commit b897bbc8135901c8edc24fc608a92d9deedeec60 (HEAD, refs/remotes/origin/master) Author: Kenichi Handa Date: Sat Mar 27 14:38:56 2021 +0900 Fix encoding by ISO-2022-JP * src/coding.c (encode_coding): Reset the CODING_MODE_LAST_BLOCK flag for all iterations but the last one. (Bug#46933) diff --git a/src/coding.c b/src/coding.c index 739dd6adcb..46e7fca0f4 100644 --- a/src/coding.c +++ b/src/coding.c @@ -7799,7 +7799,13 @@ encode_coding (struct coding_system *coding) coding_set_source (coding); consume_chars (coding, translation_table, max_lookup); coding_set_destination (coding); + /* The CODING_MODE_LAST_BLOCK flag should be set only for the last + iteration of the encoding. */ + unsigned saved_mode = coding->mode; + if (coding->consumed_char < coding->src_chars) + coding->mode &= ~CODING_MODE_LAST_BLOCK; (*(coding->encoder)) (coding); + coding->mode = saved_mode; } while (coding->consumed_char < coding->src_chars); if (BUFFERP (coding->dst_object) && coding->produced_char > 0) commit c2e72610d217f52d868c62102ff25e3279510e47 Author: Michael Albinus Date: Fri Mar 26 19:30:05 2021 +0100 Improve remote file notifications * lisp/net/tramp-sh.el (tramp-get-remote-gio-file-monitor): Remove it. (tramp-sh-handle-file-notify-add-watch): Do not call it. (tramp-sh-gio-monitor-process-filter): Read monitor name. * test/lisp/filenotify-tests.el (file-notify--test-read-event) (file-notify--test-timeout): Change timings. (file-notify--test-monitor): Read remote monitor name more reliably. (file-notify-test02-rm-watch): Retrieve remote monitor name in time. (file-notify--test-event-actions): New defun. (file-notify--test-with-actions-explainer): Use it. (file-notify--test-with-actions-check): Use it. Dump traces in case of debug. (file-notify--test-with-actions): Don't stop while debugging. (file-notify-test03-events, file-notify-test04-autorevert) (file-notify-test05-file-validity) (file-notify-test07-many-events, file-notify-test08-backup) (file-notify-test09-watched-file-in-watched-dir): Adapt tests. diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index d6fdbb0419..1764f2ef03 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -3654,6 +3654,8 @@ Fall back to normal file name handler if no Tramp handler exists." (setq file-name (expand-file-name file-name)) (with-parsed-tramp-file-name file-name nil (let ((default-directory (file-name-directory file-name)) + (process-environment + (cons "GIO_USE_FILE_MONITOR=help" process-environment)) command events filter p sequence) (cond ;; "inotifywait". @@ -3718,10 +3720,6 @@ Fall back to normal file name handler if no Tramp handler exists." (unless (process-live-p p) (tramp-error p 'file-notify-error "Monitoring not supported for `%s'" file-name)) - ;; Set "gio-file-monitor" property if needed. - (when (string-equal (file-name-nondirectory command) "gio") - (tramp-set-connection-property - p "gio-file-monitor" (tramp-get-remote-gio-file-monitor v))) p)))) (defun tramp-sh-gio-monitor-process-filter (proc string) @@ -3742,41 +3740,64 @@ Fall back to normal file name handler if no Tramp handler exists." "changes done" "changes-done-hint" string) string (tramp-compat-string-replace "renamed to" "moved" string)) - ;; https://bugs.launchpad.net/bugs/1742946 - (when - (string-match-p "Monitoring not supported\\|No locations given" string) - (delete-process proc)) - - ;; Delete empty lines. - (setq string (tramp-compat-string-replace "\n\n" "\n" string)) - - (while (string-match - (eval-when-compile - (concat "^[^:]+:" - "[[:space:]]\\([^:]+\\):" - "[[:space:]]" (regexp-opt tramp-gio-events t) - "\\([[:space:]]\\([^:]+\\)\\)?$")) - string) - - (let* ((file (match-string 1 string)) - (file1 (match-string 4 string)) - (object - (list - proc - (list - (intern-soft (match-string 2 string))) - ;; File names are returned as absolute paths. We must - ;; add the remote prefix. - (concat remote-prefix file) - (when file1 (concat remote-prefix file1))))) - (setq string (replace-match "" nil nil string)) - ;; Usually, we would add an Emacs event now. Unfortunately, - ;; `unread-command-events' does not accept several events at - ;; once. Therefore, we apply the handler directly. - (when (member (cl-caadr object) events) - (tramp-compat-funcall - (lookup-key special-event-map [file-notify]) - `(file-notify ,object file-notify-callback))))) + + (catch 'doesnt-work + ;; https://bugs.launchpad.net/bugs/1742946 + (when + (string-match-p "Monitoring not supported\\|No locations given" string) + (delete-process proc) + (throw 'doesnt-work nil)) + + ;; Determine monitor name. + (unless (tramp-connection-property-p proc "gio-file-monitor") + (cond + ;; We have seen this only on cygwin gio, which uses the + ;; GPollFileMonitor. + ((string-match + "Can't find module 'help' specified in GIO_USE_FILE_MONITOR" string) + (tramp-set-connection-property + proc "gio-file-monitor" 'GPollFileMonitor)) + ;; TODO: What happens, if several monitor names are reported? + ((string-match "\ +Supported arguments for GIO_USE_FILE_MONITOR environment variable: +\\s-*\\([[:alpha:]]+\\) - 20" string) + (tramp-set-connection-property + proc "gio-file-monitor" + (intern + (format "G%sFileMonitor" (capitalize (match-string 1 string)))))) + (t (throw 'doesnt-work nil))) + (setq string (replace-match "" nil nil string))) + + ;; Delete empty lines. + (setq string (tramp-compat-string-replace "\n\n" "\n" string)) + + (while (string-match + (eval-when-compile + (concat "^[^:]+:" + "[[:space:]]\\([^:]+\\):" + "[[:space:]]" (regexp-opt tramp-gio-events t) + "\\([[:space:]]\\([^:]+\\)\\)?$")) + string) + + (let* ((file (match-string 1 string)) + (file1 (match-string 4 string)) + (object + (list + proc + (list + (intern-soft (match-string 2 string))) + ;; File names are returned as absolute paths. We + ;; must add the remote prefix. + (concat remote-prefix file) + (when file1 (concat remote-prefix file1))))) + (setq string (replace-match "" nil nil string)) + ;; Usually, we would add an Emacs event now. Unfortunately, + ;; `unread-command-events' does not accept several events at + ;; once. Therefore, we apply the handler directly. + (when (member (cl-caadr object) events) + (tramp-compat-funcall + (lookup-key special-event-map [file-notify]) + `(file-notify ,object file-notify-callback)))))) ;; Save rest of the string. (when (zerop (length string)) (setq string nil)) @@ -5585,31 +5606,6 @@ This command is returned only if `delete-by-moving-to-trash' is non-nil." (tramp-message vec 5 "Finding a suitable `gio-monitor' command") (tramp-find-executable vec "gio" (tramp-get-remote-path vec) t t))) -(defun tramp-get-remote-gio-file-monitor (vec) - "Determine remote GFileMonitor." - (with-tramp-connection-property vec "gio-file-monitor" - (with-current-buffer (tramp-get-connection-buffer vec) - (tramp-message vec 5 "Finding the used GFileMonitor") - (when-let ((gio (tramp-get-remote-gio-monitor vec))) - ;; Search for the used FileMonitor. There is no known way to - ;; get this information directly from gio, so we check for - ;; linked libraries of libgio. - (when (tramp-send-command-and-check vec (concat "ldd " gio)) - (goto-char (point-min)) - (when (re-search-forward "\\S-+/\\(libgio\\|cyggio\\)\\S-+") - (when (tramp-send-command-and-check - vec (concat "strings " (match-string 0))) - (goto-char (point-min)) - (re-search-forward - (format - "^%s$" - (regexp-opt - '("GFamFileMonitor" "GFamDirectoryMonitor" "GFenFileMonitor" - "GInotifyFileMonitor" "GKqueueFileMonitor" - "GPollFileMonitor"))) - nil 'noerror) - (intern (match-string 0))))))))) - (defun tramp-get-remote-inotifywait (vec) "Determine remote `inotifywait' command." (with-tramp-connection-property vec "inotifywait" diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el index d73b072661..4a2f1f9a67 100644 --- a/test/lisp/filenotify-tests.el +++ b/test/lisp/filenotify-tests.el @@ -107,19 +107,19 @@ There are different timeouts for local and remote file notification libraries." (cond ;; gio/gpollfilemonitor.c declares POLL_TIME_SECS 5. So we must ;; wait at least this time in the GPollFileMonitor case. A - ;; similar timeout seems to be needed in the GFamFileMonitor case, - ;; at least on cygwin. - ((memq (file-notify--test-monitor) '(GFamFileMonitor GPollFileMonitor)) 7) - ((string-equal (file-notify--test-library) "gvfs-monitor-dir.exe") 1) + ;; similar timeout seems to be needed in the + ;; GFam{File,Directory}Monitor case. So we use a large timeout + ;; for any monitor. + ((file-notify--test-monitor) 7) ((file-remote-p temporary-file-directory) 0.1) (t 0.01)))) (defun file-notify--test-timeout () "Timeout to wait for arriving a bunch of events, in seconds." (cond + ((eq system-type 'cygwin) 10) ((file-remote-p temporary-file-directory) 6) ((string-equal (file-notify--test-library) "w32notify") 4) - ((eq system-type 'cygwin) 6) (t 3))) (defmacro file-notify--test-wait-for-events (timeout until) @@ -256,24 +256,37 @@ remote host, or nil." (defun file-notify--test-monitor () "The used monitor for the test, as a symbol. -This returns only for the local case and gfilenotify; otherwise it is nil. -`file-notify--test-desc' must be a valid watch descriptor." +This returns only for (local) gfilenotify or (remote) gio library; +otherwise it is nil. `file-notify--test-desc' must be a valid +watch descriptor." ;; We cache the result, because after `file-notify-rm-watch', ;; `gfile-monitor-name' does not return a proper result anymore. - ;; But we still need this information. - ;; So far, we know the monitors GFamFileMonitor, GFenFileMonitor, - ;; GInotifyFileMonitor, GKqueueFileMonitor and GPollFileMonitor. - (or (cdr (assq file-notify--test-desc file-notify--test-monitors)) - (progn - (add-to-list - 'file-notify--test-monitors - (cons file-notify--test-desc - (if (file-remote-p temporary-file-directory) - (tramp-get-connection-property - file-notify--test-desc "gio-file-monitor" nil) - (and (functionp 'gfile-monitor-name) - (gfile-monitor-name file-notify--test-desc))))) - (cdr (assq file-notify--test-desc file-notify--test-monitors))))) + ;; But we still need this information. So far, we know the monitors + ;; GFamFileMonitor (gfilenotify on cygwin), GFamDirectoryMonitor + ;; (gfilenotify on Solaris), GInotifyFileMonitor (gfilenotify and + ;; gio on GNU/Linux), GKqueueFileMonitor (gfilenotify and gio on + ;; FreeBSD) and GPollFileMonitor (gio on cygwin). + (when file-notify--test-desc + (or (alist-get file-notify--test-desc file-notify--test-monitors) + (when (member (file-notify--test-library) '("gfilenotify" "gio")) + (add-to-list + 'file-notify--test-monitors + (cons file-notify--test-desc + (if (file-remote-p temporary-file-directory) + ;; `file-notify--test-desc' is the connection process. + (progn + (while (not (tramp-connection-property-p + file-notify--test-desc "gio-file-monitor")) + (accept-process-output file-notify--test-desc 0)) + (tramp-get-connection-property + file-notify--test-desc "gio-file-monitor" nil)) + (and (functionp 'gfile-monitor-name) + (gfile-monitor-name file-notify--test-desc))))) + ;; If we don't know the monitor, there are good chances the + ;; test will fail. We let it fail already here, in order to + ;; know the real reason. + (should (alist-get file-notify--test-desc file-notify--test-monitors))) + (alist-get file-notify--test-desc file-notify--test-monitors)))) (defmacro file-notify--deftest-remote (test docstring &optional unstable) "Define ert `TEST-remote' for remote files. @@ -484,6 +497,9 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (file-notify-add-watch file-notify--test-tmpfile '(change) #'second-callback))) + ;; `file-notify-rm-watch' confuses `file-notify--test-monitor'. + ;; Initialize it in time. + (file-notify--test-monitor) ;; Remove first watch. (file-notify-rm-watch file-notify--test-desc) ;; Only the second callback shall run. @@ -547,6 +563,10 @@ and the event to `file-notify--test-events'." file-notify--test-results (append file-notify--test-results `(,result)))))) +(defun file-notify--test-event-actions () + "Helper function to return retrieved actions, as list." + (mapcar #'file-notify--test-event-action file-notify--test-events)) + (defun file-notify--test-with-actions-check (actions) "Check whether received actions match one of the ACTIONS alternatives." (let (result) @@ -555,22 +575,25 @@ and the event to `file-notify--test-events'." (or result (if (eq (car elt) :random) (equal (sort (cdr elt) 'string-lessp) - (sort (mapcar #'file-notify--test-event-action - file-notify--test-events) + (sort (file-notify--test-event-actions) 'string-lessp)) - (equal elt (mapcar #'file-notify--test-event-action - file-notify--test-events)))))))) + (equal elt (file-notify--test-event-actions)))))) + ;; Do not report result in case we debug. Write messages instead. + (if file-notify-debug + (prog1 t + (if result + (message "Success\n%s" (file-notify--test-event-actions)) + (message (file-notify--test-with-actions-explainer actions)))) + result))) (defun file-notify--test-with-actions-explainer (actions) "Explain why `file-notify--test-with-actions-check' fails." (if (null (cdr actions)) (format "Received actions do not match expected actions\n%s\n%s" - (mapcar #'file-notify--test-event-action file-notify--test-events) - (car actions)) + (file-notify--test-event-actions) (car actions)) (format "Received actions do not match any sequence of expected actions\n%s\n%s" - (mapcar #'file-notify--test-event-action file-notify--test-events) - actions))) + (file-notify--test-event-actions) actions))) (put 'file-notify--test-with-actions-check 'ert-explainer 'file-notify--test-with-actions-explainer) @@ -592,6 +615,9 @@ delivered." (mapcar (lambda (x) (length (if (eq (car x) :random) (cdr x) x))) actions))) + ;; Don't stop while debugging. + (while-no-input-ignore-events + (cons 'file-notify while-no-input-ignore-events)) create-lockfiles) ;; Flush pending actions. (file-notify--test-read-event) @@ -632,16 +658,11 @@ delivered." '(change) #'file-notify--test-event-handler))) (file-notify--test-with-actions (cond - ;; gvfs-monitor-dir on cygwin does not detect the - ;; `created' event reliably. - ((string-equal (file-notify--test-library) "gvfs-monitor-dir.exe") - '((deleted stopped) - (created deleted stopped))) - ;; cygwin does not raise a `changed' event. - ((eq system-type 'cygwin) - '(created deleted stopped)) - ;; GKqueueFileMonitor does not report the `changed' event. - ((equal (file-notify--test-monitor) 'GKqueueFileMonitor) + ;; GFam{File,Directory}Monitor, GKqueueFileMonitor and + ;; GPollFileMonitor do not report the `changed' event. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor + GKqueueFileMonitor GPollFileMonitor)) '(created deleted stopped)) (t '(created changed deleted stopped))) (write-region @@ -668,13 +689,14 @@ delivered." '(change) #'file-notify--test-event-handler))) (file-notify--test-with-actions (cond - ;; gvfs-monitor-dir on cygwin does not detect the - ;; `changed' event reliably. - ((string-equal (file-notify--test-library) "gvfs-monitor-dir.exe") + ;; GFam{File,Directory}Monitor and GPollFileMonitor do + ;; not detect the `changed' event reliably. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor GPollFileMonitor)) '((deleted stopped) (changed deleted stopped))) ;; GKqueueFileMonitor does not report the `changed' event. - ((equal (file-notify--test-monitor) 'GKqueueFileMonitor) + ((eq (file-notify--test-monitor) 'GKqueueFileMonitor) '(deleted stopped)) ;; There could be one or two `changed' events. (t '((changed deleted stopped) @@ -709,25 +731,22 @@ delivered." ;; events for the watched directory. ((string-equal (file-notify--test-library) "w32notify") '(created changed deleted)) - ;; gvfs-monitor-dir on cygwin does not detect the - ;; `created' event reliably. - ((string-equal - (file-notify--test-library) "gvfs-monitor-dir.exe") - '((deleted stopped) - (created deleted stopped))) ;; On emba, `deleted' and `stopped' events of the ;; directory are not detected. ((getenv "EMACS_EMBA_CI") '(created changed deleted)) ;; There are two `deleted' events, for the file and for - ;; the directory. Except for cygwin and kqueue. And - ;; cygwin does not raise a `changed' event. - ((eq system-type 'cygwin) + ;; the directory. Except for + ;; GFam{File,Directory}Monitor, GPollFileMonitor and + ;; kqueue. And GFam{File,Directory}Monitor and + ;; GPollFileMonitordo not raise a `changed' event. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor GPollFileMonitor)) '(created deleted stopped)) ((string-equal (file-notify--test-library) "kqueue") '(created changed deleted stopped)) ;; GKqueueFileMonitor does not report the `changed' event. - ((equal (file-notify--test-monitor) 'GKqueueFileMonitor) + ((eq (file-notify--test-monitor) 'GKqueueFileMonitor) '(created deleted deleted stopped)) (t '(created changed deleted deleted stopped))) (write-region @@ -762,15 +781,12 @@ delivered." '(created changed created changed changed changed changed deleted deleted)) - ;; gvfs-monitor-dir on cygwin does not detect the - ;; `created' event reliably. - ((string-equal - (file-notify--test-library) "gvfs-monitor-dir.exe") - '((deleted stopped) - (created created deleted stopped))) ;; There are three `deleted' events, for two files and - ;; for the directory. Except for cygwin and kqueue. - ((eq system-type 'cygwin) + ;; for the directory. Except for + ;; GFam{File,Directory}Monitor, GPollFileMonitor and + ;; kqueue. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor GPollFileMonitor)) '(created created changed changed deleted stopped)) ((string-equal (file-notify--test-library) "kqueue") '(created changed created changed deleted stopped)) @@ -779,7 +795,7 @@ delivered." ((getenv "EMACS_EMBA_CI") '(created changed created changed deleted deleted)) ;; GKqueueFileMonitor does not report the `changed' event. - ((equal (file-notify--test-monitor) 'GKqueueFileMonitor) + ((eq (file-notify--test-monitor) 'GKqueueFileMonitor) '(created created deleted deleted deleted stopped)) (t '(created changed created changed deleted deleted deleted stopped))) @@ -819,26 +835,23 @@ delivered." ;; events for the watched directory. ((string-equal (file-notify--test-library) "w32notify") '(created changed renamed deleted)) - ;; gvfs-monitor-dir on cygwin does not detect the - ;; `created' event reliably. - ((string-equal - (file-notify--test-library) "gvfs-monitor-dir.exe") - '((deleted stopped) - (created deleted stopped))) ;; On emba, `deleted' and `stopped' events of the ;; directory are not detected. ((getenv "EMACS_EMBA_CI") '(created changed renamed deleted)) ;; There are two `deleted' events, for the file and for - ;; the directory. Except for cygwin and kqueue. And - ;; cygwin raises `created' and `deleted' events instead - ;; of a `renamed' event. - ((eq system-type 'cygwin) + ;; the directory. Except for + ;; GFam{File,Directory}Monitor, GPollfileMonitor and + ;; kqueue. And GFam{File,Directory}Monitor and + ;; GPollFileMonitor raise `created' and `deleted' events + ;; instead of a `renamed' event. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor GPollFileMonitor)) '(created created deleted deleted stopped)) ((string-equal (file-notify--test-library) "kqueue") '(created changed renamed deleted stopped)) ;; GKqueueFileMonitor does not report the `changed' event. - ((equal (file-notify--test-monitor) 'GKqueueFileMonitor) + ((eq (file-notify--test-monitor) 'GKqueueFileMonitor) '(created renamed deleted deleted stopped)) (t '(created changed renamed deleted deleted stopped))) (write-region @@ -857,8 +870,8 @@ delivered." (file-notify--test-cleanup)) (unwind-protect - ;; Check attribute change. Does not work for cygwin. - (unless (eq system-type 'cygwin) + ;; Check attribute change. + (progn (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)) (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) @@ -876,12 +889,21 @@ delivered." ((string-equal (file-notify--test-library) "w32notify") '((changed changed) (changed changed changed changed))) - ;; GKqueueFileMonitor does not report the `attribute-changed' event. - ((equal (file-notify--test-monitor) 'GKqueueFileMonitor) nil) - ;; For kqueue and in the remote case, `write-region' - ;; raises also an `attribute-changed' event. - ((or (string-equal (file-notify--test-library) "kqueue") - (file-remote-p temporary-file-directory)) + ;; GFam{File,Directory}Monitor, GKqueueFileMonitor and + ;; GPollFileMonitor do not report the `attribute-changed' + ;; event. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor + GKqueueFileMonitor GPollFileMonitor)) + '()) + ;; For GInotifyFileMonitor,`write-region' raises + ;; also an `attribute-changed' event on gio. + ((and (string-equal (file-notify--test-library) "gio") + (eq (file-notify--test-monitor) 'GInotifyFileMonitor)) + '(attribute-changed attribute-changed attribute-changed)) + ;; For kqueue, `write-region' raises also an + ;; `attribute-changed' event. + ((string-equal (file-notify--test-library) "kqueue") '(attribute-changed attribute-changed attribute-changed)) (t '(attribute-changed attribute-changed))) (write-region @@ -946,7 +968,7 @@ delivered." ;; GKqueueFileMonitor does not report the `changed' event. (skip-unless - (not (equal (file-notify--test-monitor) 'GKqueueFileMonitor))) + (not (eq (file-notify--test-monitor) 'GKqueueFileMonitor))) ;; Check, that file notification has been used. (should auto-revert-mode) @@ -1046,13 +1068,14 @@ delivered." (should (file-notify-valid-p file-notify--test-desc)) (file-notify--test-with-actions (cond - ;; gvfs-monitor-dir on cygwin does not detect the - ;; `changed' event reliably. - ((string-equal (file-notify--test-library) "gvfs-monitor-dir.exe") + ;; GFam{File,Directory}Monitor do not + ;; detect the `changed' event reliably. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor)) '((deleted stopped) (changed deleted stopped))) ;; GKqueueFileMonitor does not report the `changed' event. - ((equal (file-notify--test-monitor) 'GKqueueFileMonitor) + ((eq (file-notify--test-monitor) 'GKqueueFileMonitor) '(deleted stopped)) ;; There could be one or two `changed' events. (t '((changed deleted stopped) @@ -1090,21 +1113,18 @@ delivered." ;; events for the watched directory. ((string-equal (file-notify--test-library) "w32notify") '(created changed deleted)) - ;; gvfs-monitor-dir on cygwin does not detect the - ;; `created' event reliably. - ((string-equal - (file-notify--test-library) "gvfs-monitor-dir.exe") - '((deleted stopped) - (created deleted stopped))) ;; There are two `deleted' events, for the file and for - ;; the directory. Except for cygwin and kqueue. And - ;; cygwin does not raise a `changed' event. - ((eq system-type 'cygwin) + ;; the directory. Except for + ;; GFam{File,Directory}Monitor, GPollFileMonitor and + ;; kqueue. And GFam{File,Directory}Monitor and + ;; GPollfileMonitor do not raise a `changed' event. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor GPollFileMonitor)) '(created deleted stopped)) ((string-equal (file-notify--test-library) "kqueue") '(created changed deleted stopped)) ;; GKqueueFileMonitor does not report the `changed' event. - ((equal (file-notify--test-monitor) 'GKqueueFileMonitor) + ((eq (file-notify--test-monitor) 'GKqueueFileMonitor) '(created deleted deleted stopped)) (t '(created changed deleted deleted stopped))) (write-region @@ -1205,7 +1225,7 @@ delivered." file-notify--test-tmpfile '(change) #'file-notify--test-event-handler))) (unwind-protect - (let ((n 1000) + (let ((n 10);00) source-file-list target-file-list (default-directory file-notify--test-tmpfile)) (dotimes (i n) @@ -1234,9 +1254,11 @@ delivered." (dotimes (_i n) (setq r (append '(deleted renamed) r))) r)) - ;; cygwin fires `changed' and `deleted' events, sometimes - ;; in random order. - ((eq system-type 'cygwin) + ;; GFam{File,Directory}Monitor and GPollFileMonitor fire + ;; `changed' and `deleted' events, sometimes in random + ;; order. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor GPollFileMonitor)) (let (r) (dotimes (_i n) (setq r (append '(changed deleted) r))) @@ -1285,7 +1307,7 @@ delivered." (file-notify--test-with-actions (cond ;; GKqueueFileMonitor does not report the `changed' event. - ((equal (file-notify--test-monitor) 'GKqueueFileMonitor) nil) + ((eq (file-notify--test-monitor) 'GKqueueFileMonitor) '()) ;; There could be one or two `changed' events. (t '((changed) (changed changed)))) @@ -1323,11 +1345,13 @@ delivered." (should (file-notify-valid-p file-notify--test-desc)) (file-notify--test-with-actions (cond - ;; On cygwin we only get the `changed' event. - ((eq system-type 'cygwin) - '(changed)) + ;; GFam{File,Directory}Monitor and GPollFileMonitor + ;; report only the `changed' event. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor GPollFileMonitor)) + '(changed)) ;; GKqueueFileMonitor does not report the `changed' event. - ((equal (file-notify--test-monitor) 'GKqueueFileMonitor) + ((eq (file-notify--test-monitor) 'GKqueueFileMonitor) '(renamed created)) (t '(renamed created changed))) ;; The file is renamed when creating a backup. It shall @@ -1398,7 +1422,7 @@ the file watch." (should (file-notify-valid-p file-notify--test-desc1)) (should (file-notify-valid-p file-notify--test-desc2)) (should-not (equal file-notify--test-desc1 file-notify--test-desc2)) - (let ((n 100)) + (let ((n 10));0)) ;; Run the test. (file-notify--test-with-actions ;; There could be one or two `changed' events. @@ -1455,10 +1479,13 @@ the file watch." ;; Now we delete the directory. (file-notify--test-with-actions (cond - ;; In kqueue and for cygwin, just one `deleted' event for - ;; the directory is received. - ((or (eq system-type 'cygwin) - (string-equal (file-notify--test-library) "kqueue")) + ;; GFam{File,Directory}Monitor, GPollFileMonitor and + ;; kqueue raise just one `deleted' event for the + ;; directory. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor GPollFileMonitor)) + '(deleted stopped)) + ((string-equal (file-notify--test-library) "kqueue") '(deleted stopped)) (t (append ;; The directory monitor raises a `deleted' event for commit 331ddd803a72056d0f0c70e5a677e0d4a6300584 Author: Basil L. Contovounesios Date: Fri Mar 26 17:13:59 2021 +0000 Address some --without-x byte-compilation warnings These came to light in the contexts of bug#29713 and bug#47234. * lisp/emulation/edt-mapper.el (edt-xserver): * lisp/emulation/edt.el (edt-xserver): * lisp/gnus/gnus-util.el (gnus-rescale-image): * lisp/gnus/nnimap.el (nnimap-map-port): * lisp/term/w32-win.el: * lisp/image.el (image--get-imagemagick-and-warn): * lisp/frame.el (frame-notice-user-settings): Declare functions that are known to be present at runtime in GUI builds. (make-frame-on-display): Signal more informative error when called interactively in a non-GUI build (bug#29713). * lisp/international/mule-diag.el (describe-font): * lisp/org/org-macs.el (org--string-from-props): Pacify warnings about unknown functions in non-GUI bilds. * lisp/mh-e/mh-mime.el (mh-small-image-p): Avoid eliminating fboundp check in non-GUI builds, to pacify unused lexical variable warning. * lisp/net/newst-plainview.el (newsticker--plainview-tool-bar-map): * lisp/net/newst-treeview.el (newsticker-treeview-tool-bar-map): Declare tool-bar-map as a special variable in non-GUI builds. diff --git a/lisp/emulation/edt-mapper.el b/lisp/emulation/edt-mapper.el index c1c17723a4..0b15278425 100644 --- a/lisp/emulation/edt-mapper.el +++ b/lisp/emulation/edt-mapper.el @@ -101,6 +101,8 @@ (define-obsolete-variable-alias 'edt-window-system 'window-system "27.1") (defconst edt-xserver (when (eq window-system 'x) + (declare-function x-server-vendor "xfns.c" + (&optional terminal)) ;; The Cygwin window manager has a `/' in its ;; name, which breaks the generated file name of ;; the custom key map file. Replace `/' with a diff --git a/lisp/emulation/edt.el b/lisp/emulation/edt.el index 8f90ed2826..50979c4dbb 100644 --- a/lisp/emulation/edt.el +++ b/lisp/emulation/edt.el @@ -299,6 +299,8 @@ This means that an edt-user.el file was found in the user's `load-path'.") ;;; o edt-emulation-on o edt-load-keys ;;; (defconst edt-xserver (when (eq window-system 'x) + (declare-function x-server-vendor "xfns.c" + (&optional terminal)) ;; The Cygwin window manager has a `/' in its ;; name, which breaks the generated file name of ;; the custom key map file. Replace `/' with a diff --git a/lisp/frame.el b/lisp/frame.el index 151aefb47a..2b6e4a60b8 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -367,6 +367,7 @@ there (in decreasing order of priority)." ;; by the lines added in x-create-frame for the tab-bar and ;; switch `tab-bar-mode' off. (when (display-graphic-p) + (declare-function tab-bar-height "xdisp.c" (&optional frame pixelwise)) (let* ((init-lines (assq 'tab-bar-lines initial-frame-alist)) (other-lines @@ -708,9 +709,11 @@ Return nil if we don't know how to interpret DISPLAY." (defun make-frame-on-display (display &optional parameters) "Make a frame on display DISPLAY. The optional argument PARAMETERS specifies additional frame parameters." - (interactive (list (completing-read - (format "Make frame on display: ") - (x-display-list)))) + (interactive (if (fboundp 'x-display-list) + (list (completing-read + (format "Make frame on display: ") + (x-display-list))) + (user-error "This Emacs build does not support X displays"))) (make-frame (cons (cons 'display display) parameters))) (defun make-frame-on-current-monitor (&optional parameters) diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el index f80243cfed..e558f639e4 100644 --- a/lisp/gnus/gnus-util.el +++ b/lisp/gnus/gnus-util.el @@ -1612,8 +1612,8 @@ empty directories from OLD-PATH." "Rescale IMAGE to SIZE if possible. SIZE is in format (WIDTH . HEIGHT). Return a new image. Sizes are in pixels." - (if (not (display-graphic-p)) - image + (when (display-images-p) + (declare-function image-size "image.c" (spec &optional pixels frame)) (let ((new-width (car size)) (new-height (cdr size))) (when (> (cdr (image-size image t)) new-height) @@ -1621,8 +1621,8 @@ Sizes are in pixels." :max-height new-height))) (when (> (car (image-size image t)) new-width) (setq image (create-image (plist-get (cdr image) :data) nil t - :max-width new-width))) - image))) + :max-width new-width))))) + image) (defun gnus-recursive-directory-files (dir) "Return all regular files below DIR. diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el index 93e1c47be7..f06959f65d 100644 --- a/lisp/gnus/nnimap.el +++ b/lisp/gnus/nnimap.el @@ -440,6 +440,7 @@ during splitting, which may be slow." ;; This is only needed for Windows XP or earlier (defun nnimap-map-port (port) + (declare-function x-server-version "xfns.c" (&optional terminal)) (if (and (eq system-type 'windows-nt) (<= (car (x-server-version)) 5) (equal port "imaps")) diff --git a/lisp/image.el b/lisp/image.el index 4ede1fbf37..b802c1c906 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -1130,6 +1130,7 @@ default is 20%." image)) (defun image--get-imagemagick-and-warn (&optional position) + (declare-function image-transforms-p "image.c" (&optional frame)) (unless (or (fboundp 'imagemagick-types) (image-transforms-p)) (error "Cannot rescale images on this terminal")) (let ((image (image--get-image position))) diff --git a/lisp/international/mule-diag.el b/lisp/international/mule-diag.el index d97d090cd0..a0063c8dbb 100644 --- a/lisp/international/mule-diag.el +++ b/lisp/international/mule-diag.el @@ -835,6 +835,8 @@ The IGNORED argument is ignored." (list (completing-read "Font name (default current choice for ASCII chars): " (and window-system + ;; Implied by `window-system'. + (fboundp 'x-list-fonts) (fboundp 'fontset-list) ;; The final element in `fontset-list' is a default ;; (generic) one, so don't include that. diff --git a/lisp/mh-e/mh-mime.el b/lisp/mh-e/mh-mime.el index 5ffba8fe1a..fec2293ff1 100644 --- a/lisp/mh-e/mh-mime.el +++ b/lisp/mh-e/mh-mime.el @@ -777,7 +777,7 @@ This is only useful if a Content-Disposition header is not present." (funcall media-test handle) ; Since mm-inline-large-images is T, ; this only tells us if the image is ; something that emacs can display - (let* ((image (mm-get-image handle))) + (let ((image (mm-get-image handle))) (or (mh-do-in-xemacs (and (mh-funcall-if-exists glyphp image) (< (glyph-width image) @@ -786,7 +786,7 @@ This is only useful if a Content-Disposition header is not present." (or mh-max-inline-image-height (window-pixel-height))))) (mh-do-in-gnu-emacs - (let ((size (mh-funcall-if-exists image-size image))) + (let ((size (and (fboundp 'image-size) (image-size image)))) (and size (< (cdr size) (or mh-max-inline-image-height (1- (window-height)))) diff --git a/lisp/net/newst-plainview.el b/lisp/net/newst-plainview.el index 76b1ef3764..420cf82e4d 100644 --- a/lisp/net/newst-plainview.el +++ b/lisp/net/newst-plainview.el @@ -273,6 +273,7 @@ images." (defvar newsticker--plainview-tool-bar-map (when (boundp 'tool-bar-map) + (defvar tool-bar-map) (let ((tool-bar-map (make-sparse-keymap))) (tool-bar-add-item "newsticker/prev-feed" 'newsticker-previous-feed diff --git a/lisp/net/newst-treeview.el b/lisp/net/newst-treeview.el index d778cc1761..29c92d52dd 100644 --- a/lisp/net/newst-treeview.el +++ b/lisp/net/newst-treeview.el @@ -1102,6 +1102,7 @@ Arguments are ignored." ;; ====================================================================== (defvar newsticker-treeview-tool-bar-map (when (boundp 'tool-bar-map) + (defvar tool-bar-map) (let ((tool-bar-map (make-sparse-keymap))) (tool-bar-add-item "newsticker/prev-feed" 'newsticker-treeview-prev-feed diff --git a/lisp/org/org-macs.el b/lisp/org/org-macs.el index ac6691db0d..58d3fd3992 100644 --- a/lisp/org/org-macs.el +++ b/lisp/org/org-macs.el @@ -869,7 +869,8 @@ delimiting S." (let ((width (plist-get props :width))) (and (wholenump width) width))) (`(image . ,_) - (ceiling (car (image-size spec)))) + (and (fboundp 'image-size) + (ceiling (car (image-size spec))))) ((pred stringp) ;; Displayed string could contain invisible parts, ;; but no nested display. diff --git a/lisp/term/w32-win.el b/lisp/term/w32-win.el index e845193013..687250fe46 100644 --- a/lisp/term/w32-win.el +++ b/lisp/term/w32-win.el @@ -555,6 +555,9 @@ be found in this alist. This alist is used by w32font.c when it looks for fonts that can display characters from scripts for which no USBs are defined.") +(declare-function x-list-fonts "xfaces.c" + (pattern &optional face frame maximum width)) + (defun w32-find-non-USB-fonts (&optional frame size) "Compute the value of `w32-non-USB-fonts' for specified SIZE and FRAME. FRAME defaults to the selected frame. commit bc506441372726341b6d95abb85011dba6d897ea Author: Stefan Monnier Date: Fri Mar 26 11:45:31 2021 -0400 * lisp/obsolete/tpu-extras.el: Avoid defadvice (tpu--respect-bottom-scroll-margin): New function, extracted from `newline`s defadvice. (newline, newline-and-indent, do-auto-fill): Delete defadvice. (tpu-set-scroll-margins): Use advice-add instead of `ad-enable-advice`+`ad-activate`. Use an explicit arg instead of `called-interactively-p`. diff --git a/lisp/obsolete/tpu-extras.el b/lisp/obsolete/tpu-extras.el index 5d59945c56..f375e05d8a 100644 --- a/lisp/obsolete/tpu-extras.el +++ b/lisp/obsolete/tpu-extras.el @@ -368,34 +368,22 @@ A repeat count means scroll that many sections." (and (< (point) top) (recenter (min beg top-margin)))))) ;; Advise the newline, newline-and-indent, and do-auto-fill functions. -(defadvice newline (around tpu-respect-bottom-scroll-margin activate disable) +(defun tpu--respect-bottom-scroll-margin (orig-fun &optional &rest args) "Respect `tpu-bottom-scroll-margin'." (let ((beg (tpu-current-line)) - (num (prefix-numeric-value (ad-get-arg 0)))) - ad-do-it + (num (prefix-numeric-value (car args)))) + (apply orig-fun args) (tpu-bottom-check beg num))) -(defadvice newline-and-indent (around tpu-respect-bottom-scroll-margin) - "Respect `tpu-bottom-scroll-margin'." - (let ((beg (tpu-current-line))) - ad-do-it - (tpu-bottom-check beg 1))) - -(defadvice do-auto-fill (around tpu-respect-bottom-scroll-margin) - "Respect `tpu-bottom-scroll-margin'." - (let ((beg (tpu-current-line))) - ad-do-it - (tpu-bottom-check beg 1))) - - ;;; Function to set scroll margins ;;;###autoload -(defun tpu-set-scroll-margins (top bottom) +(defun tpu-set-scroll-margins (top bottom &optional emit-msg) "Set scroll margins." (interactive "sEnter top scroll margin (N lines or N%% or RETURN for current value): \ -\nsEnter bottom scroll margin (N lines or N%% or RETURN for current value): ") +\nsEnter bottom scroll margin (N lines or N%% or RETURN for current value): \ +\np") ;; set top scroll margin (or (string= top "") (setq tpu-top-scroll-margin @@ -411,10 +399,9 @@ A repeat count means scroll that many sections." (/ (1- (+ (* (string-to-number bottom) 100) (window-height))) (window-height))))) (dolist (f '(newline newline-and-indent do-auto-fill)) - (ad-enable-advice f 'around 'tpu-respect-bottom-scroll-margin) - (ad-activate f)) + (advice-add f :around #'tpu--respect-bottom-scroll-margin)) ;; report scroll margin settings if running interactively - (and (called-interactively-p 'interactive) + (and emit-msg (message "Scroll margins set. Top = %s%%, Bottom = %s%%" tpu-top-scroll-margin tpu-bottom-scroll-margin))) commit 28d0654943ca4e66cdcb498c53dc8aaa41fe2fad Author: Stefan Monnier Date: Fri Mar 26 11:28:03 2021 -0400 * lisp/mh-e/: Take advice-remove of the newly enabled lexical-binding * lisp/mh-e/mh-mime.el (mh-mm-inline-message): * lisp/mh-e/mh-inc.el (mh-inc-spool-generator): Replace `(lambda...) with a proper closure. diff --git a/lisp/mh-e/mh-inc.el b/lisp/mh-e/mh-inc.el index 90d5489526..6a29195afb 100644 --- a/lisp/mh-e/mh-inc.el +++ b/lisp/mh-e/mh-inc.el @@ -62,15 +62,11 @@ (defun mh-inc-spool-generator (folder spool) "Create a command to inc into FOLDER from SPOOL file." - (let ((folder1 (make-symbol "folder")) - (spool1 (make-symbol "spool"))) - (set folder1 folder) - (set spool1 spool) - (setf (symbol-function (intern (concat "mh-inc-spool-" folder))) - `(lambda () - ,(format "Inc spool file %s into folder %s." spool folder) - (interactive) - (mh-inc-folder ,spool1 (concat "+" ,folder1)))))) + (defalias (symbol-function (intern (concat "mh-inc-spool-" folder))) + (lambda () + (:documentation (format "Inc spool file %s into folder %s." spool folder)) + (interactive) + (mh-inc-folder spool (concat "+" folder))))) (defun mh-inc-spool-def-key (key folder) "Define a KEY in `mh-inc-spool-map' to inc FOLDER and collect help string." diff --git a/lisp/mh-e/mh-mime.el b/lisp/mh-e/mh-mime.el index 3ae8b0728c..5ffba8fe1a 100644 --- a/lisp/mh-e/mh-mime.el +++ b/lisp/mh-e/mh-mime.el @@ -487,9 +487,11 @@ decoding the same message multiple times." (mh-display-emphasis) (mm-handle-set-undisplayer handle - `(lambda () - (let (buffer-read-only) - (delete-region ,(point-min-marker) ,(point-max-marker))))))))) + (let ((beg (point-min-marker)) + (end (point-max-marker))) + (lambda () + (let ((inhibit-read-only t)) + (delete-region beg end))))))))) ;;;###mh-autoload (defun mh-decode-message-header () commit c24766c4d59bc7d9f583f299b1558e2356fba933 Author: Spencer Baugh Date: Tue Mar 23 23:11:52 2021 -0400 Assert not local-variable-p after setq in let_default binding Breaking this is a likely way to break this test, so this saves a bit of time in debugging. * test/src/data-tests.el (data-tests--let-buffer-local): Add assertion to test. diff --git a/test/src/data-tests.el b/test/src/data-tests.el index d0cb87293f..b1e5fa0767 100644 --- a/test/src/data-tests.el +++ b/test/src/data-tests.el @@ -358,6 +358,7 @@ comparing the subr with a much slower lisp implementation." (should (equal (symbol-value var) 42)) (should (equal (default-value var) (symbol-value var))) (set var 123) + (should (not (local-variable-p var))) (should (equal (symbol-value var) 123)) (should (equal (default-value var) (symbol-value var)))) ;bug#44733 (should (equal (symbol-value var) def)) commit b29bf8181fe2c02becd0a3ac5e2f85cb0a3b58bf Author: Spencer Baugh Date: Tue Mar 23 23:11:51 2021 -0400 Add a test for let-binding unwinding Bindings in other buffers are not un-set when we unwind a let-binding which set the default value. There doesn't seem to be an existing test which covers this, so here's one. * test/src/data-tests.el (data-tests--let-buffer-local-no-unwind-other-buffers): Add test for let-binding unwinding behavior diff --git a/test/src/data-tests.el b/test/src/data-tests.el index 03d867f18a..d0cb87293f 100644 --- a/test/src/data-tests.el +++ b/test/src/data-tests.el @@ -364,6 +364,28 @@ comparing the subr with a much slower lisp implementation." (should (equal (default-value var) (symbol-value var)))) (should (equal (default-value var) def)))))) +(ert-deftest data-tests--let-buffer-local-no-unwind-other-buffers () + "Test that a let-binding for a buffer-local unwinds only current-buffer." + (let ((blvar (make-symbol "blvar"))) + (set-default blvar 0) + (make-variable-buffer-local blvar) + (dolist (var (list blvar 'left-margin)) + (let* ((def (default-value var)) + (newdef (+ def 1)) + (otherbuf (generate-new-buffer "otherbuf"))) + (with-temp-buffer + (cl-progv (list var) (list newdef) + (with-current-buffer otherbuf + (set var 123) + (should (local-variable-p var)) + (should (equal (symbol-value var) 123)) + (should (equal (default-value var) newdef)))) + (with-current-buffer otherbuf + (should (local-variable-p var)) + (should (equal (symbol-value var) 123)) + (should (equal (default-value var) def))) + ))))) + (ert-deftest binding-test-makunbound () "Tests of makunbound, from the manual." (with-current-buffer binding-test-buffer-B commit 55a7af9123b5c2c2cad8f768a1234b59b07f7afc Author: Stefan Monnier Date: Thu Mar 25 11:57:58 2021 -0400 * lisp/htmlfontify.el: Fix misuses of `nconc` (hfy-face-to-style-i): `this` is not known to be fresh. (hfy--size-to-int): Rename from `hfy--size-to-int` and return just the integer without wrapping it in a list. (hfy-flatten-style): Avoid O(n²) problems. Use `float`. diff --git a/lisp/htmlfontify.el b/lisp/htmlfontify.el index bfbe0ee165..0c8d534824 100644 --- a/lisp/htmlfontify.el +++ b/lisp/htmlfontify.el @@ -983,19 +983,18 @@ merged by the user - `hfy-flatten-style' should do this." (:italic (hfy-slant 'italic)))))) (setq that (hfy-face-to-style-i next)) ;;(lwarn t :warning "%S => %S" fn (nconc this that parent)) - (nconc this parent that))) ) + (append this parent that))) ) -(defun hfy-size-to-int (spec) +(defun hfy--size-to-int (spec) "Convert SPEC, a CSS font-size specifier, to an Emacs :height attribute value. Used while merging multiple font-size attributes." - ;;(message "hfy-size-to-int");;DBUG - (list - (if (string-match "\\([0-9]+\\)\\(%\\|pt\\)" spec) - (cond ((string= "%" (match-string 2 spec)) - (/ (string-to-number (match-string 1 spec)) 100.0)) - ((string= "pt" (match-string 2 spec)) - (* (string-to-number (match-string 1 spec)) 10))) - (string-to-number spec))) ) + ;;(message "hfy--size-to-int");;DBUG + (if (string-match "\\([0-9]+\\)\\(%\\|pt\\)" spec) + (cond ((string= "%" (match-string 2 spec)) + (/ (string-to-number (match-string 1 spec)) 100.0)) + ((string= "pt" (match-string 2 spec)) + (* (string-to-number (match-string 1 spec)) 10))) + (string-to-number spec)) ) ;; size is different, in that in order to get it right at all, ;; we have to trawl the inheritance path, accumulating modifiers, @@ -1006,19 +1005,18 @@ any multiple attributes appropriately. Currently only font-size is merged down to a single occurrence - others may need special handling, but I haven't encountered them yet. Returns a `hfy-style-assoc'." ;;(message "(hfy-flatten-style %S)" style) ;;DBUG - (let ((n 0) - (m (list 1)) + (let ((m (list 1)) (x nil) (r nil)) (dolist (css style) (if (string= (car css) "font-size") (progn - (when (not x) (setq m (nconc m (hfy-size-to-int (cdr css))))) + (when (not x) (push (hfy--size-to-int (cdr css)) m)) (when (string-match "pt" (cdr css)) (setq x t))) - (setq r (nconc r (list css))))) + (push css r))) ;;(message "r: %S" r) - (setq n (apply #'* m)) - (nconc r (hfy-size (if x (round n) (* n 1.0)))) )) + (let ((n (apply #'* m))) + (nconc (nreverse r) (hfy-size (if x (round n) (float n))))))) (defun hfy-face-resolve-face (fn) "For FN return a face specification. @@ -1052,7 +1050,7 @@ See also `hfy-face-to-style-i', `hfy-flatten-style'." ;; text-decoration is not inherited. ;; but it's not wrong and if this ever changes it will ;; be needed, so I think it's better to leave it in? -- v - (nconc final-style '(("text-decoration" . "none")))))) + (push '("text-decoration" . "none") final-style)))) final-style)) ;; strip redundant bits from a name. Technically, this could result in commit c4e89ac2a2a41677a03ea140832074f990c4b38a Author: Bill Wohler Date: Thu Mar 25 09:09:27 2021 -0700 Remove XEmacs support in lexical-binding * lisp/mh-e/mh-alias.el (mh-alias-insert-file): Remove reference to remove-specifier. diff --git a/lisp/mh-e/mh-mime.el b/lisp/mh-e/mh-mime.el index 8af7bcdf8f..3ae8b0728c 100644 --- a/lisp/mh-e/mh-mime.el +++ b/lisp/mh-e/mh-mime.el @@ -489,12 +489,6 @@ decoding the same message multiple times." handle `(lambda () (let (buffer-read-only) - (if (fboundp 'remove-specifier) - ;; This is only valid on XEmacs. - (mapcar (lambda (prop) - (remove-specifier - (face-property 'default prop) (current-buffer))) - '(background background-pixmap foreground))) (delete-region ,(point-min-marker) ,(point-max-marker))))))))) ;;;###mh-autoload commit f1f351def3d84813d2c4b2174dfef07b01bec058 Author: Mark A. Hershberger Date: Thu Mar 25 11:44:46 2021 -0400 Update rnc to use Open Document's Relax-NG schema to version 1.3 * Use the LibreOffice Relax-NG files since they include a hack to support 1.2. * rng source: https://raw.githubusercontent.com/freedesktop/libreoffice-core/master/ schema/libreoffice/OpenDocument-schema-v1.3%2Blibreoffice.rng * translation to rnc with trang: trang -I rng -O rnc OpenDocument-schema-v1.3+libreoffice.rng \ OpenDocument-schema-v1.3+libreoffice.rnc diff --git a/etc/schema/OpenDocument-schema-v1.3+libreoffice.rnc b/etc/schema/OpenDocument-schema-v1.3+libreoffice.rnc new file mode 100644 index 0000000000..5239c84cb5 --- /dev/null +++ b/etc/schema/OpenDocument-schema-v1.3+libreoffice.rnc @@ -0,0 +1,892 @@ +# Open Document Format for Office Applications (OpenDocument) Version 1.3 +# OASIS Standard, In progress +# Relax-NG Schema +# Source: https://tools.oasis-open.org/version-control/svn/office/ +# Copyright (c) OASIS Open 2002-2015. All Rights Reserved. +# +# All capitalized terms in the following text have the meanings assigned to them +# in the OASIS Intellectual Property Rights Policy (the "OASIS IPR Policy"). The +# full Policy may be found at the OASIS website. +# +# This document and translations of it may be copied and furnished to others, and +# derivative works that comment on or otherwise explain it or assist in its +# implementation may be prepared, copied, published, and distributed, in whole or +# in part, without restriction of any kind, provided that the above copyright +# notice and this section are included on all such copies and derivative works. +# However, this document itself may not be modified in any way, including by +# removing the copyright notice or references to OASIS, except as needed for the +# purpose of developing any document or deliverable produced by an OASIS +# Technical Committee (in which case the rules applicable to copyrights, as set +# forth in the OASIS IPR Policy, must be followed) or as required to translate it +# into languages other than English. +# +# The limited permissions granted above are perpetual and will not be revoked by +# OASIS or its successors or assigns. +# +# This document and the information contained herein is provided on an "AS IS" +# basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +# LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT +# INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR +# FITNESS FOR A PARTICULAR PURPOSE. + +namespace anim = "urn:oasis:names:tc:opendocument:xmlns:animation:1.0" +namespace calcext = + "urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" +namespace chart = "urn:oasis:names:tc:opendocument:xmlns:chart:1.0" +namespace chartooo = "http://openoffice.org/2010/chart" +namespace config = "urn:oasis:names:tc:opendocument:xmlns:config:1.0" +namespace css3t = "http://www.w3.org/TR/css3-text/" +namespace db = "urn:oasis:names:tc:opendocument:xmlns:database:1.0" +namespace dc = "http://purl.org/dc/elements/1.1/" +namespace dr3d = "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" +namespace draw = "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" +namespace drawooo = "http://openoffice.org/2010/draw" +namespace field = + "urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" +namespace fo = + "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" +namespace form = "urn:oasis:names:tc:opendocument:xmlns:form:1.0" +namespace grddl = "http://www.w3.org/2003/g/data-view#" +namespace loext = + "urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" +namespace math = "http://www.w3.org/1998/Math/MathML" +namespace meta = "urn:oasis:names:tc:opendocument:xmlns:meta:1.0" +namespace number = "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" +namespace office = "urn:oasis:names:tc:opendocument:xmlns:office:1.0" +namespace officeooo = "http://openoffice.org/2009/office" +namespace presentation = + "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" +namespace rng = "http://relaxng.org/ns/structure/1.0" +namespace script = "urn:oasis:names:tc:opendocument:xmlns:script:1.0" +namespace smil = + "urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0" +namespace style = "urn:oasis:names:tc:opendocument:xmlns:style:1.0" +namespace svg = + "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" +namespace table = "urn:oasis:names:tc:opendocument:xmlns:table:1.0" +namespace tableooo = "http://openoffice.org/2009/table" +namespace text = "urn:oasis:names:tc:opendocument:xmlns:text:1.0" +namespace xforms = "http://www.w3.org/2002/xforms" +namespace xhtml = "http://www.w3.org/1999/xhtml" +namespace xlink = "http://www.w3.org/1999/xlink" + +include "OpenDocument-schema-v1.3.rnc" { + office-document-common-attrs = + attribute office:version { + # FIXME remove this hack once we write 1.3 + "1.3" | "1.2" + } + & attribute grddl:transformation { + list { anyIRI* } + }? + style-graphic-properties-attlist = + attribute draw:stroke { "none" | "dash" | "solid" }? + & attribute draw:stroke-dash { styleNameRef }? + & attribute draw:stroke-dash-names { styleNameRefs }? + & attribute svg:stroke-width { length }? + & attribute svg:stroke-color { color }? + & attribute draw:marker-start { styleNameRef }? + & attribute draw:marker-end { styleNameRef }? + & attribute draw:marker-start-width { length }? + & attribute draw:marker-end-width { length }? + & attribute draw:marker-start-center { boolean }? + & attribute draw:marker-end-center { boolean }? + & attribute svg:stroke-opacity { + xsd:double { minInclusive = "0" maxInclusive = "1" } + | zeroToHundredPercent + }? + & attribute draw:stroke-linejoin { + "miter" | "round" | "bevel" | "middle" | "none" + }? + & attribute svg:stroke-linecap { "butt" | "square" | "round" }? + & attribute draw:symbol-color { color }? + & attribute text:animation { + "none" | "scroll" | "alternate" | "slide" + }? + & attribute text:animation-direction { + "left" | "right" | "up" | "down" + }? + & attribute text:animation-start-inside { boolean }? + & attribute text:animation-stop-inside { boolean }? + & attribute text:animation-repeat { nonNegativeInteger }? + & attribute text:animation-delay { duration }? + & attribute text:animation-steps { length }? + & attribute draw:auto-grow-width { boolean }? + & attribute draw:auto-grow-height { boolean }? + & # FIXME remove this once the export bug is fixed + attribute draw:fit-to-size { + "true" | "false" | "all" | "shrink-to-fit" + }? + & attribute draw:fit-to-contour { boolean }? + & attribute draw:textarea-vertical-align { + "top" | "middle" | "bottom" | "justify" + }? + & attribute draw:textarea-horizontal-align { + "left" | "center" | "right" | "justify" + }? + & attribute fo:wrap-option { "no-wrap" | "wrap" }? + & attribute style:shrink-to-fit { boolean }? + & attribute draw:color-mode { + "greyscale" | "mono" | "watermark" | "standard" + }? + & attribute draw:color-inversion { boolean }? + & attribute draw:luminance { signedZeroToHundredPercent } + # https://issues.oasis-open.org/browse/OFFICE-3821 + ? + & attribute draw:contrast { percent }? + & attribute draw:gamma { percent }? + & attribute draw:red { signedZeroToHundredPercent }? + & attribute draw:green { signedZeroToHundredPercent }? + & attribute draw:blue { signedZeroToHundredPercent }? + & attribute draw:image-opacity { zeroToHundredPercent }? + & attribute draw:shadow { "visible" | "hidden" }? + & attribute draw:shadow-offset-x { length }? + & attribute draw:shadow-offset-y { length }? + & attribute draw:shadow-color { color }? + & attribute draw:shadow-opacity { zeroToHundredPercent }? + & # TODO: no proposal for loext:shadow-blur + attribute loext:shadow-blur { length }? + & attribute draw:start-line-spacing-horizontal { distance }? + & attribute draw:start-line-spacing-vertical { distance }? + & attribute draw:end-line-spacing-horizontal { distance }? + & attribute draw:end-line-spacing-vertical { distance }? + & attribute draw:line-distance { distance }? + & attribute draw:guide-overhang { length }? + & attribute draw:guide-distance { distance }? + & attribute draw:start-guide { length }? + & attribute draw:end-guide { length }? + & attribute draw:placing { "below" | "above" }? + & attribute draw:parallel { boolean }? + & attribute draw:measure-align { + "automatic" | "left-outside" | "inside" | "right-outside" + }? + & attribute draw:measure-vertical-align { + "automatic" | "above" | "below" | "center" + }? + & attribute draw:unit { + "automatic" + | "mm" + | "cm" + | "m" + | "km" + | "pt" + | "pc" + | "inch" + | "ft" + | "mi" + }? + & attribute draw:show-unit { boolean }? + & attribute draw:decimal-places { nonNegativeInteger }? + & attribute draw:caption-type { + "straight-line" | "angled-line" | "angled-connector-line" + }? + & attribute draw:caption-angle-type { "fixed" | "free" }? + & attribute draw:caption-angle { angle }? + & attribute draw:caption-gap { distance }? + & attribute draw:caption-escape-direction { + "horizontal" | "vertical" | "auto" + }? + & attribute draw:caption-escape { length | percent }? + & attribute draw:caption-line-length { length }? + & attribute draw:caption-fit-line-length { boolean }? + & attribute dr3d:horizontal-segments { nonNegativeInteger }? + & attribute dr3d:vertical-segments { nonNegativeInteger }? + & attribute dr3d:edge-rounding { percent }? + & attribute dr3d:edge-rounding-mode { "correct" | "attractive" }? + & attribute dr3d:back-scale { percent }? + & attribute dr3d:depth { length }? + & attribute dr3d:backface-culling { "enabled" | "disabled" }? + & attribute dr3d:end-angle { angle }? + & attribute dr3d:close-front { boolean }? + & attribute dr3d:close-back { boolean }? + & attribute dr3d:lighting-mode { "standard" | "double-sided" }? + & attribute dr3d:normals-kind { "object" | "flat" | "sphere" }? + & attribute dr3d:normals-direction { "normal" | "inverse" }? + & attribute dr3d:texture-generation-mode-x { + "object" | "parallel" | "sphere" + }? + & attribute dr3d:texture-generation-mode-y { + "object" | "parallel" | "sphere" + }? + & attribute dr3d:texture-kind { + "luminance" | "intensity" | "color" + }? + & attribute dr3d:texture-filter { "enabled" | "disabled" }? + & attribute dr3d:texture-mode { "replace" | "modulate" | "blend" }? + & attribute dr3d:ambient-color { color }? + & attribute dr3d:emissive-color { color }? + & attribute dr3d:specular-color { color }? + & attribute dr3d:diffuse-color { color }? + & attribute dr3d:shininess { percent }? + & attribute dr3d:shadow { "visible" | "hidden" }? + & common-draw-rel-size-attlist + & attribute fo:min-width { length | percent }? + & attribute fo:min-height { length | percent }? + & attribute fo:max-height { length | percent }? + & attribute fo:max-width { length | percent }? + & common-horizontal-margin-attlist + & common-vertical-margin-attlist + & common-margin-attlist + & attribute style:print-content { boolean }? + & attribute style:protect { + "none" + | list { ("content" | "position" | "size")+ } + }? + & attribute style:horizontal-pos { + "left" + | "center" + | "right" + | "from-left" + | "inside" + | "outside" + | "from-inside" + }? + & attribute svg:x { coordinate }? + & attribute style:horizontal-rel { + "page" + | "page-content" + | "page-start-margin" + | "page-end-margin" + | "frame" + | "frame-content" + | "frame-start-margin" + | "frame-end-margin" + | "paragraph" + | "paragraph-content" + | "paragraph-start-margin" + | "paragraph-end-margin" + | "char" + }? + & common-vertical-pos-attlist + & common-vertical-rel-attlist + & common-text-anchor-attlist + & common-border-attlist + & common-border-line-width-attlist + & common-padding-attlist + & common-shadow-attlist + & common-background-color-attlist + & common-background-transparency-attlist + & common-editable-attlist + & attribute style:wrap { + "none" + | "left" + | "right" + | "parallel" + | "dynamic" + | "run-through" + | "biggest" + }? + & attribute style:wrap-dynamic-threshold { nonNegativeLength }? + & attribute style:number-wrapped-paragraphs { + "no-limit" | positiveInteger + }? + & attribute style:wrap-contour { boolean }? + & attribute style:wrap-contour-mode { "full" | "outside" }? + & attribute style:run-through { "foreground" | "background" }? + & attribute style:flow-with-text { boolean }? + & attribute style:overflow-behavior { + "clip" | "auto-create-new-frame" + }? + & attribute style:mirror { + "none" + | "vertical" + | horizontal-mirror + | list { "vertical", horizontal-mirror } + | list { horizontal-mirror, "vertical" } + }? + & attribute fo:clip { "auto" | clipShape }? + & attribute draw:wrap-influence-on-position { + "iterative" | "once-concurrent" | "once-successive" + }? + & common-writing-mode-attlist + & attribute draw:frame-display-scrollbar { boolean }? + & attribute draw:frame-display-border { boolean }? + & attribute draw:frame-margin-horizontal { nonNegativePixelLength }? + & attribute draw:frame-margin-vertical { nonNegativePixelLength }? + & attribute draw:visible-area-left { nonNegativeLength }? + & attribute draw:visible-area-top { nonNegativeLength }? + & attribute draw:visible-area-width { positiveLength }? + & attribute draw:visible-area-height { positiveLength }? + & attribute draw:draw-aspect { + "content" | "thumbnail" | "icon" | "print-view" + }? + & attribute draw:ole-draw-aspect { nonNegativeInteger }? + & # https://issues.oasis-open.org/browse/OFFICE-4047 + attribute loext:allow-overlap { boolean }? + & # TODO: no proposal for loext:glow* + attribute loext:glow-radius { length }? + & attribute loext:glow-color { color }? + & attribute loext:glow-transparency { zeroToHundredPercent }? + & # TODO: no proposal for loext:softedge-radius + attribute loext:softedge-radius { length }? + draw-text = + (text-p + | text-list + | # https://issues.oasis-open.org/browse/OFFICE-3761 + loext-table)* + office-annotation-attlist &= + attribute office:display { boolean }? + & common-office-annotation-name-attlist? + & attribute loext:resolved { boolean }? + style-style-content = + (attribute style:family { "text" }, + style-text-properties?) + | (attribute style:family { "paragraph" }, + # TODO no proposal + loext-graphic-properties?, + style-paragraph-properties?, + style-text-properties?) + | (attribute style:family { "section" }, + style-section-properties?) + | (attribute style:family { "ruby" }, + style-ruby-properties?) + | (attribute style:family { "table" }, + style-table-properties?) + | (attribute style:family { "table-column" }, + style-table-column-properties?) + | (attribute style:family { "table-row" }, + style-table-row-properties?) + | (attribute style:family { "table-cell" }, + # TODO no proposal + loext-graphic-properties?, + style-table-cell-properties?, + style-paragraph-properties?, + style-text-properties?) + | (attribute style:family { "graphic" | "presentation" }, + style-graphic-properties?, + style-paragraph-properties?, + style-text-properties?) + | (attribute style:family { "drawing-page" }, + style-drawing-page-properties?) + | (attribute style:family { "chart" }, + style-chart-properties?, + style-graphic-properties?, + style-paragraph-properties?, + style-text-properties?) + table-table-template = + element table:table-template { + table-table-template-attlist, + table-first-row?, + table-last-row?, + table-first-column?, + table-last-column?, + table-body, + table-even-rows?, + table-odd-rows?, + table-even-columns?, + table-odd-columns?, + table-background?, + # TODO no proposal + table-first-row-even-column?, + table-last-row-even-column?, + table-first-row-end-column?, + table-first-row-start-column?, + table-last-row-end-column?, + table-last-row-start-column? + } + draw-frame = + element draw:frame { + common-draw-shape-with-text-and-styles-attlist, + common-draw-position-attlist, + common-draw-rel-size-attlist, + common-draw-caption-id-attlist, + presentation-shape-attlist, + draw-frame-attlist, + (draw-text-box + | draw-image + | draw-object + | draw-object-ole + | draw-applet + | draw-floating-frame + | draw-plugin + | table-table)*, + office-event-listeners?, + draw-glue-point*, + draw-image-map?, + svg-title?, + svg-desc?, + (draw-contour-polygon | draw-contour-path)?, + # TODO no proposal + loext-signatureline?, + loext-qrcode? + } + common-value-and-type-attlist = + (attribute office:value-type { "float" }, + attribute calcext:value-type { "float" }?, + attribute office:value { double }) + | (attribute office:value-type { "percentage" }, + attribute calcext:value-type { "percentage" }?, + attribute office:value { double }) + | (attribute office:value-type { "currency" }, + attribute calcext:value-type { "currency" }?, + attribute office:value { double }, + attribute office:currency { \string }?) + | (attribute office:value-type { "date" }, + attribute calcext:value-type { "date" }?, + attribute office:date-value { dateOrDateTime }) + | (attribute office:value-type { "time" }, + attribute calcext:value-type { "time" }?, + attribute office:time-value { duration }) + | (attribute office:value-type { "boolean" }, + attribute calcext:value-type { "boolean" }?, + attribute office:boolean-value { boolean }) + | (attribute office:value-type { "string" }, + # OFFICE-3759 + attribute calcext:value-type { "string" | "error" }?, + attribute office:string-value { \string }?) + chart-axis = + element chart:axis { + chart-axis-attlist, + # OFFICE-2119 + ((attribute chartooo:axis-type { "auto" }, + chartooo-date-scale?) + | (attribute chartooo:axis-type { "date" }, + chartooo-date-scale) + | attribute chartooo:axis-type { "text" })?, + chart-title?, + chart-categories?, + chart-grid* + } + table-table = + element table:table { + table-table-attlist, + table-title?, + table-desc?, + # TODO add to proposal, OFFICE-2112 + table-table-protection?, + table-table-source?, + office-dde-source?, + table-scenario?, + office-forms?, + table-shapes?, + table-columns-and-groups, + table-rows-and-groups, + table-named-expressions?, + # TODO no proposal, this is wild guessing, OFFICE-3785 + element calcext:conditional-formats { + element calcext:conditional-format { + attribute calcext:target-range-address { cellRangeAddress }, + (element calcext:condition { + attribute calcext:apply-style-name { styleNameRef }, + attribute calcext:value { \string }, + attribute calcext:base-cell-address { cellAddress } + }+ + | element calcext:data-bar { + attribute calcext:max-length { \string }, + attribute calcext:negative-color { color }, + attribute calcext:positive-color { color }, + attribute calcext:axis-color { color }, + attribute calcext:axis-position { "middle" }?, + element calcext:formatting-entry { + attribute calcext:value { \string }, + attribute calcext:type { + "auto-minimum" + | "auto-maximum" + | "minimum" + | "maximum" + | "percent" + | "percentile" + | "number" + | "formula" + } + }, + element calcext:formatting-entry { + attribute calcext:value { \string }, + attribute calcext:type { + "auto-minimum" + | "auto-maximum" + | "minimum" + | "maximum" + | "percent" + | "percentile" + | "number" + | "formula" + } + } + } + | element calcext:color-scale { + element calcext:color-scale-entry { + attribute calcext:value { \string }, + attribute calcext:type { + "minimum" + | "maximum" + | "percent" + | "percentile" + | "number" + | "formula" + }, + attribute calcext:color { color } + }, + element calcext:color-scale-entry { + attribute calcext:value { \string }, + attribute calcext:type { + "minimum" + | "maximum" + | "percent" + | "percentile" + | "number" + | "formula" + }, + attribute calcext:color { color } + }, + element calcext:color-scale-entry { + attribute calcext:value { \string }, + attribute calcext:type { + "minimum" + | "maximum" + | "percent" + | "percentile" + | "number" + | "formula" + }, + attribute calcext:color { color } + }? + }) + }+ + }? + } + # TODO no proposal + draw-object = + element draw:object { + draw-object-attlist, + loext-text, + (common-draw-data-attlist | office-document | math-math) + } + draw-object-ole = + element draw:object-ole { + draw-object-ole-attlist, + loext-text, + (common-draw-data-attlist | office-binary-data) + } + # FIXME: one test exports 250 here, which is probably a bug + fontWeight = + "normal" + | "bold" + | "100" + | "200" + | "250" + | "300" + | "400" + | "500" + | "600" + | "700" + | "800" + | "900" +} +# TODO no proposal +loext-p = + element loext:p { paragraph-attrs, paragraph-content-or-hyperlink* } +loext-text = (loext-p | text-list | loext-table)* +# OFFICE-2119 +chartooo-date-scale = + element chartooo:date-scale { + attribute chart:base-time-unit { chart-time-unit }? + & (attribute chart:major-interval-value { positiveInteger }, + attribute chart:major-interval-unit { chart-time-unit })? + & (attribute chart:minor-interval-value { positiveInteger }, + attribute chart:minor-interval-unit { chart-time-unit })? + } +chart-time-unit = "days" | "months" | "years" +# TODO no proposal +loext-signatureline = + element loext:signatureline { + attribute loext:id { \string }, + attribute loext:suggested-signer-name { \string }, + attribute loext:suggested-signer-title { \string }, + attribute loext:suggested-signer-email { \string }, + attribute loext:signing-instructions { \string }, + attribute loext:show-sign-date { boolean }, + attribute loext:can-add-comment { boolean } + } +loext-qrcode = + element loext:qrcode { + attribute office:string-value { \string }, + attribute loext:qrcode-errorcorrection { + "low" | "medium" | "quartile" | "high" + }, + attribute loext:qrcode-border { nonNegativeInteger } + } +# https://issues.oasis-open.org/browse/OFFICE-3761 +loext-table = + element loext:table { + table-table-attlist, + table-title?, + table-desc?, + table-table-source?, + office-dde-source?, + table-scenario?, + office-forms?, + table-shapes?, + loext-columns-and-groups, + loext-rows-and-groups, + table-named-expressions? + } +loext-rows-and-groups = (table-table-row-group | loext-rows-no-group)+ +loext-rows-no-group = + (loext-rows, (table-table-header-rows, loext-rows?)?) + | (table-table-header-rows, loext-rows?) +loext-rows = + table-table-rows | (text-soft-page-break?, loext-table-row)+ +loext-table-row = + element loext:table-row { + table-table-row-attlist, + (loext-table-cell | loext-covered-table-cell)+ + } +loext-table-cell = + element loext:table-cell { + table-table-cell-attlist, + table-table-cell-attlist-extra, + table-table-cell-content + } +loext-covered-table-cell = + element loext:covered-table-cell { + table-table-cell-attlist, table-table-cell-content + } +loext-columns-and-groups = + (table-table-column-group | loext-columns-no-group)+ +loext-columns-no-group = + (loext-columns, (table-table-header-columns, loext-columns?)?) + | (table-table-header-columns, loext-columns?) +loext-columns = loext-table-columns | loext-table-column+ +loext-table-columns = + element loext:table-columns { loext-table-column+ } +loext-table-column = + element loext:table-column { table-table-column-attlist, empty } +loext-graphic-properties = + element loext:graphic-properties { + style-graphic-properties-content-strict + } +table-first-row-even-column = + element loext:first-row-even-column { + common-table-template-attlist, empty + } +table-last-row-even-column = + element loext:last-row-even-column { + common-table-template-attlist, empty + } +table-first-row-end-column = + element loext:first-row-end-column { + common-table-template-attlist, empty + } +table-first-row-start-column = + element loext:first-row-start-column { + common-table-template-attlist, empty + } +table-last-row-end-column = + element loext:last-row-end-column { + common-table-template-attlist, empty + } +table-last-row-start-column = + element loext:last-row-start-column { + common-table-template-attlist, empty + } +common-draw-rel-size-attlist &= + # OFFICE-3854 + attribute loext:rel-width-rel { + "page" + | [ + # TODO layout-environment ? + + ] + "paragraph" + }?, + attribute loext:rel-height-rel { "page" | "paragraph" }? +common-svg-font-face-xlink-attlist &= + # TODO no proposal + attribute loext:font-style { fontStyle }?, + attribute loext:font-weight { fontWeight }? +# TODO no proposal + +# there's no ref-attrs so add it here +text-common-ref-content &= + attribute loext:reference-language { language }? +style-list-level-label-alignment-attlist &= + # TODO no proposal + attribute loext:label-followed-by { + "listtab" | "space" | "nothing" | "newline" + }? +style-ruby-properties-attlist &= + # TODO proposal, OFFICE-3944 + attribute loext:ruby-position { + "above" | "below" | "inter-character" + }? +style-text-properties-attlist &= + # TODO no proposal + attribute officeooo:rsid { \string }?, + attribute officeooo:paragraph-rsid { \string }?, + # https://issues.oasis-open.org/browse/OFFICE-4049 + attribute loext:opacity { zeroToHundredPercent }? +style-text-properties-attlist &= + # OFFICE-3843 + attribute loext:padding { nonNegativeLength }?, + attribute loext:padding-left { nonNegativeLength }?, + attribute loext:padding-right { nonNegativeLength }?, + attribute loext:padding-top { nonNegativeLength }?, + attribute loext:padding-bottom { nonNegativeLength }?, + attribute loext:border { \string }?, + attribute loext:border-left { \string }?, + attribute loext:border-right { \string }?, + attribute loext:border-top { \string }?, + attribute loext:border-bottom { \string }?, + attribute loext:shadow { shadowType }? +# TODO no proposal +style-chart-properties-attlist &= + attribute loext:try-staggering-first { boolean }? +# TODO no proposal +style-chart-properties-attlist &= + attribute loext:std-weight { \string }? +# TODO no proposal +chart-series-attlist &= attribute loext:label-string { \string }? +# OFFICE-1148 +style-chart-properties-attlist &= + attribute loext:regression-max-degree { positiveInteger }?, + attribute loext:regression-force-intercept { boolean }?, + attribute loext:regression-intercept-value { double }?, + attribute loext:regression-name { \string }?, + attribute loext:regression-period { \string }?, + attribute loext:regression-extrapolate-forward { \string }?, + attribute loext:regression-extrapolate-backward { \string }? +# TODO no proposal +table-data-pilot-field-attlist &= + attribute tableooo:display-name { \string }? +# TODO no proposal, 9009663d +chart-chart-attlist &= attribute loext:data-pilot-source { \string }? +# OFFICE-2112, TODO half of this missing in proposal +table-table-protection = + element loext:table-protection { + attribute loext:select-protected-cells { boolean }?, + attribute loext:select-unprotected-cells { boolean }?, + attribute loext:insert-columns { boolean }?, + attribute loext:insert-rows { boolean }?, + attribute loext:delete-columns { boolean }?, + attribute loext:delete-rows { boolean }? + } +office-spreadsheet-attlist &= + attribute loext:protection-key-digest-algorithm-2 { anyURI }? +table-table-attlist &= + attribute loext:protection-key-digest-algorithm-2 { anyURI }? +# https://issues.oasis-open.org/browse/OFFICE-2317 +vertJustifyValues = "auto" | "distribute" +common-text-justify = + attribute css3t:text-justify { vertJustifyValues }? +style-vertical-justify = + attribute loext:vertical-justify { vertJustifyValues }?, + attribute style:vertical-justify { vertJustifyValues }? +style-paragraph-properties-attlist &= + (common-text-justify, style-vertical-justify)? +style-table-cell-properties-attlist &= + (common-text-justify, style-vertical-justify)? +number-fraction-attlist &= + # OFFICE-3695 + + # TODO no proposal, 1544a26ac9f7dd60605dd21e9cbe29d490aafdce + attribute loext:max-numerator-digits { positiveInteger }? +# TODO no proposal +table-data-pilot-level-attlist &= + attribute calcext:repeat-item-labels { boolean }? +# TODO no proposal +draw-enhanced-geometry-attlist &= + attribute drawooo:sub-view-size { \string }?, + attribute drawooo:enhanced-path { \string }? +# TODO no proposal +draw-custom-shape-attlist &= common-draw-rel-size-attlist +# TODO no proposal +style-page-layout-properties-attlist &= + style-graphic-fill-properties-attlist +style-header-footer-properties-attlist &= + style-graphic-fill-properties-attlist +# TODO no proposal +text-index-entry-tab-stop-attrs &= attribute style:with-tab { boolean }? +# TODO no proposal +style-text-properties-attlist &= + attribute loext:char-shading-value { \string }? +# TODO no proposal +text-bookmark-start-attlist &= + (attribute loext:hidden { boolean }, + attribute loext:condition { \string }?)? +# TODO no proposal; see 7a5d79f2297a43d0a854e304b0792164272edfe0 + +# FIXME this is almost certainly incomplete: need to figure out which elements can have this and which named pattern can be extended with it to get exactly these elements +form-checkbox-attlist &= attribute form:input-required { boolean }? +# https://issues.oasis-open.org/browse/OFFICE-4030 +common-writing-mode-attlist &= attribute loext:writing-mode { "bt-lr" }? +# https://issues.oasis-open.org/browse/OFFICE-4073 +common-vertical-rel-attlist &= + attribute loext:vertical-rel { + "page-content-top" | "page-content-bottom" + }? +# https://issues.oasis-open.org/browse/OFFICE-4105 +style-page-layout-properties-attlist &= + attribute loext:margin-gutter { length }? +# just a test-case for user-defined attributes, move along, nothing to see here... +style-table-cell-properties-attlist &= attribute proName { \string }? +# TODO no proposal +chart-data-point-attlist &= + attribute loext:custom-label-field { \string }? +# TODO no proposal +style-text-properties-attlist &= + attribute loext:hyphenation-no-caps { boolean }? +# TODO no proposal +chart-data-point-attlist &= + (attribute loext:custom-label-pos-x { double }, + attribute loext:custom-label-pos-y { double })? +# TODO no proposal +chart-legend-attlist &= attribute loext:overlay { boolean }? +# https://issues.oasis-open.org/browse/OFFICE-3936 +style-chart-properties-attlist &= + attribute loext:major-origin { double }? +# TODO no proposal +text-index-entry-chapter-attrs &= + attribute loext:outline-content-visible { boolean }? +# https://issues.oasis-open.org/browse/OFFICE-2096 +paragraph-content |= + element field:fieldmark-start { + attribute text:name { \string }, + attribute field:type { + # TODO + \string + }, + element field:param { + attribute field:name { \string }, + attribute field:value { \string } + }* + } +paragraph-content |= element field:fieldmark-end { empty } +paragraph-content |= + element field:fieldmark { + attribute text:name { \string }, + attribute field:type { + # TODO + \string + }, + element field:param { + attribute field:name { \string }, + attribute field:value { \string } + }* + } +# TODO no proposal +animation-element |= + element loext:animatePhysics { + common-anim-target-attlist, + common-timing-attlist, + animate-physics-attlist + } +animate-physics-attlist = + # default value: 0 + attribute loext:velocity-x { double }?, + # default value: 0 + attribute loext:velocity-y { double }?, + # default value: 0.1 + attribute loext:bounciness { + xsd:double { minInclusive = "0" maxInclusive = "1" } + }?, + # default value: 1 + attribute loext:density { + xsd:double { minInclusive = "0" } + }? +# TODO no proposal +style-chart-properties-attlist &= + attribute loext:custom-leader-lines { boolean }? +# TODO no proposal +style-chart-properties-attlist &= + attribute loext:external-data { \string }? diff --git a/etc/schema/od-schema-v1.2-os.rnc b/etc/schema/OpenDocument-schema-v1.3.rnc similarity index 96% rename from etc/schema/od-schema-v1.2-os.rnc rename to etc/schema/OpenDocument-schema-v1.3.rnc index 8d679d62e4..2a7867998f 100644 --- a/etc/schema/od-schema-v1.2-os.rnc +++ b/etc/schema/OpenDocument-schema-v1.3.rnc @@ -1,33 +1,16 @@ -# Open Document Format for Office Applications (OpenDocument) Version 1.2 -# OASIS Standard, 29 September 2011 -# Relax-NG Schema -# Source: http://docs.oasis-open.org/office/v1.2/os/ -# Copyright (c) OASIS Open 2002-2011, 2013. All Rights Reserved. +# Open Document Format for Office Applications (OpenDocument) Version 1.3 +# Committee Specification 02 +# 30 October 2020 +# Copyright (c) OASIS Open 2020. All Rights Reserved. +# Source: https://docs.oasis-open.org/office/OpenDocument/v1.3/cs02/schemas/ +# Latest stage of specification: https://docs.oasis-open.org/office/OpenDocument/v1.3/OpenDocument-v1.3-part1-introduction.html +# TC IPR Statement: https://www.oasis-open.org/committees/office/ipr.php # -# All capitalized terms in the following text have the meanings assigned to them -# in the OASIS Intellectual Property Rights Policy (the "OASIS IPR Policy"). The -# full Policy may be found at the OASIS website. -# -# This document and translations of it may be copied and furnished to others, and -# derivative works that comment on or otherwise explain it or assist in its -# implementation may be prepared, copied, published, and distributed, in whole or -# in part, without restriction of any kind, provided that the above copyright -# notice and this section are included on all such copies and derivative works. -# However, this document itself may not be modified in any way, including by -# removing the copyright notice or references to OASIS, except as needed for the -# purpose of developing any document or deliverable produced by an OASIS -# Technical Committee (in which case the rules applicable to copyrights, as set -# forth in the OASIS IPR Policy, must be followed) or as required to translate it -# into languages other than English. -# -# The limited permissions granted above are perpetual and will not be revoked by -# OASIS or its successors or assigns. -# -# This document and the information contained herein is provided on an "AS IS" -# basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT -# LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT -# INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR -# FITNESS FOR A PARTICULAR PURPOSE. +# Open Document Format for Office Applications (OpenDocument) Version 1.3 +# Relax-NG Schema +# OpenDocument-v1.3-schema.rng + +# https://issues.oasis-open.org/browse/OFFICE-2153 namespace anim = "urn:oasis:names:tc:opendocument:xmlns:animation:1.0" namespace chart = "urn:oasis:names:tc:opendocument:xmlns:chart:1.0" @@ -46,6 +29,7 @@ namespace number = "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" namespace office = "urn:oasis:names:tc:opendocument:xmlns:office:1.0" namespace presentation = "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" +namespace rng = "http://relaxng.org/ns/structure/1.0" namespace script = "urn:oasis:names:tc:opendocument:xmlns:script:1.0" namespace smil = "urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0" @@ -58,2090 +42,1874 @@ namespace xforms = "http://www.w3.org/2002/xforms" namespace xhtml = "http://www.w3.org/1999/xhtml" namespace xlink = "http://www.w3.org/1999/xlink" -office-process-content = attribute office:process-content { boolean }? start = office-document | office-document-content | office-document-styles | office-document-meta | office-document-settings -office-document = - element office:document { - office-document-attrs, - office-document-common-attrs, - office-meta, - office-settings, - office-scripts, - office-font-face-decls, - office-styles, - office-automatic-styles, - office-master-styles, - office-body - } -office-document-content = - element office:document-content { - office-document-common-attrs, - office-scripts, - office-font-face-decls, - office-automatic-styles, - office-body - } -office-document-styles = - element office:document-styles { - office-document-common-attrs, - office-font-face-decls, - office-styles, - office-automatic-styles, - office-master-styles - } -office-document-meta = - element office:document-meta { - office-document-common-attrs, office-meta - } -office-document-settings = - element office:document-settings { - office-document-common-attrs, office-settings +CURIE = + xsd:string { pattern = "(([\i-[:]][\c-[:]]*)?:)?.+" minLength = "1" } +CURIEs = list { CURIE+ } +ID = xsd:ID +IDREF = xsd:IDREF +IDREFS = xsd:IDREFS +NCName = xsd:NCName +SafeCURIE = + xsd:string { + pattern = "\[(([\i-[:]][\c-[:]]*)?:)?.+\]" + minLength = "3" } -office-document-common-attrs = - attribute office:version { "1.2" } - & attribute grddl:transformation { - list { anyIRI* } +URIorSafeCURIE = anyURI | SafeCURIE +angle = xsd:string +anim-animate-color-attlist = + attribute anim:color-interpolation { "rgb" | "hsl" }? + & attribute anim:color-interpolation-direction { + "clockwise" | "counter-clockwise" }? -office-document-attrs = attribute office:mimetype { \string } -office-meta = element office:meta { office-meta-content-strict }? -office-meta-content-strict = office-meta-data* -office-body = element office:body { office-body-content } -office-body-content = - element office:text { - office-text-attlist, - office-text-content-prelude, - office-text-content-main, - office-text-content-epilogue +anim-animate-motion-attlist = + attribute svg:path { pathData }? + & attribute svg:origin { \string }? + & attribute smil:calcMode { + "discrete" | "linear" | "paced" | "spline" + }? +anim-animate-transform-attlist = + attribute svg:type { + "translate" | "scale" | "rotate" | "skewX" | "skewY" } - | element office:drawing { - office-drawing-attlist, - office-drawing-content-prelude, - office-drawing-content-main, - office-drawing-content-epilogue +anim-audio-attlist = + attribute xlink:href { anyIRI }? + & attribute anim:audio-level { double }? +anim-command-attlist = attribute anim:command { \string } +anim-iterate-attlist = + common-anim-target-attlist + & attribute anim:iterate-type { \string }? + & attribute anim:iterate-interval { duration }? +anim-transition-filter-attlist = + attribute smil:type { \string } + & attribute smil:subtype { \string }? + & attribute smil:direction { "forward" | "reverse" }? + & attribute smil:fadeColor { color }? + & attribute smil:mode { "in" | "out" }? +animation-element = + element anim:animate { + common-anim-target-attlist, + common-anim-named-target-attlist, + common-anim-values-attlist, + common-anim-spline-mode-attlist, + common-spline-anim-value-attlist, + common-timing-attlist, + common-anim-add-accum-attlist + } + | element anim:set { + common-anim-target-attlist, + common-anim-named-target-attlist, + common-anim-set-values-attlist, + common-timing-attlist, + common-anim-add-accum-attlist } - | element office:presentation { - office-presentation-attlist, - office-presentation-content-prelude, - office-presentation-content-main, - office-presentation-content-epilogue + | element anim:animateMotion { + anim-animate-motion-attlist, + common-anim-target-attlist, + common-anim-named-target-attlist, + common-anim-add-accum-attlist, + common-anim-values-attlist, + common-timing-attlist, + common-spline-anim-value-attlist } - | element office:spreadsheet { - office-spreadsheet-attlist, - office-spreadsheet-content-prelude, - office-spreadsheet-content-main, - office-spreadsheet-content-epilogue + | element anim:animateColor { + common-anim-target-attlist, + common-anim-named-target-attlist, + common-anim-add-accum-attlist, + common-anim-values-attlist, + common-anim-spline-mode-attlist, + common-spline-anim-value-attlist, + anim-animate-color-attlist, + common-timing-attlist } - | element office:chart { - office-chart-attlist, - office-chart-content-prelude, - office-chart-content-main, - office-chart-content-epilogue + | element anim:animateTransform { + common-anim-target-attlist, + common-anim-named-target-attlist, + common-anim-add-accum-attlist, + common-anim-values-attlist, + anim-animate-transform-attlist, + common-timing-attlist } - | element office:image { - office-image-attlist, - office-image-content-prelude, - office-image-content-main, - office-image-content-epilogue + | element anim:transitionFilter { + common-anim-target-attlist, + common-anim-add-accum-attlist, + common-anim-values-attlist, + common-anim-spline-mode-attlist, + anim-transition-filter-attlist, + common-timing-attlist } - | office-database -office-text-content-prelude = - office-forms, text-tracked-changes, text-decls, table-decls -office-text-content-main = - text-content* - | (text-page-sequence, (shape)*) -text-content = - text-h - | text-p - | text-list - | text-numbered-paragraph - | table-table - | text-section - | text-soft-page-break - | text-table-of-content - | text-illustration-index - | text-table-index - | text-object-index - | text-user-index - | text-alphabetical-index - | text-bibliography - | shape - | change-marks -office-text-content-epilogue = table-functions -office-text-attlist = - attribute text:global { boolean }? - & attribute text:use-soft-page-breaks { boolean }? -office-drawing-attlist = empty -office-drawing-content-prelude = text-decls, table-decls -office-drawing-content-main = draw-page* -office-drawing-content-epilogue = table-functions -office-presentation-attlist = empty -office-presentation-content-prelude = - text-decls, table-decls, presentation-decls -office-presentation-content-main = draw-page* -office-presentation-content-epilogue = - presentation-settings, table-functions -office-spreadsheet-content-prelude = - table-tracked-changes?, text-decls, table-decls -table-decls = - table-calculation-settings?, - table-content-validations?, - table-label-ranges? -office-spreadsheet-content-main = table-table* -office-spreadsheet-content-epilogue = table-functions -table-functions = - table-named-expressions?, - table-database-ranges?, - table-data-pilot-tables?, - table-consolidation?, - table-dde-links? -office-chart-attlist = empty -office-chart-content-prelude = text-decls, table-decls -office-chart-content-main = chart-chart -office-chart-content-epilogue = table-functions -office-image-attlist = empty -office-image-content-prelude = empty -office-image-content-main = draw-frame -office-image-content-epilogue = empty -office-settings = element office:settings { config-config-item-set+ }? -config-config-item-set = - element config:config-item-set { - config-config-item-set-attlist, config-items - } -config-items = - (config-config-item - | config-config-item-set - | config-config-item-map-named - | config-config-item-map-indexed)+ -config-config-item-set-attlist = attribute config:name { \string } -config-config-item = - element config:config-item { config-config-item-attlist, text } -config-config-item-attlist = - attribute config:name { \string } - & attribute config:type { - "boolean" - | "short" - | "int" - | "long" - | "double" - | "string" - | "datetime" - | "base64Binary" + | element anim:par { + common-anim-attlist, + common-timing-attlist, + common-endsync-timing-attlist, + animation-element* } -config-config-item-map-indexed = - element config:config-item-map-indexed { - config-config-item-map-indexed-attlist, - config-config-item-map-entry+ - } -config-config-item-map-indexed-attlist = - attribute config:name { \string } -config-config-item-map-entry = - element config:config-item-map-entry { - config-config-item-map-entry-attlist, config-items - } -config-config-item-map-entry-attlist = - attribute config:name { \string }? -config-config-item-map-named = - element config:config-item-map-named { - config-config-item-map-named-attlist, config-config-item-map-entry+ - } -config-config-item-map-named-attlist = attribute config:name { \string } -office-scripts = - element office:scripts { office-script*, office-event-listeners? }? -office-script = - element office:script { - office-script-attlist, - mixed { anyElements } - } -office-script-attlist = attribute script:language { \string } -office-font-face-decls = - element office:font-face-decls { style-font-face* }? -office-styles = - element office:styles { - styles - & style-default-style* - & style-default-page-layout? - & text-outline-style? - & text-notes-configuration* - & text-bibliography-configuration? - & text-linenumbering-configuration? - & draw-gradient* - & svg-linearGradient* - & svg-radialGradient* - & draw-hatch* - & draw-fill-image* - & draw-marker* - & draw-stroke-dash* - & draw-opacity* - & style-presentation-page-layout* - & table-table-template* - }? -office-automatic-styles = - element office:automatic-styles { styles & style-page-layout* }? -office-master-styles = - element office:master-styles { - style-master-page* & style-handout-master? & draw-layer-set? - }? -styles = - style-style* - & text-list-style* - & number-number-style* - & number-currency-style* - & number-percentage-style* - & number-date-style* - & number-time-style* - & number-boolean-style* - & number-text-style* -office-meta-data = - element meta:generator { \string } - | element dc:title { \string } - | element dc:description { \string } - | element dc:subject { \string } - | element meta:keyword { \string } - | element meta:initial-creator { \string } - | dc-creator - | element meta:printed-by { \string } - | element meta:creation-date { dateTime } - | dc-date - | element meta:print-date { dateTime } - | element meta:template { - attribute xlink:type { "simple" }, - attribute xlink:href { anyIRI }, - attribute xlink:actuate { "onRequest" }?, - attribute xlink:title { \string }?, - attribute meta:date { dateTime }? - } - | element meta:auto-reload { - (attribute xlink:type { "simple" }, - attribute xlink:href { anyIRI }, - attribute xlink:show { "replace" }?, - attribute xlink:actuate { "onLoad" }?)?, - attribute meta:delay { duration }? + | element anim:seq { + common-anim-attlist, + common-endsync-timing-attlist, + common-timing-attlist, + animation-element* } - | element meta:hyperlink-behaviour { - attribute office:target-frame-name { targetFrameName }?, - attribute xlink:show { "new" | "replace" }? + | element anim:iterate { + common-anim-attlist, + anim-iterate-attlist, + common-timing-attlist, + common-endsync-timing-attlist, + animation-element* } - | element dc:language { language } - | element meta:editing-cycles { nonNegativeInteger } - | element meta:editing-duration { duration } - | element meta:document-statistic { - attribute meta:page-count { nonNegativeInteger }?, - attribute meta:table-count { nonNegativeInteger }?, - attribute meta:draw-count { nonNegativeInteger }?, - attribute meta:image-count { nonNegativeInteger }?, - attribute meta:ole-object-count { nonNegativeInteger }?, - attribute meta:object-count { nonNegativeInteger }?, - attribute meta:paragraph-count { nonNegativeInteger }?, - attribute meta:word-count { nonNegativeInteger }?, - attribute meta:character-count { nonNegativeInteger }?, - attribute meta:frame-count { nonNegativeInteger }?, - attribute meta:sentence-count { nonNegativeInteger }?, - attribute meta:syllable-count { nonNegativeInteger }?, - attribute meta:non-whitespace-character-count { - nonNegativeInteger - }?, - attribute meta:row-count { nonNegativeInteger }?, - attribute meta:cell-count { nonNegativeInteger }? + | element anim:audio { + common-anim-attlist, + anim-audio-attlist, + common-basic-timing-attlist } - | element meta:user-defined { - attribute meta:name { \string }, - ((attribute meta:value-type { "float" }, - double) - | (attribute meta:value-type { "date" }, - dateOrDateTime) - | (attribute meta:value-type { "time" }, - duration) - | (attribute meta:value-type { "boolean" }, - boolean) - | (attribute meta:value-type { "string" }, - \string) - | text) + | element anim:command { + common-anim-attlist, + anim-command-attlist, + common-begin-end-timing-attlist, + common-anim-target-attlist, + element anim:param { + attribute anim:name { \string }, + attribute anim:value { \string } + }* } -dc-creator = element dc:creator { \string } -dc-date = element dc:date { dateTime } -text-h = - element text:h { - heading-attrs, - paragraph-attrs, - text-number?, - paragraph-content-or-hyperlink* +any-date = + number-day + | number-month + | number-year + | number-era + | number-day-of-week + | number-week-of-year + | number-quarter + | number-hours + | number-am-pm + | number-minutes + | number-seconds +any-number = number-number | number-scientific-number | number-fraction +any-time = number-hours | number-am-pm | number-minutes | number-seconds +anyAttListOrElements = + attribute * { text }*, + anyElements +anyElements = + element * { + mixed { anyAttListOrElements } + }* +anyIRI = + xsd:anyURI + >> dc:description [ + "An IRI-reference as defined in [RFC3987]. See ODF 1.3 Part 3 section 18.3." + ] +anyURI = xsd:anyURI +base64Binary = xsd:base64Binary +boolean = "true" | "false" +borderWidths = list { positiveLength, positiveLength, positiveLength } +bound-column = attribute form:bound-column { \string }? +button-type = attribute form:button-type { types }? +cellAddress = + xsd:string { + pattern = "($?([^\. ']+|'([^']|'')+'))?\.$?[A-Z]+$?[0-9]+" } -heading-attrs = - attribute text:outline-level { positiveInteger } - & attribute text:restart-numbering { boolean }? - & attribute text:start-value { nonNegativeInteger }? - & attribute text:is-list-header { boolean }? -text-number = element text:number { \string } -text-p = - element text:p { paragraph-attrs, paragraph-content-or-hyperlink* } -paragraph-attrs = - attribute text:style-name { styleNameRef }? - & attribute text:class-names { styleNameRefs }? - & attribute text:cond-style-name { styleNameRef }? - & (xml-id, - attribute text:id { NCName }?)? - & common-in-content-meta-attlist? -text-page-sequence = element text:page-sequence { text-page+ } -text-page = element text:page { text-page-attlist, empty } -text-page-attlist = attribute text:master-page-name { styleNameRef } -text-list = - element text:list { - text-list-attr, text-list-header?, text-list-item* +cellRangeAddress = + xsd:string { + pattern = + "($?([^\. ']+|'([^']|'')+'))?\.$?[A-Z]+$?[0-9]+(:($?([^\. ']+|'([^']|'')+'))?\.$?[A-Z]+$?[0-9]+)?" } -text-list-attr = - attribute text:style-name { styleNameRef }? - & attribute text:continue-numbering { boolean }? - & attribute text:continue-list { IDREF }? - & xml-id? -text-list-item = - element text:list-item { text-list-item-attr, text-list-item-content } -text-list-item-content = - text-number?, (text-p | text-h | text-list | text-soft-page-break)* -text-list-item-attr = - attribute text:start-value { nonNegativeInteger }? - & attribute text:style-override { styleNameRef }? - & xml-id? -text-list-header = - element text:list-header { - text-list-header-attr, text-list-item-content + | xsd:string { + pattern = + "($?([^\. ']+|'([^']|'')+'))?\.$?[0-9]+:($?([^\. ']+|'([^']|'')+'))?\.$?[0-9]+" + } + | xsd:string { + pattern = + "($?([^\. ']+|'([^']|'')+'))?\.$?[A-Z]+:($?([^\. ']+|'([^']|'')+'))?\.$?[A-Z]+" + } +cellRangeAddressList = + xsd:string + >> dc:description [ + 'Value is a space separated list of "cellRangeAddress" patterns' + ] +change-mark-attr = attribute text:change-id { IDREF } +change-marks = + element text:change { change-mark-attr } + | element text:change-start { change-mark-attr } + | element text:change-end { change-mark-attr } +character = xsd:string { length = "1" } +chart-axis = + element chart:axis { + chart-axis-attlist, chart-title?, chart-categories?, chart-grid* } -text-list-header-attr = xml-id? -text-numbered-paragraph = - element text:numbered-paragraph { - text-numbered-paragraph-attr, text-number?, (text-p | text-h) +chart-axis-attlist = + attribute chart:dimension { chart-dimension } + & attribute chart:name { \string }? + & attribute chart:style-name { styleNameRef }? +chart-categories = + element chart:categories { + attribute table:cell-range-address { cellRangeAddressList }? } -text-numbered-paragraph-attr = - attribute text:list-id { NCName } - & attribute text:level { positiveInteger }? - & (attribute text:style-name { styleNameRef }, - attribute text:continue-numbering { boolean }, - attribute text:start-value { nonNegativeInteger })? +chart-chart = + element chart:chart { + chart-chart-attlist, + chart-title?, + chart-subtitle?, + chart-footer?, + chart-legend?, + chart-plot-area, + shape*, + # https://issues.oasis-open.org/browse/OFFICE-2123 + table-table? + } +chart-chart-attlist = + attribute chart:class { namespacedToken } + & common-draw-size-attlist + & attribute chart:column-mapping { \string }? + & attribute chart:row-mapping { \string }? + & attribute chart:style-name { styleNameRef }? + & (attribute xlink:type { "simple" }, + attribute xlink:href { anyIRI })? & xml-id? -text-section = - element text:section { - text-section-attlist, - (text-section-source | text-section-source-dde | empty), - text-content* +chart-coordinate-region = + element chart:coordinate-region { + chart-coordinate-region-attlist, empty } -text-section-attlist = - common-section-attlist - & (attribute text:display { "true" | "none" } - | (attribute text:display { "condition" }, - attribute text:condition { \string }) +chart-coordinate-region-attlist = + common-draw-position-attlist, common-draw-size-attlist +# https://issues.oasis-open.org/browse/OFFICE-3928 +chart-data-label = + element chart:data-label { chart-data-label-attlist, text-p? } +chart-data-label-attlist = + common-draw-position-attlist + & attribute chart:style-name { styleNameRef }? +chart-data-point = + element chart:data-point { + chart-data-point-attlist, chart-data-label? + } +chart-data-point-attlist = + attribute chart:repeated { positiveInteger }? + & attribute chart:style-name { styleNameRef }? + & xml-id? +chart-dimension = "x" | "y" | "z" +chart-domain = + element chart:domain { + attribute table:cell-range-address { cellRangeAddressList }? + } +chart-equation = + element chart:equation { chart-equation-attlist, text-p? } +chart-equation-attlist = + attribute chart:automatic-content { boolean }? + & attribute chart:display-r-square { boolean }? + & attribute chart:display-equation { boolean }? + & common-draw-position-attlist + & attribute chart:style-name { styleNameRef }? +chart-error-indicator = + element chart:error-indicator { chart-error-indicator-attlist, empty } +chart-error-indicator-attlist = + attribute chart:style-name { styleNameRef }? + & attribute chart:dimension { chart-dimension } +chart-floor = element chart:floor { chart-floor-attlist, empty } +chart-floor-attlist = + attribute svg:width { length }? + & attribute chart:style-name { styleNameRef }? +chart-footer = element chart:footer { chart-title-attlist, text-p? } +chart-grid = element chart:grid { chart-grid-attlist } +chart-grid-attlist = + attribute chart:class { "major" | "minor" }? + & attribute chart:style-name { styleNameRef }? +chart-legend = element chart:legend { chart-legend-attlist, text-p? } +chart-legend-attlist = + ((attribute chart:legend-position { + "start" | "end" | "top" | "bottom" + }, + attribute chart:legend-align { "start" | "center" | "end" }?) + | attribute chart:legend-position { + "top-start" | "bottom-start" | "top-end" | "bottom-end" + } + | empty) + & common-draw-position-attlist + & (attribute style:legend-expansion { "wide" | "high" | "balanced" } + | (attribute style:legend-expansion { "custom" }, + attribute style:legend-expansion-aspect-ratio { double }, + common-draw-size-attlist + # https://issues.oasis-open.org/browse/OFFICE-3883 + ) | empty) -common-section-attlist = - attribute text:style-name { styleNameRef }? - & attribute text:name { \string } - & attribute text:protected { boolean }? - & attribute text:protection-key { \string }? - & attribute text:protection-key-digest-algorithm { anyIRI }? + & attribute chart:style-name { styleNameRef }? +chart-mean-value = + element chart:mean-value { chart-mean-value-attlist, empty } +chart-mean-value-attlist = attribute chart:style-name { styleNameRef }? +chart-plot-area = + element chart:plot-area { + chart-plot-area-attlist, + # https://issues.oasis-open.org/browse/OFFICE-3928 + chart-coordinate-region?, + dr3d-light*, + chart-axis*, + chart-series*, + chart-stock-gain-marker?, + chart-stock-loss-marker?, + chart-stock-range-line?, + chart-wall?, + chart-floor? + } +chart-plot-area-attlist = + common-draw-position-attlist + & common-draw-size-attlist + & attribute chart:style-name { styleNameRef }? + & attribute table:cell-range-address { cellRangeAddressList }? + & attribute chart:data-source-has-labels { + "none" | "row" | "column" | "both" + }? + & dr3d-scene-attlist + & common-dr3d-transform-attlist & xml-id? -text-section-source = - element text:section-source { text-section-source-attr } -text-section-source-attr = - (attribute xlink:type { "simple" }, - attribute xlink:href { anyIRI }, - attribute xlink:show { "embed" }?)? - & attribute text:section-name { \string }? - & attribute text:filter-name { \string }? -text-section-source-dde = office-dde-source -text-tracked-changes = - element text:tracked-changes { - text-tracked-changes-attr, text-changed-region* - }? -text-tracked-changes-attr = attribute text:track-changes { boolean }? -text-changed-region = - element text:changed-region { - text-changed-region-attr, text-changed-region-content +chart-regression-curve = + element chart:regression-curve { + chart-regression-curve-attlist, chart-equation? } -text-changed-region-attr = - xml-id, - attribute text:id { NCName }? -text-changed-region-content = - element text:insertion { office-change-info } - | element text:deletion { office-change-info, text-content* } - | element text:format-change { office-change-info } -change-marks = - element text:change { change-mark-attr } - | element text:change-start { change-mark-attr } - | element text:change-end { change-mark-attr } -change-mark-attr = attribute text:change-id { IDREF } -text-soft-page-break = element text:soft-page-break { empty } -text-decls = - element text:variable-decls { text-variable-decl* }?, - element text:sequence-decls { text-sequence-decl* }?, - element text:user-field-decls { text-user-field-decl* }?, - element text:dde-connection-decls { text-dde-connection-decl* }?, - text-alphabetical-index-auto-mark-file? -paragraph-content-or-hyperlink = paragraph-content | text-a -paragraph-content = - text - | element text:s { - attribute text:c { nonNegativeInteger }? +chart-regression-curve-attlist = + attribute chart:style-name { styleNameRef }? +chart-series = + element chart:series { + chart-series-attlist, + chart-domain*, + chart-mean-value?, + chart-regression-curve*, + chart-error-indicator*, + chart-data-point*, + chart-data-label? + } +chart-series-attlist = + attribute chart:values-cell-range-address { cellRangeAddressList }? + & attribute chart:label-cell-address { cellRangeAddressList }? + & attribute chart:class { namespacedToken }? + & attribute chart:attached-axis { \string }? + & attribute chart:style-name { styleNameRef }? + & xml-id? +chart-stock-gain-marker = + element chart:stock-gain-marker { common-stock-marker-attlist } +chart-stock-loss-marker = + element chart:stock-loss-marker { common-stock-marker-attlist } +chart-stock-range-line = + element chart:stock-range-line { common-stock-marker-attlist } +chart-subtitle = element chart:subtitle { chart-title-attlist, text-p? } +chart-title = element chart:title { chart-title-attlist, text-p? } +chart-title-attlist = + attribute table:cell-range { cellRangeAddressList }? + & common-draw-position-attlist + & attribute chart:style-name { styleNameRef }? +chart-wall = element chart:wall { chart-wall-attlist, empty } +chart-wall-attlist = + attribute svg:width { length }? + & attribute chart:style-name { styleNameRef }? +clipShape = + xsd:string { + pattern = + "rect\([ ]*((-?([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc)))|(auto))([ ]*,[ ]*((-?([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc))))|(auto)){3}[ ]*\)" + } +color = xsd:string { pattern = "#[0-9a-fA-F]{6}" } +column-controls = + element form:text { form-text-attlist, common-form-control-content } + | element form:textarea { + form-textarea-attlist, common-form-control-content, text-p* } - | element text:tab { text-tab-attr } - | element text:line-break { empty } - | text-soft-page-break - | element text:span { - attribute text:style-name { styleNameRef }?, - attribute text:class-names { styleNameRefs }?, - paragraph-content-or-hyperlink* + | element form:formatted-text { + form-formatted-text-attlist, common-form-control-content } - | element text:meta { - text-meta-attlist, paragraph-content-or-hyperlink* + | element form:number { + form-number-attlist, + common-numeric-control-attlist, + common-form-control-content, + common-linked-cell, + common-spin-button, + common-repeat, + common-delay-for-repeat } - | (text-bookmark | text-bookmark-start | text-bookmark-end) - | element text:reference-mark { - attribute text:name { \string } + | element form:date { + form-date-attlist, + common-numeric-control-attlist, + common-form-control-content, + common-linked-cell, + common-spin-button, + common-repeat, + common-delay-for-repeat } - | (element text:reference-mark-start { - attribute text:name { \string } - } - | element text:reference-mark-end { - attribute text:name { \string } - }) - | element text:note { - text-note-class, - attribute text:id { \string }?, - element text:note-citation { - attribute text:label { \string }?, - text - }, - element text:note-body { text-content* } - } - | element text:ruby { - attribute text:style-name { styleNameRef }?, - element text:ruby-base { paragraph-content-or-hyperlink* }, - element text:ruby-text { - attribute text:style-name { styleNameRef }?, - text - } - } - | (office-annotation | office-annotation-end) - | change-marks - | shape - | element text:date { text-date-attlist, text } - | element text:time { text-time-attlist, text } - | element text:page-number { text-page-number-attlist, text } - | element text:page-continuation { - text-page-continuation-attlist, text - } - | element text:sender-firstname { common-field-fixed-attlist, text } - | element text:sender-lastname { common-field-fixed-attlist, text } - | element text:sender-initials { common-field-fixed-attlist, text } - | element text:sender-title { common-field-fixed-attlist, text } - | element text:sender-position { common-field-fixed-attlist, text } - | element text:sender-email { common-field-fixed-attlist, text } - | element text:sender-phone-private { - common-field-fixed-attlist, text - } - | element text:sender-fax { common-field-fixed-attlist, text } - | element text:sender-company { common-field-fixed-attlist, text } - | element text:sender-phone-work { common-field-fixed-attlist, text } - | element text:sender-street { common-field-fixed-attlist, text } - | element text:sender-city { common-field-fixed-attlist, text } - | element text:sender-postal-code { common-field-fixed-attlist, text } - | element text:sender-country { common-field-fixed-attlist, text } - | element text:sender-state-or-province { - common-field-fixed-attlist, text - } - | element text:author-name { common-field-fixed-attlist, text } - | element text:author-initials { common-field-fixed-attlist, text } - | element text:chapter { text-chapter-attlist, text } - | element text:file-name { text-file-name-attlist, text } - | element text:template-name { text-template-name-attlist, text } - | element text:sheet-name { text } - | element text:variable-set { - (common-field-name-attlist - & common-field-formula-attlist - & common-value-and-type-attlist - & common-field-display-value-none-attlist - & common-field-data-style-name-attlist), - text - } - | element text:variable-get { - (common-field-name-attlist - & common-field-display-value-formula-attlist - & common-field-data-style-name-attlist), - text - } - | element text:variable-input { - (common-field-name-attlist - & common-field-description-attlist - & common-value-type-attlist - & common-field-display-value-none-attlist - & common-field-data-style-name-attlist), - text - } - | element text:user-field-get { - (common-field-name-attlist - & common-field-display-value-formula-none-attlist - & common-field-data-style-name-attlist), - text - } - | element text:user-field-input { - (common-field-name-attlist - & common-field-description-attlist - & common-field-data-style-name-attlist), - text - } - | element text:sequence { - (common-field-name-attlist - & common-field-formula-attlist - & common-field-num-format-attlist - & text-sequence-ref-name), - text - } - | element text:expression { - (common-field-formula-attlist - & common-value-and-type-attlist? - & common-field-display-value-formula-attlist - & common-field-data-style-name-attlist), - text - } - | element text:text-input { common-field-description-attlist, text } - | element text:initial-creator { common-field-fixed-attlist, text } - | element text:creation-date { - (common-field-fixed-attlist - & common-field-data-style-name-attlist - & attribute text:date-value { dateOrDateTime }?), - text - } - | element text:creation-time { - (common-field-fixed-attlist - & common-field-data-style-name-attlist - & attribute text:time-value { timeOrDateTime }?), - text - } - | element text:description { common-field-fixed-attlist, text } - | element text:user-defined { - (common-field-fixed-attlist - & attribute text:name { \string } - & common-field-data-style-name-attlist - & attribute office:value { double }? - & attribute office:date-value { dateOrDateTime }? - & attribute office:time-value { duration }? - & attribute office:boolean-value { boolean }? - & attribute office:string-value { \string }?), - text - } - | element text:print-time { - (common-field-fixed-attlist - & common-field-data-style-name-attlist - & attribute text:time-value { time }?), - text - } - | element text:print-date { - (common-field-fixed-attlist - & common-field-data-style-name-attlist - & attribute text:date-value { date }?), - text - } - | element text:printed-by { common-field-fixed-attlist, text } - | element text:title { common-field-fixed-attlist, text } - | element text:subject { common-field-fixed-attlist, text } - | element text:keywords { common-field-fixed-attlist, text } - | element text:editing-cycles { common-field-fixed-attlist, text } - | element text:editing-duration { - (common-field-fixed-attlist - & common-field-data-style-name-attlist - & attribute text:duration { duration }?), - text - } - | element text:modification-time { - (common-field-fixed-attlist - & common-field-data-style-name-attlist - & attribute text:time-value { time }?), - text - } - | element text:modification-date { - (common-field-fixed-attlist - & common-field-data-style-name-attlist - & attribute text:date-value { date }?), - text - } - | element text:creator { common-field-fixed-attlist, text } - | element text:page-count - | text:paragraph-count - | text:word-count - | text:character-count - | text:table-count - | text:image-count - | text:object-count { - common-field-num-format-attlist, text - } - | element text:database-display { - text-database-display-attlist, text - } - | element text:database-next { text-database-next-attlist } - | element text:database-row-select { - text-database-row-select-attlist - } - | element text:database-row-number { - (common-field-database-table - & common-field-num-format-attlist - & attribute text:value { nonNegativeInteger }?), - text - } - | element text:database-name { common-field-database-table, text } - | element text:page-variable-set { - text-set-page-variable-attlist, text - } - | element text:page-variable-get { - text-get-page-variable-attlist, text - } - | element text:placeholder { text-placeholder-attlist, text } - | element text:conditional-text { - text-conditional-text-attlist, text - } - | element text:hidden-text { text-hidden-text-attlist, text } - | element text:reference-ref | text:bookmark-ref { - text-common-ref-content & text-bookmark-ref-content - } - | element text:note-ref { - text-common-ref-content & text-note-ref-content - } - | element text:sequence-ref { - text-common-ref-content & text-sequence-ref-content - } - | element text:script { - ((attribute xlink:type { "simple" }, - attribute xlink:href { anyIRI }) - | text) - & attribute script:language { \string }? - } - | element text:execute-macro { - attribute text:name { \string }?, - office-event-listeners?, - text - } - | element text:hidden-paragraph { - text-hidden-paragraph-attlist, text - } - | element text:dde-connection { - attribute text:connection-name { \string }, - text - } - | element text:measure { - attribute text:kind { "value" | "unit" | "gap" }, - text - } - | element text:table-formula { - (common-field-formula-attlist - & common-field-display-value-formula-attlist - & common-field-data-style-name-attlist), - text - } - | element text:meta-field { - text-meta-field-attlist, paragraph-content-or-hyperlink* + | element form:time { + form-time-attlist, + common-numeric-control-attlist, + common-form-control-content, + common-linked-cell, + common-spin-button, + common-repeat, + common-delay-for-repeat } - | element text:toc-mark-start { text-toc-mark-start-attrs } - | element text:toc-mark-end { text-id } - | element text:toc-mark { - attribute text:string-value { \string }, - text-outline-level + | element form:combobox { + form-combobox-attlist, common-form-control-content, form-item* } - | element text:user-index-mark-start { - text-id, text-outline-level, text-index-name + | element form:listbox { + form-listbox-attlist, common-form-control-content, form-option* } - | element text:user-index-mark-end { text-id } - | element text:user-index-mark { - attribute text:string-value { \string }, - text-outline-level, - text-index-name + | element form:checkbox { + form-checkbox-attlist, common-form-control-content } - | element text:alphabetical-index-mark-start { - text-id, text-alphabetical-index-mark-attrs - } - | element text:alphabetical-index-mark-end { text-id } - | element text:alphabetical-index-mark { - attribute text:string-value { \string }, - text-alphabetical-index-mark-attrs - } - | element text:bibliography-mark { - attribute text:bibliography-type { text-bibliography-types }, - attribute text:identifier - | text:address - | text:annote - | text:author - | text:booktitle - | text:chapter - | text:edition - | text:editor - | text:howpublished - | text:institution - | text:journal - | text:month - | text:note - | text:number - | text:organizations - | text:pages - | text:publisher - | text:school - | text:series - | text:title - | text:report-type - | text:volume - | text:year - | text:url - | text:custom1 - | text:custom2 - | text:custom3 - | text:custom4 - | text:custom5 - | text:isbn - | text:issn { \string }*, - text - } - | element presentation:header { empty } - | element presentation:footer { empty } - | element presentation:date-time { empty } -text-tab-attr = attribute text:tab-ref { nonNegativeInteger }? -text-a = - element text:a { - text-a-attlist, office-event-listeners?, paragraph-content* - } -text-a-attlist = - attribute office:name { \string }? - & attribute office:title { \string }? - & attribute xlink:type { "simple" } - & attribute xlink:href { anyIRI } - & attribute xlink:actuate { "onRequest" }? - & attribute office:target-frame-name { targetFrameName }? - & attribute xlink:show { "new" | "replace" }? - & attribute text:style-name { styleNameRef }? - & attribute text:visited-style-name { styleNameRef }? -text-meta-attlist = common-in-content-meta-attlist? & xml-id? -text-bookmark = element text:bookmark { text-bookmark-attlist, empty } -text-bookmark-start = - element text:bookmark-start { text-bookmark-start-attlist, empty } -text-bookmark-end = - element text:bookmark-end { text-bookmark-end-attlist, empty } -text-bookmark-attlist = - attribute text:name { \string } - & xml-id? -text-bookmark-start-attlist = - attribute text:name { \string } - & xml-id? - & common-in-content-meta-attlist? -text-bookmark-end-attlist = attribute text:name { \string } -text-note-class = attribute text:note-class { "footnote" | "endnote" } -text-date-attlist = - (common-field-fixed-attlist & common-field-data-style-name-attlist) - & attribute text:date-value { dateOrDateTime }? - & attribute text:date-adjust { duration }? -text-time-attlist = - (common-field-fixed-attlist & common-field-data-style-name-attlist) - & attribute text:time-value { timeOrDateTime }? - & attribute text:time-adjust { duration }? -text-page-number-attlist = - (common-field-num-format-attlist & common-field-fixed-attlist) - & attribute text:page-adjust { integer }? - & attribute text:select-page { "previous" | "current" | "next" }? -text-page-continuation-attlist = - attribute text:select-page { "previous" | "next" } - & attribute text:string-value { \string }? -text-chapter-attlist = - attribute text:display { - "name" - | "number" - | "number-and-name" - | "plain-number-and-name" - | "plain-number" - } - & attribute text:outline-level { nonNegativeInteger } -text-file-name-attlist = - attribute text:display { - "full" | "path" | "name" | "name-and-extension" +common-anim-add-accum-attlist = + attribute smil:accumulate { "none" | "sum" }? + & attribute smil:additive { "replace" | "sum" }? +common-anim-attlist = + attribute presentation:node-type { + "default" + | "on-click" + | "with-previous" + | "after-previous" + | "timing-root" + | "main-sequence" + | "interactive-sequence" }? - & common-field-fixed-attlist -text-template-name-attlist = - attribute text:display { - "full" | "path" | "name" | "name-and-extension" | "area" | "title" + & attribute presentation:preset-id { \string }? + & attribute presentation:preset-sub-type { \string }? + & attribute presentation:preset-class { + "custom" + | "entrance" + | "exit" + | "emphasis" + | "motion-path" + | "ole-action" + | "media-call" + }? + & attribute presentation:master-element { IDREF }? + & attribute presentation:group-id { \string }? + & (xml-id, + attribute anim:id { NCName }?)? +common-anim-named-target-attlist = + attribute smil:attributeName { \string } +common-anim-set-values-attlist = attribute smil:to { \string }? +common-anim-spline-mode-attlist = + attribute smil:calcMode { + "discrete" | "linear" | "paced" | "spline" }? -text-variable-decl = - element text:variable-decl { - common-field-name-attlist, common-value-type-attlist - } -text-user-field-decl = - element text:user-field-decl { - common-field-name-attlist, - common-field-formula-attlist?, - common-value-and-type-attlist - } -text-sequence-decl = - element text:sequence-decl { text-sequence-decl-attlist } -text-sequence-decl-attlist = - common-field-name-attlist - & attribute text:display-outline-level { nonNegativeInteger } - & attribute text:separation-character { character }? -text-sequence-ref-name = attribute text:ref-name { \string }? -common-field-database-table = - common-field-database-table-attlist, common-field-database-name -common-field-database-name = - attribute text:database-name { \string }? - | form-connection-resource -common-field-database-table-attlist = - attribute text:table-name { \string } - & attribute text:table-type { "table" | "query" | "command" }? -text-database-display-attlist = - common-field-database-table - & common-field-data-style-name-attlist - & attribute text:column-name { \string } -text-database-next-attlist = - common-field-database-table - & attribute text:condition { \string }? -text-database-row-select-attlist = - common-field-database-table - & attribute text:condition { \string }? - & attribute text:row-number { nonNegativeInteger }? -text-set-page-variable-attlist = - attribute text:active { boolean }? - & attribute text:page-adjust { integer }? -text-get-page-variable-attlist = common-field-num-format-attlist -text-placeholder-attlist = - attribute text:placeholder-type { - "text" | "table" | "text-box" | "image" | "object" - } - & common-field-description-attlist -text-conditional-text-attlist = - attribute text:condition { \string } - & attribute text:string-value-if-true { \string } - & attribute text:string-value-if-false { \string } - & attribute text:current-value { boolean }? -text-hidden-text-attlist = - attribute text:condition { \string } - & attribute text:string-value { \string } - & attribute text:is-hidden { boolean }? -text-common-ref-content = - text - & attribute text:ref-name { \string }? -text-bookmark-ref-content = - attribute text:reference-format { - common-ref-format-values - | "number-no-superior" - | "number-all-superior" - | "number" +common-anim-target-attlist = + attribute smil:targetElement { IDREF }? + & attribute anim:sub-item { \string }? +common-anim-values-attlist = + attribute smil:values { \string }? + & attribute anim:formula { \string }? + & common-anim-set-values-attlist + & attribute smil:from { \string }? + & attribute smil:by { \string }? +common-auto-reorder-attlist = + attribute number:automatic-order { boolean }? +common-background-color-attlist = + attribute fo:background-color { "transparent" | color }? +common-background-transparency-attlist = + attribute style:background-transparency { zeroToHundredPercent }? +common-basic-timing-attlist = + common-begin-end-timing-attlist, + common-dur-timing-attlist, + common-repeat-timing-attlist, + common-restart-timing-attlist, + common-restart-default-attlist, + common-fill-timing-attlist, + common-fill-default-attlist +common-begin-end-timing-attlist = + attribute smil:begin { \string }? + & attribute smil:end { \string }? +common-border-attlist = + attribute fo:border { \string }?, + attribute fo:border-top { \string }?, + attribute fo:border-bottom { \string }?, + attribute fo:border-left { \string }?, + attribute fo:border-right { \string }? +common-border-line-width-attlist = + attribute style:border-line-width { borderWidths }?, + attribute style:border-line-width-top { borderWidths }?, + attribute style:border-line-width-bottom { borderWidths }?, + attribute style:border-line-width-left { borderWidths }?, + attribute style:border-line-width-right { borderWidths }? +common-break-attlist = + attribute fo:break-before { "auto" | "column" | "page" }?, + attribute fo:break-after { "auto" | "column" | "page" }? +common-calendar-attlist = + attribute number:calendar { + "gregorian" + | "gengou" + | "ROC" + | "hanja_yoil" + | "hanja" + | "hijri" + | "jewish" + | "buddhist" + | \string }? -text-note-ref-content = - attribute text:reference-format { common-ref-format-values }? - & text-note-class -text-sequence-ref-content = - attribute text:reference-format { - common-ref-format-values - | "category-and-value" - | "caption" - | "value" - }? -common-ref-format-values = "page" | "chapter" | "direction" | "text" -text-hidden-paragraph-attlist = - attribute text:condition { \string } - & attribute text:is-hidden { boolean }? -text-meta-field-attlist = xml-id & common-field-data-style-name-attlist -common-value-type-attlist = attribute office:value-type { valueType } -common-value-and-type-attlist = - (attribute office:value-type { "float" }, - attribute office:value { double }) - | (attribute office:value-type { "percentage" }, - attribute office:value { double }) - | (attribute office:value-type { "currency" }, - attribute office:value { double }, - attribute office:currency { \string }?) - | (attribute office:value-type { "date" }, - attribute office:date-value { dateOrDateTime }) - | (attribute office:value-type { "time" }, - attribute office:time-value { duration }) - | (attribute office:value-type { "boolean" }, - attribute office:boolean-value { boolean }) - | (attribute office:value-type { "string" }, - attribute office:string-value { \string }?) -common-field-fixed-attlist = attribute text:fixed { boolean }? -common-field-name-attlist = attribute text:name { variableName } +common-contour-attlist = attribute draw:recreate-on-edit { boolean } +common-control-id-attlist = + xml-id, + attribute form:id { NCName }? +common-convert-empty-attlist = + attribute form:convert-empty-to-null { boolean }? +common-current-value-attlist = attribute form:current-value { \string }? +common-data-field-attlist = attribute form:data-field { \string }? +common-data-style-attlist = + attribute style:name { styleName } + & attribute style:display-name { \string }? + & attribute number:language { languageCode }? + & attribute number:country { countryCode }? + & attribute number:script { scriptCode }? + & attribute number:rfc-language-tag { language }? + & attribute number:title { \string }? + & attribute style:volatile { boolean }? + & attribute number:transliteration-format { \string }? + & attribute number:transliteration-language { countryCode }? + & attribute number:transliteration-country { countryCode }? + & attribute number:transliteration-style { + "short" | "medium" | "long" + }? +common-db-default-value = common-value-and-type-attlist? +common-db-object-description = attribute db:description { \string }? +common-db-object-name = attribute db:name { \string } +common-db-object-title = attribute db:title { \string }? +common-db-table-name-attlist = + attribute db:name { \string } + & attribute db:catalog-name { \string }? + & attribute db:schema-name { \string }? +common-db-table-style-name = + attribute db:style-name { styleNameRef }? + & attribute db:default-row-style-name { styleNameRef }? +common-dde-connection-decl-attlist = + attribute office:dde-application { \string } + & attribute office:dde-topic { \string } + & attribute office:dde-item { \string } + & attribute office:automatic-update { boolean }? +common-decimal-places-attlist = + attribute number:decimal-places { integer }?, + (attribute number:min-decimal-places { integer }?) + # https://issues.oasis-open.org/browse/OFFICE-3860 added number:min-decimal-places + +common-delay-for-repeat = attribute form:delay-for-repeat { duration }? +common-disabled-attlist = attribute form:disabled { boolean }? +common-dr3d-transform-attlist = attribute dr3d:transform { \string }? +common-draw-area-attlist = + (attribute xlink:type { "simple" }, + attribute xlink:href { anyIRI }, + attribute office:target-frame-name { targetFrameName }?, + attribute xlink:show { "new" | "replace" }?)? + & attribute office:name { \string }? + & attribute draw:nohref { "nohref" }? +common-draw-caption-id-attlist = attribute draw:caption-id { IDREF }? +common-draw-circle-ellipse-attlist = + attribute draw:kind { "full" | "section" | "cut" | "arc" }? + & attribute draw:start-angle { angle }? + & attribute draw:end-angle { angle }? +common-draw-circle-ellipse-pos-attlist = + attribute svg:cx { coordinate }, + attribute svg:cy { coordinate } +common-draw-data-attlist = + attribute xlink:type { "simple" }, + attribute xlink:href { anyIRI }, + attribute xlink:show { "embed" }?, + attribute xlink:actuate { "onLoad" }? +common-draw-gradient-attlist = + attribute draw:name { styleName }? + & attribute draw:display-name { \string }? + & attribute draw:style { gradient-style } + & attribute draw:cx { percent }? + & attribute draw:cy { percent }? + & attribute draw:angle { angle }? + & attribute draw:border { percent }? +common-draw-id-attlist = + (xml-id, + attribute draw:id { NCName }?)? +common-draw-layer-name-attlist = attribute draw:layer { \string }? +common-draw-mime-type-attlist = attribute draw:mime-type { \string }? +# https://issues.oasis-open.org/browse/OFFICE-3943 +common-draw-name-attlist = attribute draw:name { \string }? +common-draw-path-data-attlist = attribute svg:d { pathData } +common-draw-points-attlist = attribute draw:points { points } +common-draw-position-attlist = + attribute svg:x { coordinate }?, + attribute svg:y { coordinate }? +common-draw-rel-size-attlist = + common-draw-size-attlist, + attribute style:rel-width { percent | "scale" | "scale-min" }?, + attribute style:rel-height { percent | "scale" | "scale-min" }? +common-draw-shape-with-styles-attlist = + common-draw-z-index-attlist, + common-draw-id-attlist, + common-draw-layer-name-attlist, + common-draw-style-name-attlist, + common-draw-transform-attlist, + common-draw-name-attlist, + common-text-spreadsheet-shape-attlist +common-draw-shape-with-text-and-styles-attlist = + common-draw-shape-with-styles-attlist, + common-draw-text-style-name-attlist +common-draw-size-attlist = + attribute svg:width { length }?, + attribute svg:height { length }? +common-draw-style-name-attlist = + (attribute draw:style-name { styleNameRef }?, + attribute draw:class-names { styleNameRefs }?) + | (attribute presentation:style-name { styleNameRef }?, + attribute presentation:class-names { styleNameRefs }?) +common-draw-text-style-name-attlist = + attribute draw:text-style-name { styleNameRef }? +common-draw-transform-attlist = attribute draw:transform { \string }? +common-draw-viewbox-attlist = + attribute svg:viewBox { + list { integer, integer, integer, integer } + } +common-draw-z-index-attlist = + attribute draw:z-index { nonNegativeInteger }? +common-dur-timing-attlist = attribute smil:dur { \string }? +common-editable-attlist = attribute style:editable { boolean }? +common-endsync-timing-attlist = + attribute smil:endsync { "first" | "last" | "all" | "media" | IDREF }? +common-field-data-style-name-attlist = + attribute style:data-style-name { styleNameRef }? +common-field-database-name = + attribute text:database-name { \string }? + | form-connection-resource +common-field-database-table = + common-field-database-table-attlist, common-field-database-name +common-field-database-table-attlist = + attribute text:table-name { \string } + & attribute text:table-type { "table" | "query" | "command" }? common-field-description-attlist = attribute text:description { \string }? -common-field-display-value-none-attlist = - attribute text:display { "value" | "none" }? -common-field-display-value-formula-none-attlist = - attribute text:display { "value" | "formula" | "none" }? common-field-display-value-formula-attlist = attribute text:display { "value" | "formula" }? +common-field-display-value-formula-none-attlist = + attribute text:display { "value" | "formula" | "none" }? +common-field-display-value-none-attlist = + attribute text:display { "value" | "none" }? +common-field-fixed-attlist = attribute text:fixed { boolean }? common-field-formula-attlist = attribute text:formula { \string }? -common-field-data-style-name-attlist = - attribute style:data-style-name { styleNameRef }? +common-field-name-attlist = attribute text:name { variableName } common-field-num-format-attlist = common-num-format-attlist? -text-toc-mark-start-attrs = text-id, text-outline-level -text-outline-level = attribute text:outline-level { positiveInteger }? -text-id = attribute text:id { \string } -text-index-name = attribute text:index-name { \string } -text-alphabetical-index-mark-attrs = - attribute text:key1 { \string }? - & attribute text:key2 { \string }? - & attribute text:string-value-phonetic { \string }? - & attribute text:key1-phonetic { \string }? - & attribute text:key2-phonetic { \string }? - & attribute text:main-entry { boolean }? -text-bibliography-types = - "article" - | "book" - | "booklet" - | "conference" - | "custom1" - | "custom2" - | "custom3" - | "custom4" - | "custom5" - | "email" - | "inbook" - | "incollection" - | "inproceedings" - | "journal" - | "manual" - | "mastersthesis" - | "misc" - | "phdthesis" - | "proceedings" - | "techreport" - | "unpublished" - | "www" -text-index-body = element text:index-body { index-content-main* } -index-content-main = text-content | text-index-title -text-index-title = - element text:index-title { - common-section-attlist, index-content-main* - } -text-table-of-content = - element text:table-of-content { - common-section-attlist, - text-table-of-content-source, - text-index-body - } -text-table-of-content-source = - element text:table-of-content-source { - text-table-of-content-source-attlist, - text-index-title-template?, - text-table-of-content-entry-template*, - text-index-source-styles* - } -text-table-of-content-source-attlist = - attribute text:outline-level { positiveInteger }? - & attribute text:use-outline-level { boolean }? - & attribute text:use-index-marks { boolean }? - & attribute text:use-index-source-styles { boolean }? - & attribute text:index-scope { "document" | "chapter" }? - & attribute text:relative-tab-stop-position { boolean }? -text-table-of-content-entry-template = - element text:table-of-content-entry-template { - text-table-of-content-entry-template-attlist, - text-table-of-content-children* - } -text-table-of-content-children = - text-index-entry-chapter - | text-index-entry-page-number - | text-index-entry-text - | text-index-entry-span - | text-index-entry-tab-stop - | text-index-entry-link-start - | text-index-entry-link-end -text-table-of-content-entry-template-attlist = - attribute text:outline-level { positiveInteger } - & attribute text:style-name { styleNameRef } -text-illustration-index = - element text:illustration-index { - common-section-attlist, - text-illustration-index-source, - text-index-body - } -text-illustration-index-source = - element text:illustration-index-source { - text-illustration-index-source-attrs, - text-index-title-template?, - text-illustration-index-entry-template? - } -text-illustration-index-source-attrs = - text-index-scope-attr - & text-relative-tab-stop-position-attr - & attribute text:use-caption { boolean }? - & attribute text:caption-sequence-name { \string }? - & attribute text:caption-sequence-format { - "text" | "category-and-value" | "caption" +common-fill-default-attlist = + attribute smil:fillDefault { + "remove" | "freeze" | "hold" | "transition" | "auto" | "inherit" + }? +common-fill-timing-attlist = + attribute smil:fill { + "remove" | "freeze" | "hold" | "auto" | "default" | "transition" + }? +common-form-control-attlist = + attribute form:name { \string }? + & attribute form:control-implementation { namespacedToken }? +common-form-control-content = form-properties?, office-event-listeners? +common-form-relative-image-position-attlist = + attribute form:image-position { "center" }? + | (attribute form:image-position { + "start" | "end" | "top" | "bottom" + }, + attribute form:image-align { "start" | "center" | "end" }?) +common-form-visual-effect-attlist = + attribute form:visual-effect { "flat" | "3d" }? +common-format-source-attlist = + attribute number:format-source { "fixed" | "language" }? +common-horizontal-margin-attlist = + attribute fo:margin-left { length | percent }?, + attribute fo:margin-right { length | percent }? +common-in-content-meta-attlist = + attribute xhtml:about { URIorSafeCURIE }, + attribute xhtml:property { CURIEs }, + common-meta-literal-attlist +common-keep-with-next-attlist = + attribute fo:keep-with-next { "auto" | "always" }? +common-linked-cell = + attribute form:linked-cell { cellAddress | \string }? +common-margin-attlist = + attribute fo:margin { nonNegativeLength | percent }? +common-maxlength-attlist = + attribute form:max-length { nonNegativeInteger }? +common-meta-literal-attlist = + attribute xhtml:datatype { CURIE }?, + attribute xhtml:content { \string }? +common-num-format-attlist = + attribute style:num-format { "1" | "i" | "I" | \string | empty } + | (attribute style:num-format { "a" | "A" }, + style-num-letter-sync-attlist) + | empty +common-num-format-prefix-suffix-attlist = + attribute style:num-prefix { \string }?, + attribute style:num-suffix { \string }? +common-number-attlist = + attribute number:min-integer-digits { integer }? + & attribute number:grouping { boolean }? +common-numeric-control-attlist = + form-control-attlist, + common-disabled-attlist, + common-maxlength-attlist, + common-printable-attlist, + common-readonly-attlist, + common-tab-attlist, + common-title-attlist, + common-convert-empty-attlist, + common-data-field-attlist +common-office-annotation-name-attlist = + attribute office:name { \string } +common-padding-attlist = + attribute fo:padding { nonNegativeLength }?, + attribute fo:padding-top { nonNegativeLength }?, + attribute fo:padding-bottom { nonNegativeLength }?, + attribute fo:padding-left { nonNegativeLength }?, + attribute fo:padding-right { nonNegativeLength }? +common-page-number-attlist = + attribute style:page-number { + (nonNegativeInteger | "auto") + # https://issues.oasis-open.org/browse/OFFICE-3923 + + }? +common-presentation-effect-attlist = + attribute draw:shape-id { IDREF } + & attribute presentation:effect { presentationEffects }? + & attribute presentation:direction { presentationEffectDirections }? + & attribute presentation:speed { presentationSpeeds }? + & attribute presentation:delay { duration }? + & attribute presentation:start-scale { percent }? + & attribute presentation:path-id { \string }? +common-presentation-header-footer-attlist = + attribute presentation:use-header-name { \string }? + & attribute presentation:use-footer-name { \string }? + & attribute presentation:use-date-time-name { \string }? +common-printable-attlist = attribute form:printable { boolean }? +common-readonly-attlist = attribute form:readonly { boolean }? +common-ref-format-values = "page" | "chapter" | "direction" | "text" +common-repeat = attribute form:repeat { boolean }? +common-repeat-timing-attlist = + attribute smil:repeatDur { \string }?, + attribute smil:repeatCount { nonNegativeDecimal | "indefinite" }? +common-restart-default-attlist = + attribute smil:restartDefault { + "never" | "always" | "whenNotActive" | "inherit" + }? +common-restart-timing-attlist = + attribute smil:restart { + "never" | "always" | "whenNotActive" | "default" + }? +common-rotation-angle-attlist = + attribute style:rotation-angle { angle }? +common-section-attlist = + attribute text:style-name { styleNameRef }? + & attribute text:name { \string } + & attribute text:protected { boolean }? + & attribute text:protection-key { \string }? + & attribute text:protection-key-digest-algorithm { anyIRI }? + & xml-id? +common-shadow-attlist = attribute style:shadow { shadowType }? +common-source-cell-range = + attribute form:source-cell-range { cellRangeAddress | \string }? +common-spin-button = attribute form:spin-button { boolean }? +common-spline-anim-value-attlist = + attribute smil:keyTimes { \string }? + & attribute smil:keySplines { \string }? +common-stock-marker-attlist = + attribute chart:style-name { styleNameRef }? +common-style-direction-attlist = + attribute style:direction { "ltr" | "ttb" }? +common-style-header-footer-attlist = + attribute style:display { boolean }? +common-svg-font-face-xlink-attlist = + attribute xlink:type { "simple" }, + attribute xlink:href { anyIRI }, + attribute xlink:actuate { "onRequest" }? +common-svg-gradient-attlist = + attribute svg:gradientUnits { "objectBoundingBox" }? + & attribute svg:gradientTransform { \string }? + & attribute svg:spreadMethod { "pad" | "reflect" | "repeat" }? + & attribute draw:name { styleName } + & attribute draw:display-name { \string }? +common-tab-attlist = + attribute form:tab-index { nonNegativeInteger }? + & attribute form:tab-stop { boolean }? +common-table-cell-address-attlist = + attribute table:column { integer }, + attribute table:row { integer }, + attribute table:table { integer } +common-table-cell-range-address-attlist = + attribute table:start-column { integer }, + attribute table:start-row { integer }, + attribute table:start-table { integer }, + attribute table:end-column { integer }, + attribute table:end-row { integer }, + attribute table:end-table { integer } +common-table-change-attlist = + attribute table:id { \string } + & attribute table:acceptance-state { + "accepted" | "rejected" | "pending" }? -text-index-scope-attr = - attribute text:index-scope { "document" | "chapter" }? -text-relative-tab-stop-position-attr = - attribute text:relative-tab-stop-position { boolean }? -text-illustration-index-entry-template = - element text:illustration-index-entry-template { - text-illustration-index-entry-content + & attribute table:rejecting-change-id { \string }? +common-table-range-attlist = + common-table-cell-address-attlist + | common-table-cell-range-address-attlist +common-table-template-attlist = + attribute table:style-name { styleNameRef }, + attribute table:paragraph-style-name { styleNameRef }? +common-text-align = + attribute fo:text-align { + "start" | "end" | "left" | "right" | "center" | "justify" + }? +common-text-anchor-attlist = + attribute text:anchor-type { + "page" | "frame" | "paragraph" | "char" | "as-char" + }? + & attribute text:anchor-page-number { positiveInteger }? +common-text-spreadsheet-shape-attlist = + attribute table:end-cell-address { cellAddress }? + & attribute table:end-x { coordinate }? + & attribute table:end-y { coordinate }? + & attribute table:table-background { boolean }? + & common-text-anchor-attlist +common-time-manip-attlist = + attribute smil:accelerate { zeroToOneDecimal }? + & attribute smil:decelerate { zeroToOneDecimal }? + & attribute smil:autoReverse { boolean }? +common-timing-attlist = + common-basic-timing-attlist, common-time-manip-attlist +common-title-attlist = attribute form:title { \string }? +common-value-and-type-attlist = + (attribute office:value-type { "float" }, + attribute office:value { double }) + | (attribute office:value-type { "percentage" }, + attribute office:value { double }) + | (attribute office:value-type { "currency" }, + attribute office:value { double }, + attribute office:currency { \string }?) + | (attribute office:value-type { "date" }, + attribute office:date-value { dateOrDateTime }) + | (attribute office:value-type { "time" }, + attribute office:time-value { duration }) + | (attribute office:value-type { "boolean" }, + attribute office:boolean-value { boolean }) + | (attribute office:value-type { "string" }, + attribute office:string-value { \string }?) +common-value-attlist = attribute form:value { \string }? +common-value-type-attlist = attribute office:value-type { valueType } +common-vertical-margin-attlist = + attribute fo:margin-top { nonNegativeLength | percent }?, + attribute fo:margin-bottom { nonNegativeLength | percent }? +common-vertical-pos-attlist = + attribute style:vertical-pos { + "top" | "middle" | "bottom" | "from-top" | "below" + }?, + attribute svg:y { coordinate }? +common-vertical-rel-attlist = + attribute style:vertical-rel { + "page" + | "page-content" + | "frame" + | "frame-content" + | "paragraph" + | "paragraph-content" + | "char" + | "line" + | "baseline" + | "text" + }? +common-writing-mode-attlist = + attribute style:writing-mode { + "lr-tb" | "rl-tb" | "tb-rl" | "tb-lr" | "lr" | "rl" | "tb" | "page" + }? +config-config-item = + element config:config-item { config-config-item-attlist, text } +config-config-item-attlist = + attribute config:name { \string } + & attribute config:type { + "boolean" + | "short" + | "int" + | "long" + | "double" + | "string" + | "datetime" + | "base64Binary" + } +config-config-item-map-entry = + element config:config-item-map-entry { + config-config-item-map-entry-attlist, config-items } -text-illustration-index-entry-content = - text-illustration-index-entry-template-attrs, - (text-index-entry-chapter - | text-index-entry-page-number - | text-index-entry-text - | text-index-entry-span - | text-index-entry-tab-stop)* -text-illustration-index-entry-template-attrs = - attribute text:style-name { styleNameRef } -text-table-index = - element text:table-index { - common-section-attlist, text-table-index-source, text-index-body - } -text-table-index-source = - element text:table-index-source { - text-illustration-index-source-attrs, - text-index-title-template?, - text-table-index-entry-template? +config-config-item-map-entry-attlist = + attribute config:name { \string }? +config-config-item-map-indexed = + element config:config-item-map-indexed { + config-config-item-map-indexed-attlist, + config-config-item-map-entry+ } -text-table-index-entry-template = - element text:table-index-entry-template { - text-illustration-index-entry-content +config-config-item-map-indexed-attlist = + attribute config:name { \string } +config-config-item-map-named = + element config:config-item-map-named { + config-config-item-map-named-attlist, config-config-item-map-entry+ } -text-object-index = - element text:object-index { - common-section-attlist, text-object-index-source, text-index-body +config-config-item-map-named-attlist = attribute config:name { \string } +config-config-item-set = + element config:config-item-set { + config-config-item-set-attlist, config-items } -text-object-index-source = - element text:object-index-source { - text-object-index-source-attrs, - text-index-title-template?, - text-object-index-entry-template? +config-config-item-set-attlist = attribute config:name { \string } +config-items = + (config-config-item + | config-config-item-set + | config-config-item-map-named + | config-config-item-map-indexed)+ +controls = + column-controls + | element form:password { + form-password-attlist, common-form-control-content + } + | element form:file { form-file-attlist, common-form-control-content } + | element form:fixed-text { + form-fixed-text-attlist, common-form-control-content + } + | element form:button { + form-button-attlist, common-form-control-content + } + | element form:image { + form-image-attlist, common-form-control-content + } + | element form:radio { + form-radio-attlist, common-form-control-content + } + | element form:frame { + form-frame-attlist, common-form-control-content + } + | element form:image-frame { + form-image-frame-attlist, common-form-control-content + } + | element form:hidden { + form-hidden-attlist, common-form-control-content + } + | element form:grid { + form-grid-attlist, common-form-control-content, form-column* + } + | element form:value-range { + form-value-range-attlist, common-form-control-content + } + | element form:generic-control { + form-generic-control-attlist, common-form-control-content + } +coordinate = length +countryCode = xsd:token { pattern = "[A-Za-z0-9]{1,8}" } +currency-symbol-and-text = + number-currency-symbol, + number-text-with-fillchar + # https://issues.oasis-open.org/browse/OFFICE-3765 + ? +current-selected = attribute form:current-selected { boolean }? +custom-shape-type = "non-primitive" | \string +date = xsd:date +dateOrDateTime = xsd:date | xsd:dateTime +dateTime = xsd:dateTime +db-application-connection-settings = + element db:application-connection-settings { + db-application-connection-settings-attlist, + db-table-filter?, + db-table-type-filter?, + db-data-source-settings? } -text-object-index-source-attrs = - text-index-scope-attr - & text-relative-tab-stop-position-attr - & attribute text:use-spreadsheet-objects { boolean }? - & attribute text:use-math-objects { boolean }? - & attribute text:use-draw-objects { boolean }? - & attribute text:use-chart-objects { boolean }? - & attribute text:use-other-objects { boolean }? -text-object-index-entry-template = - element text:object-index-entry-template { - text-illustration-index-entry-content +db-application-connection-settings-attlist = + attribute db:is-table-name-length-limited { boolean }? + & attribute db:enable-sql92-check { boolean }? + & attribute db:append-table-alias-name { boolean }? + & attribute db:ignore-driver-privileges { boolean }? + & attribute db:boolean-comparison-mode { + "equal-integer" + | "is-boolean" + | "equal-boolean" + | "equal-use-only-zero" + }? + & attribute db:use-catalog { boolean }? + & attribute db:max-row-count { integer }? + & attribute db:suppress-version-columns { boolean }? +db-apply-command = attribute db:apply-command { boolean }? +db-auto-increment = + element db:auto-increment { db-auto-increment-attlist, empty } +db-auto-increment-attlist = + attribute db:additional-column-statement { \string }? + & attribute db:row-retrieving-statement { \string }? +db-character-set = + element db:character-set { db-character-set-attlist, empty } +db-character-set-attlist = attribute db:encoding { textEncoding }? +db-column = + element db:column { + db-column-attlist, + common-db-object-name, + common-db-object-title, + common-db-object-description, + common-db-default-value } -text-user-index = - element text:user-index { - common-section-attlist, text-user-index-source, text-index-body +db-column-attlist = + attribute db:visible { boolean }? + & attribute db:style-name { styleNameRef }? + & attribute db:default-cell-style-name { styleNameRef }? +db-column-definition = + element db:column-definition { + db-column-definition-attlist, common-db-default-value } -text-user-index-source = - element text:user-index-source { - text-user-index-source-attr, - text-index-title-template?, - text-user-index-entry-template*, - text-index-source-styles* +db-column-definition-attlist = + attribute db:name { \string } + & attribute db:data-type { db-data-types }? + & attribute db:type-name { \string }? + & attribute db:precision { positiveInteger }? + & attribute db:scale { positiveInteger }? + & attribute db:is-nullable { "no-nulls" | "nullable" }? + & attribute db:is-empty-allowed { boolean }? + & attribute db:is-autoincrement { boolean }? +db-column-definitions = + element db:column-definitions { + db-column-definitions-attlist, db-column-definition+ } -text-user-index-source-attr = - text-index-scope-attr - & text-relative-tab-stop-position-attr - & attribute text:use-index-marks { boolean }? - & attribute text:use-index-source-styles { boolean }? - & attribute text:use-graphics { boolean }? - & attribute text:use-tables { boolean }? - & attribute text:use-floating-frames { boolean }? - & attribute text:use-objects { boolean }? - & attribute text:copy-outline-levels { boolean }? - & attribute text:index-name { \string } -text-user-index-entry-template = - element text:user-index-entry-template { - text-user-index-entry-template-attrs, - (text-index-entry-chapter - | text-index-entry-page-number - | text-index-entry-text - | text-index-entry-span - | text-index-entry-tab-stop)* +db-column-definitions-attlist = empty +db-columns = element db:columns { db-columns-attlist, db-column+ } +db-columns-attlist = empty +db-command = attribute db:command { \string } +db-component = + element db:component { + db-component-attlist, + common-db-object-name, + common-db-object-title, + common-db-object-description, + (office-document | math-math)? } -text-user-index-entry-template-attrs = - attribute text:outline-level { positiveInteger } - & attribute text:style-name { styleNameRef } -text-alphabetical-index = - element text:alphabetical-index { - common-section-attlist, - text-alphabetical-index-source, - text-index-body +db-component-attlist = + (attribute xlink:type { "simple" }, + attribute xlink:href { anyIRI }, + attribute xlink:show { "none" }?, + attribute xlink:actuate { "onRequest" }?)? + & attribute db:as-template { boolean }? +db-component-collection = + element db:component-collection { + db-component-collection-attlist, + common-db-object-name, + common-db-object-title, + common-db-object-description, + (db-component | db-component-collection)* } -text-alphabetical-index-source = - element text:alphabetical-index-source { - text-alphabetical-index-source-attrs, - text-index-title-template?, - text-alphabetical-index-entry-template* +db-component-collection-attlist = empty +db-connection-data = + element db:connection-data { + db-connection-data-attlist, + (db-database-description | db-connection-resource), + db-login? } -text-alphabetical-index-source-attrs = - text-index-scope-attr - & text-relative-tab-stop-position-attr - & attribute text:ignore-case { boolean }? - & attribute text:main-entry-style-name { styleNameRef }? - & attribute text:alphabetical-separators { boolean }? - & attribute text:combine-entries { boolean }? - & attribute text:combine-entries-with-dash { boolean }? - & attribute text:combine-entries-with-pp { boolean }? - & attribute text:use-keys-as-entries { boolean }? - & attribute text:capitalize-entries { boolean }? - & attribute text:comma-separated { boolean }? - & attribute fo:language { languageCode }? - & attribute fo:country { countryCode }? - & attribute fo:script { scriptCode }? - & attribute style:rfc-language-tag { language }? - & attribute text:sort-algorithm { \string }? -text-alphabetical-index-auto-mark-file = - element text:alphabetical-index-auto-mark-file { - attribute xlink:type { "simple" }, - attribute xlink:href { anyIRI } +db-connection-data-attlist = empty +db-connection-resource = + element db:connection-resource { + db-connection-resource-attlist, empty } -text-alphabetical-index-entry-template = - element text:alphabetical-index-entry-template { - text-alphabetical-index-entry-template-attrs, - (text-index-entry-chapter - | text-index-entry-page-number - | text-index-entry-text - | text-index-entry-span - | text-index-entry-tab-stop)* +db-connection-resource-attlist = + attribute xlink:type { "simple" }, + attribute xlink:href { anyIRI }, + attribute xlink:show { "none" }?, + attribute xlink:actuate { "onRequest" }? +db-data-source = + element db:data-source { + db-data-source-attlist, + db-connection-data, + db-driver-settings?, + db-application-connection-settings? } -text-alphabetical-index-entry-template-attrs = - attribute text:outline-level { "1" | "2" | "3" | "separator" } - & attribute text:style-name { styleNameRef } -text-bibliography = - element text:bibliography { - common-section-attlist, text-bibliography-source, text-index-body +db-data-source-attlist = empty +db-data-source-setting = + element db:data-source-setting { + db-data-source-setting-attlist, db-data-source-setting-value+ } -text-bibliography-source = - element text:bibliography-source { - text-index-title-template?, text-bibliography-entry-template* +db-data-source-setting-attlist = + attribute db:data-source-setting-is-list { boolean }? + & attribute db:data-source-setting-name { \string } + & attribute db:data-source-setting-type { + db-data-source-setting-types + } +db-data-source-setting-types = + "boolean" | "short" | "int" | "long" | "double" | "string" +db-data-source-setting-value = + element db:data-source-setting-value { + db-data-source-setting-value-attlist, \string } -text-bibliography-entry-template = - element text:bibliography-entry-template { - text-bibliography-entry-template-attrs, - (text-index-entry-span - | text-index-entry-tab-stop - | text-index-entry-bibliography)* +db-data-source-setting-value-attlist = empty +db-data-source-settings = + element db:data-source-settings { + db-data-source-settings-attlist, db-data-source-setting+ } -text-bibliography-entry-template-attrs = - attribute text:bibliography-type { text-bibliography-types } - & attribute text:style-name { styleNameRef } -text-index-source-styles = - element text:index-source-styles { - attribute text:outline-level { positiveInteger }, - text-index-source-style* +db-data-source-settings-attlist = empty +db-data-types = + "bit" + | "boolean" + | "tinyint" + | "smallint" + | "integer" + | "bigint" + | "float" + | "real" + | "double" + | "numeric" + | "decimal" + | "char" + | "varchar" + | "longvarchar" + | "date" + | "time" + | "timestmp" + | "binary" + | "varbinary" + | "longvarbinary" + | "sqlnull" + | "other" + | "object" + | "distinct" + | "struct" + | "array" + | "blob" + | "clob" + | "ref" +db-database-description = + element db:database-description { + db-database-description-attlist, + (db-file-based-database | db-server-database) } -text-index-source-style = - element text:index-source-style { - attribute text:style-name { styleName }, - empty +db-database-description-attlist = empty +db-delimiter = element db:delimiter { db-delimiter-attlist, empty } +db-delimiter-attlist = + attribute db:field { \string }? + & attribute db:string { \string }? + & attribute db:decimal { \string }? + & attribute db:thousand { \string }? +db-driver-settings = + element db:driver-settings { + db-driver-settings-attlist, + db-auto-increment?, + db-delimiter?, + db-character-set?, + db-table-settings? } -text-index-title-template = - element text:index-title-template { - attribute text:style-name { styleNameRef }?, - text +db-driver-settings-attlist = + db-show-deleted + & attribute db:system-driver-settings { \string }? + & attribute db:base-dn { \string }? + & db-is-first-row-header-line + & attribute db:parameter-name-substitution { boolean }? +db-file-based-database = + element db:file-based-database { db-file-based-database-attlist } +db-file-based-database-attlist = + attribute xlink:type { "simple" } + & attribute xlink:href { anyIRI } + & attribute db:media-type { \string } + & attribute db:extension { \string }? +db-filter-statement = + element db:filter-statement { db-command, db-apply-command, empty } +db-forms = + element db:forms { + db-forms-attlist, (db-component | db-component-collection)* } -text-index-entry-chapter = - element text:index-entry-chapter { - attribute text:style-name { styleNameRef }?, - text-index-entry-chapter-attrs +db-forms-attlist = empty +db-host-and-port = + attribute db:hostname { \string }, + attribute db:port { positiveInteger }? +db-index = element db:index { db-index-attlist, db-index-columns+ } +db-index-attlist = + attribute db:name { \string } + & attribute db:catalog-name { \string }? + & attribute db:is-unique { boolean }? + & attribute db:is-clustered { boolean }? +db-index-column = + element db:index-column { db-index-column-attlist, empty } +db-index-column-attlist = + attribute db:name { \string } + & attribute db:is-ascending { boolean }? +db-index-columns = element db:index-columns { db-index-column+ } +db-indices = element db:indices { db-indices-attlist, db-index+ } +db-indices-attlist = empty +db-is-first-row-header-line = + attribute db:is-first-row-header-line { boolean }? +db-key = element db:key { db-key-attlist, db-key-columns+ } +db-key-attlist = + attribute db:name { \string }? + & attribute db:type { "primary" | "unique" | "foreign" } + & attribute db:referenced-table-name { \string }? + & attribute db:update-rule { + "cascade" | "restrict" | "set-null" | "no-action" | "set-default" + }? + & attribute db:delete-rule { + "cascade" | "restrict" | "set-null" | "no-action" | "set-default" + }? +db-key-column = element db:key-column { db-key-column-attlist, empty } +db-key-column-attlist = + attribute db:name { \string }? + & attribute db:related-column-name { \string }? +db-key-columns = + element db:key-columns { db-key-columns-attlist, db-key-column+ } +db-key-columns-attlist = empty +db-keys = element db:keys { db-keys-attlist, db-key+ } +db-keys-attlist = empty +db-local-socket-name = attribute db:local-socket { \string }? +db-login = element db:login { db-login-attlist, empty } +db-login-attlist = + (attribute db:user-name { \string } + | attribute db:use-system-user { boolean })? + & attribute db:is-password-required { boolean }? + & attribute db:login-timeout { positiveInteger }? +db-order-statement = + element db:order-statement { db-command, db-apply-command, empty } +db-queries = + element db:queries { + db-queries-attlist, (db-query | db-query-collection)* } -text-index-entry-chapter-attrs = - attribute text:display { - "name" - | "number" - | "number-and-name" - | "plain-number" - | "plain-number-and-name" - }? - & attribute text:outline-level { positiveInteger }? -text-index-entry-text = - element text:index-entry-text { - attribute text:style-name { styleNameRef }? +db-queries-attlist = empty +db-query = + element db:query { + db-query-attlist, + common-db-object-name, + common-db-object-title, + common-db-object-description, + common-db-table-style-name, + db-order-statement?, + db-filter-statement?, + db-columns?, + db-update-table? } -text-index-entry-page-number = - element text:index-entry-page-number { - attribute text:style-name { styleNameRef }? +db-query-attlist = + attribute db:command { \string } + & attribute db:escape-processing { boolean }? +db-query-collection = + element db:query-collection { + db-query-collection-attlist, + common-db-object-name, + common-db-object-title, + common-db-object-description, + (db-query | db-query-collection)* } -text-index-entry-span = - element text:index-entry-span { - attribute text:style-name { styleNameRef }?, - text +db-query-collection-attlist = empty +db-reports = + element db:reports { + db-reports-attlist, (db-component | db-component-collection)* } -text-index-entry-bibliography = - element text:index-entry-bibliography { - text-index-entry-bibliography-attrs +db-reports-attlist = empty +db-schema-definition = + element db:schema-definition { + db-schema-definition-attlist, db-table-definitions } -text-index-entry-bibliography-attrs = - attribute text:style-name { styleNameRef }? - & attribute text:bibliography-data-field { - "address" - | "annote" - | "author" - | "bibliography-type" - | "booktitle" - | "chapter" - | "custom1" - | "custom2" - | "custom3" - | "custom4" - | "custom5" - | "edition" - | "editor" - | "howpublished" - | "identifier" - | "institution" - | "isbn" - | "issn" - | "journal" - | "month" - | "note" - | "number" - | "organizations" - | "pages" - | "publisher" - | "report-type" - | "school" - | "series" - | "title" - | "url" - | "volume" - | "year" - } -text-index-entry-tab-stop = - element text:index-entry-tab-stop { - attribute text:style-name { styleNameRef }?, - text-index-entry-tab-stop-attrs +db-schema-definition-attlist = empty +db-server-database = + element db:server-database { db-server-database-attlist, empty } +db-server-database-attlist = + attribute db:type { namespacedToken } + & (db-host-and-port | db-local-socket-name) + & attribute db:database-name { \string }? +db-show-deleted = attribute db:show-deleted { boolean }? +db-table-definition = + element db:table-definition { + common-db-table-name-attlist, + db-table-definition-attlist, + db-column-definitions, + db-keys?, + db-indices? } -text-index-entry-tab-stop-attrs = - attribute style:leader-char { character }? - & (attribute style:type { "right" } - | (attribute style:type { "left" }, - attribute style:position { length })) -text-index-entry-link-start = - element text:index-entry-link-start { - attribute text:style-name { styleNameRef }? +db-table-definition-attlist = attribute db:type { \string }? +db-table-definitions = + element db:table-definitions { + db-table-definitions-attlist, db-table-definition* } -text-index-entry-link-end = - element text:index-entry-link-end { - attribute text:style-name { styleNameRef }? +db-table-definitions-attlist = empty +db-table-exclude-filter = + element db:table-exclude-filter { + db-table-exclude-filter-attlist, db-table-filter-pattern+ } -table-table = - element table:table { - table-table-attlist, - table-title?, - table-desc?, - table-table-source?, - office-dde-source?, - table-scenario?, - office-forms?, - table-shapes?, - table-columns-and-groups, - table-rows-and-groups, - table-named-expressions? +db-table-exclude-filter-attlist = empty +db-table-filter = + element db:table-filter { + db-table-filter-attlist, + db-table-include-filter?, + db-table-exclude-filter? } -table-columns-and-groups = - (table-table-column-group | table-columns-no-group)+ -table-columns-no-group = - (table-columns, (table-table-header-columns, table-columns?)?) - | (table-table-header-columns, table-columns?) -table-columns = table-table-columns | table-table-column+ -table-rows-and-groups = (table-table-row-group | table-rows-no-group)+ -table-rows-no-group = - (table-rows, (table-table-header-rows, table-rows?)?) - | (table-table-header-rows, table-rows?) -table-rows = - table-table-rows | (text-soft-page-break?, table-table-row)+ -table-table-attlist = - attribute table:name { \string }? - & attribute table:style-name { styleNameRef }? - & attribute table:template-name { \string }? - & attribute table:use-first-row-styles { boolean }? - & attribute table:use-last-row-styles { boolean }? - & attribute table:use-first-column-styles { boolean }? - & attribute table:use-last-column-styles { boolean }? - & attribute table:use-banding-rows-styles { boolean }? - & attribute table:use-banding-columns-styles { boolean }? - & attribute table:protected { boolean }? - & attribute table:protection-key { \string }? - & attribute table:protection-key-digest-algorithm { anyIRI }? - & attribute table:print { boolean }? - & attribute table:print-ranges { cellRangeAddressList }? - & xml-id? - & attribute table:is-sub-table { boolean }? -table-title = element table:title { text } -table-desc = element table:desc { text } -table-table-row = - element table:table-row { - table-table-row-attlist, - (table-table-cell | table-covered-table-cell)+ +db-table-filter-attlist = empty +db-table-filter-pattern = + element db:table-filter-pattern { + db-table-filter-pattern-attlist, \string } -table-table-row-attlist = - attribute table:number-rows-repeated { positiveInteger }? - & attribute table:style-name { styleNameRef }? - & attribute table:default-cell-style-name { styleNameRef }? - & attribute table:visibility { table-visibility-value }? - & xml-id? -table-visibility-value = "visible" | "collapse" | "filter" -table-table-cell = - element table:table-cell { - table-table-cell-attlist, - table-table-cell-attlist-extra, - table-table-cell-content +db-table-filter-pattern-attlist = empty +db-table-include-filter = + element db:table-include-filter { + db-table-include-filter-attlist, db-table-filter-pattern+ } -table-covered-table-cell = - element table:covered-table-cell { - table-table-cell-attlist, table-table-cell-content +db-table-include-filter-attlist = empty +db-table-presentation = + element db:table-representation { + db-table-presentation-attlist, + common-db-table-name-attlist, + common-db-object-title, + common-db-object-description, + common-db-table-style-name, + db-order-statement?, + db-filter-statement?, + db-columns? } -table-table-cell-content = - table-cell-range-source?, - office-annotation?, - table-detective?, - text-content* -table-table-cell-attlist = - attribute table:number-columns-repeated { positiveInteger }? - & attribute table:style-name { styleNameRef }? - & attribute table:content-validation-name { \string }? - & attribute table:formula { \string }? - & common-value-and-type-attlist? - & attribute table:protect { boolean }? - & attribute table:protected { boolean }? - & xml-id? - & common-in-content-meta-attlist? -table-table-cell-attlist-extra = - attribute table:number-columns-spanned { positiveInteger }? - & attribute table:number-rows-spanned { positiveInteger }? - & attribute table:number-matrix-columns-spanned { positiveInteger }? - & attribute table:number-matrix-rows-spanned { positiveInteger }? -table-table-column = - element table:table-column { table-table-column-attlist, empty } -table-table-column-attlist = - attribute table:number-columns-repeated { positiveInteger }? - & attribute table:style-name { styleNameRef }? - & attribute table:visibility { table-visibility-value }? - & attribute table:default-cell-style-name { styleNameRef }? - & xml-id? -table-table-header-columns = - element table:table-header-columns { table-table-column+ } -table-table-columns = - element table:table-columns { table-table-column+ } -table-table-column-group = - element table:table-column-group { - table-table-column-group-attlist, table-columns-and-groups +db-table-presentation-attlist = empty +db-table-presentations = + element db:table-representations { + db-table-presentations-attlist, db-table-presentation* } -table-table-column-group-attlist = attribute table:display { boolean }? -table-table-header-rows = - element table:table-header-rows { - (text-soft-page-break?, table-table-row)+ +db-table-presentations-attlist = empty +db-table-setting = + element db:table-setting { + db-table-setting-attlist, db-delimiter?, db-character-set?, empty } -table-table-rows = - element table:table-rows { (text-soft-page-break?, table-table-row)+ } -table-table-row-group = - element table:table-row-group { - table-table-row-group-attlist, table-rows-and-groups +db-table-setting-attlist = db-is-first-row-header-line, db-show-deleted +db-table-settings = element db:table-settings { db-table-setting* } +db-table-type = element db:table-type { db-table-type-attlist, \string } +db-table-type-attlist = empty +db-table-type-filter = + element db:table-type-filter { + db-table-type-filter-attlist, db-table-type* } -table-table-row-group-attlist = attribute table:display { boolean }? -cellAddress = - xsd:string { - pattern = "($?([^\. ']+|'([^']|'')+'))?\.$?[A-Z]+$?[0-9]+" +db-table-type-filter-attlist = empty +db-update-table = + element db:update-table { common-db-table-name-attlist } +dc-creator = element dc:creator { \string } +dc-date = element dc:date { dateTime } +distance = length +double = xsd:double +dr3d-cube = + element dr3d:cube { + dr3d-cube-attlist, + common-draw-z-index-attlist, + common-draw-id-attlist, + common-draw-layer-name-attlist, + common-draw-style-name-attlist, + common-dr3d-transform-attlist, + empty } -cellRangeAddress = - xsd:string { - pattern = - "($?([^\. ']+|'([^']|'')+'))?\.$?[A-Z]+$?[0-9]+(:($?([^\. ']+|'([^']|'')+'))?\.$?[A-Z]+$?[0-9]+)?" +dr3d-cube-attlist = + attribute dr3d:min-edge { vector3D }?, + attribute dr3d:max-edge { vector3D }? +dr3d-extrude = + element dr3d:extrude { + common-draw-path-data-attlist, + common-draw-viewbox-attlist, + common-draw-id-attlist, + common-draw-z-index-attlist, + common-draw-layer-name-attlist, + common-draw-style-name-attlist, + common-dr3d-transform-attlist, + empty } - | xsd:string { - pattern = - "($?([^\. ']+|'([^']|'')+'))?\.$?[0-9]+:($?([^\. ']+|'([^']|'')+'))?\.$?[0-9]+" - } - | xsd:string { - pattern = - "($?([^\. ']+|'([^']|'')+'))?\.$?[A-Z]+:($?([^\. ']+|'([^']|'')+'))?\.$?[A-Z]+" - } -cellRangeAddressList = - xsd:string - >> dc:description [ - 'Value is a space separated list of "cellRangeAddress" patterns' - ] -table-table-source = - element table:table-source { - table-table-source-attlist, table-linked-source-attlist, empty - } -table-table-source-attlist = - attribute table:mode { "copy-all" | "copy-results-only" }? - & attribute table:table-name { \string }? -table-linked-source-attlist = - attribute xlink:type { "simple" } - & attribute xlink:href { anyIRI } - & attribute xlink:actuate { "onRequest" }? - & attribute table:filter-name { \string }? - & attribute table:filter-options { \string }? - & attribute table:refresh-delay { duration }? -table-scenario = - element table:scenario { table-scenario-attlist, empty } -table-scenario-attlist = - attribute table:scenario-ranges { cellRangeAddressList } - & attribute table:is-active { boolean } - & attribute table:display-border { boolean }? - & attribute table:border-color { color }? - & attribute table:copy-back { boolean }? - & attribute table:copy-styles { boolean }? - & attribute table:copy-formulas { boolean }? - & attribute table:comment { \string }? - & attribute table:protected { boolean }? -table-shapes = element table:shapes { shape+ } -table-cell-range-source = - element table:cell-range-source { - table-table-cell-range-source-attlist, - table-linked-source-attlist, - empty - } -table-table-cell-range-source-attlist = - attribute table:name { \string } - & attribute table:last-column-spanned { positiveInteger } - & attribute table:last-row-spanned { positiveInteger } -table-detective = - element table:detective { table-highlighted-range*, table-operation* } -table-operation = - element table:operation { table-operation-attlist, empty } -table-operation-attlist = - attribute table:name { - "trace-dependents" - | "remove-dependents" - | "trace-precedents" - | "remove-precedents" - | "trace-errors" - } - & attribute table:index { nonNegativeInteger } -table-highlighted-range = - element table:highlighted-range { - (table-highlighted-range-attlist - | table-highlighted-range-attlist-invalid), +dr3d-light = element dr3d:light { dr3d-light-attlist, empty } +dr3d-light-attlist = + attribute dr3d:diffuse-color { color }? + & attribute dr3d:direction { vector3D } + & attribute dr3d:enabled { boolean }? + & attribute dr3d:specular { boolean }? +dr3d-rotate = + element dr3d:rotate { + common-draw-viewbox-attlist, + common-draw-path-data-attlist, + common-draw-z-index-attlist, + common-draw-id-attlist, + common-draw-layer-name-attlist, + common-draw-style-name-attlist, + common-dr3d-transform-attlist, empty } -table-highlighted-range-attlist = - attribute table:cell-range-address { cellRangeAddress }? - & attribute table:direction { - "from-another-table" | "to-another-table" | "from-same-table" - } - & attribute table:contains-error { boolean }? -table-highlighted-range-attlist-invalid = - attribute table:marked-invalid { boolean } -office-spreadsheet-attlist = - attribute table:structure-protected { boolean }?, - attribute table:protection-key { \string }?, - attribute table:protection-key-digest-algorithm { anyIRI }? -table-calculation-settings = - element table:calculation-settings { - table-calculation-setting-attlist, - table-null-date?, - table-iteration? +dr3d-scene = + element dr3d:scene { + dr3d-scene-attlist, + common-draw-position-attlist, + common-draw-size-attlist, + common-draw-style-name-attlist, + common-draw-z-index-attlist, + common-draw-id-attlist, + common-draw-layer-name-attlist, + common-text-spreadsheet-shape-attlist, + common-dr3d-transform-attlist, + common-draw-caption-id-attlist, + svg-title?, + svg-desc?, + dr3d-light*, + shapes3d*, + draw-glue-point* } -table-calculation-setting-attlist = - attribute table:case-sensitive { boolean }? - & attribute table:precision-as-shown { boolean }? - & attribute table:search-criteria-must-apply-to-whole-cell { - boolean +dr3d-scene-attlist = + attribute dr3d:vrp { vector3D }? + & attribute dr3d:vpn { vector3D }? + & attribute dr3d:vup { vector3D }? + & attribute dr3d:projection { "parallel" | "perspective" }? + & attribute dr3d:distance { length }? + & attribute dr3d:focal-length { length }? + & attribute dr3d:shadow-slant { angle }? + & attribute dr3d:shade-mode { + "flat" | "phong" | "gouraud" | "draft" }? - & attribute table:automatic-find-labels { boolean }? - & attribute table:use-regular-expressions { boolean }? - & attribute table:use-wildcards { boolean }? - & attribute table:null-year { positiveInteger }? -table-null-date = - element table:null-date { - attribute table:value-type { "date" }?, - attribute table:date-value { date }?, - empty - } -table-iteration = - element table:iteration { - attribute table:status { "enable" | "disable" }?, - attribute table:steps { positiveInteger }?, - attribute table:maximum-difference { double }?, + & attribute dr3d:ambient-color { color }? + & attribute dr3d:lighting-mode { boolean }? +dr3d-sphere = + element dr3d:sphere { + dr3d-sphere-attlist, + common-draw-z-index-attlist, + common-draw-id-attlist, + common-draw-layer-name-attlist, + common-draw-style-name-attlist, + common-dr3d-transform-attlist, empty } -table-content-validations = - element table:content-validations { table-content-validation+ } -table-content-validation = - element table:content-validation { - table-validation-attlist, - table-help-message?, - (table-error-message | (table-error-macro, office-event-listeners))? +dr3d-sphere-attlist = + attribute dr3d:center { vector3D }? + & attribute dr3d:size { vector3D }? +draw-a = element draw:a { draw-a-attlist, shape-instance } +draw-a-attlist = + attribute xlink:type { "simple" } + & attribute xlink:href { anyIRI } + & attribute xlink:actuate { "onRequest" }? + & attribute office:target-frame-name { targetFrameName }? + & attribute xlink:show { "new" | "replace" }? + & attribute office:name { \string }? + & attribute office:title { \string }? + & attribute office:server-map { boolean }? + & xml-id? +draw-applet = + element draw:applet { + draw-applet-attlist, common-draw-data-attlist?, draw-param* } -table-validation-attlist = - attribute table:name { \string } - & attribute table:condition { \string }? - & attribute table:base-cell-address { cellAddress }? - & attribute table:allow-empty-cell { boolean }? - & attribute table:display-list { - "none" | "unsorted" | "sort-ascending" - }? -table-help-message = - element table:help-message { - attribute table:title { \string }?, - attribute table:display { boolean }?, - text-p* +draw-applet-attlist = + attribute draw:code { \string }? + & attribute draw:object { \string }? + & attribute draw:archive { \string }? + & attribute draw:may-script { boolean }? + & xml-id? +draw-area-circle = + element draw:area-circle { + common-draw-area-attlist, + attribute svg:cx { coordinate }, + attribute svg:cy { coordinate }, + attribute svg:r { length }, + svg-title?, + svg-desc?, + office-event-listeners? } -table-error-message = - element table:error-message { - attribute table:title { \string }?, - attribute table:display { boolean }?, - attribute table:message-type { - "stop" | "warning" | "information" - }?, - text-p* +draw-area-polygon = + element draw:area-polygon { + common-draw-area-attlist, + attribute svg:x { coordinate }, + attribute svg:y { coordinate }, + attribute svg:width { length }, + attribute svg:height { length }, + common-draw-viewbox-attlist, + common-draw-points-attlist, + svg-title?, + svg-desc?, + office-event-listeners? } -table-error-macro = - element table:error-macro { - attribute table:execute { boolean }? +draw-area-rectangle = + element draw:area-rectangle { + common-draw-area-attlist, + attribute svg:x { coordinate }, + attribute svg:y { coordinate }, + attribute svg:width { length }, + attribute svg:height { length }, + svg-title?, + svg-desc?, + office-event-listeners? } -table-label-ranges = element table:label-ranges { table-label-range* } -table-label-range = - element table:label-range { table-label-range-attlist, empty } -table-label-range-attlist = - attribute table:label-cell-range-address { cellRangeAddress } - & attribute table:data-cell-range-address { cellRangeAddress } - & attribute table:orientation { "column" | "row" } -table-named-expressions = - element table:named-expressions { - (table-named-range | table-named-expression)* +draw-caption = + element draw:caption { + draw-caption-attlist, + common-draw-position-attlist, + common-draw-size-attlist, + common-draw-shape-with-text-and-styles-attlist, + common-draw-caption-id-attlist, + svg-title?, + svg-desc?, + office-event-listeners?, + draw-glue-point*, + draw-text } -table-named-range = - element table:named-range { table-named-range-attlist, empty } -table-named-range-attlist = - attribute table:name { \string }, - attribute table:cell-range-address { cellRangeAddress }, - attribute table:base-cell-address { cellAddress }?, - attribute table:range-usable-as { - "none" - | list { - ("print-range" | "filter" | "repeat-row" | "repeat-column")+ - } - }? -table-named-expression = - element table:named-expression { - table-named-expression-attlist, empty - } -table-named-expression-attlist = - attribute table:name { \string }, - attribute table:expression { \string }, - attribute table:base-cell-address { cellAddress }? -table-database-ranges = - element table:database-ranges { table-database-range* } -table-database-range = - element table:database-range { - table-database-range-attlist, - (table-database-source-sql - | table-database-source-table - | table-database-source-query)?, - table-filter?, - table-sort?, - table-subtotal-rules? - } -table-database-range-attlist = - attribute table:name { \string }? - & attribute table:is-selection { boolean }? - & attribute table:on-update-keep-styles { boolean }? - & attribute table:on-update-keep-size { boolean }? - & attribute table:has-persistent-data { boolean }? - & attribute table:orientation { "column" | "row" }? - & attribute table:contains-header { boolean }? - & attribute table:display-filter-buttons { boolean }? - & attribute table:target-range-address { cellRangeAddress } - & attribute table:refresh-delay { boolean }? -table-database-source-sql = - element table:database-source-sql { - table-database-source-sql-attlist, empty - } -table-database-source-sql-attlist = - attribute table:database-name { \string } - & attribute table:sql-statement { \string } - & attribute table:parse-sql-statement { boolean }? -table-database-source-query = - element table:database-source-table { - table-database-source-table-attlist, empty +draw-caption-attlist = + (attribute draw:caption-point-x { coordinate }, + attribute draw:caption-point-y { coordinate })? + & attribute draw:corner-radius { nonNegativeLength }? +draw-circle = + element draw:circle { + ((draw-circle-attlist, common-draw-circle-ellipse-pos-attlist) + | (common-draw-position-attlist, common-draw-size-attlist)), + common-draw-circle-ellipse-attlist, + common-draw-shape-with-text-and-styles-attlist, + common-draw-caption-id-attlist, + svg-title?, + svg-desc?, + office-event-listeners?, + draw-glue-point*, + draw-text } -table-database-source-table-attlist = - attribute table:database-name { \string } - & attribute table:database-table-name { \string } -table-database-source-table = - element table:database-source-query { - table-database-source-query-attlist, empty +draw-circle-attlist = attribute svg:r { length } +draw-connector = + element draw:connector { + draw-connector-attlist, + common-draw-shape-with-text-and-styles-attlist, + common-draw-caption-id-attlist, + common-draw-viewbox-attlist, + svg-title?, + svg-desc?, + office-event-listeners?, + draw-glue-point*, + draw-text } -table-database-source-query-attlist = - attribute table:database-name { \string } - & attribute table:query-name { \string } -table-sort = element table:sort { table-sort-attlist, table-sort-by+ } -table-sort-attlist = - attribute table:bind-styles-to-content { boolean }? - & attribute table:target-range-address { cellRangeAddress }? - & attribute table:case-sensitive { boolean }? - & attribute table:language { languageCode }? - & attribute table:country { countryCode }? - & attribute table:script { scriptCode }? - & attribute table:rfc-language-tag { language }? - & attribute table:algorithm { \string }? - & attribute table:embedded-number-behavior { - "alpha-numeric" | "integer" | "double" - }? -table-sort-by = element table:sort-by { table-sort-by-attlist, empty } -table-sort-by-attlist = - attribute table:field-number { nonNegativeInteger } - & attribute table:data-type { - "text" | "number" | "automatic" | \string +draw-connector-attlist = + attribute draw:type { "standard" | "lines" | "line" | "curve" }? + & (attribute svg:x1 { coordinate }, + attribute svg:y1 { coordinate })? + & attribute draw:start-shape { IDREF }? + & attribute draw:start-glue-point { nonNegativeInteger }? + & (attribute svg:x2 { coordinate }, + attribute svg:y2 { coordinate })? + & attribute draw:end-shape { IDREF }? + & attribute draw:end-glue-point { nonNegativeInteger }? + & attribute draw:line-skew { + list { length, (length, length?)? } }? - & attribute table:order { "ascending" | "descending" }? -table-subtotal-rules = - element table:subtotal-rules { - table-subtotal-rules-attlist, - table-sort-groups?, - table-subtotal-rule* - } -table-subtotal-rules-attlist = - attribute table:bind-styles-to-content { boolean }? - & attribute table:case-sensitive { boolean }? - & attribute table:page-breaks-on-group-change { boolean }? -table-sort-groups = - element table:sort-groups { table-sort-groups-attlist, empty } -table-sort-groups-attlist = - attribute table:data-type { - "text" | "number" | "automatic" | \string - }? - & attribute table:order { "ascending" | "descending" }? -table-subtotal-rule = - element table:subtotal-rule { - table-subtotal-rule-attlist, table-subtotal-field* - } -table-subtotal-rule-attlist = - attribute table:group-by-field-number { nonNegativeInteger } -table-subtotal-field = - element table:subtotal-field { table-subtotal-field-attlist, empty } -table-subtotal-field-attlist = - attribute table:field-number { nonNegativeInteger } - & attribute table:function { - "average" - | "count" - | "countnums" - | "max" - | "min" - | "product" - | "stdev" - | "stdevp" - | "sum" - | "var" - | "varp" - | \string - } -table-filter = - element table:filter { - table-filter-attlist, - (table-filter-condition | table-filter-and | table-filter-or) + & attribute svg:d { pathData }? +draw-contour-path = + element draw:contour-path { + common-contour-attlist, + common-draw-size-attlist, + common-draw-viewbox-attlist, + common-draw-path-data-attlist, + empty } -table-filter-attlist = - attribute table:target-range-address { cellRangeAddress }? - & attribute table:condition-source { "self" | "cell-range" }? - & attribute table:condition-source-range-address { cellRangeAddress }? - & attribute table:display-duplicates { boolean }? -table-filter-and = - element table:filter-and { - (table-filter-or | table-filter-condition)+ +draw-contour-polygon = + element draw:contour-polygon { + common-contour-attlist, + common-draw-size-attlist, + common-draw-viewbox-attlist, + common-draw-points-attlist, + empty } -table-filter-or = - element table:filter-or { - (table-filter-and | table-filter-condition)+ +draw-control = + element draw:control { + draw-control-attlist, + common-draw-position-attlist, + common-draw-size-attlist, + common-draw-shape-with-text-and-styles-attlist, + common-draw-caption-id-attlist, + svg-title?, + svg-desc?, + draw-glue-point* } -table-filter-condition = - element table:filter-condition { - table-filter-condition-attlist, table-filter-set-item* +draw-control-attlist = attribute draw:control { IDREF } +draw-custom-shape = + element draw:custom-shape { + draw-custom-shape-attlist, + common-draw-position-attlist, + common-draw-size-attlist, + common-draw-shape-with-text-and-styles-attlist, + common-draw-caption-id-attlist, + svg-title?, + svg-desc?, + office-event-listeners?, + draw-glue-point*, + draw-text, + draw-enhanced-geometry? } -table-filter-condition-attlist = - attribute table:field-number { nonNegativeInteger } - & attribute table:value { \string | double } - & attribute table:operator { \string } - & attribute table:case-sensitive { \string }? - & attribute table:data-type { "text" | "number" }? -table-filter-set-item = - element table:filter-set-item { - attribute table:value { \string }, - empty +draw-custom-shape-attlist = + attribute draw:engine { namespacedToken }? + & attribute draw:data { \string }? +draw-ellipse = + element draw:ellipse { + ((draw-ellipse-attlist, common-draw-circle-ellipse-pos-attlist) + | (common-draw-position-attlist, common-draw-size-attlist)), + common-draw-circle-ellipse-attlist, + common-draw-shape-with-text-and-styles-attlist, + common-draw-caption-id-attlist, + svg-title?, + svg-desc?, + office-event-listeners?, + draw-glue-point*, + draw-text } -table-data-pilot-tables = - element table:data-pilot-tables { table-data-pilot-table* } -table-data-pilot-table = - element table:data-pilot-table { - table-data-pilot-table-attlist, - (table-database-source-sql - | table-database-source-table - | table-database-source-query - | table-source-service - | table-source-cell-range)?, - table-data-pilot-field+ +draw-ellipse-attlist = + attribute svg:rx { length }, + attribute svg:ry { length } +draw-enhanced-geometry = + element draw:enhanced-geometry { + draw-enhanced-geometry-attlist, draw-equation*, draw-handle* } -table-data-pilot-table-attlist = - attribute table:name { \string } - & attribute table:application-data { \string }? - & attribute table:grand-total { "none" | "row" | "column" | "both" }? - & attribute table:ignore-empty-rows { boolean }? - & attribute table:identify-categories { boolean }? - & attribute table:target-range-address { cellRangeAddress } - & attribute table:buttons { cellRangeAddressList }? - & attribute table:show-filter-button { boolean }? - & attribute table:drill-down-on-double-click { boolean }? -table-source-cell-range = - element table:source-cell-range { - table-source-cell-range-attlist, table-filter? - } -table-source-cell-range-attlist = - attribute table:cell-range-address { cellRangeAddress } -table-source-service = - element table:source-service { table-source-service-attlist, empty } -table-source-service-attlist = - attribute table:name { \string } - & attribute table:source-name { \string } - & attribute table:object-name { \string } - & attribute table:user-name { \string }? - & attribute table:password { \string }? -table-data-pilot-field = - element table:data-pilot-field { - table-data-pilot-field-attlist, - table-data-pilot-level?, - table-data-pilot-field-reference?, - table-data-pilot-groups? - } -table-data-pilot-field-attlist = - attribute table:source-field-name { \string } - & (attribute table:orientation { - "row" | "column" | "data" | "hidden" - } - | (attribute table:orientation { "page" }, - attribute table:selected-page { \string })) - & attribute table:is-data-layout-field { \string }? - & attribute table:function { - "auto" - | "average" - | "count" - | "countnums" - | "max" - | "min" - | "product" - | "stdev" - | "stdevp" - | "sum" - | "var" - | "varp" - | \string +draw-enhanced-geometry-attlist = + attribute draw:type { custom-shape-type }? + & attribute svg:viewBox { + list { integer, integer, integer, integer } }? - & attribute table:used-hierarchy { integer }? -table-data-pilot-level = - element table:data-pilot-level { - table-data-pilot-level-attlist, - table-data-pilot-subtotals?, - table-data-pilot-members?, - table-data-pilot-display-info?, - table-data-pilot-sort-info?, - table-data-pilot-layout-info? - } -table-data-pilot-level-attlist = attribute table:show-empty { boolean }? -table-data-pilot-subtotals = - element table:data-pilot-subtotals { table-data-pilot-subtotal* } -table-data-pilot-subtotal = - element table:data-pilot-subtotal { - table-data-pilot-subtotal-attlist, empty - } -table-data-pilot-subtotal-attlist = - attribute table:function { - "auto" - | "average" - | "count" - | "countnums" - | "max" - | "min" - | "product" - | "stdev" - | "stdevp" - | "sum" - | "var" - | "varp" - | \string + & attribute draw:mirror-vertical { boolean }? + & attribute draw:mirror-horizontal { boolean }? + & attribute draw:text-rotate-angle { angle }? + & attribute draw:extrusion-allowed { boolean }? + & attribute draw:text-path-allowed { boolean }? + & attribute draw:concentric-gradient-fill-allowed { boolean }? + & attribute draw:extrusion { boolean }? + & attribute draw:extrusion-brightness { zeroToHundredPercent }? + & attribute draw:extrusion-depth { + list { length, double } + }? + & attribute draw:extrusion-diffusion { percent }? + & attribute draw:extrusion-number-of-line-segments { integer }? + & attribute draw:extrusion-light-face { boolean }? + & attribute draw:extrusion-first-light-harsh { boolean }? + & attribute draw:extrusion-second-light-harsh { boolean }? + & attribute draw:extrusion-first-light-level { zeroToHundredPercent }? + & attribute draw:extrusion-second-light-level { + zeroToHundredPercent + }? + & attribute draw:extrusion-first-light-direction { vector3D }? + & attribute draw:extrusion-second-light-direction { vector3D }? + & attribute draw:extrusion-metal { boolean }? + & attribute dr3d:shade-mode { + "flat" | "phong" | "gouraud" | "draft" + }? + & attribute draw:extrusion-rotation-angle { + list { angle, angle } + }? + & attribute draw:extrusion-rotation-center { vector3D }? + & attribute draw:extrusion-shininess { zeroToHundredPercent }? + & attribute draw:extrusion-skew { + list { double, angle } + }? + & attribute draw:extrusion-specularity { zeroToHundredPercent }? + & attribute dr3d:projection { "parallel" | "perspective" }? + & attribute draw:extrusion-viewpoint { point3D }? + & attribute draw:extrusion-origin { + list { extrusionOrigin, extrusionOrigin } + }? + & attribute draw:extrusion-color { boolean }? + & attribute draw:enhanced-path { \string }? + & attribute draw:path-stretchpoint-x { double }? + & attribute draw:path-stretchpoint-y { double }? + & attribute draw:text-areas { \string }? + & attribute draw:glue-points { \string }? + & attribute draw:glue-point-type { + "none" | "segments" | "rectangle" + }? + & attribute draw:glue-point-leaving-directions { \string }? + & attribute draw:text-path { boolean }? + & attribute draw:text-path-mode { "normal" | "path" | "shape" }? + & attribute draw:text-path-scale { "path" | "shape" }? + & attribute draw:text-path-same-letter-heights { boolean }? + & attribute draw:modifiers { \string }? +draw-equation = element draw:equation { draw-equation-attlist, empty } +draw-equation-attlist = + attribute draw:name { \string }? + & attribute draw:formula { \string }? +draw-fill-image = + element draw:fill-image { + draw-fill-image-attlist, + # XLink duplicate declaration removed. see common-draw-data-attlist + ((common-draw-data-attlist, empty) | office-binary-data) + # https://issues.oasis-open.org/browse/OFFICE-3933 + } -table-data-pilot-members = - element table:data-pilot-members { table-data-pilot-member* } -table-data-pilot-member = - element table:data-pilot-member { - table-data-pilot-member-attlist, empty +draw-fill-image-attlist = + attribute draw:name { styleName } + & attribute draw:display-name { \string }? + & attribute svg:width { length }? + & attribute svg:height { length }? +draw-floating-frame = + element draw:floating-frame { + draw-floating-frame-attlist, common-draw-data-attlist } -table-data-pilot-member-attlist = - attribute table:name { \string } - & attribute table:display { boolean }? - & attribute table:show-details { boolean }? -table-data-pilot-display-info = - element table:data-pilot-display-info { - table-data-pilot-display-info-attlist, empty +draw-floating-frame-attlist = + attribute draw:frame-name { \string }? + & xml-id? +draw-frame = + element draw:frame { + common-draw-shape-with-text-and-styles-attlist, + common-draw-position-attlist, + common-draw-rel-size-attlist, + common-draw-caption-id-attlist, + presentation-shape-attlist, + draw-frame-attlist, + (draw-text-box + | draw-image + | draw-object + | draw-object-ole + | draw-applet + | draw-floating-frame + | draw-plugin + | table-table)*, + office-event-listeners?, + draw-glue-point*, + draw-image-map?, + svg-title?, + svg-desc?, + (draw-contour-polygon | draw-contour-path)? } -table-data-pilot-display-info-attlist = - attribute table:enabled { boolean } - & attribute table:data-field { \string } - & attribute table:member-count { nonNegativeInteger } - & attribute table:display-member-mode { "from-top" | "from-bottom" } -table-data-pilot-sort-info = - element table:data-pilot-sort-info { - table-data-pilot-sort-info-attlist, empty +draw-frame-attlist = attribute draw:copy-of { \string }? +draw-g = + element draw:g { + draw-g-attlist, + common-draw-z-index-attlist, + common-draw-name-attlist, + common-draw-id-attlist, + common-draw-style-name-attlist, + common-text-spreadsheet-shape-attlist, + common-draw-caption-id-attlist, + svg-title?, + svg-desc?, + office-event-listeners?, + draw-glue-point*, + shape* } -table-data-pilot-sort-info-attlist = - ((attribute table:sort-mode { "data" }, - attribute table:data-field { \string }) - | attribute table:sort-mode { "none" | "manual" | "name" }) - & attribute table:order { "ascending" | "descending" } -table-data-pilot-layout-info = - element table:data-pilot-layout-info { - table-data-pilot-layout-info-attlist, empty +draw-g-attlist = attribute svg:y { coordinate }? +draw-glue-point = + element draw:glue-point { draw-glue-point-attlist, empty } +draw-glue-point-attlist = + attribute draw:id { nonNegativeInteger } + & attribute svg:x { distance | percent } + & attribute svg:y { distance | percent } + & attribute draw:align { + "top-left" + | "top" + | "top-right" + | "left" + | "center" + | "right" + | "bottom-left" + | "bottom-right" + }? + & attribute draw:escape-direction { + "auto" + | "left" + | "right" + | "up" + | "down" + | "horizontal" + | "vertical" + } +draw-gradient = + element draw:gradient { + common-draw-gradient-attlist, draw-gradient-attlist, empty } -table-data-pilot-layout-info-attlist = - attribute table:layout-mode { - "tabular-layout" - | "outline-subtotals-top" - | "outline-subtotals-bottom" - } - & attribute table:add-empty-lines { boolean } -table-data-pilot-field-reference = - element table:data-pilot-field-reference { - table-data-pilot-field-reference-attlist - } -table-data-pilot-field-reference-attlist = - attribute table:field-name { \string } - & ((attribute table:member-type { "named" }, - attribute table:member-name { \string }) - | attribute table:member-type { "previous" | "next" }) - & attribute table:type { - "none" - | "member-difference" - | "member-percentage" - | "member-percentage-difference" - | "running-total" - | "row-percentage" - | "column-percentage" - | "total-percentage" - | "index" - } -table-data-pilot-groups = - element table:data-pilot-groups { - table-data-pilot-groups-attlist, table-data-pilot-group+ - } -table-data-pilot-groups-attlist = - attribute table:source-field-name { \string } - & (attribute table:date-start { dateOrDateTime | "auto" } - | attribute table:start { double | "auto" }) - & (attribute table:date-end { dateOrDateTime | "auto" } - | attribute table:end { double | "auto" }) - & attribute table:step { double } - & attribute table:grouped-by { - "seconds" - | "minutes" - | "hours" - | "days" - | "months" - | "quarters" - | "years" - } -table-data-pilot-group = - element table:data-pilot-group { - table-data-pilot-group-attlist, table-data-pilot-group-member+ - } -table-data-pilot-group-attlist = attribute table:name { \string } -table-data-pilot-group-member = - element table:data-pilot-group-member { - table-data-pilot-group-member-attlist - } -table-data-pilot-group-member-attlist = attribute table:name { \string } -table-consolidation = - element table:consolidation { table-consolidation-attlist, empty } -table-consolidation-attlist = - attribute table:function { - "average" - | "count" - | "countnums" - | "max" - | "min" - | "product" - | "stdev" - | "stdevp" - | "sum" - | "var" - | "varp" - | \string +draw-gradient-attlist = + attribute draw:start-color { color }? + & attribute draw:end-color { color }? + & attribute draw:start-intensity { zeroToHundredPercent }? + & attribute draw:end-intensity { zeroToHundredPercent }? +draw-handle = element draw:handle { draw-handle-attlist, empty } +draw-handle-attlist = + attribute draw:handle-mirror-vertical { boolean }? + & attribute draw:handle-mirror-horizontal { boolean }? + & attribute draw:handle-switched { boolean }? + & attribute draw:handle-position { \string } + & attribute draw:handle-range-x-minimum { \string }? + & attribute draw:handle-range-x-maximum { \string }? + & attribute draw:handle-range-y-minimum { \string }? + & attribute draw:handle-range-y-maximum { \string }? + & attribute draw:handle-polar { \string }? + & attribute draw:handle-radius-range-minimum { \string }? + & attribute draw:handle-radius-range-maximum { \string }? +draw-hatch = element draw:hatch { draw-hatch-attlist, empty } +draw-hatch-attlist = + attribute draw:name { styleName } + & attribute draw:display-name { \string }? + & attribute draw:style { "single" | "double" | "triple" } + & attribute draw:color { color }? + & attribute draw:distance { length }? + & attribute draw:rotation { angle }? +draw-image = + element draw:image { + draw-image-attlist, + (common-draw-data-attlist | office-binary-data), + draw-text } - & attribute table:source-cell-range-addresses { cellRangeAddressList } - & attribute table:target-cell-address { cellAddress } - & attribute table:use-labels { "none" | "row" | "column" | "both" }? - & attribute table:link-to-source-data { boolean }? -table-dde-links = element table:dde-links { table-dde-link+ } -table-tracked-changes = - element table:tracked-changes { - table-tracked-changes-attlist, - (table-cell-content-change - | table-insertion - | table-deletion - | table-movement)* +draw-image-attlist = + attribute draw:filter-name { \string }? + & common-draw-mime-type-attlist + & # https://issues.oasis-open.org/browse/OFFICE-3943 + xml-id? +draw-image-map = + element draw:image-map { + (draw-area-rectangle | draw-area-circle | draw-area-polygon)* } -table-tracked-changes-attlist = - attribute table:track-changes { boolean }? -table-insertion = - element table:insertion { - table-insertion-attlist, - common-table-change-attlist, - office-change-info, - table-dependencies?, - table-deletions? +draw-layer = + element draw:layer { draw-layer-attlist, svg-title?, svg-desc? } +draw-layer-attlist = + attribute draw:name { \string } + & attribute draw:protected { boolean }? + & attribute draw:display { "always" | "screen" | "printer" | "none" }? +draw-layer-set = element draw:layer-set { draw-layer* } +draw-line = + element draw:line { + draw-line-attlist, + common-draw-shape-with-text-and-styles-attlist, + common-draw-caption-id-attlist, + svg-title?, + svg-desc?, + office-event-listeners?, + draw-glue-point*, + draw-text } -table-insertion-attlist = - attribute table:type { "row" | "column" | "table" } - & attribute table:position { integer } - & attribute table:count { positiveInteger }? - & attribute table:table { integer }? -table-dependencies = element table:dependencies { table-dependency+ } -table-dependency = - element table:dependency { - attribute table:id { \string }, +draw-line-attlist = + attribute svg:x1 { coordinate } + & attribute svg:y1 { coordinate } + & attribute svg:x2 { coordinate } + & attribute svg:y2 { coordinate } +draw-marker = + element draw:marker { + draw-marker-attlist, + common-draw-viewbox-attlist, + common-draw-path-data-attlist, empty } -table-deletions = - element table:deletions { - (table-cell-content-deletion | table-change-deletion)+ - } -table-cell-content-deletion = - element table:cell-content-deletion { - attribute table:id { \string }?, - table-cell-address?, - table-change-track-table-cell? - } -table-change-deletion = - element table:change-deletion { - attribute table:id { \string }?, - empty +draw-marker-attlist = + attribute draw:name { styleName } + & attribute draw:display-name { \string }? +draw-measure = + element draw:measure { + draw-measure-attlist, + common-draw-shape-with-text-and-styles-attlist, + common-draw-caption-id-attlist, + svg-title?, + svg-desc?, + office-event-listeners?, + draw-glue-point*, + draw-text } -table-deletion = - element table:deletion { - table-deletion-attlist, - common-table-change-attlist, - office-change-info, - table-dependencies?, - table-deletions?, - table-cut-offs? +draw-measure-attlist = + attribute svg:x1 { coordinate } + & attribute svg:y1 { coordinate } + & attribute svg:x2 { coordinate } + & attribute svg:y2 { coordinate } +draw-object = + element draw:object { + draw-object-attlist, + (common-draw-data-attlist | office-document | math-math) } -table-deletion-attlist = - attribute table:type { "row" | "column" | "table" } - & attribute table:position { integer } - & attribute table:table { integer }? - & attribute table:multi-deletion-spanned { integer }? -table-cut-offs = - element table:cut-offs { - table-movement-cut-off+ - | (table-insertion-cut-off, table-movement-cut-off*) +draw-object-attlist = + attribute draw:notify-on-update-of-ranges { + cellRangeAddressList | \string + }? + & xml-id? +draw-object-ole = + element draw:object-ole { + draw-object-ole-attlist, + (common-draw-data-attlist | office-binary-data) } -table-insertion-cut-off = - element table:insertion-cut-off { - table-insertion-cut-off-attlist, empty +draw-object-ole-attlist = + attribute draw:class-id { \string }? + & xml-id? +draw-opacity = + element draw:opacity { + common-draw-gradient-attlist, draw-opacity-attlist, empty } -table-insertion-cut-off-attlist = - attribute table:id { \string } - & attribute table:position { integer } -table-movement-cut-off = - element table:movement-cut-off { - table-movement-cut-off-attlist, empty - } -table-movement-cut-off-attlist = - attribute table:position { integer } - | (attribute table:start-position { integer }, - attribute table:end-position { integer }) -table-movement = - element table:movement { - common-table-change-attlist, - table-source-range-address, - table-target-range-address, - office-change-info, - table-dependencies?, - table-deletions? - } -table-source-range-address = - element table:source-range-address { - common-table-range-attlist, empty - } -table-target-range-address = - element table:target-range-address { - common-table-range-attlist, empty - } -common-table-range-attlist = - common-table-cell-address-attlist - | common-table-cell-range-address-attlist -common-table-cell-address-attlist = - attribute table:column { integer }, - attribute table:row { integer }, - attribute table:table { integer } -common-table-cell-range-address-attlist = - attribute table:start-column { integer }, - attribute table:start-row { integer }, - attribute table:start-table { integer }, - attribute table:end-column { integer }, - attribute table:end-row { integer }, - attribute table:end-table { integer } -table-change-track-table-cell = - element table:change-track-table-cell { - table-change-track-table-cell-attlist, text-p* - } -table-change-track-table-cell-attlist = - attribute table:cell-address { cellAddress }? - & attribute table:matrix-covered { boolean }? - & attribute table:formula { \string }? - & attribute table:number-matrix-columns-spanned { positiveInteger }? - & attribute table:number-matrix-rows-spanned { positiveInteger }? - & common-value-and-type-attlist? -table-cell-content-change = - element table:cell-content-change { - common-table-change-attlist, - table-cell-address, - office-change-info, - table-dependencies?, - table-deletions?, - table-previous - } -table-cell-address = - element table:cell-address { - common-table-cell-address-attlist, empty - } -table-previous = - element table:previous { - attribute table:id { \string }?, - table-change-track-table-cell - } -common-table-change-attlist = - attribute table:id { \string } - & attribute table:acceptance-state { - "accepted" | "rejected" | "pending" - }? - & attribute table:rejecting-change-id { \string }? -style-handout-master = - element style:handout-master { - common-presentation-header-footer-attlist, - style-handout-master-attlist, - shape* - } -style-handout-master-attlist = - attribute presentation:presentation-page-layout-name { styleNameRef }? - & attribute style:page-layout-name { styleNameRef } - & attribute draw:style-name { styleNameRef }? -draw-layer-set = element draw:layer-set { draw-layer* } -draw-layer = - element draw:layer { draw-layer-attlist, svg-title?, svg-desc? } -draw-layer-attlist = - attribute draw:name { \string } - & attribute draw:protected { boolean }? - & attribute draw:display { "always" | "screen" | "printer" | "none" }? -draw-page = - element draw:page { - common-presentation-header-footer-attlist, - draw-page-attlist, - svg-title?, - svg-desc?, - draw-layer-set?, - office-forms?, - shape*, - (presentation-animations | animation-element)?, - presentation-notes? +draw-opacity-attlist = + attribute draw:start { zeroToHundredPercent }?, + attribute draw:end { zeroToHundredPercent }? +draw-page = + element draw:page { + common-presentation-header-footer-attlist, + draw-page-attlist, + svg-title?, + svg-desc?, + draw-layer-set?, + office-forms?, + shape*, + (presentation-animations | animation-element)?, + presentation-notes? } draw-page-attlist = attribute draw:name { \string }? @@ -2153,34 +1921,29 @@ draw-page-attlist = & (xml-id, attribute draw:id { NCName }?)? & attribute draw:nav-order { IDREFS }? -common-presentation-header-footer-attlist = - attribute presentation:use-header-name { \string }? - & attribute presentation:use-footer-name { \string }? - & attribute presentation:use-date-time-name { \string }? -shape = shape-instance | draw-a -shape-instance = - draw-rect - | draw-line - | draw-polyline - | draw-polygon - | draw-regular-polygon - | draw-path - | draw-circle - | draw-ellipse - | draw-g - | draw-page-thumbnail - | draw-frame - | draw-measure - | draw-caption - | draw-connector - | draw-control - | dr3d-scene - | draw-custom-shape -draw-rect = - element draw:rect { - draw-rect-attlist, +draw-page-thumbnail = + element draw:page-thumbnail { + draw-page-thumbnail-attlist, + common-draw-position-attlist, + common-draw-size-attlist, + presentation-shape-attlist, + common-draw-shape-with-styles-attlist, + common-draw-caption-id-attlist, + svg-title?, + svg-desc? + } +draw-page-thumbnail-attlist = + attribute draw:page-number { positiveInteger }? +draw-param = element draw:param { draw-param-attlist, empty } +draw-param-attlist = + attribute draw:name { \string }? + & attribute draw:value { \string }? +draw-path = + element draw:path { + common-draw-path-data-attlist, common-draw-position-attlist, common-draw-size-attlist, + common-draw-viewbox-attlist, common-draw-shape-with-text-and-styles-attlist, common-draw-caption-id-attlist, svg-title?, @@ -2189,13 +1952,18 @@ draw-rect = draw-glue-point*, draw-text } -draw-rect-attlist = - attribute draw:corner-radius { nonNegativeLength }? - | (attribute svg:rx { nonNegativeLength }?, - attribute svg:ry { nonNegativeLength }?) -draw-line = - element draw:line { - draw-line-attlist, +draw-plugin = + element draw:plugin { + draw-plugin-attlist, common-draw-data-attlist, draw-param* + } +draw-plugin-attlist = common-draw-mime-type-attlist & xml-id? +# https://issues.oasis-open.org/browse/OFFICE-3943 +draw-polygon = + element draw:polygon { + common-draw-points-attlist, + common-draw-position-attlist, + common-draw-size-attlist, + common-draw-viewbox-attlist, common-draw-shape-with-text-and-styles-attlist, common-draw-caption-id-attlist, svg-title?, @@ -2204,11 +1972,6 @@ draw-line = draw-glue-point*, draw-text } -draw-line-attlist = - attribute svg:x1 { coordinate } - & attribute svg:y1 { coordinate } - & attribute svg:x2 { coordinate } - & attribute svg:y2 { coordinate } draw-polyline = element draw:polyline { common-draw-points-attlist, @@ -2223,13 +1986,11 @@ draw-polyline = draw-glue-point*, draw-text } -common-draw-points-attlist = attribute draw:points { points } -draw-polygon = - element draw:polygon { - common-draw-points-attlist, +draw-rect = + element draw:rect { + draw-rect-attlist, common-draw-position-attlist, common-draw-size-attlist, - common-draw-viewbox-attlist, common-draw-shape-with-text-and-styles-attlist, common-draw-caption-id-attlist, svg-title?, @@ -2238,6 +1999,10 @@ draw-polygon = draw-glue-point*, draw-text } +draw-rect-attlist = + attribute draw:corner-radius { nonNegativeLength }? + | (attribute svg:rx { nonNegativeLength }?, + attribute svg:ry { nonNegativeLength }?) draw-regular-polygon = element draw:regular-polygon { draw-regular-polygon-attlist, @@ -2258,262 +2023,18 @@ draw-regular-polygon-attlist = & attribute draw:corners { positiveInteger } draw-regular-polygon-sharpness-attlist = attribute draw:sharpness { percent } -draw-path = - element draw:path { - common-draw-path-data-attlist, - common-draw-position-attlist, - common-draw-size-attlist, - common-draw-viewbox-attlist, - common-draw-shape-with-text-and-styles-attlist, - common-draw-caption-id-attlist, - svg-title?, - svg-desc?, - office-event-listeners?, - draw-glue-point*, - draw-text - } -common-draw-path-data-attlist = attribute svg:d { pathData } -draw-circle = - element draw:circle { - ((draw-circle-attlist, common-draw-circle-ellipse-pos-attlist) - | (common-draw-position-attlist, common-draw-size-attlist)), - common-draw-circle-ellipse-attlist, - common-draw-shape-with-text-and-styles-attlist, - common-draw-caption-id-attlist, - svg-title?, - svg-desc?, - office-event-listeners?, - draw-glue-point*, - draw-text - } -common-draw-circle-ellipse-pos-attlist = - attribute svg:cx { coordinate }, - attribute svg:cy { coordinate } -draw-circle-attlist = attribute svg:r { length } -common-draw-circle-ellipse-attlist = - attribute draw:kind { "full" | "section" | "cut" | "arc" }? - & attribute draw:start-angle { angle }? - & attribute draw:end-angle { angle }? -draw-ellipse = - element draw:ellipse { - ((draw-ellipse-attlist, common-draw-circle-ellipse-pos-attlist) - | (common-draw-position-attlist, common-draw-size-attlist)), - common-draw-circle-ellipse-attlist, - common-draw-shape-with-text-and-styles-attlist, - common-draw-caption-id-attlist, - svg-title?, - svg-desc?, - office-event-listeners?, - draw-glue-point*, - draw-text - } -draw-ellipse-attlist = - attribute svg:rx { length }, - attribute svg:ry { length } -draw-connector = - element draw:connector { - draw-connector-attlist, - common-draw-shape-with-text-and-styles-attlist, - common-draw-caption-id-attlist, - common-draw-viewbox-attlist, - svg-title?, - svg-desc?, - office-event-listeners?, - draw-glue-point*, - draw-text - } -draw-connector-attlist = - attribute draw:type { "standard" | "lines" | "line" | "curve" }? - & (attribute svg:x1 { coordinate }, - attribute svg:y1 { coordinate })? - & attribute draw:start-shape { IDREF }? - & attribute draw:start-glue-point { nonNegativeInteger }? - & (attribute svg:x2 { coordinate }, - attribute svg:y2 { coordinate })? - & attribute draw:end-shape { IDREF }? - & attribute draw:end-glue-point { nonNegativeInteger }? - & attribute draw:line-skew { - list { length, (length, length?)? } - }? - & attribute svg:d { pathData }? -draw-caption = - element draw:caption { - draw-caption-attlist, - common-draw-position-attlist, - common-draw-size-attlist, - common-draw-shape-with-text-and-styles-attlist, - common-draw-caption-id-attlist, - svg-title?, - svg-desc?, - office-event-listeners?, - draw-glue-point*, - draw-text - } -draw-caption-attlist = - (attribute draw:caption-point-x { coordinate }, - attribute draw:caption-point-y { coordinate })? - & attribute draw:corner-radius { nonNegativeLength }? -draw-measure = - element draw:measure { - draw-measure-attlist, - common-draw-shape-with-text-and-styles-attlist, - common-draw-caption-id-attlist, - svg-title?, - svg-desc?, - office-event-listeners?, - draw-glue-point*, - draw-text - } -draw-measure-attlist = - attribute svg:x1 { coordinate } - & attribute svg:y1 { coordinate } - & attribute svg:x2 { coordinate } - & attribute svg:y2 { coordinate } -draw-control = - element draw:control { - draw-control-attlist, - common-draw-position-attlist, - common-draw-size-attlist, - common-draw-shape-with-text-and-styles-attlist, - common-draw-caption-id-attlist, - svg-title?, - svg-desc?, - draw-glue-point* - } -draw-control-attlist = attribute draw:control { IDREF } -draw-page-thumbnail = - element draw:page-thumbnail { - draw-page-thumbnail-attlist, - common-draw-position-attlist, - common-draw-size-attlist, - presentation-shape-attlist, - common-draw-shape-with-styles-attlist, - common-draw-caption-id-attlist, - svg-title?, - svg-desc? - } -draw-page-thumbnail-attlist = - attribute draw:page-number { positiveInteger }? -draw-g = - element draw:g { - draw-g-attlist, - common-draw-z-index-attlist, - common-draw-name-attlist, - common-draw-id-attlist, - common-draw-style-name-attlist, - common-text-spreadsheet-shape-attlist, - common-draw-caption-id-attlist, - svg-title?, - svg-desc?, - office-event-listeners?, - draw-glue-point*, - shape* - } -draw-g-attlist = attribute svg:y { coordinate }? -common-draw-name-attlist = attribute draw:name { \string }? -common-draw-caption-id-attlist = attribute draw:caption-id { IDREF }? -common-draw-position-attlist = - attribute svg:x { coordinate }?, - attribute svg:y { coordinate }? -common-draw-size-attlist = - attribute svg:width { length }?, - attribute svg:height { length }? -common-draw-transform-attlist = attribute draw:transform { \string }? -common-draw-viewbox-attlist = - attribute svg:viewBox { - list { integer, integer, integer, integer } - } -common-draw-style-name-attlist = - (attribute draw:style-name { styleNameRef }?, - attribute draw:class-names { styleNameRefs }?) - | (attribute presentation:style-name { styleNameRef }?, - attribute presentation:class-names { styleNameRefs }?) -common-draw-text-style-name-attlist = - attribute draw:text-style-name { styleNameRef }? -common-draw-layer-name-attlist = attribute draw:layer { \string }? -common-draw-id-attlist = - (xml-id, - attribute draw:id { NCName }?)? -common-draw-z-index-attlist = - attribute draw:z-index { nonNegativeInteger }? -common-text-spreadsheet-shape-attlist = - attribute table:end-cell-address { cellAddress }? - & attribute table:end-x { coordinate }? - & attribute table:end-y { coordinate }? - & attribute table:table-background { boolean }? - & common-text-anchor-attlist -common-text-anchor-attlist = - attribute text:anchor-type { - "page" | "frame" | "paragraph" | "char" | "as-char" - }? - & attribute text:anchor-page-number { positiveInteger }? +draw-stroke-dash = + element draw:stroke-dash { draw-stroke-dash-attlist, empty } +draw-stroke-dash-attlist = + attribute draw:name { styleName } + & attribute draw:display-name { \string }? + & attribute draw:style { "rect" | "round" }? + & attribute draw:dots1 { integer }? + & attribute draw:dots1-length { length | percent }? + & attribute draw:dots2 { integer }? + & attribute draw:dots2-length { length | percent }? + & attribute draw:distance { length | percent }? draw-text = (text-p | text-list)* -common-draw-shape-with-styles-attlist = - common-draw-z-index-attlist, - common-draw-id-attlist, - common-draw-layer-name-attlist, - common-draw-style-name-attlist, - common-draw-transform-attlist, - common-draw-name-attlist, - common-text-spreadsheet-shape-attlist -common-draw-shape-with-text-and-styles-attlist = - common-draw-shape-with-styles-attlist, - common-draw-text-style-name-attlist -draw-glue-point = - element draw:glue-point { draw-glue-point-attlist, empty } -draw-glue-point-attlist = - attribute draw:id { nonNegativeInteger } - & attribute svg:x { distance | percent } - & attribute svg:y { distance | percent } - & attribute draw:align { - "top-left" - | "top" - | "top-right" - | "left" - | "center" - | "right" - | "bottom-left" - | "bottom-right" - }? - & attribute draw:escape-direction { - "auto" - | "left" - | "right" - | "up" - | "down" - | "horizontal" - | "vertical" - } -svg-title = element svg:title { text } -svg-desc = element svg:desc { text } -draw-frame = - element draw:frame { - common-draw-shape-with-text-and-styles-attlist, - common-draw-position-attlist, - common-draw-rel-size-attlist, - common-draw-caption-id-attlist, - presentation-shape-attlist, - draw-frame-attlist, - (draw-text-box - | draw-image - | draw-object - | draw-object-ole - | draw-applet - | draw-floating-frame - | draw-plugin - | table-table)*, - office-event-listeners?, - draw-glue-point*, - draw-image-map?, - svg-title?, - svg-desc?, - (draw-contour-polygon | draw-contour-path)? - } -common-draw-rel-size-attlist = - common-draw-size-attlist, - attribute style:rel-width { percent | "scale" | "scale-min" }?, - attribute style:rel-height { percent | "scale" | "scale-min" }? -draw-frame-attlist = attribute draw:copy-of { \string }? draw-text-box = element draw:text-box { draw-text-box-attlist, text-content* } draw-text-box-attlist = @@ -2525,2177 +2046,539 @@ draw-text-box-attlist = & attribute fo:max-width { length | percent }? & (xml-id, attribute text:id { NCName }?)? -draw-image = - element draw:image { - draw-image-attlist, - (common-draw-data-attlist | office-binary-data), - draw-text - } -common-draw-data-attlist = - attribute xlink:type { "simple" }, - attribute xlink:href { anyIRI }, - attribute xlink:show { "embed" }?, - attribute xlink:actuate { "onLoad" }? -office-binary-data = element office:binary-data { base64Binary } -draw-image-attlist = - attribute draw:filter-name { \string }? - & xml-id? -draw-object = - element draw:object { - draw-object-attlist, - (common-draw-data-attlist | office-document | math-math) - } -draw-object-ole = - element draw:object-ole { - draw-object-ole-attlist, - (common-draw-data-attlist | office-binary-data) - } -draw-object-attlist = - attribute draw:notify-on-update-of-ranges { - cellRangeAddressList | \string - }? - & xml-id? -draw-object-ole-attlist = - attribute draw:class-id { \string }? - & xml-id? -draw-applet = - element draw:applet { - draw-applet-attlist, common-draw-data-attlist?, draw-param* - } -draw-applet-attlist = - attribute draw:code { \string }? - & attribute draw:object { \string }? - & attribute draw:archive { \string }? - & attribute draw:may-script { boolean }? - & xml-id? -draw-plugin = - element draw:plugin { - draw-plugin-attlist, common-draw-data-attlist, draw-param* - } -draw-plugin-attlist = - attribute draw:mime-type { \string }? - & xml-id? -draw-param = element draw:param { draw-param-attlist, empty } -draw-param-attlist = - attribute draw:name { \string }? - & attribute draw:value { \string }? -draw-floating-frame = - element draw:floating-frame { - draw-floating-frame-attlist, common-draw-data-attlist - } -draw-floating-frame-attlist = - attribute draw:frame-name { \string }? - & xml-id? -draw-contour-polygon = - element draw:contour-polygon { - common-contour-attlist, - common-draw-size-attlist, - common-draw-viewbox-attlist, - common-draw-points-attlist, - empty - } -draw-contour-path = - element draw:contour-path { - common-contour-attlist, - common-draw-size-attlist, - common-draw-viewbox-attlist, - common-draw-path-data-attlist, +dropdown = attribute form:dropdown { boolean }? +duration = xsd:duration +extrusionOrigin = + xsd:double { minInclusive = "-0.5" maxInclusive = "0.5" } +fontFamilyGeneric = + "roman" | "swiss" | "modern" | "decorative" | "script" | "system" +fontPitch = "fixed" | "variable" +fontStyle = "normal" | "italic" | "oblique" +fontVariant = "normal" | "small-caps" +fontWeight = + "normal" + | "bold" + | "100" + | "200" + | "300" + | "400" + | "500" + | "600" + | "700" + | "800" + | "900" +for = attribute form:for { \string }? +form-button-attlist = + form-control-attlist + & button-type + & common-disabled-attlist + & label + & image-data + & common-printable-attlist + & common-tab-attlist + & target-frame + & target-location + & common-title-attlist + & common-value-attlist + & common-form-relative-image-position-attlist + & common-repeat + & common-delay-for-repeat + & attribute form:default-button { boolean }? + & attribute form:toggle { boolean }? + & attribute form:focus-on-click { boolean }? + & attribute form:xforms-submission { \string }? +form-checkbox-attlist = + form-control-attlist + & common-disabled-attlist + & label + & common-printable-attlist + & common-tab-attlist + & common-title-attlist + & common-value-attlist + & common-data-field-attlist + & common-form-visual-effect-attlist + & common-form-relative-image-position-attlist + & common-linked-cell + & attribute form:current-state { states }? + & attribute form:is-tristate { boolean }? + & attribute form:state { states }? +form-column = + element form:column { form-column-attlist, column-controls+ } +form-column-attlist = + common-form-control-attlist, label, text-style-name +form-combobox-attlist = + form-control-attlist + & common-current-value-attlist + & common-disabled-attlist + & dropdown + & common-maxlength-attlist + & common-printable-attlist + & common-readonly-attlist + & size + & common-tab-attlist + & common-title-attlist + & common-value-attlist + & common-convert-empty-attlist + & common-data-field-attlist + & list-source + & list-source-type + & common-linked-cell + & common-source-cell-range + & attribute form:auto-complete { boolean }? +form-connection-resource = + element form:connection-resource { + attribute xlink:href { anyIRI }, empty } -common-contour-attlist = attribute draw:recreate-on-edit { boolean } -draw-a = element draw:a { draw-a-attlist, shape-instance } -draw-a-attlist = - attribute xlink:type { "simple" } - & attribute xlink:href { anyIRI } - & attribute xlink:actuate { "onRequest" }? - & attribute office:target-frame-name { targetFrameName }? - & attribute xlink:show { "new" | "replace" }? - & attribute office:name { \string }? - & attribute office:title { \string }? - & attribute office:server-map { boolean }? - & xml-id? -draw-image-map = - element draw:image-map { - (draw-area-rectangle | draw-area-circle | draw-area-polygon)* - } -draw-area-rectangle = - element draw:area-rectangle { - common-draw-area-attlist, - attribute svg:x { coordinate }, - attribute svg:y { coordinate }, - attribute svg:width { length }, - attribute svg:height { length }, - svg-title?, - svg-desc?, - office-event-listeners? - } -draw-area-circle = - element draw:area-circle { - common-draw-area-attlist, - attribute svg:cx { coordinate }, - attribute svg:cy { coordinate }, - attribute svg:r { length }, - svg-title?, - svg-desc?, - office-event-listeners? - } -draw-area-polygon = - element draw:area-polygon { - common-draw-area-attlist, - attribute svg:x { coordinate }, - attribute svg:y { coordinate }, - attribute svg:width { length }, - attribute svg:height { length }, - common-draw-viewbox-attlist, - common-draw-points-attlist, - svg-title?, - svg-desc?, - office-event-listeners? +form-control-attlist = + common-form-control-attlist, + common-control-id-attlist, + xforms-bind-attlist +form-date-attlist = + attribute form:value { date }? + & attribute form:current-value { date }? + & attribute form:min-value { date }? + & attribute form:max-value { date }? +form-file-attlist = + form-control-attlist, + common-current-value-attlist, + common-disabled-attlist, + common-maxlength-attlist, + common-printable-attlist, + common-readonly-attlist, + common-tab-attlist, + common-title-attlist, + common-value-attlist, + common-linked-cell +form-fixed-text-attlist = + form-control-attlist + & for + & common-disabled-attlist + & label + & common-printable-attlist + & common-title-attlist + & attribute form:multi-line { boolean }? +form-form = + element form:form { + common-form-control-attlist, + form-form-attlist, + form-properties?, + office-event-listeners?, + (controls | form-form)*, + form-connection-resource? } -common-draw-area-attlist = +form-form-attlist = (attribute xlink:type { "simple" }, attribute xlink:href { anyIRI }, - attribute office:target-frame-name { targetFrameName }?, - attribute xlink:show { "new" | "replace" }?)? - & attribute office:name { \string }? - & attribute draw:nohref { "nohref" }? -dr3d-scene = - element dr3d:scene { - dr3d-scene-attlist, - common-draw-position-attlist, - common-draw-size-attlist, - common-draw-style-name-attlist, - common-draw-z-index-attlist, - common-draw-id-attlist, - common-draw-layer-name-attlist, - common-text-spreadsheet-shape-attlist, - common-dr3d-transform-attlist, - common-draw-caption-id-attlist, - svg-title?, - svg-desc?, - dr3d-light*, - shapes3d*, - draw-glue-point* - } -shapes3d = - dr3d-scene | dr3d-extrude | dr3d-sphere | dr3d-rotate | dr3d-cube -dr3d-scene-attlist = - attribute dr3d:vrp { vector3D }? - & attribute dr3d:vpn { vector3D }? - & attribute dr3d:vup { vector3D }? - & attribute dr3d:projection { "parallel" | "perspective" }? - & attribute dr3d:distance { length }? - & attribute dr3d:focal-length { length }? - & attribute dr3d:shadow-slant { angle }? - & attribute dr3d:shade-mode { - "flat" | "phong" | "gouraud" | "draft" - }? - & attribute dr3d:ambient-color { color }? - & attribute dr3d:lighting-mode { boolean }? -common-dr3d-transform-attlist = attribute dr3d:transform { \string }? -dr3d-light = element dr3d:light { dr3d-light-attlist, empty } -dr3d-light-attlist = - attribute dr3d:diffuse-color { color }? - & attribute dr3d:direction { vector3D } - & attribute dr3d:enabled { boolean }? - & attribute dr3d:specular { boolean }? -dr3d-cube = - element dr3d:cube { - dr3d-cube-attlist, - common-draw-z-index-attlist, - common-draw-id-attlist, - common-draw-layer-name-attlist, - common-draw-style-name-attlist, - common-dr3d-transform-attlist, - empty - } -dr3d-cube-attlist = - attribute dr3d:min-edge { vector3D }?, - attribute dr3d:max-edge { vector3D }? -dr3d-sphere = - element dr3d:sphere { - dr3d-sphere-attlist, - common-draw-z-index-attlist, - common-draw-id-attlist, - common-draw-layer-name-attlist, - common-draw-style-name-attlist, - common-dr3d-transform-attlist, - empty - } -dr3d-sphere-attlist = - attribute dr3d:center { vector3D }? - & attribute dr3d:size { vector3D }? -dr3d-extrude = - element dr3d:extrude { - common-draw-path-data-attlist, - common-draw-viewbox-attlist, - common-draw-id-attlist, - common-draw-z-index-attlist, - common-draw-layer-name-attlist, - common-draw-style-name-attlist, - common-dr3d-transform-attlist, - empty - } -dr3d-rotate = - element dr3d:rotate { - common-draw-viewbox-attlist, - common-draw-path-data-attlist, - common-draw-z-index-attlist, - common-draw-id-attlist, - common-draw-layer-name-attlist, - common-draw-style-name-attlist, - common-dr3d-transform-attlist, - empty - } -draw-custom-shape = - element draw:custom-shape { - draw-custom-shape-attlist, - common-draw-position-attlist, - common-draw-size-attlist, - common-draw-shape-with-text-and-styles-attlist, - common-draw-caption-id-attlist, - svg-title?, - svg-desc?, - office-event-listeners?, - draw-glue-point*, - draw-text, - draw-enhanced-geometry? - } -draw-custom-shape-attlist = - attribute draw:engine { namespacedToken }? - & attribute draw:data { \string }? -draw-enhanced-geometry = - element draw:enhanced-geometry { - draw-enhanced-geometry-attlist, draw-equation*, draw-handle* - } -draw-enhanced-geometry-attlist = - attribute draw:type { custom-shape-type }? - & attribute svg:viewBox { - list { integer, integer, integer, integer } - }? - & attribute draw:mirror-vertical { boolean }? - & attribute draw:mirror-horizontal { boolean }? - & attribute draw:text-rotate-angle { angle }? - & attribute draw:extrusion-allowed { boolean }? - & attribute draw:text-path-allowed { boolean }? - & attribute draw:concentric-gradient-fill-allowed { boolean }? - & attribute draw:extrusion { boolean }? - & attribute draw:extrusion-brightness { zeroToHundredPercent }? - & attribute draw:extrusion-depth { - list { length, double } - }? - & attribute draw:extrusion-diffusion { percent }? - & attribute draw:extrusion-number-of-line-segments { integer }? - & attribute draw:extrusion-light-face { boolean }? - & attribute draw:extrusion-first-light-harsh { boolean }? - & attribute draw:extrusion-second-light-harsh { boolean }? - & attribute draw:extrusion-first-light-level { zeroToHundredPercent }? - & attribute draw:extrusion-second-light-level { - zeroToHundredPercent - }? - & attribute draw:extrusion-first-light-direction { vector3D }? - & attribute draw:extrusion-second-light-direction { vector3D }? - & attribute draw:extrusion-metal { boolean }? - & attribute dr3d:shade-mode { - "flat" | "phong" | "gouraud" | "draft" - }? - & attribute draw:extrusion-rotation-angle { - list { angle, angle } - }? - & attribute draw:extrusion-rotation-center { vector3D }? - & attribute draw:extrusion-shininess { zeroToHundredPercent }? - & attribute draw:extrusion-skew { - list { double, angle } - }? - & attribute draw:extrusion-specularity { zeroToHundredPercent }? - & attribute dr3d:projection { "parallel" | "perspective" }? - & attribute draw:extrusion-viewpoint { point3D }? - & attribute draw:extrusion-origin { - list { extrusionOrigin, extrusionOrigin } - }? - & attribute draw:extrusion-color { boolean }? - & attribute draw:enhanced-path { \string }? - & attribute draw:path-stretchpoint-x { double }? - & attribute draw:path-stretchpoint-y { double }? - & attribute draw:text-areas { \string }? - & attribute draw:glue-points { \string }? - & attribute draw:glue-point-type { - "none" | "segments" | "rectangle" - }? - & attribute draw:glue-point-leaving-directions { \string }? - & attribute draw:text-path { boolean }? - & attribute draw:text-path-mode { "normal" | "path" | "shape" }? - & attribute draw:text-path-scale { "path" | "shape" }? - & attribute draw:text-path-same-letter-heights { boolean }? - & attribute draw:modifiers { \string }? -custom-shape-type = "non-primitive" | \string -point3D = - xsd:string { - pattern = - "\([ ]*-?([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc))([ ]+-?([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc))){2}[ ]*\)" - } -extrusionOrigin = - xsd:double { minInclusive = "-0.5" maxInclusive = "0.5" } -draw-equation = element draw:equation { draw-equation-attlist, empty } -draw-equation-attlist = - attribute draw:name { \string }? - & attribute draw:formula { \string }? -draw-handle = element draw:handle { draw-handle-attlist, empty } -draw-handle-attlist = - attribute draw:handle-mirror-vertical { boolean }? - & attribute draw:handle-mirror-horizontal { boolean }? - & attribute draw:handle-switched { boolean }? - & attribute draw:handle-position { \string } - & attribute draw:handle-range-x-minimum { \string }? - & attribute draw:handle-range-x-maximum { \string }? - & attribute draw:handle-range-y-minimum { \string }? - & attribute draw:handle-range-y-maximum { \string }? - & attribute draw:handle-polar { \string }? - & attribute draw:handle-radius-range-minimum { \string }? - & attribute draw:handle-radius-range-maximum { \string }? -presentation-shape-attlist = - attribute presentation:class { presentation-classes }? - & attribute presentation:placeholder { boolean }? - & attribute presentation:user-transformed { boolean }? -presentation-classes = - "title" - | "outline" - | "subtitle" - | "text" - | "graphic" - | "object" - | "chart" - | "table" - | "orgchart" - | "page" - | "notes" - | "handout" - | "header" - | "footer" - | "date-time" - | "page-number" -presentation-animations = - element presentation:animations { - (presentation-animation-elements | presentation-animation-group)* - } -presentation-animation-elements = - presentation-show-shape - | presentation-show-text - | presentation-hide-shape - | presentation-hide-text - | presentation-dim - | presentation-play -presentation-sound = - element presentation:sound { - presentation-sound-attlist, - attribute xlink:type { "simple" }, - attribute xlink:href { anyIRI }, - attribute xlink:actuate { "onRequest" }?, - attribute xlink:show { "new" | "replace" }?, - empty - } -presentation-sound-attlist = - attribute presentation:play-full { boolean }? - & xml-id? -presentation-show-shape = - element presentation:show-shape { - common-presentation-effect-attlist, presentation-sound? - } -common-presentation-effect-attlist = - attribute draw:shape-id { IDREF } - & attribute presentation:effect { presentationEffects }? - & attribute presentation:direction { presentationEffectDirections }? - & attribute presentation:speed { presentationSpeeds }? - & attribute presentation:delay { duration }? - & attribute presentation:start-scale { percent }? - & attribute presentation:path-id { \string }? -presentationEffects = - "none" - | "fade" - | "move" - | "stripes" - | "open" - | "close" - | "dissolve" - | "wavyline" - | "random" - | "lines" - | "laser" - | "appear" - | "hide" - | "move-short" - | "checkerboard" - | "rotate" - | "stretch" -presentationEffectDirections = - "none" - | "from-left" - | "from-top" - | "from-right" - | "from-bottom" - | "from-center" - | "from-upper-left" - | "from-upper-right" - | "from-lower-left" - | "from-lower-right" - | "to-left" - | "to-top" - | "to-right" - | "to-bottom" - | "to-upper-left" - | "to-upper-right" - | "to-lower-right" - | "to-lower-left" - | "path" - | "spiral-inward-left" - | "spiral-inward-right" - | "spiral-outward-left" - | "spiral-outward-right" - | "vertical" - | "horizontal" - | "to-center" - | "clockwise" - | "counter-clockwise" -presentationSpeeds = "slow" | "medium" | "fast" -presentation-show-text = - element presentation:show-text { - common-presentation-effect-attlist, presentation-sound? - } -presentation-hide-shape = - element presentation:hide-shape { - common-presentation-effect-attlist, presentation-sound? - } -presentation-hide-text = - element presentation:hide-text { - common-presentation-effect-attlist, presentation-sound? - } -presentation-dim = - element presentation:dim { - presentation-dim-attlist, presentation-sound? - } -presentation-dim-attlist = - attribute draw:shape-id { IDREF } - & attribute draw:color { color } -presentation-play = - element presentation:play { presentation-play-attlist, empty } -presentation-play-attlist = - attribute draw:shape-id { IDREF }, - attribute presentation:speed { presentationSpeeds }? -presentation-animation-group = - element presentation:animation-group { - presentation-animation-elements* - } -common-anim-attlist = - attribute presentation:node-type { - "default" - | "on-click" - | "with-previous" - | "after-previous" - | "timing-root" - | "main-sequence" - | "interactive-sequence" - }? - & attribute presentation:preset-id { \string }? - & attribute presentation:preset-sub-type { \string }? - & attribute presentation:preset-class { - "custom" - | "entrance" - | "exit" - | "emphasis" - | "motion-path" - | "ole-action" - | "media-call" - }? - & attribute presentation:master-element { IDREF }? - & attribute presentation:group-id { \string }? - & (xml-id, - attribute anim:id { NCName }?)? -presentation-event-listener = - element presentation:event-listener { - presentation-event-listener-attlist, presentation-sound? - } -presentation-event-listener-attlist = - attribute script:event-name { \string } - & attribute presentation:action { - "none" - | "previous-page" - | "next-page" - | "first-page" - | "last-page" - | "hide" - | "stop" - | "execute" - | "show" - | "verb" - | "fade-out" - | "sound" - | "last-visited-page" - } - & attribute presentation:effect { presentationEffects }? - & attribute presentation:direction { presentationEffectDirections }? - & attribute presentation:speed { presentationSpeeds }? - & attribute presentation:start-scale { percent }? - & (attribute xlink:type { "simple" }, - attribute xlink:href { anyIRI }, - attribute xlink:show { "embed" }?, - attribute xlink:actuate { "onRequest" }?)? - & attribute presentation:verb { nonNegativeInteger }? -presentation-decls = presentation-decl* -presentation-decl = - element presentation:header-decl { - presentation-header-decl-attlist, text - } - | element presentation:footer-decl { - presentation-footer-decl-attlist, text - } - | element presentation:date-time-decl { - presentation-date-time-decl-attlist, text - } -presentation-header-decl-attlist = - attribute presentation:name { \string } -presentation-footer-decl-attlist = - attribute presentation:name { \string } -presentation-date-time-decl-attlist = - attribute presentation:name { \string } - & attribute presentation:source { "fixed" | "current-date" } - & attribute style:data-style-name { styleNameRef }? -presentation-settings = - element presentation:settings { - presentation-settings-attlist, presentation-show* - }? -presentation-settings-attlist = - attribute presentation:start-page { \string }? - & attribute presentation:show { \string }? - & attribute presentation:full-screen { boolean }? - & attribute presentation:endless { boolean }? - & attribute presentation:pause { duration }? - & attribute presentation:show-logo { boolean }? - & attribute presentation:force-manual { boolean }? - & attribute presentation:mouse-visible { boolean }? - & attribute presentation:mouse-as-pen { boolean }? - & attribute presentation:start-with-navigator { boolean }? - & attribute presentation:animations { "enabled" | "disabled" }? - & attribute presentation:transition-on-click { - "enabled" | "disabled" - }? - & attribute presentation:stay-on-top { boolean }? - & attribute presentation:show-end-of-presentation-slide { boolean }? -presentation-show = - element presentation:show { presentation-show-attlist, empty } -presentation-show-attlist = - attribute presentation:name { \string } - & attribute presentation:pages { \string } -chart-chart = - element chart:chart { - chart-chart-attlist, - chart-title?, - chart-subtitle?, - chart-footer?, - chart-legend?, - chart-plot-area, - table-table? - } -chart-chart-attlist = - attribute chart:class { namespacedToken } - & common-draw-size-attlist - & attribute chart:column-mapping { \string }? - & attribute chart:row-mapping { \string }? - & attribute chart:style-name { styleNameRef }? - & (attribute xlink:type { "simple" }, - attribute xlink:href { anyIRI })? - & xml-id? -chart-title = element chart:title { chart-title-attlist, text-p? } -chart-title-attlist = - attribute table:cell-range { cellRangeAddressList }? - & common-draw-position-attlist - & attribute chart:style-name { styleNameRef }? -chart-subtitle = element chart:subtitle { chart-title-attlist, text-p? } -chart-footer = element chart:footer { chart-title-attlist, text-p? } -chart-legend = element chart:legend { chart-legend-attlist, text-p? } -chart-legend-attlist = - ((attribute chart:legend-position { - "start" | "end" | "top" | "bottom" - }, - attribute chart:legend-align { "start" | "center" | "end" }?) - | attribute chart:legend-position { - "top-start" | "bottom-start" | "top-end" | "bottom-end" - } - | empty) - & common-draw-position-attlist - & (attribute style:legend-expansion { "wide" | "high" | "balanced" } - | (attribute style:legend-expansion { "custom" }, - attribute style:legend-expansion-aspect-ratio { double }) - | empty) - & attribute chart:style-name { styleNameRef }? -chart-plot-area = - element chart:plot-area { - chart-plot-area-attlist, - dr3d-light*, - chart-axis*, - chart-series*, - chart-stock-gain-marker?, - chart-stock-loss-marker?, - chart-stock-range-line?, - chart-wall?, - chart-floor? - } -chart-plot-area-attlist = - common-draw-position-attlist - & common-draw-size-attlist - & attribute chart:style-name { styleNameRef }? - & attribute table:cell-range-address { cellRangeAddressList }? - & attribute chart:data-source-has-labels { - "none" | "row" | "column" | "both" - }? - & dr3d-scene-attlist - & common-dr3d-transform-attlist - & xml-id? -chart-wall = element chart:wall { chart-wall-attlist, empty } -chart-wall-attlist = - attribute svg:width { length }? - & attribute chart:style-name { styleNameRef }? -chart-floor = element chart:floor { chart-floor-attlist, empty } -chart-floor-attlist = - attribute svg:width { length }? - & attribute chart:style-name { styleNameRef }? -chart-axis = - element chart:axis { - chart-axis-attlist, chart-title?, chart-categories?, chart-grid* - } -chart-axis-attlist = - attribute chart:dimension { chart-dimension } - & attribute chart:name { \string }? - & attribute chart:style-name { styleNameRef }? -chart-dimension = "x" | "y" | "z" -chart-categories = - element chart:categories { - attribute table:cell-range-address { cellRangeAddressList }? - } -chart-grid = element chart:grid { chart-grid-attlist } -chart-grid-attlist = - attribute chart:class { "major" | "minor" }? - & attribute chart:style-name { styleNameRef }? -chart-series = - element chart:series { - chart-series-attlist, - chart-domain*, - chart-mean-value?, - chart-regression-curve*, - chart-error-indicator*, - chart-data-point*, - chart-data-label? - } -chart-series-attlist = - attribute chart:values-cell-range-address { cellRangeAddressList }? - & attribute chart:label-cell-address { cellRangeAddressList }? - & attribute chart:class { namespacedToken }? - & attribute chart:attached-axis { \string }? - & attribute chart:style-name { styleNameRef }? - & xml-id? -chart-domain = - element chart:domain { - attribute table:cell-range-address { cellRangeAddressList }? - } -chart-data-point = - element chart:data-point { - chart-data-point-attlist, chart-data-label? - } -chart-data-point-attlist = - attribute chart:repeated { positiveInteger }? - & attribute chart:style-name { styleNameRef }? - & xml-id? -chart-data-label = - element chart:data-label { chart-data-label-attlist, text-p? } -chart-data-label-attlist = - common-draw-position-attlist - & attribute chart:style-name { styleNameRef }? -chart-mean-value = - element chart:mean-value { chart-mean-value-attlist, empty } -chart-mean-value-attlist = attribute chart:style-name { styleNameRef }? -chart-error-indicator = - element chart:error-indicator { chart-error-indicator-attlist, empty } -chart-error-indicator-attlist = - attribute chart:style-name { styleNameRef }? - & attribute chart:dimension { chart-dimension } -chart-regression-curve = - element chart:regression-curve { - chart-regression-curve-attlist, chart-equation? - } -chart-regression-curve-attlist = - attribute chart:style-name { styleNameRef }? -chart-equation = - element chart:equation { chart-equation-attlist, text-p? } -chart-equation-attlist = - attribute chart:automatic-content { boolean }? - & attribute chart:display-r-square { boolean }? - & attribute chart:display-equation { boolean }? - & common-draw-position-attlist - & attribute chart:style-name { styleNameRef }? -chart-stock-gain-marker = - element chart:stock-gain-marker { common-stock-marker-attlist } -chart-stock-loss-marker = - element chart:stock-loss-marker { common-stock-marker-attlist } -chart-stock-range-line = - element chart:stock-range-line { common-stock-marker-attlist } -common-stock-marker-attlist = - attribute chart:style-name { styleNameRef }? -office-database = - element office:database { - db-data-source, - db-forms?, - db-reports?, - db-queries?, - db-table-presentations?, - db-schema-definition? - } -db-data-source = - element db:data-source { - db-data-source-attlist, - db-connection-data, - db-driver-settings?, - db-application-connection-settings? - } -db-data-source-attlist = empty -db-connection-data = - element db:connection-data { - db-connection-data-attlist, - (db-database-description | db-connection-resource), - db-login? - } -db-connection-data-attlist = empty -db-database-description = - element db:database-description { - db-database-description-attlist, - (db-file-based-database | db-server-database) - } -db-database-description-attlist = empty -db-file-based-database = - element db:file-based-database { db-file-based-database-attlist } -db-file-based-database-attlist = - attribute xlink:type { "simple" } - & attribute xlink:href { anyIRI } - & attribute db:media-type { \string } - & attribute db:extension { \string }? -db-server-database = - element db:server-database { db-server-database-attlist, empty } -db-server-database-attlist = - attribute db:type { namespacedToken } - & (db-host-and-port | db-local-socket-name) - & attribute db:database-name { \string }? -db-host-and-port = - attribute db:hostname { \string }, - attribute db:port { positiveInteger }? -db-local-socket-name = attribute db:local-socket { \string }? -db-connection-resource = - element db:connection-resource { - db-connection-resource-attlist, empty - } -db-connection-resource-attlist = - attribute xlink:type { "simple" }, - attribute xlink:href { anyIRI }, - attribute xlink:show { "none" }?, - attribute xlink:actuate { "onRequest" }? -db-login = element db:login { db-login-attlist, empty } -db-login-attlist = - (attribute db:user-name { \string } - | attribute db:use-system-user { boolean })? - & attribute db:is-password-required { boolean }? - & attribute db:login-timeout { positiveInteger }? -db-driver-settings = - element db:driver-settings { - db-driver-settings-attlist, - db-auto-increment?, - db-delimiter?, - db-character-set?, - db-table-settings? - } -db-driver-settings-attlist = - db-show-deleted - & attribute db:system-driver-settings { \string }? - & attribute db:base-dn { \string }? - & db-is-first-row-header-line - & attribute db:parameter-name-substitution { boolean }? -db-show-deleted = attribute db:show-deleted { boolean }? -db-is-first-row-header-line = - attribute db:is-first-row-header-line { boolean }? -db-auto-increment = - element db:auto-increment { db-auto-increment-attlist, empty } -db-auto-increment-attlist = - attribute db:additional-column-statement { \string }? - & attribute db:row-retrieving-statement { \string }? -db-delimiter = element db:delimiter { db-delimiter-attlist, empty } -db-delimiter-attlist = - attribute db:field { \string }? - & attribute db:string { \string }? - & attribute db:decimal { \string }? - & attribute db:thousand { \string }? -db-character-set = - element db:character-set { db-character-set-attlist, empty } -db-character-set-attlist = attribute db:encoding { textEncoding }? -db-table-settings = element db:table-settings { db-table-setting* } -db-table-setting = - element db:table-setting { - db-table-setting-attlist, db-delimiter?, db-character-set?, empty - } -db-table-setting-attlist = db-is-first-row-header-line, db-show-deleted -db-application-connection-settings = - element db:application-connection-settings { - db-application-connection-settings-attlist, - db-table-filter?, - db-table-type-filter?, - db-data-source-settings? - } -db-application-connection-settings-attlist = - attribute db:is-table-name-length-limited { boolean }? - & attribute db:enable-sql92-check { boolean }? - & attribute db:append-table-alias-name { boolean }? - & attribute db:ignore-driver-privileges { boolean }? - & attribute db:boolean-comparison-mode { - "equal-integer" - | "is-boolean" - | "equal-boolean" - | "equal-use-only-zero" - }? - & attribute db:use-catalog { boolean }? - & attribute db:max-row-count { integer }? - & attribute db:suppress-version-columns { boolean }? -db-table-filter = - element db:table-filter { - db-table-filter-attlist, - db-table-include-filter?, - db-table-exclude-filter? - } -db-table-filter-attlist = empty -db-table-include-filter = - element db:table-include-filter { - db-table-include-filter-attlist, db-table-filter-pattern+ - } -db-table-include-filter-attlist = empty -db-table-exclude-filter = - element db:table-exclude-filter { - db-table-exclude-filter-attlist, db-table-filter-pattern+ - } -db-table-exclude-filter-attlist = empty -db-table-filter-pattern = - element db:table-filter-pattern { - db-table-filter-pattern-attlist, \string - } -db-table-filter-pattern-attlist = empty -db-table-type-filter = - element db:table-type-filter { - db-table-type-filter-attlist, db-table-type* - } -db-table-type-filter-attlist = empty -db-table-type = element db:table-type { db-table-type-attlist, \string } -db-table-type-attlist = empty -db-data-source-settings = - element db:data-source-settings { - db-data-source-settings-attlist, db-data-source-setting+ - } -db-data-source-settings-attlist = empty -db-data-source-setting = - element db:data-source-setting { - db-data-source-setting-attlist, db-data-source-setting-value+ - } -db-data-source-setting-attlist = - attribute db:data-source-setting-is-list { boolean }? - & attribute db:data-source-setting-name { \string } - & attribute db:data-source-setting-type { - db-data-source-setting-types - } -db-data-source-setting-types = - "boolean" | "short" | "int" | "long" | "double" | "string" -db-data-source-setting-value = - element db:data-source-setting-value { - db-data-source-setting-value-attlist, \string - } -db-data-source-setting-value-attlist = empty -db-forms = - element db:forms { - db-forms-attlist, (db-component | db-component-collection)* - } -db-forms-attlist = empty -db-reports = - element db:reports { - db-reports-attlist, (db-component | db-component-collection)* - } -db-reports-attlist = empty -db-component-collection = - element db:component-collection { - db-component-collection-attlist, - common-db-object-name, - common-db-object-title, - common-db-object-description, - (db-component | db-component-collection)* - } -db-component-collection-attlist = empty -db-component = - element db:component { - db-component-attlist, - common-db-object-name, - common-db-object-title, - common-db-object-description, - (office-document | math-math)? - } -db-component-attlist = - (attribute xlink:type { "simple" }, - attribute xlink:href { anyIRI }, - attribute xlink:show { "none" }?, - attribute xlink:actuate { "onRequest" }?)? - & attribute db:as-template { boolean }? -db-queries = - element db:queries { - db-queries-attlist, (db-query | db-query-collection)* - } -db-queries-attlist = empty -db-query-collection = - element db:query-collection { - db-query-collection-attlist, - common-db-object-name, - common-db-object-title, - common-db-object-description, - (db-query | db-query-collection)* - } -db-query-collection-attlist = empty -db-query = - element db:query { - db-query-attlist, - common-db-object-name, - common-db-object-title, - common-db-object-description, - common-db-table-style-name, - db-order-statement?, - db-filter-statement?, - db-columns?, - db-update-table? - } -db-query-attlist = - attribute db:command { \string } - & attribute db:escape-processing { boolean }? -db-order-statement = - element db:order-statement { db-command, db-apply-command, empty } -db-filter-statement = - element db:filter-statement { db-command, db-apply-command, empty } -db-update-table = - element db:update-table { common-db-table-name-attlist } -db-table-presentations = - element db:table-representations { - db-table-presentations-attlist, db-table-presentation* - } -db-table-presentations-attlist = empty -db-table-presentation = - element db:table-representation { - db-table-presentation-attlist, - common-db-table-name-attlist, - common-db-object-title, - common-db-object-description, - common-db-table-style-name, - db-order-statement?, - db-filter-statement?, - db-columns? - } -db-table-presentation-attlist = empty -db-columns = element db:columns { db-columns-attlist, db-column+ } -db-columns-attlist = empty -db-column = - element db:column { - db-column-attlist, - common-db-object-name, - common-db-object-title, - common-db-object-description, - common-db-default-value - } -db-column-attlist = - attribute db:visible { boolean }? - & attribute db:style-name { styleNameRef }? - & attribute db:default-cell-style-name { styleNameRef }? -db-command = attribute db:command { \string } -db-apply-command = attribute db:apply-command { boolean }? -common-db-table-name-attlist = - attribute db:name { \string } - & attribute db:catalog-name { \string }? - & attribute db:schema-name { \string }? -common-db-object-name = attribute db:name { \string } -common-db-object-title = attribute db:title { \string }? -common-db-object-description = attribute db:description { \string }? -common-db-table-style-name = - attribute db:style-name { styleNameRef }? - & attribute db:default-row-style-name { styleNameRef }? -common-db-default-value = common-value-and-type-attlist? -db-schema-definition = - element db:schema-definition { - db-schema-definition-attlist, db-table-definitions - } -db-schema-definition-attlist = empty -db-table-definitions = - element db:table-definitions { - db-table-definitions-attlist, db-table-definition* - } -db-table-definitions-attlist = empty -db-table-definition = - element db:table-definition { - common-db-table-name-attlist, - db-table-definition-attlist, - db-column-definitions, - db-keys?, - db-indices? - } -db-table-definition-attlist = attribute db:type { \string }? -db-column-definitions = - element db:column-definitions { - db-column-definitions-attlist, db-column-definition+ - } -db-column-definitions-attlist = empty -db-column-definition = - element db:column-definition { - db-column-definition-attlist, common-db-default-value - } -db-column-definition-attlist = - attribute db:name { \string } - & attribute db:data-type { db-data-types }? - & attribute db:type-name { \string }? - & attribute db:precision { positiveInteger }? - & attribute db:scale { positiveInteger }? - & attribute db:is-nullable { "no-nulls" | "nullable" }? - & attribute db:is-empty-allowed { boolean }? - & attribute db:is-autoincrement { boolean }? -db-data-types = - "bit" - | "boolean" - | "tinyint" - | "smallint" - | "integer" - | "bigint" - | "float" - | "real" - | "double" - | "numeric" - | "decimal" - | "char" - | "varchar" - | "longvarchar" - | "date" - | "time" - | "timestmp" - | "binary" - | "varbinary" - | "longvarbinary" - | "sqlnull" - | "other" - | "object" - | "distinct" - | "struct" - | "array" - | "blob" - | "clob" - | "ref" -db-keys = element db:keys { db-keys-attlist, db-key+ } -db-keys-attlist = empty -db-key = element db:key { db-key-attlist, db-key-columns+ } -db-key-attlist = - attribute db:name { \string }? - & attribute db:type { "primary" | "unique" | "foreign" } - & attribute db:referenced-table-name { \string }? - & attribute db:update-rule { - "cascade" | "restrict" | "set-null" | "no-action" | "set-default" - }? - & attribute db:delete-rule { - "cascade" | "restrict" | "set-null" | "no-action" | "set-default" - }? -db-key-columns = - element db:key-columns { db-key-columns-attlist, db-key-column+ } -db-key-columns-attlist = empty -db-key-column = element db:key-column { db-key-column-attlist, empty } -db-key-column-attlist = - attribute db:name { \string }? - & attribute db:related-column-name { \string }? -db-indices = element db:indices { db-indices-attlist, db-index+ } -db-indices-attlist = empty -db-index = element db:index { db-index-attlist, db-index-columns+ } -db-index-attlist = - attribute db:name { \string } - & attribute db:catalog-name { \string }? - & attribute db:is-unique { boolean }? - & attribute db:is-clustered { boolean }? -db-index-columns = element db:index-columns { db-index-column+ } -db-index-column = - element db:index-column { db-index-column-attlist, empty } -db-index-column-attlist = - attribute db:name { \string } - & attribute db:is-ascending { boolean }? -office-forms = - element office:forms { - office-forms-attlist, (form-form | xforms-model)* - }? -office-forms-attlist = - attribute form:automatic-focus { boolean }? - & attribute form:apply-design-mode { boolean }? -form-form = - element form:form { - common-form-control-attlist, - form-form-attlist, - form-properties?, - office-event-listeners?, - (controls | form-form)*, - form-connection-resource? - } -form-form-attlist = - (attribute xlink:type { "simple" }, - attribute xlink:href { anyIRI }, - attribute xlink:actuate { "onRequest" }?)? - & attribute office:target-frame { targetFrameName }? - & attribute form:method { "get" | "post" | \string }? - & attribute form:enctype { \string }? - & attribute form:allow-deletes { boolean }? - & attribute form:allow-inserts { boolean }? - & attribute form:allow-updates { boolean }? - & attribute form:apply-filter { boolean }? - & attribute form:command-type { "table" | "query" | "command" }? - & attribute form:command { \string }? - & attribute form:datasource { anyIRI | \string }? - & attribute form:master-fields { \string }? - & attribute form:detail-fields { \string }? - & attribute form:escape-processing { boolean }? - & attribute form:filter { \string }? - & attribute form:ignore-result { boolean }? - & attribute form:navigation-mode { navigation }? - & attribute form:order { \string }? - & attribute form:tab-cycle { tab-cycles }? -navigation = "none" | "current" | "parent" -tab-cycles = "records" | "current" | "page" -form-connection-resource = - element form:connection-resource { - attribute xlink:href { anyIRI }, - empty - } -xforms-model = element xforms:model { anyAttListOrElements } -column-controls = - element form:text { form-text-attlist, common-form-control-content } - | element form:textarea { - form-textarea-attlist, common-form-control-content, text-p* - } - | element form:formatted-text { - form-formatted-text-attlist, common-form-control-content - } - | element form:number { - form-number-attlist, - common-numeric-control-attlist, - common-form-control-content, - common-linked-cell, - common-spin-button, - common-repeat, - common-delay-for-repeat - } - | element form:date { - form-date-attlist, - common-numeric-control-attlist, - common-form-control-content, - common-linked-cell, - common-spin-button, - common-repeat, - common-delay-for-repeat - } - | element form:time { - form-time-attlist, - common-numeric-control-attlist, - common-form-control-content, - common-linked-cell, - common-spin-button, - common-repeat, - common-delay-for-repeat - } - | element form:combobox { - form-combobox-attlist, common-form-control-content, form-item* - } - | element form:listbox { - form-listbox-attlist, common-form-control-content, form-option* - } - | element form:checkbox { - form-checkbox-attlist, common-form-control-content - } -controls = - column-controls - | element form:password { - form-password-attlist, common-form-control-content - } - | element form:file { form-file-attlist, common-form-control-content } - | element form:fixed-text { - form-fixed-text-attlist, common-form-control-content - } - | element form:button { - form-button-attlist, common-form-control-content - } - | element form:image { - form-image-attlist, common-form-control-content - } - | element form:radio { - form-radio-attlist, common-form-control-content - } - | element form:frame { - form-frame-attlist, common-form-control-content - } - | element form:image-frame { - form-image-frame-attlist, common-form-control-content - } - | element form:hidden { - form-hidden-attlist, common-form-control-content - } - | element form:grid { - form-grid-attlist, common-form-control-content, form-column* - } - | element form:value-range { - form-value-range-attlist, common-form-control-content - } - | element form:generic-control { - form-generic-control-attlist, common-form-control-content - } -form-text-attlist = - form-control-attlist, - common-current-value-attlist, - common-disabled-attlist, - common-maxlength-attlist, - common-printable-attlist, - common-readonly-attlist, - common-tab-attlist, - common-title-attlist, - common-value-attlist, - common-convert-empty-attlist, - common-data-field-attlist, - common-linked-cell -form-control-attlist = - common-form-control-attlist, - common-control-id-attlist, - xforms-bind-attlist -common-form-control-content = form-properties?, office-event-listeners? -form-textarea-attlist = - form-control-attlist, - common-current-value-attlist, - common-disabled-attlist, - common-maxlength-attlist, - common-printable-attlist, - common-readonly-attlist, - common-tab-attlist, - common-title-attlist, - common-value-attlist, - common-convert-empty-attlist, - common-data-field-attlist, - common-linked-cell -form-password-attlist = - form-control-attlist - & common-disabled-attlist - & common-maxlength-attlist - & common-printable-attlist - & common-tab-attlist - & common-title-attlist - & common-value-attlist - & common-convert-empty-attlist - & common-linked-cell - & attribute form:echo-char { character }? -form-file-attlist = - form-control-attlist, - common-current-value-attlist, - common-disabled-attlist, - common-maxlength-attlist, - common-printable-attlist, - common-readonly-attlist, - common-tab-attlist, - common-title-attlist, - common-value-attlist, - common-linked-cell -form-formatted-text-attlist = - form-control-attlist - & common-current-value-attlist - & common-disabled-attlist - & common-maxlength-attlist - & common-printable-attlist - & common-readonly-attlist - & common-tab-attlist - & common-title-attlist - & common-value-attlist - & common-convert-empty-attlist - & common-data-field-attlist - & common-linked-cell - & common-spin-button - & common-repeat - & common-delay-for-repeat - & attribute form:max-value { \string }? - & attribute form:min-value { \string }? - & attribute form:validation { boolean }? -common-numeric-control-attlist = - form-control-attlist, - common-disabled-attlist, - common-maxlength-attlist, - common-printable-attlist, - common-readonly-attlist, - common-tab-attlist, - common-title-attlist, - common-convert-empty-attlist, - common-data-field-attlist -form-number-attlist = - attribute form:value { double }? - & attribute form:current-value { double }? - & attribute form:min-value { double }? - & attribute form:max-value { double }? -form-date-attlist = - attribute form:value { date }? - & attribute form:current-value { date }? - & attribute form:min-value { date }? - & attribute form:max-value { date }? -form-time-attlist = - attribute form:value { time }? - & attribute form:current-value { time }? - & attribute form:min-value { time }? - & attribute form:max-value { time }? -form-fixed-text-attlist = - form-control-attlist - & for - & common-disabled-attlist - & label - & common-printable-attlist - & common-title-attlist - & attribute form:multi-line { boolean }? -form-combobox-attlist = - form-control-attlist - & common-current-value-attlist - & common-disabled-attlist - & dropdown - & common-maxlength-attlist - & common-printable-attlist - & common-readonly-attlist - & size - & common-tab-attlist - & common-title-attlist - & common-value-attlist - & common-convert-empty-attlist - & common-data-field-attlist - & list-source - & list-source-type - & common-linked-cell - & common-source-cell-range - & attribute form:auto-complete { boolean }? -form-item = element form:item { form-item-attlist, text } -form-item-attlist = label -form-listbox-attlist = - form-control-attlist - & common-disabled-attlist - & dropdown - & common-printable-attlist - & size - & common-tab-attlist - & common-title-attlist - & bound-column - & common-data-field-attlist - & list-source - & list-source-type - & common-linked-cell - & list-linkage-type - & common-source-cell-range - & attribute form:multiple { boolean }? - & attribute form:xforms-list-source { \string }? -list-linkage-type = - attribute form:list-linkage-type { - "selection" | "selection-indices" - }? -form-option = element form:option { form-option-attlist, text } -form-option-attlist = - current-selected, selected, label, common-value-attlist -form-button-attlist = - form-control-attlist - & button-type - & common-disabled-attlist - & label - & image-data - & common-printable-attlist - & common-tab-attlist - & target-frame - & target-location - & common-title-attlist - & common-value-attlist - & common-form-relative-image-position-attlist - & common-repeat - & common-delay-for-repeat - & attribute form:default-button { boolean }? - & attribute form:toggle { boolean }? - & attribute form:focus-on-click { boolean }? - & attribute form:xforms-submission { \string }? -form-image-attlist = - form-control-attlist, - button-type, - common-disabled-attlist, - image-data, - common-printable-attlist, - common-tab-attlist, - target-frame, - target-location, - common-title-attlist, - common-value-attlist -form-checkbox-attlist = - form-control-attlist - & common-disabled-attlist - & label - & common-printable-attlist - & common-tab-attlist - & common-title-attlist - & common-value-attlist - & common-data-field-attlist - & common-form-visual-effect-attlist - & common-form-relative-image-position-attlist - & common-linked-cell - & attribute form:current-state { states }? - & attribute form:is-tristate { boolean }? - & attribute form:state { states }? -states = "unchecked" | "checked" | "unknown" -form-radio-attlist = - form-control-attlist, - current-selected, - common-disabled-attlist, - label, - common-printable-attlist, - selected, - common-tab-attlist, - common-title-attlist, - common-value-attlist, - common-data-field-attlist, - common-form-visual-effect-attlist, - common-form-relative-image-position-attlist, - common-linked-cell -form-frame-attlist = - form-control-attlist, - common-disabled-attlist, - for, - label, - common-printable-attlist, - common-title-attlist -form-image-frame-attlist = - form-control-attlist, - common-disabled-attlist, - image-data, - common-printable-attlist, - common-readonly-attlist, - common-title-attlist, - common-data-field-attlist -form-hidden-attlist = form-control-attlist, common-value-attlist -form-grid-attlist = - form-control-attlist, - common-disabled-attlist, - common-printable-attlist, - common-tab-attlist, - common-title-attlist -form-column = - element form:column { form-column-attlist, column-controls+ } -form-column-attlist = - common-form-control-attlist, label, text-style-name -text-style-name = attribute form:text-style-name { styleNameRef }? -form-value-range-attlist = - form-control-attlist - & common-disabled-attlist - & common-printable-attlist - & common-tab-attlist - & common-title-attlist - & common-value-attlist - & common-linked-cell - & common-repeat - & common-delay-for-repeat - & attribute form:max-value { integer }? - & attribute form:min-value { integer }? - & attribute form:step-size { positiveInteger }? - & attribute form:page-step-size { positiveInteger }? - & attribute form:orientation { "horizontal" | "vertical" }? -form-generic-control-attlist = form-control-attlist -common-form-control-attlist = - attribute form:name { \string }? - & attribute form:control-implementation { namespacedToken }? -xforms-bind-attlist = attribute xforms:bind { \string }? -types = "submit" | "reset" | "push" | "url" -button-type = attribute form:button-type { types }? -common-control-id-attlist = - xml-id, - attribute form:id { NCName }? -current-selected = attribute form:current-selected { boolean }? -common-value-attlist = attribute form:value { \string }? -common-current-value-attlist = attribute form:current-value { \string }? -common-disabled-attlist = attribute form:disabled { boolean }? -dropdown = attribute form:dropdown { boolean }? -for = attribute form:for { \string }? -image-data = attribute form:image-data { anyIRI }? -label = attribute form:label { \string }? -common-maxlength-attlist = - attribute form:max-length { nonNegativeInteger }? -common-printable-attlist = attribute form:printable { boolean }? -common-readonly-attlist = attribute form:readonly { boolean }? -selected = attribute form:selected { boolean }? -size = attribute form:size { nonNegativeInteger }? -common-tab-attlist = - attribute form:tab-index { nonNegativeInteger }? - & attribute form:tab-stop { boolean }? -target-frame = attribute office:target-frame { targetFrameName }? -target-location = attribute xlink:href { anyIRI }? -common-title-attlist = attribute form:title { \string }? -common-form-visual-effect-attlist = - attribute form:visual-effect { "flat" | "3d" }? -common-form-relative-image-position-attlist = - attribute form:image-position { "center" }? - | (attribute form:image-position { - "start" | "end" | "top" | "bottom" - }, - attribute form:image-align { "start" | "center" | "end" }?) -bound-column = attribute form:bound-column { \string }? -common-convert-empty-attlist = - attribute form:convert-empty-to-null { boolean }? -common-data-field-attlist = attribute form:data-field { \string }? -list-source = attribute form:list-source { \string }? -list-source-type = - attribute form:list-source-type { - "table" - | "query" - | "sql" - | "sql-pass-through" - | "value-list" - | "table-fields" - }? -common-linked-cell = - attribute form:linked-cell { cellAddress | \string }? -common-source-cell-range = - attribute form:source-cell-range { cellRangeAddress | \string }? -common-spin-button = attribute form:spin-button { boolean }? -common-repeat = attribute form:repeat { boolean }? -common-delay-for-repeat = attribute form:delay-for-repeat { duration }? -form-properties = element form:properties { form-property+ } -form-property = - element form:property { - form-property-name, form-property-value-and-type-attlist - } - | element form:list-property { - form-property-name, form-property-type-and-value-list - } -form-property-name = attribute form:property-name { \string } -form-property-value-and-type-attlist = - common-value-and-type-attlist - | attribute office:value-type { "void" } -form-property-type-and-value-list = - (attribute office:value-type { "float" }, - element form:list-value { - attribute office:value { double } - }*) - | (attribute office:value-type { "percentage" }, - element form:list-value { - attribute office:value { double } - }*) - | (attribute office:value-type { "currency" }, - element form:list-value { - attribute office:value { double }, - attribute office:currency { \string }? - }*) - | (attribute office:value-type { "date" }, - element form:list-value { - attribute office:date-value { dateOrDateTime } - }*) - | (attribute office:value-type { "time" }, - element form:list-value { - attribute office:time-value { duration } - }*) - | (attribute office:value-type { "boolean" }, - element form:list-value { - attribute office:boolean-value { boolean } - }*) - | (attribute office:value-type { "string" }, - element form:list-value { - attribute office:string-value { \string } - }*) - | attribute office:value-type { "void" } -office-annotation = - element office:annotation { - office-annotation-attlist, - draw-caption-attlist, - common-draw-position-attlist, - common-draw-size-attlist, - common-draw-shape-with-text-and-styles-attlist, - dc-creator?, - dc-date?, - meta-date-string?, - (text-p | text-list)* - } -office-annotation-end = - element office:annotation-end { office-annotation-end-attlist } -office-annotation-attlist = - attribute office:display { boolean }? - & common-office-annotation-name-attlist? -office-annotation-end-attlist = common-office-annotation-name-attlist -common-office-annotation-name-attlist = - attribute office:name { \string } -meta-date-string = element meta:date-string { \string } -common-num-format-prefix-suffix-attlist = - attribute style:num-prefix { \string }?, - attribute style:num-suffix { \string }? -common-num-format-attlist = - attribute style:num-format { "1" | "i" | "I" | \string | empty } - | (attribute style:num-format { "a" | "A" }, - style-num-letter-sync-attlist) - | empty -style-num-letter-sync-attlist = - attribute style:num-letter-sync { boolean }? -office-change-info = - element office:change-info { dc-creator, dc-date, text-p* } -office-event-listeners = - element office:event-listeners { - (script-event-listener | presentation-event-listener)* - } -script-event-listener = - element script:event-listener { script-event-listener-attlist, empty } -script-event-listener-attlist = - attribute script:event-name { \string } - & attribute script:language { \string } - & (attribute script:macro-name { \string } - | (attribute xlink:type { "simple" }, - attribute xlink:href { anyIRI }, - attribute xlink:actuate { "onRequest" }?)) -math-math = element math:math { mathMarkup } -[ - dc:description [ - "To avoid inclusion of the complete MathML schema, anything is allowed within a math:math top-level element" - ] -] -mathMarkup = - (attribute * { text } - | text - | element * { mathMarkup })* -text-dde-connection-decl = - element text:dde-connection-decl { - text-dde-connection-decl-attlist, common-dde-connection-decl-attlist - } -text-dde-connection-decl-attlist = attribute office:name { \string } -common-dde-connection-decl-attlist = - attribute office:dde-application { \string } - & attribute office:dde-topic { \string } - & attribute office:dde-item { \string } - & attribute office:automatic-update { boolean }? -table-dde-link = - element table:dde-link { office-dde-source, table-table } -office-dde-source = - element office:dde-source { - office-dde-source-attlist, common-dde-connection-decl-attlist - } -office-dde-source-attlist = - attribute office:name { \string }? - & attribute office:conversion-mode { - "into-default-style-data-style" - | "into-english-number" - | "keep-text" - }? -animation-element = - element anim:animate { - common-anim-target-attlist, - common-anim-named-target-attlist, - common-anim-values-attlist, - common-anim-spline-mode-attlist, - common-spline-anim-value-attlist, - common-timing-attlist, - common-anim-add-accum-attlist - } - | element anim:set { - common-anim-target-attlist, - common-anim-named-target-attlist, - common-anim-set-values-attlist, - common-timing-attlist, - common-anim-add-accum-attlist - } - | element anim:animateMotion { - anim-animate-motion-attlist, - common-anim-target-attlist, - common-anim-named-target-attlist, - common-anim-add-accum-attlist, - common-anim-values-attlist, - common-timing-attlist, - common-spline-anim-value-attlist - } - | element anim:animateColor { - common-anim-target-attlist, - common-anim-named-target-attlist, - common-anim-add-accum-attlist, - common-anim-values-attlist, - common-anim-spline-mode-attlist, - common-spline-anim-value-attlist, - anim-animate-color-attlist, - common-timing-attlist - } - | element anim:animateTransform { - common-anim-target-attlist, - common-anim-named-target-attlist, - common-anim-add-accum-attlist, - common-anim-values-attlist, - anim-animate-transform-attlist, - common-timing-attlist - } - | element anim:transitionFilter { - common-anim-target-attlist, - common-anim-add-accum-attlist, - common-anim-values-attlist, - common-anim-spline-mode-attlist, - anim-transition-filter-attlist, - common-timing-attlist - } - | element anim:par { - common-anim-attlist, - common-timing-attlist, - common-endsync-timing-attlist, - animation-element* - } - | element anim:seq { - common-anim-attlist, - common-endsync-timing-attlist, - common-timing-attlist, - animation-element* - } - | element anim:iterate { - common-anim-attlist, - anim-iterate-attlist, - common-timing-attlist, - common-endsync-timing-attlist, - animation-element* - } - | element anim:audio { - common-anim-attlist, - anim-audio-attlist, - common-basic-timing-attlist - } - | element anim:command { - common-anim-attlist, - anim-command-attlist, - common-begin-end-timing-attlist, - common-anim-target-attlist, - element anim:param { - attribute anim:name { \string }, - attribute anim:value { \string } - }* - } -anim-animate-motion-attlist = - attribute svg:path { pathData }? - & attribute svg:origin { \string }? - & attribute smil:calcMode { - "discrete" | "linear" | "paced" | "spline" - }? -anim-animate-color-attlist = - attribute anim:color-interpolation { "rgb" | "hsl" }? - & attribute anim:color-interpolation-direction { - "clockwise" | "counter-clockwise" - }? -anim-animate-transform-attlist = - attribute svg:type { - "translate" | "scale" | "rotate" | "skewX" | "skewY" - } -anim-transition-filter-attlist = - attribute smil:type { \string } - & attribute smil:subtype { \string }? - & attribute smil:direction { "forward" | "reverse" }? - & attribute smil:fadeColor { color }? - & attribute smil:mode { "in" | "out" }? -common-anim-target-attlist = - attribute smil:targetElement { IDREF }? - & attribute anim:sub-item { \string }? -common-anim-named-target-attlist = - attribute smil:attributeName { \string } -common-anim-values-attlist = - attribute smil:values { \string }? - & attribute anim:formula { \string }? - & common-anim-set-values-attlist - & attribute smil:from { \string }? - & attribute smil:by { \string }? -common-anim-spline-mode-attlist = - attribute smil:calcMode { - "discrete" | "linear" | "paced" | "spline" - }? -common-spline-anim-value-attlist = - attribute smil:keyTimes { \string }? - & attribute smil:keySplines { \string }? -common-anim-add-accum-attlist = - attribute smil:accumulate { "none" | "sum" }? - & attribute smil:additive { "replace" | "sum" }? -common-anim-set-values-attlist = attribute smil:to { \string }? -common-begin-end-timing-attlist = - attribute smil:begin { \string }? - & attribute smil:end { \string }? -common-dur-timing-attlist = attribute smil:dur { \string }? -common-endsync-timing-attlist = - attribute smil:endsync { "first" | "last" | "all" | "media" | IDREF }? -common-repeat-timing-attlist = - attribute smil:repeatDur { \string }?, - attribute smil:repeatCount { nonNegativeDecimal | "indefinite" }? -nonNegativeDecimal = xsd:decimal { minInclusive = "0.0" } -common-fill-timing-attlist = - attribute smil:fill { - "remove" | "freeze" | "hold" | "auto" | "default" | "transition" - }? -common-fill-default-attlist = - attribute smil:fillDefault { - "remove" | "freeze" | "hold" | "transition" | "auto" | "inherit" - }? -common-restart-timing-attlist = - attribute smil:restart { - "never" | "always" | "whenNotActive" | "default" - }? -common-restart-default-attlist = - attribute smil:restartDefault { - "never" | "always" | "whenNotActive" | "inherit" - }? -common-time-manip-attlist = - attribute smil:accelerate { zeroToOneDecimal }? - & attribute smil:decelerate { zeroToOneDecimal }? - & attribute smil:autoReverse { boolean }? -zeroToOneDecimal = xsd:decimal { minInclusive = "0" maxInclusive = "1" } -common-basic-timing-attlist = - common-begin-end-timing-attlist, - common-dur-timing-attlist, - common-repeat-timing-attlist, - common-restart-timing-attlist, - common-restart-default-attlist, - common-fill-timing-attlist, - common-fill-default-attlist -common-timing-attlist = - common-basic-timing-attlist, common-time-manip-attlist -anim-iterate-attlist = - common-anim-target-attlist - & attribute anim:iterate-type { \string }? - & attribute anim:iterate-interval { duration }? -anim-audio-attlist = - attribute xlink:href { anyIRI }? - & attribute anim:audio-level { double }? -anim-command-attlist = attribute anim:command { \string } -style-style = - element style:style { - style-style-attlist, style-style-content, style-map* - } -common-in-content-meta-attlist = - attribute xhtml:about { URIorSafeCURIE }, - attribute xhtml:property { CURIEs }, - common-meta-literal-attlist -common-meta-literal-attlist = - attribute xhtml:datatype { CURIE }?, - attribute xhtml:content { \string }? -xml-id = attribute xml:id { ID } -style-style-attlist = - attribute style:name { styleName } - & attribute style:display-name { \string }? - & attribute style:parent-style-name { styleNameRef }? - & attribute style:next-style-name { styleNameRef }? - & attribute style:list-level { positiveInteger | empty }? - & attribute style:list-style-name { styleName | empty }? - & attribute style:master-page-name { styleNameRef }? - & attribute style:auto-update { boolean }? - & attribute style:data-style-name { styleNameRef }? - & attribute style:percentage-data-style-name { styleNameRef }? - & attribute style:class { \string }? - & attribute style:default-outline-level { positiveInteger | empty }? -style-map = element style:map { style-map-attlist, empty } -style-map-attlist = - attribute style:condition { \string } - & attribute style:apply-style-name { styleNameRef } - & attribute style:base-cell-address { cellAddress }? -style-default-style = - element style:default-style { style-style-content } -style-page-layout = - element style:page-layout { - style-page-layout-attlist, style-page-layout-content - } -style-page-layout-content = - style-page-layout-properties?, - style-header-style?, - style-footer-style? -style-page-layout-attlist = - attribute style:name { styleName } - & attribute style:page-usage { - "all" | "left" | "right" | "mirrored" - }? -style-header-style = - element style:header-style { style-header-footer-properties? } -style-footer-style = - element style:footer-style { style-header-footer-properties? } -style-default-page-layout = - element style:default-page-layout { style-page-layout-content } -style-master-page = - element style:master-page { - style-master-page-attlist, - (style-header, style-header-left?)?, - (style-footer, style-footer-left?)?, - draw-layer-set?, - office-forms?, - shape*, - animation-element?, - presentation-notes? - } -style-master-page-attlist = - attribute style:name { styleName } - & attribute style:display-name { \string }? - & attribute style:page-layout-name { styleNameRef } - & attribute draw:style-name { styleNameRef }? - & attribute style:next-style-name { styleNameRef }? -style-header = - element style:header { - common-style-header-footer-attlist, header-footer-content - } -style-footer = - element style:footer { - common-style-header-footer-attlist, header-footer-content - } -style-header-left = - element style:header-left { - common-style-header-footer-attlist, header-footer-content - } -style-footer-left = - element style:footer-left { - common-style-header-footer-attlist, header-footer-content - } -header-footer-content = - (text-tracked-changes, - text-decls, - (text-h - | text-p - | text-list - | table-table - | text-section - | text-table-of-content - | text-illustration-index - | text-table-index - | text-object-index - | text-user-index - | text-alphabetical-index - | text-bibliography - | text-index-title - | change-marks)*) - | (style-region-left?, style-region-center?, style-region-right?) -common-style-header-footer-attlist = - attribute style:display { boolean }? -style-region-left = element style:region-left { region-content } -style-region-center = element style:region-center { region-content } -style-region-right = element style:region-right { region-content } -region-content = text-p* -presentation-notes = - element presentation:notes { - common-presentation-header-footer-attlist, - presentation-notes-attlist, - office-forms, - shape* - } -presentation-notes-attlist = - attribute style:page-layout-name { styleNameRef }? - & attribute draw:style-name { styleNameRef }? -table-table-template = - element table:table-template { - table-table-template-attlist, - table-first-row?, - table-last-row?, - table-first-column?, - table-last-column?, - table-body, - table-even-rows?, - table-odd-rows?, - table-even-columns?, - table-odd-columns?, - table-background? - } -table-table-template-attlist = - attribute table:name { \string } - & attribute table:first-row-start-column { rowOrCol } - & attribute table:first-row-end-column { rowOrCol } - & attribute table:last-row-start-column { rowOrCol } - & attribute table:last-row-end-column { rowOrCol } -rowOrCol = "row" | "column" -table-first-row = - element table:first-row { common-table-template-attlist, empty } -table-last-row = - element table:last-row { common-table-template-attlist, empty } -table-first-column = - element table:first-column { common-table-template-attlist, empty } -table-last-column = - element table:last-column { common-table-template-attlist, empty } -table-body = element table:body { common-table-template-attlist, empty } -table-even-rows = - element table:even-rows { common-table-template-attlist, empty } -table-odd-rows = - element table:odd-rows { common-table-template-attlist, empty } -table-even-columns = - element table:even-columns { common-table-template-attlist, empty } -table-odd-columns = - element table:odd-columns { common-table-template-attlist, empty } -common-table-template-attlist = - attribute table:style-name { styleNameRef }, - attribute table:paragraph-style-name { styleNameRef }? -table-background = - element table:background { table-background-attlist, empty } -table-background-attlist = attribute table:style-name { styleNameRef } -style-font-face = - element style:font-face { - style-font-face-attlist, svg-font-face-src?, svg-definition-src? - } -style-font-face-attlist = - attribute svg:font-family { \string }? - & attribute svg:font-style { fontStyle }? - & attribute svg:font-variant { fontVariant }? - & attribute svg:font-weight { fontWeight }? - & attribute svg:font-stretch { - "normal" - | "ultra-condensed" - | "extra-condensed" - | "condensed" - | "semi-condensed" - | "semi-expanded" - | "expanded" - | "extra-expanded" - | "ultra-expanded" - }? - & attribute svg:font-size { positiveLength }? - & attribute svg:unicode-range { \string }? - & attribute svg:units-per-em { integer }? - & attribute svg:panose-1 { \string }? - & attribute svg:stemv { integer }? - & attribute svg:stemh { integer }? - & attribute svg:slope { integer }? - & attribute svg:cap-height { integer }? - & attribute svg:x-height { integer }? - & attribute svg:accent-height { integer }? - & attribute svg:ascent { integer }? - & attribute svg:descent { integer }? - & attribute svg:widths { \string }? - & attribute svg:bbox { \string }? - & attribute svg:ideographic { integer }? - & attribute svg:alphabetic { integer }? - & attribute svg:mathematical { integer }? - & attribute svg:hanging { integer }? - & attribute svg:v-ideographic { integer }? - & attribute svg:v-alphabetic { integer }? - & attribute svg:v-mathematical { integer }? - & attribute svg:v-hanging { integer }? - & attribute svg:underline-position { integer }? - & attribute svg:underline-thickness { integer }? - & attribute svg:strikethrough-position { integer }? - & attribute svg:strikethrough-thickness { integer }? - & attribute svg:overline-position { integer }? - & attribute svg:overline-thickness { integer }? - & attribute style:name { \string } - & attribute style:font-adornments { \string }? - & attribute style:font-family-generic { fontFamilyGeneric }? - & attribute style:font-pitch { fontPitch }? - & attribute style:font-charset { textEncoding }? -svg-font-face-src = - element svg:font-face-src { - (svg-font-face-uri | svg-font-face-name)+ - } -svg-font-face-uri = - element svg:font-face-uri { - common-svg-font-face-xlink-attlist, svg-font-face-format* - } -svg-font-face-format = - element svg:font-face-format { - attribute svg:string { \string }?, - empty + attribute xlink:actuate { "onRequest" }?)? + & attribute office:target-frame { targetFrameName }? + & attribute form:method { "get" | "post" | \string }? + & attribute form:enctype { \string }? + & attribute form:allow-deletes { boolean }? + & attribute form:allow-inserts { boolean }? + & attribute form:allow-updates { boolean }? + & attribute form:apply-filter { boolean }? + & attribute form:command-type { "table" | "query" | "command" }? + & attribute form:command { \string }? + & attribute form:datasource { anyIRI | \string }? + & attribute form:master-fields { \string }? + & attribute form:detail-fields { \string }? + & attribute form:escape-processing { boolean }? + & attribute form:filter { \string }? + & attribute form:ignore-result { boolean }? + & attribute form:navigation-mode { navigation }? + & attribute form:order { \string }? + & attribute form:tab-cycle { tab-cycles }? +form-formatted-text-attlist = + form-control-attlist + & common-current-value-attlist + & common-disabled-attlist + & common-maxlength-attlist + & common-printable-attlist + & common-readonly-attlist + & common-tab-attlist + & common-title-attlist + & common-value-attlist + & common-convert-empty-attlist + & common-data-field-attlist + & common-linked-cell + & common-spin-button + & common-repeat + & common-delay-for-repeat + & attribute form:max-value { \string }? + & attribute form:min-value { \string }? + & attribute form:validation { boolean }? +form-frame-attlist = + form-control-attlist, + common-disabled-attlist, + for, + label, + common-printable-attlist, + common-title-attlist +form-generic-control-attlist = form-control-attlist +form-grid-attlist = + form-control-attlist, + common-disabled-attlist, + common-printable-attlist, + common-tab-attlist, + common-title-attlist +form-hidden-attlist = form-control-attlist, common-value-attlist +form-image-attlist = + form-control-attlist, + button-type, + common-disabled-attlist, + image-data, + common-printable-attlist, + common-tab-attlist, + target-frame, + target-location, + common-title-attlist, + common-value-attlist +form-image-frame-attlist = + form-control-attlist, + common-disabled-attlist, + image-data, + common-printable-attlist, + common-readonly-attlist, + common-title-attlist, + common-data-field-attlist +form-item = element form:item { form-item-attlist, text } +form-item-attlist = label +form-listbox-attlist = + form-control-attlist + & common-disabled-attlist + & dropdown + & common-printable-attlist + & size + & common-tab-attlist + & common-title-attlist + & bound-column + & common-data-field-attlist + & list-source + & list-source-type + & common-linked-cell + & list-linkage-type + & common-source-cell-range + & attribute form:multiple { boolean }? + & attribute form:xforms-list-source { \string }? +form-number-attlist = + attribute form:value { double }? + & attribute form:current-value { double }? + & attribute form:min-value { double }? + & attribute form:max-value { double }? +form-option = element form:option { form-option-attlist, text } +form-option-attlist = + current-selected, selected, label, common-value-attlist +form-password-attlist = + form-control-attlist + & common-disabled-attlist + & common-maxlength-attlist + & common-printable-attlist + & common-tab-attlist + & common-title-attlist + & common-value-attlist + & common-convert-empty-attlist + & common-linked-cell + & attribute form:echo-char { character }? +form-properties = element form:properties { form-property+ } +form-property = + element form:property { + form-property-name, form-property-value-and-type-attlist } -svg-font-face-name = - element svg:font-face-name { - attribute svg:name { \string }?, - empty + | element form:list-property { + form-property-name, form-property-type-and-value-list + } +form-property-name = attribute form:property-name { \string } +form-property-type-and-value-list = + (attribute office:value-type { "float" }, + element form:list-value { + attribute office:value { double } + }*) + | (attribute office:value-type { "percentage" }, + element form:list-value { + attribute office:value { double } + }*) + | (attribute office:value-type { "currency" }, + element form:list-value { + attribute office:value { double }, + attribute office:currency { \string }? + }*) + | (attribute office:value-type { "date" }, + element form:list-value { + attribute office:date-value { dateOrDateTime } + }*) + | (attribute office:value-type { "time" }, + element form:list-value { + attribute office:time-value { duration } + }*) + | (attribute office:value-type { "boolean" }, + element form:list-value { + attribute office:boolean-value { boolean } + }*) + | (attribute office:value-type { "string" }, + element form:list-value { + attribute office:string-value { \string } + }*) + | attribute office:value-type { "void" } +form-property-value-and-type-attlist = + common-value-and-type-attlist + | attribute office:value-type { "void" } +form-radio-attlist = + form-control-attlist, + current-selected, + common-disabled-attlist, + label, + common-printable-attlist, + selected, + common-tab-attlist, + common-title-attlist, + common-value-attlist, + common-data-field-attlist, + common-form-visual-effect-attlist, + common-form-relative-image-position-attlist, + common-linked-cell +form-text-attlist = + form-control-attlist, + common-current-value-attlist, + common-disabled-attlist, + common-maxlength-attlist, + common-printable-attlist, + common-readonly-attlist, + common-tab-attlist, + common-title-attlist, + common-value-attlist, + common-convert-empty-attlist, + common-data-field-attlist, + common-linked-cell +form-textarea-attlist = + form-control-attlist, + common-current-value-attlist, + common-disabled-attlist, + common-maxlength-attlist, + common-printable-attlist, + common-readonly-attlist, + common-tab-attlist, + common-title-attlist, + common-value-attlist, + common-convert-empty-attlist, + common-data-field-attlist, + common-linked-cell +form-time-attlist = + attribute form:value { time }? + & attribute form:current-value { time }? + & attribute form:min-value { time }? + & attribute form:max-value { time }? +form-value-range-attlist = + form-control-attlist + & common-disabled-attlist + & common-printable-attlist + & common-tab-attlist + & common-title-attlist + & common-value-attlist + & common-linked-cell + & common-repeat + & common-delay-for-repeat + & attribute form:max-value { integer }? + & attribute form:min-value { integer }? + & attribute form:step-size { positiveInteger }? + & attribute form:page-step-size { positiveInteger }? + & attribute form:orientation { "horizontal" | "vertical" }? +gradient-style = + "linear" | "axial" | "radial" | "ellipsoid" | "square" | "rectangular" +header-footer-content = + (text-tracked-changes, + text-decls, + (text-h + | text-p + | text-list + | table-table + | text-section + | text-table-of-content + | text-illustration-index + | text-table-index + | text-object-index + | text-user-index + | text-alphabetical-index + | text-bibliography + | text-index-title + | change-marks)*) + | (style-region-left?, style-region-center?, style-region-right?) +heading-attrs = + attribute text:outline-level { positiveInteger } + & attribute text:restart-numbering { boolean }? + & attribute text:start-value { nonNegativeInteger }? + & attribute text:is-list-header { boolean }? +horiBackPos = "left" | "center" | "right" +horizontal-mirror = + "horizontal" | "horizontal-on-odd" | "horizontal-on-even" +image-data = attribute form:image-data { anyIRI }? +index-content-main = text-content | text-index-title +integer = xsd:integer +label = attribute form:label { \string }? +labelPositions = + "avoid-overlap" + | "center" + | "top" + | "top-right" + | "right" + | "bottom-right" + | "bottom" + | "bottom-left" + | "left" + | "top-left" + | "inside" + | "outside" + | "near-origin" +language = xsd:language +languageCode = xsd:token { pattern = "[A-Za-z]{1,8}" } +length = + xsd:string { + pattern = + "-?([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc)|(px))" } -svg-definition-src = - element svg:definition-src { - common-svg-font-face-xlink-attlist, empty +lineMode = "continuous" | "skip-white-space" +lineStyle = + "none" + | "solid" + | "dotted" + | "dash" + | "long-dash" + | "dot-dash" + | "dot-dot-dash" + | "wave" +lineType = "none" | "single" | "double" +lineWidth = + "auto" + | "normal" + | "bold" + | "thin" + | "medium" + | "thick" + | positiveInteger + | percent + | positiveLength +list-linkage-type = + attribute form:list-linkage-type { + "selection" | "selection-indices" + }? +list-source = attribute form:list-source { \string }? +list-source-type = + attribute form:list-source-type { + "table" + | "query" + | "sql" + | "sql-pass-through" + | "value-list" + | "table-fields" + }? +math-math = element math:math { mathMarkup } +[ + dc:description [ + "To avoid inclusion of the complete MathML schema, anything is allowed within a math:math top-level element" + ] +] +mathMarkup = + (attribute * { text } + | text + | element * { mathMarkup })* +meta-date-string = element meta:date-string { \string } +namespacedToken = xsd:QName { pattern = "[^:]+:[^:]+" } +navigation = "none" | "current" | "parent" +nonNegativeDecimal = xsd:decimal { minInclusive = "0.0" } +nonNegativeInteger = xsd:nonNegativeInteger +nonNegativeLength = + xsd:string { + pattern = + "([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc)|(px))" } -common-svg-font-face-xlink-attlist = - attribute xlink:type { "simple" }, - attribute xlink:href { anyIRI }, - attribute xlink:actuate { "onRequest" }? -number-number-style = - element number:number-style { +nonNegativePixelLength = + xsd:string { pattern = "([0-9]+(\.[0-9]*)?|\.[0-9]+)(px)" } +number-am-pm = element number:am-pm { empty } +number-and-text = + number-number, + (number-text-with-fillchar?) + # https://issues.oasis-open.org/browse/OFFICE-3765 + +number-boolean = element number:boolean { empty } +number-boolean-style = + element number:boolean-style { common-data-style-attlist, style-text-properties?, number-text?, - (any-number, number-text?)?, + (number-boolean, number-text?)?, style-map* } -any-number = number-number | number-scientific-number | number-fraction -number-number = - element number:number { - number-number-attlist, - common-decimal-places-attlist, - common-number-attlist, - number-embedded-text* - } -number-number-attlist = - attribute number:decimal-replacement { \string }? - & attribute number:display-factor { double }? -number-embedded-text = - element number:embedded-text { number-embedded-text-attlist, text } -number-embedded-text-attlist = attribute number:position { integer } -number-scientific-number = - element number:scientific-number { - number-scientific-number-attlist, - common-decimal-places-attlist, - common-number-attlist, - empty - } -number-scientific-number-attlist = - attribute number:min-exponent-digits { integer }? -number-fraction = - element number:fraction { - number-fraction-attlist, common-number-attlist, empty - } -number-fraction-attlist = - attribute number:min-numerator-digits { integer }? - & attribute number:min-denominator-digits { integer }? - & attribute number:denominator-value { integer }? number-currency-style = element number:currency-style { common-data-style-attlist, common-auto-reorder-attlist, style-text-properties?, - number-text?, + number-text-with-fillchar?, + # https://issues.oasis-open.org/browse/OFFICE-3765 ((number-and-text, currency-symbol-and-text?) | (currency-symbol-and-text, number-and-text?))?, style-map* } -currency-symbol-and-text = number-currency-symbol, number-text? -number-and-text = number-number, number-text? number-currency-symbol = - element number:currency-symbol { - number-currency-symbol-attlist, text - } -number-currency-symbol-attlist = - attribute number:language { languageCode }?, - attribute number:country { countryCode }?, - attribute number:script { scriptCode }?, - attribute number:rfc-language-tag { language }? -number-percentage-style = - element number:percentage-style { - common-data-style-attlist, - style-text-properties?, - number-text?, - number-and-text?, - style-map* + element number:currency-symbol { + number-currency-symbol-attlist, text } +number-currency-symbol-attlist = + attribute number:language { languageCode }?, + attribute number:country { countryCode }?, + attribute number:script { scriptCode }?, + attribute number:rfc-language-tag { language }? number-date-style = element number:date-style { common-data-style-attlist, common-auto-reorder-attlist, common-format-source-attlist, style-text-properties?, - number-text?, - (any-date, number-text?)+, + number-text-with-fillchar?, + # https://issues.oasis-open.org/browse/OFFICE-3765 + (any-date, + (number-text-with-fillchar?) + # https://issues.oasis-open.org/browse/OFFICE-3765 + )+, style-map* } -any-date = - number-day - | number-month - | number-year - | number-era - | number-day-of-week - | number-week-of-year - | number-quarter - | number-hours - | number-am-pm - | number-minutes - | number-seconds number-day = element number:day { number-day-attlist, common-calendar-attlist, empty } number-day-attlist = attribute number:style { "short" | "long" }? +number-day-of-week = + element number:day-of-week { + number-day-of-week-attlist, common-calendar-attlist, empty + } +number-day-of-week-attlist = + attribute number:style { "short" | "long" }? +number-embedded-text = + element number:embedded-text { number-embedded-text-attlist, text } +number-embedded-text-attlist = attribute number:position { integer } +number-era = + element number:era { + number-era-attlist, common-calendar-attlist, empty + } +number-era-attlist = attribute number:style { "short" | "long" }? +number-fill-character = element number:fill-character { text } +# https://issues.oasis-open.org/browse/OFFICE-3765 +number-fraction = + element number:fraction { + number-fraction-attlist, common-number-attlist, empty + } +number-fraction-attlist = + attribute number:min-numerator-digits { integer }? + & attribute number:min-denominator-digits { integer }? + & attribute number:denominator-value { integer }? + & (attribute number:max-denominator-value { positiveInteger }?) + # https://issues.oasis-open.org/browse/OFFICE-3695 max-denominator-value + +number-hours = element number:hours { number-hours-attlist, empty } +number-hours-attlist = attribute number:style { "short" | "long" }? +number-minutes = + element number:minutes { number-minutes-attlist, empty } +number-minutes-attlist = attribute number:style { "short" | "long" }? number-month = element number:month { number-month-attlist, common-calendar-attlist, empty @@ -4704,743 +2587,991 @@ number-month-attlist = attribute number:textual { boolean }? & attribute number:possessive-form { boolean }? & attribute number:style { "short" | "long" }? -number-year = - element number:year { - number-year-attlist, common-calendar-attlist, empty +number-number = + element number:number { + number-number-attlist, + common-decimal-places-attlist, + common-number-attlist, + number-embedded-text* } -number-year-attlist = attribute number:style { "short" | "long" }? -number-era = - element number:era { - number-era-attlist, common-calendar-attlist, empty +number-number-attlist = + attribute number:decimal-replacement { \string }? + & attribute number:display-factor { double }? +number-number-style = + element number:number-style { + common-data-style-attlist, + style-text-properties?, + number-text-with-fillchar?, + # https://issues.oasis-open.org/browse/OFFICE-3765 + (any-number, number-text-with-fillchar?)?, + # https://issues.oasis-open.org/browse/OFFICE-3765 + style-map* } -number-era-attlist = attribute number:style { "short" | "long" }? -number-day-of-week = - element number:day-of-week { - number-day-of-week-attlist, common-calendar-attlist, empty +number-percentage-style = + element number:percentage-style { + common-data-style-attlist, + style-text-properties?, + number-text-with-fillchar?, + # https://issues.oasis-open.org/browse/OFFICE-3765 + number-and-text?, + style-map* } -number-day-of-week-attlist = - attribute number:style { "short" | "long" }? -number-week-of-year = - element number:week-of-year { common-calendar-attlist, empty } number-quarter = element number:quarter { number-quarter-attlist, common-calendar-attlist, empty } number-quarter-attlist = attribute number:style { "short" | "long" }? -number-time-style = - element number:time-style { - number-time-style-attlist, - common-data-style-attlist, - common-format-source-attlist, - style-text-properties?, - number-text?, - (any-time, number-text?)+, - style-map* +number-scientific-number = + element number:scientific-number { + number-scientific-number-attlist, + common-decimal-places-attlist, + common-number-attlist, + empty } -any-time = number-hours | number-am-pm | number-minutes | number-seconds -number-time-style-attlist = - attribute number:truncate-on-overflow { boolean }? -number-hours = element number:hours { number-hours-attlist, empty } -number-hours-attlist = attribute number:style { "short" | "long" }? -number-minutes = - element number:minutes { number-minutes-attlist, empty } -number-minutes-attlist = attribute number:style { "short" | "long" }? +number-scientific-number-attlist = + attribute number:min-exponent-digits { integer }? + & attribute number:exponent-interval { positiveInteger }? + & # https://issues.oasis-open.org/browse/OFFICE-1828 exponent-interval + attribute number:forced-exponent-sign { boolean } + # https://issues.oasis-open.org/browse/OFFICE-3860 added number:forced-exponent-sign + ? number-seconds = element number:seconds { number-seconds-attlist, empty } number-seconds-attlist = attribute number:style { "short" | "long" }? & attribute number:decimal-places { integer }? -number-am-pm = element number:am-pm { empty } -number-boolean-style = - element number:boolean-style { +number-text = element number:text { text } +number-text-content = element number:text-content { empty } +number-text-style = + element number:text-style { common-data-style-attlist, style-text-properties?, - number-text?, - (number-boolean, number-text?)?, + number-text-with-fillchar?, + # https://issues.oasis-open.org/browse/OFFICE-3765 + (number-text-content, + (number-text-with-fillchar?) + # https://issues.oasis-open.org/browse/OFFICE-3765 + )*, style-map* } -number-boolean = element number:boolean { empty } -number-text-style = - element number:text-style { +number-text-with-fillchar = + number-text?, (number-fill-character, number-text?)? +# https://issues.oasis-open.org/browse/OFFICE-3765 +number-time-style = + element number:time-style { + number-time-style-attlist, common-data-style-attlist, + common-format-source-attlist, style-text-properties?, - number-text?, - (number-text-content, number-text?)*, + number-text-with-fillchar?, + # https://issues.oasis-open.org/browse/OFFICE-3765 + (any-time, + (number-text-with-fillchar?) + # https://issues.oasis-open.org/browse/OFFICE-3765 + )+, style-map* } -number-text = element number:text { text } -number-text-content = element number:text-content { empty } -common-data-style-attlist = - attribute style:name { styleName } - & attribute style:display-name { \string }? - & attribute number:language { languageCode }? - & attribute number:country { countryCode }? - & attribute number:script { scriptCode }? - & attribute number:rfc-language-tag { language }? - & attribute number:title { \string }? - & attribute style:volatile { boolean }? - & attribute number:transliteration-format { \string }? - & attribute number:transliteration-language { countryCode }? - & attribute number:transliteration-country { countryCode }? - & attribute number:transliteration-style { - "short" | "medium" | "long" - }? -common-auto-reorder-attlist = - attribute number:automatic-order { boolean }? -common-format-source-attlist = - attribute number:format-source { "fixed" | "language" }? -common-decimal-places-attlist = - attribute number:decimal-places { integer }? -common-number-attlist = - attribute number:min-integer-digits { integer }? - & attribute number:grouping { boolean }? -common-calendar-attlist = - attribute number:calendar { - "gregorian" - | "gengou" - | "ROC" - | "hanja_yoil" - | "hanja" - | "hijri" - | "jewish" - | "buddhist" - | \string - }? -style-style-content = - (attribute style:family { "text" }, - style-text-properties?) - | (attribute style:family { "paragraph" }, - style-paragraph-properties?, - style-text-properties?) - | (attribute style:family { "section" }, - style-section-properties?) - | (attribute style:family { "ruby" }, - style-ruby-properties?) - | (attribute style:family { "table" }, - style-table-properties?) - | (attribute style:family { "table-column" }, - style-table-column-properties?) - | (attribute style:family { "table-row" }, - style-table-row-properties?) - | (attribute style:family { "table-cell" }, - style-table-cell-properties?, - style-paragraph-properties?, - style-text-properties?) - | (attribute style:family { "graphic" | "presentation" }, - style-graphic-properties?, - style-paragraph-properties?, - style-text-properties?) - | (attribute style:family { "drawing-page" }, - style-drawing-page-properties?) - | (attribute style:family { "chart" }, - style-chart-properties?, - style-graphic-properties?, - style-paragraph-properties?, - style-text-properties?) -text-linenumbering-configuration = - element text:linenumbering-configuration { - text-linenumbering-configuration-attlist, - text-linenumbering-separator? +number-time-style-attlist = + attribute number:truncate-on-overflow { boolean }? +number-week-of-year = + element number:week-of-year { common-calendar-attlist, empty } +number-year = + element number:year { + number-year-attlist, common-calendar-attlist, empty + } +number-year-attlist = attribute number:style { "short" | "long" }? +office-annotation = + element office:annotation { + office-annotation-attlist, + draw-caption-attlist, + common-draw-position-attlist, + common-draw-size-attlist, + common-draw-shape-with-text-and-styles-attlist, + dc-creator?, + dc-date?, + meta-date-string?, + element meta:creator-initials { text }?, + # https://issues.oasis-open.org/browse/OFFICE-3776 + (text-p | text-list)* + } +office-annotation-attlist = + attribute office:display { boolean }? + & common-office-annotation-name-attlist? +office-annotation-end = + element office:annotation-end { office-annotation-end-attlist } +office-annotation-end-attlist = common-office-annotation-name-attlist +office-automatic-styles = + element office:automatic-styles { styles & style-page-layout* }? +office-binary-data = element office:binary-data { base64Binary } +office-body = element office:body { office-body-content } +office-body-content = + element office:text { + office-text-attlist, + office-text-content-prelude, + office-text-content-main, + office-text-content-epilogue + } + | element office:drawing { + office-drawing-attlist, + office-drawing-content-prelude, + office-drawing-content-main, + office-drawing-content-epilogue + } + | element office:presentation { + office-presentation-attlist, + office-presentation-content-prelude, + office-presentation-content-main, + office-presentation-content-epilogue + } + | element office:spreadsheet { + office-spreadsheet-attlist, + office-spreadsheet-content-prelude, + office-spreadsheet-content-main, + office-spreadsheet-content-epilogue + } + | element office:chart { + office-chart-attlist, + office-chart-content-prelude, + office-chart-content-main, + office-chart-content-epilogue + } + | element office:image { + office-image-attlist, + office-image-content-prelude, + office-image-content-main, + office-image-content-epilogue + } + | office-database +office-change-info = + element office:change-info { dc-creator, dc-date, text-p* } +office-chart-attlist = empty +office-chart-content-epilogue = table-functions +office-chart-content-main = chart-chart +office-chart-content-prelude = text-decls, table-decls +office-database = + element office:database { + db-data-source, + db-forms?, + db-reports?, + db-queries?, + db-table-presentations?, + db-schema-definition? } -text-linenumbering-configuration-attlist = - attribute text:number-lines { boolean }? - & common-num-format-attlist? - & attribute text:style-name { styleNameRef }? - & attribute text:increment { nonNegativeInteger }? - & attribute text:number-position { - "left" | "right" | "inner" | "outer" - }? - & attribute text:offset { nonNegativeLength }? - & attribute text:count-empty-lines { boolean }? - & attribute text:count-in-text-boxes { boolean }? - & attribute text:restart-on-page { boolean }? -text-linenumbering-separator = - element text:linenumbering-separator { - attribute text:increment { nonNegativeInteger }?, - text +office-dde-source = + element office:dde-source { + office-dde-source-attlist, common-dde-connection-decl-attlist } -text-notes-configuration = - element text:notes-configuration { text-notes-configuration-content } -text-notes-configuration-content = - text-note-class - & attribute text:citation-style-name { styleNameRef }? - & attribute text:citation-body-style-name { styleNameRef }? - & attribute text:default-style-name { styleNameRef }? - & attribute text:master-page-name { styleNameRef }? - & attribute text:start-value { nonNegativeInteger }? - & common-num-format-prefix-suffix-attlist - & common-num-format-attlist? - & attribute text:start-numbering-at { - "document" | "chapter" | "page" +office-dde-source-attlist = + attribute office:name { \string }? + & attribute office:conversion-mode { + "into-default-style-data-style" + | "into-english-number" + | "keep-text" }? - & attribute text:footnotes-position { - "text" | "page" | "section" | "document" +office-document = + element office:document { + office-document-attrs, + office-document-common-attrs, + office-meta, + office-settings, + office-scripts, + office-font-face-decls, + office-styles, + office-automatic-styles, + office-master-styles, + office-body + } +office-document-attrs = attribute office:mimetype { \string } +office-document-common-attrs = + attribute office:version { "1.3" } + & attribute grddl:transformation { + list { anyIRI* } }? - & element text:note-continuation-notice-forward { text }? - & element text:note-continuation-notice-backward { text }? -text-bibliography-configuration = - element text:bibliography-configuration { - text-bibliography-configuration-attlist, text-sort-key* +office-document-content = + element office:document-content { + office-document-common-attrs, + office-scripts, + office-font-face-decls, + office-automatic-styles, + office-body } -text-bibliography-configuration-attlist = - attribute text:prefix { \string }? - & attribute text:suffix { \string }? - & attribute text:numbered-entries { boolean }? - & attribute text:sort-by-position { boolean }? - & attribute fo:language { languageCode }? - & attribute fo:country { countryCode }? - & attribute fo:script { scriptCode }? - & attribute style:rfc-language-tag { language }? - & attribute text:sort-algorithm { \string }? -text-sort-key = element text:sort-key { text-sort-key-attlist, empty } -text-sort-key-attlist = - attribute text:key { - "address" - | "annote" - | "author" - | "bibliography-type" - | "booktitle" - | "chapter" - | "custom1" - | "custom2" - | "custom3" - | "custom4" - | "custom5" - | "edition" - | "editor" - | "howpublished" - | "identifier" - | "institution" - | "isbn" - | "issn" - | "journal" - | "month" - | "note" - | "number" - | "organizations" - | "pages" - | "publisher" - | "report-type" - | "school" - | "series" - | "title" - | "url" - | "volume" - | "year" - }, - attribute text:sort-ascending { boolean }? -text-list-style = - element text:list-style { - text-list-style-attr, text-list-style-content* +office-document-meta = + element office:document-meta { + office-document-common-attrs, office-meta } -text-list-style-attr = - attribute style:name { styleName } - & attribute style:display-name { \string }? - & attribute text:consecutive-numbering { boolean }? -text-list-style-content = - element text:list-level-style-number { - text-list-level-style-attr, - text-list-level-style-number-attr, - style-list-level-properties?, - style-text-properties? +office-document-settings = + element office:document-settings { + office-document-common-attrs, office-settings + } +office-document-styles = + element office:document-styles { + office-document-common-attrs, + office-font-face-decls, + office-styles, + office-automatic-styles, + office-master-styles + } +office-drawing-attlist = empty +office-drawing-content-epilogue = table-functions +office-drawing-content-main = draw-page* +office-drawing-content-prelude = text-decls, table-decls +office-event-listeners = + element office:event-listeners { + (script-event-listener | presentation-event-listener)* + } +office-font-face-decls = + element office:font-face-decls { style-font-face* }? +office-forms = + element office:forms { + office-forms-attlist, (form-form | xforms-model)* + }? +office-forms-attlist = + attribute form:automatic-focus { boolean }? + & attribute form:apply-design-mode { boolean }? +office-image-attlist = empty +office-image-content-epilogue = empty +office-image-content-main = draw-frame +office-image-content-prelude = empty +office-master-styles = + element office:master-styles { + style-master-page* & style-handout-master? & draw-layer-set? + }? +office-meta = element office:meta { office-meta-content-strict }? +office-meta-content-strict = office-meta-data* +office-meta-data = + element meta:generator { \string } + | element dc:title { \string } + | element dc:description { \string } + | element dc:subject { \string } + | element meta:keyword { \string } + | element meta:initial-creator { \string } + | dc-creator + | element meta:printed-by { \string } + | element meta:creation-date { dateTime } + | dc-date + | element meta:print-date { dateTime } + | element meta:template { + attribute xlink:type { "simple" }, + attribute xlink:href { anyIRI }, + attribute xlink:actuate { "onRequest" }?, + attribute xlink:title { \string }?, + attribute meta:date { dateTime }? + } + | element meta:auto-reload { + (attribute xlink:type { "simple" }, + attribute xlink:href { anyIRI }, + attribute xlink:show { "replace" }?, + attribute xlink:actuate { "onLoad" }?)?, + attribute meta:delay { duration }? + } + | element meta:hyperlink-behaviour { + attribute office:target-frame-name { targetFrameName }?, + attribute xlink:show { "new" | "replace" }? + } + | element dc:language { language } + | element meta:editing-cycles { nonNegativeInteger } + | element meta:editing-duration { duration } + | element meta:document-statistic { + attribute meta:page-count { nonNegativeInteger }?, + attribute meta:table-count { nonNegativeInteger }?, + attribute meta:draw-count { nonNegativeInteger }?, + attribute meta:image-count { nonNegativeInteger }?, + attribute meta:ole-object-count { nonNegativeInteger }?, + attribute meta:object-count { nonNegativeInteger }?, + attribute meta:paragraph-count { nonNegativeInteger }?, + attribute meta:word-count { nonNegativeInteger }?, + attribute meta:character-count { nonNegativeInteger }?, + attribute meta:frame-count { nonNegativeInteger }?, + attribute meta:sentence-count { nonNegativeInteger }?, + attribute meta:syllable-count { nonNegativeInteger }?, + attribute meta:non-whitespace-character-count { + nonNegativeInteger + }?, + attribute meta:row-count { nonNegativeInteger }?, + attribute meta:cell-count { nonNegativeInteger }? + } + | element meta:user-defined { + attribute meta:name { \string }, + ((attribute meta:value-type { "float" }, + double) + | (attribute meta:value-type { "date" }, + dateOrDateTime) + | (attribute meta:value-type { "time" }, + duration) + | (attribute meta:value-type { "boolean" }, + boolean) + | (attribute meta:value-type { "string" }, + \string) + | text) + } +office-presentation-attlist = empty +office-presentation-content-epilogue = + presentation-settings, table-functions +office-presentation-content-main = draw-page* +office-presentation-content-prelude = + text-decls, table-decls, presentation-decls +# removed from text as well +# +# +# +# +# +# +# +office-script = + element office:script { + office-script-attlist, + mixed { anyElements } } - | element text:list-level-style-bullet { - text-list-level-style-attr, - text-list-level-style-bullet-attr, - style-list-level-properties?, - style-text-properties? +office-script-attlist = attribute script:language { \string } +office-scripts = + element office:scripts { office-script*, office-event-listeners? }? +office-settings = element office:settings { config-config-item-set+ }? +office-spreadsheet-attlist = + attribute table:structure-protected { boolean }?, + attribute table:protection-key { \string }?, + attribute table:protection-key-digest-algorithm { anyIRI }? +office-spreadsheet-content-epilogue = table-functions +office-spreadsheet-content-main = table-table* +office-spreadsheet-content-prelude = + table-tracked-changes?, text-decls, table-decls +office-styles = + element office:styles { + styles + & style-default-style* + & style-default-page-layout? + & text-outline-style? + & text-notes-configuration* + & text-bibliography-configuration? + & text-linenumbering-configuration? + & draw-gradient* + & svg-linearGradient* + & svg-radialGradient* + & draw-hatch* + & draw-fill-image* + & draw-marker* + & draw-stroke-dash* + & draw-opacity* + & style-presentation-page-layout* + & table-table-template* + }? +office-text-attlist = + attribute text:global { boolean }? + & attribute text:use-soft-page-breaks { boolean }? +office-text-content-epilogue = table-functions +office-text-content-main = + text-content* + | (text-page-sequence, (shape)*) +office-text-content-prelude = + office-forms, text-tracked-changes, text-decls, table-decls +paragraph-attrs = + attribute text:style-name { styleNameRef }? + & attribute text:class-names { styleNameRefs }? + & attribute text:cond-style-name { styleNameRef }? + & (xml-id, + attribute text:id { NCName }?)? + & common-in-content-meta-attlist? +paragraph-content = + text + | element text:s { + attribute text:c { nonNegativeInteger }? + } + | element text:tab { text-tab-attr } + | element text:line-break { empty } + | text-soft-page-break + | element text:span { + attribute text:style-name { styleNameRef }?, + attribute text:class-names { styleNameRefs }?, + paragraph-content-or-hyperlink* + } + | element text:meta { + text-meta-attlist, paragraph-content-or-hyperlink* + } + | (text-bookmark | text-bookmark-start | text-bookmark-end) + | element text:reference-mark { + attribute text:name { \string } + } + | (element text:reference-mark-start { + attribute text:name { \string } + } + | element text:reference-mark-end { + attribute text:name { \string } + }) + | element text:note { + text-note-class, + attribute text:id { \string }?, + element text:note-citation { + attribute text:label { \string }?, + text + }, + element text:note-body { text-content* } + } + | element text:ruby { + attribute text:style-name { styleNameRef }?, + element text:ruby-base { paragraph-content-or-hyperlink* }, + element text:ruby-text { + attribute text:style-name { styleNameRef }?, + text + } + } + | (office-annotation | office-annotation-end) + | change-marks + | shape + | element text:date { text-date-attlist, text } + | element text:time { text-time-attlist, text } + | element text:page-number { text-page-number-attlist, text } + | element text:page-continuation { + text-page-continuation-attlist, text + } + | element text:sender-firstname { common-field-fixed-attlist, text } + | element text:sender-lastname { common-field-fixed-attlist, text } + | element text:sender-initials { common-field-fixed-attlist, text } + | element text:sender-title { common-field-fixed-attlist, text } + | element text:sender-position { common-field-fixed-attlist, text } + | element text:sender-email { common-field-fixed-attlist, text } + | element text:sender-phone-private { + common-field-fixed-attlist, text + } + | element text:sender-fax { common-field-fixed-attlist, text } + | element text:sender-company { common-field-fixed-attlist, text } + | element text:sender-phone-work { common-field-fixed-attlist, text } + | element text:sender-street { common-field-fixed-attlist, text } + | element text:sender-city { common-field-fixed-attlist, text } + | element text:sender-postal-code { common-field-fixed-attlist, text } + | element text:sender-country { common-field-fixed-attlist, text } + | element text:sender-state-or-province { + common-field-fixed-attlist, text + } + | element text:author-name { common-field-fixed-attlist, text } + | element text:author-initials { common-field-fixed-attlist, text } + | element text:chapter { text-chapter-attlist, text } + | element text:file-name { text-file-name-attlist, text } + | element text:template-name { text-template-name-attlist, text } + | element text:sheet-name { text } + | element text:variable-set { + (common-field-name-attlist + & common-field-formula-attlist + & common-value-and-type-attlist + & common-field-display-value-none-attlist + & common-field-data-style-name-attlist), + text + } + | element text:variable-get { + (common-field-name-attlist + & common-field-display-value-formula-attlist + & common-field-data-style-name-attlist), + text + } + | element text:variable-input { + (common-field-name-attlist + & common-field-description-attlist + & common-value-type-attlist + & common-field-display-value-none-attlist + & common-field-data-style-name-attlist), + text + } + | element text:user-field-get { + (common-field-name-attlist + & common-field-display-value-formula-none-attlist + & common-field-data-style-name-attlist), + text + } + | element text:user-field-input { + (common-field-name-attlist + & common-field-description-attlist + & common-field-data-style-name-attlist), + text + } + | element text:sequence { + (common-field-name-attlist + & common-field-formula-attlist + & common-field-num-format-attlist + & text-sequence-ref-name), + text + } + | element text:expression { + (common-field-formula-attlist + & common-value-and-type-attlist? + & common-field-display-value-formula-attlist + & common-field-data-style-name-attlist), + text + } + | element text:text-input { common-field-description-attlist, text } + | text-drop-down + | # OFFICE-3881 + element text:initial-creator { common-field-fixed-attlist, text } + | element text:creation-date { + (common-field-fixed-attlist + & common-field-data-style-name-attlist + & attribute text:date-value { dateOrDateTime }?), + text + } + | element text:creation-time { + (common-field-fixed-attlist + & common-field-data-style-name-attlist + & attribute text:time-value { timeOrDateTime }?), + text + } + | element text:description { common-field-fixed-attlist, text } + | element text:user-defined { + (common-field-fixed-attlist + & attribute text:name { \string } + & common-field-data-style-name-attlist + & attribute office:value { double }? + & attribute office:date-value { dateOrDateTime }? + & attribute office:time-value { duration }? + & attribute office:boolean-value { boolean }? + & attribute office:string-value { \string }?), + text + } + | element text:print-time { + (common-field-fixed-attlist + & common-field-data-style-name-attlist + & attribute text:time-value { time }?), + text + } + | element text:print-date { + (common-field-fixed-attlist + & common-field-data-style-name-attlist + & attribute text:date-value { date }?), + text + } + | element text:printed-by { common-field-fixed-attlist, text } + | element text:title { common-field-fixed-attlist, text } + | element text:subject { common-field-fixed-attlist, text } + | element text:keywords { common-field-fixed-attlist, text } + | element text:editing-cycles { common-field-fixed-attlist, text } + | element text:editing-duration { + (common-field-fixed-attlist + & common-field-data-style-name-attlist + & attribute text:duration { duration }?), + text + } + | element text:modification-time { + (common-field-fixed-attlist + & common-field-data-style-name-attlist + & attribute text:time-value { time }?), + text + } + | element text:modification-date { + (common-field-fixed-attlist + & common-field-data-style-name-attlist + & attribute text:date-value { date }?), + text + } + | element text:creator { common-field-fixed-attlist, text } + | element text:page-count + | text:paragraph-count + | text:word-count + | text:character-count + | text:table-count + | text:image-count + | text:object-count { + common-field-num-format-attlist, text } - | element text:list-level-style-image { - text-list-level-style-attr, - text-list-level-style-image-attr, - style-list-level-properties? + | element text:database-display { + text-database-display-attlist, text } -text-list-level-style-number-attr = - attribute text:style-name { styleNameRef }? - & common-num-format-attlist - & common-num-format-prefix-suffix-attlist - & attribute text:display-levels { positiveInteger }? - & attribute text:start-value { positiveInteger }? -text-list-level-style-bullet-attr = - attribute text:style-name { styleNameRef }? - & attribute text:bullet-char { character } - & common-num-format-prefix-suffix-attlist - & attribute text:bullet-relative-size { percent }? -text-list-level-style-image-attr = - common-draw-data-attlist | office-binary-data -text-list-level-style-attr = attribute text:level { positiveInteger } -text-outline-style = - element text:outline-style { - text-outline-style-attr, text-outline-level-style+ - } -text-outline-style-attr = attribute style:name { styleName } -text-outline-level-style = - element text:outline-level-style { - text-outline-level-style-attlist, - style-list-level-properties?, - style-text-properties? - } -text-outline-level-style-attlist = - attribute text:level { positiveInteger } - & attribute text:style-name { styleNameRef }? - & common-num-format-attlist - & common-num-format-prefix-suffix-attlist - & attribute text:display-levels { positiveInteger }? - & attribute text:start-value { positiveInteger }? -style-graphic-properties = - element style:graphic-properties { - style-graphic-properties-content-strict - } -style-graphic-properties-content-strict = - style-graphic-properties-attlist, - style-graphic-fill-properties-attlist, - style-graphic-properties-elements -style-drawing-page-properties = - element style:drawing-page-properties { - style-drawing-page-properties-content-strict - } -style-drawing-page-properties-content-strict = - style-graphic-fill-properties-attlist, - style-drawing-page-properties-attlist, - style-drawing-page-properties-elements -draw-gradient = - element draw:gradient { - common-draw-gradient-attlist, draw-gradient-attlist, empty - } -common-draw-gradient-attlist = - attribute draw:name { styleName }? - & attribute draw:display-name { \string }? - & attribute draw:style { gradient-style } - & attribute draw:cx { percent }? - & attribute draw:cy { percent }? - & attribute draw:angle { angle }? - & attribute draw:border { percent }? -gradient-style = - "linear" | "axial" | "radial" | "ellipsoid" | "square" | "rectangular" -draw-gradient-attlist = - attribute draw:start-color { color }? - & attribute draw:end-color { color }? - & attribute draw:start-intensity { zeroToHundredPercent }? - & attribute draw:end-intensity { zeroToHundredPercent }? -svg-linearGradient = - element svg:linearGradient { - common-svg-gradient-attlist, - attribute svg:x1 { coordinate | percent }?, - attribute svg:y1 { coordinate | percent }?, - attribute svg:x2 { coordinate | percent }?, - attribute svg:y2 { coordinate | percent }?, - svg-stop* - } -svg-radialGradient = - element svg:radialGradient { - common-svg-gradient-attlist, - attribute svg:cx { coordinate | percent }?, - attribute svg:cy { coordinate | percent }?, - attribute svg:r { coordinate | percent }?, - attribute svg:fx { coordinate | percent }?, - attribute svg:fy { coordinate | percent }?, - svg-stop* - } -svg-stop = - element svg:stop { - attribute svg:offset { double | percent }, - attribute svg:stop-color { color }?, - attribute svg:stop-opacity { double }? - } -common-svg-gradient-attlist = - attribute svg:gradientUnits { "objectBoundingBox" }? - & attribute svg:gradientTransform { \string }? - & attribute svg:spreadMethod { "pad" | "reflect" | "repeat" }? - & attribute draw:name { styleName } - & attribute draw:display-name { \string }? -draw-hatch = element draw:hatch { draw-hatch-attlist, empty } -draw-hatch-attlist = - attribute draw:name { styleName } - & attribute draw:display-name { \string }? - & attribute draw:style { "single" | "double" | "triple" } - & attribute draw:color { color }? - & attribute draw:distance { length }? - & attribute draw:rotation { angle }? -draw-fill-image = - element draw:fill-image { - draw-fill-image-attlist, - attribute xlink:type { "simple" }, - attribute xlink:href { anyIRI }, - attribute xlink:show { "embed" }?, - attribute xlink:actuate { "onLoad" }?, - empty - } -draw-fill-image-attlist = - attribute draw:name { styleName } - & attribute draw:display-name { \string }? - & attribute svg:width { length }? - & attribute svg:height { length }? -draw-opacity = - element draw:opacity { - common-draw-gradient-attlist, draw-opacity-attlist, empty - } -draw-opacity-attlist = - attribute draw:start { zeroToHundredPercent }?, - attribute draw:end { zeroToHundredPercent }? -draw-marker = - element draw:marker { - draw-marker-attlist, - common-draw-viewbox-attlist, - common-draw-path-data-attlist, - empty - } -draw-marker-attlist = - attribute draw:name { styleName } - & attribute draw:display-name { \string }? -draw-stroke-dash = - element draw:stroke-dash { draw-stroke-dash-attlist, empty } -draw-stroke-dash-attlist = - attribute draw:name { styleName } - & attribute draw:display-name { \string }? - & attribute draw:style { "rect" | "round" }? - & attribute draw:dots1 { integer }? - & attribute draw:dots1-length { length | percent }? - & attribute draw:dots2 { integer }? - & attribute draw:dots2-length { length | percent }? - & attribute draw:distance { length | percent }? -style-presentation-page-layout = - element style:presentation-page-layout { - attribute style:name { styleName }, - attribute style:display-name { \string }?, - presentation-placeholder* + | element text:database-next { text-database-next-attlist } + | element text:database-row-select { + text-database-row-select-attlist + } + | element text:database-row-number { + (common-field-database-table + & common-field-num-format-attlist + & attribute text:value { nonNegativeInteger }?), + text + } + | element text:database-name { common-field-database-table, text } + | element text:page-variable-set { + text-set-page-variable-attlist, text + } + | element text:page-variable-get { + text-get-page-variable-attlist, text + } + | element text:placeholder { text-placeholder-attlist, text } + | element text:conditional-text { + text-conditional-text-attlist, text + } + | element text:hidden-text { text-hidden-text-attlist, text } + | element text:reference-ref | text:bookmark-ref { + text-common-ref-content & text-bookmark-ref-content + } + | element text:note-ref { + text-common-ref-content & text-note-ref-content + } + | element text:sequence-ref { + text-common-ref-content & text-sequence-ref-content + } + | element text:script { + ((attribute xlink:type { "simple" }, + attribute xlink:href { anyIRI }) + | text) + & attribute script:language { \string }? + } + | element text:execute-macro { + attribute text:name { \string }?, + office-event-listeners?, + text + } + | element text:hidden-paragraph { + text-hidden-paragraph-attlist, text + } + | element text:dde-connection { + attribute text:connection-name { \string }, + text + } + | element text:measure { + attribute text:kind { "value" | "unit" | "gap" }, + text + } + | element text:table-formula { + (common-field-formula-attlist + & common-field-display-value-formula-attlist + & common-field-data-style-name-attlist), + text + } + | element text:meta-field { + text-meta-field-attlist, paragraph-content-or-hyperlink* + } + | element text:toc-mark-start { text-toc-mark-start-attrs } + | element text:toc-mark-end { text-id } + | element text:toc-mark { + attribute text:string-value { \string }, + text-outline-level + } + | element text:user-index-mark-start { + text-id, text-outline-level, text-index-name + } + | element text:user-index-mark-end { text-id } + | element text:user-index-mark { + attribute text:string-value { \string }, + text-outline-level, + text-index-name + } + | element text:alphabetical-index-mark-start { + text-id, text-alphabetical-index-mark-attrs + } + | element text:alphabetical-index-mark-end { text-id } + | element text:alphabetical-index-mark { + attribute text:string-value { \string }, + text-alphabetical-index-mark-attrs + } + | element text:bibliography-mark { + attribute text:bibliography-type { text-bibliography-types }, + attribute text:identifier + | text:address + | text:annote + | text:author + | text:booktitle + | text:chapter + | text:edition + | text:editor + | text:howpublished + | text:institution + | text:journal + | text:month + | text:note + | text:number + | text:organizations + | text:pages + | text:publisher + | text:school + | text:series + | text:title + | text:report-type + | text:volume + | text:year + | text:url + | text:custom1 + | text:custom2 + | text:custom3 + | text:custom4 + | text:custom5 + | text:isbn + | text:issn { \string }*, + text + } + | element presentation:header { empty } + | element presentation:footer { empty } + | element presentation:date-time { empty } +paragraph-content-or-hyperlink = paragraph-content | text-a +pathData = xsd:string +percent = xsd:string { pattern = "-?([0-9]+(\.[0-9]*)?|\.[0-9]+)%" } +point3D = + xsd:string { + pattern = + "\([ ]*-?([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc))([ ]+-?([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc))){2}[ ]*\)" } -presentation-placeholder = - element presentation:placeholder { - attribute presentation:object { presentation-classes }, - attribute svg:x { coordinate | percent }, - attribute svg:y { coordinate | percent }, - attribute svg:width { length | percent }, - attribute svg:height { length | percent }, - empty +points = + xsd:string { pattern = "-?[0-9]+,-?[0-9]+([ ]+-?[0-9]+,-?[0-9]+)*" } +positiveInteger = xsd:positiveInteger +positiveLength = + xsd:string { + pattern = + "([0-9]*[1-9][0-9]*(\.[0-9]*)?|0+\.[0-9]*[1-9][0-9]*|\.[0-9]*[1-9][0-9]*)((cm)|(mm)|(in)|(pt)|(pc)|(px))" } -style-page-layout-properties = - element style:page-layout-properties { - style-page-layout-properties-content-strict +presentation-animation-elements = + presentation-show-shape + | presentation-show-text + | presentation-hide-shape + | presentation-hide-text + | presentation-dim + | presentation-play +presentation-animation-group = + element presentation:animation-group { + presentation-animation-elements* } -style-page-layout-properties-content-strict = - style-page-layout-properties-attlist, - style-page-layout-properties-elements -style-page-layout-properties-attlist = - attribute fo:page-width { length }? - & attribute fo:page-height { length }? - & common-num-format-attlist? - & common-num-format-prefix-suffix-attlist - & attribute style:paper-tray-name { "default" | \string }? - & attribute style:print-orientation { "portrait" | "landscape" }? - & common-horizontal-margin-attlist - & common-vertical-margin-attlist - & common-margin-attlist - & common-border-attlist - & common-border-line-width-attlist - & common-padding-attlist - & common-shadow-attlist - & common-background-color-attlist - & attribute style:register-truth-ref-style-name { styleNameRef }? - & attribute style:print { - list { - ("headers" - | "grid" - | "annotations" - | "objects" - | "charts" - | "drawings" - | "formulas" - | "zero-values")* - } - }? - & attribute style:print-page-order { "ttb" | "ltr" }? - & attribute style:first-page-number { positiveInteger | "continue" }? - & attribute style:scale-to { percent }? - & attribute style:scale-to-pages { positiveInteger }? - & attribute style:table-centering { - "horizontal" | "vertical" | "both" | "none" - }? - & attribute style:footnote-max-height { length }? - & common-writing-mode-attlist - & attribute style:layout-grid-mode { "none" | "line" | "both" }? - & attribute style:layout-grid-standard-mode { boolean }? - & attribute style:layout-grid-base-height { length }? - & attribute style:layout-grid-ruby-height { length }? - & attribute style:layout-grid-lines { positiveInteger }? - & attribute style:layout-grid-base-width { length }? - & attribute style:layout-grid-color { color }? - & attribute style:layout-grid-ruby-below { boolean }? - & attribute style:layout-grid-print { boolean }? - & attribute style:layout-grid-display { boolean }? - & attribute style:layout-grid-snap-to { boolean }? -style-page-layout-properties-elements = - style-background-image & style-columns & style-footnote-sep -style-footnote-sep = - element style:footnote-sep { style-footnote-sep-attlist, empty }? -style-footnote-sep-attlist = - attribute style:width { length }?, - attribute style:rel-width { percent }?, - attribute style:color { color }?, - attribute style:line-style { lineStyle }?, - attribute style:adjustment { "left" | "center" | "right" }?, - attribute style:distance-before-sep { length }?, - attribute style:distance-after-sep { length }? -style-header-footer-properties = - element style:header-footer-properties { - style-header-footer-properties-content-strict +presentation-animations = + element presentation:animations { + (presentation-animation-elements | presentation-animation-group)* } -style-header-footer-properties-content-strict = - style-header-footer-properties-attlist, - style-header-footer-properties-elements -style-header-footer-properties-attlist = - attribute svg:height { length }? - & attribute fo:min-height { length }? - & common-horizontal-margin-attlist - & common-vertical-margin-attlist - & common-margin-attlist - & common-border-attlist - & common-border-line-width-attlist - & common-padding-attlist - & common-background-color-attlist - & common-shadow-attlist - & attribute style:dynamic-spacing { boolean }? -style-header-footer-properties-elements = style-background-image -style-text-properties = - element style:text-properties { style-text-properties-content-strict } -style-text-properties-content-strict = - style-text-properties-attlist, style-text-properties-elements -style-text-properties-elements = empty -style-text-properties-attlist = - attribute fo:font-variant { fontVariant }? - & attribute fo:text-transform { - "none" | "lowercase" | "uppercase" | "capitalize" - }? - & attribute fo:color { color }? - & attribute style:use-window-font-color { boolean }? - & attribute style:text-outline { boolean }? - & attribute style:text-line-through-type { lineType }? - & attribute style:text-line-through-style { lineStyle }? - & attribute style:text-line-through-width { lineWidth }? - & attribute style:text-line-through-color { "font-color" | color }? - & attribute style:text-line-through-text { \string }? - & attribute style:text-line-through-text-style { styleNameRef }? - & attribute style:text-position { - list { (percent | "super" | "sub"), percent? } - }? - & attribute style:font-name { \string }? - & attribute style:font-name-asian { \string }? - & attribute style:font-name-complex { \string }? - & attribute fo:font-family { \string }? - & attribute style:font-family-asian { \string }? - & attribute style:font-family-complex { \string }? - & attribute style:font-family-generic { fontFamilyGeneric }? - & attribute style:font-family-generic-asian { fontFamilyGeneric }? - & attribute style:font-family-generic-complex { fontFamilyGeneric }? - & attribute style:font-style-name { \string }? - & attribute style:font-style-name-asian { \string }? - & attribute style:font-style-name-complex { \string }? - & attribute style:font-pitch { fontPitch }? - & attribute style:font-pitch-asian { fontPitch }? - & attribute style:font-pitch-complex { fontPitch }? - & attribute style:font-charset { textEncoding }? - & attribute style:font-charset-asian { textEncoding }? - & attribute style:font-charset-complex { textEncoding }? - & attribute fo:font-size { positiveLength | percent }? - & attribute style:font-size-asian { positiveLength | percent }? - & attribute style:font-size-complex { positiveLength | percent }? - & attribute style:font-size-rel { length }? - & attribute style:font-size-rel-asian { length }? - & attribute style:font-size-rel-complex { length }? - & attribute style:script-type { - "latin" | "asian" | "complex" | "ignore" - }? - & attribute fo:letter-spacing { length | "normal" }? - & attribute fo:language { languageCode }? - & attribute style:language-asian { languageCode }? - & attribute style:language-complex { languageCode }? - & attribute fo:country { countryCode }? - & attribute style:country-asian { countryCode }? - & attribute style:country-complex { countryCode }? - & attribute fo:script { scriptCode }? - & attribute style:script-asian { scriptCode }? - & attribute style:script-complex { scriptCode }? - & attribute style:rfc-language-tag { language }? - & attribute style:rfc-language-tag-asian { language }? - & attribute style:rfc-language-tag-complex { language }? - & attribute fo:font-style { fontStyle }? - & attribute style:font-style-asian { fontStyle }? - & attribute style:font-style-complex { fontStyle }? - & attribute style:font-relief { "none" | "embossed" | "engraved" }? - & attribute fo:text-shadow { shadowType }? - & attribute style:text-underline-type { lineType }? - & attribute style:text-underline-style { lineStyle }? - & attribute style:text-underline-width { lineWidth }? - & attribute style:text-underline-color { "font-color" | color }? - & attribute style:text-overline-type { lineType }? - & attribute style:text-overline-style { lineStyle }? - & attribute style:text-overline-width { lineWidth }? - & attribute style:text-overline-color { "font-color" | color }? - & attribute style:text-overline-mode { lineMode }? - & attribute fo:font-weight { fontWeight }? - & attribute style:font-weight-asian { fontWeight }? - & attribute style:font-weight-complex { fontWeight }? - & attribute style:text-underline-mode { lineMode }? - & attribute style:text-line-through-mode { lineMode }? - & attribute style:letter-kerning { boolean }? - & attribute style:text-blinking { boolean }? - & common-background-color-attlist - & attribute style:text-combine { "none" | "letters" | "lines" }? - & attribute style:text-combine-start-char { character }? - & attribute style:text-combine-end-char { character }? - & attribute style:text-emphasize { +presentation-classes = + "title" + | "outline" + | "subtitle" + | "text" + | "graphic" + | "object" + | "chart" + | "table" + | "orgchart" + | "page" + | "notes" + | "handout" + | "header" + | "footer" + | "date-time" + | "page-number" +presentation-date-time-decl-attlist = + attribute presentation:name { \string } + & attribute presentation:source { "fixed" | "current-date" } + & attribute style:data-style-name { styleNameRef }? +presentation-decl = + element presentation:header-decl { + presentation-header-decl-attlist, text + } + | element presentation:footer-decl { + presentation-footer-decl-attlist, text + } + | element presentation:date-time-decl { + presentation-date-time-decl-attlist, text + } +presentation-decls = presentation-decl* +presentation-dim = + element presentation:dim { + presentation-dim-attlist, presentation-sound? + } +presentation-dim-attlist = + attribute draw:shape-id { IDREF } + & attribute draw:color { color } +presentation-event-listener = + element presentation:event-listener { + presentation-event-listener-attlist, presentation-sound? + } +presentation-event-listener-attlist = + attribute script:event-name { \string } + & attribute presentation:action { "none" - | list { - ("none" | "accent" | "dot" | "circle" | "disc"), - ("above" | "below") - } + | "previous-page" + | "next-page" + | "first-page" + | "last-page" + | "hide" + | "stop" + | "execute" + | "show" + | "verb" + | "fade-out" + | "sound" + | "last-visited-page" + } + & attribute presentation:effect { presentationEffects }? + & attribute presentation:direction { presentationEffectDirections }? + & attribute presentation:speed { presentationSpeeds }? + & attribute presentation:start-scale { percent }? + & (attribute xlink:type { "simple" }, + attribute xlink:href { anyIRI }, + attribute xlink:show { "embed" }?, + attribute xlink:actuate { "onRequest" }?)? + & attribute presentation:verb { nonNegativeInteger }? +presentation-footer-decl-attlist = + attribute presentation:name { \string } +presentation-header-decl-attlist = + attribute presentation:name { \string } +presentation-hide-shape = + element presentation:hide-shape { + common-presentation-effect-attlist, presentation-sound? + } +presentation-hide-text = + element presentation:hide-text { + common-presentation-effect-attlist, presentation-sound? + } +presentation-notes = + element presentation:notes { + common-presentation-header-footer-attlist, + presentation-notes-attlist, + office-forms, + shape* + } +presentation-notes-attlist = + attribute style:page-layout-name { styleNameRef }? + & attribute draw:style-name { styleNameRef }? +presentation-placeholder = + element presentation:placeholder { + attribute presentation:object { presentation-classes }, + attribute svg:x { coordinate | percent }, + attribute svg:y { coordinate | percent }, + attribute svg:width { length | percent }, + attribute svg:height { length | percent }, + empty + } +presentation-play = + element presentation:play { presentation-play-attlist, empty } +presentation-play-attlist = + attribute draw:shape-id { IDREF }, + attribute presentation:speed { presentationSpeeds }? +presentation-settings = + element presentation:settings { + presentation-settings-attlist, presentation-show* + }? +presentation-settings-attlist = + attribute presentation:start-page { \string }? + & attribute presentation:show { \string }? + & attribute presentation:full-screen { boolean }? + & attribute presentation:endless { boolean }? + & attribute presentation:pause { duration }? + & attribute presentation:show-logo { boolean }? + & attribute presentation:force-manual { boolean }? + & attribute presentation:mouse-visible { boolean }? + & attribute presentation:mouse-as-pen { boolean }? + & attribute presentation:start-with-navigator { boolean }? + & attribute presentation:animations { "enabled" | "disabled" }? + & attribute presentation:transition-on-click { + "enabled" | "disabled" }? - & attribute style:text-scale { percent }? - & attribute style:text-rotation-angle { angle }? - & attribute style:text-rotation-scale { "fixed" | "line-height" }? - & attribute fo:hyphenate { boolean }? - & attribute fo:hyphenation-remain-char-count { positiveInteger }? - & attribute fo:hyphenation-push-char-count { positiveInteger }? - & (attribute text:display { "true" } - | attribute text:display { "none" } - | (attribute text:display { "condition" }, - attribute text:condition { "none" }) - | empty) -fontVariant = "normal" | "small-caps" -fontFamilyGeneric = - "roman" | "swiss" | "modern" | "decorative" | "script" | "system" -fontPitch = "fixed" | "variable" -textEncoding = xsd:string { pattern = "[A-Za-z][A-Za-z0-9._\-]*" } -fontStyle = "normal" | "italic" | "oblique" -shadowType = "none" | \string -lineType = "none" | "single" | "double" -lineStyle = + & attribute presentation:stay-on-top { boolean }? + & attribute presentation:show-end-of-presentation-slide { boolean }? +presentation-shape-attlist = + attribute presentation:class { presentation-classes }? + & attribute presentation:placeholder { boolean }? + & attribute presentation:user-transformed { boolean }? +presentation-show = + element presentation:show { presentation-show-attlist, empty } +presentation-show-attlist = + attribute presentation:name { \string } + & attribute presentation:pages { \string } +presentation-show-shape = + element presentation:show-shape { + common-presentation-effect-attlist, presentation-sound? + } +presentation-show-text = + element presentation:show-text { + common-presentation-effect-attlist, presentation-sound? + } +presentation-sound = + element presentation:sound { + presentation-sound-attlist, + attribute xlink:type { "simple" }, + attribute xlink:href { anyIRI }, + attribute xlink:actuate { "onRequest" }?, + attribute xlink:show { "new" | "replace" }?, + empty + } +presentation-sound-attlist = + attribute presentation:play-full { boolean }? + & xml-id? +presentationEffectDirections = "none" - | "solid" - | "dotted" - | "dash" - | "long-dash" - | "dot-dash" - | "dot-dot-dash" - | "wave" -lineWidth = - "auto" - | "normal" - | "bold" - | "thin" - | "medium" - | "thick" - | positiveInteger - | percent - | positiveLength -fontWeight = - "normal" - | "bold" - | "100" - | "200" - | "300" - | "400" - | "500" - | "600" - | "700" - | "800" - | "900" -lineMode = "continuous" | "skip-white-space" -style-paragraph-properties = - element style:paragraph-properties { - style-paragraph-properties-content-strict + | "from-left" + | "from-top" + | "from-right" + | "from-bottom" + | "from-center" + | "from-upper-left" + | "from-upper-right" + | "from-lower-left" + | "from-lower-right" + | "to-left" + | "to-top" + | "to-right" + | "to-bottom" + | "to-upper-left" + | "to-upper-right" + | "to-lower-right" + | "to-lower-left" + | "path" + | "spiral-inward-left" + | "spiral-inward-right" + | "spiral-outward-left" + | "spiral-outward-right" + | "vertical" + | "horizontal" + | "to-center" + | "clockwise" + | "counter-clockwise" +presentationEffects = + "none" + | "fade" + | "move" + | "stripes" + | "open" + | "close" + | "dissolve" + | "wavyline" + | "random" + | "lines" + | "laser" + | "appear" + | "hide" + | "move-short" + | "checkerboard" + | "rotate" + | "stretch" +presentationSpeeds = "slow" | "medium" | "fast" +region-content = text-p* +relativeLength = xsd:string { pattern = "[0-9]+\*" } +rowOrCol = "row" | "column" +script-event-listener = + element script:event-listener { script-event-listener-attlist, empty } +script-event-listener-attlist = + attribute script:event-name { \string } + & attribute script:language { \string } + & (attribute script:macro-name { \string } + | (attribute xlink:type { "simple" }, + attribute xlink:href { anyIRI }, + attribute xlink:actuate { "onRequest" }?)) +scriptCode = xsd:token { pattern = "[A-Za-z0-9]{1,8}" } +selected = attribute form:selected { boolean }? +shadowType = "none" | \string +shape = shape-instance | draw-a +shape-instance = + draw-rect + | draw-line + | draw-polyline + | draw-polygon + | draw-regular-polygon + | draw-path + | draw-circle + | draw-ellipse + | draw-g + | draw-page-thumbnail + | draw-frame + | draw-measure + | draw-caption + | draw-connector + | draw-control + | dr3d-scene + | draw-custom-shape +shapes3d = + dr3d-scene | dr3d-extrude | dr3d-sphere | dr3d-rotate | dr3d-cube +signedZeroToHundredPercent = + xsd:string { + pattern = "-?([0-9]?[0-9](\.[0-9]*)?|100(\.0*)?|\.[0-9]+)%" } -style-paragraph-properties-content-strict = - style-paragraph-properties-attlist, - style-paragraph-properties-elements -style-paragraph-properties-attlist = - attribute fo:line-height { "normal" | nonNegativeLength | percent }? - & attribute style:line-height-at-least { nonNegativeLength }? - & attribute style:line-spacing { length }? - & attribute style:font-independent-line-spacing { boolean }? - & common-text-align - & attribute fo:text-align-last { "start" | "center" | "justify" }? - & attribute style:justify-single-word { boolean }? - & attribute fo:keep-together { "auto" | "always" }? - & attribute fo:widows { nonNegativeInteger }? - & attribute fo:orphans { nonNegativeInteger }? - & attribute style:tab-stop-distance { nonNegativeLength }? - & attribute fo:hyphenation-keep { "auto" | "page" }? - & attribute fo:hyphenation-ladder-count { - "no-limit" | positiveInteger - }? - & attribute style:register-true { boolean }? - & common-horizontal-margin-attlist - & attribute fo:text-indent { length | percent }? - & attribute style:auto-text-indent { boolean }? - & common-vertical-margin-attlist - & common-margin-attlist - & common-break-attlist - & common-background-color-attlist - & common-border-attlist - & common-border-line-width-attlist - & attribute style:join-border { boolean }? - & common-padding-attlist - & common-shadow-attlist - & common-keep-with-next-attlist - & attribute text:number-lines { boolean }? - & attribute text:line-number { nonNegativeInteger }? - & attribute style:text-autospace { "none" | "ideograph-alpha" }? - & attribute style:punctuation-wrap { "simple" | "hanging" }? - & attribute style:line-break { "normal" | "strict" }? - & attribute style:vertical-align { - "top" | "middle" | "bottom" | "auto" | "baseline" - }? - & common-writing-mode-attlist - & attribute style:writing-mode-automatic { boolean }? - & attribute style:snap-to-layout-grid { boolean }? - & common-page-number-attlist - & common-background-transparency-attlist -common-text-align = - attribute fo:text-align { - "start" | "end" | "left" | "right" | "center" | "justify" - }? -style-paragraph-properties-elements = - style-tab-stops & style-drop-cap & style-background-image -style-tab-stops = element style:tab-stops { style-tab-stop* }? -style-tab-stop = - element style:tab-stop { style-tab-stop-attlist, empty } -style-tab-stop-attlist = - attribute style:position { length } - & (attribute style:type { "left" | "center" | "right" }? - | (attribute style:type { "char" }, - style-tab-stop-char-attlist)) - & attribute style:leader-type { lineType }? - & attribute style:leader-style { lineStyle }? - & attribute style:leader-width { lineWidth }? - & attribute style:leader-color { "font-color" | color }? - & attribute style:leader-text { character }? - & attribute style:leader-text-style { styleNameRef }? -style-tab-stop-char-attlist = attribute style:char { character } -style-drop-cap = - element style:drop-cap { style-drop-cap-attlist, empty }? -style-drop-cap-attlist = - attribute style:length { "word" | positiveInteger }? - & attribute style:lines { positiveInteger }? - & attribute style:distance { length }? - & attribute style:style-name { styleNameRef }? -common-horizontal-margin-attlist = - attribute fo:margin-left { length | percent }?, - attribute fo:margin-right { length | percent }? -common-vertical-margin-attlist = - attribute fo:margin-top { nonNegativeLength | percent }?, - attribute fo:margin-bottom { nonNegativeLength | percent }? -common-margin-attlist = - attribute fo:margin { nonNegativeLength | percent }? -common-break-attlist = - attribute fo:break-before { "auto" | "column" | "page" }?, - attribute fo:break-after { "auto" | "column" | "page" }? -common-background-color-attlist = - attribute fo:background-color { "transparent" | color }? +size = attribute form:size { nonNegativeInteger }? +states = "unchecked" | "checked" | "unknown" +\string = xsd:string style-background-image = element style:background-image { style-background-image-attlist, @@ -5459,74 +3590,159 @@ style-background-image-attlist = }? & attribute style:filter-name { \string }? & attribute draw:opacity { zeroToHundredPercent }? -horiBackPos = "left" | "center" | "right" -vertBackPos = "top" | "center" | "bottom" -common-border-attlist = - attribute fo:border { \string }?, - attribute fo:border-top { \string }?, - attribute fo:border-bottom { \string }?, - attribute fo:border-left { \string }?, - attribute fo:border-right { \string }? -common-border-line-width-attlist = - attribute style:border-line-width { borderWidths }?, - attribute style:border-line-width-top { borderWidths }?, - attribute style:border-line-width-bottom { borderWidths }?, - attribute style:border-line-width-left { borderWidths }?, - attribute style:border-line-width-right { borderWidths }? -borderWidths = list { positiveLength, positiveLength, positiveLength } -common-padding-attlist = - attribute fo:padding { nonNegativeLength }?, - attribute fo:padding-top { nonNegativeLength }?, - attribute fo:padding-bottom { nonNegativeLength }?, - attribute fo:padding-left { nonNegativeLength }?, - attribute fo:padding-right { nonNegativeLength }? -common-shadow-attlist = attribute style:shadow { shadowType }? -common-keep-with-next-attlist = - attribute fo:keep-with-next { "auto" | "always" }? -common-writing-mode-attlist = - attribute style:writing-mode { - "lr-tb" | "rl-tb" | "tb-rl" | "tb-lr" | "lr" | "rl" | "tb" | "page" - }? -common-page-number-attlist = - attribute style:page-number { positiveInteger | "auto" }? -common-background-transparency-attlist = - attribute style:background-transparency { zeroToHundredPercent }? -style-ruby-properties = - element style:ruby-properties { style-ruby-properties-content-strict } -style-ruby-properties-content-strict = - style-ruby-properties-attlist, style-ruby-properties-elements -style-ruby-properties-elements = empty -style-ruby-properties-attlist = - attribute style:ruby-position { "above" | "below" }? - & attribute style:ruby-align { - "left" - | "center" - | "right" - | "distribute-letter" - | "distribute-space" +style-chart-properties = + element style:chart-properties { + style-chart-properties-content-strict + } +style-chart-properties-attlist = + attribute chart:scale-text { boolean }? + & attribute chart:three-dimensional { boolean }? + & attribute chart:deep { boolean }? + & attribute chart:right-angled-axes { boolean }? + & (attribute chart:symbol-type { "none" } + | attribute chart:symbol-type { "automatic" } + | (attribute chart:symbol-type { "named-symbol" }, + attribute chart:symbol-name { + "square" + | "diamond" + | "arrow-down" + | "arrow-up" + | "arrow-right" + | "arrow-left" + | "bow-tie" + | "hourglass" + | "circle" + | "star" + | "x" + | "plus" + | "asterisk" + | "horizontal-bar" + | "vertical-bar" + }) + | (attribute chart:symbol-type { "image" }, + element chart:symbol-image { + attribute xlink:href { anyIRI } + }) + | empty) + & attribute chart:symbol-width { nonNegativeLength }? + & attribute chart:symbol-height { nonNegativeLength }? + & attribute chart:sort-by-x-values { boolean }? + & attribute chart:vertical { boolean }? + & attribute chart:connect-bars { boolean }? + & attribute chart:gap-width { integer }? + & attribute chart:overlap { integer }? + & attribute chart:group-bars-per-axis { boolean }? + & attribute chart:japanese-candle-stick { boolean }? + & attribute chart:interpolation { + "none" + | "cubic-spline" + | "b-spline" + | "step-start" + | "step-end" + | "step-center-x" + | "step-center-y" + }? + & attribute chart:spline-order { positiveInteger }? + & attribute chart:spline-resolution { positiveInteger }? + & attribute chart:pie-offset { nonNegativeInteger }? + & attribute chart:angle-offset { angle }? + & attribute chart:hole-size { percent }? + & attribute chart:lines { boolean }? + & attribute chart:solid-type { + "cuboid" | "cylinder" | "cone" | "pyramid" + }? + & attribute chart:stacked { boolean }? + & attribute chart:percentage { boolean }? + & attribute chart:treat-empty-cells { + "use-zero" | "leave-gap" | "ignore" + }? + & attribute chart:link-data-style-to-source { boolean }? + & attribute chart:logarithmic { boolean }? + & attribute chart:maximum { double }? + & attribute chart:minimum { double }? + & attribute chart:origin { double }? + & attribute chart:interval-major { double }? + & attribute chart:interval-minor-divisor { positiveInteger }? + & attribute chart:tick-marks-major-inner { boolean }? + & attribute chart:tick-marks-major-outer { boolean }? + & attribute chart:tick-marks-minor-inner { boolean }? + & attribute chart:tick-marks-minor-outer { boolean }? + & attribute chart:reverse-direction { boolean }? + & attribute chart:display-label { boolean }? + & attribute chart:text-overlap { boolean }? + & attribute text:line-break { boolean }? + & attribute chart:label-arrangement { + "side-by-side" | "stagger-even" | "stagger-odd" + }? + & common-style-direction-attlist + & common-rotation-angle-attlist + & attribute chart:data-label-number { + "none" | "value" | "percentage" | "value-and-percentage" + }? + & attribute chart:data-label-text { boolean }? + & attribute chart:data-label-symbol { boolean }? + & element chart:label-separator { text-p }? + & attribute chart:label-position { labelPositions }? + & attribute chart:label-position-negative { labelPositions }? + & attribute chart:visible { boolean }? + & attribute chart:auto-position { boolean }? + & attribute chart:auto-size { boolean }? + & attribute chart:mean-value { boolean }? + & attribute chart:error-category { + "none" + | "variance" + | "standard-deviation" + | "percentage" + | "error-margin" + | "constant" + | "standard-error" + | "cell-range" + }? + & attribute chart:error-percentage { double }? + & attribute chart:error-margin { double }? + & attribute chart:error-lower-limit { double }? + & attribute chart:error-upper-limit { double }? + & attribute chart:error-upper-indicator { boolean }? + & attribute chart:error-lower-indicator { boolean }? + & attribute chart:error-lower-range { cellRangeAddressList }? + & attribute chart:error-upper-range { cellRangeAddressList }? + & attribute chart:series-source { "columns" | "rows" }? + & attribute chart:regression-type { + "none" + | "linear" + | "logarithmic" + | "moving-average" + | "exponential" + | "power" + | "polynomial" }? -style-section-properties = - element style:section-properties { - style-section-properties-content-strict - } -style-section-properties-content-strict = - style-section-properties-attlist, style-section-properties-elements -style-section-properties-attlist = - common-background-color-attlist - & common-horizontal-margin-attlist - & attribute style:protect { boolean }? - & common-editable-attlist - & attribute text:dont-balance-text-columns { boolean }? - & common-writing-mode-attlist -style-section-properties-elements = - style-background-image & style-columns & text-notes-configuration* -style-columns = - element style:columns { - style-columns-attlist, style-column-sep?, style-column* - }? -style-columns-attlist = - attribute fo:column-count { positiveInteger } - & attribute fo:column-gap { length }? + & attribute chart:regression-max-degree { positiveInteger }? + & attribute chart:regression-force-intercept { boolean }? + & attribute chart:regression-intercept-value { double }? + & attribute chart:regression-name { \string }? + & # https://issues.oasis-open.org/browse/OFFICE-3958 + attribute chart:regression-period { positiveInteger }? + & attribute chart:regression-moving-type { + "prior" | "central" | "averaged-abscissa" + }? + & # https://issues.oasis-open.org/browse/OFFICE-3959 + attribute chart:axis-position { "start" | "end" | double }? + & attribute chart:axis-label-position { + "near-axis" + | "near-axis-other-side" + | "outside-start" + | "outside-end" + }? + & attribute chart:tick-mark-position { + "at-labels" | "at-axis" | "at-labels-and-axis" + }? + & attribute chart:include-hidden-cells { boolean }? + & (attribute chart:data-label-series { boolean }?) + # https://issues.oasis-open.org/browse/OFFICE-2117 + +style-chart-properties-content-strict = + style-chart-properties-attlist, style-chart-properties-elements +style-chart-properties-elements = empty style-column = element style:column { style-column-attlist } style-column-attlist = attribute style:rel-width { relativeLength } @@ -5543,132 +3759,235 @@ style-column-sep-attlist = & attribute style:height { zeroToHundredPercent }? & attribute style:vertical-align { "top" | "middle" | "bottom" }? & attribute style:color { color }? -style-table-properties = - element style:table-properties { - style-table-properties-content-strict - } -style-table-properties-content-strict = - style-table-properties-attlist, style-table-properties-elements -style-table-properties-attlist = - attribute style:width { positiveLength }? - & attribute style:rel-width { percent }? - & attribute table:align { "left" | "center" | "right" | "margins" }? - & common-horizontal-margin-attlist - & common-vertical-margin-attlist - & common-margin-attlist - & common-page-number-attlist - & common-break-attlist - & common-background-color-attlist - & common-shadow-attlist - & common-keep-with-next-attlist - & attribute style:may-break-between-rows { boolean }? - & attribute table:border-model { "collapsing" | "separating" }? - & common-writing-mode-attlist - & attribute table:display { boolean }? -style-table-properties-elements = style-background-image -style-table-column-properties = - element style:table-column-properties { - style-table-column-properties-content-strict +style-columns = + element style:columns { + style-columns-attlist, style-column-sep?, style-column* + }? +style-columns-attlist = + attribute fo:column-count { positiveInteger } + & attribute fo:column-gap { length }? +style-default-page-layout = + element style:default-page-layout { style-page-layout-content } +style-default-style = + element style:default-style { style-style-content } +style-drawing-page-properties = + element style:drawing-page-properties { + style-drawing-page-properties-content-strict } -style-table-column-properties-content-strict = - style-table-column-properties-attlist, - style-table-column-properties-elements -style-table-column-properties-elements = empty -style-table-column-properties-attlist = - attribute style:column-width { positiveLength }? - & attribute style:rel-column-width { relativeLength }? - & attribute style:use-optimal-column-width { boolean }? - & common-break-attlist -style-table-row-properties = - element style:table-row-properties { - style-table-row-properties-content-strict +style-drawing-page-properties-attlist = + attribute presentation:transition-type { + "manual" | "automatic" | "semi-automatic" + }? + & attribute presentation:transition-style { + "none" + | "fade-from-left" + | "fade-from-top" + | "fade-from-right" + | "fade-from-bottom" + | "fade-from-upperleft" + | "fade-from-upperright" + | "fade-from-lowerleft" + | "fade-from-lowerright" + | "move-from-left" + | "move-from-top" + | "move-from-right" + | "move-from-bottom" + | "move-from-upperleft" + | "move-from-upperright" + | "move-from-lowerleft" + | "move-from-lowerright" + | "uncover-to-left" + | "uncover-to-top" + | "uncover-to-right" + | "uncover-to-bottom" + | "uncover-to-upperleft" + | "uncover-to-upperright" + | "uncover-to-lowerleft" + | "uncover-to-lowerright" + | "fade-to-center" + | "fade-from-center" + | "vertical-stripes" + | "horizontal-stripes" + | "clockwise" + | "counterclockwise" + | "open-vertical" + | "open-horizontal" + | "close-vertical" + | "close-horizontal" + | "wavyline-from-left" + | "wavyline-from-top" + | "wavyline-from-right" + | "wavyline-from-bottom" + | "spiralin-left" + | "spiralin-right" + | "spiralout-left" + | "spiralout-right" + | "roll-from-top" + | "roll-from-left" + | "roll-from-right" + | "roll-from-bottom" + | "stretch-from-left" + | "stretch-from-top" + | "stretch-from-right" + | "stretch-from-bottom" + | "vertical-lines" + | "horizontal-lines" + | "dissolve" + | "random" + | "vertical-checkerboard" + | "horizontal-checkerboard" + | "interlocking-horizontal-left" + | "interlocking-horizontal-right" + | "interlocking-vertical-top" + | "interlocking-vertical-bottom" + | "fly-away" + | "open" + | "close" + | "melt" + }? + & attribute presentation:transition-speed { presentationSpeeds }? + & attribute smil:type { \string }? + & attribute smil:subtype { \string }? + & attribute smil:direction { "forward" | "reverse" }? + & attribute smil:fadeColor { color }? + & attribute presentation:duration { duration }? + & attribute presentation:visibility { "visible" | "hidden" }? + & attribute draw:background-size { "full" | "border" }? + & attribute presentation:background-objects-visible { boolean }? + & attribute presentation:background-visible { boolean }? + & attribute presentation:display-header { boolean }? + & attribute presentation:display-footer { boolean }? + & attribute presentation:display-page-number { boolean }? + & attribute presentation:display-date-time { boolean }? +style-drawing-page-properties-content-strict = + style-graphic-fill-properties-attlist, + style-drawing-page-properties-attlist, + style-drawing-page-properties-elements +style-drawing-page-properties-elements = presentation-sound? +style-drop-cap = + element style:drop-cap { style-drop-cap-attlist, empty }? +style-drop-cap-attlist = + attribute style:length { "word" | positiveInteger }? + & attribute style:lines { positiveInteger }? + & attribute style:distance { length }? + & attribute style:style-name { styleNameRef }? +style-font-face = + element style:font-face { + style-font-face-attlist, svg-font-face-src?, svg-definition-src? } -style-table-row-properties-content-strict = - style-table-row-properties-attlist, - style-table-row-properties-elements -style-table-row-properties-attlist = - attribute style:row-height { positiveLength }? - & attribute style:min-row-height { nonNegativeLength }? - & attribute style:use-optimal-row-height { boolean }? - & common-background-color-attlist - & common-break-attlist - & attribute fo:keep-together { "auto" | "always" }? -style-table-row-properties-elements = style-background-image -style-table-cell-properties = - element style:table-cell-properties { - style-table-cell-properties-content-strict +style-font-face-attlist = + attribute svg:font-family { \string }? + & attribute svg:font-style { fontStyle }? + & attribute svg:font-variant { fontVariant }? + & attribute svg:font-weight { fontWeight }? + & attribute svg:font-stretch { + "normal" + | "ultra-condensed" + | "extra-condensed" + | "condensed" + | "semi-condensed" + | "semi-expanded" + | "expanded" + | "extra-expanded" + | "ultra-expanded" + }? + & attribute svg:font-size { positiveLength }? + & attribute svg:unicode-range { \string }? + & attribute svg:units-per-em { integer }? + & attribute svg:panose-1 { \string }? + & attribute svg:stemv { integer }? + & attribute svg:stemh { integer }? + & attribute svg:slope { integer }? + & attribute svg:cap-height { integer }? + & attribute svg:x-height { integer }? + & attribute svg:accent-height { integer }? + & attribute svg:ascent { integer }? + & attribute svg:descent { integer }? + & attribute svg:widths { \string }? + & attribute svg:bbox { \string }? + & attribute svg:ideographic { integer }? + & attribute svg:alphabetic { integer }? + & attribute svg:mathematical { integer }? + & attribute svg:hanging { integer }? + & attribute svg:v-ideographic { integer }? + & attribute svg:v-alphabetic { integer }? + & attribute svg:v-mathematical { integer }? + & attribute svg:v-hanging { integer }? + & attribute svg:underline-position { integer }? + & attribute svg:underline-thickness { integer }? + & attribute svg:strikethrough-position { integer }? + & attribute svg:strikethrough-thickness { integer }? + & attribute svg:overline-position { integer }? + & attribute svg:overline-thickness { integer }? + & attribute style:name { \string } + & attribute style:font-adornments { \string }? + & attribute style:font-family-generic { fontFamilyGeneric }? + & attribute style:font-pitch { fontPitch }? + & attribute style:font-charset { textEncoding }? +style-footer = + element style:footer { + common-style-header-footer-attlist, header-footer-content } -style-table-cell-properties-content-strict = - style-table-cell-properties-attlist, - style-table-cell-properties-elements -style-table-cell-properties-attlist = - attribute style:vertical-align { - "top" | "middle" | "bottom" | "automatic" +style-footer-first = + element style:footer-first { + common-style-header-footer-attlist, + header-footer-content + # https://issues.oasis-open.org/browse/OFFICE-3789 + + } +style-footer-left = + element style:footer-left { + common-style-header-footer-attlist, header-footer-content + } +style-footer-style = + element style:footer-style { style-header-footer-properties? } +style-footnote-sep = + element style:footnote-sep { style-footnote-sep-attlist, empty }? +style-footnote-sep-attlist = + attribute style:width { length }?, + attribute style:rel-width { percent }?, + attribute style:color { color }?, + attribute style:line-style { lineStyle }?, + attribute style:adjustment { "left" | "center" | "right" }?, + attribute style:distance-before-sep { length }?, + attribute style:distance-after-sep { length }? +style-graphic-fill-properties-attlist = + attribute draw:fill { + "none" | "solid" | "bitmap" | "gradient" | "hatch" }? - & attribute style:text-align-source { "fix" | "value-type" }? - & common-style-direction-attlist - & attribute style:glyph-orientation-vertical { - "auto" | "0" | "0deg" | "0rad" | "0grad" - }? - & common-writing-mode-attlist - & common-shadow-attlist - & common-background-color-attlist - & common-border-attlist - & attribute style:diagonal-tl-br { \string }? - & attribute style:diagonal-tl-br-widths { borderWidths }? - & attribute style:diagonal-bl-tr { \string }? - & attribute style:diagonal-bl-tr-widths { borderWidths }? - & common-border-line-width-attlist - & common-padding-attlist - & attribute fo:wrap-option { "no-wrap" | "wrap" }? - & common-rotation-angle-attlist - & attribute style:rotation-align { - "none" | "bottom" | "top" | "center" + & attribute draw:fill-color { color }? + & attribute draw:secondary-fill-color { color }? + & attribute draw:fill-gradient-name { styleNameRef }? + & attribute draw:gradient-step-count { nonNegativeInteger }? + & attribute draw:fill-hatch-name { styleNameRef }? + & attribute draw:fill-hatch-solid { boolean }? + & attribute draw:fill-image-name { styleNameRef }? + & attribute style:repeat { "no-repeat" | "repeat" | "stretch" }? + & attribute draw:fill-image-width { length | percent }? + & attribute draw:fill-image-height { length | percent }? + & attribute draw:fill-image-ref-point-x { percent }? + & attribute draw:fill-image-ref-point-y { percent }? + & attribute draw:fill-image-ref-point { + "top-left" + | "top" + | "top-right" + | "left" + | "center" + | "right" + | "bottom-left" + | "bottom" + | "bottom-right" }? - & attribute style:cell-protect { - "none" - | "hidden-and-protected" - | list { ("protected" | "formula-hidden")+ } + & attribute draw:tile-repeat-offset { + list { zeroToHundredPercent, ("horizontal" | "vertical") } }? - & attribute style:print-content { boolean }? - & attribute style:decimal-places { nonNegativeInteger }? - & attribute style:repeat-content { boolean }? - & attribute style:shrink-to-fit { boolean }? -common-style-direction-attlist = - attribute style:direction { "ltr" | "ttb" }? -style-table-cell-properties-elements = style-background-image -common-rotation-angle-attlist = - attribute style:rotation-angle { angle }? -style-list-level-properties = - element style:list-level-properties { - style-list-level-properties-content-strict + & attribute draw:opacity { zeroToHundredPercent }? + & attribute draw:opacity-name { styleNameRef }? + & attribute svg:fill-rule { "nonzero" | "evenodd" }? +style-graphic-properties = + element style:graphic-properties { + style-graphic-properties-content-strict } -style-list-level-properties-content-strict = - style-list-level-properties-attlist, - style-list-level-properties-elements -style-list-level-properties-attlist = - common-text-align - & attribute text:space-before { length }? - & attribute text:min-label-width { nonNegativeLength }? - & attribute text:min-label-distance { nonNegativeLength }? - & attribute style:font-name { \string }? - & attribute fo:width { positiveLength }? - & attribute fo:height { positiveLength }? - & common-vertical-rel-attlist - & common-vertical-pos-attlist - & attribute text:list-level-position-and-space-mode { - "label-width-and-position" | "label-alignment" - }? -style-list-level-properties-elements = style-list-level-label-alignment -style-list-level-label-alignment = - element style:list-level-label-alignment { - style-list-level-label-alignment-attlist, empty - }? -style-list-level-label-alignment-attlist = - attribute text:label-followed-by { "listtab" | "space" | "nothing" } - & attribute text:list-tab-stop-position { length }? - & attribute fo:text-indent { length }? - & attribute fo:margin-left { length }? style-graphic-properties-attlist = attribute draw:stroke { "none" | "dash" | "solid" }? & attribute draw:stroke-dash { styleNameRef }? @@ -5717,7 +4036,9 @@ style-graphic-properties-attlist = "greyscale" | "mono" | "watermark" | "standard" }? & attribute draw:color-inversion { boolean }? - & attribute draw:luminance { zeroToHundredPercent }? + & attribute draw:luminance { signedZeroToHundredPercent } + # https://issues.oasis-open.org/browse/OFFICE-3821 + ? & attribute draw:contrast { percent }? & attribute draw:gamma { percent }? & attribute draw:red { signedZeroToHundredPercent }? @@ -5758,497 +4079,2316 @@ style-graphic-properties-attlist = | "ft" | "mi" }? - & attribute draw:show-unit { boolean }? - & attribute draw:decimal-places { nonNegativeInteger }? - & attribute draw:caption-type { - "straight-line" | "angled-line" | "angled-connector-line" + & attribute draw:show-unit { boolean }? + & attribute draw:decimal-places { nonNegativeInteger }? + & attribute draw:caption-type { + "straight-line" | "angled-line" | "angled-connector-line" + }? + & attribute draw:caption-angle-type { "fixed" | "free" }? + & attribute draw:caption-angle { angle }? + & attribute draw:caption-gap { distance }? + & attribute draw:caption-escape-direction { + "horizontal" | "vertical" | "auto" + }? + & attribute draw:caption-escape { length | percent }? + & attribute draw:caption-line-length { length }? + & attribute draw:caption-fit-line-length { boolean }? + & attribute dr3d:horizontal-segments { nonNegativeInteger }? + & attribute dr3d:vertical-segments { nonNegativeInteger }? + & attribute dr3d:edge-rounding { percent }? + & attribute dr3d:edge-rounding-mode { "correct" | "attractive" }? + & attribute dr3d:back-scale { percent }? + & attribute dr3d:depth { length }? + & attribute dr3d:backface-culling { "enabled" | "disabled" }? + & attribute dr3d:end-angle { angle }? + & attribute dr3d:close-front { boolean }? + & attribute dr3d:close-back { boolean }? + & attribute dr3d:lighting-mode { "standard" | "double-sided" }? + & attribute dr3d:normals-kind { "object" | "flat" | "sphere" }? + & attribute dr3d:normals-direction { "normal" | "inverse" }? + & attribute dr3d:texture-generation-mode-x { + "object" | "parallel" | "sphere" + }? + & attribute dr3d:texture-generation-mode-y { + "object" | "parallel" | "sphere" + }? + & attribute dr3d:texture-kind { "luminance" | "intensity" | "color" }? + & attribute dr3d:texture-filter { "enabled" | "disabled" }? + & attribute dr3d:texture-mode { "replace" | "modulate" | "blend" }? + & attribute dr3d:ambient-color { color }? + & attribute dr3d:emissive-color { color }? + & attribute dr3d:specular-color { color }? + & attribute dr3d:diffuse-color { color }? + & attribute dr3d:shininess { percent }? + & attribute dr3d:shadow { "visible" | "hidden" }? + & common-draw-rel-size-attlist + & attribute fo:min-width { length | percent }? + & attribute fo:min-height { length | percent }? + & attribute fo:max-height { length | percent }? + & attribute fo:max-width { length | percent }? + & common-horizontal-margin-attlist + & common-vertical-margin-attlist + & common-margin-attlist + & attribute style:print-content { boolean }? + & attribute style:protect { + "none" + | list { ("content" | "position" | "size")+ } + }? + & attribute style:horizontal-pos { + "left" + | "center" + | "right" + | "from-left" + | "inside" + | "outside" + | "from-inside" + }? + & attribute svg:x { coordinate }? + & attribute style:horizontal-rel { + "page" + | "page-content" + | "page-start-margin" + | "page-end-margin" + | "frame" + | "frame-content" + | "frame-start-margin" + | "frame-end-margin" + | "paragraph" + | "paragraph-content" + | "paragraph-start-margin" + | "paragraph-end-margin" + | "char" + }? + & common-vertical-pos-attlist + & common-vertical-rel-attlist + & common-text-anchor-attlist + & common-border-attlist + & common-border-line-width-attlist + & common-padding-attlist + & common-shadow-attlist + & common-background-color-attlist + & common-background-transparency-attlist + & common-editable-attlist + & attribute style:wrap { + "none" + | "left" + | "right" + | "parallel" + | "dynamic" + | "run-through" + | "biggest" + }? + & attribute style:wrap-dynamic-threshold { nonNegativeLength }? + & attribute style:number-wrapped-paragraphs { + "no-limit" | positiveInteger + }? + & attribute style:wrap-contour { boolean }? + & attribute style:wrap-contour-mode { "full" | "outside" }? + & attribute style:run-through { "foreground" | "background" }? + & attribute style:flow-with-text { boolean }? + & attribute style:overflow-behavior { + "clip" | "auto-create-new-frame" + }? + & attribute style:mirror { + "none" + | "vertical" + | horizontal-mirror + | list { "vertical", horizontal-mirror } + | list { horizontal-mirror, "vertical" } + }? + & attribute fo:clip { "auto" | clipShape }? + & attribute draw:wrap-influence-on-position { + "iterative" | "once-concurrent" | "once-successive" + }? + & common-writing-mode-attlist + & attribute draw:frame-display-scrollbar { boolean }? + & attribute draw:frame-display-border { boolean }? + & attribute draw:frame-margin-horizontal { nonNegativePixelLength }? + & attribute draw:frame-margin-vertical { nonNegativePixelLength }? + & attribute draw:visible-area-left { nonNegativeLength }? + & attribute draw:visible-area-top { nonNegativeLength }? + & attribute draw:visible-area-width { positiveLength }? + & attribute draw:visible-area-height { positiveLength }? + & attribute draw:draw-aspect { + "content" | "thumbnail" | "icon" | "print-view" + }? + & attribute draw:ole-draw-aspect { nonNegativeInteger }? +style-graphic-properties-content-strict = + style-graphic-properties-attlist, + style-graphic-fill-properties-attlist, + style-graphic-properties-elements +style-graphic-properties-elements = + text-list-style? & style-background-image & style-columns +style-handout-master = + element style:handout-master { + common-presentation-header-footer-attlist, + style-handout-master-attlist, + shape* + } +style-handout-master-attlist = + attribute presentation:presentation-page-layout-name { styleNameRef }? + & attribute style:page-layout-name { styleNameRef } + & attribute draw:style-name { styleNameRef }? +style-header = + element style:header { + common-style-header-footer-attlist, header-footer-content + } +style-header-first = + element style:header-first { + common-style-header-footer-attlist, + header-footer-content + # https://issues.oasis-open.org/browse/OFFICE-3789 + + } +style-header-footer-properties = + element style:header-footer-properties { + style-header-footer-properties-content-strict + } +style-header-footer-properties-attlist = + attribute svg:height { length }? + & attribute fo:min-height { length }? + & common-horizontal-margin-attlist + & common-vertical-margin-attlist + & common-margin-attlist + & common-border-attlist + & common-border-line-width-attlist + & common-padding-attlist + & common-background-color-attlist + & common-shadow-attlist + & attribute style:dynamic-spacing { boolean }? +style-header-footer-properties-content-strict = + style-header-footer-properties-attlist, + style-header-footer-properties-elements +style-header-footer-properties-elements = style-background-image +style-header-left = + element style:header-left { + common-style-header-footer-attlist, header-footer-content + } +style-header-style = + element style:header-style { style-header-footer-properties? } +style-list-level-label-alignment = + element style:list-level-label-alignment { + style-list-level-label-alignment-attlist, empty + }? +style-list-level-label-alignment-attlist = + attribute text:label-followed-by { "listtab" | "space" | "nothing" } + & attribute text:list-tab-stop-position { length }? + & attribute fo:text-indent { length }? + & attribute fo:margin-left { length }? +style-list-level-properties = + element style:list-level-properties { + style-list-level-properties-content-strict + } +style-list-level-properties-attlist = + common-text-align + & attribute text:space-before { length }? + & attribute text:min-label-width { nonNegativeLength }? + & attribute text:min-label-distance { nonNegativeLength }? + & attribute style:font-name { \string }? + & attribute fo:width { positiveLength }? + & attribute fo:height { positiveLength }? + & common-vertical-rel-attlist + & common-vertical-pos-attlist + & attribute text:list-level-position-and-space-mode { + "label-width-and-position" | "label-alignment" }? - & attribute draw:caption-angle-type { "fixed" | "free" }? - & attribute draw:caption-angle { angle }? - & attribute draw:caption-gap { distance }? - & attribute draw:caption-escape-direction { - "horizontal" | "vertical" | "auto" +style-list-level-properties-content-strict = + style-list-level-properties-attlist, + style-list-level-properties-elements +style-list-level-properties-elements = style-list-level-label-alignment +style-map = element style:map { style-map-attlist, empty } +style-map-attlist = + attribute style:condition { \string } + & attribute style:apply-style-name { styleNameRef } + & attribute style:base-cell-address { cellAddress }? +style-master-page = + element style:master-page { + style-master-page-attlist, + (style-header, + style-header-left?, + (style-header-first?) + # https://issues.oasis-open.org/browse/OFFICE-3789 + )?, + (style-footer, + style-footer-left?, + (style-footer-first?) + # https://issues.oasis-open.org/browse/OFFICE-3789 + )?, + draw-layer-set?, + office-forms?, + shape*, + animation-element?, + presentation-notes? + } +style-master-page-attlist = + attribute style:name { styleName } + & attribute style:display-name { \string }? + & attribute style:page-layout-name { styleNameRef } + & attribute draw:style-name { styleNameRef }? + & attribute style:next-style-name { styleNameRef }? +style-num-letter-sync-attlist = + attribute style:num-letter-sync { boolean }? +style-page-layout = + element style:page-layout { + style-page-layout-attlist, style-page-layout-content + } +style-page-layout-attlist = + attribute style:name { styleName } + & attribute style:page-usage { + "all" | "left" | "right" | "mirrored" }? - & attribute draw:caption-escape { length | percent }? - & attribute draw:caption-line-length { length }? - & attribute draw:caption-fit-line-length { boolean }? - & attribute dr3d:horizontal-segments { nonNegativeInteger }? - & attribute dr3d:vertical-segments { nonNegativeInteger }? - & attribute dr3d:edge-rounding { percent }? - & attribute dr3d:edge-rounding-mode { "correct" | "attractive" }? - & attribute dr3d:back-scale { percent }? - & attribute dr3d:depth { length }? - & attribute dr3d:backface-culling { "enabled" | "disabled" }? - & attribute dr3d:end-angle { angle }? - & attribute dr3d:close-front { boolean }? - & attribute dr3d:close-back { boolean }? - & attribute dr3d:lighting-mode { "standard" | "double-sided" }? - & attribute dr3d:normals-kind { "object" | "flat" | "sphere" }? - & attribute dr3d:normals-direction { "normal" | "inverse" }? - & attribute dr3d:texture-generation-mode-x { - "object" | "parallel" | "sphere" +style-page-layout-content = + style-page-layout-properties?, + style-header-style?, + style-footer-style? +style-page-layout-properties = + element style:page-layout-properties { + style-page-layout-properties-content-strict + } +style-page-layout-properties-attlist = + attribute fo:page-width { length }? + & attribute fo:page-height { length }? + & common-num-format-attlist? + & common-num-format-prefix-suffix-attlist + & attribute style:paper-tray-name { "default" | \string }? + & attribute style:print-orientation { "portrait" | "landscape" }? + & common-horizontal-margin-attlist + & common-vertical-margin-attlist + & common-margin-attlist + & common-border-attlist + & common-border-line-width-attlist + & common-padding-attlist + & common-shadow-attlist + & common-background-color-attlist + & attribute style:register-truth-ref-style-name { styleNameRef }? + & attribute style:print { + list { + ("headers" + | "grid" + | "annotations" + | "objects" + | "charts" + | "drawings" + | "formulas" + | "zero-values")* + } }? - & attribute dr3d:texture-generation-mode-y { - "object" | "parallel" | "sphere" + & attribute style:print-page-order { "ttb" | "ltr" }? + & attribute style:first-page-number { positiveInteger | "continue" }? + & (attribute style:scale-to { percent }? + | attribute style:scale-to-pages { positiveInteger }? + | (attribute style:scale-to-X { positiveInteger }?, + attribute style:scale-to-Y { positiveInteger }?)) + & # https://issues.oasis-open.org/browse/OFFICE-3857 + attribute style:table-centering { + "horizontal" | "vertical" | "both" | "none" }? - & attribute dr3d:texture-kind { "luminance" | "intensity" | "color" }? - & attribute dr3d:texture-filter { "enabled" | "disabled" }? - & attribute dr3d:texture-mode { "replace" | "modulate" | "blend" }? - & attribute dr3d:ambient-color { color }? - & attribute dr3d:emissive-color { color }? - & attribute dr3d:specular-color { color }? - & attribute dr3d:diffuse-color { color }? - & attribute dr3d:shininess { percent }? - & attribute dr3d:shadow { "visible" | "hidden" }? - & common-draw-rel-size-attlist - & attribute fo:min-width { length | percent }? - & attribute fo:min-height { length | percent }? - & attribute fo:max-height { length | percent }? - & attribute fo:max-width { length | percent }? + & attribute style:footnote-max-height { length }? + & common-writing-mode-attlist + & attribute style:layout-grid-mode { "none" | "line" | "both" }? + & attribute style:layout-grid-standard-mode { boolean }? + & attribute style:layout-grid-base-height { length }? + & attribute style:layout-grid-ruby-height { length }? + & attribute style:layout-grid-lines { positiveInteger }? + & attribute style:layout-grid-base-width { length }? + & attribute style:layout-grid-color { color }? + & attribute style:layout-grid-ruby-below { boolean }? + & attribute style:layout-grid-print { boolean }? + & attribute style:layout-grid-display { boolean }? + & attribute style:layout-grid-snap-to { boolean }? +style-page-layout-properties-content-strict = + style-page-layout-properties-attlist, + style-page-layout-properties-elements +style-page-layout-properties-elements = + style-background-image & style-columns & style-footnote-sep +style-paragraph-properties = + element style:paragraph-properties { + style-paragraph-properties-content-strict + } +style-paragraph-properties-attlist = + attribute style:contextual-spacing { boolean }? + & # https://issues.oasis-open.org/browse/OFFICE-3767 + attribute fo:line-height { "normal" | nonNegativeLength | percent }? + & attribute style:line-height-at-least { nonNegativeLength }? + & attribute style:line-spacing { length }? + & attribute style:font-independent-line-spacing { boolean }? + & common-text-align + & attribute fo:text-align-last { "start" | "center" | "justify" }? + & attribute style:justify-single-word { boolean }? + & attribute fo:keep-together { "auto" | "always" }? + & attribute fo:widows { nonNegativeInteger }? + & attribute fo:orphans { nonNegativeInteger }? + & attribute style:tab-stop-distance { nonNegativeLength }? + & attribute fo:hyphenation-keep { "auto" | "page" }? + & attribute fo:hyphenation-ladder-count { + "no-limit" | positiveInteger + }? + & attribute style:register-true { boolean }? & common-horizontal-margin-attlist + & attribute fo:text-indent { length | percent }? + & attribute style:auto-text-indent { boolean }? & common-vertical-margin-attlist & common-margin-attlist - & attribute style:print-content { boolean }? - & attribute style:protect { - "none" - | list { ("content" | "position" | "size")+ } + & common-break-attlist + & common-background-color-attlist + & common-border-attlist + & common-border-line-width-attlist + & attribute style:join-border { boolean }? + & common-padding-attlist + & common-shadow-attlist + & common-keep-with-next-attlist + & attribute text:number-lines { boolean }? + & attribute text:line-number { nonNegativeInteger }? + & attribute style:text-autospace { "none" | "ideograph-alpha" }? + & attribute style:punctuation-wrap { "simple" | "hanging" }? + & attribute style:line-break { "normal" | "strict" }? + & attribute style:vertical-align { + "top" | "middle" | "bottom" | "auto" | "baseline" }? - & attribute style:horizontal-pos { + & common-writing-mode-attlist + & attribute style:writing-mode-automatic { boolean }? + & attribute style:snap-to-layout-grid { boolean }? + & common-page-number-attlist + & common-background-transparency-attlist +style-paragraph-properties-content-strict = + style-paragraph-properties-attlist, + style-paragraph-properties-elements +style-paragraph-properties-elements = + style-tab-stops & style-drop-cap & style-background-image +style-presentation-page-layout = + element style:presentation-page-layout { + attribute style:name { styleName }, + attribute style:display-name { \string }?, + presentation-placeholder* + } +style-region-center = element style:region-center { region-content } +style-region-left = element style:region-left { region-content } +style-region-right = element style:region-right { region-content } +style-ruby-properties = + element style:ruby-properties { style-ruby-properties-content-strict } +style-ruby-properties-attlist = + attribute style:ruby-position { "above" | "below" }? + & attribute style:ruby-align { "left" | "center" | "right" - | "from-left" - | "inside" - | "outside" - | "from-inside" + | "distribute-letter" + | "distribute-space" }? - & attribute svg:x { coordinate }? - & attribute style:horizontal-rel { - "page" - | "page-content" - | "page-start-margin" - | "page-end-margin" - | "frame" - | "frame-content" - | "frame-start-margin" - | "frame-end-margin" - | "paragraph" - | "paragraph-content" - | "paragraph-start-margin" - | "paragraph-end-margin" - | "char" +style-ruby-properties-content-strict = + style-ruby-properties-attlist, style-ruby-properties-elements +style-ruby-properties-elements = empty +style-section-properties = + element style:section-properties { + style-section-properties-content-strict + } +style-section-properties-attlist = + common-background-color-attlist + & common-horizontal-margin-attlist + & attribute style:protect { boolean }? + & common-editable-attlist + & attribute text:dont-balance-text-columns { boolean }? + & common-writing-mode-attlist +style-section-properties-content-strict = + style-section-properties-attlist, style-section-properties-elements +style-section-properties-elements = + style-background-image & style-columns & text-notes-configuration* +style-style = + element style:style { + style-style-attlist, style-style-content, style-map* + } +style-style-attlist = + attribute style:name { styleName } + & attribute style:display-name { \string }? + & attribute style:parent-style-name { styleNameRef }? + & attribute style:next-style-name { styleNameRef }? + & attribute style:list-level { positiveInteger | empty }? + & attribute style:list-style-name { styleName | empty }? + & attribute style:master-page-name { styleNameRef }? + & attribute style:auto-update { boolean }? + & attribute style:data-style-name { styleNameRef }? + & attribute style:percentage-data-style-name { styleNameRef }? + & attribute style:class { \string }? + & attribute style:default-outline-level { positiveInteger | empty }? +style-style-content = + (attribute style:family { "text" }, + style-text-properties?) + | (attribute style:family { "paragraph" }, + style-paragraph-properties?, + style-text-properties?) + | (attribute style:family { "section" }, + style-section-properties?) + | (attribute style:family { "ruby" }, + style-ruby-properties?) + | (attribute style:family { "table" }, + style-table-properties?) + | (attribute style:family { "table-column" }, + style-table-column-properties?) + | (attribute style:family { "table-row" }, + style-table-row-properties?) + | (attribute style:family { "table-cell" }, + style-table-cell-properties?, + style-paragraph-properties?, + style-text-properties?) + | (attribute style:family { "graphic" | "presentation" }, + style-graphic-properties?, + style-paragraph-properties?, + style-text-properties?) + | (attribute style:family { "drawing-page" }, + style-drawing-page-properties?) + | (attribute style:family { "chart" }, + style-chart-properties?, + style-graphic-properties?, + style-paragraph-properties?, + style-text-properties?) +style-tab-stop = + element style:tab-stop { style-tab-stop-attlist, empty } +style-tab-stop-attlist = + attribute style:position { length } + & (attribute style:type { "left" | "center" | "right" }? + | (attribute style:type { "char" }, + style-tab-stop-char-attlist)) + & attribute style:leader-type { lineType }? + & attribute style:leader-style { lineStyle }? + & attribute style:leader-width { lineWidth }? + & attribute style:leader-color { "font-color" | color }? + & attribute style:leader-text { character }? + & attribute style:leader-text-style { styleNameRef }? +style-tab-stop-char-attlist = attribute style:char { character } +style-tab-stops = element style:tab-stops { style-tab-stop* }? +style-table-cell-properties = + element style:table-cell-properties { + style-table-cell-properties-content-strict + } +style-table-cell-properties-attlist = + attribute style:vertical-align { + "top" | "middle" | "bottom" | "automatic" + }? + & attribute style:text-align-source { "fix" | "value-type" }? + & common-style-direction-attlist + & attribute style:glyph-orientation-vertical { + "auto" | "0" | "0deg" | "0rad" | "0grad" }? - & common-vertical-pos-attlist - & common-vertical-rel-attlist - & common-text-anchor-attlist + & common-writing-mode-attlist + & common-shadow-attlist + & common-background-color-attlist & common-border-attlist + & attribute style:diagonal-tl-br { \string }? + & attribute style:diagonal-tl-br-widths { borderWidths }? + & attribute style:diagonal-bl-tr { \string }? + & attribute style:diagonal-bl-tr-widths { borderWidths }? & common-border-line-width-attlist & common-padding-attlist + & attribute fo:wrap-option { "no-wrap" | "wrap" }? + & common-rotation-angle-attlist + & attribute style:rotation-align { + "none" | "bottom" | "top" | "center" + }? + & attribute style:cell-protect { + "none" + | "hidden-and-protected" + | list { ("protected" | "formula-hidden")+ } + }? + & attribute style:print-content { boolean }? + & attribute style:decimal-places { nonNegativeInteger }? + & attribute style:repeat-content { boolean }? + & attribute style:shrink-to-fit { boolean }? +style-table-cell-properties-content-strict = + style-table-cell-properties-attlist, + style-table-cell-properties-elements +style-table-cell-properties-elements = style-background-image +style-table-column-properties = + element style:table-column-properties { + style-table-column-properties-content-strict + } +style-table-column-properties-attlist = + attribute style:column-width { positiveLength }? + & attribute style:rel-column-width { relativeLength }? + & attribute style:use-optimal-column-width { boolean }? + & common-break-attlist +style-table-column-properties-content-strict = + style-table-column-properties-attlist, + style-table-column-properties-elements +style-table-column-properties-elements = empty +style-table-properties = + element style:table-properties { + style-table-properties-content-strict + } +style-table-properties-attlist = + attribute style:width { positiveLength }? + & attribute style:rel-width { percent }? + & attribute table:align { "left" | "center" | "right" | "margins" }? + & common-horizontal-margin-attlist + & common-vertical-margin-attlist + & common-margin-attlist + & common-page-number-attlist + & common-break-attlist + & common-background-color-attlist & common-shadow-attlist + & common-keep-with-next-attlist + & attribute style:may-break-between-rows { boolean }? + & attribute table:border-model { "collapsing" | "separating" }? + & common-writing-mode-attlist + & attribute table:display { boolean }? + & (attribute table:tab-color { color }?) + # https://issues.oasis-open.org/browse/OFFICE-2173 + +style-table-properties-content-strict = + style-table-properties-attlist, style-table-properties-elements +style-table-properties-elements = style-background-image +style-table-row-properties = + element style:table-row-properties { + style-table-row-properties-content-strict + } +style-table-row-properties-attlist = + attribute style:row-height { positiveLength }? + & attribute style:min-row-height { nonNegativeLength }? + & attribute style:use-optimal-row-height { boolean }? + & common-background-color-attlist + & common-break-attlist + & attribute fo:keep-together { "auto" | "always" }? +style-table-row-properties-content-strict = + style-table-row-properties-attlist, + style-table-row-properties-elements +style-table-row-properties-elements = style-background-image +style-text-properties = + element style:text-properties { style-text-properties-content-strict } +style-text-properties-attlist = + attribute fo:font-variant { fontVariant }? + & attribute fo:text-transform { + "none" | "lowercase" | "uppercase" | "capitalize" + }? + & attribute fo:color { color }? + & attribute style:use-window-font-color { boolean }? + & attribute style:text-outline { boolean }? + & attribute style:text-line-through-type { lineType }? + & attribute style:text-line-through-style { lineStyle }? + & attribute style:text-line-through-width { lineWidth }? + & attribute style:text-line-through-color { "font-color" | color }? + & attribute style:text-line-through-text { \string }? + & attribute style:text-line-through-text-style { styleNameRef }? + & attribute style:text-position { + list { (percent | "super" | "sub"), percent? } + }? + & attribute style:font-name { \string }? + & attribute style:font-name-asian { \string }? + & attribute style:font-name-complex { \string }? + & attribute fo:font-family { \string }? + & attribute style:font-family-asian { \string }? + & attribute style:font-family-complex { \string }? + & attribute style:font-family-generic { fontFamilyGeneric }? + & attribute style:font-family-generic-asian { fontFamilyGeneric }? + & attribute style:font-family-generic-complex { fontFamilyGeneric }? + & attribute style:font-style-name { \string }? + & attribute style:font-style-name-asian { \string }? + & attribute style:font-style-name-complex { \string }? + & attribute style:font-pitch { fontPitch }? + & attribute style:font-pitch-asian { fontPitch }? + & attribute style:font-pitch-complex { fontPitch }? + & attribute style:font-charset { textEncoding }? + & attribute style:font-charset-asian { textEncoding }? + & attribute style:font-charset-complex { textEncoding }? + & attribute fo:font-size { positiveLength | percent }? + & attribute style:font-size-asian { positiveLength | percent }? + & attribute style:font-size-complex { positiveLength | percent }? + & attribute style:font-size-rel { length }? + & attribute style:font-size-rel-asian { length }? + & attribute style:font-size-rel-complex { length }? + & attribute style:script-type { + "latin" | "asian" | "complex" | "ignore" + }? + & attribute fo:letter-spacing { length | "normal" }? + & attribute fo:language { languageCode }? + & attribute style:language-asian { languageCode }? + & attribute style:language-complex { languageCode }? + & attribute fo:country { countryCode }? + & attribute style:country-asian { countryCode }? + & attribute style:country-complex { countryCode }? + & attribute fo:script { scriptCode }? + & attribute style:script-asian { scriptCode }? + & attribute style:script-complex { scriptCode }? + & attribute style:rfc-language-tag { language }? + & attribute style:rfc-language-tag-asian { language }? + & attribute style:rfc-language-tag-complex { language }? + & attribute fo:font-style { fontStyle }? + & attribute style:font-style-asian { fontStyle }? + & attribute style:font-style-complex { fontStyle }? + & attribute style:font-relief { "none" | "embossed" | "engraved" }? + & attribute fo:text-shadow { shadowType }? + & attribute style:text-underline-type { lineType }? + & attribute style:text-underline-style { lineStyle }? + & attribute style:text-underline-width { lineWidth }? + & attribute style:text-underline-color { "font-color" | color }? + & attribute style:text-overline-type { lineType }? + & attribute style:text-overline-style { lineStyle }? + & attribute style:text-overline-width { lineWidth }? + & attribute style:text-overline-color { "font-color" | color }? + & attribute style:text-overline-mode { lineMode }? + & attribute fo:font-weight { fontWeight }? + & attribute style:font-weight-asian { fontWeight }? + & attribute style:font-weight-complex { fontWeight }? + & attribute style:text-underline-mode { lineMode }? + & attribute style:text-line-through-mode { lineMode }? + & attribute style:letter-kerning { boolean }? + & attribute style:text-blinking { boolean }? & common-background-color-attlist - & common-background-transparency-attlist - & common-editable-attlist - & attribute style:wrap { + & attribute style:text-combine { "none" | "letters" | "lines" }? + & attribute style:text-combine-start-char { character }? + & attribute style:text-combine-end-char { character }? + & attribute style:text-emphasize { "none" - | "left" - | "right" - | "parallel" - | "dynamic" - | "run-through" - | "biggest" + | list { + ("none" | "accent" | "dot" | "circle" | "disc"), + ("above" | "below") + } }? - & attribute style:wrap-dynamic-threshold { nonNegativeLength }? - & attribute style:number-wrapped-paragraphs { - "no-limit" | positiveInteger + & attribute style:text-scale { percent }? + & attribute style:text-rotation-angle { angle }? + & attribute style:text-rotation-scale { "fixed" | "line-height" }? + & attribute fo:hyphenate { boolean }? + & attribute fo:hyphenation-remain-char-count { positiveInteger }? + & attribute fo:hyphenation-push-char-count { positiveInteger }? + & (attribute text:display { "true" } + | attribute text:display { "none" } + | (attribute text:display { "condition" }, + attribute text:condition { "none" }) + | empty) +style-text-properties-content-strict = + style-text-properties-attlist, style-text-properties-elements +style-text-properties-elements = empty +styleName = xsd:NCName +styleNameRef = xsd:NCName | empty +styleNameRefs = list { xsd:NCName* } +styles = + style-style* + & text-list-style* + & number-number-style* + & number-currency-style* + & number-percentage-style* + & number-date-style* + & number-time-style* + & number-boolean-style* + & number-text-style* +svg-definition-src = + element svg:definition-src { + common-svg-font-face-xlink-attlist, empty + } +svg-desc = element svg:desc { text } +svg-font-face-format = + element svg:font-face-format { + attribute svg:string { \string }?, + empty + } +svg-font-face-name = + element svg:font-face-name { + attribute svg:name { \string }?, + empty + } +svg-font-face-src = + element svg:font-face-src { + (svg-font-face-uri | svg-font-face-name)+ + } +svg-font-face-uri = + element svg:font-face-uri { + common-svg-font-face-xlink-attlist, svg-font-face-format* + } +svg-linearGradient = + element svg:linearGradient { + common-svg-gradient-attlist, + attribute svg:x1 { coordinate | percent }?, + attribute svg:y1 { coordinate | percent }?, + attribute svg:x2 { coordinate | percent }?, + attribute svg:y2 { coordinate | percent }?, + svg-stop* + } +svg-radialGradient = + element svg:radialGradient { + common-svg-gradient-attlist, + attribute svg:cx { coordinate | percent }?, + attribute svg:cy { coordinate | percent }?, + attribute svg:r { coordinate | percent }?, + attribute svg:fx { coordinate | percent }?, + attribute svg:fy { coordinate | percent }?, + svg-stop* + } +svg-stop = + element svg:stop { + attribute svg:offset { double | percent }, + attribute svg:stop-color { color }?, + attribute svg:stop-opacity { double }? + } +svg-title = element svg:title { text } +tab-cycles = "records" | "current" | "page" +table-background = + element table:background { table-background-attlist, empty } +table-background-attlist = attribute table:style-name { styleNameRef } +table-body = element table:body { common-table-template-attlist, empty } +table-calculation-setting-attlist = + attribute table:case-sensitive { boolean }? + & attribute table:precision-as-shown { boolean }? + & attribute table:search-criteria-must-apply-to-whole-cell { + boolean }? - & attribute style:wrap-contour { boolean }? - & attribute style:wrap-contour-mode { "full" | "outside" }? - & attribute style:run-through { "foreground" | "background" }? - & attribute style:flow-with-text { boolean }? - & attribute style:overflow-behavior { - "clip" | "auto-create-new-frame" + & attribute table:automatic-find-labels { boolean }? + & attribute table:use-regular-expressions { boolean }? + & attribute table:use-wildcards { boolean }? + & attribute table:null-year { positiveInteger }? +table-calculation-settings = + element table:calculation-settings { + table-calculation-setting-attlist, + table-null-date?, + table-iteration? + } +table-cell-address = + element table:cell-address { + common-table-cell-address-attlist, empty + } +table-cell-content-change = + element table:cell-content-change { + common-table-change-attlist, + table-cell-address, + office-change-info, + table-dependencies?, + table-deletions?, + table-previous + } +table-cell-content-deletion = + element table:cell-content-deletion { + attribute table:id { \string }?, + table-cell-address?, + table-change-track-table-cell? + } +table-cell-range-source = + element table:cell-range-source { + table-table-cell-range-source-attlist, + table-linked-source-attlist, + empty + } +table-change-deletion = + element table:change-deletion { + attribute table:id { \string }?, + empty + } +table-change-track-table-cell = + element table:change-track-table-cell { + table-change-track-table-cell-attlist, text-p* + } +table-change-track-table-cell-attlist = + attribute table:cell-address { cellAddress }? + & attribute table:matrix-covered { boolean }? + & attribute table:formula { \string }? + & attribute table:number-matrix-columns-spanned { positiveInteger }? + & attribute table:number-matrix-rows-spanned { positiveInteger }? + & common-value-and-type-attlist? +table-columns = table-table-columns | table-table-column+ +table-columns-and-groups = + (table-table-column-group | table-columns-no-group)+ +table-columns-no-group = + (table-columns, (table-table-header-columns, table-columns?)?) + | (table-table-header-columns, table-columns?) +table-consolidation = + element table:consolidation { table-consolidation-attlist, empty } +table-consolidation-attlist = + attribute table:function { + "average" + | "count" + | "countnums" + | "max" + | "min" + | "product" + | "stdev" + | "stdevp" + | "sum" + | "var" + | "varp" + | \string + } + & attribute table:source-cell-range-addresses { cellRangeAddressList } + & attribute table:target-cell-address { cellAddress } + & attribute table:use-labels { "none" | "row" | "column" | "both" }? + & attribute table:link-to-source-data { boolean }? +table-content-validation = + element table:content-validation { + table-validation-attlist, + table-help-message?, + (table-error-message | (table-error-macro, office-event-listeners))? + } +table-content-validations = + element table:content-validations { table-content-validation+ } +table-covered-table-cell = + element table:covered-table-cell { + table-table-cell-attlist, table-table-cell-content + } +table-cut-offs = + element table:cut-offs { + table-movement-cut-off+ + | (table-insertion-cut-off, table-movement-cut-off*) + } +table-data-pilot-display-info = + element table:data-pilot-display-info { + table-data-pilot-display-info-attlist, empty + } +table-data-pilot-display-info-attlist = + attribute table:enabled { boolean } + & attribute table:data-field { \string } + & attribute table:member-count { nonNegativeInteger } + & attribute table:display-member-mode { "from-top" | "from-bottom" } +table-data-pilot-field = + element table:data-pilot-field { + table-data-pilot-field-attlist, + table-data-pilot-level?, + table-data-pilot-field-reference?, + table-data-pilot-groups? + } +table-data-pilot-field-attlist = + attribute table:source-field-name { \string } + & (attribute table:orientation { + "row" | "column" | "data" | "hidden" + } + | (attribute table:orientation { "page" }, + attribute table:selected-page { \string })) + & attribute table:is-data-layout-field { \string }? + & attribute table:function { + "auto" + | "average" + | "count" + | "countnums" + | "max" + | "min" + | "product" + | "stdev" + | "stdevp" + | "sum" + | "var" + | "varp" + | \string }? - & attribute style:mirror { + & attribute table:used-hierarchy { integer }? +table-data-pilot-field-reference = + element table:data-pilot-field-reference { + table-data-pilot-field-reference-attlist + } +table-data-pilot-field-reference-attlist = + attribute table:field-name { \string } + & ((attribute table:member-type { "named" }, + attribute table:member-name { \string }) + | attribute table:member-type { "previous" | "next" }) + & attribute table:type { "none" - | "vertical" - | horizontal-mirror - | list { "vertical", horizontal-mirror } - | list { horizontal-mirror, "vertical" } + | "member-difference" + | "member-percentage" + | "member-percentage-difference" + | "running-total" + | "row-percentage" + | "column-percentage" + | "total-percentage" + | "index" + } +table-data-pilot-group = + element table:data-pilot-group { + table-data-pilot-group-attlist, table-data-pilot-group-member+ + } +table-data-pilot-group-attlist = attribute table:name { \string } +table-data-pilot-group-member = + element table:data-pilot-group-member { + table-data-pilot-group-member-attlist + } +table-data-pilot-group-member-attlist = attribute table:name { \string } +table-data-pilot-groups = + element table:data-pilot-groups { + table-data-pilot-groups-attlist, table-data-pilot-group+ + } +table-data-pilot-groups-attlist = + attribute table:source-field-name { \string } + & (attribute table:date-start { dateOrDateTime | "auto" } + | attribute table:start { double | "auto" })? + & (attribute table:date-end { dateOrDateTime | "auto" } + | attribute table:end { double | "auto" })? + & attribute table:step { double }? + & attribute table:grouped-by { + "seconds" + | "minutes" + | "hours" + | "days" + | "months" + | "quarters" + | "years" + }? +# https://issues.oasis-open.org/browse/OFFICE-2118 +table-data-pilot-layout-info = + element table:data-pilot-layout-info { + table-data-pilot-layout-info-attlist, empty + } +table-data-pilot-layout-info-attlist = + attribute table:layout-mode { + "tabular-layout" + | "outline-subtotals-top" + | "outline-subtotals-bottom" + } + & attribute table:add-empty-lines { boolean } +table-data-pilot-level = + element table:data-pilot-level { + table-data-pilot-level-attlist, + table-data-pilot-subtotals?, + table-data-pilot-members?, + table-data-pilot-display-info?, + table-data-pilot-sort-info?, + table-data-pilot-layout-info? + } +table-data-pilot-level-attlist = attribute table:show-empty { boolean }? +table-data-pilot-member = + element table:data-pilot-member { + table-data-pilot-member-attlist, empty + } +table-data-pilot-member-attlist = + attribute table:name { \string } + & attribute table:display { boolean }? + & attribute table:show-details { boolean }? +table-data-pilot-members = + element table:data-pilot-members { table-data-pilot-member* } +table-data-pilot-sort-info = + element table:data-pilot-sort-info { + table-data-pilot-sort-info-attlist, empty + } +table-data-pilot-sort-info-attlist = + ((attribute table:sort-mode { "data" }, + attribute table:data-field { \string }) + | attribute table:sort-mode { "none" | "manual" | "name" }) + & attribute table:order { "ascending" | "descending" } +table-data-pilot-subtotal = + element table:data-pilot-subtotal { + table-data-pilot-subtotal-attlist, empty + } +table-data-pilot-subtotal-attlist = + attribute table:function { + "auto" + | "average" + | "count" + | "countnums" + | "max" + | "min" + | "product" + | "stdev" + | "stdevp" + | "sum" + | "var" + | "varp" + | \string + } +table-data-pilot-subtotals = + element table:data-pilot-subtotals { table-data-pilot-subtotal* } +table-data-pilot-table = + element table:data-pilot-table { + table-data-pilot-table-attlist, + (table-database-source-sql + | table-database-source-table + | table-database-source-query + | table-source-service + | table-source-cell-range)?, + table-data-pilot-field+ + } +table-data-pilot-table-attlist = + attribute table:name { \string } + & attribute table:application-data { \string }? + & attribute table:grand-total { "none" | "row" | "column" | "both" }? + & attribute table:ignore-empty-rows { boolean }? + & attribute table:identify-categories { boolean }? + & attribute table:target-range-address { cellRangeAddress } + & attribute table:buttons { cellRangeAddressList }? + & attribute table:show-filter-button { boolean }? + & attribute table:drill-down-on-double-click { boolean }? +table-data-pilot-tables = + element table:data-pilot-tables { table-data-pilot-table* } +table-database-range = + element table:database-range { + table-database-range-attlist, + (table-database-source-sql + | table-database-source-table + | table-database-source-query)?, + table-filter?, + table-sort?, + table-subtotal-rules? + } +table-database-range-attlist = + attribute table:name { \string }? + & attribute table:is-selection { boolean }? + & attribute table:on-update-keep-styles { boolean }? + & attribute table:on-update-keep-size { boolean }? + & attribute table:has-persistent-data { boolean }? + & attribute table:orientation { "column" | "row" }? + & attribute table:contains-header { boolean }? + & attribute table:display-filter-buttons { boolean }? + & attribute table:target-range-address { cellRangeAddress } + & attribute table:refresh-delay { boolean }? +table-database-ranges = + element table:database-ranges { table-database-range* } +table-database-source-query = + element table:database-source-table { + table-database-source-table-attlist, empty + } +table-database-source-query-attlist = + attribute table:database-name { \string } + & attribute table:query-name { \string } +table-database-source-sql = + element table:database-source-sql { + table-database-source-sql-attlist, empty + } +table-database-source-sql-attlist = + attribute table:database-name { \string } + & attribute table:sql-statement { \string } + & attribute table:parse-sql-statement { boolean }? +table-database-source-table = + element table:database-source-query { + table-database-source-query-attlist, empty + } +table-database-source-table-attlist = + attribute table:database-name { \string } + & attribute table:database-table-name { \string } +table-dde-link = + element table:dde-link { office-dde-source, table-table } +table-dde-links = element table:dde-links { table-dde-link+ } +table-decls = + table-calculation-settings?, + table-content-validations?, + table-label-ranges? +table-deletion = + element table:deletion { + table-deletion-attlist, + common-table-change-attlist, + office-change-info, + table-dependencies?, + table-deletions?, + table-cut-offs? + } +table-deletion-attlist = + attribute table:type { "row" | "column" | "table" } + & attribute table:position { integer } + & attribute table:table { integer }? + & attribute table:multi-deletion-spanned { integer }? +table-deletions = + element table:deletions { + (table-cell-content-deletion | table-change-deletion)+ + } +table-dependencies = element table:dependencies { table-dependency+ } +table-dependency = + element table:dependency { + attribute table:id { \string }, + empty + } +table-desc = element table:desc { text } +table-detective = + element table:detective { table-highlighted-range*, table-operation* } +table-error-macro = + element table:error-macro { + attribute table:execute { boolean }? + } +table-error-message = + element table:error-message { + attribute table:title { \string }?, + attribute table:display { boolean }?, + attribute table:message-type { + "stop" | "warning" | "information" + }?, + text-p* + } +table-even-columns = + element table:even-columns { common-table-template-attlist, empty } +table-even-rows = + element table:even-rows { common-table-template-attlist, empty } +table-filter = + element table:filter { + table-filter-attlist, + (table-filter-condition | table-filter-and | table-filter-or) + } +table-filter-and = + element table:filter-and { + (table-filter-or | table-filter-condition)+ + } +table-filter-attlist = + attribute table:target-range-address { cellRangeAddress }? + & attribute table:condition-source { "self" | "cell-range" }? + & attribute table:condition-source-range-address { cellRangeAddress }? + & attribute table:display-duplicates { boolean }? +table-filter-condition = + element table:filter-condition { + table-filter-condition-attlist, table-filter-set-item* + } +table-filter-condition-attlist = + attribute table:field-number { nonNegativeInteger } + & attribute table:value { \string | double } + & attribute table:operator { \string } + & attribute table:case-sensitive { \string }? + & attribute table:data-type { "text" | "number" }? +table-filter-or = + element table:filter-or { + (table-filter-and | table-filter-condition)+ + } +table-filter-set-item = + element table:filter-set-item { + attribute table:value { \string }, + empty + } +table-first-column = + element table:first-column { common-table-template-attlist, empty } +table-first-row = + element table:first-row { common-table-template-attlist, empty } +table-functions = + table-named-expressions?, + table-database-ranges?, + table-data-pilot-tables?, + table-consolidation?, + table-dde-links? +table-help-message = + element table:help-message { + attribute table:title { \string }?, + attribute table:display { boolean }?, + text-p* + } +table-highlighted-range = + element table:highlighted-range { + (table-highlighted-range-attlist + | table-highlighted-range-attlist-invalid), + empty + } +table-highlighted-range-attlist = + attribute table:cell-range-address { cellRangeAddress }? + & attribute table:direction { + "from-another-table" | "to-another-table" | "from-same-table" + } + & attribute table:contains-error { boolean }? +table-highlighted-range-attlist-invalid = + attribute table:marked-invalid { boolean } +table-insertion = + element table:insertion { + table-insertion-attlist, + common-table-change-attlist, + office-change-info, + table-dependencies?, + table-deletions? + } +table-insertion-attlist = + attribute table:type { "row" | "column" | "table" } + & attribute table:position { integer } + & attribute table:count { positiveInteger }? + & attribute table:table { integer }? +table-insertion-cut-off = + element table:insertion-cut-off { + table-insertion-cut-off-attlist, empty + } +table-insertion-cut-off-attlist = + attribute table:id { \string } + & attribute table:position { integer } +table-iteration = + element table:iteration { + attribute table:status { "enable" | "disable" }?, + attribute table:steps { positiveInteger }?, + attribute table:maximum-difference { double }?, + empty + } +table-label-range = + element table:label-range { table-label-range-attlist, empty } +table-label-range-attlist = + attribute table:label-cell-range-address { cellRangeAddress } + & attribute table:data-cell-range-address { cellRangeAddress } + & attribute table:orientation { "column" | "row" } +table-label-ranges = element table:label-ranges { table-label-range* } +table-last-column = + element table:last-column { common-table-template-attlist, empty } +table-last-row = + element table:last-row { common-table-template-attlist, empty } +table-linked-source-attlist = + attribute xlink:type { "simple" } + & attribute xlink:href { anyIRI } + & attribute xlink:actuate { "onRequest" }? + & attribute table:filter-name { \string }? + & attribute table:filter-options { \string }? + & attribute table:refresh-delay { duration }? +table-movement = + element table:movement { + common-table-change-attlist, + table-source-range-address, + table-target-range-address, + office-change-info, + table-dependencies?, + table-deletions? + } +table-movement-cut-off = + element table:movement-cut-off { + table-movement-cut-off-attlist, empty + } +table-movement-cut-off-attlist = + attribute table:position { integer } + | (attribute table:start-position { integer }, + attribute table:end-position { integer }) +table-named-expression = + element table:named-expression { + table-named-expression-attlist, empty + } +table-named-expression-attlist = + attribute table:name { \string }, + attribute table:expression { \string }, + attribute table:base-cell-address { cellAddress }? +table-named-expressions = + element table:named-expressions { + (table-named-range | table-named-expression)* + } +table-named-range = + element table:named-range { table-named-range-attlist, empty } +table-named-range-attlist = + attribute table:name { \string }, + attribute table:cell-range-address { cellRangeAddress }, + attribute table:base-cell-address { cellAddress }?, + attribute table:range-usable-as { + "none" + | list { + ("print-range" | "filter" | "repeat-row" | "repeat-column")+ + } + }? +table-null-date = + element table:null-date { + attribute table:value-type { "date" }?, + attribute table:date-value { date }?, + empty + } +table-odd-columns = + element table:odd-columns { common-table-template-attlist, empty } +table-odd-rows = + element table:odd-rows { common-table-template-attlist, empty } +table-operation = + element table:operation { table-operation-attlist, empty } +table-operation-attlist = + attribute table:name { + "trace-dependents" + | "remove-dependents" + | "trace-precedents" + | "remove-precedents" + | "trace-errors" + } + & attribute table:index { nonNegativeInteger } +table-previous = + element table:previous { + attribute table:id { \string }?, + table-change-track-table-cell + } +table-rows = + table-table-rows | (text-soft-page-break?, table-table-row)+ +table-rows-and-groups = (table-table-row-group | table-rows-no-group)+ +table-rows-no-group = + (table-rows, (table-table-header-rows, table-rows?)?) + | (table-table-header-rows, table-rows?) +table-scenario = + element table:scenario { table-scenario-attlist, empty } +table-scenario-attlist = + attribute table:scenario-ranges { cellRangeAddressList } + & attribute table:is-active { boolean } + & attribute table:display-border { boolean }? + & attribute table:border-color { color }? + & attribute table:copy-back { boolean }? + & attribute table:copy-styles { boolean }? + & attribute table:copy-formulas { boolean }? + & attribute table:comment { \string }? + & attribute table:protected { boolean }? +table-shapes = element table:shapes { shape+ } +table-sort = element table:sort { table-sort-attlist, table-sort-by+ } +table-sort-attlist = + attribute table:bind-styles-to-content { boolean }? + & attribute table:target-range-address { cellRangeAddress }? + & attribute table:case-sensitive { boolean }? + & attribute table:language { languageCode }? + & attribute table:country { countryCode }? + & attribute table:script { scriptCode }? + & attribute table:rfc-language-tag { language }? + & attribute table:algorithm { \string }? + & attribute table:embedded-number-behavior { + "alpha-numeric" | "integer" | "double" }? - & attribute fo:clip { "auto" | clipShape }? - & attribute draw:wrap-influence-on-position { - "iterative" | "once-concurrent" | "once-successive" +table-sort-by = element table:sort-by { table-sort-by-attlist, empty } +table-sort-by-attlist = + attribute table:field-number { nonNegativeInteger } + & attribute table:data-type { + "text" | "number" | "automatic" | \string }? - & common-writing-mode-attlist - & attribute draw:frame-display-scrollbar { boolean }? - & attribute draw:frame-display-border { boolean }? - & attribute draw:frame-margin-horizontal { nonNegativePixelLength }? - & attribute draw:frame-margin-vertical { nonNegativePixelLength }? - & attribute draw:visible-area-left { nonNegativeLength }? - & attribute draw:visible-area-top { nonNegativeLength }? - & attribute draw:visible-area-width { positiveLength }? - & attribute draw:visible-area-height { positiveLength }? - & attribute draw:draw-aspect { - "content" | "thumbnail" | "icon" | "print-view" + & attribute table:order { "ascending" | "descending" }? +table-sort-groups = + element table:sort-groups { table-sort-groups-attlist, empty } +table-sort-groups-attlist = + attribute table:data-type { + "text" | "number" | "automatic" | \string + }? + & attribute table:order { "ascending" | "descending" }? +table-source-cell-range = + element table:source-cell-range { + table-source-cell-range-attlist, table-filter? + } +table-source-cell-range-attlist = + # OFFICE-3665 + (attribute table:cell-range-address { cellRangeAddress } + | (attribute table:name { \string }, + attribute table:cell-range-address { cellRangeAddress }?)) +table-source-range-address = + element table:source-range-address { + common-table-range-attlist, empty + } +table-source-service = + element table:source-service { table-source-service-attlist, empty } +table-source-service-attlist = + attribute table:name { \string } + & attribute table:source-name { \string } + & attribute table:object-name { \string } + & attribute table:user-name { \string }? + & attribute table:password { \string }? +table-subtotal-field = + element table:subtotal-field { table-subtotal-field-attlist, empty } +table-subtotal-field-attlist = + attribute table:field-number { nonNegativeInteger } + & attribute table:function { + "average" + | "count" + | "countnums" + | "max" + | "min" + | "product" + | "stdev" + | "stdevp" + | "sum" + | "var" + | "varp" + | \string + } +table-subtotal-rule = + element table:subtotal-rule { + table-subtotal-rule-attlist, table-subtotal-field* + } +table-subtotal-rule-attlist = + attribute table:group-by-field-number { nonNegativeInteger } +table-subtotal-rules = + element table:subtotal-rules { + table-subtotal-rules-attlist, + table-sort-groups?, + table-subtotal-rule* + } +table-subtotal-rules-attlist = + attribute table:bind-styles-to-content { boolean }? + & attribute table:case-sensitive { boolean }? + & attribute table:page-breaks-on-group-change { boolean }? +table-table = + element table:table { + table-table-attlist, + table-title?, + table-desc?, + table-table-source?, + office-dde-source?, + table-scenario?, + office-forms?, + table-shapes?, + table-columns-and-groups, + table-rows-and-groups, + table-named-expressions? + } +table-table-attlist = + attribute table:name { \string }? + & attribute table:style-name { styleNameRef }? + & attribute table:template-name { \string }? + & attribute table:use-first-row-styles { boolean }? + & attribute table:use-last-row-styles { boolean }? + & attribute table:use-first-column-styles { boolean }? + & attribute table:use-last-column-styles { boolean }? + & attribute table:use-banding-rows-styles { boolean }? + & attribute table:use-banding-columns-styles { boolean }? + & attribute table:protected { boolean }? + & attribute table:protection-key { \string }? + & attribute table:protection-key-digest-algorithm { anyIRI }? + & attribute table:print { boolean }? + & attribute table:print-ranges { cellRangeAddressList }? + & xml-id? + & attribute table:is-sub-table { boolean }? +table-table-cell = + element table:table-cell { + table-table-cell-attlist, + table-table-cell-attlist-extra, + table-table-cell-content + } +table-table-cell-attlist = + attribute table:number-columns-repeated { positiveInteger }? + & attribute table:style-name { styleNameRef }? + & attribute table:content-validation-name { \string }? + & attribute table:formula { \string }? + & common-value-and-type-attlist? + & attribute table:protect { boolean }? + & attribute table:protected { boolean }? + & xml-id? + & common-in-content-meta-attlist? +table-table-cell-attlist-extra = + attribute table:number-columns-spanned { positiveInteger }? + & attribute table:number-rows-spanned { positiveInteger }? + & attribute table:number-matrix-columns-spanned { positiveInteger }? + & attribute table:number-matrix-rows-spanned { positiveInteger }? +table-table-cell-content = + table-cell-range-source?, + office-annotation?, + table-detective?, + text-content* +table-table-cell-range-source-attlist = + attribute table:name { \string } + & attribute table:last-column-spanned { positiveInteger } + & attribute table:last-row-spanned { positiveInteger } +table-table-column = + element table:table-column { table-table-column-attlist, empty } +table-table-column-attlist = + attribute table:number-columns-repeated { positiveInteger }? + & attribute table:style-name { styleNameRef }? + & attribute table:visibility { table-visibility-value }? + & attribute table:default-cell-style-name { styleNameRef }? + & xml-id? +table-table-column-group = + element table:table-column-group { + table-table-column-group-attlist, table-columns-and-groups + } +table-table-column-group-attlist = attribute table:display { boolean }? +table-table-columns = + element table:table-columns { table-table-column+ } +table-table-header-columns = + element table:table-header-columns { table-table-column+ } +table-table-header-rows = + element table:table-header-rows { + (text-soft-page-break?, table-table-row)+ + } +table-table-row = + element table:table-row { + table-table-row-attlist, + (table-table-cell | table-covered-table-cell)+ + } +table-table-row-attlist = + attribute table:number-rows-repeated { positiveInteger }? + & attribute table:style-name { styleNameRef }? + & attribute table:default-cell-style-name { styleNameRef }? + & attribute table:visibility { table-visibility-value }? + & xml-id? +table-table-row-group = + element table:table-row-group { + table-table-row-group-attlist, table-rows-and-groups + } +table-table-row-group-attlist = attribute table:display { boolean }? +table-table-rows = + element table:table-rows { (text-soft-page-break?, table-table-row)+ } +table-table-source = + element table:table-source { + table-table-source-attlist, table-linked-source-attlist, empty + } +table-table-source-attlist = + attribute table:mode { "copy-all" | "copy-results-only" }? + & attribute table:table-name { \string }? +table-table-template = + element table:table-template { + table-table-template-attlist, + table-first-row?, + table-last-row?, + table-first-column?, + table-last-column?, + table-body, + table-even-rows?, + table-odd-rows?, + table-even-columns?, + table-odd-columns?, + table-background? + } +table-table-template-attlist = + attribute table:name { \string } + & attribute table:first-row-start-column { rowOrCol } + & attribute table:first-row-end-column { rowOrCol } + & attribute table:last-row-start-column { rowOrCol } + & attribute table:last-row-end-column { rowOrCol } +table-target-range-address = + element table:target-range-address { + common-table-range-attlist, empty + } +table-title = element table:title { text } +table-tracked-changes = + element table:tracked-changes { + table-tracked-changes-attlist, + (table-cell-content-change + | table-insertion + | table-deletion + | table-movement)* + } +table-tracked-changes-attlist = + attribute table:track-changes { boolean }? +table-validation-attlist = + attribute table:name { \string } + & attribute table:condition { \string }? + & attribute table:base-cell-address { cellAddress }? + & attribute table:allow-empty-cell { boolean }? + & attribute table:display-list { + "none" | "unsorted" | "sort-ascending" }? - & attribute draw:ole-draw-aspect { nonNegativeInteger }? -style-graphic-fill-properties-attlist = - attribute draw:fill { - "none" | "solid" | "bitmap" | "gradient" | "hatch" +table-visibility-value = "visible" | "collapse" | "filter" +target-frame = attribute office:target-frame { targetFrameName }? +target-location = attribute xlink:href { anyIRI }? +targetFrameName = "_self" | "_blank" | "_parent" | "_top" | \string +text-a = + element text:a { + text-a-attlist, office-event-listeners?, paragraph-content* + } +text-a-attlist = + attribute office:name { \string }? + & attribute office:title { \string }? + & attribute xlink:type { "simple" } + & attribute xlink:href { anyIRI } + & attribute xlink:actuate { "onRequest" }? + & attribute office:target-frame-name { targetFrameName }? + & attribute xlink:show { "new" | "replace" }? + & attribute text:style-name { styleNameRef }? + & attribute text:visited-style-name { styleNameRef }? +text-alphabetical-index = + element text:alphabetical-index { + common-section-attlist, + text-alphabetical-index-source, + text-index-body + } +text-alphabetical-index-auto-mark-file = + element text:alphabetical-index-auto-mark-file { + attribute xlink:type { "simple" }, + attribute xlink:href { anyIRI } + } +text-alphabetical-index-entry-template = + element text:alphabetical-index-entry-template { + text-alphabetical-index-entry-template-attrs, + (text-index-entry-chapter + | text-index-entry-page-number + | text-index-entry-text + | text-index-entry-span + | text-index-entry-tab-stop)* + } +text-alphabetical-index-entry-template-attrs = + attribute text:outline-level { "1" | "2" | "3" | "separator" } + & attribute text:style-name { styleNameRef } +text-alphabetical-index-mark-attrs = + attribute text:key1 { \string }? + & attribute text:key2 { \string }? + & attribute text:string-value-phonetic { \string }? + & attribute text:key1-phonetic { \string }? + & attribute text:key2-phonetic { \string }? + & attribute text:main-entry { boolean }? +text-alphabetical-index-source = + element text:alphabetical-index-source { + text-alphabetical-index-source-attrs, + text-index-title-template?, + text-alphabetical-index-entry-template* + } +text-alphabetical-index-source-attrs = + text-index-scope-attr + & text-relative-tab-stop-position-attr + & attribute text:ignore-case { boolean }? + & attribute text:main-entry-style-name { styleNameRef }? + & attribute text:alphabetical-separators { boolean }? + & attribute text:combine-entries { boolean }? + & attribute text:combine-entries-with-dash { boolean }? + & attribute text:combine-entries-with-pp { boolean }? + & attribute text:use-keys-as-entries { boolean }? + & attribute text:capitalize-entries { boolean }? + & attribute text:comma-separated { boolean }? + & attribute fo:language { languageCode }? + & attribute fo:country { countryCode }? + & attribute fo:script { scriptCode }? + & attribute style:rfc-language-tag { language }? + & attribute text:sort-algorithm { \string }? +text-bibliography = + element text:bibliography { + common-section-attlist, text-bibliography-source, text-index-body + } +text-bibliography-configuration = + element text:bibliography-configuration { + text-bibliography-configuration-attlist, text-sort-key* + } +text-bibliography-configuration-attlist = + attribute text:prefix { \string }? + & attribute text:suffix { \string }? + & attribute text:numbered-entries { boolean }? + & attribute text:sort-by-position { boolean }? + & attribute fo:language { languageCode }? + & attribute fo:country { countryCode }? + & attribute fo:script { scriptCode }? + & attribute style:rfc-language-tag { language }? + & attribute text:sort-algorithm { \string }? +text-bibliography-entry-template = + element text:bibliography-entry-template { + text-bibliography-entry-template-attrs, + (text-index-entry-span + | text-index-entry-tab-stop + | text-index-entry-bibliography)* + } +text-bibliography-entry-template-attrs = + attribute text:bibliography-type { text-bibliography-types } + & attribute text:style-name { styleNameRef } +text-bibliography-source = + element text:bibliography-source { + text-index-title-template?, text-bibliography-entry-template* + } +text-bibliography-types = + "article" + | "book" + | "booklet" + | "conference" + | "custom1" + | "custom2" + | "custom3" + | "custom4" + | "custom5" + | "email" + | "inbook" + | "incollection" + | "inproceedings" + | "journal" + | "manual" + | "mastersthesis" + | "misc" + | "phdthesis" + | "proceedings" + | "techreport" + | "unpublished" + | "www" +text-bookmark = element text:bookmark { text-bookmark-attlist, empty } +text-bookmark-attlist = + attribute text:name { \string } + & xml-id? +text-bookmark-end = + element text:bookmark-end { text-bookmark-end-attlist, empty } +text-bookmark-end-attlist = attribute text:name { \string } +text-bookmark-ref-content = + attribute text:reference-format { + common-ref-format-values + | "number-no-superior" + | "number-all-superior" + | "number" }? - & attribute draw:fill-color { color }? - & attribute draw:secondary-fill-color { color }? - & attribute draw:fill-gradient-name { styleNameRef }? - & attribute draw:gradient-step-count { nonNegativeInteger }? - & attribute draw:fill-hatch-name { styleNameRef }? - & attribute draw:fill-hatch-solid { boolean }? - & attribute draw:fill-image-name { styleNameRef }? - & attribute style:repeat { "no-repeat" | "repeat" | "stretch" }? - & attribute draw:fill-image-width { length | percent }? - & attribute draw:fill-image-height { length | percent }? - & attribute draw:fill-image-ref-point-x { percent }? - & attribute draw:fill-image-ref-point-y { percent }? - & attribute draw:fill-image-ref-point { - "top-left" - | "top" - | "top-right" - | "left" - | "center" - | "right" - | "bottom-left" - | "bottom" - | "bottom-right" - }? - & attribute draw:tile-repeat-offset { - list { zeroToHundredPercent, ("horizontal" | "vertical") } +text-bookmark-start = + element text:bookmark-start { text-bookmark-start-attlist, empty } +text-bookmark-start-attlist = + attribute text:name { \string } + & xml-id? + & common-in-content-meta-attlist? +text-changed-region = + element text:changed-region { + text-changed-region-attr, text-changed-region-content + } +text-changed-region-attr = + xml-id, + attribute text:id { NCName }? +text-changed-region-content = + element text:insertion { office-change-info } + | element text:deletion { office-change-info, text-content* } + | element text:format-change { office-change-info } +text-chapter-attlist = + attribute text:display { + "name" + | "number" + | "number-and-name" + | "plain-number-and-name" + | "plain-number" + } + & attribute text:outline-level { nonNegativeInteger } +text-common-ref-content = + text + & attribute text:ref-name { \string }? +text-conditional-text-attlist = + attribute text:condition { \string } + & attribute text:string-value-if-true { \string } + & attribute text:string-value-if-false { \string } + & attribute text:current-value { boolean }? +text-content = + text-h + | text-p + | text-list + | text-numbered-paragraph + | table-table + | text-section + | text-soft-page-break + | text-table-of-content + | text-illustration-index + | text-table-index + | text-object-index + | text-user-index + | text-alphabetical-index + | text-bibliography + | shape + | change-marks +text-database-display-attlist = + common-field-database-table + & common-field-data-style-name-attlist + & attribute text:column-name { \string } +text-database-next-attlist = + common-field-database-table + & attribute text:condition { \string }? +text-database-row-select-attlist = + common-field-database-table + & attribute text:condition { \string }? + & attribute text:row-number { nonNegativeInteger }? +text-date-attlist = + (common-field-fixed-attlist & common-field-data-style-name-attlist) + & attribute text:date-value { dateOrDateTime }? + & attribute text:date-adjust { duration }? +text-dde-connection-decl = + element text:dde-connection-decl { + text-dde-connection-decl-attlist, common-dde-connection-decl-attlist + } +text-dde-connection-decl-attlist = attribute office:name { \string } +text-decls = + element text:variable-decls { text-variable-decl* }?, + element text:sequence-decls { text-sequence-decl* }?, + element text:user-field-decls { text-user-field-decl* }?, + element text:dde-connection-decls { text-dde-connection-decl* }?, + text-alphabetical-index-auto-mark-file? +text-drop-down = + element text:drop-down { + attribute text:name { \string }, + element text:label { + attribute text:value { \string }?, + attribute text:current-selected { boolean }? + }*, + text + } +text-file-name-attlist = + attribute text:display { + "full" | "path" | "name" | "name-and-extension" + }? + & common-field-fixed-attlist +text-get-page-variable-attlist = common-field-num-format-attlist +text-h = + element text:h { + heading-attrs, + paragraph-attrs, + text-number?, + paragraph-content-or-hyperlink* + } +text-hidden-paragraph-attlist = + attribute text:condition { \string } + & attribute text:is-hidden { boolean }? +text-hidden-text-attlist = + attribute text:condition { \string } + & attribute text:string-value { \string } + & attribute text:is-hidden { boolean }? +text-id = attribute text:id { \string } +text-illustration-index = + element text:illustration-index { + common-section-attlist, + text-illustration-index-source, + text-index-body + } +text-illustration-index-entry-content = + text-illustration-index-entry-template-attrs, + (text-index-entry-chapter + | text-index-entry-page-number + | text-index-entry-text + | text-index-entry-span + | text-index-entry-tab-stop + | text-index-entry-link-start + | text-index-entry-link-end + # https://issues.oasis-open.org/browse/OFFICE-3941 + )* +text-illustration-index-entry-template = + element text:illustration-index-entry-template { + text-illustration-index-entry-content + } +text-illustration-index-entry-template-attrs = + attribute text:style-name { styleNameRef } +text-illustration-index-source = + element text:illustration-index-source { + text-illustration-index-source-attrs, + text-index-title-template?, + text-illustration-index-entry-template? + } +text-illustration-index-source-attrs = + text-index-scope-attr + & text-relative-tab-stop-position-attr + & attribute text:use-caption { boolean }? + & attribute text:caption-sequence-name { \string }? + & attribute text:caption-sequence-format { + "text" | "category-and-value" | "caption" }? - & attribute draw:opacity { zeroToHundredPercent }? - & attribute draw:opacity-name { styleNameRef }? - & attribute svg:fill-rule { "nonzero" | "evenodd" }? -style-graphic-properties-elements = - text-list-style? & style-background-image & style-columns -common-vertical-pos-attlist = - attribute style:vertical-pos { - "top" | "middle" | "bottom" | "from-top" | "below" - }?, - attribute svg:y { coordinate }? -common-vertical-rel-attlist = - attribute style:vertical-rel { - "page" - | "page-content" - | "frame" - | "frame-content" - | "paragraph" - | "paragraph-content" - | "char" - | "line" - | "baseline" - | "text" +text-index-body = element text:index-body { index-content-main* } +text-index-entry-bibliography = + element text:index-entry-bibliography { + text-index-entry-bibliography-attrs + } +text-index-entry-bibliography-attrs = + attribute text:style-name { styleNameRef }? + & attribute text:bibliography-data-field { + "address" + | "annote" + | "author" + | "bibliography-type" + | "booktitle" + | "chapter" + | "custom1" + | "custom2" + | "custom3" + | "custom4" + | "custom5" + | "edition" + | "editor" + | "howpublished" + | "identifier" + | "institution" + | "isbn" + | "issn" + | "journal" + | "month" + | "note" + | "number" + | "organizations" + | "pages" + | "publisher" + | "report-type" + | "school" + | "series" + | "title" + | "url" + | "volume" + | "year" + } +text-index-entry-chapter = + element text:index-entry-chapter { + attribute text:style-name { styleNameRef }?, + text-index-entry-chapter-attrs + } +text-index-entry-chapter-attrs = + attribute text:display { + "name" + | "number" + | "number-and-name" + | "plain-number" + | "plain-number-and-name" }? -common-editable-attlist = attribute style:editable { boolean }? -horizontal-mirror = - "horizontal" | "horizontal-on-odd" | "horizontal-on-even" -clipShape = - xsd:string { - pattern = - "rect\([ ]*((-?([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc)))|(auto))([ ]*,[ ]*((-?([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc))))|(auto)){3}[ ]*\)" + & attribute text:outline-level { positiveInteger }? +text-index-entry-link-end = + element text:index-entry-link-end { + attribute text:style-name { styleNameRef }? } -nonNegativePixelLength = - xsd:string { pattern = "([0-9]+(\.[0-9]*)?|\.[0-9]+)(px)" } -style-chart-properties = - element style:chart-properties { - style-chart-properties-content-strict +text-index-entry-link-start = + element text:index-entry-link-start { + attribute text:style-name { styleNameRef }? } -style-chart-properties-content-strict = - style-chart-properties-attlist, style-chart-properties-elements -style-chart-properties-elements = empty -style-chart-properties-attlist = - attribute chart:scale-text { boolean }? - & attribute chart:three-dimensional { boolean }? - & attribute chart:deep { boolean }? - & attribute chart:right-angled-axes { boolean }? - & (attribute chart:symbol-type { "none" } - | attribute chart:symbol-type { "automatic" } - | (attribute chart:symbol-type { "named-symbol" }, - attribute chart:symbol-name { - "square" - | "diamond" - | "arrow-down" - | "arrow-up" - | "arrow-right" - | "arrow-left" - | "bow-tie" - | "hourglass" - | "circle" - | "star" - | "x" - | "plus" - | "asterisk" - | "horizontal-bar" - | "vertical-bar" - }) - | (attribute chart:symbol-type { "image" }, - element chart:symbol-image { - attribute xlink:href { anyIRI } - }) - | empty) - & attribute chart:symbol-width { nonNegativeLength }? - & attribute chart:symbol-height { nonNegativeLength }? - & attribute chart:sort-by-x-values { boolean }? - & attribute chart:vertical { boolean }? - & attribute chart:connect-bars { boolean }? - & attribute chart:gap-width { integer }? - & attribute chart:overlap { integer }? - & attribute chart:group-bars-per-axis { boolean }? - & attribute chart:japanese-candle-stick { boolean }? - & attribute chart:interpolation { - "none" | "cubic-spline" | "b-spline" - }? - & attribute chart:spline-order { positiveInteger }? - & attribute chart:spline-resolution { positiveInteger }? - & attribute chart:pie-offset { nonNegativeInteger }? - & attribute chart:angle-offset { angle }? - & attribute chart:hole-size { percent }? - & attribute chart:lines { boolean }? - & attribute chart:solid-type { - "cuboid" | "cylinder" | "cone" | "pyramid" - }? - & attribute chart:stacked { boolean }? - & attribute chart:percentage { boolean }? - & attribute chart:treat-empty-cells { - "use-zero" | "leave-gap" | "ignore" - }? - & attribute chart:link-data-style-to-source { boolean }? - & attribute chart:logarithmic { boolean }? - & attribute chart:maximum { double }? - & attribute chart:minimum { double }? - & attribute chart:origin { double }? - & attribute chart:interval-major { double }? - & attribute chart:interval-minor-divisor { positiveInteger }? - & attribute chart:tick-marks-major-inner { boolean }? - & attribute chart:tick-marks-major-outer { boolean }? - & attribute chart:tick-marks-minor-inner { boolean }? - & attribute chart:tick-marks-minor-outer { boolean }? - & attribute chart:reverse-direction { boolean }? - & attribute chart:display-label { boolean }? - & attribute chart:text-overlap { boolean }? - & attribute text:line-break { boolean }? - & attribute chart:label-arrangement { - "side-by-side" | "stagger-even" | "stagger-odd" - }? - & common-style-direction-attlist - & common-rotation-angle-attlist - & attribute chart:data-label-number { - "none" | "value" | "percentage" | "value-and-percentage" - }? - & attribute chart:data-label-text { boolean }? - & attribute chart:data-label-symbol { boolean }? - & element chart:label-separator { text-p }? - & attribute chart:label-position { labelPositions }? - & attribute chart:label-position-negative { labelPositions }? - & attribute chart:visible { boolean }? - & attribute chart:auto-position { boolean }? - & attribute chart:auto-size { boolean }? - & attribute chart:mean-value { boolean }? - & attribute chart:error-category { - "none" - | "variance" - | "standard-deviation" - | "percentage" - | "error-margin" - | "constant" - | "standard-error" - | "cell-range" - }? - & attribute chart:error-percentage { double }? - & attribute chart:error-margin { double }? - & attribute chart:error-lower-limit { double }? - & attribute chart:error-upper-limit { double }? - & attribute chart:error-upper-indicator { boolean }? - & attribute chart:error-lower-indicator { boolean }? - & attribute chart:error-lower-range { cellRangeAddressList }? - & attribute chart:error-upper-range { cellRangeAddressList }? - & attribute chart:series-source { "columns" | "rows" }? - & attribute chart:regression-type { - "none" | "linear" | "logarithmic" | "exponential" | "power" - }? - & attribute chart:axis-position { "start" | "end" | double }? - & attribute chart:axis-label-position { - "near-axis" - | "near-axis-other-side" - | "outside-start" - | "outside-end" +text-index-entry-page-number = + element text:index-entry-page-number { + attribute text:style-name { styleNameRef }? + } +text-index-entry-span = + element text:index-entry-span { + attribute text:style-name { styleNameRef }?, + text + } +text-index-entry-tab-stop = + element text:index-entry-tab-stop { + attribute text:style-name { styleNameRef }?, + text-index-entry-tab-stop-attrs + } +text-index-entry-tab-stop-attrs = + attribute style:leader-char { character }? + & (attribute style:type { "right" } + | (attribute style:type { "left" }, + attribute style:position { length })) +text-index-entry-text = + element text:index-entry-text { + attribute text:style-name { styleNameRef }? + } +text-index-name = attribute text:index-name { \string } +text-index-scope-attr = + attribute text:index-scope { "document" | "chapter" }? +text-index-source-style = + element text:index-source-style { + attribute text:style-name { styleNameRef }, + empty + } +# https://issues.oasis-open.org/browse/OFFICE-3675 +text-index-source-styles = + element text:index-source-styles { + attribute text:outline-level { positiveInteger }, + text-index-source-style* + } +text-index-title = + element text:index-title { + common-section-attlist, index-content-main* + } +text-index-title-template = + element text:index-title-template { + attribute text:style-name { styleNameRef }?, + text + } +text-linenumbering-configuration = + element text:linenumbering-configuration { + text-linenumbering-configuration-attlist, + text-linenumbering-separator? + } +text-linenumbering-configuration-attlist = + attribute text:number-lines { boolean }? + & common-num-format-attlist? + & attribute text:style-name { styleNameRef }? + & attribute text:increment { nonNegativeInteger }? + & attribute text:number-position { + "left" | "right" | "inner" | "outer" }? - & attribute chart:tick-mark-position { - "at-labels" | "at-axis" | "at-labels-and-axis" + & attribute text:offset { nonNegativeLength }? + & attribute text:count-empty-lines { boolean }? + & attribute text:count-in-text-boxes { boolean }? + & attribute text:restart-on-page { boolean }? +text-linenumbering-separator = + element text:linenumbering-separator { + attribute text:increment { nonNegativeInteger }?, + text + } +text-list = + element text:list { + text-list-attr, text-list-header?, text-list-item* + } +text-list-attr = + attribute text:style-name { styleNameRef }? + & attribute text:continue-numbering { boolean }? + & attribute text:continue-list { IDREF }? + & xml-id? +text-list-header = + element text:list-header { + text-list-header-attr, text-list-item-content + } +text-list-header-attr = xml-id? +text-list-item = + element text:list-item { text-list-item-attr, text-list-item-content } +text-list-item-attr = + attribute text:start-value { nonNegativeInteger }? + & attribute text:style-override { styleNameRef }? + & xml-id? +text-list-item-content = + text-number?, (text-p | text-h | text-list | text-soft-page-break)* +text-list-level-style-attr = attribute text:level { positiveInteger } +text-list-level-style-bullet-attr = + attribute text:style-name { styleNameRef }? + & attribute text:bullet-char { character } + & common-num-format-prefix-suffix-attlist + & attribute text:bullet-relative-size { percent }? +text-list-level-style-image-attr = + common-draw-data-attlist | office-binary-data +text-list-level-style-number-attr = + attribute text:style-name { styleNameRef }? + & common-num-format-attlist + & common-num-format-prefix-suffix-attlist + & attribute text:display-levels { positiveInteger }? + & attribute text:start-value { positiveInteger }? +text-list-style = + element text:list-style { + text-list-style-attr, text-list-style-content* + } +text-list-style-attr = + attribute style:name { styleName } + & attribute style:display-name { \string }? + & attribute text:consecutive-numbering { boolean }? +text-list-style-content = + element text:list-level-style-number { + text-list-level-style-attr, + text-list-level-style-number-attr, + style-list-level-properties?, + style-text-properties? + } + | element text:list-level-style-bullet { + text-list-level-style-attr, + text-list-level-style-bullet-attr, + style-list-level-properties?, + style-text-properties? + } + | element text:list-level-style-image { + text-list-level-style-attr, + text-list-level-style-image-attr, + style-list-level-properties? + } +text-meta-attlist = common-in-content-meta-attlist? & xml-id? +text-meta-field-attlist = xml-id & common-field-data-style-name-attlist +text-note-class = attribute text:note-class { "footnote" | "endnote" } +text-note-ref-content = + attribute text:reference-format { common-ref-format-values }? + & text-note-class +text-notes-configuration = + element text:notes-configuration { text-notes-configuration-content } +text-notes-configuration-content = + text-note-class + & attribute text:citation-style-name { styleNameRef }? + & attribute text:citation-body-style-name { styleNameRef }? + & attribute text:default-style-name { styleNameRef }? + & attribute text:master-page-name { styleNameRef }? + & attribute text:start-value { nonNegativeInteger }? + & common-num-format-prefix-suffix-attlist + & common-num-format-attlist? + & attribute text:start-numbering-at { + "document" | "chapter" | "page" }? - & attribute chart:include-hidden-cells { boolean }? -labelPositions = - "avoid-overlap" - | "center" - | "top" - | "top-right" - | "right" - | "bottom-right" - | "bottom" - | "bottom-left" - | "left" - | "top-left" - | "inside" - | "outside" - | "near-origin" -style-drawing-page-properties-attlist = - attribute presentation:transition-type { - "manual" | "automatic" | "semi-automatic" - }? - & attribute presentation:transition-style { - "none" - | "fade-from-left" - | "fade-from-top" - | "fade-from-right" - | "fade-from-bottom" - | "fade-from-upperleft" - | "fade-from-upperright" - | "fade-from-lowerleft" - | "fade-from-lowerright" - | "move-from-left" - | "move-from-top" - | "move-from-right" - | "move-from-bottom" - | "move-from-upperleft" - | "move-from-upperright" - | "move-from-lowerleft" - | "move-from-lowerright" - | "uncover-to-left" - | "uncover-to-top" - | "uncover-to-right" - | "uncover-to-bottom" - | "uncover-to-upperleft" - | "uncover-to-upperright" - | "uncover-to-lowerleft" - | "uncover-to-lowerright" - | "fade-to-center" - | "fade-from-center" - | "vertical-stripes" - | "horizontal-stripes" - | "clockwise" - | "counterclockwise" - | "open-vertical" - | "open-horizontal" - | "close-vertical" - | "close-horizontal" - | "wavyline-from-left" - | "wavyline-from-top" - | "wavyline-from-right" - | "wavyline-from-bottom" - | "spiralin-left" - | "spiralin-right" - | "spiralout-left" - | "spiralout-right" - | "roll-from-top" - | "roll-from-left" - | "roll-from-right" - | "roll-from-bottom" - | "stretch-from-left" - | "stretch-from-top" - | "stretch-from-right" - | "stretch-from-bottom" - | "vertical-lines" - | "horizontal-lines" - | "dissolve" - | "random" - | "vertical-checkerboard" - | "horizontal-checkerboard" - | "interlocking-horizontal-left" - | "interlocking-horizontal-right" - | "interlocking-vertical-top" - | "interlocking-vertical-bottom" - | "fly-away" - | "open" - | "close" - | "melt" + & attribute text:footnotes-position { + "text" | "page" | "section" | "document" }? - & attribute presentation:transition-speed { presentationSpeeds }? - & attribute smil:type { \string }? - & attribute smil:subtype { \string }? - & attribute smil:direction { "forward" | "reverse" }? - & attribute smil:fadeColor { color }? - & attribute presentation:duration { duration }? - & attribute presentation:visibility { "visible" | "hidden" }? - & attribute draw:background-size { "full" | "border" }? - & attribute presentation:background-objects-visible { boolean }? - & attribute presentation:background-visible { boolean }? - & attribute presentation:display-header { boolean }? - & attribute presentation:display-footer { boolean }? - & attribute presentation:display-page-number { boolean }? - & attribute presentation:display-date-time { boolean }? -style-drawing-page-properties-elements = presentation-sound? -\string = xsd:string -date = xsd:date -time = xsd:time -dateTime = xsd:dateTime -duration = xsd:duration -integer = xsd:integer -nonNegativeInteger = xsd:nonNegativeInteger -positiveInteger = xsd:positiveInteger -double = xsd:double -anyURI = xsd:anyURI -base64Binary = xsd:base64Binary -ID = xsd:ID -IDREF = xsd:IDREF -IDREFS = xsd:IDREFS -NCName = xsd:NCName -boolean = "true" | "false" -dateOrDateTime = xsd:date | xsd:dateTime -timeOrDateTime = xsd:time | xsd:dateTime -language = xsd:language -countryCode = xsd:token { pattern = "[A-Za-z0-9]{1,8}" } -languageCode = xsd:token { pattern = "[A-Za-z]{1,8}" } -scriptCode = xsd:token { pattern = "[A-Za-z0-9]{1,8}" } -character = xsd:string { length = "1" } -length = - xsd:string { - pattern = - "-?([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc)|(px))" + & element text:note-continuation-notice-forward { text }? + & element text:note-continuation-notice-backward { text }? +text-number = element text:number { \string } +text-numbered-paragraph = + element text:numbered-paragraph { + text-numbered-paragraph-attr, text-number?, (text-p | text-h) + } +text-numbered-paragraph-attr = + attribute text:list-id { NCName } + & attribute text:level { positiveInteger }? + & (attribute text:style-name { styleNameRef }, + attribute text:continue-numbering { boolean }, + attribute text:start-value { nonNegativeInteger })? + & xml-id? +text-object-index = + element text:object-index { + common-section-attlist, text-object-index-source, text-index-body + } +text-object-index-entry-template = + element text:object-index-entry-template { + text-illustration-index-entry-content + } +text-object-index-source = + element text:object-index-source { + text-object-index-source-attrs, + text-index-title-template?, + text-object-index-entry-template? + } +text-object-index-source-attrs = + text-index-scope-attr + & text-relative-tab-stop-position-attr + & attribute text:use-spreadsheet-objects { boolean }? + & attribute text:use-math-objects { boolean }? + & attribute text:use-draw-objects { boolean }? + & attribute text:use-chart-objects { boolean }? + & attribute text:use-other-objects { boolean }? +text-outline-level = attribute text:outline-level { positiveInteger }? +text-outline-level-style = + element text:outline-level-style { + text-outline-level-style-attlist, + style-list-level-properties?, + style-text-properties? + } +text-outline-level-style-attlist = + attribute text:level { positiveInteger } + & attribute text:style-name { styleNameRef }? + & common-num-format-attlist + & common-num-format-prefix-suffix-attlist + & attribute text:display-levels { positiveInteger }? + & attribute text:start-value { positiveInteger }? +text-outline-style = + element text:outline-style { + text-outline-style-attr, text-outline-level-style+ + } +text-outline-style-attr = attribute style:name { styleName } +text-p = + element text:p { paragraph-attrs, paragraph-content-or-hyperlink* } +text-page = element text:page { text-page-attlist, empty } +text-page-attlist = attribute text:master-page-name { styleNameRef } +text-page-continuation-attlist = + attribute text:select-page { "previous" | "next" } + & attribute text:string-value { \string }? +text-page-number-attlist = + (common-field-num-format-attlist & common-field-fixed-attlist) + & attribute text:page-adjust { integer }? + & attribute text:select-page { "previous" | "current" | "next" }? +text-page-sequence = element text:page-sequence { text-page+ } +text-placeholder-attlist = + attribute text:placeholder-type { + "text" | "table" | "text-box" | "image" | "object" } -nonNegativeLength = - xsd:string { - pattern = - "([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc)|(px))" + & common-field-description-attlist +text-relative-tab-stop-position-attr = + attribute text:relative-tab-stop-position { boolean }? +text-section = + element text:section { + text-section-attlist, + (text-section-source | text-section-source-dde | empty), + text-content* } -positiveLength = - xsd:string { - pattern = - "([0-9]*[1-9][0-9]*(\.[0-9]*)?|0+\.[0-9]*[1-9][0-9]*|\.[0-9]*[1-9][0-9]*)((cm)|(mm)|(in)|(pt)|(pc)|(px))" +text-section-attlist = + common-section-attlist + & (attribute text:display { "true" | "none" } + | (attribute text:display { "condition" }, + attribute text:condition { \string }) + | empty) +text-section-source = + element text:section-source { text-section-source-attr } +text-section-source-attr = + (attribute xlink:type { "simple" }, + attribute xlink:href { anyIRI }, + attribute xlink:show { "embed" }?)? + & attribute text:section-name { \string }? + & attribute text:filter-name { \string }? +text-section-source-dde = office-dde-source +text-sequence-decl = + element text:sequence-decl { text-sequence-decl-attlist } +text-sequence-decl-attlist = + common-field-name-attlist + & attribute text:display-outline-level { nonNegativeInteger } + & attribute text:separation-character { character }? +text-sequence-ref-content = + attribute text:reference-format { + common-ref-format-values + | "category-and-value" + | "caption" + | "value" + }? +text-sequence-ref-name = attribute text:ref-name { \string }? +text-set-page-variable-attlist = + attribute text:active { boolean }? + & attribute text:page-adjust { integer }? +text-soft-page-break = element text:soft-page-break { empty } +text-sort-key = element text:sort-key { text-sort-key-attlist, empty } +text-sort-key-attlist = + attribute text:key { + "address" + | "annote" + | "author" + | "bibliography-type" + | "booktitle" + | "chapter" + | "custom1" + | "custom2" + | "custom3" + | "custom4" + | "custom5" + | "edition" + | "editor" + | "howpublished" + | "identifier" + | "institution" + | "isbn" + | "issn" + | "journal" + | "month" + | "note" + | "number" + | "organizations" + | "pages" + | "publisher" + | "report-type" + | "school" + | "series" + | "title" + | "url" + | "volume" + | "year" + }, + attribute text:sort-ascending { boolean }? +text-style-name = attribute form:text-style-name { styleNameRef }? +text-tab-attr = attribute text:tab-ref { nonNegativeInteger }? +text-table-index = + element text:table-index { + common-section-attlist, text-table-index-source, text-index-body } -percent = xsd:string { pattern = "-?([0-9]+(\.[0-9]*)?|\.[0-9]+)%" } -zeroToHundredPercent = - xsd:string { - pattern = "([0-9]?[0-9](\.[0-9]*)?|100(\.0*)?|\.[0-9]+)%" +text-table-index-entry-template = + element text:table-index-entry-template { + text-illustration-index-entry-content } -signedZeroToHundredPercent = - xsd:string { - pattern = "-?([0-9]?[0-9](\.[0-9]*)?|100(\.0*)?|\.[0-9]+)%" +text-table-index-source = + element text:table-index-source { + text-illustration-index-source-attrs, + text-index-title-template?, + text-table-index-entry-template? } -relativeLength = xsd:string { pattern = "[0-9]+\*" } -coordinate = length -distance = length -color = xsd:string { pattern = "#[0-9a-fA-F]{6}" } -angle = xsd:string -CURIE = - xsd:string { pattern = "(([\i-[:]][\c-[:]]*)?:)?.+" minLength = "1" } -CURIEs = list { CURIE+ } -SafeCURIE = - xsd:string { - pattern = "\[(([\i-[:]][\c-[:]]*)?:)?.+\]" - minLength = "3" +text-table-of-content = + element text:table-of-content { + common-section-attlist, + text-table-of-content-source, + text-index-body } -URIorSafeCURIE = anyURI | SafeCURIE -styleName = xsd:NCName -styleNameRef = xsd:NCName | empty -styleNameRefs = list { xsd:NCName* } -variableName = xsd:string -targetFrameName = "_self" | "_blank" | "_parent" | "_top" | \string +text-table-of-content-children = + text-index-entry-chapter + | text-index-entry-page-number + | text-index-entry-text + | text-index-entry-span + | text-index-entry-tab-stop + | text-index-entry-link-start + | text-index-entry-link-end +text-table-of-content-entry-template = + element text:table-of-content-entry-template { + text-table-of-content-entry-template-attlist, + text-table-of-content-children* + } +text-table-of-content-entry-template-attlist = + attribute text:outline-level { positiveInteger } + & attribute text:style-name { styleNameRef } +text-table-of-content-source = + element text:table-of-content-source { + text-table-of-content-source-attlist, + text-index-title-template?, + text-table-of-content-entry-template*, + text-index-source-styles* + } +text-table-of-content-source-attlist = + attribute text:outline-level { positiveInteger }? + & attribute text:use-outline-level { boolean }? + & attribute text:use-index-marks { boolean }? + & attribute text:use-index-source-styles { boolean }? + & attribute text:index-scope { "document" | "chapter" }? + & attribute text:relative-tab-stop-position { boolean }? +text-template-name-attlist = + attribute text:display { + "full" | "path" | "name" | "name-and-extension" | "area" | "title" + }? +text-time-attlist = + (common-field-fixed-attlist & common-field-data-style-name-attlist) + & attribute text:time-value { timeOrDateTime }? + & attribute text:time-adjust { duration }? +text-toc-mark-start-attrs = text-id, text-outline-level +text-tracked-changes = + element text:tracked-changes { + text-tracked-changes-attr, text-changed-region* + }? +text-tracked-changes-attr = attribute text:track-changes { boolean }? +text-user-field-decl = + element text:user-field-decl { + common-field-name-attlist, + common-field-formula-attlist?, + common-value-and-type-attlist + } +text-user-index = + element text:user-index { + common-section-attlist, text-user-index-source, text-index-body + } +text-user-index-entry-template = + element text:user-index-entry-template { + text-user-index-entry-template-attrs, + (text-index-entry-chapter + | text-index-entry-page-number + | text-index-entry-text + | text-index-entry-span + | text-index-entry-tab-stop + | text-index-entry-link-start + | text-index-entry-link-end + # https://issues.oasis-open.org/browse/OFFICE-3941 + )* + } +text-user-index-entry-template-attrs = + attribute text:outline-level { positiveInteger } + & attribute text:style-name { styleNameRef } +text-user-index-source = + element text:user-index-source { + text-user-index-source-attr, + text-index-title-template?, + text-user-index-entry-template*, + text-index-source-styles* + } +text-user-index-source-attr = + text-index-scope-attr + & text-relative-tab-stop-position-attr + & attribute text:use-index-marks { boolean }? + & attribute text:use-index-source-styles { boolean }? + & attribute text:use-graphics { boolean }? + & attribute text:use-tables { boolean }? + & attribute text:use-floating-frames { boolean }? + & attribute text:use-objects { boolean }? + & attribute text:copy-outline-levels { boolean }? + & attribute text:index-name { \string } +text-variable-decl = + element text:variable-decl { + common-field-name-attlist, common-value-type-attlist + } +textEncoding = xsd:string { pattern = "[A-Za-z][A-Za-z0-9._\-]*" } +time = xsd:time +timeOrDateTime = xsd:time | xsd:dateTime +types = "submit" | "reset" | "push" | "url" valueType = "float" | "time" @@ -6257,24 +6397,18 @@ valueType = | "currency" | "boolean" | "string" -points = - xsd:string { pattern = "-?[0-9]+,-?[0-9]+([ ]+-?[0-9]+,-?[0-9]+)*" } -pathData = xsd:string +variableName = xsd:string vector3D = xsd:string { pattern = "\([ ]*-?([0-9]+(\.[0-9]*)?|\.[0-9]+)([ ]+-?([0-9]+(\.[0-9]*)?|\.[0-9]+)){2}[ ]*\)" } -namespacedToken = xsd:QName { pattern = "[^:]+:[^:]+" } -anyIRI = - xsd:anyURI - >> dc:description [ - "An IRI-reference as defined in [RFC3987]. See ODF 1.2 Part 1 section 18.3." - ] -anyAttListOrElements = - attribute * { text }*, - anyElements -anyElements = - element * { - mixed { anyAttListOrElements } - }* +vertBackPos = "top" | "center" | "bottom" +xforms-bind-attlist = attribute xforms:bind { \string }? +xforms-model = element xforms:model { anyAttListOrElements } +xml-id = attribute xml:id { ID } +zeroToHundredPercent = + xsd:string { + pattern = "([0-9]?[0-9](\.[0-9]*)?|100(\.0*)?|\.[0-9]+)%" + } +zeroToOneDecimal = xsd:decimal { minInclusive = "0" maxInclusive = "1" } diff --git a/etc/schema/schemas.xml b/etc/schema/schemas.xml index 7fd91b8c72..f8acb0d40c 100644 --- a/etc/schema/schemas.xml +++ b/etc/schema/schemas.xml @@ -31,6 +31,10 @@ + + + + @@ -59,7 +63,7 @@ - + commit c3980a3ea67de9f9f997b13ce47fd1e6aca361e4 Merge: 8ab85f560e 291a421c2e Author: Paul Eggert Date: Thu Mar 25 08:26:35 2021 -0700 Merge from origin/emacs-27 291a421c2e * admin/make-tarball.txt: Improve and expand the instructi... 0e4795fc98 Fix preeditarea reporting wrong spot. commit 8ab85f560eb78e77f743309ee7e331444dd7c5a2 Merge: b702225619 6a4ed891d8 Author: Paul Eggert Date: Thu Mar 25 08:26:35 2021 -0700 ; Merge from origin/emacs-27 The following commits were skipped: 6a4ed891d8 Fix replace-buffer-contents undefined behavior 720a8b17f8 Fix filenotify-tests.el for Solaris (bug#47262), do not merge commit b702225619afebb3d5becb95d142a60a9f62f60e Merge: 52a7460416 deef5efafb Author: Paul Eggert Date: Thu Mar 25 08:26:34 2021 -0700 Merge from origin/emacs-27 deef5efafb ; * ChangeLog.3: Update with the log of the last change. bd991e3c9b Fix frame-inner-height in non-GUI builds commit 291a421c2e7420c36a0767f2c1e1d7317022f719 Author: Eli Zaretskii Date: Thu Mar 25 17:24:43 2021 +0200 * admin/make-tarball.txt: Improve and expand the instructions. diff --git a/admin/make-tarball.txt b/admin/make-tarball.txt index bf682ecadf..65c6e86b1d 100644 --- a/admin/make-tarball.txt +++ b/admin/make-tarball.txt @@ -88,6 +88,12 @@ General steps (for each step, check for possible errors): along with etc/HISTORY. Then you can tag that commit as the release. + Alternatively, you can commit and tag with the RC tag right away, + and delay the final tagging until you actually decide to make a + release and announce it. The "git tag" command can tag a specific + commit if you give it the SHA1 of that commit, even if additional + commits have been pushed in the meantime. + Name the tar file as emacs-XX.Y-rc1.tar. If all goes well in the following week, you can simply rename the file and use it for the actual release. If you need another release candidate, remember @@ -101,11 +107,11 @@ General steps (for each step, check for possible errors): Never replace an existing tarfile! If you need to fix something, always upload it with a different name. -4. autoreconf -i -I m4 --force - make bootstrap +4. autoreconf -i -I m4 --force + make bootstrap - make -C etc/refcards - make -C etc/refcards clean + make -C etc/refcards + make -C etc/refcards clean If some of the etc/refcards, especially the non-English ones, fail to build, you probably need to install some TeX/LaTeX packages, in @@ -119,13 +125,18 @@ General steps (for each step, check for possible errors): 5. Copy lisp/loaddefs.el to lisp/ldefs-boot.el. Commit ChangeLog.N, etc/AUTHORS, lisp/ldefs-boot.el, and the - files changed by M-x set-version. + files changed by M-x set-version. The easiest way of doing that + is "C-x v d ROOT-DIR RET", then go to the first modified file, + press 'M' to mark all modified files, and finally 'v' to commit + them. Make sure the commit log message mentions all the changes + in all modified files, as by default 'v' doesn't necessarily do + so. If someone else made a commit between step 1 and now, you need to repeat from step 4 onwards. (You can commit the files from step 2 and 3 earlier to reduce the chance of this.) -6. ./make-dist --snapshot --no-compress +6. ./make-dist --snapshot --no-compress Check the contents of the new tar with admin/diff-tar-files against the previous release (if this is the first pretest) or the @@ -133,6 +144,14 @@ General steps (for each step, check for possible errors): yourself, find it at . Releases are of course at . + ./admin/diff-tar-files emacs-OLD.tar.gz emacs-NEW.tar.gz + + Alternatively: + + tar tJf emacs-OLD.tar.xz | sed -e 's,^[^/]*,,' | sort > old_tmp + tar tJf emacs-NEW.tar.xz | sed -e 's,^[^/]*,,' | sort > new_tmp + diff -u old_tmp new_tmp + If this is the first pretest of a major release, just comparing with the previous release may overlook many new files. You can try something like 'find . | sort' in a clean repository, and compare the @@ -140,6 +159,7 @@ General steps (for each step, check for possible errors): 7. tar -xf emacs-NEW.tar; cd emacs-NEW ./configure --prefix=/tmp/emacs && make check && make install + Use 'script' or M-x compile to save the compilation log in compile-NEW.log and compare it against an old one. The easiest way to do that is to visit the old log in Emacs, change the version @@ -147,8 +167,23 @@ General steps (for each step, check for possible errors): M-x ediff. Especially check that Info files aren't built, and that no autotools (autoconf etc) run. -8. cd EMACS_ROOT_DIR && git tag -a TAG && git push origin tag TAG - TAG is emacs-XX.Y.ZZ for a pretest, emacs-XX.Y for a release. +8. You can now tag the release/pretest and push it together with the + last commit: + + cd EMACS_ROOT_DIR && git tag -a TAG -m "Emacs TAG" + git push + git push --tags + + Here TAG is emacs-XX.Y.ZZ for a pretest, emacs-XX.Y for a release. + For a release, if you are producing a release candidate first, use + emacs-XX.Y-rcN (N = 1, 2, ...) when you tar the RC, and add the + actual release tag later, when the official release tarball is + uploaded to ftp.gnu.org. When adding a tag later, it is safer to + use the SHA1 of the last commit which went into the release + tarball, in case there were some intervening commits since then: + + git tag -a TAG -m "Emacs TAG" SHA1 + git push --tags 9. Decide what compression schemes to offer. For a release, at least gz and xz: commit 0e4795fc989478d394bbc3870ee28baf6bd23116 Author: Amos Bird Date: Thu Mar 25 14:50:46 2021 +0800 Fix preeditarea reporting wrong spot. This patch adjust the x position of preeditarea with both left fringe and left margin, which prevents IME preedit box (such as fcitx) from placing at the wrong position in GUI emacs. * src/xfns.c (xic_set_preeditarea): Adjust X for left margin width. (Bug#47377) diff --git a/src/xfns.c b/src/xfns.c index ab04396703..b9b396382b 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -2785,7 +2785,7 @@ xic_set_preeditarea (struct window *w, int x, int y) XVaNestedList attr; XPoint spot; - spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w); + spot.x = WINDOW_TO_FRAME_PIXEL_X (w, x) + WINDOW_LEFT_FRINGE_WIDTH (w) + WINDOW_LEFT_MARGIN_WIDTH(w); spot.y = WINDOW_TO_FRAME_PIXEL_Y (w, y) + FONT_BASE (FRAME_FONT (f)); attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL); XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL); commit 6a4ed891d84b1ca1e4d68a6de9dd374f1fadd971 Author: Paul Eggert Date: Sun Mar 21 18:08:13 2021 -0700 Fix replace-buffer-contents undefined behavior * src/editfns.c (Freplace_buffer_contents): Avoid undefined behavior with competing side effects in parallel subexpressions. Problem reported by Apple clang version 12.0.0 (clang-1200.0.32.29). diff --git a/src/editfns.c b/src/editfns.c index 621e35171d..cd9633d4c6 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2053,6 +2053,8 @@ nil. */) code. */ ptrdiff_t del_bytes = (size_t) size_a / CHAR_BIT + 1; ptrdiff_t ins_bytes = (size_t) size_b / CHAR_BIT + 1; + unsigned char *deletions = SAFE_ALLOCA (del_bytes); + unsigned char *insertions = SAFE_ALLOCA (ins_bytes); struct context ctx = { .buffer_a = a, .buffer_b = b, @@ -2060,8 +2062,8 @@ nil. */) .beg_b = min_b, .a_unibyte = BUF_ZV (a) == BUF_ZV_BYTE (a), .b_unibyte = BUF_ZV (b) == BUF_ZV_BYTE (b), - .deletions = SAFE_ALLOCA (del_bytes), - .insertions = SAFE_ALLOCA (ins_bytes), + .deletions = deletions, + .insertions = insertions, .fdiag = buffer + size_b + 1, .bdiag = buffer + diags + size_b + 1, .heuristic = true, commit 720a8b17f8f48f2bc7d59dc71be1d5fc35f0964b Author: Michael Albinus Date: Thu Mar 25 15:36:33 2021 +0100 Fix filenotify-tests.el for Solaris (bug#47262), do not merge * test/lisp/filenotify-tests.el (file-notify--test-read-event): Check also for GFamDirectoryMonitor. (file-notify--test-timeout): Increase cygwin timeout. (file-notify--test-monitor): Use `alist-get'. (file-notify--test-event-actions): New defun. (file-notify--test-with-actions-explainer): Use it. (file-notify--test-with-actions-check): Use it. If file-notify-debug is non-nil, trace received events instead of checking them. (file-notify-test03-events, file-notify-test05-file-validity) (file-notify-test07-many-events, file-notify-test08-backup) (file-notify-test09-watched-file-in-watched-dir): Handle GFamFileMonitor and GFamDirectoryMonitor. diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el index a7ceeddb41..3a297f0a96 100644 --- a/test/lisp/filenotify-tests.el +++ b/test/lisp/filenotify-tests.el @@ -105,11 +105,10 @@ There are different timeouts for local and remote file notification libraries." (cond ;; gio/gpollfilemonitor.c declares POLL_TIME_SECS 5. So we must ;; wait at least this time in the GPollFileMonitor case. A - ;; similar timeout seems to be needed in the GFamFileMonitor case, - ;; at least on Cygwin. - ((and (string-equal (file-notify--test-library) "gfilenotify") - (memq (file-notify--test-monitor) - '(GFamFileMonitor GPollFileMonitor))) + ;; similar timeout seems to be needed in the + ;; GFam{File,Directory}Monitor case. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor GPollFileMonitor)) 7) ((string-equal (file-notify--test-library) "gvfs-monitor-dir.exe") 1) ((file-remote-p temporary-file-directory) 0.1) @@ -120,7 +119,7 @@ There are different timeouts for local and remote file notification libraries." (cond ((file-remote-p temporary-file-directory) 6) ((string-equal (file-notify--test-library) "w32notify") 4) - ((eq system-type 'cygwin) 6) + ((eq system-type 'cygwin) 7) (t 3))) (defmacro file-notify--test-wait-for-events (timeout until) @@ -263,12 +262,12 @@ This returns only for the local case and gfilenotify; otherwise it is nil. ;; `gfile-monitor-name' does not return a proper result anymore. ;; But we still need this information. (unless (file-remote-p temporary-file-directory) - (or (cdr (assq file-notify--test-desc file-notify--test-monitors)) + (or (alist-get file-notify--test-desc file-notify--test-monitors) (when (functionp 'gfile-monitor-name) (add-to-list 'file-notify--test-monitors (cons file-notify--test-desc (gfile-monitor-name file-notify--test-desc))) - (cdr (assq file-notify--test-desc file-notify--test-monitors)))))) + (alist-get file-notify--test-desc file-notify--test-monitors))))) (defmacro file-notify--deftest-remote (test docstring &optional unstable) "Define ert `TEST-remote' for remote files. @@ -455,7 +454,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (unwind-protect ;; Check, that removing watch descriptors out of order do not - ;; harm. This fails on Cygwin because of timing issues unless a + ;; harm. This fails on cygwin because of timing issues unless a ;; long `sit-for' is added before the call to ;; `file-notify--test-read-event'. (unless (eq system-type 'cygwin) @@ -542,6 +541,10 @@ and the event to `file-notify--test-events'." file-notify--test-results (append file-notify--test-results `(,result)))))) +(defun file-notify--test-event-actions () + "Helper function to return retrieved actions, as list." + (mapcar #'file-notify--test-event-action file-notify--test-events)) + (defun file-notify--test-with-actions-check (actions) "Check whether received actions match one of the ACTIONS alternatives." (let (result) @@ -550,22 +553,25 @@ and the event to `file-notify--test-events'." (or result (if (eq (car elt) :random) (equal (sort (cdr elt) 'string-lessp) - (sort (mapcar #'file-notify--test-event-action - file-notify--test-events) + (sort (file-notify--test-event-actions) 'string-lessp)) - (equal elt (mapcar #'file-notify--test-event-action - file-notify--test-events)))))))) + (equal elt (file-notify--test-event-actions)))))) + ;; Do not report result in case we debug. Write messages instead. + (if file-notify-debug + (prog1 t + (if result + (message "Success\n%s" (file-notify--test-event-actions)) + (message (file-notify--test-with-actions-explainer actions)))) + result))) (defun file-notify--test-with-actions-explainer (actions) "Explain why `file-notify--test-with-actions-check' fails." (if (null (cdr actions)) (format "Received actions do not match expected actions\n%s\n%s" - (mapcar #'file-notify--test-event-action file-notify--test-events) - (car actions)) + (file-notify--test-event-actions) (car actions)) (format "Received actions do not match any sequence of expected actions\n%s\n%s" - (mapcar #'file-notify--test-event-action file-notify--test-events) - actions))) + (file-notify--test-event-actions) actions))) (put 'file-notify--test-with-actions-check 'ert-explainer 'file-notify--test-with-actions-explainer) @@ -632,9 +638,10 @@ delivered." (file-notify--test-library) "gvfs-monitor-dir.exe") '((deleted stopped) (created deleted stopped))) - ;; cygwin does not raise a `changed' event. - ((eq system-type 'cygwin) - '(created deleted stopped)) + ;; GFam{File,Directory}Monitor do not report the `changed' event. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor)) + '(created deleted stopped)) (t '(created changed deleted stopped))) (write-region "another text" nil file-notify--test-tmpfile nil 'no-message) @@ -665,6 +672,12 @@ delivered." ((string-equal (file-notify--test-library) "gvfs-monitor-dir.exe") '((deleted stopped) (changed deleted stopped))) + ;; GFam{File,Directory}Monitor do not detect the + ;; `changed' event reliably. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor)) + '((deleted stopped) + (changed deleted stopped))) ;; There could be one or two `changed' events. (t '((changed deleted stopped) (changed changed deleted stopped)))) @@ -709,9 +722,11 @@ delivered." ((getenv "EMACS_EMBA_CI") '(created changed deleted)) ;; There are two `deleted' events, for the file and for - ;; the directory. Except for cygwin and kqueue. And - ;; cygwin does not raise a `changed' event. - ((eq system-type 'cygwin) + ;; the directory. Except for GFam{File,Directory}Monitor + ;; and kqueue. And GFam{File,Directory}Monitor do not + ;; raise a `changed' event. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor)) '(created deleted stopped)) ((string-equal (file-notify--test-library) "kqueue") '(created changed deleted stopped)) @@ -755,8 +770,10 @@ delivered." '((deleted stopped) (created created deleted stopped))) ;; There are three `deleted' events, for two files and - ;; for the directory. Except for cygwin and kqueue. - ((eq system-type 'cygwin) + ;; for the directory. Except for + ;; GFam{File,Directory}Monitor and kqueue. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor)) '(created created changed changed deleted stopped)) ((string-equal (file-notify--test-library) "kqueue") '(created changed created changed deleted stopped)) @@ -813,10 +830,12 @@ delivered." ((getenv "EMACS_EMBA_CI") '(created changed renamed deleted)) ;; There are two `deleted' events, for the file and for - ;; the directory. Except for cygwin and kqueue. And - ;; cygwin raises `created' and `deleted' events instead - ;; of a `renamed' event. - ((eq system-type 'cygwin) + ;; the directory. Except for GFam{File,Directory}Monitor + ;; and kqueue. And GFam{File,Directory}Monitor raise + ;; `created' and `deleted' events instead of a `renamed' + ;; event. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor)) '(created created deleted deleted stopped)) ((string-equal (file-notify--test-library) "kqueue") '(created changed renamed deleted stopped)) @@ -837,8 +856,8 @@ delivered." (file-notify--test-cleanup)) (unwind-protect - ;; Check attribute change. Does not work for cygwin. - (unless (eq system-type 'cygwin) + ;; Check attribute change. Does not work for GFam{File,Directory}Monitor. + (progn (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)) (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) @@ -847,29 +866,31 @@ delivered." (file-notify--test-add-watch file-notify--test-tmpfile '(attribute-change) #'file-notify--test-event-handler))) - (file-notify--test-with-actions - (cond - ;; w32notify does not distinguish between `changed' and - ;; `attribute-changed'. Under MS Windows 7, we get four - ;; `changed' events, and under MS Windows 10 just two. - ;; Strange. - ((string-equal (file-notify--test-library) "w32notify") - '((changed changed) - (changed changed changed changed))) - ;; For kqueue and in the remote case, `write-region' - ;; raises also an `attribute-changed' event. - ((or (string-equal (file-notify--test-library) "kqueue") - (file-remote-p temporary-file-directory)) - '(attribute-changed attribute-changed attribute-changed)) - (t '(attribute-changed attribute-changed))) - (write-region - "any text" nil file-notify--test-tmpfile nil 'no-message) - (file-notify--test-read-event) - (set-file-modes file-notify--test-tmpfile 000) - (file-notify--test-read-event) - (set-file-times file-notify--test-tmpfile '(0 0)) - (file-notify--test-read-event) - (delete-file file-notify--test-tmpfile)) + (unless (memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor)) + (file-notify--test-with-actions + (cond + ;; w32notify does not distinguish between `changed' and + ;; `attribute-changed'. Under MS Windows 7, we get + ;; four `changed' events, and under MS Windows 10 just + ;; two. Strange. + ((string-equal (file-notify--test-library) "w32notify") + '((changed changed) + (changed changed changed changed))) + ;; For kqueue and in the remote case, `write-region' + ;; raises also an `attribute-changed' event. + ((or (string-equal (file-notify--test-library) "kqueue") + (file-remote-p temporary-file-directory)) + '(attribute-changed attribute-changed attribute-changed)) + (t '(attribute-changed attribute-changed))) + (write-region + "any text" nil file-notify--test-tmpfile nil 'no-message) + (file-notify--test-read-event) + (set-file-modes file-notify--test-tmpfile 000) + (file-notify--test-read-event) + (set-file-times file-notify--test-tmpfile '(0 0)) + (file-notify--test-read-event) + (delete-file file-notify--test-tmpfile))) (file-notify-rm-watch file-notify--test-desc) ;; The environment shall be cleaned up. @@ -951,7 +972,7 @@ delivered." ;; Modify file. We wait for two seconds, in order to ;; have another timestamp. One second seems to be too - ;; short. And Cygwin sporadically requires more than two. + ;; short. And cygwin sporadically requires more than two. (ert-with-message-capture captured-messages (sleep-for (if (eq system-type 'cygwin) 3 2)) (write-region @@ -1021,6 +1042,12 @@ delivered." ((string-equal (file-notify--test-library) "gvfs-monitor-dir.exe") '((deleted stopped) (changed deleted stopped))) + ;; GFam{File,Directory}Monitor do not detect the + ;; `changed' event reliably. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor)) + '((deleted stopped) + (changed deleted stopped))) ;; There could be one or two `changed' events. (t '((changed deleted stopped) (changed changed deleted stopped)))) @@ -1064,9 +1091,12 @@ delivered." '((deleted stopped) (created deleted stopped))) ;; There are two `deleted' events, for the file and for - ;; the directory. Except for cygwin and kqueue. And - ;; cygwin does not raise a `changed' event. - ((eq system-type 'cygwin) + ;; the directory. Except for + ;; GFam{File,Directory}Monitor and kqueue. And + ;; GFam{File,Directory}Monitor do not raise a `changed' + ;; event. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor)) '(created deleted stopped)) ((string-equal (file-notify--test-library) "kqueue") '(created changed deleted stopped)) @@ -1198,9 +1228,10 @@ delivered." (dotimes (_i n) (setq r (append '(deleted renamed) r))) r)) - ;; cygwin fires `changed' and `deleted' events, sometimes - ;; in random order. - ((eq system-type 'cygwin) + ;; GFam{File,Directory}Monitor fire `changed' and + ;; `deleted' events, sometimes in random order. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor)) (let (r) (dotimes (_i n) (setq r (append '(changed deleted) r))) @@ -1283,9 +1314,10 @@ delivered." (should (file-notify-valid-p file-notify--test-desc)) (file-notify--test-with-actions (cond - ;; On cygwin we only get the `changed' event. - ((eq system-type 'cygwin) - '(changed)) + ;; GFam{File,Directory}Monitor report only the `changed' event. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor)) + '(changed)) (t '(renamed created changed))) ;; The file is renamed when creating a backup. It shall ;; still be watched. @@ -1407,10 +1439,12 @@ the file watch." ;; Now we delete the directory. (file-notify--test-with-actions (cond - ;; In kqueue and for cygwin, just one `deleted' event for - ;; the directory is received. - ((or (eq system-type 'cygwin) - (string-equal (file-notify--test-library) "kqueue")) + ;; GFam{File,Directory}Monitor and kqueue raise just one + ;; `deleted' event for the directory. + ((memq (file-notify--test-monitor) + '(GFamFileMonitor GFamDirectoryMonitor)) + '(deleted stopped)) + ((string-equal (file-notify--test-library) "kqueue") '(deleted stopped)) (t (append ;; The directory monitor raises a `deleted' event for commit 52a74604160387230c104e3305a5e08fa8c3fdf6 Author: Michael Albinus Date: Thu Mar 25 12:02:57 2021 +0100 Adapt Tramp file notification support * lisp/net/tramp-integration.el (tramp-use-ssh-controlmaster-options): Declare it. * lisp/net/tramp-sh.el (tramp-sh-handle-file-notify-add-watch): Remove "gvfs-monitor-dir". (tramp-sh-gvfs-monitor-dir-process-filter) (tramp-get-remote-gvfs-monitor-dir): Remove. (tramp-get-remote-gio-file-monitor): Support also cygwin, and GFamDirectoryMonitor, GPollFileMonitor. diff --git a/lisp/net/tramp-integration.el b/lisp/net/tramp-integration.el index 9d4dd7d42a..2931b4f0cc 100644 --- a/lisp/net/tramp-integration.el +++ b/lisp/net/tramp-integration.el @@ -49,6 +49,7 @@ (defvar recentf-exclude) (defvar tramp-current-connection) (defvar tramp-postfix-host-format) +(defvar tramp-use-ssh-controlmaster-options) ;;; Fontification of `read-file-name': diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 7182cd6b1d..d6fdbb0419 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -3686,18 +3686,6 @@ Fall back to normal file name handler if no Tramp handler exists." '(created changed changes-done-hint moved deleted)) ((memq 'attribute-change flags) '(attribute-changed))) sequence `(,command "monitor" ,localname))) - ;; "gvfs-monitor-dir". - ((setq command (tramp-get-remote-gvfs-monitor-dir v)) - (setq filter #'tramp-sh-gvfs-monitor-dir-process-filter - events - (cond - ((and (memq 'change flags) (memq 'attribute-change flags)) - '(created changed changes-done-hint moved deleted - attribute-changed)) - ((memq 'change flags) - '(created changed changes-done-hint moved deleted)) - ((memq 'attribute-change flags) '(attribute-changed))) - sequence `(,command ,localname))) ;; None. (t (tramp-error v 'file-notify-error @@ -3795,56 +3783,6 @@ Fall back to normal file name handler if no Tramp handler exists." (when string (tramp-message proc 10 "Rest string:\n%s" string)) (process-put proc 'rest-string string))) -(defun tramp-sh-gvfs-monitor-dir-process-filter (proc string) - "Read output from \"gvfs-monitor-dir\" and add corresponding \ -`file-notify' events." - (let ((events (process-get proc 'events)) - (remote-prefix - (with-current-buffer (process-buffer proc) - (file-remote-p default-directory))) - (rest-string (process-get proc 'rest-string))) - (when rest-string - (tramp-message proc 10 "Previous string:\n%s" rest-string)) - (tramp-message proc 6 "%S\n%s" proc string) - (setq string (concat rest-string string) - ;; Attribute change is returned in unused wording. - string (tramp-compat-string-replace - "ATTRIB CHANGED" "ATTRIBUTE_CHANGED" string)) - - (while (string-match - (concat "^[\n\r]*" - "Directory Monitor Event:[\n\r]+" - "Child = \\([^\n\r]+\\)[\n\r]+" - "\\(Other = \\([^\n\r]+\\)[\n\r]+\\)?" - "Event = \\([^[:blank:]]+\\)[\n\r]+") - string) - (let* ((file (match-string 1 string)) - (file1 (match-string 3 string)) - (object - (list - proc - (list - (intern-soft - (tramp-compat-string-replace - "_" "-" (downcase (match-string 4 string))))) - ;; File names are returned as absolute paths. We must - ;; add the remote prefix. - (concat remote-prefix file) - (when file1 (concat remote-prefix file1))))) - (setq string (replace-match "" nil nil string)) - ;; Usually, we would add an Emacs event now. Unfortunately, - ;; `unread-command-events' does not accept several events at - ;; once. Therefore, we apply the handler directly. - (when (member (cl-caadr object) events) - (tramp-compat-funcall - (lookup-key special-event-map [file-notify]) - `(file-notify ,object file-notify-callback))))) - - ;; Save rest of the string. - (when (zerop (length string)) (setq string nil)) - (when string (tramp-message proc 10 "Rest string:\n%s" string)) - (process-put proc 'rest-string string))) - (defun tramp-sh-inotifywait-process-filter (proc string) "Read output from \"inotifywait\" and add corresponding `file-notify' events." (let ((events (process-get proc 'events))) @@ -5658,7 +5596,7 @@ This command is returned only if `delete-by-moving-to-trash' is non-nil." ;; linked libraries of libgio. (when (tramp-send-command-and-check vec (concat "ldd " gio)) (goto-char (point-min)) - (when (re-search-forward "\\S-+/libgio\\S-+") + (when (re-search-forward "\\S-+/\\(libgio\\|cyggio\\)\\S-+") (when (tramp-send-command-and-check vec (concat "strings " (match-string 0))) (goto-char (point-min)) @@ -5666,23 +5604,12 @@ This command is returned only if `delete-by-moving-to-trash' is non-nil." (format "^%s$" (regexp-opt - '("GFamFileMonitor" "GFenFileMonitor" - "GInotifyFileMonitor" "GKqueueFileMonitor"))) + '("GFamFileMonitor" "GFamDirectoryMonitor" "GFenFileMonitor" + "GInotifyFileMonitor" "GKqueueFileMonitor" + "GPollFileMonitor"))) nil 'noerror) (intern (match-string 0))))))))) -(defun tramp-get-remote-gvfs-monitor-dir (vec) - "Determine remote `gvfs-monitor-dir' command." - (with-tramp-connection-property vec "gvfs-monitor-dir" - (tramp-message vec 5 "Finding a suitable `gvfs-monitor-dir' command") - ;; We distinguish "gvfs-monitor-dir.exe" from cygwin in order to - ;; establish better timeouts in filenotify-tests.el. Any better - ;; distinction approach would be welcome! - (or (tramp-find-executable - vec "gvfs-monitor-dir.exe" (tramp-get-remote-path vec) t t) - (tramp-find-executable - vec "gvfs-monitor-dir" (tramp-get-remote-path vec) t t)))) - (defun tramp-get-remote-inotifywait (vec) "Determine remote `inotifywait' command." (with-tramp-connection-property vec "inotifywait" commit aeb0530309527e2bbfddbd71cccd2513a340d9bf Author: Glenn Morris Date: Wed Mar 24 20:15:46 2021 -0700 * doc/emacs/maintaining.texi (Managing Projects): Fixes and copyedits. diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi index 4054b094de..925c701980 100644 --- a/doc/emacs/emacs.texi +++ b/doc/emacs/emacs.texi @@ -861,6 +861,7 @@ Projects * Project File Commands:: Commands for handling project files. * Project Buffer Commands:: Commands for handling project buffers. * Switching Projects:: Switching between projects. +* Managing Projects:: Managing the project list file. Change Logs diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index 7e449a5c25..dfe4eb0ea3 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -1664,6 +1664,7 @@ the project back-end. For example, the VC back-end doesn't consider * Project File Commands:: Commands for handling project files. * Project Buffer Commands:: Commands for handling project buffers. * Switching Projects:: Switching between projects. +* Managing Projects:: Managing the project list file. @end menu @node Project File Commands @@ -1843,21 +1844,20 @@ in the menu, and which key invokes each command. records the list of known projects. It defaults to the file @file{projects} in @code{user-emacs-directory} (@pxref{Find Init}). -@node Managing project list file -@subsection Managing Projects +@node Managing Projects +@subsection Managing the Project List File @table @kbd @item M-x project-remove-known-project -Remove a known project from the (@code{project-list-file}). +Remove a known project from the @code{project-list-file}. @end table @findex project-remove-known-project - Normally Emacs handle adding and removing projects to the -(@code{project-list-file}) automatically. Sometimes you still want to -manually edit the available -projects. @kbd{M-x project-remove-known-project} will prompt you for the -available projects, and upon selecting one, it will disappear from the -@code{project-list-file} + Normally Emacs automatically adds and removes projects to and from the +@code{project-list-file}, but sometimes you may want to manually edit +the available projects. @kbd{M-x project-remove-known-project} +prompts you to choose one of the available projects, and then removes +it from the file. @node Change Log @section Change Logs commit c678b137ab31ebc74d3fe643598b071d014f7dd4 Author: Dmitry Gutov Date: Thu Mar 25 01:20:26 2021 +0200 Fix typo * lisp/progmodes/project.el (project-remove-known-project): Fix typo (bug#47287). diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 07842977ef..f1546541d5 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1237,7 +1237,7 @@ PROJECT-ROOT is the root directory of a known project listed in the project list." (interactive (list (project-prompt-project-dir))) (project--remove-from-project-list - dir "Project `%s' removed from known projects")) + project-root "Project `%s' removed from known projects")) (defun project-prompt-project-dir () "Prompt the user for a directory that is one of the known project roots. commit 275be44dd44de4b7413490ffad912935fe2e1763 Author: Theodor Thornhill Date: Mon Mar 22 00:19:23 2021 +0100 Add command project-remove-known-project * etc/NEWS: Mention the new command. * lisp/progmodes/project.el (project--remove-from-project-list): Add new argument, report-message, used to signal various messages when removal has happened. * lisp/progmodes/project.el (project-remove-known-project): New command that removes the selected directory from the project-list-file. * lisp/progmodes/project.el (project-current): Add the report message. * doc/emacs/maintaining.text: Add information about the new command to the manual. diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index 2750418871..7e449a5c25 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -1843,6 +1843,22 @@ in the menu, and which key invokes each command. records the list of known projects. It defaults to the file @file{projects} in @code{user-emacs-directory} (@pxref{Find Init}). +@node Managing project list file +@subsection Managing Projects + +@table @kbd +@item M-x project-remove-known-project +Remove a known project from the (@code{project-list-file}). +@end table + +@findex project-remove-known-project + Normally Emacs handle adding and removing projects to the +(@code{project-list-file}) automatically. Sometimes you still want to +manually edit the available +projects. @kbd{M-x project-remove-known-project} will prompt you for the +available projects, and upon selecting one, it will disappear from the +@code{project-list-file} + @node Change Log @section Change Logs diff --git a/etc/NEWS b/etc/NEWS index 5dbd61ff9a..68812c64cc 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1575,6 +1575,11 @@ project's root directory, respectively. +++ *** New user option 'project-list-file'. ++++ +*** New command 'project-remove-known-project'. +This command lets you interactively remove an entry from the list of projects +in 'project-list-file'. + ** xref --- diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index b6a886f731..07842977ef 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -201,7 +201,8 @@ of the project instance object." (when maybe-prompt (if pr (project-remember-project pr) - (project--remove-from-project-list directory) + (project--remove-from-project-list + directory "Project `%s' not found; removed from list") (setq pr (cons 'transient directory)))) pr)) @@ -1217,17 +1218,27 @@ Save the result in `project-list-file' if the list of projects has changed." (push (list dir) project--list) (project--write-project-list)))) -(defun project--remove-from-project-list (pr-dir) - "Remove directory PR-DIR of a missing project from the project list. +(defun project--remove-from-project-list (project-root report-message) + "Remove directory PROJECT-ROOT of a missing project from the project list. If the directory was in the list before the removal, save the result in `project-list-file'. Announce the project's removal -from the list." +from the list using REPORT-MESSAGE, which is a format string +passed to `message' as its first argument." (project--ensure-read-project-list) - (when-let ((ent (assoc pr-dir project--list))) + (when-let ((ent (assoc project-root project--list))) (setq project--list (delq ent project--list)) - (message "Project `%s' not found; removed from list" pr-dir) + (message report-message project-root) (project--write-project-list))) +;;;###autoload +(defun project-remove-known-project (project-root) + "Remove directory PROJECT-ROOT from the project list. +PROJECT-ROOT is the root directory of a known project listed in +the project list." + (interactive (list (project-prompt-project-dir))) + (project--remove-from-project-list + dir "Project `%s' removed from known projects")) + (defun project-prompt-project-dir () "Prompt the user for a directory that is one of the known project roots. The project is chosen among projects known from the project list, commit 8e9835c673da09b77f478c769a1579104120a901 Author: Stefan Monnier Date: Wed Mar 24 17:11:05 2021 -0400 * list/progmodes/idl*.el: Use lexical-binding * lisp/progmodes/idlw-complete-structtag.el: Use lexical-binding. * lisp/progmodes/idlw-help.el: Use lexical-binding. Delete redundant `:group` arguments. (idlwave-query-class, idlwave-force-class-query, idlw-help-name) (idlw-help-kwd, idlw-help-link): Declare vars. (idlwave-highlight-linked-completions): Remove unused var `class`. (idlwave-help-find-in-doc-header): Remove unused var `header-re`. * lisp/progmodes/idlw-shell.el (idlwave-shell-input-mode-magic): Remove XEmacs-only code. (idlwave-shell-filter, idlwave-shell-scan-for-state): Use `functionp` since a function can also satisfy `listp`. (idlwave-shell--mouse-examine): Rename from `idlwave-shell-mouse-examine`. Make it a function, and simplify for Emacs≥22. Simplify calling convention since all callers always immediately `funcall`d the result. Update all callers. (idlwave-default-mouse-track-event-is-with-button): Use `always`. (idlwave-shell-filter-bp): Simplify a tiny bit. * lisp/progmodes/idlw-toolbar.el: Use lexical-binding. (idlwave-toolbar-add, idlwave-toolbar-remove) (idlwave-toolbar-add-everywhere, idlwave-toolbar-remove-everywhere) (idlwave-toolbar-toggle): Remove XEmacs-only code. * lisp/progmodes/idlwave.el: Use lexical-binding. (idlwave--dlet): New macro. (): Use it. (idlwave-keyword-abbrev): Turn it into a function. (idlwave-code-abbrev): Delete macro. (idlwave-mode-abbrev-table): Use `:enable-function` instead. (idlwave-with-special-syntax): Delete macro; use `with-syntax-table` instead in all callers. (idlwave-action-and-binding): Use `alist-get` and replace `(lambda...) with a proper closure. Change all callers to prefer passing a function in the `cmd` argument. (idlwave-fill-function): Delete constant var. Replace its uses with its value (the symbol `auto-fill-function`). (idlwave-mode): Set `normal-auto-fill-function` instead of the cumbersome use of `idlwave-fill-function`. Tighten a regexp. Don't set `imenu-create-index-function` to the value it should already have. (idlwave-auto-fill-mode): Make it an obsolete alias for `auto-fill-mode`. (idlwave-modify-abbrev): Rename from `idlwave-check-abbrev`. Don't check `idlwave-quoted` since `:enable-function` did it for us already. (idlwave--command-function): Rename from `idlwave-command-hook` and make it hold a function rather than an expression. (idlwave-command-hook, idlwave-modify-abbrev): Adjust accordingly. (idlwave-show-begin-check): Don't check `idlwave-quoted` since `:enable-function` did it for us already. (idlwave-do-action): Use `functionp` since a function can also satisfy `listp` (idlwave-new-sintern-type): Make it a macro, so we don't need to `declare-function` for the functions it defines. (idlwave--class-selector, idlwave--type-selector) (idlwave--method-selector, idlwave--super-classes): Rename those vars by adding the `idlwave--` prefix. Adjust all uses. (idlwave-complete-functions): Rename from `idlwave-complete-special`. (idlwave-call-special): Declare obsolete. Change all callers to use `run-hook-with-args-until-success` instead. (idlwave-complete-filename): Use `dlet`. (idlwave-rinfo-assq-any-class): Remove unused var `class`. (idlwave-determine-class-functions): Rename from `idlwave-determine-class-special`; fix docstring since the functions are called with only one argument. (idlwave--complete-after-success-function): Rename from `idlwave-complete-after-success-form` and make it hold a function. Adjust all users. (idlwave--complete-after-success-force-function): Rename from `idlwave-complete-after-success-form-force` and make it hold a function. Adjust all users. (idlwave-attach-classes): Remove always-t variable `do-dots`. (idlwave-local-value): Use `local-variable-p` and `buffer-local-value` to avoid `with-current-buffer`. (idlwave-default-choose-completion): Comment out (unused and calls a function that doesn't exist). (idlwave-shell-filter-sysvars): Remove unused vars `type`, `name`, and `class` (idlwave-fix-module-if-obj_new): Remove unused var `name`. (idlwave-fix-keywords): Bind `idlwave--super-classes` via `let` than via the function's argument. (idlwave-twin-class, idlwave-twin-name): Move before first use. (idlwave-study-twins): Remove stealth/redundant `type` variable. (idlwave-routine-entry-compare-twins): Remove unused var `type`. (idlwave-path-alist-add-flag): Avoid `add-to-list` on a local var. (idlwave-list-abbrevs): Simplify a tiny bit. diff --git a/lisp/progmodes/idlw-complete-structtag.el b/lisp/progmodes/idlw-complete-structtag.el index 25bc5ad881..6d2d402e35 100644 --- a/lisp/progmodes/idlw-complete-structtag.el +++ b/lisp/progmodes/idlw-complete-structtag.el @@ -1,4 +1,4 @@ -;;; idlw-complete-structtag.el --- Completion of structure tags. +;;; idlw-complete-structtag.el --- Completion of structure tags. -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. @@ -100,12 +100,11 @@ (defvar idlwave-sint-structtags nil) ;; Create the sintern type for structure talks -(declare-function idlwave-sintern-structtag "idlw-complete-structtag" t t) -(idlwave-new-sintern-type 'structtag) +(idlwave-new-sintern-type structtag) ;; Hook the plugin into idlwave -(add-to-list 'idlwave-complete-special 'idlwave-complete-structure-tag) -(add-hook 'idlwave-update-rinfo-hook 'idlwave-structtag-reset) +(add-hook 'idlwave-complete-functions #'idlwave-complete-structure-tag) +(add-hook 'idlwave-update-rinfo-hook #'idlwave-structtag-reset) ;;; The main code follows below (defvar idlwave-completion-help-info) diff --git a/lisp/progmodes/idlw-help.el b/lisp/progmodes/idlw-help.el index 2e7b0aa7ef..db76df96a5 100644 --- a/lisp/progmodes/idlw-help.el +++ b/lisp/progmodes/idlw-help.el @@ -1,4 +1,4 @@ -;;; idlw-help.el --- HTML Help code for IDLWAVE +;;; idlw-help.el --- HTML Help code for IDLWAVE -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. ;; @@ -50,7 +50,6 @@ (defcustom idlwave-html-help-pre-v6 nil "Whether pre or post-v6.0 IDL help documents are being used." - :group 'idlwave-online-help :type 'boolean) (defvar idlwave-html-link-sep @@ -60,7 +59,6 @@ "The directory, relative to `idlwave-system-directory', where the IDL HTML help files live, for IDL 6.2 and later. This location, if found, is used in preference to the old `idlwave-html-help-location'." - :group 'idlwave-online-help :type 'directory) (defcustom idlwave-html-help-location @@ -69,7 +67,6 @@ is used in preference to the old `idlwave-html-help-location'." "/usr/local/etc/") "The directory where the idl_html_help/ dir lives. Obsolete for IDL 6.2 or later (see `idlwave-html-system-help-location')." - :group 'idlwave-online-help :type 'directory) (defvar idlwave-help-use-hh nil @@ -77,18 +74,15 @@ is used in preference to the old `idlwave-html-help-location'." (defcustom idlwave-help-use-assistant t "Whether to use the IDL Assistant as the help browser." - :group 'idlwave-online-help :type 'boolean) (defcustom idlwave-help-browser-function browse-url-browser-function "Function to use to display HTML help. Defaults to `browse-url-browser-function', which see." - :group 'idlwave-online-help :type 'function) (defcustom idlwave-help-browser-generic-program browse-url-generic-program "Program to run if using `browse-url-generic-program'." - :group 'idlwave-online-help :type '(choice (const nil) string)) ;; AFAICS, never used since it was introduced in 2004. @@ -96,7 +90,6 @@ Defaults to `browse-url-browser-function', which see." (if (boundp 'browse-url-generic-args) browse-url-generic-args "") "Program args to use if using `browse-url-generic-program'." - :group 'idlwave-online-help :type '(repeat string)) (defcustom idlwave-help-browser-is-local nil @@ -106,7 +99,6 @@ external programs. If the browser name contains \"-w3\", it is assumed to be local to Emacs. For other local browsers, this variable must be explicitly set non-nil in order for the variable `idlwave-help-use-dedicated-frame' to function." - :group 'idlwave-online-help :type 'boolean) (defvar idlwave-help-directory "" @@ -114,7 +106,6 @@ must be explicitly set non-nil in order for the variable (defcustom idlwave-help-use-dedicated-frame t "Non-nil means, use a separate frame for Online Help if possible." - :group 'idlwave-online-help :type 'boolean) (defcustom idlwave-help-frame-parameters @@ -123,14 +114,12 @@ must be explicitly set non-nil in order for the variable See also `idlwave-help-use-dedicated-frame'. If you do not set the frame width here, the value specified in `idlw-help.el' will be used." - :group 'idlwave-online-help :type '(repeat (cons symbol sexp))) (defcustom idlwave-max-popup-menu-items 20 "Maximum number of items per pane in popup menus. Currently only used for class selection during completion help." - :group 'idlwave-online-help :type 'integer) (defcustom idlwave-extra-help-function 'idlwave-help-with-source @@ -158,12 +147,10 @@ The default value for this function is `idlwave-help-with-source' which loads the routine source file into the help buffer. If you try to write a different function which accesses a special help file or so, it is probably a good idea to still call this function as a fallback." - :group 'idlwave-online-help :type 'symbol) (defcustom idlwave-help-fontify-source-code nil "Non-nil means, fontify source code displayed as help like normal code." - :group 'idlwave-online-help :type 'boolean) (defcustom idlwave-help-source-try-header t @@ -173,7 +160,6 @@ help text. When this variable is non-nil, we try to find a description of the help item in the first routine doclib header above the routine definition. If the variable is nil, or if we cannot find/parse the header, the routine definition is displayed instead." - :group 'idlwave-online-help :type 'boolean) @@ -181,20 +167,17 @@ definition is displayed instead." "A regexp for the heading word to search for in doclib headers which specifies the `name' section. Can be used for localization support." - :group 'idlwave-online-help :type 'regexp) (defcustom idlwave-help-doclib-keyword "KEYWORD" "A regexp for the heading word to search for in doclib headers which specifies the `keywords' section. Can be used for localization support." - :group 'idlwave-online-help :type 'regexp) (defface idlwave-help-link '((t :inherit link)) - "Face for highlighting links into IDLWAVE online help." - :group 'idlwave-online-help) + "Face for highlighting links into IDLWAVE online help.") (defvar idlwave-help-activate-links-aggressively nil "Obsolete variable.") @@ -219,20 +202,20 @@ support." (defvar idlwave-help-mode-map (let ((map (make-sparse-keymap))) - (define-key map "q" 'idlwave-help-quit) - (define-key map "w" 'widen) + (define-key map "q" #'idlwave-help-quit) + (define-key map "w" #'widen) (define-key map "\C-m" (lambda (arg) (interactive "p") (scroll-up arg))) - (define-key map " " 'scroll-up-command) - (define-key map [?\S-\ ] 'scroll-down-command) - (define-key map [delete] 'scroll-down-command) - (define-key map "h" 'idlwave-help-find-header) - (define-key map "H" 'idlwave-help-find-first-header) - (define-key map "." 'idlwave-help-toggle-header-match-and-def) - (define-key map "F" 'idlwave-help-fontify) - (define-key map "\M-?" 'idlwave-help-return-to-calling-frame) - (define-key map "x" 'idlwave-help-return-to-calling-frame) + (define-key map " " #'scroll-up-command) + (define-key map [?\S-\ ] #'scroll-down-command) + (define-key map [delete] #'scroll-down-command) + (define-key map "h" #'idlwave-help-find-header) + (define-key map "H" #'idlwave-help-find-first-header) + (define-key map "." #'idlwave-help-toggle-header-match-and-def) + (define-key map "F" #'idlwave-help-fontify) + (define-key map "\M-?" #'idlwave-help-return-to-calling-frame) + (define-key map "x" #'idlwave-help-return-to-calling-frame) map) "The keymap used in `idlwave-help-mode'.") @@ -374,7 +357,7 @@ It collects and prints the diagnostics messages." (setq idlwave-last-context-help-pos marker) (idlwave-do-context-help1 arg) (if idlwave-help-diagnostics - (message "%s" (mapconcat 'identity + (message "%s" (mapconcat #'identity (nreverse idlwave-help-diagnostics) "; ")))))) @@ -384,6 +367,12 @@ It collects and prints the diagnostics messages." (defvar idlwave-system-variables-alist) (defvar idlwave-executive-commands-alist) (defvar idlwave-system-class-info) +(defvar idlwave-query-class) +(defvar idlwave-force-class-query) +(defvar idlw-help-name) +(defvar idlw-help-kwd) +(defvar idlw-help-link) + (defun idlwave-do-context-help1 (&optional arg) "The work-horse version of `idlwave-context-help', which see." (save-excursion @@ -549,16 +538,16 @@ It collects and prints the diagnostics messages." (setq mod1 (append (list t) module)))) (if mod3 (condition-case nil - (apply 'idlwave-online-help mod1) + (apply #'idlwave-online-help mod1) (error (condition-case nil - (apply 'idlwave-online-help mod2) - (error (apply 'idlwave-online-help mod3))))) + (apply #'idlwave-online-help mod2) + (error (apply #'idlwave-online-help mod3))))) (if mod2 (condition-case nil - (apply 'idlwave-online-help mod1) - (error (apply 'idlwave-online-help mod2))) + (apply #'idlwave-online-help mod1) + (error (apply #'idlwave-online-help mod2))) (if mod1 - (apply 'idlwave-online-help mod1) + (apply #'idlwave-online-help mod1) (error "Don't know which item to show help for"))))))) (defun idlwave-do-mouse-completion-help (ev) @@ -660,7 +649,7 @@ Those words in `idlwave-completion-help-links' have links. The (props (list 'face 'idlwave-help-link)) (info idlwave-completion-help-info) ; global passed in (what (nth 0 info)) ; what was completed, or a func - (class (nth 3 info)) ; any class + ;; (class (nth 3 info)) ; any class word beg end doit) (goto-char (point-min)) (re-search-forward "possible completions are:" nil t) @@ -685,7 +674,7 @@ Those words in `idlwave-completion-help-links' have links. The ;; Arrange for this function to be called after completion (add-hook 'idlwave-completion-setup-hook - 'idlwave-highlight-linked-completions) + #'idlwave-highlight-linked-completions) (defvar idlwave-help-return-frame nil "The frame to return to from the help frame.") @@ -947,7 +936,7 @@ This function can be used as `idlwave-extra-help-function'." (point))) -(defun idlwave-help-find-routine-definition (name type class keyword) +(defun idlwave-help-find-routine-definition (name type class _keyword) "Find the definition of routine CLASS::NAME in current buffer. Returns the point of match if successful, nil otherwise. KEYWORD is ignored." @@ -967,7 +956,7 @@ KEYWORD is ignored." (defvar idlwave-doclib-start) (defvar idlwave-doclib-end) -(defun idlwave-help-find-in-doc-header (name type class keyword +(defun idlwave-help-find-in-doc-header (name _type class keyword &optional exact) "Find the requested help in the doc-header above point. @@ -1025,9 +1014,9 @@ If there is a match, we assume it is the keyword description." ":[ \t]*$\\)")) ;; Header start plus name - (header-re (concat "\\(" idlwave-doclib-start "\\).*\n" - "\\(^;+.*\n\\)*" - "\\(" name-re "\\)")) + ;; (header-re (concat "\\(" idlwave-doclib-start "\\).*\n" + ;; "\\(^;+.*\n\\)*" + ;; "\\(" name-re "\\)")) ;; A keywords section (kwds-re (concat ; forgiving "^;+\\*?[ \t]*" @@ -1095,8 +1084,8 @@ When DING is non-nil, ring the bell as well." (cons string idlwave-help-diagnostics)) (if ding (ding))))) -(defun idlwave-help-toggle-header-top-and-def (arg) - (interactive "P") +(defun idlwave-help-toggle-header-top-and-def (&optional _arg) + (interactive) (let (pos) (if idlwave-help-in-header ;; Header was the last thing displayed @@ -1119,8 +1108,8 @@ When DING is non-nil, ring the bell as well." (goto-char pos) (recenter 0))))) -(defun idlwave-help-find-first-header (arg) - (interactive "P") +(defun idlwave-help-find-first-header (&optional _arg) + (interactive) (let (pos) (save-excursion (goto-char (point-min)) @@ -1140,8 +1129,8 @@ When DING is non-nil, ring the bell as well." (setq idlwave-help-in-header nil) (idlwave-help-toggle-header-match-and-def arg 'top))) -(defun idlwave-help-toggle-header-match-and-def (arg &optional top) - (interactive "P") +(defun idlwave-help-toggle-header-match-and-def (&optional _arg top) + (interactive) (let ((args idlwave-help-args) pos) (if idlwave-help-in-header @@ -1150,7 +1139,7 @@ When DING is non-nil, ring the bell as well." (setq idlwave-help-in-header nil) (setq pos idlwave-help-def-pos)) ;; Try to display header - (setq pos (apply 'idlwave-help-find-in-doc-header + (setq pos (apply #'idlwave-help-find-in-doc-header (if top (list (car args) (nth 1 args) (nth 2 args) nil) args))) @@ -1184,7 +1173,7 @@ Useful when source code is displayed as help. See the option (with-no-warnings (font-lock-fontify-buffer)))))) -(defun idlwave-help-error (name type class keyword) +(defun idlwave-help-error (name _type class keyword) (error "Can't find help on %s%s %s" (or (and (or class name) (idlwave-make-full-name class name)) "") @@ -1272,11 +1261,11 @@ IDL assistant.") (delete-process idlwave-help-assistant-socket)) (setq idlwave-help-assistant-process - (apply 'start-process + (apply #'start-process "IDL_ASSISTANT_PROC" nil command "-server" extra-args)) (set-process-filter idlwave-help-assistant-process - (lambda (proc string) + (lambda (_proc string) (setq port (string-to-number string)))) (unless (accept-process-output idlwave-help-assistant-process 15) (error "Failed binding IDL_ASSISTANT socket")) diff --git a/lisp/progmodes/idlw-shell.el b/lisp/progmodes/idlw-shell.el index 4bc52247d8..134a6c6e49 100644 --- a/lisp/progmodes/idlw-shell.el +++ b/lisp/progmodes/idlw-shell.el @@ -729,7 +729,7 @@ IDL is currently stopped.") (defconst idlwave-shell-halt-messages-re - (mapconcat 'identity idlwave-shell-halt-messages "\\|") + (mapconcat #'identity idlwave-shell-halt-messages "\\|") "The regular expression computed from `idlwave-shell-halt-messages'.") (defconst idlwave-shell-trace-message-re @@ -934,8 +934,8 @@ IDL has currently stepped.") "[ \t\n]*\\'")) (when idlwave-shell-query-for-class - (add-to-list (make-local-variable 'idlwave-determine-class-special) - 'idlwave-shell-get-object-class) + (add-hook 'idlwave-determine-class-functions + #'idlwave-shell-get-object-class nil t) (setq idlwave-store-inquired-class t)) ;; Make sure comint-last-input-end does not go to beginning of @@ -950,10 +950,10 @@ IDL has currently stepped.") (setq idlwave-shell-default-directory default-directory) (setq idlwave-shell-hide-output nil) - (add-hook 'kill-buffer-hook 'idlwave-shell-kill-shell-buffer-confirm + (add-hook 'kill-buffer-hook #'idlwave-shell-kill-shell-buffer-confirm nil 'local) - (add-hook 'kill-buffer-hook 'idlwave-shell-delete-temp-files nil 'local) - (add-hook 'kill-emacs-hook 'idlwave-shell-delete-temp-files) + (add-hook 'kill-buffer-hook #'idlwave-shell-delete-temp-files nil 'local) + (add-hook 'kill-emacs-hook #'idlwave-shell-delete-temp-files) ;; Set the optional comint variables (when idlwave-shell-comint-settings @@ -962,7 +962,7 @@ IDL has currently stepped.") (set (make-local-variable (car entry)) (cdr entry))))) - (unless (memq 'comint-carriage-motion + (unless (memq #'comint-carriage-motion (default-value 'comint-output-filter-functions)) ;; Strip those pesky ctrl-m's. (add-hook 'comint-output-filter-functions @@ -976,18 +976,21 @@ IDL has currently stepped.") (while (search-forward "\r" pmark t) (delete-region (point) (line-beginning-position))))))) 'append 'local) - (add-hook 'comint-output-filter-functions 'comint-strip-ctrl-m nil 'local)) + (add-hook 'comint-output-filter-functions #'comint-strip-ctrl-m nil 'local)) ;; Python-mode, bundled with many Emacs installs, quite cavalierly ;; adds this function to the global default hook. It interferes ;; with overlay-arrows. - (remove-hook 'comint-output-filter-functions 'py-pdbtrack-track-stack-file) + ;; FIXME: We should fix this interference rather than globally turn it off. + (when (fboundp 'py-pdbtrack-track-stack-file) + (remove-hook 'comint-output-filter-functions + #'py-pdbtrack-track-stack-file)) ;; IDLWAVE syntax, and turn on abbreviations (set (make-local-variable 'comment-start) ";") (setq abbrev-mode t) - (add-hook 'post-command-hook 'idlwave-command-hook nil t) + (add-hook 'post-command-hook #'idlwave-command-hook nil t) ;; Read the command history? (when (and idlwave-shell-save-command-history @@ -1045,7 +1048,7 @@ IDL has currently stepped.") (setq idlwave-path-alist old-path-alist)))) (if (not (fboundp 'idl-shell)) - (fset 'idl-shell 'idlwave-shell)) + (defalias 'idl-shell #'idlwave-shell)) (defvar idlwave-shell-idl-wframe nil "Frame for displaying the IDL shell window.") @@ -1120,7 +1123,7 @@ See also the variable `idlwave-shell-prompt-pattern'. (and idlwave-shell-use-dedicated-frame (setq idlwave-shell-idl-wframe (selected-frame))) (add-hook 'idlwave-shell-sentinel-hook - 'save-buffers-kill-emacs t)) + #'save-buffers-kill-emacs t)) ;; A non-nil arg means, we want a dedicated frame. This will last ;; for the current editing session. @@ -1130,7 +1133,7 @@ See also the variable `idlwave-shell-prompt-pattern'. ;; Check if the process still exists. If not, create it. (unless (comint-check-proc (idlwave-shell-buffer)) (let* ((prg (or idlwave-shell-explicit-file-name "idl")) - (buf (apply 'make-comint + (buf (apply #'make-comint idlwave-shell-process-name prg nil (if (stringp idlwave-shell-command-line-options) (idlwave-split-string @@ -1138,8 +1141,8 @@ See also the variable `idlwave-shell-prompt-pattern'. idlwave-shell-command-line-options))) (process (get-buffer-process buf))) (setq idlwave-idlwave_routine_info-compiled nil) - (set-process-filter process 'idlwave-shell-filter) - (set-process-sentinel process 'idlwave-shell-sentinel) + (set-process-filter process #'idlwave-shell-filter) + (set-process-sentinel process #'idlwave-shell-sentinel) (set-buffer buf) (idlwave-shell-mode))) (let ((window (idlwave-display-buffer (idlwave-shell-buffer) nil @@ -1315,10 +1318,7 @@ See also the variable `idlwave-shell-input-mode-spells'." (setq idlwave-shell-char-mode-active 'exit)) ((string-match (nth 1 idlwave-shell-input-mode-spells) string) ;; Set a timer which will soon start the character loop - (if (fboundp 'start-itimer) - (start-itimer "IDLWAVE Char Mode" 'idlwave-shell-char-mode-loop 0.5 - nil nil t 'no-error) - (run-at-time 0.5 nil 'idlwave-shell-char-mode-loop 'no-error))))) + (run-at-time 0.5 nil #'idlwave-shell-char-mode-loop 'no-error)))) (defvar keyboard-quit) (defun idlwave-shell-char-mode-loop (&optional no-error) @@ -1396,7 +1396,7 @@ Otherwise just move the line. Move down unless UP is non-nil." (idlwave-shell-move-or-history nil arg)) (define-obsolete-function-alias 'idlwave-shell-comint-filter - 'comint-output-filter "25.1") + #'comint-output-filter "25.1") (defun idlwave-shell-is-running () "Return t if the shell process is running." @@ -1510,13 +1510,12 @@ and then calls `idlwave-shell-send-command' for any pending commands." proc filtered)))))) ;; Call the post-command hook - (if (listp idlwave-shell-post-command-hook) - (progn - ;;(message "Calling list") - ;;(prin1 idlwave-shell-post-command-hook) - (eval idlwave-shell-post-command-hook)) - ;;(message "Calling command function") - (funcall idlwave-shell-post-command-hook)) + (if (functionp idlwave-shell-post-command-hook) + ;;(message "Calling command function") + (funcall idlwave-shell-post-command-hook) + ;;(message "Calling list") + ;;(prin1 idlwave-shell-post-command-hook) + (eval idlwave-shell-post-command-hook t)) ;; Reset to default state for next command. ;; Also we do not want to find this prompt again. @@ -1690,7 +1689,7 @@ the above." (if bp (let ((cmd (idlwave-shell-bp-get bp 'cmd))) (if cmd ;; Execute any breakpoint command - (if (listp cmd) (eval cmd) (funcall cmd)))) + (if (functionp cmd) (funcall cmd) (eval cmd t)))) ;; A breakpoint that we did not know about - perhaps it was ;; set by the user... Let's update our list. (idlwave-shell-bp-query))) @@ -1819,7 +1818,7 @@ The size is given by `idlwave-shell-graphics-window-size'." (interactive "P") (let ((n (if n (prefix-numeric-value n) 0))) (idlwave-shell-send-command - (apply 'format "window,%d,xs=%d,ys=%d" + (apply #'format "window,%d,xs=%d,ys=%d" n idlwave-shell-graphics-window-size) nil (idlwave-shell-hide-p 'misc) nil t))) @@ -1891,7 +1890,7 @@ HEAP_GC, /VERBOSE" (while (string-match "^PATH:[ \t]*<\\(.*\\)>[ \t]*\n" path-string start) (push (match-string 1 path-string) dirs) (setq start (match-end 0))) - (setq dirs (mapcar 'file-name-as-directory dirs)) + (setq dirs (mapcar #'file-name-as-directory dirs)) (if (string-match "^SYSDIR:[ \t]*<\\(.*\\)>[ \t]*\n" path-string) (setq sysdir (file-name-as-directory (match-string 1 path-string)))) @@ -1938,13 +1937,14 @@ HEAP_GC, /VERBOSE" key (nth 4 specs) keys (if (and (stringp key) (not (string-match "\\` *\\'" key))) - (mapcar 'list + (mapcar #'list (delete "" (idlwave-split-string key " +"))))) (setq name (idlwave-sintern-routine-or-method name class t) class (idlwave-sintern-class class t) file (if (equal file "") nil file) keys (mapcar (lambda (x) - (list (idlwave-sintern-keyword (car x) t))) keys)) + (list (idlwave-sintern-keyword (car x) t))) + keys)) ;; In the following ignore routines already defined in buffers, ;; assuming that if the buffer stuff differs, it is a "new" @@ -2053,7 +2053,7 @@ Change the default directory for the process buffer to concur." (match-string 1 idlwave-shell-command-output))))) (defvar idlwave-sint-sysvars nil) -(idlwave-new-sintern-type 'execcomm) +(idlwave-new-sintern-type execcomm) (defun idlwave-shell-complete (&optional arg) "Do completion in the idlwave-shell buffer. @@ -2180,7 +2180,7 @@ overlays." (defun idlwave-shell-parse-stack-and-display () (let* ((lines (delete "" (idlwave-split-string idlwave-shell-command-output "^%"))) - (stack (delq nil (mapcar 'idlwave-shell-parse-line lines))) + (stack (delq nil (mapcar #'idlwave-shell-parse-line lines))) (nmax (1- (length stack))) (nmin 0) message) (cond @@ -2710,45 +2710,34 @@ Runs to the last statement and then steps 1 statement. Use the .out command." (interactive "P") (idlwave-shell-print arg 'help)) -(defmacro idlwave-shell-mouse-examine (help &optional ev) - "Create a function for generic examination of expressions." - `(lambda (event) - "Expansion function for expression examination." - (interactive "e") - (let* ((drag-track (fboundp 'mouse-drag-track)) - (transient-mark-mode t) - (tracker - ;; Emacs 22 no longer completes the drag with - ;; mouse-drag-region, without an additional - ;; event. mouse-drag-track does so. - (if drag-track 'mouse-drag-track 'mouse-drag-region))) - (funcall tracker event) - (idlwave-shell-print (if (region-active-p) '(4) nil) - ,help ,ev)))) - -;; Begin terrible hack section -- XEmacs tests for button2 explicitly -;; on drag events, calling drag-n-drop code if detected. Ughhh... -(defun idlwave-default-mouse-track-event-is-with-button (_event _n) - (declare (obsolete nil "28.1")) - t) - -(define-obsolete-function-alias 'idlwave-xemacs-hack-mouse-track 'ignore "27.1") +(defun idlwave-shell--mouse-examine (event help &optional ev) + "Expansion function for expression examination." + (let* ((transient-mark-mode t)) + (mouse-drag-track event) + (idlwave-shell-print (if (region-active-p) '(4) nil) + help ev))) + +(define-obsolete-function-alias + 'idlwave-default-mouse-track-event-is-with-button #'always "28.1") + +(define-obsolete-function-alias 'idlwave-xemacs-hack-mouse-track + #'ignore "27.1") ;;; End terrible hack section (defun idlwave-shell-mouse-print (event) "Print value of variable at the mouse position, with `print'." (interactive "e") - (funcall (idlwave-shell-mouse-examine nil) event)) + (idlwave-shell--mouse-examine event nil)) (defun idlwave-shell-mouse-help (event) "Print value of variable at the mouse position, with `help'." (interactive "e") - (funcall (idlwave-shell-mouse-examine 'help) event)) + (idlwave-shell--mouse-examine event 'help)) (defun idlwave-shell-examine-select (event) "Pop-up a list to select from for examining the expression." (interactive "e") - (funcall (idlwave-shell-mouse-examine nil event) event)) + (idlwave-shell--mouse-examine event nil event)) (defmacro idlwave-shell-examine (help) "Create a function for key-driven expression examination." @@ -2814,7 +2803,7 @@ from `idlwave-shell-examine-alist' via mini-buffer shortcut key." (setq beg (region-beginning) end (region-end))) (t - (idlwave-with-special-syntax + (with-syntax-table idlwave-find-symbol-syntax-table ;; Move to beginning of current or previous expression (if (looking-at "\\<\\|(") ;; At beginning of expression, don't move backwards unless @@ -2847,9 +2836,9 @@ from `idlwave-shell-examine-alist' via mini-buffer shortcut key." (move-overlay idlwave-shell-expression-overlay beg end (current-buffer)) (add-hook 'pre-command-hook - 'idlwave-shell-delete-expression-overlay)) + #'idlwave-shell-delete-expression-overlay)) (add-hook 'pre-command-hook - 'idlwave-shell-delete-output-overlay) + #'idlwave-shell-delete-output-overlay) ;; Remove empty or comment-only lines (while (string-match "\n[ \t]*\\(;.*\\)?\r*\n" expr) @@ -2881,7 +2870,7 @@ from `idlwave-shell-examine-alist' via mini-buffer shortcut key." ;; "Print") (idlwave-popup-select ev - (mapcar 'car idlwave-shell-examine-alist) + (mapcar #'car idlwave-shell-examine-alist) "Examine with")) idlwave-shell-examine-alist)))) (setq help (cdr help-cons)) @@ -2916,9 +2905,8 @@ from `idlwave-shell-examine-alist' via mini-buffer shortcut key." "Variable to hold the win/height pairs for all *Examine* windows.") (defvar idlwave-shell-examine-map (make-sparse-keymap)) -(define-key idlwave-shell-examine-map "q" 'idlwave-shell-examine-display-quit) -(define-key idlwave-shell-examine-map "c" 'idlwave-shell-examine-display-clear) - +(define-key idlwave-shell-examine-map "q" #'idlwave-shell-examine-display-quit) +(define-key idlwave-shell-examine-map "c" #'idlwave-shell-examine-display-clear) (defun idlwave-shell-check-compiled-and-display () "Check examine output for warning about undefined procedure/function." @@ -3347,9 +3335,10 @@ the breakpoint overlays." count nil condition disabled)))))) (setq idlwave-shell-bp-alist (cdr idlwave-shell-bp-alist)) ;; Update breakpoint data - (if (eq bp-re bp-re54) - (mapc 'idlwave-shell-update-bp old-bp-alist) - (mapc 'idlwave-shell-update-bp-command-only old-bp-alist)))) + (mapc (if (eq bp-re bp-re54) + #'idlwave-shell-update-bp + #'idlwave-shell-update-bp-command-only) + old-bp-alist))) ;; Update the breakpoint overlays (unless no-show (idlwave-shell-update-bp-overlays)) ;; Return the new list @@ -3484,7 +3473,7 @@ The actual line number for a breakpoint in IDL may be different from the line number used with the IDL breakpoint command. Looks for a new breakpoint index number in the list. This is considered the new breakpoint if the file name of frame matches." - (let ((obp-index (mapcar 'idlwave-shell-bp-get idlwave-shell-old-bp)) + (let ((obp-index (mapcar #'idlwave-shell-bp-get idlwave-shell-old-bp)) (bpl idlwave-shell-bp-alist)) (while (and (member (idlwave-shell-bp-get (car bpl)) obp-index) (setq bpl (cdr bpl)))) @@ -3510,7 +3499,7 @@ considered the new breakpoint if the file name of frame matches." (defvar idlwave-shell-debug-line-map (make-sparse-keymap)) (define-key idlwave-shell-debug-line-map [mouse-3] - 'idlwave-shell-mouse-active-bp) + #'idlwave-shell-mouse-active-bp) (defun idlwave-shell-update-bp-overlays () "Update the overlays which mark breakpoints in the source code. @@ -3532,7 +3521,7 @@ Existing overlays are recycled, in order to minimize consumption." (setq ov-alist idlwave-shell-bp-overlays idlwave-shell-bp-overlays (if idlwave-shell-bp-glyph - (mapcar 'list (mapcar 'car idlwave-shell-bp-glyph)) + (mapcar #'list (mapcar #'car idlwave-shell-bp-glyph)) (list (list 'bp)))) (while (setq bp (pop bp-list)) (save-excursion @@ -3568,7 +3557,7 @@ Existing overlays are recycled, in order to minimize consumption." (if help-list (concat " - " - (mapconcat 'identity help-list ", "))) + (mapconcat #'identity help-list ", "))) (if (and (not count) (not condition)) " (use mouse-3 for breakpoint actions)"))) (full-type (if disabled @@ -3962,73 +3951,73 @@ Otherwise, just expand the file name." ;;(define-key map "\M-?" 'comint-dynamic-list-completions) ;;(define-key map "\t" 'comint-dynamic-complete) - (define-key map "\C-w" 'comint-kill-region) - (define-key map "\t" 'idlwave-shell-complete) - (define-key map "\M-\t" 'idlwave-shell-complete) - (define-key map "\C-c\C-s" 'idlwave-shell) - (define-key map "\C-c?" 'idlwave-routine-info) - (define-key map "\C-g" 'idlwave-keyboard-quit) - (define-key map "\M-?" 'idlwave-context-help) + (define-key map "\C-w" #'comint-kill-region) + (define-key map "\t" #'idlwave-shell-complete) + (define-key map "\M-\t" #'idlwave-shell-complete) + (define-key map "\C-c\C-s" #'idlwave-shell) + (define-key map "\C-c?" #'idlwave-routine-info) + (define-key map "\C-g" #'idlwave-keyboard-quit) + (define-key map "\M-?" #'idlwave-context-help) (define-key map [(control meta ?\?)] - 'idlwave-help-assistant-help-with-topic) - (define-key map "\C-c\C-i" 'idlwave-update-routine-info) - (define-key map "\C-c\C-y" 'idlwave-shell-char-mode-loop) - (define-key map "\C-c\C-x" 'idlwave-shell-send-char) - (define-key map "\C-c=" 'idlwave-resolve) - (define-key map "\C-c\C-v" 'idlwave-find-module) - (define-key map "\C-c\C-k" 'idlwave-kill-autoloaded-buffers) + #'idlwave-help-assistant-help-with-topic) + (define-key map "\C-c\C-i" #'idlwave-update-routine-info) + (define-key map "\C-c\C-y" #'idlwave-shell-char-mode-loop) + (define-key map "\C-c\C-x" #'idlwave-shell-send-char) + (define-key map "\C-c=" #'idlwave-resolve) + (define-key map "\C-c\C-v" #'idlwave-find-module) + (define-key map "\C-c\C-k" #'idlwave-kill-autoloaded-buffers) (define-key map idlwave-shell-prefix-key - 'idlwave-shell-debug-map) - (define-key map [(up)] 'idlwave-shell-up-or-history) - (define-key map [(down)] 'idlwave-shell-down-or-history) + #'idlwave-shell-debug-map) + (define-key map [(up)] #'idlwave-shell-up-or-history) + (define-key map [(down)] #'idlwave-shell-down-or-history) (define-key idlwave-shell-mode-map [(shift mouse-3)] - 'idlwave-mouse-context-help) + #'idlwave-mouse-context-help) map) "Keymap for `idlwave-mode'.") (defvar idlwave-shell-electric-debug-mode-map (let ((map (make-sparse-keymap))) ;; A few extras in the electric debug map - (define-key map " " 'idlwave-shell-step) - (define-key map "+" 'idlwave-shell-stack-up) - (define-key map "=" 'idlwave-shell-stack-up) - (define-key map "-" 'idlwave-shell-stack-down) - (define-key map "_" 'idlwave-shell-stack-down) + (define-key map " " #'idlwave-shell-step) + (define-key map "+" #'idlwave-shell-stack-up) + (define-key map "=" #'idlwave-shell-stack-up) + (define-key map "-" #'idlwave-shell-stack-down) + (define-key map "_" #'idlwave-shell-stack-down) (define-key map "e" (lambda () (interactive) (idlwave-shell-print '(16)))) - (define-key map "q" 'idlwave-shell-retall) + (define-key map "q" #'idlwave-shell-retall) (define-key map "t" (lambda () (interactive) (idlwave-shell-send-command "help,/TRACE"))) - (define-key map [(control ??)] 'idlwave-shell-electric-debug-help) + (define-key map [(control ??)] #'idlwave-shell-electric-debug-help) (define-key map "x" (lambda (arg) (interactive "P") (idlwave-shell-print arg nil nil t))) map)) (defvar idlwave-shell-mode-prefix-map (make-sparse-keymap)) -(fset 'idlwave-shell-mode-prefix-map idlwave-shell-mode-prefix-map) +(defalias 'idlwave-shell-mode-prefix-map idlwave-shell-mode-prefix-map) (defvar idlwave-mode-prefix-map (make-sparse-keymap)) -(fset 'idlwave-mode-prefix-map idlwave-mode-prefix-map) +(defalias 'idlwave-mode-prefix-map idlwave-mode-prefix-map) (defun idlwave-shell-define-key-both (key hook) "Define a key in both the shell and buffer mode maps." (define-key idlwave-mode-map key hook) (define-key idlwave-shell-mode-map key hook)) -(define-key idlwave-mode-map "\C-c\C-y" 'idlwave-shell-char-mode-loop) -(define-key idlwave-mode-map "\C-c\C-x" 'idlwave-shell-send-char) +(define-key idlwave-mode-map "\C-c\C-y" #'idlwave-shell-char-mode-loop) +(define-key idlwave-mode-map "\C-c\C-x" #'idlwave-shell-send-char) ;; The mouse bindings for PRINT and HELP (idlwave-shell-define-key-both [(shift down-mouse-2)] - 'idlwave-shell-mouse-print) + #'idlwave-shell-mouse-print) (idlwave-shell-define-key-both [(control meta down-mouse-2)] - 'idlwave-shell-mouse-help) + #'idlwave-shell-mouse-help) (idlwave-shell-define-key-both [(control shift down-mouse-2)] - 'idlwave-shell-examine-select) + #'idlwave-shell-examine-select) ;; We need to turn off the button release events. -(idlwave-shell-define-key-both [(shift mouse-2)] 'ignore) -(idlwave-shell-define-key-both [(shift control mouse-2)] 'ignore) -(idlwave-shell-define-key-both [(control meta mouse-2)] 'ignore) +(idlwave-shell-define-key-both [(shift mouse-2)] #'ignore) +(idlwave-shell-define-key-both [(shift control mouse-2)] #'ignore) +(idlwave-shell-define-key-both [(control meta mouse-2)] #'ignore) ;; The following set of bindings is used to bind the debugging keys. @@ -4109,8 +4098,8 @@ Otherwise, just expand the file name." cmd)))) ; Enter the prefix map in two places. -(fset 'idlwave-debug-map idlwave-mode-prefix-map) -(fset 'idlwave-shell-debug-map idlwave-shell-mode-prefix-map) +(defalias 'idlwave-debug-map idlwave-mode-prefix-map) +(defalias 'idlwave-shell-debug-map idlwave-shell-mode-prefix-map) ;; The Electric Debug Minor Mode -------------------------------------------- @@ -4496,6 +4485,6 @@ static char * file[] = { (idlwave-toolbar-toggle)) (if idlwave-shell-use-toolbar - (add-hook 'idlwave-shell-mode-hook 'idlwave-toolbar-add-everywhere)) + (add-hook 'idlwave-shell-mode-hook #'idlwave-toolbar-add-everywhere)) ;;; idlw-shell.el ends here diff --git a/lisp/progmodes/idlw-toolbar.el b/lisp/progmodes/idlw-toolbar.el index 4bd0afb2ba..d3f47fcf45 100644 --- a/lisp/progmodes/idlw-toolbar.el +++ b/lisp/progmodes/idlw-toolbar.el @@ -1,4 +1,4 @@ -;;; idlw-toolbar.el --- a debugging toolbar for IDLWAVE +;;; idlw-toolbar.el --- a debugging toolbar for IDLWAVE -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. @@ -24,8 +24,8 @@ ;;; Commentary: -;; This file implements a debugging toolbar for IDLWAVE. It requires -;; Emacs or XEmacs with toolbar and xpm support. +;; This file implements a debugging toolbar for IDLWAVE. +;; It requires toolbar and xpm support. ;; New versions of IDLWAVE, documentation, and more information ;; available from: @@ -35,22 +35,16 @@ ;;; Code: (defun idlwave-toolbar-make-button (image) - (if (featurep 'xemacs) - (toolbar-make-button-list image) - (list 'image :type 'xpm :data image))) + (list 'image :type 'xpm :data image)) (defvar idlwave-toolbar) (defvar default-toolbar) (defvar idlwave-toolbar-is-possible) -(if (not (or (and (featurep 'xemacs) ; This is XEmacs - (featurep 'xpm) ; need xpm - (featurep 'toolbar)) ; ... and the toolbar - (and (not (featurep 'xemacs)) ; This is Emacs - (boundp 'tool-bar-button-margin) ; need toolbar - (fboundp 'image-type-available-p) ; need image stuff - (image-type-available-p 'xpm)) ; need xpm - )) +(if (not (and (boundp 'tool-bar-button-margin) ; need toolbar + (fboundp 'image-type-available-p) ; need image stuff + (image-type-available-p 'xpm)) ; need xpm + ) ;; oops - cannot do the toolbar (message "Sorry, IDLWAVE xpm toolbar cannot be used on this version of Emacs") ;; OK, we can define a toolbar @@ -873,23 +867,12 @@ static char * file[] = { ;; When the shell exits, arrange to remove the special toolbar everywhere. (add-hook 'idlwave-shell-cleanup-hook - 'idlwave-toolbar-remove-everywhere) + #'idlwave-toolbar-remove-everywhere) );; End can define toolbar -(defun idlwave-toolbar-add () - "Add the IDLWAVE toolbar if appropriate." - (if (and (featurep 'xemacs) ; This is a noop on Emacs - (boundp 'idlwave-toolbar-is-possible) - (derived-mode-p 'idlwave-mode 'idlwave-shell-mode)) - (set-specifier default-toolbar (cons (current-buffer) - idlwave-toolbar)))) - -(defun idlwave-toolbar-remove () - "Add the IDLWAVE toolbar if appropriate." - (if (and (featurep 'xemacs) ; This is a noop on Emacs - (boundp 'idlwave-toolbar-is-possible) - (derived-mode-p 'idlwave-mode 'idlwave-shell-mode)) - (remove-specifier default-toolbar (current-buffer)))) +(define-obsolete-function-alias 'idlwave-toolbar-add #'ignore "28.1") + +(define-obsolete-function-alias 'idlwave-toolbar-remove #'ignore "28.1") (defvar idlwave-shell-mode-map) (defvar idlwave-mode-map) @@ -898,57 +881,40 @@ static char * file[] = { "Add the toolbar in all appropriate buffers." (when (boundp 'idlwave-toolbar-is-possible) - ;; First make sure new buffers will get the toolbar - (add-hook 'idlwave-mode-hook 'idlwave-toolbar-add) ;; Then add it to all existing buffers - (if (featurep 'xemacs) - ;; For XEmacs, map over all buffers to add toolbar - (save-excursion - (mapcar (lambda (buf) - (set-buffer buf) - (idlwave-toolbar-add)) - (buffer-list))) - ;; For Emacs, add the key definitions to the mode maps - (mapc (lambda (x) - (let* ((icon (aref x 0)) - (func (aref x 1)) - (show (aref x 2)) - (help (aref x 3)) - (key (vector 'tool-bar func)) - (def (list 'menu-item - "" - func - :image (symbol-value icon) - :visible show - :help help))) - (define-key idlwave-mode-map key def) - (define-key idlwave-shell-mode-map key def))) - (reverse idlwave-toolbar))) + ;; For Emacs, add the key definitions to the mode maps + (mapc (lambda (x) + (let* ((icon (aref x 0)) + (func (aref x 1)) + (show (aref x 2)) + (help (aref x 3)) + (key (vector 'tool-bar func)) + (def (list 'menu-item + "" + func + :image (symbol-value icon) + :visible show + :help help))) + (define-key idlwave-mode-map key def) + (define-key idlwave-shell-mode-map key def))) + (reverse idlwave-toolbar)) (setq idlwave-toolbar-visible t))) (defun idlwave-toolbar-remove-everywhere () "Remove the toolbar in all appropriate buffers." ;; First make sure new buffers won't get the toolbar (when idlwave-toolbar-is-possible - (remove-hook 'idlwave-mode-hook 'idlwave-toolbar-add) ;; Then remove it in all existing buffers. - (if (featurep 'xemacs) - ;; For XEmacs, map over all buffers to remove toolbar - (save-excursion - (mapcar (lambda (buf) - (set-buffer buf) - (idlwave-toolbar-remove)) - (buffer-list))) - ;; For Emacs, remove the key definitions from the mode maps - (mapc (lambda (x) - (let* (;;(icon (aref x 0)) - (func (aref x 1)) - ;;(show (aref x 2)) - ;;(help (aref x 3)) - (key (vector 'tool-bar func))) - (define-key idlwave-mode-map key nil) - (define-key idlwave-shell-mode-map key nil))) - idlwave-toolbar)) + ;; For Emacs, remove the key definitions from the mode maps + (mapc (lambda (x) + (let* (;;(icon (aref x 0)) + (func (aref x 1)) + ;;(show (aref x 2)) + ;;(help (aref x 3)) + (key (vector 'tool-bar func))) + (define-key idlwave-mode-map key nil) + (define-key idlwave-shell-mode-map key nil))) + idlwave-toolbar) (setq idlwave-toolbar-visible nil))) (defun idlwave-toolbar-toggle (&optional force-on) @@ -956,11 +922,8 @@ static char * file[] = { (if idlwave-toolbar-visible (or force-on (idlwave-toolbar-remove-everywhere)) (idlwave-toolbar-add-everywhere)) - ;; Now make sure this - (if (featurep 'xemacs) - nil ; no action necessary, toolbar gets updated automatically - ;; On Emacs, redraw the frame to make sure the Toolbar is updated. - (redraw-frame))) + ;; On Emacs, redraw the frame to make sure the Toolbar is updated. + (redraw-frame)) (provide 'idlw-toolbar) (provide 'idlwave-toolbar) diff --git a/lisp/progmodes/idlwave.el b/lisp/progmodes/idlwave.el index b72d9da748..f53f3f3b99 100644 --- a/lisp/progmodes/idlwave.el +++ b/lisp/progmodes/idlwave.el @@ -1,4 +1,4 @@ -;; idlwave.el --- IDL editing mode for GNU Emacs +;; idlwave.el --- IDL editing mode for GNU Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. @@ -781,7 +781,7 @@ definitions, use the command `list-abbrevs', for abbrevs that move point. Moving point is useful, for example, to place point between parentheses of expanded functions. -See `idlwave-check-abbrev'." +See `idlwave-modify-abbrev'." :group 'idlwave-abbrev-and-indent-action :type 'boolean) @@ -819,18 +819,19 @@ Has effect only if in abbrev-mode." ;; Example actions: ;; ;; Capitalize system vars -;; (idlwave-action-and-binding idlwave-sysvar '(capitalize-word 1) t) +;; (idlwave-action-and-binding idlwave-sysvar +;; (lambda (_) (capitalize-word 1)) t) ;; ;; Capitalize procedure name ;; (idlwave-action-and-binding "\\<\\(pro\\|function\\)\\>[ \t]*\\<" -;; '(capitalize-word 1) t) +;; (lambda (_) (capitalize-word 1)) t) ;; ;; Capitalize common block name ;; (idlwave-action-and-binding "\\[ \t]+\\<" -;; '(capitalize-word 1) t) +;; (lambda (_) (capitalize-word 1)) t) ;; Capitalize label ;; (idlwave-action-and-binding (concat "^[ \t]*" idlwave-label) -;; '(capitalize-word -1) t) +;; (lambda (_) (capitalize-word 1)) t) (defvar idlwave-indent-action-table nil "Associated array containing action lists of search string (car), @@ -1121,91 +1122,101 @@ As a user, you should not set this to t.") "\\<\\(&&\\|and\\|b\\(egin\\|reak\\)\\|c\\(ase\\|o\\(mpile_opt\\|ntinue\\)\\)\\|do\\|e\\(lse\\|nd\\(case\\|else\\|for\\|if\\|rep\\|switch\\|while\\)?\\|q\\)\\|for\\(ward_function\\)?\\|g\\(oto\\|[et]\\)\\|i\\(f\\|nherits\\)\\|l[et]\\|mod\\|n\\(e\\|ot\\)\\|o\\(n_\\(error\\|ioerror\\)\\|[fr]\\)\\|re\\(peat\\|turn\\)\\|switch\\|then\\|until\\|while\\|xor\\|||\\)\\>") -(let* (;; Procedure declarations. Fontify keyword plus procedure name. - ;; Function declarations. Fontify keyword plus function name. - (pros-and-functions - '("\\<\\(function\\|pro\\)\\>[ \t]+\\(\\sw+\\(::\\sw+\\)?\\)" - (1 font-lock-keyword-face) - (2 font-lock-function-name-face nil t))) - - ;; Common blocks - (common-blocks - '("\\<\\(common\\)\\>[ \t]*\\(\\sw+\\)?[ \t]*,?" - (1 font-lock-keyword-face) ; "common" - (2 font-lock-constant-face nil t) ; block name - ("[ \t]*\\(\\sw+\\)[ ,]*" - ;; Start with point after block name and comma - nil nil (1 font-lock-variable-name-face)))) ; variable names - - ;; Batch files - (batch-files - '("^[ \t]*\\(@[^ \t\n]+\\)" (1 font-lock-string-face))) - - ;; Labels - (label - '("^[ \t]*\\([a-zA-Z]\\sw*:\\)" (1 font-lock-constant-face))) - - ;; The goto statement and its label - (goto - '("\\(goto\\)[ \t]*,[ \t]*\\([a-zA-Z]\\sw*\\)" - (1 font-lock-keyword-face) - (2 font-lock-constant-face))) - - ;; Tags in structure definitions. Note that this definition - ;; actually collides with labels, so we have to use the same - ;; face. It also matches named subscript ranges, - ;; e.g. vec{bottom:top]. No good way around this. - (structtag - '("\\<\\([a-zA-Z][a-zA-Z0-9_]*:\\)[^:]" (1 font-lock-constant-face))) - - ;; Structure names - (structname - '("\\({\\|\\#]" (0 font-lock-keyword-face))) - - ;; All operators (not used because too noisy) - ;; (all-operators - ;; '("[-*^#+<>/]" (0 font-lock-keyword-face))) - - ;; Arrows with text property `idlwave-class' - (class-arrows - '(idlwave-match-class-arrows (0 idlwave-class-arrow-face)))) +(defmacro idlwave--dlet (binders &rest body) + "Like `dlet' but without warnings about non-prefixed var names." + (declare (indent 1) (debug let)) + (let ((vars (mapcar (lambda (binder) + (if (consp binder) (car binder) binder)) + binders))) + `(with-suppressed-warnings ((lexical ,@vars)) + (dlet ,binders ,@body)))) + +(idlwave--dlet + (;; Procedure declarations. Fontify keyword plus procedure name. + ;; Function declarations. Fontify keyword plus function name. + (pros-and-functions + '("\\<\\(function\\|pro\\)\\>[ \t]+\\(\\sw+\\(::\\sw+\\)?\\)" + (1 font-lock-keyword-face) + (2 font-lock-function-name-face nil t))) + + ;; Common blocks + (common-blocks + '("\\<\\(common\\)\\>[ \t]*\\(\\sw+\\)?[ \t]*,?" + (1 font-lock-keyword-face) ; "common" + (2 font-lock-constant-face nil t) ; block name + ("[ \t]*\\(\\sw+\\)[ ,]*" + ;; Start with point after block name and comma + nil nil (1 font-lock-variable-name-face)))) ; variable names + + ;; Batch files + (batch-files + '("^[ \t]*\\(@[^ \t\n]+\\)" (1 font-lock-string-face))) + + ;; Labels + (label + '("^[ \t]*\\([a-zA-Z]\\sw*:\\)" (1 font-lock-constant-face))) + + ;; The goto statement and its label + (goto + '("\\(goto\\)[ \t]*,[ \t]*\\([a-zA-Z]\\sw*\\)" + (1 font-lock-keyword-face) + (2 font-lock-constant-face))) + + ;; Tags in structure definitions. Note that this definition + ;; actually collides with labels, so we have to use the same + ;; face. It also matches named subscript ranges, + ;; e.g. vec{bottom:top]. No good way around this. + (structtag + '("\\<\\([a-zA-Z][a-zA-Z0-9_]*:\\)[^:]" (1 font-lock-constant-face))) + + ;; Structure names + (structname + '("\\({\\|\\#]" (0 font-lock-keyword-face))) + + ;; All operators (not used because too noisy) + ;; (all-operators + ;; '("[-*^#+<>/]" (0 font-lock-keyword-face))) + + ;; Arrows with text property `idlwave-class' + (class-arrows + '(idlwave-match-class-arrows (0 idlwave-class-arrow-face)))) (defconst idlwave-font-lock-keywords-1 (list pros-and-functions batch-files) "Subdued level highlighting for IDLWAVE mode.") (defconst idlwave-font-lock-keywords-2 - (mapcar 'symbol-value idlwave-default-font-lock-items) + (mapcar #'symbol-value idlwave-default-font-lock-items) "Medium level highlighting for IDLWAVE mode.") (defconst idlwave-font-lock-keywords-3 - (list pros-and-functions - batch-files - idlwave-idl-keywords - label goto - structtag - structname - common-blocks - keyword-parameters - system-variables + (list pros-and-functions + batch-files + idlwave-idl-keywords + label goto + structtag + structname + common-blocks + keyword-parameters + system-variables class-arrows) "Gaudy level highlighting for IDLWAVE mode.")) @@ -1312,13 +1323,16 @@ blocks starting with a BEGIN statement. The matches must have associations (cons 'call (list (concat "\\(" idlwave-variable "\\) *= *" "\\(" idlwave-method-call "\\s *\\)?" idlwave-identifier - "\\s *(") nil)) + "\\s *(") + nil)) (cons 'call (list (concat "\\(" idlwave-method-call "\\s *\\)?" idlwave-identifier - "\\( *\\($\\|\\$\\)\\|\\s *,\\)") nil)) + "\\( *\\($\\|\\$\\)\\|\\s *,\\)") + nil)) (cons 'assign (list (concat - "\\(" idlwave-variable "\\) *=") nil))) + "\\(" idlwave-variable "\\) *=") + nil))) "Associated list of statement matching regular expressions. Each regular expression matches the start of an IDL statement. @@ -1333,10 +1347,6 @@ list order matters since matching an assignment statement exactly is not possible without parsing. Thus assignment statement become just the leftover unidentified statements containing an equal sign.") -;; FIXME: This var seems to only ever be set, but never actually used! -(defvar idlwave-fill-function 'auto-fill-function - "IDL mode auto fill function.") - (defvar idlwave-comment-indent-function 'comment-indent-function "IDL mode comment indent function.") @@ -1353,28 +1363,9 @@ Normally a space.") (defconst idlwave-mode-version "6.1_em22") -(defmacro idlwave-keyword-abbrev (&rest args) - "Creates a function for abbrev hooks to call `idlwave-check-abbrev' with args." - `(lambda () - ,(append '(idlwave-check-abbrev) args))) - -;; If I take the time I can replace idlwave-keyword-abbrev with -;; idlwave-code-abbrev and remove the quoted abbrev check from -;; idlwave-check-abbrev. Then, e.g, (idlwave-keyword-abbrev 0 t) becomes -;; (idlwave-code-abbrev idlwave-check-abbrev 0 t). In fact I should change -;; the name of idlwave-check-abbrev to something like idlwave-modify-abbrev. - -(defmacro idlwave-code-abbrev (&rest args) - "Creates a function for abbrev hooks that ensures abbrevs are not quoted. -Specifically, if the abbrev is in a comment or string it is unexpanded. -Otherwise ARGS forms a list that is evaluated." - ;; FIXME: it would probably be better to rely on the new :enable-function - ;; to enforce the "don't expand in comments or strings". - `(lambda () - ,(prin1-to-string args) ;; Puts the code in the doc string - (if (idlwave-quoted) - (progn (unexpand-abbrev) nil) - ,(append args)))) +(defun idlwave-keyword-abbrev (&rest args) + "Create a function for abbrev hooks to call `idlwave-modify-abbrev' with args." + (lambda () (append #'idlwave-modify-abbrev args))) (autoload 'idlwave-shell "idlw-shell" "Run an inferior IDL, with I/O through buffer `(idlwave-shell-buffer)'." t) @@ -1388,41 +1379,41 @@ Otherwise ARGS forms a list that is evaluated." (autoload 'idlwave-shell-run-region "idlw-shell" "Compile and run the region." t) -(fset 'idlwave-debug-map (make-sparse-keymap)) +(defalias 'idlwave-debug-map (make-sparse-keymap)) (defvar idlwave-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\C-c " 'idlwave-hard-tab) - (define-key map [(control tab)] 'idlwave-hard-tab) - ;;(define-key map "\C-c\C- " 'idlwave-hard-tab) - (define-key map "'" 'idlwave-show-matching-quote) - (define-key map "\"" 'idlwave-show-matching-quote) - (define-key map "\C-g" 'idlwave-keyboard-quit) - (define-key map "\C-c;" 'idlwave-toggle-comment-region) - (define-key map "\C-\M-a" 'idlwave-beginning-of-subprogram) - (define-key map "\C-\M-e" 'idlwave-end-of-subprogram) - (define-key map "\C-c{" 'idlwave-beginning-of-block) - (define-key map "\C-c}" 'idlwave-end-of-block) - (define-key map "\C-c]" 'idlwave-close-block) - (define-key map [(meta control h)] 'idlwave-mark-subprogram) - (define-key map "\M-\C-n" 'idlwave-forward-block) - (define-key map "\M-\C-p" 'idlwave-backward-block) - (define-key map "\M-\C-d" 'idlwave-down-block) - (define-key map "\M-\C-u" 'idlwave-backward-up-block) - (define-key map "\M-\r" 'idlwave-split-line) - (define-key map "\M-\C-q" 'idlwave-indent-subprogram) - (define-key map "\C-c\C-p" 'idlwave-previous-statement) - (define-key map "\C-c\C-n" 'idlwave-next-statement) - ;; (define-key map "\r" 'idlwave-newline) - ;; (define-key map "\t" 'idlwave-indent-line) - (define-key map [(shift iso-lefttab)] 'idlwave-indent-statement) - (define-key map "\C-c\C-a" 'idlwave-auto-fill-mode) - (define-key map "\M-q" 'idlwave-fill-paragraph) - (define-key map "\M-s" 'idlwave-edit-in-idlde) - (define-key map "\C-c\C-h" 'idlwave-doc-header) - (define-key map "\C-c\C-m" 'idlwave-doc-modification) - (define-key map "\C-c\C-c" 'idlwave-case) - (define-key map "\C-c\C-d" 'idlwave-debug-map) + (define-key map "\C-c " #'idlwave-hard-tab) + (define-key map [(control tab)] #'idlwave-hard-tab) + ;;(define-key map "\C-c\C- " #'idlwave-hard-tab) + (define-key map "'" #'idlwave-show-matching-quote) + (define-key map "\"" #'idlwave-show-matching-quote) + (define-key map "\C-g" #'idlwave-keyboard-quit) + (define-key map "\C-c;" #'idlwave-toggle-comment-region) + (define-key map "\C-\M-a" #'idlwave-beginning-of-subprogram) + (define-key map "\C-\M-e" #'idlwave-end-of-subprogram) + (define-key map "\C-c{" #'idlwave-beginning-of-block) + (define-key map "\C-c}" #'idlwave-end-of-block) + (define-key map "\C-c]" #'idlwave-close-block) + (define-key map [(meta control h)] #'idlwave-mark-subprogram) + (define-key map "\M-\C-n" #'idlwave-forward-block) + (define-key map "\M-\C-p" #'idlwave-backward-block) + (define-key map "\M-\C-d" #'idlwave-down-block) + (define-key map "\M-\C-u" #'idlwave-backward-up-block) + (define-key map "\M-\r" #'idlwave-split-line) + (define-key map "\M-\C-q" #'idlwave-indent-subprogram) + (define-key map "\C-c\C-p" #'idlwave-previous-statement) + (define-key map "\C-c\C-n" #'idlwave-next-statement) + ;; (define-key map "\r" #'idlwave-newline) + ;; (define-key map "\t" #'idlwave-indent-line) + (define-key map [(shift iso-lefttab)] #'idlwave-indent-statement) + (define-key map "\C-c\C-a" #'auto-fill-mode) + (define-key map "\M-q" #'idlwave-fill-paragraph) + (define-key map "\M-s" #'idlwave-edit-in-idlde) + (define-key map "\C-c\C-h" #'idlwave-doc-header) + (define-key map "\C-c\C-m" #'idlwave-doc-modification) + (define-key map "\C-c\C-c" #'idlwave-case) + (define-key map "\C-c\C-d" #'idlwave-debug-map) (when (and (listp idlwave-shell-debug-modifiers) (not (equal idlwave-shell-debug-modifiers '()))) ;; Bind the debug commands also with the special modifiers. @@ -1431,38 +1422,39 @@ Otherwise ARGS forms a list that is evaluated." (delq 'shift (copy-sequence idlwave-shell-debug-modifiers)))) (define-key map (vector (append mods-noshift (list (if shift ?C ?c)))) - 'idlwave-shell-save-and-run) + #'idlwave-shell-save-and-run) (define-key map (vector (append mods-noshift (list (if shift ?B ?b)))) - 'idlwave-shell-break-here) + #'idlwave-shell-break-here) (define-key map (vector (append mods-noshift (list (if shift ?E ?e)))) - 'idlwave-shell-run-region))) - (define-key map "\C-c\C-d\C-c" 'idlwave-shell-save-and-run) - (define-key map "\C-c\C-d\C-b" 'idlwave-shell-break-here) - (define-key map "\C-c\C-d\C-e" 'idlwave-shell-run-region) - (define-key map "\C-c\C-f" 'idlwave-for) - ;; (define-key map "\C-c\C-f" 'idlwave-function) - ;; (define-key map "\C-c\C-p" 'idlwave-procedure) - (define-key map "\C-c\C-r" 'idlwave-repeat) - (define-key map "\C-c\C-w" 'idlwave-while) - (define-key map "\C-c\C-k" 'idlwave-kill-autoloaded-buffers) - (define-key map "\C-c\C-s" 'idlwave-shell) - (define-key map "\C-c\C-l" 'idlwave-shell-recenter-shell-window) - (define-key map "\C-c\C-b" 'idlwave-list-buffer-load-path-shadows) - (define-key map "\C-c\C-v" 'idlwave-find-module) - (define-key map "\C-c\C-t" 'idlwave-find-module-this-file) - (define-key map "\C-c?" 'idlwave-routine-info) - (define-key map "\M-?" 'idlwave-context-help) + #'idlwave-shell-run-region))) + (define-key map "\C-c\C-d\C-c" #'idlwave-shell-save-and-run) + (define-key map "\C-c\C-d\C-b" #'idlwave-shell-break-here) + (define-key map "\C-c\C-d\C-e" #'idlwave-shell-run-region) + (define-key map "\C-c\C-f" #'idlwave-for) + ;; (define-key map "\C-c\C-f" #'idlwave-function) + ;; (define-key map "\C-c\C-p" #'idlwave-procedure) + (define-key map "\C-c\C-r" #'idlwave-repeat) + (define-key map "\C-c\C-w" #'idlwave-while) + (define-key map "\C-c\C-k" #'idlwave-kill-autoloaded-buffers) + (define-key map "\C-c\C-s" #'idlwave-shell) + (define-key map "\C-c\C-l" #'idlwave-shell-recenter-shell-window) + (define-key map "\C-c\C-b" #'idlwave-list-buffer-load-path-shadows) + (define-key map "\C-c\C-v" #'idlwave-find-module) + (define-key map "\C-c\C-t" #'idlwave-find-module-this-file) + (define-key map "\C-c?" #'idlwave-routine-info) + (define-key map "\M-?" #'idlwave-context-help) (define-key map [(control meta ?\?)] - 'idlwave-help-assistant-help-with-topic) + #'idlwave-help-assistant-help-with-topic) ;; Pickup both forms of Esc/Meta binding - (define-key map [(meta tab)] 'idlwave-complete) - (define-key map [?\e?\t] 'idlwave-complete) - (define-key map "\M-\C-i" 'idlwave-complete) - (define-key map "\C-c\C-i" 'idlwave-update-routine-info) - (define-key map "\C-c=" 'idlwave-resolve) - (define-key map [(shift mouse-3)] 'idlwave-mouse-context-help) + ;; FIXME: Use `completion-at-point'! + (define-key map [(meta tab)] #'idlwave-complete) + (define-key map [?\e?\t] #'idlwave-complete) + (define-key map "\M-\C-i" #'idlwave-complete) + (define-key map "\C-c\C-i" #'idlwave-update-routine-info) + (define-key map "\C-c=" #'idlwave-resolve) + (define-key map [(shift mouse-3)] #'idlwave-mouse-context-help) map) "Keymap used in IDL mode.") @@ -1501,28 +1493,15 @@ Otherwise ARGS forms a list that is evaluated." st) "Syntax table that treats symbol characters as word characters.") -(defmacro idlwave-with-special-syntax (&rest body) - "Execute BODY with a different syntax table." - `(let ((saved-syntax (syntax-table))) - (unwind-protect - (progn - (set-syntax-table idlwave-find-symbol-syntax-table) - ,@body) - (set-syntax-table saved-syntax)))) - -;(defmacro idlwave-with-special-syntax1 (&rest body) -; "Execute BODY with a different syntax table." -; `(let ((saved-syntax (syntax-table))) -; (unwind-protect -; (progn -; (set-syntax-table idlwave-find-symbol-syntax-table) -; ,@body) -; (set-syntax-table saved-syntax)))) +;;(defmacro idlwave-with-special-syntax (&rest body) +;; "Execute BODY with `idlwave-find-symbol-syntax-table'." +;; `(with-syntax-table idlwave-find-symbol-syntax-table +;; ,@body)) (defun idlwave-action-and-binding (key cmd &optional select) "KEY and CMD are made into a key binding and an indent action. KEY is a string - same as for the `define-key' function. CMD is a -function of no arguments or a list to be evaluated. CMD is bound to +function of one argument. CMD is bound to KEY in `idlwave-mode-map' by defining an anonymous function calling `self-insert-command' followed by CMD. If KEY contains more than one character a binding will only be set if SELECT is `both'. @@ -1539,62 +1518,59 @@ Otherwise, if SELECT is non-nil then only an action is created. Some examples: No spaces before and 1 after a comma - (idlwave-action-and-binding \",\" \\='(idlwave-surround 0 1)) + (idlwave-action-and-binding \",\" (lambda (_) (idlwave-surround 0 1))) A minimum of 1 space before and after `=' (see `idlwave-expand-equal'). - (idlwave-action-and-binding \"=\" \\='(idlwave-expand-equal -1 -1)) + (idlwave-action-and-binding \"=\" (lambda (_) (idlwave-expand-equal -1 -1))) Capitalize system variables - action only - (idlwave-action-and-binding idlwave-sysvar \\='(capitalize-word 1) t)" + (idlwave-action-and-binding idlwave-sysvar (lambda (_) (capitalize-word 1) t))" (if (not (equal select 'noaction)) ;; Add action (let* ((table (if select 'idlwave-indent-action-table 'idlwave-indent-expand-table)) - (table-key (regexp-quote key)) - (cell (assoc table-key (eval table)))) - (if cell - ;; Replace action command - (setcdr cell cmd) - ;; New action - (set table (append (eval table) (list (cons table-key cmd))))))) + (table-key (regexp-quote key))) + (setf (alist-get table-key (symbol-value table) nil nil #'equal) cmd))) ;; Make key binding for action - (if (or (and (null select) (= (length key) 1)) - (equal select 'noaction) - (equal select 'both)) + (if (if (null select) (= (length key) 1) + (memq select '(noaction both))) + ;; FIXME: Use `post-self-insert-hook'! (define-key idlwave-mode-map key - `(lambda () - (interactive) - (self-insert-command 1) - ,(if (listp cmd) cmd (list cmd)))))) + (lambda () + (interactive) + (self-insert-command 1) + (if (functionp cmd) (funcall cmd nil) (eval cmd t)))))) ;; Set action and key bindings. ;; See description of the function `idlwave-action-and-binding'. ;; Automatically add spaces for the following characters ;; Actions for & are complicated by && -(idlwave-action-and-binding "&" 'idlwave-custom-ampersand-surround) +(idlwave-action-and-binding "&" #'idlwave-custom-ampersand-surround) ;; Automatically add spaces to equal sign if not keyword. This needs ;; to go ahead of > and <, so >= and <= will be treated correctly -(idlwave-action-and-binding "=" '(idlwave-expand-equal -1 -1)) +(idlwave-action-and-binding "=" (lambda (_) (idlwave-expand-equal -1 -1))) ;; Actions for > and < are complicated by >=, <=, and ->... -(idlwave-action-and-binding "<" '(idlwave-custom-ltgtr-surround nil)) -(idlwave-action-and-binding ">" '(idlwave-custom-ltgtr-surround 'gtr)) +(idlwave-action-and-binding "<" (lambda (a) (idlwave-custom-ltgtr-surround nil a))) +(idlwave-action-and-binding ">" (lambda (a) (idlwave-custom-ltgtr-surround t a))) -(idlwave-action-and-binding "," '(idlwave-surround 0 -1 1)) +(idlwave-action-and-binding "," (lambda (a) (idlwave-surround 0 -1 1 a))) ;;; ;;; Abbrev Section ;;; -;;; When expanding abbrevs and the abbrev hook moves backward, an extra -;;; space is inserted (this is the space typed by the user to expanded -;;; the abbrev). -;;; -(defvar idlwave-mode-abbrev-table nil - "Abbreviation table used for IDLWAVE mode.") -(define-abbrev-table 'idlwave-mode-abbrev-table ()) +;; When expanding abbrevs and the abbrev hook moves backward, an extra +;; space is inserted (this is the space typed by the user to expanded +;; the abbrev). +;; FIXME: This can be controlled with `no-self-insert' property. +;; +(define-abbrev-table 'idlwave-mode-abbrev-table () + "Abbreviation table used for IDLWAVE mode." + :enable-function (lambda () (not (idlwave-quoted)))) (defun idlwave-define-abbrev (name expansion hook &optional noprefix table) + ;; FIXME: `table' is never passed. "Define-abbrev with backward compatibility. If NOPREFIX is non-nil, don't prepend prefix character. Installs into @@ -1605,8 +1581,8 @@ If NOPREFIX is non-nil, don't prepend prefix character. Installs into expansion hook))) (condition-case nil - (apply 'define-abbrev (append args '(0 t))) - (error (apply 'define-abbrev args))))) + (apply #'define-abbrev (append args '(0 t))) + (error (apply #'define-abbrev args))))) (condition-case nil (modify-syntax-entry (string-to-char idlwave-abbrev-start-char) @@ -1616,15 +1592,15 @@ If NOPREFIX is non-nil, don't prepend prefix character. Installs into ;; ;; Templates ;; -(idlwave-define-abbrev "c" "" (idlwave-code-abbrev idlwave-case)) -(idlwave-define-abbrev "sw" "" (idlwave-code-abbrev idlwave-switch)) -(idlwave-define-abbrev "f" "" (idlwave-code-abbrev idlwave-for)) -(idlwave-define-abbrev "fu" "" (idlwave-code-abbrev idlwave-function)) -(idlwave-define-abbrev "pr" "" (idlwave-code-abbrev idlwave-procedure)) -(idlwave-define-abbrev "r" "" (idlwave-code-abbrev idlwave-repeat)) -(idlwave-define-abbrev "w" "" (idlwave-code-abbrev idlwave-while)) -(idlwave-define-abbrev "i" "" (idlwave-code-abbrev idlwave-if)) -(idlwave-define-abbrev "elif" "" (idlwave-code-abbrev idlwave-elif)) +(idlwave-define-abbrev "c" "" #'idlwave-case) +(idlwave-define-abbrev "sw" "" #'idlwave-switch) +(idlwave-define-abbrev "f" "" #'idlwave-for) +(idlwave-define-abbrev "fu" "" #'idlwave-function) +(idlwave-define-abbrev "pr" "" #'idlwave-procedure) +(idlwave-define-abbrev "r" "" #'idlwave-repeat) +(idlwave-define-abbrev "w" "" #'idlwave-while) +(idlwave-define-abbrev "i" "" #'idlwave-if) +(idlwave-define-abbrev "elif" "" #'idlwave-elif) ;; ;; Keywords, system functions, conversion routines ;; @@ -1639,15 +1615,15 @@ If NOPREFIX is non-nil, don't prepend prefix character. Installs into (idlwave-define-abbrev "cc" "complex()" (idlwave-keyword-abbrev 1)) (idlwave-define-abbrev "cd" "double()" (idlwave-keyword-abbrev 1)) (idlwave-define-abbrev "e" "else" (idlwave-keyword-abbrev 0 t)) -(idlwave-define-abbrev "ec" "endcase" 'idlwave-show-begin) -(idlwave-define-abbrev "es" "endswitch" 'idlwave-show-begin) -(idlwave-define-abbrev "ee" "endelse" 'idlwave-show-begin) -(idlwave-define-abbrev "ef" "endfor" 'idlwave-show-begin) -(idlwave-define-abbrev "ei" "endif else if" 'idlwave-show-begin) -(idlwave-define-abbrev "el" "endif else" 'idlwave-show-begin) -(idlwave-define-abbrev "en" "endif" 'idlwave-show-begin) -(idlwave-define-abbrev "er" "endrep" 'idlwave-show-begin) -(idlwave-define-abbrev "ew" "endwhile" 'idlwave-show-begin) +(idlwave-define-abbrev "ec" "endcase" #'idlwave-show-begin) +(idlwave-define-abbrev "es" "endswitch" #'idlwave-show-begin) +(idlwave-define-abbrev "ee" "endelse" #'idlwave-show-begin) +(idlwave-define-abbrev "ef" "endfor" #'idlwave-show-begin) +(idlwave-define-abbrev "ei" "endif else if" #'idlwave-show-begin) +(idlwave-define-abbrev "el" "endif else" #'idlwave-show-begin) +(idlwave-define-abbrev "en" "endif" #'idlwave-show-begin) +(idlwave-define-abbrev "er" "endrep" #'idlwave-show-begin) +(idlwave-define-abbrev "ew" "endwhile" #'idlwave-show-begin) (idlwave-define-abbrev "g" "goto," (idlwave-keyword-abbrev 0 t)) (idlwave-define-abbrev "h" "help," (idlwave-keyword-abbrev 0)) (idlwave-define-abbrev "k" "keyword_set()" (idlwave-keyword-abbrev 1)) @@ -1695,15 +1671,15 @@ If NOPREFIX is non-nil, don't prepend prefix character. Installs into (idlwave-define-abbrev "continue" "continue" (idlwave-keyword-abbrev 0 t) t) (idlwave-define-abbrev "do" "do" (idlwave-keyword-abbrev 0 t) t) (idlwave-define-abbrev "else" "else" (idlwave-keyword-abbrev 0 t) t) -(idlwave-define-abbrev "end" "end" 'idlwave-show-begin-check t) -(idlwave-define-abbrev "endcase" "endcase" 'idlwave-show-begin-check t) -(idlwave-define-abbrev "endelse" "endelse" 'idlwave-show-begin-check t) -(idlwave-define-abbrev "endfor" "endfor" 'idlwave-show-begin-check t) -(idlwave-define-abbrev "endif" "endif" 'idlwave-show-begin-check t) -(idlwave-define-abbrev "endrep" "endrep" 'idlwave-show-begin-check t) -(idlwave-define-abbrev "endswitch" "endswitch" 'idlwave-show-begin-check t) -(idlwave-define-abbrev "endwhi" "endwhi" 'idlwave-show-begin-check t) -(idlwave-define-abbrev "endwhile" "endwhile" 'idlwave-show-begin-check t) +(idlwave-define-abbrev "end" "end" #'idlwave-show-begin-check t) +(idlwave-define-abbrev "endcase" "endcase" #'idlwave-show-begin-check t) +(idlwave-define-abbrev "endelse" "endelse" #'idlwave-show-begin-check t) +(idlwave-define-abbrev "endfor" "endfor" #'idlwave-show-begin-check t) +(idlwave-define-abbrev "endif" "endif" #'idlwave-show-begin-check t) +(idlwave-define-abbrev "endrep" "endrep" #'idlwave-show-begin-check t) +(idlwave-define-abbrev "endswitch" "endswitch" #'idlwave-show-begin-check t) +(idlwave-define-abbrev "endwhi" "endwhi" #'idlwave-show-begin-check t) +(idlwave-define-abbrev "endwhile" "endwhile" #'idlwave-show-begin-check t) (idlwave-define-abbrev "eq" "eq" (idlwave-keyword-abbrev 0 t) t) (idlwave-define-abbrev "for" "for" (idlwave-keyword-abbrev 0 t) t) (idlwave-define-abbrev "function" "function" (idlwave-keyword-abbrev 0 t) t) @@ -1763,7 +1739,7 @@ The main features of this mode are Use \\[idlwave-fill-paragraph] to refill a paragraph inside a comment. The indentation of the second line of the paragraph relative to the first will be retained. Use - \\[idlwave-auto-fill-mode] to toggle auto-fill mode for these + \\[auto-fill-mode] to toggle auto-fill mode for these comments. When the variable `idlwave-fill-comment-line-only' is nil, code can also be auto-filled and auto-indented. @@ -1861,7 +1837,7 @@ The main features of this mode are (message "Emacs IDLWAVE mode version %s." idlwave-mode-version)) (setq idlwave-startup-message nil) - (set (make-local-variable 'indent-line-function) 'idlwave-indent-and-action) + (set (make-local-variable 'indent-line-function) #'idlwave-indent-and-action) (set (make-local-variable idlwave-comment-indent-function) #'idlwave-comment-hook) @@ -1875,7 +1851,7 @@ The main features of this mode are (setq abbrev-mode t) - (set (make-local-variable idlwave-fill-function) 'idlwave-auto-fill) + (set (make-local-variable 'normal-auto-fill-function) #'idlwave-auto-fill) (setq comment-end "") (set (make-local-variable 'comment-multi-line) nil) (set (make-local-variable 'paragraph-separate) @@ -1886,26 +1862,27 @@ The main features of this mode are ;; ChangeLog (set (make-local-variable 'add-log-current-defun-function) - 'idlwave-current-routine-fullname) + #'idlwave-current-routine-fullname) ;; Set tag table list to use IDLTAGS as file name. (if (boundp 'tag-table-alist) - (add-to-list 'tag-table-alist '("\\.pro$" . "IDLTAGS"))) + (add-to-list 'tag-table-alist '("\\.pro\\'" . "IDLTAGS"))) ;; Font-lock additions (set (make-local-variable 'font-lock-defaults) idlwave-font-lock-defaults) (set (make-local-variable 'font-lock-mark-block-function) - 'idlwave-mark-subprogram) + #'idlwave-mark-subprogram) (set (make-local-variable 'font-lock-fontify-region-function) - 'idlwave-font-lock-fontify-region) + #'idlwave-font-lock-fontify-region) ;; Imenu setup - (set (make-local-variable 'imenu-create-index-function) - 'imenu-default-create-index-function) + ;;(set (make-local-variable 'imenu-create-index-function) + ;; ;; FIXME: Why set it explicitly to the value it already has? + ;; #'imenu-default-create-index-function) (set (make-local-variable 'imenu-extract-index-name-function) - 'idlwave-unit-name) + #'idlwave-unit-name) (set (make-local-variable 'imenu-prev-index-position-function) - 'idlwave-prev-index-position) + #'idlwave-prev-index-position) ;; HideShow setup (add-to-list 'hs-special-modes-alist @@ -1916,12 +1893,12 @@ The main features of this mode are 'idlwave-forward-block nil)) ;; Make a local post-command-hook and add our hook to it - (add-hook 'post-command-hook 'idlwave-command-hook nil 'local) + (add-hook 'post-command-hook #'idlwave-command-hook nil 'local) ;; Make local hooks for buffer updates - (add-hook 'kill-buffer-hook 'idlwave-kill-buffer-update nil 'local) - (add-hook 'after-save-hook 'idlwave-save-buffer-update nil 'local) - (add-hook 'after-save-hook 'idlwave-revoke-license-to-kill nil 'local) + (add-hook 'kill-buffer-hook #'idlwave-kill-buffer-update nil 'local) + (add-hook 'after-save-hook #'idlwave-save-buffer-update nil 'local) + (add-hook 'after-save-hook #'idlwave-revoke-license-to-kill nil 'local) ;; Setup directories and file, if necessary (idlwave-setup) @@ -1974,29 +1951,27 @@ The main features of this mode are ;;; This stuff is experimental -(defvar idlwave-command-hook nil - "If non-nil, a list that can be evaluated using `eval'. +(defvar idlwave--command-function nil + "If non-nil, a function called from `post-command-hook'. It is evaluated in the lisp function `idlwave-command-hook' which is placed in `post-command-hook'.") (defun idlwave-command-hook () "Command run after every command. -Evaluates a non-nil value of the *variable* `idlwave-command-hook' and +Evaluates a non-nil value of the *variable* `idlwave--command-function' and sets the variable to zero afterwards." - (and idlwave-command-hook - (listp idlwave-command-hook) - (condition-case nil - (eval idlwave-command-hook) - (error nil))) - (setq idlwave-command-hook nil)) + (and idlwave--command-function + (with-demoted-errors "idlwave-command-hook: %S" + (funcall (prog1 idlwave--command-function + (setq idlwave--command-function nil)))))) ;;; End experiment ;; It would be better to use expand.el for better abbrev handling and ;; versatility. -(defun idlwave-check-abbrev (arg &optional reserved) - "Reverse abbrev expansion if in comment or string. +(defun idlwave-modify-abbrev (arg &optional reserved) + "Tweak the abbrev we just expanded. Argument ARG is the number of characters to move point backward if `idlwave-abbrev-move' is non-nil. If optional argument RESERVED is non-nil then the expansion @@ -2006,21 +1981,16 @@ Otherwise, the abbrev will be capitalized if `idlwave-abbrev-change-case' is non-nil, unless its value is `down' in which case the abbrev will be made into all lowercase. Returns non-nil if abbrev is left expanded." - (if (idlwave-quoted) - (progn (unexpand-abbrev) - nil) - (if (and reserved idlwave-reserved-word-upcase) - (upcase-region last-abbrev-location (point)) - (cond - ((equal idlwave-abbrev-change-case 'down) - (downcase-region last-abbrev-location (point))) - (idlwave-abbrev-change-case - (upcase-region last-abbrev-location (point))))) - (if (and idlwave-abbrev-move (> arg 0)) - (if (boundp 'post-command-hook) - (setq idlwave-command-hook (list 'backward-char (1+ arg))) - (backward-char arg))) - t)) + (if (and reserved idlwave-reserved-word-upcase) + (upcase-region last-abbrev-location (point)) + (cond + ((equal idlwave-abbrev-change-case 'down) + (downcase-region last-abbrev-location (point))) + (idlwave-abbrev-change-case + (upcase-region last-abbrev-location (point))))) + (if (and idlwave-abbrev-move (> arg 0)) + (setq idlwave--command-function (lambda () (backward-char (1+ arg))))) + t) (defun idlwave-in-comment () "Return t if point is inside a comment, nil otherwise." @@ -2047,7 +2017,7 @@ Returns point if comment found and nil otherwise." (backward-char 1) (point))))) -(define-obsolete-function-alias 'idlwave-region-active-p 'use-region-p "28.1") +(define-obsolete-function-alias 'idlwave-region-active-p #'use-region-p "28.1") (defun idlwave-show-matching-quote () "Insert quote and show matching quote if this is end of a string." @@ -2067,13 +2037,12 @@ Returns point if comment found and nil otherwise." (defun idlwave-show-begin-check () "Ensure that the previous word was a token before `idlwave-show-begin'. An END token must be preceded by whitespace." - (if (not (idlwave-quoted)) - (if - (save-excursion - (backward-word-strictly 1) - (backward-char 1) - (looking-at "[ \t\n\f]")) - (idlwave-show-begin)))) + (if + (save-excursion + (backward-word-strictly 1) + (backward-char 1) + (looking-at "[ \t\n\f]")) + (idlwave-show-begin))) (defun idlwave-show-begin () "Find the start of current block and blinks to it for a second. @@ -2088,7 +2057,7 @@ Also checks if the correct END statement has been used." begin-pos end-pos end end1 ) (if idlwave-reindent-end (idlwave-indent-line)) (setq last-abbrev-location (marker-position last-abbrev-marker)) - (when (and (idlwave-check-abbrev 0 t) + (when (and (idlwave-modify-abbrev 0 t) idlwave-show-block) (save-excursion ;; Move inside current block @@ -2178,11 +2147,11 @@ Also checks if the correct END statement has been used." (next-char (char-after (point))) (method-invoke (and gtr (eq prev-char ?-))) (len (if method-invoke 2 1))) - (unless (eq next-char ?=) + (unless (eq next-char ?=) ;; Key binding: pad only on left, to save for possible >=/<= (idlwave-surround -1 (if (or is-action method-invoke) -1) len)))) -(defun idlwave-surround (&optional before after length is-action) +(defun idlwave-surround (&optional before after length _is-action) "Surround the LENGTH characters before point with blanks. LENGTH defaults to 1. Optional arguments BEFORE and AFTER affect the behavior before and @@ -2641,7 +2610,7 @@ statement." (if st (append st (match-end 0)))))) -(defun idlwave-expand-equal (&optional before after is-action) +(defun idlwave-expand-equal (&optional before after _is-action) "Pad `=' with spaces. Two cases: Assignment statement, and keyword assignment. Which case is determined using `idlwave-start-of-substatement' and @@ -2749,10 +2718,10 @@ If the optional argument EXPAND is non-nil then the actions in ;; Before indenting, run action routines. ;; (if (and expand idlwave-do-actions) - (mapc 'idlwave-do-action idlwave-indent-expand-table)) + (mapc #'idlwave-do-action idlwave-indent-expand-table)) ;; (if idlwave-do-actions - (mapc 'idlwave-do-action idlwave-indent-action-table)) + (mapc #'idlwave-do-action idlwave-indent-action-table)) ;; ;; No longer expand abbrevs on the line. The user can do this ;; manually using expand-region-abbrevs. @@ -2781,18 +2750,19 @@ If the optional argument EXPAND is non-nil then the actions in (defun idlwave-do-action (action) "Perform an action repeatedly on a line. ACTION is a list (REG . FUNC). REG is a regular expression. FUNC is -either a function name to be called with `funcall' or a list to be -evaluated with `eval'. The action performed by FUNC should leave -point after the match for REG - otherwise an infinite loop may be -entered. FUNC is always passed a final argument of `is-action', so it +either a function which will be called with one argument `is-action' or +a list to be evaluated with `eval'. +The action performed by FUNC should leave point after the match for REG +- otherwise an infinite loop may be entered. +FUNC is always passed a final argument of `is-action', so it can discriminate between being run as an action, or a key binding." (let ((action-key (car action)) (action-routine (cdr action))) (beginning-of-line) (while (idlwave-look-at action-key) - (if (listp action-routine) - (eval (append action-routine '('is-action))) - (funcall action-routine 'is-action))))) + (if (functionp action-routine) + (funcall action-routine 'is-action) + (eval (append action-routine '('is-action)) t))))) (defun idlwave-indent-to (col &optional min) "Indent from point with spaces until column COL. @@ -3053,7 +3023,7 @@ Return value is the beginning of the match or (in case of failure) nil." (let ((case-fold-search t) (search-func (if (> dir 0) 're-search-forward 're-search-backward)) found) - (idlwave-with-special-syntax + (with-syntax-table idlwave-find-symbol-syntax-table (save-excursion (catch 'exit (while (funcall search-func key-re limit t) @@ -3181,7 +3151,7 @@ If successful leaves point after the match, otherwise, does not move point." (if cont (idlwave-end-of-statement) (end-of-line)) (point))) found) - (idlwave-with-special-syntax + (with-syntax-table idlwave-find-symbol-syntax-table (if beg (idlwave-beginning-of-statement)) (while (and (setq found (re-search-forward regexp eos t)) (idlwave-quoted)))) @@ -3465,25 +3435,7 @@ if `idlwave-auto-fill-split-string' is non-nil." (idlwave-indent-line)) ))))) -(defun idlwave-auto-fill-mode (arg) - "Toggle auto-fill mode for IDL mode. -With arg, turn auto-fill mode on if arg is positive. -In auto-fill mode, inserting a space at a column beyond `fill-column' -automatically breaks the line at a previous space." - (interactive "P") - (prog1 (set idlwave-fill-function - (if (if (null arg) - (not (symbol-value idlwave-fill-function)) - (> (prefix-numeric-value arg) 0)) - 'idlwave-auto-fill - nil)) - ;; update mode-line - (set-buffer-modified-p (buffer-modified-p)))) - -;(defun idlwave-fill-routine-call () -; "Fill a routine definition or statement, indenting appropriately." -; (let ((where (idlwave-where))))) - +(define-obsolete-function-alias 'idlwave-auto-fill-mode #'auto-fill-mode "28.1") (defun idlwave-doc-header (&optional nomark) "Insert a documentation header at the beginning of the unit. @@ -3578,6 +3530,7 @@ Calling from a program, arguments are START END." (defun idlwave-quoted () "Return t if point is in a comment or quoted string. Returns nil otherwise." + ;; FIXME: Use (nth 8 (synx-ppss))! (and (or (idlwave-in-comment) (idlwave-in-quote)) t)) (defun idlwave-in-quote () @@ -3858,7 +3811,7 @@ Intended for `after-save-hook'." (setq idlwave-outlawed-buffers (delq entry idlwave-outlawed-buffers))) ;; Remove this function from the hook. - (remove-hook 'after-save-hook 'idlwave-revoke-license-to-kill 'local))) + (remove-hook 'after-save-hook #'idlwave-revoke-license-to-kill 'local))) (defvar idlwave-path-alist) (defun idlwave-locate-lib-file (file) @@ -4098,10 +4051,10 @@ blank lines." (set (idlwave-sintern-set name 'class idlwave-sint-classes set)) (name))) -(defun idlwave-sintern-dir (dir &optional set) +(defun idlwave-sintern-dir (dir &optional _set) (car (or (member dir idlwave-sint-dirs) (setq idlwave-sint-dirs (cons dir idlwave-sint-dirs))))) -(defun idlwave-sintern-libname (name &optional set) +(defun idlwave-sintern-libname (name &optional _set) (car (or (member name idlwave-sint-libnames) (setq idlwave-sint-libnames (cons name idlwave-sint-libnames))))) @@ -4169,7 +4122,7 @@ the base of the directory." ;; Creating new sintern tables -(defun idlwave-new-sintern-type (tag) +(defmacro idlwave-new-sintern-type (tag) "Define a variable and a function to sintern the new type TAG. This defines the function `idlwave-sintern-TAG' and the variable `idlwave-sint-TAGs'." @@ -4177,15 +4130,15 @@ This defines the function `idlwave-sintern-TAG' and the variable (names (concat name "s")) (var (intern (concat "idlwave-sint-" names))) (func (intern (concat "idlwave-sintern-" name)))) - (set var nil) ; initial value of the association list - (fset func ; set the function - `(lambda (name &optional set) - (cond ((not (stringp name)) name) - ((cdr (assoc (downcase name) ,var))) - (set - (setq ,var (cons (cons (downcase name) name) ,var)) - name) - (name)))))) + `(progn + (defvar ,var nil) ; initial value of the association list + (defun ,func (name &optional set) + (cond ((not (stringp name)) name) + ((cdr (assoc (downcase name) ,var))) + (set + (push (cons (downcase name) name) ,var) + name) + (name)))))) (defun idlwave-reset-sintern-type (tag) "Reset the sintern variable associated with TAG." @@ -4296,12 +4249,12 @@ will re-read the catalog." "-l" (expand-file-name "~/.emacs") "-l" "idlwave" "-f" "idlwave-rescan-catalog-directories")) - (process (apply 'start-process "idlcat" + (process (apply #'start-process "idlcat" nil emacs args))) (setq idlwave-catalog-process process) (set-process-sentinel process - (lambda (pro why) + (lambda (_pro why) (when (string-match "finished" why) (setq idlwave-routines nil idlwave-system-routines nil @@ -4449,7 +4402,7 @@ information updated immediately, leave NO-CONCATENATE nil." (setq idlwave-load-rinfo-idle-timer (run-with-idle-timer idlwave-init-rinfo-when-idle-after - nil 'idlwave-load-rinfo-next-step))) + nil #'idlwave-load-rinfo-next-step))) (error nil)))) ;;------ XML Help routine info system @@ -4935,7 +4888,7 @@ Cache to disk for quick recovery." (setq idlwave-load-rinfo-idle-timer (run-with-idle-timer idlwave-init-rinfo-when-idle-after - nil 'idlwave-load-rinfo-next-step)))))) + nil #'idlwave-load-rinfo-next-step)))))) (defvar idlwave-after-load-rinfo-hook nil) @@ -5109,7 +5062,7 @@ Can run from `after-save-hook'." (error nil))) (push res routine-lists))))) ;; Concatenate the individual lists and return the result - (apply 'nconc routine-lists))) + (apply #'nconc routine-lists))) (defun idlwave-get-buffer-routine-info () "Scan the current buffer for routine info. Return (PRO-LIST FUNC-LIST)." @@ -5185,10 +5138,10 @@ Can run from `after-save-hook'." (if args (concat (if (string= type "function") "(" ", ") - (mapconcat 'identity args ", ") + (mapconcat #'identity args ", ") (if (string= type "function") ")" "")))) (if keywords - (cons nil (mapcar 'list keywords)) ;No help file + (cons nil (mapcar #'list keywords)) ;No help file nil)))) @@ -5246,7 +5199,7 @@ as last time - so no widget will pop up." (cons x (cdr path-entry)) (list x)))) (idlwave-expand-path idlwave-library-path)) - (mapcar 'list (idlwave-expand-path idlwave-library-path))))) + (mapcar #'list (idlwave-expand-path idlwave-library-path))))) ;; Ask the shell for the path and then run the widget (t @@ -5314,7 +5267,7 @@ directories and save the routine info. (widget-insert " ") (widget-create 'push-button :notify - (lambda (&rest ignore) + (lambda (&rest _ignore) (let ((path-list (widget-get idlwave-widget :path-dirs))) (dolist (x path-list) (unless (memq 'lib (cdr x)) @@ -5324,7 +5277,7 @@ directories and save the routine info. (widget-insert " ") (widget-create 'push-button :notify - (lambda (&rest ignore) + (lambda (&rest _ignore) (let ((path-list (widget-get idlwave-widget :path-dirs))) (dolist (x path-list) (idlwave-path-alist-remove-flag x 'user)) @@ -5332,7 +5285,7 @@ directories and save the routine info. "Deselect All") (widget-insert " ") (widget-create 'push-button - :notify (lambda (&rest ignore) + :notify (lambda (&rest _ignore) (kill-buffer (current-buffer))) "Quit") (widget-insert "\n\n") @@ -5340,7 +5293,7 @@ directories and save the routine info. (widget-insert "Select Directories: \n") (setq idlwave-widget - (apply 'widget-create + (apply #'widget-create 'checklist :value (delq nil (mapcar (lambda (x) (if (memq 'user (cdr x)) @@ -5352,7 +5305,8 @@ directories and save the routine info. (list 'item (if (memq 'lib (cdr x)) (concat "[LIB] " (car x) ) - (car x)))) dirs-list))) + (car x)))) + dirs-list))) (widget-put idlwave-widget :path-dirs dirs-list) (widget-insert "\n") (use-local-map widget-keymap) @@ -5360,14 +5314,14 @@ directories and save the routine info. (goto-char (point-min)) (delete-other-windows)) -(defun idlwave-delete-user-catalog-file (&rest ignore) +(defun idlwave-delete-user-catalog-file (&rest _ignore) (if (yes-or-no-p (format "Delete file %s " idlwave-user-catalog-file)) (progn (delete-file idlwave-user-catalog-file) (message "%s has been deleted" idlwave-user-catalog-file)))) -(defun idlwave-widget-scan-user-lib-files (&rest ignore) +(defun idlwave-widget-scan-user-lib-files (&rest _ignore) ;; Call `idlwave-scan-user-lib-files' with data taken from the widget. (let* ((widget idlwave-widget) (selected-dirs (widget-value widget)) @@ -5517,7 +5471,7 @@ be set to nil to disable library catalog scanning." (let ((dirs (if idlwave-library-path (idlwave-expand-path idlwave-library-path) - (mapcar 'car idlwave-path-alist))) + (mapcar #'car idlwave-path-alist))) (old-libname "") dir-entry dir catalog all-routines) (if message-base (message "%s" message-base)) @@ -5730,11 +5684,10 @@ end (defvar idlwave-completion-help-info nil) (defvar idlwave-completion-help-links nil) (defvar idlwave-current-obj_new-class nil) -(defvar idlwave-complete-special nil) -(defvar method-selector) -(defvar class-selector) -(defvar type-selector) -(defvar super-classes) +(defvar idlwave--method-selector) +(defvar idlwave--class-selector) +(defvar idlwave--type-selector) +(defvar idlwave--super-classes) (defun idlwave-complete (&optional arg module class) "Complete a function, procedure or keyword name at point. @@ -5815,8 +5768,7 @@ When we force a method or a method keyword, CLASS can specify the class." (idlwave-complete-filename)) ;; Check for any special completion functions - ((and idlwave-complete-special - (idlwave-call-special idlwave-complete-special))) + ((run-hook-with-args-until-success 'idlwave-complete-functions)) ((null what) (error "Nothing to complete here")) @@ -5829,22 +5781,26 @@ When we force a method or a method keyword, CLASS can specify the class." ((eq what 'procedure) ;; Complete a procedure name (let* ((cw-list (nth 3 where-list)) - (class-selector (idlwave-determine-class cw-list 'pro)) - (super-classes (unless (idlwave-explicit-class-listed cw-list) - (idlwave-all-class-inherits class-selector))) - (isa (concat "procedure" (if class-selector "-method" ""))) - (type-selector 'pro)) + (idlwave--class-selector (idlwave-determine-class cw-list 'pro)) + (idlwave--super-classes + (unless (idlwave-explicit-class-listed cw-list) + (idlwave-all-class-inherits idlwave--class-selector))) + (isa (concat "procedure" + (if idlwave--class-selector "-method" ""))) + (idlwave--type-selector 'pro)) (setq idlwave-completion-help-info - (list 'routine nil type-selector class-selector nil super-classes)) + (list 'routine nil + idlwave--type-selector idlwave--class-selector + nil idlwave--super-classes)) (idlwave-complete-in-buffer - 'procedure (if class-selector 'method 'routine) + 'procedure (if idlwave--class-selector 'method 'routine) (idlwave-routines) 'idlwave-selector (format "Select a %s name%s" isa - (if class-selector + (if idlwave--class-selector (format " (class is %s)" - (if (eq class-selector t) - "unknown" class-selector)) + (if (eq idlwave--class-selector t) + "unknown" idlwave--class-selector)) "")) isa 'idlwave-attach-method-classes 'idlwave-add-file-link-selector))) @@ -5852,22 +5808,25 @@ When we force a method or a method keyword, CLASS can specify the class." ((eq what 'function) ;; Complete a function name (let* ((cw-list (nth 3 where-list)) - (class-selector (idlwave-determine-class cw-list 'fun)) - (super-classes (unless (idlwave-explicit-class-listed cw-list) - (idlwave-all-class-inherits class-selector))) - (isa (concat "function" (if class-selector "-method" ""))) - (type-selector 'fun)) + (idlwave--class-selector (idlwave-determine-class cw-list 'fun)) + (idlwave--super-classes + (unless (idlwave-explicit-class-listed cw-list) + (idlwave-all-class-inherits idlwave--class-selector))) + (isa (concat "function" (if idlwave--class-selector "-method" ""))) + (idlwave--type-selector 'fun)) (setq idlwave-completion-help-info - (list 'routine nil type-selector class-selector nil super-classes)) + (list 'routine nil + idlwave--type-selector idlwave--class-selector + nil idlwave--super-classes)) (idlwave-complete-in-buffer - 'function (if class-selector 'method 'routine) + 'function (if idlwave--class-selector 'method 'routine) (idlwave-routines) 'idlwave-selector (format "Select a %s name%s" isa - (if class-selector + (if idlwave--class-selector (format " (class is %s)" - (if (eq class-selector t) - "unknown" class-selector)) + (if (eq idlwave--class-selector t) + "unknown" idlwave--class-selector)) "")) isa 'idlwave-attach-method-classes 'idlwave-add-file-link-selector))) @@ -5880,11 +5839,12 @@ When we force a method or a method keyword, CLASS can specify the class." ;; Complete a procedure keyword (let* ((where (nth 3 where-list)) (name (car where)) - (method-selector name) - (type-selector 'pro) + (idlwave--method-selector name) + (idlwave--type-selector 'pro) (class (idlwave-determine-class where 'pro)) - (class-selector class) - (super-classes (idlwave-all-class-inherits class-selector)) + (idlwave--class-selector class) + (idlwave--super-classes (idlwave-all-class-inherits + idlwave--class-selector)) (isa (format "procedure%s-keyword" (if class "-method" ""))) (entry (idlwave-best-rinfo-assq name 'pro class (idlwave-routines))) @@ -5894,11 +5854,13 @@ When we force a method or a method keyword, CLASS can specify the class." (error "Nothing known about procedure %s" (idlwave-make-full-name class name))) (setq list (idlwave-fix-keywords name 'pro class list - super-classes system)) + idlwave--super-classes system)) (unless list (error "No keywords available for procedure %s" (idlwave-make-full-name class name))) (setq idlwave-completion-help-info - (list 'keyword name type-selector class-selector entry super-classes)) + (list 'keyword name + idlwave--type-selector idlwave--class-selector + entry idlwave--super-classes)) (idlwave-complete-in-buffer 'keyword 'keyword list nil (format "Select keyword for procedure %s%s" @@ -5913,11 +5875,12 @@ When we force a method or a method keyword, CLASS can specify the class." ;; Complete a function keyword (let* ((where (nth 3 where-list)) (name (car where)) - (method-selector name) - (type-selector 'fun) + (idlwave--method-selector name) + (idlwave--type-selector 'fun) (class (idlwave-determine-class where 'fun)) - (class-selector class) - (super-classes (idlwave-all-class-inherits class-selector)) + (idlwave--class-selector class) + (idlwave--super-classes (idlwave-all-class-inherits + idlwave--class-selector)) (isa (format "function%s-keyword" (if class "-method" ""))) (entry (idlwave-best-rinfo-assq name 'fun class (idlwave-routines))) @@ -5928,7 +5891,7 @@ When we force a method or a method keyword, CLASS can specify the class." (error "Nothing known about function %s" (idlwave-make-full-name class name))) (setq list (idlwave-fix-keywords name 'fun class list - super-classes system)) + idlwave--super-classes system)) ;; OBJ_NEW: Messages mention the proper Init method (setq msg-name (if (and (null class) (string= (upcase name) "OBJ_NEW")) @@ -5938,7 +5901,9 @@ When we force a method or a method keyword, CLASS can specify the class." (unless list (error "No keywords available for function %s" msg-name)) (setq idlwave-completion-help-info - (list 'keyword name type-selector class-selector nil super-classes)) + (list 'keyword name + idlwave--type-selector idlwave--class-selector + nil idlwave--super-classes)) (idlwave-complete-in-buffer 'keyword 'keyword list nil (format "Select keyword for function %s%s" msg-name @@ -5950,7 +5915,9 @@ When we force a method or a method keyword, CLASS can specify the class." (t (error "This should not happen (idlwave-complete)"))))) -(defvar idlwave-complete-special nil +(define-obsolete-variable-alias 'idlwave-complete-special + 'idlwave-complete-functions "28.1") +(defvar idlwave-complete-functions nil "List of special completion functions. These functions are called for each completion. Each function must check if its own special completion context is present. If yes, it @@ -5960,6 +5927,7 @@ complete other contexts will be done. If the function returns nil, other completions will be tried.") (defun idlwave-call-special (functions &rest args) + (declare (obsolete run-hook-with-args-until-success "28.1")) (let ((funcs functions) fun ret) (catch 'exit @@ -6002,9 +5970,9 @@ other completions will be tried.") (list nil-list nil-list 'procedure nil-list nil)) ((eq what 'procedure-keyword) - (let* ((class-selector nil) - (super-classes nil) - (type-selector 'pro) + (let* ((idlwave--class-selector nil) + (idlwave--super-classes nil) + (idlwave--type-selector 'pro) (pro (or module (idlwave-completing-read "Procedure: " (idlwave-routines) 'idlwave-selector)))) @@ -6016,9 +5984,9 @@ other completions will be tried.") (list nil-list nil-list 'function nil-list nil)) ((eq what 'function-keyword) - (let* ((class-selector nil) - (super-classes nil) - (type-selector 'fun) + (let* ((idlwave--class-selector nil) + (idlwave--super-classes nil) + (idlwave--type-selector 'fun) (func (or module (idlwave-completing-read "Function: " (idlwave-routines) 'idlwave-selector)))) @@ -6031,12 +5999,14 @@ other completions will be tried.") ((eq what 'procedure-method-keyword) (let* ((class (idlwave-determine-class class-list 'pro)) - (class-selector class) - (super-classes (idlwave-all-class-inherits class-selector)) - (type-selector 'pro) + (idlwave--class-selector class) + (idlwave--super-classes (idlwave-all-class-inherits + idlwave--class-selector)) + (idlwave--type-selector 'pro) (pro (or module (idlwave-completing-read - (format "Procedure in %s class: " class-selector) + (format "Procedure in %s class: " + idlwave--class-selector) (idlwave-routines) 'idlwave-selector)))) (setq pro (idlwave-sintern-method pro)) (list nil-list nil-list 'procedure-keyword @@ -6047,12 +6017,14 @@ other completions will be tried.") ((eq what 'function-method-keyword) (let* ((class (idlwave-determine-class class-list 'fun)) - (class-selector class) - (super-classes (idlwave-all-class-inherits class-selector)) - (type-selector 'fun) + (idlwave--class-selector class) + (idlwave--super-classes (idlwave-all-class-inherits + idlwave--class-selector)) + (idlwave--type-selector 'fun) (func (or module (idlwave-completing-read - (format "Function in %s class: " class-selector) + (format "Function in %s class: " + idlwave--class-selector) (idlwave-routines) 'idlwave-selector)))) (setq func (idlwave-sintern-method func)) (list nil-list nil-list 'function-keyword @@ -6069,14 +6041,14 @@ other completions will be tried.") (unwind-protect (progn (setq-default completion-ignore-case t) - (apply 'completing-read args)) + (apply #'completing-read args)) (setq-default completion-ignore-case old-value)))) (defvar idlwave-shell-default-directory) (defun idlwave-complete-filename () "Use the comint stuff to complete a file name." (require 'comint) - (let* ((comint-file-name-chars "~/A-Za-z0-9+@:_.$#%={}\\-") + (dlet ((comint-file-name-chars "~/A-Za-z0-9+@:_.$#%={}\\-") (comint-completion-addsuffix nil) (default-directory (if (and (boundp 'idlwave-shell-default-directory) @@ -6110,7 +6082,7 @@ other completions will be tried.") (defun idlwave-rinfo-assq-any-class (name type class list) ;; Return the first matching method on the inheritance list (let* ((classes (cons class (idlwave-all-class-inherits class))) - class rtn) + rtn) ;; class (while classes (if (setq rtn (idlwave-rinfo-assq name type (pop classes) list)) (setq classes nil))) @@ -6127,7 +6099,7 @@ syslib files." list)) syslibp) (when (> (length twins) 1) - (setq twins (sort twins 'idlwave-routine-entry-compare-twins)) + (setq twins (sort twins #'idlwave-routine-entry-compare-twins)) (if (and (null keep-system) (eq 'system (car (nth 3 (car twins)))) (setq syslibp (idlwave-any-syslib (cdr twins))) @@ -6174,7 +6146,7 @@ If yes, return the index (>=1)." TYPE is `fun' or `pro'. When TYPE is not specified, both procedures and functions will be considered." (if (null method) - (mapcar 'car (idlwave-class-alist)) + (mapcar #'car (idlwave-class-alist)) (let (rtn) (mapc (lambda (x) (and (nth 2 x) @@ -6228,9 +6200,11 @@ INFO is as returned by `idlwave-what-function' or `-procedure'." (save-excursion (goto-char apos) (looking-at "->[a-zA-Z][a-zA-Z0-9$_]*::"))))) -(defvar idlwave-determine-class-special nil - "List of special functions for determining class. -Must accept two arguments: `apos' and `info'.") +(define-obsolete-variable-alias 'idlwave-determine-class-special + 'idlwave-determine-class-functions "28.1") +(defvar idlwave-determine-class-functions nil + "Special hook to determine a class. +The functions should accept one argument, APOS.") (defun idlwave-determine-class (info type) ;; Determine the class of a routine call. @@ -6275,10 +6249,10 @@ Must accept two arguments: `apos' and `info'.") ;; Before prompting, try any special class determination routines (when (and (eq t class) - idlwave-determine-class-special (not force-query)) (setq special-class - (idlwave-call-special idlwave-determine-class-special apos)) + (run-hook-with-args-until-success + 'idlwave-determine-class-functions apos)) (if special-class (setq class (idlwave-sintern-class special-class) store idlwave-store-inquired-class))) @@ -6287,7 +6261,7 @@ Must accept two arguments: `apos' and `info'.") (when (and (eq class t) (or force-query query)) (setq class-alist - (mapcar 'list (idlwave-all-method-classes (car info) type))) + (mapcar #'list (idlwave-all-method-classes (car info) type))) (setq class (idlwave-sintern-class (cond @@ -6321,10 +6295,10 @@ Must accept two arguments: `apos' and `info'.") (t class)))) (defun idlwave-selector (a) - (and (eq (nth 1 a) type-selector) - (or (and (nth 2 a) (eq class-selector t)) - (eq (nth 2 a) class-selector) - (memq (nth 2 a) super-classes)))) + (and (eq (nth 1 a) idlwave--type-selector) + (or (and (nth 2 a) (eq idlwave--class-selector t)) + (eq (nth 2 a) idlwave--class-selector) + (memq (nth 2 a) idlwave--super-classes)))) (defun idlwave-add-file-link-selector (a) ;; Record a file link, if any, for the tested names during selection. @@ -6442,7 +6416,7 @@ ARROW: Location of the arrow" func-point (cnt 0) func arrow-start class) - (idlwave-with-special-syntax + (with-syntax-table idlwave-find-symbol-syntax-table (save-restriction (save-excursion (narrow-to-region (max 1 (or bound 0)) (point-max)) @@ -6472,7 +6446,7 @@ ARROW: Location of the arrow" (goto-char pos)) (throw 'exit nil))))))) -(defun idlwave-what-procedure (&optional bound) +(defun idlwave-what-procedure (&optional _bound) ;; Find out if point is within the argument list of a procedure. ;; The return value is ("procedure-name" class arrow-pos (point)). @@ -6562,10 +6536,10 @@ This function is not general, can only be used for completion stuff." (throw 'exit nil))) (t (throw 'exit (preceding-char)))))))) -(defvar idlwave-complete-after-success-form nil - "A form to evaluate after successful completion.") -(defvar idlwave-complete-after-success-form-force nil - "A form to evaluate after completion selection in *Completions* buffer.") +(defvar idlwave--complete-after-success-function #'ignore + "A function to evaluate after successful completion.") +(defvar idlwave--complete-after-success-force-function #'ignore + "A function to evaluate after completion selection in *Completions* buffer.") (defconst idlwave-completion-mark (make-marker) "A mark pointing to the beginning of the completion string.") @@ -6590,12 +6564,12 @@ accumulate information on matching completions." (skip-chars-backward "a-zA-Z0-9_$") (setq slash (eq (preceding-char) ?/) beg (point) - idlwave-complete-after-success-form - (list 'idlwave-after-successful-completion - (list 'quote type) slash beg) - idlwave-complete-after-success-form-force - (list 'idlwave-after-successful-completion - (list 'quote type) slash (list 'quote 'force)))) + idlwave--complete-after-success-function + (lambda () (idlwave-after-successful-completion + type slash beg)) + idlwave--complete-after-success-force-function + (lambda () (idlwave-after-successful-completion + type slash 'force)))) ;; Try a completion (setq part (buffer-substring beg end) @@ -6699,19 +6673,20 @@ accumulate information on matching completions." ;; 'class-tag, for class tags, and otherwise for methods. ;; SHOW-CLASSES is the value of `idlwave-completion-show-classes'. (if (or (null show-classes) ; don't want to see classes - (null class-selector) ; not a method call + (null idlwave--class-selector) ; not a method call (and - (stringp class-selector) ; the class is already known - (not super-classes))) ; no possibilities for inheritance + (stringp idlwave--class-selector) ; the class is already known + (not idlwave--super-classes))) ; no possibilities for inheritance ;; In these cases, we do not have to do anything list (let* ((do-prop (>= show-classes 0)) (do-buf (not (= show-classes 0))) - (do-dots t) - (inherit (if (and (not (eq type 'class-tag)) super-classes) - (cons class-selector super-classes))) + ;; (do-dots t) + (inherit (if (and (not (eq type 'class-tag)) idlwave--super-classes) + (cons idlwave--class-selector idlwave--super-classes))) (max (abs show-classes)) - (lmax (if do-dots (apply 'max (mapcar 'length list)))) + (lmax ;; (if do-dots + (apply #'max (mapcar #'length list))) ;;) classes nclasses class-info space) (mapcar (lambda (x) @@ -6720,13 +6695,14 @@ accumulate information on matching completions." ;; Just one class for tags (setq classes (list - (idlwave-class-or-superclass-with-tag class-selector x))) + (idlwave-class-or-superclass-with-tag + idlwave--class-selector x))) ;; Multiple classes for method or method-keyword (setq classes (if (eq type 'kwd) (idlwave-all-method-keyword-classes - method-selector x type-selector) - (idlwave-all-method-classes x type-selector))) + idlwave--method-selector x idlwave--type-selector) + (idlwave-all-method-classes x idlwave--type-selector))) (if inherit (setq classes (delq nil @@ -6734,22 +6710,22 @@ accumulate information on matching completions." classes))))) (setq nclasses (length classes)) ;; Make the separator between item and class-info - (if do-dots - (setq space (concat " " (make-string (- lmax (length x)) ?.))) - (setq space " ")) + ;; (if do-dots + (setq space (concat " " (make-string (- lmax (length x)) ?.))) + ;; (setq space " ")) (if do-buf ;; We do want info in the buffer (if (<= nclasses max) (setq class-info (concat space - "<" (mapconcat 'identity classes ",") ">")) + "<" (mapconcat #'identity classes ",") ">")) (setq class-info (format "%s<%d classes>" space nclasses))) (setq class-info nil)) (when do-prop ;; We do want properties (setq x (copy-sequence x)) (put-text-property 0 (length x) - 'help-echo (mapconcat 'identity classes " ") + 'help-echo (mapconcat #'identity classes " ") x)) (if class-info (list x class-info) @@ -6839,7 +6815,7 @@ sort the list before displaying." (nth 2 last-command)) (progn (select-window win) - (eval idlwave-complete-after-success-form)) + (funcall idlwave--complete-after-success-function)) (set-window-start cwin (point-min))))) (and message (message "%s" message))) (select-window win)))) @@ -6882,7 +6858,7 @@ sort the list before displaying." (skip-chars-backward "a-zA-Z0-9_") (point)))) (remove-text-properties beg (point) '(face nil)))) - (eval idlwave-complete-after-success-form-force)) + (funcall idlwave--complete-after-success-force-function)) (defun idlwave-keyboard-quit () (interactive) @@ -6990,16 +6966,15 @@ If these don't exist, a letter in the string is automatically selected." (defun idlwave-local-value (var &optional buffer) "Return the value of VAR in BUFFER, but only if VAR is local to BUFFER." - (with-current-buffer (or buffer (current-buffer)) - (and (local-variable-p var (current-buffer)) - (symbol-value var)))) + (when (local-variable-p var buffer) + (buffer-local-value var (or buffer (current-buffer))))) (defvar idlwave-completion-map nil "Keymap for `completion-list-mode' with `idlwave-complete'.") -(defun idlwave-default-choose-completion (&rest args) - "Execute `default-choose-completion' and then restore the win-conf." - (apply 'idlwave-choose 'default-choose-completion args)) +;; (defun idlwave-default-choose-completion (&rest args) +;; "Execute `default-choose-completion' and then restore the win-conf." +;; (apply #'idlwave-choose #'default-choose-completion args)) (define-obsolete-function-alias 'idlwave-display-completion-list-emacs #'idlwave-display-completion-list-1 "28.1") @@ -7021,14 +6996,14 @@ If these don't exist, a letter in the string is automatically selected." "Replace `choose-completion' in OLD-MAP." (let ((new-map (copy-keymap old-map))) (substitute-key-definition - 'choose-completion 'idlwave-choose-completion new-map) - (define-key new-map [mouse-3] 'idlwave-mouse-completion-help) + #'choose-completion #'idlwave-choose-completion new-map) + (define-key new-map [mouse-3] #'idlwave-mouse-completion-help) new-map)) (defun idlwave-choose-completion (&rest args) "Choose the completion that point is in or next to." (interactive (list last-nonmenu-event)) - (apply 'idlwave-choose 'choose-completion args)) + (apply #'idlwave-choose #'choose-completion args)) (define-obsolete-function-alias 'idlwave-mouse-choose-completion #'idlwave-choose-completion "28.1") @@ -7278,8 +7253,8 @@ class/struct definition." (defun idlwave-all-class-tags (class) "Return a list of native and inherited tags in CLASS." (condition-case err - (apply 'append (mapcar 'idlwave-class-tags - (cons class (idlwave-all-class-inherits class)))) + (apply #'append (mapcar #'idlwave-class-tags + (cons class (idlwave-all-class-inherits class)))) (error (idlwave-class-tag-reset) (error "%s" (error-message-string err))))) @@ -7369,10 +7344,9 @@ property indicating the link is added." (defvar idlwave-current-class-tags nil) (defvar idlwave-current-native-class-tags nil) (defvar idlwave-sint-class-tags nil) -(declare-function idlwave-sintern-class-tag "idlwave" t t) -(idlwave-new-sintern-type 'class-tag) -(add-to-list 'idlwave-complete-special 'idlwave-complete-class-structure-tag) -(add-hook 'idlwave-update-rinfo-hook 'idlwave-class-tag-reset) +(idlwave-new-sintern-type class-tag) +(add-hook 'idlwave-complete-functions #'idlwave-complete-class-structure-tag) +(add-hook 'idlwave-update-rinfo-hook #'idlwave-class-tag-reset) (defun idlwave-complete-class-structure-tag () "Complete a structure tag on a `self' argument in an object method." @@ -7384,25 +7358,26 @@ property indicating the link is added." (skip-chars-backward "a-zA-Z0-9._$") (and (< (point) (- pos 4)) (looking-at "self\\."))) - (let* ((class-selector (nth 2 (idlwave-current-routine))) - (super-classes (idlwave-all-class-inherits class-selector))) + (let* ((idlwave--class-selector (nth 2 (idlwave-current-routine))) + (idlwave--super-classes (idlwave-all-class-inherits + idlwave--class-selector))) ;; Check if we are in a class routine - (unless class-selector + (unless idlwave--class-selector (error "Not in a method procedure or function")) ;; Check if we need to update the "current" class - (if (not (equal class-selector idlwave-current-tags-class)) - (idlwave-prepare-class-tag-completion class-selector)) + (if (not (equal idlwave--class-selector idlwave-current-tags-class)) + (idlwave-prepare-class-tag-completion idlwave--class-selector)) (setq idlwave-completion-help-info (list 'idlwave-complete-class-structure-tag-help (idlwave-sintern-routine - (concat class-selector "__define")) + (concat idlwave--class-selector "__define")) nil)) ;; FIXME: idlwave-cpl-bold doesn't seem used anywhere. - (let ((idlwave-cpl-bold idlwave-current-native-class-tags)) + (let ((_idlwave-cpl-bold idlwave-current-native-class-tags)) (idlwave-complete-in-buffer 'class-tag 'class-tag idlwave-current-class-tags nil - (format "Select a tag of class %s" class-selector) + (format "Select a tag of class %s" idlwave--class-selector) "class tag" 'idlwave-attach-class-tag-classes)) t) ; return t to skip other completions @@ -7420,7 +7395,7 @@ property indicating the link is added." (list (idlwave-sintern-class-tag x 'set))) (idlwave-all-class-tags class))) (setq idlwave-current-native-class-tags - (mapcar 'downcase (idlwave-class-tags class)))) + (mapcar #'downcase (idlwave-class-tags class)))) ;=========================================================================== ;; @@ -7429,13 +7404,11 @@ property indicating the link is added." (defvar idlwave-sint-sysvars nil) (defvar idlwave-sint-sysvartags nil) -(declare-function idlwave-sintern-sysvar "idlwave" t t) -(declare-function idlwave-sintern-sysvartag "idlwave" t t) -(idlwave-new-sintern-type 'sysvar) -(idlwave-new-sintern-type 'sysvartag) -(add-to-list 'idlwave-complete-special 'idlwave-complete-sysvar-or-tag) -(add-hook 'idlwave-update-rinfo-hook 'idlwave-sysvars-reset) -(add-hook 'idlwave-after-load-rinfo-hook 'idlwave-sintern-sysvar-alist) +(idlwave-new-sintern-type sysvar) +(idlwave-new-sintern-type sysvartag) +(add-hook 'idlwave-complete-functions #'idlwave-complete-sysvar-or-tag) +(add-hook 'idlwave-update-rinfo-hook #'idlwave-sysvars-reset) +(add-hook 'idlwave-after-load-rinfo-hook #'idlwave-sintern-sysvar-alist) (defun idlwave-complete-sysvar-or-tag () @@ -7591,7 +7564,7 @@ associated TAG, if any." (let ((text idlwave-shell-command-output) (start 0) (old idlwave-system-variables-alist) - var tags type name class link old-entry) + var tags link old-entry) ;; type name class (setq idlwave-system-variables-alist nil) (while (string-match "^IDLWAVE-SYSVAR: !\\([a-zA-Z0-9_$]+\\)\\( \\(.*\\)\\)?" text start) @@ -7611,7 +7584,8 @@ associated TAG, if any." (cdr (assq (idlwave-sintern-sysvartag x) (cdr (assq 'tags old-entry)))))) - tags)) link) + tags)) + link) idlwave-system-variables-alist))) ;; Keep the old value if query was not successful (setq idlwave-system-variables-alist @@ -7700,7 +7674,7 @@ itself." (setq this-command last-command) (idlwave-do-mouse-completion-help ev)) -(defun idlwave-routine-info (&optional arg external) +(defun idlwave-routine-info (&optional arg _external) "Display a routines calling sequence and list of keywords. When point is on the name a function or procedure, or in the argument list of a function or procedure, this command displays a help buffer with @@ -7737,7 +7711,7 @@ arg, the class property is cleared out." (idlwave-force-class-query (equal arg '(4))) (module (idlwave-what-module))) (if (car module) - (apply 'idlwave-display-calling-sequence + (apply #'idlwave-display-calling-sequence (idlwave-fix-module-if-obj_new module)) (error "Don't know which calling sequence to show"))))) @@ -7954,7 +7928,7 @@ Used by `idlwave-routine-info' and `idlwave-find-module'." (stringp class)) (list (car module) (nth 1 module) - (apply 'idlwave-find-inherited-class module)) + (apply #'idlwave-find-inherited-class module)) module))) (defun idlwave-find-inherited-class (name type class) @@ -7979,7 +7953,7 @@ appropriate Init method." (setq string (buffer-substring (point) pos)) (string-match "obj_new([^'\"]*['\"]\\([a-zA-Z0-9_]+\\)" string))) - (let ((name "Init") + (let (;; (name "Init") (class (match-string 1 string))) (setq module (list (idlwave-sintern-method "Init") 'fun @@ -7992,7 +7966,8 @@ appropriate Init method." Translate OBJ_NEW, adding all super-class keywords, or all keywords from all classes if CLASS equals t. If SYSTEM is non-nil, don't demand _EXTRA in the keyword list." - (let ((case-fold-search t)) + (let ((case-fold-search t) + (idlwave--super-classes super-classes)) ;; If this is the OBJ_NEW function, try to figure out the class and use ;; the keywords from the corresponding INIT method. @@ -8013,7 +7988,8 @@ demand _EXTRA in the keyword list." (idlwave-sintern-method "INIT") 'fun class - (idlwave-routines)) 'do-link)))))) + (idlwave-routines)) + 'do-link)))))) ;; If the class is t, combine all keywords of all methods NAME (when (eq class t) @@ -8030,7 +8006,7 @@ demand _EXTRA in the keyword list." ;; If we have inheritance, add all keywords from superclasses, if ;; the user indicated that method in `idlwave-keyword-class-inheritance' (when (and - super-classes + idlwave--super-classes idlwave-keyword-class-inheritance (stringp class) (or @@ -8045,7 +8021,7 @@ demand _EXTRA in the keyword list." (cl-loop for entry in (idlwave-routines) do (and (nth 2 entry) ; non-nil class - (memq (nth 2 entry) super-classes) ; an inherited class + (memq (nth 2 entry) idlwave--super-classes) ;an inherited class (eq (nth 1 entry) type) ; correct type (eq (car entry) name) ; correct name (mapc (lambda (k) (add-to-list 'keywords k)) @@ -8095,16 +8071,16 @@ If we do not know about MODULE, just return KEYWORD literally." (defvar idlwave-rinfo-mouse-map (let ((map (make-sparse-keymap))) - (define-key map [mouse-2] 'idlwave-mouse-active-rinfo) - (define-key map [(shift mouse-2)] 'idlwave-mouse-active-rinfo-shift) - (define-key map [mouse-3] 'idlwave-mouse-active-rinfo-right) - (define-key map " " 'idlwave-active-rinfo-space) - (define-key map "q" 'idlwave-quit-help) + (define-key map [mouse-2] #'idlwave-mouse-active-rinfo) + (define-key map [(shift mouse-2)] #'idlwave-mouse-active-rinfo-shift) + (define-key map [mouse-3] #'idlwave-mouse-active-rinfo-right) + (define-key map " " #'idlwave-active-rinfo-space) + (define-key map "q" #'idlwave-quit-help) map)) (defvar idlwave-rinfo-map (let ((map (make-sparse-keymap))) - (define-key map "q" 'idlwave-quit-help) + (define-key map "q" #'idlwave-quit-help) map)) (defvar idlwave-popup-source nil) @@ -8151,7 +8127,7 @@ If we do not know about MODULE, just return KEYWORD literally." (data (list name type class (current-buffer) nil initial-class)) (face 'idlwave-help-link) beg props win cnt total) - ;; Fix keywords, but don't add chained super-classes, since these + ;; Fix keywords, but don't add chained idlwave--super-classes, since these ;; are shown separately for that super-class (setq keywords (idlwave-fix-keywords name type class keywords)) (cond @@ -8336,7 +8312,7 @@ to it." (add-text-properties beg (point) (list 'face 'bold))) (when (and file (not (equal file ""))) (setq beg (point)) - (insert (apply 'abbreviate-file-name (list file))) + (insert (apply #'abbreviate-file-name (list file))) (if file-props (add-text-properties beg (point) file-props))))) @@ -8441,9 +8417,9 @@ was pressed." idlwave-keyword-completion-adds-equal) (insert "="))))) -(defun idlwave-list-buffer-load-path-shadows (&optional arg) +(defun idlwave-list-buffer-load-path-shadows (&optional _arg) "List the load path shadows of all routines defined in current buffer." - (interactive "P") + (interactive) (idlwave-routines) (if (derived-mode-p 'idlwave-mode) (idlwave-list-load-path-shadows @@ -8451,13 +8427,13 @@ was pressed." "in current buffer") (error "Current buffer is not in idlwave-mode"))) -(defun idlwave-list-shell-load-path-shadows (&optional arg) +(defun idlwave-list-shell-load-path-shadows (&optional _arg) "List the load path shadows of all routines compiled under the shell. This is very useful for checking an IDL application. Just compile the application, do RESOLVE_ALL, and `C-c C-i' to compile all referenced routines and update IDLWAVE internal info. Then check for shadowing with this command." - (interactive "P") + (interactive) (cond ((or (not (fboundp 'idlwave-shell-is-running)) (not (idlwave-shell-is-running))) @@ -8468,15 +8444,15 @@ with this command." (idlwave-list-load-path-shadows nil idlwave-compiled-routines "in the shell")))) -(defun idlwave-list-all-load-path-shadows (&optional arg) +(defun idlwave-list-all-load-path-shadows (&optional _arg) "List the load path shadows of all routines known to IDLWAVE." - (interactive "P") + (interactive) (idlwave-list-load-path-shadows nil nil "globally")) (defvar idlwave-sort-prefer-buffer-info t "Internal variable used to influence `idlwave-routine-twin-compare'.") -(defun idlwave-list-load-path-shadows (arg &optional special-routines loc) +(defun idlwave-list-load-path-shadows (_arg &optional special-routines loc) "List the routines which are defined multiple times. Search the information IDLWAVE has about IDL routines for multiple definitions. @@ -8525,12 +8501,12 @@ can be used to detect possible name clashes during this process." (lambda (ev) (interactive "e") (mouse-set-point ev) - (apply 'idlwave-do-find-module + (apply #'idlwave-do-find-module (get-text-property (point) 'find-args)))) (define-key keymap [(return)] (lambda () (interactive) - (apply 'idlwave-do-find-module + (apply #'idlwave-do-find-module (get-text-property (point) 'find-args)))) (message "Compiling list...( 0%%)") (with-current-buffer (get-buffer-create "*Shadows*") @@ -8606,6 +8582,10 @@ ENTRY will also be returned, as the first item of this list." (push candidate twins)) (cons entry (nreverse twins)))) +;; Bound in idlwave-study-twins,idlwave-routine-entry-compare-twins. +(defvar idlwave-twin-class) +(defvar idlwave-twin-name) + (defun idlwave-study-twins (entries) "Return dangerous twins of first entry in ENTRIES. Dangerous twins are routines with same name, but in different files on @@ -8618,7 +8598,7 @@ routines, and may have been scanned." (type (nth 1 entry)) ; Must be bound for (idlwave-twin-class (nth 2 entry)) ; idlwave-routine-twin-compare (cnt 0) - source type type-cons file alist syslibp key) + source type-cons file alist syslibp key) (while (setq entry (pop entries)) (cl-incf cnt) (setq source (nth 3 entry) @@ -8654,12 +8634,12 @@ routines, and may have been scanned." (when (and (idlwave-syslib-scanned-p) (setq entry (assoc 'system alist))) (setcar entry 'builtin)) - (sort alist 'idlwave-routine-twin-compare))) + (sort alist #'idlwave-routine-twin-compare))) ;; FIXME: Dynamically scoped vars need to use the `idlwave-' prefix. ;; (defvar type) -(define-obsolete-function-alias 'idlwave-xor 'xor "27.1") +(define-obsolete-function-alias 'idlwave-xor #'xor "27.1") (defun idlwave-routine-entry-compare (a b) "Compare two routine info entries for sorting. @@ -8690,7 +8670,7 @@ names and path locations." "Compare two routine entries, under the assumption that they are twins. This basically calls `idlwave-routine-twin-compare' with the correct args." (let* ((idlwave-twin-name (car a)) - (type (nth 1 a)) + ;; (type (nth 1 a)) (idlwave-twin-class (nth 2 a)) ; used in idlwave-routine-twin-compare (asrc (nth 3 a)) (atype (car asrc)) @@ -8706,10 +8686,6 @@ This basically calls `idlwave-routine-twin-compare' with the correct args." (list (file-truename bfile) bfile (list btype)) (list btype bfile (list btype)))))) -;; Bound in idlwave-study-twins,idlwave-routine-entry-compare-twins. -(defvar idlwave-twin-class) -(defvar idlwave-twin-name) - (defun idlwave-routine-twin-compare (a b) "Compare two routine twin entries for sorting. In here, A and B are not normal routine info entries, but special @@ -8809,9 +8785,7 @@ This expects NAME TYPE IDLWAVE-TWIN-CLASS to be bound to the right values." (defun idlwave-path-alist-add-flag (list-entry flag) "Add a flag to the path list entry, if not set." - (let ((flags (cdr list-entry))) - (add-to-list 'flags flag) - (setcdr list-entry flags))) + (cl-pushnew flag (cdr list-entry) :test #'equal)) (defun idlwave-path-alist-remove-flag (list-entry flag) "Remove a flag to the path list entry, if set." @@ -8920,8 +8894,8 @@ Assumes that point is at the beginning of the unit as found by ["(Un)Comment Region" idlwave-toggle-comment-region t] ["Continue/Split line" idlwave-split-line t] "--" - ["Toggle Auto Fill" idlwave-auto-fill-mode :style toggle - :selected (symbol-value idlwave-fill-function)]) + ["Toggle Auto Fill" auto-fill-mode :style toggle + :selected auto-fill-function]) ("Templates" ["Procedure" idlwave-procedure t] ["Function" idlwave-function t] @@ -9069,7 +9043,7 @@ With arg, list all abbrevs with the corresponding hook. This function was written since `list-abbrevs' looks terrible for IDLWAVE mode." (interactive "P") - (let ((table (symbol-value 'idlwave-mode-abbrev-table)) + (let ((table idlwave-mode-abbrev-table) abbrevs str rpl func fmt (len-str 0) (len-rpl 0)) (mapatoms commit 3bacf74adb4223e3dded46d63d5743554afd7c94 Author: Juri Linkov Date: Wed Mar 24 22:14:52 2021 +0200 * lisp/tab-bar.el (tab-bar-tab-post-change-group-functions): New hook. (tab-bar-change-tab-group): Run it. (tab-bar-move-tab-to-group): New command for new hook. diff --git a/etc/NEWS b/etc/NEWS index 49a4bb8106..5dbd61ff9a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -562,7 +562,9 @@ It also supports a negative argument. *** 'C-x t G' assigns a group name to the tab. 'tab-close-group' can close all tabs that belong to the selected group. The user option 'tab-bar-new-tab-group' defines the default group of a -new tab. +new tab. After customizing 'tab-bar-tab-post-change-group-functions' +to 'tab-bar-move-tab-to-group', changing the tab group will also move it +closer to other tabs in the same group. --- *** New user option 'tab-bar-tab-name-format-function'. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 63769673b9..2e27b293c5 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -1412,6 +1412,42 @@ function `tab-bar-tab-name-function'." ;;; Tab groups +(defun tab-bar-move-tab-to-group (&optional tab) + "Relocate TAB (or the current tab) closer to its group." + (interactive) + (let* ((tabs (funcall tab-bar-tabs-function)) + (tab (or tab (tab-bar--current-tab-find tabs))) + (tab-index (tab-bar--tab-index tab)) + (group (alist-get 'group tab)) + ;; Beginning position of the same group + (beg (seq-position tabs group + (lambda (tb gr) + (and (not (eq tb tab)) + (equal (alist-get 'group tb) gr))))) + ;; Size of the same group + (len (when beg + (seq-position (nthcdr beg tabs) group + (lambda (tb gr) + (not (equal (alist-get 'group tb) gr)))))) + (pos (when beg + (cond + ;; Don't move tab when it's already inside group bounds + ((and len (>= tab-index beg) (<= tab-index (+ beg len))) nil) + ;; Move tab from the right to the group end + ((and len (> tab-index (+ beg len))) (+ beg len 1)) + ;; Move tab from the left to the group beginning + ((< tab-index beg) beg))))) + (when pos + (tab-bar-move-tab-to pos (1+ tab-index))))) + +(defcustom tab-bar-tab-post-change-group-functions nil + "List of functions to call after changing a tab group. +The current tab is supplied as an argument." + :type 'hook + :options '(tab-bar-move-tab-to-group) + :group 'tab-bar + :version "28.1") + (defun tab-bar-change-tab-group (group-name &optional arg) "Add the tab specified by its absolute position ARG to GROUP-NAME. If no ARG is specified, then set the GROUP-NAME for the current tab. @@ -1445,6 +1481,8 @@ While using this command, you might also want to replace (setcdr group group-new-name) (nconc tab `((group . ,group-new-name)))) + (run-hook-with-args 'tab-bar-tab-post-change-group-functions tab) + (force-mode-line-update) (unless tab-bar-mode (message "Set tab group to '%s'" group-new-name)))) commit d20a4a50d377f1c48299dc18008ab1a106f4f58e Author: Alan Mackenzie Date: Wed Mar 24 18:57:48 2021 +0000 Improve failure reporting in test/lisp/electric-tests.el In particular, on a failure, output the test's doc string to electric-tests.log, along with all the other failure information. Fixes bug #47320. * electric-tests.el (electric-pair-test-for) New parameter doc-string. On a test failure, output the doc-string parameter with message. (electric-pair-define-test-form): Set the new variable doc-string to the generated doc string, and pass this as argument to both ert-deftest and electric-pair-test-for. diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el index 62a42b7fe4..44b3d8b672 100644 --- a/test/lisp/electric-tests.el +++ b/test/lisp/electric-tests.el @@ -50,7 +50,8 @@ `(call-with-saved-electric-modes #'(lambda () ,@body))) (defun electric-pair-test-for (fixture where char expected-string - expected-point mode bindings fixture-fn) + expected-point mode bindings + fixture-fn &optional doc-string) (with-temp-buffer (funcall mode) (insert fixture) @@ -63,6 +64,14 @@ (mapcar #'car bindings) (mapcar #'cdr bindings) (call-interactively (key-binding `[,last-command-event]))))) + (when + (and doc-string + (not + (and + (equal (buffer-substring-no-properties (point-min) (point-max)) + expected-string) + (equal (point) expected-point)))) + (message "\n%s\n" doc-string)) (should (equal (buffer-substring-no-properties (point-min) (point-max)) expected-string)) (should (equal (point) @@ -109,14 +118,9 @@ (fixture (format "%s%s%s" prefix fixture suffix)) (expected-string (format "%s%s%s" prefix expected-string suffix)) (expected-point (+ (length prefix) expected-point)) - (pos (+ (length prefix) pos))) - `(ert-deftest ,(intern (format "electric-pair-%s-at-point-%s-in-%s%s" - name - (1+ pos) - mode - extra-desc)) - () - ,(format "Electricity test in a `%s' buffer.\n + (pos (+ (length prefix) pos)) + (doc-string + (format "Electricity test in a `%s' buffer.\n Start with point at %d in a %d-char-long buffer like this one: @@ -143,7 +147,14 @@ The buffer's contents should %s: char (if (string= fixture expected-string) "stay" "become") (replace-regexp-in-string "\n" "\\\\n" expected-string) - expected-point) + expected-point))) + `(ert-deftest ,(intern (format "electric-pair-%s-at-point-%s-in-%s%s" + name + (1+ pos) + mode + extra-desc)) + () + ,doc-string (electric-pair-test-for ,fixture ,(1+ pos) ,char @@ -151,7 +162,8 @@ The buffer's contents should %s: ,expected-point ',mode ,bindings - ,fixture-fn))))) + ,fixture-fn + ,doc-string))))) (cl-defmacro define-electric-pair-test (name fixture commit a5617bccf7d77b24c6f431e2c97496c440b06fe2 Author: Stefan Monnier Date: Wed Mar 24 13:45:13 2021 -0400 * lisp/auth-source-pass.el (auth-source): Silence spurious warning diff --git a/lisp/auth-source-pass.el b/lisp/auth-source-pass.el index bd3070dcfe..a7b959c47f 100644 --- a/lisp/auth-source-pass.el +++ b/lisp/auth-source-pass.el @@ -33,10 +33,12 @@ ;;; Code: (require 'seq) -(eval-when-compile (require 'subr-x)) (require 'cl-lib) (require 'auth-source) (require 'url-parse) +;; Use `eval-when-compile' after the other `require's to avoid spurious +;; "might not be defined at runtime" warnings. +(eval-when-compile (require 'subr-x)) (defgroup auth-source-pass nil "password-store integration within auth-source." commit 711569e94c623d33cc7ab8c550f7f757e46985a5 Author: Lars Ingebrigtsen Date: Wed Mar 24 18:29:11 2021 +0100 Fix previous format-prompt change: The default can be a symbol * lisp/minibuffer.el (format-prompt): The default can also be a symbol. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 1c9b268942..5f594679ca 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -3948,7 +3948,8 @@ is included in the return value." prompt (apply #'format prompt format-args)) (and default - (length> default 0) + (or (not (stringp default)) + (length> default 0)) (format minibuffer-default-prompt-format (if (consp default) (car default) commit 1ac8cd3ef673054720d88dbc5019677d70d3c26c Author: Harald Jörg Date: Wed Mar 24 17:06:21 2021 +0100 perl-mode: Fix regexps for fontification * test/lisp/progmodes/cperl-mode-tests.el (cperl-test-fontify-declarations): New test to ensure consistency between perl-mode.el and cperl-mode.el (bug#47345). * lisp/progmodes/perl-mode.el (perl-font-lock-keywords-1): pick correct capture groups for "use Pack::Age;" Fontify all components of "Pack::Age", not just "Pack" (perl-font-lock-keywords-2): Use keyword-face for declarators diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el index c7fa5ab84b..fd23683bc0 100644 --- a/lisp/progmodes/perl-mode.el +++ b/lisp/progmodes/perl-mode.el @@ -170,9 +170,9 @@ ;; (1 font-lock-constant-face) (2 font-lock-variable-name-face nil t)) ;; ;; Fontify function and package names in declarations. - ("\\<\\(package\\|sub\\)\\>[ \t]*\\(\\sw+\\)?" + ("\\<\\(package\\|sub\\)\\>[ \t]*\\(\\(?:\\sw\\|::\\)+\\)?" (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t)) - ("\\(^\\|[^$@%&\\]\\)\\<\\(import\\|no\\|require\\|use\\)\\>[ \t]*\\(\\sw+\\)?" + ("\\(?:^\\|[^$@%&\\]\\)\\<\\(import\\|no\\|require\\|use\\)\\>[ \t]*\\(\\(?:\\sw\\|::\\)+\\)?" (1 font-lock-keyword-face) (2 font-lock-constant-face nil t))) "Subdued level highlighting for Perl mode.") @@ -187,7 +187,7 @@ "\\>") ;; ;; Fontify declarators and prefixes as types. - ("\\<\\(has\\|local\\|my\\|our\\|state\\)\\>" . font-lock-type-face) ; declarators + ("\\<\\(has\\|local\\|my\\|our\\|state\\)\\>" . font-lock-keyword-face) ; declarators ;; ;; Fontify function, variable and file name references. ("&\\(\\sw+\\(::\\sw+\\)*\\)" 1 font-lock-function-name-face) diff --git a/test/lisp/progmodes/cperl-mode-tests.el b/test/lisp/progmodes/cperl-mode-tests.el index 8078e9c9fa..14bc48b92f 100644 --- a/test/lisp/progmodes/cperl-mode-tests.el +++ b/test/lisp/progmodes/cperl-mode-tests.el @@ -135,6 +135,25 @@ point in the distant past, and is still broken in perl-mode. " (should (equal (nth 3 (syntax-ppss)) nil)) (should (equal (nth 4 (syntax-ppss)) t)))))) +(ert-deftest cperl-test-fontify-declarations () + "Test that declarations and package usage use consistent fontification." + (with-temp-buffer + (funcall cperl-test-mode) + (insert "package Foo::Bar;\n") + (insert "use Fee::Fie::Foe::Foo\n;") + (insert "my $xyzzy = 'PLUGH';\n") + (goto-char (point-min)) + (font-lock-ensure) + (search-forward "Bar") + (should (equal (get-text-property (match-beginning 0) 'face) + 'font-lock-function-name-face)) + (search-forward "use") ; This was buggy in perl-mode + (should (equal (get-text-property (match-beginning 0) 'face) + 'font-lock-keyword-face)) + (search-forward "my") + (should (equal (get-text-property (match-beginning 0) 'face) + 'font-lock-keyword-face)))) + (defvar perl-continued-statement-offset) (defvar perl-indent-level) commit 39f16a7d396a9e8299b0447cdf87a07a4fbf4d53 Author: Lars Ingebrigtsen Date: Wed Mar 24 17:02:17 2021 +0100 Revert "Remove font-lock toggle from font-lock-update" This reverts commit 23995414fec483287e7fb9c9a279483319f9fc54. The subject is under discussion. diff --git a/lisp/font-lock.el b/lisp/font-lock.el index 3105242a1f..82915d8c8b 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -1120,13 +1120,17 @@ portion of the buffer." (funcall font-lock-ensure-function (or beg (point-min)) (or end (point-max))))) -(defun font-lock-update () - "Refontify the accessible portion of the buffer. -Unconditionally activate `font-lock-mode'." - (interactive) - (unless font-lock-mode (font-lock-mode 1)) +(defun font-lock-update (&optional arg) + "Updates the syntax highlighting in this buffer. +Refontify the accessible portion of this buffer, or enable Font Lock mode +in this buffer if it is currently disabled. With prefix ARG, toggle Font +Lock mode." + (interactive "P") (save-excursion - (font-lock-fontify-region (point-min) (point-max)))) + (if (and (not arg) font-lock-mode) + (font-lock-fontify-region (point-min) (point-max)) + (font-lock-unfontify-region (point-min) (point-max)) + (font-lock-mode 'toggle)))) (defun font-lock-default-fontify-buffer () "Fontify the whole buffer using `font-lock-fontify-region-function'." commit 23995414fec483287e7fb9c9a279483319f9fc54 Author: Paul W. Rankin Date: Thu Mar 25 00:26:59 2021 +1000 Remove font-lock toggle from font-lock-update * lisp/font-lock.el (font-lock-update): Remove call to font-lock-unfontify-region and font-lock-mode toggle with ARG; this did not perform what original author intended diff --git a/lisp/font-lock.el b/lisp/font-lock.el index 82915d8c8b..3105242a1f 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -1120,17 +1120,13 @@ portion of the buffer." (funcall font-lock-ensure-function (or beg (point-min)) (or end (point-max))))) -(defun font-lock-update (&optional arg) - "Updates the syntax highlighting in this buffer. -Refontify the accessible portion of this buffer, or enable Font Lock mode -in this buffer if it is currently disabled. With prefix ARG, toggle Font -Lock mode." - (interactive "P") +(defun font-lock-update () + "Refontify the accessible portion of the buffer. +Unconditionally activate `font-lock-mode'." + (interactive) + (unless font-lock-mode (font-lock-mode 1)) (save-excursion - (if (and (not arg) font-lock-mode) - (font-lock-fontify-region (point-min) (point-max)) - (font-lock-unfontify-region (point-min) (point-max)) - (font-lock-mode 'toggle)))) + (font-lock-fontify-region (point-min) (point-max)))) (defun font-lock-default-fontify-buffer () "Fontify the whole buffer using `font-lock-fontify-region-function'." commit 344eea4113f8eb3e78cd201a90cc968a8c3658f5 Author: Dmitry Gutov Date: Wed Mar 24 12:39:08 2021 +0200 xref.el: Keep Emacs 26 compatibility * lisp/progmodes/xref.el (xref--read-identifier) (xref-find-definitions, xref-find-definitions-other-window) (xref-find-definitions-other-frame, xref-find-references): Undo the latest change for Emacs 26 compatibility (bug#47286). diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 3cb4247b4b..ea52befec5 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -1192,7 +1192,12 @@ definitions." (xref--prompt-p this-command)) (let ((id (completing-read - (format-prompt prompt def) + (if def + (format "%s (default %s): " + (substring prompt 0 (string-match + "[ :]+\\'" prompt)) + def) + prompt) (xref-backend-identifier-completion-table backend) nil nil nil 'xref--read-identifier-history def))) @@ -1252,19 +1257,19 @@ If sufficient information is available to determine a unique definition for IDENTIFIER, display it in the selected window. Otherwise, display the list of the possible definitions in a buffer where the user can select from the list." - (interactive (list (xref--read-identifier "Find definitions of"))) + (interactive (list (xref--read-identifier "Find definitions of: "))) (xref--find-definitions identifier nil)) ;;;###autoload (defun xref-find-definitions-other-window (identifier) "Like `xref-find-definitions' but switch to the other window." - (interactive (list (xref--read-identifier "Find definitions of"))) + (interactive (list (xref--read-identifier "Find definitions of: "))) (xref--find-definitions identifier 'window)) ;;;###autoload (defun xref-find-definitions-other-frame (identifier) "Like `xref-find-definitions' but switch to the other frame." - (interactive (list (xref--read-identifier "Find definitions of"))) + (interactive (list (xref--read-identifier "Find definitions of: "))) (xref--find-definitions identifier 'frame)) ;;;###autoload @@ -1275,7 +1280,7 @@ offering the symbol at point as the default. With prefix argument, or if `xref-prompt-for-identifier' is t, always prompt for the identifier. If `xref-prompt-for-identifier' is nil, prompt only if there's no usable symbol at point." - (interactive (list (xref--read-identifier "Find references of"))) + (interactive (list (xref--read-identifier "Find references of: "))) (xref--find-xrefs identifier 'references identifier nil)) ;;;###autoload commit 88fdc4945ab3d37592abdd6e18c4c01c6dde3fef Author: Gabriel do Nascimento Ribeiro Date: Wed Mar 24 10:34:22 2021 +0100 Add optional FORMAT argument to 'emacs-init-time' * lisp/time.el (emacs-init-time): Add optional FORMAT argument (bug#47306). diff --git a/lisp/time.el b/lisp/time.el index 1403c4ac00..7e1d9180f6 100644 --- a/lisp/time.el +++ b/lisp/time.el @@ -614,13 +614,14 @@ point." str)))) ;;;###autoload -(defun emacs-init-time () - "Return a string giving the duration of the Emacs initialization." +(defun emacs-init-time (&optional format) + "Return a string giving the duration of the Emacs initialization. +FORMAT is a string to format the result, using `format'. If nil, +the default format \"%f seconds\" is used." (interactive) - (let ((str - (format "%s seconds" - (float-time - (time-subtract after-init-time before-init-time))))) + (let ((str (format (or format "%f seconds") + (float-time (time-subtract after-init-time + before-init-time))))) (if (called-interactively-p 'interactive) (message "%s" str) str))) commit 50512e36c72a0b6867743ad6b1db0298a2a124f4 Author: Gabriel do Nascimento Ribeiro Date: Wed Mar 24 10:31:31 2021 +0100 Replace "(default %s)" with 'format-prompt' * lisp/cmuscheme.el (scheme-load-file, scheme-compile-file): * lisp/comint.el (comint-get-source): * lisp/emulation/viper-cmd.el (viper-quote-region, viper-kill-buffer) (viper-query-replace, viper-read-string-with-history): * lisp/eshell/esh-mode.el (eshell-find-tag): * lisp/gnus/gnus-sum.el (gnus-articles-to-read) (gnus-summary-search-article-forward) (gnus-summary-search-article-backward): * lisp/international/mule-cmds.el (set-input-method, toggle-input-method) (describe-input-method, set-language-environment) (describe-language-environment): * lisp/mh-e/mh-gnus.el (mh-mml-minibuffer-read-disposition): * lisp/mh-e/mh-letter.el (mh-insert-letter): * lisp/mh-e/mh-mime.el (mh-display-with-external-viewer) (mh-mime-save-parts, mh-mh-forward-message) (mh-mml-query-cryptographic-method, mh-minibuffer-read-type): * lisp/mh-e/mh-seq.el (mh-read-seq, mh-read-range): * lisp/mh-e/mh-utils.el (mh-prompt-for-folder): * lisp/progmodes/etags.el (find-tag-tag): (find-tag-noselect, find-tag, find-tag-other-window) (find-tag-other-frame, find-tag-regexp): * lisp/progmodes/idlwave.el (idlwave-find-module): * lisp/progmodes/inf-lisp.el (lisp-load-file, lisp-compile-file): * lisp/progmodes/tcl.el (tcl-load-file, tcl-restart-with-file): * lisp/progmodes/xref.el (xref--read-identifier): (xref-find-definitions, xref-find-definitions-other-window) (xref-find-definitions-other-frame, xref-find-references): * lisp/ses.el (ses-read-printer): (ses-read-cell-printer, ses-read-column-printer) (ses-read-default-printer, ses-define-local-printer): * lisp/subr.el (read-number): * lisp/term.el (term-get-source): * src/minibuf.c (read-buffer): Remove prompt suffix and use 'format-prompt'. * lisp/minibuffer.el (format-prompt): Ignore DEFAULT empty strings (bug#47286). diff --git a/lisp/cmuscheme.el b/lisp/cmuscheme.el index 772891d5d3..d43cdb15c0 100644 --- a/lisp/cmuscheme.el +++ b/lisp/cmuscheme.el @@ -421,7 +421,7 @@ in the next one.") (defun scheme-load-file (file-name) "Load a Scheme file FILE-NAME into the inferior Scheme process." - (interactive (comint-get-source "Load Scheme file: " scheme-prev-l/c-dir/file + (interactive (comint-get-source "Load Scheme file" scheme-prev-l/c-dir/file scheme-source-modes t)) ; t because `load' ; needs an exact name (comint-check-source file-name) ; Check to see if buffer needs saved. @@ -433,7 +433,7 @@ in the next one.") (defun scheme-compile-file (file-name) "Compile a Scheme file FILE-NAME in the inferior Scheme process." - (interactive (comint-get-source "Compile Scheme file: " + (interactive (comint-get-source "Compile Scheme file" scheme-prev-l/c-dir/file scheme-source-modes nil)) ; nil because COMPILE doesn't diff --git a/lisp/comint.el b/lisp/comint.el index 65072b0137..b04d404676 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -2946,7 +2946,7 @@ two arguments are used for determining defaults.) If MUSTMATCH-P is true, then the filename reader will only accept a file that exists. A typical use: - (interactive (comint-get-source \"Compile file: \" prev-lisp-dir/file + (interactive (comint-get-source \"Compile file\" prev-lisp-dir/file \\='(lisp-mode) t))" (let* ((def (comint-source-default prev-dir/file source-modes)) (stringfile (comint-extract-string)) @@ -2959,9 +2959,7 @@ A typical use: (car def))) (deffile (if sfile-p (file-name-nondirectory stringfile) (cdr def))) - (ans (read-file-name (if deffile (format "%s(default %s) " - prompt deffile) - prompt) + (ans (read-file-name (format-prompt prompt deffile) defdir (concat defdir deffile) mustmatch-p))) diff --git a/lisp/emulation/viper-cmd.el b/lisp/emulation/viper-cmd.el index 42d6c1eb19..728f790a96 100644 --- a/lisp/emulation/viper-cmd.el +++ b/lisp/emulation/viper-cmd.el @@ -1786,7 +1786,7 @@ Undo previous insertion and inserts new." (do-not-change-default t)) (setq quote-str (viper-read-string-with-history - "Quote string: " + "Quote string" nil 'viper-quote-region-history ;; FIXME: Use comment-region. @@ -1995,24 +1995,17 @@ problems." #'viper-minibuffer-standard-hook (if (or (not (listp old)) (eq (car old) 'lambda)) (list old) old)))) - (val "") - (padding "") - temp-msg) + (val "")) (setq keymap (or keymap minibuffer-local-map) initial (or initial "") - viper-initial initial - temp-msg (if default - (format "(default %s) " default) - "")) + viper-initial initial) (setq viper-incomplete-ex-cmd nil) - (setq val (read-from-minibuffer prompt - (concat temp-msg initial val padding) - keymap nil history-var)) - (setq minibuffer-setup-hook nil - padding (viper-array-to-string (this-command-keys)) - temp-msg "") + (setq val (read-from-minibuffer (format-prompt prompt default) + nil + keymap nil history-var default)) + (setq minibuffer-setup-hook nil) ;; the following tries to be smart about what to put in history (if (not (string= val (car (symbol-value history-var)))) (push val (symbol-value history-var))) @@ -3825,7 +3818,7 @@ Null string will repeat previous search." (let (buffer buffer-name) (setq buffer-name (funcall viper-read-buffer-function - (format "Kill buffer (%s): " + (format-prompt "Kill buffer" (buffer-name (current-buffer))))) (setq buffer (if (null buffer-name) @@ -4171,8 +4164,8 @@ and regexp replace." (interactive) (let (str) (setq str (viper-read-string-with-history - (if viper-re-query-replace "Query replace regexp: " - "Query replace: ") + (if viper-re-query-replace "Query replace regexp" + "Query replace") nil ; no initial 'viper-replace1-history (car viper-replace1-history) ; default @@ -4187,7 +4180,7 @@ and regexp replace." (query-replace-regexp str (viper-read-string-with-history - (format-message "Query replace regexp `%s' with: " str) + (format-message "Query replace regexp `%s' with" str) nil ; no initial 'viper-replace1-history (car viper-replace1-history) ; default @@ -4195,7 +4188,7 @@ and regexp replace." (query-replace str (viper-read-string-with-history - (format-message "Query replace `%s' with: " str) + (format-message "Query replace `%s' with" str) nil ; no initial 'viper-replace1-history (car viper-replace1-history) ; default diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el index d29b010ea0..f9dbce9770 100644 --- a/lisp/eshell/esh-mode.el +++ b/lisp/eshell/esh-mode.el @@ -458,7 +458,7 @@ and the hook `eshell-exit-hook'." (let ((inhibit-read-only t) (no-default (eobp)) (find-tag-default-function 'ignore)) - (setq tagname (car (find-tag-interactive "Find tag: " no-default))) + (setq tagname (car (find-tag-interactive "Find tag" no-default))) (with-suppressed-warnings ((obsolete find-tag)) (find-tag tagname next-p regexp-p)))) diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index 97da550353..c30f9a5f35 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -5977,14 +5977,15 @@ If SELECT-ARTICLES, only select those articles from GROUP." (input (read-string (if only-read-p - (format - "How many articles from %s (available %d, default %d): " - (gnus-group-real-name gnus-newsgroup-name) - number default) - (format - "How many articles from %s (%d default): " - (gnus-group-real-name gnus-newsgroup-name) - default)) + (format-prompt + "How many articles from %s (available %d)" + default + (gnus-group-real-name gnus-newsgroup-name) + number) + (format-prompt + "How many articles from %s" + default + (gnus-group-real-name gnus-newsgroup-name))) nil nil (number-to-string default)))) @@ -9514,11 +9515,9 @@ If BACKWARD, search backward instead." (interactive (list (read-string - (format "Search article %s (regexp%s): " - (if current-prefix-arg "backward" "forward") - (if gnus-last-search-regexp - (concat ", default " gnus-last-search-regexp) - ""))) + (format-prompt "Search article %s (regexp)" + gnus-last-search-regexp + (if current-prefix-arg "backward" "forward"))) current-prefix-arg) gnus-summary-mode) (if (string-equal regexp "") @@ -9537,10 +9536,8 @@ If BACKWARD, search backward instead." (interactive (list (read-string - (format "Search article backward (regexp%s): " - (if gnus-last-search-regexp - (concat ", default " gnus-last-search-regexp) - "")))) + (format-prompt "Search article backward (regexp)" + gnus-last-search-regexp))) gnus-summary-mode) (gnus-summary-search-article-forward regexp 'backward)) diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index 57958b8727..bf0df6f971 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -1524,7 +1524,7 @@ To deactivate it programmatically, use `deactivate-input-method'." (interactive (let* ((default (or (car input-method-history) default-input-method))) (list (read-input-method-name - (if default "Select input method (default %s): " "Select input method: ") + (format-prompt "Select input method" default) default t) t))) (activate-input-method input-method) @@ -1569,7 +1569,7 @@ which marks the variable `default-input-method' as set for Custom buffers." (if (or arg (not default)) (progn (read-input-method-name - (if default "Input method (default %s): " "Input method: " ) + (format-prompt "Input method" default) default t)) default)) (unless default-input-method @@ -1620,7 +1620,7 @@ If `default-transient-input-method' was not yet defined, prompt for it." "Describe input method INPUT-METHOD." (interactive (list (read-input-method-name - "Describe input method (default current choice): "))) + (format-prompt "Describe input method" current-input-method)))) (if (and input-method (symbolp input-method)) (setq input-method (symbol-name input-method))) (help-setup-xref (list #'describe-input-method @@ -1929,7 +1929,7 @@ runs the hook `exit-language-environment-hook'. After setting up the new language environment, it runs `set-language-environment-hook'." (interactive (list (read-language-name nil - "Set language environment (default English): "))) + (format-prompt "Set language environment" "English")))) (if language-name (if (symbolp language-name) (setq language-name (symbol-name language-name))) @@ -2144,7 +2144,7 @@ See `set-language-info-alist' for use in programs." (interactive (list (read-language-name 'documentation - "Describe language environment (default current choice): "))) + (format-prompt "Describe language environment" current-language-environment)))) (if (null language-name) (setq language-name current-language-environment)) (if (or (null language-name) diff --git a/lisp/mh-e/mh-gnus.el b/lisp/mh-e/mh-gnus.el index ab65637157..ac46cc63fc 100644 --- a/lisp/mh-e/mh-gnus.el +++ b/lisp/mh-e/mh-gnus.el @@ -129,7 +129,7 @@ (unless default (setq default (mml-content-disposition type filename))) (let ((disposition (completing-read - (format "Disposition (default %s): " default) + (format-prompt "Disposition" default) '(("attachment") ("inline") ("")) nil t nil nil default))) (if (not (equal disposition "")) diff --git a/lisp/mh-e/mh-letter.el b/lisp/mh-e/mh-letter.el index c44b78ad12..59790181c4 100644 --- a/lisp/mh-e/mh-letter.el +++ b/lisp/mh-e/mh-letter.el @@ -390,10 +390,7 @@ This command leaves the mark before the letter and point after it." (or mh-sent-from-msg (nth 0 (mh-translate-range folder "cur"))) (nth 0 (mh-translate-range folder "cur")))) (message - (read-string (concat "Message number" - (or (and default - (format " (default %d): " default)) - ": ")) + (read-string (format-prompt "Message number" default) nil nil (if (numberp default) (int-to-string default) diff --git a/lisp/mh-e/mh-mime.el b/lisp/mh-e/mh-mime.el index bf63ac36cf..8af7bcdf8f 100644 --- a/lisp/mh-e/mh-mime.el +++ b/lisp/mh-e/mh-mime.el @@ -259,9 +259,7 @@ usually reads the file \"/etc/mailcap\"." (methods (mapcar (lambda (x) (list (cdr (assoc 'viewer x)))) (mailcap-mime-info type 'all))) (def (caar methods)) - (prompt (format "Viewer%s: " (if def - (format " (default %s)" def) - ""))) + (prompt (format-prompt "Viewer" def)) (method (completing-read prompt methods nil nil nil nil def)) (folder mh-show-folder-buffer) (buffer-read-only nil)) @@ -395,9 +393,9 @@ do the work." ((and (or prompt (equal t mh-mime-save-parts-default-directory)) mh-mime-save-parts-directory) - (read-directory-name (format - "Store in directory (default %s): " - mh-mime-save-parts-directory) + (read-directory-name (format-prompt + "Store in directory" + mh-mime-save-parts-directory) "" mh-mime-save-parts-directory t "")) ((stringp mh-mime-save-parts-default-directory) mh-mime-save-parts-default-directory) @@ -1258,11 +1256,7 @@ See also \\[mh-mh-to-mime]." (interactive (list (mml-minibuffer-read-description) (mh-prompt-for-folder "Message from" mh-sent-from-folder nil) - (read-string (concat "Messages" - (if (numberp mh-sent-from-msg) - (format " (default %d): " - mh-sent-from-msg) - ": "))))) + (read-string (format-prompt "Messages" mh-sent-from-msg)))) (beginning-of-line) (insert "#forw [") (and description @@ -1596,7 +1590,7 @@ the possible security methods (see `mh-mml-method-default')." (if current-prefix-arg (let ((def (or (car mh-mml-cryptographic-method-history) mh-mml-method-default))) - (completing-read (format "Method (default %s): " def) + (completing-read (format-prompt "Method" def) '(("pgp") ("pgpmime") ("smime")) nil t nil 'mh-mml-cryptographic-method-history def)) mh-mml-method-default)) @@ -1731,7 +1725,7 @@ Optional argument DEFAULT is returned if a type isn't entered." (type (or (and (not (equal probed-type "application/octet-stream")) probed-type) (completing-read - (format "Content type (default %s): " default) + (format-prompt "Content type" default) (mapcar #'list (mailcap-mime-types)))))) (if (not (equal type "")) type diff --git a/lisp/mh-e/mh-seq.el b/lisp/mh-e/mh-seq.el index f4b02c1974..9b9675c78e 100644 --- a/lisp/mh-e/mh-seq.el +++ b/lisp/mh-e/mh-seq.el @@ -390,10 +390,7 @@ Prompt with PROMPT, raise an error if the sequence is empty and the NOT-EMPTY flag is non-nil, and supply an optional DEFAULT sequence. A reply of `%' defaults to the first sequence containing the current message." - (let* ((input (completing-read (format "%s sequence%s: " prompt - (if default - (format " (default %s)" default) - "")) + (let* ((input (completing-read (format-prompt "%s sequence" default prompt) (mh-seq-names mh-seq-list) nil nil nil 'mh-sequence-history)) (seq (cond ((equal input "%") @@ -646,13 +643,10 @@ should be replaced with: ((stringp default) default) ((symbolp default) (symbol-name default)))) (prompt (cond ((and guess large default) - (format "%s (folder has %s messages, default %s)" - prompt (car counts) default)) - ((and guess large) - (format "%s (folder has %s messages)" - prompt (car counts))) + (format-prompt "%s (folder has %s messages)" + default prompt (car counts))) (default - (format "%s (default %s)" prompt default)))) + (format-prompt prompt default)))) (minibuffer-local-completion-map mh-range-completion-map) (seq-list (if (eq folder mh-current-folder) mh-seq-list @@ -662,7 +656,7 @@ should be replaced with: (mh-seq-names seq-list))) (input (cond ((and (not ask-flag) unseen) (symbol-name mh-unseen-seq)) ((and (not ask-flag) (not large)) "all") - (t (completing-read (format "%s: " prompt) + (t (completing-read prompt 'mh-range-completion-function nil nil nil 'mh-range-history default)))) msg-list) diff --git a/lisp/mh-e/mh-utils.el b/lisp/mh-e/mh-utils.el index 9497ba0d11..be66e62a1d 100644 --- a/lisp/mh-e/mh-utils.el +++ b/lisp/mh-e/mh-utils.el @@ -757,10 +757,9 @@ function will accept the folder +, which means all folders when used in searching." (if (null default) (setq default "")) - (let* ((default-string (cond (default-string (format " (default %s)" default-string)) - ((equal "" default) "") - (t (format " (default %s)" default)))) - (prompt (format "%s folder%s: " prompt default-string)) + (let* ((default-string (or default-string + (if (equal default "") nil default))) + (prompt (format-prompt "%s folder" default-string prompt)) (mh-current-folder-name mh-current-folder) read-name folder-name) (while (and (setq read-name (mh-folder-completing-read diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 55825e32fc..1c9b268942 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -3941,13 +3941,14 @@ it. See `format' for details. If DEFAULT is a list, the first element is used as the default. If not, the element is used as is. -If DEFAULT is nil, no \"default value\" string is included in the -return value." +If DEFAULT is nil or an empty string, no \"default value\" string +is included in the return value." (concat (if (null format-args) prompt (apply #'format prompt format-args)) (and default + (length> default 0) (format minibuffer-default-prompt-format (if (consp default) (car default) diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el index 023c90cca5..13717b1b89 100644 --- a/lisp/progmodes/etags.el +++ b/lisp/progmodes/etags.el @@ -836,11 +836,7 @@ If no tags table is loaded, do nothing and return nil." "Read a tag name, with defaulting and completion." (let* ((completion-ignore-case (find-tag--completion-ignore-case)) (default (find-tag--default)) - (spec (completing-read (if default - (format "%s (default %s): " - (substring string 0 (string-match "[ :]+\\'" string)) - default) - string) + (spec (completing-read (format-prompt string default) (tags-lazy-completion-table) nil nil nil nil default))) (if (equal spec "") @@ -899,7 +895,7 @@ onto a ring and may be popped back to with \\[pop-tag-mark]. Contrast this with the ring of marks gone to by the command. See documentation of variable `tags-file-name'." - (interactive (find-tag-interactive "Find tag: ")) + (interactive (find-tag-interactive "Find tag")) (setq find-tag-history (cons tagname find-tag-history)) ;; Save the current buffer's value of `find-tag-hook' before @@ -971,7 +967,7 @@ Contrast this with the ring of marks gone to by the command. See documentation of variable `tags-file-name'." (declare (obsolete xref-find-definitions "25.1")) - (interactive (find-tag-interactive "Find tag: ")) + (interactive (find-tag-interactive "Find tag")) (let* ((buf (find-tag-noselect tagname next-p regexp-p)) (pos (with-current-buffer buf (point)))) (condition-case nil @@ -1000,7 +996,7 @@ Contrast this with the ring of marks gone to by the command. See documentation of variable `tags-file-name'." (declare (obsolete xref-find-definitions-other-window "25.1")) - (interactive (find-tag-interactive "Find tag other window: ")) + (interactive (find-tag-interactive "Find tag other window")) ;; This hair is to deal with the case where the tag is found in the ;; selected window's buffer; without the hair, point is moved in both @@ -1041,7 +1037,7 @@ Contrast this with the ring of marks gone to by the command. See documentation of variable `tags-file-name'." (declare (obsolete xref-find-definitions-other-frame "25.1")) - (interactive (find-tag-interactive "Find tag other frame: ")) + (interactive (find-tag-interactive "Find tag other frame")) (let ((pop-up-frames t)) (with-suppressed-warnings ((obsolete find-tag-other-window)) (find-tag-other-window tagname next-p)))) @@ -1065,7 +1061,7 @@ Contrast this with the ring of marks gone to by the command. See documentation of variable `tags-file-name'." (declare (obsolete xref-find-apropos "25.1")) - (interactive (find-tag-interactive "Find tag regexp: " t)) + (interactive (find-tag-interactive "Find tag regexp" t)) ;; We go through find-tag-other-window to do all the display hair there. (funcall (if other-window 'find-tag-other-window 'find-tag) regexp next-p t)) diff --git a/lisp/progmodes/idlwave.el b/lisp/progmodes/idlwave.el index e8e55ae96d..b72d9da748 100644 --- a/lisp/progmodes/idlwave.el +++ b/lisp/progmodes/idlwave.el @@ -7820,7 +7820,7 @@ force class query for object methods." (name (idlwave-completing-read (if (or (not this-buffer) (assoc default list)) - (format "Module (Default %s): " default) + (format-prompt "Module" default) (format "Module in this file: ")) list)) type class) diff --git a/lisp/progmodes/inf-lisp.el b/lisp/progmodes/inf-lisp.el index 146ed4dca4..af6ccce3d6 100644 --- a/lisp/progmodes/inf-lisp.el +++ b/lisp/progmodes/inf-lisp.el @@ -487,7 +487,7 @@ Used by these commands to determine defaults." (defun lisp-load-file (file-name) "Load a Lisp file into the inferior Lisp process." - (interactive (comint-get-source "Load Lisp file: " lisp-prev-l/c-dir/file + (interactive (comint-get-source "Load Lisp file" lisp-prev-l/c-dir/file lisp-source-modes nil)) ; nil because LOAD ; doesn't need an exact name (comint-check-source file-name) ; Check to see if buffer needs saved. @@ -500,7 +500,7 @@ Used by these commands to determine defaults." (defun lisp-compile-file (file-name) "Compile a Lisp file in the inferior Lisp process." - (interactive (comint-get-source "Compile Lisp file: " lisp-prev-l/c-dir/file + (interactive (comint-get-source "Compile Lisp file" lisp-prev-l/c-dir/file lisp-source-modes nil)) ; nil = don't need ; suffix .lisp (comint-check-source file-name) ; Check to see if buffer needs saved. diff --git a/lisp/progmodes/tcl.el b/lisp/progmodes/tcl.el index 82e1343e05..f6a50bf1a8 100644 --- a/lisp/progmodes/tcl.el +++ b/lisp/progmodes/tcl.el @@ -1413,7 +1413,7 @@ Prefix argument means switch to the Tcl buffer afterwards." (list ;; car because comint-get-source returns a list holding the ;; filename. - (car (comint-get-source "Load Tcl file: " + (car (comint-get-source "Load Tcl file" (or (and (derived-mode-p 'tcl-mode) (buffer-file-name)) @@ -1433,7 +1433,7 @@ If an inferior Tcl process exists, it is killed first. Prefix argument means switch to the Tcl buffer afterwards." (interactive (list - (car (comint-get-source "Restart with Tcl file: " + (car (comint-get-source "Restart with Tcl file" (or (and (derived-mode-p 'tcl-mode) (buffer-file-name)) diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index ea52befec5..3cb4247b4b 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -1192,12 +1192,7 @@ definitions." (xref--prompt-p this-command)) (let ((id (completing-read - (if def - (format "%s (default %s): " - (substring prompt 0 (string-match - "[ :]+\\'" prompt)) - def) - prompt) + (format-prompt prompt def) (xref-backend-identifier-completion-table backend) nil nil nil 'xref--read-identifier-history def))) @@ -1257,19 +1252,19 @@ If sufficient information is available to determine a unique definition for IDENTIFIER, display it in the selected window. Otherwise, display the list of the possible definitions in a buffer where the user can select from the list." - (interactive (list (xref--read-identifier "Find definitions of: "))) + (interactive (list (xref--read-identifier "Find definitions of"))) (xref--find-definitions identifier nil)) ;;;###autoload (defun xref-find-definitions-other-window (identifier) "Like `xref-find-definitions' but switch to the other window." - (interactive (list (xref--read-identifier "Find definitions of: "))) + (interactive (list (xref--read-identifier "Find definitions of"))) (xref--find-definitions identifier 'window)) ;;;###autoload (defun xref-find-definitions-other-frame (identifier) "Like `xref-find-definitions' but switch to the other frame." - (interactive (list (xref--read-identifier "Find definitions of: "))) + (interactive (list (xref--read-identifier "Find definitions of"))) (xref--find-definitions identifier 'frame)) ;;;###autoload @@ -1280,7 +1275,7 @@ offering the symbol at point as the default. With prefix argument, or if `xref-prompt-for-identifier' is t, always prompt for the identifier. If `xref-prompt-for-identifier' is nil, prompt only if there's no usable symbol at point." - (interactive (list (xref--read-identifier "Find references of: "))) + (interactive (list (xref--read-identifier "Find references of"))) (xref--find-xrefs identifier 'references identifier nil)) ;;;###autoload diff --git a/lisp/ses.el b/lisp/ses.el index a11c754abc..6058d48ed1 100644 --- a/lisp/ses.el +++ b/lisp/ses.el @@ -2653,9 +2653,7 @@ canceled." (barf-if-buffer-read-only) (if (eq default t) (setq default "") - (setq prompt (format "%s (default %S): " - (substring prompt 0 -2) - default))) + (setq prompt (format-prompt prompt default))) (dolist (key ses-completion-keys) (define-key ses-mode-edit-map key 'ses-read-printer-complete-symbol)) ;; make it globally visible, so that it can be visible from the minibuffer. @@ -2702,7 +2700,7 @@ right-justified) or a list of one string (will be left-justified)." ;;Range contains differing printer functions (setq default t) (throw 'ses-read-cell-printer t)))))) - (list (ses-read-printer (format "Cell %S printer: " ses--curcell) + (list (ses-read-printer (format "Cell %S printer" ses--curcell) default)))) (unless (eq newval t) (ses-begin-change) @@ -2716,7 +2714,7 @@ See `ses-read-cell-printer' for input forms." (interactive (let ((col (cdr (ses-sym-rowcol ses--curcell)))) (ses-check-curcell) - (list col (ses-read-printer (format "Column %s printer: " + (list col (ses-read-printer (format "Column %s printer" (ses-column-letter col)) (ses-col-printer col))))) @@ -2731,7 +2729,7 @@ See `ses-read-cell-printer' for input forms." "Set the default printer function for cells that have no other. See `ses-read-cell-printer' for input forms." (interactive - (list (ses-read-printer "Default printer: " ses--default-printer))) + (list (ses-read-printer "Default printer" ses--default-printer))) (unless (eq newval t) (ses-begin-change) (ses-set-parameter 'ses--default-printer newval) @@ -3773,7 +3771,7 @@ function is redefined." (setq name (intern name)) (let* ((cur-printer (gethash name ses--local-printer-hashmap)) (default (and cur-printer (ses--locprn-def cur-printer)))) - (setq def (ses-read-printer (format "Enter definition of printer %S: " name) + (setq def (ses-read-printer (format "Enter definition of printer %S" name) default))) (list name def))) diff --git a/lisp/subr.el b/lisp/subr.el index 1b93fcf410..c2be26a15f 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2806,9 +2806,9 @@ This function is used by the `interactive' code letter `n'." (when default1 (setq prompt (if (string-match "\\(\\):[ \t]*\\'" prompt) - (replace-match (format " (default %s)" default1) t t prompt 1) + (replace-match (format minibuffer-default-prompt-format default1) t t prompt 1) (replace-regexp-in-string "[ \t]*\\'" - (format " (default %s) " default1) + (format minibuffer-default-prompt-format default1) prompt t t)))) (while (progn diff --git a/lisp/term.el b/lisp/term.el index 6beb17fb66..d41895ad3d 100644 --- a/lisp/term.el +++ b/lisp/term.el @@ -2535,7 +2535,7 @@ See `term-prompt-regexp'." ;; then the filename reader will only accept a file that exists. ;; ;; A typical use: -;; (interactive (term-get-source "Compile file: " prev-lisp-dir/file +;; (interactive (term-get-source "Compile file" prev-lisp-dir/file ;; '(lisp-mode) t)) ;; This is pretty stupid about strings. It decides we're in a string @@ -2566,9 +2566,7 @@ See `term-prompt-regexp'." (car def))) (deffile (if sfile-p (file-name-nondirectory stringfile) (cdr def))) - (ans (read-file-name (if deffile (format "%s(default %s) " - prompt deffile) - prompt) + (ans (read-file-name (format-prompt prompt deffile) defdir (concat defdir deffile) mustmatch-p))) diff --git a/src/minibuf.c b/src/minibuf.c index d58924ae52..c9831fd50f 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -1490,8 +1490,8 @@ function, instead of the usual behavior. */) STRING_MULTIBYTE (prompt)); } - AUTO_STRING (format, "%s (default %s): "); - prompt = CALLN (Fformat, format, prompt, + prompt = CALLN (Ffuncall, intern("format-prompt"), + prompt, CONSP (def) ? XCAR (def) : def); } commit 8d334132456dfcbe5b5c3e59737dbfd0a4ea4c0d Author: Lars Ingebrigtsen Date: Wed Mar 24 10:23:07 2021 +0100 Fix problem with filling with a computed fill prefix * lisp/textmodes/fill.el (fill-region-as-paragraph): Fix problem when filling text with a computed fill prefix (bug#47338). diff --git a/lisp/textmodes/fill.el b/lisp/textmodes/fill.el index 81cd2f02cd..cb5027a976 100644 --- a/lisp/textmodes/fill.el +++ b/lisp/textmodes/fill.el @@ -703,7 +703,8 @@ space does not end a sentence, so don't break a line there." (or justify (setq justify (current-justification))) ;; Don't let Adaptive Fill mode alter the fill prefix permanently. - (let ((fill-prefix fill-prefix)) + (let ((actual-fill-prefix fill-prefix) + (fill-prefix fill-prefix)) ;; Figure out how this paragraph is indented, if desired. (when (and adaptive-fill-mode (or (null fill-prefix) (string= fill-prefix ""))) @@ -717,7 +718,7 @@ space does not end a sentence, so don't break a line there." (goto-char from) (beginning-of-line) - (if (not justify) ; filling disabled: just check indentation + (if (not justify) ; filling disabled: just check indentation (progn (goto-char from) (while (< (point) to) @@ -747,12 +748,14 @@ space does not end a sentence, so don't break a line there." linebeg) (while (< (point) to) ;; On the first line, there may be text in the fill prefix - ;; zone. In that case, don't consider that area when - ;; trying to find a place to put a line break (bug#45720). + ;; zone (when `fill-prefix' is specified externally, and + ;; not computed). In that case, don't consider that area + ;; when trying to find a place to put a line break + ;; (bug#45720). (if (not first) (setq linebeg (point)) (setq first nil - linebeg (+ (point) (length fill-prefix)))) + linebeg (+ (point) (length actual-fill-prefix)))) (move-to-column (current-fill-column)) (if (when (< (point) to) ;; Find the position where we'll break the line. commit 8b07994e201e478df8a3431cbae5187b4cde1791 Author: Stefan Kangas Date: Wed Mar 24 09:28:32 2021 +0100 Convert many more links to use HTTPS diff --git a/ChangeLog.3 b/ChangeLog.3 index ed7704e47f..83e5001e52 100644 --- a/ChangeLog.3 +++ b/ChangeLog.3 @@ -76935,7 +76935,7 @@ * lisp/emacs-lisp/lisp-mode.el (lisp-cl-font-lock-keywords-2): Highlight the Common Lisp conventional names as described in - http://www.cliki.net/Naming+conventions. + https://www.cliki.net/Naming+conventions. (lisp-el-font-lock-keywords-2): Remove the already commented out code for `do-' and `with-' because Emacs Lisp does not have a similar convention. @@ -122126,7 +122126,7 @@ I roughly followed the Bordeaux threads API: - http://trac.common-lisp.net/bordeaux-threads/wiki/ApiDocumentation + https://sionescu.github.io/bordeaux-threads/ ... but not identically. In particular I chose not to implement interrupt-thread or destroy-thread, but instead a thread-signaling diff --git a/doc/misc/gnus-faq.texi b/doc/misc/gnus-faq.texi index 35a2526211..d3db940dd9 100644 --- a/doc/misc/gnus-faq.texi +++ b/doc/misc/gnus-faq.texi @@ -1935,13 +1935,13 @@ when you're online. Let's talk about Unix systems first: For the news part, the easiest solution is a small nntp server like -@uref{http://www.leafnode.org/, Leafnode} or +@uref{https://www.leafnode.org/, Leafnode} or @uref{http://patrik.iki.fi/sn/, sn}, of course you can also install a full featured news server like @uref{https://www.isc.org/othersoftware/, inn}. Then you want to fetch your Mail, popular choices -are @uref{http://www.fetchmail.info/, fetchmail} +are @uref{https://www.fetchmail.info/, fetchmail} and @uref{http://pyropus.ca/software/getmail/, getmail}. You should tell those to write the mail to your disk and Gnus to read it from there. Last but not least the mail diff --git a/doc/misc/nxml-mode.texi b/doc/misc/nxml-mode.texi index 3671ac8f3d..4ca223d46c 100644 --- a/doc/misc/nxml-mode.texi +++ b/doc/misc/nxml-mode.texi @@ -82,7 +82,7 @@ documents. To get validation and schema-sensitive editing, you need a RELAX NG Compact Syntax (RNC) schema for your document (@pxref{Locating a schema}). The @file{etc/schema} directory includes some schemas for popular document -types. See @url{http://relaxng.org/} for more information on RELAX NG@. +types. See @url{https://relaxng.org/} for more information on RELAX NG@. You can use the @samp{Trang} program from @url{http://www.thaiopensource.com/relaxng/trang.html} to automatically create RNC schemas. This program can: diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex index dac7ae3d19..a91181b116 100644 --- a/doc/misc/texinfo.tex +++ b/doc/misc/texinfo.tex @@ -1181,7 +1181,7 @@ % double any backslashes. Otherwise, a name like "\node" will be % interpreted as a newline (\n), followed by o, d, e. Not good. % -% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and +% See https://mailman.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and % related messages. The final outcome is that it is up to the TeX user % to double the backslashes and otherwise make the string valid, so % that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to @@ -3539,7 +3539,7 @@ % We use the free feym* fonts from the eurosym package by Henrik % Theiling, which support regular, slanted, bold and bold slanted (and % "outlined" (blackboard board, sort of) versions, which we don't need). -% It is available from http://www.ctan.org/tex-archive/fonts/eurosym. +% It is available from https://www.ctan.org/tex-archive/fonts/eurosym. % % Although only regular is the truly official Euro symbol, we ignore % that. The Euro is designed to be slightly taller than the regular diff --git a/lib/pipe2.c b/lib/pipe2.c index 41493aa430..adbaa4a102 100644 --- a/lib/pipe2.c +++ b/lib/pipe2.c @@ -41,7 +41,7 @@ pipe2 (int fd[2], int flags) { /* Mingw _pipe() corrupts fd on failure; also, if we succeed at creating the pipe but later fail at changing fcntl, we want - to leave fd unchanged: http://austingroupbugs.net/view.php?id=467 */ + to leave fd unchanged: https://austingroupbugs.net/view.php?id=467 */ int tmp[2]; tmp[0] = fd[0]; tmp[1] = fd[1]; diff --git a/lisp/allout-widgets.el b/lisp/allout-widgets.el index f251be8dfb..a642af2dae 100644 --- a/lisp/allout-widgets.el +++ b/lisp/allout-widgets.el @@ -6,7 +6,7 @@ ;; Version: 1.0 ;; Created: Dec 2005 ;; Keywords: outlines -;; Website: http://myriadicity.net/software-and-systems/craft/emacs-allout +;; Website: https://myriadicity.net/software-and-systems/craft/emacs-allout ;; This file is part of GNU Emacs. @@ -38,7 +38,7 @@ ;; See the `allout-widgets-mode' docstring for more details. ;; ;; Info about allout and allout-widgets development are available at -;; http://myriadicity.net/Sundry/EmacsAllout +;; https://myriadicity.net/software-and-systems/craft/emacs-allout ;; ;; The graphics include: ;; diff --git a/lisp/allout.el b/lisp/allout.el index 3981fdd785..1876235753 100644 --- a/lisp/allout.el +++ b/lisp/allout.el @@ -6,7 +6,7 @@ ;; Created: Dec 1991 -- first release to usenet ;; Version: 2.3 ;; Keywords: outlines, wp, languages, PGP, GnuPG -;; Website: http://myriadicity.net/software-and-systems/craft/emacs-allout +;; Website: https://myriadicity.net/software-and-systems/craft/emacs-allout ;; This file is part of GNU Emacs. @@ -57,7 +57,7 @@ ;; mode. ;; ;; Directions to the latest development version and helpful notes are -;; available at http://myriadicity.net/Sundry/EmacsAllout . +;; available at https://myriadicity.net/software-and-systems/craft/emacs-allout . ;; ;; The outline menubar additions provide quick reference to many of the ;; features. See the docstring of the variables `allout-layout' and diff --git a/lisp/auth-source-pass.el b/lisp/auth-source-pass.el index 39db1a710b..bd3070dcfe 100644 --- a/lisp/auth-source-pass.el +++ b/lisp/auth-source-pass.el @@ -27,7 +27,7 @@ ;;; Commentary: -;; Integrates password-store (http://passwordstore.org/) within +;; Integrates password-store (https://passwordstore.org/) within ;; auth-source. ;;; Code: @@ -123,7 +123,7 @@ ENTRY is the name of a password-store entry. The key used to retrieve the password is the symbol `secret'. The convention used as the format for a password-store file is -the following (see http://www.passwordstore.org/#organization): +the following (see https://www.passwordstore.org/#organization): secret key1: value1 diff --git a/lisp/calendar/cal-bahai.el b/lisp/calendar/cal-bahai.el index c2e4205c0b..ff419c72f6 100644 --- a/lisp/calendar/cal-bahai.el +++ b/lisp/calendar/cal-bahai.el @@ -27,7 +27,7 @@ ;; This collection of functions implements the features of calendar.el ;; and diary-lib.el that deal with the Bahá’í calendar. -;; The Bahá’í (http://www.bahai.org) calendar system is based on a +;; The Bahá’í (https://www.bahai.org) calendar system is based on a ;; solar cycle of 19 months with 19 days each. The four remaining ;; "intercalary" days are called the Ayyám-i-Há (days of Há), and are ;; placed between the 18th and 19th months. They are meant as a time diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el index 8f4dbf0c5e..d9cd21e3cd 100644 --- a/lisp/calendar/icalendar.el +++ b/lisp/calendar/icalendar.el @@ -66,7 +66,7 @@ ;; 0.02: ;; - Should work in XEmacs now. Thanks to Len Trigg for the XEmacs patches! ;; - Added exporting from Emacs diary to ical. -;; - Some bugfixes, after testing with calendars from http://icalshare.com. +;; - Some bugfixes, after testing with calendars from https://icalshare.com. ;; - Tested with Emacs 21.3.2 and XEmacs 21.4.12 ;; 0.01: (2003-03-21) diff --git a/lisp/calendar/iso8601.el b/lisp/calendar/iso8601.el index 5a109a73cd..44c4811984 100644 --- a/lisp/calendar/iso8601.el +++ b/lisp/calendar/iso8601.el @@ -41,7 +41,7 @@ ;; ;; The standard can be found at: ;; -;; http://www.loc.gov/standards/datetime/iso-tc154-wg5_n0038_iso_wd_8601-1_2016-02-16.pdf +;; https://www.loc.gov/standards/datetime/iso-tc154-wg5_n0038_iso_wd_8601-1_2016-02-16.pdf ;; ;; The Wikipedia page on the standard is also informative: ;; diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 4aa8ddcfa1..67b7546094 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -527,7 +527,7 @@ This will generate compile-time constants from BINDINGS." ;; This is too general -- rms. ;; A user complained that he has functions whose names start with `do' ;; and that they get the wrong color. - ;; That user has violated the http://www.cliki.net/Naming+conventions: + ;; That user has violated the https://www.cliki.net/Naming+conventions: ;; CL (but not EL!) `with-' (context) and `do-' (iteration) (,(concat "(\\(\\(do-\\|with-\\)" lisp-mode-symbol-regexp "\\)") (1 font-lock-keyword-face)) diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el index 44be9afbfa..994433063c 100644 --- a/lisp/emacs-lisp/smie.el +++ b/lisp/emacs-lisp/smie.el @@ -63,7 +63,7 @@ ;; building the 2D precedence tables and then computing the precedence levels ;; from it) can be found in pages 187-194 of "Parsing techniques" by Dick Grune ;; and Ceriel Jacobs (BookBody.pdf available at -;; http://dickgrune.com/Books/PTAPG_1st_Edition/). +;; https://dickgrune.com/Books/PTAPG_1st_Edition/). ;; ;; OTOH we had to kill many chickens, read many coffee grounds, and practice ;; untold numbers of black magic spells, to come up with the indentation code. diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index ad323089ad..c1071c1c68 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -971,7 +971,7 @@ see http://www.cs.indiana.edu/picons/ftp/index.html" :version "22.1" :type '(repeat directory) :link '(url-link :tag "download" - "http://www.cs.indiana.edu/picons/ftp/index.html") + "http://www.cs.indiana.edu/picons/ftp/index.html") :link '(custom-manual "(gnus)Picons") :group 'gnus-picon) diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 1e0362a3bf..fad4ef3dcf 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -382,7 +382,7 @@ Archives \(such as groups.google.com) respect this header." :group 'message-various) (defcustom message-archive-note - "X-No-Archive: Yes - save http://groups.google.com/" + "X-No-Archive: Yes - save https://groups.google.com/" "Note to insert why you wouldn't want this posting archived. If nil, don't insert any text in the body." :version "22.1" diff --git a/lisp/gnus/mml-sec.el b/lisp/gnus/mml-sec.el index a32eed4419..15157e6fbc 100644 --- a/lisp/gnus/mml-sec.el +++ b/lisp/gnus/mml-sec.el @@ -140,7 +140,7 @@ by default identifies the used encryption keys, giving away the Bcc'ed identities. Clearly, this contradicts the original goal of *blind* copies. For an academic paper explaining the problem, see URL -`http://crypto.stanford.edu/portia/papers/bb-bcc.pdf'. +`https://crypto.stanford.edu/portia/papers/bb-bcc.pdf'. Use this variable to specify e-mail addresses whose owners do not mind if they are identifiable as recipients. This may be useful if you use Bcc headers to encrypt e-mails to yourself." diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el index 46691e3494..4867455393 100644 --- a/lisp/gnus/nnmaildir.el +++ b/lisp/gnus/nnmaildir.el @@ -21,7 +21,7 @@ ;;; Commentary: -;; Maildir format is documented at . +;; Maildir format is documented at . ;; nnmaildir also stores extra information in the .nnmaildir/ directory ;; within a maildir. ;; diff --git a/lisp/gnus/smime.el b/lisp/gnus/smime.el index 2446577c6a..e9f703e90c 100644 --- a/lisp/gnus/smime.el +++ b/lisp/gnus/smime.el @@ -42,7 +42,7 @@ ;; reflect this. ;; ;; The home of this file is in Gnus, but also available from -;; http://josefsson.org/smime.html. +;; https://josefsson.org/smime.html. ;;; Quick introduction: diff --git a/lisp/image-dired.el b/lisp/image-dired.el index e4b53bd275..2509ecf8f8 100644 --- a/lisp/image-dired.el +++ b/lisp/image-dired.el @@ -67,9 +67,9 @@ ;; ;; * For `image-dired-get-exif-data' and `image-dired-set-exif-data' to work, ;; the command line tool `exiftool' is needed. It can be found here: -;; http://www.sno.phy.queensu.ca/~phil/exiftool/. These two functions -;; are, among other things, used for writing comments to image files -;; using `image-dired-thumbnail-set-image-description' and to create +;; https://exiftool.org/. These two functions are, among other +;; things, used for writing comments to image files using +;; `image-dired-thumbnail-set-image-description' and to create ;; "unique" file names using `image-dired-get-exif-file-name' (used by ;; `image-dired-copy-with-exif-file-name'). ;; diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index e4bdf50f52..57958b8727 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -2245,7 +2245,7 @@ See `set-language-info-alist' for use in programs." ;; LANGUAGE is a language code taken from ISO 639:1988 (E/F) ;; with additions from ISO 639/RA Newsletter No.1/1989; ;; see Internet RFC 2165 (1997-06) and - ;; http://www.evertype.com/standards/iso639/iso639-en.html + ;; https://www.evertype.com/standards/iso639/iso639-en.html ;; TERRITORY is a country code taken from ISO 3166 ;; http://www.din.de/gremien/nas/nabd/iso3166ma/codlstp1/en_listp1.html. ;; CODESET and MODIFIER are implementation-dependent. diff --git a/lisp/international/mule-conf.el b/lisp/international/mule-conf.el index 64aac46fce..2d36dab632 100644 --- a/lisp/international/mule-conf.el +++ b/lisp/international/mule-conf.el @@ -41,7 +41,7 @@ ;; Standards docs equivalent to iso-2022 and iso-8859 are at ;; https://www.ecma.ch/. -;; FWIW, http://www.microsoft.com/globaldev/ lists the following for +;; FWIW, https://www.microsoft.com/globaldev/ lists the following for ;; MS Windows, which are presumably the only charsets we really need ;; to worry about on such systems: ;; `OEM codepages': 437, 720, 737, 775, 850, 852, 855, 857, 858, 862, 866 @@ -358,7 +358,7 @@ :code-offset #x130000 :unify-map "BIG5") ;; Fixme: AKA cp950 according to -;; . Is +;; . Is ;; that correct? (define-charset 'chinese-big5-1 @@ -708,7 +708,7 @@ ;; Original name for cp1125, says Serhii Hlodin (define-charset-alias 'cp866u 'cp1125) -;; Fixme: C.f. iconv, http://czyborra.com/charsets/codepages.html +;; Fixme: C.f. iconv, https://czyborra.com/charsets/codepages.html ;; shows this as not ASCII compatible, with various graphics in ;; 0x01-0x1F. (define-charset 'cp437 diff --git a/lisp/json.el b/lisp/json.el index 6677c3b1b3..0e61e1ad90 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -26,7 +26,7 @@ ;; This is a library for parsing and generating JSON (JavaScript Object ;; Notation). -;; Learn all about JSON here: . +;; Learn all about JSON here: . ;; The user-serviceable entry points for the parser are the functions ;; `json-read' and `json-read-from-string'. The encoder has a single diff --git a/lisp/language/cyrillic.el b/lisp/language/cyrillic.el index c12096f95e..b64a237cf7 100644 --- a/lisp/language/cyrillic.el +++ b/lisp/language/cyrillic.el @@ -33,7 +33,7 @@ ;; are converted to Unicode internally. See ;; . For more info ;; on Cyrillic charsets, see -;; . The KOI and +;; . The KOI and ;; Alternativnyj coding systems should live in code-pages.el, but ;; they've always been preloaded and the coding system autoload ;; mechanism didn't get accepted, so they have to stay here and diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index fa971b33c7..c9210c6251 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -36007,7 +36007,7 @@ Add a description of the problem and include a reproducible test case. Feel free to send questions and enhancement requests to . Official distribution is at -URL `http://www.iis.ee.ethz.ch/~zimmi/emacs/vera-mode.html' +URL `https://www.iis.ee.ethz.ch/~zimmi/emacs/vera-mode.html' The Vera Mode Maintainer diff --git a/lisp/leim/quail/ipa-praat.el b/lisp/leim/quail/ipa-praat.el index 0920bc7900..1a95395fd7 100644 --- a/lisp/leim/quail/ipa-praat.el +++ b/lisp/leim/quail/ipa-praat.el @@ -35,7 +35,7 @@ "ipa-praat" "IPA" "IPAP" t "International Phonetic Alphabet input method. This follows the input method of the phonetic analysis program -Praat (http://www.fon.hum.uva.nl/praat/). +Praat (https://www.fon.hum.uva.nl/praat/). * Vowels diff --git a/lisp/leim/quail/ipa.el b/lisp/leim/quail/ipa.el index e805c6ad3b..c25687574e 100644 --- a/lisp/leim/quail/ipa.el +++ b/lisp/leim/quail/ipa.el @@ -336,12 +336,12 @@ exchange in environments where Unicode is not available. This input method uses this transliteration to allow you to produce the IPA in your editor with a keyboard that's limited to ASCII. -See http://www.phon.ucl.ac.uk/home/sampa/ipasam-x.pdf for a full definition +See https://www.phon.ucl.ac.uk/home/sampa/ipasam-x.pdf for a full definition of the mapping.") (quail-define-rules ;; Table taken from https://en.wikipedia.org/wiki/X-SAMPA, checked with - ;; http://www.phon.ucl.ac.uk/home/sampa/ipasam-x.pdf + ;; https://www.phon.ucl.ac.uk/home/sampa/ipasam-x.pdf ("d`" "ɖ") ;; Voiced retroflex plosive U+0256 ("g" "ɡ") ;; Voiced velar plosive U+0261 diff --git a/lisp/leim/quail/latin-post.el b/lisp/leim/quail/latin-post.el index 8e21ed8013..10408776a2 100644 --- a/lisp/leim/quail/latin-post.el +++ b/lisp/leim/quail/latin-post.el @@ -744,7 +744,7 @@ Doubling the postfix separates the letter and postfix: e.g. a\\='\\=' -> a\\=' ;;; correctly on most displays. ;;; This reference is an authoritative guide to Hawaiian orthography: -;;; http://www2.hawaii.edu/~strauch/tips/HawaiianOrthography.html +;;; https://www2.hawaii.edu/~strauch/tips/HawaiianOrthography.html ;;; Initial coding 2018-09-08 Bob Newell, Honolulu, Hawaiʻi ;;; Comments to bobnewell@bobnewell.net diff --git a/lisp/leim/quail/latin-pre.el b/lisp/leim/quail/latin-pre.el index 22006547c4..b8b0fabfa8 100644 --- a/lisp/leim/quail/latin-pre.el +++ b/lisp/leim/quail/latin-pre.el @@ -1294,7 +1294,7 @@ of characters from a single Latin-N charset. ;;; correctly on most displays. ;;; This reference is an authoritative guide to Hawaiian orthography: -;;; http://www2.hawaii.edu/~strauch/tips/HawaiianOrthography.html +;;; https://www2.hawaii.edu/~strauch/tips/HawaiianOrthography.html ;;; Initial coding 2018-09-08 Bob Newell, Honolulu, Hawaiʻi ;;; Comments to bobnewell@bobnewell.net diff --git a/lisp/leim/quail/programmer-dvorak.el b/lisp/leim/quail/programmer-dvorak.el index 49f9d82bc0..9e1e23c04b 100644 --- a/lisp/leim/quail/programmer-dvorak.el +++ b/lisp/leim/quail/programmer-dvorak.el @@ -24,7 +24,7 @@ ;;; Commentary: ;;; This file provides an input method for the programmers Dvorak keyboard -;;; layout by Roland Kaufman (). +;;; layout by Roland Kaufman (). ;;; Code: diff --git a/lisp/mail/feedmail.el b/lisp/mail/feedmail.el index d76017b994..cec573642e 100644 --- a/lisp/mail/feedmail.el +++ b/lisp/mail/feedmail.el @@ -163,7 +163,7 @@ ;; (autoload 'feedmail-buffer-to-smtpmail "feedmail" nil t) ;; (setq feedmail-buffer-eating-function 'feedmail-buffer-to-smtpmail) ;; -;; Alternatively, the FLIM project +;; Alternatively, the FLIM project ;; provides a library called smtp.el. If you want to use that, the above lines ;; would be: ;; diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el index 11296a53b9..1aac337415 100644 --- a/lisp/mh-e/mh-e.el +++ b/lisp/mh-e/mh-e.el @@ -1907,7 +1907,7 @@ white image, can be generated using the \"compface\" command (see URL `ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.Z'). The \"Online X-Face Converter\" is a useful resource for quick conversion of images into \"X-Face:\" header fields (see URL -`http://www.dairiki.org/xface/'). +`https://www.dairiki.org/xface/'). Use the \"make-face\" script to convert a JPEG image to the higher resolution, color, \"Face:\" header field (see URL @@ -2466,9 +2466,9 @@ of citations entirely, choose \"None\"." "Disposition-Notification-Options:" ; RFC 2298 "Disposition-Notification-To:" ; RFC 2298 "Distribution:" ; RFC 1036 - "DKIM-" ; http://antispam.yahoo.com/domainkeys + "DKIM-" ; https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail "DL-Expansion-History:" ; RFC 2156 - "DomainKey-" ; http://antispam.yahoo.com/domainkeys + "DomainKey-" ; https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail "DomainKey-Signature:" "Encoding:" ; RFC 1505 "Envelope-to:" @@ -2555,7 +2555,7 @@ of citations entirely, choose \"None\"." "X-Abuse-Info:" "X-Accept-Language:" ; Netscape/Mozilla "X-Ack:" - "X-ACL-Warn:" ; http://www.exim.org + "X-ACL-Warn:" ; https://www.exim.org "X-Admin:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/ "X-Administrivia-To:" "X-AMAZON" ; Amazon.com @@ -2579,8 +2579,8 @@ of citations entirely, choose \"None\"." "X-BFI:" "X-Bigfish:" "X-Bogosity:" ; bogofilter - "X-BPS1:" ; http://www.boggletools.com - "X-BPS2:" ; http://www.boggletools.com + "X-BPS1:" ; http://www.boggletools.com [dead link?] + "X-BPS2:" ; http://www.boggletools.com [dead link?] "X-Brightmail-Tracker:" ; Brightmail "X-BrightmailFiltered:" ; Brightmail "X-Bugzilla-" ; Bugzilla @@ -2596,12 +2596,12 @@ of citations entirely, choose \"None\"." "X-Confirm-Reading-To:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/ "X-Content-Filtered-By:" "X-ContentStamp:" ; NetZero - "X-Country-Chain:" ; http://www.declude.com/x-note.htm + "X-Country-Chain:" ; http://www.declude.com/x-note.htm [dead link?] "X-Cr-Hashedpuzzle:" "X-Cr-Puzzleid:" "X-Cron-Env:" "X-DCC-" ; SpamAssassin - "X-Declude-" ; http://www.declude.com/x-note.htm + "X-Declude-" ; http://www.declude.com/x-note.htm [dead link?] "X-Dedicated:" "X-Delivered" "X-Destination-ID:" @@ -2616,7 +2616,7 @@ of citations entirely, choose \"None\"." "X-EID:" "X-ELNK-Trace:" ; Earthlink mailer "X-EM-" ; Some ecommerce software - "X-Email-Type-Id:" ; Paypal http://www.paypal.com + "X-Email-Type-Id:" ; Paypal https://www.paypal.com "X-Enigmail-Version:" "X-Envelope-Date:" ; GNU mailutils "X-Envelope-From:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/ @@ -2632,21 +2632,21 @@ of citations entirely, choose \"None\"." "X-Folder:" ; Spam "X-Forwarded-" ; Google+ "X-From-Line" - "X-FuHaFi:" ; http://www.gmx.net/ + "X-FuHaFi:" ; https://www.gmx.net/ "X-Generated-By:" ; launchpad.net "X-Gmail-" ; Gmail "X-Gnus-Mail-Source:" ; gnus "X-Google-" ; Google mail "X-Google-Sender-Auth:" "X-Greylist:" ; milter-greylist-1.2.1 - "X-Habeas-" ; http://www.returnpath.net + "X-Habeas-" ; https://www.returnpath.net "X-Hashcash:" ; hashcash "X-Headers-End:" ; SpamCop "X-HPL-" "X-HR-" "X-HTTP-UserAgent:" "X-Hz" ; Hertz - "X-Identity:" ; http://www.declude.com/x-note.htm + "X-Identity:" ; http://www.declude.com/x-note.htm [dead link?] "X-IEEE-UCE-" ; IEEE spam filter "X-Image-URL:" "X-IMAP:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/ @@ -2667,7 +2667,7 @@ of citations entirely, choose \"None\"." "X-Loop:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/ "X-Lrde-Mailscanner:" "X-Lumos-SenderID:" ; Roving ConstantContact - "X-mail_abuse_inquiries:" ; http://www.salesforce.com + "X-mail_abuse_inquiries:" ; https://www.salesforce.com "X-Mail-from:" ; fastmail.fm "X-MAIL-INFO:" ; NetZero "X-Mailer_" @@ -2680,11 +2680,11 @@ of citations entirely, choose \"None\"." "X-Mailutils-Message-Id" ; GNU Mailutils "X-Majordomo:" ; Majordomo mailing list manager "X-Match:" - "X-MaxCode-Template:" ; Paypal http://www.paypal.com + "X-MaxCode-Template:" ; Paypal https://www.paypal.com "X-MB-Message-" ; AOL WebMail "X-MDaemon-Deliver-To:" "X-MDRemoteIP:" - "X-ME-Bayesian:" ; http://www.newmediadevelopment.net/page.cfm/parent/Client-Area/content/Managing-spam/ + "X-ME-Bayesian:" ; https://www.newmediadevelopment.net/page.cfm/parent/Client-Area/content/Managing-spam/ "X-Message-Id" "X-Message-Type:" "X-MessageWall-Score:" ; Unknown mailing list manager, AUC TeX @@ -2755,7 +2755,7 @@ of citations entirely, choose \"None\"." "X-Server-Date:" "X-Server-Uuid:" "X-Service-Code:" - "X-SFDC-" ; http://www.salesforce.com + "X-SFDC-" ; https://www.salesforce.com "X-Sieve:" ; Sieve filtering "X-SMFBL:" "X-SMHeaderMap:" @@ -2770,7 +2770,7 @@ of citations entirely, choose \"None\"." "X-Submissions-To:" "X-Sun-Charset:" "X-Telecom-Digest" - "X-TM-IMSS-Message-ID:" ; http://www.trendmicro.com + "X-TM-IMSS-Message-ID:" ; https://www.trendmicro.com "X-Trace:" "X-UID" "X-UIDL:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/ @@ -2790,10 +2790,10 @@ of citations entirely, choose \"None\"." "X-WebTV-Signature:" "X-Wss-Id:" ; Worldtalk gateways "X-X-Sender:" ; https://people.dsv.su.se/~jpalme/ietf/mail-headers/ - "X-XPT-XSL-Name:" ; Paypal http://www.paypal.com + "X-XPT-XSL-Name:" ; Paypal https://www.paypal.com "X-xsi-" - "X-XWALL-" ; http://www.dataenter.co.at/doc/xwall_undocumented_config.htm - "X-Y-GMX-Trusted:" ; http://www.gmx.net/ + "X-XWALL-" ; https://www.dataenter.co.at/doc/xwall_undocumented_config.htm + "X-Y-GMX-Trusted:" ; https://www.gmx.net/ "X-Yahoo" "X-Yahoo-Newman-" "X-YMail-" @@ -3039,7 +3039,7 @@ XEmacs. For more information, see URL `ftp://ftp.cs.indiana.edu/pub/faces/compface/compface.tar.z'). Recent versions of XEmacs have internal support for \"X-Face:\" images. If your version of XEmacs does not, then you'll need both \"uncompface\" -and the x-face package (see URL `http://www.jpl.org/ftp/pub/elisp/'). +and the x-face package (see URL `https://www.jpl.org/ftp/pub/elisp/'). Finally, MH-E will display images referenced by the \"X-Image-URL:\" header field if neither the \"Face:\" nor the \"X-Face:\" fields are diff --git a/lisp/mh-e/mh-xface.el b/lisp/mh-e/mh-xface.el index bf704c1857..0b53829b05 100644 --- a/lisp/mh-e/mh-xface.el +++ b/lisp/mh-e/mh-xface.el @@ -365,7 +365,7 @@ Replace the ?/ character with a ?! character and append .png. Also replaces special characters with `mh-url-hexify-string' since not all characters, such as :, are valid within Windows filenames. In addition, replaces * with %2a. See URL -`http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/ifaces/iitemnamelimits/GetValidCharacters.asp'." +`https://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/ifaces/iitemnamelimits/GetValidCharacters.asp'." (format "%s/%s.png" mh-x-image-cache-directory (mh-replace-regexp-in-string "\\*" "%2a" diff --git a/lisp/net/gnutls.el b/lisp/net/gnutls.el index 9c7bcdc261..683abaaa04 100644 --- a/lisp/net/gnutls.el +++ b/lisp/net/gnutls.el @@ -4,7 +4,7 @@ ;; Author: Ted Zlatanov ;; Keywords: comm, tls, ssl, encryption -;; Originally-By: Simon Josefsson (See http://josefsson.org/emacs-security/) +;; Originally-By: Simon Josefsson (See https://josefsson.org/emacs-security/) ;; Thanks-To: Lars Magne Ingebrigtsen ;; This file is part of GNU Emacs. diff --git a/lisp/net/newst-backend.el b/lisp/net/newst-backend.el index c5488650b9..1d3a5e0f7d 100644 --- a/lisp/net/newst-backend.el +++ b/lisp/net/newst-backend.el @@ -67,9 +67,9 @@ considered to be running if the newsticker timer list is not empty." ;; Hard-coding URLs like this is a recipe for propagating obsolete info. (defconst newsticker--raw-url-list-defaults '(("Debian Security Advisories" - "http://www.debian.org/security/dsa.en.rdf") + "https://www.debian.org/security/dsa.en.rdf") ("Debian Security Advisories - Long format" - "http://www.debian.org/security/dsa-long.en.rdf") + "https://www.debian.org/security/dsa-long.en.rdf") ("Emacs Wiki" "https://www.emacswiki.org/emacs?action=rss" nil @@ -77,7 +77,7 @@ considered to be running if the newsticker timer list is not empty." ("LWN (Linux Weekly News)" "https://lwn.net/headlines/rss") ("Quote of the day" - "http://feeds.feedburner.com/quotationspage/qotd" + "https://feeds.feedburner.com/quotationspage/qotd" "07:00" 86400) ("The Register" @@ -1012,7 +1012,7 @@ Argument BUFFER is the buffer of the retrieval process." ;; And another one (20050702)! If description is HTML ;; encoded and starts with a `<', wrap the whole ;; description in a CDATA expression. This happened for - ;; http://www.thefreedictionary.com/_/WoD/rss.aspx?type=quote + ;; https://www.thefreedictionary.com/_/WoD/rss.aspx?type=quote (goto-char (point-min)) (while (re-search-forward "\\(" nil t) @@ -1176,7 +1176,7 @@ URL `http://www.atompub.org/2005/08/17/draft-ietf-atompub-format-11.html'" ;; unxml the content or the summary node. Atom ;; allows for integrating (x)html into the atom ;; structure but we need the raw html string. - ;; e.g. http://www.heise.de/open/news/news-atom.xml + ;; e.g. https://www.heise.de/open/news/news-atom.xml ;; http://feeds.feedburner.com/ru_nix_blogs (or (newsticker--unxml (car (xml-node-children diff --git a/lisp/net/newst-plainview.el b/lisp/net/newst-plainview.el index 705bff666a..76b1ef3764 100644 --- a/lisp/net/newst-plainview.el +++ b/lisp/net/newst-plainview.el @@ -4,7 +4,7 @@ ;; Author: Ulf Jasper ;; Filename: newst-plainview.el -;; URL: http://www.nongnu.org/newsticker +;; URL: https://www.nongnu.org/newsticker ;; Package: newsticker ;; ====================================================================== diff --git a/lisp/net/nsm.el b/lisp/net/nsm.el index 0ce65a35ea..1d9ee6db86 100644 --- a/lisp/net/nsm.el +++ b/lisp/net/nsm.el @@ -640,7 +640,7 @@ References: [1]: Sotirov A, Stevens M et al (2008). \"MD5 considered harmful today - Creating a rogue CA certificate\", -`http://www.win.tue.nl/hashclash/rogue-ca/' +`https://www.win.tue.nl/hashclash/rogue-ca/' [2]: Turner S, Chen L (2011). \"Updated Security Considerations for the MD5 Message-Digest and the HMAC-MD5 Algorithms\", `https://tools.ietf.org/html/rfc6151'" diff --git a/lisp/nxml/rng-cmpct.el b/lisp/nxml/rng-cmpct.el index 45a69a73f3..3d4b9f8741 100644 --- a/lisp/nxml/rng-cmpct.el +++ b/lisp/nxml/rng-cmpct.el @@ -26,7 +26,7 @@ ;; specified in rng-pttrn.el. ;; ;; RELAX NG Compact Syntax is specified by -;; http://relaxng.org/compact.html +;; https://relaxng.org/compact.html ;; ;; This file uses the prefix "rng-c-". diff --git a/lisp/nxml/rng-xsd.el b/lisp/nxml/rng-xsd.el index 81314b85ca..9941aba6eb 100644 --- a/lisp/nxml/rng-xsd.el +++ b/lisp/nxml/rng-xsd.el @@ -24,14 +24,14 @@ ;; The main entry point is `rng-xsd-compile'. The validator ;; knows to use this for the datatype library with URI -;; http://www.w3.org/2001/XMLSchema-datatypes because it +;; https://www.w3.org/2001/XMLSchema-datatypes because it ;; is the value of the rng-dt-compile property on that URI ;; as a symbol. ;; ;; W3C XML Schema Datatypes are specified by -;; http://www.w3.org/TR/xmlschema-2/ +;; https://www.w3.org/TR/xmlschema-2/ ;; Guidelines for using them with RELAX NG are described in -;; http://relaxng.org/xsd.html +;; https://relaxng.org/xsd.html ;;; Code: diff --git a/lisp/obsolete/bruce.el b/lisp/obsolete/bruce.el index 4aa6cd200e..1c3581f7d0 100644 --- a/lisp/obsolete/bruce.el +++ b/lisp/obsolete/bruce.el @@ -30,7 +30,7 @@ ;; Decency Act of 1996. This Act bans "indecent speech", whatever that is, ;; from the Internet. For more on the CDA, see Richard Stallman's essay on ;; censorship, included in the etc directory of emacs distributions 19.34 -;; and up. See also http://www.eff.org/blueribbon.html. +;; and up. See also https://www.eff.org/blueribbon.html. ;; For many years, emacs has included a program called Spook. This program ;; adds a series of "keywords" to email just before it goes out. On the diff --git a/lisp/obsolete/inversion.el b/lisp/obsolete/inversion.el index e61b36cd88..ac7749af5e 100644 --- a/lisp/obsolete/inversion.el +++ b/lisp/obsolete/inversion.el @@ -454,7 +454,7 @@ If it is a URL, wget will be used for download. Optional argument VERSION will restrict the list of available versions to the file matching VERSION exactly, or nil." ;;DIRECTORY should also allow a URL: -;; \"http://ftp1.sourceforge.net/PACKAGE\" +;; \"https://ftp1.sourceforge.net/PACKAGE\" ;; but then I can get file listings easily. (if (symbolp package) (setq package (symbol-name package))) (directory-files directory t diff --git a/lisp/obsolete/nnir.el b/lisp/obsolete/nnir.el index fef76ba327..f2ea5c67ce 100644 --- a/lisp/obsolete/nnir.el +++ b/lisp/obsolete/nnir.el @@ -274,7 +274,7 @@ that it is for swish++, not Namazu." :type '(regexp)) ;; Swish-E. -;; URL: http://swish-e.org/ +;; URL: http://swish-e.org/ [dead link?] ;; Variables `nnir-swish-e-index-files', `nnir-swish-e-program' and ;; `nnir-swish-e-additional-switches' @@ -311,7 +311,7 @@ that it is for swish-e, not Namazu. This could be a server parameter." :type '(regexp)) -;; HyREX engine, see +;; HyREX engine, see [dead link?] (defcustom nnir-hyrex-program "nnir-search" "Name of the nnir-search executable." diff --git a/lisp/obsolete/terminal.el b/lisp/obsolete/terminal.el index d28c4a172f..dbfc79bf91 100644 --- a/lisp/obsolete/terminal.el +++ b/lisp/obsolete/terminal.el @@ -32,7 +32,7 @@ ;; For information on US government censorship of the Internet, and ;; what you can do to bring back freedom of the press, see the web -;; site http://www.vtw.org/ +;; site https://www.eff.org/ [used to be vtw.org but that link is dead] ;;; Code: diff --git a/lisp/obsolete/vc-arch.el b/lisp/obsolete/vc-arch.el index 00e7d26cd7..cfbf981d3c 100644 --- a/lisp/obsolete/vc-arch.el +++ b/lisp/obsolete/vc-arch.el @@ -26,7 +26,7 @@ ;; The home page of the Arch version control system is at ;; -;; http://www.gnuarch.org/ +;; https://www.gnu.org/software/gnu-arch/ ;; ;; This is derived from vc-mcvs.el as follows: ;; - cp vc-mcvs.el vc-arch.el and then M-% mcvs RET arch RET diff --git a/lisp/org/ob-clojure.el b/lisp/org/ob-clojure.el index df2d691f68..9834509fb0 100644 --- a/lisp/org/ob-clojure.el +++ b/lisp/org/ob-clojure.el @@ -38,7 +38,7 @@ ;; For SLIME, the best way to install these components is by following ;; the directions as set out by Phil Hagelberg (Technomancy) on the -;; web page: http://technomancy.us/126 +;; web page: https://technomancy.us/126 ;;; Code: (require 'ob) diff --git a/lisp/org/ob-ocaml.el b/lisp/org/ob-ocaml.el index 0aa91afdb2..5fd6d1e09f 100644 --- a/lisp/org/ob-ocaml.el +++ b/lisp/org/ob-ocaml.el @@ -32,7 +32,7 @@ ;;; Requirements: -;; - tuareg-mode :: http://www-rocq.inria.fr/~acohen/tuareg/ +;; - tuareg-mode :: https://www-rocq.inria.fr/~acohen/tuareg/ ;;; Code: (require 'ob) diff --git a/lisp/pcmpl-x.el b/lisp/pcmpl-x.el index 084f0e66bc..fd147101b6 100644 --- a/lisp/pcmpl-x.el +++ b/lisp/pcmpl-x.el @@ -27,7 +27,7 @@ (require 'pcomplete) -;;;; tlmgr - http://www.tug.org/texlive/tlmgr.html +;;;; tlmgr - https://www.tug.org/texlive/tlmgr.html (defcustom pcmpl-x-tlmgr-program "tlmgr" "Name of the tlmgr program." diff --git a/lisp/play/doctor.el b/lisp/play/doctor.el index 46fd852b4c..bf923f4f2e 100644 --- a/lisp/play/doctor.el +++ b/lisp/play/doctor.el @@ -1583,7 +1583,7 @@ Hack on previous word, setting global variable DOCTOR-OWNER to correct result." E-mail: jo@samaritans.org or\, at your option\, anonymous E-mail: samaritans@anon.twwells.com\ \. or find a Befrienders crisis center at - http://www.befrienders.org/\ \. + https://www.befrienders.org/\ \. (doc$ doctor--please) (doc$ doctor--continue) \.))) (t (doctor-type (doc$ doctor--deathlst))))) diff --git a/lisp/play/morse.el b/lisp/play/morse.el index 8e09c22505..91dc687d19 100644 --- a/lisp/play/morse.el +++ b/lisp/play/morse.el @@ -146,7 +146,7 @@ "NATO phonetic alphabet. See “International Code of Signals” (INTERCO), United States Edition, 1969 Edition (Revised 2003) available from National -Geospatial-Intelligence Agency at URL `http://www.nga.mil/'") +Geospatial-Intelligence Agency at URL `https://www.nga.mil/'") ;;;###autoload (defun morse-region (beg end) diff --git a/lisp/printing.el b/lisp/printing.el index f5d3c82ae9..b9a2e33994 100644 --- a/lisp/printing.el +++ b/lisp/printing.el @@ -264,7 +264,7 @@ Please send all bug fixes and enhancements to ;; Also the gsprint utility comes together with gsview distribution. ;; ;; For more information about gsprint see -;; `http://www.cs.wisc.edu/~ghost/gsview/gsprint.htm'. +;; `https://www.cs.wisc.edu/~ghost/gsview/gsprint.htm'. ;; ;; As an example of gsprint declaration: ;; @@ -950,18 +950,18 @@ Please send all bug fixes and enhancements to ;; * For GNU or Unix system: ;; ;; gs, gv `https://www.gnu.org/software/ghostscript/ghostscript.html' -;; enscript `http://people.ssh.fi/mtr/genscript/' +;; enscript `https://people.ssh.fi/mtr/genscript/' ;; psnup `http://www.knackered.org/angus/psutils/' -;; mpage `http://www.mesa.nl/pub/mpage/' +;; mpage `https://www.mesa.nl/pub/mpage/' ;; ;; * For Windows system: ;; ;; gswin32, gsview32 ;; `https://www.gnu.org/software/ghostscript/ghostscript.html' -;; gsprint `http://www.cs.wisc.edu/~ghost/gsview/gsprint.htm'. -;; enscript `http://people.ssh.fi/mtr/genscript/' +;; gsprint `https://www.cs.wisc.edu/~ghost/gsview/gsprint.htm'. +;; enscript `https://people.ssh.fi/mtr/genscript/' ;; psnup `http://gnuwin32.sourceforge.net/packages/psutils.htm' -;; redmon `http://www.cs.wisc.edu/~ghost/redmon/' +;; redmon `http://www.ghostgum.com.au/software/redmon.htm' ;; ;; ;; Acknowledgments @@ -1520,22 +1520,19 @@ Examples: Useful links: * Information about the print command (print.exe) - `http://www.computerhope.com/printhlp.htm' + `https://www.computerhope.com/printhlp.htm' * RedMon - Redirection Port Monitor (redpr.exe) - `http://www.cs.wisc.edu/~ghost/redmon/index.htm' + `http://www.ghostgum.com.au/software/redmon.htm' * Redirection Port Monitor (redpr.exe on-line help) - `http://www.cs.wisc.edu/~ghost/redmon/en/redmon.htm' + `https://www.cs.wisc.edu/~ghost/redmon/en/redmon.htm' * UNIX man pages: lpr (or type `man lpr') - `http://bama.ua.edu/cgi-bin/man-cgi?lpr' - `http://www.mediacollege.com/cgi-bin/man/page.cgi?section=all&topic=lpr' + `https://linux.die.net/man/1/lpr-cups' * UNIX man pages: lp (or type `man lp') - `http://bama.ua.edu/cgi-bin/man-cgi?lp' - `http://www.mediacollege.com/cgi-bin/man/page.cgi?section=all&topic=lp' -" + `https://linux.die.net/man/1/lp'" :type '(repeat (list :tag "Text Printer" (symbol :tag "Printer Symbol Name") @@ -1760,30 +1757,28 @@ are not printed. Useful links: * GSPRINT - Ghostscript print to Windows printer - `http://www.cs.wisc.edu/~ghost/gsview/gsprint.htm' + `https://www.cs.wisc.edu/~ghost/gsview/gsprint.htm' * Introduction to Ghostscript - `http://www.cs.wisc.edu/~ghost/doc/intro.htm' + `https://www.cs.wisc.edu/~ghost/doc/intro.htm' * How to use Ghostscript - `http://www.cs.wisc.edu/~ghost/doc/cvs/Use.htm' + `https://www.cs.wisc.edu/~ghost/doc/cvs/Use.htm' * Information about the print command (print.exe) - `http://www.computerhope.com/printhlp.htm' + `https://www.computerhope.com/printhlp.htm' * RedMon - Redirection Port Monitor (redpr.exe) - `http://www.cs.wisc.edu/~ghost/redmon/index.htm' + `http://www.ghostgum.com.au/software/redmon.htm' * Redirection Port Monitor (redpr.exe on-line help) - `http://www.cs.wisc.edu/~ghost/redmon/en/redmon.htm' + `https://www.cs.wisc.edu/~ghost/redmon/en/redmon.htm' * UNIX man pages: lpr (or type `man lpr') - `http://bama.ua.edu/cgi-bin/man-cgi?lpr' - `http://www.mediacollege.com/cgi-bin/man/page.cgi?section=all&topic=lpr' + `https://linux.die.net/man/1/lpr-cups' * UNIX man pages: lp (or type `man lp') - `http://bama.ua.edu/cgi-bin/man-cgi?lp' - `http://www.mediacollege.com/cgi-bin/man/page.cgi?section=all&topic=lp' + `https://linux.die.net/man/1/lp' * GNU utilities for w32 (cp.exe) `http://unxutils.sourceforge.net/' @@ -1873,28 +1868,28 @@ Useful links: `https://www.gnu.org/software/gv/manual/gv.html' * GSview Help - `http://www.cs.wisc.edu/~ghost/gsview/gsviewen.htm' + `https://www.cs.wisc.edu/~ghost/gsview/gsviewen.htm' * GSview Help - Common Problems - `http://www.cs.wisc.edu/~ghost/gsview/gsviewen.htm#Common_Problems' + `https://www.cs.wisc.edu/~ghost/gsview/gsviewen.htm#Common_Problems' * GSview Readme (compilation & installation) - `http://www.cs.wisc.edu/~ghost/gsview/Readme.htm' + `https://www.cs.wisc.edu/~ghost/gsview/Readme.htm' * GSview (main site) - `http://www.cs.wisc.edu/~ghost/gsview/index.htm' + `https://www.cs.wisc.edu/~ghost/gsview/index.htm' * Ghostscript, Ghostview and GSview - `http://www.cs.wisc.edu/~ghost/' + `https://www.cs.wisc.edu/~ghost/' * Ghostview - `http://www.cs.wisc.edu/~ghost/gv/index.htm' + `https://www.cs.wisc.edu/~ghost/gv/index.htm' * gv 3.5, June 1997 - `http://www.cs.wisc.edu/~ghost/gv/gv_doc/gv.html' + `http://pages.cs.wisc.edu/~ghost/gv/gv_doc/gv.html' * MacGSView (Mac OS) - `http://www.cs.wisc.edu/~ghost/macos/index.htm' + `http://pages.cs.wisc.edu/~ghost/macos/index.htm' " :type '(string :tag "Ghostview Utility")) @@ -1910,16 +1905,16 @@ See also `pr-path-alist'. Useful links: * Ghostscript, Ghostview and GSview - `http://www.cs.wisc.edu/~ghost/' + `https://www.cs.wisc.edu/~ghost/' * Introduction to Ghostscript - `http://www.cs.wisc.edu/~ghost/doc/intro.htm' + `https://www.cs.wisc.edu/~ghost/doc/intro.htm' * How to use Ghostscript - `http://www.cs.wisc.edu/~ghost/doc/cvs/Use.htm' + `https://www.cs.wisc.edu/~ghost/doc/cvs/Use.htm' * Printer compatibility - `http://www.cs.wisc.edu/~ghost/doc/printer.htm' + `https://www.cs.wisc.edu/~ghost/doc/printer.htm' " :type '(string :tag "Ghostscript Utility")) @@ -1954,13 +1949,13 @@ To see ghostscript documentation for more information: Useful links: * Introduction to Ghostscript - `http://www.cs.wisc.edu/~ghost/doc/intro.htm' + `https://www.cs.wisc.edu/~ghost/doc/intro.htm' * How to use Ghostscript - `http://www.cs.wisc.edu/~ghost/doc/cvs/Use.htm' + `https://www.cs.wisc.edu/~ghost/doc/cvs/Use.htm' * Printer compatibility - `http://www.cs.wisc.edu/~ghost/doc/printer.htm' + `https://www.cs.wisc.edu/~ghost/doc/printer.htm' " :type '(repeat (string :tag "Ghostscript Switch"))) @@ -2407,11 +2402,10 @@ Examples: Useful links: * mpage download (GNU or Unix) - `http://www.mesa.nl/pub/mpage/' + `https://www.mesa.nl/pub/mpage/' * mpage documentation (GNU or Unix - or type `man mpage') - `http://www.cs.umd.edu/faq/guides/manual_unix/node48.html' - `http://www.rt.com/man/mpage.1.html' + `https://linux.die.net/man/1/mpage' * psnup (Windows, GNU or Unix) `http://www.knackered.org/angus/psutils/' @@ -2421,14 +2415,13 @@ Useful links: `http://gnuwin32.sourceforge.net/packages/psutils.htm' * psnup documentation (GNU or Unix - or type `man psnup') - `http://linux.about.com/library/cmd/blcmdl1_psnup.htm' - `http://amath.colorado.edu/computing/software/man/psnup.html' + `https://linux.die.net/man/1/psnup' * GNU Enscript (Windows, GNU or Unix) - `http://people.ssh.com/mtr/genscript/' + `https://people.ssh.com/mtr/genscript/' * GNU Enscript documentation (Windows, GNU or Unix) - `http://people.ssh.com/mtr/genscript/enscript.man.html' + `https://people.ssh.com/mtr/genscript/enscript.man.html' (on GNU or Unix, type `man enscript') " :type '(repeat diff --git a/lisp/progmodes/antlr-mode.el b/lisp/progmodes/antlr-mode.el index 8a1d441773..2a4b348283 100644 --- a/lisp/progmodes/antlr-mode.el +++ b/lisp/progmodes/antlr-mode.el @@ -33,7 +33,7 @@ ;; the manual style, follow all commands mentioned in the documentation of ;; `antlr-mode'. ANTLR is a LL(k)-based recognition tool which generates ;; lexers, parsers and tree transformers in Java, C++ or Sather and can be -;; found at . +;; found at . ;; Bug fixes, bug reports, improvements, and suggestions for the newest version ;; are strongly appreciated. diff --git a/lisp/progmodes/ebnf-abn.el b/lisp/progmodes/ebnf-abn.el index 99b339e223..2a37110f6a 100644 --- a/lisp/progmodes/ebnf-abn.el +++ b/lisp/progmodes/ebnf-abn.el @@ -39,10 +39,6 @@ ;; ;; See the URL: ;; `https://www.ietf.org/rfc/rfc2234.txt' -;; or -;; `http://www.faqs.org/rfcs/rfc2234.html' -;; or -;; `http://www.rnp.br/ietf/rfc/rfc2234.txt' ;; ("Augmented BNF for Syntax Specifications: ABNF"). ;; ;; diff --git a/lisp/progmodes/ebnf-iso.el b/lisp/progmodes/ebnf-iso.el index 12cc72ce1c..b4532c7625 100644 --- a/lisp/progmodes/ebnf-iso.el +++ b/lisp/progmodes/ebnf-iso.el @@ -38,7 +38,7 @@ ;; --------------- ;; ;; See the URL: -;; `http://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html' +;; `https://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html' ;; ("International Standard of the ISO EBNF Notation"). ;; ;; diff --git a/lisp/progmodes/ebnf2ps.el b/lisp/progmodes/ebnf2ps.el index c95b351d0c..7092d2c1d1 100644 --- a/lisp/progmodes/ebnf2ps.el +++ b/lisp/progmodes/ebnf2ps.el @@ -330,7 +330,7 @@ Please send all bug fixes and enhancements to ;; ("Augmented BNF for Syntax Specifications: ABNF"). ;; ;; `iso-ebnf' ebnf2ps recognizes the syntax described in the URL: -;; `http://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html' +;; `https://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html' ;; ("International Standard of the ISO EBNF Notation"). ;; The following variables *ONLY* have effect with this ;; setting: @@ -1783,7 +1783,7 @@ Valid values are: (\"Augmented BNF for Syntax Specifications: ABNF\"). `iso-ebnf' ebnf2ps recognizes the syntax described in the URL: - `http://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html' + `https://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html' (\"International Standard of the ISO EBNF Notation\"). The following variables *ONLY* have effect with this setting: diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el index a8a86478d8..196f2de344 100644 --- a/lisp/progmodes/octave.el +++ b/lisp/progmodes/octave.el @@ -491,8 +491,8 @@ Non-nil means always go to the next Octave code line after sending." 'font-lock-keyword-face) ;; Note: 'end' also serves as the last index in an indexing expression, ;; and 'enumerate' is also a function. - ;; Ref: http://www.mathworks.com/help/matlab/ref/end.html - ;; Ref: http://www.mathworks.com/help/matlab/ref/enumeration.html + ;; Ref: https://www.mathworks.com/help/matlab/ref/end.html + ;; Ref: https://www.mathworks.com/help/matlab/ref/enumeration.html (list (lambda (limit) (while (re-search-forward "\\_" limit 'move) diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 3f8afd9705..84ac8fdb28 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -331,7 +331,7 @@ It is used when `ruby-encoding-magic-comment-style' is set to `custom'." (require 'smie) ;; Here's a simplified BNF grammar, for reference: -;; http://www.cse.buffalo.edu/~regan/cse305/RubyBNF.pdf +;; https://www.cse.buffalo.edu/~regan/cse305/RubyBNF.pdf (defconst ruby-smie-grammar (smie-prec2->grammar (smie-merge-prec2s diff --git a/lisp/progmodes/scheme.el b/lisp/progmodes/scheme.el index 72ac2d95a2..b6972846cd 100644 --- a/lisp/progmodes/scheme.el +++ b/lisp/progmodes/scheme.el @@ -28,7 +28,7 @@ ;; the Lisp mode documented in the Emacs manual. `dsssl-mode' is a ;; variant of scheme-mode for editing DSSSL specifications for SGML ;; documents. [As of Apr 1997, some pointers for DSSSL may be found, -;; for instance, at .] +;; for instance, at .] ;; All these Lisp-ish modes vary basically in details of the language ;; syntax they highlight/indent/index, but dsssl-mode uses "^;;;" as ;; the page-delimiter since ^L isn't normally a valid SGML character. diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el index f1f4d61324..6224b3b5f3 100644 --- a/lisp/progmodes/sql.el +++ b/lisp/progmodes/sql.el @@ -2992,7 +2992,7 @@ displayed." ;; (defconst sql-smie-grammar ;; (smie-prec2->grammar ;; (smie-bnf->prec2 -;; ;; Partly based on http://www.h2database.com/html/grammar.html +;; ;; Partly based on https://www.h2database.com/html/grammar.html ;; '((cmd ("SELECT" select-exp "FROM" select-table-exp) ;; ) ;; (select-exp ("*") (exp) (exp "AS" column-alias)) diff --git a/lisp/progmodes/vera-mode.el b/lisp/progmodes/vera-mode.el index 036b2f447b..4622256bb9 100644 --- a/lisp/progmodes/vera-mode.el +++ b/lisp/progmodes/vera-mode.el @@ -5,7 +5,7 @@ ;; Author: Reto Zimmermann ;; Version: 2.28 ;; Keywords: languages vera -;; WWW: http://www.iis.ee.ethz.ch/~zimmi/emacs/vera-mode.html +;; WWW: https://guest.iis.ee.ethz.ch/~zimmi/emacs/vera-mode.html ;; Yoni Rabkin contacted the maintainer of this ;; file on 18/3/2008, and the maintainer agreed that when a bug is @@ -249,7 +249,7 @@ Add a description of the problem and include a reproducible test case. Feel free to send questions and enhancement requests to . Official distribution is at -URL `http://www.iis.ee.ethz.ch/~zimmi/emacs/vera-mode.html' +URL `https://www.iis.ee.ethz.ch/~zimmi/emacs/vera-mode.html' The Vera Mode Maintainer diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el index c8e55da642..856432ccf1 100644 --- a/lisp/progmodes/vhdl-mode.el +++ b/lisp/progmodes/vhdl-mode.el @@ -6,7 +6,7 @@ ;; Rodney J. Whitby ;; Maintainer: Reto Zimmermann ;; Keywords: languages vhdl -;; WWW: http://www.iis.ee.ethz.ch/~zimmi/emacs/vhdl-mode.html +;; WWW: https://guest.iis.ee.ethz.ch/~zimmi/emacs/vhdl-mode.html ;; Yoni Rabkin contacted the maintainer of this ;; file on 18/3/2008, and the maintainer agreed that when a bug is diff --git a/lisp/repeat.el b/lisp/repeat.el index 84a613da0c..a2b04b81b0 100644 --- a/lisp/repeat.el +++ b/lisp/repeat.el @@ -180,7 +180,7 @@ this function is always whether the value of `this-command' would've been (= repeat-num-input-keys-at-repeat num-input-keys)) ;; An example of the use of (repeat-is-really-this-command) may still be -;; available in ; search for +;; available in ; search for ;; "defun wm-switch-buffer". ;;;;; ******************* THE REPEAT COMMAND ITSELF ******************* ;;;;; diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el index 3d08122091..dc45a7306d 100644 --- a/lisp/textmodes/artist.el +++ b/lisp/textmodes/artist.el @@ -6,7 +6,7 @@ ;; Keywords: mouse ;; Old-Version: 1.2.6 ;; Release-date: 6-Aug-2004 -;; Location: http://www.lysator.liu.se/~tab/artist/ +;; Location: https://www.lysator.liu.se/~tab/artist/ ;; Yoni Rabkin contacted the maintainer of this ;; file on 19/3/2008, and the maintainer agreed that when a bug is filed in diff --git a/lisp/textmodes/bibtex-style.el b/lisp/textmodes/bibtex-style.el index 820033486d..6d01871bc5 100644 --- a/lisp/textmodes/bibtex-style.el +++ b/lisp/textmodes/bibtex-style.el @@ -49,7 +49,7 @@ "REVERSE" "SORT" "STRINGS")) (defconst bibtex-style-functions - ;; From http://www.eeng.dcu.ie/local-docs/btxdocs/btxhak/btxhak/node4.html. + ;; From https://www.eeng.dcu.ie/local-docs/btxdocs/btxhak/btxhak/node4.html. '("<" ">" "=" "+" "-" "*" ":=" "add.period$" "call.type$" "change.case$" "chr.to.int$" "cite$" "duplicate$" "empty$" "format.name$" "if$" "int.to.chr$" "int.to.str$" diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el index 301f7017e4..f01c66b158 100644 --- a/lisp/textmodes/bibtex.el +++ b/lisp/textmodes/bibtex.el @@ -1431,7 +1431,7 @@ If `bibtex-expand-strings' is non-nil, BibTeX strings are expanded for generating the URL. Set this variable before loading BibTeX mode. -The following is a complex example, see URL `http://link.aps.org/'. +The following is a complex example, see URL `https://link.aps.org/'. (((\"journal\" . \"\\\\=<\\(PR[ABCDEL]?\\|RMP\\)\\\\=>\") \"http://link.aps.org/abstract/%s/v%s/p%s\" diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index 622853da45..47b0b517ae 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -427,7 +427,7 @@ "paged-y" "paged-x-controls" "paged-y-controls" "fragments") ;; CSS Text Decoration Module Level 3 - ;; (http://dev.w3.org/csswg/css-text-decor-3/#property-index) + ;; (https://dev.w3.org/csswg/css-text-decor-3/#property-index) ("text-decoration" text-decoration-line text-decoration-style text-decoration-color) ("text-decoration-color" color) diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el index 7de5317b02..6958ab8f65 100644 --- a/lisp/textmodes/sgml-mode.el +++ b/lisp/textmodes/sgml-mode.el @@ -2368,7 +2368,7 @@ or Edit/Text Properties/Face commands. Pages can have named points and can link other points to them with see also somename. In the same way see also URL where URL is a filename relative to current -directory, or absolute as in `http://www.cs.indiana.edu/elisp/w3/docs.html'. +directory, or absolute as in `https://www.cs.indiana.edu/elisp/w3/docs.html'. Images in many formats can be inlined with . diff --git a/lisp/textmodes/table.el b/lisp/textmodes/table.el index a9f066c4da..13b4a6d05b 100644 --- a/lisp/textmodes/table.el +++ b/lisp/textmodes/table.el @@ -2911,11 +2911,11 @@ HTML: URL `https://www.w3.org' LaTeX: - URL `http://www.maths.tcd.ie/~dwilkins/LaTeXPrimer/Tables.html' + URL `https://www.maths.tcd.ie/~dwilkins/LaTeXPrimer/Tables.html' CALS (DocBook DTD): - URL `http://www.oasis-open.org/html/a502.htm' - URL `http://www.oreilly.com/catalog/docbook/chapter/book/table.html#AEN114751' + URL `https://www.oasis-open.org/html/a502.htm' + URL `https://www.oreilly.com/catalog/docbook/chapter/book/table.html#AEN114751' " (interactive (let* ((_ (unless (table--probe-cell) (error "Table not found here"))) diff --git a/lisp/url/ChangeLog.1 b/lisp/url/ChangeLog.1 index 5a3bf3afd1..cdd37a64cd 100644 --- a/lisp/url/ChangeLog.1 +++ b/lisp/url/ChangeLog.1 @@ -2337,7 +2337,7 @@ recurse when retrieving the property lists. Returns an assoc list keyed off of the resource, the cdr of which is a property list. (url-dav-datatype-attribute): We support the XML-Data note - (http://www.w3.org/TR/1998/NOTE-XML-data) to figure out what the + (https://www.w3.org/TR/1998/NOTE-XML-data) to figure out what the datatypes of attributes are. Currently only date, dateTime, int, number, float, boolean, and uri are supported. diff --git a/lisp/url/url-cookie.el b/lisp/url/url-cookie.el index 085159cb50..27f4f88cb8 100644 --- a/lisp/url/url-cookie.el +++ b/lisp/url/url-cookie.el @@ -60,7 +60,7 @@ (defcustom url-cookie-multiple-line nil "If nil, HTTP requests put all cookies for the server on one line. -Some web servers, such as http://www.hotmail.com/, only accept cookies +Some web servers, such as https://www.hotmail.com/, only accept cookies when they are on one line. This is broken behavior, but just try telling Microsoft that." :type 'boolean diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 342b4cc32b..2c72c45f4b 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -2826,7 +2826,7 @@ hunk text is not found in the source file." ;;; Support for converting a diff to diff3 markers via `wiggle'. -;; Wiggle can be found at http://neil.brown.name/wiggle/ or in your nearest +;; Wiggle can be found at https://neil.brown.name/wiggle/ or in your nearest ;; Debian repository. (defun diff-wiggle () diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index 465ed8735c..fda8605c67 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -252,7 +252,7 @@ included in the completions." ;; Do not use the `file-name-directory' here: git-ls-files ;; sometimes fails to return the correct status for relative ;; path specs. - ;; See also: http://marc.info/?l=git&m=125787684318129&w=2 + ;; See also: https://marc.info/?l=git&m=125787684318129&w=2 (name (file-relative-name file dir)) (str (with-demoted-errors "Error: %S" (cd dir) commit a4ececf004e5442fc245ccff910000fe407f7212 Author: Lars Ingebrigtsen Date: Wed Mar 24 09:22:40 2021 +0100 Move string-trim functions to subr.el * doc/lispref/strings.texi (Creating Strings): Document them. * lisp/faces.el: Don't require subr-x, because that leads to build errors. * lisp/subr.el (string-trim, string-trim-right) (string-trim-left): Move here from subr-x.el. * lisp/emacs-lisp/shortdoc.el (string): Adjust. diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 5cae939b7b..b4d7bc729f 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -390,6 +390,22 @@ whitespace to a single space character, as well as removing all whitespace from the start and the end of @var{string}. @end defun +@defun string-trim-left string &optional regexp +Remove the leading text that matches @var{regexp} from @var{string}. +@var{regexp} defaults to @samp{[ \t\n\r]+}. +@end defun + +@defun string-trim-right string &optional regexp +Remove the trailing text that matches @var{regexp} from @var{string}. +@var{regexp} defaults to @samp{[ \t\n\r]+}. +@end defun + +@defun string-trim string &optional trim-left trim-right +Remove the leading text that matches @var{trim-left} and trailing text +that matches @var{trim-right} from from @var{string}. Both regexps +default to @samp{[ \t\n\r]+}. +@end defun + @defun string-fill string length Attempt to Word-wrap @var{string} so that no lines are longer than @var{length}. Filling is done on whitespace boundaries only. If diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index 789d6325e9..86d5130bbe 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -168,15 +168,12 @@ There can be any number of :example/:result elements." (replace-regexp-in-string :eval (replace-regexp-in-string "[a-z]+" "_" "*foo*")) (string-trim - :no-manual t :args (string) :doc "Trim STRING of leading and trailing white space." :eval (string-trim " foo ")) (string-trim-left - :no-manual t :eval (string-trim-left "oofoo" "o+")) (string-trim-right - :no-manual t :eval (string-trim-right "barkss" "s+")) (string-truncate-left :no-manual t diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index a4514454c0..9c8c967ee9 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -215,28 +215,6 @@ The variable list SPEC is the same as in `if-let'." (define-obsolete-function-alias 'string-reverse 'reverse "25.1") -(defsubst string-trim-left (string &optional regexp) - "Trim STRING of leading string matching REGEXP. - -REGEXP defaults to \"[ \\t\\n\\r]+\"." - (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+") "\\)") string) - (substring string (match-end 0)) - string)) - -(defsubst string-trim-right (string &optional regexp) - "Trim STRING of trailing string matching REGEXP. - -REGEXP defaults to \"[ \\t\\n\\r]+\"." - (let ((i (string-match-p (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") - string))) - (if i (substring string 0 i) string))) - -(defsubst string-trim (string &optional trim-left trim-right) - "Trim STRING of leading and trailing strings matching TRIM-LEFT and TRIM-RIGHT. - -TRIM-LEFT and TRIM-RIGHT default to \"[ \\t\\n\\r]+\"." - (string-trim-left (string-trim-right string trim-right) trim-left)) - ;;;###autoload (defun string-truncate-left (string length) "Truncate STRING to LENGTH, replacing initial surplus with \"...\"." diff --git a/lisp/faces.el b/lisp/faces.el index 10675563ea..3ea4c940a3 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -25,8 +25,6 @@ ;;; Code: -(eval-when-compile (require 'subr-x)) - (defcustom term-file-prefix (purecopy "term/") "If non-nil, Emacs startup performs terminal-specific initialization. It does this by: (load (concat term-file-prefix (getenv \"TERM\"))) diff --git a/lisp/subr.el b/lisp/subr.el index ef0e5e6f78..1b93fcf410 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -6200,6 +6200,28 @@ returned list are in the same order as in TREE. ;; for discoverability: (defalias 'flatten-list #'flatten-tree) +(defun string-trim-left (string &optional regexp) + "Trim STRING of leading string matching REGEXP. + +REGEXP defaults to \"[ \\t\\n\\r]+\"." + (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+") "\\)") string) + (substring string (match-end 0)) + string)) + +(defun string-trim-right (string &optional regexp) + "Trim STRING of trailing string matching REGEXP. + +REGEXP defaults to \"[ \\t\\n\\r]+\"." + (let ((i (string-match-p (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") + string))) + (if i (substring string 0 i) string))) + +(defun string-trim (string &optional trim-left trim-right) + "Trim STRING of leading and trailing strings matching TRIM-LEFT and TRIM-RIGHT. + +TRIM-LEFT and TRIM-RIGHT default to \"[ \\t\\n\\r]+\"." + (string-trim-left (string-trim-right string trim-right) trim-left)) + ;; The initial anchoring is for better performance in searching matches. (defconst regexp-unmatchable "\\`a\\`" "Standard regexp guaranteed not to match any string at all.") commit c0d24d5316626a3d5e76f99a0f418463cb355459 Author: Stefan Kangas Date: Wed Mar 24 09:09:52 2021 +0100 Use lexical-binding in iimage.el * lisp/iimage.el: Use lexical-binding. Remove redundant :group args. diff --git a/lisp/iimage.el b/lisp/iimage.el index cc1461d7b0..192530a8e6 100644 --- a/lisp/iimage.el +++ b/lisp/iimage.el @@ -1,4 +1,4 @@ -;;; iimage.el --- Inline image minor mode. +;;; iimage.el --- Inline image minor mode. -*- lexical-binding: t -*- ;; Copyright (C) 2004-2021 Free Software Foundation, Inc. @@ -51,8 +51,7 @@ (defcustom iimage-mode-image-search-path nil "List of directories to search for image files for iimage-mode." - :type '(choice (const nil) (repeat directory)) - :group 'iimage) + :type '(choice (const nil) (repeat directory))) (defvar iimage-mode-image-filename-regex (concat "[-+./_0-9a-zA-Z]+\\." @@ -74,14 +73,12 @@ Examples of image filename patterns to match: \\=`file://foo.png\\=' \\[\\[foo.gif]] - foo.JPG -" - :type '(alist :key-type regexp :value-type integer) - :group 'iimage) + foo.JPG" + :type '(alist :key-type regexp :value-type integer)) (defvar iimage-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\C-l" 'iimage-recenter) + (define-key map "\C-l" #'iimage-recenter) map) "Keymap used in `iimage-mode'.") commit df06cfe4a9859a00d7ea046be8f82f1b9e4564ec Author: Stefan Kangas Date: Wed Mar 24 09:05:06 2021 +0100 * lisp/talk.el: Use lexical-binding. diff --git a/lisp/talk.el b/lisp/talk.el index 473f8ac921..56d36dd8df 100644 --- a/lisp/talk.el +++ b/lisp/talk.el @@ -1,4 +1,4 @@ -;;; talk.el --- allow several users to talk to each other through Emacs +;;; talk.el --- allow several users to talk to each other through Emacs -*- lexical-binding: t -*- ;; Copyright (C) 1995, 2001-2021 Free Software Foundation, Inc. @@ -23,7 +23,7 @@ ;;; Commentary: ;; This is a multi-user talk package that runs in Emacs. -;; Use talk-connect to bring a new person into the conversation. +;; Use `talk-connect' to bring a new person into the conversation. ;;; Code: commit 1ae8a18d949e3a3dc3f7a6f2284ecb35871416ca Author: Stefan Kangas Date: Wed Mar 24 06:33:45 2021 +0100 Use lexical-binding in two trivial org-mode files This change has already been made on org-mode's master branch. * lisp/org/org-install.el: * lisp/org/org-version.el: Use lexical-binding. diff --git a/lisp/org/org-install.el b/lisp/org/org-install.el index 5835959736..d521d819db 100644 --- a/lisp/org/org-install.el +++ b/lisp/org/org-install.el @@ -1,4 +1,4 @@ -;;; org-install.el --- backward compatibility file for obsolete configuration +;;; org-install.el --- backward compatibility file for obsolete configuration -*- lexical-binding: t -*- ;; ;;; Code: ;; diff --git a/lisp/org/org-version.el b/lisp/org/org-version.el index 25b3354bdd..8871ef798d 100644 --- a/lisp/org/org-version.el +++ b/lisp/org/org-version.el @@ -1,4 +1,4 @@ -;;; org-version.el --- autogenerated file, do not edit +;;; org-version.el --- autogenerated file, do not edit -*- lexical-binding: t -*- ;; ;;; Code: ;;;###autoload commit 6e974130d709e9e8624dab5c24a6639c0331cb77 Author: Stefan Kangas Date: Wed Mar 24 06:31:23 2021 +0100 * lisp/help-at-pt.el: Use lexical-binding. diff --git a/lisp/help-at-pt.el b/lisp/help-at-pt.el index e17bd0a081..233c50504b 100644 --- a/lisp/help-at-pt.el +++ b/lisp/help-at-pt.el @@ -1,4 +1,4 @@ -;;; help-at-pt.el --- local help through the keyboard +;;; help-at-pt.el --- local help through the keyboard -*- lexical-binding: t -*- ;; Copyright (C) 2003-2021 Free Software Foundation, Inc. @@ -42,9 +42,6 @@ ;; ;; (global-set-key [C-tab] 'scan-buf-next-region) ;; (global-set-key [C-M-tab] 'scan-buf-previous-region) -;; -;; You do not have to do anything special to use the functionality -;; provided by this file, because all important functions autoload. ;;; Code: commit ca194ae5c9d63c032827af6c58132b066bce7fbd Author: Stefan Kangas Date: Wed Mar 24 06:23:10 2021 +0100 * lisp/progmodes/simula.el (hilit-set-mode-patterns): Use regexp-opt. diff --git a/lisp/progmodes/simula.el b/lisp/progmodes/simula.el index ef157ce4ab..f92f446809 100644 --- a/lisp/progmodes/simula.el +++ b/lisp/progmodes/simula.el @@ -1573,7 +1573,19 @@ If not nil and not t, move to limit of search and return nil." ("^%\\([ \t\f].*\\)?$" nil comment) ("^%include\\>" nil include) ("\"[^\"\n]*\"\\|'.'\\|'![0-9]+!'" nil string) - ("\\<\\(ACTIVATE\\|AFTER\\|AND\\|ARRAY\\|AT\\|BEFORE\\|BEGIN\\|BOOLEAN\\|CHARACTER\\|CLASS\\|DELAY\\|DO\\|ELSE\\|END\\|EQ\\|EQV\\|EXTERNAL\\|FALSE\\|FOR\\|GE\\|GO\\|GOTO\\|GT\\|HIDDEN\\|IF\\|IMP\\|IN\\|INNER\\|INSPECT\\|INTEGER\\|IS\\|LABEL\\|LE\\|LONG\\|LT\\|NAME\\|NE\\|NEW\\|NONE\\|NOT\\|NOTEXT\\|OR\\|OTHERWISE\\|PRIOR\\|PROCEDURE\\|PROTECTED\\|QUA\\|REACTIVATE\\|REAL\\|REF\\|SHORT\\|STEP\\|SWITCH\\|TEXT\\|THEN\\|THIS\\|TO\\|TRUE\\|UNTIL\\|VALUE\\|VIRTUAL\\|WHEN\\|WHILE\\)\\>" nil keyword) + ((regexp-opt '("ACTIVATE" "AFTER" "AND" "ARRAY" "AT" "BEFORE" + "BEGIN" "BOOLEAN" "CHARACTER" "CLASS" "DELAY" + "DO" "ELSE" "END" "EQ" "EQV" "EXTERNAL" "FALSE" + "FOR" "GE" "GO" "GOTO" "GT" "HIDDEN" "IF" "IMP" + "IN" "INNER" "INSPECT" "INTEGER" "IS" "LABEL" + "LE" "LONG" "LT" "NAME" "NE" "NEW" "NONE" "NOT" + "NOTEXT" "OR" "OTHERWISE" "PRIOR" "PROCEDURE" + "PROTECTED" "QUA" "REACTIVATE" "REAL" "REF" + "SHORT" "STEP" "SWITCH" "TEXT" "THEN" "THIS" + "TO" "TRUE" "UNTIL" "VALUE" "VIRTUAL" "WHEN" + "WHILE") + 'words) + nil keyword) ("!\\|\\" ";" comment)) nil 'case-insensitive))) commit 6927f237679e73343aea0d70e356fc247c05c4d6 Author: Stefan Kangas Date: Wed Mar 24 06:20:33 2021 +0100 * lisp/progmodes/modula2.el: Use lexical-binding. diff --git a/lisp/progmodes/modula2.el b/lisp/progmodes/modula2.el index 536d3be005..2a0374aa81 100644 --- a/lisp/progmodes/modula2.el +++ b/lisp/progmodes/modula2.el @@ -1,4 +1,4 @@ -;;; modula2.el --- Modula-2 editing support package +;;; modula2.el --- Modula-2 editing support package -*- lexical-binding: t -*- ;; Author: Michael Schmidt ;; Tom Perrine @@ -69,33 +69,33 @@ (defvar m2-mode-map (let ((map (make-sparse-keymap))) ;; FIXME: Many of those bindings are contrary to coding conventions. - (define-key map "\C-cb" 'm2-begin) - (define-key map "\C-cc" 'm2-case) - (define-key map "\C-cd" 'm2-definition) - (define-key map "\C-ce" 'm2-else) - (define-key map "\C-cf" 'm2-for) - (define-key map "\C-ch" 'm2-header) - (define-key map "\C-ci" 'm2-if) - (define-key map "\C-cm" 'm2-module) - (define-key map "\C-cl" 'm2-loop) - (define-key map "\C-co" 'm2-or) - (define-key map "\C-cp" 'm2-procedure) - (define-key map "\C-c\C-w" 'm2-with) - (define-key map "\C-cr" 'm2-record) - (define-key map "\C-cs" 'm2-stdio) - (define-key map "\C-ct" 'm2-type) - (define-key map "\C-cu" 'm2-until) - (define-key map "\C-cv" 'm2-var) - (define-key map "\C-cw" 'm2-while) - (define-key map "\C-cx" 'm2-export) - (define-key map "\C-cy" 'm2-import) - (define-key map "\C-c{" 'm2-begin-comment) - (define-key map "\C-c}" 'm2-end-comment) - (define-key map "\C-c\C-z" 'suspend-emacs) - (define-key map "\C-c\C-v" 'm2-visit) - (define-key map "\C-c\C-t" 'm2-toggle) - (define-key map "\C-c\C-l" 'm2-link) - (define-key map "\C-c\C-c" 'm2-compile) + (define-key map "\C-cb" #'m2-begin) + (define-key map "\C-cc" #'m2-case) + (define-key map "\C-cd" #'m2-definition) + (define-key map "\C-ce" #'m2-else) + (define-key map "\C-cf" #'m2-for) + (define-key map "\C-ch" #'m2-header) + (define-key map "\C-ci" #'m2-if) + (define-key map "\C-cm" #'m2-module) + (define-key map "\C-cl" #'m2-loop) + (define-key map "\C-co" #'m2-or) + (define-key map "\C-cp" #'m2-procedure) + (define-key map "\C-c\C-w" #'m2-with) + (define-key map "\C-cr" #'m2-record) + (define-key map "\C-cs" #'m2-stdio) + (define-key map "\C-ct" #'m2-type) + (define-key map "\C-cu" #'m2-until) + (define-key map "\C-cv" #'m2-var) + (define-key map "\C-cw" #'m2-while) + (define-key map "\C-cx" #'m2-export) + (define-key map "\C-cy" #'m2-import) + (define-key map "\C-c{" #'m2-begin-comment) + (define-key map "\C-c}" #'m2-end-comment) + (define-key map "\C-c\C-z" #'suspend-emacs) + (define-key map "\C-c\C-v" #'m2-visit) + (define-key map "\C-c\C-t" #'m2-toggle) + (define-key map "\C-c\C-l" #'m2-link) + (define-key map "\C-c\C-c" #'m2-compile) map) "Keymap used in Modula-2 mode.") commit 673d281b82886490707f3356a87b5a992d1dc0ed Author: Stefan Kangas Date: Wed Mar 24 05:46:11 2021 +0100 Use lexical-binding in view.el * lisp/view.el: Use lexical-binding. Remove redundant :group args. diff --git a/lisp/view.el b/lisp/view.el index 479a4522a4..3476ced3f7 100644 --- a/lisp/view.el +++ b/lisp/view.el @@ -1,4 +1,4 @@ -;;; view.el --- peruse file or buffer without editing +;;; view.el --- peruse file or buffer without editing -*- lexical-binding: t -*- ;; Copyright (C) 1985, 1989, 1994-1995, 1997, 2000-2021 Free Software ;; Foundation, Inc. @@ -51,31 +51,27 @@ :group 'text) (defcustom view-highlight-face 'highlight - "The face used for highlighting the match found by View mode search." - :type 'face - :group 'view) + "The face used for highlighting the match found by View mode search." + :type 'face) (defcustom view-scroll-auto-exit nil "Non-nil means scrolling past the end of buffer exits View mode. A value of nil means attempting to scroll past the end of the buffer, only rings the bell and gives a message on how to leave." - :type 'boolean - :group 'view) + :type 'boolean) (defcustom view-try-extend-at-buffer-end nil "Non-nil means try to load more of file when reaching end of buffer. This variable is mainly intended to be temporarily set to non-nil by the F command in `view-mode', but you can set it to t if you want the action for all scroll commands in view mode." - :type 'boolean - :group 'view) + :type 'boolean) ;;;###autoload (defcustom view-remove-frame-by-deleting t "Determine how View mode removes a frame no longer needed. If nil, make an icon of the frame. If non-nil, delete the frame." :type 'boolean - :group 'view :version "23.1") (defcustom view-exits-all-viewing-windows nil @@ -84,15 +80,13 @@ Commands that restore windows when finished viewing a buffer, apply to all windows that display the buffer and have restore information. If `view-exits-all-viewing-windows' is nil, only the selected window is considered for restoring." - :type 'boolean - :group 'view) + :type 'boolean) (defcustom view-inhibit-help-message nil "Non-nil inhibits the help message shown upon entering View mode. This setting takes effect only when View mode is entered via an interactive command; otherwise the help message is not shown." :type 'boolean - :group 'view :version "22.1") ;;;###autoload @@ -103,8 +97,7 @@ functions that enable or disable view mode.") (defcustom view-mode-hook nil "Normal hook run when starting to view a buffer or file." - :type 'hook - :group 'view) + :type 'hook) (defvar-local view-old-buffer-read-only nil) @@ -154,62 +147,62 @@ This is local in each buffer, once it is used.") ;; Some redundant "less"-like key bindings below have been commented out. (defvar view-mode-map (let ((map (make-sparse-keymap))) - (define-key map "C" 'View-kill-and-leave) - (define-key map "c" 'View-leave) - (define-key map "Q" 'View-quit-all) - (define-key map "E" 'View-exit-and-edit) - ;; (define-key map "v" 'View-exit) - (define-key map "e" 'View-exit) - (define-key map "q" 'View-quit) - ;; (define-key map "N" 'View-search-last-regexp-backward) - (define-key map "p" 'View-search-last-regexp-backward) - (define-key map "n" 'View-search-last-regexp-forward) - ;; (define-key map "?" 'View-search-regexp-backward) ; Less does this. - (define-key map "\\" 'View-search-regexp-backward) - (define-key map "/" 'View-search-regexp-forward) - (define-key map "r" 'isearch-backward) - (define-key map "s" 'isearch-forward) - (define-key map "m" 'point-to-register) - (define-key map "'" 'register-to-point) - (define-key map "x" 'exchange-point-and-mark) - (define-key map "@" 'View-back-to-mark) - (define-key map "." 'set-mark-command) - (define-key map "%" 'View-goto-percent) - ;; (define-key map "G" 'View-goto-line-last) - (define-key map "g" 'View-goto-line) - (define-key map "=" 'what-line) - (define-key map "F" 'View-revert-buffer-scroll-page-forward) - ;; (define-key map "k" 'View-scroll-line-backward) - (define-key map "y" 'View-scroll-line-backward) - ;; (define-key map "j" 'View-scroll-line-forward) - (define-key map "\n" 'View-scroll-line-forward) - (define-key map "\r" 'View-scroll-line-forward) - (define-key map "u" 'View-scroll-half-page-backward) - (define-key map "d" 'View-scroll-half-page-forward) - (define-key map "z" 'View-scroll-page-forward-set-page-size) - (define-key map "w" 'View-scroll-page-backward-set-page-size) - ;; (define-key map "b" 'View-scroll-page-backward) - (define-key map "\C-?" 'View-scroll-page-backward) - ;; (define-key map "f" 'View-scroll-page-forward) - (define-key map " " 'View-scroll-page-forward) - (define-key map [?\S-\ ] 'View-scroll-page-backward) - (define-key map "o" 'View-scroll-to-buffer-end) - (define-key map ">" 'end-of-buffer) - (define-key map "<" 'beginning-of-buffer) - (define-key map "-" 'negative-argument) - (define-key map "9" 'digit-argument) - (define-key map "8" 'digit-argument) - (define-key map "7" 'digit-argument) - (define-key map "6" 'digit-argument) - (define-key map "5" 'digit-argument) - (define-key map "4" 'digit-argument) - (define-key map "3" 'digit-argument) - (define-key map "2" 'digit-argument) - (define-key map "1" 'digit-argument) - (define-key map "0" 'digit-argument) - (define-key map "H" 'describe-mode) - (define-key map "?" 'describe-mode) ; Maybe do as less instead? See above. - (define-key map "h" 'describe-mode) + (define-key map "C" #'View-kill-and-leave) + (define-key map "c" #'View-leave) + (define-key map "Q" #'View-quit-all) + (define-key map "E" #'View-exit-and-edit) + ;; (define-key map "v" #'View-exit) + (define-key map "e" #'View-exit) + (define-key map "q" #'View-quit) + ;; (define-key map "N" #'View-search-last-regexp-backward) + (define-key map "p" #'View-search-last-regexp-backward) + (define-key map "n" #'View-search-last-regexp-forward) + ;; (define-key map "?" #'View-search-regexp-backward) ; Less does this. + (define-key map "\\" #'View-search-regexp-backward) + (define-key map "/" #'View-search-regexp-forward) + (define-key map "r" #'isearch-backward) + (define-key map "s" #'isearch-forward) + (define-key map "m" #'point-to-register) + (define-key map "'" #'register-to-point) + (define-key map "x" #'exchange-point-and-mark) + (define-key map "@" #'View-back-to-mark) + (define-key map "." #'set-mark-command) + (define-key map "%" #'View-goto-percent) + ;; (define-key map "G" #'View-goto-line-last) + (define-key map "g" #'View-goto-line) + (define-key map "=" #'what-line) + (define-key map "F" #'View-revert-buffer-scroll-page-forward) + ;; (define-key map "k" #'View-scroll-line-backward) + (define-key map "y" #'View-scroll-line-backward) + ;; (define-key map "j" #'View-scroll-line-forward) + (define-key map "\n" #'View-scroll-line-forward) + (define-key map "\r" #'View-scroll-line-forward) + (define-key map "u" #'View-scroll-half-page-backward) + (define-key map "d" #'View-scroll-half-page-forward) + (define-key map "z" #'View-scroll-page-forward-set-page-size) + (define-key map "w" #'View-scroll-page-backward-set-page-size) + ;; (define-key map "b" #'View-scroll-page-backward) + (define-key map "\C-?" #'View-scroll-page-backward) + ;; (define-key map "f" #'View-scroll-page-forward) + (define-key map " " #'View-scroll-page-forward) + (define-key map [?\S-\ ] #'View-scroll-page-backward) + (define-key map "o" #'View-scroll-to-buffer-end) + (define-key map ">" #'end-of-buffer) + (define-key map "<" #'beginning-of-buffer) + (define-key map "-" #'negative-argument) + (define-key map "9" #'digit-argument) + (define-key map "8" #'digit-argument) + (define-key map "7" #'digit-argument) + (define-key map "6" #'digit-argument) + (define-key map "5" #'digit-argument) + (define-key map "4" #'digit-argument) + (define-key map "3" #'digit-argument) + (define-key map "2" #'digit-argument) + (define-key map "1" #'digit-argument) + (define-key map "0" #'digit-argument) + (define-key map "H" #'describe-mode) + (define-key map "?" #'describe-mode) ; Maybe do as less instead? See above. + (define-key map "h" #'describe-mode) map)) ;;; Commands that enter or exit view mode. commit a902af6c1b04abcac4d6d221a2b0086cc076bda1 Author: Stefan Kangas Date: Wed Mar 24 06:06:41 2021 +0100 Delete some commented out defgroups * lisp/eshell/esh-opt.el: * lisp/international/ccl.el: * lisp/pcmpl-linux.el: * lisp/shell.el: * lisp/url/url-news.el: Delete some commented out defgroups. diff --git a/lisp/eshell/esh-opt.el b/lisp/eshell/esh-opt.el index c1db484be5..7d31845528 100644 --- a/lisp/eshell/esh-opt.el +++ b/lisp/eshell/esh-opt.el @@ -23,14 +23,6 @@ ;;; Code: - -;; Unused. -;; (defgroup eshell-opt nil -;; "The options processing code handles command argument parsing for -;; Eshell commands implemented in Lisp." -;; :tag "Command options processing" -;; :group 'eshell) - ;;; User Functions: ;; Macro expansion of eshell-eval-using-options refers to eshell-stringify-list diff --git a/lisp/international/ccl.el b/lisp/international/ccl.el index 3c5a461a31..0eb009fa52 100644 --- a/lisp/international/ccl.el +++ b/lisp/international/ccl.el @@ -43,12 +43,6 @@ ;;; Code: -;; Unused. -;;; (defgroup ccl nil -;;; "CCL (Code Conversion Language) compiler." -;;; :prefix "ccl-" -;;; :group 'i18n) - (defconst ccl-command-table [if branch loop break repeat write-repeat write-read-repeat read read-if read-branch write call end diff --git a/lisp/pcmpl-linux.el b/lisp/pcmpl-linux.el index 263d646dc6..39d4add2be 100644 --- a/lisp/pcmpl-linux.el +++ b/lisp/pcmpl-linux.el @@ -31,11 +31,6 @@ (require 'pcomplete) -;; Unused. -;;; (defgroup pcmpl-linux nil -;;; "Functions for dealing with GNU/Linux completions." -;;; :group 'pcomplete) - ;; Functions: ;;;###autoload diff --git a/lisp/shell.el b/lisp/shell.el index 7f4ca76547..cd99b00877 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -110,11 +110,6 @@ "Directory support in shell mode." :group 'shell) -;; Unused. -;;; (defgroup shell-faces nil -;;; "Faces in shell buffers." -;;; :group 'shell) - ;;;###autoload (defcustom shell-dumb-shell-regexp (purecopy "cmd\\(proxy\\)?\\.exe") "Regexp to match shells that don't save their command history, and diff --git a/lisp/url/url-news.el b/lisp/url/url-news.el index 585a28291a..49cc587590 100644 --- a/lisp/url/url-news.el +++ b/lisp/url/url-news.el @@ -27,11 +27,6 @@ (require 'nntp) (autoload 'gnus-group-read-ephemeral-group "gnus-group") -;; Unused. -;;; (defgroup url-news nil -;;; "News related options." -;;; :group 'url) - (defun url-news-open-host (host port user pass) (if (fboundp 'nnheader-init-server-buffer) (nnheader-init-server-buffer)) commit e2613f41213c89bfd90d34a7a5fb120e7366ec6d Author: Stefan Kangas Date: Wed Mar 24 05:43:53 2021 +0100 Doc fixes in view.el * lisp/view.el: (view-try-extend-at-buffer-end, kill-buffer-if-not-modified) (view-buffer, view-buffer-other-window, view-buffer-other-frame) (view-page-size-default, view-set-half-page-size-default) (view-really-at-end, view-end-message) (view-search-no-match-lines): Doc fixes. diff --git a/lisp/view.el b/lisp/view.el index 026c1ece30..479a4522a4 100644 --- a/lisp/view.el +++ b/lisp/view.el @@ -26,9 +26,9 @@ ;; This package provides the `view' minor mode documented in the Emacs ;; user's manual. -;; View mode entry and exit is done through the functions view-mode-enter -;; and view-mode-exit. Use these functions to enter or exit view-mode from -;; emacs lisp programs. +;; View mode entry and exit is done through the functions `view-mode-enter' +;; and `view-mode-exit'. Use these functions to enter or exit `view-mode' from +;; Emacs Lisp programs. ;; We use both view- and View- as prefix for symbols. View- is used as ;; prefix for commands that have a key binding. view- is used for commands ;; without key binding. The purpose of this is to make it easier for a @@ -36,11 +36,11 @@ ;;; Suggested key bindings: ;; -;; (define-key ctl-x-4-map "v" 'view-file-other-window) ; ^x4v -;; (define-key ctl-x-5-map "v" 'view-file-other-frame) ; ^x5v +;; (define-key ctl-x-4-map "v" #'view-file-other-window) ; ^x4v +;; (define-key ctl-x-5-map "v" #'view-file-other-frame) ; ^x5v ;; -;; You could also bind view-file, view-buffer, view-buffer-other-window and -;; view-buffer-other-frame to keys. +;; You could also bind `view-file', `view-buffer', `view-buffer-other-window' and +;; `view-buffer-other-frame' to keys. ;;; Code: @@ -65,7 +65,7 @@ only rings the bell and gives a message on how to leave." (defcustom view-try-extend-at-buffer-end nil "Non-nil means try to load more of file when reaching end of buffer. This variable is mainly intended to be temporarily set to non-nil by -the F command in view-mode, but you can set it to t if you want the action +the F command in `view-mode', but you can set it to t if you want the action for all scroll commands in view mode." :type 'boolean :group 'view) @@ -220,7 +220,7 @@ This is local in each buffer, once it is used.") ;; types C-x C-q again to return to view mode. ;;;###autoload (defun kill-buffer-if-not-modified (buf) - "Like `kill-buffer', but does nothing if the buffer is modified." + "Like `kill-buffer', but does nothing if buffer BUF is modified." (let ((buf (get-buffer buf))) (and buf (not (buffer-modified-p buf)) (kill-buffer buf)))) @@ -305,7 +305,7 @@ file: Users may suspend viewing in order to modify the buffer. Exiting View mode will then discard the user's edits. Setting EXIT-ACTION to `kill-buffer-if-not-modified' avoids this. -This function does not enable View mode if the buffer's major-mode +This function does not enable View mode if the buffer's major mode has a `special' mode-class, because such modes usually have their own View-like bindings." (interactive "bView buffer: ") @@ -331,7 +331,7 @@ Optional argument EXIT-ACTION is either nil or a function with buffer as argument. This function is called when finished viewing buffer. Use this argument instead of explicitly setting `view-exit-action'. -This function does not enable View mode if the buffer's major-mode +This function does not enable View mode if the buffer's major mode has a `special' mode-class, because such modes usually have their own View-like bindings." (interactive "bIn other window view buffer:\nP") @@ -358,7 +358,7 @@ Optional argument EXIT-ACTION is either nil or a function with buffer as argument. This function is called when finished viewing buffer. Use this argument instead of explicitly setting `view-exit-action'. -This function does not enable View mode if the buffer's major-mode +This function does not enable View mode if the buffer's major mode has a `special' mode-class, because such modes usually have their own View-like bindings." (interactive "bView buffer in other frame: \nP") @@ -662,8 +662,8 @@ previous state and go to previous buffer or window." (recenter '(1))) (defun view-page-size-default (lines) - ;; If LINES is nil, 0, or larger than `view-window-size', return nil. - ;; Otherwise, return LINES. + "If LINES is nil, 0, or larger than `view-window-size', return nil. +Otherwise, return LINES." (and lines (not (zerop (setq lines (prefix-numeric-value lines)))) (<= (abs lines) @@ -671,7 +671,7 @@ previous state and go to previous buffer or window." (abs lines))) (defun view-set-half-page-size-default (lines) - ;; Get and maybe set half page size. + "Get and maybe set half page size." (if (not lines) (or view-half-page-size (/ (view-window-size) 2)) (setq view-half-page-size @@ -749,7 +749,7 @@ invocations return to earlier marks." (if (view-really-at-end) (view-end-message))))) (defun view-really-at-end () - ;; Return true if buffer end visible. Maybe revert buffer and test. + "Return non-nil if buffer end visible. Maybe revert buffer and test." (and (or (null scroll-error-top-bottom) (eobp)) (pos-visible-in-window-p (point-max)) (let ((buf (current-buffer)) @@ -772,7 +772,7 @@ invocations return to earlier marks." (pos-visible-in-window-p (point-max))))))) (defun view-end-message () - ;; Tell that we are at end of buffer. + "Tell that we are at end of buffer." (goto-char (point-max)) (if (window-parameter nil 'quit-restore) (message "End of buffer. Type %s to quit viewing." @@ -979,7 +979,7 @@ for highlighting the match that is found." ;; https://lists.gnu.org/r/bug-gnu-emacs/2007-09/msg00073.html (defun view-search-no-match-lines (times regexp) "Search for the TIMESth occurrence of a line with no match for REGEXP. -If such a line is found, return non-nil and set the match-data to that line. +If such a line is found, return non-nil and set the match data to that line. If TIMES is negative, search backwards." (let ((step (if (>= times 0) 1 (setq times (- times)) commit 3a964dc5c124d1b5402e7e5cf7a6b6f28310e67b Author: Stefan Kangas Date: Wed Mar 24 05:32:47 2021 +0100 * lisp/master.el: Use lexical-binding. diff --git a/lisp/master.el b/lisp/master.el index 796f2189d6..3dcee50c5e 100644 --- a/lisp/master.el +++ b/lisp/master.el @@ -1,4 +1,4 @@ -;;; master.el --- make a buffer the master over another buffer +;;; master.el --- make a buffer the master over another buffer -*- lexical-binding: t -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. @@ -23,7 +23,7 @@ ;;; Commentary: -;; master-mode is a minor mode which enables you to scroll another +;; `master-mode' is a minor mode which enables you to scroll another ;; buffer (the slave) without leaving your current buffer (the master). ;; It can be used by sql.el, for example: The SQL buffer is the master @@ -47,17 +47,8 @@ ;; ;; Rob Riepel -;;; History: -;; - ;;; Code: -;; Unused. -;;; (defgroup master nil -;;; "Support for master/slave relationships between buffers." -;;; :version "22.1" -;;; :group 'convenience) - ;; Variables that don't need initialization. (defvar master-of nil @@ -93,7 +84,7 @@ yourself the value of `master-of' by calling `master-show-slave'." ;; Initialize Master mode by setting a slave buffer. (defun master-set-slave (buffer) - "Makes BUFFER the slave of the current buffer. + "Make BUFFER the slave of the current buffer. Use \\[master-mode] to toggle control of the slave buffer." (interactive "bSlave: ") (setq-local master-of buffer) commit ac4dd5f244032148595fb787ff926882390b36b9 Author: Stefan Kangas Date: Wed Mar 24 03:47:27 2021 +0100 Use lexical-binding in ruler-mode.el * lisp/ruler-mode.el: Use lexical-binding. Remove redundant :group args. diff --git a/lisp/ruler-mode.el b/lisp/ruler-mode.el index c9d39397e0..fc9196caf9 100644 --- a/lisp/ruler-mode.el +++ b/lisp/ruler-mode.el @@ -1,4 +1,4 @@ -;;; ruler-mode.el --- display a ruler in the header line +;;; ruler-mode.el --- display a ruler in the header line -*- lexical-binding: t -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. @@ -122,7 +122,6 @@ Also allowing to visually change `tab-stop-list' setting using and on the ruler to respectively add or remove a tab stop. \\[ruler-mode-toggle-show-tab-stops] or on the ruler toggles showing/editing of tab stops." - :group 'ruler-mode :type 'boolean) ;; IMPORTANT: This function must be defined before the following @@ -140,7 +139,6 @@ or remove a tab stop. \\[ruler-mode-toggle-show-tab-stops] or ?\¶ ?\|) "Character used at the `fill-column' location." - :group 'ruler-mode :type '(choice (character :tag "Character") (integer :tag "Integer char value" @@ -148,7 +146,6 @@ or remove a tab stop. \\[ruler-mode-toggle-show-tab-stops] or (defcustom ruler-mode-comment-column-char ?\# "Character used at the `comment-column' location." - :group 'ruler-mode :type '(choice (character :tag "Character") (integer :tag "Integer char value" @@ -156,7 +153,6 @@ or remove a tab stop. \\[ruler-mode-toggle-show-tab-stops] or (defcustom ruler-mode-goal-column-char ?G "Character used at the `goal-column' location." - :group 'ruler-mode :type '(choice (character :tag "Character") (integer :tag "Integer char value" @@ -166,7 +162,6 @@ or remove a tab stop. \\[ruler-mode-toggle-show-tab-stops] or ?\¦ ?\@) "Character used at the `current-column' location." - :group 'ruler-mode :type '(choice (character :tag "Character") (integer :tag "Integer char value" @@ -174,7 +169,6 @@ or remove a tab stop. \\[ruler-mode-toggle-show-tab-stops] or (defcustom ruler-mode-tab-stop-char ?\T "Character used at `tab-stop-list' locations." - :group 'ruler-mode :type '(choice (character :tag "Character") (integer :tag "Integer char value" @@ -182,7 +176,6 @@ or remove a tab stop. \\[ruler-mode-toggle-show-tab-stops] or (defcustom ruler-mode-basic-graduation-char ?\. "Character used for basic graduations." - :group 'ruler-mode :type '(choice (character :tag "Character") (integer :tag "Integer char value" @@ -190,7 +183,6 @@ or remove a tab stop. \\[ruler-mode-toggle-show-tab-stops] or (defcustom ruler-mode-inter-graduation-char ?\! "Character used for intermediate graduations." - :group 'ruler-mode :type '(choice (character :tag "Character") (integer :tag "Integer char value" @@ -198,7 +190,6 @@ or remove a tab stop. \\[ruler-mode-toggle-show-tab-stops] or (defcustom ruler-mode-set-goal-column-ding-flag t "Non-nil means do `ding' when `goal-column' is set." - :group 'ruler-mode :type 'boolean) (defface ruler-mode-default @@ -215,8 +206,7 @@ or remove a tab stop. \\[ruler-mode-toggle-show-tab-stops] or :line-width 1 :style released-button) ))) - "Default face used by the ruler." - :group 'ruler-mode) + "Default face used by the ruler.") (defface ruler-mode-pad '((((type tty)) @@ -227,64 +217,56 @@ or remove a tab stop. \\[ruler-mode-toggle-show-tab-stops] or (:inherit ruler-mode-default :background "grey64" ))) - "Face used to pad inactive ruler areas." - :group 'ruler-mode) + "Face used to pad inactive ruler areas.") (defface ruler-mode-margins '((t (:inherit ruler-mode-default :foreground "white" ))) - "Face used to highlight margin areas." - :group 'ruler-mode) + "Face used to highlight margin areas.") (defface ruler-mode-fringes '((t (:inherit ruler-mode-default :foreground "green" ))) - "Face used to highlight fringes areas." - :group 'ruler-mode) + "Face used to highlight fringes areas.") (defface ruler-mode-column-number '((t (:inherit ruler-mode-default :foreground "black" ))) - "Face used to highlight number graduations." - :group 'ruler-mode) + "Face used to highlight number graduations.") (defface ruler-mode-fill-column '((t (:inherit ruler-mode-default :foreground "red" ))) - "Face used to highlight the fill column character." - :group 'ruler-mode) + "Face used to highlight the fill column character.") (defface ruler-mode-comment-column '((t (:inherit ruler-mode-default :foreground "red" ))) - "Face used to highlight the comment column character." - :group 'ruler-mode) + "Face used to highlight the comment column character.") (defface ruler-mode-goal-column '((t (:inherit ruler-mode-default :foreground "red" ))) - "Face used to highlight the goal column character." - :group 'ruler-mode) + "Face used to highlight the goal column character.") (defface ruler-mode-tab-stop '((t (:inherit ruler-mode-default :foreground "steelblue" ))) - "Face used to highlight tab stop characters." - :group 'ruler-mode) + "Face used to highlight tab stop characters.") (defface ruler-mode-current-column '((t @@ -292,8 +274,7 @@ or remove a tab stop. \\[ruler-mode-toggle-show-tab-stops] or :weight bold :foreground "yellow" ))) - "Face used to highlight the `current-column' character." - :group 'ruler-mode) + "Face used to highlight the `current-column' character.") (defsubst ruler-mode-full-window-width () @@ -547,15 +528,15 @@ START-EVENT is the mouse click event." (define-key km [header-line (control down-mouse-2)] #'ruler-mode-toggle-show-tab-stops) (define-key km [header-line (shift mouse-1)] - 'ignore) + #'ignore) (define-key km [header-line (shift mouse-3)] - 'ignore) + #'ignore) (define-key km [header-line (control mouse-1)] - 'ignore) + #'ignore) (define-key km [header-line (control mouse-3)] - 'ignore) + #'ignore) (define-key km [header-line (control mouse-2)] - 'ignore) + #'ignore) km) "Keymap for ruler minor mode.") commit 952550258dcf06bc03662974aa6b6db9d792aedb Author: Stefan Monnier Date: Tue Mar 23 22:38:41 2021 -0400 * lisp/progmodes/ebnf-*.el: Use lexical-binding * lisp/progmodes/ebnf-abn.el: * lisp/progmodes/ebnf-bnf.el: * lisp/progmodes/ebnf-dtd.el: * lisp/progmodes/ebnf-ebx.el: * lisp/progmodes/ebnf-iso.el: * lisp/progmodes/ebnf-otz.el: * lisp/progmodes/ebnf-yac.el: Enable lexical-binding. * lisp/progmodes/ebnf2ps.el (ebnf-apply-style1) (ebnf-insert-ebnf-prologue): Use lexical-binding. diff --git a/lisp/progmodes/ebnf-abn.el b/lisp/progmodes/ebnf-abn.el index 9e570b6c03..99b339e223 100644 --- a/lisp/progmodes/ebnf-abn.el +++ b/lisp/progmodes/ebnf-abn.el @@ -1,4 +1,4 @@ -;;; ebnf-abn.el --- parser for ABNF (Augmented BNF) +;;; ebnf-abn.el --- parser for ABNF (Augmented BNF) -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/progmodes/ebnf-bnf.el b/lisp/progmodes/ebnf-bnf.el index 93ebfe8654..e6717cbdf0 100644 --- a/lisp/progmodes/ebnf-bnf.el +++ b/lisp/progmodes/ebnf-bnf.el @@ -1,4 +1,4 @@ -;;; ebnf-bnf.el --- parser for EBNF +;;; ebnf-bnf.el --- parser for EBNF -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. diff --git a/lisp/progmodes/ebnf-dtd.el b/lisp/progmodes/ebnf-dtd.el index 66e5dd095e..93bae5a33c 100644 --- a/lisp/progmodes/ebnf-dtd.el +++ b/lisp/progmodes/ebnf-dtd.el @@ -1,4 +1,4 @@ -;;; ebnf-dtd.el --- parser for DTD (Data Type Description for XML) +;;; ebnf-dtd.el --- parser for DTD (Data Type Description for XML) -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/progmodes/ebnf-ebx.el b/lisp/progmodes/ebnf-ebx.el index 389049e39a..5d8541931e 100644 --- a/lisp/progmodes/ebnf-ebx.el +++ b/lisp/progmodes/ebnf-ebx.el @@ -1,4 +1,4 @@ -;;; ebnf-ebx.el --- parser for EBNF used to specify XML (EBNFX) +;;; ebnf-ebx.el --- parser for EBNF used to specify XML (EBNFX) -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/progmodes/ebnf-iso.el b/lisp/progmodes/ebnf-iso.el index d25ff3ecb4..12cc72ce1c 100644 --- a/lisp/progmodes/ebnf-iso.el +++ b/lisp/progmodes/ebnf-iso.el @@ -1,4 +1,4 @@ -;;; ebnf-iso.el --- parser for ISO EBNF +;;; ebnf-iso.el --- parser for ISO EBNF -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. diff --git a/lisp/progmodes/ebnf-otz.el b/lisp/progmodes/ebnf-otz.el index b724d75a7e..84e59cc0a5 100644 --- a/lisp/progmodes/ebnf-otz.el +++ b/lisp/progmodes/ebnf-otz.el @@ -1,4 +1,4 @@ -;;; ebnf-otz.el --- syntactic chart OpTimiZer +;;; ebnf-otz.el --- syntactic chart OpTimiZer -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. diff --git a/lisp/progmodes/ebnf-yac.el b/lisp/progmodes/ebnf-yac.el index 2765d03acb..5abf1debb1 100644 --- a/lisp/progmodes/ebnf-yac.el +++ b/lisp/progmodes/ebnf-yac.el @@ -1,4 +1,4 @@ -;;; ebnf-yac.el --- parser for Yacc/Bison +;;; ebnf-yac.el --- parser for Yacc/Bison -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. diff --git a/lisp/progmodes/ebnf2ps.el b/lisp/progmodes/ebnf2ps.el index b376423c18..c95b351d0c 100644 --- a/lisp/progmodes/ebnf2ps.el +++ b/lisp/progmodes/ebnf2ps.el @@ -2920,7 +2920,7 @@ See `ebnf-style-database' documentation." value (and (car value) (ebnf-apply-style1 (car value))) (while (setq value (cdr value)) - (set (caar value) (eval (cdar value))))))) + (set (caar value) (eval (cdar value) t)))))) (defun ebnf-check-style-values (values) @@ -5487,7 +5487,7 @@ killed after process termination." (ebnf-shape-value ebnf-chart-shape ebnf-terminal-shape-alist)) (format "/UserArrow{%s}def\n" - (let ((arrow (eval ebnf-user-arrow))) + (let ((arrow (eval ebnf-user-arrow t))) (if (stringp arrow) arrow ""))) @@ -6290,7 +6290,7 @@ killed after process termination." (defun ebnf-log-header (format-str &rest args) (when ebnf-log (apply - 'ebnf-log + #'ebnf-log (concat "\n\n===============================================================\n\n" format-str) commit 667e002e91a26c20089c5843254a39b771b64ab7 Author: Stefan Monnier Date: Tue Mar 23 01:00:56 2021 -0400 * lisp/mh-e: Enable lexical-binding in all the files * lisp/mh-e/mh-alias.el: Use lexical-binding. (mh-alias-insert-file): Completion tables can be mere lists of strings. * lisp/mh-e/mh-mime.el: Use lexical-binding. (mh-mm-inline-message): Remove always-nil var `visible-headers`. * lisp/mh-e/mh-search.el: Use lexical-binding. (mh-search-folder): Remove unused var `pick-folder`. * lisp/mh-e/mh-show.el: Use lexical-binding. (mh-display-msg): Remove always-nil var `visible-headers`. * lisp/mh-e/mh-utils.el: Use lexical-binding. (completion-root-regexp): Always declare var. * lisp/mh-e/mh-buffers.el: Use lexical-binding. * lisp/mh-e/mh-comp.el: Use lexical-binding. * lisp/mh-e/mh-folder.el: Use lexical-binding. * lisp/mh-e/mh-funcs.el: Use lexical-binding. * lisp/mh-e/mh-gnus.el: Use lexical-binding. * lisp/mh-e/mh-identity.el: Use lexical-binding. * lisp/mh-e/mh-inc.el: Use lexical-binding. * lisp/mh-e/mh-junk.el: Use lexical-binding. * lisp/mh-e/mh-letter.el: Use lexical-binding. * lisp/mh-e/mh-limit.el: Use lexical-binding. * lisp/mh-e/mh-print.el: Use lexical-binding. * lisp/mh-e/mh-scan.el: Use lexical-binding. * lisp/mh-e/mh-seq.el: Use lexical-binding. * lisp/mh-e/mh-speed.el: Use lexical-binding. * lisp/mh-e/mh-thread.el: Use lexical-binding. * lisp/mh-e/mh-tool-bar.el: Use lexical-binding. * lisp/mh-e/mh-xface.el: Use lexical-binding. diff --git a/lisp/mh-e/mh-alias.el b/lisp/mh-e/mh-alias.el index 012725cab6..67c019aa17 100644 --- a/lisp/mh-e/mh-alias.el +++ b/lisp/mh-e/mh-alias.el @@ -1,4 +1,4 @@ -;;; mh-alias.el --- MH-E mail alias completion and expansion +;;; mh-alias.el --- MH-E mail alias completion and expansion -*- lexical-binding: t; -*- ;; Copyright (C) 1994-1997, 2001-2021 Free Software Foundation, Inc. @@ -42,8 +42,8 @@ "Time aliases were last loaded.") (defvar mh-alias-read-address-map (let ((map (copy-keymap minibuffer-local-completion-map))) - (define-key map "," 'mh-alias-minibuffer-confirm-address) - (define-key map " " 'self-insert-command) + (define-key map "," #'mh-alias-minibuffer-confirm-address) + (define-key map " " #'self-insert-command) map)) (defcustom mh-alias-system-aliases @@ -270,9 +270,9 @@ Blind aliases or users from /etc/passwd are not expanded." (t (split-string (completing-read prompt mh-alias-alist nil nil) ","))))) (if (not mh-alias-expand-aliases-flag) - (mapconcat 'identity the-answer ", ") + (mapconcat #'identity the-answer ", ") ;; Loop over all elements, checking if in passwd alias or blind first - (mapconcat 'mh-alias-expand the-answer ",\n "))))) + (mapconcat #'mh-alias-expand the-answer ",\n "))))) ;;;###mh-autoload (defun mh-alias-minibuffer-confirm-address () @@ -427,10 +427,10 @@ contains it." (if (or (not alias) (string-equal alias (mh-alias-ali alias))) ;alias doesn't exist (completing-read "Alias file: " - (mapcar 'list mh-alias-insert-file) nil t) + (mapcar #'list mh-alias-insert-file) nil t) (or (mh-alias-which-file-has-alias alias mh-alias-insert-file) (completing-read "Alias file: " - (mapcar 'list mh-alias-insert-file) nil t))))) + (mapcar #'list mh-alias-insert-file) nil t))))) ((and mh-alias-insert-file (stringp mh-alias-insert-file)) mh-alias-insert-file) (t @@ -449,11 +449,10 @@ set `mh-alias-insert-file' or the \"Aliasfile:\" profile component")) (car autolist)) ((or (not alias) (string-equal alias (mh-alias-ali alias))) ;alias doesn't exist - (completing-read "Alias file: " (mapcar 'list autolist) nil t)) + (completing-read "Alias file: " autolist nil t)) (t (or (mh-alias-which-file-has-alias alias autolist) - (completing-read "Alias file: " - (mapcar 'list autolist) nil t)))))))) + (completing-read "Alias file: " autolist nil t)))))))) ;;;###mh-autoload (defun mh-alias-address-to-alias (address) diff --git a/lisp/mh-e/mh-buffers.el b/lisp/mh-e/mh-buffers.el index 55f74b6585..a32f61c82e 100644 --- a/lisp/mh-e/mh-buffers.el +++ b/lisp/mh-e/mh-buffers.el @@ -1,4 +1,4 @@ -;;; mh-buffers.el --- MH-E buffer constants and utilities +;;; mh-buffers.el --- MH-E buffer constants and utilities -*- lexical-binding: t; -*- ;; Copyright (C) 1993, 1995, 1997, 2000-2021 Free Software Foundation, ;; Inc. diff --git a/lisp/mh-e/mh-comp.el b/lisp/mh-e/mh-comp.el index 0dedb7e0ad..c1cd6c1a9e 100644 --- a/lisp/mh-e/mh-comp.el +++ b/lisp/mh-e/mh-comp.el @@ -1,4 +1,4 @@ -;;; mh-comp.el --- MH-E functions for composing and sending messages +;;; mh-comp.el --- MH-E functions for composing and sending messages -*- lexical-binding: t; -*- ;; Copyright (C) 1993, 1995, 1997, 2000-2021 Free Software Foundation, ;; Inc. @@ -719,12 +719,14 @@ message and scan line." (mh-insert-fields field value))))) (mh-components-to-list components-file)) (delete-file components-file)) - (mh-insert-fields "Resent-To:" (mapconcat 'identity (list to comp-to) ", ") - "Resent-Cc:" (mapconcat 'identity (list cc comp-cc) ", ") - "Resent-Fcc:" (mapconcat 'identity (list fcc - comp-fcc) ", ") - "Resent-Bcc:" (mapconcat 'identity (list bcc - comp-bcc) ", ") + (mh-insert-fields "Resent-To:" (mapconcat #'identity (list to comp-to) + ", ") + "Resent-Cc:" (mapconcat #'identity (list cc comp-cc) + ", ") + "Resent-Fcc:" (mapconcat #'identity (list fcc comp-fcc) + ", ") + "Resent-Bcc:" (mapconcat #'identity (list bcc comp-bcc) + ", ") "Resent-From:" from) (save-buffer) (message "Redistributing...") @@ -1096,7 +1098,7 @@ letter." (setq mode-line-buffer-identification (list " {%b}")) (mh-logo-display) (mh-make-local-hook 'kill-buffer-hook) - (add-hook 'kill-buffer-hook 'mh-tidy-draft-buffer nil t) + (add-hook 'kill-buffer-hook #'mh-tidy-draft-buffer nil t) (run-hook-with-args 'mh-compose-letter-function to subject cc)) (defun mh-insert-x-mailer () @@ -1165,7 +1167,7 @@ This should be the last function called when composing the draft." MSG can be a message number, a list of message numbers, or a sequence. The hook `mh-annotate-msg-hook' is run after annotating; see its documentation for variables it can use." - (apply 'mh-exec-cmd "anno" folder + (apply #'mh-exec-cmd "anno" folder (if (listp msg) (append msg args) (cons msg args))) (save-excursion (cond ((get-buffer folder) ; Buffer may be deleted diff --git a/lisp/mh-e/mh-compat.el b/lisp/mh-e/mh-compat.el index 6d657afa3e..0363c5aada 100644 --- a/lisp/mh-e/mh-compat.el +++ b/lisp/mh-e/mh-compat.el @@ -42,7 +42,7 @@ (eval-when-compile (require 'mh-acros)) (mh-do-in-gnu-emacs - (defalias 'mh-require 'require)) + (defalias 'mh-require #'require)) (mh-do-in-xemacs (defun mh-require (feature &optional filename noerror) diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el index eaf8eb5565..11296a53b9 100644 --- a/lisp/mh-e/mh-e.el +++ b/lisp/mh-e/mh-e.el @@ -522,7 +522,7 @@ parsed by MH-E." (let* ((initial-size (mh-truncate-log-buffer)) (start (point)) (args (mh-list-to-string args))) - (apply 'call-process (expand-file-name command mh-progs) nil t nil args) + (apply #'call-process (expand-file-name command mh-progs) nil t nil args) (when (> (buffer-size) initial-size) (save-excursion (goto-char start) @@ -560,7 +560,7 @@ ARGS are passed to COMMAND as command line arguments." (with-current-buffer (get-buffer-create mh-log-buffer) (mh-truncate-log-buffer)) (let* ((process-connection-type nil) - (process (apply 'start-process + (process (apply #'start-process command nil (expand-file-name command mh-progs) (mh-list-to-string args)))) @@ -602,7 +602,7 @@ RAISE-ERROR is non-nil, in which case an error is signaled if (set-buffer (get-buffer-create mh-temp-buffer)) (erase-buffer) (let ((value - (apply 'call-process + (apply #'call-process (expand-file-name command mh-progs) nil t nil args))) (goto-char (point-min)) @@ -616,7 +616,7 @@ Put the output into buffer after point. Set mark after inserted text. Output is expected to be shown to user, not parsed by MH-E." (push-mark (point) t) - (apply 'call-process + (apply #'call-process (expand-file-name command mh-progs) nil t display (mh-list-to-string args)) @@ -650,7 +650,7 @@ preserves whether the mark is active or not." "Execute MH library command COMMAND with ARGS. Put the output into buffer after point. Set mark after inserted text." - (apply 'mh-exec-cmd-output (expand-file-name command mh-lib-progs) nil args)) + (apply #'mh-exec-cmd-output (expand-file-name command mh-lib-progs) nil args)) (defun mh-handle-process-error (command status) "Raise error if COMMAND returned non-zero STATUS, otherwise return STATUS." @@ -974,7 +974,7 @@ necessary and can actually cause problems." :set (lambda (symbol value) (set-default symbol value) ;Done in mh-variant-set-variant! (mh-variant-set value)) - :initialize 'custom-initialize-default + :initialize #'custom-initialize-default :group 'mh-e :package-version '(MH-E . "8.0")) @@ -1548,7 +1548,7 @@ as the result is undefined." '(radio) (mapcar (lambda (arg) `(const ,arg)) - (mapcar 'car mh-identity-list)))) + (mapcar #'car mh-identity-list)))) (cons :tag "Fcc Field" (const "fcc") (string :tag "Value")) @@ -1575,7 +1575,7 @@ See `mh-identity-list'." '(radio) (cons '(const :tag "None" nil) (mapcar (lambda (arg) `(const ,arg)) - (mapcar 'car mh-identity-list)))) + (mapcar #'car mh-identity-list)))) :group 'mh-identity :package-version '(MH-E . "7.1")) @@ -1744,7 +1744,7 @@ bogofilter, then you can set this option to \"Bogofilter\"." (const :tag "SpamAssassin" spamassassin) (const :tag "Bogofilter" bogofilter) (const :tag "SpamProbe" spamprobe)) - :set 'mh-junk-choose + :set #'mh-junk-choose :group 'mh-junk :package-version '(MH-E . "7.3")) @@ -2005,7 +2005,7 @@ call `mh-set-cmd-note' with the width specified by your format file you would use \"(mh-set-cmd-note 4)\"." :type 'boolean :group 'mh-scan-line-formats - :set 'mh-adaptive-cmd-note-flag-check + :set #'mh-adaptive-cmd-note-flag-check :package-version '(MH-E . "7.0")) (defun mh-scan-format-file-check (symbol value) @@ -2044,7 +2044,7 @@ Emacs start with 0)." (const :tag "Use Default scan Format" nil) (file :tag "Specify a scan Format File")) :group 'mh-scan-line-formats - :set 'mh-scan-format-file-check + :set #'mh-scan-format-file-check :package-version '(MH-E . "6.0")) (defun mh-adaptive-cmd-note-flag-check (symbol value) diff --git a/lisp/mh-e/mh-folder.el b/lisp/mh-e/mh-folder.el index 555d13d723..2e288064f1 100644 --- a/lisp/mh-e/mh-folder.el +++ b/lisp/mh-e/mh-folder.el @@ -1,4 +1,4 @@ -;;; mh-folder.el --- MH-Folder mode +;;; mh-folder.el --- MH-Folder mode -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2003, 2005-2021 Free Software Foundation, Inc. @@ -209,10 +209,10 @@ annotation.") ;; Use defalias to make sure the documented primary key bindings ;; appear in menu lists. -(defalias 'mh-alt-show 'mh-show) -(defalias 'mh-alt-refile-msg 'mh-refile-msg) -(defalias 'mh-alt-send 'mh-send) -(defalias 'mh-alt-visit-folder 'mh-visit-folder) +(defalias 'mh-alt-show #'mh-show) +(defalias 'mh-alt-refile-msg #'mh-refile-msg) +(defalias 'mh-alt-send #'mh-send) +(defalias 'mh-alt-visit-folder #'mh-visit-folder) ;; Save the "b" binding for a future `back'. Maybe? (gnus-define-keys mh-folder-mode-map @@ -650,11 +650,11 @@ perform the operation on all messages in that region. (auto-save-mode -1) (setq buffer-offer-save t) (mh-make-local-hook (mh-write-file-functions)) - (add-hook (mh-write-file-functions) 'mh-execute-commands nil t) + (add-hook (mh-write-file-functions) #'mh-execute-commands nil t) (make-local-variable 'revert-buffer-function) (make-local-variable 'hl-line-mode) ; avoid pollution (mh-funcall-if-exists hl-line-mode 1) - (setq revert-buffer-function 'mh-undo-folder) + (setq revert-buffer-function #'mh-undo-folder) (add-to-list 'minor-mode-alist '(mh-showing-mode " Show")) (mh-do-in-xemacs (easy-menu-add mh-folder-sequence-menu) @@ -1117,7 +1117,7 @@ called interactively." (message "Destination folder: %s" (cdr mh-last-destination))) (t (mh-iterate-on-range msg range - (apply 'mh-write-msg-to-file msg (cdr mh-last-destination))) + (apply #'mh-write-msg-to-file msg (cdr mh-last-destination))) (mh-next-msg interactive-flag)))) ;;;###mh-autoload @@ -1606,7 +1606,7 @@ after the commands are processed." ;; Now delete messages (cond (mh-delete-list (setq redraw-needed-flag t) - (apply 'mh-exec-cmd "rmm" folder + (apply #'mh-exec-cmd "rmm" folder (mh-coalesce-msg-list mh-delete-list)) (mh-delete-scan-msgs mh-delete-list) (setq mh-delete-list nil))) @@ -1620,8 +1620,8 @@ after the commands are processed." ;; (mh-refile-a-msg nil (intern dest)) ;; (mh-delete-a-msg nil))) (if (null dest) - (apply 'mh-exec-cmd "rmm" folder msg-list) - (apply 'mh-exec-cmd "refile" "-src" folder dest msg-list) + (apply #'mh-exec-cmd "rmm" folder msg-list) + (apply #'mh-exec-cmd "refile" "-src" folder dest msg-list) (push dest folders-changed)) (setq redraw-needed-flag t) (mh-delete-scan-msgs mh-blacklist) @@ -1703,7 +1703,7 @@ after the commands are processed." (mh-recenter nil))) ;;;###mh-autoload -(defun mh-make-folder-mode-line (&optional ignored) +(defun mh-make-folder-mode-line (&optional _ignored) "Set the fields of the mode line for a folder buffer. The optional argument is now obsolete and IGNORED. It used to be used to pass in what is now stored in the buffer-local variable diff --git a/lisp/mh-e/mh-funcs.el b/lisp/mh-e/mh-funcs.el index 309bcb4b49..38ba43188d 100644 --- a/lisp/mh-e/mh-funcs.el +++ b/lisp/mh-e/mh-funcs.el @@ -1,4 +1,4 @@ -;;; mh-funcs.el --- MH-E functions not everyone will use right away +;;; mh-funcs.el --- MH-E functions not everyone will use right away -*- lexical-binding: t; -*- ;; Copyright (C) 1993, 1995, 2001-2021 Free Software Foundation, Inc. @@ -348,7 +348,7 @@ See `mh-store-msg' for a description of DIRECTORY." (error "Error occurred during execution of %s" command))))) ;;;###mh-autoload -(defun mh-undo-folder (&rest ignored) +(defun mh-undo-folder (&rest _ignored) "Undo all refiles and deletes in the current folder. Arguments are IGNORED (for `revert-buffer')." (interactive) diff --git a/lisp/mh-e/mh-gnus.el b/lisp/mh-e/mh-gnus.el index 6a9851662a..ab65637157 100644 --- a/lisp/mh-e/mh-gnus.el +++ b/lisp/mh-e/mh-gnus.el @@ -1,4 +1,4 @@ -;;; mh-gnus.el --- make MH-E compatible with various versions of Gnus +;;; mh-gnus.el --- make MH-E compatible with various versions of Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2004, 2006-2021 Free Software Foundation, Inc. diff --git a/lisp/mh-e/mh-identity.el b/lisp/mh-e/mh-identity.el index 1844399217..aeab049756 100644 --- a/lisp/mh-e/mh-identity.el +++ b/lisp/mh-e/mh-identity.el @@ -1,4 +1,4 @@ -;;; mh-identity.el --- multiple identify support for MH-E +;;; mh-identity.el --- multiple identify support for MH-E -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. @@ -50,7 +50,7 @@ This is normally set as part of an Identity in (defvar mh-identity-menu nil "The Identity menu.") -(defalias 'mh-identity-make-menu-no-autoload 'mh-identity-make-menu) +(defalias 'mh-identity-make-menu-no-autoload #'mh-identity-make-menu) ;;;###mh-autoload (defun mh-identity-make-menu () @@ -74,7 +74,7 @@ See `mh-identity-add-menu'." (mapcar (lambda (arg) `[,arg (mh-insert-identity ,arg) :style radio :selected (equal mh-identity-local ,arg)]) - (mapcar 'car mh-identity-list)) + (mapcar #'car mh-identity-list)) '(["None" (mh-insert-identity "None") :style radio :selected (not mh-identity-local)] @@ -142,7 +142,7 @@ See `mh-identity-list'." (completing-read "Identity: " (cons '("None") - (mapcar 'list (mapcar 'car mh-identity-list))) + (mapcar #'list (mapcar #'car mh-identity-list))) nil t default nil default)) (if (eq identity "None") nil @@ -171,8 +171,8 @@ See `mh-identity-list'." "Identity: " (if mh-identity-local (cons '("None") - (mapcar 'list (mapcar 'car mh-identity-list))) - (mapcar 'list (mapcar 'car mh-identity-list))) + (mapcar #'list (mapcar #'car mh-identity-list))) + (mapcar #'list (mapcar #'car mh-identity-list))) nil t) nil)) diff --git a/lisp/mh-e/mh-inc.el b/lisp/mh-e/mh-inc.el index 32f731799b..90d5489526 100644 --- a/lisp/mh-e/mh-inc.el +++ b/lisp/mh-e/mh-inc.el @@ -1,4 +1,4 @@ -;;; mh-inc.el --- MH-E "inc" and separate mail spool handling +;;; mh-inc.el --- MH-E "inc" and separate mail spool handling -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2004, 2006-2021 Free Software Foundation, Inc. @@ -58,7 +58,7 @@ (mh-inc-spool-generator folder spool) (mh-inc-spool-def-key key folder)))))) -(defalias 'mh-inc-spool-make-no-autoload 'mh-inc-spool-make) +(defalias 'mh-inc-spool-make-no-autoload #'mh-inc-spool-make) (defun mh-inc-spool-generator (folder spool) "Create a command to inc into FOLDER from SPOOL file." diff --git a/lisp/mh-e/mh-junk.el b/lisp/mh-e/mh-junk.el index b49c632249..5a407947a0 100644 --- a/lisp/mh-e/mh-junk.el +++ b/lisp/mh-e/mh-junk.el @@ -1,4 +1,4 @@ -;;; mh-junk.el --- MH-E interface to anti-spam measures +;;; mh-junk.el --- MH-E interface to anti-spam measures -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2021 Free Software Foundation, Inc. diff --git a/lisp/mh-e/mh-letter.el b/lisp/mh-e/mh-letter.el index f5ad73d800..c44b78ad12 100644 --- a/lisp/mh-e/mh-letter.el +++ b/lisp/mh-e/mh-letter.el @@ -1,4 +1,4 @@ -;;; mh-letter.el --- MH-Letter mode +;;; mh-letter.el --- MH-Letter mode -*- lexical-binding: t; -*- ;; Copyright (C) 1993, 1995, 1997, 2000-2021 Free Software Foundation, ;; Inc. @@ -334,15 +334,15 @@ order). ;; Maybe we want to use the existing Mail menu from mail-mode in ;; 9.0; in the mean time, let's remove it since the redundancy will ;; only produce confusion. - (define-key mh-letter-mode-map [menu-bar mail] 'undefined) + (define-key mh-letter-mode-map [menu-bar mail] #'undefined) (mh-do-in-xemacs (easy-menu-remove mail-menubar-menu)) (setq fill-column mh-letter-fill-column) (add-hook 'completion-at-point-functions - 'mh-letter-completion-at-point nil 'local) + #'mh-letter-completion-at-point nil 'local) ;; If text-mode-hook turned on auto-fill, tune it for messages (when auto-fill-function (make-local-variable 'auto-fill-function) - (setq auto-fill-function 'mh-auto-fill-for-letter))) + (setq auto-fill-function #'mh-auto-fill-for-letter))) @@ -851,7 +851,7 @@ body." (forward-line))))) ;;;###mh-autoload -(defun mh-position-on-field (field &optional ignored) +(defun mh-position-on-field (field &optional _ignored) "Move to the end of the FIELD in the header. Move to end of entire header if FIELD not found. Returns non-nil if FIELD was found. diff --git a/lisp/mh-e/mh-limit.el b/lisp/mh-e/mh-limit.el index 036522f3dd..08f1b4093f 100644 --- a/lisp/mh-e/mh-limit.el +++ b/lisp/mh-e/mh-limit.el @@ -1,4 +1,4 @@ -;;; mh-limit.el --- MH-E display limits +;;; mh-limit.el --- MH-E display limits -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2003, 2006-2021 Free Software Foundation, Inc. @@ -237,7 +237,7 @@ Return number of messages put in the sequence: (setq list (cons (mh-get-msg-num t) list))) (if (assoc 'subject mh-seq-list) (mh-delete-seq 'subject)) ;; sort the result into a sequence - (let ((sorted-list (sort (copy-sequence list) 'mh-lessp))) + (let ((sorted-list (sort (copy-sequence list) #'mh-lessp))) (while sorted-list (mh-add-msgs-to-seq (car sorted-list) 'subject nil) (setq sorted-list (cdr sorted-list))) diff --git a/lisp/mh-e/mh-mime.el b/lisp/mh-e/mh-mime.el index 70df9e6b0f..bf63ac36cf 100644 --- a/lisp/mh-e/mh-mime.el +++ b/lisp/mh-e/mh-mime.el @@ -1,4 +1,4 @@ -;;; mh-mime.el --- MH-E MIME support +;;; mh-mime.el --- MH-E MIME support -*- lexical-binding: t; -*- ;; Copyright (C) 1993, 1995, 2001-2021 Free Software Foundation, Inc. @@ -190,9 +190,9 @@ Set from last use.") ;; XEmacs doesn't care. (set-keymap-parent map mh-show-mode-map)) (mh-do-in-gnu-emacs - (define-key map [mouse-2] 'mh-push-button)) + (define-key map [mouse-2] #'mh-push-button)) (mh-do-in-xemacs - (define-key map '(button2) 'mh-push-button)) + (define-key map '(button2) #'mh-push-button)) (dolist (c mh-mime-button-commands) (define-key map (cadr c) (car c))) map)) @@ -214,11 +214,11 @@ Set from last use.") (let ((map (make-sparse-keymap))) (unless (>= (string-to-number emacs-version) 21) (set-keymap-parent map mh-show-mode-map)) - (define-key map "\r" 'mh-press-button) + (define-key map "\r" #'mh-press-button) (mh-do-in-gnu-emacs - (define-key map [mouse-2] 'mh-push-button)) + (define-key map [mouse-2] #'mh-push-button)) (mh-do-in-xemacs - (define-key map '(button2) 'mh-push-button)) + (define-key map '(button2) #'mh-push-button)) map)) @@ -413,7 +413,7 @@ do the work." (cd directory) (setq mh-mime-save-parts-directory directory) (let ((initial-size (mh-truncate-log-buffer))) - (apply 'call-process + (apply #'call-process (expand-file-name command mh-progs) nil t nil (mh-list-to-string (list folder msg "-auto" (if (not (mh-variant-p 'nmh)) @@ -452,7 +452,7 @@ decoding the same message multiple times." (let ((b (point)) (clean-message-header mh-clean-message-header-flag) (invisible-headers mh-invisible-header-fields-compiled) - (visible-headers nil)) + ) ;; (visible-headers nil) (save-excursion (save-restriction (narrow-to-region b b) @@ -474,7 +474,7 @@ decoding the same message multiple times." (cond (clean-message-header (mh-clean-msg-header (point-min) invisible-headers - visible-headers) + nil) ;; visible-headers (goto-char (point-min))) (t (mh-start-of-uncleaned-message))) @@ -1225,7 +1225,7 @@ The option `mh-compose-insertion' controls what type of tags are inserted." t) t t))) (list description folder range))) - (let ((messages (mapconcat 'identity (mh-list-to-string range) " "))) + (let ((messages (mapconcat #'identity (mh-list-to-string range) " "))) (dolist (message (mh-translate-range folder messages)) (if (equal mh-compose-insertion 'mml) (mh-mml-forward-message description folder (format "%s" message)) diff --git a/lisp/mh-e/mh-print.el b/lisp/mh-e/mh-print.el index 513a1bc953..d084cf63e9 100644 --- a/lisp/mh-e/mh-print.el +++ b/lisp/mh-e/mh-print.el @@ -1,4 +1,4 @@ -;;; mh-print.el --- MH-E printing support +;;; mh-print.el --- MH-E printing support -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2021 Free Software Foundation, Inc. @@ -207,8 +207,9 @@ Consider using \\[mh-ps-print-msg] instead." ;; Print scan listing if we have more than one message. (if (> (length msgs) 1) (let* ((msgs-string - (mapconcat 'identity (mh-list-to-string - (mh-coalesce-msg-list msgs)) " ")) + (mapconcat #'identity (mh-list-to-string + (mh-coalesce-msg-list msgs)) + " ")) (lpr-command (format mh-lpr-command-format (cond ((listp range) diff --git a/lisp/mh-e/mh-scan.el b/lisp/mh-e/mh-scan.el index cec331389b..f00ab22958 100644 --- a/lisp/mh-e/mh-scan.el +++ b/lisp/mh-e/mh-scan.el @@ -1,4 +1,4 @@ -;;; mh-scan.el --- MH-E scan line constants and utilities +;;; mh-scan.el --- MH-E scan line constants and utilities -*- lexical-binding: t; -*- ;; Copyright (C) 1993, 1995, 1997, 2000-2021 Free Software Foundation, ;; Inc. @@ -497,7 +497,7 @@ with `mh-scan-msg-format-string'." (width 0)) (with-current-buffer tmp-buffer (erase-buffer) - (apply 'call-process + (apply #'call-process (expand-file-name mh-scan-prog mh-progs) nil '(t nil) nil (list folder "last" "-format" "%(msg)")) (goto-char (point-min)) diff --git a/lisp/mh-e/mh-search.el b/lisp/mh-e/mh-search.el index 05ba12d761..aece03ef0f 100644 --- a/lisp/mh-e/mh-search.el +++ b/lisp/mh-e/mh-search.el @@ -1,4 +1,4 @@ -;;; mh-search --- MH-Search mode +;;; mh-search --- MH-Search mode -*- lexical-binding: t; -*- ;; Copyright (C) 1993, 1995, 2001-2021 Free Software Foundation, Inc. @@ -332,7 +332,7 @@ configuration and is used when the search folder is dismissed." (interactive (list (mh-prompt-for-folder "Search" mh-current-folder nil nil t) (current-window-configuration))) ;; FIXME: `pick-folder' is unused! - (let ((pick-folder (if (equal folder "+") mh-current-folder folder))) + (let () ;; (pick-folder (if (equal folder "+") mh-current-folder folder)) (switch-to-buffer-other-window "search-pattern") (if (or (zerop (buffer-size)) (not (y-or-n-p "Reuse pattern? "))) @@ -356,7 +356,7 @@ configuration and is used when the search folder is dismissed." "---------\n") (mh-search-mode) (goto-char (point-min)) - (dotimes (i 5) + (dotimes (_ 5) (add-text-properties (point) (1+ (point)) '(front-sticky t)) (add-text-properties (- (mh-line-end-position) 2) (1- (mh-line-end-position)) @@ -453,7 +453,7 @@ search all folders." (defvar mh-flists-search-folders) -(defun mh-flists-execute (&rest ignored) +(defun mh-flists-execute (&rest _ignored) "Execute flists. Search for messages belonging to `mh-flists-sequence' in the folders specified by `mh-flists-search-folders'. If @@ -880,7 +880,7 @@ used to search." folder-path (format "%s/" folder-path))))) -(defalias 'mh-swish++-next-result 'mh-swish-next-result) +(defalias 'mh-swish++-next-result #'mh-swish-next-result) (defun mh-swish++-regexp-builder (regexp-list) "Generate query for swish++. @@ -1853,7 +1853,7 @@ PROC is used to convert the value to actual data." (1+ last-slash) (1- last-space))) (buffer-substring-no-properties (1+ last-space) end)))))) -(defalias 'mh-md5-parser 'mh-openssl-parser) +(defalias 'mh-md5-parser #'mh-openssl-parser) ;;;###mh-autoload (defun mh-index-update-maps (folder &optional origin-map) diff --git a/lisp/mh-e/mh-seq.el b/lisp/mh-e/mh-seq.el index e8a03f6704..f4b02c1974 100644 --- a/lisp/mh-e/mh-seq.el +++ b/lisp/mh-e/mh-seq.el @@ -1,4 +1,4 @@ -;;; mh-seq.el --- MH-E sequences support +;;; mh-seq.el --- MH-E sequences support -*- lexical-binding: t; -*- ;; Copyright (C) 1993, 1995, 2001-2021 Free Software Foundation, Inc. @@ -156,7 +156,7 @@ The list appears in a buffer named \"*MH-E Sequences*\"." (let ((name (mh-seq-name (car seq-list))) (sorted-seq-msgs (mh-coalesce-msg-list - (sort (copy-sequence (mh-seq-msgs (car seq-list))) '<))) + (sort (copy-sequence (mh-seq-msgs (car seq-list))) #'<))) name-spec) (insert (setq name-spec (format (format "%%%ss:" max-len) name))) (while sorted-seq-msgs @@ -191,7 +191,7 @@ MESSAGE appears." (cond (dest-folder (format " (to be refiled to %s)" dest-folder)) (deleted-flag (format " (to be deleted)")) (t "")) - (mapconcat 'concat + (mapconcat #'concat (mh-list-to-string (mh-seq-containing-msg message t)) " ")))) @@ -494,13 +494,13 @@ folder buffer are not updated." ;; Add to a SEQUENCE each message the list of MSGS. (if (and (mh-valid-seq-p seq) (not (mh-folder-name-p seq))) (if msgs - (apply 'mh-exec-cmd "mark" mh-current-folder "-add" + (apply #'mh-exec-cmd "mark" mh-current-folder "-add" "-sequence" (symbol-name seq) (mh-coalesce-msg-list msgs))))) (defun mh-canonicalize-sequence (msgs) "Sort MSGS in decreasing order and remove duplicates." - (let* ((sorted-msgs (sort (copy-sequence msgs) '>)) + (let* ((sorted-msgs (sort (copy-sequence msgs) #'>)) (head sorted-msgs)) (while (cdr head) (if (= (car head) (cadr head)) @@ -565,7 +565,7 @@ OP is one of `widen' and `unthread'." (defvar mh-range-seq-names) (defvar mh-range-history ()) (defvar mh-range-completion-map (copy-keymap minibuffer-local-completion-map)) -(define-key mh-range-completion-map " " 'self-insert-command) +(define-key mh-range-completion-map " " #'self-insert-command) ;;;###mh-autoload (defun mh-interactive-range (range-prompt &optional default) diff --git a/lisp/mh-e/mh-show.el b/lisp/mh-e/mh-show.el index 1d25b14732..cb9819f17c 100644 --- a/lisp/mh-e/mh-show.el +++ b/lisp/mh-e/mh-show.el @@ -1,4 +1,4 @@ -;;; mh-show.el --- MH-Show mode +;;; mh-show.el --- MH-Show mode -*- lexical-binding: t; -*- ;; Copyright (C) 1993, 1995, 1997, 2000-2021 Free Software Foundation, ;; Inc. @@ -195,7 +195,7 @@ Sets the current buffer to the show buffer." (let ((formfile mh-mhl-format-file) (clean-message-header mh-clean-message-header-flag) (invisible-headers mh-invisible-header-fields-compiled) - (visible-headers nil) + ;; (visible-headers nil) (msg-filename (mh-msg-filename msg-num folder-name)) (show-buffer mh-show-buffer) (mm-inline-media-tests mh-mm-inline-media-tests)) @@ -241,7 +241,7 @@ Sets the current buffer to the show buffer." (cond (clean-message-header (mh-clean-msg-header (point-min) invisible-headers - visible-headers) + nil) ;; visible-headers (goto-char (point-min))) (t (mh-start-of-uncleaned-message))) @@ -862,7 +862,7 @@ See also `mh-folder-mode'. (turn-on-font-lock)) (when mh-decode-mime-flag (mh-make-local-hook 'kill-buffer-hook) - (add-hook 'kill-buffer-hook 'mh-mime-cleanup nil t)) + (add-hook 'kill-buffer-hook #'mh-mime-cleanup nil t)) (mh-do-in-xemacs (easy-menu-add mh-show-sequence-menu) (easy-menu-add mh-show-message-menu) diff --git a/lisp/mh-e/mh-speed.el b/lisp/mh-e/mh-speed.el index 7cbd42c8ea..b2deacf6a7 100644 --- a/lisp/mh-e/mh-speed.el +++ b/lisp/mh-e/mh-speed.el @@ -1,4 +1,4 @@ -;;; mh-speed.el --- MH-E speedbar support +;;; mh-speed.el --- MH-E speedbar support -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. @@ -100,9 +100,9 @@ ;; Alphabetical. -(defalias 'mh-speed-contract-folder 'mh-speed-toggle) +(defalias 'mh-speed-contract-folder #'mh-speed-toggle) -(defalias 'mh-speed-expand-folder 'mh-speed-toggle) +(defalias 'mh-speed-expand-folder #'mh-speed-toggle) (defun mh-speed-refresh () "Regenerates the list of folders in the speedbar. @@ -202,9 +202,9 @@ created." (mh-speed-flists nil)))) ;;;###mh-autoload -(defalias 'mh-show-speedbar-buttons 'mh-folder-speedbar-buttons) +(defalias 'mh-show-speedbar-buttons #'mh-folder-speedbar-buttons) ;;;###mh-autoload -(defalias 'mh-letter-speedbar-buttons 'mh-folder-speedbar-buttons) +(defalias 'mh-letter-speedbar-buttons #'mh-folder-speedbar-buttons) (defmacro mh-speed-select-attached-frame () "Compatibility macro to handle speedbar versions 0.11a and 0.14beta4." @@ -431,7 +431,7 @@ flists is run only for that one folder." (setq mh-speed-flists-folder nil) (mh-process-kill-without-query mh-speed-flists-process) (set-process-filter mh-speed-flists-process - 'mh-speed-parse-flists-output))))))) + #'mh-speed-parse-flists-output))))))) ;; Copied from mh-make-folder-list-filter... ;; XXX Refactor to use mh-make-folder-list-filer? diff --git a/lisp/mh-e/mh-thread.el b/lisp/mh-e/mh-thread.el index 365746259a..a7878aaae9 100644 --- a/lisp/mh-e/mh-thread.el +++ b/lisp/mh-e/mh-thread.el @@ -1,4 +1,4 @@ -;;; mh-thread.el --- MH-E threading support +;;; mh-thread.el --- MH-E threading support -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2004, 2006-2021 Free Software Foundation, Inc. diff --git a/lisp/mh-e/mh-tool-bar.el b/lisp/mh-e/mh-tool-bar.el index 7dbddbc891..40a430b964 100644 --- a/lisp/mh-e/mh-tool-bar.el +++ b/lisp/mh-e/mh-tool-bar.el @@ -1,4 +1,4 @@ -;;; mh-tool-bar.el --- MH-E tool bar support +;;; mh-tool-bar.el --- MH-E tool bar support -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2003, 2005-2021 Free Software Foundation, Inc. @@ -356,7 +356,7 @@ Use SEQUENCE-MAP if display is limited; DEFAULT-MAP otherwise." '(list ,@(mapcar (lambda (x) `(quote ,x)) folder-defaults)) "List of buttons to include in MH-Folder tool bar." :group 'mh-tool-bar - :set 'mh-tool-bar-folder-buttons-set + :set #'mh-tool-bar-folder-buttons-set :type '(set ,@(cl-loop for x in folder-buttons for y in folder-docs collect `(const :tag ,y ,x))) @@ -367,7 +367,7 @@ Use SEQUENCE-MAP if display is limited; DEFAULT-MAP otherwise." '(list ,@(mapcar (lambda (x) `(quote ,x)) letter-defaults)) "List of buttons to include in MH-Letter tool bar." :group 'mh-tool-bar - :set 'mh-tool-bar-letter-buttons-set + :set #'mh-tool-bar-letter-buttons-set :type '(set ,@(cl-loop for x in letter-buttons for y in letter-docs collect `(const :tag ,y ,x))) diff --git a/lisp/mh-e/mh-utils.el b/lisp/mh-e/mh-utils.el index d7c607df5c..9497ba0d11 100644 --- a/lisp/mh-e/mh-utils.el +++ b/lisp/mh-e/mh-utils.el @@ -1,4 +1,4 @@ -;;; mh-utils.el --- MH-E general utilities +;;; mh-utils.el --- MH-E general utilities -*- lexical-binding: t; -*- ;; Copyright (C) 1993, 1995, 1997, 2000-2021 Free Software Foundation, ;; Inc. @@ -268,7 +268,7 @@ and displayed in a help buffer." (interactive) (let* ((help (or help-messages (cdr (assoc nil (assoc major-mode mh-help-messages))))) - (text (substitute-command-keys (mapconcat 'identity help "")))) + (text (substitute-command-keys (mapconcat #'identity help "")))) (with-electric-help (lambda () (insert text)) @@ -298,7 +298,7 @@ and displayed in a help buffer." This is the inverse of `mh-read-msg-list', which expands ranges. Message lists passed to MH programs should be processed by this function to avoid exceeding system command line argument limits." - (let ((msgs (sort (copy-sequence messages) 'mh-greaterp)) + (let ((msgs (sort (copy-sequence messages) #'mh-greaterp)) (range-high nil) (prev -1) (ranges nil)) @@ -669,7 +669,7 @@ three arguments so we bind this variable to t or nil. This variable should never be set.") (defvar mh-folder-completion-map (copy-keymap minibuffer-local-completion-map)) -(define-key mh-folder-completion-map " " 'minibuffer-complete) ;Why??? +(define-key mh-folder-completion-map " " #'minibuffer-complete) ;Why??? (defvar mh-speed-flists-inhibit-flag nil) @@ -730,8 +730,7 @@ See Info node `(elisp) Programmed Completion' for details." (t (file-directory-p path)))))))) ;; Shush compiler. -(mh-do-in-xemacs - (defvar completion-root-regexp)) +(defvar completion-root-regexp) ;; Apparently used in XEmacs (defun mh-folder-completing-read (prompt default allow-root-folder-flag) "Read folder name with PROMPT and default result DEFAULT. @@ -925,10 +924,10 @@ Handle RFC 822 (or later) continuation lines." (defvar mh-hidden-header-keymap (let ((map (make-sparse-keymap))) (mh-do-in-gnu-emacs - (define-key map [mouse-2] 'mh-letter-toggle-header-field-display-button)) + (define-key map [mouse-2] #'mh-letter-toggle-header-field-display-button)) (mh-do-in-xemacs (define-key map '(button2) - 'mh-letter-toggle-header-field-display-button)) + #'mh-letter-toggle-header-field-display-button)) map)) ;;;###mh-autoload diff --git a/lisp/mh-e/mh-xface.el b/lisp/mh-e/mh-xface.el index 036575a8e6..bf704c1857 100644 --- a/lisp/mh-e/mh-xface.el +++ b/lisp/mh-e/mh-xface.el @@ -1,4 +1,4 @@ -;;; mh-xface.el --- MH-E X-Face and Face header field display +;;; mh-xface.el --- MH-E X-Face and Face header field display -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2003, 2005-2021 Free Software Foundation, Inc. commit efd80237ca6085f28497bded259a92a48bb6005e Author: Stefan Monnier Date: Tue Mar 23 00:08:24 2021 -0400 * lisp/wdired.el: Fix typo in last change. Reported by Michael Heerdegen . (wdired-change-to-wdired-mode, wdired-change-to-dired-mode): The `(local FOO)` form takes an expression, so the var needs to be quoted. diff --git a/lisp/wdired.el b/lisp/wdired.el index e040b52600..43026d4bb7 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -246,7 +246,7 @@ See `wdired-mode'." (add-hook 'after-change-functions #'wdired--restore-properties nil t) (setq major-mode 'wdired-mode) (setq mode-name "Editable Dired") - (add-function :override (local revert-buffer-function) #'wdired-revert) + (add-function :override (local 'revert-buffer-function) #'wdired-revert) ;; I temp disable undo for performance: since I'm going to clear the ;; undo list, it can save more than a 9% of time with big ;; directories because setting properties modify the undo-list. @@ -381,7 +381,7 @@ non-nil means return old filename." (dired-advertise) (remove-hook 'kill-buffer-hook #'wdired-check-kill-buffer t) (remove-hook 'after-change-functions #'wdired--restore-properties t) - (remove-function (local revert-buffer-function) #'wdired-revert)) + (remove-function (local 'revert-buffer-function) #'wdired-revert)) (defun wdired-abort-changes () "Abort changes and return to dired mode." commit 22910e71e5092250b2134dae07bd8e2a82e4f750 Author: Lars Ingebrigtsen Date: Mon Mar 22 20:25:37 2021 +0100 Mention `C-o' in the `RET' doc string * lisp/simple.el (newline-and-indent): Mention `C-o' in the doc string. diff --git a/lisp/simple.el b/lisp/simple.el index eeef40f384..959bd83117 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -836,7 +836,10 @@ In programming language modes, this is the same as TAB. In some text modes, where TAB inserts a tab, this command indents to the column specified by the function `current-left-margin'. -With ARG, perform this action that many times." +With ARG, perform this action that many times. + +Also see `open-line' (bound to \\[open-line]) for a command that +just inserts a newline without doing any indentation." (interactive "*p") (delete-horizontal-space t) (unless arg commit b9683230ecaada87f23bdba59ef044c4b0374216 Author: Lars Ingebrigtsen Date: Mon Mar 22 20:18:00 2021 +0100 Fix previous face.el change * lisp/faces.el (require): Fix compilation warning from previous face.el change. diff --git a/lisp/faces.el b/lisp/faces.el index 3ea4c940a3..10675563ea 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -25,6 +25,8 @@ ;;; Code: +(eval-when-compile (require 'subr-x)) + (defcustom term-file-prefix (purecopy "term/") "If non-nil, Emacs startup performs terminal-specific initialization. It does this by: (load (concat term-file-prefix (getenv \"TERM\"))) commit 8c589c2583e5e8c4935a4f74ca725c35537774b7 Author: Juri Linkov Date: Mon Mar 22 20:55:49 2021 +0200 * lisp/tab-bar.el (tab-bar-new-tab-group): Set default to t. (tab-bar-tabs, tab-bar-select-tab, tab-bar-new-tab-to): Use tab-bar--current-tab-make instead of tab-bar--current-tab. (tab-bar--tab): Add arg 'frame' to tab-bar--current-tab-find. (tab-bar--current-tab, tab-bar--current-tab-make): Move most of body from the former to the latter, thus reverting tab-bar--current-tab to its previous behavior. https://lists.gnu.org/archive/html/emacs-devel/2021-03/msg00959.html diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 45ed2a6b31..63769673b9 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -345,7 +345,7 @@ before calling the command that adds a new tab." :group 'tab-bar :version "27.1") -(defcustom tab-bar-new-tab-group nil +(defcustom tab-bar-new-tab-group t "Defines what group to assign to a new tab. If nil, don't set a default group automatically. If t, inherit the group name from the previous tab. @@ -522,7 +522,7 @@ Return its existing value or a new value." (setf (cdr current-tab-name) (funcall tab-bar-tab-name-function)))) ;; Create default tabs - (setq tabs (list (tab-bar--current-tab))) + (setq tabs (list (tab-bar--current-tab-make))) (tab-bar-tabs-set tabs frame)) tabs)) @@ -795,7 +795,7 @@ on the tab bar instead." (push '(tabs . frameset-filter-tabs) frameset-filter-alist) (defun tab-bar--tab (&optional frame) - (let* ((tab (tab-bar--current-tab-find)) + (let* ((tab (tab-bar--current-tab-find nil frame)) (tab-explicit-name (alist-get 'explicit-name tab)) (tab-group (alist-get 'group tab)) (bl (seq-filter #'buffer-live-p (frame-parameter frame 'buffer-list))) @@ -816,7 +816,10 @@ on the tab bar instead." (wc-history-back . ,(gethash (or frame (selected-frame)) tab-bar-history-back)) (wc-history-forward . ,(gethash (or frame (selected-frame)) tab-bar-history-forward))))) -(defun tab-bar--current-tab (&optional tab) +(defun tab-bar--current-tab (&optional tab frame) + (tab-bar--current-tab-make (or tab (tab-bar--current-tab-find nil frame)))) + +(defun tab-bar--current-tab-make (&optional tab) ;; `tab' here is an argument meaning "use tab as template". This is ;; necessary when switching tabs, otherwise the destination tab ;; inherits the current tab's `explicit-name' parameter. @@ -933,7 +936,7 @@ ARG counts from 1. Negative ARG counts tabs from the end of the tab bar." (when from-index (setf (nth from-index tabs) from-tab)) - (setf (nth to-index tabs) (tab-bar--current-tab (nth to-index tabs))) + (setf (nth to-index tabs) (tab-bar--current-tab-make (nth to-index tabs))) (unless tab-bar-mode (message "Selected tab '%s'" (alist-get 'name to-tab)))) @@ -1111,7 +1114,7 @@ After the tab is created, the hooks in (when from-index (setf (nth from-index tabs) from-tab)) - (let* ((to-tab (tab-bar--current-tab + (let* ((to-tab (tab-bar--current-tab-make (when (eq tab-bar-new-tab-group t) `((group . ,(alist-get 'group from-tab)))))) (to-index (and to-index (prefix-numeric-value to-index))) commit add90dcc8a1b61edeb62b53cec5b532b4bb5d311 Author: Lars Ingebrigtsen Date: Mon Mar 22 19:47:25 2021 +0100 Use read-color in read-face-attribute for color attributes * lisp/faces.el (read-face-attribute): Use read-color when prompting for a color (bug#47316). diff --git a/lisp/faces.el b/lisp/faces.el index 5ae3906acc..3ea4c940a3 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -1259,7 +1259,15 @@ of a global face. Value is the new attribute value." (or (car (rassoc old-value valid)) (format "%s" old-value)))) (setq new-value - (face-read-string face default attribute-name valid)) + (if (memq attribute '(:foreground :background)) + (let ((color + (read-color + (format-prompt "%s for face `%s'" + default attribute-name face)))) + (if (equal (string-trim color) "") + default + color)) + (face-read-string face default attribute-name valid))) (if (equal new-value default) ;; Nothing changed, so don't bother with all the stuff ;; below. In particular, this avoids a non-tty color commit 4d944f6ddbac8f001ee6964c9b4a154debd76558 Author: Michael Albinus Date: Mon Mar 22 17:47:45 2021 +0100 * lisp/files-x.el (connection-local-criteria-for-default-directory): Add optional argument APPLICATION. diff --git a/lisp/files-x.el b/lisp/files-x.el index 526a128623..23e4562f4b 100644 --- a/lisp/files-x.el +++ b/lisp/files-x.el @@ -699,13 +699,14 @@ will not be changed." (copy-tree connection-local-variables-alist))) (hack-local-variables-apply))) -(defsubst connection-local-criteria-for-default-directory () - "Return a connection-local criteria, which represents `default-directory'." +(defsubst connection-local-criteria-for-default-directory (&optional application) + "Return a connection-local criteria, which represents `default-directory'. +If APPLICATION is nil, the symbol `tramp' is used." (when (file-remote-p default-directory) - `(:application tramp - :protocol ,(file-remote-p default-directory 'method) - :user ,(file-remote-p default-directory 'user) - :machine ,(file-remote-p default-directory 'host)))) + `(:application ,(or application 'tramp) + :protocol ,(file-remote-p default-directory 'method) + :user ,(file-remote-p default-directory 'user) + :machine ,(file-remote-p default-directory 'host)))) ;;;###autoload (defmacro with-connection-local-variables (&rest body) commit cb5d1fe1aa9f280d60fcb33b58fc83ace3d95081 Author: Stefan Kangas Date: Mon Mar 22 00:02:14 2021 +0100 Remove unnecessary requires of rx * lisp/cedet/semantic/wisent/python.el (rx): * test/src/process-tests.el (rx): Remove unnecessary requires. diff --git a/lisp/cedet/semantic/wisent/python.el b/lisp/cedet/semantic/wisent/python.el index 7a5761ce8c..9ac4ed9f51 100644 --- a/lisp/cedet/semantic/wisent/python.el +++ b/lisp/cedet/semantic/wisent/python.el @@ -27,8 +27,6 @@ ;;; Code: -(require 'rx) - ;; Try to load python support, but fail silently since it is only used ;; for optional functionality (require 'python nil t) diff --git a/test/src/process-tests.el b/test/src/process-tests.el index 17aef30a43..b64c82c87d 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -26,7 +26,6 @@ (require 'cl-lib) (require 'ert) (require 'puny) -(require 'rx) (require 'subr-x) (require 'dns) commit aa21273788a8727effd05e9ae5fb2b2369fbd559 Author: Stefan Kangas Date: Sun Mar 21 17:27:44 2021 +0100 Use lexical-binding in notifications.el * lisp/notifications.el: Use lexical-binding. (notifications-notify): Prefer 'push' to 'add-to-list'. diff --git a/lisp/notifications.el b/lisp/notifications.el index 2241afa905..b439d82231 100644 --- a/lisp/notifications.el +++ b/lisp/notifications.el @@ -1,4 +1,4 @@ -;;; notifications.el --- Client interface to desktop notifications. +;;; notifications.el --- Client interface to desktop notifications. -*- lexical-binding: t -*- ;; Copyright (C) 2010-2021 Free Software Foundation, Inc. @@ -229,56 +229,69 @@ of another `notifications-notify' call." id) ;; Build hints array (when urgency - (add-to-list 'hints `(:dict-entry - "urgency" - (:variant :byte ,(pcase urgency - ('low 0) - ('critical 2) - (_ 1)))) t)) + (push `(:dict-entry + "urgency" + (:variant :byte ,(pcase urgency + ('low 0) + ('critical 2) + (_ 1)))) + hints)) (when category - (add-to-list 'hints `(:dict-entry - "category" - (:variant :string ,category)) t)) + (push `(:dict-entry + "category" + (:variant :string ,category)) + hints)) (when desktop-entry - (add-to-list 'hints `(:dict-entry - "desktop-entry" - (:variant :string ,desktop-entry)) t)) + (push `(:dict-entry + "desktop-entry" + (:variant :string ,desktop-entry)) + hints)) (when image-data - (add-to-list 'hints `(:dict-entry - "image-data" - (:variant :struct ,image-data)) t)) + (push `(:dict-entry + "image-data" + (:variant :struct ,image-data)) + hints)) (when image-path - (add-to-list 'hints `(:dict-entry - "image-path" - (:variant :string ,image-path)) t)) + (push `(:dict-entry + "image-path" + (:variant :string ,image-path)) + hints)) (when action-items - (add-to-list 'hints `(:dict-entry - "action-items" - (:variant :boolean ,action-items)) t)) + (push `(:dict-entry + "action-items" + (:variant :boolean ,action-items)) + hints)) (when sound-file - (add-to-list 'hints `(:dict-entry - "sound-file" - (:variant :string ,sound-file)) t)) + (push `(:dict-entry + "sound-file" + (:variant :string ,sound-file)) + hints)) (when sound-name - (add-to-list 'hints `(:dict-entry - "sound-name" - (:variant :string ,sound-name)) t)) + (push `(:dict-entry + "sound-name" + (:variant :string ,sound-name)) + hints)) (when suppress-sound - (add-to-list 'hints `(:dict-entry - "suppress-sound" - (:variant :boolean ,suppress-sound)) t)) + (push `(:dict-entry + "suppress-sound" + (:variant :boolean ,suppress-sound)) + hints)) (when resident - (add-to-list 'hints `(:dict-entry - "resident" - (:variant :boolean ,resident)) t)) + (push `(:dict-entry + "resident" + (:variant :boolean ,resident)) + hints)) (when transient - (add-to-list 'hints `(:dict-entry - "transient" - (:variant :boolean ,transient)) t)) + (push `(:dict-entry + "transient" + (:variant :boolean ,transient)) + hints)) (when x - (add-to-list 'hints `(:dict-entry "x" (:variant :int32 ,x)) t)) + (push `(:dict-entry "x" (:variant :int32 ,x)) hints)) (when y - (add-to-list 'hints `(:dict-entry "y" (:variant :int32 ,y)) t)) + (push `(:dict-entry "y" (:variant :int32 ,y)) hints)) + + (setq hints (nreverse hints)) ;; Call Notify method. (setq id @@ -313,8 +326,8 @@ of another `notifications-notify' call." (on-close (plist-get params :on-close)) (unique-name (dbus-get-name-owner bus notifications-service))) (when on-action - (add-to-list 'notifications-on-action-map - (list (list bus unique-name id) on-action)) + (push (list (list bus unique-name id) on-action) + notifications-on-action-map) (unless notifications-on-action-object (setq notifications-on-action-object (dbus-register-signal @@ -326,8 +339,8 @@ of another `notifications-notify' call." 'notifications-on-action-signal)))) (when on-close - (add-to-list 'notifications-on-close-map - (list (list bus unique-name id) on-close)) + (push (list (list bus unique-name id) on-close) + notifications-on-close-map) (unless notifications-on-close-object (setq notifications-on-close-object (dbus-register-signal commit 7c2ebf6e23663fdc7b1880a4d7caeadc8c47c00e Author: Alan Mackenzie Date: Sun Mar 21 16:54:31 2021 +0000 Prevent open minibuffers getting lost when their frame gets deleted This happened with minibuffer-follows-selected-frame set to t. * doc/emacs/mini.texi (Basic Minibuffer): State where a command's action takes place when a minibuffer's frame has been deleted. * lisp/window.el (window--before-delete-windows, record-window-buffer): Take into account that minibuffers are now recorded on w->prev_buffers field. * src/fns.c (merge_c): New version of `merge' taking a C function, rather than a Lisp function as the comparison function. * src/frame.c (do_switch_frame): Pass arguments sf and for_deletion to move_minibuffers_onnto_frame. * src/lisp.h (top level): Declare merge_c and move_minibuffers_onto_selected_frame. * src/minibuf.c (MB_frame): New Lisp_Object recording the minibuffer's frame. (choose_minibuf_frame): Remove all code except that which sets minibuf_window to the current frame's minibuffer. (minibuffer_ent_greater): New comparison function, passed to merge_c. (zip_minibuffer_stacks): New function. (move_minibuffers_onto_frame): Renamed from `move_minibuffer_onto_frame' given two arguments, the old frame and for_deletion, and simplified. Minibuffers are now stacked in the mini-window's ->prev_buffers field. (read_minibuf): Several detailed amendments. (exp_MB_frame): New Lisp_Object, the expired minibuffer's frame. (read_minibuf_unwind): Search for the expired minibuffer's frame, rather than taking it from (unreliable) variables. Switch temporarily to this frame for tidying up operations. (minibuffer_unwind): New function which pops a stacked minibuffer. (syms_of_minibuf): Call staticpro for the two new Lisp variables. * src/window.c (Fset_window_configuration): Don't record minibuffers with record-window-buffer. * src/xdisp.c (gui_consider_frame_title): Remove redundant Fselect_window, which caused an unwanted frame switch. Amend the arguments to format_mode_line_unwind_data to match. diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi index 9c1b975759..d0865c5d0b 100644 --- a/doc/emacs/mini.texi +++ b/doc/emacs/mini.texi @@ -82,7 +82,9 @@ after a recursive minibuffer has been opened in the current command (@pxref{Recursive Mini,,, elisp}). This option is mainly to retain (approximately) the behavior prior to Emacs 28.1. Note that the effect of the command, when you finally finish using the minibuffer, -always takes place in the frame where you first opened it. +always takes place in the frame where you first opened it. The sole +exception is that when that frame no longer exists, the action takes +place in the currently selected frame. @node Minibuffer File @section Minibuffers for File Names diff --git a/lisp/window.el b/lisp/window.el index cfd9876ed0..f27631bb86 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -4158,7 +4158,7 @@ returned by `window-start' and `window-point' respectively. This function is called only if `switch-to-buffer-preserve-window-point' evaluates non-nil." - (dolist (win (window-list)) + (dolist (win (window-list nil 'no-minibuf)) (let* ((buf (window-buffer (or window win))) (start (window-start win)) (pos (window-point win)) @@ -4416,7 +4416,8 @@ WINDOW must be a live window and defaults to the selected one." window (assq-delete-all buffer (window-prev-buffers window)))) ;; Don't record insignificant buffers. - (unless (eq (aref (buffer-name buffer) 0) ?\s) + (when (or (not (eq (aref (buffer-name buffer) 0) ?\s)) + (minibufferp buffer)) ;; Add an entry for buffer to WINDOW's previous buffers. (with-current-buffer buffer (let ((start (window-start window)) diff --git a/src/fns.c b/src/fns.c index 766e767e12..2cd59c83d9 100644 --- a/src/fns.c +++ b/src/fns.c @@ -2279,6 +2279,52 @@ merge (Lisp_Object org_l1, Lisp_Object org_l2, Lisp_Object pred) } } +Lisp_Object +merge_c (Lisp_Object org_l1, Lisp_Object org_l2, bool (*less) (Lisp_Object, Lisp_Object)) +{ + Lisp_Object l1 = org_l1; + Lisp_Object l2 = org_l2; + Lisp_Object tail = Qnil; + Lisp_Object value = Qnil; + + while (1) + { + if (NILP (l1)) + { + if (NILP (tail)) + return l2; + Fsetcdr (tail, l2); + return value; + } + if (NILP (l2)) + { + if (NILP (tail)) + return l1; + Fsetcdr (tail, l1); + return value; + } + + Lisp_Object tem; + if (less (Fcar (l1), Fcar (l2))) + { + tem = l1; + l1 = Fcdr (l1); + org_l1 = l1; + } + else + { + tem = l2; + l2 = Fcdr (l2); + org_l2 = l2; + } + if (NILP (tail)) + value = tem; + else + Fsetcdr (tail, tem); + tail = tem; + } +} + /* This does not check for quits. That is safe since it must terminate. */ diff --git a/src/frame.c b/src/frame.c index cfdf3b6193..66ae4943ba 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1487,7 +1487,7 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor #endif internal_last_event_frame = Qnil; - move_minibuffer_onto_frame (); + move_minibuffers_onto_frame (sf, for_deletion); return frame; } diff --git a/src/lisp.h b/src/lisp.h index b95f389b89..c67c8b0857 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3610,6 +3610,7 @@ extern void validate_subarray (Lisp_Object, Lisp_Object, Lisp_Object, extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t); extern Lisp_Object merge (Lisp_Object, Lisp_Object, Lisp_Object); +extern Lisp_Object merge_c (Lisp_Object, Lisp_Object, bool (*) (Lisp_Object, Lisp_Object)); extern Lisp_Object do_yes_or_no_p (Lisp_Object); extern int string_version_cmp (Lisp_Object, Lisp_Object); extern Lisp_Object concat2 (Lisp_Object, Lisp_Object); @@ -4348,7 +4349,7 @@ extern void clear_regexp_cache (void); extern Lisp_Object Vminibuffer_list; extern Lisp_Object last_minibuf_string; -extern void move_minibuffer_onto_frame (void); +extern void move_minibuffers_onto_frame (struct frame *, bool); extern bool is_minibuffer (EMACS_INT, Lisp_Object); extern EMACS_INT this_minibuffer_depth (Lisp_Object); extern EMACS_INT minibuf_level; diff --git a/src/minibuf.c b/src/minibuf.c index 4b1f4b1ff7..d58924ae52 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -59,6 +59,12 @@ Lisp_Object last_minibuf_string; static Lisp_Object minibuf_prompt; +/* The frame containinug the most recently opened Minibuffer. This is + used only when `minibuffer-follows-selected-frame' is neither nil + nor t. */ + +static Lisp_Object MB_frame; + /* Width of current mini-buffer prompt. Only set after display_line of the line that contains the prompt. */ @@ -67,6 +73,7 @@ static ptrdiff_t minibuf_prompt_width; static Lisp_Object nth_minibuffer (EMACS_INT depth); static EMACS_INT minibuf_c_loop_level (EMACS_INT depth); static void set_minibuffer_mode (Lisp_Object buf, EMACS_INT depth); +static bool live_minibuffer_p (Lisp_Object); /* Return TRUE when a frame switch causes a minibuffer on the old @@ -78,6 +85,7 @@ minibuf_follows_frame (void) Qt); } +#if 0 /* Return TRUE when a minibuffer always remains on the frame where it was first invoked. */ static bool @@ -85,6 +93,7 @@ minibuf_stays_put (void) { return NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame)); } +#endif /* Return TRUE when opening a (recursive) minibuffer causes minibuffers on other frames to move to the selected frame. */ @@ -112,84 +121,85 @@ choose_minibuf_frame (void) emacs_abort (); minibuf_window = sf->minibuffer_window; - /* If we've still got another minibuffer open, use its mini-window - instead. */ - if (minibuf_level > 1 && minibuf_stays_put ()) - { - Lisp_Object buffer = get_minibuffer (minibuf_level); - Lisp_Object tail, frame; - - FOR_EACH_FRAME (tail, frame) - if (EQ (XWINDOW (XFRAME (frame)->minibuffer_window)->contents, - buffer)) - { - minibuf_window = XFRAME (frame)->minibuffer_window; - break; - } - } } +} - if (minibuf_moves_frame_when_opened () - && FRAMEP (selected_frame) - && FRAME_LIVE_P (XFRAME (selected_frame))) - /* Make sure no other frame has a minibuffer as its selected window, - because the text would not be displayed in it, and that would be - confusing. Only allow the selected frame to do this, - and that only if the minibuffer is active. */ - { - Lisp_Object tail, frame; - struct frame *of; - - FOR_EACH_FRAME (tail, frame) - if (!EQ (frame, selected_frame) - && minibuf_level > 1 - /* The frame's minibuffer can be on a different frame. */ - && ! EQ (XWINDOW ((of = XFRAME (frame))->minibuffer_window)->frame, - selected_frame)) - { - if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (of)))) - Fset_frame_selected_window (frame, Fframe_first_window (frame), - Qnil); - - if (!EQ (XWINDOW (of->minibuffer_window)->contents, - nth_minibuffer (0))) - set_window_buffer (of->minibuffer_window, - nth_minibuffer (0), 0, 0); - } - } +/* If ENT1 has a higher minibuffer index than ENT2, return true. More +precisely, compare the buffer components of each window->prev_buffers +entry. */ +static bool +minibuffer_ent_greater (Lisp_Object ent1, Lisp_Object ent2) +{ + return this_minibuffer_depth (Fcar (ent1)) + > this_minibuffer_depth (Fcar (ent2)) ; } -/* If `minibuffer_follows_selected_frame' is t and we have a - minibuffer, move it from its current frame to the selected frame. - This function is intended to be called from `do_switch_frame' in - frame.c. */ -void move_minibuffer_onto_frame (void) +/* Move the ordered "stack" of minibuffers from SOURCE_WINDOW to + DEST_WINDOW, interleaving those minibuffers with any in DEST_WINDOW + to produce an ordered combination. The ordering is by minibuffer + depth. A stack of minibuffers consists of the minibuffer currently + in DEST/SOURCE_WINDOW together with any recorded in the + ->prev_buffers field of the struct window. */ +static void +zip_minibuffer_stacks (Lisp_Object dest_window, Lisp_Object source_window) { - if (!minibuf_level) - return; - if (!minibuf_follows_frame ()) - return; - if (FRAMEP (selected_frame) - && FRAME_LIVE_P (XFRAME (selected_frame)) - && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window)) + struct window *dw = XWINDOW (dest_window); + struct window *sw = XWINDOW (source_window); + Lisp_Object acc; + Lisp_Object d_ent; /* Entry from dw->prev_buffers */ + + if (!live_minibuffer_p (dw->contents) + && NILP (dw->prev_buffers)) { - EMACS_INT i; - struct frame *sf = XFRAME (selected_frame); - Lisp_Object old_frame = XWINDOW (minibuf_window)->frame; - struct frame *of = XFRAME (old_frame); + set_window_buffer (dest_window, sw->contents, 0, 0); + Fset_window_start (dest_window, Fwindow_start (source_window), Qnil); + Fset_window_point (dest_window, Fwindow_point (source_window)); + dw->prev_buffers = sw->prev_buffers; + set_window_buffer (source_window, get_minibuffer (0), 0, 0); + sw->prev_buffers = Qnil; + return; + } - /* Stack up all the (recursively) open minibuffers on the selected - mini_window. */ - for (i = 1; i <= minibuf_level; i++) - set_window_buffer (sf->minibuffer_window, nth_minibuffer (i), 0, 0); - minibuf_window = sf->minibuffer_window; - if (of != sf) - { - Lisp_Object temp = get_minibuffer (0); + if (live_minibuffer_p (dw->contents)) + call1 (Qrecord_window_buffer, dest_window); + if (live_minibuffer_p (sw->contents)) + call1 (Qrecord_window_buffer, source_window); - set_window_buffer (of->minibuffer_window, temp, 0, 0); - set_minibuffer_mode (temp, 0); - } + acc = merge_c (dw->prev_buffers, sw->prev_buffers, minibuffer_ent_greater); + + if (!NILP (acc)) + { + d_ent = Fcar (acc); + acc = Fcdr (acc); + set_window_buffer (dest_window, Fcar (d_ent), 0, 0); + Fset_window_start (dest_window, Fcar (Fcdr (d_ent)), Qnil); + Fset_window_point (dest_window, Fcar (Fcdr (Fcdr (d_ent)))); + } + dw->prev_buffers = acc; + sw->prev_buffers = Qnil; + set_window_buffer (source_window, get_minibuffer (0), 0, 0); +} + +/* If `minibuffer_follows_selected_frame' is t, or we're about to + delete a frame which potentially "contains" minibuffers, move them + from the old frame to the selected frame. This function is + intended to be called from `do_switch_frame' in frame.c. OF is the + old frame, FOR_DELETION is true if OF is about to be deleted. */ +void +move_minibuffers_onto_frame (struct frame *of, bool for_deletion) +{ + struct frame *f = XFRAME (selected_frame); + + minibuf_window = f->minibuffer_window; + if (!(minibuf_level + && (for_deletion || minibuf_follows_frame () || FRAME_INITIAL_P (of)))) + return; + if (FRAME_LIVE_P (f) + && !EQ (f->minibuffer_window, of->minibuffer_window)) + { + zip_minibuffer_stacks (f->minibuffer_window, of->minibuffer_window); + if (for_deletion && XFRAME (MB_frame) != of) + MB_frame = selected_frame; } } @@ -221,6 +231,7 @@ without invoking the usual minibuffer commands. */) /* Actual minibuffer invocation. */ static void read_minibuf_unwind (void); +static void minibuffer_unwind (void); static void run_exit_minibuf_hook (void); @@ -544,7 +555,6 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, Lisp_Object histval; Lisp_Object empty_minibuf; - Lisp_Object dummy, frame; specbind (Qminibuffer_default, defalt); specbind (Qinhibit_read_only, Qnil); @@ -626,17 +636,24 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window)); if (minibuf_level > 1 + && !EQ (XWINDOW (XFRAME (selected_frame)->minibuffer_window)->frame, + MB_frame) && minibuf_moves_frame_when_opened () - && (!minibuf_follows_frame () - || (!EQ (mini_frame, selected_frame)))) + && (!minibuf_follows_frame ())) { - EMACS_INT i; + struct frame *of = XFRAME (MB_frame); - /* Stack up the existing minibuffers on the current mini-window */ - for (i = 1; i < minibuf_level; i++) - set_window_buffer (minibuf_window, nth_minibuffer (i), 0, 0); + zip_minibuffer_stacks (minibuf_window, of->minibuffer_window); + /* MB_frame's minibuffer can be on a different frame. */ + if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (of)))) + Fset_frame_selected_window (MB_frame, + Fframe_first_window (MB_frame), Qnil); } + MB_frame = XWINDOW (XFRAME (selected_frame)->minibuffer_window)->frame; + if (live_minibuffer_p (XWINDOW (minibuf_window)->contents)) + call1 (Qrecord_window_buffer, minibuf_window); + record_unwind_protect_void (minibuffer_unwind); record_unwind_protect (restore_window_configuration, Fcons (Qt, Fcurrent_window_configuration (Qnil))); @@ -771,23 +788,6 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, empty_minibuf = get_minibuffer (0); set_minibuffer_mode (empty_minibuf, 0); - FOR_EACH_FRAME (dummy, frame) - { - Lisp_Object root_window = Fframe_root_window (frame); - Lisp_Object mini_window = XWINDOW (root_window)->next; - Lisp_Object buffer; - - if (!NILP (mini_window) && !EQ (mini_window, minibuf_window) - && !NILP (Fwindow_minibuffer_p (mini_window))) - { - buffer = XWINDOW (mini_window)->contents; - if (!live_minibuffer_p (buffer)) - /* Use set_window_buffer instead of Fset_window_buffer (see - discussion of bug#11984, bug#12025, bug#12026). */ - set_window_buffer (mini_window, empty_minibuf, 0, 0); - } - } - /* Display this minibuffer in the proper window. */ /* Use set_window_buffer instead of Fset_window_buffer (see discussion of bug#11984, bug#12025, bug#12026). */ @@ -908,7 +908,9 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, unbind_to (count, Qnil); /* Switch the frame back to the calling frame. */ - if (!EQ (selected_frame, calling_frame) + if ((!EQ (selected_frame, calling_frame) + || !EQ (XWINDOW (XFRAME (calling_frame)->minibuffer_window)->frame, + calling_frame)) && FRAMEP (calling_frame) && FRAME_LIVE_P (XFRAME (calling_frame))) call2 (intern ("select-frame-set-input-focus"), calling_frame, Qnil); @@ -1026,6 +1028,14 @@ run_exit_minibuf_hook (void) safe_run_hooks (Qminibuffer_exit_hook); } +/* This variable records the expired minibuffer's frame between the + calls of `read_minibuf_unwind' and `minibuffer_unwind'. It should + be used only by these two functions. Note that the same search + method for the MB's frame won't always work in `minibuffer_unwind' + because the intervening `restore-window-configuration' will have + changed the buffer in the mini-window. */ +static Lisp_Object exp_MB_frame; + /* This function is called on exiting minibuffer, whether normally or not, and it restores the current window, buffer, etc. */ @@ -1036,6 +1046,28 @@ read_minibuf_unwind (void) Lisp_Object calling_frame; Lisp_Object calling_window; Lisp_Object future_mini_window; + Lisp_Object saved_selected_frame = selected_frame; + Lisp_Object window, frames; + struct window *w; + struct frame *f; + + /* Locate the expired minibuffer. */ + FOR_EACH_FRAME (frames, exp_MB_frame) + { + f = XFRAME (exp_MB_frame); + window = f->minibuffer_window; + w = XWINDOW (window); + if (EQ (w->frame, exp_MB_frame) + && EQ (w->contents, nth_minibuffer (minibuf_level))) + goto found; + } + return; /* expired minibuffer not found. Maybe we should output an + error, here. */ + + found: + if (!EQ (exp_MB_frame, saved_selected_frame)) + do_switch_frame (exp_MB_frame, 0, 0, Qt); /* This also sets + minibuff_window */ /* To keep things predictable, in case it matters, let's be in the minibuffer when we reset the relevant variables. Don't depend on @@ -1127,20 +1159,61 @@ read_minibuf_unwind (void) away from the expired minibuffer window, both in the current minibuffer's frame and the original calling frame. */ choose_minibuf_frame (); - if (!EQ (WINDOW_FRAME (XWINDOW (minibuf_window)), calling_frame)) - { - Lisp_Object prev = Fprevious_window (minibuf_window, Qnil, Qnil); - /* PREV can be on a different frame when we have a minibuffer only - frame, the other frame's minibuffer window is MINIBUF_WINDOW, - and its "focus window" is also MINIBUF_WINDOW. */ - if (!EQ (prev, minibuf_window) - && EQ (WINDOW_FRAME (XWINDOW (prev)), - WINDOW_FRAME (XWINDOW (minibuf_window)))) - Fset_frame_selected_window (selected_frame, prev, Qnil); - } - else - Fset_frame_selected_window (calling_frame, calling_window, Qnil); + if (NILP (XWINDOW (minibuf_window)->prev_buffers)) + { + if (!EQ (WINDOW_FRAME (XWINDOW (minibuf_window)), calling_frame)) + { + Lisp_Object prev = Fprevious_window (minibuf_window, Qnil, Qnil); + /* PREV can be on a different frame when we have a minibuffer only + frame, the other frame's minibuffer window is MINIBUF_WINDOW, + and its "focus window" is also MINIBUF_WINDOW. */ + if (!EQ (prev, minibuf_window) + && EQ (WINDOW_FRAME (XWINDOW (prev)), + WINDOW_FRAME (XWINDOW (minibuf_window)))) + Fset_frame_selected_window (selected_frame, prev, Qnil); + } + else + Fset_frame_selected_window (calling_frame, calling_window, Qnil); + } + + /* Restore the selected frame. */ + if (!EQ (exp_MB_frame, saved_selected_frame)) + do_switch_frame (saved_selected_frame, 0, 0, Qt); +} + +/* Replace the expired minibuffer in frame exp_MB_frame with the next less + nested minibuffer in that frame, if any. Otherwise, replace it + with the null minibuffer. MINIBUF_WINDOW is not changed. */ +static void +minibuffer_unwind (void) +{ + struct frame *f; + struct window *w; + Lisp_Object window; + Lisp_Object entry; + + f = XFRAME (exp_MB_frame); + window = f->minibuffer_window; + w = XWINDOW (window); + if (FRAME_LIVE_P (f)) + { + /* minibuf_window = sf->minibuffer_window; */ + if (!NILP (w->prev_buffers)) + { + entry = Fcar (w->prev_buffers); + w->prev_buffers = Fcdr (w->prev_buffers); + set_window_buffer (window, Fcar (entry), 0, 0); + Fset_window_start (window, Fcar (Fcdr (entry)), Qnil); + Fset_window_point (window, Fcar (Fcdr (Fcdr (entry)))); + /* set-window-configuration may/will have unselected the + mini-window as the selected window. Restore it. */ + Fset_frame_selected_window (exp_MB_frame, window, Qnil); + } + else + set_window_buffer (window, nth_minibuffer (0), 0, 0); + } } + void @@ -2213,6 +2286,9 @@ syms_of_minibuf (void) { staticpro (&minibuf_prompt); staticpro (&minibuf_save_list); + staticpro (&MB_frame); + MB_frame = Qnil; + staticpro (&exp_MB_frame); DEFSYM (Qminibuffer_follows_selected_frame, "minibuffer-follows-selected-frame"); diff --git a/src/window.c b/src/window.c index eb16e2a433..4d5c7e763e 100644 --- a/src/window.c +++ b/src/window.c @@ -6958,7 +6958,8 @@ the return value is nil. Otherwise the value is t. */) if (BUFFERP (w->contents) && !EQ (w->contents, p->buffer) - && BUFFER_LIVE_P (XBUFFER (p->buffer))) + && BUFFER_LIVE_P (XBUFFER (p->buffer)) + && (NILP (Fminibufferp (p->buffer, Qnil)))) /* If a window we restore gets another buffer, record the window's old buffer. */ call1 (Qrecord_window_buffer, window); diff --git a/src/xdisp.c b/src/xdisp.c index cc0a689ba3..a405d51f80 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -12650,9 +12650,8 @@ gui_consider_frame_title (Lisp_Object frame) mode_line_noprop_buf; then display the title. */ record_unwind_protect (unwind_format_mode_line, format_mode_line_unwind_data - (f, current_buffer, selected_window, false)); + (NULL, current_buffer, Qnil, false)); - Fselect_window (f->selected_window, Qt); set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->contents)); fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format; commit e276810dff9838e1bb8c2ec450f85835ed60bf14 Author: Glenn Morris Date: Sun Mar 21 09:15:51 2021 -0700 * lisp/thumbs.el (thumbs-conversion-program): Simplify. /usr/bin is (normally) always in PATH, and this need not be absolute, so the executable-find is unnecesary. diff --git a/lisp/thumbs.el b/lisp/thumbs.el index e43d13d703..3e7c9124e2 100644 --- a/lisp/thumbs.el +++ b/lisp/thumbs.el @@ -93,11 +93,12 @@ When it reaches that size (in bytes), a warning is sent." ;; customize this value to the absolute filename. (defcustom thumbs-conversion-program (if (eq system-type 'windows-nt) + ;; FIXME is this necessary, or can a sane PATHEXE be assumed? + ;; Eg find-program does not do this. "convert.exe" - (or (executable-find "convert") - "/usr/bin/convert")) + "convert") "Name of conversion program for thumbnails generation. -It must be \"convert\"." +This must be the ImageMagick \"convert\" utility." :type 'string :version "28.1") commit 574eadbdaf69a70f9eba9d6ab5b960649b88de15 Author: Stefan Kangas Date: Sun Mar 21 17:04:32 2021 +0100 Actually use lexical-binding in wid-browse.el * lisp/wid-browse.el: Use lexical-binding. I apparently forgot to commit the lexical-binding cookie in my previous attempt. diff --git a/lisp/wid-browse.el b/lisp/wid-browse.el index 39b3221762..54b71c9f9f 100644 --- a/lisp/wid-browse.el +++ b/lisp/wid-browse.el @@ -1,7 +1,7 @@ -;;; wid-browse.el --- functions for browsing widgets -;; +;;; wid-browse.el --- functions for browsing widgets -*- lexical-binding: t -*- + ;; Copyright (C) 1997, 2001-2021 Free Software Foundation, Inc. -;; + ;; Author: Per Abrahamsen ;; Keywords: extensions ;; Package: emacs @@ -22,7 +22,7 @@ ;; along with GNU Emacs. If not, see . ;;; Commentary: -;; + ;; Widget browser. See `widget.el'. ;;; Code: @@ -38,7 +38,7 @@ (defvar widget-browse-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map widget-keymap) - (define-key map "q" 'bury-buffer) + (define-key map "q" #'bury-buffer) map) "Keymap for `widget-browse-mode'.") commit 70b64e0d040e9c57f1a489c9ebee553264033119 Author: Theodor Thornhill Date: Sun Mar 21 08:02:28 2021 +0100 Use pop-to-buffer-same-window for shell * lisp/progmodes/project.el (project-shell): Behave the same way as 'M-x project-eshell'. * lisp/shell.el (shell): Behave the same way as 'M-x eshell'. * etc/NEWS: Add news entry describing the change. * lisp/tutorial.el: Use lexical-binding. diff --git a/etc/NEWS b/etc/NEWS index c602166397..49a4bb8106 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2300,6 +2300,10 @@ since the latter uses 'M-s' as a prefix key of the search prefix map. ** 'vc-print-branch-log' shows the change log for BRANCH from its root directory instead of the default directory. +--- +** 'project-shell' and 'shell' now use 'pop-to-buffer-same-window'. +This is to keep the same behavior as Eshell. + * Incompatible Lisp Changes in Emacs 28.1 diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index bd552c917a..b6a886f731 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -911,7 +911,7 @@ if one already exists." "-shell*")) (shell-buffer (get-buffer default-project-shell-name))) (if (and shell-buffer (not current-prefix-arg)) - (pop-to-buffer shell-buffer) + (pop-to-buffer-same-window shell-buffer) (shell (generate-new-buffer-name default-project-shell-name))))) ;;;###autoload diff --git a/lisp/shell.el b/lisp/shell.el index 53f5d0b6f1..7f4ca76547 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -743,7 +743,7 @@ Make the shell buffer the current buffer, and return it. (current-buffer))) ;; The buffer's window must be correctly set when we call comint ;; (so that comint sets the COLUMNS env var properly). - (pop-to-buffer buffer) + (pop-to-buffer-same-window buffer) (with-connection-local-variables ;; On remote hosts, the local `shell-file-name' might be useless. commit 3cbf92323c544df516ac28da5e6eac9a241103c4 Author: Zhiwei Chen Date: Sun Mar 21 08:09:14 2021 +0100 Allow hide-ifdef-guts to work in buffers not visiting files * lisp/progmodes/hideif.el (hide-ifdef-guts): Allow working in buffers not visiting files (bug#47279). Copyright-paperwork-exempt: yes diff --git a/lisp/progmodes/hideif.el b/lisp/progmodes/hideif.el index 923f85fd4d..6f1a8781b4 100644 --- a/lisp/progmodes/hideif.el +++ b/lisp/progmodes/hideif.el @@ -1743,10 +1743,10 @@ first arg will be `hif-etc'." (defun hide-ifdef-guts () "Does most of the work of `hide-ifdefs'. It does not do the work that's pointless to redo on a recursive entry." - ;; (message "hide-ifdef-guts") (save-excursion (let* ((case-fold-search t) ; Ignore case for `hide-ifdef-header-regexp' (expand-header (and hide-ifdef-expand-reinclusion-protection + (buffer-file-name) (string-match hide-ifdef-header-regexp (buffer-file-name)) (zerop hif-recurse-level))) commit e9e691093ab843911b0ac7a9a9188d477415db2e Author: Stefan Kangas Date: Sun Mar 21 02:26:37 2021 +0100 * lisp/tutorial.el: Use lexical-binding. diff --git a/lisp/tutorial.el b/lisp/tutorial.el index 57e5570d53..186bf35fe7 100644 --- a/lisp/tutorial.el +++ b/lisp/tutorial.el @@ -1,4 +1,4 @@ -;;; tutorial.el --- tutorial for Emacs +;;; tutorial.el --- tutorial for Emacs -*- lexical-binding: t -*- ;; Copyright (C) 2006-2021 Free Software Foundation, Inc. @@ -25,10 +25,6 @@ ;; Code for running the Emacs tutorial. -;;; History: - -;; File was created 2006-09. - ;;; Code: (require 'help-mode) ;; for function help-buffer @@ -517,8 +513,8 @@ where (list "more info" 'current-binding key-fun def-fun key where)) nil)) - (add-to-list 'changed-keys - (list key def-fun def-fun-txt where remark nil)))))) + (push (list key def-fun def-fun-txt where remark nil) + changed-keys))))) changed-keys)) (defun tutorial--key-description (key) @@ -768,7 +764,7 @@ Run the Viper tutorial? ")) (if (fboundp 'viper-tutorial) (if (y-or-n-p (concat prompt1 prompt2)) (progn (message "") - (funcall 'viper-tutorial 0)) + (funcall #'viper-tutorial 0)) (message "Tutorial aborted by user")) (message prompt1))) (let* ((lang (cond commit f27a9a341ffc19b1178b2df7eac4ab0730bae961 Author: Stefan Monnier Date: Sat Mar 20 20:39:01 2021 -0400 * lisp/cedet/semantic/ia.el (semantic-ia-complete-symbol): Simplify Cut the `semantic-ia-get-completions-deprecated` middle man. diff --git a/lisp/cedet/semantic/ia.el b/lisp/cedet/semantic/ia.el index e75bc918e0..7186a78123 100644 --- a/lisp/cedet/semantic/ia.el +++ b/lisp/cedet/semantic/ia.el @@ -79,13 +79,8 @@ (insert "(")) (t nil)))) -(defalias 'semantic-ia-get-completions #'semantic-ia-get-completions-deprecated) -(make-obsolete 'semantic-ia-get-completions - #'semantic-analyze-possible-completions "28.1") - -(defun semantic-ia-get-completions-deprecated (context _point) - "A function to help transition away from `semantic-ia-get-completions'. -Return completions based on CONTEXT at POINT." +(defun semantic-ia-get-completions (context _point) + "Fetch the completion of CONTEXT at POINT." (declare (obsolete semantic-analyze-possible-completions "28.1")) (semantic-analyze-possible-completions context)) commit dee2f914f31bb6246cf39d8a79a76ce609babda2 Author: Stefan Kangas Date: Sat Mar 20 16:09:29 2021 +0100 Remove support for Syndic8.com, defunct since 2013 * lisp/gnus/nnrss.el (nnrss-discover-feed) (nnrss-find-rss-via-syndic8): Remove support for Syndic8.com, as the site was shut down in 2013. diff --git a/lisp/gnus/nnrss.el b/lisp/gnus/nnrss.el index 36b7af0e34..a40fa88631 100644 --- a/lisp/gnus/nnrss.el +++ b/lisp/gnus/nnrss.el @@ -930,60 +930,7 @@ Use Mark Pilgrim's `ultra-liberal rss locator'." (setq rss-link (nnrss-rss-title-description rss-ns href-data (car hrefs)))) (setq hrefs (cdr hrefs))))) - (if rss-link - rss-link - ;; 4. check syndic8 - (nnrss-find-rss-via-syndic8 url)))))))) - -(declare-function xml-rpc-method-call "ext:xml-rpc" - (server-url method &rest params)) - -(defun nnrss-find-rss-via-syndic8 (url) - "Query syndic8 for the rss feeds it has for URL." - (if (not (locate-library "xml-rpc")) - (progn - (message "XML-RPC is not available... not checking Syndic8.") - nil) - (require 'xml-rpc) - (let ((feedid (xml-rpc-method-call - "http://www.syndic8.com/xmlrpc.php" - 'syndic8.FindSites - url))) - (when feedid - (let* ((feedinfo (xml-rpc-method-call - "http://www.syndic8.com/xmlrpc.php" - 'syndic8.GetFeedInfo - feedid)) - (urllist - (delq nil - (mapcar - (lambda (listinfo) - (if (string-equal - (cdr (assoc "status" listinfo)) - "Syndicated") - (cons - (cdr (assoc "sitename" listinfo)) - (list - (cons 'title - (cdr (assoc - "sitename" listinfo))) - (cons 'href - (cdr (assoc - "dataurl" listinfo))))))) - feedinfo)))) - (if (not (> (length urllist) 1)) - (cdar urllist) - (let ((completion-ignore-case t) - (selection - (mapcar (lambda (listinfo) - (cons (cdr (assoc "sitename" listinfo)) - (string-to-number - (cdr (assoc "feedid" listinfo))))) - feedinfo))) - (cdr (assoc - (gnus-completing-read - "Multiple feeds found. Select one" - selection t) urllist))))))))) + rss-link)))))) (defun nnrss-rss-p (data) "Test if DATA is an RSS feed. @@ -1022,6 +969,11 @@ prefix), return the prefix." (concat ns ":") ns))) +(defun nnrss-find-rss-via-syndic8 (_url) + "This function is obsolete and does nothing. Syndic8 shut down in 2013." + (declare (obsolete nil "28.1")) + nil) + (provide 'nnrss) ;;; nnrss.el ends here commit b4a125e5ad1de3eb770dff12017f1e0658c4c6a2 Author: Eli Zaretskii Date: Sat Mar 20 12:11:04 2021 +0200 ; * etc/NEWS: Minor improvement to the last change. diff --git a/etc/NEWS b/etc/NEWS index ba93bba290..c602166397 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2275,7 +2275,12 @@ having those two commands on the 'M-o' keymap; see the next section. ** The 'M-o M-s' and 'M-o M-S' global bindings have been removed. Use 'M-x center-line' and 'M-x center-paragraph' instead. See the -previous section for how to get back the old bindings. +previous section for how to get back the old bindings. Alternatively, +if you only want these two commands to have global bindings they had +before, you can add the following to your init file: + + (define-key global-map "\M-o\M-s" 'center-line) + (define-key global-map "\M-o\M-S" 'center-paragraph) ** The 'M-o M-o' global binding has been removed. Use 'M-x font-lock-fontify-block' instead, or the new 'C-x x f' commit a9e7ea47b984e6d1de33eb34696e7fcf27622de4 Author: Eli Zaretskii Date: Sat Mar 20 11:08:25 2021 +0200 ; Improve a recent change in NEWS * etc/NEWS: Enhance the description of how to get the old bindings removed with the 'M-o' keymap. diff --git a/etc/NEWS b/etc/NEWS index 842f660048..ba93bba290 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2267,9 +2267,15 @@ To restore the old binding, say something like: (require 'facemenu) (define-key global-map "\M-o" 'facemenu-keymap) + (define-key facemenu-keymap "\es" 'center-line) + (define-key facemenu-keymap "\eS" 'center-paragraph) + +The last two lines are not strictly necessary if you don't care about +having those two commands on the 'M-o' keymap; see the next section. ** The 'M-o M-s' and 'M-o M-S' global bindings have been removed. -Use 'M-x center-line' and 'M-x center-paragraph' instead. +Use 'M-x center-line' and 'M-x center-paragraph' instead. See the +previous section for how to get back the old bindings. ** The 'M-o M-o' global binding has been removed. Use 'M-x font-lock-fontify-block' instead, or the new 'C-x x f' commit e33c2bfbf3f62449a9b62de423a1bbe3a39a3dca Author: Toby Cubitt Date: Sat Mar 20 10:01:13 2021 +0100 Fix cl-progv binding order * lisp/emacs-lisp/cl-macs.el (cl-progv): Bind variables in the correct order (bug#47272). diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 9eabfc63b4..27ed07b667 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -1976,7 +1976,8 @@ a `let' form, except that the list of symbols can be computed at run-time." (,binds ())) (while ,syms (push (list (pop ,syms) (list 'quote (pop ,vals))) ,binds)) - (eval (list 'let ,binds (list 'funcall (list 'quote ,bodyfun)))))))) + (eval (list 'let (nreverse ,binds) + (list 'funcall (list 'quote ,bodyfun)))))))) (defconst cl--labels-magic (make-symbol "cl--labels-magic")) diff --git a/test/lisp/emacs-lisp/cl-macs-tests.el b/test/lisp/emacs-lisp/cl-macs-tests.el index df1d26a074..dd6487603d 100644 --- a/test/lisp/emacs-lisp/cl-macs-tests.el +++ b/test/lisp/emacs-lisp/cl-macs-tests.el @@ -648,4 +648,9 @@ collection clause." #'len)) (`(function (lambda (,_ ,_) . ,_)) t)))) +(ert-deftest cl-macs--progv () + (should (= (cl-progv '(test test) '(1 2) test) 2)) + (should (equal (cl-progv '(test1 test2) '(1 2) (list test1 test2)) + '(1 2)))) + ;;; cl-macs-tests.el ends here commit f85b66d9b02ed440fc08e5c4dc987bbff9be97d6 Author: Gregory Heytings Date: Sat Mar 20 08:54:07 2021 +0100 * etc/NEWS: Small corrections for the new command 'font-lock-update' diff --git a/etc/NEWS b/etc/NEWS index fb8fa322a1..842f660048 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -254,8 +254,8 @@ search buffer due to too many matches being highlighted. The 'C-x x' keymap now holds keystrokes for various buffer-oriented commands. The new keystrokes are 'C-x x g' ('revert-buffer'), 'C-x x r' ('rename-buffer'), 'C-x x u' ('rename-uniquely'), 'C-x x n' -('clone-buffer'), 'C-x x i' ('insert-buffer') and 'C-x x t' -('toggle-truncate-lines'). +('clone-buffer'), 'C-x x i' ('insert-buffer'), 'C-x x t' +('toggle-truncate-lines') and 'C-x x f' ('font-lock-update'). --- ** Commands 'set-frame-width' and 'set-frame-height' can now get their @@ -2273,7 +2273,7 @@ Use 'M-x center-line' and 'M-x center-paragraph' instead. ** The 'M-o M-o' global binding has been removed. Use 'M-x font-lock-fontify-block' instead, or the new 'C-x x f' -command, which toggles fontification in the current buffer. +command, which updates the syntax highlighting in the current buffer. ** In 'f90-mode', the backslash character ('\') no longer escapes. For about a decade, the backslash character has no longer had a commit 1f63f704d18b1c62be6e990bde3864da2bdfe3b5 Author: Stefan Kangas Date: Sat Mar 20 09:58:02 2021 +0100 Remove Gnus specific .dir-locals.el * lisp/gnus/.dir-locals.el: Delete file. The only variable it set was 'show-trailing-whitespace', but this should be up to the individual developer. (Bug#47278) diff --git a/lisp/gnus/.dir-locals.el b/lisp/gnus/.dir-locals.el deleted file mode 100644 index fb968e13a3..0000000000 --- a/lisp/gnus/.dir-locals.el +++ /dev/null @@ -1,4 +0,0 @@ -((emacs-lisp-mode . ((show-trailing-whitespace . t)))) -;; Local Variables: -;; no-byte-compile: t -;; End: commit 990e748cd0354dc905bc27b7f0052850002ef98b Author: Stefan Kangas Date: Sat Mar 20 07:48:51 2021 +0100 Prefer https and fix broken links in ERC * lisp/erc/erc-button.el (erc-button-rfc-url) (erc-button-search-url): Prefer https. * lisp/erc/erc-capab.el: * lisp/erc/erc.el (erc-cmd-MODE): Fix broken links. diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el index 8b13d1cf49..044776c236 100644 --- a/lisp/erc/erc-button.el +++ b/lisp/erc/erc-button.el @@ -105,18 +105,19 @@ longer than `erc-fill-column'." "Flag indicating whether nicks should be buttonized or not." :type 'boolean) -(defcustom erc-button-rfc-url "http://www.faqs.org/rfcs/rfc%s.html" - "URL used to browse rfc references. +(defcustom erc-button-rfc-url "https://tools.ietf.org/html/rfc%s" + "URL used to browse RFC references. %s is replaced by the number." - :type 'string) + :type 'string + :version "28.1") (define-obsolete-variable-alias 'erc-button-google-url 'erc-button-search-url "27.1") -(defcustom erc-button-search-url "http://duckduckgo.com/?q=%s" +(defcustom erc-button-search-url "https://duckduckgo.com/?q=%s" "URL used to search for a term. %s is replaced by the search string." - :version "27.1" + :version "28.1" :type 'string) (defcustom erc-button-alist diff --git a/lisp/erc/erc-capab.el b/lisp/erc/erc-capab.el index 2028917da0..19bc2dbb8e 100644 --- a/lisp/erc/erc-capab.el +++ b/lisp/erc/erc-capab.el @@ -40,8 +40,8 @@ ;; disable this module, it will continue removing message flags, but the ;; unidentified nickname prefix will not be added to messages. -;; Visit and -;; to find further +;; Visit and +;; to find further ;; explanations of this capability. ;; From freenode.net's web site (not there anymore) on how to mark diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index bdb1914d7b..b6dea95bb2 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -3389,7 +3389,7 @@ to send. If only one word is given, display the mode of that target. A list of valid mode strings for Freenode may be found at -URL `http://freenode.net/using_the_network.shtml'." +URL `https://freenode.net/kb/all'." (cond ((string-match "^\\s-\\(.*\\)$" line) (let ((s (match-string 1 line))) commit f6d7e2e8f9a28ae545f4d8a48df103488b297226 Author: Stefan Kangas Date: Sat Mar 20 05:12:18 2021 +0100 * lisp/thumbs.el (thumbs-show-from-dir): Improve prompt. diff --git a/lisp/thumbs.el b/lisp/thumbs.el index 8d79ceda5b..e43d13d703 100644 --- a/lisp/thumbs.el +++ b/lisp/thumbs.el @@ -376,7 +376,7 @@ If MARKED is non-nil, the image is marked." "Make a preview buffer for all images in DIR. Optional argument REG to select file matching a regexp, and SAME-WINDOW to show thumbs in the same window." - (interactive "DDir: ") + (interactive "DThumbs (directory): ") (thumbs-show-thumbs-list (directory-files dir t (or reg (image-file-name-regexp))) dir same-window)) commit 729eae14eb648ad508b7963899d441c3e72fafea Author: Eli Zaretskii Date: Sat Mar 20 10:48:07 2021 +0200 Fix args-out-of-range error in format.el * lisp/format.el (format-deannotate-region): Ignore todo items with FROM > TO. (Bug#47277) diff --git a/lisp/format.el b/lisp/format.el index 4209fc6401..3e2d92fef1 100644 --- a/lisp/format.el +++ b/lisp/format.el @@ -747,13 +747,17 @@ to write these unknown annotations back into the file." (if (numberp val) ; add to ambient value if numeric (format-property-increment-region from to prop val 0) - (put-text-property - from to prop - (cond ((get prop 'format-list-valued) ; value gets consed onto - ; list-valued properties - (let ((prev (get-text-property from prop))) - (cons val (if (listp prev) prev (list prev))))) - (t val))))) ; normally, just set to val. + ;; Kludge alert: ignore items with reversed order of + ;; FROM and TO. They seem to be redundant anyway, and + ;; in one case I've seen them refer to EOB. + (when (<= from to) + (put-text-property + from to prop + (cond ((get prop 'format-list-valued) ; value gets consed onto + ; list-valued properties + (let ((prev (get-text-property from prop))) + (cons val (if (listp prev) prev (list prev))))) + (t val)))))) ; normally, just set to val. (setq todo (cdr todo))) (if unknown-ans commit 31544bc908d35bff513450bc4bea1d0283a7ddb0 Author: Paul Eggert Date: Fri Mar 19 17:47:24 2021 -0700 Don’t convert pointer to bool Without this patch, Oracle Studio 12.6 complains about converting pointer to bool. * src/editfns.c (styled_format): Use !!. diff --git a/src/editfns.c b/src/editfns.c index bc6553a7d2..87e743afc3 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -3138,7 +3138,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) char *format_start = SSDATA (args[0]); bool multibyte_format = STRING_MULTIBYTE (args[0]); ptrdiff_t formatlen = SBYTES (args[0]); - bool fmt_props = string_intervals (args[0]); + bool fmt_props = !!string_intervals (args[0]); /* Upper bound on number of format specs. Each uses at least 2 chars. */ ptrdiff_t nspec_bound = SCHARS (args[0]) >> 1; commit 0eeb865aae3373343c18b7674fde91f280edafef Author: Stefan Kangas Date: Sat Mar 20 01:16:26 2021 +0100 Assume something more recent than X11R6 * lisp/bindings.el: * lisp/menu-bar.el: * lisp/printing.el: * lisp/thumbs.el (thumbs-conversion-program): Assume we have something more recent than X11R6. diff --git a/lisp/bindings.el b/lisp/bindings.el index a502373997..6eac528eb6 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -1211,7 +1211,7 @@ if `inhibit-field-text-motion' is non-nil." ;; (define-key global-map [kp-9] 'function-key-error) ;; (define-key global-map [kp-equal] 'function-key-error) -;; X11R6 distinguishes these keys from the non-kp keys. +;; X11 distinguishes these keys from the non-kp keys. ;; Make them behave like the non-kp keys unless otherwise bound. ;; FIXME: rather than list such mappings for every modifier-combination, ;; we should come up with a way to do it generically, something like diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index 133df65cbc..e6cce59343 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -604,7 +604,7 @@ Do the same for the keys of the same name." (define-key global-map [f20] 'clipboard-kill-region) (define-key global-map [f16] 'clipboard-kill-ring-save) (define-key global-map [f18] 'clipboard-yank) - ;; X11R6 versions: + ;; X11 versions: (define-key global-map [cut] 'clipboard-kill-region) (define-key global-map [copy] 'clipboard-kill-ring-save) (define-key global-map [paste] 'clipboard-yank)) diff --git a/lisp/printing.el b/lisp/printing.el index f6b9494e17..f5d3c82ae9 100644 --- a/lisp/printing.el +++ b/lisp/printing.el @@ -103,14 +103,14 @@ Please send all bug fixes and enhancements to ;; For example, after previewing a PostScript file, *Printing Command Output* ;; will have the following entry: ;; -;; /usr/X11R6/bin/gv ("/home/user/example/file.ps") +;; /usr/bin/gv ("/home/user/example/file.ps") ;; Exit status: 0 ;; ;; In the example above, the previewing was successful. If during previewing, ;; you quit gv execution (by typing C-g during Emacs session), the log entry ;; would be: ;; -;; /usr/X11R6/bin/gv ("/home/user/example/file.ps") +;; /usr/bin/gv ("/home/user/example/file.ps") ;; Exit status: Quit ;; ;; So, if something goes wrong, a good place to take a look is the buffer diff --git a/lisp/thumbs.el b/lisp/thumbs.el index c6a9a67b3f..8d79ceda5b 100644 --- a/lisp/thumbs.el +++ b/lisp/thumbs.el @@ -95,10 +95,11 @@ When it reaches that size (in bytes), a warning is sent." (if (eq system-type 'windows-nt) "convert.exe" (or (executable-find "convert") - "/usr/X11R6/bin/convert")) + "/usr/bin/convert")) "Name of conversion program for thumbnails generation. It must be \"convert\"." - :type 'string) + :type 'string + :version "28.1") (defcustom thumbs-setroot-command "xloadimage -onroot -fullscreen *" commit 7607d1c4e854cf55701aef3446092d3f510697ce Author: Stefan Kangas Date: Sat Mar 20 01:10:37 2021 +0100 Use lexical-binding in thumbs.el * lisp/thumbs.el: Use lexical-binding. Remove redundant :group args. * test/lisp/thumbs-tests.el: New file. diff --git a/lisp/thumbs.el b/lisp/thumbs.el index 957940bfe0..c6a9a67b3f 100644 --- a/lisp/thumbs.el +++ b/lisp/thumbs.el @@ -1,4 +1,4 @@ -;;; thumbs.el --- Thumbnails previewer for images files +;;; thumbs.el --- Thumbnails previewer for images files -*- lexical-binding: t -*- ;; Copyright (C) 2004-2021 Free Software Foundation, Inc. @@ -23,7 +23,7 @@ ;;; Commentary: -;; This package create two new modes: thumbs-mode and thumbs-view-image-mode. +;; This package create two new modes: `thumbs-mode' and `thumbs-view-image-mode'. ;; It is used for basic browsing and viewing of images from within Emacs. ;; Minimal image manipulation functions are also available via external ;; programs. If you want to do more complex tasks like categorize and tag @@ -34,7 +34,7 @@ ;; ;; Thanks: Alex Schroeder for maintaining the package at some ;; time. The peoples at #emacs@freenode.net for numerous help. RMS -;; for emacs and the GNU project. +;; for Emacs and the GNU project. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -68,29 +68,24 @@ (defcustom thumbs-thumbsdir (locate-user-emacs-file "thumbs") "Directory to store thumbnails." - :type 'directory - :group 'thumbs) + :type 'directory) (defcustom thumbs-geometry "100x100" "Size of thumbnails." - :type 'string - :group 'thumbs) + :type 'string) (defcustom thumbs-per-line 4 "Number of thumbnails per line to show in directory." - :type 'integer - :group 'thumbs) + :type 'integer) (defcustom thumbs-max-image-number 16 "Maximum number of images initially displayed in thumbs buffer." - :type 'integer - :group 'thumbs) + :type 'integer) (defcustom thumbs-thumbsdir-max-size 50000000 "Maximum size for thumbnails directory. When it reaches that size (in bytes), a warning is sent." - :type 'integer - :group 'thumbs) + :type 'integer) ;; Unfortunately Windows XP has a program called CONVERT.EXE in ;; C:/WINDOWS/SYSTEM32/ for partitioning NTFS systems. So Emacs @@ -103,49 +98,41 @@ When it reaches that size (in bytes), a warning is sent." "/usr/X11R6/bin/convert")) "Name of conversion program for thumbnails generation. It must be \"convert\"." - :type 'string - :group 'thumbs) + :type 'string) (defcustom thumbs-setroot-command "xloadimage -onroot -fullscreen *" "Command to set the root window." - :type 'string - :group 'thumbs) + :type 'string) (defcustom thumbs-relief 5 "Size of button-like border around thumbnails." - :type 'integer - :group 'thumbs) + :type 'integer) (defcustom thumbs-margin 2 "Size of the margin around thumbnails. This is where you see the cursor." - :type 'integer - :group 'thumbs) + :type 'integer) (defcustom thumbs-thumbsdir-auto-clean t "If set, delete older file in the thumbnails directory. Deletion is done at load time when the directory size is bigger than `thumbs-thumbsdir-max-size'." - :type 'boolean - :group 'thumbs) + :type 'boolean) (defcustom thumbs-image-resizing-step 10 "Step by which to resize image as a percentage." - :type 'integer - :group 'thumbs) + :type 'integer) (defcustom thumbs-temp-dir temporary-file-directory "Temporary directory to use. Defaults to `temporary-file-directory'. Leaving it to this value can let another user see some of your images." - :type 'directory - :group 'thumbs) + :type 'directory) (defcustom thumbs-temp-prefix "emacsthumbs" "Prefix to add to temp files." - :type 'string - :group 'thumbs) + :type 'string) ;; Initialize some variable, for later use. (defvar-local thumbs-current-tmp-filename nil @@ -210,7 +197,7 @@ reached." ,f))) (directory-files (thumbs-thumbsdir) t (image-file-name-regexp))) (lambda (l1 l2) (time-less-p (car l1) (car l2))))) - (dirsize (apply '+ (mapcar (lambda (x) (cadr x)) files-list)))) + (dirsize (apply #'+ (mapcar (lambda (x) (cadr x)) files-list)))) (while (> dirsize thumbs-thumbsdir-max-size) (progn (message "Deleting file %s" (cadr (cdar files-list)))) @@ -290,7 +277,7 @@ smaller according to whether INCREMENT is 1 or -1." (subst-char-in-string ?\s ?\_ (apply - 'concat + #'concat (split-string filename "/"))))))) (defun thumbs-make-thumb (img) @@ -618,7 +605,7 @@ Open another window." (when (eolp) (forward-char))) ;; cleaning of old temp files -(mapc 'delete-file +(mapc #'delete-file (directory-files (thumbs-temp-dir) t thumbs-temp-prefix)) ;; Image modification routines diff --git a/test/lisp/thumbs-tests.el b/test/lisp/thumbs-tests.el new file mode 100644 index 0000000000..ee09613845 --- /dev/null +++ b/test/lisp/thumbs-tests.el @@ -0,0 +1,34 @@ +;;; thumbs-tests.el --- tests for thumbs.el -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Code: + +(require 'ert) +(require 'thumbs) + +(ert-deftest thumbs-tests-thumbsdir/create-if-missing () + (let ((thumbs-thumbsdir (make-temp-file "thumbs-test" t))) + (unwind-protect + (progn + (delete-directory thumbs-thumbsdir) + (should (file-directory-p (thumbs-thumbsdir)))) + (delete-directory thumbs-thumbsdir)))) + +(provide 'thumbs-tests) +;;; thumbs-tests.el ends here commit 26dc070fa947d2f60a932e02167b4bdfd464939e Author: Stefan Kangas Date: Sat Mar 20 00:12:38 2021 +0100 * lisp/novice.el: Use lexical-binding. diff --git a/lisp/novice.el b/lisp/novice.el index 22eca21784..16766c253c 100644 --- a/lisp/novice.el +++ b/lisp/novice.el @@ -1,4 +1,4 @@ -;;; novice.el --- handling of disabled commands ("novice mode") for Emacs +;;; novice.el --- handling of disabled commands ("novice mode") for Emacs -*- lexical-binding: t -*- ;; Copyright (C) 1985-1987, 1994, 2001-2021 Free Software Foundation, ;; Inc. commit 64f37487e2e7f71701451097e16bcb910f5f91fd Author: Stefan Monnier Date: Fri Mar 19 19:04:27 2021 -0400 * lisp/wdired.el: Use lexical-binding Remove redundant `:group` args. (wdired-change-to-wdired-mode): Use `add-function` to modify `revert-buffer-function`. (wdired-change-to-dired-mode): Adjust accordingly. (wdired-do-renames): Make sure to bind `dired-backup-overwrite` dynamically. diff --git a/lisp/wdired.el b/lisp/wdired.el index c495d8de34..e040b52600 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -1,4 +1,4 @@ -;;; wdired.el --- Rename files editing their names in dired buffers -*- coding: utf-8; -*- +;;; wdired.el --- Rename files editing their names in dired buffers -*- coding: utf-8; lexical-binding: t; -*- ;; Copyright (C) 2004-2021 Free Software Foundation, Inc. @@ -85,15 +85,13 @@ If nil, WDired doesn't require confirmation to change the file names, and the variable `wdired-confirm-overwrite' controls whether it is ok to overwrite files without asking." - :type 'boolean - :group 'wdired) + :type 'boolean) (defcustom wdired-confirm-overwrite t "If nil the renames can overwrite files without asking. This variable has no effect at all if `wdired-use-interactive-rename' is not nil." - :type 'boolean - :group 'wdired) + :type 'boolean) (defcustom wdired-use-dired-vertical-movement nil "If t, the \"up\" and \"down\" movement works as in Dired mode. @@ -106,15 +104,13 @@ when editing several filenames. If nil, \"up\" and \"down\" movement is done as in any other buffer." :type '(choice (const :tag "As in any other mode" nil) (const :tag "Smart cursor placement" sometimes) - (other :tag "As in dired mode" t)) - :group 'wdired) + (other :tag "As in dired mode" t))) (defcustom wdired-allow-to-redirect-links t "If non-nil, the target of the symbolic links are editable. In systems without symbolic links support, this variable has no effect at all." - :type 'boolean - :group 'wdired) + :type 'boolean) (defcustom wdired-allow-to-change-permissions nil "If non-nil, the permissions bits of the files are editable. @@ -135,8 +131,7 @@ Anyway, the real change of the permissions is done by the external program `dired-chmod-program', which must exist." :type '(choice (const :tag "Not allowed" nil) (const :tag "Toggle/set bits" t) - (other :tag "Bits freely editable" advanced)) - :group 'wdired) + (other :tag "Bits freely editable" advanced))) (defcustom wdired-keep-marker-rename t ;; Use t as default so that renamed files "take their markers with them". @@ -149,8 +144,7 @@ See `dired-keep-marker-rename' if you want to do the same for files renamed by `dired-do-rename' and `dired-do-rename-regexp'." :type '(choice (const :tag "Keep" t) (character :tag "Mark" :value ?R)) - :version "24.3" - :group 'wdired) + :version "24.3") (defcustom wdired-create-parent-directories t "If non-nil, create parent directories of destination files. @@ -159,26 +153,25 @@ nonexistent directory, wdired will create any parent directories necessary. When nil, attempts to rename a file into a nonexistent directory will fail." :version "26.1" - :type 'boolean - :group 'wdired) + :type 'boolean) (defvar wdired-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\C-x\C-s" 'wdired-finish-edit) - (define-key map "\C-c\C-c" 'wdired-finish-edit) - (define-key map "\C-c\C-k" 'wdired-abort-changes) - (define-key map "\C-c\C-[" 'wdired-abort-changes) - (define-key map "\C-x\C-q" 'wdired-exit) - (define-key map "\C-m" 'undefined) - (define-key map "\C-j" 'undefined) - (define-key map "\C-o" 'undefined) - (define-key map [up] 'wdired-previous-line) - (define-key map "\C-p" 'wdired-previous-line) - (define-key map [down] 'wdired-next-line) - (define-key map "\C-n" 'wdired-next-line) - (define-key map [remap upcase-word] 'wdired-upcase-word) - (define-key map [remap capitalize-word] 'wdired-capitalize-word) - (define-key map [remap downcase-word] 'wdired-downcase-word) + (define-key map "\C-x\C-s" #'wdired-finish-edit) + (define-key map "\C-c\C-c" #'wdired-finish-edit) + (define-key map "\C-c\C-k" #'wdired-abort-changes) + (define-key map "\C-c\C-[" #'wdired-abort-changes) + (define-key map "\C-x\C-q" #'wdired-exit) + (define-key map "\C-m" #'undefined) + (define-key map "\C-j" #'undefined) + (define-key map "\C-o" #'undefined) + (define-key map [up] #'wdired-previous-line) + (define-key map "\C-p" #'wdired-previous-line) + (define-key map [down] #'wdired-next-line) + (define-key map "\C-n" #'wdired-next-line) + (define-key map [remap upcase-word] #'wdired-upcase-word) + (define-key map [remap capitalize-word] #'wdired-capitalize-word) + (define-key map [remap downcase-word] #'wdired-downcase-word) map) "Keymap used in `wdired-mode'.") @@ -249,11 +242,11 @@ See `wdired-mode'." (force-mode-line-update) (setq buffer-read-only nil) (dired-unadvertise default-directory) - (add-hook 'kill-buffer-hook 'wdired-check-kill-buffer nil t) - (add-hook 'after-change-functions 'wdired--restore-properties nil t) + (add-hook 'kill-buffer-hook #'wdired-check-kill-buffer nil t) + (add-hook 'after-change-functions #'wdired--restore-properties nil t) (setq major-mode 'wdired-mode) (setq mode-name "Editable Dired") - (setq revert-buffer-function 'wdired-revert) + (add-function :override (local revert-buffer-function) #'wdired-revert) ;; I temp disable undo for performance: since I'm going to clear the ;; undo list, it can save more than a 9% of time with big ;; directories because setting properties modify the undo-list. @@ -386,10 +379,9 @@ non-nil means return old filename." (setq major-mode 'dired-mode) (setq mode-name "Dired") (dired-advertise) - (remove-hook 'kill-buffer-hook 'wdired-check-kill-buffer t) - (remove-hook 'after-change-functions 'wdired--restore-properties t) - (setq-local revert-buffer-function 'dired-revert)) - + (remove-hook 'kill-buffer-hook #'wdired-check-kill-buffer t) + (remove-hook 'after-change-functions #'wdired--restore-properties t) + (remove-function (local revert-buffer-function) #'wdired-revert)) (defun wdired-abort-changes () "Abort changes and return to dired mode." @@ -537,7 +529,7 @@ non-nil means return old filename." ;; So we must ensure dired-aux is loaded. (require 'dired-aux) (condition-case err - (let ((dired-backup-overwrite nil)) + (dlet ((dired-backup-overwrite nil)) (and wdired-create-parent-directories (wdired-create-parentdirs file-new)) (dired-rename-file file-ori file-new @@ -814,18 +806,18 @@ Like original function but it skips read-only words." (defvar wdired-perm-mode-map (let ((map (make-sparse-keymap))) - (define-key map " " 'wdired-toggle-bit) - (define-key map "r" 'wdired-set-bit) - (define-key map "w" 'wdired-set-bit) - (define-key map "x" 'wdired-set-bit) - (define-key map "-" 'wdired-set-bit) - (define-key map "S" 'wdired-set-bit) - (define-key map "s" 'wdired-set-bit) - (define-key map "T" 'wdired-set-bit) - (define-key map "t" 'wdired-set-bit) - (define-key map "s" 'wdired-set-bit) - (define-key map "l" 'wdired-set-bit) - (define-key map [down-mouse-1] 'wdired-mouse-toggle-bit) + (define-key map " " #'wdired-toggle-bit) + (define-key map "r" #'wdired-set-bit) + (define-key map "w" #'wdired-set-bit) + (define-key map "x" #'wdired-set-bit) + (define-key map "-" #'wdired-set-bit) + (define-key map "S" #'wdired-set-bit) + (define-key map "s" #'wdired-set-bit) + (define-key map "T" #'wdired-set-bit) + (define-key map "t" #'wdired-set-bit) + (define-key map "s" #'wdired-set-bit) + (define-key map "l" #'wdired-set-bit) + (define-key map [mouse-1] #'wdired-mouse-toggle-bit) map)) ;; Put a keymap property to the permission bits of the files, and store the commit 115c7bcfc6b297e3da1c358c841dc68d6c7aa23a Author: Stefan Kangas Date: Fri Mar 19 23:59:47 2021 +0100 Don't tag mouse command as mode exclusive * lisp/finder.el (finder-mouse-select): Don't tag for finder-mode. diff --git a/lisp/finder.el b/lisp/finder.el index 343739f903..c2d5806c0c 100644 --- a/lisp/finder.el +++ b/lisp/finder.el @@ -423,7 +423,7 @@ FILE should be in a form suitable for passing to `locate-library'." (defun finder-mouse-select (event) "Select item in a Finder buffer with the mouse." - (interactive "e" finder-mode) + (interactive "e") (with-current-buffer (window-buffer (posn-window (event-start event))) (goto-char (posn-point (event-start event))) (finder-select))) commit bf210251eadafafd1bf4176127b872030405baa3 Author: Stefan Monnier Date: Fri Mar 19 18:33:38 2021 -0400 * lisp/emacs-lisp/bytecomp.el: Remember location of unresolved calls I've gotten tired of seeing the "function foo not known to be defined" warning without any line number information. So this patch adds as line number the position of the first use of that function in the file (well, approximately, as usual). (byte-compile-unresolved-functions): Add POSITIONs in the alist. (byte-compile-function-warn): Store the current position in `byte-compile-unresolved-functions`. (byte-compile-arglist-warn): Adjust accordingly. (byte-compile-print-syms): Delete unused function. (byte-compile-warn-about-unresolved-functions): Use the stored position to give more precise warnings. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 74eb5b0377..0babbbb978 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -548,6 +548,10 @@ has the form (autoload . FILENAME).") (defvar byte-compile-unresolved-functions nil "Alist of undefined functions to which calls have been compiled. +Each element in the list has the form (FUNCTION POSITION . CALLS) +where CALLS is a list whose elements are integers (indicating the +number of arguments passed in the function call) or the constant `t' +if the function is called indirectly. This variable is only significant whilst compiling an entire buffer. Used for warnings when a function is not known to be defined or is later defined with incorrect args.") @@ -1423,9 +1427,9 @@ when printing the error message." ;; Remember number of args in call. (let ((cons (assq f byte-compile-unresolved-functions))) (if cons - (or (memq nargs (cdr cons)) - (push nargs (cdr cons))) - (push (list f nargs) + (or (memq nargs (cddr cons)) + (push nargs (cddr cons))) + (push (list f byte-compile-last-position nargs) byte-compile-unresolved-functions))))) ;; Warn if the form is calling a function with the wrong number of arguments. @@ -1525,14 +1529,14 @@ extra args." (setq byte-compile-unresolved-functions (delq calls byte-compile-unresolved-functions)) (setq calls (delq t calls)) ;Ignore higher-order uses of the function. - (when (cdr calls) + (when (cddr calls) (when (and (symbolp name) (eq (function-get name 'byte-optimizer) 'byte-compile-inline-expand)) (byte-compile-warn "defsubst `%s' was used before it was defined" name)) (setq sig (byte-compile-arglist-signature arglist) - nums (sort (copy-sequence (cdr calls)) (function <)) + nums (sort (copy-sequence (cddr calls)) (function <)) min (car nums) max (car (nreverse nums))) (when (or (< min (car sig)) @@ -1640,56 +1644,21 @@ It is too wide if it has any lines longer than the largest of kind name col)))) form) -(defun byte-compile-print-syms (str1 strn syms) - (when syms - (byte-compile-set-symbol-position (car syms) t)) - (cond ((and (cdr syms) (not noninteractive)) - (let* ((str strn) - (L (length str)) - s) - (while syms - (setq s (symbol-name (pop syms)) - L (+ L (length s) 2)) - (if (< L (1- (buffer-local-value 'fill-column - (or (get-buffer - byte-compile-log-buffer) - (current-buffer))))) - (setq str (concat str " " s (and syms ","))) - (setq str (concat str "\n " s (and syms ",")) - L (+ (length s) 4)))) - (byte-compile-warn "%s" str))) - ((cdr syms) - (byte-compile-warn "%s %s" - strn - (mapconcat #'symbol-name syms ", "))) - - (syms - (byte-compile-warn str1 (car syms))))) - ;; If we have compiled any calls to functions which are not known to be ;; defined, issue a warning enumerating them. ;; `unresolved' in the list `byte-compile-warnings' disables this. (defun byte-compile-warn-about-unresolved-functions () (when (byte-compile-warning-enabled-p 'unresolved) - (let ((byte-compile-current-form :end) - (noruntime nil) - (unresolved nil)) + (let ((byte-compile-current-form :end)) ;; Separate the functions that will not be available at runtime ;; from the truly unresolved ones. - (dolist (f byte-compile-unresolved-functions) - (setq f (car f)) - (when (not (memq f byte-compile-new-defuns)) - (if (fboundp f) (push f noruntime) (push f unresolved)))) - ;; Complain about the no-run-time functions - (byte-compile-print-syms - "the function `%s' might not be defined at runtime." - "the following functions might not be defined at runtime:" - noruntime) - ;; Complain about the unresolved functions - (byte-compile-print-syms - "the function `%s' is not known to be defined." - "the following functions are not known to be defined:" - unresolved))) + (dolist (urf byte-compile-unresolved-functions) + (let ((f (car urf))) + (when (not (memq f byte-compile-new-defuns)) + (let ((byte-compile-last-position (cadr urf))) + (byte-compile-warn + (if (fboundp f) "the function `%s' might not be defined at runtime." "the function `%s' is not known to be defined.") + (car urf)))))))) nil) @@ -4912,10 +4881,10 @@ binding slots have been popped." (byte-compile-push-constant op) (byte-compile-form fun) (byte-compile-form prop) - (let* ((fun (eval fun)) - (prop (eval prop)) + (let* ((fun (eval fun t)) + (prop (eval prop t)) (val (if (macroexp-const-p val) - (eval val) + (eval val t) (byte-compile-lambda (cadr val))))) (push `(,fun . (,prop ,val ,@(alist-get fun overriding-plist-environment))) commit 937b6c18bd6c4806eb1e4c8764db56b314c09056 Author: Stefan Monnier Date: Fri Mar 19 17:42:22 2021 -0400 * lisp/emacs-lisp/pcase.el (pcase-compile-patterns): New function (bug#47261) Extracted from `pcase--expand`. (pcase--expand): Use it. diff --git a/etc/NEWS b/etc/NEWS index 6dda3423c1..fb8fa322a1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -433,6 +433,9 @@ to nil. This was already sometimes the case, but it is now guaranteed. This is like '(pred (lambda (x) (not (FUN x))))' but results in better code. +--- +*** New function 'pcase-compile-patterns' to write other macros. + +++ ** profiler.el The results displayed by 'profiler-report' now have the usage figures diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 5342a0179d..006517db75 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -207,6 +207,7 @@ If EXP fails to match any of the patterns in CASES, an error is signaled." (pcase--dontwarn-upats (cons x pcase--dontwarn-upats))) (pcase--expand ;; FIXME: Could we add the FILE:LINE data in the error message? + ;; FILE is available from `macroexp-file-name'. exp (append cases `((,x (error "No clause matching `%S'" ,x))))))) ;;;###autoload @@ -320,34 +321,46 @@ of the elements of LIST is performed as if by `pcase-let'. (defun pcase--trivial-upat-p (upat) (and (symbolp upat) (not (memq upat pcase--dontcare-upats)))) -(defun pcase--expand (exp cases) - ;; (message "pid=%S (pcase--expand %S ...hash=%S)" - ;; (emacs-pid) exp (sxhash cases)) +(defun pcase-compile-patterns (exp cases) + "Compile the set of patterns in CASES. +EXP is the expression that will be matched against the patterns. +CASES is a list of elements (PAT . CODEGEN) +where CODEGEN is a function that returns the code to use when +PAT matches. That code has to be in the form of a cons cell. + +CODEGEN will be called with at least 2 arguments, VARVALS and COUNT. +VARVALS is a list of elements of the form (VAR VAL . RESERVED) where VAR +is a variable bound by the pattern and VAL is a duplicable expression +that returns the value this variable should be bound to. +If the pattern PAT uses `or', CODEGEN may be called multiple times, +in which case it may want to generate the code differently to avoid +a potential code explosion. For this reason the COUNT argument indicates +how many time this CODEGEN is called." (macroexp-let2 macroexp-copyable-p val exp - (let* ((defs ()) - (seen '()) + (let* ((seen '()) + (phcounter 0) (main (pcase--u (mapcar (lambda (case) `(,(pcase--match val (pcase--macroexpand (car case))) ,(lambda (vars) - (let ((prev (assq case seen)) - (code (cdr case))) + (let ((prev (assq case seen))) (unless prev ;; Keep track of the cases that are used. (push (setq prev (list case)) seen)) - (if (member code '(nil (nil))) nil - ;; Put `code' in the cdr just so that not all - ;; branches look identical (to avoid things like - ;; `macroexp--if' optimizing them too optimistically). - (let ((ph (list 'pcase--placeholder code))) - (setcdr prev (cons (cons vars ph) (cdr prev))) - ph)))))) + ;; Put a counter in the cdr just so that not + ;; all branches look identical (to avoid things + ;; like `macroexp--if' optimizing them too + ;; optimistically). + (let ((ph (cons 'pcase--placeholder + (setq phcounter (1+ phcounter))))) + (setcdr prev (cons (cons vars ph) (cdr prev))) + ph))))) cases)))) ;; Take care of the place holders now. (dolist (branch seen) - (let ((code (cdar branch)) + (let ((codegen (cdar branch)) (uses (cdr branch))) ;; Find all the vars that are in scope (the union of the ;; vars provided in each use case). @@ -358,48 +371,74 @@ of the elements of LIST is performed as if by `pcase-let'. (if vi (if (cddr v) (setcdr vi 'used)) (push (cons (car v) (cddr v)) allvarinfo)))))) - (allvars (mapcar #'car allvarinfo)) - (ignores (mapcar (lambda (vi) (when (cdr vi) `(ignore ,(car vi)))) - allvarinfo))) - ;; Since we use a tree-based pattern matching - ;; technique, the leaves (the places that contain the - ;; code to run once a pattern is matched) can get - ;; copied a very large number of times, so to avoid - ;; code explosion, we need to keep track of how many - ;; times we've used each leaf and move it - ;; to a separate function if that number is too high. - (if (or (null (cdr uses)) (pcase--small-branch-p code)) - (dolist (use uses) - (let ((vars (car use)) - (placeholder (cdr use))) - ;; (cl-assert (eq (car placeholder) 'pcase--placeholder)) - (setcar placeholder 'let) - (setcdr placeholder - `(,(mapcar (lambda (v) (list v (cadr (assq v vars)))) - allvars) - ;; Try and silence some of the most common - ;; spurious "unused var" warnings. - ,@ignores - ,@code)))) - ;; Several occurrence of this non-small branch in the output. - (let ((bsym - (make-symbol (format "pcase-%d" (length defs))))) - (push `(,bsym (lambda ,allvars ,@ignores ,@code)) defs) - (dolist (use uses) - (let ((vars (car use)) - (placeholder (cdr use))) - ;; (cl-assert (eq (car placeholder) 'pcase--placeholder)) - (setcar placeholder 'funcall) - (setcdr placeholder - `(,bsym - ,@(mapcar (lambda (v) (cadr (assq v vars))) - allvars)))))))))) + (allvars (mapcar #'car allvarinfo))) + (dolist (use uses) + (let* ((vars (car use)) + (varvals + (mapcar (lambda (v) + `(,v ,(cadr (assq v vars)) + ,(cdr (assq v allvarinfo)))) + allvars)) + (placeholder (cdr use)) + (code (funcall codegen varvals (length uses)))) + ;; (cl-assert (eq (car placeholder) 'pcase--placeholder)) + (setcar placeholder (car code)) + (setcdr placeholder (cdr code))))))) (dolist (case cases) (unless (or (assq case seen) (memq (car case) pcase--dontwarn-upats)) - (message "pcase pattern %S shadowed by previous pcase pattern" - (car case)))) - (macroexp-let* defs main)))) + (setq main + (macroexp-warn-and-return + (format "pcase pattern %S shadowed by previous pcase pattern" + (car case)) + main)))) + main))) + +(defun pcase--expand (exp cases) + ;; (message "pid=%S (pcase--expand %S ...hash=%S)" + ;; (emacs-pid) exp (sxhash cases)) + (let* ((defs ()) + (codegen + (lambda (code) + (if (member code '(nil (nil) ('nil))) + (lambda (&rest _) ''nil) + (let ((bsym ())) + (lambda (varvals count &rest _) + (let* ((ignored-vars + (delq nil (mapcar (lambda (vv) (if (nth 2 vv) (car vv))) + varvals))) + (ignores (if ignored-vars + `((ignore . ,ignored-vars))))) + ;; Since we use a tree-based pattern matching + ;; technique, the leaves (the places that contain the + ;; code to run once a pattern is matched) can get + ;; copied a very large number of times, so to avoid + ;; code explosion, we need to keep track of how many + ;; times we've used each leaf and move it + ;; to a separate function if that number is too high. + (if (or (< count 2) (pcase--small-branch-p code)) + `(let ,(mapcar (lambda (vv) (list (car vv) (cadr vv))) + varvals) + ;; Try and silence some of the most common + ;; spurious "unused var" warnings. + ,@ignores + ,@code) + ;; Several occurrence of this non-small branch in + ;; the output. + (unless bsym + (setq bsym (make-symbol + (format "pcase-%d" (length defs)))) + (push `(,bsym (lambda ,(mapcar #'car varvals) + ,@ignores ,@code)) + defs)) + `(funcall ,bsym ,@(mapcar #'cadr varvals))))))))) + (main + (pcase-compile-patterns + exp + (mapcar (lambda (case) + (cons (car case) (funcall codegen (cdr case)))) + cases)))) + (macroexp-let* defs main))) (defun pcase--macroexpand (pat) "Expands all macro-patterns in PAT." commit 3af2cee64b86e4ce59adb8e8720d92db35039cbc Author: Eli Zaretskii Date: Fri Mar 19 14:46:15 2021 +0200 Improve the docs of a recent change in mb-depth.el * lisp/mb-depth.el (minibuffer-depth-indicator-function): Improve the wording of the doc string and of the label used for the default value. (Bug#47252) diff --git a/lisp/mb-depth.el b/lisp/mb-depth.el index 3cba6a41f2..88003afb40 100644 --- a/lisp/mb-depth.el +++ b/lisp/mb-depth.el @@ -31,11 +31,14 @@ ;;; Code: (defcustom minibuffer-depth-indicator-function nil - "If non-nil, function to set up the minibuffer depth indicator. -It is called with one argument, the minibuffer depth, -and must return a string." + "If non-nil, a function to produce the minibuffer depth indicator. +The function will be called with one argument, the minibuffer depth, +and must return a string to display as indication of the minibuffer +depth. +If nil, display the depth as a number inside brackets, [NN], with +the `minibuffer-depth-indicator' face." :version "28.1" - :type '(choice (const :tag "Default" nil) + :type '(choice (const :tag "Default indicator display, [NN]" nil) (function)) :group 'minibuffer) commit 1971a3185f6b3f7c6c627d1c8968bb09a834f9c1 Author: Mauro Aranda Date: Fri Mar 19 05:50:55 2021 -0300 Fix :type of recently introduced defcustom * lisp/mb-depth.el (minibuffer-depth-indicator-function): The option can be nil, so add nil as a choice. (Bug#47252) diff --git a/lisp/mb-depth.el b/lisp/mb-depth.el index f79b0f354e..3cba6a41f2 100644 --- a/lisp/mb-depth.el +++ b/lisp/mb-depth.el @@ -35,7 +35,8 @@ It is called with one argument, the minibuffer depth, and must return a string." :version "28.1" - :type 'function + :type '(choice (const :tag "Default" nil) + (function)) :group 'minibuffer) (defface minibuffer-depth-indicator '((t :inherit highlight)) commit 240708087513143f0fcdeb59431a0b6748a0bc9c Author: Gabriel do Nascimento Ribeiro Date: Fri Mar 19 09:37:55 2021 +0100 Make minibuffer-depth-indicator-function a defcustom * lisp/mb-depth.el (minibuffer-depth-indicator-function): Make into a user option (bug#47252). diff --git a/lisp/mb-depth.el b/lisp/mb-depth.el index f9a24e34bf..f79b0f354e 100644 --- a/lisp/mb-depth.el +++ b/lisp/mb-depth.el @@ -30,10 +30,13 @@ ;;; Code: -(defvar minibuffer-depth-indicator-function nil +(defcustom minibuffer-depth-indicator-function nil "If non-nil, function to set up the minibuffer depth indicator. It is called with one argument, the minibuffer depth, -and must return a string.") +and must return a string." + :version "28.1" + :type 'function + :group 'minibuffer) (defface minibuffer-depth-indicator '((t :inherit highlight)) "Face to use for minibuffer depth indicator." commit 2c3340909abd4f88be6ab814247a6dcd5da0a899 Author: Lars Ingebrigtsen Date: Fri Mar 19 08:58:32 2021 +0100 Warn the user if we can't find pkg-config * configure.ac (WITH_IFAVAILABLE): Warn the user if we can't find a usable pkg-config (bug#47159). diff --git a/configure.ac b/configure.ac index 1802c1baa1..2c62a9fe6f 100644 --- a/configure.ac +++ b/configure.ac @@ -3897,6 +3897,11 @@ case $with_json,$HAVE_JSON in WITH_IFAVAILABLE="$WITH_IFAVAILABLE --with-json=ifavailable";; esac if test "X${MISSING}" != X; then + # If we have a missing library, and we don't have pkg-config installed, + # the missing pkg-config may be the reason. Give the user a hint. + if test "X${PKG_CONFIG}" = X; then + AC_MSG_WARN([Unable to locate a usable pkg-config]) + fi AC_MSG_ERROR([The following required libraries were not found: $MISSING Maybe some development libraries/packages are missing? commit 04a90d76954901897f0a521552c448f1f4845461 Author: Lars Ingebrigtsen Date: Fri Mar 19 08:44:19 2021 +0100 Add a note to NEWS as to how to restore the facemenu diff --git a/etc/NEWS b/etc/NEWS index 7b7678280b..6dda3423c1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2260,6 +2260,10 @@ first). * Incompatible Editing Changes in Emacs 28.1 ** The 'M-o' ('facemenu-keymap') global binding has been removed. +To restore the old binding, say something like: + + (require 'facemenu) + (define-key global-map "\M-o" 'facemenu-keymap) ** The 'M-o M-s' and 'M-o M-S' global bindings have been removed. Use 'M-x center-line' and 'M-x center-paragraph' instead. commit deef5efafb70f4b171265b896505b92b6eef24e6 (tag: refs/tags/emacs-27.2-rc2, tag: refs/tags/emacs-27.2) Author: Eli Zaretskii Date: Fri Mar 19 03:16:54 2021 -0400 ; * ChangeLog.3: Update with the log of the last change. diff --git a/ChangeLog.3 b/ChangeLog.3 index ccc06b85f7..27537de4cf 100644 --- a/ChangeLog.3 +++ b/ChangeLog.3 @@ -2,6 +2,20 @@ * Version 27.2 released. +2021-03-18 Basil L. Contovounesios + + Fix 'frame-inner-height' in non-GUI builds + + Include tab bar in frame's inner height in non-GUI builds that + don't define 'tab-bar-height'. This is consistent with the + inclusion of the menu bar in the calculated height. It is also + consistent with TTY frames of GUI builds, for which + 'tab-bar-height' is always zero anyway (bug#47234). + Fix suggested by Eli Zaretskii . + + * lisp/frame.el (frame-inner-height): Don't assume + 'tab-bar-height' is defined in builds --without-x. + 2021-03-18 Eli Zaretskii * etc/HISTORY: Update for Emacs 27.2. commit b815445cea741a61cdab7f90bdf7a0ddc487fc5b Author: Stefan Monnier Date: Thu Mar 18 23:32:57 2021 -0400 Fix copyright lines mistakenly treated as outline headers * lisp/emacs-lisp/generator.el: * test/lisp/cedet/semantic-utest.el: * test/lisp/cedet/semantic/format-tests.el: * test/lisp/cedet/semantic/fw-tests.el: * test/lisp/cedet/semantic/bovine/gcc-tests.el: * test/lisp/cedet/semantic/format-resources/test-fmt.el: * test/manual/cedet/semantic-tests.el: * lisp/obsolete/inversion.el: Use only 2 semi-colons before "Copyright". diff --git a/lisp/emacs-lisp/generator.el b/lisp/emacs-lisp/generator.el index e45260c32a..4ae20ba420 100644 --- a/lisp/emacs-lisp/generator.el +++ b/lisp/emacs-lisp/generator.el @@ -1,6 +1,6 @@ ;;; generator.el --- generators -*- lexical-binding: t -*- -;;; Copyright (C) 2015-2021 Free Software Foundation, Inc. +;; Copyright (C) 2015-2021 Free Software Foundation, Inc. ;; Author: Daniel Colascione ;; Keywords: extensions, elisp diff --git a/lisp/obsolete/inversion.el b/lisp/obsolete/inversion.el index 192186ee3b..e61b36cd88 100644 --- a/lisp/obsolete/inversion.el +++ b/lisp/obsolete/inversion.el @@ -1,6 +1,6 @@ ;;; inversion.el --- When you need something in version XX.XX -*- lexical-binding: t; -*- -;;; Copyright (C) 2002-2003, 2005-2021 Free Software Foundation, Inc. +;; Copyright (C) 2002-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Version: 1.3 diff --git a/test/lisp/cedet/semantic-utest.el b/test/lisp/cedet/semantic-utest.el index 67de4a5b02..172ab62f89 100644 --- a/test/lisp/cedet/semantic-utest.el +++ b/test/lisp/cedet/semantic-utest.el @@ -1,6 +1,6 @@ ;;; semantic-utest.el --- Tests for semantic's parsing system. -*- lexical-binding:t -*- -;;; Copyright (C) 2003-2004, 2007-2021 Free Software Foundation, Inc. +;; Copyright (C) 2003-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam diff --git a/test/lisp/cedet/semantic/bovine/gcc-tests.el b/test/lisp/cedet/semantic/bovine/gcc-tests.el index e1a18c6c64..93677d6c87 100644 --- a/test/lisp/cedet/semantic/bovine/gcc-tests.el +++ b/test/lisp/cedet/semantic/bovine/gcc-tests.el @@ -1,6 +1,6 @@ ;;; gcc-tests.el --- Tests for semantic/bovine/gcc.el -*- lexical-binding:t -*- -;;; Copyright (C) 2003-2004, 2007-2021 Free Software Foundation, Inc. +;; Copyright (C) 2003-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam diff --git a/test/lisp/cedet/semantic/format-resources/test-fmt.el b/test/lisp/cedet/semantic/format-resources/test-fmt.el index 941aaae859..8458a8e651 100644 --- a/test/lisp/cedet/semantic/format-resources/test-fmt.el +++ b/test/lisp/cedet/semantic/format-resources/test-fmt.el @@ -1,6 +1,6 @@ ;;; test-fmt.el --- test semantic tag formatting -*- lexical-binding: t -*- -;;; Copyright (C) 2012, 2019-2021 Free Software Foundation, Inc. +;; Copyright (C) 2012-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam diff --git a/test/lisp/cedet/semantic/format-tests.el b/test/lisp/cedet/semantic/format-tests.el index e82c97b4c4..149f408af1 100644 --- a/test/lisp/cedet/semantic/format-tests.el +++ b/test/lisp/cedet/semantic/format-tests.el @@ -1,6 +1,6 @@ ;;; semantic/format-tests.el --- Parsing / Formatting tests -*- lexical-binding:t -*- -;;; Copyright (C) 2003-2004, 2007-2021 Free Software Foundation, Inc. +;; Copyright (C) 2003-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam diff --git a/test/lisp/cedet/semantic/fw-tests.el b/test/lisp/cedet/semantic/fw-tests.el index 62d665dbb6..7b1cd21bd1 100644 --- a/test/lisp/cedet/semantic/fw-tests.el +++ b/test/lisp/cedet/semantic/fw-tests.el @@ -1,6 +1,6 @@ ;;; fw-tests.el --- Tests for semantic/fw.el -*- lexical-binding:t -*- -;;; Copyright (C) 2003-2004, 2007-2021 Free Software Foundation, Inc. +;; Copyright (C) 2003-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam diff --git a/test/manual/cedet/semantic-tests.el b/test/manual/cedet/semantic-tests.el index 61f1d118fd..7169c78bea 100644 --- a/test/manual/cedet/semantic-tests.el +++ b/test/manual/cedet/semantic-tests.el @@ -1,6 +1,6 @@ ;;; semantic-utest.el --- Miscellaneous Semantic tests. -*- lexical-binding: t; -*- -;;; Copyright (C) 2003-2004, 2007-2021 Free Software Foundation, Inc. +;; Copyright (C) 2003-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam commit f463633f007a92418f1ea7d46347824d51373aa3 Author: Stefan Monnier Date: Thu Mar 18 23:14:33 2021 -0400 lisp/erc: Use lexical-binding Also remove various redundant `:group` arguments. * lisp/erc/erc-backend.el (define-erc-response-handler): Move `declare` after the docstring. * lisp/erc/erc-capab.el: Use lexical-binding. (erc-capab-identify-activate): Simplify with `member`. * lisp/erc/erc-dcc.el (erc-dcc): Move before erc-dcc-mode definition, which refers to it. (erc-dcc-chat-accept): Remove unused vars `nick` and `buffer`. * lisp/erc/erc-imenu.el: Use lexical-binding. (erc-create-imenu-index): Remove unused var `prev-pos`. * lisp/erc/erc-match.el: Use lexical-binding. (erc-match-message): Remove unused var `old-pt`. (erc-match-message): Strength-reduce `eval` to `symbol-value`. * lisp/erc/erc-page.el: Use lexical-binding. (erc-page): Move Custom group before `erg-page-mode` which refers to it. * lisp/erc/erc-replace.el: Use lexical-binding. (erc-replace-insert): Use `functionp`. * lisp/erc/erc-status-sidebar.el: Use lexical-binding. (erc-status-sidebar-open): Remove unused var `sidebar-window`. * lisp/erc/erc.el: Fix header to use the customary 3 semi-colons. (erc-fill-column): Declare variable. * lisp/erc/erc-autoaway.el: Use lexical-binding. * lisp/erc/erc-ezbounce.el: Use lexical-binding. * lisp/erc/erc-fill.el: Use lexical-binding. * lisp/erc/erc-goodies.el: Use lexical-binding. * lisp/erc/erc-ibuffer.el: Use lexical-binding. * lisp/erc/erc-identd.el: Use lexical-binding. * lisp/erc/erc-join.el: Use lexical-binding. * lisp/erc/erc-lang.el: Use lexical-binding. * lisp/erc/erc-log.el: Use lexical-binding. * lisp/erc/erc-menu.el: Use lexical-binding. * lisp/erc/erc-netsplit.el: Use lexical-binding. * lisp/erc/erc-networks.el: Use lexical-binding. * lisp/erc/erc-pcomplete.el: Use lexical-binding. * lisp/erc/erc-ring.el: Use lexical-binding. * lisp/erc/erc-speedbar.el: Use lexical-binding. * lisp/erc/erc-spelling.el: Use lexical-binding. * lisp/erc/erc-truncate.el: Use lexical-binding. * lisp/erc/erc-xdcc.el: Use lexical-binding. diff --git a/lisp/erc/erc-autoaway.el b/lisp/erc/erc-autoaway.el index a0085662e2..1a13aa95cd 100644 --- a/lisp/erc/erc-autoaway.el +++ b/lisp/erc/erc-autoaway.el @@ -1,4 +1,4 @@ -;;; erc-autoaway.el --- Provides autoaway for ERC +;;; erc-autoaway.el --- Provides autoaway for ERC -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2004, 2006-2021 Free Software Foundation, Inc. @@ -58,7 +58,7 @@ function each time you change `erc-autoaway-idle-seconds'." (setq erc-autoaway-idletimer (run-with-idle-timer erc-autoaway-idle-seconds t - 'erc-autoaway-set-away + #'erc-autoaway-set-away erc-autoaway-idle-seconds))) (defun erc-autoaway-some-server-buffer () @@ -66,21 +66,21 @@ function each time you change `erc-autoaway-idle-seconds'." If none is found, return nil." (car (erc-buffer-list #'erc-open-server-buffer-p))) -(defun erc-autoaway-insinuate-maybe (&optional server &rest ignored) +(defun erc-autoaway-insinuate-maybe (&optional server &rest _ignored) "Add autoaway reset function to `post-command-hook' if at least one ERC process is alive. This is used when `erc-autoaway-idle-method' is `user'." (when (or server (erc-autoaway-some-server-buffer)) - (add-hook 'post-command-hook 'erc-autoaway-reset-idle-user))) + (add-hook 'post-command-hook #'erc-autoaway-reset-idle-user))) -(defun erc-autoaway-remove-maybe (&rest ignored) +(defun erc-autoaway-remove-maybe (&rest _ignored) "Remove the autoaway reset function from `post-command-hook' if no ERC process is alive. This is used when `erc-autoaway-idle-method' is `user'." (unless (erc-autoaway-some-server-buffer) - (remove-hook 'post-command-hook 'erc-autoaway-reset-idle-user))) + (remove-hook 'post-command-hook #'erc-autoaway-reset-idle-user))) ;;;###autoload(autoload 'erc-autoaway-mode "erc-autoaway") (define-erc-module autoaway nil @@ -107,36 +107,36 @@ set you no longer away. Related variables: `erc-public-away-p' and `erc-away-nickname'." ;; Enable: ((when (boundp 'erc-autoaway-idle-method) - (add-hook 'erc-connect-pre-hook 'erc-autoaway-reset-indicators) + (add-hook 'erc-connect-pre-hook #'erc-autoaway-reset-indicators) (setq erc-autoaway-last-sent-time (erc-current-time)) (cond ((eq erc-autoaway-idle-method 'irc) - (add-hook 'erc-send-completed-hook 'erc-autoaway-reset-idle-irc) - (add-hook 'erc-server-001-functions 'erc-autoaway-reset-idle-irc)) + (add-hook 'erc-send-completed-hook #'erc-autoaway-reset-idle-irc) + (add-hook 'erc-server-001-functions #'erc-autoaway-reset-idle-irc)) ((eq erc-autoaway-idle-method 'user) - (add-hook 'erc-after-connect 'erc-autoaway-insinuate-maybe) - (add-hook 'erc-disconnected-hook 'erc-autoaway-remove-maybe) + (add-hook 'erc-after-connect #'erc-autoaway-insinuate-maybe) + (add-hook 'erc-disconnected-hook #'erc-autoaway-remove-maybe) (erc-autoaway-insinuate-maybe)) ((eq erc-autoaway-idle-method 'emacs) (erc-autoaway-reestablish-idletimer))) - (add-hook 'erc-timer-hook 'erc-autoaway-possibly-set-away) - (add-hook 'erc-server-305-functions 'erc-autoaway-reset-indicators))) + (add-hook 'erc-timer-hook #'erc-autoaway-possibly-set-away) + (add-hook 'erc-server-305-functions #'erc-autoaway-reset-indicators))) ;; Disable: ((when (boundp 'erc-autoaway-idle-method) - (remove-hook 'erc-connect-pre-hook 'erc-autoaway-reset-indicators) + (remove-hook 'erc-connect-pre-hook #'erc-autoaway-reset-indicators) (cond ((eq erc-autoaway-idle-method 'irc) - (remove-hook 'erc-send-completed-hook 'erc-autoaway-reset-idle-irc) - (remove-hook 'erc-server-001-functions 'erc-autoaway-reset-idle-irc)) + (remove-hook 'erc-send-completed-hook #'erc-autoaway-reset-idle-irc) + (remove-hook 'erc-server-001-functions #'erc-autoaway-reset-idle-irc)) ((eq erc-autoaway-idle-method 'user) - (remove-hook 'post-command-hook 'erc-autoaway-reset-idle-user) - (remove-hook 'erc-after-connect 'erc-autoaway-insinuate-maybe) - (remove-hook 'erc-disconnected-hook 'erc-autoaway-remove-maybe)) + (remove-hook 'post-command-hook #'erc-autoaway-reset-idle-user) + (remove-hook 'erc-after-connect #'erc-autoaway-insinuate-maybe) + (remove-hook 'erc-disconnected-hook #'erc-autoaway-remove-maybe)) ((eq erc-autoaway-idle-method 'emacs) (cancel-timer erc-autoaway-idletimer) (setq erc-autoaway-idletimer nil))) - (remove-hook 'erc-timer-hook 'erc-autoaway-possibly-set-away) - (remove-hook 'erc-server-305-functions 'erc-autoaway-reset-indicators)))) + (remove-hook 'erc-timer-hook #'erc-autoaway-possibly-set-away) + (remove-hook 'erc-server-305-functions #'erc-autoaway-reset-indicators)))) (defcustom erc-autoaway-idle-method 'user "The method used to determine how long you have been idle. @@ -148,7 +148,6 @@ The time itself is specified by `erc-autoaway-idle-seconds'. See `erc-autoaway-mode' for more information on the various definitions of being idle." - :group 'erc-autoaway :type '(choice (const :tag "User idle time" user) (const :tag "Emacs idle time" emacs) (const :tag "Last IRC action" irc)) @@ -166,7 +165,6 @@ ERC autoaway mode can set you away when you idle, and set you no longer away when you type something. This variable controls whether you will be set away when you idle. See `erc-auto-discard-away' for the other half." - :group 'erc-autoaway :type 'boolean) (defcustom erc-auto-discard-away t @@ -176,20 +174,17 @@ longer away when you type something. This variable controls whether you will be set no longer away when you type something. See `erc-auto-set-away' for the other half. See also `erc-autoaway-no-auto-discard-regexp'." - :group 'erc-autoaway :type 'boolean) (defcustom erc-autoaway-no-auto-discard-regexp "^/g?away.*$" "Input that matches this will not automatically discard away status. See `erc-auto-discard-away'." - :group 'erc-autoaway :type 'regexp) (defcustom erc-autoaway-idle-seconds 1800 "Number of seconds after which ERC will set you automatically away. If you are changing this variable using lisp instead of customizing it, you have to run `erc-autoaway-reestablish-idletimer' afterwards." - :group 'erc-autoaway :set (lambda (sym val) (set-default sym val) (when (eq erc-autoaway-idle-method 'emacs) @@ -201,10 +196,9 @@ you have to run `erc-autoaway-reestablish-idletimer' afterwards." "Message ERC will use when setting you automatically away. It is used as a `format' string with the argument of the idletime in seconds." - :group 'erc-autoaway :type 'string) -(defun erc-autoaway-reset-idle-user (&rest stuff) +(defun erc-autoaway-reset-idle-user (&rest _stuff) "Reset the stored user idle time. This is one global variable since a user talking on one net can talk on another net too." @@ -212,7 +206,7 @@ talk on another net too." (erc-autoaway-set-back #'erc-autoaway-remove-maybe)) (setq erc-autoaway-last-sent-time (erc-current-time))) -(defun erc-autoaway-reset-idle-irc (line &rest stuff) +(defun erc-autoaway-reset-idle-irc (line &rest _stuff) "Reset the stored IRC idle time. This is one global variable since a user talking on one net can talk on another net too." @@ -272,7 +266,7 @@ active server buffer available." (setq erc-autoaway-caused-away t) (erc-cmd-GAWAY (format-message erc-autoaway-message idle-time)))) -(defun erc-autoaway-reset-indicators (&rest stuff) +(defun erc-autoaway-reset-indicators (&rest _stuff) "Reset indicators used by the erc-autoaway module." (setq erc-autoaway-last-sent-time (erc-current-time)) (setq erc-autoaway-caused-away nil)) diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index 73c2b56b02..b1f97aea06 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -268,7 +268,6 @@ protection algorithm.") "Non-nil means that ERC will attempt to reestablish broken connections. Reconnection will happen automatically for any unexpected disconnection." - :group 'erc-server :type 'boolean) (defcustom erc-server-reconnect-attempts 2 @@ -276,7 +275,6 @@ Reconnection will happen automatically for any unexpected disconnection." broken connection, or t to always attempt to reconnect. This only has an effect if `erc-server-auto-reconnect' is non-nil." - :group 'erc-server :type '(choice (const :tag "Always reconnect" t) integer)) @@ -285,7 +283,6 @@ This only has an effect if `erc-server-auto-reconnect' is non-nil." successive reconnect attempts. If a key is pressed while ERC is waiting, it will stop waiting." - :group 'erc-server :type 'number) (defcustom erc-split-line-length 440 @@ -299,14 +296,12 @@ And a typical message looks like this: You can limit here the maximum length of the \"Hello!\" part. Good luck." - :type 'integer - :group 'erc-server) + :type 'integer) (defcustom erc-coding-system-precedence '(utf-8 undecided) "List of coding systems to be preferred when receiving a string from the server. This will only be consulted if the coding system in `erc-server-coding-system' is `undecided'." - :group 'erc-server :version "24.1" :type '(repeat coding-system)) @@ -331,7 +326,6 @@ If you need to send non-ASCII text to people not using a client that does decoding on its own, you must tell ERC what encoding to use. Emacs cannot guess it, since it does not know what the people on the other end of the line are using." - :group 'erc-server :type '(choice (const :tag "None" nil) coding-system (cons (coding-system :tag "encoding" :value utf-8) @@ -346,37 +340,32 @@ current target as returned by `erc-default-target'. Example: If you know that the channel #linux-ru uses the coding-system `cyrillic-koi8', then add (\"#linux-ru\" . cyrillic-koi8) to the alist." - :group 'erc-server :type '(repeat (cons (regexp :tag "Target") coding-system))) (defcustom erc-server-connect-function #'erc-open-network-stream "Function used to initiate a connection. It should take same arguments as `open-network-stream' does." - :group 'erc-server :type 'function) (defcustom erc-server-prevent-duplicates '("301") "Either nil or a list of strings. Each string is a IRC message type, like PRIVMSG or NOTICE. All Message types in that list of subjected to duplicate prevention." - :type '(choice (const nil) (list string)) - :group 'erc-server) + :type '(choice (const nil) (list string))) (defcustom erc-server-duplicate-timeout 60 "The time allowed in seconds between duplicate messages. If two identical messages arrive within this value of one another, the second isn't displayed." - :type 'integer - :group 'erc-server) + :type 'integer) (defcustom erc-server-timestamp-format "%Y-%m-%d %T" "Timestamp format used with server response messages. This string is processed using `format-time-string'." :version "24.3" - :type 'string - :group 'erc-server) + :type 'string) ;;; Flood-related @@ -395,22 +384,19 @@ detailed in RFC 2813, section 5.8 \"Flood control of clients\". time, send a message, and increase `erc-server-flood-last-message' by `erc-server-flood-penalty' for each message." - :type 'integer - :group 'erc-server) + :type 'integer) (defcustom erc-server-flood-penalty 3 "How much we penalize a message. See `erc-server-flood-margin' for an explanation of the flood protection algorithm." - :type 'integer - :group 'erc-server) + :type 'integer) ;; Ping handling (defcustom erc-server-send-ping-interval 30 "Interval of sending pings to the server, in seconds. If this is set to nil, pinging the server is disabled." - :group 'erc-server :type '(choice (const :tag "Disabled" nil) (integer :tag "Seconds"))) @@ -422,7 +408,6 @@ This must be greater than or equal to the value for `erc-server-send-ping-interval'. If this is set to nil, never try to reconnect." - :group 'erc-server :type '(choice (const :tag "Disabled" nil) (integer :tag "Seconds"))) @@ -1082,9 +1067,6 @@ Finds hooks by looking in the `erc-server-responses' hash table." (cl-defmacro define-erc-response-handler ((name &rest aliases) &optional extra-fn-doc extra-var-doc &rest fn-body) - (declare (debug (&define [&name "erc-response-handler@" - (symbolp &rest symbolp)] - &optional sexp sexp def-body))) "Define an ERC handler hook/function pair. NAME is the response name as sent by the server (see the IRC RFC for meanings). @@ -1164,6 +1146,9 @@ Would expand to: See also `erc-server-311'.\")) \(fn (NAME &rest ALIASES) &optional EXTRA-FN-DOC EXTRA-VAR-DOC &rest FN-BODY)" + (declare (debug (&define [&name "erc-response-handler@" + (symbolp &rest symbolp)] + &optional sexp sexp def-body))) (if (numberp name) (setq name (intern (format "%03i" name)))) (setq aliases (mapcar (lambda (a) (if (numberp a) @@ -1226,8 +1211,8 @@ add things to `%s' instead." ,@(cl-loop for fn in fn-alternates for var in var-alternates for a in aliases - nconc (list `(defalias ',fn ',fn-name) - `(defvar ,var ',fn-name ,(format hook-doc a)) + nconc (list `(defalias ',fn #',fn-name) + `(defvar ,var #',fn-name ,(format hook-doc a)) `(put ',var 'definition-name ',hook-name)))))) (define-erc-response-handler (ERROR) diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el index 0a81da3897..8b13d1cf49 100644 --- a/lisp/erc/erc-button.el +++ b/lisp/erc/erc-button.el @@ -52,14 +52,14 @@ ;;;###autoload(autoload 'erc-button-mode "erc-button" nil t) (define-erc-module button nil "This mode buttonizes all messages according to `erc-button-alist'." - ((add-hook 'erc-insert-modify-hook 'erc-button-add-buttons 'append) - (add-hook 'erc-send-modify-hook 'erc-button-add-buttons 'append) - (add-hook 'erc-complete-functions 'erc-button-next-function) - (add-hook 'erc-mode-hook 'erc-button-setup)) - ((remove-hook 'erc-insert-modify-hook 'erc-button-add-buttons) - (remove-hook 'erc-send-modify-hook 'erc-button-add-buttons) - (remove-hook 'erc-complete-functions 'erc-button-next-function) - (remove-hook 'erc-mode-hook 'erc-button-setup))) + ((add-hook 'erc-insert-modify-hook #'erc-button-add-buttons 'append) + (add-hook 'erc-send-modify-hook #'erc-button-add-buttons 'append) + (add-hook 'erc-complete-functions #'erc-button-next-function) + (add-hook 'erc-mode-hook #'erc-button-setup)) + ((remove-hook 'erc-insert-modify-hook #'erc-button-add-buttons) + (remove-hook 'erc-send-modify-hook #'erc-button-add-buttons) + (remove-hook 'erc-complete-functions #'erc-button-next-function) + (remove-hook 'erc-mode-hook #'erc-button-setup))) ;;; Variables @@ -91,7 +91,6 @@ above them." (defcustom erc-button-url-regexp browse-url-button-regexp "Regular expression that matches URLs." :version "27.1" - :group 'erc-button :type 'regexp) (defcustom erc-button-wrap-long-urls nil @@ -100,18 +99,15 @@ above them." If this variable is a number, consider URLs longer than its value to be \"long\". If t, URLs will be considered \"long\" if they are longer than `erc-fill-column'." - :group 'erc-button :type '(choice integer boolean)) (defcustom erc-button-buttonize-nicks t "Flag indicating whether nicks should be buttonized or not." - :group 'erc-button :type 'boolean) (defcustom erc-button-rfc-url "http://www.faqs.org/rfcs/rfc%s.html" "URL used to browse rfc references. %s is replaced by the number." - :group 'erc-button :type 'string) (define-obsolete-variable-alias 'erc-button-google-url @@ -121,7 +117,6 @@ longer than `erc-fill-column'." "URL used to search for a term. %s is replaced by the search string." :version "27.1" - :group 'erc-button :type 'string) (defcustom erc-button-alist @@ -179,7 +174,6 @@ PAR is a number of a regexp grouping whose text will be passed to CALLBACK. There can be several PAR arguments. If REGEXP is \\='nicknames, these are ignored, and CALLBACK will be called with the nickname matched as the argument." - :group 'erc-button :version "24.1" ; remove finger (bug#4443) :type '(repeat (list :tag "Button" @@ -200,20 +194,18 @@ PAR is a number of a regexp grouping whose text will be passed to (defcustom erc-emacswiki-url "https://www.emacswiki.org/cgi-bin/wiki.pl?" "URL of the EmacsWiki Homepage." - :group 'erc-button :type 'string) (defcustom erc-emacswiki-lisp-url "https://www.emacswiki.org/elisp/" "URL of the EmacsWiki ELisp area." - :group 'erc-button :type 'string) (defvar erc-button-keymap (let ((map (make-sparse-keymap))) - (define-key map (kbd "RET") 'erc-button-press-button) - (define-key map (kbd "") 'erc-button-click-button) - (define-key map (kbd "TAB") 'erc-button-next) - (define-key map (kbd "") 'erc-button-previous) + (define-key map (kbd "RET") #'erc-button-press-button) + (define-key map (kbd "") #'erc-button-click-button) + (define-key map (kbd "TAB") #'erc-button-next) + (define-key map (kbd "") #'erc-button-previous) (define-key map [follow-link] 'mouse-face) (set-keymap-parent map erc-mode-map) map) @@ -244,7 +236,7 @@ global-level ERC button keys yet.") "Add ERC mode-level button movement keys. This is only done once." ;; Add keys. (unless erc-button-keys-added - (define-key erc-mode-map (kbd "") 'erc-button-previous) + (define-key erc-mode-map (kbd "") #'erc-button-previous) (setq erc-button-keys-added t))) (defun erc-button-add-buttons () @@ -287,7 +279,7 @@ specified by `erc-button-alist'." (fun (nth 3 entry)) bounds word) (when (or (eq t form) - (eval form)) + (eval form t)) (goto-char (point-min)) (while (erc-forward-word) (when (setq bounds (erc-bounds-of-word-at-point)) @@ -306,9 +298,9 @@ specified by `erc-button-alist'." (end (match-end (nth 1 entry))) (form (nth 2 entry)) (fun (nth 3 entry)) - (data (mapcar 'match-string (nthcdr 4 entry)))) + (data (mapcar #'match-string (nthcdr 4 entry)))) (when (or (eq t form) - (eval form)) + (eval form t)) (erc-button-add-button start end fun nil data regexp))))) (defun erc-button-remove-old-buttons () @@ -483,7 +475,6 @@ Examples: (format \"ldapsearch -x -P 2 -h db.debian.org -b dc=debian,dc=org ircnick=%s\" nick)))" - :group 'erc-button :type '(repeat (cons (string :tag "Op") sexp))) diff --git a/lisp/erc/erc-capab.el b/lisp/erc/erc-capab.el index 4e4d012545..2028917da0 100644 --- a/lisp/erc/erc-capab.el +++ b/lisp/erc/erc-capab.el @@ -1,4 +1,4 @@ -;;; erc-capab.el --- support for dancer-ircd and hyperion's CAPAB +;;; erc-capab.el --- support for dancer-ircd and hyperion's CAPAB -*- lexical-binding: t; -*- ;; Copyright (C) 2006-2021 Free Software Foundation, Inc. @@ -80,12 +80,10 @@ If you change this from the default \"*\", be sure to use a character not found in IRC nicknames to avoid confusion." - :group 'erc-capab :type '(choice string (const nil))) (defface erc-capab-identify-unidentified '((t)) ; same as `erc-default-face' "Face to use for `erc-capab-identify-prefix'." - :group 'erc-capab :group 'erc-faces) ;;; Define module: @@ -94,22 +92,22 @@ character not found in IRC nicknames to avoid confusion." (define-erc-module capab-identify nil "Handle dancer-ircd's CAPAB IDENTIFY-MSG and IDENTIFY-CTCP." ;; append so that `erc-server-parameters' is already set by `erc-server-005' - ((add-hook 'erc-server-005-functions 'erc-capab-identify-setup t) - (add-hook 'erc-server-290-functions 'erc-capab-identify-activate) + ((add-hook 'erc-server-005-functions #'erc-capab-identify-setup t) + (add-hook 'erc-server-290-functions #'erc-capab-identify-activate) (add-hook 'erc-server-PRIVMSG-functions - 'erc-capab-identify-remove/set-identified-flag) + #'erc-capab-identify-remove/set-identified-flag) (add-hook 'erc-server-NOTICE-functions - 'erc-capab-identify-remove/set-identified-flag) - (add-hook 'erc-insert-modify-hook 'erc-capab-identify-add-prefix t) + #'erc-capab-identify-remove/set-identified-flag) + (add-hook 'erc-insert-modify-hook #'erc-capab-identify-add-prefix t) (mapc (lambda (buffer) (when buffer (with-current-buffer buffer (erc-capab-identify-setup)))) - (erc-buffer-list 'erc-open-server-buffer-p))) - ((remove-hook 'erc-server-005-functions 'erc-capab-identify-setup) - (remove-hook 'erc-server-290-functions 'erc-capab-identify-activate) + (erc-buffer-list #'erc-open-server-buffer-p))) + ((remove-hook 'erc-server-005-functions #'erc-capab-identify-setup) + (remove-hook 'erc-server-290-functions #'erc-capab-identify-activate) ;; we don't remove the `erc-capab-identify-remove/set-identified-flag' hooks ;; because there doesn't seem to be a way to tell the server to turn it off - (remove-hook 'erc-insert-modify-hook 'erc-capab-identify-add-prefix))) + (remove-hook 'erc-insert-modify-hook #'erc-capab-identify-add-prefix))) ;;; Variables: @@ -121,7 +119,7 @@ character not found in IRC nicknames to avoid confusion." ;;; Functions: -(defun erc-capab-identify-setup (&optional proc parsed) +(defun erc-capab-identify-setup (&optional _proc _parsed) "Set up CAPAB IDENTIFY on the current server. Optional argument PROC is the current server's process. @@ -146,19 +144,19 @@ These arguments are sent to this function when called as a hook in (setq erc-capab-identify-sent t))) -(defun erc-capab-identify-activate (proc parsed) +(defun erc-capab-identify-activate (_proc parsed) "Set `erc-capab-identify-activated' and display an activation message. PROC is the current server's process. PARSED is an `erc-parsed' response struct." - (when (or (string= "IDENTIFY-MSG" (erc-response.contents parsed)) - (string= "IDENTIFY-CTCP" (erc-response.contents parsed))) + (when (member (erc-response.contents parsed) + '("IDENTIFY-MSG" "IDENTIFY-CTCP")) (setq erc-capab-identify-activated t) (erc-display-message parsed 'notice 'active (format "%s activated" (erc-response.contents parsed))))) -(defun erc-capab-identify-remove/set-identified-flag (proc parsed) +(defun erc-capab-identify-remove/set-identified-flag (_proc parsed) "Remove PARSED message's id flag and add the `erc-identified' text property. PROC is the current server's process. diff --git a/lisp/erc/erc-dcc.el b/lisp/erc/erc-dcc.el index e72d8fbe3d..234b4b5a71 100644 --- a/lisp/erc/erc-dcc.el +++ b/lisp/erc/erc-dcc.el @@ -1,4 +1,4 @@ -;;; erc-dcc.el --- CTCP DCC module for ERC +;;; erc-dcc.el --- CTCP DCC module for ERC -*- lexical-binding: t; -*- ;; Copyright (C) 1993-1995, 1998, 2002-2004, 2006-2021 Free Software ;; Foundation, Inc. @@ -55,12 +55,6 @@ ;; Require at run-time too to silence compiler. (require 'pcomplete) -;;;###autoload(autoload 'erc-dcc-mode "erc-dcc") -(define-erc-module dcc nil - "Provide Direct Client-to-Client support for ERC." - ((add-hook 'erc-server-401-functions 'erc-dcc-no-such-nick)) - ((remove-hook 'erc-server-401-functions 'erc-dcc-no-such-nick))) - (defgroup erc-dcc nil "DCC stands for Direct Client Communication, where you and your friend's client programs connect directly to each other, @@ -71,9 +65,14 @@ Using DCC get and send, you can transfer files directly from and to other IRC users." :group 'erc) +;;;###autoload(autoload 'erc-dcc-mode "erc-dcc") +(define-erc-module dcc nil + "Provide Direct Client-to-Client support for ERC." + ((add-hook 'erc-server-401-functions #'erc-dcc-no-such-nick)) + ((remove-hook 'erc-server-401-functions #'erc-dcc-no-such-nick))) + (defcustom erc-dcc-verbose nil "If non-nil, be verbose about DCC activity reporting." - :group 'erc-dcc :type 'boolean) (defconst erc-dcc-connection-types @@ -120,7 +119,8 @@ All values of the list must be uppercase strings.") ;; more: the entry data from erc-dcc-list for this particular process. (defvar erc-dcc-connect-function 'erc-dcc-open-network-stream) -(defun erc-dcc-open-network-stream (procname buffer addr port entry) +(defun erc-dcc-open-network-stream (procname buffer addr port _entry) + ;; FIXME: Time to try activating this again!? (if nil; (fboundp 'open-network-stream-nowait) ;; this currently crashes ;; cvs emacs (open-network-stream-nowait procname buffer addr port) @@ -286,7 +286,6 @@ The result is also a string." "IP address to listen on when offering files. Should be set to a string or nil. If nil, automatic detection of the host interface to use will be attempted." - :group 'erc-dcc :type (list 'choice (list 'const :tag "Auto-detect" nil) (list 'string :tag "IP-address" :valid-regexp erc-dcc-ipv4-regexp))) @@ -295,7 +294,6 @@ the host interface to use will be attempted." "IP address to use for outgoing DCC offers. Should be set to a string or nil. If nil, use the value of `erc-dcc-listen-host'." - :group 'erc-dcc :type (list 'choice (list 'const :tag "Same as erc-dcc-listen-host" nil) (list 'string :tag "IP-address" :valid-regexp erc-dcc-ipv4-regexp))) @@ -306,7 +304,6 @@ Should be set to a string or nil. If nil, use the value of You might want to set `erc-dcc-auto-masks' for this. `auto' - Automatically accept the request and begin downloading the file `ignore' - Ignore incoming DCC Send requests completely." - :group 'erc-dcc :type '(choice (const ask) (const auto) (const ignore))) (defun erc-dcc-get-host (proc) @@ -323,7 +320,6 @@ If variable `erc-dcc-host' is non-nil, use it. Otherwise call (defcustom erc-dcc-port-range nil "If nil, any available user port is used for outgoing DCC connections. If set to a cons, it specifies a range of ports to use in the form (min . max)" - :group 'erc-dcc :type '(choice (const :tag "Any port" nil) (cons :tag "Port range" @@ -335,7 +331,6 @@ If set to a cons, it specifies a range of ports to use in the form (min . max)" accepted automatically. A user identifier has the form \"nick!login@host\". For instance, to accept all incoming DCC send offers automatically, add the string \".*!.*@.*\" to this list." - :group 'erc-dcc :type '(repeat regexp)) (defun erc-dcc-server (name filter sentinel) @@ -391,7 +386,6 @@ the accepted connection." (defcustom erc-dcc-get-default-directory nil "Default directory for incoming DCC file transfers. If this is nil, then the current value of `default-directory' is used." - :group 'erc-dcc :type '(choice (const nil :tag "Default directory") directory)) ;;;###autoload @@ -468,7 +462,7 @@ where FOO is one of CLOSE, GET, SEND, LIST, CHAT, etc." 'dcc-chat-offer ?n nick) t)))) -(defun erc-dcc-do-CLOSE-command (proc &optional type nick) +(defun erc-dcc-do-CLOSE-command (_proc &optional type nick) "Close a connection. Usage: /dcc close type nick. At least one of TYPE and NICK must be provided." ;; disambiguate type and nick if only one is provided @@ -540,7 +534,7 @@ PROC is the server process." (defvar-local erc-dcc-byte-count nil) -(defun erc-dcc-do-LIST-command (proc) +(defun erc-dcc-do-LIST-command (_proc) "This is the handler for the /dcc list command. It lists the current state of `erc-dcc-list' in an easy to read manner." (let ((alist erc-dcc-list) @@ -703,7 +697,6 @@ the matching regexp, or nil if none found." `ask' - Report the Chat request, and wait for the user to manually accept it `auto' - Automatically accept the request and open a new chat window `ignore' - Ignore incoming DCC chat requests completely." - :group 'erc-dcc :type '(choice (const ask) (const auto) (const ignore))) (defun erc-dcc-handle-ctcp-chat (proc query nick login host to) @@ -757,13 +750,11 @@ the matching regexp, or nil if none found." (defcustom erc-dcc-block-size 1024 "Block size to use for DCC SEND sessions." - :group 'erc-dcc :type 'integer) (defcustom erc-dcc-pump-bytes nil "If set to an integer, keep sending until that number of bytes are unconfirmed." - :group 'erc-dcc :type '(choice (const nil) integer)) (define-inline erc-dcc-get-parent (proc) @@ -837,7 +828,6 @@ bytes sent." '(erc-dcc-display-send erc-dcc-send-block) "Hook run whenever the remote end of a DCC SEND offer connected to your listening port." - :group 'erc-dcc :type 'hook) (defun erc-dcc-nick (plist) @@ -900,7 +890,6 @@ other client." (defcustom erc-dcc-receive-cache (* 1024 512) "Number of bytes to let the receive buffer grow before flushing it." - :group 'erc-dcc :type 'integer) (defvar-local erc-dcc-file-name nil) @@ -942,12 +931,12 @@ and making the connection." (set-process-coding-system proc 'binary 'binary) (set-buffer-file-coding-system 'binary t) - (set-process-filter proc 'erc-dcc-get-filter) - (set-process-sentinel proc 'erc-dcc-get-sentinel) + (set-process-filter proc #'erc-dcc-get-filter) + (set-process-sentinel proc #'erc-dcc-get-sentinel) (setq entry (plist-put entry :start-time (erc-current-time))) (setq entry (plist-put entry :peer proc))))) -(defun erc-dcc-append-contents (buffer file) +(defun erc-dcc-append-contents (buffer _file) "Append the contents of BUFFER to FILE. The contents of the BUFFER will then be erased." (with-current-buffer buffer @@ -1000,7 +989,7 @@ rather than every 1024 byte block, but nobody seems to care." proc (erc-pack-int received-bytes))))))) -(defun erc-dcc-get-sentinel (proc event) +(defun erc-dcc-get-sentinel (proc _event) "This is the process sentinel for CTCP DCC SEND connections. It shuts down the connection and notifies the user that the transfer is complete." @@ -1025,25 +1014,21 @@ transfer is complete." (defcustom erc-dcc-chat-buffer-name-format "DCC-CHAT-%s" "Format to use for DCC Chat buffer names." - :group 'erc-dcc :type 'string) (defcustom erc-dcc-chat-mode-hook nil "Hook calls when `erc-dcc-chat-mode' finished setting up the buffer." - :group 'erc-dcc :type 'hook) (defcustom erc-dcc-chat-connect-hook nil "" - :group 'erc-dcc :type 'hook) (defcustom erc-dcc-chat-exit-hook nil "" - :group 'erc-dcc :type 'hook) -(defun erc-cmd-CREQ (line &optional force) +(defun erc-cmd-CREQ (line &optional _force) "Set or get the DCC chat request flag. Possible values are: ask, auto, ignore." (when (string-match "^\\s-*\\(auto\\|ask\\|ignore\\)?$" line) @@ -1058,7 +1043,7 @@ Possible values are: ask, auto, ignore." erc-dcc-chat-request))) t))) -(defun erc-cmd-SREQ (line &optional force) +(defun erc-cmd-SREQ (line &optional _force) "Set or get the DCC send request flag. Possible values are: ask, auto, ignore." (when (string-match "^\\s-*\\(auto\\|ask\\|ignore\\)?$" line) @@ -1075,7 +1060,7 @@ Possible values are: ask, auto, ignore." (defun pcomplete/erc-mode/CREQ () (pcomplete-here '("auto" "ask" "ignore"))) -(defalias 'pcomplete/erc-mode/SREQ 'pcomplete/erc-mode/CREQ) +(defalias 'pcomplete/erc-mode/SREQ #'pcomplete/erc-mode/CREQ) (define-obsolete-variable-alias 'erc-dcc-chat-filter-hook 'erc-dcc-chat-filter-functions "24.3") @@ -1087,19 +1072,19 @@ the unprocessed output.") (defvar erc-dcc-chat-mode-map (let ((map (make-sparse-keymap))) - (define-key map (kbd "RET") 'erc-send-current-line) - (define-key map "\t" 'completion-at-point) + (define-key map (kbd "RET") #'erc-send-current-line) + (define-key map "\t" #'completion-at-point) map) "Keymap for `erc-dcc-mode'.") (define-derived-mode erc-dcc-chat-mode fundamental-mode "DCC-Chat" "Major mode for wasting time via DCC chat." (setq mode-line-process '(":%s") - erc-send-input-line-function 'erc-dcc-chat-send-input-line + erc-send-input-line-function #'erc-dcc-chat-send-input-line erc-default-recipients '(dcc)) - (add-hook 'completion-at-point-functions 'erc-complete-word-at-point nil t)) + (add-hook 'completion-at-point-functions #'erc-complete-word-at-point nil t)) -(defun erc-dcc-chat-send-input-line (recipient line &optional force) +(defun erc-dcc-chat-send-input-line (recipient line &optional _force) "Send LINE to the remote end. Argument RECIPIENT should always be the symbol dcc, and force is ignored." @@ -1150,14 +1135,14 @@ other client." (setq erc-input-marker (make-marker)) (erc-display-prompt buffer (point-max)) (set-process-buffer proc buffer) - (add-hook 'kill-buffer-hook 'erc-dcc-chat-buffer-killed nil t) + (add-hook 'kill-buffer-hook #'erc-dcc-chat-buffer-killed nil t) (run-hook-with-args 'erc-dcc-chat-connect-hook proc) buffer)) (defun erc-dcc-chat-accept (entry parent-proc) "Accept an incoming DCC connection and open a DCC window." - (let* ((nick (erc-extract-nick (plist-get entry :nick))) - buffer proc) + (let* (;; (nick (erc-extract-nick (plist-get entry :nick))) + proc) ;; buffer (setq proc (funcall erc-dcc-connect-function "dcc-chat" nil @@ -1167,9 +1152,10 @@ other client." ;; XXX: connected, should we kill the ip/port properties? (setq entry (plist-put entry :peer proc)) (setq entry (plist-put entry :parent parent-proc)) - (set-process-filter proc 'erc-dcc-chat-filter) - (set-process-sentinel proc 'erc-dcc-chat-sentinel) - (setq buffer (erc-dcc-chat-setup entry)))) + (set-process-filter proc #'erc-dcc-chat-filter) + (set-process-sentinel proc #'erc-dcc-chat-sentinel) + ;; (setq buffer + (erc-dcc-chat-setup entry))) ;; ) (defun erc-dcc-chat-filter (proc str) (let ((orig-buffer (current-buffer))) diff --git a/lisp/erc/erc-desktop-notifications.el b/lisp/erc/erc-desktop-notifications.el index 056fb23777..990f013cd2 100644 --- a/lisp/erc/erc-desktop-notifications.el +++ b/lisp/erc/erc-desktop-notifications.el @@ -45,13 +45,11 @@ (defcustom erc-notifications-icon nil "Icon to use for notification." - :group 'erc-notifications :type '(choice (const :tag "No icon" nil) file)) (defcustom erc-notifications-bus :session "D-Bus bus to use for notification." :version "25.1" - :group 'erc-notifications :type '(choice (const :tag "Session bus" :session) string)) (defvar dbus-debug) ; used in the macroexpansion of dbus-ignore-errors @@ -99,11 +97,11 @@ This will replace the last notification sent with this function." (define-erc-module notifications nil "Send notifications on private message reception and mentions." ;; Enable - ((add-hook 'erc-server-PRIVMSG-functions 'erc-notifications-PRIVMSG) - (add-hook 'erc-text-matched-hook 'erc-notifications-notify-on-match)) + ((add-hook 'erc-server-PRIVMSG-functions #'erc-notifications-PRIVMSG) + (add-hook 'erc-text-matched-hook #'erc-notifications-notify-on-match)) ;; Disable - ((remove-hook 'erc-server-PRIVMSG-functions 'erc-notifications-PRIVMSG) - (remove-hook 'erc-text-matched-hook 'erc-notifications-notify-on-match))) + ((remove-hook 'erc-server-PRIVMSG-functions #'erc-notifications-PRIVMSG) + (remove-hook 'erc-text-matched-hook #'erc-notifications-notify-on-match))) (provide 'erc-desktop-notifications) diff --git a/lisp/erc/erc-ezbounce.el b/lisp/erc/erc-ezbounce.el index 8378ff5374..331d29a7b5 100644 --- a/lisp/erc/erc-ezbounce.el +++ b/lisp/erc/erc-ezbounce.el @@ -1,4 +1,4 @@ -;;; erc-ezbounce.el --- Handle EZBounce bouncer commands +;;; erc-ezbounce.el --- Handle EZBounce bouncer commands -*- lexical-binding: t; -*- ;; Copyright (C) 2002, 2004, 2006-2021 Free Software Foundation, Inc. @@ -33,7 +33,6 @@ (defcustom erc-ezb-regexp "^ezbounce!srv$" "Regexp used by the EZBouncer to identify itself to the user." - :group 'erc-ezbounce :type 'regexp) (defcustom erc-ezb-login-alist '() @@ -44,7 +43,6 @@ The alist's format is as follows: (((server . port) . (username . password)) ((server . port) . (username . password)) ...)" - :group 'erc-ezbounce :type '(repeat (cons (cons :tag "Server" string @@ -68,7 +66,7 @@ The alist's format is as follows: "Indicate whether current notices are expected to be EZB session listings.") ;;;###autoload -(defun erc-cmd-ezb (line &optional force) +(defun erc-cmd-ezb (line &optional _force) "Send EZB commands to the EZBouncer verbatim." (erc-server-send (concat "EZB " line))) (put 'erc-cmd-EZB 'do-not-parse-args t) @@ -102,7 +100,7 @@ in the alist is nil, prompt for the appropriate values." found)) ;;;###autoload -(defun erc-ezb-notice-autodetect (proc parsed) +(defun erc-ezb-notice-autodetect (_proc parsed) "React on an EZBounce NOTICE request." (let* ((sender (erc-response.sender parsed)) (message (erc-response.contents parsed)) @@ -113,7 +111,7 @@ in the alist is nil, prompt for the appropriate values." nil) ;;;###autoload -(defun erc-ezb-identify (message) +(defun erc-ezb-identify (_message) "Identify to the EZBouncer server." (let ((login (erc-ezb-get-login erc-session-server (erc-port-to-string erc-session-port)))) (unless (null login) @@ -122,13 +120,13 @@ in the alist is nil, prompt for the appropriate values." (erc-server-send (concat "LOGIN " username " " pass)))))) ;;;###autoload -(defun erc-ezb-init-session-list (message) +(defun erc-ezb-init-session-list (_message) "Reset the EZBounce session list to nil." (setq erc-ezb-session-list nil) (setq erc-ezb-inside-session-listing t)) ;;;###autoload -(defun erc-ezb-end-of-session-list (message) +(defun erc-ezb-end-of-session-list (_message) "Indicate the end of the EZBounce session listing." (setq erc-ezb-inside-session-listing nil)) @@ -143,7 +141,7 @@ in the alist is nil, prompt for the appropriate values." (add-to-list 'erc-ezb-session-list (list id nick to))))) ;;;###autoload -(defun erc-ezb-select (message) +(defun erc-ezb-select (_message) "Select an IRC server to use by EZBounce, in ERC style." (unless (and erc-ezb-session-list (erc-ezb-select-session)) @@ -169,7 +167,7 @@ in the alist is nil, prompt for the appropriate values." ;;;###autoload (defun erc-ezb-initialize () "Add EZBouncer convenience functions to ERC." - (add-hook 'erc-server-NOTICE-functions 'erc-ezb-notice-autodetect)) + (add-hook 'erc-server-NOTICE-functions #'erc-ezb-notice-autodetect)) (provide 'erc-ezbounce) diff --git a/lisp/erc/erc-fill.el b/lisp/erc/erc-fill.el index 83ef5f93fa..0312d221ec 100644 --- a/lisp/erc/erc-fill.el +++ b/lisp/erc/erc-fill.el @@ -1,4 +1,4 @@ -;;; erc-fill.el --- Filling IRC messages in various ways +;;; erc-fill.el --- Filling IRC messages in various ways -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2004, 2006-2021 Free Software Foundation, Inc. @@ -47,7 +47,7 @@ the mode if ARG is omitted or nil. ERC fill mode is a global minor mode. When enabled, messages in the channel buffers are filled." nil nil nil - :global t :group 'erc-fill + :global t (if erc-fill-mode (erc-fill-enable) (erc-fill-disable))) @@ -55,19 +55,18 @@ the channel buffers are filled." (defun erc-fill-enable () "Setup hooks for `erc-fill-mode'." (interactive) - (add-hook 'erc-insert-modify-hook 'erc-fill) - (add-hook 'erc-send-modify-hook 'erc-fill)) + (add-hook 'erc-insert-modify-hook #'erc-fill) + (add-hook 'erc-send-modify-hook #'erc-fill)) (defun erc-fill-disable () "Cleanup hooks, disable `erc-fill-mode'." (interactive) - (remove-hook 'erc-insert-modify-hook 'erc-fill) - (remove-hook 'erc-send-modify-hook 'erc-fill)) + (remove-hook 'erc-insert-modify-hook #'erc-fill) + (remove-hook 'erc-send-modify-hook #'erc-fill)) (defcustom erc-fill-prefix nil "Values used as `fill-prefix' for `erc-fill-variable'. nil means fill with space, a string means fill with this string." - :group 'erc-fill :type '(choice (const nil) string)) (defcustom erc-fill-function 'erc-fill-variable @@ -94,7 +93,6 @@ These two styles are implemented using `erc-fill-variable' and `erc-fill-static'. You can, of course, define your own filling function. Narrowing to the region in question is in effect while your function is called." - :group 'erc-fill :type '(choice (const :tag "Variable Filling" erc-fill-variable) (const :tag "Static Filling" erc-fill-static) function)) @@ -104,18 +102,15 @@ function is called." centered. This column denotes the point where the ` ' character between and the entered text will be put, thus aligning nick names right and text left." - :group 'erc-fill :type 'integer) (defcustom erc-fill-variable-maximum-indentation 17 "If we indent a line after a long nick, don't indent more then this characters. Set to nil to disable." - :group 'erc-fill :type 'integer) (defcustom erc-fill-column 78 "The column at which a filled paragraph is broken." - :group 'erc-fill :type 'integer) ;;;###autoload diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el index aef68810df..1143faa1e2 100644 --- a/lisp/erc/erc-goodies.el +++ b/lisp/erc/erc-goodies.el @@ -1,4 +1,4 @@ -;; erc-goodies.el --- Collection of ERC modules +;; erc-goodies.el --- Collection of ERC modules -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. @@ -37,7 +37,7 @@ "Setup Imenu support in an ERC buffer." (setq-local imenu-create-index-function #'erc-create-imenu-index)) -(add-hook 'erc-mode-hook 'erc-imenu-setup) +(add-hook 'erc-mode-hook #'erc-imenu-setup) (autoload 'erc-create-imenu-index "erc-imenu" "Imenu index creation function") ;;; Automatically scroll to bottom @@ -53,16 +53,16 @@ argument to `recenter'." (define-erc-module scrolltobottom nil "This mode causes the prompt to stay at the end of the window." - ((add-hook 'erc-mode-hook 'erc-add-scroll-to-bottom) - (add-hook 'erc-insert-done-hook 'erc-possibly-scroll-to-bottom) + ((add-hook 'erc-mode-hook #'erc-add-scroll-to-bottom) + (add-hook 'erc-insert-done-hook #'erc-possibly-scroll-to-bottom) (dolist (buffer (erc-buffer-list)) (with-current-buffer buffer (erc-add-scroll-to-bottom)))) - ((remove-hook 'erc-mode-hook 'erc-add-scroll-to-bottom) - (remove-hook 'erc-insert-done-hook 'erc-possibly-scroll-to-bottom) + ((remove-hook 'erc-mode-hook #'erc-add-scroll-to-bottom) + (remove-hook 'erc-insert-done-hook #'erc-possibly-scroll-to-bottom) (dolist (buffer (erc-buffer-list)) (with-current-buffer buffer - (remove-hook 'post-command-hook 'erc-scroll-to-bottom t))))) + (remove-hook 'post-command-hook #'erc-scroll-to-bottom t))))) (defun erc-possibly-scroll-to-bottom () "Like `erc-add-scroll-to-bottom', but only if window is selected." @@ -77,7 +77,7 @@ the value of `erc-input-line-position'. This works whenever scrolling happens, so it's added to `window-scroll-functions' rather than `erc-insert-post-hook'." - (add-hook 'post-command-hook 'erc-scroll-to-bottom nil t)) + (add-hook 'post-command-hook #'erc-scroll-to-bottom nil t)) (defun erc-scroll-to-bottom () "Recenter WINDOW so that `point' is on the last line. @@ -104,10 +104,10 @@ variable `erc-input-line-position'." ;;; Make read only (define-erc-module readonly nil "This mode causes all inserted text to be read-only." - ((add-hook 'erc-insert-post-hook 'erc-make-read-only) - (add-hook 'erc-send-post-hook 'erc-make-read-only)) - ((remove-hook 'erc-insert-post-hook 'erc-make-read-only) - (remove-hook 'erc-send-post-hook 'erc-make-read-only))) + ((add-hook 'erc-insert-post-hook #'erc-make-read-only) + (add-hook 'erc-send-post-hook #'erc-make-read-only)) + ((remove-hook 'erc-insert-post-hook #'erc-make-read-only) + (remove-hook 'erc-send-post-hook #'erc-make-read-only))) (defun erc-make-read-only () "Make all the text in the current buffer read-only. @@ -119,14 +119,14 @@ Put this function on `erc-insert-post-hook' and/or `erc-send-post-hook'." ;;; Move to prompt when typing text (define-erc-module move-to-prompt nil "This mode causes the point to be moved to the prompt when typing text." - ((add-hook 'erc-mode-hook 'erc-move-to-prompt-setup) + ((add-hook 'erc-mode-hook #'erc-move-to-prompt-setup) (dolist (buffer (erc-buffer-list)) (with-current-buffer buffer (erc-move-to-prompt-setup)))) - ((remove-hook 'erc-mode-hook 'erc-move-to-prompt-setup) + ((remove-hook 'erc-mode-hook #'erc-move-to-prompt-setup) (dolist (buffer (erc-buffer-list)) (with-current-buffer buffer - (remove-hook 'pre-command-hook 'erc-move-to-prompt t))))) + (remove-hook 'pre-command-hook #'erc-move-to-prompt t))))) (defun erc-move-to-prompt () "Move the point to the ERC prompt if this is a self-inserting command." @@ -138,15 +138,15 @@ Put this function on `erc-insert-post-hook' and/or `erc-send-post-hook'." (defun erc-move-to-prompt-setup () "Initialize the move-to-prompt module for XEmacs." - (add-hook 'pre-command-hook 'erc-move-to-prompt nil t)) + (add-hook 'pre-command-hook #'erc-move-to-prompt nil t)) ;;; Keep place in unvisited channels (define-erc-module keep-place nil "Leave point above un-viewed text in other channels." - ((add-hook 'erc-insert-pre-hook 'erc-keep-place)) - ((remove-hook 'erc-insert-pre-hook 'erc-keep-place))) + ((add-hook 'erc-insert-pre-hook #'erc-keep-place)) + ((remove-hook 'erc-insert-pre-hook #'erc-keep-place))) -(defun erc-keep-place (ignored) +(defun erc-keep-place (_ignored) "Move point away from the last line in a non-selected ERC buffer." (when (and (not (eq (window-buffer (selected-window)) (current-buffer))) @@ -183,8 +183,8 @@ does not appear in the ERC buffer after the user presses ENTER.") "This mode distinguishes non-commands. Commands listed in `erc-insert-this' know how to display themselves." - ((add-hook 'erc-pre-send-functions 'erc-send-distinguish-noncommands)) - ((remove-hook 'erc-pre-send-functions 'erc-send-distinguish-noncommands))) + ((add-hook 'erc-pre-send-functions #'erc-send-distinguish-noncommands)) + ((remove-hook 'erc-pre-send-functions #'erc-send-distinguish-noncommands))) (defun erc-send-distinguish-noncommands (state) "If STR is an ERC non-command, set `insertp' in STATE to nil." @@ -211,20 +211,17 @@ highlighting effects. When this variable is non-nil, it can cause Emacs to run slowly on systems lacking sufficient CPU speed. In chatty channels, or in an emergency (message flood) it can be turned off to save processing time. See `erc-toggle-interpret-controls'." - :group 'erc-control-characters :type '(choice (const :tag "Highlight control characters" t) (const :tag "Remove control characters" remove) (const :tag "Display raw control characters" nil))) (defcustom erc-interpret-mirc-color nil "If non-nil, ERC will interpret mIRC color codes." - :group 'erc-control-characters :type 'boolean) (defcustom erc-beep-p nil "Beep if C-g is in the server message. The value `erc-interpret-controls-p' must also be t for this to work." - :group 'erc-control-characters :type 'boolean) (defface erc-bold-face '((t :weight bold)) @@ -372,10 +369,10 @@ The value `erc-interpret-controls-p' must also be t for this to work." (define-erc-module irccontrols nil "This mode enables the interpretation of IRC control chars." - ((add-hook 'erc-insert-modify-hook 'erc-controls-highlight) - (add-hook 'erc-send-modify-hook 'erc-controls-highlight)) - ((remove-hook 'erc-insert-modify-hook 'erc-controls-highlight) - (remove-hook 'erc-send-modify-hook 'erc-controls-highlight))) + ((add-hook 'erc-insert-modify-hook #'erc-controls-highlight) + (add-hook 'erc-send-modify-hook #'erc-controls-highlight)) + ((remove-hook 'erc-insert-modify-hook #'erc-controls-highlight) + (remove-hook 'erc-send-modify-hook #'erc-controls-highlight))) (defun erc-controls-interpret (str) "Return a copy of STR after dealing with IRC control characters. @@ -546,10 +543,10 @@ Else interpretation is turned off." "This mode translates text-smileys such as :-) into pictures. This requires the function `smiley-region', which is defined in smiley.el, which is part of Gnus." - ((add-hook 'erc-insert-modify-hook 'erc-smiley) - (add-hook 'erc-send-modify-hook 'erc-smiley)) - ((remove-hook 'erc-insert-modify-hook 'erc-smiley) - (remove-hook 'erc-send-modify-hook 'erc-smiley))) + ((add-hook 'erc-insert-modify-hook #'erc-smiley) + (add-hook 'erc-send-modify-hook #'erc-smiley)) + ((remove-hook 'erc-insert-modify-hook #'erc-smiley) + (remove-hook 'erc-send-modify-hook #'erc-smiley))) (defun erc-smiley () "Smilify a region. @@ -560,8 +557,8 @@ This function should be used with `erc-insert-modify-hook'." ;; Unmorse (define-erc-module unmorse nil "This mode causes morse code in the current channel to be unmorsed." - ((add-hook 'erc-insert-modify-hook 'erc-unmorse)) - ((remove-hook 'erc-insert-modify-hook 'erc-unmorse))) + ((add-hook 'erc-insert-modify-hook #'erc-unmorse)) + ((remove-hook 'erc-insert-modify-hook #'erc-unmorse))) (defun erc-unmorse () "Unmorse some text. diff --git a/lisp/erc/erc-ibuffer.el b/lisp/erc/erc-ibuffer.el index 5a002ccae3..22336ede21 100644 --- a/lisp/erc/erc-ibuffer.el +++ b/lisp/erc/erc-ibuffer.el @@ -1,4 +1,4 @@ -;;; erc-ibuffer.el --- ibuffer integration with ERC +;;; erc-ibuffer.el --- ibuffer integration with ERC -*- lexical-binding: t; -*- ;; Copyright (C) 2002, 2004, 2006-2021 Free Software Foundation, Inc. @@ -39,20 +39,16 @@ (defcustom erc-ibuffer-keyword-char ?k "Char used to indicate a channel which had keyword traffic lately (hidden)." - :group 'erc-ibuffer :type 'character) (defcustom erc-ibuffer-pal-char ?p "Char used to indicate a channel which had pal traffic lately (hidden)." - :group 'erc-ibuffer :type 'character) (defcustom erc-ibuffer-fool-char ?f "Char used to indicate a channel which had fool traffic lately (hidden)." - :group 'erc-ibuffer :type 'character) (defcustom erc-ibuffer-dangerous-host-char ?d "Char used to indicate a channel which had dangerous-host traffic lately \(hidden)." - :group 'erc-ibuffer :type 'character) (define-ibuffer-filter erc-server @@ -153,7 +149,7 @@ (if (and (eq major-mode 'erc-mode) (or (> (length erc-channel-modes) 0) erc-channel-user-limit)) - (concat (apply 'concat + (concat (apply #'concat "(+" erc-channel-modes) (if erc-channel-user-limit (format "l %d" erc-channel-user-limit) @@ -181,6 +177,7 @@ (defvar erc-ibuffer-limit-map nil "Prefix keymap to use for ERC related limiting.") (define-prefix-command 'erc-ibuffer-limit-map) +;; FIXME: Where is `ibuffer-limit-by-erc-server' defined? (define-key 'erc-ibuffer-limit-map (kbd "s") 'ibuffer-limit-by-erc-server) (define-key ibuffer-mode-map (kbd "/ \C-e") 'erc-ibuffer-limit-map) diff --git a/lisp/erc/erc-identd.el b/lisp/erc/erc-identd.el index 1f68272ebb..3821e298cd 100644 --- a/lisp/erc/erc-identd.el +++ b/lisp/erc/erc-identd.el @@ -1,4 +1,4 @@ -;;; erc-identd.el --- RFC1413 (identd authentication protocol) server +;;; erc-identd.el --- RFC1413 (identd authentication protocol) server -*- lexical-binding: t; -*- ;; Copyright (C) 2003, 2006-2021 Free Software Foundation, Inc. @@ -50,7 +50,6 @@ `erc-identd-start'. This can be either a string or a number." - :group 'erc-identd :type '(choice (const :tag "None" nil) (integer :tag "Port number") (string :tag "Port string"))) @@ -58,10 +57,10 @@ This can be either a string or a number." ;;;###autoload(autoload 'erc-identd-mode "erc-identd") (define-erc-module identd nil "This mode launches an identd server on port 8113." - ((add-hook 'erc-connect-pre-hook 'erc-identd-quickstart) - (add-hook 'erc-disconnected-hook 'erc-identd-stop)) - ((remove-hook 'erc-connect-pre-hook 'erc-identd-quickstart) - (remove-hook 'erc-disconnected-hook 'erc-identd-stop))) + ((add-hook 'erc-connect-pre-hook #'erc-identd-quickstart) + (add-hook 'erc-disconnected-hook #'erc-identd-stop)) + ((remove-hook 'erc-connect-pre-hook #'erc-identd-quickstart) + (remove-hook 'erc-disconnected-hook #'erc-identd-stop))) (defun erc-identd-filter (proc string) "This filter implements RFC1413 (identd authentication protocol)." @@ -95,16 +94,16 @@ system." :buffer nil :host 'local :service port :server t :noquery t :nowait t - :filter 'erc-identd-filter)) + :filter #'erc-identd-filter)) (set-process-query-on-exit-flag erc-identd-process nil)) -(defun erc-identd-quickstart (&rest ignored) +(defun erc-identd-quickstart (&rest _ignored) "Start the identd server with the default port. The default port is specified by `erc-identd-port'." (erc-identd-start)) ;;;###autoload -(defun erc-identd-stop (&rest ignore) +(defun erc-identd-stop (&rest _ignore) (interactive) (when erc-identd-process (delete-process erc-identd-process) diff --git a/lisp/erc/erc-imenu.el b/lisp/erc/erc-imenu.el index ecdfc2a04b..b2a2dc588e 100644 --- a/lisp/erc/erc-imenu.el +++ b/lisp/erc/erc-imenu.el @@ -1,4 +1,4 @@ -;;; erc-imenu.el -- Imenu support for ERC +;;; erc-imenu.el -- Imenu support for ERC -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2002, 2004, 2006-2021 Free Software Foundation, ;; Inc. @@ -71,7 +71,7 @@ Don't rely on this function, read it first!" (message-alist '()) (mode-change-alist '()) (topic-change-alist '()) - prev-pos) + ) ;; prev-pos (goto-char (point-max)) (while (if (bolp) (> (forward-line -1) @@ -106,7 +106,8 @@ Don't rely on this function, read it first!" "^\\(\\S-+\\) (.+) has set the topic for \\S-+: \\(.*\\)$" notice-text) (push (cons (concat (match-string 1 notice-text) ": " - (match-string 2 notice-text)) pos) + (match-string 2 notice-text)) + pos) topic-change-alist))))) (when (looking-at "<\\(\\S-+\\)> \\(.+\\)$") (let ((from (match-string 1)) diff --git a/lisp/erc/erc-join.el b/lisp/erc/erc-join.el index 1707e714cc..2ad9c8bd94 100644 --- a/lisp/erc/erc-join.el +++ b/lisp/erc/erc-join.el @@ -1,4 +1,4 @@ -;;; erc-join.el --- autojoin channels on connect and reconnects +;;; erc-join.el --- autojoin channels on connect and reconnects -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2004, 2006-2021 Free Software Foundation, Inc. @@ -42,14 +42,14 @@ ;;;###autoload(autoload 'erc-autojoin-mode "erc-join" nil t) (define-erc-module autojoin nil "Makes ERC autojoin on connects and reconnects." - ((add-hook 'erc-after-connect 'erc-autojoin-channels) - (add-hook 'erc-nickserv-identified-hook 'erc-autojoin-after-ident) - (add-hook 'erc-server-JOIN-functions 'erc-autojoin-add) - (add-hook 'erc-server-PART-functions 'erc-autojoin-remove)) - ((remove-hook 'erc-after-connect 'erc-autojoin-channels) - (remove-hook 'erc-nickserv-identified-hook 'erc-autojoin-after-ident) - (remove-hook 'erc-server-JOIN-functions 'erc-autojoin-add) - (remove-hook 'erc-server-PART-functions 'erc-autojoin-remove))) + ((add-hook 'erc-after-connect #'erc-autojoin-channels) + (add-hook 'erc-nickserv-identified-hook #'erc-autojoin-after-ident) + (add-hook 'erc-server-JOIN-functions #'erc-autojoin-add) + (add-hook 'erc-server-PART-functions #'erc-autojoin-remove)) + ((remove-hook 'erc-after-connect #'erc-autojoin-channels) + (remove-hook 'erc-nickserv-identified-hook #'erc-autojoin-after-ident) + (remove-hook 'erc-server-JOIN-functions #'erc-autojoin-add) + (remove-hook 'erc-server-PART-functions #'erc-autojoin-remove))) (defcustom erc-autojoin-channels-alist nil "Alist of channels to autojoin on IRC networks. @@ -70,7 +70,6 @@ keeps track of what channels you are on, and will join them again when you get disconnected. When you restart Emacs, however, those changes are lost, and the customization you saved the last time is used again." - :group 'erc-autojoin :type '(repeat (cons :tag "Server" (regexp :tag "Name") (repeat :tag "Channels" @@ -82,7 +81,6 @@ If the value is `connect', autojoin immediately on connecting. If the value is `ident', autojoin after successful NickServ identification, or after `erc-autojoin-delay' seconds. Any other value means the same as `connect'." - :group 'erc-autojoin :version "24.1" :type '(choice (const :tag "On Connection" connect) (const :tag "When Identified" ident))) @@ -92,7 +90,6 @@ Any other value means the same as `connect'." This only takes effect if `erc-autojoin-timing' is `ident'. If NickServ identification occurs before this delay expires, ERC autojoins immediately at that time." - :group 'erc-autojoin :version "24.1" :type 'integer) @@ -102,7 +99,6 @@ If non-nil, and a channel on the server a.b.c is joined, then only b.c is used as the server for `erc-autojoin-channels-alist'. This is important for networks that redirect you to other servers, presumably in the same domain." - :group 'erc-autojoin :type 'boolean) (defvar-local erc--autojoin-timer nil) @@ -121,7 +117,7 @@ This is called from a timer set up by `erc-autojoin-channels'." (erc-log "Delayed autojoin started (no ident success detected yet)") (erc-autojoin-channels server nick)))) -(defun erc-autojoin-after-ident (network nick) +(defun erc-autojoin-after-ident (_network _nick) "Autojoin channels in `erc-autojoin-channels-alist'. This function is run from `erc-nickserv-identified-hook'." (if erc--autojoin-timer @@ -149,7 +145,7 @@ This function is run from `erc-nickserv-identified-hook'." (when (> erc-autojoin-delay 0) (setq erc--autojoin-timer (run-with-timer erc-autojoin-delay nil - 'erc-autojoin-channels-delayed + #'erc-autojoin-channels-delayed server nick (current-buffer)))) ;; `erc-autojoin-timing' is `connect': (let ((server (or erc-session-server erc-server-announced-name))) diff --git a/lisp/erc/erc-lang.el b/lisp/erc/erc-lang.el index 4163e5a08d..136131ca36 100644 --- a/lisp/erc/erc-lang.el +++ b/lisp/erc/erc-lang.el @@ -1,4 +1,4 @@ -;;; erc-lang.el --- provide the LANG command to ERC +;;; erc-lang.el --- provide the LANG command to ERC -*- lexical-binding: t; -*- ;; Copyright (C) 2002, 2004, 2006-2021 Free Software Foundation, Inc. diff --git a/lisp/erc/erc-list.el b/lisp/erc/erc-list.el index cf150e74ab..31693a7b77 100644 --- a/lisp/erc/erc-list.el +++ b/lisp/erc/erc-list.el @@ -59,13 +59,13 @@ ;;;###autoload(autoload 'erc-list-mode "erc-list") (define-erc-module list nil "List channels nicely in a separate buffer." - ((remove-hook 'erc-server-321-functions 'erc-server-321-message) - (remove-hook 'erc-server-322-functions 'erc-server-322-message)) + ((remove-hook 'erc-server-321-functions #'erc-server-321-message) + (remove-hook 'erc-server-322-functions #'erc-server-322-message)) ((erc-with-all-buffers-of-server nil #'erc-open-server-buffer-p - (remove-hook 'erc-server-322-functions 'erc-list-handle-322 t)) - (add-hook 'erc-server-321-functions 'erc-server-321-message t) - (add-hook 'erc-server-322-functions 'erc-server-322-message t))) + (remove-hook 'erc-server-322-functions #'erc-list-handle-322 t)) + (add-hook 'erc-server-321-functions #'erc-server-321-message t) + (add-hook 'erc-server-322-functions #'erc-server-322-message t))) ;; Format a record for display. (defun erc-list-make-string (channel users topic) @@ -126,17 +126,17 @@ (defvar erc-list-menu-mode-map (let ((map (make-keymap))) (set-keymap-parent map special-mode-map) - (define-key map "k" 'erc-list-kill) - (define-key map "j" 'erc-list-join) - (define-key map "g" 'erc-list-revert) - (define-key map "n" 'next-line) - (define-key map "p" 'previous-line) + (define-key map "k" #'erc-list-kill) + (define-key map "j" #'erc-list-join) + (define-key map "g" #'erc-list-revert) + (define-key map "n" #'next-line) + (define-key map "p" #'previous-line) map) "Local keymap for `erc-list-mode' buffers.") (defvar erc-list-menu-sort-button-map (let ((map (make-sparse-keymap))) - (define-key map [header-line mouse-1] 'erc-list-menu-sort-by-column) + (define-key map [header-line mouse-1] #'erc-list-menu-sort-by-column) (define-key map [follow-link] 'mouse-face) map) "Local keymap for ERC list menu mode sorting buttons.") @@ -181,12 +181,12 @@ (defun erc-list-install-322-handler (server-buffer) (with-current-buffer server-buffer ;; Arrange for 322 responses to insert into our buffer. - (add-hook 'erc-server-322-functions 'erc-list-handle-322 t t) + (add-hook 'erc-server-322-functions #'erc-list-handle-322 t t) ;; Arrange for 323 (end of list) to end this. (erc-once-with-server-event 323 (lambda (_proc _parsed) - (remove-hook 'erc-server-322-functions 'erc-list-handle-322 t))) + (remove-hook 'erc-server-322-functions #'erc-list-handle-322 t))) ;; Find the list buffer, empty it, and display it. (setq-local erc-list-buffer (get-buffer-create (concat "*Channels of " diff --git a/lisp/erc/erc-log.el b/lisp/erc/erc-log.el index 22fd3d2713..ddd00afd73 100644 --- a/lisp/erc/erc-log.el +++ b/lisp/erc/erc-log.el @@ -1,4 +1,4 @@ -;;; erc-log.el --- Logging facilities for ERC. +;;; erc-log.el --- Logging facilities for ERC. -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2021 Free Software Foundation, Inc. @@ -112,7 +112,6 @@ SERVER and PORT are the parameters that were used to connect to BUFFERs If you want to write logs into different directories, make a custom function which returns the directory part and set `erc-log-channels-directory' to its name." - :group 'erc-log :type '(choice (const :tag "#channel!nick@server:port.txt" erc-generate-log-file-name-long) (const :tag "#channel!nick@network.txt" @@ -124,7 +123,6 @@ custom function which returns the directory part and set (defcustom erc-truncate-buffer-on-save nil "Erase the contents of any ERC (channel, query, server) buffer when it is saved." - :group 'erc-log :type 'boolean) (defcustom erc-enable-logging t @@ -138,7 +136,6 @@ This variable is buffer local. Setting it via \\[customize] sets the default value. Log files are stored in `erc-log-channels-directory'." - :group 'erc-log :type '(choice boolean function)) (make-variable-buffer-local 'erc-enable-logging) @@ -153,14 +150,12 @@ If this is the name of a function, the function will be called with the buffer, target, nick, server, and port arguments. See `erc-generate-log-file-name-function' for a description of these arguments." - :group 'erc-log :type '(choice directory (function "Function") (const :tag "Disable logging" nil))) (defcustom erc-log-insert-log-on-open nil "Insert log file contents into the buffer if a log file exists." - :group 'erc-log :type 'boolean) (defcustom erc-save-buffer-on-part t @@ -168,7 +163,6 @@ arguments." If you set this to nil, you may want to enable both `erc-log-write-after-send' and `erc-log-write-after-insert'." - :group 'erc-log :type 'boolean) (defcustom erc-save-queries-on-quit t @@ -176,7 +170,6 @@ If you set this to nil, you may want to enable both If you set this to nil, you may want to enable both `erc-log-write-after-send' and `erc-log-write-after-insert'." - :group 'erc-log :type 'boolean) (defcustom erc-log-write-after-send nil @@ -184,7 +177,6 @@ If you set this to nil, you may want to enable both If you set this to nil, you may want to enable both `erc-save-buffer-on-part' and `erc-save-queries-on-quit'." - :group 'erc-log :type 'boolean) (defcustom erc-log-write-after-insert nil @@ -193,7 +185,6 @@ logged ERC buffer. If you set this to nil, you may want to enable both `erc-save-buffer-on-part' and `erc-save-queries-on-quit'." - :group 'erc-log :type 'boolean) (defcustom erc-log-file-coding-system 'emacs-mule @@ -201,15 +192,13 @@ If you set this to nil, you may want to enable both This should ideally, be a \"catch-all\" coding system, like `emacs-mule', or `iso-2022-7bit'." - :type 'coding-system - :group 'erc-log) + :type 'coding-system) (defcustom erc-log-filter-function nil "If non-nil, pass text through the given function before writing it to a log file. The function should take one argument, which is the text to filter." - :group 'erc-log :type '(choice (function "Function") (const :tag "No filtering" nil))) @@ -232,31 +221,31 @@ also be a predicate function. To only log when you are not set away, use: (null (erc-away-time)))))" ;; enable ((when erc-log-write-after-insert - (add-hook 'erc-insert-post-hook 'erc-save-buffer-in-logs)) + (add-hook 'erc-insert-post-hook #'erc-save-buffer-in-logs)) (when erc-log-write-after-send - (add-hook 'erc-send-post-hook 'erc-save-buffer-in-logs)) - (add-hook 'erc-kill-buffer-hook 'erc-save-buffer-in-logs) - (add-hook 'erc-kill-channel-hook 'erc-save-buffer-in-logs) - (add-hook 'kill-emacs-hook 'erc-log-save-all-buffers) - (add-hook 'erc-quit-hook 'erc-conditional-save-queries) - (add-hook 'erc-part-hook 'erc-conditional-save-buffer) + (add-hook 'erc-send-post-hook #'erc-save-buffer-in-logs)) + (add-hook 'erc-kill-buffer-hook #'erc-save-buffer-in-logs) + (add-hook 'erc-kill-channel-hook #'erc-save-buffer-in-logs) + (add-hook 'kill-emacs-hook #'erc-log-save-all-buffers) + (add-hook 'erc-quit-hook #'erc-conditional-save-queries) + (add-hook 'erc-part-hook #'erc-conditional-save-buffer) ;; append, so that 'erc-initialize-log-marker runs first - (add-hook 'erc-connect-pre-hook 'erc-log-setup-logging 'append) + (add-hook 'erc-connect-pre-hook #'erc-log-setup-logging 'append) (dolist (buffer (erc-buffer-list)) (erc-log-setup-logging buffer))) ;; disable - ((remove-hook 'erc-insert-post-hook 'erc-save-buffer-in-logs) - (remove-hook 'erc-send-post-hook 'erc-save-buffer-in-logs) - (remove-hook 'erc-kill-buffer-hook 'erc-save-buffer-in-logs) - (remove-hook 'erc-kill-channel-hook 'erc-save-buffer-in-logs) - (remove-hook 'kill-emacs-hook 'erc-log-save-all-buffers) - (remove-hook 'erc-quit-hook 'erc-conditional-save-queries) - (remove-hook 'erc-part-hook 'erc-conditional-save-buffer) - (remove-hook 'erc-connect-pre-hook 'erc-log-setup-logging) + ((remove-hook 'erc-insert-post-hook #'erc-save-buffer-in-logs) + (remove-hook 'erc-send-post-hook #'erc-save-buffer-in-logs) + (remove-hook 'erc-kill-buffer-hook #'erc-save-buffer-in-logs) + (remove-hook 'erc-kill-channel-hook #'erc-save-buffer-in-logs) + (remove-hook 'kill-emacs-hook #'erc-log-save-all-buffers) + (remove-hook 'erc-quit-hook #'erc-conditional-save-queries) + (remove-hook 'erc-part-hook #'erc-conditional-save-buffer) + (remove-hook 'erc-connect-pre-hook #'erc-log-setup-logging) (dolist (buffer (erc-buffer-list)) (erc-log-disable-logging buffer)))) -(define-key erc-mode-map "\C-c\C-l" 'erc-save-buffer-in-logs) +(define-key erc-mode-map "\C-c\C-l" #'erc-save-buffer-in-logs) ;;; functionality referenced from erc.el (defun erc-log-setup-logging (buffer) @@ -357,13 +346,13 @@ The result is converted to lowercase, as IRC is case-insensitive." buffer target nick server port) erc-log-channels-directory))))) -(defun erc-generate-log-file-name-with-date (buffer &rest ignore) +(defun erc-generate-log-file-name-with-date (buffer &rest _ignore) "This function computes a short log file name. The name of the log file is composed of BUFFER and the current date. This function is a possible value for `erc-generate-log-file-name-function'." (concat (buffer-name buffer) "-" (format-time-string "%Y-%m-%d") ".txt")) -(defun erc-generate-log-file-name-short (buffer &rest ignore) +(defun erc-generate-log-file-name-short (buffer &rest _ignore) "This function computes a short log file name. In fact, it only uses the buffer name of the BUFFER argument, so you can affect that using `rename-buffer' and the-like. This @@ -371,7 +360,7 @@ function is a possible value for `erc-generate-log-file-name-function'." (concat (buffer-name buffer) ".txt")) -(defun erc-generate-log-file-name-long (buffer target nick server port) +(defun erc-generate-log-file-name-long (_buffer target nick server port) "Generates a log-file name in the way ERC always did it. This results in a file name of the form #channel!nick@server:port.txt. This function is a possible value for `erc-generate-log-file-name-function'." @@ -385,7 +374,7 @@ This function is a possible value for `erc-generate-log-file-name-function'." (declare-function erc-network-name "erc-networks" ()) -(defun erc-generate-log-file-name-network (buffer target nick server port) +(defun erc-generate-log-file-name-network (buffer target nick server _port) "Generates a log-file name using the network name rather than server name. This results in a file name of the form #channel!nick@network.txt. This function is a possible value for `erc-generate-log-file-name-function'." diff --git a/lisp/erc/erc-match.el b/lisp/erc/erc-match.el index eede15c11a..43fbca3e66 100644 --- a/lisp/erc/erc-match.el +++ b/lisp/erc/erc-match.el @@ -1,4 +1,4 @@ -;;; erc-match.el --- Highlight messages matching certain regexps +;;; erc-match.el --- Highlight messages matching certain regexps -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. @@ -52,19 +52,17 @@ they are hidden or highlighted. This is controlled via the variables `erc-current-nick-highlight-type'. For all these highlighting types, you can decide whether the entire message or only the sending nick is highlighted." - ((add-hook 'erc-insert-modify-hook 'erc-match-message 'append)) - ((remove-hook 'erc-insert-modify-hook 'erc-match-message))) + ((add-hook 'erc-insert-modify-hook #'erc-match-message 'append)) + ((remove-hook 'erc-insert-modify-hook #'erc-match-message))) ;; Remaining customizations (defcustom erc-pals nil "List of pals on IRC." - :group 'erc-match :type '(repeat regexp)) (defcustom erc-fools nil "List of fools on IRC." - :group 'erc-match :type '(repeat regexp)) (defcustom erc-keywords nil @@ -72,14 +70,12 @@ highlighted." Each entry in the list is either a regexp, or a cons cell with the regexp in the car and the face to use in the cdr. If no face is specified, `erc-keyword-face' is used." - :group 'erc-match :type '(repeat (choice regexp (list regexp face)))) (defcustom erc-dangerous-hosts nil "List of regexps for hosts to highlight. Useful to mark nicks from dangerous hosts." - :group 'erc-match :type '(repeat regexp)) (defcustom erc-current-nick-highlight-type 'keyword @@ -99,7 +95,6 @@ The following values are allowed: current nickname occurs Any other value disables highlighting of current nickname altogether." - :group 'erc-match :type '(choice (const nil) (const nick) (const keyword) @@ -120,7 +115,6 @@ The following values are allowed: from pal Any other value disables pal highlighting altogether." - :group 'erc-match :type '(choice (const nil) (const nick) (const message) @@ -139,7 +133,6 @@ The following values are allowed: from fool Any other value disables fool highlighting altogether." - :group 'erc-match :type '(choice (const nil) (const nick) (const message) @@ -157,7 +150,6 @@ The following values are allowed: containing keyword Any other value disables keyword highlighting altogether." - :group 'erc-match :type '(choice (const nil) (const keyword) (const message) @@ -175,7 +167,6 @@ The following values are allowed: from dangerous-host Any other value disables dangerous-host highlighting altogether." - :group 'erc-match :type '(choice (const nil) (const nick) (const message) @@ -193,7 +184,6 @@ Valid match type keys are: The other element of each cons pair in this list is the buffer name to use for the logged message." - :group 'erc-match :type '(repeat (cons (choice :tag "Key" (const keyword) (const pal) @@ -207,7 +197,6 @@ use for the logged message." When nil, don't log any matched messages. When t, log messages. When `away', log messages only when away." - :group 'erc-match :type '(choice (const nil) (const away) (const t))) @@ -222,14 +211,12 @@ will be formatted. The various format specs are: %u Nickname!user@host of sender %c Channel in which this was received %m Message" - :group 'erc-match :type 'string) (defcustom erc-beep-match-types '(current-nick) "Types of matches to beep for when a match occurs. The function `erc-beep-on-match' needs to be added to `erc-text-matched-hook' for beeping to work." - :group 'erc-match :type '(choice (repeat :tag "Beep on match" (choice (const current-nick) (const keyword) @@ -244,14 +231,12 @@ Functions in this hook are passed as arguments: \(match-type nick!user@host message) where MATCH-TYPE is a symbol of: current-nick, keyword, pal, dangerous-host, fool." :options '(erc-log-matches erc-hide-fools erc-beep-on-match) - :group 'erc-match :type 'hook) (defcustom erc-match-exclude-server-buffer nil "If true, don't perform match on the server buffer; this is useful for excluding all the things like MOTDs from the server and other miscellaneous functions." - :group 'erc-match :version "24.3" :type 'boolean) @@ -390,7 +375,7 @@ car is the string." (interactive) (erc-remove-entry-from-list 'erc-dangerous-hosts "Delete dangerous-host: ")) -(defun erc-match-current-nick-p (nickuserhost msg) +(defun erc-match-current-nick-p (_nickuserhost msg) "Check whether the current nickname is in MSG. NICKUSERHOST will be ignored." (with-syntax-table erc-match-syntax-table @@ -400,7 +385,7 @@ NICKUSERHOST will be ignored." "\\b") msg)))) -(defun erc-match-pal-p (nickuserhost msg) +(defun erc-match-pal-p (nickuserhost _msg) "Check whether NICKUSERHOST is in `erc-pals'. MSG will be ignored." (and nickuserhost @@ -412,7 +397,7 @@ MSG will be ignored." (or (erc-list-match erc-fools nickuserhost) (erc-match-directed-at-fool-p msg)))) -(defun erc-match-keyword-p (nickuserhost msg) +(defun erc-match-keyword-p (_nickuserhost msg) "Check whether any keyword of `erc-keywords' matches for MSG. NICKUSERHOST will be ignored." (and msg @@ -424,7 +409,7 @@ NICKUSERHOST will be ignored." erc-keywords) msg))) -(defun erc-match-dangerous-host-p (nickuserhost msg) +(defun erc-match-dangerous-host-p (nickuserhost _msg) "Check whether NICKUSERHOST is in `erc-dangerous-hosts'. MSG will be ignored." (and nickuserhost @@ -457,7 +442,7 @@ Use this defun with `erc-insert-modify-hook'." (nickuserhost (erc-get-parsed-vector-nick vector)) (nickname (and nickuserhost (nth 0 (erc-parse-user nickuserhost)))) - (old-pt (point)) + ;; (old-pt (point)) (nick-beg (and nickname (re-search-forward (regexp-quote nickname) (point-max) t) @@ -484,11 +469,12 @@ Use this defun with `erc-insert-modify-hook'." (goto-char (point-min)) (let* ((match-prefix (concat "erc-" match-type)) (match-pred (intern (concat "erc-match-" match-type "-p"))) - (match-htype (eval (intern (concat match-prefix - "-highlight-type")))) + (match-htype (symbol-value (intern (concat match-prefix + "-highlight-type")))) (match-regex (if (string= match-type "current-nick") (regexp-quote (erc-current-nick)) - (eval (intern (concat match-prefix "s"))))) + (symbol-value + (intern (concat match-prefix "s"))))) (match-face (intern (concat match-prefix "-face")))) (when (funcall match-pred nickuserhost message) (cond @@ -601,7 +587,7 @@ See `erc-log-match-format'." (kill-buffer buffer))))) buffer))) -(defun erc-log-matches-come-back (proc parsed) +(defun erc-log-matches-come-back (_proc _parsed) "Display a notice that messages were logged while away." (when (and (erc-away-time) (eq erc-log-matches-flag 'away)) @@ -629,7 +615,7 @@ See `erc-log-match-format'." nil) ; This handler must be run _before_ erc-process-away is. -(add-hook 'erc-server-305-functions 'erc-log-matches-come-back nil) +(add-hook 'erc-server-305-functions #'erc-log-matches-come-back nil) (defun erc-go-to-log-matches-buffer () "Interactively open an erc-log-matches buffer." @@ -642,9 +628,9 @@ See `erc-log-match-format'." (get-buffer (car buffer-cons)))))) (switch-to-buffer buffer-name))) -(define-key erc-mode-map "\C-c\C-k" 'erc-go-to-log-matches-buffer) +(define-key erc-mode-map "\C-c\C-k" #'erc-go-to-log-matches-buffer) -(defun erc-hide-fools (match-type nickuserhost message) +(defun erc-hide-fools (match-type _nickuserhost _message) "Hide foolish comments. This function should be called from `erc-text-matched-hook'." (when (eq match-type 'fool) @@ -652,7 +638,7 @@ This function should be called from `erc-text-matched-hook'." '(invisible intangible) (current-buffer)))) -(defun erc-beep-on-match (match-type nickuserhost message) +(defun erc-beep-on-match (match-type _nickuserhost _message) "Beep when text matches. This function is meant to be called from `erc-text-matched-hook'." (when (member match-type erc-beep-match-types) diff --git a/lisp/erc/erc-menu.el b/lisp/erc/erc-menu.el index d76e0a345e..0dc819fbbb 100644 --- a/lisp/erc/erc-menu.el +++ b/lisp/erc/erc-menu.el @@ -1,4 +1,4 @@ -;; erc-menu.el -- Menu-bar definitions for ERC +;; erc-menu.el -- Menu-bar definitions for ERC -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2002, 2004-2021 Free Software Foundation, Inc. diff --git a/lisp/erc/erc-netsplit.el b/lisp/erc/erc-netsplit.el index 37fc4cf16c..9cfb947003 100644 --- a/lisp/erc/erc-netsplit.el +++ b/lisp/erc/erc-netsplit.el @@ -1,4 +1,4 @@ -;;; erc-netsplit.el --- Reduce JOIN/QUIT messages on netsplits +;;; erc-netsplit.el --- Reduce JOIN/QUIT messages on netsplits -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2004, 2006-2021 Free Software Foundation, Inc. @@ -42,30 +42,27 @@ netsplits, so that it can filter the JOIN messages on a netjoin too." (define-erc-module netsplit nil "This mode hides quit/join messages if a netsplit occurs." ((erc-netsplit-install-message-catalogs) - (add-hook 'erc-server-JOIN-functions 'erc-netsplit-JOIN) - (add-hook 'erc-server-MODE-functions 'erc-netsplit-MODE) - (add-hook 'erc-server-QUIT-functions 'erc-netsplit-QUIT) - (add-hook 'erc-timer-hook 'erc-netsplit-timer)) - ((remove-hook 'erc-server-JOIN-functions 'erc-netsplit-JOIN) - (remove-hook 'erc-server-MODE-functions 'erc-netsplit-MODE) - (remove-hook 'erc-server-QUIT-functions 'erc-netsplit-QUIT) - (remove-hook 'erc-timer-hook 'erc-netsplit-timer))) + (add-hook 'erc-server-JOIN-functions #'erc-netsplit-JOIN) + (add-hook 'erc-server-MODE-functions #'erc-netsplit-MODE) + (add-hook 'erc-server-QUIT-functions #'erc-netsplit-QUIT) + (add-hook 'erc-timer-hook #'erc-netsplit-timer)) + ((remove-hook 'erc-server-JOIN-functions #'erc-netsplit-JOIN) + (remove-hook 'erc-server-MODE-functions #'erc-netsplit-MODE) + (remove-hook 'erc-server-QUIT-functions #'erc-netsplit-QUIT) + (remove-hook 'erc-timer-hook #'erc-netsplit-timer))) (defcustom erc-netsplit-show-server-mode-changes-flag nil "Set to t to enable display of server mode changes." - :group 'erc-netsplit :type 'boolean) (defcustom erc-netsplit-debug nil "If non-nil, debug messages will be shown in the sever buffer." - :group 'erc-netsplit :type 'boolean) (defcustom erc-netsplit-regexp "^[^ @!\"\n]+\\.[^ @!\n]+ [^ @!\n]+\\.[^ @!\"\n]+$" "This regular expression should match quit reasons produced by netsplits." - :group 'erc-netsplit :type 'regexp) (defcustom erc-netsplit-hook nil @@ -190,13 +187,13 @@ join from that split has been detected or not.") (erc-display-message nil 'notice 'active 'netsplit-wholeft ?s (car elt) - ?n (mapconcat 'erc-extract-nick (nthcdr 3 elt) " ") + ?n (mapconcat #'erc-extract-nick (nthcdr 3 elt) " ") ?t (if (nth 2 elt) "(joining)" ""))))) t) -(defalias 'erc-cmd-WL 'erc-cmd-WHOLEFT) +(defalias 'erc-cmd-WL #'erc-cmd-WHOLEFT) (provide 'erc-netsplit) diff --git a/lisp/erc/erc-networks.el b/lisp/erc/erc-networks.el index 9926255e3a..aed02a9e26 100644 --- a/lisp/erc/erc-networks.el +++ b/lisp/erc/erc-networks.el @@ -1,4 +1,4 @@ -;;; erc-networks.el --- IRC networks +;;; erc-networks.el --- IRC networks -*- lexical-binding: t; -*- ;; Copyright (C) 2002, 2004-2021 Free Software Foundation, Inc. @@ -443,7 +443,6 @@ NET is a symbol indicating to which network from `erc-networks-alist' this server corresponds, HOST is the servers hostname and PORTS is either a number, a list of numbers, or a list of port ranges." - :group 'erc-networks :type '(alist :key-type (string :tag "Name") :value-type (group symbol (string :tag "Hostname") @@ -714,7 +713,6 @@ MATCHER is used to find a corresponding network to a server while connected to it. If it is regexp, it's used to match against `erc-server-announced-name'. It can also be a function (predicate). Then it is executed with the server buffer as current-buffer." - :group 'erc-networks :type '(repeat (list :tag "Network" (symbol :tag "Network name") @@ -762,25 +760,25 @@ Return the name of this server's network as a symbol." "Return the name of the current network as a string." (erc-with-server-buffer (symbol-name erc-network))) -(defun erc-set-network-name (proc parsed) +(defun erc-set-network-name (_proc _parsed) "Set `erc-network' to the value returned by `erc-determine-network'." (unless erc-server-connected (setq erc-network (erc-determine-network))) nil) -(defun erc-unset-network-name (nick ip reason) +(defun erc-unset-network-name (_nick _ip _reason) "Set `erc-network' to nil." (setq erc-network nil) nil) (define-erc-module networks nil "Provide data about IRC networks." - ((add-hook 'erc-server-375-functions 'erc-set-network-name) - (add-hook 'erc-server-422-functions 'erc-set-network-name) - (add-hook 'erc-disconnected-hook 'erc-unset-network-name)) - ((remove-hook 'erc-server-375-functions 'erc-set-network-name) - (remove-hook 'erc-server-422-functions 'erc-set-network-name) - (remove-hook 'erc-disconnected-hook 'erc-unset-network-name))) + ((add-hook 'erc-server-375-functions #'erc-set-network-name) + (add-hook 'erc-server-422-functions #'erc-set-network-name) + (add-hook 'erc-disconnected-hook #'erc-unset-network-name)) + ((remove-hook 'erc-server-375-functions #'erc-set-network-name) + (remove-hook 'erc-server-422-functions #'erc-set-network-name) + (remove-hook 'erc-disconnected-hook #'erc-unset-network-name))) (defun erc-ports-list (ports) "Return a list of PORTS. diff --git a/lisp/erc/erc-notify.el b/lisp/erc/erc-notify.el index e133e05a7d..1ed056c277 100644 --- a/lisp/erc/erc-notify.el +++ b/lisp/erc/erc-notify.el @@ -42,20 +42,17 @@ (defcustom erc-notify-list nil "List of nicknames you want to be notified about online/offline status change." - :group 'erc-notify :type '(repeat string)) (defcustom erc-notify-interval 60 "Time interval (in seconds) for checking online status of notified people." - :group 'erc-notify :type 'integer) (defcustom erc-notify-signon-hook nil "Hook run after someone on `erc-notify-list' has signed on. Two arguments are passed to the function, SERVER and NICK, both strings." - :group 'erc-notify :type 'hook :options '(erc-notify-signon)) @@ -63,7 +60,6 @@ strings." "Hook run after someone on `erc-notify-list' has signed off. Two arguments are passed to the function, SERVER and NICK, both strings." - :group 'erc-notify :type 'hook :options '(erc-notify-signoff)) @@ -95,14 +91,14 @@ strings." (define-erc-module notify nil "Periodically check for the online status of certain users and report changes." - ((add-hook 'erc-timer-hook 'erc-notify-timer) - (add-hook 'erc-server-JOIN-functions 'erc-notify-JOIN) - (add-hook 'erc-server-NICK-functions 'erc-notify-NICK) - (add-hook 'erc-server-QUIT-functions 'erc-notify-QUIT)) - ((remove-hook 'erc-timer-hook 'erc-notify-timer) - (remove-hook 'erc-server-JOIN-functions 'erc-notify-JOIN) - (remove-hook 'erc-server-NICK-functions 'erc-notify-NICK) - (remove-hook 'erc-server-QUIT-functions 'erc-notify-QUIT))) + ((add-hook 'erc-timer-hook #'erc-notify-timer) + (add-hook 'erc-server-JOIN-functions #'erc-notify-JOIN) + (add-hook 'erc-server-NICK-functions #'erc-notify-NICK) + (add-hook 'erc-server-QUIT-functions #'erc-notify-QUIT)) + ((remove-hook 'erc-timer-hook #'erc-notify-timer) + (remove-hook 'erc-server-JOIN-functions #'erc-notify-JOIN) + (remove-hook 'erc-server-NICK-functions #'erc-notify-NICK) + (remove-hook 'erc-server-QUIT-functions #'erc-notify-QUIT))) ;;;; Timer handler @@ -137,7 +133,7 @@ changes." (setq erc-last-ison ison-list) t))) (erc-server-send - (concat "ISON " (mapconcat 'identity erc-notify-list " "))) + (concat "ISON " (mapconcat #'identity erc-notify-list " "))) (setq erc-last-ison-time now))) (defun erc-notify-JOIN (proc parsed) @@ -211,7 +207,7 @@ with args, toggle notify status of people." 'notify_current ?l ison)))) ((string= (car args) "-l") (erc-display-message nil 'notice 'active - 'notify_list ?l (mapconcat 'identity erc-notify-list + 'notify_list ?l (mapconcat #'identity erc-notify-list " "))) (t (while args @@ -231,7 +227,7 @@ with args, toggle notify status of people." (setq args (cdr args))) (erc-display-message nil 'notice 'active - 'notify_list ?l (mapconcat 'identity erc-notify-list " ")))) + 'notify_list ?l (mapconcat #'identity erc-notify-list " ")))) t) (autoload 'pcomplete-erc-all-nicks "erc-pcomplete") diff --git a/lisp/erc/erc-page.el b/lisp/erc/erc-page.el index 0cb60f5efa..4c244b7984 100644 --- a/lisp/erc/erc-page.el +++ b/lisp/erc/erc-page.el @@ -1,4 +1,4 @@ -;; erc-page.el - CTCP PAGE support for ERC +;; erc-page.el - CTCP PAGE support for ERC -*- lexical-binding: t; -*- ;; Copyright (C) 2002, 2004, 2006-2021 Free Software Foundation, Inc. @@ -30,6 +30,10 @@ (require 'erc) +(defgroup erc-page nil + "React to CTCP PAGE messages." + :group 'erc) + ;;;###autoload(autoload 'erc-page-mode "erc-page") (define-erc-module page ctcp-page "Process CTCP PAGE requests from IRC." @@ -37,10 +41,6 @@ (erc-define-catalog-entry 'english 'CTCP-PAGE "Page from %n (%u@%h): %m") -(defgroup erc-page nil - "React to CTCP PAGE messages." - :group 'erc) - (defcustom erc-page-function nil "A function to process a \"page\" request. If nil, this prints the page message in the minibuffer and calls @@ -53,20 +53,18 @@ Example for your init file: (lambda (sender msg) (play-sound-file \"/home/alex/elisp/erc/sounds/ni.wav\") (message \"IRC Page from %s: %s\" sender msg)))" - :group 'erc-page :type '(choice (const nil) (function))) -(defcustom erc-ctcp-query-PAGE-hook '(erc-ctcp-query-PAGE) +(defcustom erc-ctcp-query-PAGE-hook (list #'erc-ctcp-query-PAGE) "List of functions to be called when a CTCP PAGE is received. This is called from `erc-process-ctcp-query'. The functions are called with six arguments: PROC NICK LOGIN HOST TO MSG. Note that you can also set `erc-page-function' to a function, which only gets two arguments, SENDER and MSG, so that might be easier to use." - :group 'erc-page :type '(repeat function)) -(defun erc-ctcp-query-PAGE (proc nick login host to msg) +(defun erc-ctcp-query-PAGE (_proc nick login host _to msg) "Deal with an CTCP PAGE query, if `erc-page-mode' is non-nil. This will call `erc-page-function', if defined, or it will just print a message and `beep'. In addition to that, the page message is also @@ -91,7 +89,7 @@ inserted into the server buffer." nil 'notice nil text))) nil) -(defun erc-cmd-PAGE (line &optional force) +(defun erc-cmd-PAGE (line &optional _force) "Send a CTCP page to the user given as the first word in LINE. The rest of LINE is the message to send. Note that you will only receive pages if `erc-page-mode' is on." diff --git a/lisp/erc/erc-pcomplete.el b/lisp/erc/erc-pcomplete.el index e9ebf0a07a..8ea37c7f29 100644 --- a/lisp/erc/erc-pcomplete.el +++ b/lisp/erc/erc-pcomplete.el @@ -1,4 +1,4 @@ -;;; erc-pcomplete.el --- Provides programmable completion for ERC +;;; erc-pcomplete.el --- Provides programmable completion for ERC -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2004, 2006-2021 Free Software Foundation, Inc. @@ -50,23 +50,21 @@ (defcustom erc-pcomplete-nick-postfix ":" "When `pcomplete' is used in the first word after the prompt, add this string to nicks completed." - :group 'erc-pcomplete :type 'string) (defcustom erc-pcomplete-order-nickname-completions t "If t, channel nickname completions will be ordered such that the most recent speakers are listed first." - :group 'erc-pcomplete :type 'boolean) ;;;###autoload(autoload 'erc-completion-mode "erc-pcomplete" nil t) (define-erc-module pcomplete Completion "In ERC Completion mode, the TAB key does completion whenever possible." - ((add-hook 'erc-mode-hook 'pcomplete-erc-setup) - (add-hook 'erc-complete-functions 'erc-pcompletions-at-point) + ((add-hook 'erc-mode-hook #'pcomplete-erc-setup) + (add-hook 'erc-complete-functions #'erc-pcompletions-at-point) (erc-buffer-list #'pcomplete-erc-setup)) - ((remove-hook 'erc-mode-hook 'pcomplete-erc-setup) - (remove-hook 'erc-complete-functions 'erc-pcompletions-at-point))) + ((remove-hook 'erc-mode-hook #'pcomplete-erc-setup) + (remove-hook 'erc-complete-functions #'erc-pcompletions-at-point))) (defun erc-pcompletions-at-point () "ERC completion data from pcomplete. @@ -154,7 +152,7 @@ for use on `completion-at-point-function'." (defun pcomplete/erc-mode/NAMES () (while (pcomplete-here (pcomplete-erc-channels)))) -(defalias 'pcomplete/erc-mode/NOTICE 'pcomplete/erc-mode/MSG) +(defalias 'pcomplete/erc-mode/NOTICE #'pcomplete/erc-mode/MSG) (defun pcomplete/erc-mode/OP () (while (pcomplete-here (pcomplete-erc-not-ops)))) @@ -162,7 +160,7 @@ for use on `completion-at-point-function'." (defun pcomplete/erc-mode/PART () (pcomplete-here (pcomplete-erc-channels))) -(defalias 'pcomplete/erc-mode/LEAVE 'pcomplete/erc-mode/PART) +(defalias 'pcomplete/erc-mode/LEAVE #'pcomplete/erc-mode/PART) (defun pcomplete/erc-mode/QUERY () (pcomplete-here (append (pcomplete-erc-all-nicks) diff --git a/lisp/erc/erc-replace.el b/lisp/erc/erc-replace.el index c67d751403..d08d9850c1 100644 --- a/lisp/erc/erc-replace.el +++ b/lisp/erc/erc-replace.el @@ -1,4 +1,4 @@ -;; erc-replace.el -- wash and massage messages inserted into the buffer +;; erc-replace.el -- wash and massage messages inserted into the buffer -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2002, 2004, 2006-2021 Free Software Foundation, ;; Inc. @@ -49,7 +49,6 @@ expression or a variable, or any sexp, TO can be a string or a function to call, or any sexp. If a function, it will be called with one argument, the string to be replaced, and it should return a replacement string." - :group 'erc-replace :type '(repeat (cons :tag "Search & Replace" (choice :tag "From" regexp @@ -68,23 +67,23 @@ It replaces text according to `erc-replace-alist'." (let ((from (car elt)) (to (cdr elt))) (unless (stringp from) - (setq from (eval from))) + (setq from (eval from t))) (while (re-search-forward from nil t) (cond ((stringp to) (replace-match to)) - ((and (symbolp to) (fboundp to)) + ((functionp to) (replace-match (funcall to (match-string 0)))) (t - (eval to)))))) + (eval to t)))))) erc-replace-alist)) ;;;###autoload(autoload 'erc-replace-mode "erc-replace") (define-erc-module replace nil "This mode replaces incoming text according to `erc-replace-alist'." ((add-hook 'erc-insert-modify-hook - 'erc-replace-insert)) + #'erc-replace-insert)) ((remove-hook 'erc-insert-modify-hook - 'erc-replace-insert))) + #'erc-replace-insert))) (provide 'erc-replace) diff --git a/lisp/erc/erc-ring.el b/lisp/erc/erc-ring.el index 028ab1eead..28299ae46c 100644 --- a/lisp/erc/erc-ring.el +++ b/lisp/erc/erc-ring.el @@ -1,4 +1,4 @@ -;; erc-ring.el -- Command history handling for erc using ring.el +;; erc-ring.el -- Command history handling for erc using ring.el -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2004, 2006-2021 Free Software Foundation, Inc. @@ -46,12 +46,12 @@ (define-erc-module ring nil "Stores input in a ring so that previous commands and messages can be recalled using M-p and M-n." - ((add-hook 'erc-pre-send-functions 'erc-add-to-input-ring) - (define-key erc-mode-map "\M-p" 'erc-previous-command) - (define-key erc-mode-map "\M-n" 'erc-next-command)) - ((remove-hook 'erc-pre-send-functions 'erc-add-to-input-ring) - (define-key erc-mode-map "\M-p" 'undefined) - (define-key erc-mode-map "\M-n" 'undefined))) + ((add-hook 'erc-pre-send-functions #'erc-add-to-input-ring) + (define-key erc-mode-map "\M-p" #'erc-previous-command) + (define-key erc-mode-map "\M-n" #'erc-next-command)) + ((remove-hook 'erc-pre-send-functions #'erc-add-to-input-ring) + (define-key erc-mode-map "\M-p" #'undefined) + (define-key erc-mode-map "\M-n" #'undefined))) (defvar-local erc-input-ring nil "Input ring for erc.") diff --git a/lisp/erc/erc-services.el b/lisp/erc/erc-services.el index 9ef8b7f46a..09d1f7a330 100644 --- a/lisp/erc/erc-services.el +++ b/lisp/erc/erc-services.el @@ -91,7 +91,6 @@ Possible settings are:. nil - Disables automatic Nickserv identification. You can also use \\[erc-nickserv-identify-mode] to change modes." - :group 'erc-services :type '(choice (const autodetect) (const nick-change) (const both) @@ -107,13 +106,13 @@ You can also use \\[erc-nickserv-identify-mode] to change modes." "This mode automates communication with services." ((erc-nickserv-identify-mode erc-nickserv-identify-mode)) ((remove-hook 'erc-server-NOTICE-functions - 'erc-nickserv-identify-autodetect) + #'erc-nickserv-identify-autodetect) (remove-hook 'erc-after-connect - 'erc-nickserv-identify-on-connect) + #'erc-nickserv-identify-on-connect) (remove-hook 'erc-nick-changed-functions - 'erc-nickserv-identify-on-nick-change) + #'erc-nickserv-identify-on-nick-change) (remove-hook 'erc-server-NOTICE-functions - 'erc-nickserv-identification-autodetect))) + #'erc-nickserv-identification-autodetect))) ;;;###autoload (defun erc-nickserv-identify-mode (mode) @@ -123,7 +122,7 @@ You can also use \\[erc-nickserv-identify-mode] to change modes." "Choose Nickserv identify mode (RET to disable): " '(("autodetect") ("nick-change") ("both")) nil t)))) (add-hook 'erc-server-NOTICE-functions - 'erc-nickserv-identification-autodetect) + #'erc-nickserv-identification-autodetect) (unless erc-networks-mode ;; Force-enable networks module, because we need it to set ;; erc-network for us. @@ -131,41 +130,40 @@ You can also use \\[erc-nickserv-identify-mode] to change modes." (cond ((eq mode 'autodetect) (setq erc-nickserv-identify-mode 'autodetect) (add-hook 'erc-server-NOTICE-functions - 'erc-nickserv-identify-autodetect) + #'erc-nickserv-identify-autodetect) (remove-hook 'erc-nick-changed-functions - 'erc-nickserv-identify-on-nick-change) + #'erc-nickserv-identify-on-nick-change) (remove-hook 'erc-after-connect - 'erc-nickserv-identify-on-connect)) + #'erc-nickserv-identify-on-connect)) ((eq mode 'nick-change) (setq erc-nickserv-identify-mode 'nick-change) (add-hook 'erc-after-connect - 'erc-nickserv-identify-on-connect) + #'erc-nickserv-identify-on-connect) (add-hook 'erc-nick-changed-functions - 'erc-nickserv-identify-on-nick-change) + #'erc-nickserv-identify-on-nick-change) (remove-hook 'erc-server-NOTICE-functions - 'erc-nickserv-identify-autodetect)) + #'erc-nickserv-identify-autodetect)) ((eq mode 'both) (setq erc-nickserv-identify-mode 'both) (add-hook 'erc-server-NOTICE-functions - 'erc-nickserv-identify-autodetect) + #'erc-nickserv-identify-autodetect) (add-hook 'erc-after-connect - 'erc-nickserv-identify-on-connect) + #'erc-nickserv-identify-on-connect) (add-hook 'erc-nick-changed-functions - 'erc-nickserv-identify-on-nick-change)) + #'erc-nickserv-identify-on-nick-change)) (t (setq erc-nickserv-identify-mode nil) (remove-hook 'erc-server-NOTICE-functions - 'erc-nickserv-identify-autodetect) + #'erc-nickserv-identify-autodetect) (remove-hook 'erc-after-connect - 'erc-nickserv-identify-on-connect) + #'erc-nickserv-identify-on-connect) (remove-hook 'erc-nick-changed-functions - 'erc-nickserv-identify-on-nick-change) + #'erc-nickserv-identify-on-nick-change) (remove-hook 'erc-server-NOTICE-functions - 'erc-nickserv-identification-autodetect)))) + #'erc-nickserv-identification-autodetect)))) (defcustom erc-prompt-for-nickserv-password t "Ask for the password when identifying to NickServ." - :group 'erc-services :type 'boolean) (defcustom erc-use-auth-source-for-nickserv-password nil @@ -174,7 +172,6 @@ This option has an no effect if `erc-prompt-for-nickserv-password' is non-nil, and passwords from `erc-nickserv-passwords' take precedence." :version "28.1" - :group 'erc-services :type 'boolean) (defcustom erc-nickserv-passwords nil @@ -187,7 +184,6 @@ Example of use: \\='((freenode ((\"nick-one\" . \"password\") (\"nick-two\" . \"password\"))) (DALnet ((\"nick\" . \"password\")))))" - :group 'erc-services :type '(repeat (list :tag "Network" (choice :tag "Network name" @@ -305,7 +301,6 @@ ANSWER is the command to use for the answer. The default is `privmsg'. SUCCESS-REGEXP is a regular expression matching the message nickserv sends when you've successfully identified. The last two elements are optional." - :group 'erc-services :type '(repeat (list :tag "Nickserv data" (symbol :tag "Network name") @@ -357,7 +352,6 @@ The last two elements are optional." (defcustom erc-nickserv-identified-hook nil "Run this hook when NickServ acknowledged successful identification. Hooks are called with arguments (NETWORK NICK)." - :group 'erc-services :type 'hook) (defun erc-nickserv-identification-autodetect (_proc parsed) diff --git a/lisp/erc/erc-sound.el b/lisp/erc/erc-sound.el index fff1639a9d..92759d206a 100644 --- a/lisp/erc/erc-sound.el +++ b/lisp/erc/erc-sound.el @@ -52,11 +52,11 @@ "In ERC sound mode, the client will respond to CTCP SOUND requests and play sound files as requested." ;; Enable: - ((add-hook 'erc-ctcp-query-SOUND-hook 'erc-ctcp-query-SOUND) - (define-key erc-mode-map "\C-c\C-s" 'erc-toggle-sound)) + ((add-hook 'erc-ctcp-query-SOUND-hook #'erc-ctcp-query-SOUND) + (define-key erc-mode-map "\C-c\C-s" #'erc-toggle-sound)) ;; Disable: - ((remove-hook 'erc-ctcp-query-SOUND-hook 'erc-ctcp-query-SOUND) - (define-key erc-mode-map "\C-c\C-s" 'undefined))) + ((remove-hook 'erc-ctcp-query-SOUND-hook #'erc-ctcp-query-SOUND) + (define-key erc-mode-map "\C-c\C-s" #'undefined))) (erc-define-catalog-entry 'english 'CTCP-SOUND "%n (%u@%h) plays %s:%m") diff --git a/lisp/erc/erc-speedbar.el b/lisp/erc/erc-speedbar.el index c2be23990f..bb85844523 100644 --- a/lisp/erc/erc-speedbar.el +++ b/lisp/erc/erc-speedbar.el @@ -1,4 +1,4 @@ -;;; erc-speedbar.el --- Speedbar support for ERC +;;; erc-speedbar.el --- Speedbar support for ERC -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2004, 2006-2021 Free Software Foundation, Inc. @@ -52,7 +52,6 @@ `activity' - Sort users by channel activity `alphabetical' - Sort users alphabetically nil - Do not sort users" - :group 'erc-speedbar :type '(choice (const :tag "Sort users by channel activity" activity) (const :tag "Sort users alphabetically" alphabetical) (const :tag "Do not sort users" nil))) @@ -67,11 +66,11 @@ nil - Do not sort users" (setq erc-speedbar-key-map (speedbar-make-specialized-keymap)) ;; Basic tree features - (define-key erc-speedbar-key-map "e" 'speedbar-edit-line) - (define-key erc-speedbar-key-map "\C-m" 'speedbar-edit-line) - (define-key erc-speedbar-key-map "+" 'speedbar-expand-line) - (define-key erc-speedbar-key-map "=" 'speedbar-expand-line) - (define-key erc-speedbar-key-map "-" 'speedbar-contract-line)) + (define-key erc-speedbar-key-map "e" #'speedbar-edit-line) + (define-key erc-speedbar-key-map "\C-m" #'speedbar-edit-line) + (define-key erc-speedbar-key-map "+" #'speedbar-expand-line) + (define-key erc-speedbar-key-map "=" #'speedbar-expand-line) + (define-key erc-speedbar-key-map "-" #'speedbar-contract-line)) (speedbar-add-expansion-list '("ERC" erc-speedbar-menu-items erc-speedbar-key-map @@ -124,7 +123,7 @@ This will add a speedbar major display mode." (erc-speedbar-insert-target buffer 0)) (t (ignore))))) -(defun erc-speedbar-server-buttons (directory depth) +(defun erc-speedbar-server-buttons (_directory depth) "Insert the initial list of servers you are connected to." (let ((servers (erc-buffer-list (lambda () @@ -154,7 +153,7 @@ This will add a speedbar major display mode." (t (error "Ooops... not sure what to do"))) (speedbar-center-buffer-smartly)) -(defun erc-speedbar-channel-buttons (directory depth server-buffer) +(defun erc-speedbar-channel-buttons (_directory depth server-buffer) (when (get-buffer server-buffer) (let* ((proc (with-current-buffer server-buffer erc-server-process)) (targets (erc-buffer-list @@ -191,7 +190,7 @@ INDENT is the current indentation level." (save-excursion (end-of-line) (forward-char 1) (let ((modes (with-current-buffer channel - (concat (apply 'concat + (concat (apply #'concat erc-channel-modes) (cond ((and erc-channel-user-limit @@ -314,7 +313,7 @@ The update is only done when the channel is actually expanded already." (t (error "Ooops... not sure what to do"))) (speedbar-center-buffer-smartly)) -(defun erc-speedbar-goto-buffer (text buffer indent) +(defun erc-speedbar-goto-buffer (_text buffer _indent) "When user clicks on TEXT, goto an ERC buffer. The INDENT level is ignored." (if (featurep 'dframe) diff --git a/lisp/erc/erc-spelling.el b/lisp/erc/erc-spelling.el index c18ac5b3ec..950a821e3c 100644 --- a/lisp/erc/erc-spelling.el +++ b/lisp/erc/erc-spelling.el @@ -1,4 +1,4 @@ -;;; erc-spelling.el --- use flyspell in ERC +;;; erc-spelling.el --- use flyspell in ERC -*- lexical-binding: t; -*- ;; Copyright (C) 2005-2021 Free Software Foundation, Inc. @@ -38,10 +38,10 @@ "Enable flyspell mode in ERC buffers." ;; Use erc-connect-pre-hook instead of erc-mode-hook as pre-hook is ;; called AFTER the server buffer is initialized. - ((add-hook 'erc-connect-pre-hook 'erc-spelling-init) + ((add-hook 'erc-connect-pre-hook #'erc-spelling-init) (dolist (buffer (erc-buffer-list)) (erc-spelling-init buffer))) - ((remove-hook 'erc-connect-pre-hook 'erc-spelling-init) + ((remove-hook 'erc-connect-pre-hook #'erc-spelling-init) (dolist (buffer (erc-buffer-list)) (with-current-buffer buffer (flyspell-mode 0))))) @@ -104,7 +104,7 @@ The cadr is the beginning and the caddr is the end." (put 'erc-mode 'flyspell-mode-predicate - 'erc-spelling-flyspell-verify) + #'erc-spelling-flyspell-verify) (provide 'erc-spelling) diff --git a/lisp/erc/erc-stamp.el b/lisp/erc/erc-stamp.el index da91364e9c..31de9e8069 100644 --- a/lisp/erc/erc-stamp.el +++ b/lisp/erc/erc-stamp.el @@ -52,7 +52,6 @@ This string is processed using `format-time-string'. Good examples are \"%T\" and \"%H:%M\". If nil, timestamping is turned off." - :group 'erc-stamp :type '(choice (const nil) (string))) @@ -66,7 +65,6 @@ screen when `erc-insert-timestamp-function' is set to `erc-insert-timestamp-left-and-right'. If nil, timestamping is turned off." - :group 'erc-stamp :type '(choice (const nil) (string))) @@ -80,7 +78,6 @@ screen when `erc-insert-timestamp-function' is set to `erc-insert-timestamp-left-and-right'. If nil, timestamping is turned off." - :group 'erc-stamp :type '(choice (const nil) (string))) @@ -95,7 +92,6 @@ operate on. You will probably want to set `erc-insert-away-timestamp-function' to the same value." - :group 'erc-stamp :type '(choice (const :tag "Both sides" erc-insert-timestamp-left-and-right) (const :tag "Right" erc-insert-timestamp-right) (const :tag "Left" erc-insert-timestamp-left) @@ -108,7 +104,6 @@ If nil, timestamping is turned off when away unless `erc-timestamp-format' is set. If `erc-timestamp-format' is set, this will not be used." - :group 'erc-stamp :type '(choice (const nil) (string))) @@ -117,7 +112,6 @@ If `erc-timestamp-format' is set, this will not be used." "Function to use to insert the away timestamp. See `erc-insert-timestamp-function' for details." - :group 'erc-stamp :type '(choice (const :tag "Both sides" erc-insert-timestamp-left-and-right) (const :tag "Right" erc-insert-timestamp-right) (const :tag "Left" erc-insert-timestamp-left) @@ -128,7 +122,6 @@ See `erc-insert-timestamp-function' for details." This is useful for logging, because, although timestamps will be hidden, they will still be present in the logs." - :group 'erc-stamp :type 'boolean) (defcustom erc-echo-timestamps nil @@ -136,20 +129,17 @@ hidden, they will still be present in the logs." Using this variable, you can turn off normal timestamping, and simply move point to an irc message to see its timestamp printed in the minibuffer." - :group 'erc-stamp :type 'boolean) (defcustom erc-echo-timestamp-format "Timestamped %A, %H:%M:%S" "Format string to be used when `erc-echo-timestamps' is non-nil. This string specifies the format of the timestamp being echoed in the minibuffer." - :group 'erc-stamp :type 'string) (defcustom erc-timestamp-intangible nil "Whether the timestamps should be intangible, i.e. prevent the point from entering them and instead jump over them." - :group 'erc-stamp :version "24.5" :type 'boolean) @@ -211,7 +201,6 @@ string of spaces which is the same size as the timestamp is added to the beginning of the line in its place. If you use `erc-insert-timestamp-right', nothing gets inserted in place of the timestamp." - :group 'erc-stamp :type 'boolean) (defcustom erc-timestamp-right-column nil @@ -219,7 +208,6 @@ timestamp." if the timestamp is to be printed to the right. If nil, `erc-insert-timestamp-right' will use other means to determine the correct column." - :group 'erc-stamp :type '(choice (integer :tag "Column number") (const :tag "Unspecified" nil))) @@ -231,7 +219,6 @@ Asian language characters and math symbols) precede a timestamp. A side effect of enabling this is that there will only be one space before a right timestamp in any saved logs." - :group 'erc-stamp :type 'boolean) (defun erc-insert-timestamp-left (string) diff --git a/lisp/erc/erc-status-sidebar.el b/lisp/erc/erc-status-sidebar.el index ff51026088..a75a74bb6f 100644 --- a/lisp/erc/erc-status-sidebar.el +++ b/lisp/erc/erc-status-sidebar.el @@ -1,4 +1,4 @@ -;;; erc-status-sidebar.el --- HexChat-like activity overview for ERC +;;; erc-status-sidebar.el --- HexChat-like activity overview for ERC -*- lexical-binding: t; -*- ;; Copyright (C) 2017, 2020-2021 Free Software Foundation, Inc. @@ -58,36 +58,30 @@ (defcustom erc-status-sidebar-buffer-name "*ERC Status*" "Name of the sidebar buffer." - :type 'string - :group 'erc-status-sidebar) + :type 'string) (defcustom erc-status-sidebar-mode-line-format "ERC Status" "Mode line format for the status sidebar." - :type 'string - :group 'erc-status-sidebar) + :type 'string) (defcustom erc-status-sidebar-header-line-format nil "Header line format for the status sidebar." :type '(choice (const :tag "No header line" nil) - string) - :group 'erc-status-sidebar) + string)) (defcustom erc-status-sidebar-width 15 "Default width of the sidebar (in columns)." - :type 'number - :group 'erc-status-sidebar) + :type 'number) (defcustom erc-status-sidebar-channel-sort 'erc-status-sidebar-default-chansort "Sorting function used to determine order of channels in the sidebar." - :type 'function - :group 'erc-status-sidebar) + :type 'function) (defcustom erc-status-sidebar-channel-format 'erc-status-sidebar-default-chan-format "Function used to format channel names for display in the sidebar." - :type 'function - :group 'erc-status-sidebar) + :type 'function) (defun erc-status-sidebar-display-window () "Display the status buffer in a side window. Return the new window." @@ -152,7 +146,8 @@ containing it on the current frame is closed. See (save-excursion (let ((sidebar-exists (erc-status-sidebar-buffer-exists-p)) (sidebar-buffer (erc-status-sidebar-get-buffer)) - (sidebar-window (erc-status-sidebar-get-window))) + ;; (sidebar-window (erc-status-sidebar-get-window)) + ) (unless sidebar-exists (with-current-buffer sidebar-buffer (erc-status-sidebar-mode) @@ -253,7 +248,7 @@ name stand out." erc-disconnected-hook erc-quit-hook)) -(defun erc-status-sidebar--post-refresh (&rest ignore) +(defun erc-status-sidebar--post-refresh (&rest _ignore) "Schedule sidebar refresh for execution after command stack is cleared. Ignore arguments in IGNORE, allowing this function to be added to @@ -276,7 +271,7 @@ to the `window-configuration-change-hook'." (when (and (eq (selected-window) (erc-status-sidebar-get-window)) (fboundp 'window-preserve-size)) (unless (eq (window-total-width) (window-min-size nil t)) - (apply 'window-preserve-size (selected-window) t t nil)))) + (apply #'window-preserve-size (selected-window) t t nil)))) (define-derived-mode erc-status-sidebar-mode special-mode "ERC Sidebar" "Major mode for ERC status sidebar" @@ -298,8 +293,7 @@ to the `window-configuration-change-hook'." ;; erc-status-sidebar-mode initialization code, so it won't undo the ;; add-hook's we did in the previous expressions. (add-hook 'change-major-mode-hook #'erc-status-sidebar-mode--unhook nil t) - (add-hook 'kill-buffer-hook #'erc-status-sidebar-mode--unhook nil t) - :group 'erc-status-sidebar) + (add-hook 'kill-buffer-hook #'erc-status-sidebar-mode--unhook nil t)) (provide 'erc-status-sidebar) ;;; erc-status-sidebar.el ends here diff --git a/lisp/erc/erc-track.el b/lisp/erc/erc-track.el index a853a36225..8be5555882 100644 --- a/lisp/erc/erc-track.el +++ b/lisp/erc/erc-track.el @@ -60,7 +60,6 @@ The reason for using this default value is to both (1) adhere to the Emacs development guidelines which say not to touch keys of the form C-c C- and also (2) to meet the expectations of long-time ERC users, many of whom rely on these keybindings." - :group 'erc-track :type '(choice (const :tag "Ask, if used already" ask) (const :tag "Enable" t) (const :tag "Disable" nil))) @@ -80,7 +79,6 @@ nil - only the selected frame selected-visible - only the selected frame if it is visible Activity means that there was no user input in the last 10 seconds." - :group 'erc-track :type '(choice (const :tag "All frames" t) (const :tag "All visible frames" visible) (const :tag "Only the selected frame" nil) @@ -89,13 +87,11 @@ Activity means that there was no user input in the last 10 seconds." (defcustom erc-track-exclude nil "A list targets (channel names or query targets) which should not be tracked." - :group 'erc-track :type '(repeat string)) (defcustom erc-track-remove-disconnected-buffers nil "If true, remove buffers associated with a server that is disconnected from `erc-modified-channels-alist'." - :group 'erc-track :type 'boolean) (defcustom erc-track-exclude-types '("NICK" "333" "353") @@ -105,25 +101,21 @@ This list could look like (\"JOIN\" \"PART\"). By default, exclude changes of nicknames (NICK), display of who set the channel topic (333), and listing of users on the current channel (353)." - :group 'erc-track :type 'erc-message-type) (defcustom erc-track-exclude-server-buffer nil "If true, don't perform tracking on the server buffer; this is useful for excluding all the things like MOTDs from the server and other miscellaneous functions." - :group 'erc-track :type 'boolean) (defcustom erc-track-shorten-start 1 "This number specifies the minimum number of characters a channel name in the mode-line should be reduced to." - :group 'erc-track :type 'number) (defcustom erc-track-shorten-cutoff 4 "All channel names longer than this value will be shortened." - :group 'erc-track :type 'number) (defcustom erc-track-shorten-aggressively nil @@ -144,7 +136,6 @@ not compared to #electronica -- only to #vi, therefore it can be shortened even more and the result is #e and #v. This setting is used by `erc-track-shorten-names'." - :group 'erc-track :type '(choice (const :tag "No" nil) (const :tag "Yes" t) (const :tag "Max" max))) @@ -154,7 +145,6 @@ This setting is used by `erc-track-shorten-names'." It takes one argument, CHANNEL-NAMES which is a list of strings. It should return a list of strings of the same number of elements. If nil instead of a function, shortening is disabled." - :group 'erc-track :type '(choice (const :tag "Disabled") function)) @@ -165,14 +155,12 @@ If nil instead of a function, shortening is disabled." This is useful for people that don't use the default mode-line notification but instead use a separate mechanism to provide notification of channel activity." - :group 'erc-track :type 'hook) (defcustom erc-track-use-faces t "Use faces in the mode-line. The faces used are the same as used for text in the buffers. \(e.g. `erc-pal-face' is used if a pal sent a message to that channel.)" - :group 'erc-track :type 'boolean) (defcustom erc-track-faces-priority-list @@ -199,7 +187,6 @@ The faces used are the same as used for text in the buffers. "A list of faces used to highlight active buffer names in the mode line. If a message contains one of the faces in this list, the buffer name will be highlighted using that face. The first matching face is used." - :group 'erc-track :type '(repeat (choice face (repeat :tag "Combination" face)))) @@ -214,7 +201,6 @@ this feature. Note: If you have a lot of faces listed in `erc-track-faces-priority-list', setting this variable might not be very useful." - :group 'erc-track :type '(choice (const nil) (repeat string) (const all))) @@ -237,7 +223,6 @@ message. This gives a rough indication that active conversations are occurring in these channels. The effect may be disabled by setting this variable to nil." - :group 'erc-track :type '(repeat (choice face (repeat :tag "Combination" face)))) @@ -249,7 +234,6 @@ Choices are: `after-modes' - add to the end of `mode-line-modes', t - add to the end of `global-mode-string', nil - don't add to mode line." - :group 'erc-track :type '(choice (const :tag "Just before mode information" before-modes) (const :tag "Just after mode information" after-modes) (const :tag "After all other information" t) @@ -266,7 +250,7 @@ nil - don't add to mode line." (if strings (concat (if (eq erc-track-position-in-mode-line 'after-modes) "[" " [") - (mapconcat 'identity (nreverse strings) ",") + (mapconcat #'identity (nreverse strings) ",") (if (eq erc-track-position-in-mode-line 'before-modes) "] " "]")) "")) @@ -289,20 +273,17 @@ while the buffer was not visible.") (defcustom erc-track-showcount nil "If non-nil, count of unseen messages will be shown for each channel." - :type 'boolean - :group 'erc-track) + :type 'boolean) (defcustom erc-track-showcount-string ":" "The string to display between buffer name and the count in the mode line. The default is a colon, resulting in \"#emacs:9\"." - :type 'string - :group 'erc-track) + :type 'string) (defcustom erc-track-switch-from-erc t "If non-nil, `erc-track-switch-buffer' will return to the last non-erc buffer when there are no more active channels." - :type 'boolean - :group 'erc-track) + :type 'boolean) (defcustom erc-track-switch-direction 'oldest "Direction `erc-track-switch-buffer' should switch. @@ -316,7 +297,6 @@ when there are no more active channels." If set to `importance', the importance is determined by position in `erc-track-faces-priority-list', where first is most important." - :group 'erc-track :type '(choice (const importance) (const oldest) (const newest) @@ -472,9 +452,9 @@ START is the minimum length of the name used." (defvar erc-track-minor-mode-map (make-sparse-keymap) "Keymap for rcirc track minor mode.") -(define-key erc-track-minor-mode-map (kbd "C-c C-@") 'erc-track-switch-buffer) +(define-key erc-track-minor-mode-map (kbd "C-c C-@") #'erc-track-switch-buffer) (define-key erc-track-minor-mode-map (kbd "C-c C-SPC") - 'erc-track-switch-buffer) + #'erc-track-switch-buffer) ;;;###autoload (define-minor-mode erc-track-minor-mode @@ -487,8 +467,7 @@ keybindings will not do anything useful." :init-value nil :lighter "" :keymap erc-track-minor-mode-map - :global t - :group 'erc-track) + :global t) (defun erc-track-minor-mode-maybe (&optional buffer) "Enable `erc-track-minor-mode', depending on `erc-track-enable-keybindings'." @@ -530,17 +509,17 @@ keybindings will not do anything useful." ((when (boundp 'erc-track-when-inactive) (if erc-track-when-inactive (progn - (add-hook 'window-configuration-change-hook 'erc-user-is-active) - (add-hook 'erc-send-completed-hook 'erc-user-is-active) - (add-hook 'erc-server-001-functions 'erc-user-is-active)) + (add-hook 'window-configuration-change-hook #'erc-user-is-active) + (add-hook 'erc-send-completed-hook #'erc-user-is-active) + (add-hook 'erc-server-001-functions #'erc-user-is-active)) (erc-track-add-to-mode-line erc-track-position-in-mode-line) (erc-update-mode-line) (add-hook 'window-configuration-change-hook - 'erc-window-configuration-change) - (add-hook 'erc-insert-post-hook 'erc-track-modified-channels) - (add-hook 'erc-disconnected-hook 'erc-modified-channels-update)) + #'erc-window-configuration-change) + (add-hook 'erc-insert-post-hook #'erc-track-modified-channels) + (add-hook 'erc-disconnected-hook #'erc-modified-channels-update)) ;; enable the tracking keybindings - (add-hook 'erc-connect-pre-hook 'erc-track-minor-mode-maybe) + (add-hook 'erc-connect-pre-hook #'erc-track-minor-mode-maybe) (erc-track-minor-mode-maybe))) ;; Disable: ((when (boundp 'erc-track-when-inactive) @@ -548,23 +527,22 @@ keybindings will not do anything useful." (if erc-track-when-inactive (progn (remove-hook 'window-configuration-change-hook - 'erc-user-is-active) - (remove-hook 'erc-send-completed-hook 'erc-user-is-active) - (remove-hook 'erc-server-001-functions 'erc-user-is-active) - (remove-hook 'erc-timer-hook 'erc-user-is-active)) + #'erc-user-is-active) + (remove-hook 'erc-send-completed-hook #'erc-user-is-active) + (remove-hook 'erc-server-001-functions #'erc-user-is-active) + (remove-hook 'erc-timer-hook #'erc-user-is-active)) (remove-hook 'window-configuration-change-hook - 'erc-window-configuration-change) - (remove-hook 'erc-disconnected-hook 'erc-modified-channels-update) - (remove-hook 'erc-insert-post-hook 'erc-track-modified-channels)) + #'erc-window-configuration-change) + (remove-hook 'erc-disconnected-hook #'erc-modified-channels-update) + (remove-hook 'erc-insert-post-hook #'erc-track-modified-channels)) ;; disable the tracking keybindings - (remove-hook 'erc-connect-pre-hook 'erc-track-minor-mode-maybe) + (remove-hook 'erc-connect-pre-hook #'erc-track-minor-mode-maybe) (when erc-track-minor-mode (erc-track-minor-mode -1))))) (defcustom erc-track-when-inactive nil "Enable channel tracking even for visible buffers, if you are inactive." - :group 'erc-track :type 'boolean :set (lambda (sym val) (if erc-track-mode @@ -705,9 +683,9 @@ Use `erc-make-mode-line-buffer-name' to create buttons." ;; four lists we use to create a new ;; `erc-modified-channels-object' using ;; `erc-make-mode-line-buffer-name'. - (let* ((buffers (mapcar 'car erc-modified-channels-alist)) - (counts (mapcar 'cadr erc-modified-channels-alist)) - (faces (mapcar 'cddr erc-modified-channels-alist)) + (let* ((buffers (mapcar #'car erc-modified-channels-alist)) + (counts (mapcar #'cadr erc-modified-channels-alist)) + (faces (mapcar #'cddr erc-modified-channels-alist)) (long-names (mapcar #'(lambda (buf) (or (buffer-name buf) "")) diff --git a/lisp/erc/erc-truncate.el b/lisp/erc/erc-truncate.el index f4514ca137..ff33fbc557 100644 --- a/lisp/erc/erc-truncate.el +++ b/lisp/erc/erc-truncate.el @@ -1,4 +1,4 @@ -;;; erc-truncate.el --- Functions for truncating ERC buffers +;;; erc-truncate.el --- Functions for truncating ERC buffers -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2004, 2006-2021 Free Software Foundation, Inc. @@ -41,7 +41,6 @@ "Maximum size in chars of each ERC buffer. Used only when auto-truncation is enabled. \(see `erc-truncate-buffer' and `erc-insert-post-hook')." - :group 'erc-truncate :type 'integer) ;;;###autoload(autoload 'erc-truncate-mode "erc-truncate" nil t) @@ -51,9 +50,9 @@ This prevents the query buffer from getting too large, which can bring any grown Emacs to its knees after a few days worth of tracking heavy-traffic channels." ;;enable - ((add-hook 'erc-insert-post-hook 'erc-truncate-buffer)) + ((add-hook 'erc-insert-post-hook #'erc-truncate-buffer)) ;; disable - ((remove-hook 'erc-insert-post-hook 'erc-truncate-buffer))) + ((remove-hook 'erc-insert-post-hook #'erc-truncate-buffer))) ;;;###autoload (defun erc-truncate-buffer-to-size (size &optional buffer) diff --git a/lisp/erc/erc-xdcc.el b/lisp/erc/erc-xdcc.el index db8383ba20..e1b9f0de3a 100644 --- a/lisp/erc/erc-xdcc.el +++ b/lisp/erc/erc-xdcc.el @@ -1,4 +1,4 @@ -;;; erc-xdcc.el --- XDCC file-server support for ERC +;;; erc-xdcc.el --- XDCC file-server support for ERC -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2004, 2006-2021 Free Software Foundation, Inc. @@ -51,7 +51,7 @@ Your friends should issue \"/ctcp yournick XDCC list\" to see this." (defcustom erc-xdcc-help-text '(("Hey " nick ", wondering how this works? Pretty easy.") ("Available commands: XDCC [" - (mapconcat 'car erc-xdcc-handler-alist "|") "]") + (mapconcat #'car erc-xdcc-handler-alist "|") "]") ("Type \"/ctcp " (erc-current-nick) " XDCC list\" to see the list of offered files, then type \"/ctcp " (erc-current-nick) " XDCC send #\" to get a particular file number.")) @@ -82,7 +82,7 @@ being evaluated and should return strings." (defvar erc-ctcp-query-XDCC-hook '(erc-xdcc) "Hook called whenever a CTCP XDCC message is received.") -(defun erc-xdcc (proc nick login host to query) +(defun erc-xdcc (proc nick login host _to query) "Handle incoming CTCP XDCC queries." (when erc-xdcc-verbose-flag (erc-display-message nil 'notice proc @@ -96,15 +96,15 @@ being evaluated and should return strings." (format "Unknown XDCC sub-command, try \"/ctcp %s XDCC help\"" (erc-current-nick)))))) -(defun erc-xdcc-help (proc nick login host args) +(defun erc-xdcc-help (proc nick _login _host _args) "Send basic help information to NICK." (mapc (lambda (msg) (erc-xdcc-reply proc nick - (mapconcat (lambda (elt) (if (stringp elt) elt (eval elt))) msg ""))) + (mapconcat (lambda (elt) (if (stringp elt) elt (eval elt t))) msg ""))) erc-xdcc-help-text)) -(defun erc-xdcc-list (proc nick login host args) +(defun erc-xdcc-list (proc nick _login _host _args) "Show the contents of `erc-xdcc-files' via privmsg to NICK." (if (null erc-xdcc-files) (erc-xdcc-reply proc nick "No files offered, sorry") @@ -117,7 +117,7 @@ being evaluated and should return strings." (setq n (1+ n)) (erc-dcc-file-to-name file))))))) -(defun erc-xdcc-send (proc nick login host args) +(defun erc-xdcc-send (proc nick _login _host args) "Send a file to NICK." (let ((n (string-to-number (car args))) (len (length erc-xdcc-files))) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 939113acc5..bdb1914d7b 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -1,4 +1,4 @@ -;; erc.el --- An Emacs Internet Relay Chat client -*- lexical-binding:t -*- +;;; erc.el --- An Emacs Internet Relay Chat client -*- lexical-binding:t -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -1133,31 +1133,31 @@ which the local user typed." (defvar erc-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\C-m" 'erc-send-current-line) - (define-key map "\C-a" 'erc-bol) - (define-key map [home] 'erc-bol) - (define-key map "\C-c\C-a" 'erc-bol) - (define-key map "\C-c\C-b" 'erc-switch-to-buffer) - (define-key map "\C-c\C-c" 'erc-toggle-interpret-controls) - (define-key map "\C-c\C-d" 'erc-input-action) - (define-key map "\C-c\C-e" 'erc-toggle-ctcp-autoresponse) - (define-key map "\C-c\C-f" 'erc-toggle-flood-control) - (define-key map "\C-c\C-i" 'erc-invite-only-mode) - (define-key map "\C-c\C-j" 'erc-join-channel) - (define-key map "\C-c\C-n" 'erc-channel-names) - (define-key map "\C-c\C-o" 'erc-get-channel-mode-from-keypress) - (define-key map "\C-c\C-p" 'erc-part-from-channel) - (define-key map "\C-c\C-q" 'erc-quit-server) - (define-key map "\C-c\C-r" 'erc-remove-text-properties-region) - (define-key map "\C-c\C-t" 'erc-set-topic) - (define-key map "\C-c\C-u" 'erc-kill-input) - (define-key map "\C-c\C-x" 'erc-quit-server) - (define-key map "\M-\t" 'ispell-complete-word) - (define-key map "\t" 'completion-at-point) + (define-key map "\C-m" #'erc-send-current-line) + (define-key map "\C-a" #'erc-bol) + (define-key map [home] #'erc-bol) + (define-key map "\C-c\C-a" #'erc-bol) + (define-key map "\C-c\C-b" #'erc-switch-to-buffer) + (define-key map "\C-c\C-c" #'erc-toggle-interpret-controls) + (define-key map "\C-c\C-d" #'erc-input-action) + (define-key map "\C-c\C-e" #'erc-toggle-ctcp-autoresponse) + (define-key map "\C-c\C-f" #'erc-toggle-flood-control) + (define-key map "\C-c\C-i" #'erc-invite-only-mode) + (define-key map "\C-c\C-j" #'erc-join-channel) + (define-key map "\C-c\C-n" #'erc-channel-names) + (define-key map "\C-c\C-o" #'erc-get-channel-mode-from-keypress) + (define-key map "\C-c\C-p" #'erc-part-from-channel) + (define-key map "\C-c\C-q" #'erc-quit-server) + (define-key map "\C-c\C-r" #'erc-remove-text-properties-region) + (define-key map "\C-c\C-t" #'erc-set-topic) + (define-key map "\C-c\C-u" #'erc-kill-input) + (define-key map "\C-c\C-x" #'erc-quit-server) + (define-key map "\M-\t" #'ispell-complete-word) + (define-key map "\t" #'completion-at-point) ;; Suppress `font-lock-fontify-block' key binding since it ;; destroys face properties. - (define-key map [remap font-lock-fontify-block] 'undefined) + (define-key map [remap font-lock-fontify-block] #'undefined) map) "ERC keymap.") @@ -1293,6 +1293,9 @@ and disable it otherwise. If called from Lisp, enable the mode if ARG is omitted or nil. %s" name name doc) nil nil nil + ;; FIXME: We don't know if this group exists, so this `:group' may + ;; actually just silence a valid warning about the fact that the var + ;; is not associated with any group. :global ,(not local-p) :group (quote ,group) (if ,mode (,enable) @@ -1313,12 +1316,10 @@ if ARG is omitted or nil. ,@disable-body) ,(when (and alias (not (eq name alias))) `(defalias - (quote - ,(intern + ',(intern (format "erc-%s-mode" - (downcase (symbol-name alias))))) - (quote - ,mode))) + (downcase (symbol-name alias)))) + #',mode)) ;; For find-function and find-variable. (put ',mode 'definition-name ',name) (put ',enable 'definition-name ',name) @@ -1745,7 +1746,7 @@ nil." (ignore res) res))) -(define-obsolete-function-alias 'erc-iswitchb 'erc-switch-to-buffer "25.1") +(define-obsolete-function-alias 'erc-iswitchb #'erc-switch-to-buffer "25.1") (defun erc--switch-to-buffer (&optional arg) (read-buffer "Switch to ERC buffer: " (when (boundp 'erc-modified-channels-alist) @@ -1854,7 +1855,7 @@ removed from the list will be disabled." :get (lambda (sym) ;; replace outdated names with their newer equivalents (erc-migrate-modules (symbol-value sym))) - :initialize 'custom-initialize-default + :initialize #'custom-initialize-default :set (lambda (sym val) ;; disable modules which have just been removed (when (and (boundp 'erc-modules) erc-modules val) @@ -2219,8 +2220,8 @@ be invoked for the values of the other parameters." (erc-open server port nick full-name t password)) ;;;###autoload -(defalias 'erc-select 'erc) -(defalias 'erc-ssl 'erc-tls) +(defalias 'erc-select #'erc) +(defalias 'erc-ssl #'erc-tls) ;;;###autoload (defun erc-tls (&rest r) @@ -2841,14 +2842,14 @@ VALUE is computed by evaluating the rest of LINE in Lisp." (val (read (match-string 2 line)))) (if (boundp var) (progn - (set var (eval val)) + (set var (eval val t)) (erc-display-message nil nil 'active (format "Set %S to %S" var val)) t) (setq var (read (match-string 1 line))) (if (boundp var) (progn - (set var (eval val)) + (set var (eval val t)) (erc-display-message nil nil 'active (format "Set %S to %S" var val)) t) @@ -2870,8 +2871,8 @@ VALUE is computed by evaluating the rest of LINE in Lisp." (current-buffer)) t) (t nil))) -(defalias 'erc-cmd-VAR 'erc-cmd-SET) -(defalias 'erc-cmd-VARIABLE 'erc-cmd-SET) +(defalias 'erc-cmd-VAR #'erc-cmd-SET) +(defalias 'erc-cmd-VARIABLE #'erc-cmd-SET) (put 'erc-cmd-SET 'do-not-parse-args t) (put 'erc-cmd-SET 'process-not-needed t) @@ -2999,7 +3000,7 @@ If no USER argument is specified, list the contents of `erc-ignore-list'." (car user-data)) ops))))) erc-channel-users)) - (setq ops (sort ops 'string-lessp)) + (setq ops (sort ops #'string-lessp)) (if ops (erc-display-message nil 'notice (current-buffer) 'ops @@ -3098,7 +3099,7 @@ For a list of user commands (/join /part, ...): (message "Type C-h m to get additional information about keybindings.") t)) -(defalias 'erc-cmd-H 'erc-cmd-HELP) +(defalias 'erc-cmd-H #'erc-cmd-HELP) (put 'erc-cmd-HELP 'process-not-needed t) (defun erc-server-join-channel (server channel &optional secret) @@ -3144,8 +3145,8 @@ were most recently invited. See also `invitation'." (erc-server-join-channel server chnl key))))) t) -(defalias 'erc-cmd-CHANNEL 'erc-cmd-JOIN) -(defalias 'erc-cmd-J 'erc-cmd-JOIN) +(defalias 'erc-cmd-CHANNEL #'erc-cmd-JOIN) +(defalias 'erc-cmd-J #'erc-cmd-JOIN) (defvar-local erc-channel-new-member-names nil "If non-nil, a names list is currently being received. @@ -3169,7 +3170,7 @@ command." (erc-server-send (concat "NAMES " tgt))) (erc-display-message nil 'error (current-buffer) 'no-default-channel))) t) -(defalias 'erc-cmd-N 'erc-cmd-NAMES) +(defalias 'erc-cmd-N #'erc-cmd-NAMES) (defun erc-cmd-KICK (target &optional reason-or-nick &rest reasonwords) "Kick the user indicated in LINE from the current channel. @@ -3239,7 +3240,7 @@ If SERVER is non-nil, use that, rather than the current server." (erc-log (format "cmd: %s" send)) (erc-server-send send) t)) -(defalias 'erc-cmd-WI 'erc-cmd-WHOIS) +(defalias 'erc-cmd-WI #'erc-cmd-WHOIS) (defun erc-cmd-WHOAMI () "Display whois information about yourself." @@ -3410,7 +3411,7 @@ The rest is the message to send." The rest of LINE is the message to send." (erc-message "PRIVMSG" line)) -(defalias 'erc-cmd-M 'erc-cmd-MSG) +(defalias 'erc-cmd-M #'erc-cmd-MSG) (put 'erc-cmd-MSG 'do-not-parse-args t) (defun erc-cmd-SQUERY (line) @@ -3465,7 +3466,7 @@ Otherwise leave the channel indicated by LINE." (t nil))) (put 'erc-cmd-PART 'do-not-parse-args t) -(defalias 'erc-cmd-LEAVE 'erc-cmd-PART) +(defalias 'erc-cmd-LEAVE #'erc-cmd-PART) (defun erc-cmd-PING (recipient) "Ping RECIPIENT." @@ -3517,7 +3518,7 @@ If USER is omitted, close the current query buffer if one exists ;; currently broken, evil hack to display help anyway ;(erc-delete-query)))) (signal 'wrong-number-of-arguments "")))) -(defalias 'erc-cmd-Q 'erc-cmd-QUERY) +(defalias 'erc-cmd-Q #'erc-cmd-QUERY) (defun erc-quit/part-reason-default () "Default quit/part message." @@ -3612,9 +3613,9 @@ the message given by REASON." t) (t nil))) -(defalias 'erc-cmd-BYE 'erc-cmd-QUIT) -(defalias 'erc-cmd-EXIT 'erc-cmd-QUIT) -(defalias 'erc-cmd-SIGNOFF 'erc-cmd-QUIT) +(defalias 'erc-cmd-BYE #'erc-cmd-QUIT) +(defalias 'erc-cmd-EXIT #'erc-cmd-QUIT) +(defalias 'erc-cmd-SIGNOFF #'erc-cmd-QUIT) (put 'erc-cmd-QUIT 'do-not-parse-args t) (put 'erc-cmd-QUIT 'process-not-needed t) @@ -3633,7 +3634,7 @@ the message given by REASON." (kill-buffer buffer))))) t) -(defalias 'erc-cmd-GQ 'erc-cmd-GQUIT) +(defalias 'erc-cmd-GQ #'erc-cmd-GQUIT) (put 'erc-cmd-GQUIT 'do-not-parse-args t) (put 'erc-cmd-GQUIT 'process-not-needed t) @@ -3731,7 +3732,7 @@ the message given by REASON." (erc-server-send (concat "TIME " args))) t) (t (erc-server-send "TIME")))) -(defalias 'erc-cmd-DATE 'erc-cmd-TIME) +(defalias 'erc-cmd-DATE #'erc-cmd-TIME) (defun erc-cmd-TOPIC (topic) "Set or request the topic for a channel. @@ -3772,7 +3773,7 @@ be displayed." (erc-display-message nil 'error (current-buffer) 'no-target))) t) (t nil))) -(defalias 'erc-cmd-T 'erc-cmd-TOPIC) +(defalias 'erc-cmd-T #'erc-cmd-TOPIC) (put 'erc-cmd-TOPIC 'do-not-parse-args t) (defun erc-cmd-APPENDTOPIC (topic) @@ -3784,7 +3785,7 @@ be displayed." ;; strip trailing ^O (when (string-match "\\(.*\\)\C-o" oldtopic) (erc-cmd-TOPIC (concat (match-string 1 oldtopic) topic))))) -(defalias 'erc-cmd-AT 'erc-cmd-APPENDTOPIC) +(defalias 'erc-cmd-AT #'erc-cmd-APPENDTOPIC) (put 'erc-cmd-APPENDTOPIC 'do-not-parse-args t) (defun erc-cmd-CLEARTOPIC (&optional channel) @@ -3808,6 +3809,8 @@ The property `received-from-server' indicates whether or not the ban list has been requested from the server.") (put 'erc-channel-banlist 'received-from-server nil) +(defvar erc-fill-column) + (defun erc-cmd-BANLIST () "Pretty-print the contents of `erc-channel-banlist'. @@ -3878,7 +3881,7 @@ The ban list is fetched from the server if necessary." (put 'erc-channel-banlist 'received-from-server nil))))) t) -(defalias 'erc-cmd-BL 'erc-cmd-BANLIST) +(defalias 'erc-cmd-BL #'erc-cmd-BANLIST) (defun erc-cmd-MASSUNBAN () "Mass Unban. @@ -3920,7 +3923,7 @@ Unban all currently banned users in the current channel." (erc-group-list bans 3)))) t)))) -(defalias 'erc-cmd-MUB 'erc-cmd-MASSUNBAN) +(defalias 'erc-cmd-MUB #'erc-cmd-MASSUNBAN) ;;;; End of IRC commands @@ -4121,7 +4124,7 @@ This places `point' just after the prompt, or at the beginning of the line." (defun erc-complete-word-at-point () (run-hook-with-args-until-success 'erc-complete-functions)) -(define-obsolete-function-alias 'erc-complete-word 'completion-at-point "24.1") +(define-obsolete-function-alias 'erc-complete-word #'completion-at-point "24.1") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -5169,7 +5172,7 @@ TOPIC string to the current topic." "Sort LIST-OF-STRINGS in lexicographic order. Side-effect free." - (sort (copy-sequence list-of-strings) 'string<)) + (sort (copy-sequence list-of-strings) #'string<)) (defun erc-parse-modes (mode-string) "Parse MODE-STRING into a list. @@ -6106,11 +6109,11 @@ non-nil value is found. ;; time routines -(define-obsolete-function-alias 'erc-string-to-emacs-time 'string-to-number +(define-obsolete-function-alias 'erc-string-to-emacs-time #'string-to-number "27.1") -(defalias 'erc-emacs-time-to-erc-time 'float-time) -(defalias 'erc-current-time 'float-time) +(defalias 'erc-emacs-time-to-erc-time #'float-time) +(defalias 'erc-current-time #'float-time) (defun erc-time-diff (t1 t2) "Return the absolute value of the difference in seconds between T1 and T2." @@ -6892,7 +6895,3 @@ Otherwise, connect to HOST:PORT as USER and /join CHANNEL." (require 'erc-goodies) ;;; erc.el ends here -;; -;; Local Variables: -;; outline-regexp: ";;+" -;; End: commit 050b830b698dfe62737428d35fec80f561692b07 Author: Stefan Kangas Date: Fri Mar 19 02:22:25 2021 +0100 Do interactive mode tagging for finder.el diff --git a/lisp/finder.el b/lisp/finder.el index 3ffbe1c8c3..343739f903 100644 --- a/lisp/finder.el +++ b/lisp/finder.el @@ -415,7 +415,7 @@ FILE should be in a form suitable for passing to `locate-library'." (defun finder-select () "Select item on current line in a Finder buffer." - (interactive) + (interactive nil finder-mode) (let ((key (finder-current-item))) (if (string-match "\\.el$" key) (finder-commentary key) @@ -423,7 +423,7 @@ FILE should be in a form suitable for passing to `locate-library'." (defun finder-mouse-select (event) "Select item in a Finder buffer with the mouse." - (interactive "e") + (interactive "e" finder-mode) (with-current-buffer (window-buffer (posn-window (event-start event))) (goto-char (posn-point (event-start event))) (finder-select))) @@ -441,13 +441,14 @@ FILE should be in a form suitable for passing to `locate-library'." \\[finder-select] more help for the item on the current line \\[finder-exit] exit Finder mode and kill the Finder buffer." :syntax-table finder-mode-syntax-table + :interactive nil (setq buffer-read-only t buffer-undo-list t) (setq-local finder-headmark nil)) (defun finder-summary () "Summarize basic Finder commands." - (interactive) + (interactive nil finder-mode) (message "%s" (substitute-command-keys "\\\\[finder-select] = select, \ @@ -457,7 +458,7 @@ finder directory, \\[finder-exit] = quit, \\[finder-summary] = help"))) (defun finder-exit () "Exit Finder mode. Quit the window and kill all Finder-related buffers." - (interactive) + (interactive nil finder-mode) (quit-window t) (dolist (buf (list finder-buffer "*Finder-package*")) (and (get-buffer buf) (kill-buffer buf)))) commit 6f20f563049b7298f694a0688da973b30060844c Author: Stefan Kangas Date: Fri Mar 19 02:14:10 2021 +0100 Use lexical-binding in finder.el * lisp/finder.el: Use lexical-binding. (finder-mode-map, finder-compile-keywords): Remove unused lexical variables. diff --git a/lisp/finder.el b/lisp/finder.el index 2c3869b508..3ffbe1c8c3 100644 --- a/lisp/finder.el +++ b/lisp/finder.el @@ -1,11 +1,10 @@ -;;; finder.el --- topic & keyword-based code finder +;;; finder.el --- topic & keyword-based code finder -*- lexical-binding: t -*- ;; Copyright (C) 1992, 1997-1999, 2001-2021 Free Software Foundation, ;; Inc. ;; Author: Eric S. Raymond ;; Created: 16 Jun 1992 -;; Version: 1.0 ;; Keywords: help ;; This file is part of GNU Emacs. @@ -78,8 +77,7 @@ Each element has the form (KEYWORD . DESCRIPTION).") (defvar finder-mode-map - (let ((map (make-sparse-keymap)) - (menu-map (make-sparse-keymap "Finder"))) + (let ((map (make-sparse-keymap))) (define-key map " " 'finder-select) (define-key map "f" 'finder-select) (define-key map [follow-link] 'mouse-face) @@ -199,8 +197,7 @@ from; the default is `load-path'." (progress (make-progress-reporter (byte-compile-info "Scanning files for finder") 0 (length files))) - package-override base-name ; processed - summary keywords package version entry desc) + base-name summary keywords package version entry desc) (dolist (elem files) (let* ((d (car elem)) (f (cdr elem)) @@ -230,7 +227,7 @@ from; the default is `load-path'." ;; (push base-name processed) (with-temp-buffer (insert-file-contents (expand-file-name f d)) - (setq keywords (mapcar 'intern (lm-keywords-list)) + (setq keywords (mapcar #'intern (lm-keywords-list)) package (or package-override (let ((str (lm-header "package"))) (if str (intern str))) @@ -290,7 +287,7 @@ from; the default is `load-path'." (defun finder-compile-keywords-make-dist () "Regenerate `finder-inf.el' for the Emacs distribution." - (apply 'finder-compile-keywords command-line-args-left) + (apply #'finder-compile-keywords command-line-args-left) (kill-emacs)) ;;; Now the retrieval code @@ -299,7 +296,7 @@ from; the default is `load-path'." "Insert, at column COLUMN, other args STRINGS." (if (>= (current-column) column) (insert "\n")) (move-to-column column t) - (apply 'insert strings)) + (apply #'insert strings)) (defvar finder-help-echo nil) @@ -316,7 +313,7 @@ from; the default is `load-path'." (keys (nconc (where-is-internal 'finder-mouse-select finder-mode-map) keys1))) - (concat (mapconcat 'key-description keys ", ") + (concat (mapconcat #'key-description keys ", ") ": select item")))) (add-text-properties (line-beginning-position) (line-end-position) @@ -368,7 +365,7 @@ not `finder-known-keywords'." (define-button-type 'finder-xref 'action #'finder-goto-xref) (defun finder-goto-xref (button) - "Jump to a lisp file for the BUTTON at point." + "Jump to a Lisp file for the BUTTON at point." (let* ((file (button-get button 'xref)) (lib (locate-library file))) (if lib (finder-commentary lib) @@ -434,6 +431,7 @@ FILE should be in a form suitable for passing to `locate-library'." ;;;###autoload (defun finder-by-keyword () "Find packages matching a given keyword." + ;; FIXME: Why does this function exist? Should it just be an alias? (interactive) (finder-list-keywords)) commit 0a305dffb8ff9e2513937b4fe75539038769dfc4 Author: Stefan Kangas Date: Fri Mar 19 02:12:01 2021 +0100 Fix a warning due to not preloading facemenu.el * test/src/undo-tests.el (facemenu): Require. diff --git a/test/src/undo-tests.el b/test/src/undo-tests.el index 743209fdac..a658bccf6d 100644 --- a/test/src/undo-tests.el +++ b/test/src/undo-tests.el @@ -46,6 +46,7 @@ ;;; Code: (require 'ert) +(require 'facemenu) (ert-deftest undo-test0 () "Test basics of \\[undo]." commit 47e85dae330447802391334927f7b0f28e485ec0 Author: Stefan Kangas Date: Thu Mar 18 23:36:08 2021 +0100 * lisp/faces.el (help-key-binding): Tweak background. diff --git a/lisp/faces.el b/lisp/faces.el index 7c6d749120..5ae3906acc 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -2816,13 +2816,13 @@ Note: Other faces cannot inherit from the cursor face." (defface help-key-binding '((((class color) (min-colors 88) (background light)) - :background "grey92" :foreground "DarkBlue" + :background "grey96" :foreground "DarkBlue" ;; We use negative thickness of the horizontal box border line to ;; avoid enlarging the height of the echo-area display, which ;; would then move the mode line a few pixels up. :box (:line-width (1 . -1) :color "grey80")) (((class color) (min-colors 88) (background dark)) - :background "grey23" :foreground "LightBlue" + :background "grey19" :foreground "LightBlue" :box (:line-width (1 . -1) :color "grey35")) (((class color grayscale) (background light)) :background "grey90") (((class color grayscale) (background dark)) :background "grey25") commit bd991e3c9bc9c26e641036f52adf82e052d4319c Author: Basil L. Contovounesios Date: Thu Mar 18 21:39:05 2021 +0000 Fix frame-inner-height in non-GUI builds Include tab bar in frame's inner height in non-GUI builds that don't define tab-bar-height. This is consistent with the inclusion of the menu bar in the calculated height. It is also consistent with TTY frames of GUI builds, for which tab-bar-height is always zero anyway (bug#47234). Fix suggested by Eli Zaretskii . * lisp/frame.el (frame-inner-height): Don't assume tab-bar-height is defined in builds --without-x. diff --git a/lisp/frame.el b/lisp/frame.el index 15e46c9e21..b7fd71e905 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -1344,7 +1344,7 @@ FRAME defaults to the selected frame." FRAME defaults to the selected frame." (setq frame (window-normalize-frame frame)) (- (frame-native-height frame) - (tab-bar-height frame t) + (if (fboundp 'tab-bar-height) (tab-bar-height frame t) 0) (* 2 (frame-internal-border-width frame)))) (defun frame-outer-width (&optional frame) commit 236aad4f8c7cbf1f4455a0f034576d48a8d13f53 Author: Stefan Monnier Date: Thu Mar 18 17:54:43 2021 -0400 * lisp/emacs-lisp/cl-macs.el (cl--self-tco): Optimize the "return nil" case diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 73ff4e6fd0..9eabfc63b4 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -2068,6 +2068,8 @@ Like `cl-flet' but the definitions can refer to previous ones. ;; even handle mutually recursive functions. (letrec ((done nil) ;; Non-nil if some TCO happened. + ;; This var always holds the value `nil' until (just before) we + ;; exit the loop. (retvar (make-symbol "retval")) (ofargs (mapcar (lambda (s) (if (memq s cl--lambda-list-keywords) s (make-symbol (symbol-name s)))) @@ -2115,14 +2117,18 @@ Like `cl-flet' but the definitions can refer to previous ones. ;; This returns the value of `exp' but it's ;; only in tail position if it's the ;; last condition. + ;; Note: This may set the var before we + ;; actually exit the loop, but luckily it's + ;; only the case if we set the var to nil, + ;; so it does preserve the invariant that + ;; the var is nil until we exit the loop. `((setq ,retvar ,exp) nil) `(,(funcall opt exp))) cs)) (exps (push (funcall opt-exps exps) cs)))) - (if (eq t (caar cs)) - `(cond . ,(nreverse cs)) - `(cond ,@(nreverse cs) (t (setq ,retvar nil)))))) + ;; No need to set `retvar' to return nil. + `(cond . ,(nreverse cs)))) ((and `(,(or 'let 'let*) ,bindings . ,exps) (guard ;; Note: it's OK for this `let' to shadow any @@ -2134,8 +2140,8 @@ Like `cl-flet' but the definitions can refer to previous ones. ;; tail-called any more. (not (memq var shadowings))))) `(,(car exp) ,bindings . ,(funcall opt-exps exps))) - (_ - `(progn (setq ,retvar ,exp) nil)))))) + ('nil nil) ;No need to set `retvar' to return nil. + (_ `(progn (setq ,retvar ,exp) nil)))))) (let ((optimized-body (funcall opt-exps body))) (if (not done) @@ -2281,7 +2287,7 @@ of `cl-symbol-macrolet' to additionally expand symbol macros." ;; on this behavior (haven't found any yet). ;; Such code should explicitly use `cl-letf' instead, I think. ;; - ;; (`(,(or `let `let*) . ,(or `(,bindings . ,body) dontcare)) + ;; (`(,(or `let `let*) . ,(or `(,bindings . ,body) pcase--dontcare)) ;; (let ((letf nil) (found nil) (nbs ())) ;; (dolist (binding bindings) ;; (let* ((var (if (symbolp binding) binding (car binding))) commit a9a4af6ff18487938f4859418e8e27ffb174af7c Author: Stefan Monnier Date: Thu Mar 18 14:32:36 2021 -0400 * test/lisp/progmodes/cperl-mode-tests.el: Silence warnings (cperl-test-bug-47112): Actually obey the major-mode for the test. diff --git a/test/lisp/progmodes/cperl-mode-tests.el b/test/lisp/progmodes/cperl-mode-tests.el index f0e15022d0..8078e9c9fa 100644 --- a/test/lisp/progmodes/cperl-mode-tests.el +++ b/test/lisp/progmodes/cperl-mode-tests.el @@ -135,6 +135,9 @@ point in the distant past, and is still broken in perl-mode. " (should (equal (nth 3 (syntax-ppss)) nil)) (should (equal (nth 4 (syntax-ppss)) t)))))) +(defvar perl-continued-statement-offset) +(defvar perl-indent-level) + (ert-deftest cperl-test-heredocs () "Test that HERE-docs are fontified with the appropriate face." (require 'perl-mode) @@ -242,7 +245,7 @@ This test relies on the specific layout of the index alist as created by CPerl mode, so skip it for Perl mode." (skip-unless (eq cperl-test-mode #'cperl-mode)) (with-temp-buffer - (insert-file (ert-resource-file "grammar.pl")) + (insert-file-contents (ert-resource-file "grammar.pl")) (cperl-mode) (let ((index (cperl-imenu--create-perl-index)) current-list) @@ -457,8 +460,8 @@ as that quote like operator." (funcall cperl-test-mode) (insert "sub y_max { q:bar:; y _bar_foo_; }") (goto-char (point-min)) - (cperl-update-syntaxification (point-max)) - (font-lock-fontify-buffer) + (syntax-propertize (point-max)) + (font-lock-ensure) (search-forward "max") (should (equal (get-text-property (match-beginning 0) 'face) 'font-lock-function-name-face)) commit 5c93063129de0a2005aac1ffe1c48c372b918634 Author: Juri Linkov Date: Thu Mar 18 20:01:26 2021 +0200 * lisp/newcomment.el: Allow 'comment-continue' with whitespace (bug#47167) * lisp/newcomment.el (comment-region-default-1): Still use 'comment-continue' as a string with whitespace even when 'comment-padright' returns nil. diff --git a/lisp/newcomment.el b/lisp/newcomment.el index ea47eec4fd..a5bfb06795 100644 --- a/lisp/newcomment.el +++ b/lisp/newcomment.el @@ -1300,7 +1300,11 @@ out." (let ((s (comment-padleft comment-end numarg))) (and s (if (string-match comment-end-skip s) s (comment-padright comment-end)))) - (if multi (comment-padright comment-continue numarg)) + (if multi + (or (comment-padright comment-continue numarg) + ;; `comment-padright' returns nil when + ;; `comment-continue' contains only whitespace + (and (stringp comment-continue) comment-continue))) (if multi (comment-padleft (comment-string-reverse comment-continue) numarg)) block commit b0902d926dd837ad06c9c6bbde35a5411a351779 Author: Juri Linkov Date: Thu Mar 18 19:56:45 2021 +0200 * lisp/simple.el (next-error-quit-window): New function (bug#44611). (next-error-found-function): Add it as a choice. diff --git a/etc/NEWS b/etc/NEWS index d5cfed46fb..7b7678280b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1934,6 +1934,12 @@ highlight the current error message in the 'next-error' buffer. This user option can be also customized to keep highlighting on all visited errors, so you can have an overview what errors were already visited. +--- +*** New choice 'next-error-quit-window' for 'next-error-found-function'. +When 'next-error-found-function' is customized to 'next-error-quit-window', +then typing the numeric prefix argument 0 before the command 'next-error' +will quit the source window after visiting the next occurrence. + +++ *** New user option 'tab-first-completion'. If 'tab-always-indent' is 'complete', this new user option can be used to diff --git a/lisp/simple.el b/lisp/simple.el index 37aa650b30..eeef40f384 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -377,11 +377,22 @@ To control which errors are matched, customize the variable (not (eq prev next-error-last-buffer))) (message "Current locus from %s" next-error-last-buffer))))) +(defun next-error-quit-window (from-buffer to-buffer) + "Quit window of FROM-BUFFER when the prefix arg is 0. +Intended to be used in `next-error-found-function'." + (when (and (eq current-prefix-arg 0) from-buffer + (not (eq from-buffer to-buffer))) + (let ((window (get-buffer-window from-buffer))) + (when (window-live-p window) + (quit-restore-window window))))) + (defcustom next-error-found-function #'ignore "Function called when a next locus is found and displayed. Function is called with two arguments: a FROM-BUFFER buffer from which next-error navigated, and a target buffer TO-BUFFER." :type '(choice (const :tag "No default" ignore) + (const :tag "Quit previous window with M-0" + next-error-quit-window) (function :tag "Other function")) :group 'next-error :version "27.1") commit d3dbf017c84959337b61b0f6809f74778b1bffe9 Author: Glenn Morris Date: Thu Mar 18 09:16:10 2021 -0700 ; ChangeLog.3 fix admin/make-tarball.txt: "It's best not to commit these files until the release is actually made" diff --git a/ChangeLog.3 b/ChangeLog.3 index 49071c6f17..ed7704e47f 100644 --- a/ChangeLog.3 +++ b/ChangeLog.3 @@ -1,4 +1,4 @@ -2021-03-18 Eli Zaretskii +2021-03-25 Eli Zaretskii * Version 27.2 released. commit c0be4754d73c5acad6e0e51aadc4eac51557cb6b Author: Glenn Morris Date: Thu Mar 18 09:02:30 2021 -0700 * admin/make-tarball.txt: Be kind to people merging branches. diff --git a/admin/make-tarball.txt b/admin/make-tarball.txt index e644f96202..9caf22d718 100644 --- a/admin/make-tarball.txt +++ b/admin/make-tarball.txt @@ -73,20 +73,23 @@ General steps (for each step, check for possible errors): 3. Set the version number (M-x load-file RET admin/admin.el RET, then M-x set-version RET). For a pretest, start at version .90. After - .99, use .990 (so that it sorts). + .99, use .990 (so that it sorts). Commit the resulting changes + as one, with nothing else included, and using a log message + of the format "Bump Emacs version to ...", so that the commit can + be skipped when merging branches (see admin/gitmerge.el). The final pretest should be a release candidate. Before a release candidate is made, the tasks listed in admin/release-process must be completed. - Set the version number to that of the actual release. Pick a date - about a week from now when you intend to make the release. Use M-x - add-release-logs to add entries to etc/HISTORY and the ChangeLog - file. It's best not to commit these files until the release is - actually made. Merge the entries from (unversioned) ChangeLog - into the top of the current versioned ChangeLog.N and commit that - along with etc/HISTORY. Then you can tag that commit as the - release. + Set the version number to that of the actual release (commit in + one, as described above). Pick a date about a week from now when + you intend to make the release. Use M-x add-release-logs to add + entries to etc/HISTORY and the ChangeLog file. It's best not to + commit these files until the release is actually made. Merge the + entries from (unversioned) ChangeLog into the top of the current + versioned ChangeLog.N and commit that along with etc/HISTORY. + Then you can tag that commit as the release. Name the tar file as emacs-XX.Y-rc1.tar. If all goes well in the following week, you can simply rename the file and use it for the commit b72ddbdfffe87f23461d2ff97b8e6c7984591e92 Merge: 94821a1249 d5b160d7cc Author: Glenn Morris Date: Thu Mar 18 08:52:48 2021 -0700 Merge from origin/emacs-27 d5b160d7cc (tag: emacs-27.2-rc1, origin/emacs-27) Prepare the Emacs 2... 216bd67a4f ; * admin/make-tarball.txt: Advise to remove stale subdire... # Conflicts: # ChangeLog.3 # README # configure.ac # etc/AUTHORS # etc/NEWS # lisp/ldefs-boot.el # msdos/sed2v2.inp # nt/README.W32 commit 94821a1249875547289c42ffae4f4d4b1bf073e8 Merge: 29ca91f3d9 7ae4588bb4 Author: Glenn Morris Date: Thu Mar 18 08:50:32 2021 -0700 ; Merge from origin/emacs-27 The following commit was skipped: 7ae4588bb4 Document that `buffer-string' retains text properties commit 29ca91f3d9ede2026ff2c90c55f78282c33cefc3 Merge: 88ab1d1cc4 a7f95d5244 Author: Glenn Morris Date: Thu Mar 18 08:50:32 2021 -0700 Merge from origin/emacs-27 a7f95d5244 Remove duplicate @table item from ELisp manual be1b3512f7 Fix reference to 'diff-font-lock-syntax' in diff-mode docu... commit 88ab1d1cc465c7403c8d381083835d86c4a6964b Merge: d92b725ffc b9ec6111e2 Author: Glenn Morris Date: Thu Mar 18 08:50:32 2021 -0700 ; Merge from origin/emacs-27 The following commit was skipped: b9ec6111e2 Fix buffer overflow in xbm_scan (bug#47094) commit d92b725ffc95b72b595818216b92184446245e7e Merge: 843eb21573 f60eb988f6 Author: Glenn Morris Date: Thu Mar 18 08:50:32 2021 -0700 Merge from origin/emacs-27 f60eb988f6 Fix typos and omissions for (elisp)Button Buffer Commands 876b95bf90 Teach Rmail about NBSP in "Re:" # Conflicts: # lisp/mail/rmail.el commit 843eb21573baaa7d050c65dfbc1a39546f6432d6 Merge: 52270aa0dc a2960025e8 Author: Glenn Morris Date: Thu Mar 18 08:44:16 2021 -0700 ; Merge from origin/emacs-27 The following commit was skipped: a2960025e8 Revert "* lisp/mouse.el: Fix mouse-1-clock-follows-mouse =... commit d5b160d7cc1d067198b4f691eeae342952e4b097 (tag: refs/tags/emacs-27.2-rc1) Author: Eli Zaretskii Date: Thu Mar 18 08:43:54 2021 -0400 Prepare the Emacs 27.2 release. * etc/HISTORY: Update for Emacs 27.2. * README: * configure.ac: * nt/README.W32: * msdos/sed2v2.inp: Set version to 27.2 diff --git a/ChangeLog.3 b/ChangeLog.3 index 1c0745e9d7..ccc06b85f7 100644 --- a/ChangeLog.3 +++ b/ChangeLog.3 @@ -1,3 +1,378 @@ +2021-03-25 Eli Zaretskii + + * Version 27.2 released. + +2021-03-18 Eli Zaretskii + + * etc/HISTORY: Update for Emacs 27.2. + + * README: + * configure.ac: + * nt/README.W32: + * msdos/sed2v2.inp: Set version to 27.2 + +2021-03-18 Lars Ingebrigtsen + + Document that `buffer-string' retains text properties + + * doc/lispref/text.texi (Buffer Contents): Mention text properties + in the `buffer-string' documentation. + * src/editfns.c (Fbuffer_string): Mention text properties in the + doc string (bug#47220). + + (cherry picked from commit 60af754170f22f5d25510af069ed0ebfec95f992) + +2021-03-17 Fabrice Bauzac + + Remove duplicate @table item from ELisp manual + + * doc/lispref/objects.texi (Special Read Syntax): Remove duplicate + item "#@N" from the table of Special Read Syntax. (Bug#47200) + +2021-03-14 Daniel Martín + + Fix reference to 'diff-font-lock-syntax' in diff-mode documentation + + * doc/emacs/files.texi (Diff Mode): Add the omitted name of the + variable. (Bug#47129) + +2021-03-14 Alan Third + + Fix buffer overflow in xbm_scan (bug#47094) + + * src/image.c (xbm_scan): Ensure reading a string doesn't overflow the + buffer. + + (cherry picked from commit ebc3b25409dd614c1814a0643960452683e37aa3) + +2021-03-13 Matt Armstrong + + Fix typos and omissions for (elisp)Button Buffer Commands + + * doc/lispref/display.texi (Button Buffer Commands): Minor + typo and omission fixes `backward-button' and + `forward-button'. (Bug#47051) + +2021-03-13 Eli Zaretskii + + Teach Rmail about NBSP in "Re:" + + * lisp/mail/rmail.el (rmail-simplified-subject) + (rmail-reply-regexp): Allow NBSP in "RE:" prefixes. + +2021-03-12 Stefan Monnier + + Revert "* lisp/mouse.el: Fix mouse-1-clock-follows-mouse = double" + + This reverts commit 02a5cfce471613f671722b35536d2a78f17b0429. + That commit breaks because of a missing patch to `parse_modifiers_uncached` + in `src/keyboard.c`. IOW, too risky for `emacs-27`. + + Don't merge to `master`. + +2021-03-11 Stefan Monnier + + * lisp/mouse.el: Fix mouse-1-clock-follows-mouse = double + + This functionality was broken by commit 3d5e31eceb9dc1fb62b2b2, + the problem being that we end up considering as distinct the events + `down-double-mouse-1` and `double-down-mouse-1`. + + Reported by Eyal Soha + + (mouse--click-1-maybe-follows-link): Make sure the last element of + the list passed to `event-convert-list` is indeed a "basic" event. + +2021-03-05 Stefan Monnier + + * lisp/emacs-lisp/gv.el (edebug-after): Don't run the getter in the setter + + This fixes bug#46573 which was introduced by commit + d79cf638f278e50c22feb53d6ba556f5ce9d7853. + The new code is a middle ground, which makes sure the instrumentation + point is used (so the coverage checker won't have ghost unreachable + instrumentation points) yet without artificially running the getter + when we only need to run the setter. + +2021-03-05 Masahiro Nakamura + + * doc/misc/tramp.texi (Remote shell setup): Fix reference. (Do not merge) + +2021-03-05 Eli Zaretskii + + Fix initialization of 'while-no-input-ignore-events' + + * src/keyboard.c (syms_of_keyboard_for_pdumper): Don't reset + 'while-no-input-ignore-events' after loading the dump file. + (Bug#46940) + +2021-03-04 Eli Zaretskii + + Update documentation of reading passwords + + * doc/emacs/mini.texi (Passwords): Update to match the modified + implementation. (Bug#46902) Add indexing. + +2021-03-02 Lars Ingebrigtsen + + Improve the 'dired-do-kill-lines' doc string + + * lisp/dired-aux.el (dired-do-kill-lines): Document the FMT + parameter (bug#46867). + + (cherry picked from commit b9cb3b904008a80c69ab433f4851377967b100db) + +2021-02-27 Eli Zaretskii + + Avoid crashes in Mew due to corrupted tool-bar label + + * src/gtkutil.c (update_frame_tool_bar): Don't keep around a + 'char *' pointer to a Lisp string's contents when calling Lisp, + because that could relocate string data; keep the Lisp string + itself instead. This avoids crashes in Mew. (Bug#46791) + +2021-02-25 Stefan Kangas + + * lisp/tooltip.el (tooltip): Doc fix for GTK. + +2021-02-20 Stefan Kangas + + * lisp/help.el (help-for-help-internal): Doc fix; use imperative. + +2021-02-19 Eli Zaretskii + + More accurate documentation of the "r" interactive spec + + * doc/lispref/commands.texi (Interactive Codes): Describe the + effect of 'mark-even-if-inactive'. + +2021-02-19 Stefan Kangas + + Mention the GNU Kind Communications Guidelines in the FAQ + + * doc/misc/efaq.texi (Guidelines for newsgroup postings): Mention + the GNU Kind Communications Guidelines. + +2021-02-18 Ryan Prior (tiny change) + + Allow newlines in password prompts again in comint + + * lisp/comint.el (comint-password-prompt-regexp): Match all + whitespace (including newline) at the end of the passphrase, not + just space and \t (bug#46609). + (comint-watch-for-password-prompt): Remove trailing newlines from + the prompt (bug#46609). + +2021-02-16 Eli Zaretskii + + Avoid point movement when visiting image files + + * lisp/image-mode.el (image-toggle-display-image): Preserve point + around the call to exif-parse-buffer, to prevent it from moving + into the image data. (Bug#46552) + +2021-02-10 Eli Zaretskii + + Avoid assertion violation in callproc.c + + * src/callproc.c (call_process): Avoid assertion violation when + DESTINATION is a cons cell '(:file . "FOO")'. (Bug#46426) + +2021-02-08 Lars Ingebrigtsen + + Clarify "changes" in CONTRIBUTE + + * CONTRIBUTE: Clarify that "changes" doesn't include removing code + (bug#44834). + + (cherry picked from commit 33c9556c9db9b8c62dcd80dd3cc665e669ea66d4) + +2021-02-07 Lars Ingebrigtsen + + Clarify when activate-mark-hook is run + + * doc/lispref/markers.texi (The Mark): + * lisp/simple.el (activate-mark-hook): Clarify when the hook is + run (bug#23444). + +2021-02-07 Eli Zaretskii + + Fix language-environment and font selection on MS-Windows + + These changes improve setting the language-environment and font + selection when MS-Windows returns useless "ZZZ" as the "language + name", which then disrupts all the setup of the locale-dependent + stuff, and in particular font selection. + * lisp/w32-fns.el (w32-charset-info-alist): Add an element for + "iso8859-5", in case LANG is set to something unusable, like + "ZZZ". This allows fonts capable of displaying Cyrillic + characters to be used even when language preferences are screwed. + + * src/w32.c (init_environment): If GetLocaleInfo returns "ZZZ" as + the "language name" for LOCALE_USER_DEFAULT, try again with locale + ID based on what GetUserDefaultUILanguage returns. (Bug#39286) + +2021-02-07 Petteri Hintsanen + + Fix example in Sequence Functions node in the manual + + * doc/lispref/sequences.texi (Sequence Functions): Fix the result + from the example. + +2021-02-06 Eli Zaretskii + + Improve doc string of 'text-scale-adjust' + + * lisp/face-remap.el (text-scale-adjust): Clarify that "default + face height" refers to the 'default' face. (Bug#25168) + +2021-02-06 Lars Ingebrigtsen + + Clarify the indent-rigidly doc string + + * lisp/indent.el (indent-rigidly): Clarify exiting the transient + mode (bug#46296). + +2021-02-06 Martin Rudalics + + Fix two small tab bar issues + + * lisp/cus-start.el (frame-inhibit-implied-resize): Update version tag. + * lisp/frame.el (frame-inner-height): Do not count in tab bar. + +2021-02-05 Eli Zaretskii + + Fix last change in syntax.texi + + * doc/lispref/syntax.texi (Syntax Properties): Fix wording in last + change. (Bug#46274) + +2021-02-05 Lars Ingebrigtsen + + Correct the lispref manual about flushing ppss info + + * doc/lispref/syntax.texi (Syntax Properties): Correct the + information about flushing the state by copying the text from the + doc string (bug#46274). + + (cherry picked from commit ff701ce2b261acce1dfcd1fe137268d87d5eab35) + +2021-02-05 Lars Ingebrigtsen + + Clarify how transient indentation modes are exited in the manual + + * doc/emacs/indent.texi (Indentation Commands): Clarify that the + other keys don't just exit the transient mode, but are also + handled as normally (bug#46296). + +2021-02-04 Dmitry Gutov + + Fix the previous change + + * lisp/progmodes/project.el (project-find-regexp): + Fix the previous change (project-root is not defined in this version). + (project-or-external-find-regexp): Same. + +2021-02-04 Dmitry Gutov + + Bind default-directory to the project root + + * lisp/progmodes/project.el (project-find-regexp): + Bind default-directory to the project root, to save this value + in the resulting buffer (esp. if the project selector was used, + (https://lists.gnu.org/archive/html/emacs-devel/2021-02/msg00140.html). + (project-or-external-find-regexp): Same. + + (cherry picked from commit c07ebfcbe084e8219d8c2588f23f77ba4ef39087) + +2021-02-04 Dmitry Gutov + + Make sure default-directory relates to the originating buffer + + * lisp/progmodes/xref.el (xref--show-xref-buffer): + Pick up default-directory value from the caller + (https://lists.gnu.org/archive/html/emacs-devel/2021-01/msg00551.html). + (xref-show-definitions-buffer-at-bottom): Same. + + (cherry picked from commit 6e73e07a6f5cbdd1c5ae6e0f3fbd0f8f56813f1a) + +2021-02-04 Eli Zaretskii + + Initialize signal descriptions after pdumping + + * src/sysdep.c (init_signals) [!HAVE_DECL_SYS_SIGLIST]: Reinit + sys_siglist also after pdumping. (Bug#46284) + +2021-02-04 Lars Ingebrigtsen + + Clarify the "Sentinels" node in the lispref manual + + * doc/lispref/processes.texi (Sentinels): Mention "run" and that + the strings can be anything (bug#30461). + + (cherry picked from commit 859a4cb6b22f75a3456e29d08fcfe9b8940fbe8b) + +2021-02-04 Alexandre Duret-Lutz (tiny change) + + Fix problem with non-ASCII characters in nnmaildir + + * lisp/gnus/nnmaildir.el (nnmaildir-request-article): Enable + multipart 8bit-content-transfer-encoded files to be displayed + correctly by reading as `raw-text' instead of having Emacs + (incorrectly) decode the files (bug#44307). + +2021-02-02 Eli Zaretskii + + * lisp/window.el (recenter-top-bottom): Clarify doc string. + +2021-01-31 Thomas Fitzsimmons + + url-http.el: Special-case NTLM authentication + + * lisp/url/url-http.el (url-http-handle-authentication): Do not + signal an error on NTLM authorization strings. (Bug#43566) + +2021-01-31 Juri Linkov + + * lisp/isearch.el (isearch-lazy-highlight): Fix defcustom type (bug#46208) + +2021-01-30 Stefan Kangas + + Sync latest SKK-JISYO.L + + * leim/SKK-DIC/SKK-JISYO.L: Sync to current upstream version. + +2021-01-30 Alan Third + + Fix build failure on macOS 10.7 (bug#46036) + + * src/nsfns.m (ns_set_represented_filename): Define the NSNumber in a + more compatible manner. + +2021-01-30 Eli Zaretskii + + Improve documentation of auto-resize-tool/tab-bars + + * src/xdisp.c (syms_of_xdisp) + : Doc fix. (Bug#46178) + +2021-01-29 Dmitry Gutov + + (xref-revert-buffer): Also 'erase-buffer' when handling a user-error + + * lisp/progmodes/xref.el (xref-revert-buffer): + Also 'erase-buffer' when handling a user-error (bug#46042). + + (cherry picked from commit e86b30d6fd04070b86560774ec82392dbe24ca1e) + +2021-01-29 Eli Zaretskii + + Update files for 27.1.91 pretest + + * ChangeLog.3: + * etc/AUTHORS + * lisp/ldefs-boot.el: Update. + 2021-01-29 Eli Zaretskii Bump Emacs version to 27.1.91 @@ -144446,7 +144821,7 @@ This file records repository revisions from commit 9d56a21e6a696ad19ac65c4b405aeca44785884a (exclusive) to -commit 86a2207d9244f7cbef9f91e697ad5fc0ce49ec97 (inclusive). +commit 216bd67a4f40a733cb139ace3af4616bc2702282 (inclusive). See ChangeLog.2 for earlier changes. ;; Local Variables: diff --git a/README b/README index 653d3665b7..6b27b52d0d 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ Copyright (C) 2001-2021 Free Software Foundation, Inc. See the end of the file for license conditions. -This directory tree holds version 27.1.91 of GNU Emacs, the extensible, +This directory tree holds version 27.2 of GNU Emacs, the extensible, customizable, self-documenting real-time display editor. The file INSTALL in this directory says how to build and install GNU diff --git a/configure.ac b/configure.ac index 3e4e0641ac..0b3453202b 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ dnl along with GNU Emacs. If not, see . AC_PREREQ(2.65) dnl Note this is parsed by (at least) make-dist and lisp/cedet/ede/emacs.el. -AC_INIT(GNU Emacs, 27.1.91, bug-gnu-emacs@gnu.org, , https://www.gnu.org/software/emacs/) +AC_INIT(GNU Emacs, 27.2, bug-gnu-emacs@gnu.org, , https://www.gnu.org/software/emacs/) dnl Set emacs_config_options to the options of 'configure', quoted for the shell, dnl and then quoted again for a C string. Separate options with spaces. diff --git a/etc/AUTHORS b/etc/AUTHORS index b06b401231..87802b6fbc 100644 --- a/etc/AUTHORS +++ b/etc/AUTHORS @@ -114,7 +114,7 @@ Alan Shutko: changed diary-lib.el calendar.el bindings.el cal-hebrew.el solar.el Alan Third: wrote dabbrev-tests.el image-transforms-tests.el -and changed nsterm.m nsterm.h nsfns.m ns-win.el nsmenu.m nsimage.m +and changed nsterm.m nsfns.m nsterm.h ns-win.el nsmenu.m nsimage.m image.c macfont.m configure.ac frame.el xdisp.c macos.texi dispextern.h display.texi image.el xterm.c Info.plist.in conf_post.h frame.c frame.h frames.texi and 21 other files @@ -157,6 +157,8 @@ Alexander Vorobiev: changed org-compat.el Alexander Zhuckov: changed ebrowse.c +Alexandre Duret-Lutz: changed nnmaildir.el + Alexandre Garreau: changed message.el Alexandre Julliard: wrote vc-git.el @@ -1026,7 +1028,8 @@ Daniel Lopez: changed progmodes/compile.el Daniel Lublin: changed dns-mode.el -Daniel Martín: changed erc.texi msdos-xtra.texi ns-win.el nsterm.m +Daniel Martín: changed erc.texi files.texi msdos-xtra.texi ns-win.el + nsterm.m Daniel McClanahan: changed lisp-mode.el @@ -1453,7 +1456,7 @@ Eli Zaretskii: wrote [bidirectional display in xdisp.c] [tty menus in term.c] abbrev-tests.el bidi.c biditest.el chartab-tests.el coding-tests.el doc-tests.el etags-tests.el rxvt.el tty-colors.el -and changed xdisp.c msdos.c w32.c display.texi w32fns.c simple.el +and changed xdisp.c w32.c msdos.c display.texi w32fns.c simple.el files.el fileio.c keyboard.c emacs.c w32term.c text.texi w32proc.c dispnew.c files.texi frames.texi lisp.h dispextern.h window.c process.c term.c and 1193 other files @@ -1628,7 +1631,7 @@ Eyal Lotem: changed ido.el Fabián Ezequiel Gallina: wrote progmodes/python.el subr-x-tests.el and changed python-tests.el subr-x.el imenu.el wisent/python.el -Fabrice Bauzac: changed dired-aux.el fixit.texi search.texi +Fabrice Bauzac: changed dired-aux.el fixit.texi objects.texi search.texi Fabrice Niessen: wrote leuven-theme.el and changed org-agenda.el @@ -3077,8 +3080,8 @@ and co-wrote gnus-kill.el gnus-mh.el gnus-msg.el gnus-score.el rfc2047.el svg.el time-date.el and changed gnus.texi process.c subr.el simple.el files.el gnutls.c gnus-ems.el smtpmail.el display.texi url-http.el auth-source.el - gnus-cite.el pop3.el dired.el edebug.el text.texi gnus-xmas.el image.el - image.c gnutls.el nnrss.el and 658 other files + gnus-cite.el pop3.el dired.el text.texi edebug.el gnus-xmas.el image.el + image.c gnutls.el nnrss.el and 662 other files Lars Rasmusson: changed ebrowse.c @@ -3375,7 +3378,7 @@ Martin Pohlack: changed iimage.el pc-select.el Martin Rudalics: changed window.el window.c windows.texi frame.c xdisp.c w32fns.c xterm.c frames.texi w32term.c xfns.c frame.el display.texi - help.el buffer.c window.h cus-start.el frame.h dispnew.c mouse.el + help.el buffer.c cus-start.el window.h frame.h dispnew.c mouse.el nsfns.m gtkutil.c and 208 other files Martin Stjernholm: wrote cc-bytecomp.el @@ -3395,7 +3398,7 @@ and changed ob-emacs-lisp.el Masahiko Sato: wrote vip.el -Masahiro Nakamura: changed ns-win.el nsterm.m w32fns.c +Masahiro Nakamura: changed ns-win.el nsterm.m tramp.texi w32fns.c Masanobu Umeda: wrote metamail.el rmailsort.el timezone.el and co-wrote gnus-kill.el gnus-mh.el gnus-msg.el gnus.el nnbabyl.el @@ -3427,8 +3430,8 @@ Mathieu Othacehe: changed tramp-adb.el Mats Lidell: changed TUTORIAL.sv european.el gnus-art.el org-element.el -Matt Armstrong: changed gnus-topic.el gnus.el message.el net/imap.el - shell.el +Matt Armstrong: changed display.texi gnus-topic.el gnus.el message.el + net/imap.el shell.el Matt Bisson: changed xterm.c @@ -4169,6 +4172,8 @@ Petri Kaurinkoski: changed configure.ac iris4d.h irix6-0.h irix6-5.h Petr Salinger: changed configure.ac gnu-kfreebsd.h +Petteri Hintsanen: changed sequences.texi + Phil Hagelberg: wrote ert-x-tests.el and changed package.el pcmpl-unix.el subr.el @@ -4533,6 +4538,8 @@ Ryan Brown: changed cl-indent.el Ryan Crum: changed json.el +Ryan Prior: changed comint.el + Ryan Thompson: changed advice-tests.el ido.el minibuffer-tests.el minibuffer.el savehist.el tmm.el @@ -4808,9 +4815,8 @@ Stefan Kangas: wrote bookmark-tests.el delim-col-tests.el morse-tests.el tabify-tests.el timezone-tests.el underline-tests.el uudecode-tests.el and changed bookmark.el package.el efaq.texi package.texi ibuffer.el mwheel.el cperl-mode.el fns.c gud.el simple.el subr.el tips.texi - autoinsert.el comint-tests.el control.texi cus-edit.el delim-col.el - dired-aux.el dired-x.el em-term.el emacs-lisp-intro.texi - and 158 other files + SKK-JISYO.L autoinsert.el comint-tests.el control.texi cus-edit.el + delim-col.el dired-aux.el dired-x.el em-term.el and 159 other files Stefan Merten: co-wrote rst.el @@ -5091,8 +5097,8 @@ Thomas Dye: changed org.texi org-bibtex.el ob-R.el org.el Thomas Fitzsimmons: wrote soap-client.el and changed soap-inspect.el ldap.el eudc-vars.el eudc.el eudc.texi - ntlm.el eudcb-ldap.el eudcb-bbdb.el eudc-bob.el eudc-export.el - eudcb-ph.el package.el url-http.el diary-lib.el display.texi + ntlm.el eudcb-ldap.el eudcb-bbdb.el url-http.el eudc-bob.el + eudc-export.el eudcb-ph.el package.el diary-lib.el display.texi eudc-hotlist.el icalendar.el url-auth.el Thomas Horsley: changed cxux-crt0.s cxux.h cxux7.h emacs.c nh3000.h diff --git a/etc/HISTORY b/etc/HISTORY index a6b9f57814..1d6425e938 100644 --- a/etc/HISTORY +++ b/etc/HISTORY @@ -222,6 +222,8 @@ GNU Emacs 26.3 (2019-08-28) emacs-26.3 GNU Emacs 27.1 (2020-08-10) emacs-27.1 +GNU Emacs 27.2 (2021-03-25) emacs-27.2 + ---------------------------------------------------------------------- This file is part of GNU Emacs. diff --git a/etc/NEWS b/etc/NEWS index 9232a308c5..d96925705f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -15,18 +15,6 @@ in older Emacs versions. You can narrow news to a specific version by calling 'view-emacs-news' with a prefix argument or by typing 'C-u C-h C-n'. -Temporary note: -+++ indicates that all relevant manuals in doc/ have been updated. ---- means no change in the manuals is needed. -When you add a new item, use the appropriate mark if you are sure it -applies, and please also update docstrings as needed. - - -* Installation Changes in Emacs 27.2 - - -* Startup Changes in Emacs 27.2 - * Changes in Emacs 27.2 @@ -40,9 +28,6 @@ If set to a non-nil value which isn't a function, resize the mini frame using the new function 'fit-mini-frame-to-buffer' which won't skip leading or trailing empty lines of the buffer. - -* Editing Changes in Emacs 27.2 - * Changes in Specialized Modes and Packages in Emacs 27.2 @@ -50,15 +35,6 @@ skip leading or trailing empty lines of the buffer. *** The user option 'tramp-completion-reread-directory-timeout' is now obsolete. - -* New Modes and Packages in Emacs 27.2 - - -* Incompatible Lisp Changes in Emacs 27.2 - - -* Lisp Changes in Emacs 27.2 - * Changes in Emacs 27.2 on Non-Free Operating Systems diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index a54a447340..0c15d78156 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -38652,10 +38652,19 @@ Zone out, completely." t nil) ;;;;;; "eshell/em-unix.el" "eshell/em-xtra.el" "facemenu.el" "faces.el" ;;;;;; "files.el" "font-core.el" "font-lock.el" "format.el" "frame.el" ;;;;;; "help.el" "hfy-cmap.el" "ibuf-ext.el" "indent.el" "international/characters.el" -;;;;;; "international/charscript.el" "international/cp51932.el" -;;;;;; "international/eucjp-ms.el" "international/mule-cmds.el" -;;;;;; "international/mule-conf.el" "international/mule.el" "isearch.el" -;;;;;; "jit-lock.el" "jka-cmpr-hook.el" "language/burmese.el" "language/cham.el" +;;;;;; "international/charprop.el" "international/charscript.el" +;;;;;; "international/cp51932.el" "international/eucjp-ms.el" "international/mule-cmds.el" +;;;;;; "international/mule-conf.el" "international/mule.el" "international/uni-bidi.el" +;;;;;; "international/uni-brackets.el" "international/uni-category.el" +;;;;;; "international/uni-combining.el" "international/uni-comment.el" +;;;;;; "international/uni-decimal.el" "international/uni-decomposition.el" +;;;;;; "international/uni-digit.el" "international/uni-lowercase.el" +;;;;;; "international/uni-mirrored.el" "international/uni-name.el" +;;;;;; "international/uni-numeric.el" "international/uni-old-name.el" +;;;;;; "international/uni-special-lowercase.el" "international/uni-special-titlecase.el" +;;;;;; "international/uni-special-uppercase.el" "international/uni-titlecase.el" +;;;;;; "international/uni-uppercase.el" "isearch.el" "jit-lock.el" +;;;;;; "jka-cmpr-hook.el" "language/burmese.el" "language/cham.el" ;;;;;; "language/chinese.el" "language/cyrillic.el" "language/czech.el" ;;;;;; "language/english.el" "language/ethiopic.el" "language/european.el" ;;;;;; "language/georgian.el" "language/greek.el" "language/hebrew.el" diff --git a/msdos/sed2v2.inp b/msdos/sed2v2.inp index 04ecee1706..7ecf5cded5 100644 --- a/msdos/sed2v2.inp +++ b/msdos/sed2v2.inp @@ -66,7 +66,7 @@ /^#undef PACKAGE_NAME/s/^.*$/#define PACKAGE_NAME ""/ /^#undef PACKAGE_STRING/s/^.*$/#define PACKAGE_STRING ""/ /^#undef PACKAGE_TARNAME/s/^.*$/#define PACKAGE_TARNAME ""/ -/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "27.1.91"/ +/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "27.2"/ /^#undef SYSTEM_TYPE/s/^.*$/#define SYSTEM_TYPE "ms-dos"/ /^#undef HAVE_DECL_GETENV/s/^.*$/#define HAVE_DECL_GETENV 1/ /^#undef SYS_SIGLIST_DECLARED/s/^.*$/#define SYS_SIGLIST_DECLARED 1/ diff --git a/nt/README.W32 b/nt/README.W32 index a93d780055..8cdabbf5a1 100644 --- a/nt/README.W32 +++ b/nt/README.W32 @@ -1,7 +1,7 @@ Copyright (C) 2001-2021 Free Software Foundation, Inc. See the end of the file for license conditions. - Emacs version 27.1.91 for MS-Windows + Emacs version 27.2 for MS-Windows This README file describes how to set up and run a precompiled distribution of the latest version of GNU Emacs for MS-Windows. You commit 52270aa0dc3313f42986a07413bf5b600d9fecbe Author: Mattias Engdegård Date: Thu Mar 18 13:33:09 2021 +0100 Optimise tail calls in `and` and `or` forms in `cl-labels` functions * lisp/emacs-lisp/cl-macs.el (cl--self-tco): Handle `and` and `or`. * test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs--labels): Add test cases. diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index c38dc44ff6..73ff4e6fd0 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -2100,6 +2100,12 @@ Like `cl-flet' but the definitions can refer to previous ones. (`(progn . ,exps) `(progn . ,(funcall opt-exps exps))) (`(if ,cond ,then . ,else) `(if ,cond ,(funcall opt then) . ,(funcall opt-exps else))) + (`(and . ,exps) `(and . ,(funcall opt-exps exps))) + (`(or ,arg) (funcall opt arg)) + (`(or ,arg . ,args) + (let ((val (make-symbol "val"))) + `(let ((,val ,arg)) + (if ,val ,(funcall opt val) ,(funcall opt `(or . ,args)))))) (`(cond . ,conds) (let ((cs '())) (while conds diff --git a/test/lisp/emacs-lisp/cl-macs-tests.el b/test/lisp/emacs-lisp/cl-macs-tests.el index 2e5f3020b4..df1d26a074 100644 --- a/test/lisp/emacs-lisp/cl-macs-tests.el +++ b/test/lisp/emacs-lisp/cl-macs-tests.el @@ -617,11 +617,26 @@ collection clause." (cl-labels ((len (xs) (if xs (1+ (len (cdr xs))) 0))) (should (equal (len (make-list 42 t)) 42))) - ;; Simple tail-recursive function. - (cl-labels ((len (xs n) (if xs (len (cdr xs) (1+ n)) n))) - (should (equal (len (make-list 42 t) 0) 42)) - ;; Should not bump into stack depth limits. - (should (equal (len (make-list 42000 t) 0) 42000))) + (let ((list-42 (make-list 42 t)) + (list-42k (make-list 42000 t))) + + (cl-labels + ;; Simple tail-recursive function. + ((len (xs n) (if xs (len (cdr xs) (1+ n)) n)) + ;; Slightly obfuscated version to exercise tail calls from + ;; `let', `progn', `and' and `or'. + (len2 (xs n) (or (and (not xs) n) + (let (n1) + (and xs + (progn (setq n1 (1+ n)) + (len2 (cdr xs) n1))))))) + (should (equal (len nil 0) 0)) + (should (equal (len2 nil 0) 0)) + (should (equal (len list-42 0) 42)) + (should (equal (len2 list-42 0) 42)) + ;; Should not bump into stack depth limits. + (should (equal (len list-42k 0) 42000)) + (should (equal (len2 list-42k 0) 42000)))) ;; Check that non-recursive functions are handled more efficiently. (should (pcase (macroexpand '(cl-labels ((f (x) (+ x 1))) (f 5))) commit ce1b4acd71e962b6a72a779ee04cb5aeb6ceb6f2 Author: Michael Albinus Date: Thu Mar 18 12:43:35 2021 +0100 Extend handled events in 'while-no-input-ignore-events' (Bug#47205) * etc/NEWS: Mention changes to 'while-no-input-ignore-events'. * src/keyboard.c (kbd_buffer_store_buffered_event): Handle also Qfile_notify and Qdbus_event as ignore_event. (Bug#47205) diff --git a/etc/NEWS b/etc/NEWS index 20407db0ac..d5cfed46fb 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -532,7 +532,7 @@ It can be used to enable/disable the tab bar individually on each frame independently from the value of 'tab-bar-mode' and 'tab-bar-show'. --- -*** New option 'tab-bar-format' defines a list of tab bar items. +*** New user option 'tab-bar-format' defines a list of tab bar items. When it contains 'tab-bar-format-global' (possibly appended after 'tab-bar-format-align-right'), then after enabling 'display-time-mode' (or any other mode that uses 'global-mode-string') it displays time @@ -558,7 +558,8 @@ It also supports a negative argument. --- *** 'C-x t G' assigns a group name to the tab. 'tab-close-group' can close all tabs that belong to the selected group. -The option 'tab-bar-new-tab-group' defines the default group of a new tab. +The user option 'tab-bar-new-tab-group' defines the default group of a +new tab. --- *** New user option 'tab-bar-tab-name-format-function'. @@ -2257,8 +2258,8 @@ first). ** The 'M-o M-s' and 'M-o M-S' global bindings have been removed. Use 'M-x center-line' and 'M-x center-paragraph' instead. -** The 'M-o M-o' global binding have been removed. -Use 'M-x font-lock-fontify-block' instead, or the new `C-x x f' +** The 'M-o M-o' global binding has been removed. +Use 'M-x font-lock-fontify-block' instead, or the new 'C-x x f' command, which toggles fontification in the current buffer. ** In 'f90-mode', the backslash character ('\') no longer escapes. @@ -2825,6 +2826,11 @@ semantics of RFC 8259 instead of the earlier RFC 4627. In particular, these functions now accept top-level JSON values that are neither arrays nor objects. +--- +** 'while-no-input-ignore-events' accepts more special events. +The special events 'dbus-event' and 'file-notify' are now ignored in +'while-no-input' when added to this variable. + * Changes in Emacs 28.1 on Non-Free Operating Systems diff --git a/src/keyboard.c b/src/keyboard.c index 512fa279b3..266ebaa5fd 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -3614,6 +3614,12 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event, case ICONIFY_EVENT: ignore_event = Qiconify_frame; break; case DEICONIFY_EVENT: ignore_event = Qmake_frame_visible; break; case SELECTION_REQUEST_EVENT: ignore_event = Qselection_request; break; +#ifdef USE_FILE_NOTIFY + case FILE_NOTIFY_EVENT: ignore_event = Qfile_notify; break; +#endif +#ifdef HAVE_DBUS + case DBUS_EVENT: ignore_event = Qdbus_event; break; +#endif default: ignore_event = Qnil; break; } commit 216bd67a4f40a733cb139ace3af4616bc2702282 Author: Eli Zaretskii Date: Thu Mar 18 12:49:02 2021 +0200 ; * admin/make-tarball.txt: Advise to remove stale subdirectories. diff --git a/admin/make-tarball.txt b/admin/make-tarball.txt index 907afbbf5a..bf682ecadf 100644 --- a/admin/make-tarball.txt +++ b/admin/make-tarball.txt @@ -33,6 +33,11 @@ General steps (for each step, check for possible errors): or some form of "git clean -x". It's probably simpler and safer to make a new working directory exclusively for the release branch. + If the working directory has subdirectories created when making + previous releases or pretests, remove those subdirectories, as the + command which updates the ChangeLog file might attempt to recurse + there and scan any ChangeLog.* files there. + Make sure the tree is built, or at least configured. That's because some of the commands below run Make, so they need Makefiles to be present. commit 4d5ad8a16e1fe925dd3fa0993aabb2612a82622b Author: Stefan Kangas Date: Thu Mar 18 11:17:34 2021 +0100 Add comint-password-prompt-regexp test for "zip -e ..." * test/lisp/comint-tests.el (comint-testsuite-password-strings): Add test for "zip -e ...". (Bug#47209) diff --git a/lisp/comint.el b/lisp/comint.el index bb28db7614..65072b0137 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -366,6 +366,8 @@ This variable is buffer-local." ;; OpenBSD doas prints "doas (user@host) password:". ;; See ert test `comint-test-password-regexp'. (defcustom comint-password-prompt-regexp + ;; When extending this, please also add a corresponding test where + ;; possible (see `comint-testsuite-password-strings'). (concat "\\(^ *\\|" (regexp-opt @@ -382,7 +384,7 @@ This variable is buffer-local." "\\(?: [[:alpha:]]+ .+\\)?[[:blank:]]*[::៖][[:space:]]*\\'") "Regexp matching prompts for passwords in the inferior process. This is used by `comint-watch-for-password-prompt'." - :version "27.1" + :version "28.1" :type 'regexp :group 'comint) diff --git a/test/lisp/comint-tests.el b/test/lisp/comint-tests.el index de1bc548e1..8a9a41f452 100644 --- a/test/lisp/comint-tests.el +++ b/test/lisp/comint-tests.el @@ -44,6 +44,7 @@ "Password (again):" "Enter password:" "Enter Auth Password:" ; OpenVPN (Bug#35724) + "Verify password: " ; zip -e zipfile.zip ... (Bug#47209) "Mot de Passe :" ; localized (Bug#29729) "Passwort:") ; localized "List of strings that should match `comint-password-prompt-regexp'.") commit 4eb030319725cfe7fe17049e91fdbed2e222a3c9 Author: Lars Ingebrigtsen Date: Thu Mar 18 11:15:50 2021 +0100 Compute chart-face-list dynamically * lisp/emacs-lisp/chart.el (chart-face-list): Allow a function as the value (bug#47133) so that we can compute the faces dynamically on different displays. (chart--face-list): New function. (chart-draw-data): Use it. diff --git a/lisp/emacs-lisp/chart.el b/lisp/emacs-lisp/chart.el index 40c17b916f..5afc6d3bde 100644 --- a/lisp/emacs-lisp/chart.el +++ b/lisp/emacs-lisp/chart.el @@ -89,33 +89,39 @@ Useful if new Emacs is used on B&W display.") (declare-function x-display-color-cells "xfns.c" (&optional terminal)) -(defvar chart-face-list - (if (display-color-p) - (let ((cl chart-face-color-list) - (pl chart-face-pixmap-list) - (faces ()) - nf) - (while cl - (setq nf (make-face - (intern (concat "chart-" (car cl) "-" (car pl))))) - (set-face-background nf (if (condition-case nil - (> (x-display-color-cells) 4) - (error t)) - (car cl) - "white")) - (set-face-foreground nf "black") - (if (and chart-face-use-pixmaps pl) - (condition-case nil - (set-face-background-pixmap nf (car pl)) - (error (message "Cannot set background pixmap %s" (car pl))))) - (push nf faces) - (setq cl (cdr cl) - pl (cdr pl))) - faces)) +(defvar chart-face-list #'chart--face-list "Faces used to colorize charts. +This should either be a list of faces, or a function that returns +a list of faces. + List is limited currently, which is ok since you really can't display too much in text characters anyways.") +(defun chart--face-list () + (and + (display-color-p) + (let ((cl chart-face-color-list) + (pl chart-face-pixmap-list) + (faces ()) + nf) + (while cl + (setq nf (make-face + (intern (concat "chart-" (car cl) "-" (car pl))))) + (set-face-background nf (if (condition-case nil + (> (x-display-color-cells) 4) + (error t)) + (car cl) + "white")) + (set-face-foreground nf "black") + (if (and chart-face-use-pixmaps pl) + (condition-case nil + (set-face-background-pixmap nf (car pl)) + (error (message "Cannot set background pixmap %s" (car pl))))) + (push nf faces) + (setq cl (cdr cl) + pl (cdr pl))) + faces))) + (define-derived-mode chart-mode special-mode "Chart" "Define a mode in Emacs for displaying a chart." (buffer-disable-undo) @@ -374,7 +380,10 @@ of the drawing." (let* ((data (oref c sequences)) (dir (oref c direction)) (odir (if (eq dir 'vertical) 'horizontal 'vertical)) - ) + (faces + (if (functionp chart-face-list) + (funcall chart-face-list) + chart-face-list))) (while data (if (stringp (car (oref (car data) data))) ;; skip string lists... @@ -390,10 +399,9 @@ of the drawing." (zp (if (eq dir 'vertical) (chart-translate-ypos c 0) (chart-translate-xpos c 0))) - (fc (if chart-face-list - (nth (% i (length chart-face-list)) chart-face-list) - 'default)) - ) + (fc (if faces + (nth (% i (length faces)) faces) + 'default))) (if (< dp zp) (progn (chart-draw-line dir (car rng) dp zp) commit 7ae4588bb4800694d841da1684538191cb291617 Author: Lars Ingebrigtsen Date: Thu Mar 18 05:59:12 2021 +0100 Document that `buffer-string' retains text properties * doc/lispref/text.texi (Buffer Contents): Mention text properties in the `buffer-string' documentation. * src/editfns.c (Fbuffer_string): Mention text properties in the doc string (bug#47220). (cherry picked from commit 60af754170f22f5d25510af069ed0ebfec95f992) diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 89582acd35..6eda581777 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -222,7 +222,9 @@ properties, just the characters themselves. @xref{Text Properties}. @defun buffer-string This function returns the contents of the entire accessible portion of -the current buffer, as a string. +the current buffer, as a string. If the text being copied has any +text properties, these are copied into the string along with the +characters they belong to. @end defun If you need to make sure the resulting string, when copied to a diff --git a/src/editfns.c b/src/editfns.c index 255537cdc6..621e35171d 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -1682,7 +1682,11 @@ they can be in either order. */) DEFUN ("buffer-string", Fbuffer_string, Sbuffer_string, 0, 0, 0, doc: /* Return the contents of the current buffer as a string. If narrowing is in effect, this function returns only the visible part -of the buffer. */) +of the buffer. + +This function copies the text properties of that part of the buffer +into the result string; if you don’t want the text properties, +use `buffer-substring-no-properties' instead. */) (void) { return make_buffer_string_both (BEGV, BEGV_BYTE, ZV, ZV_BYTE, 1); commit 869b3efe1e4b72b060d1eb495e17f28008bcbeaf Author: Lars Ingebrigtsen Date: Thu Mar 18 09:22:28 2021 +0100 Fix breaking undo-test diff --git a/test/src/undo-tests.el b/test/src/undo-tests.el index 055bf102df..743209fdac 100644 --- a/test/src/undo-tests.el +++ b/test/src/undo-tests.el @@ -87,6 +87,7 @@ (ert-deftest undo-test1 () "Test undo of \\[undo] command (redo)." + (require 'facemenu) (with-temp-buffer (buffer-enable-undo) (undo-boundary) commit 790259f01a62c2b09385aa58a84198ea378ba83d Author: Lars Ingebrigtsen Date: Thu Mar 18 08:43:22 2021 +0100 Make "not found" message in dictionary less misleading * lisp/net/dictionary.el (dictionary-do-search): Don't say there are more words when there aren't (bug#47056). diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el index 5938b8146e..f33cbaf112 100644 --- a/lisp/net/dictionary.el +++ b/lisp/net/dictionary.el @@ -721,13 +721,14 @@ of matching words." (if (dictionary-check-reply reply 552) (progn (unless nomatching - (beep) - (insert "Word not found, maybe you are looking " - "for one of these words\n\n") - (dictionary-do-matching word - dictionary - "." - 'dictionary-display-only-match-result) + (insert "Word not found") + (dictionary-do-matching + word + dictionary + "." + (lambda (reply) + (insert ", maybe you are looking for one of these words\n\n") + (dictionary-display-only-match-result reply))) (dictionary-post-buffer))) (if (dictionary-check-reply reply 550) (error "Dictionary \"%s\" is unknown, please select an existing one" @@ -1074,7 +1075,6 @@ If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." (defun dictionary-display-only-match-result (reply) "Display the results from the current matches in REPLY without the headers." - (let ((number (nth 1 (dictionary-reply-list reply))) (list (dictionary-simple-split-string (dictionary-read-answer) "\n+"))) (insert number " matching word" (if (equal number "1") "" "s") commit 21e1a126b54390b5a22e5af836d14ae8f4e423fb Author: Lars Ingebrigtsen Date: Thu Mar 18 08:33:40 2021 +0100 Make memory-report work with buffer-local unbound vars * lisp/emacs-lisp/memory-report.el (memory-report--buffer-data): Protect against buffer-local unbound variables (bug#47057). diff --git a/lisp/emacs-lisp/memory-report.el b/lisp/emacs-lisp/memory-report.el index 3d6ca957e6..ecbca280e5 100644 --- a/lisp/emacs-lisp/memory-report.el +++ b/lisp/emacs-lisp/memory-report.el @@ -295,7 +295,7 @@ by counted more than once." (- (position-bytes (point-min))) (gap-size))) (seq-reduce #'+ (mapcar (lambda (elem) - (if (cdr elem) + (if (and (consp elem) (cdr elem)) (memory-report--object-size (make-hash-table :test #'eq) (cdr elem)) commit 1e00906926325a85649394f201f575c4e3170637 Author: Lars Ingebrigtsen Date: Thu Mar 18 08:25:17 2021 +0100 Fix sorting in speedbar sub-groups * lisp/speedbar.el (speedbar-prefix-group-tag-hierarchy): Sort entries in sub-groups (bug#47073). diff --git a/lisp/speedbar.el b/lisp/speedbar.el index 6c4c8eb813..12e57b1108 100644 --- a/lisp/speedbar.el +++ b/lisp/speedbar.el @@ -2159,10 +2159,13 @@ passes some tests." ;; way by displaying the range over which we ;; have grouped them. (setq work-list - (cons (cons (concat short-start-name - " to " - short-end-name) - short-group-list) + (cons (cons + (concat short-start-name + " to " short-end-name) + (sort (copy-sequence short-group-list) + (lambda (e1 e2) + (string< (car e1) + (car e2))))) work-list)))) ;; Reset short group list information every time. (setq short-group-list nil commit 8ad87812cfe5638e8b1ffd17bedd49ab3512a2f3 Author: Gabriel do Nascimento Ribeiro Date: Thu Mar 18 08:10:52 2021 +0100 lisp/cedet/pulse.el: Use color.el * lisp/cedet/pulse.el: (pulse-int-to-hex): Remove function. (pulse-color-values-to-hex): Remove function. (pulse-lighten-highlight): Remove function. (pulse-momentary-iteration): Add variable. (pulse-momentary-highlight-overlay): Use color-gradient from color.el. (pulse-tick): Receive colors and update overlay background (bug#47083). diff --git a/lisp/cedet/pulse.el b/lisp/cedet/pulse.el index cfd2152162..d77d635f97 100644 --- a/lisp/cedet/pulse.el +++ b/lisp/cedet/pulse.el @@ -30,10 +30,9 @@ ;; ;; The following are useful entry points: ;; -;; `pulse' - Cause `pulse-highlight-face' to shift toward background color. +;; `pulse-tick' - Cause `pulse-highlight-face' to shift toward background color. ;; Assumes you are using a version of Emacs that supports pulsing. ;; -;; ;; `pulse-momentary-highlight-one-line' - Pulse a single line at POINT. ;; `pulse-momentary-highlight-region' - Pulse a region. ;; `pulse-momentary-highlight-overlay' - Pulse an overlay. @@ -50,7 +49,9 @@ ;; ;; Pulse is a part of CEDET. http://cedet.sf.net -(defun pulse-available-p () +(require 'color) + +(defun pulse-available-p () "Return non-nil if pulsing is available on the current frame." (condition-case nil (let ((v (color-values (face-background 'default)))) @@ -90,69 +91,27 @@ Face used for temporary highlighting of tags for effect." :group 'pulse) ;;; Code: -;; -(defun pulse-int-to-hex (int &optional nb-digits) - "Convert integer argument INT to a #XXXXXXXXXXXX format hex string. -Each X in the output string is a hexadecimal digit. -NB-DIGITS is the number of hex digits. If INT is too large to be -represented with NB-DIGITS, then the result is truncated from the -left. So, for example, INT=256 and NB-DIGITS=2 returns \"00\", since -the hex equivalent of 256 decimal is 100, which is more than 2 digits. - -This function was blindly copied from hexrgb.el by Drew Adams. -https://www.emacswiki.org/emacs/hexrgb.el" - (setq nb-digits (or nb-digits 4)) - (substring (format (concat "%0" (int-to-string nb-digits) "X") int) (- nb-digits))) - -(defun pulse-color-values-to-hex (values) - "Convert list of rgb color VALUES to a hex string, #XXXXXXXXXXXX. -Each X in the string is a hexadecimal digit. -Input VALUES is as for the output of `x-color-values'. - -This function was blindly copied from hexrgb.el by Drew Adams. -https://www.emacswiki.org/emacs/hexrgb.el" - (concat "#" - (pulse-int-to-hex (nth 0 values) 4) ; red - (pulse-int-to-hex (nth 1 values) 4) ; green - (pulse-int-to-hex (nth 2 values) 4))) ; blue (defcustom pulse-iterations 10 "Number of iterations in a pulse operation." :group 'pulse :type 'number) + (defcustom pulse-delay .03 "Delay between face lightening iterations." :group 'pulse :type 'number) -(defun pulse-lighten-highlight () - "Lighten the face by 1/`pulse-iterations' toward the background color. -Return t if there is more drift to do, nil if completed." - (if (>= (get 'pulse-highlight-face :iteration) pulse-iterations) - nil - (let* ((frame (color-values (face-background 'default))) - (pulse-background (face-background - (get 'pulse-highlight-face - :startface) - nil t)));; can be nil - (when pulse-background - (let* ((start (color-values pulse-background)) - (frac (list (/ (- (nth 0 frame) (nth 0 start)) pulse-iterations) - (/ (- (nth 1 frame) (nth 1 start)) pulse-iterations) - (/ (- (nth 2 frame) (nth 2 start)) pulse-iterations))) - (it (get 'pulse-highlight-face :iteration)) - ) - (set-face-background 'pulse-highlight-face - (pulse-color-values-to-hex - (list - (+ (nth 0 start) (* (nth 0 frac) it)) - (+ (nth 1 start) (* (nth 1 frac) it)) - (+ (nth 2 start) (* (nth 2 frac) it))))) - (put 'pulse-highlight-face :iteration (1+ it)) - (if (>= (1+ it) pulse-iterations) - nil - t))) - ))) +;;; Convenience Functions +;; +(defvar pulse-momentary-overlay nil + "The current pulsing overlay.") + +(defvar pulse-momentary-timer nil + "The current pulsing timer.") + +(defvar pulse-momentary-iteration 0 + "The current pulsing iteration.") (defun pulse-reset-face (&optional face) "Reset the pulse highlighting FACE." @@ -166,15 +125,7 @@ Return t if there is more drift to do, nil if completed." (face-extend-p face nil t))) (put 'pulse-highlight-face :startface (or face 'pulse-highlight-start-face)) - (put 'pulse-highlight-face :iteration 0)) - -;;; Convenience Functions -;; -(defvar pulse-momentary-overlay nil - "The current pulsing overlay.") - -(defvar pulse-momentary-timer nil - "The current pulsing timer.") + (setq pulse-momentary-iteration 0)) (defun pulse-momentary-highlight-overlay (o &optional face) "Pulse the overlay O, unhighlighting before next command. @@ -201,14 +152,22 @@ Optional argument FACE specifies the face to do the highlighting." ;; Thus above we put our face on the overlay, but pulse ;; with a reference face needed for the color. (pulse-reset-face face) - (setq pulse-momentary-timer - (run-with-timer 0 pulse-delay #'pulse-tick - (time-add nil - (* pulse-delay pulse-iterations))))))) - -(defun pulse-tick (stop-time) + (let* ((start (color-name-to-rgb + (face-background 'pulse-highlight-start-face))) + (stop (color-name-to-rgb (face-background 'default))) + (colors (mapcar (apply-partially 'apply 'color-rgb-to-hex) + (color-gradient start stop pulse-iterations)))) + (setq pulse-momentary-timer + (run-with-timer 0 pulse-delay #'pulse-tick + colors + (time-add nil + (* pulse-delay pulse-iterations)))))))) + +(defun pulse-tick (colors stop-time) (if (time-less-p nil stop-time) - (pulse-lighten-highlight) + (when-let (color (elt colors pulse-momentary-iteration)) + (set-face-background 'pulse-highlight-face color) + (setq pulse-momentary-iteration (1+ pulse-momentary-iteration))) (pulse-momentary-unhighlight))) (defun pulse-momentary-unhighlight () commit 261d0f8f74961859d3f801ed7c5205e3eeb80e31 Author: Harald Jörg Date: Thu Mar 18 08:06:13 2021 +0100 cperl-mode: Don't interpret y_ as start of y// function. * lisp/progmodes/cperl-mode.el (cperl-find-pods-heres): Avoid treating underscores as word-terminators. * test/lisp/progmodes/cperl-mode-tests.el (cperl-test-bug-47112): Test case for that bug (bug#47112). diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index cc7614dd10..7612f8d284 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -3927,21 +3927,24 @@ the sections using `cperl-pod-head-face', `cperl-pod-face', bb (char-after (1- (match-beginning b1))) ; tmp holder ;; bb == "Not a stringy" bb (if (eq b1 10) ; user variables/whatever - (and (memq bb (append "$@%*#_:-&>" nil)) ; $#y) - (cond ((eq bb ?-) (eq c ?s)) ; -s file test - ((eq bb ?\:) ; $opt::s - (eq (char-after - (- (match-beginning b1) 2)) - ?\:)) - ((eq bb ?\>) ; $foo->s - (eq (char-after - (- (match-beginning b1) 2)) - ?\-)) - ((eq bb ?\&) - (not (eq (char-after ; &&m/blah/ - (- (match-beginning b1) 2)) - ?\&))) - (t t))) + (or + ; false positive: "y_" has no word boundary + (save-match-data (looking-at "_")) + (and (memq bb (append "$@%*#_:-&>" nil)) ; $#y) + (cond ((eq bb ?-) (eq c ?s)) ; -s file test + ((eq bb ?\:) ; $opt::s + (eq (char-after + (- (match-beginning b1) 2)) + ?\:)) + ((eq bb ?\>) ; $foo->s + (eq (char-after + (- (match-beginning b1) 2)) + ?\-)) + ((eq bb ?\&) + (not (eq (char-after ; &&m/blah/ + (- (match-beginning b1) 2)) + ?\&))) + (t t)))) ;; or <$file> (and (eq c ?\<) ;; Do not stringify , <$fh> : diff --git a/test/lisp/progmodes/cperl-mode-tests.el b/test/lisp/progmodes/cperl-mode-tests.el index 61e4ece49b..f0e15022d0 100644 --- a/test/lisp/progmodes/cperl-mode-tests.el +++ b/test/lisp/progmodes/cperl-mode-tests.el @@ -447,4 +447,30 @@ have a face property." ;; The yadda-yadda operator should not be in a string. (should (equal (nth 8 (cperl-test-ppss code "\\.")) nil)))) +(ert-deftest cperl-test-bug-47112 () + "Check that in a bareword starting with a quote-like operator +followed by an underscore is not interpreted as that quote-like +operator. Also check that a quote-like operator followed by a +colon (which is, like ?_, a symbol in CPerl mode) _is_ identified +as that quote like operator." + (with-temp-buffer + (funcall cperl-test-mode) + (insert "sub y_max { q:bar:; y _bar_foo_; }") + (goto-char (point-min)) + (cperl-update-syntaxification (point-max)) + (font-lock-fontify-buffer) + (search-forward "max") + (should (equal (get-text-property (match-beginning 0) 'face) + 'font-lock-function-name-face)) + (search-forward "bar") + (should (equal (get-text-property (match-beginning 0) 'face) + 'font-lock-string-face)) + ; perl-mode doesn't highlight + (when (eq cperl-test-mode #'cperl-mode) + (search-forward "_") + (should (equal (get-text-property (match-beginning 0) 'face) + (if (eq cperl-test-mode #'cperl-mode) + 'font-lock-constant-face + font-lock-string-face)))))) + ;;; cperl-mode-tests.el ends here commit 846e8672bb41889ea10ca3b8f874ed5ea731ed14 Author: Gabriel do Nascimento Ribeiro Date: Thu Mar 18 07:54:46 2021 +0100 Fix uniquify-trailing-separator-p + uniquify-strip-common-suffix (uniquify-item): New slot 'original-dirname'. (uniquify-rationalize-file-buffer-names): Use new slot. (uniquify-rationalize): Use new slot. (uniquify-get-proposed-name): New optional argument 'original-dirname' to properly add a trailing separator when the corresponding user option is set and the dirname is an existing directory (bug#47132). diff --git a/lisp/uniquify.el b/lisp/uniquify.el index c1ec90e290..1d513d6037 100644 --- a/lisp/uniquify.el +++ b/lisp/uniquify.el @@ -175,8 +175,8 @@ contains the name of the directory which the buffer is visiting.") (cl-defstruct (uniquify-item (:constructor nil) (:copier nil) (:constructor uniquify-make-item - (base dirname buffer &optional proposed))) - base dirname buffer proposed) + (base dirname buffer &optional proposed original-dirname))) + base dirname buffer proposed original-dirname) ;; Internal variables used free (defvar uniquify-possibly-resolvable nil) @@ -211,7 +211,8 @@ this rationalization." (with-current-buffer newbuf (setq uniquify-managed nil)) (when dirname (setq dirname (expand-file-name (directory-file-name dirname))) - (let ((fix-list (list (uniquify-make-item base dirname newbuf))) + (let ((fix-list (list (uniquify-make-item base dirname newbuf + nil dirname))) items) (dolist (buffer (buffer-list)) (when (and (not (and uniquify-ignore-buffers-re @@ -284,7 +285,9 @@ in `uniquify-list-buffers-directory-modes', otherwise returns nil." ;; Refresh the dirnames and proposed names. (setf (uniquify-item-proposed item) (uniquify-get-proposed-name (uniquify-item-base item) - (uniquify-item-dirname item))) + (uniquify-item-dirname item) + nil + (uniquify-item-original-dirname item))) (setq uniquify-managed fix-list))) ;; Strip any shared last directory names of the dirname. (when (and (cdr fix-list) uniquify-strip-common-suffix) @@ -307,7 +310,8 @@ in `uniquify-list-buffers-directory-modes', otherwise returns nil." (uniquify-item-dirname item)))) (and f (directory-file-name f))) (uniquify-item-buffer item) - (uniquify-item-proposed item)) + (uniquify-item-proposed item) + (uniquify-item-original-dirname item)) fix-list))))) ;; If uniquify-min-dir-content is 0, this will end up just ;; passing fix-list to uniquify-rationalize-conflicting-sublist. @@ -335,13 +339,14 @@ in `uniquify-list-buffers-directory-modes', otherwise returns nil." (uniquify-rationalize-conflicting-sublist conflicting-sublist old-proposed depth))) -(defun uniquify-get-proposed-name (base dirname &optional depth) +(defun uniquify-get-proposed-name (base dirname &optional depth + original-dirname) (unless depth (setq depth uniquify-min-dir-content)) (cl-assert (equal (directory-file-name dirname) dirname)) ;No trailing slash. ;; Distinguish directories by adding extra separator. (if (and uniquify-trailing-separator-p - (file-directory-p (expand-file-name base dirname)) + (file-directory-p (expand-file-name base original-dirname)) (not (string-equal base ""))) (cond ((eq uniquify-buffer-name-style 'forward) (setq base (file-name-as-directory base))) @@ -410,7 +415,8 @@ in `uniquify-list-buffers-directory-modes', otherwise returns nil." (uniquify-get-proposed-name (uniquify-item-base item) (uniquify-item-dirname item) - depth))) + depth + (uniquify-item-original-dirname item)))) (uniquify-rationalize-a-list conf-list depth)) (unless (string= old-name "") (uniquify-rename-buffer (car conf-list) old-name))))) commit a5197e2240d3021ea1f301591227c389a476fd02 Author: Lars Ingebrigtsen Date: Thu Mar 18 07:36:15 2021 +0100 Fix problem of trashing files to an inconsistent trash directory * lisp/files.el (move-file-to-trash): Allow moving files to trash even if there's a file in trash with the same name (but no entry in info) (bug#47135). diff --git a/lisp/files.el b/lisp/files.el index 2868be77f2..60d6034011 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -7858,9 +7858,22 @@ Otherwise, trash FILENAME using the freedesktop.org conventions, ;; Make a .trashinfo file. Use O_EXCL, as per trash-spec 1.0. (let* ((files-base (file-name-nondirectory fn)) - (info-fn (expand-file-name + (overwrite nil) + info-fn) + ;; We're checking further down whether the info file + ;; exists, but the file name may exist in the trash + ;; directory even if there is no info file for it. + (when (file-exists-p + (expand-file-name files-base trash-files-dir)) + (setq overwrite t + files-base (file-name-nondirectory + (make-temp-file + (expand-file-name + files-base trash-files-dir))))) + (setq info-fn (expand-file-name (concat files-base ".trashinfo") - trash-info-dir))) + trash-info-dir)) + ;; Re-check the existence (sort of). (condition-case nil (write-region nil nil info-fn nil 'quiet info-fn 'excl) (file-already-exists @@ -7876,7 +7889,7 @@ Otherwise, trash FILENAME using the freedesktop.org conventions, ;; Finally, try to move the file to the trashcan. (let ((delete-by-moving-to-trash nil) (new-fn (expand-file-name files-base trash-files-dir))) - (rename-file fn new-fn))))))))) + (rename-file fn new-fn overwrite))))))))) (defsubst file-attribute-type (attributes) "The type field in ATTRIBUTES returned by `file-attributes'. commit 0aad4d134f481662e621aea62c6633678a1387e1 Author: Lars Ingebrigtsen Date: Thu Mar 18 06:21:44 2021 +0100 Autoload 'mouse-wheel-mode' * lisp/mwheel.el (mouse-wheel-mode): Autoload, since the mode can be used (but isn't preloaded) when there isn't any window system (bug#47162). diff --git a/lisp/mwheel.el b/lisp/mwheel.el index adfeaccb29..048f50c772 100644 --- a/lisp/mwheel.el +++ b/lisp/mwheel.el @@ -411,6 +411,7 @@ an event used for scrolling, such as `mouse-wheel-down-event'." (cons (vector event) (mapcar (lambda (prefix) (vector prefix event)) prefixes))))) +;;;###autoload (define-minor-mode mouse-wheel-mode "Toggle mouse wheel support (Mouse Wheel mode)." :init-value t commit 1219207a82740fc6ac21f178cacbe30e6aff9e7b Author: Lars Ingebrigtsen Date: Thu Mar 18 06:11:06 2021 +0100 Recognise "Verify password" as a password prompt * lisp/comint.el (comint-password-prompt-regexp): Also react to "Verify password" (output by "zip -e") (bug#47209). diff --git a/lisp/comint.el b/lisp/comint.el index 5c307febe2..bb28db7614 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -372,7 +372,7 @@ This variable is buffer-local." '("Enter" "enter" "Enter same" "enter same" "Enter the" "enter the" "Enter Auth" "enter auth" "Old" "old" "New" "new" "'s" "login" "Kerberos" "CVS" "UNIX" " SMB" "LDAP" "PEM" "SUDO" - "[sudo]" "doas" "Repeat" "Bad" "Retype") + "[sudo]" "doas" "Repeat" "Bad" "Retype" "Verify") t) ;; Allow for user name to precede password equivalent (Bug#31075). " +.*\\)" commit 60af754170f22f5d25510af069ed0ebfec95f992 Author: Lars Ingebrigtsen Date: Thu Mar 18 05:59:12 2021 +0100 Document that `buffer-string' retains text properties * doc/lispref/text.texi (Buffer Contents): Mention text properties in the `buffer-string' documentation. * src/editfns.c (Fbuffer_string): Mention text properties in the doc string (bug#47220). diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index e47e851b10..44c4b90b2f 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -222,7 +222,9 @@ properties, just the characters themselves. @xref{Text Properties}. @defun buffer-string This function returns the contents of the entire accessible portion of -the current buffer, as a string. +the current buffer, as a string. If the text being copied has any +text properties, these are copied into the string along with the +characters they belong to. @end defun If you need to make sure the resulting string, when copied to a diff --git a/src/editfns.c b/src/editfns.c index fb20fc9655..bc6553a7d2 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -1697,7 +1697,11 @@ they can be in either order. */) DEFUN ("buffer-string", Fbuffer_string, Sbuffer_string, 0, 0, 0, doc: /* Return the contents of the current buffer as a string. If narrowing is in effect, this function returns only the visible part -of the buffer. */) +of the buffer. + +This function copies the text properties of that part of the buffer +into the result string; if you don’t want the text properties, +use `buffer-substring-no-properties' instead. */) (void) { return make_buffer_string_both (BEGV, BEGV_BYTE, ZV, ZV_BYTE, 1); commit 6a75b6fcb10725fb1e352dec506b84e795baa7c8 Author: Lars Ingebrigtsen Date: Thu Mar 18 05:55:16 2021 +0100 Don't pre-load facemenu * lisp/facemenu.el (facemenu-add-face-function): Move to avoid a compilation warning. (facemenu-color-alist): Made obsolete. * lisp/faces.el (read-color): Don't use it. * lisp/loadup.el ("emacs-lisp/syntax"): Don't load facemenu. * lisp/wid-edit.el (color): Don't use facemenu-color-alist. (widget-color--choose-action): Require facemenu. (widget-color-action): Ditto. * lisp/progmodes/cperl-mode.el (facemenu): Require. * lisp/textmodes/sgml-mode.el (facemenu): Require. diff --git a/etc/NEWS b/etc/NEWS index ba82174833..20407db0ac 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2278,6 +2278,12 @@ directory instead of the default directory. * Incompatible Lisp Changes in Emacs 28.1 +** 'facemenu-color-alist' is now obsolete, and is not used. + +** 'facemenu.el' is no longer preloaded. +To use functions/variables from the package, you now have to say +'(require 'facemenu)' or similar. + ** 'pcomplete-ignore-case' is now an obsolete alias of 'completion-ignore-case'. ** 'completions-annotations' face is not used when the caller puts own face. diff --git a/lisp/facemenu.el b/lisp/facemenu.el index 6290b02add..2d06658b55 100644 --- a/lisp/facemenu.el +++ b/lisp/facemenu.el @@ -169,6 +169,14 @@ it will remove any faces not explicitly in the list." (defalias 'facemenu-background-menu facemenu-background-menu) (put 'facemenu-background-menu 'menu-enable '(facemenu-enable-faces-p)) +(defcustom facemenu-add-face-function nil + "Function called at beginning of text to change or nil. +This function is passed the FACE to set and END of text to change, and must +return a string which is inserted. It may set `facemenu-end-add-face'." + :type '(choice (const :tag "None" nil) + function) + :group 'facemenu) + ;;; Condition for enabling menu items that set faces. (defun facemenu-enable-faces-p () ;; Enable the facemenu if facemenu-add-face-function is defined @@ -260,14 +268,6 @@ requested in `facemenu-keybindings'.") (defalias 'facemenu-keymap facemenu-keymap) -(defcustom facemenu-add-face-function nil - "Function called at beginning of text to change or nil. -This function is passed the FACE to set and END of text to change, and must -return a string which is inserted. It may set `facemenu-end-add-face'." - :type '(choice (const :tag "None" nil) - function) - :group 'facemenu) - (defcustom facemenu-end-add-face nil "String to insert or function called at end of text to change or nil. This function is passed the FACE to set, and must return a string which is @@ -291,6 +291,7 @@ May also be t meaning to use `facemenu-add-face-function'." (defvar facemenu-color-alist nil "Alist of colors, used for completion. If this is nil, then the value of (defined-colors) is used.") +(make-obsolete-variable 'facemenu-color-alist nil "28.1") (defun facemenu-update () "Add or update the \"Face\" menu in the menu bar. diff --git a/lisp/faces.el b/lisp/faces.el index 573428f1d3..7c6d749120 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -1917,12 +1917,11 @@ Interactively, or with optional arg MSG non-nil, print the resulting color name in the echo area." (interactive "i\np\ni\np") ; Always convert to RGB interactively. (let* ((completion-ignore-case t) - (colors (or facemenu-color-alist - (append '("foreground at point" "background at point") - (if allow-empty-name '("")) - (if (display-color-p) - (defined-colors-with-face-attributes) - (defined-colors))))) + (colors (append '("foreground at point" "background at point") + (if allow-empty-name '("")) + (if (display-color-p) + (defined-colors-with-face-attributes) + (defined-colors)))) (color (completing-read (or prompt "Color (name or #RGB triplet): ") ;; Completing function for reading colors, accepting diff --git a/lisp/loadup.el b/lisp/loadup.el index 863afe427b..4a0b8f508c 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -253,7 +253,6 @@ (load "startup") (load "term/tty-colors") (load "font-core") -(load "facemenu") (load "emacs-lisp/syntax") (load "font-lock") (load "jit-lock") diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index 734797b3ad..cc7614dd10 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -92,6 +92,7 @@ (concat msg ": "))))) (eval-when-compile (require 'cl-lib)) +(require 'facemenu) (defvar msb-menu-cond) (defvar gud-perldb-history) diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el index 876347bc81..7de5317b02 100644 --- a/lisp/textmodes/sgml-mode.el +++ b/lisp/textmodes/sgml-mode.el @@ -34,6 +34,7 @@ (require 'dom) (require 'seq) +(require 'facemenu) (eval-when-compile (require 'subr-x)) (eval-when-compile (require 'skeleton) diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index 35e7b9ce7e..e71290c7ef 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el @@ -4034,7 +4034,7 @@ is inline." (mapcar #'length (defined-colors)))) :tag "Color" :value "black" - :completions (or facemenu-color-alist (defined-colors)) + :completions (defined-colors) :sample-face-get 'widget-color-sample-face-get :notify 'widget-color-notify :match #'widget-color-match @@ -4049,7 +4049,10 @@ is inline." :tag " Choose " :action 'widget-color--choose-action) (widget-insert " ")) +(declare-function list-colors-display "facemenu") + (defun widget-color--choose-action (widget &optional _event) + (require 'facemenu) (list-colors-display nil nil (let ((cbuf (current-buffer)) @@ -4072,8 +4075,11 @@ is inline." (list (cons 'foreground-color value)) 'default))) +(declare-function facemenu-read-color "facemenu") + (defun widget-color-action (widget &optional event) "Prompt for a color." + (require 'facemenu) (let* ((tag (widget-apply widget :menu-tag-get)) (prompt (concat tag ": ")) (answer (facemenu-read-color prompt))) commit 1e9c9ebee3e13773400fe93bf26db923a880be6d Author: Lars Ingebrigtsen Date: Thu Mar 18 05:10:32 2021 +0100 Unbind `M-o' and add new `C-x x f' binding * doc/lispref/modes.texi (Other Font Lock Variables): `font-lock-fontify-block' is no longer bound. * lisp/bindings.el (ctl-x-x-map): Bind `font-lock-update'. * lisp/font-lock.el (font-lock-update): New command written by Gregory Heytings . * lisp/loadup.el: Remove transitional experimental code. diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index e1299b52d4..6cf4dd21c1 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -3247,8 +3247,7 @@ set by means of @var{other-vars} in @code{font-lock-defaults} @defvar font-lock-mark-block-function If this variable is non-@code{nil}, it should be a function that is called with no arguments, to choose an enclosing range of text for -refontification for the command @kbd{M-o M-o} -(@code{font-lock-fontify-block}). +refontification for the command @kbd{M-x font-lock-fontify-block}. The function should report its choice by placing the region around it. A good choice is a range of text large enough to give proper results, diff --git a/etc/NEWS b/etc/NEWS index 27a4766a40..ba82174833 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -93,6 +93,10 @@ useful on systems such as FreeBSD which ships only with "etc/termcap". * Changes in Emacs 28.1 ++++ +** New command 'font-lock-update', bound to 'C-x x f'. +This command updates the syntax highlighting in this buffer. + ** The new NonGNU ELPA archive is enabled by default alongside GNU ELPA. +++ @@ -2254,7 +2258,8 @@ first). Use 'M-x center-line' and 'M-x center-paragraph' instead. ** The 'M-o M-o' global binding have been removed. -Use 'M-x font-lock-fontify-block' instead. +Use 'M-x font-lock-fontify-block' instead, or the new `C-x x f' +command, which toggles fontification in the current buffer. ** In 'f90-mode', the backslash character ('\') no longer escapes. For about a decade, the backslash character has no longer had a diff --git a/lisp/bindings.el b/lisp/bindings.el index 7111ae6612..a502373997 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -1432,6 +1432,7 @@ if `inhibit-field-text-motion' is non-nil." (defvar ctl-x-x-map (let ((map (make-sparse-keymap))) + (define-key map "f" #'font-lock-update) (define-key map "g" #'revert-buffer) (define-key map "r" #'rename-buffer) (define-key map "u" #'rename-uniquely) diff --git a/lisp/font-lock.el b/lisp/font-lock.el index c344a61258..82915d8c8b 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -1120,6 +1120,18 @@ portion of the buffer." (funcall font-lock-ensure-function (or beg (point-min)) (or end (point-max))))) +(defun font-lock-update (&optional arg) + "Updates the syntax highlighting in this buffer. +Refontify the accessible portion of this buffer, or enable Font Lock mode +in this buffer if it is currently disabled. With prefix ARG, toggle Font +Lock mode." + (interactive "P") + (save-excursion + (if (and (not arg) font-lock-mode) + (font-lock-fontify-region (point-min) (point-max)) + (font-lock-unfontify-region (point-min) (point-max)) + (font-lock-mode 'toggle)))) + (defun font-lock-default-fontify-buffer () "Fontify the whole buffer using `font-lock-fontify-region-function'." (let ((verbose (if (numberp font-lock-verbose) diff --git a/lisp/loadup.el b/lisp/loadup.el index 1c385e3d2f..863afe427b 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -477,29 +477,6 @@ lost after dumping"))) (setq redisplay--inhibit-bidi nil) -;; Experimental feature removal. -(define-key global-map "\M-o" #'removed-facemenu-command) - -(defun removed-facemenu-command () - "Transition command during test period for facemenu removal." - (interactive) - (switch-to-buffer "*Facemenu Removal*") - (let ((inhibit-read-only t)) - (erase-buffer) - (insert-file-contents - (expand-file-name "facemenu-removal.txt" data-directory))) - (goto-char (point-min)) - (special-mode)) - -(defun facemenu-keymap-restore () - "Restore the facemenu keymap." - ;; Global bindings: - (define-key global-map [C-down-mouse-2] 'facemenu-menu) - (define-key global-map "\M-o" 'facemenu-keymap) - (define-key facemenu-keymap "\eS" 'center-paragraph) - (define-key facemenu-keymap "\es" 'center-line) - (define-key facemenu-keymap "\M-o" 'font-lock-fontify-block)) - (if dump-mode (let ((output (cond ((equal dump-mode "pdump") "emacs.pdmp") commit 485622bbd1afad4c1e39a245cf57605208ca606f Author: Stefan Monnier Date: Wed Mar 17 23:32:39 2021 -0400 * lisp/textmodes: Use lexical-binding * lisp/textmodes/enriched.el: Use lexical-binding. (enriched-mode): Use `delete-dups` to avoid `add-to-list` on a local variable. * lisp/textmodes/makeinfo.el: Use lexical-binding. (makeinfo-region): Remove unused var `filename-or-header`. * lisp/textmodes/refbib.el: Use lexical-binding. (r2b-put-field): Remove unused var `multi-line`. (r2b-barf-output): Remove unused var `match`. * lisp/textmodes/refer.el: Use lexical-binding. (refer-find-entry-internal): Remove unused vars `old-buffer` and `found`. * lisp/textmodes/reftex-auc.el: Use lexical-binding. (LaTeX-add-bibitems): Declare function. (reftex-plug-into-AUCTeX): Use `add-function` and `advice-add` so we can properly unplug. * lisp/textmodes/reftex-cite.el: Use lexical-binding. (reftex-create-bibtex-file): Remove unused var `file`. (reftex--found-list): Declare var. (reftex-offer-bib-menu): Rename local var to `reftex--found-list`. * lisp/textmodes/reftex-dcr.el: Use lexical-binding. (reftex-use-itimer-in-xemacs): Delete XEmacs-only var. (reftex-toggle-auto-view-crossref): Delete XEmacs-only code. (reftex-start-itimer-once): Delete XEmacs-only function. * lisp/textmodes/reftex-global.el: Use lexical-binding. (reftex-isearch-push-state-function): Use a closure instead of `(lambda). * lisp/textmodes/reftex-index.el: Use lexical-binding. (mark-active, transient-mark-mode): Delete var declarations. (reftex-index-mode-map): Remove XEmacs-only code. Use `mapc` so we can use closures instead of hand-built lambdas. (reftex-index-next, reftex-index-previous): Tweak interactive spec to remove unused prefix arg and mark it as a motion command. (reftex-index-phrases-font-lock-keywords) (reftex-index-phrases-font-lock-keywords): Move initialization into declaration. (reftex-index-initialize-phrases-buffer, reftex-index-phrases-mode) reftex-index-phrases-apply-to-region: Remove XEmacs-only code. (TeX-master): Remove redundant declaration. (reftex--chars-first): Rename dynvar from `chars-first`. Adjust all uses. * lisp/textmodes/reftex-parse.el: Use lexical-binding. * lisp/textmodes/reftex-ref.el: Use lexical-binding. (reftex-label): Remove always-nil var `text`. (reftex-refstyle): Declare before first use. (): Use closures rather than `eval` when building commands from `reftex-ref-style-alist`. * lisp/textmodes/reftex-sel.el: Use lexical-binding. (reftex-select-label-mode-map, reftex-select-bib-mode-map): Use `mapc` so we can use closures instead of hand-built lambdas. (reftex-select-label-mode, reftex-select-bib-mode): Remove XEmacs-only code. (reftex-select-data, reftex-select-prompt, reftex-refstyle): Move declaration before first use. (reftex--found-list, reftex--cb-flag, reftex--last-data) (reftex--call-back, reftex--help-string): Move declaration before use, and rename by adding `reftext--` prefix. Adjust all uses in this file. For `reftex--found-list` adjust corresponding uses in `reftex-cite.el`. (reftex-select-item): Explicitly let-bind them. Remove XEmacs-only code. * lisp/textmodes/reftex-toc.el: Use lexical-binding. (reftex-toc-mode-map, reftex-toc-mode, reftex-toc-restore-region) (reftex-toc-next, reftex-toc-previous, reftex-toc-next-heading) (reftex-toc-previous-heading, reftex-toggle-auto-toc-recenter (reftex-make-separate-toc-frame): Remove XEmacs-only code. * lisp/textmodes/reftex-vars.el: Use lexical-binding. * lisp/textmodes/reftex.el: Use lexical-binding. (reftex-mode-map, reftex-mode, reftex-fontify-select-label-buffer) (reftex-verified-face): Remove XEmacs-only code. (reftex-region-active-p, reftex-overlay-put, reftex-move-overlay) (reftex-make-overlay, reftex-get-buffer-visiting, reftex-delete-overlay): Redefine as obsolete aliases. Replace all callers. (current-message): Remove XEmacs-only definition. * lisp/textmodes/remember.el: Use lexical-binding. * lisp/textmodes/table.el (): Use closures rather than `(lambda) to build commands. * lisp/textmodes/texinfmt.el: Use lexical-binding. (texinfo-example-start): Declare var. (texinfo-format-region, texinfo-format-buffer-1): Remove unused var `last-input-buffer`. (texinfo-format-scan): Use `dlet` to bind `whitespace-silent`. (texinfo-optional-braces-discard, texinfo-format-parse-line-args) (texinfo-format-parse-args): Remove unused var `start`. (texinfo-multitable-widths): Remove unused var `start-of-templates`. (texinfo-multitable-item): Strength-reduce `eval` to `symbol-value`. (texinfo-alias): Remove unused vars `start` and `args`. (texinfo-defun-type symbol-property): Change the car to help the type symbol rather than an expression returning it. (texinfo-format-deffn): Remove corresponding `eval`. (texinfo-clear): Remove unused var `value`. (texinfo-format-ifeq): Remove unused var `end`. * lisp/textmodes/texinfo.el: Use lexical-binding. (tex-show-print-queue): Declare function. * lisp/textmodes/texnfo-upd.el: Use lexical-binding. (texinfo-start-menu-description): Remove unused var `end`. (texinfo-insert-node-lines): Remove unused var `beginning-marker`. (texinfo-multiple-files-update): Remove unused vars `next-node-name` and `previous-node-name`. * lisp/textmodes/two-column.el: Use lexical-binding. diff --git a/lisp/textmodes/bib-mode.el b/lisp/textmodes/bib-mode.el index ec21987bbf..e2fd3ecaa4 100644 --- a/lisp/textmodes/bib-mode.el +++ b/lisp/textmodes/bib-mode.el @@ -29,6 +29,8 @@ ;; bibliography file. Keys are automagically inserted as you type, ;; and appropriate keys are presented for various kinds of entries. +;; FIXME: Fix the namespace use of this library. + ;;; Code: (defgroup bib nil @@ -39,7 +41,7 @@ (defcustom bib-file "~/my-bibliography.bib" "Default name of file used by `addbib'." - :type 'file) + :type 'file) (defcustom unread-bib-file "~/to-be-read.bib" "Default name of file used by `unread-bib' in Bib mode." @@ -48,10 +50,10 @@ (defvar bib-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map text-mode-map) - (define-key map "\C-M" 'return-key-bib) - (define-key map "\C-c\C-u" 'unread-bib) - (define-key map "\C-c\C-@" 'mark-bib) - (define-key map "\e`" 'abbrev-mode) + (define-key map "\C-M" #'return-key-bib) + (define-key map "\C-c\C-u" #'unread-bib) + (define-key map "\C-c\C-@" #'mark-bib) + (define-key map "\e`" #'abbrev-mode) map)) (defun addbib () diff --git a/lisp/textmodes/bibtex-style.el b/lisp/textmodes/bibtex-style.el index 66d245f908..820033486d 100644 --- a/lisp/textmodes/bibtex-style.el +++ b/lisp/textmodes/bibtex-style.el @@ -70,7 +70,7 @@ (setq-local outline-regexp "^[a-z]") (setq-local imenu-generic-expression '((nil "\\<\\(FUNCTION\\|MACRO\\)\\s-+{\\([^}\n]+\\)}" 2))) - (setq-local indent-line-function 'bibtex-style-indent-line) + (setq-local indent-line-function #'bibtex-style-indent-line) (setq-local parse-sexp-ignore-comments t) (setq font-lock-defaults '(bibtex-style-font-lock-keywords nil t diff --git a/lisp/textmodes/dns-mode.el b/lisp/textmodes/dns-mode.el index f1a7517192..2fa5e8de39 100644 --- a/lisp/textmodes/dns-mode.el +++ b/lisp/textmodes/dns-mode.el @@ -144,8 +144,8 @@ manually with \\[dns-mode-soa-increment-serial]." (defvar dns-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\C-c\C-s" 'dns-mode-soa-increment-serial) - (define-key map "\C-c\C-e" 'dns-mode-ipv6-to-nibbles) + (define-key map "\C-c\C-s" #'dns-mode-soa-increment-serial) + (define-key map "\C-c\C-e" #'dns-mode-ipv6-to-nibbles) map) "Keymap for DNS master file mode.") @@ -177,7 +177,7 @@ Turning on DNS mode runs `dns-mode-hook'." (setq-local comment-start-skip ";+ *") (setq-local font-lock-defaults '(dns-mode-font-lock-keywords nil nil ((?_ . "w")))) - (add-hook 'before-save-hook 'dns-mode-soa-maybe-increment-serial + (add-hook 'before-save-hook #'dns-mode-soa-maybe-increment-serial nil t)) ;;;###autoload (defalias 'zone-mode 'dns-mode) diff --git a/lisp/textmodes/enriched.el b/lisp/textmodes/enriched.el index e43370cdb5..ba8fac81f2 100644 --- a/lisp/textmodes/enriched.el +++ b/lisp/textmodes/enriched.el @@ -1,4 +1,4 @@ -;;; enriched.el --- read and save files in text/enriched format +;;; enriched.el --- read and save files in text/enriched format -*- lexical-binding: t; -*- ;; Copyright (C) 1994-1996, 2001-2021 Free Software Foundation, Inc. @@ -181,14 +181,16 @@ The value is a list of \(VAR VALUE VAR VALUE...).") (defvar enriched-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\C-m" 'reindent-then-newline-and-indent) + ;; FIXME: These newline/reindent bindings might be redundant now + ;; that we have `electric-indent-mode' enabled by default. + (define-key map "\C-m" #'reindent-then-newline-and-indent) (define-key map - [remap newline-and-indent] 'reindent-then-newline-and-indent) + [remap newline-and-indent] #'reindent-then-newline-and-indent) (define-key map "\M-j" 'facemenu-justification-menu) - (define-key map "\M-S" 'set-justification-center) - (define-key map "\C-x\t" 'increase-left-margin) - (define-key map "\C-c[" 'set-left-margin) - (define-key map "\C-c]" 'set-right-margin) + (define-key map "\M-S" #'set-justification-center) + (define-key map "\C-x\t" #'increase-left-margin) + (define-key map "\C-c[" #'set-left-margin) + (define-key map "\C-c]" #'set-right-margin) map) "Keymap for Enriched mode.") @@ -215,7 +217,7 @@ Commands: (cond ((null enriched-mode) ;; Turn mode off (remove-hook 'change-major-mode-hook - 'enriched-before-change-major-mode 'local) + #'enriched-before-change-major-mode 'local) (setq buffer-file-format (delq 'text/enriched buffer-file-format)) ;; restore old variable values (while enriched-old-bindings @@ -232,7 +234,7 @@ Commands: (t ; Turn mode on (add-hook 'change-major-mode-hook - 'enriched-before-change-major-mode nil 'local) + #'enriched-before-change-major-mode nil 'local) (add-to-list 'buffer-file-format 'text/enriched) ;; Save old variable values before we change them. ;; These will be restored if we exit Enriched mode. @@ -245,10 +247,12 @@ Commands: (make-local-variable 'default-text-properties) (setq buffer-display-table enriched-display-table) (use-hard-newlines 1 (if enriched-rerun-flag 'never nil)) - (let ((sticky (plist-get default-text-properties 'front-sticky)) - (p enriched-par-props)) - (dolist (x p) - (add-to-list 'sticky x)) + (let* ((sticky + (delete-dups + (append + enriched-par-props + (copy-sequence + (plist-get default-text-properties 'front-sticky)))))) (if sticky (setq default-text-properties (plist-put default-text-properties @@ -264,7 +268,7 @@ Commands: (let ((enriched-rerun-flag t)) (enriched-mode 1)))) -(add-hook 'after-change-major-mode-hook 'enriched-after-change-major-mode) +(add-hook 'after-change-major-mode-hook #'enriched-after-change-major-mode) (fset 'enriched-mode-map enriched-mode-map) @@ -342,7 +346,7 @@ the region, and the START and END of each region." (if orig-buf (set-buffer orig-buf)) (funcall enriched-initial-annotation)))) (enriched-map-property-regions 'hard - (lambda (v b e) + (lambda (v b _e) (if (and v (= ?\n (char-after b))) (progn (goto-char b) (insert "\n")))) (point) nil) @@ -386,7 +390,7 @@ which can be the value of the `face' text property." ((and (listp face) (eq (car face) :background)) (list (list "x-bg-color" (cadr face)))) ((listp face) - (apply 'append (mapcar 'enriched-face-ans face))) + (apply #'append (mapcar #'enriched-face-ans face))) ((let* ((fg (face-attribute face :foreground)) (bg (face-attribute face :background)) (weight (face-attribute face :weight)) diff --git a/lisp/textmodes/fill.el b/lisp/textmodes/fill.el index 6681b03913..81cd2f02cd 100644 --- a/lisp/textmodes/fill.el +++ b/lisp/textmodes/fill.el @@ -45,7 +45,7 @@ A value of nil means that any change in indentation starts a new paragraph." (defcustom colon-double-space nil "Non-nil means put two spaces after a colon when filling." :type 'boolean) -(put 'colon-double-space 'safe-local-variable 'booleanp) +(put 'colon-double-space 'safe-local-variable #'booleanp) (defcustom fill-separate-heterogeneous-words-with-space nil "Non-nil means to use a space to separate words of a different kind. diff --git a/lisp/textmodes/less-css-mode.el b/lisp/textmodes/less-css-mode.el index 24ccb3ce98..d374cab27a 100644 --- a/lisp/textmodes/less-css-mode.el +++ b/lisp/textmodes/less-css-mode.el @@ -91,7 +91,7 @@ executable, e.g.: \"~/.gem/ruby/1.8/bin/lessc\"." "If non-nil, Less buffers are compiled to CSS after each save." :type 'boolean) ;;;###autoload -(put 'less-css-compile-at-save 'safe-local-variable 'booleanp) +(put 'less-css-compile-at-save 'safe-local-variable #'booleanp) (defcustom less-css-lessc-options '("--no-color") "Command line options for Less executable. @@ -107,7 +107,7 @@ using `expand-file-name', so both relative and absolute paths will work as expected." :type '(choice (const :tag "Same as Less file" nil) directory)) ;;;###autoload -(put 'less-css-output-directory 'safe-local-variable 'stringp) +(put 'less-css-output-directory 'safe-local-variable #'stringp) (defcustom less-css-output-file-name nil "File name in which to save CSS, or nil to use .css for .less. @@ -133,7 +133,7 @@ the path is relative, it will be relative to the current directory by default." :type '(choice (const nil) file)) ;;;###autoload -(put 'less-css-input-file-name 'safe-local-variable 'stringp) +(put 'less-css-input-file-name 'safe-local-variable #'stringp) (make-variable-buffer-local 'less-css-input-file-name) (defconst less-css-default-error-regex @@ -211,7 +211,7 @@ directory by default." (defvar less-css-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\C-c\C-c" 'less-css-compile) + (define-key map "\C-c\C-c" #'less-css-compile) map)) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.less\\'" . less-css-mode)) @@ -226,7 +226,7 @@ Special commands: (setq-local comment-continue " *") (setq-local comment-start-skip "/[*/]+[ \t]*") (setq-local comment-end-skip "[ \t]*\\(?:\n\\|\\*+/\\)") - (add-hook 'after-save-hook 'less-css-compile-maybe nil t)) + (add-hook 'after-save-hook #'less-css-compile-maybe nil t)) (provide 'less-css-mode) ;;; less-css-mode.el ends here diff --git a/lisp/textmodes/makeinfo.el b/lisp/textmodes/makeinfo.el index f63894b815..8152f4b89c 100644 --- a/lisp/textmodes/makeinfo.el +++ b/lisp/textmodes/makeinfo.el @@ -1,4 +1,4 @@ -;;; makeinfo.el --- run makeinfo conveniently +;;; makeinfo.el --- run makeinfo conveniently -*- lexical-binding: t; -*- ;; Copyright (C) 1991, 1993, 2001-2021 Free Software Foundation, Inc. @@ -93,7 +93,7 @@ apply to a temporary file, not the original; use the `makeinfo-buffer' command to gain use of `next-error'." (interactive "r") - (let (filename-or-header + (let (;; filename-or-header filename-or-header-beginning filename-or-header-end) ;; Cannot use `let' for makeinfo-temp-file or @@ -173,7 +173,7 @@ command to gain use of `next-error'." t 'makeinfo-compilation-sentinel-region))))))) -(defun makeinfo-next-error (arg reset) +(defun makeinfo-next-error (_arg _reset) "This function is used to disable `next-error' if the user has used `makeinfo-region'. Since the compilation process is used on a temporary file in that case, calling `next-error' would give diff --git a/lisp/textmodes/nroff-mode.el b/lisp/textmodes/nroff-mode.el index 7d9b414bf0..94519c3420 100644 --- a/lisp/textmodes/nroff-mode.el +++ b/lisp/textmodes/nroff-mode.el @@ -47,12 +47,12 @@ (defvar nroff-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\t" 'tab-to-tab-stop) - (define-key map "\e?" 'nroff-count-text-lines) - (define-key map "\n" 'nroff-electric-newline) - (define-key map "\en" 'nroff-forward-text-line) - (define-key map "\ep" 'nroff-backward-text-line) - (define-key map "\C-c\C-c" 'nroff-view) + (define-key map "\t" #'tab-to-tab-stop) + (define-key map "\e?" #'nroff-count-text-lines) + (define-key map "\n" #'nroff-electric-newline) + (define-key map "\en" #'nroff-forward-text-line) + (define-key map "\ep" #'nroff-backward-text-line) + (define-key map "\C-c\C-c" #'nroff-view) map) "Major mode keymap for `nroff-mode'.") diff --git a/lisp/textmodes/page-ext.el b/lisp/textmodes/page-ext.el index c3e1fb14bc..87c91e8f1b 100644 --- a/lisp/textmodes/page-ext.el +++ b/lisp/textmodes/page-ext.el @@ -293,7 +293,7 @@ Used by `pages-directory-for-addresses' function." ;; FIXME: Merely loading a package shouldn't have this kind of side-effects! (global-unset-key "\C-x\C-p") (define-key ctl-x-map "\C-p" #'pages-ctl-x-ctl-p-prefix) -(define-obsolete-function-alias 'ctl-x-ctl-p-prefix 'pages-ctl-x-ctl-p-prefix "27.1") +(define-obsolete-function-alias 'ctl-x-ctl-p-prefix #'pages-ctl-x-ctl-p-prefix "27.1") (defalias 'pages-ctl-x-ctl-p-prefix pages--ctl-x-ctl-p-map) diff --git a/lisp/textmodes/paragraphs.el b/lisp/textmodes/paragraphs.el index 472c406961..31e91c7303 100644 --- a/lisp/textmodes/paragraphs.el +++ b/lisp/textmodes/paragraphs.el @@ -97,7 +97,7 @@ lines that start paragraphs from lines that separate them. If the variable `use-hard-newlines' is non-nil, then only lines following a hard newline are considered to match." :type 'regexp) -(put 'paragraph-start 'safe-local-variable 'stringp) +(put 'paragraph-start 'safe-local-variable #'stringp) ;; paragraph-start requires a hard newline, but paragraph-separate does not: ;; It is assumed that paragraph-separate is distinctive enough to be believed @@ -114,7 +114,7 @@ the beginning of the line, so it should not use \"^\" as an anchor. This ensures that the paragraph functions will work equally within a region of text indented by a margin setting." :type 'regexp) -(put 'paragraph-separate 'safe-local-variable 'stringp) +(put 'paragraph-separate 'safe-local-variable #'stringp) (defcustom sentence-end-double-space t "Non-nil means a single space does not end a sentence. @@ -126,7 +126,7 @@ regexp describing the end of a sentence, when the value of the variable `sentence-end' is nil. See Info node `(elisp)Standard Regexps'." :type 'boolean :group 'fill) -(put 'sentence-end-double-space 'safe-local-variable 'booleanp) +(put 'sentence-end-double-space 'safe-local-variable #'booleanp) (defcustom sentence-end-without-period nil "Non-nil means a sentence will end without a period. @@ -138,7 +138,7 @@ regexp describing the end of a sentence, when the value of the variable `sentence-end' is nil. See Info node `(elisp)Standard Regexps'." :type 'boolean :group 'fill) -(put 'sentence-end-without-period 'safe-local-variable 'booleanp) +(put 'sentence-end-without-period 'safe-local-variable #'booleanp) (defcustom sentence-end-without-space "。.?!" @@ -148,7 +148,7 @@ This value is used by the function `sentence-end' to construct the regexp describing the end of a sentence, when the value of the variable `sentence-end' is nil. See Info node `(elisp)Standard Regexps'." :type 'string) -(put 'sentence-end-without-space 'safe-local-variable 'stringp) +(put 'sentence-end-without-space 'safe-local-variable #'stringp) (defcustom sentence-end nil "Regexp describing the end of a sentence. @@ -159,13 +159,13 @@ The value nil means to use the default value defined by the function `sentence-end'. You should always use this function to obtain the value of this variable." :type '(choice regexp (const :tag "Use default value" nil))) -(put 'sentence-end 'safe-local-variable 'string-or-null-p) +(put 'sentence-end 'safe-local-variable #'string-or-null-p) (defcustom sentence-end-base "[.?!…‽][]\"'”’)}»›]*" "Regexp matching the basic end of a sentence, not including following space." :type 'regexp :version "25.1") -(put 'sentence-end-base 'safe-local-variable 'stringp) +(put 'sentence-end-base 'safe-local-variable #'stringp) (defun sentence-end () "Return the regexp describing the end of a sentence. @@ -193,13 +193,13 @@ in between. See Info node `(elisp)Standard Regexps'." (defcustom page-delimiter "^\014" "Regexp describing line-beginnings that separate pages." :type 'regexp) -(put 'page-delimiter 'safe-local-variable 'stringp) +(put 'page-delimiter 'safe-local-variable #'stringp) (defcustom paragraph-ignore-fill-prefix nil "Non-nil means the paragraph commands are not affected by `fill-prefix'. This is desirable in modes where blank lines are the paragraph delimiters." :type 'boolean) -(put 'paragraph-ignore-fill-prefix 'safe-local-variable 'booleanp) +(put 'paragraph-ignore-fill-prefix 'safe-local-variable #'booleanp) ;; Silence the compiler. (defvar multiple-lines) diff --git a/lisp/textmodes/refbib.el b/lisp/textmodes/refbib.el index 2f3e0243ef..084b17c676 100644 --- a/lisp/textmodes/refbib.el +++ b/lisp/textmodes/refbib.el @@ -1,4 +1,4 @@ -;;; refbib.el --- convert refer-style references to ones usable by Latex bib +;;; refbib.el --- convert refer-style references to ones usable by Latex bib -*- lexical-binding: t; -*- ;; Copyright (C) 1989, 2001-2021 Free Software Foundation, Inc. @@ -411,7 +411,7 @@ title if CAPITALIZE is true. Returns value of VAR." with a comma and newline; if ABBREVS list is given, then try to replace the {DATA} with an abbreviation." (if data - (let (match nodelim multi-line index) + (let (match nodelim index) ;; multi-line (cond ((and abbrevs (setq match (assoc data abbrevs))) (if (null (cdr match)) @@ -507,7 +507,7 @@ but not a publisher." (defun r2b-barf-output () "Generate bibtex based on global variables." - (let ((standard-output r2b-out-buf) (case-fold-search t) match) + (let ((standard-output r2b-out-buf) (case-fold-search t)) ;; match (r2b-trace "...barfing") (sit-for 0) diff --git a/lisp/textmodes/refer.el b/lisp/textmodes/refer.el index c2bf90f37b..53519ac338 100644 --- a/lisp/textmodes/refer.el +++ b/lisp/textmodes/refer.el @@ -1,4 +1,4 @@ -;;; refer.el --- look up references in bibliography files +;;; refer.el --- look up references in bibliography files -*- lexical-binding: t; -*- ;; Copyright (C) 1992, 1996, 2001-2021 Free Software Foundation, Inc. @@ -176,7 +176,7 @@ found on the last `refer-find-entry' or `refer-find-next-entry'." (defun refer-find-entry-internal (keywords continue) (let ((keywords-list (refer-convert-string-to-list-of-strings keywords)) - (old-buffer (current-buffer)) + ;; (old-buffer (current-buffer)) (old-window (selected-window)) (new-window (selected-window)) (files (if continue @@ -184,7 +184,7 @@ found on the last `refer-find-entry' or `refer-find-next-entry'." (setq refer-saved-pos nil) (refer-get-bib-files))) (n 0) - (found nil) + ;; (found nil) (file nil)) ;; find window in which to display bibliography file. ;; if a bibliography file is already displayed in a window, use diff --git a/lisp/textmodes/refill.el b/lisp/textmodes/refill.el index a6400c738a..0a0e4cc444 100644 --- a/lisp/textmodes/refill.el +++ b/lisp/textmodes/refill.el @@ -227,9 +227,9 @@ For true \"word wrap\" behavior, use `visual-line-mode' instead." (kill-local-variable 'refill-saved-state)) (if refill-mode (progn - (add-hook 'after-change-functions 'refill-after-change-function nil t) - (add-hook 'post-command-hook 'refill-post-command-function nil t) - (add-hook 'pre-command-hook 'refill-pre-command-function nil t) + (add-hook 'after-change-functions #'refill-after-change-function nil t) + (add-hook 'post-command-hook #'refill-post-command-function nil t) + (add-hook 'pre-command-hook #'refill-pre-command-function nil t) (setq-local refill-saved-state (mapcar (lambda (s) (cons s (symbol-value s))) '(fill-paragraph-function auto-fill-function))) @@ -244,8 +244,8 @@ For true \"word wrap\" behavior, use `visual-line-mode' instead." (overlay-put refill-ignorable-overlay 'insert-behind-hooks '(refill-adjust-ignorable-overlay)) (auto-fill-mode 0)) - (remove-hook 'after-change-functions 'refill-after-change-function t) - (remove-hook 'post-command-hook 'refill-post-command-function t) + (remove-hook 'after-change-functions #'refill-after-change-function t) + (remove-hook 'post-command-hook #'refill-post-command-function t) (kill-local-variable 'backward-delete-char-untabify-method))) (provide 'refill) diff --git a/lisp/textmodes/reftex-auc.el b/lisp/textmodes/reftex-auc.el index ae3faec4fd..8429fce625 100644 --- a/lisp/textmodes/reftex-auc.el +++ b/lisp/textmodes/reftex-auc.el @@ -1,4 +1,4 @@ -;;; reftex-auc.el --- RefTeX's interface to AUCTeX +;;; reftex-auc.el --- RefTeX's interface to AUCTeX -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -69,6 +69,8 @@ What is being used depends upon `reftex-plug-into-AUCTeX'." (LaTeX-add-labels label)) (TeX-argument-insert label optional))) +(declare-function LaTeX-add-bibitems "latex") ;FIXME: Can't find the definition + ;;;###autoload (defun reftex-arg-cite (optional &optional prompt definition) "Use `reftex-citation' or AUCTeX's code to insert a cite-key macro argument. @@ -82,13 +84,13 @@ What is being used depends upon `reftex-plug-into-AUCTeX'." (if prompt prompt "Add key") " (default none): ")) (setq items (multi-prompt "," t prompt (LaTeX-bibitem-list))))) - (apply 'LaTeX-add-bibitems items) - (TeX-argument-insert (mapconcat 'identity items reftex-cite-key-separator) + (apply #'LaTeX-add-bibitems items) + (TeX-argument-insert (mapconcat #'identity items reftex-cite-key-separator) optional))) ;;;###autoload -(defun reftex-arg-index-tag (optional &optional prompt &rest args) +(defun reftex-arg-index-tag (optional &optional prompt &rest _args) "Prompt for an index tag with completion. This is the name of an index, not the entry." (let (tag taglist) @@ -102,13 +104,13 @@ This is the name of an index, not the entry." (setq taglist (cdr (assoc 'index-tags (symbol-value reftex-docstruct-symbol))) - tag (completing-read prompt (mapcar 'list taglist)))) + tag (completing-read prompt (mapcar #'list taglist)))) ;; Just ask like AUCTeX does. (setq tag (read-string prompt))) (TeX-argument-insert tag optional))) ;;;###autoload -(defun reftex-arg-index (optional &optional prompt &rest args) +(defun reftex-arg-index (optional &optional prompt &rest _args) "Prompt for an index entry completing with known entries. Completion is specific for just one index, if the macro or a tag argument identify one of multiple indices." @@ -149,23 +151,27 @@ argument identify one of multiple indices." ;; `reftex-plug-into-AUCTeX'. (if (reftex-plug-flag 0) - (setq LaTeX-label-function 'reftex-label) - (setq LaTeX-label-function nil)) - - (and (or (reftex-plug-flag 1) (reftex-plug-flag 2)) - (fboundp 'TeX-arg-label) - (fset 'TeX-arg-label 'reftex-arg-label)) - - (and (reftex-plug-flag 3) - (fboundp 'TeX-arg-cite) - (fset 'TeX-arg-cite 'reftex-arg-cite)) - - (and (reftex-plug-flag 4) - (fboundp 'TeX-arg-index-tag) - (fset 'TeX-arg-index-tag 'reftex-arg-index-tag)) - (and (reftex-plug-flag 4) - (fboundp 'TeX-arg-index) - (fset 'TeX-arg-index 'reftex-arg-index))) + (if (bound-and-true-p LaTeX-label-function) + (add-function :override LaTeX-label-function #'reftex-label) + (setq LaTeX-label-function #'reftex-label)) + (if (eq #'reftex-label (bound-and-true-p LaTeX-label-function)) + (setq LaTeX-label-function nil) + (remove-function LaTeX-label-function #'reftex-label))) + + (if (or (reftex-plug-flag 1) (reftex-plug-flag 2)) + (advice-add 'TeX-arg-label :override #'reftex-arg-label) + (advice-remove 'TeX-arg-label #'reftex-arg-label)) + + (if (reftex-plug-flag 3) + (advice-add 'TeX-arg-cite :override #'reftex-arg-cite) + (advice-remove 'TeX-arg-cite #'reftex-arg-cite)) + + (if (reftex-plug-flag 4) + (advice-add 'TeX-arg-index-tag :override #'reftex-arg-index-tag) + (advice-remove 'TeX-arg-index-tag #'reftex-arg-index-tag)) + (if (reftex-plug-flag 4) + (advice-add 'TeX-arg-index :override #'reftex-arg-index) + (advice-remove 'TeX-arg-index #'reftex-arg-index))) ;;;###autoload (defun reftex-toggle-plug-into-AUCTeX () @@ -205,7 +211,7 @@ the label information is recompiled on next use." (when changed (put reftex-docstruct-symbol 'reftex-label-alist-style list))))) ;;;###autoload -(defalias 'reftex-add-to-label-alist 'reftex-add-label-environments) +(defalias 'reftex-add-to-label-alist #'reftex-add-label-environments) ;;;###autoload (defun reftex-add-section-levels (entry-list) diff --git a/lisp/textmodes/reftex-cite.el b/lisp/textmodes/reftex-cite.el index 5579e40179..650d11d4ac 100644 --- a/lisp/textmodes/reftex-cite.el +++ b/lisp/textmodes/reftex-cite.el @@ -1,4 +1,4 @@ -;;; reftex-cite.el --- creating citations with RefTeX +;;; reftex-cite.el --- creating citations with RefTeX -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -310,11 +310,11 @@ Return list with entries." ;; Sorting (cond ((eq 'author reftex-sort-bibtex-matches) - (sort found-list 'reftex-bib-sort-author)) + (sort found-list #'reftex-bib-sort-author)) ((eq 'year reftex-sort-bibtex-matches) - (sort found-list 'reftex-bib-sort-year)) + (sort found-list #'reftex-bib-sort-year)) ((eq 'reverse-year reftex-sort-bibtex-matches) - (sort found-list 'reftex-bib-sort-year-reverse)) + (sort found-list #'reftex-bib-sort-year-reverse)) (t found-list)))) (defun reftex-bib-sort-author (e1 e2) @@ -390,7 +390,7 @@ The environment should be located in FILES." (when (and start end) (setq entries (append entries - (mapcar 'reftex-parse-bibitem + (mapcar #'reftex-parse-bibitem (delete "" (split-string (buffer-substring-no-properties @@ -533,7 +533,7 @@ If FORMAT is non-nil `format' entry accordingly." "Format a BibTeX ENTRY so that it is nice to look at." (let* ((auth-list (reftex-get-bib-names "author" entry)) - (authors (mapconcat 'identity auth-list ", ")) + (authors (mapconcat #'identity auth-list ", ")) (year (reftex-get-bib-field "year" entry)) (title (reftex-get-bib-field "title" entry)) (type (reftex-get-bib-field "&type" entry)) @@ -607,7 +607,7 @@ If FORMAT is non-nil `format' entry accordingly." (push (substring text 0 (+ 60 (match-beginning 0))) lines) (setq text (substring text (+ 61 (match-beginning 0))))) (push text lines) - (setq text (mapconcat 'identity (nreverse lines) "\n ")) + (setq text (mapconcat #'identity (nreverse lines) "\n ")) (when (reftex-use-fonts) (put-text-property 0 (length text) 'face reftex-bib-author-face text)) @@ -676,7 +676,7 @@ While entering the regexp, completion on knows citation keys is possible. ;; All keys go into a single command - we need to trick a little ;; FIXME: Unfortunately, this means that commenting does not work right. (pop selected-entries) - (let ((concat-keys (mapconcat 'car selected-entries + (let ((concat-keys (mapconcat #'car selected-entries reftex-cite-key-separator))) (setq insert-entries (list (list concat-keys (cons "&key" concat-keys)))))) @@ -726,7 +726,7 @@ While entering the regexp, completion on knows citation keys is possible. (when (and reftex-mode (fboundp 'LaTeX-add-bibitems) reftex-plug-into-AUCTeX) - (apply 'LaTeX-add-bibitems (mapcar 'car selected-entries))) + (apply #'LaTeX-add-bibitems (mapcar #'car selected-entries))) ;; Produce the cite-view strings (when (and reftex-mode reftex-cache-cite-echo cite-view) @@ -749,7 +749,7 @@ While entering the regexp, completion on knows citation keys is possible. (forward-char 1))) ;; Return the citation key - (mapcar 'car selected-entries))) + (mapcar #'car selected-entries))) (defun reftex-figure-out-cite-format (arg &optional no-insert format-key) "Check if there is already a cite command at point and change cite format @@ -815,15 +815,16 @@ in order to only add another reference in the same cite command." (reftex-citation nil ?t)) (defvar reftex-select-bib-map) +(defvar reftex--found-list) (defun reftex-offer-bib-menu () "Offer bib menu and return list of selected items." (let ((bibtype (reftex-bib-or-thebib)) - found-list rtn key data selected-entries) + reftex--found-list rtn key data selected-entries) (while (not (catch 'done ;; Scan bibtex files - (setq found-list + (setq reftex--found-list (cond ((eq bibtype 'bib) ; ((assq 'bib (symbol-value reftex-docstruct-symbol)) @@ -834,7 +835,7 @@ in order to only add another reference in the same cite command." ;; using thebibliography environment. (reftex-extract-bib-entries-from-thebibliography (reftex-uniquify - (mapcar 'cdr + (mapcar #'cdr (reftex-all-assq 'thebib (symbol-value reftex-docstruct-symbol)))))) (reftex-default-bibliography @@ -842,7 +843,7 @@ in order to only add another reference in the same cite command." (reftex-extract-bib-entries (reftex-default-bibliography))) (t (error "No valid bibliography in this document, and no default available")))) - (unless found-list + (unless reftex--found-list (error "Sorry, no matches found")) ;; Remember where we came from @@ -854,11 +855,11 @@ in order to only add another reference in the same cite command." (delete-other-windows) (reftex-kill-buffer "*RefTeX Select*") (switch-to-buffer-other-window "*RefTeX Select*") - (unless (eq major-mode 'reftex-select-bib-mode) + (unless (derived-mode-p 'reftex-select-bib-mode) (reftex-select-bib-mode)) - (let ((buffer-read-only nil)) + (let ((inhibit-read-only t)) (erase-buffer) - (reftex-insert-bib-matches found-list)) + (reftex-insert-bib-matches reftex--found-list)) (setq buffer-read-only t) (if (= 0 (buffer-size)) (error "No matches found")) @@ -881,34 +882,36 @@ in order to only add another reference in the same cite command." (throw 'done nil)) ((eq key ?r) ;; Restrict with new regular expression - (setq found-list (reftex-restrict-bib-matches found-list)) + (setq reftex--found-list + (reftex-restrict-bib-matches reftex--found-list)) (let ((buffer-read-only nil)) (erase-buffer) - (reftex-insert-bib-matches found-list)) + (reftex-insert-bib-matches reftex--found-list)) (goto-char 1)) ((eq key ?A) ;; Take all (marked) (setq selected-entries (if reftex-select-marked - (mapcar 'car (nreverse reftex-select-marked)) - found-list)) + (mapcar #'car (nreverse reftex-select-marked)) + reftex--found-list)) (throw 'done t)) ((eq key ?a) ;; Take all (marked), and push the symbol 'concat (setq selected-entries (cons 'concat (if reftex-select-marked - (mapcar 'car (nreverse reftex-select-marked)) - found-list))) + (mapcar #'car (nreverse reftex-select-marked)) + reftex--found-list))) (throw 'done t)) ((eq key ?e) ;; Take all (marked), and push the symbol 'concat - (reftex-extract-bib-file found-list reftex-select-marked) + (reftex-extract-bib-file reftex--found-list + reftex-select-marked) (setq selected-entries "BibTeX database file created") (throw 'done t)) ((eq key ?E) ;; Take all (marked), and push the symbol 'concat - (reftex-extract-bib-file found-list reftex-select-marked + (reftex-extract-bib-file reftex--found-list reftex-select-marked 'complement) (setq selected-entries "BibTeX database file created") (throw 'done t)) @@ -918,7 +921,7 @@ in order to only add another reference in the same cite command." (setq selected-entries (if reftex-select-marked (cons 'concat - (mapcar 'car (nreverse reftex-select-marked))) + (mapcar #'car (nreverse reftex-select-marked))) (if data (list data) nil))) (throw 'done t)) ((stringp key) @@ -971,7 +974,7 @@ in order to only add another reference in the same cite command." nil) (cdr (assoc "&entry" x)))) all))) - (insert (mapconcat 'identity all "\n\n")) + (insert (mapconcat #'identity all "\n\n")) (save-buffer) (goto-char (point-min)))) @@ -1004,7 +1007,7 @@ in order to only add another reference in the same cite command." last (nth (1- n) namelist)) (setcdr (nthcdr (- n 2) namelist) nil) (concat - (mapconcat 'identity namelist (nth 0 reftex-cite-punctuation)) + (mapconcat #'identity namelist (nth 0 reftex-cite-punctuation)) (nth 1 reftex-cite-punctuation) last))))) @@ -1100,7 +1103,7 @@ in order to only add another reference in the same cite command." (put reftex-docstruct-symbol 'modified t))) string)) -(defun reftex-bibtex-selection-callback (data ignore no-revisit) +(defun reftex-bibtex-selection-callback (data _ignore no-revisit) "Callback function to be called from the BibTeX selection, in order to display context. This function is relatively slow and not recommended for follow mode. It works OK for individual lookups." @@ -1119,7 +1122,7 @@ recommended for follow mode. It works OK for individual lookups." ; ((assq 'thebib (symbol-value reftex-docstruct-symbol)) (setq bibfile-list (reftex-uniquify - (mapcar 'cdr + (mapcar #'cdr (reftex-all-assq 'thebib (symbol-value reftex-docstruct-symbol)))) item t)) @@ -1163,7 +1166,7 @@ recommended for follow mode. It works OK for individual lookups." "Return a list of BibTeX @string references that appear as values in ALIST." (reftex-remove-if (lambda (x) (string-match "^\\([\"{]\\|[0-9]+$\\)" x)) ;; get list of values, discard keys - (mapcar 'cdr + (mapcar #'cdr ;; remove &key and &type entries (reftex-remove-if (lambda (pair) (string-match "^&" (car pair))) @@ -1186,7 +1189,7 @@ created files in the variables `reftex-create-bibtex-header' or (interactive "FNew BibTeX file: ") (let ((keys (reftex-all-used-citation-keys)) (files (reftex-get-bibfile-list)) - file key entries beg end entry string-keys string-entries) + key entries beg end entry string-keys string-entries) (save-current-buffer (dolist (file files) (set-buffer (reftex-get-file-buffer-force file 'mark)) @@ -1252,9 +1255,9 @@ created files in the variables `reftex-create-bibtex-header' or (error "Abort"))) (erase-buffer) (if reftex-create-bibtex-header (insert reftex-create-bibtex-header "\n\n")) - (insert (mapconcat 'identity (reverse string-entries) "\n\n")) + (insert (mapconcat #'identity (reverse string-entries) "\n\n")) (if string-entries (insert "\n\n\n")) - (insert (mapconcat 'identity (reverse entries) "\n\n")) + (insert (mapconcat #'identity (reverse entries) "\n\n")) (if reftex-create-bibtex-footer (insert "\n\n" reftex-create-bibtex-footer)) (goto-char (point-min)) (save-buffer) diff --git a/lisp/textmodes/reftex-dcr.el b/lisp/textmodes/reftex-dcr.el index e517cea266..a21dd3362b 100644 --- a/lisp/textmodes/reftex-dcr.el +++ b/lisp/textmodes/reftex-dcr.el @@ -1,4 +1,4 @@ -;;; reftex-dcr.el --- viewing cross references and citations with RefTeX +;;; reftex-dcr.el --- viewing cross references and citations with RefTeX -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -132,7 +132,7 @@ to the functions `reftex-view-cr-cite' and `reftex-view-cr-ref'." ((eq bibtype 'thebib) (setq item t files (reftex-uniquify - (mapcar 'cdr + (mapcar #'cdr (reftex-all-assq 'thebib (symbol-value reftex-docstruct-symbol)))))) (reftex-default-bibliography @@ -161,10 +161,10 @@ to the functions `reftex-view-cr-cite' and `reftex-view-cr-ref'." (shrink-window (1- (- (window-height) size))) (recenter 0)) ;; Arrange restoration - (add-hook 'pre-command-hook 'reftex-restore-window-conf)) + (add-hook 'pre-command-hook #'reftex-restore-window-conf)) ;; Normal display in other window - (add-hook 'pre-command-hook 'reftex-highlight-shall-die) + (add-hook 'pre-command-hook #'reftex-highlight-shall-die) (setq pop-win (selected-window)) (select-window win) (goto-char pos) @@ -212,13 +212,13 @@ to the functions `reftex-view-cr-cite' and `reftex-view-cr-ref'." (error (set-window-configuration window-conf) (message "ref: Label %s not found" label) (error "ref: Label %s not found" label)))) ;; 2nd is line OK - (add-hook 'pre-command-hook 'reftex-highlight-shall-die) + (add-hook 'pre-command-hook #'reftex-highlight-shall-die) (when (eq how 'tmp-window) ;; Resize window and arrange restoration (shrink-window (1- (- (window-height) 9))) (recenter '(4)) - (add-hook 'pre-command-hook 'reftex-restore-window-conf)) + (add-hook 'pre-command-hook #'reftex-restore-window-conf)) (setq pop-win (selected-window)) (select-window win) (goto-char pos) @@ -266,7 +266,7 @@ With argument, actually select the window showing the cross reference." (defun reftex-restore-window-conf () (set-window-configuration (get 'reftex-auto-view-crossref 'last-window-conf)) (put 'reftex-auto-view-crossref 'last-window-conf nil) - (remove-hook 'pre-command-hook 'reftex-restore-window-conf)) + (remove-hook 'pre-command-hook #'reftex-restore-window-conf)) (defun reftex-echo-ref (label entry docstruct) ;; Display crossref info in echo area. @@ -320,10 +320,6 @@ With argument, actually select the window showing the cross reference." (with-current-buffer buf (run-hooks 'reftex-display-copied-context-hook))))) -(defvar reftex-use-itimer-in-xemacs nil - "Non-nil means use the idle timers in XEmacs for crossref display. -Currently, idle timer restart is broken and we use the post-command-hook.") - ;;;###autoload (defun reftex-toggle-auto-view-crossref () "Toggle the automatic display of crossref information in the echo area. @@ -332,36 +328,16 @@ will display info in the echo area." (interactive) (if reftex-auto-view-crossref-timer (progn - (if (featurep 'xemacs) - (if reftex-use-itimer-in-xemacs - (delete-itimer reftex-auto-view-crossref-timer) - (remove-hook 'post-command-hook 'reftex-start-itimer-once)) - (cancel-timer reftex-auto-view-crossref-timer)) + (cancel-timer reftex-auto-view-crossref-timer) (setq reftex-auto-view-crossref-timer nil) (message "Automatic display of crossref information was turned off")) (setq reftex-auto-view-crossref-timer - (if (featurep 'xemacs) - (if reftex-use-itimer-in-xemacs - (start-itimer "RefTeX Idle Timer" - 'reftex-view-crossref-when-idle - reftex-idle-time reftex-idle-time t) - (add-hook 'post-command-hook 'reftex-start-itimer-once) - t) - (run-with-idle-timer - reftex-idle-time t 'reftex-view-crossref-when-idle))) + (run-with-idle-timer + reftex-idle-time t #'reftex-view-crossref-when-idle)) (unless reftex-auto-view-crossref (setq reftex-auto-view-crossref t)) (message "Automatic display of crossref information was turned on"))) -(defun reftex-start-itimer-once () - (and (featurep 'xemacs) - reftex-mode - (not (itimer-live-p reftex-auto-view-crossref-timer)) - (setq reftex-auto-view-crossref-timer - (start-itimer "RefTeX Idle Timer" - 'reftex-view-crossref-when-idle - reftex-idle-time nil t)))) - ;;;###autoload (defun reftex-view-crossref-from-bibtex (&optional arg) "View location in a LaTeX document which cites the BibTeX entry at point. @@ -431,7 +407,7 @@ Calling this function several times find successive citation locations." (put 'reftex-view-regexp-match :cnt (cl-incf cnt)) (reftex-highlight 0 (match-beginning highlight-group) (match-end highlight-group)) - (add-hook 'pre-command-hook 'reftex-highlight-shall-die) + (add-hook 'pre-command-hook #'reftex-highlight-shall-die) (setq pop-window (selected-window))) (put 'reftex-view-regexp-match :props nil) (or cont (set-window-configuration window-conf))) diff --git a/lisp/textmodes/reftex-global.el b/lisp/textmodes/reftex-global.el index 4d02160901..3b7518e5c3 100644 --- a/lisp/textmodes/reftex-global.el +++ b/lisp/textmodes/reftex-global.el @@ -1,4 +1,4 @@ -;;; reftex-global.el --- operations on entire documents with RefTeX +;;; reftex-global.el --- operations on entire documents with RefTeX -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -39,7 +39,7 @@ The TAGS file is also immediately visited with `visit-tags-table'." (reftex-access-scan-info current-prefix-arg) (let* ((master (reftex-TeX-master-file)) (files (reftex-all-document-files)) - (cmd (format "etags %s" (mapconcat 'shell-quote-argument + (cmd (format "etags %s" (mapconcat #'shell-quote-argument files " ")))) (with-current-buffer (reftex-get-file-buffer-force master) (message "Running etags to create TAGS file...") @@ -65,7 +65,7 @@ No active TAGS table is required." (let* ((files (reftex-all-document-files t)) (cmd (format "%s %s" grep-cmd - (mapconcat 'identity files " ")))) + (mapconcat #'identity files " ")))) (grep cmd))) ;;;###autoload @@ -160,7 +160,7 @@ No active TAGS table is required." (when (and (car (car dlist)) (cdr (car dlist))) (cl-incf cnt) - (insert (mapconcat 'identity (car dlist) "\n ") "\n")) + (insert (mapconcat #'identity (car dlist) "\n ") "\n")) (pop dlist)) (goto-char (point-min)) (when (= cnt 0) @@ -208,7 +208,7 @@ one with the `xr' package." (error "Abort")) ;; Make the translation list (let* ((re-core (concat "\\(" - (mapconcat 'cdr reftex-typekey-to-prefix-alist "\\|") + (mapconcat #'cdr reftex-typekey-to-prefix-alist "\\|") "\\)")) (label-re (concat "\\`" re-core "\\([0-9]+\\)\\'")) (search-re (concat "[{,]\\(" re-core "\\([0-9]+\\)\\)[,}]")) @@ -326,7 +326,7 @@ labels." file buffer) (save-current-buffer (while (setq file (pop files)) - (setq buffer (reftex-get-buffer-visiting file)) + (setq buffer (find-buffer-visiting file)) (when buffer (set-buffer buffer) (save-buffer)))))) @@ -344,7 +344,7 @@ Also checks if buffers visiting the files are in read-only mode." (ding) (or (y-or-n-p (format "No write access to %s. Continue? " file)) (error "Abort"))) - (when (and (setq buf (reftex-get-buffer-visiting file)) + (when (and (setq buf (find-buffer-visiting file)) (with-current-buffer buf buffer-read-only)) (ding) @@ -366,10 +366,10 @@ Also checks if buffers visiting the files are in read-only mode." (goto-char (if isearch-forward (point-min) (point-max)))) (defun reftex-isearch-push-state-function () - `(lambda (cmd) - (reftex-isearch-pop-state-function cmd ,(current-buffer)))) + (let ((buf (current-buffer))) + (lambda (cmd) (reftex-isearch-pop-state-function cmd buf)))) -(defun reftex-isearch-pop-state-function (cmd buffer) +(defun reftex-isearch-pop-state-function (_cmd buffer) (switch-to-buffer buffer)) (defun reftex-isearch-isearch-search (string bound noerror) @@ -451,17 +451,17 @@ With no argument, this command toggles (if (boundp 'multi-isearch-next-buffer-function) (set (make-local-variable 'multi-isearch-next-buffer-function) - 'reftex-isearch-switch-to-next-file) + #'reftex-isearch-switch-to-next-file) (set (make-local-variable 'isearch-wrap-function) - 'reftex-isearch-wrap-function) + #'reftex-isearch-wrap-function) (set (make-local-variable 'isearch-search-fun-function) - (lambda () 'reftex-isearch-isearch-search)) + (lambda () #'reftex-isearch-isearch-search)) (set (make-local-variable 'isearch-push-state-function) - 'reftex-isearch-push-state-function) + #'reftex-isearch-push-state-function) (set (make-local-variable 'isearch-next-buffer-function) - 'reftex-isearch-switch-to-next-file)) + #'reftex-isearch-switch-to-next-file)) (setq reftex-isearch-minor-mode t)))) - (add-hook 'reftex-mode-hook 'reftex-isearch-minor-mode)) + (add-hook 'reftex-mode-hook #'reftex-isearch-minor-mode)) (dolist (crt-buf (buffer-list)) (with-current-buffer crt-buf (when reftex-mode @@ -472,7 +472,7 @@ With no argument, this command toggles (kill-local-variable 'isearch-push-state-function) (kill-local-variable 'isearch-next-buffer-function)) (setq reftex-isearch-minor-mode nil)))) - (remove-hook 'reftex-mode-hook 'reftex-isearch-minor-mode))) + (remove-hook 'reftex-mode-hook #'reftex-isearch-minor-mode))) ;; Force mode line redisplay. (set-buffer-modified-p (buffer-modified-p)))) diff --git a/lisp/textmodes/reftex-index.el b/lisp/textmodes/reftex-index.el index 5049ffb64b..28cc7db2dc 100644 --- a/lisp/textmodes/reftex-index.el +++ b/lisp/textmodes/reftex-index.el @@ -1,4 +1,4 @@ -;;; reftex-index.el --- index support with RefTeX +;;; reftex-index.el --- index support with RefTeX -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -30,8 +30,6 @@ (require 'reftex) ;; START remove for XEmacs release -(defvar mark-active) -(defvar transient-mark-mode) (defvar TeX-master) ;; END remove for XEmacs release @@ -49,7 +47,7 @@ which is part of AUCTeX, the string is first processed with the (interactive "P") (let* ((use-default (not (equal arg '(16)))) ; check for double prefix ;; check if we have an active selection - (active (reftex-region-active-p)) + (active (region-active-p)) (beg (if active (region-beginning) (save-excursion @@ -89,7 +87,7 @@ which is part of AUCTeX, the string is first processed with the (reftex-index def-char full-entry def-tag sel))))) ;;;###autoload -(defun reftex-index (&optional char key tag sel no-insert) +(defun reftex-index (&optional char key tag sel _no-insert) "Query for an index macro and insert it along with its arguments. The index macros available are those defined in `reftex-index-macro' or by a call to `reftex-add-index-macros', typically from an AUCTeX style file. @@ -178,7 +176,7 @@ will prompt for other arguments." (format "default %s" default)) ""))) ": "))) - (tag (completing-read prompt (mapcar 'list index-tags)))) + (tag (completing-read prompt (mapcar #'list index-tags)))) (if (and default (equal tag "")) (setq tag default)) (reftex-update-default-index tag) tag)) @@ -239,7 +237,7 @@ will prompt for other arguments." (format "[^M] %s (the default)\n" default) "") (mapconcat (lambda(x) - (apply 'format "[%c] %s" x)) + (apply #'format "[%c] %s" x)) tag-alist "\n"))) ;; Query the user for an index-tag (setq rpl (reftex-select-with-char prompt help 3 t)) @@ -278,56 +276,57 @@ will prompt for other arguments." (defvar reftex-index-mode-map (let ((map (make-sparse-keymap))) ;; Index map - (define-key map (if (featurep 'xemacs) [(button2)] [(mouse-2)]) - 'reftex-index-mouse-goto-line-and-hide) + (define-key map [(mouse-2)] #'reftex-index-mouse-goto-line-and-hide) (define-key map [follow-link] 'mouse-face) (substitute-key-definition - 'next-line 'reftex-index-next map global-map) + #'next-line #'reftex-index-next map global-map) (substitute-key-definition - 'previous-line 'reftex-index-previous map global-map) - - (define-key map "n" 'reftex-index-next) - (define-key map "p" 'reftex-index-previous) - (define-key map "?" 'reftex-index-show-help) - (define-key map " " 'reftex-index-view-entry) - (define-key map "\C-m" 'reftex-index-goto-entry-and-hide) - (define-key map "\C-i" 'reftex-index-goto-entry) - (define-key map "\C-k" 'reftex-index-kill) - (define-key map "r" 'reftex-index-rescan) - (define-key map "R" 'reftex-index-Rescan) - (define-key map "g" 'revert-buffer) - (define-key map "q" 'reftex-index-quit) - (define-key map "k" 'reftex-index-quit-and-kill) - (define-key map "f" 'reftex-index-toggle-follow) - (define-key map "s" 'reftex-index-switch-index-tag) - (define-key map "e" 'reftex-index-edit) - (define-key map "^" 'reftex-index-level-up) - (define-key map "_" 'reftex-index-level-down) - (define-key map "}" 'reftex-index-restrict-to-section) - (define-key map "{" 'reftex-index-widen) - (define-key map ">" 'reftex-index-restriction-forward) - (define-key map "<" 'reftex-index-restriction-backward) - (define-key map "(" 'reftex-index-toggle-range-beginning) - (define-key map ")" 'reftex-index-toggle-range-end) - (define-key map "|" 'reftex-index-edit-attribute) - (define-key map "@" 'reftex-index-edit-visual) - (define-key map "*" 'reftex-index-edit-key) - (define-key map "\C-c=" 'reftex-index-goto-toc) - (define-key map "c" 'reftex-index-toggle-context) + #'previous-line #'reftex-index-previous map global-map) + + (define-key map "n" #'reftex-index-next) + (define-key map "p" #'reftex-index-previous) + (define-key map "?" #'reftex-index-show-help) + (define-key map " " #'reftex-index-view-entry) + (define-key map "\C-m" #'reftex-index-goto-entry-and-hide) + (define-key map "\C-i" #'reftex-index-goto-entry) + (define-key map "\C-k" #'reftex-index-kill) + (define-key map "r" #'reftex-index-rescan) + (define-key map "R" #'reftex-index-Rescan) + (define-key map "g" #'revert-buffer) + (define-key map "q" #'reftex-index-quit) + (define-key map "k" #'reftex-index-quit-and-kill) + (define-key map "f" #'reftex-index-toggle-follow) + (define-key map "s" #'reftex-index-switch-index-tag) + (define-key map "e" #'reftex-index-edit) + (define-key map "^" #'reftex-index-level-up) + (define-key map "_" #'reftex-index-level-down) + (define-key map "}" #'reftex-index-restrict-to-section) + (define-key map "{" #'reftex-index-widen) + (define-key map ">" #'reftex-index-restriction-forward) + (define-key map "<" #'reftex-index-restriction-backward) + (define-key map "(" #'reftex-index-toggle-range-beginning) + (define-key map ")" #'reftex-index-toggle-range-end) + (define-key map "|" #'reftex-index-edit-attribute) + (define-key map "@" #'reftex-index-edit-visual) + (define-key map "*" #'reftex-index-edit-key) + (define-key map "\C-c=" #'reftex-index-goto-toc) + (define-key map "c" #'reftex-index-toggle-context) ;; The capital letters and the exclamation mark - (cl-loop for key across (concat "!" reftex-index-section-letters) do - (define-key map (vector (list key)) - (list 'lambda '() '(interactive) - (list 'reftex-index-goto-letter key)))) + (mapc (lambda (key) + (define-key map (vector (list key)) + (lambda () (interactive) + (reftex-index-goto-letter key)))) + (concat "!" reftex-index-section-letters)) (easy-menu-define reftex-index-menu map "Menu for Index buffer" '("Index" ["Goto section A-Z" (message "To go to a section, just press any of: !%s" - reftex-index-section-letters) t] + reftex-index-section-letters) + t] ["Show Entry" reftex-index-view-entry t] ["Go To Entry" reftex-index-goto-entry t] ["Exit & Go To Entry" reftex-index-goto-entry-and-hide t] @@ -394,7 +393,7 @@ Press `?' for a summary of important key bindings, or check the menu. Here are all local bindings. \\{reftex-index-mode-map}" - (set (make-local-variable 'revert-buffer-function) 'reftex-index-revert) + (set (make-local-variable 'revert-buffer-function) #'reftex-index-revert) (set (make-local-variable 'reftex-index-restriction-data) nil) (set (make-local-variable 'reftex-index-restriction-indicator) nil) (setq mode-line-format @@ -403,15 +402,9 @@ Here are all local bindings. " R<" 'reftex-index-restriction-indicator ">" " -%-")) (setq truncate-lines t) - (when (featurep 'xemacs) - ;; XEmacs needs the call to make-local-hook - (make-local-hook 'post-command-hook) - (make-local-hook 'pre-command-hook)) (make-local-variable 'reftex-last-follow-point) - (when (featurep 'xemacs) - (easy-menu-add reftex-index-menu reftex-index-mode-map)) - (add-hook 'post-command-hook 'reftex-index-post-command-hook nil t) - (add-hook 'pre-command-hook 'reftex-index-pre-command-hook nil t)) + (add-hook 'post-command-hook #'reftex-index-post-command-hook nil t) + (add-hook 'pre-command-hook #'reftex-index-pre-command-hook nil t)) (defconst reftex-index-help " AVAILABLE KEYS IN INDEX BUFFER @@ -450,7 +443,7 @@ _ ^ Add/Remove parent key (to make this item a subitem). (match (cond ((or (not no-revisit) - (reftex-get-buffer-visiting file)) + (find-buffer-visiting file)) (switch-to-buffer-other-window (reftex-get-file-buffer-force file nil)) (goto-char (or pos (point-min))) @@ -567,7 +560,7 @@ SPC=view TAB=goto RET=goto+hide [e]dit [q]uit [r]escan [f]ollow [?]Help (run-hooks 'reftex-display-copied-context-hook) (message "Building %s buffer...done." buffer-name) (setq buffer-read-only t)) - (and locations (apply 'reftex-find-start-point (point) locations)) + (and locations (apply #'reftex-find-start-point (point) locations)) (if reftex-index-restriction-indicator (message "Index restricted: <%s>" reftex-index-restriction-indicator)))) @@ -582,7 +575,7 @@ SPC=view TAB=goto RET=goto+hide [e]dit [q]uit [r]escan [f]ollow [?]Help (indent " ") (context reftex-index-include-context) (context-indent (concat indent " ")) - (section-chars (mapcar 'identity reftex-index-section-letters)) + (section-chars (mapcar #'identity reftex-index-section-letters)) (this-section-char 0) (font (reftex-use-fonts)) (bor (car reftex-index-restriction-data)) @@ -733,9 +726,9 @@ SPC=view TAB=goto RET=goto+hide [e]dit [q]uit [r]escan [f]ollow [?]Help (if reftex-index-follow-mode (setq reftex-index-follow-mode 1))) -(defun reftex-index-next (&optional arg) +(defun reftex-index-next (&optional _arg) "Move to next selectable item." - (interactive "p") + (interactive "^") (setq reftex-callback-fwd t) (or (eobp) (forward-char 1)) (goto-char (or (next-single-property-change (point) :data) @@ -743,9 +736,9 @@ SPC=view TAB=goto RET=goto+hide [e]dit [q]uit [r]escan [f]ollow [?]Help (unless (get-text-property (point) :data) (goto-char (or (next-single-property-change (point) :data) (point))))) -(defun reftex-index-previous (&optional arg) +(defun reftex-index-previous (&optional _arg) "Move to previous selectable item." - (interactive "p") + (interactive "^") (setq reftex-callback-fwd nil) (goto-char (or (previous-single-property-change (point) :data) (point))) @@ -793,7 +786,7 @@ Label context is only displayed when the labels are there as well." (or (one-window-p) (delete-window)) (switch-to-buffer (marker-buffer reftex-index-return-marker)) (goto-char (or (marker-position reftex-index-return-marker) (point)))) -(defun reftex-index-goto-toc (&rest ignore) +(defun reftex-index-goto-toc (&rest _ignore) "Switch to the table of contents of the current document. The function will go to the section where the entry at point was defined." (interactive) @@ -802,7 +795,7 @@ The function will go to the section where the entry at point was defined." (switch-to-buffer (marker-buffer reftex-index-return-marker))) (delete-other-windows) (reftex-toc)) -(defun reftex-index-rescan (&rest ignore) +(defun reftex-index-rescan (&rest _ignore) "Regenerate the *Index* buffer after reparsing file of section at point." (interactive) (let ((index-tag reftex-index-tag)) @@ -818,7 +811,7 @@ The function will go to the section where the entry at point was defined." (reftex-display-index index-tag nil 'redo line))) (reftex-index-Rescan)) (reftex-kill-temporary-buffers))) -(defun reftex-index-Rescan (&rest ignore) +(defun reftex-index-Rescan (&rest _ignore) "Regenerate the *Index* buffer after reparsing the entire document." (interactive) (let ((index-tag reftex-index-tag) @@ -827,7 +820,7 @@ The function will go to the section where the entry at point was defined." (reftex-get-file-buffer-force reftex-last-index-file)) (setq current-prefix-arg '(16)) (reftex-display-index index-tag nil 'redo line))) -(defun reftex-index-revert (&rest ignore) +(defun reftex-index-revert (&rest _ignore) "Regenerate the *Index* from the internal lists. No reparsing os done." (interactive) (let ((buf (current-buffer)) @@ -840,7 +833,7 @@ The function will go to the section where the entry at point was defined." (setq current-prefix-arg nil reftex-last-follow-point 1) (reftex-display-index index-tag nil 'redo data line))) -(defun reftex-index-switch-index-tag (&rest ignore) +(defun reftex-index-switch-index-tag (&rest _ignore) "Switch to a different index of the same document." (interactive) (switch-to-buffer @@ -865,14 +858,14 @@ The function will go to the section where the entry at point was defined." reftex-index-restriction-indicator (nth 6 bor) ))) (reftex-index-revert)) -(defun reftex-index-widen (&rest ignore) +(defun reftex-index-widen (&rest _ignore) "Show the unrestricted index (all entries)." (interactive) (setq reftex-index-restriction-indicator nil reftex-index-restriction-data nil) (reftex-index-revert) (message "Index widened")) -(defun reftex-index-restriction-forward (&rest ignore) +(defun reftex-index-restriction-forward (&rest _ignore) "Restrict to previous section. When index is currently unrestricted, restrict it to a section. When index is restricted, select the next section as restriction criterion." @@ -888,7 +881,7 @@ When index is restricted, select the next section as restriction criterion." (car (memq (assq 'toc (cdr (memq bor docstruct))) docstruct)))) (reftex-index-revert)))) -(defun reftex-index-restriction-backward (&rest ignore) +(defun reftex-index-restriction-backward (&rest _ignore) "Restrict to next section. When index is currently unrestricted, restrict it to a section. When index is restricted, select the previous section as restriction criterion." @@ -986,7 +979,7 @@ When index is restricted, select the previous section as restriction criterion." (setq analyze (reftex-index-analyze-entry data) attr (nth 2 analyze)) (setf (nth 2 analyze) (if (string= attr bor) "" bor)) - (setq new (apply 'concat analyze)) + (setq new (apply #'concat analyze)) (reftex-index-change-entry new (if (string= (nth 2 analyze) bor) "Entry is now START-OF-PAGE-RANGE" @@ -1002,7 +995,7 @@ When index is restricted, select the previous section as restriction criterion." (setq analyze (reftex-index-analyze-entry data) attr (nth 2 analyze)) (setf (nth 2 analyze) (if (string= attr eor) "" eor)) - (setq new (apply 'concat analyze)) + (setq new (apply #'concat analyze)) (reftex-index-change-entry new (if (string= (nth 2 analyze) eor) "Entry is now END-OF-PAGE-RANGE" @@ -1043,7 +1036,7 @@ When index is restricted, select the previous section as restriction criterion." (error "Invalid value") (setf (nth n analyze) npart))) (t (setf (nth n analyze) (concat initial npart)))) - (setq new (apply 'concat analyze)) + (setq new (apply #'concat analyze)) ;; Change the entry and insert the changed version into the index. (reftex-index-change-entry new (if (string= npart "") @@ -1180,27 +1173,50 @@ This gets refreshed in every phrases command.") (defvar reftex-index-phrases-files nil "List of document files relevant for the phrases file.") -(defvar reftex-index-phrases-font-lock-keywords nil - "Font lock keywords for reftex-index-phrases-mode.") -(defvar reftex-index-phrases-font-lock-defaults nil - "Font lock defaults for reftex-index-phrases-mode.") +(defvar reftex-index-phrases-font-lock-keywords + (list + (cons reftex-index-phrases-comment-regexp 'font-lock-comment-face) + (list reftex-index-phrases-macrodef-regexp + '(1 font-lock-type-face) + '(2 font-lock-keyword-face) + '(3 'secondary-selection) + '(4 font-lock-function-name-face) + '(5 'secondary-selection) + '(6 font-lock-string-face)) + (list reftex-index-phrases-phrase-regexp1 + '(1 font-lock-keyword-face) + '(2 'secondary-selection) + '(3 font-lock-string-face) + '(4 'secondary-selection)) + (list reftex-index-phrases-phrase-regexp2 + '(1 font-lock-keyword-face) + '(2 'secondary-selection) + '(3 font-lock-string-face) + '(4 'secondary-selection) + '(5 font-lock-function-name-face)) + '("^\t$" . 'secondary-selection)) + "Font lock keywords for `reftex-index-phrases-mode'.") +(defvar reftex-index-phrases-font-lock-defaults + '((reftex-index-phrases-font-lock-keywords) + nil t nil beginning-of-line) + "Font lock defaults for `reftex-index-phrases-mode'.") (define-obsolete-variable-alias 'reftex-index-phrases-map 'reftex-index-phrases-mode-map "24.1") (defvar reftex-index-phrases-mode-map (let ((map (make-sparse-keymap))) ;; Keybindings and Menu for phrases buffer - (define-key map "\C-c\C-c" 'reftex-index-phrases-save-and-return) - (define-key map "\C-c\C-x" 'reftex-index-this-phrase) - (define-key map "\C-c\C-f" 'reftex-index-next-phrase) - (define-key map "\C-c\C-r" 'reftex-index-region-phrases) - (define-key map "\C-c\C-a" 'reftex-index-all-phrases) - (define-key map "\C-c\C-d" 'reftex-index-remaining-phrases) - (define-key map "\C-c\C-s" 'reftex-index-sort-phrases) - (define-key map "\C-c\C-n" 'reftex-index-new-phrase) - (define-key map "\C-c\C-m" 'reftex-index-phrases-set-macro-key) - (define-key map "\C-c\C-i" 'reftex-index-phrases-info) - (define-key map "\C-c\C-t" 'reftex-index-find-next-conflict-phrase) - (define-key map "\C-i" 'self-insert-command) + (define-key map "\C-c\C-c" #'reftex-index-phrases-save-and-return) + (define-key map "\C-c\C-x" #'reftex-index-this-phrase) + (define-key map "\C-c\C-f" #'reftex-index-next-phrase) + (define-key map "\C-c\C-r" #'reftex-index-region-phrases) + (define-key map "\C-c\C-a" #'reftex-index-all-phrases) + (define-key map "\C-c\C-d" #'reftex-index-remaining-phrases) + (define-key map "\C-c\C-s" #'reftex-index-sort-phrases) + (define-key map "\C-c\C-n" #'reftex-index-new-phrase) + (define-key map "\C-c\C-m" #'reftex-index-phrases-set-macro-key) + (define-key map "\C-c\C-i" #'reftex-index-phrases-info) + (define-key map "\C-c\C-t" #'reftex-index-find-next-conflict-phrase) + (define-key map "\C-i" #'self-insert-command) (easy-menu-define reftex-index-phrases-menu map "Menu for Phrases buffer" @@ -1295,7 +1311,7 @@ If the buffer is non-empty, delete the old header first." reftex-key-to-index-macro-alist))) (macro-alist (sort (copy-sequence reftex-index-macro-alist) - (lambda (a b) (equal (car a) default-macro)))) + (lambda (a _b) (equal (car a) default-macro)))) macro entry key repeat) (if master (set (make-local-variable 'TeX-master) @@ -1311,9 +1327,7 @@ If the buffer is non-empty, delete the old header first." (beginning-of-line 2)) (while (looking-at "^[ \t]*$") (beginning-of-line 2)) - (if (featurep 'xemacs) - (zmacs-activate-region) - (setq mark-active t)) + (activate-mark) (if (yes-or-no-p "Delete and rebuild header? ") (delete-region (point-min) (point)))) @@ -1336,7 +1350,6 @@ If the buffer is non-empty, delete the old header first." (if repeat "t" "nil")))) (insert "%---------------------------------------------------------------------\n\n\n"))) -(defvar TeX-master) (defun reftex-index-phrase-tex-master (&optional dir) "Return the name of the master file associated with a phrase buffer." (if (and (boundp 'TeX-master) @@ -1387,41 +1400,8 @@ Here are all local bindings. :syntax-table reftex-index-phrases-syntax-table (set (make-local-variable 'font-lock-defaults) reftex-index-phrases-font-lock-defaults) - (when (featurep 'xemacs) - (easy-menu-add reftex-index-phrases-menu reftex-index-phrases-mode-map)) (set (make-local-variable 'reftex-index-phrases-marker) (make-marker))) -;; (add-hook 'reftex-index-phrases-mode-hook 'turn-on-font-lock) - -;; Font Locking stuff -(let ((ss (if (featurep 'xemacs) 'secondary-selection ''secondary-selection))) - (setq reftex-index-phrases-font-lock-keywords - (list - (cons reftex-index-phrases-comment-regexp 'font-lock-comment-face) - (list reftex-index-phrases-macrodef-regexp - '(1 font-lock-type-face) - '(2 font-lock-keyword-face) - (list 3 ss) - '(4 font-lock-function-name-face) - (list 5 ss) - '(6 font-lock-string-face)) - (list reftex-index-phrases-phrase-regexp1 - '(1 font-lock-keyword-face) - (list 2 ss) - '(3 font-lock-string-face) - (list 4 ss)) - (list reftex-index-phrases-phrase-regexp2 - '(1 font-lock-keyword-face) - (list 2 ss) - '(3 font-lock-string-face) - (list 4 ss) - '(5 font-lock-function-name-face)) - (cons "^\t$" ss))) - (setq reftex-index-phrases-font-lock-defaults - '((reftex-index-phrases-font-lock-keywords) - nil t nil beginning-of-line)) - (put 'reftex-index-phrases-mode 'font-lock-defaults - reftex-index-phrases-font-lock-defaults) ; XEmacs - ) +;; (add-hook 'reftex-index-phrases-mode-hook #'turn-on-font-lock) (defun reftex-index-next-phrase (&optional arg) "Index the next ARG phrases in the phrases buffer." @@ -1561,9 +1541,7 @@ index the new part without having to go over the unchanged parts again." (unwind-protect (progn ;; Hide the region highlighting - (if (featurep 'xemacs) - (zmacs-deactivate-region) - (deactivate-mark)) + (deactivate-mark) (delete-other-windows) (reftex-index-visit-phrases-buffer) (reftex-index-all-phrases)) @@ -1593,7 +1571,7 @@ index the new part without having to go over the unchanged parts again." (if (and text (stringp text)) (insert text))) -(defun reftex-index-find-next-conflict-phrase (&optional arg) +(defun reftex-index-find-next-conflict-phrase (&optional _arg) "Find the next a phrase which is has conflicts in the phrase buffer. The command helps to find possible conflicts in the phrase indexing process. It searches downward from point for a phrase which is repeated elsewhere @@ -1601,7 +1579,7 @@ in the buffer, or which is a subphrase of another phrase. If such a phrase is found, the phrase info is displayed. To check the whole buffer, start at the beginning and continue by calling this function repeatedly." - (interactive "P") + (interactive) (if (catch 'exit (while (re-search-forward reftex-index-phrases-phrase-regexp12 nil t) (goto-char (match-beginning 3)) @@ -1743,6 +1721,8 @@ information about the currently selected macro." (if repeat "with" "without"))) (error "Abort"))))) +(defvar reftex--chars-first) + (defun reftex-index-sort-phrases (&optional chars-first) "Sort the phrases lines in the buffer alphabetically. Normally, this looks only at the phrases. With a prefix arg CHARS-FIRST, @@ -1762,19 +1742,18 @@ it first compares the macro identifying chars and then the phrases." (if end (setq end (progn (goto-char end) (end-of-line) (point)))) ;; Take the lines, sort them and re-insert. (if (and beg end) - (progn + (let ((reftex--chars-first chars-first)) (message "Sorting lines...") (let* ((lines (split-string (buffer-substring beg end) "\n")) - (lines1 (sort lines 'reftex-compare-phrase-lines))) + (lines1 (sort lines #'reftex-compare-phrase-lines))) (message "Sorting lines...done") (let ((inhibit-quit t)) ;; make sure we do not lose lines (delete-region beg end) - (insert (mapconcat 'identity lines1 "\n")))) + (insert (mapconcat #'identity lines1 "\n")))) (goto-char (point-max)) (re-search-backward (concat "^" (regexp-quote line) "$") nil t)) (error "Cannot find phrases lines to sort")))) -(defvar chars-first) (defun reftex-compare-phrase-lines (a b) "The comparison function used for sorting." (let (ca cb pa pb c-p p-p) @@ -1798,7 +1777,7 @@ it first compares the macro identifying chars and then the phrases." p-p (string< pa pb)) ;; Do the right comparison, based on the value of `chars-first' ;; `chars-first' is bound locally in the calling function - (if chars-first + (if reftex--chars-first (if (string= ca cb) p-p c-p) (if (string= pa pb) c-p p-p))))) ;; If line a does not match, the answer we return determines @@ -1830,14 +1809,14 @@ With optional arg ALLOW-NEWLINE, allow single newline between words." (defun reftex-index-simplify-phrase (phrase) "Make phrase single spaces and single line." - (mapconcat 'identity (split-string phrase) " ")) + (mapconcat #'identity (split-string phrase) " ")) (defun reftex-index-phrases-find-dup-re (phrase &optional sub) "Return a regexp which matches variations of PHRASE (with additional space). When SUB ins non-nil, the regexp will also match when PHRASE is a subphrase of another phrase. The regexp works lonly in the phrase buffer." (concat (if sub "^\\S-?\t\\([^\t\n]*" "^\\S-?\t") - (mapconcat 'regexp-quote (split-string phrase) " +") + (mapconcat #'regexp-quote (split-string phrase) " +") (if sub "[^\t\n]*\\)\\([\t\n]\\|$\\)" " *\\([\t\n]\\|$\\)"))) (defun reftex-index-make-replace-string (macro-fmt match index-key @@ -1870,7 +1849,7 @@ Treats the logical `and' for index phrases." (unless (stringp reftex-index-phrases-restrict-file) (widen)) (goto-char (point-min)) - (apply 'reftex-query-index-phrase args)))))) + (apply #'reftex-query-index-phrase args)))))) (reftex-unhighlight 0) (set-window-configuration win-conf)))) diff --git a/lisp/textmodes/reftex-parse.el b/lisp/textmodes/reftex-parse.el index 98c61f56b4..0157f8443a 100644 --- a/lisp/textmodes/reftex-parse.el +++ b/lisp/textmodes/reftex-parse.el @@ -1,4 +1,4 @@ -;;; reftex-parse.el --- parser functions for RefTeX +;;; reftex-parse.el --- parser functions for RefTeX -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -143,7 +143,7 @@ When allowed, do only a partial scan from FILE." (car (push (list 'is-multi is-multi) docstruct))))) (setcdr entry (cons is-multi nil))) (and reftex--index-tags - (setq reftex--index-tags (sort reftex--index-tags 'string<))) + (setq reftex--index-tags (sort reftex--index-tags #'string<))) (let ((index-tag-cell (assq 'index-tags docstruct))) (if index-tag-cell (setcdr index-tag-cell reftex--index-tags) @@ -160,10 +160,10 @@ When allowed, do only a partial scan from FILE." nil)) allxr)) (alist (delq nil alist)) - (allprefix (delq nil (mapcar 'car alist))) + (allprefix (delq nil (mapcar #'car alist))) (regexp (if allprefix (concat "\\`\\(" - (mapconcat 'identity allprefix "\\|") + (mapconcat #'identity allprefix "\\|") "\\)") "\\\\\\\\\\\\"))) ; this will never match (push (list 'xr alist regexp) docstruct))) @@ -209,7 +209,7 @@ of master file." (catch 'exit (setq file-found (reftex-locate-file file "tex" master-dir)) (if (and (not file-found) - (setq buf (reftex-get-buffer-visiting file))) + (setq buf (find-buffer-visiting file))) (setq file-found (buffer-file-name buf))) (unless file-found @@ -384,8 +384,9 @@ of master file." (concat ;; "\\(\\`\\|[\n\r]\\)[^%]*\\\\\\(" "\\(^\\)[^%\n\r]*\\\\\\(" - (mapconcat 'identity reftex-bibliography-commands "\\|") - "\\)\\(\\[.+?\\]\\)?{[ \t]*\\([^}]+\\)") nil t)) + (mapconcat #'identity reftex-bibliography-commands "\\|") + "\\)\\(\\[.+?\\]\\)?{[ \t]*\\([^}]+\\)") + nil t)) (setq files (append files (split-string (reftex-match-string 4) @@ -532,7 +533,7 @@ Careful: This function expects the match-data to be still in place!" (key (if prefix (concat prefix rawkey) rawkey)) (sortkey (downcase key)) - (showkey (mapconcat 'identity + (showkey (mapconcat #'identity (split-string key reftex-index-level-re) " ! "))) (goto-char end-of-args) diff --git a/lisp/textmodes/reftex-ref.el b/lisp/textmodes/reftex-ref.el index 439c02f808..611102ecba 100644 --- a/lisp/textmodes/reftex-ref.el +++ b/lisp/textmodes/reftex-ref.el @@ -1,4 +1,4 @@ -;;; reftex-ref.el --- code to create labels and references with RefTeX +;;; reftex-ref.el --- code to create labels and references with RefTeX -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -84,10 +84,12 @@ If optional BOUND is an integer, limit backward searches to that point." (if (or (re-search-forward (format reftex-find-label-regexp-format - (regexp-quote label)) nil t) + (regexp-quote label)) + nil t) (re-search-forward (format reftex-find-label-regexp-format2 - (regexp-quote label)) nil t)) + (regexp-quote label)) + nil t)) (progn (backward-char 1) @@ -248,13 +250,13 @@ This function is controlled by the settings of reftex-insert-label-flags." "" "POSITION UNCERTAIN. RESCAN TO FIX.")) (file (buffer-file-name)) - (text nil) + ;; (text nil) (tail (memq here-I-am (symbol-value reftex-docstruct-symbol)))) (or (cdr here-I-am-info) (setq rescan-is-useful t)) (when tail - (push (list label typekey text file nil note) (cdr tail)) + (push (list label typekey nil file nil note) (cdr tail)) (put reftex-docstruct-symbol 'modified t))) ;; Insert the label into the buffer @@ -286,7 +288,7 @@ also applies `reftex-translate-to-ascii-function' to the string." (when (and reftex-translate-to-ascii-function (fboundp reftex-translate-to-ascii-function)) (setq string (funcall reftex-translate-to-ascii-function string))) - (apply 'reftex-convert-string string + (apply #'reftex-convert-string string "[-~ \t\n\r,;]+" reftex-label-illegal-re nil nil reftex-derive-label-parameters)) @@ -402,6 +404,8 @@ also applies `reftex-translate-to-ascii-function' to the string." a / A Put all marked entries into one/many \\ref commands. q / RET Quit without referencing / Accept current label (also on mouse-2).") +(defvar reftex-refstyle) + ;;;###autoload (defun reftex-reference (&optional type no-insert cut) "Make a LaTeX reference. Look only for labels of a certain TYPE. @@ -473,7 +477,7 @@ When called with 2 C-u prefix args, disable magic word recognition." ;; If the first entry is the symbol 'concat, concat all labels. ;; We keep the cdr of the first label for typekey etc information. (if (eq (car labels) 'concat) - (setq labels (list (list (mapconcat 'car (cdr labels) ",") + (setq labels (list (list (mapconcat #'car (cdr labels) ",") (cdr (nth 1 labels)))))) (setq type (nth 1 (car labels)) form (or (cdr (assoc type reftex-typekey-to-format-alist)) @@ -502,7 +506,7 @@ When called with 2 C-u prefix args, disable magic word recognition." (setq form (substring form 1))) ;; do we have a special format? (unless (string= reftex-refstyle "\\ref") - (setq reftex-format-ref-function 'reftex-format-special)) + (setq reftex-format-ref-function #'reftex-format-special)) ;; ok, insert the reference (if sep1 (insert sep1)) (insert @@ -744,7 +748,7 @@ When called with 2 C-u prefix args, disable magic word recognition." ;; Goto the file in another window (setq buffer (if no-revisit - (reftex-get-buffer-visiting file) + (find-buffer-visiting file) (reftex-get-file-buffer-force file (not reftex-keep-temporary-buffers)))) (if buffer @@ -826,14 +830,16 @@ When called with 2 C-u prefix args, disable magic word recognition." (dolist (item (nth 2 elt)) (let ((macro (car item)) (package (nth 1 elt))) - (eval `(defun ,(intern (format "reftex-%s-%s" package - (substring macro 1 (length macro)))) () - ,(format "Insert a reference using the `%s' macro from the %s \ + (defalias (intern (format "reftex-%s-%s" package + (substring macro 1 (length macro)))) + (lambda () + (:documentation + (format "Insert a reference using the `%s' macro from the %s \ package.\n\nThis is a generated function." - macro package) - (interactive) - (let ((reftex-refstyle ,macro)) - (reftex-reference)))))))) + macro package)) + (interactive) + (let ((reftex-refstyle macro)) + (reftex-reference)))))))) (defun reftex-format-special (label fmt refstyle) "Apply selected reference style to format FMT and add LABEL. diff --git a/lisp/textmodes/reftex-sel.el b/lisp/textmodes/reftex-sel.el index d2e9974499..b0a8ebf8ac 100644 --- a/lisp/textmodes/reftex-sel.el +++ b/lisp/textmodes/reftex-sel.el @@ -1,4 +1,4 @@ -;;; reftex-sel.el --- the selection modes for RefTeX +;;; reftex-sel.el --- the selection modes for RefTeX -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -34,31 +34,29 @@ (let ((map (make-sparse-keymap))) (set-keymap-parent map special-mode-map) (substitute-key-definition - 'next-line 'reftex-select-next map global-map) + #'next-line #'reftex-select-next map global-map) (substitute-key-definition - 'previous-line 'reftex-select-previous map global-map) + #'previous-line #'reftex-select-previous map global-map) (substitute-key-definition - 'keyboard-quit 'reftex-select-keyboard-quit map global-map) + #'keyboard-quit #'reftex-select-keyboard-quit map global-map) (substitute-key-definition - 'newline 'reftex-select-accept map global-map) - - (define-key map " " 'reftex-select-callback) - (define-key map "n" 'reftex-select-next) - (define-key map [(down)] 'reftex-select-next) - (define-key map "p" 'reftex-select-previous) - (define-key map [(up)] 'reftex-select-previous) - (define-key map "f" 'reftex-select-toggle-follow) - (define-key map "\C-m" 'reftex-select-accept) - (define-key map [(return)] 'reftex-select-accept) - (define-key map "q" 'reftex-select-quit) - (define-key map "." 'reftex-select-show-insertion-point) - (define-key map "?" 'reftex-select-help) + #'newline #'reftex-select-accept map global-map) + + (define-key map " " #'reftex-select-callback) + (define-key map "n" #'reftex-select-next) + (define-key map [(down)] #'reftex-select-next) + (define-key map "p" #'reftex-select-previous) + (define-key map [(up)] #'reftex-select-previous) + (define-key map "f" #'reftex-select-toggle-follow) + (define-key map "\C-m" #'reftex-select-accept) + (define-key map [(return)] #'reftex-select-accept) + (define-key map "q" #'reftex-select-quit) + (define-key map "." #'reftex-select-show-insertion-point) + (define-key map "?" #'reftex-select-help) ;; The mouse-2 binding - (if (featurep 'xemacs) - (define-key map [(button2)] 'reftex-select-mouse-accept) - (define-key map [(mouse-2)] 'reftex-select-mouse-accept) - (define-key map [follow-link] 'mouse-face)) + (define-key map [(mouse-2)] #'reftex-select-mouse-accept) + (define-key map [follow-link] 'mouse-face) map)) (define-obsolete-variable-alias @@ -67,25 +65,26 @@ (let ((map (make-sparse-keymap))) (set-keymap-parent map reftex-select-shared-map) - (cl-loop for key across "aAcgFlrRstx#%" do - (define-key map (vector (list key)) - (list 'lambda '() - "Press `?' during selection to find out about this key." - '(interactive) (list 'throw '(quote myexit) key)))) - - (define-key map "b" 'reftex-select-jump-to-previous) - (define-key map "z" 'reftex-select-jump) - (define-key map "v" 'reftex-select-cycle-ref-style-forward) - (define-key map "V" 'reftex-select-cycle-ref-style-backward) - (define-key map "m" 'reftex-select-mark) - (define-key map "u" 'reftex-select-unmark) - (define-key map "," 'reftex-select-mark-comma) - (define-key map "-" 'reftex-select-mark-to) - (define-key map "+" 'reftex-select-mark-and) - (define-key map [(tab)] 'reftex-select-read-label) - (define-key map "\C-i" 'reftex-select-read-label) - (define-key map "\C-c\C-n" 'reftex-select-next-heading) - (define-key map "\C-c\C-p" 'reftex-select-previous-heading) + (mapc (lambda (key) + (define-key map (vector (list key)) + (lambda () + "Press `?' during selection to find out about this key." + (interactive) (throw 'myexit key)))) + "aAcgFlrRstx#%") + + (define-key map "b" #'reftex-select-jump-to-previous) + (define-key map "z" #'reftex-select-jump) + (define-key map "v" #'reftex-select-cycle-ref-style-forward) + (define-key map "V" #'reftex-select-cycle-ref-style-backward) + (define-key map "m" #'reftex-select-mark) + (define-key map "u" #'reftex-select-unmark) + (define-key map "," #'reftex-select-mark-comma) + (define-key map "-" #'reftex-select-mark-to) + (define-key map "+" #'reftex-select-mark-and) + (define-key map [(tab)] #'reftex-select-read-label) + (define-key map "\C-i" #'reftex-select-read-label) + (define-key map "\C-c\C-n" #'reftex-select-next-heading) + (define-key map "\C-c\C-p" #'reftex-select-previous-heading) map) "Keymap used for *RefTeX Select* buffer, when selecting a label. @@ -104,10 +103,6 @@ Press `?' for a summary of important key bindings. During a selection process, these are the local bindings. \\{reftex-select-label-mode-map}" - (when (featurep 'xemacs) - ;; XEmacs needs the call to make-local-hook - (make-local-hook 'pre-command-hook) - (make-local-hook 'post-command-hook)) (set (make-local-variable 'reftex-select-marked) nil) (when (syntax-table-p reftex-latex-syntax-table) (set-syntax-table reftex-latex-syntax-table)) @@ -120,16 +115,17 @@ During a selection process, these are the local bindings. (let ((map (make-sparse-keymap))) (set-keymap-parent map reftex-select-shared-map) - (cl-loop for key across "grRaAeE" do - (define-key map (vector (list key)) - (list 'lambda '() - "Press `?' during selection to find out about this key." - '(interactive) (list 'throw '(quote myexit) key)))) + (mapc (lambda (key) + (define-key map (vector (list key)) + (lambda () + "Press `?' during selection to find out about this key." + (interactive) (throw 'myexit key)))) + "grRaAeE") - (define-key map "\C-i" 'reftex-select-read-cite) - (define-key map [(tab)] 'reftex-select-read-cite) - (define-key map "m" 'reftex-select-mark) - (define-key map "u" 'reftex-select-unmark) + (define-key map "\C-i" #'reftex-select-read-cite) + (define-key map [(tab)] #'reftex-select-read-cite) + (define-key map "m" #'reftex-select-mark) + (define-key map "u" #'reftex-select-unmark) map) "Keymap used for *RefTeX Select* buffer, when selecting a BibTeX entry. @@ -148,10 +144,6 @@ Press `?' for a summary of important key bindings. During a selection process, these are the local bindings. \\{reftex-select-label-mode-map}" - (when (featurep 'xemacs) - ;; XEmacs needs the call to make-local-hook - (make-local-hook 'pre-command-hook) - (make-local-hook 'post-command-hook)) (set (make-local-variable 'reftex-select-marked) nil) ;; We do not set a local map - reftex-select-item does this. ) @@ -432,12 +424,21 @@ During a selection process, these are the local bindings. (defvar reftex-last-data nil) (defvar reftex-last-line nil) (defvar reftex-select-marked nil) +(defvar reftex-refstyle) + +;; The following variables are all bound dynamically in `reftex-select-item'. + +(defvar reftex-select-data) +(defvar reftex-select-prompt) +(defvar reftex--cb-flag) +(defvar reftex--last-data) +(defvar reftex--call-back) +(defvar reftex--help-string) ;;;###autoload -(defun reftex-select-item (reftex-select-prompt help-string keymap - &optional offset - call-back cb-flag) - ;; Select an item, using REFTEX-SELECT-PROMPT. +(defun reftex-select-item ( prompt help-string keymap + &optional offset call-back cb-flag) + ;; Select an item, using PROMPT. ;; The function returns a key indicating an exit status, along with a ;; data structure indicating which item was selected. ;; HELP-STRING contains help. KEYMAP is a keymap with the available @@ -448,7 +449,12 @@ During a selection process, these are the local bindings. ;; When CALL-BACK is given, it is a function which is called with the index ;; of the element. ;; CB-FLAG is the initial value of that flag. - (let (ev reftex-select-data last-data (selection-buffer (current-buffer))) + (let ((reftex-select-prompt prompt) + (reftex--help-string help-string) + (reftex--call-back call-back) + (reftex--cb-flag cb-flag) + ev reftex-select-data reftex--last-data + (selection-buffer (current-buffer))) (setq reftex-select-marked nil) @@ -466,43 +472,29 @@ During a selection process, these are the local bindings. (unwind-protect (progn (use-local-map keymap) - (add-hook 'pre-command-hook 'reftex-select-pre-command-hook nil t) - (add-hook 'post-command-hook 'reftex-select-post-command-hook nil t) + (add-hook 'pre-command-hook #'reftex-select-pre-command-hook nil t) + (add-hook 'post-command-hook #'reftex-select-post-command-hook nil t) (princ reftex-select-prompt) (set-marker reftex-recursive-edit-marker (point)) - ;; XEmacs does not run post-command-hook here - (and (featurep 'xemacs) (run-hooks 'post-command-hook)) (recursive-edit)) (set-marker reftex-recursive-edit-marker nil) (with-current-buffer selection-buffer (use-local-map nil) - (remove-hook 'pre-command-hook 'reftex-select-pre-command-hook t) + (remove-hook 'pre-command-hook #'reftex-select-pre-command-hook t) (remove-hook 'post-command-hook - 'reftex-select-post-command-hook t)) + #'reftex-select-post-command-hook t)) ;; Kill the mark overlays - (mapc (lambda (c) (reftex-delete-overlay (nth 1 c))) + (mapc (lambda (c) (delete-overlay (nth 1 c))) reftex-select-marked))))) (set (make-local-variable 'reftex-last-line) (+ (count-lines (point-min) (point)) (if (bolp) 1 0))) - (set (make-local-variable 'reftex-last-data) last-data) + (set (make-local-variable 'reftex-last-data) reftex--last-data) (reftex-kill-buffer "*RefTeX Help*") (setq reftex-callback-fwd (not reftex-callback-fwd)) ;; ;-))) (message "") - (list ev reftex-select-data last-data))) - -;; The following variables are all bound dynamically in `reftex-select-item'. -;; The defvars are here only to silence the byte compiler. - -(defvar found-list) -(defvar cb-flag) -(defvar reftex-select-data) -(defvar reftex-select-prompt) -(defvar last-data) -(defvar call-back) -(defvar help-string) -(defvar reftex-refstyle) + (list ev reftex-select-data reftex--last-data))) ;; The selection commands @@ -513,12 +505,12 @@ During a selection process, these are the local bindings. (defun reftex-select-post-command-hook () (let (b e) (setq reftex-select-data (get-text-property (point) :data)) - (setq last-data (or reftex-select-data last-data)) + (setq reftex--last-data (or reftex-select-data reftex--last-data)) - (when (and reftex-select-data cb-flag + (when (and reftex-select-data reftex--cb-flag (not (equal reftex-last-follow-point (point)))) (setq reftex-last-follow-point (point)) - (funcall call-back reftex-select-data reftex-callback-fwd + (funcall reftex--call-back reftex-select-data reftex-callback-fwd (not reftex-revisit-to-follow))) (if reftex-select-data (setq b (or (previous-single-property-change @@ -594,7 +586,7 @@ Useful for large TOC's." "Toggle follow mode: Other window follows with full context." (interactive) (setq reftex-last-follow-point -1) - (setq cb-flag (not cb-flag))) + (setq reftex--cb-flag (not reftex--cb-flag))) (defun reftex-select-cycle-ref-style-internal (&optional reverse) "Cycle through macros used for referencing. @@ -632,7 +624,9 @@ Cycle in reverse order if optional argument REVERSE is non-nil." (defun reftex-select-callback () "Show full context in another window." (interactive) - (if reftex-select-data (funcall call-back reftex-select-data reftex-callback-fwd nil) (ding))) + (if reftex-select-data + (funcall reftex--call-back reftex-select-data reftex-callback-fwd nil) + (ding))) (defun reftex-select-accept () "Accept the currently selected item." (interactive) @@ -642,7 +636,7 @@ Cycle in reverse order if optional argument REVERSE is non-nil." (interactive "e") (mouse-set-point ev) (setq reftex-select-data (get-text-property (point) :data)) - (setq last-data (or reftex-select-data last-data)) + (setq reftex--last-data (or reftex-select-data reftex--last-data)) (throw 'myexit 'return)) (defun reftex-select-read-label () "Use minibuffer to read a label to reference, with completion." @@ -652,16 +646,19 @@ Cycle in reverse order if optional argument REVERSE is non-nil." nil nil reftex-prefix))) (unless (or (equal label "") (equal label reftex-prefix)) (throw 'myexit label)))) + +(defvar reftex--found-list) + (defun reftex-select-read-cite () "Use minibuffer to read a citation key with completion." (interactive) - (let* ((key (completing-read "Citation key: " found-list)) - (entry (assoc key found-list))) + (let* ((key (completing-read "Citation key: " reftex--found-list)) + (entry (assoc key reftex--found-list))) (cond ((or (null key) (equal key ""))) (entry (setq reftex-select-data entry) - (setq last-data reftex-select-data) + (setq reftex--last-data reftex-select-data) (throw 'myexit 'return)) (t (throw 'myexit key))))) @@ -676,14 +673,14 @@ Cycle in reverse order if optional argument REVERSE is non-nil." (setq boe (or (previous-single-property-change (1+ (point)) :data) (point-min)) eoe (or (next-single-property-change (point) :data) (point-max))) - (setq ovl (reftex-make-overlay boe eoe)) + (setq ovl (make-overlay boe eoe)) (push (list data ovl separator) reftex-select-marked) - (reftex-overlay-put ovl 'font-lock-face reftex-select-mark-face) - (reftex-overlay-put ovl 'before-string - (if separator - (format "*%c%d* " separator - (length reftex-select-marked)) - (format "*%d* " (length reftex-select-marked)))) + (overlay-put ovl 'font-lock-face reftex-select-mark-face) + (overlay-put ovl 'before-string + (if separator + (format "*%c%d* " separator + (length reftex-select-marked)) + (format "*%d* " (length reftex-select-marked)))) (message "Entry has mark no. %d" (length reftex-select-marked)))) (defun reftex-select-mark-comma () @@ -709,15 +706,15 @@ Cycle in reverse order if optional argument REVERSE is non-nil." sep) (unless cell (error "No marked entry at point")) - (and ovl (reftex-delete-overlay ovl)) + (and ovl (delete-overlay ovl)) (setq reftex-select-marked (delq cell reftex-select-marked)) (setq cnt (1+ (length reftex-select-marked))) (mapc (lambda (c) (setq sep (nth 2 c)) - (reftex-overlay-put (nth 1 c) 'before-string - (if sep - (format "*%c%d* " sep (cl-decf cnt)) - (format "*%d* " (cl-decf cnt))))) + (overlay-put (nth 1 c) 'before-string + (if sep + (format "*%c%d* " sep (cl-decf cnt)) + (format "*%d* " (cl-decf cnt))))) reftex-select-marked) (message "Entry no longer marked"))) @@ -725,7 +722,7 @@ Cycle in reverse order if optional argument REVERSE is non-nil." "Display a summary of the special key bindings." (interactive) (with-output-to-temp-buffer "*RefTeX Help*" - (princ help-string)) + (princ reftex--help-string)) (reftex-enlarge-to-fit "*RefTeX Help*" t)) (provide 'reftex-sel) diff --git a/lisp/textmodes/reftex-toc.el b/lisp/textmodes/reftex-toc.el index 3b9f970a3d..b564349133 100644 --- a/lisp/textmodes/reftex-toc.el +++ b/lisp/textmodes/reftex-toc.el @@ -1,4 +1,4 @@ -;;; reftex-toc.el --- RefTeX's table of contents mode +;;; reftex-toc.el --- RefTeX's table of contents mode -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2000, 2003-2021 Free Software Foundation, Inc. @@ -32,8 +32,7 @@ (defvar reftex-toc-mode-map (let ((map (make-sparse-keymap))) - (define-key map (if (featurep 'xemacs) [(button2)] [(mouse-2)]) - 'reftex-toc-mouse-goto-line-and-hide) + (define-key map [(mouse-2)] #'reftex-toc-mouse-goto-line-and-hide) (define-key map [follow-link] 'mouse-face) (substitute-key-definition @@ -41,34 +40,34 @@ (substitute-key-definition 'previous-line 'reftex-toc-previous map global-map) - (define-key map "n" 'reftex-toc-next) - (define-key map "p" 'reftex-toc-previous) - (define-key map "?" 'reftex-toc-show-help) - (define-key map " " 'reftex-toc-view-line) - (define-key map "\C-m" 'reftex-toc-goto-line-and-hide) - (define-key map "\C-i" 'reftex-toc-goto-line) - (define-key map "\C-c>" 'reftex-toc-display-index) - (define-key map "r" 'reftex-toc-rescan) - (define-key map "R" 'reftex-toc-Rescan) - (define-key map "q" 'reftex-toc-quit) ; - (define-key map "k" 'reftex-toc-quit-and-kill) - (define-key map "f" 'reftex-toc-toggle-follow) ; - (define-key map "a" 'reftex-toggle-auto-toc-recenter) - (define-key map "d" 'reftex-toc-toggle-dedicated-frame) - (define-key map "F" 'reftex-toc-toggle-file-boundary) - (define-key map "i" 'reftex-toc-toggle-index) - (define-key map "l" 'reftex-toc-toggle-labels) - (define-key map "t" 'reftex-toc-max-level) - (define-key map "c" 'reftex-toc-toggle-context) - ;; (define-key map "%" 'reftex-toc-toggle-commented) - (define-key map "\M-%" 'reftex-toc-rename-label) - (define-key map "x" 'reftex-toc-external) - (define-key map "z" 'reftex-toc-jump) - (define-key map "." 'reftex-toc-show-calling-point) - (define-key map "\C-c\C-n" 'reftex-toc-next-heading) - (define-key map "\C-c\C-p" 'reftex-toc-previous-heading) - (define-key map ">" 'reftex-toc-demote) - (define-key map "<" 'reftex-toc-promote) + (define-key map "n" #'reftex-toc-next) + (define-key map "p" #'reftex-toc-previous) + (define-key map "?" #'reftex-toc-show-help) + (define-key map " " #'reftex-toc-view-line) + (define-key map "\C-m" #'reftex-toc-goto-line-and-hide) + (define-key map "\C-i" #'reftex-toc-goto-line) + (define-key map "\C-c>" #'reftex-toc-display-index) + (define-key map "r" #'reftex-toc-rescan) + (define-key map "R" #'reftex-toc-Rescan) + (define-key map "q" #'reftex-toc-quit) ; + (define-key map "k" #'reftex-toc-quit-and-kill) + (define-key map "f" #'reftex-toc-toggle-follow) ; + (define-key map "a" #'reftex-toggle-auto-toc-recenter) + (define-key map "d" #'reftex-toc-toggle-dedicated-frame) + (define-key map "F" #'reftex-toc-toggle-file-boundary) + (define-key map "i" #'reftex-toc-toggle-index) + (define-key map "l" #'reftex-toc-toggle-labels) + (define-key map "t" #'reftex-toc-max-level) + (define-key map "c" #'reftex-toc-toggle-context) + ;; (define-key map "%" #'reftex-toc-toggle-commented) + (define-key map "\M-%" #'reftex-toc-rename-label) + (define-key map "x" #'reftex-toc-external) + (define-key map "z" #'reftex-toc-jump) + (define-key map "." #'reftex-toc-show-calling-point) + (define-key map "\C-c\C-n" #'reftex-toc-next-heading) + (define-key map "\C-c\C-p" #'reftex-toc-previous-heading) + (define-key map ">" #'reftex-toc-demote) + (define-key map "<" #'reftex-toc-promote) (easy-menu-define reftex-toc-menu map @@ -130,9 +129,7 @@ Here are all local bindings. \\{reftex-toc-mode-map}" (set (make-local-variable 'transient-mark-mode) t) - (when (featurep 'xemacs) - (set (make-local-variable 'zmacs-regions) t)) - (set (make-local-variable 'revert-buffer-function) 'reftex-toc-revert) + (set (make-local-variable 'revert-buffer-function) #'reftex-toc-revert) (set (make-local-variable 'reftex-toc-include-labels-indicator) "") (set (make-local-variable 'reftex-toc-max-level-indicator) (if (= reftex-toc-max-level 100) @@ -146,15 +143,9 @@ Here are all local bindings. " T<" 'reftex-toc-max-level-indicator ">" " -%-")) (setq truncate-lines t) - (when (featurep 'xemacs) - ;; XEmacs needs the call to make-local-hook - (make-local-hook 'post-command-hook) - (make-local-hook 'pre-command-hook)) (make-local-variable 'reftex-last-follow-point) - (add-hook 'post-command-hook 'reftex-toc-post-command-hook nil t) - (add-hook 'pre-command-hook 'reftex-toc-pre-command-hook nil t) - (when (featurep 'xemacs) - (easy-menu-add reftex-toc-menu reftex-toc-mode-map))) + (add-hook 'post-command-hook #'reftex-toc-post-command-hook nil t) + (add-hook 'pre-command-hook #'reftex-toc-pre-command-hook nil t)) (defvar reftex-last-toc-file nil "Stores the file name from which `reftex-toc' was called. For redo command.") @@ -420,7 +411,6 @@ SPC=view TAB=goto RET=goto+hide [q]uit [r]escan [l]abels [f]ollow [x]r [?]Help (defun reftex-toc-next (&optional _arg) "Move to next selectable item." (interactive) - (when (featurep 'xemacs) (setq zmacs-region-stays t)) (setq reftex-callback-fwd t) (or (eobp) (forward-char 1)) (goto-char (or (next-single-property-change (point) :data) @@ -428,21 +418,18 @@ SPC=view TAB=goto RET=goto+hide [q]uit [r]escan [l]abels [f]ollow [x]r [?]Help (defun reftex-toc-previous (&optional _arg) "Move to previous selectable item." (interactive) - (when (featurep 'xemacs) (setq zmacs-region-stays t)) (setq reftex-callback-fwd nil) (goto-char (or (previous-single-property-change (point) :data) (point)))) (defun reftex-toc-next-heading (&optional arg) "Move to next table of contents line." (interactive "p") - (when (featurep 'xemacs) (setq zmacs-region-stays t)) (end-of-line) (re-search-forward "^ " nil t arg) (beginning-of-line)) (defun reftex-toc-previous-heading (&optional arg) "Move to previous table of contents line." (interactive "p") - (when (featurep 'xemacs) (setq zmacs-region-stays t)) (re-search-backward "^ " nil t arg)) (defun reftex-toc-toggle-follow () "Toggle follow (other window follows with context)." @@ -662,7 +649,7 @@ point." (let* ((reftex--start-line (+ (count-lines (point-min) (point)) (if (bolp) 1 0))) (reftex--mark-line - (if (reftex-region-active-p) + (if (region-active-p) (save-excursion (goto-char (mark)) (+ (count-lines (point-min) (point)) (if (bolp) 1 0))))) @@ -671,7 +658,7 @@ point." beg end entries data sections nsec msg) (setq msg (catch 'exit - (if (reftex-region-active-p) + (if (region-active-p) ;; A region is dangerous, check if we have a brand new scan, ;; to make sure we are not missing any section statements. (if (not (reftex-toc-check-docstruct)) @@ -712,7 +699,7 @@ point." nil ; we have permission, do nothing (error "Abort")) ; abort, we don't have permission ;; Do the changes - (mapc 'reftex-toc-promote-action entries) + (mapc #'reftex-toc-promote-action entries) ;; Rescan the document and rebuilt the toc buffer (save-window-excursion (reftex-toc-Rescan)) @@ -734,10 +721,8 @@ point." (forward-line (1- point-line))) (when mpos (set-mark mpos) - (if (featurep 'xemacs) - (zmacs-activate-region) - (setq mark-active t - deactivate-mark nil))))) + (setq mark-active t + deactivate-mark nil)))) (defun reftex-toc-promote-prepare (x delta) "Look at a TOC entry and see if we could pro/demote it. @@ -918,7 +903,7 @@ label prefix determines the wording of a reference." (setq match (let ((where (car toc)) (file (nth 1 toc))) - (if (or (not no-revisit) (reftex-get-buffer-visiting file)) + (if (or (not no-revisit) (find-buffer-visiting file)) (progn (switch-to-buffer-other-window (reftex-get-file-buffer-force file nil)) @@ -981,7 +966,7 @@ label prefix determines the wording of a reference." reftex-section-levels-all))) "[[{]?")))) ((or (not no-revisit) - (reftex-get-buffer-visiting file)) + (find-buffer-visiting file)) ;; Marker is lost. Use the backup method. (switch-to-buffer-other-window (reftex-get-file-buffer-force file nil)) @@ -1035,18 +1020,12 @@ section." (interactive) (if reftex-toc-auto-recenter-timer (progn - (if (featurep 'xemacs) - (delete-itimer reftex-toc-auto-recenter-timer) - (cancel-timer reftex-toc-auto-recenter-timer)) + (cancel-timer reftex-toc-auto-recenter-timer) (setq reftex-toc-auto-recenter-timer nil) (message "Automatic recentering of TOC window was turned off")) (setq reftex-toc-auto-recenter-timer - (if (featurep 'xemacs) - (start-itimer "RefTeX Idle Timer for recenter" - 'reftex-recenter-toc-when-idle - reftex-idle-time reftex-idle-time t) - (run-with-idle-timer - reftex-idle-time t 'reftex-recenter-toc-when-idle))) + (run-with-idle-timer + reftex-idle-time t #'reftex-recenter-toc-when-idle)) (message "Automatic recentering of TOC window was turned on"))) (defun reftex-toc-toggle-dedicated-frame () @@ -1090,15 +1069,12 @@ always show the current section in connection with the option (switch-to-buffer "*toc*") (select-frame current-frame) (cond ((fboundp 'x-focus-frame) - (x-focus-frame current-frame)) - ((and (featurep 'xemacs) ; `focus-frame' is a nop in Emacs. - (fboundp 'focus-frame)) - (focus-frame current-frame))) + (x-focus-frame current-frame))) (select-window current-window) (when (eq reftex-auto-recenter-toc 'frame) (unless reftex-toc-auto-recenter-timer (reftex-toggle-auto-toc-recenter)) - (add-hook 'delete-frame-functions 'reftex-toc-delete-frame-hook))))) + (add-hook 'delete-frame-functions #'reftex-toc-delete-frame-hook))))) (defun reftex-toc-delete-frame-hook (frame) (if (and reftex-toc-auto-recenter-timer diff --git a/lisp/textmodes/reftex-vars.el b/lisp/textmodes/reftex-vars.el index 5b1e8bd8b5..a65772da1a 100644 --- a/lisp/textmodes/reftex-vars.el +++ b/lisp/textmodes/reftex-vars.el @@ -1,4 +1,4 @@ -;;; reftex-vars.el --- configuration variables for RefTeX +;;; reftex-vars.el --- configuration variables for RefTeX -*- lexical-binding: t; -*- ;; Copyright (C) 1997-1999, 2001-2021 Free Software Foundation, Inc. @@ -282,7 +282,7 @@ distribution. Mixed-case symbols are convenience aliases.") The file name is expected after the command, either in braces or separated by whitespace." :group 'reftex-table-of-contents-browser - :set 'reftex-set-dirty + :set #'reftex-set-dirty :type '(repeat string)) (defcustom reftex-max-section-depth 12 @@ -319,7 +319,7 @@ commands, promotion only works correctly if this list is sorted first by set, then within each set by level. The promotion commands always select the nearest entry with the correct new level." :group 'reftex-table-of-contents-browser - :set 'reftex-set-dirty + :set #'reftex-set-dirty :type '(repeat (cons (string :tag "sectioning macro" "") (choice @@ -463,7 +463,7 @@ The value of this variable is a list of symbols with associations in the constant `reftex-label-alist-builtin'. Check that constant for a full list of options." :group 'reftex-defining-label-environments - :set 'reftex-set-dirty + :set #'reftex-set-dirty :type `(set :indent 4 :inline t @@ -611,7 +611,7 @@ Any list entry may also be a symbol. If that has an association in list. However, builtin defaults should normally be set with the variable `reftex-default-label-alist-entries'." :group 'reftex-defining-label-environments - :set 'reftex-set-dirty + :set #'reftex-set-dirty :type `(repeat (choice :tag "Package or Detailed " @@ -1198,7 +1198,7 @@ File names matched by these regexps will not be parsed by RefTeX. Intended for files which contain only `@string' macro definitions and the like, which are ignored by RefTeX anyway." :group 'reftex-citation-support - :set 'reftex-set-dirty + :set #'reftex-set-dirty :type '(repeat (regexp))) (defcustom reftex-default-bibliography nil @@ -1460,7 +1460,7 @@ Note that AUCTeX sets these things internally for RefTeX as well, so with a sufficiently new version of AUCTeX, you should not set the package here." :group 'reftex-index-support - :set 'reftex-set-dirty + :set #'reftex-set-dirty :type `(list (repeat :inline t @@ -1728,7 +1728,7 @@ Multiple directories can be separated by the system dependent `path-separator'. Directories ending in `//' or `!!' will be expanded recursively. See also `reftex-use-external-file-finders'." :group 'reftex-finding-files - :set 'reftex-set-dirty + :set #'reftex-set-dirty :type '(repeat (string :tag "Specification"))) (defcustom reftex-bibpath-environment-variables '("BIBINPUTS" "TEXBIB") @@ -1744,7 +1744,7 @@ Directories ending in `//' or `!!' will be expanded recursively. See also `reftex-use-external-file-finders'." :group 'reftex-citation-support :group 'reftex-finding-files - :set 'reftex-set-dirty + :set #'reftex-set-dirty :type '(repeat (string :tag "Specification"))) (defcustom reftex-file-extensions '(("tex" . (".tex" ".ltx")) diff --git a/lisp/textmodes/reftex.el b/lisp/textmodes/reftex.el index 269d676c2b..c732299361 100644 --- a/lisp/textmodes/reftex.el +++ b/lisp/textmodes/reftex.el @@ -1,4 +1,4 @@ -;;; reftex.el --- minor mode for doing \label, \ref, \cite, \index in LaTeX +;;; reftex.el --- minor mode for doing \label, \ref, \cite, \index in LaTeX -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2000, 2003-2021 Free Software Foundation, Inc. ;; Author: Carsten Dominik @@ -38,9 +38,8 @@ ;; ;; https://www.gnu.org/software/auctex/manual/reftex.index.html ;; -;; RefTeX is bundled with Emacs and available as a plug-in package for -;; XEmacs 21.x. If you need to install it yourself, you can find a -;; distribution at +;; RefTeX is bundled with Emacs. +;; If you need to install it yourself, you can find a distribution at ;; ;; https://www.gnu.org/software/auctex/reftex.html ;; @@ -100,37 +99,34 @@ (defvar reftex-mode-map (let ((map (make-sparse-keymap))) ;; The default bindings in the mode map. - (define-key map "\C-c=" 'reftex-toc) - (define-key map "\C-c-" 'reftex-toc-recenter) - (define-key map "\C-c(" 'reftex-label) - (define-key map "\C-c)" 'reftex-reference) - (define-key map "\C-c[" 'reftex-citation) - (define-key map "\C-c<" 'reftex-index) - (define-key map "\C-c>" 'reftex-display-index) - (define-key map "\C-c/" 'reftex-index-selection-or-word) - (define-key map "\C-c\\" 'reftex-index-phrase-selection-or-word) - (define-key map "\C-c|" 'reftex-index-visit-phrases-buffer) - (define-key map "\C-c&" 'reftex-view-crossref) + (define-key map "\C-c=" #'reftex-toc) + (define-key map "\C-c-" #'reftex-toc-recenter) + (define-key map "\C-c(" #'reftex-label) + (define-key map "\C-c)" #'reftex-reference) + (define-key map "\C-c[" #'reftex-citation) + (define-key map "\C-c<" #'reftex-index) + (define-key map "\C-c>" #'reftex-display-index) + (define-key map "\C-c/" #'reftex-index-selection-or-word) + (define-key map "\C-c\\" #'reftex-index-phrase-selection-or-word) + (define-key map "\C-c|" #'reftex-index-visit-phrases-buffer) + (define-key map "\C-c&" #'reftex-view-crossref) ;; Bind `reftex-mouse-view-crossref' only when the key is still free - (if (featurep 'xemacs) - (unless (key-binding [(shift button2)]) - (define-key map [(shift button2)] 'reftex-mouse-view-crossref)) - (unless (key-binding [(shift mouse-2)]) - (define-key map [(shift mouse-2)] 'reftex-mouse-view-crossref))) + (unless (key-binding [(shift mouse-2)]) + (define-key map [(shift mouse-2)] #'reftex-mouse-view-crossref)) ;; For most of these commands there are already bindings in place. ;; Setting `reftex-extra-bindings' really is only there to spare users ;; the hassle of defining bindings in the user space themselves. This ;; is why they violate the key binding recommendations. (when reftex-extra-bindings - (define-key map "\C-ct" 'reftex-toc) - (define-key map "\C-cl" 'reftex-label) - (define-key map "\C-cr" 'reftex-reference) - (define-key map "\C-cc" 'reftex-citation) - (define-key map "\C-cv" 'reftex-view-crossref) - (define-key map "\C-cg" 'reftex-grep-document) - (define-key map "\C-cs" 'reftex-search-document)) + (define-key map "\C-ct" #'reftex-toc) + (define-key map "\C-cl" #'reftex-label) + (define-key map "\C-cr" #'reftex-reference) + (define-key map "\C-cc" #'reftex-citation) + (define-key map "\C-cv" #'reftex-view-crossref) + (define-key map "\C-cg" #'reftex-grep-document) + (define-key map "\C-cs" #'reftex-search-document)) map) "Keymap for RefTeX mode.") @@ -204,8 +200,6 @@ on the menu bar. (if reftex-mode (progn ;; Mode was turned on - (when (featurep 'xemacs) - (easy-menu-add reftex-mode-menu)) (and reftex-plug-into-AUCTeX (reftex-plug-into-AUCTeX)) (unless (get 'reftex-auto-view-crossref 'initialized) @@ -220,10 +214,7 @@ on the menu bar. ;; Prepare the special syntax tables. (reftex--prepare-syntax-tables) - (run-hooks 'reftex-mode-hook)) - ;; Mode was turned off - (when (featurep 'xemacs) - (easy-menu-remove reftex-mode-menu)))) + (run-hooks 'reftex-mode-hook)))) (defvar reftex-docstruct-symbol) (defun reftex-kill-buffer-hook () @@ -391,11 +382,11 @@ If the symbols for the current master file do not exist, they are created." ((null master) (error "Need a filename for this buffer, please save it first")) ((or (file-exists-p (concat master ".tex")) - (reftex-get-buffer-visiting (concat master ".tex"))) + (find-buffer-visiting (concat master ".tex"))) ;; Ahh, an extra .tex was missing... (setq master (concat master ".tex"))) ((or (file-exists-p master) - (reftex-get-buffer-visiting master)) + (find-buffer-visiting master)) ;; We either see the file, or have a buffer on it. OK. ) (t @@ -890,7 +881,7 @@ This enforces rescanning the buffer on next use." ;; Are the magic words regular expressions? Quote normal words. (if (eq (car wordlist) 'regexp) (setq wordlist (cdr wordlist)) - (setq wordlist (mapcar 'regexp-quote wordlist))) + (setq wordlist (mapcar #'regexp-quote wordlist))) ;; Remember the first association of each word. (while (stringp (setq word (pop wordlist))) (or (assoc word reftex-words-to-typekey-alist) @@ -1017,11 +1008,11 @@ This enforces rescanning the buffer on next use." (wbol "\\(^\\)%?[ \t]*") ; Need to keep the empty group because ; match numbers are hard coded (label-re (concat "\\(?:" - (mapconcat 'identity reftex-label-regexps "\\|") + (mapconcat #'identity reftex-label-regexps "\\|") "\\)")) (include-re (concat wbol "\\\\\\(" - (mapconcat 'identity + (mapconcat #'identity reftex-include-file-commands "\\|") "\\)[{ \t]+\\([^} \t\n\r]+\\)")) (section-re @@ -1033,23 +1024,24 @@ This enforces rescanning the buffer on next use." (macro-re (if macros-with-labels (concat "\\(" - (mapconcat 'regexp-quote macros-with-labels "\\|") + (mapconcat #'regexp-quote macros-with-labels "\\|") "\\)[[{]") "")) (index-re (concat "\\(" - (mapconcat 'regexp-quote reftex-macros-with-index "\\|") + (mapconcat #'regexp-quote reftex-macros-with-index "\\|") "\\)[[{]")) (find-index-re-format (concat "\\(" - (mapconcat 'regexp-quote reftex-macros-with-index "\\|") + (mapconcat #'regexp-quote reftex-macros-with-index "\\|") "\\)\\([[{][^]}]*[]}]\\)*[[{]\\(%s\\)[]}]")) (find-label-re-format (concat "\\(" "label[[:space:]]*=[[:space:]]*" "\\|" - (mapconcat 'regexp-quote (append '("\\label") - macros-with-labels) "\\|") + (mapconcat #'regexp-quote (append '("\\label") + macros-with-labels) + "\\|") "\\)\\([[{][^]}]*[]}]\\)*[[{]\\(%s\\)[]}]")) (index-level-re (regexp-quote (nth 0 reftex-index-special-chars))) @@ -1081,7 +1073,7 @@ This enforces rescanning the buffer on next use." "\\([]} \t\n\r]\\)\\([[{]\\)\\(%s\\)[]}]") (message "Compiling label environment definitions...done"))) (put reftex-docstruct-symbol 'reftex-cache - (mapcar 'symbol-value reftex-cache-variables))) + (mapcar #'symbol-value reftex-cache-variables))) (defun reftex-parse-args (macro) ;; Return a list of macro name, nargs, arg-nr which is label and a list of @@ -1277,8 +1269,8 @@ Valid actions are: readable, restore, read, kill, write." (- 1 xr-index)) (t (save-excursion - (let* ((length (apply 'max (mapcar - (lambda(x) (length (car x))) xr-alist))) + (let* ((length (apply #'max (mapcar + (lambda(x) (length (car x))) xr-alist))) (fmt (format " [%%c] %%-%ds %%s\n" length)) (n (1- ?0))) (setq key @@ -1312,7 +1304,7 @@ When DIE is non-nil, throw an error if file not found." (extensions (cdr (assoc type reftex-file-extensions))) (def-ext (car extensions)) (ext-re (concat "\\(" - (mapconcat 'regexp-quote extensions "\\|") + (mapconcat #'regexp-quote extensions "\\|") "\\)\\'")) (files (if (string-match ext-re file) (cons file nil) @@ -1354,7 +1346,7 @@ When DIE is non-nil, throw an error if file not found." out) (if (string-match "%f" prg) (setq prg (replace-match file t t prg))) - (setq out (apply 'reftex-process-string (split-string prg))) + (setq out (apply #'reftex-process-string (split-string prg))) (if (string-match "[ \t\n]+\\'" out) ; chomp (setq out (replace-match "" nil nil out))) (cond ((equal out "") nil) @@ -1367,7 +1359,7 @@ When DIE is non-nil, throw an error if file not found." (with-output-to-string (with-current-buffer standard-output (let ((default-directory calling-dir)) ; set default directory - (apply 'call-process program nil '(t nil) nil args)))))) + (apply #'call-process program nil '(t nil) nil args)))))) (defun reftex-access-search-path (type &optional recurse master-dir file) ;; Access path from environment variables. TYPE is either "tex" or "bib". @@ -1386,7 +1378,7 @@ When DIE is non-nil, throw an error if file not found." (mapconcat (lambda(x) (if (string-match "^!" x) - (apply 'reftex-process-string + (apply #'reftex-process-string (split-string (substring x 1))) (or (getenv x) x))) ;; For consistency, the next line should look like this: @@ -1531,12 +1523,7 @@ When DIE is non-nil, throw an error if file not found." (when (match-beginning n) (buffer-substring-no-properties (match-beginning n) (match-end n)))) -(defun reftex-region-active-p () - "Should we operate on an active region?" - (if (fboundp 'use-region-p) - (use-region-p) - ;; For XEmacs. - (region-active-p))) +(define-obsolete-function-alias 'reftex-region-active-p #'use-region-p "28.1") (defun reftex-kill-buffer (buffer) ;; Kill buffer if it exists. @@ -1745,26 +1732,12 @@ When DIE is non-nil, throw an error if file not found." (setq string (replace-match "[\n\r]" nil t string))) string)) -(defun reftex-get-buffer-visiting (file) - ;; return a buffer visiting FILE - (cond - ((boundp 'find-file-compare-truenames) ; XEmacs - (let ((find-file-compare-truenames t)) - (get-file-buffer file))) - ((fboundp 'find-buffer-visiting) ; Emacs - (find-buffer-visiting file)) - (t (error "This should not happen (reftex-get-buffer-visiting)")))) - -;; Define `current-message' for compatibility with XEmacs prior to 20.4 -(defvar message-stack) -(if (and (featurep 'xemacs) - (not (fboundp 'current-message))) - (defun current-message (&optional _frame) - (cdr (car message-stack)))) +(define-obsolete-function-alias 'reftex-get-buffer-visiting + #'find-buffer-visiting "28.1") (defun reftex-visited-files (list) ;; Takes a list of filenames and returns the buffers of those already visited - (delq nil (mapcar (lambda (x) (if (reftex-get-buffer-visiting x) x nil)) + (delq nil (mapcar (lambda (x) (if (find-buffer-visiting x) x nil)) list))) (defun reftex-get-file-buffer-force (file &optional mark-to-kill) @@ -1774,7 +1747,7 @@ When DIE is non-nil, throw an error if file not found." ;; initializations according to `reftex-initialize-temporary-buffers', ;; and mark the buffer to be killed after use. - (let ((buf (reftex-get-buffer-visiting file))) + (let ((buf (find-buffer-visiting file))) (cond (buf ;; We have it already as a buffer - just return it @@ -1866,7 +1839,7 @@ When DIE is non-nil, throw an error if file not found." (setq list (copy-sequence list)) (if sort (progn - (setq list (sort list 'string<)) + (setq list (sort list #'string<)) (let ((p list)) (while (cdr p) (if (string= (car p) (car (cdr p))) @@ -2003,7 +1976,7 @@ IGNORE-WORDS List of words which should be removed from the string." (setcdr (nthcdr (1- nwords) words) nil)) ;; First, try to use all words - (setq string (mapconcat 'identity words sep)) + (setq string (mapconcat #'identity words sep)) ;; Abbreviate words if enforced by user settings or string length (if (or (eq t abbrev) @@ -2017,7 +1990,7 @@ IGNORE-WORDS List of words which should be removed from the string." (match-string 1 w)) w)) words) - string (mapconcat 'identity words sep))) + string (mapconcat #'identity words sep))) ;; Shorten if still to long (setq string @@ -2081,24 +2054,11 @@ IGNORE-WORDS List of words which should be removed from the string." (progn ;; Rename buffer temporarily to start w/o space (because of font-lock) (rename-buffer newname t) - (cond - ((fboundp 'font-lock-default-fontify-region) - ;; Good: we have the indirection functions - (set (make-local-variable 'font-lock-fontify-region-function) - 'reftex-select-font-lock-fontify-region) - (let ((major-mode 'latex-mode)) - (font-lock-mode 1))) - ((fboundp 'font-lock-set-defaults-1) - ;; Looks like the XEmacs font-lock stuff. - ;; FIXME: this is still kind of a hack, but it works. - (set (make-local-variable 'font-lock-keywords) nil) - (let ((major-mode 'latex-mode) - (font-lock-defaults-computed nil)) - (font-lock-set-defaults-1) - (reftex-select-font-lock-fontify-region (point-min) (point-max)))) - (t - ;; Oops? - (message "Sorry: cannot refontify RefTeX Select buffer.")))) + ;; Good: we have the indirection functions + (set (make-local-variable 'font-lock-fontify-region-function) + #'reftex-select-font-lock-fontify-region) + (let ((major-mode 'latex-mode)) + (font-lock-mode 1))) (rename-buffer oldname)))) (defun reftex-select-font-lock-fontify-region (beg end &optional _loudly) @@ -2123,46 +2083,39 @@ IGNORE-WORDS List of words which should be removed from the string." (let (face) (catch 'exit (while (setq face (pop faces)) - (if (featurep 'xemacs) - (if (find-face face) (throw 'exit face)) - (if (facep face) (throw 'exit face))))))) - -;; Highlighting uses overlays. For XEmacs, we use extends. -(defalias 'reftex-make-overlay - (if (featurep 'xemacs) 'make-extent 'make-overlay)) -(defalias 'reftex-overlay-put - (if (featurep 'xemacs) 'set-extent-property 'overlay-put)) -(defalias 'reftex-move-overlay - (if (featurep 'xemacs) 'set-extent-endpoints 'move-overlay)) -(defalias 'reftex-delete-overlay - (if (featurep 'xemacs) 'detach-extent 'delete-overlay)) + (if (facep face) (throw 'exit face)))))) + +(define-obsolete-function-alias 'reftex-make-overlay #'make-overlay "28.1") +(define-obsolete-function-alias 'reftex-overlay-put #'overlay-put "28.1") +(define-obsolete-function-alias 'reftex-move-overlay #'move-overlay "28.1") +(define-obsolete-function-alias 'reftex-delete-overlay #'delete-overlay "28.1") ;; We keep a vector with several different overlays to do our highlighting. (defvar reftex-highlight-overlays [nil nil nil]) ;; Initialize the overlays -(aset reftex-highlight-overlays 0 (reftex-make-overlay 1 1)) -(reftex-overlay-put (aref reftex-highlight-overlays 0) +(aset reftex-highlight-overlays 0 (make-overlay 1 1)) +(overlay-put (aref reftex-highlight-overlays 0) 'face 'highlight) -(aset reftex-highlight-overlays 1 (reftex-make-overlay 1 1)) -(reftex-overlay-put (aref reftex-highlight-overlays 1) +(aset reftex-highlight-overlays 1 (make-overlay 1 1)) +(overlay-put (aref reftex-highlight-overlays 1) 'face reftex-cursor-selected-face) -(aset reftex-highlight-overlays 2 (reftex-make-overlay 1 1)) -(reftex-overlay-put (aref reftex-highlight-overlays 2) +(aset reftex-highlight-overlays 2 (make-overlay 1 1)) +(overlay-put (aref reftex-highlight-overlays 2) 'face reftex-cursor-selected-face) ;; Two functions for activating and deactivation highlight overlays (defun reftex-highlight (index begin end &optional buffer) "Highlight a region with overlay INDEX." - (reftex-move-overlay (aref reftex-highlight-overlays index) + (move-overlay (aref reftex-highlight-overlays index) begin end (or buffer (current-buffer)))) (defun reftex-unhighlight (index) "Detach overlay INDEX." - (reftex-delete-overlay (aref reftex-highlight-overlays index))) + (delete-overlay (aref reftex-highlight-overlays index))) (defun reftex-highlight-shall-die () ;; Function used in pre-command-hook to remove highlights. - (remove-hook 'pre-command-hook 'reftex-highlight-shall-die) + (remove-hook 'pre-command-hook #'reftex-highlight-shall-die) (reftex-unhighlight 0)) ;;; ========================================================================= @@ -2174,7 +2127,7 @@ IGNORE-WORDS List of words which should be removed from the string." ;; Bind `reftex-view-crossref-from-bibtex' in BibTeX mode map (eval-after-load "bibtex" - '(define-key bibtex-mode-map "\C-c&" 'reftex-view-crossref-from-bibtex)) + '(define-key bibtex-mode-map "\C-c&" #'reftex-view-crossref-from-bibtex)) ;;; ========================================================================= ;;; @@ -2379,9 +2332,9 @@ Your bug report will be posted to the AUCTeX bug reporting list. ;;; Install the kill-buffer and kill-emacs hooks ------------------------------ -(add-hook 'kill-buffer-hook 'reftex-kill-buffer-hook) +(add-hook 'kill-buffer-hook #'reftex-kill-buffer-hook) (unless noninteractive - (add-hook 'kill-emacs-hook 'reftex-kill-emacs-hook)) + (add-hook 'kill-emacs-hook #'reftex-kill-emacs-hook)) ;;; Run Hook ------------------------------------------------------------------ diff --git a/lisp/textmodes/remember.el b/lisp/textmodes/remember.el index 6a72ebb332..b731c12442 100644 --- a/lisp/textmodes/remember.el +++ b/lisp/textmodes/remember.el @@ -1,4 +1,4 @@ -;;; remember --- a mode for quickly jotting down things to remember +;;; remember --- a mode for quickly jotting down things to remember -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2001, 2003-2021 Free Software Foundation, Inc. @@ -270,12 +270,13 @@ With a prefix or a visible region, use the region as INITIAL." (buffer-substring (region-beginning) (region-end))))) (funcall (if remember-in-new-frame #'frameset-to-register - #'window-configuration-to-register) remember-register) + #'window-configuration-to-register) + remember-register) (let* ((annotation (if remember-run-all-annotation-functions-flag - (mapconcat 'identity + (mapconcat #'identity (delq nil - (mapcar 'funcall remember-annotation-functions)) + (mapcar #'funcall remember-annotation-functions)) "\n") (run-hook-with-args-until-success 'remember-annotation-functions))) @@ -283,7 +284,8 @@ With a prefix or a visible region, use the region as INITIAL." (run-hooks 'remember-before-remember-hook) (funcall (if remember-in-new-frame #'switch-to-buffer-other-frame - #'switch-to-buffer-other-window) buf) + #'switch-to-buffer-other-window) + buf) (if remember-in-new-frame (set-window-dedicated-p (get-buffer-window (current-buffer) (selected-frame)) t)) @@ -384,7 +386,7 @@ exists) might be changed." (with-current-buffer buf (set-visited-file-name (expand-file-name remember-data-file)))))) - :initialize 'custom-initialize-default) + :initialize #'custom-initialize-default) (defcustom remember-leader-text "** " "The text used to begin each remember item." @@ -541,7 +543,7 @@ If this is nil, then `diary-file' will be used instead." (while (re-search-forward remember-diary-regexp nil t) (push (remember-diary-convert-entry (match-string 1)) list)) (when list - (diary-make-entry (mapconcat 'identity list "\n") + (diary-make-entry (mapconcat #'identity list "\n") nil remember-diary-file) (when remember-save-after-remembering (with-current-buffer (find-buffer-visiting (or remember-diary-file @@ -553,9 +555,9 @@ If this is nil, then `diary-file' will be used instead." (defvar remember-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\C-x\C-s" 'remember-finalize) - (define-key map "\C-c\C-c" 'remember-finalize) - (define-key map "\C-c\C-k" 'remember-destroy) + (define-key map "\C-x\C-s" #'remember-finalize) + (define-key map "\C-c\C-c" #'remember-finalize) + (define-key map "\C-c\C-k" #'remember-destroy) map) "Keymap used in `remember-mode'.") @@ -601,7 +603,7 @@ If this is nil, use `initial-major-mode'." (defvar remember-notes-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\C-c\C-c" 'remember-notes-save-and-bury-buffer) + (define-key map "\C-c\C-c" #'remember-notes-save-and-bury-buffer) map) "Keymap used in `remember-notes-mode'.") diff --git a/lisp/textmodes/table.el b/lisp/textmodes/table.el index 60122b2fac..a9f066c4da 100644 --- a/lisp/textmodes/table.el +++ b/lisp/textmodes/table.el @@ -1306,17 +1306,16 @@ the last cache point coordinate." (let ((func-symbol (intern (format "*table--cell-%s" command))) (doc-string (format "Table remapped function for `%s'." command))) (defalias func-symbol - `(lambda - (&rest args) - ,doc-string - (interactive) - (let ((table-inhibit-update t) - (deactivate-mark nil)) - (table--finish-delayed-tasks) - (table-recognize-cell 'force) - (table-with-cache-buffer - (call-interactively ',command) - (setq table-inhibit-auto-fill-paragraph t))))) + (lambda (&rest _args) + (:documentation doc-string) + (interactive) + (let ((table-inhibit-update t) + (deactivate-mark nil)) + (table--finish-delayed-tasks) + (table-recognize-cell 'force) + (table-with-cache-buffer + (call-interactively command) + (setq table-inhibit-auto-fill-paragraph t))))) (push (cons command func-symbol) table-command-remap-alist))) @@ -1338,17 +1337,16 @@ the last cache point coordinate." (let ((func-symbol (intern (format "*table--cell-%s" command))) (doc-string (format "Table remapped function for `%s'." command))) (defalias func-symbol - `(lambda - (&rest args) - ,doc-string - (interactive) - (table--finish-delayed-tasks) - (table-recognize-cell 'force) - (table-with-cache-buffer - (table--remove-cell-properties (point-min) (point-max)) - (table--remove-eol-spaces (point-min) (point-max)) - (call-interactively ',command)) - (table--finish-delayed-tasks))) + (lambda (&rest _args) + (:documentation doc-string) + (interactive) + (table--finish-delayed-tasks) + (table-recognize-cell 'force) + (table-with-cache-buffer + (table--remove-cell-properties (point-min) (point-max)) + (table--remove-eol-spaces (point-min) (point-max)) + (call-interactively command)) + (table--finish-delayed-tasks))) (push (cons command func-symbol) table-command-remap-alist))) @@ -1360,19 +1358,18 @@ the last cache point coordinate." insert)) (let ((func-symbol (intern (format "*table--cell-%s" command))) (doc-string (format "Table remapped function for `%s'." command))) - (fset func-symbol - `(lambda - (&rest args) - ,doc-string - (interactive) - (table--finish-delayed-tasks) - (table-recognize-cell 'force) - (table-with-cache-buffer - (call-interactively ',command) - (table--untabify (point-min) (point-max)) - (table--fill-region (point-min) (point-max)) - (setq table-inhibit-auto-fill-paragraph t)) - (table--finish-delayed-tasks))) + (defalias func-symbol + (lambda (&rest _args) + (:documentation doc-string) + (interactive) + (table--finish-delayed-tasks) + (table-recognize-cell 'force) + (table-with-cache-buffer + (call-interactively command) + (table--untabify (point-min) (point-max)) + (table--fill-region (point-min) (point-max)) + (setq table-inhibit-auto-fill-paragraph t)) + (table--finish-delayed-tasks))) (push (cons command func-symbol) table-command-remap-alist))) @@ -1384,18 +1381,17 @@ the last cache point coordinate." fill-paragraph)) (let ((func-symbol (intern (format "*table--cell-%s" command))) (doc-string (format "Table remapped function for `%s'." command))) - (fset func-symbol - `(lambda - (&rest args) - ,doc-string - (interactive) - (table--finish-delayed-tasks) - (table-recognize-cell 'force) - (table-with-cache-buffer - (let ((fill-column table-cell-info-width)) - (call-interactively ',command)) - (setq table-inhibit-auto-fill-paragraph t)) - (table--finish-delayed-tasks))) + (defalias func-symbol + (lambda (&rest _args) + (:documentation doc-string) + (interactive) + (table--finish-delayed-tasks) + (table-recognize-cell 'force) + (table-with-cache-buffer + (let ((fill-column table-cell-info-width)) + (call-interactively command)) + (setq table-inhibit-auto-fill-paragraph t)) + (table--finish-delayed-tasks))) (push (cons command func-symbol) table-command-remap-alist))) @@ -2975,8 +2971,8 @@ CALS (DocBook DTD): (setq col-list (cons (car lu-coordinate) col-list))) (unless (memq (cdr lu-coordinate) row-list) (setq row-list (cons (cdr lu-coordinate) row-list)))))) - (setq col-list (sort col-list '<)) - (setq row-list (sort row-list '<)) + (setq col-list (sort col-list #'<)) + (setq row-list (sort row-list #'<)) (message "Generating source...") ;; clear the source generation property list (setplist 'table-source-info-plist nil) @@ -3023,7 +3019,7 @@ CALS (DocBook DTD): ""))) ((eq language 'latex) (insert (format "%% This LaTeX table template is generated by emacs %s\n" emacs-version) - "\\begin{tabular}{|" (apply 'concat (make-list (length col-list) "l|")) "}\n" + "\\begin{tabular}{|" (apply #'concat (make-list (length col-list) "l|")) "}\n" "\\hline\n")) ((eq language 'cals) (insert (format "\n" emacs-version) @@ -3054,7 +3050,7 @@ CALS (DocBook DTD): (set-marker-insertion-type (table-get-source-info 'colspec-marker) t) ;; insert before (save-excursion (goto-char (table-get-source-info 'colspec-marker)) - (dolist (col (sort (table-get-source-info 'colnum-list) '<)) + (dolist (col (sort (table-get-source-info 'colnum-list) #'<)) (insert (format " \n" col col)))) (insert (format " \n \n\n" (table-get-source-info 'row-type)))) ((eq language 'mediawiki) @@ -3852,7 +3848,7 @@ converts a table into plain text without frames. It is a companion to ;; Create the keymap after running the user init file so that the user ;; modification to the global-map is accounted. -(add-hook 'after-init-hook 'table--make-cell-map t) +(add-hook 'after-init-hook #'table--make-cell-map t) (defun *table--cell-self-insert-command () "Table cell version of `self-insert-command'." diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el index d5a79ad0ac..fb57b9b0f2 100644 --- a/lisp/textmodes/tex-mode.el +++ b/lisp/textmodes/tex-mode.el @@ -857,11 +857,11 @@ START is the position of the \\ and DELIM is the delimiter char." (defun tex-define-common-keys (keymap) "Define the keys that we want defined both in TeX mode and in the TeX shell." - (define-key keymap "\C-c\C-k" 'tex-kill-job) - (define-key keymap "\C-c\C-l" 'tex-recenter-output-buffer) - (define-key keymap "\C-c\C-q" 'tex-show-print-queue) - (define-key keymap "\C-c\C-p" 'tex-print) - (define-key keymap "\C-c\C-v" 'tex-view) + (define-key keymap "\C-c\C-k" #'tex-kill-job) + (define-key keymap "\C-c\C-l" #'tex-recenter-output-buffer) + (define-key keymap "\C-c\C-q" #'tex-show-print-queue) + (define-key keymap "\C-c\C-p" #'tex-print) + (define-key keymap "\C-c\C-v" #'tex-view) (define-key keymap [menu-bar tex] (cons "TeX" (make-sparse-keymap "TeX"))) @@ -884,27 +884,27 @@ START is the position of the \\ and DELIM is the delimiter char." (let ((map (make-sparse-keymap))) (set-keymap-parent map text-mode-map) (tex-define-common-keys map) - (define-key map "\"" 'tex-insert-quote) - (define-key map "\n" 'tex-handle-newline) - (define-key map "\M-\r" 'latex-insert-item) - (define-key map "\C-c}" 'up-list) - (define-key map "\C-c{" 'tex-insert-braces) - (define-key map "\C-c\C-r" 'tex-region) - (define-key map "\C-c\C-b" 'tex-buffer) - (define-key map "\C-c\C-f" 'tex-file) - (define-key map "\C-c\C-c" 'tex-compile) - (define-key map "\C-c\C-i" 'tex-bibtex-file) - (define-key map "\C-c\C-o" 'latex-insert-block) + (define-key map "\"" #'tex-insert-quote) + (define-key map "\n" #'tex-handle-newline) + (define-key map "\M-\r" #'latex-insert-item) + (define-key map "\C-c}" #'up-list) + (define-key map "\C-c{" #'tex-insert-braces) + (define-key map "\C-c\C-r" #'tex-region) + (define-key map "\C-c\C-b" #'tex-buffer) + (define-key map "\C-c\C-f" #'tex-file) + (define-key map "\C-c\C-c" #'tex-compile) + (define-key map "\C-c\C-i" #'tex-bibtex-file) + (define-key map "\C-c\C-o" #'latex-insert-block) ;; Redundant keybindings, for consistency with SGML mode. - (define-key map "\C-c\C-t" 'latex-insert-block) - (define-key map "\C-c]" 'latex-close-block) - (define-key map "\C-c/" 'latex-close-block) - - (define-key map "\C-c\C-e" 'latex-close-block) - (define-key map "\C-c\C-u" 'tex-goto-last-unclosed-latex-block) - (define-key map "\C-c\C-m" 'tex-feed-input) - (define-key map [(control return)] 'tex-feed-input) + (define-key map "\C-c\C-t" #'latex-insert-block) + (define-key map "\C-c]" #'latex-close-block) + (define-key map "\C-c/" #'latex-close-block) + + (define-key map "\C-c\C-e" #'latex-close-block) + (define-key map "\C-c\C-u" #'tex-goto-last-unclosed-latex-block) + (define-key map "\C-c\C-m" #'tex-feed-input) + (define-key map [(control return)] #'tex-feed-input) (define-key map [menu-bar tex tex-bibtex-file] '("BibTeX File" . tex-bibtex-file)) (define-key map [menu-bar tex tex-validate-region] @@ -922,7 +922,7 @@ START is the position of the \\ and DELIM is the delimiter char." (defvar latex-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map tex-mode-map) - (define-key map "\C-c\C-s" 'latex-split-block) + (define-key map "\C-c\C-s" #'latex-split-block) map) "Keymap for `latex-mode'. See also `tex-mode-map'.") @@ -1033,11 +1033,11 @@ says which mode to use." ;; received them from someone using AUCTeX). ;;;###autoload -(defalias 'TeX-mode 'tex-mode) +(defalias 'TeX-mode #'tex-mode) ;;;###autoload -(defalias 'plain-TeX-mode 'plain-tex-mode) +(defalias 'plain-TeX-mode #'plain-tex-mode) ;;;###autoload -(defalias 'LaTeX-mode 'latex-mode) +(defalias 'LaTeX-mode #'latex-mode) ;;;###autoload (define-derived-mode plain-tex-mode tex-mode "TeX" @@ -1560,7 +1560,7 @@ the name of the environment and SKEL-ELEM is an element to use in a skeleton (see `skeleton-insert').") ;; Like tex-insert-braces, but for LaTeX. -(defalias 'tex-latex-block 'latex-insert-block) +(defalias 'tex-latex-block #'latex-insert-block) (define-skeleton latex-insert-block "Create a matching pair of lines \\begin{NAME} and \\end{NAME} at point. Puts point on a blank line between them." @@ -1866,7 +1866,7 @@ Mark is left at original location." (with-syntax-table tex-mode-syntax-table (forward-sexp)))))) -(defalias 'tex-close-latex-block 'latex-close-block) +(defalias 'tex-close-latex-block #'latex-close-block) (define-skeleton latex-close-block "Create an \\end{...} to match the last unclosed \\begin{...}." (save-excursion @@ -2008,7 +2008,7 @@ Mark is left at original location." ;; Specify an interactive shell, to make sure it prompts. "-i") (let ((proc (get-process "tex-shell"))) - (set-process-sentinel proc 'tex-shell-sentinel) + (set-process-sentinel proc #'tex-shell-sentinel) (set-process-query-on-exit-flag proc nil) (tex-shell) (while (zerop (buffer-size)) @@ -2063,7 +2063,7 @@ evaluates to a command string. Return the process in which TeX is running." (save-excursion - (let* ((cmd (eval command)) + (let* ((cmd (eval command t)) (proc (tex-shell-proc)) (buf (process-buffer proc)) (star (string-match "\\*" cmd)) @@ -2313,7 +2313,7 @@ FILE is typically the output DVI or PDF file." executable)))))) (defun tex-command-executable (cmd) - (let ((s (if (stringp cmd) cmd (eval (car cmd))))) + (let ((s (if (stringp cmd) cmd (eval (car cmd) t)))) (substring s 0 (string-match "[ \t]\\|\\'" s)))) (defun tex-command-active-p (cmd fspec) @@ -2400,7 +2400,7 @@ Only applies the FSPEC to the args part of FORMAT." (setq latest (nth 1 cmd) cmds (list cmd))))))) ;; Expand the command spec into the actual text. (dolist (cmd (prog1 cmds (setq cmds nil))) - (push (cons (eval (car cmd)) (cdr cmd)) cmds)) + (push (cons (eval (car cmd) t) (cdr cmd)) cmds)) ;; Select the favorite command from the history. (let ((hist tex-compile-history) re hist-cmd) @@ -2446,7 +2446,7 @@ Only applies the FSPEC to the args part of FORMAT." (completing-read (format "Command [%s]: " (tex-summarize-command default)) (mapcar (lambda (x) - (list (tex-format-cmd (eval (car x)) fspec))) + (list (tex-format-cmd (eval (car x) t) fspec))) tex-compile-commands) nil nil nil 'tex-compile-history default)))) (save-some-buffers (not compilation-ask-about-save) nil) @@ -2740,7 +2740,7 @@ because there is no standard value that would generally work." ;; Restart the TeX shell if necessary. (or (tex-shell-running) (tex-start-shell)) - (let ((tex-dvi-print-command (eval tex-dvi-view-command))) + (let ((tex-dvi-print-command (eval tex-dvi-view-command t))) (tex-print))) (defun tex-append (file-name suffix) diff --git a/lisp/textmodes/texinfmt.el b/lisp/textmodes/texinfmt.el index fe052e3241..a797df9193 100644 --- a/lisp/textmodes/texinfmt.el +++ b/lisp/textmodes/texinfmt.el @@ -1,4 +1,4 @@ -;;; texinfmt.el --- format Texinfo files into Info files +;;; texinfmt.el --- format Texinfo files into Info files -*- lexical-binding: t; -*- ;; Copyright (C) 1985-1986, 1988, 1990-1998, 2000-2021 Free Software ;; Foundation, Inc. @@ -186,6 +186,7 @@ containing the Texinfo file.") ;; These come from tex-mode.el. (defvar tex-start-of-header) (defvar tex-end-of-header) +(defvar texinfo-example-start) ;;;###autoload (defun texinfo-format-region (region-beginning region-end) @@ -211,7 +212,7 @@ converted to Info is stored in a temporary buffer." texinfo-last-node texinfo-node-names (texinfo-footnote-number 0) - last-input-buffer + ;; last-input-buffer (fill-column-for-info fill-column) (input-buffer (current-buffer)) (input-directory default-directory) @@ -405,7 +406,7 @@ if large. You can use `Info-split' to do this manually." texinfo-stack texinfo-node-names (texinfo-footnote-number 0) - last-input-buffer + ;; last-input-buffer outfile (fill-column-for-info fill-column) (input-buffer (current-buffer)) @@ -924,7 +925,7 @@ commands." (error "Unterminated @%s" (car (car texinfo-stack))))) ;; Remove excess whitespace - (let ((whitespace-silent t)) + (dlet ((whitespace-silent t)) (whitespace-cleanup))) (defvar texinfo-copying-text "" @@ -1032,18 +1033,18 @@ Leave point after argument." (defun texinfo-optional-braces-discard () "Discard braces following command, if any." (goto-char texinfo-command-end) - (let ((start (point))) - (cond ((looking-at "[ \t]*\n")) ; do nothing - ((looking-at "{") ; remove braces, if any - (forward-list 1) - (setq texinfo-command-end (point))) - (t - (error - "Invalid `texinfo-optional-braces-discard' format (need braces?)"))) - (delete-region texinfo-command-start texinfo-command-end))) + ;; (let ((start (point))) + (cond ((looking-at "[ \t]*\n")) ; do nothing + ((looking-at "{") ; remove braces, if any + (forward-list 1) + (setq texinfo-command-end (point))) + (t + (error + "Invalid `texinfo-optional-braces-discard' format (need braces?)"))) + (delete-region texinfo-command-start texinfo-command-end)) ;;) (defun texinfo-format-parse-line-args () - (let ((start (1- (point))) + (let (;; (start (1- (point))) next beg end args) (skip-chars-forward " ") @@ -1064,7 +1065,7 @@ Leave point after argument." (nreverse args))) (defun texinfo-format-parse-args () - (let ((start (1- (point))) + (let (;; (start (1- (point))) next beg end args) (search-forward "{") @@ -2007,26 +2008,26 @@ commands that are defined in texinfo.tex for printed output. ;; ;; Case 2: {Column 1 template} {Column 2} {Column 3 example} ((looking-at "{") - (let ((start-of-templates (point))) - (while (not (eolp)) - (skip-chars-forward " \t") - (let* ((start-of-template (1+ (point))) - (end-of-template - ;; forward-sexp works with braces in Texinfo mode - (progn (forward-sexp 1) (1- (point))))) - (push (- end-of-template start-of-template) - texinfo-multitable-width-list) - ;; Remove carriage return from within a template, if any. - ;; This helps those who want to use more than - ;; one line's worth of words in @multitable line. - (narrow-to-region start-of-template end-of-template) - (goto-char (point-min)) - (while (search-forward " + ;; (let ((start-of-templates (point))) + (while (not (eolp)) + (skip-chars-forward " \t") + (let* ((start-of-template (1+ (point))) + (end-of-template + ;; forward-sexp works with braces in Texinfo mode + (progn (forward-sexp 1) (1- (point))))) + (push (- end-of-template start-of-template) + texinfo-multitable-width-list) + ;; Remove carriage return from within a template, if any. + ;; This helps those who want to use more than + ;; one line's worth of words in @multitable line. + (narrow-to-region start-of-template end-of-template) + (goto-char (point-min)) + (while (search-forward " " nil t) - (delete-char -1)) - (goto-char (point-max)) - (widen) - (forward-char 1))))) + (delete-char -1)) + (goto-char (point-max)) + (widen) + (forward-char 1)))) ;; ) ;; ;; Case 3: Trouble (t @@ -2040,7 +2041,7 @@ commands that are defined in texinfo.tex for printed output. ;; additional between column spaces, if any texinfo-extra-inter-column-width ;; sum of spaces for each entry - (apply '+ texinfo-multitable-width-list)))) + (apply #'+ texinfo-multitable-width-list)))) (if (> desired-columns fill-column) (error "Multi-column table width, %d chars, is greater than page width, %d chars." @@ -2171,9 +2172,9 @@ This command is executed when texinfmt sees @item inside @multitable." (while (< column-number total-number-of-columns) (setq here (point)) (insert-rectangle - (eval (intern - (concat texinfo-multitable-rectangle-name - (int-to-string column-number))))) + (symbol-value (intern + (concat texinfo-multitable-rectangle-name + (int-to-string column-number))))) (goto-char here) (end-of-line) (setq column-number (1+ column-number)))) @@ -2396,8 +2397,8 @@ Use only the FILENAME arg; for Info, ignore the other arguments to @image." (put 'alias 'texinfo-format 'texinfo-alias) (defun texinfo-alias () - (let ((start (1- (point))) - args) + (let (;; (start (1- (point)) + ) ;; args (skip-chars-forward " ") (setq texinfo-command-end (line-end-position)) (if (not (looking-at "\\([^=]+\\)=\\(.*\\)")) @@ -3410,7 +3411,7 @@ Default is to leave paragraph indentation as is." (while args (insert " " (if (or (= ?& (aref (car args) 0)) - (eq (eval (car texinfo-defun-type)) 'deftp-type)) + (eq (car texinfo-defun-type) 'deftp-type)) (car args) (upcase (car args)))) (setq args (cdr args))))) @@ -3775,80 +3776,80 @@ Default is to leave paragraph indentation as is." (put 'deffn 'texinfo-format 'texinfo-format-defun) (put 'deffnx 'texinfo-format 'texinfo-format-defunx) (put 'deffn 'texinfo-end 'texinfo-end-defun) -(put 'deffn 'texinfo-defun-type '('deffn-type nil)) -(put 'deffnx 'texinfo-defun-type '('deffn-type nil)) +(put 'deffn 'texinfo-defun-type '(deffn-type nil)) +(put 'deffnx 'texinfo-defun-type '(deffn-type nil)) (put 'deffn 'texinfo-defun-index 'texinfo-findex) (put 'deffnx 'texinfo-defun-index 'texinfo-findex) (put 'defun 'texinfo-format 'texinfo-format-defun) (put 'defunx 'texinfo-format 'texinfo-format-defunx) (put 'defun 'texinfo-end 'texinfo-end-defun) -(put 'defun 'texinfo-defun-type '('defun-type "Function")) -(put 'defunx 'texinfo-defun-type '('defun-type "Function")) +(put 'defun 'texinfo-defun-type '(defun-type "Function")) +(put 'defunx 'texinfo-defun-type '(defun-type "Function")) (put 'defun 'texinfo-defun-index 'texinfo-findex) (put 'defunx 'texinfo-defun-index 'texinfo-findex) (put 'defmac 'texinfo-format 'texinfo-format-defun) (put 'defmacx 'texinfo-format 'texinfo-format-defunx) (put 'defmac 'texinfo-end 'texinfo-end-defun) -(put 'defmac 'texinfo-defun-type '('defun-type "Macro")) -(put 'defmacx 'texinfo-defun-type '('defun-type "Macro")) +(put 'defmac 'texinfo-defun-type '(defun-type "Macro")) +(put 'defmacx 'texinfo-defun-type '(defun-type "Macro")) (put 'defmac 'texinfo-defun-index 'texinfo-findex) (put 'defmacx 'texinfo-defun-index 'texinfo-findex) (put 'defspec 'texinfo-format 'texinfo-format-defun) (put 'defspecx 'texinfo-format 'texinfo-format-defunx) (put 'defspec 'texinfo-end 'texinfo-end-defun) -(put 'defspec 'texinfo-defun-type '('defun-type "Special form")) -(put 'defspecx 'texinfo-defun-type '('defun-type "Special form")) +(put 'defspec 'texinfo-defun-type '(defun-type "Special form")) +(put 'defspecx 'texinfo-defun-type '(defun-type "Special form")) (put 'defspec 'texinfo-defun-index 'texinfo-findex) (put 'defspecx 'texinfo-defun-index 'texinfo-findex) (put 'defvr 'texinfo-format 'texinfo-format-defun) (put 'defvrx 'texinfo-format 'texinfo-format-defunx) (put 'defvr 'texinfo-end 'texinfo-end-defun) -(put 'defvr 'texinfo-defun-type '('deffn-type nil)) -(put 'defvrx 'texinfo-defun-type '('deffn-type nil)) +(put 'defvr 'texinfo-defun-type '(deffn-type nil)) +(put 'defvrx 'texinfo-defun-type '(deffn-type nil)) (put 'defvr 'texinfo-defun-index 'texinfo-vindex) (put 'defvrx 'texinfo-defun-index 'texinfo-vindex) (put 'defvar 'texinfo-format 'texinfo-format-defun) (put 'defvarx 'texinfo-format 'texinfo-format-defunx) (put 'defvar 'texinfo-end 'texinfo-end-defun) -(put 'defvar 'texinfo-defun-type '('defun-type "Variable")) -(put 'defvarx 'texinfo-defun-type '('defun-type "Variable")) +(put 'defvar 'texinfo-defun-type '(defun-type "Variable")) +(put 'defvarx 'texinfo-defun-type '(defun-type "Variable")) (put 'defvar 'texinfo-defun-index 'texinfo-vindex) (put 'defvarx 'texinfo-defun-index 'texinfo-vindex) (put 'defconst 'texinfo-format 'texinfo-format-defun) (put 'defconstx 'texinfo-format 'texinfo-format-defunx) (put 'defconst 'texinfo-end 'texinfo-end-defun) -(put 'defconst 'texinfo-defun-type '('defun-type "Constant")) -(put 'defconstx 'texinfo-defun-type '('defun-type "Constant")) +(put 'defconst 'texinfo-defun-type '(defun-type "Constant")) +(put 'defconstx 'texinfo-defun-type '(defun-type "Constant")) (put 'defconst 'texinfo-defun-index 'texinfo-vindex) (put 'defconstx 'texinfo-defun-index 'texinfo-vindex) (put 'defcmd 'texinfo-format 'texinfo-format-defun) (put 'defcmdx 'texinfo-format 'texinfo-format-defunx) (put 'defcmd 'texinfo-end 'texinfo-end-defun) -(put 'defcmd 'texinfo-defun-type '('defun-type "Command")) -(put 'defcmdx 'texinfo-defun-type '('defun-type "Command")) +(put 'defcmd 'texinfo-defun-type '(defun-type "Command")) +(put 'defcmdx 'texinfo-defun-type '(defun-type "Command")) (put 'defcmd 'texinfo-defun-index 'texinfo-findex) (put 'defcmdx 'texinfo-defun-index 'texinfo-findex) (put 'defopt 'texinfo-format 'texinfo-format-defun) (put 'defoptx 'texinfo-format 'texinfo-format-defunx) (put 'defopt 'texinfo-end 'texinfo-end-defun) -(put 'defopt 'texinfo-defun-type '('defun-type "User Option")) -(put 'defoptx 'texinfo-defun-type '('defun-type "User Option")) +(put 'defopt 'texinfo-defun-type '(defun-type "User Option")) +(put 'defoptx 'texinfo-defun-type '(defun-type "User Option")) (put 'defopt 'texinfo-defun-index 'texinfo-vindex) (put 'defoptx 'texinfo-defun-index 'texinfo-vindex) (put 'deftp 'texinfo-format 'texinfo-format-defun) (put 'deftpx 'texinfo-format 'texinfo-format-defunx) (put 'deftp 'texinfo-end 'texinfo-end-defun) -(put 'deftp 'texinfo-defun-type '('deftp-type nil)) -(put 'deftpx 'texinfo-defun-type '('deftp-type nil)) +(put 'deftp 'texinfo-defun-type '(deftp-type nil)) +(put 'deftpx 'texinfo-defun-type '(deftp-type nil)) (put 'deftp 'texinfo-defun-index 'texinfo-tindex) (put 'deftpx 'texinfo-defun-index 'texinfo-tindex) @@ -3857,32 +3858,32 @@ Default is to leave paragraph indentation as is." (put 'defop 'texinfo-format 'texinfo-format-defun) (put 'defopx 'texinfo-format 'texinfo-format-defunx) (put 'defop 'texinfo-end 'texinfo-end-defun) -(put 'defop 'texinfo-defun-type '('defop-type nil)) -(put 'defopx 'texinfo-defun-type '('defop-type nil)) +(put 'defop 'texinfo-defun-type '(defop-type nil)) +(put 'defopx 'texinfo-defun-type '(defop-type nil)) (put 'defop 'texinfo-defun-index 'texinfo-findex) (put 'defopx 'texinfo-defun-index 'texinfo-findex) (put 'defmethod 'texinfo-format 'texinfo-format-defun) (put 'defmethodx 'texinfo-format 'texinfo-format-defunx) (put 'defmethod 'texinfo-end 'texinfo-end-defun) -(put 'defmethod 'texinfo-defun-type '('defmethod-type "Method")) -(put 'defmethodx 'texinfo-defun-type '('defmethod-type "Method")) +(put 'defmethod 'texinfo-defun-type '(defmethod-type "Method")) +(put 'defmethodx 'texinfo-defun-type '(defmethod-type "Method")) (put 'defmethod 'texinfo-defun-index 'texinfo-findex) (put 'defmethodx 'texinfo-defun-index 'texinfo-findex) (put 'defcv 'texinfo-format 'texinfo-format-defun) (put 'defcvx 'texinfo-format 'texinfo-format-defunx) (put 'defcv 'texinfo-end 'texinfo-end-defun) -(put 'defcv 'texinfo-defun-type '('defop-type nil)) -(put 'defcvx 'texinfo-defun-type '('defop-type nil)) +(put 'defcv 'texinfo-defun-type '(defop-type nil)) +(put 'defcvx 'texinfo-defun-type '(defop-type nil)) (put 'defcv 'texinfo-defun-index 'texinfo-vindex) (put 'defcvx 'texinfo-defun-index 'texinfo-vindex) (put 'defivar 'texinfo-format 'texinfo-format-defun) (put 'defivarx 'texinfo-format 'texinfo-format-defunx) (put 'defivar 'texinfo-end 'texinfo-end-defun) -(put 'defivar 'texinfo-defun-type '('defmethod-type "Instance variable")) -(put 'defivarx 'texinfo-defun-type '('defmethod-type "Instance variable")) +(put 'defivar 'texinfo-defun-type '(defmethod-type "Instance variable")) +(put 'defivarx 'texinfo-defun-type '(defmethod-type "Instance variable")) (put 'defivar 'texinfo-defun-index 'texinfo-vindex) (put 'defivarx 'texinfo-defun-index 'texinfo-vindex) @@ -3891,32 +3892,32 @@ Default is to leave paragraph indentation as is." (put 'deftypefn 'texinfo-format 'texinfo-format-defun) (put 'deftypefnx 'texinfo-format 'texinfo-format-defunx) (put 'deftypefn 'texinfo-end 'texinfo-end-defun) -(put 'deftypefn 'texinfo-defun-type '('deftypefn-type nil)) -(put 'deftypefnx 'texinfo-defun-type '('deftypefn-type nil)) +(put 'deftypefn 'texinfo-defun-type '(deftypefn-type nil)) +(put 'deftypefnx 'texinfo-defun-type '(deftypefn-type nil)) (put 'deftypefn 'texinfo-defun-index 'texinfo-findex) (put 'deftypefnx 'texinfo-defun-index 'texinfo-findex) (put 'deftypefun 'texinfo-format 'texinfo-format-defun) (put 'deftypefunx 'texinfo-format 'texinfo-format-defunx) (put 'deftypefun 'texinfo-end 'texinfo-end-defun) -(put 'deftypefun 'texinfo-defun-type '('deftypefun-type "Function")) -(put 'deftypefunx 'texinfo-defun-type '('deftypefun-type "Function")) +(put 'deftypefun 'texinfo-defun-type '(deftypefun-type "Function")) +(put 'deftypefunx 'texinfo-defun-type '(deftypefun-type "Function")) (put 'deftypefun 'texinfo-defun-index 'texinfo-findex) (put 'deftypefunx 'texinfo-defun-index 'texinfo-findex) (put 'deftypevr 'texinfo-format 'texinfo-format-defun) (put 'deftypevrx 'texinfo-format 'texinfo-format-defunx) (put 'deftypevr 'texinfo-end 'texinfo-end-defun) -(put 'deftypevr 'texinfo-defun-type '('deftypefn-type nil)) -(put 'deftypevrx 'texinfo-defun-type '('deftypefn-type nil)) +(put 'deftypevr 'texinfo-defun-type '(deftypefn-type nil)) +(put 'deftypevrx 'texinfo-defun-type '(deftypefn-type nil)) (put 'deftypevr 'texinfo-defun-index 'texinfo-vindex) (put 'deftypevrx 'texinfo-defun-index 'texinfo-vindex) (put 'deftypevar 'texinfo-format 'texinfo-format-defun) (put 'deftypevarx 'texinfo-format 'texinfo-format-defunx) (put 'deftypevar 'texinfo-end 'texinfo-end-defun) -(put 'deftypevar 'texinfo-defun-type '('deftypevar-type "Variable")) -(put 'deftypevarx 'texinfo-defun-type '('deftypevar-type "Variable")) +(put 'deftypevar 'texinfo-defun-type '(deftypevar-type "Variable")) +(put 'deftypevarx 'texinfo-defun-type '(deftypevar-type "Variable")) (put 'deftypevar 'texinfo-defun-index 'texinfo-vindex) (put 'deftypevarx 'texinfo-defun-index 'texinfo-vindex) @@ -3943,7 +3944,8 @@ Default is to leave paragraph indentation as is." "Clear the value of the flag." (let* ((arg (texinfo-parse-arg-discard)) (flag (car (read-from-string arg))) - (value (substring arg (cdr (read-from-string arg))))) + ;; (value (substring arg (cdr (read-from-string arg)))) + ) (put flag 'texinfo-whether-setp 'flag-cleared) (put flag 'texinfo-set-value ""))) @@ -4043,7 +4045,7 @@ the @ifeq command." (goto-char texinfo-command-end) (let* ((case-fold-search t) (stop (save-excursion (forward-sexp 1) (point))) - start end + start ;; end ;; @ifeq{arg1, arg2, @command{optional-args}} (arg1 (progn diff --git a/lisp/textmodes/texinfo.el b/lisp/textmodes/texinfo.el index 278cd0cd84..750a33db0a 100644 --- a/lisp/textmodes/texinfo.el +++ b/lisp/textmodes/texinfo.el @@ -1,4 +1,4 @@ -;;; texinfo.el --- major mode for editing Texinfo files +;;; texinfo.el --- major mode for editing Texinfo files -*- lexical-binding: t; -*- ;; Copyright (C) 1985, 1988-1993, 1996-1997, 2000-2021 Free Software ;; Foundation, Inc. @@ -373,7 +373,7 @@ Subexpression 1 is what goes into the corresponding `@end' statement.") ("@\\(end\\|itemx?\\) +\\(.+\\)" 2 font-lock-keyword-face keep) ;; (,texinfo-environment-regexp ;; 1 (texinfo-clone-environment (match-beginning 1) (match-end 1)) keep) - (,(concat "^@" (regexp-opt (mapcar 'car texinfo-section-list) t) + (,(concat "^@" (regexp-opt (mapcar #'car texinfo-section-list) t) ".*\n") 0 'texinfo-heading t)) "Additional expressions to highlight in Texinfo mode.") @@ -400,19 +400,21 @@ Subexpression 1 is what goes into the corresponding `@end' statement.") ;;; Keys common both to Texinfo mode and to TeX shell. +(declare-function tex-show-print-queue "tex-mode" ()) + (defun texinfo-define-common-keys (keymap) "Define the keys both in Texinfo mode and in the texinfo-tex-shell." - (define-key keymap "\C-c\C-t\C-k" 'tex-kill-job) - (define-key keymap "\C-c\C-t\C-x" 'texinfo-quit-job) - (define-key keymap "\C-c\C-t\C-l" 'tex-recenter-output-buffer) - (define-key keymap "\C-c\C-t\C-d" 'texinfo-delete-from-print-queue) - (define-key keymap "\C-c\C-t\C-q" 'tex-show-print-queue) - (define-key keymap "\C-c\C-t\C-p" 'texinfo-tex-print) - (define-key keymap "\C-c\C-t\C-v" 'texinfo-tex-view) - (define-key keymap "\C-c\C-t\C-i" 'texinfo-texindex) - - (define-key keymap "\C-c\C-t\C-r" 'texinfo-tex-region) - (define-key keymap "\C-c\C-t\C-b" 'texinfo-tex-buffer)) + (define-key keymap "\C-c\C-t\C-k" #'tex-kill-job) + (define-key keymap "\C-c\C-t\C-x" #'texinfo-quit-job) + (define-key keymap "\C-c\C-t\C-l" #'tex-recenter-output-buffer) + (define-key keymap "\C-c\C-t\C-d" #'texinfo-delete-from-print-queue) + (define-key keymap "\C-c\C-t\C-q" #'tex-show-print-queue) + (define-key keymap "\C-c\C-t\C-p" #'texinfo-tex-print) + (define-key keymap "\C-c\C-t\C-v" #'texinfo-tex-view) + (define-key keymap "\C-c\C-t\C-i" #'texinfo-texindex) + + (define-key keymap "\C-c\C-t\C-r" #'texinfo-tex-region) + (define-key keymap "\C-c\C-t\C-b" #'texinfo-tex-buffer)) ;; Mode documentation displays commands in reverse order ;; from how they are listed in the texinfo-mode-map. @@ -423,68 +425,68 @@ Subexpression 1 is what goes into the corresponding `@end' statement.") ;; bindings for `texnfo-tex.el' (texinfo-define-common-keys map) - (define-key map "\"" 'texinfo-insert-quote) + (define-key map "\"" #'texinfo-insert-quote) ;; bindings for `makeinfo.el' - (define-key map "\C-c\C-m\C-k" 'kill-compilation) + (define-key map "\C-c\C-m\C-k" #'kill-compilation) (define-key map "\C-c\C-m\C-l" - 'makeinfo-recenter-compilation-buffer) - (define-key map "\C-c\C-m\C-r" 'makeinfo-region) - (define-key map "\C-c\C-m\C-b" 'makeinfo-buffer) + #'makeinfo-recenter-compilation-buffer) + (define-key map "\C-c\C-m\C-r" #'makeinfo-region) + (define-key map "\C-c\C-m\C-b" #'makeinfo-buffer) ;; bindings for `texinfmt.el' - (define-key map "\C-c\C-e\C-r" 'texinfo-format-region) - (define-key map "\C-c\C-e\C-b" 'texinfo-format-buffer) + (define-key map "\C-c\C-e\C-r" #'texinfo-format-region) + (define-key map "\C-c\C-e\C-b" #'texinfo-format-buffer) ;; AUCTeX-like bindings - (define-key map "\e\r" 'texinfo-insert-@item) + (define-key map "\e\r" #'texinfo-insert-@item) ;; bindings for updating nodes and menus - (define-key map "\C-c\C-um" 'texinfo-master-menu) + (define-key map "\C-c\C-um" #'texinfo-master-menu) - (define-key map "\C-c\C-u\C-m" 'texinfo-make-menu) - (define-key map "\C-c\C-u\C-n" 'texinfo-update-node) - (define-key map "\C-c\C-u\C-e" 'texinfo-every-node-update) - (define-key map "\C-c\C-u\C-a" 'texinfo-all-menus-update) + (define-key map "\C-c\C-u\C-m" #'texinfo-make-menu) + (define-key map "\C-c\C-u\C-n" #'texinfo-update-node) + (define-key map "\C-c\C-u\C-e" #'texinfo-every-node-update) + (define-key map "\C-c\C-u\C-a" #'texinfo-all-menus-update) - (define-key map "\C-c\C-s" 'texinfo-show-structure) + (define-key map "\C-c\C-s" #'texinfo-show-structure) - (define-key map "\C-c}" 'up-list) + (define-key map "\C-c}" #'up-list) ;; FIXME: This is often used for "close block" aka texinfo-insert-@end. - (define-key map "\C-c]" 'up-list) - (define-key map "\C-c/" 'texinfo-insert-@end) - (define-key map "\C-c{" 'texinfo-insert-braces) + (define-key map "\C-c]" #'up-list) + (define-key map "\C-c/" #'texinfo-insert-@end) + (define-key map "\C-c{" #'texinfo-insert-braces) ;; bindings for inserting strings - (define-key map "\C-c\C-o" 'texinfo-insert-block) - (define-key map "\C-c\C-c\C-d" 'texinfo-start-menu-description) - (define-key map "\C-c\C-c\C-s" 'texinfo-insert-@strong) - (define-key map "\C-c\C-c\C-e" 'texinfo-insert-@emph) - - (define-key map "\C-c\C-cv" 'texinfo-insert-@var) - (define-key map "\C-c\C-cu" 'texinfo-insert-@uref) - (define-key map "\C-c\C-ct" 'texinfo-insert-@table) - (define-key map "\C-c\C-cs" 'texinfo-insert-@samp) - (define-key map "\C-c\C-cr" 'texinfo-insert-dwim-@ref) - (define-key map "\C-c\C-cq" 'texinfo-insert-@quotation) - (define-key map "\C-c\C-co" 'texinfo-insert-@noindent) - (define-key map "\C-c\C-cn" 'texinfo-insert-@node) - (define-key map "\C-c\C-cm" 'texinfo-insert-@email) - (define-key map "\C-c\C-ck" 'texinfo-insert-@kbd) - (define-key map "\C-c\C-ci" 'texinfo-insert-@item) - (define-key map "\C-c\C-cf" 'texinfo-insert-@file) - (define-key map "\C-c\C-cx" 'texinfo-insert-@example) - (define-key map "\C-c\C-ce" 'texinfo-insert-@end) - (define-key map "\C-c\C-cd" 'texinfo-insert-@dfn) - (define-key map "\C-c\C-cc" 'texinfo-insert-@code) + (define-key map "\C-c\C-o" #'texinfo-insert-block) + (define-key map "\C-c\C-c\C-d" #'texinfo-start-menu-description) + (define-key map "\C-c\C-c\C-s" #'texinfo-insert-@strong) + (define-key map "\C-c\C-c\C-e" #'texinfo-insert-@emph) + + (define-key map "\C-c\C-cv" #'texinfo-insert-@var) + (define-key map "\C-c\C-cu" #'texinfo-insert-@uref) + (define-key map "\C-c\C-ct" #'texinfo-insert-@table) + (define-key map "\C-c\C-cs" #'texinfo-insert-@samp) + (define-key map "\C-c\C-cr" #'texinfo-insert-dwim-@ref) + (define-key map "\C-c\C-cq" #'texinfo-insert-@quotation) + (define-key map "\C-c\C-co" #'texinfo-insert-@noindent) + (define-key map "\C-c\C-cn" #'texinfo-insert-@node) + (define-key map "\C-c\C-cm" #'texinfo-insert-@email) + (define-key map "\C-c\C-ck" #'texinfo-insert-@kbd) + (define-key map "\C-c\C-ci" #'texinfo-insert-@item) + (define-key map "\C-c\C-cf" #'texinfo-insert-@file) + (define-key map "\C-c\C-cx" #'texinfo-insert-@example) + (define-key map "\C-c\C-ce" #'texinfo-insert-@end) + (define-key map "\C-c\C-cd" #'texinfo-insert-@dfn) + (define-key map "\C-c\C-cc" #'texinfo-insert-@code) ;; bindings for environment movement - (define-key map "\C-c." 'texinfo-to-environment-bounds) - (define-key map "\C-c\C-c\C-f" 'texinfo-next-environment-end) - (define-key map "\C-c\C-c\C-b" 'texinfo-previous-environment-end) - (define-key map "\C-c\C-c\C-n" 'texinfo-next-environment-start) - (define-key map "\C-c\C-c\C-p" 'texinfo-previous-environment-start) + (define-key map "\C-c." #'texinfo-to-environment-bounds) + (define-key map "\C-c\C-c\C-f" #'texinfo-next-environment-end) + (define-key map "\C-c\C-c\C-b" #'texinfo-previous-environment-end) + (define-key map "\C-c\C-c\C-n" #'texinfo-next-environment-start) + (define-key map "\C-c\C-c\C-p" #'texinfo-previous-environment-start) map)) (easy-menu-define texinfo-mode-menu @@ -624,7 +626,7 @@ value of `texinfo-mode-hook'." (mapcar (lambda (x) (cons (concat "@" (car x)) (cadr x))) texinfo-section-list)) (setq-local outline-regexp - (concat (regexp-opt (mapcar 'car outline-heading-alist) t) + (concat (regexp-opt (mapcar #'car outline-heading-alist) t) "\\>")) (setq-local tex-start-of-header "%\\*\\*start") @@ -893,7 +895,7 @@ A numeric argument says how many words the braces should surround. The default is not to surround any existing words with the braces." nil "@uref{" _ "}") -(defalias 'texinfo-insert-@url 'texinfo-insert-@uref) +(defalias 'texinfo-insert-@url #'texinfo-insert-@uref) ;;; Texinfo file structure diff --git a/lisp/textmodes/texnfo-upd.el b/lisp/textmodes/texnfo-upd.el index 04778ee94d..27807a95e6 100644 --- a/lisp/textmodes/texnfo-upd.el +++ b/lisp/textmodes/texnfo-upd.el @@ -1,4 +1,4 @@ -;;; texnfo-upd.el --- utilities for updating nodes and menus in Texinfo files +;;; texnfo-upd.el --- utilities for updating nodes and menus in Texinfo files -*- lexical-binding: t; -*- ;; Copyright (C) 1989-1992, 2001-2021 Free Software Foundation, Inc. @@ -420,7 +420,7 @@ of the node if one is found; else do not move point." "\\|" ; or "\\(^@ifnottex[ ]*\n\\)" ; ifnottex line, if any "\\)?" ; end of expression - (eval (cdr (assoc level texinfo-update-menu-lower-regexps)))) + (eval (cdr (assoc level texinfo-update-menu-lower-regexps)) t)) ;; the next higher level node marks the end of this ;; section, and no lower level node will be found beyond ;; this position even if region-end is farther off @@ -454,7 +454,7 @@ if the match is found there, the value is t and point does not move." "\\|" ; or "\\(^@ifnottex[ ]*\n\\)" ; ifnottex line, if any "\\)?" ; end of expression - (eval (cdr (assoc level texinfo-update-menu-higher-regexps)))) + (eval (cdr (assoc level texinfo-update-menu-higher-regexps)) t)) region-end t) (beginning-of-line) t))))) @@ -505,7 +505,7 @@ The function finds entries of the same type. Thus `subsections' and "\\(^@ifnottex[ ]*\n\\)" ; ifnottex line, if any "\\)?" ; end of expression (eval - (cdr (assoc level texinfo-update-menu-same-level-regexps)))) + (cdr (assoc level texinfo-update-menu-same-level-regexps)) t)) search-end t) (goto-char (match-beginning 1))))) @@ -742,7 +742,7 @@ You will need to edit the inserted text since a useful description complements the node name rather than repeats it as a title does." (interactive) - (let (beginning end node-name title) + (let (beginning node-name title) ;; end (save-excursion (beginning-of-line) (if (search-forward "* " (line-end-position) t) @@ -1219,7 +1219,7 @@ Only argument is a string of the general type of section." "\\(^@ifnottex[ ]*\n\\)" ; ifnottex line, if any "\\)?" ; end of expression (eval - (cdr (assoc level texinfo-update-menu-higher-regexps)))) + (cdr (assoc level texinfo-update-menu-higher-regexps)) t)) nil 'goto-beginning) (point)))))) @@ -1243,7 +1243,7 @@ string of the general type of section." "\\)?" ; end of expression (eval ;; Never finds end of level above chapter so goes to end. - (cdr (assoc level texinfo-update-menu-higher-regexps)))) + (cdr (assoc level texinfo-update-menu-higher-regexps)) t)) nil 'goto-end) (match-beginning 1) @@ -1430,7 +1430,7 @@ will be at some level higher in the Texinfo file. The fourth argument "\\(^@ifnottex[ ]*\n\\)" "\\)?") (eval - (cdr (assoc level texinfo-update-menu-same-level-regexps)))) + (cdr (assoc level texinfo-update-menu-same-level-regexps)) t)) end t) 'normal @@ -1451,7 +1451,7 @@ will be at some level higher in the Texinfo file. The fourth argument "\\(^@ifnottex[ ]*\n\\)" "\\)?") (eval - (cdr (assoc level texinfo-update-menu-same-level-regexps))) + (cdr (assoc level texinfo-update-menu-same-level-regexps)) t) "\\|" ;; Match node line. "\\(^@node\\).*\n" @@ -1465,7 +1465,7 @@ will be at some level higher in the Texinfo file. The fourth argument "\\(^@ifnottex[ ]*\n\\)" "\\)?") (eval - (cdr (assoc level texinfo-update-menu-higher-regexps))) + (cdr (assoc level texinfo-update-menu-higher-regexps)) t) "\\|" ;; Handle `Top' node specially. "^@node [ \t]*top[ \t]*\\(,\\|$\\)" @@ -1489,7 +1489,7 @@ will be at some level higher in the Texinfo file. The fourth argument "\\|" "\\(^@ifnottex[ ]*\n\\)" "\\)?") - (eval (cdr (assoc level texinfo-update-menu-higher-regexps))) + (eval (cdr (assoc level texinfo-update-menu-higher-regexps)) t) "\\|" ;; Handle `Top' node specially. "^@node [ \t]*top[ \t]*\\(,\\|$\\)" @@ -1662,7 +1662,7 @@ or `Up' pointer." 'no-pointer)) ((eq direction 'up) (if (re-search-backward - (eval (cdr (assoc level texinfo-update-menu-higher-regexps))) + (eval (cdr (assoc level texinfo-update-menu-higher-regexps)) t) (point-min) t) 'normal @@ -1686,7 +1686,7 @@ node names in pre-existing `@node' lines that lack names." ;; Use marker; after inserting node lines, leave point at end of ;; region and mark at beginning. - (let (beginning-marker end-marker title last-section-position) + (let (end-marker title last-section-position) ;; beginning-marker ;; Save current position on mark ring and set mark to end. (push-mark end t) @@ -2043,8 +2043,8 @@ chapter." (let* ((included-file-list (texinfo-multi-file-included-list outer-file)) (files included-file-list) - next-node-name - previous-node-name + ;; next-node-name + ;; previous-node-name ;; Update the pointers and collect the names of the nodes and titles (main-menu-list (texinfo-multi-file-update files update-everything))) diff --git a/lisp/textmodes/text-mode.el b/lisp/textmodes/text-mode.el index 7836bd46bc..ffeb9e64dd 100644 --- a/lisp/textmodes/text-mode.el +++ b/lisp/textmodes/text-mode.el @@ -69,7 +69,7 @@ (defvar text-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\e\t" 'ispell-complete-word) + (define-key map "\e\t" #'ispell-complete-word) map) "Keymap for `text-mode'. Many other modes, such as `mail-mode', `outline-mode' and `indented-text-mode', @@ -141,7 +141,7 @@ Turning on Paragraph-Indent minor mode runs the normal hook (remove-function (local 'indent-line-function) #'indent-to-left-margin))) -(defalias 'indented-text-mode 'text-mode) +(defalias 'indented-text-mode #'text-mode) ;; This can be made a no-op once all modes that use text-mode-hook ;; are "derived" from text-mode. (As of 2015/04, and probably well before, diff --git a/lisp/textmodes/tildify.el b/lisp/textmodes/tildify.el index 1d90562ae2..069c8e3f44 100644 --- a/lisp/textmodes/tildify.el +++ b/lisp/textmodes/tildify.el @@ -289,7 +289,7 @@ variable. For example, for an XML file one might use: (setq-local tildify-foreach-region-function (apply-partially \\='tildify-foreach-ignore-environments \\='((\"\") (\"<\" . \">\"))))" - (let ((beg-re (concat "\\(?:" (mapconcat 'car pairs "\\)\\|\\(?:") "\\)")) + (let ((beg-re (concat "\\(?:" (mapconcat #'car pairs "\\)\\|\\(?:") "\\)")) p end-re) (save-excursion (save-restriction @@ -499,8 +499,8 @@ variable will be set to the representation." "mode won't have any effect, disabling."))) (setq tildify-mode nil)))) (if tildify-mode - (add-hook 'post-self-insert-hook 'tildify-space nil t) - (remove-hook 'post-self-insert-hook 'tildify-space t))) + (add-hook 'post-self-insert-hook #'tildify-space nil t) + (remove-hook 'post-self-insert-hook #'tildify-space t))) ;;; *** Announce *** diff --git a/lisp/textmodes/two-column.el b/lisp/textmodes/two-column.el index 9c0ed8fbd5..6c3bacc647 100644 --- a/lisp/textmodes/two-column.el +++ b/lisp/textmodes/two-column.el @@ -1,4 +1,4 @@ -;;; two-column.el --- minor mode for editing of two-column text +;;; two-column.el --- minor mode for editing of two-column text -*- lexical-binding: t; -*- ;; Copyright (C) 1992-1995, 2001-2021 Free Software Foundation, Inc. @@ -165,10 +165,10 @@ minus this value." (defvar 2C-mode-map (let ((map (make-sparse-keymap))) - (define-key map "2" '2C-two-columns) - (define-key map [f2] '2C-two-columns) - (define-key map "b" '2C-associate-buffer) - (define-key map "s" '2C-split) + (define-key map "2" #'2C-two-columns) + (define-key map [f2] #'2C-two-columns) + (define-key map "b" #'2C-associate-buffer) + (define-key map "s" #'2C-split) map) "Keymap for commands for setting up two-column mode.") @@ -178,19 +178,19 @@ minus this value." ;; This one is for historical reasons and simple keyboards, it is not ;; at all mnemonic. All usual sequences containing 2 were used, and ;; f2 could not be set up in a standard way under Emacs 18. -;;;###autoload (global-set-key "\C-x6" '2C-command) +;;;###autoload (global-set-key "\C-x6" #'2C-command) -;;;###autoload (global-set-key [f2] '2C-command) +;;;###autoload (global-set-key [f2] #'2C-command) (defvar 2C-minor-mode-map (let ((map (make-sparse-keymap))) - (define-key map "1" '2C-merge) - (define-key map "d" '2C-dissociate) - (define-key map "o" '2C-associated-buffer) - (define-key map "\^m" '2C-newline) - (define-key map "|" '2C-toggle-autoscroll) - (define-key map "{" '2C-shrink-window-horizontally) - (define-key map "}" '2C-enlarge-window-horizontally) + (define-key map "1" #'2C-merge) + (define-key map "d" #'2C-dissociate) + (define-key map "o" #'2C-associated-buffer) + (define-key map "\^m" #'2C-newline) + (define-key map "|" #'2C-toggle-autoscroll) + (define-key map "{" #'2C-shrink-window-horizontally) + (define-key map "}" #'2C-enlarge-window-horizontally) map) "Keymap for commands for use in two-column mode.") @@ -275,7 +275,7 @@ some prefix. The appearance of the screen can be customized by the variables `2C-window-width', `2C-beyond-fill-column', `2C-mode-line-format' and `truncate-partial-width-windows'." - (add-hook 'post-command-hook '2C-autoscroll nil t) + (add-hook 'post-command-hook #'2C-autoscroll nil t) (setq fill-column (- 2C-window-width 2C-beyond-fill-column) mode-line-format 2C-mode-line-format commit c28ba117782cd825b2a4dd6ffcc0206ecf36898e Author: Dmitry Gutov Date: Thu Mar 18 02:35:10 2021 +0200 Leave signaling the exact error to cl-generic's internals * lisp/progmodes/project.el (project-root): Extract default definition to a new method, predicated on a context (https://lists.gnu.org/archive/html/emacs-devel/2021-03/msg00771.html). diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 65897b008c..bd552c917a 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -216,10 +216,12 @@ of the project instance object." It usually contains the main build file, dependencies configuration file, etc. Though neither is mandatory. -The directory name must be absolute." - (if project--within-roots-fallback - (signal 'cl-no-applicable-method (list 'project-root project)) - (car (project-roots project)))) +The directory name must be absolute.") + +(cl-defmethod project-root (project + &context (project--within-roots-fallback + (eql nil))) + (car (project-roots project))) (cl-defgeneric project-roots (project) "Return the list containing the current project root. commit 82c3bd1e4a58f6fefcb7d69b6e04013bd86f54be Author: Stefan Monnier Date: Wed Mar 17 19:04:28 2021 -0400 * lisp/emacs-lisp/benchmark.el (benchmark-call): New function (benchmark-run, benchmark-run-compiled, benchmark): Use it. (benchmark--adaptive): New internal function. diff --git a/doc/lispref/debugging.texi b/doc/lispref/debugging.texi index 8e4b0ebfe9..de98d2206e 100644 --- a/doc/lispref/debugging.texi +++ b/doc/lispref/debugging.texi @@ -1041,7 +1041,8 @@ functions written in Lisp, it cannot profile Emacs primitives. @cindex @file{benchmark.el} @cindex benchmarking You can measure the time it takes to evaluate individual Emacs Lisp -forms using the @file{benchmark} library. See the macros +forms using the @file{benchmark} library. See the function +@code{benchmark-call} as well as the macros @code{benchmark-run}, @code{benchmark-run-compiled} and @code{benchmark-progn} in @file{benchmark.el}. You can also use the @code{benchmark} command for timing forms interactively. diff --git a/etc/NEWS b/etc/NEWS index 6fe98dbc12..27a4766a40 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -389,6 +389,11 @@ major mode. * Changes in Specialized Modes and Packages in Emacs 28.1 +** Benchmark +*** New function 'benchmark-call' to measure the execution time of a function. +Additionally, the number of repetitions can be expressed as a minimal duration +in seconds. + ** Macroexp --- *** New function 'macroexp-file-name' to know the name of the current file. diff --git a/lisp/emacs-lisp/benchmark.el b/lisp/emacs-lisp/benchmark.el index 2a3efbe5a1..439d3bd363 100644 --- a/lisp/emacs-lisp/benchmark.el +++ b/lisp/emacs-lisp/benchmark.el @@ -31,6 +31,8 @@ ;;; Code: +(eval-when-compile (require 'subr-x)) ;For `named-let'. + (defmacro benchmark-elapse (&rest forms) "Return the time in seconds elapsed for execution of FORMS." (declare (indent 0) (debug t)) @@ -40,6 +42,61 @@ ,@forms (float-time (time-since ,t1))))) +;;;###autoload +(defun benchmark-call (func &optional repetitions) + "Measure the run time of calling FUNC a number REPETITIONS of times. +The result is a list (TIME GC GCTIME) +where TIME is the total time it took, in seconds. +GCTIME is the amount of time that was spent in the GC +and GC is the number of times the GC was called. + +REPETITIONS can also be a floating point number, in which case it +specifies a minimum number of seconds that the benchmark execution +should take. In that case the return value is prepended with the +number of repetitions actually used." + (if (floatp repetitions) + (benchmark--adaptive func repetitions) + (unless repetitions (setq repetitions 1)) + (let ((gc gc-elapsed) + (gcs gcs-done) + (empty-func (lambda () 'empty-func))) + (list + (if (> repetitions 1) + (- (benchmark-elapse (dotimes (_ repetitions) (funcall func))) + (benchmark-elapse (dotimes (_ repetitions) (funcall empty-func)))) + (- (benchmark-elapse (funcall func)) + (benchmark-elapse (funcall empty-func)))) + (- gcs-done gcs) + (- gc-elapsed gc))))) + +(defun benchmark--adaptive (func time) + "Measure the run time of FUNC, calling it enough times to last TIME seconds. +Result is (REPETITIONS . DATA) where DATA is as returned by `branchmark-call'." + (named-let loop ((repetitions 1) + (data (let ((x (list 0))) (setcdr x x) x))) + ;; (message "Running %d iteration" repetitions) + (let ((newdata (benchmark-call func repetitions))) + (if (<= (car newdata) 0) + ;; This can happen if we're unlucky, e.g. the process got preempted + ;; (or the GC ran) just during the empty-func loop. + ;; Just try again, hopefully this won't repeat itself. + (progn + ;; (message "Ignoring the %d iterations" repetitions) + (loop (* 2 repetitions) data)) + (let* ((sum (cl-mapcar #'+ data (cons repetitions newdata))) + (totaltime (nth 1 sum))) + (if (>= totaltime time) + sum + (let* ((iter-time (/ totaltime (car sum))) + (missing-time (- time totaltime)) + (missing-iter (/ missing-time iter-time))) + ;; `iter-time' is approximate because of effects like the GC, + ;; so multiply at most by 10, in case we are wildly off the mark. + (loop (max repetitions + (min (ceiling missing-iter) + (* 10 repetitions))) + sum)))))))) + ;;;###autoload (defmacro benchmark-run (&optional repetitions &rest forms) "Time execution of FORMS. @@ -53,20 +110,7 @@ See also `benchmark-run-compiled'." (unless (or (natnump repetitions) (and repetitions (symbolp repetitions))) (setq forms (cons repetitions forms) repetitions 1)) - (let ((i (make-symbol "i")) - (gcs (make-symbol "gcs")) - (gc (make-symbol "gc"))) - `(let ((,gc gc-elapsed) - (,gcs gcs-done)) - (list ,(if (or (symbolp repetitions) (> repetitions 1)) - ;; Take account of the loop overhead. - `(- (benchmark-elapse (dotimes (,i ,repetitions) - ,@forms)) - (benchmark-elapse (dotimes (,i ,repetitions) - nil))) - `(benchmark-elapse ,@forms)) - (- gcs-done ,gcs) - (- gc-elapsed ,gc))))) + `(benchmark-call (lambda () ,@forms) ,repetitions)) ;;;###autoload (defmacro benchmark-run-compiled (&optional repetitions &rest forms) @@ -78,21 +122,7 @@ result. The overhead of the `lambda's is accounted for." (unless (or (natnump repetitions) (and repetitions (symbolp repetitions))) (setq forms (cons repetitions forms) repetitions 1)) - (let ((i (make-symbol "i")) - (gcs (make-symbol "gcs")) - (gc (make-symbol "gc")) - (code (byte-compile `(lambda () ,@forms))) - (lambda-code (byte-compile '(lambda ())))) - `(let ((,gc gc-elapsed) - (,gcs gcs-done)) - (list ,(if (or (symbolp repetitions) (> repetitions 1)) - ;; Take account of the loop overhead. - `(- (benchmark-elapse (dotimes (,i ,repetitions) - (funcall ,code))) - (benchmark-elapse (dotimes (,i ,repetitions) - (funcall ,lambda-code)))) - `(benchmark-elapse (funcall ,code))) - (- gcs-done ,gcs) (- gc-elapsed ,gc))))) + `(benchmark-call (byte-compile '(lambda () ,@forms)) ,repetitions)) ;;;###autoload (defun benchmark (repetitions form) @@ -100,9 +130,15 @@ result. The overhead of the `lambda's is accounted for." Interactively, REPETITIONS is taken from the prefix arg, and the command prompts for the form to benchmark. For non-interactive use see also `benchmark-run' and -`benchmark-run-compiled'." +`benchmark-run-compiled'. +FORM can also be a function in which case we measure the time it takes +to call it without any argument." (interactive "p\nxForm: ") - (let ((result (eval `(benchmark-run ,repetitions ,form) t))) + (let ((result (benchmark-call (eval (pcase form + ((or `#',_ `(lambda . ,_)) form) + (_ `(lambda () ,form))) + t) + repetitions))) (if (zerop (nth 1 result)) (message "Elapsed time: %fs" (car result)) (message "Elapsed time: %fs (%fs in %d GCs)" (car result) commit 3cd3f230c924e5a095f37ea9c6ea6f9f6c5cf473 Author: Juri Linkov Date: Wed Mar 17 19:42:48 2021 +0200 * lisp/tab-line.el: Face cleanup. diff --git a/lisp/tab-line.el b/lisp/tab-line.el index f2c49019b1..0d97da8ca7 100644 --- a/lisp/tab-line.el +++ b/lisp/tab-line.el @@ -56,29 +56,25 @@ whether the tab is a buffer, and whether the tab is selected." :version "27.1") (defface tab-line-tab - '((default - :inherit tab-line) + '((default :inherit tab-line) (((class color) (min-colors 88)) :box (:line-width 1 :style released-button)) - (t - :inverse-video nil)) + (t :inverse-video nil)) "Tab line face for selected tab." :version "27.1" :group 'tab-line-faces) (defface tab-line-tab-inactive - '((default - :inherit tab-line-tab) + '((default :inherit tab-line-tab) (((class color) (min-colors 88)) :background "grey75") - (t - :inverse-video t)) + (t :inverse-video t)) "Tab line face for non-selected tab." :version "27.1" :group 'tab-line-faces) (defface tab-line-tab-inactive-alternate - `((t (:inherit tab-line-tab-inactive :background "grey65"))) + '((t :inherit tab-line-tab-inactive :background "grey65")) "Alternate face for inactive tab-line tabs. Applied to alternating tabs when option `tab-line-tab-face-functions' includes function @@ -87,9 +83,9 @@ Applied to alternating tabs when option :group 'tab-line-faces) (defface tab-line-tab-special - '((default (:weight bold)) + '((default :weight bold) (((supports :slant italic)) - (:slant italic :weight normal))) + :slant italic :weight normal)) "Face for special (i.e. non-file-backed) tabs. Applied when option `tab-line-tab-face-functions' includes function `tab-line-tab-face-special'." @@ -97,9 +93,7 @@ function `tab-line-tab-face-special'." :group 'tab-line-faces) (defface tab-line-tab-group - '((default - :inherit tab-line - :box nil)) + '((t :inherit tab-line :box nil)) "Face for group tabs. Applied when option `tab-line-tab-face-functions' includes function `tab-line-tab-face-group'." @@ -107,8 +101,7 @@ function `tab-line-tab-face-group'." :group 'tab-line-faces) (defface tab-line-tab-current - '((default - :inherit tab-line-tab) + '((default :inherit tab-line-tab) (((class color) (min-colors 88)) :background "grey85")) "Tab line face for tab with current buffer in selected window." @@ -116,7 +109,7 @@ function `tab-line-tab-face-group'." :group 'tab-line-faces) (defface tab-line-highlight - '((default :inherit tab-line-tab)) + '((t :inherit tab-line-tab)) "Tab line face for highlighting." :version "27.1" :group 'tab-line-faces) @@ -189,7 +182,7 @@ If the value is a function, call it with no arguments." (defvar tab-line-new-button (propertize " + " - 'display `(image :type xpm + 'display '(image :type xpm :file "tabs/new.xpm" :margin (2 . 0) :ascent center) @@ -217,7 +210,7 @@ If nil, don't show it at all." (defvar tab-line-close-button (propertize " x" - 'display `(image :type xpm + 'display '(image :type xpm :file "tabs/close.xpm" :margin (2 . 0) :ascent center) @@ -228,7 +221,7 @@ If nil, don't show it at all." (defvar tab-line-left-button (propertize " <" - 'display `(image :type xpm + 'display '(image :type xpm :file "tabs/left-arrow.xpm" :margin (2 . 0) :ascent center) @@ -239,7 +232,7 @@ If nil, don't show it at all." (defvar tab-line-right-button (propertize "> " - 'display `(image :type xpm + 'display '(image :type xpm :file "tabs/right-arrow.xpm" :margin (2 . 0) :ascent center) commit 0441e605a12a238abebdc9557151dcad87037d64 Author: Juri Linkov Date: Wed Mar 17 19:42:27 2021 +0200 * lisp/tab-bar.el: New faces and face options. * lisp/tab-bar.el (tab-bar-tab-group-current) (tab-bar-tab-group-inactive, tab-bar-tab-ungrouped): New deffaces. (tab-bar-tab-face-function): New defcustom. (tab-bar-tab-face-default): New function. (tab-bar-tab-name-format-default): Use it. (tab-bar-tab-group-format-default): Use tab-bar-tab-group-inactive face. (tab-bar-tab-group-face-function): New defcustom. (tab-bar-tab-group-face-default): New function. (tab-bar--format-tab-group): Add new arg 'current-p'. (tab-bar-format-tabs-groups): Prepend current group name before first tab. Override tab-bar-tab-face-function with tab-bar-tab-group-face-function. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 351c8cff34..45ed2a6b31 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -72,6 +72,24 @@ :version "27.1" :group 'tab-bar-faces) +(defface tab-bar-tab-group-current + '((t :inherit tab-bar-tab :box nil :weight bold)) + "Tab bar face for current group tab." + :version "28.1" + :group 'tab-bar-faces) + +(defface tab-bar-tab-group-inactive + '((t :inherit (shadow tab-bar-tab-inactive))) + "Tab bar face for inactive group tab." + :version "28.1" + :group 'tab-bar-faces) + +(defface tab-bar-tab-ungrouped + '((t :inherit (shadow tab-bar-tab-inactive))) + "Tab bar face for ungrouped tab when tab groups are used." + :version "28.1" + :group 'tab-bar-faces) + (defcustom tab-bar-select-tab-modifiers '() "List of modifier keys for selecting a tab by its index digit. @@ -513,6 +531,16 @@ Return its existing value or a new value." (set-frame-parameter frame 'tabs tabs)) +(defcustom tab-bar-tab-face-function #'tab-bar-tab-face-default + "Function to define a tab face. +Function gets one argument: a tab." + :type 'function + :group 'tab-bar + :version "28.1") + +(defun tab-bar-tab-face-default (tab) + (if (eq (car tab) 'current-tab) 'tab-bar-tab 'tab-bar-tab-inactive)) + (defcustom tab-bar-tab-name-format-function #'tab-bar-tab-name-format-default "Function to format a tab name. Function gets two arguments, the tab and its number, and should return @@ -535,7 +563,7 @@ the formatted tab name to display in the tab bar." (if current-p 'non-selected 'selected))) tab-bar-close-button) "")) - 'face (if current-p 'tab-bar-tab 'tab-bar-tab-inactive)))) + 'face (funcall tab-bar-tab-face-function tab)))) (defcustom tab-bar-format '(tab-bar-format-history tab-bar-format-tabs @@ -642,19 +670,36 @@ and should return the formatted tab group name to display in the tab bar." (propertize (concat (if tab-bar-tab-hints (format "%d " i) "") (funcall tab-bar-tab-group-function tab)) - 'face 'tab-bar-tab-inactive)) + 'face 'tab-bar-tab-group-inactive)) -(defun tab-bar--format-tab-group (tab i) +(defcustom tab-bar-tab-group-face-function #'tab-bar-tab-group-face-default + "Function to define a tab group face. +Function gets one argument: a tab." + :type 'function + :group 'tab-bar + :version "28.1") + +(defun tab-bar-tab-group-face-default (tab) + (if (not (or (eq (car tab) 'current-tab) + (funcall tab-bar-tab-group-function tab))) + 'tab-bar-tab-ungrouped + (tab-bar-tab-face-default tab))) + +(defun tab-bar--format-tab-group (tab i &optional current-p) (append `((,(intern (format "sep-%i" i)) menu-item ,(tab-bar-separator) ignore)) `((,(intern (format "group-%i" i)) menu-item - ,(funcall tab-bar-tab-group-format-function tab i) - ,(or - (alist-get 'binding tab) - `(lambda () - (interactive) - (tab-bar-select-tab ,i))) + ,(if current-p + (propertize (funcall tab-bar-tab-group-function tab) + 'face 'tab-bar-tab-group-current) + (funcall tab-bar-tab-group-format-function tab i)) + ,(if current-p 'ignore + (or + (alist-get 'binding tab) + `(lambda () + (interactive) + (tab-bar-select-tab ,i)))) :help "Click to visit group")))) (defun tab-bar-format-tabs-groups () @@ -667,13 +712,21 @@ and should return the formatted tab group name to display in the tab bar." (lambda (tab) (let ((tab-group (funcall tab-bar-tab-group-function tab))) (setq i (1+ i)) - (prog1 (if (or (not tab-group) (equal tab-group current-group)) - ;; Show current group and ungrouped tabs - (tab-bar--format-tab tab i) - ;; Otherwise, show first group tab with a group name, - ;; but hide other group tabs - (unless (equal previous-group tab-group) - (tab-bar--format-tab-group tab i))) + (prog1 (cond + ;; Show current group tabs and ungrouped tabs + ((or (equal tab-group current-group) (not tab-group)) + (append + ;; Prepend current group name before first tab + (when (and (not (equal previous-group tab-group)) tab-group) + (tab-bar--format-tab-group tab i t)) + ;; Override default tab faces to use group faces + (let ((tab-bar-tab-face-function tab-bar-tab-group-face-function)) + (tab-bar--format-tab tab i)))) + ;; Show first tab of other groups with a group name + ((not (equal previous-group tab-group)) + (tab-bar--format-tab-group tab i)) + ;; Hide other group tabs + (t nil)) (setq previous-group tab-group)))) tabs))) commit 6e796b52e1e61c67e5d939bfcc77d34b9d735158 Author: Dmitry Gutov Date: Wed Mar 17 18:49:14 2021 +0200 Stop project-root from going into infinite recursion * lisp/progmodes/project.el (project--within-roots-fallback): New variable. (project-root, project-roots): Use it (bug#47168). diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 18da4398f4..65897b008c 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -208,6 +208,8 @@ of the project instance object." (defun project--find-in-directory (dir) (run-hook-with-args-until-success 'project-find-functions dir)) +(defvar project--within-roots-fallback nil) + (cl-defgeneric project-root (project) "Return root directory of the current project. @@ -215,7 +217,9 @@ It usually contains the main build file, dependencies configuration file, etc. Though neither is mandatory. The directory name must be absolute." - (car (project-roots project))) + (if project--within-roots-fallback + (signal 'cl-no-applicable-method (list 'project-root project)) + (car (project-roots project)))) (cl-defgeneric project-roots (project) "Return the list containing the current project root. @@ -226,7 +230,8 @@ and the rest should be possible to express through ;; FIXME: Can we specify project's version here? ;; FIXME: Could we make this affect cl-defmethod calls too? (declare (obsolete project-root "0.3.0")) - (list (project-root project))) + (let ((project--within-roots-fallback t)) + (list (project-root project)))) ;; FIXME: Add MODE argument, like in `ede-source-paths'? (cl-defgeneric project-external-roots (_project) commit a7f95d5244dcb1fea067858c3ddc2bb2a22ba37a Author: Fabrice Bauzac Date: Tue Mar 16 21:09:15 2021 +0100 Remove duplicate @table item from ELisp manual * doc/lispref/objects.texi (Special Read Syntax): Remove duplicate item "#@N" from the table of Special Read Syntax. (Bug#47200) diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi index 9b44386569..99949815ed 100644 --- a/doc/lispref/objects.texi +++ b/doc/lispref/objects.texi @@ -148,9 +148,6 @@ starting list count: object, so when reading back the object, they will be the same object instead of copies (@pxref{Circular Objects}). -@item #@@N -Skip the next @samp{N} characters (@pxref{Comments}). - @item #xN @samp{N} represented as a hexadecimal number (@samp{#x2a}). commit f5e1fc371af7a4211ca7a40b5db0b7da00cb1d93 Author: Michael Albinus Date: Tue Mar 16 19:45:23 2021 +0100 ; Remove traces from tramp-tests.el diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 6847d71be2..be428fc2a6 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -237,9 +237,6 @@ is greater than 10. :expected-result (if (tramp--test-enabled) :passed :failed) (tramp--test-message "Remote directory: `%s'" tramp-test-temporary-file-directory) - (when (or (getenv "EMACS_HYDRA_CI") (getenv "EMACS_EMBA_CI")) - (tramp-test-message "%s %s %s %s %s %s" - exec-directory data-directory temporary-file-directory load-path (bound-and-true-p image-load-path) (getenv "HOME"))) (should (ignore-errors (and (file-remote-p tramp-test-temporary-file-directory) commit 3ea0a334dca81faeb619e8a52ecfaf7ad072eaf4 Author: Juri Linkov Date: Tue Mar 16 20:07:34 2021 +0200 New commands xref-next-line-no-show and xref-prev-line-no-show (bug#44611) * lisp/progmodes/xref.el (xref-next-line-no-show) (xref-prev-line-no-show): New commands. (xref-next-line, xref-prev-line): Use them. diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index c066d9dc02..ea52befec5 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -609,16 +609,26 @@ SELECT is `quit', also quit the *xref* window." (when xref (xref--show-location (xref-item-location xref))))) +(defun xref-next-line-no-show () + "Move to the next xref but don't display its source." + (interactive) + (xref--search-property 'xref-item)) + (defun xref-next-line () "Move to the next xref and display its source in the appropriate window." (interactive) - (xref--search-property 'xref-item) + (xref-next-line-no-show) (xref-show-location-at-point)) +(defun xref-prev-line-no-show () + "Move to the previous xref but don't display its source." + (interactive) + (xref--search-property 'xref-item t)) + (defun xref-prev-line () "Move to the previous xref and display its source in the appropriate window." (interactive) - (xref--search-property 'xref-item t) + (xref-prev-line-no-show) (xref-show-location-at-point)) (defun xref-next-group () commit 2ebd9502391b2be7dc750aa2947ae75b5ec59ba7 Author: Juri Linkov Date: Tue Mar 16 20:03:55 2021 +0200 Minor fixes * lisp/frame.el (set-frame-property--interactive): Remove '(point)' that makes no sense as the default value. (Bug#9970) * lisp/simple.el (next-error-found-function): Move defcustom closer to function 'next-error-found' where it's used. diff --git a/lisp/frame.el b/lisp/frame.el index 409ce0563b..b5a8e0ed72 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -2739,7 +2739,7 @@ Offer NUMBER as default value, if it is a natural number." (if (and current-prefix-arg (not (consp current-prefix-arg))) (list (selected-frame) (prefix-numeric-value current-prefix-arg)) (let ((default (and (natnump number) number))) - (list (selected-frame) (read-number prompt (list default (point))))))) + (list (selected-frame) (read-number prompt default))))) ;; Variables whose change of value should trigger redisplay of the ;; current buffer. diff --git a/lisp/simple.el b/lisp/simple.el index 98fccf4ff2..37aa650b30 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -238,15 +238,6 @@ all other buffers." :group 'next-error :version "28.1") -(defcustom next-error-found-function #'ignore - "Function called when a next locus is found and displayed. -Function is called with two arguments: a FROM-BUFFER buffer -from which next-error navigated, and a target buffer TO-BUFFER." - :type '(choice (const :tag "No default" ignore) - (function :tag "Other function")) - :group 'next-error - :version "27.1") - (defun next-error-buffer-on-selected-frame (&optional _avoid-current extra-test-inclusive extra-test-exclusive) @@ -386,6 +377,15 @@ To control which errors are matched, customize the variable (not (eq prev next-error-last-buffer))) (message "Current locus from %s" next-error-last-buffer))))) +(defcustom next-error-found-function #'ignore + "Function called when a next locus is found and displayed. +Function is called with two arguments: a FROM-BUFFER buffer +from which next-error navigated, and a target buffer TO-BUFFER." + :type '(choice (const :tag "No default" ignore) + (function :tag "Other function")) + :group 'next-error + :version "27.1") + (defun next-error-found (&optional from-buffer to-buffer) "Function to call when the next locus is found and displayed. FROM-BUFFER is a buffer from which next-error navigated, commit 6199cdc78bde331cbb9fab4fbb93b467559bf461 Author: Juri Linkov Date: Tue Mar 16 19:54:54 2021 +0200 * lisp/tab-bar.el (tab-bar-select-tab): Support negative arg. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 888f493ddc..351c8cff34 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -814,7 +814,7 @@ on the tab bar instead." When this command is bound to a numeric key (with a prefix or modifier key using `tab-bar-select-tab-modifiers'), calling it without an argument will translate its bound numeric key to the numeric argument. -ARG counts from 1." +ARG counts from 1. Negative ARG counts tabs from the end of the tab bar." (interactive "P") (unless (integerp arg) (let ((key (event-basic-type last-command-event))) @@ -824,7 +824,9 @@ ARG counts from 1." (let* ((tabs (funcall tab-bar-tabs-function)) (from-index (tab-bar--current-tab-index tabs)) - (to-index (1- (max 1 (min arg (length tabs)))))) + (to-index (if (< arg 0) (+ (length tabs) (1+ arg)) arg)) + (to-index (1- (max 1 (min to-index (length tabs)))))) + (unless (eq from-index to-index) (let* ((from-tab (tab-bar--tab)) (to-tab (nth to-index tabs)) commit 126ea102a542c04b007c2229b004a360544be5da Author: Juri Linkov Date: Tue Mar 16 19:53:27 2021 +0200 * lisp/tab-bar.el: Simplify internal functions. * lisp/tab-bar.el (tab-bar-tabs-set): New function. (tab-bar-tabs): Use tab-bar--current-tab-find and tab-bar-tabs-set. (tab-bar--tab): Use tab-bar--current-tab-find. (tab-bar--current-tab): Remove unused line (assq 'current-tab ...) because there is no current-tab when it's called. Remove unused arg 'frame'. (tab-bar--current-tab-find): Simplify. (tab-bar-move-tab-to, tab-bar-move-tab-to-frame) (tab-bar-new-tab-to, tab-bar-close-tab) (tab-bar-close-other-tabs, tab-bar-undo-close-tab) (tab-switcher-delete-from-list): Use tab-bar-tabs-set instead of set-frame-parameter. (tab-bar-close-group-tabs): Simplify using tab-bar--current-tab-find without arg. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index a2411271ae..888f493ddc 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -489,13 +489,13 @@ For example, \\='((tab (name . \"Tab 1\")) (current-tab (name . \"Tab 2\"))) By default, use function `tab-bar-tabs'.") (defun tab-bar-tabs (&optional frame) - "Return a list of tabs belonging to the selected frame. + "Return a list of tabs belonging to the FRAME. Ensure the frame parameter `tabs' is pre-populated. Update the current tab name when it exists. Return its existing value or a new value." (let ((tabs (frame-parameter frame 'tabs))) (if tabs - (let* ((current-tab (assq 'current-tab tabs)) + (let* ((current-tab (tab-bar--current-tab-find tabs)) (current-tab-name (assq 'name current-tab)) (current-tab-explicit-name (assq 'explicit-name current-tab))) (when (and current-tab-name @@ -505,9 +505,13 @@ Return its existing value or a new value." (funcall tab-bar-tab-name-function)))) ;; Create default tabs (setq tabs (list (tab-bar--current-tab))) - (set-frame-parameter frame 'tabs tabs)) + (tab-bar-tabs-set tabs frame)) tabs)) +(defun tab-bar-tabs-set (tabs &optional frame) + "Set a list of TABS on the FRAME." + (set-frame-parameter frame 'tabs tabs)) + (defcustom tab-bar-tab-name-format-function #'tab-bar-tab-name-format-default "Function to format a tab name. @@ -738,7 +742,7 @@ on the tab bar instead." (push '(tabs . frameset-filter-tabs) frameset-filter-alist) (defun tab-bar--tab (&optional frame) - (let* ((tab (assq 'current-tab (frame-parameter frame 'tabs))) + (let* ((tab (tab-bar--current-tab-find)) (tab-explicit-name (alist-get 'explicit-name tab)) (tab-group (alist-get 'group tab)) (bl (seq-filter #'buffer-live-p (frame-parameter frame 'buffer-list))) @@ -759,12 +763,11 @@ on the tab bar instead." (wc-history-back . ,(gethash (or frame (selected-frame)) tab-bar-history-back)) (wc-history-forward . ,(gethash (or frame (selected-frame)) tab-bar-history-forward))))) -(defun tab-bar--current-tab (&optional tab frame) +(defun tab-bar--current-tab (&optional tab) ;; `tab' here is an argument meaning "use tab as template". This is ;; necessary when switching tabs, otherwise the destination tab ;; inherits the current tab's `explicit-name' parameter. - (let* ((tab (or tab (assq 'current-tab (frame-parameter frame 'tabs)))) - (tab-explicit-name (alist-get 'explicit-name tab)) + (let* ((tab-explicit-name (alist-get 'explicit-name tab)) (tab-group (if tab (alist-get 'group tab) (pcase tab-bar-new-tab-group @@ -778,8 +781,7 @@ on the tab bar instead." ,@(if tab-group `((group . ,tab-group)))))) (defun tab-bar--current-tab-find (&optional tabs frame) - (seq-find (lambda (tab) (eq (car tab) 'current-tab)) - (or tabs (funcall tab-bar-tabs-function frame)))) + (assq 'current-tab (or tabs (funcall tab-bar-tabs-function frame)))) (defun tab-bar--current-tab-index (&optional tabs frame) (seq-position (or tabs (funcall tab-bar-tabs-function frame)) @@ -950,7 +952,7 @@ where argument addressing is relative." (to-index (max 0 (min (1- to-index) (1- (length tabs)))))) (setq tabs (delq from-tab tabs)) (cl-pushnew from-tab (nthcdr to-index tabs)) - (set-frame-parameter nil 'tabs tabs) + (tab-bar-tabs-set tabs) (force-mode-line-update))) (defun tab-bar-move-tab (&optional arg) @@ -992,7 +994,7 @@ Interactively, ARG selects the ARGth different frame to move to." (let ((inhibit-message t) ; avoid message about deleted tab tab-bar-closed-tabs) (tab-bar-close-tab from-index))) - (set-frame-parameter to-frame 'tabs to-tabs) + (tab-bar-tabs-set to-tabs to-frame) (force-mode-line-update t)))) @@ -1074,7 +1076,7 @@ After the tab is created, the hooks in (when (eq to-index 0) ;; `pushnew' handles the head of tabs but not frame-parameter - (set-frame-parameter nil 'tabs tabs)) + (tab-bar-tabs-set tabs)) (run-hook-with-args 'tab-bar-tab-post-open-functions (nth to-index tabs))) @@ -1230,7 +1232,7 @@ for the last tab on a frame is determined by (tab-bar--tab) close-tab))) tab-bar-closed-tabs) - (set-frame-parameter nil 'tabs (delq close-tab tabs))) + (tab-bar-tabs-set (delq close-tab tabs))) ;; Recalculate `tab-bar-lines' and update frames (tab-bar--update-tab-bar-lines) @@ -1269,7 +1271,7 @@ for the last tab on a frame is determined by (run-hook-with-args 'tab-bar-tab-pre-close-functions tab nil) (setq tabs (delq tab tabs))) (setq index (1+ index))) - (set-frame-parameter nil 'tabs tabs) + (tab-bar-tabs-set tabs) ;; Recalculate tab-bar-lines and update frames (tab-bar--update-tab-bar-lines) @@ -1299,7 +1301,7 @@ for the last tab on a frame is determined by (cl-pushnew tab (nthcdr index tabs)) (when (eq index 0) ;; pushnew handles the head of tabs but not frame-parameter - (set-frame-parameter nil 'tabs tabs)) + (tab-bar-tabs-set tabs)) (tab-bar-select-tab (1+ index)))) (message "No more closed tabs to undo"))) @@ -1392,9 +1394,8 @@ While using this command, you might also want to replace (defun tab-bar-close-group-tabs (group-name) "Close all tabs that belong to GROUP-NAME on the selected frame." (interactive - (let* ((tabs (funcall tab-bar-tabs-function)) - (group-name (funcall tab-bar-tab-group-function - (tab-bar--current-tab-find tabs)))) + (let ((group-name (funcall tab-bar-tab-group-function + (tab-bar--current-tab-find)))) (list (completing-read "Close all tabs with group name: " (delete-dups @@ -1410,12 +1411,10 @@ While using this command, you might also want to replace tab-bar-tab-prevent-close-functions))) (tab-bar-close-other-tabs) - (let* ((tabs (funcall tab-bar-tabs-function)) - (current-tab (tab-bar--current-tab-find tabs))) - (when (and current-tab - (equal (funcall tab-bar-tab-group-function current-tab) - close-group)) - (tab-bar-close-tab))))) + (when (equal (funcall tab-bar-tab-group-function + (tab-bar--current-tab-find)) + close-group) + (tab-bar-close-tab)))) ;;; Tab history mode @@ -1704,7 +1703,7 @@ Then move up one line. Prefix arg means move that many lines." (index . ,(tab-bar--tab-index tab)) (tab . ,tab)) tab-bar-closed-tabs) - (set-frame-parameter nil 'tabs (delq tab (funcall tab-bar-tabs-function)))) + (tab-bar-tabs-set (delq tab (funcall tab-bar-tabs-function)))) (defun tab-switcher-execute () "Delete window configurations marked with \\\\[tab-switcher-delete] commands." commit c209a0f82825dacd7edeef34b31f458499307eef Author: Michael Albinus Date: Tue Mar 16 18:40:24 2021 +0100 Fix problem of image-tests.el on emba * test/README: Mention $EMACS_TEST_DIRECTORY. * test/lisp/image-tests.el (image-tests--emacs-images-directory): Use `data-directory', for runs w/o of make. (image-type/from-filename): Check for `image-load-path'. diff --git a/test/README b/test/README index 1e0e43a8ac..a348074aba 100644 --- a/test/README +++ b/test/README @@ -22,7 +22,10 @@ following tags are recognized: * :unstable The test is under development. It shall run on demand only. -The Makefile in this directory supports the following targets: +The Makefile sets the environment variable $EMACS_TEST_DIRECTORY, +which points to this directory. This environment variable does not +exist when the tests are run outside make. The Makefile supports the +following targets: * make check Run all tests as defined in the directory. Expensive and unstable @@ -113,6 +116,7 @@ Some optional tests require packages from GNU ELPA. By default out somewhere else, use make GNU_ELPA_DIRECTORY=/path/to/elpa ... + There are also continuous integration tests on (see diff --git a/test/lisp/image-tests.el b/test/lisp/image-tests.el index bb42ffae18..2f7afa2f38 100644 --- a/test/lisp/image-tests.el +++ b/test/lisp/image-tests.el @@ -25,7 +25,7 @@ (require 'cl-lib)) (defconst image-tests--emacs-images-directory - (expand-file-name "../etc/images" (getenv "EMACS_TEST_DIRECTORY")) + (expand-file-name "images" data-directory) "Directory containing Emacs images.") (ert-deftest image--set-property () @@ -57,6 +57,8 @@ (should (eq (image-type-from-file-name "foo.png") 'png))) (ert-deftest image-type/from-filename () + ;; On emba, `image-load-path' does not exist. + (skip-unless (bound-and-true-p image-load-path)) (should (eq (image-type "foo.jpg") 'jpeg))) (ert-deftest image-type-from-file-header-test () commit 6c60ecd2d632ad41851e91cc53036a679c391194 Author: Michael Albinus Date: Tue Mar 16 18:39:51 2021 +0100 Fix problem in Tramp running two async processes in parallel * lisp/net/tramp-integration.el (tramp-compile-disable-ssh-controlmaster-options): New defun. Add it to `compilation-mode-hook'. (Bug#45518) * lisp/progmodes/compile.el (compilation-get-file-structure): Revert commit 4ce5646d59, it isn't needed. diff --git a/lisp/net/tramp-integration.el b/lisp/net/tramp-integration.el index 5adc4ce354..9d4dd7d42a 100644 --- a/lisp/net/tramp-integration.el +++ b/lisp/net/tramp-integration.el @@ -261,6 +261,23 @@ NAME must be equal to `tramp-current-connection'." (delete (info-lookup->mode-cache 'symbol ',mode) (info-lookup->topic-cache 'symbol)))))))) +;;; Integration of compile.el: + +;; Compilation processes use `accept-process-output' such a way that +;; Tramp's parallel `accept-process-output' blocks. See last part of +;; Bug#45518. So we don't use ssh ControlMaster options. +(defun tramp-compile-disable-ssh-controlmaster-options () + "Don't allow ssh ControlMaster while compiling." + (setq-local tramp-use-ssh-controlmaster-options nil)) + +(with-eval-after-load 'compile + (add-hook 'compilation-mode-hook + #'tramp-compile-disable-ssh-controlmaster-options) + (add-hook 'tramp-integration-unload-hook + (lambda () + (remove-hook 'compilation-start-hook + #'tramp-compile-disable-ssh-controlmaster-options)))) + ;;; Default connection-local variables for Tramp: ;; `connection-local-set-profile-variables' and ;; `connection-local-set-profiles' exists since Emacs 26.1. @@ -277,7 +294,7 @@ NAME must be equal to `tramp-current-connection'." (tramp-compat-funcall 'connection-local-set-profiles - `(:application tramp) + '(:application tramp) 'tramp-connection-local-default-system-profile) (defconst tramp-connection-local-default-shell-variables @@ -293,7 +310,7 @@ NAME must be equal to `tramp-current-connection'." (with-eval-after-load 'shell (tramp-compat-funcall 'connection-local-set-profiles - `(:application tramp) + '(:application tramp) 'tramp-connection-local-default-shell-profile)) (add-hook 'tramp-unload-hook diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index 48b5ee9973..d23c77ef86 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -3040,12 +3040,7 @@ TRUE-DIRNAME is the `file-truename' of DIRNAME, if given." ;; Get the specified directory from FILE. (spec-directory (if (cdr file) - ;; This function is active in `compilation-filter'. - ;; There could be problems to call `file-truename' - ;; for remote compilation processes. - (if (file-remote-p default-directory) - (concat comint-file-name-prefix (cdr file)) - (file-truename (concat comint-file-name-prefix (cdr file))))))) + (file-truename (concat comint-file-name-prefix (cdr file)))))) ;; Check for a comint-file-name-prefix and prepend it if appropriate. ;; (This is very useful for compilation-minor-mode in an rlogin-mode commit 9b8a6b917b43ff00adca5de0607f92dfeafb6502 Author: Michael Albinus Date: Tue Mar 16 16:35:23 2021 +0100 ; Further traces in tramp-tests.el diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 3ce390f093..6847d71be2 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -239,7 +239,7 @@ is greater than 10. "Remote directory: `%s'" tramp-test-temporary-file-directory) (when (or (getenv "EMACS_HYDRA_CI") (getenv "EMACS_EMBA_CI")) (tramp-test-message "%s %s %s %s %s %s" - exec-directory data-directory temporary-file-directory load-path image-load-path (getenv "HOME"))) + exec-directory data-directory temporary-file-directory load-path (bound-and-true-p image-load-path) (getenv "HOME"))) (should (ignore-errors (and (file-remote-p tramp-test-temporary-file-directory) commit f8fbd308b6096b644778ce6331f6e3af2b8b5eb1 Author: Michael Albinus Date: Tue Mar 16 15:36:54 2021 +0100 ; Trace variables in tramp-tests.el diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index be428fc2a6..3ce390f093 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -237,6 +237,9 @@ is greater than 10. :expected-result (if (tramp--test-enabled) :passed :failed) (tramp--test-message "Remote directory: `%s'" tramp-test-temporary-file-directory) + (when (or (getenv "EMACS_HYDRA_CI") (getenv "EMACS_EMBA_CI")) + (tramp-test-message "%s %s %s %s %s %s" + exec-directory data-directory temporary-file-directory load-path image-load-path (getenv "HOME"))) (should (ignore-errors (and (file-remote-p tramp-test-temporary-file-directory) commit 0fbd2fa88c225d228982549e528a4c5c3615f4fb Author: Stefan Monnier Date: Tue Mar 16 08:43:45 2021 -0400 * etc/themes/modus-themes.el: Bump version for GNU ELPA release (News:): New section. diff --git a/etc/themes/modus-themes.el b/etc/themes/modus-themes.el index c315d5971b..ad2070766a 100644 --- a/etc/themes/modus-themes.el +++ b/etc/themes/modus-themes.el @@ -4,7 +4,7 @@ ;; Author: Protesilaos Stavrou ;; URL: https://gitlab.com/protesilaos/modus-themes -;; Version: 1.2.3 +;; Version: 1.2.4 ;; Package-Requires: ((emacs "26.1")) ;; Keywords: faces, theme, accessibility @@ -386,6 +386,20 @@ ;; - modus-operandi-theme.el (Light theme) ;; - modus-vivendi-theme.el (Dark theme) +;;; News: +;; +;; Users updating from older versions to >= 1.0.0, are advised to read +;; the anouncement on the emacs-devel mailing list: +;; . +;; +;; The web page of the change log is also available: +;; . +;; +;; An Info manual should be distributed with the Modus themes. +;; Evaluate this form to access it directly: +;; +;; (info "(modus-themes) Top") + ;;; Code: commit ef122bf45d8ab7f8ec31612ac39fc521039ae19a Author: Daniel Martín Date: Tue Mar 16 01:29:28 2021 +0100 Add minibuffer input support to commands that set the frame size * lisp/frame.el (set-frame-property--interactive): Internal function to produce the interactive form of `set-frame-width' and `set-frame-height'. Offer the current size as default. (Bug#9970) * src/frame.c (Fset_frame_height): Modify to call `set-frame-property--interactive'. (Fset_frame_width): Modify to call `set-frame-property--interactive'. * doc/lispref/frames.texi (Frame Size): Update the manuals. * etc/NEWS: Advertise the change (bug#9970). diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index f4316b753d..cd2ff8f3b3 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -1120,9 +1120,9 @@ The optional fourth argument @var{pixelwise} non-@code{nil} means that refuse to truly honor the request if it does not increase/decrease the frame height to a multiple of its character height. -When used interactively, this command will set the height of the -currently selected frame to the number of lines specified by the -numeric prefix. +When used interactively, this command will ask the user for the number +of lines to set the height of the currently selected frame. You can +also provide this value with a numeric prefix. @end defun @defun set-frame-width frame width &optional pretend pixelwise @@ -1136,9 +1136,9 @@ The optional fourth argument @var{pixelwise} non-@code{nil} means that refuse to fully honor the request if it does not increase/decrease the frame width to a multiple of its character width. -When used interactively, this command will set the width of the -currently selected frame to the number of columns specified by the -numeric prefix. +When used interactively, this command will ask the user for the number +of columns to set the width of the currently selected frame. You can +also provide this value with a numeric prefix. @end defun None of these three functions will make a frame smaller than needed to diff --git a/etc/NEWS b/etc/NEWS index 18b1252bca..6fe98dbc12 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -253,6 +253,10 @@ commands. The new keystrokes are 'C-x x g' ('revert-buffer'), ('clone-buffer'), 'C-x x i' ('insert-buffer') and 'C-x x t' ('toggle-truncate-lines'). +--- +** Commands 'set-frame-width' and 'set-frame-height' can now get their +input using the minibuffer. + * Editing Changes in Emacs 28.1 diff --git a/lisp/frame.el b/lisp/frame.el index ce4de83b8c..409ce0563b 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -2733,6 +2733,14 @@ See also `toggle-frame-maximized'." (make-obsolete-variable 'window-system-version "it does not give useful information." "24.3") +(defun set-frame-property--interactive (prompt number) + "Get a value for `set-frame-width' or `set-frame-height', prompting with PROMPT. +Offer NUMBER as default value, if it is a natural number." + (if (and current-prefix-arg (not (consp current-prefix-arg))) + (list (selected-frame) (prefix-numeric-value current-prefix-arg)) + (let ((default (and (natnump number) number))) + (list (selected-frame) (read-number prompt (list default (point))))))) + ;; Variables whose change of value should trigger redisplay of the ;; current buffer. ;; To test whether a given variable needs to be added to this list, diff --git a/src/frame.c b/src/frame.c index a62347c1fb..cfdf3b6193 100644 --- a/src/frame.c +++ b/src/frame.c @@ -3595,7 +3595,7 @@ check_frame_pixels (Lisp_Object size, Lisp_Object pixelwise, int item_size) } DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 4, - "(list (selected-frame) (prefix-numeric-value current-prefix-arg))", + "(set-frame-property--interactive \"Frame height: \" (frame-height))", doc: /* Set text height of frame FRAME to HEIGHT lines. Optional third arg PRETEND non-nil means that redisplay should use HEIGHT lines but that the idea of the actual height of the frame should @@ -3620,7 +3620,7 @@ If FRAME is nil, it defaults to the selected frame. */) } DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 4, - "(list (selected-frame) (prefix-numeric-value current-prefix-arg))", + "(set-frame-property--interactive \"Frame width: \" (frame-width))", doc: /* Set text width of frame FRAME to WIDTH columns. Optional third arg PRETEND non-nil means that redisplay should use WIDTH columns but that the idea of the actual width of the frame should not commit c4549d3b37f7f3b9a9b5376eebb39b1929c48bd1 Author: Juri Linkov Date: Mon Mar 15 19:21:53 2021 +0200 * lisp/tab-bar.el (tab-bar-new-tab-group): New defcustom. (tab-bar--current-tab, tab-bar-new-tab-to, tab-bar-duplicate-tab): Use it. diff --git a/etc/NEWS b/etc/NEWS index 01fd7af65b..18b1252bca 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -545,6 +545,7 @@ It also supports a negative argument. --- *** 'C-x t G' assigns a group name to the tab. 'tab-close-group' can close all tabs that belong to the selected group. +The option 'tab-bar-new-tab-group' defines the default group of a new tab. --- *** New user option 'tab-bar-tab-name-format-function'. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 3cbdd528b0..a2411271ae 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -327,6 +327,20 @@ before calling the command that adds a new tab." :group 'tab-bar :version "27.1") +(defcustom tab-bar-new-tab-group nil + "Defines what group to assign to a new tab. +If nil, don't set a default group automatically. +If t, inherit the group name from the previous tab. +If the value is a string, use it as the group name of a new tab. +If the value is a function, call it with no arguments +to get the group name." + :type '(choice (const :tag "No automatic group" nil) + (const :tag "Inherit group from previous tab" t) + (string :tag "Fixed group name") + (function :tag "Function that returns group name")) + :group 'tab-bar + :version "28.1") + (defcustom tab-bar-new-button-show t "If non-nil, show the \"New tab\" button in the tab bar. When this is nil, you can create new tabs with \\[tab-new]." @@ -751,7 +765,11 @@ on the tab bar instead." ;; inherits the current tab's `explicit-name' parameter. (let* ((tab (or tab (assq 'current-tab (frame-parameter frame 'tabs)))) (tab-explicit-name (alist-get 'explicit-name tab)) - (tab-group (alist-get 'group tab))) + (tab-group (if tab + (alist-get 'group tab) + (pcase tab-bar-new-tab-group + ((pred stringp) tab-bar-new-tab-group) + ((pred functionp) (funcall tab-bar-new-tab-group)))))) `(current-tab (name . ,(if tab-explicit-name (alist-get 'name tab) @@ -1035,7 +1053,10 @@ After the tab is created, the hooks in (when from-index (setf (nth from-index tabs) from-tab)) - (let* ((to-tab (tab-bar--current-tab)) + + (let* ((to-tab (tab-bar--current-tab + (when (eq tab-bar-new-tab-group t) + `((group . ,(alist-get 'group from-tab)))))) (to-index (and to-index (prefix-numeric-value to-index))) (to-index (or (if to-index (if (< to-index 0) @@ -1090,7 +1111,8 @@ where argument addressing is absolute." If a negative ARG, duplicate the tab to ARG positions to the left. If ARG is zero, duplicate the tab in place of the current tab." (interactive "P") - (let ((tab-bar-new-tab-choice nil)) + (let ((tab-bar-new-tab-choice nil) + (tab-bar-new-tab-group t)) (tab-bar-new-tab arg))) commit 3a252ba6fd51c2b92dda397c48768d29f9168074 Author: Juri Linkov Date: Mon Mar 15 19:20:06 2021 +0200 * lisp/tab-bar.el (tab-bar-tab-group-format-function): New defcustom. (tab-bar-tab-group-default): New function. (tab-bar-tab-group-format-default, tab-bar-format-tabs-groups) (tab-bar-change-tab-group, tab-bar-close-group-tabs): Use it. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 5c6f73ab37..3cbdd528b0 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -594,6 +594,20 @@ the mode line. Replacing `tab-bar-format-tabs' with (tab-bar--format-tab tab i)) (funcall tab-bar-tabs-function)))) +(defcustom tab-bar-tab-group-function #'tab-bar-tab-group-default + "Function to get a tab group name. +Function gets one argument: a tab." + :type 'function + :initialize 'custom-initialize-default + :set (lambda (sym val) + (set-default sym val) + (force-mode-line-update)) + :group 'tab-bar + :version "28.1") + +(defun tab-bar-tab-group-default (tab) + (alist-get 'group tab)) + (defcustom tab-bar-tab-group-format-function #'tab-bar-tab-group-format-default "Function to format a tab group name. Function gets two arguments, a tab with a group name and its number, @@ -609,7 +623,7 @@ and should return the formatted tab group name to display in the tab bar." (defun tab-bar-tab-group-format-default (tab i) (propertize (concat (if tab-bar-tab-hints (format "%d " i) "") - (alist-get 'group tab)) + (funcall tab-bar-tab-group-function tab)) 'face 'tab-bar-tab-inactive)) (defun tab-bar--format-tab-group (tab i) @@ -627,12 +641,13 @@ and should return the formatted tab group name to display in the tab bar." (defun tab-bar-format-tabs-groups () (let* ((tabs (funcall tab-bar-tabs-function)) - (current-group (alist-get 'group (tab-bar--current-tab-find tabs))) + (current-group (funcall tab-bar-tab-group-function + (tab-bar--current-tab-find tabs))) (previous-group nil) (i 0)) (mapcan (lambda (tab) - (let ((tab-group (alist-get 'group tab))) + (let ((tab-group (funcall tab-bar-tab-group-function tab))) (setq i (1+ i)) (prog1 (if (or (not tab-group) (equal tab-group current-group)) ;; Show current group and ungrouped tabs @@ -1325,14 +1340,17 @@ While using this command, you might also want to replace `tab-bar-format' to group tabs on the tab bar." (interactive (let* ((tabs (funcall tab-bar-tabs-function)) - (tab-index (or current-prefix-arg (1+ (tab-bar--current-tab-index tabs)))) - (group-name (alist-get 'group (nth (1- tab-index) tabs)))) + (tab-index (or current-prefix-arg + (1+ (tab-bar--current-tab-index tabs)))) + (group-name (funcall tab-bar-tab-group-function + (nth (1- tab-index) tabs)))) (list (completing-read "Group name for tab (leave blank to remove group): " - (delete-dups (delq nil (cons group-name - (mapcar (lambda (tab) - (alist-get 'group tab)) - (funcall tab-bar-tabs-function)))))) + (delete-dups + (delq nil (cons group-name + (mapcar (lambda (tab) + (funcall tab-bar-tab-group-function tab)) + (funcall tab-bar-tabs-function)))))) current-prefix-arg))) (let* ((tabs (funcall tab-bar-tabs-function)) (tab-index (if arg @@ -1353,24 +1371,28 @@ While using this command, you might also want to replace "Close all tabs that belong to GROUP-NAME on the selected frame." (interactive (let* ((tabs (funcall tab-bar-tabs-function)) - (group-name (alist-get 'group (tab-bar--current-tab-find tabs)))) + (group-name (funcall tab-bar-tab-group-function + (tab-bar--current-tab-find tabs)))) (list (completing-read "Close all tabs with group name: " - (delete-dups (delq nil (cons group-name - (mapcar (lambda (tab) - (alist-get 'group tab)) - (funcall tab-bar-tabs-function))))))))) + (delete-dups + (delq nil (cons group-name + (mapcar (lambda (tab) + (funcall tab-bar-tab-group-function tab)) + (funcall tab-bar-tabs-function))))))))) (let* ((close-group (and (> (length group-name) 0) group-name)) (tab-bar-tab-prevent-close-functions (cons (lambda (tab _last-tab-p) - (not (equal (alist-get 'group tab) close-group))) + (not (equal (funcall tab-bar-tab-group-function tab) + close-group))) tab-bar-tab-prevent-close-functions))) (tab-bar-close-other-tabs) (let* ((tabs (funcall tab-bar-tabs-function)) (current-tab (tab-bar--current-tab-find tabs))) - (when (and current-tab (equal (alist-get 'group current-tab) - close-group)) + (when (and current-tab + (equal (funcall tab-bar-tab-group-function current-tab) + close-group)) (tab-bar-close-tab))))) commit b341e866844c183a27a19f2bc05b00b125841307 Author: Glenn Morris Date: Mon Mar 15 08:51:05 2021 -0700 * CONTRIBUTE: Refer to gnulib for request-assign.future. The vast majority of the exchanges on this topic are "please send me the form; ok I sent you the form", and there's no need to involve a mailing list for that. diff --git a/CONTRIBUTE b/CONTRIBUTE index bbf5262862..2d70c4916c 100644 --- a/CONTRIBUTE +++ b/CONTRIBUTE @@ -72,9 +72,12 @@ the copyright for your contributions. (To see how many lines were non-trivially changed, count only added and modified lines in the patched code. Consider an added or changed line non-trivial if it includes at least one identifier, string, or substantial comment.) -Ask on emacs-devel@gnu.org, and we will send you the necessary form -together with the instructions to fill and email it, in order to start -this legal paperwork. +In most cases, to start the assignment process you should download +https://git.savannah.gnu.org/cgit/gnulib.git/plain/doc/Copyright/request-assign.future +and return the completed information to the address at the top. +(There are other assignment options, but they are much less commonly used.) +If you have questions about the assignment process, you can ask the +address listed on the form, and/or emacs-devel@gnu.org. ** Issue tracker (a.k.a. "bug tracker") commit 068fdb2c775720c34f127b2eab8c68fc5f924e7f Author: Protesilaos Stavrou Date: Mon Mar 15 10:04:20 2021 -0400 Make the `kbd` macro work in both Emacs-26 and Emacs-28 This is so that elpa.gnu.org's Emacs-26 can successfully build the Info version of it for the GNU ELPA package. diff --git a/doc/misc/modus-themes.org b/doc/misc/modus-themes.org index ed464e8465..9764a3467f 100644 --- a/doc/misc/modus-themes.org +++ b/doc/misc/modus-themes.org @@ -10,10 +10,7 @@ #+macro: export-date (eval (format-time-string "%F %R %z" (current-time))) #+macro: file @@texinfo:@file{@@$1@@texinfo:}@@ #+macro: space @@texinfo:@: @@ -# The "kbd" macro turns KBD into @kbd{KBD}. Additionally, it -# encloses case-sensitive special keys (SPC, RET...) within @key{...}. -# I got this from the Org source code. -#+macro: kbd (eval (let ((case-fold-search nil) (regexp (regexp-opt '("SPC" "RET" "LFD" "TAB" "BS" "ESC" "DELETE" "SHIFT" "Ctrl" "Meta" "Alt" "Cmd" "Super" "UP" "LEFT" "RIGHT" "DOWN") 'words))) (format "@@texinfo:@kbd{@@%s@@texinfo:}@@" (replace-regexp-in-string regexp "@@texinfo:@key{@@\\&@@texinfo:}@@" $1 t)))) +#+macro: kbd @@texinfo:@kbd{@@$1@@texinfo:}@@ #+texinfo_filename: modus-themes.info #+texinfo_dir_category: Emacs misc features commit 5120b612f8520a855fc1819c3ebf86453c361e55 Author: Michael Albinus Date: Mon Mar 15 09:49:20 2021 +0100 Improve command completion in tramp-crypt.el * lisp/net/tramp-crypt.el (tramp-crypt-command-completion-p): Rename from `tramp-crypt-enabled-p'. Handle `tramp-crypt-remove-directory' special. diff --git a/lisp/net/tramp-crypt.el b/lisp/net/tramp-crypt.el index f44be449e2..1d8c0ad217 100644 --- a/lisp/net/tramp-crypt.el +++ b/lisp/net/tramp-crypt.el @@ -115,10 +115,14 @@ initializing a new crypted remote directory." ;; This function takes action since Emacs 28.1, when ;; `read-extended-command-predicate' is set to ;; `command-completion-default-include-p'. -(defun tramp-crypt-enabled-p (_symbol _buffer) +(defun tramp-crypt-command-completion-p (symbol _buffer) "A predicate for Tramp interactive commands. They are completed by \"M-x TAB\" only when encryption support is enabled." - tramp-crypt-enabled) + (and tramp-crypt-enabled + ;; `tramp-crypt-remove-directory' needs to be completed only in + ;; case we have already crypted directories. + (or (not (eq symbol #'tramp-crypt-remove-directory)) + tramp-crypt-directories))) ;;;###tramp-autoload (defconst tramp-crypt-encfs-config ".encfs6.xml" @@ -489,15 +493,17 @@ directory. File names will be also encrypted." (setq tramp-crypt-directories (cons name tramp-crypt-directories))) (tramp-register-file-name-handlers)) -;; `tramp-crypt-enabled-p' is not autoloaded, and this setting isn't either. +;; `tramp-crypt-command-completion-p' is not autoloaded, and this +;; setting isn't either. (function-put - #'tramp-crypt-add-directory 'completion-predicate #'tramp-crypt-enabled-p) + #'tramp-crypt-add-directory 'completion-predicate + #'tramp-crypt-command-completion-p) (defun tramp-crypt-remove-directory (name) "Unmark remote directory NAME for encryption. Existing files in that directory and its subdirectories will be kept in their encrypted form." - ;; (declare (completion tramp-crypt-enabled-p)) + ;; (declare (completion tramp-crypt-command-completion-p)) (interactive "DRemote directory name: ") (unless tramp-crypt-enabled (tramp-user-error nil "Feature is not enabled.")) @@ -513,7 +519,8 @@ kept in their encrypted form." ;; Starting with Emacs 28.1, this can be replaced by the "(declare ...)" form. (function-put - #'tramp-crypt-remove-directory 'completion-predicate #'tramp-crypt-enabled-p) + #'tramp-crypt-remove-directory 'completion-predicate + #'tramp-crypt-command-completion-p) ;; `auth-source' requires a user. (defun tramp-crypt-dissect-file-name (name) commit f2b0cfff93afeeb1b6d84bfce4bde83dbe4862cb Author: Stefan Kangas Date: Mon Mar 15 09:16:47 2021 +0100 ; Silence byte-compiler after previous commit diff --git a/lisp/textmodes/refill.el b/lisp/textmodes/refill.el index 83bd7b7ade..a6400c738a 100644 --- a/lisp/textmodes/refill.el +++ b/lisp/textmodes/refill.el @@ -87,7 +87,7 @@ "Portion of the most recently filled paragraph not needing filling. This is used to optimize refilling.") -(defun refill-adjust-ignorable-overlay (overlay afterp beg end &optional len) +(defun refill-adjust-ignorable-overlay (overlay afterp beg _end &optional _len) "Adjust OVERLAY to not include the about-to-be-modified region." (when (not afterp) (save-excursion @@ -152,7 +152,7 @@ ensures refilling is only done once per command that causes a change, regardless of the number of after-change calls from commands doing complex processing.") -(defun refill-after-change-function (beg end len) +(defun refill-after-change-function (_beg end _len) "Function for `after-change-functions' which just sets `refill-doit'." (unless undo-in-progress (setq refill-doit end))) commit b8b8890796e731180afb4f286addcda10263baf2 Author: Stefan Kangas Date: Mon Mar 15 09:15:29 2021 +0100 * lisp/textmodes/refill.el: Use lexical-binding. diff --git a/lisp/textmodes/refill.el b/lisp/textmodes/refill.el index 8f4f3c5a23..83bd7b7ade 100644 --- a/lisp/textmodes/refill.el +++ b/lisp/textmodes/refill.el @@ -1,4 +1,4 @@ -;;; refill.el --- `auto-fill' by refilling paragraphs on changes +;;; refill.el --- `auto-fill' by refilling paragraphs on changes -*- lexical-binding: t -*- ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. @@ -83,11 +83,6 @@ ;;; Code: -;; Unused. -;;; (defgroup refill nil -;;; "Refilling paragraphs on changes." -;;; :group 'fill) - (defvar-local refill-ignorable-overlay nil "Portion of the most recently filled paragraph not needing filling. This is used to optimize refilling.") commit 371fdd4f1be51b6a2babe21e3655e99401246c4c Author: Stefan Monnier Date: Mon Mar 15 00:08:34 2021 -0400 * lisp/cedet: Convert remaining files to lexical-binding Remove a few more redundant `:group` args. Make use of lexical scoping to replace `(lambda...) with proper closures. * lisp/cedet/ede/custom.el (ede-project-sort-targets-list): Use `dotimes` and replace `(lambda..) with closures. * lisp/cedet/ede/proj-comp.el (proj-comp-insert-variable-once): * lisp/cedet/ede/pmake.el (ede-pmake-insert-variable-once): Remove unused var `addcr`. * lisp/cedet/semantic/complete.el: Use lexical-binding. (semantic-displayer-show-request): Remove unused var `typing-count`. Use `equal` instead of `stringp+string=`. * lisp/cedet/semantic/db-ebrowse.el: Use lexical-binding. (semanticdb-create-ebrowse-database): Remove unused vars `mma` and `regexp`. (semanticdb-ebrowse-strip-trees): Remove unused var `class` and `filename`. (semanticdb-ebrowse-add-globals-to-table): Remove unused var `fname`. * lisp/cedet/semantic/db-find.el: Use lexical-binding. (semanticdb-find-adebug-insert-scanned-tag-cons): Remove always-nil var `tip`. * lisp/cedet/semantic/db-global.el: Use lexical-binding. (semanticdb-enable-gnu-global-databases): Access local var `semantic--ih` by sticking its value in the code passed to `eval` rather than by dynamic scoping. * lisp/cedet/semantic/db-typecache.el: Use lexical-binding. (semanticdb-db-typecache-dump): Remove unused var `junk`. * lisp/cedet/semantic/debug.el: Use lexical-binding. * lisp/cedet/semantic/dep.el: Use lexical-binding. (semantic-add-system-include): Avoid `add-to-list` on a local variable. Access local var `value` by sticking its value in the code passed to `eval` rather than by dynamic scoping. (semantic-remove-system-include): Don't use `delete` on a list received from elsewhere. Access local var `value` by sticking its value in the code passed to `eval` rather than by dynamic scoping. (semantic-reset-system-include): Simplify a bit. * lisp/cedet/semantic/ede-grammar.el: Use lexical-binding. (project-compile-target): Remove unused vars `csrc` and `cb`. Use `cl-incf`. Remove apparently unneeded `with-no-warnings`. * lisp/cedet/semantic/edit.el: Use lexical-binding. (semantic-edits-change-over-tags): Remove unused var `inner-start`. (semantic-edits-incremental-parser-1): Silence warnings about intentionally unused var `last-cond`. * lisp/cedet/semantic/fw.el: Use lexical-binding. (recentf-exclude, semantic-init-hook, ede-auto-add-method) (flymake-start-syntax-check-on-find-file, auto-insert): Declare vars. * lisp/cedet/semantic/ia-sb.el: Use lexical-binding. (semantic-ia-sb-key-map): Move initialization into declaration. (semantic-ia-sb-more-buttons): Remove unused var `idx`. (semantic-ia-sb-line-path): Simplify `if` -> `or`. * lisp/cedet/semantic/idle.el (semantic-idle-breadcrumbs--tag-function): Make it a function returning a closure. * lisp/cedet/semantic/senator.el: Use lexical-binding. (senator-search-set-tag-class-filter): Replace `(lambda..) with a closure. * lisp/cedet/semantic/sort.el: Use lexical-binding. (semanticdb-search-system-databases): Declare var. (semantic-tag-external-member-children-default): Replace `(lambda..) with a closure. * lisp/cedet/semantic/tag-ls.el: Use lexical-binding. (semantic-tag-protection-default, semantic-tag-abstract-p-default): Simplify with `member`. * lisp/cedet/semantic/util.el: Use lexical-binding. (semantic-something-to-tag-table): Declare function `semanticdb-abstract-table--eieio-childp` called via `cl-typep`. * lisp/cedet/semantic/bovine/scm.el (semantic-default-scheme-setup): Remove duplicate setting of `imenu-create-index-function`. * lisp/cedet/semantic/decorate/mode.el (semantic-decoration-build-style-menu): Replace `(lambda..) with a closure. * lisp/cedet/srecode/cpp.el (srecode-semantic-apply-tag-to-dict): Remove always-t variable `member`. * lisp/cedet/srecode/mode.el (srecode-minor-mode-templates-menu): Replace `(lambda..) with a closure. Use `push`. * lisp/cedet/semantic/chart.el: Use lexical-binding. * lisp/cedet/semantic/db-debug.el: Use lexical-binding. * lisp/cedet/semantic/db-el.el: Use lexical-binding. * lisp/cedet/semantic/db-file.el: Use lexical-binding. * lisp/cedet/semantic/db-javascript.el: Use lexical-binding. * lisp/cedet/semantic/db-mode.el: Use lexical-binding. * lisp/cedet/semantic/db-ref.el: Use lexical-binding. * lisp/cedet/semantic/decorate.el: Use lexical-binding. * lisp/cedet/semantic/doc.el: Use lexical-binding. * lisp/cedet/semantic/find.el: Use lexical-binding. * lisp/cedet/semantic/format.el: Use lexical-binding. * lisp/cedet/semantic/html.el: Use lexical-binding. * lisp/cedet/semantic/ia.el: Use lexical-binding. * lisp/cedet/semantic/imenu.el: Use lexical-binding. * lisp/cedet/semantic/java.el: Use lexical-binding. * lisp/cedet/semantic/mru-bookmark.el: Use lexical-binding. * lisp/cedet/semantic/symref.el: Use lexical-binding. * lisp/cedet/semantic/tag-file.el: Use lexical-binding. * lisp/cedet/semantic/tag-write.el: Use lexical-binding. * lisp/cedet/semantic/texi.el: Use lexical-binding. * lisp/cedet/semantic/util-modes.el: Use lexical-binding. diff --git a/lisp/cedet/cedet-cscope.el b/lisp/cedet/cedet-cscope.el index 95f04541c8..6ffc2765d6 100644 --- a/lisp/cedet/cedet-cscope.el +++ b/lisp/cedet/cedet-cscope.el @@ -1,6 +1,6 @@ ;;; cedet-cscope.el --- CScope support for CEDET -*- lexical-binding: t; -*- -;;; Copyright (C) 2009-2021 Free Software Foundation, Inc. +;; Copyright (C) 2009-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Package: cedet diff --git a/lisp/cedet/ede/custom.el b/lisp/cedet/ede/custom.el index adb1a49cdf..ac4f9f6684 100644 --- a/lisp/cedet/ede/custom.el +++ b/lisp/cedet/ede/custom.el @@ -133,47 +133,45 @@ OBJ is the target object to customize." (defun ede-project-sort-targets-list () "Sort the target list while using `ede-project-sort-targets'." (save-excursion - (let ((count 0) - (targets (oref ede-object-project targets)) + (let ((targets (oref ede-object-project targets)) (inhibit-read-only t) (inhibit-modification-hooks t)) (goto-char (point-min)) (forward-line 2) (delete-region (point) (point-max)) - (while (< count (length targets)) + (dotimes (count (length targets)) (if (> count 0) (widget-create 'push-button - :notify `(lambda (&rest ignore) - (let ((cur ede-project-sort-targets-order)) - (add-to-ordered-list - 'ede-project-sort-targets-order - (nth ,count cur) - (1- ,count)) - (add-to-ordered-list - 'ede-project-sort-targets-order - (nth (1- ,count) cur) ,count)) - (ede-project-sort-targets-list)) + :notify (lambda (&rest _ignore) + (let ((cur ede-project-sort-targets-order)) + (add-to-ordered-list + 'ede-project-sort-targets-order + (nth count cur) + (1- count)) + (add-to-ordered-list + 'ede-project-sort-targets-order + (nth (1- count) cur) count)) + (ede-project-sort-targets-list)) " Up ") (widget-insert " ")) (if (< count (1- (length targets))) (widget-create 'push-button - :notify `(lambda (&rest ignore) - (let ((cur ede-project-sort-targets-order)) - (add-to-ordered-list - 'ede-project-sort-targets-order - (nth ,count cur) (1+ ,count)) - (add-to-ordered-list - 'ede-project-sort-targets-order - (nth (1+ ,count) cur) ,count)) - (ede-project-sort-targets-list)) + :notify (lambda (&rest _ignore) + (let ((cur ede-project-sort-targets-order)) + (add-to-ordered-list + 'ede-project-sort-targets-order + (nth count cur) (1+ count)) + (add-to-ordered-list + 'ede-project-sort-targets-order + (nth (1+ count) cur) count)) + (ede-project-sort-targets-list)) " Down ") (widget-insert " ")) (widget-insert (concat " " (number-to-string (1+ count)) ".: " (oref (nth (nth count ede-project-sort-targets-order) targets) name) - "\n")) - (setq count (1+ count)))))) + "\n")))))) ;;; Customization hooks ;; diff --git a/lisp/cedet/ede/make.el b/lisp/cedet/ede/make.el index d9811ce52f..3402020fc4 100644 --- a/lisp/cedet/ede/make.el +++ b/lisp/cedet/ede/make.el @@ -1,6 +1,6 @@ ;;; ede/make.el --- General information about "make" -*- lexical-binding: t -*- -;;; Copyright (C) 2009-2021 Free Software Foundation, Inc. +;; Copyright (C) 2009-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam diff --git a/lisp/cedet/ede/pconf.el b/lisp/cedet/ede/pconf.el index 106ba2cf5b..c5b2ea4cb6 100644 --- a/lisp/cedet/ede/pconf.el +++ b/lisp/cedet/ede/pconf.el @@ -1,7 +1,6 @@ ;;; ede/pconf.el --- configure.ac maintenance for EDE -*- lexical-binding: t; -*- -;;; Copyright (C) 1998-2000, 2005, 2008-2021 Free Software Foundation, -;;; Inc. +;; Copyright (C) 1998-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: project diff --git a/lisp/cedet/ede/pmake.el b/lisp/cedet/ede/pmake.el index ceb44031f6..fd6918c4e8 100644 --- a/lisp/cedet/ede/pmake.el +++ b/lisp/cedet/ede/pmake.el @@ -266,14 +266,14 @@ Execute BODY in a location where a value can be placed." "Add VARNAME into the current Makefile if it doesn't exist. Execute BODY in a location where a value can be placed." (declare (debug t) (indent 1)) - `(let ((addcr t) (v ,varname)) - (unless - (save-excursion - (re-search-backward (concat "^" v "\\s-*=") nil t)) - (insert v "=") - ,@body - (when addcr (insert "\n")) - (goto-char (point-max))))) + `(let ((v ,varname)) + (unless + (save-excursion + (re-search-backward (concat "^" v "\\s-*=") nil t)) + (insert v "=") + ,@body + (insert "\n") + (goto-char (point-max))))) ;;; SOURCE VARIABLE NAME CONSTRUCTION diff --git a/lisp/cedet/ede/proj-comp.el b/lisp/cedet/ede/proj-comp.el index 1d6a4eb47c..0d797aa5fb 100644 --- a/lisp/cedet/ede/proj-comp.el +++ b/lisp/cedet/ede/proj-comp.el @@ -249,13 +249,12 @@ This will prevent rules from creating duplicate variables or rules." "Add VARNAME into the current Makefile if it doesn't exist. Execute BODY in a location where a value can be placed." (declare (indent 1) (debug (sexp body))) - `(let ((addcr t) (v ,varname)) + `(let ((v ,varname)) (unless (re-search-backward (concat "^" v "\\s-*=") nil t) (insert v "=") ,@body - (if addcr (insert "\n")) - (goto-char (point-max))) - )) + (insert "\n") + (goto-char (point-max))))) (cl-defmethod ede-proj-makefile-insert-variables ((this ede-compilation-program)) "Insert variables needed by the compiler THIS." diff --git a/lisp/cedet/ede/proj-info.el b/lisp/cedet/ede/proj-info.el index 11e0f302e2..dbb86edb21 100644 --- a/lisp/cedet/ede/proj-info.el +++ b/lisp/cedet/ede/proj-info.el @@ -1,7 +1,6 @@ ;;; ede-proj-info.el --- EDE Generic Project texinfo support -*- lexical-binding: t; -*- -;;; Copyright (C) 1998-2001, 2004, 2007-2021 Free Software Foundation, -;;; Inc. +;; Copyright (C) 1998-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: project, make diff --git a/lisp/cedet/ede/proj-obj.el b/lisp/cedet/ede/proj-obj.el index 72d09167ab..2ae62f4b38 100644 --- a/lisp/cedet/ede/proj-obj.el +++ b/lisp/cedet/ede/proj-obj.el @@ -1,7 +1,6 @@ ;;; ede/proj-obj.el --- EDE Generic Project Object code generation support -*- lexical-binding: t; -*- -;;; Copyright (C) 1998-2000, 2005, 2008-2021 Free Software Foundation, -;;; Inc. +;; Copyright (C) 1998-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: project, make diff --git a/lisp/cedet/ede/proj-shared.el b/lisp/cedet/ede/proj-shared.el index 8688d15174..01f19bc657 100644 --- a/lisp/cedet/ede/proj-shared.el +++ b/lisp/cedet/ede/proj-shared.el @@ -1,6 +1,6 @@ ;;; ede-proj-shared.el --- EDE Generic Project shared library support -*- lexical-binding: t; -*- -;;; Copyright (C) 1998-2000, 2009-2021 Free Software Foundation, Inc. +;; Copyright (C) 1998-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: project, make diff --git a/lisp/cedet/semantic/analyze/debug.el b/lisp/cedet/semantic/analyze/debug.el index 58d6644f9a..69b3b9c832 100644 --- a/lisp/cedet/semantic/analyze/debug.el +++ b/lisp/cedet/semantic/analyze/debug.el @@ -1,6 +1,6 @@ ;;; semantic/analyze/debug.el --- Debug the analyzer -*- lexical-binding: t; -*- -;;; Copyright (C) 2008-2021 Free Software Foundation, Inc. +;; Copyright (C) 2008-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -593,19 +593,20 @@ Look for key expressions, and add push-buttons near them." (setq-local semantic-analyzer-debug-orig orig-buffer) ;; First, add do-in buttons to recommendations. (while (re-search-forward "^\\s-*M-x \\(\\(\\w\\|\\s_\\)+\\) " nil t) - (let ((fcn (match-string 1))) - (when (not (fboundp (intern-soft fcn))) + (let* ((fcn (match-string 1)) + (fsym (intern-soft fcn))) + (when (not (fboundp fsym)) (error "Help Err: Can't find %s" fcn)) (end-of-line) (insert " ") (insert-button "[ Do It ]" 'mouse-face 'custom-button-pressed-face 'do-fcn fcn - 'action `(lambda (arg) - (let ((M semantic-analyzer-debug-orig)) - (set-buffer (marker-buffer M)) - (goto-char M)) - (call-interactively (quote ,(intern-soft fcn)))))))) + 'action (lambda (_arg) + (let ((M semantic-analyzer-debug-orig)) + (set-buffer (marker-buffer M)) + (goto-char M)) + (call-interactively fsym)))))) ;; Do something else? ;; Clean up the mess (set-buffer-modified-p nil)))) diff --git a/lisp/cedet/semantic/bovine/make.el b/lisp/cedet/semantic/bovine/make.el index 2c9b78f9dd..bb579cfde3 100644 --- a/lisp/cedet/semantic/bovine/make.el +++ b/lisp/cedet/semantic/bovine/make.el @@ -218,7 +218,7 @@ Uses default implementation, and also gets a list of filenames." ;; but not actually parsed. (file . "File")) semantic-case-fold t - semantic-tag-expand-function 'semantic-make-expand-tag + semantic-tag-expand-function #'semantic-make-expand-tag semantic-lex-syntax-modifications '((?. "_") (?= ".") (?/ "_") @@ -226,7 +226,7 @@ Uses default implementation, and also gets a list of filenames." (?+ ".") (?\\ ".") ) - imenu-create-index-function 'semantic-create-imenu-index + imenu-create-index-function #'semantic-create-imenu-index ) (setq semantic-lex-analyzer #'semantic-make-lexer) ) diff --git a/lisp/cedet/semantic/bovine/scm.el b/lisp/cedet/semantic/bovine/scm.el index 939348ef4a..0395412069 100644 --- a/lisp/cedet/semantic/bovine/scm.el +++ b/lisp/cedet/semantic/bovine/scm.el @@ -1,6 +1,6 @@ ;;; semantic/bovine/scm.el --- Semantic details for Scheme (guile) -*- lexical-binding: t; -*- -;;; Copyright (C) 2001-2004, 2008-2021 Free Software Foundation, Inc. +;; Copyright (C) 2001-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -102,8 +102,7 @@ syntax as specified by the syntax table." (function . "Functions") (include . "Loads") (package . "DefineModule")) - imenu-create-index-function 'semantic-create-imenu-index - imenu-create-index-function 'semantic-create-imenu-index + imenu-create-index-function #'semantic-create-imenu-index ) (setq semantic-lex-analyzer #'semantic-scheme-lexer) ) diff --git a/lisp/cedet/semantic/chart.el b/lisp/cedet/semantic/chart.el index e7848faf74..0abbe45864 100644 --- a/lisp/cedet/semantic/chart.el +++ b/lisp/cedet/semantic/chart.el @@ -1,4 +1,4 @@ -;;; semantic/chart.el --- Utilities for use with semantic tag tables +;;; semantic/chart.el --- Utilities for use with semantic tag tables -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2001, 2003, 2005, 2008-2021 Free Software ;; Foundation, Inc. @@ -43,7 +43,7 @@ TAGTABLE is passed to `semantic-something-to-tag-table'." (interactive) (let* ((stream (semantic-something-to-tag-table (or tagtable (current-buffer)))) - (names (mapcar 'cdr semantic-symbol->name-assoc-list)) + (names (mapcar #'cdr semantic-symbol->name-assoc-list)) (nums (mapcar (lambda (symname) (length @@ -57,7 +57,7 @@ TAGTABLE is passed to `semantic-something-to-tag-table'." nums "Volume") )) -(defun semantic-chart-database-size (&optional tagtable) +(defun semantic-chart-database-size (&optional _tagtable) "Create a bar chart representing the size of each file in semanticdb. Each bar represents how many toplevel tags in TAGTABLE exist in each database entry. @@ -68,7 +68,7 @@ TAGTABLE is passed to `semantic-something-to-tag-table'." (error "Semanticdb is not enabled")) (let* ((db semanticdb-current-database) (dbt (semanticdb-get-database-tables db)) - (names (mapcar 'car + (names (mapcar #'car (object-assoc-list 'file dbt))) @@ -84,8 +84,8 @@ TAGTABLE is passed to `semantic-something-to-tag-table'." (nums nil) (fh (/ (- (frame-height) 7) 4))) (setq numnuts (sort numnuts (lambda (a b) (> (car a) (car b))))) - (setq names (mapcar 'cdr numnuts) - nums (mapcar 'car numnuts)) + (setq names (mapcar #'cdr numnuts) + nums (mapcar #'car numnuts)) (if (> (length names) fh) (progn (setcdr (nthcdr fh names) nil) diff --git a/lisp/cedet/semantic/complete.el b/lisp/cedet/semantic/complete.el index c83505818f..d6ef796047 100644 --- a/lisp/cedet/semantic/complete.el +++ b/lisp/cedet/semantic/complete.el @@ -1,4 +1,4 @@ -;;; semantic/complete.el --- Routines for performing tag completion +;;; semantic/complete.el --- Routines for performing tag completion -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2005, 2007-2021 Free Software Foundation, Inc. @@ -154,8 +154,8 @@ Presumably if you call this you will insert something new there." (defun semantic-completion-message (fmt &rest args) "Display the string FMT formatted with ARGS at the end of the minibuffer." (if semantic-complete-inline-overlay - (apply 'message fmt args) - (apply 'message (concat "%s" fmt) (buffer-string) args))) + (apply #'message fmt args) + (apply #'message (concat "%s" fmt) (buffer-string) args))) ;;; ------------------------------------------------------------ ;;; MINIBUFFER: Option Selection harnesses @@ -171,14 +171,14 @@ Value should be a ... what?") (defvar semantic-complete-key-map (let ((km (make-sparse-keymap))) - (define-key km " " 'semantic-complete-complete-space) - (define-key km "\t" 'semantic-complete-complete-tab) - (define-key km "\C-m" 'semantic-complete-done) - (define-key km "\C-g" 'abort-recursive-edit) - (define-key km "\M-n" 'next-history-element) - (define-key km "\M-p" 'previous-history-element) - (define-key km "\C-n" 'next-history-element) - (define-key km "\C-p" 'previous-history-element) + (define-key km " " #'semantic-complete-complete-space) + (define-key km "\t" #'semantic-complete-complete-tab) + (define-key km "\C-m" #'semantic-complete-done) + (define-key km "\C-g" #'abort-recursive-edit) + (define-key km "\M-n" #'next-history-element) + (define-key km "\M-p" #'previous-history-element) + (define-key km "\C-n" #'next-history-element) + (define-key km "\C-p" #'previous-history-element) ;; Add history navigation km) "Keymap used while completing across a list of tags.") @@ -488,7 +488,7 @@ If PARTIAL, do partial completion stopping at spaces." ) (t nil)))) -(defun semantic-complete-do-completion (&optional partial inline) +(defun semantic-complete-do-completion (&optional partial _inline) "Do a completion for the current minibuffer. If PARTIAL, do partial completion stopping at spaces. if INLINE, then completion is happening inline in a buffer." @@ -550,12 +550,12 @@ if INLINE, then completion is happening inline in a buffer." ;; push ourselves out of this mode on alternate keypresses. (defvar semantic-complete-inline-map (let ((km (make-sparse-keymap))) - (define-key km "\C-i" 'semantic-complete-inline-TAB) - (define-key km "\M-p" 'semantic-complete-inline-up) - (define-key km "\M-n" 'semantic-complete-inline-down) - (define-key km "\C-m" 'semantic-complete-inline-done) - (define-key km "\C-\M-c" 'semantic-complete-inline-exit) - (define-key km "\C-g" 'semantic-complete-inline-quit) + (define-key km "\C-i" #'semantic-complete-inline-TAB) + (define-key km "\M-p" #'semantic-complete-inline-up) + (define-key km "\M-n" #'semantic-complete-inline-down) + (define-key km "\C-m" #'semantic-complete-inline-done) + (define-key km "\C-\M-c" #'semantic-complete-inline-exit) + (define-key km "\C-g" #'semantic-complete-inline-quit) (define-key km "?" (lambda () (interactive) (describe-variable 'semantic-complete-inline-map))) @@ -620,7 +620,7 @@ Similar to `minibuffer-contents' when completing in the minibuffer." "Exit inline completion mode." (interactive) ;; Remove this hook FIRST! - (remove-hook 'pre-command-hook 'semantic-complete-pre-command-hook) + (remove-hook 'pre-command-hook #'semantic-complete-pre-command-hook) (condition-case nil (progn @@ -649,7 +649,7 @@ Similar to `minibuffer-contents' when completing in the minibuffer." ;; Remove this hook LAST!!! ;; This will force us back through this function if there was ;; some sort of error above. - (remove-hook 'post-command-hook 'semantic-complete-post-command-hook) + (remove-hook 'post-command-hook #'semantic-complete-post-command-hook) ;;(message "Exiting inline completion.") ) @@ -770,8 +770,8 @@ END is at the end of the current symbol being completed." (overlay-put semantic-complete-inline-overlay 'semantic-original-start start) ;; Install our command hooks - (add-hook 'pre-command-hook 'semantic-complete-pre-command-hook) - (add-hook 'post-command-hook 'semantic-complete-post-command-hook) + (add-hook 'pre-command-hook #'semantic-complete-pre-command-hook) + (add-hook 'post-command-hook #'semantic-complete-post-command-hook) ;; Go! (semantic-complete-inline-force-display) ) @@ -929,8 +929,8 @@ The only options available for completion are those which can be logically inserted into the current context.") (cl-defmethod semantic-collector-calculate-completions-raw - ((obj semantic-collector-analyze-completions) prefix completionlist) - "calculate the completions for prefix from completionlist." + ((obj semantic-collector-analyze-completions) prefix _completionlist) + "calculate the completions for prefix from COMPLETIONLIST." ;; if there are no completions yet, calculate them. (if (not (slot-boundp obj 'first-pass-completions)) (oset obj first-pass-completions @@ -943,7 +943,7 @@ inserted into the current context.") prefix (oref obj first-pass-completions))))) -(cl-defmethod semantic-collector-cleanup ((obj semantic-collector-abstract)) +(cl-defmethod semantic-collector-cleanup ((_obj semantic-collector-abstract)) "Clean up any mess this collector may have." nil) @@ -1004,7 +1004,7 @@ Output must be in semanticdb Find result format." (list (cons table result))))) (cl-defmethod semantic-collector-calculate-completions - ((obj semantic-collector-abstract) prefix partial) + ((obj semantic-collector-abstract) prefix _partial) "Calculate completions for prefix as setup for other queries." (let* ((case-fold-search semantic-case-fold) (same-prefix-p (semantic-collector-last-prefix= obj prefix)) @@ -1014,7 +1014,8 @@ Output must be in semanticdb Find result format." (cond ((or same-prefix-p (and last-prefix (eq (compare-strings last-prefix 0 nil - prefix 0 (length last-prefix)) t))) + prefix 0 (length last-prefix)) + t))) ;; We have the same prefix, or last-prefix is a ;; substring of the of new prefix, in which case we are ;; refining our symbol so just re-use cache. @@ -1023,7 +1024,8 @@ Output must be in semanticdb Find result format." (> (length prefix) 1) (eq (compare-strings prefix 0 nil - last-prefix 0 (length prefix)) t)) + last-prefix 0 (length prefix)) + t)) ;; The new prefix is a substring of the old ;; prefix, and it's longer than one character. ;; Perform a full search to pull in additional @@ -1134,7 +1136,7 @@ into a buffer." (semanticdb-find-result-nth-in-buffer (oref obj current-exact-match) 0))) (cl-defmethod semantic-collector-all-completions - ((obj semantic-collector-abstract) prefix) + ((obj semantic-collector-abstract) _prefix) "For OBJ, retrieve all completions matching PREFIX. The returned list consists of all the tags currently matching PREFIX." @@ -1142,7 +1144,7 @@ matching PREFIX." (oref obj last-all-completions))) (cl-defmethod semantic-collector-try-completion - ((obj semantic-collector-abstract) prefix) + ((obj semantic-collector-abstract) _prefix) "For OBJ, attempt to match PREFIX. See `try-completion' for details on how this works. Return nil for no match. @@ -1153,7 +1155,7 @@ with that name." (oref obj last-completion))) (cl-defmethod semantic-collector-calculate-cache - ((obj semantic-collector-abstract)) + ((_obj semantic-collector-abstract)) "Calculate the completion cache for OBJ." nil ) @@ -1176,7 +1178,7 @@ These collectors track themselves on a per-buffer basis." :abstract t) (cl-defmethod make-instance ((this (subclass semantic-collector-buffer-abstract)) - &rest args) + &rest _args) "Reuse previously created objects of this type in buffer." (let ((old nil) (bl semantic-collector-per-buffer-list)) @@ -1193,7 +1195,7 @@ These collectors track themselves on a per-buffer basis." old)) ;; Buffer specific collectors should flush themselves -(defun semantic-collector-buffer-flush (newcache) +(defun semantic-collector-buffer-flush (_newcache) "Flush all buffer collector objects. NEWCACHE is the new tag table, but we ignore it." (condition-case nil @@ -1204,7 +1206,7 @@ NEWCACHE is the new tag table, but we ignore it." (error nil))) (add-hook 'semantic-after-toplevel-cache-change-hook - 'semantic-collector-buffer-flush) + #'semantic-collector-buffer-flush) ;;; DEEP BUFFER SPECIFIC COMPLETION ;; @@ -1246,8 +1248,8 @@ Uses semanticdb for searching all tags in the current project." (cl-defmethod semantic-collector-calculate-completions-raw - ((obj semantic-collector-project) prefix completionlist) - "Calculate the completions for prefix from completionlist." + ((obj semantic-collector-project) prefix _completionlist) + "Calculate the completions for prefix from COMPLETIONLIST." (semanticdb-find-tags-for-completion prefix (oref obj path))) ;;; Brutish Project search @@ -1259,8 +1261,8 @@ Uses semanticdb for searching all tags in the current project." "semantic/db-find") (cl-defmethod semantic-collector-calculate-completions-raw - ((obj semantic-collector-project-brutish) prefix completionlist) - "Calculate the completions for prefix from completionlist." + ((obj semantic-collector-project-brutish) prefix _completionlist) + "Calculate the completions for prefix from COMPLETIONLIST." (require 'semantic/db-find) (semanticdb-brute-deep-find-tags-for-completion prefix (oref obj path))) @@ -1273,8 +1275,8 @@ Uses semanticdb for searching all tags in the current project." "Completion engine for tags in a project.") (cl-defmethod semantic-collector-calculate-completions-raw - ((obj semantic-collector-local-members) prefix completionlist) - "Calculate the completions for prefix from completionlist." + ((obj semantic-collector-local-members) prefix _completionlist) + "Calculate the completions for prefix from COMPLETIONLIST." (let* ((scope (or (oref obj scope) (oset obj scope (semantic-calculate-scope)))) (localstuff (oref scope scope))) @@ -1323,7 +1325,7 @@ a collector, and tracking tables of completion to display." (define-obsolete-function-alias 'semantic-displayor-cleanup #'semantic-displayer-cleanup "27.1") -(cl-defmethod semantic-displayer-cleanup ((obj semantic-displayer-abstract)) +(cl-defmethod semantic-displayer-cleanup ((_obj semantic-displayer-abstract)) "Clean up any mess this displayer may have." nil) @@ -1348,37 +1350,37 @@ a collector, and tracking tables of completion to display." (define-obsolete-function-alias 'semantic-displayor-show-request #'semantic-displayer-show-request "27.1") -(cl-defmethod semantic-displayer-show-request ((obj semantic-displayer-abstract)) +(cl-defmethod semantic-displayer-show-request ((_obj semantic-displayer-abstract)) "A request to show the current tags table." (ding)) (define-obsolete-function-alias 'semantic-displayor-focus-request #'semantic-displayer-focus-request "27.1") -(cl-defmethod semantic-displayer-focus-request ((obj semantic-displayer-abstract)) +(cl-defmethod semantic-displayer-focus-request ((_obj semantic-displayer-abstract)) "A request to for the displayer to focus on some tag option." (ding)) (define-obsolete-function-alias 'semantic-displayor-scroll-request #'semantic-displayer-scroll-request "27.1") -(cl-defmethod semantic-displayer-scroll-request ((obj semantic-displayer-abstract)) +(cl-defmethod semantic-displayer-scroll-request ((_obj semantic-displayer-abstract)) "A request to for the displayer to scroll the completion list (if needed)." (scroll-other-window)) (define-obsolete-function-alias 'semantic-displayor-focus-previous #'semantic-displayer-focus-previous "27.1") -(cl-defmethod semantic-displayer-focus-previous ((obj semantic-displayer-abstract)) +(cl-defmethod semantic-displayer-focus-previous ((_obj semantic-displayer-abstract)) "Set the current focus to the previous item." nil) (define-obsolete-function-alias 'semantic-displayor-focus-next #'semantic-displayer-focus-next "27.1") -(cl-defmethod semantic-displayer-focus-next ((obj semantic-displayer-abstract)) +(cl-defmethod semantic-displayer-focus-next ((_obj semantic-displayer-abstract)) "Set the current focus to the next item." nil) (define-obsolete-function-alias 'semantic-displayor-current-focus #'semantic-displayer-current-focus "27.1") -(cl-defmethod semantic-displayer-current-focus ((obj semantic-displayer-abstract)) +(cl-defmethod semantic-displayer-current-focus ((_obj semantic-displayer-abstract)) "Return a single tag currently in focus. This object type doesn't do focus, so will never have a focus object." nil) @@ -1452,7 +1454,7 @@ which have the same name." (define-obsolete-function-alias 'semantic-displayor-set-completions #'semantic-displayer-set-completions "27.1") (cl-defmethod semantic-displayer-set-completions ((obj semantic-displayer-focus-abstract) - table prefix) + _table _prefix) "Set the list of tags to be completed over to TABLE." (cl-call-next-method) (slot-makeunbound obj 'focus)) @@ -1663,7 +1665,7 @@ This will not happen if you directly set this variable via `setq'." "Display completions options in a tooltip. Display mechanism using tooltip for a list of possible completions.") -(cl-defmethod initialize-instance :after ((obj semantic-displayer-tooltip) &rest args) +(cl-defmethod initialize-instance :after ((_obj semantic-displayer-tooltip) &rest _args) "Make sure we have tooltips required." (require 'tooltip)) @@ -1681,16 +1683,16 @@ Display mechanism using tooltip for a list of possible completions.") (table (semantic-unique-tag-table-by-name tablelong)) (completions (mapcar semantic-completion-displayer-format-tag-function table)) (numcompl (length completions)) - (typing-count (oref obj typing-count)) + ;; (typing-count (oref obj typing-count)) (mode (oref obj mode)) (max-tags (oref obj max-tags-initial)) (matchtxt (semantic-completion-text)) msg msg-tail) ;; Keep a count of the consecutive completion commands entered by the user. - (if (and (stringp (this-command-keys)) - (string= (this-command-keys) "\C-i")) - (oset obj typing-count (1+ (oref obj typing-count))) - (oset obj typing-count 0)) + (oset obj typing-count + (if (equal (this-command-keys) "\C-i") + (1+ (oref obj typing-count)) + 0)) (cond ((eq mode 'quiet) ;; Switch back to standard mode if user presses key more than 5 times. @@ -1730,7 +1732,7 @@ Display mechanism using tooltip for a list of possible completions.") (when semantic-idle-scheduler-verbose-flag (setq msg "[NO MATCH]")))) ;; Create the tooltip text. - (setq msg (concat msg (mapconcat 'identity completions "\n")))) + (setq msg (concat msg (mapconcat #'identity completions "\n")))) ;; Add any tail info. (setq msg (concat msg msg-tail)) ;; Display tooltip. @@ -1828,12 +1830,10 @@ text using overlay options.") (define-obsolete-function-alias 'semantic-displayor-set-completions #'semantic-displayer-set-completions "27.1") (cl-defmethod semantic-displayer-set-completions ((obj semantic-displayer-ghost) - table prefix) + _table _prefix) "Set the list of tags to be completed over to TABLE." (cl-call-next-method) - - (semantic-displayer-cleanup obj) - ) + (semantic-displayer-cleanup obj)) (define-obsolete-function-alias 'semantic-displayor-show-request @@ -2058,9 +2058,8 @@ prompts. these are calculated from the CONTEXT variable passed in." (semantic-displayer-traditional-with-focus-highlight) (with-current-buffer (oref context buffer) (goto-char (cdr (oref context bounds))) - (concat prompt (mapconcat 'identity syms ".") - (if syms "." "") - )) + (concat prompt (mapconcat #'identity syms ".") + (if syms "." ""))) nil inp history))) diff --git a/lisp/cedet/semantic/db-debug.el b/lisp/cedet/semantic/db-debug.el index c553ab499a..d8f7034f03 100644 --- a/lisp/cedet/semantic/db-debug.el +++ b/lisp/cedet/semantic/db-debug.el @@ -1,6 +1,6 @@ -;;; semantic/db-debug.el --- Extra level debugging routines for Semantic +;;; semantic/db-debug.el --- Extra level debugging routines for Semantic -*- lexical-binding: t; -*- -;;; Copyright (C) 2008-2021 Free Software Foundation, Inc. +;; Copyright (C) 2008-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -38,7 +38,7 @@ (data-debug-new-buffer "*SEMANTICDB*") (data-debug-insert-stuff-list db "*"))) -(defalias 'semanticdb-adebug-database-list 'semanticdb-dump-all-table-summary) +(defalias 'semanticdb-adebug-database-list #'semanticdb-dump-all-table-summary) (defun semanticdb-adebug-current-database () "Run ADEBUG on the current database." diff --git a/lisp/cedet/semantic/db-ebrowse.el b/lisp/cedet/semantic/db-ebrowse.el index 946f9ef632..db37512de3 100644 --- a/lisp/cedet/semantic/db-ebrowse.el +++ b/lisp/cedet/semantic/db-ebrowse.el @@ -1,4 +1,4 @@ -;;; semantic/db-ebrowse.el --- Semanticdb backend using ebrowse. +;;; semantic/db-ebrowse.el --- Semanticdb backend using ebrowse. -*- lexical-binding: t; -*- ;; Copyright (C) 2005-2021 Free Software Foundation, Inc. @@ -135,8 +135,8 @@ is specified by `semanticdb-default-save-directory'." (let* ((savein (semanticdb-ebrowse-file-for-directory dir)) (filebuff (get-buffer-create "*SEMANTICDB EBROWSE TMP*")) (files (directory-files (expand-file-name dir) t)) - (mma auto-mode-alist) - (regexp nil) + ;; (mma auto-mode-alist) + ;; (regexp nil) ) ;; Create the input to the ebrowse command (with-current-buffer filebuff @@ -227,7 +227,7 @@ warn instead." () "Search Ebrowse for symbols.") -(cl-defmethod semanticdb-needs-refresh-p ((table semanticdb-table-ebrowse)) +(cl-defmethod semanticdb-needs-refresh-p ((_table semanticdb-table-ebrowse)) "EBROWSE database do not need to be refreshed. JAVE: stub for needs-refresh, because, how do we know if BROWSE files @@ -274,7 +274,7 @@ For instance: /home//.semanticdb/!usr!include!BROWSE" (insert-file-contents B) (let ((ans nil) (efcn (symbol-function 'ebrowse-show-progress))) - (fset 'ebrowse-show-progress #'(lambda (&rest junk) nil)) + (fset 'ebrowse-show-progress #'(lambda (&rest _junk) nil)) (unwind-protect ;; Protect against errors w/ ebrowse (setq ans (list B (ebrowse-read))) ;; These items must always happen @@ -341,10 +341,10 @@ If there is no database for DIRECTORY available, then (while T (let* ((tree (car T)) - (class (ebrowse-ts-class tree)); root class of tree + ;;(class (ebrowse-ts-class tree)); root class of tree ;; Something funny going on with this file thing... - (filename (or (ebrowse-cs-source-file class) - (ebrowse-cs-file class))) + ;; (filename (or (ebrowse-cs-source-file class) + ;; (ebrowse-cs-file class))) ) (cond ((ebrowse-globals-tree-p tree) @@ -363,18 +363,18 @@ If there is no database for DIRECTORY available, then ;;; Filename based methods ;; -(defun semanticdb-ebrowse-add-globals-to-table (dbe tree) +(defun semanticdb-ebrowse-add-globals-to-table (_dbe tree) "For database DBE, add the ebrowse TREE into the table." (if (or (not (ebrowse-ts-p tree)) (not (ebrowse-globals-tree-p tree))) (signal 'wrong-type-argument (list 'ebrowse-ts-p tree))) (let* ((class (ebrowse-ts-class tree)) - (fname (or (ebrowse-cs-source-file class) - (ebrowse-cs-file class) - ;; Not def'd here, assume our current - ;; file - (concat default-directory "/unknown-proxy.hh"))) + ;; (fname (or (ebrowse-cs-source-file class) + ;; (ebrowse-cs-file class) + ;; ;; Not def'd here, assume our current + ;; ;; file + ;; (concat default-directory "/unknown-proxy.hh"))) (vars (ebrowse-ts-member-functions tree)) (fns (ebrowse-ts-member-variables tree)) (toks nil) @@ -573,7 +573,7 @@ return that." ;; how your new search routines are implemented. ;; (cl-defmethod semanticdb-find-tags-by-name-method - ((table semanticdb-table-ebrowse) name &optional tags) + ((_table semanticdb-table-ebrowse) _name &optional tags) "Find all tags named NAME in TABLE. Return a list of tags." ;;(message "semanticdb-find-tags-by-name-method name -- %s" name) @@ -588,7 +588,7 @@ Return a list of tags." ) (cl-defmethod semanticdb-find-tags-by-name-regexp-method - ((table semanticdb-table-ebrowse) regex &optional tags) + ((_table semanticdb-table-ebrowse) _regex &optional tags) "Find all tags with name matching REGEX in TABLE. Optional argument TAGS is a list of tags to search. Return a list of tags." @@ -598,7 +598,7 @@ Return a list of tags." )) (cl-defmethod semanticdb-find-tags-for-completion-method - ((table semanticdb-table-ebrowse) prefix &optional tags) + ((_table semanticdb-table-ebrowse) _prefix &optional tags) "In TABLE, find all occurrences of tags matching PREFIX. Optional argument TAGS is a list of tags to search. Returns a table of all matching tags." @@ -608,7 +608,7 @@ Returns a table of all matching tags." )) (cl-defmethod semanticdb-find-tags-by-class-method - ((table semanticdb-table-ebrowse) class &optional tags) + ((_table semanticdb-table-ebrowse) _class &optional tags) "In TABLE, find all occurrences of tags of CLASS. Optional argument TAGS is a list of tags to search. Returns a table of all matching tags." @@ -625,7 +625,7 @@ Returns a table of all matching tags." ;; (cl-defmethod semanticdb-deep-find-tags-by-name-method - ((table semanticdb-table-ebrowse) name &optional tags) + ((_table semanticdb-table-ebrowse) _name &optional _tags) "Find all tags name NAME in TABLE. Optional argument TAGS is a list of tags to search. Like `semanticdb-find-tags-by-name-method' for ebrowse." @@ -633,7 +633,7 @@ Like `semanticdb-find-tags-by-name-method' for ebrowse." (cl-call-next-method)) (cl-defmethod semanticdb-deep-find-tags-by-name-regexp-method - ((table semanticdb-table-ebrowse) regex &optional tags) + ((_table semanticdb-table-ebrowse) _regex &optional _tags) "Find all tags with name matching REGEX in TABLE. Optional argument TAGS is a list of tags to search. Like `semanticdb-find-tags-by-name-method' for ebrowse." @@ -641,7 +641,7 @@ Like `semanticdb-find-tags-by-name-method' for ebrowse." (cl-call-next-method)) (cl-defmethod semanticdb-deep-find-tags-for-completion-method - ((table semanticdb-table-ebrowse) prefix &optional tags) + ((_table semanticdb-table-ebrowse) _prefix &optional _tags) "In TABLE, find all occurrences of tags matching PREFIX. Optional argument TAGS is a list of tags to search. Like `semanticdb-find-tags-for-completion-method' for ebrowse." @@ -651,7 +651,7 @@ Like `semanticdb-find-tags-for-completion-method' for ebrowse." ;;; Advanced Searches ;; (cl-defmethod semanticdb-find-tags-external-children-of-type-method - ((table semanticdb-table-ebrowse) type &optional tags) + ((_table semanticdb-table-ebrowse) _type &optional tags) "Find all nonterminals which are child elements of TYPE Optional argument TAGS is a list of tags to search. Return a list of tags." diff --git a/lisp/cedet/semantic/db-el.el b/lisp/cedet/semantic/db-el.el index de84b97802..78339c375f 100644 --- a/lisp/cedet/semantic/db-el.el +++ b/lisp/cedet/semantic/db-el.el @@ -1,6 +1,6 @@ -;;; semantic/db-el.el --- Semantic database extensions for Emacs Lisp +;;; semantic/db-el.el --- Semantic database extensions for Emacs Lisp -*- lexical-binding: t; -*- -;;; Copyright (C) 2002-2021 Free Software Foundation, Inc. +;; Copyright (C) 2002-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: tags @@ -53,7 +53,7 @@ It does not need refreshing." "Return nil, we never need a refresh." nil) -(cl-defmethod semanticdb-debug-info ((obj semanticdb-table-emacs-lisp)) +(cl-defmethod semanticdb-debug-info ((_obj semanticdb-table-emacs-lisp)) (list "(proxy)")) (cl-defmethod cl-print-object ((obj semanticdb-table-emacs-lisp) stream) diff --git a/lisp/cedet/semantic/db-file.el b/lisp/cedet/semantic/db-file.el index d99b94f49e..c9007ac7a0 100644 --- a/lisp/cedet/semantic/db-file.el +++ b/lisp/cedet/semantic/db-file.el @@ -1,6 +1,6 @@ -;;; semantic/db-file.el --- Save a semanticdb to a cache file. +;;; semantic/db-file.el --- Save a semanticdb to a cache file. -*- lexical-binding: t; -*- -;;; Copyright (C) 2000-2005, 2007-2021 Free Software Foundation, Inc. +;; Copyright (C) 2000-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: tags @@ -358,13 +358,13 @@ Uses `semanticdb-persistent-path' to determine the return value." (object-assoc (file-name-nondirectory filename) 'file (oref obj tables))) (cl-defmethod semanticdb-file-name-non-directory - ((dbclass (subclass semanticdb-project-database-file))) + ((_dbclass (subclass semanticdb-project-database-file))) "Return the file name DBCLASS will use. File name excludes any directory part." semanticdb-default-file-name) (cl-defmethod semanticdb-file-name-directory - ((dbclass (subclass semanticdb-project-database-file)) directory) + ((_dbclass (subclass semanticdb-project-database-file)) directory) "Return the relative directory to where DBCLASS will save its cache file. The returned path is related to DIRECTORY." (if semanticdb-default-save-directory diff --git a/lisp/cedet/semantic/db-find.el b/lisp/cedet/semantic/db-find.el index db88463bfd..c96a426280 100644 --- a/lisp/cedet/semantic/db-find.el +++ b/lisp/cedet/semantic/db-find.el @@ -1,4 +1,4 @@ -;;; semantic/db-find.el --- Searching through semantic databases. +;;; semantic/db-find.el --- Searching through semantic databases. -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. @@ -209,14 +209,14 @@ This class will cache data derived during various searches.") ) (cl-defmethod semanticdb-synchronize ((idx semanticdb-find-search-index) - new-tags) + _new-tags) "Synchronize the search index IDX with some NEW-TAGS." ;; Reset our parts. (semantic-reset idx) ;; Notify dependants by clearing their indices. (semanticdb-notify-references (oref idx table) - (lambda (tab me) + (lambda (tab _me) (semantic-reset (semanticdb-get-table-index tab)))) ) @@ -230,7 +230,7 @@ This class will cache data derived during various searches.") ;; Notify dependants by clearing their indices. (semanticdb-notify-references (oref idx table) - (lambda (tab me) + (lambda (tab _me) (semantic-reset (semanticdb-get-table-index tab)))) ) ;; Else, not an include, by just a type. @@ -240,7 +240,7 @@ This class will cache data derived during various searches.") ;; Notify dependants by clearing their indices. (semanticdb-notify-references (oref idx table) - (lambda (tab me) + (lambda (tab _me) (let ((tab-idx (semanticdb-get-table-index tab))) ;; Not a full reset? (when (oref tab-idx type-cache) @@ -791,7 +791,8 @@ PREBUTTONTEXT is some text between prefix and the overlay button." (file (semantic-tag-file-name tag)) (str1 (format "%S %s" mode name)) (str2 (format " : %s" file)) - (tip nil)) + ;; (tip nil) + ) (insert prefix prebuttontext str1) (setq end (point)) (insert str2) @@ -807,7 +808,7 @@ PREBUTTONTEXT is some text between prefix and the overlay button." (put-text-property start end 'ddebug (cdr consdata)) (put-text-property start end 'ddebug-indent(length prefix)) (put-text-property start end 'ddebug-prefix prefix) - (put-text-property start end 'help-echo tip) + ;; (put-text-property start end 'help-echo tip) (put-text-property start end 'ddebug-function 'data-debug-insert-tag-parts-from-point) (insert "\n") @@ -1009,7 +1010,7 @@ is still made current." (when norm ;; The normalized tags can now be found based on that ;; tags table. - (condition-case foo + (condition-case nil (progn (semanticdb-set-buffer (car norm)) ;; Now reset ans diff --git a/lisp/cedet/semantic/db-global.el b/lisp/cedet/semantic/db-global.el index 2f40082d53..6bdc7b3f75 100644 --- a/lisp/cedet/semantic/db-global.el +++ b/lisp/cedet/semantic/db-global.el @@ -1,4 +1,4 @@ -;;; semantic/db-global.el --- Semantic database extensions for GLOBAL +;;; semantic/db-global.el --- Semantic database extensions for GLOBAL -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2006, 2008-2021 Free Software Foundation, Inc. @@ -69,7 +69,8 @@ values." (let ((semanticdb--ih (mode-local-value mode 'semantic-init-mode-hook))) (eval `(setq-mode-local ,mode semantic-init-mode-hook - (cons 'semanticdb-enable-gnu-global-hook semanticdb--ih)))) + (cons 'semanticdb-enable-gnu-global-hook ',semanticdb--ih)) + t)) t ) ) @@ -114,7 +115,7 @@ if optional DONT-ERR-IF-NOT-AVAILABLE is non-nil; else throw an error." ) "A table for returning search results from GNU Global.") -(cl-defmethod semanticdb-debug-info ((obj semanticdb-table-global)) +(cl-defmethod semanticdb-debug-info ((_obj semanticdb-table-global)) (list "(proxy)")) (cl-defmethod cl-print-object ((obj semanticdb-table-global) stream) @@ -123,7 +124,7 @@ Adds the number of tags in this file to the object print name." (princ (eieio-object-name obj (semanticdb-debug-info obj)) stream)) -(cl-defmethod semanticdb-equivalent-mode ((table semanticdb-table-global) &optional buffer) +(cl-defmethod semanticdb-equivalent-mode ((_table semanticdb-table-global) &optional _buffer) "Return t, pretend that this table's mode is equivalent to BUFFER. Equivalent modes are specified by the `semantic-equivalent-major-modes' local variable." @@ -146,7 +147,7 @@ For each file hit, get the traditional semantic table from that file." (cl-call-next-method)) -(cl-defmethod semanticdb-file-table ((obj semanticdb-project-database-global) filename) +(cl-defmethod semanticdb-file-table ((obj semanticdb-project-database-global) _filename) "From OBJ, return FILENAME's associated table object." ;; We pass in "don't load". I wonder if we need to avoid that or not? (car (semanticdb-get-database-tables obj)) @@ -157,7 +158,7 @@ For each file hit, get the traditional semantic table from that file." ;; Only NAME based searches work with GLOBAL as that is all it tracks. ;; (cl-defmethod semanticdb-find-tags-by-name-method - ((table semanticdb-table-global) name &optional tags) + ((_table semanticdb-table-global) name &optional tags) "Find all tags named NAME in TABLE. Return a list of tags." (if tags @@ -174,7 +175,7 @@ Return a list of tags." ))) (cl-defmethod semanticdb-find-tags-by-name-regexp-method - ((table semanticdb-table-global) regex &optional tags) + ((_table semanticdb-table-global) regex &optional tags) "Find all tags with name matching REGEX in TABLE. Optional argument TAGS is a list of tags to search. Return a list of tags." @@ -187,7 +188,7 @@ Return a list of tags." ))) (cl-defmethod semanticdb-find-tags-for-completion-method - ((table semanticdb-table-global) prefix &optional tags) + ((_table semanticdb-table-global) prefix &optional tags) "In TABLE, find all occurrences of tags matching PREFIX. Optional argument TAGS is a list of tags to search. Returns a table of all matching tags." diff --git a/lisp/cedet/semantic/db-javascript.el b/lisp/cedet/semantic/db-javascript.el index 2b13886621..cad561e796 100644 --- a/lisp/cedet/semantic/db-javascript.el +++ b/lisp/cedet/semantic/db-javascript.el @@ -1,4 +1,4 @@ -;;; semantic/db-javascript.el --- Semantic database extensions for javascript +;;; semantic/db-javascript.el --- Semantic database extensions for javascript -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. @@ -129,20 +129,20 @@ Create one of our special tables that can act as an intermediary." (cl-call-next-method) ) -(cl-defmethod semanticdb-file-table ((obj semanticdb-project-database-javascript) filename) +(cl-defmethod semanticdb-file-table ((obj semanticdb-project-database-javascript) _filename) "From OBJ, return FILENAME's associated table object." ;; NOTE: See not for `semanticdb-get-database-tables'. (car (semanticdb-get-database-tables obj)) ) -(cl-defmethod semanticdb-get-tags ((table semanticdb-table-javascript )) +(cl-defmethod semanticdb-get-tags ((_table semanticdb-table-javascript )) "Return the list of tags belonging to TABLE." ;; NOTE: Omniscient databases probably don't want to keep large tables ;; lolly-gagging about. Keep internal Emacs tables empty and ;; refer to alternate databases when you need something. semanticdb-javascript-tags) -(cl-defmethod semanticdb-equivalent-mode ((table semanticdb-table-javascript) &optional buffer) +(cl-defmethod semanticdb-equivalent-mode ((_table semanticdb-table-javascript) &optional buffer) "Return non-nil if TABLE's mode is equivalent to BUFFER. Equivalent modes are specified by the `semantic-equivalent-major-modes' local variable." @@ -193,7 +193,7 @@ database (if available.)" result)) (cl-defmethod semanticdb-find-tags-by-name-method - ((table semanticdb-table-javascript) name &optional tags) + ((_table semanticdb-table-javascript) name &optional tags) "Find all tags named NAME in TABLE. Return a list of tags." (if tags @@ -203,7 +203,7 @@ Return a list of tags." )) (cl-defmethod semanticdb-find-tags-by-name-regexp-method - ((table semanticdb-table-javascript) regex &optional tags) + ((_table semanticdb-table-javascript) regex &optional tags) "Find all tags with name matching REGEX in TABLE. Optional argument TAGS is a list of tags to search. Return a list of tags." @@ -214,7 +214,7 @@ Return a list of tags." )) (cl-defmethod semanticdb-find-tags-for-completion-method - ((table semanticdb-table-javascript) prefix &optional tags) + ((_table semanticdb-table-javascript) prefix &optional tags) "In TABLE, find all occurrences of tags matching PREFIX. Optional argument TAGS is a list of tags to search. Returns a table of all matching tags." @@ -224,7 +224,7 @@ Returns a table of all matching tags." )) (cl-defmethod semanticdb-find-tags-by-class-method - ((table semanticdb-table-javascript) class &optional tags) + ((_table semanticdb-table-javascript) _class &optional tags) "In TABLE, find all occurrences of tags of CLASS. Optional argument TAGS is a list of tags to search. Returns a table of all matching tags." @@ -268,7 +268,7 @@ Like `semanticdb-find-tags-for-completion-method' for javascript." ;;; Advanced Searches ;; (cl-defmethod semanticdb-find-tags-external-children-of-type-method - ((table semanticdb-table-javascript) type &optional tags) + ((_table semanticdb-table-javascript) _type &optional tags) "Find all nonterminals which are child elements of TYPE. Optional argument TAGS is a list of tags to search. Return a list of tags." diff --git a/lisp/cedet/semantic/db-mode.el b/lisp/cedet/semantic/db-mode.el index aa4634faa9..839dcb8172 100644 --- a/lisp/cedet/semantic/db-mode.el +++ b/lisp/cedet/semantic/db-mode.el @@ -1,4 +1,4 @@ -;;; semantic/db-mode.el --- Semanticdb Minor Mode +;;; semantic/db-mode.el --- Semanticdb Minor Mode -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/semantic/db-ref.el b/lisp/cedet/semantic/db-ref.el index da09f9830a..10108d3977 100644 --- a/lisp/cedet/semantic/db-ref.el +++ b/lisp/cedet/semantic/db-ref.el @@ -1,6 +1,6 @@ -;;; semantic/db-ref.el --- Handle cross-db file references +;;; semantic/db-ref.el --- Handle cross-db file references -*- lexical-binding: t; -*- -;;; Copyright (C) 2007-2021 Free Software Foundation, Inc. +;; Copyright (C) 2007-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -67,7 +67,7 @@ will be added to the database that INCLUDE-TAG refers to." (object-add-to-list refdbt 'db-refs dbt) t))) -(cl-defmethod semanticdb-check-references ((dbt semanticdb-abstract-table)) +(cl-defmethod semanticdb-check-references ((_dbt semanticdb-abstract-table)) "Check and cleanup references in the database DBT. Abstract tables would be difficult to reference." ;; Not sure how an abstract table can have references. @@ -109,7 +109,7 @@ refers to DBT will be removed." )) (setq refs (cdr refs))))) -(cl-defmethod semanticdb-refresh-references ((dbt semanticdb-abstract-table)) +(cl-defmethod semanticdb-refresh-references ((_dbt semanticdb-abstract-table)) "Refresh references to DBT in other files." ;; alternate tables can't be edited, so can't be changed. nil diff --git a/lisp/cedet/semantic/db-typecache.el b/lisp/cedet/semantic/db-typecache.el index 8c394cd7fa..c0fee3b2bd 100644 --- a/lisp/cedet/semantic/db-typecache.el +++ b/lisp/cedet/semantic/db-typecache.el @@ -1,4 +1,4 @@ -;;; semantic/db-typecache.el --- Manage Datatypes +;;; semantic/db-typecache.el --- Manage Datatypes -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. @@ -74,14 +74,14 @@ Said object must support `semantic-reset' methods.") (oset tc stream nil) - (mapc 'semantic-reset (oref tc dependants)) + (mapc #'semantic-reset (oref tc dependants)) (oset tc dependants nil) ) (cl-defmethod semanticdb-typecache-notify-reset ((tc semanticdb-typecache)) "Do a reset from a notify from a table we depend on." (oset tc includestream nil) - (mapc 'semantic-reset (oref tc dependants)) + (mapc #'semantic-reset (oref tc dependants)) (oset tc dependants nil) ) @@ -90,7 +90,7 @@ Said object must support `semantic-reset' methods.") "Reset the typecache based on a partial reparse." (when (semantic-find-tags-by-class 'include new-tags) (oset tc includestream nil) - (mapc 'semantic-reset (oref tc dependants)) + (mapc #'semantic-reset (oref tc dependants)) (oset tc dependants nil) ) @@ -167,15 +167,15 @@ If there is no table, create one, and fill it in." (oset tc stream nil) ) -(cl-defmethod semanticdb-synchronize ((cache semanticdb-database-typecache) - new-tags) +(cl-defmethod semanticdb-synchronize ((_cache semanticdb-database-typecache) + _new-tags) "Synchronize a CACHE with some NEW-TAGS." - ) + nil) -(cl-defmethod semanticdb-partial-synchronize ((cache semanticdb-database-typecache) - new-tags) +(cl-defmethod semanticdb-partial-synchronize ((_cache semanticdb-database-typecache) + _new-tags) "Synchronize a CACHE with some changed NEW-TAGS." - ) + nil) (cl-defmethod semanticdb-get-typecache ((db semanticdb-project-database)) "Retrieve the typecache from the semantic database DB. @@ -312,7 +312,7 @@ If TAG has fully qualified names, expand it to a series of nested namespaces instead." tag) -(cl-defmethod semanticdb-typecache-file-tags ((table semanticdb-abstract-table)) +(cl-defmethod semanticdb-typecache-file-tags ((_table semanticdb-abstract-table)) "No tags available from non-file based tables." nil) @@ -338,7 +338,7 @@ all included files." (oref cache filestream) )) -(cl-defmethod semanticdb-typecache-include-tags ((table semanticdb-abstract-table)) +(cl-defmethod semanticdb-typecache-include-tags ((_table semanticdb-abstract-table)) "No tags available from non-file based tables." nil) @@ -611,7 +611,7 @@ If there isn't one, create it. (require 'data-debug) (let* ((tab semanticdb-current-table) (idx (semanticdb-get-table-index tab)) - (junk (oset idx type-cache nil)) ;; flush! + (_ (oset idx type-cache nil)) ;; flush! (start (current-time)) (tc (semanticdb-typecache-for-database (oref tab parent-db))) (end (current-time)) diff --git a/lisp/cedet/semantic/debug.el b/lisp/cedet/semantic/debug.el index ce4afbbf26..4f96746166 100644 --- a/lisp/cedet/semantic/debug.el +++ b/lisp/cedet/semantic/debug.el @@ -1,4 +1,4 @@ -;;; semantic/debug.el --- Language Debugger framework +;;; semantic/debug.el --- Language Debugger framework -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2005, 2008-2021 Free Software Foundation, Inc. @@ -265,12 +265,12 @@ on different types of return values." ) "One frame representation.") -(cl-defmethod semantic-debug-frame-highlight ((frame semantic-debug-frame)) +(cl-defmethod semantic-debug-frame-highlight ((_frame semantic-debug-frame)) "Highlight one parser frame." ) -(cl-defmethod semantic-debug-frame-info ((frame semantic-debug-frame)) +(cl-defmethod semantic-debug-frame-info ((_frame semantic-debug-frame)) "Display info about this one parser frame." ) @@ -279,21 +279,21 @@ on different types of return values." ;; (defvar semantic-debug-mode-map (let ((km (make-sparse-keymap))) - (define-key km "n" 'semantic-debug-next) - (define-key km " " 'semantic-debug-next) - (define-key km "s" 'semantic-debug-step) - (define-key km "u" 'semantic-debug-up) - (define-key km "d" 'semantic-debug-down) - (define-key km "f" 'semantic-debug-fail-match) - (define-key km "h" 'semantic-debug-print-state) - (define-key km "s" 'semantic-debug-jump-to-source) - (define-key km "p" 'semantic-debug-jump-to-parser) - (define-key km "q" 'semantic-debug-quit) - (define-key km "a" 'semantic-debug-abort) - (define-key km "g" 'semantic-debug-go) - (define-key km "b" 'semantic-debug-set-breakpoint) + (define-key km "n" #'semantic-debug-next) + (define-key km " " #'semantic-debug-next) + (define-key km "s" #'semantic-debug-step) + (define-key km "u" #'semantic-debug-up) + (define-key km "d" #'semantic-debug-down) + (define-key km "f" #'semantic-debug-fail-match) + (define-key km "h" #'semantic-debug-print-state) + (define-key km "s" #'semantic-debug-jump-to-source) + (define-key km "p" #'semantic-debug-jump-to-parser) + (define-key km "q" #'semantic-debug-quit) + (define-key km "a" #'semantic-debug-abort) + (define-key km "g" #'semantic-debug-go) + (define-key km "b" #'semantic-debug-set-breakpoint) ;; Some boring bindings. - (define-key km "e" 'eval-expression) + (define-key km "e" #'eval-expression) km) "Keymap used when in semantic-debug-node.") @@ -514,49 +514,49 @@ by overriding one of the command methods. Be sure to use down to your parser later." :abstract t) -(cl-defmethod semantic-debug-parser-next ((parser semantic-debug-parser)) +(cl-defmethod semantic-debug-parser-next ((_parser semantic-debug-parser)) "Execute next for this PARSER." (setq semantic-debug-user-command 'next) ) -(cl-defmethod semantic-debug-parser-step ((parser semantic-debug-parser)) +(cl-defmethod semantic-debug-parser-step ((_parser semantic-debug-parser)) "Execute a step for this PARSER." (setq semantic-debug-user-command 'step) ) -(cl-defmethod semantic-debug-parser-go ((parser semantic-debug-parser)) +(cl-defmethod semantic-debug-parser-go ((_parser semantic-debug-parser)) "Continue execution in this PARSER until the next breakpoint." (setq semantic-debug-user-command 'go) ) -(cl-defmethod semantic-debug-parser-fail ((parser semantic-debug-parser)) +(cl-defmethod semantic-debug-parser-fail ((_parser semantic-debug-parser)) "Continue execution in this PARSER until the next breakpoint." (setq semantic-debug-user-command 'fail) ) -(cl-defmethod semantic-debug-parser-quit ((parser semantic-debug-parser)) +(cl-defmethod semantic-debug-parser-quit ((_parser semantic-debug-parser)) "Continue execution in this PARSER until the next breakpoint." (setq semantic-debug-user-command 'quit) ) -(cl-defmethod semantic-debug-parser-abort ((parser semantic-debug-parser)) +(cl-defmethod semantic-debug-parser-abort ((_parser semantic-debug-parser)) "Continue execution in this PARSER until the next breakpoint." (setq semantic-debug-user-command 'abort) ) -(cl-defmethod semantic-debug-parser-print-state ((parser semantic-debug-parser)) +(cl-defmethod semantic-debug-parser-print-state ((_parser semantic-debug-parser)) "Print state for this PARSER at the current breakpoint." (with-slots (current-frame) semantic-debug-current-interface (when current-frame (semantic-debug-frame-info current-frame) ))) -(cl-defmethod semantic-debug-parser-break ((parser semantic-debug-parser)) +(cl-defmethod semantic-debug-parser-break ((_parser semantic-debug-parser)) "Set a breakpoint for this PARSER." ) ;; Stack stuff -(cl-defmethod semantic-debug-parser-frames ((parser semantic-debug-parser)) +(cl-defmethod semantic-debug-parser-frames ((_parser semantic-debug-parser)) "Return a list of frames for the current parser. A frame is of the form: ( .. .what ? .. ) diff --git a/lisp/cedet/semantic/decorate.el b/lisp/cedet/semantic/decorate.el index 53c54ab4cc..3e6651df15 100644 --- a/lisp/cedet/semantic/decorate.el +++ b/lisp/cedet/semantic/decorate.el @@ -1,7 +1,6 @@ -;;; semantic/decorate.el --- Utilities for decorating/highlighting tokens. +;;; semantic/decorate.el --- Utilities for decorating/highlighting tokens. -*- lexical-binding: t; -*- -;;; Copyright (C) 1999-2003, 2005-2007, 2009-2021 Free Software -;;; Foundation, Inc. +;; Copyright (C) 1999-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: syntax @@ -51,7 +50,7 @@ Optional FACE specifies the face to use." )) ;;; Momentary Highlighting - One line -(defun semantic-momentary-highlight-one-tag-line (tag &optional face) +(defun semantic-momentary-highlight-one-tag-line (tag &optional _face) "Highlight the first line of TAG, unhighlighting before next command. Optional argument FACE specifies the face to do the highlighting." (save-excursion @@ -88,7 +87,7 @@ If VISIBLE is non-nil, make the text visible." (overlay-get (semantic-tag-overlay tag) 'invisible)) (defun semantic-overlay-signal-read-only - (overlay after start end &optional len) + (overlay after start end &optional _len) "Hook used in modification hooks to prevent modification. Allows deletion of the entire text. Argument OVERLAY, AFTER, START, END, and LEN are passed in by the system." @@ -261,7 +260,7 @@ nil implies the tag should be fully shown." (declare-function semantic-current-tag "semantic/find") -(defun semantic-set-tag-folded-isearch (overlay) +(defun semantic-set-tag-folded-isearch (_overlay) "Called by isearch if it discovers text in the folded region. OVERLAY is passed in by isearch." (semantic-set-tag-folded (semantic-current-tag) nil) diff --git a/lisp/cedet/semantic/decorate/include.el b/lisp/cedet/semantic/decorate/include.el index 851a2c46a9..a3bf4e252f 100644 --- a/lisp/cedet/semantic/decorate/include.el +++ b/lisp/cedet/semantic/decorate/include.el @@ -55,7 +55,7 @@ Used by the decoration style: `semantic-decoration-on-includes'." (defvar semantic-decoration-on-include-map (let ((km (make-sparse-keymap))) - (define-key km semantic-decoration-mouse-3 'semantic-decoration-include-menu) + (define-key km semantic-decoration-mouse-3 #'semantic-decoration-include-menu) km) "Keymap used on includes.") @@ -114,7 +114,7 @@ Used by the decoration style: `semantic-decoration-on-unknown-includes'." (defvar semantic-decoration-on-unknown-include-map (let ((km (make-sparse-keymap))) ;(define-key km [ mouse-2 ] 'semantic-decoration-unknown-include-describe) - (define-key km semantic-decoration-mouse-3 'semantic-decoration-unknown-include-menu) + (define-key km semantic-decoration-mouse-3 #'semantic-decoration-unknown-include-menu) km) "Keymap used on unparsed includes.") @@ -169,7 +169,7 @@ Used by the decoration style: `semantic-decoration-on-fileless-includes'." (defvar semantic-decoration-on-fileless-include-map (let ((km (make-sparse-keymap))) ;(define-key km [ mouse-2 ] 'semantic-decoration-fileless-include-describe) - (define-key km semantic-decoration-mouse-3 'semantic-decoration-fileless-include-menu) + (define-key km semantic-decoration-mouse-3 #'semantic-decoration-fileless-include-menu) km) "Keymap used on unparsed includes.") @@ -223,7 +223,7 @@ Used by the decoration style: `semantic-decoration-on-unparsed-includes'." (defvar semantic-decoration-on-unparsed-include-map (let ((km (make-sparse-keymap))) - (define-key km semantic-decoration-mouse-3 'semantic-decoration-unparsed-include-menu) + (define-key km semantic-decoration-mouse-3 #'semantic-decoration-unparsed-include-menu) km) "Keymap used on unparsed includes.") diff --git a/lisp/cedet/semantic/decorate/mode.el b/lisp/cedet/semantic/decorate/mode.el index 89cc9304d4..7895015919 100644 --- a/lisp/cedet/semantic/decorate/mode.el +++ b/lisp/cedet/semantic/decorate/mode.el @@ -264,9 +264,9 @@ non-nil if the minor mode is enabled." (buffer-name))) ;; Add hooks (add-hook 'semantic-after-partial-cache-change-hook - 'semantic-decorate-tags-after-partial-reparse nil t) + #'semantic-decorate-tags-after-partial-reparse nil t) (add-hook 'semantic-after-toplevel-cache-change-hook - 'semantic-decorate-tags-after-full-reparse nil t) + #'semantic-decorate-tags-after-full-reparse nil t) ;; Add decorations to available tags. The above hooks ensure ;; that new tags will be decorated when they become available. ;; However, don't do this immediately, because EDE will be @@ -282,9 +282,9 @@ non-nil if the minor mode is enabled." (semantic-decorate-flush-decorations) ;; Remove hooks (remove-hook 'semantic-after-partial-cache-change-hook - 'semantic-decorate-tags-after-partial-reparse t) + #'semantic-decorate-tags-after-partial-reparse t) (remove-hook 'semantic-after-toplevel-cache-change-hook - 'semantic-decorate-tags-after-full-reparse t))) + #'semantic-decorate-tags-after-full-reparse t))) (semantic-add-minor-mode 'semantic-decoration-mode "") @@ -350,13 +350,11 @@ Return non-nil if the decoration style is enabled." (defun semantic-decoration-build-style-menu (style) "Build a menu item for controlling a specific decoration STYLE." - (vector (car style) - `(lambda () (interactive) - (semantic-toggle-decoration-style - ,(car style))) - :style 'toggle - :selected `(semantic-decoration-style-enabled-p ,(car style)) - )) + (let ((s (car style))) + (vector s + (lambda () (interactive) (semantic-toggle-decoration-style s)) + :style 'toggle + :selected `(semantic-decoration-style-enabled-p ',s)))) (defun semantic-build-decoration-mode-menu (&rest _ignore) "Create a menu listing all the known decorations for toggling. diff --git a/lisp/cedet/semantic/dep.el b/lisp/cedet/semantic/dep.el index db8be5ecf4..efebe21a94 100644 --- a/lisp/cedet/semantic/dep.el +++ b/lisp/cedet/semantic/dep.el @@ -1,4 +1,4 @@ -;;; semantic/dep.el --- Methods for tracking dependencies (include files) +;;; semantic/dep.el --- Methods for tracking dependencies (include files) -*- lexical-binding: t; -*- ;; Copyright (C) 2006-2021 Free Software Foundation, Inc. @@ -123,12 +123,12 @@ Changes made by this function are not persistent." (if (not mode) (setq mode major-mode)) (let ((dirtmp (file-name-as-directory dir)) (value - (mode-local-value mode 'semantic-dependency-system-include-path)) - ) - (add-to-list 'value dirtmp t) + (mode-local-value mode 'semantic-dependency-system-include-path))) (eval `(setq-mode-local ,mode - semantic-dependency-system-include-path value)) - )) + semantic-dependency-system-include-path + ',(if (member dirtmp value) value + (append value (list dirtmp)))) + t))) ;;;###autoload (defun semantic-remove-system-include (dir &optional mode) @@ -146,10 +146,10 @@ Changes made by this function are not persistent." (value (mode-local-value mode 'semantic-dependency-system-include-path)) ) - (setq value (delete dirtmp value)) + (setq value (remove dirtmp value)) (eval `(setq-mode-local ,mode semantic-dependency-system-include-path - value)) - )) + ',value) + t))) ;;;###autoload (defun semantic-reset-system-include (&optional mode) @@ -157,10 +157,10 @@ Changes made by this function are not persistent." Modifies a mode-local version of `semantic-dependency-system-include-path'." (interactive) - (if (not mode) (setq mode major-mode)) - (eval `(setq-mode-local ,mode semantic-dependency-system-include-path - nil)) - ) + (eval `(setq-mode-local ,(or mode major-mode) + semantic-dependency-system-include-path + nil) + t)) ;;;###autoload (defun semantic-customize-system-include-path (&optional mode) diff --git a/lisp/cedet/semantic/doc.el b/lisp/cedet/semantic/doc.el index d4dd928642..413ed83a15 100644 --- a/lisp/cedet/semantic/doc.el +++ b/lisp/cedet/semantic/doc.el @@ -1,4 +1,4 @@ -;;; semantic/doc.el --- Routines for documentation strings +;;; semantic/doc.el --- Routines for documentation strings -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2003, 2005, 2008-2021 Free Software Foundation, ;; Inc. @@ -85,7 +85,7 @@ just the lexical token and not the string." )) (define-obsolete-function-alias 'semantic-documentation-comment-preceeding-tag - 'semantic-documentation-comment-preceding-tag + #'semantic-documentation-comment-preceding-tag "25.1") (defun semantic-doc-snarf-comment-for-tag (nosnarf) diff --git a/lisp/cedet/semantic/ede-grammar.el b/lisp/cedet/semantic/ede-grammar.el index 64fc07fe1b..6bb83526f6 100644 --- a/lisp/cedet/semantic/ede-grammar.el +++ b/lisp/cedet/semantic/ede-grammar.el @@ -1,4 +1,4 @@ -;;; semantic/ede-grammar.el --- EDE support for Semantic Grammar Files +;;; semantic/ede-grammar.el --- EDE support for Semantic Grammar Files -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2004, 2007-2021 Free Software Foundation, Inc. @@ -30,6 +30,7 @@ (require 'ede/pconf) (require 'ede/proj-elisp) (require 'semantic/grammar) +(eval-when-compile (require 'cl-lib)) ;;; Code: (defclass semantic-ede-proj-target-grammar (ede-proj-target-elisp) @@ -118,7 +119,7 @@ For Emacs Lisp, return addsuffix command on source files." "Compile Emacs Lisp programs.") ;;; Target options. -(cl-defmethod ede-buffer-mine ((this semantic-ede-proj-target-grammar) buffer) +(cl-defmethod ede-buffer-mine ((_this semantic-ede-proj-target-grammar) buffer) "Return t if object THIS lays claim to the file in BUFFER. Lays claim to all -by.el, and -wy.el files." ;; We need to be a little more careful than this, but at the moment it @@ -130,7 +131,7 @@ Lays claim to all -by.el, and -wy.el files." (cl-defmethod project-compile-target ((obj semantic-ede-proj-target-grammar)) "Compile all sources in a Lisp target OBJ." - (let* ((cb (current-buffer)) + (let* (;; (cb (current-buffer)) (proj (ede-target-parent obj)) (default-directory (oref proj directory)) (comp 0) @@ -141,11 +142,10 @@ Lays claim to all -by.el, and -wy.el files." (fname (progn (string-match ".*/\\(.+\\.el\\)" package) (match-string 1 package))) (src (ede-expand-filename obj fname)) - (csrc (concat (file-name-sans-extension src) ".elc"))) - (with-no-warnings - (if (eq (byte-recompile-file src nil 0) t) - (setq comp (1+ comp)) - (setq utd (1+ utd))))))) + ;; (csrc (concat (file-name-sans-extension src) ".elc")) + ) + (cl-incf (if (eq (byte-recompile-file src nil 0) t) + comp utd))))) (oref obj source)) (message "All Semantic Grammar sources are up to date in %s" (eieio-object-name obj)) (cons comp utd))) diff --git a/lisp/cedet/semantic/edit.el b/lisp/cedet/semantic/edit.el index 4594d7f696..0cca156454 100644 --- a/lisp/cedet/semantic/edit.el +++ b/lisp/cedet/semantic/edit.el @@ -1,4 +1,4 @@ -;;; semantic/edit.el --- Edit Management for Semantic +;;; semantic/edit.el --- Edit Management for Semantic -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. @@ -157,7 +157,7 @@ Optional argument BUFFER is the buffer to search for changes in." (sort ret #'(lambda (a b) (< (overlay-start a) (overlay-start b))))))) -(defun semantic-edits-change-function-handle-changes (start end length) +(defun semantic-edits-change-function-handle-changes (start end _length) "Run whenever a buffer controlled by `semantic-mode' change. Tracks when and how the buffer is re-parsed. Argument START, END, and LENGTH specify the bounds of the change." @@ -356,7 +356,7 @@ See `semantic-edits-change-leaf-tag' for details on parents." start end))) (parent nil) (overlapped-tags nil) - inner-start inner-end + inner-end ;; inner-start (list-to-search nil)) ;; By the time this is already called, we know that it is ;; not a leaf change, nor a between tag change. That leaves @@ -370,7 +370,7 @@ See `semantic-edits-change-leaf-tag' for details on parents." (progn ;; We encompass one whole change. (setq overlapped-tags (list (car tags)) - inner-start (semantic-tag-start (car tags)) + ;; inner-start (semantic-tag-start (car tags)) inner-end (semantic-tag-end (car tags)) tags (cdr tags)) ;; Keep looping while tags are inside the change. @@ -386,13 +386,14 @@ See `semantic-edits-change-leaf-tag' for details on parents." ;; This is a parent. Drop the children found ;; so far. (setq overlapped-tags (list (car tags)) - inner-start (semantic-tag-start (car tags)) + ;; inner-start (semantic-tag-start (car tags)) inner-end (semantic-tag-end (car tags)) ) ;; It is not a parent encompassing tag (setq overlapped-tags (cons (car tags) overlapped-tags) - inner-start (semantic-tag-start (car tags)))) + ;; inner-start (semantic-tag-start (car tags)) + )) (setq tags (cdr tags))) (if (not tags) ;; There are no tags left, and all tags originally @@ -533,6 +534,7 @@ This function is for internal use by `semantic-edits-incremental-parser'." ;query this when debugging to find ;source of bugs. ) + (ignore last-cond) ;; Don't warn about the var not being used. (or changes ;; If we were called, and there are no changes, then we ;; don't know what to do. Force a full reparse. diff --git a/lisp/cedet/semantic/find.el b/lisp/cedet/semantic/find.el index 706892b486..17fb20fa0a 100644 --- a/lisp/cedet/semantic/find.el +++ b/lisp/cedet/semantic/find.el @@ -1,4 +1,4 @@ -;;; semantic/find.el --- Search routines for Semantic +;;; semantic/find.el --- Search routines for Semantic -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2005, 2008-2021 Free Software Foundation, Inc. @@ -583,7 +583,7 @@ Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to ) (defun semantic-brute-find-tag-by-function - (function streamorbuffer &optional search-parts search-includes) + (function streamorbuffer &optional search-parts _search-includes) "Find all tags for which FUNCTION's value is non-nil within STREAMORBUFFER. FUNCTION must return non-nil if an element of STREAM will be included in the new list. @@ -620,7 +620,7 @@ This parameter hasn't be active for a while and is obsolete." nl)) (defun semantic-brute-find-first-tag-by-function - (function streamorbuffer &optional search-parts search-includes) + (function streamorbuffer &optional _search-parts _search-includes) "Find the first tag which FUNCTION match within STREAMORBUFFER. FUNCTION must return non-nil if an element of STREAM will be included in the new list. diff --git a/lisp/cedet/semantic/format.el b/lisp/cedet/semantic/format.el index 8927ccde84..a68ef8064d 100644 --- a/lisp/cedet/semantic/format.el +++ b/lisp/cedet/semantic/format.el @@ -1,4 +1,4 @@ -;;; semantic/format.el --- Routines for formatting tags +;;; semantic/format.el --- Routines for formatting tags -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2005, 2007-2021 Free Software Foundation, Inc. @@ -162,7 +162,7 @@ COLOR specifies if color should be used." (car args) nil color 'variable)) out) (setq args (cdr args))) - (mapconcat 'identity (nreverse out) semantic-function-argument-separator) + (mapconcat #'identity (nreverse out) semantic-function-argument-separator) )) ;;; Data Type @@ -200,7 +200,7 @@ Argument COLOR specifies to colorize the text." ;;; Abstract formatting functions ;; -(defun semantic-format-tag-prin1 (tag &optional parent color) +(defun semantic-format-tag-prin1 (tag &optional _parent _color) "Convert TAG to a string that is the print name for TAG. PARENT and COLOR are ignored." (format "%S" tag)) @@ -237,7 +237,7 @@ The name is the shortest possible representation. Optional argument PARENT is the parent type if TAG is a detail. Optional argument COLOR means highlight the prototype with font-lock colors.") -(defun semantic-format-tag-name-default (tag &optional parent color) +(defun semantic-format-tag-name-default (tag &optional _parent color) "Return an abbreviated string describing TAG. Optional argument PARENT is the parent type if TAG is a detail. Optional argument COLOR means highlight the prototype with font-lock colors." @@ -500,7 +500,7 @@ Optional argument COLOR means highlight the prototype with font-lock colors." args (if (eq class 'type) "}" ")")))) (when mods - (setq mods (concat (mapconcat 'identity mods " ") " "))) + (setq mods (concat (mapconcat #'identity mods " ") " "))) (concat (or mods "") (if type (concat type " ")) name diff --git a/lisp/cedet/semantic/fw.el b/lisp/cedet/semantic/fw.el index bdead99d68..2a3b0f5fb7 100644 --- a/lisp/cedet/semantic/fw.el +++ b/lisp/cedet/semantic/fw.el @@ -1,6 +1,6 @@ -;;; semantic/fw.el --- Framework for Semantic +;;; semantic/fw.el --- Framework for Semantic -*- lexical-binding: t; -*- -;;; Copyright (C) 1999-2021 Free Software Foundation, Inc. +;; Copyright (C) 1999-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -34,29 +34,29 @@ ;;; Compatibility ;; -(define-obsolete-function-alias 'semantic-overlay-live-p 'overlay-buffer "27.1") -(define-obsolete-function-alias 'semantic-make-overlay 'make-overlay "27.1") -(define-obsolete-function-alias 'semantic-overlay-put 'overlay-put "27.1") -(define-obsolete-function-alias 'semantic-overlay-get 'overlay-get "27.1") +(define-obsolete-function-alias 'semantic-overlay-live-p #'overlay-buffer "27.1") +(define-obsolete-function-alias 'semantic-make-overlay #'make-overlay "27.1") +(define-obsolete-function-alias 'semantic-overlay-put #'overlay-put "27.1") +(define-obsolete-function-alias 'semantic-overlay-get #'overlay-get "27.1") (define-obsolete-function-alias 'semantic-overlay-properties - 'overlay-properties "27.1") -(define-obsolete-function-alias 'semantic-overlay-move 'move-overlay "27.1") -(define-obsolete-function-alias 'semantic-overlay-delete 'delete-overlay "27.1") -(define-obsolete-function-alias 'semantic-overlays-at 'overlays-at "27.1") -(define-obsolete-function-alias 'semantic-overlays-in 'overlays-in "27.1") -(define-obsolete-function-alias 'semantic-overlay-buffer 'overlay-buffer "27.1") -(define-obsolete-function-alias 'semantic-overlay-start 'overlay-start "27.1") -(define-obsolete-function-alias 'semantic-overlay-end 'overlay-end "27.1") + #'overlay-properties "27.1") +(define-obsolete-function-alias 'semantic-overlay-move #'move-overlay "27.1") +(define-obsolete-function-alias 'semantic-overlay-delete #'delete-overlay "27.1") +(define-obsolete-function-alias 'semantic-overlays-at #'overlays-at "27.1") +(define-obsolete-function-alias 'semantic-overlays-in #'overlays-in "27.1") +(define-obsolete-function-alias 'semantic-overlay-buffer #'overlay-buffer "27.1") +(define-obsolete-function-alias 'semantic-overlay-start #'overlay-start "27.1") +(define-obsolete-function-alias 'semantic-overlay-end #'overlay-end "27.1") (define-obsolete-function-alias 'semantic-overlay-next-change - 'next-overlay-change "27.1") + #'next-overlay-change "27.1") (define-obsolete-function-alias 'semantic-overlay-previous-change - 'previous-overlay-change "27.1") -(define-obsolete-function-alias 'semantic-overlay-lists 'overlay-lists "27.1") -(define-obsolete-function-alias 'semantic-overlay-p 'overlayp "27.1") -(define-obsolete-function-alias 'semantic-read-event 'read-event "27.1") -(define-obsolete-function-alias 'semantic-popup-menu 'popup-menu "27.1") + #'previous-overlay-change "27.1") +(define-obsolete-function-alias 'semantic-overlay-lists #'overlay-lists "27.1") +(define-obsolete-function-alias 'semantic-overlay-p #'overlayp "27.1") +(define-obsolete-function-alias 'semantic-read-event #'read-event "27.1") +(define-obsolete-function-alias 'semantic-popup-menu #'popup-menu "27.1") (define-obsolete-function-alias 'semantic-buffer-local-value - 'buffer-local-value "27.1") + #'buffer-local-value "27.1") (defun semantic-event-window (event) "Extract the window from EVENT." @@ -68,11 +68,11 @@ ;; Since Emacs 22 major mode functions should use `run-mode-hooks' to ;; run major mode hooks. -(define-obsolete-function-alias 'semantic-run-mode-hooks 'run-mode-hooks "28.1") +(define-obsolete-function-alias 'semantic-run-mode-hooks #'run-mode-hooks "28.1") ;; Fancy compat usage now handled in cedet-compat (define-obsolete-function-alias 'semantic-subst-char-in-string - 'subst-char-in-string "28.1") + #'subst-char-in-string "28.1") (defun semantic-delete-overlay-maybe (overlay) "Delete OVERLAY if it is a semantic token overlay." @@ -111,7 +111,7 @@ Possible Lifespans are: (setq semantic-cache-data-overlays (cons o semantic-cache-data-overlays)) ;;(message "Adding to cache: %s" o) - (add-hook 'post-command-hook 'semantic-cache-data-post-command-hook) + (add-hook 'post-command-hook #'semantic-cache-data-post-command-hook) )) (defun semantic-cache-data-post-command-hook () @@ -137,7 +137,7 @@ Remove self from `post-command-hook' if it is empty." ;; Remove ourselves if we have removed all overlays. (unless semantic-cache-data-overlays (remove-hook 'post-command-hook - 'semantic-cache-data-post-command-hook))) + #'semantic-cache-data-post-command-hook))) (defun semantic-get-cache-data (name &optional point) "Get cached data with NAME from optional POINT." @@ -254,7 +254,7 @@ FUNCTION does not have arguments. When FUNCTION is entered `current-buffer' is a selected Semantic enabled buffer." (mode-local-map-file-buffers function #'semantic-active-p)) -(defalias 'semantic-map-mode-buffers 'mode-local-map-mode-buffers) +(defalias 'semantic-map-mode-buffers #'mode-local-map-mode-buffers) (defun semantic-install-function-overrides (overrides &optional transient) "Install the function OVERRIDES in the specified environment. @@ -318,6 +318,12 @@ calling this one." ;;; Special versions of Find File ;; +(defvar recentf-exclude) +(defvar semantic-init-hook) +(defvar ede-auto-add-method) +(defvar flymake-start-syntax-check-on-find-file) +(defvar auto-insert) + (defun semantic-find-file-noselect (file &optional nowarn rawfile wildcards) "Call `find-file-noselect' with various features turned off. Use this when referencing a file that will be soon deleted. diff --git a/lisp/cedet/semantic/html.el b/lisp/cedet/semantic/html.el index 658d218a4a..ad5d2c798f 100644 --- a/lisp/cedet/semantic/html.el +++ b/lisp/cedet/semantic/html.el @@ -1,4 +1,4 @@ -;;; semantic/html.el --- Semantic details for html files +;;; semantic/html.el --- Semantic details for html files -*- lexical-binding: t; -*- ;; Copyright (C) 2004-2005, 2007-2021 Free Software Foundation, Inc. @@ -59,14 +59,14 @@ "Alist of sectioning commands and their relative level.") (define-mode-local-override semantic-parse-region - html-mode (&rest ignore) + html-mode (&rest _ignore) "Parse the current html buffer for semantic tags. IGNORE any arguments. Always parse the whole buffer. Each tag returned is of the form: (\"NAME\" section (:members CHILDREN)) or (\"NAME\" anchor)" - (mapcar 'semantic-html-expand-tag + (mapcar #'semantic-html-expand-tag (semantic-html-parse-headings))) (define-mode-local-override semantic-parse-changes @@ -79,7 +79,7 @@ or (let ((chil (semantic-html-components tag))) (if chil (semantic-tag-put-attribute - tag :members (mapcar 'semantic-html-expand-tag chil))) + tag :members (mapcar #'semantic-html-expand-tag chil))) (car (semantic--tag-expand tag)))) (defun semantic-html-components (tag) @@ -233,7 +233,7 @@ tag with greater section value than LEVEL is found." ;; This will use our parser. (setq semantic-parser-name "HTML" semantic--parse-table t - imenu-create-index-function 'semantic-create-imenu-index + imenu-create-index-function #'semantic-create-imenu-index semantic-command-separation-character ">" semantic-type-relation-separator-character '(":") semantic-symbol->name-assoc-list '((section . "Section") diff --git a/lisp/cedet/semantic/ia-sb.el b/lisp/cedet/semantic/ia-sb.el index b132d41cd4..12a2f1db92 100644 --- a/lisp/cedet/semantic/ia-sb.el +++ b/lisp/cedet/semantic/ia-sb.el @@ -1,7 +1,6 @@ -;;; semantic/ia-sb.el --- Speedbar analysis display interactor +;;; semantic/ia-sb.el --- Speedbar analysis display interactor -*- lexical-binding: t; -*- -;;; Copyright (C) 2002-2004, 2006, 2008-2021 Free Software Foundation, -;;; Inc. +;; Copyright (C) 2002-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: syntax @@ -30,18 +29,14 @@ (require 'speedbar) ;;; Code: -(defvar semantic-ia-sb-key-map nil +(defvar semantic-ia-sb-key-map + (let ((map (speedbar-make-specialized-keymap))) + ;; Basic features. + (define-key map "\C-m" #'speedbar-edit-line) + (define-key map "I" #'semantic-ia-sb-show-tag-info) + map) "Keymap used when in semantic analysis display mode.") -(if semantic-ia-sb-key-map - nil - (setq semantic-ia-sb-key-map (speedbar-make-specialized-keymap)) - - ;; Basic features. - (define-key semantic-ia-sb-key-map "\C-m" 'speedbar-edit-line) - (define-key semantic-ia-sb-key-map "I" 'semantic-ia-sb-show-tag-info) - ) - (defvar semantic-ia-sb-easymenu-definition '( "---" ; [ "Expand" speedbar-expand-line nil ] @@ -75,7 +70,7 @@ list of possible completions." (speedbar-change-initial-expansion-list "Analyze") ) -(defun semantic-ia-speedbar (directory zero) +(defun semantic-ia-speedbar (_directory _zero) "Create buttons in speedbar which define the current analysis at POINT. DIRECTORY is the current directory, which is ignored, and ZERO is 0." (let ((analysis nil) @@ -195,7 +190,7 @@ DIRECTORY is the current directory, which is ignored, and ZERO is 0." ;; An index for the argument the prefix is in: (let ((arg (oref context argument)) (args (semantic-tag-function-arguments (car func))) - (idx 0) + ;; (idx 0) ) (speedbar-insert-separator (format "Argument #%d" (oref context index))) @@ -275,7 +270,7 @@ See `semantic-ia-sb-tag-info' for more." (setq tok (get-text-property (point) 'speedbar-token))) (semantic-ia-sb-tag-info nil tok 0))) -(defun semantic-ia-sb-tag-info (text tag indent) +(defun semantic-ia-sb-tag-info (_text tag _indent) "Display as much information as we can about tag. Show the information in a shrunk split-buffer and expand out as many details as possible. @@ -322,16 +317,15 @@ TEXT, TAG, and INDENT are speedbar function arguments." (get-buffer-window "*Tag Information*"))) (select-frame speedbar-frame)))) -(defun semantic-ia-sb-line-path (&optional depth) +(defun semantic-ia-sb-line-path (&optional _depth) "Return the file name associated with DEPTH." (save-match-data (let* ((tok (speedbar-line-token)) - (buff (if (semantic-tag-buffer tok) - (semantic-tag-buffer tok) - (current-buffer)))) + (buff (or (semantic-tag-buffer tok) + (current-buffer)))) (buffer-file-name buff)))) -(defun semantic-ia-sb-complete (text tag indent) +(defun semantic-ia-sb-complete (_text tag _indent) "At point in the attached buffer, complete the symbol clicked on. TEXT TAG and INDENT are the details." ;; Find the specified bounds from the current analysis. diff --git a/lisp/cedet/semantic/ia.el b/lisp/cedet/semantic/ia.el index 6d3ec7570b..e75bc918e0 100644 --- a/lisp/cedet/semantic/ia.el +++ b/lisp/cedet/semantic/ia.el @@ -1,6 +1,6 @@ -;;; semantic/ia.el --- Interactive Analysis functions +;;; semantic/ia.el --- Interactive Analysis functions -*- lexical-binding: t; -*- -;;; Copyright (C) 2000-2021 Free Software Foundation, Inc. +;; Copyright (C) 2000-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: syntax @@ -79,11 +79,11 @@ (insert "(")) (t nil)))) -(defalias 'semantic-ia-get-completions 'semantic-ia-get-completions-deprecated) +(defalias 'semantic-ia-get-completions #'semantic-ia-get-completions-deprecated) (make-obsolete 'semantic-ia-get-completions #'semantic-analyze-possible-completions "28.1") -(defun semantic-ia-get-completions-deprecated (context point) +(defun semantic-ia-get-completions-deprecated (context _point) "A function to help transition away from `semantic-ia-get-completions'. Return completions based on CONTEXT at POINT." (declare (obsolete semantic-analyze-possible-completions "28.1")) diff --git a/lisp/cedet/semantic/idle.el b/lisp/cedet/semantic/idle.el index 9df9778043..b6633d7ee5 100644 --- a/lisp/cedet/semantic/idle.el +++ b/lisp/cedet/semantic/idle.el @@ -1038,21 +1038,20 @@ be called." (popup-menu semantic-idle-breadcrumbs-popup-menu) (select-window old-window))) -(defmacro semantic-idle-breadcrumbs--tag-function (function) +(defun semantic-idle-breadcrumbs--tag-function (function) "Return lambda expression calling FUNCTION when called from a popup." - `(lambda (event) - (interactive "e") - (let* ((old-window (selected-window)) - (window (semantic-event-window event)) - (column (car (nth 6 (nth 1 event)))) ;; TODO semantic-event-column? - (tag (progn - (select-window window t) - (plist-get - (text-properties-at column header-line-format) - 'tag)))) - (,function tag) - (select-window old-window))) - ) + (lambda (event) + (interactive "e") + (let* ((old-window (selected-window)) + (window (semantic-event-window event)) + (column (car (nth 6 (nth 1 event)))) ;; TODO semantic-event-column? + (tag (progn + (select-window window t) + (plist-get + (text-properties-at column header-line-format) + 'tag)))) + (funcall function tag) + (select-window old-window)))) ;; TODO does this work for mode-line case? (defvar semantic-idle-breadcrumbs-popup-map @@ -1060,8 +1059,7 @@ be called." ;; mouse-1 goes to clicked tag (define-key map [ header-line mouse-1 ] - (semantic-idle-breadcrumbs--tag-function - semantic-go-to-tag)) + (semantic-idle-breadcrumbs--tag-function #'semantic-go-to-tag)) ;; mouse-3 pops up a context menu (define-key map [ header-line mouse-3 ] @@ -1077,8 +1075,7 @@ be called." "Breadcrumb Tag" (vector "Go to Tag" - (semantic-idle-breadcrumbs--tag-function - semantic-go-to-tag) + (semantic-idle-breadcrumbs--tag-function #'semantic-go-to-tag) :active t :help "Jump to this tag") ;; TODO these entries need minor changes (optional tag argument) in @@ -1086,37 +1083,32 @@ be called." ;; (semantic-menu-item ;; (vector ;; "Copy Tag" - ;; (semantic-idle-breadcrumbs--tag-function - ;; senator-copy-tag) + ;; (semantic-idle-breadcrumbs--tag-function #'senator-copy-tag) ;; :active t ;; :help "Copy this tag")) ;; (semantic-menu-item ;; (vector ;; "Kill Tag" - ;; (semantic-idle-breadcrumbs--tag-function - ;; senator-kill-tag) + ;; (semantic-idle-breadcrumbs--tag-function #'senator-kill-tag) ;; :active t ;; :help "Kill tag text to the kill ring, and copy the tag to ;; the tag ring")) ;; (semantic-menu-item ;; (vector ;; "Copy Tag to Register" - ;; (semantic-idle-breadcrumbs--tag-function - ;; senator-copy-tag-to-register) + ;; (semantic-idle-breadcrumbs--tag-function #'senator-copy-tag-to-register) ;; :active t ;; :help "Copy this tag")) ;; (semantic-menu-item ;; (vector ;; "Narrow to Tag" - ;; (semantic-idle-breadcrumbs--tag-function - ;; senator-narrow-to-defun) + ;; (semantic-idle-breadcrumbs--tag-function #'senator-narrow-to-defun) ;; :active t ;; :help "Narrow to the bounds of the current tag")) ;; (semantic-menu-item ;; (vector ;; "Fold Tag" - ;; (semantic-idle-breadcrumbs--tag-function - ;; senator-fold-tag-toggle) + ;; (semantic-idle-breadcrumbs--tag-function #'senator-fold-tag-toggle) ;; :active t ;; :style 'toggle ;; :selected '(let ((tag (semantic-current-tag))) diff --git a/lisp/cedet/semantic/imenu.el b/lisp/cedet/semantic/imenu.el index 4c13959ba1..2c5f10a2c3 100644 --- a/lisp/cedet/semantic/imenu.el +++ b/lisp/cedet/semantic/imenu.el @@ -1,4 +1,4 @@ -;;; semantic/imenu.el --- Use Semantic as an imenu tag generator +;;; semantic/imenu.el --- Use Semantic as an imenu tag generator -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2005, 2007-2008, 2010-2021 Free Software ;; Foundation, Inc. @@ -57,14 +57,12 @@ (defcustom semantic-imenu-summary-function 'semantic-format-tag-abbreviate "Function to use when creating items in Imenu. Some useful functions are found in `semantic-format-tag-functions'." - :group 'semantic-imenu :type semantic-format-tag-custom-list) (make-variable-buffer-local 'semantic-imenu-summary-function) ;;;###autoload (defcustom semantic-imenu-bucketize-file t "Non-nil if tags in a file are to be grouped into buckets." - :group 'semantic-imenu :type 'boolean) (make-variable-buffer-local 'semantic-imenu-bucketize-file) @@ -72,20 +70,17 @@ Some useful functions are found in `semantic-format-tag-functions'." "Non-nil if types in a file should adopt externally defined members. C++ and CLOS can define methods that are not in the body of a class definition." - :group 'semantic-imenu :type 'boolean) (defcustom semantic-imenu-buckets-to-submenu t "Non-nil if buckets of tags are to be turned into submenus. This option is ignored if `semantic-imenu-bucketize-file' is nil." - :group 'semantic-imenu :type 'boolean) (make-variable-buffer-local 'semantic-imenu-buckets-to-submenu) ;;;###autoload (defcustom semantic-imenu-expand-type-members t "Non-nil if types should have submenus with members in them." - :group 'semantic-imenu :type 'boolean) (make-variable-buffer-local 'semantic-imenu-expand-type-members) @@ -93,7 +88,6 @@ This option is ignored if `semantic-imenu-bucketize-file' is nil." "Non-nil if members of a type should be grouped into buckets. A nil value means to keep them in the same order. Overridden to nil if `semantic-imenu-bucketize-file' is nil." - :group 'semantic-imenu :type 'boolean) (make-variable-buffer-local 'semantic-imenu-bucketize-type-members) @@ -101,7 +95,6 @@ Overridden to nil if `semantic-imenu-bucketize-file' is nil." "Function to use when sorting tags in the buckets of functions. See `semantic-bucketize' and the FILTER argument for more details on this function." - :group 'semantic-imenu :type '(radio (const :tag "No Sorting" nil) (const semantic-sort-tags-by-name-increasing) (const semantic-sort-tags-by-name-decreasing) @@ -119,14 +112,12 @@ on this function." Doesn't actually parse the entire directory, but displays tags for all files currently listed in the current Semantic database. This variable has no meaning if semanticdb is not active." - :group 'semantic-imenu :type 'boolean) (defcustom semantic-imenu-auto-rebuild-directory-indexes nil "If non-nil automatically rebuild directory index imenus. That is when a directory index imenu is updated, automatically rebuild other buffer local ones based on the same semanticdb." - :group 'semantic-imenu :type 'boolean) (defvar semantic-imenu-directory-current-file nil @@ -206,7 +197,7 @@ Optional argument REST is some extra stuff." (setq imenu--index-alist nil))))) )) -(defun semantic-imenu-flush-fcn (&optional ignore) +(defun semantic-imenu-flush-fcn (&optional _ignore) "This function is called as a hook to clear the imenu cache. It is cleared after any parsing. IGNORE arguments." @@ -214,9 +205,9 @@ IGNORE arguments." (setq imenu--index-alist nil imenu-menubar-modified-tick 0)) (remove-hook 'semantic-after-toplevel-cache-change-hook - 'semantic-imenu-flush-fcn t) + #'semantic-imenu-flush-fcn t) (remove-hook 'semantic-after-partial-cache-change-hook - 'semantic-imenu-flush-fcn t) + #'semantic-imenu-flush-fcn t) ) ;;;###autoload @@ -224,7 +215,7 @@ IGNORE arguments." "Create an imenu index for any buffer which supports Semantic. Uses the output of the Semantic parser to create the index. Optional argument STREAM is an optional stream of tags used to create menus." - (setq imenu-default-goto-function 'semantic-imenu-goto-function) + (setq imenu-default-goto-function #'semantic-imenu-goto-function) (prog1 (if (and semantic-imenu-index-directory (featurep 'semantic/db) @@ -234,9 +225,9 @@ Optional argument STREAM is an optional stream of tags used to create menus." (semantic-create-imenu-index-1 (or stream (semantic-fetch-tags-fast)) nil)) (add-hook 'semantic-after-toplevel-cache-change-hook - 'semantic-imenu-flush-fcn nil t) + #'semantic-imenu-flush-fcn nil t) (add-hook 'semantic-after-partial-cache-change-hook - 'semantic-imenu-flush-fcn nil t))) + #'semantic-imenu-flush-fcn nil t))) (defun semantic-create-imenu-directory-index (&optional stream) "Create an imenu tag index based on all files active in semanticdb. @@ -445,7 +436,7 @@ Clears all imenu menus that may be depending on the database." ;; Clear imenu cache to redraw the imenu. (semantic-imenu-flush-fcn)))) -(add-hook 'semanticdb-mode-hook 'semantic-imenu-semanticdb-hook) +(add-hook 'semanticdb-mode-hook #'semantic-imenu-semanticdb-hook) ;;; Interactive Utilities ;; @@ -484,7 +475,6 @@ Clears all imenu menus that may be depending on the database." (defcustom semantic-which-function-use-color nil "Use color when displaying the current function with `which-function'." - :group 'semantic-imenu :type 'boolean) (defun semantic-default-which-function (taglist) diff --git a/lisp/cedet/semantic/java.el b/lisp/cedet/semantic/java.el index f60f6e87ab..8cadffa09b 100644 --- a/lisp/cedet/semantic/java.el +++ b/lisp/cedet/semantic/java.el @@ -1,6 +1,6 @@ -;;; semantic/java.el --- Semantic functions for Java +;;; semantic/java.el --- Semantic functions for Java -*- lexical-binding: t; -*- -;;; Copyright (C) 1999-2021 Free Software Foundation, Inc. +;; Copyright (C) 1999-2021 Free Software Foundation, Inc. ;; Author: David Ponce @@ -148,7 +148,7 @@ corresponding compound declaration." (let* ((name (semantic-tag-name tag)) (rsplit (nreverse (split-string name "\\." t))) (newclassname (car rsplit)) - (newpkg (mapconcat 'identity (reverse (cdr rsplit)) "."))) + (newpkg (mapconcat #'identity (reverse (cdr rsplit)) "."))) (semantic-tag-set-name tag newclassname) (setq xpand (list tag @@ -169,7 +169,7 @@ corresponding compound declaration." (define-mode-local-override semantic-ctxt-scoped-types java-mode (&optional point) "Return a list of type names currently in scope at POINT." - (mapcar 'semantic-tag-name + (mapcar #'semantic-tag-name (semantic-find-tags-by-class 'type (semantic-find-tag-by-overlay point)))) @@ -184,7 +184,7 @@ Override function for `semantic-tag-protection'." ;; Prototype handler ;; -(defun semantic-java-prototype-function (tag &optional parent color) +(defun semantic-java-prototype-function (tag &optional _parent color) "Return a function (method) prototype for TAG. Optional argument PARENT is a parent (containing) item. Optional argument COLOR indicates that color should be mixed in. @@ -212,7 +212,7 @@ See also `semantic-format-tag-prototype'." (or type "") (if type " " "") name "(" argp ")"))) -(defun semantic-java-prototype-variable (tag &optional parent color) +(defun semantic-java-prototype-variable (tag &optional _parent color) "Return a variable (field) prototype for TAG. Optional argument PARENT is a parent (containing) item. Optional argument COLOR indicates that color should be mixed in. @@ -227,7 +227,7 @@ See also `semantic-format-tag-prototype'." (semantic--format-colorize-text name 'variable) name)))) -(defun semantic-java-prototype-type (tag &optional parent color) +(defun semantic-java-prototype-type (tag &optional _parent color) "Return a type (class/interface) prototype for TAG. Optional argument PARENT is a parent (containing) item. Optional argument COLOR indicates that color should be mixed in. @@ -260,7 +260,7 @@ Optional argument COLOR indicates that color should be mixed in." (define-mode-local-override semantic-tag-include-filename java-mode (tag) "Return a suitable path for (some) Java imports." (let ((name (semantic-tag-name tag))) - (concat (mapconcat 'identity (split-string name "\\.") "/") ".java"))) + (concat (mapconcat #'identity (split-string name "\\.") "/") ".java"))) ;; Documentation handler ;; @@ -417,15 +417,13 @@ removed from the result list." (or semantic-java-doc-with-name-tags (setq semantic-java-doc-with-name-tags (semantic-java-doc-keywords-map - #'(lambda (k p) - k) + #'(lambda (k _p) k) 'with-name))) (or semantic-java-doc-with-ref-tags (setq semantic-java-doc-with-ref-tags (semantic-java-doc-keywords-map - #'(lambda (k p) - k) + #'(lambda (k _p) k) 'with-ref))) (or semantic-java-doc-extra-type-tags diff --git a/lisp/cedet/semantic/lex-spp.el b/lisp/cedet/semantic/lex-spp.el index 5675b9f3e3..0b24bd2dc4 100644 --- a/lisp/cedet/semantic/lex-spp.el +++ b/lisp/cedet/semantic/lex-spp.el @@ -850,7 +850,7 @@ Argument BEG and END specify the bounds of SYM in the buffer." )) (define-obsolete-function-alias 'semantic-lex-spp-anlyzer-do-replace - 'semantic-lex-spp-analyzer-do-replace "25.1") + #'semantic-lex-spp-analyzer-do-replace "25.1") (defvar semantic-lex-spp-replacements-enabled t "Non-nil means do replacements when finding keywords. @@ -1070,7 +1070,7 @@ and variable state from the current buffer." (semantic-lex-init) (semantic-clear-toplevel-cache) (remove-hook 'semantic-lex-reset-functions - 'semantic-lex-spp-reset-hook t) + #'semantic-lex-spp-reset-hook t) )) ;; Second Cheat: copy key variables regarding macro state from the diff --git a/lisp/cedet/semantic/lex.el b/lisp/cedet/semantic/lex.el index 29d8e29ae6..121e5c333f 100644 --- a/lisp/cedet/semantic/lex.el +++ b/lisp/cedet/semantic/lex.el @@ -469,7 +469,7 @@ PROPERTY set." ;;; Lexical Analyzer framework settings ;; -(defvar-local semantic-lex-analyzer 'semantic-lex +(defvar-local semantic-lex-analyzer #'semantic-lex "The lexical analyzer used for a given buffer. See `semantic-lex' for documentation.") diff --git a/lisp/cedet/semantic/mru-bookmark.el b/lisp/cedet/semantic/mru-bookmark.el index 956eb681f2..2e77e6b75f 100644 --- a/lisp/cedet/semantic/mru-bookmark.el +++ b/lisp/cedet/semantic/mru-bookmark.el @@ -1,4 +1,4 @@ -;;; semantic/mru-bookmark.el --- Automatic bookmark tracking +;;; semantic/mru-bookmark.el --- Automatic bookmark tracking -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. @@ -85,7 +85,7 @@ Nice values include the following: ) "A single bookmark.") -(cl-defmethod initialize-instance :after ((sbm semantic-bookmark) &rest fields) +(cl-defmethod initialize-instance :after ((sbm semantic-bookmark) &rest _fields) "Initialize the bookmark SBM with details about :tag." (condition-case nil (save-excursion @@ -216,7 +216,7 @@ Cause tags in the ring to become unlinked." (setq idx (1+ idx))))) (add-hook 'semantic-before-toplevel-cache-flush-hook - 'semantic-mrub-cache-flush-fcn) + #'semantic-mrub-cache-flush-fcn) ;;; EDIT tracker ;; @@ -246,8 +246,8 @@ been edited, and you can re-visit them with \\[semantic-mrub-switch-tags]." :group 'semantic-modes :type 'boolean :require 'semantic/util-modes - :initialize 'custom-initialize-default - :set (lambda (sym val) + :initialize #'custom-initialize-default + :set (lambda (_sym val) (global-semantic-mru-bookmark-mode (if val 1 -1)))) ;;;###autoload @@ -266,7 +266,7 @@ been edited, and you can re-visit them with \\[semantic-mrub-switch-tags]." (defvar semantic-mru-bookmark-mode-map (let ((km (make-sparse-keymap))) - (define-key km "\C-xB" 'semantic-mrub-switch-tags) + (define-key km "\C-xB" #'semantic-mrub-switch-tags) km) "Keymap for mru-bookmark minor mode.") @@ -289,14 +289,14 @@ non-nil if the minor mode is enabled." (error "Buffer %s was not set up for parsing" (buffer-name))) (add-hook 'semantic-edits-new-change-functions - 'semantic-mru-bookmark-change-hook-fcn nil t) + #'semantic-mru-bookmark-change-hook-fcn nil t) (add-hook 'semantic-edits-move-change-hooks - 'semantic-mru-bookmark-change-hook-fcn nil t)) + #'semantic-mru-bookmark-change-hook-fcn nil t)) ;; Remove hooks (remove-hook 'semantic-edits-new-change-functions - 'semantic-mru-bookmark-change-hook-fcn t) + #'semantic-mru-bookmark-change-hook-fcn t) (remove-hook 'semantic-edits-move-change-hooks - 'semantic-mru-bookmark-change-hook-fcn t))) + #'semantic-mru-bookmark-change-hook-fcn t))) (semantic-add-minor-mode 'semantic-mru-bookmark-mode "k") diff --git a/lisp/cedet/semantic/senator.el b/lisp/cedet/semantic/senator.el index f33356a170..19530094fb 100644 --- a/lisp/cedet/semantic/senator.el +++ b/lisp/cedet/semantic/senator.el @@ -1,4 +1,4 @@ -;;; semantic/senator.el --- SEmantic NAvigaTOR +;;; semantic/senator.el --- SEmantic NAvigaTOR -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. @@ -60,7 +60,6 @@ A tag class is a symbol, such as `variable', `function', or `type'. As a special exception, if the value is nil, Senator's navigation commands recognize all tag classes." - :group 'senator :type '(repeat (symbol))) ;;;###autoload (make-variable-buffer-local 'senator-step-at-tag-classes) @@ -78,7 +77,6 @@ commands stop at the beginning of every tag. If t, the navigation commands stop at the start and end of any tag, where possible." - :group 'senator :type '(choice :tag "Identifiers" (repeat :menu-tag "Symbols" (symbol)) (const :tag "All" t))) @@ -87,7 +85,6 @@ tag, where possible." (defcustom senator-highlight-found nil "If non-nil, Senator commands momentarily highlight found tags." - :group 'senator :type 'boolean) (make-variable-buffer-local 'senator-highlight-found) @@ -193,7 +190,6 @@ source." '(code block) "List of ignored tag classes. Tags of those classes are excluded from search." - :group 'senator :type '(repeat (symbol :tag "class"))) (defun senator-search-default-tag-filter (tag) @@ -461,7 +457,7 @@ filters in `senator-search-tag-filter-functions' remain active." ((symbolp classes) (list classes)) ((stringp classes) - (mapcar 'read (split-string classes))) + (mapcar #'read (split-string classes))) (t (signal 'wrong-type-argument (list classes))) )) @@ -470,11 +466,10 @@ filters in `senator-search-tag-filter-functions' remain active." senator--search-filter t) (kill-local-variable 'senator--search-filter) (if classes - (let ((tag (make-symbol "tag")) - (names (mapconcat 'symbol-name classes "', `"))) + (let ((names (mapconcat #'symbol-name classes "', `"))) (setq-local senator--search-filter - `(lambda (,tag) - (memq (semantic-tag-class ,tag) ',classes))) + (lambda (tag) + (memq (semantic-tag-class tag) classes))) (add-hook 'senator-search-tag-filter-functions senator--search-filter nil t) (message "Limit search to `%s' tags" names)) @@ -605,7 +600,7 @@ Makes C/C++ language like assumptions." "Non-nil if isearch does semantic search. This is a buffer local variable.") -(defun senator-beginning-of-defun (&optional arg) +(defun senator-beginning-of-defun (&optional _arg) "Move backward to the beginning of a defun. Use semantic tags to navigate. ARG is the number of tags to navigate (not yet implemented)." @@ -620,7 +615,7 @@ ARG is the number of tags to navigate (not yet implemented)." (goto-char (semantic-tag-start tag))) (beginning-of-line)))) -(defun senator-end-of-defun (&optional arg) +(defun senator-end-of-defun (&optional _arg) "Move forward to next end of defun. Use semantic tags to navigate. ARG is the number of tags to navigate (not yet implemented)." @@ -859,7 +854,7 @@ Use a senator search function when semantic isearch mode is enabled." (setq-local senator-old-isearch-search-fun isearch-search-fun-function)) (setq-local isearch-search-fun-function - 'senator-isearch-search-fun)) + #'senator-isearch-search-fun)) ;; When `senator-isearch-semantic-mode' is off restore the ;; previous `isearch-search-fun-function'. (when (eq isearch-search-fun-function 'senator-isearch-search-fun) diff --git a/lisp/cedet/semantic/sort.el b/lisp/cedet/semantic/sort.el index 19f46ff7f1..b4b09dc02c 100644 --- a/lisp/cedet/semantic/sort.el +++ b/lisp/cedet/semantic/sort.el @@ -1,6 +1,6 @@ -;;; semantic/sort.el --- Utilities for sorting and re-arranging tag tables. +;;; semantic/sort.el --- Utilities for sorting and re-arranging tag tables. -*- lexical-binding: t; -*- -;;; Copyright (C) 1999-2005, 2007-2021 Free Software Foundation, Inc. +;; Copyright (C) 1999-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: syntax @@ -233,8 +233,7 @@ unmodified as components of their parent tags." (semantic-flatten-tags-table components) lists))))) table) - (apply 'append (nreverse lists)) - )) + (apply #'append (nreverse lists)))) ;;; Buckets: @@ -520,12 +519,11 @@ See `semantic-tag-external-member-children' for details." (semantic-tag-name tag) tag))) (if m (apply #'append (mapcar #'cdr m)))) (semantic--find-tags-by-function - `(lambda (tok) - ;; This bit of annoying backquote forces the contents of - ;; tag into the generated lambda. - (semantic-tag-external-member-p ',tag tok)) - (current-buffer)) - )) + (lambda (tok) + ;; This bit of annoying backquote forces the contents of + ;; tag into the generated lambda. + (semantic-tag-external-member-p tag tok)) + (current-buffer)))) (define-overloadable-function semantic-tag-external-class (tag) "Return a list of real tags that faux TAG might represent. @@ -540,6 +538,8 @@ likely derived, then this function is needed." (:override) ) +(defvar semanticdb-search-system-databases) + (defun semantic-tag-external-class-default (tag) "Return a list of real tags that faux TAG might represent. See `semantic-tag-external-class' for details." diff --git a/lisp/cedet/semantic/symref.el b/lisp/cedet/semantic/symref.el index d7f91573d3..701f9ad3e0 100644 --- a/lisp/cedet/semantic/symref.el +++ b/lisp/cedet/semantic/symref.el @@ -1,4 +1,4 @@ -;;; semantic/symref.el --- Symbol Reference API +;;; semantic/symref.el --- Symbol Reference API -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -144,7 +144,7 @@ ARGS are the initialization arguments to pass to the created class." ) (when (not (class-p class)) (error "Unknown symref tool %s" semantic-symref-tool)) - (setq inst (apply 'make-instance class args)) + (setq inst (apply #'make-instance class args)) inst)) (defvar semantic-symref-last-result nil @@ -427,7 +427,7 @@ until the next command is executed." (kill-buffer buff))) semantic-symref-recently-opened-buffers) (setq semantic-symref-recently-opened-buffers nil) - (remove-hook 'post-command-hook 'semantic-symref-cleanup-recent-buffers-fcn) + (remove-hook 'post-command-hook #'semantic-symref-cleanup-recent-buffers-fcn) ) (cl-defmethod semantic-symref-result-get-tags ((result semantic-symref-result) @@ -453,7 +453,7 @@ already." lines))) ;; Kill off dead buffers, unless we were requested to leave them open. (if (not open-buffers) - (add-hook 'post-command-hook 'semantic-symref-cleanup-recent-buffers-fcn) + (add-hook 'post-command-hook #'semantic-symref-cleanup-recent-buffers-fcn) ;; Else, just clear the saved buffers so they aren't deleted later. (setq semantic-symref-recently-opened-buffers nil) ) diff --git a/lisp/cedet/semantic/symref/list.el b/lisp/cedet/semantic/symref/list.el index 50d2e2b1c3..2e447bbc58 100644 --- a/lisp/cedet/semantic/symref/list.el +++ b/lisp/cedet/semantic/symref/list.el @@ -108,20 +108,20 @@ Display the references in `semantic-symref-results-mode'." (defvar semantic-symref-results-mode-map (let ((km (make-sparse-keymap))) (suppress-keymap km) - (define-key km "\C-i" 'forward-button) - (define-key km "\M-C-i" 'backward-button) - (define-key km " " 'push-button) - (define-key km "-" 'semantic-symref-list-toggle-showing) - (define-key km "=" 'semantic-symref-list-toggle-showing) - (define-key km "+" 'semantic-symref-list-toggle-showing) - (define-key km "n" 'semantic-symref-list-next-line) - (define-key km "p" 'semantic-symref-list-prev-line) - (define-key km "q" 'quit-window) - (define-key km "\C-c\C-e" 'semantic-symref-list-expand-all) - (define-key km "\C-c\C-r" 'semantic-symref-list-contract-all) - (define-key km "R" 'semantic-symref-list-rename-open-hits) - (define-key km "(" 'semantic-symref-list-create-macro-on-open-hit) - (define-key km "E" 'semantic-symref-list-call-macro-on-open-hits) + (define-key km "\C-i" #'forward-button) + (define-key km "\M-C-i" #'backward-button) + (define-key km " " #'push-button) + (define-key km "-" #'semantic-symref-list-toggle-showing) + (define-key km "=" #'semantic-symref-list-toggle-showing) + (define-key km "+" #'semantic-symref-list-toggle-showing) + (define-key km "n" #'semantic-symref-list-next-line) + (define-key km "p" #'semantic-symref-list-prev-line) + (define-key km "q" #'quit-window) + (define-key km "\C-c\C-e" #'semantic-symref-list-expand-all) + (define-key km "\C-c\C-r" #'semantic-symref-list-contract-all) + (define-key km "R" #'semantic-symref-list-rename-open-hits) + (define-key km "(" #'semantic-symref-list-create-macro-on-open-hit) + (define-key km "E" #'semantic-symref-list-call-macro-on-open-hits) km) "Keymap used in `semantic-symref-results-mode'.") diff --git a/lisp/cedet/semantic/tag-file.el b/lisp/cedet/semantic/tag-file.el index fc5c27752a..06dd274b32 100644 --- a/lisp/cedet/semantic/tag-file.el +++ b/lisp/cedet/semantic/tag-file.el @@ -1,4 +1,4 @@ -;;; semantic/tag-file.el --- Routines that find files based on tags. +;;; semantic/tag-file.el --- Routines that find files based on tags. -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2005, 2007-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/semantic/tag-ls.el b/lisp/cedet/semantic/tag-ls.el index 6cef603af3..3aa1a62901 100644 --- a/lisp/cedet/semantic/tag-ls.el +++ b/lisp/cedet/semantic/tag-ls.el @@ -1,4 +1,4 @@ -;;; semantic/tag-ls.el --- Language Specific override functions for tags +;;; semantic/tag-ls.el --- Language Specific override functions for tags -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2004, 2006-2021 Free Software Foundation, Inc. @@ -97,7 +97,7 @@ Modes that override this function can call `semantic--tag-attribute-similar-p-default' to do the default equality tests if ATTR is not special for that mode.") -(defun semantic--tag-attribute-similar-p-default (attr value1 value2 ignorable-attributes) +(defun semantic--tag-attribute-similar-p-default (_attr value1 value2 ignorable-attributes) "For ATTR, VALUE1, VALUE2 and IGNORABLE-ATTRIBUTES, test for similarity." (cond ;; Tag sublists require special testing. @@ -109,7 +109,7 @@ ATTR is not special for that mode.") (when (not (eq (length taglist1) (length taglist2))) (setq ans nil)) (while (and ans taglist1 taglist2) - (setq ans (apply 'semantic-tag-similar-p + (setq ans (apply #'semantic-tag-similar-p (car taglist1) (car taglist2) ignorable-attributes) taglist1 (cdr taglist1) @@ -205,7 +205,7 @@ stream for a tag of class `package', and return that." (or stream-or-buffer tag)))) (:override-with-args (tag stream)))) -(defun semantic-tag-full-package-default (tag stream) +(defun semantic-tag-full-package-default (_tag stream) "Default method for `semantic-tag-full-package' for TAG. Return the name of the first tag of class `package' in STREAM." (let ((pack (car-safe (semantic-find-tags-by-class 'package stream)))) @@ -285,7 +285,7 @@ is to return a symbol based on type modifiers." (setq parent (semantic-tag-calculate-parent tag))) (:override)) -(defun semantic-tag-protection-default (tag &optional parent) +(defun semantic-tag-protection-default (tag &optional _parent) "Return the protection of TAG as a child of PARENT default action. See `semantic-tag-protection'." (let ((mods (semantic-tag-modifiers tag)) @@ -295,9 +295,7 @@ See `semantic-tag-protection'." (let ((s (car mods))) (setq prot ;; A few silly defaults to get things started. - (cond ((or (string= s "public") - (string= s "extern") - (string= s "export")) + (cond ((member s '("public" "extern" "export")) 'public) ((string= s "private") 'private) @@ -372,15 +370,14 @@ in how methods are overridden. In UML, abstract methods are italicized. The default behavior (if not overridden with `tag-abstract-p' is to return true if `abstract' is in the type modifiers.") -(defun semantic-tag-abstract-p-default (tag &optional parent) +(defun semantic-tag-abstract-p-default (tag &optional _parent) "Return non-nil if TAG is abstract as a child of PARENT default action. See `semantic-tag-abstract-p'." (let ((mods (semantic-tag-modifiers tag)) (abs nil)) (while (and (not abs) mods) (if (stringp (car mods)) - (setq abs (or (string= (car mods) "abstract") - (string= (car mods) "virtual")))) + (setq abs (member (car mods) '("abstract" "virtual")))) (setq mods (cdr mods))) abs)) @@ -392,7 +389,7 @@ In UML, leaf methods and classes have special meaning and behavior. The default behavior (if not overridden with `tag-leaf-p' is to return true if `leaf' is in the type modifiers.") -(defun semantic-tag-leaf-p-default (tag &optional parent) +(defun semantic-tag-leaf-p-default (tag &optional _parent) "Return non-nil if TAG is leaf as a child of PARENT default action. See `semantic-tag-leaf-p'." (let ((mods (semantic-tag-modifiers tag)) @@ -412,7 +409,7 @@ In UML, static methods and attributes mean that they are allocated in the parent class, and are not instance specific. UML notation specifies that STATIC entries are underlined.") -(defun semantic-tag-static-p-default (tag &optional parent) +(defun semantic-tag-static-p-default (tag &optional _parent) "Return non-nil if TAG is static as a child of PARENT default action. See `semantic-tag-static-p'." (let ((mods (semantic-tag-modifiers tag)) diff --git a/lisp/cedet/semantic/tag-write.el b/lisp/cedet/semantic/tag-write.el index f705c89c90..9d5aeea098 100644 --- a/lisp/cedet/semantic/tag-write.el +++ b/lisp/cedet/semantic/tag-write.el @@ -1,4 +1,4 @@ -;;; semantic/tag-write.el --- Write tags to a text stream +;;; semantic/tag-write.el --- Write tags to a text stream -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -88,7 +88,7 @@ INDENT is the amount of indentation to use for this tag." (if (semantic-tag-with-position-p tag) (let ((bounds (semantic-tag-bounds tag))) (princ " ") - (prin1 (apply 'vector bounds)) + (prin1 (apply #'vector bounds)) ) (princ " nil")) ;; End it. diff --git a/lisp/cedet/semantic/tag.el b/lisp/cedet/semantic/tag.el index a99e2ab279..b6386d71db 100644 --- a/lisp/cedet/semantic/tag.el +++ b/lisp/cedet/semantic/tag.el @@ -478,7 +478,7 @@ TYPE is a string or semantic tag representing the type of this variable. Optional DEFAULT-VALUE is a string representing the default value of this variable. ATTRIBUTES is a list of additional attributes belonging to this tag." - (apply 'semantic-tag name 'variable + (apply #'semantic-tag name 'variable :type type :default-value default-value attributes)) @@ -490,7 +490,7 @@ TYPE is a string or semantic tag representing the type of this function. ARG-LIST is a list of strings or semantic tags representing the arguments of this function. ATTRIBUTES is a list of additional attributes belonging to this tag." - (apply 'semantic-tag name 'function + (apply #'semantic-tag name 'function :type type :arguments arg-list attributes)) @@ -513,7 +513,7 @@ This slot can be interesting because the form: is a valid parent where there is no explicit parent, and only an interface. ATTRIBUTES is a list of additional attributes belonging to this tag." - (apply 'semantic-tag name 'type + (apply #'semantic-tag name 'type :type type :members members :superclasses (car parents) @@ -526,7 +526,7 @@ NAME is the name of this include. SYSTEM-FLAG represents that we were able to identify this include as belonging to the system, as opposed to belonging to the local project. ATTRIBUTES is a list of additional attributes belonging to this tag." - (apply 'semantic-tag name 'include + (apply #'semantic-tag name 'include :system-flag system-flag attributes)) @@ -536,7 +536,7 @@ NAME is the name of this package. DETAIL is extra information about this package, such as a location where it can be found. ATTRIBUTES is a list of additional attributes belonging to this tag." - (apply 'semantic-tag name 'package + (apply #'semantic-tag name 'package :detail detail attributes)) @@ -545,7 +545,7 @@ ATTRIBUTES is a list of additional attributes belonging to this tag." NAME is a name for this code. DETAIL is extra information about the code. ATTRIBUTES is a list of additional attributes belonging to this tag." - (apply 'semantic-tag name 'code + (apply #'semantic-tag name 'code :detail detail attributes)) @@ -685,7 +685,7 @@ FILTER takes TAG as an argument, and should return a `semantic-tag'. It is safe for FILTER to modify the input tag and return it." (when (not filter) (setq filter 'identity)) (when (not (semantic-tag-p tag)) - (signal 'wrong-type-argument (list tag 'semantic-tag-p))) + (signal 'wrong-type-argument (list tag #'semantic-tag-p))) (let ((ol (semantic-tag-overlay tag)) (fn (semantic-tag-file-name tag))) (funcall filter (list (semantic-tag-name tag) @@ -937,7 +937,7 @@ NAME is a name for this alias. META-TAG-CLASS is the class of the tag this tag is an alias. VALUE is the aliased definition. ATTRIBUTES is a list of additional attributes belonging to this tag." - (apply 'semantic-tag name 'alias + (apply #'semantic-tag name 'alias :aliasclass meta-tag-class :definition value attributes)) @@ -1093,7 +1093,7 @@ For any given situation, additional ARGS may be passed." (condition-case err ;; If a hook bombs, ignore it! Usually this is tied into ;; some sort of critical system. - (apply 'run-hook-with-args 'semantic--tag-hook-value arglist) + (apply #'run-hook-with-args 'semantic--tag-hook-value arglist) (error (message "Error: %S" err))))) ;;; Tags and Overlays @@ -1104,7 +1104,7 @@ For any given situation, additional ARGS may be passed." (defsubst semantic--tag-unlink-list-from-buffer (tags) "Convert TAGS from using an overlay to using an overlay proxy. This function is for internal use only." - (mapcar 'semantic--tag-unlink-from-buffer tags)) + (mapcar #'semantic--tag-unlink-from-buffer tags)) (defun semantic--tag-unlink-from-buffer (tag) "Convert TAG from using an overlay to using an overlay proxy. @@ -1125,7 +1125,7 @@ This function is for internal use only." (defsubst semantic--tag-link-list-to-buffer (tags) "Convert TAGS from using an overlay proxy to using an overlay. This function is for internal use only." - (mapc 'semantic--tag-link-to-buffer tags)) + (mapc #'semantic--tag-link-to-buffer tags)) (defun semantic--tag-link-to-buffer (tag) "Convert TAG from using an overlay proxy to using an overlay. diff --git a/lisp/cedet/semantic/texi.el b/lisp/cedet/semantic/texi.el index 377cec5455..5a38280d2a 100644 --- a/lisp/cedet/semantic/texi.el +++ b/lisp/cedet/semantic/texi.el @@ -1,4 +1,4 @@ -;;; semantic/texi.el --- Semantic details for Texinfo files +;;; semantic/texi.el --- Semantic details for Texinfo files -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2005, 2007-2021 Free Software Foundation, Inc. @@ -55,7 +55,7 @@ The field position is the field number (based at 1) where the name of this section is.") ;;; Code: -(defun semantic-texi-parse-region (&rest ignore) +(defun semantic-texi-parse-region (&rest _ignore) "Parse the current texinfo buffer for semantic tags. IGNORE any arguments, always parse the whole buffer. Each tag returned is of the form: @@ -79,7 +79,7 @@ function `semantic-install-function-overrides'." (let ((chil (semantic-tag-components tag))) (if chil (semantic-tag-put-attribute - tag :members (mapcar 'semantic-texi-expand-tag chil))) + tag :members (mapcar #'semantic-texi-expand-tag chil))) (car (semantic--tag-expand tag)))) (defun semantic-texi-parse-headings () @@ -297,7 +297,7 @@ can handle the @menu environment.") nil)) (define-mode-local-override semantic-ctxt-current-class-list - texinfo-mode (&optional point) + texinfo-mode (&optional _point) "Determine the class of tags that can be used at POINT. For texinfo, there two possibilities returned. 1) `function' - for a call to a texinfo function @@ -368,7 +368,7 @@ Optional argument POINT is where to look for the environment." (declare-function semantic-analyze-context "semantic/analyze") (define-mode-local-override semantic-analyze-current-context - texinfo-mode (point) + texinfo-mode (_point) "Analysis context makes no sense for texinfo. Return nil." (let* ((prefixandbounds (semantic-ctxt-current-symbol-and-bounds (point))) (prefix (car prefixandbounds)) @@ -408,7 +408,7 @@ Optional argument POINT is where to look for the environment." "List of commands that we might bother completing.") (define-mode-local-override semantic-analyze-possible-completions - texinfo-mode (context &rest flags) + texinfo-mode (context &rest _flags) "List smart completions at point. Since texinfo is not a programming language the default version is not useful. Instead, look at the current symbol. If it is a command @@ -451,7 +451,7 @@ that start with that symbol." (setq semantic-parser-name "TEXI" ;; Setup a dummy parser table to enable parsing! semantic--parse-table t - imenu-create-index-function 'semantic-create-imenu-index + imenu-create-index-function #'semantic-create-imenu-index semantic-command-separation-character "@" semantic-type-relation-separator-character '(":") semantic-symbol->name-assoc-list '((section . "Section") @@ -466,7 +466,7 @@ that start with that symbol." ;; (local-set-key [(f9)] 'semantic-texi-update-doc-from-texi) ) -(add-hook 'texinfo-mode-hook 'semantic-default-texi-setup) +(add-hook 'texinfo-mode-hook #'semantic-default-texi-setup) ;;; Special features of Texinfo tag streams @@ -500,7 +500,7 @@ that start with that symbol." ;; Turns out this might not be useful. ;; Delete later if that is true. -(defun semantic-texi-find-documentation (name &optional type) +(defun semantic-texi-find-documentation (name &optional _type) "Find the function or variable NAME of TYPE in the texinfo source. NAME is a string representing some functional symbol. TYPE is a string, such as \"variable\" or \"Command\" used to find diff --git a/lisp/cedet/semantic/util-modes.el b/lisp/cedet/semantic/util-modes.el index 0de66d29e3..a02d5667ef 100644 --- a/lisp/cedet/semantic/util-modes.el +++ b/lisp/cedet/semantic/util-modes.el @@ -1,4 +1,4 @@ -;;; semantic/util-modes.el --- Semantic minor modes +;;; semantic/util-modes.el --- Semantic minor modes -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2005, 2007-2021 Free Software Foundation, Inc. @@ -48,7 +48,7 @@ line." :group 'semantic :type 'boolean :require 'semantic/util-modes - :initialize 'custom-initialize-default + :initialize #'custom-initialize-default :set (lambda (sym val) (set-default sym val) ;; Update status of all Semantic enabled buffers @@ -60,7 +60,7 @@ line." :group 'semantic :type 'string :require 'semantic/util-modes - :initialize 'custom-initialize-default) + :initialize #'custom-initialize-default) (defvar semantic-minor-modes-format nil "Mode line format showing Semantic minor modes which are locally enabled. @@ -93,7 +93,7 @@ Only minor modes that are locally enabled are shown in the mode line." (match-string 1 semantic-mode-line-prefix) "S"))) (setq semantic-minor-modes-format - `((:eval (if (or ,@(mapcar 'car locals)) + `((:eval (if (or ,@(mapcar #'car locals)) ,(concat " " prefix))))) ;; It would be easier to just put `locals' inside ;; semantic-minor-modes-format, but then things like @@ -111,7 +111,7 @@ Only minor modes that are locally enabled are shown in the mode line." (cons elem minor-mode-alist))))) (setcdr tail (nconc locals (cdr tail))))))))) -(defun semantic-desktop-ignore-this-minor-mode (buffer) +(defun semantic-desktop-ignore-this-minor-mode (_buffer) "Installed as a minor-mode initializer for Desktop mode. BUFFER is the buffer to not initialize a Semantic minor mode in." nil) @@ -221,10 +221,10 @@ non-nil if the minor mode is enabled." (error "Buffer %s was not set up for parsing" (buffer-name))) (add-hook 'semantic-edits-new-change-functions - 'semantic-highlight-edits-new-change-hook-fcn nil t)) + #'semantic-highlight-edits-new-change-hook-fcn nil t)) ;; Remove hooks (remove-hook 'semantic-edits-new-change-functions - 'semantic-highlight-edits-new-change-hook-fcn t))) + #'semantic-highlight-edits-new-change-hook-fcn t))) (semantic-add-minor-mode 'semantic-highlight-edits-mode "e") @@ -345,7 +345,7 @@ Do not search past BOUND if non-nil." (defvar semantic-show-unmatched-syntax-mode-map (let ((km (make-sparse-keymap))) - (define-key km "\C-c,`" 'semantic-show-unmatched-syntax-next) + (define-key km "\C-c,`" #'semantic-show-unmatched-syntax-next) km) "Keymap for command `semantic-show-unmatched-syntax-mode'.") @@ -372,18 +372,18 @@ non-nil if the minor mode is enabled. (buffer-name))) ;; Add hooks (add-hook 'semantic-unmatched-syntax-hook - 'semantic-show-unmatched-syntax nil t) + #'semantic-show-unmatched-syntax nil t) (add-hook 'semantic-pre-clean-token-hooks - 'semantic-clean-token-of-unmatched-syntax nil t) + #'semantic-clean-token-of-unmatched-syntax nil t) ;; Show unmatched syntax elements (if (not (semantic--umatched-syntax-needs-refresh-p)) (semantic-show-unmatched-syntax (semantic-unmatched-syntax-tokens)))) ;; Remove hooks (remove-hook 'semantic-unmatched-syntax-hook - 'semantic-show-unmatched-syntax t) + #'semantic-show-unmatched-syntax t) (remove-hook 'semantic-pre-clean-token-hooks - 'semantic-clean-token-of-unmatched-syntax t) + #'semantic-clean-token-of-unmatched-syntax t) ;; Cleanup unmatched-syntax highlighting (semantic-clean-unmatched-syntax-in-buffer))) @@ -454,46 +454,46 @@ non-nil if the minor mode is enabled." '(semantic-show-parser-state-string)))) ;; Add hooks (add-hook 'semantic-edits-new-change-functions - 'semantic-show-parser-state-marker nil t) + #'semantic-show-parser-state-marker nil t) (add-hook 'semantic-edits-incremental-reparse-failed-hook - 'semantic-show-parser-state-marker nil t) + #'semantic-show-parser-state-marker nil t) (add-hook 'semantic-after-partial-cache-change-hook - 'semantic-show-parser-state-marker nil t) + #'semantic-show-parser-state-marker nil t) (add-hook 'semantic-after-toplevel-cache-change-hook - 'semantic-show-parser-state-marker nil t) + #'semantic-show-parser-state-marker nil t) (semantic-show-parser-state-marker) (add-hook 'semantic-before-auto-parse-hooks - 'semantic-show-parser-state-auto-marker nil t) + #'semantic-show-parser-state-auto-marker nil t) (add-hook 'semantic-after-auto-parse-hooks - 'semantic-show-parser-state-marker nil t) + #'semantic-show-parser-state-marker nil t) (add-hook 'semantic-before-idle-scheduler-reparse-hook - 'semantic-show-parser-state-auto-marker nil t) + #'semantic-show-parser-state-auto-marker nil t) (add-hook 'semantic-after-idle-scheduler-reparse-hook - 'semantic-show-parser-state-marker nil t)) + #'semantic-show-parser-state-marker nil t)) ;; Remove parts of mode line (setq mode-line-modified (delq 'semantic-show-parser-state-string mode-line-modified)) ;; Remove hooks (remove-hook 'semantic-edits-new-change-functions - 'semantic-show-parser-state-marker t) + #'semantic-show-parser-state-marker t) (remove-hook 'semantic-edits-incremental-reparse-failed-hook - 'semantic-show-parser-state-marker t) + #'semantic-show-parser-state-marker t) (remove-hook 'semantic-after-partial-cache-change-hook - 'semantic-show-parser-state-marker t) + #'semantic-show-parser-state-marker t) (remove-hook 'semantic-after-toplevel-cache-change-hook - 'semantic-show-parser-state-marker t) + #'semantic-show-parser-state-marker t) (remove-hook 'semantic-before-auto-parse-hooks - 'semantic-show-parser-state-auto-marker t) + #'semantic-show-parser-state-auto-marker t) (remove-hook 'semantic-after-auto-parse-hooks - 'semantic-show-parser-state-marker t) + #'semantic-show-parser-state-marker t) (remove-hook 'semantic-before-idle-scheduler-reparse-hook - 'semantic-show-parser-state-auto-marker t) + #'semantic-show-parser-state-auto-marker t) (remove-hook 'semantic-after-idle-scheduler-reparse-hook - 'semantic-show-parser-state-marker t))) + #'semantic-show-parser-state-marker t))) (semantic-add-minor-mode 'semantic-show-parser-state-mode "") @@ -502,7 +502,7 @@ non-nil if the minor mode is enabled." "String showing the parser state for this buffer. See `semantic-show-parser-state-marker' for details.") -(defun semantic-show-parser-state-marker (&rest ignore) +(defun semantic-show-parser-state-marker (&rest _ignore) "Set `semantic-show-parser-state-string' to indicate parser state. This marker is one of the following: `-' -> The cache is up to date. @@ -555,7 +555,7 @@ to indicate a parse in progress." (defvar semantic-stickyfunc-mode-map (let ((km (make-sparse-keymap))) - (define-key km [ header-line down-mouse-1 ] 'semantic-stickyfunc-menu) + (define-key km [ header-line down-mouse-1 ] #'semantic-stickyfunc-menu) km) "Keymap for stickyfunc minor mode.") @@ -826,7 +826,7 @@ Argument EVENT describes the event that caused this function to be called." (defvar semantic-highlight-func-mode-map (let ((km (make-sparse-keymap))) - (define-key km [mouse-3] 'semantic-highlight-func-menu) + (define-key km [mouse-3] #'semantic-highlight-func-menu) km) "Keymap for highlight-func minor mode.") @@ -916,10 +916,10 @@ non-nil if the minor mode is enabled." (error "Buffer %s was not set up for parsing" (buffer-name))) ;; Setup our hook (add-hook 'post-command-hook - 'semantic-highlight-func-highlight-current-tag nil t)) + #'semantic-highlight-func-highlight-current-tag nil t)) ;; Disable highlight func mode (remove-hook 'post-command-hook - 'semantic-highlight-func-highlight-current-tag t) + #'semantic-highlight-func-highlight-current-tag t) (semantic-highlight-func-highlight-current-tag t))) (defun semantic-highlight-func-highlight-current-tag (&optional disable) diff --git a/lisp/cedet/semantic/util.el b/lisp/cedet/semantic/util.el index 8c487e14ed..bfc923c75b 100644 --- a/lisp/cedet/semantic/util.el +++ b/lisp/cedet/semantic/util.el @@ -1,6 +1,6 @@ -;;; semantic/util.el --- Utilities for use with semantic tag tables +;;; semantic/util.el --- Utilities for use with semantic tag tables -*- lexical-binding: t; -*- -;;; Copyright (C) 1999-2005, 2007-2021 Free Software Foundation, Inc. +;; Copyright (C) 1999-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: syntax @@ -114,7 +114,10 @@ buffer, or a filename. If SOMETHING is nil return nil." ((and (featurep 'semantic/db) (require 'semantic/db-mode) (semanticdb-minor-mode-p) - (cl-typep something 'semanticdb-abstract-table)) + (progn + (declare-function semanticdb-abstract-table--eieio-childp + "semantic/db") + (cl-typep something 'semanticdb-abstract-table))) (semanticdb-refresh-table something) (semanticdb-get-tags something)) ;; Semanticdb find-results @@ -427,7 +430,7 @@ determining which symbols are considered." (setq completion (try-completion pattern collection predicate)) (if (string= pattern completion) (let ((list (all-completions pattern collection predicate))) - (setq list (sort list 'string<)) + (setq list (sort list #'string<)) (if (> (length list) 1) (with-output-to-temp-buffer "*Completions*" (display-completion-list diff --git a/lisp/cedet/semantic/wisent/comp.el b/lisp/cedet/semantic/wisent/comp.el index ae0823e669..6addc134ed 100644 --- a/lisp/cedet/semantic/wisent/comp.el +++ b/lisp/cedet/semantic/wisent/comp.el @@ -3450,7 +3450,7 @@ Automatically called by the Emacs Lisp byte compiler as a `byte-compile' handler." (byte-compile-form (macroexpand-all - (wisent-automaton-lisp-form (eval form))))) + (wisent-automaton-lisp-form (eval form t))))) (defun wisent-compile-grammar (grammar &optional start-list) ;; This is kept for compatibility with FOO-wy.el files generated diff --git a/lisp/cedet/semantic/wisent/java-tags.el b/lisp/cedet/semantic/wisent/java-tags.el index adb9a30894..b4a87be62a 100644 --- a/lisp/cedet/semantic/wisent/java-tags.el +++ b/lisp/cedet/semantic/wisent/java-tags.el @@ -111,12 +111,12 @@ Use the alternate LALR(1) parser." (setq ;; Lexical analysis semantic-lex-number-expression semantic-java-number-regexp - semantic-lex-analyzer 'wisent-java-tags-lexer + semantic-lex-analyzer #'wisent-java-tags-lexer ;; Parsing - semantic-tag-expand-function 'semantic-java-expand-tag + semantic-tag-expand-function #'semantic-java-expand-tag ;; Environment - semantic-imenu-summary-function 'semantic-format-tag-prototype - imenu-create-index-function 'semantic-create-imenu-index + semantic-imenu-summary-function #'semantic-format-tag-prototype + imenu-create-index-function #'semantic-create-imenu-index semantic-type-relation-separator-character '(".") semantic-command-separation-character ";" ;; speedbar and imenu buckets name diff --git a/lisp/cedet/semantic/wisent/javascript.el b/lisp/cedet/semantic/wisent/javascript.el index 9db51ad36b..1932f205ee 100644 --- a/lisp/cedet/semantic/wisent/javascript.el +++ b/lisp/cedet/semantic/wisent/javascript.el @@ -128,14 +128,14 @@ This is currently needed for the mozrepl omniscient database." (wisent-javascript-jv-wy--install-parser) (setq ;; Lexical Analysis - semantic-lex-analyzer 'javascript-lexer-jv + semantic-lex-analyzer #'javascript-lexer-jv semantic-lex-number-expression semantic-java-number-regexp ;; semantic-lex-depth nil ;; Full lexical analysis ;; Parsing - semantic-tag-expand-function 'wisent-javascript-jv-expand-tag + semantic-tag-expand-function #'wisent-javascript-jv-expand-tag ;; Environment - semantic-imenu-summary-function 'semantic-format-tag-name - imenu-create-index-function 'semantic-create-imenu-index + semantic-imenu-summary-function #'semantic-format-tag-name + imenu-create-index-function #'semantic-create-imenu-index semantic-command-separation-character ";" )) diff --git a/lisp/cedet/semantic/wisent/python.el b/lisp/cedet/semantic/wisent/python.el index 8732b2e975..7a5761ce8c 100644 --- a/lisp/cedet/semantic/wisent/python.el +++ b/lisp/cedet/semantic/wisent/python.el @@ -512,12 +512,12 @@ Shortens `code' tags, but passes through for others." semantic-type-relation-separator-character '(".") semantic-command-separation-character ";" ;; Parsing - semantic-tag-expand-function 'semantic-python-expand-tag + semantic-tag-expand-function #'semantic-python-expand-tag ;; Semantic to take over from the one provided by python. ;; The python one, if it uses the senator advice, will hang ;; Emacs unrecoverably. - imenu-create-index-function 'semantic-create-imenu-index + imenu-create-index-function #'semantic-create-imenu-index ;; I need a python guru to update this list: semantic-symbol->name-assoc-list-for-type-parts '((variable . "Variables") diff --git a/lisp/cedet/semantic/wisent/wisent.el b/lisp/cedet/semantic/wisent/wisent.el index df1fd73e29..d205c0e604 100644 --- a/lisp/cedet/semantic/wisent/wisent.el +++ b/lisp/cedet/semantic/wisent/wisent.el @@ -1,6 +1,6 @@ ;;; semantic/wisent/wisent.el --- GNU Bison for Emacs - Runtime -*- lexical-binding: t; -*- -;;; Copyright (C) 2002-2007, 2009-2021 Free Software Foundation, Inc. +;; Copyright (C) 2002-2021 Free Software Foundation, Inc. ;; Author: David Ponce ;; Created: 30 January 2002 diff --git a/lisp/cedet/srecode.el b/lisp/cedet/srecode.el index aa4aa812e0..83e9754a60 100644 --- a/lisp/cedet/srecode.el +++ b/lisp/cedet/srecode.el @@ -1,6 +1,6 @@ ;;; srecode.el --- Semantic buffer evaluator. -*- lexical-binding: t -*- -;;; Copyright (C) 2005, 2007-2021 Free Software Foundation, Inc. +;; Copyright (C) 2005-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: codegeneration diff --git a/lisp/cedet/srecode/cpp.el b/lisp/cedet/srecode/cpp.el index 3f66898c9c..dc5e8da5cd 100644 --- a/lisp/cedet/srecode/cpp.el +++ b/lisp/cedet/srecode/cpp.el @@ -164,7 +164,7 @@ specified in a C file." ;; when they make sense. My best bet would be ;; (semantic-tag-function-parent tag), but it is not there, when ;; the function is defined in the scope of a class. - (let ((member t) + (let (;; (member t) (templates (semantic-tag-get-attribute tag :template)) (modifiers (semantic-tag-modifiers tag))) @@ -185,7 +185,7 @@ specified in a C file." ;; When the function is a member function, it can have ;; additional modifiers. - (when member + (when t ;; member ;; For member functions, constness is called ;; 'methodconst-flag'. diff --git a/lisp/cedet/srecode/mode.el b/lisp/cedet/srecode/mode.el index 022a5db8f2..9b1c8491a1 100644 --- a/lisp/cedet/srecode/mode.el +++ b/lisp/cedet/srecode/mode.el @@ -224,13 +224,11 @@ MENU-DEF is the menu to bind this into." (if bind (concat name " (" bind ")") name) - `(lambda () (interactive) - (srecode-insert (concat ,ctxt ":" ,name))) + (lambda () (interactive) + (srecode-insert (concat ctxt ":" name))) t))) - (setcdr ctxtcons (cons - new - (cdr ctxtcons))))) + (push new (cdr ctxtcons)))) (setq ltab (cdr ltab)))) (setq subtab (cdr subtab))) diff --git a/lisp/cedet/srecode/template.el b/lisp/cedet/srecode/template.el index 4f7eaffeb4..1f6f0d345d 100644 --- a/lisp/cedet/srecode/template.el +++ b/lisp/cedet/srecode/template.el @@ -49,11 +49,11 @@ (setq ;; Lexical Analysis - semantic-lex-analyzer 'wisent-srecode-template-lexer + semantic-lex-analyzer #'wisent-srecode-template-lexer ;; Parsing ;; Environment - semantic-imenu-summary-function 'semantic-format-tag-name - imenu-create-index-function 'semantic-create-imenu-index + semantic-imenu-summary-function #'semantic-format-tag-name + imenu-create-index-function #'semantic-create-imenu-index semantic-command-separation-character "\n" semantic-lex-comment-regex ";;" ;; Speedbar commit 2d12df39267b4fca13a9739e6354985e807e1dd9 Author: Gabriel do Nascimento Ribeiro Date: Sat Mar 13 16:12:47 2021 -0300 Init archive and add noconfirm to 'package-install-selected-packages' * lisp/emacs-lisp/package.el (package-install-selected-packages): Add call to 'package--archives-initialize' and add optional argument NOCONFIRM to skip user confirmation when installing packages. (Bug#47124) diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 0973963af2..2ecd92cee9 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -2206,10 +2206,13 @@ directory." (package-install-from-buffer))) ;;;###autoload -(defun package-install-selected-packages () +(defun package-install-selected-packages (&optional noconfirm) "Ensure packages in `package-selected-packages' are installed. -If some packages are not installed propose to install them." +If some packages are not installed, propose to install them. +If optional argument NOCONFIRM is non-nil, don't ask for +confirmation to install packages." (interactive) + (package--archives-initialize) ;; We don't need to populate `package-selected-packages' before ;; using here, because the outcome is the same either way (nothing ;; gets installed). @@ -2220,10 +2223,11 @@ If some packages are not installed propose to install them." (difference (- (length not-installed) (length available)))) (cond (available - (when (y-or-n-p - (format "Packages to install: %d (%s), proceed? " - (length available) - (mapconcat #'symbol-name available " "))) + (when (or noconfirm + (y-or-n-p + (format "Packages to install: %d (%s), proceed? " + (length available) + (mapconcat #'symbol-name available " ")))) (mapc (lambda (p) (package-install p 'dont-select)) available))) ((> difference 0) (message "Packages that are not available: %d (the rest is already installed), maybe you need to `M-x package-refresh-contents'" commit ca7cb9830bde49e76c59a2414a87a3f6eb3b0679 Author: Stefan Kangas Date: Mon Mar 15 02:49:07 2021 +0100 * lisp/vc/ediff-vers.el: Remove XEmacs compat code. diff --git a/lisp/vc/ediff-vers.el b/lisp/vc/ediff-vers.el index 13a653b270..9e82392725 100644 --- a/lisp/vc/ediff-vers.el +++ b/lisp/vc/ediff-vers.el @@ -24,23 +24,9 @@ ;;; Code: -;; Compiler pacifier -(defvar rcs-default-co-switches) +(eval-when-compile (require 'ediff-init)) -(and noninteractive - (eval-when-compile - (condition-case nil - ;; for compatibility with current stable version of xemacs - (progn - ;;(require 'pcvs nil 'noerror) - ;;(require 'rcs nil 'noerror) - (require 'pcvs) - (require 'rcs)) - (error nil)) - (require 'vc) - (require 'ediff-init) - )) -;; end pacifier +(defvar rcs-default-co-switches) (defcustom ediff-keep-tmp-versions nil "If t, do not delete temporary previous versions for the files on which commit 9c4c76fb023b698270e550a61c14d7272c04552e Author: Stefan Kangas Date: Mon Mar 15 02:32:11 2021 +0100 Use lexical-binding in expand.el * lisp/expand.el: Use lexical-binding. Remove redundant :group args. diff --git a/lisp/expand.el b/lisp/expand.el index 9df8d9f15a..d11ae7c526 100644 --- a/lisp/expand.el +++ b/lisp/expand.el @@ -1,4 +1,4 @@ -;;; expand.el --- make abbreviations more usable +;;; expand.el --- make abbreviations more usable -*- lexical-binding: t -*- ;; Copyright (C) 1995-1996, 2001-2021 Free Software Foundation, Inc. @@ -74,20 +74,17 @@ (defcustom expand-load-hook nil "Hooks run when `expand.el' is loaded." - :type 'hook - :group 'expand) + :type 'hook) (make-obsolete-variable 'expand-load-hook "use `with-eval-after-load' instead." "28.1") (defcustom expand-expand-hook nil "Hooks run when an abbrev made by `expand-add-abbrevs' is expanded." - :type 'hook - :group 'expand) + :type 'hook) (defcustom expand-jump-hook nil "Hooks run by `expand-jump-to-previous-slot' and `expand-jump-to-next-slot'." - :type 'hook - :group 'expand) + :type 'hook) ;;; Samples: @@ -319,8 +316,7 @@ If ARG is omitted, point is placed at the end of the expanded text." nil) (if (and (symbolp expansion) (fboundp expansion)) expansion - nil) - ) + nil)) 'expand-abbrev-hook))) (put 'expand-abbrev-hook 'no-self-insert t) @@ -368,13 +364,12 @@ See `expand-add-abbrevs'. Value is non-nil if expansion was done." (insert text) (setq expand-point (point)))) (if jump-args - (funcall 'expand-build-list (car jump-args) (cdr jump-args))) + (funcall #'expand-build-list (car jump-args) (cdr jump-args))) (if position (backward-char position)) (if hook (funcall hook)) - t) - ) + t)) (defun expand-abbrev-from-expand (word) "Test if an abbrev has a hook." @@ -428,8 +423,7 @@ This is used only in conjunction with `expand-add-abbrevs'." (lenlist (length expand-list))) (while (< i lenlist) (aset expand-list i (- len (1- (aref expand-list i)))) - (setq i (1+ i)))) - ) + (setq i (1+ i))))) (defun expand-build-marks (p) "Transform the offsets vector into a marker vector." commit b6863bd1a683637ee50fece9b715c9b6bde38c7d Author: Stefan Kangas Date: Mon Mar 15 02:20:23 2021 +0100 * lisp/help-macro.el: Use lexical-binding. diff --git a/lisp/help-macro.el b/lisp/help-macro.el index 72371a8727..81d238305b 100644 --- a/lisp/help-macro.el +++ b/lisp/help-macro.el @@ -1,4 +1,4 @@ -;;; help-macro.el --- makes command line help such as help-for-help +;;; help-macro.el --- makes command line help such as help-for-help -*- lexical-binding: t -*- ;; Copyright (C) 1993-1994, 2001-2021 Free Software Foundation, Inc. commit 8548ad2cb3f0eff766cc87d0db78a09972c72acc Author: Stefan Kangas Date: Mon Mar 15 01:43:11 2021 +0100 Add three new tests for image.el * test/lisp/image-tests.el (image-find-image) (image-type-from-file-name, image-type/from-filename): New tests. diff --git a/test/lisp/image-tests.el b/test/lisp/image-tests.el index ab7585ca05..bb42ffae18 100644 --- a/test/lisp/image-tests.el +++ b/test/lisp/image-tests.el @@ -48,6 +48,17 @@ (setf (image-property image :width) nil) (should (equal image '(image))))) +(ert-deftest image-find-image () + (find-image '((:type xpm :file "undo.xpm"))) + (find-image '((:type png :file "newsticker/rss-feed.png" :ascent center)))) + +(ert-deftest image-type-from-file-name () + (should (eq (image-type-from-file-name "foo.jpg") 'jpeg)) + (should (eq (image-type-from-file-name "foo.png") 'png))) + +(ert-deftest image-type/from-filename () + (should (eq (image-type "foo.jpg") 'jpeg))) + (ert-deftest image-type-from-file-header-test () "Test image-type-from-file-header." (should (eq (if (image-type-available-p 'svg) 'svg) commit 8b024a6ff10f7907445ea60c4db8355638616ed1 Author: Stefan Kangas Date: Mon Mar 15 00:27:20 2021 +0100 * lisp/wid-edit.el (widget-field): Add subtle border to face. diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index de2b5d4a7c..35e7b9ce7e 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el @@ -131,16 +131,21 @@ This exists as a variable so it can be set locally in certain buffers.") (((class grayscale color) (background light)) :background "gray85" + ;; We use negative thickness of the horizontal box border line to + ;; avoid making lines taller when fields become visible. + :box (:line-width (1 . -1) :color "gray80") :extend t) (((class grayscale color) (background dark)) :background "dim gray" + :box (:line-width (1 . -1) :color "gray46") :extend t) (t :slant italic :extend t)) "Face used for editable fields." - :group 'widget-faces) + :group 'widget-faces + :version "28.1") (defface widget-single-line-field '((((type tty)) :background "green3" commit 35e31c1e7135c76076c771b153b13044af91bb56 Author: Stefan Monnier Date: Sun Mar 14 11:35:55 2021 -0400 Revert "* lisp/calendar/appt.el (appt-activate): Set the local `write-file-functions`" This reverts commit 587a97bcb23bc6ea429ab790efa03f2260a9bca8. We really do want to affect the global part of the hook. Reported by Gabriel . diff --git a/lisp/calendar/appt.el b/lisp/calendar/appt.el index 281b89e088..29bcd6de2c 100644 --- a/lisp/calendar/appt.el +++ b/lisp/calendar/appt.el @@ -700,7 +700,7 @@ ARG is positive, otherwise off." (let ((appt-active appt-timer)) (setq appt-active (if arg (> (prefix-numeric-value arg) 0) (not appt-active))) - (remove-hook 'write-file-functions #'appt-update-list 'local) + (remove-hook 'write-file-functions #'appt-update-list) (or global-mode-string (setq global-mode-string '(""))) (delq 'appt-mode-string global-mode-string) (when appt-timer @@ -708,7 +708,7 @@ ARG is positive, otherwise off." (setq appt-timer nil)) (if appt-active (progn - (add-hook 'write-file-functions #'appt-update-list nil t) + (add-hook 'write-file-functions #'appt-update-list) (setq appt-timer (run-at-time t 60 #'appt-check) global-mode-string (append global-mode-string '(appt-mode-string))) commit f9b737fb9d21ac7adff403274167e76e77d033b8 Author: Juri Linkov Date: Sun Mar 14 11:29:31 2021 +0200 * lisp/tab-bar.el: Tab groups can be displayed with tab-bar-format-tabs-groups * lisp/tab-bar.el (tab-bar-format): Turn defvar into defcustom. Add :options and force-mode-line-update in :set. (tab-bar--format-tab): New function refactored from tab-bar-format-tabs. (tab-bar-format-tabs): Move most of code to tab-bar--format-tab and call it. (tab-bar-tab-group-format-function): New defcustom. (tab-bar-tab-group-format-default): New function. (tab-bar--format-tab-group, tab-bar-format-tabs-groups): New functions. (tab-bar-format-align-right, tab-bar-format-global): Shorten id. (tab-bar-change-tab-group): Add refs to tab-bar-format in docstring. diff --git a/etc/NEWS b/etc/NEWS index fa8784db59..01fd7af65b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -519,11 +519,13 @@ It can be used to enable/disable the tab bar individually on each frame independently from the value of 'tab-bar-mode' and 'tab-bar-show'. --- -*** New variable 'tab-bar-format' defines a list of tab bar items. +*** New option 'tab-bar-format' defines a list of tab bar items. When it contains 'tab-bar-format-global' (possibly appended after 'tab-bar-format-align-right'), then after enabling 'display-time-mode' (or any other mode that uses 'global-mode-string') it displays time aligned to the right on the tab bar instead of the mode line. +When 'tab-bar-format-tabs' is replaced with 'tab-bar-format-tabs-groups', +then the tab bar displays tab groups. --- *** 'Mod-9' bound to 'tab-last' now switches to the last tab. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 29465aae63..5c6f73ab37 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -519,10 +519,10 @@ the formatted tab name to display in the tab bar." "")) 'face (if current-p 'tab-bar-tab 'tab-bar-tab-inactive)))) -(defvar tab-bar-format '(tab-bar-format-history - tab-bar-format-tabs - tab-bar-separator - tab-bar-format-add-tab) +(defcustom tab-bar-format '(tab-bar-format-history + tab-bar-format-tabs + tab-bar-separator + tab-bar-format-add-tab) "Template for displaying tab bar items. Every item in the list is a function that returns a string, or a list of menu-item elements, or nil. @@ -530,7 +530,22 @@ When you add more items `tab-bar-format-align-right' and `tab-bar-format-global' to the end, then after enabling `display-time-mode' (or any other mode that uses `global-mode-string') it will display time aligned to the right on the tab bar instead of -the mode line.") +the mode line. Replacing `tab-bar-format-tabs' with +`tab-bar-format-tabs-groups' will group tabs on the tab bar." + :type 'hook + :options '(tab-bar-format-history + tab-bar-format-tabs + tab-bar-format-tabs-groups + tab-bar-separator + tab-bar-format-add-tab + tab-bar-format-align-right + tab-bar-format-global) + :initialize 'custom-initialize-default + :set (lambda (sym val) + (set-default sym val) + (force-mode-line-update)) + :group 'tab-bar + :version "28.1") (defun tab-bar-format-history () (when (and tab-bar-history-mode tab-bar-history-buttons-show) @@ -543,39 +558,90 @@ the mode line.") menu-item ,tab-bar-forward-button tab-bar-history-forward :help "Click to go forward in tab history")))) +(defun tab-bar--format-tab (tab i) + (append + `((,(intern (format "sep-%i" i)) menu-item ,(tab-bar-separator) ignore)) + (cond + ((eq (car tab) 'current-tab) + `((current-tab + menu-item + ,(funcall tab-bar-tab-name-format-function tab i) + ignore + :help "Current tab"))) + (t + `((,(intern (format "tab-%i" i)) + menu-item + ,(funcall tab-bar-tab-name-format-function tab i) + ,(or + (alist-get 'binding tab) + `(lambda () + (interactive) + (tab-bar-select-tab ,i))) + :help "Click to visit tab")))) + `((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i))) + menu-item "" + ,(or + (alist-get 'close-binding tab) + `(lambda () + (interactive) + (tab-bar-close-tab ,i))))))) + (defun tab-bar-format-tabs () - (let ((separator (tab-bar-separator)) - (tabs (funcall tab-bar-tabs-function)) - (i 0)) + (let ((i 0)) (mapcan (lambda (tab) (setq i (1+ i)) - (append - `((,(intern (format "sep-%i" i)) menu-item ,separator ignore)) - (cond - ((eq (car tab) 'current-tab) - `((current-tab - menu-item - ,(funcall tab-bar-tab-name-format-function tab i) - ignore - :help "Current tab"))) - (t - `((,(intern (format "tab-%i" i)) - menu-item - ,(funcall tab-bar-tab-name-format-function tab i) - ,(or - (alist-get 'binding tab) - `(lambda () - (interactive) - (tab-bar-select-tab ,i))) - :help "Click to visit tab")))) - `((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i))) - menu-item "" - ,(or - (alist-get 'close-binding tab) - `(lambda () - (interactive) - (tab-bar-close-tab ,i))))))) + (tab-bar--format-tab tab i)) + (funcall tab-bar-tabs-function)))) + +(defcustom tab-bar-tab-group-format-function #'tab-bar-tab-group-format-default + "Function to format a tab group name. +Function gets two arguments, a tab with a group name and its number, +and should return the formatted tab group name to display in the tab bar." + :type 'function + :initialize 'custom-initialize-default + :set (lambda (sym val) + (set-default sym val) + (force-mode-line-update)) + :group 'tab-bar + :version "28.1") + +(defun tab-bar-tab-group-format-default (tab i) + (propertize + (concat (if tab-bar-tab-hints (format "%d " i) "") + (alist-get 'group tab)) + 'face 'tab-bar-tab-inactive)) + +(defun tab-bar--format-tab-group (tab i) + (append + `((,(intern (format "sep-%i" i)) menu-item ,(tab-bar-separator) ignore)) + `((,(intern (format "group-%i" i)) + menu-item + ,(funcall tab-bar-tab-group-format-function tab i) + ,(or + (alist-get 'binding tab) + `(lambda () + (interactive) + (tab-bar-select-tab ,i))) + :help "Click to visit group")))) + +(defun tab-bar-format-tabs-groups () + (let* ((tabs (funcall tab-bar-tabs-function)) + (current-group (alist-get 'group (tab-bar--current-tab-find tabs))) + (previous-group nil) + (i 0)) + (mapcan + (lambda (tab) + (let ((tab-group (alist-get 'group tab))) + (setq i (1+ i)) + (prog1 (if (or (not tab-group) (equal tab-group current-group)) + ;; Show current group and ungrouped tabs + (tab-bar--format-tab tab i) + ;; Otherwise, show first group tab with a group name, + ;; but hide other group tabs + (unless (equal previous-group tab-group) + (tab-bar--format-tab-group tab i))) + (setq previous-group tab-group)))) tabs))) (defun tab-bar-format-add-tab () @@ -590,7 +656,7 @@ the mode line.") (rest (mapconcat (lambda (item) (nth 2 item)) rest "")) (hpos (length rest)) (str (propertize " " 'display `(space :align-to (- right ,hpos))))) - `((tab-bar-format-align-right menu-item ,str ignore)))) + `((align-right menu-item ,str ignore)))) (defun tab-bar-format-global () "Format `global-mode-string' to display it in the tab bar. @@ -599,10 +665,7 @@ When `tab-bar-format-global' is added to `tab-bar-format' then modes that display information on the mode line using `global-mode-string' will display the same text on the tab bar instead." - `((tab-bar-format-global - menu-item - ,(format-mode-line global-mode-string) - ignore))) + `((global menu-item ,(format-mode-line global-mode-string) ignore))) (defun tab-bar-format-list (format-list) (let ((i 0)) @@ -1256,7 +1319,10 @@ function `tab-bar-tab-name-function'." "Add the tab specified by its absolute position ARG to GROUP-NAME. If no ARG is specified, then set the GROUP-NAME for the current tab. ARG counts from 1. -If GROUP-NAME is the empty string, then remove the tab from any group." +If GROUP-NAME is the empty string, then remove the tab from any group. +While using this command, you might also want to replace +`tab-bar-format-tabs' with `tab-bar-format-tabs-groups' in +`tab-bar-format' to group tabs on the tab bar." (interactive (let* ((tabs (funcall tab-bar-tabs-function)) (tab-index (or current-prefix-arg (1+ (tab-bar--current-tab-index tabs)))) commit 0a60e5d33c82803d68970c71a2e9ac9fcde5c2c6 Author: Gabriel do Nascimento Ribeiro Date: Sat Mar 13 19:04:55 2021 -0300 * lisp/tab-line.el: Update docstring of 'tab-line-tabs-function' (bug#47117) (tab-line-tabs-function): Mention 'tab-line-tabs-buffer-groups' in the docstring. (tab-line-tabs-buffer-groups): Add docstring. diff --git a/lisp/tab-line.el b/lisp/tab-line.el index c4b504aaad..f2c49019b1 100644 --- a/lisp/tab-line.el +++ b/lisp/tab-line.el @@ -305,7 +305,10 @@ be displayed, or just a list of strings to display in the tab line. By default, use function `tab-line-tabs-window-buffers' that returns a list of buffers associated with the selected window. When `tab-line-tabs-mode-buffers', return a list of buffers -with the same major mode as the current buffer." +with the same major mode as the current buffer. +When `tab-line-tabs-buffer-groups', return a list of buffers +grouped either by `tab-line-tabs-buffer-group-function', when set, +or by `tab-line-tabs-buffer-groups'." :type '(choice (const :tag "Window buffers" tab-line-tabs-window-buffers) (const :tag "Same mode buffers" @@ -367,6 +370,11 @@ If the major mode's name string matches REGEXP, use GROUPNAME instead.") mode)))) (defun tab-line-tabs-buffer-groups () + "Return a list of tabs that should be displayed in the tab line. +By default return a list of buffers grouped by major mode, +according to `tab-line-tabs-buffer-groups'. +If non-nil, `tab-line-tabs-buffer-group-function' is used to +generate the group name." (if (window-parameter nil 'tab-line-groups) (let* ((buffers (funcall tab-line-tabs-buffer-list-function)) (groups commit 0bfa9e78602a9c37c9ebd14bef43d15f6443d17c Author: Gabriel do Nascimento Ribeiro Date: Fri Mar 12 23:12:10 2021 -0300 * lisp/tab-line.el: Add face for group-tab (bug#47118) (tab-line-tab-face-functions): Add choice for 'tab-line-tab-face-group'. (tab-line-tab-group): New face. (tab-line-tabs-buffer-groups): Set alist key 'group-tab' for group tabs. (tab-line-tab-face-group): New function to set face for group tabs. diff --git a/lisp/tab-line.el b/lisp/tab-line.el index 903862a3e8..c4b504aaad 100644 --- a/lisp/tab-line.el +++ b/lisp/tab-line.el @@ -44,6 +44,7 @@ whether the tab is a buffer, and whether the tab is selected." :type '(repeat (choice (function-item tab-line-tab-face-special) (function-item tab-line-tab-face-inactive-alternating) + (function-item tab-line-tab-face-group) (function :tag "Custom function"))) :group 'tab-line :version "28.1") @@ -95,6 +96,16 @@ function `tab-line-tab-face-special'." :version "28.1" :group 'tab-line-faces) +(defface tab-line-tab-group + '((default + :inherit tab-line + :box nil)) + "Face for group tabs. +Applied when option `tab-line-tab-face-functions' includes +function `tab-line-tab-face-group'." + :version "28.1" + :group 'tab-line-faces) + (defface tab-line-tab-current '((default :inherit tab-line-tab) @@ -385,6 +396,7 @@ If the major mode's name string matches REGEXP, use GROUPNAME instead.") (set-window-parameter nil 'tab-line-group nil)))) (group-tab `(tab (name . ,group) + (group-tab . t) (select . ,(lambda () (set-window-parameter nil 'tab-line-groups t) (set-window-parameter nil 'tab-line-group group) @@ -520,6 +532,13 @@ When TAB is a non-file-backed buffer, make FACE inherit from (setf face `(:inherit (tab-line-tab-special ,face)))) face) +(defun tab-line-tab-face-group (tab _tabs face _buffer-p _selected-p) + "Return FACE for TAB according to whether it's a group tab. +For use in `tab-line-tab-face-functions'." + (when (alist-get 'group-tab tab) + (setf face `(:inherit (tab-line-tab-group ,face)))) + face) + (defvar tab-line-auto-hscroll) (defun tab-line-format () commit ebfb4c2789733d7ff11d08a595faa5804196c8e5 Author: Michael Albinus Date: Sun Mar 14 09:27:42 2021 +0100 * lisp/net/tramp-crypt.el (tramp-crypt-add-directory): Don't autoload setting property `completion-predicate'. diff --git a/lisp/net/tramp-crypt.el b/lisp/net/tramp-crypt.el index 278fb9d873..f44be449e2 100644 --- a/lisp/net/tramp-crypt.el +++ b/lisp/net/tramp-crypt.el @@ -477,7 +477,6 @@ See `tramp-crypt-do-encrypt-or-decrypt-file'." Files in that directory and all subdirectories will be encrypted before copying to, and decrypted after copying from that directory. File names will be also encrypted." - ;; (declare (completion tramp-crypt-enabled-p)) (interactive "DRemote directory name: ") (unless tramp-crypt-enabled (tramp-user-error nil "Feature is not enabled.")) @@ -490,8 +489,7 @@ directory. File names will be also encrypted." (setq tramp-crypt-directories (cons name tramp-crypt-directories))) (tramp-register-file-name-handlers)) -;; Starting with Emacs 28.1, this can be replaced by the "(declare ...)" form. -;;;###tramp-autoload +;; `tramp-crypt-enabled-p' is not autoloaded, and this setting isn't either. (function-put #'tramp-crypt-add-directory 'completion-predicate #'tramp-crypt-enabled-p) commit be1b3512f772133ac9760f93fedabd672ba04598 Author: Daniel Martín Date: Sun Mar 14 02:25:53 2021 +0100 Fix reference to 'diff-font-lock-syntax' in diff-mode documentation * doc/emacs/files.texi (Diff Mode): Add the omitted name of the variable. (Bug#47129) diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index 88fcdd0f9f..b9e45b9919 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -1652,8 +1652,9 @@ modify the original (``old'') source files rather than the patched (``new'') source files. @vindex diff-font-lock-syntax - If non-@code{nil}, fragments of source in hunks are highlighted -according to the appropriate major mode. + If @code{diff-font-lock-syntax} is non-@code{nil}, fragments of +source in hunks are highlighted according to the appropriate major +mode. @node Copying and Naming @section Copying, Naming and Renaming Files commit b9ec6111e294af747958c6f13150b8dc99dba6e2 Author: Alan Third Date: Sat Mar 13 21:59:59 2021 +0000 Fix buffer overflow in xbm_scan (bug#47094) * src/image.c (xbm_scan): Ensure reading a string doesn't overflow the buffer. (cherry picked from commit ebc3b25409dd614c1814a0643960452683e37aa3) diff --git a/src/image.c b/src/image.c index cd095e0e65..e3eae5c497 100644 --- a/src/image.c +++ b/src/image.c @@ -3256,6 +3256,7 @@ static int xbm_scan (char **s, char *end, char *sval, int *ival) { unsigned char c UNINIT; + char *sval_end = sval + BUFSIZ; loop: @@ -3315,7 +3316,7 @@ xbm_scan (char **s, char *end, char *sval, int *ival) else if (c_isalpha (c) || c == '_') { *sval++ = c; - while (*s < end + while (*s < end && sval < sval_end && (c = *(*s)++, (c_isalnum (c) || c == '_'))) *sval++ = c; *sval = 0; commit ebc3b25409dd614c1814a0643960452683e37aa3 Author: Alan Third Date: Sat Mar 13 21:59:59 2021 +0000 Fix buffer overflow in xbm_scan (bug#47094) * src/image.c (xbm_scan): Ensure reading a string doesn't overflow the buffer. diff --git a/src/image.c b/src/image.c index 6d493f6cdd..b85418c690 100644 --- a/src/image.c +++ b/src/image.c @@ -3392,6 +3392,7 @@ static int xbm_scan (char **s, char *end, char *sval, int *ival) { unsigned char c UNINIT; + char *sval_end = sval + BUFSIZ; loop: @@ -3451,7 +3452,7 @@ xbm_scan (char **s, char *end, char *sval, int *ival) else if (c_isalpha (c) || c == '_') { *sval++ = c; - while (*s < end + while (*s < end && sval < sval_end && (c = *(*s)++, (c_isalnum (c) || c == '_'))) *sval++ = c; *sval = 0; commit fbfc3bd31748015dfab9213ebedb99513a9cb2b9 Author: Juri Linkov Date: Sat Mar 13 23:33:14 2021 +0200 Separate values 'override' and 'append' in 'outline-minor-mode-highlight' * lisp/outline.el (outline-font-lock-keywords): Handle 'override' and 'append' separately. (outline-minor-mode-highlight): Separate values 'override' and 'append'. (outline-minor-mode-highlight-buffer): Go to match-beginning before checking '(point)'. diff --git a/lisp/outline.el b/lisp/outline.el index b4d37b2207..79029a6e5e 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -207,9 +207,10 @@ in the file it applies to.") (list 'face nil 'keymap outline-mode-cycle-map))) (outline-font-lock-face)) - (when (and outline-minor-mode - (eq outline-minor-mode-highlight 'override)) - 'append) + (when outline-minor-mode + (pcase outline-minor-mode-highlight + ('override t) + ('append 'append))) t))) "Additional expressions to highlight in Outline mode.") @@ -340,10 +341,12 @@ Typing these keys anywhere outside heading lines uses their default bindings." Non-nil value works well only when outline font-lock keywords don't conflict with the major mode's font-lock keywords. When t, it puts outline faces only if there are no major mode's faces -on headings. When `override', it tries to append outline faces -to major mode's faces." +on headings. When `override', it completely overwrites major mode's +faces with outline faces. When `append', it tries to append outline +faces to major mode's faces." :type '(choice (const :tag "No highlighting" nil) - (const :tag "Append to major mode faces" override) + (const :tag "Overwrite major mode faces" override) + (const :tag "Append outline faces to major mode faces" append) (const :tag "Highlight separately from major mode faces" t)) :version "28.1") ;;;###autoload(put 'outline-minor-mode-highlight 'safe-local-variable 'booleanp) @@ -359,6 +362,7 @@ to major mode's faces." (overlay-put overlay 'outline-overlay t) (when (or (eq outline-minor-mode-highlight 'override) (and (eq outline-minor-mode-highlight t) + (goto-char (match-beginning 0)) (not (get-text-property (point) 'face)))) (overlay-put overlay 'face (outline-font-lock-face))) (when outline-minor-mode-cycle commit 34b49ee8e9ff5b8615aa0c6f3de41be59d7557df Author: Stefan Kangas Date: Sat Mar 13 20:14:54 2021 +0100 Add help-key-binding styling to wombat theme * etc/themes/wombat-theme.el (help-key-binding): Add face definition. diff --git a/etc/themes/wombat-theme.el b/etc/themes/wombat-theme.el index aaa7cceaf6..d625b7f9cf 100644 --- a/etc/themes/wombat-theme.el +++ b/etc/themes/wombat-theme.el @@ -57,6 +57,8 @@ are included.") `(font-lock-type-face ((,class (:foreground "#92a65e" :weight bold)))) `(font-lock-variable-name-face ((,class (:foreground "#cae682")))) `(font-lock-warning-face ((,class (:foreground "#ccaa8f")))) + ;; Help faces + `(help-key-binding ((,class (:background "#333333" :foreground "#f6f3e8")))) ;; Button and link faces `(link ((,class (:foreground "#8ac6f2" :underline t)))) `(link-visited ((,class (:foreground "#e5786d" :underline t)))) commit 2b34304ad431e4a9f1c655f93862e24ccc55c8d6 Author: Eli Zaretskii Date: Sat Mar 13 17:04:46 2021 +0200 ; Add comment for a recent change * lisp/faces.el (help-key-binding): Comment on the reason for a recent change. diff --git a/lisp/faces.el b/lisp/faces.el index ec650e30ca..573428f1d3 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -2818,6 +2818,9 @@ Note: Other faces cannot inherit from the cursor face." (defface help-key-binding '((((class color) (min-colors 88) (background light)) :background "grey92" :foreground "DarkBlue" + ;; We use negative thickness of the horizontal box border line to + ;; avoid enlarging the height of the echo-area display, which + ;; would then move the mode line a few pixels up. :box (:line-width (1 . -1) :color "grey80")) (((class color) (min-colors 88) (background dark)) :background "grey23" :foreground "LightBlue" commit 1f0fb1f6fa50faf67ffaaee0e52d00144883821e Author: Eli Zaretskii Date: Sat Mar 13 17:00:15 2021 +0200 Fix rare redisplay glitches when image has been removed from display * src/dispnew.c (update_window): Make sure all glyph rows below the last visible one are marked as invalid, even when the loop which "updates the rest of the lines" didn't examine the last visible row. (Bug#47093) diff --git a/src/dispnew.c b/src/dispnew.c index b3e4587250..f613f7b656 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -3588,6 +3588,7 @@ update_window (struct window *w, bool force_p) int yb; bool changed_p = 0, mouse_face_overwritten_p = 0; int n_updated = 0; + bool invisible_rows_marked = false; #ifdef HAVE_WINDOW_SYSTEM gui_update_window_begin (w); @@ -3679,13 +3680,36 @@ update_window (struct window *w, bool force_p) tempted to optimize redisplay based on lines displayed in the first redisplay. */ if (MATRIX_ROW_BOTTOM_Y (row) >= yb) - for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i) - SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false); + { + for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i) + SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false); + invisible_rows_marked = true; + } } /* Was display preempted? */ paused_p = row < end; + if (!paused_p && !invisible_rows_marked) + { + /* If we didn't mark the invisible rows in the current + matrix as invalid above, do that now. This can happen if + scrolling_window updates the last visible rows of the + current matrix, in which case the above loop doesn't get + to examine the last visible row. */ + int i; + for (i = 0; i < w->current_matrix->nrows - 1; ++i) + { + struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, i); + if (current_row->enabled_p + && MATRIX_ROW_BOTTOM_Y (current_row) >= yb) + { + for (++i ; i < w->current_matrix->nrows - 1; ++i) + SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false); + } + } + } + set_cursor: /* Update the tab line after scrolling because a new tab commit 8415a9513085d1c307610e2275655699cf7a55d5 Author: Stefan Kangas Date: Sat Mar 13 15:17:24 2021 +0100 Adjust colors of help-key-binding face for readability * lisp/faces.el (help-key-binding): Adjust colors for improved readability, and use a flat :box for highlighting (with negative :line-width height to avoid any vertical resizing of the minibuffer). This was discussed in: https://lists.gnu.org/r/emacs-devel/2021-03/msg00535.html diff --git a/lisp/faces.el b/lisp/faces.el index 1e668a43f4..ec650e30ca 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -2816,8 +2816,12 @@ Note: Other faces cannot inherit from the cursor face." :group 'help) (defface help-key-binding - '((((class color) (min-colors 88) (background light)) :background "grey90") - (((class color) (min-colors 88) (background dark)) :background "grey25") + '((((class color) (min-colors 88) (background light)) + :background "grey92" :foreground "DarkBlue" + :box (:line-width (1 . -1) :color "grey80")) + (((class color) (min-colors 88) (background dark)) + :background "grey23" :foreground "LightBlue" + :box (:line-width (1 . -1) :color "grey35")) (((class color grayscale) (background light)) :background "grey90") (((class color grayscale) (background dark)) :background "grey25") (t :background "grey90")) commit 695f6792f1524a446d276bf5c5e53bbb4c200909 Author: Michael Albinus Date: Sat Mar 13 14:35:39 2021 +0100 Remove ;;;###tramp-autoload cookie from Tramp defcustoms (Bug#47063) * lisp/net/tramp-crypt.el (tramp-crypt-enabled-p): New defun. (tramp-crypt-add-directory, tramp-crypt-remove-directory): Add property `completion-predicate'. * lisp/net/tramp-sh.el (tramp-terminal-type, tramp-remote-path) (tramp-remote-process-environment): Remove. Move them to ... * lisp/net/tramp.el: ... here. diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index 6ec4d1fed3..aacf83e663 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -44,7 +44,6 @@ :version "24.4" :type 'string) -;;;###tramp-autoload (defcustom tramp-adb-connect-if-not-connected nil "Try to run `adb connect' if provided device is not connected currently. It is used for TCP/IP devices." @@ -56,7 +55,6 @@ It is used for TCP/IP devices." (defconst tramp-adb-method "adb" "When this method name is used, forward all calls to Android Debug Bridge.") -;;;###tramp-autoload (defcustom tramp-adb-prompt "^[^#$\n\r]*[#$][[:space:]]" "Regexp used as prompt in almquist shell." :type 'regexp diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el index 1e48f8dbb8..d208f0e044 100644 --- a/lisp/net/tramp-cmds.el +++ b/lisp/net/tramp-cmds.el @@ -208,7 +208,6 @@ This includes password cache, file cache, connection cache, buffers." (dolist (name (tramp-list-remote-buffers)) (when (bufferp (get-buffer name)) (kill-buffer name)))) -;;;###tramp-autoload (defcustom tramp-default-rename-alist nil "Default target for renaming remote buffer file names. This is an alist of cons cells (SOURCE . TARGET). The first @@ -231,7 +230,6 @@ expression which always matches." :type '(repeat (cons (choice :tag "Source regexp" regexp sexp) (choice :tag "Target name" string (const nil))))) -;;;###tramp-autoload (defcustom tramp-confirm-rename-file-names t "Whether renaming a buffer file name must be confirmed." :group 'tramp diff --git a/lisp/net/tramp-crypt.el b/lisp/net/tramp-crypt.el index f8de7085e2..278fb9d873 100644 --- a/lisp/net/tramp-crypt.el +++ b/lisp/net/tramp-crypt.el @@ -112,6 +112,14 @@ initializing a new crypted remote directory." "Non-nil when encryption support is available.") (setq tramp-crypt-enabled (executable-find tramp-crypt-encfs-program)) +;; This function takes action since Emacs 28.1, when +;; `read-extended-command-predicate' is set to +;; `command-completion-default-include-p'. +(defun tramp-crypt-enabled-p (_symbol _buffer) + "A predicate for Tramp interactive commands. +They are completed by \"M-x TAB\" only when encryption support is enabled." + tramp-crypt-enabled) + ;;;###tramp-autoload (defconst tramp-crypt-encfs-config ".encfs6.xml" "Encfs configuration file name.") @@ -469,6 +477,7 @@ See `tramp-crypt-do-encrypt-or-decrypt-file'." Files in that directory and all subdirectories will be encrypted before copying to, and decrypted after copying from that directory. File names will be also encrypted." + ;; (declare (completion tramp-crypt-enabled-p)) (interactive "DRemote directory name: ") (unless tramp-crypt-enabled (tramp-user-error nil "Feature is not enabled.")) @@ -481,10 +490,16 @@ directory. File names will be also encrypted." (setq tramp-crypt-directories (cons name tramp-crypt-directories))) (tramp-register-file-name-handlers)) +;; Starting with Emacs 28.1, this can be replaced by the "(declare ...)" form. +;;;###tramp-autoload +(function-put + #'tramp-crypt-add-directory 'completion-predicate #'tramp-crypt-enabled-p) + (defun tramp-crypt-remove-directory (name) "Unmark remote directory NAME for encryption. Existing files in that directory and its subdirectories will be kept in their encrypted form." + ;; (declare (completion tramp-crypt-enabled-p)) (interactive "DRemote directory name: ") (unless tramp-crypt-enabled (tramp-user-error nil "Feature is not enabled.")) @@ -498,6 +513,10 @@ kept in their encrypted form." (setq tramp-crypt-directories (delete name tramp-crypt-directories)) (tramp-register-file-name-handlers))) +;; Starting with Emacs 28.1, this can be replaced by the "(declare ...)" form. +(function-put + #'tramp-crypt-remove-directory 'completion-predicate #'tramp-crypt-enabled-p) + ;; `auth-source' requires a user. (defun tramp-crypt-dissect-file-name (name) "Return a `tramp-file-name' structure for NAME. diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index 9d4e04ca68..c4ec1121da 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -175,7 +175,6 @@ They are checked during start up via (dbus-list-known-names :session)) (setq tramp-media-methods (delete method tramp-media-methods))))) -;;;###tramp-autoload (defcustom tramp-gvfs-zeroconf-domain "local" "Zeroconf domain to be used for discovering services, like host names." :group 'tramp diff --git a/lisp/net/tramp-rclone.el b/lisp/net/tramp-rclone.el index e6f9fe56ec..3b6de3e0b7 100644 --- a/lisp/net/tramp-rclone.el +++ b/lisp/net/tramp-rclone.el @@ -42,7 +42,6 @@ (defconst tramp-rclone-method "rclone" "When this method name is used, forward all calls to rclone mounts.") -;;;###tramp-autoload (defcustom tramp-rclone-program "rclone" "Name of the rclone program." :group 'tramp diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 14abf55e55..7182cd6b1d 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -46,7 +46,6 @@ (defconst tramp-default-remote-shell "/bin/sh" "The default remote shell Tramp applies.") -;;;###tramp-autoload (defcustom tramp-inline-compress-start-size 4096 "The minimum size of compressing where inline transfer. When inline transfer, compress transferred data of file whose @@ -56,23 +55,12 @@ If it is nil, no compression at all will be applied." :group 'tramp :type '(choice (const nil) integer)) -;;;###tramp-autoload (defcustom tramp-copy-size-limit 10240 "Maximum file size where inline copying is preferred to an out-of-the-band copy. If it is nil, out-of-the-band copy will be used without a check." :group 'tramp :type '(choice (const nil) integer)) -;;;###tramp-autoload -(defcustom tramp-terminal-type "dumb" - "Value of TERM environment variable for logging in to remote host. -Because Tramp wants to parse the output of the remote shell, it is easily -confused by ANSI color escape sequences and suchlike. Often, shell init -files conditionalize this setup based on the TERM environment variable." - :group 'tramp - :type 'string) - -;;;###tramp-autoload (defcustom tramp-histfile-override "~/.tramp_history" "When invoking a shell, override the HISTFILE with this value. When setting to a string, it redirects the shell history to that @@ -115,7 +103,6 @@ detected as prompt when being sent on echoing hosts, therefore.") (defconst tramp-end-of-heredoc (md5 tramp-end-of-output) "String used to recognize end of heredoc strings.") -;;;###tramp-autoload (defcustom tramp-use-ssh-controlmaster-options t "Whether to use `tramp-ssh-controlmaster-options'. Set it to nil, if you use Control* or Proxy* options in your ssh @@ -477,70 +464,6 @@ The string is used in `tramp-methods'.") (tramp-set-completion-function "psftp" tramp-completion-function-alist-ssh) (tramp-set-completion-function "fcp" tramp-completion-function-alist-ssh)) -;; "getconf PATH" yields: -;; HP-UX: /usr/bin:/usr/ccs/bin:/opt/ansic/bin:/opt/langtools/bin:/opt/fortran/bin -;; Solaris: /usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin -;; GNU/Linux (Debian, Suse, RHEL): /bin:/usr/bin -;; FreeBSD, DragonFly: /usr/bin:/bin:/usr/sbin:/sbin: - beware trailing ":"! -;; FreeBSD 12.1, Darwin: /usr/bin:/bin:/usr/sbin:/sbin -;; IRIX64: /usr/bin -;; QNAP QTS: --- -;; Hydra: /run/current-system/sw/bin:/bin:/usr/bin -;;;###tramp-autoload -(defcustom tramp-remote-path - '(tramp-default-remote-path "/bin" "/usr/bin" "/sbin" "/usr/sbin" - "/usr/local/bin" "/usr/local/sbin" "/local/bin" "/local/freeware/bin" - "/local/gnu/bin" "/usr/freeware/bin" "/usr/pkg/bin" "/usr/contrib/bin" - "/opt/bin" "/opt/sbin" "/opt/local/bin") - "List of directories to search for executables on remote host. -For every remote host, this variable will be set buffer local, -keeping the list of existing directories on that host. - -You can use \"~\" in this list, but when searching for a shell which groks -tilde expansion, all directory names starting with \"~\" will be ignored. - -`Default Directories' represent the list of directories given by -the command \"getconf PATH\". It is recommended to use this -entry on head of this list, because these are the default -directories for POSIX compatible commands. On remote hosts which -do not offer the getconf command (like cygwin), the value -\"/bin:/usr/bin\" is used instead. This entry is represented in -the list by the special value `tramp-default-remote-path'. - -`Private Directories' are the settings of the $PATH environment, -as given in your `~/.profile'. This entry is represented in -the list by the special value `tramp-own-remote-path'." - :group 'tramp - :type '(repeat (choice - (const :tag "Default Directories" tramp-default-remote-path) - (const :tag "Private Directories" tramp-own-remote-path) - (string :tag "Directory")))) - -;;;###tramp-autoload -(defcustom tramp-remote-process-environment - '("ENV=''" "TMOUT=0" "LC_CTYPE=''" - "CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH=" "PAGER=cat" - "autocorrect=" "correct=") - "List of environment variables to be set on the remote host. - -Each element should be a string of the form ENVVARNAME=VALUE. An -entry ENVVARNAME= disables the corresponding environment variable, -which might have been set in the init files like ~/.profile. - -Special handling is applied to some environment variables, -which should not be set here: - -The PATH environment variable should be set via `tramp-remote-path'. - -The TERM environment variable should be set via `tramp-terminal-type'. - -The INSIDE_EMACS environment variable will automatically be set -based on the Tramp and Emacs versions, and should not be set here." - :group 'tramp - :version "26.1" - :type '(repeat string)) - -;;;###tramp-autoload (defcustom tramp-sh-extra-args '(("/bash\\'" . "-noediting -norc -noprofile") ("/zsh\\'" . "-f +Z -V")) diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 69359553e4..6fbf08801e 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -60,20 +60,17 @@ tramp-smb-method '((tramp-parse-netrc "~/.netrc")))) -;;;###tramp-autoload (defcustom tramp-smb-program "smbclient" "Name of SMB client to run." :group 'tramp :type 'string) -;;;###tramp-autoload (defcustom tramp-smb-acl-program "smbcacls" "Name of SMB acls to run." :group 'tramp :type 'string :version "24.4") -;;;###tramp-autoload (defcustom tramp-smb-conf null-device "Path of the \"smb.conf\" file. If it is nil, no \"smb.conf\" will be added to the `tramp-smb-program' @@ -81,7 +78,6 @@ call, letting the SMB client use the default one." :group 'tramp :type '(choice (const nil) (file :must-match t))) -;;;###tramp-autoload (defcustom tramp-smb-options nil "List of additional options. They are added to the `tramp-smb-program' call via \"--option '...'\". @@ -305,7 +301,6 @@ See `tramp-actions-before-shell' for more info.") Operations not mentioned here will be handled by the default Emacs primitives.") ;; Options for remote processes via winexe. -;;;###tramp-autoload (defcustom tramp-smb-winexe-program "winexe" "Name of winexe client to run. If it isn't found in the local $PATH, the absolute path of winexe @@ -314,7 +309,6 @@ shall be given. This is needed for remote processes." :type 'string :version "24.3") -;;;###tramp-autoload (defcustom tramp-smb-winexe-shell-command "powershell.exe" "Shell to be used for processes on remote machines. This must be Powershell V2 compatible." @@ -322,7 +316,6 @@ This must be Powershell V2 compatible." :type 'string :version "24.3") -;;;###tramp-autoload (defcustom tramp-smb-winexe-shell-command-switch "-file -" "Command switch used together with `tramp-smb-winexe-shell-command'. This can be used to disable echo etc." diff --git a/lisp/net/tramp-sshfs.el b/lisp/net/tramp-sshfs.el index 2a00d5ce67..c4a36fe2a3 100644 --- a/lisp/net/tramp-sshfs.el +++ b/lisp/net/tramp-sshfs.el @@ -40,7 +40,6 @@ (defconst tramp-sshfs-method "sshfs" "Tramp method for sshfs mounts.") -;;;###tramp-autoload (defcustom tramp-sshfs-program "sshfs" "The sshfs mount command." :group 'tramp diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index da779d3386..8141f026f7 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -660,6 +660,14 @@ The regexp should match at end of buffer. See also `tramp-yesno-prompt-regexp'." :type 'regexp) +(defcustom tramp-terminal-type "dumb" + "Value of TERM environment variable for logging in to remote host. +Because Tramp wants to parse the output of the remote shell, it is easily +confused by ANSI color escape sequences and suchlike. Often, shell init +files conditionalize this setup based on the TERM environment variable." + :group 'tramp + :type 'string) + (defcustom tramp-terminal-prompt-regexp (concat "\\(" "TERM = (.*)" @@ -1243,6 +1251,67 @@ let-bind this variable." :version "24.4" :type '(choice (const nil) integer)) +;; "getconf PATH" yields: +;; HP-UX: /usr/bin:/usr/ccs/bin:/opt/ansic/bin:/opt/langtools/bin:/opt/fortran/bin +;; Solaris: /usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin +;; GNU/Linux (Debian, Suse, RHEL): /bin:/usr/bin +;; FreeBSD, DragonFly: /usr/bin:/bin:/usr/sbin:/sbin: - beware trailing ":"! +;; FreeBSD 12.1, Darwin: /usr/bin:/bin:/usr/sbin:/sbin +;; IRIX64: /usr/bin +;; QNAP QTS: --- +;; Hydra: /run/current-system/sw/bin:/bin:/usr/bin +(defcustom tramp-remote-path + '(tramp-default-remote-path "/bin" "/usr/bin" "/sbin" "/usr/sbin" + "/usr/local/bin" "/usr/local/sbin" "/local/bin" "/local/freeware/bin" + "/local/gnu/bin" "/usr/freeware/bin" "/usr/pkg/bin" "/usr/contrib/bin" + "/opt/bin" "/opt/sbin" "/opt/local/bin") + "List of directories to search for executables on remote host. +For every remote host, this variable will be set buffer local, +keeping the list of existing directories on that host. + +You can use \"~\" in this list, but when searching for a shell which groks +tilde expansion, all directory names starting with \"~\" will be ignored. + +`Default Directories' represent the list of directories given by +the command \"getconf PATH\". It is recommended to use this +entry on head of this list, because these are the default +directories for POSIX compatible commands. On remote hosts which +do not offer the getconf command (like cygwin), the value +\"/bin:/usr/bin\" is used instead. This entry is represented in +the list by the special value `tramp-default-remote-path'. + +`Private Directories' are the settings of the $PATH environment, +as given in your `~/.profile'. This entry is represented in +the list by the special value `tramp-own-remote-path'." + :group 'tramp + :type '(repeat (choice + (const :tag "Default Directories" tramp-default-remote-path) + (const :tag "Private Directories" tramp-own-remote-path) + (string :tag "Directory")))) + +(defcustom tramp-remote-process-environment + '("ENV=''" "TMOUT=0" "LC_CTYPE=''" + "CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH=" "PAGER=cat" + "autocorrect=" "correct=") + "List of environment variables to be set on the remote host. + +Each element should be a string of the form ENVVARNAME=VALUE. An +entry ENVVARNAME= disables the corresponding environment variable, +which might have been set in the init files like ~/.profile. + +Special handling is applied to some environment variables, +which should not be set here: + +The PATH environment variable should be set via `tramp-remote-path'. + +The TERM environment variable should be set via `tramp-terminal-type'. + +The INSIDE_EMACS environment variable will automatically be set +based on the Tramp and Emacs versions, and should not be set here." + :group 'tramp + :version "26.1" + :type '(repeat string)) + (defcustom tramp-completion-reread-directory-timeout 10 "Defines seconds since last remote command before rereading a directory. A remote directory might have changed its contents. In order to commit aa644996dfd67872a0271d5bf92dcaa44aba6469 Author: Eli Zaretskii Date: Sat Mar 13 12:26:48 2021 +0200 Extend support for faces in Enriched mode * lisp/textmodes/enriched.el (enriched-face-ans): Support faces with bold and italic attributes. (Bug#46507) diff --git a/lisp/textmodes/enriched.el b/lisp/textmodes/enriched.el index c44b69cdb7..e43370cdb5 100644 --- a/lisp/textmodes/enriched.el +++ b/lisp/textmodes/enriched.el @@ -389,6 +389,8 @@ which can be the value of the `face' text property." (apply 'append (mapcar 'enriched-face-ans face))) ((let* ((fg (face-attribute face :foreground)) (bg (face-attribute face :background)) + (weight (face-attribute face :weight)) + (slant (face-attribute face :slant)) (props (face-font face t)) (ans (cdr (format-annotate-single-property-change 'face nil props enriched-translations)))) @@ -396,6 +398,10 @@ which can be the value of the `face' text property." (setq ans (cons (list "x-color" fg) ans))) (unless (eq bg 'unspecified) (setq ans (cons (list "x-bg-color" bg) ans))) + (if (eq weight 'bold) + (setq ans (cons (list "bold") ans))) + (if (eq slant 'italic) + (setq ans (cons (list "italic") ans))) ans)))) ;;; commit f60eb988f6dfcd590d17dd6fd3f93ee71e830391 Author: Matt Armstrong Date: Wed Mar 10 09:24:43 2021 -0800 Fix typos and omissions for (elisp)Button Buffer Commands * doc/lispref/display.texi (Button Buffer Commands): Minor typo and omission fixes `backward-button' and `forward-button'. (Bug#47051) diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index a49f08dd2e..fed1762e30 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -6964,11 +6964,11 @@ end of the buffer continues from the other end. If @var{display-message} is non-@code{nil}, the button's help-echo string is displayed. Any button with a non-@code{nil} @code{skip} property is skipped over. Returns the button found, and signals an error if no -buttons can be found. If @var{no-error} in non-@code{nil}, return nil +buttons can be found. If @var{no-error} is non-@code{nil}, return nil instead of signaling the error. @end deffn -@deffn Command backward-button n &optional wrap display-message +@deffn Command backward-button n &optional wrap display-message no-error Move to the @var{n}th previous button, or @var{n}th next button if @var{n} is negative. If @var{n} is zero, move to the start of any button at point. If @var{wrap} is non-@code{nil}, moving past either @@ -6976,7 +6976,7 @@ end of the buffer continues from the other end. If @var{display-message} is non-@code{nil}, the button's help-echo string is displayed. Any button with a non-@code{nil} @code{skip} property is skipped over. Returns the button found, and signals an error if no -buttons can be found. If @var{no-error} in non-@code{nil}, return nil +buttons can be found. If @var{no-error} is non-@code{nil}, return nil instead of signaling the error. @end deffn commit 876b95bf90653fe61ad0b9e2d17924832422e8bb Author: Eli Zaretskii Date: Sat Mar 13 11:22:01 2021 +0200 Teach Rmail about NBSP in "Re:" * lisp/mail/rmail.el (rmail-simplified-subject) (rmail-reply-regexp): Allow NBSP in "RE:" prefixes. diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el index 628e876238..86154f2a61 100644 --- a/lisp/mail/rmail.el +++ b/lisp/mail/rmail.el @@ -582,7 +582,7 @@ Examples: ;; This pattern should catch all the common variants. ;; rms: I deleted the change to delete tags in square brackets ;; because they mess up RT tags. -(defvar rmail-reply-regexp "\\`\\(Re\\(([0-9]+)\\|\\[[0-9]+\\]\\|\\^[0-9]+\\)?: *\\)*" +(defvar rmail-reply-regexp "\\`\\(Re\\(([0-9]+)\\|\\[[0-9]+\\]\\|\\^[0-9]+\\)?\u00a0*: *\\)*" "Regexp to delete from Subject line before inserting `rmail-reply-prefix'.") (defcustom rmail-display-summary nil @@ -3398,7 +3398,8 @@ whitespace, replacing whitespace runs with a single space and removing prefixes such as Re:, Fwd: and so on and mailing list tags such as [tag]." (let ((subject (or (rmail-get-header "Subject" msgnum) "")) - (regexp "\\`[ \t\n]*\\(\\(\\w\\{1,3\\}:\\|\\[[^]]+]\\)[ \t\n]+\\)*")) + (regexp + "\\`[ \t\n]*\\(\\(\\w\\{1,3\\}\u00a0*:\\|\\[[^]]+]\\)[ \t\n]+\\)*")) (setq subject (rfc2047-decode-string subject)) (setq subject (replace-regexp-in-string regexp "" subject)) (replace-regexp-in-string "[ \t\n]+" " " subject))) commit 82e3acc9cda5373d090d56b50a7b322d3ce9d8b1 Author: Stefan Monnier Date: Fri Mar 12 14:33:41 2021 -0500 * src/keyboard.c parse_solitary_modifier): Accept `click` modifier diff --git a/src/keyboard.c b/src/keyboard.c index e3fc6adf81..512fa279b3 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -6679,6 +6679,7 @@ parse_solitary_modifier (Lisp_Object symbol) case 'c': MULTI_LETTER_MOD (ctrl_modifier, "ctrl", 4); MULTI_LETTER_MOD (ctrl_modifier, "control", 7); + MULTI_LETTER_MOD (click_modifier, "click", 5); break; case 'H': commit a2960025e8e029bcccf22143e183b9e1e9965dd6 Author: Stefan Monnier Date: Fri Mar 12 14:30:47 2021 -0500 Revert "* lisp/mouse.el: Fix mouse-1-clock-follows-mouse = double" This reverts commit 02a5cfce471613f671722b35536d2a78f17b0429. That commit breaks because of a missing patch to `parse_modifiers_uncached` in `src/keyboard.c`. IOW, too risky for `emacs-27`. Don't merge to `master`. diff --git a/lisp/mouse.el b/lisp/mouse.el index 6b8e65c4a2..72ad77c634 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -116,9 +116,7 @@ Expects to be bound to `(double-)mouse-1' in `key-translation-map'." (time-since (cdr mouse--last-down)) (/ (abs mouse-1-click-follows-link) 1000.0)))))) (eq (car mouse--last-down) - (event-convert-list - `(down ,@(event-modifiers last-input-event) - ,(event-basic-type last-input-event)))) + (event-convert-list (list 'down (car-safe last-input-event)))) (let* ((action (mouse-on-link-p (event-start last-input-event)))) (when (and action (or mouse-1-click-in-non-selected-windows commit 75705b302dd025dc2d678124aa1b7bd52a8d35b2 Author: Yuan Fu Date: Fri Mar 12 12:18:22 2021 -0500 Fix simple-tests--undo* * test/lisp/simple-tests.el (simple-tests--undo-in-region, simple-tests--undo-equiv-table): Re-enable in batch mode. Enable 'transient-mark-mode' in temp buffer. diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el index 8fa8295765..601eca6cd4 100644 --- a/test/lisp/simple-tests.el +++ b/test/lisp/simple-tests.el @@ -469,8 +469,11 @@ See bug#35036." (ert-deftest simple-tests--undo-in-region () ;; Test undo/redo in region. - (skip-unless (not noninteractive)) (with-temp-buffer + ;; Enable `transient-mark-mode' so `region-active-p' works as + ;; expected. `region-active-p' is used to determine whether to + ;; perform regional undo in `undo'. + (transient-mark-mode) (buffer-enable-undo) (dolist (x '("a" "b" "c" "d" "e")) (insert x) @@ -506,9 +509,9 @@ See bug#35036." lst) (ert-deftest simple-tests--undo-equiv-table () - (skip-unless (not noninteractive)) (with-temp-buffer (buffer-enable-undo) + (transient-mark-mode) (let ((ul-hash-table (make-hash-table :test #'equal))) (dolist (x '("a" "b" "c")) (insert x) commit 6d024ae867ced056f9ca1206f178720ba5390213 Author: Stefan Monnier Date: Fri Mar 12 11:57:32 2021 -0500 * lisp/filesets.el: Address byte-compiler warning (filesets-run-cmd): Let-bind `filesets--files`. (filesets-cmd-isearch-getargs): Use it. diff --git a/lisp/filesets.el b/lisp/filesets.el index a51b6f8135..8e9fae80f6 100644 --- a/lisp/filesets.el +++ b/lisp/filesets.el @@ -1183,7 +1183,7 @@ Return full path if FULL-FLAG is non-nil." (constraint-flag (message "Obsolete :constraint-flag %S, use :constraintp instead" (cadr constraint-flag)) - (eval (cadr constraint-flag))) + (eval (cadr constraint-flag) t)) (t t)))) @@ -1557,18 +1557,20 @@ Replace or <> with filename." (completing-read "Select fileset: " filesets-data nil t)))) (when (and cmd-name name) (let* ((event (if (equal cmd-name "Grep <>") - 'on-grep + 'on-grep 'on-cmd)) (files (if (and fileset - (or (equal mode ':ingroup) - (equal mode ':tree))) + (or (equal mode :ingroup) + (equal mode :tree))) (filesets-get-filelist fileset mode event) - (filesets-get-filelist - (filesets-get-fileset-from-name name) - mode event)))) + (filesets-get-filelist + (filesets-get-fileset-from-name name) + mode event)))) (when files (let ((fn (filesets-cmd-get-fn cmd-name)) - (args (filesets-cmd-get-args cmd-name))) + (args + (dlet ((filesets--files files)) + (filesets-cmd-get-args cmd-name)))) (if (memq fn '(multi-isearch-files multi-isearch-files-regexp)) (apply fn args) (dolist (this files nil) @@ -1577,28 +1579,27 @@ Replace or <> with filename." (let ((buffer (filesets-find-file this))) (when buffer (goto-char (point-min)) - (progn - (cond - ((stringp fn) - (let* ((args - (mapconcat - (lambda (this) - (filesets-run-cmd--repl-fn - this - (lambda (this) - (format "%s" this)))) - args - " ")) - (cmd (concat fn " " args))) - (filesets-cmd-show-result - cmd (shell-command-to-string cmd)))) - ((symbolp fn) - (apply fn - (mapcan (lambda (this) - (filesets-run-cmd--repl-fn - this - 'list)) - args))))))))))))))))) + (cond + ((stringp fn) + (let* ((args + (mapconcat + (lambda (this) + (filesets-run-cmd--repl-fn + this + (lambda (this) + (format "%s" this)))) + args + " ")) + (cmd (concat fn " " args))) + (filesets-cmd-show-result + cmd (shell-command-to-string cmd)))) + ((symbolp fn) + (apply fn + (mapcan (lambda (this) + (filesets-run-cmd--repl-fn + this + 'list)) + args)))))))))))))))) (defun filesets-get-cmd-menu () "Create filesets command menu." @@ -1624,7 +1625,7 @@ Replace or <> with filename." (defun filesets-cmd-isearch-getargs () "Get arguments for `multi-isearch-files' and `multi-isearch-files-regexp'." - (and (boundp 'files) (list files))) + (and (boundp 'filesets--files) (list filesets--files))) (defun filesets-cmd-shell-command-getargs () "Get arguments for `filesets-cmd-shell-command'." commit 8ea2f84402453103829c8ba269e4038f6e72ebc6 Author: Glenn Morris Date: Fri Mar 12 08:57:26 2021 -0800 * lisp/tooltip.el (tooltip): Restore group that was not "redundant". diff --git a/lisp/tooltip.el b/lisp/tooltip.el index 293c034395..03d9f54ea6 100644 --- a/lisp/tooltip.el +++ b/lisp/tooltip.el @@ -135,6 +135,7 @@ of the `tooltip' face are used instead." When using the GTK toolkit, this face will only be used if `x-gtk-use-system-tooltips' is non-nil." + :group 'tooltip :group 'basic-faces) (defcustom tooltip-use-echo-area nil commit 1feddd35abb3b3a1ac4b63c24de53d491d596ba0 Merge: 069ff11fb2 02a5cfce47 Author: Glenn Morris Date: Fri Mar 12 08:47:41 2021 -0800 Merge from origin/emacs-27 02a5cfce47 (origin/emacs-27) * lisp/mouse.el: Fix mouse-1-clock-follo... c881e990e3 * lisp/emacs-lisp/gv.el (edebug-after): Don't run the gett... commit 069ff11fb26a16bae13c11bd1486f9ac4b39db41 Merge: 7c3ec4ef35 9f09083bcd Author: Glenn Morris Date: Fri Mar 12 08:47:41 2021 -0800 ; Merge from origin/emacs-27 The following commit was skipped: 9f09083bcd * doc/misc/tramp.texi (Remote shell setup): Fix reference.... commit 7c3ec4ef35de78e99c6e97ec9e1ac7666a9c4d67 Merge: a49b2aa5c3 fc83f37951 Author: Glenn Morris Date: Fri Mar 12 08:47:41 2021 -0800 Merge from origin/emacs-27 fc83f37951 Fix initialization of 'while-no-input-ignore-events' 8f603da44c Update documentation of reading passwords commit a49b2aa5c33b389e2c7d976a5d3eed8e65ab30e9 Merge: 74c389526f ed2b23ecc1 Author: Glenn Morris Date: Fri Mar 12 08:47:41 2021 -0800 ; Merge from origin/emacs-27 The following commits were skipped: ed2b23ecc1 Improve the 'dired-do-kill-lines' doc string 8c93becb35 (emacs-27) ; Auto-commit of loaddefs files. commit 74c389526f93cc4eded6759ffd3e1cfa4d429d6f Merge: f7b7ecc4df 2c5f215419 Author: Glenn Morris Date: Fri Mar 12 08:47:41 2021 -0800 Merge from origin/emacs-27 2c5f215419 Avoid crashes in Mew due to corrupted tool-bar label 7a23915618 * lisp/tooltip.el (tooltip): Doc fix for GTK. c4bbe02cc4 * lisp/help.el (help-for-help-internal): Doc fix; use impe... # Conflicts: # lisp/help.el # lisp/tooltip.el commit f7b7ecc4df7108da31625a3630cbbbdbec3abbd7 Author: Glenn Morris Date: Fri Mar 12 08:41:03 2021 -0800 Skip recent undo tests in batch mode for now * test/lisp/simple-tests.el (simple-tests--undo-in-region): Split into separate test. Skip in batch mode for now. (simple-tests--undo-equiv-table): Skip in batch mode for now. diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el index 1819775bda..8fa8295765 100644 --- a/test/lisp/simple-tests.el +++ b/test/lisp/simple-tests.el @@ -465,8 +465,11 @@ See bug#35036." (simple-tests--exec '(backward-char undo-redo undo-redo)) (should (equal (buffer-string) "abc")) (simple-tests--exec '(backward-char undo-redo undo-redo)) - (should (equal (buffer-string) "abcde"))) + (should (equal (buffer-string) "abcde")))) + +(ert-deftest simple-tests--undo-in-region () ;; Test undo/redo in region. + (skip-unless (not noninteractive)) (with-temp-buffer (buffer-enable-undo) (dolist (x '("a" "b" "c" "d" "e")) @@ -503,6 +506,7 @@ See bug#35036." lst) (ert-deftest simple-tests--undo-equiv-table () + (skip-unless (not noninteractive)) (with-temp-buffer (buffer-enable-undo) (let ((ul-hash-table (make-hash-table :test #'equal))) commit d1a7d16f8e1a42d6e6edc0621e29b38f92e9fc2e Author: Stefan Monnier Date: Fri Mar 12 11:32:42 2021 -0500 * lisp/cedet/{*.el,ede/*.el}: Use lexical-binding Remove a few redundant `:group` arguments as well. * lisp/cedet/ede.el: Use lexical-binding. Don't load `ede/files` at compile-time. (ede-speedbar): Declare function. (ede-load-project-file): Allow `rootreturn` to be a reference rather than a symbol. (ede-initialize-state-current-buffer): Pass `ROOT` as a reference rather than a symbol to `ede-directory-get-open-project` and `ede-load-project-file` so we don't need to make it dynamically scoped. (ede-flush-deleted-projects): Avoid `add-to-list` on a local var. * lisp/cedet/ede/files.el: Use lexical-binding. (ede-directory-get-open-project): Allow `rootreturn` to be a reference rather than a symbol. (ede-project-root-directory): Remove unused var `root`. (ede-expand-filename-impl): Remove unused vars `path` and `proj`. * lisp/cedet/cedet-idutils.el: Use lexical-binding. (cedet-idutils-search): Remove always-nil variable `scopeflags`. * lisp/cedet/data-debug.el: Use lexical-binding. (data-debug-insert-overlay-button, data-debug-insert-overlay-list-button) (data-debug-insert-buffer-button, data-debug-insert-buffer-list-button) (data-debug-insert-process-button): Remove always-nil variable `tip`. (data-debug-insert-ring-button): Remove unused var `ringthing`. (data-debug-insert-widget-properties): Remove unused var `type`. * lisp/cedet/semantic.el: Use lexical-binding. (semantic-mode): Strength-reduce `eval` to `symbol-value`. * lisp/cedet/ede/custom.el: Use lexical-binding. (ede-project-sort-targets): Remove unused vars `count`, `current`, and `order`. * lisp/cedet/ede/pconf.el: Use lexical-binding. (ede-proj-configure-synchronize): Remove unused var `add-missing`. * lisp/cedet/ede/pmake.el (ede-proj-makefile-garbage-patterns): Simplify via η-reduction. (ede-proj-makefile-dependencies): Use `seq-some` rather than `eval+or`. * lisp/cedet/ede/proj-elisp.el: Use lexical-binding. (project-compile-target): Remove unused var `elc`. (ede-update-version-in-source): Remove unused var `match`. (project-compile-target): Declare function `cedet-update-autoloads` from file we don't have. * lisp/cedet/cedet-cscope.el: Use lexical-binding. * lisp/cedet/cedet-files.el: Use lexical-binding. * lisp/cedet/cedet-global.el: Use lexical-binding. * lisp/cedet/cedet.el: Use lexical-binding. * lisp/cedet/ede/auto.el: Use lexical-binding. * lisp/cedet/ede/autoconf-edit.el: Use lexical-binding. * lisp/cedet/ede/config.el: Use lexical-binding. * lisp/cedet/ede/cpp-root.el: Use lexical-binding. * lisp/cedet/ede/detect.el: Use lexical-binding. * lisp/cedet/ede/generic.el: Use lexical-binding. * lisp/cedet/ede/linux.el: Use lexical-binding. * lisp/cedet/ede/locate.el: Use lexical-binding. * lisp/cedet/ede/makefile-edit.el: Use lexical-binding. * lisp/cedet/ede/proj-info.el: Use lexical-binding. * lisp/cedet/ede/proj-obj.el: Use lexical-binding. * lisp/cedet/ede/proj-prog.el: Use lexical-binding. * lisp/cedet/ede/proj-shared.el: Use lexical-binding. * lisp/cedet/ede/proj.el: Use lexical-binding. * lisp/cedet/ede/shell.el: Use lexical-binding. * lisp/cedet/ede/simple.el: Use lexical-binding. * lisp/cedet/ede/source.el: Use lexical-binding. * lisp/cedet/ede/speedbar.el: Use lexical-binding. * lisp/cedet/ede/util.el: Use lexical-binding. diff --git a/lisp/cedet/cedet-cscope.el b/lisp/cedet/cedet-cscope.el index 4d4a9f78d5..95f04541c8 100644 --- a/lisp/cedet/cedet-cscope.el +++ b/lisp/cedet/cedet-cscope.el @@ -1,4 +1,4 @@ -;;; cedet-cscope.el --- CScope support for CEDET +;;; cedet-cscope.el --- CScope support for CEDET -*- lexical-binding: t; -*- ;;; Copyright (C) 2009-2021 Free Software Foundation, Inc. @@ -34,7 +34,7 @@ :type 'string :group 'cedet) -(defun cedet-cscope-search (searchtext texttype type scope) +(defun cedet-cscope-search (searchtext texttype type _scope) "Perform a search with CScope, return the created buffer. SEARCHTEXT is text to find. TEXTTYPE is the type of text, such as `regexp', `string', `tagname', @@ -85,7 +85,7 @@ options -cR." (with-current-buffer b (setq default-directory cd) (erase-buffer)) - (apply 'call-process cedet-cscope-command + (apply #'call-process cedet-cscope-command nil b nil flags) b)) diff --git a/lisp/cedet/cedet-files.el b/lisp/cedet/cedet-files.el index 31608159cc..c9d557f597 100644 --- a/lisp/cedet/cedet-files.el +++ b/lisp/cedet/cedet-files.el @@ -1,4 +1,4 @@ -;;; cedet-files.el --- Common routines dealing with file names. +;;; cedet-files.el --- Common routines dealing with file names. -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/cedet-global.el b/lisp/cedet/cedet-global.el index 77b4474439..227ebd54b8 100644 --- a/lisp/cedet/cedet-global.el +++ b/lisp/cedet/cedet-global.el @@ -1,4 +1,4 @@ -;;; cedet-global.el --- GNU Global support for CEDET. +;;; cedet-global.el --- GNU Global support for CEDET. -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -75,7 +75,7 @@ SCOPE is the scope of the search, such as `project' or `subdirs'." (with-current-buffer b (setq default-directory cd) (erase-buffer)) - (apply 'call-process cedet-global-command + (apply #'call-process cedet-global-command nil b nil flags) b)) @@ -88,7 +88,7 @@ SCOPE is the scope of the search, such as `project' or `subdirs'." (with-current-buffer b (setq default-directory cd) (erase-buffer)) - (apply 'call-process cedet-global-gtags-command + (apply #'call-process cedet-global-gtags-command nil b nil flags) diff --git a/lisp/cedet/cedet-idutils.el b/lisp/cedet/cedet-idutils.el index 3e3d6a5e94..a2b8cb3524 100644 --- a/lisp/cedet/cedet-idutils.el +++ b/lisp/cedet/cedet-idutils.el @@ -1,4 +1,4 @@ -;;; cedet-idutils.el --- ID Utils support for CEDET. +;;; cedet-idutils.el --- ID Utils support for CEDET. -*- lexical-binding: t; -*- ;; Copyright (C) 2009-2021 Free Software Foundation, Inc. @@ -47,7 +47,7 @@ :type 'string :group 'cedet) -(defun cedet-idutils-search (searchtext texttype type scope) +(defun cedet-idutils-search (searchtext texttype type _scope) "Perform a search with ID Utils, return the created buffer. SEARCHTEXT is text to find. TEXTTYPE is the type of text, such as `regexp', `string', `tagname', @@ -64,7 +64,7 @@ Note: Scope is not yet supported." (let* ((resultflg (if (eq texttype 'tagcompletions) (list "--key=token") (list "--result=grep"))) - (scopeflgs nil) ; (cond ((eq scope 'project) "" ) ((eq scope 'target) "l"))) + ;; (scopeflgs (cond ((eq scope 'project) "" ) ((eq scope 'target) "l"))) (stflag (cond ((or (eq texttype 'tagname) (eq texttype 'tagregexp)) (list "-r" "-w")) @@ -77,7 +77,7 @@ Note: Scope is not yet supported." ;; t means 'symbol (t (list "-l" "-w")))) ) - (cedet-idutils-lid-call (append resultflg scopeflgs stflag + (cedet-idutils-lid-call (append resultflg nil stflag ;; scopeflgs (list searchtext)))))) (defun cedet-idutils-fnid-call (flags) @@ -89,7 +89,7 @@ Return the created buffer with program output." (with-current-buffer b (setq default-directory cd) (erase-buffer)) - (apply 'call-process cedet-idutils-file-command + (apply #'call-process cedet-idutils-file-command nil b nil flags) b)) @@ -103,7 +103,7 @@ Return the created buffer with program output." (with-current-buffer b (setq default-directory cd) (erase-buffer)) - (apply 'call-process cedet-idutils-token-command + (apply #'call-process cedet-idutils-token-command nil b nil flags) b)) @@ -117,7 +117,7 @@ Return the created buffer with program output." (with-current-buffer b (setq default-directory cd) (erase-buffer)) - (apply 'call-process cedet-idutils-make-command + (apply #'call-process cedet-idutils-make-command nil b nil flags) b)) @@ -133,7 +133,7 @@ Return a filename relative to the default directory." (if (looking-at "[^ \n]*fnid: ") (error "ID Utils not available") (split-string (buffer-string) "\n" t))))) - (setq ans (mapcar 'expand-file-name ans)) + (setq ans (mapcar #'expand-file-name ans)) (when (called-interactively-p 'interactive) (if ans (if (= (length ans) 1) diff --git a/lisp/cedet/cedet.el b/lisp/cedet/cedet.el index 5d98a1939d..b6043f1403 100644 --- a/lisp/cedet/cedet.el +++ b/lisp/cedet/cedet.el @@ -1,4 +1,4 @@ -;;; cedet.el --- Setup CEDET environment +;;; cedet.el --- Setup CEDET environment -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. @@ -48,25 +48,25 @@ (defvar cedet-menu-map ;(make-sparse-keymap "CEDET menu") (let ((map (make-sparse-keymap "CEDET menu"))) - (define-key map [semantic-force-refresh] 'undefined) - (define-key map [semantic-edit-menu] 'undefined) - (define-key map [navigate-menu] 'undefined) - (define-key map [semantic-options-separator] 'undefined) - (define-key map [global-semantic-highlight-func-mode] 'undefined) - (define-key map [global-semantic-stickyfunc-mode] 'undefined) - (define-key map [global-semantic-decoration-mode] 'undefined) - (define-key map [global-semantic-idle-completions-mode] 'undefined) - (define-key map [global-semantic-idle-summary-mode] 'undefined) - (define-key map [global-semantic-idle-scheduler-mode] 'undefined) - (define-key map [global-semanticdb-minor-mode] 'undefined) - (define-key map [cedet-menu-separator] 'undefined) - (define-key map [ede-find-file] 'undefined) - (define-key map [ede-speedbar] 'undefined) - (define-key map [ede] 'undefined) - (define-key map [ede-new] 'undefined) - (define-key map [ede-target-options] 'undefined) - (define-key map [ede-project-options] 'undefined) - (define-key map [ede-build-forms-menu] 'undefined) + (define-key map [semantic-force-refresh] #'undefined) + (define-key map [semantic-edit-menu] #'undefined) + (define-key map [navigate-menu] #'undefined) + (define-key map [semantic-options-separator] #'undefined) + (define-key map [global-semantic-highlight-func-mode] #'undefined) + (define-key map [global-semantic-stickyfunc-mode] #'undefined) + (define-key map [global-semantic-decoration-mode] #'undefined) + (define-key map [global-semantic-idle-completions-mode] #'undefined) + (define-key map [global-semantic-idle-summary-mode] #'undefined) + (define-key map [global-semantic-idle-scheduler-mode] #'undefined) + (define-key map [global-semanticdb-minor-mode] #'undefined) + (define-key map [cedet-menu-separator] #'undefined) + (define-key map [ede-find-file] #'undefined) + (define-key map [ede-speedbar] #'undefined) + (define-key map [ede] #'undefined) + (define-key map [ede-new] #'undefined) + (define-key map [ede-target-options] #'undefined) + (define-key map [ede-project-options] #'undefined) + (define-key map [ede-build-forms-menu] #'undefined) map) "Menu keymap for the CEDET package. This is used by `semantic-mode' and `global-ede-mode'.") diff --git a/lisp/cedet/data-debug.el b/lisp/cedet/data-debug.el index f0fa91b3b1..428848be04 100644 --- a/lisp/cedet/data-debug.el +++ b/lisp/cedet/data-debug.el @@ -1,4 +1,4 @@ -;;; data-debug.el --- Data structure debugger +;;; data-debug.el --- Data structure debugger -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. @@ -48,9 +48,9 @@ ;;; Compatibility ;; -(define-obsolete-function-alias 'data-debug-overlay-properties 'overlay-properties "28.1") -(define-obsolete-function-alias 'data-debug-overlay-p 'overlayp "28.1") -(define-obsolete-function-alias 'dd-propertize 'propertize "28.1") +(define-obsolete-function-alias 'data-debug-overlay-properties #'overlay-properties "28.1") +(define-obsolete-function-alias 'data-debug-overlay-p #'overlayp "28.1") +(define-obsolete-function-alias 'dd-propertize #'propertize "28.1") ;;; GENERIC STUFF ;; @@ -100,14 +100,14 @@ PREBUTTONTEXT is some text between prefix and the overlay button." (let ((start (point)) (end nil) (str (format "%s" overlay)) - (tip nil)) + ) ;; (tip nil) (insert prefix prebuttontext str) (setq end (point)) (put-text-property (- end (length str)) end 'face 'font-lock-comment-face) (put-text-property start end 'ddebug overlay) (put-text-property start end 'ddebug-indent(length prefix)) (put-text-property start end 'ddebug-prefix prefix) - (put-text-property start end 'help-echo tip) + ;; (put-text-property start end 'help-echo tip) (put-text-property start end 'ddebug-function 'data-debug-insert-overlay-from-point) (insert "\n") @@ -149,14 +149,14 @@ PREBUTTONTEXT is some text between prefix and the overlay list button." (let ((start (point)) (end nil) (str (format "#" (length overlaylist))) - (tip nil)) + ) ;; (tip nil) (insert prefix prebuttontext str) (setq end (point)) (put-text-property (- end (length str)) end 'face 'font-lock-comment-face) (put-text-property start end 'ddebug overlaylist) (put-text-property start end 'ddebug-indent(length prefix)) (put-text-property start end 'ddebug-prefix prefix) - (put-text-property start end 'help-echo tip) + ;; (put-text-property start end 'help-echo tip) (put-text-property start end 'ddebug-function 'data-debug-insert-overlay-list-from-point) (insert "\n") @@ -204,14 +204,14 @@ PREBUTTONTEXT is some text between prefix and the buffer button." (let ((start (point)) (end nil) (str (format "%S" buffer)) - (tip nil)) + ) ;; (tip nil) (insert prefix prebuttontext str) (setq end (point)) (put-text-property (- end (length str)) end 'face 'font-lock-comment-face) (put-text-property start end 'ddebug buffer) (put-text-property start end 'ddebug-indent(length prefix)) (put-text-property start end 'ddebug-prefix prefix) - (put-text-property start end 'help-echo tip) + ;; (put-text-property start end 'help-echo tip) (put-text-property start end 'ddebug-function 'data-debug-insert-buffer-from-point) (insert "\n") @@ -253,14 +253,14 @@ PREBUTTONTEXT is some text between prefix and the buffer list button." (let ((start (point)) (end nil) (str (format "#" (length bufferlist))) - (tip nil)) + ) ;; (tip nil) (insert prefix prebuttontext str) (setq end (point)) (put-text-property (- end (length str)) end 'face 'font-lock-comment-face) (put-text-property start end 'ddebug bufferlist) (put-text-property start end 'ddebug-indent(length prefix)) (put-text-property start end 'ddebug-prefix prefix) - (put-text-property start end 'help-echo tip) + ;; (put-text-property start end 'help-echo tip) (put-text-property start end 'ddebug-function 'data-debug-insert-buffer-list-from-point) (insert "\n") @@ -309,14 +309,14 @@ PREBUTTONTEXT is some text between prefix and the process button." (let ((start (point)) (end nil) (str (format "%S : %s" process (process-status process))) - (tip nil)) + ) ;; (tip nil) (insert prefix prebuttontext str) (setq end (point)) (put-text-property (- end (length str)) end 'face 'font-lock-comment-face) (put-text-property start end 'ddebug process) (put-text-property start end 'ddebug-indent(length prefix)) (put-text-property start end 'ddebug-prefix prefix) - (put-text-property start end 'help-echo tip) + ;; (put-text-property start end 'help-echo tip) (put-text-property start end 'ddebug-function 'data-debug-insert-process-from-point) (insert "\n") @@ -363,8 +363,8 @@ PREBUTTONTEXT is some text between prefix and the stuff list button." (str (format "#" (ring-length ring) (ring-size ring))) - (ringthing - (if (= (ring-length ring) 0) nil (ring-ref ring 0))) + ;; (ringthing + ;; (if (= (ring-length ring) 0) nil (ring-ref ring 0))) (tip (format "Ring max-size %d, length %d." (ring-size ring) (ring-length ring))) @@ -437,7 +437,7 @@ PREBUTTONTEXT is some text between prefix and the stuff list button." ;; Widgets have a long list of properties (defun data-debug-insert-widget-properties (widget prefix) "Insert the contents of WIDGET inserting PREFIX before each element." - (let ((type (car widget)) + (let (;; (type (car widget)) (rest (cdr widget))) (while rest (data-debug-insert-thing (car (cdr rest)) @@ -683,7 +683,7 @@ PREBUTTONTEXT is some text between prefix and the thing." ) ;;; nil thing -(defun data-debug-insert-nil (thing prefix prebuttontext) +(defun data-debug-insert-nil (_thing prefix prebuttontext) "Insert one simple THING with a face. PREFIX is the text that precedes the button. PREBUTTONTEXT is some text between prefix and the thing. @@ -856,19 +856,18 @@ If PARENT is non-nil, it is somehow related as a parent to thing." (defvar data-debug-mode-map (let ((km (make-sparse-keymap))) (suppress-keymap km) - (define-key km [mouse-2] 'data-debug-expand-or-contract-mouse) - (define-key km " " 'data-debug-expand-or-contract) - (define-key km "\C-m" 'data-debug-expand-or-contract) - (define-key km "n" 'data-debug-next) - (define-key km "p" 'data-debug-prev) - (define-key km "N" 'data-debug-next-expando) - (define-key km "P" 'data-debug-prev-expando) + (define-key km [mouse-2] #'data-debug-expand-or-contract-mouse) + (define-key km " " #'data-debug-expand-or-contract) + (define-key km "\C-m" #'data-debug-expand-or-contract) + (define-key km "n" #'data-debug-next) + (define-key km "p" #'data-debug-prev) + (define-key km "N" #'data-debug-next-expando) + (define-key km "P" #'data-debug-prev-expando) km) "Keymap used in data-debug.") (defcustom data-debug-mode-hook nil "Hook run when data-debug starts." - :group 'data-debug :type 'hook) (define-derived-mode data-debug-mode fundamental-mode "DATA-DEBUG" @@ -1032,7 +1031,7 @@ Do nothing if already contracted." nil read-expression-map t 'read-expression-history)) )) - (let ((v (eval expr))) + (let ((v (eval expr t))) (if (not v) (message "Expression %s is nil." expr) (data-debug-show-stuff v "expression")))) @@ -1049,12 +1048,12 @@ If the result is a list or vector, then use the data debugger to display it." (let (result) (if (null eval-expression-debug-on-error) - (setq result (values--store-value (eval expr))) + (setq result (values--store-value (eval expr t))) (let ((old-value (make-symbol "t")) new-value) ;; Bind debug-on-error to something unique so that we can ;; detect when evalled code changes it. (let ((debug-on-error old-value)) - (setq result (values--store-value (eval expr))) + (setq result (values--store-value (eval expr t))) (setq new-value debug-on-error)) ;; If evalled code has changed the value of debug-on-error, ;; propagate that change to the global binding. diff --git a/lisp/cedet/ede.el b/lisp/cedet/ede.el index 369a9f7e71..2ec9f5d9d6 100644 --- a/lisp/cedet/ede.el +++ b/lisp/cedet/ede.el @@ -1,4 +1,4 @@ -;;; ede.el --- Emacs Development Environment gloss +;;; ede.el --- Emacs Development Environment gloss -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2005, 2007-2021 Free Software Foundation, Inc. @@ -87,7 +87,6 @@ target wants the file, the user is asked. If only one target wants the file, then it is automatically added to that target. If the value is `ask', then the user is always asked, unless there is no target willing to take the file. `never' means never perform the check." - :group 'ede :type '(choice (const always) (const multi-ask) (const ask) @@ -95,7 +94,6 @@ target willing to take the file. `never' means never perform the check." (defcustom ede-debug-program-function 'gdb "Default Emacs command used to debug a target." - :group 'ede :type 'function) ; make this be a list of options some day (defcustom ede-project-directories nil @@ -112,7 +110,6 @@ If you invoke the commands \\[ede] or \\[ede-new] on a directory that is not listed, Emacs will offer to add it to the list. Any other value disables searching for EDE project files." - :group 'ede :type '(choice (const :tag "Any directory" t) (repeat :tag "List of directories" (directory)) @@ -186,21 +183,23 @@ Argument LIST-O-O is the list of objects to choose from." ;;; Menu and Keymap +(declare-function ede-speedbar "ede/speedbar" ()) + (defvar ede-minor-mode-map (let ((map (make-sparse-keymap)) (pmap (make-sparse-keymap))) - (define-key pmap "e" 'ede-edit-file-target) - (define-key pmap "a" 'ede-add-file) - (define-key pmap "d" 'ede-remove-file) - (define-key pmap "t" 'ede-new-target) - (define-key pmap "g" 'ede-rescan-toplevel) - (define-key pmap "s" 'ede-speedbar) - (define-key pmap "f" 'ede-find-file) - (define-key pmap "C" 'ede-compile-project) - (define-key pmap "c" 'ede-compile-target) - (define-key pmap "\C-c" 'ede-compile-selected) - (define-key pmap "D" 'ede-debug-target) - (define-key pmap "R" 'ede-run-target) + (define-key pmap "e" #'ede-edit-file-target) + (define-key pmap "a" #'ede-add-file) + (define-key pmap "d" #'ede-remove-file) + (define-key pmap "t" #'ede-new-target) + (define-key pmap "g" #'ede-rescan-toplevel) + (define-key pmap "s" #'ede-speedbar) + (define-key pmap "f" #'ede-find-file) + (define-key pmap "C" #'ede-compile-project) + (define-key pmap "c" #'ede-compile-target) + (define-key pmap "\C-c" #'ede-compile-selected) + (define-key pmap "D" #'ede-debug-target) + (define-key pmap "R" #'ede-run-target) ;; bind our submap into map (define-key map "\C-c." pmap) map) @@ -476,7 +475,7 @@ To be used in hook functions." If this file is contained, or could be contained in an EDE controlled project, then this mode is activated automatically provided `global-ede-mode' is enabled." - :group 'ede + :global nil (cond ((or (eq major-mode 'dired-mode) (eq major-mode 'vc-dir-mode)) (ede-dired-minor-mode (if ede-minor-mode 1 -1))) @@ -486,6 +485,9 @@ provided `global-ede-mode' is enabled." ;; If we fail to have a project here, turn it back off. (ede-minor-mode -1))))) +(declare-function ede-directory-project-cons "ede/files" (dir &optional force)) +(declare-function ede-toplevel-project-or-nil "ede/files" (dir)) + (defun ede-initialize-state-current-buffer () "Initialize the current buffer's state for EDE. Sets buffer local variables for EDE." @@ -496,7 +498,7 @@ Sets buffer local variables for EDE." ;; Init the buffer. (let* ((ROOT nil) (proj (ede-directory-get-open-project default-directory - 'ROOT))) + (gv-ref ROOT)))) (when (not proj) ;; If there is no open project, look up the project @@ -517,7 +519,8 @@ Sets buffer local variables for EDE." (ede-directory-safe-p top))) ;; The project is safe, so load it in. - (setq proj (ede-load-project-file default-directory projdetect 'ROOT)))))) + (setq proj (ede-load-project-file default-directory projdetect + (gv-ref ROOT))))))) ;; If PROJ is now loaded in, we can initialize our buffer to it. (when proj @@ -561,30 +564,29 @@ Sets buffer local variables for EDE." This global minor mode enables `ede-minor-mode' in all buffers in an EDE controlled project." :global t - :group 'ede (if global-ede-mode ;; Turn on global-ede-mode (progn (if semantic-mode (define-key cedet-menu-map [cedet-menu-separator] '("--"))) - (add-hook 'semanticdb-project-predicate-functions 'ede-directory-project-p) - (add-hook 'semanticdb-project-root-functions 'ede-toplevel-project-or-nil) - (add-hook 'ecb-source-path-functions 'ede-ecb-project-paths) + (add-hook 'semanticdb-project-predicate-functions #'ede-directory-project-p) + (add-hook 'semanticdb-project-root-functions #'ede-toplevel-project-or-nil) + (add-hook 'ecb-source-path-functions #'ede-ecb-project-paths) ;; Append our hook to the end. This allows mode-local to finish ;; it's stuff before we start doing misc file loads, etc. - (add-hook 'find-file-hook 'ede-turn-on-hook t) - (add-hook 'dired-mode-hook 'ede-turn-on-hook) - (add-hook 'kill-emacs-hook 'ede-save-cache) + (add-hook 'find-file-hook #'ede-turn-on-hook t) + (add-hook 'dired-mode-hook #'ede-turn-on-hook) + (add-hook 'kill-emacs-hook #'ede-save-cache) (ede-load-cache) (ede-reset-all-buffers)) ;; Turn off global-ede-mode (define-key cedet-menu-map [cedet-menu-separator] nil) - (remove-hook 'semanticdb-project-predicate-functions 'ede-directory-project-p) - (remove-hook 'semanticdb-project-root-functions 'ede-toplevel-project-or-nil) - (remove-hook 'ecb-source-path-functions 'ede-ecb-project-paths) - (remove-hook 'find-file-hook 'ede-turn-on-hook) - (remove-hook 'dired-mode-hook 'ede-turn-on-hook) - (remove-hook 'kill-emacs-hook 'ede-save-cache) + (remove-hook 'semanticdb-project-predicate-functions #'ede-directory-project-p) + (remove-hook 'semanticdb-project-root-functions #'ede-toplevel-project-or-nil) + (remove-hook 'ecb-source-path-functions #'ede-ecb-project-paths) + (remove-hook 'find-file-hook #'ede-turn-on-hook) + (remove-hook 'dired-mode-hook #'ede-turn-on-hook) + (remove-hook 'kill-emacs-hook #'ede-save-cache) (ede-save-cache) (ede-reset-all-buffers))) @@ -1080,7 +1082,7 @@ Flush the dead projects from the project cache." (let ((dead nil)) (dolist (P ede-projects) (when (not (file-exists-p (oref P file))) - (add-to-list 'dead P))) + (cl-pushnew P dead :test #'equal))) (dolist (D dead) (ede-delete-project-from-global-list D)) )) @@ -1108,7 +1110,7 @@ Flush the dead projects from the project cache." "Project file independent way to read a project in from DIR. Optional DETECTIN is an autoload cons from `ede-detect-directory-for-project' which can be passed in to save time. -Optional ROOTRETURN will return the root project for DIR." +Optional ROOTRETURN reference will return the root project for DIR." ;; Don't do anything if we are in the process of ;; constructing an EDE object. ;; @@ -1147,7 +1149,8 @@ Optional ROOTRETURN will return the root project for DIR." (setq o (ede-auto-load-project autoloader toppath)))) ;; Return the found root project. - (when rootreturn (set rootreturn o)) + (when rootreturn (if (symbolp rootreturn) (set rootreturn o) + (setf (gv-deref rootreturn) o))) ;; The project has been found (in the global list) or loaded from ;; disk (via autoloader.) We can now search for the project asked @@ -1504,6 +1507,8 @@ It does not apply the value to buffers." ;;; Integration with project.el (defun project-try-ede (dir) + ;; FIXME: This passes the `ROOT' dynbound variable, but I don't know + ;; where it comes from! (let ((project-dir (locate-dominating-file dir @@ -1523,7 +1528,7 @@ It does not apply the value to buffers." (provide 'ede) ;; Include this last because it depends on ede. -(require 'ede/files) +(if t (require 'ede/files)) ;; Don't bother loading it at compile-time. ;; If this does not occur after the provide, we can get a recursive ;; load. Yuck! diff --git a/lisp/cedet/ede/auto.el b/lisp/cedet/ede/auto.el index e1417d7806..ee9d0116af 100644 --- a/lisp/cedet/ede/auto.el +++ b/lisp/cedet/ede/auto.el @@ -1,4 +1,4 @@ -;;; ede/auto.el --- Autoload features for EDE +;;; ede/auto.el --- Autoload features for EDE -*- lexical-binding: t; -*- ;; Copyright (C) 2010-2021 Free Software Foundation, Inc. @@ -325,13 +325,13 @@ NOTE: Do not call this - it should only be called from `ede-load-project-file'." ;; See if we can do without them. ;; @FIXME - delete from loaddefs to remove this. -(cl-defmethod ede-project-root ((this ede-project-autoload)) +(cl-defmethod ede-project-root ((_this ede-project-autoload)) "If a project knows its root, return it here. Allows for one-project-object-for-a-tree type systems." nil) ;; @FIXME - delete from loaddefs to remove this. -(cl-defmethod ede-project-root-directory ((this ede-project-autoload) &optional file) +(cl-defmethod ede-project-root-directory ((_this ede-project-autoload) &optional _file) "" nil) (provide 'ede/auto) diff --git a/lisp/cedet/ede/autoconf-edit.el b/lisp/cedet/ede/autoconf-edit.el index ca8535fdf2..d6f0a86f9a 100644 --- a/lisp/cedet/ede/autoconf-edit.el +++ b/lisp/cedet/ede/autoconf-edit.el @@ -1,4 +1,4 @@ -;;; ede/autoconf-edit.el --- Keymap for autoconf +;;; ede/autoconf-edit.el --- Keymap for autoconf -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2000, 2009-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/ede/config.el b/lisp/cedet/ede/config.el index 19686216cd..bc1810aa84 100644 --- a/lisp/cedet/ede/config.el +++ b/lisp/cedet/ede/config.el @@ -1,4 +1,4 @@ -;;; ede/config.el --- Configuration Handler baseclass +;;; ede/config.el --- Configuration Handler baseclass -*- lexical-binding: t; -*- ;; Copyright (C) 2014-2021 Free Software Foundation, Inc. @@ -171,7 +171,7 @@ the directory isn't on the `safe' list, ask to add it to the safe list." (oset config project proj))) config)) -(cl-defmethod ede-config-setup-configuration ((proj ede-project-with-config) config) +(cl-defmethod ede-config-setup-configuration ((_proj ede-project-with-config) _config) "Default configuration setup method." nil) @@ -187,7 +187,7 @@ the directory isn't on the `safe' list, ask to add it to the safe list." (let ((config (ede-config-get-configuration proj t))) (eieio-customize-object config))) -(cl-defmethod ede-customize ((target ede-target-with-config)) +(cl-defmethod ede-customize ((_target ede-target-with-config)) "Customize the EDE TARGET by actually configuring the config object." ;; Nothing unique for the targets, use the project. (ede-customize-project)) @@ -302,14 +302,14 @@ This class brings in method overloads for building.") "Class to mix into a project with configuration for builds. This class brings in method overloads for building.") -(cl-defmethod project-compile-project ((proj ede-project-with-config-build) &optional command) +(cl-defmethod project-compile-project ((proj ede-project-with-config-build) &optional _command) "Compile the entire current project PROJ. Argument COMMAND is the command to use when compiling." (let* ((config (ede-config-get-configuration proj t)) (comp (oref config build-command))) (compile comp))) -(cl-defmethod project-compile-target ((obj ede-target-with-config-build) &optional command) +(cl-defmethod project-compile-target ((_obj ede-target-with-config-build) &optional command) "Compile the current target OBJ. Argument COMMAND is the command to use for compiling the target." (project-compile-project (ede-current-project) command)) diff --git a/lisp/cedet/ede/cpp-root.el b/lisp/cedet/ede/cpp-root.el index 41f0c68289..652d6476f0 100644 --- a/lisp/cedet/ede/cpp-root.el +++ b/lisp/cedet/ede/cpp-root.el @@ -1,4 +1,4 @@ -;;; ede/cpp-root.el --- A simple way to wrap a C++ project with a single root +;;; ede/cpp-root.el --- A simple way to wrap a C++ project with a single root -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. @@ -275,7 +275,7 @@ Each directory needs a project file to control it.") ;; objects is deleted. (cl-defmethod initialize-instance ((this ede-cpp-root-project) - &rest fields) + &rest _fields) "Make sure the :file is fully expanded." ;; Add ourselves to the master list (cl-call-next-method) @@ -310,7 +310,7 @@ Each directory needs a project file to control it.") ;; project, simplifying authoring new single-point projects. (cl-defmethod ede-find-subproject-for-directory ((proj ede-cpp-root-project) - dir) + _dir) "Return PROJ, for handling all subdirs below DIR." proj) @@ -319,7 +319,7 @@ Each directory needs a project file to control it.") ;; Creating new targets on a per directory basis is a good way to keep ;; files organized. See ede-emacs for an example with multiple file ;; types. -(cl-defmethod ede-find-target ((proj ede-cpp-root-project) buffer) +(cl-defmethod ede-find-target ((proj ede-cpp-root-project) _buffer) "Find an EDE target in PROJ for BUFFER. If one doesn't exist, create a new one for this directory." (let* ((targets (oref proj targets)) @@ -451,7 +451,7 @@ This is for project include paths and spp source files." "Get the pre-processor map for project THIS." (ede-preprocessor-map (ede-target-parent this))) -(cl-defmethod project-compile-project ((proj ede-cpp-root-project) &optional command) +(cl-defmethod project-compile-project ((proj ede-cpp-root-project) &optional _command) "Compile the entire current project PROJ. Argument COMMAND is the command to use when compiling." ;; we need to be in the proj root dir for this to work @@ -474,7 +474,7 @@ Argument COMMAND is the command to use for compiling the target." (project-compile-project (oref obj project) command))) -(cl-defmethod project-rescan ((this ede-cpp-root-project)) +(cl-defmethod project-rescan ((_this ede-cpp-root-project)) "Don't rescan this project from the sources." (message "cpp-root has nothing to rescan.")) diff --git a/lisp/cedet/ede/custom.el b/lisp/cedet/ede/custom.el index a128f9e124..adb1a49cdf 100644 --- a/lisp/cedet/ede/custom.el +++ b/lisp/cedet/ede/custom.el @@ -1,4 +1,4 @@ -;;; ede/custom.el --- customization of EDE projects. +;;; ede/custom.el --- customization of EDE projects. -*- lexical-binding: t; -*- ;; Copyright (C) 2010-2021 Free Software Foundation, Inc. @@ -97,13 +97,13 @@ OBJ is the target object to customize." "Create a custom-like buffer for sorting targets of current project." (interactive) (let ((proj (ede-current-project)) - (count 1) - current order) + ;; (count 1) + ) ;; current order (switch-to-buffer (get-buffer-create "*EDE sort targets*")) (erase-buffer) (setq ede-object-project proj) (widget-create 'push-button - :notify (lambda (&rest ignore) + :notify (lambda (&rest _ignore) (let ((targets (oref ede-object-project targets)) cur newtargets) (while (setq cur (pop ede-project-sort-targets-order)) @@ -115,7 +115,7 @@ OBJ is the target object to customize." " Accept ") (widget-insert " ") (widget-create 'push-button - :notify (lambda (&rest ignore) + :notify (lambda (&rest _ignore) (kill-buffer)) " Cancel ") (widget-insert "\n\n") @@ -170,7 +170,9 @@ OBJ is the target object to customize." (widget-insert " ")) (widget-insert (concat " " (number-to-string (1+ count)) ".: " (oref (nth (nth count ede-project-sort-targets-order) - targets) name) "\n")) + targets) + name) + "\n")) (setq count (1+ count)))))) ;;; Customization hooks @@ -195,11 +197,11 @@ OBJ is the target object to customize." ;; These two methods should be implemented by subclasses of ;; project and targets in order to account for user specified ;; changes. -(cl-defmethod eieio-done-customizing ((target ede-target)) +(cl-defmethod eieio-done-customizing ((_target ede-target)) "Call this when a user finishes customizing TARGET." nil) -(cl-defmethod ede-commit-project ((proj ede-project)) +(cl-defmethod ede-commit-project ((_proj ede-project)) "Commit any change to PROJ to its file." nil ) diff --git a/lisp/cedet/ede/detect.el b/lisp/cedet/ede/detect.el index 027d008ea3..c933fc4515 100644 --- a/lisp/cedet/ede/detect.el +++ b/lisp/cedet/ede/detect.el @@ -1,4 +1,4 @@ -;;; ede/detect.el --- EDE project detection and file associations +;;; ede/detect.el --- EDE project detection and file associations -*- lexical-binding: t; -*- ;; Copyright (C) 2014-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/ede/dired.el b/lisp/cedet/ede/dired.el index 8b9eae0b43..27735176c2 100644 --- a/lisp/cedet/ede/dired.el +++ b/lisp/cedet/ede/dired.el @@ -35,11 +35,11 @@ (defvar ede-dired-keymap (let ((map (make-sparse-keymap))) - (define-key map ".a" 'ede-dired-add-to-target) - (define-key map ".t" 'ede-new-target) - (define-key map ".s" 'ede-speedbar) - (define-key map ".C" 'ede-compile-project) - (define-key map ".d" 'ede-make-dist) + (define-key map ".a" #'ede-dired-add-to-target) + (define-key map ".t" #'ede-new-target) + (define-key map ".s" #'ede-speedbar) + (define-key map ".C" #'ede-compile-project) + (define-key map ".d" #'ede-make-dist) (easy-menu-define ede-dired-menu map "EDE Dired Minor Mode Menu" diff --git a/lisp/cedet/ede/files.el b/lisp/cedet/ede/files.el index cf5396ad00..6b7e159564 100644 --- a/lisp/cedet/ede/files.el +++ b/lisp/cedet/ede/files.el @@ -1,4 +1,4 @@ -;;; ede/files.el --- Associate projects with files and directories. +;;; ede/files.el --- Associate projects with files and directories. -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -33,6 +33,7 @@ ;; till no ede-project-autoload structure matches. ;; +(require 'eieio) (require 'ede) (declare-function ede-locate-file-in-hash "ede/locate") @@ -75,13 +76,13 @@ Allows for one-project-object-for-a-tree type systems." (oref this rootproject)) (cl-defmethod ede-project-root-directory ((this ede-project-placeholder) - &optional file) + &optional _file) "If a project knows its root, return it here. Allows for one-project-object-for-a-tree type systems. Optional FILE is the file to test. It is ignored in preference of the anchor file for the project." - (let ((root (or (ede-project-root this) this))) - (file-name-directory (expand-file-name (oref this file))))) + ;; (let ((root (or (ede-project-root this) this))) + (file-name-directory (expand-file-name (oref this file)))) ;; ) ;; Why INODEs? @@ -141,7 +142,7 @@ Does not check subprojects." (defun ede-directory-get-open-project (dir &optional rootreturn) "Return an already open project that is managing DIR. -Optional ROOTRETURN specifies a symbol to set to the root project. +Optional ROOTRETURN specifies a `gv-ref' to set to the root project. If DIR is the root project, then it is the same." (let* ((inode (ede--inode-for-dir dir)) (ft (file-name-as-directory (expand-file-name dir))) @@ -153,7 +154,8 @@ If DIR is the root project, then it is the same." ;; Default answer is this project (setq ans proj) ;; Save. - (when rootreturn (set rootreturn proj)) + (when rootreturn (if (symbolp rootreturn) (set rootreturn proj) + (setf (gv-deref rootreturn) proj))) ;; Find subprojects. (when (and proj (if ede--disable-inode (not (string= ft (expand-file-name @@ -272,7 +274,7 @@ Do this whenever a new project is created, as opposed to loaded." (remhash (file-name-as-directory dir) ede-project-directory-hash) ;; Look for all subdirs of D, and remove them. (let ((match (concat "^" (regexp-quote dir)))) - (maphash (lambda (K O) + (maphash (lambda (K _O) (when (string-match match K) (remhash K ede-project-directory-hash))) ede-project-directory-hash))) @@ -363,7 +365,7 @@ If DIR is not part of a project, return nil." (t nil)))) -(defalias 'ede-toplevel-project-or-nil 'ede-toplevel-project) +(defalias 'ede-toplevel-project-or-nil #'ede-toplevel-project) ;;; DIRECTORY CONVERSION STUFF ;; @@ -469,15 +471,15 @@ is returned." ans)) -(cl-defmethod ede-expand-filename-impl ((this ede-project) filename &optional force) +(cl-defmethod ede-expand-filename-impl ((this ede-project) filename &optional _force) "Return a fully qualified file name based on project THIS. FILENAME should be just a filename which occurs in a directory controlled by this project. Optional argument FORCE forces the default filename to be provided even if it doesn't exist." (let ((loc (ede-get-locator-object this)) - (path (ede-project-root-directory this)) - (proj (oref this subproj)) + ;; (path (ede-project-root-directory this)) + ;; (proj (oref this subproj)) (found nil)) ;; find it Locally. (setq found (or (ede-expand-filename-local this filename) diff --git a/lisp/cedet/ede/generic.el b/lisp/cedet/ede/generic.el index 3d1e1c5818..b3b59b5dc3 100644 --- a/lisp/cedet/ede/generic.el +++ b/lisp/cedet/ede/generic.el @@ -1,4 +1,4 @@ -;;; ede/generic.el --- Base Support for generic build systems +;;; ede/generic.el --- Base Support for generic build systems -*- lexical-binding: t; -*- ;; Copyright (C) 2010-2021 Free Software Foundation, Inc. @@ -93,7 +93,7 @@ ) "User Configuration object for a generic project.") -(defun ede-generic-load (dir &optional rootproj) +(defun ede-generic-load (dir &optional _rootproj) "Return a Generic Project object if there is a match. Return nil if there isn't one. Argument DIR is the directory it is created for. @@ -149,7 +149,7 @@ The class allocated value is replace by different sub classes.") :abstract t) (cl-defmethod initialize-instance ((this ede-generic-project) - &rest fields) + &rest _fields) "Make sure the targets slot is bound." (cl-call-next-method) (unless (slot-boundp this 'targets) @@ -161,7 +161,7 @@ The class allocated value is replace by different sub classes.") this) (cl-defmethod ede-find-subproject-for-directory ((proj ede-generic-project) - dir) + _dir) "Return PROJ, for handling all subdirs below DIR." proj) @@ -324,7 +324,7 @@ CLASS is the EIEIO class that is used to track this project. It should subclass ) "Generic Project for makefiles.") -(cl-defmethod ede-generic-setup-configuration ((proj ede-generic-makefile-project) config) +(cl-defmethod ede-generic-setup-configuration ((_proj ede-generic-makefile-project) config) "Setup a configuration for Make." (oset config build-command "make -k") (oset config debug-command "gdb ") @@ -337,7 +337,7 @@ CLASS is the EIEIO class that is used to track this project. It should subclass ) "Generic Project for scons.") -(cl-defmethod ede-generic-setup-configuration ((proj ede-generic-scons-project) config) +(cl-defmethod ede-generic-setup-configuration ((_proj ede-generic-scons-project) config) "Setup a configuration for SCONS." (oset config build-command "scons") (oset config debug-command "gdb ") @@ -350,7 +350,7 @@ CLASS is the EIEIO class that is used to track this project. It should subclass ) "Generic Project for cmake.") -(cl-defmethod ede-generic-setup-configuration ((proj ede-generic-cmake-project) config) +(cl-defmethod ede-generic-setup-configuration ((_proj ede-generic-cmake-project) config) "Setup a configuration for CMake." (oset config build-command "cmake") (oset config debug-command "gdb ") @@ -361,9 +361,9 @@ CLASS is the EIEIO class that is used to track this project. It should subclass () "Generic project found via Version Control files.") -(cl-defmethod ede-generic-setup-configuration ((proj ede-generic-vc-project) config) +(cl-defmethod ede-generic-setup-configuration ((_proj ede-generic-vc-project) _config) "Setup a configuration for projects identified by revision control." - ) + nil) (provide 'ede/generic) diff --git a/lisp/cedet/ede/linux.el b/lisp/cedet/ede/linux.el index 7a1c4c9e26..4b5530d6ac 100644 --- a/lisp/cedet/ede/linux.el +++ b/lisp/cedet/ede/linux.el @@ -1,4 +1,4 @@ -;;; ede/linux.el --- Special project for Linux +;;; ede/linux.el --- Special project for Linux -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -47,26 +47,22 @@ (defcustom project-linux-build-directory-default 'ask "Build directory." :version "24.4" - :group 'project-linux :type '(choice (const :tag "Same as source directory" same) (const :tag "Ask the user" ask))) (defcustom project-linux-architecture-default 'ask "Target architecture to assume when not auto-detected." :version "24.4" - :group 'project-linux :type '(choice (string :tag "Architecture name") (const :tag "Ask the user" ask))) (defcustom project-linux-compile-target-command (concat ede-make-command " -k -C %s SUBDIRS=%s") "Default command used to compile a target." - :group 'project-linux :type 'string) (defcustom project-linux-compile-project-command (concat ede-make-command " -k -C %s") "Default command used to compile a project." - :group 'project-linux :type 'string) (defun ede-linux-version (dir) diff --git a/lisp/cedet/ede/locate.el b/lisp/cedet/ede/locate.el index e6a89533cc..016092cd8b 100644 --- a/lisp/cedet/ede/locate.el +++ b/lisp/cedet/ede/locate.el @@ -1,4 +1,4 @@ -;;; ede/locate.el --- Locate support +;;; ede/locate.el --- Locate support -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -110,7 +110,7 @@ based on `ede-locate-setup-options'." ) "Baseclass for LOCATE feature in EDE.") -(cl-defmethod initialize-instance ((loc ede-locate-base) &rest fields) +(cl-defmethod initialize-instance ((loc ede-locate-base) &rest _fields) "Make sure we have a hash table." ;; Basic setup. (cl-call-next-method) @@ -118,8 +118,8 @@ based on `ede-locate-setup-options'." (ede-locate-flush-hash loc) ) -(cl-defmethod ede-locate-ok-in-project ((loc (subclass ede-locate-base)) - root) +(cl-defmethod ede-locate-ok-in-project ((_loc (subclass ede-locate-base)) + _root) "Is it ok to use this project type under ROOT." t) @@ -149,17 +149,15 @@ that created this EDE locate object." (oset loc lastanswer ans) ans)) -(cl-defmethod ede-locate-file-in-project-impl ((loc ede-locate-base) - filesubstring - ) +(cl-defmethod ede-locate-file-in-project-impl ((_loc ede-locate-base) + _filesubstring) "Locate with LOC occurrences of FILESUBSTRING. Searches are done under the current root of the EDE project that created this EDE locate object." - nil - ) + nil) (cl-defmethod ede-locate-create/update-root-database - ((loc (subclass ede-locate-base)) root) + ((loc (subclass ede-locate-base)) _root) "Create or update the database for the current project. You cannot create projects for the baseclass." (error "Cannot create/update a database of type %S" @@ -177,8 +175,8 @@ You cannot create projects for the baseclass." Configure the Emacs `locate-program' variable to also configure the use of EDE locate.") -(cl-defmethod ede-locate-ok-in-project ((loc (subclass ede-locate-locate)) - root) +(cl-defmethod ede-locate-ok-in-project ((_loc (subclass ede-locate-locate)) + _root) "Is it ok to use this project type under ROOT." (or (featurep 'locate) (locate-library "locate")) ) @@ -198,7 +196,7 @@ that created this EDE locate object." (with-current-buffer b (setq default-directory cd) (erase-buffer)) - (apply 'call-process locate-command + (apply #'call-process locate-command nil b nil searchstr nil) (with-current-buffer b @@ -221,7 +219,7 @@ Configure EDE's use of GNU Global through the cedet-global.el variable `cedet-global-command'.") (cl-defmethod initialize-instance ((loc ede-locate-global) - &rest slots) + &rest _slots) "Make sure that we can use GNU Global." (require 'cedet-global) ;; Get ourselves initialized. @@ -235,8 +233,8 @@ variable `cedet-global-command'.") (oref loc root)))) ) -(cl-defmethod ede-locate-ok-in-project ((loc (subclass ede-locate-global)) - root) +(cl-defmethod ede-locate-ok-in-project ((_loc (subclass ede-locate-global)) + root) "Is it ok to use this project type under ROOT." (require 'cedet-global) (cedet-gnu-global-version-check) @@ -252,7 +250,7 @@ variable `cedet-global-command'.") (cedet-gnu-global-expand-filename filesubstring))) (cl-defmethod ede-locate-create/update-root-database - ((loc (subclass ede-locate-global)) root) + ((_loc (subclass ede-locate-global)) root) "Create or update the GNU Global database for the current project." (cedet-gnu-global-create/update-database root)) @@ -271,7 +269,7 @@ Configure EDE's use of IDUtils through the cedet-idutils.el file name searching variable `cedet-idutils-file-command'.") (cl-defmethod initialize-instance ((loc ede-locate-idutils) - &rest slots) + &rest _slots) "Make sure that we can use IDUtils." ;; Get ourselves initialized. (cl-call-next-method) @@ -283,8 +281,8 @@ file name searching variable `cedet-idutils-file-command'.") (oref loc root))) ) -(cl-defmethod ede-locate-ok-in-project ((loc (subclass ede-locate-idutils)) - root) +(cl-defmethod ede-locate-ok-in-project ((_loc (subclass ede-locate-idutils)) + root) "Is it ok to use this project type under ROOT." (require 'cedet-idutils) (cedet-idutils-version-check) @@ -301,7 +299,7 @@ that created this EDE locate object." (cedet-idutils-expand-filename filesubstring))) (cl-defmethod ede-locate-create/update-root-database - ((loc (subclass ede-locate-idutils)) root) + ((_loc (subclass ede-locate-idutils)) root) "Create or update the GNU Global database for the current project." (cedet-idutils-create/update-database root)) @@ -320,7 +318,7 @@ Configure EDE's use of Cscope through the cedet-cscope.el file name searching variable `cedet-cscope-file-command'.") (cl-defmethod initialize-instance ((loc ede-locate-cscope) - &rest slots) + &rest _slots) "Make sure that we can use Cscope." ;; Get ourselves initialized. (cl-call-next-method) @@ -332,8 +330,8 @@ file name searching variable `cedet-cscope-file-command'.") (oref loc root))) ) -(cl-defmethod ede-locate-ok-in-project ((loc (subclass ede-locate-cscope)) - root) +(cl-defmethod ede-locate-ok-in-project ((_loc (subclass ede-locate-cscope)) + root) "Is it ok to use this project type under ROOT." (require 'cedet-cscope) (cedet-cscope-version-check) @@ -350,7 +348,7 @@ that created this EDE locate object." (cedet-cscope-expand-filename filesubstring))) (cl-defmethod ede-locate-create/update-root-database - ((loc (subclass ede-locate-cscope)) root) + ((_loc (subclass ede-locate-cscope)) root) "Create or update the Cscope database for the current project." (require 'cedet-cscope) (cedet-cscope-create/update-database root)) diff --git a/lisp/cedet/ede/makefile-edit.el b/lisp/cedet/ede/makefile-edit.el index 43655a5d1e..d696594549 100644 --- a/lisp/cedet/ede/makefile-edit.el +++ b/lisp/cedet/ede/makefile-edit.el @@ -1,4 +1,4 @@ -;;; makefile-edit.el --- Makefile editing/scanning commands. +;;; makefile-edit.el --- Makefile editing/scanning commands. -*- lexical-binding: t; -*- ;; Copyright (C) 2009-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/ede/pconf.el b/lisp/cedet/ede/pconf.el index 5bed32ff05..106ba2cf5b 100644 --- a/lisp/cedet/ede/pconf.el +++ b/lisp/cedet/ede/pconf.el @@ -1,4 +1,4 @@ -;;; ede/pconf.el --- configure.ac maintenance for EDE +;;; ede/pconf.el --- configure.ac maintenance for EDE -*- lexical-binding: t; -*- ;;; Copyright (C) 1998-2000, 2005, 2008-2021 Free Software Foundation, ;;; Inc. @@ -67,7 +67,7 @@ don't do it. A value of nil means to just do it.") ;;(td (file-name-directory (ede-proj-configure-file this))) (targs (oref this targets)) (postcmd "") - (add-missing nil)) + ) ;; (add-missing nil) ;; First, make sure we have a file. (if (not (file-exists-p (ede-proj-configure-file this))) (autoconf-new-program b (oref this name) "Project.ede")) @@ -97,7 +97,7 @@ don't do it. A value of nil means to just do it.") (ede-map-targets sp #'ede-proj-flush-autoconf))) (ede-map-all-subprojects this - (lambda (sp) + (lambda (_sp) (ede-map-targets this #'ede-proj-tweak-autoconf))) ;; Now save (save-buffer) @@ -109,14 +109,15 @@ don't do it. A value of nil means to just do it.") (ede-proj-configure-test-required-file this "README") (ede-proj-configure-test-required-file this "ChangeLog") ;; Let specific targets get missing files. - (mapc 'ede-proj-configure-create-missing targs) + (mapc #'ede-proj-configure-create-missing targs) ;; Verify that we have a make system. (if (or (not (ede-expand-filename (ede-toplevel this) "Makefile")) ;; Now is this one of our old Makefiles? (with-current-buffer (find-file-noselect (ede-expand-filename (ede-toplevel this) - "Makefile" t) t) + "Makefile" t) + t) (goto-char (point-min)) ;; Here is the unique piece for our makefiles. (re-search-forward "For use with: make" nil t))) @@ -166,11 +167,11 @@ don't do it. A value of nil means to just do it.") "Tweak the configure file (current buffer) to accommodate THIS." ;; Check the compilers belonging to THIS, and call the autoconf ;; setup for those compilers. - (mapc 'ede-proj-tweak-autoconf (ede-proj-compilers this)) - (mapc 'ede-proj-tweak-autoconf (ede-proj-linkers this)) + (mapc #'ede-proj-tweak-autoconf (ede-proj-compilers this)) + (mapc #'ede-proj-tweak-autoconf (ede-proj-linkers this)) ) -(cl-defmethod ede-proj-flush-autoconf ((this ede-proj-target)) +(cl-defmethod ede-proj-flush-autoconf ((_this ede-proj-target)) "Flush the configure file (current buffer) to accommodate THIS. By flushing, remove any cruft that may be in the file. Subsequent calls to `ede-proj-tweak-autoconf' can restore items removed by flush." @@ -178,13 +179,13 @@ calls to `ede-proj-tweak-autoconf' can restore items removed by flush." ;; @TODO - No-one calls this ??? -(cl-defmethod ede-proj-configure-add-missing ((this ede-proj-target)) +(cl-defmethod ede-proj-configure-add-missing ((_this ede-proj-target)) "Query if any files needed by THIS provided by automake are missing. Results in --add-missing being passed to automake." nil) ;; @TODO - No-one implements this yet. -(cl-defmethod ede-proj-configure-create-missing ((this ede-proj-target)) +(cl-defmethod ede-proj-configure-create-missing ((_this ede-proj-target)) "Add any missing files for THIS by creating them." nil) diff --git a/lisp/cedet/ede/pmake.el b/lisp/cedet/ede/pmake.el index 47bb0c61eb..ceb44031f6 100644 --- a/lisp/cedet/ede/pmake.el +++ b/lisp/cedet/ede/pmake.el @@ -46,6 +46,7 @@ (require 'ede/proj) (require 'ede/proj-obj) (require 'ede/proj-comp) +(require 'seq) (declare-function ede-srecode-setup "ede/srecode") (declare-function ede-srecode-insert "ede/srecode") @@ -111,13 +112,13 @@ MFILENAME is the makefile to generate." (let* ((targ (if isdist (oref this targets) mt)) (sp (oref this subproj)) - (df (apply 'append + (df (apply #'append (mapcar (lambda (tg) (ede-proj-makefile-dependency-files tg)) targ)))) ;; Distribution variables (ede-compiler-begin-unique - (mapc 'ede-proj-makefile-insert-variables targ)) + (mapc #'ede-proj-makefile-insert-variables targ)) ;; Only add the distribution stuff in when depth != 0 (let ((top (ede-toplevel this)) (tmp this) @@ -153,7 +154,8 @@ MFILENAME is the makefile to generate." (concat ".deps/" (file-name-nondirectory (file-name-sans-extension - f)) ".P")) + f)) + ".P")) df " ")))) ;; ;; Insert ALL Rule @@ -188,11 +190,11 @@ MFILENAME is the makefile to generate." ;; (ede-compiler-begin-unique (ede-proj-makefile-insert-rules this) - (mapc 'ede-proj-makefile-insert-rules targ)) + (mapc #'ede-proj-makefile-insert-rules targ)) ;; ;; phony targets for sub projects ;; - (mapc 'ede-proj-makefile-insert-subproj-rules sp) + (mapc #'ede-proj-makefile-insert-subproj-rules sp) ;; ;; Distribution rules such as CLEAN and DIST ;; @@ -210,11 +212,11 @@ MFILENAME is the makefile to generate." ;; Distribution variables (let ((targ (if isdist (oref this targets) mt))) (ede-compiler-begin-unique - (mapc 'ede-proj-makefile-insert-automake-pre-variables targ)) + (mapc #'ede-proj-makefile-insert-automake-pre-variables targ)) (ede-compiler-begin-unique - (mapc 'ede-proj-makefile-insert-source-variables targ)) + (mapc #'ede-proj-makefile-insert-source-variables targ)) (ede-compiler-begin-unique - (mapc 'ede-proj-makefile-insert-automake-post-variables targ)) + (mapc #'ede-proj-makefile-insert-automake-post-variables targ)) (ede-compiler-begin-unique (ede-proj-makefile-insert-user-rules this)) (insert "\n# End of Makefile.am\n") @@ -464,9 +466,9 @@ sources variable." "Return a list of patterns that are considered garbage to THIS. These are removed with make clean." (let ((mc (ede-map-targets - this (lambda (c) (ede-proj-makefile-garbage-patterns c)))) + this #'ede-proj-makefile-garbage-patterns)) (uniq nil)) - (setq mc (sort (apply 'append mc) 'string<)) + (setq mc (sort (apply #'append mc) #'string<)) ;; Filter out duplicates from the targets. (while mc (if (and (car uniq) (string= (car uniq) (car mc))) @@ -502,13 +504,13 @@ These are removed with make clean." (cl-defmethod ede-proj-makefile-insert-rules ((this ede-proj-project)) "Insert rules needed by THIS target." - (mapc 'ede-proj-makefile-insert-rules (oref this inference-rules)) + (mapc #'ede-proj-makefile-insert-rules (oref this inference-rules)) ) (cl-defmethod ede-proj-makefile-insert-dist-dependencies ((this ede-proj-project)) "Insert any symbols that the DIST rule should depend on. Argument THIS is the project that should insert stuff." - (mapc 'ede-proj-makefile-insert-dist-dependencies (oref this targets)) + (mapc #'ede-proj-makefile-insert-dist-dependencies (oref this targets)) ) (cl-defmethod ede-proj-makefile-insert-dist-dependencies ((_this ede-proj-target)) @@ -608,10 +610,10 @@ Argument THIS is the target that should insert stuff." (cl-defmethod ede-proj-makefile-insert-rules ((this ede-proj-target-makefile)) "Insert rules needed by THIS target." - (mapc 'ede-proj-makefile-insert-rules (oref this rules)) + (mapc #'ede-proj-makefile-insert-rules (oref this rules)) (let ((c (ede-proj-compilers this))) (when c - (mapc 'ede-proj-makefile-insert-rules c) + (mapc #'ede-proj-makefile-insert-rules c) (if (oref this phony) (insert ".PHONY: " (ede-proj-makefile-target-name this) "\n")) (insert (ede-proj-makefile-target-name this) ": " @@ -622,9 +624,9 @@ Argument THIS is the target that should insert stuff." (cl-defmethod ede-proj-makefile-insert-commands ((this ede-proj-target-makefile)) "Insert the commands needed by target THIS. For targets, insert the commands needed by the chosen compiler." - (mapc 'ede-proj-makefile-insert-commands (ede-proj-compilers this)) + (mapc #'ede-proj-makefile-insert-commands (ede-proj-compilers this)) (when (object-assoc t :uselinker (ede-proj-compilers this)) - (mapc 'ede-proj-makefile-insert-commands (ede-proj-linkers this)))) + (mapc #'ede-proj-makefile-insert-commands (ede-proj-linkers this)))) (cl-defmethod ede-proj-makefile-insert-user-rules ((this ede-proj-project)) @@ -632,11 +634,11 @@ For targets, insert the commands needed by the chosen compiler." This is different from `ede-proj-makefile-insert-rules' in that this function won't create the building rules which are auto created with automake." - (mapc 'ede-proj-makefile-insert-user-rules (oref this inference-rules))) + (mapc #'ede-proj-makefile-insert-user-rules (oref this inference-rules))) (cl-defmethod ede-proj-makefile-insert-user-rules ((this ede-proj-target)) "Insert user specified rules needed by THIS target." - (mapc 'ede-proj-makefile-insert-rules (oref this rules))) + (mapc #'ede-proj-makefile-insert-rules (oref this rules))) (cl-defmethod ede-proj-makefile-dependencies ((this ede-proj-target-makefile)) "Return a string representing the dependencies for THIS. @@ -644,7 +646,7 @@ Some compilers only use the first element in the dependencies, others have a list of intermediates (object files), and others don't care. This allows customization of how these elements appear." (let* ((c (ede-proj-compilers this)) - (io (eval (cons 'or (mapcar 'ede-compiler-intermediate-objects-p c)))) + (io (seq-some #'ede-compiler-intermediate-objects-p c)) (out nil)) (if io (progn @@ -652,7 +654,8 @@ This allows customization of how these elements appear." (setq out (concat out "$(" (ede-compiler-intermediate-object-variable (car c) - (ede-proj-makefile-target-name this)) ")") + (ede-proj-makefile-target-name this)) + ")") c (cdr c))) out) (let ((sv (ede-proj-makefile-sourcevar this)) diff --git a/lisp/cedet/ede/proj-comp.el b/lisp/cedet/ede/proj-comp.el index 397354ad9c..1d6a4eb47c 100644 --- a/lisp/cedet/ede/proj-comp.el +++ b/lisp/cedet/ede/proj-comp.el @@ -309,7 +309,7 @@ Not all compilers do this." (cl-defmethod ede-proj-makefile-insert-rules ((this ede-compilation-program)) "Insert rules needed for THIS compiler object." (ede-compiler-only-once this - (mapc 'ede-proj-makefile-insert-rules (oref this rules)))) + (mapc #'ede-proj-makefile-insert-rules (oref this rules)))) (cl-defmethod ede-proj-makefile-insert-rules ((this ede-makefile-rule)) "Insert rules needed for THIS rule object." diff --git a/lisp/cedet/ede/proj-elisp.el b/lisp/cedet/ede/proj-elisp.el index 9ec96945c1..7e0f5a8934 100644 --- a/lisp/cedet/ede/proj-elisp.el +++ b/lisp/cedet/ede/proj-elisp.el @@ -1,4 +1,4 @@ -;;; ede-proj-elisp.el --- EDE Generic Project Emacs Lisp support +;;; ede-proj-elisp.el --- EDE Generic Project Emacs Lisp support -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2005, 2007-2021 Free Software Foundation, Inc. @@ -64,7 +64,7 @@ This inserts the PRELOADS target-local variable." (when preloads (insert (format "%s: PRELOADS=%s\n" (oref this name) - (mapconcat 'identity preloads " "))))) + (mapconcat #'identity preloads " "))))) (insert "\n")) (cl-defmethod ede-proj-makefile-dependencies ((this ede-proj-target-elisp)) @@ -152,7 +152,7 @@ Bonus: Return a cons cell: (COMPILED . UPTODATE)." (utd 0)) (mapc (lambda (src) (let* ((fsrc (expand-file-name src dir)) - (elc (concat (file-name-sans-extension fsrc) ".elc"))) + ) ;; (elc (concat (file-name-sans-extension fsrc) ".elc")) (with-no-warnings (if (eq (byte-recompile-file fsrc nil 0) t) (setq comp (1+ comp)) @@ -169,7 +169,7 @@ is found, such as a `-version' variable, or the standard header." (if (and (slot-boundp this 'versionsource) (oref this versionsource)) (let ((vs (oref this versionsource)) - (match nil)) + ) ;; (match nil) (while vs (with-current-buffer (find-file-noselect (ede-expand-filename this (car vs))) @@ -177,7 +177,7 @@ is found, such as a `-version' variable, or the standard header." (let ((case-fold-search t)) (if (re-search-forward "-version\\s-+\"\\([^\"]+\\)\"" nil t) (progn - (setq match t) + ;; (setq match t) (delete-region (match-beginning 1) (match-end 1)) (goto-char (match-beginning 1)) @@ -331,27 +331,27 @@ Lays claim to all .elc files that match .el files in this target." If the `compiler' slot is empty, get the car of the compilers list." (let ((comp (oref obj compiler))) (if comp - (if (listp comp) - (setq comp (mapcar 'symbol-value comp)) - (setq comp (list (symbol-value comp)))) + (setq comp (if (listp comp) + (mapcar #'symbol-value comp) + (list (symbol-value comp)))) ;; Get the first element from our list of compilers. - (let ((avail (mapcar 'symbol-value (oref obj availablecompilers)))) + (let ((avail (mapcar #'symbol-value (oref obj availablecompilers)))) (setq comp (list (car avail))))) comp)) -(cl-defmethod ede-proj-makefile-insert-source-variables ((this ede-proj-target-elisp-autoloads) - &optional - moresource) +(cl-defmethod ede-proj-makefile-insert-source-variables ((_this ede-proj-target-elisp-autoloads) + &optional + _moresource) "Insert the source variables needed by THIS. Optional argument MORESOURCE is a list of additional sources to add to the sources variable." nil) -(cl-defmethod ede-proj-makefile-sourcevar ((this ede-proj-target-elisp-autoloads)) +(cl-defmethod ede-proj-makefile-sourcevar ((_this ede-proj-target-elisp-autoloads)) "Return the variable name for THIS's sources." nil) ; "LOADDEFS") -(cl-defmethod ede-proj-makefile-dependencies ((this ede-proj-target-elisp-autoloads)) +(cl-defmethod ede-proj-makefile-dependencies ((_this ede-proj-target-elisp-autoloads)) "Return a string representing the dependencies for THIS. Always return an empty string for an autoloads generator." "") @@ -361,21 +361,22 @@ Always return an empty string for an autoloads generator." (ede-pmake-insert-variable-shared "LOADDEFS" (insert (oref this autoload-file))) (ede-pmake-insert-variable-shared "LOADDIRS" - (insert (mapconcat 'identity + (insert (mapconcat #'identity (or (oref this autoload-dirs) '(".")) " "))) ) (cl-defmethod project-compile-target ((obj ede-proj-target-elisp-autoloads)) "Create or update the autoload target." - (require 'cedet-autogen) + (require 'cedet-autogen) ;FIXME: We don't have this file! + (declare-function cedet-update-autoloads "cedet-autogen") (let ((default-directory (ede-expand-filename obj "."))) - (apply 'cedet-update-autoloads + (apply #'cedet-update-autoloads (oref obj autoload-file) (oref obj autoload-dirs)) )) -(cl-defmethod ede-update-version-in-source ((this ede-proj-target-elisp-autoloads) version) +(cl-defmethod ede-update-version-in-source ((_this ede-proj-target-elisp-autoloads) _version) "In a Lisp file, updated a version string for THIS to VERSION. There are standards in Elisp files specifying how the version string is found, such as a `-version' variable, or the standard header." @@ -397,11 +398,11 @@ Argument THIS is the target which needs to insert an info file." (insert " " (oref this autoload-file)) ) -(cl-defmethod ede-proj-tweak-autoconf ((this ede-proj-target-elisp-autoloads)) +(cl-defmethod ede-proj-tweak-autoconf ((_this ede-proj-target-elisp-autoloads)) "Tweak the configure file (current buffer) to accommodate THIS." (error "Autoloads not supported in autoconf yet")) -(cl-defmethod ede-proj-flush-autoconf ((this ede-proj-target-elisp-autoloads)) +(cl-defmethod ede-proj-flush-autoconf ((_this ede-proj-target-elisp-autoloads)) "Flush the configure file (current buffer) to accommodate THIS." nil) diff --git a/lisp/cedet/ede/proj-info.el b/lisp/cedet/ede/proj-info.el index 3d437016e9..11e0f302e2 100644 --- a/lisp/cedet/ede/proj-info.el +++ b/lisp/cedet/ede/proj-info.el @@ -1,4 +1,4 @@ -;;; ede-proj-info.el --- EDE Generic Project texinfo support +;;; ede-proj-info.el --- EDE Generic Project texinfo support -*- lexical-binding: t; -*- ;;; Copyright (C) 1998-2001, 2004, 2007-2021 Free Software Foundation, ;;; Inc. @@ -70,7 +70,7 @@ All other sources should be included independently.")) ;;; Makefile generation ;; (cl-defmethod ede-proj-configure-add-missing - ((this ede-proj-target-makefile-info)) + ((_this ede-proj-target-makefile-info)) "Query if any files needed by THIS provided by automake are missing. Results in --add-missing being passed to automake." (not (ede-expand-filename (ede-toplevel) "texinfo.tex"))) @@ -97,7 +97,7 @@ when working in Automake mode." (insert menu)) ;; Now insert the rest of the source elsewhere (ede-pmake-insert-variable-shared sv - (insert (mapconcat 'identity src " "))) + (insert (mapconcat #'identity src " "))) (if moresource (error "Texinfo files should not have moresource"))))) diff --git a/lisp/cedet/ede/proj-obj.el b/lisp/cedet/ede/proj-obj.el index 3aa4497f93..72d09167ab 100644 --- a/lisp/cedet/ede/proj-obj.el +++ b/lisp/cedet/ede/proj-obj.el @@ -1,4 +1,4 @@ -;;; ede/proj-obj.el --- EDE Generic Project Object code generation support +;;; ede/proj-obj.el --- EDE Generic Project Object code generation support -*- lexical-binding: t; -*- ;;; Copyright (C) 1998-2000, 2005, 2008-2021 Free Software Foundation, ;;; Inc. @@ -282,15 +282,15 @@ Argument THIS is the target to get sources from." (append (oref this source) (oref this auxsource))) (cl-defmethod ede-proj-makefile-insert-variables ((this ede-proj-target-makefile-objectcode) - &optional moresource) + &optional _moresource) "Insert variables needed by target THIS. Optional argument MORESOURCE is not used." (let ((ede-proj-objectcode-dodependencies (oref (ede-target-parent this) automatic-dependencies))) (cl-call-next-method))) -(cl-defmethod ede-buffer-header-file((this ede-proj-target-makefile-objectcode) - buffer) +(cl-defmethod ede-buffer-header-file ((this ede-proj-target-makefile-objectcode) + _buffer) "There are no default header files." (or (cl-call-next-method) ;; Ok, nothing obvious. Try looking in ourselves. diff --git a/lisp/cedet/ede/proj-prog.el b/lisp/cedet/ede/proj-prog.el index 3817cd7d40..87b2ff7a55 100644 --- a/lisp/cedet/ede/proj-prog.el +++ b/lisp/cedet/ede/proj-prog.el @@ -1,4 +1,4 @@ -;;; ede-proj-prog.el --- EDE Generic Project program support +;;; ede-proj-prog.el --- EDE Generic Project program support -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2001, 2005, 2008-2021 Free Software Foundation, ;; Inc. @@ -90,11 +90,11 @@ Note: Currently only used for Automake projects." (cl-defmethod ede-proj-makefile-insert-variables ((this ede-proj-target-makefile-program)) "Insert variables needed by the compiler THIS." (cl-call-next-method) - (let ((lf (mapconcat 'identity (oref this ldflags) " "))) + (let ((lf (mapconcat #'identity (oref this ldflags) " "))) (with-slots (ldlibs) this (if ldlibs (setq lf - (concat lf " -l" (mapconcat 'identity ldlibs " -l"))))) + (concat lf " -l" (mapconcat #'identity ldlibs " -l"))))) ;; LDFLAGS as needed. (when (and lf (not (string= "" lf))) (ede-pmake-insert-variable-once "LDDEPS" (insert lf))))) diff --git a/lisp/cedet/ede/proj-shared.el b/lisp/cedet/ede/proj-shared.el index 130d7b897a..8688d15174 100644 --- a/lisp/cedet/ede/proj-shared.el +++ b/lisp/cedet/ede/proj-shared.el @@ -1,4 +1,4 @@ -;;; ede-proj-shared.el --- EDE Generic Project shared library support +;;; ede-proj-shared.el --- EDE Generic Project shared library support -*- lexical-binding: t; -*- ;;; Copyright (C) 1998-2000, 2009-2021 Free Software Foundation, Inc. @@ -170,7 +170,7 @@ Use ldlibs to add addition libraries.") ) (cl-defmethod ede-proj-configure-add-missing - ((this ede-proj-target-makefile-shared-object)) + ((_this ede-proj-target-makefile-shared-object)) "Query if any files needed by THIS provided by automake are missing. Results in --add-missing being passed to automake." (not (and (ede-expand-filename (ede-toplevel) "ltconfig") @@ -185,7 +185,7 @@ Makefile.am generator, so use it to add this important bin program." (insert (concat "lib" (ede-name this) ".la")))) (cl-defmethod ede-proj-makefile-insert-automake-post-variables - ((this ede-proj-target-makefile-shared-object)) + ((_this ede-proj-target-makefile-shared-object)) "Insert bin_PROGRAMS variables needed by target THIS. We need to override -program which has an LDADD element." nil) diff --git a/lisp/cedet/ede/proj.el b/lisp/cedet/ede/proj.el index 4af8b4104f..6ff763016e 100644 --- a/lisp/cedet/ede/proj.el +++ b/lisp/cedet/ede/proj.el @@ -1,4 +1,4 @@ -;;; ede/proj.el --- EDE Generic Project file driver +;;; ede/proj.el --- EDE Generic Project file driver -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2003, 2007-2021 Free Software Foundation, Inc. @@ -339,7 +339,7 @@ Argument PROJ is the project to save." (cl-call-next-method) (ede-proj-save proj)) -(cl-defmethod eieio-done-customizing ((target ede-proj-target)) +(cl-defmethod eieio-done-customizing ((_target ede-proj-target)) "Call this when a user finishes customizing this object. Argument TARGET is the project we are completing customization on." (cl-call-next-method) @@ -462,7 +462,7 @@ FILE must be massaged by `ede-convert-path'." (object-remove-from-list target 'auxsource (ede-convert-path target file)) (ede-proj-save)) -(cl-defmethod project-update-version ((this ede-proj-project)) +(cl-defmethod project-update-version ((_this ede-proj-project)) "The :version of project THIS has changed." (ede-proj-save)) @@ -486,7 +486,7 @@ FILE must be massaged by `ede-convert-path'." (concat (oref this name) "-" (oref this version) ".tar.gz") )) -(cl-defmethod project-compile-project ((proj ede-proj-project) &optional command) +(cl-defmethod project-compile-project ((proj ede-proj-project) &optional _command) "Compile the entire current project PROJ. Argument COMMAND is the command to use when compiling." (let ((pm (ede-proj-dist-makefile proj)) @@ -499,13 +499,13 @@ Argument COMMAND is the command to use when compiling." ;;; Target type specific compilations/debug ;; -(cl-defmethod project-compile-target ((obj ede-proj-target) &optional command) +(cl-defmethod project-compile-target ((_obj ede-proj-target) &optional command) "Compile the current target OBJ. Argument COMMAND is the command to use for compiling the target." (project-compile-project (ede-current-project) command)) (cl-defmethod project-compile-target ((obj ede-proj-target-makefile) - &optional command) + &optional _command) "Compile the current target program OBJ. Optional argument COMMAND is the s the alternate command to use." (ede-proj-setup-buildenvironment (ede-current-project)) @@ -545,11 +545,11 @@ Converts all symbols into the objects to be used." (if comp ;; Now that we have a pre-set compilers to use, convert tye symbols ;; into objects for ease of use - (if (listp comp) - (setq comp (mapcar 'symbol-value comp)) - (setq comp (list (symbol-value comp)))) + (setq comp (if (listp comp) + (mapcar #'symbol-value comp) + (list (symbol-value comp)))) (let* ((acomp (oref obj availablecompilers)) - (avail (mapcar 'symbol-value acomp)) + (avail (mapcar #'symbol-value acomp)) (st (oref obj sourcetype)) (sources (oref obj source))) ;; COMP is not specified, so generate a list from the available @@ -585,7 +585,7 @@ Converts all symbols into the objects to be used." (setq link (list (symbol-value link))) (error ":linker is not a symbol. Howd you do that?")) (let* ((alink (oref obj availablelinkers)) - (avail (mapcar 'symbol-value alink)) + (avail (mapcar #'symbol-value alink)) (st (oref obj sourcetype)) (sources (oref obj source))) ;; LINKER is not specified, so generate a list from the available diff --git a/lisp/cedet/ede/shell.el b/lisp/cedet/ede/shell.el index ba36fccd0b..371b04f9d2 100644 --- a/lisp/cedet/ede/shell.el +++ b/lisp/cedet/ede/shell.el @@ -1,4 +1,4 @@ -;;; ede/shell.el --- A shell controlled by EDE. +;;; ede/shell.el --- A shell controlled by EDE. -*- lexical-binding: t; -*- ;; ;; Copyright (C) 2009-2021 Free Software Foundation, Inc. ;; diff --git a/lisp/cedet/ede/simple.el b/lisp/cedet/ede/simple.el index ea6162ef94..aaeb3f713c 100644 --- a/lisp/cedet/ede/simple.el +++ b/lisp/cedet/ede/simple.el @@ -1,4 +1,4 @@ -;;; ede/simple.el --- Overlay an EDE structure on an existing project +;;; ede/simple.el --- Overlay an EDE structure on an existing project -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. @@ -78,7 +78,7 @@ The directory has three parts: ede-simple-save-file-name) )) -(defun ede-simple-load (dir &optional rootproj) +(defun ede-simple-load (dir &optional _rootproj) "Load a project of type `Simple' for the directory DIR. Return nil if there isn't one. ROOTPROJ is nil, since we will only create a single EDE project here." @@ -112,7 +112,7 @@ Each directory needs a project file to control it.") (eieio-persistent-save proj)) (cl-defmethod ede-find-subproject-for-directory ((proj ede-simple-project) - dir) + _dir) "Return PROJ, for handling all subdirs below DIR." proj) diff --git a/lisp/cedet/ede/source.el b/lisp/cedet/ede/source.el index abdb07f2d7..5dbad4fcc0 100644 --- a/lisp/cedet/ede/source.el +++ b/lisp/cedet/ede/source.el @@ -1,4 +1,4 @@ -;; ede/source.el --- EDE source code object +;; ede/source.el --- EDE source code object -*- lexical-binding: t; -*- ;; Copyright (C) 2000, 2008-2021 Free Software Foundation, Inc. @@ -72,7 +72,7 @@ that they are willing to use.") ;;; Methods ;; -(cl-defmethod initialize-instance :after ((this ede-sourcecode) &rest fields) +(cl-defmethod initialize-instance :after ((this ede-sourcecode) &rest _fields) "Make sure that all ede compiler objects are cached in `ede-compiler-list'." (let ((lst ede-sourcecode-list)) diff --git a/lisp/cedet/ede/speedbar.el b/lisp/cedet/ede/speedbar.el index 48c4a89c44..01d4f943df 100644 --- a/lisp/cedet/ede/speedbar.el +++ b/lisp/cedet/ede/speedbar.el @@ -1,4 +1,4 @@ -;;; ede/speedbar.el --- Speedbar viewing of EDE projects +;;; ede/speedbar.el --- Speedbar viewing of EDE projects -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2001, 2003, 2005, 2007-2021 Free Software ;; Foundation, Inc. @@ -42,21 +42,21 @@ (setq ede-speedbar-key-map (speedbar-make-specialized-keymap)) ;; General viewing things - (define-key ede-speedbar-key-map "\C-m" 'speedbar-edit-line) - (define-key ede-speedbar-key-map "+" 'speedbar-expand-line) - (define-key ede-speedbar-key-map "=" 'speedbar-expand-line) - (define-key ede-speedbar-key-map "-" 'speedbar-contract-line) - (define-key ede-speedbar-key-map " " 'speedbar-toggle-line-expansion) + (define-key ede-speedbar-key-map "\C-m" #'speedbar-edit-line) + (define-key ede-speedbar-key-map "+" #'speedbar-expand-line) + (define-key ede-speedbar-key-map "=" #'speedbar-expand-line) + (define-key ede-speedbar-key-map "-" #'speedbar-contract-line) + (define-key ede-speedbar-key-map " " #'speedbar-toggle-line-expansion) ;; Some object based things - (define-key ede-speedbar-key-map "C" 'eieio-speedbar-customize-line) + (define-key ede-speedbar-key-map "C" #'eieio-speedbar-customize-line) ;; Some project based things - (define-key ede-speedbar-key-map "R" 'ede-speedbar-remove-file-from-target) - (define-key ede-speedbar-key-map "b" 'ede-speedbar-compile-line) - (define-key ede-speedbar-key-map "B" 'ede-speedbar-compile-project) - (define-key ede-speedbar-key-map "D" 'ede-speedbar-make-distribution) - (define-key ede-speedbar-key-map "E" 'ede-speedbar-edit-projectfile) + (define-key ede-speedbar-key-map "R" #'ede-speedbar-remove-file-from-target) + (define-key ede-speedbar-key-map "b" #'ede-speedbar-compile-line) + (define-key ede-speedbar-key-map "B" #'ede-speedbar-compile-project) + (define-key ede-speedbar-key-map "D" #'ede-speedbar-make-distribution) + (define-key ede-speedbar-key-map "E" #'ede-speedbar-edit-projectfile) ) (defvar ede-speedbar-menu @@ -98,7 +98,7 @@ (speedbar-get-focus) ) -(defun ede-speedbar-toplevel-buttons (dir) +(defun ede-speedbar-toplevel-buttons (_dir) "Return a list of objects to display in speedbar. Argument DIR is the directory from which to derive the list of objects." ede-projects @@ -180,13 +180,13 @@ Argument DIR is the directory from which to derive the list of objects." (setq depth (1- depth))) (speedbar-line-token)))) -(cl-defmethod eieio-speedbar-derive-line-path ((obj ede-project) &optional depth) +(cl-defmethod eieio-speedbar-derive-line-path ((obj ede-project) &optional _depth) "Return the path to OBJ. Optional DEPTH is the depth we start at." (file-name-directory (oref obj file)) ) -(cl-defmethod eieio-speedbar-derive-line-path ((obj ede-target) &optional depth) +(cl-defmethod eieio-speedbar-derive-line-path ((obj ede-target) &optional _depth) "Return the path to OBJ. Optional DEPTH is the depth we start at." (let ((proj (ede-target-parent obj))) @@ -208,7 +208,7 @@ Optional DEPTH is the depth we start at." "Provide a speedbar description for OBJ." (ede-description obj)) -(cl-defmethod eieio-speedbar-child-description ((obj ede-target)) +(cl-defmethod eieio-speedbar-child-description ((_obj ede-target)) "Provide a speedbar description for a plain-child of OBJ. A plain child is a child element which is not an EIEIO object." (or (speedbar-item-info-file-helper) @@ -251,7 +251,7 @@ It has depth DEPTH." ;;; Generic file management for TARGETS ;; -(defun ede-file-find (text token indent) +(defun ede-file-find (_text token indent) "Find the file TEXT at path TOKEN. INDENT is the current indentation level." (speedbar-find-file-in-frame @@ -290,7 +290,7 @@ level." (t (error "Ooops... not sure what to do"))) (speedbar-center-buffer-smartly)) -(defun ede-tag-find (text token indent) +(defun ede-tag-find (_text token _indent) "For the tag TEXT in a file TOKEN, goto that position. INDENT is the current indentation level." (let ((file (ede-find-nearest-file-line))) @@ -314,21 +314,21 @@ INDENT is the current indentation level." (defvar ede-speedbar-file-menu-additions '("----" ["Create EDE Target" ede-new-target (ede-current-project) ] - ["Add to project" ede-speedbar-file-add-to-project (ede-current-project) ] + ;; ["Add to project" ede-speedbar-file-add-to-project (ede-current-project) ] ["Compile project" ede-speedbar-compile-project (ede-current-project) ] - ["Compile file target" ede-speedbar-compile-file-target (ede-current-project) ] + ;; ["Compile file target" ede-speedbar-compile-file-target (ede-current-project) ] ["Make distribution" ede-make-dist (ede-current-project) ] ) "Set of menu items to splice into the speedbar menu.") (defvar ede-speedbar-file-keymap (let ((km (make-sparse-keymap))) - (define-key km "a" 'ede-speedbar-file-add-to-project) - (define-key km "t" 'ede-new-target) - (define-key km "s" 'ede-speedbar) - (define-key km "C" 'ede-speedbar-compile-project) - (define-key km "c" 'ede-speedbar-compile-file-target) - (define-key km "d" 'ede-make-dist) + ;; (define-key km "a" #'ede-speedbar-file-add-to-project) + (define-key km "t" #'ede-new-target) + (define-key km "s" #'ede-speedbar) + (define-key km "C" #'ede-speedbar-compile-project) + ;; (define-key km "c" #'ede-speedbar-compile-file-target) + (define-key km "d" #'ede-make-dist) km) "Keymap spliced into the speedbar keymap.") diff --git a/lisp/cedet/ede/util.el b/lisp/cedet/ede/util.el index 80cbc211fc..2b2402c642 100644 --- a/lisp/cedet/ede/util.el +++ b/lisp/cedet/ede/util.el @@ -1,4 +1,4 @@ -;;; ede/util.el --- EDE utilities +;;; ede/util.el --- EDE utilities -*- lexical-binding: t; -*- ;; Copyright (C) 2000, 2005, 2009-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/mode-local.el b/lisp/cedet/mode-local.el index 63e0cef61a..4218b23c17 100644 --- a/lisp/cedet/mode-local.el +++ b/lisp/cedet/mode-local.el @@ -576,7 +576,7 @@ OVERARGS is a list of arguments passed to the override and (put :override-with-args 'lisp-indent-function 1) (define-obsolete-function-alias 'define-overload - 'define-overloadable-function "27.1") + #'define-overloadable-function "27.1") (define-obsolete-function-alias 'function-overload-p #'mode-local--function-overload-p "27.1") diff --git a/lisp/cedet/pulse.el b/lisp/cedet/pulse.el index 3257feb1fe..cfd2152162 100644 --- a/lisp/cedet/pulse.el +++ b/lisp/cedet/pulse.el @@ -194,7 +194,7 @@ Optional argument FACE specifies the face to do the highlighting." (progn (overlay-put o 'face (or face 'pulse-highlight-start-face)) (add-hook 'pre-command-hook - 'pulse-momentary-unhighlight)) + #'pulse-momentary-unhighlight)) ;; Pulse it. (overlay-put o 'face 'pulse-highlight-face) ;; The pulse function puts FACE onto 'pulse-highlight-face. @@ -233,7 +233,7 @@ Optional argument FACE specifies the face to do the highlighting." (cancel-timer pulse-momentary-timer)) ;; Remove this hook. - (remove-hook 'pre-command-hook 'pulse-momentary-unhighlight)) + (remove-hook 'pre-command-hook #'pulse-momentary-unhighlight)) ;;;###autoload (defun pulse-momentary-highlight-one-line (point &optional face) diff --git a/lisp/cedet/semantic.el b/lisp/cedet/semantic.el index 797ff753a6..15388f08d6 100644 --- a/lisp/cedet/semantic.el +++ b/lisp/cedet/semantic.el @@ -1,4 +1,4 @@ -;;; semantic.el --- Semantic buffer evaluator. +;;; semantic.el --- Semantic buffer evaluator. -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. @@ -297,7 +297,7 @@ to use Semantic, and `semantic-init-hook' is run." 'semantic-inhibit-functions))) ;; Make sure that if this buffer is cloned, our tags and overlays ;; don't go along for the ride. - (add-hook 'clone-indirect-buffer-hook 'semantic-clear-toplevel-cache + (add-hook 'clone-indirect-buffer-hook #'semantic-clear-toplevel-cache nil t) ;; Specify that this function has done its work. At this point ;; we can consider that semantic is active in this buffer. @@ -466,12 +466,12 @@ is requested." ;; Nuke all semantic overlays. This is faster than deleting based ;; on our data structure. (let ((l (overlay-lists))) - (mapc 'semantic-delete-overlay-maybe (car l)) - (mapc 'semantic-delete-overlay-maybe (cdr l)) + (mapc #'semantic-delete-overlay-maybe (car l)) + (mapc #'semantic-delete-overlay-maybe (cdr l)) ) (semantic-parse-tree-set-needs-rebuild) ;; Remove this hook which tracks if a buffer is up to date or not. - (remove-hook 'after-change-functions 'semantic-change-function t) + (remove-hook 'after-change-functions #'semantic-change-function t) (run-hook-with-args 'semantic-after-toplevel-cache-change-hook semantic--buffer-cache) @@ -487,7 +487,7 @@ is requested." ;; This is specific to the bovine parser. (setq-local semantic-bovinate-nonterminal-check-obarray nil) (semantic-parse-tree-set-up-to-date) - (add-hook 'after-change-functions 'semantic-change-function nil t) + (add-hook 'after-change-functions #'semantic-change-function nil t) (run-hook-with-args 'semantic-after-toplevel-cache-change-hook semantic--buffer-cache) (setq semantic--completion-cache nil) @@ -779,25 +779,25 @@ Throw away all the old tags, and recreate the tag database." (defvar semantic-mode-map (let ((map (make-sparse-keymap))) ;; Key bindings: - ;; (define-key km "f" 'senator-search-set-tag-class-filter) - ;; (define-key km "i" 'senator-isearch-toggle-semantic-mode) - (define-key map "\C-c,j" 'semantic-complete-jump-local) - (define-key map "\C-c,J" 'semantic-complete-jump) - (define-key map "\C-c,m" 'semantic-complete-jump-local-members) - (define-key map "\C-c,g" 'semantic-symref-symbol) - (define-key map "\C-c,G" 'semantic-symref) - (define-key map "\C-c,p" 'senator-previous-tag) - (define-key map "\C-c,n" 'senator-next-tag) - (define-key map "\C-c,u" 'senator-go-to-up-reference) - (define-key map "\C-c, " 'semantic-complete-analyze-inline) - (define-key map "\C-c,\C-w" 'senator-kill-tag) - (define-key map "\C-c,\M-w" 'senator-copy-tag) - (define-key map "\C-c,\C-y" 'senator-yank-tag) - (define-key map "\C-c,r" 'senator-copy-tag-to-register) - (define-key map "\C-c,," 'semantic-force-refresh) - (define-key map [?\C-c ?, up] 'senator-transpose-tags-up) - (define-key map [?\C-c ?, down] 'senator-transpose-tags-down) - (define-key map "\C-c,l" 'semantic-analyze-possible-completions) + ;; (define-key km "f" #'senator-search-set-tag-class-filter) + ;; (define-key km "i" #'senator-isearch-toggle-semantic-mode) + (define-key map "\C-c,j" #'semantic-complete-jump-local) + (define-key map "\C-c,J" #'semantic-complete-jump) + (define-key map "\C-c,m" #'semantic-complete-jump-local-members) + (define-key map "\C-c,g" #'semantic-symref-symbol) + (define-key map "\C-c,G" #'semantic-symref) + (define-key map "\C-c,p" #'senator-previous-tag) + (define-key map "\C-c,n" #'senator-next-tag) + (define-key map "\C-c,u" #'senator-go-to-up-reference) + (define-key map "\C-c, " #'semantic-complete-analyze-inline) + (define-key map "\C-c,\C-w" #'senator-kill-tag) + (define-key map "\C-c,\M-w" #'senator-copy-tag) + (define-key map "\C-c,\C-y" #'senator-yank-tag) + (define-key map "\C-c,r" #'senator-copy-tag-to-register) + (define-key map "\C-c,," #'semantic-force-refresh) + (define-key map [?\C-c ?, up] #'senator-transpose-tags-up) + (define-key map [?\C-c ?, down] #'senator-transpose-tags-down) + (define-key map "\C-c,l" #'semantic-analyze-possible-completions) ;; This hack avoids showing the CEDET menu twice if ede-minor-mode ;; and Semantic are both enabled. Is there a better way? (define-key map [menu-bar cedet-menu] @@ -1029,7 +1029,7 @@ Semantic mode. (file-exists-p semanticdb-default-system-save-directory)) (require 'semantic/db-ebrowse) (semanticdb-load-ebrowse-caches))) - (add-hook 'mode-local-init-hook 'semantic-new-buffer-fcn) + (add-hook 'mode-local-init-hook #'semantic-new-buffer-fcn) ;; Add semantic-ia-complete-symbol to ;; completion-at-point-functions, so that it is run from ;; M-TAB. @@ -1037,11 +1037,11 @@ Semantic mode. ;; Note: The first entry added is the last entry run, so the ;; most specific entry should be last. (add-hook 'completion-at-point-functions - 'semantic-analyze-nolongprefix-completion-at-point-function) + #'semantic-analyze-nolongprefix-completion-at-point-function) (add-hook 'completion-at-point-functions - 'semantic-analyze-notc-completion-at-point-function) + #'semantic-analyze-notc-completion-at-point-function) (add-hook 'completion-at-point-functions - 'semantic-analyze-completion-at-point-function) + #'semantic-analyze-completion-at-point-function) (if (bound-and-true-p global-ede-mode) (define-key cedet-menu-map [cedet-menu-separator] '("--"))) @@ -1052,21 +1052,21 @@ Semantic mode. ;; introduced in the buffer is pretty much futile, but we have to ;; clean the hooks and delete Semantic-related overlays, so that ;; Semantic can be re-activated cleanly. - (remove-hook 'mode-local-init-hook 'semantic-new-buffer-fcn) + (remove-hook 'mode-local-init-hook #'semantic-new-buffer-fcn) (remove-hook 'completion-at-point-functions - 'semantic-analyze-completion-at-point-function) + #'semantic-analyze-completion-at-point-function) (remove-hook 'completion-at-point-functions - 'semantic-analyze-notc-completion-at-point-function) + #'semantic-analyze-notc-completion-at-point-function) (remove-hook 'completion-at-point-functions - 'semantic-analyze-nolongprefix-completion-at-point-function) + #'semantic-analyze-nolongprefix-completion-at-point-function) (remove-hook 'after-change-functions - 'semantic-change-function) + #'semantic-change-function) (define-key cedet-menu-map [cedet-menu-separator] nil) (define-key cedet-menu-map [semantic-options-separator] nil) ;; FIXME: handle semanticdb-load-ebrowse-caches (dolist (mode semantic-submode-list) - (if (and (boundp mode) (eval mode)) + (if (and (boundp mode) (symbol-value mode)) (funcall mode -1))) ;; Unlink buffer and clear cache (semantic--tag-unlink-cache-from-buffer) commit e609bf59ebb23c10f0e9f56df38f64be37de06dd Author: Michael Albinus Date: Fri Mar 12 16:09:42 2021 +0100 Tramp sshfs fixes * doc/misc/tramp.texi (FUSE setup): Fix typo. * lisp/net/tramp-sshfs.el (tramp-sshfs-handle-set-file-modes): Use `tramp-compat-set-file-modes'. * test/lisp/net/tramp-tests.el (tramp-test43-asynchronous-requests): Don't run for tramp-sshfs. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index e5e15cdaa5..7ae562244e 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -2653,7 +2653,7 @@ The method @option{sshfs} declares the mount arguments in the variable a list of list of strings, and can be overwritten by the connection property @t{"mount-args"}, @xref{Predefined connection information}. -Additionally. it declares also the arguments for running remote +Additionally, it declares also the arguments for running remote processes, using the @command{ssh} command. These don't need to be changed. diff --git a/lisp/net/tramp-sshfs.el b/lisp/net/tramp-sshfs.el index ce9412c0be..2a00d5ce67 100644 --- a/lisp/net/tramp-sshfs.el +++ b/lisp/net/tramp-sshfs.el @@ -276,7 +276,8 @@ arguments to pass to the OPERATION." (with-parsed-tramp-file-name filename nil (unless (and (eq flag 'nofollow) (file-symlink-p filename)) (tramp-flush-file-properties v localname) - (set-file-modes (tramp-fuse-local-file-name filename) mode flag)))) + (tramp-compat-set-file-modes + (tramp-fuse-local-file-name filename) mode flag)))) (defun tramp-sshfs-handle-write-region (start end filename &optional append visit lockname mustbenew) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 6565919c77..be428fc2a6 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -6380,7 +6380,7 @@ process sentinels. They shall not disturb each other." ;; Prior Emacs 27, `shell-file-name' was hard coded as "/bin/sh" for ;; remote processes in Emacs. That doesn't work for tramp-adb.el. (skip-unless (or (and (tramp--test-adb-p) (tramp--test-emacs27-p)) - (tramp--test-sh-p) (tramp--test-sshfs-p))) + (tramp--test-sh-p))) (skip-unless (not (tramp--test-crypt-p))) (skip-unless (not (tramp--test-docker-p))) (skip-unless (not (tramp--test-windows-nt-p))) @@ -6767,6 +6767,8 @@ If INTERACTIVE is non-nil, the tests are run interactively." ;; * Fix `tramp-test06-directory-file-name' for `ftp'. ;; * Implement `tramp-test31-interrupt-process' for `adb', `sshfs' and ;; for direct async processes. +;; * Check, why direct async processes do not work for +;; `tramp-test43-asynchronous-requests'. (provide 'tramp-tests) commit a0854f939ce3a1de2c8cbc5e38b106a8df4480f6 Author: Mattias Engdegård Date: Fri Mar 12 12:11:17 2021 +0100 ; Fix typos in doc strings diff --git a/lisp/calculator.el b/lisp/calculator.el index 00883989b2..6dd8d9a7ec 100644 --- a/lisp/calculator.el +++ b/lisp/calculator.el @@ -291,7 +291,7 @@ user-defined operators, use `calculator-user-operators' instead.") 5. The function's precedence -- should be in the range of 1 (lowest) to 9 (highest) (optional, defaults to 1); -It it possible have a unary prefix version of a binary operator if it +It is possible have a unary prefix version of a binary operator if it comes later in this list. If the list begins with the symbol `nobind', then no key binding will take place -- this is only used for predefined keys. diff --git a/lisp/cedet/semantic/grammar.el b/lisp/cedet/semantic/grammar.el index ca7c273feb..8d8faac9c4 100644 --- a/lisp/cedet/semantic/grammar.el +++ b/lisp/cedet/semantic/grammar.el @@ -1740,7 +1740,7 @@ If it is a macro name, return a description of the associated expander function parameter list. If it is a function name, return a description of this function parameter list. -It it is a variable name, return a brief (one-line) documentation +If it is a variable name, return a brief (one-line) documentation string for the variable. If a default description of the current context can be obtained, return it. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 6f3c7d6688..f1455ffe73 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -3508,7 +3508,7 @@ canceled the first time the function is entered." (defun edebug-cancel-on-entry (function) "Cause Edebug to not stop when FUNCTION is called. -The removes the effect of `edebug-on-entry'. If FUNCTION is is +The removes the effect of `edebug-on-entry'. If FUNCTION is nil, remove `edebug-on-entry' on all functions." (interactive (list (let ((name (completing-read diff --git a/lisp/emulation/cua-rect.el b/lisp/emulation/cua-rect.el index e66050b713..0039092fd6 100644 --- a/lisp/emulation/cua-rect.el +++ b/lisp/emulation/cua-rect.el @@ -46,7 +46,7 @@ A cua-rectangle definition is a vector used for all actions in TOP is the upper-left corner point. -BOTTOM is the point at the end of line after the the lower-right +BOTTOM is the point at the end of line after the lower-right corner point. LEFT and RIGHT are column numbers. diff --git a/lisp/international/quail.el b/lisp/international/quail.el index f52747084b..87a905045d 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el @@ -1075,7 +1075,7 @@ The installed decode map can be referred by the function `quail-decode-map'." KEY is a string meaning a sequence of keystrokes to be translated. TRANSLATION is a character, a string, a vector, a Quail map, a function, or a cons. -It it is a character, it is the sole translation of KEY. +If it is a character, it is the sole translation of KEY. If it is a string, each character is a candidate for the translation. If it is a vector, each element (string or character) is a candidate for the translation. diff --git a/lisp/jit-lock.el b/lisp/jit-lock.el index d169e40b81..a1287926eb 100644 --- a/lisp/jit-lock.el +++ b/lisp/jit-lock.el @@ -105,7 +105,7 @@ This means those subsequent lines are refontified to reflect their new syntactic context, after `jit-lock-context-time' seconds. If any other value, e.g., `syntax-driven', it means refontification of subsequent lines to reflect their new syntactic context may or may not -occur after `jit-lock-context-time', depending on the the font-lock +occur after `jit-lock-context-time', depending on the font-lock definitions of the buffer. Specifically, if `font-lock-keywords-only' is nil in a buffer, which generally means the syntactic fontification is done using the buffer mode's syntax table, the syntactic diff --git a/lisp/mail/smtpmail.el b/lisp/mail/smtpmail.el index 5c7ffd9989..ac5e8c3b6f 100644 --- a/lisp/mail/smtpmail.el +++ b/lisp/mail/smtpmail.el @@ -186,7 +186,7 @@ mean \"try again\"." (defvar smtpmail-auth-supported '(cram-md5 plain login) "List of supported SMTP AUTH mechanisms. The list is in preference order. -Every element should have a matching `cl-defmethod' for +Every element should have a matching `cl-defmethod' for `smtpmail-try-auth-method'.") (defvar smtpmail-mail-address nil diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el index 5148a66724..5938b8146e 100644 --- a/lisp/net/dictionary.el +++ b/lisp/net/dictionary.el @@ -829,7 +829,7 @@ The DICTIONARY is only used for decoding the bytes to display the DESCRIPTION." (defun dictionary-display-word-definition (reply word dictionary) "Insert the definition in REPLY for the current WORD from DICTIONARY. It will replace links which are found in the REPLY and replace -them with buttons to perform a a new search." +them with buttons to perform a new search." (let ((start (point))) (insert (dictionary-decode-charset reply dictionary)) (insert "\n\n") diff --git a/lisp/obsolete/iswitchb.el b/lisp/obsolete/iswitchb.el index a9bc6ef071..7ffee762eb 100644 --- a/lisp/obsolete/iswitchb.el +++ b/lisp/obsolete/iswitchb.el @@ -313,7 +313,7 @@ Possible values: `otherwindow' Show new buffer in another window (same frame) `display' Display buffer in another window without switching to it `otherframe' Show new buffer in another frame -`maybe-frame' If a buffer is visible in another frame, prompt to ask if you +`maybe-frame' If a buffer is visible in another frame, prompt to ask if you want to see the buffer in the same window of the current frame or in the other frame. `always-frame' If a buffer is visible in another frame, raise that diff --git a/lisp/org/ol.el b/lisp/org/ol.el index 9ed6ab954e..38e2dd6a02 100644 --- a/lisp/org/ol.el +++ b/lisp/org/ol.el @@ -591,7 +591,7 @@ handle this as a special case. When the function does handle the link, it must return a non-nil value. If it decides that it is not responsible for this link, it must return -nil to indicate that that Org can continue with other options like +nil to indicate that Org can continue with other options like exact and fuzzy text search.") diff --git a/lisp/org/org-tempo.el b/lisp/org/org-tempo.el index 36b8614fe1..c121b8e7ac 100644 --- a/lisp/org/org-tempo.el +++ b/lisp/org/org-tempo.el @@ -65,7 +65,7 @@ just like `org-structure-template-alist'. The tempo snippet \" \\cite[Chapter 1]{Jones} \\cite[see][]{Jones} -> \\cite[see][]{Jones} \\cite[see][Chapter 1]{Jones} -> \\cite{Jones} -Is is possible that other packages have other conventions about which +It is possible that other packages have other conventions about which optional argument is interpreted how - that is why this cleaning up can be turned off." :group 'reftex-citation-support diff --git a/test/lisp/kmacro-tests.el b/test/lisp/kmacro-tests.el index c891072076..8736f7fd2d 100644 --- a/test/lisp/kmacro-tests.el +++ b/test/lisp/kmacro-tests.el @@ -519,7 +519,7 @@ This is a regression test for: Bug#3412, Bug#11817." (should (eq saved-binding (key-binding "\C-a"))))) (kmacro-tests-deftest kmacro-tests-name-or-bind-to-key-when-no-macro () - "Bind to key, symbol or register fails when when no macro exists." + "Bind to key, symbol or register fails when no macro exists." (should-error (kmacro-bind-to-key nil)) (should-error (kmacro-name-last-macro 'kmacro-tests-symbol-for-test)) (should-error (kmacro-to-register))) commit 14b54cea1756f4d66c7376c55cf4aa88e8c3c0c3 Author: Robert Pluim Date: Fri Mar 12 11:34:38 2021 +0100 Document how to create a branch for Git/Mercurial * doc/emacs/maintaining.texi (Creating Branches): Add instructions for git/Mercurial. diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index bc276c4904..2750418871 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -1611,6 +1611,10 @@ branch ID for a branch starting at the current revision. For example, if the current revision is 2.5, the branch ID should be 2.5.1, 2.5.2, and so on, depending on the number of existing branches at that point. + This procedure will not work for distributed version control systems +like git or Mercurial. For those systems you should use the prefix +argument to @code{vc-create-tag} (@kbd{C-u C-x v s}) instead. + To create a new branch at an older revision (one that is no longer the head of a branch), first select that revision (@pxref{Switching Branches}). Your procedure will then differ depending on whether you commit ba6ae500f19b7791a81005b0af54ca8354ebffcc Author: Stefan Monnier Date: Thu Mar 11 22:31:39 2021 -0500 * lisp/emacs-lisp/cconv.el (cconv--analyze-use): Simplify (doh!) diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el index cfb0168a6e..afaa13a869 100644 --- a/lisp/emacs-lisp/cconv.el +++ b/lisp/emacs-lisp/cconv.el @@ -602,7 +602,7 @@ FORM is the parent form that binds this var." (byte-compile-warn "%s `%S' not left unused" varkind var)) ((and (let (or 'let* 'let) (car form)) - `(,`(,var) ;; (or `(,var nil) : Too many false positives: bug#47080 + `((,var) ;; (or `(,var nil) : Too many false positives: bug#47080 t nil ,_ ,_)) ;; FIXME: Convert this warning to use `macroexp--warn-wrap' ;; so as to give better position information. commit 009bc7c9d8bd0074a78ebef73102f600a514172c Author: Stefan Monnier Date: Thu Mar 11 22:27:41 2021 -0500 * lisp/emacs-lisp/cconv.el (cconv--analyze-use): Tune down the warning Don't warn for always-nil bindings if the binding is made explicit. Fixes bug#47080. diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el index ca641a2ef0..cfb0168a6e 100644 --- a/lisp/emacs-lisp/cconv.el +++ b/lisp/emacs-lisp/cconv.el @@ -602,7 +602,8 @@ FORM is the parent form that binds this var." (byte-compile-warn "%s `%S' not left unused" varkind var)) ((and (let (or 'let* 'let) (car form)) - `(,(or `(,var) `(,var nil)) t nil ,_ ,_)) + `(,`(,var) ;; (or `(,var nil) : Too many false positives: bug#47080 + t nil ,_ ,_)) ;; FIXME: Convert this warning to use `macroexp--warn-wrap' ;; so as to give better position information. (unless (not (intern-soft var)) commit 7109307c1a62fb3ab781989d495bacd3c2b15a2e Author: Stefan Monnier Date: Thu Mar 11 21:47:10 2021 -0500 * lisp/emacs-lisp/syntax.el (syntax-propertize-rules): Use `macroexp-let2` This also silences the recently introduced compilation warning. diff --git a/lisp/emacs-lisp/syntax.el b/lisp/emacs-lisp/syntax.el index bee2f9639e..6d5b04b83b 100644 --- a/lisp/emacs-lisp/syntax.el +++ b/lisp/emacs-lisp/syntax.el @@ -290,12 +290,13 @@ all RULES in total." ',(string-to-syntax (nth 1 action))) ,@(nthcdr 2 action)) `((let ((mb (match-beginning ,gn)) - (me (match-end ,gn)) - (syntax ,(nth 1 action))) - (if syntax - (put-text-property - mb me 'syntax-table syntax)) - ,@(nthcdr 2 action))))) + (me (match-end ,gn))) + ,(macroexp-let2 nil syntax (nth 1 action) + `(progn + (if ,syntax + (put-text-property + mb me 'syntax-table ,syntax)) + ,@(nthcdr 2 action))))))) (t `((let ((mb (match-beginning ,gn)) (me (match-end ,gn)) commit b08b2e03b255c0ad85bd026a8d786b21ee22eee8 Author: Lars Ingebrigtsen Date: Fri Mar 12 02:37:53 2021 +0100 Rename to image--transform-smoothing in image-mode.el * lisp/image-mode.el (image--transform-smoothing): Rename from image-transform-smoothing. (image-transform-properties, image-transform-reset): Adjust usage. diff --git a/lisp/image-mode.el b/lisp/image-mode.el index e9a962ffe9..2de16cb6af 100644 --- a/lisp/image-mode.el +++ b/lisp/image-mode.el @@ -95,7 +95,7 @@ Its value should be one of the following: (defvar-local image-transform-rotation 0.0 "Rotation angle for the image in the current Image mode buffer.") -(defvar-local image-transform-smoothing nil +(defvar-local image--transform-smoothing nil "Whether to use transform smoothing.") (defvar image-transform-right-angle-fudge 0.0001 @@ -1481,9 +1481,9 @@ return value is suitable for appending to an image spec." (list :height (cdr resized))) ,@(unless (= 0.0 image-transform-rotation) (list :rotation image-transform-rotation)) - ,@(when image-transform-smoothing + ,@(when image--transform-smoothing (list :transform-smoothing - (string= image-transform-smoothing "smooth"))))))) + (string= image--transform-smoothing "smooth"))))))) (defun image-transform-set-scale (scale) "Prompt for a number, and resize the current image by that amount." @@ -1519,7 +1519,7 @@ ROTATION should be in degrees." (defun image-transform-set-smoothing (smoothing) (interactive (list (completing-read "Smoothing: " '("none" "smooth") nil t))) - (setq image-transform-smoothing smoothing) + (setq image--transform-smoothing smoothing) (image-toggle-display-image)) (defun image-transform-original () @@ -1535,7 +1535,7 @@ ROTATION should be in degrees." (setq image-transform-resize image-auto-resize image-transform-rotation 0.0 image-transform-scale 1 - image-transform-smoothing nil) + image--transform-smoothing nil) (image-toggle-display-image)) (provide 'image-mode) commit 5dff53f5da4f17d74a0ad2cd7ec0a736aa5111f7 Author: Lars Ingebrigtsen Date: Fri Mar 12 02:37:10 2021 +0100 Add a new `image-transform-smoothing' user option * doc/lispref/display.texi (Image Descriptors): Document it. * lisp/image.el (image-transform-smoothing): New user option. (create-image): Use it. (image--default-smoothing): New function. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 9723376de9..f003d52427 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -5399,8 +5399,13 @@ is platform dependent, but should be equivalent to bilinear filtering. Disabling smoothing will use the nearest neighbor algorithm. -The default, if this property is not specified, is for down-scaling to -apply smoothing, and for up-scaling to not apply smoothing. +If this property is not specified, @code{create-image} will use the +@code{image-transform-smoothing} user option to say whether scaling +should be done or not. This option can be @code{nil} (no smoothing), +@code{t} (use smoothing) or a predicate function that's called with +the image object as the only parameter, and should return either +@code{nil} or @code{t}. The default is for down-scaling to apply +smoothing, and for large up-scaling to not apply smoothing. @item :index @var{frame} @xref{Multi-Frame Images}. diff --git a/etc/NEWS b/etc/NEWS index 4b8700a01c..fa8784db59 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1483,6 +1483,12 @@ and nil to disable smoothing. The default behaviour of smoothing on down-scaling and not smoothing on up-scaling remains unchanged. ++++ +*** New user option 'image-transform-smoothing'. +This controls whether to use smoothing or not for an image. Values +include nil (no smoothing), t (do smoothing) or a predicate function +that's called with the image object and should return nil/t. + ** EWW +++ diff --git a/lisp/image.el b/lisp/image.el index 6955a90de7..4ede1fbf37 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -141,6 +141,18 @@ based on the font pixel size." (const :tag "Automatically compute" auto)) :version "26.1") +(defcustom image-transform-smoothing #'image--default-smoothing + "Whether to do smoothing when applying transforms to images. +Common transforms are rescaling and rotation. + +Valid values are nil (no smoothing), t (smoothing) or a predicate +function that is called with the image specification and should return +either nil or non-nil." + :type '(choice (const :tag "Do smoothing" t) + (const :tag "No smoothing" nil) + function) + :version "28.1") + (defcustom image-use-external-converter nil "If non-nil, `create-image' will use external converters for exotic formats. Emacs handles most of the common image formats (SVG, JPEG, PNG, GIF @@ -485,11 +497,40 @@ Image file names that are not absolute are searched for in the type 'png data-p t))) (when (image-type-available-p type) - (append (list 'image :type type (if data-p :data :file) file-or-data) - (and (not (plist-get props :scale)) - (list :scale - (image-compute-scaling-factor image-scaling-factor))) - props))) + (let ((image + (append (list 'image :type type (if data-p :data :file) + file-or-data) + (and (not (plist-get props :scale)) + ;; Add default scaling. + (list :scale + (image-compute-scaling-factor + image-scaling-factor))) + props))) + ;; Add default smoothing. + (unless (plist-member props :transform-smoothing) + (setq image (nconc image + (list :transform-smoothing + (pcase image-transform-smoothing + ('t t) + ('nil nil) + (func (funcall func image))))))) + image))) + +(defun image--default-smoothing (image) + "Say whether IMAGE should be smoothed when transformed." + (let* ((props (nthcdr 5 image)) + (scaling (plist-get props :scale)) + (rotation (plist-get props :rotation))) + (cond + ;; We always smooth when scaling down and small upwards scaling. + ((and scaling (< scaling 2)) + t) + ;; Smooth when doing non-90-degree rotation + ((and rotation + (or (not (zerop (mod rotation 1))) + (not (zerop (% (truncate rotation) 90))))) + t) + (t nil)))) (defun image--set-property (image property value) "Set PROPERTY in IMAGE to VALUE. commit fd3705adf9fe73dfd5becfe4afbd4673e71942b8 Author: Lars Ingebrigtsen Date: Fri Mar 12 01:20:07 2021 +0100 Fix compilation warning in python-wy.el after lexical rewrite * admin/grammars/python.wy: Require semantic/tag. In end of data: cedet/semantic/wisent/python-wy.el:862:1: Warning: the function `semantic-tag-name' might not be defined at runtime. diff --git a/admin/grammars/python.wy b/admin/grammars/python.wy index 22e85570dc..2539d1bec8 100644 --- a/admin/grammars/python.wy +++ b/admin/grammars/python.wy @@ -91,6 +91,7 @@ %expectedconflicts 5 %{ +(require 'semantic/tag) (declare-function wisent-python-reconstitute-function-tag "semantic/wisent/python" (tag suite)) (declare-function wisent-python-reconstitute-class-tag "semantic/wisent/python" commit d0125959d775fc8868b3c4cec78c4120eb67d643 Author: Lars Ingebrigtsen Date: Fri Mar 12 00:41:50 2021 +0100 Make byte-compiled uses of `define-minor-mode' more compatible * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Be more defensive about accessing minor mode variables. diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 4a9e58083b..addb58cdbb 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -332,12 +332,20 @@ or call the function `%s'.")))) t))) ;; Keep minor modes list up to date. ,@(if globalp - `((setq global-minor-modes (delq ',modefun global-minor-modes)) + ;; When running this byte-compiled code in earlier + ;; Emacs versions, these variables may not be defined + ;; there. So check defensively, even if they're + ;; always defined in Emacs 28 and up. + `((when (boundp 'global-minor-modes) + (setq global-minor-modes + (delq ',modefun global-minor-modes)) + (when ,getter + (push ',modefun global-minor-modes)))) + ;; Ditto check. + `((when (boundp 'local-minor-modes) + (setq local-minor-modes (delq ',modefun local-minor-modes)) (when ,getter - (push ',modefun global-minor-modes))) - `((setq local-minor-modes (delq ',modefun local-minor-modes)) - (when ,getter - (push ',modefun local-minor-modes)))) + (push ',modefun local-minor-modes))))) ,@body ;; The on/off hooks are here for backward compatibility only. (run-hooks ',hook (if ,getter ',hook-on ',hook-off)) commit 17cdb732a76796e585dd9defe8fa5a2724a9c1db Author: Basil L. Contovounesios Date: Thu Mar 11 22:27:20 2021 +0000 ; Fix some typos. diff --git a/etc/NEWS b/etc/NEWS index b3f4ade337..4b8700a01c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1441,9 +1441,9 @@ decaying average of delays, and if this number gets too high, the animation is stopped. +++ -*** The 'n' and 'p' commands (next/previous image) now respects dired order. +*** The 'n' and 'p' commands (next/previous image) now respect Dired order. These commands would previously display the next/previous image in -alphabetical order, but will now find the "parent" dired buffer and +lexicographic order, but will now find the "parent" Dired buffer and select the next/previous image file according to how the files are sorted there. The commands have also been extended to work when the "parent" buffer is an archive mode (i.e., zip file or the like) or tar diff --git a/lisp/button.el b/lisp/button.el index 043de8eeb7..69d70540c0 100644 --- a/lisp/button.el +++ b/lisp/button.el @@ -472,8 +472,8 @@ mouse event is used. If there's no button at POS, do nothing and return nil, otherwise return t. -To get a description of what function will called when pushing a -butting, use the `button-describe' command." +To get a description of the function that will be invoked when +pushing a button, use the `button-describe' command." (interactive (list (if (integerp last-command-event) (point) last-command-event))) (if (and (not (integerp pos)) (eventp pos)) diff --git a/lisp/image-mode.el b/lisp/image-mode.el index 8b61aa7e73..e9a962ffe9 100644 --- a/lisp/image-mode.el +++ b/lisp/image-mode.el @@ -1144,8 +1144,8 @@ replacing the current Image mode buffer." (funcall next)))) (defun image-mode--directory-buffers (file) - "Return a alist of type/buffer for all \"parent\" buffers to image FILE. -This is normally a list of dired buffers, but can also be archive and + "Return an alist of type/buffer for all \"parent\" buffers to image FILE. +This is normally a list of Dired buffers, but can also be archive and tar mode buffers." (let ((buffers nil) (dir (file-name-directory file))) diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index c4bcf88e4c..18da4398f4 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -106,7 +106,7 @@ ;; ;; - Write a new function that will determine the current project ;; based on the directory and add it to `project-find-functions' -;; (which see) using `add-hook'. It is a good idea to depend on the +;; (which see) using `add-hook'. It is a good idea to depend on the ;; directory only, and not on the current major mode, for example. ;; Because the usual expectation is that all files in the directory ;; belong to the same project (even if some/most of them are ignored). commit 71ef0122abf5215eafa2dc414b75630a709de008 Author: Yuan Fu Date: Wed Mar 3 09:50:15 2021 -0500 Map redo records for undo in region to 'undo-in-region * lisp/simple.el (undo-equiv-table): Add explaination for undo-in-region, undo to the beginning of undo list and null undo. (undo): If equiv is 'undo-in-region, empty or t, set pending-undo-list to t. If the redo is undo-in-region, map buffer-undo-list to 'undo-in-region instead of t, if it is an identity mapping, map to 'empty. (undo-make-selective-list): Only continue when ulist is a proper list. * test/lisp/simple-tests.el (simple-tests--undo): Add test for undo-only in region. (simple-tests--sans-leading-nil): New helper function. (simple-tests--undo-equiv-table): New test for 'undo-equiv-table'. diff --git a/lisp/simple.el b/lisp/simple.el index f8050091d5..98fccf4ff2 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -2824,8 +2824,35 @@ the minibuffer contents." (defconst undo-equiv-table (make-hash-table :test 'eq :weakness t) "Table mapping redo records to the corresponding undo one. -A redo record for undo-in-region maps to t. -A redo record for ordinary undo maps to the following (earlier) undo.") +A redo record for an undo in region maps to 'undo-in-region. +A redo record for ordinary undo maps to the following (earlier) undo. +A redo record that undoes to the beginning of the undo list maps to t. +In the rare case where there are (erroneously) consecutive nil's in +`buffer-undo-list', `undo' maps the previous valid undo record to +'empty, if the previous record is a redo record, `undo' doesn't change +its mapping. + +To be clear, a redo record is just an undo record, the only difference +is that it is created by an undo command (instead of an ordinary buffer +edit). Since a record used to undo ordinary change is called undo +record, a record used to undo an undo is called redo record. + +`undo' uses this table to make sure the previous command is `undo'. +`undo-redo' uses this table to set the correct `pending-undo-list'. + +When you undo, `pending-undo-list' shrinks and `buffer-undo-list' +grows, and Emacs maps the tip of `buffer-undo-list' to the tip of +`pending-undo-list' in this table. + +For example, consider this undo list where each node represents an +undo record: if we undo from 4, `pending-undo-list' will be at 3, +`buffer-undo-list' at 5, and 5 will map to 3. + + | + 3 5 + | / + |/ + 4") (defvar undo-in-region nil "Non-nil if `pending-undo-list' is not just a tail of `buffer-undo-list'.") @@ -2872,7 +2899,9 @@ as an argument limits undo to changes within the current region." ;; the next command should not be a "consecutive undo". ;; So set `this-command' to something other than `undo'. (setq this-command 'undo-start) - + ;; Here we decide whether to break the undo chain. If the + ;; previous command is `undo', we don't call `undo-start', i.e., + ;; don't break the undo chain. (unless (and (eq last-command 'undo) (or (eq pending-undo-list t) ;; If something (a timer or filter?) changed the buffer @@ -2901,7 +2930,7 @@ as an argument limits undo to changes within the current region." ;; undo-redo-undo-redo-... so skip to the very last equiv. (while (let ((next (gethash equiv undo-equiv-table))) (if next (setq equiv next)))) - (setq pending-undo-list equiv))) + (setq pending-undo-list (if (consp equiv) equiv t)))) (undo-more (if (numberp arg) (prefix-numeric-value arg) @@ -2917,11 +2946,17 @@ as an argument limits undo to changes within the current region." (while (eq (car list) nil) (setq list (cdr list))) (puthash list - ;; Prevent identity mapping. This can happen if - ;; consecutive nils are erroneously in undo list. - (if (or undo-in-region (eq list pending-undo-list)) - t - pending-undo-list) + (cond + (undo-in-region 'undo-in-region) + ;; Prevent identity mapping. This can happen if + ;; consecutive nils are erroneously in undo list. It + ;; has to map to _something_ so that the next `undo' + ;; command recognizes that the previous command is + ;; `undo' and doesn't break the undo chain. + ((eq list pending-undo-list) + (or (gethash list undo-equiv-table) + 'empty)) + (t pending-undo-list)) undo-equiv-table)) ;; Don't specify a position in the undo record for the undo command. ;; Instead, undoing this should move point to where the change is. @@ -3234,7 +3269,7 @@ list can be applied to the current buffer." undo-elt) (while ulist (when undo-no-redo - (while (gethash ulist undo-equiv-table) + (while (consp (gethash ulist undo-equiv-table)) (setq ulist (gethash ulist undo-equiv-table)))) (setq undo-elt (car ulist)) (cond diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el index f2ddc2e3fb..1819775bda 100644 --- a/test/lisp/simple-tests.el +++ b/test/lisp/simple-tests.el @@ -465,8 +465,117 @@ See bug#35036." (simple-tests--exec '(backward-char undo-redo undo-redo)) (should (equal (buffer-string) "abc")) (simple-tests--exec '(backward-char undo-redo undo-redo)) + (should (equal (buffer-string) "abcde"))) + ;; Test undo/redo in region. + (with-temp-buffer + (buffer-enable-undo) + (dolist (x '("a" "b" "c" "d" "e")) + (insert x) + (undo-boundary)) + (should (equal (buffer-string) "abcde")) + ;; The test does this: activate region, `undo', break the undo + ;; chain (by deactivating and reactivating the region), then + ;; `undo-only'. There used to be a bug in + ;; `undo-make-selective-list' that makes `undo-only' error out in + ;; that case, which is fixed by in the same commit as this change. + (simple-tests--exec '(move-beginning-of-line + push-mark-command + forward-char + forward-char + undo)) + (should (equal (buffer-string) "acde")) + (simple-tests--exec '(move-beginning-of-line + push-mark-command + forward-char + forward-char + undo-only)) (should (equal (buffer-string) "abcde")) - )) + ;; Rest are simple redo in region tests. + (simple-tests--exec '(undo-redo)) + (should (equal (buffer-string) "acde")) + (simple-tests--exec '(undo-redo)) + (should (equal (buffer-string) "abcde")))) + +(defun simple-tests--sans-leading-nil (lst) + "Return LST sans the leading nils." + (while (and (consp lst) (null (car lst))) + (setq lst (cdr lst))) + lst) + +(ert-deftest simple-tests--undo-equiv-table () + (with-temp-buffer + (buffer-enable-undo) + (let ((ul-hash-table (make-hash-table :test #'equal))) + (dolist (x '("a" "b" "c")) + (insert x) + (puthash x (simple-tests--sans-leading-nil buffer-undo-list) + ul-hash-table) + (undo-boundary)) + (should (equal (buffer-string) "abc")) + ;; Tests mappings in `undo-equiv-table'. + (simple-tests--exec '(undo)) + (should (equal (buffer-string) "ab")) + (should (eq (gethash (simple-tests--sans-leading-nil + buffer-undo-list) + undo-equiv-table) + (gethash "b" ul-hash-table))) + (simple-tests--exec '(backward-char undo)) + (should (equal (buffer-string) "abc")) + (should (eq (gethash (simple-tests--sans-leading-nil + buffer-undo-list) + undo-equiv-table) + (gethash "c" ul-hash-table))) + ;; Undo in region should map to 'undo-in-region. + (simple-tests--exec '(backward-char + push-mark-command + move-end-of-line + undo)) + (should (equal (buffer-string) "ab")) + (should (eq (gethash (simple-tests--sans-leading-nil + buffer-undo-list) + undo-equiv-table) + 'undo-in-region)) + ;; The undo that undoes to the beginning should map to t. + (deactivate-mark 'force) + (simple-tests--exec '(backward-char + undo undo undo + undo undo undo)) + (should (equal (buffer-string) "")) + (should (eq (gethash (simple-tests--sans-leading-nil + buffer-undo-list) + undo-equiv-table) + t)) + ;; Erroneous nil undo should map to 'empty. + (insert "a") + (undo-boundary) + (push nil buffer-undo-list) + (simple-tests--exec '(backward-char undo)) + (should (equal (buffer-string) "a")) + (should (eq (gethash (simple-tests--sans-leading-nil + buffer-undo-list) + undo-equiv-table) + 'empty)) + ;; But if the previous record is a redo record, its mapping + ;; shouldn't change. + (insert "e") + (undo-boundary) + (should (equal (buffer-string) "ea")) + (puthash "e" (simple-tests--sans-leading-nil buffer-undo-list) + ul-hash-table) + (insert "a") + (undo-boundary) + (simple-tests--exec '(backward-char undo)) + (should (equal (buffer-string) "ea")) + (push nil buffer-undo-list) + (simple-tests--exec '(forward-char undo)) + ;; Buffer content should change since we just undid a nil + ;; record. + (should (equal (buffer-string) "ea")) + ;; The previous redo record shouldn't map to empty. + (should (equal (gethash (simple-tests--sans-leading-nil + buffer-undo-list) + undo-equiv-table) + (gethash "e" ul-hash-table)))))) ;;; undo auto-boundary tests (ert-deftest undo-auto-boundary-timer () commit d9c94e93b7013d575aeb2a8e8077564a80b04f7c Author: Stefan Monnier Date: Thu Mar 11 14:32:42 2021 -0500 * lisp/mail/: Use lexical-binding Remove some redundant `:group` args as well. * lisp/mail/supercite.el: Use lexical-binding. (completer-disable): Declare var. (sc-set-variable): Don't rely on dynbind to access `help` variable. * lisp/mail/mail-extr.el: Use lexical-binding. (mail-extract-address-components): Avoid use of dynamic scoping to refer to local vars. * lisp/mail/mailabbrev.el: Use lexical-binding. (mail-abbrev-make-syntax-table): Rename `_` variable to `syntax-_`. * lisp/mail/mailheader.el: Use lexical-binding. (headers): Don't declare as dynbound globally. (mail-header-set, mail-header-merge): Declare `headers` as dynbound locally, instead. Mark those functions as obsolete. (mail-header-format): Use `alist-get` instead of `mail-header`. * lisp/mail/binhex.el (binhex-decode-region-external): Remove always-nil var `firstline`. * lisp/mail/emacsbug.el: Use lexical-binding. (report-emacs-bug): Remove always-nil var `message-end-point`. * lisp/mail/rmail-spam-filter.el: Use lexical-binding. (bbdb/mail_auto_create_p): Declare variable. * lisp/mail/rmail.el (rmail-get-new-mail): Remove always-nil var `delete-files`. * lisp/mail/rmailout.el: Use lexical-binding. (rmail-output-read-file-name): Remove unused var `err`. (rmail-convert-to-babyl-format): Remove unused var `count`. (rmail-output-as-mbox): Remove unused vars `from` and `date`. * lisp/mail/rmailsort.el: Use lexical-binding. (rmail-sort-messages): Remove unused var `msginfo`. * lisp/mail/rfc822.el: Use lexical-binding. * lisp/mail/rmailedit.el: Use lexical-binding. * lisp/mail/mailclient.el: Use lexical-binding. * lisp/mail/blessmail.el: Use lexical-binding. * lisp/mail/mail-hist.el: Use lexical-binding. * lisp/mail/rmailkwd.el: Use lexical-binding. * lisp/mail/rmailmsc.el: Use lexical-binding. * lisp/mail/uce.el: Use lexical-binding. * lisp/mail/unrmail.el: Use lexical-binding. diff --git a/lisp/mail/binhex.el b/lisp/mail/binhex.el index edb52b6578..af327442c2 100644 --- a/lisp/mail/binhex.el +++ b/lisp/mail/binhex.el @@ -38,19 +38,16 @@ "Non-nil value should be a string that names a binhex decoder. The program should expect to read binhex data on its standard input and write the converted data to its standard output." - :type 'string - :group 'binhex) + :type 'string) (defcustom binhex-decoder-switches '("-d") "List of command line flags passed to the command `binhex-decoder-program'." - :group 'binhex :type '(repeat string)) (defcustom binhex-use-external (executable-find binhex-decoder-program) "Use external binhex program." :version "22.1" - :group 'binhex :type 'boolean) (defconst binhex-alphabet-decoding-alist @@ -80,7 +77,7 @@ input and write the converted data to its standard output." (make-obsolete-variable 'binhex-temporary-file-directory 'temporary-file-directory "28.1") -(defun binhex-insert-char (char &optional count ignored buffer) +(defun binhex-insert-char (char &optional count _ignored buffer) "Insert COUNT copies of CHARACTER into BUFFER." (if (or (null buffer) (eq buffer (current-buffer))) (insert-char char count) @@ -273,7 +270,8 @@ If HEADER-ONLY is non-nil only decode header and return filename." (defun binhex-decode-region-external (start end) "Binhex decode region between START and END using external decoder." (interactive "r") - (let ((cbuf (current-buffer)) firstline work-buffer + (let ((cbuf (current-buffer)) + work-buffer ;; firstline (file-name (expand-file-name (concat (binhex-decode-region-internal start end t) ".data") @@ -287,9 +285,9 @@ If HEADER-ONLY is non-nil only decode header and return filename." (set-buffer (setq work-buffer (generate-new-buffer " *binhex-work*"))) (buffer-disable-undo work-buffer) - (insert-buffer-substring cbuf firstline end) + (insert-buffer-substring cbuf nil end) ;; firstline (cd temporary-file-directory) - (apply 'call-process-region + (apply #'call-process-region (point-min) (point-max) binhex-decoder-program diff --git a/lisp/mail/blessmail.el b/lisp/mail/blessmail.el index 505ce5d476..f380f0df29 100644 --- a/lisp/mail/blessmail.el +++ b/lisp/mail/blessmail.el @@ -1,4 +1,4 @@ -;;; blessmail.el --- decide whether movemail needs special privileges -*- no-byte-compile: t -*- +;;; blessmail.el --- decide whether movemail needs special privileges -*- no-byte-compile: t; lexical-binding: t; -*- ;; Copyright (C) 1994, 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/mail/emacsbug.el b/lisp/mail/emacsbug.el index 815ff4339e..5f3d75ecc7 100644 --- a/lisp/mail/emacsbug.el +++ b/lisp/mail/emacsbug.el @@ -1,4 +1,4 @@ -;;; emacsbug.el --- command to report Emacs bugs to appropriate mailing list +;;; emacsbug.el --- command to report Emacs bugs to appropriate mailing list -*- lexical-binding: t; -*- ;; Copyright (C) 1985, 1994, 1997-1998, 2000-2021 Free Software ;; Foundation, Inc. @@ -45,12 +45,10 @@ (defcustom report-emacs-bug-no-confirmation nil "If non-nil, suppress the confirmations asked for the sake of novice users." - :group 'emacsbug :type 'boolean) (defcustom report-emacs-bug-no-explanations nil "If non-nil, suppress the explanations given for the sake of novice users." - :group 'emacsbug :type 'boolean) ;; User options end here. @@ -204,7 +202,7 @@ This requires either the macOS \"open\" command, or the freedesktop (defvar message-sendmail-envelope-from) ;;;###autoload -(defun report-emacs-bug (topic &optional unused) +(defun report-emacs-bug (topic &optional _unused) "Report a bug in GNU Emacs. Prompts for bug subject. Leaves you in a mail buffer. @@ -219,10 +217,10 @@ Already submitted bugs can be found in the Emacs bug tracker: (let ((from-buffer (current-buffer)) (can-insert-mail (or (report-emacs-bug-can-use-xdg-email) (report-emacs-bug-can-use-osx-open))) - user-point message-end-point) - (setq message-end-point - (with-current-buffer (messages-buffer) - (point-max-marker))) + user-point) ;; message-end-point + ;; (setq message-end-point + ;; (with-current-buffer (messages-buffer) + ;; (point-max-marker))) (condition-case nil ;; For the novice user make sure there's always enough space for ;; the mail and the warnings buffer on this frame (Bug#10873). @@ -263,7 +261,7 @@ Already submitted bugs can be found in the Emacs bug tracker: "Bug-GNU-Emacs" 'face 'link 'help-echo (concat "mouse-2, RET: Follow this link") - 'action (lambda (button) + 'action (lambda (_button) (browse-url "https://lists.gnu.org/r/bug-gnu-emacs/")) 'follow-link t) (insert " mailing list\nand the GNU bug tracker at ") @@ -271,7 +269,7 @@ Already submitted bugs can be found in the Emacs bug tracker: "debbugs.gnu.org" 'face 'link 'help-echo (concat "mouse-2, RET: Follow this link") - 'action (lambda (button) + 'action (lambda (_button) (browse-url "https://debbugs.gnu.org/cgi/pkgreport.cgi?package=emacs;max-bugs=100;base-order=1;bug-rev=1")) 'follow-link t) @@ -347,10 +345,10 @@ usually do not have translators for other languages.\n\n"))) ;; This is so the user has to type something in order to send easily. (use-local-map (nconc (make-sparse-keymap) (current-local-map))) - (define-key (current-local-map) "\C-c\C-i" 'info-emacs-bug) + (define-key (current-local-map) "\C-c\C-i" #'info-emacs-bug) (if can-insert-mail (define-key (current-local-map) "\C-c\M-i" - 'report-emacs-bug-insert-to-mailer)) + #'report-emacs-bug-insert-to-mailer)) (setq report-emacs-bug-send-command (get mail-user-agent 'sendfunc) report-emacs-bug-send-hook (get mail-user-agent 'hookvar)) (if report-emacs-bug-send-command @@ -376,7 +374,7 @@ usually do not have translators for other languages.\n\n"))) (shrink-window-if-larger-than-buffer (get-buffer-window "*Bug Help*"))) ;; Make it less likely people will send empty messages. (if report-emacs-bug-send-hook - (add-hook report-emacs-bug-send-hook 'report-emacs-bug-hook nil t)) + (add-hook report-emacs-bug-send-hook #'report-emacs-bug-hook nil t)) (goto-char (point-max)) (skip-chars-backward " \t\n") (setq-local report-emacs-bug-orig-text @@ -398,7 +396,7 @@ usually do not have translators for other languages.\n\n"))) ;; This is used not only for X11 but also W32 and others. (insert "Windowing system distributor '" (x-server-vendor) "', version " - (mapconcat 'number-to-string (x-server-version) ".") "\n") + (mapconcat #'number-to-string (x-server-version) ".") "\n") (error t))) (let ((os (ignore-errors (report-emacs-bug--os-description)))) (if (stringp os) @@ -409,7 +407,7 @@ usually do not have translators for other languages.\n\n"))) system-configuration-options "'\n\n") (fill-region (line-beginning-position -1) (point)))) -(define-obsolete-function-alias 'report-emacs-bug-info 'info-emacs-bug "24.3") +(define-obsolete-function-alias 'report-emacs-bug-info #'info-emacs-bug "24.3") (defun report-emacs-bug-hook () "Do some checking before sending a bug report." diff --git a/lisp/mail/feedmail.el b/lisp/mail/feedmail.el index 2bcbdf4a22..d76017b994 100644 --- a/lisp/mail/feedmail.el +++ b/lisp/mail/feedmail.el @@ -1381,7 +1381,7 @@ It shows the simple addresses and gets a confirmation. Use as: (save-window-excursion (display-buffer (set-buffer (get-buffer-create " F-C-A-H-E"))) (erase-buffer) - (insert (mapconcat 'identity feedmail-address-list " ")) + (insert (mapconcat #'identity feedmail-address-list " ")) (if (not (y-or-n-p "How do you like them apples? ")) (error "FQM: Sending...gave up in last chance hook")))) @@ -1592,10 +1592,10 @@ Feeds the buffer to it." (feedmail-say-debug ">in-> feedmail-buffer-to-binmail %s" addr-listoid) (set-buffer prepped) (apply - 'call-process-region + #'call-process-region (append (list (point-min) (point-max) "/bin/sh" nil errors-to nil "-c" (format feedmail-binmail-template - (mapconcat 'identity addr-listoid " ")))))) + (mapconcat #'identity addr-listoid " ")))))) (defvar sendmail-program) @@ -1609,7 +1609,7 @@ local gurus." (require 'sendmail) (feedmail-say-debug ">in-> feedmail-buffer-to-sendmail %s" addr-listoid) (set-buffer prepped) - (apply 'call-process-region + (apply #'call-process-region (append (list (point-min) (point-max) sendmail-program nil errors-to nil "-oi" "-t") ;; provide envelope "from" to sendmail; results will vary @@ -2042,7 +2042,7 @@ backup file names and the like)." (message "FQM: Trapped `%s', message left in queue." (car signal-stuff)) (sit-for 3) (message "FQM: Trap details: \"%s\"" - (mapconcat 'identity (cdr signal-stuff) "\" \"")) + (mapconcat #'identity (cdr signal-stuff) "\" \"")) (sit-for 3))) (kill-buffer blobby-buffer) (feedmail-say-chatter diff --git a/lisp/mail/flow-fill.el b/lisp/mail/flow-fill.el index 0fab1b21b4..5319ab994c 100644 --- a/lisp/mail/flow-fill.el +++ b/lisp/mail/flow-fill.el @@ -81,7 +81,7 @@ RFC 2646 suggests 66 characters for readability." (while (setq end (text-property-any start (point-max) 'hard 't)) (save-restriction (narrow-to-region start end) - (let ((fill-column (eval fill-flowed-encode-column))) + (let ((fill-column (eval fill-flowed-encode-column t))) (fill-flowed-fill-buffer)) (goto-char (point-min)) (while (re-search-forward "\n" nil t) @@ -119,7 +119,7 @@ If BUFFER is nil, default to the current buffer. If DELETE-SPACE, delete RFC2646 spaces padding at the end of lines." (with-current-buffer (or buffer (current-buffer)) - (let ((fill-column (eval fill-flowed-display-column))) + (let ((fill-column (eval fill-flowed-display-column t))) (goto-char (point-min)) (while (not (eobp)) (cond diff --git a/lisp/mail/ietf-drums.el b/lisp/mail/ietf-drums.el index 795e37dced..2d68357474 100644 --- a/lisp/mail/ietf-drums.el +++ b/lisp/mail/ietf-drums.el @@ -232,13 +232,13 @@ If DECODE, the DISPLAY-NAME will have RFC2047 decoding performed ;; If we found no display-name, then we look for comments. (if display-name (setq display-string - (mapconcat 'identity (reverse display-name) " ")) + (mapconcat #'identity (reverse display-name) " ")) (setq display-string (ietf-drums-get-comment string))) (if (not mailbox) (when (and display-string (string-match "@" display-string)) (cons - (mapconcat 'identity (nreverse display-name) "") + (mapconcat #'identity (nreverse display-name) "") (ietf-drums-get-comment string))) (cons mailbox (if decode (rfc2047-decode-string display-string) diff --git a/lisp/mail/mail-extr.el b/lisp/mail/mail-extr.el index 4e3bf78c80..7fbdfefc46 100644 --- a/lisp/mail/mail-extr.el +++ b/lisp/mail/mail-extr.el @@ -1,4 +1,4 @@ -;;; mail-extr.el --- extract full name and address from email header +;;; mail-extr.el --- extract full name and address from email header -*- lexical-binding: t; -*- ;; Copyright (C) 1991-1994, 1997, 2001-2021 Free Software Foundation, ;; Inc. @@ -222,23 +222,20 @@ "Whether to try to guess middle initial from mail address. If true, then when we see an address like \"John Smith \" we will assume that \"John Q. Smith\" is the fellow's name." - :type 'boolean - :group 'mail-extr) + :type 'boolean) (defcustom mail-extr-ignore-single-names nil "Whether to ignore a name that is just a single word. If true, then when we see an address like \"Idiot \" we will act as though we couldn't find a full name in the address." :type 'boolean - :version "22.1" - :group 'mail-extr) + :version "22.1") (defcustom mail-extr-ignore-realname-equals-mailbox-name t "Whether to ignore a name that is equal to the mailbox name. If true, then when the address is like \"Single \" we will act as though we couldn't find a full name in the address." - :type 'boolean - :group 'mail-extr) + :type 'boolean) ;; Matches a leading title that is not part of the name (does not ;; contribute to uniquely identifying the person). @@ -248,19 +245,16 @@ we will act as though we couldn't find a full name in the address." "Matches prefixes to the full name that identify a person's position. These are stripped from the full name because they do not contribute to uniquely identifying the person." - :type 'regexp - :group 'mail-extr) + :type 'regexp) (defcustom mail-extr-@-binds-tighter-than-! nil "Whether the local mail transport agent looks at ! before @." - :type 'boolean - :group 'mail-extr) + :type 'boolean) (defcustom mail-extr-mangle-uucp nil "Whether to throw away information in UUCP addresses by translating things like \"foo!bar!baz@host\" into \"baz@bar.UUCP\"." - :type 'boolean - :group 'mail-extr) + :type 'boolean) ;;---------------------------------------------------------------------- ;; what orderings are meaningful????? @@ -760,7 +754,6 @@ non-display use, you should probably use end-of-address <-pos >-pos @-pos colon-pos comma-pos !-pos %-pos \;-pos group-:-pos group-\;-pos route-addr-:-pos - record-pos-symbol first-real-pos last-real-pos phrase-beg phrase-end ;; Dynamically set in mail-extr-voodoo. @@ -852,13 +845,16 @@ non-display use, you should probably use ) ;; record the position of various interesting chars, determine ;; validity later. - ((setq record-pos-symbol - (cdr (assq char - '((?< . <-pos) (?> . >-pos) (?@ . @-pos) - (?: . colon-pos) (?, . comma-pos) (?! . !-pos) - (?% . %-pos) (?\; . \;-pos))))) - (set record-pos-symbol - (cons (point) (symbol-value record-pos-symbol))) + ((memq char '(?< ?> ?@ ?: ?, ?! ?% ?\;)) + (push (point) (pcase-exhaustive char + (?< <-pos) + (?> >-pos) + (?@ @-pos) + (?: colon-pos) + (?, comma-pos) + (?! !-pos) + (?% %-pos) + (?\; \;-pos))) (forward-char 1)) ((eq char ?.) (forward-char 1)) @@ -1065,7 +1061,7 @@ non-display use, you should probably use (mail-extr-demarkerize route-addr-:-pos) (setq route-addr-:-pos nil >-pos (mail-extr-demarkerize >-pos) - %-pos (mapcar 'mail-extr-demarkerize %-pos))) + %-pos (mapcar #'mail-extr-demarkerize %-pos))) ;; de-listify @-pos (setq @-pos (car @-pos)) @@ -1122,7 +1118,7 @@ non-display use, you should probably use (setq insert-point (point-max))) (%-pos (setq insert-point (car (last %-pos)) - saved-%-pos (mapcar 'mail-extr-markerize %-pos) + saved-%-pos (mapcar #'mail-extr-markerize %-pos) %-pos nil @-pos (mail-extr-markerize @-pos))) (@-pos @@ -1162,7 +1158,7 @@ non-display use, you should probably use "uucp")) (setq !-pos (cdr !-pos)))) (and saved-%-pos - (setq %-pos (append (mapcar 'mail-extr-demarkerize + (setq %-pos (append (mapcar #'mail-extr-demarkerize saved-%-pos) %-pos))) (setq @-pos (mail-extr-demarkerize @-pos)) @@ -1461,8 +1457,7 @@ If it is neither nil nor a string, modifying of names will never take place. It affects how `mail-extract-address-components' works." :type '(choice (regexp :size 0) (const :tag "Always enabled" nil) - (const :tag "Always disabled" t)) - :group 'mail-extr) + (const :tag "Always disabled" t))) (defun mail-extr-voodoo (mbox-beg mbox-end canonicalization-buffer) (unless (and mail-extr-disable-voodoo diff --git a/lisp/mail/mail-hist.el b/lisp/mail/mail-hist.el index 37c8ad6886..239b386ff8 100644 --- a/lisp/mail/mail-hist.el +++ b/lisp/mail/mail-hist.el @@ -1,4 +1,4 @@ -;;; mail-hist.el --- headers and message body history for outgoing mail +;;; mail-hist.el --- headers and message body history for outgoing mail -*- lexical-binding: t; -*- ;; Copyright (C) 1994, 2001-2021 Free Software Foundation, Inc. @@ -69,8 +69,8 @@ ;;;###autoload (defun mail-hist-enable () - (add-hook 'mail-mode-hook 'mail-hist-define-keys) - (add-hook 'mail-send-hook 'mail-hist-put-headers-into-history)) + (add-hook 'mail-mode-hook #'mail-hist-define-keys) + (add-hook 'mail-send-hook #'mail-hist-put-headers-into-history)) (defvar mail-hist-header-ring-alist nil "Alist of form (header-name . history-ring). @@ -80,14 +80,12 @@ previous/next input.") (defcustom mail-hist-history-size (or kill-ring-max 1729) "The maximum number of elements in a mail field's history. Oldest elements are dumped first." - :type 'integer - :group 'mail-hist) + :type 'integer) ;;;###autoload (defcustom mail-hist-keep-history t "Non-nil means keep a history for headers and text of outgoing mail." - :type 'boolean - :group 'mail-hist) + :type 'boolean) ;; For handling repeated history requests (defvar mail-hist-access-count 0) @@ -184,8 +182,7 @@ HEADER is a string without the colon." (defcustom mail-hist-text-size-limit nil "Don't store any header or body with more than this many characters. If the value is nil, that means no limit on text size." - :type '(choice (const nil) integer) - :group 'mail-hist) + :type '(choice (const nil) integer)) (defun mail-hist-text-too-long-p (text) "Return non-nil if TEXT's length exceeds `mail-hist-text-size-limit'." diff --git a/lisp/mail/mail-utils.el b/lisp/mail/mail-utils.el index 83125a0d20..bb1f8f13ba 100644 --- a/lisp/mail/mail-utils.el +++ b/lisp/mail/mail-utils.el @@ -134,7 +134,7 @@ we expect to find and remove the wrapper characters =?ISO-8859-1?Q?....?=." (aref string (1+ (match-beginning 1)))))) strings))) (setq i (match-end 0))) - (apply 'concat (nreverse (cons (substring string i) strings)))))) + (apply #'concat (nreverse (cons (substring string i) strings)))))) ;; FIXME Gnus for some reason has `quoted-printable-decode-region' in qp.el. ;;;###autoload @@ -194,7 +194,7 @@ Also delete leading/trailing whitespace and replace FOO with just BAR. Return a modified address list." (when address (if mail-use-rfc822 - (mapconcat 'identity (rfc822-addresses address) ", ") + (mapconcat #'identity (rfc822-addresses address) ", ") (let (pos) ;; Strip comments. @@ -282,7 +282,7 @@ comma-separated list, and return the pruned list." destinations)) ;; Legacy name -(define-obsolete-function-alias 'rmail-dont-reply-to 'mail-dont-reply-to "24.1") +(define-obsolete-function-alias 'rmail-dont-reply-to #'mail-dont-reply-to "24.1") ;;;###autoload diff --git a/lisp/mail/mailabbrev.el b/lisp/mail/mailabbrev.el index 2147049ab1..5cb4a7469a 100644 --- a/lisp/mail/mailabbrev.el +++ b/lisp/mail/mailabbrev.el @@ -1,4 +1,4 @@ -;;; mailabbrev.el --- abbrev-expansion of mail aliases +;;; mailabbrev.el --- abbrev-expansion of mail aliases -*- lexical-binding: t; -*- ;; Copyright (C) 1985-1987, 1992-1993, 1996-1997, 2000-2021 Free ;; Software Foundation, Inc. @@ -140,15 +140,13 @@ abbrev-like expansion is performed when editing certain mail headers (those specified by `mail-abbrev-mode-regexp'), based on the entries in your `mail-personal-alias-file'." :global t - :group 'mail-abbrev :version "20.3" (if mail-abbrevs-mode (mail-abbrevs-enable) (mail-abbrevs-disable))) (defcustom mail-abbrevs-only nil "Non-nil means only mail abbrevs should expand automatically. Other abbrevs expand only when you explicitly use `expand-abbrev'." - :type 'boolean - :group 'mail-abbrev) + :type 'boolean) ;; originally defined in sendmail.el - used to be an alist, now is a table. (defvar mail-abbrevs nil @@ -186,11 +184,11 @@ no aliases, which is represented by this being a table with no entries.)") (abbrev-mode 1)) (defun mail-abbrevs-enable () - (add-hook 'mail-mode-hook 'mail-abbrevs-setup)) + (add-hook 'mail-mode-hook #'mail-abbrevs-setup)) (defun mail-abbrevs-disable () "Turn off use of the `mailabbrev' package." - (remove-hook 'mail-mode-hook 'mail-abbrevs-setup) + (remove-hook 'mail-mode-hook #'mail-abbrevs-setup) (abbrev-mode (if (default-value 'abbrev-mode) 1 -1))) ;;;###autoload @@ -258,8 +256,7 @@ By default this is the file specified by `mail-personal-alias-file'." "String inserted between addresses in multi-address mail aliases. This has to contain a comma, so \", \" is a reasonable value. You might also want something like \",\\n \" to get each address on its own line." - :type 'string - :group 'mail-abbrev) + :type 'string) ;; define-mail-abbrev sets this flag, which causes mail-resolve-all-aliases ;; to be called before expanding abbrevs if it's necessary. @@ -367,7 +364,7 @@ double-quotes." (defun mail-resolve-all-aliases-1 (sym &optional so-far) (if (memq sym so-far) (error "mail alias loop detected: %s" - (mapconcat 'symbol-name (cons sym so-far) " <- "))) + (mapconcat #'symbol-name (cons sym so-far) " <- "))) (let ((definition (and (boundp sym) (symbol-value sym)))) (if definition (let ((result '()) @@ -420,8 +417,7 @@ of the current line; if it matches, abbrev mode will be turned on, otherwise it will be turned off. (You don't need to worry about continuation lines.) This should be set to match those mail fields in which you want abbreviations turned on." - :type 'regexp - :group 'mail-abbrev) + :type 'regexp) (defvar mail-abbrev-syntax-table nil "The syntax-table used for abbrev-expansion purposes. @@ -433,14 +429,14 @@ of a mail alias. The value is set up, buffer-local, when first needed.") (make-local-variable 'mail-abbrev-syntax-table) (unless mail-abbrev-syntax-table (let ((tab (copy-syntax-table (syntax-table))) - (_ (aref (standard-syntax-table) ?_)) + (syntax-_ (aref (standard-syntax-table) ?_)) (w (aref (standard-syntax-table) ?w))) (map-char-table (lambda (key value) (if (null value) ;; Fetch the inherited value (setq value (aref tab key))) - (if (equal value _) + (if (equal value syntax-_) (set-char-table-range tab key w))) tab) (modify-syntax-entry ?@ "w" tab) @@ -600,12 +596,12 @@ In other respects, this behaves like `end-of-buffer', which see." (eval-after-load "sendmail" '(progn - (define-key mail-mode-map "\C-c\C-a" 'mail-abbrev-insert-alias) + (define-key mail-mode-map "\C-c\C-a" #'mail-abbrev-insert-alias) (define-key mail-mode-map "\e\t" ; like completion-at-point - 'mail-abbrev-complete-alias))) + #'mail-abbrev-complete-alias))) ;; FIXME: Use `completion-at-point'. -;;(define-key mail-mode-map "\C-n" 'mail-abbrev-next-line) -;;(define-key mail-mode-map "\M->" 'mail-abbrev-end-of-buffer) +;;(define-key mail-mode-map "\C-n" #'mail-abbrev-next-line) +;;(define-key mail-mode-map "\M->" #'mail-abbrev-end-of-buffer) (provide 'mailabbrev) diff --git a/lisp/mail/mailclient.el b/lisp/mail/mailclient.el index 3cba6a60e8..5c153ce1c1 100644 --- a/lisp/mail/mailclient.el +++ b/lisp/mail/mailclient.el @@ -1,4 +1,4 @@ -;;; mailclient.el --- mail sending via system's mail client. +;;; mailclient.el --- mail sending via system's mail client. -*- lexical-binding: t; -*- ;; Copyright (C) 2005-2021 Free Software Foundation, Inc. diff --git a/lisp/mail/mailheader.el b/lisp/mail/mailheader.el index cbc01e4a44..0443279be8 100644 --- a/lisp/mail/mailheader.el +++ b/lisp/mail/mailheader.el @@ -1,4 +1,4 @@ -;;; mailheader.el --- mail header parsing, merging, formatting +;;; mailheader.el --- mail header parsing, merging, formatting -*- lexical-binding: t; -*- ;; Copyright (C) 1996, 2001-2021 Free Software Foundation, Inc. @@ -99,23 +99,23 @@ value." headers) ;; Advertised part of the interface; see mail-header, mail-header-set. -(with-suppressed-warnings ((lexical headers)) - (defvar headers)) -(defsubst mail-header (header &optional header-alist) +(defun mail-header (header &optional header-alist) "Return the value associated with header HEADER in HEADER-ALIST. If the value is a string, it is the original value of the header. If the value is a list, its first element is the original value of the header, -with any subsequent elements being the result of parsing the value. -If HEADER-ALIST is nil, the dynamically bound variable `headers' is used." +with any subsequent elements being the result of parsing the value." (declare (gv-setter (lambda (value) `(mail-header-set ,header ,value ,header-alist)))) + (with-suppressed-warnings ((lexical headers)) (defvar headers)) (cdr (assq header (or header-alist headers)))) (defun mail-header-set (header value &optional header-alist) "Set the value associated with header HEADER to VALUE in HEADER-ALIST. HEADER-ALIST defaults to the dynamically bound variable `headers' if nil. See `mail-header' for the semantics of VALUE." + (declare (obsolete alist-get "28.1")) + (with-suppressed-warnings ((lexical headers)) (defvar headers)) (let* ((alist (or header-alist headers)) (entry (assq header alist))) (if entry @@ -131,10 +131,13 @@ should be a string or a list of string. The first element may be nil to denote that the formatting functions must use the remaining elements, or skip the header altogether if there are no other elements. The macro `mail-header' can be used to access headers in HEADERS." - (mapcar - (lambda (rule) - (cons (car rule) (eval (cdr rule)))) - merge-rules)) + (declare (obsolete alist-get "28.1")) + (with-suppressed-warnings ((lexical headers)) (defvar headers)) + (let ((headers headers)) + (mapcar + (lambda (rule) + (cons (car rule) (eval (cdr rule) t))) + merge-rules))) (defvar mail-header-format-function (lambda (header value) @@ -167,7 +170,7 @@ A key of nil has as its value a list of defaulted headers to ignore." (mapcar #'car format-rules)))) (dolist (rule format-rules) (let* ((header (car rule)) - (value (mail-header header))) + (value (alist-get header headers))) (if (stringp header) (setq header (intern header))) (cond ((null header) 'ignore) @@ -176,13 +179,11 @@ A key of nil has as its value a list of defaulted headers to ignore." (unless (memq (car defaulted) ignore) (let* ((header (car defaulted)) (value (cdr defaulted))) - (if (cdr rule) - (funcall (cdr rule) header value) - (funcall mail-header-format-function header value)))))) + (funcall (or (cdr rule) mail-header-format-function) + header value))))) (value - (if (cdr rule) - (funcall (cdr rule) header value) - (funcall mail-header-format-function header value)))))) + (funcall (or (cdr rule) mail-header-format-function) + header value))))) (insert "\n"))) (provide 'mailheader) diff --git a/lisp/mail/mspools.el b/lisp/mail/mspools.el index 970f52c337..6d83414058 100644 --- a/lisp/mail/mspools.el +++ b/lisp/mail/mspools.el @@ -167,11 +167,11 @@ your primary spool is. If this fails, set it to something like (defvar mspools-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\C-c\C-c" 'mspools-visit-spool) - (define-key map "\C-m" 'mspools-visit-spool) - (define-key map " " 'mspools-visit-spool) - (define-key map "n" 'next-line) - (define-key map "p" 'previous-line) + (define-key map "\C-c\C-c" #'mspools-visit-spool) + (define-key map "\C-m" #'mspools-visit-spool) + (define-key map " " #'mspools-visit-spool) + (define-key map "n" #'next-line) + (define-key map "p" #'previous-line) map) "Keymap for the *spools* buffer.") diff --git a/lisp/mail/rfc822.el b/lisp/mail/rfc822.el index f07fcdfc9f..2e97226662 100644 --- a/lisp/mail/rfc822.el +++ b/lisp/mail/rfc822.el @@ -1,4 +1,4 @@ -;;; rfc822.el --- hairy RFC 822 (or later) parser for mail, news, etc. +;;; rfc822.el --- hairy RFC 822 (or later) parser for mail, news, etc. -*- lexical-binding: t; -*- ;; Copyright (C) 1986-1987, 1990, 2001-2021 Free Software Foundation, ;; Inc. diff --git a/lisp/mail/rmail-spam-filter.el b/lisp/mail/rmail-spam-filter.el index dda472eb30..d833685a8d 100644 --- a/lisp/mail/rmail-spam-filter.el +++ b/lisp/mail/rmail-spam-filter.el @@ -1,4 +1,4 @@ -;;; rmail-spam-filter.el --- spam filter for Rmail, the Emacs mail reader +;;; rmail-spam-filter.el --- spam filter for Rmail, the Emacs mail reader -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. ;; Keywords: email, spam, filter, rmail @@ -82,50 +82,42 @@ (defcustom rmail-use-spam-filter nil "Non-nil to activate the Rmail spam filter. Set `rsf-definitions-alist' to define what you consider spam emails." - :type 'boolean - :group 'rmail-spam-filter) + :type 'boolean) (defcustom rsf-file "~/XRMAIL-SPAM" "Name of Rmail file for optionally saving some of the spam. You can either just delete spam, or save it in this file for later review. Which action to take for each spam definition is specified by the \"action\" element of the definition." - :type 'string - :group 'rmail-spam-filter) + :type 'string) (defcustom rsf-no-blind-cc nil "Non-nil means mail with no explicit To: or Cc: is spam." - :type 'boolean - :group 'rmail-spam-filter) + :type 'boolean) (defcustom rsf-ignore-case nil "Non-nil means to ignore case in `rsf-definitions-alist'." - :type 'boolean - :group 'rmail-spam-filter) + :type 'boolean) (defcustom rsf-beep nil "Non-nil means to beep if spam is found." - :type 'boolean - :group 'rmail-spam-filter) + :type 'boolean) (defcustom rsf-sleep-after-message 2.0 "Seconds to wait after displaying a message that spam was found." - :type 'number - :group 'rmail-spam-filter) + :type 'number) (defcustom rsf-min-region-to-spam-list 7 "Minimum size of region that you can add to the spam list. The aim is to avoid adding too short a region, which could result in false positive identification of a valid message as spam." - :type 'integer - :group 'rmail-spam-filter) + :type 'integer) (defcustom rsf-autosave-newly-added-definitions nil "Non-nil to auto-save new spam entries. Any time you add an entry via the \"Spam\" menu, immediately saves the custom file." - :type 'boolean - :group 'rmail-spam-filter) + :type 'boolean) (defcustom rsf-white-list nil "List of regexps to identify valid senders. @@ -133,8 +125,7 @@ If any element matches the \"From\" header, the message is flagged as a valid, non-spam message. E.g., if your domain is \"emacs.com\" then including \"emacs\\\\.com\" in this list would flag all mail (purporting to be) from your colleagues as valid." - :type '(repeat regexp) - :group 'rmail-spam-filter) + :type '(repeat regexp)) (defcustom rsf-definitions-alist nil "A list of rules (definitions) matching spam messages. @@ -178,8 +169,7 @@ A rule matches only if all the specified elements match." (choice :tag "Action selection" (const :tag "Output and delete" output-and-delete) (const :tag "Delete" delete-spam) - )))) - :group 'rmail-spam-filter) + ))))) ;; FIXME nothing uses this, and it could just be let-bound. (defvar rsf-scanning-messages-now nil @@ -224,6 +214,8 @@ the cdr is set to t. Else, the car is set to nil." ;; empty buffer. (1- (or (rmail-first-unseen-message) 1)))) +(defvar bbdb/mail_auto_create_p) + (defun rmail-spam-filter (msg) "Return nil if message number MSG is spam based on `rsf-definitions-alist'. If spam, optionally output message to a file `rsf-file' and delete @@ -522,12 +514,12 @@ to the spam list (remember to save it)" region-to-spam-list)))))) ["Customize spam definitions" rsf-customize-spam-definitions] ["Browse spam customizations" rsf-customize-group] )) - (define-key map "\C-cSt" 'rsf-add-subject-to-spam-list) - (define-key map "\C-cSr" 'rsf-add-sender-to-spam-list) - (define-key map "\C-cSn" 'rsf-add-region-to-spam-list) - (define-key map "\C-cSa" 'rsf-custom-save-all) - (define-key map "\C-cSd" 'rsf-customize-spam-definitions) - (define-key map "\C-cSg" 'rsf-customize-group)) + (define-key map "\C-cSt" #'rsf-add-subject-to-spam-list) + (define-key map "\C-cSr" #'rsf-add-sender-to-spam-list) + (define-key map "\C-cSn" #'rsf-add-region-to-spam-list) + (define-key map "\C-cSa" #'rsf-custom-save-all) + (define-key map "\C-cSd" #'rsf-customize-spam-definitions) + (define-key map "\C-cSg" #'rsf-customize-group)) (defun rsf-add-content-type-field () "Maintain backward compatibility for `rmail-spam-filter'. diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el index 8ccf1bffdd..2bd3ffa291 100644 --- a/lisp/mail/rmail.el +++ b/lisp/mail/rmail.el @@ -1721,7 +1721,7 @@ not be a new one). It returns non-nil if it got any new messages." (buffer-read-only nil) ;; Don't make undo records while getting mail. (buffer-undo-list t) - delete-files files file-last-names) + files file-last-names) ;; delete-files ;; Pull files off all-files onto files as long as there is ;; no name conflict. A conflict happens when two inbox ;; file names have the same last component. @@ -1743,7 +1743,7 @@ not be a new one). It returns non-nil if it got any new messages." (while (not (looking-back "\n\n" (- (point) 2))) (insert "\n"))) (setq found (or - (rmail-get-new-mail-1 file-name files delete-files) + (rmail-get-new-mail-1 file-name files nil) ;; delete-files found)))) ;; Move to the first new message unless we have other unseen ;; messages before it. diff --git a/lisp/mail/rmailedit.el b/lisp/mail/rmailedit.el index c3b351d7bc..fd24bdcecc 100644 --- a/lisp/mail/rmailedit.el +++ b/lisp/mail/rmailedit.el @@ -1,4 +1,4 @@ -;;; rmailedit.el --- "RMAIL edit mode" Edit the current message +;;; rmailedit.el --- "RMAIL edit mode" Edit the current message -*- lexical-binding: t; -*- ;; Copyright (C) 1985, 1994, 2001-2021 Free Software Foundation, Inc. @@ -38,8 +38,8 @@ (let ((map (make-sparse-keymap))) ;; Make a keymap that inherits text-mode-map. (set-keymap-parent map text-mode-map) - (define-key map "\C-c\C-c" 'rmail-cease-edit) - (define-key map "\C-c\C-]" 'rmail-abort-edit) + (define-key map "\C-c\C-c" #'rmail-cease-edit) + (define-key map "\C-c\C-]" #'rmail-abort-edit) map)) (declare-function rmail-summary-disable "rmailsum" ()) @@ -69,7 +69,7 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'. (setq-local auto-save-include-big-deletions t) ;; If someone uses C-x C-s, don't clobber the rmail file (bug#2625). (add-hook 'write-region-annotate-functions - 'rmail-write-region-annotate nil t) + #'rmail-write-region-annotate nil t) (run-mode-hooks 'rmail-edit-mode-hook))) ;; Rmail Edit mode is suitable only for specially formatted data. diff --git a/lisp/mail/rmailkwd.el b/lisp/mail/rmailkwd.el index 657b3629bd..acbb5880b5 100644 --- a/lisp/mail/rmailkwd.el +++ b/lisp/mail/rmailkwd.el @@ -1,4 +1,4 @@ -;;; rmailkwd.el --- part of the "RMAIL" mail reader for Emacs +;;; rmailkwd.el --- part of the "RMAIL" mail reader for Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 1985, 1988, 1994, 2001-2021 Free Software Foundation, ;; Inc. @@ -73,7 +73,7 @@ according to the choice made, and returns a symbol." (or (eq major-mode 'rmail-summary-mode) (rmail-summary-exists) (and (setq old (rmail-get-keywords)) - (mapc 'rmail-make-label (split-string old ", ")))) + (mapc #'rmail-make-label (split-string old ", ")))) (completing-read (concat prompt (if rmail-last-label (concat " (default " diff --git a/lisp/mail/rmailmsc.el b/lisp/mail/rmailmsc.el index ef5f3c31bb..673b2c5a7e 100644 --- a/lisp/mail/rmailmsc.el +++ b/lisp/mail/rmailmsc.el @@ -1,4 +1,4 @@ -;;; rmailmsc.el --- miscellaneous support functions for the RMAIL mail reader +;;; rmailmsc.el --- miscellaneous support functions for the RMAIL mail reader -*- lexical-binding: t; -*- ;; Copyright (C) 1985, 2001-2021 Free Software Foundation, Inc. @@ -45,7 +45,7 @@ This applies only to the current session." (nreverse (mail-parse-comma-list))))) (when (or (not rmail-inbox-list) (y-or-n-p (concat "Replace " - (mapconcat 'identity + (mapconcat #'identity rmail-inbox-list ", ") "? "))) diff --git a/lisp/mail/rmailout.el b/lisp/mail/rmailout.el index 9305a48b8d..eb8590f1f7 100644 --- a/lisp/mail/rmailout.el +++ b/lisp/mail/rmailout.el @@ -1,4 +1,4 @@ -;;; rmailout.el --- "RMAIL" mail reader for Emacs: output message to a file +;;; rmailout.el --- "RMAIL" mail reader for Emacs: output message to a file -*- lexical-binding: t; -*- ;; Copyright (C) 1985, 1987, 1993-1994, 2001-2021 Free Software ;; Foundation, Inc. @@ -81,14 +81,14 @@ This uses `rmail-output-file-alist'." (widen) (narrow-to-region beg end) (let ((tail rmail-output-file-alist) - answer err) + answer) ;; err ;; Suggest a file based on a pattern match. (while (and tail (not answer)) (goto-char (point-min)) (if (re-search-forward (caar tail) nil t) (setq answer (condition-case err - (eval (cdar tail)) + (eval (cdar tail) t) (error (display-warning 'rmail-output @@ -197,7 +197,8 @@ display message number MSG." (defun rmail-convert-to-babyl-format () "Convert the mbox message in the current buffer to Babyl format." - (let ((count 0) (start (point-min)) + (let (;; (count 0) + (start (point-min)) (case-fold-search nil) (buffer-undo-list t)) (goto-char (point-min)) @@ -357,7 +358,7 @@ unless NOMSG is a symbol (neither nil nor t). AS-SEEN is non-nil if we are copying the message \"as seen\"." (let ((case-fold-search t) encrypted-file-name - from date) + ) ;; from date (goto-char (point-min)) ;; Preserve the Mail-From and MIME-Version fields ;; even if they have been pruned. diff --git a/lisp/mail/rmailsort.el b/lisp/mail/rmailsort.el index 2c42e6c859..1669c8cd7b 100644 --- a/lisp/mail/rmailsort.el +++ b/lisp/mail/rmailsort.el @@ -1,4 +1,4 @@ -;;; rmailsort.el --- Rmail: sort messages +;;; rmailsort.el --- Rmail: sort messages -*- lexical-binding: t; -*- ;; Copyright (C) 1990, 1993-1994, 2001-2021 Free Software Foundation, ;; Inc. @@ -142,7 +142,7 @@ If prefix argument REVERSE is non-nil, sorts in reverse order." "\\(,\\|\\'\\)") labelvec)) (setq labels (substring labels (match-end 0)))) - (setq labelvec (apply 'vector (nreverse labelvec)) + (setq labelvec (apply #'vector (nreverse labelvec)) nmax (length labelvec)) (rmail-sort-messages reverse ;; If no labels match, returns nmax; if they @@ -205,7 +205,7 @@ Numeric keys are sorted numerically, all others as strings." (inhibit-read-only t) (current-message nil) (msgnum 1) - (msginfo nil) + ;; (msginfo nil) (undo (not (eq buffer-undo-list t)))) ;; There's little hope that we can easily undo after that. (buffer-disable-undo (current-buffer)) diff --git a/lisp/mail/smtpmail.el b/lisp/mail/smtpmail.el index 5526f2fbe6..5c7ffd9989 100644 --- a/lisp/mail/smtpmail.el +++ b/lisp/mail/smtpmail.el @@ -326,7 +326,7 @@ for `smtpmail-try-auth-method'.") ;; Insert an extra newline if we need it to work around ;; Sun's bug that swallows newlines. (goto-char (1+ delimline)) - (if (eval mail-mailer-swallows-blank-line) + (if (eval mail-mailer-swallows-blank-line t) (newline)) ;; Find and handle any Fcc fields. (goto-char (point-min)) @@ -627,7 +627,7 @@ USER and PASSWORD should be non-nil." (= code (car response))))) (defun smtpmail-response-text (response) - (mapconcat 'identity (cdr response) "\n")) + (mapconcat #'identity (cdr response) "\n")) (defun smtpmail-query-smtp-server () "Query for an SMTP server and try to contact it. @@ -741,7 +741,7 @@ Returns an error if the server cannot be contacted." "Unable to contact server"))) ;; set the send-filter - (set-process-filter process 'smtpmail-process-filter) + (set-process-filter process #'smtpmail-process-filter) (let* ((greeting (plist-get (cdr result) :greeting)) (code (smtpmail-response-code greeting))) diff --git a/lisp/mail/supercite.el b/lisp/mail/supercite.el index 99ac41dd9b..dc1c641052 100644 --- a/lisp/mail/supercite.el +++ b/lisp/mail/supercite.el @@ -1,4 +1,4 @@ -;;; supercite.el --- minor mode for citing mail and news replies +;;; supercite.el --- minor mode for citing mail and news replies -*- lexical-binding: t; -*- ;; Copyright (C) 1993, 1997, 2001-2021 Free Software Foundation, Inc. @@ -527,71 +527,71 @@ string." (defvar sc-T-keymap (let ((map (make-sparse-keymap))) - (define-key map "a" 'sc-S-preferred-attribution-list) - (define-key map "b" 'sc-T-mail-nuke-blank-lines) - (define-key map "c" 'sc-T-confirm-always) - (define-key map "d" 'sc-T-downcase) - (define-key map "e" 'sc-T-electric-references) - (define-key map "f" 'sc-T-auto-fill-region) - (define-key map "h" 'sc-T-describe) - (define-key map "l" 'sc-S-cite-region-limit) - (define-key map "n" 'sc-S-mail-nuke-mail-headers) - (define-key map "N" 'sc-S-mail-header-nuke-list) - (define-key map "o" 'sc-T-electric-circular) - (define-key map "p" 'sc-S-preferred-header-style) - (define-key map "s" 'sc-T-nested-citation) - (define-key map "u" 'sc-T-use-only-preferences) - (define-key map "w" 'sc-T-fixup-whitespace) - (define-key map "?" 'sc-T-describe) + (define-key map "a" #'sc-S-preferred-attribution-list) + (define-key map "b" #'sc-T-mail-nuke-blank-lines) + (define-key map "c" #'sc-T-confirm-always) + (define-key map "d" #'sc-T-downcase) + (define-key map "e" #'sc-T-electric-references) + (define-key map "f" #'sc-T-auto-fill-region) + (define-key map "h" #'sc-T-describe) + (define-key map "l" #'sc-S-cite-region-limit) + (define-key map "n" #'sc-S-mail-nuke-mail-headers) + (define-key map "N" #'sc-S-mail-header-nuke-list) + (define-key map "o" #'sc-T-electric-circular) + (define-key map "p" #'sc-S-preferred-header-style) + (define-key map "s" #'sc-T-nested-citation) + (define-key map "u" #'sc-T-use-only-preferences) + (define-key map "w" #'sc-T-fixup-whitespace) + (define-key map "?" #'sc-T-describe) map) "Keymap for sub-keymap of setting and toggling functions.") (defvar sc-mode-map (let ((map (make-sparse-keymap))) - (define-key map "c" 'sc-cite-region) - (define-key map "f" 'sc-mail-field-query) - (define-key map "g" 'sc-mail-process-headers) - (define-key map "h" 'sc-describe) - (define-key map "i" 'sc-insert-citation) - (define-key map "o" 'sc-open-line) - (define-key map "r" 'sc-recite-region) - (define-key map "\C-p" 'sc-raw-mode-toggle) - (define-key map "u" 'sc-uncite-region) - (define-key map "w" 'sc-insert-reference) - (define-key map "\C-t" sc-T-keymap) - (define-key map "?" 'sc-describe) + (define-key map "c" #'sc-cite-region) + (define-key map "f" #'sc-mail-field-query) + (define-key map "g" #'sc-mail-process-headers) + (define-key map "h" #'sc-describe) + (define-key map "i" #'sc-insert-citation) + (define-key map "o" #'sc-open-line) + (define-key map "r" #'sc-recite-region) + (define-key map "\C-p" #'sc-raw-mode-toggle) + (define-key map "u" #'sc-uncite-region) + (define-key map "w" #'sc-insert-reference) + (define-key map "\C-t" sc-T-keymap) + (define-key map "?" #'sc-describe) map) "Keymap for Supercite quasi-mode.") (defvar sc-electric-mode-map (let ((map (make-sparse-keymap))) - (define-key map "p" 'sc-eref-prev) - (define-key map "n" 'sc-eref-next) - (define-key map "s" 'sc-eref-setn) - (define-key map "j" 'sc-eref-jump) - (define-key map "x" 'sc-eref-abort) - (define-key map "q" 'sc-eref-abort) - (define-key map "\r" 'sc-eref-exit) - (define-key map "\n" 'sc-eref-exit) - (define-key map "g" 'sc-eref-goto) - (define-key map "?" 'describe-mode) - (define-key map "\C-h" 'describe-mode) - (define-key map [f1] 'describe-mode) - (define-key map [help] 'describe-mode) + (define-key map "p" #'sc-eref-prev) + (define-key map "n" #'sc-eref-next) + (define-key map "s" #'sc-eref-setn) + (define-key map "j" #'sc-eref-jump) + (define-key map "x" #'sc-eref-abort) + (define-key map "q" #'sc-eref-abort) + (define-key map "\r" #'sc-eref-exit) + (define-key map "\n" #'sc-eref-exit) + (define-key map "g" #'sc-eref-goto) + (define-key map "?" #'describe-mode) + (define-key map "\C-h" #'describe-mode) + (define-key map [f1] #'describe-mode) + (define-key map [help] #'describe-mode) map) "Keymap for `sc-electric-mode' electric references mode.") (defvar sc-minibuffer-local-completion-map (let ((map (copy-keymap minibuffer-local-completion-map))) - (define-key map "\C-t" 'sc-toggle-fn) - (define-key map " " 'self-insert-command) + (define-key map "\C-t" #'sc-toggle-fn) + (define-key map " " #'self-insert-command) map) "Keymap for minibuffer confirmation of attribution strings.") (defvar sc-minibuffer-local-map (let ((map (copy-keymap minibuffer-local-map))) - (define-key map "\C-t" 'sc-toggle-fn) + (define-key map "\C-t" #'sc-toggle-fn) map) "Keymap for minibuffer confirmation of attribution strings.") @@ -1109,6 +1109,8 @@ Only used during confirmation." (setq sc-attrib-or-cite (not sc-attrib-or-cite)) (throw 'sc-reconfirm t)) +(defvar completer-disable) ;; From some `completer.el' package. + (defun sc-select-attribution () "Select an attribution from `sc-attributions'. @@ -1150,7 +1152,7 @@ to the auto-selected attribution string." (setq attribution attrib attriblist nil)) ((listp attrib) - (setq attribution (eval attrib)) + (setq attribution (eval attrib t)) (if (stringp attribution) (setq attriblist nil) (setq attribution nil @@ -1593,7 +1595,7 @@ error occurs." (let ((ref (nth sc-eref-style sc-rewrite-header-list))) (condition-case err (progn - (eval ref) + (eval ref t) (let ((lines (count-lines (point-min) (point-max)))) (or nomsg (message "Ref header %d [%d line%s]: %s" sc-eref-style lines @@ -1767,8 +1769,7 @@ querying you by typing `C-h'. Note that the format is changed slightly from that used by `set-variable' -- the current value is printed just after the variable's name instead of at the bottom of the help window." - (let* ((minibuffer-help-form '(funcall myhelp)) - (myhelp + (let* ((myhelp (lambda () (with-output-to-temp-buffer "*Help*" (prin1 var) @@ -1784,7 +1785,8 @@ help window." 1)) (with-current-buffer standard-output (help-mode)) - nil)))) + nil))) + (minibuffer-help-form `(funcall #',myhelp))) (set var (eval-minibuffer (format "Set %s to value: " var))))) (defmacro sc-toggle-symbol (rootname) diff --git a/lisp/mail/uce.el b/lisp/mail/uce.el index a573c8a267..9ebffef2e5 100644 --- a/lisp/mail/uce.el +++ b/lisp/mail/uce.el @@ -1,4 +1,4 @@ -;;; uce.el --- facilitate reply to unsolicited commercial email +;;; uce.el --- facilitate reply to unsolicited commercial email -*- lexical-binding: t; -*- ;; Copyright (C) 1996, 1998, 2000-2021 Free Software Foundation, Inc. @@ -127,14 +127,12 @@ "A symbol indicating which mail reader you are using. Choose from: `gnus', `rmail'." :type '(choice (const gnus) (const rmail)) - :version "20.3" - :group 'uce) + :version "20.3") (defcustom uce-setup-hook nil "Hook to run after UCE rant message is composed. This hook is run after `mail-setup-hook', which is run as well." - :type 'hook - :group 'uce) + :type 'hook) (defcustom uce-message-text "Recently, I have received an Unsolicited Commercial E-mail from you. @@ -180,36 +178,31 @@ on beginning of some line from the spamming list. So, when you set it up, it might be a good idea to actually use this feature. Value nil means insert no text by default, lets you type it in." - :type '(choice (const nil) string) - :group 'uce) + :type '(choice (const nil) string)) (defcustom uce-uce-separator "----- original unsolicited commercial email follows -----" "Line that will begin quoting of the UCE. Value nil means use no separator." - :type '(choice (const nil) string) - :group 'uce) + :type '(choice (const nil) string)) (defcustom uce-signature mail-signature "Text to put as your signature after the note to UCE sender. Value nil means none, t means insert `~/.signature' file (if it happens to exist), if this variable is a string this string will be inserted as your signature." - :type '(choice (const nil) (const t) string) - :group 'uce) + :type '(choice (const nil) (const t) string)) (defcustom uce-default-headers "Errors-To: nobody@localhost\nPrecedence: bulk\n" "Additional headers to use when responding to a UCE with \\[uce-reply-to-uce]. These are mostly meant for headers that prevent delivery errors reporting." - :type '(choice (const nil) string) - :group 'uce) + :type '(choice (const nil) string)) (defcustom uce-subject-line "Spam alert: unsolicited commercial e-mail" "Subject of the message that will be sent in response to a UCE." - :type 'string - :group 'uce) + :type 'string) ;; End of user options. @@ -221,7 +214,7 @@ These are mostly meant for headers that prevent delivery errors reporting." (declare-function rmail-toggle-header "rmail" (&optional arg)) ;;;###autoload -(defun uce-reply-to-uce (&optional ignored) +(defun uce-reply-to-uce (&optional _ignored) "Compose a reply to unsolicited commercial email (UCE). Sets up a reply buffer addressed to: the sender, his postmaster, his abuse@ address, and the postmaster of the mail relay used. @@ -367,7 +360,7 @@ You might need to set `uce-mail-reader' before using this." ;; functions in mail-mode, etc. (run-hooks 'mail-setup-hook 'uce-setup-hook)))) -(defun uce-insert-ranting (&optional ignored) +(defun uce-insert-ranting (&optional _ignored) "Insert text of the usual reply to UCE into current buffer." (interactive "P") (insert uce-message-text)) diff --git a/lisp/mail/unrmail.el b/lisp/mail/unrmail.el index 34de416c95..5b1abd54c6 100644 --- a/lisp/mail/unrmail.el +++ b/lisp/mail/unrmail.el @@ -1,4 +1,4 @@ -;;; unrmail.el --- convert Rmail Babyl files to mbox files +;;; unrmail.el --- convert Rmail Babyl files to mbox files -*- lexical-binding: t; -*- ;; Copyright (C) 1992, 2001-2021 Free Software Foundation, Inc. @@ -235,7 +235,7 @@ The variable `unrmail-mbox-format' controls which mbox format to use." ;; Insert the `From ' line. (insert mail-from) ;; Record the keywords and attributes in our special way. - (insert "X-RMAIL-ATTRIBUTES: " (apply 'string attrs) "\n") + (insert "X-RMAIL-ATTRIBUTES: " (apply #'string attrs) "\n") (when keywords (insert "X-RMAIL-KEYWORDS: " keywords "\n")) ;; Convert From to >From, etc. commit b90c658492a2548f183bf072be50f4a57a2b5f0b Author: Juri Linkov Date: Thu Mar 11 21:08:09 2021 +0200 Update docstrings of 'delete'/'remove' to interlink each other (bug#47054) * lisp/subr.el (remove): Add xref to 'delete'. * src/fns.c (Fdelete): Add xref to 'remove'. diff --git a/lisp/subr.el b/lisp/subr.el index 77bc7a33b3..ef0e5e6f78 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -887,7 +887,9 @@ Example: (defun remove (elt seq) "Return a copy of SEQ with all occurrences of ELT removed. -SEQ must be a list, vector, or string. The comparison is done with `equal'." +SEQ must be a list, vector, or string. The comparison is done with `equal'. +Contrary to `delete', this does not use side-effects, and the argument +SEQ is not modified." (declare (side-effect-free t)) (if (nlistp seq) ;; If SEQ isn't a list, there's no need to copy SEQ because diff --git a/src/fns.c b/src/fns.c index b193ad648a..766e767e12 100644 --- a/src/fns.c +++ b/src/fns.c @@ -1867,7 +1867,8 @@ If SEQ is not a list, deletion is never performed destructively; instead this function creates and returns a new vector or string. Write `(setq foo (delete element foo))' to be sure of correctly -changing the value of a sequence `foo'. */) +changing the value of a sequence `foo'. See also `remove', which +does not modify the argument. */) (Lisp_Object elt, Lisp_Object seq) { if (VECTORP (seq)) commit 8ad221cdf4337a3c4e2d270e09973b4e67a4b4a2 Author: Juri Linkov Date: Thu Mar 11 21:05:12 2021 +0200 * lisp/tab-bar.el (tab-bar--current-tab-find): New function. (tab-bar-close-other-tabs, tab-bar-close-group-tabs): Use it. (tab-bar--history-pre-change): Rename from 'tab-bar-history--pre-change' to follow naming convention. (tab-bar-history-mode): Use renamed 'tab-bar--history-pre-change'. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 66f8ccae47..29465aae63 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -681,6 +681,10 @@ on the tab bar instead." (explicit-name . ,tab-explicit-name) ,@(if tab-group `((group . ,tab-group)))))) +(defun tab-bar--current-tab-find (&optional tabs frame) + (seq-find (lambda (tab) (eq (car tab) 'current-tab)) + (or tabs (funcall tab-bar-tabs-function frame)))) + (defun tab-bar--current-tab-index (&optional tabs frame) (seq-position (or tabs (funcall tab-bar-tabs-function frame)) 'current-tab (lambda (a b) (eq (car a) b)))) @@ -1148,8 +1152,7 @@ for the last tab on a frame is determined by "Close all tabs on the selected frame, except the selected one." (interactive) (let* ((tabs (funcall tab-bar-tabs-function)) - (current-index (tab-bar--current-tab-index tabs)) - (current-tab (and current-index (nth current-index tabs))) + (current-tab (tab-bar--current-tab-find tabs)) (index 0)) (when current-tab (dolist (tab tabs) @@ -1284,8 +1287,7 @@ If GROUP-NAME is the empty string, then remove the tab from any group." "Close all tabs that belong to GROUP-NAME on the selected frame." (interactive (let* ((tabs (funcall tab-bar-tabs-function)) - (tab-index (1+ (tab-bar--current-tab-index tabs))) - (group-name (alist-get 'group (nth (1- tab-index) tabs)))) + (group-name (alist-get 'group (tab-bar--current-tab-find tabs)))) (list (completing-read "Close all tabs with group name: " (delete-dups (delq nil (cons group-name @@ -1300,8 +1302,7 @@ If GROUP-NAME is the empty string, then remove the tab from any group." (tab-bar-close-other-tabs) (let* ((tabs (funcall tab-bar-tabs-function)) - (current-index (tab-bar--current-tab-index tabs)) - (current-tab (and current-index (nth current-index tabs)))) + (current-tab (tab-bar--current-tab-find tabs))) (when (and current-tab (equal (alist-get 'group current-tab) close-group)) (tab-bar-close-tab))))) @@ -1327,7 +1328,7 @@ If GROUP-NAME is the empty string, then remove the tab from any group." (defvar tab-bar-history-old-minibuffer-depth 0 "Minibuffer depth before the current command.") -(defun tab-bar-history--pre-change () +(defun tab-bar--history-pre-change () (setq tab-bar-history-old-minibuffer-depth (minibuffer-depth)) ;; Store wc before possibly entering the minibuffer (when (zerop tab-bar-history-old-minibuffer-depth) @@ -1410,9 +1411,9 @@ and can restore them." :ascent center)) tab-bar-forward-button)) - (add-hook 'pre-command-hook 'tab-bar-history--pre-change) + (add-hook 'pre-command-hook 'tab-bar--history-pre-change) (add-hook 'window-configuration-change-hook 'tab-bar--history-change)) - (remove-hook 'pre-command-hook 'tab-bar-history--pre-change) + (remove-hook 'pre-command-hook 'tab-bar--history-pre-change) (remove-hook 'window-configuration-change-hook 'tab-bar--history-change))) commit b8bf62b60a63e4af4be0cfdd7b4e0d4b424af45c Author: Paul Eggert Date: Thu Mar 11 10:35:04 2021 -0800 On MS-Windows, fflush stderr after newline Problem reported by Ioannis Kappas (Bug#46388). * src/sysdep.c (errputc) [WINDOWSNT]: Flush stderr after newline. diff --git a/src/sysdep.c b/src/sysdep.c index 24d8832b2f..d940acc4e0 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -2670,6 +2670,13 @@ void errputc (int c) { fputc_unlocked (c, errstream ()); + +#ifdef WINDOWSNT + /* Flush stderr after outputting a newline since stderr is fully + buffered when redirected to a pipe, contrary to POSIX. */ + if (c == '\n') + fflush_unlocked (stderr); +#endif } void commit 1d4195856b2e8c45cb678821fca35e94c8eb2bf9 Author: Stefan Monnier Date: Thu Mar 11 13:30:15 2021 -0500 * lisp/outline.el (outline-font-lock-keywords): Simplify The `laxmatch` part of `font-lock-keywords` is just a boolean. diff --git a/lisp/outline.el b/lisp/outline.el index a859f9ac8f..b4d37b2207 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -210,10 +210,7 @@ in the file it applies to.") (when (and outline-minor-mode (eq outline-minor-mode-highlight 'override)) 'append) - (if (and outline-minor-mode - (eq outline-minor-mode-highlight t)) - 'append - t)))) + t))) "Additional expressions to highlight in Outline mode.") (defface outline-1 commit b21f6193fe1b92382bf7efbd9d44eba0613f3168 Author: Stefan Monnier Date: Thu Mar 11 13:29:14 2021 -0500 * lisp: Remove yet more always-nil variables * lisp/align.el (align-region): Remove always-nil variable `group-c`. * lisp/ido.el (ido-make-prompt): Remove always-nil variable `prefix`. * lisp/xdg.el (xdg-mime-collect-associations): Remove always-nil variable `end`. * lisp/calc/calc-yank.el (calc-edit): Remove always-nil variable `flag`. * lisp/calendar/todo-mode.el (todo-edit-item--header): Remove always-nil variable `dayname`. (todo-show-categories-table): Remove always-nil variable `sortkey`. * lisp/emacs-lisp/checkdoc.el (checkdoc-ispell-docstring-engine): Remove always-nil variable `err`. * lisp/emacs-lisp/tcover-ses.el: Remove always-nil variable `pause`. * lisp/eshell/em-ls.el (eshell-ls-files): Remove always-nil variable `ignore`. * lisp/net/ange-ftp.el (ange-ftp-copy-file-internal): Remove always-nil variable `temp2`. * lisp/progmodes/cperl-mode.el (cperl-tags-hier-init): Remove always-nil variables `l1`, `l2`, `l3`. (cperl-tags-treeify): Remove always-nil variable `l1`. * lisp/progmodes/ebrowse.el (ebrowse-tags-read-member+class-name): Remove always-nil variable `class`. * lisp/textmodes/artist.el (artist-draw-ellipse-with-0-height): Remove always-nil variable `fill-info`. * lisp/textmodes/flyspell.el (flyspell-emacs-popup): Remove always-nil variable `show-affix-info`. * lisp/textmodes/rst.el (rst-Ado): Remove always-nil variable `char`. * lisp/vc/vc.el (vc-diff-build-argument-list-internal): Remove always-nil variable `rev2-default`. diff --git a/lisp/align.el b/lisp/align.el index 1a1d3dd7ec..7ae067f8c5 100644 --- a/lisp/align.el +++ b/lisp/align.el @@ -1310,7 +1310,7 @@ aligner would have dealt with are." (thissep (if rulesep (cdr rulesep) separate)) same (eol 0) search-start - groups group-c + groups ;; group-c spacing spacing-c tab-stop tab-stop-c repeat repeat-c @@ -1434,7 +1434,7 @@ aligner would have dealt with are." ;; lookup the `group' attribute the first time ;; that we need it - (unless group-c + (unless nil ;; group-c (setq groups (or (cdr (assq 'group rule)) 1)) (unless (listp groups) (setq groups (list groups))) diff --git a/lisp/calc/calc-yank.el b/lisp/calc/calc-yank.el index e5f05236f3..762adbd407 100644 --- a/lisp/calc/calc-yank.el +++ b/lisp/calc/calc-yank.el @@ -639,7 +639,7 @@ Interactively, reads the register using `register-read-with-preview'." (calc-slow-wrapper (when (eq n 0) (setq n (calc-stack-size))) - (let* ((flag nil) + (let* (;; (flag nil) (allow-ret (> n 1)) (list (math-showing-full-precision (mapcar (if (> n 1) @@ -651,7 +651,8 @@ Interactively, reads the register using `register-read-with-preview'." (if (> n 0) (calc-top-list n) (calc-top-list 1 (- n))))))) - (calc--edit-mode (lambda () (calc-finish-stack-edit (or flag n))) allow-ret) + (calc--edit-mode (lambda () (calc-finish-stack-edit n)) ;; (or flag n) + allow-ret) (while list (insert (car list) "\n") (setq list (cdr list))))) diff --git a/lisp/calendar/todo-mode.el b/lisp/calendar/todo-mode.el index 0daa153010..dab468d0c1 100644 --- a/lisp/calendar/todo-mode.el +++ b/lisp/calendar/todo-mode.el @@ -2279,7 +2279,7 @@ made in the number or names of categories." (inc (prefix-numeric-value inc)) (buffer-read-only nil) ndate ntime - year monthname month day dayname) + year monthname month day) ;; dayname (when marked (todo--user-error-if-marked-done-item)) (save-excursion (or (and marked (goto-char (point-min))) (todo-item-start)) @@ -2437,7 +2437,7 @@ made in the number or names of categories." (monthname monthname) (month month) (day day) - (dayname dayname)) + (dayname nil)) ;; dayname (mapconcat #'eval calendar-date-display-form ""))))) (when ndate (replace-match ndate nil nil nil 1)) ;; Add new time string to the header, if it was supplied. @@ -3450,8 +3450,8 @@ containing only archived items, provided user option are shown in `todo-archived-only' face." (interactive) (todo-display-categories) - (let (sortkey) - (todo-update-categories-display sortkey))) + ;; (let (sortkey) + (todo-update-categories-display nil)) ;; sortkey (defun todo-next-button (n) "Move point to the Nth next button in the table of categories." diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index ee2e77480d..62851660c6 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -2134,8 +2134,8 @@ buffer, otherwise stop after the first error." (user-error "No spellchecker installed: check the variable `ispell-program-name'")) (save-excursion (skip-chars-forward "^a-zA-Z") - (let (word sym case-fold-search err word-beginning word-end) - (while (and (not err) (< (point) end)) + (let (word sym case-fold-search word-beginning word-end) ;; err + (while (and (< (point) end)) ;; (not err) (if (save-excursion (forward-char -1) (looking-at "[('`]")) ;; Skip lists describing meta-syntax, or bound variables (forward-sexp 1) @@ -2167,7 +2167,7 @@ buffer, otherwise stop after the first error." (sit-for 0) (message "Continuing...")))))))) (skip-chars-forward "^a-zA-Z")) - err)))) + nil)))) ;; err ;;; Rogue space checking engine ;; diff --git a/lisp/emacs-lisp/tcover-ses.el b/lisp/emacs-lisp/tcover-ses.el index 12b0dcfff9..d9db1d3cdc 100644 --- a/lisp/emacs-lisp/tcover-ses.el +++ b/lisp/emacs-lisp/tcover-ses.el @@ -32,8 +32,8 @@ ;;;Here are some macros that exercise SES. Set `pause' to t if you want the ;;;macros to pause after each step. -(let* ((pause nil) - (x (if pause "\^Xq" "")) +(let* (;; (pause nil) + (x (if nil "\^Xq" "")) ;; pause (y "\^X\^Fses-test.ses\r\^[<")) ;;Fiddle with the existing spreadsheet (fset 'ses-exercise-example diff --git a/lisp/eshell/em-ls.el b/lisp/eshell/em-ls.el index e942ae2692..3d7c43b404 100644 --- a/lisp/eshell/em-ls.el +++ b/lisp/eshell/em-ls.el @@ -680,12 +680,12 @@ Each member of FILES is either a string or a cons cell of the form (let ((f files) last-f display-files - ignore) + ) ;; ignore (while f (if (cdar f) (setq last-f f f (cdr f)) - (unless ignore + (unless nil ;; ignore (funcall error-func (format "%s: No such file or directory\n" (caar f)))) (if (eq f files) @@ -698,7 +698,7 @@ Each member of FILES is either a string or a cons cell of the form (setcar f (cadr f)) (setcdr f (cddr f)))))) (if (not show-size) - (setq display-files (mapcar 'eshell-ls-annotate files)) + (setq display-files (mapcar #'eshell-ls-annotate files)) (dolist (file files) (let* ((str (eshell-ls-printable-size (file-attribute-size (cdr file)) t)) (len (length str))) diff --git a/lisp/ido.el b/lisp/ido.el index 3ed0d952f3..9362904680 100644 --- a/lisp/ido.el +++ b/lisp/ido.el @@ -1746,7 +1746,7 @@ is enabled then some keybindings are changed in the keymap." ido-max-file-prompt-width)) (literal (and (boundp 'ido-find-literal) ido-find-literal "(literal) ")) (vc-off (and ido-saved-vc-hb (not vc-handled-backends) "[-VC] ")) - (prefix nil) + ;; (prefix nil) (rule ido-rewrite-file-prompt-rules)) (let ((case-fold-search nil)) (while rule @@ -1762,7 +1762,7 @@ is enabled then some keybindings are changed in the keymap." ; (if ido-process-ignore-lists "" "&") (or literal "") (or vc-off "") - (or prefix "") + ;; (or prefix "") (let ((l (length dirname))) (if (and max-width (> max-width 0) (> l max-width)) (let* ((s (substring dirname (- max-width))) diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el index d27eeab82b..86b5d44987 100644 --- a/lisp/net/ange-ftp.el +++ b/lisp/net/ange-ftp.el @@ -3716,7 +3716,7 @@ so return the size on the remote host exactly. See RFC 3659." (binary (or (ange-ftp-binary-file filename) (ange-ftp-binary-file newname))) temp1 - temp2) + ) ;; temp2 ;; check to see if we can overwrite (if (or (not ok-if-already-exists) @@ -3750,7 +3750,7 @@ so return the size on the remote host exactly. See RFC 3659." filename newname binary msg f-parsed f-host f-user f-name f-abbr t-parsed t-host t-user t-name t-abbr - temp1 temp2 cont nowait) + temp1 nil cont nowait) ;; temp2 nowait)) ;; filename wasn't remote. newname must be remote. call the diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index 649eff19cf..734797b3ad 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -6701,9 +6701,9 @@ One may build such TAGS files from CPerl mode menu." (or (nthcdr 2 elt) ;; Only in one file (setcdr elt (cdr (nth 1 elt)))))) - to l1 l2 l3) + to) ;; l1 l2 l3 ;; (setq cperl-hierarchy '(() () ())) ; Would write into '() later! - (setq cperl-hierarchy (list l1 l2 l3)) + (setq cperl-hierarchy (list () () ())) ;; (list l1 l2 l3) (or tags-table-list (call-interactively 'visit-tags-table)) (mapc @@ -6749,7 +6749,7 @@ One may build such TAGS files from CPerl mode menu." "\\)\\(::\\)?")) (packages (cdr (nth 1 to))) (methods (cdr (nth 2 to))) - l1 head cons1 cons2 ord writeto recurse + head cons1 cons2 ord writeto recurse ;; l1 root-packages root-functions (move-deeper (lambda (elt) @@ -6769,7 +6769,7 @@ One may build such TAGS files from CPerl mode menu." (setq root-functions (cons elt root-functions))) (t (setq root-packages (cons elt root-packages))))))) - (setcdr to l1) ; Init to dynamic space + (setcdr to nil) ;; l1 ; Init to dynamic space (setq writeto to) (setq ord 1) (mapc move-deeper packages) diff --git a/lisp/progmodes/ebrowse.el b/lisp/progmodes/ebrowse.el index 40bdaad574..cafdb3b828 100644 --- a/lisp/progmodes/ebrowse.el +++ b/lisp/progmodes/ebrowse.el @@ -3184,8 +3184,8 @@ MEMBER-NAME is the name of the member found." (let* ((start (point)) (name (progn (skip-chars-forward "a-zA-Z0-9_") (buffer-substring start (point)))) - class) - (list class name)))) + ) ;; class + (list nil name)))) ;; class (defun ebrowse-tags-choose-class (_tree header name initial-class-name) diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el index 9a886d2397..3d08122091 100644 --- a/lisp/textmodes/artist.el +++ b/lisp/textmodes/artist.el @@ -3466,7 +3466,7 @@ The Y-RADIUS must be 0, but the X-RADIUS must not be 0." (line-char (if artist-line-char-set artist-line-char ?-)) (i 0) (point-list nil) - (fill-info nil) + ;; (fill-info nil) (shape-info (make-vector 2 0))) (while (< i width) (let* ((line-x (+ left-edge i)) @@ -3479,7 +3479,7 @@ The Y-RADIUS must be 0, but the X-RADIUS must not be 0." (setq point-list (append point-list (list new-coord))) (setq i (1+ i)))) (aset shape-info 0 point-list) - (aset shape-info 1 fill-info) + (aset shape-info 1 nil) ;; fill-info (artist-make-2point-object (artist-make-endpoint x1 y1) (artist-make-endpoint x-radius y-radius) shape-info))) diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el index 83dba7177a..a48b3457aa 100644 --- a/lisp/textmodes/flyspell.el +++ b/lisp/textmodes/flyspell.el @@ -2293,8 +2293,8 @@ If OPOINT is non-nil, restore point there after adjusting it for replacement." corrects) '())) (affix (car (cdr (cdr (cdr poss))))) - show-affix-info - (base-menu (let ((save (if (and (consp affix) show-affix-info) + ;; show-affix-info + (base-menu (let ((save (if nil ;; (and (consp affix) show-affix-info) (list (list (concat "Save affix: " (car affix)) 'save) diff --git a/lisp/textmodes/rst.el b/lisp/textmodes/rst.el index c51285d3de..ce156370d5 100644 --- a/lisp/textmodes/rst.el +++ b/lisp/textmodes/rst.el @@ -616,7 +616,7 @@ After interpretation of ARGS the results are concatenated as for (:constructor rst-Ado-new-transition (&aux - (char nil) + ;; (char nil) (-style 'transition))) ;; Construct a simple section header. (:constructor diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index b926c3819d..95126fac10 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -1832,7 +1832,7 @@ Return t if the buffer had changes, nil otherwise." (backend (car vc-fileset)) (first (car files)) (rev1-default nil) - (rev2-default nil)) + ) ;; (rev2-default nil) (cond ;; someday we may be able to do revision completion on non-singleton ;; filesets, but not yet. @@ -1856,9 +1856,10 @@ Return t if the buffer had changes, nil otherwise." rev1-default "): ") "Older revision: ")) (rev2-prompt (concat "Newer revision (default " - (or rev2-default "current source") "): ")) + ;; (or rev2-default + "current source): ")) (rev1 (vc-read-revision rev1-prompt files backend rev1-default)) - (rev2 (vc-read-revision rev2-prompt files backend rev2-default))) + (rev2 (vc-read-revision rev2-prompt files backend nil))) ;; rev2-default (when (string= rev1 "") (setq rev1 nil)) (when (string= rev2 "") (setq rev2 nil)) (list files rev1 rev2)))) diff --git a/lisp/xdg.el b/lisp/xdg.el index 0f0df53d27..11039499ea 100644 --- a/lisp/xdg.el +++ b/lisp/xdg.el @@ -256,8 +256,8 @@ which is expected to be ordered by priority as in (when (file-readable-p f) (insert-file-contents-literally f nil nil nil t) (goto-char (point-min)) - (let (end) - (while (not (or (eobp) end)) + (let () ;; end + (while (not (or (eobp))) ;; end (if (= (following-char) ?\[) (progn (setq sec (char-after (1+ (point)))) (forward-line)) commit fe844299a4432ef2443ac89b63df985fc58b2752 Author: Stefan Monnier Date: Thu Mar 11 13:21:22 2021 -0500 * lisp/cedet: Remove always-nil variables * lisp/cedet/ede/pmake.el (ede-proj-makefile-insert-variables): Remove always-nil variable `conf-done`. * lisp/cedet/ede/project-am.el: Use ref instead of dynbound var. (project-rescan): Pass the ref. (project-am-expand-subdirlist): Use it. * lisp/cedet/semantic/idle.el (semantic-idle-work-core-handler): Fix misuse of the wrong `errbuf `variable. * lisp/cedet/semantic/scope.el (semantic-analyze-scoped-type-parts): Remove always-nil variable `extmeth`. * lisp/cedet/semantic/wisent/comp.el (wisent-context-name) (wisent-context-bindings): Make them into functions. (wisent-with-context): Use `dlet`. diff --git a/lisp/cedet/ede/pmake.el b/lisp/cedet/ede/pmake.el index e1fe85659f..47bb0c61eb 100644 --- a/lisp/cedet/ede/pmake.el +++ b/lisp/cedet/ede/pmake.el @@ -428,11 +428,11 @@ sources variable." (let* ((proj (ede-target-parent this)) (conf-table (ede-proj-makefile-configuration-variables this (oref proj configuration-default))) - (conf-done nil) + ;; (conf-done nil) ) ;; Add in all variables from the configuration not already covered. (mapc (lambda (c) - (if (member (car c) conf-done) + (if nil ;; (member (car c) conf-done) nil (insert (car c) "=" (cdr c) "\n"))) conf-table)) diff --git a/lisp/cedet/ede/project-am.el b/lisp/cedet/ede/project-am.el index d676c5749c..258917f01b 100644 --- a/lisp/cedet/ede/project-am.el +++ b/lisp/cedet/ede/project-am.el @@ -596,10 +596,8 @@ Strip out duplicates, and recurse on variables." (project-am-expand-subdirlist place (makefile-macro-file-list var)) ;; Else, add SP in if it isn't a dup. - (if (member sp (symbol-value place)) - nil ; don't do it twice. - (set place (cons sp (symbol-value place))) ;; add - )))) + (cl-pushnew sp (gv-deref place) :test #'equal) ;; add + ))) subdirs) ) @@ -645,7 +643,7 @@ Strip out duplicates, and recurse on variables." ;; We still have a list of targets. For all buffers, make sure ;; their object still exists! ;; FIGURE THIS OUT - (project-am-expand-subdirlist 'csubprojexpanded csubproj) + (project-am-expand-subdirlist (gv-ref csubprojexpanded) csubproj) ;; Ok, now let's look at all our sub-projects. (mapc (lambda (sp) (let* ((subdir (file-name-as-directory diff --git a/lisp/cedet/semantic/idle.el b/lisp/cedet/semantic/idle.el index 2b6d11f458..9df9778043 100644 --- a/lisp/cedet/semantic/idle.el +++ b/lisp/cedet/semantic/idle.el @@ -348,54 +348,56 @@ Returns t if all processing succeeded." Visits Semantic controlled buffers, and makes sure all needed include files have been parsed, and that the typecache is up to date. Uses `semantic-idle-work-for-on-buffer' to do the work." - (let ((errbuf nil) - (interrupted - (semantic-exit-on-input 'idle-work-timer - (let* ((inhibit-quit nil) - (cb (current-buffer)) - (buffers (delq (current-buffer) - (delq nil - (mapcar #'(lambda (b) - (and (buffer-file-name b) - b)) - (buffer-list))))) - safe errbuf) - ;; First, handle long tasks in the current buffer. - (when (semantic-idle-scheduler-enabled-p) - (save-excursion - (setq safe (semantic-idle-work-for-one-buffer (current-buffer)) - ))) - (when (not safe) (push (current-buffer) errbuf)) - - ;; Now loop over other buffers with same major mode, trying to - ;; update them as well. Stop on keypress. - (dolist (b buffers) - (semantic-throw-on-input 'parsing-mode-buffers) - (with-current-buffer b - (when (semantic-idle-scheduler-enabled-p) - (and (semantic-idle-scheduler-enabled-p) - (unless (semantic-idle-work-for-one-buffer (current-buffer)) - (push (current-buffer) errbuf))) - )) - ) - - (when (and (featurep 'semantic/db) (semanticdb-minor-mode-p)) - ;; Save everything. - (semanticdb-save-all-db-idle) - - ;; Parse up files near our active buffer - (when semantic-idle-work-parse-neighboring-files-flag - (semantic-safe "Idle Work Parse Neighboring Files: %S" - (set-buffer cb) - (semantic-idle-scheduler-work-parse-neighboring-files)) - t) + (let* + ((errbuf nil) + (interrupted + (semantic-exit-on-input 'idle-work-timer + (let* ((inhibit-quit nil) + (cb (current-buffer)) + (buffers (delq (current-buffer) + (delq nil + (mapcar #'(lambda (b) + (and (buffer-file-name b) + b)) + (buffer-list))))) + safe) ;; errbuf + ;; First, handle long tasks in the current buffer. + (when (semantic-idle-scheduler-enabled-p) + (save-excursion + (setq safe (semantic-idle-work-for-one-buffer (current-buffer)) + ))) + (when (not safe) (push (current-buffer) errbuf)) + + ;; Now loop over other buffers with same major mode, trying to + ;; update them as well. Stop on keypress. + (dolist (b buffers) + (semantic-throw-on-input 'parsing-mode-buffers) + (with-current-buffer b + (when (semantic-idle-scheduler-enabled-p) + (and (semantic-idle-scheduler-enabled-p) + (unless (semantic-idle-work-for-one-buffer + (current-buffer)) + (push (current-buffer) errbuf))) + )) + ) - ;; Save everything... again - (semanticdb-save-all-db-idle) - ) + (when (and (featurep 'semantic/db) (semanticdb-minor-mode-p)) + ;; Save everything. + (semanticdb-save-all-db-idle) + + ;; Parse up files near our active buffer + (when semantic-idle-work-parse-neighboring-files-flag + (semantic-safe "Idle Work Parse Neighboring Files: %S" + (set-buffer cb) + (semantic-idle-scheduler-work-parse-neighboring-files)) + t) + + ;; Save everything... again + (semanticdb-save-all-db-idle) + ) - ;; Done w/ processing - nil)))) + ;; Done w/ processing + nil)))) ;; Done (if interrupted diff --git a/lisp/cedet/semantic/scope.el b/lisp/cedet/semantic/scope.el index 6bd04b2e34..2d806e58ee 100644 --- a/lisp/cedet/semantic/scope.el +++ b/lisp/cedet/semantic/scope.el @@ -562,7 +562,7 @@ such as `public' or `private'." ;; @TODO - is this line needed?? Try w/out for a while ;; @note - I think C++ says no. elisp might, but methods ;; look like defuns, so it makes no difference. - (extmeth nil) ; (semantic-tag-external-member-children type t)) + ;;(extmeth nil) ; (semantic-tag-external-member-children type t)) ;; INHERITED are tags found in classes that our TYPE tag ;; inherits from. Do not do this if it was not requested. @@ -584,7 +584,7 @@ such as `public' or `private'." (setq slots (nreverse copyslots)) )) ;; Flatten the database output. - (append slots extmeth inherited) + (append slots nil inherited) ;; extmeth ))) (defun semantic-analyze-scoped-inherited-tags (type scope access) diff --git a/lisp/cedet/semantic/wisent/comp.el b/lisp/cedet/semantic/wisent/comp.el index 574922049f..ae0823e669 100644 --- a/lisp/cedet/semantic/wisent/comp.el +++ b/lisp/cedet/semantic/wisent/comp.el @@ -54,15 +54,16 @@ ;; bound locally, without all these "reference to free variable" ;; compiler warnings! -(defmacro wisent-context-name (name) - "Return the context name from NAME." - `(if (and ,name (symbolp ,name)) - (intern (format "wisent-context-%s" ,name)) - (error "Invalid context name: %S" ,name))) +(eval-when-compile + (defun wisent-context-name (name) + "Return the context name from NAME." + (if (and name (symbolp name)) + (intern (format "wisent-context-%s" name)) + (error "Invalid context name: %S" name))) -(defmacro wisent-context-bindings (name) - "Return the variables in context NAME." - `(symbol-value (wisent-context-name ,name))) + (defun wisent-context-bindings (name) + "Return the variables in context NAME." + (symbol-value (wisent-context-name name)))) (defmacro wisent-defcontext (name &rest vars) "Define a context NAME that will bind variables VARS." @@ -71,18 +72,14 @@ (declarations (mapcar #'(lambda (v) (list 'defvar v)) vars))) `(progn ,@declarations - (eval-and-compile + (eval-when-compile (defvar ,context ',vars))))) (defmacro wisent-with-context (name &rest body) "Bind variables in context NAME then eval BODY." (declare (indent 1)) - (let ((bindings (wisent-context-bindings name))) - `(progn - ,@(mapcar (lambda (binding) `(defvar ,(or (car-safe binding) binding))) - bindings) - (let* ,bindings - ,@body)))) + `(dlet ,(wisent-context-bindings name) + ,@body)) ;; Other utilities commit 2c9594ae0626abe3838b8f0ec33122c94e02ddf1 Author: Stefan Monnier Date: Thu Mar 11 13:15:32 2021 -0500 * lisp/emulation/edt.el (edt-with-position): Don't bind `left` (edt-find-forward, edt-find-next-forward, edt-sentence-forward) (edt-paragraph-forward): Adjust accordingly. diff --git a/lisp/emulation/edt.el b/lisp/emulation/edt.el index b8dea2f2cc..8f90ed2826 100644 --- a/lisp/emulation/edt.el +++ b/lisp/emulation/edt.el @@ -635,8 +635,7 @@ Argument NUM is the number of lines to move." (defmacro edt-with-position (&rest body) "Execute BODY with some position-related variables bound." - `(let* ((left nil) - (beg (edt-current-line)) + `(let* ((beg (edt-current-line)) (height (window-height)) (top-percent (if (zerop edt-top-scroll-margin) 10 edt-top-scroll-margin)) @@ -650,7 +649,7 @@ Argument NUM is the number of lines to move." (far (save-excursion (goto-char bottom) (point-at-bol (1- height))))) - (ignore top left far) + (ignore top far) ,@body)) ;;; @@ -668,9 +667,10 @@ Optional argument FIND is t is this function is called from `edt-find'." (search-backward edt-find-last-text) (edt-set-match) (if (> (point) far) - (if (zerop (setq left (save-excursion (forward-line height)))) - (recenter top-margin) - (recenter (- left bottom-up-margin))) + (let ((left (save-excursion (forward-line height)))) + (recenter (if (zerop left) + top-margin + (- left bottom-up-margin)))) (and (> (point) bottom) (recenter bottom-margin)))))) (defun edt-find-backward (&optional find) @@ -707,9 +707,9 @@ Optional argument FIND is t if this function is called from `edt-find'." (search-backward edt-find-last-text) (edt-set-match) (if (> (point) far) - (if (zerop (setq left (save-excursion (forward-line height)))) - (recenter top-margin) - (recenter (- left bottom-up-margin))) + (let ((left (save-excursion (forward-line height)))) + (recenter (if (zerop left) top-margin + (- left bottom-up-margin)))) (and (> (point) bottom) (recenter bottom-margin)))) (backward-char 1) (error "Search failed: \"%s\"" edt-find-last-text)))) @@ -1241,9 +1241,8 @@ Argument NUM is the positive number of sentences to move." (forward-word 1) (backward-sentence)) (if (> (point) far) - (if (zerop (setq left (save-excursion (forward-line height)))) - (recenter top-margin) - (recenter (- left bottom-up-margin))) + (let ((left (save-excursion (forward-line height)))) + (recenter (if (zerop left) top-margin (- left bottom-up-margin)))) (and (> (point) bottom) (recenter bottom-margin))))) (defun edt-sentence-backward (num) @@ -1282,9 +1281,8 @@ Argument NUM is the positive number of paragraphs to move." (forward-line 1)) (setq num (1- num))) (if (> (point) far) - (if (zerop (setq left (save-excursion (forward-line height)))) - (recenter top-margin) - (recenter (- left bottom-up-margin))) + (let ((left (save-excursion (forward-line height)))) + (recenter (if (zerop left) top-margin (- left bottom-up-margin)))) (and (> (point) bottom) (recenter bottom-margin))))) (defun edt-paragraph-backward (num) commit 6e77869750abdd2d4cb6e8b9f35cc5a82fbe25b1 Author: Stefan Monnier Date: Thu Mar 11 13:14:19 2021 -0500 * lisp/vc/pcvs-parse.el: Fix lexical-binding breakage (cvs-parse-table, cvs-parse-merge, cvs-parse-status, cvs-parse-commit): Declare vars set by `cvs-match` as dynamic. diff --git a/lisp/vc/pcvs-parse.el b/lisp/vc/pcvs-parse.el index d0b2e898b0..3a96c93054 100644 --- a/lisp/vc/pcvs-parse.el +++ b/lisp/vc/pcvs-parse.el @@ -197,6 +197,9 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'." (defun cvs-parse-table () "Table of message objects for `cvs-parse-process'." + (with-suppressed-warnings ((lexical c file dir path base-rev subtype)) + (defvar c) (defvar file) (defvar dir) (defvar path) (defvar base-rev) + (defvar subtype)) (let (c file dir path base-rev subtype) (cvs-or @@ -402,6 +405,8 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'." (defun cvs-parse-merge () + (with-suppressed-warnings ((lexical path base-rev head-rev type)) + (defvar path) (defvar base-rev) (defvar head-rev) (defvar type)) (let (path base-rev head-rev type) ;; A merge (maybe with a conflict). (and @@ -446,6 +451,9 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'." :merge (cons base-rev head-rev)))))) (defun cvs-parse-status () + (with-suppressed-warnings ((lexical nofile path base-rev head-rev type)) + (defvar nofile) (defvar path) (defvar base-rev) (defvar head-rev) + (defvar type)) (let (nofile path base-rev head-rev type) (and (cvs-match @@ -494,6 +502,8 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'." :head-rev head-rev)))) (defun cvs-parse-commit () + (with-suppressed-warnings ((lexical path file base-rev subtype)) + (defvar path) (defvar file) (defvar base-rev) (defvar subtype)) (let (path file base-rev subtype) (cvs-or commit a0d8fd279cbe155a76bdc79f607ba098d9b275b5 Author: Stefan Monnier Date: Thu Mar 11 13:11:40 2021 -0500 * lisp/ses.el (ses-set-cell): Use `macroexp-let2` (ses--\,@); Rename from `ses--metaprogramming`. diff --git a/lisp/ses.el b/lisp/ses.el index d6090f3e8d..a11c754abc 100644 --- a/lisp/ses.el +++ b/lisp/ses.el @@ -332,9 +332,9 @@ column or default printer and then modify its output.") next-line-add-newlines transient-mark-mode) "Buffer-local variables used by SES.")) -(defmacro ses--metaprogramming (exp) (declare (debug t)) (eval exp t)) -(ses--metaprogramming - `(progn ,@(mapcar (lambda (x) `(defvar ,(or (car-safe x) x))) ses-localvars))) +(defmacro ses--\,@ (exp) (declare (debug t)) (macroexp-progn (eval exp t))) +(ses--\,@ + (mapcar (lambda (x) `(defvar ,(or (car-safe x) x))) ses-localvars)) (defun ses-set-localvars () "Set buffer-local and initialize some SES variables." @@ -840,31 +840,31 @@ and ARGS and reset `ses-start-time' to the current time." "Install VAL as the contents for field FIELD (named by a quoted symbol) of cell (ROW,COL). This is undoable. The cell's data will be updated through `post-command-hook'." - `(let ((row ,row) - (col ,col) - (val ,val)) - (let* ((cell (ses-get-cell row col)) + (macroexp-let2 nil row row + (macroexp-let2 nil col col + (macroexp-let2 nil val val + `(let* ((cell (ses-get-cell ,row ,col)) (change ,(let ((field (progn (cl-assert (eq (car field) 'quote)) (cadr field)))) (if (eq field 'value) - '(ses-set-with-undo (ses-cell-symbol cell) val) + `(ses-set-with-undo (ses-cell-symbol cell) ,val) ;; (let* ((slots (get 'ses-cell 'cl-struct-slots)) ;; (slot (or (assq field slots) ;; (error "Unknown field %S" field))) ;; (idx (- (length slots) ;; (length (memq slot slots))))) - ;; `(ses-aset-with-undo cell ,idx val)) + ;; `(ses-aset-with-undo cell ,idx ,val)) (let ((getter (intern-soft (format "ses-cell--%s" field)))) `(ses-setter-with-undo (eval-when-compile (cons #',getter (lambda (newval cell) (setf (,getter cell) newval)))) - val cell)))))) + ,val cell)))))) (if change - (add-to-list 'ses--deferred-write (cons row col)))) - nil)) ; Make coverage-tester happy. + (add-to-list 'ses--deferred-write (cons ,row ,col))) + nil))))) ; Make coverage-tester happy. (defun ses-cell-set-formula (row col formula) "Store a new formula for (ROW . COL) and enqueue the cell for commit 5926f0c02402acb9de6c44f0b4155456aebdc981 Author: Stefan Monnier Date: Thu Mar 11 13:10:13 2021 -0500 * lisp/obsolete/iswitchb.el: Remove dead code (most-len, most-is-exact): Delete vars. (iswitchb-output-completion): Delete function. (iswitchb-completions): Delete dead code consequence of `most` being nil. diff --git a/lisp/obsolete/iswitchb.el b/lisp/obsolete/iswitchb.el index a7fd6ccb5f..a9bc6ef071 100644 --- a/lisp/obsolete/iswitchb.el +++ b/lisp/obsolete/iswitchb.el @@ -1158,18 +1158,6 @@ Copied from `icomplete-exhibit' with two changes: (insert (iswitchb-completions contents)))))) -(defvar most-len) -(defvar most-is-exact) - -(defun iswitchb-output-completion (com) - (if (= (length com) most-len) - ;; Most is one exact match, - ;; note that and leave out - ;; for later indication: - (ignore - (setq most-is-exact t)) - (substring com most-len))) - (defun iswitchb-completions (name) "Return the string that is displayed after the user's text. Modified from `icomplete-completions'." @@ -1260,16 +1248,11 @@ Modified from `icomplete-completions'." (nreverse res)) (list "...") (nthcdr (- (length comps) - (/ iswitchb-max-to-show 2)) comps)))) + (/ iswitchb-max-to-show 2)) + comps)))) (let* ( - ;;(most (try-completion name candidates predicate)) - (most nil) - (most-len (length most)) - most-is-exact (alternatives - (mapconcat (if most #'iswitchb-output-completion - #'identity) - comps iswitchb-delim))) + (mapconcat #'identity comps iswitchb-delim))) (concat @@ -1283,17 +1266,9 @@ Modified from `icomplete-completions'." close-bracket-determined)) ;; end of partial matches... - ;; think this bit can be ignored. - (and (> most-len (length name)) - (concat open-bracket-determined - (substring most (length name)) - close-bracket-determined)) - ;; list all alternatives open-bracket-prospects - (if most-is-exact - (concat iswitchb-delim alternatives) - alternatives) + alternatives close-bracket-prospects)))))) (defun iswitchb-minibuffer-setup () commit 7d0dc31833d471a6f86e947d3165d3fd1452a184 Author: Stefan Monnier Date: Thu Mar 11 13:07:37 2021 -0500 * lisp/org/: Delete some always-nil variables * lisp/org/ob-lilypond.el (org-babel-lilypond-compile-lilyfile): Remove always-nil variable `arg-2`. * lisp/org/ol-gnus.el (org-gnus-store-link): Remove always-nil variables `newsgroup` and `xarchive`. * lisp/org/ol.el (org-store-link): Remove always-nil variable `description`. * lisp/org/org-clock.el (org-clock-special-range): Remove always-nil variables `m1` and `m`. * lisp/org/org-crypt.el (org--matcher-tags-todo-only): Declare var. * lisp/org/org-protocol.el (org-protocol-open-source): Remove always-nil variable `result`. * lisp/org/ox-odt.el (org-odt-format-label): Remove always-nil variable `short-caption`. (org-odt-link--inline-formula): Remove always-nil variables `width` and `height`. * lisp/org/ox.el (org-export--missing-definitions): Remove always-nil variable `seen`. diff --git a/lisp/org/ob-lilypond.el b/lisp/org/ob-lilypond.el index fbdd905a5f..47397e6625 100644 --- a/lisp/org/ob-lilypond.el +++ b/lisp/org/ob-lilypond.el @@ -220,7 +220,7 @@ If error in compilation, attempt to mark the error in lilypond org file." FILE-NAME is full path to lilypond (.ly) file." (message "Compiling LilyPond...") (let ((arg-1 org-babel-lilypond-ly-command) ;program - (arg-2 nil) ;infile + ;; (arg-2 nil) ;infile (arg-3 "*lilypond*") ;buffer (arg-4 t) ;display (arg-5 (if org-babel-lilypond-gen-png "--png" "")) ;&rest... @@ -231,10 +231,10 @@ FILE-NAME is full path to lilypond (.ly) file." (arg-10 (concat "--output=" (file-name-sans-extension file-name))) (arg-11 file-name)) (if test - `(,arg-1 ,arg-2 ,arg-3 ,arg-4 ,arg-5 ,arg-6 + `(,arg-1 ,nil ,arg-3 ,arg-4 ,arg-5 ,arg-6 ;; arg-2 ,arg-7 ,arg-8 ,arg-9 ,arg-10 ,arg-11) (call-process - arg-1 arg-2 arg-3 arg-4 arg-5 arg-6 + arg-1 nil arg-3 arg-4 arg-5 arg-6 ;; arg-2 arg-7 arg-8 arg-9 arg-10 arg-11)))) (defun org-babel-lilypond-check-for-compile-error (file-name &optional test) diff --git a/lisp/org/ol-gnus.el b/lisp/org/ol-gnus.el index 71051bc683..2d51447e0c 100644 --- a/lisp/org/ol-gnus.el +++ b/lisp/org/ol-gnus.el @@ -198,11 +198,11 @@ If `org-store-link' was called with a prefix arg the meaning of (to (mail-fetch-field "To")) (from (mail-fetch-field "From")) (subject (mail-fetch-field "Subject")) - newsgroup xarchive) ;those are always nil for gcc + ) ;; newsgroup xarchive ;those are always nil for gcc (unless gcc (error "Can not create link: No Gcc header found")) (org-link-store-props :type "gnus" :from from :subject subject :message-id id :group gcc :to to) - (let ((link (org-gnus-article-link gcc newsgroup id xarchive)) + (let ((link (org-gnus-article-link gcc nil id nil)) ;;newsgroup xarchive (description (org-link-email-description))) (org-link-add-props :link link :description description) link))))))) diff --git a/lisp/org/ol.el b/lisp/org/ol.el index 994e30f4f4..9ed6ab954e 100644 --- a/lisp/org/ol.el +++ b/lisp/org/ol.el @@ -1467,7 +1467,7 @@ non-nil." (move-beginning-of-line 2) (set-mark (point))))) (setq org-store-link-plist nil) - (let (link cpltxt desc description search custom-id agenda-link) + (let (link cpltxt desc search custom-id agenda-link) ;; description (cond ;; Store a link using an external link type, if any function is ;; available. If more than one can generate a link from current @@ -1598,7 +1598,7 @@ non-nil." 'org-create-file-search-functions)) (setq link (concat "file:" (abbreviate-file-name buffer-file-name) "::" search)) - (setq cpltxt (or description link))) + (setq cpltxt (or link))) ;; description ((and (buffer-file-name (buffer-base-buffer)) (derived-mode-p 'org-mode)) (org-with-limited-levels diff --git a/lisp/org/org-clock.el b/lisp/org/org-clock.el index 2844b0e511..251ad97cde 100644 --- a/lisp/org/org-clock.el +++ b/lisp/org/org-clock.el @@ -2239,7 +2239,7 @@ have priority." ((>= month 7) 3) ((>= month 4) 2) (t 1))) - m1 h1 d1 month1 y1 shiftedy shiftedm shiftedq) + h1 d1 month1 y1 shiftedy shiftedm shiftedq) ;; m1 (cond ((string-match "\\`[0-9]+\\'" skey) (setq y (string-to-number skey) month 1 d 1 key 'year)) @@ -2342,7 +2342,7 @@ have priority." (`interactive (org-read-date nil t nil "Range end? ")) (`untilnow (current-time)) (_ (encode-time 0 - (or m1 m) + m ;; (or m1 m) (or h1 h) (or d1 d) (or month1 month) @@ -2389,7 +2389,7 @@ the currently selected interval size." (user-error "Line needs a :block definition before this command works") (let* ((b (match-beginning 1)) (e (match-end 1)) (s (match-string 1)) - block shift ins y mw d date wp m) + block shift ins y mw d date wp) ;; m (cond ((equal s "yesterday") (setq s "today-1")) ((equal s "lastweek") (setq s "thisweek-1")) @@ -2414,7 +2414,7 @@ the currently selected interval size." (cond (d (setq ins (format-time-string "%Y-%m-%d" - (encode-time 0 0 0 (+ d n) m y)))) + (encode-time 0 0 0 (+ d n) nil y)))) ;; m ((and wp (string-match "w\\|W" wp) mw (> (length wp) 0)) (require 'cal-iso) (setq date (calendar-gregorian-from-absolute diff --git a/lisp/org/org-crypt.el b/lisp/org/org-crypt.el index caf9de91b9..103baeb49e 100644 --- a/lisp/org/org-crypt.el +++ b/lisp/org/org-crypt.el @@ -284,6 +284,8 @@ Assume `epg-context' is set." nil))) (_ nil))) +(defvar org--matcher-tags-todo-only) + ;;;###autoload (defun org-encrypt-entries () "Encrypt all top-level entries in the current buffer." diff --git a/lisp/org/org-protocol.el b/lisp/org/org-protocol.el index 74043f8340..726c1ca2ba 100644 --- a/lisp/org/org-protocol.el +++ b/lisp/org/org-protocol.el @@ -535,7 +535,7 @@ The location for a browser's bookmark should look like this: encodeURIComponent(location.href)" ;; As we enter this function for a match on our protocol, the return value ;; defaults to nil. - (let ((result nil) + (let (;; (result nil) (f (org-protocol-sanitize-uri (plist-get (org-protocol-parse-parameters fname nil '(:url)) :url)))) @@ -586,7 +586,7 @@ The location for a browser's bookmark should look like this: (if (file-exists-p the-file) (message "%s: permission denied!" the-file) (message "%s: no such file or directory." the-file)))))) - result))) + nil))) ;; FIXME: Really? ;;; Core functions: diff --git a/lisp/org/ox-odt.el b/lisp/org/ox-odt.el index 2d550d9277..a076d15978 100644 --- a/lisp/org/ox-odt.el +++ b/lisp/org/ox-odt.el @@ -2111,7 +2111,8 @@ SHORT-CAPTION are strings." (caption (let ((c (org-export-get-caption element-or-parent))) (and c (org-export-data c info)))) ;; FIXME: We don't use short-caption for now - (short-caption nil)) + ;; (short-caption nil) + ) (when (or label caption) (let* ((default-category (cl-case (org-element-type element) @@ -2159,7 +2160,7 @@ SHORT-CAPTION are strings." "%s" label counter counter seqno)) (?c . ,(or caption ""))))) - short-caption)) + nil)) ;; short-caption ;; Case 2: Handle Label reference. (reference (let* ((fmt (cddr (assoc-string label-style org-odt-label-styles t))) @@ -2362,14 +2363,14 @@ used as a communication channel." ;; If yes, note down its contents. It will go in to frame ;; description. This quite useful for debugging. (desc (and replaces (org-element-property :value replaces))) - width height) + ) ;; width height (cond ((eq embed-as 'character) - (org-odt--render-image/formula "InlineFormula" href width height + (org-odt--render-image/formula "InlineFormula" href nil nil ;; width height nil nil title desc)) (t (let* ((equation (org-odt--render-image/formula - "CaptionedDisplayFormula" href width height + "CaptionedDisplayFormula" href nil nil ;; width height captions nil title desc)) (label (let* ((org-odt-category-map-alist diff --git a/lisp/org/ox.el b/lisp/org/ox.el index 050a8094d0..36ecf01483 100644 --- a/lisp/org/ox.el +++ b/lisp/org/ox.el @@ -2706,9 +2706,9 @@ a list of footnote definitions or in the widened buffer." (and (or (eq (org-element-type f) 'footnote-definition) (eq (org-element-property :type f) 'inline)) (org-element-property :label f))))) - seen) + ) ;; seen (dolist (l (funcall list-labels tree)) - (cond ((member l seen)) + (cond ;; ((member l seen)) ((member l known-definitions) (push l defined)) (t (push l undefined))))) ;; Complete MISSING-DEFINITIONS by finding the definition of every commit e13c30132a81ca2087f7d1a3adc5f6feab84ea2e Author: Stefan Monnier Date: Thu Mar 11 13:01:59 2021 -0500 * lisp/emacs-lisp/cconv.el (cconv--analyze-use): Warn never-initialized vars (byte-compile-not-lexical-var-p): Remove Emacs<24 compatibility. diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el index 68e930fa3f..ca641a2ef0 100644 --- a/lisp/emacs-lisp/cconv.el +++ b/lisp/emacs-lisp/cconv.el @@ -585,9 +585,6 @@ places where they originally did not directly appear." (_ (or (cdr (assq form env)) form)))) -(unless (fboundp 'byte-compile-not-lexical-var-p) - ;; Only used to test the code in non-lexbind Emacs. - (defalias 'byte-compile-not-lexical-var-p 'boundp)) (defvar byte-compile-lexical-variables) (defun cconv--analyze-use (vardata form varkind) @@ -603,7 +600,13 @@ FORM is the parent form that binds this var." ;; FIXME: Convert this warning to use `macroexp--warn-wrap' ;; so as to give better position information. (byte-compile-warn - "%s `%S' not left unused" varkind var))) + "%s `%S' not left unused" varkind var)) + ((and (let (or 'let* 'let) (car form)) + `(,(or `(,var) `(,var nil)) t nil ,_ ,_)) + ;; FIXME: Convert this warning to use `macroexp--warn-wrap' + ;; so as to give better position information. + (unless (not (intern-soft var)) + (byte-compile-warn "Variable `%S' left uninitialized" var)))) (pcase vardata (`(,binder nil ,_ ,_ nil) (push (cons (cons binder form) :unused) cconv-var-classification)) @@ -784,7 +787,7 @@ This function does not return anything but instead fills the (let ((dv (assq form env))) ; dv = declared and visible (when dv (setf (nth 1 dv) t)))))) -(define-obsolete-function-alias 'cconv-analyse-form 'cconv-analyze-form "25.1") +(define-obsolete-function-alias 'cconv-analyse-form #'cconv-analyze-form "25.1") (provide 'cconv) ;;; cconv.el ends here commit 27b8638409138a02577d2dd43e4cb59540f9174f Author: Lars Ingebrigtsen Date: Thu Mar 11 17:50:02 2021 +0100 Re-fix previous Info-fontify-node change * lisp/info.el (Info-fontify-node): Re-fix previous fix here (bug#34661) by fixing an off-by-one error in the `looking-back'. diff --git a/lisp/info.el b/lisp/info.el index e7324efa2f..dd7e16f870 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -4797,10 +4797,10 @@ first line or header line, and for breadcrumb links.") (skip-syntax-backward " (")) (setq other-tag (cond ((save-match-data (looking-back "\\(^\\| \\)see" - (- (point) 3))) + (- (point) 4))) "") ((save-match-data (looking-back "\\(^\\| \\)in" - (- (point) 2))) + (- (point) 3))) "") ((memq (char-before) '(nil ?\. ?! ??)) "See ") commit 02a5cfce471613f671722b35536d2a78f17b0429 Author: Stefan Monnier Date: Thu Mar 11 11:41:53 2021 -0500 * lisp/mouse.el: Fix mouse-1-clock-follows-mouse = double This functionality was broken by commit 3d5e31eceb9dc1fb62b2b2, the problem being that we end up considering as distinct the events `down-double-mouse-1` and `double-down-mouse-1`. Reported by Eyal Soha (mouse--click-1-maybe-follows-link): Make sure the last element of the list passed to `event-convert-list` is indeed a "basic" event. diff --git a/lisp/mouse.el b/lisp/mouse.el index 72ad77c634..6b8e65c4a2 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -116,7 +116,9 @@ Expects to be bound to `(double-)mouse-1' in `key-translation-map'." (time-since (cdr mouse--last-down)) (/ (abs mouse-1-click-follows-link) 1000.0)))))) (eq (car mouse--last-down) - (event-convert-list (list 'down (car-safe last-input-event)))) + (event-convert-list + `(down ,@(event-modifiers last-input-event) + ,(event-basic-type last-input-event)))) (let* ((action (mouse-on-link-p (event-start last-input-event)))) (when (and action (or mouse-1-click-in-non-selected-windows commit 65441a6fab7a24d2433411119191002cb366c96d Author: Michael Albinus Date: Thu Mar 11 17:16:50 2021 +0100 Add remote processes to Tramp sshfs method * doc/misc/tramp.texi (FUSE setup): Method sshfs supports also remote processes. * lisp/net/tramp-cache.el (tramp-get-file-property) (tramp-set-file-property): Move setting of `tramp-cache-unload-hook' out of function. * lisp/net/tramp.el (tramp-expand-args): New defun. (tramp-handle-make-process): * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-out-of-band) (tramp-maybe-open-connection): * lisp/net/tramp-sshfs.el (tramp-sshfs-maybe-open-connection): * lisp/net/tramp-sudoedit.el (tramp-sudoedit-send-command): Use it. * lisp/net/tramp-sshfs.el (tramp-methods) : Adapt `tramp-mount-args'. Add `tramp-login-args', `tramp-direct-async', `tramp-remote-shell', `tramp-remote-shell-login' and `tramp-remote-shell-args'. (tramp-connection-properties): Set "direct-async-process" fir sshfs. (tramp-sshfs-file-name-handler-alist): Add `exec-path', `make-process', `process-file', `set-file-modes', `shell-command', `start-file-process', `tramp-get-remote-gid', `tramp-get-remote-uid' and `tramp-set-file-uid-gid'. (tramp-sshfs-handle-exec-path, tramp-sshfs-handle-process-file) (tramp-sshfs-handle-set-file-modes): New defuns. * test/lisp/net/tramp-tests.el (tramp-test20-file-modes) (tramp-test28-process-file, tramp-test29-start-file-process) (tramp-test30-make-process, tramp-test32-shell-command) (tramp-test32-shell-command-dont-erase-buffer) (tramp-test34-explicit-shell-file-name, tramp-test35-exec-path) (tramp-test43-asynchronous-requests): Run also for tramp-sshfs. (tramp--test-shell-file-name): New defun. (tramp-test28-process-file) (tramp-test34-explicit-shell-file-name) (tramp-test43-asynchronous-requests): Use it. (tramp-test40-special-characters-with-stat) (tramp-test40-special-characters-with-perl) (tramp-test40-special-characters-with-ls) (tramp-test41-utf8-with-stat, tramp-test41-utf8-with-perl) (tramp-test41-utf8-with-ls): Remove superfluous skip. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 5958162d93..e5e15cdaa5 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -2648,11 +2648,14 @@ visibility of files. @subsection @option{sshfs} setup @cindex sshfs setup -The method @option{sshfs} declares only the mount arguments, passed to -the @command{sshfs} command. This is a list of list of strings, and -can be overwritten by the connection property @t{"mount-args"}, -@xref{Predefined connection information}. +The method @option{sshfs} declares the mount arguments in the variable +@code{tramp-methods}, passed to the @command{sshfs} command. This is +a list of list of strings, and can be overwritten by the connection +property @t{"mount-args"}, @xref{Predefined connection information}. +Additionally. it declares also the arguments for running remote +processes, using the @command{ssh} command. These don't need to be +changed. @node Android shell setup @section Android shell setup hints diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index c79a3a02a3..2fcb7b11e8 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el @@ -162,17 +162,20 @@ Return DEFAULT if not set." (tramp-message key 8 "%s %s %s; inhibit: %s; cache used: %s; cached at: %s" file property value remote-file-name-inhibit-cache cache-used cached-at) + ;; For analysis purposes, count the number of getting this file attribute. (when (>= tramp-verbose 10) (let* ((var (intern (concat "tramp-cache-get-count-" property))) (val (or (and (boundp var) (numberp (symbol-value var)) (symbol-value var)) - (progn - (add-hook 'tramp-cache-unload-hook - (lambda () (makunbound var))) - 0)))) + 0))) (set var (1+ val)))) value)) +(add-hook 'tramp-cache-unload-hook + (lambda () + (dolist (var (all-completions "tramp-cache-get-count-" obarray)) + (unintern var obarray)))) + ;;;###tramp-autoload (defun tramp-set-file-property (key file property value) "Set the PROPERTY of FILE to VALUE, in the cache context of KEY. @@ -187,17 +190,20 @@ Return VALUE." ;; We put the timestamp there. (puthash property (cons (current-time) value) hash) (tramp-message key 8 "%s %s %s" file property value) + ;; For analysis purposes, count the number of setting this file attribute. (when (>= tramp-verbose 10) (let* ((var (intern (concat "tramp-cache-set-count-" property))) (val (or (and (boundp var) (numberp (symbol-value var)) (symbol-value var)) - (progn - (add-hook 'tramp-cache-unload-hook - (lambda () (makunbound var))) - 0)))) + 0))) (set var (1+ val)))) value)) +(add-hook 'tramp-cache-unload-hook + (lambda () + (dolist (var (all-completions "tramp-cache-set-count-" obarray)) + (unintern var obarray)))) + ;;;###tramp-autoload (defun tramp-flush-file-property (key file property) "Remove PROPERTY of FILE in the cache context of KEY." diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 7f6ecc6c32..14abf55e55 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -2370,53 +2370,29 @@ The method used must be an out-of-band method." (setq listener (number-to-string (+ 50000 (random 10000)))))) ;; Compose copy command. - (setq host (or host "") - user (or user "") - port (or port "") - spec (format-spec-make - ?t (tramp-get-connection-property - (tramp-get-connection-process v) "temp-file" "")) - options (format-spec (tramp-ssh-controlmaster-options v) spec) - spec (format-spec-make - ?h host ?u user ?p port ?r listener ?c options - ?k (if keep-date " " "") + (setq options + (format-spec + (tramp-ssh-controlmaster-options v) + (format-spec-make + ?t (tramp-get-connection-property + (tramp-get-connection-process v) "temp-file" ""))) + spec (list + ?h (or host "") ?u (or user "") ?p (or port "") + ?r listener ?c options ?k (if keep-date " " "") ?n (concat "2>" (tramp-get-remote-null-device v))) copy-program (tramp-get-method-parameter v 'tramp-copy-program) copy-keep-date (tramp-get-method-parameter v 'tramp-copy-keep-date) - copy-args - (delete - ;; " " has either been a replacement of "%k" (when - ;; keep-date argument is non-nil), or a replacement - ;; for the whole keep-date sublist. - " " - (dolist - (x (tramp-get-method-parameter v 'tramp-copy-args) copy-args) - (setq copy-args - (append - copy-args - (let ((y (mapcar (lambda (z) (format-spec z spec)) x))) - (unless (member "" y) y)))))) - - copy-env - (delq - nil - (mapcar - (lambda (x) - (setq x (mapcar (lambda (y) (format-spec y spec)) x)) - (unless (member "" x) (string-join x " "))) - (tramp-get-method-parameter v 'tramp-copy-env))) - + ;; " " has either been a replacement of "%k" (when + ;; keep-date argument is non-nil), or a replacement for + ;; the whole keep-date sublist. + (delete " " (apply #'tramp-expand-args v 'tramp-copy-args spec)) + copy-env (apply #'tramp-expand-args v 'tramp-copy-env spec) remote-copy-program - (tramp-get-method-parameter v 'tramp-remote-copy-program)) - - (dolist (x (tramp-get-method-parameter v 'tramp-remote-copy-args)) - (setq remote-copy-args - (append - remote-copy-args - (let ((y (mapcar (lambda (z) (format-spec z spec)) x))) - (unless (member "" y) y))))) + (tramp-get-method-parameter v 'tramp-remote-copy-program) + remote-copy-args + (apply #'tramp-expand-args v 'tramp-remote-copy-args spec)) ;; Check for local copy program. (unless (executable-find copy-program) @@ -2462,10 +2438,11 @@ The method used must be an out-of-band method." v "process-name" (buffer-name (current-buffer))) (tramp-set-connection-property v "process-buffer" (current-buffer)) - (while copy-env + (when copy-env (tramp-message - orig-vec 6 "%s=\"%s\"" (car copy-env) (cadr copy-env)) - (setenv (pop copy-env) (pop copy-env))) + orig-vec 6 "%s=\"%s\"" + (car copy-env) (string-join (cdr copy-env) " ")) + (setenv (car copy-env) (string-join (cdr copy-env) " "))) (setq copy-args (append @@ -5049,19 +5026,17 @@ connection if a previous connection has died for some reason." (l-domain (tramp-file-name-domain hop)) (l-host (tramp-file-name-host hop)) (l-port (tramp-file-name-port hop)) - (login-program - (tramp-get-method-parameter hop 'tramp-login-program)) - (login-args - (tramp-get-method-parameter hop 'tramp-login-args)) (remote-shell (tramp-get-method-parameter hop 'tramp-remote-shell)) (extra-args (tramp-get-sh-extra-args remote-shell)) (async-args - (tramp-get-method-parameter hop 'tramp-async-args)) + (tramp-compat-flatten-tree + (tramp-get-method-parameter hop 'tramp-async-args))) (connection-timeout (tramp-get-method-parameter hop 'tramp-connection-timeout)) - (command login-program) + (command + (tramp-get-method-parameter hop 'tramp-login-program)) ;; We don't create the temporary file. In ;; fact, it is just a prefix for the ;; ControlPath option of ssh; the real @@ -5075,11 +5050,7 @@ connection if a previous connection has died for some reason." (with-tramp-connection-property (tramp-get-process vec) "temp-file" (tramp-compat-make-temp-name))) - spec r-shell) - - ;; Add arguments for asynchronous processes. - (when (and process-name async-args) - (setq login-args (append async-args login-args))) + r-shell) ;; Check, whether there is a restricted shell. (dolist (elt tramp-restricted-shell-hosts-alist) @@ -5104,31 +5075,28 @@ connection if a previous connection has died for some reason." ;; Replace `login-args' place holders. (setq - l-host (or l-host "") - l-user (or l-user "") - l-port (or l-port "") - spec (format-spec-make ?t tmpfile) - options (format-spec options spec) - spec (format-spec-make - ?h l-host ?u l-user ?p l-port ?c options - ?l (concat remote-shell " " extra-args " -i")) command - (concat - ;; We do not want to see the trailing local - ;; prompt in `start-file-process'. - (unless r-shell "exec ") - command " " - (mapconcat - (lambda (x) - (setq x (mapcar (lambda (y) (format-spec y spec)) x)) - (unless (member "" x) (string-join x " "))) - login-args " ") - ;; Local shell could be a Windows COMSPEC. It - ;; doesn't know the ";" syntax, but we must exit - ;; always for `start-file-process'. It could - ;; also be a restricted shell, which does not - ;; allow "exec". - (when r-shell " && exit || exit"))) + (mapconcat + #'identity + (append + ;; We do not want to see the trailing local + ;; prompt in `start-file-process'. + (unless r-shell '("exec")) + `(,command) + ;; Add arguments for asynchronous processes. + (when process-name async-args) + (tramp-expand-args + hop 'tramp-login-args + ?h (or l-host "") ?u (or l-user "") ?p (or l-port "") + ?c (format-spec options (format-spec-make ?t tmpfile)) + ?l (concat remote-shell " " extra-args " -i")) + ;; Local shell could be a Windows COMSPEC. It + ;; doesn't know the ";" syntax, but we must + ;; exit always for `start-file-process'. It + ;; could also be a restricted shell, which does + ;; not allow "exec". + (when r-shell '("&&" "exit" "||" "exit"))) + " ")) ;; Send the command. (tramp-message vec 3 "Sending command `%s'" command) @@ -5469,7 +5437,7 @@ Nonexistent directories are removed from spec." (progn (tramp-message vec 3 - "`getconf PATH' not successful, using default value \"%s\"." + "`getconf PATH' not successful, using default value \"%s\"." "/bin:/usr/bin") "/bin:/usr/bin")))) (own-remote-path diff --git a/lisp/net/tramp-sshfs.el b/lisp/net/tramp-sshfs.el index feb64b82bc..ce9412c0be 100644 --- a/lisp/net/tramp-sshfs.el +++ b/lisp/net/tramp-sshfs.el @@ -51,9 +51,19 @@ (tramp--with-startup (add-to-list 'tramp-methods `(,tramp-sshfs-method - (tramp-mount-args - (("-p" "%p") - ("-o" "idmap=user,reconnect"))))) + (tramp-mount-args (("-C") ("-p" "%p") + ("-o" "idmap=user,reconnect"))) + ;; These are for remote processes. + (tramp-login-program "ssh") + (tramp-login-args (("-q")("-l" "%u") ("-p" "%p") + ("-e" "none") ("%h") ("%l"))) + (tramp-direct-async t) + (tramp-remote-shell ,tramp-default-remote-shell) + (tramp-remote-shell-login ("-l")) + (tramp-remote-shell-args ("-c")))) + + (add-to-list 'tramp-connection-properties + `(,(format "/%s:" tramp-sshfs-method) "direct-async-process" t)) (tramp-set-completion-function tramp-sshfs-method tramp-completion-function-alist-ssh)) @@ -76,7 +86,7 @@ . tramp-handle-directory-files-and-attributes) (dired-compress-file . ignore) (dired-uncache . tramp-handle-dired-uncache) -;; (exec-path . ignore) + (exec-path . tramp-sshfs-handle-exec-path) (expand-file-name . tramp-handle-expand-file-name) (file-accessible-directory-p . tramp-handle-file-accessible-directory-p) (file-acl . ignore) @@ -117,22 +127,22 @@ (make-directory . tramp-fuse-handle-make-directory) (make-directory-internal . ignore) (make-nearby-temp-file . tramp-handle-make-nearby-temp-file) -;; (make-process . ignore) + (make-process . tramp-handle-make-process) (make-symbolic-link . tramp-handle-make-symbolic-link) -;; (process-file . ignore) + (process-file . tramp-sshfs-handle-process-file) (rename-file . tramp-sshfs-handle-rename-file) (set-file-acl . ignore) - (set-file-modes . ignore) + (set-file-modes . tramp-sshfs-handle-set-file-modes) (set-file-selinux-context . ignore) (set-file-times . ignore) (set-visited-file-modtime . tramp-handle-set-visited-file-modtime) -;; (shell-command . ignore) -;; (start-file-process . ignore) + (shell-command . tramp-handle-shell-command) + (start-file-process . tramp-handle-start-file-process) (substitute-in-file-name . tramp-handle-substitute-in-file-name) (temporary-file-directory . tramp-handle-temporary-file-directory) -;; (tramp-get-remote-gid . ignore) -;; (tramp-get-remote-uid . ignore) -;; (tramp-set-file-uid-gid . ignore) + (tramp-get-remote-gid . ignore) + (tramp-get-remote-uid . ignore) + (tramp-set-file-uid-gid . ignore) (unhandled-file-name-directory . ignore) (vc-registered . ignore) (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime) @@ -185,6 +195,22 @@ arguments to pass to the OPERATION." (with-parsed-tramp-file-name newname nil (tramp-flush-file-properties v localname))))) +(defun tramp-sshfs-handle-exec-path () + "Like `exec-path' for Tramp files." + (append + (with-parsed-tramp-file-name default-directory nil + (with-tramp-connection-property (tramp-get-process v) "remote-path" + (with-temp-buffer + (process-file "getconf" nil t nil "PATH") + (split-string + (progn + ;; Read the expression. + (goto-char (point-min)) + (buffer-substring (point) (point-at-eol))) + ":" 'omit)))) + ;; The equivalent to `exec-directory'. + `(,(tramp-file-local-name (expand-file-name default-directory))))) + (defun tramp-sshfs-handle-file-system-info (filename) "Like `file-system-info' for Tramp files." ;;`file-system-info' exists since Emacs 27.1. @@ -199,6 +225,34 @@ arguments to pass to the OPERATION." (when visit (setq buffer-file-name filename)) (cons (expand-file-name filename) (cdr result)))) +(defun tramp-sshfs-handle-process-file + (program &optional infile destination display &rest args) + "Like `process-file' for Tramp files." + ;; The implementation is not complete yet. + (when (and (numberp destination) (zerop destination)) + (error "Implementation does not handle immediate return")) + + (with-parsed-tramp-file-name default-directory nil + (let ((command + (format + "cd %s && exec %s" + localname + (mapconcat #'tramp-shell-quote-argument (cons program args) " ")))) + (unwind-protect + (apply + #'tramp-call-process + v (tramp-get-method-parameter v 'tramp-login-program) + infile destination display + (tramp-expand-args + v 'tramp-login-args + ?h (or (tramp-file-name-host v) "") + ?u (or (tramp-file-name-user v) "") + ?p (or (tramp-file-name-port v) "") + ?l command)) + + (unless process-file-side-effects + (tramp-flush-directory-properties v "")))))) + (defun tramp-sshfs-handle-rename-file (filename newname &optional ok-if-already-exists) "Like `rename-file' for Tramp files." @@ -217,6 +271,13 @@ arguments to pass to the OPERATION." (with-parsed-tramp-file-name newname nil (tramp-flush-file-properties v localname)))) +(defun tramp-sshfs-handle-set-file-modes (filename mode &optional flag) + "Like `set-file-modes' for Tramp files." + (with-parsed-tramp-file-name filename nil + (unless (and (eq flag 'nofollow) (file-symlink-p filename)) + (tramp-flush-file-properties v localname) + (set-file-modes (tramp-fuse-local-file-name filename) mode flag)))) + (defun tramp-sshfs-handle-write-region (start end filename &optional append visit lockname mustbenew) "Like `write-region' for Tramp files." @@ -269,28 +330,16 @@ connection if a previous connection has died for some reason." (unless (or (tramp-fuse-mounted-p vec) - (let* ((port (or (tramp-file-name-port vec) "")) - (spec (format-spec-make ?p port)) - mount-args - (mount-args - (dolist - (x - (tramp-get-method-parameter vec 'tramp-mount-args) - mount-args) - (setq mount-args - (append - mount-args - (let ((y (mapcar - (lambda (z) (format-spec z spec)) - x))) - (unless (member "" y) y))))))) - (with-temp-buffer - (zerop - (apply - #'tramp-call-process - vec tramp-sshfs-program nil t nil - (tramp-fuse-mount-spec vec) - (tramp-fuse-mount-point vec) mount-args)))) + (with-temp-buffer + (zerop + (apply + #'tramp-call-process + vec tramp-sshfs-program nil t nil + (tramp-fuse-mount-spec vec) + (tramp-fuse-mount-point vec) + (tramp-expand-args + vec 'tramp-mount-args + ?p (or (tramp-file-name-port vec) ""))))) (tramp-error vec 'file-error "Error mounting %s" (tramp-fuse-mount-spec vec)))) diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el index e181365162..66737e61da 100644 --- a/lisp/net/tramp-sudoedit.el +++ b/lisp/net/tramp-sudoedit.el @@ -791,22 +791,16 @@ in case of error, t otherwise." (tramp-sudoedit-maybe-open-connection vec) (with-current-buffer (tramp-get-connection-buffer vec) (erase-buffer) - (let* ((login (tramp-get-method-parameter vec 'tramp-sudo-login)) - (host (or (tramp-file-name-host vec) "")) - (user (or (tramp-file-name-user vec) "")) - (spec (format-spec-make ?h host ?u user)) - (args (append - (tramp-compat-flatten-tree - (mapcar - (lambda (x) - (setq x (mapcar (lambda (y) (format-spec y spec)) x)) - (unless (member "" x) x)) - login)) - (tramp-compat-flatten-tree (delq nil args)))) - (delete-exited-processes t) + (let* ((delete-exited-processes t) (process-connection-type tramp-process-connection-type) (p (apply #'start-process - (tramp-get-connection-name vec) (current-buffer) args)) + (tramp-get-connection-name vec) (current-buffer) + (append + (tramp-expand-args + vec 'tramp-sudo-login + ?h (or (tramp-file-name-host vec) "") + ?u (or (tramp-file-name-user vec) "")) + (tramp-compat-flatten-tree args)))) ;; We suppress the messages `Waiting for prompts from remote shell'. (tramp-verbose (if (= tramp-verbose 3) 2 tramp-verbose)) ;; We do not want to save the password. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 9f65608f3a..da779d3386 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -3765,6 +3765,22 @@ User is always nil." ;; Result. target-alist)) +(defun tramp-expand-args (vec parameter &rest spec-list) + "Expand login arguments as given by PARAMETER in `tramp-methods'. +PARAMETER is a symbol like `tramp-login-args', denoting a list of +list of strings from `tramp-methods', containing %-sequences for +substitution. SPEC-LIST is a list of char/value pairs used for +`format-spec-make'." + (let ((args (tramp-get-method-parameter vec parameter)) + (spec (apply 'format-spec-make spec-list))) + ;; Expand format spec. + (tramp-compat-flatten-tree + (mapcar + (lambda (x) + (setq x (mapcar (lambda (y) (format-spec y spec)) x)) + (unless (member "" x) x)) + args)))) + (defun tramp-direct-async-process-p (&rest args) "Whether direct async `make-process' can be called." (let ((v (tramp-dissect-file-name default-directory)) @@ -3846,14 +3862,11 @@ It does not support `:stderr'." (append `("cd" ,localname "&&" "(" "env") env `(,command ")")))) ;; Check for `tramp-sh-file-name-handler', because something - ;; is different between tramp-adb.el and tramp-sh.el. + ;; is different between tramp-sh.el, and tramp-adb.el or + ;; tramp-sshfs.el. (let* ((sh-file-name-handler-p (tramp-sh-file-name-handler-p v)) (login-program (tramp-get-method-parameter v 'tramp-login-program)) - (login-args - (tramp-get-method-parameter v 'tramp-login-args)) - (async-args - (tramp-get-method-parameter v 'tramp-async-args)) ;; We don't create the temporary file. In fact, it ;; is just a prefix for the ControlPath option of ;; ssh; the real temporary file has another name, and @@ -3871,29 +3884,23 @@ It does not support `:stderr'." (when sh-file-name-handler-p (tramp-compat-funcall 'tramp-ssh-controlmaster-options v))) - spec p) + login-args p) - ;; Replace `login-args' place holders. + ;; Replace `login-args' place holders. Split + ;; ControlMaster options. (setq - spec (format-spec-make ?t tmpfile) - options (format-spec (or options "") spec) - spec (format-spec-make - ?h (or host "") ?u (or user "") ?p (or port "") - ?c options ?l "") - ;; Add arguments for asynchronous processes. - login-args (append async-args login-args) - ;; Expand format spec. login-args - (tramp-compat-flatten-tree - (mapcar - (lambda (x) - (setq x (mapcar (lambda (y) (format-spec y spec)) x)) - (unless (member "" x) x)) - login-args)) - ;; Split ControlMaster options. - login-args - (tramp-compat-flatten-tree - (mapcar (lambda (x) (split-string x " ")) login-args)) + (append + (tramp-compat-flatten-tree + (tramp-get-method-parameter v 'tramp-async-args)) + (tramp-compat-flatten-tree + (mapcar + (lambda (x) (split-string x " ")) + (tramp-expand-args + v 'tramp-login-args + ?h (or host "") ?u (or user "") ?p (or port "") + ?c (format-spec (or options "") (format-spec-make ?t tmpfile)) + ?l "")))) p (make-process :name name :buffer buffer :command (append `(,login-program) login-args command) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index d9a8065e72..6565919c77 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -3537,7 +3537,7 @@ They might differ only in time attributes or directory size." This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." (skip-unless (tramp--test-enabled)) (skip-unless - (or (tramp--test-sh-p) (tramp--test-sudoedit-p) + (or (tramp--test-sh-p) (tramp--test-sshfs-p) (tramp--test-sudoedit-p) ;; Not all tramp-gvfs.el methods support changing the file mode. (and (tramp--test-gvfs-p) @@ -4368,11 +4368,15 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (and (featurep 'tramp-test-load) (unload-feature 'tramp-test-load)) (delete-file tmp-name)))))) +(defun tramp--test-shell-file-name () + "Return default remote shell.." + (if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh")) + (ert-deftest tramp-test28-process-file () "Check `process-file'." :tags '(:expensive-test) (skip-unless (tramp--test-enabled)) - (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p))) + (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p) (tramp--test-sshfs-p))) (skip-unless (not (tramp--test-crypt-p))) (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil))) @@ -4389,25 +4393,27 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (should-not (zerop (process-file "binary-does-not-exist"))) ;; Return exit code. (should (= 42 (process-file - (if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh") + (tramp--test-shell-file-name) nil nil nil "-c" "exit 42"))) ;; Return exit code in case the process is interrupted, ;; and there's no indication for a signal describing string. - (let (process-file-return-signal-string) - (should - (= (+ 128 2) - (process-file - (if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh") - nil nil nil "-c" "kill -2 $$")))) + (unless (tramp--test-sshfs-p) + (let (process-file-return-signal-string) + (should + (= (+ 128 2) + (process-file + (tramp--test-shell-file-name) + nil nil nil "-c" "kill -2 $$"))))) ;; Return string in case the process is interrupted and ;; there's an indication for a signal describing string. - (let ((process-file-return-signal-string t)) - (should - (string-match-p - "Interrupt\\|Signal 2" - (process-file - (if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh") - nil nil nil "-c" "kill -2 $$")))) + (unless (tramp--test-sshfs-p) + (let ((process-file-return-signal-string t)) + (should + (string-match-p + "Interrupt\\|Signal 2" + (process-file + (tramp--test-shell-file-name) + nil nil nil "-c" "kill -2 $$"))))) (with-temp-buffer (write-region "foo" nil tmp-name) @@ -4451,7 +4457,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." "Check `start-file-process'." :tags '(:expensive-test) (skip-unless (tramp--test-enabled)) - (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p))) + (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p) (tramp--test-sshfs-p))) (skip-unless (not (tramp--test-crypt-p))) (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil))) @@ -4571,7 +4577,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." "Check `make-process'." :tags '(:expensive-test) (skip-unless (tramp--test-enabled)) - (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p))) + (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p) (tramp--test-sshfs-p))) (skip-unless (not (tramp--test-crypt-p))) ;; `make-process' supports file name handlers since Emacs 27. (skip-unless (tramp--test-emacs27-p)) @@ -4799,7 +4805,7 @@ INPUT, if non-nil, is a string sent to the process." ;; Prior Emacs 27, `shell-file-name' was hard coded as "/bin/sh" for ;; remote processes in Emacs. That doesn't work for tramp-adb.el. (skip-unless (or (and (tramp--test-adb-p) (tramp--test-emacs27-p)) - (tramp--test-sh-p))) + (tramp--test-sh-p) (tramp--test-sshfs-p))) (skip-unless (not (tramp--test-crypt-p))) (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil))) @@ -4898,7 +4904,7 @@ INPUT, if non-nil, is a string sent to the process." :tags '(:expensive-test :unstable) (skip-unless (tramp--test-enabled)) (skip-unless nil) - (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p))) + (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p) (tramp--test-sshfs-p))) (skip-unless (not (tramp--test-crypt-p))) ;; Prior Emacs 27, `shell-command-dont-erase-buffer' wasn't working properly. (skip-unless (tramp--test-emacs27-p)) @@ -5223,7 +5229,7 @@ Use direct async.") ;; Prior Emacs 27, `shell-file-name' was hard coded as "/bin/sh" for ;; remote processes in Emacs. That doesn't work for tramp-adb.el. (skip-unless (or (and (tramp--test-adb-p) (tramp--test-emacs27-p)) - (tramp--test-sh-p))) + (tramp--test-sh-p) (tramp--test-sshfs-p))) (skip-unless (not (tramp--test-crypt-p))) ;; Since Emacs 26.1. (skip-unless (and (fboundp 'connection-local-set-profile-variables) @@ -5245,8 +5251,7 @@ Use direct async.") (with-no-warnings (connection-local-set-profile-variables 'remote-sh - `((explicit-shell-file-name - . ,(if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh")) + `((explicit-shell-file-name . ,(tramp--test-shell-file-name)) (explicit-sh-args . ("-c" "echo foo")))) (connection-local-set-profiles `(:application tramp @@ -5280,7 +5285,7 @@ Use direct async.") (ert-deftest tramp-test35-exec-path () "Check `exec-path' and `executable-find'." (skip-unless (tramp--test-enabled)) - (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p))) + (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p) (tramp--test-sshfs-p))) (skip-unless (not (tramp--test-crypt-p))) ;; Since Emacs 27.1. (skip-unless (fboundp 'exec-path)) @@ -6120,7 +6125,6 @@ Use the `stat' command." (skip-unless (tramp--test-sh-p)) (skip-unless (not (tramp--test-rsync-p))) (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) - (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) ;; We cannot use `tramp-test-vec', because this fails during compilation. (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil (skip-unless (tramp-get-remote-stat v))) @@ -6140,7 +6144,6 @@ Use the `perl' command." (skip-unless (tramp--test-sh-p)) (skip-unless (not (tramp--test-rsync-p))) (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) - (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) ;; We cannot use `tramp-test-vec', because this fails during compilation. (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil (skip-unless (tramp-get-remote-perl v))) @@ -6163,7 +6166,6 @@ Use the `ls' command." (skip-unless (tramp--test-sh-p)) (skip-unless (not (tramp--test-rsync-p))) (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) - (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) (let ((tramp-connection-properties (append @@ -6249,7 +6251,6 @@ Use the `stat' command." (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) (skip-unless (not (tramp--test-ksh-p))) (skip-unless (not (tramp--test-crypt-p))) - (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) ;; We cannot use `tramp-test-vec', because this fails during compilation. (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil (skip-unless (tramp-get-remote-stat v))) @@ -6273,7 +6274,6 @@ Use the `perl' command." (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) (skip-unless (not (tramp--test-ksh-p))) (skip-unless (not (tramp--test-crypt-p))) - (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) ;; We cannot use `tramp-test-vec', because this fails during compilation. (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil (skip-unless (tramp-get-remote-perl v))) @@ -6300,7 +6300,6 @@ Use the `ls' command." (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) (skip-unless (not (tramp--test-ksh-p))) (skip-unless (not (tramp--test-crypt-p))) - (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) (let ((tramp-connection-properties (append @@ -6341,6 +6340,7 @@ Use the `ls' command." "Set \"process-name\" and \"process-buffer\" connection properties. The values are derived from PROC. Run BODY. This is needed in timer functions as well as process filters and sentinels." + ;; FIXME: For tramp-sshfs.el, `processp' does not work. (declare (indent 1) (debug (processp body))) `(let* ((v (tramp-get-connection-property ,proc "vector" nil)) (pname (tramp-get-connection-property v "process-name" nil)) @@ -6380,7 +6380,7 @@ process sentinels. They shall not disturb each other." ;; Prior Emacs 27, `shell-file-name' was hard coded as "/bin/sh" for ;; remote processes in Emacs. That doesn't work for tramp-adb.el. (skip-unless (or (and (tramp--test-adb-p) (tramp--test-emacs27-p)) - (tramp--test-sh-p))) + (tramp--test-sh-p) (tramp--test-sshfs-p))) (skip-unless (not (tramp--test-crypt-p))) (skip-unless (not (tramp--test-docker-p))) (skip-unless (not (tramp--test-windows-nt-p))) @@ -6390,7 +6390,7 @@ process sentinels. They shall not disturb each other." (define-key special-event-map [sigusr1] #'tramp--test-timeout-handler) (let* (;; For the watchdog. (default-directory (expand-file-name temporary-file-directory)) - (shell-file-name (if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh")) + (shell-file-name (tramp--test-shell-file-name)) ;; It doesn't work on w32 systems. (watchdog (start-process-shell-command @@ -6765,8 +6765,8 @@ If INTERACTIVE is non-nil, the tests are run interactively." ;; * Work on skipped tests. Make a comment, when it is impossible. ;; * Revisit expensive tests, once problems in `tramp-error' are solved. ;; * Fix `tramp-test06-directory-file-name' for `ftp'. -;; * Implement `tramp-test31-interrupt-process' for `adb' and for -;; direct async processes. +;; * Implement `tramp-test31-interrupt-process' for `adb', `sshfs' and +;; for direct async processes. (provide 'tramp-tests) commit 62610da8c44ae864d21a1f1e12bd4444e688eaf6 Author: Petteri Hintsanen Date: Mon Mar 8 00:25:53 2021 +0200 Make tags tables from Texinfo sources * doc/misc/Makefile.in (ETAGS, texifiles): New variables. (TAGS, tags, FORCE, ${ETAGS}): New targets. (bootstrap-clean maintainer-clean): Delete TAGS. * doc/lispref/Makefile.in (ETAGS, texifiles): New variables. (TAGS, tags, FORCE, ${ETAGS}): New targets. (bootstrap-clean maintainer-clean): Delete TAGS. * doc/lispintro/Makefile.in (ETAGS, texifiles): New variables. (TAGS, tags, FORCE, ${ETAGS}): New targets. (bootstrap-clean maintainer-clean): Delete TAGS. * doc/emacs/Makefile.in (ETAGS, texifiles): New variables. (TAGS, tags, FORCE, ${ETAGS}): New targets. (bootstrap-clean maintainer-clean): Delete TAGS. * Makefile.in (TAGS tags): Make tags in doc/emacs, doc/lispintro, doc/lispref and doc/misc. diff --git a/Makefile.in b/Makefile.in index 6acf9791ab..4fa7c9ed5f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -941,6 +941,10 @@ extraclean: $(extraclean_dirs:=_extraclean) # I removed it because it causes `make tags` to build Emacs. TAGS tags: lib lib-src # src $(MAKE) -C src tags + $(MAKE) -C doc/emacs tags + $(MAKE) -C doc/lispintro tags + $(MAKE) -C doc/lispref tags + $(MAKE) -C doc/misc tags CHECK_TARGETS = check check-maybe check-expensive check-all .PHONY: $(CHECK_TARGETS) diff --git a/doc/emacs/Makefile.in b/doc/emacs/Makefile.in index 4585b2e0dd..69d39efa8b 100644 --- a/doc/emacs/Makefile.in +++ b/doc/emacs/Makefile.in @@ -220,7 +220,7 @@ infoclean: $(buildinfodir)/emacs.info-[1-9][0-9] bootstrap-clean maintainer-clean: distclean infoclean - rm -f ${srcdir}/emacsver.texi + rm -f ${srcdir}/emacsver.texi TAGS .PHONY: install-dvi install-html install-pdf install-ps install-doc @@ -269,4 +269,20 @@ uninstall-pdf: uninstall-doc: uninstall-dvi uninstall-html uninstall-pdf uninstall-ps +ETAGS = ../../lib-src/etags${EXEEXT} + +${ETAGS}: FORCE + $(MAKE) -C $(dir $@) $(notdir $@) + +texifiles = $(wildcard ${srcdir}/*.texi) + +TAGS: ${ETAGS} $(texifiles) + $(AM_V_GEN)${ETAGS} --include=../lispref/TAGS --include=../misc/TAGS $(texifiles) + +tags: TAGS +.PHONY: tags + +FORCE: +.PHONY: FORCE + ### Makefile ends here diff --git a/doc/lispintro/Makefile.in b/doc/lispintro/Makefile.in index 45b4fe7e3b..294b310d67 100644 --- a/doc/lispintro/Makefile.in +++ b/doc/lispintro/Makefile.in @@ -119,6 +119,7 @@ infoclean: $(buildinfodir)/eintr.info-[1-9] bootstrap-clean maintainer-clean: distclean infoclean + rm -f TAGS .PHONY: install-dvi install-html install-pdf install-ps install-doc @@ -166,5 +167,20 @@ uninstall-pdf: uninstall-doc: uninstall-dvi uninstall-html uninstall-pdf uninstall-ps +ETAGS = ../../lib-src/etags${EXEEXT} + +${ETAGS}: FORCE + $(MAKE) -C $(dir $@) $(notdir $@) + +texifiles = $(wildcard ${srcdir}/*.texi) + +TAGS: ${ETAGS} $(texifiles) + $(AM_V_GEN)${ETAGS} $(texifiles) + +tags: TAGS +.PHONY: tags + +FORCE: +.PHONY: FORCE ### Makefile ends here diff --git a/doc/lispref/Makefile.in b/doc/lispref/Makefile.in index 876303593c..a7701c5f98 100644 --- a/doc/lispref/Makefile.in +++ b/doc/lispref/Makefile.in @@ -180,6 +180,7 @@ infoclean: $(buildinfodir)/elisp.info-[1-9][0-9] bootstrap-clean maintainer-clean: distclean infoclean + rm -f TAGS .PHONY: install-dvi install-html install-pdf install-ps install-doc @@ -227,5 +228,20 @@ uninstall-pdf: uninstall-doc: uninstall-dvi uninstall-html uninstall-pdf uninstall-ps +ETAGS = ../../lib-src/etags${EXEEXT} + +${ETAGS}: FORCE + $(MAKE) -C $(dir $@) $(notdir $@) + +texifiles = $(wildcard ${srcdir}/*.texi) + +TAGS: ${ETAGS} $(texifiles) + $(AM_V_GEN)${ETAGS} $(texifiles) + +tags: TAGS +.PHONY: tags + +FORCE: +.PHONY: FORCE ### Makefile ends here diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in index 5130650fef..63d4bf0337 100644 --- a/doc/misc/Makefile.in +++ b/doc/misc/Makefile.in @@ -287,6 +287,7 @@ orgclean: rm -f ${TEXI_FROM_ORG} bootstrap-clean maintainer-clean: distclean infoclean orgclean + rm -f TAGS .PHONY: install-dvi install-html install-pdf install-ps install-doc @@ -336,4 +337,20 @@ uninstall-pdf: uninstall-doc: uninstall-dvi uninstall-html uninstall-pdf uninstall-ps +ETAGS = ../../lib-src/etags${EXEEXT} + +${ETAGS}: FORCE + $(MAKE) -C $(dir $@) $(notdir $@) + +texifiles = $(wildcard ${srcdir}/*.texi) + +TAGS: ${ETAGS} $(texifiles) + $(AM_V_GEN)${ETAGS} $(texifiles) + +tags: TAGS +.PHONY: tags + +FORCE: +.PHONY: FORCE + ### Makefile ends here commit 222d70333f2cfeefa6c3430fc54714bd122cc779 Author: Philipp Stephani Date: Thu Mar 11 11:05:32 2021 +0100 * src/image.c (image_set_transform): Don't use ! for Lisp object. diff --git a/src/image.c b/src/image.c index 025ee72703..6d493f6cdd 100644 --- a/src/image.c +++ b/src/image.c @@ -2234,7 +2234,7 @@ image_set_transform (struct frame *f, struct image *img) TODO: implement for Windows. */ bool smoothing; Lisp_Object s = image_spec_value (img->spec, QCtransform_smoothing, NULL); - if (!s) + if (NILP (s)) smoothing = (width < img->width) || (height < img->height); else smoothing = !NILP (s); commit 9ab51428cd53f1e3160fad85c952b956d18ed442 Author: Philipp Stephani Date: Thu Mar 11 11:04:57 2021 +0100 * src/image.c (FRAME_SCALE_FACTOR): Define only when needed. diff --git a/src/image.c b/src/image.c index 485e08a66e..025ee72703 100644 --- a/src/image.c +++ b/src/image.c @@ -135,11 +135,13 @@ typedef struct ns_bitmap_record Bitmap_Record; # define COLOR_TABLE_SUPPORT 1 #endif +#ifdef HAVE_RSVG #if defined HAVE_NS # define FRAME_SCALE_FACTOR(f) ns_frame_scale_factor (f) #else # define FRAME_SCALE_FACTOR(f) 1; #endif +#endif static void image_disable_image (struct frame *, struct image *); static void image_edge_detection (struct frame *, struct image *, Lisp_Object, commit 0445720b75edc8ff06074750512ade3d0e667575 Author: Eli Zaretskii Date: Thu Mar 11 08:37:29 2021 +0200 Fix wording of a recently added documentation * etc/NEWS: * doc/lispref/display.texi (Image Descriptors): Fix wording of the description of :transform-smoothing. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 6dfbabb2b6..9723376de9 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -5393,15 +5393,14 @@ values rotate clockwise, negative values counter-clockwise. Rotation is performed after scaling and cropping. @item :transform-smoothing @var{smooth} -When @code{t} any image transform will have smoothing applied, and if -@code{nil} no smoothing will be applied. The exact algorithm used -will be platform dependent, but should be equivalent to bilinear -filtering. Disabling smoothing will use a nearest neighbor +If this is @code{t}, any image transform will have smoothing applied; +if @code{nil}, no smoothing will be applied. The exact algorithm used +is platform dependent, but should be equivalent to bilinear +filtering. Disabling smoothing will use the nearest neighbor algorithm. -The default, if this property is not specified, will be for -down-scaling to apply smoothing, and up-scaling to not apply -smoothing. +The default, if this property is not specified, is for down-scaling to +apply smoothing, and for up-scaling to not apply smoothing. @item :index @var{frame} @xref{Multi-Frame Images}. diff --git a/etc/NEWS b/etc/NEWS index ac092675b4..b3f4ade337 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1477,7 +1477,7 @@ background colors or transparency, such as xbm, pbm, svg, png and gif. *** Image smoothing can now be explicitly enabled or disabled. Smoothing applies a bilinear filter while scaling or rotating an image to prevent aliasing and other unwanted effects. The new image -property ':transform-smoothing' can be set to t to enable smoothing +property ':transform-smoothing' can be set to t to force smoothing and nil to disable smoothing. The default behaviour of smoothing on down-scaling and not smoothing commit 8497af6892fcf9b08a1c120e897c9f5c21ea64fa Author: Stefan Monnier Date: Thu Mar 11 01:14:30 2021 -0500 * lisp/gnus/nnmh.el (nnmh-newsgroup-articles): Declare var Reported by Barry Fishman . Along the way, I checked other variables which are similarly let-bound to nil and then read with any intervening assignment, which found another similar case of missing `defvar`s plus a bit of dead code. * lisp/gnus/gnus-kill.el (gnus-apply-kill-file-internal): Remove constant nil var `beg`. * lisp/gnus/gnus-search.el (gnus-search-query-parse-kv): Remove constant nil var `return`. * lisp/gnus/gnus-start.el (gnus-ask-server-for-new-groups): Remove constant nil var `group`. (gnus-killed-assoc, gnus-marked-assoc, gnus-newsrc-assoc): Declare vars. * lisp/gnus/gnus-sum.el (gnus-compute-read-articles): Remove constant nil var `first`. * lisp/gnus/nnbabyl.el (nnbabyl-request-accept-article): Remove constant nil var `beg`. * lisp/gnus/nnfolder.el (nnfolder-possibly-change-group): Remove constant nil var `inf`. * lisp/gnus/nnrss.el (nnrss-request-article): Remove constant nil var `err`. diff --git a/lisp/gnus/gnus-kill.el b/lisp/gnus/gnus-kill.el index b0e6cb59d5..f73627a648 100644 --- a/lisp/gnus/gnus-kill.el +++ b/lisp/gnus/gnus-kill.el @@ -337,7 +337,7 @@ Returns the number of articles marked as read." (gnus-newsgroup-kill-file gnus-newsgroup-name))) (unreads (length gnus-newsgroup-unreads)) (gnus-summary-inhibit-highlight t) - beg) + ) ;; beg (setq gnus-newsgroup-kill-headers nil) ;; If there are any previously scored articles, we remove these ;; from the `gnus-newsgroup-headers' list that the score functions @@ -381,7 +381,7 @@ Returns the number of articles marked as read." (gnus-set-mode-line 'summary) - (if beg + (if nil ;; beg (let ((nunreads (- unreads (length gnus-newsgroup-unreads)))) (or (eq nunreads 0) (gnus-message 6 "Marked %d articles as read" nunreads)) diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el index 339bff9d67..61a1d67524 100644 --- a/lisp/gnus/gnus-search.el +++ b/lisp/gnus/gnus-search.el @@ -549,7 +549,7 @@ structure. In the simplest case, they are simply consed together. String KEY is converted to a symbol." - (let (return) + (let () ;; return (cond ((member key gnus-search-date-keys) (when (string= "after" key) @@ -559,7 +559,7 @@ KEY is converted to a symbol." (setq value (gnus-search-query-parse-mark value))) ((string= "message-id" key) (setq key "id"))) - (or return + (or nil ;; return (cons (intern key) value)))) (defun gnus-search-query-parse-date (value &optional rel-date) diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el index a6b362e083..44e97d5484 100644 --- a/lisp/gnus/gnus-start.el +++ b/lisp/gnus/gnus-start.el @@ -1172,7 +1172,7 @@ for new groups, and subscribe the new groups as zombies." gnus-check-new-newsgroups) gnus-secondary-select-methods)))) (groups 0) - group new-newsgroups got-new method hashtb + new-newsgroups got-new method hashtb ;; group gnus-override-subscribe-method) (unless gnus-killed-hashtb (gnus-make-hashtable-from-killed)) @@ -1203,14 +1203,14 @@ for new groups, and subscribe the new groups as zombies." (cond ((eq do-sub 'subscribe) (cl-incf groups) - (puthash g-name group gnus-killed-hashtb) + (puthash g-name nil gnus-killed-hashtb) ;; group (gnus-call-subscribe-functions gnus-subscribe-options-newsgroup-method g-name)) ((eq do-sub 'ignore) nil) (t (cl-incf groups) - (puthash g-name group gnus-killed-hashtb) + (puthash g-name nil gnus-killed-hashtb) ;; group (if gnus-subscribe-hierarchical-interactive (push g-name new-newsgroups) (gnus-call-subscribe-functions @@ -2378,6 +2378,11 @@ If FORCE is non-nil, the .newsrc file is read." (unless (gnus-yes-or-no-p (concat errmsg "; continue? ")) (error "%s" errmsg))))))))) +;; IIUC these 3 vars were used in older .newsrc files. +(defvar gnus-killed-assoc) +(defvar gnus-marked-assoc) +(defvar gnus-newsrc-assoc) + (defun gnus-read-newsrc-el-file (file) (let ((ding-file (concat file "d"))) (when (file-exists-p ding-file) diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index bf58cf419a..97da550353 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -6354,9 +6354,9 @@ The resulting hash table is returned, or nil if no Xrefs were found." ;; First peel off all invalid article numbers. (when active (let ((ids articles) - id first) + id) ;; first (while (setq id (pop ids)) - (when (and first (> id (cdr active))) + (when nil ;; (and first (> id (cdr active))) ;; We'll end up in this situation in one particular ;; obscure situation. If you re-scan a group and get ;; a new article that is cross-posted to a different diff --git a/lisp/gnus/nnbabyl.el b/lisp/gnus/nnbabyl.el index 3e6f9e88ee..5f486f4970 100644 --- a/lisp/gnus/nnbabyl.el +++ b/lisp/gnus/nnbabyl.el @@ -323,7 +323,7 @@ (nnbabyl-possibly-change-newsgroup group server) (nnmail-check-syntax) (let ((buf (current-buffer)) - result beg) + result) ;; beg (and (nnmail-activate 'nnbabyl) (save-excursion @@ -331,7 +331,7 @@ (search-forward "\n\n" nil t) (forward-line -1) (save-excursion - (while (re-search-backward "^X-Gnus-Newsgroup: " beg t) + (while (re-search-backward "^X-Gnus-Newsgroup: " nil t) ;; beg (delete-region (point) (progn (forward-line 1) (point))))) (when nnmail-cache-accepted-message-ids (nnmail-cache-insert (nnmail-fetch-field "message-id") diff --git a/lisp/gnus/nnfolder.el b/lisp/gnus/nnfolder.el index 1dd784d5a5..2de5b83a7b 100644 --- a/lisp/gnus/nnfolder.el +++ b/lisp/gnus/nnfolder.el @@ -706,7 +706,7 @@ deleted. Point is left where the deleted region was." (if dont-check (setq nnfolder-current-group group nnfolder-current-buffer nil) - (let (inf file) + (let (file) ;; inf ;; If we have to change groups, see if we don't already have ;; the folder in memory. If we do, verify the modtime and ;; destroy the folder if needed so we can rescan it. @@ -718,7 +718,7 @@ deleted. Point is left where the deleted region was." ;; touched the file since last time. (when (and nnfolder-current-buffer (not (gnus-buffer-live-p nnfolder-current-buffer))) - (setq nnfolder-buffer-alist (delq inf nnfolder-buffer-alist) + (setq nnfolder-buffer-alist (delq nil nnfolder-buffer-alist) ;; inf nnfolder-current-buffer nil)) (setq nnfolder-current-group group) diff --git a/lisp/gnus/nnmh.el b/lisp/gnus/nnmh.el index 231583fae8..0923b8eff3 100644 --- a/lisp/gnus/nnmh.el +++ b/lisp/gnus/nnmh.el @@ -503,6 +503,8 @@ as unread by Gnus.") (setcdr active (1+ (cdr active)))) (cdr active))) +(defvar nnmh-newsgroup-articles) + (defun nnmh-update-gnus-unreads (group) ;; Go through the .nnmh-articles file and compare with the actual ;; articles in this folder. The articles that are "new" will be diff --git a/lisp/gnus/nnrss.el b/lisp/gnus/nnrss.el index aa7c8e584a..36b7af0e34 100644 --- a/lisp/gnus/nnrss.el +++ b/lisp/gnus/nnrss.el @@ -200,7 +200,7 @@ for decoding when the cdr that the data specify is not available.") (nnrss-possibly-change-group group server) (let ((e (assq article nnrss-group-data)) (nntp-server-buffer (or buffer nntp-server-buffer)) - err) ;; post + ) ;; err post (when e (with-current-buffer nntp-server-buffer (erase-buffer) @@ -302,8 +302,7 @@ for decoding when the cdr that the data specify is not available.") (when nnrss-content-function (funcall nnrss-content-function e group article)))) (cond - (err - (nnheader-report 'nnrss err)) + ;; (err (nnheader-report 'nnrss err)) ((not e) (nnheader-report 'nnrss "no such id: %d" article)) (t commit f695fdfef7d8e9ea4e0e17b69e0a28f952db55d6 Author: Basil L. Contovounesios Date: Wed Mar 10 23:28:28 2021 +0000 ; Fix US spelling in last change. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 3d91ed2764..6dfbabb2b6 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -5396,7 +5396,7 @@ is performed after scaling and cropping. When @code{t} any image transform will have smoothing applied, and if @code{nil} no smoothing will be applied. The exact algorithm used will be platform dependent, but should be equivalent to bilinear -filtering. Disabling smoothing will use a nearest neighbour +filtering. Disabling smoothing will use a nearest neighbor algorithm. The default, if this property is not specified, will be for diff --git a/src/image.c b/src/image.c index 95ae573354..485e08a66e 100644 --- a/src/image.c +++ b/src/image.c @@ -2225,7 +2225,7 @@ image_set_transform (struct frame *f, struct image *img) compute_image_rotation (img, &rotation); # if defined USE_CAIRO || defined HAVE_XRENDER || defined HAVE_NS - /* We want scale up operations to use a nearest neighbour filter to + /* We want scale up operations to use a nearest neighbor filter to show real pixels instead of munging them, but scale down operations to use a blended filter, to avoid aliasing and the like. commit c93447eac6f801d7ff97ed6dad368dc49d55cc46 Author: Alan Third Date: Tue Mar 9 18:05:10 2021 +0000 Enable selectable image smoothing (bug#38394) * lisp/doc-view.el (doc-view-insert-image): Always use smoothing in docview. * lisp/image-mode.el (image-transform-smoothing): New variable. (image-mode-map): Add smoothing binding. (image-transform-properties): Apply smoothing when requested. (image-transform-set-smoothing): New function. (image-transform-reset): Reset smoothing. * src/image.c (image_set_transform): Use new :transform-smoothing attribute. (syms_of_image): Add :transform-smoothing attribute. * doc/lispref/display.texi (Image Descriptors): Document new :transform-smoothing property. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 131ad2d9c8..3d91ed2764 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -5392,6 +5392,17 @@ are supported, unless the image type is @code{imagemagick}. Positive values rotate clockwise, negative values counter-clockwise. Rotation is performed after scaling and cropping. +@item :transform-smoothing @var{smooth} +When @code{t} any image transform will have smoothing applied, and if +@code{nil} no smoothing will be applied. The exact algorithm used +will be platform dependent, but should be equivalent to bilinear +filtering. Disabling smoothing will use a nearest neighbour +algorithm. + +The default, if this property is not specified, will be for +down-scaling to apply smoothing, and up-scaling to not apply +smoothing. + @item :index @var{frame} @xref{Multi-Frame Images}. diff --git a/etc/NEWS b/etc/NEWS index b48f7c3616..ac092675b4 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1473,6 +1473,16 @@ To load images with the default frame colors use the ':foreground' and This change only affects image types that support foreground and background colors or transparency, such as xbm, pbm, svg, png and gif. ++++ +*** Image smoothing can now be explicitly enabled or disabled. +Smoothing applies a bilinear filter while scaling or rotating an image +to prevent aliasing and other unwanted effects. The new image +property ':transform-smoothing' can be set to t to enable smoothing +and nil to disable smoothing. + +The default behaviour of smoothing on down-scaling and not smoothing +on up-scaling remains unchanged. + ** EWW +++ diff --git a/lisp/doc-view.el b/lisp/doc-view.el index f6fcfae453..cef09009d9 100644 --- a/lisp/doc-view.el +++ b/lisp/doc-view.el @@ -1439,6 +1439,8 @@ ARGS is a list of image descriptors." (apply #'create-image file doc-view--image-type nil args) (unless (member :width args) (setq args `(,@args :width ,doc-view-image-width))) + (unless (member :transform-smoothing args) + (setq args `(,@args :transform-smoothing t))) (apply #'create-image file doc-view--image-type nil args)))) (slice (doc-view-current-slice)) (img-width (and image (car (image-size image)))) diff --git a/lisp/image-mode.el b/lisp/image-mode.el index 7384abf3b2..8b61aa7e73 100644 --- a/lisp/image-mode.el +++ b/lisp/image-mode.el @@ -95,6 +95,9 @@ Its value should be one of the following: (defvar-local image-transform-rotation 0.0 "Rotation angle for the image in the current Image mode buffer.") +(defvar-local image-transform-smoothing nil + "Whether to use transform smoothing.") + (defvar image-transform-right-angle-fudge 0.0001 "Snap distance to a multiple of a right angle. There's no deep theory behind the default value, it should just @@ -457,6 +460,7 @@ call." (define-key map "sb" 'image-transform-fit-both) (define-key map "ss" 'image-transform-set-scale) (define-key map "sr" 'image-transform-set-rotation) + (define-key map "sm" 'image-transform-set-smoothing) (define-key map "so" 'image-transform-original) (define-key map "s0" 'image-transform-reset) @@ -523,6 +527,8 @@ call." :help "Rotate the image"] ["Set Rotation..." image-transform-set-rotation :help "Set rotation angle of the image"] + ["Set Smoothing..." image-transform-set-smoothing + :help "Toggle smoothing"] ["Original Size" image-transform-original :help "Reset image to actual size"] ["Reset to Default Size" image-transform-reset @@ -1474,7 +1480,10 @@ return value is suitable for appending to an image spec." ,@(when (cdr resized) (list :height (cdr resized))) ,@(unless (= 0.0 image-transform-rotation) - (list :rotation image-transform-rotation)))))) + (list :rotation image-transform-rotation)) + ,@(when image-transform-smoothing + (list :transform-smoothing + (string= image-transform-smoothing "smooth"))))))) (defun image-transform-set-scale (scale) "Prompt for a number, and resize the current image by that amount." @@ -1507,6 +1516,12 @@ ROTATION should be in degrees." (setq image-transform-rotation (float (mod rotation 360))) (image-toggle-display-image)) +(defun image-transform-set-smoothing (smoothing) + (interactive (list (completing-read "Smoothing: " + '("none" "smooth") nil t))) + (setq image-transform-smoothing smoothing) + (image-toggle-display-image)) + (defun image-transform-original () "Display the current image with the original (actual) size and rotation." (interactive) @@ -1519,7 +1534,8 @@ ROTATION should be in degrees." (interactive) (setq image-transform-resize image-auto-resize image-transform-rotation 0.0 - image-transform-scale 1) + image-transform-scale 1 + image-transform-smoothing nil) (image-toggle-display-image)) (provide 'image-mode) diff --git a/src/image.c b/src/image.c index 8137dbea8d..95ae573354 100644 --- a/src/image.c +++ b/src/image.c @@ -2230,7 +2230,12 @@ image_set_transform (struct frame *f, struct image *img) operations to use a blended filter, to avoid aliasing and the like. TODO: implement for Windows. */ - bool scale_down = (width < img->width) || (height < img->height); + bool smoothing; + Lisp_Object s = image_spec_value (img->spec, QCtransform_smoothing, NULL); + if (!s) + smoothing = (width < img->width) || (height < img->height); + else + smoothing = !NILP (s); # endif /* Perform scale transformation. */ @@ -2344,13 +2349,13 @@ image_set_transform (struct frame *f, struct image *img) /* Under NS the transform is applied to the drawing surface at drawing time, so store it for later. */ ns_image_set_transform (img->pixmap, matrix); - ns_image_set_smoothing (img->pixmap, scale_down); + ns_image_set_smoothing (img->pixmap, smoothing); # elif defined USE_CAIRO cairo_matrix_t cr_matrix = {matrix[0][0], matrix[0][1], matrix[1][0], matrix[1][1], matrix[2][0], matrix[2][1]}; cairo_pattern_t *pattern = cairo_pattern_create_rgb (0, 0, 0); cairo_pattern_set_matrix (pattern, &cr_matrix); - cairo_pattern_set_filter (pattern, scale_down + cairo_pattern_set_filter (pattern, smoothing ? CAIRO_FILTER_BEST : CAIRO_FILTER_NEAREST); /* Dummy solid color pattern just to record pattern matrix. */ img->cr_data = pattern; @@ -2369,13 +2374,13 @@ image_set_transform (struct frame *f, struct image *img) XDoubleToFixed (matrix[2][2])}}}; XRenderSetPictureFilter (FRAME_X_DISPLAY (f), img->picture, - scale_down ? FilterBest : FilterNearest, 0, 0); + smoothing ? FilterBest : FilterNearest, 0, 0); XRenderSetPictureTransform (FRAME_X_DISPLAY (f), img->picture, &tmat); if (img->mask_picture) { XRenderSetPictureFilter (FRAME_X_DISPLAY (f), img->mask_picture, - scale_down ? FilterBest : FilterNearest, 0, 0); + smoothing ? FilterBest : FilterNearest, 0, 0); XRenderSetPictureTransform (FRAME_X_DISPLAY (f), img->mask_picture, &tmat); } @@ -10693,6 +10698,7 @@ non-numeric, there is no explicit limit on the size of images. */); DEFSYM (QCrotation, ":rotation"); DEFSYM (QCmatrix, ":matrix"); DEFSYM (QCscale, ":scale"); + DEFSYM (QCtransform_smoothing, ":transform-smoothing"); DEFSYM (QCcolor_adjustment, ":color-adjustment"); DEFSYM (QCmask, ":mask"); commit d07ed6dfee9338b0d715f8181703252c99e5133a Author: Juri Linkov Date: Wed Mar 10 20:09:23 2021 +0200 * lisp/tab-bar.el (tab-bar-close-group-tabs): New command. (tab-close-group): New alias. (tab-bar-close-other-tabs): Rewrite to fix old bug where regardless of the returned value from tab-bar-tab-prevent-close-functions, only one tab was retained. diff --git a/etc/NEWS b/etc/NEWS index b5ee78893c..b48f7c3616 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -542,6 +542,7 @@ It also supports a negative argument. --- *** 'C-x t G' assigns a group name to the tab. +'tab-close-group' can close all tabs that belong to the selected group. --- *** New user option 'tab-bar-tab-name-format-function'. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index bc89a11422..66f8ccae47 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -1148,22 +1148,25 @@ for the last tab on a frame is determined by "Close all tabs on the selected frame, except the selected one." (interactive) (let* ((tabs (funcall tab-bar-tabs-function)) - (current-index (tab-bar--current-tab-index tabs))) - (when current-index - (dotimes (index (length tabs)) - (unless (or (eq index current-index) + (current-index (tab-bar--current-tab-index tabs)) + (current-tab (and current-index (nth current-index tabs))) + (index 0)) + (when current-tab + (dolist (tab tabs) + (unless (or (eq tab current-tab) (run-hook-with-args-until-success - 'tab-bar-tab-prevent-close-functions - (nth index tabs) + 'tab-bar-tab-prevent-close-functions tab ;; `last-tab-p' logically can't ever be true ;; if we make it this far nil)) (push `((frame . ,(selected-frame)) (index . ,index) - (tab . ,(nth index tabs))) + (tab . ,tab)) tab-bar-closed-tabs) - (run-hook-with-args 'tab-bar-tab-pre-close-functions (nth index tabs) nil))) - (set-frame-parameter nil 'tabs (list (nth current-index tabs))) + (run-hook-with-args 'tab-bar-tab-pre-close-functions tab nil) + (setq tabs (delq tab tabs))) + (setq index (1+ index))) + (set-frame-parameter nil 'tabs tabs) ;; Recalculate tab-bar-lines and update frames (tab-bar--update-tab-bar-lines) @@ -1277,6 +1280,32 @@ If GROUP-NAME is the empty string, then remove the tab from any group." (unless tab-bar-mode (message "Set tab group to '%s'" group-new-name)))) +(defun tab-bar-close-group-tabs (group-name) + "Close all tabs that belong to GROUP-NAME on the selected frame." + (interactive + (let* ((tabs (funcall tab-bar-tabs-function)) + (tab-index (1+ (tab-bar--current-tab-index tabs))) + (group-name (alist-get 'group (nth (1- tab-index) tabs)))) + (list (completing-read + "Close all tabs with group name: " + (delete-dups (delq nil (cons group-name + (mapcar (lambda (tab) + (alist-get 'group tab)) + (funcall tab-bar-tabs-function))))))))) + (let* ((close-group (and (> (length group-name) 0) group-name)) + (tab-bar-tab-prevent-close-functions + (cons (lambda (tab _last-tab-p) + (not (equal (alist-get 'group tab) close-group))) + tab-bar-tab-prevent-close-functions))) + (tab-bar-close-other-tabs) + + (let* ((tabs (funcall tab-bar-tabs-function)) + (current-index (tab-bar--current-tab-index tabs)) + (current-tab (and current-index (nth current-index tabs)))) + (when (and current-tab (equal (alist-get 'group current-tab) + close-group)) + (tab-bar-close-tab))))) + ;;; Tab history mode @@ -1807,6 +1836,7 @@ When `switch-to-buffer-obey-display-actions' is non-nil, (defalias 'tab-duplicate 'tab-bar-duplicate-tab) (defalias 'tab-close 'tab-bar-close-tab) (defalias 'tab-close-other 'tab-bar-close-other-tabs) +(defalias 'tab-close-group 'tab-bar-close-group-tabs) (defalias 'tab-undo 'tab-bar-undo-close-tab) (defalias 'tab-select 'tab-bar-select-tab) (defalias 'tab-switch 'tab-bar-switch-to-tab) commit 5fa2775c0cab746d49aa0bcc96ecdcff23a9ba05 Author: Juri Linkov Date: Wed Mar 10 19:57:48 2021 +0200 * lisp/tab-bar.el: 'C-x t G' (tab-group) assigns a group name to the tab. * lisp/tab-bar.el (tab-bar--tab, tab-bar--current-tab): Add tab group if any. (tab-bar-change-tab-group): New command. (display-buffer-in-new-tab): Handle tab-group alist entry. (tab-group): New alias. (tab-prefix-map): Bind "G" to 'tab-group'. diff --git a/etc/NEWS b/etc/NEWS index d667bcd3b0..b5ee78893c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -540,6 +540,9 @@ It also supports a negative argument. *** 'C-x t M' moves the current tab to the specified absolute position. It also supports a negative argument. +--- +*** 'C-x t G' assigns a group name to the tab. + --- *** New user option 'tab-bar-tab-name-format-function'. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 2f97bd4eaf..bc89a11422 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -648,6 +648,7 @@ on the tab bar instead." (defun tab-bar--tab (&optional frame) (let* ((tab (assq 'current-tab (frame-parameter frame 'tabs))) (tab-explicit-name (alist-get 'explicit-name tab)) + (tab-group (alist-get 'group tab)) (bl (seq-filter #'buffer-live-p (frame-parameter frame 'buffer-list))) (bbl (seq-filter #'buffer-live-p (frame-parameter frame 'buried-buffer-list)))) `(tab @@ -655,6 +656,7 @@ on the tab bar instead." (alist-get 'name tab) (funcall tab-bar-tab-name-function))) (explicit-name . ,tab-explicit-name) + ,@(if tab-group `((group . ,tab-group))) (time . ,(float-time)) (ws . ,(window-state-get (frame-root-window (or frame (selected-frame))) 'writable)) @@ -670,12 +672,14 @@ on the tab bar instead." ;; necessary when switching tabs, otherwise the destination tab ;; inherits the current tab's `explicit-name' parameter. (let* ((tab (or tab (assq 'current-tab (frame-parameter frame 'tabs)))) - (tab-explicit-name (alist-get 'explicit-name tab))) + (tab-explicit-name (alist-get 'explicit-name tab)) + (tab-group (alist-get 'group tab))) `(current-tab (name . ,(if tab-explicit-name (alist-get 'name tab) (funcall tab-bar-tab-name-function))) - (explicit-name . ,tab-explicit-name)))) + (explicit-name . ,tab-explicit-name) + ,@(if tab-group `((group . ,tab-group)))))) (defun tab-bar--current-tab-index (&optional tabs frame) (seq-position (or tabs (funcall tab-bar-tabs-function frame)) @@ -1239,6 +1243,40 @@ function `tab-bar-tab-name-function'." nil nil nil nil tab-name)))) (tab-bar-rename-tab new-name (1+ (tab-bar--tab-index-by-name tab-name)))) + +;;; Tab groups + +(defun tab-bar-change-tab-group (group-name &optional arg) + "Add the tab specified by its absolute position ARG to GROUP-NAME. +If no ARG is specified, then set the GROUP-NAME for the current tab. +ARG counts from 1. +If GROUP-NAME is the empty string, then remove the tab from any group." + (interactive + (let* ((tabs (funcall tab-bar-tabs-function)) + (tab-index (or current-prefix-arg (1+ (tab-bar--current-tab-index tabs)))) + (group-name (alist-get 'group (nth (1- tab-index) tabs)))) + (list (completing-read + "Group name for tab (leave blank to remove group): " + (delete-dups (delq nil (cons group-name + (mapcar (lambda (tab) + (alist-get 'group tab)) + (funcall tab-bar-tabs-function)))))) + current-prefix-arg))) + (let* ((tabs (funcall tab-bar-tabs-function)) + (tab-index (if arg + (1- (max 0 (min arg (length tabs)))) + (tab-bar--current-tab-index tabs))) + (tab (nth tab-index tabs)) + (group (assq 'group tab)) + (group-new-name (and (> (length group-name) 0) group-name))) + (if group + (setcdr group group-new-name) + (nconc tab `((group . ,group-new-name)))) + + (force-mode-line-update) + (unless tab-bar-mode + (message "Set tab group to '%s'" group-new-name)))) + ;;; Tab history mode @@ -1630,6 +1668,8 @@ a function, then it is called with two arguments: BUFFER and ALIST, and should return the tab name. When a `tab-name' entry is omitted, create a new tab without an explicit name. +The ALIST entry `tab-group' (string or function) defines the tab group. + If ALIST contains a `reusable-frames' entry, its value determines which frames to search for a reusable tab: nil -- the selected frame (actually the last non-minibuffer frame) @@ -1682,6 +1722,8 @@ then it is called with two arguments: BUFFER and ALIST, and should return the tab name. When a `tab-name' entry is omitted, create a new tab without an explicit name. +The ALIST entry `tab-group' (string or function) defines the tab group. + This is an action function for buffer display, see Info node `(elisp) Buffer Display Action Functions'. It should be called only by `display-buffer' or a function directly or @@ -1693,6 +1735,11 @@ indirectly called by the latter." (setq tab-name (funcall tab-name buffer alist))) (when tab-name (tab-bar-rename-tab tab-name))) + (let ((tab-group (alist-get 'tab-group alist))) + (when (functionp tab-group) + (setq tab-group (funcall tab-group buffer alist))) + (when tab-group + (tab-bar-change-tab-group tab-group))) (window--display-buffer buffer (selected-window) 'tab alist))) (defun switch-to-buffer-other-tab (buffer-or-name &optional norecord) @@ -1770,6 +1817,7 @@ When `switch-to-buffer-obey-display-actions' is non-nil, (defalias 'tab-move 'tab-bar-move-tab) (defalias 'tab-move-to 'tab-bar-move-tab-to) (defalias 'tab-rename 'tab-bar-rename-tab) +(defalias 'tab-group 'tab-bar-change-tab-group) (defalias 'tab-list 'tab-switcher) (define-key tab-prefix-map "n" 'tab-duplicate) @@ -1782,6 +1830,7 @@ When `switch-to-buffer-obey-display-actions' is non-nil, (define-key tab-prefix-map "O" 'tab-previous) (define-key tab-prefix-map "m" 'tab-move) (define-key tab-prefix-map "M" 'tab-move-to) +(define-key tab-prefix-map "G" 'tab-group) (define-key tab-prefix-map "r" 'tab-rename) (define-key tab-prefix-map "\r" 'tab-switch) (define-key tab-prefix-map "b" 'switch-to-buffer-other-tab) commit 88409b21c23de13d0eac82f579cae9cc2f58d8b3 Author: Kévin Le Gouguec Date: Wed Mar 10 16:15:01 2021 +0100 Highlight the entire summary line for selected articles * lisp/gnus/gnus-sum.el (gnus-highlight-selected-summary): Highlight the entire summary line (bug#47026). diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index ee74f01393..bf58cf419a 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -12741,7 +12741,7 @@ If REVERSE, save parts that do not match TYPE." ;; so we highlight the entire line instead. (when (= (+ to 2) from) (setq from beg) - (setq to end)) + (setq to (1+ end))) (if gnus-newsgroup-selected-overlay ;; Move old overlay. (move-overlay @@ -12796,7 +12796,7 @@ If REVERSE, save parts that do not match TYPE." (let ((face (funcall (gnus-summary-highlight-line-0)))) (unless (eq face (gnus-get-text-property-excluding-characters-with-faces beg 'face)) (gnus-put-text-property-excluding-characters-with-faces - beg (point-at-eol) 'face + beg (1+ (point-at-eol)) 'face (setq face (if (boundp face) (symbol-value face) face))) (when gnus-summary-highlight-line-function (funcall gnus-summary-highlight-line-function article face)))))) commit b4ae1024832bf95fb957baf6f464d67b5a4972b6 Author: Stefan Kangas Date: Wed Mar 10 15:52:07 2021 +0100 Remove Emacs 19 workaround from cperl-mode.el * lisp/progmodes/cperl-mode.el (cperl-make-indent): Remove Emacs 19 workaround. diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index 6b22228397..649eff19cf 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -907,22 +907,12 @@ In regular expressions (including character classes): (defun cperl-make-indent (column &optional minimum keep) - "Makes indent of the current line the requested amount. -Unless KEEP, removes the old indentation. Works around a bug in ancient -versions of Emacs." - (let ((prop (get-text-property (point) 'syntax-type))) - (or keep - (delete-horizontal-space)) - (indent-to column minimum) - ;; In old versions (e.g., 19.33) `indent-to' would not inherit properties - (and prop - (> (current-column) 0) - (save-excursion - (beginning-of-line) - (or (get-text-property (point) 'syntax-type) - (and (looking-at "\\=[ \t]") - (put-text-property (point) (match-end 0) - 'syntax-type prop))))))) + "Indent from point with tabs and spaces until COLUMN is reached. +MINIMUM is like in `indent-to', which see. +Unless KEEP, removes the old indentation." + (or keep + (delete-horizontal-space)) + (indent-to column minimum)) ;; Probably it is too late to set these guys already, but it can help later: commit 4b47eb32c6a45ac9f4d4895c1a6dd6db441baafb Author: Lars Ingebrigtsen Date: Wed Mar 10 15:52:36 2021 +0100 Fix byte-compilation warning in benchmark-run * lisp/emacs-lisp/benchmark.el (benchmark-run): Avoid a byte-compilation warning about an empty let body (bug#46819). diff --git a/lisp/emacs-lisp/benchmark.el b/lisp/emacs-lisp/benchmark.el index 14bc281739..2a3efbe5a1 100644 --- a/lisp/emacs-lisp/benchmark.el +++ b/lisp/emacs-lisp/benchmark.el @@ -62,7 +62,8 @@ See also `benchmark-run-compiled'." ;; Take account of the loop overhead. `(- (benchmark-elapse (dotimes (,i ,repetitions) ,@forms)) - (benchmark-elapse (dotimes (,i ,repetitions)))) + (benchmark-elapse (dotimes (,i ,repetitions) + nil))) `(benchmark-elapse ,@forms)) (- gcs-done ,gcs) (- gc-elapsed ,gc))))) commit a412141c9d67bb4a66c9b2050be1275436da89fd Author: Stefan Kangas Date: Wed Mar 10 15:10:24 2021 +0100 * lisp/files.el (cd): Improve error message. diff --git a/lisp/files.el b/lisp/files.el index e5fa1d8b22..2868be77f2 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -823,7 +823,9 @@ The path separator is colon in GNU and GNU-like systems." (expand-file-name dir)) (locate-file dir cd-path nil (lambda (f) (and (file-directory-p f) 'dir-ok))) - (error "No such directory found via CDPATH environment variable")))) + (if (getenv "CDPATH") + (error "No such directory found via CDPATH environment variable: %s" dir) + (error "No such directory: %s" dir))))) (defun directory-files-recursively (dir regexp &optional include-directories predicate commit 7add3309035394340b9d75d12c7e5412a3c96690 Author: Mattias Engdegård Date: Wed Mar 10 14:08:41 2021 +0100 Mark string predicates side-effect-free * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Add string>, string-greaterp, string-empty-p, string-prefix-p, string-suffix-p and string-blank-p, all recently marked pure. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index b3325816c5..db8d825cfe 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -1327,6 +1327,8 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") radians-to-degrees rassq rassoc read-from-string regexp-opt regexp-quote region-beginning region-end reverse round sin sqrt string string< string= string-equal string-lessp + string> string-greaterp string-empty-p + string-prefix-p string-suffix-p string-blank-p string-search string-to-char string-to-number string-to-syntax substring sxhash sxhash-equal sxhash-eq sxhash-eql commit a1c84b4308b509c2215fe19f8c8754d76413d43c Author: Stefan Kangas Date: Wed Mar 10 05:45:47 2021 +0100 Remove several references to Emacs 22 and earlier * admin/charsets/mapfiles/README: * doc/emacs/custom.texi (Saving Customizations): * doc/lispintro/emacs-lisp-intro.texi (Simple Extension): * doc/misc/efaq-w32.texi (Location of init file): * doc/misc/gnus-faq.texi (FAQ 1-3): * doc/misc/gnus.texi (Top, Various, Image Enhancements): * lisp/erc/erc-menu.el (menu): * lisp/progmodes/cfengine.el (cfengine-fill-paragraph): Remove some references to Emacs 22 and earlier. * doc/lispref/buffers.texi: * doc/lispref/eval.texi: * doc/lispref/files.texi: * doc/lispref/keymaps.texi: * doc/lispref/loading.texi: * doc/lispref/minibuf.texi: * doc/lispref/positions.texi: * doc/lispref/variables.texi: Remove comments about "Emacs 19 specific" features. diff --git a/admin/charsets/mapfiles/README b/admin/charsets/mapfiles/README index 60f09125a9..fb078269d6 100644 --- a/admin/charsets/mapfiles/README +++ b/admin/charsets/mapfiles/README @@ -63,8 +63,8 @@ to "JIS X 0213:2004". * MULE-*.map -Created by using ../mule-charsets.el in Emacs 22 as this: - % emacs-22 -batch -l ../mule-charsets.el +Created by using ../mule-charsets.el in Emacs as this: + % emacs -batch -l ../mule-charsets.el This file is part of GNU Emacs. diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi index 22900c5739..bd505d27ec 100644 --- a/doc/emacs/custom.texi +++ b/doc/emacs/custom.texi @@ -388,15 +388,15 @@ file. For example: Emacs versions, like this: @example -(cond ((< emacs-major-version 22) - ;; @r{Emacs 21 customization.} - (setq custom-file "~/.config/custom-21.el")) - ((and (= emacs-major-version 22) +(cond ((< emacs-major-version 28) + ;; @r{Emacs 27 customization.} + (setq custom-file "~/.config/custom-27.el")) + ((and (= emacs-major-version 26) (< emacs-minor-version 3)) - ;; @r{Emacs 22 customization, before version 22.3.} - (setq custom-file "~/.config/custom-22.el")) + ;; @r{Emacs 26 customization, before version 26.3.} + (setq custom-file "~/.config/custom-26.el")) (t - ;; @r{Emacs version 22.3 or later.} + ;; @r{Emacs version 28.1 or later.} (setq custom-file "~/.config/emacs-custom.el"))) (load custom-file) diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index d5c280b792..5b15a456ff 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -17532,10 +17532,9 @@ Here is the definition: @need 1250 Now for the keybinding. -Nowadays, function keys as well as mouse button events and -non-@sc{ascii} characters are written within square brackets, without -quotation marks. (In Emacs version 18 and before, you had to write -different function key bindings for each different make of terminal.) +Function keys as well as mouse button events and non-@sc{ascii} +characters are written within square brackets, without quotation +marks. I bind @code{line-to-top-of-window} to my @key{F6} function key like this: @@ -17550,18 +17549,18 @@ Your Init File, emacs, The GNU Emacs Manual}. @cindex Conditional 'twixt two versions of Emacs @cindex Version of Emacs, choosing @cindex Emacs version, choosing -If you run two versions of GNU Emacs, such as versions 22 and 23, and +If you run two versions of GNU Emacs, such as versions 27 and 28, and use one @file{.emacs} file, you can select which code to evaluate with the following conditional: @smallexample @group (cond - ((= 22 emacs-major-version) - ;; evaluate version 22 code + ((= 27 emacs-major-version) + ;; evaluate version 27 code ( @dots{} )) - ((= 23 emacs-major-version) - ;; evaluate version 23 code + ((= 28 emacs-major-version) + ;; evaluate version 28 code ( @dots{} ))) @end group @end smallexample diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi index 69733f91c4..0d31b0bc4c 100644 --- a/doc/lispref/buffers.texi +++ b/doc/lispref/buffers.texi @@ -309,7 +309,6 @@ foo This function renames the current buffer to @var{newname}. An error is signaled if @var{newname} is not a string. -@c Emacs 19 feature Ordinarily, @code{rename-buffer} signals an error if @var{newname} is already in use. However, if @var{unique} is non-@code{nil}, it modifies @var{newname} to make a name that is not in use. Interactively, you can @@ -344,7 +343,6 @@ a name. For example: See also the function @code{get-buffer-create} in @ref{Creating Buffers}. @end defun -@c Emacs 19 feature @defun generate-new-buffer-name starting-name &optional ignore This function returns a name that would be unique for a new buffer---but does not create the buffer. It starts with @var{starting-name}, and @@ -879,7 +877,6 @@ then @code{other-buffer} uses that predicate to decide which buffers to consider. It calls the predicate once for each buffer, and if the value is @code{nil}, that buffer is ignored. @xref{Buffer Parameters}. -@c Emacs 19 feature If @var{visible-ok} is @code{nil}, @code{other-buffer} avoids returning a buffer visible in any window on any visible frame, except as a last resort. If @var{visible-ok} is non-@code{nil}, then it does not matter diff --git a/doc/lispref/eval.texi b/doc/lispref/eval.texi index 80e038c96d..448b8ae17a 100644 --- a/doc/lispref/eval.texi +++ b/doc/lispref/eval.texi @@ -332,7 +332,6 @@ or just The built-in function @code{indirect-function} provides an easy way to perform symbol function indirection explicitly. -@c Emacs 19 feature @defun indirect-function function &optional noerror @anchor{Definition of indirect-function} This function returns the meaning of @var{function} as a function. If diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index 4110c51099..2828b50cad 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -455,7 +455,6 @@ Even though this is not a normal hook, you can use @code{add-hook} and @code{remove-hook} to manipulate the list. @xref{Hooks}. @end defvar -@c Emacs 19 feature @defvar write-contents-functions This works just like @code{write-file-functions}, but it is intended for hooks that pertain to the buffer's contents, not to the particular @@ -486,7 +485,6 @@ this hook to make sure the file you are saving has the current year in its copyright notice. @end defopt -@c Emacs 19 feature @defopt after-save-hook This normal hook runs after a buffer has been saved in its visited file. @end defopt @@ -622,7 +620,6 @@ If @var{start} is @code{nil}, then the command writes the entire buffer contents (@emph{not} just the accessible portion) to the file and ignores @var{end}. -@c Emacs 19 feature If @var{start} is a string, then @code{write-region} writes or appends that string, rather than text from the buffer. @var{end} is ignored in this case. @@ -653,7 +650,6 @@ It also sets the last file modification time for the current buffer to feature is used by @code{save-buffer}, but you probably should not use it yourself. -@c Emacs 19 feature If @var{visit} is a string, it specifies the file name to visit. This way, you can write the data to one file (@var{filename}) while recording the buffer as visiting another file (@var{visit}). The argument @@ -3094,7 +3090,6 @@ which generate the listing with Lisp code. @node Create/Delete Dirs @section Creating, Copying and Deleting Directories @cindex creating, copying and deleting directories -@c Emacs 19 features Most Emacs Lisp file-manipulation functions get errors when used on files that are directories. For example, you cannot delete a directory diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi index 6a227e3a79..dabf985018 100644 --- a/doc/lispref/keymaps.texi +++ b/doc/lispref/keymaps.texi @@ -369,7 +369,6 @@ appear directly as bindings in @var{keymap} are also copied recursively, and so on to any number of levels. However, recursive copying does not take place when the definition of a character is a symbol whose function definition is a keymap; the same symbol appears in the new copy. -@c Emacs 19 feature @example @group @@ -1140,7 +1139,6 @@ and have extra events at the end that do not fit into a single key sequence. Then the value is a number, the number of events at the front of @var{key} that compose a complete key. -@c Emacs 19 feature If @var{accept-defaults} is non-@code{nil}, then @code{lookup-key} considers default bindings as well as bindings for the specific events in @var{key}. Otherwise, @code{lookup-key} reports only bindings for @@ -1182,7 +1180,6 @@ not cause an error. This function returns the binding for @var{key} in the current local keymap, or @code{nil} if it is undefined there. -@c Emacs 19 feature The argument @var{accept-defaults} controls checking for default bindings, as in @code{lookup-key} (above). @end defun @@ -1191,12 +1188,10 @@ as in @code{lookup-key} (above). This function returns the binding for command @var{key} in the current global keymap, or @code{nil} if it is undefined there. -@c Emacs 19 feature The argument @var{accept-defaults} controls checking for default bindings, as in @code{lookup-key} (above). @end defun -@c Emacs 19 feature @defun minor-mode-key-binding key &optional accept-defaults This function returns a list of all the active minor mode bindings of @var{key}. More precisely, it returns an alist of pairs @@ -1414,7 +1409,6 @@ standard bindings: @end group @end smallexample -@c Emacs 19 feature If @var{oldmap} is non-@code{nil}, that changes the behavior of @code{substitute-key-definition}: the bindings in @var{oldmap} determine which keys to rebind. The rebindings still happen in @var{keymap}, not diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi index 8c6aeb0472..e68a1ef314 100644 --- a/doc/lispref/loading.texi +++ b/doc/lispref/loading.texi @@ -1052,7 +1052,6 @@ rather than replacing that element. @xref{Eval}. @section Unloading @cindex unloading packages -@c Emacs 19 feature You can discard the functions and variables loaded by a library to reclaim memory for other Lisp objects. To do this, use the function @code{unload-feature}: diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index bbc834004b..d16409d6c8 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -379,8 +379,6 @@ default, it makes the following bindings: @end table @end defvar -@c In version 18, initial is required -@c Emacs 19 feature @defun read-no-blanks-input prompt &optional initial inherit-input-method This function reads a string from the minibuffer, but does not allow whitespace characters as part of the input: instead, those characters @@ -2475,7 +2473,6 @@ usual minibuffer input functions because they all start by choosing the minibuffer window according to the selected frame. @end defun -@c Emacs 19 feature @defun window-minibuffer-p &optional window This function returns @code{t} if @var{window} is a minibuffer window. @var{window} defaults to the selected window. @@ -2619,7 +2616,6 @@ when the minibuffer is active, not even if you switch to another window to do it. @end defopt -@c Emacs 19 feature If a command name has a property @code{enable-recursive-minibuffers} that is non-@code{nil}, then the command can use the minibuffer to read arguments even if it is invoked from the minibuffer. A command can diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index dc0c7442d8..769aeed75f 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi @@ -232,7 +232,6 @@ backward until encountering the front of a word, rather than forward. @end deffn @defopt words-include-escapes -@c Emacs 19 feature This variable affects the behavior of @code{forward-word} and @code{backward-word}, and everything that uses them. If it is non-@code{nil}, then characters in the escape and character-quote diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi index 63438170d1..0ddf3e465d 100644 --- a/doc/lispref/variables.texi +++ b/doc/lispref/variables.texi @@ -1696,7 +1696,6 @@ buffer has a buffer-local binding. For example, you could use you are in a C or Lisp mode buffer that has a buffer-local value for this variable. -@c Emacs 19 feature The special forms @code{defvar} and @code{defconst} also set the default value (if they set the variable at all), rather than any buffer-local value. @@ -1708,7 +1707,6 @@ this variable. If @var{symbol} is not buffer-local, this is equivalent to @code{symbol-value} (@pxref{Accessing Variables}). @end defun -@c Emacs 19 feature @defun default-boundp symbol The function @code{default-boundp} tells you whether @var{symbol}'s default value is nonvoid. If @code{(default-boundp 'foo)} returns diff --git a/doc/misc/efaq-w32.texi b/doc/misc/efaq-w32.texi index 2abde2c284..6eff88b76e 100644 --- a/doc/misc/efaq-w32.texi +++ b/doc/misc/efaq-w32.texi @@ -370,11 +370,10 @@ On Windows, the @file{.emacs} file may be called @file{_emacs} for backward compatibility with DOS and FAT filesystems where filenames could not start with a dot. Some users prefer to continue using such a name due to historical problems various Windows tools had in the -past with file names that begin with a dot. In Emacs 22 and later, -the init file may also be called @file{.emacs.d/init.el}. Many of the -other files that are created by lisp packages are now stored in the -@file{.emacs.d} directory too, so this keeps all your Emacs related -files in one place. +past with file names that begin with a dot. The init file may also be +called @file{.emacs.d/init.el}. Many of the other files that are +created by Lisp packages are stored in the @file{.emacs.d} directory +too, which keeps all your Emacs related files in one place. All the files mentioned above should go in your @env{HOME} directory. The @env{HOME} directory is determined by following the steps below: diff --git a/doc/misc/gnus-faq.texi b/doc/misc/gnus-faq.texi index 4c29976c05..35a2526211 100644 --- a/doc/misc/gnus-faq.texi +++ b/doc/misc/gnus-faq.texi @@ -160,13 +160,7 @@ Where and how to get Gnus? @subsubheading Answer -Gnus is released independent from releases of Emacs. Therefore, the -version bundled with Emacs might not be up to date (e.g., Gnus 5.9 -bundled with Emacs 21 is outdated). -You can get the latest released version of Gnus from -@uref{https://www.gnus.org/dist/gnus.tar.gz} -or from -@uref{https://ftp.gnus.org/pub/gnus/gnus.tar.gz}. +Gnus is bundled with Emacs. @node FAQ 1-4 @subsubheading Question 1.4 diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi index faf5366e2b..b6553c8a63 100644 --- a/doc/misc/gnus.texi +++ b/doc/misc/gnus.texi @@ -815,7 +815,7 @@ Various * Undo:: Some actions can be undone. * Predicate Specifiers:: Specifying predicates. * Moderation:: What to do if you're a moderator. -* Image Enhancements:: Modern versions of Emacs can display images. +* Image Enhancements:: Emacs can display images. * Fuzzy Matching:: What's the big fuzz? * Thwarting Email Spam:: Simple ways to avoid unsolicited commercial email. * Spam Package:: A package for filtering and processing spam. @@ -22505,7 +22505,7 @@ to you, using @kbd{G b u} and updating the group will usually fix this. * Predicate Specifiers:: Specifying predicates. * Moderation:: What to do if you're a moderator. * Fetching a Group:: Starting Gnus just to read a group. -* Image Enhancements:: Modern versions of Emacs can display images. +* Image Enhancements:: Emacs can display images. * Fuzzy Matching:: What's the big fuzz? * Thwarting Email Spam:: Simple ways to avoid unsolicited commercial email. * Spam Package:: A package for filtering and processing spam. @@ -23668,9 +23668,8 @@ It takes the group name as a parameter. @node Image Enhancements @section Image Enhancements -Emacs 21@footnote{Emacs 21 on MS Windows doesn't -support images, Emacs 22 does.} and up are able to display pictures and -stuff, so Gnus has taken advantage of that. +Emacs is able to display pictures and stuff, so Gnus has taken +advantage of that. @menu * X-Face:: Display a funky, teensy black-and-white image. diff --git a/lisp/erc/erc-menu.el b/lisp/erc/erc-menu.el index 0e334e93bd..d76e0a345e 100644 --- a/lisp/erc/erc-menu.el +++ b/lisp/erc/erc-menu.el @@ -110,11 +110,11 @@ ERC menu yet.") (define-erc-module menu nil "Enable a menu in ERC buffers." ((unless erc-menu-defined - ;; make sure the menu only gets defined once, since Emacs 22 + ;; make sure the menu only gets defined once, since Emacs ;; activates it immediately (easy-menu-define erc-menu erc-mode-map "ERC menu" erc-menu-definition) (setq erc-menu-defined t))) - (;; `easy-menu-remove' is a no-op in Emacs 22 + (;; `easy-menu-remove' is a no-op in Emacs (message "You might have to restart Emacs to remove the ERC menu"))) (defun erc-menu-add () diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el index bef99f2484..472788d18e 100644 --- a/lisp/progmodes/cfengine.el +++ b/lisp/progmodes/cfengine.el @@ -987,13 +987,11 @@ Intended as the value of `indent-line-function'." (if (> (- (point-max) pos) (point)) (goto-char (- (point-max) pos))))) -;; This doesn't work too well in Emacs 21.2. See 22.1 development -;; code. (defun cfengine-fill-paragraph (&optional justify) "Fill `paragraphs' in Cfengine code." (interactive "P") (or (if (fboundp 'fill-comment-paragraph) - (fill-comment-paragraph justify) ; post Emacs 21.3 + (fill-comment-paragraph justify) ;; else do nothing in a comment (nth 4 (parse-partial-sexp (save-excursion (beginning-of-defun) commit 4cb52200cb67d3cd1aa77717d12d4b88845e1755 Author: Stefan Kangas Date: Wed Mar 10 04:34:53 2021 +0100 Fix duplicate ":" in ert-find-test-other-window prompt * lisp/emacs-lisp/ert.el (ert-find-test-other-window): Don't insert duplicate ":" in prompt. diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index f7f53eaa70..e91ec0af44 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -1633,7 +1633,7 @@ default (if any)." (defun ert-find-test-other-window (test-name) "Find, in another window, the definition of TEST-NAME." - (interactive (list (ert-read-test-name-at-point "Find test definition: "))) + (interactive (list (ert-read-test-name-at-point "Find test definition"))) (find-function-do-it test-name 'ert--test 'switch-to-buffer-other-window)) (defun ert-delete-test (test-name) commit dc2688acb30afe747e874a0737cdfc07bd1efa3b Author: Stefan Kangas Date: Wed Mar 10 04:34:01 2021 +0100 Do mode tagging in ert.el diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index d22b239774..f7f53eaa70 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -2083,6 +2083,7 @@ and how to display message." (define-derived-mode ert-results-mode special-mode "ERT-Results" "Major mode for viewing results of ERT test runs." + :interactive nil (setq-local revert-buffer-function (lambda (&rest _) (ert-results-rerun-all-tests)))) @@ -2178,7 +2179,7 @@ To be used in the ERT results buffer." "Move point to the next test. To be used in the ERT results buffer." - (interactive) + (interactive nil ert-results-mode) (ert--results-move (ewoc-locate ert--results-ewoc) 'ewoc-next "No tests below")) @@ -2186,7 +2187,7 @@ To be used in the ERT results buffer." "Move point to the previous test. To be used in the ERT results buffer." - (interactive) + (interactive nil ert-results-mode) (ert--results-move (ewoc-locate ert--results-ewoc) 'ewoc-prev "No tests above")) @@ -2219,7 +2220,7 @@ user-error is signaled with the message ERROR-MESSAGE." "Find the definition of the test at point in another window. To be used in the ERT results buffer." - (interactive) + (interactive nil ert-results-mode) (let ((name (ert-test-at-point))) (unless name (user-error "No test at point")) @@ -2253,7 +2254,7 @@ To be used in the ERT results buffer." ;; the summary apparently needs to be easily accessible from the ;; error log, and perhaps it would be better to have it in a ;; separate buffer to keep it visible. - (interactive) + (interactive nil ert-results-mode) (let ((ewoc ert--results-ewoc) (progress-bar-begin ert--results-progress-bar-button-begin)) (cond ((ert--results-test-node-or-null-at-point) @@ -2370,7 +2371,7 @@ definition." "Re-run all tests, using the same selector. To be used in the ERT results buffer." - (interactive) + (interactive nil ert-results-mode) (cl-assert (eql major-mode 'ert-results-mode)) (let ((selector (ert--stats-selector ert--results-stats))) (ert-run-tests-interactively selector (buffer-name)))) @@ -2379,7 +2380,7 @@ To be used in the ERT results buffer." "Re-run the test at point. To be used in the ERT results buffer." - (interactive) + (interactive nil ert-results-mode) (cl-destructuring-bind (test redefinition-state) (ert--results-test-at-point-allow-redefinition) (when (null test) @@ -2414,7 +2415,7 @@ To be used in the ERT results buffer." "Re-run the test at point with `ert-debug-on-error' bound to t. To be used in the ERT results buffer." - (interactive) + (interactive nil ert-results-mode) (let ((ert-debug-on-error t)) (ert-results-rerun-test-at-point))) @@ -2422,7 +2423,7 @@ To be used in the ERT results buffer." "Display the backtrace for the test at point. To be used in the ERT results buffer." - (interactive) + (interactive nil ert-results-mode) (let* ((test (ert--results-test-at-point-no-redefinition t)) (stats ert--results-stats) (pos (ert--stats-test-pos stats test)) @@ -2449,7 +2450,7 @@ To be used in the ERT results buffer." "Display the part of the *Messages* buffer generated during the test at point. To be used in the ERT results buffer." - (interactive) + (interactive nil ert-results-mode) (let* ((test (ert--results-test-at-point-no-redefinition t)) (stats ert--results-stats) (pos (ert--stats-test-pos stats test)) @@ -2470,7 +2471,7 @@ To be used in the ERT results buffer." "Display the list of `should' forms executed during the test at point. To be used in the ERT results buffer." - (interactive) + (interactive nil ert-results-mode) (let* ((test (ert--results-test-at-point-no-redefinition t)) (stats ert--results-stats) (pos (ert--stats-test-pos stats test)) @@ -2506,7 +2507,7 @@ To be used in the ERT results buffer." "Toggle how much of the condition to print for the test at point. To be used in the ERT results buffer." - (interactive) + (interactive nil ert-results-mode) (let* ((ewoc ert--results-ewoc) (node (ert--results-test-node-at-point)) (entry (ewoc-data node))) @@ -2518,7 +2519,7 @@ To be used in the ERT results buffer." "Display test timings for the last run. To be used in the ERT results buffer." - (interactive) + (interactive nil ert-results-mode) (let* ((stats ert--results-stats) (buffer (get-buffer-create "*ERT timings*")) (data (cl-loop for test across (ert--stats-tests stats) @@ -2597,7 +2598,7 @@ To be used in the ERT results buffer." "Display the documentation of the test at point. To be used in the ERT results buffer." - (interactive) + (interactive nil ert-results-mode) (ert-describe-test (ert--results-test-at-point-no-redefinition t))) commit 1c5cb14c0daa00fcdc32e324cc8e0e327bf46bce Author: Stefan Kangas Date: Mon Mar 8 12:50:22 2021 +0100 Use proper command substitutions in some docstrings * lisp/arc-mode.el (archive-mode): * lisp/ibuffer.el (ibuffer): * lisp/tar-mode.el (tar-mode): * lisp/textmodes/table.el (table-insert): Use substitute-command-keys instead of hardcoded keys in some docstrings. diff --git a/lisp/arc-mode.el b/lisp/arc-mode.el index 6c9ceb0b5a..83c516100a 100644 --- a/lisp/arc-mode.el +++ b/lisp/arc-mode.el @@ -660,11 +660,11 @@ Does not signal an error if optional argument NOERROR is non-nil." (defun archive-mode (&optional force) "Major mode for viewing an archive file in a dired-like way. You can move around using the usual cursor motion commands. -Letters no longer insert themselves. -Type `e' to pull a file out of the archive and into its own buffer; +Letters no longer insert themselves.\\ +Type \\[archive-extract] to pull a file out of the archive and into its own buffer; or click mouse-2 on the file's line in the archive mode buffer. -If you edit a sub-file of this archive (as with the `e' command) and +If you edit a sub-file of this archive (as with the \\[archive-extract] command) and save it, the contents of that buffer will be saved back into the archive. diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el index 78ae2705a9..b484dd717c 100644 --- a/lisp/ibuffer.el +++ b/lisp/ibuffer.el @@ -2297,7 +2297,7 @@ buffers which are visiting a file." (defun ibuffer (&optional other-window-p name qualifiers noselect shrink filter-groups formats) "Begin using Ibuffer to edit a list of buffers. -Type `h' after entering ibuffer for more information. +Type \\\\[describe-mode] after entering ibuffer for more information. All arguments are optional. OTHER-WINDOW-P says to use another window. diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el index 59f7c87e99..fa9b47556f 100644 --- a/lisp/tar-mode.el +++ b/lisp/tar-mode.el @@ -685,12 +685,12 @@ For instance, if mode is #o700, then it produces `rwx------'." (define-derived-mode tar-mode special-mode "Tar" "Major mode for viewing a tar file as a dired-like listing of its contents. You can move around using the usual cursor motion commands. -Letters no longer insert themselves. -Type `e' to pull a file out of the tar file and into its own buffer; +Letters no longer insert themselves.\\ +Type \\[tar-extract] to pull a file out of the tar file and into its own buffer; or click mouse-2 on the file's line in the Tar mode buffer. -Type `c' to copy an entry from the tar file into another file on disk. +Type \\[tar-copy] to copy an entry from the tar file into another file on disk. -If you edit a sub-file of this archive (as with the `e' command) and +If you edit a sub-file of this archive (as with the \\[tar-extract] command) and save it with \\[save-buffer], the contents of that buffer will be saved back into the tar-file buffer; in this way you can edit a file inside of a tar archive without extracting it and re-archiving it. diff --git a/lisp/textmodes/table.el b/lisp/textmodes/table.el index 06785e458b..60122b2fac 100644 --- a/lisp/textmodes/table.el +++ b/lisp/textmodes/table.el @@ -1492,7 +1492,7 @@ Move the point under the table as shown below. +--------------+------+--------------------------------+ -!- -Type M-x table-insert-row instead of \\[table-insert-row-column]. \\[table-insert-row-column] does not work +Type \\[table-insert-row] instead of \\[table-insert-row-column]. \\[table-insert-row-column] does not work when the point is outside of the table. This insertion at outside of the table effectively appends a row at the end. commit 5217b56ee1bdee5df41b9c3773da85c4586af36f Author: Stefan Kangas Date: Wed Mar 10 04:07:48 2021 +0100 * lisp/userlock.el: Use lexical-binding. diff --git a/lisp/userlock.el b/lisp/userlock.el index 0ef3c7770b..57311ac99c 100644 --- a/lisp/userlock.el +++ b/lisp/userlock.el @@ -1,4 +1,4 @@ -;;; userlock.el --- handle file access contention between multiple users +;;; userlock.el --- handle file access contention between multiple users -*- lexical-binding: t -*- ;; Copyright (C) 1985-1986, 2001-2021 Free Software Foundation, Inc. commit 8605ddc79caa70f7655f41cee36e59031d5e97f8 Author: Stefan Kangas Date: Wed Mar 10 03:29:50 2021 +0100 Use 'help-key-binding' face in userlock.el * lisp/userlock.el (userlock--fontify-key): New function. (ask-user-about-lock, ask-user-about-lock-help, (ask-user-about-supersession-threat) (ask-user-about-supersession-help): Add face 'help-key-binding' to displayed keys. diff --git a/lisp/userlock.el b/lisp/userlock.el index a340ff85b2..0ef3c7770b 100644 --- a/lisp/userlock.el +++ b/lisp/userlock.el @@ -39,6 +39,10 @@ (define-error 'file-locked "File is locked" 'file-error) +(defun userlock--fontify-key (key) + "Add the `help-key-binding' face to string KEY." + (propertize key 'face 'help-key-binding)) + ;;;###autoload (defun ask-user-about-lock (file opponent) "Ask user what to do when he wants to edit FILE but it is locked by OPPONENT. @@ -64,8 +68,12 @@ in any way you like." (match-string 0 opponent))) opponent)) (while (null answer) - (message "%s locked by %s: (s, q, p, ?)? " - short-file short-opponent) + (message "%s locked by %s: (%s, %s, %s, %s)? " + short-file short-opponent + (userlock--fontify-key "s") + (userlock--fontify-key "q") + (userlock--fontify-key "p") + (userlock--fontify-key "?")) (if noninteractive (error "Cannot resolve lock conflict in batch mode")) (let ((tem (let ((inhibit-quit t) (cursor-in-echo-area t)) @@ -80,7 +88,12 @@ in any way you like." (?? . help)))) (cond ((null answer) (beep) - (message "Please type q, s, or p; or ? for help") + (message "Please type %s, %s, or %s; or %s for help" + (userlock--fontify-key "q") + (userlock--fontify-key "s") + (userlock--fontify-key "p") + ;; FIXME: Why do we use "?" here and "C-h" below? + (userlock--fontify-key "?")) (sit-for 3)) ((eq (cdr answer) 'help) (ask-user-about-lock-help) @@ -91,14 +104,19 @@ in any way you like." (defun ask-user-about-lock-help () (with-output-to-temp-buffer "*Help*" - (princ "It has been detected that you want to modify a file that someone else has + (with-current-buffer standard-output + (insert + (format + "It has been detected that you want to modify a file that someone else has already started modifying in Emacs. -You can teal the file; the other user becomes the +You can <%s>teal the file; the other user becomes the intruder if (s)he ever unmodifies the file and then changes it again. -You can

roceed; you edit at your own (and the other user's) risk. -You can uit; don't modify this file.") - (with-current-buffer standard-output +You can <%s>roceed; you edit at your own (and the other user's) risk. +You can <%s>uit; don't modify this file." + (userlock--fontify-key "s") + (userlock--fontify-key "p") + (userlock--fontify-key "q"))) (help-mode)))) (define-error 'file-supersession nil 'file-error) @@ -151,8 +169,13 @@ The buffer in question is current when this function is called." (save-window-excursion (let ((prompt (format "%s changed on disk; \ -really edit the buffer? (y, n, r or C-h) " - (file-name-nondirectory filename))) +really edit the buffer? (%s, %s, %s or %s) " + (file-name-nondirectory filename) + (userlock--fontify-key "y") + (userlock--fontify-key "n") + (userlock--fontify-key "r") + ;; FIXME: Why do we use "C-h" here and "?" above? + (userlock--fontify-key "C-h"))) (choices '(?y ?n ?r ?? ?\C-h)) answer) (when noninteractive @@ -177,20 +200,28 @@ really edit the buffer? (y, n, r or C-h) " (defun ask-user-about-supersession-help () (with-output-to-temp-buffer "*Help*" - (princ - (substitute-command-keys - "You want to modify a buffer whose disk file has changed + (let ((revert-buffer-binding + ;; This takes place in the original buffer. + (substitute-command-keys "\\[revert-buffer]"))) + (with-current-buffer standard-output + (insert + (format + "You want to modify a buffer whose disk file has changed since you last read it in or saved it with this buffer. -If you say `y' to go ahead and modify this buffer, +If you say %s to go ahead and modify this buffer, you risk ruining the work of whoever rewrote the file. -If you say `r' to revert, the contents of the buffer are refreshed +If you say %s to revert, the contents of the buffer are refreshed from the file on disk. -If you say `n', the change you started to make will be aborted. - -Usually, you should type `n' and then `\\[revert-buffer]', -to get the latest version of the file, then make the change again.")) - (with-current-buffer standard-output - (help-mode)))) +If you say %s, the change you started to make will be aborted. + +Usually, you should type %s and then %s, +to get the latest version of the file, then make the change again." + (userlock--fontify-key "y") + (userlock--fontify-key "r") + (userlock--fontify-key "n") + (userlock--fontify-key "n") + revert-buffer-binding)) + (help-mode))))) ;;; userlock.el ends here commit de9b19cbfdc690fe14865044e05650d066b6c04c Author: Dmitry Gutov Date: Wed Mar 10 03:08:29 2021 +0200 (project-switch-commands): Remove the ###autoload instruction * lisp/progmodes/project.el (project-switch-commands): Remove the ###autoload instruction. It's unnecessary and can cause surprises in some circumstances (bug#46986). diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 67e827eea4..c4bcf88e4c 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1255,7 +1255,6 @@ It's also possible to enter an arbitrary directory not in the list." ;;; Project switching -;;;###autoload (defcustom project-switch-commands '((project-find-file "Find file") (project-find-regexp "Find regexp") commit 48bfebc3b91def777bf13a7a889e31f330c4d32d Author: Stefan Kangas Date: Wed Mar 10 01:20:58 2021 +0100 * lisp/help.el (help--describe-translation): Fix typo. diff --git a/lisp/help.el b/lisp/help.el index 94073e5730..79d8296cfe 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -1253,7 +1253,7 @@ Return nil if the key sequence is too long." ;; Converted from describe_translation in keymap.c. ;; Avoid using the `help-keymap' face. (let ((op (point))) - (indent-to 16) + (indent-to 16 1) (set-text-properties op (point) '( face nil font-lock-face nil))) (cond ((symbolp definition) commit e8f0a7b6c152116b1e87487f405dea67385e35fb Author: Stefan Monnier Date: Tue Mar 9 16:17:31 2021 -0500 * lisp/mail/rmailmm.el: Use `cl-defstruct` and `lexical-binding` Remove redundant `:group` args. (rmail-mime-entity): Make it a `cl-defstruct`. (rmail-mime-entity-set-truncated): Mark as obsolete. (rmail-mime-display): New `cl-defstruct`. (rmail-mime-shown-mode, rmail-mime-hidden-mode, rmail-mime-raw-mode) (rmail-mime-toggle-hidden, rmail-mime-update-tagline) (rmail-mime-text-handler, rmail-mime-bulk-handler) (rmail-mime-process-multipart, rmail-mime-handle, rmail-mime-process) (rmail-mime-parse, rmail-mime-insert, rmail-show-mime): Adjust accordingly. (rmail-mime-toggle-raw): Apply de Morgan. (rmail-mime-insert-text): Remove unused var `tagline`. (rmail-mime-insert-image): Remove unused var `content-type`. (shr-inhibit-images, shr-width): Declare vars. (rmail-mime-insert-multipart): Remove unused vars `tagline` and `body`. (rmail-mime-insert): Remove unused var `tagline`. (rmail-search-mime-message): Remove unused var `body-end`. diff --git a/lisp/mail/rmailmm.el b/lisp/mail/rmailmm.el index ab5b49aab9..cdb994a5c8 100644 --- a/lisp/mail/rmailmm.el +++ b/lisp/mail/rmailmm.el @@ -1,4 +1,4 @@ -;;; rmailmm.el --- MIME decoding and display stuff for RMAIL +;;; rmailmm.el --- MIME decoding and display stuff for RMAIL -*- lexical-binding: t; -*- ;; Copyright (C) 2006-2021 Free Software Foundation, Inc. @@ -78,6 +78,7 @@ (require 'rmail) (require 'mail-parse) (require 'message) +(require 'cl-lib) ;;; User options. @@ -101,8 +102,7 @@ all others are handled by `rmail-mime-bulk-handler'. Note also that this alist is ignored when the variable `rmail-enable-mime' is non-nil." :type '(alist :key-type regexp :value-type (repeat function)) - :version "23.1" - :group 'rmail-mime) + :version "23.1") (defcustom rmail-mime-attachment-dirs-alist `(("text/.*" "~/Documents") @@ -114,8 +114,7 @@ The first item is a regular expression matching a content-type. The remaining elements are directories, in order of decreasing preference. The first directory that exists is used." :type '(alist :key-type regexp :value-type (repeat directory)) - :version "23.1" - :group 'rmail-mime) + :version "23.1") (defcustom rmail-mime-show-images 'button "What to do with image attachments that Emacs is capable of displaying. @@ -128,12 +127,11 @@ automatically display the image in the buffer." (const :tag "No special treatment" nil) (number :tag "Show if smaller than certain size") (other :tag "Always show" show)) - :version "23.2" - :group 'rmail-mime) + :version "23.2") (defcustom rmail-mime-render-html-function - (cond ((fboundp 'libxml-parse-html-region) 'rmail-mime-render-html-shr) - ((executable-find "lynx") 'rmail-mime-render-html-lynx) + (cond ((fboundp 'libxml-parse-html-region) #'rmail-mime-render-html-shr) + ((executable-find "lynx") #'rmail-mime-render-html-lynx) (t nil)) "Function to convert HTML to text. Called with buffer containing HTML extracted from message in a @@ -177,9 +175,12 @@ operations such as HTML decoding") ;;; MIME-entity object -(defun rmail-mime-entity (type disposition transfer-encoding - display header tagline body children handler - &optional truncated) +(cl-defstruct (rmail-mime-entity + (:copier nil) (:constructor nil) + (:constructor rmail-mime-entity + ( type disposition transfer-encoding + display header tagline body children handler + &optional truncated) "Return a newly created MIME-entity object from arguments. A MIME-entity is a vector of 10 elements: @@ -210,12 +211,7 @@ Content-Transfer-Encoding, and is a lower-case string. DISPLAY is a vector [CURRENT NEW], where CURRENT indicates how the header, tag line, and body of the entity are displayed now, and NEW indicates how their display should be updated. -Both elements are vectors [HEADER-DISPLAY TAGLINE-DISPLAY BODY-DISPLAY], -where each constituent element is a symbol for the corresponding -item with these values: - nil: not displayed - t: displayed by the decoded presentation form - raw: displayed by the raw MIME data (for the header and body only) +Both elements are `rmail-mime-display' objects. HEADER and BODY are vectors [BEG END DISPLAY-FLAG], where BEG and END are markers that specify the region of the header or body lines @@ -236,24 +232,13 @@ has just one child. Any other entity has no child. HANDLER is a function to insert the entity according to DISPLAY. It is called with one argument ENTITY. -TRUNCATED is non-nil if the text of this entity was truncated." - - (vector type disposition transfer-encoding - display header tagline body children handler truncated)) - -;; Accessors for a MIME-entity object. -(defsubst rmail-mime-entity-type (entity) (aref entity 0)) -(defsubst rmail-mime-entity-disposition (entity) (aref entity 1)) -(defsubst rmail-mime-entity-transfer-encoding (entity) (aref entity 2)) -(defsubst rmail-mime-entity-display (entity) (aref entity 3)) -(defsubst rmail-mime-entity-header (entity) (aref entity 4)) -(defsubst rmail-mime-entity-tagline (entity) (aref entity 5)) -(defsubst rmail-mime-entity-body (entity) (aref entity 6)) -(defsubst rmail-mime-entity-children (entity) (aref entity 7)) -(defsubst rmail-mime-entity-handler (entity) (aref entity 8)) -(defsubst rmail-mime-entity-truncated (entity) (aref entity 9)) +TRUNCATED is non-nil if the text of this entity was truncated.")) + type disposition transfer-encoding + display header tagline body children handler truncated) + (defsubst rmail-mime-entity-set-truncated (entity truncated) - (aset entity 9 truncated)) + (declare (obsolete (setf rmail-mime-entity-truncated) "28.1")) + (setf (rmail-mime-entity-truncated entity) truncated)) ;;; Buttons @@ -303,9 +288,16 @@ TRUNCATED is non-nil if the text of this entity was truncated." ;; Display options returned by rmail-mime-entity-display. ;; Value is on of nil, t, raw. -(defsubst rmail-mime-display-header (disp) (aref disp 0)) -(defsubst rmail-mime-display-tagline (disp) (aref disp 1)) -(defsubst rmail-mime-display-body (disp) (aref disp 2)) +(cl-defstruct (rmail-mime-display + (:copier rmail-mime--copy-display) (:constructor nil) + (:constructor rmail-mime--make-display (header tagline body) + "Make an object describing how to display. +Each field's value is a symbol for the corresponding +item with these values: + nil: not displayed + t: displayed by the decoded presentation form + raw: displayed by the raw MIME data (for the header and body only).")) + header tagline body) (defun rmail-mime-entity-segment (pos &optional entity) "Return a vector describing the displayed region of a MIME-entity at POS. @@ -371,27 +363,30 @@ The value is a vector [INDEX HEADER TAGLINE BODY END], where (defun rmail-mime-shown-mode (entity) "Make MIME-entity ENTITY display in the default way." (let ((new (aref (rmail-mime-entity-display entity) 1))) - (aset new 0 (aref (rmail-mime-entity-header entity) 2)) - (aset new 1 (aref (rmail-mime-entity-tagline entity) 2)) - (aset new 2 (aref (rmail-mime-entity-body entity) 2))) + (setf (rmail-mime-display-header new) + (aref (rmail-mime-entity-header entity) 2)) + (setf (rmail-mime-display-tagline new) + (aref (rmail-mime-entity-tagline entity) 2)) + (setf (rmail-mime-display-body new) + (aref (rmail-mime-entity-body entity) 2))) (dolist (child (rmail-mime-entity-children entity)) (rmail-mime-shown-mode child))) (defun rmail-mime-hidden-mode (entity) "Make MIME-entity ENTITY display in hidden mode." (let ((new (aref (rmail-mime-entity-display entity) 1))) - (aset new 0 nil) - (aset new 1 t) - (aset new 2 nil)) + (setf (rmail-mime-display-header new) nil) + (setf (rmail-mime-display-tagline new) t) + (setf (rmail-mime-display-body new) nil)) (dolist (child (rmail-mime-entity-children entity)) (rmail-mime-hidden-mode child))) (defun rmail-mime-raw-mode (entity) "Make MIME-entity ENTITY display in raw mode." (let ((new (aref (rmail-mime-entity-display entity) 1))) - (aset new 0 'raw) - (aset new 1 nil) - (aset new 2 'raw)) + (setf (rmail-mime-display-header new) 'raw) + (setf (rmail-mime-display-tagline new) nil) + (setf (rmail-mime-display-body new) 'raw)) (dolist (child (rmail-mime-entity-children entity)) (rmail-mime-raw-mode child))) @@ -404,8 +399,8 @@ Use `raw' for raw mode, and any other non-nil value for decoded mode." (current (aref (rmail-mime-entity-display entity) 0)) (segment (rmail-mime-entity-segment pos entity))) (if (or (eq state 'raw) - (and (not state) - (not (eq (rmail-mime-display-header current) 'raw)))) + (not (or state + (eq (rmail-mime-display-header current) 'raw)))) ;; Enter the raw mode. (rmail-mime-raw-mode entity) ;; Enter the shown mode. @@ -439,7 +434,7 @@ Use `raw' for raw mode, and any other non-nil value for decoded mode." ;; header. (if (and rmail-mime-mbox-buffer (= (aref segment 1) (point-min))) (let ((new (aref (rmail-mime-entity-display entity) 1))) - (aset new 0 t)))) + (setf (rmail-mime-display-header new) t)))) ;; Query as a warning before showing if truncated. (if (and (not (stringp entity)) (rmail-mime-entity-truncated entity)) @@ -448,7 +443,8 @@ Use `raw' for raw mode, and any other non-nil value for decoded mode." ;; Enter the shown mode. (rmail-mime-shown-mode entity) ;; Force this body shown. - (aset (aref (rmail-mime-entity-display entity) 1) 2 t)) + (let ((new (aref (rmail-mime-entity-display entity) 1))) + (setf (rmail-mime-display-body new) t))) (let ((inhibit-read-only t) (modified (buffer-modified-p)) (rmail-mime-mbox-buffer rmail-view-buffer) @@ -458,9 +454,9 @@ Use `raw' for raw mode, and any other non-nil value for decoded mode." (rmail-mime-insert entity) (restore-buffer-modified-p modified)))))) -(define-key rmail-mode-map "\t" 'forward-button) -(define-key rmail-mode-map [backtab] 'backward-button) -(define-key rmail-mode-map "\r" 'rmail-mime-toggle-hidden) +(define-key rmail-mode-map "\t" #'forward-button) +(define-key rmail-mode-map [backtab] #'backward-button) +(define-key rmail-mode-map "\r" #'rmail-mime-toggle-hidden) ;;; Handlers @@ -483,7 +479,7 @@ to the tag line." (when item (if (stringp item) (insert item) - (apply 'insert-button item)))) + (apply #'insert-button item)))) ;; Follow the tagline by an empty line to make it a separate ;; paragraph, so that the paragraph direction of the following text ;; is determined based on that text. @@ -495,8 +491,10 @@ to the tag line." (modified (buffer-modified-p)) ;; If we are going to show the body, the new button label is ;; "Hide". Otherwise, it's "Show". - (label (if (aref (aref (rmail-mime-entity-display entity) 1) 2) "Hide" - "Show")) + (label + (if (rmail-mime-display-body + (aref (rmail-mime-entity-display entity) 1)) + "Hide" "Show")) (button (next-button (point)))) ;; Go to the second character of the button "Show" or "Hide". (goto-char (1+ (button-start button))) @@ -556,9 +554,10 @@ HEADER is a header component of a MIME-entity object (see (rmail-mime-insert-text (rmail-mime-entity content-type content-disposition content-transfer-encoding - (vector (vector nil nil nil) (vector nil nil t)) + (vector (rmail-mime--make-display nil nil nil) + (rmail-mime--make-display nil nil t)) (vector nil nil nil) (vector "" (cons nil nil) t) - (vector nil nil nil) nil 'rmail-mime-insert-text)) + (vector nil nil nil) nil #'rmail-mime-insert-text)) t) (defun rmail-mime-insert-decoded-text (entity) @@ -592,7 +591,7 @@ HEADER is a header component of a MIME-entity object (see (let ((current (aref (rmail-mime-entity-display entity) 0)) (new (aref (rmail-mime-entity-display entity) 1)) (header (rmail-mime-entity-header entity)) - (tagline (rmail-mime-entity-tagline entity)) + ;; (tagline (rmail-mime-entity-tagline entity)) (body (rmail-mime-entity-body entity)) (beg (point)) (segment (rmail-mime-entity-segment (point) entity))) @@ -634,7 +633,7 @@ HEADER is a header component of a MIME-entity object (see (defun rmail-mime-insert-image (entity) "Decode and insert the image body of MIME-entity ENTITY." - (let* ((content-type (car (rmail-mime-entity-type entity))) + (let* (;; (content-type (car (rmail-mime-entity-type entity))) (bulk-data (aref (rmail-mime-entity-tagline entity) 1)) (body (rmail-mime-entity-body entity)) data) @@ -709,6 +708,9 @@ HEADER is a header component of a MIME-entity object (see (declare-function libxml-parse-html-region "xml.c" (start end &optional base-url discard-comments)) +(defvar shr-inhibit-images) +(defvar shr-width) + (defun rmail-mime-render-html-shr (source-buffer) (let ((dom (with-current-buffer source-buffer (libxml-parse-html-region (point-min) (point-max)))) @@ -759,7 +761,8 @@ For images that Emacs is capable of displaying, the behavior depends upon the value of `rmail-mime-show-images'." (rmail-mime-insert-bulk (rmail-mime-entity content-type content-disposition content-transfer-encoding - (vector (vector nil nil nil) (vector nil t nil)) + (vector (rmail-mime--make-display nil nil nil) + (rmail-mime--make-display nil t nil)) (vector nil nil nil) (vector "" (cons nil nil) t) (vector nil nil nil) nil 'rmail-mime-insert-bulk))) @@ -1024,9 +1027,10 @@ The other arguments are the same as `rmail-mime-multipart-handler'." nil (format "%s/%d" parse-tag index) content-type content-disposition))) ;; Display a tagline. - (aset (aref (rmail-mime-entity-display child) 1) 1 + (setf (rmail-mime-display-tagline + (aref (rmail-mime-entity-display child) 1)) (aset (rmail-mime-entity-tagline child) 2 t)) - (rmail-mime-entity-set-truncated child truncated) + (setf (rmail-mime-entity-truncated child) truncated) (push child entities))) (delete-region end next) @@ -1072,8 +1076,8 @@ The other arguments are the same as `rmail-mime-multipart-handler'." (let ((current (aref (rmail-mime-entity-display entity) 0)) (new (aref (rmail-mime-entity-display entity) 1)) (header (rmail-mime-entity-header entity)) - (tagline (rmail-mime-entity-tagline entity)) - (body (rmail-mime-entity-body entity)) + ;; (tagline (rmail-mime-entity-tagline entity)) + ;; (body (rmail-mime-entity-body entity)) (beg (point)) (segment (rmail-mime-entity-segment (point) entity))) ;; header @@ -1169,13 +1173,11 @@ The parsed header value: content-transfer-encoding)) (save-restriction (widen) - (let ((entity (get-text-property (1- (point)) 'rmail-mime-entity)) - current new) + (let ((entity (get-text-property (1- (point)) 'rmail-mime-entity))) (when entity - (setq current (aref (rmail-mime-entity-display entity) 0) - new (aref (rmail-mime-entity-display entity) 1)) - (dotimes (i 3) - (aset current i (aref new i))))))) + (let ((new (aref (rmail-mime-entity-display entity) 1))) + (setf (aref (rmail-mime-entity-display entity) 0) + (rmail-mime--copy-display new))))))) (defun rmail-mime-show (&optional show-headers) "Handle the current buffer as a MIME message. @@ -1240,13 +1242,15 @@ modified." (header (vector (point-min-marker) hdr-end nil)) (tagline (vector parse-tag (cons nil nil) t)) (body (vector hdr-end (point-max-marker) is-inline)) - (new (vector (aref header 2) (aref tagline 2) (aref body 2))) + (new (rmail-mime--make-display + (aref header 2) (aref tagline 2) (aref body 2))) children handler entity) (cond ((string-match "multipart/.*" (car content-type)) (save-restriction (narrow-to-region (1- end) (point-max)) (if (zerop (length parse-tag)) ; top level of message - (aset new 1 (aset tagline 2 nil))) ; don't show tagline + (setf (rmail-mime-display-tagline new) + (aset tagline 2 nil))) ; don't show tagline (setq children (rmail-mime-process-multipart content-type content-disposition @@ -1260,37 +1264,38 @@ modified." '("text/plain") '("inline"))) (msg-new (aref (rmail-mime-entity-display msg) 1))) ;; Show header of the child. - (aset msg-new 0 t) + (setf (rmail-mime-display-header msg-new) t) (aset (rmail-mime-entity-header msg) 2 t) ;; Hide tagline of the child. - (aset msg-new 1 nil) + (setf (rmail-mime-display-tagline msg-new) nil) (aset (rmail-mime-entity-tagline msg) 2 nil) (setq children (list msg) handler 'rmail-mime-insert-multipart)))) ((and is-inline (string-match "text/html" (car content-type))) ;; Display tagline, so part can be detached - (aset new 1 (aset tagline 2 t)) - (aset new 2 (aset body 2 t)) ; display body also. + (setf (rmail-mime-display-tagline new) (aset tagline 2 t)) + (setf (rmail-mime-display-body new) (aset body 2 t)) ; display body also. (setq handler 'rmail-mime-insert-bulk)) ;; Inline non-HTML text ((and is-inline (string-match "text/" (car content-type))) ;; Don't need a tagline. - (aset new 1 (aset tagline 2 nil)) + (setf (rmail-mime-display-tagline new) (aset tagline 2 nil)) (setq handler 'rmail-mime-insert-text)) (t ;; Force hidden mode. - (aset new 1 (aset tagline 2 t)) - (aset new 2 (aset body 2 nil)) + (setf (rmail-mime-display-tagline new) (aset tagline 2 t)) + (setf (rmail-mime-display-body new) (aset body 2 nil)) (setq handler 'rmail-mime-insert-bulk))) - (setq entity (rmail-mime-entity content-type - content-disposition - content-transfer-encoding - (vector (vector nil nil nil) new) - header tagline body children handler)) + (setq entity (rmail-mime-entity + content-type + content-disposition + content-transfer-encoding + (vector (rmail-mime--make-display nil nil nil) new) + header tagline body children handler)) (if (and (eq handler 'rmail-mime-insert-bulk) (rmail-mime-set-bulk-data entity)) ;; Show the body. - (aset new 2 (aset body 2 t))) + (setf (rmail-mime-display-body new) (aset body 2 t))) entity) ;; Hide headers and handle the part. @@ -1324,7 +1329,8 @@ If an error occurs, return an error message string." '("text/plain") '("inline"))) (new (aref (rmail-mime-entity-display entity) 1))) ;; Show header. - (aset new 0 (aset (rmail-mime-entity-header entity) 2 t)) + (setf (rmail-mime-display-header new) + (aset (rmail-mime-entity-header entity) 2 t)) entity))) (error (format "%s" err))))) @@ -1339,7 +1345,7 @@ available." ;; Not a raw-mode. Each handler should handle it. (funcall (rmail-mime-entity-handler entity) entity) (let ((header (rmail-mime-entity-header entity)) - (tagline (rmail-mime-entity-tagline entity)) + ;; (tagline (rmail-mime-entity-tagline entity)) (body (rmail-mime-entity-body entity)) (beg (point)) (segment (rmail-mime-entity-segment (point) entity))) @@ -1370,15 +1376,15 @@ available." (aref body 0) (aref body 1)) (or (bolp) (insert "\n"))) (put-text-property beg (point) 'rmail-mime-entity entity))))) - (dotimes (i 3) - (aset current i (aref new i))))) + (setf (aref (rmail-mime-entity-display entity) 0) + (rmail-mime--copy-display new)))) (define-derived-mode rmail-mime-mode fundamental-mode "RMIME" "Major mode used in `rmail-mime' buffers." (setq font-lock-defaults '(rmail-font-lock-keywords t t nil nil))) ;;;###autoload -(defun rmail-mime (&optional arg state) +(defun rmail-mime (&optional _arg state) "Toggle the display of a MIME message. The actual behavior depends on the value of `rmail-enable-mime'. @@ -1442,7 +1448,7 @@ The arguments ARG and STATE have no effect in this case." (rmail-mime-view-buffer rmail-view-buffer) (rmail-mime-coding-system nil)) ;; If ENTITY is not a vector, it is a string describing an error. - (if (vectorp entity) + (if (rmail-mime-entity-p entity) (with-current-buffer rmail-mime-view-buffer (erase-buffer) ;; This condition-case is for catching an error in the @@ -1530,7 +1536,7 @@ This is the usual value of `rmail-insert-mime-forwarded-message-function'." (rmail-mime-view-buffer rmail-view-buffer) (header-end (save-excursion (re-search-forward "^$" nil 'move) (point))) - (body-end (point-max)) + ;; (body-end (point-max)) (entity (rmail-mime-parse))) (or ;; At first, just search the headers. commit f97e07ea807cc6d38774a3888a15091b20645ac6 Author: Paul Eggert Date: Tue Mar 9 11:22:59 2021 -0800 Port alternate signal stack to upcoming glibc 2.34 * src/sysdep.c (sigsegv_stack): Increase size to 64 KiB and align it to max_align_t. This copies from Gnulib’s c-stack.c, and works around a portability bug in draft glibc 2.34, which no longer defines SIGSTKSZ when _GNU_SOURCE is defined. diff --git a/src/sysdep.c b/src/sysdep.c index 941b4e2fa2..24d8832b2f 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1785,7 +1785,15 @@ handle_arith_signal (int sig) /* Alternate stack used by SIGSEGV handler below. */ -static unsigned char sigsegv_stack[SIGSTKSZ]; +/* Storage for the alternate signal stack. + 64 KiB is not too large for Emacs, and is large enough + for all known platforms. Smaller sizes may run into trouble. + For example, libsigsegv 2.6 through 2.8 have a bug where some + architectures use more than the Linux default of an 8 KiB alternate + stack when deciding if a fault was caused by stack overflow. */ +static max_align_t sigsegv_stack[(64 * 1024 + + sizeof (max_align_t) - 1) + / sizeof (max_align_t)]; /* Return true if SIGINFO indicates a stack overflow. */ commit c6ed17cc70ee49250f7d3999bb56918f0e925757 Author: Stefan Monnier Date: Tue Mar 9 13:04:14 2021 -0500 * src/buffer.c (Fbuffer_swap_text): Swap `mark-active` as well This avoids undesirable situations where `mark-active` is set even though the `mark` isn't. diff --git a/src/buffer.c b/src/buffer.c index 03c10cc7ae..8e33162989 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -2419,6 +2419,7 @@ results, see Info node `(elisp)Swapping Text'. */) swapfield (overlay_center, ptrdiff_t); swapfield_ (undo_list, Lisp_Object); swapfield_ (mark, Lisp_Object); + swapfield_ (mark_active, Lisp_Object); /* Belongs with the `mark'. */ swapfield_ (enable_multibyte_characters, Lisp_Object); swapfield_ (bidi_display_reordering, Lisp_Object); swapfield_ (bidi_paragraph_direction, Lisp_Object); commit 29458ec7d2843baa725f9b613d0e935df3a61301 Author: Juri Linkov Date: Tue Mar 9 19:27:31 2021 +0200 * lisp/tab-bar.el (tab-bar-select-tab): Set window-state-put WINDOW arg to nil WINDOW arg nil will always create a new window regardless of the value returned by 'frame-root-window' that is nondeterministic - it returns an internal window when there are more than 1 window on the frame/tab, otherwise it returns a live window that was reused between different tabs (bug#46904) (tab-prefix-map): Bind "u" to 'tab-undo'. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 917b5e496b..2f97bd4eaf 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -766,7 +766,7 @@ ARG counts from 1." tab-bar-history-forward))) (ws - (window-state-put ws (frame-root-window (selected-frame)) 'safe))) + (window-state-put ws nil 'safe))) (setq tab-bar-history-omit t) @@ -1777,6 +1777,7 @@ When `switch-to-buffer-obey-display-actions' is non-nil, (define-key tab-prefix-map "2" 'tab-new) (define-key tab-prefix-map "1" 'tab-close-other) (define-key tab-prefix-map "0" 'tab-close) +(define-key tab-prefix-map "u" 'tab-undo) (define-key tab-prefix-map "o" 'tab-next) (define-key tab-prefix-map "O" 'tab-previous) (define-key tab-prefix-map "m" 'tab-move) commit 7561c01380aa3347901eeddd2d0a466cb29ebbd8 Author: Stefan Monnier Date: Tue Mar 9 11:04:03 2021 -0500 * lisp/emacs-lisp/cconv.el: Don't confuse a string for a docstring (cconv--convert-funcbody): Check there's something after a docstring. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-string-vs-docstring): New corresponding test. diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el index bd0a3e87e6..68e930fa3f 100644 --- a/lisp/emacs-lisp/cconv.el +++ b/lisp/emacs-lisp/cconv.el @@ -295,8 +295,9 @@ of converted forms." (if wrappers (let ((special-forms '())) ;; Keep special forms at the beginning of the body. - (while (or (stringp (car funcbody)) ;docstring. - (memq (car-safe (car funcbody)) '(interactive declare))) + (while (or (and (cdr funcbody) (stringp (car funcbody))) ;docstring. + (memq (car-safe (car funcbody)) + '(interactive declare :documentation))) (push (pop funcbody) special-forms)) (let ((body (macroexp-progn funcbody))) (dolist (wrapper wrappers) (setq body (funcall wrapper body))) diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el index 03c267ccd0..5147cd2688 100644 --- a/test/lisp/emacs-lisp/bytecomp-tests.el +++ b/test/lisp/emacs-lisp/bytecomp-tests.el @@ -1222,6 +1222,11 @@ compiled correctly." (byte-compile 'counter) (should (equal (counter) 1)))))) +(ert-deftest bytecomp-string-vs-docstring () + ;; Don't confuse a string return value for a docstring. + (let ((lexical-binding t)) + (should (equal (funcall (byte-compile '(lambda (x) "foo")) 'dummy) "foo")))) + ;; Local Variables: ;; no-byte-compile: t ;; End: commit 40d8f83e53ba64355035da78967c994d09a7802d Author: Konstantin Kharlamov Date: Tue Mar 9 04:47:49 2021 +0200 smerge-vc-next-conflict: Move to conflict markers more reliably * lisp/vc/smerge-mode.el (smerge-vc-next-conflict): Search for a conflict marker if call to (vc-find-conflicted-file) haven't resulted in a jump to one. And remove `buffer` variable that becomes unused. diff --git a/lisp/vc/smerge-mode.el b/lisp/vc/smerge-mode.el index 782c799273..694d4529b9 100644 --- a/lisp/vc/smerge-mode.el +++ b/lisp/vc/smerge-mode.el @@ -1450,30 +1450,31 @@ If no conflict maker is found, turn off `smerge-mode'." First tries to go to the next conflict in the current buffer, and if not found, uses VC to try and find the next file with conflict." (interactive) - (let ((buffer (current-buffer))) - (condition-case nil - ;; FIXME: Try again from BOB before moving to the next file. - (smerge-next) - (error - (if (and (or smerge-change-buffer-confirm - (and (buffer-modified-p) buffer-file-name)) - (not (or (eq last-command this-command) - (eq ?\r last-command-event)))) ;Called via M-x!? - ;; FIXME: Don't emit this message if `vc-find-conflicted-file' won't - ;; go to another file anyway (because there are no more conflicted - ;; files). - (message (if (buffer-modified-p) - "No more conflicts here. Repeat to save and go to next buffer" - "No more conflicts here. Repeat to go to next buffer")) - (if (and (buffer-modified-p) buffer-file-name) - (save-buffer)) - (vc-find-conflicted-file) - (when (eq buffer (current-buffer)) - ;; Try to find a conflict marker in current file above the point. - (let ((prev-pos (point))) - (goto-char (point-min)) - (unless (ignore-errors (not (smerge-next))) - (goto-char prev-pos))))))))) + (condition-case nil + ;; FIXME: Try again from BOB before moving to the next file. + (smerge-next) + (error + (if (and (or smerge-change-buffer-confirm + (and (buffer-modified-p) buffer-file-name)) + (not (or (eq last-command this-command) + (eq ?\r last-command-event)))) ;Called via M-x!? + ;; FIXME: Don't emit this message if `vc-find-conflicted-file' won't + ;; go to another file anyway (because there are no more conflicted + ;; files). + (message (if (buffer-modified-p) + "No more conflicts here. Repeat to save and go to next buffer" + "No more conflicts here. Repeat to go to next buffer")) + (if (and (buffer-modified-p) buffer-file-name) + (save-buffer)) + (vc-find-conflicted-file) + ;; At this point, the caret will only be at a conflict marker + ;; if the file did not correspond to an opened + ;; buffer. Otherwise we need to jump to a marker explicitly. + (unless (looking-at "^<<<<<<<") + (let ((prev-pos (point))) + (goto-char (point-min)) + (unless (ignore-errors (not (smerge-next))) + (goto-char prev-pos)))))))) (provide 'smerge-mode) commit 853810813283662a71358a11c128c0a1d224197e Author: Dmitry Gutov Date: Tue Mar 9 04:06:01 2021 +0200 Strip text properties from the default string * lisp/progmodes/project.el (project--read-regexp): Strip text properties from the default string (bug#47012). diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index d59da2496a..67e827eea4 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -775,7 +775,7 @@ pattern to search for." xrefs)) (defun project--read-regexp () - (let ((sym (thing-at-point 'symbol))) + (let ((sym (thing-at-point 'symbol t))) (read-regexp "Find regexp" (and sym (regexp-quote sym))))) ;;;###autoload commit 612095220d158a7e8d1d1fb74b264b375ceee508 Author: Lars Ingebrigtsen Date: Mon Mar 8 20:37:31 2021 +0100 Make semantic/idle not move point after last change * lisp/cedet/semantic/idle.el (semantic--eldoc-info): Don't move point (bug#46999). diff --git a/lisp/cedet/semantic/idle.el b/lisp/cedet/semantic/idle.el index 0f997474de..2b6d11f458 100644 --- a/lisp/cedet/semantic/idle.el +++ b/lisp/cedet/semantic/idle.el @@ -734,7 +734,8 @@ Call `semantic-idle-summary-current-symbol-info' for getting the current tag to display information." (or (eq major-mode 'emacs-lisp-mode) (not (semantic-idle-summary-useful-context-p)) - (let* ((found (semantic-idle-summary-current-symbol-info)) + (let* ((found (save-excursion + (semantic-idle-summary-current-symbol-info))) (str (cond ((stringp found) found) ((semantic-tag-p found) (funcall semantic-idle-summary-function commit 9b86a6add8f559dace7a881bd7d8f0652c2a5278 Author: Glenn Morris Date: Mon Mar 8 09:50:43 2021 -0800 ; NEWS fix diff --git a/etc/NEWS b/etc/NEWS index 26bed2af18..d667bcd3b0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -24,7 +24,7 @@ applies, and please also update docstrings as needed. * Installation Changes in Emacs 28.1 --- +--- ** Support for building with Motif has been removed. ** Cairo graphics library is now used by default if found. @@ -69,8 +69,7 @@ It was declared obsolete in Emacs 27.1. --- ** The configure option '--without-makeinfo' has been removed. This was only ever relevant when building from a repository checkout. -Please install makeinfo, or if all else fails run 'make lisp' instead -of 'make [all]'. +This now requires makeinfo, which is part of the texinfo package. --- ** Support for building with '-fcheck-pointer-bounds' has been removed. commit 04c43bb0477682a839187f2df816342d95bf6f21 Author: Juri Linkov Date: Mon Mar 8 19:48:28 2021 +0200 * lisp/progmodes/xref.el (xref-after-update-hook): New defcustom (bug#46992). (xref--insert-xrefs): Use run-hooks on it. diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index af46365325..c066d9dc02 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -411,6 +411,12 @@ elements is negated: these commands will NOT prompt." "Functions called after returning to a pre-jump location." :type 'hook) +(defcustom xref-after-update-hook nil + "Functions called after the xref buffer is updated." + :type 'hook + :version "28.1" + :package-version '(xref . "1.0.4")) + (defvar xref--marker-ring (make-ring xref-marker-ring-length) "Ring of markers to implement the marker stack.") @@ -927,7 +933,8 @@ GROUP is a string for decoration purposes and XREF is an prefix summary) (setq prev-line line prev-group group)))) - (insert "\n"))) + (insert "\n")) + (run-hooks 'xref-after-update-hook)) (defun xref--analyze (xrefs) "Find common filenames in XREFS. commit 7ec870c5383d08b965aae898bbdc206cb9056638 Author: Juri Linkov Date: Mon Mar 8 19:42:44 2021 +0200 * lisp/faces.el (help-argument-name): Use grey background, not foreground https://lists.gnu.org/archive/html/emacs-devel/2021-03/msg00402.html diff --git a/lisp/faces.el b/lisp/faces.el index b2d47edca0..1e668a43f4 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -2816,11 +2816,11 @@ Note: Other faces cannot inherit from the cursor face." :group 'help) (defface help-key-binding - '((((class color) (min-colors 88) (background light)) :foreground "ForestGreen") - (((class color) (min-colors 88) (background dark)) :foreground "#44bc44") - (((class color grayscale) (background light)) :foreground "grey15") - (((class color grayscale) (background dark)) :foreground "grey85") - (t :foreground "ForestGreen")) + '((((class color) (min-colors 88) (background light)) :background "grey90") + (((class color) (min-colors 88) (background dark)) :background "grey25") + (((class color grayscale) (background light)) :background "grey90") + (((class color grayscale) (background dark)) :background "grey25") + (t :background "grey90")) "Face for keybindings in *Help* buffers. This face is added by `substitute-command-keys', which see. commit dc083ebc4e34158b3be4c16d558d104c8c4e5c77 Author: Stefan Monnier Date: Mon Mar 8 10:11:22 2021 -0500 * lisp/net/*.el: Use lexical-binding Also remove some redundant `:group` arguments. * lisp/net/eudc-export.el: Use lexical-binding. (eudc-create-bbdb-record): Use `cl-progv` and `apply` to avoid `eval`. * lisp/net/eudc-hotlist.el: Use lexical-binding. * lisp/net/eudc.el (eudc-print-attribute-value): Use `funcall` to avoid `eval`. * lisp/net/eudcb-bbdb.el: Use lexical-binding. (eudc-bbdb-filter-non-matching-record): Use `funcall` to avoid `eval`. Move `bbdb-val` binding to avoid `setq`. Use `seq-some` instead of `eval+or`. (eudc-bbdb-format-record-as-result): Use `dolist` and `pcase`. Use `funcall` to avoid `eval`. (eudc-bbdb-query-internal): Simplify a bit. * lisp/net/eudcb-ldap.el: Use lexical-binding. (eudc-ldap-get-host-parameter): Use `defalias` to avoid `eval-and-compile`. * lisp/net/telnet.el: Use lexical-binding. * lisp/net/quickurl.el: Use lexical-binding. * lisp/net/newst-ticker.el: Use lexical-binding. * lisp/net/newst-reader.el: Use lexical-binding. * lisp/net/goto-addr.el: Use lexical-binding. * lisp/net/gnutls.el: Use lexical-binding. * lisp/net/eudcb-macos-contacts.el: Use lexical-binding. * lisp/net/eudcb-mab.el: Use lexical-binding. * lisp/net/net-utils.el: Use lexical-binding. (finger): Remove unused var `found`. * lisp/net/network-stream.el (open-protocol-stream): Remove redundant `defalias`. * lisp/net/newst-plainview.el: Use lexical-binding. (newsticker-hide-entry, newsticker-show-entry): Remove unused var `is-invisible`. (w3m-fill-column, w3-maximum-line-length): Declare vars. * lisp/net/tramp.el (tramp-compute-multi-hops): * lisp/net/tramp-compat.el (tramp-compat-temporary-file-directory): * lisp/net/tramp-cmds.el (tramp-default-rename-file): * lisp/net/webjump.el (webjump): Don't forget lexical-binding for `eval`. diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el index 58f01d5bf9..1c98335a20 100644 --- a/lisp/net/browse-url.el +++ b/lisp/net/browse-url.el @@ -826,7 +826,7 @@ If optional arg TEMP-FILE-NAME is non-nil, delete it instead." (if (and file-name (file-exists-p file-name)) (delete-file file-name)))) -(add-hook 'kill-buffer-hook 'browse-url-delete-temp-file) +(add-hook 'kill-buffer-hook #'browse-url-delete-temp-file) (declare-function dired-get-filename "dired" (&optional localp no-error-if-not-filep)) @@ -1064,7 +1064,7 @@ xdg-open is a desktop utility that calls your preferred web browser." (executable-find "xdg-open"))) ;;;###autoload -(defun browse-url-xdg-open (url &optional ignored) +(defun browse-url-xdg-open (url &optional _ignored) "Pass the specified URL to the \"xdg-open\" command. xdg-open is a desktop utility that calls your preferred web browser. The optional argument IGNORED is not used." @@ -1095,7 +1095,7 @@ used instead of `browse-url-new-window-flag'." (setq url (browse-url-encode-url url)) (let* ((process-environment (browse-url-process-environment)) (process - (apply 'start-process + (apply #'start-process (concat "netscape " url) nil browse-url-netscape-program (append @@ -1125,7 +1125,7 @@ used instead of `browse-url-new-window-flag'." (let* ((process-environment (browse-url-process-environment))) ;; Netscape not running - start it (message "Starting %s..." browse-url-netscape-program) - (apply 'start-process (concat "netscape" url) nil + (apply #'start-process (concat "netscape" url) nil browse-url-netscape-program (append browse-url-netscape-startup-arguments (list url)))))) @@ -1144,7 +1144,7 @@ How depends on `browse-url-netscape-version'." "Send a remote control command to Netscape." (declare (obsolete nil "25.1")) (let* ((process-environment (browse-url-process-environment))) - (apply 'start-process "netscape" nil + (apply #'start-process "netscape" nil browse-url-netscape-program (append browse-url-netscape-arguments (list "-remote" command))))) @@ -1170,7 +1170,7 @@ used instead of `browse-url-new-window-flag'." (setq url (browse-url-encode-url url)) (let* ((process-environment (browse-url-process-environment)) (process - (apply 'start-process + (apply #'start-process (concat "mozilla " url) nil browse-url-mozilla-program (append @@ -1196,7 +1196,7 @@ used instead of `browse-url-new-window-flag'." (let* ((process-environment (browse-url-process-environment))) ;; Mozilla is not running - start it (message "Starting %s..." browse-url-mozilla-program) - (apply 'start-process (concat "mozilla " url) nil + (apply #'start-process (concat "mozilla " url) nil browse-url-mozilla-program (append browse-url-mozilla-startup-arguments (list url)))))) @@ -1219,7 +1219,7 @@ instead of `browse-url-new-window-flag'." (interactive (browse-url-interactive-arg "URL: ")) (setq url (browse-url-encode-url url)) (let* ((process-environment (browse-url-process-environment))) - (apply 'start-process + (apply #'start-process (concat "firefox " url) nil browse-url-firefox-program (append @@ -1242,7 +1242,7 @@ The optional argument NEW-WINDOW is not used." (interactive (browse-url-interactive-arg "URL: ")) (setq url (browse-url-encode-url url)) (let* ((process-environment (browse-url-process-environment))) - (apply 'start-process + (apply #'start-process (concat "chromium " url) nil browse-url-chromium-program (append @@ -1260,7 +1260,7 @@ The optional argument NEW-WINDOW is not used." (interactive (browse-url-interactive-arg "URL: ")) (setq url (browse-url-encode-url url)) (let* ((process-environment (browse-url-process-environment))) - (apply 'start-process + (apply #'start-process (concat "google-chrome " url) nil browse-url-chrome-program (append @@ -1290,7 +1290,7 @@ used instead of `browse-url-new-window-flag'." (interactive (browse-url-interactive-arg "URL: ")) (setq url (browse-url-encode-url url)) (let* ((process-environment (browse-url-process-environment)) - (process (apply 'start-process + (process (apply #'start-process (concat "galeon " url) nil browse-url-galeon-program @@ -1315,7 +1315,7 @@ used instead of `browse-url-new-window-flag'." (let* ((process-environment (browse-url-process-environment))) ;; Galeon is not running - start it (message "Starting %s..." browse-url-galeon-program) - (apply 'start-process (concat "galeon " url) nil + (apply #'start-process (concat "galeon " url) nil browse-url-galeon-program (append browse-url-galeon-startup-arguments (list url)))))) @@ -1338,7 +1338,7 @@ used instead of `browse-url-new-window-flag'." (interactive (browse-url-interactive-arg "URL: ")) (setq url (browse-url-encode-url url)) (let* ((process-environment (browse-url-process-environment)) - (process (apply 'start-process + (process (apply #'start-process (concat "epiphany " url) nil browse-url-epiphany-program @@ -1362,7 +1362,7 @@ used instead of `browse-url-new-window-flag'." (let* ((process-environment (browse-url-process-environment))) ;; Epiphany is not running - start it (message "Starting %s..." browse-url-epiphany-program) - (apply 'start-process (concat "epiphany " url) nil + (apply #'start-process (concat "epiphany " url) nil browse-url-epiphany-program (append browse-url-epiphany-startup-arguments (list url)))))) @@ -1403,7 +1403,7 @@ When called non-interactively, optional second argument NEW-WINDOW is used instead of `browse-url-new-window-flag'." (declare (obsolete nil "25.1")) (interactive (browse-url-interactive-arg "URL: ")) - (apply 'start-process (concat "gnome-moz-remote " url) + (apply #'start-process (concat "gnome-moz-remote " url) nil browse-url-gnome-moz-program (append @@ -1437,7 +1437,7 @@ NEW-WINDOW instead of `browse-url-new-window-flag'." (interactive (browse-url-interactive-arg "URL: ")) (setq url (browse-url-encode-url url)) (let* ((process-environment (browse-url-process-environment))) - (apply 'start-process (format "conkeror %s" url) + (apply #'start-process (format "conkeror %s" url) nil browse-url-conkeror-program (append @@ -1487,7 +1487,7 @@ The `browse-url-gnudoit-program' program is used with options given by `browse-url-gnudoit-args'. Default to the URL around or before point." (declare (obsolete nil "25.1")) (interactive (browse-url-interactive-arg "W3 URL: ")) - (apply 'start-process (concat "gnudoit:" url) nil + (apply #'start-process (concat "gnudoit:" url) nil browse-url-gnudoit-program (append browse-url-gnudoit-args (list (concat "(w3-fetch \"" url "\")") @@ -1667,7 +1667,7 @@ don't offer a form of remote control." (interactive (browse-url-interactive-arg "URL: ")) (if (not browse-url-generic-program) (error "No browser defined (`browse-url-generic-program')")) - (apply 'call-process browse-url-generic-program nil + (apply #'call-process browse-url-generic-program nil 0 nil (append browse-url-generic-args (list url)))) @@ -1742,9 +1742,9 @@ from `browse-url-elinks-wrapper'." (defvar browse-url-button-map (let ((map (make-sparse-keymap))) - (define-key map "\r" 'browse-url-button-open) - (define-key map [mouse-2] 'browse-url-button-open) - (define-key map "w" 'browse-url-button-copy) + (define-key map "\r" #'browse-url-button-open) + (define-key map [mouse-2] #'browse-url-button-open) + (define-key map "w" #'browse-url-button-copy) map) "The keymap used for browse-url buttons.") diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el index aba3698a53..5148a66724 100644 --- a/lisp/net/dictionary.el +++ b/lisp/net/dictionary.el @@ -76,7 +76,7 @@ You can specify here: - dict.org: Only use dict.org - User-defined: You can specify your own server here" :group 'dictionary - :set 'dictionary-set-server-var + :set #'dictionary-set-server-var :type '(choice (const :tag "Automatic" nil) (const :tag "localhost" "localhost") (const :tag "dict.org" "dict.org") @@ -88,7 +88,7 @@ You can specify here: "The port of the dictionary server. This port is propably always 2628 so there should be no need to modify it." :group 'dictionary - :set 'dictionary-set-server-var + :set #'dictionary-set-server-var :type 'number :version "28.1") @@ -189,7 +189,7 @@ where the current word was found." nil "Connects via a HTTP proxy using the CONNECT command when not nil." :group 'dictionary-proxy - :set 'dictionary-set-server-var + :set #'dictionary-set-server-var :type 'boolean :version "28.1") @@ -197,7 +197,7 @@ where the current word was found." "proxy" "The name of the HTTP proxy to use when `dictionary-use-http-proxy' is set." :group 'dictionary-proxy - :set 'dictionary-set-server-var + :set #'dictionary-set-server-var :type 'string :version "28.1") @@ -205,7 +205,7 @@ where the current word was found." 3128 "The port of the proxy server, used only when `dictionary-use-http-proxy' is set." :group 'dictionary-proxy - :set 'dictionary-set-server-var + :set #'dictionary-set-server-var :type 'number :version "28.1") @@ -331,19 +331,19 @@ is utf-8" (suppress-keymap map) (set-keymap-parent map button-buffer-map) - (define-key map "q" 'dictionary-close) - (define-key map "h" 'dictionary-help) - (define-key map "s" 'dictionary-search) - (define-key map "d" 'dictionary-lookup-definition) - (define-key map "D" 'dictionary-select-dictionary) - (define-key map "M" 'dictionary-select-strategy) - (define-key map "m" 'dictionary-match-words) - (define-key map "l" 'dictionary-previous) - (define-key map "n" 'forward-button) - (define-key map "p" 'backward-button) - (define-key map " " 'scroll-up-command) - (define-key map [?\S-\ ] 'scroll-down-command) - (define-key map (read-kbd-macro "M-SPC") 'scroll-down-command) + (define-key map "q" #'dictionary-close) + (define-key map "h" #'dictionary-help) + (define-key map "s" #'dictionary-search) + (define-key map "d" #'dictionary-lookup-definition) + (define-key map "D" #'dictionary-select-dictionary) + (define-key map "M" #'dictionary-select-strategy) + (define-key map "m" #'dictionary-match-words) + (define-key map "l" #'dictionary-previous) + (define-key map "n" #'forward-button) + (define-key map "p" #'backward-button) + (define-key map " " #'scroll-up-command) + (define-key map [?\S-\ ] #'scroll-down-command) + (define-key map (read-kbd-macro "M-SPC") #'scroll-down-command) map) "Keymap for the dictionary mode.") @@ -413,7 +413,7 @@ This is a quick reference to this mode describing the default key bindings: (make-local-variable 'dictionary-default-dictionary) (make-local-variable 'dictionary-default-strategy) - (add-hook 'kill-buffer-hook 'dictionary-close t t) + (add-hook 'kill-buffer-hook #'dictionary-close t t) (run-hooks 'dictionary-mode-hook)) ;;;###autoload @@ -535,7 +535,7 @@ The connection takes the proxy setting in customization group ;; Dealing with closing the buffer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun dictionary-close (&rest ignored) +(defun dictionary-close (&rest _ignored) "Close the current dictionary buffer and its connection." (interactive) (if (eq major-mode 'dictionary-mode) @@ -669,7 +669,7 @@ previous state." (setq dictionary-positions (cons (point) (window-start)))) ;; Restore the previous state -(defun dictionary-restore-state (&rest ignored) +(defun dictionary-restore-state (&rest _ignored) "Restore the state just before the last operation." (let ((position (pop dictionary-position-stack)) (data (pop dictionary-data-stack))) @@ -872,7 +872,7 @@ The word is taken from the buffer, the DICTIONARY is given as argument." 'help-echo (concat "Press Mouse-2 to lookup \"" word "\" in \"" dictionary "\""))))) -(defun dictionary-select-dictionary (&rest ignored) +(defun dictionary-select-dictionary (&rest _ignored) "Save the current state and start a dictionary selection." (interactive) (dictionary-ensure-buffer) @@ -880,7 +880,7 @@ The word is taken from the buffer, the DICTIONARY is given as argument." (dictionary-do-select-dictionary) (dictionary-store-state 'dictionary-do-select-dictionary nil)) -(defun dictionary-do-select-dictionary (&rest ignored) +(defun dictionary-do-select-dictionary (&rest _ignored) "The workhorse for doing the dictionary selection." (message "Looking up databases and descriptions") @@ -916,7 +916,7 @@ If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." (dictionary-display-dictionary-line "! \"The first matching dictionary\"") (let* ((reply (dictionary-read-answer)) (list (dictionary-simple-split-string reply "\n+"))) - (mapc 'dictionary-display-dictionary-line list)) + (mapc #'dictionary-display-dictionary-line list)) (dictionary-post-buffer)) (defun dictionary-display-dictionary-line (string) @@ -984,7 +984,7 @@ If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." (dictionary-store-state 'dictionary-display-more-info dictionary)))) -(defun dictionary-select-strategy (&rest ignored) +(defun dictionary-select-strategy (&rest _ignored) "Save the current state and start a strategy selection." (interactive) (dictionary-ensure-buffer) @@ -1014,7 +1014,7 @@ If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." (dictionary-display-strategy-line ". \"The servers default\"") (let* ((reply (dictionary-read-answer)) (list (dictionary-simple-split-string reply "\n+"))) - (mapc 'dictionary-display-strategy-line list)) + (mapc #'dictionary-display-strategy-line list)) (dictionary-post-buffer)) (defun dictionary-display-strategy-line (string) @@ -1030,7 +1030,7 @@ If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." 'help-echo (purecopy "Mouse-2 to select this matching algorithm")) (insert "\n"))))) -(defun dictionary-set-strategy (strategy &rest ignored) +(defun dictionary-set-strategy (strategy &rest _ignored) "Select this STRATEGY as new default." (setq dictionary-default-strategy strategy) (dictionary-restore-state) @@ -1194,7 +1194,7 @@ allows editing it." (describe-function 'dictionary-mode)) ;;;###autoload -(defun dictionary-match-words (&optional pattern &rest ignored) +(defun dictionary-match-words (&optional pattern &rest _ignored) "Search PATTERN in current default dictionary using default strategy." (interactive) ;; can't use interactive because of mouse events @@ -1270,7 +1270,7 @@ allows editing it." (defun dictionary-read-definition (&ignore) (let ((list (dictionary-simple-split-string (dictionary-read-answer) "\n+"))) - (mapconcat 'identity (cdr list) "\n"))) + (mapconcat #'identity (cdr list) "\n"))) ;;; Tooltip support for GNU Emacs (defvar global-dictionary-tooltip-mode @@ -1322,8 +1322,8 @@ will be set to nil." (interactive) (tooltip-mode on) (if on - (add-hook 'tooltip-functions 'dictionary-display-tooltip) - (remove-hook 'tooltip-functions 'dictionary-display-tooltip))) + (add-hook 'tooltip-functions #'dictionary-display-tooltip) + (remove-hook 'tooltip-functions #'dictionary-display-tooltip))) ;;;###autoload (defun dictionary-tooltip-mode (&optional arg) @@ -1364,9 +1364,8 @@ any buffer where (dictionary-tooltip-mode 1) has been called." (make-local-variable 'dictionary-tooltip-mouse-event) (setq-default track-mouse on) (dictionary-switch-tooltip-mode 1) - (if on - (global-set-key [mouse-movement] 'dictionary-tooltip-track-mouse) - (global-set-key [mouse-movement] 'ignore)) + (global-set-key [mouse-movement] + (if on #'dictionary-tooltip-track-mouse #'ignore)) on)) (provide 'dictionary) diff --git a/lisp/net/dig.el b/lisp/net/dig.el index 92dcf73250..ddbfb9598b 100644 --- a/lisp/net/dig.el +++ b/lisp/net/dig.el @@ -79,7 +79,7 @@ and is a commonly available debugging tool." (push domain cmdline) (if server (push (concat "@" server) cmdline) (if dig-dns-server (push (concat "@" dig-dns-server) cmdline))) - (apply 'call-process dig-program nil buf nil cmdline) + (apply #'call-process dig-program nil buf nil cmdline) buf)) (defun dig-extract-rr (domain &optional type class) @@ -120,7 +120,7 @@ Buffer should contain output generated by `dig-invoke'." (defvar dig-mode-map (let ((map (make-sparse-keymap))) (define-key map "g" nil) - (define-key map "q" 'dig-exit) + (define-key map "q" #'dig-exit) map)) (define-derived-mode dig-mode special-mode "Dig" diff --git a/lisp/net/dns.el b/lisp/net/dns.el index 90776e3c6f..1086bab946 100644 --- a/lisp/net/dns.el +++ b/lisp/net/dns.el @@ -135,8 +135,8 @@ updated. Set this variable to t to disable the check.") (if (stringp ended) (if (null name) ended - (concat (mapconcat 'identity (nreverse name) ".") "." ended)) - (mapconcat 'identity (nreverse name) ".")))) + (concat (mapconcat #'identity (nreverse name) ".") "." ended)) + (mapconcat #'identity (nreverse name) ".")))) (defun dns-write (spec &optional tcp-p) "Write a DNS packet according to SPEC. @@ -283,7 +283,7 @@ If TCP-P, the first two bytes of the packet will be the length field." (let ((bytes nil)) (dotimes (_ 4) (push (dns-read-bytes 1) bytes)) - (mapconcat 'number-to-string (nreverse bytes) "."))) + (mapconcat #'number-to-string (nreverse bytes) "."))) ((eq type 'AAAA) (let (hextets) (dotimes (_ 8) @@ -386,7 +386,7 @@ If REVERSE, look up an IP address." (when reverse (setq name (concat - (mapconcat 'identity (nreverse (split-string name "\\.")) ".") + (mapconcat #'identity (nreverse (split-string name "\\.")) ".") ".in-addr.arpa") type 'PTR)) diff --git a/lisp/net/eudc-bob.el b/lisp/net/eudc-bob.el index 456d70ee0f..1d7af7f5b5 100644 --- a/lisp/net/eudc-bob.el +++ b/lisp/net/eudc-bob.el @@ -41,38 +41,38 @@ (defvar eudc-bob-generic-keymap (let ((map (make-sparse-keymap))) - (define-key map "s" 'eudc-bob-save-object) - (define-key map "!" 'eudc-bob-pipe-object-to-external-program) - (define-key map [down-mouse-3] 'eudc-bob-popup-menu) + (define-key map "s" #'eudc-bob-save-object) + (define-key map "!" #'eudc-bob-pipe-object-to-external-program) + (define-key map [down-mouse-3] #'eudc-bob-popup-menu) map) "Keymap for multimedia objects.") (defvar eudc-bob-image-keymap (let ((map (make-sparse-keymap))) (set-keymap-parent map eudc-bob-generic-keymap) - (define-key map "t" 'eudc-bob-toggle-inline-display) + (define-key map "t" #'eudc-bob-toggle-inline-display) map) "Keymap for inline images.") (defvar eudc-bob-sound-keymap (let ((map (make-sparse-keymap))) (set-keymap-parent map eudc-bob-generic-keymap) - (define-key map (kbd "RET") 'eudc-bob-play-sound-at-point) - (define-key map [down-mouse-2] 'eudc-bob-play-sound-at-mouse) + (define-key map (kbd "RET") #'eudc-bob-play-sound-at-point) + (define-key map [down-mouse-2] #'eudc-bob-play-sound-at-mouse) map) "Keymap for inline sounds.") (defvar eudc-bob-url-keymap (let ((map (make-sparse-keymap))) - (define-key map (kbd "RET") 'browse-url-at-point) - (define-key map [down-mouse-2] 'browse-url-at-mouse) + (define-key map (kbd "RET") #'browse-url-at-point) + (define-key map [down-mouse-2] #'browse-url-at-mouse) map) "Keymap for inline urls.") (defvar eudc-bob-mail-keymap (let ((map (make-sparse-keymap))) - (define-key map (kbd "RET") 'goto-address-at-point) - (define-key map [down-mouse-2] 'goto-address-at-point) + (define-key map (kbd "RET") #'goto-address-at-point) + (define-key map [down-mouse-2] #'goto-address-at-point) map) "Keymap for inline e-mail addresses.") diff --git a/lisp/net/eudc-export.el b/lisp/net/eudc-export.el index bac75e6555..66db7814ad 100644 --- a/lisp/net/eudc-export.el +++ b/lisp/net/eudc-export.el @@ -1,4 +1,4 @@ -;;; eudc-export.el --- functions to export EUDC query results +;;; eudc-export.el --- functions to export EUDC query results -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2021 Free Software Foundation, Inc. @@ -35,6 +35,7 @@ ;; NOERROR is so we can compile it. (require 'bbdb nil t) (require 'bbdb-com nil t) +(require 'cl-lib) (defun eudc-create-bbdb-record (record &optional silent) "Create a BBDB record using the RECORD alist. @@ -42,24 +43,22 @@ RECORD is an alist of (KEY . VALUE) where KEY is a directory attribute name symbol and VALUE is the corresponding value for the record. If SILENT is non-nil then the created BBDB record is not displayed." (require 'bbdb) + (declare-function bbdb-create-internal "bbdb-com" (&rest spec)) + (declare-function bbdb-display-records "bbdb" + (records &optional layout append)) ;; This function runs in a special context where lisp symbols corresponding ;; to field names in record are bound to the corresponding values - (eval - `(let* (,@(mapcar (lambda (c) - (list (car c) (if (listp (cdr c)) - (list 'quote (cdr c)) - (cdr c)))) - record) - bbdb-name - bbdb-company - bbdb-net - bbdb-address - bbdb-phones - bbdb-notes - spec - bbdb-record - value - (conversion-alist (symbol-value eudc-bbdb-conversion-alist))) + (cl-progv (mapcar #'car record) (mapcar #'cdr record) + (let* (bbdb-name + bbdb-company + bbdb-net + bbdb-address + bbdb-phones + bbdb-notes + spec + bbdb-record + value + (conversion-alist (symbol-value eudc-bbdb-conversion-alist))) ;; BBDB standard fields (setq bbdb-name (eudc-parse-spec (cdr (assq 'name conversion-alist)) record nil) @@ -68,14 +67,14 @@ If SILENT is non-nil then the created BBDB record is not displayed." bbdb-notes (eudc-parse-spec (cdr (assq 'notes conversion-alist)) record nil)) (setq spec (cdr (assq 'address conversion-alist))) (setq bbdb-address (delq nil (eudc-parse-spec (if (listp (car spec)) - spec - (list spec)) - record t))) + spec + (list spec)) + record t))) (setq spec (cdr (assq 'phone conversion-alist))) (setq bbdb-phones (delq nil (eudc-parse-spec (if (listp (car spec)) - spec - (list spec)) - record t))) + spec + (list spec)) + record t))) ;; BBDB custom fields (setq bbdb-notes (append (list (and bbdb-notes (cons 'notes bbdb-notes))) (mapcar (lambda (mapping) @@ -85,19 +84,20 @@ If SILENT is non-nil then the created BBDB record is not displayed." (cons (car mapping) value))) conversion-alist))) (setq bbdb-notes (delq nil bbdb-notes)) - (setq bbdb-record (bbdb-create-internal - bbdb-name - ,@(when (eudc--using-bbdb-3-or-newer-p) - '(nil - nil)) - bbdb-company - bbdb-net - ,@(if (eudc--using-bbdb-3-or-newer-p) - '(bbdb-phones - bbdb-address) - '(bbdb-address - bbdb-phones)) - bbdb-notes)) + (setq bbdb-record + (apply #'bbdb-create-internal + `(,bbdb-name + ,@(when (eudc--using-bbdb-3-or-newer-p) + '(nil + nil)) + ,bbdb-company + ,bbdb-net + ,@(if (eudc--using-bbdb-3-or-newer-p) + (list bbdb-phones + bbdb-address) + (list bbdb-address + bbdb-phones)) + ,bbdb-notes))) (or silent (bbdb-display-records (list bbdb-record)))))) @@ -111,7 +111,7 @@ If RECURSE is non-nil then SPEC may be a list of atomic specs." (symbolp (car spec)) (fboundp (car spec)))) (condition-case nil - (eval spec) + (eval spec t) (void-variable nil))) ((and recurse (listp spec)) @@ -194,9 +194,9 @@ LOCATION is used as the phone location for BBDB." (signal (car err) (cdr err))))) (if (= 3 (length phone-list)) (setq phone-list (append phone-list '(nil)))) - (apply 'vector location phone-list))) + (apply #'vector location phone-list))) ((listp phone) - (vector location (mapconcat 'identity phone ", "))) + (vector location (mapconcat #'identity phone ", "))) (t (error "Invalid phone specification")))) diff --git a/lisp/net/eudc-hotlist.el b/lisp/net/eudc-hotlist.el index e4b7e8ae71..a737a99ce9 100644 --- a/lisp/net/eudc-hotlist.el +++ b/lisp/net/eudc-hotlist.el @@ -1,4 +1,4 @@ -;;; eudc-hotlist.el --- hotlist management for EUDC +;;; eudc-hotlist.el --- hotlist management for EUDC -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2021 Free Software Foundation, Inc. @@ -37,12 +37,12 @@ (defvar eudc-hotlist-mode-map (let ((map (make-sparse-keymap))) - (define-key map "a" 'eudc-hotlist-add-server) - (define-key map "d" 'eudc-hotlist-delete-server) - (define-key map "s" 'eudc-hotlist-select-server) - (define-key map "t" 'eudc-hotlist-transpose-servers) - (define-key map "q" 'eudc-hotlist-quit-edit) - (define-key map "x" 'kill-current-buffer) + (define-key map "a" #'eudc-hotlist-add-server) + (define-key map "d" #'eudc-hotlist-delete-server) + (define-key map "s" #'eudc-hotlist-select-server) + (define-key map "t" #'eudc-hotlist-transpose-servers) + (define-key map "q" #'eudc-hotlist-quit-edit) + (define-key map "x" #'kill-current-buffer) map)) (define-derived-mode eudc-hotlist-mode fundamental-mode "EUDC-Servers" diff --git a/lisp/net/eudc.el b/lisp/net/eudc.el index 4f048045d5..c112d27330 100644 --- a/lisp/net/eudc.el +++ b/lisp/net/eudc.el @@ -65,12 +65,12 @@ (defvar eudc-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map widget-keymap) - (define-key map "q" 'kill-current-buffer) - (define-key map "x" 'kill-current-buffer) - (define-key map "f" 'eudc-query-form) - (define-key map "b" 'eudc-try-bbdb-insert) - (define-key map "n" 'eudc-move-to-next-record) - (define-key map "p" 'eudc-move-to-previous-record) + (define-key map "q" #'kill-current-buffer) + (define-key map "x" #'kill-current-buffer) + (define-key map "f" #'eudc-query-form) + (define-key map "b" #'eudc-try-bbdb-insert) + (define-key map "n" #'eudc-move-to-next-record) + (define-key map "p" #'eudc-move-to-previous-record) map)) (defvar mode-popup-menu) @@ -407,7 +407,7 @@ if any, is called to print the value in cdr of FIELD." (val (cdr field))) (if match (progn - (eval (list (cdr match) val)) + (funcall (cdr match) val) (insert "\n")) (mapc (lambda (val-elem) diff --git a/lisp/net/eudcb-bbdb.el b/lisp/net/eudcb-bbdb.el index e11458b29c..e241a1c2fa 100644 --- a/lisp/net/eudcb-bbdb.el +++ b/lisp/net/eudcb-bbdb.el @@ -1,4 +1,4 @@ -;;; eudcb-bbdb.el --- Emacs Unified Directory Client - BBDB Backend +;;; eudcb-bbdb.el --- Emacs Unified Directory Client - BBDB Backend -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2021 Free Software Foundation, Inc. @@ -34,6 +34,7 @@ ;; Make it loadable on systems without bbdb. (require 'bbdb nil t) (require 'bbdb-com nil t) +(require 'seq) ;;{{{ Internal cooking @@ -87,33 +88,30 @@ BBDB < 3 used `net'; BBDB >= 3 uses `mail'." "Return RECORD if it matches `eudc-bbdb-current-query', nil otherwise." (require 'bbdb) (catch 'unmatch - (progn - (dolist (condition eudc-bbdb-current-query) - (let ((attr (car condition)) - (val (cdr condition)) - (case-fold-search t) - bbdb-val) - (or (and (memq attr '(firstname lastname aka company phones - addresses net)) - (progn - (setq bbdb-val - (eval (list (intern (concat "bbdb-record-" - (symbol-name - (eudc-bbdb-field - attr)))) - 'record))) - (if (listp bbdb-val) - (if eudc-bbdb-enable-substring-matches - (eval `(or ,@(mapcar (lambda (subval) - (string-match val subval)) - bbdb-val))) - (member (downcase val) - (mapcar 'downcase bbdb-val))) + (dolist (condition eudc-bbdb-current-query) + (let ((attr (car condition)) + (val (cdr condition)) + (case-fold-search t)) + (or (and (memq attr '(firstname lastname aka company phones + addresses net)) + (let ((bbdb-val + (funcall (intern (concat "bbdb-record-" + (symbol-name + (eudc-bbdb-field + attr)))) + record))) + (if (listp bbdb-val) (if eudc-bbdb-enable-substring-matches - (string-match val bbdb-val) - (string-equal (downcase val) (downcase bbdb-val)))))) - (throw 'unmatch nil)))) - record))) + (seq-some (lambda (subval) + (string-match val subval)) + bbdb-val) + (member (downcase val) + (mapcar #'downcase bbdb-val))) + (if eudc-bbdb-enable-substring-matches + (string-match val bbdb-val) + (string-equal (downcase val) (downcase bbdb-val)))))) + (throw 'unmatch nil)))) + record)) ;; External. (declare-function bbdb-phone-location "ext:bbdb" t) ; via bbdb-defstruct @@ -182,40 +180,34 @@ The record is filtered according to `eudc-bbdb-current-return-attributes'." (require 'bbdb) (let ((attrs (or eudc-bbdb-current-return-attributes '(firstname lastname aka company phones addresses net notes))) - attr - eudc-rec - val) - (while (prog1 - (setq attr (car attrs)) - (setq attrs (cdr attrs))) - (cond - ((eq attr 'phones) - (setq val (eudc-bbdb-extract-phones record))) - ((eq attr 'addresses) - (setq val (eudc-bbdb-extract-addresses record))) - ((eq attr 'notes) - (if (eudc--using-bbdb-3-or-newer-p) - (setq val (bbdb-record-xfield record 'notes)) - (setq val (bbdb-record-notes record)))) - ((memq attr '(firstname lastname aka company net)) - (setq val (eval - (list (intern - (concat "bbdb-record-" - (symbol-name (eudc-bbdb-field attr)))) - 'record)))) - (t - (error "Unknown BBDB attribute"))) - (cond - ((or (not val) (equal val ""))) ; do nothing - ((memq attr '(phones addresses)) - (setq eudc-rec (append val eudc-rec))) - ((and (listp val) - (= 1 (length val))) - (setq eudc-rec (cons (cons attr (car val)) eudc-rec))) - ((> (length val) 0) - (setq eudc-rec (cons (cons attr val) eudc-rec))) - (t - (error "Unexpected attribute value")))) + eudc-rec) + (dolist (attr attrs) + (let ((val + (pcase attr + ('phones (eudc-bbdb-extract-phones record)) + ('addresses (eudc-bbdb-extract-addresses record)) + ('notes + (if (eudc--using-bbdb-3-or-newer-p) + (bbdb-record-xfield record 'notes) + (bbdb-record-notes record))) + ((or 'firstname 'lastname 'aka 'company 'net) + (funcall (intern + (concat "bbdb-record-" + (symbol-name (eudc-bbdb-field attr)))) + record)) + (_ + (error "Unknown BBDB attribute"))))) + (cond + ((or (not val) (equal val ""))) ; do nothing + ((memq attr '(phones addresses)) + (setq eudc-rec (append val eudc-rec))) + ((and (listp val) + (= 1 (length val))) + (push (cons attr (car val)) eudc-rec)) + ((> (length val) 0) + (push (cons attr val) eudc-rec)) + (t + (error "Unexpected attribute value"))))) (nreverse eudc-rec))) @@ -240,21 +232,20 @@ RETURN-ATTRS is a list of attributes to return, defaulting to (while (and records (> (length query-attrs) 0)) (setq bbdb-attrs (append bbdb-attrs (list (car query-attrs)))) (if (car query-attrs) - (setq records (eval `(bbdb-search ,(quote records) ,@bbdb-attrs)))) + ;; BEWARE: `bbdb-search' is a macro! + (setq records (eval `(bbdb-search records ,@bbdb-attrs) t))) (setq query-attrs (cdr query-attrs))) (mapc (lambda (record) (setq filtered (eudc-filter-duplicate-attributes record)) ;; If there were duplicate attributes reverse the order of the ;; record so the unique attributes appear first (if (> (length filtered) 1) - (setq filtered (mapcar (lambda (rec) - (reverse rec)) - filtered))) + (setq filtered (mapcar #'reverse filtered))) (setq result (append result filtered))) (delq nil - (mapcar 'eudc-bbdb-format-record-as-result + (mapcar #'eudc-bbdb-format-record-as-result (delq nil - (mapcar 'eudc-bbdb-filter-non-matching-record + (mapcar #'eudc-bbdb-filter-non-matching-record records))))) result)) diff --git a/lisp/net/eudcb-ldap.el b/lisp/net/eudcb-ldap.el index 4623079ea9..0aff276475 100644 --- a/lisp/net/eudcb-ldap.el +++ b/lisp/net/eudcb-ldap.el @@ -1,4 +1,4 @@ -;;; eudcb-ldap.el --- Emacs Unified Directory Client - LDAP Backend +;;; eudcb-ldap.el --- Emacs Unified Directory Client - LDAP Backend -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2021 Free Software Foundation, Inc. @@ -38,10 +38,10 @@ ;;{{{ Internal cooking -(eval-and-compile +(defalias 'eudc-ldap-get-host-parameter (if (fboundp 'ldap-get-host-parameter) - (fset 'eudc-ldap-get-host-parameter 'ldap-get-host-parameter) - (defun eudc-ldap-get-host-parameter (host parameter) + #'ldap-get-host-parameter + (lambda (host parameter) "Get the value of PARAMETER for HOST in `ldap-host-parameters-alist'." (plist-get (cdr (assoc host ldap-host-parameters-alist)) parameter)))) @@ -84,7 +84,7 @@ record)) (defun eudc-filter-$ (string) - (mapconcat 'identity (split-string string "\\$") "\n")) + (mapconcat #'identity (split-string string "\\$") "\n")) (defun eudc-ldap-cleanup-record-filtering-addresses (record) "Clean up RECORD to make it suitable for EUDC. @@ -104,7 +104,7 @@ multiple addresses." (value (cdr field))) (when (and clean-up-addresses (memq name '(postaladdress registeredaddress))) - (setq value (mapcar 'eudc-filter-$ value))) + (setq value (mapcar #'eudc-filter-$ value))) (if (eq name 'mail) (setq mail-addresses (append mail-addresses value)) (push (cons name (if (cdr value) @@ -126,9 +126,9 @@ RETURN-ATTRS is a list of attributes to return, defaulting to (let ((result (ldap-search (eudc-ldap-format-query-as-rfc1558 query) eudc-server (if (listp return-attrs) - (mapcar 'symbol-name return-attrs)))) + (mapcar #'symbol-name return-attrs)))) final-result) - (setq result (mapcar 'eudc-ldap-cleanup-record-filtering-addresses result)) + (setq result (mapcar #'eudc-ldap-cleanup-record-filtering-addresses result)) (if (and eudc-strict-return-matches return-attrs @@ -154,7 +154,7 @@ attribute names are returned. Default to `person'." (let ((ldap-host-parameters-alist (list (cons eudc-server '(scope subtree sizelimit 1))))) - (mapcar 'eudc-ldap-cleanup-record-filtering-addresses + (mapcar #'eudc-ldap-cleanup-record-filtering-addresses (ldap-search (eudc-ldap-format-query-as-rfc1558 (list (cons "objectclass" diff --git a/lisp/net/eudcb-mab.el b/lisp/net/eudcb-mab.el index eb7032ac4c..732881f75a 100644 --- a/lisp/net/eudcb-mab.el +++ b/lisp/net/eudcb-mab.el @@ -1,4 +1,4 @@ -;;; eudcb-mab.el --- Emacs Unified Directory Client - AddressBook backend +;;; eudcb-mab.el --- Emacs Unified Directory Client - AddressBook backend -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2021 Free Software Foundation, Inc. diff --git a/lisp/net/eudcb-macos-contacts.el b/lisp/net/eudcb-macos-contacts.el index b07016c122..18c8958c16 100644 --- a/lisp/net/eudcb-macos-contacts.el +++ b/lisp/net/eudcb-macos-contacts.el @@ -1,4 +1,4 @@ -;;; eudcb-macos-contacts.el --- EUDC - macOS Contacts backend +;;; eudcb-macos-contacts.el --- EUDC - macOS Contacts backend -*- lexical-binding: t; -*- ;; Copyright (C) 2020-2021 Free Software Foundation, Inc. @@ -74,7 +74,7 @@ end tell" str)) "`osascript' executable not found. " "Is this is a macOS 10.0 or later system?")))) -(defun eudc-macos-contacts-query-internal (query &optional return-attrs) +(defun eudc-macos-contacts-query-internal (query &optional _return-attrs) "Query macOS Contacts with QUERY. QUERY is a list of cons cells (ATTR . VALUE) where ATTRs should be valid macOS Contacts attribute names. diff --git a/lisp/net/gnutls.el b/lisp/net/gnutls.el index ff58cbb035..9c7bcdc261 100644 --- a/lisp/net/gnutls.el +++ b/lisp/net/gnutls.el @@ -1,4 +1,4 @@ -;;; gnutls.el --- Support SSL/TLS connections through GnuTLS +;;; gnutls.el --- Support SSL/TLS connections through GnuTLS -*- lexical-binding: t; -*- ;; Copyright (C) 2010-2021 Free Software Foundation, Inc. @@ -59,7 +59,6 @@ general, Emacs network security is handled by the Network Security Manager (NSM), and the default value of nil delegates the job of checking the connection security to the NSM. See Info node `(emacs) Network Security'." - :group 'gnutls :type '(choice (const nil) string)) @@ -91,7 +90,6 @@ checks are performed at the gnutls level. Instead the checks are performed via `open-network-stream' at a higher level by the Network Security Manager. See Info node `(emacs) Network Security'." - :group 'gnutls :version "24.4" :type '(choice (const t) @@ -118,7 +116,6 @@ Security'." If a file path contains glob wildcards, they will be expanded. The files may be in PEM or DER format, as per the GnuTLS documentation. The files may not exist, in which case they will be ignored." - :group 'gnutls :type '(choice (function :tag "Function to produce list of bundle filenames") (repeat (file :tag "Bundle filename")))) @@ -139,7 +136,6 @@ network security is handled at a higher level via node `(emacs) Network Security'." :type '(choice (const :tag "Use default value" nil) (integer :tag "Number of bits" 2048)) - :group 'gnutls :version "27.1") (defcustom gnutls-crlfiles @@ -150,7 +146,6 @@ node `(emacs) Network Security'." If a file path contains glob wildcards, they will be expanded. The files may be in PEM or DER format, as per the GnuTLS documentation. The files may not exist, in which case they will be ignored." - :group 'gnutls :type '(choice (function :tag "Function to produce list of CRL filenames") (repeat (file :tag "CRL filename"))) :version "27.1") diff --git a/lisp/net/goto-addr.el b/lisp/net/goto-addr.el index d192630247..af12f6970a 100644 --- a/lisp/net/goto-addr.el +++ b/lisp/net/goto-addr.el @@ -1,4 +1,4 @@ -;;; goto-addr.el --- click to browse URL or to send to e-mail address +;;; goto-addr.el --- click to browse URL or to send to e-mail address -*- lexical-binding: t; -*- ;; Copyright (C) 1995, 2000-2021 Free Software Foundation, Inc. @@ -73,19 +73,16 @@ (defcustom goto-address-fontify-p t "Non-nil means URLs and e-mail addresses in buffer are fontified. But only if `goto-address-highlight-p' is also non-nil." - :type 'boolean - :group 'goto-address) + :type 'boolean) (defcustom goto-address-highlight-p t "Non-nil means URLs and e-mail addresses in buffer are highlighted." - :type 'boolean - :group 'goto-address) + :type 'boolean) (defcustom goto-address-fontify-maximum-size 30000 "Maximum size of file in which to fontify and/or highlight URLs. A value of t means there is no limit--fontify regardless of the size." - :type '(choice (integer :tag "Maximum size") (const :tag "No limit" t)) - :group 'goto-address) + :type '(choice (integer :tag "Maximum size") (const :tag "No limit" t))) (defvar goto-address-mail-regexp ;; Actually pretty much any char could appear in the username part. -stef @@ -122,30 +119,26 @@ will have no effect.") (defvar goto-address-highlight-keymap (let ((m (make-sparse-keymap))) - (define-key m (kbd "") 'goto-address-at-point) - (define-key m (kbd "C-c RET") 'goto-address-at-point) + (define-key m (kbd "") #'goto-address-at-point) + (define-key m (kbd "C-c RET") #'goto-address-at-point) m) "Keymap to hold goto-addr's mouse key defs under highlighted URLs.") (defcustom goto-address-url-face 'link "Face to use for URLs." - :type 'face - :group 'goto-address) + :type 'face) (defcustom goto-address-url-mouse-face 'highlight "Face to use for URLs when the mouse is on them." - :type 'face - :group 'goto-address) + :type 'face) (defcustom goto-address-mail-face 'italic "Face to use for e-mail addresses." - :type 'face - :group 'goto-address) + :type 'face) (defcustom goto-address-mail-mouse-face 'secondary-selection "Face to use for e-mail addresses when the mouse is on them." - :type 'face - :group 'goto-address) + :type 'face) (defun goto-address-unfontify (start end) "Remove `goto-address' fontification from the given region." @@ -287,7 +280,6 @@ Also fontifies the buffer appropriately (see `goto-address-fontify-p' and ;;;###autoload (define-globalized-minor-mode global-goto-address-mode goto-address-mode goto-addr-mode--turn-on - :group 'goto-address :version "28.1") ;;;###autoload diff --git a/lisp/net/net-utils.el b/lisp/net/net-utils.el index d5aad3a3f7..3a561a0ea5 100644 --- a/lisp/net/net-utils.el +++ b/lisp/net/net-utils.el @@ -1,4 +1,4 @@ -;;; net-utils.el --- network functions +;;; net-utils.el --- network functions -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2021 Free Software Foundation, Inc. @@ -67,17 +67,14 @@ "tracert" "traceroute") "Program to trace network hops to a destination." - :group 'net-utils :type 'string) (defcustom traceroute-program-options nil "Options for the traceroute program." - :group 'net-utils :type '(repeat string)) (defcustom ping-program "ping" "Program to send network test packets to a host." - :group 'net-utils :type 'string) ;; On GNU/Linux and Irix, the system's ping program seems to send packets @@ -87,7 +84,6 @@ (list "-c" "4")) "Options for the ping program. These options can be used to limit how many ICMP packets are emitted." - :group 'net-utils :type '(repeat string)) (defcustom ifconfig-program @@ -98,7 +94,6 @@ These options can be used to limit how many ICMP packets are emitted." (t "ip")) "Program to print network configuration information." :version "25.1" ; add ip - :group 'net-utils :type 'string) (defcustom ifconfig-program-options @@ -108,7 +103,6 @@ These options can be used to limit how many ICMP packets are emitted." "Options for the ifconfig program." :version "25.1" :set-after '(ifconfig-program) - :group 'net-utils :type '(repeat string)) (defcustom iwconfig-program @@ -116,7 +110,6 @@ These options can be used to limit how many ICMP packets are emitted." ((net-utils--executable-find-sbin "iw") "iw") (t "iw")) "Program to print wireless network configuration information." - :group 'net-utils :type 'string :version "26.1") @@ -124,7 +117,6 @@ These options can be used to limit how many ICMP packets are emitted." (cond ((string-match-p "iw\\'" iwconfig-program) (list "dev")) (t nil)) "Options for the iwconfig program." - :group 'net-utils :type '(repeat string) :version "26.1") @@ -133,25 +125,21 @@ These options can be used to limit how many ICMP packets are emitted." ((net-utils--executable-find-sbin "ss")) (t "ss")) "Program to print network statistics." - :group 'net-utils :type 'string :version "26.1") (defcustom netstat-program-options (list "-a") "Options for the netstat program." - :group 'net-utils :type '(repeat string)) (defcustom arp-program (or (net-utils--executable-find-sbin "arp") "arp") "Program to print IP to address translation tables." - :group 'net-utils :type 'string) (defcustom arp-program-options (list "-a") "Options for the arp program." - :group 'net-utils :type '(repeat string)) (defcustom route-program @@ -162,7 +150,6 @@ These options can be used to limit how many ICMP packets are emitted." ((net-utils--executable-find-sbin "ip")) (t "ip")) "Program to print routing tables." - :group 'net-utils :type 'string :version "26.1") @@ -171,18 +158,15 @@ These options can be used to limit how many ICMP packets are emitted." ((string-match-p "netstat\\'" route-program) (list "-r")) (t (list "route"))) "Options for the route program." - :group 'net-utils :type '(repeat string) :version "26.1") (defcustom nslookup-program "nslookup" "Program to interactively query DNS information." - :group 'net-utils :type 'string) (defcustom nslookup-program-options nil "Options for the nslookup program." - :group 'net-utils :type '(repeat string)) (defcustom nslookup-prompt-regexp "^> " @@ -190,28 +174,23 @@ These options can be used to limit how many ICMP packets are emitted." This variable is only used if the variable `comint-use-prompt-regexp' is non-nil." - :group 'net-utils :type 'regexp) (defcustom dig-program "dig" "Program to query DNS information." - :group 'net-utils :type 'string) (defcustom dig-program-options nil "Options for the dig program." - :group 'net-utils :type '(repeat string) :version "26.1") (defcustom ftp-program "ftp" "Program to run to do FTP transfers." - :group 'net-utils :type 'string) (defcustom ftp-program-options nil "Options for the ftp program." - :group 'net-utils :type '(repeat string)) (defcustom ftp-prompt-regexp "^ftp>" @@ -219,17 +198,14 @@ This variable is only used if the variable This variable is only used if the variable `comint-use-prompt-regexp' is non-nil." - :group 'net-utils :type 'regexp) (defcustom smbclient-program "smbclient" "Smbclient program." - :group 'net-utils :type 'string) (defcustom smbclient-program-options nil "Options for the smbclient program." - :group 'net-utils :type '(repeat string)) (defcustom smbclient-prompt-regexp "^smb: >" @@ -237,17 +213,14 @@ This variable is only used if the variable This variable is only used if the variable `comint-use-prompt-regexp' is non-nil." - :group 'net-utils :type 'regexp) (defcustom dns-lookup-program "host" "Program to interactively query DNS information." - :group 'net-utils :type 'string) (defcustom dns-lookup-program-options nil "Options for the dns-lookup program." - :group 'net-utils :type '(repeat string)) ;; Internal variables @@ -265,7 +238,7 @@ This variable is only used if the variable 1 'font-lock-keyword-face) ;; Dotted quads (list - (mapconcat 'identity + (mapconcat #'identity (make-list 4 "[0-9]+") "\\.") 0 'font-lock-variable-name-face) @@ -273,7 +246,7 @@ This variable is only used if the variable (list (let ((host-expression "[-A-Za-z0-9]+")) (concat - (mapconcat 'identity + (mapconcat #'identity (make-list 2 host-expression) "\\.") "\\(\\." host-expression "\\)*")) @@ -288,7 +261,7 @@ This variable is only used if the variable (list ;; Dotted quads (list - (mapconcat 'identity (make-list 4 "[0-9]+") "\\.") + (mapconcat #'identity (make-list 4 "[0-9]+") "\\.") 0 'font-lock-variable-name-face) ;; Simple rfc4291 addresses (list (concat @@ -300,7 +273,7 @@ This variable is only used if the variable (list (let ((host-expression "[-A-Za-z0-9]+")) (concat - (mapconcat 'identity (make-list 2 host-expression) "\\.") + (mapconcat #'identity (make-list 2 host-expression) "\\.") "\\(\\." host-expression "\\)*")) 0 'font-lock-variable-name-face)) "Expressions to font-lock for general network utilities.") @@ -371,8 +344,8 @@ This variable is only used if the variable (erase-buffer) (insert header "\n") (set-process-filter - (apply 'start-process name buf program args) - 'net-utils-remove-ctrl-m-filter) + (apply #'start-process name buf program args) + #'net-utils-remove-ctrl-m-filter) (display-buffer buf) buf)) @@ -405,12 +378,12 @@ This variable is only used if the variable `(net-utils-run-simple ,(current-buffer) ,program-name ,args nodisplay)) (set-process-filter - (apply 'start-process program-name - (current-buffer) program-name args) - 'net-utils-remove-ctrl-m-filter) + (apply #'start-process program-name + (current-buffer) program-name args) + #'net-utils-remove-ctrl-m-filter) (unless nodisplay (display-buffer (current-buffer))))) -(defun net-utils--revert-function (&optional ignore-auto noconfirm) +(defun net-utils--revert-function (&optional _ignore-auto _noconfirm) (message "Reverting `%s'..." (buffer-name)) (apply (car net-utils--revert-cmd) (cdr net-utils--revert-cmd)) (let ((proc (get-buffer-process (current-buffer)))) @@ -430,7 +403,7 @@ This variable is only used if the variable ifconfig-program ifconfig-program-options)) -(defalias 'ipconfig 'ifconfig) +(defalias 'ipconfig #'ifconfig) ;;;###autoload (defun iwconfig () @@ -532,7 +505,7 @@ in Lisp code." (net-utils-run-program "Nslookup" (concat "** " - (mapconcat 'identity + (mapconcat #'identity (list "Nslookup" host nslookup-program) " ** ")) nslookup-program @@ -618,7 +591,7 @@ This command uses `nslookup-program' to look up DNS records." (defvar nslookup-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\t" 'completion-at-point) + (define-key map "\t" #'completion-at-point) map)) ;; Using a derived mode gives us keymaps, hooks, etc. @@ -646,9 +619,9 @@ This command uses `dns-lookup-program' for looking up the DNS information." (net-utils-run-program (concat "DNS Lookup [" host "]") (concat "** " - (mapconcat 'identity - (list "DNS Lookup" host dns-lookup-program) - " ** ")) + (mapconcat #'identity + (list "DNS Lookup" host dns-lookup-program) + " ** ")) dns-lookup-program options))) @@ -669,13 +642,14 @@ This command uses `dig-program' for looking up the DNS information." (net-utils-run-program "Dig" (concat "** " - (mapconcat 'identity + (mapconcat #'identity (list "Dig" host dig-program) " ** ")) dig-program options))) (autoload 'comint-exec "comint") +(declare-function comint-watch-for-password-prompt "comint" (string)) ;; This is a lot less than ange-ftp, but much simpler. ;;;###autoload @@ -697,7 +671,7 @@ This command uses `dig-program' for looking up the DNS information." (defvar ftp-mode-map (let ((map (make-sparse-keymap))) ;; Occasionally useful - (define-key map "\t" 'completion-at-point) + (define-key map "\t" #'completion-at-point) map)) (define-derived-mode ftp-mode comint-mode "FTP" @@ -710,9 +684,9 @@ This command uses `dig-program' for looking up the DNS information." ;; password prompts will probably immediately follow the initial ;; connection), but it's better than getting prompted twice for the ;; same password. - (unless (memq 'comint-watch-for-password-prompt + (unless (memq #'comint-watch-for-password-prompt (default-value 'comint-output-filter-functions)) - (add-hook 'comint-output-filter-functions 'comint-watch-for-password-prompt + (add-hook 'comint-output-filter-functions #'comint-watch-for-password-prompt nil t))) (defun smbclient (host service) @@ -759,9 +733,9 @@ This command uses `smbclient-program' to connect to HOST." ;; password prompts will probably immediately follow the initial ;; connection), but it's better than getting prompted twice for the ;; same password. - (unless (memq 'comint-watch-for-password-prompt + (unless (memq #'comint-watch-for-password-prompt (default-value 'comint-output-filter-functions)) - (add-hook 'comint-output-filter-functions 'comint-watch-for-password-prompt + (add-hook 'comint-output-filter-functions #'comint-watch-for-password-prompt nil t))) @@ -810,7 +784,7 @@ This list is not complete.") (error "Could not open connection to %s" host)) (erase-buffer) (set-marker (process-mark tcp-connection) (point-min)) - (set-process-filter tcp-connection 'net-utils-remove-ctrl-m-filter) + (set-process-filter tcp-connection #'net-utils-remove-ctrl-m-filter) (and initial-string (process-send-string tcp-connection (concat initial-string "\r\n"))) @@ -825,7 +799,6 @@ This list is not complete.") If a host name passed to `finger' matches one of these regular expressions, it is assumed to be a host that doesn't accept queries of the form USER@HOST, and wants a query containing USER only." - :group 'net-utils :type '(repeat regexp) :version "21.1") @@ -852,7 +825,7 @@ and `network-connection-service-alist', which see." (let* ((user-and-host (concat user "@" host)) (process-name (concat "Finger [" user-and-host "]")) (regexps finger-X.500-host-regexps) - found) + ) ;; found (and regexps (while (not (string-match (car regexps) host)) (setq regexps (cdr regexps))) @@ -866,7 +839,6 @@ and `network-connection-service-alist', which see." (defcustom whois-server-name "rs.internic.net" "Default host name for the whois service." - :group 'net-utils :type 'string) (defcustom whois-server-list @@ -880,7 +852,6 @@ and `network-connection-service-alist', which see." ("whois.nic.gov") ("whois.ripe.net")) "A list of whois servers that can be queried." - :group 'net-utils :type '(repeat (list string))) ;; FIXME: modern whois clients include a much better tld <-> whois server @@ -903,14 +874,12 @@ and `network-connection-service-alist', which see." ("whois.nic.gov" . "gov") ("whois.nic.mil" . "mil")) "Alist to map top level domains to whois servers." - :group 'net-utils :type '(repeat (cons string string))) (defcustom whois-guess-server t "If non-nil then whois will try to deduce the appropriate whois server from the query. If the query doesn't look like a domain or hostname then the server named by `whois-server-name' is used." - :group 'net-utils :type 'boolean) (defun whois-get-tld (host) @@ -951,7 +920,6 @@ The port is deduced from `network-connection-service-alist'." (defcustom whois-reverse-lookup-server "whois.arin.net" "Server which provides inverse DNS mapping." - :group 'net-utils :type 'string) ;;;###autoload diff --git a/lisp/net/network-stream.el b/lisp/net/network-stream.el index b45cefcb44..1983688cef 100644 --- a/lisp/net/network-stream.el +++ b/lisp/net/network-stream.el @@ -248,8 +248,7 @@ gnutls-boot (as returned by `gnutls-boot-parameters')." (list key cert))))))) ;;;###autoload -(defalias 'open-protocol-stream 'open-network-stream) -(define-obsolete-function-alias 'open-protocol-stream 'open-network-stream +(define-obsolete-function-alias 'open-protocol-stream #'open-network-stream "26.1") (defun network-stream-open-plain (name buffer host service parameters) diff --git a/lisp/net/newst-backend.el b/lisp/net/newst-backend.el index 418c1e2e96..c5488650b9 100644 --- a/lisp/net/newst-backend.el +++ b/lisp/net/newst-backend.el @@ -163,7 +163,7 @@ These were mostly extracted from the Radio Community Server You may add other entries in `newsticker-url-list'." :type `(set ,@(mapcar #'newsticker--splicer newsticker--raw-url-list-defaults)) - :set 'newsticker--set-customvar-retrieval + :set #'newsticker--set-customvar-retrieval :group 'newsticker-retrieval) (defcustom newsticker-url-list nil @@ -217,7 +217,7 @@ which apply for this feed only, overriding the value of (choice :tag "Wget Arguments" (const :tag "Default arguments" nil) (repeat :tag "Special arguments" string)))) - :set 'newsticker--set-customvar-retrieval + :set #'newsticker--set-customvar-retrieval :group 'newsticker-retrieval) (defcustom newsticker-retrieval-method @@ -260,7 +260,7 @@ make it less than 1800 seconds (30 minutes)!" (const :tag "Daily" 86400) (const :tag "Weekly" 604800) (integer :tag "Interval")) - :set 'newsticker--set-customvar-retrieval + :set #'newsticker--set-customvar-retrieval :group 'newsticker-retrieval) (defcustom newsticker-desc-comp-max @@ -549,7 +549,7 @@ name/timer pair to `newsticker--retrieval-timer-list'." (if (<= interval 0) (setq interval nil)) (setq timer (run-at-time start-time interval - 'newsticker-get-news feed-name)) + #'newsticker-get-news feed-name)) (if interval (add-to-list 'newsticker--retrieval-timer-list (cons feed-name timer)))))) @@ -727,10 +727,10 @@ See `newsticker-get-news'." (error "Another wget-process is running for %s" feed-name)) ;; start wget (let* ((args (append wget-arguments (list url))) - (proc (apply 'start-process feed-name buffername + (proc (apply #'start-process feed-name buffername newsticker-wget-name args))) (set-process-coding-system proc 'no-conversion 'no-conversion) - (set-process-sentinel proc 'newsticker--sentinel) + (set-process-sentinel proc #'newsticker--sentinel) (process-put proc 'nt-feed-name feed-name) (setq newsticker--process-ids (cons (process-id proc) newsticker--process-ids)) @@ -1131,9 +1131,9 @@ Restore an xml-string from a an xml NODE that was returned by xml-parse..." (children (cddr node))) (concat "<" qname (when att-list " ") - (mapconcat 'newsticker--unxml-attribute att-list " ") + (mapconcat #'newsticker--unxml-attribute att-list " ") ">" - (mapconcat 'newsticker--unxml children "") ""))) + (mapconcat #'newsticker--unxml children "") ""))) (defun newsticker--unxml-attribute (attribute) "Actually restore xml-string of an ATTRIBUTE of an xml node." @@ -1580,7 +1580,7 @@ Remove the pre-formatted from `newsticker--cache'." "Forget all cached pre-formatted data. Remove the pre-formatted from `newsticker--cache'." (mapc (lambda (feed) - (mapc 'newsticker--do-forget-preformatted + (mapc #'newsticker--do-forget-preformatted (cdr feed))) newsticker--cache) (when (fboundp 'newsticker--buffer-set-uptodate) @@ -1593,7 +1593,7 @@ This function calls `message' with arguments STRING and ARGS, if (and newsticker-debug ;;(not (active-minibuffer-window)) ;;(not (current-message)) - (apply 'message string args))) + (apply #'message string args))) (defun newsticker--decode-iso8601-date (string) "Return ISO8601-encoded STRING in format like `encode-time'. @@ -1751,10 +1751,10 @@ Save image as FILENAME in DIRECTORY, download it from URL." feed-name)) ;; start wget (let* ((args (append wget-arguments (list url))) - (proc (apply 'start-process proc-name buffername + (proc (apply #'start-process proc-name buffername newsticker-wget-name args))) (set-process-coding-system proc 'no-conversion 'no-conversion) - (set-process-sentinel proc 'newsticker--image-sentinel) + (set-process-sentinel proc #'newsticker--image-sentinel) (process-put proc 'nt-directory directory) (process-put proc 'nt-feed-name feed-name) (process-put proc 'nt-filename filename))))) @@ -2149,7 +2149,7 @@ FEED is a symbol!" "Save cache data for all feeds." (unless (file-directory-p newsticker-dir) (make-directory newsticker-dir t)) - (mapc 'newsticker--cache-save-feed newsticker--cache) + (mapc #'newsticker--cache-save-feed newsticker--cache) nil) (defun newsticker--cache-save-feed (feed) @@ -2223,7 +2223,7 @@ If AGES is nil, the total number of items is returned." (defun newsticker--stat-num-items-total (&optional age) "Return total number of items in all feeds which have the given AGE. If AGE is nil, the total number of items is returned." - (apply '+ + (apply #'+ (mapcar (lambda (feed) (if age (newsticker--stat-num-items (intern (car feed)) age) @@ -2395,7 +2395,7 @@ the item." (make-directory temp-dir t)) (cd temp-dir) (message "Getting image %s" url) - (apply 'start-process "wget-image" + (apply #'start-process "wget-image" " *newsticker-wget-download-images*" newsticker-wget-name (list url)) @@ -2417,7 +2417,7 @@ This function is suited for adding it to `newsticker-new-item-functions'." (make-directory temp-dir t)) (cd temp-dir) (message "Getting enclosure %s" url) - (apply 'start-process "wget-enclosure" + (apply #'start-process "wget-enclosure" " *newsticker-wget-download-enclosures*" newsticker-wget-name (list url)) diff --git a/lisp/net/newst-plainview.el b/lisp/net/newst-plainview.el index 21d47b838f..705bff666a 100644 --- a/lisp/net/newst-plainview.el +++ b/lisp/net/newst-plainview.el @@ -1,4 +1,4 @@ -;;; newst-plainview.el --- Single buffer frontend for newsticker. +;;; newst-plainview.el --- Single buffer frontend for newsticker. -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2021 Free Software Foundation, Inc. @@ -90,7 +90,7 @@ The following sort methods are available: (const :tag "Keep original order" sort-by-original-order) (const :tag "Sort by time" sort-by-time) (const :tag "Sort by title" sort-by-title)) - :set 'newsticker--set-customvar-sorting + :set #'newsticker--set-customvar-sorting :group 'newsticker-plainview) (defcustom newsticker-heading-format @@ -107,7 +107,7 @@ The following printf-like specifiers can be used: %s The statistical data of the feed. See `newsticker-statistics-format'. %t The title of the feed, i.e. its name." :type 'string - :set 'newsticker--set-customvar-formatting + :set #'newsticker--set-customvar-formatting :group 'newsticker-plainview) (defcustom newsticker-item-format @@ -122,7 +122,7 @@ The following printf-like specifiers can be used: the title of the feed is used. %t The title of the item." :type 'string - :set 'newsticker--set-customvar-formatting + :set #'newsticker--set-customvar-formatting :group 'newsticker-plainview) (defcustom newsticker-desc-format @@ -133,7 +133,7 @@ The following printf-like specifiers can be used: %d The date the item was (first) retrieved. See `newsticker-date-format'." :type 'string - :set 'newsticker--set-customvar-formatting + :set #'newsticker--set-customvar-formatting :group 'newsticker-plainview) (defcustom newsticker-statistics-format @@ -146,7 +146,7 @@ The following printf-like specifiers can be used: %o The number of old items in the feed. %O The number of obsolete items in the feed." :type 'string - :set 'newsticker--set-customvar-formatting + :set #'newsticker--set-customvar-formatting :group 'newsticker-plainview) @@ -195,7 +195,7 @@ If set to t old items will be completely folded and only new items will show up in the *newsticker* buffer. Otherwise old as well as new items will be visible." :type 'boolean - :set 'newsticker--set-customvar-buffer + :set #'newsticker--set-customvar-buffer :group 'newsticker-plainview) (defcustom newsticker-show-descriptions-of-new-items @@ -204,14 +204,14 @@ well as new items will be visible." If set to t old items will be folded and new items will be unfolded. Otherwise old as well as new items will be folded." :type 'boolean - :set 'newsticker--set-customvar-buffer + :set #'newsticker--set-customvar-buffer :group 'newsticker-plainview) (defcustom newsticker-show-all-news-elements nil "Show all news elements." :type 'boolean - ;;:set 'newsticker--set-customvar + ;;:set #'newsticker--set-customvar :group 'newsticker-plainview) ;; ====================================================================== @@ -386,51 +386,45 @@ images." (defvar newsticker-mode-map (let ((map (make-keymap))) - (define-key map "sO" 'newsticker-show-old-items) - (define-key map "hO" 'newsticker-hide-old-items) - (define-key map "sa" 'newsticker-show-all-desc) - (define-key map "ha" 'newsticker-hide-all-desc) - (define-key map "sf" 'newsticker-show-feed-desc) - (define-key map "hf" 'newsticker-hide-feed-desc) - (define-key map "so" 'newsticker-show-old-item-desc) - (define-key map "ho" 'newsticker-hide-old-item-desc) - (define-key map "sn" 'newsticker-show-new-item-desc) - (define-key map "hn" 'newsticker-hide-new-item-desc) - (define-key map "se" 'newsticker-show-entry) - (define-key map "he" 'newsticker-hide-entry) - (define-key map "sx" 'newsticker-show-extra) - (define-key map "hx" 'newsticker-hide-extra) - - (define-key map [?\S-\ ] 'scroll-down-command) - (define-key map " " 'scroll-up-command) - (define-key map "q" 'newsticker-close-buffer) - (define-key map "p" 'newsticker-previous-item) - (define-key map "P" 'newsticker-previous-new-item) - (define-key map "F" 'newsticker-previous-feed) - (define-key map "\t" 'newsticker-next-item) - (define-key map "n" 'newsticker-next-item) - (define-key map "N" 'newsticker-next-new-item) - (define-key map "f" 'newsticker-next-feed) - (define-key map "M" 'newsticker-mark-all-items-as-read) - (define-key map "m" - 'newsticker-mark-all-items-at-point-as-read-and-redraw) - (define-key map "o" - 'newsticker-mark-item-at-point-as-read) - (define-key map "O" - 'newsticker-mark-all-items-at-point-as-read) - (define-key map "G" 'newsticker-get-all-news) - (define-key map "g" 'newsticker-get-news-at-point) - (define-key map "u" 'newsticker-buffer-update) - (define-key map "U" 'newsticker-buffer-force-update) - (define-key map "a" 'newsticker-add-url) - - (define-key map "i" - 'newsticker-mark-item-at-point-as-immortal) - - (define-key map "xf" - 'newsticker-toggle-auto-narrow-to-feed) - (define-key map "xi" - 'newsticker-toggle-auto-narrow-to-item) + (define-key map "sO" #'newsticker-show-old-items) + (define-key map "hO" #'newsticker-hide-old-items) + (define-key map "sa" #'newsticker-show-all-desc) + (define-key map "ha" #'newsticker-hide-all-desc) + (define-key map "sf" #'newsticker-show-feed-desc) + (define-key map "hf" #'newsticker-hide-feed-desc) + (define-key map "so" #'newsticker-show-old-item-desc) + (define-key map "ho" #'newsticker-hide-old-item-desc) + (define-key map "sn" #'newsticker-show-new-item-desc) + (define-key map "hn" #'newsticker-hide-new-item-desc) + (define-key map "se" #'newsticker-show-entry) + (define-key map "he" #'newsticker-hide-entry) + (define-key map "sx" #'newsticker-show-extra) + (define-key map "hx" #'newsticker-hide-extra) + + (define-key map [?\S-\ ] #'scroll-down-command) + (define-key map " " #'scroll-up-command) + (define-key map "q" #'newsticker-close-buffer) + (define-key map "p" #'newsticker-previous-item) + (define-key map "P" #'newsticker-previous-new-item) + (define-key map "F" #'newsticker-previous-feed) + (define-key map "\t" #'newsticker-next-item) + (define-key map "n" #'newsticker-next-item) + (define-key map "N" #'newsticker-next-new-item) + (define-key map "f" #'newsticker-next-feed) + (define-key map "M" #'newsticker-mark-all-items-as-read) + (define-key map "m" #'newsticker-mark-all-items-at-point-as-read-and-redraw) + (define-key map "o" #'newsticker-mark-item-at-point-as-read) + (define-key map "O" #'newsticker-mark-all-items-at-point-as-read) + (define-key map "G" #'newsticker-get-all-news) + (define-key map "g" #'newsticker-get-news-at-point) + (define-key map "u" #'newsticker-buffer-update) + (define-key map "U" #'newsticker-buffer-force-update) + (define-key map "a" #'newsticker-add-url) + + (define-key map "i" #'newsticker-mark-item-at-point-as-immortal) + + (define-key map "xf" #'newsticker-toggle-auto-narrow-to-feed) + (define-key map "xi" #'newsticker-toggle-auto-narrow-to-item) ;; Bind menu to mouse. (define-key map [down-mouse-3] newsticker-menu) @@ -479,11 +473,11 @@ images." ;; maps for the clickable portions (defvar newsticker--url-keymap (let ((map (make-sparse-keymap))) - (define-key map [mouse-1] 'newsticker-mouse-browse-url) - (define-key map [mouse-2] 'newsticker-mouse-browse-url) - (define-key map "\n" 'newsticker-browse-url) - (define-key map "\C-m" 'newsticker-browse-url) - (define-key map [(control return)] 'newsticker-handle-url) + (define-key map [mouse-1] #'newsticker-mouse-browse-url) + (define-key map [mouse-2] #'newsticker-mouse-browse-url) + (define-key map "\n" #'newsticker-browse-url) + (define-key map "\C-m" #'newsticker-browse-url) + (define-key map [(control return)] #'newsticker-handle-url) map) "Key map for click-able headings in the newsticker buffer.") @@ -980,7 +974,7 @@ not get changed." (let* (pos1 pos2 (inhibit-read-only t) inv-prop org-inv-prop - is-invisible) + ) ;; is-invisible (newsticker--buffer-beginning-of-item) (newsticker--buffer-goto '(desc)) (setq pos1 (max (point-min) (1- (point)))) @@ -1009,7 +1003,7 @@ not get changed." (let* (pos1 pos2 (inhibit-read-only t) inv-prop org-inv-prop - is-invisible) + ) ;; is-invisible (newsticker--buffer-beginning-of-item) (newsticker--buffer-goto '(desc)) (setq pos1 (max (point-min) (1- (point)))) @@ -1147,7 +1141,7 @@ If VALUE is nil, auto-narrowing is turned off, otherwise it is turned on." (setq index-alist (list feed-list))) index-alist))) -(defun newsticker--imenu-goto (name pos &rest args) +(defun newsticker--imenu-goto (_name pos &rest _args) "Go to item NAME at position POS and show item. ARGS are ignored." (goto-char pos) @@ -1236,6 +1230,9 @@ item-retrieval time is added as well." ;; insert the description (newsticker--buffer-do-insert-text item 'desc feed-name-symbol)) +(defvar w3m-fill-column) +(defvar w3-maximum-line-length) + (defun newsticker--buffer-do-insert-text (item type feed-name-symbol) "Actually insert contents of news item, format it, render it and all that. ITEM is a news item, TYPE tells which part of the item shall be inserted, diff --git a/lisp/net/newst-reader.el b/lisp/net/newst-reader.el index b188bd4589..40e304402a 100644 --- a/lisp/net/newst-reader.el +++ b/lisp/net/newst-reader.el @@ -1,4 +1,4 @@ -;;; newst-reader.el --- Generic RSS reader functions. +;;; newst-reader.el --- Generic RSS reader functions. -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2021 Free Software Foundation, Inc. @@ -94,7 +94,7 @@ done." (const :tag "Right" right) (const :tag "Center" center) (const :tag "Full" full)) - :set 'newsticker--set-customvar-formatting + :set #'newsticker--set-customvar-formatting :group 'newsticker-reader) (defcustom newsticker-use-full-width @@ -103,7 +103,7 @@ done." If non-nil newsticker sets `fill-column' so that the whole window is used when filling. See also `newsticker-justification'." :type 'boolean - :set 'newsticker--set-customvar-formatting + :set #'newsticker--set-customvar-formatting :group 'newsticker-reader) (defcustom newsticker-html-renderer @@ -122,7 +122,7 @@ htmlr if this option is set." (const :tag "w3" w3-region) (const :tag "w3m" w3m-region) (const :tag "htmlr" newsticker-htmlr-render)) - :set 'newsticker--set-customvar-formatting + :set #'newsticker--set-customvar-formatting :group 'newsticker-reader) (defcustom newsticker-date-format @@ -130,7 +130,7 @@ htmlr if this option is set." "Format for the date part in item and feed lines. See `format-time-string' for a list of valid specifiers." :type 'string - :set 'newsticker--set-customvar-formatting + :set #'newsticker--set-customvar-formatting :group 'newsticker-reader) (defgroup newsticker-faces nil diff --git a/lisp/net/newst-ticker.el b/lisp/net/newst-ticker.el index 275c91a36e..2f76470870 100644 --- a/lisp/net/newst-ticker.el +++ b/lisp/net/newst-ticker.el @@ -1,4 +1,4 @@ -;; newst-ticker.el --- mode line ticker for newsticker. +;; newst-ticker.el --- mode line ticker for newsticker. -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2021 Free Software Foundation, Inc. @@ -83,7 +83,7 @@ smooth display (see `newsticker-scroll-smoothly') a value of 0.3 seems reasonable. For non-smooth display a value of 10 is a good starting point." :type 'number - :set 'newsticker--set-customvar-ticker + :set #'newsticker--set-customvar-ticker :group 'newsticker-ticker) (defcustom newsticker-scroll-smoothly @@ -104,7 +104,7 @@ at all. If you change `newsticker-scroll-smoothly' you should also change If t the echo area will not show immortal items. See also `newsticker-hide-old-items-in-echo-area'." :type 'boolean - :set 'newsticker--set-customvar-ticker + :set #'newsticker--set-customvar-ticker :group 'newsticker-ticker) (defcustom newsticker-hide-old-items-in-echo-area @@ -113,7 +113,7 @@ If t the echo area will not show immortal items. See also If t the echo area will show only new items, i.e. only items which have been added between the last two retrievals." :type 'boolean - :set 'newsticker--set-customvar-ticker + :set #'newsticker--set-customvar-ticker :group 'newsticker-ticker) (defcustom newsticker-hide-obsolete-items-in-echo-area @@ -122,7 +122,7 @@ been added between the last two retrievals." If t the echo area will not show obsolete items. See also `newsticker-hide-old-items-in-echo-area'." :type 'boolean - :set 'newsticker--set-customvar-ticker + :set #'newsticker--set-customvar-ticker :group 'newsticker-ticker) (defun newsticker--display-tick () @@ -205,7 +205,7 @@ running already." (setq newsticker--ticker-timer (run-at-time newsticker-ticker-interval newsticker-ticker-interval - 'newsticker--display-tick)))) + #'newsticker--display-tick)))) (defun newsticker-stop-ticker () "Stop newsticker's ticker (but not the news retrieval)." diff --git a/lisp/net/newst-treeview.el b/lisp/net/newst-treeview.el index 2e207be20f..d778cc1761 100644 --- a/lisp/net/newst-treeview.el +++ b/lisp/net/newst-treeview.el @@ -52,86 +52,73 @@ (defface newsticker-treeview-face '((((class color) (background dark)) :foreground "white") (((class color) (background light)) :foreground "black")) - "Face for newsticker tree." - :group 'newsticker-treeview) + "Face for newsticker tree.") (defface newsticker-treeview-new-face '((t :inherit newsticker-treeview-face :weight bold)) - "Face for newsticker tree." - :group 'newsticker-treeview) + "Face for newsticker tree.") (defface newsticker-treeview-old-face '((t :inherit newsticker-treeview-face)) - "Face for newsticker tree." - :group 'newsticker-treeview) + "Face for newsticker tree.") (defface newsticker-treeview-immortal-face '((default :inherit newsticker-treeview-face :slant italic) (((class color) (background dark)) :foreground "orange") (((class color) (background light)) :foreground "blue")) - "Face for newsticker tree." - :group 'newsticker-treeview) + "Face for newsticker tree.") (defface newsticker-treeview-obsolete-face '((t :inherit newsticker-treeview-face :strike-through t)) - "Face for newsticker tree." - :group 'newsticker-treeview) + "Face for newsticker tree.") (defface newsticker-treeview-selection-face '((((class color) (background dark)) :background "#4444aa") (((class color) (background light)) :background "#bbbbff")) - "Face for newsticker selection." - :group 'newsticker-treeview) + "Face for newsticker selection.") (defcustom newsticker-treeview-date-format "%d.%m.%y, %H:%M" "Format for the date column in the treeview list buffer. See `format-time-string' for a list of valid specifiers." :version "25.1" - :type 'string - :group 'newsticker-treeview) + :type 'string) (defcustom newsticker-treeview-own-frame nil "Decides whether newsticker treeview creates and uses its own frame." - :type 'boolean - :group 'newsticker-treeview) + :type 'boolean) (defcustom newsticker-treeview-treewindow-width 30 "Width of tree window in treeview layout. See also `newsticker-treeview-listwindow-height'." - :type 'integer - :group 'newsticker-treeview) + :type 'integer) (defcustom newsticker-treeview-listwindow-height 10 "Height of list window in treeview layout. See also `newsticker-treeview-treewindow-width'." - :type 'integer - :group 'newsticker-treeview) + :type 'integer) (defcustom newsticker-treeview-automatically-mark-displayed-items-as-old t "Decides whether to automatically mark displayed items as old. If t an item is marked as old as soon as it is displayed. This applies to newsticker only." - :type 'boolean - :group 'newsticker-treeview) + :type 'boolean) (defcustom newsticker-treeview-use-feed-name-from-url-list-in-treeview t "Use the feed names from 'newsticker-url-list' for display in treeview." :version "28.1" - :type 'boolean - :group 'newsticker-treeview) + :type 'boolean) (defcustom newsticker-treeview-use-feed-name-from-url-list-in-itemview t "Use feed names from 'newsticker-url-list' in itemview." :version "28.1" - :type 'boolean - :group 'newsticker-treeview) + :type 'boolean) (defvar newsticker-groups '("Feeds") @@ -166,14 +153,16 @@ Example: (\"Topmost group\" \"feed1\" (\"subgroup1\" \"feed 2\") (defvar newsticker--treeview-feed-tree nil) (defvar newsticker--treeview-vfeed-tree nil) +(declare-function newsticker-handle-url "newst-plainview" ()) + ;; maps for the clickable portions (defvar newsticker--treeview-url-keymap (let ((map (make-sparse-keymap 'newsticker--treeview-url-keymap))) - (define-key map [mouse-1] 'newsticker-treeview-mouse-browse-url) - (define-key map [mouse-2] 'newsticker-treeview-mouse-browse-url) - (define-key map "\n" 'newsticker-treeview-browse-url) - (define-key map "\C-m" 'newsticker-treeview-browse-url) - (define-key map [(control return)] 'newsticker-handle-url) + (define-key map [mouse-1] #'newsticker-treeview-mouse-browse-url) + (define-key map [mouse-2] #'newsticker-treeview-mouse-browse-url) + (define-key map "\n" #'newsticker-treeview-browse-url) + (define-key map "\C-m" #'newsticker-treeview-browse-url) + (define-key map [(control return)] #'newsticker-handle-url) map) "Key map for click-able headings in the newsticker treeview buffers.") @@ -342,9 +331,9 @@ If string SHOW-FEED is non-nil it is shown in the item string." (replace-match " ")) (let ((map (make-sparse-keymap))) (dolist (key'([mouse-1] [mouse-3])) - (define-key map key 'newsticker-treeview-tree-click)) - (define-key map "\n" 'newsticker-treeview-show-item) - (define-key map "\C-m" 'newsticker-treeview-show-item) + (define-key map key #'newsticker-treeview-tree-click)) + (define-key map "\n" #'newsticker-treeview-show-item) + (define-key map "\C-m" #'newsticker-treeview-show-item) (add-text-properties pos1 (point-max) (list :nt-item item :nt-feed feed @@ -626,9 +615,9 @@ If CLEAR-BUFFER is non-nil the list buffer is completely erased." (defvar newsticker-treeview-list-sort-button-map (let ((map (make-sparse-keymap))) (define-key map [header-line mouse-1] - 'newsticker--treeview-list-sort-by-column) + #'newsticker--treeview-list-sort-by-column) (define-key map [header-line mouse-2] - 'newsticker--treeview-list-sort-by-column) + #'newsticker--treeview-list-sort-by-column) map) "Local keymap for newsticker treeview list window sort buttons.") @@ -960,9 +949,9 @@ arguments NT-ID, FEED, VFEED and TOOLTIP are added as properties." (if (and num-new (> num-new 0)) (setq face 'newsticker-treeview-new-face)) (dolist (key '([mouse-1] [mouse-3])) - (define-key map key 'newsticker-treeview-tree-click)) - (define-key map "\n" 'newsticker-treeview-tree-do-click) - (define-key map "\C-m" 'newsticker-treeview-tree-do-click) + (define-key map key #'newsticker-treeview-tree-click)) + (define-key map "\n" #'newsticker-treeview-tree-do-click) + (define-key map "\C-m" #'newsticker-treeview-tree-do-click) (propertize tag 'face face 'keymap map :nt-id nt-id :nt-feed feed @@ -2029,37 +2018,37 @@ Return t if groups have changed, nil otherwise." (defvar newsticker-treeview-mode-map (let ((map (make-sparse-keymap 'newsticker-treeview-mode-map))) - (define-key map " " 'newsticker-treeview-next-page) - (define-key map "a" 'newsticker-add-url) - (define-key map "b" 'newsticker-treeview-browse-url-item) - (define-key map "c" 'newsticker-treeview-customize-current-feed) - (define-key map "F" 'newsticker-treeview-prev-feed) - (define-key map "f" 'newsticker-treeview-next-feed) - (define-key map "g" 'newsticker-treeview-get-news) - (define-key map "G" 'newsticker-get-all-news) - (define-key map "i" 'newsticker-treeview-toggle-item-immortal) - (define-key map "j" 'newsticker-treeview-jump) - (define-key map "n" 'newsticker-treeview-next-item) - (define-key map "N" 'newsticker-treeview-next-new-or-immortal-item) - (define-key map "O" 'newsticker-treeview-mark-list-items-old) - (define-key map "o" 'newsticker-treeview-mark-item-old) - (define-key map "p" 'newsticker-treeview-prev-item) - (define-key map "P" 'newsticker-treeview-prev-new-or-immortal-item) - (define-key map "q" 'newsticker-treeview-quit) - (define-key map "S" 'newsticker-treeview-save-item) - (define-key map "s" 'newsticker-treeview-save) - (define-key map "u" 'newsticker-treeview-update) - (define-key map "v" 'newsticker-treeview-browse-url) - ;;(define-key map "\n" 'newsticker-treeview-scroll-item) - ;;(define-key map "\C-m" 'newsticker-treeview-scroll-item) - (define-key map "\M-m" 'newsticker-group-move-feed) - (define-key map "\M-a" 'newsticker-group-add-group) - (define-key map "\M-d" 'newsticker-group-delete-group) - (define-key map "\M-r" 'newsticker-group-rename-group) - (define-key map [M-down] 'newsticker-group-shift-feed-down) - (define-key map [M-up] 'newsticker-group-shift-feed-up) - (define-key map [M-S-down] 'newsticker-group-shift-group-down) - (define-key map [M-S-up] 'newsticker-group-shift-group-up) + (define-key map " " #'newsticker-treeview-next-page) + (define-key map "a" #'newsticker-add-url) + (define-key map "b" #'newsticker-treeview-browse-url-item) + (define-key map "c" #'newsticker-treeview-customize-current-feed) + (define-key map "F" #'newsticker-treeview-prev-feed) + (define-key map "f" #'newsticker-treeview-next-feed) + (define-key map "g" #'newsticker-treeview-get-news) + (define-key map "G" #'newsticker-get-all-news) + (define-key map "i" #'newsticker-treeview-toggle-item-immortal) + (define-key map "j" #'newsticker-treeview-jump) + (define-key map "n" #'newsticker-treeview-next-item) + (define-key map "N" #'newsticker-treeview-next-new-or-immortal-item) + (define-key map "O" #'newsticker-treeview-mark-list-items-old) + (define-key map "o" #'newsticker-treeview-mark-item-old) + (define-key map "p" #'newsticker-treeview-prev-item) + (define-key map "P" #'newsticker-treeview-prev-new-or-immortal-item) + (define-key map "q" #'newsticker-treeview-quit) + (define-key map "S" #'newsticker-treeview-save-item) + (define-key map "s" #'newsticker-treeview-save) + (define-key map "u" #'newsticker-treeview-update) + (define-key map "v" #'newsticker-treeview-browse-url) + ;;(define-key map "\n" #'newsticker-treeview-scroll-item) + ;;(define-key map "\C-m" #'newsticker-treeview-scroll-item) + (define-key map "\M-m" #'newsticker-group-move-feed) + (define-key map "\M-a" #'newsticker-group-add-group) + (define-key map "\M-d" #'newsticker-group-delete-group) + (define-key map "\M-r" #'newsticker-group-rename-group) + (define-key map [M-down] #'newsticker-group-shift-feed-down) + (define-key map [M-up] #'newsticker-group-shift-feed-up) + (define-key map [M-S-down] #'newsticker-group-shift-group-down) + (define-key map [M-S-up] #'newsticker-group-shift-group-up) map) "Mode map for newsticker treeview.") diff --git a/lisp/net/puny.el b/lisp/net/puny.el index 1cdefc08f0..42a7e79679 100644 --- a/lisp/net/puny.el +++ b/lisp/net/puny.el @@ -37,7 +37,7 @@ For instance, \"fśf.org\" => \"xn--ff-2sa.org\"." ;; add a check first to avoid doing unnecessary work. (if (string-match "\\`[[:ascii:]]+\\'" domain) domain - (mapconcat 'puny-encode-string (split-string domain "[.]") "."))) + (mapconcat #'puny-encode-string (split-string domain "[.]") "."))) (defun puny-encode-string (string) "Encode STRING according to the IDNA/punycode algorithm. @@ -57,7 +57,7 @@ For instance, \"bücher\" => \"xn--bcher-kva\"." (defun puny-decode-domain (domain) "Decode DOMAIN according to the IDNA/punycode algorithm. For instance, \"xn--ff-2sa.org\" => \"fśf.org\"." - (mapconcat 'puny-decode-string (split-string domain "[.]") ".")) + (mapconcat #'puny-decode-string (split-string domain "[.]") ".")) (defun puny-decode-string (string) "Decode an IDNA/punycode-encoded string. diff --git a/lisp/net/quickurl.el b/lisp/net/quickurl.el index ab1f43f552..2574c8cb63 100644 --- a/lisp/net/quickurl.el +++ b/lisp/net/quickurl.el @@ -1,4 +1,4 @@ -;;; quickurl.el --- insert a URL based on text at point in buffer +;;; quickurl.el --- insert a URL based on text at point in buffer -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. @@ -97,23 +97,19 @@ (locate-user-emacs-file "quickurls" ".quickurls") "File that contains the URL list." :version "24.4" ; added locate-user-emacs-file - :type 'file - :group 'quickurl) + :type 'file) (defcustom quickurl-format-function #'quickurl-format-url "Function to format the URL before insertion into the current buffer." - :type 'function - :group 'quickurl) + :type 'function) (defcustom quickurl-sort-function #'quickurl-sort-urls "Function to sort the URL list." - :type 'function - :group 'quickurl) + :type 'function) (defcustom quickurl-grab-lookup-function #'current-word "Function to grab the thing to lookup." - :type 'function - :group 'quickurl) + :type 'function) (defun quickurl--assoc-function (key alist) "Default function for `quickurl-assoc-function'." @@ -122,31 +118,26 @@ (defcustom quickurl-assoc-function #'quickurl--assoc-function "Function to use for alist lookup into `quickurl-urls'." :version "26.1" ; was the obsolete assoc-ignore-case - :type 'function - :group 'quickurl) + :type 'function) (defcustom quickurl-completion-ignore-case t "Should `quickurl-ask' ignore case when doing the input lookup?" - :type 'boolean - :group 'quickurl) + :type 'boolean) (defcustom quickurl-prefix ";; -*- lisp -*-\n\n" "Text to write to `quickurl-url-file' before writing the URL list." - :type 'string - :group 'quickurl) + :type 'string) (defcustom quickurl-postfix "" "Text to write to `quickurl-url-file' after writing the URL list. See the constant `quickurl-reread-hook-postfix' for some example text that could be used here." - :type 'string - :group 'quickurl) + :type 'string) (defcustom quickurl-list-mode-hook nil "Hooks for `quickurl-list-mode'." - :type 'hook - :group 'quickurl) + :type 'hook) ;; Constants. diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el index c80cd49c00..938fadfed7 100644 --- a/lisp/net/rcirc.el +++ b/lisp/net/rcirc.el @@ -293,7 +293,7 @@ The following replacements are made: Setting this alone will not affect the prompt; use either M-x customize or also call `rcirc-update-prompt'." :type 'string - :set 'rcirc-set-changed + :set #'rcirc-set-changed :initialize 'custom-initialize-default) (defcustom rcirc-keywords nil diff --git a/lisp/net/secrets.el b/lisp/net/secrets.el index ad27167961..94db318c1b 100644 --- a/lisp/net/secrets.el +++ b/lisp/net/secrets.el @@ -643,7 +643,7 @@ starting with a colon. Example: The object labels of the found items are returned as list." (mapcar (lambda (item-path) (secrets-get-item-property item-path "Label")) - (apply 'secrets-search-item-paths collection attributes))) + (apply #'secrets-search-item-paths collection attributes))) (defun secrets-create-item (collection item password &rest attributes) "Create a new item in COLLECTION with label ITEM and password PASSWORD. @@ -780,9 +780,9 @@ ITEM can also be an object path, which is used if contained in COLLECTION." (defvar secrets-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map (make-composed-keymap special-mode-map widget-keymap)) - (define-key map "n" 'next-line) - (define-key map "p" 'previous-line) - (define-key map "z" 'kill-current-buffer) + (define-key map "n" #'next-line) + (define-key map "p" #'previous-line) + (define-key map "z" #'kill-current-buffer) map) "Keymap used in `secrets-mode' buffers.") @@ -859,7 +859,7 @@ to their attributes." ;; padding is needed to format attribute names. (padding (apply - 'max + #'max (cons (1+ (length "password")) (mapcar diff --git a/lisp/net/shr-color.el b/lisp/net/shr-color.el index ac1f701fd3..eb78a259a8 100644 --- a/lisp/net/shr-color.el +++ b/lisp/net/shr-color.el @@ -36,14 +36,12 @@ (defcustom shr-color-visible-luminance-min 40 "Minimum luminance distance between two colors to be considered visible. Must be between 0 and 100." - :group 'shr-color :type 'number) (defcustom shr-color-visible-distance-min 5 "Minimum color distance between two colors to be considered visible. This value is used to compare result for `ciede2000'. It's an absolute value without any unit." - :group 'shr-color :type 'integer) (defconst shr-color-html-colors-alist @@ -332,8 +330,8 @@ color will be adapted to be visible on BG." (if (or (null fg-norm) (null bg-norm)) (list bg fg) - (let* ((fg-lab (apply 'color-srgb-to-lab fg-norm)) - (bg-lab (apply 'color-srgb-to-lab bg-norm)) + (let* ((fg-lab (apply #'color-srgb-to-lab fg-norm)) + (bg-lab (apply #'color-srgb-to-lab bg-norm)) ;; Compute color distance using CIE DE 2000 (fg-bg-distance (color-cie-de2000 fg-lab bg-lab)) ;; Compute luminance distance (subtract L component) @@ -351,12 +349,12 @@ color will be adapted to be visible on BG." (list (if fixed-background bg - (apply 'format "#%02x%02x%02x" + (apply #'format "#%02x%02x%02x" (mapcar (lambda (x) (* (max (min 1 x) 0) 255)) - (apply 'color-lab-to-srgb bg-lab)))) - (apply 'format "#%02x%02x%02x" + (apply #'color-lab-to-srgb bg-lab)))) + (apply #'format "#%02x%02x%02x" (mapcar (lambda (x) (* (max (min 1 x) 0) 255)) - (apply 'color-lab-to-srgb fg-lab)))))))))) + (apply #'color-lab-to-srgb fg-lab)))))))))) (provide 'shr-color) diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 0e89999b75..c122a19e90 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -220,20 +220,20 @@ and other things: (defvar shr-map (let ((map (make-sparse-keymap))) - (define-key map "a" 'shr-show-alt-text) - (define-key map "i" 'shr-browse-image) - (define-key map "z" 'shr-zoom-image) - (define-key map [?\t] 'shr-next-link) - (define-key map [?\M-\t] 'shr-previous-link) + (define-key map "a" #'shr-show-alt-text) + (define-key map "i" #'shr-browse-image) + (define-key map "z" #'shr-zoom-image) + (define-key map [?\t] #'shr-next-link) + (define-key map [?\M-\t] #'shr-previous-link) (define-key map [follow-link] 'mouse-face) - (define-key map [mouse-2] 'shr-browse-url) - (define-key map [C-down-mouse-1] 'shr-mouse-browse-url-new-window) - (define-key map "I" 'shr-insert-image) - (define-key map "w" 'shr-maybe-probe-and-copy-url) - (define-key map "u" 'shr-maybe-probe-and-copy-url) - (define-key map "v" 'shr-browse-url) - (define-key map "O" 'shr-save-contents) - (define-key map "\r" 'shr-browse-url) + (define-key map [mouse-2] #'shr-browse-url) + (define-key map [C-down-mouse-1] #'shr-mouse-browse-url-new-window) + (define-key map "I" #'shr-insert-image) + (define-key map "w" #'shr-maybe-probe-and-copy-url) + (define-key map "u" #'shr-maybe-probe-and-copy-url) + (define-key map "v" #'shr-browse-url) + (define-key map "O" #'shr-save-contents) + (define-key map "\r" #'shr-browse-url) map)) (defvar shr-image-map diff --git a/lisp/net/sieve-mode.el b/lisp/net/sieve-mode.el index 7bc1d16122..966f0f056b 100644 --- a/lisp/net/sieve-mode.el +++ b/lisp/net/sieve-mode.el @@ -139,9 +139,9 @@ (defvar sieve-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\C-c\C-l" 'sieve-upload) - (define-key map "\C-c\C-c" 'sieve-upload-and-kill) - (define-key map "\C-c\C-m" 'sieve-manage) + (define-key map "\C-c\C-l" #'sieve-upload) + (define-key map "\C-c\C-c" #'sieve-upload-and-kill) + (define-key map "\C-c\C-m" #'sieve-manage) map) "Key map used in sieve mode.") diff --git a/lisp/net/soap-client.el b/lisp/net/soap-client.el index 3cc5569b55..821ef4af8e 100644 --- a/lisp/net/soap-client.el +++ b/lisp/net/soap-client.el @@ -10,6 +10,7 @@ ;; Package: soap-client ;; Homepage: https://github.com/alex-hhh/emacs-soap-client ;; Package-Requires: ((cl-lib "0.6.1")) +;;FIXME: Put in `Package-Requires:' the Emacs version we expect. ;; This file is part of GNU Emacs. @@ -771,6 +772,8 @@ This is a specialization of `soap-decode-type' for (Array (soap-decode-array node)))))) (defalias 'soap-type-of + ;; FIXME: Once we drop support for Emacs<25, use generic functions + ;; via `cl-defmethod' instead of our own ad-hoc version of it. (if (eq 'soap-xs-basic-type (type-of (make-soap-xs-basic-type))) ;; `type-of' in Emacs ≥ 26 already does what we need. #'type-of @@ -1263,7 +1266,7 @@ See also `soap-wsdl-resolve-references'." (soap-l2wk (xml-node-name node))) (setf (soap-xs-simple-type-base type) - (mapcar 'soap-l2fq + (mapcar #'soap-l2fq (split-string (or (xml-get-attribute-or-nil node 'memberTypes) "")))) @@ -1343,7 +1346,7 @@ See also `soap-wsdl-resolve-references'." (soap-validate-xs-basic-type value base)))) (error (push (cadr error-object) messages)))) (when messages - (error (mapconcat 'identity (nreverse messages) "; and: ")))) + (error (mapconcat #'identity (nreverse messages) "; and: ")))) (cl-labels ((fail-with-message (format value) (push (format format value) messages) (throw 'invalid nil))) @@ -2345,8 +2348,8 @@ See also `soap-resolve-references' and (when (= (length (soap-operation-parameter-order operation)) 0) (setf (soap-operation-parameter-order operation) - (mapcar 'car (soap-message-parts - (cdr (soap-operation-input operation)))))) + (mapcar #'car (soap-message-parts + (cdr (soap-operation-input operation)))))) (setf (soap-operation-parameter-order operation) (mapcar (lambda (p) @@ -2391,13 +2394,13 @@ See also `soap-wsdl-resolve-references'." ;; Install resolvers for our types (progn (put (soap-type-of (make-soap-message)) 'soap-resolve-references - 'soap-resolve-references-for-message) + #'soap-resolve-references-for-message) (put (soap-type-of (make-soap-operation)) 'soap-resolve-references - 'soap-resolve-references-for-operation) + #'soap-resolve-references-for-operation) (put (soap-type-of (make-soap-binding)) 'soap-resolve-references - 'soap-resolve-references-for-binding) + #'soap-resolve-references-for-binding) (put (soap-type-of (make-soap-port)) 'soap-resolve-references - 'soap-resolve-references-for-port)) + #'soap-resolve-references-for-port)) (defun soap-wsdl-resolve-references (wsdl) "Resolve all references inside the WSDL structure. @@ -2511,7 +2514,7 @@ Build on WSDL if it is provided." (soap-wsdl-resolve-references (soap-parse-wsdl xml wsdl)) wsdl)) -(defalias 'soap-load-wsdl-from-url 'soap-load-wsdl) +(defalias 'soap-load-wsdl-from-url #'soap-load-wsdl) (defun soap-parse-wsdl-phase-validate-node (node) "Assert that NODE is valid." @@ -2884,7 +2887,7 @@ decode function to perform the actual decoding." (if (fboundp 'define-error) (define-error 'soap-error "SOAP error") - ;; Support older Emacs versions that do not have define-error, so + ;; Support Emacs<24.4 that do not have define-error, so ;; that soap-client can remain unchanged in GNU ELPA. (put 'soap-error 'error-conditions @@ -3123,8 +3126,7 @@ http://schemas.xmlsoap.org/soap/encoding/\"\n")) (defcustom soap-debug nil "When t, enable some debugging facilities." - :type 'boolean - :group 'soap-client) + :type 'boolean) (defun soap-find-port (wsdl service) "Return the WSDL port having SERVICE name. diff --git a/lisp/net/soap-inspect.el b/lisp/net/soap-inspect.el index 9d4e440719..6f9ce6a2d6 100644 --- a/lisp/net/soap-inspect.el +++ b/lisp/net/soap-inspect.el @@ -109,7 +109,7 @@ soap-xs-attribute objects." This is a specialization of `soap-sample-value' for `soap-xs-simple-type' objects." (append - (mapcar 'soap-sample-value-for-xs-attribute + (mapcar #'soap-sample-value-for-xs-attribute (soap-xs-type-attributes type)) (cond ((soap-xs-simple-type-enumeration type) @@ -143,7 +143,7 @@ This is a specialization of `soap-sample-value' for This is a specialization of `soap-sample-value' for `soap-xs-complex-type' objects." (append - (mapcar 'soap-sample-value-for-xs-attribute + (mapcar #'soap-sample-value-for-xs-attribute (soap-xs-type-attributes type)) (cl-case (soap-xs-complex-type-indicator type) (array @@ -176,31 +176,31 @@ This is a specialization of `soap-sample-value' for ;; Install soap-sample-value methods for our types (put (soap-type-of (make-soap-xs-basic-type)) 'soap-sample-value - 'soap-sample-value-for-xs-basic-type) + #'soap-sample-value-for-xs-basic-type) (put (soap-type-of (make-soap-xs-element)) 'soap-sample-value - 'soap-sample-value-for-xs-element) + #'soap-sample-value-for-xs-element) (put (soap-type-of (make-soap-xs-attribute)) 'soap-sample-value - 'soap-sample-value-for-xs-attribute) + #'soap-sample-value-for-xs-attribute) (put (soap-type-of (make-soap-xs-attribute)) 'soap-sample-value - 'soap-sample-value-for-xs-attribute-group) + #'soap-sample-value-for-xs-attribute-group) (put (soap-type-of (make-soap-xs-simple-type)) 'soap-sample-value - 'soap-sample-value-for-xs-simple-type) + #'soap-sample-value-for-xs-simple-type) (put (soap-type-of (make-soap-xs-complex-type)) 'soap-sample-value - 'soap-sample-value-for-xs-complex-type) + #'soap-sample-value-for-xs-complex-type) (put (soap-type-of (make-soap-message)) 'soap-sample-value - 'soap-sample-value-for-message)) + #'soap-sample-value-for-message)) @@ -437,7 +437,7 @@ TYPE is a `soap-xs-complex-type'." (funcall (list 'soap-invoke '*WSDL* "SomeService" (soap-element-name operation)))) (let ((sample-invocation - (append funcall (mapcar 'cdr sample-message-value)))) + (append funcall (mapcar #'cdr sample-message-value)))) (pp sample-invocation (current-buffer))))) (defun soap-inspect-port-type (port-type) @@ -460,7 +460,7 @@ TYPE is a `soap-xs-complex-type'." collect o)) op-name-width) - (setq operations (sort operations 'string<)) + (setq operations (sort operations #'string<)) (setq op-name-width (cl-loop for o in operations maximizing (length o))) @@ -504,39 +504,39 @@ TYPE is a `soap-xs-complex-type'." ;; Install the soap-inspect methods for our types (put (soap-type-of (make-soap-xs-basic-type)) 'soap-inspect - 'soap-inspect-xs-basic-type) + #'soap-inspect-xs-basic-type) (put (soap-type-of (make-soap-xs-element)) 'soap-inspect - 'soap-inspect-xs-element) + #'soap-inspect-xs-element) (put (soap-type-of (make-soap-xs-simple-type)) 'soap-inspect - 'soap-inspect-xs-simple-type) + #'soap-inspect-xs-simple-type) (put (soap-type-of (make-soap-xs-complex-type)) 'soap-inspect - 'soap-inspect-xs-complex-type) + #'soap-inspect-xs-complex-type) (put (soap-type-of (make-soap-xs-attribute)) 'soap-inspect - 'soap-inspect-xs-attribute) + #'soap-inspect-xs-attribute) (put (soap-type-of (make-soap-xs-attribute-group)) 'soap-inspect - 'soap-inspect-xs-attribute-group) + #'soap-inspect-xs-attribute-group) (put (soap-type-of (make-soap-message)) 'soap-inspect - 'soap-inspect-message) + #'soap-inspect-message) (put (soap-type-of (make-soap-operation)) 'soap-inspect - 'soap-inspect-operation) + #'soap-inspect-operation) (put (soap-type-of (make-soap-port-type)) 'soap-inspect - 'soap-inspect-port-type) + #'soap-inspect-port-type) (put (soap-type-of (make-soap-binding)) 'soap-inspect - 'soap-inspect-binding) + #'soap-inspect-binding) (put (soap-type-of (make-soap-port)) 'soap-inspect - 'soap-inspect-port) + #'soap-inspect-port) (put (soap-type-of (soap-make-wsdl "origin")) 'soap-inspect - 'soap-inspect-wsdl)) + #'soap-inspect-wsdl)) (provide 'soap-inspect) ;;; soap-inspect.el ends here diff --git a/lisp/net/telnet.el b/lisp/net/telnet.el index 44f535f01c..bb65ecaa98 100644 --- a/lisp/net/telnet.el +++ b/lisp/net/telnet.el @@ -1,4 +1,4 @@ -;;; telnet.el --- run a telnet session from within an Emacs buffer +;;; telnet.el --- run a telnet session from within an Emacs buffer -*- lexical-binding: t; -*- ;; Copyright (C) 1985, 1988, 1992, 1994, 2001-2021 Free Software ;; Foundation, Inc. @@ -63,11 +63,11 @@ LOGIN-NAME, which is optional, says what to log in as on that machine.") (defvar telnet-new-line "\r") (defvar telnet-mode-map (let ((map (nconc (make-sparse-keymap) comint-mode-map))) - (define-key map "\C-m" 'telnet-send-input) - ;; (define-key map "\C-j" 'telnet-send-input) - (define-key map "\C-c\C-q" 'send-process-next-char) - (define-key map "\C-c\C-c" 'telnet-interrupt-subjob) - (define-key map "\C-c\C-z" 'telnet-c-z) + (define-key map "\C-m" #'telnet-send-input) + ;; (define-key map "\C-j" #'telnet-send-input) + (define-key map "\C-c\C-q" #'send-process-next-char) + (define-key map "\C-c\C-c" #'telnet-interrupt-subjob) + (define-key map "\C-c\C-z" #'telnet-c-z) map)) (defvar telnet-prompt-pattern "^[^#$%>\n]*[#$%>] *") @@ -152,7 +152,7 @@ rejecting one login and prompting again for a username and password.") (t (telnet-check-software-type-initialize string) (telnet-filter proc string) (cond ((> telnet-count telnet-maximum-count) - (set-process-filter proc 'telnet-filter)) + (set-process-filter proc #'telnet-filter)) (t (setq telnet-count (1+ telnet-count))))))))) ;; Identical to comint-simple-send, except that it sends telnet-new-line @@ -227,9 +227,9 @@ Normally input is edited in Emacs and sent a line at a time." (if (and buffer (get-buffer-process buffer)) (switch-to-buffer (concat "*" name "*")) (switch-to-buffer - (apply 'make-comint name telnet-program nil telnet-options)) + (apply #'make-comint name telnet-program nil telnet-options)) (setq process (get-buffer-process (current-buffer))) - (set-process-filter process 'telnet-initial-filter) + (set-process-filter process #'telnet-initial-filter) ;; Don't send the `open' cmd till telnet is ready for it. (accept-process-output process) (erase-buffer) @@ -263,7 +263,7 @@ Normally input is edited in Emacs and sent a line at a time." (require 'shell) (let ((name (concat "rsh-" host ))) (switch-to-buffer (make-comint name remote-shell-program nil host)) - (set-process-filter (get-process name) 'telnet-initial-filter) + (set-process-filter (get-process name) #'telnet-initial-filter) (telnet-mode) (setq-local telnet-connect-command (list 'rsh host)) (setq telnet-count -16))) diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el index 2aacf266f2..1e48f8dbb8 100644 --- a/lisp/net/tramp-cmds.el +++ b/lisp/net/tramp-cmds.el @@ -250,7 +250,7 @@ function returns nil" (host (or (file-remote-p string 'host) "")) item result) (while (setq item (pop tdra)) - (when (string-match-p (or (eval (car item)) "") string) + (when (string-match-p (or (eval (car item) t) "") string) (setq tdra nil result (format-spec diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el index 27461e6917..b67de1bd21 100644 --- a/lisp/net/tramp-compat.el +++ b/lisp/net/tramp-compat.el @@ -70,7 +70,7 @@ It is the default value of `temporary-file-directory'." ;; We must return a local directory. If it is remote, we could run ;; into an infloop. - (eval (car (get 'temporary-file-directory 'standard-value)))) + (eval (car (get 'temporary-file-directory 'standard-value)) t)) (defsubst tramp-compat-make-temp-name () "Generate a local temporary file name (compat function)." diff --git a/lisp/net/tramp-integration.el b/lisp/net/tramp-integration.el index 64b5b48e7d..5adc4ce354 100644 --- a/lisp/net/tramp-integration.el +++ b/lisp/net/tramp-integration.el @@ -231,7 +231,7 @@ NAME must be equal to `tramp-current-connection'." (delete (info-lookup->mode-cache 'symbol 'tramp-info-lookup-mode) (info-lookup->topic-cache 'symbol))))) - (dolist (mode (mapcar 'car (info-lookup->topic-value 'symbol))) + (dolist (mode (mapcar #'car (info-lookup->topic-value 'symbol))) ;; Add `tramp-info-lookup-mode' to `other-modes' for either ;; `emacs-lisp-mode' itself, or to modes which use ;; `emacs-lisp-mode' as `other-modes'. Reset `info-lookup-cache'. diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index dac83b82a8..7f6ecc6c32 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -4918,7 +4918,7 @@ If there is just some editing, retry it after 5 seconds." (progn (tramp-message vec 5 "Cannot timeout session, trying it again in %s seconds." 5) - (run-at-time 5 nil 'tramp-timeout-session vec)) + (run-at-time 5 nil #'tramp-timeout-session vec)) (tramp-message vec 3 "Timeout session %s" (tramp-make-tramp-file-name vec 'noloc)) (tramp-cleanup-connection vec 'keep-debug nil 'keep-processes))) @@ -5149,7 +5149,7 @@ connection if a previous connection has died for some reason." (when (tramp-get-connection-property p "session-timeout" nil) (run-at-time (tramp-get-connection-property p "session-timeout" nil) nil - 'tramp-timeout-session vec)) + #'tramp-timeout-session vec)) ;; Make initial shell settings. (tramp-open-connection-setup-interactive-shell p vec) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 47d62f3804..9f65608f3a 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -386,6 +386,8 @@ Also see `tramp-default-method-alist'." :type 'string) (defcustom tramp-default-method-alist nil + ;; FIXME: This is not an "alist", because its elements are not of + ;; the form (KEY . VAL) but (KEY1 KEY2 VAL). "Default method to use for specific host/user pairs. This is an alist of items (HOST USER METHOD). The first matching item specifies the method to use for a file name which does not specify a @@ -413,6 +415,8 @@ This variable is regarded as obsolete, and will be removed soon." :type '(choice (const nil) string)) (defcustom tramp-default-user-alist nil + ;; FIXME: This is not an "alist", because its elements are not of + ;; the form (KEY . VAL) but (KEY1 KEY2 VAL). "Default user to use for specific method/host pairs. This is an alist of items (METHOD HOST USER). The first matching item specifies the user to use for a file name which does not specify a @@ -432,6 +436,8 @@ Useful for su and sudo methods mostly." :type 'string) (defcustom tramp-default-host-alist nil + ;; FIXME: This is not an "alist", because its elements are not of + ;; the form (KEY . VAL) but (KEY1 KEY2 VAL). "Default host to use for specific method/user pairs. This is an alist of items (METHOD USER HOST). The first matching item specifies the host to use for a file name which does not specify a @@ -447,6 +453,8 @@ empty string for the method name." (choice :tag " Host name" string (const nil))))) (defcustom tramp-default-proxies-alist nil + ;; FIXME: This is not an "alist", because its elements are not of + ;; the form (KEY . VAL) but (KEY1 KEY2 VAL). "Route to be followed for specific host/user pairs. This is an alist of items (HOST USER PROXY). The first matching item specifies the proxy to be passed for a file name located on @@ -1710,6 +1718,10 @@ version, the function does nothing." "Used for highlighting Tramp debug buffers in `outline-mode'.") (defconst tramp-debug-font-lock-keywords + ;; FIXME: Make it a function instead of an ELisp expression, so you + ;; can evaluate it with `funcall' rather than `eval'! + ;; Also, in `font-lock-defaults' you can specify a function name for + ;; the "KEYWORDS" part, so font-lock calls it to get the actual keywords! '(list (concat "^\\(?:" tramp-debug-outline-regexp "\\).+") '(1 font-lock-warning-face t t) @@ -1738,8 +1750,11 @@ The outline level is equal to the verbosity of the Tramp message." (outline-mode)) (setq-local outline-level 'tramp-debug-outline-level) (setq-local font-lock-keywords - `(t (eval ,tramp-debug-font-lock-keywords) - ,(eval tramp-debug-font-lock-keywords))) + ;; FIXME: This `(t FOO . BAR)' representation in + ;; `font-lock-keywords' is supposed to be an + ;; internal implementation "detail". Don't abuse it here! + `(t (eval ,tramp-debug-font-lock-keywords t) + ,(eval tramp-debug-font-lock-keywords t))) ;; Do not edit the debug buffer. (use-local-map special-mode-map)) (current-buffer))) @@ -3691,15 +3706,15 @@ User is always nil." (setq choices tramp-default-proxies-alist) (while choices (setq item (pop choices) - proxy (eval (nth 2 item))) + proxy (eval (nth 2 item) t)) (when (and ;; Host. (string-match-p - (or (eval (nth 0 item)) "") + (or (eval (nth 0 item) t) "") (or (tramp-file-name-host-port (car target-alist)) "")) ;; User. (string-match-p - (or (eval (nth 1 item)) "") + (or (eval (nth 1 item) t) "") (or (tramp-file-name-user-domain (car target-alist)) ""))) (if (null proxy) ;; No more hops needed. diff --git a/lisp/net/webjump.el b/lisp/net/webjump.el index 1fa625c324..4baa657c0a 100644 --- a/lisp/net/webjump.el +++ b/lisp/net/webjump.el @@ -252,7 +252,7 @@ Please submit bug reports and other feedback to the author, Neil W. Van Dyke (cond ((not expr) "") ((stringp expr) expr) ((vectorp expr) (webjump-builtin expr name)) - ((listp expr) (eval expr)) + ((listp expr) (eval expr t)) ((symbolp expr) (if (fboundp expr) (funcall expr name) commit b4bfdd3999841dcdd779a48316b5cdb9b4f61209 Author: Michael Albinus Date: Mon Mar 8 15:44:38 2021 +0100 Fix handling of `tramp-cache-{g,s}et-count-*' * lisp/net/tramp-cache.el (tramp-get-file-property) (tramp-set-file-property): Fix handling of `tramp-cache-{g,s}et-count-*'. diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index ad8310c5ea..c79a3a02a3 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el @@ -164,7 +164,8 @@ Return DEFAULT if not set." file property value remote-file-name-inhibit-cache cache-used cached-at) (when (>= tramp-verbose 10) (let* ((var (intern (concat "tramp-cache-get-count-" property))) - (val (or (numberp (and (boundp var) (symbol-value var))) + (val (or (and (boundp var) (numberp (symbol-value var)) + (symbol-value var)) (progn (add-hook 'tramp-cache-unload-hook (lambda () (makunbound var))) @@ -188,7 +189,8 @@ Return VALUE." (tramp-message key 8 "%s %s %s" file property value) (when (>= tramp-verbose 10) (let* ((var (intern (concat "tramp-cache-set-count-" property))) - (val (or (numberp (and (boundp var) (symbol-value var))) + (val (or (and (boundp var) (numberp (symbol-value var)) + (symbol-value var)) (progn (add-hook 'tramp-cache-unload-hook (lambda () (makunbound var))) commit f4452bb8140cb7485be0a529afc91476becb5d91 Author: Philipp Stephani Date: Mon Mar 8 14:30:24 2021 +0100 Fix structure of condition object in nested 'ert-fail'. See the test 'ert-test-fail' for the expected structure. * lisp/emacs-lisp/ert.el (ert--should-signal-hook): Condition list should be (SYMBOL . DATA), not (SYMBOL DATA). * test/lisp/emacs-lisp/ert-tests.el (ert-test-fail-inside-should): Fix unit test. diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index 155b6a9d4e..d22b239774 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -261,7 +261,7 @@ DATA is displayed to the user and should state the reason for skipping." It should only be stopped when ran from inside ert--run-test-internal." (when (and (not (symbolp debugger)) ; only run on anonymous debugger (memq error-symbol '(ert-test-failed ert-test-skipped))) - (funcall debugger 'error (list error-symbol data)))) + (funcall debugger 'error (cons error-symbol data)))) (defun ert--special-operator-p (thing) "Return non-nil if THING is a symbol naming a special operator." diff --git a/test/lisp/emacs-lisp/ert-tests.el b/test/lisp/emacs-lisp/ert-tests.el index bdacb0832b..5c9696105e 100644 --- a/test/lisp/emacs-lisp/ert-tests.el +++ b/test/lisp/emacs-lisp/ert-tests.el @@ -814,7 +814,7 @@ This macro is used to test if macroexpansion in `should' works." :body (lambda () (should (integerp (ert-fail "Boo")))))))) (should (ert-test-failed-p result)) (should (equal (ert-test-failed-condition result) - '(ert-test-failed ("Boo")))))) + '(ert-test-failed "Boo"))))) (provide 'ert-tests) commit 432c1aaa80ce109250a93f50858a03ce3d01ca34 Author: Simen Heggestøyl Date: Mon Mar 8 12:38:41 2021 +0100 Use `pop-to-buffer-same-window' in `project-eshell' * lisp/progmodes/project.el (project-eshell): Use `pop-to-buffer-same-window' instead of `pop-to-buffer' to match the behavior of `M-x eshell'. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index abe563bec0..d59da2496a 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -924,7 +924,7 @@ if one already exists." "-eshell*")) (eshell-buffer (get-buffer eshell-buffer-name))) (if (and eshell-buffer (not current-prefix-arg)) - (pop-to-buffer eshell-buffer) + (pop-to-buffer-same-window eshell-buffer) (eshell t)))) ;;;###autoload commit a01166562cec3f97e722b627cf5db8ef49338cde Author: Mauro Aranda Date: Mon Mar 8 08:11:38 2021 -0300 Make checkdoc--next-docstring use the doc-string-elt property This follows from a fix for Bug#46918 and a discussion to use doc-string-elt: https://lists.gnu.org/archive/html/emacs-devel/2021-03/msg00232.html * lisp/emacs-lisp/checkdoc.el (checkdoc--next-docstring): Check for a non-nil doc-string-elt property, instead of hard-coding the supported symbols. Use that property to position point at the doc-string. diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index 213ab43184..ee2e77480d 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -931,35 +931,20 @@ don't move point." ;; Don't bug out if the file is empty (or a ;; definition ends prematurely. (end-of-file))) - (`(,(or 'defun 'defvar 'defcustom 'defmacro 'defconst 'defsubst 'defadvice - 'cl-defun 'cl-defgeneric 'cl-defmacro) + (`(,(and (pred symbolp) def + (let (and doc (guard doc)) (function-get def 'doc-string-elt))) ,(pred symbolp) ;; Require an initializer, i.e. ignore single-argument `defvar' ;; forms, which never have a doc string. ,_ . ,_) (down-list) - ;; Skip over function or macro name, symbol to be defined, and - ;; initializer or argument list. - (forward-sexp 3) - (skip-chars-forward " \n\t") - t) - (`(,'cl-defmethod - ,(pred symbolp) - . ,rest) - (down-list) - (forward-sexp (pcase (car rest) - ;; No qualifier, so skip like we would have skipped in - ;; the first clause of the outer `pcase'. - ((pred listp) 3) - (':extra - ;; Skip the :extra qualifier together with its string too. - ;; Skip any additional qualifier. - (if (memq (nth 2 rest) '(:around :before :after)) - 6 - 5)) - ;; Skip :before, :after or :around qualifier too. - ((or ':around ':before ':after) - 4))) + ;; Skip over function or macro name. + (forward-sexp 1) + ;; And now skip until the docstring. + (forward-sexp (1- ; We already skipped the function or macro name. + (cond + ((numberp doc) doc) + ((functionp doc) (funcall doc))))) (skip-chars-forward " \n\t") t))) commit 11d3af3c7b9dc5a2910807d311168fb82d962d0d Author: Michael Albinus Date: Mon Mar 8 12:05:29 2021 +0100 Add Tramp sshfs method * doc/misc/tramp.texi (Top, Configuration): Insert sections 'FUSE-based methods' and 'FUSE setup' in menu. (Quick Start Guide): Fix @anchors. Add doas. Extend section 'Using @command{rclone}' to 'Using @acronym{FUSE}-based methods'. (External methods): Remove rclone paragraph. (FUSE-based methods, FUSE setup): New nodes. (Predefined connection information): Mention "mount-point". * etc/NEWS: Mention Tramp sshfs method. Fix typos and other oddities. * lisp/net/tramp-fuse.el: New file. * lisp/net/tramp-rclone.el (tramp-fuse): Require. (tramp-rclone-file-name-handler-alist): Replace `tramp-rclone-handle-*' by `tramp-fuse-handle-*' where appropriate. (tramp-rclone-handle-delete-directory) (tramp-rclone-handle-delete-file) (tramp-rclone-handle-directory-files) (tramp-rclone-handle-file-attributes) (tramp-rclone-handle-file-executable-p) (tramp-rclone-handle-file-name-all-completions) (tramp-rclone-handle-file-readable-p) (tramp-rclone-handle-insert-directory) (tramp-rclone-handle-insert-file-contents) (tramp-rclone-handle-make-directory, tramp-rclone-mount-point) (tramp-rclone-mounted-p, tramp-rclone-local-file-name): Remove. Functionality moved to tramp-fuse.el. (tramp-rclone-remote-file-name) (tramp-rclone-maybe-open-connection): Use `tramp-fuse-*' functions. * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-out-of-band): Simplify check. * lisp/net/tramp-sshfs.el: New file. * lisp/net/tramp.el: Remove TODO item. * test/lisp/net/tramp-tests.el (tramp--test-sshfs-p): New defun. (tramp-test14-delete-directory): Use it. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 2c9348f6d0..5958162d93 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -126,6 +126,7 @@ Configuring @value{tramp} for use * Inline methods:: Inline methods. * External methods:: External methods. * GVFS-based methods:: @acronym{GVFS}-based external methods. +* FUSE-based methods:: @acronym{FUSE}-based external methods. * Default Method:: Selecting a default method. * Default User:: Selecting a default user. * Default Host:: Selecting a default host. @@ -139,6 +140,7 @@ Configuring @value{tramp} for use Setting own connection related information. * Remote programs:: How @value{tramp} finds and uses programs on the remote host. * Remote shell setup:: Remote shell setup hints. +* FUSE setup:: @acronym{FUSE} setup hints. * Android shell setup:: Android shell setup hints. * Auto-save and Backup:: Auto-save and Backup. * Keeping files encrypted:: Protect remote files by encryption. @@ -433,7 +435,7 @@ remote host, when the buffer you call the process from has a remote @code{default-directory}. -@anchor{Quick Start Guide: File name syntax} +@anchor{Quick Start Guide File name syntax} @section File name syntax @cindex file name syntax @@ -459,7 +461,7 @@ connection methods also support a notation for the port to be used, in which case it is written as @code{host#port}. -@anchor{Quick Start Guide: @option{ssh} and @option{plink} methods} +@anchor{Quick Start Guide ssh and plink methods} @section Using @option{ssh} and @option{plink} @cindex method @option{ssh} @cindex @option{ssh} method @@ -478,28 +480,31 @@ an @command{ssh} server: @file{@trampfn{plink,user@@host,/path/to/file}}. -@anchor{Quick Start Guide: @option{su}, @option{sudo} and @option{sg} methods} -@section Using @option{su}, @option{sudo} and @option{sg} +@anchor{Quick Start Guide su, sudo, doas and sg methods} +@section Using @option{su}, @option{sudo}, @option{doas} and @option{sg} @cindex method @option{su} @cindex @option{su} method @cindex method @option{sudo} @cindex @option{sudo} method +@cindex method @option{doas} +@cindex @option{doas} method @cindex method @option{sg} @cindex @option{sg} method Sometimes, it is necessary to work on your local host under different permissions. For this, you can use the @option{su} or @option{sudo} -connection method. Both methods use @samp{root} as default user name -and the return value of @code{(system-name)} as default host name. -Therefore, it is convenient to open a file as +connection method. On OpenBSD systems, the @option{doas} connection +method offers the same functionality. These methods use @samp{root} +as default user name and the return value of @code{(system-name)} as +default host name. Therefore, it is convenient to open a file as @file{@trampfn{sudo,,/path/to/file}}. The method @option{sg} stands for ``switch group''; here the user name is used as the group to change to. The default host name is the same. -@anchor{Quick Start Guide: @option{ssh}, @option{plink}, @option{su}, @option{sudo} and @option{sg} methods} -@section Combining @option{ssh} or @option{plink} with @option{su} or @option{sudo} +@anchor{Quick Start Guide Combining ssh, plink, su, sudo and doas methods} +@section Combining @option{ssh} or @option{plink} with @option{su}, @option{sudo} or @option{doas} @cindex method @option{ssh} @cindex @option{ssh} method @cindex method @option{plink} @@ -508,18 +513,20 @@ is used as the group to change to. The default host name is the same. @cindex @option{su} method @cindex method @option{sudo} @cindex @option{sudo} method +@cindex method @option{doas} +@cindex @option{doas} method -If the @option{su} or @option{sudo} option should be performed on -another host, it can be comnbined with a leading @option{ssh} or -@option{plink} option. That means that @value{tramp} connects first to -the other host with non-administrative credentials, and changes to -administrative credentials on that host afterwards. In a simple case, -the syntax looks like +If the @option{su}, @option{sudo} or @option{doas} option should be +performed on another host, it can be comnbined with a leading +@option{ssh} or @option{plink} option. That means that @value{tramp} +connects first to the other host with non-administrative credentials, +and changes to administrative credentials on that host afterwards. In +a simple case, the syntax looks like @file{@value{prefix}ssh@value{postfixhop}user@@host|sudo@value{postfixhop}@value{postfix}/path/to/file}. @xref{Ad-hoc multi-hops}. -@anchor{Quick Start Guide: @option{sudoedit} method} +@anchor{Quick Start Guide sudoedit method} @section Using @command{sudoedit} @cindex method @option{sudoedit} @cindex @option{sudoedit} method @@ -532,7 +539,7 @@ method, it is restricted to @samp{localhost} only, and it does not support external processes. -@anchor{Quick Start Guide: @option{smb} method} +@anchor{Quick Start Guide smb method} @section Using @command{smbclient} @cindex method @option{smb} @cindex @option{smb} method @@ -546,7 +553,7 @@ of the local file name is the share exported by the remote host, @samp{path} in this example. -@anchor{Quick Start Guide: GVFS-based methods} +@anchor{Quick Start Guide GVFS-based methods} @section Using @acronym{GVFS}-based methods @cindex methods, gvfs @cindex gvfs-based methods @@ -570,7 +577,7 @@ file system), @file{@trampfn{dav,user@@host,/path/to/file}}, @file{@trampfn{mtp,device,/path/to/file}} (for media devices). -@anchor{Quick Start Guide: GNOME Online Accounts based methods} +@anchor{Quick Start Guide GNOME Online Accounts based methods} @section Using @acronym{GNOME} Online Accounts based methods @cindex @acronym{GNOME} Online Accounts @cindex method @option{gdrive} @@ -590,21 +597,18 @@ account), or @file{@trampfn{nextcloud,user@@host#8081,/path/to/file}} (@samp{8081} stands for the port number) for OwnCloud/NextCloud files. -@anchor{Quick Start Guide: Android} -@section Using Android -@cindex method @option{adb} -@cindex @option{adb} method -@cindex android - -An Android device, which is connected via USB to your local host, can -be accessed via the @command{adb} command. No user or host name is -needed. The file name syntax is @file{@trampfn{adb,,/path/to/file}}. - - -@anchor{Quick Start Guide: @option{rclone} method} -@section Using @command{rclone} +@anchor{Quick Start Guide FUSE-based methods} +@section Using @acronym{FUSE}-based methods +@cindex methods, fuse +@cindex fuse-based methods @cindex method @option{rclone} @cindex @option{rclone} method +@cindex method @option{sshfs} +@cindex @option{sshfs} method + +@acronym{FUSE, Filesystem in Userspace} allows users to mount a +virtual file system. It is also used by @acronym{GVFS} internally, +but here we discuss methods which do not use the @acronym{GVFS} API. A convenient way to access system storages is the @command{rclone} program. If you have configured a storage in @command{rclone} under a @@ -612,6 +616,24 @@ name @samp{storage} (for example), you can access it via the remote file name syntax @file{@trampfn{rclone,storage,/path/to/file}}. User names are not needed. +On local hosts which have installed the @command{sshfs} client for +mounting a file system based on @command{sftp}, this method can be +used. All remote files are available via the local mount point. +@value{tramp} aids in mounting the file system if it isn't mounted +yet, and it supports the access with the usual file name syntax +@file{@trampfn{sshfs,user@@host,/path/to/file}}. + + +@anchor{Quick Start Guide Android} +@section Using Android +@cindex method @option{adb} +@cindex @option{adb} method +@cindex android + +An Android device, which is connected via USB to your local host, can +be accessed via the @command{adb} command. No user or host name is +needed. The file name syntax is @file{@trampfn{adb,,/path/to/file}}. + @node Configuration @chapter Configuring @value{tramp} @@ -650,6 +672,7 @@ may be used in your init file: * Inline methods:: Inline methods. * External methods:: External methods. * GVFS-based methods:: @acronym{GVFS}-based external methods. +* FUSE-based methods:: @acronym{FUSE}-based external methods. * Default Method:: Selecting a default method. Here we also try to help those who don't have the foggiest which method @@ -666,6 +689,7 @@ may be used in your init file: Setting own connection related information. * Remote programs:: How @value{tramp} finds and uses programs on the remote host. * Remote shell setup:: Remote shell setup hints. +* FUSE setup:: @acronym{FUSE} setup hints. * Android shell setup:: Android shell setup hints. * Auto-save and Backup:: Auto-save and Backup. * Keeping files encrypted:: Protect remote files by encryption. @@ -1110,7 +1134,6 @@ UNC file name specification does not allow the specification of a different user name for authentication like the @command{smbclient} can. - @item @option{adb} @cindex method @option{adb} @cindex @option{adb} method @@ -1150,45 +1173,6 @@ specified using @file{device#42} host name syntax or @value{tramp} can use the default value as declared in @command{adb} command. Port numbers are not applicable to Android devices connected through USB@. - -@item @option{rclone} -@cindex method @option{rclone} -@cindex @option{rclone} method - -@vindex tramp-rclone-program -The program @command{rclone} allows to access different system -storages in the cloud, see @url{https://rclone.org/} for a list of -supported systems. If the @command{rclone} program isn't found in -your @env{PATH} environment variable, you can tell @value{tramp} its -absolute path via the user option @code{tramp-rclone-program}. - -A system storage must be configured via the @command{rclone config} -command, outside Emacs. If you have configured a storage in -@command{rclone} under a name @samp{storage} (for example), you could -access it via the remote file name - -@example -@trampfn{rclone,storage,/path/to/file} -@end example - -User names are part of the @command{rclone} configuration, and not -needed in the remote file name. If a user name is contained in the -remote file name, it is ignored. - -Internally, @value{tramp} mounts the remote system storage at location -@file{/tmp/tramp.rclone.storage}, with @file{storage} being the name -of the configured system storage. - -Optional flags to the different @option{rclone} operations could be -passed as connection property, @xref{Predefined connection -information}. Supported properties are @t{"mount-args"}, -@t{"copyto-args"}, @t{"moveto-args"} and @t{"about-args"}. - -Access via @option{rclone} is slow. If you have an alternative method -for accessing the system storage, you should use it. -@ref{GVFS-based methods} for example, methods @option{gdrive} and -@option{nextcloud}. - @end table @@ -1200,8 +1184,8 @@ for accessing the system storage, you should use it. @acronym{GVFS} is the virtual file system for the @acronym{GNOME} Desktop, @uref{https://en.wikipedia.org/wiki/GVFS}. Remote files on -@acronym{GVFS} are mounted locally through FUSE and @value{tramp} uses -this locally mounted directory internally. +@acronym{GVFS} are mounted locally through @acronym{FUSE} and +@value{tramp} uses this locally mounted directory internally. Emacs uses the D-Bus mechanism to communicate with @acronym{GVFS}@. Emacs must have the message bus system, D-Bus integration active, @@ -1317,6 +1301,88 @@ respectively: @end defopt +@node FUSE-based methods +@section @acronym{FUSE}-based external methods +@cindex methods, fuse +@cindex fuse-based methods + +Besides @acronym{GVFS}, there are other virtual file systems using the +@acronym{FUSE} interface. Remote files are mounted locally through +@acronym{FUSE} and @value{tramp} uses this locally mounted directory +internally. When possible, @value{tramp} maps the remote file names +to their respective local file name, and applies the file name +operation on them. For some of the file name operations this is not +possible, @value{tramp} emulates those operations otherwise. + +@table @asis +@item @option{rclone} +@cindex method @option{rclone} +@cindex @option{rclone} method + +@vindex tramp-rclone-program +The program @command{rclone} allows to access different system +storages in the cloud, see @url{https://rclone.org/} for a list of +supported systems. If the @command{rclone} program isn't found in +your @env{PATH} environment variable, you can tell @value{tramp} its +absolute path via the user option @code{tramp-rclone-program}. + +A system storage must be configured via the @command{rclone config} +command, outside Emacs. If you have configured a storage in +@command{rclone} under a name @samp{storage} (for example), you could +access it via the remote file name + +@example +@trampfn{rclone,storage,/path/to/file} +@end example + +User names are part of the @command{rclone} configuration, and not +needed in the remote file name. If a user name is contained in the +remote file name, it is ignored. + +Internally, @value{tramp} mounts the remote system storage at location +@file{/tmp/tramp.rclone.storage}, with @file{storage} being the name +of the configured system storage. + +The mount point and optional flags to the different @option{rclone} +operations could be passed as connection properties, @xref{Setup of +rclone method}. + +Access via @option{rclone} is slow. If you have an alternative method +for accessing the system storage, you should use it. +@ref{GVFS-based methods} for example, methods @option{gdrive} and +@option{nextcloud}. + +@item @option{sshfs} +@cindex method @option{sshfs} +@cindex @option{sshfs} method + +@vindex tramp-sshfs-program +On local hosts which have installed the @command{sshfs} client for +mounting a file system based on @command{sftp}, this method can be +used, see +@url{https://github.com/libfuse/sshfs/blob/master/README.rst/}. If +the @command{sshfs} program isn't found in your @env{PATH} environment +variable, you can tell @value{tramp} its absolute path via the user +option @code{tramp-sshfs-program}. + +All remote files are available via the local mount point. +@value{tramp} aids in mounting the file system if it isn't mounted +yet. The remote file name syntax is + +@example +@trampfn{sshfs,user@@host#port,/path/to/file} +@end example + +User name and port number are optional. This method does not support +password handling, the file system must either be mounted already, or +the connection must be established passwordless via ssh keys. + +The mount point and mount arguments could be passed as connection +properties, @xref{Setup of sshfs method}. + +@end table + + @node Default Method @section Selecting a default method @cindex default method @@ -2102,6 +2168,13 @@ The default value of this property is @code{t} (not specified in @code{tramp-methods}). If the remote host runs native MS Windows, this propery has no effect. +@item @t{"mount-point"} + +The directory file name an @acronym{FUSE}-based file system is mounted +on. The default value of this property is +@t{"/tmp/tramp.method.user@@host#port"} (not specified in +@code{tramp-methods}). + @item @t{"mount-args"}@* @t{"copyto-args"}@* @t{"moveto-args"}@* @@ -2430,7 +2503,6 @@ match the end of the connection buffer. Due to performance reasons, this search starts at the end of the buffer, and it is limited to 256 characters backwards. - @item Conflicting names for users and variables in @file{.profile} When a user name is the same as a variable name in a local file, such @@ -2440,7 +2512,6 @@ variable name to something different from the user name. For example, if the user name is @env{FRUMPLE}, then change the variable name to @env{FRUMPLE_DIR}. - @item Non-Bourne commands in @file{.profile} When the remote host's @file{.profile} is also used for shells other @@ -2465,7 +2536,6 @@ To accommodate using non-Bourne shells on that remote, use other shell-specific config files. For example, bash can use @file{~/.bash_profile} and ignore @file{.profile}. - @item Interactive shell prompt @vindex INSIDE_EMACS@r{, environment variable} @@ -2533,6 +2603,57 @@ where @samp{192.168.0.1} is the remote host IP address @end table +@node FUSE setup +@section @acronym{FUSE} setup hints + +The @acronym{FUSE} file systems are mounted per default at +@file{/tmp/tramp.method.user@@host#port}. The user name and port +number are optional. If the file system is already mounted, it will +be used as it is. If the mount point does not exist yet, +@value{tramp} creates this directory. + +The mount point can be overwritten by the connection property +@t{"mount-point"}, @ref{Predefined connection information}. +Example: + +@lisp +@group +(add-to-list 'tramp-connection-properties + `(,(regexp-quote "@trampfn{sshfs,user@@host,}") + "mount-point" + ,(expand-file-name "sshfs.user@@host" user-emacs-directory))) +@end group +@end lisp + + +@anchor{Setup of rclone method} +@subsection @option{rclone} setup +@cindex rclone setup + +The default arguments of the @command{rclone} operations +@command{mount}, @command{coopyto}, @command{moveto} and +@command{about} are declared in the variable @code{tramp-methods} as +method specific parameters. Usually, they don't need to be overwritten. + +If needed, these parameters can be overwritten as connection +properties @t{"mount-args"}, @t{"copyto-args"}, @t{"moveto-args"} and +@t{"about-args"}, @xref{Predefined connection information}. All of +them are list of strings. + +Be careful changing @t{"--dir-cache-time"}, this could delay +visibility of files. + + +@anchor{Setup of sshfs method} +@subsection @option{sshfs} setup +@cindex sshfs setup + +The method @option{sshfs} declares only the mount arguments, passed to +the @command{sshfs} command. This is a list of list of strings, and +can be overwritten by the connection property @t{"mount-args"}, +@xref{Predefined connection information}. + + @node Android shell setup @section Android shell setup hints @cindex android shell setup for ssh @@ -4197,6 +4318,7 @@ Disable excessive traces. Set @code{tramp-verbose} to 3 or lower, default being 3. Increase trace levels temporarily when hunting for bugs. + @item @value{tramp} does not connect to the remote host @@ -4448,6 +4570,7 @@ disable @samp{--color=yes} or @samp{--color=auto} in the remote host's @file{.bashrc} or @file{.profile}. Turn this alias on and off to see if file name completion works. + @item File name completion does not work in directories with large number of files @@ -4846,6 +4969,7 @@ In BBDB buffer, access an entry by pressing the key @kbd{F}. Thanks to @value{tramp} users for contributing to these recipes. + @item Why saved multi-hop file names do not work in a new Emacs session? diff --git a/etc/NEWS b/etc/NEWS index ce337e7517..26bed2af18 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -266,8 +266,8 @@ current mode. +++ ** New user option 'read-extended-command-predicate'. -This option controls how 'M-x' performs completion of commands when -you type TAB. By default, any command that matches what you have +This user option controls how 'M-x' performs completion of commands when +you type 'TAB'. By default, any command that matches what you have typed is considered a completion candidate, but you can customize this option to exclude commands that are not applicable to the current buffer's major and minor modes, and respect the command's completion @@ -369,25 +369,26 @@ Typing 'TAB' on a heading line cycles the current section between anywhere in the buffer cycles the whole buffer between "only top-level headings", "all headings and subheadings", and "show all" states. -*** New option 'outline-minor-mode-cycle'. -This option customizes 'outline-minor-mode', with the difference +*** New user option 'outline-minor-mode-cycle'. +This user option customizes 'outline-minor-mode', with the difference that 'TAB' and 'S-TAB' on heading lines cycle heading visibility. Typing 'TAB' on a heading line cycles the current section between "hide all", "subheadings", and "show all" states. Typing 'S-TAB' on a heading line cycles the whole buffer between "only top-level headings", "all headings and subheadings", and "show all" states. -*** New option 'outline-minor-mode-highlight'. -This option customizes 'outline-minor-mode'. It puts highlighting -on heading lines using standard outline faces. This works well only -when there are no conflicts with faces used by the major mode. +*** New user option 'outline-minor-mode-highlight'. +This user option customizes 'outline-minor-mode'. It puts +highlighting on heading lines using standard outline faces. This +works well only when there are no conflicts with faces used by the +major mode. * Changes in Specialized Modes and Packages in Emacs 28.1 ** Macroexp --- -*** New function 'macroexp-file-name' to know the name of the current file +*** New function 'macroexp-file-name' to know the name of the current file. --- *** New function 'macroexp-compiling-p' to know if we're compiling. --- @@ -400,17 +401,18 @@ It used to be enabled when Emacs is started in GUI mode but not when started in text mode. The cursor still only actually blinks in GUI frames. ** Bindat + +++ *** New 'Bindat type expression' description language. This new system is provided by the new macro 'bindat-type' and obsoletes the old data layout specifications. It supports arbitrary-size integers, recursive types, and more. See the Info node -'Byte Packing' in the ELisp manual for more details. +"(elisp) Byte Packing" in the ELisp manual for more details. ** pcase +++ -*** The 'or' pattern now binds the union of the vars of its sub-patterns +*** The 'or' pattern now binds the union of the vars of its sub-patterns. If a variable is not bound by the subpattern that matched, it gets bound to nil. This was already sometimes the case, but it is now guaranteed. @@ -1031,10 +1033,9 @@ To customize obsolete user options, use 'customize-option' or ** Edebug ---- *** Obsoletions +--- **** 'get-edebug-spec' is obsolete, replaced by 'edebug-get-spec'. - +++ **** The spec operator ':name NAME' is obsolete, use '&name' instead. +++ @@ -1066,7 +1067,7 @@ use) and HEAD is the code that matched SPEC. +++ *** New user option 'eldoc-echo-area-display-truncation-message'. If non-nil (the default), eldoc will display a message saying -something like "(Documentation truncated. Use `M-x eldoc-doc-buffer' +something like "(Documentation truncated. Use `M-x eldoc-doc-buffer' to see rest)" when a message has been truncated. If nil, truncated messages will be marked with just "..." at the end. @@ -1134,6 +1135,10 @@ preferred over the eudcb-mab.el backend. *** New connection method "mtp", which allows accessing media devices like cell phones, tablets or cameras. ++++ +*** New connection method "sshfs", which allows accessing remote files +via a file system mounted with 'sshfs'. + +++ *** Trashed remote files are moved to the local trash directory. All remote files, which are trashed, are moved to the local trash @@ -1555,7 +1560,7 @@ have been renamed to have "proper" public names and documented 'xref-show-definitions-buffer-at-bottom'). *** New command 'xref-quit-and-pop-marker-stack' and a binding for it -in "*xref*" buffers ('M-,'). This combination is easy to press +in "*xref*" buffers ('M-,'). This combination is easy to press semi-accidentally if the user wants to go back in the middle of choosing the exact definition to go to, and this should do TRT. @@ -2138,7 +2143,7 @@ messages, contain the error name of that message now. +++ *** D-Bus events have changed their internal structure. They carry now the destination and the error-name of an event. They -also keep the type information of their arguments. Use the +also keep the type information of their arguments. Use the 'dbus-event-*' accessor functions. ** CPerl Mode @@ -2180,7 +2185,7 @@ You can type 'C-x u u' instead of 'C-x u C-x u' to undo many changes, 'C-x { { } } ^ ^ v v' to resize the selected window interactively, 'M-g n n p p' to navigate next-error matches. Any other key exits transient mode and then is executed normally. 'repeat-exit-key' -defines an additional key to exit mode like 'isearch-exit' (RET). +defines an additional key to exit mode like 'isearch-exit' ('RET'). * New Modes and Packages in Emacs 28.1 @@ -2296,7 +2301,7 @@ by mistake and were not useful to Lisp code. --- ** Loading 'generic-x' unconditionally loads all modes. -The user option `generic-extras-enable-list' is now obsolete, and +The user option 'generic-extras-enable-list' is now obsolete, and setting it has no effect. --- @@ -2343,8 +2348,8 @@ ledit.el, lmenu.el, lucid.el and old-whitespace.el. 'dirtrack-debug-toggle', 'dynamic-completion-table', 'easy-menu-precalculate-equivalent-keybindings', 'epa-display-verify-result', 'epg-passphrase-callback-function', -'erc-announced-server-name', 'erc-process', -'erc-default-coding-system', 'erc-send-command', 'eshell-report-bug', +'erc-announced-server-name', 'erc-default-coding-system', +'erc-process', 'erc-send-command', 'eshell-report-bug', 'eval-next-after-load', 'exchange-dot-and-mark', 'ffap-bug', 'ffap-submit-bug', 'ffap-version', 'file-cache-choose-completion', 'forward-point', 'generic-char-p', 'global-highlight-changes', @@ -2391,7 +2396,7 @@ ledit.el, lmenu.el, lucid.el and old-whitespace.el. 'semantic-toplevel-bovine-table', 'semanticdb-mode-hooks', 'set-coding-priority', 'set-process-filter-multibyte', 'shadows-compare-text-p', 'shell-dirtrack-toggle', -'speedbar-update-speed', 'speedbar-navigating-speed', 't-mouse-mode', +'speedbar-navigating-speed', 'speedbar-update-speed', 't-mouse-mode', 'term-dynamic-simple-complete', 'tooltip-hook', 'tpu-have-ispell', 'url-generate-unique-filename', 'url-temporary-directory', 'vc-arch-command', 'vc-default-working-revision' (variable), @@ -2413,6 +2418,8 @@ back in Emacs 23.1. The affected functions are: 'make-obsolete', ** The variable 'keyboard-type' is obsolete and not dynamically scoped any more. +** The 'values' variable is now obsolete. + * Lisp Changes in Emacs 28.1 @@ -2449,13 +2456,13 @@ This variable holds a list of currently enabled global minor modes (as a list of symbols). +++ -** 'define-minor-mode' now takes an :interactive argument. +** 'define-minor-mode' now takes an ':interactive' argument. This can be used for specifying which modes this minor mode is meant for, or to make the new minor mode non-interactive. The default value is t. +++ -** 'define-derived-mode' now takes an :interactive argument. +** 'define-derived-mode' now takes an ':interactive' argument. This can be used to control whether the defined mode is a command or not, and is useful when defining commands that aren't meant to be used by users directly. @@ -2463,8 +2470,6 @@ used by users directly. --- ** The 'easymenu' library is now preloaded. -** The 'values' variable is now obsolete. - --- ** New variable 'indent-line-ignored-functions'. This allows modes to cycle through a set of indentation functions @@ -2495,10 +2500,11 @@ When non-nil, then functions 'read-char-choice' and 'y-or-n-p' (respectively) use the function 'read-key' to read a character instead of using the minibuffer. --- -** New variable 'use-short-answers' to use 'y-or-n-p' instead of 'yes-or-no-p'. -This eliminates the need to define an alias that maps one to another -in the init file. The same variable also controls whether the -function 'read-answer' accepts short answers. +** New user option 'use-short-answers'. +When non-nil, the function 'y-or-n-p' is used instead of +'yes-or-no-p'. This eliminates the need to define an alias that maps +one to another in the init file. The same user option also controls +whether the function 'read-answer' accepts short answers. +++ ** 'set-window-configuration' now takes an optional 'dont-set-frame' @@ -2700,7 +2706,7 @@ menu handling. It is meant as an (experimental) aid for converting Emacs Lisp code to lexical binding, where dynamic (special) variables bound in one file can affect code in another. For details, see the manual section -"(Elisp) Converting to Lexical Binding". +"(elisp) Converting to Lexical Binding". +++ *** 'byte-recompile-directory' can now compile symlinked ".el" files. diff --git a/lisp/net/tramp-fuse.el b/lisp/net/tramp-fuse.el new file mode 100644 index 0000000000..ec1db8680f --- /dev/null +++ b/lisp/net/tramp-fuse.el @@ -0,0 +1,205 @@ +;;; tramp-fuse.el --- Tramp access functions for FUSE mounts -*- lexical-binding:t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Michael Albinus +;; Keywords: comm, processes +;; Package: tramp + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; These are helper functions for FUSE file systems. + +;;; Code: + +(require 'tramp) + +;; File name primitives. + +(defun tramp-fuse-handle-delete-directory + (directory &optional recursive trash) + "Like `delete-directory' for Tramp files." + (with-parsed-tramp-file-name (expand-file-name directory) nil + (tramp-flush-directory-properties v localname) + (delete-directory (tramp-fuse-local-file-name directory) recursive trash))) + +(defun tramp-fuse-handle-delete-file (filename &optional trash) + "Like `delete-file' for Tramp files." + (with-parsed-tramp-file-name (expand-file-name filename) nil + (delete-file (tramp-fuse-local-file-name filename) trash) + (tramp-flush-file-properties v localname))) + +(defun tramp-fuse-handle-directory-files + (directory &optional full match nosort count) + "Like `directory-files' for Tramp files." + (unless (file-exists-p directory) + (tramp-compat-file-missing (tramp-dissect-file-name directory) directory)) + (when (file-directory-p directory) + (setq directory (file-name-as-directory (expand-file-name directory))) + (with-parsed-tramp-file-name directory nil + (let ((result + (tramp-compat-directory-files + (tramp-fuse-local-file-name directory) full match nosort count))) + ;; Massage the result. + (when full + (let ((local (concat "^" (regexp-quote (tramp-fuse-mount-point v)))) + (remote (directory-file-name + (funcall + (if (tramp-compat-file-name-quoted-p directory) + #'tramp-compat-file-name-quote #'identity) + (file-remote-p directory))))) + (setq result + (mapcar + (lambda (x) (replace-regexp-in-string local remote x)) + result)))) + ;; Some storage systems do not return "." and "..". + (dolist (item '(".." ".")) + (when (and (string-match-p (or match (regexp-quote item)) item) + (not + (member (if full (setq item (concat directory item)) item) + result))) + (setq result (cons item result)))) + ;; Return result. + (if nosort result (sort result #'string<)))))) + +(defun tramp-fuse-handle-file-attributes (filename &optional id-format) + "Like `file-attributes' for Tramp files." + (with-parsed-tramp-file-name (expand-file-name filename) nil + (with-tramp-file-property + v localname (format "file-attributes-%s" id-format) + (file-attributes (tramp-fuse-local-file-name filename) id-format)))) + +(defun tramp-fuse-handle-file-executable-p (filename) + "Like `file-executable-p' for Tramp files." + (with-parsed-tramp-file-name (expand-file-name filename) nil + (with-tramp-file-property v localname "file-executable-p" + (file-executable-p (tramp-fuse-local-file-name filename))))) + +(defun tramp-fuse-handle-file-name-all-completions (filename directory) + "Like `file-name-all-completions' for Tramp files." + (all-completions + filename + (delete-dups + (append + (file-name-all-completions + filename (tramp-fuse-local-file-name directory)) + ;; Some storage systems do not return "." and "..". + (let (result) + (dolist (item '(".." ".") result) + (when (string-prefix-p filename item) + (catch 'match + (dolist (elt completion-regexp-list) + (unless (string-match-p elt item) (throw 'match nil))) + (setq result (cons (concat item "/") result)))))))))) + +(defun tramp-fuse-handle-file-readable-p (filename) + "Like `file-readable-p' for Tramp files." + (with-parsed-tramp-file-name (expand-file-name filename) nil + (with-tramp-file-property v localname "file-readable-p" + (file-readable-p (tramp-fuse-local-file-name filename))))) + +;; This function isn't used. +(defun tramp-fuse-handle-insert-directory + (filename switches &optional wildcard full-directory-p) + "Like `insert-directory' for Tramp files." + (insert-directory + (tramp-fuse-local-file-name filename) switches wildcard full-directory-p) + (goto-char (point-min)) + (while (search-forward (tramp-fuse-local-file-name filename) nil 'noerror) + (replace-match filename))) + +(defun tramp-fuse-handle-make-directory (dir &optional parents) + "Like `make-directory' for Tramp files." + (with-parsed-tramp-file-name (expand-file-name dir) nil + (make-directory (tramp-fuse-local-file-name dir) parents) + ;; When PARENTS is non-nil, DIR could be a chain of non-existent + ;; directories a/b/c/... Instead of checking, we simply flush the + ;; whole file cache. + (tramp-flush-file-properties v localname) + (tramp-flush-directory-properties + v (if parents "/" (file-name-directory localname))))) + + +;; File name helper functions. + +(defun tramp-fuse-mount-spec (vec) + "Return local mount spec of VEC." + (if-let ((host (tramp-file-name-host vec)) + (user (tramp-file-name-user vec))) + (format "%s@%s:/" user host) + (format "%s:/" host))) + +(defun tramp-fuse-mount-point (vec) + "Return local mount point of VEC." + (or (tramp-get-connection-property vec "mount-point" nil) + (expand-file-name + (concat + tramp-temp-name-prefix + (tramp-file-name-method vec) "." + (when (tramp-file-name-user vec) + (concat (tramp-file-name-user-domain vec) "@")) + (tramp-file-name-host-port vec)) + (tramp-compat-temporary-file-directory)))) + +(defun tramp-fuse-mounted-p (vec) + "Check, whether fuse volume determined by VEC is mounted." + (when (tramp-get-connection-process vec) + ;; We cannot use `with-connection-property', because we don't want + ;; to cache a nil result. + (or (tramp-get-connection-property + (tramp-get-connection-process vec) "mounted" nil) + (let* ((default-directory (tramp-compat-temporary-file-directory)) + (fuse (concat "fuse." (tramp-file-name-method vec))) + (mount (shell-command-to-string (format "mount -t %s" fuse)))) + (tramp-message vec 6 "%s %s" "mount -t" fuse) + (tramp-message vec 6 "\n%s" mount) + (tramp-set-connection-property + (tramp-get-connection-process vec) "mounted" + (when (string-match + (format + "^\\(%s\\)\\s-" (regexp-quote (tramp-fuse-mount-spec vec))) + mount) + (match-string 1 mount))))))) + +(defun tramp-fuse-local-file-name (filename) + "Return local mount name of FILENAME." + (setq filename (tramp-compat-file-name-unquote (expand-file-name filename))) + (with-parsed-tramp-file-name filename nil + ;; As long as we call `tramp-*-maybe-open-connection' here, + ;; we cache the result. + (with-tramp-file-property v localname "local-file-name" + (funcall + (intern + (format "tramp-%s-maybe-open-connection" (tramp-file-name-method v))) + v) + (let ((quoted (tramp-compat-file-name-quoted-p localname)) + (localname (tramp-compat-file-name-unquote localname))) + (funcall + (if quoted #'tramp-compat-file-name-quote #'identity) + (expand-file-name + (if (file-name-absolute-p localname) + (substring localname 1) localname) + (tramp-fuse-mount-point v))))))) + +(add-hook 'tramp-unload-hook + (lambda () + (unload-feature 'tramp-fuse 'force))) + +(provide 'tramp-fuse) + +;;; tramp-fuse.el ends here diff --git a/lisp/net/tramp-rclone.el b/lisp/net/tramp-rclone.el index a7f4c9be82..e6f9fe56ec 100644 --- a/lisp/net/tramp-rclone.el +++ b/lisp/net/tramp-rclone.el @@ -35,8 +35,8 @@ ;;; Code: -(eval-when-compile (require 'cl-lib)) (require 'tramp) +(require 'tramp-fuse) ;;;###tramp-autoload (defconst tramp-rclone-method "rclone" @@ -77,11 +77,11 @@ ;; `byte-compiler-base-file-name' performed by default handler. (copy-directory . tramp-handle-copy-directory) (copy-file . tramp-rclone-handle-copy-file) - (delete-directory . tramp-rclone-handle-delete-directory) - (delete-file . tramp-rclone-handle-delete-file) + (delete-directory . tramp-fuse-handle-delete-directory) + (delete-file . tramp-fuse-handle-delete-file) ;; `diff-latest-backup-file' performed by default handler. (directory-file-name . tramp-handle-directory-file-name) - (directory-files . tramp-rclone-handle-directory-files) + (directory-files . tramp-fuse-handle-directory-files) (directory-files-and-attributes . tramp-handle-directory-files-and-attributes) (dired-compress-file . ignore) @@ -90,15 +90,15 @@ (expand-file-name . tramp-handle-expand-file-name) (file-accessible-directory-p . tramp-handle-file-accessible-directory-p) (file-acl . ignore) - (file-attributes . tramp-rclone-handle-file-attributes) + (file-attributes . tramp-fuse-handle-file-attributes) (file-directory-p . tramp-handle-file-directory-p) (file-equal-p . tramp-handle-file-equal-p) - (file-executable-p . tramp-rclone-handle-file-executable-p) + (file-executable-p . tramp-fuse-handle-file-executable-p) (file-exists-p . tramp-handle-file-exists-p) (file-in-directory-p . tramp-handle-file-in-directory-p) (file-local-copy . tramp-handle-file-local-copy) (file-modes . tramp-handle-file-modes) - (file-name-all-completions . tramp-rclone-handle-file-name-all-completions) + (file-name-all-completions . tramp-fuse-handle-file-name-all-completions) (file-name-as-directory . tramp-handle-file-name-as-directory) (file-name-case-insensitive-p . tramp-handle-file-name-case-insensitive-p) (file-name-completion . tramp-handle-file-name-completion) @@ -110,7 +110,7 @@ (file-notify-rm-watch . ignore) (file-notify-valid-p . ignore) (file-ownership-preserved-p . ignore) - (file-readable-p . tramp-rclone-handle-file-readable-p) + (file-readable-p . tramp-fuse-handle-file-readable-p) (file-regular-p . tramp-handle-file-regular-p) (file-remote-p . tramp-handle-file-remote-p) (file-selinux-context . tramp-handle-file-selinux-context) @@ -124,7 +124,7 @@ (insert-file-contents . tramp-handle-insert-file-contents) (load . tramp-handle-load) (make-auto-save-file-name . tramp-handle-make-auto-save-file-name) - (make-directory . tramp-rclone-handle-make-directory) + (make-directory . tramp-fuse-handle-make-directory) (make-directory-internal . ignore) (make-nearby-temp-file . tramp-handle-make-nearby-temp-file) (make-process . ignore) @@ -277,86 +277,6 @@ file names." (list filename newname ok-if-already-exists keep-date preserve-uid-gid preserve-extended-attributes)))) -(defun tramp-rclone-handle-delete-directory - (directory &optional recursive trash) - "Like `delete-directory' for Tramp files." - (with-parsed-tramp-file-name (expand-file-name directory) nil - (tramp-flush-directory-properties v localname) - (delete-directory (tramp-rclone-local-file-name directory) recursive trash))) - -(defun tramp-rclone-handle-delete-file (filename &optional trash) - "Like `delete-file' for Tramp files." - (with-parsed-tramp-file-name (expand-file-name filename) nil - (delete-file (tramp-rclone-local-file-name filename) trash) - (tramp-flush-file-properties v localname))) - -(defun tramp-rclone-handle-directory-files - (directory &optional full match nosort count) - "Like `directory-files' for Tramp files." - (unless (file-exists-p directory) - (tramp-compat-file-missing (tramp-dissect-file-name directory) directory)) - (when (file-directory-p directory) - (setq directory (file-name-as-directory (expand-file-name directory))) - (with-parsed-tramp-file-name directory nil - (let ((result - (tramp-compat-directory-files - (tramp-rclone-local-file-name directory) full match nosort count))) - ;; Massage the result. - (when full - (let ((local (concat "^" (regexp-quote (tramp-rclone-mount-point v)))) - (remote (funcall (if (tramp-compat-file-name-quoted-p directory) - #'tramp-compat-file-name-quote #'identity) - (file-remote-p directory)))) - (setq result - (mapcar - (lambda (x) (replace-regexp-in-string local remote x)) - result)))) - ;; Some storage systems do not return "." and "..". - (dolist (item '(".." ".")) - (when (and (string-match-p (or match (regexp-quote item)) item) - (not - (member (if full (setq item (concat directory item)) item) - result))) - (setq result (cons item result)))) - ;; Return result. - (if nosort result (sort result #'string<)))))) - -(defun tramp-rclone-handle-file-attributes (filename &optional id-format) - "Like `file-attributes' for Tramp files." - (with-parsed-tramp-file-name (expand-file-name filename) nil - (with-tramp-file-property - v localname (format "file-attributes-%s" id-format) - (file-attributes (tramp-rclone-local-file-name filename) id-format)))) - -(defun tramp-rclone-handle-file-executable-p (filename) - "Like `file-executable-p' for Tramp files." - (with-parsed-tramp-file-name (expand-file-name filename) nil - (with-tramp-file-property v localname "file-executable-p" - (file-executable-p (tramp-rclone-local-file-name filename))))) - -(defun tramp-rclone-handle-file-name-all-completions (filename directory) - "Like `file-name-all-completions' for Tramp files." - (all-completions - filename - (delete-dups - (append - (file-name-all-completions - filename (tramp-rclone-local-file-name directory)) - ;; Some storage systems do not return "." and "..". - (let (result) - (dolist (item '(".." ".") result) - (when (string-prefix-p filename item) - (catch 'match - (dolist (elt completion-regexp-list) - (unless (string-match-p elt item) (throw 'match nil))) - (setq result (cons (concat item "/") result)))))))))) - -(defun tramp-rclone-handle-file-readable-p (filename) - "Like `file-readable-p' for Tramp files." - (with-parsed-tramp-file-name (expand-file-name filename) nil - (with-tramp-file-property v localname "file-readable-p" - (file-readable-p (tramp-rclone-local-file-name filename))))) - (defun tramp-rclone-handle-file-system-info (filename) "Like `file-system-info' for Tramp files." (ignore-errors @@ -384,36 +304,6 @@ file names." (when (and total free) (list total free (- total free)))))))) -(defun tramp-rclone-handle-insert-directory - (filename switches &optional wildcard full-directory-p) - "Like `insert-directory' for Tramp files." - (insert-directory - (tramp-rclone-local-file-name filename) switches wildcard full-directory-p) - (goto-char (point-min)) - (while (search-forward (tramp-rclone-local-file-name filename) nil 'noerror) - (replace-match filename))) - -(defun tramp-rclone-handle-insert-file-contents - (filename &optional visit beg end replace) - "Like `insert-file-contents' for Tramp files." - (let ((result - (insert-file-contents - (tramp-rclone-local-file-name filename) visit beg end replace))) - (prog1 - (list (expand-file-name filename) (cadr result)) - (when visit (setq buffer-file-name filename))))) - -(defun tramp-rclone-handle-make-directory (dir &optional parents) - "Like `make-directory' for Tramp files." - (with-parsed-tramp-file-name (expand-file-name dir) nil - (make-directory (tramp-rclone-local-file-name dir) parents) - ;; When PARENTS is non-nil, DIR could be a chain of non-existent - ;; directories a/b/c/... Instead of checking, we simply flush the - ;; whole file cache. - (tramp-flush-file-properties v localname) - (tramp-flush-directory-properties - v (if parents "/" (file-name-directory localname))))) - (defun tramp-rclone-handle-rename-file (filename newname &optional ok-if-already-exists) "Like `rename-file' for Tramp files." @@ -431,50 +321,6 @@ file names." ;; File name conversions. -(defun tramp-rclone-mount-point (vec) - "Return local mount point of VEC." - (expand-file-name - (concat - tramp-temp-name-prefix (tramp-file-name-method vec) - "." (tramp-file-name-host vec)) - (tramp-compat-temporary-file-directory))) - -(defun tramp-rclone-mounted-p (vec) - "Check, whether storage system determined by VEC is mounted." - (when (tramp-get-connection-process vec) - ;; We cannot use `with-connection-property', because we don't want - ;; to cache a nil result. - (or (tramp-get-connection-property - (tramp-get-connection-process vec) "mounted" nil) - (let* ((default-directory (tramp-compat-temporary-file-directory)) - (mount (shell-command-to-string "mount -t fuse.rclone"))) - (tramp-message vec 6 "%s" "mount -t fuse.rclone") - (tramp-message vec 6 "\n%s" mount) - (tramp-set-connection-property - (tramp-get-connection-process vec) "mounted" - (when (string-match - (format - "^\\(%s:\\S-*\\)" (regexp-quote (tramp-file-name-host vec))) - mount) - (match-string 1 mount))))))) - -(defun tramp-rclone-local-file-name (filename) - "Return local mount name of FILENAME." - (setq filename (tramp-compat-file-name-unquote (expand-file-name filename))) - (with-parsed-tramp-file-name filename nil - ;; As long as we call `tramp-rclone-maybe-open-connection' here, - ;; we cache the result. - (with-tramp-file-property v localname "local-file-name" - (tramp-rclone-maybe-open-connection v) - (let ((quoted (tramp-compat-file-name-quoted-p localname)) - (localname (tramp-compat-file-name-unquote localname))) - (funcall - (if quoted #'tramp-compat-file-name-quote #'identity) - (expand-file-name - (if (file-name-absolute-p localname) - (substring localname 1) localname) - (tramp-rclone-mount-point v))))))) - (defun tramp-rclone-remote-file-name (filename) "Return FILENAME as used in the `rclone' command." (setq filename (tramp-compat-file-name-unquote (expand-file-name filename))) @@ -487,7 +333,7 @@ file names." ;; TODO: This shall be handled by `expand-file-name'. (setq localname (replace-regexp-in-string "^\\." "" (or localname ""))) - (format "%s%s" (tramp-rclone-mounted-p v) localname))) + (format "%s%s" (tramp-fuse-mounted-p v) localname))) ;; It is a local file name. filename)) @@ -517,20 +363,18 @@ connection if a previous connection has died for some reason." (tramp-set-connection-local-variables vec))) ;; Create directory. - (unless (file-directory-p (tramp-rclone-mount-point vec)) - (make-directory (tramp-rclone-mount-point vec) 'parents)) + (unless (file-directory-p (tramp-fuse-mount-point vec)) + (make-directory (tramp-fuse-mount-point vec) 'parents)) ;; Mount. This command does not return, so we use 0 as ;; DESTINATION of `tramp-call-process'. - (unless (tramp-rclone-mounted-p vec) + (unless (tramp-fuse-mounted-p vec) (apply #'tramp-call-process vec tramp-rclone-program nil 0 nil - (delq nil - `("mount" ,(concat host ":/") - ,(tramp-rclone-mount-point vec) - ;; This could be nil. - ,@(tramp-get-method-parameter vec 'tramp-mount-args)))) + "mount" (tramp-fuse-mount-spec vec) + (tramp-fuse-mount-point vec) + (tramp-get-method-parameter vec 'tramp-mount-args)) (while (not (file-exists-p (tramp-make-tramp-file-name vec 'noloc))) (tramp-cleanup-connection vec 'keep-debug 'keep-password)) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 5730199407..dac83b82a8 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -2397,7 +2397,7 @@ The method used must be an out-of-band method." (append copy-args (let ((y (mapcar (lambda (z) (format-spec z spec)) x))) - (if (member "" y) '(" ") y)))))) + (unless (member "" y) y)))))) copy-env (delq @@ -2416,7 +2416,7 @@ The method used must be an out-of-band method." (append remote-copy-args (let ((y (mapcar (lambda (z) (format-spec z spec)) x))) - (if (member "" y) '(" ") y))))) + (unless (member "" y) y))))) ;; Check for local copy program. (unless (executable-find copy-program) diff --git a/lisp/net/tramp-sshfs.el b/lisp/net/tramp-sshfs.el new file mode 100644 index 0000000000..feb64b82bc --- /dev/null +++ b/lisp/net/tramp-sshfs.el @@ -0,0 +1,318 @@ +;;; tramp-sshfs.el --- Tramp access functions via sshfs -*- lexical-binding:t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Michael Albinus +;; Keywords: comm, processes +;; Package: tramp + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; sshfs is a program to mount a virtual file system, based on an sftp +;; connection. Tramp uses its mount utility to access files and +;; directories there. + +;; A remote file under sshfs control has the form +;; "/sshfs:user@host#port:/path/to/file". User name and port number +;; are optional. + +;;; Code: + +(require 'tramp) +(require 'tramp-fuse) + +;;;###tramp-autoload +(defconst tramp-sshfs-method "sshfs" + "Tramp method for sshfs mounts.") + +;;;###tramp-autoload +(defcustom tramp-sshfs-program "sshfs" + "The sshfs mount command." + :group 'tramp + :version "28.1" + :type 'string) + +;;;###tramp-autoload +(tramp--with-startup + (add-to-list 'tramp-methods + `(,tramp-sshfs-method + (tramp-mount-args + (("-p" "%p") + ("-o" "idmap=user,reconnect"))))) + + (tramp-set-completion-function + tramp-sshfs-method tramp-completion-function-alist-ssh)) + + +;; New handlers should be added here. +;;;###tramp-autoload +(defconst tramp-sshfs-file-name-handler-alist + '((access-file . tramp-handle-access-file) + (add-name-to-file . tramp-handle-add-name-to-file) + ;; `byte-compiler-base-file-name' performed by default handler. + (copy-directory . tramp-handle-copy-directory) + (copy-file . tramp-sshfs-handle-copy-file) + (delete-directory . tramp-fuse-handle-delete-directory) + (delete-file . tramp-fuse-handle-delete-file) + ;; `diff-latest-backup-file' performed by default handler. + (directory-file-name . tramp-handle-directory-file-name) + (directory-files . tramp-fuse-handle-directory-files) + (directory-files-and-attributes + . tramp-handle-directory-files-and-attributes) + (dired-compress-file . ignore) + (dired-uncache . tramp-handle-dired-uncache) +;; (exec-path . ignore) + (expand-file-name . tramp-handle-expand-file-name) + (file-accessible-directory-p . tramp-handle-file-accessible-directory-p) + (file-acl . ignore) + (file-attributes . tramp-fuse-handle-file-attributes) + (file-directory-p . tramp-handle-file-directory-p) + (file-equal-p . tramp-handle-file-equal-p) + (file-executable-p . tramp-fuse-handle-file-executable-p) + (file-exists-p . tramp-handle-file-exists-p) + (file-in-directory-p . tramp-handle-file-in-directory-p) + (file-local-copy . tramp-handle-file-local-copy) + (file-modes . tramp-handle-file-modes) + (file-name-all-completions . tramp-fuse-handle-file-name-all-completions) + (file-name-as-directory . tramp-handle-file-name-as-directory) + (file-name-case-insensitive-p . tramp-handle-file-name-case-insensitive-p) + (file-name-completion . tramp-handle-file-name-completion) + (file-name-directory . tramp-handle-file-name-directory) + (file-name-nondirectory . tramp-handle-file-name-nondirectory) + ;; `file-name-sans-versions' performed by default handler. + (file-newer-than-file-p . tramp-handle-file-newer-than-file-p) + (file-notify-add-watch . ignore) + (file-notify-rm-watch . ignore) + (file-notify-valid-p . ignore) + (file-ownership-preserved-p . ignore) + (file-readable-p . tramp-fuse-handle-file-readable-p) + (file-regular-p . tramp-handle-file-regular-p) + (file-remote-p . tramp-handle-file-remote-p) + (file-selinux-context . tramp-handle-file-selinux-context) + (file-symlink-p . tramp-handle-file-symlink-p) + (file-system-info . tramp-sshfs-handle-file-system-info) + (file-truename . tramp-handle-file-truename) + (file-writable-p . tramp-handle-file-writable-p) + (find-backup-file-name . tramp-handle-find-backup-file-name) + ;; `get-file-buffer' performed by default handler. + (insert-directory . tramp-handle-insert-directory) + (insert-file-contents . tramp-sshfs-handle-insert-file-contents) + (load . tramp-handle-load) + (make-auto-save-file-name . tramp-handle-make-auto-save-file-name) + (make-directory . tramp-fuse-handle-make-directory) + (make-directory-internal . ignore) + (make-nearby-temp-file . tramp-handle-make-nearby-temp-file) +;; (make-process . ignore) + (make-symbolic-link . tramp-handle-make-symbolic-link) +;; (process-file . ignore) + (rename-file . tramp-sshfs-handle-rename-file) + (set-file-acl . ignore) + (set-file-modes . ignore) + (set-file-selinux-context . ignore) + (set-file-times . ignore) + (set-visited-file-modtime . tramp-handle-set-visited-file-modtime) +;; (shell-command . ignore) +;; (start-file-process . ignore) + (substitute-in-file-name . tramp-handle-substitute-in-file-name) + (temporary-file-directory . tramp-handle-temporary-file-directory) +;; (tramp-get-remote-gid . ignore) +;; (tramp-get-remote-uid . ignore) +;; (tramp-set-file-uid-gid . ignore) + (unhandled-file-name-directory . ignore) + (vc-registered . ignore) + (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime) + (write-region . tramp-sshfs-handle-write-region)) +"Alist of handler functions for Tramp SSHFS method. +Operations not mentioned here will be handled by the default Emacs primitives.") + +;; It must be a `defsubst' in order to push the whole code into +;; tramp-loaddefs.el. Otherwise, there would be recursive autoloading. +;;;###tramp-autoload +(defsubst tramp-sshfs-file-name-p (filename) + "Check if it's a FILENAME for sshfs." + (and (tramp-tramp-file-p filename) + (string= (tramp-file-name-method (tramp-dissect-file-name filename)) + tramp-sshfs-method))) + +;;;###tramp-autoload +(defun tramp-sshfs-file-name-handler (operation &rest args) + "Invoke the sshfs handler for OPERATION and ARGS. +First arg specifies the OPERATION, second arg is a list of +arguments to pass to the OPERATION." + (if-let ((fn (assoc operation tramp-sshfs-file-name-handler-alist))) + (save-match-data (apply (cdr fn) args)) + (tramp-run-real-handler operation args))) + +;;;###tramp-autoload +(tramp--with-startup + (tramp-register-foreign-file-name-handler + #'tramp-sshfs-file-name-p #'tramp-sshfs-file-name-handler)) + + +;; File name primitives. + +(defun tramp-sshfs-handle-copy-file + (filename newname &optional ok-if-already-exists keep-date + preserve-uid-gid preserve-extended-attributes) + "Like `copy-file' for Tramp files." + (setq filename (expand-file-name filename) + newname (expand-file-name newname)) + (if (file-directory-p filename) + (copy-directory filename newname keep-date t) + (copy-file + (if (tramp-sshfs-file-name-p filename) + (tramp-fuse-local-file-name filename) filename) + (if (tramp-sshfs-file-name-p newname) + (tramp-fuse-local-file-name newname) newname) + ok-if-already-exists keep-date + preserve-uid-gid preserve-extended-attributes) + (when (tramp-sshfs-file-name-p newname) + (with-parsed-tramp-file-name newname nil + (tramp-flush-file-properties v localname))))) + +(defun tramp-sshfs-handle-file-system-info (filename) + "Like `file-system-info' for Tramp files." + ;;`file-system-info' exists since Emacs 27.1. + (tramp-compat-funcall 'file-system-info (tramp-fuse-local-file-name filename))) + +(defun tramp-sshfs-handle-insert-file-contents + (filename &optional visit beg end replace) + "Like `insert-file-contents' for Tramp files." + (let ((result + (insert-file-contents + (tramp-fuse-local-file-name filename) visit beg end replace))) + (when visit (setq buffer-file-name filename)) + (cons (expand-file-name filename) (cdr result)))) + +(defun tramp-sshfs-handle-rename-file + (filename newname &optional ok-if-already-exists) + "Like `rename-file' for Tramp files." + (setq filename (expand-file-name filename) + newname (expand-file-name newname)) + (rename-file + (if (tramp-sshfs-file-name-p filename) + (tramp-fuse-local-file-name filename) filename) + (if (tramp-sshfs-file-name-p newname) + (tramp-fuse-local-file-name newname) newname) + ok-if-already-exists) + (when (tramp-sshfs-file-name-p filename) + (with-parsed-tramp-file-name filename nil + (tramp-flush-file-properties v localname))) + (when (tramp-sshfs-file-name-p newname) + (with-parsed-tramp-file-name newname nil + (tramp-flush-file-properties v localname)))) + +(defun tramp-sshfs-handle-write-region + (start end filename &optional append visit lockname mustbenew) + "Like `write-region' for Tramp files." + (setq filename (expand-file-name filename)) + (with-parsed-tramp-file-name filename nil + (when (and mustbenew (file-exists-p filename) + (or (eq mustbenew 'excl) + (not + (y-or-n-p + (format "File %s exists; overwrite anyway? " filename))))) + (tramp-error v 'file-already-exists filename)) + + (write-region + start end (tramp-fuse-local-file-name filename) append 'nomessage lockname) + (tramp-flush-file-properties v localname) + + ;; The end. + (when (and (null noninteractive) + (or (eq visit t) (null visit) (stringp visit))) + (tramp-message v 0 "Wrote %s" filename)) + (run-hooks 'tramp-handle-write-region-hook))) + + +;; File name conversions. + +(defun tramp-sshfs-maybe-open-connection (vec) + "Maybe open a connection VEC. +Does not do anything if a connection is already open, but re-opens the +connection if a previous connection has died for some reason." + ;; During completion, don't reopen a new connection. + (unless (tramp-connectable-p vec) + (throw 'non-essential 'non-essential)) + + ;; We need a process bound to the connection buffer. Therefore, we + ;; create a dummy process. Maybe there is a better solution? + (unless (get-buffer-process (tramp-get-connection-buffer vec)) + (let ((p (make-network-process + :name (tramp-get-connection-name vec) + :buffer (tramp-get-connection-buffer vec) + :server t :host 'local :service t :noquery t))) + (process-put p 'vector vec) + (set-process-query-on-exit-flag p nil) + + ;; Set connection-local variables. + (tramp-set-connection-local-variables vec) + + ;; Create directory. + (unless (file-directory-p (tramp-fuse-mount-point vec)) + (make-directory (tramp-fuse-mount-point vec) 'parents)) + + (unless + (or (tramp-fuse-mounted-p vec) + (let* ((port (or (tramp-file-name-port vec) "")) + (spec (format-spec-make ?p port)) + mount-args + (mount-args + (dolist + (x + (tramp-get-method-parameter vec 'tramp-mount-args) + mount-args) + (setq mount-args + (append + mount-args + (let ((y (mapcar + (lambda (z) (format-spec z spec)) + x))) + (unless (member "" y) y))))))) + (with-temp-buffer + (zerop + (apply + #'tramp-call-process + vec tramp-sshfs-program nil t nil + (tramp-fuse-mount-spec vec) + (tramp-fuse-mount-point vec) mount-args)))) + (tramp-error + vec 'file-error "Error mounting %s" (tramp-fuse-mount-spec vec)))) + + ;; Mark it as connected. + (tramp-set-connection-property + (tramp-get-connection-process vec) "connected" t))) + + ;; In `tramp-check-cached-permissions', the connection properties + ;; "{uid,gid}-{integer,string}" are used. We set them to proper values. + (with-tramp-connection-property + vec "uid-integer" (tramp-get-local-uid 'integer)) + (with-tramp-connection-property + vec "gid-integer" (tramp-get-local-gid 'integer)) + (with-tramp-connection-property + vec "uid-string" (tramp-get-local-uid 'string)) + (with-tramp-connection-property + vec "gid-string" (tramp-get-local-gid 'string))) + +(add-hook 'tramp-unload-hook + (lambda () + (unload-feature 'tramp-sshfs 'force))) + +(provide 'tramp-sshfs) + +;;; tramp-sshfs.el ends here diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 14d5f8c3b6..47d62f3804 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -5447,11 +5447,6 @@ BODY is the backend specific code." ;; strange when doing zerop, we should kill the process and start ;; again. (Greg Stark) ;; -;; * I was wondering if it would be possible to use tramp even if I'm -;; actually using sshfs. But when I launch a command I would like -;; to get it executed on the remote machine where the files really -;; are. (Andrea Crotti) -;; ;; * Run emerge on two remote files. Bug is described here: ;; . ;; (Bug#6850) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 016b4d3c8f..d9a8065e72 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -2824,9 +2824,10 @@ This tests also `file-directory-p' and `file-accessible-directory-p'." (should (file-exists-p (expand-file-name "bla" tmp-name2))) (should-error (delete-directory tmp-name1 nil 'trash) - ;; tramp-rclone.el calls the local `delete-directory'. - ;; This raises another error. - :type (if (tramp--test-rclone-p) 'error 'file-error)) + ;; tramp-rclone.el and tramp-sshfs.el call the local + ;; `delete-directory'. This raises another error. + :type (if (or (tramp--test-rclone-p) (tramp--test-sshfs-p)) + 'error 'file-error)) (delete-directory tmp-name1 'recursive 'trash) (should-not (file-directory-p tmp-name1)) (should @@ -3254,8 +3255,8 @@ This tests also `file-directory-p' and `file-accessible-directory-p'." (ignore-errors (delete-directory tmp-name1 'recursive)))))) ;; Method "smb" supports `make-symbolic-link' only if the remote host -;; has CIFS capabilities. tramp-adb.el, tramp-gvfs.el and -;; tramp-rclone.el do not support symbolic links at all. +;; has CIFS capabilities. tramp-adb.el, tramp-gvfs.el, tramp-rclone.el +;; and tramp-sshfs.el do not support symbolic links at all. (defmacro tramp--test-ignore-make-symbolic-link-error (&rest body) "Run BODY, ignoring \"make-symbolic-link not supported\" file error." (declare (indent defun) (debug (body))) @@ -5819,6 +5820,11 @@ Additionally, ls does not support \"--dired\"." "^\\(afp\\|davs?\\|smb\\)$" (file-remote-p tramp-test-temporary-file-directory 'method)))) +(defun tramp--test-sshfs-p () + "Check, whether the remote host is offered by sshfs. +This requires restrictions of file name syntax." + (tramp-sshfs-file-name-p tramp-test-temporary-file-directory)) + (defun tramp--test-sudoedit-p () "Check, whether the sudoedit method is used." (tramp-sudoedit-file-name-p tramp-test-temporary-file-directory)) @@ -6761,7 +6767,6 @@ If INTERACTIVE is non-nil, the tests are run interactively." ;; * Fix `tramp-test06-directory-file-name' for `ftp'. ;; * Implement `tramp-test31-interrupt-process' for `adb' and for ;; direct async processes. -;; * Fix `tramp-test44-threads'. (provide 'tramp-tests) commit a190bc9f3067d9c35fc4344248222eb6ff2a0fc6 Author: Stefan Kangas Date: Mon Mar 8 05:25:18 2021 +0100 Delete two more items obsoleted in Emacs 23.1 * lisp/calendar/icalendar.el (icalendar--datetime-to-noneuropean-date): Remove alias obsolete since * lisp/obsolete/nnir.el (nnir-swish-e-index-file): Delete items obsolete since Emacs 23.1. ; * etc/NEWS: List removed items. diff --git a/etc/NEWS b/etc/NEWS index 3d94a0325d..ce337e7517 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2350,18 +2350,20 @@ ledit.el, lmenu.el, lucid.el and old-whitespace.el. 'forward-point', 'generic-char-p', 'global-highlight-changes', 'hi-lock-face-history', 'hi-lock-regexp-history', 'highlight-changes-active-string', 'highlight-changes-initial-state', -'highlight-changes-passive-string', 'image-mode-maybe', +'highlight-changes-passive-string', +'icalendar--datetime-to-noneuropean-date', 'image-mode-maybe', 'imenu-example--name-and-position', 'ispell-aspell-supports-utf8', 'lisp-mode-auto-fill', 'locate-file-completion', 'make-coding-system', 'minibuffer-local-must-match-filename-map', 'mouse-choose-completion', 'mouse-major-mode-menu', 'mouse-popup-menubar', 'mouse-popup-menubar-stuff', 'newsticker-groups-filename', -'nnmail-fix-eudora-headers', 'non-iso-charset-alist', -'nonascii-insert-offset', 'nonascii-translation-table', -'password-read-and-add', 'pre-abbrev-expand-hook', 'princ-list', -'print-help-return-message', 'process-filter-multibyte-p', -'read-file-name-predicate', 'remember-buffer', 'rmail-highlight-face', -'rmail-message-filter', 'semantic-after-idle-scheduler-reparse-hooks', +'nnir-swish-e-index-file', 'nnmail-fix-eudora-headers', +'non-iso-charset-alist', 'nonascii-insert-offset', +'nonascii-translation-table', 'password-read-and-add', +'pre-abbrev-expand-hook', 'princ-list', 'print-help-return-message', +'process-filter-multibyte-p', 'read-file-name-predicate', +'remember-buffer', 'rmail-highlight-face', 'rmail-message-filter', +'semantic-after-idle-scheduler-reparse-hooks', 'semantic-after-toplevel-bovinate-hook', 'semantic-before-idle-scheduler-reparse-hooks', 'semantic-before-toplevel-bovination-hook', diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el index 0b6ff56042..8f4dbf0c5e 100644 --- a/lisp/calendar/icalendar.el +++ b/lisp/calendar/icalendar.el @@ -773,9 +773,6 @@ American format: \"month day year\"." ;; datetime == nil nil)) -(define-obsolete-function-alias 'icalendar--datetime-to-noneuropean-date - 'icalendar--datetime-to-american-date "23.1") - (defun icalendar--datetime-to-european-date (datetime &optional separator) "Convert the decoded DATETIME to European format. Optional argument SEPARATOR gives the separator between month, diff --git a/lisp/obsolete/nnir.el b/lisp/obsolete/nnir.el index 7d7e88184c..fef76ba327 100644 --- a/lisp/obsolete/nnir.el +++ b/lisp/obsolete/nnir.el @@ -275,21 +275,11 @@ that it is for swish++, not Namazu." ;; Swish-E. ;; URL: http://swish-e.org/ -;; Variables `nnir-swish-e-index-file', `nnir-swish-e-program' and +;; Variables `nnir-swish-e-index-files', `nnir-swish-e-program' and ;; `nnir-swish-e-additional-switches' -(make-obsolete-variable 'nnir-swish-e-index-file - 'nnir-swish-e-index-files "23.1") -(defcustom nnir-swish-e-index-file - (expand-file-name "~/Mail/index.swish-e") - "Index file for swish-e. -This could be a server parameter. -It is never consulted once `nnir-swish-e-index-files', which should be -used instead, has been customized." - :type '(file)) - (defcustom nnir-swish-e-index-files - (list nnir-swish-e-index-file) + (list (expand-file-name "~/Mail/index.swish-e")) "List of index files for swish-e. This could be a server parameter." :type '(repeat (file))) commit 0e4a2dca836b52740ead29d5ff6436d938d17a78 Author: Stefan Kangas Date: Mon Mar 8 05:09:27 2021 +0100 Normalize version specifiers for make-obsolete and friends * lisp/auth-source.el (auth-source-forget-user-or-password) (auth-source-user-or-password, auth-source-hide-passwords): * lisp/calendar/icalendar.el (icalendar--datetime-to-noneuropean-date): * lisp/cedet/semantic/db-el.el (semanticdb-elisp-sym-function-arglist): * lisp/emacs-lisp/debug.el (debugger-insert-backtrace): * lisp/obsolete/nnir.el (nnir-swish-e-index-file): * lisp/obsolete/starttls.el (starttls-any-program-available): Normalize version specifiers for make-obsolete and friends. diff --git a/lisp/auth-source.el b/lisp/auth-source.el index 14cae8a52c..2516b4b9fa 100644 --- a/lisp/auth-source.el +++ b/lisp/auth-source.el @@ -162,7 +162,7 @@ let-binding." (defvar auth-source-creation-prompts nil "Default prompts for token values. Usually let-bound.") -(make-obsolete 'auth-source-hide-passwords nil "Emacs 24.1") +(make-obsolete 'auth-source-hide-passwords nil "24.1") (defcustom auth-source-save-behavior 'ask "If set, auth-source will respect it for save behavior." @@ -2307,9 +2307,9 @@ See `auth-source-search' for details on SPEC." ;; deprecate the old interface (make-obsolete 'auth-source-user-or-password - 'auth-source-search "Emacs 24.1") + 'auth-source-search "24.1") (make-obsolete 'auth-source-forget-user-or-password - 'auth-source-forget "Emacs 24.1") + 'auth-source-forget "24.1") (defun auth-source-user-or-password (mode host port &optional username create-missing delete-existing) diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el index dafdd418d0..0b6ff56042 100644 --- a/lisp/calendar/icalendar.el +++ b/lisp/calendar/icalendar.el @@ -774,7 +774,7 @@ American format: \"month day year\"." nil)) (define-obsolete-function-alias 'icalendar--datetime-to-noneuropean-date - 'icalendar--datetime-to-american-date "icalendar 0.19") + 'icalendar--datetime-to-american-date "23.1") (defun icalendar--datetime-to-european-date (datetime &optional separator) "Convert the decoded DATETIME to European format. diff --git a/lisp/cedet/semantic/db-el.el b/lisp/cedet/semantic/db-el.el index 4699e722c1..de84b97802 100644 --- a/lisp/cedet/semantic/db-el.el +++ b/lisp/cedet/semantic/db-el.el @@ -195,9 +195,6 @@ If Emacs cannot resolve this symbol to a particular file, then return nil." (when tab (cons tab match)))))) (autoload 'help-function-arglist "help-fns") -(defalias 'semanticdb-elisp-sym-function-arglist 'help-function-arglist) -(make-obsolete 'semanticdb-elisp-sym-function-arglist - 'help-function-arglist "CEDET 1.1") (defun semanticdb-elisp-sym->tag (sym &optional toktype) "Convert SYM into a semantic tag. @@ -347,6 +344,9 @@ Return a list of tags." ) taglst)))) +(define-obsolete-function-alias 'semanticdb-elisp-sym-function-arglist + #'help-function-arglist "24.3") + (provide 'semantic/db-el) ;;; semantic/db-el.el ends here diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el index d9da0db455..b2d54c77fe 100644 --- a/lisp/emacs-lisp/debug.el +++ b/lisp/emacs-lisp/debug.el @@ -321,7 +321,7 @@ the debugger will not be entered." (make-obsolete 'debugger-insert-backtrace "use a `backtrace-mode' buffer or `backtrace-to-string'." - "Emacs 27.1") + "27.1") (defun debugger-insert-backtrace (frames do-xrefs) "Format and insert the backtrace FRAMES at point. diff --git a/lisp/obsolete/nnir.el b/lisp/obsolete/nnir.el index 337d83ccca..7d7e88184c 100644 --- a/lisp/obsolete/nnir.el +++ b/lisp/obsolete/nnir.el @@ -279,7 +279,7 @@ that it is for swish++, not Namazu." ;; `nnir-swish-e-additional-switches' (make-obsolete-variable 'nnir-swish-e-index-file - 'nnir-swish-e-index-files "Emacs 23.1") + 'nnir-swish-e-index-files "23.1") (defcustom nnir-swish-e-index-file (expand-file-name "~/Mail/index.swish-e") "Index file for swish-e. diff --git a/lisp/obsolete/starttls.el b/lisp/obsolete/starttls.el index 0ca486324f..926248db9a 100644 --- a/lisp/obsolete/starttls.el +++ b/lisp/obsolete/starttls.el @@ -288,7 +288,7 @@ GnuTLS requires a port number." starttls-program)))) (define-obsolete-function-alias 'starttls-any-program-available - #'starttls-available-p "2011-08-02") + #'starttls-available-p "24.1") (provide 'starttls) commit 570afde3765732b6705ba447adfc4c36fa6e9a0c Author: Stefan Kangas Date: Mon Mar 8 04:23:11 2021 +0100 * lisp/help-mode.el (help-mode-tool-bar-map): Fix tooltips. diff --git a/lisp/help-mode.el b/lisp/help-mode.el index e6a5fe8a80..c7eaae5feb 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -66,11 +66,11 @@ (defvar help-mode-tool-bar-map (let ((map (make-sparse-keymap))) (tool-bar-local-item "close" 'quit-window 'quit map - :label "Quit help." + :help "Quit help" :vert-only t) (define-key-after map [separator-1] menu-bar-separator) (tool-bar-local-item "search" 'isearch-forward 'search map - :label "Search" :vert-only t) + :help "Search" :vert-only t) (tool-bar-local-item-from-menu 'help-go-back "left-arrow" map help-mode-map :rtl "right-arrow" :vert-only t) (tool-bar-local-item-from-menu 'help-go-forward "right-arrow" map help-mode-map commit 4a112fd7a6f0dcbd1b99b811b324123f5699bdfb Author: Stefan Kangas Date: Mon Mar 8 03:29:42 2021 +0100 Add new face 'help-key-binding' for keybindings in help * lisp/faces.el (help-key-binding): New face. * lisp/help.el (help-for-help): Rename from 'help-for-help-internal'. Use 'substitute-command-keys' syntax. (help): Make into alias for 'help-for-help'. (help-for-help-internal): Make into obsolete alias for 'help-for-help'. (help--key-description-fontified): New function to add the 'help-key-binding' face. (help-key-description, substitute-command-keys) (describe-map-tree, help--describe-command) (help--describe-translation, describe-map): * lisp/help-fns.el (help-fns--key-bindings, describe-mode): Use above new function. * lisp/isearch.el (isearch-help-for-help-internal): Use `substitute-command-keys' syntax. * lisp/help-macro.el (make-help-screen): Use 'substitute-command-keys' and 'help--key-description-fontified'. Simplify. * src/keymap.c (describe_key_maybe_fontify): New function to add the 'help-key-binding' face to keybindings. (describe_vector): Use above new keybinding. (syms_of_keymap) : New DEFSYMs. (fontify_key_properties): New static variable. * lisp/tooltip.el (tooltip-show): Avoid overriding faces in specified tooltip text. * test/lisp/help-tests.el (with-substitute-command-keys-test): Don't test for text properties. (help-tests-substitute-command-keys/add-key-face) (help-tests-substitute-command-keys/add-key-face-listing): New tests. diff --git a/etc/NEWS b/etc/NEWS index cf21a7b0f1..3d94a0325d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -919,6 +919,15 @@ skipped. ** Help +--- +*** Keybindings in 'help-mode' use the new 'help-key-binding' face. +This face is added by 'substitute-command-keys' to any "\[command]" +substitution. The return value of that function should consequently +be assumed to be a propertized string. + +Note that the new face will also be used in tooltips. When using the +GTK toolkit, this is only true if 'x-gtk-use-system-tooltips' is t. + --- *** 'g' ('revert-buffer') in 'help-mode' no longer requires confirmation. diff --git a/lisp/faces.el b/lisp/faces.el index 90f11bbe3b..b2d47edca0 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -2815,6 +2815,23 @@ Note: Other faces cannot inherit from the cursor face." "Face to highlight argument names in *Help* buffers." :group 'help) +(defface help-key-binding + '((((class color) (min-colors 88) (background light)) :foreground "ForestGreen") + (((class color) (min-colors 88) (background dark)) :foreground "#44bc44") + (((class color grayscale) (background light)) :foreground "grey15") + (((class color grayscale) (background dark)) :foreground "grey85") + (t :foreground "ForestGreen")) + "Face for keybindings in *Help* buffers. + +This face is added by `substitute-command-keys', which see. + +Note that this face will also be used for key bindings in +tooltips. This means that, for example, changing the :height of +this face will increase the height of any tooltip containing key +bindings. See also the face `tooltip'." + :version "28.1" + :group 'help) + (defface glyphless-char '((((type tty)) :inherit underline) (((type pc)) :inherit escape-glyph) diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 01d3756bf0..c27cdb5aa4 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -466,13 +466,16 @@ suitable file is found, return nil." ;; If lots of ordinary text characters run this command, ;; don't mention them one by one. (if (< (length non-modified-keys) 10) - (princ (mapconcat #'key-description keys ", ")) + (with-current-buffer standard-output + (insert (mapconcat #'help--key-description-fontified + keys ", "))) (dolist (key non-modified-keys) (setq keys (delq key keys))) (if keys - (progn - (princ (mapconcat #'key-description keys ", ")) - (princ ", and many ordinary text characters")) + (with-current-buffer standard-output + (insert (mapconcat #'help--key-description-fontified + keys ", ")) + (insert ", and many ordinary text characters")) (princ "many ordinary text characters")))) (when (or remapped keys non-modified-keys) (princ ".") @@ -1824,10 +1827,12 @@ documentation for the major and minor modes of that buffer." (save-excursion (re-search-backward (substitute-command-keys "`\\([^`']+\\)'") nil t) - (help-xref-button 1 'help-function-def mode file-name))))) - (princ ":\n") - (princ (help-split-fundoc (documentation major-mode) nil 'doc)) - (princ (help-fns--list-local-commands))))) + (help-xref-button 1 'help-function-def mode file-name))))) + (let ((fundoc (help-split-fundoc (documentation major-mode) nil 'doc))) + (with-current-buffer standard-output + (insert ":\n") + (insert fundoc) + (insert (help-fns--list-local-commands))))))) ;; For the sake of IELM and maybe others nil) diff --git a/lisp/help-macro.el b/lisp/help-macro.el index 791b10a878..72371a8727 100644 --- a/lisp/help-macro.el +++ b/lisp/help-macro.el @@ -92,119 +92,117 @@ If HELP-TEXT contains the sequence `%THIS-KEY%', that is replaced with the key sequence that invoked FNAME. When FNAME finally does get a command, it executes that command and then returns." - (let ((doc-fn (intern (concat (symbol-name fname) "-doc")))) - `(progn - (defun ,doc-fn () ,help-text nil) - (defun ,fname () - "Help command." - (interactive) - (let ((line-prompt - (substitute-command-keys ,help-line))) - (when three-step-help - (message "%s" line-prompt)) - (let* ((help-screen (documentation (quote ,doc-fn))) - ;; We bind overriding-local-map for very small - ;; sections, *excluding* where we switch buffers - ;; and where we execute the chosen help command. - (local-map (make-sparse-keymap)) - (new-minor-mode-map-alist minor-mode-map-alist) - (prev-frame (selected-frame)) - config new-frame key char) - (when (string-match "%THIS-KEY%" help-screen) - (setq help-screen - (replace-match (key-description - (substring (this-command-keys) 0 -1)) - t t help-screen))) - (unwind-protect - (let ((minor-mode-map-alist nil)) - (setcdr local-map ,helped-map) - (define-key local-map [t] 'undefined) - ;; Make the scroll bar keep working normally. - (define-key local-map [vertical-scroll-bar] - (lookup-key global-map [vertical-scroll-bar])) - (if three-step-help - (progn - (setq key (let ((overriding-local-map local-map)) - (read-key-sequence nil))) - ;; Make the HELP key translate to C-h. - (if (lookup-key function-key-map key) - (setq key (lookup-key function-key-map key))) - (setq char (aref key 0))) - (setq char ??)) - (when (or (eq char ??) (eq char help-char) - (memq char help-event-list)) - (setq config (current-window-configuration)) - (pop-to-buffer " *Metahelp*" nil t) - (and (fboundp 'make-frame) - (not (eq (window-frame) - prev-frame)) - (setq new-frame (window-frame) - config nil)) - (setq buffer-read-only nil) - (let ((inhibit-read-only t)) - (erase-buffer) - (insert help-screen)) - (let ((minor-mode-map-alist new-minor-mode-map-alist)) - (help-mode) - (setq new-minor-mode-map-alist minor-mode-map-alist)) - (goto-char (point-min)) - (while (or (memq char (append help-event-list - (cons help-char '(?? ?\C-v ?\s ?\177 delete backspace vertical-scroll-bar ?\M-v)))) - (eq (car-safe char) 'switch-frame) - (equal key "\M-v")) - (condition-case nil - (cond - ((eq (car-safe char) 'switch-frame) - (handle-switch-frame char)) - ((memq char '(?\C-v ?\s)) - (scroll-up)) - ((or (memq char '(?\177 ?\M-v delete backspace)) - (equal key "\M-v")) - (scroll-down))) - (error nil)) - (let ((cursor-in-echo-area t) - (overriding-local-map local-map)) - (setq key (read-key-sequence - (format "Type one of the options listed%s: " - (if (pos-visible-in-window-p - (point-max)) - "" ", or SPACE or DEL to scroll"))) - char (aref key 0))) - - ;; If this is a scroll bar command, just run it. - (when (eq char 'vertical-scroll-bar) - (command-execute (lookup-key local-map key) nil key)))) - ;; We don't need the prompt any more. - (message "") - ;; Mouse clicks are not part of the help feature, - ;; so reexecute them in the standard environment. - (if (listp char) - (setq unread-command-events - (cons char unread-command-events) - config nil) - (let ((defn (lookup-key local-map key))) - (if defn - (progn - (when config - (set-window-configuration config) - (setq config nil)) - ;; Temporarily rebind `minor-mode-map-alist' - ;; to `new-minor-mode-map-alist' (Bug#10454). - (let ((minor-mode-map-alist new-minor-mode-map-alist)) - ;; `defn' must make sure that its frame is - ;; selected, so we won't iconify it below. - (call-interactively defn)) - (when new-frame - ;; Do not iconify the selected frame. - (unless (eq new-frame (selected-frame)) - (iconify-frame new-frame)) - (setq new-frame nil))) - (ding))))) - (when config - (set-window-configuration config)) - (when new-frame - (iconify-frame new-frame)) - (setq minor-mode-map-alist new-minor-mode-map-alist)))))))) + (declare (indent defun)) + `(defun ,fname () + "Help command." + (interactive) + (let ((line-prompt + (substitute-command-keys ,help-line))) + (when three-step-help + (message "%s" line-prompt)) + (let* ((help-screen ,help-text) + ;; We bind overriding-local-map for very small + ;; sections, *excluding* where we switch buffers + ;; and where we execute the chosen help command. + (local-map (make-sparse-keymap)) + (new-minor-mode-map-alist minor-mode-map-alist) + (prev-frame (selected-frame)) + config new-frame key char) + (when (string-match "%THIS-KEY%" help-screen) + (setq help-screen + (replace-match (help--key-description-fontified + (substring (this-command-keys) 0 -1)) + t t help-screen))) + (unwind-protect + (let ((minor-mode-map-alist nil)) + (setcdr local-map ,helped-map) + (define-key local-map [t] 'undefined) + ;; Make the scroll bar keep working normally. + (define-key local-map [vertical-scroll-bar] + (lookup-key global-map [vertical-scroll-bar])) + (if three-step-help + (progn + (setq key (let ((overriding-local-map local-map)) + (read-key-sequence nil))) + ;; Make the HELP key translate to C-h. + (if (lookup-key function-key-map key) + (setq key (lookup-key function-key-map key))) + (setq char (aref key 0))) + (setq char ??)) + (when (or (eq char ??) (eq char help-char) + (memq char help-event-list)) + (setq config (current-window-configuration)) + (pop-to-buffer " *Metahelp*" nil t) + (and (fboundp 'make-frame) + (not (eq (window-frame) + prev-frame)) + (setq new-frame (window-frame) + config nil)) + (setq buffer-read-only nil) + (let ((inhibit-read-only t)) + (erase-buffer) + (insert (substitute-command-keys help-screen))) + (let ((minor-mode-map-alist new-minor-mode-map-alist)) + (help-mode) + (setq new-minor-mode-map-alist minor-mode-map-alist)) + (goto-char (point-min)) + (while (or (memq char (append help-event-list + (cons help-char '(?? ?\C-v ?\s ?\177 delete backspace vertical-scroll-bar ?\M-v)))) + (eq (car-safe char) 'switch-frame) + (equal key "\M-v")) + (condition-case nil + (cond + ((eq (car-safe char) 'switch-frame) + (handle-switch-frame char)) + ((memq char '(?\C-v ?\s)) + (scroll-up)) + ((or (memq char '(?\177 ?\M-v delete backspace)) + (equal key "\M-v")) + (scroll-down))) + (error nil)) + (let ((cursor-in-echo-area t) + (overriding-local-map local-map)) + (setq key (read-key-sequence + (format "Type one of the options listed%s: " + (if (pos-visible-in-window-p + (point-max)) + "" ", or SPACE or DEL to scroll"))) + char (aref key 0))) + + ;; If this is a scroll bar command, just run it. + (when (eq char 'vertical-scroll-bar) + (command-execute (lookup-key local-map key) nil key)))) + ;; We don't need the prompt any more. + (message "") + ;; Mouse clicks are not part of the help feature, + ;; so reexecute them in the standard environment. + (if (listp char) + (setq unread-command-events + (cons char unread-command-events) + config nil) + (let ((defn (lookup-key local-map key))) + (if defn + (progn + (when config + (set-window-configuration config) + (setq config nil)) + ;; Temporarily rebind `minor-mode-map-alist' + ;; to `new-minor-mode-map-alist' (Bug#10454). + (let ((minor-mode-map-alist new-minor-mode-map-alist)) + ;; `defn' must make sure that its frame is + ;; selected, so we won't iconify it below. + (call-interactively defn)) + (when new-frame + ;; Do not iconify the selected frame. + (unless (eq new-frame (selected-frame)) + (iconify-frame new-frame)) + (setq new-frame nil))) + (ding))))) + (when config + (set-window-configuration config)) + (when new-frame + (iconify-frame new-frame)) + (setq minor-mode-map-alist new-minor-mode-map-alist)))))) (provide 'help-macro) diff --git a/lisp/help.el b/lisp/help.el index 084e941549..94073e5730 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -104,8 +104,8 @@ (define-key map "R" 'info-display-manual) (define-key map "s" 'describe-syntax) (define-key map "t" 'help-with-tutorial) - (define-key map "w" 'where-is) (define-key map "v" 'describe-variable) + (define-key map "w" 'where-is) (define-key map "q" 'help-quit) map) "Keymap for characters following the Help key.") @@ -187,64 +187,58 @@ Do not call this in the scope of `with-help-window'." ;; So keyboard macro definitions are documented correctly (fset 'defining-kbd-macro (symbol-function 'start-kbd-macro)) -(defalias 'help 'help-for-help-internal) -;; find-function can find this. -(defalias 'help-for-help 'help-for-help-internal) -;; It can't find this, but nobody will look. -(make-help-screen help-for-help-internal +(defalias 'help 'help-for-help) +(make-help-screen help-for-help (purecopy "Type a help option: [abcCdefFgiIkKlLmnprstvw.] C-[cdefmnoptw] or ?") - ;; Don't purecopy this one, because it's not evaluated (it's - ;; directly used as a docstring in a function definition, so it'll - ;; be moved to the DOC file anyway: no need for purecopying it). "You have typed %THIS-KEY%, the help character. Type a Help option: \(Use SPC or DEL to scroll through this text. Type \\\\[help-quit] to exit the Help command.) -a PATTERN Show commands whose name matches the PATTERN (a list of words - or a regexp). See also the `apropos' command. -b Display all key bindings. -c KEYS Display the command name run by the given key sequence. -C CODING Describe the given coding system, or RET for current ones. -d PATTERN Show a list of functions, variables, and other items whose +\\[apropos-command] PATTERN Show commands whose name matches the PATTERN (a list of words + or a regexp). See also \\[apropos]. +\\[describe-bindings] Display all key bindings. +\\[describe-key-briefly] KEYS Display the command name run by the given key sequence. +\\[describe-coding-system] CODING Describe the given coding system, or RET for current ones. +\\[apropos-documentation] PATTERN Show a list of functions, variables, and other items whose documentation matches the PATTERN (a list of words or a regexp). -e Go to the *Messages* buffer which logs echo-area messages. -f FUNCTION Display documentation for the given function. -F COMMAND Show the Emacs manual's section that describes the command. -g Display information about the GNU project. -h Display the HELLO file which illustrates various scripts. -i Start the Info documentation reader: read included manuals. -I METHOD Describe a specific input method, or RET for current. -k KEYS Display the full documentation for the key sequence. -K KEYS Show the Emacs manual's section for the command bound to KEYS. -l Show last 300 input keystrokes (lossage). -L LANG-ENV Describes a specific language environment, or RET for current. -m Display documentation of current minor modes and current major mode, - including their special commands. -n Display news of recent Emacs changes. -o SYMBOL Display the given function or variable's documentation and value. -p TOPIC Find packages matching a given topic keyword. -P PACKAGE Describe the given Emacs Lisp package. -r Display the Emacs manual in Info mode. -R Prompt for a manual and then display it in Info mode. -s Display contents of current syntax table, plus explanations. -S SYMBOL Show the section for the given symbol in the Info manual +\\[view-echo-area-messages] Go to the *Messages* buffer which logs echo-area messages. +\\[describe-function] FUNCTION Display documentation for the given function. +\\[Info-goto-emacs-command-node] COMMAND Show the Emacs manual's section that describes the command. +\\[describe-gnu-project] Display information about the GNU project. +\\[view-hello-file] Display the HELLO file which illustrates various scripts. +\\[info] Start the Info documentation reader: read included manuals. +\\[describe-input-method] METHOD Describe a specific input method, or RET for current. +\\[describe-key] KEYS Display the full documentation for the key sequence. +\\[Info-goto-emacs-key-command-node] KEYS Show the Emacs manual's section for the command bound to KEYS. +\\[view-lossage] Show last 300 input keystrokes (lossage). +\\[describe-language-environment] LANG-ENV Describes a specific language environment, or RET for current. +\\[describe-mode] Display documentation of current minor modes and current major mode, + including their special commands. +\\[view-emacs-news] Display news of recent Emacs changes. +\\[describe-symbol] SYMBOL Display the given function or variable's documentation and value. +\\[finder-by-keyword] TOPIC Find packages matching a given topic keyword. +\\[describe-package] PACKAGE Describe the given Emacs Lisp package. +\\[info-emacs-manual] Display the Emacs manual in Info mode. +\\[info-display-manual] Prompt for a manual and then display it in Info mode. +\\[describe-syntax] Display contents of current syntax table, plus explanations. +\\[info-lookup-symbol] SYMBOL Show the section for the given symbol in the Info manual for the programming language used in this buffer. -t Start the Emacs learn-by-doing tutorial. -v VARIABLE Display the given variable's documentation and value. -w COMMAND Display which keystrokes invoke the given command (where-is). -. Display any available local help at point in the echo area. - -C-a Information about Emacs. -C-c Emacs copying permission (GNU General Public License). -C-d Instructions for debugging GNU Emacs. -C-e External packages and information about Emacs. -C-f Emacs FAQ. +\\[help-with-tutorial] Start the Emacs learn-by-doing tutorial. +\\[describe-variable] VARIABLE Display the given variable's documentation and value. +\\[where-is] COMMAND Display which keystrokes invoke the given command (where-is). +\\[display-local-help] Display any available local help at point in the echo area. + +\\[about-emacs] Information about Emacs. +\\[describe-copying] Emacs copying permission (GNU General Public License). +\\[view-emacs-debugging] Instructions for debugging GNU Emacs. +\\[view-external-packages] External packages and information about Emacs. +\\[view-emacs-FAQ] Emacs FAQ. C-m How to order printed Emacs manuals. C-n News of recent Emacs changes. -C-o Emacs ordering and distribution information. -C-p Info about known Emacs problems. -C-s Search forward \"help window\". -C-t Emacs TODO list. -C-w Information on absence of warranty for GNU Emacs." +\\[describe-distribution] Emacs ordering and distribution information. +\\[view-emacs-problems] Info about known Emacs problems. +\\[search-forward-help-for-help] Search forward \"help window\". +\\[view-emacs-todo] Emacs TODO list. +\\[describe-no-warranty] Information on absence of warranty for GNU Emacs." help-map) @@ -492,6 +486,15 @@ To record all your input, use `open-dribble-file'." ;; Key bindings +(defun help--key-description-fontified (keys &optional prefix) + "Like `key-description' but add face for \"*Help*\" buffers." + ;; We add both the `font-lock-face' and `face' properties here, as this + ;; seems to be the only way to get this to work reliably in any + ;; buffer. + (propertize (key-description keys prefix) + 'font-lock-face 'help-key-binding + 'face 'help-key-binding)) + (defun describe-bindings (&optional prefix buffer) "Display a buffer showing a list of all defined keys, and their definitions. The keys are displayed in order of precedence. @@ -511,7 +514,6 @@ or a buffer name." (with-current-buffer (help-buffer) (describe-buffer-bindings buffer prefix)))) -;; This function used to be in keymap.c. (defun describe-bindings-internal (&optional menus prefix) "Show a list of all defined keys, and their definitions. We put that list in a buffer, and display the buffer. @@ -559,7 +561,8 @@ If INSERT (the prefix arg) is non-nil, insert the message in the buffer." (let* ((remapped (command-remapping symbol)) (keys (where-is-internal symbol overriding-local-map nil nil remapped)) - (keys (mapconcat 'key-description keys ", ")) + (keys (mapconcat #'help--key-description-fontified + keys ", ")) string) (setq string (if insert @@ -587,11 +590,11 @@ If INSERT (the prefix arg) is non-nil, insert the message in the buffer." nil) (defun help-key-description (key untranslated) - (let ((string (key-description key))) + (let ((string (help--key-description-fontified key))) (if (or (not untranslated) (and (eq (aref untranslated 0) ?\e) (not (eq (aref key 0) ?\e)))) string - (let ((otherstring (key-description untranslated))) + (let ((otherstring (help--key-description-fontified untranslated))) (if (equal string otherstring) string (format "%s (translated from %s)" string otherstring)))))) @@ -979,7 +982,7 @@ is currently activated with completion." "Substitute key descriptions for command names in STRING. Each substring of the form \\\\=[COMMAND] is replaced by either a keystroke sequence that invokes COMMAND, or \"M-x COMMAND\" if COMMAND -is not on any keys. +is not on any keys. Keybindings will use the face `help-key-binding'. Each substring of the form \\\\={MAPVAR} is replaced by a summary of the value of MAPVAR as a keymap. This summary is similar to the one @@ -999,7 +1002,7 @@ into the output, \\\\==\\[ puts \\[ into the output, and \\\\==\\=` puts \\=` in output. Return the original STRING if no substitutions are made. -Otherwise, return a new string (without any text properties)." +Otherwise, return a new string." (when (not (null string)) ;; KEYMAP is either nil (which means search all the active ;; keymaps) or a specified local map (which means search just that @@ -1053,12 +1056,16 @@ Otherwise, return a new string (without any text properties)." (where-is-internal fun keymap t)))) (if (not key) ;; Function is not on any key. - (progn (insert "M-x ") - (goto-char (+ end-point 3)) - (delete-char 1)) + (let ((op (point))) + (insert "M-x ") + (goto-char (+ end-point 3)) + (add-text-properties op (point) + '( face help-key-binding + font-lock-face help-key-binding)) + (delete-char 1)) ;; Function is on a key. (delete-char (- end-point (point))) - (insert (key-description key))))) + (insert (help--key-description-fontified key))))) ;; 1D. \{foo} is replaced with a summary of the keymap ;; (symbol-value foo). ;; \ just sets the keymap used for \[cmd]. @@ -1172,7 +1179,7 @@ Any inserted text ends in two newlines (used by (concat title (if prefix (concat " Starting With " - (key-description prefix))) + (help--key-description-fontified prefix))) ":\n")) "key binding\n" "--- -------\n"))) @@ -1228,7 +1235,11 @@ Return nil if the key sequence is too long." (= help--previous-description-column 32))) 32) (t 16)))) - (indent-to description-column 1) + ;; Avoid using the `help-keymap' face. + (let ((op (point))) + (indent-to description-column 1) + (set-text-properties op (point) '( face nil + font-lock-face nil))) (setq help--previous-description-column description-column) (cond ((symbolp definition) (insert (symbol-name definition) "\n")) @@ -1240,7 +1251,11 @@ Return nil if the key sequence is too long." (defun help--describe-translation (definition) ;; Converted from describe_translation in keymap.c. - (indent-to 16 1) + ;; Avoid using the `help-keymap' face. + (let ((op (point))) + (indent-to 16) + (set-text-properties op (point) '( face nil + font-lock-face nil))) (cond ((symbolp definition) (insert (symbol-name definition) "\n")) ((or (stringp definition) (vectorp definition)) @@ -1351,9 +1366,9 @@ TRANSL, PARTIAL, SHADOW, NOMENU, MENTION-SHADOW are as in (setq end (caar vect)))) ;; Now START .. END is the range to describe next. ;; Insert the string to describe the event START. - (insert (key-description (vector start) prefix)) + (insert (help--key-description-fontified (vector start) prefix)) (when (not (eq start end)) - (insert " .. " (key-description (vector end) prefix))) + (insert " .. " (help--key-description-fontified (vector end) prefix))) ;; Print a description of the definition of this character. ;; Called function will take care of spacing out far enough ;; for alignment purposes. @@ -1420,7 +1435,7 @@ TRANSL, PARTIAL, SHADOW, NOMENU, MENTION-SHADOW are as in ;; (setq first nil)) ;; (when (and prefix (> (length prefix) 0)) ;; (insert (format "%s" prefix))) -;; (insert (key-description (vector start-idx) prefix)) +;; (insert (help--key-description-fontified (vector start-idx) prefix)) ;; ;; Find all consecutive characters or rows that have the ;; ;; same definition. ;; (while (equal (keymap--get-keyelt (aref vector (1+ idx)) nil) @@ -1433,7 +1448,7 @@ TRANSL, PARTIAL, SHADOW, NOMENU, MENTION-SHADOW are as in ;; (insert " .. ") ;; (when (and prefix (> (length prefix) 0)) ;; (insert (format "%s" prefix))) -;; (insert (key-description (vector idx) prefix))) +;; (insert (help--key-description-fontified (vector idx) prefix))) ;; (if transl ;; (help--describe-translation definition) ;; (help--describe-command definition)) @@ -1924,6 +1939,8 @@ the suggested string to use instead. See (add-function :after command-error-function #'help-command-error-confusable-suggestions) +(define-obsolete-function-alias 'help-for-help-internal #'help-for-help "28.1") + (provide 'help) diff --git a/lisp/isearch.el b/lisp/isearch.el index e7926ac08c..943e24aa56 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -460,11 +460,11 @@ and doesn't remove full-buffer highlighting after a search." (make-help-screen isearch-help-for-help-internal (purecopy "Type a help option: [bkm] or ?") "You have typed %THIS-KEY%, the help character. Type a Help option: -\(Type \\\\[help-quit] to exit the Help command.) +\(Type \\\\[help-quit] to exit the Help command.) -b Display all Isearch key bindings. -k KEYS Display full documentation of Isearch key sequence. -m Display documentation of Isearch mode. +\\[isearch-describe-bindings] Display all Isearch key bindings. +\\[isearch-describe-key] KEYS Display full documentation of Isearch key sequence. +\\[isearch-describe-mode] Display documentation of Isearch mode. You can't type here other help keys available in the global help map, but outside of this help window when you type them in Isearch mode, diff --git a/lisp/tooltip.el b/lisp/tooltip.el index 8e00aa5c2a..af3b86bba7 100644 --- a/lisp/tooltip.el +++ b/lisp/tooltip.el @@ -248,7 +248,12 @@ in echo area." (setf (alist-get 'border-color params) fg)) (when (stringp bg) (setf (alist-get 'background-color params) bg)) - (x-show-tip (propertize text 'face 'tooltip) + ;; Use non-nil APPEND argument below to avoid overriding any + ;; faces used in our TEXT. Among other things, this allows + ;; tooltips to use the `help-key-binding' face used in + ;; `substitute-command-keys' substitutions. + (add-face-text-property 0 (length text) 'tooltip t text) + (x-show-tip text (selected-frame) params tooltip-hide-delay diff --git a/src/keymap.c b/src/keymap.c index 782931fadf..bb26b6389d 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -2846,6 +2846,21 @@ DESCRIBER is the output function used; nil means use `princ'. */) return unbind_to (count, Qnil); } +static Lisp_Object fontify_key_properties; + +static Lisp_Object +describe_key_maybe_fontify (Lisp_Object str, Lisp_Object prefix, + bool keymap_p) +{ + Lisp_Object key_desc = Fkey_description (str, prefix); + if (keymap_p) + Fadd_text_properties (make_fixnum (0), + make_fixnum (SCHARS (key_desc)), + fontify_key_properties, + key_desc); + return key_desc; +} + DEFUN ("help--describe-vector", Fhelp__describe_vector, Shelp__describe_vector, 7, 7, 0, doc: /* Insert in the current buffer a description of the contents of VECTOR. Call DESCRIBER to insert the description of one value found in VECTOR. @@ -3021,7 +3036,7 @@ describe_vector (Lisp_Object vector, Lisp_Object prefix, Lisp_Object args, if (!NILP (elt_prefix)) insert1 (elt_prefix); - insert1 (Fkey_description (kludge, prefix)); + insert1 (describe_key_maybe_fontify (kludge, prefix, keymap_p)); /* Find all consecutive characters or rows that have the same definition. But, if VECTOR is a char-table, we had better @@ -3071,7 +3086,7 @@ describe_vector (Lisp_Object vector, Lisp_Object prefix, Lisp_Object args, if (!NILP (elt_prefix)) insert1 (elt_prefix); - insert1 (Fkey_description (kludge, prefix)); + insert1 (describe_key_maybe_fontify (kludge, prefix, keymap_p)); } /* Print a description of the definition of this character. @@ -3200,6 +3215,12 @@ be preferred. */); staticpro (&where_is_cache); staticpro (&where_is_cache_keymaps); + DEFSYM (Qfont_lock_face, "font-lock-face"); + DEFSYM (Qhelp_key_binding, "help-key-binding"); + staticpro (&fontify_key_properties); + fontify_key_properties = Fcons (Qfont_lock_face, + Fcons (Qhelp_key_binding, Qnil)); + defsubr (&Skeymapp); defsubr (&Skeymap_parent); defsubr (&Skeymap_prompt); diff --git a/test/lisp/help-tests.el b/test/lisp/help-tests.el index 8034764741..b2fec5c1bd 100644 --- a/test/lisp/help-tests.el +++ b/test/lisp/help-tests.el @@ -26,6 +26,7 @@ (require 'ert) (eval-when-compile (require 'cl-lib)) +(require 'text-property-search) ; for `text-property-search-forward' (ert-deftest help-split-fundoc-SECTION () "Test new optional arg SECTION." @@ -60,9 +61,8 @@ (defmacro with-substitute-command-keys-test (&rest body) `(cl-flet* ((test (lambda (orig result) - (should (equal-including-properties - (substitute-command-keys orig) - result)))) + (should (equal (substitute-command-keys orig) + result)))) (test-re (lambda (orig regexp) (should (string-match (concat "^" regexp "$") @@ -222,6 +222,24 @@ M-s next-matching-history-element (define-minor-mode help-tests-minor-mode "Minor mode for testing shadowing.") +(ert-deftest help-tests-substitute-command-keys/add-key-face () + (should (equal (substitute-command-keys "\\[next-line]") + (propertize "C-n" + 'face 'help-key-binding + 'font-lock-face 'help-key-binding)))) + +(ert-deftest help-tests-substitute-command-keys/add-key-face-listing () + (with-temp-buffer + (insert (substitute-command-keys "\\{help-tests-minor-mode-map}")) + (goto-char (point-min)) + (text-property-search-forward 'face 'help-key-binding) + (should (looking-at "C-e")) + ;; Don't fontify trailing whitespace. + (should-not (get-text-property (+ (point) 3) 'face)) + (text-property-search-forward 'face 'help-key-binding) + (should (looking-at "x")) + (should-not (get-text-property (+ (point) 1) 'face)))) + (ert-deftest help-tests-substitute-command-keys/test-mode () (with-substitute-command-keys-test (with-temp-buffer commit 8e103ebef12bb723723c7e6ec8e1053e86878a5b Author: Dmitry Gutov Date: Mon Mar 8 04:25:15 2021 +0200 Speed up xref rendering for matches on very long lines * lisp/progmodes/xref.el (xref--insert-xrefs): Cut up the current line into pieces here for multiple matches's summaries, so that xref--insert-xrefs can do less work (bug#46859). (xref--insert-xrefs): Do less work. (xref--outdated-p): Update accordingly to how the summary creation logic changed. (xref--buf-pairs-iterator): Update to the new calling convention. (xref-location-column): Effectively rename back to xref-file-location-column since the generic version is now unused. * test/lisp/progmodes/xref-tests.el (xref-matches-in-directory-finds-two-matches-on-the-same-line) (xref-matches-in-directory-finds-an-empty-line-regexp-match): Adjust to the xref-location-column change. (xref-matches-in-files-trims-summary-for-matches-on-same-line): New test. * test/lisp/progmodes/xref-resources/file1.txt: Change contents slightly to test the new xref--outdated-p code. diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 18fdd963fb..af46365325 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -97,10 +97,6 @@ This is typically the filename.") "Return the line number corresponding to the location." nil) -(cl-defgeneric xref-location-column (_location) - "Return the exact column corresponding to the location." - nil) - (cl-defgeneric xref-match-length (_item) "Return the length of the match." nil) @@ -130,7 +126,7 @@ in its full absolute form." (defclass xref-file-location (xref-location) ((file :type string :initarg :file) (line :type fixnum :initarg :line :reader xref-location-line) - (column :type fixnum :initarg :column :reader xref-location-column)) + (column :type fixnum :initarg :column :reader xref-file-location-column)) :documentation "A file location is a file/line/column triple. Line numbers start from 1 and columns from 0.") @@ -713,10 +709,7 @@ references displayed in the current *xref* buffer." (push pair all-pairs) ;; Perform sanity check first. (xref--goto-location loc) - (if (xref--outdated-p item - (buffer-substring-no-properties - (line-beginning-position) - (line-end-position))) + (if (xref--outdated-p item) (message "Search result out of date, skipping") (cond ((null file-buf) @@ -733,18 +726,38 @@ references displayed in the current *xref* buffer." (move-marker (car pair) nil) (move-marker (cdr pair) nil))))))) -(defun xref--outdated-p (item line-text) - ;; FIXME: The check should probably be a generic function instead of - ;; the assumption that all matches contain the full line as summary. - (let ((summary (xref-item-summary item)) - (strip (lambda (s) (if (string-match "\r\\'" s) - (substring-no-properties s 0 -1) - s)))) +(defun xref--outdated-p (item) + "Check that the match location at current position is up-to-date. +ITEMS is an xref item which " + ;; FIXME: The check should most likely be a generic function instead + ;; of the assumption that all matches' summaries relate to the + ;; buffer text in a particular way. + (let* ((summary (xref-item-summary item)) + ;; Sometimes buffer contents include ^M, and sometimes Grep + ;; output includes it, and they don't always match. + (strip (lambda (s) (if (string-match "\r\\'" s) + (substring-no-properties s 0 -1) + s))) + (stripped-summary (funcall strip summary)) + (lendpos (line-end-position)) + (check (lambda () + (let ((comparison-end + (+ (point) (length stripped-summary)))) + (and (>= lendpos comparison-end) + (equal stripped-summary + (buffer-substring-no-properties + (point) comparison-end))))))) (not - ;; Sometimes buffer contents include ^M, and sometimes Grep - ;; output includes it, and they don't always match. - (equal (funcall strip line-text) - (funcall strip summary))))) + (or + ;; Either summary contains match text and after + ;; (2nd+ match on the line)... + (funcall check) + ;; ...or it starts at bol, includes the match and after. + (and (< (point) (+ (line-beginning-position) + (length stripped-summary))) + (save-excursion + (forward-line 0) + (funcall check))))))) ;; FIXME: Write a nicer UI. (defun xref--query-replace-1 (from to iter) @@ -886,30 +899,24 @@ GROUP is a string for decoration purposes and XREF is an (length (and line (format "%d" line))))) for line-format = (and max-line-width (format "%%%dd: " max-line-width)) - with prev-line-key = nil + with prev-group = nil + with prev-line = nil do (xref--insert-propertized '(face xref-file-header xref-group t) group "\n") (cl-loop for (xref . more2) on xrefs do (with-slots (summary location) xref (let* ((line (xref-location-line location)) - (new-summary summary) - (line-key (list (xref-location-group location) line)) (prefix - (if line - (propertize (format line-format line) - 'face 'xref-line-number) - " "))) + (cond + ((not line) " ") + ((equal line prev-line) "") + (t (propertize (format line-format line) + 'face 'xref-line-number))))) ;; Render multiple matches on the same line, together. - (when (and line (equal prev-line-key line-key)) - (when-let ((column (xref-location-column location))) - (delete-region - (save-excursion - (forward-line -1) - (move-to-column (+ (length prefix) column)) - (point)) - (point)) - (setq new-summary (substring summary column) prefix ""))) + (when (and (equal prev-group group) + (not (equal prev-line line))) + (insert "\n")) (xref--insert-propertized (list 'xref-item xref 'mouse-face 'highlight @@ -917,9 +924,10 @@ GROUP is a string for decoration purposes and XREF is an 'help-echo (concat "mouse-2: display in another window, " "RET or mouse-1: follow reference")) - prefix new-summary) - (setq prev-line-key line-key))) - (insert "\n")))) + prefix summary) + (setq prev-line line + prev-group group)))) + (insert "\n"))) (defun xref--analyze (xrefs) "Find common filenames in XREFS. @@ -1678,20 +1686,30 @@ Such as the current syntax table and the applied syntax properties." syntax-needed))))) (defun xref--collect-matches-1 (regexp file line line-beg line-end syntax-needed) - (let (matches) + (let (match-pairs matches) (when syntax-needed (syntax-propertize line-end)) - ;; FIXME: This results in several lines with the same - ;; summary. Solve with composite pattern? (while (and ;; REGEXP might match an empty string. Or line. - (or (null matches) + (or (null match-pairs) (> (point) line-beg)) (re-search-forward regexp line-end t)) - (let* ((beg-column (- (match-beginning 0) line-beg)) - (end-column (- (match-end 0) line-beg)) + (push (cons (match-beginning 0) + (match-end 0)) + match-pairs)) + (setq match-pairs (nreverse match-pairs)) + (while match-pairs + (let* ((beg-end (pop match-pairs)) + (beg-column (- (car beg-end) line-beg)) + (end-column (- (cdr beg-end) line-beg)) (loc (xref-make-file-location file line beg-column)) - (summary (buffer-substring line-beg line-end))) + (summary (buffer-substring (if matches (car beg-end) line-beg) + (if match-pairs + (caar match-pairs) + line-end)))) + (when matches + (cl-decf beg-column (- (car beg-end) line-beg)) + (cl-decf end-column (- (car beg-end) line-beg))) (add-face-text-property beg-column end-column 'xref-match t summary) (push (xref-make-match summary loc (- end-column beg-column)) diff --git a/test/lisp/progmodes/xref-resources/file1.txt b/test/lisp/progmodes/xref-resources/file1.txt index 5d7cc54444..85b92f1156 100644 --- a/test/lisp/progmodes/xref-resources/file1.txt +++ b/test/lisp/progmodes/xref-resources/file1.txt @@ -1,2 +1,2 @@ -foo foo + foo foo bar diff --git a/test/lisp/progmodes/xref-resources/file3.txt b/test/lisp/progmodes/xref-resources/file3.txt new file mode 100644 index 0000000000..6283185910 --- /dev/null +++ b/test/lisp/progmodes/xref-resources/file3.txt @@ -0,0 +1 @@ + match some words match more match ends here diff --git a/test/lisp/progmodes/xref-tests.el b/test/lisp/progmodes/xref-tests.el index 028c43db43..9982c32d41 100644 --- a/test/lisp/progmodes/xref-tests.el +++ b/test/lisp/progmodes/xref-tests.el @@ -59,15 +59,15 @@ (should (string-match-p "file1\\.txt\\'" (xref-location-group (nth 1 locs)))) (should (equal 1 (xref-location-line (nth 0 locs)))) (should (equal 1 (xref-location-line (nth 1 locs)))) - (should (equal 0 (xref-location-column (nth 0 locs)))) - (should (equal 4 (xref-location-column (nth 1 locs)))))) + (should (equal 1 (xref-file-location-column (nth 0 locs)))) + (should (equal 5 (xref-file-location-column (nth 1 locs)))))) (ert-deftest xref-matches-in-directory-finds-an-empty-line-regexp-match () (let ((locs (xref-tests--locations-in-data-dir "^$"))) (should (= 1 (length locs))) (should (string-match-p "file2\\.txt\\'" (xref-location-group (nth 0 locs)))) (should (equal 1 (xref-location-line (nth 0 locs)))) - (should (equal 0 (xref-location-column (nth 0 locs)))))) + (should (equal 0 (xref-file-location-column (nth 0 locs)))))) (ert-deftest xref-matches-in-files-includes-matches-from-all-the-files () (let ((matches (xref-matches-in-files "bar" @@ -78,6 +78,15 @@ (lambda (match) (equal (xref-item-summary match) "bar")) matches)))) +(ert-deftest xref-matches-in-files-trims-summary-for-matches-on-same-line () + (let ((matches (xref-matches-in-files "match" + (directory-files xref-tests--data-dir t + "\\`[^.]")))) + (should (= 3 (length matches))) + (should + (equal (mapcar #'xref-item-summary matches) + '(" match some words " "match more " "match ends here"))))) + (ert-deftest xref--buf-pairs-iterator-groups-markers-by-buffers-1 () (let* ((xrefs (xref-tests--matches-in-data-dir "foo")) (iter (xref--buf-pairs-iterator xrefs)) commit 05adcefa1f615a6e944322755ce35b75c0dfe24d Author: Dmitry Gutov Date: Mon Mar 8 02:44:24 2021 +0200 Xref test improvements * test/lisp/progmodes/xref-tests.el (xref--xref-file-name-display-is-abs): Fix not to rely on the default value. (xref-matches-in-files-includes-matches-from-all-the-files): New test. diff --git a/test/lisp/progmodes/xref-tests.el b/test/lisp/progmodes/xref-tests.el index b4b5e4db5d..028c43db43 100644 --- a/test/lisp/progmodes/xref-tests.el +++ b/test/lisp/progmodes/xref-tests.el @@ -69,6 +69,15 @@ (should (equal 1 (xref-location-line (nth 0 locs)))) (should (equal 0 (xref-location-column (nth 0 locs)))))) +(ert-deftest xref-matches-in-files-includes-matches-from-all-the-files () + (let ((matches (xref-matches-in-files "bar" + (directory-files xref-tests--data-dir t + "\\`[^.]")))) + (should (= 2 (length matches))) + (should (cl-every + (lambda (match) (equal (xref-item-summary match) "bar")) + matches)))) + (ert-deftest xref--buf-pairs-iterator-groups-markers-by-buffers-1 () (let* ((xrefs (xref-tests--matches-in-data-dir "foo")) (iter (xref--buf-pairs-iterator xrefs)) @@ -99,18 +108,18 @@ (should (null (marker-position (cdr (nth 0 (cdr cons2)))))))) (ert-deftest xref--xref-file-name-display-is-abs () - (let ((xref-file-name-display 'abs) - ;; Some older BSD find versions can produce '//' in the output. - (expected (list - (concat xref-tests--data-dir "/?file1.txt") - (concat xref-tests--data-dir "/?file2.txt"))) - (actual (delete-dups - (mapcar 'xref-location-group - (xref-tests--locations-in-data-dir "\\(bar\\|foo\\)"))))) - (should (and (= (length expected) (length actual)) - (cl-every (lambda (e1 e2) - (string-match-p e1 e2)) - expected actual))))) + (let* ((xref-file-name-display 'abs) + ;; Some older BSD find versions can produce '//' in the output. + (expected (list + (concat xref-tests--data-dir "/?file1.txt") + (concat xref-tests--data-dir "/?file2.txt"))) + (actual (delete-dups + (mapcar 'xref-location-group + (xref-tests--locations-in-data-dir "\\(bar\\|foo\\)"))))) + (should (= (length expected) (length actual))) + (should (cl-every (lambda (e1 e2) + (string-match-p e1 e2)) + expected actual)))) (ert-deftest xref--xref-file-name-display-is-nondirectory () (let ((xref-file-name-display 'nondirectory)) commit 7e1cfa29c3c3f4566c9f973fb1b0e6a28f3eaf59 Author: Stefan Monnier Date: Sun Mar 7 19:07:27 2021 -0500 * lisp/net/tramp-cache.el: Fix misuse of bound-and-true-p (tramp-get-file-property, tramp-set-file-property): Check the var's value rather than its name. diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index 2b0a4d9cd0..ad8310c5ea 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el @@ -164,7 +164,7 @@ Return DEFAULT if not set." file property value remote-file-name-inhibit-cache cache-used cached-at) (when (>= tramp-verbose 10) (let* ((var (intern (concat "tramp-cache-get-count-" property))) - (val (or (numberp (bound-and-true-p var)) + (val (or (numberp (and (boundp var) (symbol-value var))) (progn (add-hook 'tramp-cache-unload-hook (lambda () (makunbound var))) @@ -188,7 +188,7 @@ Return VALUE." (tramp-message key 8 "%s %s %s" file property value) (when (>= tramp-verbose 10) (let* ((var (intern (concat "tramp-cache-set-count-" property))) - (val (or (numberp (bound-and-true-p var)) + (val (or (numberp (and (boundp var) (symbol-value var))) (progn (add-hook 'tramp-cache-unload-hook (lambda () (makunbound var))) commit 490f8305e1901719dcd0e0d3561e37d66fddff18 Author: Stefan Monnier Date: Sun Mar 7 19:06:45 2021 -0500 * lisp/net/ange-ftp.el: Fix problem pointed out by compiler warning (ange-ftp-fix-name-for-bs2000): Remove redundant `boundp` test. diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el index fa13dd57d1..d27eeab82b 100644 --- a/lisp/net/ange-ftp.el +++ b/lisp/net/ange-ftp.el @@ -6111,8 +6111,7 @@ Other orders of $ and _ seem to all work just fine.") (1- (match-end 2))))) (filename (if (match-beginning 3) (substring name (match-beginning 3))))) - (if (and (boundp 'filename) - (stringp filename) + (if (and (stringp filename) (string-match "[#@].+" filename)) (setq filename (concat ange-ftp-bs2000-special-prefix (substring filename 1)))) commit fb779e98572fe1a7a37dd6feed3cf08ee4ea7244 Author: Stefan Monnier Date: Sun Mar 7 19:06:06 2021 -0500 * lisp/erc/erc.el: Fix problem pointed out by compiler warning [ Also use `read-string` instead of `read-from-minibuffer`. ] (erc-part-from-channel): Comment out improbable reference to the formal argument from within the interactive spec. diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 4d45ac29ba..939113acc5 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -2144,15 +2144,15 @@ parameters SERVER and NICK." (defun erc-select-read-args () "Prompt the user for values of nick, server, port, and password." (let (user-input server port nick passwd) - (setq user-input (read-from-minibuffer + (setq user-input (read-string "IRC server: " - (erc-compute-server) nil nil 'erc-server-history-list)) + (erc-compute-server) 'erc-server-history-list)) (if (string-match "\\(.*\\):\\(.*\\)\\'" user-input) (setq port (erc-string-to-port (match-string 2 user-input)) user-input (match-string 1 user-input)) (setq port - (erc-string-to-port (read-from-minibuffer + (erc-string-to-port (read-string "IRC port: " (erc-port-to-string (erc-compute-port)))))) @@ -2161,13 +2161,12 @@ parameters SERVER and NICK." user-input (match-string 2 user-input)) (setq nick (if (erc-already-logged-in server port nick) - (read-from-minibuffer + (read-string (erc-format-message 'nick-in-use ?n nick) - nick - nil nil 'erc-nick-history-list) - (read-from-minibuffer + nick 'erc-nick-history-list) + (read-string "Nickname: " (erc-compute-nick nick) - nil nil 'erc-nick-history-list)))) + 'erc-nick-history-list)))) (setq server user-input) @@ -2186,10 +2185,9 @@ parameters SERVER and NICK." ;; bnc with the same nick. actually it would be nice to have ;; bncs transparent, so that erc-compute-buffer-name displays ;; the server one is connected to. - (setq nick (read-from-minibuffer + (setq nick (read-string (erc-format-message 'nick-in-use ?n nick) - nick - nil nil 'erc-nick-history-list))) + nick 'erc-nick-history-list))) (list :server server :port port :nick nick :password passwd))) ;;;###autoload @@ -3511,7 +3509,7 @@ The type of query window/frame/etc will depend on the value of If USER is omitted, close the current query buffer if one exists - except this is broken now ;-)" (interactive - (list (read-from-minibuffer "Start a query with: " nil))) + (list (read-string "Start a query with: "))) (let ((session-buffer (erc-server-buffer)) (erc-join-buffer erc-query-display)) (if user @@ -4023,8 +4021,7 @@ If FACE is non-nil, it will be used to propertize the prompt. If it is nil, "Interactively input a user action and send it to IRC." (interactive "") (erc-set-active-buffer (current-buffer)) - (let ((action (read-from-minibuffer - "Action: " nil nil nil 'erc-action-history-list))) + (let ((action (read-string "Action: " nil 'erc-action-history-list))) (if (not (string-match "^\\s-*$" action)) (erc-send-action (erc-default-target) action)))) @@ -4041,24 +4038,25 @@ If `point' is at the beginning of a channel name, use that as default." (completing-read (format-prompt "Join channel" chnl) table nil nil nil nil chnl)) (when (or current-prefix-arg erc-prompt-for-channel-key) - (read-from-minibuffer "Channel key (RET for none): " nil)))) + (read-string "Channel key (RET for none): ")))) (erc-cmd-JOIN channel (when (>= (length key) 1) key))) (defun erc-part-from-channel (reason) "Part from the current channel and prompt for a REASON." (interactive + ;; FIXME: Has this ever worked? We're in the interactive-spec, so the + ;; argument `reason' can't be in scope yet! + ;;(if (and (boundp 'reason) (stringp reason) (not (string= reason ""))) + ;; reason (list - (if (and (boundp 'reason) (stringp reason) (not (string= reason ""))) - reason - (read-from-minibuffer (concat "Reason for leaving " (erc-default-target) - ": "))))) + (read-string (concat "Reason for leaving " (erc-default-target) ": ")))) (erc-cmd-PART (concat (erc-default-target)" " reason))) (defun erc-set-topic (topic) "Prompt for a TOPIC for the current channel." (interactive (list - (read-from-minibuffer + (read-string (concat "Set topic of " (erc-default-target) ": ") (when erc-channel-topic (let ((ss (split-string erc-channel-topic "\C-o"))) @@ -4070,7 +4068,7 @@ If `point' is at the beginning of a channel name, use that as default." (defun erc-set-channel-limit (&optional limit) "Set a LIMIT for the current channel. Remove limit if nil. Prompt for one if called interactively." - (interactive (list (read-from-minibuffer + (interactive (list (read-string (format "Limit for %s (RET to remove limit): " (erc-default-target))))) (let ((tgt (erc-default-target))) @@ -4081,7 +4079,7 @@ Prompt for one if called interactively." (defun erc-set-channel-key (&optional key) "Set a KEY for the current channel. Remove key if nil. Prompt for one if called interactively." - (interactive (list (read-from-minibuffer + (interactive (list (read-string (format "Key for %s (RET to remove key): " (erc-default-target))))) (let ((tgt (erc-default-target))) @@ -4092,7 +4090,7 @@ Prompt for one if called interactively." (defun erc-quit-server (reason) "Disconnect from current server after prompting for REASON. `erc-quit-reason' works with this just like with `erc-cmd-QUIT'." - (interactive (list (read-from-minibuffer + (interactive (list (read-string (format "Reason for quitting %s: " (or erc-server-announced-name erc-session-server))))) commit 42751f440dc46628ac09a522026f4ce41cada8d3 Author: Stefan Monnier Date: Sun Mar 7 19:05:02 2021 -0500 * lisp/cedet/semantic/fw.el (semantic-find-file-noselect): Fix warning Remove ugly hack trying to warn the user about some unknown problem, and which stopped working in 2013 when files.el started using lexical-binding. diff --git a/lisp/cedet/semantic/fw.el b/lisp/cedet/semantic/fw.el index 3c36c6cb9f..bdead99d68 100644 --- a/lisp/cedet/semantic/fw.el +++ b/lisp/cedet/semantic/fw.el @@ -322,17 +322,7 @@ calling this one." "Call `find-file-noselect' with various features turned off. Use this when referencing a file that will be soon deleted. FILE, NOWARN, RAWFILE, and WILDCARDS are passed into `find-file-noselect'." - ;; Hack - - ;; Check if we are in set-auto-mode, and if so, warn about this. - (when (boundp 'keep-mode-if-same) - (let ((filename (or (and (boundp 'filename) filename) - "(unknown)"))) - (message "WARNING: semantic-find-file-noselect called for \ -%s while in set-auto-mode for %s. You should call the responsible function \ -into `mode-local-init-hook'." file filename) - (sit-for 1))) - - (let* ((recentf-exclude '( (lambda (f) t) )) + (let* ((recentf-exclude #'always) ;; This is a brave statement. Don't waste time loading in ;; lots of modes. Especially decoration mode can waste a lot ;; of time for a buffer we intend to kill. commit c4f49d7609f63d6a8d7a57c7fc6cd14d9b0b9ab0 Author: Stefan Monnier Date: Sun Mar 7 19:04:18 2021 -0500 * lisp/skeleton.el (skeleton-read): Silence compiler warning diff --git a/lisp/skeleton.el b/lisp/skeleton.el index 8a50fbef64..c363fb2c48 100644 --- a/lisp/skeleton.el +++ b/lisp/skeleton.el @@ -290,7 +290,8 @@ i.e. we are handling the iterator of a subskeleton, returns empty string if user didn't modify input. While reading, the value of `minibuffer-help-form' is variable `help' if that is non-nil or a default string." - (let ((minibuffer-help-form (or (if (boundp 'help) (symbol-value 'help)) + (with-suppressed-warnings ((lexical help)) (defvar help)) ;FIXME: Prefix! + (let ((minibuffer-help-form (or (bound-and-true-p help) (if recursive "\ As long as you provide input you will insert another subskeleton. commit 26bfd0cdcf8bdf4569608227c527bebd755ef2e6 Author: Stefan Monnier Date: Sun Mar 7 19:03:36 2021 -0500 * lisp/cedet/semantic/bovine.el: Fix recent regression The conversion to `lexical-binding` introduced a regression because `bovine/c.el` relied on inspecting the local variable `lse` in one of its callers. (semantic-bovinate-stream): Bind `lse` dynamically, because of `semantic-parse-region-c-mode`. (semantic-bovinate-nonterminal-check-map): Rename from `semantic-bovinate-nonterminal-check-obarray` to hold some other kind of table. (semantic-bovinate-nonterminal-check): Use a hash-table instead of an obarray. * lisp/cedet/semantic/bovine/c.el (semantic-parse-region-c-mode): Declare use of `lse` via dynamic scoping. * test/lisp/cedet/semantic-utest-c.el (semantic-test-c-preprocessor-simulation): Re-enable test. diff --git a/lisp/cedet/semantic/bovine.el b/lisp/cedet/semantic/bovine.el index b585e387fe..6be6dfd8df 100644 --- a/lisp/cedet/semantic/bovine.el +++ b/lisp/cedet/semantic/bovine.el @@ -41,7 +41,7 @@ ;;; Variables ;; -(defvar-local semantic-bovinate-nonterminal-check-obarray nil +(defvar-local semantic-bovinate-nonterminal-check-map nil "Obarray of streams already parsed for nonterminal symbols. Use this to detect infinite recursion during a parse.") @@ -79,21 +79,18 @@ environment of `semantic-bovinate-stream'." (defun semantic-bovinate-nonterminal-check (stream nonterminal) "Check if STREAM not already parsed for NONTERMINAL. If so abort because an infinite recursive parse is suspected." - (or (vectorp semantic-bovinate-nonterminal-check-obarray) - (setq semantic-bovinate-nonterminal-check-obarray - (make-vector 13 nil))) - (let* ((nt (symbol-name nonterminal)) - (vs (symbol-value - (intern-soft - nt semantic-bovinate-nonterminal-check-obarray)))) + (or (hash-table-p semantic-bovinate-nonterminal-check-map) + (setq semantic-bovinate-nonterminal-check-map + (make-hash-table :test #'eq))) + (let* ((vs (gethash nonterminal semantic-bovinate-nonterminal-check-map))) (if (memq stream vs) ;; Always enter debugger to see the backtrace (let ((debug-on-signal t) (debug-on-error t)) - (setq semantic-bovinate-nonterminal-check-obarray nil) - (error "Infinite recursive parse suspected on %s" nt)) - (set (intern nt semantic-bovinate-nonterminal-check-obarray) - (cons stream vs))))) + (setq semantic-bovinate-nonterminal-check-map nil) + (error "Infinite recursive parse suspected on %s" nonterminal)) + (push stream + (gethash nonterminal semantic-bovinate-nonterminal-check-map))))) ;;;###autoload (defun semantic-bovinate-stream (stream &optional nonterminal) @@ -110,6 +107,9 @@ list of semantic tokens found." (or semantic--buffer-cache (semantic-bovinate-nonterminal-check stream nonterminal)) + ;; FIXME: `semantic-parse-region-c-mode' inspects `lse' to try and + ;; detect a recursive call (used with macroexpansion, to avoid inf-loops). + (with-suppressed-warnings ((lexical lse)) (defvar lse)) (let* ((table semantic--parse-table) (matchlist (cdr (assq nonterminal table))) (starting-stream stream) @@ -216,7 +216,8 @@ list of semantic tokens found." (setq cvl (cons (if (memq (semantic-lex-token-class lse) '(comment semantic-list)) - valdot val) cvl))) ;append unchecked value. + valdot val) + cvl))) ;append unchecked value. (setq end (semantic-lex-token-end lse)) ) (setq lte nil cvl nil)) ;No more matches, exit diff --git a/lisp/cedet/semantic/bovine/c.el b/lisp/cedet/semantic/bovine/c.el index 7be55ea9e1..5712f9b6df 100644 --- a/lisp/cedet/semantic/bovine/c.el +++ b/lisp/cedet/semantic/bovine/c.el @@ -819,7 +819,9 @@ MACRO expansion mode is handled through the nature of Emacs's non-lexical binding of variables. START, END, NONTERMINAL, DEPTH, and RETURNONERRORS are the same as for the parent." - (if (and (boundp 'lse) (or (/= start 1) (/= end (point-max)))) + ;; FIXME: We shouldn't depend on the internals of `semantic-bovinate-stream'. + (with-suppressed-warnings ((lexical lse)) (defvar lse)) + (if (and (boundp 'lse) (or (/= start (point-min)) (/= end (point-max)))) (let* ((last-lexical-token lse) (llt-class (semantic-lex-token-class last-lexical-token)) (llt-fakebits (car (cdr last-lexical-token))) diff --git a/test/lisp/cedet/semantic-utest-c.el b/test/lisp/cedet/semantic-utest-c.el index b881cdb93b..d08c79cad3 100644 --- a/test/lisp/cedet/semantic-utest-c.el +++ b/test/lisp/cedet/semantic-utest-c.el @@ -43,10 +43,9 @@ (defvar semantic-lex-c-nested-namespace-ignore-second) ;;; Code: -;;;###autoload (ert-deftest semantic-test-c-preprocessor-simulation () "Run parsing test for C from the test directory." - :tags '(:expensive-test :unstable) + :tags '(:expensive-test) (semantic-mode 1) (dolist (fp semantic-utest-c-comparisons) (let* ((semantic-lex-c-nested-namespace-ignore-second nil) commit 251dea693a4e5d1c33257ab3402734a8067049ec Author: Stefan Monnier Date: Sun Mar 7 19:00:47 2021 -0500 * lisp/emacs-lisp/bytecomp.el: Warn about unprefixed vars in `boundp` (byte-compile--check-prefixed-var): New fun, extracted from `byte-compile--declare-var`. (byte-compile--declare-var): Use it. (byte-compile-maybe-guarded): Use it as well. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 4e00fe6121..74eb5b0377 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2497,12 +2497,14 @@ list that represents a doc string reference. (put 'defvar 'byte-hunk-handler 'byte-compile-file-form-defvar) (put 'defconst 'byte-hunk-handler 'byte-compile-file-form-defvar) -(defun byte-compile--declare-var (sym) +(defun byte-compile--check-prefixed-var (sym) (when (and (symbolp sym) (not (string-match "[-*/:$]" (symbol-name sym))) (byte-compile-warning-enabled-p 'lexical sym)) - (byte-compile-warn "global/dynamic var `%s' lacks a prefix" - sym)) + (byte-compile-warn "global/dynamic var `%s' lacks a prefix" sym))) + +(defun byte-compile--declare-var (sym) + (byte-compile--check-prefixed-var sym) (when (memq sym byte-compile-lexical-variables) (setq byte-compile-lexical-variables (delq sym byte-compile-lexical-variables)) @@ -4184,9 +4186,15 @@ that suppresses all warnings during execution of BODY." byte-compile-unresolved-functions)) (bound-list (byte-compile-find-bound-condition ,condition '(boundp default-boundp local-variable-p))) + (new-bound-list + ;; (seq-difference byte-compile-bound-variables)) + (delq nil (mapcar (lambda (s) + (if (memq s byte-compile-bound-variables) nil s)) + bound-list))) ;; Maybe add to the bound list. (byte-compile-bound-variables - (append bound-list byte-compile-bound-variables))) + (append new-bound-list byte-compile-bound-variables))) + (mapc #'byte-compile--check-prefixed-var new-bound-list) (unwind-protect ;; If things not being bound at all is ok, so must them being ;; obsolete. Note that we add to the existing lists since Tramp commit c63d2ef59c511c1c48c69a202907b7edfcbb19b3 Author: Juri Linkov Date: Sun Mar 7 20:52:39 2021 +0200 Remove outline-cycle-minor-mode and outline-cycle-highlight-minor-mode * lisp/outline.el (outline-font-lock-keywords): Use OVERRIDE or LAXMATCH depending on outline-minor-mode-highlight in outline-minor-mode. (outline-minor-mode-cycle, outline-minor-mode-highlight): Promote defvar to defcustom. (outline-minor-mode-highlight-buffer): Don't override existing faces. (outline-cycle-minor-mode, outline-cycle-highlight-minor-mode): Remove minor modes. * etc/compilation.txt: * etc/grep.txt: Enable outline-minor-mode-cycle and outline-minor-mode-highlight with outline-minor-mode. https://lists.gnu.org/archive/html/emacs-devel/2021-03/msg00144.html diff --git a/etc/NEWS b/etc/NEWS index c4feabb511..cf21a7b0f1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -369,19 +369,18 @@ Typing 'TAB' on a heading line cycles the current section between anywhere in the buffer cycles the whole buffer between "only top-level headings", "all headings and subheadings", and "show all" states. -*** New minor mode 'outline-cycle-minor-mode'. -This mode is a variant of 'outline-minor-mode', with the difference +*** New option 'outline-minor-mode-cycle'. +This option customizes 'outline-minor-mode', with the difference that 'TAB' and 'S-TAB' on heading lines cycle heading visibility. Typing 'TAB' on a heading line cycles the current section between "hide all", "subheadings", and "show all" states. Typing 'S-TAB' on a heading line cycles the whole buffer between "only top-level headings", "all headings and subheadings", and "show all" states. -*** New minor mode 'outline-cycle-highlight-minor-mode'. -This mode is a variant of 'outline-cycle-minor-mode'. It puts -highlighting on heading lines using standard outline faces. This -works well only when there are no conflicts with faces used by the -major mode. +*** New option 'outline-minor-mode-highlight'. +This option customizes 'outline-minor-mode'. It puts highlighting +on heading lines using standard outline faces. This works well only +when there are no conflicts with faces used by the major mode. * Changes in Specialized Modes and Packages in Emacs 28.1 diff --git a/etc/compilation.txt b/etc/compilation.txt index 05c04649be..01d4df1b09 100644 --- a/etc/compilation.txt +++ b/etc/compilation.txt @@ -696,5 +696,7 @@ COPYING PERMISSIONS: ;;; Local Variables: ;;; outline-regexp: "\\*\\_>" -;;; eval: (outline-cycle-highlight-minor-mode) +;;; outline-minor-mode-cycle: t +;;; outline-minor-mode-highlight: t +;;; eval: (outline-minor-mode 1) ;;; End: diff --git a/etc/grep.txt b/etc/grep.txt index a54ebf8a3b..0370ae4e2c 100644 --- a/etc/grep.txt +++ b/etc/grep.txt @@ -125,5 +125,7 @@ COPYING PERMISSIONS: ;;; Local Variables: ;;; eval: (let ((inhibit-read-only t) (compilation-filter-start (point-min))) (save-excursion (goto-char (point-max)) (grep-filter) (set-buffer-modified-p nil))) ;;; buffer-read-only: t -;;; eval: (outline-cycle-highlight-minor-mode) +;;; outline-minor-mode-cycle: t +;;; outline-minor-mode-highlight: t +;;; eval: (outline-minor-mode 1) ;;; End: diff --git a/lisp/outline.el b/lisp/outline.el index 640c0e06b9..a859f9ac8f 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -186,7 +186,7 @@ in the file it applies to.") (define-key map (kbd "TAB") tab-binding) (define-key map (kbd "") #'outline-cycle-buffer)) map) - "Keymap used by `outline-mode-map' and `outline-cycle-minor-mode'.") + "Keymap used by `outline-mode-map' and `outline-minor-mode-cycle'.") (defvar outline-mode-map (let ((map (make-sparse-keymap))) @@ -199,16 +199,19 @@ in the file it applies to.") '( ;; Highlight headings according to the level. (eval . (list (concat "^\\(?:" outline-regexp "\\).+") - 0 '(if outline-minor-mode-cycle - (if outline-minor-mode-highlight - (list 'face (outline-font-lock-face) - 'keymap outline-mode-cycle-map) - (list 'face nil - 'keymap outline-mode-cycle-map)) + 0 '(if outline-minor-mode + (if outline-minor-mode-cycle + (if outline-minor-mode-highlight + (list 'face (outline-font-lock-face) + 'keymap outline-mode-cycle-map) + (list 'face nil + 'keymap outline-mode-cycle-map))) (outline-font-lock-face)) - nil - (if (or outline-minor-mode-cycle - outline-minor-mode-highlight) + (when (and outline-minor-mode + (eq outline-minor-mode-highlight 'override)) + 'append) + (if (and outline-minor-mode + (eq outline-minor-mode-highlight t)) 'append t)))) "Additional expressions to highlight in Outline mode.") @@ -324,18 +327,28 @@ After that, changing the prefix key requires manipulating keymaps." (define-key outline-minor-mode-map val outline-mode-prefix-map) (set-default sym val))) -(defvar outline-minor-mode-cycle nil +(defcustom outline-minor-mode-cycle nil "Enable cycling of headings in `outline-minor-mode'. +When enabled, it puts a keymap with cycling keys on heading lines. When point is on a heading line, then typing `TAB' cycles between `hide all', `headings only' and `show all' (`outline-cycle'). Typing `S-TAB' on a heading line cycles the whole buffer (`outline-cycle-buffer'). -Typing these keys anywhere outside heading lines uses their default bindings.") +Typing these keys anywhere outside heading lines uses their default bindings." + :type 'boolean + :version "28.1") ;;;###autoload(put 'outline-minor-mode-cycle 'safe-local-variable 'booleanp) -(defvar outline-minor-mode-highlight nil +(defcustom outline-minor-mode-highlight nil "Highlight headings in `outline-minor-mode' using font-lock keywords. Non-nil value works well only when outline font-lock keywords -don't conflict with the major mode's font-lock keywords.") +don't conflict with the major mode's font-lock keywords. +When t, it puts outline faces only if there are no major mode's faces +on headings. When `override', it tries to append outline faces +to major mode's faces." + :type '(choice (const :tag "No highlighting" nil) + (const :tag "Append to major mode faces" override) + (const :tag "Highlight separately from major mode faces" t)) + :version "28.1") ;;;###autoload(put 'outline-minor-mode-highlight 'safe-local-variable 'booleanp) (defun outline-minor-mode-highlight-buffer () @@ -347,7 +360,9 @@ don't conflict with the major mode's font-lock keywords.") (let ((overlay (make-overlay (match-beginning 0) (match-end 0)))) (overlay-put overlay 'outline-overlay t) - (when outline-minor-mode-highlight + (when (or (eq outline-minor-mode-highlight 'override) + (and (eq outline-minor-mode-highlight t) + (not (get-text-property (point) 'face)))) (overlay-put overlay 'face (outline-font-lock-face))) (when outline-minor-mode-cycle (overlay-put overlay 'keymap outline-mode-cycle-map))) @@ -386,32 +401,6 @@ See the command `outline-mode' for more information on this mode." ;; When turning off outline mode, get rid of any outline hiding. (outline-show-all))) -;;;###autoload -(define-minor-mode outline-cycle-minor-mode - "Toggle Outline-Cycle minor mode. -Set the buffer-local variable `outline-minor-mode-cycle' to t -and enable `outline-minor-mode'." - nil nil nil - (if outline-cycle-minor-mode - (progn - (setq-local outline-minor-mode-cycle t) - (outline-minor-mode +1)) - (outline-minor-mode -1) - (kill-local-variable 'outline-minor-mode-cycle))) - -;;;###autoload -(define-minor-mode outline-cycle-highlight-minor-mode - "Toggle Outline-Cycle-Highlight minor mode. -Set the buffer-local variable `outline-minor-mode-highlight' to t -and enable `outline-cycle-minor-mode'." - nil nil nil - (if outline-cycle-highlight-minor-mode - (progn - (setq-local outline-minor-mode-highlight t) - (outline-cycle-minor-mode +1)) - (outline-cycle-minor-mode -1) - (kill-local-variable 'outline-minor-mode-highlight))) - (defvar-local outline-heading-alist () "Alist associating a heading for every possible level. Each entry is of the form (HEADING . LEVEL). commit c1f4a16cf3d71aa3f67c1c209e7060dc71afc545 Author: Michael Albinus Date: Sun Mar 7 18:55:44 2021 +0100 * test/infra/Dockerfile.emba: Install texinfo. diff --git a/test/infra/Dockerfile.emba b/test/infra/Dockerfile.emba index 63a48b4ef6..cde657aada 100644 --- a/test/infra/Dockerfile.emba +++ b/test/infra/Dockerfile.emba @@ -28,7 +28,7 @@ FROM debian:stretch as emacs-base RUN apt-get update && \ apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 \ - libc-dev gcc g++ make autoconf automake libncurses-dev gnutls-dev git \ + libc-dev gcc g++ make autoconf automake libncurses-dev gnutls-dev git texinfo \ && rm -rf /var/lib/apt/lists/* FROM emacs-base as emacs-inotify @@ -39,11 +39,10 @@ RUN apt-get update && \ COPY . /checkout WORKDIR /checkout -RUN mkdir info && touch info/emacs RUN ./autogen.sh autoconf RUN ./configure RUN make -j4 bootstrap -RUN make -j4 lisp +RUN make -j4 FROM emacs-base as emacs-filenotify-gio @@ -53,11 +52,10 @@ RUN apt-get update && \ COPY . /checkout WORKDIR /checkout -RUN mkdir info && touch info/emacs RUN ./autogen.sh autoconf RUN ./configure --with-file-notification=gfile RUN make -j4 bootstrap -RUN make -j4 lisp +RUN make -j4 FROM emacs-base as emacs-gnustep @@ -67,8 +65,7 @@ RUN apt-get update && \ COPY . /checkout WORKDIR /checkout -RUN mkdir info && touch info/emacs RUN ./autogen.sh autoconf RUN ./configure --with-ns RUN make -j4 bootstrap -RUN make -j4 lisp +RUN make -j4 commit d4d92464119c38c8b87b2a10fa1999fe230c51f7 Author: Glenn Morris Date: Sun Mar 7 09:27:27 2021 -0800 Tag a semantic test that seems to hang recently * test/lisp/cedet/semantic-utest-c.el (semantic-test-c-preprocessor-simulation): Mark as unstable. diff --git a/test/lisp/cedet/semantic-utest-c.el b/test/lisp/cedet/semantic-utest-c.el index a7cbe116c2..b881cdb93b 100644 --- a/test/lisp/cedet/semantic-utest-c.el +++ b/test/lisp/cedet/semantic-utest-c.el @@ -46,7 +46,7 @@ ;;;###autoload (ert-deftest semantic-test-c-preprocessor-simulation () "Run parsing test for C from the test directory." - :tags '(:expensive-test) + :tags '(:expensive-test :unstable) (semantic-mode 1) (dolist (fp semantic-utest-c-comparisons) (let* ((semantic-lex-c-nested-namespace-ignore-second nil) commit 8558ecd65fc1c87345353f6352299df04280e729 Author: Basil L. Contovounesios Date: Sun Mar 7 14:55:15 2021 +0000 Fix string-replace error data * lisp/subr.el (string-replace): Signal an error with data that is a list, and whose contents are consistent with other uses of wrong-length-argument. * test/lisp/subr-tests.el (string-replace): Test for this. (subr-test-define-prefix-command): Pacify byte-compiler warnings. diff --git a/lisp/subr.el b/lisp/subr.el index 0b56347399..77bc7a33b3 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4784,7 +4784,7 @@ Unless optional argument INPLACE is non-nil, return a new string." "Replace FROMSTRING with TOSTRING in INSTRING each time it occurs." (declare (pure t) (side-effect-free t)) (when (equal fromstring "") - (signal 'wrong-length-argument fromstring)) + (signal 'wrong-length-argument '(0))) (let ((start 0) (result nil) pos) diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index fc5a1eba6d..7a116aa129 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -78,10 +78,14 @@ (ert-deftest subr-test-define-prefix-command () (define-prefix-command 'foo-prefix-map) + (defvar foo-prefix-map) + (declare-function foo-prefix-map "subr-tests") (should (keymapp foo-prefix-map)) (should (fboundp #'foo-prefix-map)) ;; With optional argument. (define-prefix-command 'bar-prefix 'bar-prefix-map) + (defvar bar-prefix-map) + (declare-function bar-prefix "subr-tests") (should (keymapp bar-prefix-map)) (should (fboundp #'bar-prefix)) ;; Returns the symbol. @@ -531,7 +535,8 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350." (should (equal (string-replace "a" "aa" "aaa") "aaaaaa")) (should (equal (string-replace "abc" "defg" "abc") "defg")) - (should-error (string-replace "" "x" "abc"))) + (should (equal (should-error (string-replace "" "x" "abc")) + '(wrong-length-argument 0)))) (ert-deftest subr-replace-regexp-in-string () (should (equal (replace-regexp-in-string "a+" "xy" "abaabbabaaba") commit 564b6391f809b3fe0807825b219f2534f2196630 Author: Michael Albinus Date: Sun Mar 7 11:43:27 2021 +0100 ; * test/infra/Dockerfile.emba: Fix last change. diff --git a/test/infra/Dockerfile.emba b/test/infra/Dockerfile.emba index 4294a3ce62..63a48b4ef6 100644 --- a/test/infra/Dockerfile.emba +++ b/test/infra/Dockerfile.emba @@ -39,7 +39,7 @@ RUN apt-get update && \ COPY . /checkout WORKDIR /checkout -RUN touch info/emacs +RUN mkdir info && touch info/emacs RUN ./autogen.sh autoconf RUN ./configure RUN make -j4 bootstrap @@ -53,7 +53,7 @@ RUN apt-get update && \ COPY . /checkout WORKDIR /checkout -RUN touch info/emacs +RUN mkdir info && touch info/emacs RUN ./autogen.sh autoconf RUN ./configure --with-file-notification=gfile RUN make -j4 bootstrap @@ -67,7 +67,7 @@ RUN apt-get update && \ COPY . /checkout WORKDIR /checkout -RUN touch info/emacs +RUN mkdir info && touch info/emacs RUN ./autogen.sh autoconf RUN ./configure --with-ns RUN make -j4 bootstrap commit 30489f4264d338b20af5f8261b190c23b4d55ff4 Author: Michael Albinus Date: Sun Mar 7 11:36:38 2021 +0100 * test/infra/Dockerfile.emba: Touch "info/emacs". diff --git a/test/infra/Dockerfile.emba b/test/infra/Dockerfile.emba index be684d672a..4294a3ce62 100644 --- a/test/infra/Dockerfile.emba +++ b/test/infra/Dockerfile.emba @@ -39,6 +39,7 @@ RUN apt-get update && \ COPY . /checkout WORKDIR /checkout +RUN touch info/emacs RUN ./autogen.sh autoconf RUN ./configure RUN make -j4 bootstrap @@ -52,6 +53,7 @@ RUN apt-get update && \ COPY . /checkout WORKDIR /checkout +RUN touch info/emacs RUN ./autogen.sh autoconf RUN ./configure --with-file-notification=gfile RUN make -j4 bootstrap @@ -65,6 +67,7 @@ RUN apt-get update && \ COPY . /checkout WORKDIR /checkout +RUN touch info/emacs RUN ./autogen.sh autoconf RUN ./configure --with-ns RUN make -j4 bootstrap commit 83fa649e02367baa88bb31ddc2c75c75fb0b0599 Author: Michael Albinus Date: Sun Mar 7 10:44:12 2021 +0100 Adapt Dockerfile.emba according to recent configure changes * test/infra/Dockerfile.emba: Remove "--without-makeinfo" from configure. Add "lisp" to make. diff --git a/test/infra/Dockerfile.emba b/test/infra/Dockerfile.emba index 421264db9c..be684d672a 100644 --- a/test/infra/Dockerfile.emba +++ b/test/infra/Dockerfile.emba @@ -40,9 +40,9 @@ RUN apt-get update && \ COPY . /checkout WORKDIR /checkout RUN ./autogen.sh autoconf -RUN ./configure --without-makeinfo +RUN ./configure RUN make -j4 bootstrap -RUN make -j4 +RUN make -j4 lisp FROM emacs-base as emacs-filenotify-gio @@ -53,9 +53,9 @@ RUN apt-get update && \ COPY . /checkout WORKDIR /checkout RUN ./autogen.sh autoconf -RUN ./configure --without-makeinfo --with-file-notification=gfile -RUN make bootstrap -RUN make -j4 +RUN ./configure --with-file-notification=gfile +RUN make -j4 bootstrap +RUN make -j4 lisp FROM emacs-base as emacs-gnustep @@ -66,6 +66,6 @@ RUN apt-get update && \ COPY . /checkout WORKDIR /checkout RUN ./autogen.sh autoconf -RUN ./configure --without-makeinfo --with-ns -RUN make bootstrap -RUN make -j4 +RUN ./configure --with-ns +RUN make -j4 bootstrap +RUN make -j4 lisp commit 468bb5ab7f949441f68c4133fcd5292dfbbfd83d Author: Stefan Monnier Date: Sun Mar 7 01:58:16 2021 -0500 * lisp/cedet/semantic/wisent: Use lexical-binding * lisp/cedet/semantic/wisent/comp.el: lexical-binding. (wisent-defcontext): Make sure the vars are also dynbound in the files that `require` us. (wisent-state-actions, wisent-automaton-lisp-form): Use `obarray-make`. (wisent--compile-grammar): Rename from `wisent-compile-grammar`. (wisent-compile-grammar): Redefine as an obsolete function. (wisent-automaton-lisp-form): Avoid variable `state`. * lisp/cedet/semantic/grammar.el: Use lexical-binding. (semantic-grammar-require-form): New var. (semantic-grammar-header): Use it to provide new element `require-form`. (semantic-grammar-header-template): Use it. * lisp/cedet/semantic/wisent.el (wisent-compiled-grammar): New macro. * lisp/cedet/semantic/wisent/grammar.el (wisent-grammar-parsetable-builder): Use it in the generated code instead of the `wisent-compile-grammar` function. (wisent-grammar-mode): Set `semantic-grammar-require-form` so the generated ELisp files require `semantic/wisent` rather than `semantic/bovine`. * lisp/cedet/semantic/wisent/wisent.el: Use lexical-binding. * lisp/cedet/semantic/wisent/java-tags.el: Use lexical-binding. * lisp/cedet/semantic/wisent/python.el: Use lexical-binding. * lisp/cedet/semantic/wisent/javascript.el: Use lexical-binding. (semantic-ctxt-current-symbol): Remove unused var `symlist`. * admin/grammars/python.wy (wisent-python-EXPANDING-block): Declare dynbound var. * lisp/cedet/semantic/grammar-wy.el: Regenerate. diff --git a/admin/grammars/grammar.wy b/admin/grammars/grammar.wy index 054e85bf70..35fb7e832e 100644 --- a/admin/grammars/grammar.wy +++ b/admin/grammars/grammar.wy @@ -128,7 +128,7 @@ epilogue: ;; declaration: decl - (eval $1) + (eval $1 t) ; decl: @@ -206,7 +206,7 @@ put_decl: put_name_list: BRACE_BLOCK - (mapcar 'semantic-tag-name (EXPANDFULL $1 put_names)) + (mapcar #'semantic-tag-name (EXPANDFULL $1 put_names)) ; put_names: @@ -226,7 +226,7 @@ put_name: put_value_list: BRACE_BLOCK - (mapcar 'semantic-tag-code-detail (EXPANDFULL $1 put_values)) + (mapcar #'semantic-tag-code-detail (EXPANDFULL $1 put_values)) ; put_values: @@ -300,7 +300,7 @@ plist: use_name_list: BRACE_BLOCK - (mapcar 'semantic-tag-name (EXPANDFULL $1 use_names)) + (mapcar #'semantic-tag-name (EXPANDFULL $1 use_names)) ; use_names: @@ -356,7 +356,7 @@ nonterminal: rules: lifo_rules - (apply 'nconc (nreverse $1)) + (apply #'nconc (nreverse $1)) ; lifo_rules: diff --git a/admin/grammars/python.wy b/admin/grammars/python.wy index 9c8f4ac6a9..22e85570dc 100644 --- a/admin/grammars/python.wy +++ b/admin/grammars/python.wy @@ -97,6 +97,7 @@ (tag)) (declare-function semantic-parse-region "semantic" (start end &optional nonterminal depth returnonerror)) +(defvar wisent-python-EXPANDING-block) } %languagemode python-mode @@ -871,7 +872,7 @@ paren_class_list_opt paren_class_list : PAREN_BLOCK (let ((wisent-python-EXPANDING-block t)) - (mapcar 'semantic-tag-name (EXPANDFULL $1 paren_classes))) + (mapcar #'semantic-tag-name (EXPANDFULL $1 paren_classes))) ; ;; parameters: '(' [varargslist] ')' diff --git a/lisp/cedet/semantic/grammar-wy.el b/lisp/cedet/semantic/grammar-wy.el index 9a7f393072..b301403437 100644 --- a/lisp/cedet/semantic/grammar-wy.el +++ b/lisp/cedet/semantic/grammar-wy.el @@ -24,7 +24,7 @@ ;;; Code: (require 'semantic/lex) -(eval-when-compile (require 'semantic/bovine)) +(require 'semantic/wisent) ;;; Prologue ;; @@ -112,315 +112,312 @@ "Table of lexical tokens.") (defconst semantic-grammar-wy--parse-table - (progn - (eval-when-compile - (require 'semantic/wisent/comp)) - (wisent-compile-grammar - '((DEFAULT-PREC NO-DEFAULT-PREC KEYWORD LANGUAGEMODE LEFT NONASSOC PACKAGE EXPECTEDCONFLICTS PROVIDE PREC PUT QUOTEMODE RIGHT SCOPESTART START TOKEN TYPE USE-MACROS STRING SYMBOL PERCENT_PERCENT CHARACTER PREFIXED_LIST SEXP PROLOGUE EPILOGUE PAREN_BLOCK BRACE_BLOCK LPAREN RPAREN LBRACE RBRACE COLON SEMI OR LT GT) - nil - (grammar - ((prologue)) - ((epilogue)) - ((declaration)) - ((nonterminal)) - ((PERCENT_PERCENT))) - (prologue - ((PROLOGUE) + (wisent-compiled-grammar + ((DEFAULT-PREC NO-DEFAULT-PREC KEYWORD LANGUAGEMODE LEFT NONASSOC PACKAGE EXPECTEDCONFLICTS PROVIDE PREC PUT QUOTEMODE RIGHT SCOPESTART START TOKEN TYPE USE-MACROS STRING SYMBOL PERCENT_PERCENT CHARACTER PREFIXED_LIST SEXP PROLOGUE EPILOGUE PAREN_BLOCK BRACE_BLOCK LPAREN RPAREN LBRACE RBRACE COLON SEMI OR LT GT) + nil + (grammar + ((prologue)) + ((epilogue)) + ((declaration)) + ((nonterminal)) + ((PERCENT_PERCENT))) + (prologue + ((PROLOGUE) + (wisent-raw-tag + (semantic-tag-new-code "prologue" nil)))) + (epilogue + ((EPILOGUE) + (wisent-raw-tag + (semantic-tag-new-code "epilogue" nil)))) + (declaration + ((decl) + (eval $1 t))) + (decl + ((default_prec_decl)) + ((no_default_prec_decl)) + ((languagemode_decl)) + ((package_decl)) + ((expectedconflicts_decl)) + ((provide_decl)) + ((precedence_decl)) + ((put_decl)) + ((quotemode_decl)) + ((scopestart_decl)) + ((start_decl)) + ((keyword_decl)) + ((token_decl)) + ((type_decl)) + ((use_macros_decl))) + (default_prec_decl + ((DEFAULT-PREC) + `(wisent-raw-tag + (semantic-tag "default-prec" 'assoc :value + '("t"))))) + (no_default_prec_decl + ((NO-DEFAULT-PREC) + `(wisent-raw-tag + (semantic-tag "default-prec" 'assoc :value + '("nil"))))) + (languagemode_decl + ((LANGUAGEMODE symbols) + `(wisent-raw-tag + (semantic-tag ',(car $2) + 'languagemode :rest ',(cdr $2))))) + (package_decl + ((PACKAGE SYMBOL) + `(wisent-raw-tag + (semantic-tag-new-package ',$2 nil)))) + (expectedconflicts_decl + ((EXPECTEDCONFLICTS symbols) + `(wisent-raw-tag + (semantic-tag ',(car $2) + 'expectedconflicts :rest ',(cdr $2))))) + (provide_decl + ((PROVIDE SYMBOL) + `(wisent-raw-tag + (semantic-tag ',$2 'provide)))) + (precedence_decl + ((associativity token_type_opt items) + `(wisent-raw-tag + (semantic-tag ',$1 'assoc :type ',$2 :value ',$3)))) + (associativity + ((LEFT) + (progn "left")) + ((RIGHT) + (progn "right")) + ((NONASSOC) + (progn "nonassoc"))) + (put_decl + ((PUT put_name put_value) + `(wisent-raw-tag + (semantic-tag ',$2 'put :value ',(list $3)))) + ((PUT put_name put_value_list) + `(wisent-raw-tag + (semantic-tag ',$2 'put :value ',$3))) + ((PUT put_name_list put_value) + `(wisent-raw-tag + (semantic-tag ',(car $2) + 'put :rest ',(cdr $2) + :value ',(list $3)))) + ((PUT put_name_list put_value_list) + `(wisent-raw-tag + (semantic-tag ',(car $2) + 'put :rest ',(cdr $2) + :value ',$3)))) + (put_name_list + ((BRACE_BLOCK) + (mapcar #'semantic-tag-name + (semantic-parse-region + (car $region1) + (cdr $region1) + 'put_names 1)))) + (put_names + ((LBRACE) + nil) + ((RBRACE) + nil) + ((put_name) + (wisent-raw-tag + (semantic-tag $1 'put-name)))) + (put_name + ((SYMBOL)) + ((token_type))) + (put_value_list + ((BRACE_BLOCK) + (mapcar #'semantic-tag-code-detail + (semantic-parse-region + (car $region1) + (cdr $region1) + 'put_values 1)))) + (put_values + ((LBRACE) + nil) + ((RBRACE) + nil) + ((put_value) + (wisent-raw-tag + (semantic-tag-new-code "put-value" $1)))) + (put_value + ((SYMBOL any_value) + (cons $1 $2))) + (scopestart_decl + ((SCOPESTART SYMBOL) + `(wisent-raw-tag + (semantic-tag ',$2 'scopestart)))) + (quotemode_decl + ((QUOTEMODE SYMBOL) + `(wisent-raw-tag + (semantic-tag ',$2 'quotemode)))) + (start_decl + ((START symbols) + `(wisent-raw-tag + (semantic-tag ',(car $2) + 'start :rest ',(cdr $2))))) + (keyword_decl + ((KEYWORD SYMBOL string_value) + `(wisent-raw-tag + (semantic-tag ',$2 'keyword :value ',$3)))) + (token_decl + ((TOKEN token_type_opt SYMBOL string_value) + `(wisent-raw-tag + (semantic-tag ',$3 ',(if $2 'token 'keyword) + :type ',$2 :value ',$4))) + ((TOKEN token_type_opt symbols) + `(wisent-raw-tag + (semantic-tag ',(car $3) + 'token :type ',$2 :rest ',(cdr $3))))) + (token_type_opt + (nil) + ((token_type))) + (token_type + ((LT SYMBOL GT) + (progn $2))) + (type_decl + ((TYPE token_type plist_opt) + `(wisent-raw-tag + (semantic-tag ',$2 'type :value ',$3)))) + (plist_opt + (nil) + ((plist))) + (plist + ((plist put_value) + (append + (list $2) + $1)) + ((put_value) + (list $1))) + (use_name_list + ((BRACE_BLOCK) + (mapcar #'semantic-tag-name + (semantic-parse-region + (car $region1) + (cdr $region1) + 'use_names 1)))) + (use_names + ((LBRACE) + nil) + ((RBRACE) + nil) + ((SYMBOL) + (wisent-raw-tag + (semantic-tag $1 'use-name)))) + (use_macros_decl + ((USE-MACROS SYMBOL use_name_list) + `(wisent-raw-tag + (semantic-tag "macro" 'macro :type ',$2 :value ',$3)))) + (string_value + ((STRING) + (read $1))) + (any_value + ((SYMBOL)) + ((STRING)) + ((PAREN_BLOCK)) + ((PREFIXED_LIST)) + ((SEXP))) + (symbols + ((lifo_symbols) + (nreverse $1))) + (lifo_symbols + ((lifo_symbols SYMBOL) + (cons $2 $1)) + ((SYMBOL) + (list $1))) + (nonterminal + ((SYMBOL + (setq semantic-grammar-wy--nterm $1 semantic-grammar-wy--rindx 0) + COLON rules SEMI) + (wisent-raw-tag + (semantic-tag $1 'nonterminal :children $4)))) + (rules + ((lifo_rules) + (apply #'nconc + (nreverse $1)))) + (lifo_rules + ((lifo_rules OR rule) + (cons $3 $1)) + ((rule) + (list $1))) + (rule + ((rhs) + (let* + ((nterm semantic-grammar-wy--nterm) + (rindx semantic-grammar-wy--rindx) + (rhs $1) + comps prec action elt) + (setq semantic-grammar-wy--rindx + (1+ semantic-grammar-wy--rindx)) + (while rhs + (setq elt + (car rhs) + rhs + (cdr rhs)) + (cond + ((vectorp elt) + (if prec + (error "Duplicate %%prec in `%s:%d' rule" nterm rindx)) + (setq prec + (aref elt 0))) + ((consp elt) + (if + (or action comps) + (setq comps + (cons elt comps) + semantic-grammar-wy--rindx + (1+ semantic-grammar-wy--rindx)) + (setq action + (car elt)))) + (t + (setq comps + (cons elt comps))))) + (wisent-cook-tag (wisent-raw-tag - (semantic-tag-new-code "prologue" nil)))) - (epilogue - ((EPILOGUE) - (wisent-raw-tag - (semantic-tag-new-code "epilogue" nil)))) - (declaration - ((decl) - (eval $1))) - (decl - ((default_prec_decl)) - ((no_default_prec_decl)) - ((languagemode_decl)) - ((package_decl)) - ((expectedconflicts_decl)) - ((provide_decl)) - ((precedence_decl)) - ((put_decl)) - ((quotemode_decl)) - ((scopestart_decl)) - ((start_decl)) - ((keyword_decl)) - ((token_decl)) - ((type_decl)) - ((use_macros_decl))) - (default_prec_decl - ((DEFAULT-PREC) - `(wisent-raw-tag - (semantic-tag "default-prec" 'assoc :value - '("t"))))) - (no_default_prec_decl - ((NO-DEFAULT-PREC) - `(wisent-raw-tag - (semantic-tag "default-prec" 'assoc :value - '("nil"))))) - (languagemode_decl - ((LANGUAGEMODE symbols) - `(wisent-raw-tag - (semantic-tag ',(car $2) - 'languagemode :rest ',(cdr $2))))) - (package_decl - ((PACKAGE SYMBOL) - `(wisent-raw-tag - (semantic-tag-new-package ',$2 nil)))) - (expectedconflicts_decl - ((EXPECTEDCONFLICTS symbols) - `(wisent-raw-tag - (semantic-tag ',(car $2) - 'expectedconflicts :rest ',(cdr $2))))) - (provide_decl - ((PROVIDE SYMBOL) - `(wisent-raw-tag - (semantic-tag ',$2 'provide)))) - (precedence_decl - ((associativity token_type_opt items) - `(wisent-raw-tag - (semantic-tag ',$1 'assoc :type ',$2 :value ',$3)))) - (associativity - ((LEFT) - (progn "left")) - ((RIGHT) - (progn "right")) - ((NONASSOC) - (progn "nonassoc"))) - (put_decl - ((PUT put_name put_value) - `(wisent-raw-tag - (semantic-tag ',$2 'put :value ',(list $3)))) - ((PUT put_name put_value_list) - `(wisent-raw-tag - (semantic-tag ',$2 'put :value ',$3))) - ((PUT put_name_list put_value) - `(wisent-raw-tag - (semantic-tag ',(car $2) - 'put :rest ',(cdr $2) - :value ',(list $3)))) - ((PUT put_name_list put_value_list) - `(wisent-raw-tag - (semantic-tag ',(car $2) - 'put :rest ',(cdr $2) - :value ',$3)))) - (put_name_list - ((BRACE_BLOCK) - (mapcar 'semantic-tag-name - (semantic-parse-region - (car $region1) - (cdr $region1) - 'put_names 1)))) - (put_names - ((LBRACE) - nil) - ((RBRACE) - nil) - ((put_name) - (wisent-raw-tag - (semantic-tag $1 'put-name)))) - (put_name - ((SYMBOL)) - ((token_type))) - (put_value_list - ((BRACE_BLOCK) - (mapcar 'semantic-tag-code-detail - (semantic-parse-region - (car $region1) - (cdr $region1) - 'put_values 1)))) - (put_values - ((LBRACE) - nil) - ((RBRACE) - nil) - ((put_value) - (wisent-raw-tag - (semantic-tag-new-code "put-value" $1)))) - (put_value - ((SYMBOL any_value) - (cons $1 $2))) - (scopestart_decl - ((SCOPESTART SYMBOL) - `(wisent-raw-tag - (semantic-tag ',$2 'scopestart)))) - (quotemode_decl - ((QUOTEMODE SYMBOL) - `(wisent-raw-tag - (semantic-tag ',$2 'quotemode)))) - (start_decl - ((START symbols) - `(wisent-raw-tag - (semantic-tag ',(car $2) - 'start :rest ',(cdr $2))))) - (keyword_decl - ((KEYWORD SYMBOL string_value) - `(wisent-raw-tag - (semantic-tag ',$2 'keyword :value ',$3)))) - (token_decl - ((TOKEN token_type_opt SYMBOL string_value) - `(wisent-raw-tag - (semantic-tag ',$3 ',(if $2 'token 'keyword) - :type ',$2 :value ',$4))) - ((TOKEN token_type_opt symbols) - `(wisent-raw-tag - (semantic-tag ',(car $3) - 'token :type ',$2 :rest ',(cdr $3))))) - (token_type_opt - (nil) - ((token_type))) - (token_type - ((LT SYMBOL GT) - (progn $2))) - (type_decl - ((TYPE token_type plist_opt) - `(wisent-raw-tag - (semantic-tag ',$2 'type :value ',$3)))) - (plist_opt - (nil) - ((plist))) - (plist - ((plist put_value) - (append - (list $2) - $1)) - ((put_value) - (list $1))) - (use_name_list - ((BRACE_BLOCK) - (mapcar 'semantic-tag-name - (semantic-parse-region - (car $region1) - (cdr $region1) - 'use_names 1)))) - (use_names - ((LBRACE) - nil) - ((RBRACE) - nil) - ((SYMBOL) - (wisent-raw-tag - (semantic-tag $1 'use-name)))) - (use_macros_decl - ((USE-MACROS SYMBOL use_name_list) - `(wisent-raw-tag - (semantic-tag "macro" 'macro :type ',$2 :value ',$3)))) - (string_value - ((STRING) - (read $1))) - (any_value - ((SYMBOL)) - ((STRING)) - ((PAREN_BLOCK)) - ((PREFIXED_LIST)) - ((SEXP))) - (symbols - ((lifo_symbols) - (nreverse $1))) - (lifo_symbols - ((lifo_symbols SYMBOL) - (cons $2 $1)) - ((SYMBOL) - (list $1))) - (nonterminal - ((SYMBOL - (setq semantic-grammar-wy--nterm $1 semantic-grammar-wy--rindx 0) - COLON rules SEMI) - (wisent-raw-tag - (semantic-tag $1 'nonterminal :children $4)))) - (rules - ((lifo_rules) - (apply 'nconc - (nreverse $1)))) - (lifo_rules - ((lifo_rules OR rule) - (cons $3 $1)) - ((rule) - (list $1))) - (rule - ((rhs) - (let* - ((nterm semantic-grammar-wy--nterm) - (rindx semantic-grammar-wy--rindx) - (rhs $1) - comps prec action elt) - (setq semantic-grammar-wy--rindx - (1+ semantic-grammar-wy--rindx)) - (while rhs - (setq elt - (car rhs) - rhs - (cdr rhs)) - (cond - ((vectorp elt) - (if prec - (error "Duplicate %%prec in `%s:%d' rule" nterm rindx)) - (setq prec - (aref elt 0))) - ((consp elt) - (if - (or action comps) - (setq comps - (cons elt comps) - semantic-grammar-wy--rindx - (1+ semantic-grammar-wy--rindx)) - (setq action - (car elt)))) - (t - (setq comps - (cons elt comps))))) - (wisent-cook-tag - (wisent-raw-tag - (semantic-tag - (format "%s:%d" nterm rindx) - 'rule :type - (if comps "group" "empty") - :value comps :prec prec :expr action)))))) - (rhs - (nil) - ((rhs item) - (cons $2 $1)) - ((rhs action) - (cons - (list $2) - $1)) - ((rhs PREC item) - (cons - (vector $3) - $1))) - (action - ((PAREN_BLOCK)) - ((PREFIXED_LIST)) - ((BRACE_BLOCK) - (format "(progn\n%s)" - (let - ((s $1)) - (if - (string-match "^{[ \n ]*" s) - (setq s - (substring s - (match-end 0)))) - (if - (string-match "[ \n ]*}$" s) - (setq s - (substring s 0 - (match-beginning 0)))) - s)))) - (items - ((lifo_items) - (nreverse $1))) - (lifo_items - ((lifo_items item) - (cons $2 $1)) - ((item) - (list $1))) - (item - ((SYMBOL)) - ((CHARACTER)))) - '(grammar prologue epilogue declaration nonterminal rule put_names put_values use_names))) + (semantic-tag + (format "%s:%d" nterm rindx) + 'rule :type + (if comps "group" "empty") + :value comps :prec prec :expr action)))))) + (rhs + (nil) + ((rhs item) + (cons $2 $1)) + ((rhs action) + (cons + (list $2) + $1)) + ((rhs PREC item) + (cons + (vector $3) + $1))) + (action + ((PAREN_BLOCK)) + ((PREFIXED_LIST)) + ((BRACE_BLOCK) + (format "(progn\n%s)" + (let + ((s $1)) + (if + (string-match "^{[ \n ]*" s) + (setq s + (substring s + (match-end 0)))) + (if + (string-match "[ \n ]*}$" s) + (setq s + (substring s 0 + (match-beginning 0)))) + s)))) + (items + ((lifo_items) + (nreverse $1))) + (lifo_items + ((lifo_items item) + (cons $2 $1)) + ((item) + (list $1))) + (item + ((SYMBOL)) + ((CHARACTER)))) + (grammar prologue epilogue declaration nonterminal rule put_names put_values use_names)) "Parser table.") (defun semantic-grammar-wy--install-parser () @@ -434,7 +431,7 @@ semantic-lex-types-obarray semantic-grammar-wy--token-table) ;; Collect unmatched syntax lexical tokens (add-hook 'wisent-discarding-token-functions - 'wisent-collect-unmatched-syntax nil t)) + #'wisent-collect-unmatched-syntax nil t)) ;;; Analyzers diff --git a/lisp/cedet/semantic/grammar.el b/lisp/cedet/semantic/grammar.el index 4551811c23..ca7c273feb 100644 --- a/lisp/cedet/semantic/grammar.el +++ b/lisp/cedet/semantic/grammar.el @@ -1,4 +1,4 @@ -;;; semantic/grammar.el --- Major mode framework for Semantic grammars +;;; semantic/grammar.el --- Major mode framework for Semantic grammars -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2005, 2007-2021 Free Software Foundation, Inc. @@ -191,11 +191,11 @@ Warn if other tags of class CLASS exist." That is tag names plus names defined in tag attribute `:rest'." (let* ((tags (semantic-find-tags-by-class class (current-buffer)))) - (apply 'append + (apply #'append (mapcar #'(lambda (tag) (mapcar - 'intern + #'intern (cons (semantic-tag-name tag) (semantic-tag-get-attribute tag :rest)))) tags)))) @@ -312,7 +312,7 @@ the keyword and TOKEN is the terminal symbol identifying the keyword." (setq put (car puts) puts (cdr puts) keys (mapcar - 'intern + #'intern (cons (semantic-tag-name put) (semantic-tag-get-attribute put :rest)))) (while keys @@ -565,6 +565,10 @@ Typically a DEFINE expression should look like this: (goto-char start) (indent-sexp)))) +(defvar semantic-grammar-require-form + '(eval-when-compile (require 'semantic/bovine)) + "The form to use to load the parser engine.") + (defconst semantic-grammar-header-template '("\ ;;; " file " --- Generated parser support file @@ -602,7 +606,7 @@ Typically a DEFINE expression should look like this: ;;; Code: (require 'semantic/lex) -(eval-when-compile (require 'semantic/bovine)) +" require-form " ") "Generated header template. The symbols in the template are local variables in @@ -651,6 +655,7 @@ The symbols in the list are local variables in semantic--grammar-output-buffer)) (gram . ,(semantic-grammar-buffer-file)) (date . ,(format-time-string "%Y-%m-%d %T%z")) + (require-form . ,(format "%S" semantic-grammar-require-form)) (vcid . ,(concat "$" "Id" "$")) ;; Avoid expansion ;; Try to get the copyright from the input grammar, or ;; generate a new one if not found. @@ -818,7 +823,7 @@ Block definitions are read from the current table of lexical types." (let ((semantic-lex-types-obarray (semantic-lex-make-type-table tokens props)) semantic-grammar--lex-block-specs) - (mapatoms 'semantic-grammar-insert-defanalyzer + (mapatoms #'semantic-grammar-insert-defanalyzer semantic-lex-types-obarray)))) ;;; Generation of the grammar support file. @@ -846,7 +851,8 @@ Lisp code." (semantic--grammar-package (semantic-grammar-package)) (semantic--grammar-provide (semantic-grammar-first-tag-name 'provide)) (output (concat (or semantic--grammar-provide - semantic--grammar-package) ".el")) + semantic--grammar-package) + ".el")) (semantic--grammar-input-buffer (current-buffer)) (semantic--grammar-output-buffer (find-file-noselect @@ -1197,20 +1203,20 @@ END is the limit of the search." (defvar semantic-grammar-mode-map (let ((km (make-sparse-keymap))) - (define-key km "|" 'semantic-grammar-electric-punctuation) - (define-key km ";" 'semantic-grammar-electric-punctuation) - (define-key km "%" 'semantic-grammar-electric-punctuation) - (define-key km "(" 'semantic-grammar-electric-punctuation) - (define-key km ")" 'semantic-grammar-electric-punctuation) - (define-key km ":" 'semantic-grammar-electric-punctuation) - - (define-key km "\t" 'semantic-grammar-indent) - (define-key km "\M-\t" 'semantic-grammar-complete) - (define-key km "\C-c\C-c" 'semantic-grammar-create-package) - (define-key km "\C-cm" 'semantic-grammar-find-macro-expander) - (define-key km "\C-cik" 'semantic-grammar-insert-keyword) -;; (define-key km "\C-cc" 'semantic-grammar-generate-and-load) -;; (define-key km "\C-cr" 'semantic-grammar-generate-one-rule) + (define-key km "|" #'semantic-grammar-electric-punctuation) + (define-key km ";" #'semantic-grammar-electric-punctuation) + (define-key km "%" #'semantic-grammar-electric-punctuation) + (define-key km "(" #'semantic-grammar-electric-punctuation) + (define-key km ")" #'semantic-grammar-electric-punctuation) + (define-key km ":" #'semantic-grammar-electric-punctuation) + + (define-key km "\t" #'semantic-grammar-indent) + (define-key km "\M-\t" #'semantic-grammar-complete) + (define-key km "\C-c\C-c" #'semantic-grammar-create-package) + (define-key km "\C-cm" #'semantic-grammar-find-macro-expander) + (define-key km "\C-cik" #'semantic-grammar-insert-keyword) +;; (define-key km "\C-cc" #'semantic-grammar-generate-and-load) +;; (define-key km "\C-cr" #'semantic-grammar-generate-one-rule) km) "Keymap used in `semantic-grammar-mode'.") @@ -1322,7 +1328,7 @@ the change bounds to encompass the whole nonterminal tag." ;; Setup Semantic to parse grammar (semantic-grammar-wy--install-parser) (setq semantic-lex-comment-regex ";;" - semantic-lex-analyzer 'semantic-grammar-lexer + semantic-lex-analyzer #'semantic-grammar-lexer semantic-type-relation-separator-character '(":") semantic-symbol->name-assoc-list '( @@ -1343,10 +1349,10 @@ the change bounds to encompass the whole nonterminal tag." ;; Before each change, clear the cached regexp used to highlight ;; macros local in this grammar. (add-hook 'before-change-functions - 'semantic--grammar-clear-macros-regexp-2 nil t) + #'semantic--grammar-clear-macros-regexp-2 nil t) ;; Handle safe re-parse of grammar rules. (add-hook 'semantic-edits-new-change-functions - 'semantic-grammar-edits-new-change-hook-fcn + #'semantic-grammar-edits-new-change-hook-fcn nil t)) ;;;; @@ -1876,7 +1882,7 @@ Optional argument COLOR determines if color is added to the text." (names (semantic-tag-get-attribute tag :rest)) (type (semantic-tag-type tag))) (if names - (setq name (mapconcat 'identity (cons name names) " "))) + (setq name (mapconcat #'identity (cons name names) " "))) (setq desc (concat (if type (format " <%s>" type) @@ -1893,7 +1899,7 @@ Optional argument COLOR determines if color is added to the text." (format " <%s>" type) "") (if val - (concat " " (mapconcat 'identity val " ")) + (concat " " (mapconcat #'identity val " ")) ""))))) (t (setq desc (semantic-format-tag-abbreviate tag parent color)))) @@ -1944,7 +1950,7 @@ Optional argument COLOR determines if color is added to the text." context-return))) (define-mode-local-override semantic-analyze-possible-completions - semantic-grammar-mode (context &rest flags) + semantic-grammar-mode (context &rest _flags) "Return a list of possible completions based on CONTEXT." (require 'semantic/analyze/complete) (if (semantic-grammar-in-lisp-p) diff --git a/lisp/cedet/semantic/wisent.el b/lisp/cedet/semantic/wisent.el index ecd9683135..f498e7edcc 100644 --- a/lisp/cedet/semantic/wisent.el +++ b/lisp/cedet/semantic/wisent.el @@ -224,7 +224,7 @@ the standard function `semantic-parse-stream'." (error-message-string error-to-filter)) (message "wisent-parse-max-stack-size \ might need to be increased")) - (apply 'signal error-to-filter)))))) + (apply #'signal error-to-filter)))))) ;; Manage returned lookahead token (if wisent-lookahead (if (eq (caar la-elt) wisent-lookahead) @@ -252,6 +252,17 @@ might need to be increased")) (if (consp cache) cache '(nil)) ))) +(defmacro wisent-compiled-grammar (grammar &optional start-list) + "Return a compiled form of the LALR(1) Wisent GRAMMAR. +See `wisent--compile-grammar' for a description of the arguments +and return value." + ;; Ensure that the grammar compiler is available. + (require 'semantic/wisent/comp) + (declare-function wisent-automaton-lisp-form "semantic/wisent/comp" (x)) + (declare-function wisent--compile-grammar "semantic/wisent/comp" (grm st)) + (wisent-automaton-lisp-form + (wisent--compile-grammar grammar start-list))) + (defun wisent-parse-region (start end &optional goal depth returnonerror) "Parse the area between START and END using the Wisent LALR parser. Return the list of semantic tags found. diff --git a/lisp/cedet/semantic/wisent/comp.el b/lisp/cedet/semantic/wisent/comp.el index 7a64fe2fec..574922049f 100644 --- a/lisp/cedet/semantic/wisent/comp.el +++ b/lisp/cedet/semantic/wisent/comp.el @@ -1,4 +1,4 @@ -;;; semantic/wisent/comp.el --- GNU Bison for Emacs - Grammar compiler +;;; semantic/wisent/comp.el --- GNU Bison for Emacs - Grammar compiler -*- lexical-binding: t; -*- ;; Copyright (C) 1984, 1986, 1989, 1992, 1995, 2000-2007, 2009-2021 Free ;; Software Foundation, Inc. @@ -71,7 +71,7 @@ (declarations (mapcar #'(lambda (v) (list 'defvar v)) vars))) `(progn ,@declarations - (eval-when-compile + (eval-and-compile (defvar ,context ',vars))))) (defmacro wisent-with-context (name &rest body) @@ -101,6 +101,8 @@ If optional LEFT is non-nil insert spaces on left." ;;;; Environment dependencies ;;;; ------------------------ +;; FIXME: Use bignums or bool-vectors? + (defconst wisent-BITS-PER-WORD (logcount most-positive-fixnum)) (defsubst wisent-WORDSIZE (n) @@ -2774,7 +2776,7 @@ that likes a token gets to handle it." "Figure out the actions for every state. Return the action table." ;; Store the semantic action obarray in (unused) RCODE[0]. - (aset rcode 0 (make-vector 13 0)) + (aset rcode 0 (obarray-make 13)) (let (i j action-table actrow action) (setq action-table (make-vector nstates nil) actrow (make-vector ntokens nil) @@ -3388,7 +3390,7 @@ NONTERMS is the list of non terminal definitions (see function ;;;; Compile input grammar ;;;; --------------------- -(defun wisent-compile-grammar (grammar &optional start-list) +(defun wisent--compile-grammar (grammar start-list) "Compile the LALR(1) GRAMMAR. GRAMMAR is a list (TOKENS ASSOCS . NONTERMS) where: @@ -3440,7 +3442,7 @@ where: (wisent-parser-automaton))))) ;;;; -------------------------- -;;;; Byte compile input grammar +;;;; Obsolete byte compile support ;;;; -------------------------- (require 'bytecomp) @@ -3449,25 +3451,32 @@ where: "Byte compile the `wisent-compile-grammar' FORM. Automatically called by the Emacs Lisp byte compiler as a `byte-compile' handler." - ;; Eval the `wisent-compile-grammar' form to obtain an LALR - ;; automaton internal data structure. Then, because the internal - ;; data structure contains an obarray, convert it to a lisp form so - ;; it can be byte-compiled. (byte-compile-form - ;; FIXME: we macroexpand here since `byte-compile-form' expects - ;; macroexpanded code, but that's just a workaround: for lexical-binding - ;; the lisp form should have to pass through closure-conversion and - ;; `wisent-byte-compile-grammar' is called much too late for that. - ;; Why isn't this `wisent-automaton-lisp-form' performed at - ;; macroexpansion time? --Stef (macroexpand-all (wisent-automaton-lisp-form (eval form))))) -;; FIXME: We shouldn't use a `byte-compile' handler. Maybe using a hash-table -;; instead of an obarray would work around the problem that obarrays -;; aren't printable. Then (put 'wisent-compile-grammar 'side-effect-free t). -(put 'wisent-compile-grammar 'byte-compile 'wisent-byte-compile-grammar) +(defun wisent-compile-grammar (grammar &optional start-list) + ;; This is kept for compatibility with FOO-wy.el files generated + ;; with older Emacsen. + (declare (obsolete wisent-compiled-grammar "Mar 2021")) + (wisent--compile-grammar grammar start-list)) + +(put 'wisent-compile-grammar 'byte-compile #'wisent-byte-compile-grammar) + +;;;; -------------------------- +;;;; Byte compile input grammar +;;;; -------------------------- +;; `wisent--compile-grammar' generates the actual parse table +;; we need at run-time, but in order to be able to compile the code it +;; contains, we need to "reify" it back into a piece of ELisp code +;; which (re)builds it. +;; This is needed for 2 reasons: +;; - The parse tables include an obarray and these don't survive the print+read +;; steps involved in generating a `.elc' file and reading it back in. +;; - Within the parse table vectors/obarrays we have ELisp functions which +;; we want to byte-compile, but if we were to just `quote' the table +;; we'd get them with the same non-compiled functions. (defun wisent-automaton-lisp-form (automaton) "Return a Lisp form that produces AUTOMATON. See also `wisent-compile-grammar' for more details on AUTOMATON." @@ -3477,7 +3486,7 @@ See also `wisent-compile-grammar' for more details on AUTOMATON." (let ((obn (make-symbol "ob")) ; Generated obarray name (obv (aref automaton 3)) ; Semantic actions obarray ) - `(let ((,obn (make-vector 13 0))) + `(let ((,obn (obarray-make 13))) ;; Generate code to initialize the semantic actions obarray, ;; in local variable OBN. ,@(let (obcode) @@ -3496,7 +3505,9 @@ See also `wisent-compile-grammar' for more details on AUTOMATON." ;; obarray. (vector ,@(mapcar - #'(lambda (state) ;; for each state + ;; Use name `st' rather than `state' since `state' is + ;; defined as dynbound in `semantic-actions' context above :-( ! + #'(lambda (st) ;; for each state `(list ,@(mapcar #'(lambda (tr) ;; for each transition @@ -3507,7 +3518,7 @@ See also `wisent-compile-grammar' for more details on AUTOMATON." `(cons ,(if (symbolp k) `(quote ,k) k) (intern-soft ,(symbol-name a) ,obn)) `(quote ,tr)))) - state))) + st))) (aref automaton 0))) ;; The code of the goto table is unchanged. ,(aref automaton 1) diff --git a/lisp/cedet/semantic/wisent/grammar.el b/lisp/cedet/semantic/wisent/grammar.el index edc5c5c702..819ebd5dad 100644 --- a/lisp/cedet/semantic/wisent/grammar.el +++ b/lisp/cedet/semantic/wisent/grammar.el @@ -286,12 +286,9 @@ Return the expanded expression." (defun wisent-grammar-parsetable-builder () "Return the value of the parser table." - `(progn - ;; Ensure that the grammar [byte-]compiler is available. - (eval-when-compile (require 'semantic/wisent/comp)) - (wisent-compile-grammar - ',(wisent-grammar-grammar) - ',(semantic-grammar-start)))) + `(wisent-compiled-grammar + ,(wisent-grammar-grammar) + ,(semantic-grammar-start))) (defun wisent-grammar-setupcode-builder () "Return the parser setup code." @@ -305,7 +302,7 @@ Return the expanded expression." semantic-lex-types-obarray %s)\n\ ;; Collect unmatched syntax lexical tokens\n\ (add-hook 'wisent-discarding-token-functions\n\ - 'wisent-collect-unmatched-syntax nil t)" + #'wisent-collect-unmatched-syntax nil t)" (semantic-grammar-parsetable) (buffer-name) (semantic-grammar-keywordtable) @@ -325,6 +322,7 @@ Menu items are appended to the common grammar menu.") (define-derived-mode wisent-grammar-mode semantic-grammar-mode "WY" "Major mode for editing Wisent grammars." (semantic-grammar-setup-menu wisent-grammar-menu) + (setq-local semantic-grammar-require-form '(require 'semantic/wisent)) (semantic-install-function-overrides '((semantic-grammar-parsetable-builder . wisent-grammar-parsetable-builder) (semantic-grammar-setupcode-builder . wisent-grammar-setupcode-builder)))) diff --git a/lisp/cedet/semantic/wisent/java-tags.el b/lisp/cedet/semantic/wisent/java-tags.el index d455c02d1b..adb9a30894 100644 --- a/lisp/cedet/semantic/wisent/java-tags.el +++ b/lisp/cedet/semantic/wisent/java-tags.el @@ -1,4 +1,4 @@ -;;; semantic/wisent/java-tags.el --- Java LALR parser for Emacs +;;; semantic/wisent/java-tags.el --- Java LALR parser for Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2006, 2009-2021 Free Software Foundation, Inc. @@ -92,7 +92,7 @@ This function override `get-local-variables'." (define-mode-local-override semantic-analyze-unsplit-name java-mode (namelist) "Assemble the list of names NAMELIST into a namespace name." - (mapconcat 'identity namelist ".")) + (mapconcat #'identity namelist ".")) diff --git a/lisp/cedet/semantic/wisent/javascript.el b/lisp/cedet/semantic/wisent/javascript.el index 684eea1d93..9db51ad36b 100644 --- a/lisp/cedet/semantic/wisent/javascript.el +++ b/lisp/cedet/semantic/wisent/javascript.el @@ -1,4 +1,4 @@ -;;; semantic/wisent/javascript.el --- javascript parser support +;;; semantic/wisent/javascript.el --- javascript parser support -*- lexical-binding: t; -*- ;; Copyright (C) 2005, 2009-2021 Free Software Foundation, Inc. @@ -70,7 +70,7 @@ This function overrides `get-local-variables'." ;; Does javascript have identifiable local variables? nil) -(define-mode-local-override semantic-tag-protection js-mode (tag &optional parent) +(define-mode-local-override semantic-tag-protection js-mode (_tag &optional _parent) "Return protection information about TAG with optional PARENT. This function returns on of the following symbols: nil - No special protection. Language dependent. @@ -85,7 +85,7 @@ The default behavior (if not overridden with `tag-protection' is to return a symbol based on type modifiers." nil) -(define-mode-local-override semantic-analyze-scope-calculate-access js-mode (type scope) +(define-mode-local-override semantic-analyze-scope-calculate-access js-mode (_type _scope) "Calculate the access class for TYPE as defined by the current SCOPE. Access is related to the :parents in SCOPE. If type is a member of SCOPE then access would be `private'. If TYPE is inherited by a member of SCOPE, @@ -101,7 +101,7 @@ This is currently needed for the mozrepl omniscient database." (save-excursion (if point (goto-char point)) (let* ((case-fold-search semantic-case-fold) - symlist tmp end) + tmp end) ;; symlist (with-syntax-table semantic-lex-syntax-table (save-excursion (when (looking-at "\\w\\|\\s_") @@ -110,10 +110,11 @@ This is currently needed for the mozrepl omniscient database." (unless (re-search-backward "\\s-" (point-at-bol) t) (beginning-of-line)) (setq tmp (buffer-substring-no-properties (point) end)) + ;; (setq symlist (if (string-match "\\(.+\\)\\." tmp) - (setq symlist (list (match-string 1 tmp) - (substring tmp (1+ (match-end 1)) (length tmp)))) - (setq symlist (list tmp)))))))) + (list (match-string 1 tmp) + (substring tmp (1+ (match-end 1)) (length tmp))) + (list tmp)))))));; ) ;;; Setup Function ;; diff --git a/lisp/cedet/semantic/wisent/python.el b/lisp/cedet/semantic/wisent/python.el index 7769ad1961..8732b2e975 100644 --- a/lisp/cedet/semantic/wisent/python.el +++ b/lisp/cedet/semantic/wisent/python.el @@ -1,4 +1,4 @@ -;;; wisent-python.el --- Semantic support for Python +;;; wisent-python.el --- Semantic support for Python -*- lexical-binding: t; -*- ;; Copyright (C) 2002, 2004, 2006-2021 Free Software Foundation, Inc. @@ -464,19 +464,19 @@ To be implemented for Python! For now just return nil." (define-mode-local-override semantic-tag-include-filename python-mode (tag) "Return a suitable path for (some) Python imports." (let ((name (semantic-tag-name tag))) - (concat (mapconcat 'identity (split-string name "\\.") "/") ".py"))) + (concat (mapconcat #'identity (split-string name "\\.") "/") ".py"))) ;; Override ctxt-current-function/assignment defaults, since they do ;; not work properly with Python code, even leading to endless loops ;; (see bug #xxxxx). -(define-mode-local-override semantic-ctxt-current-function python-mode (&optional point) +(define-mode-local-override semantic-ctxt-current-function python-mode (&optional _point) "Return the current function call the cursor is in at POINT. The function returned is the one accepting the arguments that the cursor is currently in. It will not return function symbol if the cursor is on the text representing that function." nil) -(define-mode-local-override semantic-ctxt-current-assignment python-mode (&optional point) +(define-mode-local-override semantic-ctxt-current-assignment python-mode (&optional _point) "Return the current assignment near the cursor at POINT. Return a list as per `semantic-ctxt-current-symbol'. Return nil if there is nothing relevant." diff --git a/lisp/cedet/semantic/wisent/wisent.el b/lisp/cedet/semantic/wisent/wisent.el index 26cf87f842..df1fd73e29 100644 --- a/lisp/cedet/semantic/wisent/wisent.el +++ b/lisp/cedet/semantic/wisent/wisent.el @@ -1,4 +1,4 @@ -;;; semantic/wisent/wisent.el --- GNU Bison for Emacs - Runtime +;;; semantic/wisent/wisent.el --- GNU Bison for Emacs - Runtime -*- lexical-binding: t; -*- ;;; Copyright (C) 2002-2007, 2009-2021 Free Software Foundation, Inc. @@ -139,7 +139,7 @@ POSITIONS are available." "Print a one-line message if `wisent-parse-verbose-flag' is set. Pass STRING and ARGS arguments to `message'." (and wisent-parse-verbose-flag - (apply 'message string args))) + (apply #'message string args))) ;;;; -------------------- ;;;; The LR parser engine @@ -147,13 +147,11 @@ Pass STRING and ARGS arguments to `message'." (defcustom wisent-parse-max-stack-size 500 "The parser stack size." - :type 'integer - :group 'wisent) + :type 'integer) (defcustom wisent-parse-max-recover 3 "Number of tokens to shift before turning off error status." - :type 'integer - :group 'wisent) + :type 'integer) (defvar wisent-discarding-token-functions nil "List of functions to be called when discarding a lexical token. @@ -397,9 +395,9 @@ automaton has only one entry point." (wisent-error (format "Syntax error, unexpected %s, expecting %s" (wisent-token-to-string wisent-input) - (mapconcat 'wisent-item-to-string + (mapconcat #'wisent-item-to-string (delq wisent-error-term - (mapcar 'car (cdr choices))) + (mapcar #'car (cdr choices))) ", ")))) ;; Increment the error counter (setq wisent-nerrs (1+ wisent-nerrs)) commit 856a0a913a1932e1bad8e44d34944ce7504b23ff Author: Stefan Kangas Date: Sun Mar 7 06:26:53 2021 +0100 Remove additional items obsolete since Emacs 22/23 * lisp/speedbar.el (speedbar-update-speed) (speedbar-navigating-speed): Remove variables obsolete since Emacs 23. (speedbar-dir-follow, speedbar-directory-buttons-follow): Don't use above removed variables. * lisp/erc/erc.el (erc-announced-server-name, erc-process) (erc-default-coding-system, erc-send-command): Remove variables and functions obsolete since Emacs 22. ; * etc/NEWS: List removed items. diff --git a/etc/NEWS b/etc/NEWS index d36771377e..c4feabb511 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2335,15 +2335,16 @@ ledit.el, lmenu.el, lucid.el and old-whitespace.el. 'dirtrack-debug-toggle', 'dynamic-completion-table', 'easy-menu-precalculate-equivalent-keybindings', 'epa-display-verify-result', 'epg-passphrase-callback-function', -'eshell-report-bug', 'eval-next-after-load', 'exchange-dot-and-mark', -'ffap-bug', 'ffap-submit-bug', 'ffap-version', -'file-cache-choose-completion', 'forward-point', 'generic-char-p', -'global-highlight-changes', 'hi-lock-face-history', -'hi-lock-regexp-history', 'highlight-changes-active-string', -'highlight-changes-initial-state', 'highlight-changes-passive-string', -'image-mode-maybe', 'imenu-example--name-and-position', -'ispell-aspell-supports-utf8', 'lisp-mode-auto-fill', -'locate-file-completion', 'make-coding-system', +'erc-announced-server-name', 'erc-process', +'erc-default-coding-system', 'erc-send-command', 'eshell-report-bug', +'eval-next-after-load', 'exchange-dot-and-mark', 'ffap-bug', +'ffap-submit-bug', 'ffap-version', 'file-cache-choose-completion', +'forward-point', 'generic-char-p', 'global-highlight-changes', +'hi-lock-face-history', 'hi-lock-regexp-history', +'highlight-changes-active-string', 'highlight-changes-initial-state', +'highlight-changes-passive-string', 'image-mode-maybe', +'imenu-example--name-and-position', 'ispell-aspell-supports-utf8', +'lisp-mode-auto-fill', 'locate-file-completion', 'make-coding-system', 'minibuffer-local-must-match-filename-map', 'mouse-choose-completion', 'mouse-major-mode-menu', 'mouse-popup-menubar', 'mouse-popup-menubar-stuff', 'newsticker-groups-filename', @@ -2379,7 +2380,8 @@ ledit.el, lmenu.el, lucid.el and old-whitespace.el. 'semantic-token-type-parent', 'semantic-toplevel-bovine-cache', 'semantic-toplevel-bovine-table', 'semanticdb-mode-hooks', 'set-coding-priority', 'set-process-filter-multibyte', -'shadows-compare-text-p', 'shell-dirtrack-toggle', 't-mouse-mode', +'shadows-compare-text-p', 'shell-dirtrack-toggle', +'speedbar-update-speed', 'speedbar-navigating-speed', 't-mouse-mode', 'term-dynamic-simple-complete', 'tooltip-hook', 'tpu-have-ispell', 'url-generate-unique-filename', 'url-temporary-directory', 'vc-arch-command', 'vc-default-working-revision' (variable), diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 1e44e4e3e3..4d45ac29ba 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -114,17 +114,6 @@ "Running scripts at startup and with /LOAD" :group 'erc) -;; compatibility with older ERC releases - -(define-obsolete-variable-alias 'erc-announced-server-name - 'erc-server-announced-name "ERC 5.1") -(define-obsolete-variable-alias 'erc-process 'erc-server-process "ERC 5.1") -(define-obsolete-variable-alias 'erc-default-coding-system - 'erc-server-coding-system "ERC 5.1") - -(define-obsolete-function-alias 'erc-send-command - 'erc-server-send "ERC 5.1") - (require 'erc-backend) ;; tunable connection and authentication parameters diff --git a/lisp/speedbar.el b/lisp/speedbar.el index 4a78562380..6c4c8eb813 100644 --- a/lisp/speedbar.el +++ b/lisp/speedbar.el @@ -289,22 +289,6 @@ A nil value means don't show the file in the list." :group 'speedbar :type 'boolean) -;;; EVENTUALLY REMOVE THESE - -;; When I moved to a repeating timer, I had the horrible misfortune -;; of losing the ability for adaptive speed choice. This update -;; speed currently causes long delays when it should have been turned off. -(defvar speedbar-update-speed dframe-update-speed) -(make-obsolete-variable 'speedbar-update-speed - 'dframe-update-speed - "speedbar 1.0pre3 (Emacs 23.1)") - -(defvar speedbar-navigating-speed dframe-update-speed) -(make-obsolete-variable 'speedbar-navigating-speed - 'dframe-update-speed - "speedbar 1.0pre3 (Emacs 23.1)") -;;; END REMOVE THESE - (defcustom speedbar-frame-parameters '((minibuffer . nil) (width . 20) (border-width . 0) @@ -3260,7 +3244,7 @@ subdirectory chosen will be at INDENT level." ;; in case. (let ((speedbar-smart-directory-expand-flag nil)) (speedbar-update-contents)) - (speedbar-set-timer speedbar-navigating-speed) + (speedbar-set-timer dframe-update-speed) (setq speedbar-last-selected-file nil) (speedbar-stealthy-updates)) @@ -3323,7 +3307,7 @@ INDENT is the current indentation level and is unused." ;; update contents will change directory without ;; having to touch the attached frame. (speedbar-update-contents) - (speedbar-set-timer speedbar-navigating-speed)) + (speedbar-set-timer dframe-update-speed)) (defun speedbar-tag-file (text token indent) "The cursor is on a selected line. Expand the tags in the specified file. commit 98533555de42f2bded824130466cf0aefc648292 Author: Stefan Kangas Date: Sun Mar 7 05:36:11 2021 +0100 Remove some items obsolete since Emacs 22/23 from Gnus * lisp/gnus/gnus-art.el (gnus-article-hide-pgp-hook) (gnus-treat-strip-pgp, gnus-treat-display-xface): * lisp/gnus/gnus-msg.el (gnus-inews-mark-gcc-as-read): * lisp/gnus/gnus-start.el (nnmail-spool-file): * lisp/gnus/nnmail.el (nnmail-spool-file) (nnmail-fix-eudora-headers): Remove items obsolete since 22.1. * lisp/gnus/gnus-art.el (gnus-treat-display-x-face): * lisp/gnus/gnus-msg.el (gnus-inews-do-gcc): Don't use above obsolete symbols. * doc/misc/gnus.texi (Washing Mail, Not Reading Mail): Don't refer to above obsolete variables. ; * etc/NEWS: List removed items. * lisp/gnus/gnus.el (gnus-local-domain, gnus-carpal): * lisp/gnus/nnimap.el (nnimap-split-rule): * lisp/gnus/nntp.el (nntp-authinfo-file): Fix obsolete variable version format. diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi index fef066db8f..faf5366e2b 100644 --- a/doc/misc/gnus.texi +++ b/doc/misc/gnus.texi @@ -16269,7 +16269,6 @@ Translate all @samp{@key{TAB}} characters into @samp{@key{SPC}} characters. @item nnmail-ignore-broken-references @findex nnmail-ignore-broken-references -@c @findex nnmail-fix-eudora-headers @cindex Eudora @cindex Pegasus Some mail user agents (e.g., Eudora and Pegasus) produce broken @@ -16359,9 +16358,8 @@ If you start using any of the mail back ends, they have the annoying habit of assuming that you want to read mail with them. This might not be unreasonable, but it might not be what you want. -If you set @code{mail-sources} and @code{nnmail-spool-file} to -@code{nil}, none of the back ends will ever attempt to read incoming -mail, which should help. +If you set @code{mail-sources} to @code{nil}, none of the back ends +will ever attempt to read incoming mail, which should help. @vindex nnbabyl-get-new-mail @vindex nnmbox-get-new-mail diff --git a/etc/NEWS b/etc/NEWS index d2b84d733d..d36771377e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2347,12 +2347,12 @@ ledit.el, lmenu.el, lucid.el and old-whitespace.el. 'minibuffer-local-must-match-filename-map', 'mouse-choose-completion', 'mouse-major-mode-menu', 'mouse-popup-menubar', 'mouse-popup-menubar-stuff', 'newsticker-groups-filename', -'non-iso-charset-alist', 'nonascii-insert-offset', -'nonascii-translation-table', 'password-read-and-add', -'pre-abbrev-expand-hook', 'princ-list', 'print-help-return-message', -'process-filter-multibyte-p', 'read-file-name-predicate', -'remember-buffer', 'rmail-highlight-face', 'rmail-message-filter', -'semantic-after-idle-scheduler-reparse-hooks', +'nnmail-fix-eudora-headers', 'non-iso-charset-alist', +'nonascii-insert-offset', 'nonascii-translation-table', +'password-read-and-add', 'pre-abbrev-expand-hook', 'princ-list', +'print-help-return-message', 'process-filter-multibyte-p', +'read-file-name-predicate', 'remember-buffer', 'rmail-highlight-face', +'rmail-message-filter', 'semantic-after-idle-scheduler-reparse-hooks', 'semantic-after-toplevel-bovinate-hook', 'semantic-before-idle-scheduler-reparse-hooks', 'semantic-before-toplevel-bovination-hook', @@ -2387,6 +2387,12 @@ ledit.el, lmenu.el, lucid.el and old-whitespace.el. 'vcursor-toggle-vcursor-map', 'w32-focus-frame', 'w32-select-font', 'wisent-lex-make-token-table'. +--- +** Some functions and variables obsolete since Emacs 22 have been removed: +'gnus-article-hide-pgp-hook', 'gnus-inews-mark-gcc-as-read', +'gnus-treat-display-xface', 'gnus-treat-strip-pgp', +'nnmail-spool-file'. + ** The WHEN argument of 'make-obsolete' and related functions is mandatory. The use of those functions without a WHEN argument was marked obsolete back in Emacs 23.1. The affected functions are: 'make-obsolete', diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index 435ccab740..ad323089ad 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -728,9 +728,6 @@ Each element is a regular expression." :type '(repeat regexp) :group 'gnus-article-various) -(make-obsolete-variable 'gnus-article-hide-pgp-hook nil - "Gnus 5.10 (Emacs 22.1)") - (defface gnus-button '((t (:weight bold))) "Face used for highlighting a button in the article buffer." @@ -1264,9 +1261,6 @@ Any symbol is used to look up a regular expression to match the banner in `gnus-list-identifiers'. A string is used as a regular expression to match the identifier directly.") -(make-obsolete-variable 'gnus-treat-strip-pgp nil - "Gnus 5.10 (Emacs 22.1)") - (defcustom gnus-treat-strip-pem nil "Strip PEM signatures. Valid values are nil, t, `head', `first', `last', an integer or a @@ -1396,9 +1390,6 @@ predicate. See Info node `(gnus)Customizing Articles'." :link '(custom-manual "(gnus)Customizing Articles") :type gnus-article-treat-custom) -(make-obsolete-variable 'gnus-treat-display-xface - 'gnus-treat-display-x-face "Emacs 22.1") - (defcustom gnus-treat-display-x-face (and (not noninteractive) (gnus-image-type-available-p 'xbm) @@ -1423,17 +1414,7 @@ See Info node `(gnus)Customizing Articles' and Info node symbol (cond ((or (boundp symbol) (get symbol 'saved-value)) value) - ((boundp 'gnus-treat-display-xface) - (message "\ -** gnus-treat-display-xface is an obsolete variable;\ - use gnus-treat-display-x-face instead") - (default-value 'gnus-treat-display-xface)) - ((get 'gnus-treat-display-xface 'saved-value) - (message "\ -** gnus-treat-display-xface is an obsolete variable;\ - use gnus-treat-display-x-face instead") - (eval (car (get 'gnus-treat-display-xface 'saved-value)) t)) - (t + (t value))))) (put 'gnus-treat-display-x-face 'highlight t) diff --git a/lisp/gnus/gnus-msg.el b/lisp/gnus/gnus-msg.el index d7851f2629..f1181d4091 100644 --- a/lisp/gnus/gnus-msg.el +++ b/lisp/gnus/gnus-msg.el @@ -143,9 +143,6 @@ See Info node `(gnus)Posting Styles'." :group 'gnus-message :type 'boolean) -(make-obsolete-variable 'gnus-inews-mark-gcc-as-read - 'gnus-gcc-mark-as-read "Emacs 22.1") - (defcustom gnus-gcc-externalize-attachments nil "Should local-file attachments be included as external parts in Gcc copies? If it is `all', attach files as external parts; @@ -1659,9 +1656,7 @@ this is a reply." ;; FIXME: Should gcc-mark-as-read work when ;; Gnus is not running? (gnus-alive-p)) - (if (or gnus-gcc-mark-as-read - (and (boundp 'gnus-inews-mark-gcc-as-read) - (symbol-value 'gnus-inews-mark-gcc-as-read))) + (if gnus-gcc-mark-as-read (gnus-group-mark-article-read group (cdr group-art)) (with-current-buffer gnus-group-buffer (let ((gnus-group-marked (list group)) diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el index a3112bdd9f..a6b362e083 100644 --- a/lisp/gnus/gnus-start.el +++ b/lisp/gnus/gnus-start.el @@ -663,7 +663,6 @@ the first newsgroup." (defvar mail-sources) (defvar nnmail-scan-directory-mail-source-once) (defvar nnmail-split-history) -(defvar nnmail-spool-file) (defun gnus-close-all-servers () "Close all servers." diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index 0334b81f0b..2f2b2061b9 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el @@ -1138,7 +1138,7 @@ no need to set this variable." :group 'gnus-message :type '(choice (const :tag "default" nil) string)) -(make-obsolete-variable 'gnus-local-domain nil "Emacs 24.1") +(make-obsolete-variable 'gnus-local-domain nil "24.1") ;; Customization variables @@ -2310,7 +2310,7 @@ automatically cache the article in the agent cache." ;; The carpal mode has been removed, but define the variable for ;; backwards compatibility. (defvar gnus-carpal nil) -(make-obsolete-variable 'gnus-carpal nil "Emacs 24.1") +(make-obsolete-variable 'gnus-carpal nil "24.1") (defvar gnus-agent-fetching nil "Whether Gnus agent is in fetching mode.") diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el index f4f4ef89a9..93e1c47be7 100644 --- a/lisp/gnus/nnimap.el +++ b/lisp/gnus/nnimap.el @@ -95,7 +95,7 @@ Uses the same syntax as `nnmail-split-methods'.") "Articles with the flags in the list will not be considered when splitting.") (make-obsolete-variable 'nnimap-split-rule "see `nnimap-split-methods'." - "Emacs 24.1") + "24.1") (defvoo nnimap-authenticator nil "How nnimap authenticate itself to the server. diff --git a/lisp/gnus/nnmail.el b/lisp/gnus/nnmail.el index 9826bc6172..bcf01cfa9e 100644 --- a/lisp/gnus/nnmail.el +++ b/lisp/gnus/nnmail.el @@ -240,11 +240,6 @@ If non-nil, also update the cache when copy or move articles." :group 'nnmail :type 'boolean) -(make-obsolete-variable 'nnmail-spool-file 'mail-sources - "Gnus 5.9 (Emacs 22.1)") -;; revision 5.29 / p0-85 / Gnus 5.9 -;; Variable removed in No Gnus v0.7 - (defcustom nnmail-resplit-incoming nil "If non-nil, re-split incoming procmail sorted mail." :group 'nnmail-procmail @@ -1321,9 +1316,6 @@ Eudora has a broken References line, but an OK In-Reply-To." (when (re-search-forward "^\\(In-Reply-To:[^\n]+\\)\n[ \t]+" nil t) (replace-match "\\1" t)))) -(defalias 'nnmail-fix-eudora-headers #'nnmail-ignore-broken-references) -(make-obsolete 'nnmail-fix-eudora-headers #'nnmail-ignore-broken-references "Emacs 23.1") - (custom-add-option 'nnmail-prepare-incoming-header-hook 'nnmail-ignore-broken-references) diff --git a/lisp/gnus/nntp.el b/lisp/gnus/nntp.el index 1eb604d675..1fd2ed06eb 100644 --- a/lisp/gnus/nntp.el +++ b/lisp/gnus/nntp.el @@ -233,7 +233,7 @@ server there that you can connect to. See also (const :format "" "password") (string :format "Password: %v"))))))) -(make-obsolete 'nntp-authinfo-file nil "Emacs 24.1") +(make-obsolete 'nntp-authinfo-file nil "24.1") commit 97f8ab359e6133c975ff2c84f62daa0165421727 Author: Stefan Kangas Date: Sun Mar 7 05:09:21 2021 +0100 Remove some references to Emacs 21 * lisp/erc/erc-track.el (erc-track-position-in-mode-line): * lisp/erc/erc.el (erc-header-line-format): * lisp/ibuffer.el (ibuffer-mode): * lisp/ruler-mode.el: Remove some references to Emacs 21. diff --git a/lisp/erc/erc-track.el b/lisp/erc/erc-track.el index 56f66563ad..a853a36225 100644 --- a/lisp/erc/erc-track.el +++ b/lisp/erc/erc-track.el @@ -244,8 +244,6 @@ The effect may be disabled by setting this variable to nil." (defcustom erc-track-position-in-mode-line 'before-modes "Where to show modified channel information in the mode-line. -Setting this variable only has effect in GNU Emacs versions above 21.3. - Choices are: `before-modes' - add to the beginning of `mode-line-modes', `after-modes' - add to the end of `mode-line-modes', diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 7ee409b735..1e44e4e3e3 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -6290,7 +6290,6 @@ The following characters are replaced: (defcustom erc-header-line-format "%n on %t (%m,%l) %o" "A string to be formatted and shown in the header-line in `erc-mode'. -Only used starting in Emacs 21. Set this to nil if you do not want the header line to be displayed. diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el index 7939bbb773..78ae2705a9 100644 --- a/lisp/ibuffer.el +++ b/lisp/ibuffer.el @@ -2579,7 +2579,7 @@ will be inserted before the group at point." (setq buffer-read-only t) (buffer-disable-undo) (setq truncate-lines ibuffer-truncate-lines) - ;; This makes things less ugly for Emacs 21 users with a non-nil + ;; This makes things less ugly for users with a non-nil ;; `show-trailing-whitespace'. (setq show-trailing-whitespace nil) ;; disable `show-paren-mode' buffer-locally diff --git a/lisp/ruler-mode.el b/lisp/ruler-mode.el index 38283a5c56..c9d39397e0 100644 --- a/lisp/ruler-mode.el +++ b/lisp/ruler-mode.el @@ -25,7 +25,7 @@ ;;; Commentary: ;; This library provides a minor mode to display a ruler in the header -;; line. It works from Emacs 21 onwards. +;; line. ;; ;; You can use the mouse to change the `fill-column' `comment-column', ;; `goal-column', `window-margins' and `tab-stop-list' settings: commit e959107a75e57f0c23354d1cc41873df0dd9f661 Author: Stefan Kangas Date: Sun Mar 7 05:01:42 2021 +0100 * lisp/mouse-drag.el: Use lexical-binding. diff --git a/lisp/mouse-drag.el b/lisp/mouse-drag.el index b2960a4ccd..b424b6edfe 100644 --- a/lisp/mouse-drag.el +++ b/lisp/mouse-drag.el @@ -1,4 +1,4 @@ -;;; mouse-drag.el --- use mouse-2 to do a new style of scrolling +;;; mouse-drag.el --- use mouse-2 to do a new style of scrolling -*- lexical-binding: t -*- ;; Copyright (C) 1996-1997, 2001-2021 Free Software Foundation, Inc. commit fc25474f43c5f764b27589b01bd061245c81b107 Author: Stefan Kangas Date: Sun Mar 7 04:33:45 2021 +0100 * lisp/mouse-copy.el: Use lexical-binding. diff --git a/lisp/mouse-copy.el b/lisp/mouse-copy.el index 8155c9dff3..14fbb51b27 100644 --- a/lisp/mouse-copy.el +++ b/lisp/mouse-copy.el @@ -1,4 +1,4 @@ -;;; mouse-copy.el --- one-click text copy and move +;;; mouse-copy.el --- one-click text copy and move -*- lexical-binding: t -*- ;; Copyright (C) 1996, 2001-2021 Free Software Foundation, Inc. @@ -213,8 +213,7 @@ by johnh@ficus.cs.ucla.edu." (if (mouse-drag-secondary start-event) (progn (mouse-kill-preserving-secondary) - (insert (gui-get-selection 'SECONDARY)))) -) + (insert (gui-get-selection 'SECONDARY))))) (provide 'mouse-copy) commit 5f74397490ef3d629f717116d39c588d3c2de298 Author: Stefan Monnier Date: Sat Mar 6 22:33:19 2021 -0500 * lisp/cedet/semantic/bovine/*.el: Use lexical-binding * lisp/cedet/semantic/bovine/c.el: Use lexical-binding. (semantic-lex-cpp-define): Remove unused var `name`. (semantic-c-do-lex-if): Remove unused var `pt`. (semantic-analyze-tag-references): Remove unused var `refs`. (semantic-c-dereference-namespace): Remove unused vars `tmp` and `usingname`. (semantic-c-dereference-namespace-alias): Remove unused var `newtype`. (semantic-c-check-type-namespace-using): Remove unused vars `tmp` and `shortname`. (semanticdb-find-table-for-include): Remove unused var `prefix`. (semantic-default-c-setup, semantic-c-describe-environment): Use `derived-mode-p`. * lisp/cedet/semantic/bovine/debug.el: Use lexical-binding. * lisp/cedet/semantic/bovine/make.el: Use lexical-binding. * lisp/cedet/semantic/bovine/scm.el: Use lexical-binding. * lisp/cedet/semantic/lex.el (define-lex-analyzer): Define the var (and the function) in a single step. diff --git a/lisp/cedet/semantic/bovine/c.el b/lisp/cedet/semantic/bovine/c.el index fb55139738..7be55ea9e1 100644 --- a/lisp/cedet/semantic/bovine/c.el +++ b/lisp/cedet/semantic/bovine/c.el @@ -1,4 +1,4 @@ -;;; semantic/bovine/c.el --- Semantic details for C +;;; semantic/bovine/c.el --- Semantic details for C -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. @@ -114,7 +114,8 @@ part of the preprocessor map.") "Reset the C preprocessor symbol map based on all input variables." (when (and semantic-mode (featurep 'semantic/bovine/c)) - (remove-hook 'mode-local-init-hook 'semantic-c-reset-preprocessor-symbol-map) + (remove-hook 'mode-local-init-hook + #'semantic-c-reset-preprocessor-symbol-map) ;; Initialize semantic-lex-spp-macro-symbol-obarray with symbols. (setq-mode-local c-mode semantic-lex-spp-macro-symbol-obarray @@ -154,7 +155,7 @@ part of the preprocessor map.") ;; Make sure the preprocessor symbols are set up when mode-local kicks ;; in. -(add-hook 'mode-local-init-hook 'semantic-c-reset-preprocessor-symbol-map) +(add-hook 'mode-local-init-hook #'semantic-c-reset-preprocessor-symbol-map) (defcustom semantic-lex-c-preprocessor-symbol-map nil "Table of C Preprocessor keywords used by the Semantic C lexer. @@ -237,8 +238,8 @@ Return the defined symbol as a special spp lex token." (skip-chars-forward " \t") (if (eolp) nil - (let* ((name (buffer-substring-no-properties - (match-beginning 1) (match-end 1))) + (let* (;; (name (buffer-substring-no-properties + ;; (match-beginning 1) (match-end 1))) (beginning-of-define (match-end 1)) (with-args (save-excursion (goto-char (match-end 0)) @@ -488,7 +489,7 @@ code to parse." (error nil)))) (let ((eval-form (condition-case err - (eval parsedtokelist) + (eval parsedtokelist t) (error (semantic-push-parser-warning (format "Hideif forms produced an error. Assuming false.\n%S" err) @@ -499,11 +500,11 @@ code to parse." (equal eval-form 0)));; ifdef line resulted in false ;; The if indicates to skip this preprocessor section - (let ((pt nil)) + (let () ;; (pt nil) (semantic-push-parser-warning (format "Skip %s" (buffer-substring-no-properties (point-at-bol) (point-at-eol))) (point-at-bol) (point-at-eol)) (beginning-of-line) - (setq pt (point)) + ;; (setq pt (point)) ;; This skips only a section of a conditional. Once that section ;; is opened, encountering any new #else or related conditional ;; should be skipped. @@ -926,7 +927,7 @@ the regular parser." (semantic-lex-init) (semantic-clear-toplevel-cache) (remove-hook 'semantic-lex-reset-functions - 'semantic-lex-spp-reset-hook t) + #'semantic-lex-spp-reset-hook t) ) ;; Get the macro symbol table right. (setq semantic-lex-spp-dynamic-macro-symbol-obarray spp-syms) @@ -970,7 +971,7 @@ the regular parser." ;; Notify about the debug (setq semantic-c-debug-mode-init-last-mode mm) - (add-hook 'post-command-hook 'semantic-c-debug-mode-init-pch))) + (add-hook 'post-command-hook #'semantic-c-debug-mode-init-pch))) (defun semantic-c-debug-mode-init-pch () "Notify user about needing to debug their major mode hooks." @@ -987,7 +988,7 @@ M-x semantic-c-debug-mode-init now. ") - (remove-hook 'post-command-hook 'semantic-c-debug-mode-init-pch))) + (remove-hook 'post-command-hook #'semantic-c-debug-mode-init-pch))) (defun semantic-expand-c-tag (tag) "Expand TAG into a list of equivalent tags, or nil." @@ -1228,7 +1229,7 @@ Use `semantic-analyze-current-tag' to debug this fcn." (when (not (semantic-tag-p tag)) (signal 'wrong-type-argument (list 'semantic-tag-p tag))) (let ((allhits nil) (scope nil) - (refs nil)) + ) ;; (refs nil) (save-excursion (semantic-go-to-tag tag db) (setq scope (semantic-calculate-scope)) @@ -1250,11 +1251,12 @@ Use `semantic-analyze-current-tag' to debug this fcn." (reverse newparents))) (setq allhits (semantic--analyze-refs-full-lookup tag scope t))) - (setq refs (semantic-analyze-references (semantic-tag-name tag) - :tag tag - :tagdb db - :scope scope - :rawsearchdata allhits))))) + ;; (setq refs + (semantic-analyze-references (semantic-tag-name tag) + :tag tag + :tagdb db + :scope scope + :rawsearchdata allhits)))) ;;) (defun semantic-c-reconstitute-token (tokenpart declmods typedecl) "Reconstitute a token TOKENPART with DECLMODS and TYPEDECL. @@ -1540,9 +1542,9 @@ This might be a string, or a list of tokens." ((semantic-tag-p templatespec) (semantic-format-tag-abbreviate templatespec)) ((listp templatespec) - (mapconcat 'semantic-format-tag-abbreviate templatespec ", ")))) + (mapconcat #'semantic-format-tag-abbreviate templatespec ", ")))) -(defun semantic-c-template-string (token &optional parent color) +(defun semantic-c-template-string (token &optional parent _color) "Return a string representing the TEMPLATE attribute of TOKEN. This string is prefixed with a space, or is the empty string. Argument PARENT specifies a parent type. @@ -1550,8 +1552,8 @@ Argument COLOR specifies that the string should be colorized." (let ((t2 (semantic-c-tag-template-specifier token)) (t1 (semantic-c-tag-template token)) ;; @todo - Need to account for a parent that is a template - (pt1 (if parent (semantic-c-tag-template parent))) - (pt2 (if parent (semantic-c-tag-template-specifier parent))) + (_pt1 (if parent (semantic-c-tag-template parent))) + (_pt2 (if parent (semantic-c-tag-template-specifier parent))) ) (cond (t2 ;; we have a template with specifier (concat " <" @@ -1610,7 +1612,7 @@ handled. A class is abstract only if its destructor is virtual." (member "virtual" (semantic-tag-modifiers tag)))) (t (semantic-tag-abstract-p-default tag parent)))) -(defun semantic-c-dereference-typedef (type scope &optional type-declaration) +(defun semantic-c-dereference-typedef (type _scope &optional type-declaration) "If TYPE is a typedef, get TYPE's type by name or tag, and return. SCOPE is not used, and TYPE-DECLARATION is used only if TYPE is not a typedef." (if (and (eq (semantic-tag-class type) 'type) @@ -1655,7 +1657,7 @@ return `ref'." (concat (semantic-tag-name type) "<" (semantic-c--template-name-1 (cdr spec-list)) ">")) -(defun semantic-c-dereference-template (type scope &optional type-declaration) +(defun semantic-c-dereference-template (type _scope &optional type-declaration) "Dereference any template specifiers in TYPE within SCOPE. If TYPE is a template, return a TYPE copy with the templates types instantiated as specified in TYPE-DECLARATION." @@ -1677,7 +1679,7 @@ instantiated as specified in TYPE-DECLARATION." (list type type-declaration)) ;;; Patch here by "Raf" for instantiating templates. -(defun semantic-c-dereference-member-of (type scope &optional type-declaration) +(defun semantic-c-dereference-member-of (type _scope &optional type-declaration) "Dereference through the `->' operator of TYPE. Uses the return type of the `->' operator if it is contained in TYPE. SCOPE is the current local scope to perform searches in. @@ -1700,7 +1702,7 @@ Such an alias can be created through `using' statements in a namespace declaration. This function checks the namespaces in SCOPE for such statements." (let ((scopetypes (oref scope scopetypes)) - typename currentns tmp usingname result namespaces) + typename currentns result namespaces) ;; usingname tmp (when (and (semantic-tag-p type-declaration) (or (null type) (semantic-tag-prototype-p type))) (setq typename (semantic-analyze-split-name (semantic-tag-name type-declaration))) @@ -1739,11 +1741,11 @@ with a fully qualified name in the original namespace. Returns nil if NAMESPACE is not an alias." (when (eq (semantic-tag-get-attribute namespace :kind) 'alias) (let ((typename (semantic-analyze-split-name (semantic-tag-name type))) - ns nstype originaltype newtype) + ns nstype originaltype) ;; newtype ;; Make typename unqualified - (if (listp typename) - (setq typename (last typename)) - (setq typename (list typename))) + (setq typename (if (listp typename) + (last typename) + (list typename))) (when (and ;; Get original namespace and make sure TYPE exists there. @@ -1755,13 +1757,13 @@ nil if NAMESPACE is not an alias." (semantic-tag-get-attribute nstype :members)))) ;; Construct new type with name in original namespace. (setq ns (semantic-analyze-split-name ns)) - (setq newtype - (semantic-tag-clone - (car originaltype) - (semantic-analyze-unsplit-name - (if (listp ns) - (append ns typename) - (append (list ns) typename))))))))) + ;; (setq newtype + (semantic-tag-clone + (car originaltype) + (semantic-analyze-unsplit-name + (if (listp ns) + (append ns typename) + (append (list ns) typename)))))))) ;; ) ;; This searches a type in a namespace, following through all using ;; statements. @@ -1769,7 +1771,7 @@ nil if NAMESPACE is not an alias." "Check if TYPE is accessible in NAMESPACE through a using statement. Returns the original type from the namespace where it is defined, or nil if it cannot be found." - (let (usings result usingname usingtype unqualifiedname members shortname tmp) + (let (usings result usingname usingtype unqualifiedname members) ;; shortname tmp ;; Get all using statements from NAMESPACE. (when (and (setq usings (semantic-tag-get-attribute namespace :members)) (setq usings (semantic-find-tags-by-class 'using usings))) @@ -1842,7 +1844,7 @@ These are constants which are of type TYPE." (define-mode-local-override semantic-analyze-unsplit-name c-mode (namelist) "Assemble the list of names NAMELIST into a namespace name." - (mapconcat 'identity namelist "::")) + (mapconcat #'identity namelist "::")) (define-mode-local-override semantic-ctxt-scoped-types c++-mode (&optional point) "Return a list of tags of CLASS type based on POINT. @@ -1885,7 +1887,7 @@ DO NOT return the list of tags encompassing point." (semantic-get-local-variables)))) (setq tagreturn (append tagreturn - (mapcar 'semantic-tag-type tmp)))))) + (mapcar #'semantic-tag-type tmp)))))) ;; Return the stuff tagreturn)) @@ -1943,7 +1945,7 @@ namespace, since this means all tags inside this include will have to be wrapped in that namespace." (let ((inctable (semanticdb-find-table-for-include-default includetag table)) (inside-ns (semantic-tag-get-attribute includetag :inside-ns)) - tags newtags namespaces prefix parenttable newtable) + tags newtags namespaces parenttable newtable) ;; prefix (if (or (null inside-ns) (not inctable) (not (slot-boundp inctable 'tags))) @@ -2111,13 +2113,11 @@ actually in their parent which is not accessible.") "Set up a buffer for semantic parsing of the C language." (semantic-c-by--install-parser) (setq semantic-lex-syntax-modifications '((?> ".") - (?< ".") - ) - ) + (?< "."))) (setq semantic-lex-analyzer #'semantic-c-lexer) - (add-hook 'semantic-lex-reset-functions 'semantic-lex-spp-reset-hook nil t) - (when (eq major-mode 'c++-mode) + (add-hook 'semantic-lex-reset-functions #'semantic-lex-spp-reset-hook nil t) + (when (derived-mode-p 'c++-mode) (add-to-list 'semantic-lex-c-preprocessor-symbol-map '("__cplusplus" . ""))) ) @@ -2142,7 +2142,7 @@ actually in their parent which is not accessible.") (defun semantic-c-describe-environment () "Describe the Semantic features of the current C environment." (interactive) - (if (not (member 'c-mode (mode-local-equivalent-mode-p major-mode))) + (if (not (derived-mode-p 'c-mode)) (error "Not useful to query C mode in %s mode" major-mode)) (let ((gcc (when (boundp 'semantic-gcc-setup-data) semantic-gcc-setup-data)) diff --git a/lisp/cedet/semantic/bovine/debug.el b/lisp/cedet/semantic/bovine/debug.el index 8ea9ac2442..47850a5d1f 100644 --- a/lisp/cedet/semantic/bovine/debug.el +++ b/lisp/cedet/semantic/bovine/debug.el @@ -1,4 +1,4 @@ -;;; semantic/bovine/debug.el --- Debugger support for bovinator +;;; semantic/bovine/debug.el --- Debugger support for bovinator -*- lexical-binding: t; -*- ;; Copyright (C) 2003, 2009-2021 Free Software Foundation, Inc. @@ -123,7 +123,7 @@ Argument CONDITION is the thrown error condition." frame) frame)) -(cl-defmethod semantic-debug-frame-highlight ((frame semantic-bovine-debug-error-frame)) +(cl-defmethod semantic-debug-frame-highlight ((_frame semantic-bovine-debug-error-frame)) "Highlight a frame from an action." ;; How do I get the location of the action in the source buffer? ) diff --git a/lisp/cedet/semantic/bovine/el.el b/lisp/cedet/semantic/bovine/el.el index 4d94d34323..1170e71687 100644 --- a/lisp/cedet/semantic/bovine/el.el +++ b/lisp/cedet/semantic/bovine/el.el @@ -940,7 +940,7 @@ ELisp variables can be pretty long, so track this one too.") ;; loaded into Emacs. ) -(add-hook 'emacs-lisp-mode-hook 'semantic-default-elisp-setup) +(add-hook 'emacs-lisp-mode-hook #'semantic-default-elisp-setup) ;;; LISP MODE ;; @@ -950,7 +950,7 @@ ELisp variables can be pretty long, so track this one too.") ;; See this syntax: ;; (defun foo () /#A) ;; -(add-hook 'lisp-mode-hook 'semantic-default-elisp-setup) +(add-hook 'lisp-mode-hook #'semantic-default-elisp-setup) (eval-after-load "semantic/db" '(require 'semantic/db-el) diff --git a/lisp/cedet/semantic/bovine/gcc.el b/lisp/cedet/semantic/bovine/gcc.el index c2121e5d58..02bd0defef 100644 --- a/lisp/cedet/semantic/bovine/gcc.el +++ b/lisp/cedet/semantic/bovine/gcc.el @@ -47,11 +47,11 @@ to give to the program." (erase-buffer) (setenv "LC_ALL" "C") (condition-case nil - (setq err (apply 'call-process gcc-cmd options)) + (setq err (apply #'call-process gcc-cmd options)) (error ;; Some bogus directory for the first time perhaps? (let ((default-directory (expand-file-name "~/"))) (condition-case nil - (setq err (apply 'call-process gcc-cmd options)) + (setq err (apply #'call-process gcc-cmd options)) (error ;; gcc doesn't exist??? nil))))) (setenv "LC_ALL" old-lc-messages) @@ -151,12 +151,12 @@ It should also include other symbols GCC was compiled with.") (let* ((fields (or semantic-gcc-setup-data (semantic-gcc-fields (semantic-gcc-query "gcc" "-v")))) (cpp-options `("-E" "-dM" "-x" "c++" ,null-device)) - (query (let ((q (apply 'semantic-gcc-query "cpp" cpp-options))) + (query (let ((q (apply #'semantic-gcc-query "cpp" cpp-options))) (if (stringp q) q ;; `cpp' command in `semantic-gcc-setup' doesn't work on ;; Mac, try `gcc'. - (apply 'semantic-gcc-query "gcc" cpp-options)))) + (apply #'semantic-gcc-query "gcc" cpp-options)))) (defines (if (stringp query) (semantic-cpp-defs query) (message (concat "Could not query gcc for defines. " diff --git a/lisp/cedet/semantic/bovine/make.el b/lisp/cedet/semantic/bovine/make.el index 8089556527..2c9b78f9dd 100644 --- a/lisp/cedet/semantic/bovine/make.el +++ b/lisp/cedet/semantic/bovine/make.el @@ -1,4 +1,4 @@ -;;; semantic/bovine/make.el --- Makefile parsing rules. +;;; semantic/bovine/make.el --- Makefile parsing rules. -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2004, 2008-2021 Free Software Foundation, Inc. @@ -103,13 +103,13 @@ Ignore them." xpand)) (define-mode-local-override semantic-get-local-variables - makefile-mode (&optional point) + makefile-mode (&optional _point) "Override `semantic-get-local-variables' so it does not throw an error. We never have local variables in Makefiles." nil) (define-mode-local-override semantic-ctxt-current-class-list - makefile-mode (&optional point) + makefile-mode (&optional _point) "List of classes that are valid to place at point." (let ((tag (semantic-current-tag))) (when tag @@ -176,7 +176,7 @@ This is the same as a regular prototype." (semantic-format-tag-prototype tag parent color)) (define-mode-local-override semantic-analyze-possible-completions - makefile-mode (context &rest flags) + makefile-mode (context &rest _flags) "Return a list of possible completions in a Makefile. Uses default implementation, and also gets a list of filenames." (require 'semantic/analyze/complete) diff --git a/lisp/cedet/semantic/bovine/scm.el b/lisp/cedet/semantic/bovine/scm.el index aaa86a1e36..939348ef4a 100644 --- a/lisp/cedet/semantic/bovine/scm.el +++ b/lisp/cedet/semantic/bovine/scm.el @@ -1,4 +1,4 @@ -;;; semantic/bovine/scm.el --- Semantic details for Scheme (guile) +;;; semantic/bovine/scm.el --- Semantic details for Scheme (guile) -*- lexical-binding: t; -*- ;;; Copyright (C) 2001-2004, 2008-2021 Free Software Foundation, Inc. @@ -49,7 +49,7 @@ actually on the local machine.") ")") (semantic-format-tag-prototype-default tag parent color)))) -(define-mode-local-override semantic-documentation-for-tag scheme-mode (tag &optional nosnarf) +(define-mode-local-override semantic-documentation-for-tag scheme-mode (tag &optional _nosnarf) "Return the documentation string for TAG. Optional argument NOSNARF is ignored." (let ((d (semantic-tag-docstring tag))) @@ -57,7 +57,7 @@ Optional argument NOSNARF is ignored." (substring d 1) d))) -(define-mode-local-override semantic-insert-foreign-tag scheme-mode (tag tagfile) +(define-mode-local-override semantic-insert-foreign-tag scheme-mode (tag _tagfile) "Insert TAG from TAGFILE at point. Attempts a simple prototype for calling or using TAG." (cond ((eq (semantic-tag-class tag) 'function) diff --git a/lisp/cedet/semantic/lex.el b/lisp/cedet/semantic/lex.el index b3399aa2e6..29d8e29ae6 100644 --- a/lisp/cedet/semantic/lex.el +++ b/lisp/cedet/semantic/lex.el @@ -1098,26 +1098,21 @@ at the beginning of `semantic-lex-token-stream'. This can be done by using `semantic-lex-push-token'." (declare (debug (&define name stringp form def-body))) `(eval-and-compile - (defvar ,name nil ,doc) - (defun ,name nil) - ;; Do this part separately so that re-evaluation rebuilds this code. - (setq ,name '(,condition ,@forms)) + ;; This is the real info used by `define-lex' (via semantic-lex-one-token). + (defconst ,name '(,condition ,@forms) ,doc) ;; Build a single lexical analyzer function, so the doc for ;; function help is automatically provided, and perhaps the ;; function could be useful for testing and debugging one ;; analyzer. - (fset ',name (lambda () ,doc - (let ((semantic-lex-token-stream nil) - (semantic-lex-end-point (point)) - (semantic-lex-analysis-bounds - (cons (point) (point-max))) - (semantic-lex-current-depth 0) - (semantic-lex-maximum-depth - semantic-lex-depth) - ) - (when ,condition ,@forms) - semantic-lex-token-stream))) - )) + (defun ,name () + ,doc + (let ((semantic-lex-token-stream nil) + (semantic-lex-end-point (point)) + (semantic-lex-analysis-bounds (cons (point) (point-max))) + (semantic-lex-current-depth 0) + (semantic-lex-maximum-depth semantic-lex-depth)) + (when ,condition ,@forms) + semantic-lex-token-stream)))) (defmacro define-lex-regex-analyzer (name doc regexp &rest forms) "Create a lexical analyzer with NAME and DOC that will match REGEXP. commit b8b05fff1b3d6a515bdaa9dc069c0e29f4d0ef8b Author: Stefan Monnier Date: Sat Mar 6 21:57:02 2021 -0500 * lisp/obsolete/inversion.el: Use lexical-binding diff --git a/lisp/obsolete/inversion.el b/lisp/obsolete/inversion.el index f192d88868..192186ee3b 100644 --- a/lisp/obsolete/inversion.el +++ b/lisp/obsolete/inversion.el @@ -1,4 +1,4 @@ -;;; inversion.el --- When you need something in version XX.XX +;;; inversion.el --- When you need something in version XX.XX -*- lexical-binding: t; -*- ;;; Copyright (C) 2002-2003, 2005-2021 Free Software Foundation, Inc. @@ -223,7 +223,7 @@ not an indication of new features or bug fixes." ))) (defun inversion-check-version (version incompatible-version - minimum &rest reserved) + minimum &rest _reserved) "Check that a given version meets the minimum requirement. VERSION, INCOMPATIBLE-VERSION and MINIMUM are of similar format to return entries of `inversion-decode-version', or a classic version @@ -330,7 +330,7 @@ Return nil if everything is ok. Return an error string otherwise." (t "Inversion version check failed.")))) (defun inversion-require (package version &optional file directory - &rest reserved) + &rest _reserved) "Declare that you need PACKAGE with at least VERSION. PACKAGE might be found in FILE. (See `require'.) Throws an error if VERSION is incompatible with what is installed. commit 3c6d087def3daafce27ee2e4108b025d44826e90 Author: Glenn Morris Date: Sat Mar 6 16:39:04 2021 -0800 * admin/admin.el (make-manuals-dist-output-variables): Update. diff --git a/admin/admin.el b/admin/admin.el index 203cf10687..e3701070d0 100644 --- a/admin/admin.el +++ b/admin/admin.el @@ -665,7 +665,7 @@ style=\"text-align:left\">") (defconst make-manuals-dist-output-variables '(("@\\(top_\\)?srcdir@" . ".") ; top_srcdir is wrong, but not used - ("@abs_top_builddir@" . ".") ; wrong but unused + ("@\\(abs_\\)?top_builddir@" . ".") ; wrong but unused ("^\\(EMACS *=\\).*" . "\\1 emacs") ("^\\(\\(?:texinfo\\|buildinfo\\|emacs\\)dir *=\\).*" . "\\1 .") ("^\\(clean:.*\\)" . "\\1 infoclean") @@ -684,9 +684,7 @@ style=\"text-align:left\">") ("@INSTALL@" . "install -c") ("@INSTALL_DATA@" . "${INSTALL} -m 644") ("@configure_input@" . "") - ("@AM_DEFAULT_VERBOSITY@" . "0") - ("@AM_V@" . "${V}") - ("@AM_DEFAULT_V@" . "${AM_DEFAULT_VERBOSITY}")) + ("@AM_DEFAULT_VERBOSITY@" . "0")) "Alist of (REGEXP . REPLACEMENT) pairs for `make-manuals-dist'.") (defun make-manuals-dist--1 (root type) commit d632622b5aac5ff776e1b5048f29aeaf3ceaf553 Author: Glenn Morris Date: Sat Mar 6 16:28:46 2021 -0800 Simplify silent-rules build machinery * src/verbose.mk.in: New file. * configure.ac (AM_V, AM_DEFAULT_V): Remove output variables. (src/verbose.mk): New output file. * Makefile.in, admin/charsets/Makefile.in: * admin/grammars/Makefile.in, admin/unidata/Makefile.in: * doc/emacs/Makefile.in, doc/lispintro/Makefile.in: * doc/lispref/Makefile.in, doc/misc/Makefile.in, leim/Makefile.in: * lib-src/Makefile.in, lib/Makefile.in, lisp/Makefile.in: * lwlib/Makefile.in, nt/Makefile.in, oldXMenu/Makefile.in: * src/Makefile.in, src/verbose.mk.in, test/Makefile.in: Include src/verbose.mk rather than repeatedly defining AM_V_at etc. diff --git a/.gitignore b/.gitignore index ba8a65547f..b653ef215b 100644 --- a/.gitignore +++ b/.gitignore @@ -76,6 +76,7 @@ lib/unistd.h src/buildobj.h src/globals.h src/lisp.mk +src/verbose.mk # Lisp-level sources built by 'make'. *cus-load.el diff --git a/Makefile.in b/Makefile.in index 46373190a6..6acf9791ab 100644 --- a/Makefile.in +++ b/Makefile.in @@ -95,18 +95,8 @@ configuration=@configuration@ ### The nt/ subdirectory gets built only for MinGW NTDIR=@NTDIR@ -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +top_builddir = @top_builddir@ +-include ${top_builddir}/src/verbose.mk # ==================== Where To Install Things ==================== diff --git a/admin/charsets/Makefile.in b/admin/charsets/Makefile.in index 0fd130d346..1fe029984b 100644 --- a/admin/charsets/Makefile.in +++ b/admin/charsets/Makefile.in @@ -31,6 +31,7 @@ AWK = @AWK@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ charsetdir = ${top_srcdir}/etc/charsets lispintdir = ${top_srcdir}/lisp/international @@ -38,16 +39,7 @@ mapfiledir = ${srcdir}/mapfiles GLIBC_CHARMAPS = ${srcdir}/glibc -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +-include ${top_builddir}/src/verbose.mk # Note: We can not prepend "ISO-" to these map files because of file # name limits on DOS. diff --git a/admin/grammars/Makefile.in b/admin/grammars/Makefile.in index 98c9c623ab..aa09d9edf9 100644 --- a/admin/grammars/Makefile.in +++ b/admin/grammars/Makefile.in @@ -28,18 +28,7 @@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = @top_builddir@ -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +-include ${top_builddir}/src/verbose.mk # Prevent any settings in the user environment causing problems. unexport EMACSDATA EMACSDOC EMACSPATH diff --git a/admin/unidata/Makefile.in b/admin/unidata/Makefile.in index f31e1bb09f..183569fb9b 100644 --- a/admin/unidata/Makefile.in +++ b/admin/unidata/Makefile.in @@ -36,23 +36,7 @@ emacs = "${EMACS}" -batch --no-site-file --no-site-lisp lparen = ( unifiles = $(addprefix ${unidir}/,$(sort $(shell sed -n 's/^[ \t][ \t]*${lparen}"\(uni-[^"]*\)"$$/\1/p' ${srcdir}/unidata-gen.el))) -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_ELC = $(am__v_ELC_@AM_V@) -am__v_ELC_ = $(am__v_ELC_@AM_DEFAULT_V@) -am__v_ELC_0 = @echo " ELC " $@; -am__v_ELC_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +-include ${top_builddir}/src/verbose.mk .PHONY: all diff --git a/configure.ac b/configure.ac index 385a126dd3..1802c1baa1 100644 --- a/configure.ac +++ b/configure.ac @@ -1184,9 +1184,6 @@ AC_DEFUN([AM_CONDITIONAL], dnl Prefer silent make output. For verbose output, use dnl 'configure --disable-silent-rules' or 'make V=1' . -dnl This code is adapted from Automake. -dnl Although it can be simplified now that GNU Make is assumed, -dnl the simplification hasn't been done yet. AC_ARG_ENABLE([silent-rules], [AS_HELP_STRING( [--disable-silent-rules], @@ -1196,11 +1193,8 @@ if test "$enable_silent_rules" = no; then else AM_DEFAULT_VERBOSITY=0 fi -AM_V='$(V)' -AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -AC_SUBST([AM_V]) -AC_SUBST([AM_DEFAULT_V]) AC_SUBST([AM_DEFAULT_VERBOSITY]) +AC_CONFIG_FILES([src/verbose.mk]) dnl Some other nice autoconf tests. AC_PROG_INSTALL diff --git a/doc/emacs/Makefile.in b/doc/emacs/Makefile.in index 2a3f53f740..4585b2e0dd 100644 --- a/doc/emacs/Makefile.in +++ b/doc/emacs/Makefile.in @@ -28,6 +28,8 @@ srcdir=@srcdir@ top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ + version = @version@ ## Where the output files go. @@ -73,13 +75,7 @@ TEXI2DVI = texi2dvi TEXI2PDF = texi2pdf DVIPS = dvips -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = +-include ${top_builddir}/src/verbose.mk ENVADD = $(AM_V_GEN)TEXINPUTS="$(srcdir):$(texinfodir):$(TEXINPUTS)" \ MAKEINFO="$(MAKEINFO) $(MAKEINFO_OPTS)" diff --git a/doc/lispintro/Makefile.in b/doc/lispintro/Makefile.in index d8b909c9c1..45b4fe7e3b 100644 --- a/doc/lispintro/Makefile.in +++ b/doc/lispintro/Makefile.in @@ -20,6 +20,7 @@ SHELL = @SHELL@ srcdir = @srcdir@ +top_builddir = @top_builddir@ buildinfodir = $(srcdir)/../../info # Directory with the (customized) texinfo.tex file. @@ -55,13 +56,7 @@ TEXI2DVI = texi2dvi TEXI2PDF = texi2pdf DVIPS = dvips -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = +-include ${top_builddir}/src/verbose.mk ENVADD = \ $(AM_V_GEN)TEXINPUTS="$(srcdir):$(texinfodir):$(emacsdir):$(TEXINPUTS)" \ diff --git a/doc/lispref/Makefile.in b/doc/lispref/Makefile.in index 271f06eddd..876303593c 100644 --- a/doc/lispref/Makefile.in +++ b/doc/lispref/Makefile.in @@ -24,6 +24,7 @@ SHELL = @SHELL@ # Standard configure variables. srcdir = @srcdir@ +top_builddir = @top_builddir@ buildinfodir = $(srcdir)/../../info # Directory with the (customized) texinfo.tex file. @@ -59,13 +60,7 @@ TEXI2DVI = texi2dvi TEXI2PDF = texi2pdf DVIPS = dvips -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = +-include ${top_builddir}/src/verbose.mk ENVADD = \ $(AM_V_GEN)TEXINPUTS="$(srcdir):$(texinfodir):$(emacsdir):$(TEXINPUTS)" \ diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in index 87d87bf200..5130650fef 100644 --- a/doc/misc/Makefile.in +++ b/doc/misc/Makefile.in @@ -23,6 +23,8 @@ SHELL = @SHELL@ # of the source tree. This is set by configure's '--srcdir' option. srcdir=@srcdir@ +top_builddir = @top_builddir@ + ## Where the output files go. ## Note that all the Info targets build the Info files in srcdir. ## There is no provision for Info files to exist in the build directory. @@ -112,13 +114,7 @@ TEXI2DVI = texi2dvi TEXI2PDF = texi2pdf DVIPS = dvips -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = +-include ${top_builddir}/src/verbose.mk ENVADD = $(AM_V_GEN)TEXINPUTS="$(srcdir):$(emacsdir):$(TEXINPUTS)" \ MAKEINFO="$(MAKEINFO) $(MAKEINFO_OPTS)" diff --git a/leim/Makefile.in b/leim/Makefile.in index f3e530a11d..c2f9cf5ab5 100644 --- a/leim/Makefile.in +++ b/leim/Makefile.in @@ -25,24 +25,14 @@ SHELL = @SHELL@ # Here are the things that we expect ../configure to edit. srcdir=@srcdir@ +top_builddir = @top_builddir@ # Where the generated files go. leimdir = ${srcdir}/../lisp/leim EXEEXT = @EXEEXT@ -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +-include ${top_builddir}/src/verbose.mk # Prevent any settings in the user environment causing problems. unexport EMACSDATA EMACSDOC EMACSPATH diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in index 0a6dd826c1..05eb524d19 100644 --- a/lib-src/Makefile.in +++ b/lib-src/Makefile.in @@ -44,33 +44,8 @@ WERROR_CFLAGS = @WERROR_CFLAGS@ # Program name transformation. TRANSFORM = @program_transform_name@ -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = - -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_RC = $(am__v_RC_@AM_V@) -am__v_RC_ = $(am__v_RC_@AM_DEFAULT_V@) -am__v_RC_0 = @echo " RC " $@; -am__v_RC_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +top_builddir = @top_builddir@ +-include ${top_builddir}/src/verbose.mk # ==================== Where To Install Things ==================== diff --git a/lib/Makefile.in b/lib/Makefile.in index 91a6b5ff3f..043ace29fd 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -29,26 +29,7 @@ top_srcdir = @top_srcdir@ all: .PHONY: all -# 'make' verbosity. -AM_V_AR = $(am__v_AR_@AM_V@) -am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) -am__v_AR_0 = @echo " AR " $@; -am__v_AR_1 = - -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +-include ${top_builddir}/src/verbose.mk ALL_CFLAGS= \ $(C_SWITCH_SYSTEM) $(C_SWITCH_MACHINE) $(DEPFLAGS) \ diff --git a/lisp/Makefile.in b/lisp/Makefile.in index 72f7f1676b..8ea2841558 100644 --- a/lisp/Makefile.in +++ b/lisp/Makefile.in @@ -21,6 +21,7 @@ SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ lisp = $(srcdir) VPATH = $(srcdir) EXEEXT = @EXEEXT@ @@ -29,24 +30,7 @@ EXEEXT = @EXEEXT@ # limitation. XARGS_LIMIT = @XARGS_LIMIT@ -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_ELC = $(am__v_ELC_@AM_V@) -am__v_ELC_ = $(am__v_ELC_@AM_DEFAULT_V@) -am__v_ELC_0 = @echo " ELC " $@; -am__v_ELC_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = - +-include ${top_builddir}/src/verbose.mk FIND_DELETE = @FIND_DELETE@ diff --git a/lwlib/Makefile.in b/lwlib/Makefile.in index 28c16acbab..fb0ae0e1c2 100644 --- a/lwlib/Makefile.in +++ b/lwlib/Makefile.in @@ -26,6 +26,7 @@ all: liblw.a .PHONY: all srcdir=@srcdir@ +top_builddir=@top_builddir@ # MinGW CPPFLAGS may use this. abs_top_srcdir=@abs_top_srcdir@ VPATH=@srcdir@ @@ -56,23 +57,7 @@ TOOLKIT_OBJS = $(@X_TOOLKIT_TYPE@_OBJS) OBJS = lwlib.o $(TOOLKIT_OBJS) lwlib-utils.o -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +-include ${top_builddir}/src/verbose.mk AUTO_DEPEND = @AUTO_DEPEND@ DEPDIR = deps diff --git a/nt/Makefile.in b/nt/Makefile.in index aa3a76280e..0d448903ba 100644 --- a/nt/Makefile.in +++ b/nt/Makefile.in @@ -41,23 +41,8 @@ WERROR_CFLAGS = @WERROR_CFLAGS@ # Program name transformation. TRANSFORM = @program_transform_name@ -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = - -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = - -AM_V_RC = $(am__v_RC_@AM_V@) -am__v_RC_ = $(am__v_RC_@AM_DEFAULT_V@) -am__v_RC_0 = @echo " RC " $@; -am__v_RC_1 = +top_builddir = @top_builddir@ +-include ${top_builddir}/src/verbose.mk # ==================== Where To Install Things ==================== diff --git a/oldXMenu/Makefile.in b/oldXMenu/Makefile.in index 7ae355b568..39fd155735 100644 --- a/oldXMenu/Makefile.in +++ b/oldXMenu/Makefile.in @@ -43,6 +43,7 @@ ### Code: srcdir=@srcdir@ +top_builddir = @top_builddir@ # MinGW CPPFLAGS may use this. abs_top_srcdir=@abs_top_srcdir@ VPATH=@srcdir@ @@ -93,23 +94,7 @@ OBJS = Activate.o \ all: libXMenu11.a .PHONY: all -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = +-include ${top_builddir}/src/verbose.mk AUTO_DEPEND = @AUTO_DEPEND@ DEPDIR = deps diff --git a/src/Makefile.in b/src/Makefile.in index a5ea5498a4..f3c545dba9 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -29,6 +29,7 @@ SHELL = @SHELL@ # We use $(srcdir) explicitly in dependencies so as not to depend on VPATH. srcdir = @srcdir@ top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ # MinGW CPPFLAGS may use this. abs_top_srcdir=@abs_top_srcdir@ VPATH = $(srcdir) @@ -340,33 +341,7 @@ HAVE_PDUMPER = @HAVE_PDUMPER@ ## invalidates the signature, we must re-sign to fix it. DO_CODESIGN=$(patsubst aarch64-apple-darwin%,yes,@configuration@) -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = - -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = - -AM_V_NO_PD = $(am__v_NO_PD_@AM_V@) -am__v_NO_PD_ = $(am__v_NO_PD_@AM_DEFAULT_V@) -am__v_NO_PD_0 = --no-print-directory -am__v_NO_PD_1 = +-include ${top_builddir}/src/verbose.mk bootstrap_exe = ../src/bootstrap-emacs$(EXEEXT) ifeq ($(DUMPING),pdumper) @@ -621,11 +596,6 @@ buildobj.h: Makefile GLOBAL_SOURCES = $(base_obj:.o=.c) $(NS_OBJC_OBJ:.o=.m) -AM_V_GLOBALS = $(am__v_GLOBALS_@AM_V@) -am__v_GLOBALS_ = $(am__v_GLOBALS_@AM_DEFAULT_V@) -am__v_GLOBALS_0 = @echo " GEN " globals.h; -am__v_GLOBALS_1 = - gl-stamp: $(libsrc)/make-docfile$(EXEEXT) $(GLOBAL_SOURCES) $(AM_V_GLOBALS)$(libsrc)/make-docfile -d $(srcdir) -g $(obj) > globals.tmp $(AM_V_at)$(top_srcdir)/build-aux/move-if-change globals.tmp globals.h @@ -724,7 +694,7 @@ bootstrap-clean: clean fi distclean: bootstrap-clean - rm -f Makefile lisp.mk + rm -f Makefile lisp.mk verbose.mk rm -fr $(DEPDIR) maintainer-clean: distclean diff --git a/src/verbose.mk.in b/src/verbose.mk.in new file mode 100644 index 0000000000..e55fd63fc3 --- /dev/null +++ b/src/verbose.mk.in @@ -0,0 +1,42 @@ +### verbose.mk --- Makefile fragment for GNU Emacs + +## Copyright (C) 2021 Free Software Foundation, Inc. + +## This file is part of GNU Emacs. + +## GNU Emacs is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## GNU Emacs is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with GNU Emacs. If not, see . + +# 'make' verbosity. +V = @AM_DEFAULT_VERBOSITY@ +ifeq (${V},1) +AM_V_AR = +AM_V_at = +AM_V_CC = +AM_V_CCLD = +AM_V_ELC = +AM_V_GEN = +AM_V_GLOBALS = +AM_V_NO_PD = +AM_V_RC = +else +AM_V_AR = @echo " AR " $@; +AM_V_at = @ +AM_V_CC = @echo " CC " $@; +AM_V_CCLD = @echo " CCLD " $@; +AM_V_ELC = @echo " ELC " $@; +AM_V_GEN = @echo " GEN " $@; +AM_V_GLOBALS = @echo " GEN " globals.h; +AM_V_NO_PD = --no-print-directory +AM_V_RC = @echo " RC " $@; +endif diff --git a/test/Makefile.in b/test/Makefile.in index 48bbe8712b..ba354289e2 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -32,6 +32,7 @@ SHELL = @SHELL@ srcdir = @srcdir@ abs_top_srcdir=@abs_top_srcdir@ +top_builddir = @top_builddir@ VPATH = $(srcdir) FIND_DELETE = @FIND_DELETE@ @@ -46,30 +47,7 @@ SO = @MODULES_SUFFIX@ SEPCHAR = @SEPCHAR@ - -# 'make' verbosity. -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = - -AM_V_ELC = $(am__v_ELC_@AM_V@) -am__v_ELC_ = $(am__v_ELC_@AM_DEFAULT_V@) -am__v_ELC_0 = @echo " ELC " $@; -am__v_ELC_1 = - -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = - -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = - +-include ${top_builddir}/src/verbose.mk # Load any GNU ELPA dependencies that are present, for optional tests. GNU_ELPA_DIRECTORY ?= $(srcdir)/../../elpa commit 9cbdf20316e1cec835a7dfe28877142e437976f4 Author: Glenn Morris Date: Sat Mar 6 11:37:11 2021 -0800 * src/Makefile.in (base_obj): Remove GMP_OBJ, undefined since 202007. diff --git a/src/Makefile.in b/src/Makefile.in index 4100edf471..a5ea5498a4 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -426,7 +426,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \ thread.o systhread.o \ $(if $(HYBRID_MALLOC),sheap.o) \ $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \ - $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ) $(GMP_OBJ) + $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ) obj = $(base_obj) $(NS_OBJC_OBJ) ## Object files used on some machine or other. commit f476e282d2420132aff38ba142feffbac011a321 Author: Glenn Morris Date: Sat Mar 6 11:09:19 2021 -0800 Don't pass implicit flags to sub-makes * Makefile.in (info_misc, uninstall, texi_misc): Don't pass any implicit make flags to sub-makes. Ref https://lists.gnu.org/r/help-make/2021-03/msg00007.html diff --git a/Makefile.in b/Makefile.in index 85d063d8f6..46373190a6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -658,7 +658,7 @@ install-info: info [ -f "$(DESTDIR)${infodir}/dir" ] || \ [ ! -f ${srcdir}/info/dir ] || \ ${INSTALL_DATA} ${srcdir}/info/dir "$(DESTDIR)${infodir}/dir"; \ - info_misc=`$(MAKE) --no-print-directory -s -C doc/misc echo-info`; \ + info_misc=`MAKEFLAGS= $(MAKE) --no-print-directory -s -C doc/misc echo-info`; \ cd ${srcdir}/info ; \ for elt in ${INFO_NONMISC} $${info_misc}; do \ for f in `ls $$elt $$elt-[1-9] $$elt-[1-9][0-9] 2>/dev/null`; do \ @@ -772,7 +772,7 @@ uninstall: uninstall-$(NTDIR) uninstall-doc done -rm -rf "$(DESTDIR)${libexecdir}/emacs/${version}" thisdir=`/bin/pwd`; \ - (info_misc=`$(MAKE) --no-print-directory -s -C doc/misc echo-info`; \ + (info_misc=`MAKEFLAGS= $(MAKE) --no-print-directory -s -C doc/misc echo-info`; \ if cd "$(DESTDIR)${infodir}"; then \ for elt in ${INFO_NONMISC} $${info_misc}; do \ (cd "$${thisdir}"; \ @@ -1001,7 +1001,7 @@ misc-dvi misc-html misc-pdf misc-ps: src info-dir: ${srcdir}/info/dir -texi_misc = $(shell ${MAKE} --no-print-directory -s -C doc/misc echo-sources) +texi_misc = $(shell MAKEFLAGS= ${MAKE} --no-print-directory -s -C doc/misc echo-sources) srcdir_doc_info_dir_inputs = \ ${srcdir}/doc/emacs/emacs.texi \ commit c3cf99f53714ce1227ab508c9e359910a963659e Author: Glenn Morris Date: Sat Mar 6 10:38:07 2021 -0800 Remove the --without-makeinfo configure option (bug#46837) * configure.ac (--without-makeinfo): Remove option. (HAVE_MAKEINFO): Remove output variable. * Makefile.in (HAVE_MAKEINFO): Remove. (info_misc): Remove HAVE_MAKEINFO check. (info-real): Remove target. (info): Simplify. ; * etc/NEWS: Mention this. diff --git a/Makefile.in b/Makefile.in index 856c29a453..85d063d8f6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -166,9 +166,6 @@ infodir=@infodir@ # Info files not in the doc/misc directory (we get those via make echo-info). INFO_NONMISC=emacs.info eintr.info elisp.info -# If no makeinfo was found and configured --without-makeinfo, "no"; else "yes". -HAVE_MAKEINFO=@HAVE_MAKEINFO@ - # Directory for local state files for all programs. localstatedir=@localstatedir@ @@ -650,9 +647,6 @@ install-etcdoc: src install-arch-indep ## If info/dir is missing, but we have install-info, we should let ## that handle it. If info/dir is present and we do not have install-info, ## we should check for missing entries and add them by hand. -## -## FIXME: -## If HAVE_MAKEINFO = no and there are no info files, do not install info/dir. install-info: info umask 022; ${MKDIR_P} "$(DESTDIR)${infodir}" -unset CDPATH; \ @@ -667,7 +661,6 @@ install-info: info info_misc=`$(MAKE) --no-print-directory -s -C doc/misc echo-info`; \ cd ${srcdir}/info ; \ for elt in ${INFO_NONMISC} $${info_misc}; do \ - test "$(HAVE_MAKEINFO)" = "no" && test ! -f $$elt && continue; \ for f in `ls $$elt $$elt-[1-9] $$elt-[1-9][0-9] 2>/dev/null`; do \ (cd "$${thisdir}"; \ ${INSTALL_DATA} ${srcdir}/info/$$f "$(DESTDIR)${infodir}/$$f"); \ @@ -987,13 +980,13 @@ $(DOCS): $(MAKE) -C doc/$(subst -, ,$@) .PHONY: $(DOCS) docs pdf ps -.PHONY: info dvi dist html info-real info-dir check-info +.PHONY: info dvi dist html info-dir check-info ## TODO add etc/refcards. docs: $(DOCS) dvi: $(DVIS) html: $(HTMLS) -info-real: $(INFOS) +info: $(INFOS) info-dir pdf: $(PDFS) ps: $(PSS) @@ -1027,7 +1020,7 @@ info_dir_deps = \ ## installation location by the install-info rule, but we also ## need one in the source directory for people running uninstalled. ## FIXME it would be faster to use the install-info program if we have it, -## but then we would need to depend on info-real, which would +## but then we would need to depend on ${INFOS}, which would ## slow down parallelization. ${srcdir}/info/dir: ${info_dir_deps} $(AM_V_at)${MKDIR_P} ${srcdir}/info @@ -1082,24 +1075,6 @@ uninstall-html: $(UNINSTALL_HTML) uninstall-pdf: $(UNINSTALL_PDF) uninstall-ps: $(UNINSTALL_PS) - -# Note that man/Makefile knows how to put the info files in $(srcdir), -# so we can do ok running make in the build dir. -# This used to have a clause that exited with an error if MAKEINFO = no. -# But it is inappropriate to do so without checking if makeinfo is -# actually needed - it is not if the info files are up-to-date. (Bug#3982) -# Only the doc/*/Makefiles can decide that, so we let those rules run -# and give a standard error if makeinfo is needed but missing. -# While it would be nice to give a more detailed error message, that -# would require changing every rule in doc/ that builds an info file, -# and it's not worth it. This case is only relevant if you download a -# release, then change the .texi files. -ifneq ($(HAVE_MAKEINFO),no) -info: info-real info-dir -else -info: -endif - ## build-aux/make-info-dir expects only certain dircategories. check-info: info cd info ; \ diff --git a/configure.ac b/configure.ac index 11a06a39be..385a126dd3 100644 --- a/configure.ac +++ b/configure.ac @@ -506,11 +506,6 @@ otherwise for the first of 'inotify', 'kqueue' or 'gfile' that is usable.]) OPTION_DEFAULT_OFF([xwidgets], [enable use of xwidgets in Emacs buffers (requires gtk3 or macOS Cocoa)]) -## For the times when you want to build Emacs but don't have -## a suitable makeinfo, and can live without the manuals. -dnl https://lists.gnu.org/r/emacs-devel/2008-04/msg01844.html -OPTION_DEFAULT_ON([makeinfo],[don't require makeinfo for building manuals]) - ## Makefile.in needs the cache file name. AC_SUBST(cache_file) @@ -1344,14 +1339,13 @@ if test -n "$BREW"; then fi ## Require makeinfo >= 4.13 (last of the 4.x series) to build the manuals. -if test "${MAKEINFO:=makeinfo}" != "no"; then - case `($MAKEINFO --version) 2>/dev/null` in - *' (GNU texinfo) '4.1[[3-9]]* | \ - *' (GNU texinfo) '[[5-9]]* | \ - *' (GNU texinfo) '[[1-9][0-9]]* ) ;; - *) MAKEINFO=no;; - esac -fi +: ${MAKEINFO:=makeinfo} +case `($MAKEINFO --version) 2>/dev/null` in + *' (GNU texinfo) '4.1[[3-9]]* | \ + *' (GNU texinfo) '[[5-9]]* | \ + *' (GNU texinfo) '[[1-9][0-9]]* ) ;; + *) MAKEINFO=no;; +esac ## Makeinfo is unusual. For a released Emacs, the manuals are ## pre-built, and not deleted by the normal clean rules. makeinfo is @@ -1362,21 +1356,19 @@ fi ## should test for it as it does for any other build requirement. ## We use the presence of $srcdir/info/emacs to distinguish a release, ## with pre-built manuals, from a repository checkout. -HAVE_MAKEINFO=yes - if test "$MAKEINFO" = "no"; then MAKEINFO=makeinfo - if test "x${with_makeinfo}" = "xno"; then - HAVE_MAKEINFO=no - elif test ! -e "$srcdir/info/emacs" && test ! -e "$srcdir/info/emacs.info"; then + if test ! -e "$srcdir/info/emacs" && test ! -e "$srcdir/info/emacs.info"; then AC_MSG_ERROR( [You do not seem to have makeinfo >= 4.13, and your source tree does not seem to have pre-built manuals in the 'info' directory. -Either install a suitable version of makeinfo, or re-run configure -with the '--without-makeinfo' option to build without the manuals.] ) +Please install a suitable version of makeinfo.] ) + else + AC_MSG_WARN( [You do not seem to have makeinfo >= 4.13. +You will not be able to rebuild the manuals if you delete them or change +their sources.] ) fi fi AC_SUBST([MAKEINFO]) -AC_SUBST(HAVE_MAKEINFO) if test $opsys = mingw32; then DOCMISC_W32=efaq-w32 diff --git a/etc/NEWS b/etc/NEWS index 2e0628b45e..d2b84d733d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -66,6 +66,12 @@ shaping, so 'configure' now recommends that combination. ** The ftx font backend driver has been removed. It was declared obsolete in Emacs 27.1. +--- +** The configure option '--without-makeinfo' has been removed. +This was only ever relevant when building from a repository checkout. +Please install makeinfo, or if all else fails run 'make lisp' instead +of 'make [all]'. + --- ** Support for building with '-fcheck-pointer-bounds' has been removed. GCC has withdrawn the '-fcheck-pointer-bounds' option and support for commit 8fc6810eb640ffe7af1885166814689f5b28a65e Author: Stefan Monnier Date: Sat Mar 6 13:31:58 2021 -0500 * lisp/cedet/srecode/compile.el: Fix last change (srecode-compile-inserter): Call `make-instance` properly. diff --git a/lisp/cedet/srecode/compile.el b/lisp/cedet/srecode/compile.el index 22cacab078..36df1da9e3 100644 --- a/lisp/cedet/srecode/compile.el +++ b/lisp/cedet/srecode/compile.el @@ -499,7 +499,7 @@ PROPS are additional properties that might need to be passed to the inserter constructor." ;;(message "Compile: %s %S" name props) (if (not key) - (make-instance 'srecode-template-inserter-variable name props) + (apply #'make-instance 'srecode-template-inserter-variable name props) (let ((classes (eieio-class-children 'srecode-template-inserter)) (new nil)) ;; Loop over the various subclasses and @@ -510,7 +510,7 @@ to the inserter constructor." (when (and (not (class-abstract-p (car classes))) (equal (oref-default (car classes) key) key)) ;; Create the new class, and apply state. - (setq new (apply (car classes) name props)) + (setq new (apply #'make-instance (car classes) name props)) (srecode-inserter-apply-state new STATE) ) (setq classes (cdr classes))) commit 428339e2316a552713b265193d6648125042cc98 Author: Basil L. Contovounesios Date: Sun Feb 21 20:10:08 2021 +0000 Speed up json.el encoding This replaces most json-encode-* functions with similar json--print-* counterparts that insert into the current buffer instead of returning a string (bug#46761). Some unused but useful json-encode-* functions are kept for backward compatibility and as a public API, and the rest are deprecated. * etc/NEWS: Announce obsoletions. * lisp/json.el: Document organization of library. Make subsection headings more consistent. (json--encoding-current-indentation): Rename... (json--print-indentation-prefix): ...to this, to reflect new use. (json--encode-stringlike, json--encode-alist): Rename... (json--print-stringlike, json--print-alist): ...to these, respectively, and encode argument into current buffer instead. All callers changed. (json--print-string, json--print-unordered-map, json--print-array) (json--print): New functions. (json-encode-string, json-encode-plist, json-encode-array) (json-encode): Use them, respectively. (json-encode-number, json-encode-hash-table): Mark as obsolete aliases of json-encode. (json-encode-key, json-encode-list): Mark as obsolete in preference for json-encode. (json--print-indentation-depth, json--print-keyval-separator): New variables. (json--with-output-to-string): New macro. (json--print-indentation, json--print-keyword, json--print-key) (json--print-pair, json--print-map, json--print-list): New functions. (json--with-indentation): Use json--print-indentation-depth to avoid unnecessary string allocation. (json-encoding-default-indentation, json-pretty-print-max-secs): Clarify docstrings. (json--escape, json--long-string-threshold, json--string-buffer): Remove; no longer used. * lisp/progmodes/js.el (js--js-encode-value): Replace json-encode-string and json-encode-number with json-encode. (js-eval-defun): Use json--print-list to avoid json-encode-list->insert roundtrip. * test/lisp/json-tests.el (test-json-encode-number) (test-json-encode-hash-table, test-json-encode-hash-table-pretty) (test-json-encode-hash-table-lisp-style) (test-json-encode-hash-table-sort, test-json-encode-list): Replace uses of obsolete functions with the equivalent use of json-encode. (test-json-encode-key): Suppress obsoletion warnings. (test-json-encode-string): Check that text properties are stripped. diff --git a/etc/NEWS b/etc/NEWS index 5487448eae..2e0628b45e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1559,6 +1559,16 @@ component are now rejected by 'json-read' and friends. This makes them more compliant with the JSON specification and consistent with the native JSON parsing functions. +--- +*** Some JSON encoding functions are now obsolete. +The functions 'json-encode-number', 'json-encode-hash-table', +'json-encode-key', and 'json-encode-list' are now obsolete. + +The first two are kept as aliases of 'json-encode', which should be +used instead. Uses of 'json-encode-list' should be changed to call +one of 'json-encode', 'json-encode-alist', 'json-encode-plist', or +'json-encode-array' instead. + ** xml.el *** XML serialization functions now reject invalid characters. diff --git a/lisp/json.el b/lisp/json.el index f20123fcfb..6677c3b1b3 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -40,6 +40,17 @@ ;; Similarly, since `false' and `null' are distinct in JSON, you can ;; distinguish them by binding `json-false' and `json-null' as desired. +;;; Organization: + +;; Historically json.el used the prefix `json-read-' for decoding and +;; the prefix `json-encode-' for encoding. Many of these definitions +;; are used by external packages since few were marked as internal. +;; Optimizing the encoder to manipulate a buffer rather than strings +;; while minimizing code duplication therefore necessitated a new +;; namespace `json--print-'. This rendered many encoding functions +;; obsolete and unused, but those considered externally useful are +;; kept for backward compatibility and as a public API. + ;;; History: ;; 2006-03-11 - Initial version. @@ -57,7 +68,7 @@ (require 'map) (require 'subr-x) -;; Parameters +;;;; Parameters (defvar json-object-type 'alist "Type to convert JSON objects to. @@ -102,13 +113,22 @@ this around your call to `json-read' instead of `setq'ing it.") "Value to use as an element separator when encoding.") (defvar json-encoding-default-indentation " " - "The default indentation level for encoding. + "String used for a single indentation level during encoding. +This value is repeated for each further nested element. +Used only when `json-encoding-pretty-print' is non-nil.") + +(defvar json--print-indentation-prefix "\n" + "String used to start indentation during encoding. Used only when `json-encoding-pretty-print' is non-nil.") -(defvar json--encoding-current-indentation "\n" - "Internally used to keep track of the current indentation level of encoding. +(defvar json--print-indentation-depth 0 + "Current indentation level during encoding. +Dictates repetitions of `json-encoding-default-indentation'. Used only when `json-encoding-pretty-print' is non-nil.") +(defvar json--print-keyval-separator ":" + "String used to separate key-value pairs during encoding.") + (defvar json-encoding-pretty-print nil "If non-nil, then the output of `json-encode' will be pretty-printed.") @@ -137,7 +157,7 @@ respectively, with no arguments.") -;;; Utilities +;;;; Utilities (define-obsolete-function-alias 'json-join #'string-join "28.1") @@ -169,18 +189,38 @@ destructively modify PLIST to produce the result." (setcdr (cdr plist) prev))) plist) +;; Encoder utilities + +(defmacro json--with-output-to-string (&rest body) + "Eval BODY in a temporary buffer bound to `standard-output'. +Return the resulting buffer contents as a string." + (declare (indent 0) (debug t)) + `(with-output-to-string + (with-current-buffer standard-output + ;; This affords decent performance gains. + (setq-local inhibit-modification-hooks t) + ,@body))) + (defmacro json--with-indentation (&rest body) - "Evaluate BODY with the correct indentation for JSON encoding. -This macro binds `json--encoding-current-indentation' according -to `json-encoding-pretty-print' around BODY." + "Eval BODY with the JSON encoding nesting incremented by one step. +This macro sets up appropriate variable bindings for +`json--print-indentation' to produce the correct indentation when +`json-encoding-pretty-print' is non-nil." (declare (debug t) (indent 0)) - `(let ((json--encoding-current-indentation - (if json-encoding-pretty-print - (concat json--encoding-current-indentation - json-encoding-default-indentation) - ""))) + `(let ((json--print-indentation-prefix + (if json-encoding-pretty-print json--print-indentation-prefix "")) + (json--print-keyval-separator (if json-encoding-pretty-print ": " ":")) + (json--print-indentation-depth (1+ json--print-indentation-depth))) ,@body)) +(defun json--print-indentation () + "Insert the current indentation for JSON encoding at point. +Has no effect if `json-encoding-pretty-print' is nil." + (when json-encoding-pretty-print + (insert json--print-indentation-prefix) + (dotimes (_ json--print-indentation-depth) + (insert json-encoding-default-indentation)))) + ;; Reader utilities (define-inline json-advance (&optional n) @@ -210,8 +250,6 @@ Signal `json-end-of-file' if called at the end of the buffer." ;; definition of whitespace in JSON. (inline-quote (skip-chars-forward "\t\n\r "))) - - ;; Error conditions (define-error 'json-error "Unknown JSON error") @@ -228,7 +266,7 @@ Signal `json-end-of-file' if called at the end of the buffer." -;;; Paths +;;;; Paths (defvar json--path '() "Keeps track of the path during recursive calls to `json-read'. @@ -283,7 +321,9 @@ element in a deeply nested structure." (when (plist-get path :path) path)))) -;;; Keywords + + +;;;; Keywords (defconst json-keywords '("true" "false" "null") "List of JSON keywords.") @@ -316,7 +356,13 @@ element in a deeply nested structure." ((eq keyword json-false) "false") ((eq keyword json-null) "null"))) -;;; Numbers +(defun json--print-keyword (keyword) + "Insert KEYWORD as a JSON value at point. +Return nil if KEYWORD is not recognized as a JSON keyword." + (prog1 (setq keyword (json-encode-keyword keyword)) + (and keyword (insert keyword)))) + +;;;; Numbers ;; Number parsing @@ -339,10 +385,9 @@ element in a deeply nested structure." ;; Number encoding -(defalias 'json-encode-number #'number-to-string - "Return a JSON representation of NUMBER.") +(define-obsolete-function-alias 'json-encode-number #'json-encode "28.1") -;;; Strings +;;;; Strings (defconst json-special-chars '((?\" . ?\") @@ -410,65 +455,52 @@ element in a deeply nested structure." ;; String encoding -;; Escape only quotation mark, backslash, and the control -;; characters U+0000 to U+001F (RFC 4627, ECMA-404). -(rx-define json--escape (in ?\" ?\\ cntrl)) - -(defvar json--long-string-threshold 200 - "Length above which strings are considered long for JSON encoding. -It is generally faster to manipulate such strings in a buffer -rather than directly.") - -(defvar json--string-buffer nil - "Buffer used for encoding Lisp strings as JSON. -Initialized lazily by `json-encode-string'.") +(defun json--print-string (string &optional from) + "Insert a JSON representation of STRING at point. +FROM is the index of STRING to start from and defaults to 0." + (insert ?\") + (goto-char (prog1 (point) (princ string))) + (and from (delete-char from)) + ;; Escape only quotation mark, backslash, and the control + ;; characters U+0000 to U+001F (RFC 4627, ECMA-404). + (while (re-search-forward (rx (in ?\" ?\\ cntrl)) nil 'move) + (let ((char (preceding-char))) + (delete-char -1) + (insert ?\\ (or + ;; Special JSON character (\n, \r, etc.). + (car (rassq char json-special-chars)) + ;; Fallback: UCS code point in \uNNNN form. + (format "u%04x" char))))) + (insert ?\") + string) (defun json-encode-string (string) "Return a JSON representation of STRING." - ;; Try to avoid buffer overhead in trivial cases, while also - ;; avoiding searching pathological strings for escape characters. - ;; Since `string-match-p' doesn't take a LIMIT argument, we use - ;; string length as our heuristic. See also bug#20154. - (if (and (< (length string) json--long-string-threshold) - (not (string-match-p (rx json--escape) string))) - (concat "\"" (substring-no-properties string) "\"") - (with-current-buffer - (or json--string-buffer - (with-current-buffer (generate-new-buffer " *json-string*" t) - ;; This seems to afford decent performance gains. - (setq-local inhibit-modification-hooks t) - (setq json--string-buffer (current-buffer)))) - ;; Strip `read-only' property (bug#43549). - (insert ?\" (substring-no-properties string)) - (goto-char (1+ (point-min))) - (while (re-search-forward (rx json--escape) nil 'move) - (let ((char (preceding-char))) - (delete-char -1) - (insert ?\\ (or - ;; Special JSON character (\n, \r, etc.). - (car (rassq char json-special-chars)) - ;; Fallback: UCS code point in \uNNNN form. - (format "u%04x" char))))) - (insert ?\") - ;; Empty buffer for next invocation. - (delete-and-extract-region (point-min) (point-max))))) - -(defun json--encode-stringlike (object) - "Return OBJECT encoded as a JSON string, or nil if not possible." - (cond ((stringp object) (json-encode-string object)) - ((keywordp object) (json-encode-string - (substring (symbol-name object) 1))) - ((symbolp object) (json-encode-string (symbol-name object))))) + (json--with-output-to-string (json--print-string string))) + +(defun json--print-stringlike (object) + "Insert OBJECT encoded as a JSON string at point. +Return nil if OBJECT cannot be encoded as a JSON string." + (cond ((stringp object) (json--print-string object)) + ((keywordp object) (json--print-string (symbol-name object) 1)) + ((symbolp object) (json--print-string (symbol-name object))))) + +(defun json--print-key (object) + "Insert a JSON key representation of OBJECT at point. +Signal `json-key-format' if it cannot be encoded as a string." + (or (json--print-stringlike object) + (signal 'json-key-format (list object)))) (defun json-encode-key (object) "Return a JSON representation of OBJECT. If the resulting JSON object isn't a valid JSON object key, this signals `json-key-format'." - ;; Encoding must be a JSON string. - (or (json--encode-stringlike object) - (signal 'json-key-format (list object)))) + (declare (obsolete json-encode "28.1")) + (json--with-output-to-string (json--print-key object))) -;;; Objects +;;;; Objects + +;; JSON object parsing (defun json-new-object () "Create a new Elisp object corresponding to an empty JSON object. @@ -501,8 +533,6 @@ Please see the documentation of `json-object-type' and `json-key-type'." ((eq json-object-type 'plist) (cons key (cons value object)))))) -;; JSON object parsing - (defun json-read-object () "Read the JSON object at point." ;; Skip over the '{'. @@ -537,95 +567,81 @@ Please see the documentation of `json-object-type' and `json-key-type'." ('plist (json--plist-nreverse elements)) (_ elements)))) +;; JSON object encoding + +(defun json--print-pair (key val) + "Insert JSON representation of KEY-VAL pair at point. +This always inserts a trailing `json-encoding-separator'." + (json--print-indentation) + (json--print-key key) + (insert json--print-keyval-separator) + (json--print val) + (insert json-encoding-separator)) + +(defun json--print-map (map) + "Insert JSON object representation of MAP at point. +This works for any MAP satisfying `mapp'." + (insert ?\{) + (unless (map-empty-p map) + (json--with-indentation + (map-do #'json--print-pair map) + (delete-char (- (length json-encoding-separator)))) + (or json-encoding-lisp-style-closings + (json--print-indentation))) + (insert ?\})) + +(defun json--print-unordered-map (map) + "Like `json--print-map', but optionally sort MAP first. +If `json-encoding-object-sort-predicate' is non-nil, this first +transforms an unsortable MAP into a sortable alist." + (if (and json-encoding-object-sort-predicate + (not (map-empty-p map))) + (json--print-alist (map-pairs map) t) + (json--print-map map))) + ;; Hash table encoding -(defun json-encode-hash-table (hash-table) - "Return a JSON representation of HASH-TABLE." - (cond ((hash-table-empty-p hash-table) "{}") - (json-encoding-object-sort-predicate - (json--encode-alist (map-pairs hash-table) t)) - (t - (let ((kv-sep (if json-encoding-pretty-print ": " ":")) - result) - (json--with-indentation - (maphash - (lambda (k v) - (push (concat json--encoding-current-indentation - (json-encode-key k) - kv-sep - (json-encode v)) - result)) - hash-table)) - (concat "{" - (string-join (nreverse result) json-encoding-separator) - (and json-encoding-pretty-print - (not json-encoding-lisp-style-closings) - json--encoding-current-indentation) - "}"))))) +(define-obsolete-function-alias 'json-encode-hash-table #'json-encode "28.1") ;; List encoding (including alists and plists) -(defun json--encode-alist (alist &optional destructive) - "Return a JSON representation of ALIST. -DESTRUCTIVE non-nil means it is safe to modify ALIST by -side-effects." - (when json-encoding-object-sort-predicate - (setq alist (sort (if destructive alist (copy-sequence alist)) - (lambda (a b) - (funcall json-encoding-object-sort-predicate - (car a) (car b)))))) - (concat "{" - (let ((kv-sep (if json-encoding-pretty-print ": " ":"))) - (json--with-indentation - (mapconcat (lambda (cons) - (concat json--encoding-current-indentation - (json-encode-key (car cons)) - kv-sep - (json-encode (cdr cons)))) - alist - json-encoding-separator))) - (and json-encoding-pretty-print - (not json-encoding-lisp-style-closings) - json--encoding-current-indentation) - "}")) +(defun json--print-alist (alist &optional destructive) + "Insert a JSON representation of ALIST at point. +Sort ALIST first if `json-encoding-object-sort-predicate' is +non-nil. Sorting can optionally be DESTRUCTIVE for speed." + (json--print-map (if (and json-encoding-object-sort-predicate alist) + (sort (if destructive alist (copy-sequence alist)) + (lambda (a b) + (funcall json-encoding-object-sort-predicate + (car a) (car b)))) + alist))) + +;; The following two are unused but useful to keep around due to the +;; inherent ambiguity of lists. (defun json-encode-alist (alist) "Return a JSON representation of ALIST." - (if alist (json--encode-alist alist) "{}")) + (json--with-output-to-string (json--print-alist alist))) (defun json-encode-plist (plist) "Return a JSON representation of PLIST." - (cond ((null plist) "{}") - (json-encoding-object-sort-predicate - (json--encode-alist (map-pairs plist) t)) - (t - (let ((kv-sep (if json-encoding-pretty-print ": " ":")) - result) - (json--with-indentation - (while plist - (push (concat json--encoding-current-indentation - (json-encode-key (pop plist)) - kv-sep - (json-encode (pop plist))) - result))) - (concat "{" - (string-join (nreverse result) json-encoding-separator) - (and json-encoding-pretty-print - (not json-encoding-lisp-style-closings) - json--encoding-current-indentation) - "}"))))) + (json--with-output-to-string (json--print-unordered-map plist))) + +(defun json--print-list (list) + "Like `json-encode-list', but insert the JSON at point." + (cond ((json-alist-p list) (json--print-alist list)) + ((json-plist-p list) (json--print-unordered-map list)) + ((listp list) (json--print-array list)) + ((signal 'json-error (list list))))) (defun json-encode-list (list) "Return a JSON representation of LIST. -Tries to DWIM: simple lists become JSON arrays, while alists and plists -become JSON objects." - (cond ((json-alist-p list) (json-encode-alist list)) - ((json-plist-p list) (json-encode-plist list)) - ((listp list) (json-encode-array list)) - (t - (signal 'json-error (list list))))) +Tries to DWIM: alists and plists become JSON objects, while +simple lists become JSON arrays." + (declare (obsolete json-encode "28.1")) + (json--with-output-to-string (json--print-list list))) -;;; Arrays +;;;; Arrays ;; Array parsing @@ -658,28 +674,32 @@ become JSON objects." ;; Array encoding +(defun json--print-array (array) + "Like `json-encode-array', but insert the JSON at point." + (insert ?\[) + (unless (length= array 0) + (json--with-indentation + (json--print-indentation) + (let ((first t)) + (mapc (lambda (elt) + (if first + (setq first nil) + (insert json-encoding-separator) + (json--print-indentation)) + (json--print elt)) + array))) + (or json-encoding-lisp-style-closings + (json--print-indentation))) + (insert ?\])) + (defun json-encode-array (array) "Return a JSON representation of ARRAY. ARRAY can also be a list." - (if (and json-encoding-pretty-print - (not (length= array 0))) - (concat - "[" - (json--with-indentation - (concat json--encoding-current-indentation - (mapconcat #'json-encode array - (concat json-encoding-separator - json--encoding-current-indentation)))) - (unless json-encoding-lisp-style-closings - json--encoding-current-indentation) - "]") - (concat "[" - (mapconcat #'json-encode array json-encoding-separator) - "]"))) + (json--with-output-to-string (json--print-array array))) -;;; Reader +;;;; Reader (defmacro json-readtable-dispatch (char) "Dispatch reader function for CHAR at point. @@ -735,7 +755,17 @@ you will get the following structure returned: -;;; Encoder +;;;; Encoder + +(defun json--print (object) + "Like `json-encode', but insert or print the JSON at point." + (cond ((json--print-keyword object)) + ((listp object) (json--print-list object)) + ((json--print-stringlike object)) + ((numberp object) (prin1 object)) + ((arrayp object) (json--print-array object)) + ((hash-table-p object) (json--print-unordered-map object)) + ((signal 'json-error (list object))))) (defun json-encode (object) "Return a JSON representation of OBJECT as a string. @@ -743,15 +773,9 @@ you will get the following structure returned: OBJECT should have a structure like one returned by `json-read'. If an error is detected during encoding, an error based on `json-error' is signaled." - (cond ((json-encode-keyword object)) - ((listp object) (json-encode-list object)) - ((json--encode-stringlike object)) - ((numberp object) (json-encode-number object)) - ((arrayp object) (json-encode-array object)) - ((hash-table-p object) (json-encode-hash-table object)) - (t (signal 'json-error (list object))))) + (json--with-output-to-string (json--print object))) -;;; Pretty printing & minimizing +;;;; Pretty printing & minimizing (defun json-pretty-print-buffer (&optional minimize) "Pretty-print current buffer. @@ -762,7 +786,7 @@ With prefix argument MINIMIZE, minimize it instead." (defvar json-pretty-print-max-secs 2.0 "Maximum time for `json-pretty-print's comparison. The function `json-pretty-print' uses `replace-region-contents' -(which see) passing the value of this variable as argument +\(which see) passing the value of this variable as argument MAX-SECS.") (defun json-pretty-print (begin end &optional minimize) diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index c233dcebe1..eb690a72f6 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -3699,8 +3699,7 @@ Otherwise, use the current value of `process-mark'." Strings and numbers are JSON-encoded. Lists (including nil) are made into JavaScript array literals and their contents encoded with `js--js-encode-value'." - (cond ((stringp x) (json-encode-string x)) - ((numberp x) (json-encode-number x)) + (cond ((or (stringp x) (numberp x)) (json-encode x)) ((symbolp x) (format "{objid:%S}" (symbol-name x))) ((js--js-handle-p x) @@ -4390,7 +4389,8 @@ If one hasn't been set, or if it's stale, prompt for a new one." (with-temp-buffer (insert js--js-inserter) (insert "(") - (insert (json-encode-list defun-info)) + (let ((standard-output (current-buffer))) + (json--print-list defun-info)) (insert ",\n") (insert defun-body) (insert "\n)") diff --git a/test/lisp/json-tests.el b/test/lisp/json-tests.el index 9886dc0d45..f400fb064a 100644 --- a/test/lisp/json-tests.el +++ b/test/lisp/json-tests.el @@ -329,13 +329,13 @@ Point is moved to beginning of the buffer." (should (equal (read str) res))))))) (ert-deftest test-json-encode-number () - (should (equal (json-encode-number 0) "0")) - (should (equal (json-encode-number -0) "0")) - (should (equal (json-encode-number 3) "3")) - (should (equal (json-encode-number -5) "-5")) - (should (equal (json-encode-number 123.456) "123.456")) + (should (equal (json-encode 0) "0")) + (should (equal (json-encode -0) "0")) + (should (equal (json-encode 3) "3")) + (should (equal (json-encode -5) "-5")) + (should (equal (json-encode 123.456) "123.456")) (let ((bignum (1+ most-positive-fixnum))) - (should (equal (json-encode-number bignum) + (should (equal (json-encode bignum) (number-to-string bignum))))) ;;; Strings @@ -404,6 +404,8 @@ Point is moved to beginning of the buffer." (should (equal (json-read-string) "abcαβγ"))) (json-tests--with-temp-buffer "\"\\nasd\\u0444\\u044b\\u0432fgh\\t\"" (should (equal (json-read-string) "\nasdфывfgh\t"))) + (json-tests--with-temp-buffer "\"abc\uFFFFαβγ𝔸𝐁𝖢\\\"\\\\\"" + (should (equal (json-read-string) "abc\uFFFFαβγ𝔸𝐁𝖢\"\\"))) ;; Bug#24784 (json-tests--with-temp-buffer "\"\\uD834\\uDD1E\"" (should (equal (json-read-string) "\U0001D11E"))) @@ -418,30 +420,37 @@ Point is moved to beginning of the buffer." (should (equal (json-encode-string "foo") "\"foo\"")) (should (equal (json-encode-string "a\n\fb") "\"a\\n\\fb\"")) (should (equal (json-encode-string "\nasdфыв\u001f\u007ffgh\t") - "\"\\nasdфыв\\u001f\u007ffgh\\t\""))) + "\"\\nasdфыв\\u001f\u007ffgh\\t\"")) + ;; Bug#43549. + (should (equal (json-encode-string (propertize "foo" 'read-only t)) + "\"foo\"")) + (should (equal (json-encode-string "a\0b") "\"a\\u0000b\"")) + (should (equal (json-encode-string "abc\uFFFFαβγ𝔸𝐁𝖢\"\\") + "\"abc\uFFFFαβγ𝔸𝐁𝖢\\\"\\\\\""))) (ert-deftest test-json-encode-key () - (should (equal (json-encode-key '##) "\"\"")) - (should (equal (json-encode-key :) "\"\"")) - (should (equal (json-encode-key "") "\"\"")) - (should (equal (json-encode-key 'a) "\"a\"")) - (should (equal (json-encode-key :a) "\"a\"")) - (should (equal (json-encode-key "a") "\"a\"")) - (should (equal (json-encode-key t) "\"t\"")) - (should (equal (json-encode-key :t) "\"t\"")) - (should (equal (json-encode-key "t") "\"t\"")) - (should (equal (json-encode-key nil) "\"nil\"")) - (should (equal (json-encode-key :nil) "\"nil\"")) - (should (equal (json-encode-key "nil") "\"nil\"")) - (should (equal (json-encode-key ":a") "\":a\"")) - (should (equal (json-encode-key ":t") "\":t\"")) - (should (equal (json-encode-key ":nil") "\":nil\"")) - (should (equal (should-error (json-encode-key 5)) - '(json-key-format 5))) - (should (equal (should-error (json-encode-key ["foo"])) - '(json-key-format ["foo"]))) - (should (equal (should-error (json-encode-key '("foo"))) - '(json-key-format ("foo"))))) + (with-suppressed-warnings ((obsolete json-encode-key)) + (should (equal (json-encode-key '##) "\"\"")) + (should (equal (json-encode-key :) "\"\"")) + (should (equal (json-encode-key "") "\"\"")) + (should (equal (json-encode-key 'a) "\"a\"")) + (should (equal (json-encode-key :a) "\"a\"")) + (should (equal (json-encode-key "a") "\"a\"")) + (should (equal (json-encode-key t) "\"t\"")) + (should (equal (json-encode-key :t) "\"t\"")) + (should (equal (json-encode-key "t") "\"t\"")) + (should (equal (json-encode-key nil) "\"nil\"")) + (should (equal (json-encode-key :nil) "\"nil\"")) + (should (equal (json-encode-key "nil") "\"nil\"")) + (should (equal (json-encode-key ":a") "\":a\"")) + (should (equal (json-encode-key ":t") "\":t\"")) + (should (equal (json-encode-key ":nil") "\":nil\"")) + (should (equal (should-error (json-encode-key 5)) + '(json-key-format 5))) + (should (equal (should-error (json-encode-key ["foo"])) + '(json-key-format ["foo"]))) + (should (equal (should-error (json-encode-key '("foo"))) + '(json-key-format ("foo")))))) ;;; Objects @@ -578,45 +587,32 @@ Point is moved to beginning of the buffer." (ert-deftest test-json-encode-hash-table () (let ((json-encoding-object-sort-predicate nil) (json-encoding-pretty-print nil)) - (should (equal (json-encode-hash-table #s(hash-table)) "{}")) - (should (equal (json-encode-hash-table #s(hash-table data (a 1))) - "{\"a\":1}")) - (should (equal (json-encode-hash-table #s(hash-table data (t 1))) - "{\"t\":1}")) - (should (equal (json-encode-hash-table #s(hash-table data (nil 1))) - "{\"nil\":1}")) - (should (equal (json-encode-hash-table #s(hash-table data (:a 1))) - "{\"a\":1}")) - (should (equal (json-encode-hash-table #s(hash-table data (:t 1))) - "{\"t\":1}")) - (should (equal (json-encode-hash-table #s(hash-table data (:nil 1))) - "{\"nil\":1}")) - (should (equal (json-encode-hash-table - #s(hash-table test equal data ("a" 1))) + (should (equal (json-encode #s(hash-table)) "{}")) + (should (equal (json-encode #s(hash-table data (a 1))) "{\"a\":1}")) + (should (equal (json-encode #s(hash-table data (t 1))) "{\"t\":1}")) + (should (equal (json-encode #s(hash-table data (nil 1))) "{\"nil\":1}")) + (should (equal (json-encode #s(hash-table data (:a 1))) "{\"a\":1}")) + (should (equal (json-encode #s(hash-table data (:t 1))) "{\"t\":1}")) + (should (equal (json-encode #s(hash-table data (:nil 1))) "{\"nil\":1}")) + (should (equal (json-encode #s(hash-table test equal data ("a" 1))) "{\"a\":1}")) - (should (equal (json-encode-hash-table - #s(hash-table test equal data ("t" 1))) + (should (equal (json-encode #s(hash-table test equal data ("t" 1))) "{\"t\":1}")) - (should (equal (json-encode-hash-table - #s(hash-table test equal data ("nil" 1))) + (should (equal (json-encode #s(hash-table test equal data ("nil" 1))) "{\"nil\":1}")) - (should (equal (json-encode-hash-table - #s(hash-table test equal data (":a" 1))) + (should (equal (json-encode #s(hash-table test equal data (":a" 1))) "{\":a\":1}")) - (should (equal (json-encode-hash-table - #s(hash-table test equal data (":t" 1))) + (should (equal (json-encode #s(hash-table test equal data (":t" 1))) "{\":t\":1}")) - (should (equal (json-encode-hash-table - #s(hash-table test equal data (":nil" 1))) + (should (equal (json-encode #s(hash-table test equal data (":nil" 1))) "{\":nil\":1}")) - (should (member (json-encode-hash-table #s(hash-table data (t 2 :nil 1))) + (should (member (json-encode #s(hash-table data (t 2 :nil 1))) '("{\"nil\":1,\"t\":2}" "{\"t\":2,\"nil\":1}"))) - (should (member (json-encode-hash-table - #s(hash-table test equal data (:t 2 ":t" 1))) + (should (member (json-encode #s(hash-table test equal data (:t 2 ":t" 1))) '("{\":t\":1,\"t\":2}" "{\"t\":2,\":t\":1}"))) - (should (member (json-encode-hash-table #s(hash-table data (b 2 a 1))) + (should (member (json-encode #s(hash-table data (b 2 a 1))) '("{\"a\":1,\"b\":2}" "{\"b\":2,\"a\":1}"))) - (should (member (json-encode-hash-table #s(hash-table data (c 3 b 2 a 1))) + (should (member (json-encode #s(hash-table data (c 3 b 2 a 1))) '("{\"a\":1,\"b\":2,\"c\":3}" "{\"a\":1,\"c\":3,\"b\":2}" "{\"b\":2,\"a\":1,\"c\":3}" @@ -629,13 +625,12 @@ Point is moved to beginning of the buffer." (json-encoding-pretty-print t) (json-encoding-default-indentation " ") (json-encoding-lisp-style-closings nil)) - (should (equal (json-encode-hash-table #s(hash-table)) "{}")) - (should (equal (json-encode-hash-table #s(hash-table data (a 1))) - "{\n \"a\": 1\n}")) - (should (member (json-encode-hash-table #s(hash-table data (b 2 a 1))) + (should (equal (json-encode #s(hash-table)) "{}")) + (should (equal (json-encode #s(hash-table data (a 1))) "{\n \"a\": 1\n}")) + (should (member (json-encode #s(hash-table data (b 2 a 1))) '("{\n \"a\": 1,\n \"b\": 2\n}" "{\n \"b\": 2,\n \"a\": 1\n}"))) - (should (member (json-encode-hash-table #s(hash-table data (c 3 b 2 a 1))) + (should (member (json-encode #s(hash-table data (c 3 b 2 a 1))) '("{\n \"a\": 1,\n \"b\": 2,\n \"c\": 3\n}" "{\n \"a\": 1,\n \"c\": 3,\n \"b\": 2\n}" "{\n \"b\": 2,\n \"a\": 1,\n \"c\": 3\n}" @@ -648,13 +643,12 @@ Point is moved to beginning of the buffer." (json-encoding-pretty-print t) (json-encoding-default-indentation " ") (json-encoding-lisp-style-closings t)) - (should (equal (json-encode-hash-table #s(hash-table)) "{}")) - (should (equal (json-encode-hash-table #s(hash-table data (a 1))) - "{\n \"a\": 1}")) - (should (member (json-encode-hash-table #s(hash-table data (b 2 a 1))) + (should (equal (json-encode #s(hash-table)) "{}")) + (should (equal (json-encode #s(hash-table data (a 1))) "{\n \"a\": 1}")) + (should (member (json-encode #s(hash-table data (b 2 a 1))) '("{\n \"a\": 1,\n \"b\": 2}" "{\n \"b\": 2,\n \"a\": 1}"))) - (should (member (json-encode-hash-table #s(hash-table data (c 3 b 2 a 1))) + (should (member (json-encode #s(hash-table data (c 3 b 2 a 1))) '("{\n \"a\": 1,\n \"b\": 2,\n \"c\": 3}" "{\n \"a\": 1,\n \"c\": 3,\n \"b\": 2}" "{\n \"b\": 2,\n \"a\": 1,\n \"c\": 3}" @@ -672,7 +666,7 @@ Point is moved to beginning of the buffer." (#s(hash-table data (c 3 b 2 a 1)) . "{\"a\":1,\"b\":2,\"c\":3}"))) (let ((copy (map-pairs in))) - (should (equal (json-encode-hash-table in) out)) + (should (equal (json-encode in) out)) ;; Ensure sorting isn't destructive. (should (seq-set-equal-p (map-pairs in) copy)))))) @@ -785,38 +779,42 @@ Point is moved to beginning of the buffer." (should (equal in copy)))))) (ert-deftest test-json-encode-list () + "Test `json-encode-list' or its more moral equivalents." (let ((json-encoding-object-sort-predicate nil) (json-encoding-pretty-print nil)) - (should (equal (json-encode-list ()) "{}")) - (should (equal (json-encode-list '(a)) "[\"a\"]")) - (should (equal (json-encode-list '(:a)) "[\"a\"]")) - (should (equal (json-encode-list '("a")) "[\"a\"]")) - (should (equal (json-encode-list '(a 1)) "[\"a\",1]")) - (should (equal (json-encode-list '("a" 1)) "[\"a\",1]")) - (should (equal (json-encode-list '(:a 1)) "{\"a\":1}")) - (should (equal (json-encode-list '((a . 1))) "{\"a\":1}")) - (should (equal (json-encode-list '((:a . 1))) "{\"a\":1}")) - (should (equal (json-encode-list '(:b 2 :a)) "[\"b\",2,\"a\"]")) - (should (equal (json-encode-list '(4 3 2 1)) "[4,3,2,1]")) - (should (equal (json-encode-list '(b 2 a 1)) "[\"b\",2,\"a\",1]")) - (should (equal (json-encode-list '(:b 2 :a 1)) "{\"b\":2,\"a\":1}")) - (should (equal (json-encode-list '((b . 2) (a . 1))) "{\"b\":2,\"a\":1}")) - (should (equal (json-encode-list '((:b . 2) (:a . 1))) + ;; Trick `json-encode' into using `json--print-list'. + (let ((json-null (list nil))) + (should (equal (json-encode ()) "{}"))) + (should (equal (json-encode '(a)) "[\"a\"]")) + (should (equal (json-encode '(:a)) "[\"a\"]")) + (should (equal (json-encode '("a")) "[\"a\"]")) + (should (equal (json-encode '(a 1)) "[\"a\",1]")) + (should (equal (json-encode '("a" 1)) "[\"a\",1]")) + (should (equal (json-encode '(:a 1)) "{\"a\":1}")) + (should (equal (json-encode '((a . 1))) "{\"a\":1}")) + (should (equal (json-encode '((:a . 1))) "{\"a\":1}")) + (should (equal (json-encode '(:b 2 :a)) "[\"b\",2,\"a\"]")) + (should (equal (json-encode '(4 3 2 1)) "[4,3,2,1]")) + (should (equal (json-encode '(b 2 a 1)) "[\"b\",2,\"a\",1]")) + (should (equal (json-encode '(:b 2 :a 1)) "{\"b\":2,\"a\":1}")) + (should (equal (json-encode '((b . 2) (a . 1))) "{\"b\":2,\"a\":1}")) + (should (equal (json-encode '((:b . 2) (:a . 1))) "{\"b\":2,\"a\":1}")) - (should (equal (json-encode-list '((a) 1)) "[[\"a\"],1]")) - (should (equal (json-encode-list '((:a) 1)) "[[\"a\"],1]")) - (should (equal (json-encode-list '(("a") 1)) "[[\"a\"],1]")) - (should (equal (json-encode-list '((a 1) 2)) "[[\"a\",1],2]")) - (should (equal (json-encode-list '((:a 1) 2)) "[{\"a\":1},2]")) - (should (equal (json-encode-list '(((a . 1)) 2)) "[{\"a\":1},2]")) - (should (equal (json-encode-list '(:a 1 :b (2))) "{\"a\":1,\"b\":[2]}")) - (should (equal (json-encode-list '((a . 1) (b 2))) "{\"a\":1,\"b\":[2]}")) - (should-error (json-encode-list '(a . 1)) :type 'wrong-type-argument) - (should-error (json-encode-list '((a . 1) 2)) :type 'wrong-type-argument) - (should (equal (should-error (json-encode-list [])) - '(json-error []))) - (should (equal (should-error (json-encode-list [a])) - '(json-error [a]))))) + (should (equal (json-encode '((a) 1)) "[[\"a\"],1]")) + (should (equal (json-encode '((:a) 1)) "[[\"a\"],1]")) + (should (equal (json-encode '(("a") 1)) "[[\"a\"],1]")) + (should (equal (json-encode '((a 1) 2)) "[[\"a\",1],2]")) + (should (equal (json-encode '((:a 1) 2)) "[{\"a\":1},2]")) + (should (equal (json-encode '(((a . 1)) 2)) "[{\"a\":1},2]")) + (should (equal (json-encode '(:a 1 :b (2))) "{\"a\":1,\"b\":[2]}")) + (should (equal (json-encode '((a . 1) (b 2))) "{\"a\":1,\"b\":[2]}")) + (should-error (json-encode '(a . 1)) :type 'wrong-type-argument) + (should-error (json-encode '((a . 1) 2)) :type 'wrong-type-argument) + (with-suppressed-warnings ((obsolete json-encode-list)) + (should (equal (should-error (json-encode-list [])) + '(json-error []))) + (should (equal (should-error (json-encode-list [a])) + '(json-error [a])))))) ;;; Arrays commit b24c21e82ca0819f06ea5708274ce9091b3bc6d2 Author: Stefan Monnier Date: Sat Mar 6 13:19:46 2021 -0500 * lisp/emacs-lisp/bindat.el (bindat-struct): Fix Edebug def diff --git a/lisp/emacs-lisp/bindat.el b/lisp/emacs-lisp/bindat.el index adf2d67284..98994963e3 100644 --- a/lisp/emacs-lisp/bindat.el +++ b/lisp/emacs-lisp/bindat.el @@ -805,8 +805,8 @@ is the name of a variable that will hold the value we need to pack.") (_ (error "Unrecognized format in bindat fields: %S" fields))))) (def-edebug-elem-spec 'bindat-struct - [[&rest (symbolp bindat-type &optional ":pack-val" def-form)] - &optional ":unpack-val" def-form]) + '([&rest (symbolp bindat-type &optional ":pack-val" def-form)] + &optional ":unpack-val" def-form)) (def-edebug-elem-spec 'bindat-type '(&or ["uint" def-form] commit 16975078b421b6b88caecf6d6143789fb44f1ddc Author: Stefan Monnier Date: Sat Mar 6 13:03:12 2021 -0500 * lisp/emulation/: Use lexical-binding * lisp/emulation/cua-base.el: Use lexical-binding. Remove redundant `:group` arguments. (cua-mode): Don't use `:require` since the autoload on `define-minor-mode` takes care of loading the mode when custom-setting it. * lisp/emulation/cua-gmrk.el: Use lexical-binding. (cua--copy-rectangle-to-global-mark): Remove unused var `src-buf`. * lisp/emulation/edt-mapper.el: Use lexical-binding. * lisp/emulation/edt.el: Use lexical-binding. Remove redundant `:group` arguments. (edt-with-position): Allow `top`, `left`, and `far` to be left unused in `body`. * lisp/emulation/keypad.el: Use lexical-binding. * lisp/emulation/viper-cmd.el: Move `provide` to the end. (viper-read-string-with-history): Strength reduce `eval` to `symbol-value`. * lisp/emulation/viper-ex.el: Use lexical-binding. Remove redundant `:group` arguments. Move `provide` to the end. * lisp/emulation/viper-init.el: Use lexical-binding. * lisp/emulation/viper-keym.el (viper-toggle-key): Use `dolist`. (viper-insert-diehard-map): Use `string`. (viper-modify-major-mode): Use `alist-get` and `setf`. * lisp/emulation/viper-macs.el (viper-ex-work-buf): Move `provide` to the end. (viper-record-kbd-macro): Strength reduce `eval` to `symbol-value`. (viper-describe-kbd-macros): Return value is not significant. (viper-keyseq-is-a-possible-macro): Use `seq-some`. (viper-common-seq-prefix): Use `seq-every-p`. * lisp/emulation/viper-mous.el: Use lexical-binding. Remove redundant `:group` arguments. Move `provide` to the end. (viper-remember-current-frame): Accept arbitrary ignored args. (viper-parse-mouse-key): Strength reduce `eval` to `symbol-value`. Remove unused var `key-spec`. (viper-bind-mouse-search-key, viper-bind-mouse-insert-key): Apply de Morgan. * lisp/emulation/viper-util.el: Move `provide` to the end. (viper-move-marker-locally, viper-push-onto-ring, viper-save-setting): Strength reduce `eval` to `symbol-value`. (viper-event-vector-p, viper-char-symbol-sequence-p, viper-char-array-p): Use `seq-every-p`. * lisp/emulation/viper.el (viper-non-hook-settings): Eta-reduce use of `viper-remember-current-frame`. diff --git a/lisp/emulation/cua-base.el b/lisp/emulation/cua-base.el index a64274bc0c..54f881bde8 100644 --- a/lisp/emulation/cua-base.el +++ b/lisp/emulation/cua-base.el @@ -1,4 +1,4 @@ -;;; cua-base.el --- emulate CUA key bindings +;;; cua-base.el --- emulate CUA key bindings -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -272,19 +272,16 @@ a shifted movement key. If the value is nil, these keys are never enabled." :type '(choice (const :tag "Disabled" nil) (const :tag "Shift region only" shift) - (other :tag "Enabled" t)) - :group 'cua) + (other :tag "Enabled" t))) (defcustom cua-remap-control-v t "If non-nil, C-v binding is used for paste (yank). Also, M-v is mapped to `delete-selection-repeat-replace-region'." - :type 'boolean - :group 'cua) + :type 'boolean) (defcustom cua-remap-control-z t "If non-nil, C-z binding is used for undo." - :type 'boolean - :group 'cua) + :type 'boolean) (defcustom cua-highlight-region-shift-only nil "If non-nil, only highlight region if marked with S-. @@ -292,8 +289,7 @@ When this is non-nil, CUA toggles `transient-mark-mode' on when the region is marked using shifted movement keys, and off when the mark is cleared. But when the mark was set using \\[cua-set-mark], Transient Mark mode is not turned on." - :type 'boolean - :group 'cua) + :type 'boolean) (make-obsolete-variable 'cua-highlight-region-shift-only 'transient-mark-mode "24.4") @@ -307,33 +303,28 @@ first prefix key is discarded, so typing a prefix key twice in quick succession will also inhibit overriding the prefix key. If the value is nil, use a shifted prefix key to inhibit the override." :type '(choice (number :tag "Inhibit delay") - (const :tag "No delay" nil)) - :group 'cua) + (const :tag "No delay" nil))) (defcustom cua-delete-selection t "If non-nil, typed text replaces text in the active selection." :type '(choice (const :tag "Disabled" nil) - (other :tag "Enabled" t)) - :group 'cua) + (other :tag "Enabled" t))) (defcustom cua-keep-region-after-copy nil "If non-nil, don't deselect the region after copying." - :type 'boolean - :group 'cua) + :type 'boolean) (defcustom cua-toggle-set-mark t "If non-nil, the `cua-set-mark' command toggles the mark." :type '(choice (const :tag "Disabled" nil) - (other :tag "Enabled" t)) - :group 'cua) + (other :tag "Enabled" t))) (defcustom cua-auto-mark-last-change nil "If non-nil, set implicit mark at position of last buffer change. This means that \\[universal-argument] \\[cua-set-mark] will jump to the position of the last buffer change before jumping to the explicit marks on the mark ring. See `cua-set-mark' for details." - :type 'boolean - :group 'cua) + :type 'boolean) (defcustom cua-enable-register-prefix 'not-ctrl-u "If non-nil, registers are supported via numeric prefix arg. @@ -346,32 +337,27 @@ interpreted as a register number." :type '(choice (const :tag "Disabled" nil) (const :tag "Enabled, but C-u arg is not a register" not-ctrl-u) (const :tag "Enabled, but only for C-u arg" ctrl-u-only) - (other :tag "Enabled" t)) - :group 'cua) + (other :tag "Enabled" t))) (defcustom cua-delete-copy-to-register-0 t ;; FIXME: Obey delete-selection-save-to-register rather than hardcoding ;; register 0. "If non-nil, save last deleted region or rectangle to register 0." - :type 'boolean - :group 'cua) + :type 'boolean) (defcustom cua-enable-region-auto-help nil "If non-nil, automatically show help for active region." - :type 'boolean - :group 'cua) + :type 'boolean) (defcustom cua-enable-modeline-indications nil "If non-nil, use minor-mode hook to show status in mode line." - :type 'boolean - :group 'cua) + :type 'boolean) (defcustom cua-check-pending-input t "If non-nil, don't override prefix key if input pending. It is rumored that `input-pending-p' is unreliable under some window managers, so try setting this to nil, if prefix override doesn't work." - :type 'boolean - :group 'cua) + :type 'boolean) (defcustom cua-paste-pop-rotate-temporarily nil "If non-nil, \\[cua-paste-pop] only rotates the kill-ring temporarily. @@ -380,8 +366,7 @@ insert the most recently killed text. Each immediately following \\[cua-paste-p replaces the previous text with the next older element on the `kill-ring'. With prefix arg, \\[universal-argument] \\[yank-pop] inserts the same text as the most recent \\[yank-pop] (or \\[yank]) command." - :type 'boolean - :group 'cua) + :type 'boolean) ;;; Rectangle Customization @@ -390,8 +375,7 @@ most recent \\[yank-pop] (or \\[yank]) command." Note that although rectangles are always DISPLAYED with straight edges, the buffer is NOT modified, until you execute a command that actually modifies it. M-p toggles this feature when a rectangle is active." - :type 'boolean - :group 'cua) + :type 'boolean) (defcustom cua-auto-tabify-rectangles 1000 "If non-nil, automatically tabify after rectangle commands. @@ -403,11 +387,12 @@ present. The number specifies then number of characters before and after the region marked by the rectangle to search." :type '(choice (number :tag "Auto detect (limit)") (const :tag "Disabled" nil) - (other :tag "Enabled" t)) - :group 'cua) + (other :tag "Enabled" t))) (defvar cua-global-keymap) ; forward (defvar cua--region-keymap) ; forward +(declare-function cua-clear-rectangle-mark "cua-rect" ()) +(declare-function cua-mouse-set-rectangle-mark "cua-rect" (event)) (defcustom cua-rectangle-mark-key [(control return)] "Global key used to toggle the cua rectangle mark." @@ -416,14 +401,13 @@ and after the region marked by the rectangle to search." (when (and (boundp 'cua--keymaps-initialized) cua--keymaps-initialized) (define-key cua-global-keymap value - 'cua-set-rectangle-mark) + #'cua-set-rectangle-mark) (when (boundp 'cua--rectangle-keymap) (define-key cua--rectangle-keymap value - 'cua-clear-rectangle-mark) + #'cua-clear-rectangle-mark) (define-key cua--region-keymap value - 'cua-toggle-rectangle-mark)))) - :type 'key-sequence - :group 'cua) + #'cua-toggle-rectangle-mark)))) + :type 'key-sequence) (defcustom cua-rectangle-modifier-key 'meta "Modifier key used for rectangle commands bindings. @@ -432,8 +416,7 @@ Must be set prior to enabling CUA." :type '(choice (const :tag "Meta key" meta) (const :tag "Alt key" alt) (const :tag "Hyper key" hyper) - (const :tag "Super key" super)) - :group 'cua) + (const :tag "Super key" super))) (defcustom cua-rectangle-terminal-modifier-key 'meta "Modifier key used for rectangle commands bindings in terminals. @@ -442,54 +425,46 @@ Must be set prior to enabling CUA." (const :tag "Alt key" alt) (const :tag "Hyper key" hyper) (const :tag "Super key" super)) - :group 'cua :version "27.1") (defcustom cua-enable-rectangle-auto-help t "If non-nil, automatically show help for region, rectangle and global mark." - :type 'boolean - :group 'cua) + :type 'boolean) (defface cua-rectangle '((default :inherit region) (((class color)) :foreground "white" :background "maroon")) - "Font used by CUA for highlighting the rectangle." - :group 'cua) + "Font used by CUA for highlighting the rectangle.") (defface cua-rectangle-noselect '((default :inherit region) (((class color)) :foreground "white" :background "dimgray")) - "Font used by CUA for highlighting the non-selected rectangle lines." - :group 'cua) + "Font used by CUA for highlighting the non-selected rectangle lines.") ;;; Global Mark Customization (defcustom cua-global-mark-keep-visible t "If non-nil, always keep global mark visible in other window." - :type 'boolean - :group 'cua) + :type 'boolean) (defface cua-global-mark '((((min-colors 88)(class color)) :foreground "black" :background "yellow1") (((class color)) :foreground "black" :background "yellow") (t :weight bold)) - "Font used by CUA for highlighting the global mark." - :group 'cua) + "Font used by CUA for highlighting the global mark.") (defcustom cua-global-mark-blink-cursor-interval 0.20 "Blink cursor at this interval when global mark is active." :type '(choice (number :tag "Blink interval") - (const :tag "No blink" nil)) - :group 'cua) + (const :tag "No blink" nil))) ;;; Cursor Indication Customization (defcustom cua-enable-cursor-indications nil "If non-nil, use different cursor colors for indications." - :type 'boolean - :group 'cua) + :type 'boolean) (defcustom cua-normal-cursor-color (or (and (boundp 'initial-cursor-color) initial-cursor-color) (and (boundp 'initial-frame-alist) @@ -507,7 +482,7 @@ If the value is a COLOR name, then only the `cursor-color' attribute will be affected. If the value is a cursor TYPE (one of: box, hollow, bar, or hbar), then only the `cursor-type' property will be affected. If the value is a cons (TYPE . COLOR), then both properties are affected." - :initialize 'custom-initialize-default + :initialize #'custom-initialize-default :type '(choice (color :tag "Color") (choice :tag "Type" @@ -521,8 +496,7 @@ a cons (TYPE . COLOR), then both properties are affected." (const :tag "Vertical bar" bar) (const :tag "Horizontal bar" hbar) (const :tag "Hollow box" hollow)) - (color :tag "Color"))) - :group 'cua) + (color :tag "Color")))) (defcustom cua-read-only-cursor-color "darkgreen" "Cursor color used in read-only buffers, if non-nil. @@ -545,8 +519,7 @@ a cons (TYPE . COLOR), then both properties are affected." (const :tag "Vertical bar" bar) (const :tag "Horizontal bar" hbar) (const :tag "Hollow box" hollow)) - (color :tag "Color"))) - :group 'cua) + (color :tag "Color")))) (defcustom cua-overwrite-cursor-color "yellow" "Cursor color used when overwrite mode is set, if non-nil. @@ -569,8 +542,7 @@ a cons (TYPE . COLOR), then both properties are affected." (const :tag "Vertical bar" bar) (const :tag "Horizontal bar" hbar) (const :tag "Hollow box" hollow)) - (color :tag "Color"))) - :group 'cua) + (color :tag "Color")))) (defcustom cua-global-mark-cursor-color "cyan" "Indication for active global mark. @@ -594,8 +566,7 @@ a cons (TYPE . COLOR), then both properties are affected." (const :tag "Vertical bar" bar) (const :tag "Horizontal bar" hbar) (const :tag "Hollow box" hollow)) - (color :tag "Color"))) - :group 'cua) + (color :tag "Color")))) ;;; Rectangle support is in cua-rect.el @@ -710,7 +681,7 @@ a cons (TYPE . COLOR), then both properties are affected." (<= cua-prefix-override-inhibit-delay 0) ;; In state [1], start [T] and change to state [2] (run-with-timer cua-prefix-override-inhibit-delay nil - 'cua--prefix-override-timeout))) + #'cua--prefix-override-timeout))) ;; Don't record this command (setq this-command last-command) ;; Restore the prefix arg @@ -1243,6 +1214,8 @@ If ARG is the atom `-', scroll upward by nearly full screen." (interactive) (cua--shift-control-prefix ?\C-x)) +(declare-function delete-selection-repeat-replace-region "delsel" (arg)) + (defun cua--init-keymaps () ;; Cache actual rectangle modifier key. (setq cua--rectangle-modifier-key @@ -1250,68 +1223,84 @@ If ARG is the atom `-', scroll upward by nearly full screen." cua-rectangle-terminal-modifier-key cua-rectangle-modifier-key)) ;; C-return always toggles rectangle mark - (define-key cua-global-keymap cua-rectangle-mark-key 'cua-set-rectangle-mark) + (define-key cua-global-keymap cua-rectangle-mark-key #'cua-set-rectangle-mark) (unless (eq cua--rectangle-modifier-key 'meta) - (cua--M/H-key cua-global-keymap ?\s 'cua-set-rectangle-mark) + (cua--M/H-key cua-global-keymap ?\s #'cua-set-rectangle-mark) (define-key cua-global-keymap - (vector (list cua--rectangle-modifier-key 'mouse-1)) 'cua-mouse-set-rectangle-mark)) + (vector (list cua--rectangle-modifier-key 'mouse-1)) + #'cua-mouse-set-rectangle-mark)) - (define-key cua-global-keymap [(shift control ?\s)] 'cua-toggle-global-mark) + (define-key cua-global-keymap [(shift control ?\s)] #'cua-toggle-global-mark) ;; replace region with rectangle or element on kill ring - (define-key cua-global-keymap [remap yank] 'cua-paste) - (define-key cua-global-keymap [remap clipboard-yank] 'cua-paste) - (define-key cua-global-keymap [remap x-clipboard-yank] 'cua-paste) + (define-key cua-global-keymap [remap yank] #'cua-paste) + (define-key cua-global-keymap [remap clipboard-yank] #'cua-paste) + (define-key cua-global-keymap [remap x-clipboard-yank] #'cua-paste) ;; replace current yank with previous kill ring element - (define-key cua-global-keymap [remap yank-pop] 'cua-paste-pop) + (define-key cua-global-keymap [remap yank-pop] #'cua-paste-pop) ;; set mark - (define-key cua-global-keymap [remap set-mark-command] 'cua-set-mark) - (define-key cua-global-keymap [remap exchange-point-and-mark] 'cua-exchange-point-and-mark) + (define-key cua-global-keymap [remap set-mark-command] #'cua-set-mark) + (define-key cua-global-keymap [remap exchange-point-and-mark] + #'cua-exchange-point-and-mark) ;; scrolling - (define-key cua-global-keymap [remap scroll-up] 'cua-scroll-up) - (define-key cua-global-keymap [remap scroll-down] 'cua-scroll-down) - (define-key cua-global-keymap [remap scroll-up-command] 'cua-scroll-up) - (define-key cua-global-keymap [remap scroll-down-command] 'cua-scroll-down) + (define-key cua-global-keymap [remap scroll-up] #'cua-scroll-up) + (define-key cua-global-keymap [remap scroll-down] #'cua-scroll-down) + (define-key cua-global-keymap [remap scroll-up-command] #'cua-scroll-up) + (define-key cua-global-keymap [remap scroll-down-command] #'cua-scroll-down) - (define-key cua--cua-keys-keymap [(control x) timeout] 'kill-region) - (define-key cua--cua-keys-keymap [(control c) timeout] 'copy-region-as-kill) + (define-key cua--cua-keys-keymap [(control x) timeout] #'kill-region) + (define-key cua--cua-keys-keymap [(control c) timeout] #'copy-region-as-kill) (when cua-remap-control-z - (define-key cua--cua-keys-keymap [(control z)] 'undo)) + (define-key cua--cua-keys-keymap [(control z)] #'undo)) (when cua-remap-control-v - (define-key cua--cua-keys-keymap [(control v)] 'yank) + (define-key cua--cua-keys-keymap [(control v)] #'yank) (define-key cua--cua-keys-keymap [(meta v)] - 'delete-selection-repeat-replace-region)) + #'delete-selection-repeat-replace-region)) - (define-key cua--prefix-override-keymap [(control x)] 'cua--prefix-override-handler) - (define-key cua--prefix-override-keymap [(control c)] 'cua--prefix-override-handler) + (define-key cua--prefix-override-keymap [(control x)] + #'cua--prefix-override-handler) + (define-key cua--prefix-override-keymap [(control c)] + #'cua--prefix-override-handler) - (define-key cua--prefix-repeat-keymap [(control x) (control x)] 'cua--prefix-repeat-handler) - (define-key cua--prefix-repeat-keymap [(control c) (control c)] 'cua--prefix-repeat-handler) + (define-key cua--prefix-repeat-keymap [(control x) (control x)] + #'cua--prefix-repeat-handler) + (define-key cua--prefix-repeat-keymap [(control c) (control c)] + #'cua--prefix-repeat-handler) (dolist (key '(up down left right home end next prior)) - (define-key cua--prefix-repeat-keymap (vector '(control x) key) 'cua--prefix-cut-handler) - (define-key cua--prefix-repeat-keymap (vector '(control c) key) 'cua--prefix-copy-handler)) + (define-key cua--prefix-repeat-keymap (vector '(control x) key) + #'cua--prefix-cut-handler) + (define-key cua--prefix-repeat-keymap (vector '(control c) key) + #'cua--prefix-copy-handler)) ;; Enable shifted fallbacks for C-x and C-c when region is active - (define-key cua--region-keymap [(shift control x)] 'cua--shift-control-x-prefix) - (define-key cua--region-keymap [(shift control c)] 'cua--shift-control-c-prefix) + (define-key cua--region-keymap [(shift control x)] + #'cua--shift-control-x-prefix) + (define-key cua--region-keymap [(shift control c)] + #'cua--shift-control-c-prefix) ;; delete current region - (define-key cua--region-keymap [remap delete-backward-char] 'cua-delete-region) - (define-key cua--region-keymap [remap backward-delete-char] 'cua-delete-region) - (define-key cua--region-keymap [remap backward-delete-char-untabify] 'cua-delete-region) - (define-key cua--region-keymap [remap delete-char] 'cua-delete-region) - (define-key cua--region-keymap [remap delete-forward-char] 'cua-delete-region) + (define-key cua--region-keymap [remap delete-backward-char] + #'cua-delete-region) + (define-key cua--region-keymap [remap backward-delete-char] + #'cua-delete-region) + (define-key cua--region-keymap [remap backward-delete-char-untabify] + #'cua-delete-region) + (define-key cua--region-keymap [remap delete-char] + #'cua-delete-region) + (define-key cua--region-keymap [remap delete-forward-char] + #'cua-delete-region) ;; kill region - (define-key cua--region-keymap [remap kill-region] 'cua-cut-region) - (define-key cua--region-keymap [remap clipboard-kill-region] 'cua-cut-region) + (define-key cua--region-keymap [remap kill-region] #'cua-cut-region) + (define-key cua--region-keymap [remap clipboard-kill-region] #'cua-cut-region) ;; copy region - (define-key cua--region-keymap [remap copy-region-as-kill] 'cua-copy-region) - (define-key cua--region-keymap [remap kill-ring-save] 'cua-copy-region) - (define-key cua--region-keymap [remap clipboard-kill-ring-save] 'cua-copy-region) + (define-key cua--region-keymap [remap copy-region-as-kill] #'cua-copy-region) + (define-key cua--region-keymap [remap kill-ring-save] #'cua-copy-region) + (define-key cua--region-keymap [remap clipboard-kill-ring-save] + #'cua-copy-region) ;; cancel current region/rectangle - (define-key cua--region-keymap [remap keyboard-escape-quit] 'cua-cancel) - (define-key cua--region-keymap [remap keyboard-quit] 'cua-cancel) + (define-key cua--region-keymap [remap keyboard-escape-quit] #'cua-cancel) + (define-key cua--region-keymap [remap keyboard-quit] #'cua-cancel) ) @@ -1344,11 +1333,9 @@ You can customize `cua-enable-cua-keys' to completely disable the CUA bindings, or `cua-prefix-override-inhibit-delay' to change the prefix fallback behavior." :global t - :group 'cua :set-after '(cua-enable-modeline-indications cua-remap-control-v cua-remap-control-z cua-rectangle-mark-key cua-rectangle-modifier-key) - :require 'cua-base :link '(emacs-commentary-link "cua-base.el") (setq mark-even-if-inactive t) (setq highlight-nonselected-windows nil) @@ -1359,15 +1346,15 @@ the prefix fallback behavior." (if cua-mode (progn - (add-hook 'pre-command-hook 'cua--pre-command-handler) - (add-hook 'post-command-hook 'cua--post-command-handler) + (add-hook 'pre-command-hook #'cua--pre-command-handler) + (add-hook 'post-command-hook #'cua--post-command-handler) (if (and cua-enable-modeline-indications (not (assoc 'cua-mode minor-mode-alist))) (setq minor-mode-alist (cons '(cua-mode cua--status-string) minor-mode-alist))) (if cua-enable-cursor-indications (cua--update-indications))) - (remove-hook 'pre-command-hook 'cua--pre-command-handler) - (remove-hook 'post-command-hook 'cua--post-command-handler)) + (remove-hook 'pre-command-hook #'cua--pre-command-handler) + (remove-hook 'post-command-hook #'cua--post-command-handler)) (if (not cua-mode) (setq emulation-mode-map-alists diff --git a/lisp/emulation/cua-gmrk.el b/lisp/emulation/cua-gmrk.el index 6f6b9fce13..7014330b6e 100644 --- a/lisp/emulation/cua-gmrk.el +++ b/lisp/emulation/cua-gmrk.el @@ -1,4 +1,4 @@ -;;; cua-gmrk.el --- CUA unified global mark support +;;; cua-gmrk.el --- CUA unified global mark support -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -186,7 +186,7 @@ With prefix argument, don't jump to global mark when canceling it." (defun cua--copy-rectangle-to-global-mark (as-text) ;; Copy rectangle to global mark buffer/position. (if (cua--global-mark-active) - (let ((src-buf (current-buffer)) + (let (;; (src-buf (current-buffer)) (text (cua--extract-rectangle))) (with-current-buffer (marker-buffer cua--global-mark-marker) (goto-char (marker-position cua--global-mark-marker)) @@ -351,29 +351,44 @@ With prefix argument, don't jump to global mark when canceling it." ;;; Initialization (defun cua--init-global-mark () - (define-key cua--global-mark-keymap [remap copy-region-as-kill] 'cua-copy-to-global-mark) - (define-key cua--global-mark-keymap [remap kill-ring-save] 'cua-copy-to-global-mark) - (define-key cua--global-mark-keymap [remap kill-region] 'cua-cut-to-global-mark) - (define-key cua--global-mark-keymap [remap yank] 'cua-copy-next-to-global-mark) - - (define-key cua--global-mark-keymap [remap keyboard-escape-quit] 'cua-cancel-global-mark) - (define-key cua--global-mark-keymap [remap keyboard-quit] 'cua-cancel-global-mark) - - (define-key cua--global-mark-keymap [(control ?d)] 'cua-cut-next-to-global-mark) - (define-key cua--global-mark-keymap [remap delete-backward-char] 'cua-delete-backward-char-at-global-mark) - (define-key cua--global-mark-keymap [remap backward-delete-char] 'cua-delete-backward-char-at-global-mark) - (define-key cua--global-mark-keymap [remap backward-delete-char-untabify] 'cua-delete-backward-char-at-global-mark) - (define-key cua--global-mark-keymap [remap self-insert-command] 'cua-insert-char-at-global-mark) + (define-key cua--global-mark-keymap [remap copy-region-as-kill] + #'cua-copy-to-global-mark) + (define-key cua--global-mark-keymap [remap kill-ring-save] + #'cua-copy-to-global-mark) + (define-key cua--global-mark-keymap [remap kill-region] + #'cua-cut-to-global-mark) + (define-key cua--global-mark-keymap [remap yank] + #'cua-copy-next-to-global-mark) + + (define-key cua--global-mark-keymap [remap keyboard-escape-quit] + #'cua-cancel-global-mark) + (define-key cua--global-mark-keymap [remap keyboard-quit] + #'cua-cancel-global-mark) + + (define-key cua--global-mark-keymap [(control ?d)] + #'cua-cut-next-to-global-mark) + (define-key cua--global-mark-keymap [remap delete-backward-char] + #'cua-delete-backward-char-at-global-mark) + (define-key cua--global-mark-keymap [remap backward-delete-char] + #'cua-delete-backward-char-at-global-mark) + (define-key cua--global-mark-keymap [remap backward-delete-char-untabify] + #'cua-delete-backward-char-at-global-mark) + (define-key cua--global-mark-keymap [remap self-insert-command] + #'cua-insert-char-at-global-mark) ;; Catch self-inserting characters which are "stolen" by other modes (define-key cua--global-mark-keymap [t] '(menu-item "sic" cua-insert-char-at-global-mark :filter cua--self-insert-char-p)) - (define-key cua--global-mark-keymap [remap newline] 'cua-insert-newline-at-global-mark) - (define-key cua--global-mark-keymap [remap newline-and-indent] 'cua-insert-newline-at-global-mark) - (define-key cua--global-mark-keymap "\r" 'cua-insert-newline-at-global-mark) + (define-key cua--global-mark-keymap [remap newline] + #'cua-insert-newline-at-global-mark) + (define-key cua--global-mark-keymap [remap newline-and-indent] + #'cua-insert-newline-at-global-mark) + (define-key cua--global-mark-keymap "\r" + #'cua-insert-newline-at-global-mark) - (define-key cua--global-mark-keymap "\t" 'cua-indent-to-global-mark-column) + (define-key cua--global-mark-keymap "\t" + #'cua-indent-to-global-mark-column) (setq cua--global-mark-initialized t)) diff --git a/lisp/emulation/cua-rect.el b/lisp/emulation/cua-rect.el index b734fd15a2..e66050b713 100644 --- a/lisp/emulation/cua-rect.el +++ b/lisp/emulation/cua-rect.el @@ -90,7 +90,7 @@ See `cua--rectangle'.") (defvar cua--overlay-keymap (let ((map (make-sparse-keymap))) - (define-key map "\r" 'cua-rotate-rectangle))) + (define-key map "\r" #'cua-rotate-rectangle))) (defvar cua--virtual-edges-debug nil) @@ -104,7 +104,7 @@ See `cua--rectangle'.") (e (cua--rect-end-position))) (undo-boundary) (push (list 'apply 0 s e - 'cua--rect-undo-handler + #'cua--rect-undo-handler (copy-sequence cua--rectangle) t s e) buffer-undo-list)))) @@ -114,7 +114,7 @@ See `cua--rectangle'.") (setq cua--restored-rectangle (copy-sequence rect)) (setq cua--buffer-and-point-before-command nil)) (push (list 'apply 0 s (if on e s) - 'cua--rect-undo-handler rect on s e) + #'cua--rect-undo-handler rect on s e) buffer-undo-list)) ;;;###autoload @@ -1483,79 +1483,79 @@ With prefix arg, indent to that column." (cua--M/H-key cua--rectangle-keymap key cmd)) (defun cua--init-rectangles () - (define-key cua--rectangle-keymap cua-rectangle-mark-key 'cua-clear-rectangle-mark) - (define-key cua--region-keymap cua-rectangle-mark-key 'cua-toggle-rectangle-mark) + (define-key cua--rectangle-keymap cua-rectangle-mark-key #'cua-clear-rectangle-mark) + (define-key cua--region-keymap cua-rectangle-mark-key #'cua-toggle-rectangle-mark) (unless (eq cua--rectangle-modifier-key 'meta) - (cua--rect-M/H-key ?\s 'cua-clear-rectangle-mark) - (cua--M/H-key cua--region-keymap ?\s 'cua-toggle-rectangle-mark)) - - (define-key cua--rectangle-keymap [remap set-mark-command] 'cua-toggle-rectangle-mark) - - (define-key cua--rectangle-keymap [remap forward-char] 'cua-resize-rectangle-right) - (define-key cua--rectangle-keymap [remap right-char] 'cua-resize-rectangle-right) - (define-key cua--rectangle-keymap [remap backward-char] 'cua-resize-rectangle-left) - (define-key cua--rectangle-keymap [remap left-char] 'cua-resize-rectangle-left) - (define-key cua--rectangle-keymap [remap next-line] 'cua-resize-rectangle-down) - (define-key cua--rectangle-keymap [remap previous-line] 'cua-resize-rectangle-up) - (define-key cua--rectangle-keymap [remap end-of-line] 'cua-resize-rectangle-eol) - (define-key cua--rectangle-keymap [remap beginning-of-line] 'cua-resize-rectangle-bol) - (define-key cua--rectangle-keymap [remap end-of-buffer] 'cua-resize-rectangle-bot) - (define-key cua--rectangle-keymap [remap beginning-of-buffer] 'cua-resize-rectangle-top) - (define-key cua--rectangle-keymap [remap scroll-down] 'cua-resize-rectangle-page-up) - (define-key cua--rectangle-keymap [remap scroll-up] 'cua-resize-rectangle-page-down) - (define-key cua--rectangle-keymap [remap scroll-down-command] 'cua-resize-rectangle-page-up) - (define-key cua--rectangle-keymap [remap scroll-up-command] 'cua-resize-rectangle-page-down) - - (define-key cua--rectangle-keymap [remap delete-backward-char] 'cua-delete-char-rectangle) - (define-key cua--rectangle-keymap [remap backward-delete-char] 'cua-delete-char-rectangle) - (define-key cua--rectangle-keymap [remap backward-delete-char-untabify] 'cua-delete-char-rectangle) - (define-key cua--rectangle-keymap [remap self-insert-command] 'cua-insert-char-rectangle) + (cua--rect-M/H-key ?\s #'cua-clear-rectangle-mark) + (cua--M/H-key cua--region-keymap ?\s #'cua-toggle-rectangle-mark)) + + (define-key cua--rectangle-keymap [remap set-mark-command] #'cua-toggle-rectangle-mark) + + (define-key cua--rectangle-keymap [remap forward-char] #'cua-resize-rectangle-right) + (define-key cua--rectangle-keymap [remap right-char] #'cua-resize-rectangle-right) + (define-key cua--rectangle-keymap [remap backward-char] #'cua-resize-rectangle-left) + (define-key cua--rectangle-keymap [remap left-char] #'cua-resize-rectangle-left) + (define-key cua--rectangle-keymap [remap next-line] #'cua-resize-rectangle-down) + (define-key cua--rectangle-keymap [remap previous-line] #'cua-resize-rectangle-up) + (define-key cua--rectangle-keymap [remap end-of-line] #'cua-resize-rectangle-eol) + (define-key cua--rectangle-keymap [remap beginning-of-line] #'cua-resize-rectangle-bol) + (define-key cua--rectangle-keymap [remap end-of-buffer] #'cua-resize-rectangle-bot) + (define-key cua--rectangle-keymap [remap beginning-of-buffer] #'cua-resize-rectangle-top) + (define-key cua--rectangle-keymap [remap scroll-down] #'cua-resize-rectangle-page-up) + (define-key cua--rectangle-keymap [remap scroll-up] #'cua-resize-rectangle-page-down) + (define-key cua--rectangle-keymap [remap scroll-down-command] #'cua-resize-rectangle-page-up) + (define-key cua--rectangle-keymap [remap scroll-up-command] #'cua-resize-rectangle-page-down) + + (define-key cua--rectangle-keymap [remap delete-backward-char] #'cua-delete-char-rectangle) + (define-key cua--rectangle-keymap [remap backward-delete-char] #'cua-delete-char-rectangle) + (define-key cua--rectangle-keymap [remap backward-delete-char-untabify] #'cua-delete-char-rectangle) + (define-key cua--rectangle-keymap [remap self-insert-command] #'cua-insert-char-rectangle) ;; Catch self-inserting characters which are "stolen" by other modes (define-key cua--rectangle-keymap [t] '(menu-item "sic" cua-insert-char-rectangle :filter cua--self-insert-char-p)) - (define-key cua--rectangle-keymap "\r" 'cua-rotate-rectangle) - (define-key cua--rectangle-keymap "\t" 'cua-indent-rectangle) - - (define-key cua--rectangle-keymap [(control ??)] 'cua-help-for-rectangle) - - (define-key cua--rectangle-keymap [mouse-1] 'cua-mouse-set-rectangle-mark) - (define-key cua--rectangle-keymap [down-mouse-1] 'cua--mouse-ignore) - (define-key cua--rectangle-keymap [drag-mouse-1] 'cua--mouse-ignore) - (define-key cua--rectangle-keymap [mouse-3] 'cua-mouse-save-then-kill-rectangle) - (define-key cua--rectangle-keymap [down-mouse-3] 'cua--mouse-ignore) - (define-key cua--rectangle-keymap [drag-mouse-3] 'cua--mouse-ignore) - - (cua--rect-M/H-key 'up 'cua-move-rectangle-up) - (cua--rect-M/H-key 'down 'cua-move-rectangle-down) - (cua--rect-M/H-key 'left 'cua-move-rectangle-left) - (cua--rect-M/H-key 'right 'cua-move-rectangle-right) - - (cua--rect-M/H-key '(control up) 'cua-scroll-rectangle-up) - (cua--rect-M/H-key '(control down) 'cua-scroll-rectangle-down) - - (cua--rect-M/H-key ?a 'cua-align-rectangle) - (cua--rect-M/H-key ?b 'cua-blank-rectangle) - (cua--rect-M/H-key ?c 'cua-close-rectangle) - (cua--rect-M/H-key ?f 'cua-fill-char-rectangle) - (cua--rect-M/H-key ?i 'cua-incr-rectangle) - (cua--rect-M/H-key ?k 'cua-cut-rectangle-as-text) - (cua--rect-M/H-key ?l 'cua-downcase-rectangle) - (cua--rect-M/H-key ?m 'cua-copy-rectangle-as-text) - (cua--rect-M/H-key ?n 'cua-sequence-rectangle) - (cua--rect-M/H-key ?o 'cua-open-rectangle) - (cua--rect-M/H-key ?p 'cua-toggle-rectangle-virtual-edges) - (cua--rect-M/H-key ?P 'cua-do-rectangle-padding) - (cua--rect-M/H-key ?q 'cua-refill-rectangle) - (cua--rect-M/H-key ?r 'cua-replace-in-rectangle) - (cua--rect-M/H-key ?R 'cua-reverse-rectangle) - (cua--rect-M/H-key ?s 'cua-string-rectangle) - (cua--rect-M/H-key ?t 'cua-text-fill-rectangle) - (cua--rect-M/H-key ?u 'cua-upcase-rectangle) - (cua--rect-M/H-key ?| 'cua-shell-command-on-rectangle) - (cua--rect-M/H-key ?' 'cua-restrict-prefix-rectangle) - (cua--rect-M/H-key ?/ 'cua-restrict-regexp-rectangle) + (define-key cua--rectangle-keymap "\r" #'cua-rotate-rectangle) + (define-key cua--rectangle-keymap "\t" #'cua-indent-rectangle) + + (define-key cua--rectangle-keymap [(control ??)] #'cua-help-for-rectangle) + + (define-key cua--rectangle-keymap [mouse-1] #'cua-mouse-set-rectangle-mark) + (define-key cua--rectangle-keymap [down-mouse-1] #'cua--mouse-ignore) + (define-key cua--rectangle-keymap [drag-mouse-1] #'cua--mouse-ignore) + (define-key cua--rectangle-keymap [mouse-3] #'cua-mouse-save-then-kill-rectangle) + (define-key cua--rectangle-keymap [down-mouse-3] #'cua--mouse-ignore) + (define-key cua--rectangle-keymap [drag-mouse-3] #'cua--mouse-ignore) + + (cua--rect-M/H-key 'up #'cua-move-rectangle-up) + (cua--rect-M/H-key 'down #'cua-move-rectangle-down) + (cua--rect-M/H-key 'left #'cua-move-rectangle-left) + (cua--rect-M/H-key 'right #'cua-move-rectangle-right) + + (cua--rect-M/H-key '(control up) #'cua-scroll-rectangle-up) + (cua--rect-M/H-key '(control down) #'cua-scroll-rectangle-down) + + (cua--rect-M/H-key ?a #'cua-align-rectangle) + (cua--rect-M/H-key ?b #'cua-blank-rectangle) + (cua--rect-M/H-key ?c #'cua-close-rectangle) + (cua--rect-M/H-key ?f #'cua-fill-char-rectangle) + (cua--rect-M/H-key ?i #'cua-incr-rectangle) + (cua--rect-M/H-key ?k #'cua-cut-rectangle-as-text) + (cua--rect-M/H-key ?l #'cua-downcase-rectangle) + (cua--rect-M/H-key ?m #'cua-copy-rectangle-as-text) + (cua--rect-M/H-key ?n #'cua-sequence-rectangle) + (cua--rect-M/H-key ?o #'cua-open-rectangle) + (cua--rect-M/H-key ?p #'cua-toggle-rectangle-virtual-edges) + (cua--rect-M/H-key ?P #'cua-do-rectangle-padding) + (cua--rect-M/H-key ?q #'cua-refill-rectangle) + (cua--rect-M/H-key ?r #'cua-replace-in-rectangle) + (cua--rect-M/H-key ?R #'cua-reverse-rectangle) + (cua--rect-M/H-key ?s #'cua-string-rectangle) + (cua--rect-M/H-key ?t #'cua-text-fill-rectangle) + (cua--rect-M/H-key ?u #'cua-upcase-rectangle) + (cua--rect-M/H-key ?| #'cua-shell-command-on-rectangle) + (cua--rect-M/H-key ?' #'cua-restrict-prefix-rectangle) + (cua--rect-M/H-key ?/ #'cua-restrict-regexp-rectangle) (setq cua--rectangle-initialized t)) diff --git a/lisp/emulation/edt-mapper.el b/lisp/emulation/edt-mapper.el index 98085c6214..c1c17723a4 100644 --- a/lisp/emulation/edt-mapper.el +++ b/lisp/emulation/edt-mapper.el @@ -1,4 +1,4 @@ -;;; edt-mapper.el --- create an EDT LK-201 map file for X-Windows Emacs +;;; edt-mapper.el --- create an EDT LK-201 map file for X-Windows Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 1994-1995, 2000-2021 Free Software Foundation, Inc. @@ -176,7 +176,7 @@ (mapc (lambda (function-key) (if (not (lookup-key (current-global-map) function-key)) - (define-key (current-global-map) function-key 'forward-char))) + (define-key (current-global-map) function-key #'forward-char))) '([kp-0] [kp-1] [kp-2] [kp-3] [kp-4] [kp-5] [kp-6] [kp-7] [kp-8] [kp-9] [kp-space] diff --git a/lisp/emulation/edt.el b/lisp/emulation/edt.el index 7760a7f2b4..b8dea2f2cc 100644 --- a/lisp/emulation/edt.el +++ b/lisp/emulation/edt.el @@ -1,4 +1,4 @@ -;;; edt.el --- enhanced EDT keypad mode emulation for GNU Emacs +;;; edt.el --- enhanced EDT keypad mode emulation for GNU Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 1986, 1992-1995, 2000-2021 Free Software Foundation, ;; Inc. @@ -192,8 +192,7 @@ Emulation. If set to nil (the default), the `page-delimiter' variable is set to \"\\f\" when edt-emulation-on is first invoked. This setting replicates EDT's page delimiter behavior. The original value is restored when edt-emulation-off is called." - :type 'boolean - :group 'edt) + :type 'boolean) (defcustom edt-use-EDT-control-key-bindings nil "Emacs MUST be restarted for a change in value to take effect! @@ -201,8 +200,7 @@ Non-nil causes the control key bindings to be replaced with EDT bindings. If set to nil (the default), EDT control key bindings are not used and the current Emacs control key bindings are retained for use within the EDT emulation." - :type 'boolean - :group 'edt) + :type 'boolean) (defcustom edt-word-entities '(?\t) "Specifies the list of EDT word entity characters. @@ -226,22 +224,19 @@ representations, which you can also use: In EDT Emulation movement-by-word commands, each character in the list will be treated as if it were a separate word." - :type '(repeat integer) - :group 'edt) + :type '(repeat integer)) (defcustom edt-top-scroll-margin 10 "Scroll margin at the top of the screen. Interpreted as a percent of the current window size with a default setting of 10%. If set to 0, top scroll margin is disabled." - :type 'integer - :group 'edt) + :type 'integer) (defcustom edt-bottom-scroll-margin 15 "Scroll margin at the bottom of the screen. Interpreted as a percent of the current window size with a default setting of 15%. If set to 0, bottom scroll margin is disabled." - :type 'integer - :group 'edt) + :type 'integer) ;;; ;;; Internal Variables @@ -323,31 +318,31 @@ This means that an edt-user.el file was found in the user's `load-path'.") ;;;; EDT Emulation Commands ;;;; -;;; Almost all of EDT's keypad mode commands have equivalent Emacs -;;; function counterparts. But many of these counterparts behave -;;; somewhat differently in Emacs. -;;; -;;; So, the following Emacs functions emulate, where practical, the -;;; exact behavior of the corresponding EDT keypad mode commands. In -;;; a few cases, the emulation is not exact, but it should be close -;;; enough for most EDT die-hards. -;;; +;; Almost all of EDT's keypad mode commands have equivalent Emacs +;; function counterparts. But many of these counterparts behave +;; somewhat differently in Emacs. +;; +;; So, the following Emacs functions emulate, where practical, the +;; exact behavior of the corresponding EDT keypad mode commands. In +;; a few cases, the emulation is not exact, but it should be close +;; enough for most EDT die-hards. +;; ;;; ;;; PAGE ;;; -;;; Emacs uses the regexp assigned to page-delimiter to determine what -;;; marks a page break. This is normally "^\f", which causes the -;;; edt-page command to ignore form feeds not located at the beginning -;;; of a line. To emulate the EDT PAGE command exactly, -;;; page-delimiter is set to "\f" when EDT emulation is turned on, and -;;; restored to its original value when EDT emulation is turned off. -;;; But this can be overridden if the EDT definition is not desired by -;;; placing -;;; -;;; (setq edt-keep-current-page-delimiter t) -;;; -;;; in your init file. +;; Emacs uses the regexp assigned to page-delimiter to determine what +;; marks a page break. This is normally "^\f", which causes the +;; edt-page command to ignore form feeds not located at the beginning +;; of a line. To emulate the EDT PAGE command exactly, +;; page-delimiter is set to "\f" when EDT emulation is turned on, and +;; restored to its original value when EDT emulation is turned off. +;; But this can be overridden if the EDT definition is not desired by +;; placing +;; +;; (setq edt-keep-current-page-delimiter t) +;; +;; in your init file. (defun edt-page-forward (num) "Move forward to just after next page delimiter. @@ -384,12 +379,12 @@ Argument NUM is the number of page delimiters to move." ;;; ;;; SECT ;;; -;;; EDT defaults a section size to be 16 lines of its one and only -;;; 24-line window. That's two-thirds of the window at a time. The -;;; EDT SECT commands moves the cursor, not the window. -;;; -;;; This emulation of EDT's SECT moves the cursor approximately -;;; two-thirds of the current window at a time. +;; EDT defaults a section size to be 16 lines of its one and only +;; 24-line window. That's two-thirds of the window at a time. The +;; EDT SECT commands moves the cursor, not the window. +;; +;; This emulation of EDT's SECT moves the cursor approximately +;; two-thirds of the current window at a time. (defun edt-sect-forward (num) "Move cursor forward two-thirds of a window's number of lines. @@ -417,8 +412,8 @@ Argument NUM is the number of sections to move." ;;; ;;; BEGINNING OF LINE ;;; -;;; EDT's beginning-of-line command is not affected by current -;;; direction, for some unknown reason. +;; EDT's beginning-of-line command is not affected by current +;; direction, for some unknown reason. (defun edt-beginning-of-line (num) "Move backward to next beginning of line mark. @@ -470,13 +465,13 @@ Argument NUM is the number of EOL marks to move." ;;; ;;; WORD ;;; -;;; This one is a tad messy. To emulate EDT's behavior everywhere in -;;; the file (beginning of file, end of file, beginning of line, end -;;; of line, etc.) it takes a bit of special handling. -;;; -;;; The variable edt-word-entities contains a list of characters which -;;; are to be viewed as distinct words wherever they appear in the -;;; buffer. This emulates the EDT line mode command SET ENTITY WORD. +;; This one is a tad messy. To emulate EDT's behavior everywhere in +;; the file (beginning of file, end of file, beginning of line, end +;; of line, etc.) it takes a bit of special handling. +;; +;; The variable edt-word-entities contains a list of characters which +;; are to be viewed as distinct words wherever they appear in the +;; buffer. This emulates the EDT line mode command SET ENTITY WORD. (defun edt-one-word-forward () @@ -567,9 +562,9 @@ Argument NUM is the number of characters to move." ;;; ;;; LINE ;;; -;;; When direction is set to BACKUP, LINE behaves just like BEGINNING -;;; OF LINE in EDT. So edt-line-backward is not really needed as a -;;; separate function. +;; When direction is set to BACKUP, LINE behaves just like BEGINNING +;; OF LINE in EDT. So edt-line-backward is not really needed as a +;; separate function. (defun edt-line-backward (num) "Move backward to next beginning of line mark. @@ -655,6 +650,7 @@ Argument NUM is the number of lines to move." (far (save-excursion (goto-char bottom) (point-at-bol (1- height))))) + (ignore top left far) ,@body)) ;;; @@ -1203,9 +1199,9 @@ Argument BOTTOM is the bottom margin in number of lines or percent of window." ;;;; ;;; -;;; Several enhancements and additions to EDT keypad mode commands are -;;; provided here. Some of these have been motivated by similar -;;; TPU/EVE and EVE-Plus commands. Others are new. +;; Several enhancements and additions to EDT keypad mode commands are +;; provided here. Some of these have been motivated by similar +;; TPU/EVE and EVE-Plus commands. Others are new. ;;; ;;; CHANGE DIRECTION @@ -1378,8 +1374,8 @@ Definition is stored in `edt-last-replaced-key-definition'." ;;; ;;; SCROLL WINDOW ;;; -;;; Scroll a window (less one line) at a time. Leave cursor in center of -;;; window. +;; Scroll a window (less one line) at a time. Leave cursor in center of +;; window. (defun edt-scroll-window-forward (num) "Scroll forward one window in buffer, less one line. @@ -2051,7 +2047,7 @@ Optional argument USER-SETUP non-nil means called from function (fset 'edt-emulation-on (symbol-function 'edt-select-default-global-map)) (edt-select-default-global-map))) ;; Keep the menu bar Buffers menu up-to-date in edt-default-global-map. - (add-hook 'menu-bar-update-hook 'edt-default-menu-bar-update-buffers)) + (add-hook 'menu-bar-update-hook #'edt-default-menu-bar-update-buffers)) (defun edt-user-emulation-setup () "Setup user custom emulation of DEC's EDT editor." @@ -2072,7 +2068,7 @@ Optional argument USER-SETUP non-nil means called from function (edt-setup-user-bindings)) (edt-select-user-global-map) ;; Keep the menu bar Buffers menu up-to-date in edt-user-global-map. - (add-hook 'menu-bar-update-hook 'edt-user-menu-bar-update-buffers)) + (add-hook 'menu-bar-update-hook #'edt-user-menu-bar-update-buffers)) (defun edt-select-default-global-map() "Select default EDT emulation key bindings." @@ -2490,7 +2486,7 @@ G-C-\\: Split Window | FNDNXT | Yank | CUT | (and b (with-current-buffer b (set-buffer-modified-p t))) - (fset 'help-print-return-message 'ignore) + (fset 'help-print-return-message #'ignore) (call-interactively fun) (and (get-buffer name) (get-buffer-window (get-buffer name)) diff --git a/lisp/emulation/keypad.el b/lisp/emulation/keypad.el index e4f3c4d53e..56202c7fff 100644 --- a/lisp/emulation/keypad.el +++ b/lisp/emulation/keypad.el @@ -1,4 +1,4 @@ -;;; keypad.el --- simplified keypad bindings +;;; keypad.el --- simplified keypad bindings -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. @@ -101,10 +101,10 @@ "Specifies the keypad setup for unshifted keypad keys when NumLock is off. When selecting the plain numeric keypad setup, the character returned by the decimal key must be specified." - :set (lambda (symbol value) + :set (lambda (_symbol value) (if value (keypad-setup value nil nil value))) - :initialize 'custom-initialize-default + :initialize #'custom-initialize-default :link '(emacs-commentary-link "keypad.el") :version "22.1" :type '(choice (const :tag "Plain numeric keypad" numeric) @@ -124,10 +124,10 @@ decimal key must be specified." "Specifies the keypad setup for unshifted keypad keys when NumLock is on. When selecting the plain numeric keypad setup, the character returned by the decimal key must be specified." - :set (lambda (symbol value) + :set (lambda (_symbol value) (if value (keypad-setup value t nil value))) - :initialize 'custom-initialize-default + :initialize #'custom-initialize-default :link '(emacs-commentary-link "keypad.el") :version "22.1" :type '(choice (const :tag "Plain numeric keypad" numeric) @@ -147,10 +147,10 @@ decimal key must be specified." "Specifies the keypad setup for shifted keypad keys when NumLock is off. When selecting the plain numeric keypad setup, the character returned by the decimal key must be specified." - :set (lambda (symbol value) + :set (lambda (_symbol value) (if value (keypad-setup value nil t value))) - :initialize 'custom-initialize-default + :initialize #'custom-initialize-default :link '(emacs-commentary-link "keypad.el") :version "22.1" :type '(choice (const :tag "Plain numeric keypad" numeric) @@ -170,10 +170,10 @@ decimal key must be specified." "Specifies the keypad setup for shifted keypad keys when NumLock is off. When selecting the plain numeric keypad setup, the character returned by the decimal key must be specified." - :set (lambda (symbol value) + :set (lambda (_symbol value) (if value (keypad-setup value t t value))) - :initialize 'custom-initialize-default + :initialize #'custom-initialize-default :link '(emacs-commentary-link "keypad.el") :version "22.1" :type '(choice (const :tag "Plain numeric keypad" numeric) diff --git a/lisp/emulation/viper-cmd.el b/lisp/emulation/viper-cmd.el index f38be90889..42d6c1eb19 100644 --- a/lisp/emulation/viper-cmd.el +++ b/lisp/emulation/viper-cmd.el @@ -24,8 +24,6 @@ ;;; Code: -(provide 'viper-cmd) - ;; Compiler pacifier (defvar viper-minibuffer-current-face) (defvar viper-minibuffer-insert-face) @@ -293,15 +291,15 @@ ;; desirable that viper-pre-command-sentinel is the last hook and ;; viper-post-command-sentinel is the first hook. - (remove-hook 'post-command-hook 'viper-post-command-sentinel) - (add-hook 'post-command-hook 'viper-post-command-sentinel) - (remove-hook 'pre-command-hook 'viper-pre-command-sentinel) - (add-hook 'pre-command-hook 'viper-pre-command-sentinel t) + (remove-hook 'post-command-hook #'viper-post-command-sentinel) + (add-hook 'post-command-hook #'viper-post-command-sentinel) + (remove-hook 'pre-command-hook #'viper-pre-command-sentinel) + (add-hook 'pre-command-hook #'viper-pre-command-sentinel t) ;; These hooks will be added back if switching to insert/replace mode (remove-hook 'viper-post-command-hooks - 'viper-insert-state-post-command-sentinel 'local) + #'viper-insert-state-post-command-sentinel 'local) (remove-hook 'viper-pre-command-hooks - 'viper-insert-state-pre-command-sentinel 'local) + #'viper-insert-state-pre-command-sentinel 'local) (setq viper-intermediate-command nil) (cond ((eq new-state 'vi-state) (cond ((member viper-current-state '(insert-state replace-state)) @@ -344,9 +342,9 @@ (viper-move-marker-locally 'viper-last-posn-while-in-insert-state (point)) (add-hook 'viper-post-command-hooks - 'viper-insert-state-post-command-sentinel t 'local) + #'viper-insert-state-post-command-sentinel t 'local) (add-hook 'viper-pre-command-hooks - 'viper-insert-state-pre-command-sentinel t 'local)) + #'viper-insert-state-pre-command-sentinel t 'local)) ) ; outermost cond ;; Nothing needs to be done to switch to emacs mode! Just set some @@ -378,12 +376,12 @@ (cond ((memq state '(insert-state replace-state)) (if viper-auto-indent (progn - (define-key viper-insert-basic-map "\C-m" 'viper-autoindent) + (define-key viper-insert-basic-map "\C-m" #'viper-autoindent) (if viper-want-emacs-keys-in-insert ;; expert (define-key viper-insert-basic-map "\C-j" nil) ;; novice - (define-key viper-insert-basic-map "\C-j" 'viper-autoindent))) + (define-key viper-insert-basic-map "\C-j" #'viper-autoindent))) (define-key viper-insert-basic-map "\C-m" nil) (define-key viper-insert-basic-map "\C-j" nil)) @@ -392,25 +390,24 @@ (if viper-want-ctl-h-help (progn - (define-key viper-insert-basic-map "\C-h" 'help-command) - (define-key viper-replace-map "\C-h" 'help-command)) + (define-key viper-insert-basic-map "\C-h" #'help-command) + (define-key viper-replace-map "\C-h" #'help-command)) (define-key viper-insert-basic-map - "\C-h" 'viper-del-backward-char-in-insert) + "\C-h" #'viper-del-backward-char-in-insert) (define-key viper-replace-map - "\C-h" 'viper-del-backward-char-in-replace)) + "\C-h" #'viper-del-backward-char-in-replace)) ;; In XEmacs, C-h overrides backspace, so we make sure it doesn't. (define-key viper-insert-basic-map - [backspace] 'viper-del-backward-char-in-insert) + [backspace] #'viper-del-backward-char-in-insert) (define-key viper-replace-map - [backspace] 'viper-del-backward-char-in-replace) + [backspace] #'viper-del-backward-char-in-replace) ) ; end insert/replace case (t ; Vi state (setq viper-vi-diehard-minor-mode (not viper-want-emacs-keys-in-vi)) - (if viper-want-ctl-h-help - (define-key viper-vi-basic-map "\C-h" 'help-command) - (define-key viper-vi-basic-map "\C-h" 'viper-backward-char)) + (define-key viper-vi-basic-map "\C-h" + (if viper-want-ctl-h-help #'help-command #'viper-backward-char)) ;; In XEmacs, C-h overrides backspace, so we make sure it doesn't. - (define-key viper-vi-basic-map [backspace] 'viper-backward-char)) + (define-key viper-vi-basic-map [backspace] #'viper-backward-char)) )) @@ -831,7 +828,7 @@ Vi's prefix argument will be used. Otherwise, the prefix argument passed to (condition-case nil (let (viper-vi-kbd-minor-mode) ; execute without kbd macros - (setq result (eval form))) + (setq result (eval form t))) (error (signal 'quit nil))) @@ -847,7 +844,7 @@ Similar to `viper-escape-to-emacs', but accepts forms rather than keystrokes." (let ((buff (current-buffer)) result) (viper-set-mode-vars-for 'emacs-state) - (setq result (eval form)) + (setq result (eval form t)) (if (not (equal buff (current-buffer))) ; cmd switched buffer (with-current-buffer buff (viper-set-mode-vars-for viper-current-state))) @@ -1411,17 +1408,17 @@ as a Meta key and any number of multiple escapes are allowed." ;; without affecting other functions. Buffer search can now be bound ;; to any character. -(aset viper-exec-array ?c 'viper-exec-change) -(aset viper-exec-array ?C 'viper-exec-Change) -(aset viper-exec-array ?d 'viper-exec-delete) -(aset viper-exec-array ?D 'viper-exec-Delete) -(aset viper-exec-array ?y 'viper-exec-yank) -(aset viper-exec-array ?Y 'viper-exec-Yank) -(aset viper-exec-array ?r 'viper-exec-dummy) -(aset viper-exec-array ?! 'viper-exec-bang) -(aset viper-exec-array ?< 'viper-exec-shift) -(aset viper-exec-array ?> 'viper-exec-shift) -(aset viper-exec-array ?= 'viper-exec-equals) +(aset viper-exec-array ?c #'viper-exec-change) +(aset viper-exec-array ?C #'viper-exec-Change) +(aset viper-exec-array ?d #'viper-exec-delete) +(aset viper-exec-array ?D #'viper-exec-Delete) +(aset viper-exec-array ?y #'viper-exec-yank) +(aset viper-exec-array ?Y #'viper-exec-Yank) +(aset viper-exec-array ?r #'viper-exec-dummy) +(aset viper-exec-array ?! #'viper-exec-bang) +(aset viper-exec-array ?< #'viper-exec-shift) +(aset viper-exec-array ?> #'viper-exec-shift) +(aset viper-exec-array ?= #'viper-exec-equals) @@ -1560,7 +1557,7 @@ invokes the command before that, etc." (defun viper-undo-sentinel (beg end length) (run-hook-with-args 'viper-undo-functions beg end length)) -(add-hook 'after-change-functions 'viper-undo-sentinel) +(add-hook 'after-change-functions #'viper-undo-sentinel) ;; Hook used in viper-undo (defun viper-after-change-undo-hook (beg end _len) @@ -1570,7 +1567,7 @@ invokes the command before that, etc." ;; some other hooks may be changing various text properties in ;; the buffer in response to 'undo'; so remove this hook to avoid ;; its repeated invocation - (remove-hook 'viper-undo-functions 'viper-after-change-undo-hook 'local) + (remove-hook 'viper-undo-functions #'viper-after-change-undo-hook 'local) )) (defun viper-undo () @@ -1581,7 +1578,7 @@ invokes the command before that, etc." undo-beg-posn undo-end-posn) ;; the viper-after-change-undo-hook removes itself after the 1st invocation - (add-hook 'viper-undo-functions 'viper-after-change-undo-hook nil 'local) + (add-hook 'viper-undo-functions #'viper-after-change-undo-hook nil 'local) (undo-start) (undo-more 2) @@ -1853,8 +1850,8 @@ Undo previous insertion and inserts new." ;;; Minibuffer business (defsubst viper-set-minibuffer-style () - (add-hook 'minibuffer-setup-hook 'viper-minibuffer-setup-sentinel) - (add-hook 'post-command-hook 'viper-minibuffer-post-command-hook)) + (add-hook 'minibuffer-setup-hook #'viper-minibuffer-setup-sentinel) + (add-hook 'post-command-hook #'viper-minibuffer-post-command-hook)) (defun viper-minibuffer-setup-sentinel () @@ -2017,11 +2014,12 @@ problems." padding (viper-array-to-string (this-command-keys)) temp-msg "") ;; the following tries to be smart about what to put in history - (if (not (string= val (car (eval history-var)))) - (set history-var (cons val (eval history-var)))) - (if (or (string= (nth 0 (eval history-var)) (nth 1 (eval history-var))) - (string= (nth 0 (eval history-var)) "")) - (set history-var (cdr (eval history-var)))) + (if (not (string= val (car (symbol-value history-var)))) + (push val (symbol-value history-var))) + (if (or (string= (nth 0 (symbol-value history-var)) + (nth 1 (symbol-value history-var))) + (string= (nth 0 (symbol-value history-var)) "")) + (pop (symbol-value history-var))) ;; If the user enters nothing but the prev cmd wasn't viper-ex, ;; viper-command-argument, or `! shell-command', this probably means ;; that the user typed something then erased. Return "" in this case, not @@ -2192,22 +2190,22 @@ problems." viper-sitting-in-replace t viper-replace-chars-to-delete 0) (add-hook - 'viper-after-change-functions 'viper-replace-mode-spy-after t 'local) + 'viper-after-change-functions #'viper-replace-mode-spy-after t 'local) (add-hook - 'viper-before-change-functions 'viper-replace-mode-spy-before t 'local) + 'viper-before-change-functions #'viper-replace-mode-spy-before t 'local) ;; this will get added repeatedly, but no harm - (add-hook 'after-change-functions 'viper-after-change-sentinel t) - (add-hook 'before-change-functions 'viper-before-change-sentinel t) + (add-hook 'after-change-functions #'viper-after-change-sentinel t) + (add-hook 'before-change-functions #'viper-before-change-sentinel t) (viper-move-marker-locally 'viper-last-posn-in-replace-region (viper-replace-start)) (add-hook - 'viper-post-command-hooks 'viper-replace-state-post-command-sentinel + 'viper-post-command-hooks #'viper-replace-state-post-command-sentinel t 'local) (add-hook - 'viper-pre-command-hooks 'viper-replace-state-pre-command-sentinel t 'local) + 'viper-pre-command-hooks #'viper-replace-state-pre-command-sentinel t 'local) ;; guard against a smarty who switched from R-replace to normal replace (remove-hook - 'viper-post-command-hooks 'viper-R-state-post-command-sentinel 'local) + 'viper-post-command-hooks #'viper-R-state-post-command-sentinel 'local) (if overwrite-mode (overwrite-mode -1)) ) @@ -2281,13 +2279,13 @@ problems." ;; Don't delete anything if current point is past the end of the overlay. (defun viper-finish-change () (remove-hook - 'viper-after-change-functions 'viper-replace-mode-spy-after 'local) + 'viper-after-change-functions #'viper-replace-mode-spy-after 'local) (remove-hook - 'viper-before-change-functions 'viper-replace-mode-spy-before 'local) + 'viper-before-change-functions #'viper-replace-mode-spy-before 'local) (remove-hook - 'viper-post-command-hooks 'viper-replace-state-post-command-sentinel 'local) + 'viper-post-command-hooks #'viper-replace-state-post-command-sentinel 'local) (remove-hook - 'viper-pre-command-hooks 'viper-replace-state-pre-command-sentinel 'local) + 'viper-pre-command-hooks #'viper-replace-state-pre-command-sentinel 'local) (viper-restore-cursor-color 'after-replace-mode) (setq viper-sitting-in-replace nil) ; just in case we'll need to know it (save-excursion @@ -2317,21 +2315,21 @@ problems." (defun viper-finish-R-mode () (remove-hook - 'viper-post-command-hooks 'viper-R-state-post-command-sentinel 'local) + 'viper-post-command-hooks #'viper-R-state-post-command-sentinel 'local) (remove-hook - 'viper-pre-command-hooks 'viper-replace-state-pre-command-sentinel 'local) + 'viper-pre-command-hooks #'viper-replace-state-pre-command-sentinel 'local) (viper-downgrade-to-insert)) (defun viper-start-R-mode () ;; Leave arg as 1, not t: XEmacs insists that it must be a pos number (overwrite-mode 1) (add-hook - 'viper-post-command-hooks 'viper-R-state-post-command-sentinel t 'local) + 'viper-post-command-hooks #'viper-R-state-post-command-sentinel t 'local) (add-hook - 'viper-pre-command-hooks 'viper-replace-state-pre-command-sentinel t 'local) + 'viper-pre-command-hooks #'viper-replace-state-pre-command-sentinel t 'local) ;; guard against a smarty who switched from R-replace to normal replace (remove-hook - 'viper-post-command-hooks 'viper-replace-state-post-command-sentinel 'local) + 'viper-post-command-hooks #'viper-replace-state-post-command-sentinel 'local) ) @@ -3467,7 +3465,8 @@ controlled by the sign of prefix numeric value." '(viper-command-argument viper-digit-argument viper-repeat)) (setq viper-this-command-keys (this-command-keys))) (let* ((keymap (let ((keymap (copy-keymap minibuffer-local-map))) - (define-key keymap [(control ?s)] 'viper-insert-isearch-string) + (define-key keymap [(control ?s)] + #'viper-insert-isearch-string) keymap)) (s (viper-read-string-with-history prompt @@ -3776,8 +3775,8 @@ Null string will repeat previous search." (char-to-string viper-buffer-search-char)) (t (error "viper-buffer-search-char: wrong value type, %S" viper-buffer-search-char))) - 'viper-command-argument) - (aset viper-exec-array viper-buffer-search-char 'viper-exec-buffer-search) + #'viper-command-argument) + (aset viper-exec-array viper-buffer-search-char #'viper-exec-buffer-search) (setq viper-prefix-commands (cons viper-buffer-search-char viper-prefix-commands))) @@ -4368,7 +4367,7 @@ One can use \\=`\\=` and \\='\\=' to temporarily jump 1 step back." ;; Input Mode Indentation -(define-obsolete-function-alias 'viper-looking-back 'looking-back "24.4") +(define-obsolete-function-alias 'viper-looking-back #'looking-back "24.4") (defun viper-forward-indent () @@ -4511,8 +4510,8 @@ One can use \\=`\\=` and \\='\\=' to temporarily jump 1 step back." ;; standard value. Otherwise, get the value saved in the alist STORAGE. If ;; STORAGE is nil, use viper-saved-user-settings. (defun viper-standard-value (symbol &optional storage) - (or (eval (car (get symbol 'customized-value))) - (eval (car (get symbol 'saved-value))) + (or (eval (car (get symbol 'customized-value)) t) + (eval (car (get symbol 'saved-value)) t) (nth 1 (assoc symbol (or storage viper-saved-user-settings))))) @@ -4849,7 +4848,5 @@ Mail anyway (y or n)? ") nil 'delete-other-windows salutation))) - - - +(provide 'viper-cmd) ;;; viper-cmd.el ends here diff --git a/lisp/emulation/viper-ex.el b/lisp/emulation/viper-ex.el index 238faed069..5b2fa048a0 100644 --- a/lisp/emulation/viper-ex.el +++ b/lisp/emulation/viper-ex.el @@ -1,4 +1,4 @@ -;;; viper-ex.el --- functions implementing the Ex commands for Viper +;;; viper-ex.el --- functions implementing the Ex commands for Viper -*- lexical-binding: t; -*- ;; Copyright (C) 1994-1998, 2000-2021 Free Software Foundation, Inc. @@ -24,8 +24,6 @@ ;;; Code: -(provide 'viper-ex) - ;; Compiler pacifier (defvar read-file-name-map) (defvar viper-use-register) @@ -190,7 +188,7 @@ ;; Executes the function associated with the command (defun ex-cmd-execute (cmd) - (eval (cadr cmd))) + (eval (cadr cmd) t)) ;; If this is a one-letter magic command, splice in args. (defun ex-splice-args-in-1-letr-cmd (key list) @@ -299,8 +297,7 @@ "\\)") shell-file-name))) "Is the user using a unix-type shell under a non-OS?" - :type 'boolean - :group 'viper-ex) + :type 'boolean) (defcustom ex-unix-type-shell-options (let ((case-fold-search t)) @@ -312,13 +309,11 @@ ))) "Options to pass to the Unix-style shell. Don't put `-c' here, as it is added automatically." - :type '(choice (const nil) string) - :group 'viper-ex) + :type '(choice (const nil) string)) (defcustom ex-compile-command "make" "The command to run when the user types :make." - :type 'string - :group 'viper-ex) + :type 'string) (defcustom viper-glob-function (cond (ex-unix-type-shell 'viper-glob-unix-files) @@ -331,8 +326,7 @@ The default tries to set this variable to work with Unix or MS Windows. However, if it doesn't work right for some types of Unix shells or some OS, the user should supply the appropriate function and set this variable to the corresponding function symbol." - :type 'symbol - :group 'viper-ex) + :type 'symbol) ;; Remembers the previous Ex tag. @@ -363,13 +357,11 @@ corresponding function symbol." "If t, :n and :b cycles through files and buffers in other window. Then :N and :B cycles in the current window. If nil, this behavior is reversed." - :type 'boolean - :group 'viper-ex) + :type 'boolean) (defcustom ex-cycle-through-non-files nil "Cycle through *scratch* and other buffers that don't visit any file." - :type 'boolean - :group 'viper-ex) + :type 'boolean) ;; Last shell command executed with :! command. (defvar viper-ex-last-shell-com nil) @@ -1314,7 +1306,7 @@ reversed." (let ((nonstandard-filename-chars "[^-a-zA-Z0-9_./,~$\\]")) (cond ((file-exists-p filespec) (find-file filespec)) ((string-match nonstandard-filename-chars filespec) - (mapcar 'find-file (funcall viper-glob-function filespec))) + (mapcar #'find-file (funcall viper-glob-function filespec))) (t (find-file filespec))) )) @@ -1639,7 +1631,7 @@ reversed." ;; this function fixes ex-history for some commands like ex-read, ex-edit (defun ex-fixup-history (&rest args) (setq viper-ex-history - (cons (mapconcat 'identity args " ") (cdr viper-ex-history)))) + (cons (mapconcat #'identity args " ") (cdr viper-ex-history)))) ;; Ex recover from emacs \#file\# @@ -1672,8 +1664,8 @@ reversed." (cursor-in-echo-area t) str batch) (define-key - minibuffer-local-completion-map " " 'minibuffer-complete-and-exit) - (define-key minibuffer-local-completion-map "=" 'exit-minibuffer) + minibuffer-local-completion-map " " #'minibuffer-complete-and-exit) + (define-key minibuffer-local-completion-map "=" #'exit-minibuffer) (if (viper-set-unread-command-events (ex-get-inline-cmd-args "[ \t]*[a-zA-Z]*[ \t]*" nil "\C-m")) (progn @@ -1837,7 +1829,7 @@ reversed." (format "%S" val) val))) (if actual-lisp-cmd - (eval (car (read-from-string actual-lisp-cmd)))) + (eval (car (read-from-string actual-lisp-cmd)) t)) (if (string= var "fill-column") (if (> val2 0) (auto-fill-mode 1) @@ -2319,4 +2311,5 @@ Type `mak ' (including the space) to run make with no args." (with-output-to-temp-buffer " *viper-info*" (princ lines)))))) +(provide 'viper-ex) ;;; viper-ex.el ends here diff --git a/lisp/emulation/viper-init.el b/lisp/emulation/viper-init.el index c05cf6a48b..8188971c0d 100644 --- a/lisp/emulation/viper-init.el +++ b/lisp/emulation/viper-init.el @@ -1,4 +1,4 @@ -;;; viper-init.el --- some common definitions for Viper +;;; viper-init.el --- some common definitions for Viper -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -46,7 +46,7 @@ ;; Tell whether we are running as a window application or on a TTY -(define-obsolete-function-alias 'viper-device-type 'window-system "27.1") +(define-obsolete-function-alias 'viper-device-type #'window-system "27.1") (defun viper-color-display-p () (condition-case nil @@ -141,7 +141,7 @@ docstring. The variable becomes buffer-local whenever set." (append (vconcat string) nil)) (defsubst viper-charlist-to-string (list) - (mapconcat 'char-to-string list "")) + (mapconcat #'char-to-string list "")) ;; like char-after/before, but saves typing (defun viper-char-at-pos (direction &optional offset) diff --git a/lisp/emulation/viper-keym.el b/lisp/emulation/viper-keym.el index 1d80c9cd02..4a9070e84b 100644 --- a/lisp/emulation/viper-keym.el +++ b/lisp/emulation/viper-keym.el @@ -155,29 +155,26 @@ In insert mode, this key also functions as Meta." (let ((old-value (if (boundp 'viper-toggle-key) viper-toggle-key [(control ?z)]))) - (mapc - (lambda (buf) - (with-current-buffer buf - (when (and (boundp 'viper-insert-basic-map) - (keymapp viper-insert-basic-map)) - (when old-value - (define-key viper-insert-basic-map old-value nil)) - (define-key viper-insert-basic-map value 'viper-escape-to-vi)) - (when (and (boundp 'viper-vi-intercept-map) - (keymapp viper-vi-intercept-map)) - (when old-value - (define-key viper-vi-intercept-map old-value nil)) - (define-key - viper-vi-intercept-map value 'viper-toggle-key-action)) - (when (and (boundp 'viper-emacs-intercept-map) - (keymapp viper-emacs-intercept-map)) - (define-key viper-emacs-intercept-map old-value nil) - (define-key - viper-emacs-intercept-map value 'viper-change-state-to-vi)) - )) - (buffer-list)) - (set-default symbol value) - ))) + (dolist (buf (buffer-list)) + (with-current-buffer buf + (when (and (boundp 'viper-insert-basic-map) + (keymapp viper-insert-basic-map)) + (when old-value + (define-key viper-insert-basic-map old-value nil)) + (define-key viper-insert-basic-map value 'viper-escape-to-vi)) + (when (and (boundp 'viper-vi-intercept-map) + (keymapp viper-vi-intercept-map)) + (when old-value + (define-key viper-vi-intercept-map old-value nil)) + (define-key + viper-vi-intercept-map value 'viper-toggle-key-action)) + (when (and (boundp 'viper-emacs-intercept-map) + (keymapp viper-emacs-intercept-map)) + (define-key viper-emacs-intercept-map old-value nil) + (define-key + viper-emacs-intercept-map value 'viper-change-state-to-vi)) + )) + (set-default symbol value)))) (defcustom viper-quoted-insert-key "\C-v" "The key used to quote special characters when inserting them in Insert state." @@ -257,7 +254,7 @@ In insert mode, this key also functions as Meta." (let ((i ?\ )) (while (<= i ?~) - (define-key viper-insert-diehard-map (make-string 1 i) 'self-insert-command) + (define-key viper-insert-diehard-map (string i) #'self-insert-command) (setq i (1+ i)))) ;; Insert mode map when user wants emacs style @@ -490,7 +487,7 @@ Useful in some modes, such as Gnus, MH, etc.") The effect is seen in the current buffer only. Useful for customizing mailer buffers, gnus, etc. STATE is `vi-state', `insert-state', or `emacs-state'. -ALIST is of the form ((key . func) (key . func) ...) +ALIST is of the form ((KEY . FUNC) (KEY . FUNC) ...) Normally, this would be called from a hook to a major mode or on a per buffer basis. Usage: @@ -548,14 +545,11 @@ The above needs not to be done for major modes that come up in Vi or Insert state by default. Arguments: (major-mode viper-state keymap)" - (let ((alist - (cond ((eq state 'vi-state) 'viper-vi-state-modifier-alist) - ((eq state 'insert-state) 'viper-insert-state-modifier-alist) - ((eq state 'emacs-state) 'viper-emacs-state-modifier-alist))) - elt) - (if (setq elt (assoc mode (eval alist))) - (set alist (delq elt (eval alist)))) - (set alist (cons (cons mode keymap) (eval alist))) + (let* ((alist + (cond ((eq state 'vi-state) 'viper-vi-state-modifier-alist) + ((eq state 'insert-state) 'viper-insert-state-modifier-alist) + ((eq state 'emacs-state) 'viper-emacs-state-modifier-alist)))) + (setf (alist-get mode (symbol-value alist)) keymap) ;; Normalization usually doesn't help here, since one needs to ;; normalize in the actual buffer where changes to the keymap are @@ -646,9 +640,9 @@ Arguments: (major-mode viper-state keymap)" (cdr mapsrc))) (defun viper-modify-keymap (map alist) - "Modifies MAP with bindings specified in the ALIST. The alist has the -form ((key . function) (key . function) ... )." - (mapcar (lambda (p) (define-key map (eval (car p)) (cdr p))) + "Modifies MAP with bindings specified in the ALIST. +The ALIST has the form ((KEY . FUNCTION) (KEY . FUNCTION) ... )." + (mapcar (lambda (p) (define-key map (eval (car p) t) (cdr p))) alist)) diff --git a/lisp/emulation/viper-macs.el b/lisp/emulation/viper-macs.el index 039ddabcdc..94ab817892 100644 --- a/lisp/emulation/viper-macs.el +++ b/lisp/emulation/viper-macs.el @@ -24,8 +24,6 @@ ;;; Code: -(provide 'viper-macs) - ;; compiler pacifier (defvar viper-ex-work-buf) (defvar viper-custom-file-name) @@ -37,7 +35,7 @@ (require 'viper-util) (require 'viper-keym) - +(require 'seq) ;;; Variables @@ -102,9 +100,11 @@ a key is a symbol, e.g., `a', `\\1', `f2', etc., or a list, e.g., ;; if defining macro for insert, switch there for authentic WYSIWYG (if ins (viper-change-state-to-insert)) (start-kbd-macro nil) - (define-key viper-vi-intercept-map "\C-x)" 'viper-end-mapping-kbd-macro) - (define-key viper-insert-intercept-map "\C-x)" 'viper-end-mapping-kbd-macro) - (define-key viper-emacs-intercept-map "\C-x)" 'viper-end-mapping-kbd-macro) + (define-key viper-vi-intercept-map "\C-x)" #'viper-end-mapping-kbd-macro) + (define-key viper-insert-intercept-map "\C-x)" + #'viper-end-mapping-kbd-macro) + (define-key viper-emacs-intercept-map "\C-x)" + #'viper-end-mapping-kbd-macro) (message "Mapping %S in %s state. Type macro definition followed by `C-x )'" (viper-display-macro macro-name) (if ins "Insert" "Vi"))) @@ -442,7 +442,7 @@ If SCOPE is nil, the user is asked to specify the scope." (list nil (list (cons scope nil)) (cons t nil))) ((stringp scope) (list (list (cons scope nil)) nil (cons t nil)))))) - (setq old-elt (assoc macro-name (eval macro-alist-var))) + (setq old-elt (assoc macro-name (symbol-value macro-alist-var))) (if (null old-elt) (progn @@ -450,8 +450,8 @@ If SCOPE is nil, the user is asked to specify the scope." (define-key keymap (vector (viper-key-to-emacs-key (aref macro-name 0))) - 'viper-exec-mapped-kbd-macro) - (setq lis (eval macro-alist-var)) + #'viper-exec-mapped-kbd-macro) + (setq lis (symbol-value macro-alist-var)) (while (and lis (string< (viper-array-to-string (car (car lis))) (viper-array-to-string macro-name))) (setq lis2 (cons (car lis) lis2)) @@ -514,7 +514,7 @@ mistakes in macro names to be passed to this function is to use (if (viper-char-array-p macro-name) (setq macro-name (viper-char-array-to-macro macro-name))) - (setq macro-entry (assoc macro-name (eval macro-alist-var))) + (setq macro-entry (assoc macro-name (symbol-value macro-alist-var))) (if (= (length macro-name) 0) (error "Can't unmap an empty macro name")) (if (null macro-entry) @@ -557,9 +557,10 @@ mistakes in macro names to be passed to this function is to use (cdr mode-mapping) (cdr global-mapping) (progn - (set macro-alist-var (delq macro-entry (eval macro-alist-var))) + (set macro-alist-var (delq macro-entry + (symbol-value macro-alist-var))) (if (viper-can-release-key (aref macro-name 0) - (eval macro-alist-var)) + (symbol-value macro-alist-var)) (define-key keymap (vector (viper-key-to-emacs-key (aref macro-name 0))) @@ -649,11 +650,11 @@ mistakes in macro names to be passed to this function is to use (interactive) (with-output-to-temp-buffer " *viper-info*" (princ "Macros in Vi state:\n===================\n") - (mapc 'viper-describe-one-macro viper-vi-kbd-macro-alist) + (mapc #'viper-describe-one-macro viper-vi-kbd-macro-alist) (princ "\n\nMacros in Insert and Replace states:\n====================================\n") - (mapc 'viper-describe-one-macro viper-insert-kbd-macro-alist) + (mapc #'viper-describe-one-macro viper-insert-kbd-macro-alist) (princ "\n\nMacros in Emacs state:\n======================\n") - (mapcar 'viper-describe-one-macro viper-emacs-kbd-macro-alist) + (mapc #'viper-describe-one-macro viper-emacs-kbd-macro-alist) )) (defun viper-describe-one-macro (macro) @@ -661,11 +662,11 @@ mistakes in macro names to be passed to this function is to use (viper-display-macro (car macro)))) (princ " ** Buffer-specific:") (if (viper-kbd-buf-alist macro) - (mapc 'viper-describe-one-macro-elt (viper-kbd-buf-alist macro)) + (mapc #'viper-describe-one-macro-elt (viper-kbd-buf-alist macro)) (princ " none\n")) (princ "\n ** Mode-specific:") (if (viper-kbd-mode-alist macro) - (mapc 'viper-describe-one-macro-elt (viper-kbd-mode-alist macro)) + (mapc #'viper-describe-one-macro-elt (viper-kbd-mode-alist macro)) (princ " none\n")) (princ "\n ** Global:") (if (viper-kbd-global-definition macro) @@ -683,10 +684,9 @@ mistakes in macro names to be passed to this function is to use ;; check if SEQ is a prefix of some car of an element in ALIST (defun viper-keyseq-is-a-possible-macro (seq alist) (let ((converted-seq (viper-events-to-macro seq))) - (eval (cons 'or - (mapcar - (lambda (elt) (viper-prefix-subseq-p converted-seq elt)) - (viper-this-buffer-macros alist)))))) + (seq-some + (lambda (elt) (viper-prefix-subseq-p converted-seq elt)) + (viper-this-buffer-macros alist)))) ;; whether SEQ1 is a prefix of SEQ2 (defun viper-prefix-subseq-p (seq1 seq2) @@ -704,11 +704,10 @@ mistakes in macro names to be passed to this function is to use len) (if (= (length seqs) 0) (setq len 0) - (setq len (apply 'min (mapcar 'length seqs)))) + (setq len (apply #'min (mapcar #'length seqs)))) (while (< idx len) - (if (eval (cons 'and - (mapcar (lambda (s) (equal (elt first idx) (elt s idx))) - rest))) + (if (seq-every-p (lambda (s) (equal (elt first idx) (elt s idx))) + rest) (setq pref (vconcat pref (vector (elt first idx))))) (setq idx (1+ idx))) pref)) @@ -720,7 +719,7 @@ mistakes in macro names to be passed to this function is to use (defun viper-do-sequence-completion (seq alist compl-message) (let* ((matches (viper-extract-matching-alist-members seq alist)) - (new-seq (apply 'viper-common-seq-prefix matches)) + (new-seq (apply #'viper-common-seq-prefix matches)) ) (cond ((and (equal seq new-seq) (= (length matches) 1)) (message "%s (Sole completion)" compl-message) @@ -741,8 +740,8 @@ mistakes in macro names to be passed to this function is to use (defun viper-display-vector-completions (list) (with-output-to-temp-buffer "*Completions*" (display-completion-list - (mapcar 'prin1-to-string - (mapcar 'viper-display-macro list))))) + (mapcar #'prin1-to-string + (mapcar #'viper-display-macro list))))) @@ -793,9 +792,9 @@ mistakes in macro names to be passed to this function is to use ;; string--do so. Otherwise, do nothing. (defun viper-display-macro (macro-name-or-body) (cond ((viper-char-symbol-sequence-p macro-name-or-body) - (mapconcat 'symbol-name macro-name-or-body "")) + (mapconcat #'symbol-name macro-name-or-body "")) ((viper-char-array-p macro-name-or-body) - (mapconcat 'char-to-string macro-name-or-body "")) + (mapconcat #'char-to-string macro-name-or-body "")) (t macro-name-or-body))) ;; convert sequence of events (that came presumably from emacs kbd macro) into @@ -815,7 +814,7 @@ mistakes in macro names to be passed to this function is to use ;; convert strings or arrays of characters to Viper macro form (defun viper-char-array-to-macro (array) - (vconcat (mapcar 'viper-event-key (vconcat array)))) + (vconcat (mapcar #'viper-event-key (vconcat array)))) ;; For macros bodies and names, goes over MACRO and checks if all members are ;; names of keys (actually, it only checks if they are symbols or lists @@ -850,7 +849,7 @@ mistakes in macro names to be passed to this function is to use macro))) (defun viper-macro-to-events (macro-body) - (vconcat (mapcar 'viper-key-to-emacs-key macro-body))) + (vconcat (mapcar #'viper-key-to-emacs-key macro-body))) @@ -929,5 +928,5 @@ mistakes in macro names to be passed to this function is to use (beginning-of-line) (call-last-kbd-macro))) - +(provide 'viper-macs) ;;; viper-macs.el ends here diff --git a/lisp/emulation/viper-mous.el b/lisp/emulation/viper-mous.el index 71e40ee023..83fc5afafa 100644 --- a/lisp/emulation/viper-mous.el +++ b/lisp/emulation/viper-mous.el @@ -1,4 +1,4 @@ -;;; viper-mous.el --- mouse support for Viper +;;; viper-mous.el --- mouse support for Viper -*- lexical-binding: t; -*- ;; Copyright (C) 1994-1997, 2001-2021 Free Software Foundation, Inc. @@ -24,8 +24,6 @@ ;;; Code: -(provide 'viper-mous) - ;; compiler pacifier (defvar double-click-time) (defvar mouse-track-multi-click-time) @@ -60,8 +58,7 @@ Takes two parameters: a COUNT, indicating how many words to return, and CLICK-COUNT, telling whether this is the first click, a double-click, or a triple-click." - :type 'symbol - :group 'viper-mouse) + :type 'symbol) ;; time interval in millisecond within which successive clicks are ;; considered related @@ -70,8 +67,7 @@ or a triple-click." 500) "Time interval in millisecond within which successive mouse clicks are considered related." - :type 'integer - :group 'viper-mouse) + :type 'integer) ;; Local variable used to toggle wraparound search on click. (defvar-local viper-mouse-click-search-noerror t) @@ -292,7 +288,7 @@ See `viper-surrounding-word' for the definition of a word in this case." (prin1-to-string (viper-event-key event))))) (define-obsolete-function-alias 'viper-event-click-count - 'event-click-count "28.1") + #'event-click-count "28.1") (declare-function viper-forward-word "viper-cmd" (arg)) (declare-function viper-adjust-window "viper-cmd" ()) @@ -407,7 +403,7 @@ this command. (setq arg (1- arg))) )))) -(defun viper-mouse-catch-frame-switch (event arg) +(defun viper-mouse-catch-frame-switch (_event arg) "Catch the event of switching frame. Usually is bound to a `down-mouse' event to work properly. See sample bindings in the Viper manual." @@ -436,8 +432,9 @@ bindings in the Viper manual." ;; until you do something other than viper-mouse-click-* command. ;; In XEmacs, you have to manually select frame B (with the mouse click) in ;; order to shift focus to frame B. -(defsubst viper-remember-current-frame (frame) - (setq last-command 'handle-switch-frame +(defun viper-remember-current-frame (&rest _) + "Remember the selected frame before the switch-frame event." + (setq last-command #'handle-switch-frame viper-current-frame-saved (selected-frame))) @@ -446,8 +443,8 @@ bindings in the Viper manual." ;; Emacs. EVENT-TYPE is either `up' or `down'. Up returns button-up key; down ;; returns button-down key. (defun viper-parse-mouse-key (key-var event-type) - (let ((key (eval key-var)) - button-spec meta-spec shift-spec control-spec key-spec) + (let ((key (symbol-value key-var)) + button-spec meta-spec shift-spec control-spec) (if (null key) ;; just return nil () @@ -470,10 +467,9 @@ bindings in the Viper manual." control-spec (if (memq 'control key) "C-" "")) - (setq key-spec - (vector - (intern (concat control-spec meta-spec - shift-spec button-spec))))))) + (vector + (intern (concat control-spec meta-spec + shift-spec button-spec)))))) (defun viper-unbind-mouse-search-key () (if viper-mouse-up-search-key-parsed @@ -497,8 +493,8 @@ bindings in the Viper manual." (viper-parse-mouse-key 'viper-mouse-search-key 'up) viper-mouse-down-search-key-parsed (viper-parse-mouse-key 'viper-mouse-search-key 'down)) - (cond ((or (null viper-mouse-up-search-key-parsed) - (null viper-mouse-down-search-key-parsed)) + (cond ((not (and viper-mouse-up-search-key-parsed + viper-mouse-down-search-key-parsed)) nil) ; just quit ((and (null force) (key-binding viper-mouse-up-search-key-parsed) @@ -516,9 +512,9 @@ bindings in the Viper manual." viper-mouse-down-search-key-parsed)) (t (global-set-key viper-mouse-up-search-key-parsed - 'viper-mouse-click-search-word) + #'viper-mouse-click-search-word) (global-set-key viper-mouse-down-search-key-parsed - 'viper-mouse-catch-frame-switch)))) + #'viper-mouse-catch-frame-switch)))) ;; If FORCE, bind even if this mouse action is already bound to something else (defun viper-bind-mouse-insert-key (&optional force) @@ -526,8 +522,8 @@ bindings in the Viper manual." (viper-parse-mouse-key 'viper-mouse-insert-key 'up) viper-mouse-down-insert-key-parsed (viper-parse-mouse-key 'viper-mouse-insert-key 'down)) - (cond ((or (null viper-mouse-up-insert-key-parsed) - (null viper-mouse-down-insert-key-parsed)) + (cond ((not (and viper-mouse-up-insert-key-parsed + viper-mouse-down-insert-key-parsed)) nil) ; just quit ((and (null force) (key-binding viper-mouse-up-insert-key-parsed) @@ -545,9 +541,9 @@ bindings in the Viper manual." viper-mouse-down-insert-key-parsed)) (t (global-set-key viper-mouse-up-insert-key-parsed - 'viper-mouse-click-insert-word) + #'viper-mouse-click-insert-word) (global-set-key viper-mouse-down-insert-key-parsed - 'viper-mouse-catch-frame-switch)))) + #'viper-mouse-catch-frame-switch)))) (defun viper-reset-mouse-search-key (symb val) (viper-unbind-mouse-search-key) @@ -573,8 +569,7 @@ This buffer may be different from the one where the click occurred." (const :format "%v " shift) (const control)) (integer :tag "Button")) - :set 'viper-reset-mouse-search-key - :group 'viper-mouse) + :set #'viper-reset-mouse-search-key) (defcustom viper-mouse-insert-key '(meta shift 2) "Key used to click-insert in Viper. @@ -589,7 +584,7 @@ This buffer may be different from the one where the click occurred." (const :format "%v " shift) (const control)) (integer :tag "Button")) - :set 'viper-reset-mouse-insert-key - :group 'viper-mouse) + :set #'viper-reset-mouse-insert-key) +(provide 'viper-mous) ;;; viper-mous.el ends here diff --git a/lisp/emulation/viper-util.el b/lisp/emulation/viper-util.el index 1bdb155538..51f7406ad2 100644 --- a/lisp/emulation/viper-util.el +++ b/lisp/emulation/viper-util.el @@ -24,8 +24,7 @@ ;;; Code: -(provide 'viper-util) - +(require 'seq) ;; Compiler pacifier (defvar viper-minibuffer-current-face) @@ -47,22 +46,22 @@ -(define-obsolete-function-alias 'viper-overlay-p 'overlayp "27.1") -(define-obsolete-function-alias 'viper-make-overlay 'make-overlay "27.1") -(define-obsolete-function-alias 'viper-overlay-live-p 'overlayp "27.1") -(define-obsolete-function-alias 'viper-move-overlay 'move-overlay "27.1") -(define-obsolete-function-alias 'viper-overlay-start 'overlay-start "27.1") -(define-obsolete-function-alias 'viper-overlay-end 'overlay-end "27.1") -(define-obsolete-function-alias 'viper-overlay-get 'overlay-get "27.1") -(define-obsolete-function-alias 'viper-overlay-put 'overlay-put "27.1") -(define-obsolete-function-alias 'viper-read-event 'read-event "27.1") -(define-obsolete-function-alias 'viper-characterp 'integerp "27.1") -(define-obsolete-function-alias 'viper-int-to-char 'identity "27.1") -(define-obsolete-function-alias 'viper-get-face 'facep "27.1") +(define-obsolete-function-alias 'viper-overlay-p #'overlayp "27.1") +(define-obsolete-function-alias 'viper-make-overlay #'make-overlay "27.1") +(define-obsolete-function-alias 'viper-overlay-live-p #'overlayp "27.1") +(define-obsolete-function-alias 'viper-move-overlay #'move-overlay "27.1") +(define-obsolete-function-alias 'viper-overlay-start #'overlay-start "27.1") +(define-obsolete-function-alias 'viper-overlay-end #'overlay-end "27.1") +(define-obsolete-function-alias 'viper-overlay-get #'overlay-get "27.1") +(define-obsolete-function-alias 'viper-overlay-put #'overlay-put "27.1") +(define-obsolete-function-alias 'viper-read-event #'read-event "27.1") +(define-obsolete-function-alias 'viper-characterp #'integerp "27.1") +(define-obsolete-function-alias 'viper-int-to-char #'identity "27.1") +(define-obsolete-function-alias 'viper-get-face #'facep "27.1") (define-obsolete-function-alias 'viper-color-defined-p - 'x-color-defined-p "27.1") + #'x-color-defined-p "27.1") (define-obsolete-function-alias 'viper-iconify - 'iconify-or-deiconify-frame "27.1") + #'iconify-or-deiconify-frame "27.1") ;; CHAR is supposed to be a char or an integer (positive or negative) @@ -269,10 +268,10 @@ Otherwise return the normal value." ;; Then, each time this var is used in `viper-move-marker-locally' in a new ;; buffer, a new marker will be created. (defun viper-move-marker-locally (var pos &optional buffer) - (if (markerp (eval var)) + (if (markerp (symbol-value var)) () (set var (make-marker))) - (move-marker (eval var) pos buffer)) + (move-marker (symbol-value var) pos buffer)) ;; Print CONDITIONS as a message. @@ -280,7 +279,7 @@ Otherwise return the normal value." (let ((case (car conditions)) (msg (cdr conditions))) (if (null msg) (message "%s" case) - (message "%s: %s" case (mapconcat 'prin1-to-string msg " "))) + (message "%s: %s" case (mapconcat #'prin1-to-string msg " "))) (beep 1))) @@ -453,7 +452,7 @@ Otherwise return the normal value." "$")) tmp2)) (setq tmp (cdr tmp))) - (reverse (apply 'append tmp2))))) + (reverse (apply #'append tmp2))))) ;;; Insertion ring @@ -488,11 +487,11 @@ Otherwise return the normal value." ;; Push item onto ring. The second argument is a ring-variable, not value. (defun viper-push-onto-ring (item ring-var) - (or (ring-p (eval ring-var)) - (set ring-var (make-ring (eval (intern (format "%S-size" ring-var)))))) + (or (ring-p (symbol-value ring-var)) + (set ring-var (make-ring (symbol-value (intern (format "%S-size" ring-var)))))) (or (null item) ; don't push nil (and (stringp item) (string= item "")) ; or empty strings - (equal item (viper-current-ring-item (eval ring-var))) ; or old stuff + (equal item (viper-current-ring-item (symbol-value ring-var))) ; or old stuff ;; Since viper-set-destructive-command checks if we are inside ;; viper-repeat, we don't check whether this-command-keys is a `.'. The ;; cmd viper-repeat makes a call to the current function only if `.' is @@ -505,7 +504,7 @@ Otherwise return the normal value." (and (eq ring-var 'viper-command-ring) (string-match "\\([0-9]*\e\\|^[ \t]*$\\|escape\\)" (viper-array-to-string (this-command-keys)))) - (viper-ring-insert (eval ring-var) item)) + (viper-ring-insert (symbol-value ring-var) item)) ) @@ -595,7 +594,7 @@ Otherwise return the normal value." ;; Arguments: var message file &optional erase-message (defun viper-save-setting (var message file &optional erase-msg) (let* ((var-name (symbol-name var)) - (var-val (if (boundp var) (eval var))) + (var-val (if (boundp var) (symbol-value var))) (regexp (format "^[^;]*%s[ \t\n]*[a-zA-Z0-9---_']*[ \t\n)]" var-name)) (buf (find-file-noselect (substitute-in-file-name file))) ) @@ -795,7 +794,7 @@ Otherwise return the normal value." ;;; XEmacs compatibility (define-obsolete-function-alias 'viper-abbreviate-file-name - 'abbreviate-file-name "27.1") + #'abbreviate-file-name "27.1") (defsubst viper-sit-for-short (val &optional nodisp) (declare (obsolete nil "28.1")) @@ -815,7 +814,7 @@ Otherwise return the normal value." (with-current-buffer buf (and (<= pos (point-max)) (<= (point-min) pos)))))) -(define-obsolete-function-alias 'viper-mark-marker 'mark-marker "27.1") +(define-obsolete-function-alias 'viper-mark-marker #'mark-marker "27.1") (defvar viper-saved-mark nil "Where viper saves mark. This mark is resurrected by m^.") @@ -831,9 +830,9 @@ Otherwise return the normal value." ;; highlighted due to Viper's pushing marks. So, we deactivate marks, ;; unless the user explicitly wants highlighting, e.g., by hitting '' ;; or `` -(define-obsolete-function-alias 'viper-deactivate-mark 'deactivate-mark "27.1") +(define-obsolete-function-alias 'viper-deactivate-mark #'deactivate-mark "27.1") -(define-obsolete-function-alias 'viper-leave-region-active 'ignore "27.1") +(define-obsolete-function-alias 'viper-leave-region-active #'ignore "27.1") ;; Check if arg is a valid character for register ;; TYPE is a list that can contain `letter', `Letter', and `digit'. @@ -852,7 +851,7 @@ Otherwise return the normal value." -(define-obsolete-function-alias 'viper-copy-event 'identity "27.1") +(define-obsolete-function-alias 'viper-copy-event #'identity "27.1") ;; Uses different timeouts for ESC-sequences and others (defun viper-fast-keysequence-p () @@ -862,7 +861,7 @@ Otherwise return the normal value." t))) (define-obsolete-function-alias 'viper-read-event-convert-to-char - 'read-event "27.1") + #'read-event "27.1") ;; Emacs has a bug in eventp, which causes (eventp nil) to return (nil) @@ -941,20 +940,20 @@ Otherwise return the normal value." (car (read-from-string (concat "?\\" - (mapconcat 'identity mod-char-list "-\\") + (mapconcat #'identity mod-char-list "-\\") "-" base-key-name)))) (setq key-name (intern (concat - (mapconcat 'identity mod-char-list "-") + (mapconcat #'identity mod-char-list "-") "-" base-key-name)))))) )) ;; LIS is assumed to be a list of events of characters -(define-obsolete-function-alias 'viper-eventify-list-xemacs 'ignore "27.1") +(define-obsolete-function-alias 'viper-eventify-list-xemacs #'ignore "27.1") ;; Arg is a character, an event, a list of events or a sequence of @@ -985,22 +984,20 @@ Otherwise return the normal value." ;; XEmacs only (defun viper-event-vector-p (vec) (and (vectorp vec) - (eval (cons 'and (mapcar (lambda (elt) (if (eventp elt) t)) vec))))) + (seq-every-p (lambda (elt) (if (eventp elt) t)) vec))) ;; check if vec is a vector of character symbols (defun viper-char-symbol-sequence-p (vec) (and (sequencep vec) - (eval - (cons 'and - (mapcar (lambda (elt) - (and (symbolp elt) (= (length (symbol-name elt)) 1))) - vec))))) + (seq-every-p (lambda (elt) + (and (symbolp elt) (= (length (symbol-name elt)) 1))) + vec))) (defun viper-char-array-p (array) - (eval (cons 'and (mapcar 'characterp array)))) + (seq-every-p #'characterp array)) ;; Args can be a sequence of events, a string, or a Viper macro. Will try to @@ -1012,19 +1009,19 @@ Otherwise return the normal value." (let (temp temp2) (cond ((stringp event-seq) event-seq) ((viper-event-vector-p event-seq) - (setq temp (mapcar 'viper-event-key event-seq)) + (setq temp (mapcar #'viper-event-key event-seq)) (cond ((viper-char-symbol-sequence-p temp) - (mapconcat 'symbol-name temp "")) + (mapconcat #'symbol-name temp "")) ((and (viper-char-array-p - (setq temp2 (mapcar 'viper-key-to-character temp)))) - (mapconcat 'char-to-string temp2 "")) + (setq temp2 (mapcar #'viper-key-to-character temp)))) + (mapconcat #'char-to-string temp2 "")) (t (prin1-to-string (vconcat temp))))) ((viper-char-symbol-sequence-p event-seq) - (mapconcat 'symbol-name event-seq "")) + (mapconcat #'symbol-name event-seq "")) ((and (vectorp event-seq) (viper-char-array-p - (setq temp (mapcar 'viper-key-to-character event-seq)))) - (mapconcat 'char-to-string temp "")) + (setq temp (mapcar #'viper-key-to-character event-seq)))) + (mapconcat #'char-to-string temp "")) (t (prin1-to-string event-seq))))) (defun viper-key-press-events-to-chars (events) @@ -1172,7 +1169,7 @@ syntax tables. This option is appropriate if you like Emacs-style words." :type '(radio (const strict-vi) (const reformed-vi) (const extended) (const emacs)) - :set 'viper-set-syntax-preference + :set #'viper-set-syntax-preference :group 'viper) (make-variable-buffer-local 'viper-syntax-preference) @@ -1375,4 +1372,5 @@ This option is appropriate if you like Emacs-style words." (setq i (1+ i) start (1+ start))) res)))))) +(provide 'viper-util) ;;; viper-util.el ends here diff --git a/lisp/emulation/viper.el b/lisp/emulation/viper.el index df5a083a08..cce5117433 100644 --- a/lisp/emulation/viper.el +++ b/lisp/emulation/viper.el @@ -1061,9 +1061,7 @@ This may be needed if the previous `:map' command terminated abnormally." (if (viper-window-display-p) (viper--advice-add 'handle-switch-frame :before - (lambda (&rest _) - "Remember the selected frame before the switch-frame event." - (viper-remember-current-frame (selected-frame))))) + #'viper-remember-current-frame)) ) ; end viper-non-hook-settings @@ -1191,7 +1189,7 @@ These two lines must come in the order given.")) ;; The default viper-toggle-key is \C-z; for the novice, it suspends or ;; iconifies Emacs -(define-key viper-vi-intercept-map viper-toggle-key 'viper-toggle-key-action) +(define-key viper-vi-intercept-map viper-toggle-key #'viper-toggle-key-action) (define-key viper-emacs-intercept-map viper-toggle-key #'viper-change-state-to-vi) commit d925121b1e1cdf953705a5da43f8092f2a6e1d8c Author: Basil L. Contovounesios Date: Wed Feb 24 00:53:05 2021 +0000 Various map.el improvements * lisp/emacs-lisp/seq.el (seq-do-indexed): Return nil as per doc. * lisp/emacs-lisp/map.el: Require Emacs >= 26 due to dependence on 5-arg alist-get. Bump package to version 3.0. Fix other headers. (Bug#46754) (map--plist-p): Detect list starting with nil as plist, not alist. (map-elt, map-filter, map-apply, map--make-pcase-bindings) (map--make-pcase-patterns): Simplify. (map-let, map-put, map-nested-elt, mapp): Update docstring for plist support. (map-delete): Fix OBOE on arrays. Split into cl-defmethods. (map-values, map-values-apply): Specialize for arrays. (map-pairs, map-keys-apply, map-put!): Improve docstring. (map-length): Clarify docstring w.r.t. duplicate keys. Split into cl-defmethods. Optimize default implementation. (map-copy): Use copy-alist on alists. Split into cl-defmethods. (map-contains-key): Add plist support. Clarify docstring w.r.t. optional argument. Simplify default implementation. (map-some, map-every-p, map-merge, map-merge-with, map--into-hash): Don't use map-apply for side effects. (map-into): Preserve plist ordering. Improve docstrings. (map-insert): Add hash-table and array support. (map-inplace): Remove unused error symbol. (map-do): Return nil as per doc. * etc/NEWS: Announce new user-visible behavior. * test/lisp/emacs-lisp/map-tests.el: Prefer should-not over (should (not ...)) in general. (with-maps-do): Fix docstring. (with-empty-maps-do): New macro. (test-map-elt-default, test-mapp, test-map-keys, test-map-values) (test-map-pairs, test-map-length, test-map-copy, test-map-apply) (test-map-do, test-map-keys-apply, test-map-values-apply) (test-map-filter, test-map-remove, test-map-empty-p) (test-map-contains-key, test-map-some, test-map-every-p): Use it. (test-map-plist-p, test-map-put!-new-keys, test-map-insert-empty) (test-map-insert, test-map-delete-empty, test-map-copy-alist) (test-map-contains-key-testfn, test-map-into-hash-test) (test-map-into-empty, test-map-merge, test-map-merge-empty): New tests. (test-map-elt): Test array key that is within bounds but not fixnum. (test-map-put!): Use map--plist-p. Remove redundant tests. (test-map-put-alist-new-key): Don't modify list literal. (test-map-put-testfn-alist, test-map-put-return-value): Silence obsoletion warnings. (test-map-delete): Check for OBOE on arrays. (test-map-delete-return-value): Remove test made redundant by test-map-delete. (test-map-nested-elt, test-map-into): Test plists too. diff --git a/etc/NEWS b/etc/NEWS index 6b4456e3de..5487448eae 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1160,6 +1160,13 @@ effect. A pattern like '(map :sym)' binds the map's value for ':sym' to 'sym', equivalent to '(map (:sym sym))'. +--- +*** The function 'map-copy' now uses 'copy-alist' on alists. +This is a slightly deeper copy than the previous 'copy-sequence'. + +--- +*** The function 'map-contains-key' now supports plists. + ** Package +++ diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el index 46a1bd21a3..c0cbc7b5a1 100644 --- a/lisp/emacs-lisp/map.el +++ b/lisp/emacs-lisp/map.el @@ -3,12 +3,10 @@ ;; Copyright (C) 2015-2021 Free Software Foundation, Inc. ;; Author: Nicolas Petton -;; Keywords: convenience, map, hash-table, alist, array -;; Version: 2.1 -;; Package-Requires: ((emacs "25")) -;; Package: map - ;; Maintainer: emacs-devel@gnu.org +;; Keywords: extensions, lisp +;; Version: 3.0 +;; Package-Requires: ((emacs "26")) ;; This file is part of GNU Emacs. @@ -27,8 +25,9 @@ ;;; Commentary: -;; map.el provides map-manipulation functions that work on alists, -;; hash-table and arrays. All functions are prefixed with "map-". +;; map.el provides generic map-manipulation functions that work on +;; alists, plists, hash-tables, and arrays. All functions are +;; prefixed with "map-". ;; ;; Functions taking a predicate or iterating over a map using a ;; function take the function as their first argument. All other @@ -54,7 +53,7 @@ ARGS is a list of elements to be matched in the map. Each element of ARGS can be of the form (KEY PAT), in which case KEY is evaluated and searched for in the map. The match fails if for any KEY found in the map, the corresponding PAT doesn't match the value -associated to the KEY. +associated with the KEY. Each element can also be a SYMBOL, which is an abbreviation of a (KEY PAT) tuple of the form (\\='SYMBOL SYMBOL). When SYMBOL @@ -75,7 +74,7 @@ bound to the looked up value in MAP. KEYS can also be a list of (KEY VARNAME) pairs, in which case KEY is an unquoted form. -MAP can be a list, hash-table or array." +MAP can be an alist, plist, hash-table, or array." (declare (indent 2) (debug ((&rest &or symbolp ([form symbolp])) form body))) `(pcase-let ((,(map--make-pcase-patterns keys) ,map)) @@ -101,7 +100,7 @@ Returns the result of evaluating the form associated with MAP-VAR's type." (define-error 'map-not-inplace "Cannot modify map in-place") (defsubst map--plist-p (list) - (and (consp list) (not (listp (car list))))) + (and (consp list) (atom (car list)))) (cl-defgeneric map-elt (map key &optional default testfn) "Lookup KEY in MAP and return its associated value. @@ -109,7 +108,8 @@ If KEY is not found, return DEFAULT which defaults to nil. TESTFN is deprecated. Its default depends on the MAP argument. -In the base definition, MAP can be an alist, hash-table, or array." +In the base definition, MAP can be an alist, plist, hash-table, +or array." (declare (gv-expander (lambda (do) @@ -127,26 +127,25 @@ In the base definition, MAP can be an alist, hash-table, or array." `(map-insert ,mgetter ,key ,v)))))))))) ;; `testfn' is deprecated. (advertised-calling-convention (map key &optional default) "27.1")) + ;; Can't use `cl-defmethod' with `advertised-calling-convention'. (map--dispatch map :list (if (map--plist-p map) - (let ((res (plist-get map key))) - (if (and default (null res) (not (plist-member map key))) - default - res)) + (let ((res (plist-member map key))) + (if res (cadr res) default)) (alist-get key map default nil testfn)) :hash-table (gethash key map default) - :array (if (and (>= key 0) (< key (seq-length map))) - (seq-elt map key) + :array (if (map-contains-key map key) + (aref map key) default))) (defmacro map-put (map key value &optional testfn) "Associate KEY with VALUE in MAP and return VALUE. If KEY is already present in MAP, replace the associated value with VALUE. -When MAP is a list, test equality with TESTFN if non-nil, +When MAP is an alist, test equality with TESTFN if non-nil, otherwise use `eql'. -MAP can be a list, hash-table or array." +MAP can be an alist, plist, hash-table, or array." (declare (obsolete "use map-put! or (setf (map-elt ...) ...) instead" "27.1")) `(setf (map-elt ,map ,key nil ,testfn) ,value)) @@ -168,23 +167,30 @@ MAP can be a list, hash-table or array." (cl-defgeneric map-delete (map key) "Delete KEY in-place from MAP and return MAP. -No error is signaled if KEY is not a key of MAP. -If MAP is an array, store nil at the index KEY." - (map--dispatch map - ;; FIXME: Signal map-not-inplace i.s.o returning a different list? - :list (if (map--plist-p map) - (setq map (map--plist-delete map key)) - (setf (alist-get key map nil t) nil)) - :hash-table (remhash key map) - :array (and (>= key 0) - (<= key (seq-length map)) - (aset map key nil))) +Keys not present in MAP are ignored.") + +(cl-defmethod map-delete ((map list) key) + ;; FIXME: Signal map-not-inplace i.s.o returning a different list? + (if (map--plist-p map) + (map--plist-delete map key) + (setf (alist-get key map nil t) nil) + map)) + +(cl-defmethod map-delete ((map hash-table) key) + (remhash key map) + map) + +(cl-defmethod map-delete ((map array) key) + "Store nil at index KEY." + (when (map-contains-key map key) + (aset map key nil)) map) (defun map-nested-elt (map keys &optional default) "Traverse MAP using KEYS and return the looked up value or DEFAULT if nil. -Map can be a nested map composed of alists, hash-tables and arrays." +MAP can be a nested map composed of alists, plists, hash-tables, +and arrays." (or (seq-reduce (lambda (acc key) (when (mapp acc) (map-elt acc key))) @@ -202,30 +208,49 @@ The default implementation delegates to `map-apply'." The default implementation delegates to `map-apply'." (map-apply (lambda (_ value) value) map)) +(cl-defmethod map-values ((map array)) + "Convert MAP into a list." + (append map ())) + (cl-defgeneric map-pairs (map) - "Return the elements of MAP as key/value association lists. + "Return the key/value pairs in MAP as an alist. The default implementation delegates to `map-apply'." (map-apply #'cons map)) (cl-defgeneric map-length (map) ;; FIXME: Should we rename this to `map-size'? - "Return the number of elements in the map. -The default implementation counts `map-keys'." - (cond - ((hash-table-p map) (hash-table-count map)) - ((listp map) - ;; FIXME: What about repeated/shadowed keys? - (if (map--plist-p map) (/ (length map) 2) (length map))) - ((arrayp map) (length map)) - (t (length (map-keys map))))) + "Return the number of key/value pairs in MAP. +Note that this does not always reflect the number of unique keys. +The default implementation delegates to `map-do'." + (let ((size 0)) + (map-do (lambda (_k _v) (setq size (1+ size))) map) + size)) + +(cl-defmethod map-length ((map hash-table)) + (hash-table-count map)) + +(cl-defmethod map-length ((map list)) + (if (map--plist-p map) + (/ (length map) 2) + (length map))) + +(cl-defmethod map-length ((map array)) + (length map)) (cl-defgeneric map-copy (map) - "Return a copy of MAP." - ;; FIXME: Clarify how deep is the copy! - (map--dispatch map - :list (seq-copy map) ;FIXME: Probably not deep enough for alists! - :hash-table (copy-hash-table map) - :array (seq-copy map))) + "Return a copy of MAP.") + +(cl-defmethod map-copy ((map list)) + "Use `copy-alist' on alists and `copy-sequence' on plists." + (if (map--plist-p map) + (copy-sequence map) + (copy-alist map))) + +(cl-defmethod map-copy ((map hash-table)) + (copy-hash-table map)) + +(cl-defmethod map-copy ((map array)) + (copy-sequence map)) (cl-defgeneric map-apply (function map) "Apply FUNCTION to each element of MAP and return the result as a list. @@ -243,26 +268,28 @@ FUNCTION is called with two arguments, the key and the value.") (cl-defmethod map-do (function (map hash-table)) (maphash function map)) (cl-defgeneric map-keys-apply (function map) - "Return the result of applying FUNCTION to each key of MAP. + "Return the result of applying FUNCTION to each key in MAP. The default implementation delegates to `map-apply'." (map-apply (lambda (key _) (funcall function key)) map)) (cl-defgeneric map-values-apply (function map) - "Return the result of applying FUNCTION to each value of MAP. + "Return the result of applying FUNCTION to each value in MAP. The default implementation delegates to `map-apply'." (map-apply (lambda (_ val) (funcall function val)) map)) +(cl-defmethod map-values-apply (function (map array)) + (mapcar function map)) + (cl-defgeneric map-filter (pred map) "Return an alist of key/val pairs for which (PRED key val) is non-nil in MAP. The default implementation delegates to `map-apply'." (delq nil (map-apply (lambda (key val) - (if (funcall pred key val) - (cons key val) - nil)) + (and (funcall pred key val) + (cons key val))) map))) (cl-defgeneric map-remove (pred map) @@ -272,7 +299,7 @@ The default implementation delegates to `map-filter'." map)) (cl-defgeneric mapp (map) - "Return non-nil if MAP is a map (alist, hash-table, array, ...)." + "Return non-nil if MAP is a map (alist/plist, hash-table, array, ...)." (or (listp map) (hash-table-p map) (arrayp map))) @@ -292,56 +319,58 @@ The default implementation delegates to `map-length'." ;; test function! "Return non-nil if and only if MAP contains KEY. TESTFN is deprecated. Its default depends on MAP. -The default implementation delegates to `map-do'." +The default implementation delegates to `map-some'." (unless testfn (setq testfn #'equal)) - (catch 'map--catch - (map-do (lambda (k _v) - (if (funcall testfn key k) (throw 'map--catch t))) - map) - nil)) + (map-some (lambda (k _v) (funcall testfn key k)) map)) (cl-defmethod map-contains-key ((map list) key &optional testfn) - (let ((v '(nil))) - (not (eq v (alist-get key map v nil (or testfn #'equal)))))) + "Return non-nil if MAP contains KEY. +If MAP is an alist, TESTFN defaults to `equal'. +If MAP is a plist, `plist-member' is used instead." + (if (map--plist-p map) + (plist-member map key) + (let ((v '(nil))) + (not (eq v (alist-get key map v nil (or testfn #'equal))))))) (cl-defmethod map-contains-key ((map array) key &optional _testfn) - (and (integerp key) - (>= key 0) - (< key (length map)))) + "Return non-nil if KEY is an index of MAP, ignoring TESTFN." + (and (natnump key) (< key (length map)))) (cl-defmethod map-contains-key ((map hash-table) key &optional _testfn) + "Return non-nil if MAP contains KEY, ignoring TESTFN." (let ((v '(nil))) (not (eq v (gethash key map v))))) (cl-defgeneric map-some (pred map) "Return the first non-nil (PRED key val) in MAP. -The default implementation delegates to `map-apply'." +Return nil if no such element is found. +The default implementation delegates to `map-do'." ;; FIXME: Not sure if there's much benefit to defining it as defgeneric, ;; since as defined, I can't think of a map-type where we could provide an ;; algorithmically more efficient algorithm than the default. (catch 'map--break - (map-apply (lambda (key value) - (let ((result (funcall pred key value))) - (when result - (throw 'map--break result)))) - map) + (map-do (lambda (key value) + (let ((result (funcall pred key value))) + (when result + (throw 'map--break result)))) + map) nil)) (cl-defgeneric map-every-p (pred map) "Return non-nil if (PRED key val) is non-nil for all elements of MAP. -The default implementation delegates to `map-apply'." +The default implementation delegates to `map-do'." ;; FIXME: Not sure if there's much benefit to defining it as defgeneric, ;; since as defined, I can't think of a map-type where we could provide an ;; algorithmically more efficient algorithm than the default. (catch 'map--break - (map-apply (lambda (key value) + (map-do (lambda (key value) (or (funcall pred key value) (throw 'map--break nil))) map) t)) (defun map-merge (type &rest maps) - "Merge into a map of type TYPE all the key/value pairs in MAPS. + "Merge into a map of TYPE all the key/value pairs in MAPS. See `map-into' for all supported values of TYPE." (let ((result (map-into (pop maps) type))) (while maps @@ -349,48 +378,57 @@ See `map-into' for all supported values of TYPE." ;; For small tables, this is fine, but for large tables, we ;; should probably use a hash-table internally which we convert ;; to an alist in the end. - (map-apply (lambda (key value) - (setf (map-elt result key) value)) - (pop maps))) + (map-do (lambda (key value) + (setf (map-elt result key) value)) + (pop maps))) result)) (defun map-merge-with (type function &rest maps) - "Merge into a map of type TYPE all the key/value pairs in MAPS. -When two maps contain the same key (`eql'), call FUNCTION on the two + "Merge into a map of TYPE all the key/value pairs in MAPS. +When two maps contain the same (`eql') key, call FUNCTION on the two values and use the value returned by it. -MAP can be a list, hash-table or array. +Each of MAPS can be an alist, plist, hash-table, or array. See `map-into' for all supported values of TYPE." (let ((result (map-into (pop maps) type)) - (not-found (cons nil nil))) + (not-found (list nil))) (while maps - (map-apply (lambda (key value) - (cl-callf (lambda (old) - (if (eql old not-found) - value - (funcall function old value))) - (map-elt result key not-found))) - (pop maps))) + (map-do (lambda (key value) + (cl-callf (lambda (old) + (if (eql old not-found) + value + (funcall function old value))) + (map-elt result key not-found))) + (pop maps))) result)) (cl-defgeneric map-into (map type) - "Convert the map MAP into a map of type TYPE.") + "Convert MAP into a map of TYPE.") + ;; FIXME: I wish there was a way to avoid this η-redex! -(cl-defmethod map-into (map (_type (eql list))) (map-pairs map)) -(cl-defmethod map-into (map (_type (eql alist))) (map-pairs map)) +(cl-defmethod map-into (map (_type (eql list))) + "Convert MAP into an alist." + (map-pairs map)) + +(cl-defmethod map-into (map (_type (eql alist))) + "Convert MAP into an alist." + (map-pairs map)) + (cl-defmethod map-into (map (_type (eql plist))) - (let ((plist '())) - (map-do (lambda (k v) (setq plist `(,k ,v ,@plist))) map) - plist)) + "Convert MAP into a plist." + (let (plist) + (map-do (lambda (k v) (setq plist `(,v ,k ,@plist))) map) + (nreverse plist))) (cl-defgeneric map-put! (map key value &optional testfn) "Associate KEY with VALUE in MAP. If KEY is already present in MAP, replace the associated value with VALUE. This operates by modifying MAP in place. -If it cannot do that, it signals the `map-not-inplace' error. -If you want to insert an element without modifying MAP, use `map-insert'." +If it cannot do that, it signals a `map-not-inplace' error. +To insert an element without modifying MAP, use `map-insert'." ;; `testfn' only exists for backward compatibility with `map-put'! (declare (advertised-calling-convention (map key value) "27.1")) + ;; Can't use `cl-defmethod' with `advertised-calling-convention'. (map--dispatch map :list (if (map--plist-p map) @@ -404,18 +442,20 @@ If you want to insert an element without modifying MAP, use `map-insert'." ;; and let `map-insert' grow the array? :array (aset map key value))) -(define-error 'map-inplace "Can only modify map in place") - (cl-defgeneric map-insert (map key value) "Return a new map like MAP except that it associates KEY with VALUE. This does not modify MAP. -If you want to insert an element in place, use `map-put!'." - (if (listp map) - (if (map--plist-p map) - `(,key ,value ,@map) - (cons (cons key value) map)) - ;; FIXME: Should we signal an error or use copy+put! ? - (signal 'map-inplace (list map)))) +If you want to insert an element in place, use `map-put!'. +The default implementation defaults to `map-copy' and `map-put!'." + (let ((copy (map-copy map))) + (map-put! copy key value) + copy)) + +(cl-defmethod map-insert ((map list) key value) + "Cons KEY and VALUE to the front of MAP." + (if (map--plist-p map) + (cons key (cons value map)) + (cons (cons key value) map))) ;; There shouldn't be old source code referring to `map--put', yet we do ;; need to keep it for backward compatibility with .elc files where the @@ -425,11 +465,9 @@ If you want to insert an element in place, use `map-put!'." (cl-defmethod map-apply (function (map list)) (if (map--plist-p map) (cl-call-next-method) - (seq-map (lambda (pair) - (funcall function - (car pair) - (cdr pair))) - map))) + (mapcar (lambda (pair) + (funcall function (car pair) (cdr pair))) + map))) (cl-defmethod map-apply (function (map hash-table)) (let (result) @@ -439,46 +477,40 @@ If you want to insert an element in place, use `map-put!'." (nreverse result))) (cl-defmethod map-apply (function (map array)) - (let ((index 0)) - (seq-map (lambda (elt) - (prog1 - (funcall function index elt) - (setq index (1+ index)))) - map))) + (seq-map-indexed (lambda (elt index) + (funcall function index elt)) + map)) (cl-defmethod map-do (function (map list)) - "Private function used to iterate over ALIST using FUNCTION." (if (map--plist-p map) (while map (funcall function (pop map) (pop map))) - (seq-do (lambda (pair) - (funcall function - (car pair) - (cdr pair))) - map))) + (mapc (lambda (pair) + (funcall function (car pair) (cdr pair))) + map) + nil)) -(cl-defmethod map-do (function (array array)) - "Private function used to iterate over ARRAY using FUNCTION." +(cl-defmethod map-do (function (map array)) (seq-do-indexed (lambda (elt index) - (funcall function index elt)) - array)) + (funcall function index elt)) + map)) (defun map--into-hash (map keyword-args) "Convert MAP into a hash-table. KEYWORD-ARGS are forwarded to `make-hash-table'." (let ((ht (apply #'make-hash-table keyword-args))) - (map-apply (lambda (key value) - (setf (gethash key ht) value)) - map) + (map-do (lambda (key value) + (puthash key value ht)) + map) ht)) (cl-defmethod map-into (map (_type (eql hash-table))) - "Convert MAP into a hash-table." - (map--into-hash map (list :size (map-length map) :test 'equal))) + "Convert MAP into a hash-table with keys compared with `equal'." + (map--into-hash map (list :size (map-length map) :test #'equal))) (cl-defmethod map-into (map (type (head hash-table))) "Convert MAP into a hash-table. -TYPE is a list where the car is `hash-table' and the cdr are the +TYPE is a list whose car is `hash-table' and cdr a list of keyword-args forwarded to `make-hash-table'. Example: @@ -487,23 +519,23 @@ Example: (defun map--make-pcase-bindings (args) "Return a list of pcase bindings from ARGS to the elements of a map." - (seq-map (lambda (elt) - (cond ((consp elt) - `(app (pcase--flip map-elt ,(car elt)) ,(cadr elt))) - ((keywordp elt) - (let ((var (intern (substring (symbol-name elt) 1)))) - `(app (pcase--flip map-elt ,elt) ,var))) - (t `(app (pcase--flip map-elt ',elt) ,elt)))) - args)) + (mapcar (lambda (elt) + (cond ((consp elt) + `(app (pcase--flip map-elt ,(car elt)) ,(cadr elt))) + ((keywordp elt) + (let ((var (intern (substring (symbol-name elt) 1)))) + `(app (pcase--flip map-elt ,elt) ,var))) + (t `(app (pcase--flip map-elt ',elt) ,elt)))) + args)) (defun map--make-pcase-patterns (args) "Return a list of `(map ...)' pcase patterns built from ARGS." (cons 'map - (seq-map (lambda (elt) - (if (and (consp elt) (eq 'map (car elt))) - (map--make-pcase-patterns elt) - elt)) - args))) + (mapcar (lambda (elt) + (if (eq (car-safe elt) 'map) + (map--make-pcase-patterns elt) + elt)) + args))) (provide 'map) ;;; map.el ends here diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index adfce95017..2b8807faad 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -134,9 +134,10 @@ Unlike `seq-map', FUNCTION takes two arguments: the element of the sequence, and its index within the sequence." (let ((index 0)) (seq-do (lambda (elt) - (funcall function elt index) - (setq index (1+ index))) - sequence))) + (funcall function elt index) + (setq index (1+ index))) + sequence)) + nil) (cl-defgeneric seqp (object) "Return non-nil if OBJECT is a sequence, nil otherwise." diff --git a/test/lisp/emacs-lisp/map-tests.el b/test/lisp/emacs-lisp/map-tests.el index 9a2cd42a21..67666d8e7e 100644 --- a/test/lisp/emacs-lisp/map-tests.el +++ b/test/lisp/emacs-lisp/map-tests.el @@ -22,7 +22,7 @@ ;;; Commentary: -;; Tests for map.el +;; Tests for map.el. ;;; Code: @@ -30,12 +30,10 @@ (require 'map) (defmacro with-maps-do (var &rest body) - "Successively bind VAR to an alist, vector and hash-table. + "Successively bind VAR to an alist, plist, vector, and hash-table. Each map is built from the following alist data: -'((0 . 3) (1 . 4) (2 . 5)). -Evaluate BODY for each created map. - -\(fn (var map) body)" + \\='((0 . 3) (1 . 4) (2 . 5)). +Evaluate BODY for each created map." (declare (indent 1) (debug (symbolp body))) (let ((alist (make-symbol "alist")) (plist (make-symbol "plist")) @@ -53,43 +51,62 @@ Evaluate BODY for each created map. (dolist (,var (list ,alist ,plist ,vec ,ht)) ,@body)))) +(defmacro with-empty-maps-do (var &rest body) + "Like `with-maps-do', but with empty maps." + (declare (indent 1) (debug (symbolp body))) + `(dolist (,var (list (list) (vector) (make-hash-table))) + ,@body)) + +(ert-deftest test-map-plist-p () + "Test `map--plist-p'." + (with-empty-maps-do map + (should-not (map--plist-p map))) + (should-not (map--plist-p "")) + (should-not (map--plist-p '((())))) + (should (map--plist-p '(:a))) + (should (map--plist-p '(a))) + (should (map--plist-p '(nil))) + (should (map--plist-p '("")))) + (ert-deftest test-map-elt () (with-maps-do map (should (= 3 (map-elt map 0))) (should (= 4 (map-elt map 1))) (should (= 5 (map-elt map 2))) - (should (null (map-elt map -1))) - (should (null (map-elt map 4))))) + (should-not (map-elt map -1)) + (should-not (map-elt map 4)) + (should-not (map-elt map 0.1)))) (ert-deftest test-map-elt-default () (with-maps-do map - (should (= 5 (map-elt map 7 5))))) + (should (= 5 (map-elt map 7 5))) + (should (= 5 (map-elt map 0.1 5)))) + (with-empty-maps-do map + (should (= 5 (map-elt map 0 5))))) (ert-deftest test-map-elt-testfn () (let ((map (list (cons "a" 1) (cons "b" 2))) ;; Make sure to use a non-eq "a", even when compiled. (noneq-key (string ?a))) (should-not (map-elt map noneq-key)) - (should (map-elt map noneq-key nil 'equal)))) + (should (map-elt map noneq-key nil #'equal)))) (ert-deftest test-map-elt-with-nil-value () - (should (null (map-elt '((a . 1) - (b)) - 'b - '2)))) + (should-not (map-elt '((a . 1) (b)) 'b 2))) (ert-deftest test-map-put! () (with-maps-do map (setf (map-elt map 2) 'hello) (should (eq (map-elt map 2) 'hello))) (with-maps-do map - (map-put map 2 'hello) + (with-suppressed-warnings ((obsolete map-put)) + (map-put map 2 'hello)) (should (eq (map-elt map 2) 'hello))) (with-maps-do map (map-put! map 2 'hello) (should (eq (map-elt map 2) 'hello)) (if (not (or (hash-table-p map) - (and (listp map) (not (listp (car map)))))) ;plist! + (map--plist-p map))) (should-error (map-put! map 5 'value) ;; For vectors, it could arguably signal ;; map-not-inplace as well, but it currently doesn't. @@ -97,49 +114,88 @@ Evaluate BODY for each created map. 'map-not-inplace 'error)) (map-put! map 5 'value) - (should (eq (map-elt map 5) 'value)))) - (let ((ht (make-hash-table))) - (setf (map-elt ht 2) 'a) - (should (eq (map-elt ht 2) - 'a))) - (let ((alist '((0 . a) (1 . b) (2 . c)))) - (setf (map-elt alist 2) 'a) - (should (eq (map-elt alist 2) - 'a))) - (let ((vec [3 4 5])) - (should-error (setf (map-elt vec 3) 6)))) + (should (eq (map-elt map 5) 'value))))) + +(ert-deftest test-map-put!-new-keys () + "Test `map-put!' with new keys." + (with-maps-do map + (let ((size (map-length map))) + (if (arrayp map) + (progn + (should-error (setf (map-elt map 'k) 'v)) + (should-error (setf (map-elt map size) 'v))) + (setf (map-elt map 'k) 'v) + (should (eq (map-elt map 'k) 'v)) + (setf (map-elt map size) 'v) + (should (eq (map-elt map size) 'v)))))) (ert-deftest test-map-put-alist-new-key () "Regression test for Bug#23105." - (let ((alist '((0 . a)))) - (map-put alist 2 'b) - (should (eq (map-elt alist 2) - 'b)))) + (let ((alist (list (cons 0 'a)))) + (with-suppressed-warnings ((obsolete map-put)) + (map-put alist 2 'b)) + (should (eq (map-elt alist 2) 'b)))) (ert-deftest test-map-put-testfn-alist () (let ((alist (list (cons "a" 1) (cons "b" 2))) ;; Make sure to use a non-eq "a", even when compiled. (noneq-key (string ?a))) - (map-put alist noneq-key 3 #'equal) - (should-not (cddr alist)) - (map-put alist noneq-key 9 #'eql) - (should (cddr alist)))) + (with-suppressed-warnings ((obsolete map-put)) + (map-put alist noneq-key 3 #'equal) + (should-not (cddr alist)) + (map-put alist noneq-key 9 #'eql) + (should (cddr alist))))) (ert-deftest test-map-put-return-value () (let ((ht (make-hash-table))) - (should (eq (map-put ht 'a 'hello) 'hello)))) + (with-suppressed-warnings ((obsolete map-put)) + (should (eq (map-put ht 'a 'hello) 'hello))))) + +(ert-deftest test-map-insert-empty () + "Test `map-insert' on empty maps." + (with-empty-maps-do map + (if (arrayp map) + (should-error (map-insert map 0 6)) + (let ((new (map-insert map 0 6))) + (should-not (eq map new)) + (should-not (map-pairs map)) + (should (= (map-elt new 0) 6)))))) + +(ert-deftest test-map-insert () + "Test `map-insert'." + (with-maps-do map + (let ((pairs (map-pairs map)) + (size (map-length map)) + (new (map-insert map 0 6))) + (should-not (eq map new)) + (should (equal (map-pairs map) pairs)) + (should (= (map-elt new 0) 6)) + (if (arrayp map) + (should-error (map-insert map size 7)) + (setq new (map-insert map size 7)) + (should-not (eq map new)) + (should (equal (map-pairs map) pairs)) + (should (= (map-elt new size) 7)))))) (ert-deftest test-map-delete () (with-maps-do map - (map-delete map 1) - (should (null (map-elt map 1)))) + (should (map-elt map 1)) + (should (eq map (map-delete map 1))) + (should-not (map-elt map 1))) (with-maps-do map - (map-delete map -2) - (should (null (map-elt map -2))))) + (should-not (map-elt map -2)) + (should (eq map (map-delete map -2))) + (should-not (map-elt map -2))) + (with-maps-do map + ;; Check for OBOE. + (let ((key (map-length map))) + (should-not (map-elt map key)) + (should (eq map (map-delete map key))) + (should-not (map-elt map key))))) -(ert-deftest test-map-delete-return-value () - (let ((ht (make-hash-table))) - (should (eq (map-delete ht 'a) ht)))) +(ert-deftest test-map-delete-empty () + (with-empty-maps-do map + (should (eq map (map-delete map t))))) (ert-deftest test-map-nested-elt () (let ((vec [a b [c d [e f]]])) @@ -149,8 +205,9 @@ Evaluate BODY for each created map. (d . 3) (e . ((f . 4) (g . 5)))))))) - (should (eq (map-nested-elt alist '(b e f)) - 4))) + (should (eq (map-nested-elt alist '(b e f)) 4))) + (let ((plist '(a 1 b (c 2 d 3 e (f 4 g 5))))) + (should (eq (map-nested-elt plist '(b e f)) 4))) (let ((ht (make-hash-table))) (setf (map-elt ht 'a) 1) (setf (map-elt ht 'b) (make-hash-table)) @@ -160,214 +217,238 @@ Evaluate BODY for each created map. (ert-deftest test-map-nested-elt-default () (let ((vec [a b [c d]])) - (should (null (map-nested-elt vec '(2 3)))) - (should (null (map-nested-elt vec '(2 1 1)))) + (should-not (map-nested-elt vec '(2 3))) + (should-not (map-nested-elt vec '(2 1 1))) (should (= 4 (map-nested-elt vec '(2 1 1) 4))))) (ert-deftest test-mapp () - (should (mapp nil)) - (should (mapp '((a . b) (c . d)))) - (should (mapp '(a b c d))) - (should (mapp [])) - (should (mapp [1 2 3])) - (should (mapp (make-hash-table))) + (with-empty-maps-do map + (should (mapp map))) + (with-maps-do map + (should (mapp map))) + (should (mapp "")) (should (mapp "hello")) - (should (not (mapp 1))) - (should (not (mapp 'hello)))) + (should-not (mapp 1)) + (should-not (mapp 'hello))) (ert-deftest test-map-keys () (with-maps-do map (should (equal (map-keys map) '(0 1 2)))) - (should (null (map-keys nil))) - (should (null (map-keys [])))) + (with-empty-maps-do map + (should-not (map-keys map)))) (ert-deftest test-map-values () (with-maps-do map - (should (equal (map-values map) '(3 4 5))))) + (should (equal (map-values map) '(3 4 5)))) + (with-empty-maps-do map + (should-not (map-values map)))) (ert-deftest test-map-pairs () (with-maps-do map - (should (equal (map-pairs map) '((0 . 3) - (1 . 4) - (2 . 5)))))) + (should (equal (map-pairs map) + '((0 . 3) + (1 . 4) + (2 . 5))))) + (with-empty-maps-do map + (should-not (map-pairs map)))) (ert-deftest test-map-length () - (let ((ht (make-hash-table))) - (puthash 'a 1 ht) - (puthash 'b 2 ht) - (puthash 'c 3 ht) - (puthash 'd 4 ht) - (should (= 0 (map-length nil))) - (should (= 0 (map-length []))) - (should (= 0 (map-length (make-hash-table)))) - (should (= 5 (map-length [0 1 2 3 4]))) - (should (= 2 (map-length '((a . 1) (b . 2))))) - (should (= 4 (map-length ht))))) + (with-empty-maps-do map + (should (zerop (map-length map)))) + (with-maps-do map + (should (= 3 (map-length map)))) + (should (= 1 (map-length '(nil 1)))) + (should (= 2 (map-length '(nil 1 t 2)))) + (should (= 2 (map-length '((a . 1) (b . 2))))) + (should (= 5 (map-length [0 1 2 3 4]))) + (should (= 4 (map-length #s(hash-table data (a 1 b 2 c 3 d 4)))))) (ert-deftest test-map-copy () (with-maps-do map (let ((copy (map-copy map))) - (should (equal (map-keys map) (map-keys copy))) - (should (equal (map-values map) (map-values copy))) - (should (not (eq map copy)))))) + (should (equal (map-pairs map) (map-pairs copy))) + (should-not (eq map copy)) + (map-put! map 0 0) + (should-not (equal (map-pairs map) (map-pairs copy))))) + (with-empty-maps-do map + (should-not (map-pairs (map-copy map))))) + +(ert-deftest test-map-copy-alist () + "Test use of `copy-alist' for alists." + (let* ((cons (list 'a 1 2)) + (alist (list cons)) + (copy (map-copy alist))) + (setcar cons 'b) + (should (equal alist '((b 1 2)))) + (should (equal copy '((a 1 2)))) + (setcar (cdr cons) 0) + (should (equal alist '((b 0 2)))) + (should (equal copy '((a 0 2)))) + (setcdr cons 3) + (should (equal alist '((b . 3)))) + (should (equal copy '((a 0 2)))))) (ert-deftest test-map-apply () - (with-maps-do map - (should (equal (map-apply (lambda (k v) (cons (int-to-string k) v)) - map) - '(("0" . 3) ("1" . 4) ("2" . 5))))) - (let ((vec [a b c])) - (should (equal (map-apply (lambda (k v) (cons (1+ k) v)) - vec) - '((1 . a) - (2 . b) - (3 . c)))))) + (let ((fn (lambda (k v) (cons (number-to-string k) v)))) + (with-maps-do map + (should (equal (map-apply fn map) + '(("0" . 3) ("1" . 4) ("2" . 5))))) + (with-empty-maps-do map + (should-not (map-apply fn map))))) (ert-deftest test-map-do () - (with-maps-do map - (let ((result nil)) - (map-do (lambda (k v) - (push (list (int-to-string k) v) result)) - map) - (should (equal result '(("2" 5) ("1" 4) ("0" 3))))))) + (let* (res + (fn (lambda (k v) + (push (list (number-to-string k) v) res)))) + (with-empty-maps-do map + (should-not (map-do fn map)) + (should-not res)) + (with-maps-do map + (setq res nil) + (should-not (map-do fn map)) + (should (equal res '(("2" 5) ("1" 4) ("0" 3))))))) (ert-deftest test-map-keys-apply () (with-maps-do map - (should (equal (map-keys-apply (lambda (k) (int-to-string k)) - map) - '("0" "1" "2")))) - (let ((vec [a b c])) - (should (equal (map-keys-apply (lambda (k) (1+ k)) - vec) - '(1 2 3))))) + (should (equal (map-keys-apply #'1+ map) '(1 2 3)))) + (with-empty-maps-do map + (let (ks) + (should-not (map-keys-apply (lambda (k) (push k ks)) map)) + (should-not ks)))) (ert-deftest test-map-values-apply () (with-maps-do map - (should (equal (map-values-apply (lambda (v) (1+ v)) - map) - '(4 5 6)))) - (let ((vec [a b c])) - (should (equal (map-values-apply (lambda (v) (symbol-name v)) - vec) - '("a" "b" "c"))))) + (should (equal (map-values-apply #'1+ map) '(4 5 6)))) + (with-empty-maps-do map + (let (vs) + (should-not (map-values-apply (lambda (v) (push v vs)) map)) + (should-not vs)))) (ert-deftest test-map-filter () (with-maps-do map - (should (equal (map-keys (map-filter (lambda (_k v) - (<= 4 v)) - map)) - '(1 2))) - (should (null (map-filter (lambda (k _v) - (eq 'd k)) - map)))) - (should (null (map-filter (lambda (_k v) - (eq 3 v)) - [1 2 4 5]))) - (should (equal (map-filter (lambda (k _v) - (eq 3 k)) - [1 2 4 5]) - '((3 . 5))))) + (should (equal (map-filter (lambda (_k v) (> v 3)) map) + '((1 . 4) (2 . 5)))) + (should (equal (map-filter #'always map) (map-pairs map))) + (should-not (map-filter #'ignore map))) + (with-empty-maps-do map + (should-not (map-filter #'always map)) + (should-not (map-filter #'ignore map)))) (ert-deftest test-map-remove () (with-maps-do map - (should (equal (map-keys (map-remove (lambda (_k v) - (>= v 4)) - map)) - '(0))) - (should (equal (map-keys (map-remove (lambda (k _v) - (eq 'd k)) - map)) - (map-keys map)))) - (should (equal (map-remove (lambda (_k v) - (eq 3 v)) - [1 2 4 5]) - '((0 . 1) - (1 . 2) - (2 . 4) - (3 . 5)))) - (should (null (map-remove (lambda (k _v) - (>= k 0)) - [1 2 4 5])))) + (should (equal (map-remove (lambda (_k v) (> v 3)) map) + '((0 . 3)))) + (should (equal (map-remove #'ignore map) (map-pairs map))) + (should-not (map-remove #'always map))) + (with-empty-maps-do map + (should-not (map-remove #'always map)) + (should-not (map-remove #'ignore map)))) (ert-deftest test-map-empty-p () - (should (map-empty-p nil)) - (should (not (map-empty-p '((a . b) (c . d))))) - (should (map-empty-p [])) - (should (not (map-empty-p [1 2 3]))) - (should (map-empty-p (make-hash-table))) - (should (not (map-empty-p "hello"))) - (should (map-empty-p ""))) + (with-empty-maps-do map + (should (map-empty-p map))) + (should (map-empty-p "")) + (should-not (map-empty-p '((a . b) (c . d)))) + (should-not (map-empty-p [1 2 3])) + (should-not (map-empty-p "hello"))) (ert-deftest test-map-contains-key () - (should (map-contains-key '((a . 1) (b . 2)) 'a)) - (should (not (map-contains-key '((a . 1) (b . 2)) 'c))) - (should (map-contains-key '(("a" . 1)) "a")) - (should (not (map-contains-key '(("a" . 1)) "a" #'eq))) - (should (map-contains-key [a b c] 2)) - (should (not (map-contains-key [a b c] 3)))) + (with-empty-maps-do map + (should-not (map-contains-key map -1)) + (should-not (map-contains-key map 0)) + (should-not (map-contains-key map 1)) + (should-not (map-contains-key map (map-length map)))) + (with-maps-do map + (should-not (map-contains-key map -1)) + (should (map-contains-key map 0)) + (should (map-contains-key map 1)) + (should-not (map-contains-key map (map-length map))))) + +(ert-deftest test-map-contains-key-testfn () + "Test `map-contains-key' under different equalities." + (let ((key (string ?a)) + (plist '("a" 1 a 2)) + (alist '(("a" . 1) (a . 2)))) + (should (map-contains-key alist 'a)) + (should (map-contains-key plist 'a)) + (should (map-contains-key alist 'a #'eq)) + (should (map-contains-key plist 'a #'eq)) + (should (map-contains-key alist key)) + (should-not (map-contains-key plist key)) + (should-not (map-contains-key alist key #'eq)) + (should-not (map-contains-key plist key #'eq)))) (ert-deftest test-map-some () (with-maps-do map - (should (map-some (lambda (k _v) - (eq 1 k)) - map)) - (should-not (map-some (lambda (k _v) - (eq 'd k)) - map))) - (let ((vec [a b c])) - (should (map-some (lambda (k _v) - (> k 1)) - vec)) - (should-not (map-some (lambda (k _v) - (> k 3)) - vec)))) + (should (eq (map-some (lambda (k _v) (and (= k 1) 'found)) map) + 'found)) + (should-not (map-some #'ignore map))) + (with-empty-maps-do map + (should-not (map-some #'always map)) + (should-not (map-some #'ignore map)))) (ert-deftest test-map-every-p () (with-maps-do map - (should (map-every-p (lambda (k _v) - k) - map)) - (should (not (map-every-p (lambda (_k _v) - nil) - map)))) - (let ((vec [a b c])) - (should (map-every-p (lambda (k _v) - (>= k 0)) - vec)) - (should (not (map-every-p (lambda (k _v) - (> k 3)) - vec))))) + (should (map-every-p #'always map)) + (should-not (map-every-p #'ignore map)) + (should-not (map-every-p (lambda (k _v) (zerop k)) map))) + (with-empty-maps-do map + (should (map-every-p #'always map)) + (should (map-every-p #'ignore map)) + (should (map-every-p (lambda (k _v) (zerop k)) map)))) (ert-deftest test-map-into () - (let* ((alist '((a . 1) (b . 2))) + (let* ((plist '(a 1 b 2)) + (alist '((a . 1) (b . 2))) (ht (map-into alist 'hash-table)) (ht2 (map-into alist '(hash-table :test equal)))) (should (hash-table-p ht)) - (should (equal (map-into (map-into alist 'hash-table) 'list) - alist)) - (should (listp (map-into ht 'list))) - (should (equal (map-keys (map-into (map-into ht 'list) 'hash-table)) - (map-keys ht))) - (should (equal (map-values (map-into (map-into ht 'list) 'hash-table)) - (map-values ht))) + (should (equal (map-into ht 'list) alist)) + (should (equal (map-pairs (map-into (map-into ht 'list) 'hash-table)) + (map-pairs ht))) (should (equal (map-into ht 'alist) (map-into ht2 'alist))) - (should (eq (hash-table-test ht2) 'equal)) - (should (null (map-into nil 'list))) - (should (map-empty-p (map-into nil 'hash-table))) - (should-error (map-into [1 2 3] 'string)))) + (should (equal (map-into alist 'list) alist)) + (should (equal (map-into alist 'alist) alist)) + (should (equal (map-into alist 'plist) plist)) + (should (equal (map-into plist 'alist) alist)) + (should (equal (map-into plist 'plist) plist))) + (should-error (map-into [1 2 3] 'string) :type 'cl-no-applicable-method)) + +(ert-deftest test-map-into-hash-test () + "Test `map-into' with different hash-table test functions." + (should (eq (hash-table-test (map-into () 'hash-table)) #'equal)) + (should (eq (hash-table-test (map-into () '(hash-table))) #'eql)) + (should (eq (hash-table-test (map-into () '(hash-table :test eq))) #'eq)) + (should (eq (hash-table-test (map-into () '(hash-table :test eql))) #'eql)) + (should (eq (hash-table-test (map-into () '(hash-table :test equal))) + #'equal))) + +(ert-deftest test-map-into-empty () + "Test `map-into' with empty maps." + (with-empty-maps-do map + (should-not (map-into map 'list)) + (should-not (map-into map 'alist)) + (should-not (map-into map 'plist)) + (should (map-empty-p (map-into map 'hash-table))))) (ert-deftest test-map-let () (map-let (foo bar baz) '((foo . 1) (bar . 2)) (should (= foo 1)) (should (= bar 2)) - (should (null baz))) + (should-not baz)) (map-let (('foo a) ('bar b) ('baz c)) '((foo . 1) (bar . 2)) (should (= a 1)) (should (= b 2)) - (should (null c)))) + (should-not c))) + +(ert-deftest test-map-merge () + "Test `map-merge'." + (should (equal (map-merge 'list '(a 1) '((b . 2) (c . 3)) + #s(hash-table data (c 4))) + '((c . 4) (b . 2) (a . 1))))) (ert-deftest test-map-merge-with () (should (equal (map-merge-with 'list #'+ @@ -376,6 +457,19 @@ Evaluate BODY for each created map. '((1 . 1) (2 . 5) (3 . 0))) '((3 . 0) (2 . 9) (1 . 6))))) +(ert-deftest test-map-merge-empty () + "Test merging of empty maps." + (should-not (map-merge 'list)) + (should-not (map-merge 'alist)) + (should-not (map-merge 'plist)) + (should-not (map-merge-with 'list #'+)) + (should-not (map-merge-with 'alist #'+)) + (should-not (map-merge-with 'plist #'+)) + (should (map-empty-p (map-merge 'hash-table))) + (should (map-empty-p (map-merge-with 'hash-table #'+))) + (should-error (map-merge 'array) :type 'cl-no-applicable-method) + (should-error (map-merge-with 'array #'+) :type 'cl-no-applicable-method)) + (ert-deftest test-map-plist-pcase () (let ((plist '(:one 1 :two 2))) (should (equal (pcase-let (((map :one (:two two)) plist)) commit 1d43c1854a5cd8305200f6cff8ff8e80cb2b4b8a Author: Alan Mackenzie Date: Sat Mar 6 15:22:25 2021 +0000 CC Mode: Fix calculation of c-parse-state when there're macros with braces This fixes bug #46951. * lisp/progmodes/cc-engine.el (c-append-lower-brace-pair-to-state-cache): Ensure the starting point for backward scanning is not within a macro which doesn't contain HERE. diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 5a8b2f4f90..b7ad02cf0c 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -3793,12 +3793,14 @@ mhtml-mode." (point))) (bra ; Position of "{". ;; Don't start scanning in the middle of a CPP construct unless - ;; it contains HERE - these constructs, in Emacs, are "commented - ;; out" with category properties. - (if (eq (c-get-char-property macro-start-or-from 'category) - 'c-cpp-delimiter) - macro-start-or-from - from)) + ;; it contains HERE. + (if (and (not (eq macro-start-or-from from)) + (< macro-start-or-from here) ; Might not be needed. + (progn (goto-char macro-start-or-from) + (c-end-of-macro) + (>= (point) here))) + from + macro-start-or-from)) ce) ; Position of "}" (or upper-lim (setq upper-lim from)) commit b8e3f338a67ca9c440f52ff2a6a9ac98dd5e0154 Author: Stefan Monnier Date: Sat Mar 6 09:56:43 2021 -0500 * lisp/progmodes/flymake.el (flymake-log): Push the right code diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index e9b2b8a77c..8481a27775 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -294,7 +294,7 @@ generated it." (sublog (if file (intern (file-name-nondirectory - (file-name-sans-extension compile-file)))))) + (file-name-sans-extension file)))))) `(flymake--log-1 ,level ',sublog ,msg ,@args))) (defun flymake-error (text &rest args) commit da383aeb8e629f642b46e9c64b2ffcec9976c23f Author: Stefan Monnier Date: Sat Mar 6 09:55:30 2021 -0500 * lisp/progmodes/flymake.el (flymake-log): Simplify diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index e7e746b981..e9b2b8a77c 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -284,15 +284,14 @@ If set to nil, don't suppress any zero counters." (defmacro flymake-log (level msg &rest args) "Log, at level LEVEL, the message MSG formatted with ARGS. LEVEL is passed to `display-warning', which is used to display -the warning. If this form is included in a byte-compiled file, +the warning. If this form is included in a file, the generated warning contains an indication of the file that generated it." - (let* ((compile-file (or (and (fboundp 'macroexp-file-name) - (macroexp-file-name)) - (bound-and-true-p byte-compile-current-file))) - (sublog (if (and - compile-file - (not load-file-name)) + (let* ((file (if (fboundp 'macroexp-file-name) + (macroexp-file-name) + (and (not load-file-name) + (bound-and-true-p byte-compile-current-file)))) + (sublog (if file (intern (file-name-nondirectory (file-name-sans-extension compile-file)))))) commit 45b1151696287e469dcb426f8b6e908125635373 Author: Eli Zaretskii Date: Sat Mar 6 16:49:00 2021 +0200 Revert "Fix Makefile subshell output when run in parallel" This reverts commit 117505454ce04c0c0ce2c2b4058823cf764fc2eb. It breaks the build for versions of GNU Make that don't support -O. diff --git a/Makefile.in b/Makefile.in index 0e16145c0a..856c29a453 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1008,7 +1008,7 @@ misc-dvi misc-html misc-pdf misc-ps: src info-dir: ${srcdir}/info/dir -texi_misc = $(shell ${MAKE} --no-print-directory -O -s -C doc/misc echo-sources) +texi_misc = $(shell ${MAKE} --no-print-directory -s -C doc/misc echo-sources) srcdir_doc_info_dir_inputs = \ ${srcdir}/doc/emacs/emacs.texi \ commit 117505454ce04c0c0ce2c2b4058823cf764fc2eb Author: Basil L. Contovounesios Date: Sat Mar 6 11:40:48 2021 +0000 Fix Makefile subshell output when run in parallel For discussion, see the following thread: https://lists.gnu.org/r/emacs-devel/2021-03/msg00255.html * Makefile.in (texi_misc): Avoid interspersing parallel Make output with that from subshell. diff --git a/Makefile.in b/Makefile.in index 856c29a453..0e16145c0a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1008,7 +1008,7 @@ misc-dvi misc-html misc-pdf misc-ps: src info-dir: ${srcdir}/info/dir -texi_misc = $(shell ${MAKE} --no-print-directory -s -C doc/misc echo-sources) +texi_misc = $(shell ${MAKE} --no-print-directory -O -s -C doc/misc echo-sources) srcdir_doc_info_dir_inputs = \ ${srcdir}/doc/emacs/emacs.texi \ commit 6c498786fed219ee8f98092f7921b5a5b1aaca29 Author: Basil L. Contovounesios Date: Sat Mar 6 13:13:40 2021 +0000 Pacify some semantic-tag-make-plist warnings * lisp/cedet/semantic/tag.el (semantic-tag-make-plist): Define before its first use to pacify some recent "may not be defined at runtime" warnings after turning on lexical-binding. diff --git a/lisp/cedet/semantic/tag.el b/lisp/cedet/semantic/tag.el index 3d7bce8657..a99e2ab279 100644 --- a/lisp/cedet/semantic/tag.el +++ b/lisp/cedet/semantic/tag.el @@ -229,6 +229,28 @@ See also the function `semantic-ctxt-current-mode'." (require 'semantic/ctxt) (semantic-ctxt-current-mode))))) +;; Is this function still necessary? +(defun semantic-tag-make-plist (args) + "Create a property list with ARGS. +Args is a property list of the form (KEY1 VALUE1 ... KEYN VALUEN). +Where KEY is a symbol, and VALUE is the value for that symbol. +The return value will be a new property list, with these KEY/VALUE +pairs eliminated: + + - KEY associated to nil VALUE. + - KEY associated to an empty string VALUE. + - KEY associated to a zero VALUE." + (let (plist key val) + (while args + (setq key (car args) + val (nth 1 args) + args (nthcdr 2 args)) + (or (member val '("" nil)) + (and (numberp val) (zerop val)) + (setq plist (cons key (cons val plist))))) + ;; It is not useful to reverse the new plist. + plist)) + (defsubst semantic--tag-attributes-cdr (tag) "Return the cons cell whose car is the ATTRIBUTES part of TAG. That function is for internal use only." @@ -441,28 +463,6 @@ class to store those methods." ;;; Tag creation ;; -;; Is this function still necessary? -(defun semantic-tag-make-plist (args) - "Create a property list with ARGS. -Args is a property list of the form (KEY1 VALUE1 ... KEYN VALUEN). -Where KEY is a symbol, and VALUE is the value for that symbol. -The return value will be a new property list, with these KEY/VALUE -pairs eliminated: - - - KEY associated to nil VALUE. - - KEY associated to an empty string VALUE. - - KEY associated to a zero VALUE." - (let (plist key val) - (while args - (setq key (car args) - val (nth 1 args) - args (nthcdr 2 args)) - (or (member val '("" nil)) - (and (numberp val) (zerop val)) - (setq plist (cons key (cons val plist))))) - ;; It is not useful to reverse the new plist. - plist)) - (defsubst semantic-tag (name class &rest attributes) "Create a generic semantic tag. NAME is a string representing the name of this tag. commit 328e7cc475e3cd08fd72b71f985fcee6895e4c7e Author: Lars Ingebrigtsen Date: Sat Mar 6 13:27:34 2021 +0100 Remove mention of using defun- and defvar- as prefixes * doc/lispref/tips.texi (Coding Conventions): Remove mention of using defun- and defvar- as prefixes, as this is something that we rarely do in Emacs (bug#46899). diff --git a/doc/lispref/tips.texi b/doc/lispref/tips.texi index 4a7793a976..36c68ee5ce 100644 --- a/doc/lispref/tips.texi +++ b/doc/lispref/tips.texi @@ -75,8 +75,8 @@ example, it is our convention to have commands that list objects named as @samp{list-@var{something}}, e.g., a package called @samp{frob} could have a command @samp{list-frobs}, when its other global symbols begin with @samp{frob-}. Also, constructs that define functions, -variables, etc., work better if they start with @samp{defun} or -@samp{defvar}, so put the name prefix later on in the name. +variables, etc., work better if they start with @samp{define-}, so put +the name prefix later on in the name. This recommendation applies even to names for traditional Lisp primitives that are not primitives in Emacs Lisp---such as commit 4eb8cbd90379fee413ef138ed71176204775f255 Author: Eli Zaretskii Date: Sat Mar 6 12:16:37 2021 +0200 ; Fix last change. diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 866404f0ff..b3246494a2 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -3426,8 +3426,8 @@ Like @code{vec}, but it unpacks to and packs from lists, whereas List of bits that are set to 1 in @var{len} bytes. The bytes are taken in big-endian order, and the bits are numbered starting with @code{8 * @var{len} @minus{} 1} and ending with zero. For example: -@code{bits 2} unpacks @code{#x28} @code{#x1c} to @code{(2 3 4 11 13)} -and @code{#x1c} @code{#x28} to @code{(3 5 10 11 12)}. +@code{bits 2} unpacks @code{#x28} @code{#x1c} to @w{@code{(2 3 4 11 13)}} +and @code{#x1c} @code{#x28} to @w{@code{(3 5 10 11 12)}}. @item fill @var{len} @var{len} bytes used as a mere filler. In packing, these bytes are commit 16a98c39ffa0eaa9e9753b96a1fcf2e921a31301 Author: Eli Zaretskii Date: Sat Mar 6 12:12:44 2021 +0200 Improve documentation of Bindat * doc/lispref/processes.texi (Bindat Types, Bindat Functions) (Bindat Computed Types): Improve wording and add indexing. * etc/NEWS: Add a pointer to the ELisp manual for "Bindat". diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 23111f7c5c..866404f0ff 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -3361,24 +3361,30 @@ direction is also known as @dfn{serializing} or @dfn{packing}. @node Bindat Types @subsection Describing Data Layout +@cindex bindat types +@cindex data layout specification +@cindex bindat type expression +@cindex base type, in bindat specification +@cindex composite type, in bindat specification To control unpacking and packing, you write a @dfn{data layout -specification}, also called a Bindat type expression. -This can be a base type or a composite type made of several fields, +specification}, also called a @dfn{Bindat type expression}. This can +be a @dfn{base type} or a @dfn{composite type} made of several fields, where the specification controls the length of each field to be processed, and how to pack or unpack it. We normally keep bindat type -values in variables whose names end in @samp{-bindat-spec}; that kind of name -is automatically recognized as risky. +values in variables whose names end in @code{-bindat-spec}; that kind +of name is automatically recognized as risky (@pxref{File Local +Variables}). @defmac bindat-type &rest type Creates a Bindat type @emph{value} object according to the Bindat type @emph{expression} @var{type}. @end defmac -@cindex endianness -@cindex big endian -@cindex little endian -@cindex network byte ordering +@cindex endianness, in bindat specification +@cindex big endian, in bindat specification +@cindex little endian, in bindat specification +@cindex network byte ordering, in Bindat specification A field's @dfn{type} describes the size (in bytes) of the object that the field represents and, in the case of multibyte fields, how the bytes are ordered within the field. The two possible orderings @@ -3408,19 +3414,20 @@ String of bytes of length @var{len}. Zero-terminated string of bytes, in a fixed-size field with length @var{len}. @item vec @var{len} [@var{type}] -Vector of @var{len} elements of type @var{type}, defaulting to bytes. -The @var{type} can be any Bindat type expression. +Vector of @var{len} elements. The type of the elements is given by +@var{type}, defaulting to bytes. The @var{type} can be any Bindat +type expression. @item repeat @var{len} [@var{type}] Like @code{vec}, but it unpacks to and packs from lists, whereas @code{vec} unpacks to vectors. @item bits @var{len} -List of set bits in @var{len} bytes. The bytes are taken in big -endian order and the bits are numbered starting with @code{8 * -@var{len} @minus{} 1} and ending with zero. For example: @code{bits -2} unpacks @code{#x28} @code{#x1c} to @code{(2 3 4 11 13)} and -@code{#x1c} @code{#x28} to @code{(3 5 10 11 12)}. +List of bits that are set to 1 in @var{len} bytes. The bytes are +taken in big-endian order, and the bits are numbered starting with +@code{8 * @var{len} @minus{} 1} and ending with zero. For example: +@code{bits 2} unpacks @code{#x28} @code{#x1c} to @code{(2 3 4 11 13)} +and @code{#x1c} @code{#x28} to @code{(3 5 10 11 12)}. @item fill @var{len} @var{len} bytes used as a mere filler. In packing, these bytes are @@ -3466,9 +3473,10 @@ the size of a subsequent vector of 16 bit integers could be: @node Bindat Functions @subsection Functions to Unpack and Pack Bytes +@cindex bindat functions In the following documentation, @var{type} refers to a Bindat type -value as returned from @code{bindat-type}, @code{raw} to a byte +value as returned from @code{bindat-type}, @var{raw} to a byte array, and @var{struct} to an alist representing unpacked field data. @defun bindat-unpack type raw &optional idx @@ -3487,12 +3495,13 @@ This function selects a field's data from the nested alist @var{struct}. Usually @var{struct} was returned by @code{bindat-unpack}. If @var{name} corresponds to just one argument, that means to extract a top-level field value. Multiple @var{name} -arguments specify repeated lookup of sub-structures. An integer name -acts as an array index. +arguments specify repeated lookup of sub-structures. An integer +@var{name} acts as an array index. -For example, if @var{name} is @code{(a b 2 c)}, that means to find -field @code{c} in the third element of subfield @code{b} of field -@code{a}. (This corresponds to @code{struct.a.b[2].c} in C.) +For example, @w{@code{(bindat-get-field @var{struct} a b 2 c)}} means +to find field @code{c} in the third element of subfield @code{b} of +field @code{a}. (This corresponds to @code{@var{struct}.a.b[2].c} in +the C programming language syntax.) @end defun Although packing and unpacking operations change the organization of @@ -3533,11 +3542,12 @@ dotted notation. @node Bindat Computed Types @subsection Advanced data layout specifications +@cindex bindat computed types Bindat type expressions are not limited to the types described earlier. They can also be arbitrary Lisp forms returning Bindat type expressions. For example, the type below describes data which -can either contain a 24bit error code or a vector of bytes: +can either contain a 24-bit error code or a vector of bytes: @example (bindat-type @@ -3545,13 +3555,14 @@ can either contain a 24bit error code or a vector of bytes: (payload . (if (zerop len) (uint 24) (vec (1- len))))) @end example +@cindex bindat packing and unpacking into arbitrary types Furthermore, while composite types are normally unpacked to (and packed from) association lists, this can be changed via the use of the following special keyword arguments: @table @code @item :unpack-val @var{exp} -When the list of fields end with this keyword argument, then the value +When the list of fields ends with this keyword argument, then the value returned when unpacking is the value of @var{exp} instead of the standard alist. @var{exp} can refer to all the previous fields by their name. @@ -3568,7 +3579,7 @@ value to pack into this composite type via the variable named @var{name}. @end table -For example, one could describe a 16 bit signed integer as follows: +For example, one could describe a 16-bit signed integer as follows: @example (defconst sint16-bindat-spec @@ -3588,6 +3599,8 @@ Which would then behave as follows: @result{} -16320 @end example +@cindex define new bindat type forms +@cindex bindat, define new type forms Finally, you can define new Bindat type forms to use in Bindat type expressions with @code{bindat-defmacro}: diff --git a/etc/NEWS b/etc/NEWS index 15df9cdcda..6b4456e3de 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -399,7 +399,8 @@ in text mode. The cursor still only actually blinks in GUI frames. *** New 'Bindat type expression' description language. This new system is provided by the new macro 'bindat-type' and obsoletes the old data layout specifications. It supports -arbitrary-size integers, recursive types, and more. +arbitrary-size integers, recursive types, and more. See the Info node +'Byte Packing' in the ELisp manual for more details. ** pcase commit 8fb33bae32e39f597317eb4857447bb0ea1a4de3 Author: Protesilaos Stavrou Date: Fri Mar 5 18:31:08 2021 +0000 Pull Modus themes version 1.2.3 from upstream This syncs with the following upstream revision: Update to version 1.2.3 0a36239 2021-03-05 19:43:30 +0200 https://gitlab.com/protesilaos/modus-themes/-/commit/0a36239baf908585cdf32c6188eb86713d9bf6c6 For discussion, see bug#45068 and the following upstream issue: https://gitlab.com/protesilaos/modus-themes/-/issues/162 * doc/misc/modus-themes.org: * etc/themes/modus-operandi-theme.el: * etc/themes/modus-themes.el: * etc/themes/modus-vivendi-theme.el: Update to version 1.2.3. diff --git a/doc/misc/modus-themes.org b/doc/misc/modus-themes.org index 20d7767053..ed464e8465 100644 --- a/doc/misc/modus-themes.org +++ b/doc/misc/modus-themes.org @@ -4,8 +4,8 @@ #+language: en #+options: ':t toc:nil author:t email:t -#+macro: stable-version 1.2.0 -#+macro: release-date 2021-03-04 +#+macro: stable-version 1.2.3 +#+macro: release-date 2021-03-05 #+macro: development-version 1.3.0-dev #+macro: export-date (eval (format-time-string "%F %R %z" (current-time))) #+macro: file @@texinfo:@file{@@$1@@texinfo:}@@ @@ -35,8 +35,8 @@ The documentation furnished herein corresponds to stable version feature which does not yet form part of the latest tagged commit, is explicitly marked as such. -# Current development target is {{{development-version}}}. This manual was -# built on {{{export-date}}}. +Current development target is {{{development-version}}}. This manual was +built on {{{export-date}}}. #+toc: headlines 8 insert TOC here, with eight headline levels diff --git a/etc/themes/modus-operandi-theme.el b/etc/themes/modus-operandi-theme.el index ce2c75e9a8..64763a1682 100644 --- a/etc/themes/modus-operandi-theme.el +++ b/etc/themes/modus-operandi-theme.el @@ -4,7 +4,7 @@ ;; Author: Protesilaos Stavrou ;; URL: https://gitlab.com/protesilaos/modus-themes -;; Version: 1.2.0 +;; Version: 1.2.3 ;; Package-Requires: ((emacs "26.1")) ;; Keywords: faces, theme, accessibility @@ -50,7 +50,10 @@ -(require-theme 'modus-themes) +(eval-and-compile + (unless (and (fboundp 'require-theme) + (require-theme 'modus-themes t)) + (require 'modus-themes))) (deftheme modus-operandi "Accessible and customizable light theme (WCAG AAA standard). diff --git a/etc/themes/modus-themes.el b/etc/themes/modus-themes.el index 79846dbf3a..c315d5971b 100644 --- a/etc/themes/modus-themes.el +++ b/etc/themes/modus-themes.el @@ -4,7 +4,7 @@ ;; Author: Protesilaos Stavrou ;; URL: https://gitlab.com/protesilaos/modus-themes -;; Version: 1.2.0 +;; Version: 1.2.3 ;; Package-Requires: ((emacs "26.1")) ;; Keywords: faces, theme, accessibility @@ -3616,7 +3616,7 @@ by virtue of calling either of `modus-themes-load-operandi' and ;;;;; dictionary `(dictionary-button-face ((,class :inherit bold :foreground ,fg-special-cold))) `(dictionary-reference-face ((,class :inherit button))) - `(dictionary-word-definition-face ((,class))) + `(dictionary-word-definition-face (())) `(dictionary-word-entry-face ((,class :inherit font-lock-comment-face))) ;;;;; diff-hl `(diff-hl-change ((,class :inherit modus-theme-fringe-yellow))) @@ -3918,8 +3918,8 @@ by virtue of calling either of `modus-themes-load-operandi' and `(epa-field-name ((,class :inherit bold :foreground ,fg-dim))) `(epa-mark ((,class :inherit bold :foreground ,magenta))) `(epa-string ((,class :foreground ,blue-alt))) - `(epa-validity-disabled ((,class :inherit modus-theme-refine-red))) - `(epa-validity-high ((,class :inherit bold :foreground ,green-alt-other))) + `(epa-validity-disabled ((,class :foreground ,red))) + `(epa-validity-high ((,class :inherit bold :foreground ,cyan))) `(epa-validity-low ((,class :inherit shadow))) `(epa-validity-medium ((,class :foreground ,green-alt))) ;;;;; equake @@ -5378,7 +5378,7 @@ by virtue of calling either of `modus-themes-load-operandi' and `(org-done ((,class :foreground ,green))) `(org-drawer ((,class ,@(modus-themes--mixed-fonts) :foreground ,fg-alt))) - `(org-ellipsis ((,class))) ; inherits from the heading's color + `(org-ellipsis (())) ; inherits from the heading's color `(org-footnote ((,class :inherit button ,@(modus-themes--link-color blue-alt blue-alt-faint)))) @@ -5811,7 +5811,7 @@ by virtue of calling either of `modus-themes-load-operandi' and `(sh-quoted-exec ((,class :inherit modus-theme-bold :foreground ,magenta-alt))) ;;;;; shortdoc `(shortdoc-heading ((,class :inherit modus-theme-pseudo-header))) - `(shortdoc-section ((,class))) ; remove the default's variable-pitch style + `(shortdoc-section (())) ; remove the default's variable-pitch style ;;;;; show-paren-mode `(show-paren-match ((,class ,@(modus-themes--paren bg-paren-match bg-paren-match-intense) @@ -5875,7 +5875,7 @@ by virtue of calling either of `modus-themes-load-operandi' and `(smerge-lower ((,class :inherit modus-theme-diff-added))) `(smerge-markers ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-2))) `(smerge-refined-added ((,class :inherit modus-theme-diff-refine-added))) - `(smerge-refined-changed ((,class))) + `(smerge-refined-changed (())) `(smerge-refined-removed ((,class :inherit modus-theme-diff-refine-removed))) `(smerge-upper ((,class :inherit modus-theme-diff-removed))) ;;;;; solaire @@ -6432,5 +6432,11 @@ by virtue of calling either of `modus-themes-load-operandi' and `(org-src-block-faces '()))) "Custom variables for `modus-themes-theme'.") +;;;###autoload +(when load-file-name + (let ((dir (file-name-directory load-file-name))) + (unless (equal dir (expand-file-name "themes/" data-directory)) + (add-to-list 'custom-theme-load-path dir)))) + (provide 'modus-themes) ;;; modus-themes.el ends here diff --git a/etc/themes/modus-vivendi-theme.el b/etc/themes/modus-vivendi-theme.el index fd7f5df24d..814f10d105 100644 --- a/etc/themes/modus-vivendi-theme.el +++ b/etc/themes/modus-vivendi-theme.el @@ -4,7 +4,7 @@ ;; Author: Protesilaos Stavrou ;; URL: https://gitlab.com/protesilaos/modus-themes -;; Version: 1.2.0 +;; Version: 1.2.3 ;; Package-Requires: ((emacs "26.1")) ;; Keywords: faces, theme, accessibility @@ -50,7 +50,10 @@ -(require-theme 'modus-themes) +(eval-and-compile + (unless (and (fboundp 'require-theme) + (require-theme 'modus-themes t)) + (require 'modus-themes))) (deftheme modus-vivendi "Accessible and customizable dark theme (WCAG AAA standard). commit de602dd7cf76b001244964aa5bbef4d9e08ea62b Author: Protesilaos Stavrou Date: Thu Mar 4 16:20:15 2021 +0200 Update Modus themes to their version 1.2.0 * doc/misc/modus-themes.org: Add new version of the manual, with changes to markup and references to the latest state of the project. * etc/themes/modus-vivendi-theme.el: * etc/themes/modus-operandi-theme.el: Provide updated version of each theme, which expands the contents of 'modus-themes.el' (bug#45068). * etc/themes/modus-themes.el: Add new supportive file. This is where theme data, functions, and face definitions are defined. diff --git a/doc/misc/modus-themes.org b/doc/misc/modus-themes.org index 4a6150cf9d..20d7767053 100644 --- a/doc/misc/modus-themes.org +++ b/doc/misc/modus-themes.org @@ -1,30 +1,52 @@ -#+TITLE: Modus themes for GNU Emacs -#+AUTHOR: Protesilaos Stavrou -#+EMAIL: info@protesilaos.com -#+TEXINFO_DIR_CATEGORY: Emacs misc features -#+TEXINFO_DIR_TITLE: Modus Themes: (modus-themes) -#+TEXINFO_DIR_DESC: Highly accessible themes (WCAG AAA) -#+OPTIONS: ':t toc:nil author:t email:t -#+MACRO: version-tag 0.13.0 -#+MACRO: release-date 2020-10-08 +#+title: Modus themes for GNU Emacs +#+author: Protesilaos Stavrou +#+email: info@protesilaos.com +#+language: en +#+options: ':t toc:nil author:t email:t + +#+macro: stable-version 1.2.0 +#+macro: release-date 2021-03-04 +#+macro: development-version 1.3.0-dev +#+macro: export-date (eval (format-time-string "%F %R %z" (current-time))) +#+macro: file @@texinfo:@file{@@$1@@texinfo:}@@ +#+macro: space @@texinfo:@: @@ +# The "kbd" macro turns KBD into @kbd{KBD}. Additionally, it +# encloses case-sensitive special keys (SPC, RET...) within @key{...}. +# I got this from the Org source code. +#+macro: kbd (eval (let ((case-fold-search nil) (regexp (regexp-opt '("SPC" "RET" "LFD" "TAB" "BS" "ESC" "DELETE" "SHIFT" "Ctrl" "Meta" "Alt" "Cmd" "Super" "UP" "LEFT" "RIGHT" "DOWN") 'words))) (format "@@texinfo:@kbd{@@%s@@texinfo:}@@" (replace-regexp-in-string regexp "@@texinfo:@key{@@\\&@@texinfo:}@@" $1 t)))) + +#+texinfo_filename: modus-themes.info +#+texinfo_dir_category: Emacs misc features +#+texinfo_dir_title: Modus Themes: (modus-themes) +#+texinfo_dir_desc: Highly accessible themes (WCAG AAA) +#+texinfo_header: @set MAINTAINERSITE @uref{https://protesilaos.com,maintainer webpage} +#+texinfo_header: @set MAINTAINER Protesilaos Stavrou +#+texinfo_header: @set MAINTAINEREMAIL @email{info@protesilaos.com} +#+texinfo_header: @set MAINTAINERCONTACT @uref{mailto:info@protesilaos.com,contact the maintainer} #+texinfo: @insertcopying This manual, written by Protesilaos Stavrou, describes the customization -options for the =modus-operandi= and =modus-vivendi= themes, and provides +options for the ~modus-operandi~ and ~modus-vivendi~ themes, and provides every other piece of information pertinent to them. -The documentation furnished herein corresponds to version {{{version-tag}}}, -released on {{{release-date}}}. Any reference to a newer feature which does -not yet form part of the latest tagged commit, is explicitly marked as -such. +The documentation furnished herein corresponds to stable version +{{{stable-version}}}, released on {{{release-date}}}. Any reference to a newer +feature which does not yet form part of the latest tagged commit, is +explicitly marked as such. -* Copying -:PROPERTIES: -:copying: t -:END: +# Current development target is {{{development-version}}}. This manual was +# built on {{{export-date}}}. -Copyright (C) 2020--2021 Free Software Foundation, Inc. +#+toc: headlines 8 insert TOC here, with eight headline levels + +* COPYING +:properties: +:copying: t +:custom_id: h:b14c3fcb-13dd-4144-9d92-2c58b3ed16d3 +:end: + +Copyright (C) 2020-2021 Free Software Foundation, Inc. #+begin_quote Permission is granted to copy, distribute and/or modify this @@ -34,12 +56,10 @@ Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. #+end_quote -#+TOC: headlines 8 insert TOC here, with eight headline levels - * Overview -:PROPERTIES: -:CUSTOM_ID: h:f0f3dbcb-602d-40cf-b918-8f929c441baf -:END: +:properties: +:custom_id: h:f0f3dbcb-602d-40cf-b918-8f929c441baf +:end: The Modus themes are designed for accessible readability. They conform with the highest standard for color contrast between any given @@ -47,9 +67,9 @@ combination of background and foreground values. This corresponds to the WCAG AAA standard, which specifies a minimum rate of distance in relative luminance of 7:1. -Modus Operandi (=modus-operandi=) is a light theme, while Modus Vivendi -(=modus-vivendi=) is dark. Each theme's color palette is designed to -meet the needs of the numerous interfaces that are possible in the Emacs +Modus Operandi (~modus-operandi~) is a light theme, while Modus Vivendi +(~modus-vivendi~) is dark. Each theme's color palette is designed to meet +the needs of the numerous interfaces that are possible in the Emacs computing environment. The overarching objective of this project is to always offer accessible @@ -59,15 +79,16 @@ and stylistic considerations, we will always opt for the former. To ensure that users have a consistently accessible experience, the themes strive to achieve as close to full face coverage as possible -(see [[#h:a9c8f29d-7f72-4b54-b74b-ddefe15d6a19][Face coverage]]). +([[#h:a9c8f29d-7f72-4b54-b74b-ddefe15d6a19][Face coverage]]). Starting with version 0.12.0 and onwards, the themes are built into GNU -Emacs (current version is {{{version-tag}}}). +Emacs. ** How do the themes look like -:PROPERTIES: -:CUSTOM_ID: h:69b92089-069c-4ba1-9d94-cc3415fc4f87 -:END: +:properties: +:custom_id: h:69b92089-069c-4ba1-9d94-cc3415fc4f87 +:end: +#+cindex: Screenshots Check the web page with [[https://protesilaos.com/modus-themes-pictures/][the screen shots]]. There are lots of scenarios on display that draw attention to details and important aspects in the @@ -77,596 +98,562 @@ options. [[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization options]]. ** Learn about the latest changes -:PROPERTIES: -:CUSTOM_ID: h:2cc37c36-6c1a-48b2-a010-1050b270ee18 -:END: +:properties: +:custom_id: h:2cc37c36-6c1a-48b2-a010-1050b270ee18 +:end: +#+cindex: Changelog Please refer to the [[https://protesilaos.com/modus-themes-changelog][web page with the change log]]. It is comprehensive and covers everything that goes into every tagged release of the themes. * Installation -:PROPERTIES: -:CUSTOM_ID: h:1af85373-7f81-4c35-af25-afcef490c111 -:END: +:properties: +:custom_id: h:1af85373-7f81-4c35-af25-afcef490c111 +:end: The Modus themes are distributed with Emacs starting with version 28.1. On older versions of Emacs, they can be installed using Emacs' package -manager or manually from their code repository. +manager or manually from their code repository. There also exist +packages for distributions of GNU/Linux. + +** Install manually from source +:properties: +:custom_id: h:da3414b7-1426-46b8-8e76-47b845b76fd0 +:end: + +In the following example, we are assuming that your Emacs files are +stored in =~/.emacs.d= and that you want to place the Modus themes in +=~/.emacs.d/modus-themes=. + +1. Get the source and store it in the desired path by running the + following in the command line shell: + +: $ git clone https://gitlab.com/protesilaos/modus-themes.git ~/.emacs.d/modus-themes + +2. Add that path to your known Elisp libraries' list, by placing this + snippet of Emacs Lisp in your init file (e.g. {{{file(init.el)}}}): + +#+begin_src emacs-lisp +(add-to-list 'load-path "~/.emacs.d/modus-themes") +#+end_src -Modus Operandi (light theme) and Modus Vivendi (dark) are normally -distributed as standalone packages in Emacs-specific archives. There -also exist packages for GNU/Linux distributions. +The themes are now ready to be used: [[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]]. ** Install from the archives -:PROPERTIES: -:CUSTOM_ID: h:c4b10085-149f-43e2-bd4d-347f33aee054 -:END: +:properties: +:custom_id: h:c4b10085-149f-43e2-bd4d-347f33aee054 +:end: -=modus-operandi-theme= and =modus-vivendi-theme= are available from GNU the -ELPA archive, which is configured by default. +The =modus-themes= package is available from the GNU ELPA archive, which +is configured by default. Prior to querying any package archive, make sure to have updated the -index, with =M-x package-refresh-contents=. Then all you need to do is -type =M-x package-install= and specify the theme of your choice. +index, with {{{kbd(M-x package-refresh-contents)}}}. Then all you need to do +is type {{{kbd(M-x package-install)}}} and specify the ~modus-themes~. + +Note that older versions of the themes used to be distributed as +standalone packages. This practice has been discontinued starting with +version 1.0.0 of this project. + +Once installed, the themes are ready to be used: [[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]]. ** Install on GNU/Linux -:PROPERTIES: -:CUSTOM_ID: h:da640eb1-95dd-4e86-bb4e-1027b27885f0 -:END: +:properties: +:custom_id: h:da640eb1-95dd-4e86-bb4e-1027b27885f0 +:end: -The themes are also available from the archives of some GNU/Linux -distributions. These should correspond to a tagged release rather than +The themes are also available from the archives of some distributions of +GNU/Linux. These should correspond to a tagged release rather than building directly from the latest Git commit. It all depends on the distro's packaging policies. *** Debian 11 Bullseye -:PROPERTIES: -:CUSTOM_ID: h:7e570360-9ee6-4bc5-8c04-9dc11418a3e4 -:END: - -The two themes are distributed as a single package for Debian and its -derivatives. Currently in the unstable and testing suites and should be -available in time for Debian 11 Bullseye (next stable). +:properties: +:custom_id: h:7e570360-9ee6-4bc5-8c04-9dc11418a3e4 +:end: -Get them with: +The themes are part of Debian 11 Bullseye. Get them with: #+begin_src sh sudo apt install elpa-modus-themes #+end_src +They are now ready to be used: [[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]]. + *** GNU Guix -:PROPERTIES: -:CUSTOM_ID: h:a4ca52cd-869f-46a5-9e16-4d9665f5b88e -:END: +:properties: +:custom_id: h:a4ca52cd-869f-46a5-9e16-4d9665f5b88e +:end: -Users of either the Guix System (the distro) or just Guix (the package -manager) can get each theme as a standalone package. +Users of Guix can get the themes with this command: #+begin_src sh -guix package -i emacs-modus-operandi-theme +guix package -i emacs-modus-themes #+end_src -And/or: - -#+begin_src sh -guix package -i emacs-modus-vivendi-theme -#+end_src +They are now ready to be used: [[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]]. * Enable and load -:PROPERTIES: -:CUSTOM_ID: h:3f3c3728-1b34-437d-9d0c-b110f5b161a9 -:END: - -This section documents how to load the theme of your choice and how to -further control its initialization. It also includes some sample code -snippets that could help you in the task, especially if you intend to -use both Modus Operandi and Modus Vivendi. +:properties: +:custom_id: h:3f3c3728-1b34-437d-9d0c-b110f5b161a9 +:end: +#+findex: modus-themes-load-themes +#+findex: modus-themes-toggle +#+findex: modus-themes-load-operandi +#+findex: modus-themes-load-vivendi +#+cindex: Essential configuration +#+vindex: modus-themes-after-load-theme-hook + +Users of the built-in themes can load and automatically enable the theme +of their preference by adding either form to their init file: -** Load automatically -:PROPERTIES: -:CUSTOM_ID: h:1777c247-1b56-46b7-a4ce-54e720b33d06 -:END: +#+begin_src emacs-lisp +(load-theme 'modus-operandi) ; Light theme +(load-theme 'modus-vivendi) ; Dark theme +#+end_src -A simple way to load the theme from your Emacs initialization file is to -include either of the following expressions: +This is all one needs. -#+BEGIN_SRC emacs-lisp -(load-theme 'modus-operandi t) ; Light theme -(load-theme 'modus-vivendi t) ; Dark theme -#+END_SRC +Users of packaged variants of the themes must add a few more lines to +ensure that everything works as intended. First, one has to require the +main library before loading either theme: -Make sure to remove any other theme that is being loaded, otherwise you -might run into unexpected issues. +#+begin_src emacs-lisp +(require 'modus-themes) +#+end_src -Note that you can always =M-x disable-theme= and specify an item. The -command does exactly what its name suggests. To deactivate all enabled -themes at once, in case you have multiple of them enabled, you may -evaluate the expression: +Then it is recommended to load the individual theme files with the +helper function ~modus-themes-load-themes~: #+begin_src emacs-lisp -(mapc #'disable-theme custom-enabled-themes) +;; Load the theme files before enabling a theme (else you get an error). +(modus-themes-load-themes) #+end_src -** Load at a given time or at sunset/sunrise -:PROPERTIES: -:CUSTOM_ID: h:4e936e31-e9eb-4b50-8fdd-45d827a03cca -:END: - -It is possible to schedule a time during the day at or after which a -given theme will be loaded.[fn:: Contributed on Reddit by user =b3n=, -https://www.reddit.com/r/emacs/comments/gdtqov/weekly_tipstricketc_thread/fq9186h/.] +Once the libraries that define the themes are enabled, one can activate +a theme with either of the following expressions: #+begin_src emacs-lisp -;; Light for the day -(load-theme 'modus-operandi t t) -(run-at-time "05:00" (* 60 60 24) - (lambda () - (enable-theme 'modus-operandi))) - -;; Dark for the night -(load-theme 'modus-vivendi t t) -(run-at-time "21:00" (* 60 60 24) - (lambda () - (enable-theme 'modus-vivendi))) +(modus-themes-load-operandi) ; Light theme +;; OR +(modus-themes-load-vivendi) ; Dark theme #+end_src -A modified version of the above technique is to use the sunrise and -sunset as references, instead of specifying a fixed hour value.[fn:: -Contributed directly by André Alexandre Gomes https://gitlab.com/aadcg.] -If you set =calendar-latitude= and =calendar-longitude= (defined in the -built-in =solar.el= library---read it with =M-x find-library=), you can -automatically switch between both themes at the appropriate time-of-day. -Note that /those calendar variables need to be set before loading the -themes/. +Changes to the available customization options must always be evaluated +before loading a theme ([[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization Options]]). This is how a basic +setup could look like: #+begin_src emacs-lisp -;; Define coordinates -(setq calendar-latitude 35.17 - calendar-longitude 33.36) +(require 'modus-themes) -;; Light at sunrise -(load-theme 'modus-operandi t t) -(run-at-time (nth 1 (split-string (sunrise-sunset))) - (* 60 60 24) - (lambda () - (enable-theme 'modus-operandi))) +;; Your customisations here. For example: +(setq modus-themes-bold-constructs t + modus-themes-mode-line '3d) -;; Dark at sunset -(load-theme 'modus-vivendi t t) -(run-at-time (nth 4 (split-string (sunrise-sunset))) - (* 60 60 24) - (lambda () - (enable-theme 'modus-vivendi))) -#+end_src +;; Load the theme files before enabling a theme (else you get an error). +(modus-themes-load-themes) -For the sake of completeness, the =load-theme= call in these snippets is -slightly different than the one shown in [[#h:1777c247-1b56-46b7-a4ce-54e720b33d06][Load automatically]], because it -does not enable the theme directly: the subsequent =enable-theme= does -that when needed. +;; Enable the theme of your preference: +(modus-themes-load-operandi) -** Toggle between the themes on demand -:PROPERTIES: -:CUSTOM_ID: h:2a0895a6-3281-4e55-8aa1-8a737555821e -:END: +;; Optionally add a key binding for the toggle between the themes: +(define-key global-map (kbd "") #'modus-themes-toggle) +#+end_src -With both themes available, it is possible to design a simple command to -switch between them on demand. +[[#h:e979734c-a9e1-4373-9365-0f2cd36107b8][Sample configuration for use-package]]. -#+begin_src emacs-lisp -(defun modus-themes-toggle () - "Toggle between `modus-operandi' and `modus-vivendi' themes." - (interactive) - (if (eq (car custom-enabled-themes) 'modus-operandi) - (progn - (disable-theme 'modus-operandi) - (load-theme 'modus-vivendi t)) - (disable-theme 'modus-vivendi) - (load-theme 'modus-operandi t))) -#+end_src +With those granted, bear in mind a couple of technical points on +~modus-themes-load-operandi~ and ~modus-themes-load-vivendi~, as well as +~modus-themes-toggle~ which relies on them: -You could use =(mapc #'disable-theme custom-enabled-themes)= instead of -disabling a single target, but you get the idea. +1. Those functions call ~load-theme~. Some users prefer to opt for + ~enable-theme~ instead ([[#h:e68560b3-7fb0-42bc-a151-e015948f8a35][Differences between loading and enabling]]). -** Configure options prior to loading -:PROPERTIES: -:CUSTOM_ID: h:a897b302-8e10-4a26-beab-3caaee1e1193 -:END: +2. The functions will run the ~modus-themes-after-load-theme-hook~ as + their final step. This can be employed for bespoke configurations + ([[#h:f4651d55-8c07-46aa-b52b-bed1e53463bb][Advanced customization (do-it-yourself)]]). Experienced users may not + wish to rely on such a hook and the functions that run it: they may + prefer a custom solution ([[#h:86f6906b-f090-46cc-9816-1fe8aeb38776][A theme-agnostic hook for theme loading]]). -If you plan to use both themes and wish to apply styles consistently -(see [[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization Options]]), you could define wrapper functions around -the standard =load-theme= command. These extend the simple function we -presented in [[#h:2a0895a6-3281-4e55-8aa1-8a737555821e][Toggle between the themes on demand]]. +** Sample configuration for use-package +:properties: +:custom_id: h:e979734c-a9e1-4373-9365-0f2cd36107b8 +:end: +#+cindex: use-package configuration -Here is a comprehensive setup (the values assigned to the variables are -just for the sake of this demonstration):[fn:: The =defmacro= and =dolist= -method were contributed on Reddit by user =b3n= -https://www.reddit.com/r/emacs/comments/gqsz8u/weekly_tipstricketc_thread/fsfakhg/.] +It is common for Emacs users to rely on ~use-package~ for declaring +package configurations in their setup. We use this as an example: #+begin_src emacs-lisp -(defmacro modus-themes-format-sexp (sexp &rest objects) - `(eval (read (format ,(format "%S" sexp) ,@objects)))) - -(dolist (theme '("operandi" "vivendi")) - (modus-themes-format-sexp - (defun modus-%1$s-theme-load () - (setq modus-%1$s-theme-slanted-constructs t - modus-%1$s-theme-bold-constructs t - modus-%1$s-theme-fringes 'subtle ; {nil,'subtle,'intense} - modus-%1$s-theme-mode-line '3d ; {nil,'3d,'moody} - modus-%1$s-theme-syntax 'alt-syntax ; {nil,faint,'yellow-comments,'green-strings,'yellow-comments-green-strings,'alt-syntax,'alt-syntax-yellow-comments} - modus-%1$s-theme-intense-hl-line nil - modus-%1$s-theme-intense-paren-match nil - modus-%1$s-theme-links 'faint ; {nil,'faint,'neutral-underline,'faint-neutral-underline,'no-underline} - modus-%1$s-theme-no-mixed-fonts nil - modus-%1$s-theme-prompts nil ; {nil,'subtle,'intense} - modus-%1$s-theme-completions 'moderate ; {nil,'moderate,'opinionated} - modus-%1$s-theme-diffs nil ; {nil,'desaturated,'fg-only} - modus-%1$s-theme-org-blocks 'grayscale ; {nil,'grayscale,'rainbow} - modus-%1$s-theme-headings ; Read further below in the manual for this one - '((1 . section) - (2 . line) - (t . rainbow-line-no-bold)) - modus-%1$s-theme-variable-pitch-headings nil - modus-%1$s-theme-scale-headings t - modus-%1$s-theme-scale-1 1.1 - modus-%1$s-theme-scale-2 1.15 - modus-%1$s-theme-scale-3 1.21 - modus-%1$s-theme-scale-4 1.27 - modus-%1$s-theme-scale-5 1.33) - (load-theme 'modus-%1$s t)) - theme)) - -(defun modus-themes-toggle () - "Toggle between `modus-operandi' and `modus-vivendi' themes." - (interactive) - (if (eq (car custom-enabled-themes) 'modus-operandi) - (progn - (disable-theme 'modus-operandi) - (modus-vivendi-theme-load)) - (disable-theme 'modus-vivendi) - (modus-operandi-theme-load))) +(use-package modus-themes + :ensure ; omit this to use the built-in themes + :init + ;; Add all your customizations prior to loading the themes + (setq modus-themes-slanted-constructs t + modus-themes-bold-constructs nil) + + ;; Load the theme files before enabling a theme (else you get an error). + (modus-themes-load-themes) + :config + ;; Load the theme of your choice: + (modus-themes-load-operandi) ;; OR (modus-themes-load-vivendi) + :bind ("" . modus-themes-toggle)) #+end_src -* Customization Options -:PROPERTIES: -:CUSTOM_ID: h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f -:END: - -The Modus themes are highly configurable, though they should work well -without any further tweaks. - -By default, all customization options are set to =nil=. - -All customization options need to be evaluated before loading their -theme (see [[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]]). +[[#h:e68560b3-7fb0-42bc-a151-e015948f8a35][Differences between loading and enabling]]. + +Note: make sure not to customize the variable ~custom-theme-load-path~ +or ~custom-theme-directory~ after the themes' package declaration. That +will lead to failures in loading the files. If either or both of those +variables need to be changed, their values should be defined before the +package declaration of the themes. + +** Differences between loading and enabling +:properties: +:custom_id: h:e68560b3-7fb0-42bc-a151-e015948f8a35 +:end: +#+cindex: load-theme VS enable-theme + +The reason we recommend ~load-theme~ instead of the other option of +~enable-theme~ is that the former does a kind of "reset" on the face +specs. It quite literally loads (or re-loads) the theme. Whereas the +latter simply puts an already loaded theme at the top of the list of +enabled items, re-using whatever state was last loaded. + +As such, ~load-theme~ reads all customizations that may happen during +any given Emacs session: even after the initial setup of a theme. +Examples are calls to ~custom-set-faces~, as well as new values assigned +to the options the Modus themes provide ([[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization Options]]). + +Our tests show that ~enable-theme~ does not read such variables anew, so +it might appear to the unsuspecting user that the themes are somehow +broken whenever they try to assign a new value to a customization option +or some face. + +This "reset" that ~load-theme~ conducts does, however, come at the cost +of being somewhat slower than ~enable-theme~. Users who have a stable +setup and who seldom update their variables during a given Emacs +session, are better off using something like this: -** Option for more bold constructs -:PROPERTIES: -:ALT_TITLE: Bold constructs -:DESCRIPTION: Toggle bold constructs in code -:CUSTOM_ID: h:b25714f6-0fbe-41f6-89b5-6912d304091e -:END: - -Symbol names: - -+ =modus-operandi-theme-bold-constructs= -+ =modus-vivendi-theme-bold-constructs= +#+begin_src emacs-lisp +(require 'modus-themes) +(load-theme 'modus-operandi t t) +(load-theme 'modus-vivendi t t) -Possible values: +(enable-theme 'modus-operandi) ;; OR (enable-theme 'modus-vivendi) +#+end_src -1. =nil= (default) -2. =t= +[[#h:e979734c-a9e1-4373-9365-0f2cd36107b8][Sample configuration for use-package]]. -Display several constructs in bold weight. This concerns keywords and -other important aspects of code syntax. It also affects certain mode -line indicators and command-line prompts. +With the above granted, other sections of the manual discuss how to +configure custom faces, where ~load-theme~ is expected, though +~enable-theme~ could still apply in stable setups: -The default is to only use a bold weight when it is required. +[[#h:1487c631-f4fe-490d-8d58-d72ffa3bd474][Case-by-case face specs using the themes' palette]]. -Additionally, and while not necessary, to define the precise weight for -bold constructs, you can change the typographic intensity of the =bold= -face. The standard is a bold weight. It requires no further -intervention. Assuming though that your typeface of choice supports a -"semibold" weight, adding the following snippet to your init file should -suffice. +[[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]]. -#+begin_src emacs-lisp -(set-face-attribute 'bold nil :weight 'semibold) -#+end_src +* Customization Options +:properties: +:custom_id: h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f +:end: -Note that if you are switching themes, you need to re-evaluate this -expression after the new theme is loaded. +The Modus themes are highly configurable, though they should work well +without any further tweaks. By default, all customization options are +set to nil. -** Option for more slanted constructs -:PROPERTIES: -:ALT_TITLE: Slanted constructs -:DESCRIPTION: Toggle slanted constructs (italics) in code -:CUSTOM_ID: h:977c900d-0d6d-4dbb-82d9-c2aae69543d6 -:END: +Remember that all customization options must be evaluated before loading +a theme ([[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]]). -Symbol names: +** Option for more bold constructs +:properties: +:alt_title: Bold constructs +:description: Toggle bold constructs in code +:custom_id: h:b25714f6-0fbe-41f6-89b5-6912d304091e +:end: +#+vindex: modus-themes-bold-constructs -+ =modus-operandi-theme-slanted-constructs= -+ =modus-vivendi-theme-slanted-constructs= +Symbol: ~modus-themes-bold-constructs~ Possible values: 1. =nil= (default) 2. =t= -Choose to render more faces in slanted text (italics). This typically -affects documentation strings and code comments. - -The default is to not use italics unless it is absolutely necessary. +The default is to use a bold typographic weight only when it is +required. -** Option for faint code syntax highlighting (deprecated for ~0.14.0~) -:PROPERTIES: -:ALT_TITLE: Faint syntax -:DESCRIPTION: Toggle subtle coloration in code (deprecated for 0.14.0) -:CUSTOM_ID: h:741379fe-7203-4dad-a7f8-ab71f61b43e6 -:END: +With a non-nil value (=t=) display several syntactic constructs in bold +weight. This concerns keywords and other important aspects of code +syntax. It also affects certain mode line indicators and command-line +prompts. -Symbol names: +** Option for more slanted constructs +:properties: +:alt_title: Slanted constructs +:description: Toggle slanted constructs (italics) in code +:custom_id: h:977c900d-0d6d-4dbb-82d9-c2aae69543d6 +:end: +#+vindex: modus-themes-slanted-constructs -+ =modus-operandi-theme-faint-syntax= -+ =modus-vivendi-theme-faint-syntax= +Symbol: ~modus-themes-slanted-constructs~ Possible values: 1. =nil= (default) 2. =t= -Use less saturated colors in programming modes for highlighting code -syntax. The default is to use saturated colors. +The default is to not use slanted text (italics) unless it is absolutely +necessary. -This option essentially affects the font-lock faces, so it may also have -implications in other places that are hard-wired to rely directly on -them instead of specifying their own faces (which could inherit from -font-lock if that is the intent). The author is aware of =vc-dir= as a -case in point. +With a non-nil value (=t=) choose to render more faces in slanted text. +This typically affects documentation strings and code comments. ** Option for syntax highlighting -:PROPERTIES: -:ALT_TITLE: Syntax styles -:DESCRIPTION: Choose the overall aesthetic of code syntax -:CUSTOM_ID: h:c119d7b2-fcd4-4e44-890e-5e25733d5e52 -:END: - -This option supersedes the "faint syntax" one ahead of version =0.14.0= -([[#h:741379fe-7203-4dad-a7f8-ab71f61b43e6][Option for faint code syntax highlighting]]). +:properties: +:alt_title: Syntax styles +:description: Choose the overall aesthetic of code syntax +:custom_id: h:c119d7b2-fcd4-4e44-890e-5e25733d5e52 +:end: +#+vindex: modus-themes-syntax -Symbol names: - -+ =modus-operandi-theme-syntax= -+ =modus-vivendi-theme-syntax= +Symbol: ~modus-themes-syntax~ Possible values: 1. =nil= (default) -2. =faint= -3. =yellow-comments= -4. =green-strings= -5. =yellow-comments-green-strings= -6. =alt-syntax= -7. =alt-syntax-yellow-comments= +2. ~faint~ +3. ~yellow-comments~ +4. ~green-strings~ +5. ~yellow-comments-green-strings~ +6. ~alt-syntax~ +7. ~alt-syntax-yellow-comments~ +8. ~faint-yellow-comments~ The default style (nil) for code syntax highlighting is a balanced combination of colors on the cyan-blue-magenta side of the spectrum. There is little to no use of greens, yellows, or reds, except when it is necessary. -Option =faint= is like the default in terms of the choice of palette but +Option ~faint~ is like the default in terms of the choice of palette but applies desaturated color values. -Option =yellow-comments= applies a yellow tint to comments. The rest of -the syntax is the same as the default. +Option ~yellow-comments~ adds a yellow tint to comments. The rest of the +syntax is the same as the default. -Option =green-strings= replaces the blue/cyan/cold color variants in +Option ~green-strings~ replaces the blue/cyan/cold color variants in strings with greener alternatives. The rest of the syntax remains the same. -Option =yellow-comments-green-strings= combines yellow comments with green +Option ~yellow-comments-green-strings~ combines yellow comments with green strings and the rest of the default syntax highlighting style. -Option =alt-syntax= expands the color palette and applies new color -combinations. Strings are green. Doc strings are magenta tinted. -Comments are gray. +Option ~alt-syntax~ expands the active spectrum by applying color +combinations with more contrasting hues between them. Expect to find +red and green variants in addition to cyan, blue, magenta. -Option =alt-syntax-yellow-comments= combines =alt-syntax= with -=yellow-comments=. +Option ~alt-syntax-yellow-comments~ combines ~alt-syntax~ with +~yellow-comments~. -** Option for no font mixing -:PROPERTIES: -:ALT_TITLE: No mixed fonts -:DESCRIPTION: Toggle mixing of font families -:CUSTOM_ID: h:115e6c23-ee35-4a16-8cef-e2fcbb08e28b -:END: +Option ~faint-yellow-comments~ combines the ~faint~ style with +~yellow-comments~. -Symbol names: +** Option for no font mixing +:properties: +:alt_title: No mixed fonts +:description: Toggle mixing of font families +:custom_id: h:115e6c23-ee35-4a16-8cef-e2fcbb08e28b +:end: +#+vindex: modus-themes-no-mixed-fonts -+ =modus-operandi-theme-no-mixed-fonts= -+ =modus-vivendi-theme-no-mixed-fonts= +Symbol: ~modus-themes-no-mixed-fonts~ Possible values: 1. =nil= (default) 2. =t= -By default, the themes configure some spacing-sensitive faces, such as -Org tables and code blocks, to always inherit from the =fixed-pitch= face. -This is to ensure that those constructs remain monospaced when users opt -for something like the built-in =M-x variable-pitch-mode=. Otherwise the -layout would appear broken. To disable this behaviour, set the option -to =t=. +By default, the themes configure some spacing-sensitive faces like Org +tables and code blocks to always inherit from the ~fixed-pitch~ face. +This is to ensure that those constructs remain monospaced even when +users opt for a mode that remaps typeface families, such as the built-in +{{{kbd(M-x variable-pitch-mode)}}}. Otherwise the layout would appear +broken, due to how spacing is done. To disable this behaviour, set the +option to =t=. Users may prefer to use another package for handling mixed typeface configurations, rather than letting the theme do it, perhaps because a purpose-specific package has extra functionality. Two possible options -are =org-variable-pitch= and =mixed-pitch=. - -** Option for no link underline (deprecated for ~0.14.0~) -:PROPERTIES: -:ALT_TITLE: Link underline -:DESCRIPTION: Toggle underlined text in links (deprecated for 0.14.0) -:CUSTOM_ID: h:a1a639e9-d247-414c-a0ad-08adadcbc6c1 -:END: - -Note: deprecated ahead of version =0.14.0= ([[#h:c119d7b2-fcd4-4e44-890e-5e25733d5e52][Option for links]]). - -Symbol names: - -+ =modus-operandi-theme-no-link-underline= -+ =modus-vivendi-theme-no-link-underline= - -Possible values: - -1. =nil= (default) -2. =t= +are ~org-variable-pitch~ and ~mixed-pitch~. -Remove the underline effect from links, symbolic links, and buttons. -The default is to apply an underline. +[[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations for Org (and others)]]. ** Option for links -:PROPERTIES: -:ALT_TITLE: Link styles -:DESCRIPTION: Choose color intensity or no underline for links -:CUSTOM_ID: h:c119d7b2-fcd4-4e44-890e-5e25733d5e52 -:END: - -This option supersedes the "no link underline" one ahead of version -=0.14.0= ([[#h:a1a639e9-d247-414c-a0ad-08adadcbc6c1][Option for no link underline]]). - -Symbol names: +:properties: +:alt_title: Link styles +:description: Choose among several styles, with or without underline +:custom_id: h:c119d7b2-fcd4-4e44-890e-5e25733d5e52 +:end: +#+vindex: modus-themes-links -+ =modus-operandi-theme-links= -+ =modus-vivendi-theme-links= +Symbol: ~modus-themes-links~ Possible values: 1. =nil= (default) -2. =faint= -3. =neutral-underline= -4. =faint-neutral-underline= -5. =no-underline= +2. ~faint~ +3. ~neutral-underline~ +4. ~faint-neutral-underline~ +5. ~no-underline~ +6. ~underline-only~ +7. ~neutral-underline-only~ The default style (nil) for links is to apply an underline and a -saturated color to the affected text. The color of the two is the -same, which makes the link fairly prominent. +saturated color to the affected text. The color of the two is the same, +which makes the link fairly prominent. -Option =faint= follows the same approach as the default, but uses less +Option ~faint~ follows the same approach as the default, but uses less intense colors. -Option =neutral-underline= changes the underline's color to a subtle -gray, while retaining the default text color. +Option ~neutral-underline~ changes the underline's color to a subtle gray, +while retaining the default text color. -Option =faint-neutral-underline= combines a desaturated text color with a +Option ~faint-neutral-underline~ combines a desaturated text color with a subtle gray underline. -Option =no-underline= removes link underlines altogether, while keeping -their text color the same as the default. +Option ~no-underline~ removes link underlines altogether, while retaining +their original fairly vivid color. -** Option for command prompt styles -:PROPERTIES: -:ALT_TITLE: Command prompts -:DESCRIPTION: Choose among plain, subtle, or intense prompts -:CUSTOM_ID: h:db5a9a7c-2928-4a28-b0f0-6f2b9bd52ba1 -:END: +Option ~underline-only~ applies a prominent underline while making the +affected text colorless (it uses the same foreground as the theme's +default). + +Option ~neutral-underline-only~ makes the text colorless while using a +subtle gray underline below it. -Symbol names: +NOTE: The placement of the underline, i.e. its proximity to the affected +text, is controlled by the built-in ~x-underline-at-descent-line~, +~x-use-underline-position-properties~, ~underline-minimum-offset~. Please +refer to their documentation strings. -+ =modus-operandi-theme-prompts= -+ =modus-vivendi-theme-prompts= +** Option for command prompt styles +:properties: +:alt_title: Command prompts +:description: Choose among plain, subtle, or intense prompts +:custom_id: h:db5a9a7c-2928-4a28-b0f0-6f2b9bd52ba1 +:end: +#+vindex: modus-themes-prompts + +Symbol: ~modus-themes-prompts~ Possible values: 1. =nil= (default) -2. =subtle= -3. =intense= +2. ~subtle-accented~ (~subtle~ exists for backward compatibility) +3. ~intense-accented~ (~intense~ exists for backward compatibility) +4. ~subtle-gray~ +5. ~intense-gray~ -The symbols "subtle" and "intense" will apply a combination of accented -background and foreground to the minibuffer and other REPL prompts (like -=M-x shell= and =M-x eshell=). The difference between the two is that the -latter has a more pronounced/noticeable effect than the former. +The default does not use any background for minibuffer and command line +prompts. It relies exclusively on an accented foreground color. -The default does not use any background for such prompts, while relying -exclusively on an accented foreground color. +Options ~subtle-accented~ and ~intense-accented~ will change both the +background and the foreground values to use accented color combinations +that follow the hue of the default styles' foreground (e.g. the default +minibuffer prompt is cyan text, so these combinations will involved a +cyan background and an appropriate cyan foreground). The difference +between the two is that the latter has a more pronounced/noticeable +effect than the former. -** Option for mode line presentation -:PROPERTIES: -:ALT_TITLE: Mode line -:DESCRIPTION: Choose among plain, three-dimension, or moody-compliant styles -:CUSTOM_ID: h:27943af6-d950-42d0-bc23-106e43f50a24 -:END: +Options ~subtle-gray~, ~intense-gray~ are like their accented counterparts, +except they use grayscale values. -Symbol names: +** Option for mode line presentation +:properties: +:alt_title: Mode line +:description: Choose among several styles, with or without borders +:custom_id: h:27943af6-d950-42d0-bc23-106e43f50a24 +:end: +#+vindex: modus-themes-mode-line -+ =modus-operandi-theme-mode-line= -+ =modus-vivendi-theme-mode-line= +Symbol: ~modus-themes-mode-line~ Possible values: 1. =nil= (default) -2. =3d= -3. =moody= - -The default value (=nil=) produces a two-dimensional effect both for the -active and inactive modelines. The differences between the two are -limited to distinct shades of grayscale values, with the active being -more intense than the inactive. - -A =3d= symbol will make the active modeline look like a three-dimensional +2. ~3d~ +3. ~moody~ +4. ~borderless~ +5. ~borderless-3d~ +6. ~borderless-moody~ + +The default produces a two-dimensional effect both for the active and +inactive modelines. The differences between the two are limited to +distinct shades of grayscale values, with the active being more intense +than the inactive. + +Option ~3d~ will make the active modeline look like a three-dimensional rectangle. Inactive modelines remain 2D, though they are slightly toned -down relative to the default. This aesthetic is the same as what you -get when you run Emacs without any customizations (=emacs -Q= on the -command line). +down relative to the default. This aesthetic is virtually the same as +what you get when you run Emacs without any customizations (=emacs -Q= on +the command line). -While =moody= removes all box effects from the modelines and applies +While ~moody~ removes all box effects from the modelines and applies underline and overline properties instead. It also tones down a bit the inactive modelines. This is meant to optimize things for use with the [[https://github.com/tarsius/moody][moody package]] (hereinafter referred to as "Moody"), though it can work fine even without it. +The ~borderless~ option uses the same colors as the default (nil value), +but removes the border effect. This is done by making the box property +use the same color as the background, effectively blending the two and +creating some padding. + +The ~borderless-3d~ and ~borderless-moody~ approximate the ~3d~ and ~moody~ +options respectively, while removing the borders. However, to ensure +that the inactive modelines remain visible, they apply a slightly more +prominent background to them than what their counterparts do (same +inactive background as with the default). + Note that Moody does not expose any faces that the themes could style directly. Instead it re-purposes existing ones to render its tabs and ribbons. As such, there may be cases where the contrast ratio falls below the 7:1 target that the themes conform with (WCAG AAA). To hedge -against this, we configure a fallback foreground for the =moody= option, +against this, we configure a fallback foreground for the ~moody~ option, which will come into effect when the background of the modeline changes to something less accessible, such as Moody ribbons (read the doc string -of =set-face-attribute=, specifically =:distant-foreground=). This fallback -comes into effect when Emacs determines that the background and -foreground of the given construct are too close to each other in terms -of color distance. In effect, users would need to experiment with the -variable =face-near-same-color-threshold= to trigger the fallback color. -We find that a value of =45000= would suffice, contrary to the default -=30000=. Do not set the value too high, because that would have the -adverse effect of always overriding the default color (which has been -carefully designed to be highly accessible). +of ~set-face-attribute~, specifically ~:distant-foreground~). This fallback +is activated when Emacs determines that the background and foreground of +the given construct are too close to each other in terms of color +distance. In effect, users would need to experiment with the variable +~face-near-same-color-threshold~ to trigger the effect. We find that a +value of =45000= will suffice, contrary to the default =30000=. Do not set +the value too high, because that would have the adverse effect of always +overriding the default color (which has been carefully designed to be +highly accessible). Furthermore, because Moody expects an underline and overline instead of -a box style, it is recommended you also include this in your setup: +a box style, it is advised you include this in your setup: #+begin_src emacs-lisp (setq x-underline-at-descent-line t) #+end_src ** Option for completion framework aesthetics -:PROPERTIES: -:ALT_TITLE: Completion UIs -:DESCRIPTION: Choose among standard, moderate, or opinionated looks -:CUSTOM_ID: h:f1c20c02-7b34-4c35-9c65-99170efb2882 -:END: - -Symbol names: +:properties: +:alt_title: Completion UIs +:description: Choose among standard, moderate, or opinionated looks +:custom_id: h:f1c20c02-7b34-4c35-9c65-99170efb2882 +:end: +#+vindex: modus-themes-completions -+ =modus-operandi-theme-completions= -+ =modus-vivendi-theme-completions= +Symbol: ~modus-themes-completions~ Possible values: 1. =nil= (default) -2. =moderate= -3. =opinionated= +2. ~moderate~ +3. ~opinionated~ This is a special option that has different effects depending on the completion UI. The interfaces can be grouped in two categories, based @@ -679,512 +666,1008 @@ Ivy, and similar. A value of =nil= will respect the metaphors of each completion framework. -The symbol =moderate= will apply a combination of background and -foreground that is fairly subtle. For Icomplete and friends this -constitutes a departure from their default aesthetics, however the -difference is small. While Helm et al will appear slightly different -than their original looks, as they are toned down a bit. +Option ~moderate~ applies a combination of background and foreground that +is fairly subtle. For Icomplete and friends this constitutes a +departure from their default aesthetics, however the difference is +small. While Helm, Ivy et al appear slightly different than their +original looks, as they are toned down a bit. -The symbol =opinionated= will apply color combinations that refashion the -completion UI. For the Icomplete camp this means that intense -background and foreground combinations are used: in effect their looks -emulate those of Ivy and co. in their original style. Whereas the other -group of packages will revert to an even more nuanced aesthetic with -some additional changes to the choice of hues. +Option ~opinionated~ uses color combinations that refashion the completion +UI. For the Icomplete camp this means that intense background and +foreground combinations are used: in effect their looks emulate those of +Helm, Ivy and co. in their original style. Whereas the other group of +packages will revert to an even more nuanced aesthetic with some +additional changes to the choice of hues. To appreciate the scope of this customization option, you should spend -some time with every one of the =nil= (default), =moderate=, and =opinionated= +some time with every one of the =nil= (default), ~moderate~, and ~opinionated~ possibilities. ** Option for fringe visibility -:PROPERTIES: -:ALT_TITLE: Fringes -:DESCRIPTION: Choose among plain, subtle, or intense fringe visibility -:CUSTOM_ID: h:1983c3fc-74f6-44f3-b917-967c403bebae -:END: +:properties: +:alt_title: Fringes +:description: Choose among invisible, subtle, or intense fringe styles +:custom_id: h:1983c3fc-74f6-44f3-b917-967c403bebae +:end: +#+vindex: modus-themes-fringes -Symbol names: - -+ =modus-operandi-theme-fringes= -+ =modus-vivendi-theme-fringes= +Symbol: ~modus-themes-fringes~ Possible values: 1. =nil= (default) -2. =subtle= -3. =intense= - -The "subtle" symbol will apply a grayscale background that is visible, -yet close enough to the main background color. While the "intense" -symbol will use a more noticeable grayscale background. +2. ~subtle~ +3. ~intense~ The default is to use the same color as that of the main background, meaning that the fringes are not obvious though they still occupy the -space given to them by =fringe-mode=. +space given to them by ~fringe-mode~. -** Option for line highlighting (hl-line-mode) -:PROPERTIES: -:ALT_TITLE: Line highlighting -:DESCRIPTION: Toggle intense style for current line highlighting -:CUSTOM_ID: h:1dba1cfe-d079-4c13-a810-f768e8789177 -:END: +Options ~subtle~ and ~intense~ apply a gray background, making the fringes +visible. The difference between the two is one of degree, as their +names imply. -Symbol names: +** Option for language checkers +:properties: +:alt_title: Language checkers +:description: Control the style of language checkers/linters +:custom_id: h:4b13743a-8ebf-4d2c-a043-cceba10b1eb4 +:end: +#+vindex: modus-themes-lang-checkers -+ =modus-operandi-theme-intense-hl-line= -+ =modus-vivendi-theme-intense-hl-line= +Symbol: ~modus-themes-lang-checkers~ + +Possible values: + +1. =nil= (default) +2. ~subtle-foreground~ +3. ~intense-foreground~ +4. ~straight-underline~ +5. ~subtle-foreground-straight-underline~ +6. ~intense-foreground-straight-underline~ +7. ~colored-background~ + +Nil (the default) applies a color-coded underline to the affected text, +while it leaves the original foreground in tact. If the display spec +where Emacs runs in has support for it (e.g. Emacs GUI), the underline's +style is that of a wave, otherwise it is a straight line. + +Options ~subtle-foreground~ and ~intense-foreground~ follow the same +color-coding pattern and wavy underline of the default, while extending +it with a corresponding foreground value for the affected text. The +difference between the two options is one of degree, as their names +suggest. + +Option ~straight-underline~ is like the default but always applies a +straight line under the affected text. Same principle for +~subtle-foreground-straight-underline~ and its counterpart +~intense-foreground-straight-underline~. + +Option ~colored-background~ uses a straight underline, a tinted +background, and a suitable foreground. All are color-coded. This is +the most intense combination of face properties. + +The present variable affects packages and/or face groups such as those +of =flyspell=, =flymake=, =flycheck=, ~artbollocks-mode~, and ~writegood-mode~. + +NOTE: The placement of the straight underline, though not the wave +style, is controlled by the built-in ~x-underline-at-descent-line~, +~x-use-underline-position-properties~, ~underline-minimum-offset~. Please +refer to their documentation strings. + +** Option for line highlighting (hl-line-mode) +:properties: +:alt_title: Line highlighting +:description: Toggle intense style for current line highlighting +:custom_id: h:1dba1cfe-d079-4c13-a810-f768e8789177 +:end: +#+vindex: modus-themes-intense-hl-line + +Symbol: ~modus-themes-intense-hl-line~ Possible values: 1. =nil= (default) 2. =t= -Draw the current line of =hl-line-mode= or its global equivalent in a more -prominent background color. This would also affect several packages -that enable =hl-line-mode=, such as =elfeed= and =mu4e=. +The default is to use a subtle gray background for ~hl-line-mode~ and its +global equivalent. -The default is to use a more subtle gray. +With a non-nil value (=t=) use a more prominent background color instead. + +This affects several packages that enable ~hl-line-mode~, such as =elfeed= +and =mu4e=. + +** Option for line numbers (display-line-numbers-mode) +:properties: +:alt_title: Line numbers +:description: Toggle subtle style for line numbers +:custom_id: h:8c4a6230-2e43-4aa2-a631-3b7179392e09 +:end: +#+vindex: modus-themes-subtle-line-numbers + +Symbol: ~modus-themes-subtle-line-numbers~ + +Possible value: + +1. =nil= (default) +2. =t= + +The default style for ~display-line-numbers-mode~ and its global variant +is to apply a subtle gray background to the line numbers. The current +line has a more pronounced background and foreground combination to +bring more attention to itself. + +Similarly, the faces for ~display-line-numbers-major-tick~ and its +counterpart ~display-line-numbers-minor-tick~ use appropriate styles that +involve a bespoke background and foreground combination. + +With a non-nil value (=t=), line numbers have no background of their own. +Instead they retain the primary background of the theme, blending with +the rest of the buffer. Foreground values for all relevant faces are +updated to accommodate this aesthetic. ** Option for parenthesis matching (show-paren-mode) -:PROPERTIES: -:ALT_TITLE: Matching parentheses -:DESCRIPTION: Toggle intense style for matching delimiters/parentheses -:CUSTOM_ID: h:e66a7e4d-a512-4bc7-9f86-fbbb5923bf37 -:END: +:properties: +:alt_title: Matching parentheses +:description: Choose between various styles for matching delimiters/parentheses +:custom_id: h:e66a7e4d-a512-4bc7-9f86-fbbb5923bf37 +:end: +#+vindex: modus-themes-paren-match + +Symbol: ~modus-themes-paren-match~ + +Possible values: + +1. =nil= (default) +2. ~subtle-bold~ +3. ~intense~ +4. ~intense-bold~ -Symbol names: +Nil means to use a subtle tinted background color for the matching +delimiters. -+ =modus-operandi-theme-intense-paren-match= -+ =modus-vivendi-theme-intense-paren-match= +Option ~intense~ applies a saturated background color. + +Option ~subtle-bold~ is the same as the default, but also makes use of +bold typographic weight (inherits the ~bold~ face). + +Option ~intense-bold~ is the same as ~intense~, while it also uses a bold +weight. + +This customization variable affects tools such as the built-in +~show-paren-mode~ and the =smartparens= package. + +** Option for active region +:properties: +:alt_title: Active region +:description: Choose between various styles for the active region +:custom_id: h:60798063-b4ad-45ea-b9a7-ff7b5c0ab74c +:end: +#+vindex: modus-themes-region + +Symbol: ~modus-themes-region~ Possible values: 1. =nil= (default) -2. =t= +2. ~no-extend~ +3. ~bg-only~ +4. ~bg-only-no-extend~ -Apply a more intense background to the matching parentheses (or -delimiters). This affects tools such as the built-in =show-paren-mode=. -The default is to use a subtle warm color for the background of those -overlays. +Nil means to only use a prominent gray background with a neutral +foreground. The foreground overrides all syntax highlighting. The +region extends to the edge of the window. -** Option for diff buffer looks -:PROPERTIES: -:ALT_TITLE: Diffs -:DESCRIPTION: Choose among intense, desaturated, or text-only diffs -:CUSTOM_ID: h:ea7ac54f-5827-49bd-b09f-62424b3b6427 -:END: +Option ~no-extend~ preserves the default aesthetic but prevents the region +from extending to the edge of the window. + +Option ~bg-only~ applies a faint tinted background that is distinct from +all others used in the theme, while it does not override any existing +colors. It extends to the edge of the window. + +Option ~bg-only-no-extend~ is a combination of the ~bg-only~ and ~no-extend~ +options. -Symbol names: +** Option for diff buffer looks +:properties: +:alt_title: Diffs +:description: Choose among intense, desaturated, or text-only diffs +:custom_id: h:ea7ac54f-5827-49bd-b09f-62424b3b6427 +:end: +#+vindex: modus-themes-diffs -+ =modus-operandi-theme-diffs= -+ =modus-vivendi-theme-diffs= +Symbol: ~modus-themes-diffs~ Possible values: 1. =nil= (default) -2. =desaturated= -2. =fg-only= - -By default the themes will apply richly colored backgrounds to the -output of diffs, such as those of =diff-mode=, =ediff=, =smerge-mode=, and -=magit=. These are color combinations of an accented background and -foreground so that, for example, added lines have a pronounced green -background with an appropriate shade of green for the affected text. -Word-wise or "refined" changes follow this pattern but use different -shades of those colors to remain distinct. - -A =desaturated= value tones down all relevant color values. It still +2. ~desaturated~ +3. ~fg-only~ +4. ~bg-only~ +5. ~deuteranopia~ + +By default the themes apply rich coloration to the output of diffs, such +as those of ~diff-mode~, ~ediff~, ~smerge-mode~, and Magit. These are +color combinations of an accented background and foreground so that, for +example, added lines have a pronounced green background with an +appropriate shade of green for the affected text. Word-wise or +"refined" changes follow this pattern but use different shades of those +colors to remain distinct. + +Option ~desaturated~ tones down all relevant color values. It still combines an accented background with an appropriate foreground, yet its -overall impression is very subtle. Refined changes are a bit more +overall impression is fairly subtle. Refined changes are a bit more intense to fulfil their intended function, though still less saturated than default. -While =fg-only= will remove all accented backgrounds and instead rely on -color-coded text to denote changes. For instance, added lines use an -intense green foreground, while their background is the same as the rest -of the buffer. Word-wise highlights still use a background value which -is, nonetheless, more subtle than its default equivalent. - -Concerning =magit=, an extra set of tweaks are introduced for the effect -of highlighting the current diff hunk, so as to remain consistent with -the overall experience of that mode. Expect changes that are consistent -with the overall intent of the aforementioned. +Option ~fg-only~ will remove most accented backgrounds and instead rely +on color-coded text to denote changes. For instance, added lines use a +green foreground, while their background is the same as the rest of the +buffer. Word-wise highlights still use a background value which is, +nonetheless, more subtle than its default equivalent. + +Option ~bg-only~ applies color-coded backgrounds but does not override +any syntax highlighting that may be present. This makes it suitable for +use with a non-nil value for ~diff-font-lock-syntax~ (which is the +default for ~diff-mode~ buffers in Emacs 27 or higher). + +Option ~deuteranopia~ optimizes for red-green color deficiency. It +replaces all instances of green with blue variants. This is to ensure +that indicators for "removed" and "added" states are not mistaken for +each other. + +Concerning Magit, an extra set of tweaks are introduced for the effect +of highlighting the current diff hunk, so as to remain aligned with the +overall experience of that mode. Expect changes that are consistent +with the overall intent of the aforementioned. Note, however, that the +~bg-only~ option will not deliver the intended results in Magit diffs +because no syntax highlighting is used there (last checked with Magit +version 20201116.1057, though upstream has a plan to eventually support +such a feature---this entry shall be updated accordingly). ** Option for org-mode block styles -:PROPERTIES: -:ALT_TITLE: Org mode blocks -:DESCRIPTION: Choose among plain, grayscale, or rainbow styles -:CUSTOM_ID: h:b7e328c0-3034-4db7-9cdf-d5ba12081ca2 -:END: - -Symbol names: +:properties: +:alt_title: Org mode blocks +:description: Choose among plain, grayscale, or rainbow styles +:custom_id: h:b7e328c0-3034-4db7-9cdf-d5ba12081ca2 +:end: +#+vindex: modus-themes-org-blocks -+ =modus-operandi-theme-org-blocks= -+ =modus-vivendi-theme-org-blocks= +Symbol: ~modus-themes-org-blocks~ Possible values: 1. =nil= (default) -2. =grayscale= -3. =rainbow= +2. ~grayscale~ +3. ~rainbow~ The default is to use the same background as the rest of the buffer for the contents of the block. -A value of =grayscale= will apply a subtle neutral gray background to the -block's contents. It will also extend to the edge of the window the -background of the "begin" and "end" block delimiter lines (only relevant -for Emacs versions >= 27 where the 'extend' keyword is recognised by -=set-face-attribute=). +Option ~grayscale~ applies a subtle neutral gray background to the block's +contents. It will also extend to the edge of the window the background +of the "begin" and "end" block delimiter lines (only relevant for Emacs +versions >= 27 where the 'extend' keyword is part of the face +specifications). -While =rainbow= will instead use an accented background for the contents -of the block. The exact color will depend on the programming language -and is controlled by the =org-src-block-faces= variable (refer to the -theme's source code for the current association list). This is most -suitable for users who work on literate programming documents that mix -and match several languages. +Option ~rainbow~ uses an accented background for the contents of the +block. The exact color will depend on the programming language and is +controlled by the ~org-src-block-faces~ variable. This is most suitable +for users who work on literate programming documents that mix and match +several languages. Note that the "rainbow" blocks may require you to also reload the -major-mode so that the colors are applied properly: use =M-x org-mode= or -=M-x org-mode-restart= to refresh the buffer. Or start typing in each -code block (inefficient at scale, but it still works). +major-mode so that the colors are applied consistently throughout: use +{{{kbd(M-x org-mode)}}} or {{{kbd(M-x org-mode-restart)}}} to refresh the buffer. +Or start typing in each code block (inefficient at scale, but it still +works). -** Option for headings' overall style -:PROPERTIES: -:ALT_TITLE: Heading styles -:DESCRIPTION: Choose among several styles, also per heading level -:CUSTOM_ID: h:271eff19-97aa-4090-9415-a6463c2f9ae1 -:END: +** Option for org-habit graph styles +:properties: +:alt_title: Org agenda habits +:description: Choose among standard, simplified, or traffic light styles +:custom_id: h:b7e328c0-3034-4db7-9cdf-d5ba12081ca2 +:end: +#+vindex: modus-themes-org-habit + +Symbol: ~modus-themes-org-habit~ + +Possible values: + +1. =nil= (default) +2. ~simplified~ +3. ~traffic-light~ + +The default is meant to conform with the original aesthetic of +=org-habit=. It employs all four color codes that correspond to the +org-habit states---clear, ready, alert, and overdue---while +distinguishing between their present and future variants. This results +in a total of eight colors in use: red, yellow, green, blue, in tinted +and shaded versions. They cover the full set of information provided by +the =org-habit= consistency graph. + +Option ~simplified~ is like the default except that it removes the +dichotomy between current and future variants by applying uniform +color-coded values. It applies a total of four colors: red, yellow, +green, blue. They produce a simplified consistency graph that is more +legible (or less "busy") than the default. The intent is to shift focus +towards the distinction between the four states of a habit task, rather +than each state's present/future outlook. + +Option ~traffic-light~ further reduces the available colors to red, +yellow, and green. As in ~simplified~, present and future variants appear +uniformly, but differently from it, the 'clear' state is rendered in a +green hue, instead of the original blue. This is meant to capture the +use-case where a habit task being "too early" is less important than it +being "too late". The difference between ready and clear states is +attenuated by painting both of them using shades of green. This option +thus highlights the alert and overdue states. + +** Option for the headings' overall style +:properties: +:alt_title: Heading styles +:description: Choose among several styles, also per heading level +:custom_id: h:271eff19-97aa-4090-9415-a6463c2f9ae1 +:end: +#+vindex: modus-themes-headings This is defined as an alist and, therefore, uses a different approach than other customization options documented in this manual. -Symbol names: - -+ =modus-operandi-theme-headings= -+ =modus-vivendi-theme-headings= +Symbol: ~modus-themes-headings~ Possible values, which can be specified for each heading level (examples further below): + nil (default fallback option---covers all heading levels) + =t= (default style for a single heading, when the fallback differs) -+ =no-bold= -+ =line= -+ =line-no-bold= -+ =rainbow= -+ =rainbow-line= -+ =rainbow-line-no-bold= -+ =highlight= -+ =highlight-no-bold= -+ =rainbow-highlight= -+ =rainbow-highlight-no-bold= -+ =section= -+ =section-no-bold= -+ =rainbow-section= -+ =rainbow-section-no-bold= - -To control faces per level from 1-8, use something like this (same for -=modus-vivendi-theme-headings=): ++ ~no-bold~ ++ ~line~ ++ ~line-no-bold~ ++ ~rainbow~ ++ ~rainbow-line~ ++ ~rainbow-line-no-bold~ ++ ~highlight~ ++ ~highlight-no-bold~ ++ ~rainbow-highlight~ ++ ~rainbow-highlight-no-bold~ ++ ~section~ ++ ~section-no-bold~ ++ ~rainbow-section~ ++ ~rainbow-section-no-bold~ ++ ~no-color~ ++ ~no-color-no-bold~ + +To control faces per level from 1-8, use something like this: #+begin_src emacs-lisp -(setq modus-operandi-theme-headings +(setq modus-themes-headings '((1 . section) - (2 . line) - (3 . highlight) - (t . rainbow-no-bold))) + (2 . section-no-bold) + (3 . rainbow-line) + (t . rainbow-line-no-bold))) #+end_src -The above uses the =section= value for heading levels 1, the =line= for -headings 2, =highlight= for 3. All other levels fall back to -=rainbow-line-no-bold=. +The above uses the ~section~ value for heading levels 1, ~section-no-bold~ +for headings 2, ~rainbow-line~ for 3. All other levels fall back to +~rainbow-line-no-bold~. To set a uniform value for all heading levels, use this pattern: #+begin_src emacs-lisp ;; A given style for every heading -(setq modus-operandi-theme-headings - '((t . rainbow-line-no-bold))) +(setq modus-themes-headings + '((t . section))) ;; Default aesthetic for every heading -(setq modus-operandi-theme-headings - '((t . nil))) +(setq modus-themes-headings + '()) #+end_src The default style for headings uses a fairly desaturated foreground -value in combination with a bold typographic weight. To specify this -style for a given level N (assuming you wish to have another fallback -option), just specify the value =t= like this: +value in combination with bold typographic weight. To specify this +style for a given level N, assuming you wish to have another fallback +option, just specify the value =t= like this: #+begin_src emacs-lisp -(setq modus-operandi-theme-headings +(setq modus-themes-headings '((1 . t) (2 . line) (t . rainbow-line-no-bold))) #+end_src -A description of all other possible styles: +A description of all other possible styles beyond the default: -+ =no-bold= retains the default text color while removing the typographic - weight. ++ ~no-bold~ retains the default text color while removing the bold + typographic weight. -+ =line= is the same as the default plus an overline over the heading. ++ ~line~ is the same as the default plus an overline across the + heading's length. -+ =line-no-bold= is the same as =line= without bold weight. ++ ~line-no-bold~ is the same as ~line~ without bold weight. -+ =rainbow= uses a more colorful foreground in combination with bold - weight. ++ ~rainbow~ uses a more colorful foreground in combination with bold + typographic weight. -+ =rainbow-line= is the same as =rainbow= plus an overline. ++ ~rainbow-line~ is the same as ~rainbow~ plus an overline. -+ =rainbow-line-no-bold= is the same as =rainbow-line= without the bold ++ ~rainbow-line-no-bold~ is the same as ~rainbow-line~ without the bold weight. -+ =highlight= retains the default style of a fairly desaturated foreground - combined with a bold weight and adds to it a subtle accented - background. ++ ~highlight~ retains the default style of a fairly desaturated + foreground combined with a bold weight and adds to it a subtle + accented background. -+ =highlight-no-bold= is the same as =highlight= without a bold weight. ++ ~highlight-no-bold~ is the same as ~highlight~ without a bold weight. -+ =rainbow-highlight= is the same as =highlight= but with a more colorful - foreground. ++ ~rainbow-highlight~ is the same as ~highlight~ but with a more + colorful foreground. -+ =rainbow-highlight-no-bold= is the same as =rainbow-highlight= without a - bold weight. ++ ~rainbow-highlight-no-bold~ is the same as ~rainbow-highlight~ without + a bold weight. -+ =section= retains the default looks and adds to them both an overline ++ ~section~ retains the default looks and adds to them both an overline and a slightly accented background. It is, in effect, a combination - of the =line= and =highlight= values. + of the ~line~ and ~highlight~ values. -+ =section-no-bold= is the same as =section= without a bold weight. ++ ~section-no-bold~ is the same as ~section~ without a bold weight. -+ =rainbow-section= is the same as =section= but with a more colorful ++ ~rainbow-section~ is the same as ~section~ but with a more colorful foreground. -+ =rainbow-section-no-bold= is the same as =rainbow-section= without a bold - weight." ++ ~rainbow-section-no-bold~ is the same as ~rainbow-section~ without a + bold weight. + ++ ~no-color~ does not apply any color to the heading, meaning that it + uses the foreground of the ~default~ face. It still renders the text + with a bold typographic weight. -** Option for scaled headings -:PROPERTIES: -:ALT_TITLE: Scaled headings -:DESCRIPTION: Toggle scaling of headings -:CUSTOM_ID: h:075eb022-37a6-41a4-a040-cc189f6bfa1f -:END: ++ ~no-color-no-bold~ is like ~no-color~ but without the bold weight. -Symbol names: +** Option for scaled headings +:properties: +:alt_title: Scaled headings +:description: Toggle scaling of headings +:custom_id: h:075eb022-37a6-41a4-a040-cc189f6bfa1f +:end: +#+vindex: modus-themes-scale-headings -+ =modus-operandi-theme-scale-headings= -+ =modus-vivendi-theme-scale-headings= +Symbol: ~modus-themes-scale-headings~ Possible values: 1. =nil= (default) 2. =t= -Make headings larger in height relative to the main text. This is -noticeable in modes like Org. The default is to use the same size for -headings and body copy. +The default is to use the same size for headings and paragraph text. + +With a non-nil value (=t=) make headings larger in height relative to the +main text. This is noticeable in modes like Org, Markdown, and Info. *** Control the scale of headings -:PROPERTIES: -:ALT_TITLE: Scaled heading sizes -:DESCRIPTION: Specify rate of increase for scaled headings -:CUSTOM_ID: h:6868baa1-beba-45ed-baa5-5fd68322ccb3 -:END: +:properties: +:alt_title: Scaled heading sizes +:description: Specify rate of increase for scaled headings +:custom_id: h:6868baa1-beba-45ed-baa5-5fd68322ccb3 +:end: -In addition to toggles for enabling scaled headings, users can also +In addition to the toggle for enabling scaled headings, users can also specify a number of their own. + If it is a floating point, say, =1.5=, it is interpreted as a multiple - of the base font size. This is the recommended method. - -+ If it is an integer, it is read as an absolute font height. The - number is basically the point size multiplied by ten. So if you want - it to be =18pt= you must pass =180=. Please understand that setting an - absolute value is discouraged, as it will break the layout when you - try to change font sizes with the built-in =text-scale-adjust= command - (see [[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations]]). + of the base font size. This is the recommended method, because it + will always adapt to changes in the base font size, such as while + using the ~text-scale-adjust~ command. + ++ If it is an integer, it is read as an absolute font height that is + 1/10 of the typographic point size. Thus a value of =18pt= must be + expressed as =180=. Setting an absolute value is discouraged, as it + will break the layout in cases where the base font size must change, + such as with the ~text-scale-adjust~ command ([[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations]]). + While we discourage using absolute values, we still provide for this + option for users who do not need to perform text-scaling operations or + who are content with whatever discrepancies in height. Below are the variables in their default values, using the floating -point paradigm. The numbers are very conservative, but you are free to -change them to your liking, such as =1.2=, =1.4=, =1.6=, =1.8=, =2.0=---or use a +point paradigm. The numbers are very conservative, but one is free to +change them to their liking, such as =1.2=, =1.4=, =1.6=, =1.8=, =2.0=---or use a resource for finding a consistent scale: #+begin_src emacs-lisp -(setq modus-operandi-theme-scale-1 1.05 - modus-operandi-theme-scale-2 1.1 - modus-operandi-theme-scale-3 1.15 - modus-operandi-theme-scale-4 1.2 - modus-operandi-theme-scale-5 1.3) - -(setq modus-vivendi-theme-scale-1 1.05 - modus-vivendi-theme-scale-2 1.1 - modus-vivendi-theme-scale-3 1.15 - modus-vivendi-theme-scale-4 1.2 - modus-vivendi-theme-scale-5 1.3) +(setq modus-themes-scale-1 1.05 + modus-themes-scale-2 1.1 + modus-themes-scale-3 1.15 + modus-themes-scale-4 1.2 + modus-themes-scale-5 1.3) #+end_src +As for the application of that scale, the variables that range from +~modus-themes-scale-1~ up to ~modus-themes-scale-4~ apply to regular +headings within the context of the given major mode. The former is the +smallest, while the latter is the largest. "Regular headings" are those +that have a standard syntax for their scale, such as Org mode's eight +levels of asterisks or Markdown's six columns. + +Whereas ~modus-themes-scale-5~ is applied to special headings that do not +conform with the aforementioned syntax, yet which are expected to be +larger than the largest value on that implied scale. Put concretely, +Org's =#+title= meta datum is not part of the eight levels of headings in +an Org file, yet is supposed to signify the primary header. Similarly, +the Org Agenda's structure headings are not part of a recognisable scale +and so they also get ~modus-themes-scale-5~. + +Users who wish to maintain scaled headings for the normal syntax while +preventing special headings from standing out, can assign a value of =1.0= +to ~modus-themes-scale-5~ to make it the same as body text (or whatever +value would render it indistinguishable from the desired point of +reference). + Note that in earlier versions of Org, scaling would only increase the size of the heading, but not of keywords that were added to it, like "TODO". The issue has been fixed upstream: . -** Option for variable-pitch font in headings -:PROPERTIES: -:ALT_TITLE: Headings' font -:DESCRIPTION: Toggle proportionately spaced fonts in headings -:CUSTOM_ID: h:97caca76-fa13-456c-aef1-a2aa165ea274 -:END: +** Option for variable-pitch font in UI elements +:properties: +:alt_title: UI typeface +:description: Toggle the use of variable-pitch across the User Interface +:custom_id: h:16cf666c-5e65-424c-a855-7ea8a4a1fcac +:end: +#+vindex: modus-themes-variable-pitch-ui + +Symbol: ~modus-themes-variable-pitch-ui~ + +Possible values: + +1. =nil= (default) +2. =t= + +This option concerns User Interface elements that are under the direct +control of Emacs. In particular: the mode line, header line, tab bar, +and tab line. + +The default is to use the same font as the rest of Emacs, which usually +is a monospaced family. -Symbol names: +With a non-nil value (=t=) apply a proportionately spaced typeface. This +is done by assigning the ~variable-pitch~ face to the relevant items. -+ =modus-operandi-theme-variable-pitch-headings= -+ =modus-vivendi-theme-variable-pitch-headings= +[[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations for Org and others]]. + +** Option for variable-pitch font in headings +:properties: +:alt_title: Headings' typeface +:description: Toggle the use of variable-pitch in headings +:custom_id: h:97caca76-fa13-456c-aef1-a2aa165ea274 +:end: +#+vindex: modus-themes-variable-pitch-headings + +Symbol: ~modus-themes-variable-pitch-headings~ Possible values: 1. =nil= (default) 2. =t= -Choose to apply a proportionately spaced, else "variable-pitch", -typeface to headings (such as in Org mode). The default is to use the -main font family. +The default is to use the main font family, which typically is +monospaced. -[[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations for Org (and others)]]. +With a non-nil value (=t=) apply a proportionately spaced typeface, else +"variable-pitch", to headings (such as in Org mode). + +[[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations for Org and others]]. * Advanced customization (do-it-yourself) -:PROPERTIES: -:INDEX: cp -:CUSTOM_ID: h:f4651d55-8c07-46aa-b52b-bed1e53463bb -:END: +:properties: +:custom_id: h:f4651d55-8c07-46aa-b52b-bed1e53463bb +:end: -Unlike the predefined customization options which follow a -straightforward pattern of allowing the user to quickly specify their -preference, the themes also provide a more flexible, albeit difficult, -mechanism to control things with precision (see [[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization Options]]). +Unlike the predefined customization options which follow a clear pattern +of allowing the user to quickly specify their preference, the themes +also provide a more flexible, albeit difficult, mechanism to control +things with precision ([[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization Options]]). This section is of interest only to users who are prepared to maintain their own local tweaks and who are willing to deal with any possible incompatibilities between versioned releases of the themes. As such, they are labelled as "do-it-yourself" or "DIY". -** Full access to the themes' palette -:PROPERTIES: -:ALT_TITLE: Tweak colors (DIY) -:DESCRIPTION: Declare your own palette overrides -:CUSTOM_ID: h:1487c631-f4fe-490d-8d58-d72ffa3bd474 -:END: +** Per-theme customization settings (DIY) +:properties: +:custom_id: h:a897b302-8e10-4a26-beab-3caaee1e1193 +:end: + +If you prefer to maintain different customization options between the +two themes, it is best you write your own functions that first set those +options and then load the relevant theme. The following code does +exactly that by simply differentiating the two themes on the choice of +bold constructs in code syntax (enabled for one, disabled for the +other). + +#+begin_src emacs-lisp +(defun my-demo-modus-operandi () + (interactive) + (setq modus-themes-bold-constructs t) ; ENABLE bold + (modus-themes-load-operandi)) + +(defun my-demo-modus-vivendi () + (interactive) + (setq modus-themes-bold-constructs nil) ; DISABLE bold + (modus-themes-load-vivendi)) + +(defun my-demo-modus-themes-toggle () + (if (eq (car custom-enabled-themes) 'modus-operandi) + (my-demo-modus-vivendi) + (my-demo-modus-operandi))) +#+end_src + +Then assign ~my-demo-modus-themes-toggle~ to a key instead of the +equivalent the themes provide. + +For a more elaborate design, it is better to inspect the source code of +~modus-themes-toggle~ and relevant functions. + +** Case-by-case face specs using the themes' palette (DIY) +:properties: +:custom_id: h:1487c631-f4fe-490d-8d58-d72ffa3bd474 +:end: +#+findex: modus-themes-color +#+findex: modus-themes-color-alts +#+cindex: Extracting individual colors + +This section is about tweaking individual faces. If you plan to do +things at scale, consult the next section: [[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Set multiple faces]]. + +We already covered in previous sections how to toggle between the themes +and how to configure options prior to loading. We also explained that +some of the functions made available to users will fire up a hook that +can be used to pass tweaks in the post-theme-load phase. + +Now assume you wish to change a single face, say, the ~cursor~. And you +would like to get the standard "blue" color value of the active Modus +theme, whether it is Modus Operandi or Modus Vivendi. To do that, you +can use the ~modus-themes-color~ function. It accepts a symbol that is +associated with a color in ~modus-themes-operandi-colors~ and +~modus-themes-vivendi-colors~. Like this: + +#+begin_src emacs-lisp +(modus-themes-color 'blue) +#+end_src + +The function always extracts the color value of the active Modus theme. + +#+begin_src emacs-lisp +(progn + (load-theme 'modus-operandi t) + (modus-themes-color 'blue)) ; "#0031a9" for `modus-operandi' + +(progn + (load-theme 'modus-vivendi t) + (modus-themes-color 'blue)) ; "#2fafff" for `modus-vivendi' +#+end_src + +Do {{{kbd(C-h v)}}} on the aforementioned variables to check all the available +symbols that can be passed to this function. + +With that granted, let us expand the example to actually change the +~cursor~ face's background property. We employ the built-in function of +~set-face-attribute~: + +#+begin_src emacs-lisp +(set-face-attribute 'cursor nil :background (modus-themes-color 'blue)) +#+end_src + +If you evaluate this form, your cursor will become blue. But if you +change themes, such as with ~modus-themes-toggle~, your edits will be +lost, because the newly loaded theme will override the =:background= +attribute you had assigned to that face. -The variables are: +For such changes to persist, we need to make them after loading the +theme. So we rely on ~modus-themes-after-load-theme-hook~, which gets +called from ~modus-themes-load-operandi~, ~modus-themes-load-vivendi~, as +well as the command ~modus-themes-toggle~. Here is a sample function that +tweaks two faces and then gets added to the hook: -+ =modus-operandi-theme-override-colors-alist= -+ =modus-vivendi-theme-override-colors-alist= +#+begin_src emacs-lisp +(defun my-modus-themes-custom-faces () + (set-face-attribute 'cursor nil :background (modus-themes-color 'blue)) + (set-face-attribute 'font-lock-type-face nil :foreground (modus-themes-color 'magenta-alt))) + +(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces) +#+end_src -Users can specify an association list that maps the names of color -variables to hexadecimal RGB values (in the form of =#RRGGBB=). This -means that it is possible to override the entire palette or subsets -thereof (see the source code for the actual names and values). +[[#h:86f6906b-f090-46cc-9816-1fe8aeb38776][A theme-agnostic hook for theme loading]]. -Example: +Using this principle, it is possible to override the styles of faces +without having to find color values for each case. + +Another application is to control the precise weight for bold +constructs. This is particularly useful if your typeface has several +variants such as "heavy", "extrabold", "semibold". All you have to do +is edit the ~bold~ face. For example: #+begin_src emacs-lisp -;; Redefine the values of those three variables for the given theme -(setq modus-vivendi-theme-override-colors-alist - '(("magenta" . "#ffaabb") - ("magenta-alt" . "#ee88ff") - ("magenta-alt-other" . "#bbaaff"))) +(set-face-attribute 'bold nil :weight 'semibold) #+end_src -If you want to be creative, you can define a minor mode that refashions -the themes on demand. The following is a minor mode that gets activated -on demand. We combine it with the function to switch between Modus -Operandi and Modus Vivendi (see [[#h:2a0895a6-3281-4e55-8aa1-8a737555821e][Toggle between the themes on demand]] for -a basic command, and/or [[*Configure options prior to loading][Configure options prior to loading]] for a more -comprehensive setup). +Remember to use the custom function and hook combo we demonstrated +above. Because the themes do not hard-wire a specific weight, this +simple form is enough to change the weight of all bold constructs +throughout the interface. + +Finally, there are cases where you want to tweak colors though wish to +apply different ones to each theme, say, a blue hue for Modus Operandi +and a shade of red for Modus Vivendi. To this end, we provide +~modus-themes-color-alts~ as a convenience function to save you from the +trouble of writing separate wrappers for each theme. It still returns a +single value by querying either of ~modus-themes-operandi-colors~ and +~modus-themes-vivendi-colors~, only here you pass the two keys you want, +first for ~modus-operandi~ then ~modus-vivendi~. + +Take the previous example with the ~cursor~ face: #+begin_src emacs-lisp -(define-minor-mode modus-themes-alt-mode - "Override Modus themes' palette variables with custom values. +;; Blue for `modus-operandi' and red for `modus-vivendi' +(set-face-attribute 'cursor nil :background (modus-themes-color-alts 'blue 'red)) +#+end_src -This is intended as a proof-of-concept. It is, nonetheless, a -perfectly accessible alternative, conforming with the design -principles of the Modus themes. It still is not as good as the -default colors." +** Face specs at scale using the themes' palette (DIY) +:properties: +:custom_id: h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae +:end: +#+findex: modus-themes-with-colors +#+cindex: Extracting colors en masse + +The examples here are for large scale operations. For simple, one-off +tweaks, you may prefer the approach documented in the previous section +([[#h:1487c631-f4fe-490d-8d58-d72ffa3bd474][Case-by-case face specs using the themes' palette]]). + +The ~modus-themes-with-colors~ macro lets you retrieve multiple color +values by employing the backquote/backtick and comma notation. The +values are stored in the alists ~modus-themes-operandi-colors~ and +~modus-themes-vivendi-colors~, while the macro always queries that of the +active Modus theme. + +Here is an abstract example that just returns a list of color values +while ~modus-operandi~ is enabled: + +#+begin_src emacs-lisp +(modus-themes-with-colors + (list fg-main + blue-faint + magenta + magenta-alt-other + cyan-alt-other + fg-special-cold + blue-alt + magenta-faint + cyan + fg-main + green-faint + red-alt-faint + blue-alt-faint + fg-special-warm + cyan-alt + blue)) +;; => +;; ("#000000" "#002f88" "#721045" "#5317ac" +;; "#005a5f" "#093060" "#2544bb" "#752f50" +;; "#00538b" "#000000" "#104410" "#702f00" +;; "#003f78" "#5d3026" "#30517f" "#0031a9") +#+end_src + +Getting a list of colors may have its applications, though what you are +most likely interested in is how to use those variables to configure +several faces at once. To do so we can rely on the built-in +~custom-set-faces~ function, which sets face specifications for the +special =user= theme. That "theme" gets applied on top of regular themes +like ~modus-operandi~ and ~modus-vivendi~. + +This is how it works: + +#+begin_src emacs-lisp +(modus-themes-with-colors + (custom-set-faces + `(cursor ((,class :background ,blue))) + `(mode-line ((,class :background ,yellow-nuanced-bg + :foreground ,yellow-nuanced-fg))) + `(mode-line-inactive ((,class :background ,blue-nuanced-bg + :foreground ,blue-nuanced-fg))))) +#+end_src + +The above snippet will immediately refashion the faces it names once it +is evaluated. However, if you switch between the Modus themes, say, +from ~modus-operandi~ to ~modus-vivendi~, the colors will not get updated to +match those of the new theme. To make things work across the themes, we +need to employ the same technique we discussed in the previous section, +namely, to pass our changes at the post-theme-load phase via a hook. + +The themes provide the ~modus-themes-after-load-theme-hook~, which gets +called from ~modus-themes-load-operandi~, ~modus-themes-load-vivendi~, as +well as the command ~modus-themes-toggle~. With this knowledge, you can +wrap the macro in a function and then assign that function to the hook. +Thus: + +#+begin_src emacs-lisp +(defun my-modus-themes-custom-faces () + (modus-themes-with-colors + (custom-set-faces + `(cursor ((,class :background ,blue))) + `(mode-line ((,class :background ,yellow-nuanced-bg + :foreground ,yellow-nuanced-fg))) + `(mode-line-inactive ((,class :background ,blue-nuanced-bg + :foreground ,blue-nuanced-fg)))))) + +(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces) +#+end_src + +[[#h:86f6906b-f090-46cc-9816-1fe8aeb38776][A theme-agnostic hook for theme loading]]. + +To discover the faces defined by all loaded libraries, you may do +{{{kbd(M-x list-faces-display)}}}. Be warned that when you =:inherit= a face +you are introducing an implicit dependency, so try to avoid doing so for +libraries other than the built-in {{{file(faces.el)}}} (or at least understand +that things may break if you inherit from a yet-to-be-loaded face). + +Also bear in mind that these examples are meant to work with the Modus +themes. If you are cycling between multiple themes you may encounter +unforeseen issues, such as the colors of the Modus themes being applied +to a non-Modus item. + +Finally, note that you can still use other functions where those make +sense. For example, the ~modus-themes-color-alts~ that was discussed in +the previous section. Adapt the above example like this: + +#+begin_src emacs-lisp +... +(modus-themes-with-colors + (custom-set-faces + `(cursor ((,class :background ,(modus-themes-color-alts 'blue 'green)))) + ...)) +#+end_src + +** Override colors (DIY) +:properties: +:custom_id: h:307d95dd-8dbd-4ece-a543-10ae86f155a6 +:end: +#+vindex: modus-themes-operandi-color-overrides +#+vindex: modus-themes-vivendi-color-overrides +#+cindex: Change a theme's colors + +The themes provide a mechanism for overriding their color values. This +is controlled by the variables ~modus-themes-operandi-color-overrides~ and +~modus-themes-vivendi-color-overrides~, which are alists that should +mirror a subset of the associations in ~modus-themes-operandi-colors~ and +~modus-themes-vivendi-colors~ respectively. As with all customisations, +overriding must be done before loading the affected theme. + +Let us approach the present topic one step at a time. Here is a +simplified excerpt of the default palette for Modus Operandi with some +basic background values that apply to buffers and the mode line +(remember to inspect the actual value to find out all the associations +that can be overridden): + +#+begin_src emacs-lisp +(defconst modus-themes-colors-operandi + '((bg-main . "#ffffff") + (bg-dim . "#f8f8f8") + (bg-alt . "#f0f0f0") + (bg-active . "#d7d7d7") + (bg-inactive . "#efefef"))) +#+end_src + +As one can tell, we bind a key to a hexadecimal RGB color value. Now +say we wish to override those specific values and have our changes +propagate to all faces that use those keys. We could write something +like this, which adds a subtle ochre tint: + +#+begin_src emacs-lisp +(setq modus-themes-operandi-color-overrides + '((bg-main . "#fefcf4") + (bg-dim . "#faf6ef") + (bg-alt . "#f7efe5") + (bg-active . "#e8dfd1") + (bg-inactive . "#f6ece5"))) +#+end_src + +Once this is evaluated, any subsequent loading of ~modus-operandi~ will +use those values instead of the defaults. No further intervention is +required. + +To reset the changes, we apply this and reload the theme: + +#+begin_src emacs-lisp +(setq modus-themes-operandi-color-overrides nil) +#+end_src + +Users who wish to leverage such a mechanism can opt to implement it +on-demand by means of a global minor mode. The following snippet covers +both themes and expands to some more assosiations in the palette: + +#+begin_src emacs-lisp +(define-minor-mode my-modus-themes-tinted + "Tweak some Modus themes colors." :init-value nil :global t - (if modus-themes-alt-mode - (setq modus-operandi-theme-override-colors-alist - '(("bg-main" . "#fefcf4") - ("bg-dim" . "#faf6ef") - ("bg-alt" . "#f7efe5") - ("bg-hl-line" . "#f4f0e3") - ("bg-active" . "#e8dfd1") - ("bg-inactive" . "#f6ece5") - ("bg-region" . "#c6bab1") - ("bg-header" . "#ede3e0") - ("bg-tab-bar" . "#dcd3d3") - ("bg-tab-active" . "#fdf6eb") - ("bg-tab-inactive" . "#c8bab8") - ("fg-unfocused" . "#55556f")) - modus-vivendi-theme-override-colors-alist - '(("bg-main" . "#100b17") - ("bg-dim" . "#161129") - ("bg-alt" . "#181732") - ("bg-hl-line" . "#191628") - ("bg-active" . "#282e46") - ("bg-inactive" . "#1a1e39") - ("bg-region" . "#393a53") - ("bg-header" . "#202037") - ("bg-tab-bar" . "#262b41") - ("bg-tab-active" . "#120f18") - ("bg-tab-inactive" . "#3a3a5a") - ("fg-unfocused" . "#9a9aab"))) - (setq modus-operandi-theme-override-colors-alist nil - modus-vivendi-theme-override-colors-alist nil))) - -(defun modus-themes-toggle (&optional arg) - "Toggle between `modus-operandi' and `modus-vivendi' themes. - -With optional \\[universal-argument] prefix, enable -`modus-themes-alt-mode' for the loaded theme." - (interactive "P") - (if arg - (modus-themes-alt-mode 1) - (modus-themes-alt-mode -1)) - (if (eq (car custom-enabled-themes) 'modus-operandi) - (progn - (disable-theme 'modus-operandi) - (load-theme 'modus-vivendi t)) - (disable-theme 'modus-vivendi) - (load-theme 'modus-operandi t))) + (if my-modus-themes-tinted + (setq modus-themes-operandi-color-overrides + '((bg-main . "#fefcf4") + (bg-dim . "#faf6ef") + (bg-alt . "#f7efe5") + (bg-hl-line . "#f4f0e3") + (bg-active . "#e8dfd1") + (bg-inactive . "#f6ece5") + (bg-region . "#c6bab1") + (bg-header . "#ede3e0") + (bg-tab-bar . "#dcd3d3") + (bg-tab-active . "#fdf6eb") + (bg-tab-inactive . "#c8bab8") + (fg-unfocused . "#55556f")) + modus-themes-vivendi-color-overrides + '((bg-main . "#100b17") + (bg-dim . "#161129") + (bg-alt . "#181732") + (bg-hl-line . "#191628") + (bg-active . "#282e46") + (bg-inactive . "#1a1e39") + (bg-region . "#393a53") + (bg-header . "#202037") + (bg-tab-bar . "#262b41") + (bg-tab-active . "#120f18") + (bg-tab-inactive . "#3a3a5a") + (fg-unfocused . "#9a9aab"))) + (setq modus-themes-operandi-color-overrides nil + modus-themes-vivendi-color-overrides nil))) #+end_src -** Font configurations for Org (and others) -:PROPERTIES: -:ALT_TITLE: Font configs (DIY) -:DESCRIPTION: Optimise for mixed typeface buffers -:CUSTOM_ID: h:defcf4fc-8fa8-4c29-b12e-7119582cc929 -:END: +With this in place, one can invoke {{{kbd(M-x my-modus-themes-tinted)}}} and +then load the Modus theme of their choice. The new palette subset will +come into effect: subtle ochre tints for Modus Operandi and night sky +shades for Modus Vivendi. Switching between the two themes, such as +with {{{kbd(M-x modus-themes-toggle)}}} will also use the overrides. + +Given that this is a user-level customisation, one is free to implement +whatever color values they desire, even if the possible combinations +fall below the minimum 7:1 contrast ratio that governs the design of the +themes (the WCAG AAA legibility standard). Preferences aside, it is +advised to inspect the source code of ~modus-themes-operandi-colors~ and +~modus-themes-vivendi-colors~ to read the inline commentary: it explains +what the intended use of each palette subset is. -The themes are designed to cope well with mixed font settings ([[#h:115e6c23-ee35-4a16-8cef-e2fcbb08e28b][Option -for no font mixing]]). Currently this applies to =org-mode= and -=markdown-mode=. +Furthermore, users may benefit from the ~modus-themes-contrast~ function +that we provide: [[#h:02e25930-e71a-493d-828a-8907fc80f874][test color combinations]]. It measures the contrast +ratio between two color values, so it can help in overriding the palette +(or a subset thereof) without making the end result inaccessible. + +** Font configurations for Org and others (DIY) +:properties: +:custom_id: h:defcf4fc-8fa8-4c29-b12e-7119582cc929 +:end: +#+cindex: Font configurations + +The themes are designed to cope well with mixed font configurations. + +[[#h:115e6c23-ee35-4a16-8cef-e2fcbb08e28b][Option for no font mixing]]. + +This mostly concerns ~org-mode~ and ~markdown-mode~, though expect to find +it elsewhere like in ~Info-mode~. In practice it means that the user can safely opt for a more prose-friendly proportionately spaced typeface as their default, while letting spacing-sensitive elements like tables and inline code always -use a monospaced font, by inheriting from the =fixed-pitch= face. +use a monospaced font, by inheriting from the ~fixed-pitch~ face. -Users can try the built-in =M-x variable-pitch-mode= to see the effect in -action. +Users can try the built-in {{{kbd(M-x variable-pitch-mode)}}} to see the +effect in action. To make everything use your desired font families, you need to configure -the =variable-pitch= (proportional spacing) and =fixed-pitch= (monospaced) +the ~variable-pitch~ (proportional spacing) and ~fixed-pitch~ (monospaced) faces respectively. It may also be convenient to set your main typeface -by configuring the =default= face the same way. +by configuring the ~default~ face the same way. -Put something like this in your initialization file (make sure to read -the documentation of =set-face-attribute=, with =M-x describe-function=): +Put something like this in your initialization file (also consider +reading the doc string of ~set-face-attribute~): #+begin_src emacs-lisp ;; Main typeface @@ -1199,50 +1682,35 @@ the documentation of =set-face-attribute=, with =M-x describe-function=): Note the differences in the =:height= property. The =default= face must specify an absolute value, which is the point size × 10. So if you want -to use a font at point size =11=, you set the height at =110=.[fn:: =:height= +to use a font at point size =11=, you set the height to =110=.[fn:: =:height= values do not need to be rounded to multiples of ten: the likes of =115= are perfectly valid—some typefaces will change to account for those finer increments.] Whereas every other face must have a value that is relative to the default, represented as a floating point (if you use an -integer, say, =15= then that means an absolute height). This is of -paramount importance: it ensures that all fonts can scale gracefully -when using something like the =text-scale-adjust= command which only -operates on the base font size (i.e. the =default= face's absolute -height). - -An alternative syntax for the =default= face, is to pass all typeface -parameters directly to a =font= property.[fn:: Has the benefit of -accepting =fontconfig= parameters (GNU/Linux), such as ="DejaVu Sans -Mono-11:hintstyle=hintslight:autohint=false"=. -https://www.freedesktop.org/software/fontconfig/fontconfig-user.html] -Note that here we use a standard point size: - -#+begin_src emacs-lisp -(set-face-attribute 'default nil :font "DejaVu Sans Mono-11") -#+end_src - -Again, remember to only ever specify an absolute height for the =default=. - -** Org user faces (DIY) -:PROPERTIES: -:DESCRIPTION: Extend styles for org-mode keywords and priorities -:CUSTOM_ID: h:89f0678d-c5c3-4a57-a526-668b2bb2d7ad -:END: - -Users of =org-mode= have the option to configure various keywords and +integer, then that means an absolute height). This is of paramount +importance: it ensures that all fonts can scale gracefully when using +something like the ~text-scale-adjust~ command which only operates on the +base font size (i.e. the ~default~ face's absolute height). + +** Custom Org user faces (DIY) +:properties: +:custom_id: h:89f0678d-c5c3-4a57-a526-668b2bb2d7ad +:end: +#+cindex: Org extra faces + +Users of ~org-mode~ have the option to configure various keywords and priority cookies to better match their workflow. User options are -=org-todo-keyword-faces= and =org-priority-faces=. +~org-todo-keyword-faces~ and ~org-priority-faces~. -As those are meant to be custom faces, it would be futile to have the -themes try to guess what each user would want to use, which keywords to -target, and so on. Instead, we can provide guidelines on how to -customize things to one's liking with the intent of retaining the -overall aesthetics of the theme. +As those are meant to be custom faces, it is futile to have the themes +guess what each user wants to use, which keywords to target, and so on. +Instead, we can provide guidelines on how to customize things to one's +liking with the intent of retaining the overall aesthetic of the themes. Please bear in mind that the end result of those is not controlled by -the active theme but by how Org maps faces to its constructs. Editing -those while =org-mode= is active requires =M-x org-mode-restart= for changes -to take effect. +the active Modus theme but by how Org maps faces to its constructs. +Editing those while ~org-mode~ is active requires re-initialization of the +mode with {{{kbd(M-x org-mode-restart)}}} for changes to take effect. Let us assume you wish to visually differentiate your keywords. You have something like this: @@ -1257,7 +1725,7 @@ have something like this: You could then use a variant of the following to inherit from a face that uses the styles you want and also to preserve the properties -applied by the =org-todo= face: +applied by the ~org-todo~ face: #+begin_src emacs-lisp (setq org-todo-keyword-faces @@ -1267,10 +1735,10 @@ applied by the =org-todo= face: #+end_src This will refashion the keywords you specify, while letting the other -items in =org-todo-keywords= use their original styles (which are defined -in the =org-todo= and =org-done= faces). +items in ~org-todo-keywords~ use their original styles (which are defined +in the ~org-todo~ and ~org-done~ faces). -If you want back the defaults, try specifying just the =org-todo= face: +If you want back the defaults, try specifying just the ~org-todo~ face: #+begin_src emacs-lisp (setq org-todo-keyword-faces @@ -1282,7 +1750,7 @@ If you want back the defaults, try specifying just the =org-todo= face: When you inherit from multiple faces, you need to quote the list as shown further above. The order is important: the last item is applied over the previous ones. If you do not want to blend multiple faces, you -do not need a quoted list. A pattern of =keyword . face= would suffice. +do not need a quoted list. A pattern of =keyword . face= will suffice. Both approaches can be used simultaneously, as illustrated in this configuration of the priority cookies: @@ -1295,29 +1763,182 @@ configuration of the priority cookies: #+end_src To find all the faces that are loaded in your current Emacs session, use -=M-x list-faces-display=. Also try =M-x describe-variable= and then specify -the name of each of those Org variables demonstrated above. Their -documentation strings will offer you further guidance. +{{{kbd(M-x list-faces-display)}}}. Try {{{kbd(M-x describe-variable)}}} as well and +then specify the name of each of those Org variables demonstrated above. +Their documentation strings will offer you further guidance. + +Recall that the themes let you retrieve a color from their palette. Do +it if you plan to control face attributes. + +[[#h:1487c631-f4fe-490d-8d58-d72ffa3bd474][Custom face specs using the themes' palette]]. + +[[#h:02e25930-e71a-493d-828a-8907fc80f874][Check color combinations]]. + +** Measure color contrast (DIY) +:properties: +:custom_id: h:02e25930-e71a-493d-828a-8907fc80f874 +:end: +#+findex: modus-themes-contrast +#+findex: modus-themes-wcag-formula +#+cindex: Color contrast + +The themes provide the functions ~modus-themes-wcag-formula~ and +~modus-themes-contrast~. The former is a direct implementation of the +WCAG formula: . It +calculates the relative luminance of a color value that is expressed in +hexadecimal RGB notation. While the latter function is just a +convenient wrapper for comparing the relative luminance between two +colors. + +In practice, one needs to work only with ~modus-themes-contrast~. It +accepts two color values and returns their contrast ratio. Values range +from 1 to 21 (lowest to highest). The themes are designed to always be +equal or higher than 7 for each combination of background and foreground +that they use (this is the WCAG AAA standard---the most demanding of its +kind). + +A couple of examples (rounded numbers): -Furthermore, consider reading the "Notes for aspiring Emacs theme -developers", published on 2020-08-28 by me (Protesilaos Stavrou): -https://protesilaos.com/codelog/2020-08-28-notes-emacs-theme-devs/. +#+begin_src emacs-lisp +;; Pure white with pure green +(modus-themes-contrast "#ffffff" "#00ff00") +;; => 1.37 +;; That is an outright inaccessible combo + +;; Pure black with pure green +(modus-themes-contrast "#000000" "#00ff00") +;; => 15.3 +;; That is is a highly accessible combo +#+end_src + +It does not matter which color value comes first. The ratio is always +the same. + +If one does not wish to read all the decimal points, it is possible to +try something like this: + +#+begin_src emacs-lisp +(format "%0.2f" (modus-themes-contrast "#000000" "#00ff00")) +#+end_src + +While it is fine to perform such calculations on a case-by-case basis, +it is preferable to implement formulas and tables for more demanding +tasks. Such instruments are provided by ~org-mode~ or ~orgtbl-mode~, both +of which are built into Emacs. Below is such a table that derives the +contrast ratio of all colors in the first column (pure red, green, blue) +relative to the color specified in the first row of the second column +(pure white) and rounds the results: + +#+begin_example +| | #ffffff | +|---------+---------| +| #ff0000 | 4.00 | +| #00ff00 | 1.37 | +| #0000ff | 8.59 | +#+tblfm: $2='(modus-themes-contrast $1 @1$2);%0.2f +#+end_example + +To measure color contrast one needs to start from a known value. This +typically is the background. The Modus themes define an expanded +palette in large part because certain colors are only meant to be used +in combination with some others. Consult the source code for the +minutia and relevant commentary. + +Such knowledge may prove valuable while attempting to override some of +the themes' colors: [[#h:307d95dd-8dbd-4ece-a543-10ae86f155a6][Override colors]]. + +** Load theme depending on time of day +:properties: +:custom_id: h:1d1ef4b4-8600-4a09-993c-6de3af0ddd26 +:end: + +While we do provide ~modus-themes-toggle~ to manually switch between the +themes, users may also set up their system to perform such a task +automatically at sunrise and sunset. + +This can be accomplished by specifying the coordinates of one's location +using the built-in {{{file(solar.el)}}} and then configuring the =circadian= +package: + +#+begin_src emacs-lisp +(use-package solar ; built-in + :config + (setq calendar-latitude 35.17 + calendar-longitude 33.36)) + +(use-package circadian ; you need to install this + :ensure + :after solar + (setq circadian-themes '((:sunrise . modus-operandi) + (:sunset . modus-vivendi))) + (circadian-setup)) +#+end_src + +** A theme-agnostic hook for theme loading (DIY) +:properties: +:custom_id: h:86f6906b-f090-46cc-9816-1fe8aeb38776 +:end: + +The themes are designed with the intent to be useful to Emacs users of +varying skill levels, from beginners to experts. This means that we try +to make things easier by not expecting anyone reading this document to +be proficient in Emacs Lisp or programming in general. + +Such a case is with the use of the ~modus-themes-after-load-theme-hook~, +which runs after ~modus-themes-toggle~, ~modus-themes-load-operandi~, or +~modus-themes-load-vivendi~ is evaluated. We recommend using that hook +for advanced customizations, because (1) we know for sure that it is +available once the themes are loaded, and (2) anyone consulting this +manual, especially the sections on enabling and loading the themes, will +be in a good position to benefit from that hook. + +Advanced users who have a need to switch between the Modus themes and +other items will find that such a hook does not meet their requirements: +it only works with the Modus themes and only with the aforementioned +functions. + +A theme-agnostic setup can be configured thus: + +#+begin_src emacs-lisp +(defvar after-enable-theme-hook nil + "Normal hook run after enabling a theme.") + +(defun run-after-enable-theme-hook (&rest _args) + "Run `after-enable-theme-hook'." + (run-hooks 'after-enable-theme-hook)) + +(advice-add 'enable-theme :after #'run-after-enable-theme-hook) +#+end_src + +This creates the ~after-enable-theme-hook~ and makes it run after each +call to ~enable-theme~, which means that it will work for all themes and +also has the benefit that it does not depend on functions such as +~modus-themes-toggle~ and the others mentioned above. ~enable-theme~ is +called internally by ~load-theme~, so the hook works everywhere. + +Now this specific piece of Elisp may be simple for experienced users, +but it is not easy to read for newcomers, including the author of the +Modus themes for the first several months of their time as an Emacs +user. Hence our hesitation to recommend it as part of the standard +setup of the Modus themes (it is generally a good idea to understand +what the implications are of advising a function). * Face coverage -:PROPERTIES: -:CUSTOM_ID: h:a9c8f29d-7f72-4b54-b74b-ddefe15d6a19 -:END: +:properties: +:custom_id: h:a9c8f29d-7f72-4b54-b74b-ddefe15d6a19 +:end: -Modus Operandi and Modus Vivendi try to provide as close to full face -coverage as possible. This is necessary to ensure a consistently -accessible reading experience across all possible interfaces. +The Modus themes try to provide as close to full face coverage as +possible. This is necessary to ensure a consistently accessible reading +experience across all available interfaces. ** Full support for packages or face groups -:PROPERTIES: -:ALT_TITLE: Supported packages -:DESCRIPTION: Full list of covered face groups -:CUSTOM_ID: h:60ed4275-60d6-49f8-9287-9a64e54bea0e -:END: +:properties: +:alt_title: Supported packages +:description: Full list of covered face groups +:custom_id: h:60ed4275-60d6-49f8-9287-9a64e54bea0e +:end: +#+cindex: Explicitly supported packages This list will always be updated to reflect the current state of the project. The idea is to offer an overview of the known status of all @@ -1337,16 +1958,18 @@ have lots of extensions, so the "full support" may not be 100% true… + auto-dim-other-buffers + avy + awesome-tray ++ bbdb + binder + bm + bongo + boon -+ breakpoint (provided by the built-in =gdb-mi.el= library) ++ breakpoint (provided by the built-in {{{file(gdb-mi.el)}}} library) + buffer-expose + calendar and diary + calfw + centaur-tabs -+ change-log and log-view (such as =vc-print-log= and =vc-print-root-log=) ++ cfrs ++ change-log and log-view (such as ~vc-print-log~, ~vc-print-root-log~) + cider + circe + color-rg @@ -1355,6 +1978,7 @@ have lots of extensions, so the "full support" may not be 100% true… + company-posframe + compilation-mode + completions ++ consult + counsel* + counsel-css + counsel-notmuch @@ -1363,7 +1987,7 @@ have lots of extensions, so the "full support" may not be 100% true… + cperl-mode + csv-mode + ctrlf -+ custom (=M-x customize=) ++ custom (what you get with {{{kbd(M-x customize)}}}) + dap-mode + dashboard (emacs-dashboard) + deadgrep @@ -1381,8 +2005,11 @@ have lots of extensions, so the "full support" may not be 100% true… + dired-git-info + dired-narrow + dired-subtree ++ diredc + diredfl ++ diredp (dired+) + disk-usage ++ display-fill-column-indicator-mode + doom-modeline + dynamic-ruler + easy-jekyll @@ -1408,8 +2035,10 @@ have lots of extensions, so the "full support" may not be 100% true… + eshell-syntax-highlighting + evil* (evil-mode) + evil-goggles ++ evil-snipe + evil-visual-mark-mode + eww ++ exwm + eyebrowse + fancy-dabbrev + flycheck @@ -1443,7 +2072,7 @@ have lots of extensions, so the "full support" may not be 100% true… + helpful + highlight-blocks + highlight-defined -+ highlight-escape-sequences (=hes-mode=) ++ highlight-escape-sequences (~hes-mode~) + highlight-indentation + highlight-numbers + highlight-symbol @@ -1468,6 +2097,7 @@ have lots of extensions, so the "full support" may not be 100% true… + interaction-log + ioccur + isearch, occur, etc. ++ isl (isearch-light) + ivy* + ivy-posframe + jira (org-jira) @@ -1477,19 +2107,22 @@ have lots of extensions, so the "full support" may not be 100% true… + jupyter + kaocha-runner + keycast -+ line numbers (=display-line-numbers-mode= and global variant) ++ line numbers (~display-line-numbers-mode~ and global variant) + lsp-mode + lsp-ui ++ macrostep + magit + magit-imerge + make-mode + man ++ marginalia + markdown-mode -+ markup-faces (=adoc-mode=) ++ markup-faces (~adoc-mode~) + mentor + messages + minibuffer-line + minimap ++ mmm-mode + modeline + mood-line + moody @@ -1512,11 +2145,12 @@ have lots of extensions, so the "full support" may not be 100% true… + org-roam + org-superstar + org-table-sticky-header ++ org-tree-slide + org-treescope + origami + outline-mode + outline-minor-faces -+ package (=M-x list-packages=) ++ package (what you get with {{{kbd(M-x list-packages)}}}) + page-break-lines + paradox + paren-face @@ -1532,23 +2166,28 @@ have lots of extensions, so the "full support" may not be 100% true… + popup + powerline + powerline-evil ++ prism ([[#h:a94272e0-99da-4149-9e80-11a7e67a2cf2][Note for prism.el]]) + proced + prodigy ++ quick-peek + racket-mode + rainbow-blocks + rainbow-identifiers + rainbow-delimiters + rcirc -+ regexp-builder (also known as =re-builder=) ++ recursion-indicator ++ regexp-builder (also known as ~re-builder~) + rg (rg.el) + ripgrep + rmail + ruler-mode + sallet + selectrum ++ selectrum-prescient + semantic + sesman + shell-script-mode ++ shortdoc + show-paren-mode + shr + side-notes @@ -1557,9 +2196,11 @@ have lots of extensions, so the "full support" may not be 100% true… + smart-mode-line + smartparens + smerge ++ solaire + spaceline + speedbar + spell-fu ++ spray + stripes + suggest + switch-window @@ -1570,6 +2211,7 @@ have lots of extensions, so the "full support" may not be 100% true… + syslog-mode + table (built-in table.el) + telephone-line ++ terraform-mode + term + tomatinho + transient (pop-up windows such as Magit's) @@ -1580,7 +2222,7 @@ have lots of extensions, so the "full support" may not be 100% true… + typescript + undo-tree + vc (built-in mode line status for version control) -+ vc-annotate (=C-x v g=) ++ vc-annotate (the out put of {{{kbd(C-x v g)}}}) + vdiff + vimish-fold + visible-mark @@ -1608,67 +2250,234 @@ Plus many other miscellaneous faces that are provided by the upstream GNU Emacs distribution. ** Indirectly covered packages -:PROPERTIES: -:CUSTOM_ID: h:2cb359c7-3a84-4262-bab3-dcdc1d0034d7 -:END: +:properties: +:custom_id: h:2cb359c7-3a84-4262-bab3-dcdc1d0034d7 +:end: +#+cindex: Implicitly supported packages These do not require any extra styles because they are configured to inherit from some basic faces. Please confirm. + edit-indirect + evil-owl ++ fortran-mode ++ goggles + i3wm-config-mode + perl-mode + php-mode + rjsx-mode + swift-mode - -** Will NOT be supported -:PROPERTIES: -:CUSTOM_ID: h:6c6e8d94-6782-47fc-9eef-ad78671e9eea -:END: - -I have thus far identified a single package that does fit into the -overarching objective of this project: [[https://github.com/hlissner/emacs-solaire-mode][solaire]]. It basically tries to -cast a less intense background on the main file-visiting buffers, so -that secondary elements like sidebars can have the default (pure -white/black) background. - -I will only cover this package if it ever supports the inverse effect: -less intense colors (but still accessible) for ancillary interfaces -and the intended styles for the content you are actually working on. ++ tab-bar-echo-area * Notes for individual packages -:PROPERTIES: -:CUSTOM_ID: h:4c4d901a-84d7-4f20-bd99-0808c2b06eba -:END: +:properties: +:custom_id: h:4c4d901a-84d7-4f20-bd99-0808c2b06eba +:end: This section covers information that may be of interest to users of individual packages. +** Note for display-fill-column-indicator-mode +:properties: +:custom_id: h:2a602816-bc1b-45bf-9675-4cbbd7bf6cab +:end: + +While designing the style for ~display-fill-column-indicator-mode~, we +stayed close to the mode's defaults: to apply a subtle foreground color +to the ~fill-column-indicator~ face, which blends well with the rest of +theme and is consistent with the role of that mode. This is to not +upset the expectations of users. + +Nevertheless, ~display-fill-column-indicator-mode~ has some known +limitations pertaining to its choice of using typographic characters to +draw its indicator. What should be a continuous vertical line might +appear as a series of dashes in certain contexts or under specific +conditions: a non-default value for ~line-spacing~, scaled and/or +variable-pitch headings have been observed to cause this effect. + +Given that we cannot control such factors, it may be better for affected +users to deviate from the default style of the ~fill-column-indicator~ +face. Instead of setting a foreground color, one could use a background +and have the foreground be indistinguishable from it. For example: + +#+begin_src emacs-lisp +(modus-themes-with-colors + (custom-set-faces + `(fill-column-indicator ((,class :background ,bg-inactive + :foreground ,bg-inactive))))) +#+end_src + +[[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]]. + +** Note for mmm-mode.el background colors +:properties: +:custom_id: h:99cf0d6c-e478-4e26-9932-3bf3427d13f6 +:end: + +The faces used by {{{file(mmm-mode.el)}}} are expected to have a colorful +background, while they should not touch any foreground value. The idea +is that they must not interfere with existing fontification. Those +background colors need to be distinct from each other, such as an +unambiguous red juxtaposed with a clear blue. + +While this design may be internally consistent with the raison d'être of +that library, it inevitably produces inaccessible color combinations. + +There are two competing goals at play: + +1. Legibility of the text, understood as the contrast ratio between the + background and the foreground. + +2. Semantic precision of each face which entails faithfulness to + color-coding of the underlying background. + +As the Modus themes are designed with the express purpose of conforming +with the first point, we have to forgo the apparent color-coding of the +background elements. Instead we use subtle colors that do not undermine +the legibility of the affected text while they still offer a sense of +added context. + +Users who might prefer to fall below the minimum 7:1 contrast ratio in +relative luminance (the accessibility target we conform with), can opt +to configure the relevant faces on their own. + +[[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]]. + +This example uses more vivid background colors, though it comes at the +very high cost of degraded legibility. + +#+begin_src emacs-lisp +(modus-themes-with-colors + (custom-set-faces + `(mmm-cleanup-submode-face ((,class :background ,yellow-refine-bg))) + `(mmm-code-submode-face ((,class :background ,bg-active))) + `(mmm-comment-submode-face ((,class :background ,blue-refine-bg))) + `(mmm-declaration-submode-face ((,class :background ,cyan-refine-bg))) + `(mmm-default-submode-face ((,class :background ,bg-alt))) + `(mmm-init-submode-face ((,class :background ,magenta-refine-bg))) + `(mmm-output-submode-face ((,class :background ,red-refine-bg))) + `(mmm-special-submode-face ((,class :background ,green-refine-bg))))) +#+end_src + +** Note for prism.el +:properties: +:alt_title: Note for prism +:custom_id: h:a94272e0-99da-4149-9e80-11a7e67a2cf2 +:end: + +This package by Adam Porter, aka "alphapapa" or "github-alphapapa", +implements an alternative to the typical coloration of code. Instead of +highlighting the syntactic constructs, it applies color to different +levels of depth in the code structure. + +As {{{file(prism.el)}}} offers a broad range of customisations, we cannot +style it directly at the theme level: that would run contrary to the +spirit of the package. Instead, we may offer preset color schemes. +Those should offer a starting point for users to adapt to their needs. + +In the following code snippets, we employ the ~modus-themes-with-colors~ +macro: [[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]]. + +These are the minimum recommended settings with 16 colors: + +#+begin_src emacs-lisp +(setq prism-num-faces 16) + +(prism-set-colors + :desaturations '(0) ; do not change---may lower the contrast ratio + :lightens '(0) ; same + :colors (modus-themes-with-colors + (list fg-main + magenta + cyan-alt-other + magenta-alt-other + blue + magenta-alt + cyan-alt + red-alt-other + green + fg-main + cyan + yellow + blue-alt + red-alt + green-alt-other + fg-special-warm))) +#+end_src + +With 8 colors: + +#+begin_src emacs-lisp +(setq prism-num-faces 8) + +(prism-set-colors + :desaturations '(0) ; do not change---may lower the contrast ratio + :lightens '(0) ; same + :colors (modus-themes-with-colors + (list fg-special-cold + magenta + magenta-alt-other + cyan-alt-other + fg-main + blue-alt + red-alt-other + cyan))) +#+end_src + +And this is with 4 colors, which produces results that are the closest +to the themes' default aesthetic: + +#+begin_src emacs-lisp +(setq prism-num-faces 4) + +(prism-set-colors + :desaturations '(0) ; do not change---may lower the contrast ratio + :lightens '(0) ; same + :colors (modus-themes-with-colors + (list fg-main + cyan-alt-other + magenta-alt-other + magenta))) +#+end_src + +If you need to apply desaturation and lightening, you can use what the +{{{file(prism.el)}}} documentation recommends, like this (adapting to the +examples with the 4, 8, 16 colors): + +#+begin_src emacs-lisp +(prism-set-colors + :desaturations (cl-loop for i from 0 below 16 collect (* i 2.5)) + :lightens (cl-loop for i from 0 below 16 collect (* i 2.5)) + :colors (modus-themes-with-colors + (list fg-main + cyan-alt-other + magenta-alt-other + magenta))) +#+end_src + ** Note on company-mode overlay pop-up -:PROPERTIES: -:CUSTOM_ID: h:20cef8c4-d11f-4053-8b2c-2872925780b1 -:END: +:properties: +:custom_id: h:20cef8c4-d11f-4053-8b2c-2872925780b1 +:end: -By default, the =company-mode= pop-up that lists completion candidates is +By default, the ~company-mode~ pop-up that lists completion candidates is drawn using an overlay. This creates alignment issues every time it is placed above a piece of text that has a different height than the default. The solution recommended by the project's maintainer is to use an -alternative front-end for drawing the pop-up which uses child frames +alternative front-end for drawing the pop-up which draws child frames instead of overlays.[fn:: https://github.com/company-mode/company-mode/issues/1010][fn:: https://github.com/tumashu/company-posframe/] ** Note for ERC escaped color sequences -:PROPERTIES: -:CUSTOM_ID: h:98bdf319-1e32-4469-8a01-771200fba65c -:END: +:properties: +:custom_id: h:98bdf319-1e32-4469-8a01-771200fba65c +:end: -The built-in IRC client =erc= has the ability to colorise any text using -escape sequences that start with =^C= (inserted with =C-q C-c=) and are +The built-in IRC client ~erc~ has the ability to colorise any text using +escape sequences that start with =^C= (inserted with {{{kbd(C-q C-c)}}}) and are followed by a number for the foreground and background.[fn:: This page explains the basics, though it is not specific to Emacs: https://www.mirc.com/colors.html] Possible numbers are 0-15, with the @@ -1681,13 +2490,13 @@ separated by a comma. Like this =^C1,6=. The minimum setup is this: erc-interpret-mirc-color t) #+end_src -As this allows users to make arbitrary combinations, it is impossible to -guarantee a consistently high contrast ratio. All we can we do is -provide guidance on the combinations that satisfy the accessibility -standard of the themes: +As this allows users the chance to make arbitrary combinations, it is +impossible to guarantee a consistently high contrast ratio. All we can +we do is provide guidance on the combinations that satisfy the +accessibility standard of the themes: + Modus Operandi :: Use foreground color 1 for all backgrounds from - 2-15. Like so: =C-q C-c1,N= where =N= is the background. + 2-15. Like so: {{{kbd(C-q C-c1,N)}}} where =N= is the background. + Modus Vivendi :: Use foreground color 0 for all backgrounds from 2-13. Use foreground =1= for backgrounds 14, 15. @@ -1696,35 +2505,38 @@ Colors 0 and 1 are white and black respectively. So combine them together, if you must. ** Note for powerline or spaceline -:PROPERTIES: -:CUSTOM_ID: h:9130a8ba-d8e3-41be-a58b-3cb1eb7b6d17 -:END: +:properties: +:custom_id: h:9130a8ba-d8e3-41be-a58b-3cb1eb7b6d17 +:end: Both Powerline and Spaceline package users will likely need to use the -command =powerline-reset= whenever they make changes to their themes +command ~powerline-reset~ whenever they make changes to their themes and/or modeline setup. -** Note on shr colors -:PROPERTIES: -:CUSTOM_ID: h:4cc767dc-ffef-4c5c-9f10-82eb7b8921bf -:END: +** Note on SHR colors +:properties: +:custom_id: h:4cc767dc-ffef-4c5c-9f10-82eb7b8921bf +:end: -Emacs' HTML rendering mechanism (=shr=) may need explicit configuration to -respect the theme's colors instead of whatever specifications the -webpage provides. Consult =C-h v shr-use-colors=. +Emacs' HTML rendering library ({{{file(shr.el)}}}) may need explicit +configuration to respect the theme's colors instead of whatever +specifications the webpage provides. + +Consult {{{kbd(C-h v shr-use-colors)}}}. ** Note for Helm grep -:PROPERTIES: -:CUSTOM_ID: h:d28879a2-8e4b-4525-986e-14c0f873d229 -:END: +:properties: +:custom_id: h:d28879a2-8e4b-4525-986e-14c0f873d229 +:end: There is one face from the Helm package that is meant to highlight the matches of a grep or grep-like command (=ag= or =ripgrep=). It is -=helm-grep-match=. However, this face can only apply when the user does +~helm-grep-match~. However, this face can only apply when the user does not pass =--color=always= as a command-line option for their command. Here is the docstring for that face, which is defined in the -=helm-grep.el= library (view a library with =M-x find-library=). +{{{file(helm-grep.el)}}} library (you can always visit the source code with +{{{kbd(M-x find-library)}}}). #+begin_quote Face used to highlight grep matches. Have no effect when grep backend @@ -1734,23 +2546,23 @@ use "--color=" The user must either remove =--color= from the flags passed to the grep function, or explicitly use =--color=never= (or equivalent). Helm provides user-facing customization options for controlling the grep -function's parameters, such as =helm-grep-default-command= and -=helm-grep-git-grep-command=. +function's parameters, such as ~helm-grep-default-command~ and +~helm-grep-git-grep-command~. When =--color=always= is in effect, the grep output will use red text in bold letter forms to present the matching part in the list of candidates. That style still meets the contrast ratio target of >= 7:1 (accessibility standard WCAG AAA), because it draws the reference to ANSI color number 1 (red) from the already-supported array of -=ansi-color-names-vector=. +~ansi-color-names-vector~. ** Note on vc-annotate-background-mode -:PROPERTIES: -:CUSTOM_ID: h:5095cbd1-e17a-419c-93e8-951c186362a3 -:END: +:properties: +:custom_id: h:5095cbd1-e17a-419c-93e8-951c186362a3 +:end: -Due to the unique way =vc-annotate= (=C-x v g=) applies colors, support for -its background mode (=vc-annotate-background-mode=) is disabled at the +Due to the unique way ~vc-annotate~ ({{{kbd(C-x v g)}}}) applies colors, support +for its background mode (~vc-annotate-background-mode~) is disabled at the theme level. Normally, such a drastic measure should not belong in a theme: assuming @@ -1760,35 +2572,87 @@ while still supporting a useful built-in tool. If there actually is a way to avoid such a course of action, without prejudice to the accessibility standard of this project, then please -report as much or send patches (see [[#h:9c3cd842-14b7-44d7-84b2-a5c8bc3fc3b1][Contributing]]). +report as much or send patches ([[#h:9c3cd842-14b7-44d7-84b2-a5c8bc3fc3b1][Contributing]]). + +** Note on pdf-tools link hints +:properties: +:custom_id: h:2659d13e-b1a5-416c-9a89-7c3ce3a76574 +:end: + +Hints are drawn by [[https://imagemagick.org/][ImageMagick]], not Emacs, i.e., ImageMagick doesn't +know about the hint face unless you tell ImageMagick about it. By +default, only the foreground and background color attributes are +passed. The below snippet adds to those the various font attributes. As +it queries various faces, specifically ~pdf-links-read-link~ and the faces +it inherits, it needs to be added to your initialization file after +you've customized any faces. + +#+begin_src emacs-lisp +(use-package pdf-links + :config + (let ((spec + (apply #'append + (mapcar + (lambda (name) + (list name + (face-attribute 'pdf-links-read-link + name nil 'default))) + '(:family :width :weight :slant))))) + (setq pdf-links-read-link-convert-commands + `("-density" "96" + "-family" ,(plist-get spec :family) + "-stretch" ,(let* ((width (plist-get spec :width)) + (name (symbol-name width))) + (replace-regexp-in-string "-" "" + (capitalize name))) + "-weight" ,(pcase (plist-get spec :weight) + ('ultra-light "Thin") + ('extra-light "ExtraLight") + ('light "Light") + ('semi-bold "SemiBold") + ('bold "Bold") + ('extra-bold "ExtraBold") + ('ultra-bold "Black") + (_weight "Normal")) + "-style" ,(pcase (plist-get spec :slant) + ('italic "Italic") + ('oblique "Oblique") + (_slant "Normal")) + "-pointsize" "%P" + "-undercolor" "%f" + "-fill" "%b" + "-draw" "text %X,%Y '%c'")))) +#+end_src * Contributing -:PROPERTIES: -:CUSTOM_ID: h:9c3cd842-14b7-44d7-84b2-a5c8bc3fc3b1 -:END: +:properties: +:custom_id: h:9c3cd842-14b7-44d7-84b2-a5c8bc3fc3b1 +:end: This section documents the canonical sources of the themes and the ways in which you can contribute to their ongoing development. ** Sources of the themes -:PROPERTIES: -:CUSTOM_ID: h:89504f1c-c9a1-4bd9-ab39-78fd0eddb47c -:END: +:properties: +:custom_id: h:89504f1c-c9a1-4bd9-ab39-78fd0eddb47c +:end: +#+cindex: Sources of the themes -The =modus-operandi= and =modus-vivendi= themes are built into Emacs. -Currently they are in the project's =master= branch, which is tracking the -next development release target. +The ~modus-operandi~ and ~modus-vivendi~ themes are built into Emacs. +Currently they are in Emacs' git main branch (trunk), which is tracking +the next development release target. The source code of the themes is [[https://gitlab.com/protesilaos/modus-themes/][available on Gitlab]], for the time being. A [[https://github.com/protesilaos/modus-themes/][mirror on Github]] is also on offer. -An HTML version of this manual is available as an extension to the +An HTML version of this manual is provided as an extension of the [[https://protesilaos.com/modus-themes/][author's personal website]] (does not rely on any non-free code). ** Issues you can help with -:PROPERTIES: -:CUSTOM_ID: h:6536c8d5-3f98-43ab-a787-b94120e735e8 -:END: +:properties: +:custom_id: h:6536c8d5-3f98-43ab-a787-b94120e735e8 +:end: +#+cindex: Contributing A few tasks you can help with: @@ -1802,8 +2666,8 @@ A few tasks you can help with: [[#h:111773e2-f26f-4b68-8c4f-9794ca6b9633][Patches require copyright assignment to the FSF]]. -It would be great if your feedback also includes some screenshots, GIFs, -or short videos, as well as further instructions to reproduce a given +It is preferable that your feedback includes some screenshots, GIFs, or +short videos, as well as further instructions to reproduce a given setup. Though this is not a requirement. Whatever you do, bear in mind the overarching objective of the Modus @@ -1813,11 +2677,9 @@ between aesthetics and accessibility, it shall always be made in the interest of the latter. ** Patches require copyright assignment to the FSF -:PROPERTIES: -:ALT_TITLE: Merge requests -:DESCRIPTION: Legal considerations for code patches -:CUSTOM_ID: h:111773e2-f26f-4b68-8c4f-9794ca6b9633 -:END: +:properties: +:custom_id: h:111773e2-f26f-4b68-8c4f-9794ca6b9633 +:end: Code contributions are most welcome. For any major edit (more than 15 lines, or so, in aggregate per person), you need to make a copyright @@ -1875,48 +2737,58 @@ your changes? Do you attend a school which might make such a claim?] [Which files have you changed so far, and which new files have you written so far?] -Changed a couple of themes that are part of the Emacs source code: - -./etc/themes/modus-operandi-theme.el -./etc/themes/modus-vivendi-theme.el #+end_example * Acknowledgements -:PROPERTIES: -:CUSTOM_ID: h:95c3da23-217f-404e-b5f3-56c75760ebcf -:END: +:properties: +:custom_id: h:95c3da23-217f-404e-b5f3-56c75760ebcf +:end: +#+cindex: Contributors -The Modus themes are a collective effort. Every contribution counts. +The Modus themes are a collective effort. Every bit of work matters. + Author/maintainer :: Protesilaos Stavrou. + Contributions to code or documentation :: Anders Johansson, Basil - L. Contovounesios, Eli Zaretskii, Madhavan Krishnan, Markus Beppler, - Matthew Stevenson, Shreyas Ragavan, Stefan Kangas, Vincent Murphy. - -+ Ideas and user feedback :: Aaron Jensen, Adam Spiers, Alex Griffin, - Alex Peitsinis, Alexey Shmalko, Anders Johansson, André Alexandre - Gomes, Arif Rezai, Basil L. Contovounesios, Damien Cassou, Dario - Gjorgjevski, David Edmondson, Davor Rotim, Divan Santana, Gerry - Agbobada, Gianluca Recchia, Ilja Kocken, Iris Garcia, Len Trigg, - Manuel Uberti, Mark Burton, Markus Beppler, Michael Goldenberg, Murilo - Pereira, Nicolas De Jaeghere, Paul Poloskov, Pierre Téchoueyres, Roman - Rudakov, Ryan Phillips, Shreyas Ragavan, Simon Pugnet, Tassilo Horn, - Thibaut Verron, Trey Merkley, Togan Muftuoglu, Uri Sharf, Utkarsh - Singh, Vincent Foley. As well as users: Ben, Eugene, Fourchaux, - Fredrik, Moesasji, Nick, TheBlob42, bepolymathe, dinko, doolio, - jixiuf, okamsn, tycho garen. - -+ Packaging :: Dhavan Vaidya (Debian), Stefan Kangas (core Emacs), - Stefan Monnier (GNU Elpa). + L.{{{space()}}} Contovounesios, Carlo Zancanaro, Eli Zaretskii, Kostadin + Ninev, Madhavan Krishnan, Markus Beppler, Matthew Stevenson, Nicolas + De Jaeghere, Shreyas Ragavan, Stefan Kangas, Vincent Murphy, Xinglu + Chen. + ++ Ideas and user feedback :: Aaron Jensen, Adam Spiers, Adrian Manea, + Alex Griffin, Alex Peitsinis, Alexey Shmalko, Alok Singh, Anders + Johansson, André Alexandre Gomes, Arif Rezai, Basil L.{{{space()}}} + Contovounesios, Burgess Chang, Christian Tietze, Christopher Dimech, + Damien Cassou, Daniel Mendler, Dario Gjorgjevski, David Edmondson, + Davor Rotim, Divan Santana, Gerry Agbobada, Gianluca Recchia, Gustavo + Barros, Hörmetjan Yiltiz, Ilja Kocken, Iris Garcia, Jeremy Friesen, + John Haman, Joshua O'Connor, Kevin Fleming, Kostadin Ninev, Len Trigg, + Manuel Uberti, Mark Burton, Markus Beppler, Michael Goldenberg, Morgan + Smith, Murilo Pereira, Nicolas De Jaeghere, Paul Poloskov, Pete + Kazmier, Peter Wu, Philip K., Pierre Téchoueyres, Roman Rudakov, Ryan + Phillips, Sam Kleinman, Shreyas Ragavan, Simon Pugnet, Tassilo Horn, + Thibaut Verron, Trey Merkley, Togan Muftuoglu, Toon Claes, Uri Sharf, + Utkarsh Singh, Vincent Foley. As well as users: Ben, CsBigDataHub1, + Emacs Contrib, Eugene, Fourchaux, Fredrik, Moesasji, Nick, TheBlob42, + bepolymathe, doolio, fleimgruber, iSeeU, jixiuf, okamsn. + ++ Packaging :: Basil L.{{{space()}}} Contovounesios, Eli Zaretskii, Glenn + Morris, Mauro Aranda, Richard Stallman, Stefan Kangas (core Emacs), + Stefan Monnier (GNU Elpa), André Alexandre Gomes, Dimakakos Dimos, + Morgan Smith, Nicolas Goaziou (Guix), Dhavan Vaidya (Debian). + Inspiration for certain features :: Bozhidar Batsov (zenburn-theme), Fabrice Niessen (leuven-theme). +Special thanks, in no particular order, to Manuel Uberti and Omar +Antolín Camarena for their long time contributions and insightful +commentary. + * Meta -:PROPERTIES: -:CUSTOM_ID: h:13752581-4378-478c-af17-165b6e76bc1b -:END: +:properties: +:custom_id: h:13752581-4378-478c-af17-165b6e76bc1b +:end: +#+cindex: Development notes If you are curious about the principles that govern the development of this project read the essay [[https://protesilaos.com/codelog/2020-03-17-design-modus-themes-emacs/][On the design of the Modus themes]] @@ -1931,32 +2803,501 @@ of this sort): + [[https://protesilaos.com/codelog/2020-07-04-modus-themes-faint-colours/][Modus themes: new "faint syntax" option]] (2020-07-04) + [[https://protesilaos.com/codelog/2020-07-08-modus-themes-nuanced-colours/][Modus themes: major review of "nuanced" colours]] (2020-07-08) + [[https://protesilaos.com/codelog/2020-09-14-modus-themes-review-blues/][Modus themes: review of blue colours]] (2020-09-14) ++ [[https://protesilaos.com/codelog/2020-12-27-modus-themes-review-rainbow-delimiters/][Modus themes: review rainbow-delimiters faces]] (2020-12-27) ++ [[https://protesilaos.com/codelog/2021-01-11-modus-themes-review-select-faint-colours/][Modus themes: review of select "faint" colours]] (2021-01-11) ++ [[https://protesilaos.com/codelog/2021-02-25-modus-themes-diffs-deuteranopia/][The Modus themes now cover deuteranopia in diffs]] (2021-02-25) -And here are the canonical sources for this project's documentation: +And here are the canonical sources of this project's documentation: + Manual :: + Change Log :: + Screenshots :: -* External projects (ports) -:PROPERTIES: -:CUSTOM_ID: h:21adb7c8-2208-41e8-803c-052e42e2c05d -:END: - -The present section documents projects that extend the scope of the -Modus themes. The following list will be updated whenever relevant -information is brought to my attention. If you already have or intend -to produce such a port, feel welcome [[https://protesilaos.com/contact][to contact me]]. - -+ Modus exporter :: This is [[https://github.com/polaris64/modus-exporter][an Elisp library written by Simon Pugnet]]. - Licensed under the terms of the GNU General Public License. It is - meant to capture the color values of the active Modus theme (Operandi - or Vivendi) and output it as a valid theme for some other application. - * GNU Free Documentation License -:PROPERTIES: -:APPENDIX: t -:CUSTOM_ID: h:3077c3d2-7f90-4228-8f0a-73124f4026f6 -:END: +:properties: +:appendix: t +:custom_id: h:3077c3d2-7f90-4228-8f0a-73124f4026f6 +:end: #+texinfo: @include doclicense.texi + +#+begin_export html + + GNU Free Documentation License + Version 1.3, 3 November 2008 + + + Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +0. PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document "free" in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + +1. APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The "Document", below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as "you". You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "Secondary Section" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not "Transparent" is called "Opaque". + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML, PostScript or PDF designed for human modification. Examples of +transparent image formats include PNG, XCF and JPG. Opaque formats +include proprietary formats that can be read and edited only by +proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML, PostScript or PDF produced by some word +processors for output purposes only. + +The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +The "publisher" means any person or entity that distributes copies of +the Document to the public. + +A section "Entitled XYZ" means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as "Acknowledgements", +"Dedications", "Endorsements", or "History".) To "Preserve the Title" +of such a section when you modify the Document means that it remains a +section "Entitled XYZ" according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + +2. VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no +other conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +3. COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to +give them a chance to provide you with an updated version of the +Document. + + +4. MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has fewer than five), + unless they release you from this requirement. +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. +D. Preserve all the copyright notices of the Document. +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. +I. Preserve the section Entitled "History", Preserve its Title, and add + to it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section Entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +K. For any section Entitled "Acknowledgements" or "Dedications", + Preserve the Title of the section, and preserve in the section all + the substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +M. Delete any section Entitled "Endorsements". Such a section + may not be included in the Modified Version. +N. Do not retitle any existing section to be Entitled "Endorsements" + or to conflict in title with any Invariant Section. +O. Preserve any Warranty Disclaimers. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +5. COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled "History" +in the various original documents, forming one section Entitled +"History"; likewise combine any sections Entitled "Acknowledgements", +and any sections Entitled "Dedications". You must delete all sections +Entitled "Endorsements". + + +6. COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other +documents released under this License, and replace the individual +copies of this License in the various documents with a single copy +that is included in the collection, provided that you follow the rules +of this License for verbatim copying of each of the documents in all +other respects. + +You may extract a single document from such a collection, and +distribute it individually under this License, provided you insert a +copy of this License into the extracted document, and follow this +License in all other respects regarding verbatim copying of that +document. + + +7. AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an "aggregate" if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + + +8. TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled "Acknowledgements", +"Dedications", or "History", the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + + +9. TERMINATION + +You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. + +However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally +terminates your license, and (b) permanently, if the copyright holder +fails to notify you of the violation by some reasonable means prior to +60 days after the cessation. + +Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, receipt of a copy of some or all of the same material does +not give you any rights to use it. + + +10. FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions of the +GNU Free Documentation License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in +detail to address new problems or concerns. See +https://www.gnu.org/licenses/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. + +11. RELICENSING + +"Massive Multiauthor Collaboration Site" (or "MMC Site") means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +"Massive Multiauthor Collaboration" (or "MMC") contained in the site +means any set of copyrightable works thus published on the MMC site. + +"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. + +"Incorporate" means to publish or republish a Document, in whole or in +part, as part of another Document. + +An MMC is "eligible for relicensing" if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole or +in part into the MMC, (1) had no cover texts or invariant sections, and +(2) were thus incorporated prior to November 1, 2008. + +The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. + + +ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the "with...Texts." line with this: + + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. +#+end_export + +#+html: diff --git a/etc/themes/modus-operandi-theme.el b/etc/themes/modus-operandi-theme.el index 9d6e9ad50f..ce2c75e9a8 100644 --- a/etc/themes/modus-operandi-theme.el +++ b/etc/themes/modus-operandi-theme.el @@ -1,4663 +1,65 @@ ;;; modus-operandi-theme.el --- Accessible light theme (WCAG AAA) -*- lexical-binding:t -*- -;; Copyright (C) 2019-2021 Free Software Foundation, Inc. +;; Copyright (C) 2019-2021 Free Software Foundation, Inc. ;; Author: Protesilaos Stavrou ;; URL: https://gitlab.com/protesilaos/modus-themes -;; Version: 0.13.0 +;; Version: 1.2.0 ;; Package-Requires: ((emacs "26.1")) ;; Keywords: faces, theme, accessibility ;; This file is part of GNU Emacs. -;; GNU Emacs is free software: you can redistribute it and/or modify +;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs. If not, see . +;; along with this program. If not, see . ;;; Commentary: ;; -;; This theme is designed for colour-contrast accessibility. -;; -;; 1. Provide a consistent minimum contrast ratio between background and -;; foreground values of 7:1 or higher. This meets the highest such -;; accessibility criterion per the guidelines of the Worldwide Web -;; Consortium's Working Group on Accessibility (WCAG AAA standard). +;; Modus Operandi is the light variant of the Modus themes (Modus +;; Vivendi is the dark one). The themes are designed for color-contrast +;; accessibility. More specifically: ;; -;; 2. Offer as close to full face coverage as possible. The list is -;; already quite long (see further below), with more additions to follow -;; as part of the ongoing development process. +;; 1. Provide a consistent minimum contrast ratio between background +;; and foreground values of 7:1 or higher. This meets the highest +;; such accessibility criterion per the guidelines of the Worldwide +;; Web Consortium's Working Group on Accessibility (WCAG AAA +;; standard). ;; -;; The theme provides the following customisation options, all of which -;; are disabled by default: +;; 2. Offer as close to full face coverage as possible. The list is +;; already quite long, with more additions to follow as part of the +;; ongoing development process. ;; -;; modus-operandi-theme-slanted-constructs (boolean) -;; modus-operandi-theme-bold-constructs (boolean) -;; modus-operandi-theme-variable-pitch-headings (boolean) -;; modus-operandi-theme-no-mixed-fonts (boolean) -;; modus-operandi-theme-headings (alist) -;; modus-operandi-theme-scale-headings (boolean) -;; modus-operandi-theme-fringes (choice) -;; modus-operandi-theme-org-blocks (choice) -;; modus-operandi-theme-prompts (choice) -;; modus-operandi-theme-mode-line (choice) -;; modus-operandi-theme-diffs (choice) -;; modus-operandi-theme-faint-syntax (boolean) -;; modus-operandi-theme-intense-hl-line (boolean) -;; modus-operandi-theme-intense-paren-match (boolean) -;; modus-operandi-theme-no-link-underline (boolean) -;; modus-operandi-theme-completions (choice) -;; modus-operandi-theme-override-colors-alist (alist) +;; For a complete view of the project, also refer to the following files +;; (should be distributed in the same repository/directory as the +;; current item): ;; -;; The default scale is as follows (it can be customised as well): -;; -;; modus-operandi-theme-scale-1 1.05 -;; modus-operandi-theme-scale-2 1.1 -;; modus-operandi-theme-scale-3 1.15 -;; modus-operandi-theme-scale-4 1.2 -;; modus-operandi-theme-scale-5 1.3 -;; -;; What follows is the list of explicitly supported packages or face -;; groups (there are implicitly supported packages as well, which -;; inherit from font-lock or some basic group). You are encouraged to -;; notify me of any missing package or change you would like to see. -;; -;; ace-window -;; ag -;; alert -;; all-the-icons -;; annotate -;; anzu -;; apropos -;; apt-sources-list -;; artbollocks-mode -;; auctex and TeX -;; auto-dim-other-buffers -;; avy -;; awesome-tray -;; binder -;; bm -;; bongo -;; boon -;; breakpoint (provided by built-in gdb-mi.el) -;; buffer-expose -;; calendar and diary -;; calfw -;; centaur-tabs -;; change-log and log-view (`vc-print-log' and `vc-print-root-log') -;; cider -;; circe -;; color-rg -;; column-enforce-mode -;; company-mode -;; company-posframe -;; compilation-mode -;; completions -;; counsel -;; counsel-css -;; counsel-notmuch -;; counsel-org-capture-string -;; cov -;; cperl-mode -;; csv-mode -;; ctrlf -;; custom (M-x customize) -;; dap-mode -;; dashboard (emacs-dashboard) -;; deadgrep -;; debbugs -;; define-word -;; deft -;; dictionary -;; diff-hl -;; diff-mode -;; dim-autoload -;; dir-treeview -;; dired -;; dired-async -;; dired-git -;; dired-git-info -;; dired-narrow -;; dired-subtree -;; diredfl -;; disk-usage -;; doom-modeline -;; dynamic-ruler -;; easy-jekyll -;; easy-kill -;; ebdb -;; ediff -;; eglot -;; el-search -;; eldoc -;; eldoc-box -;; elfeed -;; elfeed-score -;; emms -;; enhanced-ruby-mode -;; epa -;; equake -;; erc -;; eros -;; ert -;; eshell -;; eshell-fringe-status -;; eshell-git-prompt -;; eshell-prompt-extras (epe) -;; eshell-syntax-highlighting -;; evil (evil-mode) -;; evil-goggles -;; evil-visual-mark-mode -;; eww -;; eyebrowse -;; fancy-dabbrev -;; flycheck -;; flycheck-color-mode-line -;; flycheck-indicator -;; flycheck-posframe -;; flymake -;; flyspell -;; flyspell-correct -;; flx -;; freeze-it -;; frog-menu -;; focus -;; fold-this -;; font-lock (generic syntax highlighting) -;; forge -;; fountain (fountain-mode) -;; geiser -;; git-commit -;; git-gutter (and variants) -;; git-lens -;; git-rebase -;; git-timemachine -;; git-walktree -;; gnus -;; golden-ratio-scroll-screen -;; helm -;; helm-ls-git -;; helm-switch-shell -;; helm-xref -;; helpful -;; highlight-blocks -;; highlight-defined -;; highlight-escape-sequences (`hes-mode') -;; highlight-indentation -;; highlight-numbers -;; highlight-symbol -;; highlight-tail -;; highlight-thing -;; hl-defined -;; hl-fill-column -;; hl-line-mode -;; hl-todo -;; hydra -;; hyperlist -;; ibuffer -;; icomplete -;; ido-mode -;; iedit -;; iflipb -;; imenu-list -;; indium -;; info -;; info-colors -;; interaction-log -;; ioccur -;; isearch, occur, etc. -;; ivy -;; ivy-posframe -;; jira (org-jira) -;; journalctl-mode -;; js2-mode -;; julia -;; jupyter -;; kaocha-runner -;; keycast -;; line numbers (`display-line-numbers-mode' and global variant) -;; lsp-mode -;; lsp-ui -;; magit -;; magit-imerge -;; man -;; markdown-mode -;; markup-faces (`adoc-mode') -;; mentor -;; messages -;; minibuffer-line -;; minimap -;; modeline -;; mood-line -;; mpdel -;; mu4e -;; mu4e-conversation -;; multiple-cursors -;; neotree -;; no-emoji -;; notmuch -;; num3-mode -;; nxml-mode -;; objed -;; orderless -;; org -;; org-journal -;; org-noter -;; org-pomodoro -;; org-recur -;; org-roam -;; org-superstar -;; org-table-sticky-header -;; org-treescope -;; origami -;; outline-mode -;; outline-minor-faces -;; package (M-x list-packages) -;; page-break-lines -;; paradox -;; paren-face -;; parrot -;; pass -;; persp-mode -;; perspective -;; phi-grep -;; phi-search -;; pkgbuild-mode -;; pomidor -;; powerline -;; powerline-evil -;; proced -;; prodigy -;; racket-mode -;; rainbow-blocks -;; rainbow-identifiers -;; rainbow-delimiters -;; rcirc -;; regexp-builder (also known as `re-builder') -;; rg -;; ripgrep -;; rmail -;; ruler-mode -;; sallet -;; selectrum -;; semantic -;; sesman -;; shell-script-mode -;; show-paren-mode -;; side-notes -;; skewer-mode -;; smart-mode-line -;; smartparens -;; smerge -;; spaceline -;; speedbar -;; spell-fu -;; stripes -;; suggest -;; switch-window -;; swiper -;; swoop -;; sx -;; symbol-overlay -;; tab-bar-mode -;; tab-line-mode -;; syslog-mode -;; table (built-in table.el) -;; telephone-line -;; term -;; tomatinho -;; transient (pop-up windows like Magit's) -;; trashed -;; treemacs -;; tty-menu -;; tuareg -;; typescript -;; undo-tree -;; vc (built-in mode line status for version control) -;; vc-annotate (C-x v g) -;; vdiff -;; vimish-fold -;; visible-mark -;; visual-regexp -;; volatile-highlights -;; vterm -;; wcheck-mode -;; web-mode -;; wgrep -;; which-function-mode -;; which-key -;; whitespace-mode -;; window-divider-mode -;; winum -;; writegood-mode -;; woman -;; xah-elisp-mode -;; xref -;; xterm-color (and ansi-colors) -;; yaml-mode -;; yasnippet -;; ztree +;; - modus-themes.el (Main code shared between the themes) +;; - modus-vivendi-theme.el (Dark theme) ;;; Code: -(deftheme modus-operandi - "Light theme that conforms with the highest accessibility - standard for colour contrast between background and - foreground elements (WCAG AAA).") - -;;; Custom faces - -;; These faces will be inherited by actual constructs. They are meant -;; for those cases where a face needs to distinguish its output from -;; the rest of the text, such as `isearch' and `occur'… We define -;; these separately in order to combine each colour with its -;; appropriate foreground value. This is to ensure a consistent -;; contrast ratio of >= 7:1. -(defgroup modus-theme () - "Theme that ensures WCAG AAA accessibility (contrast ratio -between foreground and background is >= 7:1)." - :group 'faces - :prefix "modus-theme-" - :link '(url-link :tag "GitLab" "https://gitlab.com/protesilaos/modus-themes") - :tag "Modus Operandi") - -(defface modus-theme-subtle-red nil nil) -(defface modus-theme-subtle-green nil nil) -(defface modus-theme-subtle-yellow nil nil) -(defface modus-theme-subtle-blue nil nil) -(defface modus-theme-subtle-magenta nil nil) -(defface modus-theme-subtle-cyan nil nil) -(defface modus-theme-subtle-neutral nil nil) -(defface modus-theme-intense-red nil nil) -(defface modus-theme-intense-green nil nil) -(defface modus-theme-intense-yellow nil nil) -(defface modus-theme-intense-blue nil nil) -(defface modus-theme-intense-magenta nil nil) -(defface modus-theme-intense-cyan nil nil) -(defface modus-theme-intense-neutral nil nil) -(defface modus-theme-refine-red nil nil) -(defface modus-theme-refine-green nil nil) -(defface modus-theme-refine-yellow nil nil) -(defface modus-theme-refine-blue nil nil) -(defface modus-theme-refine-magenta nil nil) -(defface modus-theme-refine-cyan nil nil) -(defface modus-theme-active-red nil nil) -(defface modus-theme-active-green nil nil) -(defface modus-theme-active-yellow nil nil) -(defface modus-theme-active-blue nil nil) -(defface modus-theme-active-magenta nil nil) -(defface modus-theme-active-cyan nil nil) -(defface modus-theme-fringe-red nil nil) -(defface modus-theme-fringe-green nil nil) -(defface modus-theme-fringe-yellow nil nil) -(defface modus-theme-fringe-blue nil nil) -(defface modus-theme-fringe-magenta nil nil) -(defface modus-theme-fringe-cyan nil nil) -(defface modus-theme-nuanced-red nil nil) -(defface modus-theme-nuanced-green nil nil) -(defface modus-theme-nuanced-yellow nil nil) -(defface modus-theme-nuanced-blue nil nil) -(defface modus-theme-nuanced-magenta nil nil) -(defface modus-theme-nuanced-cyan nil nil) -(defface modus-theme-special-cold nil nil) -(defface modus-theme-special-mild nil nil) -(defface modus-theme-special-warm nil nil) -(defface modus-theme-special-calm nil nil) -(defface modus-theme-diff-added nil nil) -(defface modus-theme-diff-changed nil nil) -(defface modus-theme-diff-removed nil nil) -(defface modus-theme-diff-refine-added nil nil) -(defface modus-theme-diff-refine-changed nil nil) -(defface modus-theme-diff-refine-removed nil nil) -(defface modus-theme-diff-focus-added nil nil) -(defface modus-theme-diff-focus-changed nil nil) -(defface modus-theme-diff-focus-removed nil nil) -(defface modus-theme-diff-heading nil nil) -(defface modus-theme-pseudo-header nil nil) -(defface modus-theme-mark-alt nil nil) -(defface modus-theme-mark-del nil nil) -(defface modus-theme-mark-sel nil nil) -(defface modus-theme-mark-symbol nil nil) -(defface modus-theme-heading-1 nil nil) -(defface modus-theme-heading-2 nil nil) -(defface modus-theme-heading-3 nil nil) -(defface modus-theme-heading-4 nil nil) -(defface modus-theme-heading-5 nil nil) -(defface modus-theme-heading-6 nil nil) -(defface modus-theme-heading-7 nil nil) -(defface modus-theme-heading-8 nil nil) -(defface modus-theme-hl-line nil nil) - -;;; Customisation options - -;; User-facing customisation options. They are all deactivated by -;; default (users must opt in). -(defcustom modus-operandi-theme-slanted-constructs nil - "Use slanted text in more code constructs (italics or oblique)." - :type 'boolean) - -(defcustom modus-operandi-theme-bold-constructs nil - "Use bold text in more code constructs." - :type 'boolean) - -(define-obsolete-variable-alias 'modus-operandi-theme-proportional-fonts - 'modus-operandi-theme-variable-pitch-headings "`modus-operandi-theme' 0.11.0") - -(defcustom modus-operandi-theme-proportional-fonts nil - "Use proportional fonts (variable-pitch) in headings." - :type 'boolean) - -(defcustom modus-operandi-theme-variable-pitch-headings nil - "Use proportional fonts (variable-pitch) in headings." - :type 'boolean) - -(defcustom modus-operandi-theme-no-mixed-fonts nil - "Disable inheritance from `fixed-pitch' in some faces. - -This is done by default to allow spacing-sensitive constructs, -such as Org tables and code blocks, to remain monospaced when -users opt for something like the command `variable-pitch-mode'. -The downside with the default is that users need to explicitly -configure the font family of `fixed-pitch' in order to get a -consistent experience. That may be something they do not want to -do. Hence this option to disable any kind of technique for -mixing fonts." - :type 'boolean) - -(make-obsolete 'modus-operandi-theme-rainbow-headings - 'modus-operandi-theme-headings - "`modus-operandi-theme' 0.13.0") - -(defcustom modus-operandi-theme-rainbow-headings nil - "Use more saturated colours for headings." - :type 'boolean) - -(make-obsolete 'modus-operandi-theme-section-headings - 'modus-operandi-theme-headings - "`modus-operandi-theme' 0.13.0") - -(defcustom modus-operandi-theme-section-headings nil - "Use a background and an overline in headings." - :type 'boolean) - -(defcustom modus-operandi-theme-headings - '((t . nil)) - "Alist of styles for headings, with optional value per level. - -To control faces per level from 1-8, use something like this: - - (setq modus-operandi-theme-headings - '((1 . highlight) - (2 . line) - (t . rainbow-line-no-bold))) - -To set a uniform value for all heading levels, use this pattern: - - (setq modus-operandi-theme-headings - '((t . rainbow-line-no-bold))) - -The default uses a fairly desaturated foreground value in -combination with a bold typographic weight. To specify this -style for a given level N (assuming you wish to have another -fallback option), just specify the value t like this: - - (setq modus-operandi-theme-headings - '((1 . t) - (2 . line) - (t . rainbow-line-no-bold))) - -A description of all possible values: - -+ `no-bold' retains the default text colour while removing - the typographic weight. - -+ `line' is the same as the default plus an overline over the - heading. - -+ `line-no-bold' is the same as `line' without bold weight. - -+ `rainbow' uses a more colourful foreground in combination - with bold weight. - -+ `rainbow-line' is the same as `rainbow' plus an overline. - -+ `rainbow-line-no-bold' is the same as `rainbow-line' without - the bold weight. - -+ `highlight' retains the default style of a fairly desaturated - foreground combined with a bold weight and add to it a subtle - accented background. - -+ `highlight-no-bold' is the same as `highlight' without a bold - weight. - -+ `rainbow-highlight' is the same as `highlight' but with a more - colourful foreground. - -+ `rainbow-highlight-no-bold' is the same as `rainbow-highlight' - without a bold weight. - -+ `section' retains the default looks and adds to them both an - overline and a slightly accented background. It is, in effect, - a combination of the `line' and `highlight' values. - -+ `section-no-bold' is the same as `section' without a bold - weight. - -+ `rainbow-section' is the same as `section' but with a more - colourful foreground. - -+ `rainbow-section-no-bold' is the same as `rainbow-section' - without a bold weight." - :type - '(alist - :key-type symbol - :value-type - (choice (const :tag "Fairly desaturated foreground with bold weight (default)" t) - (const :tag "Like the default without bold weight" no-bold) - (const :tag "Like the default plus overline" line) - (const :tag "Like `line' without bold weight" line-no-bold) - (const :tag "Like the default but with more colourful foreground" rainbow) - (const :tag "Like `rainbow' plus overline" rainbow-line) - (const :tag "Like `rainbow' without bold weight" rainbow-no-bold) - (const :tag "Like `rainbow-line' without bold weight" rainbow-line-no-bold) - (const :tag "Like the default plus subtle background" highlight) - (const :tag "Like `highlight' without bold weight" highlight-no-bold) - (const :tag "Like `highlight' with more colourful foreground" rainbow-highlight) - (const :tag "Like `rainbow-highlight' without bold weight" rainbow-highlight-no-bold) - (const :tag "Like `highlight' plus overline" section) - (const :tag "Like `section' without bold weight" section-no-bold) - (const :tag "Like `section' with more colourful foreground" rainbow-section) - (const :tag "Like `rainbow-section' without bold weight" rainbow-section-no-bold)))) - -(defcustom modus-operandi-theme-scale-headings nil - "Use font scaling for headings." - :type 'boolean) - -(defcustom modus-operandi-theme-scale-1 1.05 - "Font size that is slightly larger than the base value. -The default is a floating point that is interpreted as a multiple -of the base font size. However, the variable also accepts an -integer, understood as an absolute height (e.g. a value of 140 is -the same as setting the font at 14 point size). - -For more on the matter, read the documentation of -`set-face-attribute', specifically the ':height' section." - :type 'number) - -(defcustom modus-operandi-theme-scale-2 1.1 - "Font size slightly larger than `modus-operandi-theme-scale-1'. -The default is a floating point that is interpreted as a multiple -of the base font size. However, the variable also accepts an -integer, understood as an absolute height (e.g. a value of 140 is -the same as setting the font at 14 point size). - -For more on the matter, read the documentation of -`set-face-attribute', specifically the ':height' section." - :type 'number) - -(defcustom modus-operandi-theme-scale-3 1.15 - "Font size slightly larger than `modus-operandi-theme-scale-2'. -The default is a floating point that is interpreted as a multiple -of the base font size. However, the variable also accepts an -integer, understood as an absolute height (e.g. a value of 140 is -the same as setting the font at 14 point size). - -For more on the matter, read the documentation of -`set-face-attribute', specifically the ':height' section." - :type 'number) - -(defcustom modus-operandi-theme-scale-4 1.2 - "Font size slightly larger than `modus-operandi-theme-scale-3'. -The default is a floating point that is interpreted as a multiple -of the base font size. However, the variable also accepts an -integer, understood as an absolute height (e.g. a value of 140 is -the same as setting the font at 14 point size). - -For more on the matter, read the documentation of -`set-face-attribute', specifically the ':height' section." - :type 'number) - -(defcustom modus-operandi-theme-scale-5 1.3 - "Font size slightly larger than `modus-operandi-theme-scale-4'. -The default is a floating point that is interpreted as a multiple -of the base font size. However, the variable also accepts an -integer, understood as an absolute height (e.g. a value of 140 is -the same as setting the font at 14 point size). - -For more on the matter, read the documentation of -`set-face-attribute', specifically the ':height' section." - :type 'number) - -(make-obsolete 'modus-operandi-theme-visible-fringes - 'modus-operandi-theme-fringes - "`modus-operandi-theme' 0.12.0") - -(defcustom modus-operandi-theme-visible-fringes nil - "Use a visible style for fringes." - :type 'boolean) - -(defcustom modus-operandi-theme-fringes nil - "Define the visibility of fringes. - -Nil means the fringes have no background colour. Option `subtle' -will apply a greyscale value that is visible yet close to the -main buffer background colour. Option `intense' will use a more -pronounced greyscale value." - :type '(choice - (const :tag "No visible fringes (default)" nil) - (const :tag "Subtle greyscale background" subtle) - (const :tag "Intense greyscale background" intense))) - -(make-obsolete 'modus-operandi-theme-distinct-org-blocks - 'modus-operandi-theme-org-blocks - "`modus-operandi-theme' 0.11.0") - -(defcustom modus-operandi-theme-distinct-org-blocks nil - "Use a distinct neutral background for `org-mode' blocks." - :type 'boolean) - -(make-obsolete 'modus-operandi-theme-rainbow-org-src-blocks - 'modus-operandi-theme-org-blocks - "`modus-operandi-theme' 0.11.0") - -(defcustom modus-operandi-theme-rainbow-org-src-blocks nil - "Use colour-coded backgrounds for `org-mode' source blocks. -The colour in use depends on the language (send feedback to -include more languages)." - :type 'boolean) - -(defcustom modus-operandi-theme-org-blocks nil - "Use a subtle grey or colour-coded background for Org blocks. - -Nil means that the block will have no background of its own and -will use the default that applies to the rest of the buffer. - -Option `greyscale' will apply a subtle neutral grey background to -the block's contents. It also affects the begin and end lines of -the block: their background will be extended to the edge of the -window for Emacs version >= 27 where the ':extend' keyword is -recognised by `set-face-attribute'. - -Option `rainbow' will use an accented background for the contents -of the block. The exact colour will depend on the programming -language and is controlled by the `org-src-block-faces' -variable (refer to the theme's source code for the current -association list)." - :type '(choice - (const :tag "No Org block background (default)" nil) - (const :tag "Subtle grey block background" greyscale) - (const :tag "Colour-coded background per programming language" rainbow))) - -(make-obsolete 'modus-operandi-theme-3d-modeline - 'modus-operandi-theme-mode-line - "`modus-operandi-theme' 0.13.0") - -(defcustom modus-operandi-theme-3d-modeline nil - "Use a three-dimensional style for the active mode line." - :type 'boolean) - -(defcustom modus-operandi-theme-mode-line nil - "Adjust the overall style of the mode line. - -Nil is a two-dimensional rectangle with a border around it. The -active and the inactive modelines use different shades of -greyscale values for the background and foreground. - -A `3d' value will apply a three-dimensional effect to the active -modeline. The inactive modelines remain two-dimensional and are -toned down a bit, relative to the nil value. - -The `moody' option is meant to optimise the modeline for use with -the library of the same name. This practically means to remove -the box effect and rely on underline and overline properties -instead. It also tones down the inactive modelines. Despite its -intended purpose, this option can also be used without the -`moody' library." - :type '(choice - (const :tag "Two-dimensional box (default)" nil) - (const :tag "Three-dimensional style for the active mode line" 3d) - (const :tag "No box effects, which are optimal for use with the `moody' library" moody))) - -(make-obsolete 'modus-operandi-theme-subtle-diffs - 'modus-operandi-theme-diffs - "`modus-operandi-theme' 0.13.0") - -(defcustom modus-operandi-theme-subtle-diffs nil - "Use fewer/dim backgrounds in `diff-mode', `ediff',`magit'." - :type 'boolean) +(require-theme 'modus-themes) -(defcustom modus-operandi-theme-diffs nil - "Adjust the overall styles of diffs. - -Nil means to use fairly intense colour combinations for diffs. -For example, you get a rich green background with a green -foreground for added lines. Word-wise or 'refined' diffs follow -the same pattern but use different shades of those colours to -remain distinct. - -A `desaturated' value follows the same principles as with the nil -option, while it tones down all relevant colours. - -Option `fg-only' will remove all accented backgrounds, except -from word-wise changes. It instead uses colour-coded foreground -values to differentiate between added/removed/changed lines. If -a background is necessary, such as with `ediff', then a subtle -greyscale value is used." - :type '(choice - (const :tag "Intensely coloured backgrounds (default)" nil) - (const :tag "Slightly accented backgrounds with tinted text" desaturated) - (const :tag "No backgrounds, except for refined diffs" fg-only))) - -(make-obsolete 'modus-operandi-theme-intense-standard-completions - 'modus-operandi-theme-completions - "`modus-operandi-theme' 0.12.0") - -(defcustom modus-operandi-theme-intense-standard-completions nil - "Use prominent backgrounds for Icomplete, Ido, or similar." - :type 'boolean) - -(defcustom modus-operandi-theme-completions nil - "Apply special styles to the UI of completion frameworks. - -This concerns Icomplete, Ivy, Helm, Selectrum, Ido, as well as -any other tool meant to enhance their experience. The effect -will vary depending on the completion framework. - -Nil means to remain faithful to the metaphors that each UI -establishes. For example, Icomplete and Ido only use foreground -colours to style their matches, whereas Ivy or Helm rely on an -aesthetic that combines coloured backgrounds with appropriate -text colour. - -Option `moderate' will apply a combination of background and -foreground that is fairly subtle. For Icomplete and the like, -this constitutes a departure from their standard style. While -Ivy, Helm, and the others, will use less pronounced colours for -applicable contexts. - -Option `opinionated' will apply colour combinations that -refashion the completion UI. So Icomplete et al will now use -styles that resemble the defaults of Ivy and co., while the -latter group will revert to an even more nuanced aesthetic." - :type '(choice - (const :tag "Respect the framework's established aesthetic (default)" nil) - (const :tag "Subtle backgrounds for various elements" moderate) - (const :tag "Radical alternative to the framework's looks" opinionated))) - -(defcustom modus-operandi-theme-prompts nil - "Use subtle or intense styles for minibuffer and REPL prompts. - -Nil means to only use an accented foreground colour. - -Options `subtle' and `intense' will change both the background -and the foreground values. The latter has a more pronounced -effect than the former." - :type '(choice - (const :tag "No prompt background (default)" nil) - (const :tag "Subtle accented background for the prompt" subtle) - (const :tag "Intense background and foreground for the prompt" intense))) - -(defcustom modus-operandi-theme-intense-hl-line nil - "Use more prominent background for command `hl-line-mode'." - :type 'boolean) - -(defcustom modus-operandi-theme-intense-paren-match nil - "Use more prominent colour for parenthesis matching." - :type 'boolean) - -(defcustom modus-operandi-theme-faint-syntax nil - "Use less saturated colours for code syntax highlighting." - :type 'boolean) - -(defcustom modus-operandi-theme-no-link-underline nil - "Do not underline links." - :type 'boolean) - -;;; Internal functions - -;; Helper functions that are meant to ease the implementation of the -;; above customisation options. -(defun modus-operandi-theme-bold-weight () - "Conditional use of a heavier text weight." - (when modus-operandi-theme-bold-constructs - (list :inherit 'bold))) - -(defun modus-operandi-theme-mixed-fonts () - "Conditional application of `fixed-pitch' inheritance." - (unless modus-operandi-theme-no-mixed-fonts - (list :inherit 'fixed-pitch))) - -(defun modus-operandi-theme-fringe (subtlebg intensebg) - "Conditional use of background colours for fringes. -SUBTLEBG should be a subtle greyscale value. INTENSEBG must be a -more pronounced greyscale colour." - (pcase modus-operandi-theme-fringes - ('intense (list :background intensebg)) - ('subtle (list :background subtlebg)) - (_ (list :background nil)))) - -(defun modus-operandi-theme-prompt (mainfg subtlebg subtlefg intensebg intensefg) - "Conditional use of background colours for prompts. -MAINFG is the prompt's standard foreground. SUBTLEBG should be a -subtle accented background that works with SUBTLEFG. INTENSEBG -must be a more pronounced accented colour that should be -combinable with INTENSEFG." - (pcase modus-operandi-theme-prompts - ('intense (list :background intensebg :foreground intensefg)) - ('subtle (list :background subtlebg :foreground subtlefg)) - (_ (list :background nil :foreground mainfg)))) - -(defun modus-operandi-theme-paren (normalbg intensebg) - "Conditional use of intense colours for matching parentheses. -NORMALBG should the special palette colour 'bg-paren-match' or -something similar. INTENSEBG must be easier to discern next to -other backgrounds, such as the special palette colour -'bg-paren-match-intense'." - (if modus-operandi-theme-intense-paren-match - (list :background intensebg) - (list :background normalbg))) - -(defun modus-operandi-theme-syntax-foreground (normal faint) - "Apply foreground value to code syntax. -NORMAL is the more saturated colour, which should be the default. -FAINT is the less saturated colour." - (if modus-operandi-theme-faint-syntax - (list :foreground faint) - (list :foreground normal))) - -(defun modus-operandi-theme-heading-p (key) - "Query style of KEY in `modus-operandi-theme-headings'." - (cdr (assoc key modus-operandi-theme-headings))) - -(defun modus-operandi-theme-heading (level fg fg-alt bg border) - "Conditional styles for `modus-operandi-theme-headings'. - -LEVEL is the heading's position in their order. FG is the -default text colour. FG-ALT is an accented, more saturated value -than the default. BG is a nuanced, typically accented, -background that can work well with either of the foreground -values. BORDER is a colour value that combines well with the -background and alternative foreground." - (let* ((key (modus-operandi-theme-heading-p `,level)) - (style (or key (modus-operandi-theme-heading-p t))) - (var (if modus-operandi-theme-variable-pitch-headings - 'variable-pitch - 'default))) - (pcase style - ('no-bold - (list :inherit `,var :foreground fg)) - ('line - (list :inherit `(bold ,var) :foreground fg :overline border)) - ('line-no-bold - (list :inherit `,var :foreground fg :overline border)) - ('rainbow - (list :inherit `(bold ,var) :foreground fg-alt)) - ('rainbow-no-bold - (list :inherit `,var :foreground fg-alt)) - ('rainbow-line - (list :inherit `(bold ,var) :foreground fg-alt :overline border)) - ('rainbow-line-no-bold - (list :inherit `,var :foreground fg-alt :overline border)) - ('highlight - (list :inherit `(bold ,var) :background bg :foreground fg)) - ('highlight-no-bold - (list :inherit `,var :background bg :foreground fg)) - ('rainbow-highlight - (list :inherit `(bold ,var) :background bg :foreground fg-alt)) - ('rainbow-highlight-no-bold - (list :inherit `,var :background bg :foreground fg-alt)) - ('section - (append - (and (>= emacs-major-version 27) '(:extend t)) - (list :inherit `(bold ,var) :background bg :foreground fg :overline border))) - ('section-no-bold - (append - (and (>= emacs-major-version 27) '(:extend t)) - (list :inherit `,var :background bg :foreground fg :overline border))) - ('rainbow-section - (append - (and (>= emacs-major-version 27) '(:extend t)) - (list :inherit `(bold ,var) :background bg :foreground fg-alt :overline border))) - ('rainbow-section-no-bold - (append - (and (>= emacs-major-version 27) '(:extend t)) - (list :inherit `,var :background bg :foreground fg-alt :overline border))) - (_ - (list :inherit `(bold ,var) :foreground fg))))) - -(defun modus-operandi-theme-org-block (bgblk) - "Conditionally set the background of Org blocks. -BGBLK applies to a distinct neutral background. Else blocks have -no background of their own (the default), so they look the same -as the rest of the buffer. - -`modus-operandi-theme-org-blocks' also accepts a `rainbow' option -which is applied conditionally to `org-src-block-faces' (see the -theme's source code)." - (if (eq modus-operandi-theme-org-blocks 'greyscale) - (append - (and (>= emacs-major-version 27) '(:extend t)) - (list :background bgblk)) - (list :background nil))) - -(defun modus-operandi-theme-org-block-delim (bgaccent fgaccent bg fg) - "Conditionally set the styles of Org block delimiters. -BG, FG, BGACCENT, FGACCENT apply a background and foreground -colour respectively. - -The former pair is a greyscale combination that should be more -distinct than the background of the block. It is applied to the -default styles or when `modus-operandi-theme-org-blocks' is set -to `greyscale'. - -The latter pair should be more subtle than the background of the -block, as it is used when `modus-operandi-theme-org-blocks' is -set to `rainbow'." - (pcase modus-operandi-theme-org-blocks - ('greyscale (append (and (>= emacs-major-version 27) '(:extend t)) - (list :background bg :foreground fg))) - ('rainbow (list :background bgaccent :foreground fgaccent)) - (_ (list :background bg :foreground fg)))) - -(defun modus-operandi-theme-mode-line-attrs - (fg bg fg-alt bg-alt border border-3d &optional alt-style border-width fg-distant) - "Colour combinations for `modus-operandi-theme-mode-line'. - -FG and BG are the default colours. FG-ALT and BG-ALT are meant -to accommodate the options for a 3D modeline or a `moody' -compliant one. BORDER applies to all permutations of the -modeline, except the three-dimensional effect, where BORDER-3D is -used instead. - -Optional ALT-STYLE applies an appropriate style to the mode -line's box property. - -Optional BORDER-WIDTH specifies an integer for the width of the -rectangle that produces the box effect. - -Optional FG-DISTANT should be close to the main background -values. It is intended to be used as a distant-foreground -property." - (pcase modus-operandi-theme-mode-line - ('3d - `(:background ,bg-alt :foreground ,fg-alt - :box (:line-width ,(or border-width 1) - :color ,border-3d - :style ,(and alt-style 'released-button)))) - ('moody - `(:background ,bg-alt :foreground ,fg-alt :underline ,border :overline ,border - :distant-foreground ,fg-distant)) - (_ - `(:foreground ,fg :background ,bg :box ,border)))) - -(defun modus-operandi-theme-diff (fg-only-bg fg-only-fg mainbg mainfg altbg altfg) - "Colour combinations for `modus-operandi-theme-diffs'. - -FG-ONLY-BG should be similar or the same as the main background. -FG-ONLY-FG should be a saturated accent value that can be -combined with the former. - -MAINBG must be one of the dedicated backgrounds for diffs while -MAINFG must be the same for the foreground. - -ALTBG needs to be a slightly accented background that is meant to -be combined with ALTFG. Both must be less intense than MAINBG -and MAINFG respectively." - (pcase modus-operandi-theme-diffs - ('fg-only (list :background fg-only-bg :foreground fg-only-fg)) - ('desaturated (list :background altbg :foreground altfg)) - (_ (list :background mainbg :foreground mainfg)))) - -(defun modus-operandi-theme-standard-completions (mainfg subtlebg intensebg intensefg) - "Combinations for `modus-operandi-theme-completions'. - -MAINFG is an accented foreground value. SUBTLEBG is an accented -background value that can be combined with MAINFG. INTENSEBG and -INTENSEFG are accented colours that are designed to be used in -tandem. - -These are intended for Icomplete, Ido, and related." - (pcase modus-operandi-theme-completions - ('opinionated (list :background intensebg :foreground intensefg)) - ('moderate (list :background subtlebg :foreground mainfg)) - (_ (list :foreground mainfg)))) - -(defun modus-operandi-theme-extra-completions (subtleface intenseface altface &optional altfg bold) - "Combinations for `modus-operandi-theme-completions'. - -SUBTLEFACE and INTENSEFACE are custom theme faces that combine a -background and foreground value. The difference between the two -is a matter of degree. - -ALTFACE is a combination of colours that represents a departure -from the UI's default aesthetics. Optional ALTFG is meant to be -used in tandem with it. - -Optional BOLD will apply a heavier weight to the text. - -These are intended for Helm, Ivy, etc." - (pcase modus-operandi-theme-completions - ('opinionated (list :inherit (list altface bold) - :foreground (or altfg 'unspecified))) - ('moderate (list :inherit (list subtleface bold))) - (_ (list :inherit (list intenseface bold))))) - -(defun modus-operandi-theme-scale (amount) - "Scale heading by AMOUNT. - -AMOUNT is a customisation option." - (when modus-operandi-theme-scale-headings - (list :height amount))) - -;;; Colour palette - -;; Define colour palette. Each colour must have a >= 7:1 contrast -;; ratio relative to the foreground/background colour it is rendered -;; against. -;; -;; The design of the colour palette as a macro that maps it to faces is -;; adapted from zenbern-theme.el, last seen at commit 7dd7968: -;; https://github.com/bbatsov/zenburn-emacs -(eval-and-compile - (defconst modus-operandi-theme-default-colors-alist - '(;; base values - ("bg-main" . "#ffffff") ("fg-main" . "#000000") - ("bg-alt" . "#f0f0f0") ("fg-alt" . "#505050") - ("bg-dim" . "#f8f8f8") ("fg-dim" . "#282828") - ;; specifically for on/off states (e.g. `mode-line') - ;; - ;; must be combined with themselves - ("bg-active" . "#d7d7d7") ("fg-active" . "#0a0a0a") - ("bg-inactive" . "#efefef") ("fg-inactive" . "#404148") - ;; special base values, used only for cases where the above - ;; fg-* or bg-* cannot or should not be used (to avoid confusion) - ;; must be combined with: {fg,bg}-{main,alt,dim} - ("bg-special-cold" . "#dde3f4") ("fg-special-cold" . "#093060") - ("bg-special-mild" . "#c4ede0") ("fg-special-mild" . "#184034") - ("bg-special-warm" . "#f0e0d4") ("fg-special-warm" . "#5d3026") - ("bg-special-calm" . "#f8ddea") ("fg-special-calm" . "#61284f") - ;; styles for the main constructs - ;; - ;; must be combined with: `bg-main', `bg-alt', `bg-dim' - ("red" . "#a60000") ("green" . "#005e00") - ("yellow" . "#813e00") ("blue" . "#0031a9") - ("magenta" . "#721045") ("cyan" . "#00538b") - ;; styles for common, but still specialised constructs - ;; - ;; must be combined with: `bg-main', `bg-alt', `bg-dim' - ("red-alt" . "#972500") ("green-alt" . "#315b00") - ("yellow-alt" . "#70480f") ("blue-alt" . "#2544bb") - ("magenta-alt" . "#8f0075") ("cyan-alt" . "#30517f") - ;; same purpose as above, just slight differences - ;; - ;; must be combined with: `bg-main', `bg-alt', `bg-dim' - ("red-alt-other" . "#a0132f") ("green-alt-other" . "#145c33") - ("yellow-alt-other" . "#863927") ("blue-alt-other" . "#0000c0") - ("magenta-alt-other" . "#5317ac") ("cyan-alt-other" . "#005a5f") - ;; styles for desaturated foreground text, intended for use with - ;; the `modus-operandi-theme-faint-syntax' option - ;; - ;; must be combined with: `bg-main', `bg-alt', `bg-dim' - ("red-faint" . "#7f1010") ("green-faint" . "#104410") - ("yellow-faint" . "#5f4400") ("blue-faint" . "#002f88") - ("magenta-faint" . "#752f50") ("cyan-faint" . "#12506f") - - ("red-alt-faint" . "#702f00") ("green-alt-faint" . "#30440f") - ("yellow-alt-faint" . "#5d5000") ("blue-alt-faint" . "#003f78") - ("magenta-alt-faint" . "#702565") ("cyan-alt-faint" . "#354f6f") - - ("red-alt-other-faint" . "#7f002f") ("green-alt-other-faint" . "#0f443f") - ("yellow-alt-other-faint" . "#5e3a20") ("blue-alt-other-faint" . "#1f2f6f") - ("magenta-alt-other-faint" . "#5f3f7f") ("cyan-alt-other-faint" . "#2e584f") - ;; styles for elements that should be very subtle, yet accented - ;; - ;; must be combined with: `bg-main', `bg-alt', `bg-dim' or any of - ;; the "nuanced" backgrounds - ("red-nuanced" . "#5f0000") ("green-nuanced" . "#004000") - ("yellow-nuanced" . "#3f3000") ("blue-nuanced" . "#201f55") - ("magenta-nuanced" . "#541f4f") ("cyan-nuanced" . "#0f3360") - ;; styles for slightly accented background - ;; - ;; must be combined with any of the above foreground values - ("red-nuanced-bg" . "#fff1f0") ("green-nuanced-bg" . "#ecf7ed") - ("yellow-nuanced-bg" . "#fff3da") ("blue-nuanced-bg" . "#f3f3ff") - ("magenta-nuanced-bg" . "#fdf0ff") ("cyan-nuanced-bg" . "#ebf6fa") - ;; styles for elements that should draw attention to themselves - ;; - ;; must be combined with: `bg-main' - ("red-intense" . "#b60000") ("green-intense" . "#006800") - ("yellow-intense" . "#904200") ("blue-intense" . "#1111ee") - ("magenta-intense" . "#7000e0") ("cyan-intense" . "#205b93") - ;; styles for background elements that should be visible yet - ;; subtle - ;; - ;; must be combined with: `fg-dim' - ("red-subtle-bg" . "#f2b0a2") ("green-subtle-bg" . "#aecf90") - ("yellow-subtle-bg" . "#e4c340") ("blue-subtle-bg" . "#b5d0ff") - ("magenta-subtle-bg" . "#f0d3ff") ("cyan-subtle-bg" . "#c0efff") - ;; styles for background elements that should be visible and - ;; distinguishable - ;; - ;; must be combined with: `fg-main' - ("red-intense-bg" . "#ff8892") ("green-intense-bg" . "#5ada88") - ("yellow-intense-bg" . "#f5df23") ("blue-intense-bg" . "#6aaeff") - ("magenta-intense-bg" . "#d5baff") ("cyan-intense-bg" . "#42cbd4") - ;; styles for refined contexts where both the foreground and the - ;; background need to have the same/similar hue - ;; - ;; must be combined with themselves OR the foregrounds can be - ;; combined with any of the base backgrounds - ("red-refine-bg" . "#ffcccc") ("red-refine-fg" . "#780000") - ("green-refine-bg" . "#aceaac") ("green-refine-fg" . "#004c00") - ("yellow-refine-bg" . "#fff29a") ("yellow-refine-fg" . "#604000") - ("blue-refine-bg" . "#8ac7ff") ("blue-refine-fg" . "#002288") - ("magenta-refine-bg" . "#ffccff") ("magenta-refine-fg" . "#770077") - ("cyan-refine-bg" . "#8eecf4") ("cyan-refine-fg" . "#004850") - ;; styles that are meant exclusively for the mode line - ;; - ;; must be combined with: `bg-active', `bg-inactive' - ("red-active" . "#8a0000") ("green-active" . "#004c2e") - ("yellow-active" . "#702d1f") ("blue-active" . "#0030b4") - ("magenta-active" . "#5c2092") ("cyan-active" . "#003f8a") - ;; styles that are meant exclusively for the fringes - ;; - ;; must be combined with `fg-main' - ("red-fringe-bg" . "#f08290") ("green-fringe-bg" . "#62c86a") - ("yellow-fringe-bg" . "#dbba3f") ("blue-fringe-bg" . "#82afff") - ("magenta-fringe-bg" . "#e0a3ff") ("cyan-fringe-bg" . "#2fcddf") - ;; styles reserved for specific faces - ;; - ;; `bg-hl-line' is between `bg-dim' and `bg-alt', so it should - ;; work with all accents that cover those two, plus `bg-main' - ;; - ;; `bg-hl-alt' and `bg-hl-alt-intense' should only be used when no - ;; other greyscale or fairly neutral background is available to - ;; properly draw attention to a given construct - ;; - ;; `bg-header' is between `bg-active' and `bg-inactive', so it - ;; can be combined with any of the "active" values, plus the - ;; "special" and base foreground colours - ;; - ;; `bg-paren-match', `bg-paren-match-intense', `bg-region' and - ;; `bg-tab-active' must be combined with `fg-main', while - ;; `bg-tab-inactive' should be combined with `fg-dim' - ;; - ;; `bg-tab-bar' is only intended for the bar that holds the tabs and - ;; can only be combined with `fg-main' - ;; - ;; `fg-tab-active' is meant to be combined with `bg-tab-active', - ;; though only for styling special elements, such as underlining - ;; the current tab - ;; - ;; `fg-escape-char-construct' and `fg-escape-char-backslash' can - ;; be combined `bg-main', `bg-dim', `bg-alt' - ;; - ;; `fg-lang-error', `fg-lang-warning', `fg-lang-note' can be - ;; combined with `bg-main', `bg-dim', `bg-alt' - ;; - ;; `fg-mark-sel', `fg-mark-del', `fg-mark-alt' can be combined - ;; with `bg-main', `bg-dim', `bg-alt', `bg-hl-line' - ;; - ;; `fg-unfocused' must be combined with `fg-main' - ;; - ;; the window divider colours apply to faces with just an fg value - ;; - ;; all pairs are combinable with themselves - ("bg-hl-line" . "#f2eff3") - ("bg-hl-line-intense" . "#e0e0e0") - ("bg-hl-alt" . "#fbeee0") - ("bg-hl-alt-intense" . "#e8dfd1") - ("bg-paren-match" . "#e0af82") - ("bg-paren-match-intense" . "#c488ff") - ("bg-region" . "#bcbcbc") - - ("bg-tab-bar" . "#d5d5d5") - ("bg-tab-active" . "#f6f6f6") - ("bg-tab-inactive" . "#bdbdbd") - ("fg-tab-active" . "#30169e") - - ("fg-escape-char-construct" . "#8b1030") - ("fg-escape-char-backslash" . "#654d0f") - - ("fg-lang-error" . "#9f004f") - ("fg-lang-warning" . "#604f0f") - ("fg-lang-note" . "#4040ae") - - ("fg-window-divider-inner" . "#888888") - ("fg-window-divider-outer" . "#585858") - - ("fg-unfocused" . "#56576d") - - ("bg-header" . "#e5e5e5") ("fg-header" . "#2a2a2a") - - ("bg-whitespace" . "#fff8fc") ("fg-whitespace" . "#645060") - - ("bg-diff-heading" . "#b7c2dd") ("fg-diff-heading" . "#043355") - ("bg-diff-added" . "#d4fad4") ("fg-diff-added" . "#004500") - ("bg-diff-changed" . "#fcefcf") ("fg-diff-changed" . "#524200") - ("bg-diff-removed" . "#ffe8ef") ("fg-diff-removed" . "#691616") - - ("bg-diff-refine-added" . "#94cf94") ("fg-diff-refine-added" . "#002a00") - ("bg-diff-refine-changed" . "#cccf8f") ("fg-diff-refine-changed" . "#302010") - ("bg-diff-refine-removed" . "#daa2b0") ("fg-diff-refine-removed" . "#400000") - - ("bg-diff-focus-added" . "#bbeabb") ("fg-diff-focus-added" . "#002c00") - ("bg-diff-focus-changed" . "#ecdfbf") ("fg-diff-focus-changed" . "#392900") - ("bg-diff-focus-removed" . "#efcbcf") ("fg-diff-focus-removed" . "#4a0000") - - ("bg-diff-neutral-0" . "#979797") ("fg-diff-neutral-0" . "#040404") - ("bg-diff-neutral-1" . "#b0b0b0") ("fg-diff-neutral-1" . "#252525") - ("bg-diff-neutral-2" . "#cccccc") ("fg-diff-neutral-2" . "#3a3a3a") - - ("bg-mark-sel" . "#a0f0cf") ("fg-mark-sel" . "#005040") - ("bg-mark-del" . "#ffccbb") ("fg-mark-del" . "#840040") - ("bg-mark-alt" . "#f5d88f") ("fg-mark-alt" . "#782900")) - "The entire palette of `modus-operandi-theme'. -Each element has the form (NAME . HEX).") - - (defcustom modus-operandi-theme-override-colors-alist '() - "Association list of palette colour overrides. -Values can be mapped to variables, using the same syntax as the -one present in `modus-operandi-theme-default-colors-alist'. - -This is only meant for do-it-yourself usage, with the -understanding that the user is responsible for the resulting -contrast ratio between new and existing colours." - :type '(alist - :key-type (string :tag "Name") - :value-type (string :tag " Hex"))) - - (defmacro modus-operandi-theme-with-color-variables (&rest body) - "`let' bind all colours around BODY. -Also bind `class' to ((class color) (min-colors 89))." - (declare (indent 0)) - `(let ((class '((class color) (min-colors 89))) - ,@(mapcar (lambda (cons) - (list (intern (car cons)) (cdr cons))) - (append modus-operandi-theme-default-colors-alist - modus-operandi-theme-override-colors-alist)) - ;; simple conditional styles that evaluate user-facing - ;; customisation options - (modus-theme-slant - (if modus-operandi-theme-slanted-constructs 'italic 'normal)) - (modus-theme-variable-pitch - (if modus-operandi-theme-variable-pitch-headings 'variable-pitch 'default))) - ,@body))) - - - -;;; Faces - -(modus-operandi-theme-with-color-variables - (custom-theme-set-faces - 'modus-operandi -;;;; custom faces - ;; these bespoke faces are inherited by other constructs below -;;;;; subtle coloured backgrounds - `(modus-theme-subtle-red ((,class :background ,red-subtle-bg :foreground ,fg-dim))) - `(modus-theme-subtle-green ((,class :background ,green-subtle-bg :foreground ,fg-dim))) - `(modus-theme-subtle-yellow ((,class :background ,yellow-subtle-bg :foreground ,fg-dim))) - `(modus-theme-subtle-blue ((,class :background ,blue-subtle-bg :foreground ,fg-dim))) - `(modus-theme-subtle-magenta ((,class :background ,magenta-subtle-bg :foreground ,fg-dim))) - `(modus-theme-subtle-cyan ((,class :background ,cyan-subtle-bg :foreground ,fg-dim))) - `(modus-theme-subtle-neutral ((,class :background ,bg-inactive :foreground ,fg-inactive))) -;;;;; intense coloured backgrounds - `(modus-theme-intense-red ((,class :background ,red-intense-bg :foreground ,fg-main))) - `(modus-theme-intense-green ((,class :background ,green-intense-bg :foreground ,fg-main))) - `(modus-theme-intense-yellow ((,class :background ,yellow-intense-bg :foreground ,fg-main))) - `(modus-theme-intense-blue ((,class :background ,blue-intense-bg :foreground ,fg-main))) - `(modus-theme-intense-magenta ((,class :background ,magenta-intense-bg :foreground ,fg-main))) - `(modus-theme-intense-cyan ((,class :background ,cyan-intense-bg :foreground ,fg-main))) - `(modus-theme-intense-neutral ((,class :background ,bg-active :foreground ,fg-main))) -;;;;; refined background and foreground combinations - ;; general purpose styles that use an accented foreground against an - ;; accented background - `(modus-theme-refine-red ((,class :background ,red-refine-bg :foreground ,red-refine-fg))) - `(modus-theme-refine-green ((,class :background ,green-refine-bg :foreground ,green-refine-fg))) - `(modus-theme-refine-yellow ((,class :background ,yellow-refine-bg :foreground ,yellow-refine-fg))) - `(modus-theme-refine-blue ((,class :background ,blue-refine-bg :foreground ,blue-refine-fg))) - `(modus-theme-refine-magenta ((,class :background ,magenta-refine-bg :foreground ,magenta-refine-fg))) - `(modus-theme-refine-cyan ((,class :background ,cyan-refine-bg :foreground ,cyan-refine-fg))) -;;;;; "active" combinations, mostly for use on the mode line - `(modus-theme-active-red ((,class :background ,red-active :foreground ,bg-active))) - `(modus-theme-active-green ((,class :background ,green-active :foreground ,bg-active))) - `(modus-theme-active-yellow ((,class :background ,yellow-active :foreground ,bg-active))) - `(modus-theme-active-blue ((,class :background ,blue-active :foreground ,bg-active))) - `(modus-theme-active-magenta ((,class :background ,magenta-active :foreground ,bg-active))) - `(modus-theme-active-cyan ((,class :background ,cyan-active :foreground ,bg-active))) -;;;;; nuanced backgrounds - ;; useful for adding an accented background that is suitable for all - ;; main foreground colours (intended for use in Org source blocks) - `(modus-theme-nuanced-red ((,class :background ,red-nuanced-bg - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(modus-theme-nuanced-green ((,class :background ,green-nuanced-bg - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(modus-theme-nuanced-yellow ((,class :background ,yellow-nuanced-bg - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(modus-theme-nuanced-blue ((,class :background ,blue-nuanced-bg - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(modus-theme-nuanced-magenta ((,class :background ,magenta-nuanced-bg - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(modus-theme-nuanced-cyan ((,class :background ,cyan-nuanced-bg - ,@(and (>= emacs-major-version 27) '(:extend t))))) -;;;;; fringe-specific combinations - `(modus-theme-fringe-red ((,class :background ,red-fringe-bg :foreground ,fg-main))) - `(modus-theme-fringe-green ((,class :background ,green-fringe-bg :foreground ,fg-main))) - `(modus-theme-fringe-yellow ((,class :background ,yellow-fringe-bg :foreground ,fg-main))) - `(modus-theme-fringe-blue ((,class :background ,blue-fringe-bg :foreground ,fg-main))) - `(modus-theme-fringe-magenta ((,class :background ,magenta-fringe-bg :foreground ,fg-main))) - `(modus-theme-fringe-cyan ((,class :background ,cyan-fringe-bg :foreground ,fg-main))) -;;;;; special base values - ;; these are closer to the grayscale than the accents defined above - ;; and should only be used when the next closest alternative would be - ;; a greyscale value than an accented one - `(modus-theme-special-cold ((,class :background ,bg-special-cold :foreground ,fg-special-cold))) - `(modus-theme-special-mild ((,class :background ,bg-special-mild :foreground ,fg-special-mild))) - `(modus-theme-special-warm ((,class :background ,bg-special-warm :foreground ,fg-special-warm))) - `(modus-theme-special-calm ((,class :background ,bg-special-calm :foreground ,fg-special-calm))) -;;;;; diff-specific combinations - ;; intended for `diff-mode' or equivalent - `(modus-theme-diff-added - ((,class ,@(modus-operandi-theme-diff - bg-main green - bg-diff-focus-added fg-diff-focus-added - green-nuanced-bg fg-diff-added)))) - `(modus-theme-diff-changed - ((,class ,@(modus-operandi-theme-diff - bg-main yellow - bg-diff-focus-changed fg-diff-focus-changed - yellow-nuanced-bg fg-diff-changed)))) - `(modus-theme-diff-removed - ((,class ,@(modus-operandi-theme-diff - bg-main red - bg-diff-focus-removed fg-diff-focus-removed - red-nuanced-bg fg-diff-removed)))) - `(modus-theme-diff-refine-added - ((,class ,@(modus-operandi-theme-diff - bg-diff-added fg-diff-added - bg-diff-refine-added fg-diff-refine-added - bg-diff-focus-added fg-diff-focus-added)))) - `(modus-theme-diff-refine-changed - ((,class ,@(modus-operandi-theme-diff - bg-diff-changed fg-diff-changed - bg-diff-refine-changed fg-diff-refine-changed - bg-diff-focus-changed fg-diff-focus-changed)))) - `(modus-theme-diff-refine-removed - ((,class ,@(modus-operandi-theme-diff - bg-diff-removed fg-diff-removed - bg-diff-refine-removed fg-diff-refine-removed - bg-diff-focus-removed fg-diff-focus-removed)))) - `(modus-theme-diff-focus-added - ((,class ,@(modus-operandi-theme-diff - bg-dim green - bg-diff-focus-added fg-diff-focus-added - bg-diff-added fg-diff-added)))) - `(modus-theme-diff-focus-changed - ((,class ,@(modus-operandi-theme-diff - bg-dim yellow - bg-diff-focus-changed fg-diff-focus-changed - bg-diff-changed fg-diff-changed)))) - `(modus-theme-diff-focus-removed - ((,class ,@(modus-operandi-theme-diff - bg-dim red - bg-diff-focus-removed fg-diff-focus-removed - bg-diff-removed fg-diff-removed)))) - `(modus-theme-diff-heading - ((,class ,@(modus-operandi-theme-diff - bg-alt blue-alt - bg-diff-heading fg-diff-heading - blue-nuanced-bg blue)))) -;;;;; mark indicators - ;; colour combinations intended for Dired, Ibuffer, or equivalent - `(modus-theme-pseudo-header ((,class :inherit bold :foreground ,fg-main))) - `(modus-theme-mark-alt ((,class :inherit bold :background ,bg-mark-alt :foreground ,fg-mark-alt))) - `(modus-theme-mark-del ((,class :inherit bold :background ,bg-mark-del :foreground ,fg-mark-del))) - `(modus-theme-mark-sel ((,class :inherit bold :background ,bg-mark-sel :foreground ,fg-mark-sel))) - `(modus-theme-mark-symbol ((,class :inherit bold :foreground ,blue-alt))) -;;;;; heading levels - ;; styles for regular headings used in Org, Markdown, Info, etc. - `(modus-theme-heading-1 - ((,class ,@(modus-operandi-theme-heading - 1 fg-main magenta-alt-other magenta-nuanced-bg bg-region) - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-4)))) - `(modus-theme-heading-2 - ((,class ,@(modus-operandi-theme-heading - 2 fg-special-warm magenta-alt red-nuanced-bg bg-region) - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-3)))) - `(modus-theme-heading-3 - ((,class ,@(modus-operandi-theme-heading - 3 fg-special-cold blue blue-nuanced-bg bg-region) - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-2)))) - `(modus-theme-heading-4 - ((,class ,@(modus-operandi-theme-heading - 4 fg-special-mild cyan cyan-nuanced-bg bg-region) - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-1)))) - `(modus-theme-heading-5 - ((,class ,@(modus-operandi-theme-heading - 5 fg-special-calm green-alt-other green-nuanced-bg bg-region)))) - `(modus-theme-heading-6 - ((,class ,@(modus-operandi-theme-heading - 6 yellow-nuanced yellow-alt-other yellow-nuanced-bg bg-region)))) - `(modus-theme-heading-7 - ((,class ,@(modus-operandi-theme-heading - 7 red-nuanced red-alt red-nuanced-bg bg-region)))) - `(modus-theme-heading-8 - ((,class ,@(modus-operandi-theme-heading - 8 fg-dim magenta bg-alt bg-region)))) -;;;;; other custom faces - `(modus-theme-hl-line ((,class :background ,(if modus-operandi-theme-intense-hl-line - bg-hl-line-intense bg-hl-line) - (and (>= emacs-major-version 27) '(:extend t))))) -;;;; standard faces -;;;;; absolute essentials - `(default ((,class :background ,bg-main :foreground ,fg-main))) - `(cursor ((,class :background ,fg-main))) - `(fringe ((,class ,@(modus-operandi-theme-fringe bg-inactive bg-active) - :foreground ,fg-main))) - `(vertical-border ((,class :foreground ,fg-window-divider-inner))) -;;;;; basic and/or ungrouped styles - ;; Modify the `bold' face to change the weight of all "bold" elements - ;; defined by the theme. You need a typeface that supports a - ;; multitude of heavier weights than the regular one and then you - ;; must specify the exact name of the one you wish to apply. Example - ;; for your init.el: - ;; - ;; (set-face-attribute 'bold nil :weight 'semibold) - `(bold ((,class :weight bold))) - `(comint-highlight-input ((,class :inherit bold))) - `(comint-highlight-prompt ((,class ,@(modus-operandi-theme-bold-weight) - ,@(modus-operandi-theme-prompt - cyan - blue-nuanced-bg blue-alt - blue-refine-bg fg-main)))) - `(error ((,class :inherit bold :foreground ,red))) - `(escape-glyph ((,class :foreground ,fg-escape-char-construct))) - `(file-name-shadow ((,class :foreground ,fg-unfocused))) - `(header-line ((,class :background ,bg-header :foreground ,fg-header))) - `(header-line-highlight ((,class :inherit modus-theme-active-blue))) - `(help-argument-name ((,class :foreground ,cyan :slant ,modus-theme-slant))) - `(homoglyph ((,class :foreground ,fg-escape-char-construct))) - `(ibuffer-locked-buffer ((,class :foreground ,yellow-alt-other))) - `(italic ((,class :slant italic))) - `(nobreak-hyphen ((,class :foreground ,fg-escape-char-construct))) - `(nobreak-space ((,class :foreground ,fg-escape-char-construct :underline t))) - `(minibuffer-prompt ((,class ,@(modus-operandi-theme-prompt - cyan-alt-other - cyan-nuanced-bg cyan - cyan-refine-bg fg-main)))) - `(mm-command-output ((,class :foreground ,red-alt-other))) - `(mm-uu-extract ((,class :background ,bg-dim :foreground ,fg-special-mild))) - `(next-error ((,class :inherit modus-theme-subtle-red))) - `(rectangle-preview ((,class :inherit modus-theme-special-mild))) - `(region ((,class :background ,bg-region :foreground ,fg-main))) - `(secondary-selection ((,class :inherit modus-theme-special-cold))) - `(shadow ((,class :foreground ,fg-alt))) - `(success ((,class :inherit bold :foreground ,green))) - `(trailing-whitespace ((,class :background ,red-intense-bg))) - `(warning ((,class :inherit bold :foreground ,yellow))) -;;;;; buttons, links, widgets - `(button ((,class :foreground ,blue-alt-other - ,@(unless modus-operandi-theme-no-link-underline - (list :underline t))))) - `(link ((,class :inherit button))) - `(link-visited ((,class :inherit link :foreground ,magenta-alt-other))) - `(tooltip ((,class :background ,bg-special-cold :foreground ,fg-main))) - `(widget-button ((,class :inherit button))) - `(widget-button-pressed ((,class :inherit button :foreground ,magenta))) - `(widget-documentation ((,class :foreground ,green))) - `(widget-field ((,class :background ,bg-alt :foreground ,fg-dim))) - `(widget-inactive ((,class :background ,bg-inactive :foreground ,fg-inactive))) - `(widget-single-line-field ((,class :inherit widget-field))) -;;;;; ag - `(ag-hit-face ((,class :foreground ,fg-special-cold))) - `(ag-match-face ((,class :inherit modus-theme-special-calm))) -;;;;; alert - `(alert-high-face ((,class :inherit bold :foreground ,red-alt))) - `(alert-low-face ((,class :foreground ,fg-special-mild))) - `(alert-moderate-face ((,class :inherit bold :foreground ,yellow))) - `(alert-trivial-face ((,class :foreground ,fg-special-calm))) - `(alert-urgent-face ((,class :inherit bold :foreground ,red-intense))) -;;;;; all-the-icons - `(all-the-icons-blue ((,class :foreground ,blue))) - `(all-the-icons-blue-alt ((,class :foreground ,blue-alt))) - `(all-the-icons-cyan ((,class :foreground ,cyan))) - `(all-the-icons-cyan-alt ((,class :foreground ,cyan-alt))) - `(all-the-icons-dblue ((,class :foreground ,blue-alt-other))) - `(all-the-icons-dcyan ((,class :foreground ,cyan-alt-other))) - `(all-the-icons-dgreen ((,class :foreground ,green-alt-other))) - `(all-the-icons-dired-dir-face ((,class :foreground ,blue))) - `(all-the-icons-dmaroon ((,class :foreground ,magenta-alt-other))) - `(all-the-icons-dorange ((,class :foreground ,red-alt-other))) - `(all-the-icons-dpink ((,class :foreground ,magenta))) - `(all-the-icons-dpurple ((,class :foreground ,magenta-alt))) - `(all-the-icons-dred ((,class :foreground ,red))) - `(all-the-icons-dsilver ((,class :foreground ,fg-special-cold))) - `(all-the-icons-dyellow ((,class :foreground ,yellow))) - `(all-the-icons-green ((,class :foreground ,green))) - `(all-the-icons-lblue ((,class :foreground ,blue-refine-fg))) - `(all-the-icons-lcyan ((,class :foreground ,cyan-refine-fg))) - `(all-the-icons-lgreen ((,class :foreground ,green-refine-fg))) - `(all-the-icons-lmaroon ((,class :foreground ,magenta-refine-fg))) - `(all-the-icons-lorange ((,class :foreground ,red-refine-fg))) - `(all-the-icons-lpink ((,class :foreground ,magenta-refine-fg))) - `(all-the-icons-lpurple ((,class :foreground ,magenta-refine-fg))) - `(all-the-icons-lred ((,class :foreground ,red-refine-fg))) - `(all-the-icons-lsilver ((,class :foreground ,fg-special-cold))) - `(all-the-icons-lyellow ((,class :foreground ,yellow-refine-fg))) - `(all-the-icons-maroon ((,class :foreground ,magenta))) - `(all-the-icons-orange ((,class :foreground ,red-alt))) - `(all-the-icons-pink ((,class :foreground ,magenta))) - `(all-the-icons-purple ((,class :foreground ,magenta-alt))) - `(all-the-icons-purple-alt ((,class :foreground ,magenta-alt-other))) - `(all-the-icons-red ((,class :foreground ,red))) - `(all-the-icons-red-alt ((,class :foreground ,red-alt))) - `(all-the-icons-silver ((,class :foreground ,fg-special-cold))) - `(all-the-icons-yellow ((,class :foreground ,yellow))) -;;;;; annotate - `(annotate-annotation ((,class :inherit modus-theme-subtle-blue))) - `(annotate-annotation-secondary ((,class :inherit modus-theme-subtle-green))) - `(annotate-highlight ((,class :background ,blue-nuanced-bg :underline ,blue-intense))) - `(annotate-highlight-secondary ((,class :background ,green-nuanced-bg :underline ,green-intense))) -;;;;; anzu - `(anzu-match-1 ((,class :inherit modus-theme-subtle-cyan))) - `(anzu-match-2 ((,class :inherit modus-theme-subtle-green))) - `(anzu-match-3 ((,class :inherit modus-theme-subtle-yellow))) - `(anzu-mode-line ((,class :inherit bold :foreground ,green-active))) - `(anzu-mode-line-no-match ((,class :inherit bold :foreground ,red-active))) - `(anzu-replace-highlight ((,class :inherit modus-theme-refine-yellow :underline t))) - `(anzu-replace-to ((,class :inherit (modus-theme-intense-green bold)))) -;;;;; apropos - `(apropos-function-button ((,class :inherit button :foreground ,magenta-alt-other))) - `(apropos-keybinding ((,class :inherit bold :foreground ,cyan))) - `(apropos-misc-button ((,class :inherit button :foreground ,cyan-alt-other))) - `(apropos-property ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,magenta-alt))) - `(apropos-symbol ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,blue-alt-other))) - `(apropos-user-option-button ((,class :inherit button :foreground ,green-alt-other))) - `(apropos-variable-button ((,class :inherit button :foreground ,blue))) -;;;;; apt-sources-list - `(apt-sources-list-components ((,class :foreground ,cyan))) - `(apt-sources-list-options ((,class :foreground ,yellow))) - `(apt-sources-list-suite ((,class :foreground ,green))) - `(apt-sources-list-type ((,class :foreground ,magenta))) - `(apt-sources-list-uri ((,class :foreground ,blue))) -;;;;; artbollocks-mode - `(artbollocks-face ((,class :foreground ,cyan-nuanced :underline ,fg-lang-note))) - `(artbollocks-lexical-illusions-face ((,class :background ,bg-alt :foreground ,red-alt :underline t))) - `(artbollocks-passive-voice-face ((,class :foreground ,yellow-nuanced :underline ,fg-lang-warning))) - `(artbollocks-weasel-words-face ((,class :foreground ,red-nuanced :underline ,fg-lang-error))) -;;;;; auctex and Tex - `(font-latex-bold-face ((,class :inherit bold :foreground ,fg-special-calm))) - `(font-latex-doctex-documentation-face ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(font-latex-doctex-preprocessor-face ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,red-alt-other))) - `(font-latex-italic-face ((,class :foreground ,fg-special-calm :slant italic))) - `(font-latex-math-face ((,class :foreground ,cyan-alt-other))) - `(font-latex-script-char-face ((,class :foreground ,cyan-alt-other))) - `(font-latex-sectioning-0-face ((,class :inherit ,modus-theme-variable-pitch :foreground ,blue-nuanced))) - `(font-latex-sectioning-1-face ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,blue-nuanced))) - `(font-latex-sectioning-2-face ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,blue-nuanced))) - `(font-latex-sectioning-3-face ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,blue-nuanced))) - `(font-latex-sectioning-4-face ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,blue-nuanced))) - `(font-latex-sectioning-5-face ((,class :inherit ,modus-theme-variable-pitch :foreground ,blue-nuanced))) - `(font-latex-sedate-face ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,magenta-alt-other))) - `(font-latex-slide-title-face ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,cyan-nuanced - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-4)))) - `(font-latex-string-face ((,class :foreground ,blue-alt))) - `(font-latex-subscript-face ((,class :height 0.95))) - `(font-latex-superscript-face ((,class :height 0.95))) - `(font-latex-verbatim-face ((,class :background ,bg-dim :foreground ,fg-special-mild))) - `(font-latex-warning-face ((,class :foreground ,yellow-alt-other))) - `(tex-match ((,class :foreground ,blue-alt-other))) - `(tex-verbatim ((,class :background ,bg-dim :foreground ,fg-special-mild))) - `(texinfo-heading ((,class :foreground ,magenta))) - `(TeX-error-description-error ((,class :inherit bold :foreground ,red))) - `(TeX-error-description-help ((,class :foreground ,blue))) - `(TeX-error-description-tex-said ((,class :foreground ,blue))) - `(TeX-error-description-warning ((,class :inherit bold :foreground ,yellow))) -;;;;; auto-dim-other-buffers - `(auto-dim-other-buffers-face ((,class :background ,bg-alt))) -;;;;; avy - `(avy-background-face ((,class :background ,bg-dim :foreground ,fg-dim))) - `(avy-goto-char-timer-face ((,class :inherit (modus-theme-intense-yellow bold)))) - `(avy-lead-face ((,class :inherit (modus-theme-intense-magenta bold)))) - `(avy-lead-face-0 ((,class :inherit (modus-theme-intense-blue bold)))) - `(avy-lead-face-1 ((,class :inherit (modus-theme-intense-red bold)))) - `(avy-lead-face-2 ((,class :inherit (modus-theme-intense-green bold)))) -;;;;; aw (ace-window) - `(aw-background-face ((,class :background ,bg-dim :foreground ,fg-dim))) - `(aw-key-face ((,class :inherit bold :foreground ,blue-intense))) - `(aw-leading-char-face ((,class :inherit bold :height 1.5 :background ,bg-main :foreground ,red-intense))) - `(aw-minibuffer-leading-char-face ((,class :foreground ,magenta-active))) - `(aw-mode-line-face ((,class :inherit bold))) -;;;;; awesome-tray - `(awesome-tray-module-awesome-tab-face ((,class :inherit bold :foreground ,red-alt-other))) - `(awesome-tray-module-battery-face ((,class :inherit bold :foreground ,cyan-alt-other))) - `(awesome-tray-module-buffer-name-face ((,class :inherit bold :foreground ,yellow-alt-other))) - `(awesome-tray-module-circe-face ((,class :inherit bold :foreground ,blue-alt))) - `(awesome-tray-module-date-face ((,class :inherit bold :foreground ,fg-dim))) - `(awesome-tray-module-evil-face ((,class :inherit bold :foreground ,green-alt))) - `(awesome-tray-module-git-face ((,class :inherit bold :foreground ,magenta))) - `(awesome-tray-module-last-command-face ((,class :inherit bold :foreground ,blue-alt-other))) - `(awesome-tray-module-location-face ((,class :inherit bold :foreground ,yellow))) - `(awesome-tray-module-mode-name-face ((,class :inherit bold :foreground ,green))) - `(awesome-tray-module-parent-dir-face ((,class :inherit bold :foreground ,cyan))) - `(awesome-tray-module-rvm-face ((,class :inherit bold :foreground ,magenta-alt-other))) -;;;;; binder - `(binder-sidebar-highlight ((,class :inherit modus-theme-subtle-cyan))) - `(binder-sidebar-marked ((,class :inherit modus-theme-mark-sel))) - `(binder-sidebar-missing ((,class :inherit modus-theme-subtle-red))) - `(binder-sidebar-tags ((,class :foreground ,cyan))) -;;;;; bm - `(bm-face ((,class :inherit modus-theme-subtle-yellow - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(bm-fringe-face ((,class :inherit modus-theme-fringe-yellow))) - `(bm-fringe-persistent-face ((,class :inherit modus-theme-fringe-blue))) - `(bm-persistent-face ((,class :inherit modus-theme-intense-blue - ,@(and (>= emacs-major-version 27) '(:extend t))))) -;;;;; bongo - `(bongo-album-title ((,class :foreground ,cyan-active))) - `(bongo-artist ((,class :foreground ,magenta-active))) - `(bongo-currently-playing-track ((,class :inherit bold))) - `(bongo-elapsed-track-part ((,class :inherit modus-theme-subtle-magenta :underline t))) - `(bongo-filled-seek-bar ((,class :background ,blue-subtle-bg :foreground ,fg-main))) - `(bongo-marked-track ((,class :foreground ,fg-mark-alt))) - `(bongo-marked-track-line ((,class :background ,bg-mark-alt))) - `(bongo-played-track ((,class :foreground ,fg-unfocused :strike-through t))) - `(bongo-track-length ((,class :foreground ,blue-alt-other))) - `(bongo-track-title ((,class :foreground ,blue-active))) - `(bongo-unfilled-seek-bar ((,class :background ,blue-nuanced-bg :foreground ,fg-main))) -;;;;; boon - `(boon-modeline-cmd ((,class :inherit modus-theme-active-blue))) - `(boon-modeline-ins ((,class :inherit modus-theme-active-red))) - `(boon-modeline-off ((,class :inherit modus-theme-active-yellow))) - `(boon-modeline-spc ((,class :inherit modus-theme-active-green))) -;;;;; breakpoint (built-in gdb-mi.el) - `(breakpoint-disabled ((,class :foreground ,fg-alt))) - `(breakpoint-enabled ((,class :inherit bold :foreground ,red))) -;;;;; buffer-expose - `(buffer-expose-ace-char-face ((,class :inherit bold :foreground ,red-active))) - `(buffer-expose-mode-line-face ((,class :foreground ,cyan-active))) - `(buffer-expose-selected-face ((,class :inherit modus-theme-special-mild))) -;;;;; calendar and diary - `(calendar-month-header ((,class :inherit bold :foreground ,fg-main))) - `(calendar-today ((,class :underline t))) - `(calendar-weekday-header ((,class :foreground ,fg-dim))) - `(calendar-weekend-header ((,class :foreground ,fg-alt))) - `(diary ((,class :foreground ,cyan-alt-other))) - `(diary-anniversary ((,class :foreground ,red-alt-other))) - `(diary-time ((,class :foreground ,blue-alt))) - `(holiday ((,class :foreground ,magenta-alt))) -;;;;; calfw - `(cfw:face-annotation ((,class :foreground ,fg-special-warm))) - `(cfw:face-day-title ((,class :foreground ,fg-main))) - `(cfw:face-default-content ((,class :foreground ,green-alt))) - `(cfw:face-default-day ((,class :inherit (cfw:face-day-title bold)))) - `(cfw:face-disable ((,class :foreground ,fg-unfocused))) - `(cfw:face-grid ((,class :foreground ,fg-window-divider-outer))) - `(cfw:face-header ((,class :inherit bold :foreground ,fg-main))) - `(cfw:face-holiday ((,class :foreground ,magenta-alt-other))) - `(cfw:face-periods ((,class :foreground ,cyan-alt-other))) - `(cfw:face-saturday ((,class :inherit bold :foreground ,cyan-alt-other))) - `(cfw:face-select ((,class :inherit modus-theme-intense-blue))) - `(cfw:face-sunday ((,class :inherit bold :foreground ,cyan-alt-other))) - `(cfw:face-title ((,class :inherit ,modus-theme-variable-pitch - :foreground ,fg-special-cold - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-5)))) - `(cfw:face-today ((,class :background ,bg-inactive))) - `(cfw:face-today-title ((,class :background ,bg-active))) - `(cfw:face-toolbar ((,class :background ,bg-alt :foreground ,bg-alt))) - `(cfw:face-toolbar-button-off ((,class :foreground ,fg-alt))) - `(cfw:face-toolbar-button-on ((,class :inherit bold :background ,blue-nuanced-bg - :foreground ,blue-alt))) -;;;;; centaur-tabs - `(centaur-tabs-active-bar-face ((,class :background ,fg-tab-active))) - `(centaur-tabs-close-mouse-face ((,class :inherit bold :foreground ,red-active :underline t))) - `(centaur-tabs-close-selected ((,class :inherit centaur-tabs-selected))) - `(centaur-tabs-close-unselected ((,class :inherit centaur-tabs-unselected))) - `(centaur-tabs-modified-marker-selected ((,class :inherit centaur-tabs-selected))) - `(centaur-tabs-modified-marker-unselected ((,class :inherit centaur-tabs-unselected))) - `(centaur-tabs-default ((,class :background ,bg-main :foreground ,bg-main))) - `(centaur-tabs-selected ((,class :inherit bold :background ,bg-tab-active :foreground ,fg-main))) - `(centaur-tabs-selected-modified ((,class :background ,bg-tab-active :foreground ,fg-main :slant italic))) - `(centaur-tabs-unselected ((,class :background ,bg-tab-inactive :foreground ,fg-dim))) - `(centaur-tabs-unselected-modified ((,class :background ,bg-tab-inactive :foreground ,fg-dim :slant italic))) -;;;;; change-log and log-view (`vc-print-log' and `vc-print-root-log') - `(change-log-acknowledgment ((,class :foreground ,fg-alt))) - `(change-log-conditionals ((,class :foreground ,magenta-alt))) - `(change-log-date ((,class :foreground ,cyan-alt-other))) - `(change-log-email ((,class :foreground ,cyan))) - `(change-log-file ((,class :foreground ,blue))) - `(change-log-function ((,class :foreground ,green-alt-other))) - `(change-log-list ((,class :foreground ,magenta-alt-other))) - `(change-log-name ((,class :foreground ,cyan))) - `(log-edit-header ((,class :foreground ,fg-special-warm))) - `(log-edit-summary ((,class :inherit bold :foreground ,cyan))) - `(log-edit-unknown-header ((,class :foreground ,fg-alt))) - `(log-view-file ((,class :inherit bold :foreground ,fg-special-cold))) - `(log-view-message ((,class :foreground ,fg-alt))) -;;;;; cider - `(cider-debug-code-overlay-face ((,class :background ,bg-alt))) - `(cider-debug-prompt-face ((,class :foreground ,magenta-alt :underline t))) - `(cider-deprecated-face ((,class :inherit modus-theme-refine-yellow))) - `(cider-docview-emphasis-face ((,class :foreground ,fg-special-cold :slant italic))) - `(cider-docview-literal-face ((,class :foreground ,blue-alt))) - `(cider-docview-strong-face ((,class :inherit bold :foreground ,fg-special-cold))) - `(cider-docview-table-border-face ((,class :foreground ,fg-alt))) - `(cider-enlightened-face ((,class :box (:line-width -1 :color ,yellow-alt :style nil) :background ,bg-dim))) - `(cider-enlightened-local-face ((,class :inherit bold :foreground ,yellow-alt-other))) - `(cider-error-highlight-face ((,class :foreground ,red :underline t))) - `(cider-fragile-button-face ((,class :box (:line-width 3 :color ,fg-alt :style released-button) :foreground ,yellow))) - `(cider-fringe-good-face ((,class :foreground ,green-active))) - `(cider-instrumented-face ((,class :box (:line-width -1 :color ,red :style nil) :background ,bg-dim))) - `(cider-reader-conditional-face ((,class :foreground ,fg-special-warm :slant italic))) - `(cider-repl-input-face ((,class :inherit bold))) - `(cider-repl-prompt-face ((,class :foreground ,cyan-alt-other))) - `(cider-repl-stderr-face ((,class :inherit bold :foreground ,red))) - `(cider-repl-stdout-face ((,class :foreground ,blue))) - `(cider-result-overlay-face ((,class :box (:line-width -1 :color ,blue :style nil) :background ,bg-dim))) - `(cider-stacktrace-error-class-face ((,class :inherit bold :foreground ,red))) - `(cider-stacktrace-error-message-face ((,class :foreground ,red-alt-other :slant italic))) - `(cider-stacktrace-face ((,class :foreground ,fg-main))) - `(cider-stacktrace-filter-active-face ((,class :foreground ,cyan-alt :underline t))) - `(cider-stacktrace-filter-inactive-face ((,class :foreground ,cyan-alt))) - `(cider-stacktrace-fn-face ((,class :inherit bold :foreground ,fg-main))) - `(cider-stacktrace-ns-face ((,class :foreground ,fg-alt :slant italic))) - `(cider-stacktrace-promoted-button-face ((,class :box (:line-width 3 :color ,fg-alt :style released-button) :foreground ,red))) - `(cider-stacktrace-suppressed-button-face ((,class :box (:line-width 3 :color ,fg-alt :style pressed-button) - :background ,bg-alt :foreground ,fg-alt))) - `(cider-test-error-face ((,class :inherit modus-theme-subtle-red))) - `(cider-test-failure-face ((,class :inherit (modus-theme-intense-red bold)))) - `(cider-test-success-face ((,class :inherit modus-theme-intense-green))) - `(cider-traced-face ((,class :box (:line-width -1 :color ,cyan :style nil) :background ,bg-dim))) - `(cider-warning-highlight-face ((,class :foreground ,yellow :underline t))) -;;;;; circe (and lui) - `(circe-fool-face ((,class :foreground ,fg-alt))) - `(circe-highlight-nick-face ((,class :inherit bold :foreground ,blue))) - `(circe-prompt-face ((,class :inherit bold :foreground ,cyan-alt-other))) - `(circe-server-face ((,class :foreground ,fg-unfocused))) - `(lui-button-face ((,class :inherit button :foreground ,blue))) - `(lui-highlight-face ((,class :foreground ,magenta-alt))) - `(lui-time-stamp-face ((,class :foreground ,blue-nuanced))) -;;;;; color-rg - `(color-rg-font-lock-column-number ((,class :foreground ,magenta-alt-other))) - `(color-rg-font-lock-command ((,class :inherit bold :foreground ,fg-main))) - `(color-rg-font-lock-file ((,class :inherit bold :foreground ,fg-special-cold))) - `(color-rg-font-lock-flash ((,class :inherit modus-theme-intense-blue))) - `(color-rg-font-lock-function-location ((,class :inherit modus-theme-special-calm))) - `(color-rg-font-lock-header-line-directory ((,class :foreground ,blue-active))) - `(color-rg-font-lock-header-line-edit-mode ((,class :foreground ,magenta-active))) - `(color-rg-font-lock-header-line-keyword ((,class :foreground ,green-active))) - `(color-rg-font-lock-header-line-text ((,class :foreground ,fg-active))) - `(color-rg-font-lock-line-number ((,class :foreground ,fg-special-warm))) - `(color-rg-font-lock-mark-changed ((,class :inherit bold :foreground ,blue))) - `(color-rg-font-lock-mark-deleted ((,class :inherit bold :foreground ,red))) - `(color-rg-font-lock-match ((,class :inherit modus-theme-special-calm))) - `(color-rg-font-lock-position-splitter ((,class :foreground ,fg-alt))) -;;;;; column-enforce-mode - `(column-enforce-face ((,class :inherit modus-theme-refine-yellow))) -;;;;; company-mode - `(company-echo-common ((,class :foreground ,magenta-alt-other))) - `(company-preview ((,class :background ,bg-dim :foreground ,fg-dim))) - `(company-preview-common ((,class :foreground ,blue-alt))) - `(company-preview-search ((,class :inherit modus-theme-special-calm))) - `(company-scrollbar-bg ((,class :background ,bg-active))) - `(company-scrollbar-fg ((,class :background ,fg-active))) - `(company-template-field ((,class :inherit modus-theme-intense-magenta))) - `(company-tooltip ((,class :background ,bg-alt :foreground ,fg-alt))) - `(company-tooltip-annotation ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(company-tooltip-annotation-selection ((,class :inherit bold :foreground ,fg-main))) - `(company-tooltip-common ((,class :inherit bold :foreground ,blue-alt))) - `(company-tooltip-common-selection ((,class :foreground ,fg-main))) - `(company-tooltip-mouse ((,class :inherit modus-theme-intense-blue))) - `(company-tooltip-search ((,class :inherit (modus-theme-refine-cyan bold)))) - `(company-tooltip-search-selection ((,class :inherit (modus-theme-intense-green bold) :underline t))) - `(company-tooltip-selection ((,class :inherit (modus-theme-subtle-cyan bold)))) -;;;;; company-posframe - `(company-posframe-active-backend-name ((,class :inherit bold :background ,bg-active :foreground ,blue-active))) - `(company-posframe-inactive-backend-name ((,class :background ,bg-active :foreground ,fg-active))) - `(company-posframe-metadata ((,class :background ,bg-inactive :foreground ,fg-inactive))) -;;;;; compilation feedback - `(compilation-column-number ((,class :foreground ,magenta-alt-other))) - `(compilation-error ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,red))) - `(compilation-info ((,class :foreground ,fg-special-cold))) - `(compilation-line-number ((,class :foreground ,fg-special-warm))) - `(compilation-mode-line-exit ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,blue-active))) - `(compilation-mode-line-fail ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,red-active))) - `(compilation-mode-line-run ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,magenta-active))) - `(compilation-warning ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,yellow))) -;;;;; completions - `(completions-annotations ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(completions-common-part ((,class ,@(modus-operandi-theme-standard-completions - blue-alt blue-nuanced-bg - cyan-refine-bg cyan-refine-fg)))) - `(completions-first-difference ((,class :inherit bold - ,@(modus-operandi-theme-standard-completions - magenta-alt blue-nuanced-bg - magenta-intense-bg fg-main)))) -;;;;; counsel - `(counsel-active-mode ((,class :foreground ,magenta-alt-other))) - `(counsel-application-name ((,class :foreground ,red-alt-other))) - `(counsel-key-binding ((,class :inherit bold :foreground ,blue-alt-other))) - `(counsel-outline-1 ((,class :inherit outline-1))) - `(counsel-outline-2 ((,class :inherit outline-2))) - `(counsel-outline-3 ((,class :inherit outline-3))) - `(counsel-outline-4 ((,class :inherit outline-4))) - `(counsel-outline-5 ((,class :inherit outline-5))) - `(counsel-outline-6 ((,class :inherit outline-6))) - `(counsel-outline-7 ((,class :inherit outline-7))) - `(counsel-outline-8 ((,class :inherit outline-8))) - `(counsel-outline-default ((,class :inherit bold :foreground ,green-alt-other))) - `(counsel-variable-documentation ((,class :foreground ,yellow-alt-other :slant ,modus-theme-slant))) -;;;;; counsel-css - `(counsel-css-selector-depth-face-1 ((,class :foreground ,blue))) - `(counsel-css-selector-depth-face-2 ((,class :foreground ,cyan))) - `(counsel-css-selector-depth-face-3 ((,class :foreground ,green))) - `(counsel-css-selector-depth-face-4 ((,class :foreground ,yellow))) - `(counsel-css-selector-depth-face-5 ((,class :foreground ,magenta))) - `(counsel-css-selector-depth-face-6 ((,class :foreground ,red))) -;;;;; counsel-notmuch - `(counsel-notmuch-count-face ((,class :foreground ,cyan))) - `(counsel-notmuch-date-face ((,class :foreground ,blue))) - `(counsel-notmuch-people-face ((,class :foreground ,magenta))) - `(counsel-notmuch-subject-face ((,class :foreground ,magenta-alt-other))) -;;;;; counsel-org-capture-string - `(counsel-org-capture-string-template-body-face ((,class :foreground ,fg-special-cold))) -;;;;; cov - `(cov-coverage-not-run-face ((,class :foreground ,red-intense))) - `(cov-coverage-run-face ((,class :foreground ,green-intense))) - `(cov-heavy-face ((,class :foreground ,magenta-intense))) - `(cov-light-face ((,class :foreground ,blue-intense))) - `(cov-med-face ((,class :foreground ,yellow-intense))) - `(cov-none-face ((,class :foreground ,cyan-intense))) -;;;;; cperl-mode - `(cperl-nonoverridable-face ((,class :foreground ,yellow-alt-other))) - `(cperl-array-face ((,class :inherit bold :background ,bg-alt :foreground ,magenta-alt))) - `(cperl-hash-face ((,class :inherit bold :background ,bg-alt :foreground ,red-alt :slant ,modus-theme-slant))) -;;;;; csv-mode - `(csv-separator-face ((,class :background ,bg-special-cold :foreground ,fg-main))) -;;;;; ctrlf - `(ctrlf-highlight-active ((,class :inherit (modus-theme-intense-green bold)))) - `(ctrlf-highlight-line ((,class :inherit modus-theme-hl-line))) - `(ctrlf-highlight-passive ((,class :inherit modus-theme-refine-cyan))) -;;;;; custom (M-x customize) - `(custom-button ((,class :box (:line-width 2 :color nil :style released-button) - :background ,bg-active :foreground ,fg-main))) - `(custom-button-mouse ((,class :box (:line-width 2 :color nil :style released-button) - :background ,bg-active :foreground ,fg-active))) - `(custom-button-pressed ((,class :box (:line-width 2 :color nil :style pressed-button) - :background ,bg-active :foreground ,fg-main))) - `(custom-changed ((,class :inherit modus-theme-subtle-cyan))) - `(custom-comment ((,class :foreground ,fg-alt))) - `(custom-comment-tag ((,class :background ,bg-alt :foreground ,yellow-alt-other))) - `(custom-face-tag ((,class :inherit bold :foreground ,blue-intense))) - `(custom-group-tag ((,class :inherit bold :foreground ,green-intense))) - `(custom-group-tag-1 ((,class :inherit modus-theme-special-warm))) - `(custom-invalid ((,class :inherit (modus-theme-intense-red bold)))) - `(custom-modified ((,class :inherit modus-theme-subtle-cyan))) - `(custom-rogue ((,class :inherit modus-theme-refine-magenta))) - `(custom-set ((,class :foreground ,blue-alt))) - `(custom-state ((,class :foreground ,cyan-alt-other))) - `(custom-themed ((,class :inherit modus-theme-subtle-blue))) - `(custom-variable-tag ((,class :inherit bold :foreground ,cyan))) -;;;;; dap-mode - `(dap-mouse-eval-thing-face ((,class :box (:line-width -1 :color ,blue-active :style nil) - :background ,bg-active :foreground ,fg-main))) - `(dap-result-overlay-face ((,class :box (:line-width -1 :color ,bg-active :style nil) - :background ,bg-active :foreground ,fg-main))) - `(dap-ui-breakpoint-verified-fringe ((,class :inherit bold :foreground ,green-active))) - `(dap-ui-compile-errline ((,class :inherit bold :foreground ,red-intense))) - `(dap-ui-locals-scope-face ((,class :inherit bold :foreground ,magenta :underline t))) - `(dap-ui-locals-variable-face ((,class :inherit bold :foreground ,cyan))) - `(dap-ui-locals-variable-leaf-face ((,class :foreground ,cyan-alt-other :slant italic))) - `(dap-ui-marker-face ((,class :inherit modus-theme-subtle-blue))) - `(dap-ui-sessions-stack-frame-face ((,class :inherit bold :foreground ,magenta-alt))) - `(dap-ui-sessions-terminated-active-face ((,class :inherit bold :foreground ,fg-alt))) - `(dap-ui-sessions-terminated-face ((,class :foreground ,fg-alt))) -;;;;; dashboard (emacs-dashboard) - `(dashboard-banner-logo-title ((,class :inherit bold :foreground ,fg-special-cold))) - `(dashboard-footer ((,class :inherit bold :foreground ,fg-special-mild))) - `(dashboard-heading ((,class :inherit bold :foreground ,fg-special-warm))) - `(dashboard-navigator ((,class :foreground ,cyan-alt-other))) - `(dashboard-text-banner ((,class :foreground ,fg-dim))) -;;;;; deadgrep - `(deadgrep-filename-face ((,class :inherit bold :foreground ,fg-special-cold))) - `(deadgrep-match-face ((,class :inherit modus-theme-special-calm))) - `(deadgrep-meta-face ((,class :foreground ,fg-alt))) - `(deadgrep-regexp-metachar-face ((,class :inherit bold :foreground ,yellow-intense))) - `(deadgrep-search-term-face ((,class :inherit bold :foreground ,green-intense))) -;;;;; debbugs - `(debbugs-gnu-archived ((,class :inverse-video t))) - `(debbugs-gnu-done ((,class :foreground ,fg-alt))) - `(debbugs-gnu-forwarded ((,class :foreground ,fg-special-warm))) - `(debbugs-gnu-handled ((,class :foreground ,green))) - `(debbugs-gnu-new ((,class :foreground ,red))) - `(debbugs-gnu-pending ((,class :foreground ,cyan))) - `(debbugs-gnu-stale-1 ((,class :foreground ,yellow-nuanced))) - `(debbugs-gnu-stale-2 ((,class :foreground ,yellow))) - `(debbugs-gnu-stale-3 ((,class :foreground ,yellow-alt))) - `(debbugs-gnu-stale-4 ((,class :foreground ,yellow-alt-other))) - `(debbugs-gnu-stale-5 ((,class :foreground ,red-alt))) - `(debbugs-gnu-tagged ((,class :foreground ,magenta-alt))) -;;;;; define-word - `(define-word-face-1 ((,class :foreground ,yellow))) - `(define-word-face-2 ((,class :foreground ,fg-main))) -;;;;; deft - `(deft-filter-string-error-face ((,class :inherit modus-theme-refine-red))) - `(deft-filter-string-face ((,class :foreground ,green-intense))) - `(deft-header-face ((,class :inherit bold :foreground ,fg-special-warm))) - `(deft-separator-face ((,class :foreground ,fg-alt))) - `(deft-summary-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(deft-time-face ((,class :foreground ,fg-special-cold))) - `(deft-title-face ((,class :inherit bold :foreground ,fg-main))) -;;;;; dictionary - `(dictionary-button-face ((,class :inherit bold :foreground ,fg-special-cold))) - `(dictionary-reference-face ((,class :inherit :foreground ,blue-alt-other))) - `(dictionary-word-definition-face ((,class :foreground ,fg-main))) - `(dictionary-word-entry-face ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) -;;;;; diff-hl - `(diff-hl-change ((,class :inherit modus-theme-fringe-yellow))) - `(diff-hl-delete ((,class :inherit modus-theme-fringe-red))) - `(diff-hl-dired-change ((,class :inherit diff-hl-change))) - `(diff-hl-dired-delete ((,class :inherit diff-hl-delete))) - `(diff-hl-dired-ignored ((,class :inherit dired-ignored))) - `(diff-hl-dired-insert ((,class :inherit diff-hl-insert))) - `(diff-hl-dired-unknown ((,class :inherit dired-ignored))) - `(diff-hl-insert ((,class :inherit modus-theme-fringe-green))) - `(diff-hl-reverted-hunk-highlight ((,class :inherit (modus-theme-active-magenta bold)))) -;;;;; diff-mode - `(diff-added ((,class :inherit modus-theme-diff-added))) - `(diff-changed ((,class :inherit modus-theme-diff-changed))) - `(diff-context ((,class :foreground ,fg-unfocused))) - `(diff-file-header ((,class :inherit bold :foreground ,blue))) - `(diff-function ((,class :foreground ,fg-special-cold))) - `(diff-header ((,class :foreground ,blue-nuanced))) - `(diff-hunk-header ((,class :inherit modus-theme-diff-heading))) - `(diff-index ((,class :inherit bold :foreground ,blue-alt))) - `(diff-indicator-added ((,class :inherit diff-added))) - `(diff-indicator-changed ((,class :inherit diff-changed))) - `(diff-indicator-removed ((,class :inherit diff-removed))) - `(diff-nonexistent ((,class :inherit (modus-theme-neutral bold)))) - `(diff-refine-added ((,class :inherit modus-theme-diff-refine-added))) - `(diff-refine-changed ((,class :inherit modus-theme-diff-refine-changed))) - `(diff-refine-removed ((,class :inherit modus-theme-diff-refine-removed))) - `(diff-removed ((,class :inherit modus-theme-diff-removed))) -;;;;; dim-autoload - `(dim-autoload-cookie-line ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) -;;;;; dir-treeview - `(dir-treeview-archive-face ((,class :foreground ,fg-special-warm))) - `(dir-treeview-archive-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,yellow))) - `(dir-treeview-audio-face ((,class :foreground ,magenta))) - `(dir-treeview-audio-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,magenta-alt))) - `(dir-treeview-control-face ((,class :foreground ,fg-alt))) - `(dir-treeview-control-mouse-face ((,class :inherit highlight))) - `(dir-treeview-default-icon-face ((,class :inherit bold :family "Font Awesome" :foreground ,fg-alt))) - `(dir-treeview-default-filename-face ((,class :foreground ,fg-main))) - `(dir-treeview-directory-face ((,class :foreground ,blue))) - `(dir-treeview-directory-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,blue-alt))) - `(dir-treeview-executable-face ((,class :foreground ,red-alt))) - `(dir-treeview-executable-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,red-alt-other))) - `(dir-treeview-image-face ((,class :foreground ,green-alt-other))) - `(dir-treeview-image-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,green-alt))) - `(dir-treeview-indent-face ((,class :foreground ,fg-alt))) - `(dir-treeview-label-mouse-face ((,class :inherit highlight))) - `(dir-treeview-start-dir-face ((,class :inherit modus-theme-pseudo-header))) - `(dir-treeview-symlink-face ((,class :inherit button :foreground ,cyan))) - `(dir-treeview-video-face ((,class :foreground ,magenta-alt-other))) - `(dir-treeview-video-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,magenta-alt-other))) -;;;;; dired - `(dired-directory ((,class :foreground ,blue))) - `(dired-flagged ((,class :inherit modus-theme-mark-del))) - `(dired-header ((,class :inherit modus-theme-pseudo-header))) - `(dired-ignored ((,class :foreground ,fg-alt))) - `(dired-mark ((,class :inherit modus-theme-mark-symbol))) - `(dired-marked ((,class :inherit modus-theme-mark-sel))) - `(dired-perm-write ((,class :foreground ,fg-special-warm))) - `(dired-symlink ((,class :inherit button :foreground ,cyan-alt))) - `(dired-warning ((,class :inherit bold :foreground ,yellow))) -;;;;; dired-async - `(dired-async-failures ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,red-active))) - `(dired-async-message ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,green-active))) - `(dired-async-mode-message ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,cyan-active))) -;;;;; dired-git - `(dired-git-branch-else ((,class :inherit bold :foreground ,magenta-alt))) - `(dired-git-branch-master ((,class :inherit bold :foreground ,magenta-alt-other))) -;;;;; dired-git-info - `(dgi-commit-message-face ((,class :foreground ,fg-special-mild))) -;;;;; dired-narrow - `(dired-narrow-blink ((,class :inherit (modus-theme-subtle-cyan bold)))) -;;;;; dired-subtree - ;; remove background from dired-subtree, else it breaks - ;; dired-{flagged,marked} and any other face that sets a background - ;; such as hl-line - `(dired-subtree-depth-1-face ((,class :background nil))) - `(dired-subtree-depth-2-face ((,class :background nil))) - `(dired-subtree-depth-3-face ((,class :background nil))) - `(dired-subtree-depth-4-face ((,class :background nil))) - `(dired-subtree-depth-5-face ((,class :background nil))) - `(dired-subtree-depth-6-face ((,class :background nil))) -;;;;; diredfl - `(diredfl-autofile-name ((,class :inherit modus-theme-special-cold))) - `(diredfl-compressed-file-name ((,class :foreground ,fg-special-warm))) - `(diredfl-compressed-file-suffix ((,class :foreground ,red-alt))) - `(diredfl-date-time ((,class :foreground ,cyan-alt-other))) - `(diredfl-deletion ((,class :inherit modus-theme-mark-del))) - `(diredfl-deletion-file-name ((,class :inherit modus-theme-mark-del))) - `(diredfl-dir-heading ((,class :inherit modus-theme-pseudo-header))) - `(diredfl-dir-name ((,class :inherit dired-directory))) - `(diredfl-dir-priv ((,class :foreground ,blue-alt))) - `(diredfl-exec-priv ((,class :foreground ,magenta))) - `(diredfl-executable-tag ((,class :foreground ,magenta-alt))) - `(diredfl-file-name ((,class :foreground ,fg-main))) - `(diredfl-file-suffix ((,class :foreground ,cyan))) - `(diredfl-flag-mark ((,class :inherit modus-theme-mark-sel))) - `(diredfl-flag-mark-line ((,class :inherit modus-theme-mark-sel))) - `(diredfl-ignored-file-name ((,class :foreground ,fg-alt))) - `(diredfl-link-priv ((,class :foreground ,blue-alt-other))) - `(diredfl-no-priv ((,class :foreground ,fg-alt))) - `(diredfl-number ((,class :foreground ,cyan-alt))) - `(diredfl-other-priv ((,class :foreground ,yellow))) - `(diredfl-rare-priv ((,class :foreground ,red-alt))) - `(diredfl-read-priv ((,class :foreground ,fg-main))) - `(diredfl-symlink ((,class :inherit dired-symlink))) - `(diredfl-tagged-autofile-name ((,class :inherit modus-theme-refine-magenta))) - `(diredfl-write-priv ((,class :foreground ,cyan))) -;;;;; disk-usage - `(disk-usage-children ((,class :foreground ,yellow))) - `(disk-usage-inaccessible ((,class :inherit bold :foreground ,red))) - `(disk-usage-percent ((,class :foreground ,green))) - `(disk-usage-size ((,class :foreground ,cyan))) - `(disk-usage-symlink ((,class :inherit button :foreground ,blue))) - `(disk-usage-symlink-directory ((,class :inherit bold :foreground ,blue-alt))) -;;;;; doom-modeline - `(doom-modeline-bar ((,class :inherit modus-theme-active-blue))) - `(doom-modeline-bar-inactive ((,class :background ,fg-inactive :foreground ,bg-main))) - `(doom-modeline-battery-charging ((,class :foreground ,green-active))) - `(doom-modeline-battery-critical ((,class :inherit bold :foreground ,red-active))) - `(doom-modeline-battery-error ((,class :inherit bold :box (:line-width -2) - :foreground ,red-active))) - `(doom-modeline-battery-full ((,class :foreground ,blue-active))) - `(doom-modeline-battery-normal ((,class :foreground ,fg-active))) - `(doom-modeline-battery-warning ((,class :inherit bold :foreground ,yellow-active))) - `(doom-modeline-buffer-file ((,class :inherit bold :foreground ,fg-active))) - `(doom-modeline-buffer-major-mode ((,class :inherit bold :foreground ,cyan-active))) - `(doom-modeline-buffer-minor-mode ((,class :foreground ,fg-inactive))) - `(doom-modeline-buffer-modified ((,class :inherit bold :foreground ,magenta-active))) - `(doom-modeline-buffer-path ((,class :inherit bold :foreground ,fg-active))) - `(doom-modeline-debug ((,class :inherit bold :foreground ,yellow-active))) - `(doom-modeline-debug-visual ((,class :inherit bold :foreground ,red-active))) - `(doom-modeline-evil-emacs-state ((,class :inherit bold :foreground ,magenta-active))) - `(doom-modeline-evil-insert-state ((,class :inherit bold :foreground ,green-active))) - `(doom-modeline-evil-motion-state ((,class :inherit bold :foreground ,fg-inactive))) - `(doom-modeline-evil-normal-state ((,class :inherit bold :foreground ,fg-active))) - `(doom-modeline-evil-operator-state ((,class :inherit bold :foreground ,blue-active))) - `(doom-modeline-evil-replace-state ((,class :inherit bold :foreground ,red-active))) - `(doom-modeline-evil-visual-state ((,class :inherit bold :foreground ,cyan-active))) - `(doom-modeline-highlight ((,class :inherit bold :foreground ,blue-active))) - `(doom-modeline-host ((,class :slant italic))) - `(doom-modeline-info ((,class :foreground ,green-active))) - `(doom-modeline-lsp-error ((,class :inherit bold :foreground ,red-active))) - `(doom-modeline-lsp-success ((,class :inherit bold :foreground ,green-active))) - `(doom-modeline-lsp-warning ((,class :inherit bold :foreground ,yellow-active))) - `(doom-modeline-panel ((,class :inherit modus-theme-active-blue))) - `(doom-modeline-persp-buffer-not-in-persp ((,class :foreground ,yellow-active :slant italic))) - `(doom-modeline-persp-name ((,class :foreground ,fg-active))) - `(doom-modeline-project-dir ((,class :inherit bold :foreground ,blue-active))) - `(doom-modeline-project-parent-dir ((,class :foreground ,blue-active))) - `(doom-modeline-project-root-dir ((,class :foreground ,fg-active))) - `(doom-modeline-unread-number ((,class :foreground ,fg-active :slant italic))) - `(doom-modeline-urgent ((,class :inherit bold :foreground ,red-active))) - `(doom-modeline-warning ((,class :inherit bold :foreground ,yellow-active))) -;;;;; dynamic-ruler - `(dynamic-ruler-negative-face ((,class :inherit modus-theme-intense-neutral))) - `(dynamic-ruler-positive-face ((,class :inherit modus-theme-intense-yellow))) -;;;;; easy-jekyll - `(easy-jekyll-help-face ((,class :background ,bg-dim :foreground ,cyan-alt-other))) -;;;;; easy-kill - `(easy-kill-origin ((,class :inherit modus-theme-subtle-red))) - `(easy-kill-selection ((,class :inherit modus-theme-subtle-yellow))) -;;;;; ebdb - `(ebdb-address-default ((,class :foreground ,fg-main))) - `(ebdb-db-char ((,class :foreground ,fg-special-cold))) - `(ebdb-defunct ((,class :foreground ,fg-alt))) - `(ebdb-field-hidden ((,class :foreground ,magenta))) - `(ebdb-field-url ((,class :foreground ,blue))) - `(ebdb-label ((,class :foreground ,cyan-alt-other))) - `(ebdb-mail-default ((,class :foreground ,fg-main))) - `(ebdb-mail-primary ((,class :foreground ,blue-alt))) - `(ebdb-marked ((,class :background ,cyan-intense-bg))) - `(ebdb-organization-name ((,class :foreground ,fg-special-calm))) - `(ebdb-person-name ((,class :foreground ,magenta-alt-other))) - `(ebdb-phone-default ((,class :foreground ,fg-special-warm))) - `(ebdb-role-defunct ((,class :foreground ,fg-alt))) - `(eieio-custom-slot-tag-face ((,class :foreground ,red-alt))) -;;;;; ediff - ;; NOTE: here we break from the pattern of inheriting from the - ;; modus-theme-diff-* faces. - `(ediff-current-diff-A ((,class ,@(modus-operandi-theme-diff - bg-dim red - bg-diff-removed fg-diff-removed - red-nuanced-bg red-faint)))) - `(ediff-current-diff-Ancestor ((,class ,@(modus-operandi-theme-diff - bg-dim fg-special-cold - bg-special-cold fg-special-cold - blue-nuanced-bg blue)))) - `(ediff-current-diff-B ((,class ,@(modus-operandi-theme-diff - bg-dim green - bg-diff-added fg-diff-added - green-nuanced-bg green-faint)))) - `(ediff-current-diff-C ((,class ,@(modus-operandi-theme-diff - bg-dim yellow - bg-diff-changed fg-diff-changed - yellow-nuanced-bg yellow-faint)))) - `(ediff-even-diff-A ((,class :background ,bg-diff-neutral-1 :foreground ,fg-diff-neutral-1))) - `(ediff-even-diff-Ancestor ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-1))) - `(ediff-even-diff-B ((,class :background ,bg-diff-neutral-1 :foreground ,fg-diff-neutral-1))) - `(ediff-even-diff-C ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-2))) - `(ediff-fine-diff-A ((,class :background ,bg-diff-focus-removed :foreground ,fg-diff-focus-removed))) - `(ediff-fine-diff-Ancestor ((,class :inherit modus-theme-refine-cyan))) - `(ediff-fine-diff-B ((,class :background ,bg-diff-focus-added :foreground ,fg-diff-focus-added))) - `(ediff-fine-diff-C ((,class :background ,bg-diff-focus-changed :foreground ,fg-diff-focus-changed))) - `(ediff-odd-diff-A ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-2))) - `(ediff-odd-diff-Ancestor ((,class :background ,bg-diff-neutral-0 :foreground ,fg-diff-neutral-0))) - `(ediff-odd-diff-B ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-2))) - `(ediff-odd-diff-C ((,class :background ,bg-diff-neutral-1 :foreground ,fg-diff-neutral-1))) -;;;;; eglot - `(eglot-mode-line ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,magenta-active))) -;;;;; el-search - `(el-search-highlight-in-prompt-face ((,class :inherit bold :foreground ,magenta-alt))) - `(el-search-match ((,class :inherit modus-theme-intense-green))) - `(el-search-other-match ((,class :inherit modus-theme-special-mild))) - `(el-search-occur-match ((,class :inherit modus-theme-special-calm))) -;;;;; eldoc - ;; NOTE: see https://github.com/purcell/package-lint/issues/187 - (list 'eldoc-highlight-function-argument `((,class :inherit bold :foreground ,blue-alt-other))) -;;;;; eldoc-box - `(eldoc-box-body ((,class :background ,bg-alt :foreground ,fg-main))) - `(eldoc-box-border ((,class :background ,fg-alt))) -;;;;; elfeed - `(elfeed-log-date-face ((,class :foreground ,cyan-alt))) - `(elfeed-log-debug-level-face ((,class :foreground ,magenta))) - `(elfeed-log-error-level-face ((,class :foreground ,red))) - `(elfeed-log-info-level-face ((,class :foreground ,green))) - `(elfeed-log-warn-level-face ((,class :foreground ,yellow))) - `(elfeed-search-date-face ((,class :foreground ,blue-nuanced))) - `(elfeed-search-feed-face ((,class :foreground ,cyan))) - `(elfeed-search-filter-face ((,class :inherit bold :foreground ,magenta-active))) - `(elfeed-search-last-update-face ((,class :foreground ,cyan-active))) - `(elfeed-search-tag-face ((,class :foreground ,blue-nuanced))) - `(elfeed-search-title-face ((,class :foreground ,fg-dim))) - `(elfeed-search-unread-count-face ((,class :foreground ,green-active))) - `(elfeed-search-unread-title-face ((,class :inherit bold :foreground ,fg-main))) -;;;;; elfeed-score - `(elfeed-score-date-face ((,class :foreground ,blue))) - `(elfeed-score-debug-level-face ((,class :foreground ,magenta-alt-other))) - `(elfeed-score-error-level-face ((,class :foreground ,red))) - `(elfeed-score-info-level-face ((,class :foreground ,cyan))) - `(elfeed-score-warn-level-face ((,class :foreground ,yellow))) -;;;;; emms - `(emms-playlist-track-face ((,class :foreground ,blue))) - `(emms-playlist-selected-face ((,class :inherit bold :foreground ,magenta))) -;;;;; enhanced-ruby-mode - `(enh-ruby-heredoc-delimiter-face ((,class :foreground ,blue-alt-other))) - `(enh-ruby-op-face ((,class :foreground ,fg-main))) - `(enh-ruby-regexp-delimiter-face ((,class :foreground ,green))) - `(enh-ruby-regexp-face ((,class :foreground ,magenta))) - `(enh-ruby-string-delimiter-face ((,class :foreground ,blue-alt))) - `(erm-syn-errline ((,class :foreground ,red :underline t))) - `(erm-syn-warnline ((,class :foreground ,yellow :underline t))) -;;;;; epa - `(epa-field-body ((,class :foreground ,fg-main))) - `(epa-field-name ((,class :inherit bold :foreground ,fg-dim))) - `(epa-mark ((,class :inherit bold :foreground ,magenta))) - `(epa-string ((,class :foreground ,blue-alt))) - `(epa-validity-disabled ((,class :inherit modus-theme-refine-red))) - `(epa-validity-high ((,class :inherit bold :foreground ,green-alt-other))) - `(epa-validity-low ((,class :foreground ,fg-alt))) - `(epa-validity-medium ((,class :foreground ,green-alt))) -;;;;; equake - `(equake-buffer-face ((,class :background ,bg-main :foreground ,fg-main))) - `(equake-shell-type-eshell ((,class :background ,bg-inactive :foreground ,green-active))) - `(equake-shell-type-rash ((,class :background ,bg-inactive :foreground ,red-active))) - `(equake-shell-type-shell ((,class :background ,bg-inactive :foreground ,cyan-active))) - `(equake-shell-type-term ((,class :background ,bg-inactive :foreground ,yellow-active))) - `(equake-shell-type-vterm ((,class :background ,bg-inactive :foreground ,magenta-active))) - `(equake-tab-active ((,class :background ,fg-alt :foreground ,bg-alt))) - `(equake-tab-inactive ((,class :foreground ,fg-inactive))) -;;;;; erc - `(erc-action-face ((,class :inherit bold :foreground ,cyan))) - `(erc-bold-face ((,class :inherit bold))) - `(erc-button ((,class :inherit button))) - `(erc-command-indicator-face ((,class :inherit bold :foreground ,cyan-alt))) - `(erc-current-nick-face ((,class :foreground ,magenta-alt-other))) - `(erc-dangerous-host-face ((,class :inherit modus-theme-intense-red))) - `(erc-direct-msg-face ((,class :foreground ,magenta))) - `(erc-error-face ((,class :inherit bold :foreground ,red))) - `(erc-fool-face ((,class :foreground ,fg-inactive))) - `(erc-header-line ((,class :background ,bg-header :foreground ,fg-header))) - `(erc-input-face ((,class :foreground ,fg-special-calm))) - `(erc-inverse-face ((,class :inherit erc-default-face :inverse-video t))) - `(erc-keyword-face ((,class :inherit bold :foreground ,magenta-alt))) - `(erc-my-nick-face ((,class :inherit bold :foreground ,magenta))) - `(erc-my-nick-prefix-face ((,class :inherit erc-my-nick-face))) - `(erc-nick-default-face ((,class :inherit bold :foreground ,blue))) - `(erc-nick-msg-face ((,class :inherit bold :foreground ,green))) - `(erc-nick-prefix-face ((,class :inherit erc-nick-default-face))) - `(erc-notice-face ((,class :foreground ,fg-unfocused))) - `(erc-pal-face ((,class :inherit bold :foreground ,red-alt))) - `(erc-prompt-face ((,class :inherit bold :foreground ,cyan-alt-other))) - `(erc-timestamp-face ((,class :foreground ,blue-nuanced))) - `(erc-underline-face ((,class :underline t))) - `(bg:erc-color-face0 ((,class :background "white"))) - `(bg:erc-color-face1 ((,class :background "black"))) - `(bg:erc-color-face10 ((,class :background ,cyan-subtle-bg))) - `(bg:erc-color-face11 ((,class :background ,cyan-intense-bg))) - `(bg:erc-color-face12 ((,class :background ,blue-subtle-bg))) - `(bg:erc-color-face13 ((,class :background ,magenta-subtle-bg))) - `(bg:erc-color-face14 ((,class :background "gray60"))) - `(bg:erc-color-face15 ((,class :background "gray80"))) - `(bg:erc-color-face2 ((,class :background ,blue-intense-bg))) - `(bg:erc-color-face3 ((,class :background ,green-intense-bg))) - `(bg:erc-color-face4 ((,class :background ,red-subtle-bg))) - `(bg:erc-color-face5 ((,class :background ,red-intense-bg))) - `(bg:erc-color-face6 ((,class :background ,magenta-refine-bg))) - `(bg:erc-color-face7 ((,class :background ,yellow-subtle-bg))) - `(bg:erc-color-face8 ((,class :background ,yellow-refine-bg))) - `(bg:erc-color-face9 ((,class :background ,green-subtle-bg))) - `(fg:erc-color-face0 ((,class :foreground "white"))) - `(fg:erc-color-face1 ((,class :foreground "black"))) - `(fg:erc-color-face10 ((,class :foreground ,cyan))) - `(fg:erc-color-face11 ((,class :foreground ,cyan-alt-other))) - `(fg:erc-color-face12 ((,class :foreground ,blue))) - `(fg:erc-color-face13 ((,class :foreground ,magenta-alt))) - `(fg:erc-color-face14 ((,class :foreground "gray60"))) - `(fg:erc-color-face15 ((,class :foreground "gray80"))) - `(fg:erc-color-face2 ((,class :foreground ,blue-alt-other))) - `(fg:erc-color-face3 ((,class :foreground ,green))) - `(fg:erc-color-face4 ((,class :foreground ,red))) - `(fg:erc-color-face5 ((,class :foreground ,red-alt))) - `(fg:erc-color-face6 ((,class :foreground ,magenta-alt-other))) - `(fg:erc-color-face7 ((,class :foreground ,yellow-alt-other))) - `(fg:erc-color-face8 ((,class :foreground ,yellow-alt))) - `(fg:erc-color-face9 ((,class :foreground ,green-alt-other))) -;;;;; eros - `(eros-result-overlay-face ((,class :box (:line-width -1 :color ,blue) - :background ,bg-dim :foreground ,fg-dim))) -;;;;; ert - `(ert-test-result-expected ((,class :inherit modus-theme-intense-green))) - `(ert-test-result-unexpected ((,class :inherit modus-theme-intense-red))) -;;;;; eshell - `(eshell-ls-archive ((,class :inherit bold :foreground ,cyan-alt))) - `(eshell-ls-backup ((,class :foreground ,yellow-alt))) - `(eshell-ls-clutter ((,class :foreground ,red-alt))) - `(eshell-ls-directory ((,class :inherit bold :foreground ,blue-alt))) - `(eshell-ls-executable ((,class :foreground ,magenta-alt))) - `(eshell-ls-missing ((,class :inherit modus-theme-intense-red))) - `(eshell-ls-product ((,class :foreground ,fg-special-warm))) - `(eshell-ls-readonly ((,class :foreground ,fg-special-cold))) - `(eshell-ls-special ((,class :inherit bold :foreground ,magenta))) - `(eshell-ls-symlink ((,class :inherit button :foreground ,cyan))) - `(eshell-ls-unreadable ((,class :background ,bg-inactive :foreground ,fg-inactive))) - `(eshell-prompt ((,class ,@(modus-operandi-theme-bold-weight) - ,@(modus-operandi-theme-prompt - green-alt-other - green-nuanced-bg green-alt - green-refine-bg fg-main)))) -;;;;; eshell-fringe-status - `(eshell-fringe-status-failure ((,class :foreground ,red))) - `(eshell-fringe-status-success ((,class :foreground ,green))) -;;;;; eshell-git-prompt - `(eshell-git-prompt-add-face ((,class :foreground ,fg-alt))) - `(eshell-git-prompt-branch-face ((,class :foreground ,fg-alt))) - `(eshell-git-prompt-directory-face ((,class :foreground ,cyan))) - `(eshell-git-prompt-exit-fail-face ((,class :foreground ,red))) - `(eshell-git-prompt-exit-success-face ((,class :foreground ,green))) - `(eshell-git-prompt-modified-face ((,class :foreground ,yellow))) - `(eshell-git-prompt-powerline-clean-face ((,class :background ,green-refine-bg))) - `(eshell-git-prompt-powerline-dir-face ((,class :background ,blue-refine-bg))) - `(eshell-git-prompt-powerline-not-clean-face ((,class :background ,magenta-refine-bg))) - `(eshell-git-prompt-robyrussell-branch-face ((,class :foreground ,red))) - `(eshell-git-prompt-robyrussell-git-dirty-face ((,class :foreground ,yellow))) - `(eshell-git-prompt-robyrussell-git-face ((,class :foreground ,blue))) -;;;;; eshell-prompt-extras (epe) - `(epe-dir-face ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,blue))) - `(epe-git-dir-face ((,class :foreground ,red-alt-other))) - `(epe-git-face ((,class :foreground ,cyan-alt))) - `(epe-pipeline-delimiter-face ((,class :foreground ,green-alt))) - `(epe-pipeline-host-face ((,class :foreground ,blue))) - `(epe-pipeline-time-face ((,class :foreground ,fg-special-warm))) - `(epe-pipeline-user-face ((,class :foreground ,magenta))) - `(epe-remote-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(epe-status-face ((,class :foreground ,magenta-alt-other))) - `(epe-venv-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) -;;;;; eshell-syntax-highlighting - `(eshell-syntax-highlighting-alias-face ((,class :foreground ,cyan))) - `(eshell-syntax-highlighting-comment-face ((,class :foreground ,fg-alt))) - `(eshell-syntax-highlighting-directory-face ((,class :foreground ,blue))) - `(eshell-syntax-highlighting-envvar-face ((,class :foreground ,magenta-alt))) - `(eshell-syntax-highlighting-invalid-face ((,class :foreground ,red))) - `(eshell-syntax-highlighting-lisp-function-face ((,class :foreground ,magenta))) - `(eshell-syntax-highlighting-shell-command-face ((,class :foreground ,cyan-alt-other))) - `(eshell-syntax-highlighting-string-face ((,class :foreground ,blue-alt))) -;;;;; evil-mode - `(evil-ex-commands ((,class :foreground ,magenta-alt-other))) - `(evil-ex-info ((,class :foreground ,cyan-alt-other))) - `(evil-ex-lazy-highlight ((,class :inherit modus-theme-refine-cyan))) - `(evil-ex-search ((,class :inherit modus-theme-intense-green))) - `(evil-ex-substitute-matches ((,class :inherit modus-theme-refine-yellow :underline t))) - `(evil-ex-substitute-replacement ((,class :inherit (modus-theme-intense-green bold)))) -;;;;; evil-goggles - `(evil-goggles-change-face ((,class :inherit modus-theme-refine-yellow))) - `(evil-goggles-commentary-face ((,class :inherit modus-theme-subtle-neutral :slant ,modus-theme-slant))) - `(evil-goggles-default-face ((,class :inherit modus-theme-subtle-neutral))) - `(evil-goggles-delete-face ((,class :inherit modus-theme-refine-red))) - `(evil-goggles-fill-and-move-face ((,class :inherit evil-goggles-default-face))) - `(evil-goggles-indent-face ((,class :inherit evil-goggles-default-face))) - `(evil-goggles-join-face ((,class :inherit modus-theme-subtle-green))) - `(evil-goggles-nerd-commenter-face ((,class :inherit evil-goggles-commentary-face))) - `(evil-goggles-paste-face ((,class :inherit modus-theme-subtle-cyan))) - `(evil-goggles-record-macro-face ((,class :inherit modus-theme-special-cold))) - `(evil-goggles-replace-with-register-face ((,class :inherit modus-theme-refine-magenta))) - `(evil-goggles-set-marker-face ((,class :inherit modus-theme-intense-magenta))) - `(evil-goggles-shift-face ((,class :inherit evil-goggles-default-face))) - `(evil-goggles-surround-face ((,class :inherit evil-goggles-default-face))) - `(evil-goggles-yank-face ((,class :inherit modus-theme-subtle-blue))) -;;;;; evil-visual-mark-mode - `(evil-visual-mark-face ((,class :inherit modus-theme-intense-magenta))) -;;;;; eww - `(eww-invalid-certificate ((,class :foreground ,red-active))) - `(eww-valid-certificate ((,class :foreground ,green-active))) - `(eww-form-checkbox ((,class :box (:line-width 1 :color ,fg-inactive :style released-button) :background ,bg-inactive :foreground ,fg-main))) - `(eww-form-file ((,class :box (:line-width 1 :color ,fg-inactive :style released-button) :background ,bg-active :foreground ,fg-main))) - `(eww-form-select ((,class :inherit eww-form-checkbox))) - `(eww-form-submit ((,class :inherit eww-form-file))) - `(eww-form-text ((,class :box (:line-width 1 :color ,fg-inactive :style none) :background ,bg-active :foreground ,fg-active))) - `(eww-form-textarea ((,class :background ,bg-alt :foreground ,fg-main))) -;;;;; eyebrowse - `(eyebrowse-mode-line-active ((,class :inherit bold :foreground ,blue-active))) -;;;;; fancy-dabbrev - `(fancy-dabbrev-menu-face ((,class :background ,bg-alt :foreground ,fg-alt))) - `(fancy-dabbrev-preview-face ((,class :foreground ,fg-alt :underline t))) - `(fancy-dabbrev-selection-face ((,class :inherit (modus-theme-intense-cyan bold)))) -;;;;; flycheck - `(flycheck-error - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-error :style wave)) - (,class :foreground ,fg-lang-error :underline t))) - `(flycheck-error-list-checker-name ((,class :foreground ,magenta-active))) - `(flycheck-error-list-column-number ((,class :foreground ,fg-special-cold))) - `(flycheck-error-list-error ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,red))) - `(flycheck-error-list-filename ((,class :foreground ,blue))) - `(flycheck-error-list-highlight ((,class :inherit modus-theme-hl-line))) - `(flycheck-error-list-id ((,class :foreground ,magenta-alt-other))) - `(flycheck-error-list-id-with-explainer ((,class :inherit flycheck-error-list-id :box t))) - `(flycheck-error-list-info ((,class :foreground ,cyan))) - `(flycheck-error-list-line-number ((,class :foreground ,fg-special-warm))) - `(flycheck-error-list-warning ((,class :foreground ,yellow))) - `(flycheck-fringe-error ((,class :inherit modus-theme-fringe-red))) - `(flycheck-fringe-info ((,class :inherit modus-theme-fringe-cyan))) - `(flycheck-fringe-warning ((,class :inherit modus-theme-fringe-yellow))) - `(flycheck-info - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-note :style wave)) - (,class :foreground ,fg-lang-note :underline t))) - `(flycheck-verify-select-checker ((,class :box (:line-width 1 :color nil :style released-button)))) - `(flycheck-warning - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-warning :style wave)) - (,class :foreground ,fg-lang-warning :underline t))) -;;;;; flycheck-color-mode-line - `(flycheck-color-mode-line-error-face ((,class :inherit flycheck-fringe-error))) - `(flycheck-color-mode-line-info-face ((,class :inherit flycheck-fringe-info))) - `(flycheck-color-mode-line-running-face ((,class :foreground ,fg-inactive :slant italic))) - `(flycheck-color-mode-line-info-face ((,class :inherit flycheck-fringe-warning))) -;;;;; flycheck-indicator - `(flycheck-indicator-disabled ((,class :foreground ,fg-inactive :slant ,modus-theme-slant))) - `(flycheck-indicator-error ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,red-active))) - `(flycheck-indicator-info ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,blue-active))) - `(flycheck-indicator-running ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,magenta-active))) - `(flycheck-indicator-success ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,green-active))) - `(flycheck-indicator-warning ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,yellow-active))) -;;;;; flycheck-posframe - `(flycheck-posframe-background-face ((,class :background ,bg-alt))) - `(flycheck-posframe-border-face ((,class :foreground ,fg-alt))) - `(flycheck-posframe-error-face ((,class :inherit bold :foreground ,red))) - `(flycheck-posframe-face ((,class :foreground ,fg-main :slant ,modus-theme-slant))) - `(flycheck-posframe-info-face ((,class :inherit bold :foreground ,cyan))) - `(flycheck-posframe-warning-face ((,class :inherit bold :foreground ,yellow))) -;;;;; flymake - `(flymake-error - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-error :style wave)) - (,class :foreground ,fg-lang-error :underline t))) - `(flymake-note - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-note :style wave)) - (,class :foreground ,fg-lang-note :underline t))) - `(flymake-warning - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-warning :style wave)) - (,class :foreground ,fg-lang-warning :underline t))) -;;;;; flyspell - `(flyspell-duplicate - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-warning :style wave)) - (,class :foreground ,fg-lang-warning :underline t))) - `(flyspell-incorrect - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-error :style wave)) - (,class :foreground ,fg-lang-error :underline t))) -;;;;; flyspell-correct - `(flyspell-correct-highlight-face ((,class :inherit modus-theme-refine-green))) -;;;;; flx - `(flx-highlight-face ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-magenta - 'modus-theme-intense-magenta - 'modus-theme-nuanced-magenta - magenta-alt - 'bold)))) -;;;;; freeze-it - `(freeze-it-show ((,class :background ,bg-dim :foreground ,fg-special-warm))) -;;;;; frog-menu - `(frog-menu-action-keybinding-face ((,class :foreground ,blue-alt-other))) - `(frog-menu-actions-face ((,class :foreground ,magenta))) - `(frog-menu-border ((,class :background ,bg-active))) - `(frog-menu-candidates-face ((,class :foreground ,fg-main))) - `(frog-menu-posframe-background-face ((,class :background ,bg-dim))) - `(frog-menu-prompt-face ((,class :foreground ,cyan))) -;;;;; focus - `(focus-unfocused ((,class :foreground ,fg-unfocused))) -;;;;; fold-this - `(fold-this-overlay ((,class :inherit modus-theme-special-mild))) -;;;;; font-lock - `(font-lock-builtin-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(font-lock-comment-delimiter-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(font-lock-comment-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(font-lock-constant-face ((,class ,@(modus-operandi-theme-syntax-foreground - blue-alt-other blue-alt-other-faint)))) - `(font-lock-doc-face ((,class ,@(modus-operandi-theme-syntax-foreground - fg-special-cold cyan-alt-other-faint) - :slant ,modus-theme-slant))) - `(font-lock-function-name-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta magenta-faint)))) - `(font-lock-keyword-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt-other magenta-alt-other-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(font-lock-negation-char-face ((,class ,@(modus-operandi-theme-syntax-foreground - yellow yellow-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(font-lock-preprocessor-face ((,class ,@(modus-operandi-theme-syntax-foreground - red-alt-other red-alt-other-faint)))) - `(font-lock-regexp-grouping-backslash ((,class :inherit bold :foreground ,fg-escape-char-backslash))) - `(font-lock-regexp-grouping-construct ((,class :inherit bold :foreground ,fg-escape-char-construct))) - `(font-lock-string-face ((,class ,@(modus-operandi-theme-syntax-foreground - blue-alt blue-alt-faint)))) - `(font-lock-type-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt magenta-alt-faint)))) - `(font-lock-variable-name-face ((,class ,@(modus-operandi-theme-syntax-foreground - cyan cyan-faint)))) - `(font-lock-warning-face ((,class ,@(modus-operandi-theme-syntax-foreground - yellow-active yellow-alt-faint) - ,@(modus-operandi-theme-bold-weight)))) -;;;;; forge - `(forge-post-author ((,class :inherit bold :foreground ,fg-main))) - `(forge-post-date ((,class :foreground ,fg-special-cold))) - `(forge-topic-closed ((,class :foreground ,fg-alt))) - `(forge-topic-merged ((,class :foreground ,fg-alt))) - `(forge-topic-open ((,class :foreground ,fg-special-mild))) - `(forge-topic-unmerged ((,class :foreground ,magenta :slant ,modus-theme-slant))) - `(forge-topic-unread ((,class :inherit bold :foreground ,fg-main))) -;;;;; fountain-mode - `(fountain-character ((,class :foreground ,blue-alt-other))) - `(fountain-comment ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(fountain-dialog ((,class :foreground ,blue-alt))) - `(fountain-metadata-key ((,class :foreground ,green-alt-other))) - `(fountain-metadata-value ((,class :foreground ,blue))) - `(fountain-non-printing ((,class :foreground ,fg-alt))) - `(fountain-note ((,class :foreground ,yellow :slant ,modus-theme-slant))) - `(fountain-page-break ((,class :inherit bold :foreground ,red-alt))) - `(fountain-page-number ((,class :inherit bold :foreground ,red-alt-other))) - `(fountain-paren ((,class :foreground ,cyan))) - `(fountain-scene-heading ((,class :inherit bold :foreground ,blue-nuanced))) - `(fountain-section-heading ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,fg-main - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-4)))) - `(fountain-section-heading-1 ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,fg-main - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-4)))) - `(fountain-section-heading-2 ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,fg-special-warm - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-3)))) - `(fountain-section-heading-3 ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,fg-special-mild - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-2)))) - `(fountain-section-heading-4 ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,fg-special-calm - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-1)))) - `(fountain-section-heading-5 ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,fg-special-calm))) - `(fountain-synopsis ((,class :foreground ,cyan-alt))) - `(fountain-trans ((,class :foreground ,yellow-alt-other))) -;;;;; geiser - `(geiser-font-lock-autodoc-current-arg ((,class ,@(modus-operandi-theme-syntax-foreground - magenta magenta-faint)))) - `(geiser-font-lock-autodoc-identifier ((,class ,@(modus-operandi-theme-syntax-foreground - blue blue-faint)))) - `(geiser-font-lock-doc-button ((,class ,@(modus-operandi-theme-syntax-foreground - cyan-alt cyan-alt-faint) - :underline t))) - `(geiser-font-lock-doc-link ((,class :inherit link))) - `(geiser-font-lock-error-link ((,class ,@(modus-operandi-theme-syntax-foreground - red-alt red-alt-faint) - :underline t))) - `(geiser-font-lock-image-button ((,class ,@(modus-operandi-theme-syntax-foreground - green-alt green-alt-faint) - :underline t))) - `(geiser-font-lock-repl-input ((,class :inherit bold))) - `(geiser-font-lock-repl-output ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt-other magenta-alt-other-faint)))) - `(geiser-font-lock-repl-prompt ((,class ,@(modus-operandi-theme-syntax-foreground - cyan-alt-other cyan-alt-other-faint)))) - `(geiser-font-lock-xref-header ((,class :inherit bold))) - `(geiser-font-lock-xref-link ((,class :inherit link))) -;;;;; git-commit - `(git-commit-comment-action ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(git-commit-comment-branch-local ((,class :foreground ,blue-alt :slant ,modus-theme-slant))) - `(git-commit-comment-branch-remote ((,class :foreground ,magenta-alt :slant ,modus-theme-slant))) - `(git-commit-comment-detached ((,class :foreground ,cyan-alt :slant ,modus-theme-slant))) - `(git-commit-comment-file ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(git-commit-comment-heading ((,class :inherit bold :foreground ,fg-dim :slant ,modus-theme-slant))) - `(git-commit-keyword ((,class :foreground ,magenta))) - `(git-commit-known-pseudo-header ((,class :foreground ,cyan-alt-other))) - `(git-commit-nonempty-second-line ((,class :inherit modus-theme-refine-yellow))) - `(git-commit-overlong-summary ((,class :inherit modus-theme-refine-yellow))) - `(git-commit-pseudo-header ((,class :foreground ,blue))) - `(git-commit-summary ((,class :inherit bold :foreground ,cyan))) -;;;;; git-gutter - `(git-gutter:added ((,class :inherit modus-theme-fringe-green))) - `(git-gutter:deleted ((,class :inherit modus-theme-fringe-red))) - `(git-gutter:modified ((,class :inherit modus-theme-fringe-yellow))) - `(git-gutter:separator ((,class :inherit modus-theme-fringe-cyan))) - `(git-gutter:unchanged ((,class :inherit modus-theme-fringe-magenta))) -;;;;; git-gutter-fr - `(git-gutter-fr:added ((,class :inherit modus-theme-fringe-green))) - `(git-gutter-fr:deleted ((,class :inherit modus-theme-fringe-red))) - `(git-gutter-fr:modified ((,class :inherit modus-theme-fringe-yellow))) -;;;;; git-{gutter,fringe}+ - `(git-gutter+-added ((,class :inherit modus-theme-fringe-green))) - `(git-gutter+-deleted ((,class :inherit modus-theme-fringe-red))) - `(git-gutter+-modified ((,class :inherit modus-theme-fringe-yellow))) - `(git-gutter+-separator ((,class :inherit modus-theme-fringe-cyan))) - `(git-gutter+-unchanged ((,class :inherit modus-theme-fringe-magenta))) - `(git-gutter-fr+-added ((,class :inherit modus-theme-fringe-green))) - `(git-gutter-fr+-deleted ((,class :inherit modus-theme-fringe-red))) - `(git-gutter-fr+-modified ((,class :inherit modus-theme-fringe-yellow))) -;;;;; git-lens - `(git-lens-added ((,class :inherit bold :foreground ,green))) - `(git-lens-deleted ((,class :inherit bold :foreground ,red))) - `(git-lens-header ((,class :inherit bold :height 1.1 :foreground ,cyan))) - `(git-lens-modified ((,class :inherit bold :foreground ,yellow))) - `(git-lens-renamed ((,class :inherit bold :foreground ,magenta))) -;;;;; git-rebase - `(git-rebase-comment-hash ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(git-rebase-comment-heading ((,class :inherit bold :foreground ,fg-dim :slant ,modus-theme-slant))) - `(git-rebase-description ((,class :foreground ,fg-main))) - `(git-rebase-hash ((,class :foreground ,cyan-alt-other))) -;;;;; git-timemachine - `(git-timemachine-commit ((,class :inherit bold :foreground ,yellow-active))) - `(git-timemachine-minibuffer-author-face ((,class :foreground ,fg-special-warm))) - `(git-timemachine-minibuffer-detail-face ((,class :foreground ,red-alt))) -;;;;; git-walktree - `(git-walktree-commit-face ((,class :foreground ,yellow))) - `(git-walktree-symlink-face ((,class :inherit button :foreground ,cyan))) - `(git-walktree-tree-face ((,class :foreground ,magenta))) -;;;;; gnus - `(gnus-button ((,class :inherit button))) - `(gnus-cite-1 ((,class :foreground ,blue-alt))) - `(gnus-cite-10 ((,class :foreground ,magenta-alt-other))) - `(gnus-cite-11 ((,class :foreground ,yellow-alt-other))) - `(gnus-cite-2 ((,class :foreground ,red-alt))) - `(gnus-cite-3 ((,class :foreground ,green-alt))) - `(gnus-cite-4 ((,class :foreground ,magenta-alt))) - `(gnus-cite-5 ((,class :foreground ,yellow-alt))) - `(gnus-cite-6 ((,class :foreground ,cyan-alt))) - `(gnus-cite-7 ((,class :foreground ,blue-alt-other))) - `(gnus-cite-8 ((,class :foreground ,red-alt-other))) - `(gnus-cite-9 ((,class :foreground ,green-alt-other))) - `(gnus-cite-attribution ((,class :foreground ,fg-main :slant italic))) - `(gnus-emphasis-highlight-words ((,class :inherit modus-theme-refine-yellow))) - `(gnus-group-mail-1 ((,class :inherit bold :foreground ,magenta-alt))) - `(gnus-group-mail-1-empty ((,class :foreground ,magenta-alt))) - `(gnus-group-mail-2 ((,class :inherit bold :foreground ,magenta))) - `(gnus-group-mail-2-empty ((,class :foreground ,magenta))) - `(gnus-group-mail-3 ((,class :inherit bold :foreground ,magenta-alt-other))) - `(gnus-group-mail-3-empty ((,class :foreground ,magenta-alt-other))) - `(gnus-group-mail-low ((,class :inherit bold :foreground ,magenta-nuanced))) - `(gnus-group-mail-low-empty ((,class :foreground ,magenta-nuanced))) - `(gnus-group-news-1 ((,class :inherit bold :foreground ,green))) - `(gnus-group-news-1-empty ((,class :foreground ,green))) - `(gnus-group-news-2 ((,class :inherit bold :foreground ,cyan))) - `(gnus-group-news-2-empty ((,class :foreground ,cyan))) - `(gnus-group-news-3 ((,class :inherit bold :foreground ,yellow-nuanced))) - `(gnus-group-news-3-empty ((,class :foreground ,yellow-nuanced))) - `(gnus-group-news-4 ((,class :inherit bold :foreground ,cyan-nuanced))) - `(gnus-group-news-4-empty ((,class :foreground ,cyan-nuanced))) - `(gnus-group-news-5 ((,class :inherit bold :foreground ,red-nuanced))) - `(gnus-group-news-5-empty ((,class :foreground ,red-nuanced))) - `(gnus-group-news-6 ((,class :inherit bold :foreground ,fg-alt))) - `(gnus-group-news-6-empty ((,class :foreground ,fg-alt))) - `(gnus-group-news-low ((,class :inherit bold :foreground ,green-nuanced))) - `(gnus-group-news-low-empty ((,class :foreground ,green-nuanced))) - `(gnus-header-content ((,class :foreground ,cyan))) - `(gnus-header-from ((,class :inherit bold :foreground ,cyan-alt-other :underline nil))) - `(gnus-header-name ((,class :foreground ,green))) - `(gnus-header-newsgroups ((,class :inherit bold :foreground ,blue-alt))) - `(gnus-header-subject ((,class :inherit bold :foreground ,magenta-alt-other))) - `(gnus-server-agent ((,class :inherit bold :foreground ,cyan))) - `(gnus-server-closed ((,class :inherit bold :foreground ,magenta))) - `(gnus-server-cloud ((,class :inherit bold :foreground ,cyan-alt))) - `(gnus-server-cloud-host ((,class :inherit modus-theme-refine-cyan))) - `(gnus-server-denied ((,class :inherit bold :foreground ,red))) - `(gnus-server-offline ((,class :inherit bold :foreground ,yellow))) - `(gnus-server-opened ((,class :inherit bold :foreground ,green))) - `(gnus-signature ((,class :foreground ,fg-special-cold :slant italic))) - `(gnus-splash ((,class :foreground ,fg-alt))) - `(gnus-summary-cancelled ((,class :inherit modus-theme-mark-alt))) - `(gnus-summary-high-ancient ((,class :inherit bold :foreground ,fg-alt))) - `(gnus-summary-high-read ((,class :inherit bold :foreground ,fg-special-cold))) - `(gnus-summary-high-ticked ((,class :inherit bold :foreground ,red-alt-other))) - `(gnus-summary-high-undownloaded ((,class :inherit bold :foreground ,yellow))) - `(gnus-summary-high-unread ((,class :inherit bold :foreground ,fg-main))) - `(gnus-summary-low-ancient ((,class :foreground ,fg-alt :slant italic))) - `(gnus-summary-low-read ((,class :foreground ,fg-alt :slant italic))) - `(gnus-summary-low-ticked ((,class :foreground ,red-refine-fg :slant italic))) - `(gnus-summary-low-undownloaded ((,class :foreground ,yellow-refine-fg :slant italic))) - `(gnus-summary-low-unread ((,class :inherit bold :foreground ,fg-special-cold))) - `(gnus-summary-normal-ancient ((,class :foreground ,fg-special-calm))) - `(gnus-summary-normal-read ((,class :foreground ,fg-alt))) - `(gnus-summary-normal-ticked ((,class :foreground ,red-alt-other))) - `(gnus-summary-normal-undownloaded ((,class :foreground ,yellow))) - `(gnus-summary-normal-unread ((,class :foreground ,fg-main))) - `(gnus-summary-selected ((,class :inherit modus-theme-subtle-blue))) -;;;;; golden-ratio-scroll-screen - `(golden-ratio-scroll-highlight-line-face ((,class :background ,cyan-subtle-bg :foreground ,fg-main))) -;;;;; helm - `(helm-M-x-key ((,class :inherit bold :foreground ,magenta-alt-other))) - `(helm-action ((,class :underline t))) - `(helm-bookmark-addressbook ((,class :foreground ,green-alt))) - `(helm-bookmark-directory ((,class :inherit bold :foreground ,blue))) - `(helm-bookmark-file ((,class :foreground ,fg-main))) - `(helm-bookmark-file-not-found ((,class :background ,bg-alt :foreground ,fg-alt))) - `(helm-bookmark-gnus ((,class :foreground ,magenta))) - `(helm-bookmark-info ((,class :foreground ,cyan-alt))) - `(helm-bookmark-man ((,class :foreground ,yellow-alt))) - `(helm-bookmark-w3m ((,class :foreground ,blue-alt))) - `(helm-buffer-archive ((,class :inherit bold :foreground ,cyan))) - `(helm-buffer-directory ((,class :inherit bold :foreground ,blue))) - `(helm-buffer-file ((,class :foreground ,fg-main))) - `(helm-buffer-modified ((,class :foreground ,yellow-alt))) - `(helm-buffer-not-saved ((,class :foreground ,red-alt))) - `(helm-buffer-process ((,class :foreground ,magenta))) - `(helm-buffer-saved-out ((,class :inherit bold :background ,bg-alt :foreground ,red))) - `(helm-buffer-size ((,class :foreground ,fg-alt))) - `(helm-candidate-number ((,class :foreground ,cyan-active))) - `(helm-candidate-number-suspended ((,class :foreground ,yellow-active))) - `(helm-comint-prompts-buffer-name ((,class :foreground ,green-active))) - `(helm-comint-prompts-promptidx ((,class :foreground ,cyan-active))) - `(helm-delete-async-message ((,class :inherit bold :foreground ,magenta-active))) - `(helm-eob-line ((,class :background ,bg-main :foreground ,fg-main))) - `(helm-eshell-prompts-buffer-name ((,class :foreground ,green-active))) - `(helm-eshell-prompts-promptidx ((,class :foreground ,cyan-active))) - `(helm-etags-file ((,class :foreground ,fg-dim :underline t))) - `(helm-ff-backup-file ((,class :foreground ,fg-alt))) - `(helm-ff-denied ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-red - 'modus-theme-intense-red - 'modus-theme-nuanced-red - red)))) - `(helm-ff-directory ((,class :inherit helm-buffer-directory))) - `(helm-ff-dirs ((,class :inherit bold :foreground ,blue-alt-other))) - `(helm-ff-dotted-directory ((,class :inherit bold :background ,bg-alt :foreground ,fg-alt))) - `(helm-ff-dotted-symlink-directory ((,class :inherit (button helm-ff-dotted-directory)))) - `(helm-ff-executable ((,class :foreground ,magenta-alt))) - `(helm-ff-file ((,class :foreground ,fg-main))) - `(helm-ff-file-extension ((,class :foreground ,fg-special-warm))) - `(helm-ff-invalid-symlink ((,class :inherit button :foreground ,red))) - `(helm-ff-pipe ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-refine-magenta - 'modus-theme-subtle-magenta - 'modus-theme-nuanced-magenta - magenta)))) - `(helm-ff-prefix ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-refine-yellow - 'modus-theme-subtle-yellow - 'modus-theme-nuanced-yellow - yellow-alt-other)))) - `(helm-ff-socket ((,class :foreground ,red-alt-other))) - `(helm-ff-suid ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-red - 'modus-theme-refine-red - 'modus-theme-nuanced-yellow - red-alt)))) - `(helm-ff-symlink ((,class :inherit button :foreground ,cyan))) - `(helm-ff-truename ((,class :foreground ,blue-alt-other))) - `(helm-grep-cmd-line ((,class :foreground ,yellow-alt-other))) - `(helm-grep-file ((,class :inherit bold :foreground ,fg-special-cold))) - `(helm-grep-finish ((,class :foreground ,green-active))) - `(helm-grep-lineno ((,class :foreground ,fg-special-warm))) - `(helm-grep-match ((,class :inherit modus-theme-special-calm))) - `(helm-header ((,class :inherit bold :foreground ,fg-special-cold))) - `(helm-header-line-left-margin ((,class :inherit bold :foreground ,yellow-intense))) - `(helm-history-deleted ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-red - 'modus-theme-intense-red - 'modus-theme-nuanced-red - red - 'bold)))) - `(helm-history-remote ((,class :foreground ,red-alt-other))) - `(helm-lisp-completion-info ((,class :foreground ,fg-special-warm))) - `(helm-lisp-show-completion ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-yellow - 'modus-theme-refine-yellow - 'modus-theme-nuanced-yellow - yellow - 'bold)))) - `(helm-locate-finish ((,class :foreground ,green-active))) - `(helm-match ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-cyan - 'modus-theme-refine-cyan - 'modus-theme-nuanced-cyan - cyan - 'bold)))) - `(helm-match-item ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-neutral - 'modus-theme-subtle-cyan - 'modus-theme-nuanced-cyan - cyan-alt-other)))) - `(helm-minibuffer-prompt ((,class :inherit minibuffer-prompt))) - `(helm-moccur-buffer ((,class :inherit button :foreground ,cyan-alt-other))) - `(helm-mode-prefix ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-magenta - 'modus-theme-intense-magenta - 'modus-theme-nuanced-magenta - magenta-alt - 'bold)))) - `(helm-non-file-buffer ((,class :foreground ,fg-alt))) - `(helm-prefarg ((,class :foreground ,red-active))) - `(helm-resume-need-update ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-magenta - 'modus-theme-refine-magenta - 'modus-theme-nuanced-magenta - magenta-alt-other)))) - `(helm-selection ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-blue - 'modus-theme-refine-blue - 'modus-theme-special-cold - nil - 'bold)))) - `(helm-selection-line ((,class :inherit modus-theme-special-cold))) - `(helm-separator ((,class :foreground ,fg-special-mild))) - `(helm-time-zone-current ((,class :foreground ,green))) - `(helm-time-zone-home ((,class :foreground ,magenta))) - `(helm-source-header ((,class :inherit bold :foreground ,red-alt - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-4)))) - `(helm-top-columns ((,class :inherit helm-header))) - `(helm-ucs-char ((,class :foreground ,yellow-alt-other))) - `(helm-visible-mark ((,class :inherit modus-theme-subtle-cyan))) -;;;;; helm-ls-git - `(helm-ls-git-added-copied-face ((,class :foreground ,green-intense))) - `(helm-ls-git-added-modified-face ((,class :foreground ,yellow-intense))) - `(helm-ls-git-conflict-face ((,class :inherit bold :foreground ,red-intense))) - `(helm-ls-git-deleted-and-staged-face ((,class :foreground ,red-nuanced))) - `(helm-ls-git-deleted-not-staged-face ((,class :foreground ,red))) - `(helm-ls-git-modified-and-staged-face ((,class :foreground ,yellow-nuanced))) - `(helm-ls-git-modified-not-staged-face ((,class :foreground ,yellow))) - `(helm-ls-git-renamed-modified-face ((,class :foreground ,magenta))) - `(helm-ls-git-untracked-face ((,class :foreground ,fg-special-cold))) -;;;;; helm-switch-shell - `(helm-switch-shell-new-shell-face ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-magenta - 'modus-theme-refine-magenta - 'modus-theme-nuanced-magenta - magenta-alt-other - 'bold)))) -;;;;; helm-xref - `(helm-xref-file-name ((,class :inherit bold :foreground ,fg-special-cold))) - `(helm-xref-file-name ((,class :foreground ,fg-special-warm))) -;;;;; helpful - `(helpful-heading ((,class :inherit modus-theme-heading-1))) -;;;;; highlight region or ad-hoc regexp - `(hi-black-b ((,class :background ,fg-main :foreground ,bg-main))) - `(hi-blue ((,class :background ,bg-alt :foreground ,blue :underline t))) - `(hi-blue-b ((,class :inherit modus-theme-intense-blue))) - `(hi-green ((,class :background ,bg-alt :foreground ,green :underline t))) - `(hi-green-b ((,class :inherit modus-theme-intense-green))) - `(hi-pink ((,class :background ,bg-alt :foreground ,magenta :underline t))) - `(hi-red-b ((,class :inherit modus-theme-intense-red))) - `(hi-yellow ((,class :background ,bg-alt :foreground ,yellow :underline t))) - `(highlight ((,class :inherit modus-theme-subtle-blue))) - `(highlight-changes ((,class :foreground ,yellow-alt-other))) - `(highlight-changes-delete ((,class :foreground ,red-alt-other :underline t))) - `(hl-line ((,class :inherit modus-theme-hl-line))) -;;;;; highlight-blocks - `(highlight-blocks-depth-1-face ((,class :background ,bg-dim :foreground ,fg-main))) - `(highlight-blocks-depth-2-face ((,class :background ,bg-alt :foreground ,fg-main))) - `(highlight-blocks-depth-3-face ((,class :background ,bg-special-cold :foreground ,fg-main))) - `(highlight-blocks-depth-4-face ((,class :background ,bg-special-calm :foreground ,fg-main))) - `(highlight-blocks-depth-5-face ((,class :background ,bg-special-warm :foreground ,fg-main))) - `(highlight-blocks-depth-6-face ((,class :background ,bg-special-mild :foreground ,fg-main))) - `(highlight-blocks-depth-7-face ((,class :background ,bg-inactive :foreground ,fg-main))) - `(highlight-blocks-depth-8-face ((,class :background ,bg-active :foreground ,fg-main))) - `(highlight-blocks-depth-9-face ((,class :background ,cyan-subtle-bg :foreground ,fg-main))) -;;;;; highlight-defined - `(highlight-defined-builtin-function-name-face ((,class :foreground ,magenta))) - `(highlight-defined-face-name-face ((,class :foreground ,fg-main))) - `(highlight-defined-function-name-face ((,class :foreground ,magenta))) - `(highlight-defined-macro-name-face ((,class :foreground ,magenta-alt))) - `(highlight-defined-special-form-name-face ((,class :foreground ,magenta-alt-other))) - `(highlight-defined-variable-name-face ((,class :foreground ,cyan))) -;;;;; highlight-escape-sequences (`hes-mode') - `(hes-escape-backslash-face ((,class :inherit bold :foreground ,fg-escape-char-construct))) - `(hes-escape-sequence-face ((,class :inherit bold :foreground ,fg-escape-char-backslash))) -;;;;; highlight-indentation - `(highlight-indentation-face ((,class :inherit modus-theme-hl-line))) - `(highlight-indentation-current-column-face ((,class :background ,bg-active))) -;;;;; highlight-numbers - `(highlight-numbers-number ((,class :foreground ,blue-alt-other))) -;;;;; highlight-symbol - `(highlight-symbol-face ((,class :inherit modus-theme-special-mild))) -;;;;; highlight-thing - `(highlight-thing ((,class :background ,bg-alt :foreground ,cyan))) -;;;;; hl-defined - `(hdefd-functions ((,class :foreground ,blue))) - `(hdefd-undefined ((,class :foreground ,red-alt))) - `(hdefd-variables ((,class :foreground ,cyan-alt))) -;;;;; hl-fill-column - `(hl-fill-column-face ((,class :background ,bg-active :foreground ,fg-active))) -;;;;; hl-todo - `(hl-todo ((,class :inherit bold :foreground ,red-alt-other :slant ,modus-theme-slant))) -;;;;; hydra - `(hydra-face-amaranth ((,class :inherit bold :foreground ,yellow))) - `(hydra-face-blue ((,class :inherit bold :foreground ,blue-alt))) - `(hydra-face-pink ((,class :inherit bold :foreground ,magenta-alt))) - `(hydra-face-red ((,class :inherit bold :foreground ,red))) - `(hydra-face-teal ((,class :inherit bold :foreground ,cyan))) -;;;;; hyperlist - `(hyperlist-condition ((,class :foreground ,green))) - `(hyperlist-hashtag ((,class :foreground ,yellow))) - `(hyperlist-operator ((,class :foreground ,blue-alt))) - `(hyperlist-paren ((,class :foreground ,cyan-alt-other))) - `(hyperlist-quote ((,class :foreground ,cyan-alt))) - `(hyperlist-ref ((,class :foreground ,magenta-alt-other))) - `(hyperlist-stars ((,class :foreground ,fg-alt))) - `(hyperlist-tag ((,class :foreground ,red))) - `(hyperlist-toplevel ((,class :inherit bold :foreground ,fg-main))) -;;;;; icomplete - `(icomplete-first-match ((,class :inherit bold - ,@(modus-operandi-theme-standard-completions - magenta bg-alt - bg-active fg-main)))) -;;;;; icomplete-vertical - `(icomplete-vertical-separator ((,class :foreground ,fg-alt))) -;;;;; ido-mode - `(ido-first-match ((,class :inherit bold - ,@(modus-operandi-theme-standard-completions - magenta bg-alt - bg-active fg-main)))) - `(ido-incomplete-regexp ((,class :inherit error))) - `(ido-indicator ((,class :inherit modus-theme-subtle-yellow))) - `(ido-only-match ((,class :inherit bold - ,@(modus-operandi-theme-standard-completions - green green-nuanced-bg - green-intense-bg fg-main)))) - `(ido-subdir ((,class :foreground ,blue))) - `(ido-virtual ((,class :foreground ,fg-special-warm))) -;;;;; iedit - `(iedit-occurrence ((,class :inherit modus-theme-refine-blue))) - `(iedit-read-only-occurrence ((,class :inherit modus-theme-intense-yellow))) -;;;;; iflipb - `(iflipb-current-buffer-face ((,class :inherit bold :foreground ,cyan-alt))) - `(iflipb-other-buffer-face ((,class :foreground ,fg-alt))) -;;;;; imenu-list - `(imenu-list-entry-face-0 ((,class :foreground ,cyan))) - `(imenu-list-entry-face-1 ((,class :foreground ,blue))) - `(imenu-list-entry-face-2 ((,class :foreground ,cyan-alt-other))) - `(imenu-list-entry-face-3 ((,class :foreground ,blue-alt))) - `(imenu-list-entry-subalist-face-0 ((,class :inherit bold :foreground ,magenta-alt-other :underline t))) - `(imenu-list-entry-subalist-face-1 ((,class :inherit bold :foreground ,magenta :underline t))) - `(imenu-list-entry-subalist-face-2 ((,class :inherit bold :foreground ,green-alt-other :underline t))) - `(imenu-list-entry-subalist-face-3 ((,class :inherit bold :foreground ,red-alt-other :underline t))) -;;;;; indium - `(indium-breakpoint-face ((,class :foreground ,red-active))) - `(indium-frame-url-face ((,class :inherit button :foreground ,fg-alt))) - `(indium-keyword-face ((,class :foreground ,magenta-alt-other))) - `(indium-litable-face ((,class :foreground ,fg-special-warm :slant ,modus-theme-slant))) - `(indium-repl-error-face ((,class :inherit bold :foreground ,red))) - `(indium-repl-prompt-face ((,class :foreground ,cyan-alt-other))) - `(indium-repl-stdout-face ((,class :foreground ,fg-main))) -;;;;; info - `(Info-quoted ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,magenta))) ; the capitalisation is canonical - `(info-header-node ((,class :inherit bold :foreground ,fg-alt))) - `(info-header-xref ((,class :foreground ,blue-active))) - `(info-index-match ((,class :inherit match))) - `(info-menu-header ((,class :inherit modus-theme-heading-3))) - `(info-menu-star ((,class :foreground ,red))) - `(info-node ((,class :inherit bold))) - `(info-title-1 ((,class :inherit modus-theme-heading-1))) - `(info-title-2 ((,class :inherit modus-theme-heading-2))) - `(info-title-3 ((,class :inherit modus-theme-heading-3))) - `(info-title-4 ((,class :inherit modus-theme-heading-4))) -;;;;; info-colors - `(info-colors-lisp-code-block ((,class :inherit fixed-pitch))) - `(info-colors-ref-item-command ((,class :foreground ,magenta))) - `(info-colors-ref-item-constant ((,class :foreground ,blue-alt-other))) - `(info-colors-ref-item-function ((,class :foreground ,magenta))) - `(info-colors-ref-item-macro ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,magenta-alt-other))) - `(info-colors-ref-item-other ((,class :foreground ,cyan))) - `(info-colors-ref-item-special-form ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,magenta-alt-other))) - `(info-colors-ref-item-syntax-class ((,class :foreground ,magenta))) - `(info-colors-ref-item-type ((,class :foreground ,magenta-alt))) - `(info-colors-ref-item-user-option ((,class :foreground ,cyan))) - `(info-colors-ref-item-variable ((,class :foreground ,cyan))) -;;;;; interaction-log - `(ilog-buffer-face ((,class :foreground ,magenta-alt-other))) - `(ilog-change-face ((,class :foreground ,magenta-alt))) - `(ilog-echo-face ((,class :foreground ,yellow-alt-other))) - `(ilog-load-face ((,class :foreground ,green))) - `(ilog-message-face ((,class :foreground ,fg-alt))) - `(ilog-non-change-face ((,class :foreground ,blue))) -;;;;; ioccur - `(ioccur-cursor ((,class :foreground ,fg-main))) - `(ioccur-invalid-regexp ((,class :foreground ,red))) - `(ioccur-match-face ((,class :inherit modus-theme-special-calm))) - `(ioccur-match-overlay-face ((,class ,@(and (>= emacs-major-version 27) '(:extend t)) - :inherit modus-theme-special-cold))) - `(ioccur-num-line-face ((,class :foreground ,fg-special-warm))) - `(ioccur-overlay-face ((,class ,@(and (>= emacs-major-version 27) '(:extend t)) - :inherit modus-theme-refine-blue))) - `(ioccur-regexp-face ((,class :inherit (modus-theme-intense-magenta bold)))) - `(ioccur-title-face ((,class :inherit bold :foreground ,red-alt - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-4)))) -;;;;; isearch, occur, and the like - `(isearch ((,class :inherit (modus-theme-intense-green bold)))) - `(isearch-fail ((,class :inherit modus-theme-refine-red))) - `(lazy-highlight ((,class :inherit modus-theme-refine-cyan))) - `(match ((,class :inherit modus-theme-special-calm))) - `(query-replace ((,class :inherit (modus-theme-intense-yellow bold)))) -;;;;; ivy - `(ivy-action ((,class :inherit bold :foreground ,red-alt))) - `(ivy-completions-annotations ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(ivy-confirm-face ((,class :foreground ,cyan))) - `(ivy-current-match ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-refine-cyan - 'modus-theme-intense-cyan - 'modus-theme-special-warm - nil - 'bold)))) - `(ivy-cursor ((,class :background ,fg-main :foreground ,bg-main))) - `(ivy-grep-info ((,class :foreground ,cyan-alt))) - `(ivy-grep-line-number ((,class :foreground ,fg-special-warm))) - `(ivy-highlight-face ((,class :foreground ,magenta))) - `(ivy-match-required-face ((,class :inherit error))) - `(ivy-minibuffer-match-face-1 ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-neutral - 'modus-theme-intense-neutral - 'modus-theme-subtle-neutral - fg-alt)))) - `(ivy-minibuffer-match-face-2 ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-green - 'modus-theme-refine-green - 'modus-theme-nuanced-green - green-alt-other - 'bold)))) - `(ivy-minibuffer-match-face-3 ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-cyan - 'modus-theme-refine-cyan - 'modus-theme-nuanced-cyan - cyan-alt-other - 'bold)))) - `(ivy-minibuffer-match-face-4 ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-magenta - 'modus-theme-refine-magenta - 'modus-theme-nuanced-magenta - magenta-alt-other - 'bold)))) - `(ivy-minibuffer-match-highlight ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-blue - 'modus-theme-intense-blue - 'modus-theme-nuanced-blue - blue-alt-other - 'bold)))) - `(ivy-modified-buffer ((,class :foreground ,yellow :slant ,modus-theme-slant))) - `(ivy-modified-outside-buffer ((,class :foreground ,yellow-alt :slant ,modus-theme-slant))) - `(ivy-org ((,class :foreground ,cyan-alt-other))) - `(ivy-prompt-match ((,class :inherit ivy-current-match))) - `(ivy-remote ((,class :foreground ,magenta))) - `(ivy-separator ((,class :foreground ,fg-alt))) - `(ivy-subdir ((,class :foreground ,blue-alt-other))) - `(ivy-virtual ((,class :foreground ,magenta-alt-other))) - `(ivy-yanked-word ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-blue - 'modus-theme-refine-blue - 'modus-theme-nuanced-blue - blue-alt)))) -;;;;; ivy-posframe - `(ivy-posframe ((,class :background ,bg-dim :foreground ,fg-main))) - `(ivy-posframe-border ((,class :background ,bg-active))) - `(ivy-posframe-cursor ((,class :background ,fg-main :foreground ,bg-main))) -;;;;; jira (org-jira) - `(jiralib-comment-face ((,class :background ,bg-alt))) - `(jiralib-comment-header-face ((,class :inherit bold))) - `(jiralib-issue-info-face ((,class :inherit modus-theme-special-warm))) - `(jiralib-issue-info-header-face ((,class :inherit (modus-theme-special-warm bold)))) - `(jiralib-issue-summary-face ((,class :inherit bold))) - `(jiralib-link-filter-face ((,class :underline t))) - `(jiralib-link-issue-face ((,class :underline t))) - `(jiralib-link-project-face ((,class :underline t))) -;;;;; journalctl-mode - `(journalctl-error-face ((,class :inherit bold :foreground ,red))) - `(journalctl-finished-face ((,class :inherit bold :foreground ,green))) - `(journalctl-host-face ((,class :foreground ,blue))) - `(journalctl-process-face ((,class :foreground ,cyan-alt-other))) - `(journalctl-starting-face ((,class :foreground ,green))) - `(journalctl-timestamp-face ((,class :foreground ,fg-special-cold))) - `(journalctl-warning-face ((,class :inherit bold :foreground ,yellow))) -;;;;; js2-mode - `(js2-error ((,class :foreground ,red))) - `(js2-external-variable ((,class :foreground ,cyan-alt-other))) - `(js2-function-call ((,class :foreground ,magenta))) - `(js2-function-param ((,class :foreground ,blue))) - `(js2-instance-member ((,class :foreground ,magenta-alt-other))) - `(js2-jsdoc-html-tag-delimiter ((,class :foreground ,fg-main))) - `(js2-jsdoc-html-tag-name ((,class :foreground ,cyan))) - `(js2-jsdoc-tag ((,class :foreground ,fg-special-calm))) - `(js2-jsdoc-type ((,class :foreground ,fg-special-cold))) - `(js2-jsdoc-value ((,class :foreground ,fg-special-warm))) - `(js2-object-property ((,class :foreground ,fg-main))) - `(js2-object-property-access ((,class :foreground ,fg-main))) - `(js2-private-function-call ((,class :foreground ,green-alt-other))) - `(js2-private-member ((,class :foreground ,fg-special-mild))) - `(js2-warning ((,class :foreground ,yellow-alt :underline t))) -;;;;; julia - `(julia-macro-face ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,magenta))) - `(julia-quoted-symbol-face ((,class :foreground ,blue-alt-other))) -;;;;; jupyter - `(jupyter-eval-overlay ((,class :inherit bold :foreground ,blue))) - `(jupyter-repl-input-prompt ((,class :foreground ,cyan-alt-other))) - `(jupyter-repl-output-prompt ((,class :foreground ,magenta-alt-other))) - `(jupyter-repl-traceback ((,class :inherit modus-theme-intense-red))) -;;;;; kaocha-runner - `(kaocha-runner-error-face ((,class :foreground ,red))) - `(kaocha-runner-success-face ((,class :foreground ,green))) - `(kaocha-runner-warning-face ((,class :foreground ,yellow))) -;;;;; keycast - `(keycast-command ((,class :inherit bold :foreground ,blue-active))) - `(keycast-key ((,class ,@(modus-operandi-theme-mode-line-attrs - bg-main blue-active - bg-main blue-active - blue-active blue-intense - 'alt-style -3)))) -;;;;; line numbers (display-line-numbers-mode and global variant) - `(line-number ((,class :inherit default :background ,bg-dim :foreground ,fg-alt))) - `(line-number-current-line ((,class :inherit default :background ,bg-active :foreground ,fg-main))) -;;;;; lsp-mode - `(lsp-face-highlight-read ((,class :inherit modus-theme-subtle-blue :underline t))) - `(lsp-face-highlight-textual ((,class :inherit modus-theme-subtle-blue))) - `(lsp-face-highlight-write ((,class :inherit (modus-theme-refine-blue bold)))) - `(lsp-face-semhl-constant ((,class :foreground ,blue-alt-other))) - `(lsp-face-semhl-deprecated - ((,(append '((supports :underline (:style wave))) class) - :foreground ,yellow :underline (:style wave)) - (,class :foreground ,yellow :underline t))) - `(lsp-face-semhl-enummember ((,class :foreground ,blue-alt-other))) - `(lsp-face-semhl-field ((,class :foreground ,cyan-alt))) - `(lsp-face-semhl-field-static ((,class :foreground ,cyan-alt :slant ,modus-theme-slant))) - `(lsp-face-semhl-function ((,class :foreground ,magenta))) - `(lsp-face-semhl-method ((,class :foreground ,magenta))) - `(lsp-face-semhl-namespace ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,magenta-alt))) - `(lsp-face-semhl-preprocessor ((,class :foreground ,red-alt-other))) - `(lsp-face-semhl-static-method ((,class :foreground ,magenta :slant ,modus-theme-slant))) - `(lsp-face-semhl-type-class ((,class :foreground ,magenta-alt))) - `(lsp-face-semhl-type-enum ((,class :foreground ,magenta-alt))) - `(lsp-face-semhl-type-primitive ((,class :foreground ,magenta-alt :slant ,modus-theme-slant))) - `(lsp-face-semhl-type-template ((,class :foreground ,magenta-alt :slant ,modus-theme-slant))) - `(lsp-face-semhl-type-typedef ((,class :foreground ,magenta-alt :slant ,modus-theme-slant))) - `(lsp-face-semhl-variable ((,class :foreground ,cyan))) - `(lsp-face-semhl-variable-local ((,class :foreground ,cyan))) - `(lsp-face-semhl-variable-parameter ((,class :foreground ,cyan-alt-other))) - `(lsp-lens-face ((,class :height 0.8 :foreground ,fg-alt))) - `(lsp-lens-mouse-face ((,class :height 0.8 :foreground ,blue-alt-other :underline t))) - `(lsp-ui-doc-background ((,class :background ,bg-alt))) - `(lsp-ui-doc-header ((,class :background ,bg-header :foreground ,fg-header))) - `(lsp-ui-doc-url ((,class :inherit button :foreground ,blue-alt-other))) - `(lsp-ui-peek-filename ((,class :foreground ,fg-special-warm))) - `(lsp-ui-peek-footer ((,class :background ,bg-header :foreground ,fg-header))) - `(lsp-ui-peek-header ((,class :background ,bg-header :foreground ,fg-header))) - `(lsp-ui-peek-highlight ((,class :inherit modus-theme-subtle-blue))) - `(lsp-ui-peek-line-number ((,class :foreground ,fg-alt))) - `(lsp-ui-peek-list ((,class :background ,bg-dim))) - `(lsp-ui-peek-peek ((,class :background ,bg-alt))) - `(lsp-ui-peek-selection ((,class :inherit modus-theme-subtle-cyan))) - `(lsp-ui-sideline-code-action ((,class :foreground ,yellow))) - `(lsp-ui-sideline-current-symbol ((,class :inherit bold :height 0.99 :box (:line-width -1 :style nil) :foreground ,fg-main))) - `(lsp-ui-sideline-symbol ((,class :inherit bold :height 0.99 :box (:line-width -1 :style nil) :foreground ,fg-alt))) - `(lsp-ui-sideline-symbol-info ((,class :height 0.99 :slant italic))) -;;;;; magit - `(magit-bisect-bad ((,class :foreground ,red-alt-other))) - `(magit-bisect-good ((,class :foreground ,green-alt-other))) - `(magit-bisect-skip ((,class :foreground ,yellow-alt-other))) - `(magit-blame-date ((,class :foreground ,blue))) - `(magit-blame-dimmed ((,class :foreground ,fg-alt))) - `(magit-blame-hash ((,class :foreground ,fg-special-warm))) - `(magit-blame-heading ((,class :background ,bg-alt))) - `(magit-blame-highlight ((,class :inherit modus-theme-nuanced-cyan))) - `(magit-blame-margin ((,class :inherit magit-blame-highlight))) - `(magit-blame-name ((,class :foreground ,magenta-alt-other))) - `(magit-blame-summary ((,class :foreground ,cyan-alt-other))) - `(magit-branch-current ((,class :foreground ,blue-alt-other :box t))) - `(magit-branch-local ((,class :foreground ,blue-alt))) - `(magit-branch-remote ((,class :foreground ,magenta-alt))) - `(magit-branch-remote-head ((,class :foreground ,magenta-alt-other :box t))) - `(magit-branch-upstream ((,class :slant italic))) - `(magit-cherry-equivalent ((,class :background ,bg-main :foreground ,magenta-intense))) - `(magit-cherry-unmatched ((,class :background ,bg-main :foreground ,cyan-intense))) - ;; NOTE: here we break from the pattern of inheriting from the - ;; modus-theme-diff-* faces, though only for the standard actions, - ;; not the highlighted ones. This is because Magit's interaction - ;; model relies on highlighting the current diff hunk. - `(magit-diff-added ((,class ,@(modus-operandi-theme-diff - bg-main green - bg-diff-added fg-diff-added - green-nuanced-bg fg-diff-added)))) - `(magit-diff-added-highlight ((,class :inherit modus-theme-diff-focus-added))) - `(magit-diff-base ((,class ,@(modus-operandi-theme-diff - bg-main yellow - bg-diff-changed fg-diff-changed - yellow-nuanced-bg fg-diff-changed)))) - `(magit-diff-base-highlight ((,class :inherit modus-theme-diff-focus-changed))) - `(magit-diff-context ((,class :foreground ,fg-unfocused))) - `(magit-diff-context-highlight ((,class ,@(modus-operandi-theme-diff - bg-dim fg-dim - bg-inactive fg-inactive - bg-dim fg-alt)))) - `(magit-diff-file-heading ((,class :inherit bold :foreground ,fg-special-cold))) - `(magit-diff-file-heading-highlight ((,class :inherit (modus-theme-special-cold bold)))) - `(magit-diff-file-heading-selection ((,class :inherit modus-theme-refine-cyan))) - ;; NOTE: here we break from the pattern of inheriting from the - ;; modus-theme-diff-* faces. - `(magit-diff-hunk-heading ((,class :inherit bold :background ,bg-active - :foreground ,fg-inactive))) - `(magit-diff-hunk-heading-highlight ((,class :inherit bold :background ,bg-diff-heading - :foreground ,fg-diff-heading))) - `(magit-diff-hunk-heading-selection ((,class :inherit modus-theme-refine-blue))) - `(magit-diff-hunk-region ((,class :inherit bold))) - `(magit-diff-lines-boundary ((,class :background ,fg-main))) - `(magit-diff-lines-heading ((,class :inherit modus-theme-refine-magenta))) - `(magit-diff-removed ((,class ,@(modus-operandi-theme-diff - bg-main red - bg-diff-removed fg-diff-removed - red-nuanced-bg fg-diff-removed)))) - `(magit-diff-removed-highlight ((,class :inherit modus-theme-diff-focus-removed))) - `(magit-diffstat-added ((,class :foreground ,green))) - `(magit-diffstat-removed ((,class :foreground ,red))) - `(magit-dimmed ((,class :foreground ,fg-unfocused))) - `(magit-filename ((,class :foreground ,fg-special-cold))) - `(magit-hash ((,class :foreground ,fg-alt))) - `(magit-head ((,class :inherit magit-branch-local))) - `(magit-header-line ((,class :inherit bold :foreground ,magenta-active))) - `(magit-header-line-key ((,class :inherit bold :foreground ,red-active))) - `(magit-header-line-log-select ((,class :inherit bold :foreground ,fg-main))) - `(magit-keyword ((,class :foreground ,magenta))) - `(magit-keyword-squash ((,class :inherit bold :foreground ,yellow-alt-other))) - `(magit-log-author ((,class :foreground ,cyan))) - `(magit-log-date ((,class :foreground ,fg-alt))) - `(magit-log-graph ((,class :foreground ,fg-dim))) - `(magit-mode-line-process ((,class :inherit bold :foreground ,blue-active))) - `(magit-mode-line-process-error ((,class :inherit bold :foreground ,red-active))) - `(magit-process-ng ((,class :inherit error))) - `(magit-process-ok ((,class :inherit success))) - `(magit-reflog-amend ((,class :background ,bg-main :foreground ,magenta-intense))) - `(magit-reflog-checkout ((,class :background ,bg-main :foreground ,blue-intense))) - `(magit-reflog-cherry-pick ((,class :background ,bg-main :foreground ,green-intense))) - `(magit-reflog-commit ((,class :background ,bg-main :foreground ,green-intense))) - `(magit-reflog-merge ((,class :background ,bg-main :foreground ,green-intense))) - `(magit-reflog-other ((,class :background ,bg-main :foreground ,cyan-intense))) - `(magit-reflog-rebase ((,class :background ,bg-main :foreground ,magenta-intense))) - `(magit-reflog-remote ((,class :background ,bg-main :foreground ,cyan-intense))) - `(magit-reflog-reset ((,class :background ,bg-main :foreground ,red-intense))) - `(magit-refname ((,class :foreground ,fg-alt))) - `(magit-refname-pullreq ((,class :foreground ,fg-alt))) - `(magit-refname-stash ((,class :foreground ,fg-alt))) - `(magit-refname-wip ((,class :foreground ,fg-alt))) - `(magit-section ((,class :background ,bg-dim :foreground ,fg-main))) - `(magit-section-heading ((,class :inherit bold :foreground ,cyan))) - `(magit-section-heading-selection ((,class :inherit (modus-theme-refine-cyan bold)))) - `(magit-section-highlight ((,class :background ,bg-alt))) - `(magit-sequence-done ((,class :foreground ,green-alt))) - `(magit-sequence-drop ((,class :foreground ,red-alt))) - `(magit-sequence-exec ((,class :foreground ,magenta-alt))) - `(magit-sequence-head ((,class :foreground ,cyan-alt))) - `(magit-sequence-onto ((,class :foreground ,fg-alt))) - `(magit-sequence-part ((,class :foreground ,yellow-alt))) - `(magit-sequence-pick ((,class :foreground ,blue-alt))) - `(magit-sequence-stop ((,class :foreground ,red))) - `(magit-signature-bad ((,class :inherit bold :foreground ,red))) - `(magit-signature-error ((,class :foreground ,red-alt))) - `(magit-signature-expired ((,class :foreground ,yellow))) - `(magit-signature-expired-key ((,class :foreground ,yellow))) - `(magit-signature-good ((,class :foreground ,green))) - `(magit-signature-revoked ((,class :foreground ,magenta))) - `(magit-signature-untrusted ((,class :foreground ,cyan))) - `(magit-tag ((,class :foreground ,yellow-alt-other))) -;;;;; magit-imerge - `(magit-imerge-overriding-value ((,class :inherit bold :foreground ,red-alt))) -;;;;; man - `(Man-overstrike ((,class :inherit bold :foreground ,magenta))) - `(Man-reverse ((,class :inherit modus-theme-subtle-magenta))) - `(Man-underline ((,class :foreground ,cyan :underline t))) -;;;;; markdown-mode - `(markdown-blockquote-face ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(markdown-bold-face ((,class :inherit bold))) - `(markdown-code-face ((,class ,@(modus-operandi-theme-mixed-fonts)))) - `(markdown-comment-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(markdown-footnote-marker-face ((,class :inherit bold :foreground ,cyan-alt))) - `(markdown-footnote-text-face ((,class :foreground ,fg-main :slant ,modus-theme-slant))) - `(markdown-gfm-checkbox-face ((,class :foreground ,cyan-alt-other))) - `(markdown-header-delimiter-face ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,fg-dim))) - `(markdown-header-face ((t nil))) - `(markdown-header-face-1 ((,class :inherit modus-theme-heading-1))) - `(markdown-header-face-2 ((,class :inherit modus-theme-heading-2))) - `(markdown-header-face-3 ((,class :inherit modus-theme-heading-3))) - `(markdown-header-face-4 ((,class :inherit modus-theme-heading-4))) - `(markdown-header-face-5 ((,class :inherit modus-theme-heading-5))) - `(markdown-header-face-6 ((,class :inherit modus-theme-heading-6))) - `(markdown-header-rule-face ((,class :inherit bold :foreground ,fg-special-warm))) - `(markdown-hr-face ((,class :inherit bold :foreground ,fg-special-warm))) - `(markdown-html-attr-name-face ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,cyan))) - `(markdown-html-attr-value-face ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,blue))) - `(markdown-html-entity-face ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,cyan))) - `(markdown-html-tag-delimiter-face ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,fg-special-mild))) - `(markdown-html-tag-name-face ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,magenta-alt))) - `(markdown-inline-code-face ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,magenta))) - `(markdown-italic-face ((,class :foreground ,fg-special-cold :slant italic))) - `(markdown-language-info-face ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,fg-special-cold))) - `(markdown-language-keyword-face ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,green-alt-other))) - `(markdown-line-break-face ((,class :inherit modus-theme-refine-cyan :underline t))) - `(markdown-link-face ((,class :inherit link))) - `(markdown-link-title-face ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(markdown-list-face ((,class :foreground ,fg-dim))) - `(markdown-markup-face ((,class :foreground ,fg-alt))) - `(markdown-math-face ((,class :foreground ,magenta-alt-other))) - `(markdown-metadata-key-face ((,class :foreground ,cyan-alt-other))) - `(markdown-metadata-value-face ((,class :foreground ,blue-alt))) - `(markdown-missing-link-face ((,class :inherit bold :foreground ,yellow))) - `(markdown-plain-url-face ((,class :inherit markdown-link-face))) - `(markdown-pre-face ((,class ,@(and (>= emacs-major-version 27) '(:extend t)) - ,@(modus-operandi-theme-mixed-fonts) - :background ,bg-dim - :foreground ,fg-special-mild))) - `(markdown-reference-face ((,class :inherit markdown-markup-face))) - `(markdown-strike-through-face ((,class :strike-through t))) - `(markdown-table-face ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,fg-special-cold))) - `(markdown-url-face ((,class :foreground ,blue-alt))) -;;;;; markup-faces (`adoc-mode') - `(markup-anchor-face ((,class :foreground ,fg-inactive))) - `(markup-attribute-face ((,class :foreground ,fg-inactive :slant italic))) - `(markup-big-face ((,class :height 1.3 :foreground ,blue-nuanced))) - `(markup-bold-face ((,class :inherit bold :foreground ,red-nuanced))) - `(markup-code-face ((,class :inherit fixed-pitch :foreground ,magenta))) - `(markup-command-face ((,class :foreground ,fg-inactive))) - `(markup-comment-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(markup-complex-replacement-face ((,class :box (:line-width 2 :color nil :style released-button) - :inherit modus-theme-refine-magenta))) - `(markup-emphasis-face ((,class :foreground ,fg-special-cold :slant italic))) - `(markup-error-face ((,class :inherit bold :foreground ,red))) - `(markup-gen-face ((,class :foreground ,magenta-alt))) - `(markup-internal-reference-face ((,class :inherit button :foreground ,fg-inactive))) - `(markup-italic-face ((,class :foreground ,fg-special-cold :slant italic))) - `(markup-list-face ((,class :inherit modus-theme-special-calm))) - `(markup-meta-face ((,class :foreground ,fg-inactive))) - `(markup-meta-hide-face ((,class :foreground ,fg-alt))) - `(markup-passthrough-face ((,class :inherit fixed-pitch :foreground ,cyan))) - `(markup-preprocessor-face ((,class :foreground ,red-alt-other))) - `(markup-replacement-face ((,class :foreground ,yellow-alt-other))) - `(markup-secondary-text-face ((,class :height 0.8 :foreground ,magenta-nuanced))) - `(markup-small-face ((,class :height 0.8 :foreground ,fg-main))) - `(markup-strong-face ((,class :inherit bold :foreground ,red-nuanced))) - `(markup-subscript-face ((,class :height 0.8 :foreground ,fg-special-cold))) - `(markup-superscript-face ((,class :height 0.8 :foreground ,fg-special-cold))) - `(markup-table-cell-face ((,class :inherit modus-theme-special-cold))) - `(markup-table-face ((,class :inherit modus-theme-subtle-cyan))) - `(markup-table-row-face ((,class :inherit modus-theme-subtle-cyan))) - `(markup-title-0-face ((,class :height 3.0 :foreground ,blue-nuanced))) - `(markup-title-1-face ((,class :height 2.4 :foreground ,blue-nuanced))) - `(markup-title-2-face ((,class :height 1.8 :foreground ,blue-nuanced))) - `(markup-title-3-face ((,class :height 1.4 :foreground ,blue-nuanced))) - `(markup-title-4-face ((,class :height 1.2 :foreground ,blue-nuanced))) - `(markup-title-5-face ((,class :height 1.2 :foreground ,blue-nuanced :underline t))) - `(markup-value-face ((,class :foreground ,fg-inactive))) - `(markup-verbatim-face ((,class :inherit modus-theme-special-mild))) -;;;;; mentor - `(mentor-download-message ((,class :foreground ,fg-special-warm))) - `(mentor-download-name ((,class :foreground ,fg-special-cold))) - `(mentor-download-progress ((,class :foreground ,blue-alt-other))) - `(mentor-download-size ((,class :foreground ,magenta-alt-other))) - `(mentor-download-speed-down ((,class :foreground ,cyan-alt))) - `(mentor-download-speed-up ((,class :foreground ,red-alt))) - `(mentor-download-state ((,class :foreground ,yellow-alt))) - `(mentor-highlight-face ((,class :inherit modus-theme-subtle-blue))) - `(mentor-tracker-name ((,class :foreground ,magenta-alt))) -;;;;; messages - `(message-cited-text-1 ((,class :foreground ,blue-alt))) - `(message-cited-text-2 ((,class :foreground ,red-alt))) - `(message-cited-text-3 ((,class :foreground ,green-alt))) - `(message-cited-text-4 ((,class :foreground ,magenta-alt))) - `(message-header-cc ((,class :inherit bold :foreground ,cyan-alt))) - `(message-header-name ((,class :foreground ,green-alt-other))) - `(message-header-newsgroups ((,class :inherit bold :foreground ,green-alt))) - `(message-header-other ((,class :inherit bold :foreground ,cyan-alt-other))) - `(message-header-subject ((,class :inherit bold :foreground ,magenta-alt-other))) - `(message-header-to ((,class :inherit bold :foreground ,blue))) - `(message-header-xheader ((,class :foreground ,cyan))) - `(message-mml ((,class :foreground ,fg-special-warm))) - `(message-separator ((,class :inherit modus-theme-intense-neutral))) -;;;;; minibuffer-line - `(minibuffer-line ((,class :foreground ,fg-main))) -;;;;; minimap - `(minimap-active-region-background ((,class :background ,bg-active))) - `(minimap-current-line-face ((,class :background ,cyan-intense-bg :foreground ,fg-main))) -;;;;; modeline - `(mode-line ((,class ,@(modus-operandi-theme-mode-line-attrs - fg-active bg-active fg-dim bg-active - fg-alt bg-active 'alt-style nil bg-main)))) - `(mode-line-buffer-id ((,class :inherit bold))) - `(mode-line-emphasis ((,class :inherit bold :foreground ,blue-active))) - `(mode-line-highlight ((,class :inherit modus-theme-active-blue :box (:line-width -1 :style pressed-button)))) - `(mode-line-inactive ((,class ,@(modus-operandi-theme-mode-line-attrs - fg-inactive bg-inactive fg-alt bg-dim - bg-region bg-active)))) -;;;;; mood-line - `(mood-line-modified ((,class :foreground ,magenta-active))) - `(mood-line-status-error ((,class :inherit bold :foreground ,red-active))) - `(mood-line-status-info ((,class :foreground ,cyan-active))) - `(mood-line-status-neutral ((,class :foreground ,blue-active))) - `(mood-line-status-success ((,class :foreground ,green-active))) - `(mood-line-status-warning ((,class :inherit bold :foreground ,yellow-active))) - `(mood-line-unimportant ((,class :foreground ,fg-inactive))) -;;;;; mpdel - `(mpdel-browser-directory-face ((,class :foreground ,blue))) - `(mpdel-playlist-current-song-face ((,class :inherit bold :foreground ,blue-alt-other))) -;;;;; mu4e - `(mu4e-attach-number-face ((,class :inherit bold :foreground ,cyan-alt))) - `(mu4e-cited-1-face ((,class :foreground ,blue-alt))) - `(mu4e-cited-2-face ((,class :foreground ,red-alt))) - `(mu4e-cited-3-face ((,class :foreground ,green-alt))) - `(mu4e-cited-4-face ((,class :foreground ,magenta-alt))) - `(mu4e-cited-5-face ((,class :foreground ,yellow-alt))) - `(mu4e-cited-6-face ((,class :foreground ,cyan-alt))) - `(mu4e-cited-7-face ((,class :foreground ,magenta))) - `(mu4e-compose-header-face ((,class :inherit mu4e-compose-separator-face))) - `(mu4e-compose-separator-face ((,class :inherit modus-theme-intense-neutral))) - `(mu4e-contact-face ((,class :inherit bold :foreground ,cyan-alt-other))) - `(mu4e-context-face ((,class :foreground ,blue-active))) - `(mu4e-draft-face ((,class :foreground ,magenta-alt))) - `(mu4e-flagged-face ((,class :foreground ,red-alt))) - `(mu4e-footer-face ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(mu4e-forwarded-face ((,class :foreground ,magenta-alt-other))) - `(mu4e-header-face ((,class :foreground ,fg-alt))) - `(mu4e-header-highlight-face ((,class :inherit modus-theme-hl-line))) - `(mu4e-header-key-face ((,class :foreground ,cyan))) - `(mu4e-header-marks-face ((,class :inherit bold :foreground ,magenta-alt))) - `(mu4e-header-title-face ((,class :foreground ,fg-special-mild))) - `(mu4e-header-value-face ((,class :inherit bold :foreground ,magenta-alt-other))) - `(mu4e-highlight-face ((,class :inherit bold :foreground ,blue-alt-other))) - `(mu4e-link-face ((,class :inherit link))) - `(mu4e-modeline-face ((,class :foreground ,magenta-active))) - `(mu4e-moved-face ((,class :foreground ,yellow :slant ,modus-theme-slant))) - `(mu4e-ok-face ((,class :inherit bold :foreground ,green))) - `(mu4e-region-code ((,class :inherit modus-theme-special-calm))) - `(mu4e-replied-face ((,class :foreground ,blue-faint))) - `(mu4e-special-header-value-face ((,class :inherit bold :foreground ,blue-alt-other))) - `(mu4e-system-face ((,class :foreground ,fg-mark-del :slant ,modus-theme-slant))) - `(mu4e-title-face ((,class :foreground ,fg-main))) - `(mu4e-trashed-face ((,class :foreground ,red))) - `(mu4e-unread-face ((,class :inherit bold :foreground ,fg-main))) - `(mu4e-url-number-face ((,class :inherit bold :foreground ,cyan-alt-other))) - `(mu4e-view-body-face ((,class :foreground ,fg-main))) - `(mu4e-warning-face ((,class :inherit warning))) -;;;;; mu4e-conversation - `(mu4e-conversation-header ((,class :inherit modus-theme-special-cold))) - `(mu4e-conversation-sender-1 ((,class :foreground ,fg-special-warm))) - `(mu4e-conversation-sender-2 ((,class :foreground ,fg-special-cold))) - `(mu4e-conversation-sender-3 ((,class :foreground ,fg-special-mild))) - `(mu4e-conversation-sender-4 ((,class :foreground ,fg-alt))) - `(mu4e-conversation-sender-5 ((,class :foreground ,yellow-refine-fg))) - `(mu4e-conversation-sender-6 ((,class :foreground ,cyan-refine-fg))) - `(mu4e-conversation-sender-7 ((,class :foreground ,green-refine-fg))) - `(mu4e-conversation-sender-8 ((,class :foreground ,blue-refine-fg))) - `(mu4e-conversation-sender-me ((,class :foreground ,fg-main))) - `(mu4e-conversation-unread ((,class :inherit bold))) -;;;;; multiple-cursors - `(mc/cursor-bar-face ((,class :height 1 :background ,fg-main))) - `(mc/cursor-face ((,class :inverse-video t))) - `(mc/region-face ((,class :inherit region))) -;;;;; neotree - `(neo-banner-face ((,class :foreground ,magenta))) - `(neo-button-face ((,class :inherit button))) - `(neo-dir-link-face ((,class :inherit bold :foreground ,blue))) - `(neo-expand-btn-face ((,class :foreground ,cyan))) - `(neo-file-link-face ((,class :foreground ,fg-main))) - `(neo-header-face ((,class :inherit bold :foreground ,fg-main))) - `(neo-root-dir-face ((,class :inherit bold :foreground ,cyan-alt))) - `(neo-vc-added-face ((,class :foreground ,green))) - `(neo-vc-conflict-face ((,class :inherit bold :foreground ,red))) - `(neo-vc-default-face ((,class :foreground ,fg-main))) - `(neo-vc-edited-face ((,class :foreground ,yellow))) - `(neo-vc-ignored-face ((,class :foreground ,fg-inactive))) - `(neo-vc-missing-face ((,class :foreground ,red-alt))) - `(neo-vc-needs-merge-face ((,class :foreground ,magenta-alt))) - `(neo-vc-needs-update-face ((,class :underline t))) - `(neo-vc-removed-face ((,class :strike-through t))) - `(neo-vc-unlocked-changes-face ((,class :inherit modus-theme-refine-blue))) - `(neo-vc-up-to-date-face ((,class :foreground ,fg-alt))) - `(neo-vc-user-face ((,class :foreground ,magenta))) -;;;;; no-emoji - `(no-emoji ((,class :foreground ,cyan))) -;;;;; notmuch - `(notmuch-crypto-decryption ((,class :inherit modus-theme-refine-magenta))) - `(notmuch-crypto-part-header ((,class :foreground ,magenta-alt-other))) - `(notmuch-crypto-signature-bad ((,class :inherit modus-theme-intense-red))) - `(notmuch-crypto-signature-good ((,class :inherit modus-theme-refine-green))) - `(notmuch-crypto-signature-good-key ((,class :inherit modus-theme-refine-yellow))) - `(notmuch-crypto-signature-unknown ((,class :inherit modus-theme-refine-red))) - `(notmuch-hello-logo-background ((,class :background ,bg-main))) - `(notmuch-message-summary-face ((,class :inherit modus-theme-nuanced-cyan))) - `(notmuch-search-flagged-face ((,class :foreground ,red-alt))) - `(notmuch-search-matching-authors ((,class :foreground ,fg-main))) - `(notmuch-search-non-matching-authors ((,class :foreground ,fg-alt))) - `(notmuch-search-unread-face ((,class :inherit bold))) - `(notmuch-tag-added - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,green :style wave)) - (,class :foreground ,green :underline t))) - `(notmuch-tag-deleted - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,red :style wave)) - (,class :foreground ,red :underline t))) - `(notmuch-tag-face ((,class :inherit bold :foreground ,blue-alt))) - `(notmuch-tag-flagged ((,class :foreground ,red-alt))) - `(notmuch-tag-unread ((,class :foreground ,magenta-alt))) - `(notmuch-tree-match-author-face ((,class :foreground ,fg-special-cold))) - `(notmuch-tree-match-face ((,class :foreground ,fg-main))) - `(notmuch-tree-match-tag-face ((,class :inherit bold :foreground ,blue-alt))) - `(notmuch-tree-no-match-face ((,class :foreground ,fg-alt))) - `(notmuch-wash-cited-text ((,class :foreground ,cyan))) - `(notmuch-wash-toggle-button ((,class :background ,bg-alt :foreground ,fg-alt))) -;;;;; num3-mode - `(num3-face-even ((,class :inherit bold :background ,bg-alt))) -;;;;; nxml-mode - `(nxml-attribute-colon ((,class :foreground ,fg-main))) - `(nxml-attribute-local-name ((,class ,@(modus-operandi-theme-syntax-foreground - cyan-alt cyan-alt-faint)))) - `(nxml-attribute-prefix ((,class ,@(modus-operandi-theme-syntax-foreground - cyan-alt-other cyan-alt-other-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(nxml-attribute-value ((,class ,@(modus-operandi-theme-syntax-foreground - blue blue-faint)))) - `(nxml-cdata-section-CDATA ((,class ,@(modus-operandi-theme-syntax-foreground - red-alt red-alt-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(nxml-cdata-section-delimiter ((,class ,@(modus-operandi-theme-syntax-foreground - red-alt red-alt-faint)))) - `(nxml-char-ref-delimiter ((,class ,@(modus-operandi-theme-syntax-foreground - green-alt-other green-alt-other-faint)))) - `(nxml-char-ref-number ((,class ,@(modus-operandi-theme-syntax-foreground - green-alt-other green-alt-other-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(nxml-delimited-data ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(nxml-delimiter ((,class :foreground ,fg-dim))) - `(nxml-element-colon ((,class :foreground ,fg-main))) - `(nxml-element-local-name ((,class ,@(modus-operandi-theme-syntax-foreground - magenta magenta-faint)))) - `(nxml-element-prefix ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(nxml-entity-ref-delimiter ((,class ,@(modus-operandi-theme-syntax-foreground - green-alt-other green-alt-other-faint)))) - `(nxml-entity-ref-name ((,class ,@(modus-operandi-theme-syntax-foreground - green-alt-other green-alt-other-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(nxml-glyph ((,class :inherit modus-theme-intense-neutral))) - `(nxml-hash ((,class ,@(modus-operandi-theme-syntax-foreground - blue-alt blue-alt-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(nxml-heading ((,class :inherit bold))) - `(nxml-name ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(nxml-namespace-attribute-colon ((,class :foreground ,fg-main))) - `(nxml-namespace-attribute-prefix ((,class ,@(modus-operandi-theme-syntax-foreground - cyan cyan-faint)))) - `(nxml-processing-instruction-target ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt-other magenta-alt-other-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(nxml-prolog-keyword ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt-other magenta-alt-other-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(nxml-ref ((,class ,@(modus-operandi-theme-syntax-foreground - green-alt-other green-alt-other-faint) - ,@(modus-operandi-theme-bold-weight)))) -;;;;; objed - `(objed-hl ((,class :background ,(if modus-operandi-theme-intense-hl-line - bg-hl-alt-intense bg-hl-alt)))) - `(objed-mark ((,class :background ,bg-active))) - `(objed-mode-line ((,class :foreground ,cyan-active))) -;;;;; orderless - `(orderless-match-face-0 ((,class :inherit bold - ,@(modus-operandi-theme-standard-completions - blue-alt-other blue-nuanced-bg - blue-refine-bg blue-refine-fg)))) - `(orderless-match-face-1 ((,class :inherit bold - ,@(modus-operandi-theme-standard-completions - magenta-alt magenta-nuanced-bg - magenta-refine-bg magenta-refine-fg)))) - `(orderless-match-face-2 ((,class :inherit bold - ,@(modus-operandi-theme-standard-completions - green green-nuanced-bg - green-refine-bg green-refine-fg)))) - `(orderless-match-face-3 ((,class :inherit bold - ,@(modus-operandi-theme-standard-completions - yellow yellow-nuanced-bg - yellow-refine-bg yellow-refine-fg)))) -;;;;; org - `(org-agenda-calendar-event ((,class :foreground ,fg-main))) - `(org-agenda-calendar-sexp ((,class :foreground ,cyan-alt))) - `(org-agenda-clocking ((,class :inherit modus-theme-special-cold - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(org-agenda-column-dateline ((,class :background ,bg-alt))) - `(org-agenda-current-time ((,class :inherit bold :foreground ,blue-alt-other))) - `(org-agenda-date ((,class :foreground ,cyan))) - `(org-agenda-date-today ((,class :inherit bold :foreground ,fg-main :underline t))) - `(org-agenda-date-weekend ((,class :foreground ,cyan-alt-other))) - `(org-agenda-diary ((,class :foreground ,fg-main))) - `(org-agenda-dimmed-todo-face ((,class :inherit bold :foreground ,fg-alt))) - `(org-agenda-done ((,class :foreground ,green-alt))) - `(org-agenda-filter-category ((,class :inherit bold :foreground ,magenta-active))) - `(org-agenda-filter-effort ((,class :inherit bold :foreground ,magenta-active))) - `(org-agenda-filter-regexp ((,class :inherit bold :foreground ,magenta-active))) - `(org-agenda-filter-tags ((,class :inherit bold :foreground ,magenta-active))) - `(org-agenda-restriction-lock ((,class :background ,bg-dim :foreground ,fg-dim))) - `(org-agenda-structure ((,class :foreground ,blue-alt))) - `(org-archived ((,class :background ,bg-alt :foreground ,fg-alt))) - `(org-block ((,class ,@(modus-operandi-theme-mixed-fonts) - ,@(modus-operandi-theme-org-block bg-dim) - :foreground ,fg-main))) - `(org-block-begin-line ((,class ,@(modus-operandi-theme-mixed-fonts) - ,@(modus-operandi-theme-org-block-delim - bg-dim fg-special-cold - bg-alt fg-special-mild)))) - `(org-block-end-line ((,class :inherit org-block-begin-line))) - `(org-checkbox ((,class :box (:line-width 1 :color ,bg-active) - :background ,bg-inactive :foreground ,fg-active))) - `(org-checkbox-statistics-done ((,class :inherit org-done))) - `(org-checkbox-statistics-todo ((,class :inherit org-todo))) - `(org-clock-overlay ((,class :inherit modus-theme-special-cold))) - `(org-code ((,class ,@(modus-operandi-theme-mixed-fonts) :foreground ,magenta))) - `(org-column ((,class :background ,bg-alt))) - `(org-column-title ((,class :inherit bold :underline t :background ,bg-alt))) - `(org-date ((,class :inherit (button fixed-pitch) :foreground ,cyan-alt-other))) - `(org-date-selected ((,class :inherit bold :foreground ,blue-alt :inverse-video t))) - `(org-document-info ((,class :foreground ,fg-special-cold))) - `(org-document-info-keyword ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,fg-alt))) - `(org-document-title ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,fg-special-cold - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-5)))) - `(org-done ((,class :box ,bg-region :background ,bg-dim :foreground ,green))) - `(org-drawer ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,cyan))) - `(org-ellipsis ((,class :foreground nil))) ; inherits from the heading's colour - `(org-footnote ((,class :inherit button :foreground ,blue-alt))) - `(org-formula ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,red-alt))) - `(org-habit-alert-face ((,class :inherit modus-theme-intense-yellow))) - `(org-habit-alert-future-face ((,class :inherit modus-theme-refine-yellow))) - `(org-habit-clear-face ((,class :inherit modus-theme-intense-magenta))) - `(org-habit-clear-future-face ((,class :inherit modus-theme-refine-magenta))) - `(org-habit-overdue-face ((,class :inherit modus-theme-intense-red))) - `(org-habit-overdue-future-face ((,class :inherit modus-theme-refine-red))) - `(org-habit-ready-face ((,class :inherit modus-theme-intense-blue))) - `(org-habit-ready-future-face ((,class :inherit modus-theme-refine-blue))) - `(org-headline-done ((,class :inherit ,modus-theme-variable-pitch :foreground ,green-nuanced))) - `(org-headline-todo ((,class :inherit ,modus-theme-variable-pitch :foreground ,red-nuanced))) - `(org-hide ((,class :foreground ,bg-main))) - `(org-indent ((,class :inherit (fixed-pitch org-hide)))) - `(org-latex-and-related ((,class :foreground ,magenta-refine-fg))) - `(org-level-1 ((,class :inherit modus-theme-heading-1))) - `(org-level-2 ((,class :inherit modus-theme-heading-2))) - `(org-level-3 ((,class :inherit modus-theme-heading-3))) - `(org-level-4 ((,class :inherit modus-theme-heading-4))) - `(org-level-5 ((,class :inherit modus-theme-heading-5))) - `(org-level-6 ((,class :inherit modus-theme-heading-6))) - `(org-level-7 ((,class :inherit modus-theme-heading-7))) - `(org-level-8 ((,class :inherit modus-theme-heading-8))) - `(org-link ((,class :inherit link))) - `(org-list-dt ((,class :inherit bold))) - `(org-macro ((,class :background ,blue-nuanced-bg :foreground ,magenta-alt-other))) - `(org-meta-line ((,class ,@(modus-operandi-theme-mixed-fonts) :foreground ,fg-alt))) - `(org-mode-line-clock ((,class :foreground ,fg-main))) - `(org-mode-line-clock-overrun ((,class :inherit modus-theme-active-red))) - `(org-priority ((,class :box ,bg-region :background ,bg-dim :foreground ,magenta))) - `(org-property-value ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,cyan-alt-other))) - `(org-quote ((,class ,@(modus-operandi-theme-org-block bg-dim) - :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(org-scheduled ((,class :foreground ,fg-special-warm))) - `(org-scheduled-previously ((,class :foreground ,yellow-alt-other))) - `(org-scheduled-today ((,class :foreground ,magenta-alt-other))) - `(org-sexp-date ((,class :inherit org-date))) - `(org-special-keyword ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,blue-nuanced))) - `(org-table ((,class ,@(modus-operandi-theme-mixed-fonts) - :foreground ,fg-special-cold))) - `(org-table-header ((,class :inherit (fixed-pitch modus-theme-intense-neutral)))) - `(org-tag ((,class :foreground ,magenta-nuanced))) - `(org-tag-group ((,class :inherit bold :foreground ,cyan-nuanced))) - `(org-target ((,class :underline t))) - `(org-time-grid ((,class :foreground ,fg-unfocused))) - `(org-todo ((,class :box ,bg-region :background ,bg-dim :foreground ,red-alt))) - `(org-upcoming-deadline ((,class :foreground ,red-alt-other))) - `(org-upcoming-distant-deadline ((,class :foreground ,red-nuanced))) - `(org-verbatim ((,class ,@(modus-operandi-theme-mixed-fonts) - :background ,bg-alt :foreground ,fg-special-calm))) - `(org-verse ((,class :inherit org-quote))) - `(org-warning ((,class :inherit bold :foreground ,red-alt-other))) -;;;;; org-journal - `(org-journal-calendar-entry-face ((,class :foreground ,yellow-alt-other :slant ,modus-theme-slant))) - `(org-journal-calendar-scheduled-face ((,class :foreground ,red-alt-other :slant ,modus-theme-slant))) - `(org-journal-highlight ((,class :foreground ,magenta-alt))) -;;;;; org-noter - `(org-noter-no-notes-exist-face ((,class :inherit bold :foreground ,red-active))) - `(org-noter-notes-exist-face ((,class :inherit bold :foreground ,green-active))) -;;;;; org-pomodoro - `(org-pomodoro-mode-line ((,class :foreground ,red-active))) - `(org-pomodoro-mode-line-break ((,class :foreground ,cyan-active))) - `(org-pomodoro-mode-line-overtime ((,class :inherit bold :foreground ,red-active))) -;;;;; org-recur - `(org-recur ((,class :foreground ,magenta-active))) -;;;;; org-roam - `(org-roam-link ((,class :inherit button :foreground ,green))) - `(org-roam-link-current ((,class :inherit button :foreground ,green-alt))) - `(org-roam-link-invalid ((,class :inherit button :foreground ,red))) - `(org-roam-link-shielded ((,class :inherit button :foreground ,yellow))) - `(org-roam-tag ((,class :foreground ,fg-alt :slant italic))) -;;;;; org-superstar - `(org-superstar-item ((,class :foreground ,fg-main))) - `(org-superstar-leading ((,class :foreground ,fg-whitespace))) -;;;;; org-table-sticky-header - `(org-table-sticky-header-face ((,class :inherit modus-theme-intense-neutral))) -;;;;; org-treescope - `(org-treescope-faces--markerinternal-midday ((,class :inherit modus-theme-intense-blue))) - `(org-treescope-faces--markerinternal-range ((,class :inherit modus-theme-special-mild))) -;;;;; origami - `(origami-fold-header-face ((,class :background ,bg-dim :foreground ,fg-dim :box t))) - `(origami-fold-replacement-face ((,class :background ,bg-alt :foreground ,fg-alt))) -;;;;; outline-mode - `(outline-1 ((,class :inherit modus-theme-heading-1))) - `(outline-2 ((,class :inherit modus-theme-heading-2))) - `(outline-3 ((,class :inherit modus-theme-heading-3))) - `(outline-4 ((,class :inherit modus-theme-heading-4))) - `(outline-5 ((,class :inherit modus-theme-heading-5))) - `(outline-6 ((,class :inherit modus-theme-heading-6))) - `(outline-7 ((,class :inherit modus-theme-heading-7))) - `(outline-8 ((,class :inherit modus-theme-heading-8))) -;;;;; outline-minor-faces - `(outline-minor-0 ((,class nil))) -;;;;; package (M-x list-packages) - `(package-description ((,class :foreground ,fg-special-cold))) - `(package-help-section-name ((,class :inherit bold :foreground ,magenta-alt-other))) - `(package-name ((,class :inherit link))) - `(package-status-avail-obso ((,class :inherit bold :foreground ,red))) - `(package-status-available ((,class :foreground ,fg-special-mild))) - `(package-status-built-in ((,class :foreground ,magenta))) - `(package-status-dependency ((,class :foreground ,magenta-alt-other))) - `(package-status-disabled ((,class :inherit modus-theme-subtle-red))) - `(package-status-external ((,class :foreground ,cyan-alt-other))) - `(package-status-held ((,class :foreground ,yellow-alt))) - `(package-status-incompat ((,class :inherit bold :foreground ,yellow))) - `(package-status-installed ((,class :foreground ,fg-special-warm))) - `(package-status-new ((,class :inherit bold :foreground ,green))) - `(package-status-unsigned ((,class :inherit bold :foreground ,red-alt))) -;;;;; page-break-lines - `(page-break-lines ((,class :inherit default :foreground ,fg-window-divider-outer))) -;;;;; paradox - `(paradox-archive-face ((,class :foreground ,fg-special-mild))) - `(paradox-comment-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(paradox-commit-tag-face ((,class :inherit modus-theme-refine-magenta :box t))) - `(paradox-description-face ((,class :foreground ,fg-special-cold))) - `(paradox-description-face-multiline ((,class :foreground ,fg-special-cold))) - `(paradox-download-face ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,blue-alt-other))) - `(paradox-highlight-face ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,cyan-alt-other))) - `(paradox-homepage-button-face ((,class :foreground ,magenta-alt-other :underline t))) - `(paradox-mode-line-face ((,class :inherit bold :foreground ,cyan-active))) - `(paradox-name-face ((,class :foreground ,blue :underline t))) - `(paradox-star-face ((,class :foreground ,magenta))) - `(paradox-starred-face ((,class :foreground ,magenta-alt))) -;;;;; paren-face - `(parenthesis ((,class :foreground ,fg-unfocused))) -;;;;; parrot - `(parrot-rotate-rotation-highlight-face ((,class :inherit modus-theme-refine-magenta))) -;;;;; pass - `(pass-mode-directory-face ((,class :inherit bold :foreground ,fg-special-cold))) - `(pass-mode-entry-face ((,class :background ,bg-main :foreground ,fg-main))) - `(pass-mode-header-face ((,class :foreground ,fg-special-warm))) -;;;;; persp-mode - `(persp-face-lighter-buffer-not-in-persp ((,class :inherit modus-theme-intense-red))) - `(persp-face-lighter-default ((,class :inherit bold :foreground ,blue-active))) - `(persp-face-lighter-nil-persp ((,class :inherit bold :foreground ,fg-active))) -;;;;; perspective - `(persp-selected-face ((,class :inherit bold :foreground ,blue-active))) -;;;;; phi-grep - `(phi-grep-heading-face ((,class :inherit bold :foreground ,red-alt - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-4)))) - `(phi-grep-line-number-face ((,class :foreground ,fg-special-warm))) - `(phi-grep-match-face ((,class :inherit modus-theme-special-calm))) - `(phi-grep-modified-face ((,class :inherit modus-theme-refine-yellow))) - `(phi-grep-overlay-face ((,class :inherit modus-theme-refine-blue))) -;;;;; phi-search - `(phi-replace-preview-face ((,class :inherit modus-theme-intense-magenta))) - `(phi-search-failpart-face ((,class :inherit modus-theme-refine-red))) - `(phi-search-match-face ((,class :inherit modus-theme-refine-cyan))) - `(phi-search-selection-face ((,class :inherit (modus-theme-intense-green bold)))) -;;;;; pkgbuild-mode - `(pkgbuild-error-face ((,class :underline ,fg-lang-error))) -;;;;; pomidor - `(pomidor-break-face ((,class :foreground ,blue-alt-other))) - `(pomidor-overwork-face ((,class :foreground ,red-alt-other))) - `(pomidor-skip-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(pomidor-work-face ((,class :foreground ,green-alt-other))) -;;;;; powerline - `(powerline-active0 ((,class :background ,bg-main :foreground ,blue-faint :inverse-video t))) - `(powerline-active1 ((,class :background ,blue-nuanced-bg :foreground ,blue-nuanced))) - `(powerline-active2 ((,class :background ,bg-active :foreground ,fg-active))) - `(powerline-inactive0 ((,class :background ,bg-special-cold :foreground ,fg-special-cold))) - `(powerline-inactive1 ((,class :background ,bg-dim :foreground ,fg-inactive))) - `(powerline-inactive2 ((,class :background ,bg-inactive :foreground ,fg-inactive))) -;;;;; powerline-evil - `(powerline-evil-base-face ((,class :background ,fg-main :foreground ,bg-main))) - `(powerline-evil-emacs-face ((,class :inherit modus-theme-active-magenta))) - `(powerline-evil-insert-face ((,class :inherit modus-theme-active-green))) - `(powerline-evil-motion-face ((,class :inherit modus-theme-active-blue))) - `(powerline-evil-normal-face ((,class :background ,fg-alt :foreground ,bg-main))) - `(powerline-evil-operator-face ((,class :inherit modus-theme-active-yellow))) - `(powerline-evil-replace-face ((,class :inherit modus-theme-active-red))) - `(powerline-evil-visual-face ((,class :inherit modus-theme-active-cyan))) -;;;;; proced - `(proced-mark ((,class :inherit modus-theme-mark-symbol))) - `(proced-marked ((,class :inherit modus-theme-mark-alt))) - `(proced-sort-header ((,class :inherit bold :foreground ,fg-special-calm :underline t))) -;;;;; prodigy - `(prodigy-green-face ((,class :foreground ,green))) - `(prodigy-red-face ((,class :foreground ,red))) - `(prodigy-yellow-face ((,class :foreground ,yellow))) -;;;;; racket-mode - `(racket-debug-break-face ((,class :inherit modus-theme-intense-red))) - `(racket-debug-locals-face ((,class :box (:line-width -1 :color nil) - :foreground ,green-alt-other))) - `(racket-debug-result-face ((,class :inherit bold :box (:line-width -1 :color nil) - :foreground ,green))) - `(racket-here-string-face ((,class :foreground ,blue-alt))) - `(racket-keyword-argument-face ((,class :foreground ,red-alt))) - `(racket-logger-config-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(racket-logger-debug-face ((,class :foreground ,blue-alt-other))) - `(racket-logger-info-face ((,class :foreground ,fg-lang-note))) - `(racket-logger-topic-face ((,class :foreground ,magenta :slant ,modus-theme-slant))) - `(racket-selfeval-face ((,class :foreground ,green-alt))) - `(racket-xp-error-face - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-error :style wave)) - (,class :foreground ,fg-lang-error :underline t))) -;;;;; rainbow-blocks - `(rainbow-blocks-depth-1-face ((,class :foreground ,magenta-alt-other))) - `(rainbow-blocks-depth-2-face ((,class :foreground ,blue))) - `(rainbow-blocks-depth-3-face ((,class :foreground ,magenta-alt))) - `(rainbow-blocks-depth-4-face ((,class :foreground ,green))) - `(rainbow-blocks-depth-5-face ((,class :foreground ,magenta))) - `(rainbow-blocks-depth-6-face ((,class :foreground ,cyan))) - `(rainbow-blocks-depth-7-face ((,class :foreground ,yellow))) - `(rainbow-blocks-depth-8-face ((,class :foreground ,cyan-alt))) - `(rainbow-blocks-depth-9-face ((,class :foreground ,red-alt))) - `(rainbow-blocks-unmatched-face ((,class :foreground ,red))) -;;;;; rainbow-identifiers - `(rainbow-identifiers-identifier-1 ((,class :foreground ,green-alt-other))) - `(rainbow-identifiers-identifier-2 ((,class :foreground ,magenta-alt-other))) - `(rainbow-identifiers-identifier-3 ((,class :foreground ,cyan-alt-other))) - `(rainbow-identifiers-identifier-4 ((,class :foreground ,yellow-alt-other))) - `(rainbow-identifiers-identifier-5 ((,class :foreground ,blue-alt-other))) - `(rainbow-identifiers-identifier-6 ((,class :foreground ,green-alt))) - `(rainbow-identifiers-identifier-7 ((,class :foreground ,magenta-alt))) - `(rainbow-identifiers-identifier-8 ((,class :foreground ,cyan-alt))) - `(rainbow-identifiers-identifier-9 ((,class :foreground ,yellow-alt))) - `(rainbow-identifiers-identifier-10 ((,class :foreground ,green))) - `(rainbow-identifiers-identifier-11 ((,class :foreground ,magenta))) - `(rainbow-identifiers-identifier-12 ((,class :foreground ,cyan))) - `(rainbow-identifiers-identifier-13 ((,class :foreground ,yellow))) - `(rainbow-identifiers-identifier-14 ((,class :foreground ,blue-alt))) - `(rainbow-identifiers-identifier-15 ((,class :foreground ,red-alt))) -;;;;; rainbow-delimiters - `(rainbow-delimiters-base-face-error ((,class :foreground ,red))) - `(rainbow-delimiters-base-face ((,class :foreground ,fg-main))) - `(rainbow-delimiters-depth-1-face ((,class :foreground ,green-alt-other))) - `(rainbow-delimiters-depth-2-face ((,class :foreground ,magenta-alt-other))) - `(rainbow-delimiters-depth-3-face ((,class :foreground ,cyan-alt-other))) - `(rainbow-delimiters-depth-4-face ((,class :foreground ,yellow-alt-other))) - `(rainbow-delimiters-depth-5-face ((,class :foreground ,blue-alt-other))) - `(rainbow-delimiters-depth-6-face ((,class :foreground ,green-alt))) - `(rainbow-delimiters-depth-7-face ((,class :foreground ,magenta-alt))) - `(rainbow-delimiters-depth-8-face ((,class :foreground ,cyan-alt))) - `(rainbow-delimiters-depth-9-face ((,class :foreground ,yellow-alt))) - `(rainbow-delimiters-mismatched-face ((,class :inherit bold :foreground ,red-alt))) - `(rainbow-delimiters-unmatched-face ((,class :inherit bold :foreground ,red))) -;;;;; rcirc - `(rcirc-bright-nick ((,class :inherit bold :foreground ,magenta-alt))) - `(rcirc-dim-nick ((,class :foreground ,fg-alt))) - `(rcirc-my-nick ((,class :inherit bold :foreground ,magenta))) - `(rcirc-nick-in-message ((,class :foreground ,magenta-alt-other))) - `(rcirc-nick-in-message-full-line ((,class :inherit bold :foreground ,fg-special-mild))) - `(rcirc-other-nick ((,class :inherit bold :foreground ,fg-special-cold))) - `(rcirc-prompt ((,class :inherit bold :foreground ,cyan-alt-other))) - `(rcirc-server ((,class :foreground ,fg-unfocused))) - `(rcirc-timestamp ((,class :foreground ,blue-nuanced))) - `(rcirc-url ((,class :foreground ,blue :underline t))) -;;;;; regexp-builder (re-builder) - `(reb-match-0 ((,class :inherit modus-theme-intense-blue))) - `(reb-match-1 ((,class :inherit modus-theme-intense-magenta))) - `(reb-match-2 ((,class :inherit modus-theme-intense-green))) - `(reb-match-3 ((,class :inherit modus-theme-intense-red))) - `(reb-regexp-grouping-backslash ((,class :inherit bold :foreground ,fg-escape-char-backslash))) - `(reb-regexp-grouping-construct ((,class :inherit bold :foreground ,fg-escape-char-construct))) -;;;;; rg (rg.el) - `(rg-column-number-face ((,class :foreground ,magenta-alt-other))) - `(rg-context-face ((,class :foreground ,fg-unfocused))) - `(rg-error-face ((,class :inherit bold :foreground ,red))) - `(rg-file-tag-face ((,class :foreground ,fg-special-cold))) - `(rg-filename-face ((,class :inherit bold :foreground ,fg-special-cold))) - `(rg-line-number-face ((,class :foreground ,fg-special-warm))) - `(rg-literal-face ((,class :foreground ,blue-alt))) - `(rg-match-face ((,class :inherit modus-theme-special-calm))) - `(rg-regexp-face ((,class :foreground ,magenta-active))) - `(rg-toggle-off-face ((,class :inherit bold :foreground ,fg-inactive))) - `(rg-toggle-on-face ((,class :inherit bold :foreground ,cyan-active))) - `(rg-warning-face ((,class :inherit bold :foreground ,yellow))) -;;;;; ripgrep - `(ripgrep-context-face ((,class :foreground ,fg-unfocused))) - `(ripgrep-error-face ((,class :inherit bold :foreground ,red))) - `(ripgrep-hit-face ((,class :foreground ,cyan))) - `(ripgrep-match-face ((,class :inherit modus-theme-special-calm))) -;;;;; rmail - `(rmail-header-name ((,class :foreground ,cyan-alt-other))) - `(rmail-highlight ((,class :inherit bold :foreground ,magenta-alt))) -;;;;; ruler-mode - `(ruler-mode-column-number ((,class :inherit (ruler-mode-default bold) :foreground ,fg-main))) - `(ruler-mode-comment-column ((,class :inherit ruler-mode-default :foreground ,red-active))) - `(ruler-mode-current-column ((,class :inherit ruler-mode-default :foreground ,cyan-active :box t))) - `(ruler-mode-default ((,class :background ,bg-inactive :foreground ,fg-inactive))) - `(ruler-mode-fill-column ((,class :inherit ruler-mode-default :foreground ,green-active))) - `(ruler-mode-fringes ((,class :inherit ruler-mode-default :foreground ,blue-active))) - `(ruler-mode-goal-column ((,class :inherit ruler-mode-default :foreground ,magenta-active))) - `(ruler-mode-margins ((,class :inherit ruler-mode-default :foreground ,bg-main))) - `(ruler-mode-pad ((,class :background ,bg-active :foreground ,fg-inactive))) - `(ruler-mode-tab-stop ((,class :inherit ruler-mode-default :foreground ,yellow-active))) -;;;;; sallet - `(sallet-buffer-compressed ((,class :foreground ,yellow-nuanced :slant italic))) - `(sallet-buffer-default-directory ((,class :foreground ,cyan-nuanced))) - `(sallet-buffer-directory ((,class :foreground ,blue-nuanced))) - `(sallet-buffer-help ((,class :foreground ,fg-special-cold))) - `(sallet-buffer-modified ((,class :foreground ,yellow-alt-other :slant italic))) - `(sallet-buffer-ordinary ((,class :foreground ,fg-main))) - `(sallet-buffer-read-only ((,class :foreground ,yellow-alt))) - `(sallet-buffer-size ((,class :foreground ,fg-special-calm))) - `(sallet-buffer-special ((,class :foreground ,magenta-alt-other))) - `(sallet-flx-match ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-cyan - 'modus-theme-refine-cyan - 'modus-theme-nuanced-cyan - cyan-alt-other)))) - `(sallet-recentf-buffer-name ((,class :foreground ,blue-nuanced))) - `(sallet-recentf-file-path ((,class :foreground ,fg-special-mild))) - `(sallet-regexp-match ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-magenta - 'modus-theme-refine-magenta - 'modus-theme-nuanced-magenta - magenta-alt-other)))) - `(sallet-source-header ((,class :inherit bold :foreground ,red-alt - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-4)))) - `(sallet-substring-match ((,class ,@(modus-operandi-theme-extra-completions - 'modus-theme-subtle-blue - 'modus-theme-refine-blue - 'modus-theme-nuanced-blue - blue-alt-other)))) -;;;;; selectrum - `(selectrum-current-candidate - ((,class :inherit bold :foreground ,fg-main :underline ,fg-main - :background ,@(pcase modus-operandi-theme-completions - ('opinionated (list bg-active)) - (_ (list bg-inactive)))))) - `(selectrum-primary-highlight ((,class :inherit bold - ,@(modus-operandi-theme-standard-completions - magenta-alt magenta-nuanced-bg - magenta-refine-bg magenta-refine-fg)))) - `(selectrum-secondary-highlight ((,class :inherit bold - ,@(modus-operandi-theme-standard-completions - cyan-alt-other cyan-nuanced-bg - cyan-refine-bg cyan-refine-fg)))) -;;;;; semantic - `(semantic-complete-inline-face ((,class :foreground ,fg-special-warm :underline t))) - `(semantic-decoration-on-private-members-face ((,class :inherit modus-theme-refine-cyan))) - `(semantic-decoration-on-protected-members-face ((,class :background ,bg-dim))) - `(semantic-highlight-edits-face ((,class :background ,bg-alt))) - `(semantic-highlight-func-current-tag-face ((,class :background ,bg-alt))) - `(semantic-idle-symbol-highlight ((,class :inherit modus-theme-special-mild))) - `(semantic-tag-boundary-face ((,class :overline ,blue-intense))) - `(semantic-unmatched-syntax-face ((,class :underline ,fg-lang-error))) -;;;;; sesman - `(sesman-browser-button-face ((,class :foreground ,blue-alt-other :underline t))) - `(sesman-browser-highligh-face ((,class :inherit modus-theme-subtle-blue))) - `(sesman-buffer-face ((,class :foreground ,magenta))) - `(sesman-directory-face ((,class :inherit bold :foreground ,blue))) - `(sesman-project-face ((,class :inherit bold :foreground ,magenta-alt-other))) -;;;;; shell-script-mode - `(sh-heredoc ((,class :foreground ,blue-alt))) - `(sh-quoted-exec ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,magenta-alt))) -;;;;; show-paren-mode - `(show-paren-match ((,class ,@(modus-operandi-theme-paren bg-paren-match - bg-paren-match-intense) - :foreground ,fg-main))) - `(show-paren-match-expression ((,class :inherit modus-theme-special-calm))) - `(show-paren-mismatch ((,class :inherit modus-theme-intense-red))) -;;;;; side-notes - `(side-notes ((,class :background ,bg-dim :foreground ,fg-dim))) -;;;;; skewer-mode - `(skewer-error-face ((,class :foreground ,red :underline t))) -;;;;; smart-mode-line - `(sml/charging ((,class :foreground ,green-active))) - `(sml/discharging ((,class :foreground ,red-active))) - `(sml/filename ((,class :inherit bold :foreground ,blue-active))) - `(sml/folder ((,class :foreground ,fg-active))) - `(sml/git ((,class :inherit bold :foreground ,green-active))) - `(sml/global ((,class :foreground ,fg-active))) - `(sml/line-number ((,class :inherit sml/global))) - `(sml/minor-modes ((,class :inherit sml/global))) - `(sml/modes ((,class :inherit bold :foreground ,fg-active))) - `(sml/modified ((,class :inherit bold :foreground ,magenta-active))) - `(sml/mule-info ((,class :inherit sml/global))) - `(sml/name-filling ((,class :foreground ,yellow-active))) - `(sml/not-modified ((,class :inherit sml/global))) - `(sml/numbers-separator ((,class :inherit sml/global))) - `(sml/outside-modified ((,class :inherit modus-theme-intense-red))) - `(sml/position-percentage ((,class :inherit sml/global))) - `(sml/prefix ((,class :foreground ,green-active))) - `(sml/process ((,class :inherit sml/prefix))) - `(sml/projectile ((,class :inherit sml/git))) - `(sml/read-only ((,class :inherit bold :foreground ,cyan-active))) - `(sml/remote ((,class :inherit sml/global))) - `(sml/sudo ((,class :inherit modus-theme-subtle-red))) - `(sml/time ((,class :inherit sml/global))) - `(sml/vc ((,class :inherit sml/git))) - `(sml/vc-edited ((,class :inherit bold :foreground ,yellow-active))) -;;;;; smartparens - `(sp-pair-overlay-face ((,class :inherit modus-theme-special-warm))) - `(sp-show-pair-enclosing ((,class :inherit modus-theme-special-mild))) - `(sp-show-pair-match-face ((,class ,@(modus-operandi-theme-paren bg-paren-match - bg-paren-match-intense) - :foreground ,fg-main))) - `(sp-show-pair-mismatch-face ((,class :inherit modus-theme-intense-red))) - `(sp-wrap-overlay-closing-pair ((,class :inherit sp-pair-overlay-face))) - `(sp-wrap-overlay-face ((,class :inherit sp-pair-overlay-face))) - `(sp-wrap-overlay-opening-pair ((,class :inherit sp-pair-overlay-face))) - `(sp-wrap-tag-overlay-face ((,class :inherit sp-pair-overlay-face))) -;;;;; smerge - `(smerge-base ((,class :inherit modus-theme-diff-changed))) - `(smerge-lower ((,class :inherit modus-theme-diff-added))) - `(smerge-markers ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-2))) - `(smerge-refined-added ((,class :inherit modus-theme-diff-refine-added))) - `(smerge-refined-changed ((,class))) - `(smerge-refined-removed ((,class :inherit modus-theme-diff-refine-removed))) - `(smerge-upper ((,class :inherit modus-theme-diff-removed))) -;;;;; spaceline - `(spaceline-evil-emacs ((,class :inherit modus-theme-active-magenta))) - `(spaceline-evil-insert ((,class :inherit modus-theme-active-green))) - `(spaceline-evil-motion ((,class :inherit modus-theme-active-blue))) - `(spaceline-evil-normal ((,class :background ,fg-alt :foreground ,bg-alt))) - `(spaceline-evil-replace ((,class :inherit modus-theme-active-red))) - `(spaceline-evil-visual ((,class :inherit modus-theme-active-cyan))) - `(spaceline-flycheck-error ((,class :foreground ,red-active))) - `(spaceline-flycheck-info ((,class :foreground ,cyan-active))) - `(spaceline-flycheck-warning ((,class :foreground ,yellow-active))) - `(spaceline-highlight-face ((,class :inherit modus-theme-fringe-blue))) - `(spaceline-modified ((,class :inherit modus-theme-fringe-magenta))) - `(spaceline-python-venv ((,class :foreground ,magenta-active))) - `(spaceline-read-only ((,class :inherit modus-theme-fringe-red))) - `(spaceline-unmodified ((,class :inherit modus-theme-fringe-cyan))) -;;;;; speedbar - `(speedbar-button-face ((,class :inherit link))) - `(speedbar-directory-face ((,class :inherit bold :foreground ,blue))) - `(speedbar-file-face ((,class :foreground ,fg-main))) - `(speedbar-highlight-face ((,class :inherit modus-theme-subtle-blue))) - `(speedbar-selected-face ((,class :inherit bold :foreground ,cyan))) - `(speedbar-separator-face ((,class :inherit modus-theme-intense-neutral))) - `(speedbar-tag-face ((,class :foreground ,yellow-alt-other))) -;;;;; spell-fu - `(spell-fu-incorrect-face - ((,(append '((supports :underline (:style wave))) class) - :foreground ,fg-lang-error :underline (:style wave)) - (,class :foreground ,fg-lang-error :underline t))) -;;;;; stripes - `(stripes ((,class :inherit modus-theme-hl-line))) -;;;;; success - `(suggest-heading ((,class :inherit bold :foreground ,yellow-alt-other))) -;;;;; switch-window - `(switch-window-background ((,class :background ,bg-dim))) - `(switch-window-label ((,class :height 3.0 :foreground ,blue-intense))) -;;;;; swiper - `(swiper-background-match-face-1 ((,class :inherit modus-theme-subtle-neutral))) - `(swiper-background-match-face-2 ((,class :inherit modus-theme-subtle-cyan))) - `(swiper-background-match-face-3 ((,class :inherit modus-theme-subtle-magenta))) - `(swiper-background-match-face-4 ((,class :inherit modus-theme-subtle-green))) - `(swiper-line-face ((,class ,@(and (>= emacs-major-version 27) '(:extend t)) - :inherit modus-theme-special-cold))) - `(swiper-match-face-1 ((,class :inherit swiper-line-face))) - `(swiper-match-face-2 ((,class :inherit swiper-line-face))) - `(swiper-match-face-3 ((,class :inherit swiper-line-face))) - `(swiper-match-face-4 ((,class :inherit swiper-line-face))) -;;;;; swoop - `(swoop-face-header-format-line ((,class :inherit bold :foreground ,red-alt - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-3)))) - `(swoop-face-line-buffer-name ((,class :inherit bold :foreground ,blue-alt - ,@(modus-operandi-theme-scale modus-operandi-theme-scale-4)))) - `(swoop-face-line-number ((,class :foreground ,fg-special-warm))) - `(swoop-face-target-line ((,class :inherit modus-theme-intense-blue - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(swoop-face-target-words ((,class :inherit modus-theme-refine-cyan))) -;;;;; sx - `(sx-inbox-item-type ((,class :foreground ,magenta-alt-other))) - `(sx-inbox-item-type-unread ((,class :inherit (sx-inbox-item-type bold)))) - `(sx-question-list-answers ((,class :foreground ,green))) - `(sx-question-list-answers-accepted ((,class :box t :foreground ,green))) - `(sx-question-list-bounty ((,class :inherit bold :background ,bg-alt :foreground ,yellow))) - `(sx-question-list-date ((,class :foreground ,fg-special-cold))) - `(sx-question-list-favorite ((,class :inherit bold :foreground ,fg-special-warm))) - `(sx-question-list-parent ((,class :foreground ,fg-main))) - `(sx-question-list-read-question ((,class :foreground ,fg-alt))) - `(sx-question-list-score ((,class :foreground ,fg-special-mild))) - `(sx-question-list-score-upvoted ((,class :inherit (sx-question-list-score bold)))) - `(sx-question-list-unread-question ((,class :inherit bold :foreground ,fg-main))) - `(sx-question-mode-accepted ((,class :inherit bold :height 1.3 :foreground ,green))) - `(sx-question-mode-closed ((,class :inherit modus-theme-active-yellow :box (:line-width 2 :color nil)))) - `(sx-question-mode-closed-reason ((,class :box (:line-width 2 :color nil) :foreground ,fg-main))) - `(sx-question-mode-content-face ((,class :background ,bg-dim))) - `(sx-question-mode-date ((,class :foreground ,blue))) - `(sx-question-mode-header ((,class :inherit bold :foreground ,cyan))) - `(sx-question-mode-kbd-tag ((,class :inherit bold :height 0.9 :box (:line-width 3 :color ,fg-main :style released-button) :foreground ,fg-main))) - `(sx-question-mode-score ((,class :foreground ,fg-dim))) - `(sx-question-mode-score-downvoted ((,class :foreground ,yellow))) - `(sx-question-mode-score-upvoted ((,class :inherit bold :foreground ,magenta))) - `(sx-question-mode-title ((,class :inherit bold :foreground ,fg-main))) - `(sx-question-mode-title-comments ((,class :inherit bold :foreground ,fg-alt))) - `(sx-tag ((,class :foreground ,magenta-alt))) - `(sx-user-name ((,class :foreground ,blue-alt))) - `(sx-user-reputation ((,class :foreground ,fg-alt))) -;;;;; symbol-overlay - `(symbol-overlay-default-face ((,class :inherit modus-theme-special-warm))) - `(symbol-overlay-face-1 ((,class :inherit modus-theme-intense-blue))) - `(symbol-overlay-face-2 ((,class :inherit modus-theme-refine-magenta))) - `(symbol-overlay-face-3 ((,class :inherit modus-theme-intense-yellow))) - `(symbol-overlay-face-4 ((,class :inherit modus-theme-intense-magenta))) - `(symbol-overlay-face-5 ((,class :inherit modus-theme-intense-red))) - `(symbol-overlay-face-6 ((,class :inherit modus-theme-refine-red))) - `(symbol-overlay-face-7 ((,class :inherit modus-theme-intense-cyan))) - `(symbol-overlay-face-8 ((,class :inherit modus-theme-refine-cyan))) -;;;;; syslog-mode - `(syslog-debug ((,class :inherit bold :foreground ,cyan-alt-other))) - `(syslog-error ((,class :inherit bold :foreground ,red))) - `(syslog-file ((,class :inherit bold :foreground ,fg-special-cold))) - `(syslog-hide ((,class :background ,bg-main :foreground ,fg-main))) - `(syslog-hour ((,class :inherit bold :foreground ,magenta-alt-other))) - `(syslog-info ((,class :inherit bold :foreground ,blue-alt-other))) - `(syslog-ip ((,class :inherit bold :foreground ,fg-special-mild :underline t))) - `(syslog-su ((,class :inherit bold :foreground ,red-alt))) - `(syslog-warn ((,class :inherit bold :foreground ,yellow))) -;;;;; table (built-in table.el) - `(table-cell ((,class :background ,blue-nuanced-bg))) -;;;;; telephone-line - `(telephone-line-accent-active ((,class :background ,fg-inactive :foreground ,bg-inactive))) - `(telephone-line-accent-inactive ((,class :background ,bg-active :foreground ,fg-active))) - `(telephone-line-error ((,class :inherit bold :foreground ,red-active))) - `(telephone-line-evil ((,class :foreground ,fg-main))) - `(telephone-line-evil-emacs ((,class :inherit telephone-line-evil :background ,magenta-intense-bg))) - `(telephone-line-evil-insert ((,class :inherit telephone-line-evil :background ,green-intense-bg))) - `(telephone-line-evil-motion ((,class :inherit telephone-line-evil :background ,yellow-intense-bg))) - `(telephone-line-evil-normal ((,class :inherit telephone-line-evil :background ,bg-alt))) - `(telephone-line-evil-operator ((,class :inherit telephone-line-evil :background ,yellow-subtle-bg))) - `(telephone-line-evil-replace ((,class :inherit telephone-line-evil :background ,red-intense-bg))) - `(telephone-line-evil-visual ((,class :inherit telephone-line-evil :background ,cyan-intense-bg))) - `(telephone-line-projectile ((,class :foreground ,cyan-active))) - `(telephone-line-unimportant ((,class :foreground ,fg-inactive))) - `(telephone-line-warning ((,class :inherit bold :foreground ,yellow-active))) -;;;;; term - `(term ((,class :background ,bg-main :foreground ,fg-main))) - `(term-bold ((,class :inherit bold))) - `(term-color-blue ((,class :background ,blue :foreground ,blue))) - `(term-color-cyan ((,class :background ,cyan :foreground ,cyan))) - `(term-color-green ((,class :background ,green :foreground ,green))) - `(term-color-magenta ((,class :background ,magenta :foreground ,magenta))) - `(term-color-red ((,class :background ,red :foreground ,red))) - `(term-color-yellow ((,class :background ,yellow :foreground ,yellow))) - `(term-underline ((,class :underline t))) -;;;;; tomatinho - `(tomatinho-ok-face ((,class :foreground ,blue-intense))) - `(tomatinho-pause-face ((,class :foreground ,yellow-intense))) - `(tomatinho-reset-face ((,class :foreground ,fg-alt))) -;;;;; transient - `(transient-active-infix ((,class :inherit modus-theme-special-mild))) - `(transient-amaranth ((,class :inherit bold :foreground ,yellow))) - `(transient-argument ((,class :inherit bold :foreground ,red-alt))) - `(transient-blue ((,class :inherit bold :foreground ,blue))) - `(transient-disabled-suffix ((,class :inherit modus-theme-intense-red))) - `(transient-enabled-suffix ((,class :inherit modus-theme-intense-green))) - `(transient-heading ((,class :inherit bold :foreground ,fg-main))) - `(transient-inactive-argument ((,class :foreground ,fg-alt))) - `(transient-inactive-value ((,class :foreground ,fg-alt))) - `(transient-key ((,class :inherit bold :foreground ,blue))) - `(transient-mismatched-key ((,class :underline t))) - `(transient-nonstandard-key ((,class :underline t))) - `(transient-pink ((,class :inherit bold :foreground ,magenta))) - `(transient-red ((,class :inherit bold :foreground ,red-intense))) - `(transient-teal ((,class :inherit bold :foreground ,cyan-alt-other))) - `(transient-unreachable ((,class :foreground ,fg-unfocused))) - `(transient-unreachable-key ((,class :foreground ,fg-unfocused))) - `(transient-value ((,class :foreground ,magenta-alt))) -;;;;; trashed - `(trashed-deleted ((,class :inherit modus-theme-mark-del))) - `(trashed-directory ((,class :foreground ,blue))) - `(trashed-mark ((,class :inherit modus-theme-mark-symbol))) - `(trashed-marked ((,class :inherit modus-theme-mark-alt))) - `(trashed-restored ((,class :inherit modus-theme-mark-sel))) - `(trashed-symlink ((,class :inherit button :foreground ,cyan-alt))) -;;;;; treemacs - `(treemacs-directory-collapsed-face ((,class :foreground ,magenta-alt))) - `(treemacs-directory-face ((,class :inherit dired-directory))) - `(treemacs-file-face ((,class :foreground ,fg-main))) - `(treemacs-fringe-indicator-face ((,class :foreground ,fg-main))) - `(treemacs-git-added-face ((,class :foreground ,green-intense))) - `(treemacs-git-conflict-face ((,class :inherit (modus-theme-intense-red bold)))) - `(treemacs-git-ignored-face ((,class :foreground ,fg-alt))) - `(treemacs-git-modified-face ((,class :foreground ,yellow-alt-other))) - `(treemacs-git-renamed-face ((,class :foreground ,cyan-alt-other))) - `(treemacs-git-unmodified-face ((,class :foreground ,fg-main))) - `(treemacs-git-untracked-face ((,class :foreground ,red-alt-other))) - `(treemacs-help-column-face ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,magenta-alt-other :underline t))) - `(treemacs-help-title-face ((,class :foreground ,blue-alt-other))) - `(treemacs-on-failure-pulse-face ((,class :inherit modus-theme-intense-red))) - `(treemacs-on-success-pulse-face ((,class :inherit modus-theme-intense-green))) - `(treemacs-root-face ((,class :inherit bold :foreground ,blue-alt-other :height 1.2 :underline t))) - `(treemacs-root-remote-disconnected-face ((,class :inherit treemacs-root-remote-face :foreground ,yellow))) - `(treemacs-root-remote-face ((,class :inherit treemacs-root-face :foreground ,magenta))) - `(treemacs-root-remote-unreadable-face ((,class :inherit treemacs-root-unreadable-face))) - `(treemacs-root-unreadable-face ((,class :inherit treemacs-root-face :strike-through t))) - `(treemacs-tags-face ((,class :foreground ,blue-alt))) - `(treemacs-tags-face ((,class :foreground ,magenta-alt))) -;;;;; tty-menu - `(tty-menu-disabled-face ((,class :background ,bg-alt :foreground ,fg-alt))) - `(tty-menu-enabled-face ((,class :inherit bold :background ,bg-alt :foreground ,fg-main))) - `(tty-menu-selected-face ((,class :inherit modus-theme-intense-blue))) -;;;;; tuareg - `(caml-types-def-face ((,class :inherit modus-theme-subtle-red))) - `(caml-types-expr-face ((,class :inherit modus-theme-subtle-green))) - `(caml-types-occ-face ((,class :inherit modus-theme-subtle-green))) - `(caml-types-scope-face ((,class :inherit modus-theme-subtle-blue))) - `(caml-types-typed-face ((,class :inherit modus-theme-subtle-magenta))) - `(tuareg-font-double-semicolon-face ((,class ,@(modus-operandi-theme-syntax-foreground - red-alt red-alt-faint)))) - `(tuareg-font-lock-attribute-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta magenta-faint)))) - `(tuareg-font-lock-constructor-face ((,class :foreground ,fg-main))) - `(tuareg-font-lock-error-face ((,class :inherit (modus-theme-intense-red bold)))) - `(tuareg-font-lock-extension-node-face ((,class :background ,bg-alt :foreground ,magenta))) - `(tuareg-font-lock-governing-face ((,class :inherit bold :foreground ,fg-main))) - `(tuareg-font-lock-infix-extension-node-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta magenta-faint)))) - `(tuareg-font-lock-interactive-directive-face ((,class :foreground ,fg-special-cold))) - `(tuareg-font-lock-interactive-error-face ((,class :inherit bold - ,@(modus-operandi-theme-syntax-foreground - red red-faint)))) - `(tuareg-font-lock-interactive-output-face ((,class ,@(modus-operandi-theme-syntax-foreground - blue-alt-other blue-alt-other-faint)))) - `(tuareg-font-lock-label-face ((,class ,@(modus-operandi-theme-syntax-foreground - cyan-alt-other cyan-alt-other-faint)))) - `(tuareg-font-lock-line-number-face ((,class :foreground ,fg-special-warm))) - `(tuareg-font-lock-module-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt magenta-alt-faint)))) - `(tuareg-font-lock-multistage-face ((,class :inherit bold :background ,bg-alt - ,@(modus-operandi-theme-syntax-foreground - blue blue-faint)))) - `(tuareg-font-lock-operator-face ((,class ,@(modus-operandi-theme-syntax-foreground - red-alt red-alt-faint)))) - `(tuareg-opam-error-face ((,class :inherit bold - ,@(modus-operandi-theme-syntax-foreground - red red-faint)))) - `(tuareg-opam-pkg-variable-name-face ((,class ,@(modus-operandi-theme-syntax-foreground - cyan cyan-faint) - :slant ,modus-theme-slant))) -;;;;; typescript - `(typescript-jsdoc-tag ((,class :foreground ,fg-special-mild :slant ,modus-theme-slant))) - `(typescript-jsdoc-type ((,class :foreground ,fg-special-calm :slant ,modus-theme-slant))) - `(typescript-jsdoc-value ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) -;;;;; undo-tree - `(undo-tree-visualizer-active-branch-face ((,class :inherit bold :foreground ,fg-main))) - `(undo-tree-visualizer-current-face ((,class :foreground ,blue-intense))) - `(undo-tree-visualizer-default-face ((,class :foreground ,fg-alt))) - `(undo-tree-visualizer-register-face ((,class :foreground ,magenta-intense))) - `(undo-tree-visualizer-unmodified-face ((,class :foreground ,green-intense))) -;;;;; vc (vc-hooks.el) - `(vc-conflict-state ((,class :foreground ,red-active :slant ,modus-theme-slant))) - `(vc-edited-state ((,class :foreground ,yellow-active))) - `(vc-locally-added-state ((,class :foreground ,cyan-active))) - `(vc-locked-state ((,class :foreground ,blue-active))) - `(vc-missing-state ((,class :foreground ,magenta-active :slant ,modus-theme-slant))) - `(vc-needs-update-state ((,class :foreground ,green-active :slant ,modus-theme-slant))) - `(vc-removed-state ((,class :foreground ,red-active))) - `(vc-state-base ((,class :foreground ,fg-active))) - `(vc-up-to-date-state ((,class :foreground ,fg-special-cold))) -;;;;; vdiff - `(vdiff-addition-face ((,class :inherit modus-theme-diff-added))) - `(vdiff-change-face ((,class :inherit modus-theme-diff-changed))) - `(vdiff-closed-fold-face ((,class :background ,bg-diff-neutral-1 :foreground ,fg-diff-neutral-1))) - `(vdiff-refine-added ((,class :inherit modus-theme-diff-refine-added))) - `(vdiff-refine-changed ((,class :inherit modus-theme-diff-refine-changed))) - `(vdiff-subtraction-face ((,class :inherit modus-theme-diff-removed))) - `(vdiff-target-face ((,class :inherit modus-theme-intense-blue))) -;;;;; vimish-fold - `(vimish-fold-fringe ((,class :foreground ,cyan-active))) - `(vimish-fold-mouse-face ((,class :inherit modus-theme-intense-blue))) - `(vimish-fold-overlay ((,class :background ,bg-alt :foreground ,fg-special-cold))) -;;;;; visible-mark - `(visible-mark-active ((,class :background ,blue-intense-bg))) - `(visible-mark-face1 ((,class :background ,cyan-intense-bg))) - `(visible-mark-face2 ((,class :background ,yellow-intense-bg))) - `(visible-mark-forward-face1 ((,class :background ,magenta-intense-bg))) - `(visible-mark-forward-face2 ((,class :background ,green-intense-bg))) -;;;;; visual-regexp - `(vr/group-0 ((,class :inherit modus-theme-intense-blue))) - `(vr/group-1 ((,class :inherit modus-theme-intense-magenta))) - `(vr/group-2 ((,class :inherit modus-theme-intense-green))) - `(vr/match-0 ((,class :inherit modus-theme-refine-yellow))) - `(vr/match-1 ((,class :inherit modus-theme-refine-yellow))) - `(vr/match-separator-face ((,class :inherit (modus-theme-intense-neutral bold)))) -;;;;; volatile-highlights - `(vhl/default-face ((,class ,@(and (>= emacs-major-version 27) '(:extend t)) - :background ,bg-alt :foreground ,blue-nuanced))) -;;;;; vterm - `(vterm-color-black ((,class :background "gray35" :foreground "gray35"))) - `(vterm-color-blue ((,class :background ,blue :foreground ,blue))) - `(vterm-color-cyan ((,class :background ,cyan :foreground ,cyan))) - `(vterm-color-default ((,class :background ,bg-main :foreground ,fg-main))) - `(vterm-color-green ((,class :background ,green :foreground ,green))) - `(vterm-color-inverse-video ((,class :background ,bg-main :inverse-video t))) - `(vterm-color-magenta ((,class :background ,magenta :foreground ,magenta))) - `(vterm-color-red ((,class :background ,red :foreground ,red))) - `(vterm-color-underline ((,class :foreground ,fg-special-warm :underline t))) - `(vterm-color-white ((,class :background "gray65" :foreground "gray65"))) - `(vterm-color-yellow ((,class :background ,yellow :foreground ,yellow))) -;;;;; wcheck-mode - `(wcheck-default-face ((,class :foreground ,red :underline t))) -;;;;; web-mode - `(web-mode-annotation-face ((,class :inherit web-mode-comment-face))) - `(web-mode-annotation-html-face ((,class :inherit web-mode-comment-face))) - `(web-mode-annotation-tag-face ((,class :inherit web-mode-comment-face :underline t))) - `(web-mode-block-attr-name-face ((,class ,@(modus-operandi-theme-syntax-foreground - blue blue-faint)))) - `(web-mode-block-attr-value-face ((,class ,@(modus-operandi-theme-syntax-foreground - cyan-alt-other cyan-alt-other-faint)))) - `(web-mode-block-comment-face ((,class :inherit web-mode-comment-face))) - `(web-mode-block-control-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(web-mode-block-delimiter-face ((,class :foreground ,fg-main))) - `(web-mode-block-face ((,class :background ,bg-dim))) - `(web-mode-block-string-face ((,class :inherit web-mode-string-face))) - `(web-mode-bold-face ((,class :inherit bold))) - `(web-mode-builtin-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(web-mode-comment-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(web-mode-comment-keyword-face ((,class :inherit bold :background ,bg-dim - ,@(modus-operandi-theme-syntax-foreground - yellow yellow-faint)))) - `(web-mode-constant-face ((,class ,@(modus-operandi-theme-syntax-foreground - blue-alt-other blue-alt-other-faint)))) - `(web-mode-css-at-rule-face ((,class ,@(modus-operandi-theme-syntax-foreground - blue-alt-other blue-alt-other-faint)))) - `(web-mode-css-color-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(web-mode-css-comment-face ((,class :inherit web-mode-comment-face))) - `(web-mode-css-function-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(web-mode-css-priority-face ((,class ,@(modus-operandi-theme-syntax-foreground - yellow-alt yellow-alt-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(web-mode-css-property-name-face ((,class ,@(modus-operandi-theme-syntax-foreground - cyan cyan-faint)))) - `(web-mode-css-pseudo-class-face ((,class ,@(modus-operandi-theme-syntax-foreground - cyan-alt-other cyan-alt-other-faint)))) - `(web-mode-css-selector-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt-other magenta-alt-other-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(web-mode-css-string-face ((,class :inherit web-mode-string-face))) - `(web-mode-css-variable-face ((,class :foreground ,fg-special-warm))) - `(web-mode-current-column-highlight-face ((,class :background ,bg-alt))) - `(web-mode-current-element-highlight-face ((,class :inherit modus-theme-special-mild))) - `(web-mode-doctype-face ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(web-mode-error-face ((,class :inherit modus-theme-intense-red))) - `(web-mode-filter-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta magenta-faint)))) - `(web-mode-folded-face ((,class :underline t))) - `(web-mode-function-call-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta magenta-faint)))) - `(web-mode-function-name-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta magenta-faint)))) - `(web-mode-html-attr-custom-face ((,class ,@(modus-operandi-theme-syntax-foreground - cyan cyan-faint)))) - `(web-mode-html-attr-engine-face ((,class :foreground ,fg-main))) - `(web-mode-html-attr-equal-face ((,class :foreground ,fg-main))) - `(web-mode-html-attr-name-face ((,class ,@(modus-operandi-theme-syntax-foreground - cyan cyan-faint)))) - `(web-mode-html-attr-value-face ((,class ,@(modus-operandi-theme-syntax-foreground - blue-alt-other blue-alt-other-faint)))) - `(web-mode-html-entity-face ((,class ,@(modus-operandi-theme-syntax-foreground - yellow-alt-other yellow-alt-other-faint) - :slant ,modus-theme-slant))) - `(web-mode-html-tag-bracket-face ((,class :foreground ,fg-dim))) - `(web-mode-html-tag-custom-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta magenta-faint)))) - `(web-mode-html-tag-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta magenta-faint)))) - `(web-mode-html-tag-namespaced-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(web-mode-html-tag-unclosed-face ((,class ,@(modus-operandi-theme-syntax-foreground - red red-faint) - :underline t))) - `(web-mode-inlay-face ((,class :background ,bg-alt))) - `(web-mode-italic-face ((,class :slant italic))) - `(web-mode-javascript-comment-face ((,class :inherit web-mode-comment-face))) - `(web-mode-javascript-string-face ((,class :inherit web-mode-string-face))) - `(web-mode-json-comment-face ((,class :inherit web-mode-comment-face))) - `(web-mode-json-context-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt magenta-alt-faint)))) - `(web-mode-json-key-face ((,class :foreground ,blue-nuanced))) - `(web-mode-json-string-face ((,class :inherit web-mode-string-face))) - `(web-mode-jsx-depth-1-face ((,class :background ,blue-intense-bg :foreground ,fg-main))) - `(web-mode-jsx-depth-2-face ((,class :background ,blue-subtle-bg :foreground ,fg-main))) - `(web-mode-jsx-depth-3-face ((,class :background ,bg-special-cold :foreground ,fg-special-cold))) - `(web-mode-jsx-depth-4-face ((,class :background ,bg-alt :foreground ,blue-refine-fg))) - `(web-mode-jsx-depth-5-face ((,class :background ,bg-alt :foreground ,blue-nuanced))) - `(web-mode-keyword-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt-other magenta-alt-other-faint) - ,@(modus-operandi-theme-bold-weight)))) - `(web-mode-param-name-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta magenta-faint)))) - `(web-mode-part-comment-face ((,class :inherit web-mode-comment-face))) - `(web-mode-part-face ((,class :inherit web-mode-block-face))) - `(web-mode-part-string-face ((,class :inherit web-mode-string-face))) - `(web-mode-preprocessor-face ((,class ,@(modus-operandi-theme-syntax-foreground - red-alt-other red-alt-other-faint)))) - `(web-mode-script-face ((,class :inherit web-mode-part-face))) - `(web-mode-sql-keyword-face ((,class :inherit bold - ,@(modus-operandi-theme-syntax-foreground - yellow yellow-faint)))) - `(web-mode-string-face ((,class ,@(modus-operandi-theme-syntax-foreground - blue-alt blue-alt-faint)))) - `(web-mode-style-face ((,class :inherit web-mode-part-face))) - `(web-mode-symbol-face ((,class ,@(modus-operandi-theme-syntax-foreground - blue-alt-other blue-alt-other-faint)))) - `(web-mode-type-face ((,class ,@(modus-operandi-theme-syntax-foreground - magenta-alt magenta-alt-faint)))) - `(web-mode-underline-face ((,class :underline t))) - `(web-mode-variable-name-face ((,class ,@(modus-operandi-theme-syntax-foreground - cyan cyan-faint)))) - `(web-mode-warning-face ((,class :inherit bold :background ,bg-alt - ,@(modus-operandi-theme-syntax-foreground - yellow-alt-other yellow-alt-other-faint)))) - `(web-mode-whitespace-face ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) -;;;;; wgrep - `(wgrep-delete-face ((,class :inherit modus-theme-refine-yellow))) - `(wgrep-done-face ((,class :inherit modus-theme-refine-blue))) - `(wgrep-face ((,class :inherit modus-theme-refine-green))) - `(wgrep-file-face ((,class :foreground ,fg-special-warm))) - `(wgrep-reject-face ((,class :inherit (modus-theme-intense-red bold)))) -;;;;; which-function-mode - `(which-func ((,class :foreground ,magenta-active))) -;;;;; which-key - `(which-key-command-description-face ((,class :foreground ,cyan))) - `(which-key-group-description-face ((,class :foreground ,magenta-alt))) - `(which-key-highlighted-command-face ((,class :foreground ,cyan-alt :underline t))) - `(which-key-key-face ((,class :inherit bold :foreground ,blue-intense))) - `(which-key-local-map-description-face ((,class :foreground ,fg-main))) - `(which-key-note-face ((,class :background ,bg-dim :foreground ,fg-special-mild))) - `(which-key-separator-face ((,class :foreground ,fg-alt))) - `(which-key-special-key-face ((,class :inherit bold :foreground ,yellow-intense))) -;;;;; whitespace-mode - `(whitespace-big-indent ((,class :inherit modus-theme-subtle-red))) - `(whitespace-empty ((,class :inherit modus-theme-intense-magenta))) - `(whitespace-hspace ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) - `(whitespace-indentation ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) - `(whitespace-line ((,class :inherit modus-theme-special-warm))) - `(whitespace-newline ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) - `(whitespace-space ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) - `(whitespace-space-after-tab ((,class :inherit modus-theme-subtle-magenta))) - `(whitespace-space-before-tab ((,class :inherit modus-theme-subtle-cyan))) - `(whitespace-tab ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) - `(whitespace-trailing ((,class :inherit modus-theme-intense-red))) -;;;;; window-divider-mode - `(window-divider ((,class :foreground ,fg-window-divider-inner))) - `(window-divider-first-pixel ((,class :foreground ,fg-window-divider-outer))) - `(window-divider-last-pixel ((,class :foreground ,fg-window-divider-outer))) -;;;;; winum - `(winum-face ((,class ,@(modus-operandi-theme-bold-weight) :foreground ,cyan-active))) -;;;;; writegood-mode - `(writegood-duplicates-face ((,class :background ,bg-alt :foreground ,red-alt :underline t))) - `(writegood-passive-voice-face ((,class :foreground ,yellow-nuanced :underline ,fg-lang-warning))) - `(writegood-weasels-face ((,class :foreground ,red-nuanced :underline ,fg-lang-error))) -;;;;; woman - `(woman-addition ((,class :foreground ,magenta-alt-other))) - `(woman-bold ((,class :inherit bold :foreground ,magenta))) - `(woman-italic ((,class :foreground ,cyan :slant italic))) - `(woman-unknown ((,class :foreground ,yellow :slant italic))) -;;;;; xah-elisp-mode - `(xah-elisp-at-symbol ((,class :inherit bold - ,@(modus-operandi-theme-syntax-foreground - red-alt red-alt-faint)))) - `(xah-elisp-cap-variable ((,class ,@(modus-operandi-theme-syntax-foreground - red-alt-other red-alt-other-faint)))) - `(xah-elisp-command-face ((,class ,@(modus-operandi-theme-syntax-foreground - cyan-alt-other cyan-alt-other-faint)))) - `(xah-elisp-dollar-symbol ((,class ,@(modus-operandi-theme-syntax-foreground - green green-faint)))) -;;;;; xref - `(xref-file-header ((,class :inherit bold :foreground ,fg-special-cold))) - `(xref-line-number ((,class :foreground ,fg-alt))) - `(xref-match ((,class :inherit match))) -;;;;; yaml-mode - `(yaml-tab-face ((,class :inherit modus-theme-intense-red))) -;;;;; yasnippet - `(yas-field-highlight-face ((,class :background ,bg-alt :foreground ,fg-main))) -;;;;; ztree - `(ztreep-arrow-face ((,class :foreground ,fg-inactive))) - `(ztreep-diff-header-face ((,class :inherit bold :height 1.2 :foreground ,fg-special-cold))) - `(ztreep-diff-header-small-face ((,class :inherit bold :foreground ,fg-special-mild))) - `(ztreep-diff-model-add-face ((,class :foreground ,green))) - `(ztreep-diff-model-diff-face ((,class :foreground ,red))) - `(ztreep-diff-model-ignored-face ((,class :foreground ,fg-alt :strike-through t))) - `(ztreep-diff-model-normal-face ((,class :foreground ,fg-alt))) - `(ztreep-expand-sign-face ((,class :foreground ,blue))) - `(ztreep-header-face ((,class :inherit bold :height 1.2 :foreground ,fg-special-cold))) - `(ztreep-leaf-face ((,class :foreground ,cyan))) - `(ztreep-node-count-children-face ((,class :foreground ,fg-special-warm))) - `(ztreep-node-face ((,class :foreground ,fg-main)))) -;;;; Emacs 27+ - (when (>= emacs-major-version 27) - (custom-theme-set-faces - 'modus-operandi -;;;;; line numbers (`display-line-numbers-mode' and global variant) - ;; NOTE that this is specifically for the faces that were - ;; introduced in Emacs 27, as the other faces are already - ;; supported. - `(line-number-major-tick ((,class :inherit (bold default) - :background ,yellow-nuanced-bg - :foreground ,yellow-nuanced))) - `(line-number-minor-tick ((,class :inherit (bold default) - :background ,bg-inactive - :foreground ,fg-inactive))) -;;;;; tab-bar-mode - `(tab-bar ((,class :background ,bg-tab-bar :foreground ,fg-main))) - `(tab-bar-tab ((,class :inherit bold :box (:line-width 2 :color ,bg-tab-active) - :background ,bg-tab-active :foreground ,fg-main))) - `(tab-bar-tab-inactive ((,class :box (:line-width 2 :color ,bg-tab-inactive) - :background ,bg-tab-inactive :foreground ,fg-dim))) -;;;;; tab-line-mode - `(tab-line ((,class :height 0.95 :background ,bg-tab-bar :foreground ,fg-main))) - `(tab-line-close-highlight ((,class :foreground ,red))) - `(tab-line-highlight ((,class :background ,blue-subtle-bg :foreground ,fg-dim))) - `(tab-line-tab ((,class :inherit bold :box (:line-width 2 :color ,bg-tab-active) - :background ,bg-tab-active :foreground ,fg-main))) - `(tab-line-tab-current ((,class :inherit tab-line-tab))) - `(tab-line-tab-inactive ((,class :box (:line-width 2 :color ,bg-tab-inactive) - :background ,bg-tab-inactive :foreground ,fg-dim))))) -;;;; Emacs 28+ - (when (>= emacs-major-version 28) - (custom-theme-set-faces - 'modus-operandi -;;;;; isearch regexp groups - `(isearch-group-1 ((,class :inherit modus-theme-intense-blue))) - `(isearch-group-2 ((,class :inherit modus-theme-intense-magenta))))) -;;; variables - (custom-theme-set-variables - 'modus-operandi -;;;; ansi-colors - `(ansi-color-faces-vector [default bold shadow italic underline success warning error]) - `(ansi-color-names-vector [,fg-main ,red ,green ,yellow ,blue ,magenta ,cyan ,bg-main]) -;;;; awesome-tray - `(awesome-tray-mode-line-active-color ,blue) - `(awesome-tray-mode-line-inactive-color ,bg-active) -;;;; flymake fringe indicators - `(flymake-error-bitmap '(flymake-double-exclamation-mark modus-theme-fringe-red)) - `(flymake-warning-bitmap '(exclamation-mark modus-theme-fringe-yellow)) - `(flymake-note-bitmap '(exclamation-mark modus-theme-fringe-cyan)) -;;;; ibuffer - `(ibuffer-deletion-face 'modus-theme-mark-del) - `(ibuffer-filter-group-name-face 'modus-theme-mark-symbol) - `(ibuffer-marked-face 'modus-theme-mark-sel) - `(ibuffer-title-face 'modus-theme-pseudo-header) -;;;; highlight-tail - `(highlight-tail-colors - '((,green-subtle-bg . 0) - (,cyan-subtle-bg . 20))) -;;;; hl-todo - `(hl-todo-keyword-faces - '(("HOLD" . ,yellow-alt) - ("TODO" . ,magenta) - ("NEXT" . ,magenta-alt-other) - ("THEM" . ,magenta-alt) - ("PROG" . ,cyan) - ("OKAY" . ,cyan-alt) - ("DONT" . ,green-alt) - ("FAIL" . ,red) - ("BUG" . ,red) - ("DONE" . ,green) - ("NOTE" . ,yellow-alt-other) - ("KLUDGE" . ,yellow) - ("HACK" . ,yellow) - ("TEMP" . ,red-nuanced) - ("FIXME" . ,red-alt-other) - ("XXX+" . ,red-alt) - ("REVIEW" . ,cyan-alt-other) - ("DEPRECATED" . ,blue-nuanced))) -;;;; vc-annotate (C-x v g) - `(vc-annotate-background nil) - `(vc-annotate-background-mode nil) - `(vc-annotate-color-map - '((20 . ,red) - (40 . ,magenta) - (60 . ,magenta-alt) - (80 . ,red-alt) - (100 . ,yellow) - (120 . ,yellow-alt) - (140 . ,fg-special-warm) - (160 . ,fg-special-mild) - (180 . ,green) - (200 . ,green-alt) - (220 . ,cyan-alt-other) - (240 . ,cyan-alt) - (260 . ,cyan) - (280 . ,fg-special-cold) - (300 . ,blue) - (320 . ,blue-alt) - (340 . ,blue-alt-other) - (360 . ,magenta-alt-other))) - `(vc-annotate-very-old-color nil) -;;;; xterm-color - `(xterm-color-names [,fg-main ,red ,green ,yellow ,blue ,magenta ,cyan ,bg-alt]) - `(xterm-color-names-bright [,fg-alt ,red-alt ,green-alt ,yellow-alt ,blue-alt ,magenta-alt ,cyan-alt ,bg-main])) -;;; Conditional theme variables -;;;; org-src-block-faces - ;; this is a user option to add a colour-coded background to source - ;; blocks for various programming languages - (when (eq modus-operandi-theme-org-blocks 'rainbow) - (custom-theme-set-variables - 'modus-operandi - `(org-src-block-faces ; TODO this list should be expanded - `(("emacs-lisp" modus-theme-nuanced-magenta) - ("elisp" modus-theme-nuanced-magenta) - ("clojure" modus-theme-nuanced-magenta) - ("clojurescript" modus-theme-nuanced-magenta) - ("c" modus-theme-nuanced-blue) - ("c++" modus-theme-nuanced-blue) - ("sh" modus-theme-nuanced-green) - ("shell" modus-theme-nuanced-green) - ("html" modus-theme-nuanced-yellow) - ("xml" modus-theme-nuanced-yellow) - ("css" modus-theme-nuanced-red) - ("scss" modus-theme-nuanced-red) - ("python" modus-theme-nuanced-green) - ("ipython" modus-theme-nuanced-magenta) - ("r" modus-theme-nuanced-cyan) - ("yaml" modus-theme-nuanced-cyan) - ("conf" modus-theme-nuanced-cyan) - ("docker" modus-theme-nuanced-cyan) - ("json" modus-theme-nuanced-cyan)))))) +(deftheme modus-operandi + "Accessible and customizable light theme (WCAG AAA standard). +Conforms with the highest legibility standard for color contrast +between background and foreground in any given piece of text, +which corresponds to a minimum contrast in relative luminance of +7:1.") -;;; library provides -;;;###autoload -(when load-file-name - (add-to-list 'custom-theme-load-path - (file-name-as-directory (file-name-directory load-file-name)))) +(modus-themes-theme modus-operandi) (provide-theme 'modus-operandi) diff --git a/etc/themes/modus-themes.el b/etc/themes/modus-themes.el new file mode 100644 index 0000000000..79846dbf3a --- /dev/null +++ b/etc/themes/modus-themes.el @@ -0,0 +1,6436 @@ +;;; modus-themes.el --- Highly accessible themes (WCAG AAA) -*- lexical-binding:t -*- + +;; Copyright (C) 2019-2021 Free Software Foundation, Inc. + +;; Author: Protesilaos Stavrou +;; URL: https://gitlab.com/protesilaos/modus-themes +;; Version: 1.2.0 +;; Package-Requires: ((emacs "26.1")) +;; Keywords: faces, theme, accessibility + +;; This file is part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: +;; +;; The Modus themes conform with the highest standard for color-contrast +;; accessibility between background and foreground values (WCAG AAA). +;; This file contains all customization options, helper functions, +;; interactive commands, and face specifications. Please refer to the +;; official Info manual for further documentation (distributed with the +;; themes, or available at: ). +;; +;; The themes share the following customization options, all of which +;; are disabled by default (nil): +;; +;; modus-themes-slanted-constructs (boolean) +;; modus-themes-bold-constructs (boolean) +;; modus-themes-variable-pitch-headings (boolean) +;; modus-themes-variable-pitch-ui (boolean) +;; modus-themes-no-mixed-fonts (boolean) +;; modus-themes-headings (alist) +;; modus-themes-scale-headings (boolean) +;; modus-themes-fringes (choice) +;; modus-themes-lang-checkers (choice) +;; modus-themes-org-blocks (choice) +;; modus-themes-org-habit (choice) +;; modus-themes-prompts (choice) +;; modus-themes-mode-line (choice) +;; modus-themes-diffs (choice) +;; modus-themes-syntax (choice) +;; modus-themes-intense-hl-line (boolean) +;; modus-themes-subtle-line-numbers (boolean) +;; modus-themes-paren-match (choice) +;; modus-themes-region (choice) +;; modus-themes-links (choice) +;; modus-themes-completions (choice) +;; +;; The default scale for headings is as follows (it can be customized as +;; well---remember, no scaling takes place by default): +;; +;; modus-themes-scale-1 1.05 +;; modus-themes-scale-2 1.1 +;; modus-themes-scale-3 1.15 +;; modus-themes-scale-4 1.2 +;; modus-themes-scale-5 1.3 +;; +;; There also exist two unique customization options for overriding +;; color palette values. The specifics are documented in the manual. +;; The symbols are: +;; +;; modus-themes-operandi-color-overrides (alist) +;; modus-themes-vivendi-color-overrides (alist) +;; +;; Below is the list of explicitly supported packages or face groups +;; (there are implicitly supported packages as well, which inherit from +;; font-lock or some basic group). You are encouraged to report any +;; missing package or change you would like to see. +;; +;; ace-window +;; ag +;; alert +;; all-the-icons +;; annotate +;; anzu +;; apropos +;; apt-sources-list +;; artbollocks-mode +;; auctex and TeX +;; auto-dim-other-buffers +;; avy +;; awesome-tray +;; bbdb +;; binder +;; bm +;; bongo +;; boon +;; breakpoint (provided by built-in gdb-mi.el) +;; buffer-expose +;; calendar and diary +;; calfw +;; centaur-tabs +;; cfrs +;; change-log and log-view (`vc-print-log' and `vc-print-root-log') +;; cider +;; circe +;; color-rg +;; column-enforce-mode +;; company-mode +;; company-posframe +;; compilation-mode +;; completions +;; consult +;; counsel +;; counsel-css +;; counsel-notmuch +;; counsel-org-capture-string +;; cov +;; cperl-mode +;; csv-mode +;; ctrlf +;; custom (M-x customize) +;; dap-mode +;; dashboard (emacs-dashboard) +;; deadgrep +;; debbugs +;; define-word +;; deft +;; dictionary +;; diff-hl +;; diff-mode +;; dim-autoload +;; dir-treeview +;; dired +;; dired-async +;; dired-git +;; dired-git-info +;; dired-narrow +;; dired-subtree +;; diredc +;; diredfl +;; diredp (dired+) +;; disk-usage +;; display-fill-column-indicator-mode +;; doom-modeline +;; dynamic-ruler +;; easy-jekyll +;; easy-kill +;; ebdb +;; ediff +;; eglot +;; el-search +;; eldoc +;; eldoc-box +;; elfeed +;; elfeed-score +;; emms +;; enhanced-ruby-mode +;; epa +;; equake +;; erc +;; eros +;; ert +;; eshell +;; eshell-fringe-status +;; eshell-git-prompt +;; eshell-prompt-extras (epe) +;; eshell-syntax-highlighting +;; evil (evil-mode) +;; evil-goggles +;; evil-snipe +;; evil-visual-mark-mode +;; eww +;; exwm +;; eyebrowse +;; fancy-dabbrev +;; flycheck +;; flycheck-color-mode-line +;; flycheck-indicator +;; flycheck-posframe +;; flymake +;; flyspell +;; flyspell-correct +;; flx +;; freeze-it +;; frog-menu +;; focus +;; fold-this +;; font-lock (generic syntax highlighting) +;; forge +;; fountain (fountain-mode) +;; geiser +;; git-commit +;; git-gutter (and variants) +;; git-lens +;; git-rebase +;; git-timemachine +;; git-walktree +;; gnus +;; golden-ratio-scroll-screen +;; helm +;; helm-ls-git +;; helm-switch-shell +;; helm-xref +;; helpful +;; highlight-blocks +;; highlight-defined +;; highlight-escape-sequences (`hes-mode') +;; highlight-indentation +;; highlight-numbers +;; highlight-symbol +;; highlight-tail +;; highlight-thing +;; hl-defined +;; hl-fill-column +;; hl-line-mode +;; hl-todo +;; hydra +;; hyperlist +;; ibuffer +;; icomplete +;; ido-mode +;; iedit +;; iflipb +;; imenu-list +;; indium +;; info +;; info-colors +;; interaction-log +;; ioccur +;; isearch, occur, etc. +;; isl (isearch-light) +;; ivy +;; ivy-posframe +;; jira (org-jira) +;; journalctl-mode +;; js2-mode +;; julia +;; jupyter +;; kaocha-runner +;; keycast +;; line numbers (`display-line-numbers-mode' and global variant) +;; lsp-mode +;; lsp-ui +;; macrostep +;; magit +;; magit-imerge +;; make-mode +;; man +;; marginalia +;; markdown-mode +;; markup-faces (`adoc-mode') +;; mentor +;; messages +;; minibuffer-line +;; minimap +;; mmm-mode +;; modeline +;; mood-line +;; mpdel +;; mu4e +;; mu4e-conversation +;; multiple-cursors +;; neotree +;; no-emoji +;; notmuch +;; num3-mode +;; nxml-mode +;; objed +;; orderless +;; org +;; org-journal +;; org-noter +;; org-pomodoro +;; org-recur +;; org-roam +;; org-superstar +;; org-table-sticky-header +;; org-tree-slide +;; org-treescope +;; origami +;; outline-mode +;; outline-minor-faces +;; package (M-x list-packages) +;; page-break-lines +;; paradox +;; paren-face +;; parrot +;; pass +;; pdf-tools +;; persp-mode +;; perspective +;; phi-grep +;; phi-search +;; pkgbuild-mode +;; pomidor +;; popup +;; powerline +;; powerline-evil +;; prism (see "Note for prism.el" in the manual) +;; proced +;; prodigy +;; quick-peek +;; racket-mode +;; rainbow-blocks +;; rainbow-identifiers +;; rainbow-delimiters +;; rcirc +;; recursion-indicator +;; regexp-builder (also known as `re-builder') +;; rg +;; ripgrep +;; rmail +;; ruler-mode +;; sallet +;; selectrum +;; selectrum-prescient +;; semantic +;; sesman +;; shell-script-mode +;; shortdoc +;; show-paren-mode +;; shr +;; side-notes +;; sieve-mode +;; skewer-mode +;; smart-mode-line +;; smartparens +;; smerge +;; spaceline +;; speedbar +;; spell-fu +;; spray +;; stripes +;; suggest +;; switch-window +;; swiper +;; swoop +;; sx +;; symbol-overlay +;; tab-bar-mode +;; tab-line-mode +;; syslog-mode +;; table (built-in table.el) +;; telephone-line +;; terraform-mode +;; term +;; tomatinho +;; transient (pop-up windows like Magit's) +;; trashed +;; treemacs +;; tty-menu +;; tuareg +;; typescript +;; undo-tree +;; vc (built-in mode line status for version control) +;; vc-annotate (C-x v g) +;; vdiff +;; vimish-fold +;; visible-mark +;; visual-regexp +;; volatile-highlights +;; vterm +;; wcheck-mode +;; web-mode +;; wgrep +;; which-function-mode +;; which-key +;; whitespace-mode +;; window-divider-mode +;; winum +;; writegood-mode +;; woman +;; xah-elisp-mode +;; xref +;; xterm-color (and ansi-colors) +;; yaml-mode +;; yasnippet +;; ztree +;; +;; For a complete view of the project, also refer to the following files +;; (should be distributed in the same repository/directory as the +;; current item): +;; +;; - modus-operandi-theme.el (Light theme) +;; - modus-vivendi-theme.el (Dark theme) + +;;; Code: + + + +(eval-when-compile (require 'cl-lib)) + +(defgroup modus-themes () + "Options for `modus-operandi', `modus-vivendi'." + :group 'faces + :link '(info-link "(modus-themes) Top") + :prefix "modus-themes-" + :tag "Modus Themes") + +;;; Variables for each theme variant + +;;;; Modus Operandi + +(define-obsolete-variable-alias + 'modus-operandi-theme-default-colors-alist + 'modus-themes-colors-operandi + "1.0.0") + +(define-obsolete-variable-alias + 'modus-themes-colors-operandi + 'modus-themes-operandi-colors + "1.1.0") + +(defconst modus-themes-operandi-colors + '(;; base values + (bg-main . "#ffffff") (fg-main . "#000000") + (bg-dim . "#f8f8f8") (fg-dim . "#282828") + (bg-alt . "#f0f0f0") (fg-alt . "#505050") + ;; specifically for on/off states and must be combined with + ;; themselves, though the backgrounds are also meant to be used with + ;; other "active" values, defined further below + (bg-active . "#d7d7d7") (fg-active . "#0a0a0a") + (bg-inactive . "#efefef") (fg-inactive . "#404148") + ;; these special values are intended as alternatives to the base + ;; values for cases where we need to avoid confusion between the + ;; highlighted constructs; they must either be used as pairs based + ;; on their name or each can be combined with {fg,bg}-{main,alt,dim} + ;; always in accordance with their role as background or foreground + (bg-special-cold . "#dde3f4") (fg-special-cold . "#093060") + (bg-special-mild . "#c4ede0") (fg-special-mild . "#184034") + (bg-special-warm . "#f0e0d4") (fg-special-warm . "#5d3026") + (bg-special-calm . "#f8ddea") (fg-special-calm . "#61284f") + ;; foregrounds that can be combined with bg-main, bg-dim, bg-alt + (red . "#a60000") + (red-alt . "#972500") + (red-alt-other . "#a0132f") + (red-faint . "#7f1010") + (red-alt-faint . "#702f00") + (red-alt-other-faint . "#7f002f") + (green . "#005e00") + (green-alt . "#315b00") + (green-alt-other . "#145c33") + (green-faint . "#104410") + (green-alt-faint . "#30440f") + (green-alt-other-faint . "#0f443f") + (yellow . "#813e00") + (yellow-alt . "#70480f") + (yellow-alt-other . "#863927") + (yellow-faint . "#5f4400") + (yellow-alt-faint . "#5d5000") + (yellow-alt-other-faint . "#5e3a20") + (blue . "#0031a9") + (blue-alt . "#2544bb") + (blue-alt-other . "#0000c0") + (blue-faint . "#003497") + (blue-alt-faint . "#0f3d8c") + (blue-alt-other-faint . "#001087") + (magenta . "#721045") + (magenta-alt . "#8f0075") + (magenta-alt-other . "#5317ac") + (magenta-faint . "#752f50") + (magenta-alt-faint . "#7b206f") + (magenta-alt-other-faint . "#55348e") + (cyan . "#00538b") + (cyan-alt . "#30517f") + (cyan-alt-other . "#005a5f") + (cyan-faint . "#005077") + (cyan-alt-faint . "#354f6f") + (cyan-alt-other-faint . "#125458") + ;; these foreground values can only be combined with bg-main and are + ;; thus not suitable for general purpose highlighting + (red-intense . "#b60000") + (orange-intense . "#904200") + (green-intense . "#006800") + (yellow-intense . "#605b00") + (blue-intense . "#1f1fce") + (magenta-intense . "#a8007f") + (purple-intense . "#7f10d0") + (cyan-intense . "#005f88") + ;; those foregrounds are meant exclusively for bg-active, bg-inactive + (red-active . "#8a0000") + (green-active . "#004c2e") + (yellow-active . "#702d1f") + (blue-active . "#0030b4") + (magenta-active . "#5c2092") + (cyan-active . "#003f8a") + ;; the "subtle" values below be combined with fg-dim, while the + ;; "intense" should be paired with fg-main + (red-subtle-bg . "#f2b0a2") + (red-intense-bg . "#ff8892") + (green-subtle-bg . "#aecf90") + (green-intense-bg . "#5ada88") + (yellow-subtle-bg . "#e4c340") + (yellow-intense-bg . "#f5df23") + (blue-subtle-bg . "#b5d0ff") + (blue-intense-bg . "#6aaeff") + (magenta-subtle-bg . "#f0d3ff") + (magenta-intense-bg . "#d5baff") + (cyan-subtle-bg . "#c0efff") + (cyan-intense-bg . "#42cbd4") + ;; those background values must be combined with fg-main and should + ;; only be used for indicators that are placed on the fringes + (red-fringe-bg . "#f08290") + (green-fringe-bg . "#62c86a") + (yellow-fringe-bg . "#dbba3f") + (blue-fringe-bg . "#82afff") + (magenta-fringe-bg . "#e0a3ff") + (cyan-fringe-bg . "#2fcddf") + ;; those background values should only be used for graphs or similar + ;; applications where colored blocks are expected to be positioned + ;; next to each other + (red-graph-0-bg . "#ef6f79") + (red-graph-1-bg . "#ff9f9f") + (green-graph-0-bg . "#49d239") + (green-graph-1-bg . "#6dec6d") + (yellow-graph-0-bg . "#efec08") + (yellow-graph-1-bg . "#dbff4e") + (blue-graph-0-bg . "#55a2f0") + (blue-graph-1-bg . "#7fcfff") + (magenta-graph-0-bg . "#ba86ef") + (magenta-graph-1-bg . "#e7afff") + (cyan-graph-0-bg . "#30d3f0") + (cyan-graph-1-bg . "#6fefff") + ;; the following are for cases where both the foreground and the + ;; background need to have a similar hue and so must be combined + ;; with themselves, even though the foregrounds can be paired with + ;; any of the base backgrounds + (red-refine-bg . "#ffcccc") (red-refine-fg . "#780000") + (green-refine-bg . "#aceaac") (green-refine-fg . "#004c00") + (yellow-refine-bg . "#fff29a") (yellow-refine-fg . "#604000") + (blue-refine-bg . "#8ac7ff") (blue-refine-fg . "#002288") + (magenta-refine-bg . "#ffccff") (magenta-refine-fg . "#770077") + (cyan-refine-bg . "#8eecf4") (cyan-refine-fg . "#004850") + ;; the "nuanced" backgrounds can be combined with all of the above + ;; foregrounds, as well as those included here, while the "nuanced" + ;; foregrounds can in turn also be combined with bg-main, bg-dim, + ;; bg-alt + (red-nuanced-bg . "#fff1f0") (red-nuanced-fg . "#5f0000") + (green-nuanced-bg . "#ecf7ed") (green-nuanced-fg . "#004000") + (yellow-nuanced-bg . "#fff3da") (yellow-nuanced-fg . "#3f3000") + (blue-nuanced-bg . "#f3f3ff") (blue-nuanced-fg . "#201f55") + (magenta-nuanced-bg . "#fdf0ff") (magenta-nuanced-fg . "#541f4f") + (cyan-nuanced-bg . "#ebf6fa") (cyan-nuanced-fg . "#0f3360") + ;; the following are reserved for specific cases + ;; + ;; bg-hl-line is between bg-dim and bg-alt, so it should + ;; work with all accents that cover those two, plus bg-main + ;; + ;; bg-hl-alt and bg-hl-alt-intense should only be used when no + ;; other greyscale or fairly neutral background is available to + ;; properly draw attention to a given construct + ;; + ;; bg-header is between bg-active and bg-inactive, so it + ;; can be combined with any of the "active" values, plus the + ;; "special" and base foreground colors + ;; + ;; bg-paren-match, bg-paren-match-intense, bg-region and + ;; bg-tab-active must be combined with fg-main, while + ;; bg-tab-inactive should be combined with fg-dim, whereas + ;; bg-tab-inactive-alt goes together with fg-main + ;; + ;; bg-tab-bar is only intended for the bar that holds the tabs and + ;; can only be combined with fg-main + ;; + ;; fg-tab-active is meant to be combined with bg-tab-active, + ;; though only for styling special elements, such as underlining + ;; the current tab + ;; + ;; fg-escape-char-construct and fg-escape-char-backslash can + ;; be combined bg-main, bg-dim, bg-alt + ;; + ;; fg-lang-error, fg-lang-warning, fg-lang-note can be + ;; combined with bg-main, bg-dim, bg-alt + ;; + ;; fg-mark-sel, fg-mark-del, fg-mark-alt can be combined + ;; with bg-main, bg-dim, bg-alt, bg-hl-line + ;; + ;; fg-unfocused must be combined with bg-main + ;; + ;; fg-docstring, fg-comment-yellow can be combined with + ;; bg-main, bg-dim, bg-alt + ;; + ;; the window divider colors apply to faces with just an fg value + ;; + ;; all pairs are combinable with themselves + (bg-hl-line . "#f2eff3") + (bg-hl-line-intense . "#e0e0e0") + (bg-hl-alt . "#fbeee0") + (bg-hl-alt-intense . "#e8dfd1") + (bg-paren-match . "#e0af82") + (bg-paren-match-intense . "#c488ff") + (bg-region . "#bcbcbc") + + (bg-tab-bar . "#d5d5d5") + (bg-tab-active . "#f6f6f6") + (bg-tab-inactive . "#bdbdbd") + (bg-tab-inactive-alt . "#999999") + (fg-tab-active . "#30169e") + + (fg-escape-char-construct . "#8b1030") + (fg-escape-char-backslash . "#654d0f") + + (fg-lang-error . "#9f004f") + (fg-lang-warning . "#604f0f") + (fg-lang-note . "#4040ae") + (fg-lang-underline-error . "#ef4f54") + (fg-lang-underline-warning . "#cf9f00") + (fg-lang-underline-note . "#3f6fef") + + (fg-window-divider-inner . "#888888") + (fg-window-divider-outer . "#585858") + + (fg-unfocused . "#56576d") + + (fg-docstring . "#2a486a") + (fg-comment-yellow . "#5f4400") + + (bg-header . "#e5e5e5") (fg-header . "#2a2a2a") + + (bg-whitespace . "#f5efef") (fg-whitespace . "#624956") + + (bg-diff-heading . "#b7cfe0") (fg-diff-heading . "#041645") + (bg-diff-added . "#d4fad4") (fg-diff-added . "#004500") + (bg-diff-added-deuteran . "#daefff") (fg-diff-added-deuteran . "#002044") + (bg-diff-changed . "#fcefcf") (fg-diff-changed . "#524200") + (bg-diff-removed . "#ffe8ef") (fg-diff-removed . "#691616") + + (bg-diff-refine-added . "#94cf94") (fg-diff-refine-added . "#002a00") + (bg-diff-refine-added-deuteran . "#77c0ef") (fg-diff-refine-added-deuteran . "#000035") + (bg-diff-refine-changed . "#cccf8f") (fg-diff-refine-changed . "#302010") + (bg-diff-refine-removed . "#daa2b0") (fg-diff-refine-removed . "#400000") + + (bg-diff-focus-added . "#bbeabb") (fg-diff-focus-added . "#002c00") + (bg-diff-focus-added-deuteran . "#bacfff") (fg-diff-focus-added-deuteran . "#001755") + (bg-diff-focus-changed . "#ecdfbf") (fg-diff-focus-changed . "#392900") + (bg-diff-focus-removed . "#efcbcf") (fg-diff-focus-removed . "#4a0000") + + (bg-diff-neutral-0 . "#979797") (fg-diff-neutral-0 . "#040404") + (bg-diff-neutral-1 . "#b0b0b0") (fg-diff-neutral-1 . "#252525") + (bg-diff-neutral-2 . "#cccccc") (fg-diff-neutral-2 . "#3a3a3a") + + (bg-mark-sel . "#a0f0cf") (fg-mark-sel . "#005040") + (bg-mark-del . "#ffccbb") (fg-mark-del . "#840040") + (bg-mark-alt . "#f5d88f") (fg-mark-alt . "#782900")) + "The entire palette of `modus-operandi' theme. +Each element has the form (NAME . HEX) with the former as a +symbol and the latter as a string.") + +;;;; Modus Vivendi + +(define-obsolete-variable-alias + 'modus-vivendi-theme-default-colors-alist + 'modus-themes-colors-vivendi + "1.0.0") + +(define-obsolete-variable-alias + 'modus-themes-colors-vivendi + 'modus-themes-vivendi-colors + "1.1.0") + +(defconst modus-themes-vivendi-colors + '(;; base values + (bg-main . "#000000") (fg-main . "#ffffff") + (bg-dim . "#110b11") (fg-dim . "#e0e6f0") + (bg-alt . "#181a20") (fg-alt . "#a8a8a8") + ;; specifically for on/off states and must be combined with + ;; themselves, though the backgrounds are also meant to be used with + ;; other "active" values, defined further below + (bg-active . "#323232") (fg-active . "#f4f4f4") + (bg-inactive . "#1e1e1e") (fg-inactive . "#bfc0c4") + ;; these special values are intended as alternatives to the base + ;; values for cases where we need to avoid confusion between the + ;; highlighted constructs; they must either be used as pairs based + ;; on their name or each can be combined with {fg,bg}-{main,alt,dim} + ;; always in accordance with their role as background or foreground + (bg-special-cold . "#203448") (fg-special-cold . "#c6eaff") + (bg-special-mild . "#00322e") (fg-special-mild . "#bfebe0") + (bg-special-warm . "#382f27") (fg-special-warm . "#f8dec0") + (bg-special-calm . "#392a48") (fg-special-calm . "#fbd6f4") + ;; foregrounds that can be combined with bg-main, bg-dim, bg-alt + (red . "#ff8059") + (red-alt . "#f4923b") + (red-alt-other . "#ff9977") + (red-faint . "#ffa0a0") + (red-alt-faint . "#f5aa80") + (red-alt-other-faint . "#ff9fbf") + (green . "#44bc44") + (green-alt . "#70c900") + (green-alt-other . "#00cd68") + (green-faint . "#88cf88") + (green-alt-faint . "#a8cf88") + (green-alt-other-faint . "#88cfaf") + (yellow . "#eecc00") + (yellow-alt . "#cfdf30") + (yellow-alt-other . "#f0ce43") + (yellow-faint . "#d2b580") + (yellow-alt-faint . "#cabf77") + (yellow-alt-other-faint . "#d0ba95") + (blue . "#2fafff") + (blue-alt . "#79a8ff" ) + (blue-alt-other . "#00bcff") + (blue-faint . "#92baff") + (blue-alt-faint . "#a0acf5") + (blue-alt-other-faint . "#87c8ff") + (magenta . "#feacd0") + (magenta-alt . "#f78fe7") + (magenta-alt-other . "#b6a0ff") + (magenta-faint . "#e0b2d6") + (magenta-alt-faint . "#ef9fe4") + (magenta-alt-other-faint . "#cfa6ff") + (cyan . "#00d3d0") + (cyan-alt . "#4ae8fc") + (cyan-alt-other . "#6ae4b9") + (cyan-faint . "#90c4ed") + (cyan-alt-faint . "#a0bfdf") + (cyan-alt-other-faint . "#a4d0bb") + ;; these foreground values can only be combined with bg-main and are + ;; thus not suitable for general purpose highlighting + (red-intense . "#fe6060") + (orange-intense . "#fba849") + (green-intense . "#4fe42f") + (yellow-intense . "#f0dd60") + (blue-intense . "#4fafff") + (magenta-intense . "#ff62d4") + (purple-intense . "#9f80ff") + (cyan-intense . "#3fdfd0") + ;; those foregrounds are meant exclusively for bg-active, bg-inactive + (red-active . "#ffa7ba") + (green-active . "#70d73f") + (yellow-active . "#dbbe5f") + (blue-active . "#34cfff") + (magenta-active . "#d5b1ff") + (cyan-active . "#00d8b4") + ;; the "subtle" values below be combined with fg-dim, while the + ;; "intense" should be paired with fg-main + (red-subtle-bg . "#762422") + (red-intense-bg . "#a4202a") + (green-subtle-bg . "#2f4a00") + (green-intense-bg . "#006800") + (yellow-subtle-bg . "#604200") + (yellow-intense-bg . "#874900") + (blue-subtle-bg . "#10387c") + (blue-intense-bg . "#2a40b8") + (magenta-subtle-bg . "#49366e") + (magenta-intense-bg . "#7042a2") + (cyan-subtle-bg . "#00415e") + (cyan-intense-bg . "#005f88") + ;; those background values must be combined with fg-main and should + ;; only be used for indicators that are placed on the fringes + (red-fringe-bg . "#8f1f4b") + (green-fringe-bg . "#006700") + (yellow-fringe-bg . "#6f4f00") + (blue-fringe-bg . "#3f33af") + (magenta-fringe-bg . "#6f2f89") + (cyan-fringe-bg . "#004f8f") + ;; those background values should only be used for graphs or similar + ;; applications where colored blocks are expected to be positioned + ;; next to each other + (red-graph-0-bg . "#af0404") + (red-graph-1-bg . "#801f2f") + (green-graph-0-bg . "#24ba2f") + (green-graph-1-bg . "#0f8f07") + (yellow-graph-0-bg . "#ffd03e") + (yellow-graph-1-bg . "#d7d800") + (blue-graph-0-bg . "#406fff") + (blue-graph-1-bg . "#2f50c8") + (magenta-graph-0-bg . "#af7bee") + (magenta-graph-1-bg . "#7f59cf") + (cyan-graph-0-bg . "#47dcfa") + (cyan-graph-1-bg . "#0bc0df") + ;; the following are for cases where both the foreground and the + ;; background need to have a similar hue and so must be combined + ;; with themselves, even though the foregrounds can be paired with + ;; any of the base backgrounds + (red-refine-bg . "#77002a") (red-refine-fg . "#ffb9ab") + (green-refine-bg . "#00422a") (green-refine-fg . "#9ff0cf") + (yellow-refine-bg . "#693200") (yellow-refine-fg . "#e2d980") + (blue-refine-bg . "#242679") (blue-refine-fg . "#8ec6ff") + (magenta-refine-bg . "#71206a") (magenta-refine-fg . "#ffcaf0") + (cyan-refine-bg . "#004065") (cyan-refine-fg . "#8ae4f2") + ;; the "nuanced" backgrounds can be combined with all of the above + ;; foregrounds, as well as those included here, while the "nuanced" + ;; foregrounds can in turn also be combined with bg-main, bg-dim, + ;; bg-alt + (red-nuanced-bg . "#2c0614") (red-nuanced-fg . "#ffcccc") + (green-nuanced-bg . "#001904") (green-nuanced-fg . "#b8e2b8") + (yellow-nuanced-bg . "#221000") (yellow-nuanced-fg . "#dfdfb0") + (blue-nuanced-bg . "#0f0e39") (blue-nuanced-fg . "#bfd9ff") + (magenta-nuanced-bg . "#230631") (magenta-nuanced-fg . "#e5cfef") + (cyan-nuanced-bg . "#041529") (cyan-nuanced-fg . "#a8e5e5") + ;; the following are reserved for specific cases + ;; + ;; bg-hl-line is between bg-dim and bg-alt, so it should + ;; work with all accents that cover those two, plus bg-main + ;; + ;; bg-hl-alt and bg-hl-alt-intense should only be used when no + ;; other greyscale or fairly neutral background is available to + ;; properly draw attention to a given construct + ;; + ;; bg-header is between bg-active and bg-inactive, so it + ;; can be combined with any of the "active" values, plus the + ;; "special" and base foreground colors + ;; + ;; bg-paren-match, bg-paren-match-intense, bg-region and + ;; bg-tab-active must be combined with fg-main, while + ;; bg-tab-inactive should be combined with fg-dim, whereas + ;; bg-tab-inactive-alt goes together with fg-main + ;; + ;; bg-tab-bar is only intended for the bar that holds the tabs and + ;; can only be combined with fg-main + ;; + ;; fg-tab-active is meant to be combined with bg-tab-active, + ;; though only for styling special elements, such as underlining + ;; the current tab + ;; + ;; fg-escape-char-construct and fg-escape-char-backslash can + ;; be combined bg-main, bg-dim, bg-alt + ;; + ;; fg-lang-error, fg-lang-warning, fg-lang-note can be + ;; combined with bg-main, bg-dim, bg-alt + ;; + ;; fg-mark-sel, fg-mark-del, fg-mark-alt can be combined + ;; with bg-main, bg-dim, bg-alt, bg-hl-line + ;; + ;; fg-unfocused must be combined with bg-main + ;; + ;; fg-docstring, fg-comment-yellow can be combined with + ;; bg-main, bg-dim, bg-alt + ;; + ;; the window divider colors apply to faces with just an fg value + ;; + ;; all pairs are combinable with themselves + (bg-hl-line . "#151823") + (bg-hl-line-intense . "#2f2f2f") + (bg-hl-alt . "#181732") + (bg-hl-alt-intense . "#282e46") + (bg-paren-match . "#5f362f") + (bg-paren-match-intense . "#7416b5") + (bg-region . "#3c3c3c") + + (bg-tab-bar . "#2c2c2c") + (bg-tab-active . "#0e0e0e") + (bg-tab-inactive . "#3d3d3d") + (bg-tab-inactive-alt . "#595959") + (fg-tab-active . "#5ac3cf") + + (fg-escape-char-construct . "#e7a59a") + (fg-escape-char-backslash . "#abab00") + + (fg-lang-error . "#ef8690") + (fg-lang-warning . "#b0aa00") + (fg-lang-note . "#9d9def") + (fg-lang-underline-error . "#ff4a6f") + (fg-lang-underline-warning . "#d0de00") + (fg-lang-underline-note . "#5f6fff") + + (fg-window-divider-inner . "#646464") + (fg-window-divider-outer . "#969696") + + (fg-unfocused . "#93959b") + + (fg-docstring . "#b0d6f5") + (fg-comment-yellow . "#cab98f") + + (bg-header . "#212121") (fg-header . "#dddddd") + + (bg-whitespace . "#101424") (fg-whitespace . "#aa9e9f") + + (bg-diff-heading . "#304466") (fg-diff-heading . "#dae7ff") + (bg-diff-added . "#0a280a") (fg-diff-added . "#94ba94") + (bg-diff-added-deuteran . "#001a3f") (fg-diff-added-deuteran . "#c4cdf2") + (bg-diff-changed . "#2a2000") (fg-diff-changed . "#b0ba9f") + (bg-diff-removed . "#40160f") (fg-diff-removed . "#c6adaa") + + (bg-diff-refine-added . "#005a36") (fg-diff-refine-added . "#e0f6e0") + (bg-diff-refine-added-deuteran . "#234f8f") (fg-diff-refine-added-deuteran . "#dde4ff") + (bg-diff-refine-changed . "#585800") (fg-diff-refine-changed . "#ffffcc") + (bg-diff-refine-removed . "#852828") (fg-diff-refine-removed . "#ffd9eb") + + (bg-diff-focus-added . "#203d20") (fg-diff-focus-added . "#b4ddb4") + (bg-diff-focus-added-deuteran . "#00405f") (fg-diff-focus-added-deuteran . "#bfe4ff") + (bg-diff-focus-changed . "#4a3a10") (fg-diff-focus-changed . "#d0daaf") + (bg-diff-focus-removed . "#5e2526") (fg-diff-focus-removed . "#eebdba") + + (bg-diff-neutral-0 . "#575757") (fg-diff-neutral-0 . "#fcfcfc") + (bg-diff-neutral-1 . "#454545") (fg-diff-neutral-1 . "#dddddd") + (bg-diff-neutral-2 . "#313131") (fg-diff-neutral-2 . "#bfbfbf") + + (bg-mark-sel . "#002f2f") (fg-mark-sel . "#60cfa2") + (bg-mark-del . "#5a0000") (fg-mark-del . "#ff99aa") + (bg-mark-alt . "#3f2210") (fg-mark-alt . "#f0aa20")) + "The entire palette of `modus-vivendi' theme. +Each element has the form (NAME . HEX) with the former as a +symbol and the latter as a string.") + + + +;;; Custom faces + +;; These faces are used internally to ensure consistency between various +;; groups and to streamline the evaluation of relevant customization +;; options. +(defface modus-theme-subtle-red nil + "Subtle red background combined with a dimmed foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-subtle-green nil + "Subtle green background combined with a dimmed foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-subtle-yellow nil + "Subtle yellow background combined with a dimmed foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-subtle-blue nil + "Subtle blue background combined with a dimmed foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-subtle-magenta nil + "Subtle magenta background combined with a dimmed foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-subtle-cyan nil + "Subtle cyan background combined with a dimmed foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-subtle-neutral nil + "Subtle gray background combined with a dimmed foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-intense-red nil + "Intense red background combined with the main foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-intense-green nil + "Intense green background combined with the main foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-intense-yellow nil + "Intense yellow background combined with the main foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-intense-blue nil + "Intense blue background combined with the main foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-intense-magenta nil + "Intense magenta background combined with the main foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-intense-cyan nil + "Intense cyan background combined with the main foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-intense-neutral nil + "Intense gray background combined with the main foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-refine-red nil + "Combination of accented red background and foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-refine-green nil + "Combination of accented green background and foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-refine-yellow nil + "Combination of accented yellow background and foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-refine-blue nil + "Combination of accented blue background and foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-refine-magenta nil + "Combination of accented magenta background and foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-refine-cyan nil + "Combination of accented cyan background and foreground. +This is used for general purpose highlighting, mostly in buffers +or for completion interfaces. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-active-red nil + "A red background meant for use on the modeline or similar. +This is combined with the modelines primary foreground value. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-active-green nil + "A green background meant for use on the modeline or similar. +This is combined with the modelines primary foreground value. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-active-yellow nil + "A yellow background meant for use on the modeline or similar. +This is combined with the modelines primary foreground value. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-active-blue nil + "A blue background meant for use on the modeline or similar. +This is combined with the modelines primary foreground value. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-active-magenta nil + "A magenta background meant for use on the modeline or similar. +This is combined with the modelines primary foreground value. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-active-cyan nil + "A cyan background meant for use on the modeline or similar. +This is combined with the modelines primary foreground value. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-fringe-red nil + "A red background meant for use on the fringe or similar. +This is combined with the main foreground value. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-fringe-green nil + "A green background meant for use on the fringe or similar. +This is combined with the main foreground value. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-fringe-yellow nil + "A yellow background meant for use on the fringe or similar. +This is combined with the main foreground value. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-fringe-blue nil + "A blue background meant for use on the fringe or similar. +This is combined with the main foreground value. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-fringe-magenta nil + "A magenta background meant for use on the fringe or similar. +This is combined with the main foreground value. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-fringe-cyan nil + "A cyan background meant for use on the fringe or similar. +This is combined with the main foreground value. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-nuanced-red nil + "A nuanced red background. +This does not specify a foreground of its own. Instead it is meant to +serve as the backdrop for elements such as Org blocks, headings, and any +other surface that needs to retain the colors on display. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-nuanced-green nil + "A nuanced green background. +This does not specify a foreground of its own. Instead it is meant to +serve as the backdrop for elements such as Org blocks, headings, and any +other surface that needs to retain the colors on display. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-nuanced-yellow nil + "A nuanced yellow background. +This does not specify a foreground of its own. Instead it is meant to +serve as the backdrop for elements such as Org blocks, headings, and any +other surface that needs to retain the colors on display. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-nuanced-blue nil + "A nuanced blue background. +This does not specify a foreground of its own. Instead it is meant to +serve as the backdrop for elements such as Org blocks, headings, and any +other surface that needs to retain the colors on display. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-nuanced-magenta nil + "A nuanced magenta background. +This does not specify a foreground of its own. Instead it is meant to +serve as the backdrop for elements such as Org blocks, headings, and any +other surface that needs to retain the colors on display. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-nuanced-cyan nil + "A nuanced cyan background. +This does not specify a foreground of its own. Instead it is meant to +serve as the backdrop for elements such as Org blocks, headings, and any +other surface that needs to retain the colors on display. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-special-cold nil + "Combines the 'special cold' background and foreground values. +This is intended for cases when a neutral gray background is not +suitable and where a combination of more saturated colors would not be +appropriate. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-special-mild nil + "Combines the 'special mild' background and foreground values. +This is intended for cases when a neutral gray background is not +suitable and where a combination of more saturated colors would not be +appropriate. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-special-warm nil + "Combines the 'special warm' background and foreground values. +This is intended for cases when a neutral gray background is not +suitable and where a combination of more saturated colors would not be +appropriate. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-special-calm nil + "Combines the 'special calm' background and foreground values. +This is intended for cases when a neutral gray background is not +suitable and where a combination of more saturated colors would not be +appropriate. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-diff-added nil + "Combines green colors for the 'added' state in diffs. +The applied colors are contingent on the value assigned to +`modus-themes-diffs'. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-diff-changed nil + "Combines yellow colors for the 'changed' state in diffs. +The applied colors are contingent on the value assigned to +`modus-themes-diffs'. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-diff-removed nil + "Combines red colors for the 'removed' state in diffs. +The applied colors are contingent on the value assigned to +`modus-themes-diffs'. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-diff-refine-added nil + "Combines green colors for word-wise 'added' state in diffs. +The applied colors are contingent on the value assigned to +`modus-themes-diffs'. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-diff-refine-changed nil + "Combines yellow colors for word-wise 'changed' state in diffs. +The applied colors are contingent on the value assigned to +`modus-themes-diffs'. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-diff-refine-removed nil + "Combines red colors for word-wise 'removed' state in diffs. +The applied colors are contingent on the value assigned to +`modus-themes-diffs'. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-diff-focus-added nil + "Combines green colors for the focused 'added' state in diffs. +The applied colors are contingent on the value assigned to +`modus-themes-diffs'. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-diff-focus-changed nil + "Combines yellow colors for the focused 'changed' state in. +The applied colors are contingent on the value assigned to +`modus-themes-diffs'. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-diff-focus-removed nil + "Combines red colors for the focused 'removed' state in diffs. +The applied colors are contingent on the value assigned to +`modus-themes-diffs'. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-diff-heading nil + "Combines blue colors for the diff hunk heading. +The applied colors are contingent on the value assigned to +`modus-themes-diffs'. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-pseudo-header nil + "Generic style for some elements that function like headings. +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-mark-alt nil + "Combines yellow colors for marking special lines +This is intended for use in modes such as Dired, Ibuffer, Proced. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-mark-del nil + "Combines red colors for marking deletable lines +This is intended for use in modes such as Dired, Ibuffer, Proced. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-mark-sel nil + "Combines green colors for marking lines +This is intended for use in modes such as Dired, Ibuffer, Proced. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-mark-symbol nil + "Applies a blue color and other styles for mark indicators. +This is intended for use in modes such as Dired, Ibuffer, Proced. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-heading-1 nil + "General purpose face for use in headings level 1 +The exact attributes assigned to this face are contingent on the values +assigned to the `modus-themes-headings' variable. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-heading-2 nil + "General purpose face for use in headings level 2. +The exact attributes assigned to this face are contingent on the values +assigned to the `modus-themes-headings' variable. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-heading-3 nil + "General purpose face for use in headings level 3. +The exact attributes assigned to this face are contingent on the values +assigned to the `modus-themes-headings' variable. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-heading-4 nil + "General purpose face for use in headings level 4. +The exact attributes assigned to this face are contingent on the values +assigned to the `modus-themes-headings' variable. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-heading-5 nil + "General purpose face for use in headings level 5. +The exact attributes assigned to this face are contingent on the values +assigned to the `modus-themes-headings' variable. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-heading-6 nil + "General purpose face for use in headings level 6. +The exact attributes assigned to this face are contingent on the values +assigned to the `modus-themes-headings' variable. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-heading-7 nil + "General purpose face for use in headings level 7. +The exact attributes assigned to this face are contingent on the values +assigned to the `modus-themes-headings' variable. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-heading-8 nil + "General purpose face for use in headings level 8. +The exact attributes assigned to this face are contingent on the values +assigned to the `modus-themes-headings' variable. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-hl-line nil + "General purpose face for the current line. +The exact attributes assigned to this face are contingent on the values +assigned to the `modus-themes-intense-hl-line' variable. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-bold nil + "Generic face for applying a conditional bold weight. +This behaves in accordance with `modus-themes-bold-constructs'. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-slant nil + "Generic face for applying a conditional slant (italics). +This behaves in accordance with `modus-themes-slanted-constructs'. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-variable-pitch nil + "Generic face for applying a conditional `variable-pitch'. +This behaves in accordance with `modus-themes-no-mixed-fonts', +`modus-themes-variable-pitch-headings' for all heading levels, and +`modus-themes-variable-pitch-ui'. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-graph-red-0 nil + "Special subdued red face for use in graphs. +This is intended to be applied in contexts such as the Org agenda habit +graph where faithfulness to the semantics of a color value is of +paramount importance. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-graph-red-1 nil + "Special prominent red face for use in graphs. +This is intended to be applied in contexts such as the Org agenda habit +graph where faithfulness to the semantics of a color value is of +paramount importance. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-graph-green-0 nil + "Special subdued green face for use in graphs. +This is intended to be applied in contexts such as the Org agenda habit +graph where faithfulness to the semantics of a color value is of +paramount importance. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-graph-green-1 nil + "Special prominent green face for use in graphs. +This is intended to be applied in contexts such as the Org agenda habit +graph where faithfulness to the semantics of a color value is of +paramount importance. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-graph-yellow-0 nil + "Special subdued yellow face for use in graphs. +This is intended to be applied in contexts such as the Org agenda habit +graph where faithfulness to the semantics of a color value is of +paramount importance. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-graph-yellow-1 nil + "Special prominent yellow face for use in graphs. +This is intended to be applied in contexts such as the Org agenda habit +graph where faithfulness to the semantics of a color value is of +paramount importance. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-graph-blue-0 nil + "Special subdued blue face for use in graphs. +This is intended to be applied in contexts such as the Org agenda habit +graph where faithfulness to the semantics of a color value is of +paramount importance. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-graph-blue-1 nil + "Special prominent blue face for use in graphs. +This is intended to be applied in contexts such as the Org agenda habit +graph where faithfulness to the semantics of a color value is of +paramount importance. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-graph-magenta-0 nil + "Special subdued magenta face for use in graphs. +This is intended to be applied in contexts such as the Org agenda habit +graph where faithfulness to the semantics of a color value is of +paramount importance. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-graph-magenta-1 nil + "Special prominent magenta face for use in graphs. +This is intended to be applied in contexts such as the Org agenda habit +graph where faithfulness to the semantics of a color value is of +paramount importance. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-graph-cyan-0 nil + "Special subdued cyan face for use in graphs. +This is intended to be applied in contexts such as the Org agenda habit +graph where faithfulness to the semantics of a color value is of +paramount importance. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-graph-cyan-1 nil + "Special prominent cyan face for use in graphs. +This is intended to be applied in contexts such as the Org agenda habit +graph where faithfulness to the semantics of a color value is of +paramount importance. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-lang-note nil + "Generic face for linter or spell checker notes. +The exact attributes and color combinations are controlled by +`modus-themes-lang-checkers'. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-lang-warning nil + "Generic face for linter or spell checker warnings. +The exact attributes and color combinations are controlled by +`modus-themes-lang-checkers'. + +The actual styling of the face is done by `modus-themes-faces'.") + +(defface modus-theme-lang-error nil + "Generic face for linter or spell checker errors. +The exact attributes and color combinations are controlled by +`modus-themes-lang-checkers'. + +The actual styling of the face is done by `modus-themes-faces'.") + + + +;;; Customization options + +;;;; Current customization options (>= 1.0.0) + +(defcustom modus-themes-operandi-color-overrides nil + "Override colors in the Modus Operandi palette. + +For form, see `modus-themes-operandi-colors'." + :group 'modus-themes + :package-version '(modus-themes . "1.1.0") + :version "28.1" + :type '(alist :key-type symbol :value-type color) + :link '(info-link "(modus-themes) Override colors (DIY)")) + +(defcustom modus-themes-vivendi-color-overrides nil + "Override colors in the Modus Vivendi palette. + +For form, see `modus-themes-vivendi-colors'." + :group 'modus-themes + :package-version '(modus-themes . "1.1.0") + :version "28.1" + :type '(alist :key-type symbol :value-type color) + :link '(info-link "(modus-themes) Override colors (DIY)")) + +;; The byte compiler complains when a defcustom isn't a top level form +(let* ((names (mapcar (lambda (pair) + (symbol-name (car pair))) + modus-themes-operandi-colors)) + (colors (mapcar #'intern (sort names #'string<)))) + (put 'modus-themes-operandi-color-overrides + 'custom-options (copy-sequence colors)) + (put 'modus-themes-vivendi-color-overrides + 'custom-options (copy-sequence colors))) + +(defcustom modus-themes-slanted-constructs nil + "Use slanted text in more code constructs (italics or oblique)." + :group 'modus-themes + :package-version '(modus-themes . "1.0.0") + :version "28.1" + :type 'boolean + :link '(info-link "(modus-themes) Slanted constructs")) + +(defcustom modus-themes-bold-constructs nil + "Use bold text in more code constructs." + :group 'modus-themes + :package-version '(modus-themes . "1.0.0") + :version "28.1" + :type 'boolean + :link '(info-link "(modus-themes) Bold constructs")) + +(defcustom modus-themes-variable-pitch-headings nil + "Use proportional fonts (variable-pitch) in headings." + :group 'modus-themes + :package-version '(modus-themes . "1.0.0") + :version "28.1" + :type 'boolean + :link '(info-link "(modus-themes) Headings' typeface")) + +(defcustom modus-themes-variable-pitch-ui nil + "Use proportional fonts (variable-pitch) in UI elements. +This includes the mode line, header line, tab bar, and tab line." + :group 'modus-themes + :package-version '(modus-themes . "1.1.0") + :version "28.1" + :type 'boolean + :link '(info-link "(modus-themes) UI typeface")) + +(defcustom modus-themes-no-mixed-fonts nil + "Disable inheritance from `fixed-pitch' in some faces. + +This is done by default to allow spacing-sensitive constructs, +such as Org tables and code blocks, to remain monospaced when +users opt for something like the command `variable-pitch-mode'. +The downside with the default is that users need to explicitly +configure the font family of `fixed-pitch' in order to get a +consistent experience. That may be something they do not want to +do. Hence this option to disable any kind of technique for +mixing fonts." + :group 'modus-themes + :package-version '(modus-themes . "1.0.0") + :version "28.1" + :type 'boolean + :link '(info-link "(modus-themes) No mixed fonts")) + +(defcustom modus-themes-headings + '((t . nil)) + "Alist of styles for headings, with optional value per level. + +To control faces per level from 1-8, use something like this: + + (setq modus-themes-headings + '((1 . highlight) + (2 . line) + (t . rainbow-line-no-bold))) + +To set a uniform value for all heading levels, use this pattern: + + (setq modus-themes-headings + '((t . rainbow-line-no-bold))) + +The default uses a fairly desaturated foreground value in +combination with a bold typographic weight. To specify this +style for a given level N (assuming you wish to have another +fallback option), just specify the value t like this: + + (setq modus-themes-headings + '((1 . t) + (2 . line) + (t . rainbow-line-no-bold))) + +A description of all possible values: + ++ `no-bold' retains the default text color while removing the + typographic weight. + ++ `line' is the same as the default plus an overline over the + heading. + ++ `line-no-bold' is the same as `line' without bold weight. + ++ `rainbow' uses a more colorful foreground in combination with + bold weight. + ++ `rainbow-line' is the same as `rainbow' plus an overline. + ++ `rainbow-line-no-bold' is the same as `rainbow-line' without + the bold weight. + ++ `highlight' retains the default style of a fairly desaturated + foreground combined with a bold weight and add to it a subtle + accented background. + ++ `highlight-no-bold' is the same as `highlight' without a bold + weight. + ++ `rainbow-highlight' is the same as `highlight' but with a more + colorful foreground. + ++ `rainbow-highlight-no-bold' is the same as `rainbow-highlight' + without a bold weight. + ++ `section' retains the default looks and adds to them both an + overline and a slightly accented background. It is, in effect, + a combination of the `line' and `highlight' values. + ++ `section-no-bold' is the same as `section' without a bold + weight. + ++ `rainbow-section' is the same as `section' but with a more + colorful foreground. + ++ `rainbow-section-no-bold' is the same as `rainbow-section' + without a bold weight. + ++ `no-color' does not apply any color to the heading, meaning + that it uses the foreground of the `default' face. It still + renders the text with a bold typographic weight. + ++ `no-color-no-bold' is like `no-color' but without the bold + weight." + :group 'modus-themes + :package-version '(modus-themes . "1.2.0") + :version "28.1" + :type + '(alist + :key-type symbol + :value-type + (choice (const :tag "Fairly desaturated foreground with bold weight (default)" t) + (const :tag "Like the default without bold weight" no-bold) + (const :tag "Like the default plus overline" line) + (const :tag "Like `line' without bold weight" line-no-bold) + (const :tag "Like the default but with more colorful foreground" rainbow) + (const :tag "Like `rainbow' plus overline" rainbow-line) + (const :tag "Like `rainbow' without bold weight" rainbow-no-bold) + (const :tag "Like `rainbow-line' without bold weight" rainbow-line-no-bold) + (const :tag "Like the default plus subtle background" highlight) + (const :tag "Like `highlight' without bold weight" highlight-no-bold) + (const :tag "Like `highlight' with more colorful foreground" rainbow-highlight) + (const :tag "Like `rainbow-highlight' without bold weight" rainbow-highlight-no-bold) + (const :tag "Like `highlight' plus overline" section) + (const :tag "Like `section' without bold weight" section-no-bold) + (const :tag "Like `section' with more colorful foreground" rainbow-section) + (const :tag "Like `rainbow-section' without bold weight" rainbow-section-no-bold) + (const :tag "Do not use any distinct foreground color; just bold weight" no-color) + (const :tag "Like `no-bold' but without the distinct foreground color" no-color-no-bold))) + :link '(info-link "(modus-themes) Heading styles")) + +(defcustom modus-themes-scale-headings nil + "Use font scaling for headings. + +For regular headings the scale is controlled by the variables +`modus-themes-scale-1' (smallest) and its variants all the way up +to `modus-themes-scale-4' (larger). While `modus-themes-scale-5' +is reserved for special headings that must be the largest on the +scale. + +A special heading is, in this context, one that does not fit into +the syntax for heading levels that apply to the given mode. For +example, Org's #+title keyword lies outside the normal eight +levels of headings. Whereas, say, Markdown does not have such a +special heading." + :group 'modus-themes + :package-version '(modus-themes . "1.2.0") + :version "28.1" + :type 'boolean + :link '(info-link "(modus-themes) Scaled headings")) + +(defcustom modus-themes-scale-1 1.05 + "Font size that is slightly larger than the base value. + +This size is used for level 4 headings, such as in Org and +Markdown files. + +The default value is a floating point that is interpreted as a +multiple of the base font size. It is recommended to use such a +value. + +However, the variable also accepts an integer, understood as an +absolute height that is 1/10 of the typeface's point size (e.g. a +value of 140 is the same as setting the font at 14 point size). +This will ignore the base font size and, thus, will not scale in +accordance with it in cases where it changes, such as while using +`text-scale-adjust'." + :group 'modus-themes + :package-version '(modus-themes . "1.2.0") + :version "28.1" + :type 'number + :link '(info-link "(modus-themes) Scaled heading sizes")) + +(defcustom modus-themes-scale-2 1.1 + "Font size slightly larger than `modus-themes-scale-1'. + +This size is used for level 3 headings, such as in Org and +Markdown files. + +The default value is a floating point that is interpreted as a +multiple of the base font size. It is recommended to use such a +value. + +However, the variable also accepts an integer, understood as an +absolute height that is 1/10 of the typeface's point size (e.g. a +value of 140 is the same as setting the font at 14 point size). +This will ignore the base font size and, thus, will not scale in +accordance with it in cases where it changes, such as while using +`text-scale-adjust'." + :group 'modus-themes + :package-version '(modus-themes . "1.2.0") + :version "28.1" + :type 'number + :link '(info-link "(modus-themes) Scaled heading sizes")) + +(defcustom modus-themes-scale-3 1.15 + "Font size slightly larger than `modus-themes-scale-2'. + +This size is used for level 2 headings, such as in Org and +Markdown files. + +The default value is a floating point that is interpreted as a +multiple of the base font size. It is recommended to use such a +value. + +However, the variable also accepts an integer, understood as an +absolute height that is 1/10 of the typeface's point size (e.g. a +value of 140 is the same as setting the font at 14 point size). +This will ignore the base font size and, thus, will not scale in +accordance with it in cases where it changes, such as while using +`text-scale-adjust'." + :group 'modus-themes + :package-version '(modus-themes . "1.2.0") + :version "28.1" + :type 'number + :link '(info-link "(modus-themes) Scaled heading sizes")) + +(defcustom modus-themes-scale-4 1.2 + "Font size slightly larger than `modus-themes-scale-3'. + +This size is used for level 1 headings, such as in Org and +Markdown files. + +The default value is a floating point that is interpreted as a +multiple of the base font size. It is recommended to use such a +value. + +However, the variable also accepts an integer, understood as an +absolute height that is 1/10 of the typeface's point size (e.g. a +value of 140 is the same as setting the font at 14 point size). +This will ignore the base font size and, thus, will not scale in +accordance with it in cases where it changes, such as while using +`text-scale-adjust'." + :group 'modus-themes + :package-version '(modus-themes . "1.2.0") + :version "28.1" + :type 'number + :link '(info-link "(modus-themes) Scaled heading sizes")) + +(defcustom modus-themes-scale-5 1.3 + "Font size slightly larger than `modus-themes-scale-4'. + +This size is only used for 'special' top level headings, such as +Org's file title heading, denoted by the #+title key word, and +the Org agenda structure headers. + +The default value is a floating point that is interpreted as a +multiple of the base font size. It is recommended to use such a +value. + +However, the variable also accepts an integer, understood as an +absolute height that is 1/10 of the typeface's point size (e.g. a +value of 140 is the same as setting the font at 14 point size). +This will ignore the base font size and, thus, will not scale in +accordance with it in cases where it changes, such as while using +`text-scale-adjust'." + :group 'modus-themes + :package-version '(modus-themes . "1.2.0") + :version "28.1" + :type 'number + :link '(info-link "(modus-themes) Scaled heading sizes")) + +(defcustom modus-themes-fringes nil + "Define the visibility of fringes. + +Nil means the fringes have no background color. Option `subtle' +will apply a greyscale value that is visible yet close to the +main buffer background color. Option `intense' will use a more +pronounced greyscale value." + :group 'modus-themes + :package-version '(modus-themes . "1.0.0") + :version "28.1" + :type '(choice + (const :tag "No visible fringes (default)" nil) + (const :tag "Subtle greyscale background" subtle) + (const :tag "Intense greyscale background" intense)) + :link '(info-link "(modus-themes) Fringes")) + +(defcustom modus-themes-lang-checkers nil + "Control the style of spelling and code checkers/linters. + +Nil (the default) applies a color-coded underline to the affected +text, while it leaves the original foreground in tact. If the +display spec of Emacs has support for it, the underline's style +is that of a wave, otherwise it is a straight line. + +Options `subtle-foreground' and `intense-foreground' add a +color-coded underline while also changing the text's foreground +accordingly. The style of the underline is the same as with the +default option. + +Option `straight-underline' is like the default but always +applies a straight line under the affected text. Same principle +for `subtle-foreground-straight-underline' and its counterpart +`intense-foreground-straight-underline'. + +Option `colored-background' uses a straight underline, a +background, and a foreground. All are color-coded. This is the +most intense combination of face properties." + :group 'modus-themes + :package-version '(modus-themes . "1.1.0") + :version "28.1" + :type '(choice + (const :tag "Only color-coded wavy underline (default)" nil) + (const :tag "Like the default, but with a straight underline" straight-underline) + (const :tag "Color-coded wavy underline; subtle foreground" subtle-foreground) + (const :tag "Combines `straight-underline' and `subtle-foreground'" subtle-foreground-straight-underline) + (const :tag "Color-coded wavy underline; intense foreground" intense-foreground) + (const :tag "Combines `straight-underline' and `intense-foreground'" intense-foreground-straight-underline) + (const :tag "Color-coded background, foreground, straight underline" colored-background)) + :link '(info-link "(modus-themes) Language checkers")) + +(defcustom modus-themes-org-blocks nil + "Use a subtle gray or color-coded background for Org blocks. + +Nil means that the block will have no background of its own and +will use the default that applies to the rest of the buffer. + +Option `grayscale' (or `greyscale') will apply a subtle neutral +gray background to the block's contents. It also affects the +begin and end lines of the block: their background will be +extended to the edge of the window for Emacs version >= 27 where +the ':extend' keyword is recognized by `set-face-attribute'. + +Option `rainbow' will use an accented background for the contents +of the block. The exact color will depend on the programming +language and is controlled by the `org-src-block-faces' +variable (refer to the theme's source code for the current +association list)." + :group 'modus-themes + :package-version '(modus-themes . "1.0.0") + :version "28.1" + :type '(choice + (const :tag "No Org block background (default)" nil) + (const :tag "Subtle gray block background" grayscale) + (const :tag "Subtle gray block background (alt spelling)" greyscale) + (const :tag "Color-coded background per programming language" rainbow)) + :link '(info-link "(modus-themes) Org mode blocks")) + +(defcustom modus-themes-org-habit nil + "Control the presentation of the `org-habit' graph. + +The default is meant to conform with the original aesthetic of +`org-habit'. It employs all four color codes that correspond to +the org-habit states---clear, ready, alert, and overdue---while +distinguishing between their present and future variants. This +results in a total of eight colors in use: red, yellow, green, +blue, in tinted and shaded versions. They cover the full set of +information provided by the `org-habit' consistency graph. + +Option `simplified' is like the default except that it removes +the dichotomy between current and future variants by applying +uniform color-coded values. It applies a total of four colors: +red, yellow, green, blue. They produce a simplified consistency +graph that is more legible (or less \"busy\") than the default. +The intent is to shift focus towards the distinction between the +four states of a habit task, rather than each state's +present/future outlook. + +Option `traffic-light' further reduces the available colors to +red, yellow, and green. As in `simplified', present and future +variants appear uniformly, but differently from it, the 'clear' +state is rendered in a green hue, instead of the original blue. +This is meant to capture the use-case where a habit task being +\"too early\" is less important than it being \"too late\". The +difference between ready and clear states is attenuated by +painting both of them using shades of green. This option thus +highlights the alert and overdue states." + :group 'modus-themes + :package-version '(modus-themes . "1.1.0") + :version "28.1" + :type '(choice + (const :tag "Respect the original design of org-habit (default)" nil) + (const :tag "Like the default, but do not distinguish between present and future variants" simplified) + (const :tag "Like `simplified', but only use red, yellow, green" traffic-light)) + :link '(info-link "(modus-themes) Org agenda habits")) + +(defcustom modus-themes-mode-line nil + "Adjust the overall style of the mode line. + +Nil is a two-dimensional rectangle with a border around it. The +active and the inactive modelines use different shades of +greyscale values for the background and foreground. + +A `3d' value will apply a three-dimensional effect to the active +modeline. The inactive modelines remain two-dimensional and are +toned down a bit, relative to the nil value. + +The `moody' option is meant to optimize the modeline for use with +the library of the same name. This practically means to remove +the box effect and rely on underline and overline properties +instead. It also tones down the inactive modelines. Despite its +intended purpose, this option can also be used without the +`moody' library. + +The `borderless' option uses the same colors as the default (nil +value), but removes the border effect. This is done by making +the box property use the same color as the background, +effectively blending the two and creating some padding. + +The `borderless-3d' and `borderless-moody' approximate the `3d' +and `moody' options respectively, while removing the borders. +However, to ensure that the inactive modelines remain visible, +they apply a slightly more prominent background to them than what +their counterparts do (same inactive background as with the +default)." + :group 'modus-themes + :package-version '(modus-themes . "1.0.0") + :version "28.1" + :type '(choice + (const :tag "Two-dimensional box (default)" nil) + (const :tag "Three-dimensional style for the active mode line" 3d) + (const :tag "No box effects, which are optimal for use with the `moody' library" moody) + (const :tag "Like the default, but without border effects" borderless) + (const :tag "Like `3d', but without noticeable border" borderless-3d) + (const :tag "Like `moody', but without noticeable border" borderless-moody)) + :link '(info-link "(modus-themes) Mode line")) + +(defcustom modus-themes-diffs nil + "Adjust the overall styles of diffs. + +Nil means to use fairly intense color combinations for diffs. +For example, you get a rich green background with a green +foreground for added lines. Word-wise or 'refined' diffs follow +the same pattern but use different shades of those colors to +remain distinct. + +A `desaturated' value follows the same principles as with the nil +option, while it tones down all relevant colors. + +Option `fg-only' will remove all accented backgrounds, except +from word-wise changes. It instead uses color-coded foreground +values to differentiate between added/removed/changed lines. If +a background is necessary, such as with `ediff', then a subtle +greyscale value is used. + +Option `bg-only' applies a background but does not override the +text's foreground. This makes it suitable for a non-nil value +passed to `diff-font-lock-syntax' (note: Magit does not support +syntax highlighting in diffs as of 2020-11-25, version +20201116.1057). + +Option `deuteranopia' accounts for red-green color defficiency by +replacing all instances of green with colors on the blue side of +the spectrum. Other stylistic changes are made in the interest +of optimizing for such a use-case." + :group 'modus-themes + :package-version '(modus-themes . "1.2.0") + :version "28.1" + :type '(choice + (const :tag "Intensely colored backgrounds (default)" nil) + (const :tag "Slightly accented backgrounds with tinted text" desaturated) + (const :tag "No backgrounds, except for refined diffs" fg-only) + (const :tag "Apply color-coded backgrounds; keep syntax colors in tact" bg-only) + (const :tag "Optimized for red-green color defficiency" deuteranopia)) + :link '(info-link "(modus-themes) Diffs")) + +(defcustom modus-themes-completions nil + "Apply special styles to the UI of completion frameworks. + +This concerns Icomplete, Ivy, Helm, Selectrum, Ido, as well as +any other tool meant to enhance their experience. The effect +will vary depending on the completion framework. + +Nil means to remain faithful to the metaphors that each UI +establishes. For example, Icomplete and Ido only use foreground +colors to style their matches, whereas Ivy or Helm rely on an +aesthetic that combines colored backgrounds with appropriate text +color. + +Option `moderate' will apply a combination of background and +foreground that is fairly subtle. For Icomplete and the like, +this constitutes a departure from their standard style. While +Ivy, Helm, and the others, will use less pronounced colors for +applicable contexts. + +Option `opinionated' will apply color combinations that refashion +the completion UI. So Icomplete et al will now use styles that +resemble the defaults of Ivy and co., while the latter group will +revert to an even more nuanced aesthetic." + :group 'modus-themes + :package-version '(modus-themes . "1.0.0") + :version "28.1" + :type '(choice + (const :tag "Respect the framework's established aesthetic (default)" nil) + (const :tag "Subtle backgrounds for various elements" moderate) + (const :tag "Radical alternative to the framework's looks" opinionated)) + :link '(info-link "(modus-themes) Completion UIs")) + +(defcustom modus-themes-prompts nil + "Use subtle or intense styles for minibuffer and REPL prompts. + +Nil means to only use an accented foreground color. + +Options `subtle-accented' and `intense-accented' will change both +the background and the foreground values to use accented color +combinations that follow the hue of the default styles' +foreground (e.g. the default minibuffer prompt is cyan text, so +these combinations will involved a cyan background and an +appropriate cyan foreground). + +Options `subtle-gray' and `intense-gray' are like their +`subtle-accented' and `intense-accented' counterparts, except +they use grayscale values instead of accented ones." + :group 'modus-themes + :package-version '(modus-themes . "1.0.0") + :version "28.1" + :type '(choice + ;; `subtle' is the same as `subtle-accented', while `intense' is + ;; equal to `intense-accented' for backward compatibility + (const :tag "No prompt background (default)" nil) + (const :tag "Subtle accented background for the prompt" subtle-accented) + (const :tag "Same as `subtle-accented' for compatibility with older versions" subtle) + (const :tag "Intense accented background and foreground for the prompt" intense-accented) + (const :tag "Same as `intense-accented' for compatibility with older versions" intense) + (const :tag "Like `subtle-accented' but grayscale" subtle-gray) + (const :tag "Like `intense-accented' but grayscale" intense-gray)) + :link '(info-link "(modus-themes) Command prompts")) + +(defcustom modus-themes-intense-hl-line nil + "Use a more prominent background for command `hl-line-mode'." + :group 'modus-themes + :package-version '(modus-themes . "1.0.0") + :version "28.1" + :type 'boolean + :link '(info-link "(modus-themes) Line highlighting")) + +(defcustom modus-themes-subtle-line-numbers nil + "Use more subtle style for command `display-line-numbers-mode'." + :group 'modus-themes + :package-version '(modus-themes . "1.2.0") + :version "28.1" + :type 'boolean + :link '(info-link "(modus-themes) Line numbers")) + +(defcustom modus-themes-paren-match nil + "Choose the style of matching parentheses or delimiters. + +Nil means to use a subtle tinted background color (the default). + +Option `intense' applies a saturated background color. + +Option `subtle-bold' is the same as the default, but also makes +use of bold typographic weight (inherits the `bold' face). + +Option `intense-bold' is the same as `intense', while it also +uses a bold weight." + :group 'modus-themes + :package-version '(modus-themes . "1.0.0") + :version "28.1" + :type '(choice + (const :tag "Sublte tinted background (default)" nil) + (const :tag "Like the default, but also use bold typographic weight" subtle-bold) + (const :tag "Intense saturated background" intense) + (const :tag "Like `intense' but with bold weight" intense-bold)) + :link '(info-link "(modus-themes) Matching parentheses")) + +(defcustom modus-themes-syntax nil + "Control the overall style of code syntax highlighting. + +Nil (the default) means to use colors on the cyan-blue-magenta +side of the spectrum. There is little to no use of greens, +yellows, and reds. + +Option `faint' is like the default in terms of the choice of +palette but applies desaturated color values. + +Option `yellow-comments' applies a yellow tint to comments. The +rest of the syntax is the same as the default. + +Option `green-strings' replaces the blue/cyan/cold color variants +in strings with greener alternatives. The rest of the syntax +remains the same. + +Option `yellow-comments-green-strings' combines yellow comments +with green strings and the rest of the default syntax +highlighting style. + +Option `alt-syntax' expands the color palette and applies new +color combinations. Strings are green. Doc strings are magenta +tinted. Comments are gray. + +Option `alt-syntax-yellow-comments' combines `alt-syntax' with +`yellow-comments'. + +Option `faint-yellow-comments' combines the `faint' style with +`yellow-comments'." + :group 'modus-themes + :package-version '(modus-themes . "1.2.0") + :version "28.1" + :type '(choice + (const :tag "Balanced use of blue, cyan, magenta, purple variants (default)" nil) + (const :tag "Like the default, but with desaturated color values" faint) + (const :tag "Apply yellow tint to comments, keep the default style for the rest" yellow-comments) + (const :tag "Use green for strings, keep the default style for the rest" green-strings) + (const :tag "Use green for strings, yellow for comments, keep the default style for the rest" yellow-comments-green-strings) + (const :tag "Refashion syntax highlighting with more colors, gray comments" alt-syntax) + (const :tag "Like `alt-syntax' but with yellow comments" alt-syntax-yellow-comments) + (const :tag "Like `faint' but with yellow comments" faint-yellow-comments)) + :link '(info-link "(modus-themes) Syntax styles")) + +(defcustom modus-themes-links nil + "Set the style of links. + +Nil means to use an underline that is the same color as the +foreground. + +Option `faint' applies desaturated colors to the link's text and +underline. + +Option `neutral-underline' applies a subtle grey underline, while +retaining the link's foreground. + +Option `faint-neutral-underline' combines a desaturated text +color with a subtle grey underline. + +Option `no-underline' removes link underlines altogether, while +retaining their original fairly vivid color. + +Option `underline-only' applies an underline while making the +affected text colorless (it uses the same foreground as the +theme's default). + +Option `neutral-underline-only' makes the text colorless while +using a subtle underline below it." + :group 'modus-themes + :package-version '(modus-themes . "1.2.0") + :version "28.1" + :type '(choice + (const :tag "Undeline link using the same color as the text (default)" nil) + (const :tag "Like the default, but apply less intense colors to links" faint) + (const :tag "Change the color of link underlines to a neutral grey" neutral-underline) + (const :tag "Desaturated foreground with neutral grey underline" faint-neutral-underline) + (const :tag "Remove underline property from links, keeping their foreground as-is" no-underline) + (const :tag "Apply underline only; use default foreground" underline-only) + (const :tag "Like `underline-only' but with a subtle underline" neutral-underline-only)) + :link '(info-link "(modus-themes) Link styles")) + +(defcustom modus-themes-region nil + "Change the overall appearance of the active region. + +Nil (the default) means to only use a prominent gray background +with a neutral foreground. The foreground overrides all syntax +highlighting. The region extends to the edge of the window. + +Option `no-extend' preserves the default aesthetic but prevents +the region from extending to the edge of the window. + +Option `bg-only' applies a faint tinted background that is +distinct from all others used in the theme, while it does not +override any existing colors. It extends to the edge of the +window. + +Option `bg-only-no-extend' is a combination of the `bg-only' and +`no-extend' options." + :group 'modus-themes + :package-version '(modus-themes . "1.0.0") + :version "28.1" + :type '(choice + (const :tag "Intense background; overrides colors; extends to edge of window (default)" nil) + (const :tag "As with the default, but does not extend" no-extend) + (const :tag "Subtle background; preserves colors; extends to edge of window" bg-only) + (const :tag "As with the `subtle' option, but does not extend" bg-only-no-extend)) + :link '(info-link "(modus-themes) Active region")) + + + +;;;; Deprecated customization options (prior to 1.0.0) + +;;;;; Modus Operandi obsolete options + +(make-obsolete 'modus-operandi-theme-override-colors-alist nil "1.0.0") +(make-obsolete 'modus-operandi-theme-slanted-constructs 'modus-themes-slanted-constructs "1.0.0") +(make-obsolete 'modus-operandi-theme-bold-constructs 'modus-themes-bold-constructs "1.0.0") +(make-obsolete 'modus-operandi-theme-proportional-fonts 'modus-themes-variable-pitch-headings "1.0.0") +(make-obsolete 'modus-operandi-theme-variable-pitch-headings 'modus-themes-variable-pitch-headings "1.0.0") +(make-obsolete 'modus-operandi-theme-no-mixed-fonts 'modus-themes-no-mixed-fonts "1.0.0") +(make-obsolete 'modus-operandi-theme-rainbow-headings 'modus-themes-headings "1.0.0") +(make-obsolete 'modus-operandi-theme-section-headings 'modus-themes-headings "1.0.0") +(make-obsolete 'modus-operandi-theme-headings 'modus-themes-headings "1.0.0") +(make-obsolete 'modus-operandi-theme-scale-headings 'modus-themes-scale-headings "1.0.0") +(make-obsolete 'modus-operandi-theme-scale-1 'modus-themes-scale-1 "1.0.0") +(make-obsolete 'modus-operandi-theme-scale-2 'modus-themes-scale-2 "1.0.0") +(make-obsolete 'modus-operandi-theme-scale-3 'modus-themes-scale-3 "1.0.0") +(make-obsolete 'modus-operandi-theme-scale-4 'modus-themes-scale-4 "1.0.0") +(make-obsolete 'modus-operandi-theme-scale-5 'modus-themes-scale-5 "1.0.0") +(make-obsolete 'modus-operandi-theme-visible-fringes 'modus-themes-fringes "1.0.0") +(make-obsolete 'modus-operandi-theme-fringes 'modus-themes-fringes "1.0.0") +(make-obsolete 'modus-operandi-theme-distinct-org-blocks 'modus-themes-org-blocks "1.0.0") +(make-obsolete 'modus-operandi-theme-rainbow-org-src-blocks 'modus-themes-org-blocks "1.0.0") +(make-obsolete 'modus-operandi-theme-org-blocks 'modus-themes-org-blocks "1.0.0") +(make-obsolete 'modus-operandi-theme-3d-modeline 'modus-themes-mode-line "1.0.0") +(make-obsolete 'modus-operandi-theme-mode-line 'modus-themes-mode-line "1.0.0") +(make-obsolete 'modus-operandi-theme-subtle-diffs 'modus-themes-diffs "1.0.0") +(make-obsolete 'modus-operandi-theme-diffs 'modus-themes-diffs "1.0.0") +(make-obsolete 'modus-operandi-theme-intense-standard-completions 'modus-themes-completions "1.0.0") +(make-obsolete 'modus-operandi-theme-completions 'modus-themes-completions "1.0.0") +(make-obsolete 'modus-operandi-theme-prompts 'modus-themes-prompts "1.0.0") +(make-obsolete 'modus-operandi-theme-intense-hl-line 'modus-themes-intense-hl-line "1.0.0") +(make-obsolete 'modus-operandi-theme-intense-paren-match 'modus-themes-paren-match "1.0.0") +(make-obsolete 'modus-operandi-theme-faint-syntax 'modus-themes-syntax "1.0.0") +(make-obsolete 'modus-operandi-theme-comments 'modus-themes-syntax "1.0.0") +(make-obsolete 'modus-operandi-theme-syntax 'modus-themes-syntax "1.0.0") +(make-obsolete 'modus-operandi-theme-no-link-underline 'modus-themes-links "1.0.0") +(make-obsolete 'modus-operandi-theme-links 'modus-themes-links "1.0.0") + +;;;;; Modus Vivendi obsolete options + +(make-obsolete 'modus-vivendi-theme-override-colors-alist nil "1.0.0") +(make-obsolete 'modus-vivendi-theme-slanted-constructs 'modus-themes-slanted-constructs "1.0.0") +(make-obsolete 'modus-vivendi-theme-bold-constructs 'modus-themes-bold-constructs "1.0.0") +(make-obsolete 'modus-vivendi-theme-proportional-fonts 'modus-themes-variable-pitch-headings "1.0.0") +(make-obsolete 'modus-vivendi-theme-variable-pitch-headings 'modus-themes-variable-pitch-headings "1.0.0") +(make-obsolete 'modus-vivendi-theme-no-mixed-fonts 'modus-themes-no-mixed-fonts "1.0.0") +(make-obsolete 'modus-vivendi-theme-rainbow-headings 'modus-themes-headings "1.0.0") +(make-obsolete 'modus-vivendi-theme-section-headings 'modus-themes-headings "1.0.0") +(make-obsolete 'modus-vivendi-theme-headings 'modus-themes-headings "1.0.0") +(make-obsolete 'modus-vivendi-theme-scale-headings 'modus-themes-scale-headings "1.0.0") +(make-obsolete 'modus-vivendi-theme-scale-1 'modus-themes-scale-1 "1.0.0") +(make-obsolete 'modus-vivendi-theme-scale-2 'modus-themes-scale-2 "1.0.0") +(make-obsolete 'modus-vivendi-theme-scale-3 'modus-themes-scale-3 "1.0.0") +(make-obsolete 'modus-vivendi-theme-scale-4 'modus-themes-scale-4 "1.0.0") +(make-obsolete 'modus-vivendi-theme-scale-5 'modus-themes-scale-5 "1.0.0") +(make-obsolete 'modus-vivendi-theme-visible-fringes 'modus-themes-fringes "1.0.0") +(make-obsolete 'modus-vivendi-theme-fringes 'modus-themes-fringes "1.0.0") +(make-obsolete 'modus-vivendi-theme-distinct-org-blocks 'modus-themes-org-blocks "1.0.0") +(make-obsolete 'modus-vivendi-theme-rainbow-org-src-blocks 'modus-themes-org-blocks "1.0.0") +(make-obsolete 'modus-vivendi-theme-org-blocks 'modus-themes-org-blocks "1.0.0") +(make-obsolete 'modus-vivendi-theme-3d-modeline 'modus-themes-mode-line "1.0.0") +(make-obsolete 'modus-vivendi-theme-mode-line 'modus-themes-mode-line "1.0.0") +(make-obsolete 'modus-vivendi-theme-subtle-diffs 'modus-themes-diffs "1.0.0") +(make-obsolete 'modus-vivendi-theme-diffs 'modus-themes-diffs "1.0.0") +(make-obsolete 'modus-vivendi-theme-intense-standard-completions 'modus-themes-completions "1.0.0") +(make-obsolete 'modus-vivendi-theme-completions 'modus-themes-completions "1.0.0") +(make-obsolete 'modus-vivendi-theme-prompts 'modus-themes-prompts "1.0.0") +(make-obsolete 'modus-vivendi-theme-intense-hl-line 'modus-themes-intense-hl-line "1.0.0") +(make-obsolete 'modus-vivendi-theme-intense-paren-match 'modus-themes-paren-match "1.0.0") +(make-obsolete 'modus-vivendi-theme-faint-syntax 'modus-themes-syntax "1.0.0") +(make-obsolete 'modus-vivendi-theme-comments 'modus-themes-syntax "1.0.0") +(make-obsolete 'modus-vivendi-theme-syntax 'modus-themes-syntax "1.0.0") +(make-obsolete 'modus-vivendi-theme-no-link-underline 'modus-themes-links "1.0.0") +(make-obsolete 'modus-vivendi-theme-links 'modus-themes-links "1.0.0") + + + +;;; Internal functions + +(defun modus-themes--palette (theme) + "Return color palette for Modus theme THEME. +THEME is a symbol, either `modus-operandi' or `modus-vivendi'." + (pcase theme + ('modus-operandi + (append modus-themes-operandi-color-overrides + modus-themes-operandi-colors)) + ('modus-vivendi + (append modus-themes-vivendi-color-overrides + modus-themes-vivendi-colors)) + (_theme + (error "'%s' is not a Modus theme" theme)))) + +(defvar modus-themes-faces) +(defvar modus-themes-custom-variables) + +(defmacro modus-themes-theme (name) + "Bind NAME's color palette around face specs and variables. + +NAME should be the proper name of a Modus theme, either +`modus-operandi' or `modus-vivendi'. + +Face specifications are passed to `custom-theme-set-faces'. +While variables are handled by `custom-theme-set-variables'. +Those are stored in `modus-themes-faces' and +`modus-themes-custom-variables' respectively." + (declare (indent 0)) + (let ((palette-sym (gensym)) + (colors (mapcar #'car modus-themes-operandi-colors))) + `(let* ((class '((class color) (min-colors 89))) + (,palette-sym (modus-themes--palette ',name)) + ,@(mapcar (lambda (color) + (list color `(alist-get ',color ,palette-sym))) + colors)) + (custom-theme-set-faces ',name ,@modus-themes-faces) + (custom-theme-set-variables ',name ,@modus-themes-custom-variables)))) + +(defun modus-themes--current-theme () + "Return current theme." + (car custom-enabled-themes)) + +;; Helper functions that are meant to ease the implementation of the +;; above customization options. +(defun modus-themes--bold-weight () + "Conditional use of a heavier text weight." + (when modus-themes-bold-constructs + (list :inherit 'bold))) + +(defun modus-themes--mixed-fonts () + "Conditional application of `fixed-pitch' inheritance." + (unless modus-themes-no-mixed-fonts + (list :inherit 'fixed-pitch))) + +(defun modus-themes--slant () + "Conditional use of italics for slant attribute." + (if modus-themes-slanted-constructs + (list 'italic) + (list 'normal))) + +(defun modus-themes--variable-pitch () + "Conditional use of `variable-pitch' in headings." + (when modus-themes-variable-pitch-headings + (list :inherit 'variable-pitch))) + +(defun modus-themes--variable-pitch-ui () + "Conditional use of `variable-pitch' in UI elements." + (when modus-themes-variable-pitch-ui + (list :inherit 'variable-pitch))) + +(defun modus-themes--fringe (mainbg subtlebg intensebg) + "Conditional use of background colors for fringes. +MAINBG is the default. SUBTLEBG should be a subtle greyscale +value. INTENSEBG must be a more pronounced greyscale color." + (pcase modus-themes-fringes + ('intense (list :background intensebg)) + ('subtle (list :background subtlebg)) + (_ (list :background mainbg)))) + +(defun modus-themes--line-numbers (mainfg mainbg altfg &optional altbg) + "Conditional use of colors for line numbers. +MAINBG and MAINFG are the default colors. ALTFG is a color that +combines with the theme's primary background (white/black)." + (if modus-themes-subtle-line-numbers + (list :background (or altbg 'unspecified) :foreground altfg) + (list :background mainbg :foreground mainfg))) + +(defun modus-themes--lang-check (underline subtlefg intensefg bg) + "Conditional use of foreground colors for language checkers. +UNDERLINE is a color-code value for the affected text's underline +property. SUBTLEFG and INTENSEFG follow the same color-coding +pattern and represent a value that is faint or vibrant +respectively. BG is a color-coded background." + (pcase modus-themes-lang-checkers + ('colored-background + (list :underline underline :background bg :foreground intensefg)) + ('intense-foreground + (list :underline (list :color underline :style 'wave) :foreground intensefg)) + ('intense-foreground-straight-underline + (list :underline underline :foreground intensefg)) + ('subtle-foreground + (list :underline (list :color underline :style 'wave) :foreground subtlefg)) + ('subtle-foreground-straight-underline + (list :underline underline :foreground subtlefg)) + ('straight-underline + (list :underline underline)) + (_ (list :underline (list :color underline :style 'wave))))) + +(defun modus-themes--prompt (mainfg subtlebg subtlefg intensebg intensefg) + "Conditional use of background colors for prompts. +MAINFG is the prompt's standard foreground. SUBTLEBG should be a +subtle accented background that works with SUBTLEFG. INTENSEBG +must be a more pronounced accented color that should be +combinable with INTENSEFG." + (pcase modus-themes-prompts + ;; `subtle' is the same as `subtle-accented', while `intense' is + ;; equal to `intense-accented' for backward compatibility + ('intense-accented (list :background intensebg :foreground intensefg)) + ('intense (list :background intensebg :foreground intensefg)) + ('subtle-accented (list :background subtlebg :foreground subtlefg)) + ('subtle (list :background subtlebg :foreground subtlefg)) + ('subtle-gray (list :inherit 'modus-theme-subtle-neutral)) + ('intense-gray (list :inherit 'modus-theme-intense-neutral)) + (_ (list :background nil :foreground mainfg)))) + +(defun modus-themes--paren (normalbg intensebg) + "Conditional use of intense colors for matching parentheses. +NORMALBG should be the special palette color 'bg-paren-match' or +something similar. INTENSEBG must be easier to discern next to +other backgrounds, such as the special palette color +'bg-paren-match-intense'." + (pcase modus-themes-paren-match + ('subtle-bold (list :inherit 'bold :background normalbg)) + ('intense-bold (list :inherit 'bold :background intensebg)) + ('intense (list :background intensebg)) + (_ (list :background normalbg)))) + +(defun modus-themes--syntax-foreground (fg faint) + "Apply foreground value to code syntax. +FG is the default. FAINT is typically the same color in its +desaturated version." + (pcase modus-themes-syntax + ('faint (list :foreground faint)) + ('faint-yellow-comments (list :foreground faint)) + (_ (list :foreground fg)))) + +(defun modus-themes--syntax-extra (fg faint alt) + "Apply foreground value to code syntax. +FG is the default. FAINT is typically the same color in its +desaturated version. ALT is another hue." + (pcase modus-themes-syntax + ('faint (list :foreground faint)) + ('faint-yellow-comments (list :foreground faint)) + ('alt-syntax (list :foreground alt)) + ('alt-syntax-yellow-comments (list :foreground alt)) + (_ (list :foreground fg)))) + +(defun modus-themes--syntax-string (fg faint green alt) + "Apply foreground value to strings in code syntax. +FG is the default. FAINT is typically the same color in its +desaturated version. GREEN is a color variant in that side of +the spectrum. ALT is another hue." + (pcase modus-themes-syntax + ('faint (list :foreground faint)) + ('faint-yellow-comments (list :foreground faint)) + ('green-strings (list :foreground green)) + ('yellow-comments-green-strings (list :foreground alt)) + ('alt-syntax (list :foreground alt)) + ('alt-syntax-yellow-comments (list :foreground alt)) + (_ (list :foreground fg)))) + +(defun modus-themes--syntax-docstring (fg faint green alt) + "Apply foreground value to strings in code syntax. +FG is the default. FAINT is typically the same color in its +desaturated version. GREEN is a color variant in that side of +the spectrum. ALT is another hue." + (pcase modus-themes-syntax + ('faint (list :foreground faint)) + ('faint-yellow-comments (list :foreground faint)) + ('green-strings (list :foreground green)) + ('yellow-comments-green-strings (list :foreground green)) + ('alt-syntax (list :foreground alt)) + ('alt-syntax-yellow-comments (list :foreground alt)) + (_ (list :foreground fg)))) + +(defun modus-themes--syntax-comment (fg yellow) + "Apply foreground value to strings in code syntax. +FG is the default. YELLOW is a color variant of that name." + (pcase modus-themes-syntax + ('yellow-comments (list :foreground yellow)) + ('yellow-comments-green-strings (list :foreground yellow)) + ('alt-syntax-yellow-comments (list :foreground yellow)) + ('faint-yellow-comments (list :foreground yellow)) + (_ (list :foreground fg)))) + +(defun modus-themes--heading-p (key) + "Query style of KEY in `modus-themes-headings'." + (cdr (assoc key modus-themes-headings))) + +(defun modus-themes--heading (level fg fg-alt bg border) + "Conditional styles for `modus-themes-headings'. + +LEVEL is the heading's position in their order. FG is the +default text color. FG-ALT is an accented, more saturated value +than the default. BG is a nuanced, typically accented, +background that can work well with either of the foreground +values. BORDER is a color value that combines well with the +background and alternative foreground." + (let* ((key (modus-themes--heading-p `,level)) + (style (or key (modus-themes--heading-p t))) + (var (when modus-themes-variable-pitch-headings + 'variable-pitch)) + (varbold (if var + (append (list 'bold) (list var)) + 'bold))) + (pcase style + ('no-bold + (list :inherit `,var :foreground fg)) + ('no-color + (list :inherit `,varbold)) + ('no-color-no-bold + (list :inherit `,var)) + ('line + (list :inherit `,varbold :foreground fg :overline border)) + ('line-no-bold + (list :inherit `,var :foreground fg :overline border)) + ('rainbow + (list :inherit `,varbold :foreground fg-alt)) + ('rainbow-no-bold + (list :inherit `,var :foreground fg-alt)) + ('rainbow-line + (list :inherit `,varbold :foreground fg-alt :overline border)) + ('rainbow-line-no-bold + (list :inherit `,var :foreground fg-alt :overline border)) + ('highlight + (list :inherit `,varbold :background bg :foreground fg)) + ('highlight-no-bold + (list :inherit `,var :background bg :foreground fg)) + ('rainbow-highlight + (list :inherit `,varbold :background bg :foreground fg-alt)) + ('rainbow-highlight-no-bold + (list :inherit `,var :background bg :foreground fg-alt)) + ('section + (list :inherit `,varbold :background bg :foreground fg :overline border :extend t)) + ('section-no-bold + (list :inherit `,var :background bg :foreground fg :overline border :extend t)) + ('rainbow-section + (list :inherit `,varbold :background bg :foreground fg-alt :overline border :extend t)) + ('rainbow-section-no-bold + (list :inherit `,var :background bg :foreground fg-alt :overline border :extend t)) + (_ + (list :inherit `,varbold :foreground fg))))) + +(defun modus-themes--org-block (bgblk) + "Conditionally set the background of Org blocks. +BGBLK applies to a distinct neutral background. Else blocks have +no background of their own (the default), so they look the same +as the rest of the buffer. + +`modus-themes-org-blocks' also accepts a `rainbow' option +which is applied conditionally to `org-src-block-faces' (see the +theme's source code)." + (if (or (eq modus-themes-org-blocks 'grayscale) + (eq modus-themes-org-blocks 'greyscale)) + (list :background bgblk :extend t) + (list :background 'unspecified))) + +(defun modus-themes--org-block-delim (bgaccent fgaccent bg fg) + "Conditionally set the styles of Org block delimiters. +BG, FG, BGACCENT, FGACCENT apply a background and foreground +color respectively. + +The former pair is a greyscale combination that should be more +distinct than the background of the block. It is applied to the +default styles or when `modus-themes-org-blocks' is set +to `greyscale'. + +The latter pair should be more subtle than the background of the +block, as it is used when `modus-themes-org-blocks' is +set to `rainbow'." + (pcase modus-themes-org-blocks + ('grayscale (list :background bg :foreground fg :extend t)) + ('greyscale (list :background bg :foreground fg :extend t)) + ('rainbow (list :background bgaccent :foreground fgaccent)) + (_ (list :background bg :foreground fg)))) + +(defun modus-themes--org-habit (default &optional traffic simple) + "Specify background values for `modus-themes-org-habit'. +If no optional TRAFFIC argument is supplied, the DEFAULT is used +instead. Same for SIMPLE." + (pcase modus-themes-org-habit + ('traffic-light (list :background (or traffic default))) + ('simplified (list :background (or simple default))) + (_ (list :background default)))) + +(defun modus-themes--mode-line-attrs + (fg bg fg-alt bg-alt border border-3d &optional alt-style border-width fg-distant) + "Color combinations for `modus-themes-mode-line'. + +FG and BG are the default colors. FG-ALT and BG-ALT are meant to +accommodate the options for a 3D modeline or a `moody' compliant +one. BORDER applies to all permutations of the modeline, except +the three-dimensional effect, where BORDER-3D is used instead. + +Optional ALT-STYLE applies an appropriate style to the mode +line's box property. + +Optional BORDER-WIDTH specifies an integer for the width of the +rectangle that produces the box effect. + +Optional FG-DISTANT should be close to the main background +values. It is intended to be used as a distant-foreground +property." + (pcase modus-themes-mode-line + ('3d + `(:background ,bg-alt :foreground ,fg-alt + :box (:line-width ,(or border-width 1) + :color ,border-3d + :style ,(and alt-style 'released-button)))) + ('moody + `(:background ,bg-alt :foreground ,fg-alt + :underline ,border :overline ,border + :distant-foreground ,fg-distant)) + ('borderless + `(:foreground ,fg :background ,bg :box ,bg)) + ('borderless-3d + `(:foreground ,fg :background ,bg + :box (:line-width ,(or border-width 1) + :color ,bg + :style ,(and alt-style 'released-button)))) + ('borderless-moody + `(:background ,bg :foreground ,fg + :underline ,bg :overline ,bg + :distant-foreground ,fg-distant)) + (_ + `(:foreground ,fg :background ,bg :box ,border)))) + +(defun modus-themes--diff + (fg-only-bg fg-only-fg mainbg mainfg altbg altfg &optional deuteranbg deuteranfg bg-only-fg) + "Color combinations for `modus-themes-diffs'. + +FG-ONLY-BG should be similar or the same as the main background. +FG-ONLY-FG should be a saturated accent value that can be +combined with the former. + +MAINBG must be one of the dedicated backgrounds for diffs while +MAINFG must be the same for the foreground. + +ALTBG needs to be a slightly accented background that is meant to +be combined with ALTFG. Both must be less intense than MAINBG +and MAINFG respectively. + +DEUTERANBG and DEUTERANFG must be combinations of colors that account +for red-green color defficiency (deuteranopia). + +Optional BG-ONLY-FG applies ALTFG else leaves the foreground +unspecified." + (pcase modus-themes-diffs + ('fg-only (list :background fg-only-bg :foreground fg-only-fg)) + ('desaturated (list :background altbg :foreground altfg)) + ('deuteranopia (list :background (or deuteranbg mainbg) :foreground (or deuteranfg mainfg))) + ('bg-only (list :background altbg :foreground (if bg-only-fg altfg 'unspecified))) + (_ (list :background mainbg :foreground mainfg)))) + +(defun modus-themes--diff-deuteran (deuteran main) + "Determine whether the DEUTERAN or MAIN color should be used. +This is based on whether `modus-themes-diffs' has the value +`deuteranopia'." + (if (eq modus-themes-diffs 'deuteranopia) + (list deuteran) + (list main))) + +(defun modus-themes--diff-text (fg-only-fg default-fg) + "Like `modus-themes--diff', but only for foregrounds. +FG-ONLY-FG is the foreground that is used when diffs are styled +using only foreground colors. DEFAULT-FG covers all other +cases." + (pcase modus-themes-diffs + ('fg-only (list :foreground fg-only-fg)) + ('bg-only (list :foreground 'unspecified)) + (_ (list :foreground default-fg)))) + +(defun modus-themes--standard-completions (mainfg subtlebg intensebg intensefg) + "Combinations for `modus-themes-completions'. + +MAINFG is an accented foreground value. SUBTLEBG is an accented +background value that can be combined with MAINFG. INTENSEBG and +INTENSEFG are accented colors that are designed to be used in +tandem. + +These are intended for Icomplete, Ido, and related." + (pcase modus-themes-completions + ('opinionated (list :background intensebg :foreground intensefg)) + ('moderate (list :background subtlebg :foreground mainfg)) + (_ (list :foreground mainfg)))) + +(defun modus-themes--extra-completions (subtleface intenseface altface &optional altfg bold) + "Combinations for `modus-themes-completions'. + +SUBTLEFACE and INTENSEFACE are custom theme faces that combine a +background and foreground value. The difference between the two +is a matter of degree. + +ALTFACE is a combination of colors that represents a departure +from the UI's default aesthetics. Optional ALTFG is meant to be +used in tandem with it. + +Optional BOLD will apply a heavier weight to the text. + +These are intended for Helm, Ivy, etc." + (pcase modus-themes-completions + ('opinionated (list :inherit (list altface bold) + :foreground (or altfg 'unspecified))) + ('moderate (list :inherit (list subtleface bold))) + (_ (list :inherit (list intenseface bold))))) + +(defun modus-themes--link (fg fgfaint underline) + "Conditional application of link styles. +FG is the link's default color for its text and underline +property. FGFAINT is a desaturated color for the text and +underline. UNDERLINE is a grey color only for the undeline." + (pcase modus-themes-links + ('faint (list :foreground fgfaint :underline t)) + ('neutral-underline (list :foreground fg :underline underline)) + ('faint-neutral-underline (list :foreground fgfaint :underline underline)) + ('no-underline (list :foreground fg :underline nil)) + ('underline-only (list :underline t)) + ('neutral-underline-only (list :underline underline)) + (_ (list :foreground fg :underline t)))) + +(defun modus-themes--link-color (fg fgfaint &optional neutralfg) + "Extends `modus-themes--link'. +FG is the main accented foreground. FGFAINT is also accented, +yet desaturated. Optional NEUTRALFG is a gray value." + (pcase modus-themes-links + ('faint (list :foreground fgfaint)) + ('faint-neutral-underline (list :foreground fgfaint)) + ('underline-only (list :underline t :foreground (or neutralfg 'unspecified))) + ('neutral-underline-only (list :underline 'unspecified :foreground (or neutralfg 'unspecified))) + (_ (list :foreground fg)))) + +(defun modus-themes--scale (amount) + "Scale heading by AMOUNT. +AMOUNT is a customization option." + (when modus-themes-scale-headings + (list :height amount))) + +(defun modus-themes--region (bg fg bgsubtle) + "Apply `modus-themes-region' styles. + +BG and FG are the main values that are used by default. BGSUBTLE +is a subtle background value that can be combined with all colors +used to fontify text and code syntax." + (pcase modus-themes-region + ('bg-only (list :background bgsubtle)) + ('bg-only-no-extend (list :background bgsubtle :extend nil)) + ('no-extend (list :background bg :foreground fg :extend nil)) + (_ (list :background bg :foreground fg)))) + + + +;;;; Utilities for DIY users + +;; This is the WCAG formula: https://www.w3.org/TR/WCAG20-TECHS/G18.html +(defun modus-themes-wcag-formula (hex) + "Get WCAG value of color value HEX. +The value is defined in hexadecimal RGB notation, such as those in +`modus-themes-operandi-colors' and `modus-themes-vivendi-colors'." + (cl-loop for k in '(0.2126 0.7152 0.0722) + for x in (color-name-to-rgb hex) + sum (* k (if (<= x 0.03928) + (/ x 12.92) + (expt (/ (+ x 0.055) 1.055) 2.4))))) + +;;;###autoload +(defun modus-themes-contrast (c1 c2) + "Measure WCAG contrast ratio between C1 and C2. +C1 and C2 are color values written in hexadecimal RGB." + (let ((ct (/ (+ (modus-themes-wcag-formula c1) 0.05) + (+ (modus-themes-wcag-formula c2) 0.05)))) + (max ct (/ ct)))) + +(defun modus-themes-current-palette () + "Return current color palette." + (modus-themes--palette (modus-themes--current-theme))) + +;;;###autoload +(defun modus-themes-color (color) + "Return color value for COLOR from current palette. +COLOR is a key in `modus-themes-operandi-colors' or +`modus-themes-vivendi-colors'." + (alist-get color (modus-themes-current-palette))) + +;;;###autoload +(defun modus-themes-color-alts (light-color dark-color) + "Return color value from current palette. +When Modus Operandi is enabled, return color value for color +LIGHT-COLOR. When Modus Vivendi is enabled, return color value +for DARK-COLOR. LIGHT-COLOR and DARK-COLOR are keys in +`modus-themes-operandi-colors' or `modus-themes-vivendi-colors'." + (let* ((theme (modus-themes--current-theme)) + (color (pcase theme + ('modus-operandi light-color) + ('modus-vivendi dark-color) + (_theme + (error "'%s' is not a Modus theme" theme))))) + (alist-get color (modus-themes--palette theme)))) + +(defmacro modus-themes-with-colors (&rest body) + "Evaluate BODY with colors from current palette bound. +For colors bound, see `modus-themes-operandi-colors' or +`modus-themes-vivendi-colors'." + (declare (indent 0)) + (let ((palette-sym (gensym)) + (colors (mapcar #'car modus-themes-operandi-colors))) + `(let* ((class '((class color) (min-colors 89))) + (,palette-sym (modus-themes-current-palette)) + ,@(mapcar (lambda (color) + (list color `(alist-get ',color ,palette-sym))) + colors)) + (ignore class ,@colors) ; Silence unused variable warnings + ,@body))) + + + +;;;; Commands + +;;;###autoload +(defun modus-themes-load-themes () + "Ensure that the Modus themes are in `custom-enabled-themes'. + +This function is intended for use in package declarations such as +those defined with the help of `use-package'. The idea is to add +this function to the `:init' stage of the package's loading, so +that subsequent calls that assume the presence of a loaded theme, +like `modus-themes-toggle' or `modus-themes-load-operandi', will +continue to work as intended even if they are lazy-loaded (such +as when they are declared in the `:config' phase)." + (unless (or (custom-theme-p 'modus-operandi) + (custom-theme-p 'modus-vivendi)) + (load-theme 'modus-operandi t t) + (load-theme 'modus-vivendi t t))) + +(defvar modus-themes-after-load-theme-hook nil + "Hook that runs after the `modus-themes-toggle' routines.") + +;; The reason we use `load-theme' instead of `enable-theme' is that the +;; former does a kind of "reset" on the face specs. So it plays nicely +;; with `custom-set-faces', as well as defcustom user customizations, +;; including the likes of `modus-themes-operandi-color-overrides'. +;; +;; Tests show that `enable-theme' does not re-read those variables, so +;; it might appear to the unsuspecting user that the themes are somehow +;; broken. +;; +;; This "reset", however, comes at the cost of being a bit slower than +;; `enable-theme'. User who have a stable setup and seldom update their +;; variables during a given Emacs session, are better off using +;; something like this: +;; +;; (defun modus-themes-toggle-enabled () +;; "Toggle between `modus-operandi' and `modus-vivendi' themes." +;; (interactive) +;; (pcase (modus-themes--current-theme) +;; ('modus-operandi (progn (enable-theme 'modus-vivendi) +;; (disable-theme 'modus-operandi))) +;; ('modus-vivendi (progn (enable-theme 'modus-operandi) +;; (disable-theme 'modus-vivendi))) +;; (_ (error "No Modus theme is loaded; evaluate `modus-themes-load-themes' first")))) + +;;;###autoload +(defun modus-themes-load-operandi () + "Load `modus-operandi' and disable `modus-vivendi'. +Also run `modus-themes-after-load-theme-hook'." + (disable-theme 'modus-vivendi) + (load-theme 'modus-operandi t) + (run-hooks 'modus-themes-after-load-theme-hook)) + +;;;###autoload +(defun modus-themes-load-vivendi () + "Load `modus-vivendi' and disable `modus-operandi'. +Also run `modus-themes-after-load-theme-hook'." + (disable-theme 'modus-operandi) + (load-theme 'modus-vivendi t) + (run-hooks 'modus-themes-after-load-theme-hook)) + +(defun modus-themes--load-prompt () + "Helper for `modus-themes-toggle'." + (let ((theme + (intern + (completing-read "Load Modus theme (will disable all others): " + '(modus-operandi modus-vivendi) nil t)))) + (mapc #'disable-theme custom-enabled-themes) + (pcase theme + ('modus-operandi (modus-themes-load-operandi)) + ('modus-vivendi (modus-themes-load-vivendi))))) + +;;;###autoload +(defun modus-themes-toggle () + "Toggle between `modus-operandi' and `modus-vivendi' themes. +Also runs `modus-themes-after-load-theme-hook' at its last stage +by virtue of calling either of `modus-themes-load-operandi' and +`modus-themes-load-vivendi' functions." + (interactive) + (modus-themes-load-themes) + (pcase (modus-themes--current-theme) + ('modus-operandi (modus-themes-load-vivendi)) + ('modus-vivendi (modus-themes-load-operandi)) + (_ (modus-themes--load-prompt)))) + + + +;;;; Face specifications + +(defconst modus-themes-faces + '( +;;;; custom faces + ;; these bespoke faces are inherited by other constructs below +;;;;; subtle colored backgrounds + `(modus-theme-subtle-red ((,class :background ,red-subtle-bg :foreground ,fg-dim))) + `(modus-theme-subtle-green ((,class :background ,green-subtle-bg :foreground ,fg-dim))) + `(modus-theme-subtle-yellow ((,class :background ,yellow-subtle-bg :foreground ,fg-dim))) + `(modus-theme-subtle-blue ((,class :background ,blue-subtle-bg :foreground ,fg-dim))) + `(modus-theme-subtle-magenta ((,class :background ,magenta-subtle-bg :foreground ,fg-dim))) + `(modus-theme-subtle-cyan ((,class :background ,cyan-subtle-bg :foreground ,fg-dim))) + `(modus-theme-subtle-neutral ((,class :background ,bg-inactive :foreground ,fg-inactive))) +;;;;; intense colored backgrounds + `(modus-theme-intense-red ((,class :background ,red-intense-bg :foreground ,fg-main))) + `(modus-theme-intense-green ((,class :background ,green-intense-bg :foreground ,fg-main))) + `(modus-theme-intense-yellow ((,class :background ,yellow-intense-bg :foreground ,fg-main))) + `(modus-theme-intense-blue ((,class :background ,blue-intense-bg :foreground ,fg-main))) + `(modus-theme-intense-magenta ((,class :background ,magenta-intense-bg :foreground ,fg-main))) + `(modus-theme-intense-cyan ((,class :background ,cyan-intense-bg :foreground ,fg-main))) + `(modus-theme-intense-neutral ((,class :background ,bg-active :foreground ,fg-main))) +;;;;; refined background and foreground combinations + ;; general purpose styles that use an accented foreground against an + ;; accented background + `(modus-theme-refine-red ((,class :background ,red-refine-bg :foreground ,red-refine-fg))) + `(modus-theme-refine-green ((,class :background ,green-refine-bg :foreground ,green-refine-fg))) + `(modus-theme-refine-yellow ((,class :background ,yellow-refine-bg :foreground ,yellow-refine-fg))) + `(modus-theme-refine-blue ((,class :background ,blue-refine-bg :foreground ,blue-refine-fg))) + `(modus-theme-refine-magenta ((,class :background ,magenta-refine-bg :foreground ,magenta-refine-fg))) + `(modus-theme-refine-cyan ((,class :background ,cyan-refine-bg :foreground ,cyan-refine-fg))) +;;;;; "active" combinations, mostly for use on the mode line + `(modus-theme-active-red ((,class :background ,red-active :foreground ,bg-active))) + `(modus-theme-active-green ((,class :background ,green-active :foreground ,bg-active))) + `(modus-theme-active-yellow ((,class :background ,yellow-active :foreground ,bg-active))) + `(modus-theme-active-blue ((,class :background ,blue-active :foreground ,bg-active))) + `(modus-theme-active-magenta ((,class :background ,magenta-active :foreground ,bg-active))) + `(modus-theme-active-cyan ((,class :background ,cyan-active :foreground ,bg-active))) +;;;;; nuanced backgrounds + ;; useful for adding an accented background that is suitable for all + ;; main foreground colors (intended for use in Org source blocks) + `(modus-theme-nuanced-red ((,class :background ,red-nuanced-bg :extend t))) + `(modus-theme-nuanced-green ((,class :background ,green-nuanced-bg :extend t))) + `(modus-theme-nuanced-yellow ((,class :background ,yellow-nuanced-bg :extend t))) + `(modus-theme-nuanced-blue ((,class :background ,blue-nuanced-bg :extend t))) + `(modus-theme-nuanced-magenta ((,class :background ,magenta-nuanced-bg :extend t))) + `(modus-theme-nuanced-cyan ((,class :background ,cyan-nuanced-bg :extend t))) +;;;;; fringe-specific combinations + `(modus-theme-fringe-red ((,class :background ,red-fringe-bg :foreground ,fg-main))) + `(modus-theme-fringe-green ((,class :background ,green-fringe-bg :foreground ,fg-main))) + `(modus-theme-fringe-yellow ((,class :background ,yellow-fringe-bg :foreground ,fg-main))) + `(modus-theme-fringe-blue ((,class :background ,blue-fringe-bg :foreground ,fg-main))) + `(modus-theme-fringe-magenta ((,class :background ,magenta-fringe-bg :foreground ,fg-main))) + `(modus-theme-fringe-cyan ((,class :background ,cyan-fringe-bg :foreground ,fg-main))) +;;;;; special base values + ;; these are closer to the grayscale than the accents defined above + ;; and should only be used when the next closest alternative would be + ;; a greyscale value than an accented one + `(modus-theme-special-cold ((,class :background ,bg-special-cold :foreground ,fg-special-cold))) + `(modus-theme-special-mild ((,class :background ,bg-special-mild :foreground ,fg-special-mild))) + `(modus-theme-special-warm ((,class :background ,bg-special-warm :foreground ,fg-special-warm))) + `(modus-theme-special-calm ((,class :background ,bg-special-calm :foreground ,fg-special-calm))) +;;;;; diff-specific combinations + ;; intended for `diff-mode' or equivalent + `(modus-theme-diff-added + ((,class ,@(modus-themes--diff + bg-main green + bg-diff-focus-added fg-diff-focus-added + green-nuanced-bg fg-diff-added + bg-diff-focus-added-deuteran fg-diff-focus-added-deuteran)))) + `(modus-theme-diff-changed + ((,class ,@(modus-themes--diff + bg-main yellow + bg-diff-focus-changed fg-diff-focus-changed + yellow-nuanced-bg fg-diff-changed)))) + `(modus-theme-diff-removed + ((,class ,@(modus-themes--diff + bg-main red + bg-diff-focus-removed fg-diff-focus-removed + red-nuanced-bg fg-diff-removed)))) + `(modus-theme-diff-refine-added + ((,class ,@(modus-themes--diff + bg-diff-added fg-diff-added + bg-diff-refine-added fg-diff-refine-added + bg-diff-focus-added fg-diff-focus-added + bg-diff-refine-added-deuteran fg-diff-refine-added-deuteran)))) + `(modus-theme-diff-refine-changed + ((,class ,@(modus-themes--diff + bg-diff-changed fg-diff-changed + bg-diff-refine-changed fg-diff-refine-changed + bg-diff-focus-changed fg-diff-focus-changed)))) + `(modus-theme-diff-refine-removed + ((,class ,@(modus-themes--diff + bg-diff-removed fg-diff-removed + bg-diff-refine-removed fg-diff-refine-removed + bg-diff-focus-removed fg-diff-focus-removed)))) + `(modus-theme-diff-focus-added + ((,class ,@(modus-themes--diff + bg-dim green + bg-diff-focus-added fg-diff-focus-added + bg-diff-added fg-diff-added + bg-diff-focus-added-deuteran fg-diff-focus-added-deuteran)))) + `(modus-theme-diff-focus-changed + ((,class ,@(modus-themes--diff + bg-dim yellow + bg-diff-focus-changed fg-diff-focus-changed + bg-diff-changed fg-diff-changed)))) + `(modus-theme-diff-focus-removed + ((,class ,@(modus-themes--diff + bg-dim red + bg-diff-focus-removed fg-diff-focus-removed + bg-diff-removed fg-diff-removed)))) + `(modus-theme-diff-heading + ((,class ,@(modus-themes--diff + bg-main blue + bg-diff-heading fg-diff-heading + cyan-nuanced-bg cyan-nuanced-fg + bg-header fg-main + t)))) +;;;;; mark indicators + ;; color combinations intended for Dired, Ibuffer, or equivalent + `(modus-theme-pseudo-header ((,class :inherit bold :foreground ,fg-main))) + `(modus-theme-mark-alt ((,class :inherit bold :background ,bg-mark-alt :foreground ,fg-mark-alt))) + `(modus-theme-mark-del ((,class :inherit bold :background ,bg-mark-del :foreground ,fg-mark-del))) + `(modus-theme-mark-sel ((,class :inherit bold :background ,bg-mark-sel :foreground ,fg-mark-sel))) + `(modus-theme-mark-symbol ((,class :inherit bold :foreground ,blue-alt))) +;;;;; heading levels + ;; styles for regular headings used in Org, Markdown, Info, etc. + `(modus-theme-heading-1 + ((,class ,@(modus-themes--heading + 1 fg-main magenta-alt-other magenta-nuanced-bg bg-region) + ,@(modus-themes--scale modus-themes-scale-4)))) + `(modus-theme-heading-2 + ((,class ,@(modus-themes--heading + 2 fg-special-warm magenta-alt red-nuanced-bg bg-region) + ,@(modus-themes--scale modus-themes-scale-3)))) + `(modus-theme-heading-3 + ((,class ,@(modus-themes--heading + 3 fg-special-cold blue blue-nuanced-bg bg-region) + ,@(modus-themes--scale modus-themes-scale-2)))) + `(modus-theme-heading-4 + ((,class ,@(modus-themes--heading + 4 fg-special-mild cyan cyan-nuanced-bg bg-region) + ,@(modus-themes--scale modus-themes-scale-1)))) + `(modus-theme-heading-5 + ((,class ,@(modus-themes--heading + 5 fg-special-calm green-alt-other green-nuanced-bg bg-region)))) + `(modus-theme-heading-6 + ((,class ,@(modus-themes--heading + 6 yellow-nuanced-fg yellow-alt-other yellow-nuanced-bg bg-region)))) + `(modus-theme-heading-7 + ((,class ,@(modus-themes--heading + 7 red-nuanced-fg red-alt red-nuanced-bg bg-region)))) + `(modus-theme-heading-8 + ((,class ,@(modus-themes--heading + 8 fg-dim magenta bg-alt bg-region)))) +;;;;; graph-specific faces + `(modus-theme-graph-red-0 ((,class :background ,red-graph-0-bg))) + `(modus-theme-graph-red-1 ((,class :background ,red-graph-1-bg))) + `(modus-theme-graph-green-0 ((,class :background ,green-graph-0-bg))) + `(modus-theme-graph-green-1 ((,class :background ,green-graph-1-bg))) + `(modus-theme-graph-yellow-0 ((,class :background ,yellow-graph-0-bg))) + `(modus-theme-graph-yellow-1 ((,class :background ,yellow-graph-1-bg))) + `(modus-theme-graph-blue-0 ((,class :background ,blue-graph-0-bg))) + `(modus-theme-graph-blue-1 ((,class :background ,blue-graph-1-bg))) + `(modus-theme-graph-magenta-0 ((,class :background ,magenta-graph-0-bg))) + `(modus-theme-graph-magenta-1 ((,class :background ,magenta-graph-1-bg))) + `(modus-theme-graph-cyan-0 ((,class :background ,cyan-graph-0-bg))) + `(modus-theme-graph-cyan-1 ((,class :background ,cyan-graph-1-bg))) +;;;;; language checkers + `(modus-theme-lang-error ((,class ,@(modus-themes--lang-check fg-lang-underline-error fg-lang-error red red-nuanced-bg)))) + `(modus-theme-lang-note ((,class ,@(modus-themes--lang-check fg-lang-underline-note fg-lang-note blue-alt blue-nuanced-bg)))) + `(modus-theme-lang-warning ((,class ,@(modus-themes--lang-check fg-lang-underline-warning fg-lang-warning yellow yellow-nuanced-bg)))) +;;;;; other custom faces + `(modus-theme-bold ((,class ,@(modus-themes--bold-weight)))) + `(modus-theme-hl-line ((,class :background ,(if modus-themes-intense-hl-line + bg-hl-line-intense bg-hl-line) + :extend t))) + `(modus-theme-slant ((,class :inherit italic :slant ,@(modus-themes--slant)))) + `(modus-theme-variable-pitch ((,class ,@(modus-themes--variable-pitch)))) +;;;; standard faces +;;;;; absolute essentials + `(default ((,class :background ,bg-main :foreground ,fg-main))) + `(cursor ((,class :background ,fg-main))) + `(fringe ((,class ,@(modus-themes--fringe bg-main bg-inactive bg-active) + :foreground ,fg-main))) + `(vertical-border ((,class :foreground ,fg-window-divider-inner))) +;;;;; basic and/or ungrouped styles + `(bold ((,class :weight bold))) + `(bold-italic ((,class :inherit (bold italic)))) + `(buffer-menu-buffer ((,class :inherit bold))) + `(comint-highlight-input ((,class :inherit bold))) + `(comint-highlight-prompt ((,class :inherit modus-theme-bold + ,@(modus-themes--prompt + cyan + blue-nuanced-bg blue-alt + blue-refine-bg fg-main)))) + `(error ((,class :inherit bold :foreground ,red))) + `(escape-glyph ((,class :foreground ,fg-escape-char-construct))) + `(file-name-shadow ((,class :foreground ,fg-unfocused))) + `(header-line ((,class ,@(modus-themes--variable-pitch-ui) + :background ,bg-header :foreground ,fg-header))) + `(header-line-highlight ((,class :inherit modus-theme-active-blue))) + `(help-argument-name ((,class :inherit modus-theme-slant :foreground ,cyan))) + `(homoglyph ((,class :foreground ,red-alt-faint))) + `(ibuffer-locked-buffer ((,class :foreground ,yellow-alt-other-faint))) + `(italic ((,class :slant italic))) + `(nobreak-hyphen ((,class :foreground ,fg-escape-char-construct))) + `(nobreak-space ((,class :foreground ,fg-escape-char-construct :underline t))) + `(minibuffer-prompt ((,class ,@(modus-themes--prompt + cyan-alt-other + cyan-nuanced-bg cyan + cyan-refine-bg fg-main)))) + `(mm-command-output ((,class :foreground ,red-alt-other))) + `(mm-uu-extract ((,class :background ,bg-dim :foreground ,fg-special-mild))) + `(next-error ((,class :inherit modus-theme-subtle-red))) + `(rectangle-preview ((,class :inherit modus-theme-special-mild))) + `(region ((,class ,@(modus-themes--region bg-region fg-main bg-hl-alt-intense)))) + `(secondary-selection ((,class :inherit modus-theme-special-cold))) + `(shadow ((,class :foreground ,fg-alt))) + `(success ((,class :inherit bold :foreground ,green))) + `(trailing-whitespace ((,class :background ,red-intense-bg))) + `(warning ((,class :inherit bold :foreground ,yellow))) +;;;;; buttons, links, widgets + `(button ((,class ,@(modus-themes--link + blue-alt-other blue-alt-other-faint bg-region)))) + `(link ((,class :inherit button))) + `(link-visited ((,class :inherit button + ,@(modus-themes--link-color + magenta-alt-other magenta-alt-other-faint fg-alt)))) + `(tooltip ((,class :background ,bg-special-cold :foreground ,fg-main))) + `(widget-button ((,class :inherit button))) + `(widget-button-pressed ((,class :inherit button + ,@(modus-themes--link-color + magenta magenta-faint)))) + `(widget-documentation ((,class :foreground ,green))) + `(widget-field ((,class :background ,bg-alt :foreground ,fg-dim))) + `(widget-inactive ((,class :background ,bg-inactive :foreground ,fg-inactive))) + `(widget-single-line-field ((,class :inherit widget-field))) +;;;;; ag + `(ag-hit-face ((,class :foreground ,fg-special-cold))) + `(ag-match-face ((,class :inherit modus-theme-special-calm))) +;;;;; alert + `(alert-high-face ((,class :inherit bold :foreground ,red-alt))) + `(alert-low-face ((,class :foreground ,fg-special-mild))) + `(alert-moderate-face ((,class :inherit bold :foreground ,yellow))) + `(alert-trivial-face ((,class :foreground ,fg-special-calm))) + `(alert-urgent-face ((,class :inherit bold :foreground ,red-intense))) +;;;;; all-the-icons + `(all-the-icons-blue ((,class :foreground ,blue))) + `(all-the-icons-blue-alt ((,class :foreground ,blue-alt))) + `(all-the-icons-cyan ((,class :foreground ,cyan))) + `(all-the-icons-cyan-alt ((,class :foreground ,cyan-alt))) + `(all-the-icons-dblue ((,class :foreground ,blue-alt-other))) + `(all-the-icons-dcyan ((,class :foreground ,cyan-alt-other))) + `(all-the-icons-dgreen ((,class :foreground ,green-alt-other))) + `(all-the-icons-dired-dir-face ((,class :foreground ,blue))) + `(all-the-icons-dmaroon ((,class :foreground ,magenta-alt-other))) + `(all-the-icons-dorange ((,class :foreground ,red-alt-other))) + `(all-the-icons-dpink ((,class :foreground ,magenta))) + `(all-the-icons-dpurple ((,class :foreground ,magenta-alt))) + `(all-the-icons-dred ((,class :foreground ,red))) + `(all-the-icons-dsilver ((,class :foreground ,fg-special-cold))) + `(all-the-icons-dyellow ((,class :foreground ,yellow))) + `(all-the-icons-green ((,class :foreground ,green))) + `(all-the-icons-lblue ((,class :foreground ,blue-refine-fg))) + `(all-the-icons-lcyan ((,class :foreground ,cyan-refine-fg))) + `(all-the-icons-lgreen ((,class :foreground ,green-refine-fg))) + `(all-the-icons-lmaroon ((,class :foreground ,magenta-refine-fg))) + `(all-the-icons-lorange ((,class :foreground ,red-refine-fg))) + `(all-the-icons-lpink ((,class :foreground ,magenta-refine-fg))) + `(all-the-icons-lpurple ((,class :foreground ,magenta-refine-fg))) + `(all-the-icons-lred ((,class :foreground ,red-refine-fg))) + `(all-the-icons-lsilver ((,class :foreground ,fg-special-cold))) + `(all-the-icons-lyellow ((,class :foreground ,yellow-refine-fg))) + `(all-the-icons-maroon ((,class :foreground ,magenta))) + `(all-the-icons-orange ((,class :foreground ,red-alt))) + `(all-the-icons-pink ((,class :foreground ,magenta))) + `(all-the-icons-purple ((,class :foreground ,magenta-alt))) + `(all-the-icons-purple-alt ((,class :foreground ,magenta-alt-other))) + `(all-the-icons-red ((,class :foreground ,red))) + `(all-the-icons-red-alt ((,class :foreground ,red-alt))) + `(all-the-icons-silver ((,class :foreground ,fg-special-cold))) + `(all-the-icons-yellow ((,class :foreground ,yellow))) +;;;;; annotate + `(annotate-annotation ((,class :inherit modus-theme-subtle-blue))) + `(annotate-annotation-secondary ((,class :inherit modus-theme-subtle-green))) + `(annotate-highlight ((,class :background ,blue-nuanced-bg :underline ,blue-intense))) + `(annotate-highlight-secondary ((,class :background ,green-nuanced-bg :underline ,green-intense))) +;;;;; anzu + `(anzu-match-1 ((,class :inherit modus-theme-subtle-cyan))) + `(anzu-match-2 ((,class :inherit modus-theme-subtle-green))) + `(anzu-match-3 ((,class :inherit modus-theme-subtle-yellow))) + `(anzu-mode-line ((,class :inherit bold :foreground ,green-active))) + `(anzu-mode-line-no-match ((,class :inherit bold :foreground ,red-active))) + `(anzu-replace-highlight ((,class :inherit modus-theme-refine-yellow :underline t))) + `(anzu-replace-to ((,class :inherit (modus-theme-intense-green bold)))) +;;;;; apropos + `(apropos-function-button ((,class :inherit button + ,@(modus-themes--link-color + magenta-alt-other magenta-alt-other-faint)))) + `(apropos-keybinding ((,class :inherit bold :foreground ,cyan))) + `(apropos-misc-button ((,class :inherit button + ,@(modus-themes--link-color + cyan-alt-other cyan-alt-other-faint)))) + `(apropos-property ((,class :inherit modus-theme-bold :foreground ,magenta-alt))) + `(apropos-symbol ((,class :inherit modus-theme-bold :foreground ,blue-alt-other))) + `(apropos-user-option-button ((,class :inherit button + ,@(modus-themes--link-color + green-alt-other green-alt-other-faint)))) + `(apropos-variable-button ((,class :inherit button + ,@(modus-themes--link-color + blue blue-faint)))) +;;;;; apt-sources-list + `(apt-sources-list-components ((,class :foreground ,cyan))) + `(apt-sources-list-options ((,class :foreground ,yellow))) + `(apt-sources-list-suite ((,class :foreground ,green))) + `(apt-sources-list-type ((,class :foreground ,magenta))) + `(apt-sources-list-uri ((,class :foreground ,blue))) +;;;;; artbollocks-mode + `(artbollocks-face ((,class :inherit modus-theme-lang-note))) + `(artbollocks-lexical-illusions-face ((,class :background ,bg-alt :foreground ,red-alt :underline t))) + `(artbollocks-passive-voice-face ((,class :inherit modus-theme-lang-warning))) + `(artbollocks-weasel-words-face ((,class :inherit modus-theme-lang-error))) +;;;;; auctex and Tex + `(font-latex-bold-face ((,class :inherit bold :foreground ,fg-special-calm))) + `(font-latex-doctex-documentation-face ((,class :inherit modus-theme-slant :foreground ,fg-special-cold))) + `(font-latex-doctex-preprocessor-face ((,class :inherit modus-theme-bold :foreground ,red-alt-other))) + `(font-latex-italic-face ((,class :inherit italic :foreground ,fg-special-calm))) + `(font-latex-math-face ((,class :foreground ,cyan-alt-other))) + `(font-latex-script-char-face ((,class :foreground ,cyan-alt-other))) + `(font-latex-sectioning-0-face ((,class :inherit modus-theme-variable-pitch :foreground ,blue-nuanced-fg))) + `(font-latex-sectioning-1-face ((,class :inherit (bold modus-theme-variable-pitch) :foreground ,blue-nuanced-fg))) + `(font-latex-sectioning-2-face ((,class :inherit (bold modus-theme-variable-pitch) :foreground ,blue-nuanced-fg))) + `(font-latex-sectioning-3-face ((,class :inherit (bold modus-theme-variable-pitch) :foreground ,blue-nuanced-fg))) + `(font-latex-sectioning-4-face ((,class :inherit (bold modus-theme-variable-pitch) :foreground ,blue-nuanced-fg))) + `(font-latex-sectioning-5-face ((,class :inherit modus-theme-variable-pitch :foreground ,blue-nuanced-fg))) + `(font-latex-sedate-face ((,class :inherit modus-theme-bold :foreground ,magenta-alt-other))) + `(font-latex-slide-title-face ((,class :inherit (bold modus-theme-variable-pitch) :foreground ,cyan-nuanced-fg + ,@(modus-themes--scale modus-themes-scale-4)))) + `(font-latex-string-face ((,class :inherit font-lock-string-face))) + `(font-latex-subscript-face ((,class :height 0.95))) + `(font-latex-superscript-face ((,class :height 0.95))) + `(font-latex-verbatim-face ((,class :background ,bg-dim :foreground ,fg-special-mild))) + `(font-latex-warning-face ((,class :inherit font-lock-warning-face))) + `(tex-match ((,class :foreground ,blue-alt-other))) + `(tex-verbatim ((,class :background ,bg-dim :foreground ,fg-special-mild))) + `(texinfo-heading ((,class :foreground ,magenta))) + `(TeX-error-description-error ((,class :inherit error))) + `(TeX-error-description-help ((,class :foreground ,blue))) + `(TeX-error-description-tex-said ((,class :foreground ,blue))) + `(TeX-error-description-warning ((,class :inherit warning))) +;;;;; auto-dim-other-buffers + `(auto-dim-other-buffers-face ((,class :background ,bg-alt))) +;;;;; avy + `(avy-background-face ((,class :background ,bg-dim :foreground ,fg-dim))) + `(avy-goto-char-timer-face ((,class :inherit (modus-theme-intense-yellow bold)))) + `(avy-lead-face ((,class :inherit (modus-theme-intense-magenta bold)))) + `(avy-lead-face-0 ((,class :inherit (modus-theme-intense-blue bold)))) + `(avy-lead-face-1 ((,class :inherit (modus-theme-intense-red bold)))) + `(avy-lead-face-2 ((,class :inherit (modus-theme-intense-green bold)))) +;;;;; aw (ace-window) + `(aw-background-face ((,class :background ,bg-dim :foreground ,fg-dim))) + `(aw-key-face ((,class :inherit bold :foreground ,blue-intense))) + `(aw-leading-char-face ((,class :inherit bold :height 1.5 :slant normal :background ,bg-main :foreground ,red-intense))) + `(aw-minibuffer-leading-char-face ((,class :foreground ,magenta-active))) + `(aw-mode-line-face ((,class :inherit bold))) +;;;;; awesome-tray + `(awesome-tray-module-awesome-tab-face ((,class :inherit bold :foreground ,red-alt-other))) + `(awesome-tray-module-battery-face ((,class :inherit bold :foreground ,cyan-alt-other))) + `(awesome-tray-module-buffer-name-face ((,class :inherit bold :foreground ,yellow-alt-other))) + `(awesome-tray-module-circe-face ((,class :inherit bold :foreground ,blue-alt))) + `(awesome-tray-module-date-face ((,class :inherit bold :foreground ,fg-dim))) + `(awesome-tray-module-evil-face ((,class :inherit bold :foreground ,green-alt))) + `(awesome-tray-module-git-face ((,class :inherit bold :foreground ,magenta))) + `(awesome-tray-module-last-command-face ((,class :inherit bold :foreground ,blue-alt-other))) + `(awesome-tray-module-location-face ((,class :inherit bold :foreground ,yellow))) + `(awesome-tray-module-mode-name-face ((,class :inherit bold :foreground ,green))) + `(awesome-tray-module-parent-dir-face ((,class :inherit bold :foreground ,cyan))) + `(awesome-tray-module-rvm-face ((,class :inherit bold :foreground ,magenta-alt-other))) +;;;;; bbdb + `(bbdb-name ((,class :foreground ,magenta-alt-other))) + `(bbdb-organization ((,class :foreground ,red-alt-other))) + `(bbdb-field-name ((,class :foreground ,cyan-alt-other))) +;;;;; binder + `(binder-sidebar-highlight ((,class :inherit modus-theme-subtle-cyan))) + `(binder-sidebar-marked ((,class :inherit modus-theme-mark-sel))) + `(binder-sidebar-missing ((,class :inherit modus-theme-subtle-red))) + `(binder-sidebar-tags ((,class :foreground ,cyan))) +;;;;; bm + `(bm-face ((,class :inherit modus-theme-subtle-yellow :extend t))) + `(bm-fringe-face ((,class :inherit modus-theme-fringe-yellow))) + `(bm-fringe-persistent-face ((,class :inherit modus-theme-fringe-blue))) + `(bm-persistent-face ((,class :inherit modus-theme-intense-blue :extend t))) +;;;;; bongo + `(bongo-album-title ((,class :foreground ,yellow-active))) + `(bongo-artist ((,class :foreground ,magenta-active))) + `(bongo-currently-playing-track ((,class :inherit bold))) + `(bongo-elapsed-track-part ((,class :inherit modus-theme-subtle-magenta :underline t))) + `(bongo-filled-seek-bar ((,class :background ,blue-intense-bg :foreground ,fg-main))) + `(bongo-marked-track ((,class :foreground ,fg-mark-alt))) + `(bongo-marked-track-line ((,class :background ,bg-mark-alt))) + `(bongo-played-track ((,class :foreground ,fg-unfocused :strike-through t))) + `(bongo-track-length ((,class :foreground ,fg-active))) + `(bongo-track-title ((,class :foreground ,cyan-active))) + `(bongo-unfilled-seek-bar ((,class :background ,bg-special-cold :foreground ,fg-main))) +;;;;; boon + `(boon-modeline-cmd ((,class :inherit modus-theme-active-blue))) + `(boon-modeline-ins ((,class :inherit modus-theme-active-red))) + `(boon-modeline-off ((,class :inherit modus-theme-active-yellow))) + `(boon-modeline-spc ((,class :inherit modus-theme-active-green))) +;;;;; breakpoint (built-in gdb-mi.el) + `(breakpoint-disabled ((,class :inherit shadow))) + `(breakpoint-enabled ((,class :inherit bold :foreground ,red))) +;;;;; buffer-expose + `(buffer-expose-ace-char-face ((,class :inherit bold :foreground ,red-active))) + `(buffer-expose-mode-line-face ((,class :foreground ,cyan-active))) + `(buffer-expose-selected-face ((,class :inherit modus-theme-special-mild))) +;;;;; calendar and diary + `(calendar-month-header ((,class :inherit modus-theme-pseudo-header))) + `(calendar-today ((,class :inherit bold :underline t))) + `(calendar-weekday-header ((,class :inherit shadow))) + `(calendar-weekend-header ((,class :inherit shadow))) + `(diary ((,class :background ,green-nuanced-bg :foreground ,green-alt-other))) + `(diary-anniversary ((,class :foreground ,red-alt-other))) + `(diary-time ((,class :foreground ,blue-alt))) + `(holiday ((,class :background ,magenta-nuanced-bg :foreground ,magenta-alt))) +;;;;; calfw + `(cfw:face-annotation ((,class :foreground ,fg-special-warm))) + `(cfw:face-day-title ((,class :foreground ,fg-main))) + `(cfw:face-default-content ((,class :foreground ,green-alt))) + `(cfw:face-default-day ((,class :inherit (cfw:face-day-title bold)))) + `(cfw:face-disable ((,class :foreground ,fg-unfocused))) + `(cfw:face-grid ((,class :foreground ,fg-window-divider-outer))) + `(cfw:face-header ((,class :inherit bold :foreground ,fg-main))) + `(cfw:face-holiday ((,class :foreground ,magenta-alt-other))) + `(cfw:face-periods ((,class :foreground ,cyan-alt-other))) + `(cfw:face-saturday ((,class :inherit bold :foreground ,cyan-alt-other))) + `(cfw:face-select ((,class :inherit modus-theme-intense-blue))) + `(cfw:face-sunday ((,class :inherit bold :foreground ,cyan-alt-other))) + `(cfw:face-title ((,class :inherit modus-theme-variable-pitch + :foreground ,fg-special-cold + ,@(modus-themes--scale modus-themes-scale-5)))) + `(cfw:face-today ((,class :background ,bg-inactive))) + `(cfw:face-today-title ((,class :background ,bg-active))) + `(cfw:face-toolbar ((,class :background ,bg-alt :foreground ,bg-alt))) + `(cfw:face-toolbar-button-off ((,class :inherit shadow))) + `(cfw:face-toolbar-button-on ((,class :inherit bold :background ,blue-nuanced-bg + :foreground ,blue-alt))) +;;;;; centaur-tabs + `(centaur-tabs-active-bar-face ((,class :background ,fg-tab-active))) + `(centaur-tabs-close-mouse-face ((,class :inherit bold :foreground ,red-active :underline t))) + `(centaur-tabs-close-selected ((,class :inherit centaur-tabs-selected))) + `(centaur-tabs-close-unselected ((,class :inherit centaur-tabs-unselected))) + `(centaur-tabs-modified-marker-selected ((,class :inherit centaur-tabs-selected))) + `(centaur-tabs-modified-marker-unselected ((,class :inherit centaur-tabs-unselected))) + `(centaur-tabs-default ((,class :background ,bg-main :foreground ,bg-main))) + `(centaur-tabs-selected ((,class :inherit bold :background ,bg-tab-active :foreground ,fg-main))) + `(centaur-tabs-selected-modified ((,class :inherit italic :background ,bg-tab-active :foreground ,fg-main))) + `(centaur-tabs-unselected ((,class :background ,bg-tab-inactive :foreground ,fg-dim))) + `(centaur-tabs-unselected-modified ((,class :inherit italic :background ,bg-tab-inactive :foreground ,fg-dim))) +;;;;; cfrs + `(cfrs-border-color ((,class :background ,fg-window-divider-inner))) +;;;;; change-log and log-view (`vc-print-log' and `vc-print-root-log') + `(change-log-acknowledgment ((,class :foreground ,fg-alt))) + `(change-log-conditionals ((,class :foreground ,yellow))) + `(change-log-date ((,class :foreground ,cyan))) + `(change-log-email ((,class :foreground ,cyan-alt-other))) + `(change-log-file ((,class :inherit bold :foreground ,fg-special-cold))) + `(change-log-function ((,class :foreground ,green-alt-other))) + `(change-log-list ((,class :foreground ,magenta-alt))) + `(change-log-name ((,class :foreground ,magenta-alt-other))) + `(log-edit-header ((,class :foreground ,fg-special-warm))) + `(log-edit-summary ((,class :inherit bold :foreground ,blue))) + `(log-edit-unknown-header ((,class :inherit shadow))) + `(log-view-commit-body ((,class :foreground ,blue-nuanced-fg))) + `(log-view-file ((,class :inherit bold :foreground ,fg-special-cold))) + `(log-view-message ((,class :background ,bg-alt :foreground ,fg-alt))) +;;;;; cider + `(cider-debug-code-overlay-face ((,class :background ,bg-alt))) + `(cider-debug-prompt-face ((,class :foreground ,magenta-alt :underline t))) + `(cider-deprecated-face ((,class :inherit modus-theme-refine-yellow))) + `(cider-docview-emphasis-face ((,class :inherit italic :foreground ,fg-special-cold))) + `(cider-docview-literal-face ((,class :foreground ,blue-alt))) + `(cider-docview-strong-face ((,class :inherit bold :foreground ,fg-special-cold))) + `(cider-docview-table-border-face ((,class :inherit shadow))) + `(cider-enlightened-face ((,class :box (:line-width -1 :color ,yellow-alt :style nil) :background ,bg-dim))) + `(cider-enlightened-local-face ((,class :inherit bold :foreground ,yellow-alt-other))) + `(cider-error-highlight-face ((,class :foreground ,red :underline t))) + `(cider-fragile-button-face ((,class :box (:line-width 3 :color ,fg-alt :style released-button) :foreground ,yellow))) + `(cider-fringe-good-face ((,class :foreground ,green-active))) + `(cider-instrumented-face ((,class :box (:line-width -1 :color ,red :style nil) :background ,bg-dim))) + `(cider-reader-conditional-face ((,class :inherit italic :foreground ,fg-special-warm))) + `(cider-repl-input-face ((,class :inherit bold))) + `(cider-repl-prompt-face ((,class :foreground ,cyan-alt-other))) + `(cider-repl-stderr-face ((,class :inherit bold :foreground ,red))) + `(cider-repl-stdout-face ((,class :foreground ,blue))) + `(cider-result-overlay-face ((,class :box (:line-width -1 :color ,blue :style nil) :background ,bg-dim))) + `(cider-stacktrace-error-class-face ((,class :inherit bold :foreground ,red))) + `(cider-stacktrace-error-message-face ((,class :inherit italic :foreground ,red-alt-other))) + `(cider-stacktrace-face ((,class :foreground ,fg-main))) + `(cider-stacktrace-filter-active-face ((,class :foreground ,cyan-alt :underline t))) + `(cider-stacktrace-filter-inactive-face ((,class :foreground ,cyan-alt))) + `(cider-stacktrace-fn-face ((,class :inherit bold :foreground ,fg-main))) + `(cider-stacktrace-ns-face ((,class :inherit italic :foreground ,fg-alt))) + `(cider-stacktrace-promoted-button-face ((,class :box (:line-width 3 :color ,fg-alt :style released-button) :foreground ,red))) + `(cider-stacktrace-suppressed-button-face ((,class :box (:line-width 3 :color ,fg-alt :style pressed-button) + :background ,bg-alt :foreground ,fg-alt))) + `(cider-test-error-face ((,class :inherit modus-theme-subtle-red))) + `(cider-test-failure-face ((,class :inherit (modus-theme-intense-red bold)))) + `(cider-test-success-face ((,class :inherit modus-theme-intense-green))) + `(cider-traced-face ((,class :box (:line-width -1 :color ,cyan :style nil) :background ,bg-dim))) + `(cider-warning-highlight-face ((,class :foreground ,yellow :underline t))) +;;;;; circe (and lui) + `(circe-fool-face ((,class :inherit shadow))) + `(circe-highlight-nick-face ((,class :inherit bold :foreground ,blue))) + `(circe-prompt-face ((,class :inherit bold :foreground ,cyan-alt-other))) + `(circe-server-face ((,class :foreground ,fg-unfocused))) + `(lui-button-face ((,class :inherit button))) + `(lui-highlight-face ((,class :foreground ,magenta-alt))) + `(lui-time-stamp-face ((,class :foreground ,blue-nuanced-fg))) +;;;;; color-rg + `(color-rg-font-lock-column-number ((,class :foreground ,magenta-alt-other))) + `(color-rg-font-lock-command ((,class :inherit bold :foreground ,fg-main))) + `(color-rg-font-lock-file ((,class :inherit bold :foreground ,fg-special-cold))) + `(color-rg-font-lock-flash ((,class :inherit modus-theme-intense-blue))) + `(color-rg-font-lock-function-location ((,class :inherit modus-theme-special-calm))) + `(color-rg-font-lock-header-line-directory ((,class :foreground ,blue-active))) + `(color-rg-font-lock-header-line-edit-mode ((,class :foreground ,magenta-active))) + `(color-rg-font-lock-header-line-keyword ((,class :foreground ,green-active))) + `(color-rg-font-lock-header-line-text ((,class :foreground ,fg-active))) + `(color-rg-font-lock-line-number ((,class :foreground ,fg-special-warm))) + `(color-rg-font-lock-mark-changed ((,class :inherit bold :foreground ,blue))) + `(color-rg-font-lock-mark-deleted ((,class :inherit bold :foreground ,red))) + `(color-rg-font-lock-match ((,class :inherit modus-theme-special-calm))) + `(color-rg-font-lock-position-splitter ((,class :inherit shadow))) +;;;;; column-enforce-mode + `(column-enforce-face ((,class :inherit modus-theme-refine-yellow))) +;;;;; company-mode + `(company-echo-common ((,class :foreground ,magenta-alt-other))) + `(company-preview ((,class :background ,bg-dim :foreground ,fg-dim))) + `(company-preview-common ((,class :foreground ,blue-alt))) + `(company-preview-search ((,class :inherit modus-theme-special-calm))) + `(company-scrollbar-bg ((,class :background ,bg-active))) + `(company-scrollbar-fg ((,class :background ,fg-active))) + `(company-template-field ((,class :inherit modus-theme-intense-magenta))) + `(company-tooltip ((,class :background ,bg-alt :foreground ,fg-alt))) + `(company-tooltip-annotation ((,class :inherit modus-theme-slant :foreground ,fg-special-cold))) + `(company-tooltip-annotation-selection ((,class :inherit bold :foreground ,fg-main))) + `(company-tooltip-common ((,class :inherit bold :foreground ,blue-alt))) + `(company-tooltip-common-selection ((,class :foreground ,fg-main))) + `(company-tooltip-mouse ((,class :inherit modus-theme-intense-blue))) + `(company-tooltip-search ((,class :inherit (modus-theme-refine-cyan bold)))) + `(company-tooltip-search-selection ((,class :inherit (modus-theme-intense-green bold) :underline t))) + `(company-tooltip-selection ((,class :inherit (modus-theme-subtle-cyan bold)))) +;;;;; company-posframe + `(company-posframe-active-backend-name ((,class :inherit bold :background ,bg-active :foreground ,blue-active))) + `(company-posframe-inactive-backend-name ((,class :background ,bg-active :foreground ,fg-active))) + `(company-posframe-metadata ((,class :background ,bg-inactive :foreground ,fg-inactive))) +;;;;; compilation feedback + `(compilation-column-number ((,class :foreground ,magenta-alt-other))) + `(compilation-error ((,class :inherit modus-theme-bold :foreground ,red))) + `(compilation-info ((,class :inherit modus-theme-bold :foreground ,fg-special-cold))) + `(compilation-line-number ((,class :foreground ,fg-special-warm))) + `(compilation-mode-line-exit ((,class :inherit modus-theme-bold :foreground ,blue-active))) + `(compilation-mode-line-fail ((,class :inherit modus-theme-bold :foreground ,red-active))) + `(compilation-mode-line-run ((,class :inherit modus-theme-bold :foreground ,magenta-active))) + `(compilation-warning ((,class :inherit modus-theme-bold :foreground ,yellow))) +;;;;; completions + `(completions-annotations ((,class :inherit modus-theme-slant :foreground ,cyan-faint))) + `(completions-common-part ((,class ,@(modus-themes--standard-completions + blue-alt blue-nuanced-bg + cyan-refine-bg cyan-refine-fg)))) + `(completions-first-difference ((,class :inherit bold + ,@(modus-themes--standard-completions + magenta-alt blue-nuanced-bg + magenta-intense-bg fg-main)))) +;;;;; consult + `(consult-async-running ((,class :inherit bold :foreground ,blue))) + `(consult-async-split ((,class :foreground ,magenta-alt))) + `(consult-bookmark ((,class :foreground ,blue))) + `(consult-file ((,class :foreground ,fg-special-cold))) + `(consult-imenu-prefix ((,class :inherit shadow))) + `(consult-key ((,class :inherit modus-themes-bold :foreground ,magenta-alt-other))) + `(consult-line-number ((,class :foreground ,fg-special-warm))) + `(consult-line-number-prefix ((,class :foreground ,fg-unfocused))) + `(consult-narrow-indicator ((,class :foreground ,magenta-alt))) + `(consult-preview-cursor ((,class :inherit modus-theme-intense-blue))) + `(consult-preview-error ((,class :inherit modus-theme-intense-red))) + `(consult-preview-line ((,class :background ,bg-hl-alt-intense))) +;;;;; counsel + `(counsel-active-mode ((,class :foreground ,magenta-alt-other))) + `(counsel-application-name ((,class :foreground ,red-alt-other))) + `(counsel-key-binding ((,class :inherit bold :foreground ,blue-alt-other))) + `(counsel-outline-1 ((,class :inherit org-level-1))) + `(counsel-outline-2 ((,class :inherit org-level-2))) + `(counsel-outline-3 ((,class :inherit org-level-3))) + `(counsel-outline-4 ((,class :inherit org-level-4))) + `(counsel-outline-5 ((,class :inherit org-level-5))) + `(counsel-outline-6 ((,class :inherit org-level-6))) + `(counsel-outline-7 ((,class :inherit org-level-7))) + `(counsel-outline-8 ((,class :inherit org-level-8))) + `(counsel-outline-default ((,class :foreground ,fg-main))) + `(counsel-variable-documentation ((,class :inherit modus-theme-slant :foreground ,yellow-alt-other))) +;;;;; counsel-css + `(counsel-css-selector-depth-face-1 ((,class :foreground ,blue))) + `(counsel-css-selector-depth-face-2 ((,class :foreground ,cyan))) + `(counsel-css-selector-depth-face-3 ((,class :foreground ,green))) + `(counsel-css-selector-depth-face-4 ((,class :foreground ,yellow))) + `(counsel-css-selector-depth-face-5 ((,class :foreground ,magenta))) + `(counsel-css-selector-depth-face-6 ((,class :foreground ,red))) +;;;;; counsel-notmuch + `(counsel-notmuch-count-face ((,class :foreground ,cyan))) + `(counsel-notmuch-date-face ((,class :foreground ,blue))) + `(counsel-notmuch-people-face ((,class :foreground ,magenta))) + `(counsel-notmuch-subject-face ((,class :foreground ,magenta-alt-other))) +;;;;; counsel-org-capture-string + `(counsel-org-capture-string-template-body-face ((,class :foreground ,fg-special-cold))) +;;;;; cov + `(cov-coverage-not-run-face ((,class :foreground ,red-intense))) + `(cov-coverage-run-face ((,class :foreground ,green-intense))) + `(cov-heavy-face ((,class :foreground ,magenta-intense))) + `(cov-light-face ((,class :foreground ,blue-intense))) + `(cov-med-face ((,class :foreground ,yellow-intense))) + `(cov-none-face ((,class :foreground ,cyan-intense))) +;;;;; cperl-mode + `(cperl-nonoverridable-face ((,class :foreground unspecified))) + `(cperl-array-face ((,class :inherit font-lock-keyword-face))) + `(cperl-hash-face ((,class :inherit font-lock-variable-name-face))) +;;;;; csv-mode + `(csv-separator-face ((,class :background ,bg-special-cold :foreground ,fg-main))) +;;;;; ctrlf + `(ctrlf-highlight-active ((,class :inherit (modus-theme-intense-green bold)))) + `(ctrlf-highlight-line ((,class :inherit modus-theme-hl-line))) + `(ctrlf-highlight-passive ((,class :inherit modus-theme-refine-cyan))) +;;;;; custom (M-x customize) + `(custom-button ((,class :box (:line-width 2 :color nil :style released-button) + :background ,bg-active :foreground ,fg-main))) + `(custom-button-mouse ((,class :box (:line-width 2 :color nil :style released-button) + :background ,bg-active :foreground ,fg-active))) + `(custom-button-pressed ((,class :box (:line-width 2 :color nil :style pressed-button) + :background ,bg-active :foreground ,fg-main))) + `(custom-changed ((,class :inherit modus-theme-subtle-cyan))) + `(custom-comment ((,class :inherit shadow))) + `(custom-comment-tag ((,class :background ,bg-alt :foreground ,yellow-alt-other))) + `(custom-face-tag ((,class :inherit bold :foreground ,blue-intense))) + `(custom-group-tag ((,class :inherit bold :foreground ,green-intense))) + `(custom-group-tag-1 ((,class :inherit modus-theme-special-warm))) + `(custom-invalid ((,class :inherit (modus-theme-intense-red bold)))) + `(custom-modified ((,class :inherit modus-theme-subtle-cyan))) + `(custom-rogue ((,class :inherit modus-theme-refine-magenta))) + `(custom-set ((,class :foreground ,blue-alt))) + `(custom-state ((,class :foreground ,cyan-alt-other))) + `(custom-themed ((,class :inherit modus-theme-subtle-blue))) + `(custom-variable-tag ((,class :inherit bold :foreground ,cyan))) +;;;;; dap-mode + `(dap-mouse-eval-thing-face ((,class :box (:line-width -1 :color ,blue-active :style nil) + :background ,bg-active :foreground ,fg-main))) + `(dap-result-overlay-face ((,class :box (:line-width -1 :color ,bg-active :style nil) + :background ,bg-active :foreground ,fg-main))) + `(dap-ui-breakpoint-verified-fringe ((,class :inherit bold :foreground ,green-active))) + `(dap-ui-compile-errline ((,class :inherit bold :foreground ,red-intense))) + `(dap-ui-locals-scope-face ((,class :inherit bold :foreground ,magenta :underline t))) + `(dap-ui-locals-variable-face ((,class :inherit bold :foreground ,cyan))) + `(dap-ui-locals-variable-leaf-face ((,class :inherit italic :foreground ,cyan-alt-other))) + `(dap-ui-marker-face ((,class :inherit modus-theme-subtle-blue))) + `(dap-ui-sessions-stack-frame-face ((,class :inherit bold :foreground ,magenta-alt))) + `(dap-ui-sessions-terminated-active-face ((,class :inherit bold :foreground ,fg-alt))) + `(dap-ui-sessions-terminated-face ((,class :inherit shadow))) +;;;;; dashboard (emacs-dashboard) + `(dashboard-banner-logo-title ((,class :inherit bold :foreground ,fg-special-cold))) + `(dashboard-footer ((,class :inherit bold :foreground ,fg-special-mild))) + `(dashboard-heading ((,class :inherit bold :foreground ,fg-special-warm))) + `(dashboard-navigator ((,class :foreground ,cyan-alt-other))) + `(dashboard-text-banner ((,class :foreground ,fg-dim))) +;;;;; deadgrep + `(deadgrep-filename-face ((,class :inherit bold :foreground ,fg-special-cold))) + `(deadgrep-match-face ((,class :inherit modus-theme-special-calm))) + `(deadgrep-meta-face ((,class :inherit shadow))) + `(deadgrep-regexp-metachar-face ((,class :inherit bold :foreground ,yellow-intense))) + `(deadgrep-search-term-face ((,class :inherit bold :foreground ,green-intense))) +;;;;; debbugs + `(debbugs-gnu-archived ((,class :inverse-video t))) + `(debbugs-gnu-done ((,class :inherit shadow))) + `(debbugs-gnu-forwarded ((,class :foreground ,fg-special-warm))) + `(debbugs-gnu-handled ((,class :foreground ,green))) + `(debbugs-gnu-new ((,class :foreground ,red))) + `(debbugs-gnu-pending ((,class :foreground ,cyan))) + `(debbugs-gnu-stale-1 ((,class :foreground ,yellow-nuanced-fg))) + `(debbugs-gnu-stale-2 ((,class :foreground ,yellow))) + `(debbugs-gnu-stale-3 ((,class :foreground ,yellow-alt))) + `(debbugs-gnu-stale-4 ((,class :foreground ,yellow-alt-other))) + `(debbugs-gnu-stale-5 ((,class :foreground ,red-alt))) + `(debbugs-gnu-tagged ((,class :foreground ,magenta-alt))) +;;;;; define-word + `(define-word-face-1 ((,class :foreground ,yellow))) + `(define-word-face-2 ((,class :foreground ,fg-main))) +;;;;; deft + `(deft-filter-string-error-face ((,class :inherit modus-theme-refine-red))) + `(deft-filter-string-face ((,class :foreground ,green-intense))) + `(deft-header-face ((,class :inherit bold :foreground ,fg-special-warm))) + `(deft-separator-face ((,class :inherit shadow))) + `(deft-summary-face ((,class :inherit modus-theme-slant :foreground ,fg-alt))) + `(deft-time-face ((,class :foreground ,fg-special-cold))) + `(deft-title-face ((,class :inherit bold :foreground ,fg-main))) +;;;;; dictionary + `(dictionary-button-face ((,class :inherit bold :foreground ,fg-special-cold))) + `(dictionary-reference-face ((,class :inherit button))) + `(dictionary-word-definition-face ((,class))) + `(dictionary-word-entry-face ((,class :inherit font-lock-comment-face))) +;;;;; diff-hl + `(diff-hl-change ((,class :inherit modus-theme-fringe-yellow))) + `(diff-hl-delete ((,class :inherit modus-theme-fringe-red))) + `(diff-hl-dired-change ((,class :inherit diff-hl-change))) + `(diff-hl-dired-delete ((,class :inherit diff-hl-delete))) + `(diff-hl-dired-ignored ((,class :inherit dired-ignored))) + `(diff-hl-dired-insert ((,class :inherit diff-hl-insert))) + `(diff-hl-dired-unknown ((,class :inherit dired-ignored))) + `(diff-hl-insert ((,class :inherit modus-theme-fringe-green))) + `(diff-hl-reverted-hunk-highlight ((,class :inherit (modus-theme-active-magenta bold)))) +;;;;; diff-mode + `(diff-added ((,class :inherit modus-theme-diff-added))) + `(diff-changed ((,class :inherit modus-theme-diff-changed :extend t))) + `(diff-context ((,class ,@(modus-themes--diff-text fg-main fg-unfocused)))) + `(diff-error ((,class :inherit modus-theme-intense-red))) + `(diff-file-header ((,class :inherit (bold diff-header)))) + `(diff-function ((,class :inherit modus-theme-diff-heading))) + `(diff-header ((,class ,@(modus-themes--diff-text cyan-faint fg-main)))) + `(diff-hunk-header ((,class :inherit (bold modus-theme-diff-heading)))) + `(diff-index ((,class :inherit bold :foreground ,blue-alt))) + `(diff-indicator-added ((,class :inherit (diff-added bold) + :foreground ,@(modus-themes--diff-deuteran blue green)))) + `(diff-indicator-changed ((,class :inherit (diff-changed bold) :foreground ,yellow))) + `(diff-indicator-removed ((,class :inherit (diff-removed bold) :foreground ,red))) + `(diff-nonexistent ((,class :inherit (modus-theme-neutral bold)))) + `(diff-refine-added ((,class :inherit modus-theme-diff-refine-added))) + `(diff-refine-changed ((,class :inherit modus-theme-diff-refine-changed))) + `(diff-refine-removed ((,class :inherit modus-theme-diff-refine-removed))) + `(diff-removed ((,class :inherit modus-theme-diff-removed))) +;;;;; dim-autoload + `(dim-autoload-cookie-line ((,class :inherit font-lock-comment-face))) +;;;;; dir-treeview + `(dir-treeview-archive-face ((,class :foreground ,fg-special-warm))) + `(dir-treeview-archive-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,yellow))) + `(dir-treeview-audio-face ((,class :foreground ,magenta))) + `(dir-treeview-audio-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,magenta-alt))) + `(dir-treeview-control-face ((,class :inherit shadow))) + `(dir-treeview-control-mouse-face ((,class :inherit highlight))) + `(dir-treeview-default-icon-face ((,class :inherit bold :family "Font Awesome" :foreground ,fg-alt))) + `(dir-treeview-default-filename-face ((,class :foreground ,fg-main))) + `(dir-treeview-directory-face ((,class :foreground ,blue))) + `(dir-treeview-directory-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,blue-alt))) + `(dir-treeview-executable-face ((,class :foreground ,red-alt))) + `(dir-treeview-executable-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,red-alt-other))) + `(dir-treeview-image-face ((,class :foreground ,green-alt-other))) + `(dir-treeview-image-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,green-alt))) + `(dir-treeview-indent-face ((,class :inherit shadow))) + `(dir-treeview-label-mouse-face ((,class :inherit highlight))) + `(dir-treeview-start-dir-face ((,class :inherit modus-theme-pseudo-header))) + `(dir-treeview-symlink-face ((,class :inherit button + ,@(modus-themes--link-color + cyan cyan-faint)))) + `(dir-treeview-video-face ((,class :foreground ,magenta-alt-other))) + `(dir-treeview-video-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,magenta-alt-other))) +;;;;; dired + `(dired-broken-symlink ((,class :inherit button :foreground ,red))) + `(dired-directory ((,class :foreground ,blue))) + `(dired-flagged ((,class :inherit modus-theme-mark-del))) + `(dired-header ((,class :inherit modus-theme-pseudo-header))) + `(dired-ignored ((,class :inherit shadow))) + `(dired-mark ((,class :inherit modus-theme-mark-symbol))) + `(dired-marked ((,class :inherit modus-theme-mark-sel))) + `(dired-perm-write ((,class :foreground ,fg-special-warm))) + `(dired-symlink ((,class :inherit button + ,@(modus-themes--link-color + cyan-alt cyan-alt-faint)))) + `(dired-warning ((,class :inherit bold :foreground ,yellow))) +;;;;; dired-async + `(dired-async-failures ((,class :inherit modus-theme-bold :foreground ,red-active))) + `(dired-async-message ((,class :inherit modus-theme-bold :foreground ,green-active))) + `(dired-async-mode-message ((,class :inherit modus-theme-bold :foreground ,cyan-active))) +;;;;; dired-git + `(dired-git-branch-else ((,class :inherit bold :foreground ,magenta-alt))) + `(dired-git-branch-master ((,class :inherit bold :foreground ,magenta-alt-other))) +;;;;; dired-git-info + `(dgi-commit-message-face ((,class :foreground ,fg-special-mild))) +;;;;; dired-narrow + `(dired-narrow-blink ((,class :inherit (modus-theme-subtle-cyan bold)))) +;;;;; dired-subtree + ;; remove backgrounds from dired-subtree faces, else they break + ;; dired-{flagged,marked} and any other face that sets a background + ;; such as hl-line. Also, denoting depth by varying shades of gray + ;; is not good for accessibility. + `(dired-subtree-depth-1-face (())) + `(dired-subtree-depth-2-face (())) + `(dired-subtree-depth-3-face (())) + `(dired-subtree-depth-4-face (())) + `(dired-subtree-depth-5-face (())) + `(dired-subtree-depth-6-face (())) +;;;;; diredc + `(diredc-face-chmod-font-lock-dir ((,class :foreground ,blue-alt))) + `(diredc-face-chmod-font-lock-exec ((,class :foreground ,magenta))) + `(diredc-face-chmod-font-lock-read ((,class :foreground ,fg-main))) + `(diredc-face-chmod-font-lock-write ((,class :foreground ,cyan))) +;;;;; diredfl + `(diredfl-autofile-name ((,class :inherit modus-theme-special-cold))) + `(diredfl-compressed-file-name ((,class :foreground ,fg-special-warm))) + `(diredfl-compressed-file-suffix ((,class :foreground ,red-alt))) + `(diredfl-date-time ((,class :foreground ,cyan-alt-other))) + `(diredfl-deletion ((,class :inherit modus-theme-mark-del))) + `(diredfl-deletion-file-name ((,class :inherit modus-theme-mark-del))) + `(diredfl-dir-heading ((,class :inherit modus-theme-pseudo-header))) + `(diredfl-dir-name ((,class :inherit dired-directory))) + `(diredfl-dir-priv ((,class :foreground ,blue-alt))) + `(diredfl-exec-priv ((,class :foreground ,magenta))) + `(diredfl-executable-tag ((,class :foreground ,magenta-alt))) + `(diredfl-file-name ((,class :foreground ,fg-main))) + `(diredfl-file-suffix ((,class :foreground ,cyan))) + `(diredfl-flag-mark ((,class :inherit modus-theme-mark-sel))) + `(diredfl-flag-mark-line ((,class :inherit modus-theme-mark-sel))) + `(diredfl-ignored-file-name ((,class :inherit shadow))) + `(diredfl-link-priv ((,class :foreground ,blue-alt-other))) + `(diredfl-no-priv ((,class :inherit shadow))) + `(diredfl-number ((,class :foreground ,cyan-alt))) + `(diredfl-other-priv ((,class :foreground ,yellow))) + `(diredfl-rare-priv ((,class :foreground ,red-alt))) + `(diredfl-read-priv ((,class :foreground ,fg-main))) + `(diredfl-symlink ((,class :inherit dired-symlink))) + `(diredfl-tagged-autofile-name ((,class :inherit modus-theme-refine-magenta))) + `(diredfl-write-priv ((,class :foreground ,cyan))) +;;;;; dired+ + `(diredp-autofile-name ((,class :inherit modus-theme-special-cold))) + `(diredp-compressed-file-name ((,class :foreground ,fg-special-warm))) + `(diredp-compressed-file-suffix ((,class :foreground ,red-alt))) + `(diredp-date-time ((,class :foreground ,cyan-alt-other))) + `(diredp-deletion ((,class :inherit modus-theme-mark-del))) + `(diredp-deletion-file-name ((,class :inherit modus-theme-mark-del))) + `(diredp-dir-heading ((,class :inherit modus-theme-pseudo-header))) + `(diredp-dir-name ((,class :inherit dired-directory))) + `(diredp-dir-priv ((,class :foreground ,blue-alt))) + `(diredp-exec-priv ((,class :foreground ,magenta))) + `(diredp-executable-tag ((,class :foreground ,magenta-alt))) + `(diredp-file-name ((,class :foreground ,fg-main))) + `(diredp-file-suffix ((,class :foreground ,cyan))) + `(diredp-flag-mark ((,class :inherit modus-theme-mark-sel))) + `(diredp-flag-mark-line ((,class :inherit modus-theme-mark-sel))) + `(diredp-ignored-file-name ((,class :inherit shadow))) + `(diredp-link-priv ((,class :foreground ,blue-alt-other))) + `(diredp-mode-line-flagged ((,class :foreground ,red-active))) + `(diredp-mode-line-marked ((,class :foreground ,green-active))) + `(diredp-no-priv ((,class :inherit shadow))) + `(diredp-number ((,class :foreground ,cyan-alt))) + `(diredp-omit-file-name ((,class :inherit shadow :strike-through t))) + `(diredp-other-priv ((,class :foreground ,yellow))) + `(diredp-rare-priv ((,class :foreground ,red-alt))) + `(diredp-read-priv ((,class :foreground ,fg-main))) + `(diredp-symlink ((,class :inherit dired-symlink))) + `(diredp-tagged-autofile-name ((,class :inherit modus-theme-refine-magenta))) + `(diredp-write-priv ((,class :foreground ,cyan))) +;;;;; disk-usage + `(disk-usage-children ((,class :foreground ,yellow))) + `(disk-usage-inaccessible ((,class :inherit bold :foreground ,red))) + `(disk-usage-percent ((,class :foreground ,green))) + `(disk-usage-size ((,class :foreground ,cyan))) + `(disk-usage-symlink ((,class :inherit button))) + `(disk-usage-symlink-directory ((,class :inherit bold :foreground ,blue-alt))) +;;;;; display-fill-column-indicator-mode + `(fill-column-indicator ((,class :foreground ,bg-active))) +;;;;; doom-modeline + `(doom-modeline-bar ((,class :inherit modus-theme-active-blue))) + `(doom-modeline-bar-inactive ((,class :background ,fg-inactive :foreground ,bg-main))) + `(doom-modeline-battery-charging ((,class :foreground ,green-active))) + `(doom-modeline-battery-critical ((,class :inherit bold :foreground ,red-active))) + `(doom-modeline-battery-error ((,class :inherit bold :box (:line-width -2) + :foreground ,red-active))) + `(doom-modeline-battery-full ((,class :foreground ,blue-active))) + `(doom-modeline-battery-normal ((,class :foreground ,fg-active))) + `(doom-modeline-battery-warning ((,class :inherit bold :foreground ,yellow-active))) + `(doom-modeline-buffer-file ((,class :inherit bold :foreground ,fg-active))) + `(doom-modeline-buffer-major-mode ((,class :inherit bold :foreground ,cyan-active))) + `(doom-modeline-buffer-minor-mode ((,class :foreground ,fg-inactive))) + `(doom-modeline-buffer-modified ((,class :inherit bold :foreground ,magenta-active))) + `(doom-modeline-buffer-path ((,class :inherit bold :foreground ,fg-active))) + `(doom-modeline-debug ((,class :inherit bold :foreground ,yellow-active))) + `(doom-modeline-debug-visual ((,class :inherit bold :foreground ,red-active))) + `(doom-modeline-evil-emacs-state ((,class :inherit bold :foreground ,magenta-active))) + `(doom-modeline-evil-insert-state ((,class :inherit bold :foreground ,green-active))) + `(doom-modeline-evil-motion-state ((,class :inherit bold :foreground ,fg-inactive))) + `(doom-modeline-evil-normal-state ((,class :inherit bold :foreground ,fg-active))) + `(doom-modeline-evil-operator-state ((,class :inherit bold :foreground ,blue-active))) + `(doom-modeline-evil-replace-state ((,class :inherit bold :foreground ,red-active))) + `(doom-modeline-evil-visual-state ((,class :inherit bold :foreground ,cyan-active))) + `(doom-modeline-highlight ((,class :inherit bold :foreground ,blue-active))) + `(doom-modeline-host ((,class :inherit italic))) + `(doom-modeline-info ((,class :foreground ,green-active))) + `(doom-modeline-lsp-error ((,class :inherit bold :foreground ,red-active))) + `(doom-modeline-lsp-success ((,class :inherit bold :foreground ,green-active))) + `(doom-modeline-lsp-warning ((,class :inherit bold :foreground ,yellow-active))) + `(doom-modeline-panel ((,class :inherit modus-theme-active-blue))) + `(doom-modeline-persp-buffer-not-in-persp ((,class :inherit italic :foreground ,yellow-active))) + `(doom-modeline-persp-name ((,class :foreground ,fg-active))) + `(doom-modeline-project-dir ((,class :inherit bold :foreground ,blue-active))) + `(doom-modeline-project-parent-dir ((,class :foreground ,blue-active))) + `(doom-modeline-project-root-dir ((,class :foreground ,fg-active))) + `(doom-modeline-unread-number ((,class :inherit italic :foreground ,fg-active))) + `(doom-modeline-urgent ((,class :inherit bold :foreground ,red-active))) + `(doom-modeline-warning ((,class :inherit bold :foreground ,yellow-active))) +;;;;; dynamic-ruler + `(dynamic-ruler-negative-face ((,class :inherit modus-theme-intense-neutral))) + `(dynamic-ruler-positive-face ((,class :inherit modus-theme-intense-yellow))) +;;;;; easy-jekyll + `(easy-jekyll-help-face ((,class :background ,bg-dim :foreground ,cyan-alt-other))) +;;;;; easy-kill + `(easy-kill-origin ((,class :inherit modus-theme-subtle-red))) + `(easy-kill-selection ((,class :inherit modus-theme-subtle-yellow))) +;;;;; ebdb + `(ebdb-address-default ((,class :foreground ,fg-special-calm))) + `(ebdb-defunct ((,class :inherit shadow))) + `(ebdb-field-hidden ((,class :foreground ,magenta))) + `(ebdb-label ((,class :foreground ,cyan-alt-other))) + `(ebdb-mail-default ((,class :foreground ,fg-main))) + `(ebdb-mail-primary ((,class :foreground ,magenta-alt))) + `(ebdb-marked ((,class :background ,cyan-intense-bg))) + `(ebdb-organization-name ((,class :foreground ,red-alt-other))) + `(ebdb-person-name ((,class :foreground ,magenta-alt-other))) + `(ebdb-phone-default ((,class :foreground ,cyan))) + `(eieio-custom-slot-tag-face ((,class :foreground ,red-alt))) +;;;;; ediff + ;; NOTE: here we break from the pattern of inheriting from the + ;; modus-theme-diff-* faces. + `(ediff-current-diff-A ((,class ,@(modus-themes--diff + bg-dim red + bg-diff-removed fg-diff-removed + red-nuanced-bg red-faint)))) + `(ediff-current-diff-Ancestor ((,class ,@(modus-themes--diff + bg-dim fg-special-cold + bg-special-cold fg-special-cold + blue-nuanced-bg blue)))) + `(ediff-current-diff-B ((,class ,@(modus-themes--diff + bg-dim green + bg-diff-added fg-diff-added + green-nuanced-bg green-faint + bg-diff-added-deuteran fg-diff-added-deuteran)))) + `(ediff-current-diff-C ((,class ,@(modus-themes--diff + bg-dim yellow + bg-diff-changed fg-diff-changed + yellow-nuanced-bg yellow-faint)))) + `(ediff-even-diff-A ((,class :background ,bg-diff-neutral-1 :foreground ,fg-diff-neutral-1))) + `(ediff-even-diff-Ancestor ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-1))) + `(ediff-even-diff-B ((,class :background ,bg-diff-neutral-1 :foreground ,fg-diff-neutral-1))) + `(ediff-even-diff-C ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-2))) + `(ediff-fine-diff-A ((,class :background ,bg-diff-focus-removed :foreground ,fg-diff-focus-removed))) + `(ediff-fine-diff-Ancestor ((,class :inherit modus-theme-refine-cyan))) + `(ediff-fine-diff-B + ((,class :background ,@(modus-themes--diff-deuteran bg-diff-focus-added-deuteran bg-diff-focus-added) + :foreground ,@(modus-themes--diff-deuteran fg-diff-focus-added-deuteran fg-diff-focus-added)))) + `(ediff-fine-diff-C ((,class :background ,bg-diff-focus-changed :foreground ,fg-diff-focus-changed))) + `(ediff-odd-diff-A ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-2))) + `(ediff-odd-diff-Ancestor ((,class :background ,bg-diff-neutral-0 :foreground ,fg-diff-neutral-0))) + `(ediff-odd-diff-B ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-2))) + `(ediff-odd-diff-C ((,class :background ,bg-diff-neutral-1 :foreground ,fg-diff-neutral-1))) +;;;;; eglot + `(eglot-mode-line ((,class :inherit modus-theme-bold :foreground ,magenta-active))) +;;;;; el-search + `(el-search-highlight-in-prompt-face ((,class :inherit bold :foreground ,magenta-alt))) + `(el-search-match ((,class :inherit modus-theme-intense-green))) + `(el-search-other-match ((,class :inherit modus-theme-special-mild))) + `(el-search-occur-match ((,class :inherit modus-theme-special-calm))) +;;;;; eldoc + ;; NOTE: see https://github.com/purcell/package-lint/issues/187 + (list 'eldoc-highlight-function-argument `((,class :inherit bold :foreground ,blue-alt-other))) +;;;;; eldoc-box + `(eldoc-box-body ((,class :background ,bg-alt :foreground ,fg-main))) + `(eldoc-box-border ((,class :background ,fg-alt))) +;;;;; elfeed + `(elfeed-log-date-face ((,class :inherit elfeed-search-date-face))) + `(elfeed-log-debug-level-face ((,class :inherit elfeed-search-filter-face))) + `(elfeed-log-error-level-face ((,class :inherit error))) + `(elfeed-log-info-level-face ((,class :inherit success))) + `(elfeed-log-warn-level-face ((,class :inherit warning))) + `(elfeed-search-date-face ((,class :foreground ,cyan))) + `(elfeed-search-feed-face ((,class :foreground ,blue-faint))) + `(elfeed-search-filter-face ((,class :inherit bold :foreground ,magenta-active))) + `(elfeed-search-last-update-face ((,class :foreground ,cyan-active))) + `(elfeed-search-tag-face ((,class :foreground ,cyan-alt-other))) + `(elfeed-search-title-face ((,class :foreground ,fg-dim))) + `(elfeed-search-unread-count-face ((,class :foreground ,green-active))) + `(elfeed-search-unread-title-face ((,class :inherit bold :foreground ,fg-main))) +;;;;; elfeed-score + `(elfeed-score-date-face ((,class :foreground ,blue))) + `(elfeed-score-debug-level-face ((,class :foreground ,magenta-alt-other))) + `(elfeed-score-error-level-face ((,class :foreground ,red))) + `(elfeed-score-info-level-face ((,class :foreground ,cyan))) + `(elfeed-score-warn-level-face ((,class :foreground ,yellow))) +;;;;; emms + `(emms-playlist-track-face ((,class :foreground ,blue))) + `(emms-playlist-selected-face ((,class :inherit bold :foreground ,magenta))) +;;;;; enhanced-ruby-mode + `(enh-ruby-heredoc-delimiter-face ((,class :foreground ,blue-alt-other))) + `(enh-ruby-op-face ((,class :foreground ,fg-main))) + `(enh-ruby-regexp-delimiter-face ((,class :foreground ,green))) + `(enh-ruby-regexp-face ((,class :foreground ,magenta))) + `(enh-ruby-string-delimiter-face ((,class :foreground ,blue-alt))) + `(erm-syn-errline ((,class :foreground ,red :underline t))) + `(erm-syn-warnline ((,class :foreground ,yellow :underline t))) +;;;;; epa + `(epa-field-body ((,class :foreground ,fg-main))) + `(epa-field-name ((,class :inherit bold :foreground ,fg-dim))) + `(epa-mark ((,class :inherit bold :foreground ,magenta))) + `(epa-string ((,class :foreground ,blue-alt))) + `(epa-validity-disabled ((,class :inherit modus-theme-refine-red))) + `(epa-validity-high ((,class :inherit bold :foreground ,green-alt-other))) + `(epa-validity-low ((,class :inherit shadow))) + `(epa-validity-medium ((,class :foreground ,green-alt))) +;;;;; equake + `(equake-buffer-face ((,class :background ,bg-main :foreground ,fg-main))) + `(equake-shell-type-eshell ((,class :background ,bg-inactive :foreground ,green-active))) + `(equake-shell-type-rash ((,class :background ,bg-inactive :foreground ,red-active))) + `(equake-shell-type-shell ((,class :background ,bg-inactive :foreground ,cyan-active))) + `(equake-shell-type-term ((,class :background ,bg-inactive :foreground ,yellow-active))) + `(equake-shell-type-vterm ((,class :background ,bg-inactive :foreground ,magenta-active))) + `(equake-tab-active ((,class :background ,fg-alt :foreground ,bg-alt))) + `(equake-tab-inactive ((,class :foreground ,fg-inactive))) +;;;;; erc + `(erc-action-face ((,class :inherit bold :foreground ,cyan))) + `(erc-bold-face ((,class :inherit bold))) + `(erc-button ((,class :inherit button))) + `(erc-command-indicator-face ((,class :inherit bold :foreground ,cyan-alt))) + `(erc-current-nick-face ((,class :foreground ,magenta-alt-other))) + `(erc-dangerous-host-face ((,class :inherit modus-theme-intense-red))) + `(erc-direct-msg-face ((,class :foreground ,magenta))) + `(erc-error-face ((,class :inherit bold :foreground ,red))) + `(erc-fool-face ((,class :foreground ,fg-inactive))) + `(erc-header-line ((,class :background ,bg-header :foreground ,fg-header))) + `(erc-input-face ((,class :foreground ,fg-special-calm))) + `(erc-inverse-face ((,class :inherit erc-default-face :inverse-video t))) + `(erc-keyword-face ((,class :inherit bold :foreground ,magenta-alt))) + `(erc-my-nick-face ((,class :inherit bold :foreground ,magenta))) + `(erc-my-nick-prefix-face ((,class :inherit erc-my-nick-face))) + `(erc-nick-default-face ((,class :inherit bold :foreground ,blue))) + `(erc-nick-msg-face ((,class :inherit bold :foreground ,green))) + `(erc-nick-prefix-face ((,class :inherit erc-nick-default-face))) + `(erc-notice-face ((,class :foreground ,fg-unfocused))) + `(erc-pal-face ((,class :inherit bold :foreground ,red-alt))) + `(erc-prompt-face ((,class :inherit bold :foreground ,cyan-alt-other))) + `(erc-timestamp-face ((,class :foreground ,blue-nuanced-fg))) + `(erc-underline-face ((,class :underline t))) + `(bg:erc-color-face0 ((,class :background "white"))) + `(bg:erc-color-face1 ((,class :background "black"))) + `(bg:erc-color-face10 ((,class :background ,cyan-subtle-bg))) + `(bg:erc-color-face11 ((,class :background ,cyan-intense-bg))) + `(bg:erc-color-face12 ((,class :background ,blue-subtle-bg))) + `(bg:erc-color-face13 ((,class :background ,magenta-subtle-bg))) + `(bg:erc-color-face14 ((,class :background "gray60"))) + `(bg:erc-color-face15 ((,class :background "gray80"))) + `(bg:erc-color-face2 ((,class :background ,blue-intense-bg))) + `(bg:erc-color-face3 ((,class :background ,green-intense-bg))) + `(bg:erc-color-face4 ((,class :background ,red-subtle-bg))) + `(bg:erc-color-face5 ((,class :background ,red-intense-bg))) + `(bg:erc-color-face6 ((,class :background ,magenta-refine-bg))) + `(bg:erc-color-face7 ((,class :background ,yellow-subtle-bg))) + `(bg:erc-color-face8 ((,class :background ,yellow-refine-bg))) + `(bg:erc-color-face9 ((,class :background ,green-subtle-bg))) + `(fg:erc-color-face0 ((,class :foreground "white"))) + `(fg:erc-color-face1 ((,class :foreground "black"))) + `(fg:erc-color-face10 ((,class :foreground ,cyan))) + `(fg:erc-color-face11 ((,class :foreground ,cyan-alt-other))) + `(fg:erc-color-face12 ((,class :foreground ,blue))) + `(fg:erc-color-face13 ((,class :foreground ,magenta-alt))) + `(fg:erc-color-face14 ((,class :foreground "gray60"))) + `(fg:erc-color-face15 ((,class :foreground "gray80"))) + `(fg:erc-color-face2 ((,class :foreground ,blue-alt-other))) + `(fg:erc-color-face3 ((,class :foreground ,green))) + `(fg:erc-color-face4 ((,class :foreground ,red))) + `(fg:erc-color-face5 ((,class :foreground ,red-alt))) + `(fg:erc-color-face6 ((,class :foreground ,magenta-alt-other))) + `(fg:erc-color-face7 ((,class :foreground ,yellow-alt-other))) + `(fg:erc-color-face8 ((,class :foreground ,yellow-alt))) + `(fg:erc-color-face9 ((,class :foreground ,green-alt-other))) +;;;;; eros + `(eros-result-overlay-face ((,class :box (:line-width -1 :color ,blue) + :background ,bg-dim :foreground ,fg-dim))) +;;;;; ert + `(ert-test-result-expected ((,class :inherit modus-theme-intense-green))) + `(ert-test-result-unexpected ((,class :inherit modus-theme-intense-red))) +;;;;; eshell + `(eshell-ls-archive ((,class :inherit bold :foreground ,cyan-alt))) + `(eshell-ls-backup ((,class :foreground ,yellow-alt))) + `(eshell-ls-clutter ((,class :foreground ,red-alt))) + `(eshell-ls-directory ((,class :inherit bold :foreground ,blue-alt))) + `(eshell-ls-executable ((,class :foreground ,magenta-alt))) + `(eshell-ls-missing ((,class :inherit modus-theme-intense-red))) + `(eshell-ls-product ((,class :foreground ,fg-special-warm))) + `(eshell-ls-readonly ((,class :foreground ,fg-special-cold))) + `(eshell-ls-special ((,class :inherit bold :foreground ,magenta))) + `(eshell-ls-symlink ((,class :inherit button + ,@(modus-themes--link-color + cyan cyan-faint)))) + `(eshell-ls-unreadable ((,class :background ,bg-inactive :foreground ,fg-inactive))) + `(eshell-prompt ((,class :inherit modus-theme-bold + ,@(modus-themes--prompt + green-alt-other + green-nuanced-bg green-alt + green-refine-bg fg-main)))) +;;;;; eshell-fringe-status + `(eshell-fringe-status-failure ((,class :foreground ,red))) + `(eshell-fringe-status-success ((,class :foreground ,green))) +;;;;; eshell-git-prompt + `(eshell-git-prompt-add-face ((,class :inherit shadow))) + `(eshell-git-prompt-branch-face ((,class :inherit shadow))) + `(eshell-git-prompt-directory-face ((,class :foreground ,cyan))) + `(eshell-git-prompt-exit-fail-face ((,class :foreground ,red))) + `(eshell-git-prompt-exit-success-face ((,class :foreground ,green))) + `(eshell-git-prompt-modified-face ((,class :foreground ,yellow))) + `(eshell-git-prompt-powerline-clean-face ((,class :background ,green-refine-bg))) + `(eshell-git-prompt-powerline-dir-face ((,class :background ,blue-refine-bg))) + `(eshell-git-prompt-powerline-not-clean-face ((,class :background ,magenta-refine-bg))) + `(eshell-git-prompt-robyrussell-branch-face ((,class :foreground ,red))) + `(eshell-git-prompt-robyrussell-git-dirty-face ((,class :foreground ,yellow))) + `(eshell-git-prompt-robyrussell-git-face ((,class :foreground ,blue))) +;;;;; eshell-prompt-extras (epe) + `(epe-dir-face ((,class :inherit modus-theme-bold :foreground ,blue))) + `(epe-git-dir-face ((,class :foreground ,red-alt-other))) + `(epe-git-face ((,class :foreground ,cyan-alt))) + `(epe-pipeline-delimiter-face ((,class :foreground ,green-alt))) + `(epe-pipeline-host-face ((,class :foreground ,blue))) + `(epe-pipeline-time-face ((,class :foreground ,fg-special-warm))) + `(epe-pipeline-user-face ((,class :foreground ,magenta))) + `(epe-remote-face ((,class :inherit modus-theme-slant :foreground ,fg-alt))) + `(epe-status-face ((,class :foreground ,magenta-alt-other))) + `(epe-venv-face ((,class :inherit modus-theme-slant :foreground ,fg-alt))) +;;;;; eshell-syntax-highlighting + `(eshell-syntax-highlighting-alias-face ((,class :foreground ,cyan))) + `(eshell-syntax-highlighting-comment-face ((,class :inherit shadow))) + `(eshell-syntax-highlighting-directory-face ((,class :foreground ,blue))) + `(eshell-syntax-highlighting-envvar-face ((,class :foreground ,magenta-alt))) + `(eshell-syntax-highlighting-invalid-face ((,class :foreground ,red))) + `(eshell-syntax-highlighting-lisp-function-face ((,class :foreground ,magenta))) + `(eshell-syntax-highlighting-shell-command-face ((,class :foreground ,cyan-alt-other))) + `(eshell-syntax-highlighting-string-face ((,class :foreground ,blue-alt))) +;;;;; evil-mode + `(evil-ex-commands ((,class :foreground ,magenta-alt-other))) + `(evil-ex-info ((,class :foreground ,cyan-alt-other))) + `(evil-ex-lazy-highlight ((,class :inherit modus-theme-refine-cyan))) + `(evil-ex-search ((,class :inherit modus-theme-intense-green))) + `(evil-ex-substitute-matches ((,class :inherit modus-theme-refine-yellow :underline t))) + `(evil-ex-substitute-replacement ((,class :inherit (modus-theme-intense-green bold)))) +;;;;; evil-goggles + `(evil-goggles-change-face ((,class :inherit modus-theme-refine-yellow))) + `(evil-goggles-commentary-face ((,class :inherit (modus-theme-subtle-neutral modus-theme-slant)))) + `(evil-goggles-default-face ((,class :inherit modus-theme-subtle-neutral))) + `(evil-goggles-delete-face ((,class :inherit modus-theme-refine-red))) + `(evil-goggles-fill-and-move-face ((,class :inherit evil-goggles-default-face))) + `(evil-goggles-indent-face ((,class :inherit evil-goggles-default-face))) + `(evil-goggles-join-face ((,class :inherit modus-theme-subtle-green))) + `(evil-goggles-nerd-commenter-face ((,class :inherit evil-goggles-commentary-face))) + `(evil-goggles-paste-face ((,class :inherit modus-theme-subtle-cyan))) + `(evil-goggles-record-macro-face ((,class :inherit modus-theme-special-cold))) + `(evil-goggles-replace-with-register-face ((,class :inherit modus-theme-refine-magenta))) + `(evil-goggles-set-marker-face ((,class :inherit modus-theme-intense-magenta))) + `(evil-goggles-shift-face ((,class :inherit evil-goggles-default-face))) + `(evil-goggles-surround-face ((,class :inherit evil-goggles-default-face))) + `(evil-goggles-yank-face ((,class :inherit modus-theme-subtle-blue))) +;;;;; evil-snipe + `(evil-snipe-first-match-face ((,class :inherit (bold modus-theme-intense-blue)))) + `(evil-snipe-matches-face ((,class :inherit modus-theme-refine-magenta))) +;;;;; evil-visual-mark-mode + `(evil-visual-mark-face ((,class :inherit modus-theme-intense-magenta))) +;;;;; eww + `(eww-invalid-certificate ((,class :foreground ,red-active))) + `(eww-valid-certificate ((,class :foreground ,green-active))) + `(eww-form-checkbox ((,class :box (:line-width 1 :color ,fg-inactive :style released-button) :background ,bg-inactive :foreground ,fg-main))) + `(eww-form-file ((,class :box (:line-width 1 :color ,fg-inactive :style released-button) :background ,bg-active :foreground ,fg-main))) + `(eww-form-select ((,class :inherit eww-form-checkbox))) + `(eww-form-submit ((,class :inherit eww-form-file))) + `(eww-form-text ((,class :box (:line-width 1 :color ,fg-inactive :style none) :background ,bg-active :foreground ,fg-active))) + `(eww-form-textarea ((,class :background ,bg-alt :foreground ,fg-main))) +;;;;; eyebrowse + `(eyebrowse-mode-line-active ((,class :inherit bold :foreground ,blue-active))) +;;;;; fancy-dabbrev + `(fancy-dabbrev-menu-face ((,class :background ,bg-alt :foreground ,fg-alt))) + `(fancy-dabbrev-preview-face ((,class :inherit shadow :underline t))) + `(fancy-dabbrev-selection-face ((,class :inherit (modus-theme-intense-cyan bold)))) +;;;;; flycheck + `(flycheck-error ((,class :inherit modus-theme-lang-error))) + `(flycheck-error-list-checker-name ((,class :foreground ,magenta-active))) + `(flycheck-error-list-column-number ((,class :foreground ,fg-special-cold))) + `(flycheck-error-list-error ((,class :inherit modus-theme-bold :foreground ,red))) + `(flycheck-error-list-filename ((,class :foreground ,blue))) + `(flycheck-error-list-highlight ((,class :inherit modus-theme-hl-line))) + `(flycheck-error-list-id ((,class :foreground ,magenta-alt-other))) + `(flycheck-error-list-id-with-explainer ((,class :inherit flycheck-error-list-id :box t))) + `(flycheck-error-list-info ((,class :foreground ,cyan))) + `(flycheck-error-list-line-number ((,class :foreground ,fg-special-warm))) + `(flycheck-error-list-warning ((,class :foreground ,yellow))) + `(flycheck-fringe-error ((,class :inherit modus-theme-fringe-red))) + `(flycheck-fringe-info ((,class :inherit modus-theme-fringe-cyan))) + `(flycheck-fringe-warning ((,class :inherit modus-theme-fringe-yellow))) + `(flycheck-info ((,class :inherit modus-theme-lang-note))) + `(flycheck-verify-select-checker ((,class :box (:line-width 1 :color nil :style released-button)))) + `(flycheck-warning ((,class :inherit modus-theme-lang-warning))) +;;;;; flycheck-color-mode-line + `(flycheck-color-mode-line-error-face ((,class :inherit flycheck-fringe-error))) + `(flycheck-color-mode-line-info-face ((,class :inherit flycheck-fringe-info))) + `(flycheck-color-mode-line-running-face ((,class :inherit italic :foreground ,fg-inactive))) + `(flycheck-color-mode-line-info-face ((,class :inherit flycheck-fringe-warning))) +;;;;; flycheck-indicator + `(flycheck-indicator-disabled ((,class :inherit modus-theme-slant :foreground ,fg-inactive))) + `(flycheck-indicator-error ((,class :inherit modus-theme-bold :foreground ,red-active))) + `(flycheck-indicator-info ((,class :inherit modus-theme-bold :foreground ,blue-active))) + `(flycheck-indicator-running ((,class :inherit modus-theme-bold :foreground ,magenta-active))) + `(flycheck-indicator-success ((,class :inherit modus-theme-bold :foreground ,green-active))) + `(flycheck-indicator-warning ((,class :inherit modus-theme-bold :foreground ,yellow-active))) +;;;;; flycheck-posframe + `(flycheck-posframe-background-face ((,class :background ,bg-alt))) + `(flycheck-posframe-border-face ((,class :inherit shadow))) + `(flycheck-posframe-error-face ((,class :inherit bold :foreground ,red))) + `(flycheck-posframe-face ((,class :inherit modus-theme-slant :foreground ,fg-main))) + `(flycheck-posframe-info-face ((,class :inherit bold :foreground ,cyan))) + `(flycheck-posframe-warning-face ((,class :inherit bold :foreground ,yellow))) +;;;;; flymake + `(flymake-error ((,class :inherit modus-theme-lang-error))) + `(flymake-note ((,class :inherit modus-theme-lang-note))) + `(flymake-warning ((,class :inherit modus-theme-lang-warning))) +;;;;; flyspell + `(flyspell-duplicate ((,class :inherit modus-theme-lang-warning))) + `(flyspell-incorrect ((,class :inherit modus-theme-lang-error))) +;;;;; flyspell-correct + `(flyspell-correct-highlight-face ((,class :inherit modus-theme-refine-green))) +;;;;; flx + `(flx-highlight-face ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-magenta + 'modus-theme-intense-magenta + 'modus-theme-nuanced-magenta + magenta-alt + 'bold)))) +;;;;; freeze-it + `(freeze-it-show ((,class :background ,bg-dim :foreground ,fg-special-warm))) +;;;;; frog-menu + `(frog-menu-action-keybinding-face ((,class :foreground ,blue-alt-other))) + `(frog-menu-actions-face ((,class :foreground ,magenta))) + `(frog-menu-border ((,class :background ,bg-active))) + `(frog-menu-candidates-face ((,class :foreground ,fg-main))) + `(frog-menu-posframe-background-face ((,class :background ,bg-dim))) + `(frog-menu-prompt-face ((,class :foreground ,cyan))) +;;;;; focus + `(focus-unfocused ((,class :foreground ,fg-unfocused))) +;;;;; fold-this + `(fold-this-overlay ((,class :inherit modus-theme-special-mild))) +;;;;; font-lock + `(font-lock-builtin-face ((,class :inherit modus-theme-bold + ,@(modus-themes--syntax-extra + magenta-alt magenta-alt-faint blue-alt)))) + `(font-lock-comment-delimiter-face ((,class :inherit font-lock-comment-face))) + `(font-lock-comment-face ((,class :inherit modus-theme-slant + ,@(modus-themes--syntax-comment + fg-alt fg-comment-yellow)))) + `(font-lock-constant-face ((,class ,@(modus-themes--syntax-extra + blue-alt-other blue-alt-other-faint magenta-alt-other)))) + `(font-lock-doc-face ((,class :inherit modus-theme-slant + ,@(modus-themes--syntax-docstring + fg-docstring green-alt-other-faint + green-alt-other-faint magenta-nuanced-fg)))) + `(font-lock-function-name-face ((,class ,@(modus-themes--syntax-extra + magenta magenta-faint magenta-alt)))) + `(font-lock-keyword-face ((,class :inherit modus-theme-bold + ,@(modus-themes--syntax-extra + magenta-alt-other magenta-alt-other-faint cyan-alt-other)))) + `(font-lock-negation-char-face ((,class :inherit modus-theme-bold + ,@(modus-themes--syntax-foreground + yellow yellow-faint)))) + `(font-lock-preprocessor-face ((,class ,@(modus-themes--syntax-foreground + red-alt-other red-alt-other-faint)))) + `(font-lock-regexp-grouping-backslash ((,class :inherit bold + ,@(modus-themes--syntax-string + fg-escape-char-backslash yellow-alt-faint + magenta-alt-other blue-alt)))) + `(font-lock-regexp-grouping-construct ((,class :inherit bold + ,@(modus-themes--syntax-string + fg-escape-char-construct red-alt-other-faint + red magenta-alt)))) + `(font-lock-string-face ((,class ,@(modus-themes--syntax-string + blue-alt blue-alt-faint green green-alt)))) + `(font-lock-type-face ((,class :inherit modus-theme-bold + ,@(modus-themes--syntax-extra + cyan-alt-other cyan-alt-faint cyan-alt)))) + `(font-lock-variable-name-face ((,class ,@(modus-themes--syntax-extra + cyan cyan-faint blue-alt-faint)))) + `(font-lock-warning-face ((,class :inherit modus-theme-bold + ,@(modus-themes--syntax-foreground + yellow-active yellow-alt-faint)))) +;;;;; forge + `(forge-post-author ((,class :inherit bold :foreground ,fg-main))) + `(forge-post-date ((,class :foreground ,fg-special-cold))) + `(forge-topic-closed ((,class :inherit shadow))) + `(forge-topic-merged ((,class :inherit shadow))) + `(forge-topic-open ((,class :foreground ,fg-special-mild))) + `(forge-topic-unmerged ((,class :inherit modus-theme-slant :foreground ,magenta))) + `(forge-topic-unread ((,class :inherit bold :foreground ,fg-main))) +;;;;; fountain-mode + `(fountain-character ((,class :foreground ,blue-alt-other))) + `(fountain-comment ((,class :inherit modus-theme-slant :foreground ,fg-alt))) + `(fountain-dialog ((,class :foreground ,blue-alt))) + `(fountain-metadata-key ((,class :foreground ,green-alt-other))) + `(fountain-metadata-value ((,class :foreground ,blue))) + `(fountain-non-printing ((,class :inherit shadow))) + `(fountain-note ((,class :inherit modus-theme-slant :foreground ,yellow))) + `(fountain-page-break ((,class :inherit bold :foreground ,red-alt))) + `(fountain-page-number ((,class :inherit bold :foreground ,red-alt-other))) + `(fountain-paren ((,class :foreground ,cyan))) + `(fountain-scene-heading ((,class :inherit bold :foreground ,blue-nuanced-fg))) + `(fountain-section-heading ((,class :inherit modus-theme-heading-1))) + `(fountain-section-heading-1 ((,class :inherit modus-theme-heading-1))) + `(fountain-section-heading-2 ((,class :inherit modus-theme-heading-2))) + `(fountain-section-heading-3 ((,class :inherit modus-theme-heading-3))) + `(fountain-section-heading-4 ((,class :inherit modus-theme-heading-4))) + `(fountain-section-heading-5 ((,class :inherit modus-theme-heading-5))) + `(fountain-synopsis ((,class :foreground ,cyan-alt))) + `(fountain-trans ((,class :foreground ,yellow-alt-other))) +;;;;; geiser + `(geiser-font-lock-autodoc-current-arg ((,class :inherit font-lock-function-name-face))) + `(geiser-font-lock-autodoc-identifier ((,class :inherit font-lock-constant-face))) + `(geiser-font-lock-doc-button ((,class :inherit button :foreground ,fg-docstring))) + `(geiser-font-lock-doc-link ((,class :inherit button))) + `(geiser-font-lock-error-link ((,class :inherit button :foreground ,red))) + `(geiser-font-lock-image-button ((,class :inherit button :foreground ,green-alt))) + `(geiser-font-lock-repl-input ((,class :inherit bold))) + `(geiser-font-lock-repl-output ((,class :inherit font-lock-keyword-face))) + `(geiser-font-lock-repl-prompt ((,class :inherit minibuffer-prompt))) + `(geiser-font-lock-xref-header ((,class :inherit bold))) + `(geiser-font-lock-xref-link ((,class :inherit button))) +;;;;; git-commit + `(git-commit-comment-action ((,class :inherit font-lock-comment-face))) + `(git-commit-comment-branch-local ((,class :inherit modus-theme-slant :foreground ,blue-alt))) + `(git-commit-comment-branch-remote ((,class :inherit modus-theme-slant :foreground ,magenta-alt))) + `(git-commit-comment-detached ((,class :inherit modus-theme-slant :foreground ,cyan-alt))) + `(git-commit-comment-file ((,class :inherit modus-theme-slant + ,@(modus-themes--syntax-comment + fg-special-cold red-nuanced-fg)))) + `(git-commit-comment-heading ((,class :inherit (bold modus-theme-slant) + ,@(modus-themes--syntax-comment + fg-dim fg-special-warm)))) + `(git-commit-keyword ((,class :foreground ,magenta))) + `(git-commit-known-pseudo-header ((,class :foreground ,cyan-alt-other))) + `(git-commit-nonempty-second-line ((,class :inherit modus-theme-refine-yellow))) + `(git-commit-overlong-summary ((,class :inherit modus-theme-refine-yellow))) + `(git-commit-pseudo-header ((,class :foreground ,blue))) + `(git-commit-summary ((,class :inherit bold :foreground ,cyan))) +;;;;; git-gutter + `(git-gutter:added ((,class :inherit modus-theme-fringe-green))) + `(git-gutter:deleted ((,class :inherit modus-theme-fringe-red))) + `(git-gutter:modified ((,class :inherit modus-theme-fringe-yellow))) + `(git-gutter:separator ((,class :inherit modus-theme-fringe-cyan))) + `(git-gutter:unchanged ((,class :inherit modus-theme-fringe-magenta))) +;;;;; git-gutter-fr + `(git-gutter-fr:added ((,class :inherit modus-theme-fringe-green))) + `(git-gutter-fr:deleted ((,class :inherit modus-theme-fringe-red))) + `(git-gutter-fr:modified ((,class :inherit modus-theme-fringe-yellow))) +;;;;; git-{gutter,fringe}+ + `(git-gutter+-added ((,class :inherit modus-theme-fringe-green))) + `(git-gutter+-deleted ((,class :inherit modus-theme-fringe-red))) + `(git-gutter+-modified ((,class :inherit modus-theme-fringe-yellow))) + `(git-gutter+-separator ((,class :inherit modus-theme-fringe-cyan))) + `(git-gutter+-unchanged ((,class :inherit modus-theme-fringe-magenta))) + `(git-gutter-fr+-added ((,class :inherit modus-theme-fringe-green))) + `(git-gutter-fr+-deleted ((,class :inherit modus-theme-fringe-red))) + `(git-gutter-fr+-modified ((,class :inherit modus-theme-fringe-yellow))) +;;;;; git-lens + `(git-lens-added ((,class :inherit bold :foreground ,green))) + `(git-lens-deleted ((,class :inherit bold :foreground ,red))) + `(git-lens-header ((,class :inherit bold :height 1.1 :foreground ,cyan))) + `(git-lens-modified ((,class :inherit bold :foreground ,yellow))) + `(git-lens-renamed ((,class :inherit bold :foreground ,magenta))) +;;;;; git-rebase + `(git-rebase-comment-hash ((,class :inherit modus-theme-slant + ,@(modus-themes--syntax-comment + fg-special-cold red-nuanced-fg)))) + `(git-rebase-comment-heading ((,class :inherit (bold modus-theme-slant) + ,@(modus-themes--syntax-comment + fg-dim fg-special-warm)))) + `(git-rebase-description ((,class :foreground ,fg-main))) + `(git-rebase-hash ((,class :foreground ,cyan-alt-other))) +;;;;; git-timemachine + `(git-timemachine-commit ((,class :inherit bold :foreground ,yellow-active))) + `(git-timemachine-minibuffer-author-face ((,class :foreground ,fg-special-warm))) + `(git-timemachine-minibuffer-detail-face ((,class :foreground ,red-alt))) +;;;;; git-walktree + `(git-walktree-commit-face ((,class :foreground ,yellow))) + `(git-walktree-symlink-face ((,class :inherit button))) + `(git-walktree-tree-face ((,class :foreground ,magenta))) +;;;;; gnus + `(gnus-button ((,class :inherit button))) + `(gnus-cite-1 ((,class :foreground ,blue-faint))) + `(gnus-cite-10 ((,class :foreground ,yellow-alt-other))) + `(gnus-cite-11 ((,class :foreground ,magenta-alt))) + `(gnus-cite-2 ((,class :foreground ,green-alt-other))) + `(gnus-cite-3 ((,class :foreground ,red-alt-other))) + `(gnus-cite-4 ((,class :foreground ,cyan))) + `(gnus-cite-5 ((,class :foreground ,yellow-alt))) + `(gnus-cite-6 ((,class :foreground ,magenta))) + `(gnus-cite-7 ((,class :foreground ,green-alt))) + `(gnus-cite-8 ((,class :foreground ,magenta-alt-other))) + `(gnus-cite-9 ((,class :foreground ,cyan-alt))) + `(gnus-cite-attribution ((,class :inherit italic :foreground ,fg-main))) + `(gnus-emphasis-bold ((,class :inherit bold))) + `(gnus-emphasis-bold-italic ((,class :inherit bold-italic))) + `(gnus-emphasis-highlight-words ((,class :inherit modus-theme-refine-yellow))) + `(gnus-emphasis-italic ((,class :inherit italic))) + `(gnus-emphasis-underline-bold ((,class :inherit gnus-emphasis-bold :underline t))) + `(gnus-emphasis-underline-bold-italic ((,class :inherit gnus-emphasis-bold-italic :underline t))) + `(gnus-emphasis-underline-italic ((,class :inherit gnus-emphasis-italic :underline t))) + `(gnus-group-mail-1 ((,class :inherit bold :foreground ,magenta-alt))) + `(gnus-group-mail-1-empty ((,class :foreground ,magenta-alt))) + `(gnus-group-mail-2 ((,class :inherit bold :foreground ,magenta))) + `(gnus-group-mail-2-empty ((,class :foreground ,magenta))) + `(gnus-group-mail-3 ((,class :inherit bold :foreground ,magenta-alt-other))) + `(gnus-group-mail-3-empty ((,class :foreground ,magenta-alt-other))) + `(gnus-group-mail-low ((,class :inherit bold :foreground ,magenta-nuanced-fg))) + `(gnus-group-mail-low-empty ((,class :foreground ,magenta-nuanced-fg))) + `(gnus-group-news-1 ((,class :inherit bold :foreground ,green))) + `(gnus-group-news-1-empty ((,class :foreground ,green))) + `(gnus-group-news-2 ((,class :inherit bold :foreground ,cyan))) + `(gnus-group-news-2-empty ((,class :foreground ,cyan))) + `(gnus-group-news-3 ((,class :inherit bold :foreground ,yellow-nuanced-fg))) + `(gnus-group-news-3-empty ((,class :foreground ,yellow-nuanced-fg))) + `(gnus-group-news-4 ((,class :inherit bold :foreground ,cyan-nuanced-fg))) + `(gnus-group-news-4-empty ((,class :foreground ,cyan-nuanced-fg))) + `(gnus-group-news-5 ((,class :inherit bold :foreground ,red-nuanced-fg))) + `(gnus-group-news-5-empty ((,class :foreground ,red-nuanced-fg))) + `(gnus-group-news-6 ((,class :inherit bold :foreground ,fg-alt))) + `(gnus-group-news-6-empty ((,class :inherit shadow))) + `(gnus-group-news-low ((,class :inherit bold :foreground ,green-nuanced-fg))) + `(gnus-group-news-low-empty ((,class :foreground ,green-nuanced-fg))) + `(gnus-header-content ((,class :inherit message-header-other))) + `(gnus-header-from ((,class :inherit message-header-to :underline nil))) + `(gnus-header-name ((,class :inherit message-header-name))) + `(gnus-header-newsgroups ((,class :inherit message-header-newsgroups))) + `(gnus-header-subject ((,class :inherit message-header-subject))) + `(gnus-server-agent ((,class :inherit bold :foreground ,cyan))) + `(gnus-server-closed ((,class :inherit bold :foreground ,magenta))) + `(gnus-server-cloud ((,class :inherit bold :foreground ,cyan-alt))) + `(gnus-server-cloud-host ((,class :inherit modus-theme-refine-cyan))) + `(gnus-server-denied ((,class :inherit bold :foreground ,red))) + `(gnus-server-offline ((,class :inherit bold :foreground ,yellow))) + `(gnus-server-opened ((,class :inherit bold :foreground ,green))) + `(gnus-signature ((,class :inherit italic :foreground ,fg-special-cold))) + `(gnus-splash ((,class :inherit shadow))) + `(gnus-summary-cancelled ((,class :inherit modus-theme-mark-alt))) + `(gnus-summary-high-ancient ((,class :inherit bold :foreground ,fg-alt))) + `(gnus-summary-high-read ((,class :inherit bold :foreground ,fg-special-cold))) + `(gnus-summary-high-ticked ((,class :inherit bold :foreground ,red-alt-other))) + `(gnus-summary-high-undownloaded ((,class :inherit bold :foreground ,yellow))) + `(gnus-summary-high-unread ((,class :inherit bold :foreground ,fg-main))) + `(gnus-summary-low-ancient ((,class :inherit italic :foreground ,fg-alt))) + `(gnus-summary-low-read ((,class :inherit italic :foreground ,fg-alt))) + `(gnus-summary-low-ticked ((,class :inherit italic :foreground ,red-refine-fg))) + `(gnus-summary-low-undownloaded ((,class :inherit italic :foreground ,yellow-refine-fg))) + `(gnus-summary-low-unread ((,class :inherit bold :foreground ,fg-special-cold))) + `(gnus-summary-normal-ancient ((,class :foreground ,fg-special-calm))) + `(gnus-summary-normal-read ((,class :inherit shadow))) + `(gnus-summary-normal-ticked ((,class :foreground ,red-alt-other))) + `(gnus-summary-normal-undownloaded ((,class :foreground ,yellow))) + `(gnus-summary-normal-unread ((,class :foreground ,fg-main))) + `(gnus-summary-selected ((,class :inherit modus-theme-subtle-blue))) +;;;;; golden-ratio-scroll-screen + `(golden-ratio-scroll-highlight-line-face ((,class :background ,cyan-subtle-bg :foreground ,fg-main))) +;;;;; helm + `(helm-M-x-key ((,class :inherit bold :foreground ,magenta-alt-other))) + `(helm-action ((,class :underline t))) + `(helm-bookmark-addressbook ((,class :foreground ,green-alt))) + `(helm-bookmark-directory ((,class :inherit bold :foreground ,blue))) + `(helm-bookmark-file ((,class :foreground ,fg-main))) + `(helm-bookmark-file-not-found ((,class :background ,bg-alt :foreground ,fg-alt))) + `(helm-bookmark-gnus ((,class :foreground ,magenta))) + `(helm-bookmark-info ((,class :foreground ,cyan-alt))) + `(helm-bookmark-man ((,class :foreground ,yellow-alt))) + `(helm-bookmark-w3m ((,class :foreground ,blue-alt))) + `(helm-buffer-archive ((,class :inherit bold :foreground ,cyan))) + `(helm-buffer-directory ((,class :inherit bold :foreground ,blue))) + `(helm-buffer-file ((,class :foreground ,fg-main))) + `(helm-buffer-modified ((,class :foreground ,yellow-alt))) + `(helm-buffer-not-saved ((,class :foreground ,red-alt))) + `(helm-buffer-process ((,class :foreground ,magenta))) + `(helm-buffer-saved-out ((,class :inherit bold :background ,bg-alt :foreground ,red))) + `(helm-buffer-size ((,class :inherit shadow))) + `(helm-candidate-number ((,class :foreground ,cyan-active))) + `(helm-candidate-number-suspended ((,class :foreground ,yellow-active))) + `(helm-comint-prompts-buffer-name ((,class :foreground ,green-active))) + `(helm-comint-prompts-promptidx ((,class :foreground ,cyan-active))) + `(helm-delete-async-message ((,class :inherit bold :foreground ,magenta-active))) + `(helm-eob-line ((,class :background ,bg-main :foreground ,fg-main))) + `(helm-eshell-prompts-buffer-name ((,class :foreground ,green-active))) + `(helm-eshell-prompts-promptidx ((,class :foreground ,cyan-active))) + `(helm-etags-file ((,class :foreground ,fg-dim :underline t))) + `(helm-ff-backup-file ((,class :inherit shadow))) + `(helm-ff-denied ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-red + 'modus-theme-intense-red + 'modus-theme-nuanced-red + red)))) + `(helm-ff-directory ((,class :inherit helm-buffer-directory))) + `(helm-ff-dirs ((,class :inherit bold :foreground ,blue-alt-other))) + `(helm-ff-dotted-directory ((,class :inherit bold :background ,bg-alt :foreground ,fg-alt))) + `(helm-ff-dotted-symlink-directory ((,class :inherit (button helm-ff-dotted-directory)))) + `(helm-ff-executable ((,class :foreground ,magenta-alt))) + `(helm-ff-file ((,class :foreground ,fg-main))) + `(helm-ff-file-extension ((,class :foreground ,fg-special-warm))) + `(helm-ff-invalid-symlink ((,class :inherit button + ,@(modus-themes--link-color + red red-faint)))) + `(helm-ff-pipe ((,class ,@(modus-themes--extra-completions + 'modus-theme-refine-magenta + 'modus-theme-subtle-magenta + 'modus-theme-nuanced-magenta + magenta)))) + `(helm-ff-prefix ((,class ,@(modus-themes--extra-completions + 'modus-theme-refine-yellow + 'modus-theme-subtle-yellow + 'modus-theme-nuanced-yellow + yellow-alt-other)))) + `(helm-ff-socket ((,class :foreground ,red-alt-other))) + `(helm-ff-suid ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-red + 'modus-theme-refine-red + 'modus-theme-nuanced-yellow + red-alt)))) + `(helm-ff-symlink ((,class :inherit button + ,@(modus-themes--link-color + cyan cyan-faint)))) + `(helm-ff-truename ((,class :foreground ,blue-alt-other))) + `(helm-fd-finish ((,class :foreground ,green-active))) + `(helm-grep-cmd-line ((,class :foreground ,yellow-alt-other))) + `(helm-grep-file ((,class :inherit bold :foreground ,fg-special-cold))) + `(helm-grep-finish ((,class :foreground ,green-active))) + `(helm-grep-lineno ((,class :foreground ,fg-special-warm))) + `(helm-grep-match ((,class :inherit modus-theme-special-calm))) + `(helm-header ((,class :inherit bold :foreground ,fg-special-cold))) + `(helm-header-line-left-margin ((,class :inherit bold :foreground ,yellow-intense))) + `(helm-history-deleted ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-red + 'modus-theme-intense-red + 'modus-theme-nuanced-red + red + 'bold)))) + `(helm-history-remote ((,class :foreground ,red-alt-other))) + `(helm-lisp-completion-info ((,class :foreground ,fg-special-warm))) + `(helm-lisp-show-completion ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-yellow + 'modus-theme-refine-yellow + 'modus-theme-nuanced-yellow + yellow + 'bold)))) + `(helm-locate-finish ((,class :foreground ,green-active))) + `(helm-match ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-cyan + 'modus-theme-refine-cyan + 'modus-theme-nuanced-cyan + cyan + 'bold)))) + `(helm-match-item ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-neutral + 'modus-theme-subtle-cyan + 'modus-theme-nuanced-cyan + cyan-alt-other)))) + `(helm-minibuffer-prompt ((,class :inherit minibuffer-prompt))) + `(helm-moccur-buffer ((,class :inherit button + ,@(modus-themes--link-color + cyan-alt-other cyan-alt-other-faint)))) + `(helm-mode-prefix ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-magenta + 'modus-theme-intense-magenta + 'modus-theme-nuanced-magenta + magenta-alt + 'bold)))) + `(helm-non-file-buffer ((,class :inherit shadow))) + `(helm-prefarg ((,class :foreground ,red-active))) + `(helm-resume-need-update ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-magenta + 'modus-theme-refine-magenta + 'modus-theme-nuanced-magenta + magenta-alt-other)))) + `(helm-selection ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-blue + 'modus-theme-refine-blue + 'modus-theme-special-cold + nil + 'bold)))) + `(helm-selection-line ((,class :inherit modus-theme-special-cold))) + `(helm-separator ((,class :foreground ,fg-special-mild))) + `(helm-time-zone-current ((,class :foreground ,green))) + `(helm-time-zone-home ((,class :foreground ,magenta))) + `(helm-source-header ((,class :inherit bold :foreground ,red-alt + ,@(modus-themes--scale modus-themes-scale-4)))) + `(helm-top-columns ((,class :inherit helm-header))) + `(helm-ucs-char ((,class :foreground ,yellow-alt-other))) + `(helm-visible-mark ((,class :inherit modus-theme-subtle-cyan))) +;;;;; helm-ls-git + `(helm-ls-git-added-copied-face ((,class :foreground ,green-intense))) + `(helm-ls-git-added-modified-face ((,class :foreground ,yellow-intense))) + `(helm-ls-git-conflict-face ((,class :inherit bold :foreground ,red-intense))) + `(helm-ls-git-deleted-and-staged-face ((,class :foreground ,red-nuanced-fg))) + `(helm-ls-git-deleted-not-staged-face ((,class :foreground ,red))) + `(helm-ls-git-modified-and-staged-face ((,class :foreground ,yellow-nuanced-fg))) + `(helm-ls-git-modified-not-staged-face ((,class :foreground ,yellow))) + `(helm-ls-git-renamed-modified-face ((,class :foreground ,magenta))) + `(helm-ls-git-untracked-face ((,class :foreground ,fg-special-cold))) +;;;;; helm-switch-shell + `(helm-switch-shell-new-shell-face ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-magenta + 'modus-theme-refine-magenta + 'modus-theme-nuanced-magenta + magenta-alt-other + 'bold)))) +;;;;; helm-xref + `(helm-xref-file-name ((,class :inherit bold :foreground ,fg-special-cold))) + `(helm-xref-file-name ((,class :foreground ,fg-special-warm))) +;;;;; helpful + `(helpful-heading ((,class :inherit modus-theme-heading-1))) +;;;;; highlight region or ad-hoc regexp + `(hi-aquamarine ((,class :background ,cyan-subtle-bg :foreground ,fg-main))) + `(hi-black-b ((,class :inherit bold :background ,fg-main :foreground ,bg-main))) + `(hi-black-hb ((,class :inherit bold :background ,fg-alt :foreground ,bg-main))) + `(hi-blue ((,class :background ,blue-subtle-bg :foreground ,fg-main))) + `(hi-blue-b ((,class :inherit (bold hi-blue)))) + `(hi-green ((,class :background ,green-subtle-bg :foreground ,fg-main))) + `(hi-green-b ((,class :inherit (bold hi-green)))) + `(hi-pink ((,class :background ,magenta-subtle-bg :foreground ,fg-main))) + `(hi-pink-b ((,class :inherit (bold hi-pink)))) + `(hi-red-b ((,class :inherit bold :background ,red-intense-bg :foreground ,fg-main))) + `(hi-salmon ((,class :background ,red-subtle-bg :foreground ,fg-main))) + `(hi-yellow ((,class :background ,yellow-subtle-bg :foreground ,fg-main))) + `(highlight ((,class :inherit modus-theme-subtle-blue))) + `(highlight-changes ((,class :foreground ,yellow-alt-other))) + `(highlight-changes-delete ((,class :foreground ,red-alt-other :underline t))) + `(hl-line ((,class :inherit modus-theme-hl-line))) +;;;;; highlight-blocks + `(highlight-blocks-depth-1-face ((,class :background ,bg-dim :foreground ,fg-main))) + `(highlight-blocks-depth-2-face ((,class :background ,bg-alt :foreground ,fg-main))) + `(highlight-blocks-depth-3-face ((,class :background ,bg-special-cold :foreground ,fg-main))) + `(highlight-blocks-depth-4-face ((,class :background ,bg-special-calm :foreground ,fg-main))) + `(highlight-blocks-depth-5-face ((,class :background ,bg-special-warm :foreground ,fg-main))) + `(highlight-blocks-depth-6-face ((,class :background ,bg-special-mild :foreground ,fg-main))) + `(highlight-blocks-depth-7-face ((,class :background ,bg-inactive :foreground ,fg-main))) + `(highlight-blocks-depth-8-face ((,class :background ,bg-active :foreground ,fg-main))) + `(highlight-blocks-depth-9-face ((,class :background ,cyan-subtle-bg :foreground ,fg-main))) +;;;;; highlight-defined + `(highlight-defined-builtin-function-name-face ((,class :foreground ,magenta))) + `(highlight-defined-face-name-face ((,class :foreground ,fg-main))) + `(highlight-defined-function-name-face ((,class :foreground ,magenta))) + `(highlight-defined-macro-name-face ((,class :foreground ,magenta-alt))) + `(highlight-defined-special-form-name-face ((,class :foreground ,magenta-alt-other))) + `(highlight-defined-variable-name-face ((,class :foreground ,cyan))) +;;;;; highlight-escape-sequences (`hes-mode') + `(hes-escape-backslash-face ((,class :inherit bold :foreground ,fg-escape-char-construct))) + `(hes-escape-sequence-face ((,class :inherit bold :foreground ,fg-escape-char-backslash))) +;;;;; highlight-indentation + `(highlight-indentation-face ((,class :inherit modus-theme-hl-line))) + `(highlight-indentation-current-column-face ((,class :background ,bg-active))) +;;;;; highlight-numbers + `(highlight-numbers-number ((,class :foreground ,blue-alt-other))) +;;;;; highlight-symbol + `(highlight-symbol-face ((,class :inherit modus-theme-special-mild))) +;;;;; highlight-thing + `(highlight-thing ((,class :background ,bg-alt :foreground ,cyan))) +;;;;; hl-defined + `(hdefd-functions ((,class :foreground ,blue))) + `(hdefd-undefined ((,class :foreground ,red-alt))) + `(hdefd-variables ((,class :foreground ,cyan-alt))) +;;;;; hl-fill-column + `(hl-fill-column-face ((,class :background ,bg-active :foreground ,fg-active))) +;;;;; hl-todo + `(hl-todo ((,class :inherit (bold modus-theme-slant) :foreground ,red-alt-other))) +;;;;; hydra + `(hydra-face-amaranth ((,class :inherit bold :foreground ,yellow))) + `(hydra-face-blue ((,class :inherit bold :foreground ,blue-alt))) + `(hydra-face-pink ((,class :inherit bold :foreground ,magenta-alt))) + `(hydra-face-red ((,class :inherit bold :foreground ,red))) + `(hydra-face-teal ((,class :inherit bold :foreground ,cyan))) +;;;;; hyperlist + `(hyperlist-condition ((,class :foreground ,green))) + `(hyperlist-hashtag ((,class :foreground ,yellow))) + `(hyperlist-operator ((,class :foreground ,blue-alt))) + `(hyperlist-paren ((,class :foreground ,cyan-alt-other))) + `(hyperlist-quote ((,class :foreground ,cyan-alt))) + `(hyperlist-ref ((,class :foreground ,magenta-alt-other))) + `(hyperlist-stars ((,class :inherit shadow))) + `(hyperlist-tag ((,class :foreground ,red))) + `(hyperlist-toplevel ((,class :inherit bold :foreground ,fg-main))) +;;;;; icomplete + `(icomplete-first-match ((,class :inherit bold + ,@(modus-themes--standard-completions + magenta bg-alt + bg-active fg-main)))) +;;;;; icomplete-vertical + `(icomplete-vertical-separator ((,class :inherit shadow))) +;;;;; ido-mode + `(ido-first-match ((,class :inherit bold + ,@(modus-themes--standard-completions + magenta bg-alt + bg-active fg-main)))) + `(ido-incomplete-regexp ((,class :inherit error))) + `(ido-indicator ((,class :inherit modus-theme-subtle-yellow))) + `(ido-only-match ((,class :inherit bold + ,@(modus-themes--standard-completions + green green-nuanced-bg + green-intense-bg fg-main)))) + `(ido-subdir ((,class :foreground ,blue))) + `(ido-virtual ((,class :foreground ,fg-special-warm))) +;;;;; iedit + `(iedit-occurrence ((,class :inherit modus-theme-refine-blue))) + `(iedit-read-only-occurrence ((,class :inherit modus-theme-intense-yellow))) +;;;;; iflipb + `(iflipb-current-buffer-face ((,class :inherit bold :foreground ,cyan-alt))) + `(iflipb-other-buffer-face ((,class :inherit shadow))) +;;;;; imenu-list + `(imenu-list-entry-face-0 ((,class :foreground ,cyan))) + `(imenu-list-entry-face-1 ((,class :foreground ,blue))) + `(imenu-list-entry-face-2 ((,class :foreground ,cyan-alt-other))) + `(imenu-list-entry-face-3 ((,class :foreground ,blue-alt))) + `(imenu-list-entry-subalist-face-0 ((,class :inherit bold :foreground ,magenta-alt-other :underline t))) + `(imenu-list-entry-subalist-face-1 ((,class :inherit bold :foreground ,magenta :underline t))) + `(imenu-list-entry-subalist-face-2 ((,class :inherit bold :foreground ,green-alt-other :underline t))) + `(imenu-list-entry-subalist-face-3 ((,class :inherit bold :foreground ,red-alt-other :underline t))) +;;;;; indium + `(indium-breakpoint-face ((,class :foreground ,red-active))) + `(indium-frame-url-face ((,class :inherit button :foreground ,fg-alt))) + `(indium-keyword-face ((,class :foreground ,magenta-alt-other))) + `(indium-litable-face ((,class :inherit modus-theme-slant :foreground ,fg-special-warm))) + `(indium-repl-error-face ((,class :inherit bold :foreground ,red))) + `(indium-repl-prompt-face ((,class :foreground ,cyan-alt-other))) + `(indium-repl-stdout-face ((,class :foreground ,fg-main))) +;;;;; info + `(Info-quoted ((,class ,@(modus-themes--mixed-fonts) ; the capitalization is canonical + :background ,bg-alt :foreground ,fg-special-calm))) + `(info-header-node ((,class :inherit bold :foreground ,fg-alt))) + `(info-header-xref ((,class :foreground ,blue-active))) + `(info-index-match ((,class :inherit match))) + `(info-menu-header ((,class :inherit modus-theme-heading-3))) + `(info-menu-star ((,class :foreground ,red))) + `(info-node ((,class :inherit bold))) + `(info-title-1 ((,class :inherit modus-theme-heading-1))) + `(info-title-2 ((,class :inherit modus-theme-heading-2))) + `(info-title-3 ((,class :inherit modus-theme-heading-3))) + `(info-title-4 ((,class :inherit modus-theme-heading-4))) +;;;;; info-colors + `(info-colors-lisp-code-block ((,class :inherit fixed-pitch))) + `(info-colors-ref-item-command ((,class :foreground ,magenta))) + `(info-colors-ref-item-constant ((,class :inherit font-lock-constant-face))) + `(info-colors-ref-item-function ((,class :inherit font-lock-function-name-face))) + `(info-colors-ref-item-macro ((,class :inherit font-lock-keyword-face))) + `(info-colors-ref-item-other ((,class :inherit font-lock-doc-face))) + `(info-colors-ref-item-special-form ((,class :inherit font-lock-keyword-face))) + `(info-colors-ref-item-syntax-class ((,class :inherit font-lock-builtin-face))) + `(info-colors-ref-item-type ((,class :inherit font-lock-type-face))) + `(info-colors-ref-item-user-option ((,class :inherit font-lock-variable-name-face))) + `(info-colors-ref-item-variable ((,class :inherit font-lock-variable-name-face))) +;;;;; interaction-log + `(ilog-buffer-face ((,class :foreground ,magenta-alt-other))) + `(ilog-change-face ((,class :foreground ,magenta-alt))) + `(ilog-echo-face ((,class :foreground ,yellow-alt-other))) + `(ilog-load-face ((,class :foreground ,green))) + `(ilog-message-face ((,class :inherit shadow))) + `(ilog-non-change-face ((,class :foreground ,blue))) +;;;;; ioccur + `(ioccur-cursor ((,class :foreground ,fg-main))) + `(ioccur-invalid-regexp ((,class :foreground ,red))) + `(ioccur-match-face ((,class :inherit modus-theme-special-calm))) + `(ioccur-match-overlay-face ((,class :inherit modus-theme-special-cold :extend t))) + `(ioccur-num-line-face ((,class :foreground ,fg-special-warm))) + `(ioccur-overlay-face ((,class :inherit modus-theme-refine-blue :extend t))) + `(ioccur-regexp-face ((,class :inherit (modus-theme-intense-magenta bold)))) + `(ioccur-title-face ((,class :inherit bold :foreground ,red-alt + ,@(modus-themes--scale modus-themes-scale-4)))) +;;;;; isearch, occur, and the like + `(isearch ((,class :inherit (modus-theme-intense-green bold)))) + `(isearch-fail ((,class :inherit modus-theme-refine-red))) + `(isearch-group-1 ((,class :inherit modus-theme-intense-blue))) + `(isearch-group-2 ((,class :inherit modus-theme-intense-magenta))) + `(lazy-highlight ((,class :inherit modus-theme-refine-cyan))) + `(match ((,class :inherit modus-theme-special-calm))) + `(query-replace ((,class :inherit (modus-theme-intense-yellow bold)))) +;;;;; isl (isearch-light) + `(isl-line ((,class :inherit modus-theme-subtle-green))) + `(isl-match ((,class :inherit modus-theme-refine-cyan))) + `(isl-number ((,class :inherit modus-theme-bold :foreground ,green-active))) + `(isl-on ((,class :inherit (bold modus-theme-intense-green)))) + `(isl-string ((,class :inherit modus-theme-bold :foreground ,cyan-active))) +;;;;; ivy + `(ivy-action ((,class :inherit bold :foreground ,red-alt))) + `(ivy-completions-annotations ((,class :inherit completions-annotations))) + `(ivy-confirm-face ((,class :foreground ,cyan))) + `(ivy-current-match ((,class ,@(modus-themes--extra-completions + 'modus-theme-refine-cyan + 'modus-theme-intense-cyan + 'modus-theme-special-cold + nil + 'bold)))) + `(ivy-cursor ((,class :background ,fg-main :foreground ,bg-main))) + `(ivy-grep-info ((,class :foreground ,cyan-alt))) + `(ivy-grep-line-number ((,class :foreground ,fg-special-warm))) + `(ivy-highlight-face ((,class :foreground ,magenta))) + `(ivy-match-required-face ((,class :inherit error))) + `(ivy-minibuffer-match-face-1 ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-neutral + 'modus-theme-intense-neutral + 'modus-theme-nuanced-cyan + fg-alt)))) + `(ivy-minibuffer-match-face-2 ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-green + 'modus-theme-refine-green + 'modus-theme-nuanced-green + green-alt-other + 'bold)))) + `(ivy-minibuffer-match-face-3 ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-blue + 'modus-theme-refine-blue + 'modus-theme-nuanced-blue + blue-alt-other + 'bold)))) + `(ivy-minibuffer-match-face-4 ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-magenta + 'modus-theme-refine-magenta + 'modus-theme-nuanced-magenta + magenta-alt-other + 'bold)))) + `(ivy-minibuffer-match-highlight ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-cyan + 'modus-theme-intense-cyan + 'modus-theme-nuanced-cyan + cyan-alt-other + 'bold)))) + `(ivy-modified-buffer ((,class :inherit modus-theme-slant :foreground ,yellow))) + `(ivy-modified-outside-buffer ((,class :inherit modus-theme-slant :foreground ,yellow-alt))) + `(ivy-org ((,class :foreground ,cyan-alt-other))) + `(ivy-prompt-match ((,class :inherit ivy-current-match))) + `(ivy-remote ((,class :foreground ,magenta))) + `(ivy-separator ((,class :inherit shadow))) + `(ivy-subdir ((,class :foreground ,blue-alt-other))) + `(ivy-virtual ((,class :foreground ,magenta-alt-other))) + `(ivy-yanked-word ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-blue + 'modus-theme-refine-blue + 'modus-theme-nuanced-blue + blue-alt)))) +;;;;; ivy-posframe + `(ivy-posframe ((,class :background ,bg-dim :foreground ,fg-main))) + `(ivy-posframe-border ((,class :background ,fg-window-divider-inner))) + `(ivy-posframe-cursor ((,class :background ,fg-main :foreground ,bg-main))) +;;;;; jira (org-jira) + `(jiralib-comment-face ((,class :background ,bg-alt))) + `(jiralib-comment-header-face ((,class :inherit bold))) + `(jiralib-issue-info-face ((,class :inherit modus-theme-special-warm))) + `(jiralib-issue-info-header-face ((,class :inherit (modus-theme-special-warm bold)))) + `(jiralib-issue-summary-face ((,class :inherit bold))) + `(jiralib-link-filter-face ((,class :underline t))) + `(jiralib-link-issue-face ((,class :underline t))) + `(jiralib-link-project-face ((,class :underline t))) +;;;;; journalctl-mode + `(journalctl-error-face ((,class :inherit bold :foreground ,red))) + `(journalctl-finished-face ((,class :inherit bold :foreground ,green))) + `(journalctl-host-face ((,class :foreground ,blue))) + `(journalctl-process-face ((,class :foreground ,cyan-alt-other))) + `(journalctl-starting-face ((,class :foreground ,green))) + `(journalctl-timestamp-face ((,class :foreground ,fg-special-cold))) + `(journalctl-warning-face ((,class :inherit bold :foreground ,yellow))) +;;;;; js2-mode + `(js2-error ((,class :foreground ,red))) + `(js2-external-variable ((,class :foreground ,cyan-alt-other))) + `(js2-function-call ((,class :foreground ,magenta))) + `(js2-function-param ((,class :foreground ,blue))) + `(js2-instance-member ((,class :foreground ,magenta-alt-other))) + `(js2-jsdoc-html-tag-delimiter ((,class :foreground ,fg-main))) + `(js2-jsdoc-html-tag-name ((,class :foreground ,cyan))) + `(js2-jsdoc-tag ((,class :foreground ,fg-special-calm))) + `(js2-jsdoc-type ((,class :foreground ,fg-special-cold))) + `(js2-jsdoc-value ((,class :foreground ,fg-special-warm))) + `(js2-object-property ((,class :foreground ,fg-main))) + `(js2-object-property-access ((,class :foreground ,fg-main))) + `(js2-private-function-call ((,class :foreground ,green-alt-other))) + `(js2-private-member ((,class :foreground ,fg-special-mild))) + `(js2-warning ((,class :foreground ,yellow-alt :underline t))) +;;;;; julia + `(julia-macro-face ((,class :inherit modus-theme-bold :foreground ,magenta))) + `(julia-quoted-symbol-face ((,class :foreground ,blue-alt-other))) +;;;;; jupyter + `(jupyter-eval-overlay ((,class :inherit bold :foreground ,blue))) + `(jupyter-repl-input-prompt ((,class :foreground ,cyan-alt-other))) + `(jupyter-repl-output-prompt ((,class :foreground ,magenta-alt-other))) + `(jupyter-repl-traceback ((,class :inherit modus-theme-intense-red))) +;;;;; kaocha-runner + `(kaocha-runner-error-face ((,class :foreground ,red))) + `(kaocha-runner-success-face ((,class :foreground ,green))) + `(kaocha-runner-warning-face ((,class :foreground ,yellow))) +;;;;; keycast + `(keycast-command ((,class :inherit bold :foreground ,blue-active))) + `(keycast-key ((,class ,@(modus-themes--mode-line-attrs + bg-main blue-active + bg-main blue-active + blue-active blue-intense + 'alt-style -3)))) +;;;;; line numbers (display-line-numbers-mode and global variant) + `(line-number + ((,class :inherit default + ,@(modus-themes--line-numbers + fg-alt bg-dim + fg-unfocused)))) + `(line-number-current-line + ((,class :inherit (bold default) + ,@(modus-themes--line-numbers + fg-main bg-active + blue-alt-other)))) + `(line-number-major-tick + ((,class :inherit (bold default) + ,@(modus-themes--line-numbers + yellow-nuanced-fg yellow-nuanced-bg + red-alt)))) + `(line-number-minor-tick + ((,class :inherit (bold default) + ,@(modus-themes--line-numbers + fg-alt bg-inactive + fg-inactive)))) +;;;;; lsp-mode + `(lsp-face-highlight-read ((,class :inherit modus-theme-subtle-blue :underline t))) + `(lsp-face-highlight-textual ((,class :inherit modus-theme-subtle-blue))) + `(lsp-face-highlight-write ((,class :inherit (modus-theme-refine-blue bold)))) + `(lsp-face-semhl-constant ((,class :foreground ,blue-alt-other))) + `(lsp-face-semhl-deprecated + ((,(append '((supports :underline (:style wave))) class) + :foreground ,yellow :underline (:style wave)) + (,class :foreground ,yellow :underline t))) + `(lsp-face-semhl-enummember ((,class :foreground ,blue-alt-other))) + `(lsp-face-semhl-field ((,class :foreground ,cyan-alt))) + `(lsp-face-semhl-field-static ((,class :inherit modus-theme-slant :foreground ,cyan-alt))) + `(lsp-face-semhl-function ((,class :foreground ,magenta))) + `(lsp-face-semhl-method ((,class :foreground ,magenta))) + `(lsp-face-semhl-namespace ((,class :inherit modus-theme-bold :foreground ,magenta-alt))) + `(lsp-face-semhl-preprocessor ((,class :foreground ,red-alt-other))) + `(lsp-face-semhl-static-method ((,class :inherit modus-theme-slant :foreground ,magenta))) + `(lsp-face-semhl-type-class ((,class :foreground ,magenta-alt))) + `(lsp-face-semhl-type-enum ((,class :foreground ,magenta-alt))) + `(lsp-face-semhl-type-primitive ((,class :inherit modus-theme-slant :foreground ,magenta-alt))) + `(lsp-face-semhl-type-template ((,class :inherit modus-theme-slant :foreground ,magenta-alt))) + `(lsp-face-semhl-type-typedef ((,class :inherit modus-theme-slant :foreground ,magenta-alt))) + `(lsp-face-semhl-variable ((,class :foreground ,cyan))) + `(lsp-face-semhl-variable-local ((,class :foreground ,cyan))) + `(lsp-face-semhl-variable-parameter ((,class :foreground ,cyan-alt-other))) + `(lsp-lens-face ((,class :height 0.8 :foreground ,fg-alt))) + `(lsp-lens-mouse-face ((,class :height 0.8 :foreground ,blue-alt-other :underline t))) + `(lsp-ui-doc-background ((,class :background ,bg-alt))) + `(lsp-ui-doc-header ((,class :background ,bg-header :foreground ,fg-header))) + `(lsp-ui-doc-url ((,class :inherit button))) + `(lsp-ui-peek-filename ((,class :foreground ,fg-special-warm))) + `(lsp-ui-peek-footer ((,class :background ,bg-header :foreground ,fg-header))) + `(lsp-ui-peek-header ((,class :background ,bg-header :foreground ,fg-header))) + `(lsp-ui-peek-highlight ((,class :inherit modus-theme-subtle-blue))) + `(lsp-ui-peek-line-number ((,class :inherit shadow))) + `(lsp-ui-peek-list ((,class :background ,bg-dim))) + `(lsp-ui-peek-peek ((,class :background ,bg-alt))) + `(lsp-ui-peek-selection ((,class :inherit modus-theme-subtle-cyan))) + `(lsp-ui-sideline-code-action ((,class :foreground ,yellow))) + `(lsp-ui-sideline-current-symbol ((,class :inherit bold :height 0.99 :box (:line-width -1 :style nil) :foreground ,fg-main))) + `(lsp-ui-sideline-symbol ((,class :inherit bold :height 0.99 :box (:line-width -1 :style nil) :foreground ,fg-alt))) + `(lsp-ui-sideline-symbol-info ((,class :inherit italic :height 0.99))) +;;;;; macrostep + `(macrostep-compiler-macro-face ((,class :inherit italic))) + `(macrostep-expansion-highlight-face ((,class :background ,blue-nuanced-bg))) + `(macrostep-gensym-1 ((,class :inherit bold :foreground ,blue :box t))) + `(macrostep-gensym-2 ((,class :inherit bold :foreground ,green :box t))) + `(macrostep-gensym-3 ((,class :inherit bold :foreground ,yellow :box t))) + `(macrostep-gensym-4 ((,class :inherit bold :foreground ,red :box t))) + `(macrostep-gensym-5 ((,class :inherit bold :foreground ,magenta :box t))) + `(macrostep-macro-face ((,class :inherit button :foreground ,green-alt))) +;;;;; magit + `(magit-bisect-bad ((,class :foreground ,red-alt-other))) + `(magit-bisect-good ((,class :foreground ,green-alt-other))) + `(magit-bisect-skip ((,class :foreground ,yellow-alt-other))) + `(magit-blame-date ((,class :foreground ,blue))) + `(magit-blame-dimmed ((,class :inherit shadow))) + `(magit-blame-hash ((,class :foreground ,fg-special-warm))) + `(magit-blame-heading ((,class :background ,bg-alt))) + `(magit-blame-highlight ((,class :inherit modus-theme-nuanced-cyan))) + `(magit-blame-margin ((,class :inherit magit-blame-highlight))) + `(magit-blame-name ((,class :foreground ,magenta-alt-other))) + `(magit-blame-summary ((,class :foreground ,cyan-alt-other))) + `(magit-branch-current ((,class :foreground ,blue-alt-other :box t))) + `(magit-branch-local ((,class :foreground ,blue-alt))) + `(magit-branch-remote ((,class :foreground ,magenta-alt))) + `(magit-branch-remote-head ((,class :foreground ,magenta-alt-other :box t))) + `(magit-branch-upstream ((,class :inherit italic))) + `(magit-cherry-equivalent ((,class :background ,bg-main :foreground ,magenta-intense))) + `(magit-cherry-unmatched ((,class :background ,bg-main :foreground ,cyan-intense))) + ;; NOTE: here we break from the pattern of inheriting from the + ;; modus-theme-diff-* faces, though only for the standard actions, + ;; not the highlighted ones. This is because Magit's interaction + ;; model relies on highlighting the current diff hunk. + `(magit-diff-added ((,class ,@(modus-themes--diff + bg-main green + bg-diff-added fg-diff-added + green-nuanced-bg fg-diff-added + bg-diff-added-deuteran fg-diff-added-deuteran)))) + `(magit-diff-added-highlight ((,class :inherit modus-theme-diff-focus-added))) + `(magit-diff-base ((,class ,@(modus-themes--diff + bg-main yellow + bg-diff-changed fg-diff-changed + yellow-nuanced-bg fg-diff-changed)))) + `(magit-diff-base-highlight ((,class :inherit modus-theme-diff-focus-changed))) + `(magit-diff-context ((,class :foreground ,fg-unfocused))) + `(magit-diff-context-highlight ((,class ,@(modus-themes--diff + bg-dim fg-dim + bg-inactive fg-inactive + bg-dim fg-alt)))) + `(magit-diff-file-heading ((,class :inherit bold :foreground ,fg-special-cold))) + `(magit-diff-file-heading-highlight ((,class :inherit (modus-theme-special-cold bold)))) + `(magit-diff-file-heading-selection ((,class :inherit modus-theme-refine-cyan))) + ;; NOTE: here we break from the pattern of inheriting from the + ;; modus-theme-diff-* faces. + `(magit-diff-hunk-heading ((,class :inherit bold :background ,bg-active + :foreground ,fg-inactive))) + `(magit-diff-hunk-heading-highlight + ((,class :inherit bold + :background ,@(modus-themes--diff-deuteran bg-region bg-diff-heading) + :foreground ,@(modus-themes--diff-deuteran fg-main fg-diff-heading)))) + `(magit-diff-hunk-heading-selection ((,class :inherit modus-theme-refine-blue))) + `(magit-diff-hunk-region ((,class :inherit bold))) + `(magit-diff-lines-boundary ((,class :background ,fg-main))) + `(magit-diff-lines-heading ((,class :inherit modus-theme-refine-magenta))) + `(magit-diff-removed ((,class ,@(modus-themes--diff + bg-main red + bg-diff-removed fg-diff-removed + red-nuanced-bg fg-diff-removed)))) + `(magit-diff-removed-highlight ((,class :inherit modus-theme-diff-focus-removed))) + `(magit-diffstat-added ((,class :foreground ,@(modus-themes--diff-deuteran blue green)))) + `(magit-diffstat-removed ((,class :foreground ,red))) + `(magit-dimmed ((,class :foreground ,fg-unfocused))) + `(magit-filename ((,class :foreground ,fg-special-cold))) + `(magit-hash ((,class :inherit shadow))) + `(magit-head ((,class :inherit magit-branch-local))) + `(magit-header-line ((,class :inherit bold :foreground ,magenta-active))) + `(magit-header-line-key ((,class :inherit bold :foreground ,blue-active))) + `(magit-header-line-log-select ((,class :inherit bold :foreground ,fg-main))) + `(magit-keyword ((,class :foreground ,magenta))) + `(magit-keyword-squash ((,class :inherit bold :foreground ,yellow-alt-other))) + `(magit-log-author ((,class :foreground ,cyan))) + `(magit-log-date ((,class :inherit shadow))) + `(magit-log-graph ((,class :foreground ,fg-dim))) + `(magit-mode-line-process ((,class :inherit bold :foreground ,blue-active))) + `(magit-mode-line-process-error ((,class :inherit bold :foreground ,red-active))) + `(magit-process-ng ((,class :inherit error))) + `(magit-process-ok ((,class :inherit success))) + `(magit-reflog-amend ((,class :background ,bg-main :foreground ,magenta-intense))) + `(magit-reflog-checkout ((,class :background ,bg-main :foreground ,blue-intense))) + `(magit-reflog-cherry-pick ((,class :background ,bg-main :foreground ,green-intense))) + `(magit-reflog-commit ((,class :background ,bg-main :foreground ,green-intense))) + `(magit-reflog-merge ((,class :background ,bg-main :foreground ,green-intense))) + `(magit-reflog-other ((,class :background ,bg-main :foreground ,cyan-intense))) + `(magit-reflog-rebase ((,class :background ,bg-main :foreground ,magenta-intense))) + `(magit-reflog-remote ((,class :background ,bg-main :foreground ,cyan-intense))) + `(magit-reflog-reset ((,class :background ,bg-main :foreground ,red-intense))) + `(magit-refname ((,class :inherit shadow))) + `(magit-refname-pullreq ((,class :inherit shadow))) + `(magit-refname-stash ((,class :inherit shadow))) + `(magit-refname-wip ((,class :inherit shadow))) + `(magit-section ((,class :background ,bg-dim :foreground ,fg-main))) + `(magit-section-heading ((,class :inherit bold :foreground ,cyan))) + `(magit-section-heading-selection ((,class :inherit (modus-theme-refine-cyan bold)))) + `(magit-section-highlight ((,class :background ,bg-alt))) + `(magit-sequence-done ((,class :foreground ,green-alt))) + `(magit-sequence-drop ((,class :foreground ,red-alt))) + `(magit-sequence-exec ((,class :foreground ,magenta-alt))) + `(magit-sequence-head ((,class :foreground ,cyan-alt))) + `(magit-sequence-onto ((,class :inherit shadow))) + `(magit-sequence-part ((,class :foreground ,yellow-alt))) + `(magit-sequence-pick ((,class :foreground ,blue-alt))) + `(magit-sequence-stop ((,class :foreground ,red))) + `(magit-signature-bad ((,class :inherit bold :foreground ,red))) + `(magit-signature-error ((,class :foreground ,red-alt))) + `(magit-signature-expired ((,class :foreground ,yellow))) + `(magit-signature-expired-key ((,class :foreground ,yellow))) + `(magit-signature-good ((,class :foreground ,green))) + `(magit-signature-revoked ((,class :foreground ,magenta))) + `(magit-signature-untrusted ((,class :foreground ,cyan))) + `(magit-tag ((,class :foreground ,yellow-alt-other))) +;;;;; magit-imerge + `(magit-imerge-overriding-value ((,class :inherit bold :foreground ,red-alt))) +;;;;; make-mode (makefiles) + `(makefile-makepp-perl ((,class :background ,cyan-nuanced-bg))) + `(makefile-space ((,class :background ,magenta-nuanced-bg))) +;;;;; man + `(Man-overstrike ((,class :inherit bold :foreground ,magenta))) + `(Man-reverse ((,class :inherit modus-theme-subtle-magenta))) + `(Man-underline ((,class :foreground ,cyan :underline t))) +;;;;; marginalia + `(marginalia-archive ((,class :foreground ,green-nuanced-fg))) + `(marginalia-date ((,class :foreground ,blue-nuanced-fg))) + `(marginalia-char ((,class :foreground ,red-active))) + `(marginalia-documentation ((,class :foreground ,fg-special-cold :inherit modus-theme-slant))) + `(marginalia-file-modes ((,class :inherit shadow))) + `(marginalia-file-name ((,class :foreground ,fg-special-mild))) + `(marginalia-file-owner ((,class :foreground ,red-nuanced-fg))) + `(marginalia-key ((,class :foreground ,magenta-active))) + `(marginalia-mode ((,class :foreground ,cyan-active))) + `(marginalia-modified ((,class :foreground ,yellow-active))) + `(marginalia-number ((,class :foreground ,blue-active))) + `(marginalia-size ((,class :foreground ,green-active))) + `(marginalia-type ((,class :foreground ,fg-special-warm))) + `(marginalia-variable ((,class :foreground ,yellow-nuanced-fg))) + `(marginalia-version ((,class :foreground ,cyan-active))) +;;;;; markdown-mode + `(markdown-blockquote-face ((,class :inherit modus-theme-slant :foreground ,fg-special-cold))) + `(markdown-bold-face ((,class :inherit bold))) + `(markdown-code-face ((,class ,@(modus-themes--mixed-fonts) :background ,bg-dim :extend t))) + `(markdown-comment-face ((,class :inherit font-lock-comment-face))) + `(markdown-footnote-marker-face ((,class :inherit bold :foreground ,cyan-alt))) + `(markdown-footnote-text-face ((,class :inherit modus-theme-slant :foreground ,fg-main))) + `(markdown-gfm-checkbox-face ((,class :foreground ,cyan-alt-other))) + `(markdown-header-delimiter-face ((,class :inherit modus-theme-bold :foreground ,fg-dim))) + `(markdown-header-face ((t nil))) + `(markdown-header-face-1 ((,class :inherit modus-theme-heading-1))) + `(markdown-header-face-2 ((,class :inherit modus-theme-heading-2))) + `(markdown-header-face-3 ((,class :inherit modus-theme-heading-3))) + `(markdown-header-face-4 ((,class :inherit modus-theme-heading-4))) + `(markdown-header-face-5 ((,class :inherit modus-theme-heading-5))) + `(markdown-header-face-6 ((,class :inherit modus-theme-heading-6))) + `(markdown-header-rule-face ((,class :inherit bold :foreground ,fg-special-warm))) + `(markdown-hr-face ((,class :inherit bold :foreground ,fg-special-warm))) + `(markdown-html-attr-name-face ((,class ,@(modus-themes--mixed-fonts) + :foreground ,cyan))) + `(markdown-html-attr-value-face ((,class ,@(modus-themes--mixed-fonts) + :foreground ,blue))) + `(markdown-html-entity-face ((,class ,@(modus-themes--mixed-fonts) + :foreground ,cyan))) + `(markdown-html-tag-delimiter-face ((,class ,@(modus-themes--mixed-fonts) + :foreground ,fg-special-mild))) + `(markdown-html-tag-name-face ((,class ,@(modus-themes--mixed-fonts) + :foreground ,magenta-alt))) + `(markdown-inline-code-face ((,class ,@(modus-themes--mixed-fonts) + :background ,bg-alt :foreground ,fg-special-calm))) + `(markdown-italic-face ((,class :inherit italic :foreground ,fg-special-cold))) + `(markdown-language-info-face ((,class ,@(modus-themes--mixed-fonts) + :foreground ,fg-special-cold))) + `(markdown-language-keyword-face ((,class ,@(modus-themes--mixed-fonts) + :background ,bg-alt + :foreground ,fg-alt))) + `(markdown-line-break-face ((,class :inherit modus-theme-refine-cyan :underline t))) + `(markdown-link-face ((,class :inherit button))) + `(markdown-link-title-face ((,class :inherit modus-theme-slant :foreground ,fg-special-cold))) + `(markdown-list-face ((,class :foreground ,fg-dim))) + `(markdown-markup-face ((,class :inherit shadow))) + `(markdown-math-face ((,class :foreground ,magenta-alt-other))) + `(markdown-metadata-key-face ((,class :foreground ,cyan-alt-other))) + `(markdown-metadata-value-face ((,class :foreground ,blue-alt))) + `(markdown-missing-link-face ((,class :inherit bold :foreground ,yellow))) + `(markdown-plain-url-face ((,class :inherit markdown-link-face))) + `(markdown-pre-face ((,class :inherit markdown-code-face :foreground ,fg-special-mild))) + `(markdown-reference-face ((,class :inherit markdown-markup-face))) + `(markdown-strike-through-face ((,class :strike-through t))) + `(markdown-table-face ((,class ,@(modus-themes--mixed-fonts) + :foreground ,fg-special-cold))) + `(markdown-url-face ((,class :foreground ,blue-alt))) +;;;;; markup-faces (`adoc-mode') + `(markup-anchor-face ((,class :foreground ,fg-inactive))) + `(markup-attribute-face ((,class :inherit italic :foreground ,fg-inactive))) + `(markup-big-face ((,class :height 1.3 :foreground ,blue-nuanced-fg))) + `(markup-bold-face ((,class :inherit bold :foreground ,red-nuanced-fg))) + `(markup-code-face ((,class :inherit fixed-pitch :foreground ,magenta))) + `(markup-command-face ((,class :foreground ,fg-inactive))) + `(markup-comment-face ((,class :inherit font-lock-comment-face))) + `(markup-complex-replacement-face ((,class :box (:line-width 2 :color nil :style released-button) + :inherit modus-theme-refine-magenta))) + `(markup-emphasis-face ((,class :inherit italic :foreground ,fg-special-cold))) + `(markup-error-face ((,class :inherit bold :foreground ,red))) + `(markup-gen-face ((,class :foreground ,magenta-alt))) + `(markup-internal-reference-face ((,class :inherit button :foreground ,fg-alt))) + `(markup-italic-face ((,class :inherit italic :foreground ,fg-special-cold))) + `(markup-list-face ((,class :inherit modus-theme-special-calm))) + `(markup-meta-face ((,class :foreground ,fg-inactive))) + `(markup-meta-hide-face ((,class :inherit shadow))) + `(markup-passthrough-face ((,class :inherit fixed-pitch :foreground ,cyan))) + `(markup-preprocessor-face ((,class :foreground ,red-alt-other))) + `(markup-replacement-face ((,class :foreground ,yellow-alt-other))) + `(markup-secondary-text-face ((,class :height 0.8 :foreground ,magenta-nuanced-fg))) + `(markup-small-face ((,class :height 0.8 :foreground ,fg-main))) + `(markup-strong-face ((,class :inherit bold :foreground ,red-nuanced-fg))) + `(markup-subscript-face ((,class :height 0.8 :foreground ,fg-special-cold))) + `(markup-superscript-face ((,class :height 0.8 :foreground ,fg-special-cold))) + `(markup-table-cell-face ((,class :inherit modus-theme-special-cold))) + `(markup-table-face ((,class :inherit modus-theme-subtle-cyan))) + `(markup-table-row-face ((,class :inherit modus-theme-subtle-cyan))) + `(markup-title-0-face ((,class :height 3.0 :foreground ,blue-nuanced-fg))) + `(markup-title-1-face ((,class :height 2.4 :foreground ,blue-nuanced-fg))) + `(markup-title-2-face ((,class :height 1.8 :foreground ,blue-nuanced-fg))) + `(markup-title-3-face ((,class :height 1.4 :foreground ,blue-nuanced-fg))) + `(markup-title-4-face ((,class :height 1.2 :foreground ,blue-nuanced-fg))) + `(markup-title-5-face ((,class :height 1.2 :foreground ,blue-nuanced-fg :underline t))) + `(markup-value-face ((,class :foreground ,fg-inactive))) + `(markup-verbatim-face ((,class :inherit modus-theme-special-mild))) +;;;;; mentor + `(mentor-download-message ((,class :foreground ,fg-special-warm))) + `(mentor-download-name ((,class :foreground ,fg-special-cold))) + `(mentor-download-progress ((,class :foreground ,blue-alt-other))) + `(mentor-download-size ((,class :foreground ,magenta-alt-other))) + `(mentor-download-speed-down ((,class :foreground ,cyan-alt))) + `(mentor-download-speed-up ((,class :foreground ,red-alt))) + `(mentor-download-state ((,class :foreground ,yellow-alt))) + `(mentor-highlight-face ((,class :inherit modus-theme-subtle-blue))) + `(mentor-tracker-name ((,class :foreground ,magenta-alt))) +;;;;; messages + `(message-cited-text-1 ((,class :foreground ,blue-faint))) + `(message-cited-text-2 ((,class :foreground ,green-alt-other))) + `(message-cited-text-3 ((,class :foreground ,red-alt-other))) + `(message-cited-text-4 ((,class :foreground ,cyan))) + `(message-header-cc ((,class :foreground ,blue-alt-other))) + `(message-header-name ((,class :inherit bold :foreground ,cyan))) + `(message-header-newsgroups ((,class :inherit message-header-other))) + `(message-header-other ((,class :foreground ,fg-special-calm))) + `(message-header-subject ((,class :inherit bold :foreground ,magenta-alt))) + `(message-header-to ((,class :inherit bold :foreground ,magenta-alt-other))) + `(message-header-xheader ((,class :foreground ,blue-alt))) + `(message-mml ((,class :foreground ,yellow))) + `(message-separator ((,class :inherit modus-theme-intense-neutral))) +;;;;; minibuffer-line + `(minibuffer-line ((,class :foreground ,fg-main))) +;;;;; minimap + `(minimap-active-region-background ((,class :background ,bg-active))) + `(minimap-current-line-face ((,class :background ,cyan-intense-bg :foreground ,fg-main))) +;;;;; mmm-mode + `(mmm-cleanup-submode-face ((,class :background ,yellow-nuanced-bg))) + `(mmm-code-submode-face ((,class :background ,bg-alt))) + `(mmm-comment-submode-face ((,class :background ,blue-nuanced-bg))) + `(mmm-declaration-submode-face ((,class :background ,cyan-nuanced-bg))) + `(mmm-default-submode-face ((,class :background ,bg-dim))) + `(mmm-init-submode-face ((,class :background ,magenta-nuanced-bg))) + `(mmm-output-submode-face ((,class :background ,red-nuanced-bg))) + `(mmm-special-submode-face ((,class :background ,green-nuanced-bg))) +;;;;; modeline + `(mode-line ((,class ,@(modus-themes--variable-pitch-ui) + ,@(modus-themes--mode-line-attrs + fg-active bg-active fg-dim bg-active + fg-alt bg-active 'alt-style nil bg-main)))) + `(mode-line-buffer-id ((,class :inherit bold))) + `(mode-line-emphasis ((,class :inherit bold :foreground ,blue-active))) + `(mode-line-highlight ((,class :inherit modus-theme-active-blue :box (:line-width -1 :style pressed-button)))) + `(mode-line-inactive ((,class ,@(modus-themes--variable-pitch-ui) + ,@(modus-themes--mode-line-attrs + fg-inactive bg-inactive fg-alt bg-dim + bg-region bg-active)))) +;;;;; mood-line + `(mood-line-modified ((,class :foreground ,magenta-active))) + `(mood-line-status-error ((,class :inherit bold :foreground ,red-active))) + `(mood-line-status-info ((,class :foreground ,cyan-active))) + `(mood-line-status-neutral ((,class :foreground ,blue-active))) + `(mood-line-status-success ((,class :foreground ,green-active))) + `(mood-line-status-warning ((,class :inherit bold :foreground ,yellow-active))) + `(mood-line-unimportant ((,class :foreground ,fg-inactive))) +;;;;; mpdel + `(mpdel-browser-directory-face ((,class :foreground ,blue))) + `(mpdel-playlist-current-song-face ((,class :inherit bold :foreground ,blue-alt-other))) +;;;;; mu4e + `(mu4e-attach-number-face ((,class :inherit bold :foreground ,fg-dim))) + `(mu4e-cited-1-face ((,class :foreground ,blue-faint))) + `(mu4e-cited-2-face ((,class :foreground ,green-alt-other))) + `(mu4e-cited-3-face ((,class :foreground ,red-alt-other))) + `(mu4e-cited-4-face ((,class :foreground ,cyan))) + `(mu4e-cited-5-face ((,class :foreground ,yellow-alt))) + `(mu4e-cited-6-face ((,class :foreground ,magenta))) + `(mu4e-cited-7-face ((,class :foreground ,green-alt))) + `(mu4e-compose-header-face ((,class :inherit mu4e-compose-separator-face))) + `(mu4e-compose-separator-face ((,class :inherit modus-theme-intense-neutral))) + `(mu4e-contact-face ((,class :inherit message-header-to))) + `(mu4e-context-face ((,class :foreground ,blue-active))) + `(mu4e-draft-face ((,class :foreground ,magenta-alt))) + `(mu4e-flagged-face ((,class :foreground ,red-alt))) + `(mu4e-footer-face ((,class :inherit modus-theme-slant :foreground ,fg-special-cold))) + `(mu4e-forwarded-face ((,class :foreground ,magenta-alt-other))) + `(mu4e-header-face ((,class :inherit shadow))) + `(mu4e-header-highlight-face ((,class :inherit modus-theme-hl-line))) + `(mu4e-header-key-face ((,class :inherit message-header-name))) + `(mu4e-header-marks-face ((,class :inherit mu4e-special-header-value-face))) + `(mu4e-header-title-face ((,class :foreground ,fg-special-mild))) + `(mu4e-header-value-face ((,class :inherit message-header-other))) + `(mu4e-highlight-face ((,class :inherit bold :foreground ,blue-alt-other))) + `(mu4e-link-face ((,class :inherit button))) + `(mu4e-modeline-face ((,class :foreground ,magenta-active))) + `(mu4e-moved-face ((,class :inherit modus-theme-slant :foreground ,yellow))) + `(mu4e-ok-face ((,class :inherit bold :foreground ,green))) + `(mu4e-region-code ((,class :inherit modus-theme-special-calm))) + `(mu4e-replied-face ((,class :foreground ,blue))) + `(mu4e-special-header-value-face ((,class :inherit message-header-subject))) + `(mu4e-system-face ((,class :inherit modus-theme-slant :foreground ,fg-mark-del))) + `(mu4e-title-face ((,class :foreground ,fg-main))) + `(mu4e-trashed-face ((,class :foreground ,red))) + `(mu4e-unread-face ((,class :inherit bold))) + `(mu4e-url-number-face ((,class :foreground ,fg-alt))) + `(mu4e-view-body-face ((,class :foreground ,fg-main))) + `(mu4e-warning-face ((,class :inherit warning))) +;;;;; mu4e-conversation + `(mu4e-conversation-header ((,class :inherit modus-theme-special-cold))) + `(mu4e-conversation-sender-1 ((,class :foreground ,fg-special-warm))) + `(mu4e-conversation-sender-2 ((,class :foreground ,fg-special-cold))) + `(mu4e-conversation-sender-3 ((,class :foreground ,fg-special-mild))) + `(mu4e-conversation-sender-4 ((,class :inherit shadow))) + `(mu4e-conversation-sender-5 ((,class :foreground ,yellow-refine-fg))) + `(mu4e-conversation-sender-6 ((,class :foreground ,cyan-refine-fg))) + `(mu4e-conversation-sender-7 ((,class :foreground ,green-refine-fg))) + `(mu4e-conversation-sender-8 ((,class :foreground ,blue-refine-fg))) + `(mu4e-conversation-sender-me ((,class :foreground ,fg-main))) + `(mu4e-conversation-unread ((,class :inherit bold))) +;;;;; multiple-cursors + `(mc/cursor-bar-face ((,class :height 1 :background ,fg-main))) + `(mc/cursor-face ((,class :inverse-video t))) + `(mc/region-face ((,class :inherit region))) +;;;;; neotree + `(neo-banner-face ((,class :foreground ,magenta))) + `(neo-button-face ((,class :inherit button))) + `(neo-dir-link-face ((,class :inherit bold :foreground ,blue))) + `(neo-expand-btn-face ((,class :foreground ,cyan))) + `(neo-file-link-face ((,class :foreground ,fg-main))) + `(neo-header-face ((,class :inherit bold :foreground ,fg-main))) + `(neo-root-dir-face ((,class :inherit bold :foreground ,cyan-alt))) + `(neo-vc-added-face ((,class :foreground ,green))) + `(neo-vc-conflict-face ((,class :inherit bold :foreground ,red))) + `(neo-vc-default-face ((,class :foreground ,fg-main))) + `(neo-vc-edited-face ((,class :foreground ,yellow))) + `(neo-vc-ignored-face ((,class :foreground ,fg-inactive))) + `(neo-vc-missing-face ((,class :foreground ,red-alt))) + `(neo-vc-needs-merge-face ((,class :foreground ,magenta-alt))) + `(neo-vc-needs-update-face ((,class :underline t))) + `(neo-vc-removed-face ((,class :strike-through t))) + `(neo-vc-unlocked-changes-face ((,class :inherit modus-theme-refine-blue))) + `(neo-vc-up-to-date-face ((,class :inherit shadow))) + `(neo-vc-user-face ((,class :foreground ,magenta))) +;;;;; no-emoji + `(no-emoji ((,class :foreground ,cyan))) +;;;;; notmuch + `(notmuch-crypto-decryption ((,class :inherit modus-theme-refine-magenta))) + `(notmuch-crypto-part-header ((,class :foreground ,magenta-alt-other))) + `(notmuch-crypto-signature-bad ((,class :inherit modus-theme-intense-red))) + `(notmuch-crypto-signature-good ((,class :inherit modus-theme-refine-green))) + `(notmuch-crypto-signature-good-key ((,class :inherit modus-theme-refine-yellow))) + `(notmuch-crypto-signature-unknown ((,class :inherit modus-theme-refine-red))) + `(notmuch-hello-logo-background ((,class :background "gray50"))) + `(notmuch-message-summary-face ((,class :inherit modus-theme-nuanced-cyan))) + `(notmuch-search-count ((,class :inherit shadow))) + `(notmuch-search-date ((,class :foreground ,cyan))) + `(notmuch-search-flagged-face ((,class :foreground ,red-alt))) + `(notmuch-search-matching-authors ((,class :foreground ,fg-main))) + `(notmuch-search-non-matching-authors ((,class :inherit shadow))) + `(notmuch-search-subject ((,class :foreground ,fg-dim))) + `(notmuch-search-unread-face ((,class :inherit bold))) + `(notmuch-tag-added + ((,(append '((supports :underline (:style wave))) class) + :underline (:color ,green :style wave)) + (,class :foreground ,green :underline t))) + `(notmuch-tag-deleted + ((,(append '((supports :underline (:style wave))) class) + :underline (:color ,red :style wave)) + (,class :foreground ,red :underline t))) + `(notmuch-tag-face ((,class :inherit bold :foreground ,blue-alt))) + `(notmuch-tag-flagged ((,class :foreground ,red-alt))) + `(notmuch-tag-unread ((,class :foreground ,magenta-alt))) + `(notmuch-tree-match-author-face ((,class :foreground ,fg-special-cold))) + `(notmuch-tree-match-date-face ((,class :inherit notmuch-search-date))) + `(notmuch-tree-match-face ((,class :foreground ,fg-main))) + `(notmuch-tree-match-tag-face ((,class :inherit bold :foreground ,blue-alt))) + `(notmuch-tree-no-match-face ((,class :inherit shadow))) + `(notmuch-tree-no-match-date-face ((,class :inherit shadow))) + `(notmuch-wash-cited-text ((,class :foreground ,cyan))) + `(notmuch-wash-toggle-button ((,class :background ,bg-alt :foreground ,fg-alt))) +;;;;; num3-mode + `(num3-face-even ((,class :inherit bold :background ,bg-alt))) +;;;;; nxml-mode + `(nxml-attribute-colon ((,class :foreground ,fg-main))) + `(nxml-attribute-local-name ((,class :inherit font-lock-variable-name-face))) + `(nxml-attribute-prefix ((,class :inherit font-lock-type-face))) + `(nxml-attribute-value ((,class :inherit font-lock-constant-face))) + `(nxml-cdata-section-CDATA ((,class :inherit error))) + `(nxml-cdata-section-delimiter ((,class :inherit error))) + `(nxml-char-ref-delimiter ((,class :foreground ,fg-special-mild))) + `(nxml-char-ref-number ((,class :inherit modus-theme-bold :foreground ,fg-special-mild))) + `(nxml-delimited-data ((,class :inherit modus-theme-slant :foreground ,fg-special-cold))) + `(nxml-delimiter ((,class :foreground ,fg-dim))) + `(nxml-element-colon ((,class :foreground ,fg-main))) + `(nxml-element-local-name ((,class :inherit font-lock-function-name-face))) + `(nxml-element-prefix ((,class :inherit font-lock-builtin-face))) + `(nxml-entity-ref-delimiter ((,class :foreground ,fg-special-mild))) + `(nxml-entity-ref-name ((,class :inherit modus-theme-bold :foreground ,fg-special-mild))) + `(nxml-glyph ((,class :inherit modus-theme-intense-neutral))) + `(nxml-hash ((,class :inherit (bold font-lock-string-face)))) + `(nxml-heading ((,class :inherit bold))) + `(nxml-name ((,class :inherit font-lock-builtin-face))) + `(nxml-namespace-attribute-colon ((,class :foreground ,fg-main))) + `(nxml-namespace-attribute-prefix ((,class :inherit font-lock-variable-name-face))) + `(nxml-processing-instruction-target ((,class :inherit font-lock-keyword-face))) + `(nxml-prolog-keyword ((,class :inherit font-lock-keyword-face))) + `(nxml-ref ((,class :inherit modus-theme-bold :foreground ,fg-special-mild))) + `(rng-error ((,class :inherit error))) +;;;;; objed + `(objed-hl ((,class :background ,(if modus-themes-intense-hl-line + bg-hl-alt-intense bg-hl-alt)))) + `(objed-mark ((,class :background ,bg-active))) + `(objed-mode-line ((,class :foreground ,cyan-active))) +;;;;; orderless + `(orderless-match-face-0 ((,class :inherit bold + ,@(modus-themes--standard-completions + blue-alt-other blue-nuanced-bg + blue-refine-bg blue-refine-fg)))) + `(orderless-match-face-1 ((,class :inherit bold + ,@(modus-themes--standard-completions + magenta-alt magenta-nuanced-bg + magenta-refine-bg magenta-refine-fg)))) + `(orderless-match-face-2 ((,class :inherit bold + ,@(modus-themes--standard-completions + green green-nuanced-bg + green-refine-bg green-refine-fg)))) + `(orderless-match-face-3 ((,class :inherit bold + ,@(modus-themes--standard-completions + yellow yellow-nuanced-bg + yellow-refine-bg yellow-refine-fg)))) +;;;;; org + `(org-agenda-calendar-event ((,class :foreground ,fg-main))) + `(org-agenda-calendar-sexp ((,class :foreground ,cyan-alt))) + `(org-agenda-clocking ((,class :inherit modus-theme-special-cold :extend t))) + `(org-agenda-column-dateline ((,class :background ,bg-alt))) + `(org-agenda-current-time ((,class :inherit bold :foreground ,blue-alt-other))) + `(org-agenda-date ((,class :foreground ,cyan))) + `(org-agenda-date-today ((,class :inherit bold :foreground ,fg-main :underline t))) + `(org-agenda-date-weekend ((,class :foreground ,cyan-alt-other))) + `(org-agenda-diary ((,class :foreground ,fg-main))) + `(org-agenda-dimmed-todo-face ((,class :inherit bold :foreground ,fg-alt))) + `(org-agenda-done ((,class :foreground ,green-alt))) + `(org-agenda-filter-category ((,class :inherit bold :foreground ,magenta-active))) + `(org-agenda-filter-effort ((,class :inherit bold :foreground ,magenta-active))) + `(org-agenda-filter-regexp ((,class :inherit bold :foreground ,magenta-active))) + `(org-agenda-filter-tags ((,class :inherit bold :foreground ,magenta-active))) + `(org-agenda-restriction-lock ((,class :background ,bg-dim :foreground ,fg-dim))) + `(org-agenda-structure ((,class ,@(modus-themes--scale modus-themes-scale-5) + :foreground ,blue-alt))) + `(org-archived ((,class :background ,bg-alt :foreground ,fg-alt))) + `(org-block ((,class ,@(modus-themes--mixed-fonts) + ,@(modus-themes--org-block bg-dim) + :foreground ,fg-main))) + `(org-block-begin-line ((,class ,@(modus-themes--mixed-fonts) + ,@(modus-themes--org-block-delim + bg-dim fg-special-cold + bg-alt fg-special-mild)))) + `(org-block-end-line ((,class :inherit org-block-begin-line))) + `(org-checkbox ((,class :box (:line-width 1 :color ,bg-active) + :background ,bg-inactive :foreground ,fg-active))) + `(org-checkbox-statistics-done ((,class :inherit org-done))) + `(org-checkbox-statistics-todo ((,class :inherit org-todo))) + `(org-clock-overlay ((,class :inherit modus-theme-special-cold))) + `(org-code ((,class ,@(modus-themes--mixed-fonts) + :background ,red-nuanced-bg :foreground ,magenta))) + `(org-column ((,class :background ,bg-alt))) + `(org-column-title ((,class :inherit bold :underline t :background ,bg-alt))) + `(org-date ((,class :inherit ,(if modus-themes-no-mixed-fonts + 'button + '(button fixed-pitch)) + ,@(modus-themes--link-color + cyan cyan-faint)))) + `(org-date-selected ((,class :inherit bold :foreground ,blue-alt :inverse-video t))) + `(org-dispatcher-highlight ((,class :inherit (bold modus-theme-mark-alt)))) + `(org-document-info ((,class :foreground ,fg-special-cold))) + `(org-document-info-keyword ((,class ,@(modus-themes--mixed-fonts) + :foreground ,fg-alt))) + `(org-document-title ((,class :inherit (bold modus-theme-variable-pitch) :foreground ,fg-special-cold + ,@(modus-themes--scale modus-themes-scale-5)))) + `(org-done ((,class :foreground ,green))) + `(org-drawer ((,class ,@(modus-themes--mixed-fonts) + :foreground ,fg-alt))) + `(org-ellipsis ((,class))) ; inherits from the heading's color + `(org-footnote ((,class :inherit button + ,@(modus-themes--link-color + blue-alt blue-alt-faint)))) + `(org-formula ((,class ,@(modus-themes--mixed-fonts) + :foreground ,red-alt))) + `(org-habit-alert-face ((,class ,@(modus-themes--org-habit + yellow-graph-0-bg + yellow-graph-0-bg + yellow-graph-1-bg)))) + `(org-habit-alert-future-face ((,class ,@(modus-themes--org-habit + yellow-graph-1-bg + yellow-graph-0-bg + yellow-graph-1-bg)))) + `(org-habit-clear-face ((,class ,@(modus-themes--org-habit + blue-graph-0-bg + green-graph-1-bg + blue-graph-1-bg)))) + `(org-habit-clear-future-face ((,class ,@(modus-themes--org-habit + blue-graph-1-bg + green-graph-1-bg + blue-graph-1-bg)))) + `(org-habit-overdue-face ((,class ,@(modus-themes--org-habit + red-graph-0-bg + red-graph-0-bg + red-graph-1-bg)))) + `(org-habit-overdue-future-face ((,class ,@(modus-themes--org-habit + red-graph-1-bg + red-graph-0-bg + red-graph-1-bg)))) + `(org-habit-ready-face ((,class ,@(modus-themes--org-habit + green-graph-0-bg + green-graph-0-bg + green-graph-1-bg)))) + `(org-habit-ready-future-face ((,class ,@(modus-themes--org-habit + green-graph-1-bg + green-graph-0-bg + green-graph-1-bg)))) + `(org-headline-done ((,class :inherit modus-theme-variable-pitch :foreground ,green-nuanced-fg))) + `(org-headline-todo ((,class :inherit modus-theme-variable-pitch :foreground ,red-nuanced-fg))) + `(org-hide ((,class :foreground ,bg-main))) + `(org-indent ((,class :inherit (fixed-pitch org-hide)))) + `(org-latex-and-related ((,class :foreground ,magenta-refine-fg))) + `(org-level-1 ((,class :inherit modus-theme-heading-1))) + `(org-level-2 ((,class :inherit modus-theme-heading-2))) + `(org-level-3 ((,class :inherit modus-theme-heading-3))) + `(org-level-4 ((,class :inherit modus-theme-heading-4))) + `(org-level-5 ((,class :inherit modus-theme-heading-5))) + `(org-level-6 ((,class :inherit modus-theme-heading-6))) + `(org-level-7 ((,class :inherit modus-theme-heading-7))) + `(org-level-8 ((,class :inherit modus-theme-heading-8))) + `(org-link ((,class :inherit button))) + `(org-list-dt ((,class :inherit bold))) + `(org-macro ((,class ,@(modus-themes--mixed-fonts) + :background ,blue-nuanced-bg :foreground ,magenta-alt-other))) + `(org-meta-line ((,class ,@(modus-themes--mixed-fonts) :foreground ,fg-alt))) + `(org-mode-line-clock ((,class :foreground ,fg-main))) + `(org-mode-line-clock-overrun ((,class :inherit modus-theme-active-red))) + `(org-priority ((,class :foreground ,magenta))) + `(org-property-value ((,class ,@(modus-themes--mixed-fonts) + :foreground ,fg-special-cold))) + `(org-quote ((,class :inherit modus-theme-slant + ,@(modus-themes--org-block bg-dim) + :foreground ,fg-special-cold))) + `(org-scheduled ((,class :foreground ,magenta-alt))) + `(org-scheduled-previously ((,class :foreground ,yellow-alt-other))) + `(org-scheduled-today ((,class :foreground ,magenta-alt-other))) + `(org-sexp-date ((,class :inherit org-date))) + `(org-special-keyword ((,class ,@(modus-themes--mixed-fonts) + :foreground ,fg-alt))) + `(org-table ((,class ,@(modus-themes--mixed-fonts) + :foreground ,fg-special-cold))) + `(org-table-header ((,class :inherit (fixed-pitch modus-theme-intense-neutral)))) + `(org-tag ((,class :foreground ,magenta-nuanced-fg))) + `(org-tag-group ((,class :inherit bold :foreground ,cyan-nuanced-fg))) + `(org-target ((,class :underline t))) + `(org-time-grid ((,class :foreground ,fg-unfocused))) + `(org-todo ((,class :foreground ,red))) + `(org-upcoming-deadline ((,class :foreground ,red-alt-other))) + `(org-upcoming-distant-deadline ((,class :foreground ,red-nuanced-fg))) + `(org-verbatim ((,class ,@(modus-themes--mixed-fonts) + :background ,bg-alt :foreground ,fg-special-calm))) + `(org-verse ((,class :inherit org-quote))) + `(org-warning ((,class :inherit bold :foreground ,red-alt-other))) +;;;;; org-journal + `(org-journal-calendar-entry-face ((,class :inherit modus-theme-slant :foreground ,yellow-alt-other))) + `(org-journal-calendar-scheduled-face ((,class :inherit modus-theme-slant :foreground ,red-alt-other))) + `(org-journal-highlight ((,class :foreground ,magenta-alt))) +;;;;; org-noter + `(org-noter-no-notes-exist-face ((,class :inherit bold :foreground ,red-active))) + `(org-noter-notes-exist-face ((,class :inherit bold :foreground ,green-active))) +;;;;; org-pomodoro + `(org-pomodoro-mode-line ((,class :foreground ,red-active))) + `(org-pomodoro-mode-line-break ((,class :foreground ,cyan-active))) + `(org-pomodoro-mode-line-overtime ((,class :inherit bold :foreground ,red-active))) +;;;;; org-recur + `(org-recur ((,class :foreground ,magenta-active))) +;;;;; org-roam + `(org-roam-link ((,class :inherit button + ,@(modus-themes--link-color + green green-faint)))) + `(org-roam-link-current ((,class :inherit button + ,@(modus-themes--link-color + green-alt green-alt-faint)))) + `(org-roam-link-invalid ((,class :inherit button + ,@(modus-themes--link-color + red red-faint)))) + `(org-roam-link-shielded ((,class :inherit button + ,@(modus-themes--link-color + yellow yellow-faint)))) + `(org-roam-tag ((,class :inherit italic :foreground ,fg-alt))) +;;;;; org-superstar + `(org-superstar-item ((,class :foreground ,fg-main))) + `(org-superstar-leading ((,class :foreground ,fg-whitespace))) +;;;;; org-table-sticky-header + `(org-table-sticky-header-face ((,class :inherit modus-theme-intense-neutral))) +;;;;; org-tree-slide + `(org-tree-slide-header-overlay-face + ((,class :inherit (bold modus-theme-variable-pitch) :background ,bg-main + :foreground ,fg-special-cold :overline nil + ,@(modus-themes--scale modus-themes-scale-5)))) +;;;;; org-treescope + `(org-treescope-faces--markerinternal-midday ((,class :inherit modus-theme-intense-blue))) + `(org-treescope-faces--markerinternal-range ((,class :inherit modus-theme-special-mild))) +;;;;; origami + `(origami-fold-header-face ((,class :background ,bg-dim :foreground ,fg-dim :box t))) + `(origami-fold-replacement-face ((,class :background ,bg-alt :foreground ,fg-alt))) +;;;;; outline-mode + `(outline-1 ((,class :inherit modus-theme-heading-1))) + `(outline-2 ((,class :inherit modus-theme-heading-2))) + `(outline-3 ((,class :inherit modus-theme-heading-3))) + `(outline-4 ((,class :inherit modus-theme-heading-4))) + `(outline-5 ((,class :inherit modus-theme-heading-5))) + `(outline-6 ((,class :inherit modus-theme-heading-6))) + `(outline-7 ((,class :inherit modus-theme-heading-7))) + `(outline-8 ((,class :inherit modus-theme-heading-8))) +;;;;; outline-minor-faces + `(outline-minor-0 ((,class :background ,bg-alt))) +;;;;; package (M-x list-packages) + `(package-description ((,class :foreground ,fg-special-cold))) + `(package-help-section-name ((,class :inherit bold :foreground ,magenta-alt-other))) + `(package-name ((,class :inherit button))) + `(package-status-avail-obso ((,class :inherit bold :foreground ,red))) + `(package-status-available ((,class :foreground ,fg-special-mild))) + `(package-status-built-in ((,class :foreground ,magenta))) + `(package-status-dependency ((,class :foreground ,magenta-alt-other))) + `(package-status-disabled ((,class :inherit modus-theme-subtle-red))) + `(package-status-external ((,class :foreground ,cyan-alt-other))) + `(package-status-held ((,class :foreground ,yellow-alt))) + `(package-status-incompat ((,class :inherit bold :foreground ,yellow))) + `(package-status-installed ((,class :foreground ,fg-special-warm))) + `(package-status-new ((,class :inherit bold :foreground ,green))) + `(package-status-unsigned ((,class :inherit bold :foreground ,red-alt))) +;;;;; page-break-lines + `(page-break-lines ((,class :inherit default :foreground ,fg-window-divider-outer))) +;;;;; paradox + `(paradox-archive-face ((,class :foreground ,fg-special-mild))) + `(paradox-comment-face ((,class :inherit font-lock-comment-face))) + `(paradox-commit-tag-face ((,class :inherit modus-theme-refine-magenta :box t))) + `(paradox-description-face ((,class :foreground ,fg-special-cold))) + `(paradox-description-face-multiline ((,class :foreground ,fg-special-cold))) + `(paradox-download-face ((,class :inherit modus-theme-bold :foreground ,blue-alt-other))) + `(paradox-highlight-face ((,class :inherit modus-theme-bold :foreground ,cyan-alt-other))) + `(paradox-homepage-button-face ((,class :foreground ,magenta-alt-other :underline t))) + `(paradox-mode-line-face ((,class :inherit bold :foreground ,cyan-active))) + `(paradox-name-face ((,class :foreground ,blue :underline t))) + `(paradox-star-face ((,class :foreground ,magenta))) + `(paradox-starred-face ((,class :foreground ,magenta-alt))) +;;;;; paren-face + `(parenthesis ((,class :foreground ,fg-unfocused))) +;;;;; parrot + `(parrot-rotate-rotation-highlight-face ((,class :inherit modus-theme-refine-magenta))) +;;;;; pass + `(pass-mode-directory-face ((,class :inherit bold :foreground ,fg-special-cold))) + `(pass-mode-entry-face ((,class :background ,bg-main :foreground ,fg-main))) + `(pass-mode-header-face ((,class :foreground ,fg-special-warm))) +;;;;; pdf-tools + `(pdf-links-read-link ((,class :background ,fg-main :foreground ,magenta-intense-bg :inherit bold))) ; Foreground is background and vice versa + `(pdf-occur-document-face ((,class :inherit shadow))) + `(pdf-occur-page-face ((,class :inherit shadow))) +;;;;; persp-mode + `(persp-face-lighter-buffer-not-in-persp ((,class :inherit modus-theme-intense-red))) + `(persp-face-lighter-default ((,class :inherit bold :foreground ,blue-active))) + `(persp-face-lighter-nil-persp ((,class :inherit bold :foreground ,fg-active))) +;;;;; perspective + `(persp-selected-face ((,class :inherit bold :foreground ,blue-active))) +;;;;; phi-grep + `(phi-grep-heading-face ((,class :inherit bold :foreground ,red-alt + ,@(modus-themes--scale modus-themes-scale-4)))) + `(phi-grep-line-number-face ((,class :foreground ,fg-special-warm))) + `(phi-grep-match-face ((,class :inherit modus-theme-special-calm))) + `(phi-grep-modified-face ((,class :inherit modus-theme-refine-yellow))) + `(phi-grep-overlay-face ((,class :inherit modus-theme-refine-blue))) +;;;;; phi-search + `(phi-replace-preview-face ((,class :inherit modus-theme-intense-magenta))) + `(phi-search-failpart-face ((,class :inherit modus-theme-refine-red))) + `(phi-search-match-face ((,class :inherit modus-theme-refine-cyan))) + `(phi-search-selection-face ((,class :inherit (modus-theme-intense-green bold)))) +;;;;; pkgbuild-mode + `(pkgbuild-error-face ((,class :inherit modus-theme-lang-error))) +;;;;; pomidor + `(pomidor-break-face ((,class :foreground ,blue-alt-other))) + `(pomidor-overwork-face ((,class :foreground ,red-alt-other))) + `(pomidor-skip-face ((,class :inherit modus-theme-slant :foreground ,fg-alt))) + `(pomidor-work-face ((,class :foreground ,green-alt-other))) +;;;;; popup + `(popup-face ((,class :background ,bg-alt :foreground ,fg-main))) + `(popup-isearch-match ((,class :inherit (modus-theme-refine-cyan bold)))) + `(popup-menu-mouse-face ((,class :inherit modus-theme-intense-blue))) + `(popup-menu-selection-face ((,class :inherit (modus-theme-subtle-cyan bold)))) + `(popup-scroll-bar-background-face ((,class :background ,bg-active))) + `(popup-scroll-bar-foreground-face ((,class :foreground ,fg-active))) + `(popup-summary-face ((,class :background ,bg-active :foreground ,fg-inactive))) + `(popup-tip-face ((,class :inherit modus-theme-refine-yellow))) +;;;;; powerline + `(powerline-active0 ((,class :background ,bg-main :foreground ,blue-faint :inverse-video t))) + `(powerline-active1 ((,class :background ,blue-nuanced-bg :foreground ,blue-nuanced-fg))) + `(powerline-active2 ((,class :background ,bg-active :foreground ,fg-active))) + `(powerline-inactive0 ((,class :background ,bg-special-cold :foreground ,fg-special-cold))) + `(powerline-inactive1 ((,class :background ,bg-dim :foreground ,fg-inactive))) + `(powerline-inactive2 ((,class :background ,bg-inactive :foreground ,fg-inactive))) +;;;;; powerline-evil + `(powerline-evil-base-face ((,class :background ,fg-main :foreground ,bg-main))) + `(powerline-evil-emacs-face ((,class :inherit modus-theme-active-magenta))) + `(powerline-evil-insert-face ((,class :inherit modus-theme-active-green))) + `(powerline-evil-motion-face ((,class :inherit modus-theme-active-blue))) + `(powerline-evil-normal-face ((,class :background ,fg-alt :foreground ,bg-main))) + `(powerline-evil-operator-face ((,class :inherit modus-theme-active-yellow))) + `(powerline-evil-replace-face ((,class :inherit modus-theme-active-red))) + `(powerline-evil-visual-face ((,class :inherit modus-theme-active-cyan))) +;;;;; proced + `(proced-mark ((,class :inherit modus-theme-mark-symbol))) + `(proced-marked ((,class :inherit modus-theme-mark-alt))) + `(proced-sort-header ((,class :inherit bold :foreground ,fg-special-calm :underline t))) +;;;;; prodigy + `(prodigy-green-face ((,class :foreground ,green))) + `(prodigy-red-face ((,class :foreground ,red))) + `(prodigy-yellow-face ((,class :foreground ,yellow))) +;;;;; quick-peek + `(quick-peek-background-face ((,class :background ,bg-alt))) + `(quick-peek-border-face ((,class :background ,fg-window-divider-inner :height 1))) + `(quick-peek-padding-face ((,class :background ,bg-alt :height 0.15))) +;;;;; racket-mode + `(racket-debug-break-face ((,class :inherit modus-theme-intense-red))) + `(racket-debug-locals-face ((,class :box (:line-width -1 :color nil) + :foreground ,green-alt-other))) + `(racket-debug-result-face ((,class :inherit bold :box (:line-width -1 :color nil) + :foreground ,green))) + `(racket-here-string-face ((,class :foreground ,blue-alt))) + `(racket-keyword-argument-face ((,class :foreground ,red-alt))) + `(racket-logger-config-face ((,class :inherit modus-theme-slant :foreground ,fg-alt))) + `(racket-logger-debug-face ((,class :foreground ,blue-alt-other))) + `(racket-logger-info-face ((,class :foreground ,fg-lang-note))) + `(racket-logger-topic-face ((,class :inherit modus-theme-slant :foreground ,magenta))) + `(racket-selfeval-face ((,class :foreground ,green-alt))) + `(racket-xp-error-face ((,class :inherit modus-theme-lang-error))) +;;;;; rainbow-blocks + `(rainbow-blocks-depth-1-face ((,class :foreground ,magenta-alt-other))) + `(rainbow-blocks-depth-2-face ((,class :foreground ,blue))) + `(rainbow-blocks-depth-3-face ((,class :foreground ,magenta-alt))) + `(rainbow-blocks-depth-4-face ((,class :foreground ,green))) + `(rainbow-blocks-depth-5-face ((,class :foreground ,magenta))) + `(rainbow-blocks-depth-6-face ((,class :foreground ,cyan))) + `(rainbow-blocks-depth-7-face ((,class :foreground ,yellow))) + `(rainbow-blocks-depth-8-face ((,class :foreground ,cyan-alt))) + `(rainbow-blocks-depth-9-face ((,class :foreground ,red-alt))) + `(rainbow-blocks-unmatched-face ((,class :foreground ,red))) +;;;;; rainbow-identifiers + `(rainbow-identifiers-identifier-1 ((,class :foreground ,green-alt-other))) + `(rainbow-identifiers-identifier-2 ((,class :foreground ,magenta-alt-other))) + `(rainbow-identifiers-identifier-3 ((,class :foreground ,cyan-alt-other))) + `(rainbow-identifiers-identifier-4 ((,class :foreground ,yellow-alt-other))) + `(rainbow-identifiers-identifier-5 ((,class :foreground ,blue-alt-other))) + `(rainbow-identifiers-identifier-6 ((,class :foreground ,green-alt))) + `(rainbow-identifiers-identifier-7 ((,class :foreground ,magenta-alt))) + `(rainbow-identifiers-identifier-8 ((,class :foreground ,cyan-alt))) + `(rainbow-identifiers-identifier-9 ((,class :foreground ,yellow-alt))) + `(rainbow-identifiers-identifier-10 ((,class :foreground ,green))) + `(rainbow-identifiers-identifier-11 ((,class :foreground ,magenta))) + `(rainbow-identifiers-identifier-12 ((,class :foreground ,cyan))) + `(rainbow-identifiers-identifier-13 ((,class :foreground ,yellow))) + `(rainbow-identifiers-identifier-14 ((,class :foreground ,blue-alt))) + `(rainbow-identifiers-identifier-15 ((,class :foreground ,red-alt))) +;;;;; rainbow-delimiters + `(rainbow-delimiters-base-error-face ((,class :background ,red-subtle-bg :foreground ,fg-main))) + `(rainbow-delimiters-base-face ((,class :foreground ,fg-main))) + `(rainbow-delimiters-depth-1-face ((,class :foreground ,fg-main))) + `(rainbow-delimiters-depth-2-face ((,class :foreground ,magenta-intense))) + `(rainbow-delimiters-depth-3-face ((,class :foreground ,cyan-intense))) + `(rainbow-delimiters-depth-4-face ((,class :foreground ,orange-intense))) + `(rainbow-delimiters-depth-5-face ((,class :foreground ,purple-intense))) + `(rainbow-delimiters-depth-6-face ((,class :foreground ,green-intense))) + `(rainbow-delimiters-depth-7-face ((,class :foreground ,red-intense))) + `(rainbow-delimiters-depth-8-face ((,class :foreground ,blue-intense))) + `(rainbow-delimiters-depth-9-face ((,class :foreground ,yellow-intense))) + `(rainbow-delimiters-mismatched-face ((,class :inherit (bold modus-theme-refine-yellow)))) + `(rainbow-delimiters-unmatched-face ((,class :inherit (bold modus-theme-refine-red)))) +;;;;; rcirc + `(rcirc-bright-nick ((,class :inherit bold :foreground ,magenta-alt))) + `(rcirc-dim-nick ((,class :inherit shadow))) + `(rcirc-my-nick ((,class :inherit bold :foreground ,magenta))) + `(rcirc-nick-in-message ((,class :foreground ,magenta-alt-other))) + `(rcirc-nick-in-message-full-line ((,class :inherit bold :foreground ,fg-special-mild))) + `(rcirc-other-nick ((,class :inherit bold :foreground ,fg-special-cold))) + `(rcirc-prompt ((,class :inherit bold :foreground ,cyan-alt-other))) + `(rcirc-server ((,class :foreground ,fg-unfocused))) + `(rcirc-timestamp ((,class :foreground ,blue-nuanced-fg))) + `(rcirc-url ((,class :foreground ,blue :underline t))) +;;;;; recursion-indicator + `(recursion-indicator-general ((,class :foreground ,blue-active))) + `(recursion-indicator-minibuffer ((,class :foreground ,red-active))) +;;;;; regexp-builder (re-builder) + `(reb-match-0 ((,class :inherit modus-theme-refine-cyan))) + `(reb-match-1 ((,class :inherit modus-theme-subtle-magenta))) + `(reb-match-2 ((,class :inherit modus-theme-subtle-green))) + `(reb-match-3 ((,class :inherit modus-theme-refine-yellow))) + `(reb-regexp-grouping-backslash ((,class :inherit font-lock-regexp-grouping-backslash))) + `(reb-regexp-grouping-construct ((,class :inherit font-lock-regexp-grouping-construct))) +;;;;; rg (rg.el) + `(rg-column-number-face ((,class :foreground ,magenta-alt-other))) + `(rg-context-face ((,class :foreground ,fg-unfocused))) + `(rg-error-face ((,class :inherit bold :foreground ,red))) + `(rg-file-tag-face ((,class :foreground ,fg-special-cold))) + `(rg-filename-face ((,class :inherit bold :foreground ,fg-special-cold))) + `(rg-line-number-face ((,class :foreground ,fg-special-warm))) + `(rg-literal-face ((,class :foreground ,blue-alt))) + `(rg-match-face ((,class :inherit modus-theme-special-calm))) + `(rg-regexp-face ((,class :foreground ,magenta-active))) + `(rg-toggle-off-face ((,class :inherit bold :foreground ,fg-inactive))) + `(rg-toggle-on-face ((,class :inherit bold :foreground ,cyan-active))) + `(rg-warning-face ((,class :inherit bold :foreground ,yellow))) +;;;;; ripgrep + `(ripgrep-context-face ((,class :foreground ,fg-unfocused))) + `(ripgrep-error-face ((,class :inherit bold :foreground ,red))) + `(ripgrep-hit-face ((,class :foreground ,cyan))) + `(ripgrep-match-face ((,class :inherit modus-theme-special-calm))) +;;;;; rmail + `(rmail-header-name ((,class :foreground ,cyan-alt-other))) + `(rmail-highlight ((,class :inherit bold :foreground ,magenta-alt))) +;;;;; ruler-mode + `(ruler-mode-column-number ((,class :inherit ruler-mode-default :foreground ,fg-main))) + `(ruler-mode-comment-column ((,class :inherit ruler-mode-default :foreground ,red))) + `(ruler-mode-current-column ((,class :inherit ruler-mode-default :background ,blue-subtle-bg :foreground ,fg-main))) + `(ruler-mode-default ((,class :inherit default :background ,bg-alt :foreground ,fg-unfocused))) + `(ruler-mode-fill-column ((,class :inherit ruler-mode-default :foreground ,green))) + `(ruler-mode-fringes ((,class :inherit ruler-mode-default :foreground ,cyan))) + `(ruler-mode-goal-column ((,class :inherit ruler-mode-default :foreground ,blue))) + `(ruler-mode-margins ((,class :inherit ruler-mode-default :foreground ,bg-main))) + `(ruler-mode-pad ((,class :inherit ruler-mode-default :background ,bg-active :foreground ,fg-inactive))) + `(ruler-mode-tab-stop ((,class :inherit ruler-mode-default :foreground ,fg-special-warm))) +;;;;; sallet + `(sallet-buffer-compressed ((,class :inherit italic :foreground ,yellow-nuanced-fg))) + `(sallet-buffer-default-directory ((,class :foreground ,cyan-nuanced-fg))) + `(sallet-buffer-directory ((,class :foreground ,blue-nuanced-fg))) + `(sallet-buffer-help ((,class :foreground ,fg-special-cold))) + `(sallet-buffer-modified ((,class :inherit italic :foreground ,yellow-alt-other))) + `(sallet-buffer-ordinary ((,class :foreground ,fg-main))) + `(sallet-buffer-read-only ((,class :foreground ,yellow-alt))) + `(sallet-buffer-size ((,class :foreground ,fg-special-calm))) + `(sallet-buffer-special ((,class :foreground ,magenta-alt-other))) + `(sallet-flx-match ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-cyan + 'modus-theme-refine-cyan + 'modus-theme-nuanced-cyan + cyan-alt-other)))) + `(sallet-recentf-buffer-name ((,class :foreground ,blue-nuanced-fg))) + `(sallet-recentf-file-path ((,class :foreground ,fg-special-mild))) + `(sallet-regexp-match ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-magenta + 'modus-theme-refine-magenta + 'modus-theme-nuanced-magenta + magenta-alt-other)))) + `(sallet-source-header ((,class :inherit bold :foreground ,red-alt + ,@(modus-themes--scale modus-themes-scale-4)))) + `(sallet-substring-match ((,class ,@(modus-themes--extra-completions + 'modus-theme-subtle-blue + 'modus-theme-refine-blue + 'modus-theme-nuanced-blue + blue-alt-other)))) +;;;;; selectrum +;; NOTE 2021-02-22: The `selectrum-primary-highlight' and +;; `selectrum-secondary-highlight' are deprecated upstream in favour of +;; their selectrum-prescient counterparts. We shall remove those faces +;; from the themes once we are certain that they are no longer relevant. + `(selectrum-current-candidate + ((,class :inherit bold :foreground ,fg-main + :background ,@(pcase modus-themes-completions + ('opinionated (list bg-active)) + (_ (list bg-inactive)))))) + `(selectrum-primary-highlight + ((,class :inherit bold + ,@(modus-themes--standard-completions + magenta-alt magenta-nuanced-bg + magenta-refine-bg magenta-refine-fg)))) + `(selectrum-secondary-highlight + ((,class :inherit bold + ,@(modus-themes--standard-completions + cyan-alt-other cyan-nuanced-bg + cyan-refine-bg cyan-refine-fg)))) +;;;;; selectrum-prescient + `(selectrum-prescient-primary-highlight + ((,class :inherit bold + ,@(modus-themes--standard-completions + magenta-alt magenta-nuanced-bg + magenta-refine-bg magenta-refine-fg)))) + `(selectrum-prescient-secondary-highlight + ((,class :inherit bold + ,@(modus-themes--standard-completions + cyan-alt-other cyan-nuanced-bg + cyan-refine-bg cyan-refine-fg)))) +;;;;; semantic + `(semantic-complete-inline-face ((,class :foreground ,fg-special-warm :underline t))) + `(semantic-decoration-on-fileless-includes ((,class :inherit modus-theme-refine-green))) + `(semantic-decoration-on-private-members-face ((,class :inherit modus-theme-refine-cyan))) + `(semantic-decoration-on-protected-members-face ((,class :background ,bg-dim))) + `(semantic-decoration-on-unknown-includes ((,class :inherit modus-theme-refine-red))) + `(semantic-decoration-on-unparsed-includes ((,class :inherit modus-theme-refine-yellow))) + `(semantic-highlight-edits-face ((,class :background ,bg-alt))) + `(semantic-highlight-func-current-tag-face ((,class :background ,bg-alt))) + `(semantic-idle-symbol-highlight ((,class :inherit modus-theme-special-mild))) + `(semantic-tag-boundary-face ((,class :overline ,blue-intense))) + `(semantic-unmatched-syntax-face ((,class :underline ,fg-lang-error))) +;;;;; sesman + `(sesman-browser-button-face ((,class :foreground ,blue-alt-other :underline t))) + `(sesman-browser-highligh-face ((,class :inherit modus-theme-subtle-blue))) + `(sesman-buffer-face ((,class :foreground ,magenta))) + `(sesman-directory-face ((,class :inherit bold :foreground ,blue))) + `(sesman-project-face ((,class :inherit bold :foreground ,magenta-alt-other))) +;;;;; shell-script-mode + `(sh-heredoc ((,class :foreground ,blue-alt))) + `(sh-quoted-exec ((,class :inherit modus-theme-bold :foreground ,magenta-alt))) +;;;;; shortdoc + `(shortdoc-heading ((,class :inherit modus-theme-pseudo-header))) + `(shortdoc-section ((,class))) ; remove the default's variable-pitch style +;;;;; show-paren-mode + `(show-paren-match ((,class ,@(modus-themes--paren bg-paren-match + bg-paren-match-intense) + :foreground ,fg-main))) + `(show-paren-match-expression ((,class :inherit modus-theme-special-calm))) + `(show-paren-mismatch ((,class :inherit modus-theme-intense-red))) +;;;;; shr + `(shr-abbreviation + ((,(append '((supports :underline (:style wave))) class) + :foreground ,fg-docstring :underline (:color ,fg-alt :style wave)) + (,class :foreground ,fg-docstring :underline t))) + `(shr-selected-link ((,class :inherit modus-theme-subtle-cyan))) +;;;;; side-notes + `(side-notes ((,class :background ,bg-dim :foreground ,fg-dim))) +;;;;; sieve-mode + `(sieve-action-commands ((,class :inherit font-lock-builtin-face))) + `(sieve-control-commands ((,class :inherit font-lock-keyword-face))) + `(sieve-tagged-arguments ((,class :inherit font-lock-type-face))) + `(sieve-test-commands ((,class :inherit font-lock-function-name-face))) +;;;;; skewer-mode + `(skewer-error-face ((,class :foreground ,red :underline t))) +;;;;; smart-mode-line + `(sml/charging ((,class :foreground ,green-active))) + `(sml/discharging ((,class :foreground ,red-active))) + `(sml/filename ((,class :inherit bold :foreground ,blue-active))) + `(sml/folder ((,class :foreground ,fg-active))) + `(sml/git ((,class :inherit bold :foreground ,green-active))) + `(sml/global ((,class :foreground ,fg-active))) + `(sml/line-number ((,class :inherit sml/global))) + `(sml/minor-modes ((,class :inherit sml/global))) + `(sml/modes ((,class :inherit bold :foreground ,fg-active))) + `(sml/modified ((,class :inherit bold :foreground ,magenta-active))) + `(sml/mule-info ((,class :inherit sml/global))) + `(sml/name-filling ((,class :foreground ,yellow-active))) + `(sml/not-modified ((,class :inherit sml/global))) + `(sml/numbers-separator ((,class :inherit sml/global))) + `(sml/outside-modified ((,class :inherit modus-theme-intense-red))) + `(sml/position-percentage ((,class :inherit sml/global))) + `(sml/prefix ((,class :foreground ,green-active))) + `(sml/process ((,class :inherit sml/prefix))) + `(sml/projectile ((,class :inherit sml/git))) + `(sml/read-only ((,class :inherit bold :foreground ,cyan-active))) + `(sml/remote ((,class :inherit sml/global))) + `(sml/sudo ((,class :inherit modus-theme-subtle-red))) + `(sml/time ((,class :inherit sml/global))) + `(sml/vc ((,class :inherit sml/git))) + `(sml/vc-edited ((,class :inherit bold :foreground ,yellow-active))) +;;;;; smartparens + `(sp-pair-overlay-face ((,class :inherit modus-theme-special-warm))) + `(sp-show-pair-enclosing ((,class :inherit modus-theme-special-mild))) + `(sp-show-pair-match-face ((,class ,@(modus-themes--paren bg-paren-match + bg-paren-match-intense) + :foreground ,fg-main))) + `(sp-show-pair-mismatch-face ((,class :inherit modus-theme-intense-red))) + `(sp-wrap-overlay-closing-pair ((,class :inherit sp-pair-overlay-face))) + `(sp-wrap-overlay-face ((,class :inherit sp-pair-overlay-face))) + `(sp-wrap-overlay-opening-pair ((,class :inherit sp-pair-overlay-face))) + `(sp-wrap-tag-overlay-face ((,class :inherit sp-pair-overlay-face))) +;;;;; smerge + `(smerge-base ((,class :inherit modus-theme-diff-changed))) + `(smerge-lower ((,class :inherit modus-theme-diff-added))) + `(smerge-markers ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-2))) + `(smerge-refined-added ((,class :inherit modus-theme-diff-refine-added))) + `(smerge-refined-changed ((,class))) + `(smerge-refined-removed ((,class :inherit modus-theme-diff-refine-removed))) + `(smerge-upper ((,class :inherit modus-theme-diff-removed))) +;;;;; solaire + `(solaire-default-face ((,class :inherit default :background ,bg-alt :foreground ,fg-dim))) + `(solaire-line-number-face ((,class :inherit solaire-default-face :foreground ,fg-unfocused))) + `(solaire-hl-line-face ((,class :background ,bg-active))) + `(solaire-org-hide-face ((,class :background ,bg-alt :foreground ,bg-alt))) +;;;;; spaceline + `(spaceline-evil-emacs ((,class :inherit modus-theme-active-magenta))) + `(spaceline-evil-insert ((,class :inherit modus-theme-active-green))) + `(spaceline-evil-motion ((,class :inherit modus-theme-active-blue))) + `(spaceline-evil-normal ((,class :background ,fg-alt :foreground ,bg-alt))) + `(spaceline-evil-replace ((,class :inherit modus-theme-active-red))) + `(spaceline-evil-visual ((,class :inherit modus-theme-active-cyan))) + `(spaceline-flycheck-error ((,class :foreground ,red-active))) + `(spaceline-flycheck-info ((,class :foreground ,cyan-active))) + `(spaceline-flycheck-warning ((,class :foreground ,yellow-active))) + `(spaceline-highlight-face ((,class :inherit modus-theme-fringe-blue))) + `(spaceline-modified ((,class :inherit modus-theme-fringe-magenta))) + `(spaceline-python-venv ((,class :foreground ,magenta-active))) + `(spaceline-read-only ((,class :inherit modus-theme-fringe-red))) + `(spaceline-unmodified ((,class :inherit modus-theme-fringe-cyan))) +;;;;; speedbar + `(speedbar-button-face ((,class :inherit button))) + `(speedbar-directory-face ((,class :inherit bold :foreground ,blue))) + `(speedbar-file-face ((,class :foreground ,fg-main))) + `(speedbar-highlight-face ((,class :inherit modus-theme-subtle-blue))) + `(speedbar-selected-face ((,class :inherit bold :foreground ,cyan))) + `(speedbar-separator-face ((,class :inherit modus-theme-intense-neutral))) + `(speedbar-tag-face ((,class :foreground ,yellow-alt-other))) +;;;;; spell-fu + `(spell-fu-incorrect-face ((,class :inherit modus-theme-lang-error))) +;;;;; spray + `(spray-accent-face ((,class :foreground ,red-intense))) + `(spray-base-face ((,class :inherit default :foreground ,fg-special-cold))) +;;;;; stripes + `(stripes ((,class :inherit modus-theme-hl-line))) +;;;;; success + `(suggest-heading ((,class :inherit bold :foreground ,yellow-alt-other))) +;;;;; switch-window + `(switch-window-background ((,class :background ,bg-dim))) + `(switch-window-label ((,class :height 3.0 :foreground ,blue-intense))) +;;;;; swiper + `(swiper-background-match-face-1 ((,class :inherit modus-theme-subtle-neutral))) + `(swiper-background-match-face-2 ((,class :inherit modus-theme-refine-cyan))) + `(swiper-background-match-face-3 ((,class :inherit modus-theme-refine-magenta))) + `(swiper-background-match-face-4 ((,class :inherit modus-theme-refine-yellow))) + `(swiper-line-face ((,class :inherit modus-theme-special-cold))) + `(swiper-match-face-1 ((,class :inherit (bold modus-theme-intense-neutral)))) + `(swiper-match-face-2 ((,class :inherit (bold modus-theme-intense-green)))) + `(swiper-match-face-3 ((,class :inherit (bold modus-theme-intense-blue)))) + `(swiper-match-face-4 ((,class :inherit (bold modus-theme-intense-red)))) +;;;;; swoop + `(swoop-face-header-format-line ((,class :inherit bold :foreground ,red-alt + ,@(modus-themes--scale modus-themes-scale-3)))) + `(swoop-face-line-buffer-name ((,class :inherit bold :foreground ,blue-alt + ,@(modus-themes--scale modus-themes-scale-4)))) + `(swoop-face-line-number ((,class :foreground ,fg-special-warm))) + `(swoop-face-target-line ((,class :inherit modus-theme-intense-blue :extend t))) + `(swoop-face-target-words ((,class :inherit modus-theme-refine-cyan))) +;;;;; sx + `(sx-inbox-item-type ((,class :foreground ,magenta-alt-other))) + `(sx-inbox-item-type-unread ((,class :inherit (sx-inbox-item-type bold)))) + `(sx-question-list-answers ((,class :foreground ,green))) + `(sx-question-list-answers-accepted ((,class :box t :foreground ,green))) + `(sx-question-list-bounty ((,class :inherit bold :background ,bg-alt :foreground ,yellow))) + `(sx-question-list-date ((,class :foreground ,fg-special-cold))) + `(sx-question-list-favorite ((,class :inherit bold :foreground ,fg-special-warm))) + `(sx-question-list-parent ((,class :foreground ,fg-main))) + `(sx-question-list-read-question ((,class :inherit shadow))) + `(sx-question-list-score ((,class :foreground ,fg-special-mild))) + `(sx-question-list-score-upvoted ((,class :inherit (sx-question-list-score bold)))) + `(sx-question-list-unread-question ((,class :inherit bold :foreground ,fg-main))) + `(sx-question-mode-accepted ((,class :inherit bold :height 1.3 :foreground ,green))) + `(sx-question-mode-closed ((,class :inherit modus-theme-active-yellow :box (:line-width 2 :color nil)))) + `(sx-question-mode-closed-reason ((,class :box (:line-width 2 :color nil) :foreground ,fg-main))) + `(sx-question-mode-content-face ((,class :background ,bg-dim))) + `(sx-question-mode-date ((,class :foreground ,blue))) + `(sx-question-mode-header ((,class :inherit bold :foreground ,cyan))) + `(sx-question-mode-kbd-tag ((,class :inherit bold :height 0.9 :box (:line-width 3 :color ,fg-main :style released-button) :foreground ,fg-main))) + `(sx-question-mode-score ((,class :foreground ,fg-dim))) + `(sx-question-mode-score-downvoted ((,class :foreground ,yellow))) + `(sx-question-mode-score-upvoted ((,class :inherit bold :foreground ,magenta))) + `(sx-question-mode-title ((,class :inherit bold :foreground ,fg-main))) + `(sx-question-mode-title-comments ((,class :inherit bold :foreground ,fg-alt))) + `(sx-tag ((,class :foreground ,magenta-alt))) + `(sx-user-name ((,class :foreground ,blue-alt))) + `(sx-user-reputation ((,class :inherit shadow))) +;;;;; symbol-overlay + `(symbol-overlay-default-face ((,class :inherit modus-theme-special-warm))) + `(symbol-overlay-face-1 ((,class :inherit modus-theme-intense-blue))) + `(symbol-overlay-face-2 ((,class :inherit modus-theme-refine-magenta))) + `(symbol-overlay-face-3 ((,class :inherit modus-theme-intense-yellow))) + `(symbol-overlay-face-4 ((,class :inherit modus-theme-intense-magenta))) + `(symbol-overlay-face-5 ((,class :inherit modus-theme-intense-red))) + `(symbol-overlay-face-6 ((,class :inherit modus-theme-refine-red))) + `(symbol-overlay-face-7 ((,class :inherit modus-theme-intense-cyan))) + `(symbol-overlay-face-8 ((,class :inherit modus-theme-refine-cyan))) +;;;;; syslog-mode + `(syslog-debug ((,class :inherit bold :foreground ,cyan-alt-other))) + `(syslog-error ((,class :inherit bold :foreground ,red))) + `(syslog-file ((,class :inherit bold :foreground ,fg-special-cold))) + `(syslog-hide ((,class :background ,bg-main :foreground ,fg-main))) + `(syslog-hour ((,class :inherit bold :foreground ,magenta-alt-other))) + `(syslog-info ((,class :inherit bold :foreground ,blue-alt-other))) + `(syslog-ip ((,class :inherit bold :foreground ,fg-special-mild :underline t))) + `(syslog-su ((,class :inherit bold :foreground ,red-alt))) + `(syslog-warn ((,class :inherit bold :foreground ,yellow))) +;;;;; tab-bar-mode + `(tab-bar ((,class ,@(modus-themes--variable-pitch-ui) + :background ,bg-tab-bar :foreground ,fg-main))) + `(tab-bar-tab ((,class :inherit bold :box (:line-width 2 :color ,bg-tab-active) + :background ,bg-tab-active :foreground ,fg-main))) + `(tab-bar-tab-inactive ((,class :box (:line-width 2 :color ,bg-tab-inactive) + :background ,bg-tab-inactive :foreground ,fg-dim))) +;;;;; tab-line-mode + `(tab-line ((,class ,@(modus-themes--variable-pitch-ui) + :height 0.95 :background ,bg-tab-bar :foreground ,fg-main))) + `(tab-line-close-highlight ((,class :foreground ,red))) + `(tab-line-highlight ((,class :background ,blue-subtle-bg :foreground ,fg-dim))) + `(tab-line-tab ((,class :inherit bold :box (:line-width 2 :color ,bg-tab-active) + :background ,bg-tab-active :foreground ,fg-main))) + `(tab-line-tab-current ((,class :inherit tab-line-tab))) + `(tab-line-tab-inactive ((,class :box (:line-width 2 :color ,bg-tab-inactive) + :background ,bg-tab-inactive :foreground ,fg-dim))) + `(tab-line-tab-inactive-alternate ((,class :box (:line-width 2 :color ,bg-tab-inactive-alt) + :background ,bg-tab-inactive-alt :foreground ,fg-main))) +;;;;; table (built-in table.el) + `(table-cell ((,class :background ,blue-nuanced-bg))) +;;;;; telephone-line + `(telephone-line-accent-active ((,class :background ,fg-inactive :foreground ,bg-inactive))) + `(telephone-line-accent-inactive ((,class :background ,bg-active :foreground ,fg-active))) + `(telephone-line-error ((,class :inherit bold :foreground ,red-active))) + `(telephone-line-evil ((,class :foreground ,fg-main))) + `(telephone-line-evil-emacs ((,class :inherit telephone-line-evil :background ,magenta-intense-bg))) + `(telephone-line-evil-insert ((,class :inherit telephone-line-evil :background ,green-intense-bg))) + `(telephone-line-evil-motion ((,class :inherit telephone-line-evil :background ,yellow-intense-bg))) + `(telephone-line-evil-normal ((,class :inherit telephone-line-evil :background ,bg-alt))) + `(telephone-line-evil-operator ((,class :inherit telephone-line-evil :background ,yellow-subtle-bg))) + `(telephone-line-evil-replace ((,class :inherit telephone-line-evil :background ,red-intense-bg))) + `(telephone-line-evil-visual ((,class :inherit telephone-line-evil :background ,cyan-intense-bg))) + `(telephone-line-projectile ((,class :foreground ,cyan-active))) + `(telephone-line-unimportant ((,class :foreground ,fg-inactive))) + `(telephone-line-warning ((,class :inherit bold :foreground ,yellow-active))) +;;;;; terraform-mode + `(terraform--resource-name-face ((,class ,@(modus-themes--syntax-string + magenta-alt-other magenta-alt-other-faint + red-alt red-alt)))) + `(terraform--resource-type-face ((,class ,@(modus-themes--syntax-string + green green-faint + blue-alt magenta-alt)))) +;;;;; term + `(term ((,class :background ,bg-main :foreground ,fg-main))) + `(term-bold ((,class :inherit bold))) + `(term-color-black ((,class :background "gray35" :foreground "gray35"))) + `(term-color-blue ((,class :background ,blue :foreground ,blue))) + `(term-color-cyan ((,class :background ,cyan :foreground ,cyan))) + `(term-color-green ((,class :background ,green :foreground ,green))) + `(term-color-magenta ((,class :background ,magenta :foreground ,magenta))) + `(term-color-red ((,class :background ,red :foreground ,red))) + `(term-color-white ((,class :background "gray65" :foreground "gray65"))) + `(term-color-yellow ((,class :background ,yellow :foreground ,yellow))) + `(term-underline ((,class :underline t))) +;;;;; tomatinho + `(tomatinho-ok-face ((,class :foreground ,blue-intense))) + `(tomatinho-pause-face ((,class :foreground ,yellow-intense))) + `(tomatinho-reset-face ((,class :inherit shadow))) +;;;;; transient + `(transient-active-infix ((,class :inherit modus-theme-special-mild))) + `(transient-amaranth ((,class :inherit bold :foreground ,yellow))) + `(transient-argument ((,class :inherit bold :foreground ,red-alt))) + `(transient-blue ((,class :inherit bold :foreground ,blue))) + `(transient-disabled-suffix ((,class :inherit modus-theme-intense-red))) + `(transient-enabled-suffix ((,class :inherit modus-theme-intense-green))) + `(transient-heading ((,class :inherit bold :foreground ,fg-main))) + `(transient-inactive-argument ((,class :inherit shadow))) + `(transient-inactive-value ((,class :inherit shadow))) + `(transient-key ((,class :inherit bold :foreground ,blue))) + `(transient-mismatched-key ((,class :underline t))) + `(transient-nonstandard-key ((,class :underline t))) + `(transient-pink ((,class :inherit bold :foreground ,magenta))) + `(transient-red ((,class :inherit bold :foreground ,red-intense))) + `(transient-teal ((,class :inherit bold :foreground ,cyan-alt-other))) + `(transient-unreachable ((,class :foreground ,fg-unfocused))) + `(transient-unreachable-key ((,class :foreground ,fg-unfocused))) + `(transient-value ((,class :inherit bold :foreground ,magenta-alt-other))) +;;;;; trashed + `(trashed-deleted ((,class :inherit modus-theme-mark-del))) + `(trashed-directory ((,class :foreground ,blue))) + `(trashed-mark ((,class :inherit modus-theme-mark-symbol))) + `(trashed-marked ((,class :inherit modus-theme-mark-alt))) + `(trashed-restored ((,class :inherit modus-theme-mark-sel))) + `(trashed-symlink ((,class :inherit button + ,@(modus-themes--link-color + cyan-alt cyan-alt-faint)))) +;;;;; treemacs + `(treemacs-directory-collapsed-face ((,class :foreground ,magenta-alt))) + `(treemacs-directory-face ((,class :inherit dired-directory))) + `(treemacs-file-face ((,class :foreground ,fg-main))) + `(treemacs-fringe-indicator-face ((,class :foreground ,fg-main))) + `(treemacs-git-added-face ((,class :foreground ,green-intense))) + `(treemacs-git-conflict-face ((,class :inherit (modus-theme-intense-red bold)))) + `(treemacs-git-ignored-face ((,class :inherit shadow))) + `(treemacs-git-modified-face ((,class :foreground ,yellow-alt-other))) + `(treemacs-git-renamed-face ((,class :foreground ,cyan-alt-other))) + `(treemacs-git-unmodified-face ((,class :foreground ,fg-main))) + `(treemacs-git-untracked-face ((,class :foreground ,red-alt-other))) + `(treemacs-help-column-face ((,class :inherit modus-theme-bold :foreground ,magenta-alt-other :underline t))) + `(treemacs-help-title-face ((,class :foreground ,blue-alt-other))) + `(treemacs-on-failure-pulse-face ((,class :inherit modus-theme-intense-red))) + `(treemacs-on-success-pulse-face ((,class :inherit modus-theme-intense-green))) + `(treemacs-root-face ((,class :inherit bold :foreground ,blue-alt-other :height 1.2 :underline t))) + `(treemacs-root-remote-disconnected-face ((,class :inherit treemacs-root-remote-face :foreground ,yellow))) + `(treemacs-root-remote-face ((,class :inherit treemacs-root-face :foreground ,magenta))) + `(treemacs-root-remote-unreadable-face ((,class :inherit treemacs-root-unreadable-face))) + `(treemacs-root-unreadable-face ((,class :inherit treemacs-root-face :strike-through t))) + `(treemacs-tags-face ((,class :foreground ,blue-alt))) + `(treemacs-tags-face ((,class :foreground ,magenta-alt))) +;;;;; tty-menu + `(tty-menu-disabled-face ((,class :background ,bg-alt :foreground ,fg-alt))) + `(tty-menu-enabled-face ((,class :inherit bold :background ,bg-alt :foreground ,fg-main))) + `(tty-menu-selected-face ((,class :inherit modus-theme-intense-blue))) +;;;;; tuareg + `(caml-types-def-face ((,class :inherit modus-theme-subtle-red))) + `(caml-types-expr-face ((,class :inherit modus-theme-subtle-green))) + `(caml-types-occ-face ((,class :inherit modus-theme-subtle-green))) + `(caml-types-scope-face ((,class :inherit modus-theme-subtle-blue))) + `(caml-types-typed-face ((,class :inherit modus-theme-subtle-magenta))) + `(tuareg-font-double-semicolon-face ((,class :inherit font-lock-preprocessor-face))) + `(tuareg-font-lock-attribute-face ((,class :inherit font-lock-function-name-face))) + `(tuareg-font-lock-constructor-face ((,class :foreground ,fg-main))) + `(tuareg-font-lock-error-face ((,class :inherit (modus-theme-intense-red bold)))) + `(tuareg-font-lock-extension-node-face ((,class :background ,bg-alt :foreground ,magenta))) + `(tuareg-font-lock-governing-face ((,class :inherit bold :foreground ,fg-main))) + `(tuareg-font-lock-infix-extension-node-face ((,class :inherit font-lock-function-name-face))) + `(tuareg-font-lock-interactive-directive-face ((,class :foreground ,fg-special-cold))) + `(tuareg-font-lock-interactive-error-face ((,class :inherit error))) + `(tuareg-font-lock-interactive-output-face ((,class :inherit font-lock-constant-face))) + `(tuareg-font-lock-label-face ((,class :inherit font-lock-type-face))) + `(tuareg-font-lock-line-number-face ((,class :foreground ,fg-special-warm))) + `(tuareg-font-lock-module-face ((,class :inherit font-lock-builtin-face))) + `(tuareg-font-lock-multistage-face ((,class :inherit bold :background ,bg-alt :foreground ,blue))) + `(tuareg-font-lock-operator-face ((,class :inherit font-lock-preprocessor-face))) + `(tuareg-opam-error-face ((,class :inherit error))) + `(tuareg-opam-pkg-variable-name-face ((,class :inherit font-lock-variable-name-face))) +;;;;; typescript + `(typescript-jsdoc-tag ((,class :inherit modus-theme-slant :foreground ,fg-special-mild))) + `(typescript-jsdoc-type ((,class :inherit modus-theme-slant :foreground ,fg-special-calm))) + `(typescript-jsdoc-value ((,class :inherit modus-theme-slant :foreground ,fg-special-cold))) +;;;;; undo-tree + `(undo-tree-visualizer-active-branch-face ((,class :inherit bold :foreground ,fg-main))) + `(undo-tree-visualizer-current-face ((,class :foreground ,blue-intense))) + `(undo-tree-visualizer-default-face ((,class :inherit shadow))) + `(undo-tree-visualizer-register-face ((,class :foreground ,magenta-intense))) + `(undo-tree-visualizer-unmodified-face ((,class :foreground ,green-intense))) +;;;;; vc (vc-dir.el, vc-hooks.el) + `(vc-dir-directory ((,class :foreground ,blue))) + `(vc-dir-file ((,class :foreground ,fg-main))) + `(vc-dir-header ((,class :foreground ,cyan-alt-other))) + `(vc-dir-header-value ((,class :foreground ,magenta-alt-other))) + `(vc-dir-mark-indicator ((,class :foreground ,blue-alt-other))) + `(vc-dir-status-edited ((,class :foreground ,yellow))) + `(vc-dir-status-ignored ((,class :foreground ,fg-unfocused))) + `(vc-dir-status-up-to-date ((,class :foreground ,cyan))) + `(vc-dir-status-warning ((,class :foreground ,red))) + `(vc-conflict-state ((,class :inherit modus-theme-slant :foreground ,red-active))) + `(vc-edited-state ((,class :foreground ,yellow-active))) + `(vc-locally-added-state ((,class :foreground ,cyan-active))) + `(vc-locked-state ((,class :foreground ,blue-active))) + `(vc-missing-state ((,class :inherit modus-theme-slant :foreground ,magenta-active))) + `(vc-needs-update-state ((,class :inherit modus-theme-slant :foreground ,green-active))) + `(vc-removed-state ((,class :foreground ,red-active))) + `(vc-state-base ((,class :foreground ,fg-active))) + `(vc-up-to-date-state ((,class :foreground ,fg-special-cold))) +;;;;; vdiff + `(vdiff-addition-face ((,class :inherit modus-theme-diff-added))) + `(vdiff-change-face ((,class :inherit modus-theme-diff-changed))) + `(vdiff-closed-fold-face ((,class :background ,bg-diff-neutral-1 :foreground ,fg-diff-neutral-1))) + `(vdiff-refine-added ((,class :inherit modus-theme-diff-refine-added))) + `(vdiff-refine-changed ((,class :inherit modus-theme-diff-refine-changed))) + `(vdiff-subtraction-face ((,class :inherit modus-theme-diff-removed))) + `(vdiff-target-face ((,class :inherit modus-theme-intense-blue))) +;;;;; vimish-fold + `(vimish-fold-fringe ((,class :foreground ,cyan-active))) + `(vimish-fold-mouse-face ((,class :inherit modus-theme-intense-blue))) + `(vimish-fold-overlay ((,class :background ,bg-alt :foreground ,fg-special-cold))) +;;;;; visible-mark + `(visible-mark-active ((,class :background ,blue-intense-bg))) + `(visible-mark-face1 ((,class :background ,cyan-intense-bg))) + `(visible-mark-face2 ((,class :background ,yellow-intense-bg))) + `(visible-mark-forward-face1 ((,class :background ,magenta-intense-bg))) + `(visible-mark-forward-face2 ((,class :background ,green-intense-bg))) +;;;;; visual-regexp + `(vr/group-0 ((,class :inherit modus-theme-intense-blue))) + `(vr/group-1 ((,class :inherit modus-theme-intense-magenta))) + `(vr/group-2 ((,class :inherit modus-theme-intense-green))) + `(vr/match-0 ((,class :inherit modus-theme-refine-yellow))) + `(vr/match-1 ((,class :inherit modus-theme-refine-yellow))) + `(vr/match-separator-face ((,class :inherit (modus-theme-intense-neutral bold)))) +;;;;; volatile-highlights + `(vhl/default-face ((,class :background ,bg-alt :foreground ,blue-nuanced-fg :extend t))) +;;;;; vterm + `(vterm-color-black ((,class :background "gray35" :foreground "gray35"))) + `(vterm-color-blue ((,class :background ,blue :foreground ,blue))) + `(vterm-color-cyan ((,class :background ,cyan :foreground ,cyan))) + `(vterm-color-default ((,class :background ,bg-main :foreground ,fg-main))) + `(vterm-color-green ((,class :background ,green :foreground ,green))) + `(vterm-color-inverse-video ((,class :background ,bg-main :inverse-video t))) + `(vterm-color-magenta ((,class :background ,magenta :foreground ,magenta))) + `(vterm-color-red ((,class :background ,red :foreground ,red))) + `(vterm-color-underline ((,class :foreground ,fg-special-warm :underline t))) + `(vterm-color-white ((,class :background "gray65" :foreground "gray65"))) + `(vterm-color-yellow ((,class :background ,yellow :foreground ,yellow))) +;;;;; wcheck-mode + `(wcheck-default-face ((,class :foreground ,red :underline t))) +;;;;; web-mode + `(web-mode-annotation-face ((,class :inherit web-mode-comment-face))) + `(web-mode-annotation-html-face ((,class :inherit web-mode-comment-face))) + `(web-mode-annotation-tag-face ((,class :inherit web-mode-comment-face :underline t))) + `(web-mode-block-attr-name-face ((,class :inherit font-lock-constant-face))) + `(web-mode-block-attr-value-face ((,class :inherit font-lock-type-face))) + `(web-mode-block-comment-face ((,class :inherit web-mode-comment-face))) + `(web-mode-block-control-face ((,class :inherit font-lock-builtin-face))) + `(web-mode-block-delimiter-face ((,class :foreground ,fg-main))) + `(web-mode-block-face ((,class :background ,bg-dim))) + `(web-mode-block-string-face ((,class :inherit web-mode-string-face))) + `(web-mode-bold-face ((,class :inherit bold))) + `(web-mode-builtin-face ((,class :inherit font-lock-builtin-face))) + `(web-mode-comment-face ((,class :inherit font-lock-comment-face))) + `(web-mode-comment-keyword-face ((,class :inherit font-lock-warning-face))) + `(web-mode-constant-face ((,class :inherit font-lock-constant-face))) + `(web-mode-css-at-rule-face ((,class :inherit font-lock-constant-face))) + `(web-mode-css-color-face ((,class :inherit font-lock-builtin-face))) + `(web-mode-css-comment-face ((,class :inherit web-mode-comment-face))) + `(web-mode-css-function-face ((,class :inherit font-lock-builtin-face))) + `(web-mode-css-priority-face ((,class :inherit font-lock-warning-face))) + `(web-mode-css-property-name-face ((,class :inherit font-lock-keyword-face))) + `(web-mode-css-pseudo-class-face ((,class :inherit font-lock-doc-face))) + `(web-mode-css-selector-face ((,class :inherit font-lock-keyword-face))) + `(web-mode-css-string-face ((,class :inherit web-mode-string-face))) + `(web-mode-css-variable-face ((,class :foreground ,fg-special-warm))) + `(web-mode-current-column-highlight-face ((,class :background ,bg-alt))) + `(web-mode-current-element-highlight-face ((,class :inherit modus-theme-special-mild))) + `(web-mode-doctype-face ((,class :inherit modus-theme-slant :foreground ,fg-special-cold))) + `(web-mode-error-face ((,class :inherit modus-theme-intense-red))) + `(web-mode-filter-face ((,class :inherit font-lock-function-name-face))) + `(web-mode-folded-face ((,class :underline t))) + `(web-mode-function-call-face ((,class :inherit font-lock-function-name-face))) + `(web-mode-function-name-face ((,class :inherit font-lock-function-name-face))) + `(web-mode-html-attr-custom-face ((,class :inherit font-lock-variable-name-face))) + `(web-mode-html-attr-engine-face ((,class :foreground ,fg-main))) + `(web-mode-html-attr-equal-face ((,class :foreground ,fg-main))) + `(web-mode-html-attr-name-face ((,class :inherit font-lock-variable-name-face))) + `(web-mode-html-attr-value-face ((,class :inherit font-lock-constant-face))) + `(web-mode-html-entity-face ((,class :inherit font-lock-negation-char-face))) + `(web-mode-html-tag-bracket-face ((,class :foreground ,fg-dim))) + `(web-mode-html-tag-custom-face ((,class :inherit font-lock-function-name-face))) + `(web-mode-html-tag-face ((,class :inherit font-lock-function-name-face))) + `(web-mode-html-tag-namespaced-face ((,class :inherit font-lock-builtin-face))) + `(web-mode-html-tag-unclosed-face ((,class :inherit error :underline t))) + `(web-mode-inlay-face ((,class :background ,bg-alt))) + `(web-mode-italic-face ((,class :inherit italic))) + `(web-mode-javascript-comment-face ((,class :inherit web-mode-comment-face))) + `(web-mode-javascript-string-face ((,class :inherit web-mode-string-face))) + `(web-mode-json-comment-face ((,class :inherit web-mode-comment-face))) + `(web-mode-json-context-face ((,class :inherit font-lock-builtin-face))) + `(web-mode-json-key-face ((,class :foreground ,blue-nuanced-fg))) + `(web-mode-json-string-face ((,class :inherit web-mode-string-face))) + `(web-mode-jsx-depth-1-face ((,class :background ,blue-intense-bg :foreground ,fg-main))) + `(web-mode-jsx-depth-2-face ((,class :background ,blue-subtle-bg :foreground ,fg-main))) + `(web-mode-jsx-depth-3-face ((,class :background ,bg-special-cold :foreground ,fg-special-cold))) + `(web-mode-jsx-depth-4-face ((,class :background ,bg-alt :foreground ,blue-refine-fg))) + `(web-mode-jsx-depth-5-face ((,class :background ,bg-alt :foreground ,blue-nuanced-fg))) + `(web-mode-keyword-face ((,class :inherit :inherit font-lock-keyword-face))) + `(web-mode-param-name-face ((,class :inherit font-lock-function-name-face))) + `(web-mode-part-comment-face ((,class :inherit web-mode-comment-face))) + `(web-mode-part-face ((,class :inherit web-mode-block-face))) + `(web-mode-part-string-face ((,class :inherit web-mode-string-face))) + `(web-mode-preprocessor-face ((,class :inherit font-lock-preprocessor-face))) + `(web-mode-script-face ((,class :inherit web-mode-part-face))) + `(web-mode-sql-keyword-face ((,class :inherit font-lock-negation-char-face))) + `(web-mode-string-face ((,class :inherit font-lock-string-face))) + `(web-mode-style-face ((,class :inherit web-mode-part-face))) + `(web-mode-symbol-face ((,class :inherit font-lock-constant-face))) + `(web-mode-type-face ((,class :inherit font-lock-builtin-face))) + `(web-mode-underline-face ((,class :underline t))) + `(web-mode-variable-name-face ((,class :inherit font-lock-variable-name-face))) + `(web-mode-warning-face ((,class :inherit font-lock-warning-face))) + `(web-mode-whitespace-face ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) +;;;;; wgrep + `(wgrep-delete-face ((,class :inherit modus-theme-refine-yellow))) + `(wgrep-done-face ((,class :inherit modus-theme-refine-blue))) + `(wgrep-face ((,class :inherit modus-theme-refine-green))) + `(wgrep-file-face ((,class :foreground ,fg-special-warm))) + `(wgrep-reject-face ((,class :inherit (modus-theme-intense-red bold)))) +;;;;; which-function-mode + `(which-func ((,class :foreground ,magenta-active))) +;;;;; which-key + `(which-key-command-description-face ((,class :foreground ,fg-main))) + `(which-key-group-description-face ((,class :foreground ,magenta-alt))) + `(which-key-highlighted-command-face ((,class :foreground ,yellow :underline t))) + `(which-key-key-face ((,class :inherit bold :foreground ,blue-intense))) + `(which-key-local-map-description-face ((,class :foreground ,fg-main))) + `(which-key-note-face ((,class :foreground ,fg-special-warm))) + `(which-key-separator-face ((,class :inherit shadow))) + `(which-key-special-key-face ((,class :inherit bold :foreground ,orange-intense))) +;;;;; whitespace-mode + `(whitespace-big-indent ((,class :inherit modus-theme-subtle-red))) + `(whitespace-empty ((,class :inherit modus-theme-intense-magenta))) + `(whitespace-hspace ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) + `(whitespace-indentation ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) + `(whitespace-line ((,class :background ,bg-alt))) + `(whitespace-newline ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) + `(whitespace-space ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) + `(whitespace-space-after-tab ((,class :inherit modus-theme-subtle-magenta))) + `(whitespace-space-before-tab ((,class :inherit modus-theme-subtle-cyan))) + `(whitespace-tab ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) + `(whitespace-trailing ((,class :inherit modus-theme-intense-red))) +;;;;; window-divider-mode + `(window-divider ((,class :foreground ,fg-window-divider-inner))) + `(window-divider-first-pixel ((,class :foreground ,fg-window-divider-outer))) + `(window-divider-last-pixel ((,class :foreground ,fg-window-divider-outer))) +;;;;; winum + `(winum-face ((,class :inherit modus-theme-bold :foreground ,cyan-active))) +;;;;; writegood-mode + `(writegood-duplicates-face ((,class :background ,bg-alt :foreground ,red-alt :underline t))) + `(writegood-passive-voice-face ((,class :inherit modus-theme-lang-warning))) + `(writegood-weasels-face ((,class :inherit modus-theme-lang-error))) +;;;;; woman + `(woman-addition ((,class :foreground ,magenta-alt-other))) + `(woman-bold ((,class :inherit bold :foreground ,magenta))) + `(woman-italic ((,class :inherit italic :foreground ,cyan))) + `(woman-unknown ((,class :inherit italic :foreground ,yellow))) +;;;;; xah-elisp-mode + `(xah-elisp-at-symbol ((,class :inherit font-lock-warning-face))) + `(xah-elisp-cap-variable ((,class :inherit font-lock-preprocessor-face))) + `(xah-elisp-command-face ((,class :inherit font-lock-type-face))) + `(xah-elisp-dollar-symbol ((,class :inherit font-lock-variable-name-face))) +;;;;; xref + `(xref-file-header ((,class :inherit bold :foreground ,fg-special-cold))) + `(xref-line-number ((,class :inherit shadow))) + `(xref-match ((,class :inherit match))) +;;;;; yaml-mode + `(yaml-tab-face ((,class :inherit modus-theme-intense-red))) +;;;;; yasnippet + `(yas-field-highlight-face ((,class :background ,bg-hl-alt-intense))) +;;;;; ztree + `(ztreep-arrow-face ((,class :foreground ,fg-inactive))) + `(ztreep-diff-header-face ((,class :inherit bold :height 1.2 :foreground ,fg-special-cold))) + `(ztreep-diff-header-small-face ((,class :inherit bold :foreground ,fg-special-mild))) + `(ztreep-diff-model-add-face ((,class :foreground ,green))) + `(ztreep-diff-model-diff-face ((,class :foreground ,red))) + `(ztreep-diff-model-ignored-face ((,class :inherit shadow :strike-through t))) + `(ztreep-diff-model-normal-face ((,class :inherit shadow))) + `(ztreep-expand-sign-face ((,class :foreground ,blue))) + `(ztreep-header-face ((,class :inherit bold :height 1.2 :foreground ,fg-special-cold))) + `(ztreep-leaf-face ((,class :foreground ,cyan))) + `(ztreep-node-count-children-face ((,class :foreground ,fg-special-warm))) + `(ztreep-node-face ((,class :foreground ,fg-main)))) + "Face specs for use with `modus-themes-theme'.") + +(defconst modus-themes-custom-variables + '( +;;;; ansi-colors + `(ansi-color-faces-vector [default bold shadow italic underline success warning error]) + `(ansi-color-names-vector ["gray35" ,red ,green ,yellow ,blue ,magenta ,cyan "gray65"]) +;;;; awesome-tray + `(awesome-tray-mode-line-active-color ,blue) + `(awesome-tray-mode-line-inactive-color ,bg-active) +;;;; exwm + `(exwm-floating-border-color ,fg-window-divider-inner) +;;;; flymake fringe indicators + `(flymake-error-bitmap '(flymake-double-exclamation-mark modus-theme-fringe-red)) + `(flymake-warning-bitmap '(exclamation-mark modus-theme-fringe-yellow)) + `(flymake-note-bitmap '(exclamation-mark modus-theme-fringe-cyan)) +;;;; ibuffer + `(ibuffer-deletion-face 'modus-theme-mark-del) + `(ibuffer-filter-group-name-face 'modus-theme-mark-symbol) + `(ibuffer-marked-face 'modus-theme-mark-sel) + `(ibuffer-title-face 'modus-theme-pseudo-header) +;;;; highlight-tail + `(highlight-tail-colors + '((,green-subtle-bg . 0) + (,cyan-subtle-bg . 20))) +;;;; hl-todo + `(hl-todo-keyword-faces + '(("HOLD" . ,yellow-alt) + ("TODO" . ,magenta) + ("NEXT" . ,magenta-alt-other) + ("THEM" . ,magenta-alt) + ("PROG" . ,cyan) + ("OKAY" . ,cyan-alt) + ("DONT" . ,green-alt) + ("FAIL" . ,red) + ("BUG" . ,red) + ("DONE" . ,green) + ("NOTE" . ,yellow-alt-other) + ("KLUDGE" . ,yellow) + ("HACK" . ,yellow) + ("TEMP" . ,red-nuanced-fg) + ("FIXME" . ,red-alt-other) + ("XXX+" . ,red-alt) + ("REVIEW" . ,cyan-alt-other) + ("DEPRECATED" . ,blue-nuanced-fg))) +;;;; pdf-tools + `(pdf-view-midnight-colors + '(,fg-main . ,bg-dim)) +;;;; vc-annotate (C-x v g) + `(vc-annotate-background nil) + `(vc-annotate-background-mode nil) + `(vc-annotate-color-map + '((20 . ,red) + (40 . ,magenta) + (60 . ,magenta-alt) + (80 . ,red-alt) + (100 . ,yellow) + (120 . ,yellow-alt) + (140 . ,fg-special-warm) + (160 . ,fg-special-mild) + (180 . ,green) + (200 . ,green-alt) + (220 . ,cyan-alt-other) + (240 . ,cyan-alt) + (260 . ,cyan) + (280 . ,fg-special-cold) + (300 . ,blue) + (320 . ,blue-alt) + (340 . ,blue-alt-other) + (360 . ,magenta-alt-other))) + `(vc-annotate-very-old-color nil) +;;;; xterm-color + `(xterm-color-names ["black" ,red ,green ,yellow ,blue ,magenta ,cyan "gray65"]) + `(xterm-color-names-bright ["gray35" ,red-alt ,green-alt ,yellow-alt ,blue-alt ,magenta-alt ,cyan-alt "white"]) + (if (eq modus-themes-org-blocks 'rainbow) + `(org-src-block-faces ; TODO this list should be expanded + `(("emacs-lisp" modus-theme-nuanced-magenta) + ("elisp" modus-theme-nuanced-magenta) + ("clojure" modus-theme-nuanced-magenta) + ("clojurescript" modus-theme-nuanced-magenta) + ("c" modus-theme-nuanced-blue) + ("c++" modus-theme-nuanced-blue) + ("sh" modus-theme-nuanced-green) + ("shell" modus-theme-nuanced-green) + ("html" modus-theme-nuanced-yellow) + ("xml" modus-theme-nuanced-yellow) + ("css" modus-theme-nuanced-red) + ("scss" modus-theme-nuanced-red) + ("python" modus-theme-nuanced-green) + ("ipython" modus-theme-nuanced-magenta) + ("r" modus-theme-nuanced-cyan) + ("yaml" modus-theme-nuanced-cyan) + ("conf" modus-theme-nuanced-cyan) + ("docker" modus-theme-nuanced-cyan))) + `(org-src-block-faces '()))) + "Custom variables for `modus-themes-theme'.") + +(provide 'modus-themes) +;;; modus-themes.el ends here diff --git a/etc/themes/modus-vivendi-theme.el b/etc/themes/modus-vivendi-theme.el index 171313244b..fd7f5df24d 100644 --- a/etc/themes/modus-vivendi-theme.el +++ b/etc/themes/modus-vivendi-theme.el @@ -1,4663 +1,65 @@ ;;; modus-vivendi-theme.el --- Accessible dark theme (WCAG AAA) -*- lexical-binding:t -*- -;; Copyright (C) 2019-2021 Free Software Foundation, Inc. +;; Copyright (C) 2019-2021 Free Software Foundation, Inc. ;; Author: Protesilaos Stavrou ;; URL: https://gitlab.com/protesilaos/modus-themes -;; Version: 0.13.0 +;; Version: 1.2.0 ;; Package-Requires: ((emacs "26.1")) ;; Keywords: faces, theme, accessibility ;; This file is part of GNU Emacs. -;; GNU Emacs is free software: you can redistribute it and/or modify +;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs. If not, see . +;; along with this program. If not, see . ;;; Commentary: ;; -;; This theme is designed for colour-contrast accessibility. -;; -;; 1. Provide a consistent minimum contrast ratio between background and -;; foreground values of 7:1 or higher. This meets the highest such -;; accessibility criterion per the guidelines of the Worldwide Web -;; Consortium's Working Group on Accessibility (WCAG AAA standard). +;; Modus Vivendi is the dark variant of the Modus themes (Modus Operandi +;; is the light one). The themes are designed for color-contrast +;; accessibility. More specifically: ;; -;; 2. Offer as close to full face coverage as possible. The list is -;; already quite long (see further below), with more additions to follow -;; as part of the ongoing development process. +;; 1. Provide a consistent minimum contrast ratio between background +;; and foreground values of 7:1 or higher. This meets the highest +;; such accessibility criterion per the guidelines of the Worldwide +;; Web Consortium's Working Group on Accessibility (WCAG AAA +;; standard). ;; -;; The theme provides the following customisation options, all of which -;; are disabled by default: +;; 2. Offer as close to full face coverage as possible. The list is +;; already quite long, with more additions to follow as part of the +;; ongoing development process. ;; -;; modus-vivendi-theme-slanted-constructs (boolean) -;; modus-vivendi-theme-bold-constructs (boolean) -;; modus-vivendi-theme-variable-pitch-headings (boolean) -;; modus-vivendi-theme-no-mixed-fonts (boolean) -;; modus-vivendi-theme-headings (alist) -;; modus-vivendi-theme-scale-headings (boolean) -;; modus-vivendi-theme-fringes (choice) -;; modus-vivendi-theme-org-blocks (choice) -;; modus-vivendi-theme-prompts (choice) -;; modus-vivendi-theme-mode-line (choice) -;; modus-vivendi-theme-diffs (choice) -;; modus-vivendi-theme-faint-syntax (boolean) -;; modus-vivendi-theme-intense-hl-line (boolean) -;; modus-vivendi-theme-intense-paren-match (boolean) -;; modus-vivendi-theme-no-link-underline (boolean) -;; modus-vivendi-theme-completions (choice) -;; modus-vivendi-theme-override-colors-alist (alist) +;; For a complete view of the project, also refer to the following files +;; (should be distributed in the same repository/directory as the +;; current item): ;; -;; The default scale is as follows (it can be customised as well): -;; -;; modus-vivendi-theme-scale-1 1.05 -;; modus-vivendi-theme-scale-2 1.1 -;; modus-vivendi-theme-scale-3 1.15 -;; modus-vivendi-theme-scale-4 1.2 -;; modus-vivendi-theme-scale-5 1.3 -;; -;; What follows is the list of explicitly supported packages or face -;; groups (there are implicitly supported packages as well, which -;; inherit from font-lock or some basic group). You are encouraged to -;; notify me of any missing package or change you would like to see. -;; -;; ace-window -;; ag -;; alert -;; all-the-icons -;; annotate -;; anzu -;; apropos -;; apt-sources-list -;; artbollocks-mode -;; auctex and TeX -;; auto-dim-other-buffers -;; avy -;; awesome-tray -;; binder -;; bm -;; bongo -;; boon -;; breakpoint (provided by built-in gdb-mi.el) -;; buffer-expose -;; calendar and diary -;; calfw -;; centaur-tabs -;; change-log and log-view (`vc-print-log' and `vc-print-root-log') -;; cider -;; circe -;; color-rg -;; column-enforce-mode -;; company-mode -;; company-posframe -;; compilation-mode -;; completions -;; counsel -;; counsel-css -;; counsel-notmuch -;; counsel-org-capture-string -;; cov -;; cperl-mode -;; csv-mode -;; ctrlf -;; custom (M-x customize) -;; dap-mode -;; dashboard (emacs-dashboard) -;; deadgrep -;; debbugs -;; define-word -;; deft -;; dictionary -;; diff-hl -;; diff-mode -;; dim-autoload -;; dir-treeview -;; dired -;; dired-async -;; dired-git -;; dired-git-info -;; dired-narrow -;; dired-subtree -;; diredfl -;; disk-usage -;; doom-modeline -;; dynamic-ruler -;; easy-jekyll -;; easy-kill -;; ebdb -;; ediff -;; eglot -;; el-search -;; eldoc -;; eldoc-box -;; elfeed -;; elfeed-score -;; emms -;; enhanced-ruby-mode -;; epa -;; equake -;; erc -;; eros -;; ert -;; eshell -;; eshell-fringe-status -;; eshell-git-prompt -;; eshell-prompt-extras (epe) -;; eshell-syntax-highlighting -;; evil (evil-mode) -;; evil-goggles -;; evil-visual-mark-mode -;; eww -;; eyebrowse -;; fancy-dabbrev -;; flycheck -;; flycheck-color-mode-line -;; flycheck-indicator -;; flycheck-posframe -;; flymake -;; flyspell -;; flyspell-correct -;; flx -;; freeze-it -;; frog-menu -;; focus -;; fold-this -;; font-lock (generic syntax highlighting) -;; forge -;; fountain (fountain-mode) -;; geiser -;; git-commit -;; git-gutter (and variants) -;; git-lens -;; git-rebase -;; git-timemachine -;; git-walktree -;; gnus -;; golden-ratio-scroll-screen -;; helm -;; helm-ls-git -;; helm-switch-shell -;; helm-xref -;; helpful -;; highlight-blocks -;; highlight-defined -;; highlight-escape-sequences (`hes-mode') -;; highlight-indentation -;; highlight-numbers -;; highlight-symbol -;; highlight-tail -;; highlight-thing -;; hl-defined -;; hl-fill-column -;; hl-line-mode -;; hl-todo -;; hydra -;; hyperlist -;; ibuffer -;; icomplete -;; ido-mode -;; iedit -;; iflipb -;; imenu-list -;; indium -;; info -;; info-colors -;; interaction-log -;; ioccur -;; isearch, occur, etc. -;; ivy -;; ivy-posframe -;; jira (org-jira) -;; journalctl-mode -;; js2-mode -;; julia -;; jupyter -;; kaocha-runner -;; keycast -;; line numbers (`display-line-numbers-mode' and global variant) -;; lsp-mode -;; lsp-ui -;; magit -;; magit-imerge -;; man -;; markdown-mode -;; markup-faces (`adoc-mode') -;; mentor -;; messages -;; minibuffer-line -;; minimap -;; modeline -;; mood-line -;; mpdel -;; mu4e -;; mu4e-conversation -;; multiple-cursors -;; neotree -;; no-emoji -;; notmuch -;; num3-mode -;; nxml-mode -;; objed -;; orderless -;; org -;; org-journal -;; org-noter -;; org-pomodoro -;; org-recur -;; org-roam -;; org-superstar -;; org-table-sticky-header -;; org-treescope -;; origami -;; outline-mode -;; outline-minor-faces -;; package (M-x list-packages) -;; page-break-lines -;; paradox -;; paren-face -;; parrot -;; pass -;; persp-mode -;; perspective -;; phi-grep -;; phi-search -;; pkgbuild-mode -;; pomidor -;; powerline -;; powerline-evil -;; proced -;; prodigy -;; racket-mode -;; rainbow-blocks -;; rainbow-identifiers -;; rainbow-delimiters -;; rcirc -;; regexp-builder (also known as `re-builder') -;; rg -;; ripgrep -;; rmail -;; ruler-mode -;; sallet -;; selectrum -;; semantic -;; sesman -;; shell-script-mode -;; show-paren-mode -;; side-notes -;; skewer-mode -;; smart-mode-line -;; smartparens -;; smerge -;; spaceline -;; speedbar -;; spell-fu -;; stripes -;; suggest -;; switch-window -;; swiper -;; swoop -;; sx -;; symbol-overlay -;; tab-bar-mode -;; tab-line-mode -;; syslog-mode -;; table (built-in table.el) -;; telephone-line -;; term -;; tomatinho -;; transient (pop-up windows like Magit's) -;; trashed -;; treemacs -;; tty-menu -;; tuareg -;; typescript -;; undo-tree -;; vc (built-in mode line status for version control) -;; vc-annotate (C-x v g) -;; vdiff -;; vimish-fold -;; visible-mark -;; visual-regexp -;; volatile-highlights -;; vterm -;; wcheck-mode -;; web-mode -;; wgrep -;; which-function-mode -;; which-key -;; whitespace-mode -;; window-divider-mode -;; winum -;; writegood-mode -;; woman -;; xah-elisp-mode -;; xref -;; xterm-color (and ansi-colors) -;; yaml-mode -;; yasnippet -;; ztree +;; - modus-themes.el (Main code shared between the themes) +;; - modus-operandi-theme.el (Light theme) ;;; Code: -(deftheme modus-vivendi - "Dark theme that conforms with the highest accessibility - standard for colour contrast between background and - foreground elements (WCAG AAA).") - -;;; Custom faces - -;; These faces will be inherited by actual constructs. They are meant -;; for those cases where a face needs to distinguish its output from -;; the rest of the text, such as `isearch' and `occur'… We define -;; these separately in order to combine each colour with its -;; appropriate foreground value. This is to ensure a consistent -;; contrast ratio of >= 7:1. -(defgroup modus-theme () - "Theme that ensures WCAG AAA accessibility (contrast ratio -between foreground and background is >= 7:1)." - :group 'faces - :prefix "modus-theme-" - :link '(url-link :tag "GitLab" "https://gitlab.com/protesilaos/modus-themes") - :tag "Modus Vivendi") - -(defface modus-theme-subtle-red nil nil) -(defface modus-theme-subtle-green nil nil) -(defface modus-theme-subtle-yellow nil nil) -(defface modus-theme-subtle-blue nil nil) -(defface modus-theme-subtle-magenta nil nil) -(defface modus-theme-subtle-cyan nil nil) -(defface modus-theme-subtle-neutral nil nil) -(defface modus-theme-intense-red nil nil) -(defface modus-theme-intense-green nil nil) -(defface modus-theme-intense-yellow nil nil) -(defface modus-theme-intense-blue nil nil) -(defface modus-theme-intense-magenta nil nil) -(defface modus-theme-intense-cyan nil nil) -(defface modus-theme-intense-neutral nil nil) -(defface modus-theme-refine-red nil nil) -(defface modus-theme-refine-green nil nil) -(defface modus-theme-refine-yellow nil nil) -(defface modus-theme-refine-blue nil nil) -(defface modus-theme-refine-magenta nil nil) -(defface modus-theme-refine-cyan nil nil) -(defface modus-theme-active-red nil nil) -(defface modus-theme-active-green nil nil) -(defface modus-theme-active-yellow nil nil) -(defface modus-theme-active-blue nil nil) -(defface modus-theme-active-magenta nil nil) -(defface modus-theme-active-cyan nil nil) -(defface modus-theme-fringe-red nil nil) -(defface modus-theme-fringe-green nil nil) -(defface modus-theme-fringe-yellow nil nil) -(defface modus-theme-fringe-blue nil nil) -(defface modus-theme-fringe-magenta nil nil) -(defface modus-theme-fringe-cyan nil nil) -(defface modus-theme-nuanced-red nil nil) -(defface modus-theme-nuanced-green nil nil) -(defface modus-theme-nuanced-yellow nil nil) -(defface modus-theme-nuanced-blue nil nil) -(defface modus-theme-nuanced-magenta nil nil) -(defface modus-theme-nuanced-cyan nil nil) -(defface modus-theme-special-cold nil nil) -(defface modus-theme-special-mild nil nil) -(defface modus-theme-special-warm nil nil) -(defface modus-theme-special-calm nil nil) -(defface modus-theme-diff-added nil nil) -(defface modus-theme-diff-changed nil nil) -(defface modus-theme-diff-removed nil nil) -(defface modus-theme-diff-refine-added nil nil) -(defface modus-theme-diff-refine-changed nil nil) -(defface modus-theme-diff-refine-removed nil nil) -(defface modus-theme-diff-focus-added nil nil) -(defface modus-theme-diff-focus-changed nil nil) -(defface modus-theme-diff-focus-removed nil nil) -(defface modus-theme-diff-heading nil nil) -(defface modus-theme-pseudo-header nil nil) -(defface modus-theme-mark-alt nil nil) -(defface modus-theme-mark-del nil nil) -(defface modus-theme-mark-sel nil nil) -(defface modus-theme-mark-symbol nil nil) -(defface modus-theme-heading-1 nil nil) -(defface modus-theme-heading-2 nil nil) -(defface modus-theme-heading-3 nil nil) -(defface modus-theme-heading-4 nil nil) -(defface modus-theme-heading-5 nil nil) -(defface modus-theme-heading-6 nil nil) -(defface modus-theme-heading-7 nil nil) -(defface modus-theme-heading-8 nil nil) -(defface modus-theme-hl-line nil nil) - -;;; Customisation options - -;; User-facing customisation options. They are all deactivated by -;; default (users must opt in). -(defcustom modus-vivendi-theme-slanted-constructs nil - "Use slanted text in more code constructs (italics or oblique)." - :type 'boolean) - -(defcustom modus-vivendi-theme-bold-constructs nil - "Use bold text in more code constructs." - :type 'boolean) - -(define-obsolete-variable-alias 'modus-vivendi-theme-proportional-fonts - 'modus-vivendi-theme-variable-pitch-headings "`modus-vivendi-theme' 0.11.0") - -(defcustom modus-vivendi-theme-proportional-fonts nil - "Use proportional fonts (variable-pitch) in headings." - :type 'boolean) - -(defcustom modus-vivendi-theme-variable-pitch-headings nil - "Use proportional fonts (variable-pitch) in headings." - :type 'boolean) - -(defcustom modus-vivendi-theme-no-mixed-fonts nil - "Disable inheritance from `fixed-pitch' in some faces. - -This is done by default to allow spacing-sensitive constructs, -such as Org tables and code blocks, to remain monospaced when -users opt for something like the command `variable-pitch-mode'. -The downside with the default is that users need to explicitly -configure the font family of `fixed-pitch' in order to get a -consistent experience. That may be something they do not want to -do. Hence this option to disable any kind of technique for -mixing fonts." - :type 'boolean) - -(make-obsolete 'modus-vivendi-theme-rainbow-headings - 'modus-vivendi-theme-headings - "`modus-vivendi-theme' 0.13.0") - -(defcustom modus-vivendi-theme-rainbow-headings nil - "Use more saturated colours for headings." - :type 'boolean) - -(make-obsolete 'modus-vivendi-theme-section-headings - 'modus-vivendi-theme-headings - "`modus-vivendi-theme' 0.13.0") - -(defcustom modus-vivendi-theme-section-headings nil - "Use a background and an overline in headings." - :type 'boolean) - -(defcustom modus-vivendi-theme-headings - '((t . nil)) - "Alist of styles for headings, with optional value per level. - -To control faces per level from 1-8, use something like this: - - (setq modus-vivendi-theme-headings - '((1 . highlight) - (2 . line) - (t . rainbow-line-no-bold))) - -To set a uniform value for all heading levels, use this pattern: - - (setq modus-vivendi-theme-headings - '((t . rainbow-line-no-bold))) - -The default uses a fairly desaturated foreground value in -combination with a bold typographic weight. To specify this -style for a given level N (assuming you wish to have another -fallback option), just specify the value t like this: - - (setq modus-vivendi-theme-headings - '((1 . t) - (2 . line) - (t . rainbow-line-no-bold))) - -A description of all possible values: - -+ `no-bold' retains the default text colour while removing - the typographic weight. - -+ `line' is the same as the default plus an overline over the - heading. - -+ `line-no-bold' is the same as `line' without bold weight. - -+ `rainbow' uses a more colourful foreground in combination - with bold weight. - -+ `rainbow-line' is the same as `rainbow' plus an overline. - -+ `rainbow-line-no-bold' is the same as `rainbow-line' without - the bold weight. - -+ `highlight' retains the default style of a fairly desaturated - foreground combined with a bold weight and add to it a subtle - accented background. - -+ `highlight-no-bold' is the same as `highlight' without a bold - weight. - -+ `rainbow-highlight' is the same as `highlight' but with a more - colourful foreground. - -+ `rainbow-highlight-no-bold' is the same as `rainbow-highlight' - without a bold weight. - -+ `section' retains the default looks and adds to them both an - overline and a slightly accented background. It is, in effect, - a combination of the `line' and `highlight' values. - -+ `section-no-bold' is the same as `section' without a bold - weight. - -+ `rainbow-section' is the same as `section' but with a more - colourful foreground. - -+ `rainbow-section-no-bold' is the same as `rainbow-section' - without a bold weight." - :type - '(alist - :key-type symbol - :value-type - (choice (const :tag "Fairly desaturated foreground with bold weight (default)" t) - (const :tag "Like the default without bold weight" no-bold) - (const :tag "Like the default plus overline" line) - (const :tag "Like `line' without bold weight" line-no-bold) - (const :tag "Like the default but with more colourful foreground" rainbow) - (const :tag "Like `rainbow' plus overline" rainbow-line) - (const :tag "Like `rainbow' without bold weight" rainbow-no-bold) - (const :tag "Like `rainbow-line' without bold weight" rainbow-line-no-bold) - (const :tag "Like the default plus subtle background" highlight) - (const :tag "Like `highlight' without bold weight" highlight-no-bold) - (const :tag "Like `highlight' with more colourful foreground" rainbow-highlight) - (const :tag "Like `rainbow-highlight' without bold weight" rainbow-highlight-no-bold) - (const :tag "Like `highlight' plus overline" section) - (const :tag "Like `section' without bold weight" section-no-bold) - (const :tag "Like `section' with more colourful foreground" rainbow-section) - (const :tag "Like `rainbow-section' without bold weight" rainbow-section-no-bold)))) - -(defcustom modus-vivendi-theme-scale-headings nil - "Use font scaling for headings." - :type 'boolean) - -(defcustom modus-vivendi-theme-scale-1 1.05 - "Font size that is slightly larger than the base value. -The default is a floating point that is interpreted as a multiple -of the base font size. However, the variable also accepts an -integer, understood as an absolute height (e.g. a value of 140 is -the same as setting the font at 14 point size). - -For more on the matter, read the documentation of -`set-face-attribute', specifically the ':height' section." - :type 'number) - -(defcustom modus-vivendi-theme-scale-2 1.1 - "Font size slightly larger than `modus-vivendi-theme-scale-1'. -The default is a floating point that is interpreted as a multiple -of the base font size. However, the variable also accepts an -integer, understood as an absolute height (e.g. a value of 140 is -the same as setting the font at 14 point size). - -For more on the matter, read the documentation of -`set-face-attribute', specifically the ':height' section." - :type 'number) - -(defcustom modus-vivendi-theme-scale-3 1.15 - "Font size slightly larger than `modus-vivendi-theme-scale-2'. -The default is a floating point that is interpreted as a multiple -of the base font size. However, the variable also accepts an -integer, understood as an absolute height (e.g. a value of 140 is -the same as setting the font at 14 point size). - -For more on the matter, read the documentation of -`set-face-attribute', specifically the ':height' section." - :type 'number) - -(defcustom modus-vivendi-theme-scale-4 1.2 - "Font size slightly larger than `modus-vivendi-theme-scale-3'. -The default is a floating point that is interpreted as a multiple -of the base font size. However, the variable also accepts an -integer, understood as an absolute height (e.g. a value of 140 is -the same as setting the font at 14 point size). - -For more on the matter, read the documentation of -`set-face-attribute', specifically the ':height' section." - :type 'number) - -(defcustom modus-vivendi-theme-scale-5 1.3 - "Font size slightly larger than `modus-vivendi-theme-scale-4'. -The default is a floating point that is interpreted as a multiple -of the base font size. However, the variable also accepts an -integer, understood as an absolute height (e.g. a value of 140 is -the same as setting the font at 14 point size). - -For more on the matter, read the documentation of -`set-face-attribute', specifically the ':height' section." - :type 'number) - -(make-obsolete 'modus-vivendi-theme-visible-fringes - 'modus-vivendi-theme-fringes - "`modus-vivendi-theme' 0.12.0") - -(defcustom modus-vivendi-theme-visible-fringes nil - "Use a visible style for fringes." - :type 'boolean) - -(defcustom modus-vivendi-theme-fringes nil - "Define the visibility of fringes. - -Nil means the fringes have no background colour. Option `subtle' -will apply a greyscale value that is visible yet close to the -main buffer background colour. Option `intense' will use a more -pronounced greyscale value." - :type '(choice - (const :tag "No visible fringes (default)" nil) - (const :tag "Subtle greyscale background" subtle) - (const :tag "Intense greyscale background" intense))) - -(make-obsolete 'modus-vivendi-theme-distinct-org-blocks - 'modus-vivendi-theme-org-blocks - "`modus-vivendi-theme' 0.11.0") - -(defcustom modus-vivendi-theme-distinct-org-blocks nil - "Use a distinct neutral background for `org-mode' blocks." - :type 'boolean) - -(make-obsolete 'modus-vivendi-theme-rainbow-org-src-blocks - 'modus-vivendi-theme-org-blocks - "`modus-vivendi-theme' 0.11.0") - -(defcustom modus-vivendi-theme-rainbow-org-src-blocks nil - "Use colour-coded backgrounds for `org-mode' source blocks. -The colour in use depends on the language (send feedback to -include more languages)." - :type 'boolean) - -(defcustom modus-vivendi-theme-org-blocks nil - "Use a subtle grey or colour-coded background for Org blocks. - -Nil means that the block will have no background of its own and -will use the default that applies to the rest of the buffer. - -Option `greyscale' will apply a subtle neutral grey background to -the block's contents. It also affects the begin and end lines of -the block: their background will be extended to the edge of the -window for Emacs version >= 27 where the ':extend' keyword is -recognised by `set-face-attribute'. - -Option `rainbow' will use an accented background for the contents -of the block. The exact colour will depend on the programming -language and is controlled by the `org-src-block-faces' -variable (refer to the theme's source code for the current -association list)." - :type '(choice - (const :tag "No Org block background (default)" nil) - (const :tag "Subtle grey block background" greyscale) - (const :tag "Colour-coded background per programming language" rainbow))) - -(make-obsolete 'modus-vivendi-theme-3d-modeline - 'modus-vivendi-theme-mode-line - "`modus-vivendi-theme' 0.13.0") - -(defcustom modus-vivendi-theme-3d-modeline nil - "Use a three-dimensional style for the active mode line." - :type 'boolean) - -(defcustom modus-vivendi-theme-mode-line nil - "Adjust the overall style of the mode line. - -Nil is a two-dimensional rectangle with a border around it. The -active and the inactive modelines use different shades of -greyscale values for the background and foreground. - -A `3d' value will apply a three-dimensional effect to the active -modeline. The inactive modelines remain two-dimensional and are -toned down a bit, relative to the nil value. - -The `moody' option is meant to optimise the modeline for use with -the library of the same name. This practically means to remove -the box effect and rely on underline and overline properties -instead. It also tones down the inactive modelines. Despite its -intended purpose, this option can also be used without the -`moody' library." - :type '(choice - (const :tag "Two-dimensional box (default)" nil) - (const :tag "Three-dimensional style for the active mode line" 3d) - (const :tag "No box effects, which are optimal for use with the `moody' library" moody))) - -(make-obsolete 'modus-vivendi-theme-subtle-diffs - 'modus-vivendi-theme-diffs - "`modus-vivendi-theme' 0.13.0") - -(defcustom modus-vivendi-theme-subtle-diffs nil - "Use fewer/dim backgrounds in `diff-mode', `ediff',`magit'." - :type 'boolean) +(require-theme 'modus-themes) -(defcustom modus-vivendi-theme-diffs nil - "Adjust the overall styles of diffs. - -Nil means to use fairly intense colour combinations for diffs. -For example, you get a rich green background with a green -foreground for added lines. Word-wise or 'refined' diffs follow -the same pattern but use different shades of those colours to -remain distinct. - -A `desaturated' value follows the same principles as with the nil -option, while it tones down all relevant colours. - -Option `fg-only' will remove all accented backgrounds, except -from word-wise changes. It instead uses colour-coded foreground -values to differentiate between added/removed/changed lines. If -a background is necessary, such as with `ediff', then a subtle -greyscale value is used." - :type '(choice - (const :tag "Intensely coloured backgrounds (default)" nil) - (const :tag "Slightly accented backgrounds with tinted text" desaturated) - (const :tag "No backgrounds, except for refined diffs" fg-only))) - -(make-obsolete 'modus-vivendi-theme-intense-standard-completions - 'modus-vivendi-theme-completions - "`modus-vivendi-theme' 0.12.0") - -(defcustom modus-vivendi-theme-intense-standard-completions nil - "Use prominent backgrounds for Icomplete, Ido, or similar." - :type 'boolean) - -(defcustom modus-vivendi-theme-completions nil - "Apply special styles to the UI of completion frameworks. - -This concerns Icomplete, Ivy, Helm, Selectrum, Ido, as well as -any other tool meant to enhance their experience. The effect -will vary depending on the completion framework. - -Nil means to remain faithful to the metaphors that each UI -establishes. For example, Icomplete and Ido only use foreground -colours to style their matches, whereas Ivy or Helm rely on an -aesthetic that combines coloured backgrounds with appropriate -text colour. - -Option `moderate' will apply a combination of background and -foreground that is fairly subtle. For Icomplete and the like, -this constitutes a departure from their standard style. While -Ivy, Helm, and the others, will use less pronounced colours for -applicable contexts. - -Option `opinionated' will apply colour combinations that -refashion the completion UI. So Icomplete et al will now use -styles that resemble the defaults of Ivy and co., while the -latter group will revert to an even more nuanced aesthetic." - :type '(choice - (const :tag "Respect the framework's established aesthetic (default)" nil) - (const :tag "Subtle backgrounds for various elements" moderate) - (const :tag "Radical alternative to the framework's looks" opinionated))) - -(defcustom modus-vivendi-theme-prompts nil - "Use subtle or intense styles for minibuffer and REPL prompts. - -Nil means to only use an accented foreground colour. - -Options `subtle' and `intense' will change both the background -and the foreground values. The latter has a more pronounced -effect than the former." - :type '(choice - (const :tag "No prompt background (default)" nil) - (const :tag "Subtle accented background for the prompt" subtle) - (const :tag "Intense background and foreground for the prompt" intense))) - -(defcustom modus-vivendi-theme-intense-hl-line nil - "Use more prominent background for command `hl-line-mode'." - :type 'boolean) - -(defcustom modus-vivendi-theme-intense-paren-match nil - "Use more prominent colour for parenthesis matching." - :type 'boolean) - -(defcustom modus-vivendi-theme-faint-syntax nil - "Use less saturated colours for code syntax highlighting." - :type 'boolean) - -(defcustom modus-vivendi-theme-no-link-underline nil - "Do not underline links." - :type 'boolean) - -;;; Internal functions - -;; Helper functions that are meant to ease the implementation of the -;; above customisation options. -(defun modus-vivendi-theme-bold-weight () - "Conditional use of a heavier text weight." - (when modus-vivendi-theme-bold-constructs - (list :inherit 'bold))) - -(defun modus-vivendi-theme-mixed-fonts () - "Conditional application of `fixed-pitch' inheritance." - (unless modus-vivendi-theme-no-mixed-fonts - (list :inherit 'fixed-pitch))) - -(defun modus-vivendi-theme-fringe (subtlebg intensebg) - "Conditional use of background colours for fringes. -SUBTLEBG should be a subtle greyscale value. INTENSEBG must be a -more pronounced greyscale colour." - (pcase modus-vivendi-theme-fringes - ('intense (list :background intensebg)) - ('subtle (list :background subtlebg)) - (_ (list :background nil)))) - -(defun modus-vivendi-theme-prompt (mainfg subtlebg subtlefg intensebg intensefg) - "Conditional use of background colours for prompts. -MAINFG is the prompt's standard foreground. SUBTLEBG should be a -subtle accented background that works with SUBTLEFG. INTENSEBG -must be a more pronounced accented colour that should be -combinable with INTENSEFG." - (pcase modus-vivendi-theme-prompts - ('intense (list :background intensebg :foreground intensefg)) - ('subtle (list :background subtlebg :foreground subtlefg)) - (_ (list :background nil :foreground mainfg)))) - -(defun modus-vivendi-theme-paren (normalbg intensebg) - "Conditional use of intense colours for matching parentheses. -NORMALBG should the special palette colour 'bg-paren-match' or -something similar. INTENSEBG must be easier to discern next to -other backgrounds, such as the special palette colour -'bg-paren-match-intense'." - (if modus-vivendi-theme-intense-paren-match - (list :background intensebg) - (list :background normalbg))) - -(defun modus-vivendi-theme-syntax-foreground (normal faint) - "Apply foreground value to code syntax. -NORMAL is the more saturated colour, which should be the default. -FAINT is the less saturated colour." - (if modus-vivendi-theme-faint-syntax - (list :foreground faint) - (list :foreground normal))) - -(defun modus-vivendi-theme-heading-p (key) - "Query style of KEY in `modus-vivendi-theme-headings'." - (cdr (assoc key modus-vivendi-theme-headings))) - -(defun modus-vivendi-theme-heading (level fg fg-alt bg border) - "Conditional styles for `modus-vivendi-theme-headings'. - -LEVEL is the heading's position in their order. FG is the -default text colour. FG-ALT is an accented, more saturated value -than the default. BG is a nuanced, typically accented, -background that can work well with either of the foreground -values. BORDER is a colour value that combines well with the -background and alternative foreground." - (let* ((key (modus-vivendi-theme-heading-p `,level)) - (style (or key (modus-vivendi-theme-heading-p t))) - (var (if modus-vivendi-theme-variable-pitch-headings - 'variable-pitch - 'default))) - (pcase style - ('no-bold - (list :inherit `,var :foreground fg)) - ('line - (list :inherit `(bold ,var) :foreground fg :overline border)) - ('line-no-bold - (list :inherit `,var :foreground fg :overline border)) - ('rainbow - (list :inherit `(bold ,var) :foreground fg-alt)) - ('rainbow-no-bold - (list :inherit `,var :foreground fg-alt)) - ('rainbow-line - (list :inherit `(bold ,var) :foreground fg-alt :overline border)) - ('rainbow-line-no-bold - (list :inherit `,var :foreground fg-alt :overline border)) - ('highlight - (list :inherit `(bold ,var) :background bg :foreground fg)) - ('highlight-no-bold - (list :inherit `,var :background bg :foreground fg)) - ('rainbow-highlight - (list :inherit `(bold ,var) :background bg :foreground fg-alt)) - ('rainbow-highlight-no-bold - (list :inherit `,var :background bg :foreground fg-alt)) - ('section - (append - (and (>= emacs-major-version 27) '(:extend t)) - (list :inherit `(bold ,var) :background bg :foreground fg :overline border))) - ('section-no-bold - (append - (and (>= emacs-major-version 27) '(:extend t)) - (list :inherit `,var :background bg :foreground fg :overline border))) - ('rainbow-section - (append - (and (>= emacs-major-version 27) '(:extend t)) - (list :inherit `(bold ,var) :background bg :foreground fg-alt :overline border))) - ('rainbow-section-no-bold - (append - (and (>= emacs-major-version 27) '(:extend t)) - (list :inherit `,var :background bg :foreground fg-alt :overline border))) - (_ - (list :inherit `(bold ,var) :foreground fg))))) - -(defun modus-vivendi-theme-org-block (bgblk) - "Conditionally set the background of Org blocks. -BGBLK applies to a distinct neutral background. Else blocks have -no background of their own (the default), so they look the same -as the rest of the buffer. - -`modus-vivendi-theme-org-blocks' also accepts a `rainbow' option -which is applied conditionally to `org-src-block-faces' (see the -theme's source code)." - (if (eq modus-vivendi-theme-org-blocks 'greyscale) - (append - (and (>= emacs-major-version 27) '(:extend t)) - (list :background bgblk)) - (list :background nil))) - -(defun modus-vivendi-theme-org-block-delim (bgaccent fgaccent bg fg) - "Conditionally set the styles of Org block delimiters. -BG, FG, BGACCENT, FGACCENT apply a background and foreground -colour respectively. - -The former pair is a greyscale combination that should be more -distinct than the background of the block. It is applied to the -default styles or when `modus-vivendi-theme-org-blocks' is set -to `greyscale'. - -The latter pair should be more subtle than the background of the -block, as it is used when `modus-vivendi-theme-org-blocks' is -set to `rainbow'." - (pcase modus-vivendi-theme-org-blocks - ('greyscale (append (and (>= emacs-major-version 27) '(:extend t)) - (list :background bg :foreground fg))) - ('rainbow (list :background bgaccent :foreground fgaccent)) - (_ (list :background bg :foreground fg)))) - -(defun modus-vivendi-theme-mode-line-attrs - (fg bg fg-alt bg-alt border border-3d &optional alt-style border-width fg-distant) - "Colour combinations for `modus-vivendi-theme-mode-line'. - -FG and BG are the default colours. FG-ALT and BG-ALT are meant -to accommodate the options for a 3D modeline or a `moody' -compliant one. BORDER applies to all permutations of the -modeline, except the three-dimensional effect, where BORDER-3D is -used instead. - -Optional ALT-STYLE applies an appropriate style to the mode -line's box property. - -Optional BORDER-WIDTH specifies an integer for the width of the -rectangle that produces the box effect. - -Optional FG-DISTANT should be close to the main background -values. It is intended to be used as a distant-foreground -property." - (pcase modus-vivendi-theme-mode-line - ('3d - `(:background ,bg-alt :foreground ,fg-alt - :box (:line-width ,(or border-width 1) - :color ,border-3d - :style ,(and alt-style 'released-button)))) - ('moody - `(:background ,bg-alt :foreground ,fg-alt :underline ,border :overline ,border - :distant-foreground ,fg-distant)) - (_ - `(:foreground ,fg :background ,bg :box ,border)))) - -(defun modus-vivendi-theme-diff (fg-only-bg fg-only-fg mainbg mainfg altbg altfg) - "Colour combinations for `modus-vivendi-theme-diffs'. - -FG-ONLY-BG should be similar or the same as the main background. -FG-ONLY-FG should be a saturated accent value that can be -combined with the former. - -MAINBG must be one of the dedicated backgrounds for diffs while -MAINFG must be the same for the foreground. - -ALTBG needs to be a slightly accented background that is meant to -be combined with ALTFG. Both must be less intense than MAINBG -and MAINFG respectively." - (pcase modus-vivendi-theme-diffs - ('fg-only (list :background fg-only-bg :foreground fg-only-fg)) - ('desaturated (list :background altbg :foreground altfg)) - (_ (list :background mainbg :foreground mainfg)))) - -(defun modus-vivendi-theme-standard-completions (mainfg subtlebg intensebg intensefg) - "Combinations for `modus-vivendi-theme-completions'. - -MAINFG is an accented foreground value. SUBTLEBG is an accented -background value that can be combined with MAINFG. INTENSEBG and -INTENSEFG are accented colours that are designed to be used in -tandem. - -These are intended for Icomplete, Ido, and related." - (pcase modus-vivendi-theme-completions - ('opinionated (list :background intensebg :foreground intensefg)) - ('moderate (list :background subtlebg :foreground mainfg)) - (_ (list :foreground mainfg)))) - -(defun modus-vivendi-theme-extra-completions (subtleface intenseface altface &optional altfg bold) - "Combinations for `modus-vivendi-theme-completions'. - -SUBTLEFACE and INTENSEFACE are custom theme faces that combine a -background and foreground value. The difference between the two -is a matter of degree. - -ALTFACE is a combination of colours that represents a departure -from the UI's default aesthetics. Optional ALTFG is meant to be -used in tandem with it. - -Optional BOLD will apply a heavier weight to the text. - -These are intended for Helm, Ivy, etc." - (pcase modus-vivendi-theme-completions - ('opinionated (list :inherit (list altface bold) - :foreground (or altfg 'unspecified))) - ('moderate (list :inherit (list subtleface bold))) - (_ (list :inherit (list intenseface bold))))) - -(defun modus-vivendi-theme-scale (amount) - "Scale heading by AMOUNT. - -AMOUNT is a customisation option." - (when modus-vivendi-theme-scale-headings - (list :height amount))) - -;;; Colour palette - -;; Define colour palette. Each colour must have a >= 7:1 contrast -;; ratio relative to the foreground/background colour it is rendered -;; against. -;; -;; The design of the colour palette as a macro that maps it to faces is -;; adapted from zenbern-theme.el, last seen at commit 7dd7968: -;; https://github.com/bbatsov/zenburn-emacs -(eval-and-compile - (defconst modus-vivendi-theme-default-colors-alist - '(;; base values - ("bg-main" . "#000000") ("fg-main" . "#ffffff") - ("bg-alt" . "#181a20") ("fg-alt" . "#a8a8a8") - ("bg-dim" . "#110b11") ("fg-dim" . "#e0e6f0") - ;; specifically for on/off states (e.g. `mode-line') - ;; - ;; must be combined with themselves - ("bg-active" . "#323232") ("fg-active" . "#f4f4f4") - ("bg-inactive" . "#1e1e1e") ("fg-inactive" . "#bfc0c4") - ;; special base values, used only for cases where the above - ;; fg-* or bg-* cannot or should not be used (to avoid confusion) - ;; must be combined with: {fg,bg}-{main,alt,dim} - ("bg-special-cold" . "#203448") ("fg-special-cold" . "#c6eaff") - ("bg-special-mild" . "#00322e") ("fg-special-mild" . "#bfebe0") - ("bg-special-warm" . "#382f27") ("fg-special-warm" . "#f8dec0") - ("bg-special-calm" . "#392a48") ("fg-special-calm" . "#fbd6f4") - ;; styles for the main constructs - ;; - ;; must be combined with: `bg-main', `bg-alt', `bg-dim' - ("red" . "#ff8059") ("green" . "#44bc44") - ("yellow" . "#eecc00") ("blue" . "#2fafff") - ("magenta" . "#feacd0") ("cyan" . "#00d3d0") - ;; styles for common, but still specialised constructs - ;; - ;; must be combined with: `bg-main', `bg-alt', `bg-dim' - ("red-alt" . "#f4923b") ("green-alt" . "#80d200") - ("yellow-alt" . "#cfdf30") ("blue-alt" . "#79a8ff") - ("magenta-alt" . "#f78fe7") ("cyan-alt" . "#4ae8fc") - ;; same purpose as above, just slight differences - ;; - ;; must be combined with: `bg-main', `bg-alt', `bg-dim' - ("red-alt-other" . "#ff9977") ("green-alt-other" . "#00cd68") - ("yellow-alt-other" . "#f0ce43") ("blue-alt-other" . "#00bcff") - ("magenta-alt-other" . "#b6a0ff") ("cyan-alt-other" . "#6ae4b9") - ;; styles for desaturated foreground text, intended for use with - ;; the `modus-vivendi-theme-faint-syntax' option - ;; - ;; must be combined with: `bg-main', `bg-alt', `bg-dim' - ("red-faint" . "#ffa0a0") ("green-faint" . "#88cf88") - ("yellow-faint" . "#d2b580") ("blue-faint" . "#92baff") - ("magenta-faint" . "#e0b2d6") ("cyan-faint" . "#a0bfdf") - - ("red-alt-faint" . "#f5aa80") ("green-alt-faint" . "#a8cf88") - ("yellow-alt-faint" . "#cabf77") ("blue-alt-faint" . "#a4b0ff") - ("magenta-alt-faint" . "#ef9fe4") ("cyan-alt-faint" . "#90c4ed") - - ("red-alt-other-faint" . "#ff9fbf") ("green-alt-other-faint" . "#88cfaf") - ("yellow-alt-other-faint" . "#d0ba95") ("blue-alt-other-faint" . "#8fc5ff") - ("magenta-alt-other-faint" . "#d0b4ff") ("cyan-alt-other-faint" . "#a4d0bb") - ;; styles for elements that should be very subtle, yet accented - ;; - ;; must be combined with: `bg-main', `bg-alt', `bg-dim' or any of - ;; the "nuanced" backgrounds - ("red-nuanced" . "#ffcccc") ("green-nuanced" . "#b8e2b8") - ("yellow-nuanced" . "#dfdfb0") ("blue-nuanced" . "#bfd9ff") - ("magenta-nuanced" . "#e5cfef") ("cyan-nuanced" . "#a8e5e5") - ;; styles for slightly accented background - ;; - ;; must be combined with any of the above foreground values - ("red-nuanced-bg" . "#2c0614") ("green-nuanced-bg" . "#001904") - ("yellow-nuanced-bg" . "#221000") ("blue-nuanced-bg" . "#0f0e39") - ("magenta-nuanced-bg" . "#230631") ("cyan-nuanced-bg" . "#041529") - ;; styles for elements that should draw attention to themselves - ;; - ;; must be combined with: `bg-main' - ("red-intense" . "#fb6859") ("green-intense" . "#00fc50") - ("yellow-intense" . "#ffdd00") ("blue-intense" . "#00a2ff") - ("magenta-intense" . "#ff8bd4") ("cyan-intense" . "#30ffc0") - ;; styles for background elements that should be visible yet - ;; subtle - ;; - ;; must be combined with: `fg-dim' - ("red-subtle-bg" . "#762422") ("green-subtle-bg" . "#2f4a00") - ("yellow-subtle-bg" . "#604200") ("blue-subtle-bg" . "#10387c") - ("magenta-subtle-bg" . "#49366e") ("cyan-subtle-bg" . "#00415e") - ;; styles for background elements that should be visible and - ;; distinguishable - ;; - ;; must be combined with: `fg-main' - ("red-intense-bg" . "#a4202a") ("green-intense-bg" . "#006800") - ("yellow-intense-bg" . "#874900") ("blue-intense-bg" . "#2a40b8") - ("magenta-intense-bg" . "#7042a2") ("cyan-intense-bg" . "#005f88") - ;; styles for refined contexts where both the foreground and the - ;; background need to have the same/similar hue - ;; - ;; must be combined with themselves OR the foregrounds can be - ;; combined with any of the base backgrounds - ("red-refine-bg" . "#77002a") ("red-refine-fg" . "#ffb9ab") - ("green-refine-bg" . "#00422a") ("green-refine-fg" . "#9ff0cf") - ("yellow-refine-bg" . "#693200") ("yellow-refine-fg" . "#e2d980") - ("blue-refine-bg" . "#242679") ("blue-refine-fg" . "#8ec6ff") - ("magenta-refine-bg" . "#71206a") ("magenta-refine-fg" . "#ffcaf0") - ("cyan-refine-bg" . "#004065") ("cyan-refine-fg" . "#8ae4f2") - ;; styles that are meant exclusively for the mode line - ;; - ;; must be combined with: `bg-active', `bg-inactive' - ("red-active" . "#ffa7ba") ("green-active" . "#70d73f") - ("yellow-active" . "#dbbe5f") ("blue-active" . "#34cfff") - ("magenta-active" . "#d5b1ff") ("cyan-active" . "#00d8b4") - ;; styles that are meant exclusively for the fringes - ;; - ;; must be combined with `fg-main' - ("red-fringe-bg" . "#8f1f4b") ("green-fringe-bg" . "#006700") - ("yellow-fringe-bg" . "#6f4f00") ("blue-fringe-bg" . "#3f33af") - ("magenta-fringe-bg" . "#6f2f89") ("cyan-fringe-bg" . "#004f8f") - ;; styles reserved for specific faces - ;; - ;; `bg-hl-line' is between `bg-dim' and `bg-alt', so it should - ;; work with all accents that cover those two, plus `bg-main' - ;; - ;; `bg-hl-alt' and `bg-hl-alt-intense' should only be used when no - ;; other greyscale or fairly neutral background is available to - ;; properly draw attention to a given construct - ;; - ;; `bg-header' is between `bg-active' and `bg-inactive', so it - ;; can be combined with any of the "active" values, plus the - ;; "special" and base foreground colours - ;; - ;; `bg-paren-match', `bg-paren-match-intense', `bg-region' and - ;; `bg-tab-active' must be combined with `fg-main', while - ;; `bg-tab-inactive' should be combined with `fg-dim' - ;; - ;; `bg-tab-bar' is only intended for the bar that holds the tabs and - ;; can only be combined with `fg-main' - ;; - ;; `fg-tab-active' is meant to be combined with `bg-tab-active', - ;; though only for styling special elements, such as underlining - ;; the current tab - ;; - ;; `fg-escape-char-construct' and `fg-escape-char-backslash' can - ;; be combined `bg-main', `bg-dim', `bg-alt' - ;; - ;; `fg-lang-error', `fg-lang-warning', `fg-lang-note' can be - ;; combined with `bg-main', `bg-dim', `bg-alt' - ;; - ;; `fg-mark-sel', `fg-mark-del', `fg-mark-alt' can be combined - ;; with `bg-main', `bg-dim', `bg-alt', `bg-hl-line' - ;; - ;; `fg-unfocused' must be combined with `fg-main' - ;; - ;; the window divider colours apply to faces with just an fg value - ;; - ;; all pairs are combinable with themselves - ("bg-hl-line" . "#151823") - ("bg-hl-line-intense" . "#2f2f2f") - ("bg-hl-alt" . "#181732") - ("bg-hl-alt-intense" . "#282e46") - ("bg-paren-match" . "#5f362f") - ("bg-paren-match-intense" . "#7416b5") - ("bg-region" . "#3c3c3c") - - ("bg-tab-bar" . "#2c2c2c") - ("bg-tab-active" . "#0e0e0e") - ("bg-tab-inactive" . "#3d3d3d") - ("fg-tab-active" . "#5ac3cf") - - ("fg-escape-char-construct" . "#e7a59a") - ("fg-escape-char-backslash" . "#abab00") - - ("fg-lang-error" . "#ef8690") - ("fg-lang-warning" . "#b0aa00") - ("fg-lang-note" . "#9d9def") - - ("fg-window-divider-inner" . "#646464") - ("fg-window-divider-outer" . "#969696") - - ("fg-unfocused" . "#93959b") - - ("bg-header" . "#212121") ("fg-header" . "#dddddd") - - ("bg-whitespace" . "#170016") ("fg-whitespace" . "#a4959f") - - ("bg-diff-heading" . "#304466") ("fg-diff-heading" . "#dadffe") - ("bg-diff-added" . "#0a280a") ("fg-diff-added" . "#94ba94") - ("bg-diff-changed" . "#2a2000") ("fg-diff-changed" . "#b0ba9f") - ("bg-diff-removed" . "#40160f") ("fg-diff-removed" . "#c6adaa") - - ("bg-diff-refine-added" . "#005a36") ("fg-diff-refine-added" . "#e0f6e0") - ("bg-diff-refine-changed" . "#585800") ("fg-diff-refine-changed" . "#ffffcc") - ("bg-diff-refine-removed" . "#852828") ("fg-diff-refine-removed" . "#ffd9eb") - - ("bg-diff-focus-added" . "#203d20") ("fg-diff-focus-added" . "#b4ddb4") - ("bg-diff-focus-changed" . "#4a3a10") ("fg-diff-focus-changed" . "#d0daaf") - ("bg-diff-focus-removed" . "#5e2526") ("fg-diff-focus-removed" . "#eebdba") - - ("bg-diff-neutral-0" . "#575757") ("fg-diff-neutral-0" . "#fcfcfc") - ("bg-diff-neutral-1" . "#454545") ("fg-diff-neutral-1" . "#dddddd") - ("bg-diff-neutral-2" . "#313131") ("fg-diff-neutral-2" . "#bfbfbf") - - ("bg-mark-sel" . "#002f2f") ("fg-mark-sel" . "#60cfa2") - ("bg-mark-del" . "#5a0000") ("fg-mark-del" . "#ff99aa") - ("bg-mark-alt" . "#3f2210") ("fg-mark-alt" . "#f0aa20")) - "The entire palette of `modus-vivendi-theme'. -Each element has the form (NAME . HEX).") - - (defcustom modus-vivendi-theme-override-colors-alist '() - "Association list of palette colour overrides. -Values can be mapped to variables, using the same syntax as the -one present in `modus-vivendi-theme-default-colors-alist'. - -This is only meant for do-it-yourself usage, with the -understanding that the user is responsible for the resulting -contrast ratio between new and existing colours." - :type '(alist - :key-type (string :tag "Name") - :value-type (string :tag " Hex"))) - - (defmacro modus-vivendi-theme-with-color-variables (&rest body) - "`let' bind all colours around BODY. -Also bind `class' to ((class color) (min-colors 89))." - (declare (indent 0)) - `(let ((class '((class color) (min-colors 89))) - ,@(mapcar (lambda (cons) - (list (intern (car cons)) (cdr cons))) - (append modus-vivendi-theme-default-colors-alist - modus-vivendi-theme-override-colors-alist)) - ;; simple conditional styles that evaluate user-facing - ;; customisation options - (modus-theme-slant - (if modus-vivendi-theme-slanted-constructs 'italic 'normal)) - (modus-theme-variable-pitch - (if modus-vivendi-theme-variable-pitch-headings 'variable-pitch 'default))) - ,@body))) - - - -;;; Faces - -(modus-vivendi-theme-with-color-variables - (custom-theme-set-faces - 'modus-vivendi -;;;; custom faces - ;; these bespoke faces are inherited by other constructs below -;;;;; subtle coloured backgrounds - `(modus-theme-subtle-red ((,class :background ,red-subtle-bg :foreground ,fg-dim))) - `(modus-theme-subtle-green ((,class :background ,green-subtle-bg :foreground ,fg-dim))) - `(modus-theme-subtle-yellow ((,class :background ,yellow-subtle-bg :foreground ,fg-dim))) - `(modus-theme-subtle-blue ((,class :background ,blue-subtle-bg :foreground ,fg-dim))) - `(modus-theme-subtle-magenta ((,class :background ,magenta-subtle-bg :foreground ,fg-dim))) - `(modus-theme-subtle-cyan ((,class :background ,cyan-subtle-bg :foreground ,fg-dim))) - `(modus-theme-subtle-neutral ((,class :background ,bg-inactive :foreground ,fg-inactive))) -;;;;; intense coloured backgrounds - `(modus-theme-intense-red ((,class :background ,red-intense-bg :foreground ,fg-main))) - `(modus-theme-intense-green ((,class :background ,green-intense-bg :foreground ,fg-main))) - `(modus-theme-intense-yellow ((,class :background ,yellow-intense-bg :foreground ,fg-main))) - `(modus-theme-intense-blue ((,class :background ,blue-intense-bg :foreground ,fg-main))) - `(modus-theme-intense-magenta ((,class :background ,magenta-intense-bg :foreground ,fg-main))) - `(modus-theme-intense-cyan ((,class :background ,cyan-intense-bg :foreground ,fg-main))) - `(modus-theme-intense-neutral ((,class :background ,bg-active :foreground ,fg-main))) -;;;;; refined background and foreground combinations - ;; general purpose styles that use an accented foreground against an - ;; accented background - `(modus-theme-refine-red ((,class :background ,red-refine-bg :foreground ,red-refine-fg))) - `(modus-theme-refine-green ((,class :background ,green-refine-bg :foreground ,green-refine-fg))) - `(modus-theme-refine-yellow ((,class :background ,yellow-refine-bg :foreground ,yellow-refine-fg))) - `(modus-theme-refine-blue ((,class :background ,blue-refine-bg :foreground ,blue-refine-fg))) - `(modus-theme-refine-magenta ((,class :background ,magenta-refine-bg :foreground ,magenta-refine-fg))) - `(modus-theme-refine-cyan ((,class :background ,cyan-refine-bg :foreground ,cyan-refine-fg))) -;;;;; "active" combinations, mostly for use on the mode line - `(modus-theme-active-red ((,class :background ,red-active :foreground ,bg-active))) - `(modus-theme-active-green ((,class :background ,green-active :foreground ,bg-active))) - `(modus-theme-active-yellow ((,class :background ,yellow-active :foreground ,bg-active))) - `(modus-theme-active-blue ((,class :background ,blue-active :foreground ,bg-active))) - `(modus-theme-active-magenta ((,class :background ,magenta-active :foreground ,bg-active))) - `(modus-theme-active-cyan ((,class :background ,cyan-active :foreground ,bg-active))) -;;;;; nuanced backgrounds - ;; useful for adding an accented background that is suitable for all - ;; main foreground colours (intended for use in Org source blocks) - `(modus-theme-nuanced-red ((,class :background ,red-nuanced-bg - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(modus-theme-nuanced-green ((,class :background ,green-nuanced-bg - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(modus-theme-nuanced-yellow ((,class :background ,yellow-nuanced-bg - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(modus-theme-nuanced-blue ((,class :background ,blue-nuanced-bg - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(modus-theme-nuanced-magenta ((,class :background ,magenta-nuanced-bg - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(modus-theme-nuanced-cyan ((,class :background ,cyan-nuanced-bg - ,@(and (>= emacs-major-version 27) '(:extend t))))) -;;;;; fringe-specific combinations - `(modus-theme-fringe-red ((,class :background ,red-fringe-bg :foreground ,fg-main))) - `(modus-theme-fringe-green ((,class :background ,green-fringe-bg :foreground ,fg-main))) - `(modus-theme-fringe-yellow ((,class :background ,yellow-fringe-bg :foreground ,fg-main))) - `(modus-theme-fringe-blue ((,class :background ,blue-fringe-bg :foreground ,fg-main))) - `(modus-theme-fringe-magenta ((,class :background ,magenta-fringe-bg :foreground ,fg-main))) - `(modus-theme-fringe-cyan ((,class :background ,cyan-fringe-bg :foreground ,fg-main))) -;;;;; special base values - ;; these are closer to the grayscale than the accents defined above - ;; and should only be used when the next closest alternative would be - ;; a greyscale value than an accented one - `(modus-theme-special-cold ((,class :background ,bg-special-cold :foreground ,fg-special-cold))) - `(modus-theme-special-mild ((,class :background ,bg-special-mild :foreground ,fg-special-mild))) - `(modus-theme-special-warm ((,class :background ,bg-special-warm :foreground ,fg-special-warm))) - `(modus-theme-special-calm ((,class :background ,bg-special-calm :foreground ,fg-special-calm))) -;;;;; diff-specific combinations - ;; intended for `diff-mode' or equivalent - `(modus-theme-diff-added - ((,class ,@(modus-vivendi-theme-diff - bg-main green - bg-diff-focus-added fg-diff-focus-added - green-nuanced-bg fg-diff-added)))) - `(modus-theme-diff-changed - ((,class ,@(modus-vivendi-theme-diff - bg-main yellow - bg-diff-focus-changed fg-diff-focus-changed - yellow-nuanced-bg fg-diff-changed)))) - `(modus-theme-diff-removed - ((,class ,@(modus-vivendi-theme-diff - bg-main red - bg-diff-focus-removed fg-diff-focus-removed - red-nuanced-bg fg-diff-removed)))) - `(modus-theme-diff-refine-added - ((,class ,@(modus-vivendi-theme-diff - bg-diff-added fg-diff-added - bg-diff-refine-added fg-diff-refine-added - bg-diff-focus-added fg-diff-focus-added)))) - `(modus-theme-diff-refine-changed - ((,class ,@(modus-vivendi-theme-diff - bg-diff-changed fg-diff-changed - bg-diff-refine-changed fg-diff-refine-changed - bg-diff-focus-changed fg-diff-focus-changed)))) - `(modus-theme-diff-refine-removed - ((,class ,@(modus-vivendi-theme-diff - bg-diff-removed fg-diff-removed - bg-diff-refine-removed fg-diff-refine-removed - bg-diff-focus-removed fg-diff-focus-removed)))) - `(modus-theme-diff-focus-added - ((,class ,@(modus-vivendi-theme-diff - bg-dim green - bg-diff-focus-added fg-diff-focus-added - bg-diff-added fg-diff-added)))) - `(modus-theme-diff-focus-changed - ((,class ,@(modus-vivendi-theme-diff - bg-dim yellow - bg-diff-focus-changed fg-diff-focus-changed - bg-diff-changed fg-diff-changed)))) - `(modus-theme-diff-focus-removed - ((,class ,@(modus-vivendi-theme-diff - bg-dim red - bg-diff-focus-removed fg-diff-focus-removed - bg-diff-removed fg-diff-removed)))) - `(modus-theme-diff-heading - ((,class ,@(modus-vivendi-theme-diff - bg-alt blue-alt - bg-diff-heading fg-diff-heading - blue-nuanced-bg blue)))) -;;;;; mark indicators - ;; colour combinations intended for Dired, Ibuffer, or equivalent - `(modus-theme-pseudo-header ((,class :inherit bold :foreground ,fg-main))) - `(modus-theme-mark-alt ((,class :inherit bold :background ,bg-mark-alt :foreground ,fg-mark-alt))) - `(modus-theme-mark-del ((,class :inherit bold :background ,bg-mark-del :foreground ,fg-mark-del))) - `(modus-theme-mark-sel ((,class :inherit bold :background ,bg-mark-sel :foreground ,fg-mark-sel))) - `(modus-theme-mark-symbol ((,class :inherit bold :foreground ,blue-alt))) -;;;;; heading levels - ;; styles for regular headings used in Org, Markdown, Info, etc. - `(modus-theme-heading-1 - ((,class ,@(modus-vivendi-theme-heading - 1 fg-main magenta-alt-other magenta-nuanced-bg bg-region) - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-4)))) - `(modus-theme-heading-2 - ((,class ,@(modus-vivendi-theme-heading - 2 fg-special-warm magenta-alt red-nuanced-bg bg-region) - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-3)))) - `(modus-theme-heading-3 - ((,class ,@(modus-vivendi-theme-heading - 3 fg-special-cold blue blue-nuanced-bg bg-region) - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-2)))) - `(modus-theme-heading-4 - ((,class ,@(modus-vivendi-theme-heading - 4 fg-special-mild cyan cyan-nuanced-bg bg-region) - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-1)))) - `(modus-theme-heading-5 - ((,class ,@(modus-vivendi-theme-heading - 5 fg-special-calm green-alt-other green-nuanced-bg bg-region)))) - `(modus-theme-heading-6 - ((,class ,@(modus-vivendi-theme-heading - 6 yellow-nuanced yellow-alt-other yellow-nuanced-bg bg-region)))) - `(modus-theme-heading-7 - ((,class ,@(modus-vivendi-theme-heading - 7 red-nuanced red-alt red-nuanced-bg bg-region)))) - `(modus-theme-heading-8 - ((,class ,@(modus-vivendi-theme-heading - 8 fg-dim magenta bg-alt bg-region)))) -;;;;; other custom faces - `(modus-theme-hl-line ((,class :background ,(if modus-vivendi-theme-intense-hl-line - bg-hl-line-intense bg-hl-line) - (and (>= emacs-major-version 27) '(:extend t))))) -;;;; standard faces -;;;;; absolute essentials - `(default ((,class :background ,bg-main :foreground ,fg-main))) - `(cursor ((,class :background ,fg-main))) - `(fringe ((,class ,@(modus-vivendi-theme-fringe bg-inactive bg-active) - :foreground ,fg-main))) - `(vertical-border ((,class :foreground ,fg-window-divider-inner))) -;;;;; basic and/or ungrouped styles - ;; Modify the `bold' face to change the weight of all "bold" elements - ;; defined by the theme. You need a typeface that supports a - ;; multitude of heavier weights than the regular one and then you - ;; must specify the exact name of the one you wish to apply. Example - ;; for your init.el: - ;; - ;; (set-face-attribute 'bold nil :weight 'semibold) - `(bold ((,class :weight bold))) - `(comint-highlight-input ((,class :inherit bold))) - `(comint-highlight-prompt ((,class ,@(modus-vivendi-theme-bold-weight) - ,@(modus-vivendi-theme-prompt - cyan - blue-nuanced-bg blue-alt - blue-refine-bg fg-main)))) - `(error ((,class :inherit bold :foreground ,red))) - `(escape-glyph ((,class :foreground ,fg-escape-char-construct))) - `(file-name-shadow ((,class :foreground ,fg-unfocused))) - `(header-line ((,class :background ,bg-header :foreground ,fg-header))) - `(header-line-highlight ((,class :inherit modus-theme-active-blue))) - `(help-argument-name ((,class :foreground ,cyan :slant ,modus-theme-slant))) - `(homoglyph ((,class :foreground ,fg-escape-char-construct))) - `(ibuffer-locked-buffer ((,class :foreground ,yellow-alt-other))) - `(italic ((,class :slant italic))) - `(nobreak-hyphen ((,class :foreground ,fg-escape-char-construct))) - `(nobreak-space ((,class :foreground ,fg-escape-char-construct :underline t))) - `(minibuffer-prompt ((,class ,@(modus-vivendi-theme-prompt - cyan-alt-other - cyan-nuanced-bg cyan - cyan-refine-bg fg-main)))) - `(mm-command-output ((,class :foreground ,red-alt-other))) - `(mm-uu-extract ((,class :background ,bg-dim :foreground ,fg-special-mild))) - `(next-error ((,class :inherit modus-theme-subtle-red))) - `(rectangle-preview ((,class :inherit modus-theme-special-mild))) - `(region ((,class :background ,bg-region :foreground ,fg-main))) - `(secondary-selection ((,class :inherit modus-theme-special-cold))) - `(shadow ((,class :foreground ,fg-alt))) - `(success ((,class :inherit bold :foreground ,green))) - `(trailing-whitespace ((,class :background ,red-intense-bg))) - `(warning ((,class :inherit bold :foreground ,yellow))) -;;;;; buttons, links, widgets - `(button ((,class :foreground ,blue-alt-other - ,@(unless modus-vivendi-theme-no-link-underline - (list :underline t))))) - `(link ((,class :inherit button))) - `(link-visited ((,class :inherit link :foreground ,magenta-alt-other))) - `(tooltip ((,class :background ,bg-special-cold :foreground ,fg-main))) - `(widget-button ((,class :inherit button))) - `(widget-button-pressed ((,class :inherit button :foreground ,magenta))) - `(widget-documentation ((,class :foreground ,green))) - `(widget-field ((,class :background ,bg-alt :foreground ,fg-dim))) - `(widget-inactive ((,class :background ,bg-inactive :foreground ,fg-inactive))) - `(widget-single-line-field ((,class :inherit widget-field))) -;;;;; ag - `(ag-hit-face ((,class :foreground ,fg-special-cold))) - `(ag-match-face ((,class :inherit modus-theme-special-calm))) -;;;;; alert - `(alert-high-face ((,class :inherit bold :foreground ,red-alt))) - `(alert-low-face ((,class :foreground ,fg-special-mild))) - `(alert-moderate-face ((,class :inherit bold :foreground ,yellow))) - `(alert-trivial-face ((,class :foreground ,fg-special-calm))) - `(alert-urgent-face ((,class :inherit bold :foreground ,red-intense))) -;;;;; all-the-icons - `(all-the-icons-blue ((,class :foreground ,blue))) - `(all-the-icons-blue-alt ((,class :foreground ,blue-alt))) - `(all-the-icons-cyan ((,class :foreground ,cyan))) - `(all-the-icons-cyan-alt ((,class :foreground ,cyan-alt))) - `(all-the-icons-dblue ((,class :foreground ,blue-alt-other))) - `(all-the-icons-dcyan ((,class :foreground ,cyan-alt-other))) - `(all-the-icons-dgreen ((,class :foreground ,green-alt-other))) - `(all-the-icons-dired-dir-face ((,class :foreground ,blue))) - `(all-the-icons-dmaroon ((,class :foreground ,magenta-alt-other))) - `(all-the-icons-dorange ((,class :foreground ,red-alt-other))) - `(all-the-icons-dpink ((,class :foreground ,magenta))) - `(all-the-icons-dpurple ((,class :foreground ,magenta-alt))) - `(all-the-icons-dred ((,class :foreground ,red))) - `(all-the-icons-dsilver ((,class :foreground ,fg-special-cold))) - `(all-the-icons-dyellow ((,class :foreground ,yellow))) - `(all-the-icons-green ((,class :foreground ,green))) - `(all-the-icons-lblue ((,class :foreground ,blue-refine-fg))) - `(all-the-icons-lcyan ((,class :foreground ,cyan-refine-fg))) - `(all-the-icons-lgreen ((,class :foreground ,green-refine-fg))) - `(all-the-icons-lmaroon ((,class :foreground ,magenta-refine-fg))) - `(all-the-icons-lorange ((,class :foreground ,red-refine-fg))) - `(all-the-icons-lpink ((,class :foreground ,magenta-refine-fg))) - `(all-the-icons-lpurple ((,class :foreground ,magenta-refine-fg))) - `(all-the-icons-lred ((,class :foreground ,red-refine-fg))) - `(all-the-icons-lsilver ((,class :foreground ,fg-special-cold))) - `(all-the-icons-lyellow ((,class :foreground ,yellow-refine-fg))) - `(all-the-icons-maroon ((,class :foreground ,magenta))) - `(all-the-icons-orange ((,class :foreground ,red-alt))) - `(all-the-icons-pink ((,class :foreground ,magenta))) - `(all-the-icons-purple ((,class :foreground ,magenta-alt))) - `(all-the-icons-purple-alt ((,class :foreground ,magenta-alt-other))) - `(all-the-icons-red ((,class :foreground ,red))) - `(all-the-icons-red-alt ((,class :foreground ,red-alt))) - `(all-the-icons-silver ((,class :foreground ,fg-special-cold))) - `(all-the-icons-yellow ((,class :foreground ,yellow))) -;;;;; annotate - `(annotate-annotation ((,class :inherit modus-theme-subtle-blue))) - `(annotate-annotation-secondary ((,class :inherit modus-theme-subtle-green))) - `(annotate-highlight ((,class :background ,blue-nuanced-bg :underline ,blue-intense))) - `(annotate-highlight-secondary ((,class :background ,green-nuanced-bg :underline ,green-intense))) -;;;;; anzu - `(anzu-match-1 ((,class :inherit modus-theme-subtle-cyan))) - `(anzu-match-2 ((,class :inherit modus-theme-subtle-green))) - `(anzu-match-3 ((,class :inherit modus-theme-subtle-yellow))) - `(anzu-mode-line ((,class :inherit bold :foreground ,green-active))) - `(anzu-mode-line-no-match ((,class :inherit bold :foreground ,red-active))) - `(anzu-replace-highlight ((,class :inherit modus-theme-refine-yellow :underline t))) - `(anzu-replace-to ((,class :inherit (modus-theme-intense-green bold)))) -;;;;; apropos - `(apropos-function-button ((,class :inherit button :foreground ,magenta-alt-other))) - `(apropos-keybinding ((,class :inherit bold :foreground ,cyan))) - `(apropos-misc-button ((,class :inherit button :foreground ,cyan-alt-other))) - `(apropos-property ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,magenta-alt))) - `(apropos-symbol ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,blue-alt-other))) - `(apropos-user-option-button ((,class :inherit button :foreground ,green-alt-other))) - `(apropos-variable-button ((,class :inherit button :foreground ,blue))) -;;;;; apt-sources-list - `(apt-sources-list-components ((,class :foreground ,cyan))) - `(apt-sources-list-options ((,class :foreground ,yellow))) - `(apt-sources-list-suite ((,class :foreground ,green))) - `(apt-sources-list-type ((,class :foreground ,magenta))) - `(apt-sources-list-uri ((,class :foreground ,blue))) -;;;;; artbollocks-mode - `(artbollocks-face ((,class :foreground ,cyan-nuanced :underline ,fg-lang-note))) - `(artbollocks-lexical-illusions-face ((,class :background ,bg-alt :foreground ,red-alt :underline t))) - `(artbollocks-passive-voice-face ((,class :foreground ,yellow-nuanced :underline ,fg-lang-warning))) - `(artbollocks-weasel-words-face ((,class :foreground ,red-nuanced :underline ,fg-lang-error))) -;;;;; auctex and Tex - `(font-latex-bold-face ((,class :inherit bold :foreground ,fg-special-calm))) - `(font-latex-doctex-documentation-face ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(font-latex-doctex-preprocessor-face ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,red-alt-other))) - `(font-latex-italic-face ((,class :foreground ,fg-special-calm :slant italic))) - `(font-latex-math-face ((,class :foreground ,cyan-alt-other))) - `(font-latex-script-char-face ((,class :foreground ,cyan-alt-other))) - `(font-latex-sectioning-0-face ((,class :inherit ,modus-theme-variable-pitch :foreground ,blue-nuanced))) - `(font-latex-sectioning-1-face ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,blue-nuanced))) - `(font-latex-sectioning-2-face ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,blue-nuanced))) - `(font-latex-sectioning-3-face ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,blue-nuanced))) - `(font-latex-sectioning-4-face ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,blue-nuanced))) - `(font-latex-sectioning-5-face ((,class :inherit ,modus-theme-variable-pitch :foreground ,blue-nuanced))) - `(font-latex-sedate-face ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,magenta-alt-other))) - `(font-latex-slide-title-face ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,cyan-nuanced - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-4)))) - `(font-latex-string-face ((,class :foreground ,blue-alt))) - `(font-latex-subscript-face ((,class :height 0.95))) - `(font-latex-superscript-face ((,class :height 0.95))) - `(font-latex-verbatim-face ((,class :background ,bg-dim :foreground ,fg-special-mild))) - `(font-latex-warning-face ((,class :foreground ,yellow-alt-other))) - `(tex-match ((,class :foreground ,blue-alt-other))) - `(tex-verbatim ((,class :background ,bg-dim :foreground ,fg-special-mild))) - `(texinfo-heading ((,class :foreground ,magenta))) - `(TeX-error-description-error ((,class :inherit bold :foreground ,red))) - `(TeX-error-description-help ((,class :foreground ,blue))) - `(TeX-error-description-tex-said ((,class :foreground ,blue))) - `(TeX-error-description-warning ((,class :inherit bold :foreground ,yellow))) -;;;;; auto-dim-other-buffers - `(auto-dim-other-buffers-face ((,class :background ,bg-alt))) -;;;;; avy - `(avy-background-face ((,class :background ,bg-dim :foreground ,fg-dim))) - `(avy-goto-char-timer-face ((,class :inherit (modus-theme-intense-yellow bold)))) - `(avy-lead-face ((,class :inherit (modus-theme-intense-magenta bold)))) - `(avy-lead-face-0 ((,class :inherit (modus-theme-intense-blue bold)))) - `(avy-lead-face-1 ((,class :inherit (modus-theme-intense-red bold)))) - `(avy-lead-face-2 ((,class :inherit (modus-theme-intense-green bold)))) -;;;;; aw (ace-window) - `(aw-background-face ((,class :background ,bg-dim :foreground ,fg-dim))) - `(aw-key-face ((,class :inherit bold :foreground ,blue-intense))) - `(aw-leading-char-face ((,class :inherit bold :height 1.5 :background ,bg-main :foreground ,red-intense))) - `(aw-minibuffer-leading-char-face ((,class :foreground ,magenta-active))) - `(aw-mode-line-face ((,class :inherit bold))) -;;;;; awesome-tray - `(awesome-tray-module-awesome-tab-face ((,class :inherit bold :foreground ,red-alt-other))) - `(awesome-tray-module-battery-face ((,class :inherit bold :foreground ,cyan-alt-other))) - `(awesome-tray-module-buffer-name-face ((,class :inherit bold :foreground ,yellow-alt-other))) - `(awesome-tray-module-circe-face ((,class :inherit bold :foreground ,blue-alt))) - `(awesome-tray-module-date-face ((,class :inherit bold :foreground ,fg-dim))) - `(awesome-tray-module-evil-face ((,class :inherit bold :foreground ,green-alt))) - `(awesome-tray-module-git-face ((,class :inherit bold :foreground ,magenta))) - `(awesome-tray-module-last-command-face ((,class :inherit bold :foreground ,blue-alt-other))) - `(awesome-tray-module-location-face ((,class :inherit bold :foreground ,yellow))) - `(awesome-tray-module-mode-name-face ((,class :inherit bold :foreground ,green))) - `(awesome-tray-module-parent-dir-face ((,class :inherit bold :foreground ,cyan))) - `(awesome-tray-module-rvm-face ((,class :inherit bold :foreground ,magenta-alt-other))) -;;;;; binder - `(binder-sidebar-highlight ((,class :inherit modus-theme-subtle-cyan))) - `(binder-sidebar-marked ((,class :inherit modus-theme-mark-sel))) - `(binder-sidebar-missing ((,class :inherit modus-theme-subtle-red))) - `(binder-sidebar-tags ((,class :foreground ,cyan))) -;;;;; bm - `(bm-face ((,class :inherit modus-theme-subtle-yellow - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(bm-fringe-face ((,class :inherit modus-theme-fringe-yellow))) - `(bm-fringe-persistent-face ((,class :inherit modus-theme-fringe-blue))) - `(bm-persistent-face ((,class :inherit modus-theme-intense-blue - ,@(and (>= emacs-major-version 27) '(:extend t))))) -;;;;; bongo - `(bongo-album-title ((,class :foreground ,cyan-active))) - `(bongo-artist ((,class :foreground ,magenta-active))) - `(bongo-currently-playing-track ((,class :inherit bold))) - `(bongo-elapsed-track-part ((,class :inherit modus-theme-subtle-magenta :underline t))) - `(bongo-filled-seek-bar ((,class :background ,blue-subtle-bg :foreground ,fg-main))) - `(bongo-marked-track ((,class :foreground ,fg-mark-alt))) - `(bongo-marked-track-line ((,class :background ,bg-mark-alt))) - `(bongo-played-track ((,class :foreground ,fg-unfocused :strike-through t))) - `(bongo-track-length ((,class :foreground ,blue-alt-other))) - `(bongo-track-title ((,class :foreground ,blue-active))) - `(bongo-unfilled-seek-bar ((,class :background ,blue-nuanced-bg :foreground ,fg-main))) -;;;;; boon - `(boon-modeline-cmd ((,class :inherit modus-theme-active-blue))) - `(boon-modeline-ins ((,class :inherit modus-theme-active-red))) - `(boon-modeline-off ((,class :inherit modus-theme-active-yellow))) - `(boon-modeline-spc ((,class :inherit modus-theme-active-green))) -;;;;; breakpoint (built-in gdb-mi.el) - `(breakpoint-disabled ((,class :foreground ,fg-alt))) - `(breakpoint-enabled ((,class :inherit bold :foreground ,red))) -;;;;; buffer-expose - `(buffer-expose-ace-char-face ((,class :inherit bold :foreground ,red-active))) - `(buffer-expose-mode-line-face ((,class :foreground ,cyan-active))) - `(buffer-expose-selected-face ((,class :inherit modus-theme-special-mild))) -;;;;; calendar and diary - `(calendar-month-header ((,class :inherit bold :foreground ,fg-main))) - `(calendar-today ((,class :underline t))) - `(calendar-weekday-header ((,class :foreground ,fg-dim))) - `(calendar-weekend-header ((,class :foreground ,fg-alt))) - `(diary ((,class :foreground ,cyan-alt-other))) - `(diary-anniversary ((,class :foreground ,red-alt-other))) - `(diary-time ((,class :foreground ,blue-alt))) - `(holiday ((,class :foreground ,magenta-alt))) -;;;;; calfw - `(cfw:face-annotation ((,class :foreground ,fg-special-warm))) - `(cfw:face-day-title ((,class :foreground ,fg-main))) - `(cfw:face-default-content ((,class :foreground ,green-alt))) - `(cfw:face-default-day ((,class :inherit (cfw:face-day-title bold)))) - `(cfw:face-disable ((,class :foreground ,fg-unfocused))) - `(cfw:face-grid ((,class :foreground ,fg-window-divider-outer))) - `(cfw:face-header ((,class :inherit bold :foreground ,fg-main))) - `(cfw:face-holiday ((,class :foreground ,magenta-alt-other))) - `(cfw:face-periods ((,class :foreground ,cyan-alt-other))) - `(cfw:face-saturday ((,class :inherit bold :foreground ,cyan-alt-other))) - `(cfw:face-select ((,class :inherit modus-theme-intense-blue))) - `(cfw:face-sunday ((,class :inherit bold :foreground ,cyan-alt-other))) - `(cfw:face-title ((,class :inherit ,modus-theme-variable-pitch - :foreground ,fg-special-cold - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-5)))) - `(cfw:face-today ((,class :background ,bg-inactive))) - `(cfw:face-today-title ((,class :background ,bg-active))) - `(cfw:face-toolbar ((,class :background ,bg-alt :foreground ,bg-alt))) - `(cfw:face-toolbar-button-off ((,class :foreground ,fg-alt))) - `(cfw:face-toolbar-button-on ((,class :inherit bold :background ,blue-nuanced-bg - :foreground ,blue-alt))) -;;;;; centaur-tabs - `(centaur-tabs-active-bar-face ((,class :background ,fg-tab-active))) - `(centaur-tabs-close-mouse-face ((,class :inherit bold :foreground ,red-active :underline t))) - `(centaur-tabs-close-selected ((,class :inherit centaur-tabs-selected))) - `(centaur-tabs-close-unselected ((,class :inherit centaur-tabs-unselected))) - `(centaur-tabs-modified-marker-selected ((,class :inherit centaur-tabs-selected))) - `(centaur-tabs-modified-marker-unselected ((,class :inherit centaur-tabs-unselected))) - `(centaur-tabs-default ((,class :background ,bg-main :foreground ,bg-main))) - `(centaur-tabs-selected ((,class :inherit bold :background ,bg-tab-active :foreground ,fg-main))) - `(centaur-tabs-selected-modified ((,class :background ,bg-tab-active :foreground ,fg-main :slant italic))) - `(centaur-tabs-unselected ((,class :background ,bg-tab-inactive :foreground ,fg-dim))) - `(centaur-tabs-unselected-modified ((,class :background ,bg-tab-inactive :foreground ,fg-dim :slant italic))) -;;;;; change-log and log-view (`vc-print-log' and `vc-print-root-log') - `(change-log-acknowledgment ((,class :foreground ,fg-alt))) - `(change-log-conditionals ((,class :foreground ,magenta-alt))) - `(change-log-date ((,class :foreground ,cyan-alt-other))) - `(change-log-email ((,class :foreground ,cyan))) - `(change-log-file ((,class :foreground ,blue))) - `(change-log-function ((,class :foreground ,green-alt-other))) - `(change-log-list ((,class :foreground ,magenta-alt-other))) - `(change-log-name ((,class :foreground ,cyan))) - `(log-edit-header ((,class :foreground ,fg-special-warm))) - `(log-edit-summary ((,class :inherit bold :foreground ,cyan))) - `(log-edit-unknown-header ((,class :foreground ,fg-alt))) - `(log-view-file ((,class :inherit bold :foreground ,fg-special-cold))) - `(log-view-message ((,class :foreground ,fg-alt))) -;;;;; cider - `(cider-debug-code-overlay-face ((,class :background ,bg-alt))) - `(cider-debug-prompt-face ((,class :foreground ,magenta-alt :underline t))) - `(cider-deprecated-face ((,class :inherit modus-theme-refine-yellow))) - `(cider-docview-emphasis-face ((,class :foreground ,fg-special-cold :slant italic))) - `(cider-docview-literal-face ((,class :foreground ,blue-alt))) - `(cider-docview-strong-face ((,class :inherit bold :foreground ,fg-special-cold))) - `(cider-docview-table-border-face ((,class :foreground ,fg-alt))) - `(cider-enlightened-face ((,class :box (:line-width -1 :color ,yellow-alt :style nil) :background ,bg-dim))) - `(cider-enlightened-local-face ((,class :inherit bold :foreground ,yellow-alt-other))) - `(cider-error-highlight-face ((,class :foreground ,red :underline t))) - `(cider-fragile-button-face ((,class :box (:line-width 3 :color ,fg-alt :style released-button) :foreground ,yellow))) - `(cider-fringe-good-face ((,class :foreground ,green-active))) - `(cider-instrumented-face ((,class :box (:line-width -1 :color ,red :style nil) :background ,bg-dim))) - `(cider-reader-conditional-face ((,class :foreground ,fg-special-warm :slant italic))) - `(cider-repl-input-face ((,class :inherit bold))) - `(cider-repl-prompt-face ((,class :foreground ,cyan-alt-other))) - `(cider-repl-stderr-face ((,class :inherit bold :foreground ,red))) - `(cider-repl-stdout-face ((,class :foreground ,blue))) - `(cider-result-overlay-face ((,class :box (:line-width -1 :color ,blue :style nil) :background ,bg-dim))) - `(cider-stacktrace-error-class-face ((,class :inherit bold :foreground ,red))) - `(cider-stacktrace-error-message-face ((,class :foreground ,red-alt-other :slant italic))) - `(cider-stacktrace-face ((,class :foreground ,fg-main))) - `(cider-stacktrace-filter-active-face ((,class :foreground ,cyan-alt :underline t))) - `(cider-stacktrace-filter-inactive-face ((,class :foreground ,cyan-alt))) - `(cider-stacktrace-fn-face ((,class :inherit bold :foreground ,fg-main))) - `(cider-stacktrace-ns-face ((,class :foreground ,fg-alt :slant italic))) - `(cider-stacktrace-promoted-button-face ((,class :box (:line-width 3 :color ,fg-alt :style released-button) :foreground ,red))) - `(cider-stacktrace-suppressed-button-face ((,class :box (:line-width 3 :color ,fg-alt :style pressed-button) - :background ,bg-alt :foreground ,fg-alt))) - `(cider-test-error-face ((,class :inherit modus-theme-subtle-red))) - `(cider-test-failure-face ((,class :inherit (modus-theme-intense-red bold)))) - `(cider-test-success-face ((,class :inherit modus-theme-intense-green))) - `(cider-traced-face ((,class :box (:line-width -1 :color ,cyan :style nil) :background ,bg-dim))) - `(cider-warning-highlight-face ((,class :foreground ,yellow :underline t))) -;;;;; circe (and lui) - `(circe-fool-face ((,class :foreground ,fg-alt))) - `(circe-highlight-nick-face ((,class :inherit bold :foreground ,blue))) - `(circe-prompt-face ((,class :inherit bold :foreground ,cyan-alt-other))) - `(circe-server-face ((,class :foreground ,fg-unfocused))) - `(lui-button-face ((,class :inherit button :foreground ,blue))) - `(lui-highlight-face ((,class :foreground ,magenta-alt))) - `(lui-time-stamp-face ((,class :foreground ,blue-nuanced))) -;;;;; color-rg - `(color-rg-font-lock-column-number ((,class :foreground ,magenta-alt-other))) - `(color-rg-font-lock-command ((,class :inherit bold :foreground ,fg-main))) - `(color-rg-font-lock-file ((,class :inherit bold :foreground ,fg-special-cold))) - `(color-rg-font-lock-flash ((,class :inherit modus-theme-intense-blue))) - `(color-rg-font-lock-function-location ((,class :inherit modus-theme-special-calm))) - `(color-rg-font-lock-header-line-directory ((,class :foreground ,blue-active))) - `(color-rg-font-lock-header-line-edit-mode ((,class :foreground ,magenta-active))) - `(color-rg-font-lock-header-line-keyword ((,class :foreground ,green-active))) - `(color-rg-font-lock-header-line-text ((,class :foreground ,fg-active))) - `(color-rg-font-lock-line-number ((,class :foreground ,fg-special-warm))) - `(color-rg-font-lock-mark-changed ((,class :inherit bold :foreground ,blue))) - `(color-rg-font-lock-mark-deleted ((,class :inherit bold :foreground ,red))) - `(color-rg-font-lock-match ((,class :inherit modus-theme-special-calm))) - `(color-rg-font-lock-position-splitter ((,class :foreground ,fg-alt))) -;;;;; column-enforce-mode - `(column-enforce-face ((,class :inherit modus-theme-refine-yellow))) -;;;;; company-mode - `(company-echo-common ((,class :foreground ,magenta-alt-other))) - `(company-preview ((,class :background ,bg-dim :foreground ,fg-dim))) - `(company-preview-common ((,class :foreground ,blue-alt))) - `(company-preview-search ((,class :inherit modus-theme-special-calm))) - `(company-scrollbar-bg ((,class :background ,bg-active))) - `(company-scrollbar-fg ((,class :background ,fg-active))) - `(company-template-field ((,class :inherit modus-theme-intense-magenta))) - `(company-tooltip ((,class :background ,bg-alt :foreground ,fg-alt))) - `(company-tooltip-annotation ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(company-tooltip-annotation-selection ((,class :inherit bold :foreground ,fg-main))) - `(company-tooltip-common ((,class :inherit bold :foreground ,blue-alt))) - `(company-tooltip-common-selection ((,class :foreground ,fg-main))) - `(company-tooltip-mouse ((,class :inherit modus-theme-intense-blue))) - `(company-tooltip-search ((,class :inherit (modus-theme-refine-cyan bold)))) - `(company-tooltip-search-selection ((,class :inherit (modus-theme-intense-green bold) :underline t))) - `(company-tooltip-selection ((,class :inherit (modus-theme-subtle-cyan bold)))) -;;;;; company-posframe - `(company-posframe-active-backend-name ((,class :inherit bold :background ,bg-active :foreground ,blue-active))) - `(company-posframe-inactive-backend-name ((,class :background ,bg-active :foreground ,fg-active))) - `(company-posframe-metadata ((,class :background ,bg-inactive :foreground ,fg-inactive))) -;;;;; compilation feedback - `(compilation-column-number ((,class :foreground ,magenta-alt-other))) - `(compilation-error ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,red))) - `(compilation-info ((,class :foreground ,fg-special-cold))) - `(compilation-line-number ((,class :foreground ,fg-special-warm))) - `(compilation-mode-line-exit ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,blue-active))) - `(compilation-mode-line-fail ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,red-active))) - `(compilation-mode-line-run ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,magenta-active))) - `(compilation-warning ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,yellow))) -;;;;; completions - `(completions-annotations ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(completions-common-part ((,class ,@(modus-vivendi-theme-standard-completions - blue-alt blue-nuanced-bg - cyan-refine-bg cyan-refine-fg)))) - `(completions-first-difference ((,class :inherit bold - ,@(modus-vivendi-theme-standard-completions - magenta-alt blue-nuanced-bg - magenta-intense-bg fg-main)))) -;;;;; counsel - `(counsel-active-mode ((,class :foreground ,magenta-alt-other))) - `(counsel-application-name ((,class :foreground ,red-alt-other))) - `(counsel-key-binding ((,class :inherit bold :foreground ,blue-alt-other))) - `(counsel-outline-1 ((,class :inherit outline-1))) - `(counsel-outline-2 ((,class :inherit outline-2))) - `(counsel-outline-3 ((,class :inherit outline-3))) - `(counsel-outline-4 ((,class :inherit outline-4))) - `(counsel-outline-5 ((,class :inherit outline-5))) - `(counsel-outline-6 ((,class :inherit outline-6))) - `(counsel-outline-7 ((,class :inherit outline-7))) - `(counsel-outline-8 ((,class :inherit outline-8))) - `(counsel-outline-default ((,class :inherit bold :foreground ,green-alt-other))) - `(counsel-variable-documentation ((,class :foreground ,yellow-alt-other :slant ,modus-theme-slant))) -;;;;; counsel-css - `(counsel-css-selector-depth-face-1 ((,class :foreground ,blue))) - `(counsel-css-selector-depth-face-2 ((,class :foreground ,cyan))) - `(counsel-css-selector-depth-face-3 ((,class :foreground ,green))) - `(counsel-css-selector-depth-face-4 ((,class :foreground ,yellow))) - `(counsel-css-selector-depth-face-5 ((,class :foreground ,magenta))) - `(counsel-css-selector-depth-face-6 ((,class :foreground ,red))) -;;;;; counsel-notmuch - `(counsel-notmuch-count-face ((,class :foreground ,cyan))) - `(counsel-notmuch-date-face ((,class :foreground ,blue))) - `(counsel-notmuch-people-face ((,class :foreground ,magenta))) - `(counsel-notmuch-subject-face ((,class :foreground ,magenta-alt-other))) -;;;;; counsel-org-capture-string - `(counsel-org-capture-string-template-body-face ((,class :foreground ,fg-special-cold))) -;;;;; cov - `(cov-coverage-not-run-face ((,class :foreground ,red-intense))) - `(cov-coverage-run-face ((,class :foreground ,green-intense))) - `(cov-heavy-face ((,class :foreground ,magenta-intense))) - `(cov-light-face ((,class :foreground ,blue-intense))) - `(cov-med-face ((,class :foreground ,yellow-intense))) - `(cov-none-face ((,class :foreground ,cyan-intense))) -;;;;; cperl-mode - `(cperl-nonoverridable-face ((,class :foreground ,yellow-alt-other))) - `(cperl-array-face ((,class :inherit bold :background ,bg-alt :foreground ,magenta-alt))) - `(cperl-hash-face ((,class :inherit bold :background ,bg-alt :foreground ,red-alt :slant ,modus-theme-slant))) -;;;;; csv-mode - `(csv-separator-face ((,class :background ,bg-special-cold :foreground ,fg-main))) -;;;;; ctrlf - `(ctrlf-highlight-active ((,class :inherit (modus-theme-intense-green bold)))) - `(ctrlf-highlight-line ((,class :inherit modus-theme-hl-line))) - `(ctrlf-highlight-passive ((,class :inherit modus-theme-refine-cyan))) -;;;;; custom (M-x customize) - `(custom-button ((,class :box (:line-width 2 :color nil :style released-button) - :background ,bg-active :foreground ,fg-main))) - `(custom-button-mouse ((,class :box (:line-width 2 :color nil :style released-button) - :background ,bg-active :foreground ,fg-active))) - `(custom-button-pressed ((,class :box (:line-width 2 :color nil :style pressed-button) - :background ,bg-active :foreground ,fg-main))) - `(custom-changed ((,class :inherit modus-theme-subtle-cyan))) - `(custom-comment ((,class :foreground ,fg-alt))) - `(custom-comment-tag ((,class :background ,bg-alt :foreground ,yellow-alt-other))) - `(custom-face-tag ((,class :inherit bold :foreground ,blue-intense))) - `(custom-group-tag ((,class :inherit bold :foreground ,green-intense))) - `(custom-group-tag-1 ((,class :inherit modus-theme-special-warm))) - `(custom-invalid ((,class :inherit (modus-theme-intense-red bold)))) - `(custom-modified ((,class :inherit modus-theme-subtle-cyan))) - `(custom-rogue ((,class :inherit modus-theme-refine-magenta))) - `(custom-set ((,class :foreground ,blue-alt))) - `(custom-state ((,class :foreground ,cyan-alt-other))) - `(custom-themed ((,class :inherit modus-theme-subtle-blue))) - `(custom-variable-tag ((,class :inherit bold :foreground ,cyan))) -;;;;; dap-mode - `(dap-mouse-eval-thing-face ((,class :box (:line-width -1 :color ,blue-active :style nil) - :background ,bg-active :foreground ,fg-main))) - `(dap-result-overlay-face ((,class :box (:line-width -1 :color ,bg-active :style nil) - :background ,bg-active :foreground ,fg-main))) - `(dap-ui-breakpoint-verified-fringe ((,class :inherit bold :foreground ,green-active))) - `(dap-ui-compile-errline ((,class :inherit bold :foreground ,red-intense))) - `(dap-ui-locals-scope-face ((,class :inherit bold :foreground ,magenta :underline t))) - `(dap-ui-locals-variable-face ((,class :inherit bold :foreground ,cyan))) - `(dap-ui-locals-variable-leaf-face ((,class :foreground ,cyan-alt-other :slant italic))) - `(dap-ui-marker-face ((,class :inherit modus-theme-subtle-blue))) - `(dap-ui-sessions-stack-frame-face ((,class :inherit bold :foreground ,magenta-alt))) - `(dap-ui-sessions-terminated-active-face ((,class :inherit bold :foreground ,fg-alt))) - `(dap-ui-sessions-terminated-face ((,class :foreground ,fg-alt))) -;;;;; dashboard (emacs-dashboard) - `(dashboard-banner-logo-title ((,class :inherit bold :foreground ,fg-special-cold))) - `(dashboard-footer ((,class :inherit bold :foreground ,fg-special-mild))) - `(dashboard-heading ((,class :inherit bold :foreground ,fg-special-warm))) - `(dashboard-navigator ((,class :foreground ,cyan-alt-other))) - `(dashboard-text-banner ((,class :foreground ,fg-dim))) -;;;;; deadgrep - `(deadgrep-filename-face ((,class :inherit bold :foreground ,fg-special-cold))) - `(deadgrep-match-face ((,class :inherit modus-theme-special-calm))) - `(deadgrep-meta-face ((,class :foreground ,fg-alt))) - `(deadgrep-regexp-metachar-face ((,class :inherit bold :foreground ,yellow-intense))) - `(deadgrep-search-term-face ((,class :inherit bold :foreground ,green-intense))) -;;;;; debbugs - `(debbugs-gnu-archived ((,class :inverse-video t))) - `(debbugs-gnu-done ((,class :foreground ,fg-alt))) - `(debbugs-gnu-forwarded ((,class :foreground ,fg-special-warm))) - `(debbugs-gnu-handled ((,class :foreground ,green))) - `(debbugs-gnu-new ((,class :foreground ,red))) - `(debbugs-gnu-pending ((,class :foreground ,cyan))) - `(debbugs-gnu-stale-1 ((,class :foreground ,yellow-nuanced))) - `(debbugs-gnu-stale-2 ((,class :foreground ,yellow))) - `(debbugs-gnu-stale-3 ((,class :foreground ,yellow-alt))) - `(debbugs-gnu-stale-4 ((,class :foreground ,yellow-alt-other))) - `(debbugs-gnu-stale-5 ((,class :foreground ,red-alt))) - `(debbugs-gnu-tagged ((,class :foreground ,magenta-alt))) -;;;;; define-word - `(define-word-face-1 ((,class :foreground ,yellow))) - `(define-word-face-2 ((,class :foreground ,fg-main))) -;;;;; deft - `(deft-filter-string-error-face ((,class :inherit modus-theme-refine-red))) - `(deft-filter-string-face ((,class :foreground ,green-intense))) - `(deft-header-face ((,class :inherit bold :foreground ,fg-special-warm))) - `(deft-separator-face ((,class :foreground ,fg-alt))) - `(deft-summary-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(deft-time-face ((,class :foreground ,fg-special-cold))) - `(deft-title-face ((,class :inherit bold :foreground ,fg-main))) -;;;;; dictionary - `(dictionary-button-face ((,class :inherit bold :foreground ,fg-special-cold))) - `(dictionary-reference-face ((,class :inherit button :foreground ,blue-alt-other))) - `(dictionary-word-definition-face ((,class :foreground ,fg-main))) - `(dictionary-word-entry-face ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) -;;;;; diff-hl - `(diff-hl-change ((,class :inherit modus-theme-fringe-yellow))) - `(diff-hl-delete ((,class :inherit modus-theme-fringe-red))) - `(diff-hl-dired-change ((,class :inherit diff-hl-change))) - `(diff-hl-dired-delete ((,class :inherit diff-hl-delete))) - `(diff-hl-dired-ignored ((,class :inherit dired-ignored))) - `(diff-hl-dired-insert ((,class :inherit diff-hl-insert))) - `(diff-hl-dired-unknown ((,class :inherit dired-ignored))) - `(diff-hl-insert ((,class :inherit modus-theme-fringe-green))) - `(diff-hl-reverted-hunk-highlight ((,class :inherit (modus-theme-active-magenta bold)))) -;;;;; diff-mode - `(diff-added ((,class :inherit modus-theme-diff-added))) - `(diff-changed ((,class :inherit modus-theme-diff-changed))) - `(diff-context ((,class :foreground ,fg-unfocused))) - `(diff-file-header ((,class :inherit bold :foreground ,blue))) - `(diff-function ((,class :foreground ,fg-special-cold))) - `(diff-header ((,class :foreground ,blue-nuanced))) - `(diff-hunk-header ((,class :inherit modus-theme-diff-heading))) - `(diff-index ((,class :inherit bold :foreground ,blue-alt))) - `(diff-indicator-added ((,class :inherit diff-added))) - `(diff-indicator-changed ((,class :inherit diff-changed))) - `(diff-indicator-removed ((,class :inherit diff-removed))) - `(diff-nonexistent ((,class :inherit (modus-theme-neutral bold)))) - `(diff-refine-added ((,class :inherit modus-theme-diff-refine-added))) - `(diff-refine-changed ((,class :inherit modus-theme-diff-refine-changed))) - `(diff-refine-removed ((,class :inherit modus-theme-diff-refine-removed))) - `(diff-removed ((,class :inherit modus-theme-diff-removed))) -;;;;; dim-autoload - `(dim-autoload-cookie-line ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) -;;;;; dir-treeview - `(dir-treeview-archive-face ((,class :foreground ,fg-special-warm))) - `(dir-treeview-archive-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,yellow))) - `(dir-treeview-audio-face ((,class :foreground ,magenta))) - `(dir-treeview-audio-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,magenta-alt))) - `(dir-treeview-control-face ((,class :foreground ,fg-alt))) - `(dir-treeview-control-mouse-face ((,class :inherit highlight))) - `(dir-treeview-default-icon-face ((,class :inherit bold :family "Font Awesome" :foreground ,fg-alt))) - `(dir-treeview-default-filename-face ((,class :foreground ,fg-main))) - `(dir-treeview-directory-face ((,class :foreground ,blue))) - `(dir-treeview-directory-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,blue-alt))) - `(dir-treeview-executable-face ((,class :foreground ,red-alt))) - `(dir-treeview-executable-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,red-alt-other))) - `(dir-treeview-image-face ((,class :foreground ,green-alt-other))) - `(dir-treeview-image-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,green-alt))) - `(dir-treeview-indent-face ((,class :foreground ,fg-alt))) - `(dir-treeview-label-mouse-face ((,class :inherit highlight))) - `(dir-treeview-start-dir-face ((,class :inherit modus-theme-pseudo-header))) - `(dir-treeview-symlink-face ((,class :inherit button :foreground ,cyan))) - `(dir-treeview-video-face ((,class :foreground ,magenta-alt-other))) - `(dir-treeview-video-icon-face ((,class :inherit dir-treeview-default-icon-face :foreground ,magenta-alt-other))) -;;;;; dired - `(dired-directory ((,class :foreground ,blue))) - `(dired-flagged ((,class :inherit modus-theme-mark-del))) - `(dired-header ((,class :inherit modus-theme-pseudo-header))) - `(dired-ignored ((,class :foreground ,fg-alt))) - `(dired-mark ((,class :inherit modus-theme-mark-symbol))) - `(dired-marked ((,class :inherit modus-theme-mark-sel))) - `(dired-perm-write ((,class :foreground ,fg-special-warm))) - `(dired-symlink ((,class :inherit button :foreground ,cyan-alt))) - `(dired-warning ((,class :inherit bold :foreground ,yellow))) -;;;;; dired-async - `(dired-async-failures ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,red-active))) - `(dired-async-message ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,green-active))) - `(dired-async-mode-message ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,cyan-active))) -;;;;; dired-git - `(dired-git-branch-else ((,class :inherit bold :foreground ,magenta-alt))) - `(dired-git-branch-master ((,class :inherit bold :foreground ,magenta-alt-other))) -;;;;; dired-git-info - `(dgi-commit-message-face ((,class :foreground ,fg-special-mild))) -;;;;; dired-narrow - `(dired-narrow-blink ((,class :inherit (modus-theme-subtle-cyan bold)))) -;;;;; dired-subtree - ;; remove background from dired-subtree, else it breaks - ;; dired-{flagged,marked} and any other face that sets a background - ;; such as hl-line - `(dired-subtree-depth-1-face ((,class :background nil))) - `(dired-subtree-depth-2-face ((,class :background nil))) - `(dired-subtree-depth-3-face ((,class :background nil))) - `(dired-subtree-depth-4-face ((,class :background nil))) - `(dired-subtree-depth-5-face ((,class :background nil))) - `(dired-subtree-depth-6-face ((,class :background nil))) -;;;;; diredfl - `(diredfl-autofile-name ((,class :inherit modus-theme-special-cold))) - `(diredfl-compressed-file-name ((,class :foreground ,fg-special-warm))) - `(diredfl-compressed-file-suffix ((,class :foreground ,red-alt))) - `(diredfl-date-time ((,class :foreground ,cyan-alt-other))) - `(diredfl-deletion ((,class :inherit modus-theme-mark-del))) - `(diredfl-deletion-file-name ((,class :inherit modus-theme-mark-del))) - `(diredfl-dir-heading ((,class :inherit modus-theme-pseudo-header))) - `(diredfl-dir-name ((,class :inherit dired-directory))) - `(diredfl-dir-priv ((,class :foreground ,blue-alt))) - `(diredfl-exec-priv ((,class :foreground ,magenta))) - `(diredfl-executable-tag ((,class :foreground ,magenta-alt))) - `(diredfl-file-name ((,class :foreground ,fg-main))) - `(diredfl-file-suffix ((,class :foreground ,cyan))) - `(diredfl-flag-mark ((,class :inherit modus-theme-mark-sel))) - `(diredfl-flag-mark-line ((,class :inherit modus-theme-mark-sel))) - `(diredfl-ignored-file-name ((,class :foreground ,fg-alt))) - `(diredfl-link-priv ((,class :foreground ,blue-alt-other))) - `(diredfl-no-priv ((,class :foreground ,fg-alt))) - `(diredfl-number ((,class :foreground ,cyan-alt))) - `(diredfl-other-priv ((,class :foreground ,yellow))) - `(diredfl-rare-priv ((,class :foreground ,red-alt))) - `(diredfl-read-priv ((,class :foreground ,fg-main))) - `(diredfl-symlink ((,class :inherit dired-symlink))) - `(diredfl-tagged-autofile-name ((,class :inherit modus-theme-refine-magenta))) - `(diredfl-write-priv ((,class :foreground ,cyan))) -;;;;; disk-usage - `(disk-usage-children ((,class :foreground ,yellow))) - `(disk-usage-inaccessible ((,class :inherit bold :foreground ,red))) - `(disk-usage-percent ((,class :foreground ,green))) - `(disk-usage-size ((,class :foreground ,cyan))) - `(disk-usage-symlink ((,class :inherit button :foreground ,blue))) - `(disk-usage-symlink-directory ((,class :inherit bold :foreground ,blue-alt))) -;;;;; doom-modeline - `(doom-modeline-bar ((,class :inherit modus-theme-active-blue))) - `(doom-modeline-bar-inactive ((,class :background ,fg-inactive :foreground ,bg-main))) - `(doom-modeline-battery-charging ((,class :foreground ,green-active))) - `(doom-modeline-battery-critical ((,class :inherit bold :foreground ,red-active))) - `(doom-modeline-battery-error ((,class :inherit bold :box (:line-width -2) - :foreground ,red-active))) - `(doom-modeline-battery-full ((,class :foreground ,blue-active))) - `(doom-modeline-battery-normal ((,class :foreground ,fg-active))) - `(doom-modeline-battery-warning ((,class :inherit bold :foreground ,yellow-active))) - `(doom-modeline-buffer-file ((,class :inherit bold :foreground ,fg-active))) - `(doom-modeline-buffer-major-mode ((,class :inherit bold :foreground ,cyan-active))) - `(doom-modeline-buffer-minor-mode ((,class :foreground ,fg-inactive))) - `(doom-modeline-buffer-modified ((,class :inherit bold :foreground ,magenta-active))) - `(doom-modeline-buffer-path ((,class :inherit bold :foreground ,fg-active))) - `(doom-modeline-debug ((,class :inherit bold :foreground ,yellow-active))) - `(doom-modeline-debug-visual ((,class :inherit bold :foreground ,red-active))) - `(doom-modeline-evil-emacs-state ((,class :inherit bold :foreground ,magenta-active))) - `(doom-modeline-evil-insert-state ((,class :inherit bold :foreground ,green-active))) - `(doom-modeline-evil-motion-state ((,class :inherit bold :foreground ,fg-inactive))) - `(doom-modeline-evil-normal-state ((,class :inherit bold :foreground ,fg-active))) - `(doom-modeline-evil-operator-state ((,class :inherit bold :foreground ,blue-active))) - `(doom-modeline-evil-replace-state ((,class :inherit bold :foreground ,red-active))) - `(doom-modeline-evil-visual-state ((,class :inherit bold :foreground ,cyan-active))) - `(doom-modeline-highlight ((,class :inherit bold :foreground ,blue-active))) - `(doom-modeline-host ((,class :slant italic))) - `(doom-modeline-info ((,class :foreground ,green-active))) - `(doom-modeline-lsp-error ((,class :inherit bold :foreground ,red-active))) - `(doom-modeline-lsp-success ((,class :inherit bold :foreground ,green-active))) - `(doom-modeline-lsp-warning ((,class :inherit bold :foreground ,yellow-active))) - `(doom-modeline-panel ((,class :inherit modus-theme-active-blue))) - `(doom-modeline-persp-buffer-not-in-persp ((,class :foreground ,yellow-active :slant italic))) - `(doom-modeline-persp-name ((,class :foreground ,fg-active))) - `(doom-modeline-project-dir ((,class :inherit bold :foreground ,blue-active))) - `(doom-modeline-project-parent-dir ((,class :foreground ,blue-active))) - `(doom-modeline-project-root-dir ((,class :foreground ,fg-active))) - `(doom-modeline-unread-number ((,class :foreground ,fg-active :slant italic))) - `(doom-modeline-urgent ((,class :inherit bold :foreground ,red-active))) - `(doom-modeline-warning ((,class :inherit bold :foreground ,yellow-active))) -;;;;; dynamic-ruler - `(dynamic-ruler-negative-face ((,class :inherit modus-theme-intense-neutral))) - `(dynamic-ruler-positive-face ((,class :inherit modus-theme-intense-yellow))) -;;;;; easy-jekyll - `(easy-jekyll-help-face ((,class :background ,bg-dim :foreground ,cyan-alt-other))) -;;;;; easy-kill - `(easy-kill-origin ((,class :inherit modus-theme-subtle-red))) - `(easy-kill-selection ((,class :inherit modus-theme-subtle-yellow))) -;;;;; ebdb - `(ebdb-address-default ((,class :foreground ,fg-main))) - `(ebdb-db-char ((,class :foreground ,fg-special-cold))) - `(ebdb-defunct ((,class :foreground ,fg-alt))) - `(ebdb-field-hidden ((,class :foreground ,magenta))) - `(ebdb-field-url ((,class :foreground ,blue))) - `(ebdb-label ((,class :foreground ,cyan-alt-other))) - `(ebdb-mail-default ((,class :foreground ,fg-main))) - `(ebdb-mail-primary ((,class :foreground ,blue-alt))) - `(ebdb-marked ((,class :background ,cyan-intense-bg))) - `(ebdb-organization-name ((,class :foreground ,fg-special-calm))) - `(ebdb-person-name ((,class :foreground ,magenta-alt-other))) - `(ebdb-phone-default ((,class :foreground ,fg-special-warm))) - `(ebdb-role-defunct ((,class :foreground ,fg-alt))) - `(eieio-custom-slot-tag-face ((,class :foreground ,red-alt))) -;;;;; ediff - ;; NOTE: here we break from the pattern of inheriting from the - ;; modus-theme-diff-* faces. - `(ediff-current-diff-A ((,class ,@(modus-vivendi-theme-diff - bg-dim red - bg-diff-removed fg-diff-removed - red-nuanced-bg red-faint)))) - `(ediff-current-diff-Ancestor ((,class ,@(modus-vivendi-theme-diff - bg-dim fg-special-cold - bg-special-cold fg-special-cold - blue-nuanced-bg blue)))) - `(ediff-current-diff-B ((,class ,@(modus-vivendi-theme-diff - bg-dim green - bg-diff-added fg-diff-added - green-nuanced-bg green-faint)))) - `(ediff-current-diff-C ((,class ,@(modus-vivendi-theme-diff - bg-dim yellow - bg-diff-changed fg-diff-changed - yellow-nuanced-bg yellow-faint)))) - `(ediff-even-diff-A ((,class :background ,bg-diff-neutral-1 :foreground ,fg-diff-neutral-1))) - `(ediff-even-diff-Ancestor ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-1))) - `(ediff-even-diff-B ((,class :background ,bg-diff-neutral-1 :foreground ,fg-diff-neutral-1))) - `(ediff-even-diff-C ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-2))) - `(ediff-fine-diff-A ((,class :background ,bg-diff-focus-removed :foreground ,fg-diff-focus-removed))) - `(ediff-fine-diff-Ancestor ((,class :inherit modus-theme-refine-cyan))) - `(ediff-fine-diff-B ((,class :background ,bg-diff-focus-added :foreground ,fg-diff-focus-added))) - `(ediff-fine-diff-C ((,class :background ,bg-diff-focus-changed :foreground ,fg-diff-focus-changed))) - `(ediff-odd-diff-A ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-2))) - `(ediff-odd-diff-Ancestor ((,class :background ,bg-diff-neutral-0 :foreground ,fg-diff-neutral-0))) - `(ediff-odd-diff-B ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-2))) - `(ediff-odd-diff-C ((,class :background ,bg-diff-neutral-1 :foreground ,fg-diff-neutral-1))) -;;;;; eglot - `(eglot-mode-line ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,magenta-active))) -;;;;; el-search - `(el-search-highlight-in-prompt-face ((,class :inherit bold :foreground ,magenta-alt))) - `(el-search-match ((,class :inherit modus-theme-intense-green))) - `(el-search-other-match ((,class :inherit modus-theme-special-mild))) - `(el-search-occur-match ((,class :inherit modus-theme-special-calm))) -;;;;; eldoc - ;; NOTE: see https://github.com/purcell/package-lint/issues/187 - (list 'eldoc-highlight-function-argument `((,class :inherit bold :foreground ,blue-alt-other))) -;;;;; eldoc-box - `(eldoc-box-body ((,class :background ,bg-alt :foreground ,fg-main))) - `(eldoc-box-border ((,class :background ,fg-alt))) -;;;;; elfeed - `(elfeed-log-date-face ((,class :foreground ,cyan-alt))) - `(elfeed-log-debug-level-face ((,class :foreground ,magenta))) - `(elfeed-log-error-level-face ((,class :foreground ,red))) - `(elfeed-log-info-level-face ((,class :foreground ,green))) - `(elfeed-log-warn-level-face ((,class :foreground ,yellow))) - `(elfeed-search-date-face ((,class :foreground ,blue-nuanced))) - `(elfeed-search-feed-face ((,class :foreground ,cyan))) - `(elfeed-search-filter-face ((,class :inherit bold :foreground ,magenta-active))) - `(elfeed-search-last-update-face ((,class :foreground ,cyan-active))) - `(elfeed-search-tag-face ((,class :foreground ,blue-nuanced))) - `(elfeed-search-title-face ((,class :foreground ,fg-dim))) - `(elfeed-search-unread-count-face ((,class :foreground ,green-active))) - `(elfeed-search-unread-title-face ((,class :inherit bold :foreground ,fg-main))) -;;;;; elfeed-score - `(elfeed-score-date-face ((,class :foreground ,blue))) - `(elfeed-score-debug-level-face ((,class :foreground ,magenta-alt-other))) - `(elfeed-score-error-level-face ((,class :foreground ,red))) - `(elfeed-score-info-level-face ((,class :foreground ,cyan))) - `(elfeed-score-warn-level-face ((,class :foreground ,yellow))) -;;;;; emms - `(emms-playlist-track-face ((,class :foreground ,blue))) - `(emms-playlist-selected-face ((,class :inherit bold :foreground ,magenta))) -;;;;; enhanced-ruby-mode - `(enh-ruby-heredoc-delimiter-face ((,class :foreground ,blue-alt-other))) - `(enh-ruby-op-face ((,class :foreground ,fg-main))) - `(enh-ruby-regexp-delimiter-face ((,class :foreground ,green))) - `(enh-ruby-regexp-face ((,class :foreground ,magenta))) - `(enh-ruby-string-delimiter-face ((,class :foreground ,blue-alt))) - `(erm-syn-errline ((,class :foreground ,red :underline t))) - `(erm-syn-warnline ((,class :foreground ,yellow :underline t))) -;;;;; epa - `(epa-field-body ((,class :foreground ,fg-main))) - `(epa-field-name ((,class :inherit bold :foreground ,fg-dim))) - `(epa-mark ((,class :inherit bold :foreground ,magenta))) - `(epa-string ((,class :foreground ,blue-alt))) - `(epa-validity-disabled ((,class :inherit modus-theme-refine-red))) - `(epa-validity-high ((,class :inherit bold :foreground ,green-alt-other))) - `(epa-validity-low ((,class :foreground ,fg-alt))) - `(epa-validity-medium ((,class :foreground ,green-alt))) -;;;;; equake - `(equake-buffer-face ((,class :background ,bg-main :foreground ,fg-main))) - `(equake-shell-type-eshell ((,class :background ,bg-inactive :foreground ,green-active))) - `(equake-shell-type-rash ((,class :background ,bg-inactive :foreground ,red-active))) - `(equake-shell-type-shell ((,class :background ,bg-inactive :foreground ,cyan-active))) - `(equake-shell-type-term ((,class :background ,bg-inactive :foreground ,yellow-active))) - `(equake-shell-type-vterm ((,class :background ,bg-inactive :foreground ,magenta-active))) - `(equake-tab-active ((,class :background ,fg-alt :foreground ,bg-alt))) - `(equake-tab-inactive ((,class :foreground ,fg-inactive))) -;;;;; erc - `(erc-action-face ((,class :inherit bold :foreground ,cyan))) - `(erc-bold-face ((,class :inherit bold))) - `(erc-button ((,class :inherit button))) - `(erc-command-indicator-face ((,class :inherit bold :foreground ,cyan-alt))) - `(erc-current-nick-face ((,class :foreground ,magenta-alt-other))) - `(erc-dangerous-host-face ((,class :inherit modus-theme-intense-red))) - `(erc-direct-msg-face ((,class :foreground ,magenta))) - `(erc-error-face ((,class :inherit bold :foreground ,red))) - `(erc-fool-face ((,class :foreground ,fg-inactive))) - `(erc-header-line ((,class :background ,bg-header :foreground ,fg-header))) - `(erc-input-face ((,class :foreground ,fg-special-calm))) - `(erc-inverse-face ((,class :inherit erc-default-face :inverse-video t))) - `(erc-keyword-face ((,class :inherit bold :foreground ,magenta-alt))) - `(erc-my-nick-face ((,class :inherit bold :foreground ,magenta))) - `(erc-my-nick-prefix-face ((,class :inherit erc-my-nick-face))) - `(erc-nick-default-face ((,class :inherit bold :foreground ,blue))) - `(erc-nick-msg-face ((,class :inherit bold :foreground ,green))) - `(erc-nick-prefix-face ((,class :inherit erc-nick-default-face))) - `(erc-notice-face ((,class :foreground ,fg-unfocused))) - `(erc-pal-face ((,class :inherit bold :foreground ,red-alt))) - `(erc-prompt-face ((,class :inherit bold :foreground ,cyan-alt-other))) - `(erc-timestamp-face ((,class :foreground ,blue-nuanced))) - `(erc-underline-face ((,class :underline t))) - `(bg:erc-color-face0 ((,class :background "white"))) - `(bg:erc-color-face1 ((,class :background "black"))) - `(bg:erc-color-face10 ((,class :background ,cyan-subtle-bg))) - `(bg:erc-color-face11 ((,class :background ,cyan-intense-bg))) - `(bg:erc-color-face12 ((,class :background ,blue-subtle-bg))) - `(bg:erc-color-face13 ((,class :background ,magenta-subtle-bg))) - `(bg:erc-color-face14 ((,class :background "gray60"))) - `(bg:erc-color-face15 ((,class :background "gray80"))) - `(bg:erc-color-face2 ((,class :background ,blue-intense-bg))) - `(bg:erc-color-face3 ((,class :background ,green-intense-bg))) - `(bg:erc-color-face4 ((,class :background ,red-subtle-bg))) - `(bg:erc-color-face5 ((,class :background ,red-intense-bg))) - `(bg:erc-color-face6 ((,class :background ,magenta-refine-bg))) - `(bg:erc-color-face7 ((,class :background ,yellow-subtle-bg))) - `(bg:erc-color-face8 ((,class :background ,yellow-refine-bg))) - `(bg:erc-color-face9 ((,class :background ,green-subtle-bg))) - `(fg:erc-color-face0 ((,class :foreground "white"))) - `(fg:erc-color-face1 ((,class :foreground "black"))) - `(fg:erc-color-face10 ((,class :foreground ,cyan))) - `(fg:erc-color-face11 ((,class :foreground ,cyan-alt-other))) - `(fg:erc-color-face12 ((,class :foreground ,blue))) - `(fg:erc-color-face13 ((,class :foreground ,magenta-alt))) - `(fg:erc-color-face14 ((,class :foreground "gray60"))) - `(fg:erc-color-face15 ((,class :foreground "gray80"))) - `(fg:erc-color-face2 ((,class :foreground ,blue-alt-other))) - `(fg:erc-color-face3 ((,class :foreground ,green))) - `(fg:erc-color-face4 ((,class :foreground ,red))) - `(fg:erc-color-face5 ((,class :foreground ,red-alt))) - `(fg:erc-color-face6 ((,class :foreground ,magenta-alt-other))) - `(fg:erc-color-face7 ((,class :foreground ,yellow-alt-other))) - `(fg:erc-color-face8 ((,class :foreground ,yellow-alt))) - `(fg:erc-color-face9 ((,class :foreground ,green-alt-other))) -;;;;; eros - `(eros-result-overlay-face ((,class :box (:line-width -1 :color ,blue) - :background ,bg-dim :foreground ,fg-dim))) -;;;;; ert - `(ert-test-result-expected ((,class :inherit modus-theme-intense-green))) - `(ert-test-result-unexpected ((,class :inherit modus-theme-intense-red))) -;;;;; eshell - `(eshell-ls-archive ((,class :inherit bold :foreground ,cyan-alt))) - `(eshell-ls-backup ((,class :foreground ,yellow-alt))) - `(eshell-ls-clutter ((,class :foreground ,red-alt))) - `(eshell-ls-directory ((,class :inherit bold :foreground ,blue-alt))) - `(eshell-ls-executable ((,class :foreground ,magenta-alt))) - `(eshell-ls-missing ((,class :inherit modus-theme-intense-red))) - `(eshell-ls-product ((,class :foreground ,fg-special-warm))) - `(eshell-ls-readonly ((,class :foreground ,fg-special-cold))) - `(eshell-ls-special ((,class :inherit bold :foreground ,magenta))) - `(eshell-ls-symlink ((,class :inherit button :foreground ,cyan))) - `(eshell-ls-unreadable ((,class :background ,bg-inactive :foreground ,fg-inactive))) - `(eshell-prompt ((,class ,@(modus-vivendi-theme-bold-weight) - ,@(modus-vivendi-theme-prompt - green-alt-other - green-nuanced-bg green-alt - green-refine-bg fg-main)))) -;;;;; eshell-fringe-status - `(eshell-fringe-status-failure ((,class :foreground ,red))) - `(eshell-fringe-status-success ((,class :foreground ,green))) -;;;;; eshell-git-prompt - `(eshell-git-prompt-add-face ((,class :foreground ,fg-alt))) - `(eshell-git-prompt-branch-face ((,class :foreground ,fg-alt))) - `(eshell-git-prompt-directory-face ((,class :foreground ,cyan))) - `(eshell-git-prompt-exit-fail-face ((,class :foreground ,red))) - `(eshell-git-prompt-exit-success-face ((,class :foreground ,green))) - `(eshell-git-prompt-modified-face ((,class :foreground ,yellow))) - `(eshell-git-prompt-powerline-clean-face ((,class :background ,green-refine-bg))) - `(eshell-git-prompt-powerline-dir-face ((,class :background ,blue-refine-bg))) - `(eshell-git-prompt-powerline-not-clean-face ((,class :background ,magenta-refine-bg))) - `(eshell-git-prompt-robyrussell-branch-face ((,class :foreground ,red))) - `(eshell-git-prompt-robyrussell-git-dirty-face ((,class :foreground ,yellow))) - `(eshell-git-prompt-robyrussell-git-face ((,class :foreground ,blue))) -;;;;; eshell-prompt-extras (epe) - `(epe-dir-face ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,blue))) - `(epe-git-dir-face ((,class :foreground ,red-alt-other))) - `(epe-git-face ((,class :foreground ,cyan-alt))) - `(epe-pipeline-delimiter-face ((,class :foreground ,green-alt))) - `(epe-pipeline-host-face ((,class :foreground ,blue))) - `(epe-pipeline-time-face ((,class :foreground ,fg-special-warm))) - `(epe-pipeline-user-face ((,class :foreground ,magenta))) - `(epe-remote-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(epe-status-face ((,class :foreground ,magenta-alt-other))) - `(epe-venv-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) -;;;;; eshell-syntax-highlighting - `(eshell-syntax-highlighting-alias-face ((,class :foreground ,cyan))) - `(eshell-syntax-highlighting-comment-face ((,class :foreground ,fg-alt))) - `(eshell-syntax-highlighting-directory-face ((,class :foreground ,blue))) - `(eshell-syntax-highlighting-envvar-face ((,class :foreground ,magenta-alt))) - `(eshell-syntax-highlighting-invalid-face ((,class :foreground ,red))) - `(eshell-syntax-highlighting-lisp-function-face ((,class :foreground ,magenta))) - `(eshell-syntax-highlighting-shell-command-face ((,class :foreground ,cyan-alt-other))) - `(eshell-syntax-highlighting-string-face ((,class :foreground ,blue-alt))) -;;;;; evil-mode - `(evil-ex-commands ((,class :foreground ,magenta-alt-other))) - `(evil-ex-info ((,class :foreground ,cyan-alt-other))) - `(evil-ex-lazy-highlight ((,class :inherit modus-theme-refine-cyan))) - `(evil-ex-search ((,class :inherit modus-theme-intense-green))) - `(evil-ex-substitute-matches ((,class :inherit modus-theme-refine-yellow :underline t))) - `(evil-ex-substitute-replacement ((,class :inherit (modus-theme-intense-green bold)))) -;;;;; evil-goggles - `(evil-goggles-change-face ((,class :inherit modus-theme-refine-yellow))) - `(evil-goggles-commentary-face ((,class :inherit modus-theme-subtle-neutral :slant ,modus-theme-slant))) - `(evil-goggles-default-face ((,class :inherit modus-theme-subtle-neutral))) - `(evil-goggles-delete-face ((,class :inherit modus-theme-refine-red))) - `(evil-goggles-fill-and-move-face ((,class :inherit evil-goggles-default-face))) - `(evil-goggles-indent-face ((,class :inherit evil-goggles-default-face))) - `(evil-goggles-join-face ((,class :inherit modus-theme-subtle-green))) - `(evil-goggles-nerd-commenter-face ((,class :inherit evil-goggles-commentary-face))) - `(evil-goggles-paste-face ((,class :inherit modus-theme-subtle-cyan))) - `(evil-goggles-record-macro-face ((,class :inherit modus-theme-special-cold))) - `(evil-goggles-replace-with-register-face ((,class :inherit modus-theme-refine-magenta))) - `(evil-goggles-set-marker-face ((,class :inherit modus-theme-intense-magenta))) - `(evil-goggles-shift-face ((,class :inherit evil-goggles-default-face))) - `(evil-goggles-surround-face ((,class :inherit evil-goggles-default-face))) - `(evil-goggles-yank-face ((,class :inherit modus-theme-subtle-blue))) -;;;;; evil-visual-mark-mode - `(evil-visual-mark-face ((,class :inherit modus-theme-intense-magenta))) -;;;;; eww - `(eww-invalid-certificate ((,class :foreground ,red-active))) - `(eww-valid-certificate ((,class :foreground ,green-active))) - `(eww-form-checkbox ((,class :box (:line-width 1 :color ,fg-inactive :style released-button) :background ,bg-inactive :foreground ,fg-main))) - `(eww-form-file ((,class :box (:line-width 1 :color ,fg-inactive :style released-button) :background ,bg-active :foreground ,fg-main))) - `(eww-form-select ((,class :inherit eww-form-checkbox))) - `(eww-form-submit ((,class :inherit eww-form-file))) - `(eww-form-text ((,class :box (:line-width 1 :color ,fg-inactive :style none) :background ,bg-active :foreground ,fg-active))) - `(eww-form-textarea ((,class :background ,bg-alt :foreground ,fg-main))) -;;;;; eyebrowse - `(eyebrowse-mode-line-active ((,class :inherit bold :foreground ,blue-active))) -;;;;; fancy-dabbrev - `(fancy-dabbrev-menu-face ((,class :background ,bg-alt :foreground ,fg-alt))) - `(fancy-dabbrev-preview-face ((,class :foreground ,fg-alt :underline t))) - `(fancy-dabbrev-selection-face ((,class :inherit (modus-theme-intense-cyan bold)))) -;;;;; flycheck - `(flycheck-error - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-error :style wave)) - (,class :foreground ,fg-lang-error :underline t))) - `(flycheck-error-list-checker-name ((,class :foreground ,magenta-active))) - `(flycheck-error-list-column-number ((,class :foreground ,fg-special-cold))) - `(flycheck-error-list-error ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,red))) - `(flycheck-error-list-filename ((,class :foreground ,blue))) - `(flycheck-error-list-highlight ((,class :inherit modus-theme-hl-line))) - `(flycheck-error-list-id ((,class :foreground ,magenta-alt-other))) - `(flycheck-error-list-id-with-explainer ((,class :inherit flycheck-error-list-id :box t))) - `(flycheck-error-list-info ((,class :foreground ,cyan))) - `(flycheck-error-list-line-number ((,class :foreground ,fg-special-warm))) - `(flycheck-error-list-warning ((,class :foreground ,yellow))) - `(flycheck-fringe-error ((,class :inherit modus-theme-fringe-red))) - `(flycheck-fringe-info ((,class :inherit modus-theme-fringe-cyan))) - `(flycheck-fringe-warning ((,class :inherit modus-theme-fringe-yellow))) - `(flycheck-info - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-note :style wave)) - (,class :foreground ,fg-lang-note :underline t))) - `(flycheck-verify-select-checker ((,class :box (:line-width 1 :color nil :style released-button)))) - `(flycheck-warning - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-warning :style wave)) - (,class :foreground ,fg-lang-warning :underline t))) -;;;;; flycheck-color-mode-line - `(flycheck-color-mode-line-error-face ((,class :inherit flycheck-fringe-error))) - `(flycheck-color-mode-line-info-face ((,class :inherit flycheck-fringe-info))) - `(flycheck-color-mode-line-running-face ((,class :foreground ,fg-inactive :slant italic))) - `(flycheck-color-mode-line-info-face ((,class :inherit flycheck-fringe-warning))) -;;;;; flycheck-indicator - `(flycheck-indicator-disabled ((,class :foreground ,fg-inactive :slant ,modus-theme-slant))) - `(flycheck-indicator-error ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,red-active))) - `(flycheck-indicator-info ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,blue-active))) - `(flycheck-indicator-running ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,magenta-active))) - `(flycheck-indicator-success ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,green-active))) - `(flycheck-indicator-warning ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,yellow-active))) -;;;;; flycheck-posframe - `(flycheck-posframe-background-face ((,class :background ,bg-alt))) - `(flycheck-posframe-border-face ((,class :foreground ,fg-alt))) - `(flycheck-posframe-error-face ((,class :inherit bold :foreground ,red))) - `(flycheck-posframe-face ((,class :foreground ,fg-main :slant ,modus-theme-slant))) - `(flycheck-posframe-info-face ((,class :inherit bold :foreground ,cyan))) - `(flycheck-posframe-warning-face ((,class :inherit bold :foreground ,yellow))) -;;;;; flymake - `(flymake-error - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-error :style wave)) - (,class :foreground ,fg-lang-error :underline t))) - `(flymake-note - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-note :style wave)) - (,class :foreground ,fg-lang-note :underline t))) - `(flymake-warning - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-warning :style wave)) - (,class :foreground ,fg-lang-warning :underline t))) -;;;;; flyspell - `(flyspell-duplicate - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-warning :style wave)) - (,class :foreground ,fg-lang-warning :underline t))) - `(flyspell-incorrect - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-error :style wave)) - (,class :foreground ,fg-lang-error :underline t))) -;;;;; flyspell-correct - `(flyspell-correct-highlight-face ((,class :inherit modus-theme-refine-green))) -;;;;; flx - `(flx-highlight-face ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-magenta - 'modus-theme-intense-magenta - 'modus-theme-nuanced-magenta - magenta-alt - 'bold)))) -;;;;; freeze-it - `(freeze-it-show ((,class :background ,bg-dim :foreground ,fg-special-warm))) -;;;;; frog-menu - `(frog-menu-action-keybinding-face ((,class :foreground ,blue-alt-other))) - `(frog-menu-actions-face ((,class :foreground ,magenta))) - `(frog-menu-border ((,class :background ,bg-active))) - `(frog-menu-candidates-face ((,class :foreground ,fg-main))) - `(frog-menu-posframe-background-face ((,class :background ,bg-dim))) - `(frog-menu-prompt-face ((,class :foreground ,cyan))) -;;;;; focus - `(focus-unfocused ((,class :foreground ,fg-unfocused))) -;;;;; fold-this - `(fold-this-overlay ((,class :inherit modus-theme-special-mild))) -;;;;; font-lock - `(font-lock-builtin-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(font-lock-comment-delimiter-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(font-lock-comment-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(font-lock-constant-face ((,class ,@(modus-vivendi-theme-syntax-foreground - blue-alt-other blue-alt-other-faint)))) - `(font-lock-doc-face ((,class ,@(modus-vivendi-theme-syntax-foreground - fg-special-cold cyan-alt-other-faint) - :slant ,modus-theme-slant))) - `(font-lock-function-name-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta magenta-faint)))) - `(font-lock-keyword-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt-other magenta-alt-other-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(font-lock-negation-char-face ((,class ,@(modus-vivendi-theme-syntax-foreground - yellow yellow-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(font-lock-preprocessor-face ((,class ,@(modus-vivendi-theme-syntax-foreground - red-alt-other red-alt-other-faint)))) - `(font-lock-regexp-grouping-backslash ((,class :inherit bold :foreground ,fg-escape-char-backslash))) - `(font-lock-regexp-grouping-construct ((,class :inherit bold :foreground ,fg-escape-char-construct))) - `(font-lock-string-face ((,class ,@(modus-vivendi-theme-syntax-foreground - blue-alt blue-alt-faint)))) - `(font-lock-type-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt magenta-alt-faint)))) - `(font-lock-variable-name-face ((,class ,@(modus-vivendi-theme-syntax-foreground - cyan cyan-faint)))) - `(font-lock-warning-face ((,class ,@(modus-vivendi-theme-syntax-foreground - yellow-active yellow-alt-faint) - ,@(modus-vivendi-theme-bold-weight)))) -;;;;; forge - `(forge-post-author ((,class :inherit bold :foreground ,fg-main))) - `(forge-post-date ((,class :foreground ,fg-special-cold))) - `(forge-topic-closed ((,class :foreground ,fg-alt))) - `(forge-topic-merged ((,class :foreground ,fg-alt))) - `(forge-topic-open ((,class :foreground ,fg-special-mild))) - `(forge-topic-unmerged ((,class :foreground ,magenta :slant ,modus-theme-slant))) - `(forge-topic-unread ((,class :inherit bold :foreground ,fg-main))) -;;;;; fountain-mode - `(fountain-character ((,class :foreground ,blue-alt-other))) - `(fountain-comment ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(fountain-dialog ((,class :foreground ,blue-alt))) - `(fountain-metadata-key ((,class :foreground ,green-alt-other))) - `(fountain-metadata-value ((,class :foreground ,blue))) - `(fountain-non-printing ((,class :foreground ,fg-alt))) - `(fountain-note ((,class :foreground ,yellow :slant ,modus-theme-slant))) - `(fountain-page-break ((,class :inherit bold :foreground ,red-alt))) - `(fountain-page-number ((,class :inherit bold :foreground ,red-alt-other))) - `(fountain-paren ((,class :foreground ,cyan))) - `(fountain-scene-heading ((,class :inherit bold :foreground ,blue-nuanced))) - `(fountain-section-heading ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,fg-main - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-4)))) - `(fountain-section-heading-1 ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,fg-main - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-4)))) - `(fountain-section-heading-2 ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,fg-special-warm - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-3)))) - `(fountain-section-heading-3 ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,fg-special-mild - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-2)))) - `(fountain-section-heading-4 ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,fg-special-calm - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-1)))) - `(fountain-section-heading-5 ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,fg-special-calm))) - `(fountain-synopsis ((,class :foreground ,cyan-alt))) - `(fountain-trans ((,class :foreground ,yellow-alt-other))) -;;;;; geiser - `(geiser-font-lock-autodoc-current-arg ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta magenta-faint)))) - `(geiser-font-lock-autodoc-identifier ((,class ,@(modus-vivendi-theme-syntax-foreground - blue blue-faint)))) - `(geiser-font-lock-doc-button ((,class ,@(modus-vivendi-theme-syntax-foreground - cyan-alt cyan-alt-faint) - :underline t))) - `(geiser-font-lock-doc-link ((,class :inherit link))) - `(geiser-font-lock-error-link ((,class ,@(modus-vivendi-theme-syntax-foreground - red-alt red-alt-faint) - :underline t))) - `(geiser-font-lock-image-button ((,class ,@(modus-vivendi-theme-syntax-foreground - green-alt green-alt-faint) - :underline t))) - `(geiser-font-lock-repl-input ((,class :inherit bold))) - `(geiser-font-lock-repl-output ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt-other magenta-alt-other-faint)))) - `(geiser-font-lock-repl-prompt ((,class ,@(modus-vivendi-theme-syntax-foreground - cyan-alt-other cyan-alt-other-faint)))) - `(geiser-font-lock-xref-header ((,class :inherit bold))) - `(geiser-font-lock-xref-link ((,class :inherit link))) -;;;;; git-commit - `(git-commit-comment-action ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(git-commit-comment-branch-local ((,class :foreground ,blue-alt :slant ,modus-theme-slant))) - `(git-commit-comment-branch-remote ((,class :foreground ,magenta-alt :slant ,modus-theme-slant))) - `(git-commit-comment-detached ((,class :foreground ,cyan-alt :slant ,modus-theme-slant))) - `(git-commit-comment-file ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(git-commit-comment-heading ((,class :inherit bold :foreground ,fg-dim :slant ,modus-theme-slant))) - `(git-commit-keyword ((,class :foreground ,magenta))) - `(git-commit-known-pseudo-header ((,class :foreground ,cyan-alt-other))) - `(git-commit-nonempty-second-line ((,class :inherit modus-theme-refine-yellow))) - `(git-commit-overlong-summary ((,class :inherit modus-theme-refine-yellow))) - `(git-commit-pseudo-header ((,class :foreground ,blue))) - `(git-commit-summary ((,class :inherit bold :foreground ,cyan))) -;;;;; git-gutter - `(git-gutter:added ((,class :inherit modus-theme-fringe-green))) - `(git-gutter:deleted ((,class :inherit modus-theme-fringe-red))) - `(git-gutter:modified ((,class :inherit modus-theme-fringe-yellow))) - `(git-gutter:separator ((,class :inherit modus-theme-fringe-cyan))) - `(git-gutter:unchanged ((,class :inherit modus-theme-fringe-magenta))) -;;;;; git-gutter-fr - `(git-gutter-fr:added ((,class :inherit modus-theme-fringe-green))) - `(git-gutter-fr:deleted ((,class :inherit modus-theme-fringe-red))) - `(git-gutter-fr:modified ((,class :inherit modus-theme-fringe-yellow))) -;;;;; git-{gutter,fringe}+ - `(git-gutter+-added ((,class :inherit modus-theme-fringe-green))) - `(git-gutter+-deleted ((,class :inherit modus-theme-fringe-red))) - `(git-gutter+-modified ((,class :inherit modus-theme-fringe-yellow))) - `(git-gutter+-separator ((,class :inherit modus-theme-fringe-cyan))) - `(git-gutter+-unchanged ((,class :inherit modus-theme-fringe-magenta))) - `(git-gutter-fr+-added ((,class :inherit modus-theme-fringe-green))) - `(git-gutter-fr+-deleted ((,class :inherit modus-theme-fringe-red))) - `(git-gutter-fr+-modified ((,class :inherit modus-theme-fringe-yellow))) -;;;;; git-lens - `(git-lens-added ((,class :inherit bold :foreground ,green))) - `(git-lens-deleted ((,class :inherit bold :foreground ,red))) - `(git-lens-header ((,class :inherit bold :height 1.1 :foreground ,cyan))) - `(git-lens-modified ((,class :inherit bold :foreground ,yellow))) - `(git-lens-renamed ((,class :inherit bold :foreground ,magenta))) -;;;;; git-rebase - `(git-rebase-comment-hash ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(git-rebase-comment-heading ((,class :inherit bold :foreground ,fg-dim :slant ,modus-theme-slant))) - `(git-rebase-description ((,class :foreground ,fg-main))) - `(git-rebase-hash ((,class :foreground ,cyan-alt-other))) -;;;;; git-timemachine - `(git-timemachine-commit ((,class :inherit bold :foreground ,yellow-active))) - `(git-timemachine-minibuffer-author-face ((,class :foreground ,fg-special-warm))) - `(git-timemachine-minibuffer-detail-face ((,class :foreground ,red-alt))) -;;;;; git-walktree - `(git-walktree-commit-face ((,class :foreground ,yellow))) - `(git-walktree-symlink-face ((,class :inherit button :foreground ,cyan))) - `(git-walktree-tree-face ((,class :foreground ,magenta))) -;;;;; gnus - `(gnus-button ((,class :inherit button))) - `(gnus-cite-1 ((,class :foreground ,blue-alt))) - `(gnus-cite-10 ((,class :foreground ,magenta-alt-other))) - `(gnus-cite-11 ((,class :foreground ,yellow-alt-other))) - `(gnus-cite-2 ((,class :foreground ,red-alt))) - `(gnus-cite-3 ((,class :foreground ,green-alt))) - `(gnus-cite-4 ((,class :foreground ,magenta-alt))) - `(gnus-cite-5 ((,class :foreground ,yellow-alt))) - `(gnus-cite-6 ((,class :foreground ,cyan-alt))) - `(gnus-cite-7 ((,class :foreground ,blue-alt-other))) - `(gnus-cite-8 ((,class :foreground ,red-alt-other))) - `(gnus-cite-9 ((,class :foreground ,green-alt-other))) - `(gnus-cite-attribution ((,class :foreground ,fg-main :slant italic))) - `(gnus-emphasis-highlight-words ((,class :inherit modus-theme-refine-yellow))) - `(gnus-group-mail-1 ((,class :inherit bold :foreground ,magenta-alt))) - `(gnus-group-mail-1-empty ((,class :foreground ,magenta-alt))) - `(gnus-group-mail-2 ((,class :inherit bold :foreground ,magenta))) - `(gnus-group-mail-2-empty ((,class :foreground ,magenta))) - `(gnus-group-mail-3 ((,class :inherit bold :foreground ,magenta-alt-other))) - `(gnus-group-mail-3-empty ((,class :foreground ,magenta-alt-other))) - `(gnus-group-mail-low ((,class :inherit bold :foreground ,magenta-nuanced))) - `(gnus-group-mail-low-empty ((,class :foreground ,magenta-nuanced))) - `(gnus-group-news-1 ((,class :inherit bold :foreground ,green))) - `(gnus-group-news-1-empty ((,class :foreground ,green))) - `(gnus-group-news-2 ((,class :inherit bold :foreground ,cyan))) - `(gnus-group-news-2-empty ((,class :foreground ,cyan))) - `(gnus-group-news-3 ((,class :inherit bold :foreground ,yellow-nuanced))) - `(gnus-group-news-3-empty ((,class :foreground ,yellow-nuanced))) - `(gnus-group-news-4 ((,class :inherit bold :foreground ,cyan-nuanced))) - `(gnus-group-news-4-empty ((,class :foreground ,cyan-nuanced))) - `(gnus-group-news-5 ((,class :inherit bold :foreground ,red-nuanced))) - `(gnus-group-news-5-empty ((,class :foreground ,red-nuanced))) - `(gnus-group-news-6 ((,class :inherit bold :foreground ,fg-alt))) - `(gnus-group-news-6-empty ((,class :foreground ,fg-alt))) - `(gnus-group-news-low ((,class :inherit bold :foreground ,green-nuanced))) - `(gnus-group-news-low-empty ((,class :foreground ,green-nuanced))) - `(gnus-header-content ((,class :foreground ,cyan))) - `(gnus-header-from ((,class :inherit bold :foreground ,cyan-alt-other :underline nil))) - `(gnus-header-name ((,class :foreground ,green))) - `(gnus-header-newsgroups ((,class :inherit bold :foreground ,blue-alt))) - `(gnus-header-subject ((,class :inherit bold :foreground ,magenta-alt-other))) - `(gnus-server-agent ((,class :inherit bold :foreground ,cyan))) - `(gnus-server-closed ((,class :inherit bold :foreground ,magenta))) - `(gnus-server-cloud ((,class :inherit bold :foreground ,cyan-alt))) - `(gnus-server-cloud-host ((,class :inherit modus-theme-refine-cyan))) - `(gnus-server-denied ((,class :inherit bold :foreground ,red))) - `(gnus-server-offline ((,class :inherit bold :foreground ,yellow))) - `(gnus-server-opened ((,class :inherit bold :foreground ,green))) - `(gnus-signature ((,class :foreground ,fg-special-cold :slant italic))) - `(gnus-splash ((,class :foreground ,fg-alt))) - `(gnus-summary-cancelled ((,class :inherit modus-theme-mark-alt))) - `(gnus-summary-high-ancient ((,class :inherit bold :foreground ,fg-alt))) - `(gnus-summary-high-read ((,class :inherit bold :foreground ,fg-special-cold))) - `(gnus-summary-high-ticked ((,class :inherit bold :foreground ,red-alt-other))) - `(gnus-summary-high-undownloaded ((,class :inherit bold :foreground ,yellow))) - `(gnus-summary-high-unread ((,class :inherit bold :foreground ,fg-main))) - `(gnus-summary-low-ancient ((,class :foreground ,fg-alt :slant italic))) - `(gnus-summary-low-read ((,class :foreground ,fg-alt :slant italic))) - `(gnus-summary-low-ticked ((,class :foreground ,red-refine-fg :slant italic))) - `(gnus-summary-low-undownloaded ((,class :foreground ,yellow-refine-fg :slant italic))) - `(gnus-summary-low-unread ((,class :inherit bold :foreground ,fg-special-cold))) - `(gnus-summary-normal-ancient ((,class :foreground ,fg-special-calm))) - `(gnus-summary-normal-read ((,class :foreground ,fg-alt))) - `(gnus-summary-normal-ticked ((,class :foreground ,red-alt-other))) - `(gnus-summary-normal-undownloaded ((,class :foreground ,yellow))) - `(gnus-summary-normal-unread ((,class :foreground ,fg-main))) - `(gnus-summary-selected ((,class :inherit modus-theme-subtle-blue))) -;;;;; golden-ratio-scroll-screen - `(golden-ratio-scroll-highlight-line-face ((,class :background ,cyan-subtle-bg :foreground ,fg-main))) -;;;;; helm - `(helm-M-x-key ((,class :inherit bold :foreground ,magenta-alt-other))) - `(helm-action ((,class :underline t))) - `(helm-bookmark-addressbook ((,class :foreground ,green-alt))) - `(helm-bookmark-directory ((,class :inherit bold :foreground ,blue))) - `(helm-bookmark-file ((,class :foreground ,fg-main))) - `(helm-bookmark-file-not-found ((,class :background ,bg-alt :foreground ,fg-alt))) - `(helm-bookmark-gnus ((,class :foreground ,magenta))) - `(helm-bookmark-info ((,class :foreground ,cyan-alt))) - `(helm-bookmark-man ((,class :foreground ,yellow-alt))) - `(helm-bookmark-w3m ((,class :foreground ,blue-alt))) - `(helm-buffer-archive ((,class :inherit bold :foreground ,cyan))) - `(helm-buffer-directory ((,class :inherit bold :foreground ,blue))) - `(helm-buffer-file ((,class :foreground ,fg-main))) - `(helm-buffer-modified ((,class :foreground ,yellow-alt))) - `(helm-buffer-not-saved ((,class :foreground ,red-alt))) - `(helm-buffer-process ((,class :foreground ,magenta))) - `(helm-buffer-saved-out ((,class :inherit bold :background ,bg-alt :foreground ,red))) - `(helm-buffer-size ((,class :foreground ,fg-alt))) - `(helm-candidate-number ((,class :foreground ,cyan-active))) - `(helm-candidate-number-suspended ((,class :foreground ,yellow-active))) - `(helm-comint-prompts-buffer-name ((,class :foreground ,green-active))) - `(helm-comint-prompts-promptidx ((,class :foreground ,cyan-active))) - `(helm-delete-async-message ((,class :inherit bold :foreground ,magenta-active))) - `(helm-eob-line ((,class :background ,bg-main :foreground ,fg-main))) - `(helm-eshell-prompts-buffer-name ((,class :foreground ,green-active))) - `(helm-eshell-prompts-promptidx ((,class :foreground ,cyan-active))) - `(helm-etags-file ((,class :foreground ,fg-dim :underline t))) - `(helm-ff-backup-file ((,class :foreground ,fg-alt))) - `(helm-ff-denied ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-red - 'modus-theme-intense-red - 'modus-theme-nuanced-red - red)))) - `(helm-ff-directory ((,class :inherit helm-buffer-directory))) - `(helm-ff-dirs ((,class :inherit bold :foreground ,blue-alt-other))) - `(helm-ff-dotted-directory ((,class :inherit bold :background ,bg-alt :foreground ,fg-alt))) - `(helm-ff-dotted-symlink-directory ((,class :inherit (button helm-ff-dotted-directory)))) - `(helm-ff-executable ((,class :foreground ,magenta-alt))) - `(helm-ff-file ((,class :foreground ,fg-main))) - `(helm-ff-file-extension ((,class :foreground ,fg-special-warm))) - `(helm-ff-invalid-symlink ((,class :inherit button :foreground ,red))) - `(helm-ff-pipe ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-refine-magenta - 'modus-theme-subtle-magenta - 'modus-theme-nuanced-magenta - magenta)))) - `(helm-ff-prefix ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-refine-yellow - 'modus-theme-subtle-yellow - 'modus-theme-nuanced-yellow - yellow-alt-other)))) - `(helm-ff-socket ((,class :foreground ,red-alt-other))) - `(helm-ff-suid ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-red - 'modus-theme-refine-red - 'modus-theme-nuanced-yellow - red-alt)))) - `(helm-ff-symlink ((,class :inherit button :foreground ,cyan))) - `(helm-ff-truename ((,class :foreground ,blue-alt-other))) - `(helm-grep-cmd-line ((,class :foreground ,yellow-alt-other))) - `(helm-grep-file ((,class :inherit bold :foreground ,fg-special-cold))) - `(helm-grep-finish ((,class :foreground ,green-active))) - `(helm-grep-lineno ((,class :foreground ,fg-special-warm))) - `(helm-grep-match ((,class :inherit modus-theme-special-calm))) - `(helm-header ((,class :inherit bold :foreground ,fg-special-cold))) - `(helm-header-line-left-margin ((,class :inherit bold :foreground ,yellow-intense))) - `(helm-history-deleted ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-red - 'modus-theme-intense-red - 'modus-theme-nuanced-red - red - 'bold)))) - `(helm-history-remote ((,class :foreground ,red-alt-other))) - `(helm-lisp-completion-info ((,class :foreground ,fg-special-warm))) - `(helm-lisp-show-completion ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-yellow - 'modus-theme-refine-yellow - 'modus-theme-nuanced-yellow - yellow - 'bold)))) - `(helm-locate-finish ((,class :foreground ,green-active))) - `(helm-match ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-cyan - 'modus-theme-refine-cyan - 'modus-theme-nuanced-cyan - cyan - 'bold)))) - `(helm-match-item ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-neutral - 'modus-theme-subtle-cyan - 'modus-theme-nuanced-cyan - cyan-alt-other)))) - `(helm-minibuffer-prompt ((,class :inherit minibuffer-prompt))) - `(helm-moccur-buffer ((,class :inherit button :foreground ,cyan-alt-other))) - `(helm-mode-prefix ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-magenta - 'modus-theme-intense-magenta - 'modus-theme-nuanced-magenta - magenta-alt - 'bold)))) - `(helm-non-file-buffer ((,class :foreground ,fg-alt))) - `(helm-prefarg ((,class :foreground ,red-active))) - `(helm-resume-need-update ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-magenta - 'modus-theme-refine-magenta - 'modus-theme-nuanced-magenta - magenta-alt-other)))) - `(helm-selection ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-blue - 'modus-theme-refine-blue - 'modus-theme-special-cold - nil - 'bold)))) - `(helm-selection-line ((,class :inherit modus-theme-special-cold))) - `(helm-separator ((,class :foreground ,fg-special-mild))) - `(helm-time-zone-current ((,class :foreground ,green))) - `(helm-time-zone-home ((,class :foreground ,magenta))) - `(helm-source-header ((,class :inherit bold :foreground ,red-alt - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-4)))) - `(helm-top-columns ((,class :inherit helm-header))) - `(helm-ucs-char ((,class :foreground ,yellow-alt-other))) - `(helm-visible-mark ((,class :inherit modus-theme-subtle-cyan))) -;;;;; helm-ls-git - `(helm-ls-git-added-copied-face ((,class :foreground ,green-intense))) - `(helm-ls-git-added-modified-face ((,class :foreground ,yellow-intense))) - `(helm-ls-git-conflict-face ((,class :inherit bold :foreground ,red-intense))) - `(helm-ls-git-deleted-and-staged-face ((,class :foreground ,red-nuanced))) - `(helm-ls-git-deleted-not-staged-face ((,class :foreground ,red))) - `(helm-ls-git-modified-and-staged-face ((,class :foreground ,yellow-nuanced))) - `(helm-ls-git-modified-not-staged-face ((,class :foreground ,yellow))) - `(helm-ls-git-renamed-modified-face ((,class :foreground ,magenta))) - `(helm-ls-git-untracked-face ((,class :foreground ,fg-special-cold))) -;;;;; helm-switch-shell - `(helm-switch-shell-new-shell-face ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-magenta - 'modus-theme-refine-magenta - 'modus-theme-nuanced-magenta - magenta-alt-other - 'bold)))) -;;;;; helm-xref - `(helm-xref-file-name ((,class :inherit bold :foreground ,fg-special-cold))) - `(helm-xref-file-name ((,class :foreground ,fg-special-warm))) -;;;;; helpful - `(helpful-heading ((,class :inherit modus-theme-heading-1))) -;;;;; highlight region or ad-hoc regexp - `(hi-black-b ((,class :background ,fg-main :foreground ,bg-main))) - `(hi-blue ((,class :background ,bg-alt :foreground ,blue :underline t))) - `(hi-blue-b ((,class :inherit modus-theme-intense-blue))) - `(hi-green ((,class :background ,bg-alt :foreground ,green :underline t))) - `(hi-green-b ((,class :inherit modus-theme-intense-green))) - `(hi-pink ((,class :background ,bg-alt :foreground ,magenta :underline t))) - `(hi-red-b ((,class :inherit modus-theme-intense-red))) - `(hi-yellow ((,class :background ,bg-alt :foreground ,yellow :underline t))) - `(highlight ((,class :inherit modus-theme-subtle-blue))) - `(highlight-changes ((,class :foreground ,yellow-alt-other))) - `(highlight-changes-delete ((,class :foreground ,red-alt-other :underline t))) - `(hl-line ((,class :inherit modus-theme-hl-line))) -;;;;; highlight-blocks - `(highlight-blocks-depth-1-face ((,class :background ,bg-dim :foreground ,fg-main))) - `(highlight-blocks-depth-2-face ((,class :background ,bg-alt :foreground ,fg-main))) - `(highlight-blocks-depth-3-face ((,class :background ,bg-special-cold :foreground ,fg-main))) - `(highlight-blocks-depth-4-face ((,class :background ,bg-special-calm :foreground ,fg-main))) - `(highlight-blocks-depth-5-face ((,class :background ,bg-special-warm :foreground ,fg-main))) - `(highlight-blocks-depth-6-face ((,class :background ,bg-special-mild :foreground ,fg-main))) - `(highlight-blocks-depth-7-face ((,class :background ,bg-inactive :foreground ,fg-main))) - `(highlight-blocks-depth-8-face ((,class :background ,bg-active :foreground ,fg-main))) - `(highlight-blocks-depth-9-face ((,class :background ,cyan-subtle-bg :foreground ,fg-main))) -;;;;; highlight-defined - `(highlight-defined-builtin-function-name-face ((,class :foreground ,magenta))) - `(highlight-defined-face-name-face ((,class :foreground ,fg-main))) - `(highlight-defined-function-name-face ((,class :foreground ,magenta))) - `(highlight-defined-macro-name-face ((,class :foreground ,magenta-alt))) - `(highlight-defined-special-form-name-face ((,class :foreground ,magenta-alt-other))) - `(highlight-defined-variable-name-face ((,class :foreground ,cyan))) -;;;;; highlight-escape-sequences (`hes-mode') - `(hes-escape-backslash-face ((,class :inherit bold :foreground ,fg-escape-char-construct))) - `(hes-escape-sequence-face ((,class :inherit bold :foreground ,fg-escape-char-backslash))) -;;;;; highlight-indentation - `(highlight-indentation-face ((,class :inherit modus-theme-hl-line))) - `(highlight-indentation-current-column-face ((,class :background ,bg-active))) -;;;;; highlight-numbers - `(highlight-numbers-number ((,class :foreground ,blue-alt-other))) -;;;;; highlight-symbol - `(highlight-symbol-face ((,class :inherit modus-theme-special-mild))) -;;;;; highlight-thing - `(highlight-thing ((,class :background ,bg-alt :foreground ,cyan))) -;;;;; hl-defined - `(hdefd-functions ((,class :foreground ,blue))) - `(hdefd-undefined ((,class :foreground ,red-alt))) - `(hdefd-variables ((,class :foreground ,cyan-alt))) -;;;;; hl-fill-column - `(hl-fill-column-face ((,class :background ,bg-active :foreground ,fg-active))) -;;;;; hl-todo - `(hl-todo ((,class :inherit bold :foreground ,red-alt-other :slant ,modus-theme-slant))) -;;;;; hydra - `(hydra-face-amaranth ((,class :inherit bold :foreground ,yellow))) - `(hydra-face-blue ((,class :inherit bold :foreground ,blue-alt))) - `(hydra-face-pink ((,class :inherit bold :foreground ,magenta-alt))) - `(hydra-face-red ((,class :inherit bold :foreground ,red))) - `(hydra-face-teal ((,class :inherit bold :foreground ,cyan))) -;;;;; hyperlist - `(hyperlist-condition ((,class :foreground ,green))) - `(hyperlist-hashtag ((,class :foreground ,yellow))) - `(hyperlist-operator ((,class :foreground ,blue-alt))) - `(hyperlist-paren ((,class :foreground ,cyan-alt-other))) - `(hyperlist-quote ((,class :foreground ,cyan-alt))) - `(hyperlist-ref ((,class :foreground ,magenta-alt-other))) - `(hyperlist-stars ((,class :foreground ,fg-alt))) - `(hyperlist-tag ((,class :foreground ,red))) - `(hyperlist-toplevel ((,class :inherit bold :foreground ,fg-main))) -;;;;; icomplete - `(icomplete-first-match ((,class :inherit bold - ,@(modus-vivendi-theme-standard-completions - magenta bg-alt - bg-active fg-main)))) -;;;;; icomplete-vertical - `(icomplete-vertical-separator ((,class :foreground ,fg-alt))) -;;;;; ido-mode - `(ido-first-match ((,class :inherit bold - ,@(modus-vivendi-theme-standard-completions - magenta bg-alt - bg-active fg-main)))) - `(ido-incomplete-regexp ((,class :inherit error))) - `(ido-indicator ((,class :inherit modus-theme-subtle-yellow))) - `(ido-only-match ((,class :inherit bold - ,@(modus-vivendi-theme-standard-completions - green green-nuanced-bg - green-intense-bg fg-main)))) - `(ido-subdir ((,class :foreground ,blue))) - `(ido-virtual ((,class :foreground ,fg-special-warm))) -;;;;; iedit - `(iedit-occurrence ((,class :inherit modus-theme-refine-blue))) - `(iedit-read-only-occurrence ((,class :inherit modus-theme-intense-yellow))) -;;;;; iflipb - `(iflipb-current-buffer-face ((,class :inherit bold :foreground ,cyan-alt))) - `(iflipb-other-buffer-face ((,class :foreground ,fg-alt))) -;;;;; imenu-list - `(imenu-list-entry-face-0 ((,class :foreground ,cyan))) - `(imenu-list-entry-face-1 ((,class :foreground ,blue))) - `(imenu-list-entry-face-2 ((,class :foreground ,cyan-alt-other))) - `(imenu-list-entry-face-3 ((,class :foreground ,blue-alt))) - `(imenu-list-entry-subalist-face-0 ((,class :inherit bold :foreground ,magenta-alt-other :underline t))) - `(imenu-list-entry-subalist-face-1 ((,class :inherit bold :foreground ,magenta :underline t))) - `(imenu-list-entry-subalist-face-2 ((,class :inherit bold :foreground ,green-alt-other :underline t))) - `(imenu-list-entry-subalist-face-3 ((,class :inherit bold :foreground ,red-alt-other :underline t))) -;;;;; indium - `(indium-breakpoint-face ((,class :foreground ,red-active))) - `(indium-frame-url-face ((,class :inherit button :foreground ,fg-alt))) - `(indium-keyword-face ((,class :foreground ,magenta-alt-other))) - `(indium-litable-face ((,class :foreground ,fg-special-warm :slant ,modus-theme-slant))) - `(indium-repl-error-face ((,class :inherit bold :foreground ,red))) - `(indium-repl-prompt-face ((,class :foreground ,cyan-alt-other))) - `(indium-repl-stdout-face ((,class :foreground ,fg-main))) -;;;;; info - `(Info-quoted ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,magenta))) ; the capitalisation is canonical - `(info-header-node ((,class :inherit bold :foreground ,fg-alt))) - `(info-header-xref ((,class :foreground ,blue-active))) - `(info-index-match ((,class :inherit match))) - `(info-menu-header ((,class :inherit modus-theme-heading-3))) - `(info-menu-star ((,class :foreground ,red))) - `(info-node ((,class :inherit bold))) - `(info-title-1 ((,class :inherit modus-theme-heading-1))) - `(info-title-2 ((,class :inherit modus-theme-heading-2))) - `(info-title-3 ((,class :inherit modus-theme-heading-3))) - `(info-title-4 ((,class :inherit modus-theme-heading-4))) -;;;;; info-colors - `(info-colors-lisp-code-block ((,class :inherit fixed-pitch))) - `(info-colors-ref-item-command ((,class :foreground ,magenta))) - `(info-colors-ref-item-constant ((,class :foreground ,blue-alt-other))) - `(info-colors-ref-item-function ((,class :foreground ,magenta))) - `(info-colors-ref-item-macro ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,magenta-alt-other))) - `(info-colors-ref-item-other ((,class :foreground ,cyan))) - `(info-colors-ref-item-special-form ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,magenta-alt-other))) - `(info-colors-ref-item-syntax-class ((,class :foreground ,magenta))) - `(info-colors-ref-item-type ((,class :foreground ,magenta-alt))) - `(info-colors-ref-item-user-option ((,class :foreground ,cyan))) - `(info-colors-ref-item-variable ((,class :foreground ,cyan))) -;;;;; interaction-log - `(ilog-buffer-face ((,class :foreground ,magenta-alt-other))) - `(ilog-change-face ((,class :foreground ,magenta-alt))) - `(ilog-echo-face ((,class :foreground ,yellow-alt-other))) - `(ilog-load-face ((,class :foreground ,green))) - `(ilog-message-face ((,class :foreground ,fg-alt))) - `(ilog-non-change-face ((,class :foreground ,blue))) -;;;;; ioccur - `(ioccur-cursor ((,class :foreground ,fg-main))) - `(ioccur-invalid-regexp ((,class :foreground ,red))) - `(ioccur-match-face ((,class :inherit modus-theme-special-calm))) - `(ioccur-match-overlay-face ((,class ,@(and (>= emacs-major-version 27) '(:extend t)) - :inherit modus-theme-special-cold))) - `(ioccur-num-line-face ((,class :foreground ,fg-special-warm))) - `(ioccur-overlay-face ((,class ,@(and (>= emacs-major-version 27) '(:extend t)) - :inherit modus-theme-refine-blue))) - `(ioccur-regexp-face ((,class :inherit (modus-theme-intense-magenta bold)))) - `(ioccur-title-face ((,class :inherit bold :foreground ,red-alt - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-4)))) -;;;;; isearch, occur, and the like - `(isearch ((,class :inherit (modus-theme-intense-green bold)))) - `(isearch-fail ((,class :inherit modus-theme-refine-red))) - `(lazy-highlight ((,class :inherit modus-theme-refine-cyan))) - `(match ((,class :inherit modus-theme-special-calm))) - `(query-replace ((,class :inherit (modus-theme-intense-yellow bold)))) -;;;;; ivy - `(ivy-action ((,class :inherit bold :foreground ,red-alt))) - `(ivy-completions-annotations ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(ivy-confirm-face ((,class :foreground ,cyan))) - `(ivy-current-match ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-refine-cyan - 'modus-theme-intense-cyan - 'modus-theme-special-warm - nil - 'bold)))) - `(ivy-cursor ((,class :background ,fg-main :foreground ,bg-main))) - `(ivy-grep-info ((,class :foreground ,cyan-alt))) - `(ivy-grep-line-number ((,class :foreground ,fg-special-warm))) - `(ivy-highlight-face ((,class :foreground ,magenta))) - `(ivy-match-required-face ((,class :inherit error))) - `(ivy-minibuffer-match-face-1 ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-neutral - 'modus-theme-intense-neutral - 'modus-theme-subtle-neutral - fg-alt)))) - `(ivy-minibuffer-match-face-2 ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-green - 'modus-theme-refine-green - 'modus-theme-nuanced-green - green-alt-other - 'bold)))) - `(ivy-minibuffer-match-face-3 ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-cyan - 'modus-theme-refine-cyan - 'modus-theme-nuanced-cyan - cyan-alt-other - 'bold)))) - `(ivy-minibuffer-match-face-4 ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-magenta - 'modus-theme-refine-magenta - 'modus-theme-nuanced-magenta - magenta-alt-other - 'bold)))) - `(ivy-minibuffer-match-highlight ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-blue - 'modus-theme-intense-blue - 'modus-theme-nuanced-blue - blue-alt-other - 'bold)))) - `(ivy-modified-buffer ((,class :foreground ,yellow :slant ,modus-theme-slant))) - `(ivy-modified-outside-buffer ((,class :foreground ,yellow-alt :slant ,modus-theme-slant))) - `(ivy-org ((,class :foreground ,cyan-alt-other))) - `(ivy-prompt-match ((,class :inherit ivy-current-match))) - `(ivy-remote ((,class :foreground ,magenta))) - `(ivy-separator ((,class :foreground ,fg-alt))) - `(ivy-subdir ((,class :foreground ,blue-alt-other))) - `(ivy-virtual ((,class :foreground ,magenta-alt-other))) - `(ivy-yanked-word ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-blue - 'modus-theme-refine-blue - 'modus-theme-nuanced-blue - blue-alt)))) -;;;;; ivy-posframe - `(ivy-posframe ((,class :background ,bg-dim :foreground ,fg-main))) - `(ivy-posframe-border ((,class :background ,bg-active))) - `(ivy-posframe-cursor ((,class :background ,fg-main :foreground ,bg-main))) -;;;;; jira (org-jira) - `(jiralib-comment-face ((,class :background ,bg-alt))) - `(jiralib-comment-header-face ((,class :inherit bold))) - `(jiralib-issue-info-face ((,class :inherit modus-theme-special-warm))) - `(jiralib-issue-info-header-face ((,class :inherit (modus-theme-special-warm bold)))) - `(jiralib-issue-summary-face ((,class :inherit bold))) - `(jiralib-link-filter-face ((,class :underline t))) - `(jiralib-link-issue-face ((,class :underline t))) - `(jiralib-link-project-face ((,class :underline t))) -;;;;; journalctl-mode - `(journalctl-error-face ((,class :inherit bold :foreground ,red))) - `(journalctl-finished-face ((,class :inherit bold :foreground ,green))) - `(journalctl-host-face ((,class :foreground ,blue))) - `(journalctl-process-face ((,class :foreground ,cyan-alt-other))) - `(journalctl-starting-face ((,class :foreground ,green))) - `(journalctl-timestamp-face ((,class :foreground ,fg-special-cold))) - `(journalctl-warning-face ((,class :inherit bold :foreground ,yellow))) -;;;;; js2-mode - `(js2-error ((,class :foreground ,red))) - `(js2-external-variable ((,class :foreground ,cyan-alt-other))) - `(js2-function-call ((,class :foreground ,magenta))) - `(js2-function-param ((,class :foreground ,blue))) - `(js2-instance-member ((,class :foreground ,magenta-alt-other))) - `(js2-jsdoc-html-tag-delimiter ((,class :foreground ,fg-main))) - `(js2-jsdoc-html-tag-name ((,class :foreground ,cyan))) - `(js2-jsdoc-tag ((,class :foreground ,fg-special-calm))) - `(js2-jsdoc-type ((,class :foreground ,fg-special-cold))) - `(js2-jsdoc-value ((,class :foreground ,fg-special-warm))) - `(js2-object-property ((,class :foreground ,fg-main))) - `(js2-object-property-access ((,class :foreground ,fg-main))) - `(js2-private-function-call ((,class :foreground ,green-alt-other))) - `(js2-private-member ((,class :foreground ,fg-special-mild))) - `(js2-warning ((,class :foreground ,yellow-alt :underline t))) -;;;;; julia - `(julia-macro-face ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,magenta))) - `(julia-quoted-symbol-face ((,class :foreground ,blue-alt-other))) -;;;;; jupyter - `(jupyter-eval-overlay ((,class :inherit bold :foreground ,blue))) - `(jupyter-repl-input-prompt ((,class :foreground ,cyan-alt-other))) - `(jupyter-repl-output-prompt ((,class :foreground ,magenta-alt-other))) - `(jupyter-repl-traceback ((,class :inherit modus-theme-intense-red))) -;;;;; kaocha-runner - `(kaocha-runner-error-face ((,class :foreground ,red))) - `(kaocha-runner-success-face ((,class :foreground ,green))) - `(kaocha-runner-warning-face ((,class :foreground ,yellow))) -;;;;; keycast - `(keycast-command ((,class :inherit bold :foreground ,blue-active))) - `(keycast-key ((,class ,@(modus-vivendi-theme-mode-line-attrs - bg-main blue-active - bg-main blue-active - blue-active blue-intense - 'alt-style -3)))) -;;;;; line numbers (display-line-numbers-mode and global variant) - `(line-number ((,class :inherit default :background ,bg-dim :foreground ,fg-alt))) - `(line-number-current-line ((,class :inherit default :background ,bg-active :foreground ,fg-main))) -;;;;; lsp-mode - `(lsp-face-highlight-read ((,class :inherit modus-theme-subtle-blue :underline t))) - `(lsp-face-highlight-textual ((,class :inherit modus-theme-subtle-blue))) - `(lsp-face-highlight-write ((,class :inherit (modus-theme-refine-blue bold)))) - `(lsp-face-semhl-constant ((,class :foreground ,blue-alt-other))) - `(lsp-face-semhl-deprecated - ((,(append '((supports :underline (:style wave))) class) - :foreground ,yellow :underline (:style wave)) - (,class :foreground ,yellow :underline t))) - `(lsp-face-semhl-enummember ((,class :foreground ,blue-alt-other))) - `(lsp-face-semhl-field ((,class :foreground ,cyan-alt))) - `(lsp-face-semhl-field-static ((,class :foreground ,cyan-alt :slant ,modus-theme-slant))) - `(lsp-face-semhl-function ((,class :foreground ,magenta))) - `(lsp-face-semhl-method ((,class :foreground ,magenta))) - `(lsp-face-semhl-namespace ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,magenta-alt))) - `(lsp-face-semhl-preprocessor ((,class :foreground ,red-alt-other))) - `(lsp-face-semhl-static-method ((,class :foreground ,magenta :slant ,modus-theme-slant))) - `(lsp-face-semhl-type-class ((,class :foreground ,magenta-alt))) - `(lsp-face-semhl-type-enum ((,class :foreground ,magenta-alt))) - `(lsp-face-semhl-type-primitive ((,class :foreground ,magenta-alt :slant ,modus-theme-slant))) - `(lsp-face-semhl-type-template ((,class :foreground ,magenta-alt :slant ,modus-theme-slant))) - `(lsp-face-semhl-type-typedef ((,class :foreground ,magenta-alt :slant ,modus-theme-slant))) - `(lsp-face-semhl-variable ((,class :foreground ,cyan))) - `(lsp-face-semhl-variable-local ((,class :foreground ,cyan))) - `(lsp-face-semhl-variable-parameter ((,class :foreground ,cyan-alt-other))) - `(lsp-lens-face ((,class :height 0.8 :foreground ,fg-alt))) - `(lsp-lens-mouse-face ((,class :height 0.8 :foreground ,blue-alt-other :underline t))) - `(lsp-ui-doc-background ((,class :background ,bg-alt))) - `(lsp-ui-doc-header ((,class :background ,bg-header :foreground ,fg-header))) - `(lsp-ui-doc-url ((,class :inherit button :foreground ,blue-alt-other))) - `(lsp-ui-peek-filename ((,class :foreground ,fg-special-warm))) - `(lsp-ui-peek-footer ((,class :background ,bg-header :foreground ,fg-header))) - `(lsp-ui-peek-header ((,class :background ,bg-header :foreground ,fg-header))) - `(lsp-ui-peek-highlight ((,class :inherit modus-theme-subtle-blue))) - `(lsp-ui-peek-line-number ((,class :foreground ,fg-alt))) - `(lsp-ui-peek-list ((,class :background ,bg-dim))) - `(lsp-ui-peek-peek ((,class :background ,bg-alt))) - `(lsp-ui-peek-selection ((,class :inherit modus-theme-subtle-cyan))) - `(lsp-ui-sideline-code-action ((,class :foreground ,yellow))) - `(lsp-ui-sideline-current-symbol ((,class :inherit bold :height 0.99 :box (:line-width -1 :style nil) :foreground ,fg-main))) - `(lsp-ui-sideline-symbol ((,class :inherit bold :height 0.99 :box (:line-width -1 :style nil) :foreground ,fg-alt))) - `(lsp-ui-sideline-symbol-info ((,class :height 0.99 :slant italic))) -;;;;; magit - `(magit-bisect-bad ((,class :foreground ,red-alt-other))) - `(magit-bisect-good ((,class :foreground ,green-alt-other))) - `(magit-bisect-skip ((,class :foreground ,yellow-alt-other))) - `(magit-blame-date ((,class :foreground ,blue))) - `(magit-blame-dimmed ((,class :foreground ,fg-alt))) - `(magit-blame-hash ((,class :foreground ,fg-special-warm))) - `(magit-blame-heading ((,class :background ,bg-alt))) - `(magit-blame-highlight ((,class :inherit modus-theme-nuanced-cyan))) - `(magit-blame-margin ((,class :inherit magit-blame-highlight))) - `(magit-blame-name ((,class :foreground ,magenta-alt-other))) - `(magit-blame-summary ((,class :foreground ,cyan-alt-other))) - `(magit-branch-current ((,class :foreground ,blue-alt-other :box t))) - `(magit-branch-local ((,class :foreground ,blue-alt))) - `(magit-branch-remote ((,class :foreground ,magenta-alt))) - `(magit-branch-remote-head ((,class :foreground ,magenta-alt-other :box t))) - `(magit-branch-upstream ((,class :slant italic))) - `(magit-cherry-equivalent ((,class :background ,bg-main :foreground ,magenta-intense))) - `(magit-cherry-unmatched ((,class :background ,bg-main :foreground ,cyan-intense))) - ;; NOTE: here we break from the pattern of inheriting from the - ;; modus-theme-diff-* faces, though only for the standard actions, - ;; not the highlighted ones. This is because Magit's interaction - ;; model relies on highlighting the current diff hunk. - `(magit-diff-added ((,class ,@(modus-vivendi-theme-diff - bg-main green - bg-diff-added fg-diff-added - green-nuanced-bg fg-diff-added)))) - `(magit-diff-added-highlight ((,class :inherit modus-theme-diff-focus-added))) - `(magit-diff-base ((,class ,@(modus-vivendi-theme-diff - bg-main yellow - bg-diff-changed fg-diff-changed - yellow-nuanced-bg fg-diff-changed)))) - `(magit-diff-base-highlight ((,class :inherit modus-theme-diff-focus-changed))) - `(magit-diff-context ((,class :foreground ,fg-unfocused))) - `(magit-diff-context-highlight ((,class ,@(modus-vivendi-theme-diff - bg-dim fg-dim - bg-inactive fg-inactive - bg-dim fg-alt)))) - `(magit-diff-file-heading ((,class :inherit bold :foreground ,fg-special-cold))) - `(magit-diff-file-heading-highlight ((,class :inherit (modus-theme-special-cold bold)))) - `(magit-diff-file-heading-selection ((,class :inherit modus-theme-refine-cyan))) - ;; NOTE: here we break from the pattern of inheriting from the - ;; modus-theme-diff-* faces. - `(magit-diff-hunk-heading ((,class :inherit bold :background ,bg-active - :foreground ,fg-inactive))) - `(magit-diff-hunk-heading-highlight ((,class :inherit bold :background ,bg-diff-heading - :foreground ,fg-diff-heading))) - `(magit-diff-hunk-heading-selection ((,class :inherit modus-theme-refine-blue))) - `(magit-diff-hunk-region ((,class :inherit bold))) - `(magit-diff-lines-boundary ((,class :background ,fg-main))) - `(magit-diff-lines-heading ((,class :inherit modus-theme-refine-magenta))) - `(magit-diff-removed ((,class ,@(modus-vivendi-theme-diff - bg-main red - bg-diff-removed fg-diff-removed - red-nuanced-bg fg-diff-removed)))) - `(magit-diff-removed-highlight ((,class :inherit modus-theme-diff-focus-removed))) - `(magit-diffstat-added ((,class :foreground ,green))) - `(magit-diffstat-removed ((,class :foreground ,red))) - `(magit-dimmed ((,class :foreground ,fg-unfocused))) - `(magit-filename ((,class :foreground ,fg-special-cold))) - `(magit-hash ((,class :foreground ,fg-alt))) - `(magit-head ((,class :inherit magit-branch-local))) - `(magit-header-line ((,class :inherit bold :foreground ,magenta-active))) - `(magit-header-line-key ((,class :inherit bold :foreground ,red-active))) - `(magit-header-line-log-select ((,class :inherit bold :foreground ,fg-main))) - `(magit-keyword ((,class :foreground ,magenta))) - `(magit-keyword-squash ((,class :inherit bold :foreground ,yellow-alt-other))) - `(magit-log-author ((,class :foreground ,cyan))) - `(magit-log-date ((,class :foreground ,fg-alt))) - `(magit-log-graph ((,class :foreground ,fg-dim))) - `(magit-mode-line-process ((,class :inherit bold :foreground ,blue-active))) - `(magit-mode-line-process-error ((,class :inherit bold :foreground ,red-active))) - `(magit-process-ng ((,class :inherit error))) - `(magit-process-ok ((,class :inherit success))) - `(magit-reflog-amend ((,class :background ,bg-main :foreground ,magenta-intense))) - `(magit-reflog-checkout ((,class :background ,bg-main :foreground ,blue-intense))) - `(magit-reflog-cherry-pick ((,class :background ,bg-main :foreground ,green-intense))) - `(magit-reflog-commit ((,class :background ,bg-main :foreground ,green-intense))) - `(magit-reflog-merge ((,class :background ,bg-main :foreground ,green-intense))) - `(magit-reflog-other ((,class :background ,bg-main :foreground ,cyan-intense))) - `(magit-reflog-rebase ((,class :background ,bg-main :foreground ,magenta-intense))) - `(magit-reflog-remote ((,class :background ,bg-main :foreground ,cyan-intense))) - `(magit-reflog-reset ((,class :background ,bg-main :foreground ,red-intense))) - `(magit-refname ((,class :foreground ,fg-alt))) - `(magit-refname-pullreq ((,class :foreground ,fg-alt))) - `(magit-refname-stash ((,class :foreground ,fg-alt))) - `(magit-refname-wip ((,class :foreground ,fg-alt))) - `(magit-section ((,class :background ,bg-dim :foreground ,fg-main))) - `(magit-section-heading ((,class :inherit bold :foreground ,cyan))) - `(magit-section-heading-selection ((,class :inherit (modus-theme-refine-cyan bold)))) - `(magit-section-highlight ((,class :background ,bg-alt))) - `(magit-sequence-done ((,class :foreground ,green-alt))) - `(magit-sequence-drop ((,class :foreground ,red-alt))) - `(magit-sequence-exec ((,class :foreground ,magenta-alt))) - `(magit-sequence-head ((,class :foreground ,cyan-alt))) - `(magit-sequence-onto ((,class :foreground ,fg-alt))) - `(magit-sequence-part ((,class :foreground ,yellow-alt))) - `(magit-sequence-pick ((,class :foreground ,blue-alt))) - `(magit-sequence-stop ((,class :foreground ,red))) - `(magit-signature-bad ((,class :inherit bold :foreground ,red))) - `(magit-signature-error ((,class :foreground ,red-alt))) - `(magit-signature-expired ((,class :foreground ,yellow))) - `(magit-signature-expired-key ((,class :foreground ,yellow))) - `(magit-signature-good ((,class :foreground ,green))) - `(magit-signature-revoked ((,class :foreground ,magenta))) - `(magit-signature-untrusted ((,class :foreground ,cyan))) - `(magit-tag ((,class :foreground ,yellow-alt-other))) -;;;;; magit-imerge - `(magit-imerge-overriding-value ((,class :inherit bold :foreground ,red-alt))) -;;;;; man - `(Man-overstrike ((,class :inherit bold :foreground ,magenta))) - `(Man-reverse ((,class :inherit modus-theme-subtle-magenta))) - `(Man-underline ((,class :foreground ,cyan :underline t))) -;;;;; markdown-mode - `(markdown-blockquote-face ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(markdown-bold-face ((,class :inherit bold))) - `(markdown-code-face ((,class ,@(modus-vivendi-theme-mixed-fonts)))) - `(markdown-comment-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(markdown-footnote-marker-face ((,class :inherit bold :foreground ,cyan-alt))) - `(markdown-footnote-text-face ((,class :foreground ,fg-main :slant ,modus-theme-slant))) - `(markdown-gfm-checkbox-face ((,class :foreground ,cyan-alt-other))) - `(markdown-header-delimiter-face ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,fg-dim))) - `(markdown-header-face ((t nil))) - `(markdown-header-face-1 ((,class :inherit modus-theme-heading-1))) - `(markdown-header-face-2 ((,class :inherit modus-theme-heading-2))) - `(markdown-header-face-3 ((,class :inherit modus-theme-heading-3))) - `(markdown-header-face-4 ((,class :inherit modus-theme-heading-4))) - `(markdown-header-face-5 ((,class :inherit modus-theme-heading-5))) - `(markdown-header-face-6 ((,class :inherit modus-theme-heading-6))) - `(markdown-header-rule-face ((,class :inherit bold :foreground ,fg-special-warm))) - `(markdown-hr-face ((,class :inherit bold :foreground ,fg-special-warm))) - `(markdown-html-attr-name-face ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,cyan))) - `(markdown-html-attr-value-face ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,blue))) - `(markdown-html-entity-face ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,cyan))) - `(markdown-html-tag-delimiter-face ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,fg-special-mild))) - `(markdown-html-tag-name-face ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,magenta-alt))) - `(markdown-inline-code-face ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,magenta))) - `(markdown-italic-face ((,class :foreground ,fg-special-cold :slant italic))) - `(markdown-language-info-face ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,fg-special-cold))) - `(markdown-language-keyword-face ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,green-alt-other))) - `(markdown-line-break-face ((,class :inherit modus-theme-refine-cyan :underline t))) - `(markdown-link-face ((,class :inherit link))) - `(markdown-link-title-face ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(markdown-list-face ((,class :foreground ,fg-dim))) - `(markdown-markup-face ((,class :foreground ,fg-alt))) - `(markdown-math-face ((,class :foreground ,magenta-alt-other))) - `(markdown-metadata-key-face ((,class :foreground ,cyan-alt-other))) - `(markdown-metadata-value-face ((,class :foreground ,blue-alt))) - `(markdown-missing-link-face ((,class :inherit bold :foreground ,yellow))) - `(markdown-plain-url-face ((,class :inherit markdown-link-face))) - `(markdown-pre-face ((,class ,@(and (>= emacs-major-version 27) '(:extend t)) - ,@(modus-vivendi-theme-mixed-fonts) - :background ,bg-dim - :foreground ,fg-special-mild))) - `(markdown-reference-face ((,class :inherit markdown-markup-face))) - `(markdown-strike-through-face ((,class :strike-through t))) - `(markdown-table-face ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,fg-special-cold))) - `(markdown-url-face ((,class :foreground ,blue-alt))) -;;;;; markup-faces (`adoc-mode') - `(markup-anchor-face ((,class :foreground ,fg-inactive))) - `(markup-attribute-face ((,class :foreground ,fg-inactive :slant italic))) - `(markup-big-face ((,class :height 1.3 :foreground ,blue-nuanced))) - `(markup-bold-face ((,class :inherit bold :foreground ,red-nuanced))) - `(markup-code-face ((,class :inherit fixed-pitch :foreground ,magenta))) - `(markup-command-face ((,class :foreground ,fg-inactive))) - `(markup-comment-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(markup-complex-replacement-face ((,class :box (:line-width 2 :color nil :style released-button) - :inherit modus-theme-refine-magenta))) - `(markup-emphasis-face ((,class :foreground ,fg-special-cold :slant italic))) - `(markup-error-face ((,class :inherit bold :foreground ,red))) - `(markup-gen-face ((,class :foreground ,magenta-alt))) - `(markup-internal-reference-face ((,class :inherit button :foreground ,fg-inactive))) - `(markup-italic-face ((,class :foreground ,fg-special-cold :slant italic))) - `(markup-list-face ((,class :inherit modus-theme-special-calm))) - `(markup-meta-face ((,class :foreground ,fg-inactive))) - `(markup-meta-hide-face ((,class :foreground ,fg-alt))) - `(markup-passthrough-face ((,class :inherit fixed-pitch :foreground ,cyan))) - `(markup-preprocessor-face ((,class :foreground ,red-alt-other))) - `(markup-replacement-face ((,class :foreground ,yellow-alt-other))) - `(markup-secondary-text-face ((,class :height 0.8 :foreground ,magenta-nuanced))) - `(markup-small-face ((,class :height 0.8 :foreground ,fg-main))) - `(markup-strong-face ((,class :inherit bold :foreground ,red-nuanced))) - `(markup-subscript-face ((,class :height 0.8 :foreground ,fg-special-cold))) - `(markup-superscript-face ((,class :height 0.8 :foreground ,fg-special-cold))) - `(markup-table-cell-face ((,class :inherit modus-theme-special-cold))) - `(markup-table-face ((,class :inherit modus-theme-subtle-cyan))) - `(markup-table-row-face ((,class :inherit modus-theme-subtle-cyan))) - `(markup-title-0-face ((,class :height 3.0 :foreground ,blue-nuanced))) - `(markup-title-1-face ((,class :height 2.4 :foreground ,blue-nuanced))) - `(markup-title-2-face ((,class :height 1.8 :foreground ,blue-nuanced))) - `(markup-title-3-face ((,class :height 1.4 :foreground ,blue-nuanced))) - `(markup-title-4-face ((,class :height 1.2 :foreground ,blue-nuanced))) - `(markup-title-5-face ((,class :height 1.2 :foreground ,blue-nuanced :underline t))) - `(markup-value-face ((,class :foreground ,fg-inactive))) - `(markup-verbatim-face ((,class :inherit modus-theme-special-mild))) -;;;;; mentor - `(mentor-download-message ((,class :foreground ,fg-special-warm))) - `(mentor-download-name ((,class :foreground ,fg-special-cold))) - `(mentor-download-progress ((,class :foreground ,blue-alt-other))) - `(mentor-download-size ((,class :foreground ,magenta-alt-other))) - `(mentor-download-speed-down ((,class :foreground ,cyan-alt))) - `(mentor-download-speed-up ((,class :foreground ,red-alt))) - `(mentor-download-state ((,class :foreground ,yellow-alt))) - `(mentor-highlight-face ((,class :inherit modus-theme-subtle-blue))) - `(mentor-tracker-name ((,class :foreground ,magenta-alt))) -;;;;; messages - `(message-cited-text-1 ((,class :foreground ,blue-alt))) - `(message-cited-text-2 ((,class :foreground ,red-alt))) - `(message-cited-text-3 ((,class :foreground ,green-alt))) - `(message-cited-text-4 ((,class :foreground ,magenta-alt))) - `(message-header-cc ((,class :inherit bold :foreground ,cyan-alt))) - `(message-header-name ((,class :foreground ,green-alt-other))) - `(message-header-newsgroups ((,class :inherit bold :foreground ,green-alt))) - `(message-header-other ((,class :inherit bold :foreground ,cyan-alt-other))) - `(message-header-subject ((,class :inherit bold :foreground ,magenta-alt-other))) - `(message-header-to ((,class :inherit bold :foreground ,blue))) - `(message-header-xheader ((,class :foreground ,cyan))) - `(message-mml ((,class :foreground ,fg-special-warm))) - `(message-separator ((,class :inherit modus-theme-intense-neutral))) -;;;;; minibuffer-line - `(minibuffer-line ((,class :foreground ,fg-main))) -;;;;; minimap - `(minimap-active-region-background ((,class :background ,bg-active))) - `(minimap-current-line-face ((,class :background ,cyan-intense-bg :foreground ,fg-main))) -;;;;; modeline - `(mode-line ((,class ,@(modus-vivendi-theme-mode-line-attrs - fg-active bg-active fg-dim bg-active - fg-alt bg-active 'alt-style nil bg-main)))) - `(mode-line-buffer-id ((,class :inherit bold))) - `(mode-line-emphasis ((,class :inherit bold :foreground ,blue-active))) - `(mode-line-highlight ((,class :inherit modus-theme-active-blue :box (:line-width -1 :style pressed-button)))) - `(mode-line-inactive ((,class ,@(modus-vivendi-theme-mode-line-attrs - fg-inactive bg-inactive fg-alt bg-dim - bg-region bg-active)))) -;;;;; mood-line - `(mood-line-modified ((,class :foreground ,magenta-active))) - `(mood-line-status-error ((,class :inherit bold :foreground ,red-active))) - `(mood-line-status-info ((,class :foreground ,cyan-active))) - `(mood-line-status-neutral ((,class :foreground ,blue-active))) - `(mood-line-status-success ((,class :foreground ,green-active))) - `(mood-line-status-warning ((,class :inherit bold :foreground ,yellow-active))) - `(mood-line-unimportant ((,class :foreground ,fg-inactive))) -;;;;; mpdel - `(mpdel-browser-directory-face ((,class :foreground ,blue))) - `(mpdel-playlist-current-song-face ((,class :inherit bold :foreground ,blue-alt-other))) -;;;;; mu4e - `(mu4e-attach-number-face ((,class :inherit bold :foreground ,cyan-alt))) - `(mu4e-cited-1-face ((,class :foreground ,blue-alt))) - `(mu4e-cited-2-face ((,class :foreground ,red-alt))) - `(mu4e-cited-3-face ((,class :foreground ,green-alt))) - `(mu4e-cited-4-face ((,class :foreground ,magenta-alt))) - `(mu4e-cited-5-face ((,class :foreground ,yellow-alt))) - `(mu4e-cited-6-face ((,class :foreground ,cyan-alt))) - `(mu4e-cited-7-face ((,class :foreground ,magenta))) - `(mu4e-compose-header-face ((,class :inherit mu4e-compose-separator-face))) - `(mu4e-compose-separator-face ((,class :inherit modus-theme-intense-neutral))) - `(mu4e-contact-face ((,class :inherit bold :foreground ,cyan-alt-other))) - `(mu4e-context-face ((,class :foreground ,blue-active))) - `(mu4e-draft-face ((,class :foreground ,magenta-alt))) - `(mu4e-flagged-face ((,class :foreground ,red-alt))) - `(mu4e-footer-face ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(mu4e-forwarded-face ((,class :foreground ,magenta-alt-other))) - `(mu4e-header-face ((,class :foreground ,fg-alt))) - `(mu4e-header-highlight-face ((,class :inherit modus-theme-hl-line))) - `(mu4e-header-key-face ((,class :foreground ,cyan))) - `(mu4e-header-marks-face ((,class :inherit bold :foreground ,magenta-alt))) - `(mu4e-header-title-face ((,class :foreground ,fg-special-mild))) - `(mu4e-header-value-face ((,class :inherit bold :foreground ,magenta-alt-other))) - `(mu4e-highlight-face ((,class :inherit bold :foreground ,blue-alt-other))) - `(mu4e-link-face ((,class :inherit link))) - `(mu4e-modeline-face ((,class :foreground ,magenta-active))) - `(mu4e-moved-face ((,class :foreground ,yellow :slant ,modus-theme-slant))) - `(mu4e-ok-face ((,class :inherit bold :foreground ,green))) - `(mu4e-region-code ((,class :inherit modus-theme-special-calm))) - `(mu4e-replied-face ((,class :foreground ,blue-faint))) - `(mu4e-special-header-value-face ((,class :inherit bold :foreground ,blue-alt-other))) - `(mu4e-system-face ((,class :foreground ,fg-mark-del :slant ,modus-theme-slant))) - `(mu4e-title-face ((,class :foreground ,fg-main))) - `(mu4e-trashed-face ((,class :foreground ,red))) - `(mu4e-unread-face ((,class :inherit bold :foreground ,fg-main))) - `(mu4e-url-number-face ((,class :inherit bold :foreground ,cyan-alt-other))) - `(mu4e-view-body-face ((,class :foreground ,fg-main))) - `(mu4e-warning-face ((,class :inherit warning))) -;;;;; mu4e-conversation - `(mu4e-conversation-header ((,class :inherit modus-theme-special-cold))) - `(mu4e-conversation-sender-1 ((,class :foreground ,fg-special-warm))) - `(mu4e-conversation-sender-2 ((,class :foreground ,fg-special-cold))) - `(mu4e-conversation-sender-3 ((,class :foreground ,fg-special-mild))) - `(mu4e-conversation-sender-4 ((,class :foreground ,fg-alt))) - `(mu4e-conversation-sender-5 ((,class :foreground ,yellow-refine-fg))) - `(mu4e-conversation-sender-6 ((,class :foreground ,cyan-refine-fg))) - `(mu4e-conversation-sender-7 ((,class :foreground ,green-refine-fg))) - `(mu4e-conversation-sender-8 ((,class :foreground ,blue-refine-fg))) - `(mu4e-conversation-sender-me ((,class :foreground ,fg-main))) - `(mu4e-conversation-unread ((,class :inherit bold))) -;;;;; multiple-cursors - `(mc/cursor-bar-face ((,class :height 1 :background ,fg-main))) - `(mc/cursor-face ((,class :inverse-video t))) - `(mc/region-face ((,class :inherit region))) -;;;;; neotree - `(neo-banner-face ((,class :foreground ,magenta))) - `(neo-button-face ((,class :inherit button))) - `(neo-dir-link-face ((,class :inherit bold :foreground ,blue))) - `(neo-expand-btn-face ((,class :foreground ,cyan))) - `(neo-file-link-face ((,class :foreground ,fg-main))) - `(neo-header-face ((,class :inherit bold :foreground ,fg-main))) - `(neo-root-dir-face ((,class :inherit bold :foreground ,cyan-alt))) - `(neo-vc-added-face ((,class :foreground ,green))) - `(neo-vc-conflict-face ((,class :inherit bold :foreground ,red))) - `(neo-vc-default-face ((,class :foreground ,fg-main))) - `(neo-vc-edited-face ((,class :foreground ,yellow))) - `(neo-vc-ignored-face ((,class :foreground ,fg-inactive))) - `(neo-vc-missing-face ((,class :foreground ,red-alt))) - `(neo-vc-needs-merge-face ((,class :foreground ,magenta-alt))) - `(neo-vc-needs-update-face ((,class :underline t))) - `(neo-vc-removed-face ((,class :strike-through t))) - `(neo-vc-unlocked-changes-face ((,class :inherit modus-theme-refine-blue))) - `(neo-vc-up-to-date-face ((,class :foreground ,fg-alt))) - `(neo-vc-user-face ((,class :foreground ,magenta))) -;;;;; no-emoji - `(no-emoji ((,class :foreground ,cyan))) -;;;;; notmuch - `(notmuch-crypto-decryption ((,class :inherit modus-theme-refine-magenta))) - `(notmuch-crypto-part-header ((,class :foreground ,magenta-alt-other))) - `(notmuch-crypto-signature-bad ((,class :inherit modus-theme-intense-red))) - `(notmuch-crypto-signature-good ((,class :inherit modus-theme-refine-green))) - `(notmuch-crypto-signature-good-key ((,class :inherit modus-theme-refine-yellow))) - `(notmuch-crypto-signature-unknown ((,class :inherit modus-theme-refine-red))) - `(notmuch-hello-logo-background ((,class :background ,bg-main))) - `(notmuch-message-summary-face ((,class :inherit modus-theme-nuanced-cyan))) - `(notmuch-search-flagged-face ((,class :foreground ,red-alt))) - `(notmuch-search-matching-authors ((,class :foreground ,fg-main))) - `(notmuch-search-non-matching-authors ((,class :foreground ,fg-alt))) - `(notmuch-search-unread-face ((,class :inherit bold))) - `(notmuch-tag-added - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,green :style wave)) - (,class :foreground ,green :underline t))) - `(notmuch-tag-deleted - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,red :style wave)) - (,class :foreground ,red :underline t))) - `(notmuch-tag-face ((,class :inherit bold :foreground ,blue-alt))) - `(notmuch-tag-flagged ((,class :foreground ,red-alt))) - `(notmuch-tag-unread ((,class :foreground ,magenta-alt))) - `(notmuch-tree-match-author-face ((,class :foreground ,fg-special-cold))) - `(notmuch-tree-match-face ((,class :foreground ,fg-main))) - `(notmuch-tree-match-tag-face ((,class :inherit bold :foreground ,blue-alt))) - `(notmuch-tree-no-match-face ((,class :foreground ,fg-alt))) - `(notmuch-wash-cited-text ((,class :foreground ,cyan))) - `(notmuch-wash-toggle-button ((,class :background ,bg-alt :foreground ,fg-alt))) -;;;;; num3-mode - `(num3-face-even ((,class :inherit bold :background ,bg-alt))) -;;;;; nxml-mode - `(nxml-attribute-colon ((,class :foreground ,fg-main))) - `(nxml-attribute-local-name ((,class ,@(modus-vivendi-theme-syntax-foreground - cyan-alt cyan-alt-faint)))) - `(nxml-attribute-prefix ((,class ,@(modus-vivendi-theme-syntax-foreground - cyan-alt-other cyan-alt-other-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(nxml-attribute-value ((,class ,@(modus-vivendi-theme-syntax-foreground - blue blue-faint)))) - `(nxml-cdata-section-CDATA ((,class ,@(modus-vivendi-theme-syntax-foreground - red-alt red-alt-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(nxml-cdata-section-delimiter ((,class ,@(modus-vivendi-theme-syntax-foreground - red-alt red-alt-faint)))) - `(nxml-char-ref-delimiter ((,class ,@(modus-vivendi-theme-syntax-foreground - green-alt-other green-alt-other-faint)))) - `(nxml-char-ref-number ((,class ,@(modus-vivendi-theme-syntax-foreground - green-alt-other green-alt-other-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(nxml-delimited-data ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(nxml-delimiter ((,class :foreground ,fg-dim))) - `(nxml-element-colon ((,class :foreground ,fg-main))) - `(nxml-element-local-name ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta magenta-faint)))) - `(nxml-element-prefix ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(nxml-entity-ref-delimiter ((,class ,@(modus-vivendi-theme-syntax-foreground - green-alt-other green-alt-other-faint)))) - `(nxml-entity-ref-name ((,class ,@(modus-vivendi-theme-syntax-foreground - green-alt-other green-alt-other-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(nxml-glyph ((,class :inherit modus-theme-intense-neutral))) - `(nxml-hash ((,class ,@(modus-vivendi-theme-syntax-foreground - blue-alt blue-alt-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(nxml-heading ((,class :inherit bold))) - `(nxml-name ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(nxml-namespace-attribute-colon ((,class :foreground ,fg-main))) - `(nxml-namespace-attribute-prefix ((,class ,@(modus-vivendi-theme-syntax-foreground - cyan cyan-faint)))) - `(nxml-processing-instruction-target ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt-other magenta-alt-other-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(nxml-prolog-keyword ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt-other magenta-alt-other-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(nxml-ref ((,class ,@(modus-vivendi-theme-syntax-foreground - green-alt-other green-alt-other-faint) - ,@(modus-vivendi-theme-bold-weight)))) -;;;;; objed - `(objed-hl ((,class :background ,(if modus-vivendi-theme-intense-hl-line - bg-hl-alt-intense bg-hl-alt)))) - `(objed-mark ((,class :background ,bg-active))) - `(objed-mode-line ((,class :foreground ,cyan-active))) -;;;;; orderless - `(orderless-match-face-0 ((,class :inherit bold - ,@(modus-vivendi-theme-standard-completions - blue-alt-other blue-nuanced-bg - blue-refine-bg blue-refine-fg)))) - `(orderless-match-face-1 ((,class :inherit bold - ,@(modus-vivendi-theme-standard-completions - magenta-alt magenta-nuanced-bg - magenta-refine-bg magenta-refine-fg)))) - `(orderless-match-face-2 ((,class :inherit bold - ,@(modus-vivendi-theme-standard-completions - green green-nuanced-bg - green-refine-bg green-refine-fg)))) - `(orderless-match-face-3 ((,class :inherit bold - ,@(modus-vivendi-theme-standard-completions - yellow yellow-nuanced-bg - yellow-refine-bg yellow-refine-fg)))) -;;;;; org - `(org-agenda-calendar-event ((,class :foreground ,fg-main))) - `(org-agenda-calendar-sexp ((,class :foreground ,cyan-alt))) - `(org-agenda-clocking ((,class :inherit modus-theme-special-cold - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(org-agenda-column-dateline ((,class :background ,bg-alt))) - `(org-agenda-current-time ((,class :inherit bold :foreground ,blue-alt-other))) - `(org-agenda-date ((,class :foreground ,cyan))) - `(org-agenda-date-today ((,class :inherit bold :foreground ,fg-main :underline t))) - `(org-agenda-date-weekend ((,class :foreground ,cyan-alt-other))) - `(org-agenda-diary ((,class :foreground ,fg-main))) - `(org-agenda-dimmed-todo-face ((,class :inherit bold :foreground ,fg-alt))) - `(org-agenda-done ((,class :foreground ,green-alt))) - `(org-agenda-filter-category ((,class :inherit bold :foreground ,magenta-active))) - `(org-agenda-filter-effort ((,class :inherit bold :foreground ,magenta-active))) - `(org-agenda-filter-regexp ((,class :inherit bold :foreground ,magenta-active))) - `(org-agenda-filter-tags ((,class :inherit bold :foreground ,magenta-active))) - `(org-agenda-restriction-lock ((,class :background ,bg-dim :foreground ,fg-dim))) - `(org-agenda-structure ((,class :foreground ,blue-alt))) - `(org-archived ((,class :background ,bg-alt :foreground ,fg-alt))) - `(org-block ((,class ,@(modus-vivendi-theme-mixed-fonts) - ,@(modus-vivendi-theme-org-block bg-dim) - :foreground ,fg-main))) - `(org-block-begin-line ((,class ,@(modus-vivendi-theme-mixed-fonts) - ,@(modus-vivendi-theme-org-block-delim - bg-dim fg-special-cold - bg-alt fg-special-mild)))) - `(org-block-end-line ((,class :inherit org-block-begin-line))) - `(org-checkbox ((,class :box (:line-width 1 :color ,bg-active) - :background ,bg-inactive :foreground ,fg-active))) - `(org-checkbox-statistics-done ((,class :inherit org-done))) - `(org-checkbox-statistics-todo ((,class :inherit org-todo))) - `(org-clock-overlay ((,class :inherit modus-theme-special-cold))) - `(org-code ((,class ,@(modus-vivendi-theme-mixed-fonts) :foreground ,magenta))) - `(org-column ((,class :background ,bg-alt))) - `(org-column-title ((,class :inherit bold :underline t :background ,bg-alt))) - `(org-date ((,class :inherit (button fixed-pitch) :foreground ,cyan-alt-other))) - `(org-date-selected ((,class :inherit bold :foreground ,blue-alt :inverse-video t))) - `(org-document-info ((,class :foreground ,fg-special-cold))) - `(org-document-info-keyword ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,fg-alt))) - `(org-document-title ((,class :inherit (bold ,modus-theme-variable-pitch) :foreground ,fg-special-cold - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-5)))) - `(org-done ((,class :box ,bg-region :background ,bg-dim :foreground ,green))) - `(org-drawer ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,cyan))) - `(org-ellipsis ((,class :foreground nil))) ; inherits from the heading's colour - `(org-footnote ((,class :inherit button :foreground ,blue-alt))) - `(org-formula ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,red-alt))) - `(org-habit-alert-face ((,class :inherit modus-theme-intense-yellow))) - `(org-habit-alert-future-face ((,class :inherit modus-theme-refine-yellow))) - `(org-habit-clear-face ((,class :inherit modus-theme-intense-magenta))) - `(org-habit-clear-future-face ((,class :inherit modus-theme-refine-magenta))) - `(org-habit-overdue-face ((,class :inherit modus-theme-intense-red))) - `(org-habit-overdue-future-face ((,class :inherit modus-theme-refine-red))) - `(org-habit-ready-face ((,class :inherit modus-theme-intense-blue))) - `(org-habit-ready-future-face ((,class :inherit modus-theme-refine-blue))) - `(org-headline-done ((,class :inherit ,modus-theme-variable-pitch :foreground ,green-nuanced))) - `(org-headline-todo ((,class :inherit ,modus-theme-variable-pitch :foreground ,red-nuanced))) - `(org-hide ((,class :foreground ,bg-main))) - `(org-indent ((,class :inherit (fixed-pitch org-hide)))) - `(org-latex-and-related ((,class :foreground ,magenta-refine-fg))) - `(org-level-1 ((,class :inherit modus-theme-heading-1))) - `(org-level-2 ((,class :inherit modus-theme-heading-2))) - `(org-level-3 ((,class :inherit modus-theme-heading-3))) - `(org-level-4 ((,class :inherit modus-theme-heading-4))) - `(org-level-5 ((,class :inherit modus-theme-heading-5))) - `(org-level-6 ((,class :inherit modus-theme-heading-6))) - `(org-level-7 ((,class :inherit modus-theme-heading-7))) - `(org-level-8 ((,class :inherit modus-theme-heading-8))) - `(org-link ((,class :inherit link))) - `(org-list-dt ((,class :inherit bold))) - `(org-macro ((,class :background ,blue-nuanced-bg :foreground ,magenta-alt-other))) - `(org-meta-line ((,class ,@(modus-vivendi-theme-mixed-fonts) :foreground ,fg-alt))) - `(org-mode-line-clock ((,class :foreground ,fg-main))) - `(org-mode-line-clock-overrun ((,class :inherit modus-theme-active-red))) - `(org-priority ((,class :box ,bg-region :background ,bg-dim :foreground ,magenta))) - `(org-property-value ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,cyan-alt-other))) - `(org-quote ((,class ,@(modus-vivendi-theme-org-block bg-dim) - :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(org-scheduled ((,class :foreground ,fg-special-warm))) - `(org-scheduled-previously ((,class :foreground ,yellow-alt-other))) - `(org-scheduled-today ((,class :foreground ,magenta-alt-other))) - `(org-sexp-date ((,class :inherit org-date))) - `(org-special-keyword ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,blue-nuanced))) - `(org-table ((,class ,@(modus-vivendi-theme-mixed-fonts) - :foreground ,fg-special-cold))) - `(org-table-header ((,class :inherit (fixed-pitch modus-theme-intense-neutral)))) - `(org-tag ((,class :foreground ,magenta-nuanced))) - `(org-tag-group ((,class :inherit bold :foreground ,cyan-nuanced))) - `(org-target ((,class :underline t))) - `(org-time-grid ((,class :foreground ,fg-unfocused))) - `(org-todo ((,class :box ,bg-region :background ,bg-dim :foreground ,red-alt))) - `(org-upcoming-deadline ((,class :foreground ,red-alt-other))) - `(org-upcoming-distant-deadline ((,class :foreground ,red-nuanced))) - `(org-verbatim ((,class ,@(modus-vivendi-theme-mixed-fonts) - :background ,bg-alt :foreground ,fg-special-calm))) - `(org-verse ((,class :inherit org-quote))) - `(org-warning ((,class :inherit bold :foreground ,red-alt-other))) -;;;;; org-journal - `(org-journal-calendar-entry-face ((,class :foreground ,yellow-alt-other :slant ,modus-theme-slant))) - `(org-journal-calendar-scheduled-face ((,class :foreground ,red-alt-other :slant ,modus-theme-slant))) - `(org-journal-highlight ((,class :foreground ,magenta-alt))) -;;;;; org-noter - `(org-noter-no-notes-exist-face ((,class :inherit bold :foreground ,red-active))) - `(org-noter-notes-exist-face ((,class :inherit bold :foreground ,green-active))) -;;;;; org-pomodoro - `(org-pomodoro-mode-line ((,class :foreground ,red-active))) - `(org-pomodoro-mode-line-break ((,class :foreground ,cyan-active))) - `(org-pomodoro-mode-line-overtime ((,class :inherit bold :foreground ,red-active))) -;;;;; org-recur - `(org-recur ((,class :foreground ,magenta-active))) -;;;;; org-roam - `(org-roam-link ((,class :inherit button :foreground ,green))) - `(org-roam-link-current ((,class :inherit button :foreground ,green-alt))) - `(org-roam-link-invalid ((,class :inherit button :foreground ,red))) - `(org-roam-link-shielded ((,class :inherit button :foreground ,yellow))) - `(org-roam-tag ((,class :foreground ,fg-alt :slant italic))) -;;;;; org-superstar - `(org-superstar-item ((,class :foreground ,fg-main))) - `(org-superstar-leading ((,class :foreground ,fg-whitespace))) -;;;;; org-table-sticky-header - `(org-table-sticky-header-face ((,class :inherit modus-theme-intense-neutral))) -;;;;; org-treescope - `(org-treescope-faces--markerinternal-midday ((,class :inherit modus-theme-intense-blue))) - `(org-treescope-faces--markerinternal-range ((,class :inherit modus-theme-special-mild))) -;;;;; origami - `(origami-fold-header-face ((,class :background ,bg-dim :foreground ,fg-dim :box t))) - `(origami-fold-replacement-face ((,class :background ,bg-alt :foreground ,fg-alt))) -;;;;; outline-mode - `(outline-1 ((,class :inherit modus-theme-heading-1))) - `(outline-2 ((,class :inherit modus-theme-heading-2))) - `(outline-3 ((,class :inherit modus-theme-heading-3))) - `(outline-4 ((,class :inherit modus-theme-heading-4))) - `(outline-5 ((,class :inherit modus-theme-heading-5))) - `(outline-6 ((,class :inherit modus-theme-heading-6))) - `(outline-7 ((,class :inherit modus-theme-heading-7))) - `(outline-8 ((,class :inherit modus-theme-heading-8))) -;;;;; outline-minor-faces - `(outline-minor-0 ((,class nil))) -;;;;; package (M-x list-packages) - `(package-description ((,class :foreground ,fg-special-cold))) - `(package-help-section-name ((,class :inherit bold :foreground ,magenta-alt-other))) - `(package-name ((,class :inherit link))) - `(package-status-avail-obso ((,class :inherit bold :foreground ,red))) - `(package-status-available ((,class :foreground ,fg-special-mild))) - `(package-status-built-in ((,class :foreground ,magenta))) - `(package-status-dependency ((,class :foreground ,magenta-alt-other))) - `(package-status-disabled ((,class :inherit modus-theme-subtle-red))) - `(package-status-external ((,class :foreground ,cyan-alt-other))) - `(package-status-held ((,class :foreground ,yellow-alt))) - `(package-status-incompat ((,class :inherit bold :foreground ,yellow))) - `(package-status-installed ((,class :foreground ,fg-special-warm))) - `(package-status-new ((,class :inherit bold :foreground ,green))) - `(package-status-unsigned ((,class :inherit bold :foreground ,red-alt))) -;;;;; page-break-lines - `(page-break-lines ((,class :inherit default :foreground ,fg-window-divider-outer))) -;;;;; paradox - `(paradox-archive-face ((,class :foreground ,fg-special-mild))) - `(paradox-comment-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(paradox-commit-tag-face ((,class :inherit modus-theme-refine-magenta :box t))) - `(paradox-description-face ((,class :foreground ,fg-special-cold))) - `(paradox-description-face-multiline ((,class :foreground ,fg-special-cold))) - `(paradox-download-face ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,blue-alt-other))) - `(paradox-highlight-face ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,cyan-alt-other))) - `(paradox-homepage-button-face ((,class :foreground ,magenta-alt-other :underline t))) - `(paradox-mode-line-face ((,class :inherit bold :foreground ,cyan-active))) - `(paradox-name-face ((,class :foreground ,blue :underline t))) - `(paradox-star-face ((,class :foreground ,magenta))) - `(paradox-starred-face ((,class :foreground ,magenta-alt))) -;;;;; paren-face - `(parenthesis ((,class :foreground ,fg-unfocused))) -;;;;; parrot - `(parrot-rotate-rotation-highlight-face ((,class :inherit modus-theme-refine-magenta))) -;;;;; pass - `(pass-mode-directory-face ((,class :inherit bold :foreground ,fg-special-cold))) - `(pass-mode-entry-face ((,class :background ,bg-main :foreground ,fg-main))) - `(pass-mode-header-face ((,class :foreground ,fg-special-warm))) -;;;;; persp-mode - `(persp-face-lighter-buffer-not-in-persp ((,class :inherit modus-theme-intense-red))) - `(persp-face-lighter-default ((,class :inherit bold :foreground ,blue-active))) - `(persp-face-lighter-nil-persp ((,class :inherit bold :foreground ,fg-active))) -;;;;; perspective - `(persp-selected-face ((,class :inherit bold :foreground ,blue-active))) -;;;;; phi-grep - `(phi-grep-heading-face ((,class :inherit bold :foreground ,red-alt - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-4)))) - `(phi-grep-line-number-face ((,class :foreground ,fg-special-warm))) - `(phi-grep-match-face ((,class :inherit modus-theme-special-calm))) - `(phi-grep-modified-face ((,class :inherit modus-theme-refine-yellow))) - `(phi-grep-overlay-face ((,class :inherit modus-theme-refine-blue))) -;;;;; phi-search - `(phi-replace-preview-face ((,class :inherit modus-theme-intense-magenta))) - `(phi-search-failpart-face ((,class :inherit modus-theme-refine-red))) - `(phi-search-match-face ((,class :inherit modus-theme-refine-cyan))) - `(phi-search-selection-face ((,class :inherit (modus-theme-intense-green bold)))) -;;;;; pkgbuild-mode - `(pkgbuild-error-face ((,class :underline ,fg-lang-error))) -;;;;; pomidor - `(pomidor-break-face ((,class :foreground ,blue-alt-other))) - `(pomidor-overwork-face ((,class :foreground ,red-alt-other))) - `(pomidor-skip-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(pomidor-work-face ((,class :foreground ,green-alt-other))) -;;;;; powerline - `(powerline-active0 ((,class :background ,bg-main :foreground ,blue-faint :inverse-video t))) - `(powerline-active1 ((,class :background ,blue-nuanced-bg :foreground ,blue-nuanced))) - `(powerline-active2 ((,class :background ,bg-active :foreground ,fg-active))) - `(powerline-inactive0 ((,class :background ,bg-special-cold :foreground ,fg-special-cold))) - `(powerline-inactive1 ((,class :background ,bg-dim :foreground ,fg-inactive))) - `(powerline-inactive2 ((,class :background ,bg-inactive :foreground ,fg-inactive))) -;;;;; powerline-evil - `(powerline-evil-base-face ((,class :background ,fg-main :foreground ,bg-main))) - `(powerline-evil-emacs-face ((,class :inherit modus-theme-active-magenta))) - `(powerline-evil-insert-face ((,class :inherit modus-theme-active-green))) - `(powerline-evil-motion-face ((,class :inherit modus-theme-active-blue))) - `(powerline-evil-normal-face ((,class :background ,fg-alt :foreground ,bg-main))) - `(powerline-evil-operator-face ((,class :inherit modus-theme-active-yellow))) - `(powerline-evil-replace-face ((,class :inherit modus-theme-active-red))) - `(powerline-evil-visual-face ((,class :inherit modus-theme-active-cyan))) -;;;;; proced - `(proced-mark ((,class :inherit modus-theme-mark-symbol))) - `(proced-marked ((,class :inherit modus-theme-mark-alt))) - `(proced-sort-header ((,class :inherit bold :foreground ,fg-special-calm :underline t))) -;;;;; prodigy - `(prodigy-green-face ((,class :foreground ,green))) - `(prodigy-red-face ((,class :foreground ,red))) - `(prodigy-yellow-face ((,class :foreground ,yellow))) -;;;;; racket-mode - `(racket-debug-break-face ((,class :inherit modus-theme-intense-red))) - `(racket-debug-locals-face ((,class :box (:line-width -1 :color nil) - :foreground ,green-alt-other))) - `(racket-debug-result-face ((,class :inherit bold :box (:line-width -1 :color nil) - :foreground ,green))) - `(racket-here-string-face ((,class :foreground ,blue-alt))) - `(racket-keyword-argument-face ((,class :foreground ,red-alt))) - `(racket-logger-config-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(racket-logger-debug-face ((,class :foreground ,blue-alt-other))) - `(racket-logger-info-face ((,class :foreground ,fg-lang-note))) - `(racket-logger-topic-face ((,class :foreground ,magenta :slant ,modus-theme-slant))) - `(racket-selfeval-face ((,class :foreground ,green-alt))) - `(racket-xp-error-face - ((,(append '((supports :underline (:style wave))) class) - :underline (:color ,fg-lang-error :style wave)) - (,class :foreground ,fg-lang-error :underline t))) -;;;;; rainbow-blocks - `(rainbow-blocks-depth-1-face ((,class :foreground ,magenta-alt-other))) - `(rainbow-blocks-depth-2-face ((,class :foreground ,blue))) - `(rainbow-blocks-depth-3-face ((,class :foreground ,magenta-alt))) - `(rainbow-blocks-depth-4-face ((,class :foreground ,green))) - `(rainbow-blocks-depth-5-face ((,class :foreground ,magenta))) - `(rainbow-blocks-depth-6-face ((,class :foreground ,cyan))) - `(rainbow-blocks-depth-7-face ((,class :foreground ,yellow))) - `(rainbow-blocks-depth-8-face ((,class :foreground ,cyan-alt))) - `(rainbow-blocks-depth-9-face ((,class :foreground ,red-alt))) - `(rainbow-blocks-unmatched-face ((,class :foreground ,red))) -;;;;; rainbow-identifiers - `(rainbow-identifiers-identifier-1 ((,class :foreground ,green-alt-other))) - `(rainbow-identifiers-identifier-2 ((,class :foreground ,magenta-alt-other))) - `(rainbow-identifiers-identifier-3 ((,class :foreground ,cyan-alt-other))) - `(rainbow-identifiers-identifier-4 ((,class :foreground ,yellow-alt-other))) - `(rainbow-identifiers-identifier-5 ((,class :foreground ,blue-alt-other))) - `(rainbow-identifiers-identifier-6 ((,class :foreground ,green-alt))) - `(rainbow-identifiers-identifier-7 ((,class :foreground ,magenta-alt))) - `(rainbow-identifiers-identifier-8 ((,class :foreground ,cyan-alt))) - `(rainbow-identifiers-identifier-9 ((,class :foreground ,yellow-alt))) - `(rainbow-identifiers-identifier-10 ((,class :foreground ,green))) - `(rainbow-identifiers-identifier-11 ((,class :foreground ,magenta))) - `(rainbow-identifiers-identifier-12 ((,class :foreground ,cyan))) - `(rainbow-identifiers-identifier-13 ((,class :foreground ,yellow))) - `(rainbow-identifiers-identifier-14 ((,class :foreground ,blue-alt))) - `(rainbow-identifiers-identifier-15 ((,class :foreground ,red-alt))) -;;;;; rainbow-delimiters - `(rainbow-delimiters-base-face-error ((,class :foreground ,red))) - `(rainbow-delimiters-base-face ((,class :foreground ,fg-main))) - `(rainbow-delimiters-depth-1-face ((,class :foreground ,green-alt-other))) - `(rainbow-delimiters-depth-2-face ((,class :foreground ,magenta-alt-other))) - `(rainbow-delimiters-depth-3-face ((,class :foreground ,cyan-alt-other))) - `(rainbow-delimiters-depth-4-face ((,class :foreground ,yellow-alt-other))) - `(rainbow-delimiters-depth-5-face ((,class :foreground ,blue-alt-other))) - `(rainbow-delimiters-depth-6-face ((,class :foreground ,green-alt))) - `(rainbow-delimiters-depth-7-face ((,class :foreground ,magenta-alt))) - `(rainbow-delimiters-depth-8-face ((,class :foreground ,cyan-alt))) - `(rainbow-delimiters-depth-9-face ((,class :foreground ,yellow-alt))) - `(rainbow-delimiters-mismatched-face ((,class :inherit bold :foreground ,red-alt))) - `(rainbow-delimiters-unmatched-face ((,class :inherit bold :foreground ,red))) -;;;;; rcirc - `(rcirc-bright-nick ((,class :inherit bold :foreground ,magenta-alt))) - `(rcirc-dim-nick ((,class :foreground ,fg-alt))) - `(rcirc-my-nick ((,class :inherit bold :foreground ,magenta))) - `(rcirc-nick-in-message ((,class :foreground ,magenta-alt-other))) - `(rcirc-nick-in-message-full-line ((,class :inherit bold :foreground ,fg-special-mild))) - `(rcirc-other-nick ((,class :inherit bold :foreground ,fg-special-cold))) - `(rcirc-prompt ((,class :inherit bold :foreground ,cyan-alt-other))) - `(rcirc-server ((,class :foreground ,fg-unfocused))) - `(rcirc-timestamp ((,class :foreground ,blue-nuanced))) - `(rcirc-url ((,class :foreground ,blue :underline t))) -;;;;; regexp-builder (re-builder) - `(reb-match-0 ((,class :inherit modus-theme-intense-blue))) - `(reb-match-1 ((,class :inherit modus-theme-intense-magenta))) - `(reb-match-2 ((,class :inherit modus-theme-intense-green))) - `(reb-match-3 ((,class :inherit modus-theme-intense-red))) - `(reb-regexp-grouping-backslash ((,class :inherit bold :foreground ,fg-escape-char-backslash))) - `(reb-regexp-grouping-construct ((,class :inherit bold :foreground ,fg-escape-char-construct))) -;;;;; rg (rg.el) - `(rg-column-number-face ((,class :foreground ,magenta-alt-other))) - `(rg-context-face ((,class :foreground ,fg-unfocused))) - `(rg-error-face ((,class :inherit bold :foreground ,red))) - `(rg-file-tag-face ((,class :foreground ,fg-special-cold))) - `(rg-filename-face ((,class :inherit bold :foreground ,fg-special-cold))) - `(rg-line-number-face ((,class :foreground ,fg-special-warm))) - `(rg-literal-face ((,class :foreground ,blue-alt))) - `(rg-match-face ((,class :inherit modus-theme-special-calm))) - `(rg-regexp-face ((,class :foreground ,magenta-active))) - `(rg-toggle-off-face ((,class :inherit bold :foreground ,fg-inactive))) - `(rg-toggle-on-face ((,class :inherit bold :foreground ,cyan-active))) - `(rg-warning-face ((,class :inherit bold :foreground ,yellow))) -;;;;; ripgrep - `(ripgrep-context-face ((,class :foreground ,fg-unfocused))) - `(ripgrep-error-face ((,class :inherit bold :foreground ,red))) - `(ripgrep-hit-face ((,class :foreground ,cyan))) - `(ripgrep-match-face ((,class :inherit modus-theme-special-calm))) -;;;;; rmail - `(rmail-header-name ((,class :foreground ,cyan-alt-other))) - `(rmail-highlight ((,class :inherit bold :foreground ,magenta-alt))) -;;;;; ruler-mode - `(ruler-mode-column-number ((,class :inherit (ruler-mode-default bold) :foreground ,fg-main))) - `(ruler-mode-comment-column ((,class :inherit ruler-mode-default :foreground ,red-active))) - `(ruler-mode-current-column ((,class :inherit ruler-mode-default :foreground ,cyan-active :box t))) - `(ruler-mode-default ((,class :background ,bg-inactive :foreground ,fg-inactive))) - `(ruler-mode-fill-column ((,class :inherit ruler-mode-default :foreground ,green-active))) - `(ruler-mode-fringes ((,class :inherit ruler-mode-default :foreground ,blue-active))) - `(ruler-mode-goal-column ((,class :inherit ruler-mode-default :foreground ,magenta-active))) - `(ruler-mode-margins ((,class :inherit ruler-mode-default :foreground ,bg-main))) - `(ruler-mode-pad ((,class :background ,bg-active :foreground ,fg-inactive))) - `(ruler-mode-tab-stop ((,class :inherit ruler-mode-default :foreground ,yellow-active))) -;;;;; sallet - `(sallet-buffer-compressed ((,class :foreground ,yellow-nuanced :slant italic))) - `(sallet-buffer-default-directory ((,class :foreground ,cyan-nuanced))) - `(sallet-buffer-directory ((,class :foreground ,blue-nuanced))) - `(sallet-buffer-help ((,class :foreground ,fg-special-cold))) - `(sallet-buffer-modified ((,class :foreground ,yellow-alt-other :slant italic))) - `(sallet-buffer-ordinary ((,class :foreground ,fg-main))) - `(sallet-buffer-read-only ((,class :foreground ,yellow-alt))) - `(sallet-buffer-size ((,class :foreground ,fg-special-calm))) - `(sallet-buffer-special ((,class :foreground ,magenta-alt-other))) - `(sallet-flx-match ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-cyan - 'modus-theme-refine-cyan - 'modus-theme-nuanced-cyan - cyan-alt-other)))) - `(sallet-recentf-buffer-name ((,class :foreground ,blue-nuanced))) - `(sallet-recentf-file-path ((,class :foreground ,fg-special-mild))) - `(sallet-regexp-match ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-magenta - 'modus-theme-refine-magenta - 'modus-theme-nuanced-magenta - magenta-alt-other)))) - `(sallet-source-header ((,class :inherit bold :foreground ,red-alt - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-4)))) - `(sallet-substring-match ((,class ,@(modus-vivendi-theme-extra-completions - 'modus-theme-subtle-blue - 'modus-theme-refine-blue - 'modus-theme-nuanced-blue - blue-alt-other)))) -;;;;; selectrum - `(selectrum-current-candidate - ((,class :inherit bold :foreground ,fg-main :underline ,fg-main - :background ,@(pcase modus-vivendi-theme-completions - ('opinionated (list bg-active)) - (_ (list bg-inactive)))))) - `(selectrum-primary-highlight ((,class :inherit bold - ,@(modus-vivendi-theme-standard-completions - magenta-alt magenta-nuanced-bg - magenta-refine-bg magenta-refine-fg)))) - `(selectrum-secondary-highlight ((,class :inherit bold - ,@(modus-vivendi-theme-standard-completions - cyan-alt-other cyan-nuanced-bg - cyan-refine-bg cyan-refine-fg)))) -;;;;; semantic - `(semantic-complete-inline-face ((,class :foreground ,fg-special-warm :underline t))) - `(semantic-decoration-on-private-members-face ((,class :inherit modus-theme-refine-cyan))) - `(semantic-decoration-on-protected-members-face ((,class :background ,bg-dim))) - `(semantic-highlight-edits-face ((,class :background ,bg-alt))) - `(semantic-highlight-func-current-tag-face ((,class :background ,bg-alt))) - `(semantic-idle-symbol-highlight ((,class :inherit modus-theme-special-mild))) - `(semantic-tag-boundary-face ((,class :overline ,blue-intense))) - `(semantic-unmatched-syntax-face ((,class :underline ,fg-lang-error))) -;;;;; sesman - `(sesman-browser-button-face ((,class :foreground ,blue-alt-other :underline t))) - `(sesman-browser-highligh-face ((,class :inherit modus-theme-subtle-blue))) - `(sesman-buffer-face ((,class :foreground ,magenta))) - `(sesman-directory-face ((,class :inherit bold :foreground ,blue))) - `(sesman-project-face ((,class :inherit bold :foreground ,magenta-alt-other))) -;;;;; shell-script-mode - `(sh-heredoc ((,class :foreground ,blue-alt))) - `(sh-quoted-exec ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,magenta-alt))) -;;;;; show-paren-mode - `(show-paren-match ((,class ,@(modus-vivendi-theme-paren bg-paren-match - bg-paren-match-intense) - :foreground ,fg-main))) - `(show-paren-match-expression ((,class :inherit modus-theme-special-calm))) - `(show-paren-mismatch ((,class :inherit modus-theme-intense-red))) -;;;;; side-notes - `(side-notes ((,class :background ,bg-dim :foreground ,fg-dim))) -;;;;; skewer-mode - `(skewer-error-face ((,class :foreground ,red :underline t))) -;;;;; smart-mode-line - `(sml/charging ((,class :foreground ,green-active))) - `(sml/discharging ((,class :foreground ,red-active))) - `(sml/filename ((,class :inherit bold :foreground ,blue-active))) - `(sml/folder ((,class :foreground ,fg-active))) - `(sml/git ((,class :inherit bold :foreground ,green-active))) - `(sml/global ((,class :foreground ,fg-active))) - `(sml/line-number ((,class :inherit sml/global))) - `(sml/minor-modes ((,class :inherit sml/global))) - `(sml/modes ((,class :inherit bold :foreground ,fg-active))) - `(sml/modified ((,class :inherit bold :foreground ,magenta-active))) - `(sml/mule-info ((,class :inherit sml/global))) - `(sml/name-filling ((,class :foreground ,yellow-active))) - `(sml/not-modified ((,class :inherit sml/global))) - `(sml/numbers-separator ((,class :inherit sml/global))) - `(sml/outside-modified ((,class :inherit modus-theme-intense-red))) - `(sml/position-percentage ((,class :inherit sml/global))) - `(sml/prefix ((,class :foreground ,green-active))) - `(sml/process ((,class :inherit sml/prefix))) - `(sml/projectile ((,class :inherit sml/git))) - `(sml/read-only ((,class :inherit bold :foreground ,cyan-active))) - `(sml/remote ((,class :inherit sml/global))) - `(sml/sudo ((,class :inherit modus-theme-subtle-red))) - `(sml/time ((,class :inherit sml/global))) - `(sml/vc ((,class :inherit sml/git))) - `(sml/vc-edited ((,class :inherit bold :foreground ,yellow-active))) -;;;;; smartparens - `(sp-pair-overlay-face ((,class :inherit modus-theme-special-warm))) - `(sp-show-pair-enclosing ((,class :inherit modus-theme-special-mild))) - `(sp-show-pair-match-face ((,class ,@(modus-vivendi-theme-paren bg-paren-match - bg-paren-match-intense) - :foreground ,fg-main))) - `(sp-show-pair-mismatch-face ((,class :inherit modus-theme-intense-red))) - `(sp-wrap-overlay-closing-pair ((,class :inherit sp-pair-overlay-face))) - `(sp-wrap-overlay-face ((,class :inherit sp-pair-overlay-face))) - `(sp-wrap-overlay-opening-pair ((,class :inherit sp-pair-overlay-face))) - `(sp-wrap-tag-overlay-face ((,class :inherit sp-pair-overlay-face))) -;;;;; smerge - `(smerge-base ((,class :inherit modus-theme-diff-changed))) - `(smerge-lower ((,class :inherit modus-theme-diff-added))) - `(smerge-markers ((,class :background ,bg-diff-neutral-2 :foreground ,fg-diff-neutral-2))) - `(smerge-refined-added ((,class :inherit modus-theme-diff-refine-added))) - `(smerge-refined-changed ((,class))) - `(smerge-refined-removed ((,class :inherit modus-theme-diff-refine-removed))) - `(smerge-upper ((,class :inherit modus-theme-diff-removed))) -;;;;; spaceline - `(spaceline-evil-emacs ((,class :inherit modus-theme-active-magenta))) - `(spaceline-evil-insert ((,class :inherit modus-theme-active-green))) - `(spaceline-evil-motion ((,class :inherit modus-theme-active-blue))) - `(spaceline-evil-normal ((,class :background ,fg-alt :foreground ,bg-alt))) - `(spaceline-evil-replace ((,class :inherit modus-theme-active-red))) - `(spaceline-evil-visual ((,class :inherit modus-theme-active-cyan))) - `(spaceline-flycheck-error ((,class :foreground ,red-active))) - `(spaceline-flycheck-info ((,class :foreground ,cyan-active))) - `(spaceline-flycheck-warning ((,class :foreground ,yellow-active))) - `(spaceline-highlight-face ((,class :inherit modus-theme-fringe-blue))) - `(spaceline-modified ((,class :inherit modus-theme-fringe-magenta))) - `(spaceline-python-venv ((,class :foreground ,magenta-active))) - `(spaceline-read-only ((,class :inherit modus-theme-fringe-red))) - `(spaceline-unmodified ((,class :inherit modus-theme-fringe-cyan))) -;;;;; speedbar - `(speedbar-button-face ((,class :inherit link))) - `(speedbar-directory-face ((,class :inherit bold :foreground ,blue))) - `(speedbar-file-face ((,class :foreground ,fg-main))) - `(speedbar-highlight-face ((,class :inherit modus-theme-subtle-blue))) - `(speedbar-selected-face ((,class :inherit bold :foreground ,cyan))) - `(speedbar-separator-face ((,class :inherit modus-theme-intense-neutral))) - `(speedbar-tag-face ((,class :foreground ,yellow-alt-other))) -;;;;; spell-fu - `(spell-fu-incorrect-face - ((,(append '((supports :underline (:style wave))) class) - :foreground ,fg-lang-error :underline (:style wave)) - (,class :foreground ,fg-lang-error :underline t))) -;;;;; stripes - `(stripes ((,class :inherit modus-theme-hl-line))) -;;;;; success - `(suggest-heading ((,class :inherit bold :foreground ,yellow-alt-other))) -;;;;; switch-window - `(switch-window-background ((,class :background ,bg-dim))) - `(switch-window-label ((,class :height 3.0 :foreground ,blue-intense))) -;;;;; swiper - `(swiper-background-match-face-1 ((,class :inherit modus-theme-subtle-neutral))) - `(swiper-background-match-face-2 ((,class :inherit modus-theme-subtle-cyan))) - `(swiper-background-match-face-3 ((,class :inherit modus-theme-subtle-magenta))) - `(swiper-background-match-face-4 ((,class :inherit modus-theme-subtle-green))) - `(swiper-line-face ((,class ,@(and (>= emacs-major-version 27) '(:extend t)) - :inherit modus-theme-special-cold))) - `(swiper-match-face-1 ((,class :inherit swiper-line-face))) - `(swiper-match-face-2 ((,class :inherit swiper-line-face))) - `(swiper-match-face-3 ((,class :inherit swiper-line-face))) - `(swiper-match-face-4 ((,class :inherit swiper-line-face))) -;;;;; swoop - `(swoop-face-header-format-line ((,class :inherit bold :foreground ,red-alt - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-3)))) - `(swoop-face-line-buffer-name ((,class :inherit bold :foreground ,blue-alt - ,@(modus-vivendi-theme-scale modus-vivendi-theme-scale-4)))) - `(swoop-face-line-number ((,class :foreground ,fg-special-warm))) - `(swoop-face-target-line ((,class :inherit modus-theme-intense-blue - ,@(and (>= emacs-major-version 27) '(:extend t))))) - `(swoop-face-target-words ((,class :inherit modus-theme-refine-cyan))) -;;;;; sx - `(sx-inbox-item-type ((,class :foreground ,magenta-alt-other))) - `(sx-inbox-item-type-unread ((,class :inherit (sx-inbox-item-type bold)))) - `(sx-question-list-answers ((,class :foreground ,green))) - `(sx-question-list-answers-accepted ((,class :box t :foreground ,green))) - `(sx-question-list-bounty ((,class :inherit bold :background ,bg-alt :foreground ,yellow))) - `(sx-question-list-date ((,class :foreground ,fg-special-cold))) - `(sx-question-list-favorite ((,class :inherit bold :foreground ,fg-special-warm))) - `(sx-question-list-parent ((,class :foreground ,fg-main))) - `(sx-question-list-read-question ((,class :foreground ,fg-alt))) - `(sx-question-list-score ((,class :foreground ,fg-special-mild))) - `(sx-question-list-score-upvoted ((,class :inherit (sx-question-list-score bold)))) - `(sx-question-list-unread-question ((,class :inherit bold :foreground ,fg-main))) - `(sx-question-mode-accepted ((,class :inherit bold :height 1.3 :foreground ,green))) - `(sx-question-mode-closed ((,class :inherit modus-theme-active-yellow :box (:line-width 2 :color nil)))) - `(sx-question-mode-closed-reason ((,class :box (:line-width 2 :color nil) :foreground ,fg-main))) - `(sx-question-mode-content-face ((,class :background ,bg-dim))) - `(sx-question-mode-date ((,class :foreground ,blue))) - `(sx-question-mode-header ((,class :inherit bold :foreground ,cyan))) - `(sx-question-mode-kbd-tag ((,class :inherit bold :height 0.9 :box (:line-width 3 :color ,fg-main :style released-button) :foreground ,fg-main))) - `(sx-question-mode-score ((,class :foreground ,fg-dim))) - `(sx-question-mode-score-downvoted ((,class :foreground ,yellow))) - `(sx-question-mode-score-upvoted ((,class :inherit bold :foreground ,magenta))) - `(sx-question-mode-title ((,class :inherit bold :foreground ,fg-main))) - `(sx-question-mode-title-comments ((,class :inherit bold :foreground ,fg-alt))) - `(sx-tag ((,class :foreground ,magenta-alt))) - `(sx-user-name ((,class :foreground ,blue-alt))) - `(sx-user-reputation ((,class :foreground ,fg-alt))) -;;;;; symbol-overlay - `(symbol-overlay-default-face ((,class :inherit modus-theme-special-warm))) - `(symbol-overlay-face-1 ((,class :inherit modus-theme-intense-blue))) - `(symbol-overlay-face-2 ((,class :inherit modus-theme-refine-magenta))) - `(symbol-overlay-face-3 ((,class :inherit modus-theme-intense-yellow))) - `(symbol-overlay-face-4 ((,class :inherit modus-theme-intense-magenta))) - `(symbol-overlay-face-5 ((,class :inherit modus-theme-intense-red))) - `(symbol-overlay-face-6 ((,class :inherit modus-theme-refine-red))) - `(symbol-overlay-face-7 ((,class :inherit modus-theme-intense-cyan))) - `(symbol-overlay-face-8 ((,class :inherit modus-theme-refine-cyan))) -;;;;; syslog-mode - `(syslog-debug ((,class :inherit bold :foreground ,cyan-alt-other))) - `(syslog-error ((,class :inherit bold :foreground ,red))) - `(syslog-file ((,class :inherit bold :foreground ,fg-special-cold))) - `(syslog-hide ((,class :background ,bg-main :foreground ,fg-main))) - `(syslog-hour ((,class :inherit bold :foreground ,magenta-alt-other))) - `(syslog-info ((,class :inherit bold :foreground ,blue-alt-other))) - `(syslog-ip ((,class :inherit bold :foreground ,fg-special-mild :underline t))) - `(syslog-su ((,class :inherit bold :foreground ,red-alt))) - `(syslog-warn ((,class :inherit bold :foreground ,yellow))) -;;;;; table (built-in table.el) - `(table-cell ((,class :background ,blue-nuanced-bg))) -;;;;; telephone-line - `(telephone-line-accent-active ((,class :background ,fg-inactive :foreground ,bg-inactive))) - `(telephone-line-accent-inactive ((,class :background ,bg-active :foreground ,fg-active))) - `(telephone-line-error ((,class :inherit bold :foreground ,red-active))) - `(telephone-line-evil ((,class :foreground ,fg-main))) - `(telephone-line-evil-emacs ((,class :inherit telephone-line-evil :background ,magenta-intense-bg))) - `(telephone-line-evil-insert ((,class :inherit telephone-line-evil :background ,green-intense-bg))) - `(telephone-line-evil-motion ((,class :inherit telephone-line-evil :background ,yellow-intense-bg))) - `(telephone-line-evil-normal ((,class :inherit telephone-line-evil :background ,bg-alt))) - `(telephone-line-evil-operator ((,class :inherit telephone-line-evil :background ,yellow-subtle-bg))) - `(telephone-line-evil-replace ((,class :inherit telephone-line-evil :background ,red-intense-bg))) - `(telephone-line-evil-visual ((,class :inherit telephone-line-evil :background ,cyan-intense-bg))) - `(telephone-line-projectile ((,class :foreground ,cyan-active))) - `(telephone-line-unimportant ((,class :foreground ,fg-inactive))) - `(telephone-line-warning ((,class :inherit bold :foreground ,yellow-active))) -;;;;; term - `(term ((,class :background ,bg-main :foreground ,fg-main))) - `(term-bold ((,class :inherit bold))) - `(term-color-blue ((,class :background ,blue :foreground ,blue))) - `(term-color-cyan ((,class :background ,cyan :foreground ,cyan))) - `(term-color-green ((,class :background ,green :foreground ,green))) - `(term-color-magenta ((,class :background ,magenta :foreground ,magenta))) - `(term-color-red ((,class :background ,red :foreground ,red))) - `(term-color-yellow ((,class :background ,yellow :foreground ,yellow))) - `(term-underline ((,class :underline t))) -;;;;; tomatinho - `(tomatinho-ok-face ((,class :foreground ,blue-intense))) - `(tomatinho-pause-face ((,class :foreground ,yellow-intense))) - `(tomatinho-reset-face ((,class :foreground ,fg-alt))) -;;;;; transient - `(transient-active-infix ((,class :inherit modus-theme-special-mild))) - `(transient-amaranth ((,class :inherit bold :foreground ,yellow))) - `(transient-argument ((,class :inherit bold :foreground ,red-alt))) - `(transient-blue ((,class :inherit bold :foreground ,blue))) - `(transient-disabled-suffix ((,class :inherit modus-theme-intense-red))) - `(transient-enabled-suffix ((,class :inherit modus-theme-intense-green))) - `(transient-heading ((,class :inherit bold :foreground ,fg-main))) - `(transient-inactive-argument ((,class :foreground ,fg-alt))) - `(transient-inactive-value ((,class :foreground ,fg-alt))) - `(transient-key ((,class :inherit bold :foreground ,blue))) - `(transient-mismatched-key ((,class :underline t))) - `(transient-nonstandard-key ((,class :underline t))) - `(transient-pink ((,class :inherit bold :foreground ,magenta))) - `(transient-red ((,class :inherit bold :foreground ,red-intense))) - `(transient-teal ((,class :inherit bold :foreground ,cyan-alt-other))) - `(transient-unreachable ((,class :foreground ,fg-unfocused))) - `(transient-unreachable-key ((,class :foreground ,fg-unfocused))) - `(transient-value ((,class :foreground ,magenta-alt))) -;;;;; trashed - `(trashed-deleted ((,class :inherit modus-theme-mark-del))) - `(trashed-directory ((,class :foreground ,blue))) - `(trashed-mark ((,class :inherit modus-theme-mark-symbol))) - `(trashed-marked ((,class :inherit modus-theme-mark-alt))) - `(trashed-restored ((,class :inherit modus-theme-mark-sel))) - `(trashed-symlink ((,class :inherit button :foreground ,cyan-alt))) -;;;;; treemacs - `(treemacs-directory-collapsed-face ((,class :foreground ,magenta-alt))) - `(treemacs-directory-face ((,class :inherit dired-directory))) - `(treemacs-file-face ((,class :foreground ,fg-main))) - `(treemacs-fringe-indicator-face ((,class :foreground ,fg-main))) - `(treemacs-git-added-face ((,class :foreground ,green-intense))) - `(treemacs-git-conflict-face ((,class :inherit (modus-theme-intense-red bold)))) - `(treemacs-git-ignored-face ((,class :foreground ,fg-alt))) - `(treemacs-git-modified-face ((,class :foreground ,yellow-alt-other))) - `(treemacs-git-renamed-face ((,class :foreground ,cyan-alt-other))) - `(treemacs-git-unmodified-face ((,class :foreground ,fg-main))) - `(treemacs-git-untracked-face ((,class :foreground ,red-alt-other))) - `(treemacs-help-column-face ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,magenta-alt-other :underline t))) - `(treemacs-help-title-face ((,class :foreground ,blue-alt-other))) - `(treemacs-on-failure-pulse-face ((,class :inherit modus-theme-intense-red))) - `(treemacs-on-success-pulse-face ((,class :inherit modus-theme-intense-green))) - `(treemacs-root-face ((,class :inherit bold :foreground ,blue-alt-other :height 1.2 :underline t))) - `(treemacs-root-remote-disconnected-face ((,class :inherit treemacs-root-remote-face :foreground ,yellow))) - `(treemacs-root-remote-face ((,class :inherit treemacs-root-face :foreground ,magenta))) - `(treemacs-root-remote-unreadable-face ((,class :inherit treemacs-root-unreadable-face))) - `(treemacs-root-unreadable-face ((,class :inherit treemacs-root-face :strike-through t))) - `(treemacs-tags-face ((,class :foreground ,blue-alt))) - `(treemacs-tags-face ((,class :foreground ,magenta-alt))) -;;;;; tty-menu - `(tty-menu-disabled-face ((,class :background ,bg-alt :foreground ,fg-alt))) - `(tty-menu-enabled-face ((,class :inherit bold :background ,bg-alt :foreground ,fg-main))) - `(tty-menu-selected-face ((,class :inherit modus-theme-intense-blue))) -;;;;; tuareg - `(caml-types-def-face ((,class :inherit modus-theme-subtle-red))) - `(caml-types-expr-face ((,class :inherit modus-theme-subtle-green))) - `(caml-types-occ-face ((,class :inherit modus-theme-subtle-green))) - `(caml-types-scope-face ((,class :inherit modus-theme-subtle-blue))) - `(caml-types-typed-face ((,class :inherit modus-theme-subtle-magenta))) - `(tuareg-font-double-semicolon-face ((,class ,@(modus-vivendi-theme-syntax-foreground - red-alt red-alt-faint)))) - `(tuareg-font-lock-attribute-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta magenta-faint)))) - `(tuareg-font-lock-constructor-face ((,class :foreground ,fg-main))) - `(tuareg-font-lock-error-face ((,class :inherit (modus-theme-intense-red bold)))) - `(tuareg-font-lock-extension-node-face ((,class :background ,bg-alt :foreground ,magenta))) - `(tuareg-font-lock-governing-face ((,class :inherit bold :foreground ,fg-main))) - `(tuareg-font-lock-infix-extension-node-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta magenta-faint)))) - `(tuareg-font-lock-interactive-directive-face ((,class :foreground ,fg-special-cold))) - `(tuareg-font-lock-interactive-error-face ((,class :inherit bold - ,@(modus-vivendi-theme-syntax-foreground - red red-faint)))) - `(tuareg-font-lock-interactive-output-face ((,class ,@(modus-vivendi-theme-syntax-foreground - blue-alt-other blue-alt-other-faint)))) - `(tuareg-font-lock-label-face ((,class ,@(modus-vivendi-theme-syntax-foreground - cyan-alt-other cyan-alt-other-faint)))) - `(tuareg-font-lock-line-number-face ((,class :foreground ,fg-special-warm))) - `(tuareg-font-lock-module-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt magenta-alt-faint)))) - `(tuareg-font-lock-multistage-face ((,class :inherit bold :background ,bg-alt - ,@(modus-vivendi-theme-syntax-foreground - blue blue-faint)))) - `(tuareg-font-lock-operator-face ((,class ,@(modus-vivendi-theme-syntax-foreground - red-alt red-alt-faint)))) - `(tuareg-opam-error-face ((,class :inherit bold - ,@(modus-vivendi-theme-syntax-foreground - red red-faint)))) - `(tuareg-opam-pkg-variable-name-face ((,class ,@(modus-vivendi-theme-syntax-foreground - cyan cyan-faint) - :slant ,modus-theme-slant))) -;;;;; typescript - `(typescript-jsdoc-tag ((,class :foreground ,fg-special-mild :slant ,modus-theme-slant))) - `(typescript-jsdoc-type ((,class :foreground ,fg-special-calm :slant ,modus-theme-slant))) - `(typescript-jsdoc-value ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) -;;;;; undo-tree - `(undo-tree-visualizer-active-branch-face ((,class :inherit bold :foreground ,fg-main))) - `(undo-tree-visualizer-current-face ((,class :foreground ,blue-intense))) - `(undo-tree-visualizer-default-face ((,class :foreground ,fg-alt))) - `(undo-tree-visualizer-register-face ((,class :foreground ,magenta-intense))) - `(undo-tree-visualizer-unmodified-face ((,class :foreground ,green-intense))) -;;;;; vc (vc-hooks.el) - `(vc-conflict-state ((,class :foreground ,red-active :slant ,modus-theme-slant))) - `(vc-edited-state ((,class :foreground ,yellow-active))) - `(vc-locally-added-state ((,class :foreground ,cyan-active))) - `(vc-locked-state ((,class :foreground ,blue-active))) - `(vc-missing-state ((,class :foreground ,magenta-active :slant ,modus-theme-slant))) - `(vc-needs-update-state ((,class :foreground ,green-active :slant ,modus-theme-slant))) - `(vc-removed-state ((,class :foreground ,red-active))) - `(vc-state-base ((,class :foreground ,fg-active))) - `(vc-up-to-date-state ((,class :foreground ,fg-special-cold))) -;;;;; vdiff - `(vdiff-addition-face ((,class :inherit modus-theme-diff-added))) - `(vdiff-change-face ((,class :inherit modus-theme-diff-changed))) - `(vdiff-closed-fold-face ((,class :background ,bg-diff-neutral-1 :foreground ,fg-diff-neutral-1))) - `(vdiff-refine-added ((,class :inherit modus-theme-diff-refine-added))) - `(vdiff-refine-changed ((,class :inherit modus-theme-diff-refine-changed))) - `(vdiff-subtraction-face ((,class :inherit modus-theme-diff-removed))) - `(vdiff-target-face ((,class :inherit modus-theme-intense-blue))) -;;;;; vimish-fold - `(vimish-fold-fringe ((,class :foreground ,cyan-active))) - `(vimish-fold-mouse-face ((,class :inherit modus-theme-intense-blue))) - `(vimish-fold-overlay ((,class :background ,bg-alt :foreground ,fg-special-cold))) -;;;;; visible-mark - `(visible-mark-active ((,class :background ,blue-intense-bg))) - `(visible-mark-face1 ((,class :background ,cyan-intense-bg))) - `(visible-mark-face2 ((,class :background ,yellow-intense-bg))) - `(visible-mark-forward-face1 ((,class :background ,magenta-intense-bg))) - `(visible-mark-forward-face2 ((,class :background ,green-intense-bg))) -;;;;; visual-regexp - `(vr/group-0 ((,class :inherit modus-theme-intense-blue))) - `(vr/group-1 ((,class :inherit modus-theme-intense-magenta))) - `(vr/group-2 ((,class :inherit modus-theme-intense-green))) - `(vr/match-0 ((,class :inherit modus-theme-refine-yellow))) - `(vr/match-1 ((,class :inherit modus-theme-refine-yellow))) - `(vr/match-separator-face ((,class :inherit (modus-theme-intense-neutral bold)))) -;;;;; volatile-highlights - `(vhl/default-face ((,class ,@(and (>= emacs-major-version 27) '(:extend t)) - :background ,bg-alt :foreground ,blue-nuanced))) -;;;;; vterm - `(vterm-color-black ((,class :background "gray35" :foreground "gray35"))) - `(vterm-color-blue ((,class :background ,blue :foreground ,blue))) - `(vterm-color-cyan ((,class :background ,cyan :foreground ,cyan))) - `(vterm-color-default ((,class :background ,bg-main :foreground ,fg-main))) - `(vterm-color-green ((,class :background ,green :foreground ,green))) - `(vterm-color-inverse-video ((,class :background ,bg-main :inverse-video t))) - `(vterm-color-magenta ((,class :background ,magenta :foreground ,magenta))) - `(vterm-color-red ((,class :background ,red :foreground ,red))) - `(vterm-color-underline ((,class :foreground ,fg-special-warm :underline t))) - `(vterm-color-white ((,class :background "gray65" :foreground "gray65"))) - `(vterm-color-yellow ((,class :background ,yellow :foreground ,yellow))) -;;;;; wcheck-mode - `(wcheck-default-face ((,class :foreground ,red :underline t))) -;;;;; web-mode - `(web-mode-annotation-face ((,class :inherit web-mode-comment-face))) - `(web-mode-annotation-html-face ((,class :inherit web-mode-comment-face))) - `(web-mode-annotation-tag-face ((,class :inherit web-mode-comment-face :underline t))) - `(web-mode-block-attr-name-face ((,class ,@(modus-vivendi-theme-syntax-foreground - blue blue-faint)))) - `(web-mode-block-attr-value-face ((,class ,@(modus-vivendi-theme-syntax-foreground - cyan-alt-other cyan-alt-other-faint)))) - `(web-mode-block-comment-face ((,class :inherit web-mode-comment-face))) - `(web-mode-block-control-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(web-mode-block-delimiter-face ((,class :foreground ,fg-main))) - `(web-mode-block-face ((,class :background ,bg-dim))) - `(web-mode-block-string-face ((,class :inherit web-mode-string-face))) - `(web-mode-bold-face ((,class :inherit bold))) - `(web-mode-builtin-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(web-mode-comment-face ((,class :foreground ,fg-alt :slant ,modus-theme-slant))) - `(web-mode-comment-keyword-face ((,class :inherit bold :background ,bg-dim - ,@(modus-vivendi-theme-syntax-foreground - yellow yellow-faint)))) - `(web-mode-constant-face ((,class ,@(modus-vivendi-theme-syntax-foreground - blue-alt-other blue-alt-other-faint)))) - `(web-mode-css-at-rule-face ((,class ,@(modus-vivendi-theme-syntax-foreground - blue-alt-other blue-alt-other-faint)))) - `(web-mode-css-color-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(web-mode-css-comment-face ((,class :inherit web-mode-comment-face))) - `(web-mode-css-function-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(web-mode-css-priority-face ((,class ,@(modus-vivendi-theme-syntax-foreground - yellow-alt yellow-alt-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(web-mode-css-property-name-face ((,class ,@(modus-vivendi-theme-syntax-foreground - cyan cyan-faint)))) - `(web-mode-css-pseudo-class-face ((,class ,@(modus-vivendi-theme-syntax-foreground - cyan-alt-other cyan-alt-other-faint)))) - `(web-mode-css-selector-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt-other magenta-alt-other-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(web-mode-css-string-face ((,class :inherit web-mode-string-face))) - `(web-mode-css-variable-face ((,class :foreground ,fg-special-warm))) - `(web-mode-current-column-highlight-face ((,class :background ,bg-alt))) - `(web-mode-current-element-highlight-face ((,class :inherit modus-theme-special-mild))) - `(web-mode-doctype-face ((,class :foreground ,fg-special-cold :slant ,modus-theme-slant))) - `(web-mode-error-face ((,class :inherit modus-theme-intense-red))) - `(web-mode-filter-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta magenta-faint)))) - `(web-mode-folded-face ((,class :underline t))) - `(web-mode-function-call-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta magenta-faint)))) - `(web-mode-function-name-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta magenta-faint)))) - `(web-mode-html-attr-custom-face ((,class ,@(modus-vivendi-theme-syntax-foreground - cyan cyan-faint)))) - `(web-mode-html-attr-engine-face ((,class :foreground ,fg-main))) - `(web-mode-html-attr-equal-face ((,class :foreground ,fg-main))) - `(web-mode-html-attr-name-face ((,class ,@(modus-vivendi-theme-syntax-foreground - cyan cyan-faint)))) - `(web-mode-html-attr-value-face ((,class ,@(modus-vivendi-theme-syntax-foreground - blue-alt-other blue-alt-other-faint)))) - `(web-mode-html-entity-face ((,class ,@(modus-vivendi-theme-syntax-foreground - yellow-alt-other yellow-alt-other-faint) - :slant ,modus-theme-slant))) - `(web-mode-html-tag-bracket-face ((,class :foreground ,fg-dim))) - `(web-mode-html-tag-custom-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta magenta-faint)))) - `(web-mode-html-tag-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta magenta-faint)))) - `(web-mode-html-tag-namespaced-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt magenta-alt-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(web-mode-html-tag-unclosed-face ((,class ,@(modus-vivendi-theme-syntax-foreground - red red-faint) - :underline t))) - `(web-mode-inlay-face ((,class :background ,bg-alt))) - `(web-mode-italic-face ((,class :slant italic))) - `(web-mode-javascript-comment-face ((,class :inherit web-mode-comment-face))) - `(web-mode-javascript-string-face ((,class :inherit web-mode-string-face))) - `(web-mode-json-comment-face ((,class :inherit web-mode-comment-face))) - `(web-mode-json-context-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt magenta-alt-faint)))) - `(web-mode-json-key-face ((,class :foreground ,blue-nuanced))) - `(web-mode-json-string-face ((,class :inherit web-mode-string-face))) - `(web-mode-jsx-depth-1-face ((,class :background ,blue-intense-bg :foreground ,fg-main))) - `(web-mode-jsx-depth-2-face ((,class :background ,blue-subtle-bg :foreground ,fg-main))) - `(web-mode-jsx-depth-3-face ((,class :background ,bg-special-cold :foreground ,fg-special-cold))) - `(web-mode-jsx-depth-4-face ((,class :background ,bg-alt :foreground ,blue-refine-fg))) - `(web-mode-jsx-depth-5-face ((,class :background ,bg-alt :foreground ,blue-nuanced))) - `(web-mode-keyword-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt-other magenta-alt-other-faint) - ,@(modus-vivendi-theme-bold-weight)))) - `(web-mode-param-name-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta magenta-faint)))) - `(web-mode-part-comment-face ((,class :inherit web-mode-comment-face))) - `(web-mode-part-face ((,class :inherit web-mode-block-face))) - `(web-mode-part-string-face ((,class :inherit web-mode-string-face))) - `(web-mode-preprocessor-face ((,class ,@(modus-vivendi-theme-syntax-foreground - red-alt-other red-alt-other-faint)))) - `(web-mode-script-face ((,class :inherit web-mode-part-face))) - `(web-mode-sql-keyword-face ((,class :inherit bold - ,@(modus-vivendi-theme-syntax-foreground - yellow yellow-faint)))) - `(web-mode-string-face ((,class ,@(modus-vivendi-theme-syntax-foreground - blue-alt blue-alt-faint)))) - `(web-mode-style-face ((,class :inherit web-mode-part-face))) - `(web-mode-symbol-face ((,class ,@(modus-vivendi-theme-syntax-foreground - blue-alt-other blue-alt-other-faint)))) - `(web-mode-type-face ((,class ,@(modus-vivendi-theme-syntax-foreground - magenta-alt magenta-alt-faint)))) - `(web-mode-underline-face ((,class :underline t))) - `(web-mode-variable-name-face ((,class ,@(modus-vivendi-theme-syntax-foreground - cyan cyan-faint)))) - `(web-mode-warning-face ((,class :inherit bold :background ,bg-alt - ,@(modus-vivendi-theme-syntax-foreground - yellow-alt-other yellow-alt-other-faint)))) - `(web-mode-whitespace-face ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) -;;;;; wgrep - `(wgrep-delete-face ((,class :inherit modus-theme-refine-yellow))) - `(wgrep-done-face ((,class :inherit modus-theme-refine-blue))) - `(wgrep-face ((,class :inherit modus-theme-refine-green))) - `(wgrep-file-face ((,class :foreground ,fg-special-warm))) - `(wgrep-reject-face ((,class :inherit (modus-theme-intense-red bold)))) -;;;;; which-function-mode - `(which-func ((,class :foreground ,magenta-active))) -;;;;; which-key - `(which-key-command-description-face ((,class :foreground ,cyan))) - `(which-key-group-description-face ((,class :foreground ,magenta-alt))) - `(which-key-highlighted-command-face ((,class :foreground ,cyan-alt :underline t))) - `(which-key-key-face ((,class :inherit bold :foreground ,blue-intense))) - `(which-key-local-map-description-face ((,class :foreground ,fg-main))) - `(which-key-note-face ((,class :background ,bg-dim :foreground ,fg-special-mild))) - `(which-key-separator-face ((,class :foreground ,fg-alt))) - `(which-key-special-key-face ((,class :inherit bold :foreground ,yellow-intense))) -;;;;; whitespace-mode - `(whitespace-big-indent ((,class :inherit modus-theme-subtle-red))) - `(whitespace-empty ((,class :inherit modus-theme-intense-magenta))) - `(whitespace-hspace ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) - `(whitespace-indentation ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) - `(whitespace-line ((,class :inherit modus-theme-special-warm))) - `(whitespace-newline ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) - `(whitespace-space ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) - `(whitespace-space-after-tab ((,class :inherit modus-theme-subtle-magenta))) - `(whitespace-space-before-tab ((,class :inherit modus-theme-subtle-cyan))) - `(whitespace-tab ((,class :background ,bg-whitespace :foreground ,fg-whitespace))) - `(whitespace-trailing ((,class :inherit modus-theme-intense-red))) -;;;;; window-divider-mode - `(window-divider ((,class :foreground ,fg-window-divider-inner))) - `(window-divider-first-pixel ((,class :foreground ,fg-window-divider-outer))) - `(window-divider-last-pixel ((,class :foreground ,fg-window-divider-outer))) -;;;;; winum - `(winum-face ((,class ,@(modus-vivendi-theme-bold-weight) :foreground ,cyan-active))) -;;;;; writegood-mode - `(writegood-duplicates-face ((,class :background ,bg-alt :foreground ,red-alt :underline t))) - `(writegood-passive-voice-face ((,class :foreground ,yellow-nuanced :underline ,fg-lang-warning))) - `(writegood-weasels-face ((,class :foreground ,red-nuanced :underline ,fg-lang-error))) -;;;;; woman - `(woman-addition ((,class :foreground ,magenta-alt-other))) - `(woman-bold ((,class :inherit bold :foreground ,magenta))) - `(woman-italic ((,class :foreground ,cyan :slant italic))) - `(woman-unknown ((,class :foreground ,yellow :slant italic))) -;;;;; xah-elisp-mode - `(xah-elisp-at-symbol ((,class :inherit bold - ,@(modus-vivendi-theme-syntax-foreground - red-alt red-alt-faint)))) - `(xah-elisp-cap-variable ((,class ,@(modus-vivendi-theme-syntax-foreground - red-alt-other red-alt-other-faint)))) - `(xah-elisp-command-face ((,class ,@(modus-vivendi-theme-syntax-foreground - cyan-alt-other cyan-alt-other-faint)))) - `(xah-elisp-dollar-symbol ((,class ,@(modus-vivendi-theme-syntax-foreground - green green-faint)))) -;;;;; xref - `(xref-file-header ((,class :inherit bold :foreground ,fg-special-cold))) - `(xref-line-number ((,class :foreground ,fg-alt))) - `(xref-match ((,class :inherit match))) -;;;;; yaml-mode - `(yaml-tab-face ((,class :inherit modus-theme-intense-red))) -;;;;; yasnippet - `(yas-field-highlight-face ((,class :background ,bg-alt :foreground ,fg-main))) -;;;;; ztree - `(ztreep-arrow-face ((,class :foreground ,fg-inactive))) - `(ztreep-diff-header-face ((,class :inherit bold :height 1.2 :foreground ,fg-special-cold))) - `(ztreep-diff-header-small-face ((,class :inherit bold :foreground ,fg-special-mild))) - `(ztreep-diff-model-add-face ((,class :foreground ,green))) - `(ztreep-diff-model-diff-face ((,class :foreground ,red))) - `(ztreep-diff-model-ignored-face ((,class :foreground ,fg-alt :strike-through t))) - `(ztreep-diff-model-normal-face ((,class :foreground ,fg-alt))) - `(ztreep-expand-sign-face ((,class :foreground ,blue))) - `(ztreep-header-face ((,class :inherit bold :height 1.2 :foreground ,fg-special-cold))) - `(ztreep-leaf-face ((,class :foreground ,cyan))) - `(ztreep-node-count-children-face ((,class :foreground ,fg-special-warm))) - `(ztreep-node-face ((,class :foreground ,fg-main)))) -;;;; Emacs 27+ - (when (>= emacs-major-version 27) - (custom-theme-set-faces - 'modus-vivendi -;;;;; line numbers (`display-line-numbers-mode' and global variant) - ;; NOTE that this is specifically for the faces that were - ;; introduced in Emacs 27, as the other faces are already - ;; supported. - `(line-number-major-tick ((,class :inherit (bold default) - :background ,yellow-nuanced-bg - :foreground ,yellow-nuanced))) - `(line-number-minor-tick ((,class :inherit (bold default) - :background ,bg-inactive - :foreground ,fg-inactive))) -;;;;; tab-bar-mode - `(tab-bar ((,class :background ,bg-tab-bar :foreground ,fg-main))) - `(tab-bar-tab ((,class :inherit bold :box (:line-width 2 :color ,bg-tab-active) - :background ,bg-tab-active :foreground ,fg-main))) - `(tab-bar-tab-inactive ((,class :box (:line-width 2 :color ,bg-tab-inactive) - :background ,bg-tab-inactive :foreground ,fg-dim))) -;;;;; tab-line-mode - `(tab-line ((,class :height 0.95 :background ,bg-tab-bar :foreground ,fg-main))) - `(tab-line-close-highlight ((,class :foreground ,red))) - `(tab-line-highlight ((,class :background ,blue-subtle-bg :foreground ,fg-dim))) - `(tab-line-tab ((,class :inherit bold :box (:line-width 2 :color ,bg-tab-active) - :background ,bg-tab-active :foreground ,fg-main))) - `(tab-line-tab-current ((,class :inherit tab-line-tab))) - `(tab-line-tab-inactive ((,class :box (:line-width 2 :color ,bg-tab-inactive) - :background ,bg-tab-inactive :foreground ,fg-dim))))) -;;;; Emacs 28+ - (when (>= emacs-major-version 28) - (custom-theme-set-faces - 'modus-vivendi -;;;;; isearch regexp groups - `(isearch-group-1 ((,class :inherit modus-theme-intense-blue))) - `(isearch-group-2 ((,class :inherit modus-theme-intense-magenta))))) -;;; variables - (custom-theme-set-variables - 'modus-vivendi -;;;; ansi-colors - `(ansi-color-faces-vector [default bold shadow italic underline success warning error]) - `(ansi-color-names-vector [,bg-main ,red ,green ,yellow ,blue ,magenta ,cyan ,fg-main]) -;;;; awesome-tray - `(awesome-tray-mode-line-active-color ,blue) - `(awesome-tray-mode-line-inactive-color ,bg-active) -;;;; flymake fringe indicators - `(flymake-error-bitmap '(flymake-double-exclamation-mark modus-theme-fringe-red)) - `(flymake-warning-bitmap '(exclamation-mark modus-theme-fringe-yellow)) - `(flymake-note-bitmap '(exclamation-mark modus-theme-fringe-cyan)) -;;;; ibuffer - `(ibuffer-deletion-face 'modus-theme-mark-del) - `(ibuffer-filter-group-name-face 'modus-theme-mark-symbol) - `(ibuffer-marked-face 'modus-theme-mark-sel) - `(ibuffer-title-face 'modus-theme-pseudo-header) -;;;; highlight-tail - `(highlight-tail-colors - '((,green-subtle-bg . 0) - (,cyan-subtle-bg . 20))) -;;;; hl-todo - `(hl-todo-keyword-faces - '(("HOLD" . ,yellow-alt) - ("TODO" . ,magenta) - ("NEXT" . ,magenta-alt-other) - ("THEM" . ,magenta-alt) - ("PROG" . ,cyan) - ("OKAY" . ,cyan-alt) - ("DONT" . ,green-alt) - ("FAIL" . ,red) - ("BUG" . ,red) - ("DONE" . ,green) - ("NOTE" . ,yellow-alt-other) - ("KLUDGE" . ,yellow) - ("HACK" . ,yellow) - ("TEMP" . ,red-nuanced) - ("FIXME" . ,red-alt-other) - ("XXX+" . ,red-alt) - ("REVIEW" . ,cyan-alt-other) - ("DEPRECATED" . ,blue-nuanced))) -;;;; vc-annotate (C-x v g) - `(vc-annotate-background nil) - `(vc-annotate-background-mode nil) - `(vc-annotate-color-map - '((20 . ,red) - (40 . ,magenta) - (60 . ,magenta-alt) - (80 . ,red-alt) - (100 . ,yellow) - (120 . ,yellow-alt) - (140 . ,fg-special-warm) - (160 . ,fg-special-mild) - (180 . ,green) - (200 . ,green-alt) - (220 . ,cyan-alt-other) - (240 . ,cyan-alt) - (260 . ,cyan) - (280 . ,fg-special-cold) - (300 . ,blue) - (320 . ,blue-alt) - (340 . ,blue-alt-other) - (360 . ,magenta-alt-other))) - `(vc-annotate-very-old-color nil) -;;;; xterm-color - `(xterm-color-names [,bg-main ,red ,green ,yellow ,blue ,magenta ,cyan ,fg-alt]) - `(xterm-color-names-bright [,bg-alt ,red-alt ,green-alt ,yellow-alt ,blue-alt ,magenta-alt ,cyan-alt ,fg-main])) -;;; Conditional theme variables -;;;; org-src-block-faces - ;; this is a user option to add a colour-coded background to source - ;; blocks for various programming languages - (when (eq modus-vivendi-theme-org-blocks 'rainbow) - (custom-theme-set-variables - 'modus-vivendi - `(org-src-block-faces ; TODO this list should be expanded - `(("emacs-lisp" modus-theme-nuanced-magenta) - ("elisp" modus-theme-nuanced-magenta) - ("clojure" modus-theme-nuanced-magenta) - ("clojurescript" modus-theme-nuanced-magenta) - ("c" modus-theme-nuanced-blue) - ("c++" modus-theme-nuanced-blue) - ("sh" modus-theme-nuanced-green) - ("shell" modus-theme-nuanced-green) - ("html" modus-theme-nuanced-yellow) - ("xml" modus-theme-nuanced-yellow) - ("css" modus-theme-nuanced-red) - ("scss" modus-theme-nuanced-red) - ("python" modus-theme-nuanced-green) - ("ipython" modus-theme-nuanced-magenta) - ("r" modus-theme-nuanced-cyan) - ("yaml" modus-theme-nuanced-cyan) - ("conf" modus-theme-nuanced-cyan) - ("docker" modus-theme-nuanced-cyan) - ("json" modus-theme-nuanced-cyan)))))) +(deftheme modus-vivendi + "Accessible and customizable dark theme (WCAG AAA standard). +Conforms with the highest legibility standard for color contrast +between background and foreground in any given piece of text, +which corresponds to a minimum contrast in relative luminance of +7:1.") -;;; library provides -;;;###autoload -(when load-file-name - (add-to-list 'custom-theme-load-path - (file-name-as-directory (file-name-directory load-file-name)))) +(modus-themes-theme modus-vivendi) (provide-theme 'modus-vivendi) commit f2f233d867ac5a81504c62d5fdb45e8c1c04739b Author: Basil L. Contovounesios Date: Sat Mar 6 09:05:49 2021 +0000 Conditionally use macroexp-file-name in Flymake * lisp/progmodes/flymake.el (flymake-log): Reinstate Emacs 26 support by conditionally using macroexp-file-name which is new in Emacs 28 (bug#46957). diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index bd308e0220..e7e746b981 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -287,7 +287,9 @@ LEVEL is passed to `display-warning', which is used to display the warning. If this form is included in a byte-compiled file, the generated warning contains an indication of the file that generated it." - (let* ((compile-file (macroexp-file-name)) + (let* ((compile-file (or (and (fboundp 'macroexp-file-name) + (macroexp-file-name)) + (bound-and-true-p byte-compile-current-file))) (sublog (if (and compile-file (not load-file-name)) commit 6d580dee309187ac0e5922215e133883e15718f9 Author: Stefan Monnier Date: Fri Mar 5 23:33:21 2021 -0500 * * lisp/cedet/semantic: Use lexical-binding in the generated grammars * admin/grammars/c.by (typesimple): Bind `semantic-c-classname` dynamically. * lisp/cedet/semantic/bovine.el: Use lexical-binding. (semantic-lambda): Silence warnings if the `vals` arg is not used. * lisp/cedet/semantic/grammar-wy.el: Re-generate. * lisp/cedet/semantic/bovine/grammar.el: Use lexical-binding. (bovine-grammar-expand-action): Silence warnings if some of the `vals`, `start`, or `end` args is not used. (bovine--make-parser-1): Use lexical-binding in the generated files. * lisp/cedet/semantic/wisent/grammar.el: Use lexical-binding. (wisent--make-parser-1): Use lexical-binding in the generated files. diff --git a/admin/grammars/c.by b/admin/grammars/c.by index 2d04c999ac..289081e3ce 100644 --- a/admin/grammars/c.by +++ b/admin/grammars/c.by @@ -415,7 +415,7 @@ typesimple : struct-or-class opt-class opt-name opt-template-specifier opt-class-parents semantic-list (TYPE-TAG (car $3) (car $1) - (let ((semantic-c-classname (cons (car ,$3) (car ,$1)))) + (dlet ((semantic-c-classname (cons (car ,$3) (car ,$1)))) (EXPANDFULL $6 classsubparts)) $5 :template-specifier $4 diff --git a/lisp/cedet/ede/custom.el b/lisp/cedet/ede/custom.el index aada872cd0..a128f9e124 100644 --- a/lisp/cedet/ede/custom.el +++ b/lisp/cedet/ede/custom.el @@ -53,7 +53,7 @@ (setq-local eieio-ede-old-variables ov))) ;;;###autoload -(defalias 'customize-project 'ede-customize-project) +(defalias 'customize-project #'ede-customize-project) ;;;###autoload (defun ede-customize-current-target() @@ -65,7 +65,7 @@ (ede-customize-target ede-object)) ;;;###autoload -(defalias 'customize-target 'ede-customize-current-target) +(defalias 'customize-target #'ede-customize-current-target) (defun ede-customize-target (obj) "Edit fields of the current target through EIEIO & Custom. diff --git a/lisp/cedet/semantic/bovine.el b/lisp/cedet/semantic/bovine.el index 65d7868588..b585e387fe 100644 --- a/lisp/cedet/semantic/bovine.el +++ b/lisp/cedet/semantic/bovine.el @@ -1,4 +1,4 @@ -;;; semantic/bovine.el --- LL Parser/Analyzer core. +;;; semantic/bovine.el --- LL Parser/Analyzer core -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2004, 2006-2007, 2009-2021 Free Software ;; Foundation, Inc. @@ -54,6 +54,7 @@ Use this to detect infinite recursion during a parse.") "Create a lambda expression to return a list including RETURN-VAL. The return list is a lambda expression to be used in a bovine table." `(lambda (vals start end) + (ignore vals) (append ,@return-val (list start end)))) ;;; Semantic Bovination diff --git a/lisp/cedet/semantic/bovine/grammar.el b/lisp/cedet/semantic/bovine/grammar.el index 4914ec9b12..e3df7b12ab 100644 --- a/lisp/cedet/semantic/bovine/grammar.el +++ b/lisp/cedet/semantic/bovine/grammar.el @@ -1,4 +1,4 @@ -;;; semantic/bovine/grammar.el --- Bovine's input grammar mode +;;; semantic/bovine/grammar.el --- Bovine's input grammar mode -*- lexical-binding: t; -*- ;; ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. ;; @@ -243,7 +243,8 @@ QUOTEMODE is the mode in which quoted symbols are slurred." (insert "\n") (cond ((eq (car sexp) 'EXPAND) - (insert ",(lambda (vals start end)") + (insert ",(lambda (vals start end)" + "\n(ignore vals start end)") ;; The EXPAND macro definition is mandatory (bovine-grammar-expand-form (apply (cdr (assq 'EXPAND bovine--grammar-macros)) (cdr sexp)) @@ -520,7 +521,8 @@ Menu items are appended to the common grammar menu.") (goto-char (point-min)) (delete-region (point-min) (line-end-position)) (insert ";;; " packagename - " --- Generated parser support file") + " --- Generated parser support file " + "-*- lexical-binding:t -*-") (delete-trailing-whitespace) (re-search-forward ";;; \\(.*\\) ends here") (replace-match packagename nil nil nil 1))))) diff --git a/lisp/cedet/semantic/grammar-wy.el b/lisp/cedet/semantic/grammar-wy.el index 12c9c047fc..9a7f393072 100644 --- a/lisp/cedet/semantic/grammar-wy.el +++ b/lisp/cedet/semantic/grammar-wy.el @@ -1,6 +1,6 @@ -;;; semantic/grammar-wy.el --- Generated parser support file +;;; semantic/grammar-wy.el --- Generated parser support file -*- lexical-binding:t -*- -;; Copyright (C) 2002-2004, 2009-2021 Free Software Foundation, Inc. +;; Copyright (C) 2002-2021 Free Software Foundation, Inc. ;; This file is part of GNU Emacs. @@ -23,8 +23,9 @@ ;;; Code: -(require 'semantic) - +(require 'semantic/lex) +(eval-when-compile (require 'semantic/bovine)) + ;;; Prologue ;; (defvar semantic-grammar-lex-c-char-re) @@ -36,16 +37,20 @@ ;;; Declarations ;; +(eval-and-compile (defconst semantic-grammar-wy--expected-conflicts + nil + "The number of expected shift/reduce conflicts in this grammar.")) + (defconst semantic-grammar-wy--keyword-table (semantic-lex-make-keyword-table '(("%default-prec" . DEFAULT-PREC) ("%no-default-prec" . NO-DEFAULT-PREC) ("%keyword" . KEYWORD) - ("%expectedconflicts" . EXPECTEDCONFLICTS) ("%languagemode" . LANGUAGEMODE) ("%left" . LEFT) ("%nonassoc" . NONASSOC) ("%package" . PACKAGE) + ("%expectedconflicts" . EXPECTEDCONFLICTS) ("%provide" . PROVIDE) ("%prec" . PREC) ("%put" . PUT) @@ -111,239 +116,239 @@ (eval-when-compile (require 'semantic/wisent/comp)) (wisent-compile-grammar - '((DEFAULT-PREC NO-DEFAULT-PREC KEYWORD LANGUAGEMODE EXPECTEDCONFLICTS LEFT NONASSOC PACKAGE PROVIDE PREC PUT QUOTEMODE RIGHT SCOPESTART START TOKEN TYPE USE-MACROS STRING SYMBOL PERCENT_PERCENT CHARACTER PREFIXED_LIST SEXP PROLOGUE EPILOGUE PAREN_BLOCK BRACE_BLOCK LPAREN RPAREN LBRACE RBRACE COLON SEMI OR LT GT) + '((DEFAULT-PREC NO-DEFAULT-PREC KEYWORD LANGUAGEMODE LEFT NONASSOC PACKAGE EXPECTEDCONFLICTS PROVIDE PREC PUT QUOTEMODE RIGHT SCOPESTART START TOKEN TYPE USE-MACROS STRING SYMBOL PERCENT_PERCENT CHARACTER PREFIXED_LIST SEXP PROLOGUE EPILOGUE PAREN_BLOCK BRACE_BLOCK LPAREN RPAREN LBRACE RBRACE COLON SEMI OR LT GT) nil (grammar - ((prologue)) - ((epilogue)) - ((declaration)) - ((nonterminal)) - ((PERCENT_PERCENT))) + ((prologue)) + ((epilogue)) + ((declaration)) + ((nonterminal)) + ((PERCENT_PERCENT))) (prologue - ((PROLOGUE) - (wisent-raw-tag + ((PROLOGUE) + (wisent-raw-tag (semantic-tag-new-code "prologue" nil)))) (epilogue - ((EPILOGUE) - (wisent-raw-tag + ((EPILOGUE) + (wisent-raw-tag (semantic-tag-new-code "epilogue" nil)))) (declaration - ((decl) - (eval $1))) + ((decl) + (eval $1))) (decl - ((default_prec_decl)) - ((no_default_prec_decl)) - ((languagemode_decl)) - ((expectedconflicts_decl)) - ((package_decl)) - ((provide_decl)) - ((precedence_decl)) - ((put_decl)) - ((quotemode_decl)) - ((scopestart_decl)) - ((start_decl)) - ((keyword_decl)) - ((token_decl)) - ((type_decl)) - ((use_macros_decl))) + ((default_prec_decl)) + ((no_default_prec_decl)) + ((languagemode_decl)) + ((package_decl)) + ((expectedconflicts_decl)) + ((provide_decl)) + ((precedence_decl)) + ((put_decl)) + ((quotemode_decl)) + ((scopestart_decl)) + ((start_decl)) + ((keyword_decl)) + ((token_decl)) + ((type_decl)) + ((use_macros_decl))) (default_prec_decl - ((DEFAULT-PREC) + ((DEFAULT-PREC) `(wisent-raw-tag (semantic-tag "default-prec" 'assoc :value '("t"))))) (no_default_prec_decl - ((NO-DEFAULT-PREC) - `(wisent-raw-tag + ((NO-DEFAULT-PREC) + `(wisent-raw-tag (semantic-tag "default-prec" 'assoc :value - '("nil"))))) + '("nil"))))) (languagemode_decl - ((LANGUAGEMODE symbols) - `(wisent-raw-tag - (semantic-tag ',(car $2) - 'languagemode :rest ',(cdr $2))))) - (expectedconflicts_decl - ((EXPECTEDCONFLICTS symbols) - `(wisent-raw-tag + ((LANGUAGEMODE symbols) + `(wisent-raw-tag (semantic-tag ',(car $2) - 'expectedconflicts :rest ',(cdr $2))))) + 'languagemode :rest ',(cdr $2))))) (package_decl - ((PACKAGE SYMBOL) - `(wisent-raw-tag + ((PACKAGE SYMBOL) + `(wisent-raw-tag (semantic-tag-new-package ',$2 nil)))) + (expectedconflicts_decl + ((EXPECTEDCONFLICTS symbols) + `(wisent-raw-tag + (semantic-tag ',(car $2) + 'expectedconflicts :rest ',(cdr $2))))) (provide_decl - ((PROVIDE SYMBOL) - `(wisent-raw-tag + ((PROVIDE SYMBOL) + `(wisent-raw-tag (semantic-tag ',$2 'provide)))) (precedence_decl - ((associativity token_type_opt items) - `(wisent-raw-tag + ((associativity token_type_opt items) + `(wisent-raw-tag (semantic-tag ',$1 'assoc :type ',$2 :value ',$3)))) (associativity - ((LEFT) - (progn "left")) - ((RIGHT) - (progn "right")) - ((NONASSOC) - (progn "nonassoc"))) + ((LEFT) + (progn "left")) + ((RIGHT) + (progn "right")) + ((NONASSOC) + (progn "nonassoc"))) (put_decl - ((PUT put_name put_value) - `(wisent-raw-tag + ((PUT put_name put_value) + `(wisent-raw-tag (semantic-tag ',$2 'put :value ',(list $3)))) - ((PUT put_name put_value_list) - `(wisent-raw-tag + ((PUT put_name put_value_list) + `(wisent-raw-tag (semantic-tag ',$2 'put :value ',$3))) - ((PUT put_name_list put_value) - `(wisent-raw-tag + ((PUT put_name_list put_value) + `(wisent-raw-tag (semantic-tag ',(car $2) - 'put :rest ',(cdr $2) - :value ',(list $3)))) - ((PUT put_name_list put_value_list) - `(wisent-raw-tag + 'put :rest ',(cdr $2) + :value ',(list $3)))) + ((PUT put_name_list put_value_list) + `(wisent-raw-tag (semantic-tag ',(car $2) - 'put :rest ',(cdr $2) - :value ',$3)))) + 'put :rest ',(cdr $2) + :value ',$3)))) (put_name_list - ((BRACE_BLOCK) - (mapcar 'semantic-tag-name - (semantic-parse-region + ((BRACE_BLOCK) + (mapcar 'semantic-tag-name + (semantic-parse-region (car $region1) (cdr $region1) 'put_names 1)))) (put_names - ((LBRACE) - nil) - ((RBRACE) - nil) - ((put_name) - (wisent-raw-tag + ((LBRACE) + nil) + ((RBRACE) + nil) + ((put_name) + (wisent-raw-tag (semantic-tag $1 'put-name)))) (put_name - ((SYMBOL)) - ((token_type))) + ((SYMBOL)) + ((token_type))) (put_value_list - ((BRACE_BLOCK) - (mapcar 'semantic-tag-code-detail - (semantic-parse-region + ((BRACE_BLOCK) + (mapcar 'semantic-tag-code-detail + (semantic-parse-region (car $region1) (cdr $region1) 'put_values 1)))) (put_values - ((LBRACE) - nil) - ((RBRACE) - nil) - ((put_value) - (wisent-raw-tag + ((LBRACE) + nil) + ((RBRACE) + nil) + ((put_value) + (wisent-raw-tag (semantic-tag-new-code "put-value" $1)))) (put_value - ((SYMBOL any_value) - (cons $1 $2))) + ((SYMBOL any_value) + (cons $1 $2))) (scopestart_decl - ((SCOPESTART SYMBOL) - `(wisent-raw-tag + ((SCOPESTART SYMBOL) + `(wisent-raw-tag (semantic-tag ',$2 'scopestart)))) (quotemode_decl - ((QUOTEMODE SYMBOL) - `(wisent-raw-tag + ((QUOTEMODE SYMBOL) + `(wisent-raw-tag (semantic-tag ',$2 'quotemode)))) (start_decl - ((START symbols) - `(wisent-raw-tag + ((START symbols) + `(wisent-raw-tag (semantic-tag ',(car $2) - 'start :rest ',(cdr $2))))) + 'start :rest ',(cdr $2))))) (keyword_decl - ((KEYWORD SYMBOL string_value) - `(wisent-raw-tag + ((KEYWORD SYMBOL string_value) + `(wisent-raw-tag (semantic-tag ',$2 'keyword :value ',$3)))) (token_decl - ((TOKEN token_type_opt SYMBOL string_value) - `(wisent-raw-tag + ((TOKEN token_type_opt SYMBOL string_value) + `(wisent-raw-tag (semantic-tag ',$3 ',(if $2 'token 'keyword) - :type ',$2 :value ',$4))) - ((TOKEN token_type_opt symbols) - `(wisent-raw-tag + :type ',$2 :value ',$4))) + ((TOKEN token_type_opt symbols) + `(wisent-raw-tag (semantic-tag ',(car $3) - 'token :type ',$2 :rest ',(cdr $3))))) + 'token :type ',$2 :rest ',(cdr $3))))) (token_type_opt - (nil) - ((token_type))) + (nil) + ((token_type))) (token_type - ((LT SYMBOL GT) - (progn $2))) + ((LT SYMBOL GT) + (progn $2))) (type_decl - ((TYPE token_type plist_opt) - `(wisent-raw-tag + ((TYPE token_type plist_opt) + `(wisent-raw-tag (semantic-tag ',$2 'type :value ',$3)))) (plist_opt - (nil) - ((plist))) + (nil) + ((plist))) (plist - ((plist put_value) - (append + ((plist put_value) + (append (list $2) $1)) - ((put_value) - (list $1))) + ((put_value) + (list $1))) (use_name_list - ((BRACE_BLOCK) - (mapcar 'semantic-tag-name - (semantic-parse-region + ((BRACE_BLOCK) + (mapcar 'semantic-tag-name + (semantic-parse-region (car $region1) (cdr $region1) 'use_names 1)))) (use_names - ((LBRACE) - nil) - ((RBRACE) - nil) - ((SYMBOL) - (wisent-raw-tag + ((LBRACE) + nil) + ((RBRACE) + nil) + ((SYMBOL) + (wisent-raw-tag (semantic-tag $1 'use-name)))) (use_macros_decl - ((USE-MACROS SYMBOL use_name_list) - `(wisent-raw-tag + ((USE-MACROS SYMBOL use_name_list) + `(wisent-raw-tag (semantic-tag "macro" 'macro :type ',$2 :value ',$3)))) (string_value - ((STRING) - (read $1))) + ((STRING) + (read $1))) (any_value - ((SYMBOL)) - ((STRING)) - ((PAREN_BLOCK)) - ((PREFIXED_LIST)) - ((SEXP))) + ((SYMBOL)) + ((STRING)) + ((PAREN_BLOCK)) + ((PREFIXED_LIST)) + ((SEXP))) (symbols - ((lifo_symbols) - (nreverse $1))) + ((lifo_symbols) + (nreverse $1))) (lifo_symbols - ((lifo_symbols SYMBOL) - (cons $2 $1)) - ((SYMBOL) - (list $1))) + ((lifo_symbols SYMBOL) + (cons $2 $1)) + ((SYMBOL) + (list $1))) (nonterminal - ((SYMBOL + ((SYMBOL (setq semantic-grammar-wy--nterm $1 semantic-grammar-wy--rindx 0) COLON rules SEMI) - (wisent-raw-tag + (wisent-raw-tag (semantic-tag $1 'nonterminal :children $4)))) (rules - ((lifo_rules) - (apply 'nconc - (nreverse $1)))) + ((lifo_rules) + (apply 'nconc + (nreverse $1)))) (lifo_rules - ((lifo_rules OR rule) - (cons $3 $1)) - ((rule) - (list $1))) + ((lifo_rules OR rule) + (cons $3 $1)) + ((rule) + (list $1))) (rule - ((rhs) - (let* + ((rhs) + (let* ((nterm semantic-grammar-wy--nterm) (rindx semantic-grammar-wy--rindx) (rhs $1) comps prec action elt) (setq semantic-grammar-wy--rindx - (1+ semantic-grammar-wy--rindx)) + (1+ semantic-grammar-wy--rindx)) (while rhs (setq elt (car rhs) @@ -359,10 +364,10 @@ (if (or action comps) (setq comps - (cons elt comps) - semantic-grammar-wy--rindx - (1+ semantic-grammar-wy--rindx)) - (setq action + (cons elt comps) + semantic-grammar-wy--rindx + (1+ semantic-grammar-wy--rindx)) + (setq action (car elt)))) (t (setq comps @@ -375,46 +380,46 @@ (if comps "group" "empty") :value comps :prec prec :expr action)))))) (rhs - (nil) - ((rhs item) - (cons $2 $1)) - ((rhs action) - (cons + (nil) + ((rhs item) + (cons $2 $1)) + ((rhs action) + (cons (list $2) $1)) - ((rhs PREC item) - (cons + ((rhs PREC item) + (cons (vector $3) $1))) (action - ((PAREN_BLOCK)) - ((PREFIXED_LIST)) - ((BRACE_BLOCK) - (format "(progn\n%s)" - (let + ((PAREN_BLOCK)) + ((PREFIXED_LIST)) + ((BRACE_BLOCK) + (format "(progn\n%s)" + (let ((s $1)) (if - (string-match "^{[\r\n\t ]*" s) + (string-match "^{[ \n ]*" s) (setq s (substring s - (match-end 0)))) + (match-end 0)))) (if - (string-match "[\r\n\t ]*}$" s) + (string-match "[ \n ]*}$" s) (setq s (substring s 0 - (match-beginning 0)))) + (match-beginning 0)))) s)))) (items - ((lifo_items) - (nreverse $1))) + ((lifo_items) + (nreverse $1))) (lifo_items - ((lifo_items item) - (cons $2 $1)) - ((item) - (list $1))) + ((lifo_items item) + (cons $2 $1)) + ((item) + (list $1))) (item - ((SYMBOL)) - ((CHARACTER)))) + ((SYMBOL)) + ((CHARACTER)))) '(grammar prologue epilogue declaration nonterminal rule put_names put_values use_names))) "Parser table.") @@ -423,25 +428,26 @@ (semantic-install-function-overrides '((semantic-parse-stream . wisent-parse-stream))) (setq semantic-parser-name "LALR" - semantic--parse-table semantic-grammar-wy--parse-table - semantic-debug-parser-source "grammar.wy" - semantic-flex-keywords-obarray semantic-grammar-wy--keyword-table - semantic-lex-types-obarray semantic-grammar-wy--token-table) + semantic--parse-table semantic-grammar-wy--parse-table + semantic-debug-parser-source "grammar.wy" + semantic-flex-keywords-obarray semantic-grammar-wy--keyword-table + semantic-lex-types-obarray semantic-grammar-wy--token-table) ;; Collect unmatched syntax lexical tokens (add-hook 'wisent-discarding-token-functions - 'wisent-collect-unmatched-syntax nil t)) + 'wisent-collect-unmatched-syntax nil t)) ;;; Analyzers ;; -(define-lex-block-type-analyzer semantic-grammar-wy---block-analyzer - "block analyzer for tokens." - "\\s(\\|\\s)" - '((("(" LPAREN PAREN_BLOCK) - ("{" LBRACE BRACE_BLOCK)) - (")" RPAREN) - ("}" RBRACE)) - ) +(define-lex-regex-type-analyzer semantic-grammar-wy---regexp-analyzer + "regexp analyzer for tokens." + ":?\\(\\sw\\|\\s_\\)+" + '((PERCENT_PERCENT . "\\`%%\\'")) + 'SYMBOL) + +(define-lex-keyword-type-analyzer semantic-grammar-wy---keyword-analyzer + "keyword analyzer for tokens." + "\\(\\sw\\|\\s_\\)+") (define-lex-regex-type-analyzer semantic-grammar-wy---regexp-analyzer "regexp analyzer for tokens." @@ -449,21 +455,19 @@ nil 'CHARACTER) -(define-lex-regex-type-analyzer semantic-grammar-wy---regexp-analyzer - "regexp analyzer for tokens." - ":?\\(\\sw\\|\\s_\\)+" - '((PERCENT_PERCENT . "\\`%%\\'")) - 'SYMBOL) - (define-lex-sexp-type-analyzer semantic-grammar-wy---sexp-analyzer "sexp analyzer for tokens." "\\s'\\s-*(" 'PREFIXED_LIST) -(define-lex-sexp-type-analyzer semantic-grammar-wy---sexp-analyzer - "sexp analyzer for tokens." - "\\s\"" - 'STRING) +(define-lex-block-type-analyzer semantic-grammar-wy---block-analyzer + "block analyzer for tokens." + "\\s(\\|\\s)" + '((("(" LPAREN PAREN_BLOCK) + ("{" LBRACE BRACE_BLOCK)) + (")" RPAREN) + ("}" RBRACE)) + ) (define-lex-string-type-analyzer semantic-grammar-wy---string-analyzer "string analyzer for tokens." @@ -475,9 +479,10 @@ (COLON . ":")) 'punctuation) -(define-lex-keyword-type-analyzer semantic-grammar-wy---keyword-analyzer - "keyword analyzer for tokens." - "\\(\\sw\\|\\s_\\)+") +(define-lex-sexp-type-analyzer semantic-grammar-wy---sexp-analyzer + "sexp analyzer for tokens." + "\\s\"" + 'STRING) (define-lex-sexp-type-analyzer semantic-grammar-wy---sexp-analyzer "sexp analyzer for tokens." @@ -493,4 +498,9 @@ (provide 'semantic/grammar-wy) +;; Local Variables: +;; version-control: never +;; no-update-autoloads: t +;; End: + ;;; semantic/grammar-wy.el ends here diff --git a/lisp/cedet/semantic/wisent/grammar.el b/lisp/cedet/semantic/wisent/grammar.el index cfd4899186..edc5c5c702 100644 --- a/lisp/cedet/semantic/wisent/grammar.el +++ b/lisp/cedet/semantic/wisent/grammar.el @@ -1,4 +1,4 @@ -;;; semantic/wisent/grammar.el --- Wisent's input grammar mode +;;; semantic/wisent/grammar.el --- Wisent's input grammar mode -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. ;; @@ -228,7 +228,7 @@ Keep order of declaration in the WY file without duplicates." Return the expanded expression." (if (or (atom expr) (semantic-grammar-quote-p (car expr))) expr ;; Just return atom or quoted expression. - (let* ((expr (mapcar 'wisent-grammar-expand-macros expr)) + (let* ((expr (mapcar #'wisent-grammar-expand-macros expr)) (macro (assq (car expr) wisent--grammar-macros))) (if macro ;; Expand Semantic built-in. (apply (cdr macro) (cdr expr)) @@ -514,7 +514,8 @@ Menu items are appended to the common grammar menu.") (goto-char (point-min)) (delete-region (point-min) (line-end-position)) (insert ";;; " packagename - " --- Generated parser support file") + " --- Generated parser support file " + "-*- lexical-binding:t -*-") (re-search-forward ";;; \\(.*\\) ends here") (replace-match packagename nil nil nil 1) (delete-trailing-whitespace)))))) diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 7b05f5796a..b7afef6516 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -36,7 +36,7 @@ (defun minibuffer-prompt-properties--setter (symbol value) (set-default symbol value) (if (memq 'cursor-intangible value) - (add-hook 'minibuffer-setup-hook 'cursor-intangible-mode) + (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) ;; Removing it is a bit trickier since it could have been added by someone ;; else as well, so let's just not bother. )) commit 4b5155673dcbffeb126a063a2288a360473cd845 Author: Stefan Kangas Date: Sat Mar 6 04:08:54 2021 +0100 ; Fix typo. diff --git a/lisp/emacs-lisp/easymenu.el b/lisp/emacs-lisp/easymenu.el index d3c3d5e65f..87b34e7cd5 100644 --- a/lisp/emacs-lisp/easymenu.el +++ b/lisp/emacs-lisp/easymenu.el @@ -193,7 +193,7 @@ This is expected to be bound to a mouse event." (vector 'menu-bar (if (symbolp (car menu)) (car menu) ;; If a string, then use the downcased - ;; version for greater backwards compatibiltiy. + ;; version for greater backwards compatibility. (intern (downcase (car menu))))) (easy-menu-binding keymap (car menu)))))) commit 106e6f48bf3c48cc265ac12e3761afada0b31be5 Author: Stefan Kangas Date: Sat Mar 6 03:17:23 2021 +0100 Add some new tests for keymap.c * test/src/keymap-tests.el (keymap-define-key/undefined) (keymap-define-key/keyboard-macro, keymap-define-key/lambda) (keymap-define-key/keymap, keymap-define-key/menu-item) (keymap-lookup-key/list-of-keymaps, keymap-lookup-key/too-long): New tests. (keymap-lookup-key): Extend test slightly. diff --git a/test/src/keymap-tests.el b/test/src/keymap-tests.el index d4f5fc3f19..a9b0cb502d 100644 --- a/test/src/keymap-tests.el +++ b/test/src/keymap-tests.el @@ -63,10 +63,66 @@ (keymap--get-keyelt object t) (should menu-item-filter-ran))) +(ert-deftest keymap-define-key/undefined () + ;; nil (means key is undefined in this keymap), + (let ((map (make-keymap))) + (define-key map [?a] nil) + (should-not (lookup-key map [?a])))) + +(ert-deftest keymap-define-key/keyboard-macro () + ;; a string (treated as a keyboard macro), + (let ((map (make-keymap))) + (define-key map [?a] "abc") + (should (equal (lookup-key map [?a]) "abc")))) + +(ert-deftest keymap-define-key/lambda () + (let ((map (make-keymap))) + (define-key map [?a] (lambda () (interactive) nil)) + (should (functionp (lookup-key map [?a]))))) + +(ert-deftest keymap-define-key/keymap () + ;; a keymap (to define a prefix key), + (let ((map (make-keymap)) + (map2 (make-keymap))) + (define-key map [?a] map2) + (define-key map2 [?b] 'foo) + (should (eq (lookup-key map [?a ?b]) 'foo)))) + +(ert-deftest keymap-define-key/menu-item () + ;; or an extended menu item definition. + ;; (See info node ‘(elisp)Extended Menu Items’.) + (let ((map (make-sparse-keymap)) + (menu (make-sparse-keymap))) + (define-key menu [new-file] + '(menu-item "Visit New File..." find-file + :enable (menu-bar-non-minibuffer-window-p) + :help "Specify a new file's name, to edit the file")) + (define-key map [menu-bar file] (cons "File" menu)) + (should (eq (lookup-key map [menu-bar file new-file]) 'find-file)))) + (ert-deftest keymap-lookup-key () (let ((map (make-keymap))) (define-key map [?a] 'foo) - (should (eq (lookup-key map [?a]) 'foo)))) + (should (eq (lookup-key map [?a]) 'foo)) + (should-not (lookup-key map [?b])))) + +(ert-deftest keymap-lookup-key/list-of-keymaps () + (let ((map1 (make-keymap)) + (map2 (make-keymap))) + (define-key map1 [?a] 'foo) + (define-key map2 [?b] 'bar) + (should (eq (lookup-key (list map1 map2) [?a]) 'foo)) + (should (eq (lookup-key (list map1 map2) [?b]) 'bar)) + (should-not (lookup-key (list map1 map2) [?c])))) + +(ert-deftest keymap-lookup-key/too-long () + (let ((map (make-keymap))) + (define-key map (kbd "C-c f") 'foo) + (should (= (lookup-key map (kbd "C-c f x")) 2)))) + +;; TODO: Write test for the ACCEPT-DEFAULT argument. +;; (ert-deftest keymap-lookup-key/accept-default () +;; ...) (ert-deftest describe-buffer-bindings/header-in-current-buffer () "Header should be inserted into the current buffer. commit 0f85f2c0e54894a5d7edbffb0d8b29033f4a2af7 Author: Stefan Monnier Date: Fri Mar 5 21:00:00 2021 -0500 * lisp/cedet/srecode/*.el: Use lexical-binding * lisp/cedet/srecode/compile.el (srecode-compile-inserter): Use `make-instance` instead of the class name-as-function. * lisp/cedet/srecode/fields.el (srecode-field-behind-hook): Remove unused var `field`. * lisp/cedet/srecode/find.el (srecode-load-tables-for-mode): Simplify. * lisp/cedet/srecode/getset.el (srecode-semantic-selected-tag): Declare var. * lisp/cedet/srecode/mode.el (srecode-minor-mode): Mark references to non-existing `srecode-m3-items` function. * lisp/cedet/srecode/srt-mode.el (srecode-parse-this-macro): Remove unused var `raw`. diff --git a/lisp/cedet/semantic/bovine.el b/lisp/cedet/semantic/bovine.el index 3bc0e4dd61..65d7868588 100644 --- a/lisp/cedet/semantic/bovine.el +++ b/lisp/cedet/semantic/bovine.el @@ -283,7 +283,7 @@ list of semantic tokens found." ;; Make it the default parser ;;;###autoload -(defalias 'semantic-parse-stream-default 'semantic-bovinate-stream) +(defalias 'semantic-parse-stream-default #'semantic-bovinate-stream) (provide 'semantic/bovine) diff --git a/lisp/cedet/semantic/edit.el b/lisp/cedet/semantic/edit.el index f39cc093cc..4594d7f696 100644 --- a/lisp/cedet/semantic/edit.el +++ b/lisp/cedet/semantic/edit.el @@ -828,8 +828,7 @@ This function is for internal use by `semantic-edits-incremental-parser'." ;; Make it the default changes parser ;;;###autoload -(defalias 'semantic-parse-changes-default - 'semantic-edits-incremental-parser) +(defalias 'semantic-parse-changes-default #'semantic-edits-incremental-parser) ;;; Cache Splicing ;; diff --git a/lisp/cedet/srecode/args.el b/lisp/cedet/srecode/args.el index 24c5f22f2e..79d2700c5d 100644 --- a/lisp/cedet/srecode/args.el +++ b/lisp/cedet/srecode/args.el @@ -1,4 +1,4 @@ -;;; srecode/args.el --- Provide some simple template arguments +;;; srecode/args.el --- Provide some simple template arguments -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/srecode/compile.el b/lisp/cedet/srecode/compile.el index 7146b64383..22cacab078 100644 --- a/lisp/cedet/srecode/compile.el +++ b/lisp/cedet/srecode/compile.el @@ -1,4 +1,4 @@ -;;; srecode/compile --- Compilation of srecode template files. +;;; srecode/compile --- Compilation of srecode template files. -*- lexical-binding: t; -*- ;; Copyright (C) 2005, 2007-2021 Free Software Foundation, Inc. @@ -499,7 +499,7 @@ PROPS are additional properties that might need to be passed to the inserter constructor." ;;(message "Compile: %s %S" name props) (if (not key) - (apply 'srecode-template-inserter-variable name props) + (make-instance 'srecode-template-inserter-variable name props) (let ((classes (eieio-class-children 'srecode-template-inserter)) (new nil)) ;; Loop over the various subclasses and diff --git a/lisp/cedet/srecode/cpp.el b/lisp/cedet/srecode/cpp.el index 1b9610f3f1..3f66898c9c 100644 --- a/lisp/cedet/srecode/cpp.el +++ b/lisp/cedet/srecode/cpp.el @@ -1,4 +1,4 @@ -;;; srecode/cpp.el --- C++ specific handlers for Semantic Recoder +;;; srecode/cpp.el --- C++ specific handlers for Semantic Recoder -*- lexical-binding: t; -*- ;; Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc. @@ -44,7 +44,6 @@ A dictionary entry of the named PREFIX_NAMESPACE with the value NAMESPACE:: is created for each namespace unless the current buffer contains a using NAMESPACE; statement." - :group 'srecode-cpp :type '(repeat string)) ;;; :c ARGUMENT HANDLING diff --git a/lisp/cedet/srecode/ctxt.el b/lisp/cedet/srecode/ctxt.el index 20334f9583..c49237b94c 100644 --- a/lisp/cedet/srecode/ctxt.el +++ b/lisp/cedet/srecode/ctxt.el @@ -1,4 +1,4 @@ -;;; srecode/ctxt.el --- Derive a context from the source buffer. +;;; srecode/ctxt.el --- Derive a context from the source buffer. -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/srecode/dictionary.el b/lisp/cedet/srecode/dictionary.el index c1fe4b2c34..5da045e17f 100644 --- a/lisp/cedet/srecode/dictionary.el +++ b/lisp/cedet/srecode/dictionary.el @@ -1,4 +1,4 @@ -;;; srecode/dictionary.el --- Dictionary code for the semantic recoder. +;;; srecode/dictionary.el --- Dictionary code for the semantic recoder. -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. @@ -443,8 +443,8 @@ The root dictionary is usually for a current or active insertion." ;; for use in converting the compound value into something insertable. (cl-defmethod srecode-compound-toString ((cp srecode-dictionary-compound-value) - function - dictionary) + _function + _dictionary) "Convert the compound dictionary value CP to a string. If FUNCTION is non-nil, then FUNCTION is somehow applied to an aspect of the compound value. The FUNCTION could be a fraction @@ -457,14 +457,15 @@ standard out is a buffer, and using `insert'." (eieio-object-name cp)) (cl-defmethod srecode-dump ((cp srecode-dictionary-compound-value) - &optional indent) + &optional _indent) "Display information about this compound value." (princ (eieio-object-name cp)) ) -(cl-defmethod srecode-compound-toString ((cp srecode-dictionary-compound-variable) - function - dictionary) +(cl-defmethod srecode-compound-toString + ((cp srecode-dictionary-compound-variable) + _function + dictionary) "Convert the compound dictionary variable value CP into a string. FUNCTION and DICTIONARY are as for the baseclass." (require 'srecode/insert) @@ -606,9 +607,9 @@ STATE is the current compiler state." (require 'srecode/find) (let* ((modesym major-mode) (start (current-time)) - (junk (or (progn (srecode-load-tables-for-mode modesym) - (srecode-get-mode-table modesym)) - (error "No table found for mode %S" modesym))) + (_ (or (progn (srecode-load-tables-for-mode modesym) + (srecode-get-mode-table modesym)) + (error "No table found for mode %S" modesym))) (dict (srecode-create-dictionary (current-buffer))) ) (message "Creating a dictionary took %.2f seconds." diff --git a/lisp/cedet/srecode/document.el b/lisp/cedet/srecode/document.el index 0d1a4c01d3..270b80d901 100644 --- a/lisp/cedet/srecode/document.el +++ b/lisp/cedet/srecode/document.el @@ -1,4 +1,4 @@ -;;; srecode/document.el --- Documentation (comment) generation +;;; srecode/document.el --- Documentation (comment) generation -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -88,7 +88,6 @@ versions of names. This is an alist with each element of the form: (MATCH . RESULT) MATCH is a regexp to match in the type field. RESULT is a string." - :group 'document :type '(repeat (cons (regexp :tag "Regexp") (string :tag "Doc Text")))) @@ -144,7 +143,6 @@ A string may end in a space, in which case, last-alist is searched to see how best to describe what can be returned. Doesn't always work correctly, but that is just because English doesn't always work correctly." - :group 'document :type '(repeat (cons (regexp :tag "Regexp") (string :tag "Doc Text")))) @@ -175,7 +173,6 @@ versions of names. This is an alist with each element of the form: (MATCH . RESULT) MATCH is a regexp to match in the type field. RESULT is a string." - :group 'document :type '(repeat (cons (regexp :tag "Regexp") (string :tag "Doc Text")))) @@ -192,7 +189,6 @@ This is an alist with each element of the form: (MATCH . RESULT) MATCH is a regexp to match in the type field. RESULT is a string." - :group 'document :type '(repeat (cons (regexp :tag "Regexp") (string :tag "Doc Text")))) @@ -213,7 +209,6 @@ This is an alist with each element of the form: MATCH is a regexp to match in the type field. RESULT is a string, which can contain %s, which is replaced with `match-string' 1." - :group 'document :type '(repeat (cons (regexp :tag "Regexp") (string :tag "Doc Text")))) @@ -233,7 +228,6 @@ MATCH is a regexp to match in the type field. RESULT is a string of text to use to describe MATCH. When one is encountered, document-insert-parameters will automatically place this comment after the parameter name." - :group 'document :type '(repeat (cons (regexp :tag "Regexp") (string :tag "Doc Text")))) @@ -258,7 +252,6 @@ This is an alist with each element of the form: (MATCH . RESULT) MATCH is a regexp to match in the type field. RESULT is a string." - :group 'document :type '(repeat (cons (regexp :tag "Regexp") (string :tag "Doc Text")))) @@ -716,7 +709,7 @@ allocating something based on its type." (setq al (cdr al))))) news)) -(defun srecode-document-parameter-comment (param &optional commentlist) +(defun srecode-document-parameter-comment (param &optional _commentlist) "Convert tag or string PARAM into a name,comment pair. Optional COMMENTLIST is list of previously existing comments to use instead in alist form. If the name doesn't appear in the list of diff --git a/lisp/cedet/srecode/el.el b/lisp/cedet/srecode/el.el index 7e9dd10fd4..974a4fac72 100644 --- a/lisp/cedet/srecode/el.el +++ b/lisp/cedet/srecode/el.el @@ -1,4 +1,4 @@ -;;; srecode/el.el --- Emacs Lisp specific arguments +;;; srecode/el.el --- Emacs Lisp specific arguments -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/srecode/expandproto.el b/lisp/cedet/srecode/expandproto.el index cdb29d16b7..a40d5aec24 100644 --- a/lisp/cedet/srecode/expandproto.el +++ b/lisp/cedet/srecode/expandproto.el @@ -1,4 +1,4 @@ -;;; srecode/expandproto.el --- Expanding prototypes. +;;; srecode/expandproto.el --- Expanding prototypes. -*- lexical-binding: t; -*- ;; Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/srecode/extract.el b/lisp/cedet/srecode/extract.el index 625b854b77..9e6a98fd76 100644 --- a/lisp/cedet/srecode/extract.el +++ b/lisp/cedet/srecode/extract.el @@ -1,4 +1,4 @@ -;;; srecode/extract.el --- Extract content from previously inserted macro. +;;; srecode/extract.el --- Extract content from previously inserted macro. -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -139,24 +139,24 @@ Uses STATE to maintain the current extraction state." ;;; Inserter Base Extractors ;; -(cl-defmethod srecode-inserter-do-extract-p ((ins srecode-template-inserter)) +(cl-defmethod srecode-inserter-do-extract-p ((_ins srecode-template-inserter)) "Return non-nil if this inserter can extract values." nil) -(cl-defmethod srecode-inserter-extract ((ins srecode-template-inserter) - start end dict state) +(cl-defmethod srecode-inserter-extract ((_ins srecode-template-inserter) + _start _end _dict _state) "Extract text from START/END and store in DICT. Return nil as this inserter will extract nothing." nil) ;;; Variable extractor is simple and can extract later. ;; -(cl-defmethod srecode-inserter-do-extract-p ((ins srecode-template-inserter-variable)) +(cl-defmethod srecode-inserter-do-extract-p ((_ins srecode-template-inserter-variable)) "Return non-nil if this inserter can extract values." 'later) (cl-defmethod srecode-inserter-extract ((ins srecode-template-inserter-variable) - start end vdict state) + start end vdict _state) "Extract text from START/END and store in VDICT. Return t if something was extracted. Return nil if this inserter doesn't need to extract anything." @@ -168,12 +168,12 @@ Return nil if this inserter doesn't need to extract anything." ;;; Section Inserter ;; -(cl-defmethod srecode-inserter-do-extract-p ((ins srecode-template-inserter-section-start)) +(cl-defmethod srecode-inserter-do-extract-p ((_ins srecode-template-inserter-section-start)) "Return non-nil if this inserter can extract values." 'now) (cl-defmethod srecode-inserter-extract ((ins srecode-template-inserter-section-start) - start end indict state) + _start _end indict state) "Extract text from START/END and store in INDICT. Return the starting location of the first plain-text match. Return nil if nothing was extracted." @@ -201,12 +201,12 @@ Return nil if nothing was extracted." ;;; Include Extractor must extract now. ;; -(cl-defmethod srecode-inserter-do-extract-p ((ins srecode-template-inserter-include)) +(cl-defmethod srecode-inserter-do-extract-p ((_ins srecode-template-inserter-include)) "Return non-nil if this inserter can extract values." 'now) (cl-defmethod srecode-inserter-extract ((ins srecode-template-inserter-include) - start end dict state) + start _end dict state) "Extract text from START/END and store in DICT. Return the starting location of the first plain-text match. Return nil if nothing was extracted." diff --git a/lisp/cedet/srecode/fields.el b/lisp/cedet/srecode/fields.el index 71613bcc2a..e65e319432 100644 --- a/lisp/cedet/srecode/fields.el +++ b/lisp/cedet/srecode/fields.el @@ -1,4 +1,4 @@ -;;; srecode/fields.el --- Handling type-in fields in a buffer. +;;; srecode/fields.el --- Handling type-in fields in a buffer. -*- lexical-binding: t; -*- ;; ;; Copyright (C) 2009-2021 Free Software Foundation, Inc. ;; @@ -193,7 +193,7 @@ If SET-TO is a string, then replace the text of OLAID with SET-TO." "Manage a buffer region in which fields exist.") (cl-defmethod initialize-instance ((ir srecode-template-inserted-region) - &rest args) + &rest _args) "Initialize IR, capturing the active fields, and creating the overlay." ;; Fill in the fields (oset ir fields srecode-field-archive) @@ -221,7 +221,7 @@ If SET-TO is a string, then replace the text of OLAID with SET-TO." (oset ir active-region ir) ;; Setup the post command hook. - (add-hook 'post-command-hook 'srecode-field-post-command t t) + (add-hook 'post-command-hook #'srecode-field-post-command t t) ) (cl-defmethod srecode-delete ((ir srecode-template-inserted-region)) @@ -229,12 +229,11 @@ If SET-TO is a string, then replace the text of OLAID with SET-TO." ;; Clear us out of the baseclass. (oset ir active-region nil) ;; Clear our fields. - (mapc 'srecode-delete (oref ir fields)) + (mapc #'srecode-delete (oref ir fields)) ;; Call to our base (cl-call-next-method) ;; Clear our hook. - (remove-hook 'post-command-hook 'srecode-field-post-command t) - ) + (remove-hook 'post-command-hook #'srecode-field-post-command t)) (defsubst srecode-active-template-region () "Return the active region for template fields." @@ -246,7 +245,7 @@ If SET-TO is a string, then replace the text of OLAID with SET-TO." ) (if (not ar) ;; Find a bug and fix it. - (remove-hook 'post-command-hook 'srecode-field-post-command t) + (remove-hook 'post-command-hook #'srecode-field-post-command t) (if (srecode-point-in-region-p ar) nil ;; Keep going ;; We moved out of the template. Cancel the edits. @@ -277,16 +276,16 @@ Try to use this to provide useful completion when available.") (defvar srecode-field-keymap (let ((km (make-sparse-keymap))) - (define-key km "\C-i" 'srecode-field-next) - (define-key km "\M-\C-i" 'srecode-field-prev) - (define-key km "\C-e" 'srecode-field-end) - (define-key km "\C-a" 'srecode-field-start) - (define-key km "\M-m" 'srecode-field-start) - (define-key km "\C-c\C-c" 'srecode-field-exit-ask) + (define-key km "\C-i" #'srecode-field-next) + (define-key km "\M-\C-i" #'srecode-field-prev) + (define-key km "\C-e" #'srecode-field-end) + (define-key km "\C-a" #'srecode-field-start) + (define-key km "\M-m" #'srecode-field-start) + (define-key km "\C-c\C-c" #'srecode-field-exit-ask) km) "Keymap applied to field overlays.") -(cl-defmethod initialize-instance ((field srecode-field) &optional args) +(cl-defmethod initialize-instance ((field srecode-field) &optional _args) "Initialize FIELD, being sure it archived." (add-to-list 'srecode-field-archive field t) (cl-call-next-method) @@ -327,7 +326,7 @@ Try to use this to provide useful completion when available.") (defvar srecode-field-replication-max-size 100 "Maximum size of a field before canceling replication.") -(defun srecode-field-mod-hook (ol after start end &optional pre-len) +(defun srecode-field-mod-hook (ol after _start _end &optional _pre-len) "Modification hook for the field overlay. OL is the overlay. AFTER is non-nil if it is called after the change. @@ -374,7 +373,7 @@ AFTER is non-nil if it is called after the change. START and END are the bounds of the change. PRE-LEN is used in the after mode for the length of the changed text." (when after - (let* ((field (overlay-get ol 'srecode)) + (let* (;; (field (overlay-get ol 'srecode)) ) (move-overlay ol (overlay-start ol) end) (srecode-field-mod-hook ol after start end pre-len)) diff --git a/lisp/cedet/srecode/filters.el b/lisp/cedet/srecode/filters.el index 4a996cf6f1..b76ce2c94b 100644 --- a/lisp/cedet/srecode/filters.el +++ b/lisp/cedet/srecode/filters.el @@ -1,4 +1,4 @@ -;;; srecode/filters.el --- Filters for use in template variables. +;;; srecode/filters.el --- Filters for use in template variables. -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/srecode/find.el b/lisp/cedet/srecode/find.el index aec73dce5a..1c208d0f32 100644 --- a/lisp/cedet/srecode/find.el +++ b/lisp/cedet/srecode/find.el @@ -1,4 +1,4 @@ -;;;; srecode/find.el --- Tools for finding templates in the database. +;;;; srecode/find.el --- Tools for finding templates in the database. -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. @@ -58,17 +58,14 @@ See `srecode-get-maps' for more. APPNAME is the name of an application. In this case, all template files for that application will be loaded." (let ((files - (if appname - (apply 'append - (mapcar + (apply #'append + (mapcar + (if appname (lambda (map) (srecode-map-entries-for-app-and-mode map appname mmode)) - (srecode-get-maps))) - (apply 'append - (mapcar (lambda (map) - (srecode-map-entries-for-mode map mmode)) - (srecode-get-maps))))) + (srecode-map-entries-for-mode map mmode))) + (srecode-get-maps)))) ) ;; Don't recurse if we are already the 'default state. (when (not (eq mmode 'default)) @@ -112,8 +109,8 @@ If TAB is nil, then always return t." ;; Find a given template based on name, and features of the current ;; buffer. (cl-defmethod srecode-template-get-table ((tab srecode-template-table) - template-name &optional - context application) + template-name &optional + context _application) "Find in the template in table TAB, the template with TEMPLATE-NAME. Optional argument CONTEXT specifies that the template should part of a particular context. @@ -218,7 +215,7 @@ tables that do not belong to an application will be searched." (defvar srecode-read-template-name-history nil "History for completing reads for template names.") -(defun srecode-user-template-p (template) +(defun srecode-user-template-p (_template) "Non-nil if TEMPLATE is intended for user insertion. Templates not matching this predicate are used for code generation or other internal purposes." @@ -264,7 +261,7 @@ with `srecode-calculate-context'." ;; the prefix for the completing read (concat (nth 0 ctxt) ":")))) -(defun srecode-read-template-name (prompt &optional initial hist default) +(defun srecode-read-template-name (prompt &optional initial hist _default) "Completing read for Semantic Recoder template names. PROMPT is used to query for the name of the template desired. INITIAL is the initial string to use. diff --git a/lisp/cedet/srecode/getset.el b/lisp/cedet/srecode/getset.el index 1e4888655f..ce4c818c70 100644 --- a/lisp/cedet/srecode/getset.el +++ b/lisp/cedet/srecode/getset.el @@ -1,4 +1,4 @@ -;;; srecode/getset.el --- Package for inserting new get/set methods. +;;; srecode/getset.el --- Package for inserting new get/set methods. -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. @@ -33,6 +33,8 @@ (defvar srecode-insert-getset-fully-automatic-flag nil "Non-nil means accept choices srecode comes up with without asking.") +(defvar srecode-semantic-selected-tag) + ;;;###autoload (defun srecode-insert-getset (&optional class-in field-in) "Insert get/set methods for the current class. diff --git a/lisp/cedet/srecode/java.el b/lisp/cedet/srecode/java.el index 768d48a7c5..0f0a80ee29 100644 --- a/lisp/cedet/srecode/java.el +++ b/lisp/cedet/srecode/java.el @@ -1,4 +1,4 @@ -;;; srecode/java.el --- Srecode Java support +;;; srecode/java.el --- Srecode Java support -*- lexical-binding: t; -*- ;; Copyright (C) 2009-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/srecode/map.el b/lisp/cedet/srecode/map.el index a94db0bb8d..254b15e6e0 100644 --- a/lisp/cedet/srecode/map.el +++ b/lisp/cedet/srecode/map.el @@ -1,4 +1,4 @@ -;;; srecode/map.el --- Manage a template file map +;;; srecode/map.el --- Manage a template file map -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -245,7 +245,7 @@ Optional argument RESET forces a reset of the current map." (princ "\n") )) -(defun srecode-map-file-still-valid-p (filename map) +(defun srecode-map-file-still-valid-p (filename _map) "Return t if FILENAME should be in MAP still." (let ((valid nil)) (and (file-exists-p filename) @@ -407,7 +407,7 @@ Return non-nil if the map changed." "Global load path for SRecode template files." :group 'srecode :type '(repeat file) - :set 'srecode-map-load-path-set) + :set #'srecode-map-load-path-set) (provide 'srecode/map) diff --git a/lisp/cedet/srecode/mode.el b/lisp/cedet/srecode/mode.el index 159dc7a999..022a5db8f2 100644 --- a/lisp/cedet/srecode/mode.el +++ b/lisp/cedet/srecode/mode.el @@ -1,4 +1,4 @@ -;;; srecode/mode.el --- Minor mode for managing and using SRecode templates +;;; srecode/mode.el --- Minor mode for managing and using SRecode templates -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -54,14 +54,14 @@ (defvar srecode-prefix-map (let ((km (make-sparse-keymap))) ;; Basic template codes - (define-key km "/" 'srecode-insert) - (define-key km [insert] 'srecode-insert) - (define-key km "." 'srecode-insert-again) - (define-key km "E" 'srecode-edit) + (define-key km "/" #'srecode-insert) + (define-key km [insert] #'srecode-insert) + (define-key km "." #'srecode-insert-again) + (define-key km "E" #'srecode-edit) ;; Template indirect binding (let ((k ?a)) (while (<= k ?z) - (define-key km (format "%c" k) 'srecode-bind-insert) + (define-key km (format "%c" k) #'srecode-bind-insert) (setq k (1+ k)))) km) "Keymap used behind the srecode prefix key in srecode minor mode.") @@ -141,16 +141,17 @@ non-nil if the minor mode is enabled. ;; this mode first. (if srecode-minor-mode (if (not (apply - 'append + #'append (mapcar (lambda (map) (srecode-map-entries-for-mode map major-mode)) (srecode-get-maps)))) (setq srecode-minor-mode nil) ;; Else, we have success, do stuff - (add-hook 'cedet-m3-menu-do-hooks 'srecode-m3-items nil t) - ) - (remove-hook 'cedet-m3-menu-do-hooks 'srecode-m3-items t) - ) + ;; FIXME: Where are `cedet-m3-menu-do-hooks' nor `srecode-m3-items'? + (when (fboundp 'srecode-m3-items) + (add-hook 'cedet-m3-menu-do-hooks #'srecode-m3-items nil t))) + (when (fboundp 'srecode-m3-items) + (remove-hook 'cedet-m3-menu-do-hooks #'srecode-m3-items t))) ;; Run hooks if we are turning this on. (when srecode-minor-mode (run-hooks 'srecode-minor-mode-hook)) @@ -170,7 +171,7 @@ non-nil if the minor mode is enabled. ;;; Menu Filters ;; -(defun srecode-minor-mode-templates-menu (menu-def) +(defun srecode-minor-mode-templates-menu (_menu-def) "Create a menu item of cascading filters active for this mode. MENU-DEF is the menu to bind this into." ;; Doing this SEGVs Emacs on windows. @@ -246,7 +247,7 @@ MENU-DEF is the menu to bind this into." (defvar srecode-minor-mode-generators nil "List of code generators to be displayed in the srecoder menu.") -(defun srecode-minor-mode-generate-menu (menu-def) +(defun srecode-minor-mode-generate-menu (_menu-def) "Create a menu item of cascading filters active for this mode. MENU-DEF is the menu to bind this into." ;; Doing this SEGVs Emacs on windows. diff --git a/lisp/cedet/srecode/srt-mode.el b/lisp/cedet/srecode/srt-mode.el index bbe1e5e469..7157915849 100644 --- a/lisp/cedet/srecode/srt-mode.el +++ b/lisp/cedet/srecode/srt-mode.el @@ -1,4 +1,4 @@ -;;; srecode/srt-mode.el --- Major mode for writing screcode macros +;;; srecode/srt-mode.el --- Major mode for writing screcode macros -*- lexical-binding: t; -*- ;; Copyright (C) 2005, 2007-2021 Free Software Foundation, Inc. @@ -181,9 +181,9 @@ we can tell font lock about them.") (defvar srecode-template-mode-map (let ((km (make-sparse-keymap))) - (define-key km "\C-c\C-c" 'srecode-compile-templates) - (define-key km "\C-c\C-m" 'srecode-macro-help) - (define-key km "/" 'srecode-self-insert-complete-end-macro) + (define-key km "\C-c\C-c" #'srecode-compile-templates) + (define-key km "\C-c\C-m" #'srecode-macro-help) + (define-key km "/" #'srecode-self-insert-complete-end-macro) km) "Keymap used in srecode mode.") @@ -205,7 +205,7 @@ we can tell font lock about them.") ((?_ . "w") (?- . "w"))))) ;;;###autoload -(defalias 'srt-mode 'srecode-template-mode) +(defalias 'srt-mode #'srecode-template-mode) ;;; Template Commands ;; @@ -436,7 +436,7 @@ Moves to the end of one named section." (when point (goto-char (point))) (let* ((tag (semantic-current-tag)) (args (semantic-tag-function-arguments tag)) - (argsym (mapcar 'intern args)) + (argsym (mapcar #'intern args)) (argvars nil) ;; Create a temporary dictionary in which the ;; arguments can be resolved so we can extract @@ -475,7 +475,7 @@ section or ? for an ask variable." (ee (regexp-quote (srecode-template-get-escape-end))) (start (point)) (macrostart nil) - (raw nil) + ;; (raw nil) ) (when (and tag (semantic-tag-of-class-p tag 'function) (srecode-in-macro-p point) @@ -627,7 +627,7 @@ section or ? for an ask variable." context-return))) (define-mode-local-override semantic-analyze-possible-completions - srecode-template-mode (context &rest flags) + srecode-template-mode (context &rest _flags) "Return a list of possible completions based on NONTEXT." (with-current-buffer (oref context buffer) (let* ((prefix (car (last (oref context prefix)))) diff --git a/lisp/cedet/srecode/srt.el b/lisp/cedet/srecode/srt.el index e222997708..161b5105b5 100644 --- a/lisp/cedet/srecode/srt.el +++ b/lisp/cedet/srecode/srt.el @@ -1,4 +1,4 @@ -;;; srecode/srt.el --- argument handlers for SRT files +;;; srecode/srt.el --- argument handlers for SRT files -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -43,7 +43,7 @@ DEFAULT is the default if RET is hit." (currfcn (semantic-current-tag)) ) (srecode-resolve-argument-list - (mapcar 'read + (mapcar #'read (semantic-tag-get-attribute currfcn :arguments)) newdict) @@ -56,7 +56,7 @@ DEFAULT is the default if RET is hit." (defvar srecode-read-major-mode-history nil "History for `srecode-read-variable-name'.") -(defun srecode-read-major-mode-name (prompt &optional initial hist default) +(defun srecode-read-major-mode-name (prompt &optional initial hist _default) "Read in the name of a desired `major-mode'. PROMPT is the prompt to use. INITIAL is the initial string. @@ -64,7 +64,7 @@ HIST is the history value, otherwise `srecode-read-variable-name-history' is used. DEFAULT is the default if RET is hit." (completing-read prompt obarray - (lambda (s) (string-match "-mode$" (symbol-name s))) + (lambda (s) (string-match "-mode\\'" (symbol-name s))) nil initial (or hist 'srecode-read-major-mode-history)) ) diff --git a/lisp/cedet/srecode/table.el b/lisp/cedet/srecode/table.el index 60a466f89d..7ce5cc73b6 100644 --- a/lisp/cedet/srecode/table.el +++ b/lisp/cedet/srecode/table.el @@ -1,4 +1,4 @@ -;;; srecode/table.el --- Tables of Semantic Recoders +;;; srecode/table.el --- Tables of Semantic Recoders -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. @@ -169,7 +169,7 @@ calculate all inherited templates from parent modes." :modetables nil :tables nil))) ;; Save this new mode table in that mode's variable. - (eval `(setq-mode-local ,mode srecode-table ,new)) + (eval `(setq-mode-local ,mode srecode-table ,new) t) new)))) @@ -184,7 +184,7 @@ INIT are the initialization parameters for the new template table." (let* ((mt (srecode-make-mode-table mode)) (old (srecode-mode-table-find mt file)) (attr (file-attributes file)) - (new (apply 'srecode-template-table + (new (apply #'srecode-template-table (file-name-nondirectory file) :file file :filesize (file-attribute-size attr) diff --git a/lisp/cedet/srecode/template.el b/lisp/cedet/srecode/template.el index e9e5115128..4f7eaffeb4 100644 --- a/lisp/cedet/srecode/template.el +++ b/lisp/cedet/srecode/template.el @@ -1,4 +1,4 @@ -;;; srecode/template.el --- SRecoder template language parser support. +;;; srecode/template.el --- SRecoder template language parser support. -*- lexical-binding: t; -*- ;; Copyright (C) 2005, 2007-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/srecode/texi.el b/lisp/cedet/srecode/texi.el index 892ae4e2e3..1312a55a89 100644 --- a/lisp/cedet/srecode/texi.el +++ b/lisp/cedet/srecode/texi.el @@ -1,4 +1,4 @@ -;;; srecode/texi.el --- Srecode texinfo support. +;;; srecode/texi.el --- Srecode texinfo support. -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -224,7 +224,7 @@ Takes a few very generic guesses as to what the formatting is." ;; Return our modified doc string. docstring)) -(defun srecode-texi-massage-to-texinfo (tag buffer string) +(defun srecode-texi-massage-to-texinfo (_tag buffer string) "Massage TAG's documentation from BUFFER as STRING. This is to take advantage of TeXinfo's markup symbols." (save-excursion commit 533c659b6c73fd381231f25d0644c69729dd0aed Author: Stefan Monnier Date: Fri Mar 5 19:56:31 2021 -0500 Bindat: new macro-expansion based data layout language Thorough redesign of the Bindat system, which makes it possible to define new Bindat type forms, define recursive types, control the values returned when unpacking, freely mix arbitrary computations with type definitions, as well as support for arbitrary sized integers. This also reverts the recent addition of the `bindat-spec` macro and the support for 64bit integers in the old Bindat language since that is now considered obsolete anyway. * doc/lispref/processes.texi (Bindat Types): Rename from `Bindat Spec` and rewrite for the new sublanguage. (Bindat Functions): Adjust to the new terminology. (Bindat Computed Types): New node. * lisp/emacs-lisp/bindat.el (bindat--type): New type. (bindat--unpack-u64, bindat--unpack-u64r): Delete functions. (bindat--unpack-item, bindat--pack-item, bindat--fixed-length-alist): Revert addition of support for 64bit integers. (bindat--unpack-group, bindat--length-group, bindat--pack-group): Handle the new `bindat--type` values. (bindat-spec): Revert addition of this macro. (bindat--unpack-uint, bindat--unpack-uintr, bindat--pack-uint) (bindat--pack-uintr): New functions. (bindat-type, bindat-defmacro, bindat--pcase): New macros. (bindat-type): New Edebug elem. (bindat--type): New generic function. (bindat--primitives): New constant. (bindat--macroenv, bindat--op): New vars. (bindat--make-docstring, bindat--fun, bindat--makefun, bindat--toplevel): New functions. * test/lisp/emacs-lisp/bindat-tests.el: Use `bindat-type`. (ip): New Bindat type. (header-bindat-spec, data-bindat-spec, packet-bindat-spec): Adjust to new `bindat-type` macro. (bindat-test-unpack): Simplify now that the order of fields is preserved. (bindat-test--int-websocket-type, bindat-test--LEB128): New consts. (bindat-test--pack-val, bindat-test--sint, bindat-test--recursive): New tests. diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi index 12255d122f..dade855518 100644 --- a/doc/lispref/elisp.texi +++ b/doc/lispref/elisp.texi @@ -1408,8 +1408,9 @@ Low-Level Network Access Packing and Unpacking Byte Arrays -* Bindat Spec:: Describing data layout. +* Bindat Types:: Describing data layout. * Bindat Functions:: Doing the unpacking and packing. +* Bindat Computed Types:: Advanced data layout specifications. Emacs Display diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index bb4c57a619..23111f7c5c 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -3354,23 +3354,25 @@ To use the functions referred to in this section, load the direction is also known as @dfn{serializing} or @dfn{packing}. @menu -* Bindat Spec:: Describing data layout. -* Bindat Functions:: Doing the unpacking and packing. +* Bindat Types:: Describing data layout. +* Bindat Functions:: Doing the unpacking and packing. +* Bindat Computed Types:: Advanced data layout specifications. @end menu -@node Bindat Spec +@node Bindat Types @subsection Describing Data Layout To control unpacking and packing, you write a @dfn{data layout -specification}, a special nested list describing named and typed -@dfn{fields}. This specification controls the length of each field to be -processed, and how to pack or unpack it. We normally keep bindat specs -in variables whose names end in @samp{-bindat-spec}; that kind of name +specification}, also called a Bindat type expression. +This can be a base type or a composite type made of several fields, +where the specification controls the length of each field to be +processed, and how to pack or unpack it. We normally keep bindat type +values in variables whose names end in @samp{-bindat-spec}; that kind of name is automatically recognized as risky. -@defmac bindat-spec &rest specs -Creates a Bindat spec object according to the data layout -specification @var{specs}. +@defmac bindat-type &rest type +Creates a Bindat type @emph{value} object according to the Bindat type +@emph{expression} @var{type}. @end defmac @cindex endianness @@ -3391,44 +3393,27 @@ type values: @itemx byte Unsigned byte, with length 1. -@item u16 -@itemx word -@itemx short -Unsigned integer in network byte order, with length 2. +@item uint @var{bitlen} +Unsigned integer in network byte order, with @var{bitlen} bits. +@var{bitlen} has to be a multiple of 8. -@item u24 -Unsigned integer in network byte order, with length 3. - -@item u32 -@itemx dword -@itemx long -Unsigned integer in network byte order, with length 4. - -@item u64 -Unsigned integer in network byte order, with length 8. - -@item u16r -@itemx u24r -@itemx u32r -@itemx u64r -Unsigned integer in little endian order, with length 2, 3, 4, and -8, respectively. +@item uintr @var{bitlen} +Unsigned integer in little endian order, with @var{bitlen} bits. +@var{bitlen} has to be a multiple of 8. @item str @var{len} -String of length @var{len}. +String of bytes of length @var{len}. @item strz @var{len} -Zero-terminated string, in a fixed-size field with length @var{len}. +Zero-terminated string of bytes, in a fixed-size field with length @var{len}. @item vec @var{len} [@var{type}] Vector of @var{len} elements of type @var{type}, defaulting to bytes. -The @var{type} is any of the simple types above, or another vector -specified as a list of the form @code{(vec @var{len} [@var{type}])}. +The @var{type} can be any Bindat type expression. -@item ip -@c FIXME? IPv6? -Four-byte vector representing an Internet address. For example: -@code{[127 0 0 1]} for localhost. +@item repeat @var{len} [@var{type}] +Like @code{vec}, but it unpacks to and packs from lists, whereas +@code{vec} unpacks to vectors. @item bits @var{len} List of set bits in @var{len} bytes. The bytes are taken in big @@ -3437,121 +3422,59 @@ endian order and the bits are numbered starting with @code{8 * 2} unpacks @code{#x28} @code{#x1c} to @code{(2 3 4 11 13)} and @code{#x1c} @code{#x28} to @code{(3 5 10 11 12)}. -@item (eval @var{form}) -@var{form} is a Lisp expression evaluated at the moment the field is -unpacked or packed. The result of the evaluation should be one of the -above-listed type specifications. -@end table - -For a fixed-size field, the length @var{len} is given as an integer -specifying the number of bytes in the field. - -When the length of a field is not fixed, it typically depends on the -value of a preceding field. In this case, the length @var{len} can be -given either as a list @code{(@var{name} ...)} identifying a -@dfn{field name} in the format specified for @code{bindat-get-field} -below, or by an expression @code{(eval @var{form})} where @var{form} -should evaluate to an integer, specifying the field length. - -A field specification generally has the form @code{([@var{name}] -@var{handler})}, where @var{name} is optional. Don't use names that -are symbols meaningful as type specifications (above) or handler -specifications (below), since that would be ambiguous. @var{name} can -be a symbol or an expression @code{(eval @var{form})}, in which case -@var{form} should evaluate to a symbol. - -@var{handler} describes how to unpack or pack the field and can be one -of the following: - -@table @code -@item @var{type} -Unpack/pack this field according to the type specification @var{type}. - -@item eval @var{form} -Evaluate @var{form}, a Lisp expression, for side-effect only. If the -field name is specified, the value is bound to that field name. - @item fill @var{len} -Skip @var{len} bytes. In packing, this leaves them unchanged, -which normally means they remain zero. In unpacking, this means -they are ignored. +@var{len} bytes used as a mere filler. In packing, these bytes are +are left unchanged, which normally means they remain zero. +When unpacking, this just returns nil. @item align @var{len} -Skip to the next multiple of @var{len} bytes. - -@item struct @var{spec-name} -Process @var{spec-name} as a sub-specification. This describes a -structure nested within another structure. - -@item union @var{form} (@var{tag} @var{spec})@dots{} -@c ??? I don't see how one would actually use this. -@c ??? what kind of expression would be useful for @var{form}? -Evaluate @var{form}, a Lisp expression, find the first @var{tag} -that matches it, and process its associated data layout specification -@var{spec}. Matching can occur in one of three ways: - -@itemize -@item -If a @var{tag} has the form @code{(eval @var{expr})}, evaluate -@var{expr} with the variable @code{tag} dynamically bound to the value -of @var{form}. A non-@code{nil} result indicates a match. - -@item -@var{tag} matches if it is @code{equal} to the value of @var{form}. - -@item -@var{tag} matches unconditionally if it is @code{t}. -@end itemize - -@item repeat @var{count} @var{field-specs}@dots{} -Process the @var{field-specs} recursively, in order, then repeat -starting from the first one, processing all the specifications @var{count} -times overall. The @var{count} is given using the same formats as a -field length---if an @code{eval} form is used, it is evaluated just once. -For correct operation, each specification in @var{field-specs} must -include a name. +Same as @code{fill} except the number of bytes is that needed to skip +to the next multiple of @var{len} bytes. + +@item type @var{exp} +This lets you refer to a type indirectly: @var{exp} is a Lisp +expression which should return a Bindat type @emph{value}. + +@item unit @var{exp} +This is a trivial type which uses up 0 bits of space. @var{exp} +describes the value returned when we try to ``unpack'' such a field. + +@item struct @var{fields}... +Composite type made of several fields. Every field is of the form +@code{(@var{name} @var{type})} where @var{type} can be any Bindat +type expression. @var{name} can be @code{_} when the field's value +does not deserve to be named, as is often the case for @code{align} +and @code{fill} fields. +When the context makes it clear that this is a Bindat type expression, +the symbol @code{struct} can be omitted. @end table -For the @code{(eval @var{form})} forms used in a bindat specification, -the @var{form} can access and update these dynamically bound variables -during evaluation: +In the types above, @var{len} and @var{bitlen} are given as an integer +specifying the number of bytes (or bits) in the field. When the +length of a field is not fixed, it typically depends on the value of +preceding fields. For this reason, the length @var{len} does not have +to be a constant but can be any Lisp expression and it can refer to +the value of previous fields via their name. -@table @code -@item last -Value of the last field processed. - -@item bindat-raw -The data as a byte array. - -@item bindat-idx -Current index (within @code{bindat-raw}) for unpacking or packing. - -@item struct -The alist containing the structured data that have been unpacked so -far, or the entire structure being packed. You can use -@code{bindat-get-field} to access specific fields of this structure. - -@item count -@itemx index -Inside a @code{repeat} block, these contain the maximum number of -repetitions (as specified by the @var{count} parameter), and the -current repetition number (counting from 0). Setting @code{count} to -zero will terminate the inner-most repeat block after the current -repetition has completed. -@end table +For example, the specification of a data layout where a leading byte gives +the size of a subsequent vector of 16 bit integers could be: +@example +(bindat-type + (len u8) + (payload vec (1+ len) uint 16)) +@end example @node Bindat Functions @subsection Functions to Unpack and Pack Bytes - In the following documentation, @var{spec} refers to a Bindat spec -object as returned from @code{bindat-spec}, @code{raw} to a byte + In the following documentation, @var{type} refers to a Bindat type +value as returned from @code{bindat-type}, @code{raw} to a byte array, and @var{struct} to an alist representing unpacked field data. -@defun bindat-unpack spec raw &optional idx -@c FIXME? Again, no multibyte? +@defun bindat-unpack type raw &optional idx This function unpacks data from the unibyte string or byte array @var{raw} -according to @var{spec}. Normally, this starts unpacking at the +according to @var{type}. Normally, this starts unpacking at the beginning of the byte array, but if @var{idx} is non-@code{nil}, it specifies a zero-based starting position to use instead. @@ -3580,13 +3503,13 @@ both pieces of information contribute to its calculation. Likewise, the length of a string or array being unpacked may be longer than the data's total length as described by the specification. -@defun bindat-length spec struct +@defun bindat-length type struct This function returns the total length of the data in @var{struct}, -according to @var{spec}. +according to @var{type}. @end defun -@defun bindat-pack spec struct &optional raw idx -This function returns a byte array packed according to @var{spec} from +@defun bindat-pack type struct &optional raw idx +This function returns a byte array packed according to @var{type} from the data in the alist @var{struct}. It normally creates and fills a new byte array starting at the beginning. However, if @var{raw} is non-@code{nil}, it specifies a pre-allocated unibyte string or vector to @@ -3607,3 +3530,70 @@ dotted notation. @result{} "127.0.0.1" @end example @end defun + +@node Bindat Computed Types +@subsection Advanced data layout specifications + +Bindat type expressions are not limited to the types described +earlier. They can also be arbitrary Lisp forms returning Bindat +type expressions. For example, the type below describes data which +can either contain a 24bit error code or a vector of bytes: + +@example +(bindat-type + (len u8) + (payload . (if (zerop len) (uint 24) (vec (1- len))))) +@end example + +Furthermore, while composite types are normally unpacked to (and +packed from) association lists, this can be changed via the use of +the following special keyword arguments: + +@table @code +@item :unpack-val @var{exp} +When the list of fields end with this keyword argument, then the value +returned when unpacking is the value of @var{exp} instead of the +standard alist. @var{exp} can refer to all the previous fields by +their name. + +@item :pack-val @var{exp} +If a field's type is followed by this keyword argument, then the value +packed into this field is returned by @var{exp} instead of being +extracted from the alist. + +@item :pack-var @var{name} +If the list of fields is preceded by this keyword argument, then all +the subsequent @code{:pack-val} arguments can refer to the overall +value to pack into this composite type via the variable named +@var{name}. +@end table + +For example, one could describe a 16 bit signed integer as follows: + +@example +(defconst sint16-bindat-spec + (let* ((max (ash 1 15)) + (wrap (+ max max))) + (bindat-type :pack-var v + (n uint 16 :pack-val (if (< v 0) (+ v wrap) v)) + :unpack-val (if (>= n max) (- n wrap) n)))) +@end example + +Which would then behave as follows: +@example +(bindat-pack sint16-bindat-spec -8) + @result{} "\377\370" + +(bindat-unpack sint16-bindat-spec "\300\100") + @result{} -16320 +@end example + +Finally, you can define new Bindat type forms to use in Bindat type +expressions with @code{bindat-defmacro}: + +@defmac bindat-defmacro name args &rest body +Define a new Bindat type expression named @var{name} and taking +arguments @var{args}. Its behavior follows that of @code{defmacro}, +which the important difference that the new forms can only be used +within Bindat type expressions. +@end defmac diff --git a/etc/NEWS b/etc/NEWS index 3522fce03a..15df9cdcda 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -396,9 +396,11 @@ in text mode. The cursor still only actually blinks in GUI frames. ** Bindat +++ -*** New types 'u64' and 'u64r' -+++ -*** New macro 'bindat-spec' to define specs, with Edebug support +*** New 'Bindat type expression' description language. +This new system is provided by the new macro 'bindat-type' and +obsoletes the old data layout specifications. It supports +arbitrary-size integers, recursive types, and more. + ** pcase +++ diff --git a/lisp/emacs-lisp/bindat.el b/lisp/emacs-lisp/bindat.el index 830e61f851..adf2d67284 100644 --- a/lisp/emacs-lisp/bindat.el +++ b/lisp/emacs-lisp/bindat.el @@ -62,39 +62,40 @@ ;; struct data item[/* items */]; ;; }; ;; -;; The corresponding Lisp bindat specification looks like this: +;; The corresponding Lisp bindat specification could look like this: +;; +;; (bindat-defmacro ip () '(vec 4 byte)) ;; ;; (setq header-bindat-spec -;; (bindat-spec +;; (bindat-type ;; (dest-ip ip) ;; (src-ip ip) -;; (dest-port u16) -;; (src-port u16))) +;; (dest-port uint 16) +;; (src-port uint 16))) ;; ;; (setq data-bindat-spec -;; (bindat-spec +;; (bindat-type ;; (type u8) ;; (opcode u8) -;; (length u32r) ;; little endian order +;; (length uintr 32) ;; little endian order ;; (id strz 8) -;; (data vec (length)) -;; (align 4))) +;; (data vec length) +;; (_ align 4))) ;; ;; (setq packet-bindat-spec -;; (bindat-spec -;; (header struct header-bindat-spec) -;; (items u8) -;; (fill 3) -;; (item repeat (items) -;; (struct data-bindat-spec)))) -;; +;; (bindat-type +;; (header type header-bindat-spec) +;; (nitems u8) +;; (_ fill 3) +;; (items repeat nitems type data-bindat-spec))) ;; ;; A binary data representation may look like ;; [ 192 168 1 100 192 168 1 101 01 28 21 32 2 0 0 0 ;; 2 3 5 0 ?A ?B ?C ?D ?E ?F 0 0 1 2 3 4 5 0 0 0 ;; 1 4 7 0 ?B ?C ?D ?E ?F ?G 0 0 6 7 8 9 10 11 12 0 ] ;; -;; The corresponding decoded structure looks like +;; The corresponding decoded structure returned by `bindat-unpack' (or taken +;; by `bindat-pack') looks like: ;; ;; ((header ;; (dest-ip . [192 168 1 100]) @@ -114,90 +115,24 @@ ;; (type . 1)))) ;; ;; To access a specific value in this structure, use the function -;; bindat-get-field with the structure as first arg followed by a list +;; `bindat-get-field' with the structure as first arg followed by a list ;; of field names and array indexes, e.g. using the data above, ;; (bindat-get-field decoded-structure 'item 1 'id) ;; returns "BCDEFG". -;; Binary Data Structure Specification Format -;; ------------------------------------------ - -;; We recommend using names that end in `-bindat-spec'; such names -;; are recognized automatically as "risky" variables. - -;; The data specification is formatted as follows: - -;; SPEC ::= ( ITEM... ) - -;; ITEM ::= ( FIELD TYPE ) -;; | ( [FIELD] eval FORM ) -- eval FORM for side-effect only -;; | ( [FIELD] fill LEN ) -- skip LEN bytes -;; | ( [FIELD] align LEN ) -- skip to next multiple of LEN bytes -;; | ( [FIELD] struct SPEC_NAME ) -;; | ( [FIELD] union TAG_VAL (TAG SPEC)... [(t SPEC)] ) -;; | ( FIELD repeat ARG ITEM... ) - -;; -- In (eval EXPR), the value of the last field is available in -;; the dynamically bound variable `last' and all the previous -;; ones in the variable `struct'. - -;; TYPE ::= ( eval EXPR ) -- interpret result as TYPE -;; | u8 | byte -- length 1 -;; | u16 | word | short -- length 2, network byte order -;; | u24 -- 3-byte value -;; | u32 | dword | long -- length 4, network byte order -;; | u64 -- length 8, network byte order -;; | u16r | u24r | u32r | u64r - little endian byte order. -;; | str LEN -- LEN byte string -;; | strz LEN -- LEN byte (zero-terminated) string -;; | vec LEN [TYPE] -- vector of LEN items of TYPE (default: u8) -;; | ip -- 4 byte vector -;; | bits LEN -- bit vector using LEN bytes. -;; -;; -- Example: `bits 2' will unpack 0x28 0x1c to (2 3 4 11 13) -;; and 0x1c 0x28 to (3 5 10 11 12). - -;; FIELD ::= ( eval EXPR ) -- use result as NAME -;; | NAME - -;; LEN ::= ARG -;; | | nil -- LEN = 1 - - -;; TAG_VAL ::= ARG - -;; TAG ::= LISP_CONSTANT -;; | ( eval EXPR ) -- return non-nil if tag match; -;; current TAG_VAL in `tag'. - -;; ARG ::= ( eval EXPR ) -- interpret result as ARG -;; | INTEGER_CONSTANT -;; | DEREF - -;; DEREF ::= ( [NAME | INTEGER]... ) -- Field NAME or Array index relative -;; to current structure spec. -;; -- see bindat-get-field - -;; A `union' specification -;; ([FIELD] union TAG_VAL (TAG SPEC) ... [(t SPEC)]) -;; is interpreted by evalling TAG_VAL and then comparing that to -;; each TAG using equal; if a match is found, the corresponding SPEC -;; is used. -;; If TAG is a form (eval EXPR), EXPR is eval'ed with `tag' bound to the -;; value of TAG_VAL; the corresponding SPEC is used if the result is non-nil. -;; Finally, if TAG is t, the corresponding SPEC is used unconditionally. -;; -;; An `eval' specification -;; ([FIELD] eval FORM) -;; is interpreted by evalling FORM for its side effects only. -;; If FIELD is specified, the value is bound to that field. -;; The FORM may access and update `bindat-raw' and `bindat-idx' (see `bindat-unpack'). - ;;; Code: ;; Helper functions for structure unpacking. ;; Relies on dynamic binding of `bindat-raw' and `bindat-idx'. +(eval-when-compile (require 'cl-lib)) +(eval-when-compile (require 'subr-x)) ;For `named-let'. + +(cl-defstruct (bindat--type + (:predicate nil) + (:constructor bindat--make)) + le ue pe) + (defvar bindat-raw) (defvar bindat-idx) @@ -215,9 +150,6 @@ (defun bindat--unpack-u32 () (logior (ash (bindat--unpack-u16) 16) (bindat--unpack-u16))) -(defun bindat--unpack-u64 () - (logior (ash (bindat--unpack-u32) 32) (bindat--unpack-u32))) - (defun bindat--unpack-u16r () (logior (bindat--unpack-u8) (ash (bindat--unpack-u8) 8))) @@ -227,9 +159,6 @@ (defun bindat--unpack-u32r () (logior (bindat--unpack-u16r) (ash (bindat--unpack-u16r) 16))) -(defun bindat--unpack-u64r () - (logior (bindat--unpack-u32r) (ash (bindat--unpack-u32r) 32))) - (defun bindat--unpack-str (len) (let ((s (substring bindat-raw bindat-idx (+ bindat-idx len)))) (setq bindat-idx (+ bindat-idx len)) @@ -266,11 +195,9 @@ ((or 'u16 'word 'short) (bindat--unpack-u16)) ('u24 (bindat--unpack-u24)) ((or 'u32 'dword 'long) (bindat--unpack-u32)) - ('u64 (bindat--unpack-u64)) ('u16r (bindat--unpack-u16r)) ('u24r (bindat--unpack-u24r)) ('u32r (bindat--unpack-u32r)) - ('u64r (bindat--unpack-u64r)) ('bits (bindat--unpack-bits len)) ('str (bindat--unpack-str len)) ('strz (bindat--unpack-strz len)) @@ -290,6 +217,11 @@ (* len (/ (+ n (1- len)) len))) ;Isn't there a simpler way? (defun bindat--unpack-group (spec) + ;; FIXME: Introduce a new primitive so we can mark `bindat-unpack' + ;; as obsolete (maybe that primitive should be a macro which takes + ;; a bindat type *expression* as argument). + (if (cl-typep spec 'bindat--type) + (funcall (bindat--type-ue spec)) (with-suppressed-warnings ((lexical struct last)) (defvar struct) (defvar last)) (let (struct last) @@ -350,7 +282,7 @@ (setq struct (if field (cons (cons field data) struct) (append data struct)))))) - struct)) + struct))) (defun bindat-unpack (spec raw &optional idx) "Return structured data according to SPEC for binary data in RAW. @@ -383,10 +315,11 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (u16 . 2) (u16r . 2) (word . 2) (short . 2) (u24 . 3) (u24r . 3) (u32 . 4) (u32r . 4) (dword . 4) (long . 4) - (u64 . 8) (u64r . 8) (ip . 4))) (defun bindat--length-group (struct spec) + (if (cl-typep spec 'bindat--type) + (funcall (bindat--type-le spec) struct) (with-suppressed-warnings ((lexical struct last)) (defvar struct) (defvar last)) (let ((struct struct) last) @@ -452,7 +385,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (setq len (* len (cdr type)))) (if field (setq last (bindat-get-field struct field))) - (setq bindat-idx (+ bindat-idx len)))))))) + (setq bindat-idx (+ bindat-idx len))))))))) (defun bindat-length (spec struct) "Calculate `bindat-raw' length for STRUCT according to bindat SPEC." @@ -529,11 +462,9 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." ((or 'u16 'word 'short) (bindat--pack-u16 v)) ('u24 (bindat--pack-u24 v)) ((or 'u32 'dword 'long) (bindat--pack-u32 v)) - ('u64 (bindat--pack-u64 v)) ('u16r (bindat--pack-u16r v)) ('u24r (bindat--pack-u24r v)) ('u32r (bindat--pack-u32r v)) - ('u64r (bindat--pack-u64r v)) ('bits (bindat--pack-bits len v)) ((or 'str 'strz) (bindat--pack-str len v)) ('vec @@ -550,6 +481,8 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (setq bindat-idx (+ bindat-idx len))))) (defun bindat--pack-group (struct spec) + (if (cl-typep spec 'bindat--type) + (funcall (bindat--type-pe spec) struct) (with-suppressed-warnings ((lexical struct last)) (defvar struct) (defvar last)) (let ((struct struct) last) @@ -607,7 +540,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (_ (setq last (bindat-get-field struct field)) (bindat--pack-item last type len vectype) - )))))) + ))))))) (defun bindat-pack (spec struct &optional raw idx) "Return binary data packed according to SPEC for structured data STRUCT. @@ -623,52 +556,6 @@ Optional fourth arg IDX is the starting offset into RAW." (bindat--pack-group struct spec) (if raw nil bindat-raw))) -;;;; Debugging support - -(def-edebug-elem-spec 'bindat-spec '(&rest bindat-item)) - - -(def-edebug-elem-spec 'bindat--item-aux - ;; Field types which can come without a field label. - '(&or ["eval" form] - ["fill" bindat-len] - ["align" bindat-len] - ["struct" form] ;A reference to another bindat-spec. - ["union" bindat-tag-val &rest (bindat-tag bindat-spec)])) - -(def-edebug-elem-spec 'bindat-item - '((&or bindat--item-aux ;Without label.. - [bindat-field ;..or with label - &or bindat--item-aux - ["repeat" bindat-arg bindat-spec] - bindat-type]))) - -(def-edebug-elem-spec 'bindat-type - '(&or ("eval" form) - ["str" bindat-len] - ["strz" bindat-len] - ["vec" bindat-len &optional bindat-type] - ["bits" bindat-len] - symbolp)) - -(def-edebug-elem-spec 'bindat-field - '(&or ("eval" form) symbolp)) - -(def-edebug-elem-spec 'bindat-len '(&or [] "nil" bindat-arg)) - -(def-edebug-elem-spec 'bindat-tag-val '(bindat-arg)) - -(def-edebug-elem-spec 'bindat-tag '(&or ("eval" form) atom)) - -(def-edebug-elem-spec 'bindat-arg - '(&or ("eval" form) integerp (&rest symbolp integerp))) - -(defmacro bindat-spec (&rest fields) - "Build the bindat spec described by FIELDS." - (declare (indent 0) (debug (bindat-spec))) - ;; FIXME: We should really "compile" this to a triplet of functions! - `',fields) - ;;;; Misc. format conversions (defun bindat-format-vector (vect fmt sep &optional len) @@ -697,6 +584,384 @@ The port (if any) is omitted. IP can be a string, as well." (format "%d.%d.%d.%d" (aref ip 0) (aref ip 1) (aref ip 2) (aref ip 3)))) +;;;; New approach based on macro-expansion + +;; Further improvements suggested by reading websocket.el: +;; - Support for bit-sized fields? +;; +;; - Add some way to verify redundant/checksum fields's contents without +;; having to provide a complete `:unpack-val' expression. +;; The `:pack-val' thingy can work nicely to compute checksum fields +;; based on previous fields's contents (without impacting or being impacted +;; by the unpacked representation), but if we want to verify +;; those checksums when unpacking, we have to use the :unpack-val +;; and build the whole object by hand instead of being able to focus +;; just on the checksum field. +;; Maybe this could be related to `unit' type fields where we might like +;; to make sure that the "value" we write into it is the same as the +;; value it holds (tho those checks don't happen at the same time (pack +;; vs unpack). +;; +;; - Support for packing/unpacking to/from something else than +;; a unibyte string, e.g. from a buffer. Problems to do that are: +;; - the `str' and `strz' types which use `substring' rather than reading +;; one byte at a time. +;; - the `align' and `fill' which just want to skip without reading/writing +;; - the `pack-uint' case, which would prefer writing the LSB first. +;; - the `align' case needs to now the current position in order to know +;; how far to advance +;; +;; - Don't write triple code when the type is only ever used at a single place +;; (e.g. to unpack). + +(defun bindat--unpack-uint (bitlen) + (let ((v 0) (bitsdone 0)) + (while (< bitsdone bitlen) + (setq v (logior (ash v 8) (bindat--unpack-u8))) + (setq bitsdone (+ bitsdone 8))) + v)) + +(defun bindat--unpack-uintr (bitlen) + (let ((v 0) (bitsdone 0)) + (while (< bitsdone bitlen) + (setq v (logior v (ash (bindat--unpack-u8) bitsdone))) + (setq bitsdone (+ bitsdone 8))) + v)) + +(defun bindat--pack-uint (bitlen v) + (let* ((len (/ bitlen 8)) + (shift (- (* 8 (1- len))))) + (dotimes (_ len) + (bindat--pack-u8 (logand 255 (ash v shift))) + (setq shift (+ 8 shift))))) + +(defun bindat--pack-uintr (bitlen v) + (let* ((len (/ bitlen 8))) + (dotimes (_ len) + (bindat--pack-u8 (logand v 255)) + (setq v (ash v -8))))) + +(defmacro bindat--pcase (&rest args) + "Like `pcase' but optimize the code under the assumption that it's exhaustive." + (declare (indent 1) (debug pcase)) + `(pcase ,@args (pcase--dontcare nil))) + +(cl-defgeneric bindat--type (op head &rest args) + "Return the code for the operation OP of the Bindat type (HEAD . ARGS). +OP can be one of: unpack', (pack VAL), or (length VAL) where VAL +is the name of a variable that will hold the value we need to pack.") + +(cl-defmethod bindat--type (op (_ (eql byte))) + (bindat--pcase op + ('unpack `(bindat--unpack-u8)) + (`(length . ,_) `(cl-incf bindat-idx 1)) + (`(pack . ,args) `(bindat--pack-u8 . ,args)))) + +(cl-defmethod bindat--type (op (_ (eql uint)) n) + (if (eq n 8) (bindat--type op 'byte) + (bindat--pcase op + ('unpack `(bindat--unpack-uint ,n)) + (`(length . ,_) `(cl-incf bindat-idx (/ ,n 8))) + (`(pack . ,args) `(bindat--pack-uint ,n . ,args))))) + +(cl-defmethod bindat--type (op (_ (eql uintr)) n) + (if (eq n 8) (bindat--type op 'byte) + (bindat--pcase op + ('unpack `(bindat--unpack-uintr ,n)) + (`(length . ,_) `(cl-incf bindat-idx (/ ,n 8))) + (`(pack . ,args) `(bindat--pack-uintr ,n . ,args))))) + +(cl-defmethod bindat--type (op (_ (eql str)) len) + (bindat--pcase op + ('unpack `(bindat--unpack-str ,len)) + (`(length . ,_) `(cl-incf bindat-idx ,len)) + (`(pack . ,args) `(bindat--pack-str ,len . ,args)))) + +(cl-defmethod bindat--type (op (_ (eql strz)) len) + (bindat--pcase op + ('unpack `(bindat--unpack-strz ,len)) + (`(length . ,_) `(cl-incf bindat-idx ,len)) + ;; Here we don't add the terminating zero because we rely + ;; on the fact that `bindat-raw' was presumably initialized with + ;; all-zeroes before we started. + (`(pack . ,args) `(bindat--pack-str ,len . ,args)))) + +(cl-defmethod bindat--type (op (_ (eql bits)) len) + (bindat--pcase op + ('unpack `(bindat--unpack-bits ,len)) + (`(length . ,_) `(cl-incf bindat-idx ,len)) + (`(pack . ,args) `(bindat--pack-bits ,len . ,args)))) + +(cl-defmethod bindat--type (_op (_ (eql fill)) len) + `(progn (cl-incf bindat-idx ,len) nil)) + +(cl-defmethod bindat--type (_op (_ (eql align)) len) + `(progn (cl-callf bindat--align bindat-idx ,len) nil)) + +(cl-defmethod bindat--type (op (_ (eql type)) exp) + (bindat--pcase op + ('unpack `(funcall (bindat--type-ue ,exp))) + (`(length . ,args) `(funcall (bindat--type-le ,exp) . ,args)) + (`(pack . ,args) `(funcall (bindat--type-pe ,exp) . ,args)))) + +(cl-defmethod bindat--type (op (_ (eql vec)) count &rest type) + (unless type (setq type '(byte))) + (let ((fun (macroexpand-all (bindat--fun type) macroexpand-all-environment))) + (bindat--pcase op + ('unpack + `(let* ((bindat--len ,count) + (bindat--v (make-vector bindat--len 0))) + (dotimes (bindat--i bindat--len) + (aset bindat--v bindat--i (funcall ,fun))) + bindat--v)) + ((and `(length . ,_) + ;; FIXME: Improve the pattern match to recognize more complex + ;; "constant" functions? + (let `#'(lambda (,val) (setq bindat-idx (+ bindat-idx ,len))) fun) + (guard (not (macroexp--fgrep `((,val)) len)))) + ;; Optimize the case where the size of each element is constant. + `(cl-incf bindat-idx (* ,count ,len))) + ;; FIXME: It's tempting to use `(mapc (lambda (,val) ,exp) ,val)' + ;; which would be more efficient when `val' is a list, + ;; but that's only right if length of `val' is indeed `count'. + (`(,_ ,val) + `(dotimes (bindat--i ,count) + (funcall ,fun (elt ,val bindat--i))))))) + +(cl-defmethod bindat--type (op (_ (eql unit)) val) + (pcase op ('unpack val) (_ nil))) + +(cl-defmethod bindat--type (op (_ (eql struct)) &rest args) + (apply #'bindat--type op args)) + +(cl-defmethod bindat--type (op (_ (eql :pack-var)) var &rest fields) + (unless (consp (cdr fields)) + (error "`:pack-var VAR' needs to be followed by fields")) + (bindat--pcase op + ((or 'unpack (guard (null var))) + (apply #'bindat--type op fields)) + (`(,_ ,val) + `(let ((,var ,val)) ,(apply #'bindat--type op fields))))) + +(cl-defmethod bindat--type (op (field cons) &rest fields) + (named-let loop + ((fields (cons field fields)) + (labels ())) + (bindat--pcase fields + ('nil + (bindat--pcase op + ('unpack + (let ((exp ())) + (pcase-dolist (`(,label . ,labelvar) labels) + (setq exp + (if (eq label '_) + (if exp `(nconc ,labelvar ,exp) labelvar) + `(cons (cons ',label ,labelvar) ,exp)))) + exp)) + (_ nil))) + (`(:unpack-val ,exp) + ;; Make it so `:kwd nil' is the same as the absence of the keyword arg. + (if exp (pcase op ('unpack exp)) (loop nil labels))) + + (`((,label . ,type) . ,fields) + (let* ((get-field-val + (let ((tail (memq :pack-val type))) + ;; FIXME: This `TYPE.. :pack EXP' syntax doesn't work well + ;; when TYPE is a struct (a list of fields) or with extensions + ;; such as allowing TYPE to be `if ...'. + (if tail + (prog1 (cadr tail) + (setq type (butlast type (length tail))))))) + (fieldvar (make-symbol (format "field%d" (length fields)))) + (labelvar + (cond + ((eq label '_) fieldvar) + ((keywordp label) + (intern (substring (symbol-name label) 1))) + (t label))) + (field-fun (bindat--fun type)) + (rest-exp (loop fields `((,label . ,labelvar) . ,labels)))) + (bindat--pcase op + ('unpack + (let ((code + `(let ((,labelvar (funcall ,field-fun))) + ,rest-exp))) + (if (or (eq label '_) (not (assq label labels))) + code + (macroexp-warn-and-return + (format "Duplicate label: %S" label) + code)))) + (`(,_ ,val) + ;; `cdr-safe' is easier to optimize (can't signal an error). + `(let ((,fieldvar ,(or get-field-val + (if (eq label '_) val + `(cdr-safe (assq ',label ,val)))))) + (funcall ,field-fun ,fieldvar) + ,@(when rest-exp + `((let ,(unless (eq labelvar fieldvar) + `((,labelvar ,fieldvar))) + (ignore ,labelvar) + ,rest-exp)))))))) + (_ (error "Unrecognized format in bindat fields: %S" fields))))) + +(def-edebug-elem-spec 'bindat-struct + [[&rest (symbolp bindat-type &optional ":pack-val" def-form)] + &optional ":unpack-val" def-form]) + +(def-edebug-elem-spec 'bindat-type + '(&or ["uint" def-form] + ["uintr" def-form] + ["str" def-form] + ["strz" def-form] + ["bits" def-form] + ["fill" def-form] + ["align" def-form] + ["vec" def-form bindat-type] + ["repeat" def-form bindat-type] + ["type" def-form] + ["struct" bindat-struct] + ["unit" def-form] + [":pack-var" symbolp bindat-type] + symbolp ;; u8, u16, etc... + bindat-struct)) + +(defmacro bindat-type (&rest type) + "Return the Bindat type value to pack&unpack TYPE. +TYPE is a Bindat type expression. It can take the following forms: + + uint BITLEN - Big-endian unsigned integer + uintr BITLEN - Little-endian unsigned integer + str LEN - Byte string + strz LEN - Zero-terminated byte-string + bits LEN - Bit vector (LEN is counted in bytes) + fill LEN - Just a filler + align LEN - Fill up to the next multiple of LEN bytes + vec COUNT TYPE - COUNT repetitions of TYPE + type EXP - Indirection; EXP should return a Bindat type value + unit EXP - 0-width type holding the value returned by EXP + struct FIELDS... - A composite type + +When the context makes it clear, the symbol `struct' can be omitted. +A composite type is a list of FIELDS where each FIELD is of the form + + (LABEL TYPE) + +where LABEL can be `_' if the field should not deserve a name. + +Composite types get normally packed/unpacked to/from alists, but this can be +controlled in the following way: +- If the list of fields ends with `:unpack-val EXP', then unpacking will + return the value of EXP (which has the previous fields in its scope). +- If a field's TYPE is followed by `:pack-val EXP', then the value placed + into this field will be that returned by EXP instead of looking up the alist. +- If the list of fields is preceded with `:pack-var VAR' then the object to + be packed is bound to VAR when evaluating the EXPs of `:pack-val'. + +All the above BITLEN, LEN, COUNT, and EXP are ELisp expressions evaluated +in the current lexical context extended with the previous fields. + +TYPE can additionally be one of the Bindat type macros defined with +`bindat-defmacro' (and listed below) or an ELisp expression which returns +a bindat type expression." + (declare (indent 0) (debug (bindat-type))) + `(progn + (defvar bindat-idx) + (bindat--make :ue ,(bindat--toplevel 'unpack type) + :le ,(bindat--toplevel 'length type) + :pe ,(bindat--toplevel 'pack type)))) + +(eval-and-compile + (defconst bindat--primitives '(byte uint uintr str strz bits fill align + struct type vec unit))) + +(eval-and-compile + (defvar bindat--macroenv + (mapcar (lambda (s) (cons s (lambda (&rest args) + (bindat--makefun (cons s args))))) + bindat--primitives))) + +(defmacro bindat-defmacro (name args &rest body) + "Define a new Bindat type as a macro." + (declare (indent 2) (doc-string 3) (debug (&define name sexp def-body))) + (let ((leaders ())) + (while (and (cdr body) + (or (stringp (car body)) + (memq (car-safe (car body)) '(:documentation declare)))) + (push (pop body) leaders)) + ;; FIXME: Add support for Edebug decls to those macros. + `(eval-and-compile ;; Yuck! But needed to define types where you use them! + (setf (alist-get ',name bindat--macroenv) + (lambda ,args ,@(nreverse leaders) + (bindat--fun ,(macroexp-progn body))))))) + +(put 'bindat-type 'function-documentation '(bindat--make-docstring)) +(defun bindat--make-docstring () + ;; Largely inspired from `pcase--make-docstring'. + (let* ((main (documentation (symbol-function 'bindat-type) 'raw)) + (ud (help-split-fundoc main 'bindat-type))) + (require 'help-fns) + (declare-function help-fns--signature "help-fns") + (with-temp-buffer + (insert (or (cdr ud) main)) + (pcase-dolist (`(,name . ,me) (reverse bindat--macroenv)) + (unless (memq name bindat--primitives) + (let ((doc (documentation me 'raw))) + (insert "\n\n-- ") + (setq doc (help-fns--signature name doc me + (indirect-function me) + nil)) + (insert "\n" (or doc "Not documented."))))) + (let ((combined-doc (buffer-string))) + (if ud (help-add-fundoc-usage combined-doc (car ud)) combined-doc))))) + +(bindat-defmacro u8 () "Unsigned 8bit integer." '(byte)) +(bindat-defmacro sint (bitlen r) + "Signed integer of size BITLEN. +Bigendian if R is nil and little endian if not." + (let ((bl (make-symbol "bitlen")) + (max (make-symbol "max")) + (wrap (make-symbol "wrap"))) + `(let* ((,bl ,bitlen) + (,max (ash 1 (1- ,bl))) + (,wrap (+ ,max ,max))) + (struct :pack-var v + (n if ,r (uintr ,bl) (uint ,bl) + :pack-val (if (< v 0) (+ v ,wrap) v)) + :unpack-val (if (>= n ,max) (- n ,wrap) n))))) + +(bindat-defmacro repeat (count &rest type) + "Like `vec', but unpacks to a list rather than a vector." + `(:pack-var v + (v vec ,count ,@type :pack-val v) + :unpack-val (append v nil))) + +(defvar bindat--op nil + "The operation we're currently building. +This is a simple symbol and can be one of: `unpack', `pack', or `length'. +This is used during macroexpansion of `bindat-type' so that the +macros know which code to generate. +FIXME: this is closely related and very similar to the `op' argument passed +to `bindat--type', yet it's annoyingly different.") + +(defun bindat--fun (type) + (if (or (keywordp (car type)) (consp (car type))) (cons 'struct type) + type)) + +(defun bindat--makefun (type) + (let* ((v (make-symbol "v")) + (args (pcase bindat--op ('unpack ()) (_ (list v))))) + (pcase (apply #'bindat--type + (pcase bindat--op ('unpack 'unpack) (op `(,op . ,args))) + type) + (`(funcall ,f . ,(pred (equal args))) f) ;η-reduce. + (exp `(lambda ,args ,exp))))) + +(defun bindat--toplevel (op type) + (let* ((bindat--op op) + (env `(,@bindat--macroenv + ,@macroexpand-all-environment))) + (macroexpand-all (bindat--fun type) env))) + (provide 'bindat) ;;; bindat.el ends here diff --git a/test/lisp/emacs-lisp/bindat-tests.el b/test/lisp/emacs-lisp/bindat-tests.el index 9c417c855c..911a5f0c7b 100644 --- a/test/lisp/emacs-lisp/bindat-tests.el +++ b/test/lisp/emacs-lisp/bindat-tests.el @@ -23,29 +23,32 @@ (require 'bindat) (require 'cl-lib) +(bindat-defmacro ip () "An IPv4 address" '(vec 4 byte)) + (defconst header-bindat-spec - (bindat-spec + (bindat-type (dest-ip ip) (src-ip ip) - (dest-port u16) - (src-port u16))) + (dest-port uint 16) + (src-port uint 16))) (defconst data-bindat-spec - (bindat-spec + (bindat-type (type u8) (opcode u8) - (length u16r) ;; little endian order + (length uintr 16) ;; little endian order (id strz 8) - (data vec (length)) - (align 4))) + (data vec length) + (_ align 4))) + (defconst packet-bindat-spec - (bindat-spec - (header struct header-bindat-spec) + (bindat-type + (header type header-bindat-spec) (items u8) - (fill 3) - (item repeat (items) - (struct data-bindat-spec)))) + (_ fill 3) + (item repeat items + (_ type data-bindat-spec)))) (defconst struct-bindat '((header @@ -77,27 +80,7 @@ (should (equal (bindat-unpack packet-bindat-spec (bindat-pack packet-bindat-spec struct-bindat)) - '((item - ((data . - [1 2 3 4 5]) - (id . "ABCDEF") - (length . 5) - (opcode . 3) - (type . 2)) - ((data . - [6 7 8 9 10 11 12]) - (id . "BCDEFG") - (length . 7) - (opcode . 4) - (type . 1))) - (items . 2) - (header - (src-port . 5408) - (dest-port . 284) - (src-ip . - [192 168 1 101]) - (dest-ip . - [192 168 1 100])))))) + struct-bindat))) (ert-deftest bindat-test-pack/multibyte-string-fails () (should-error (bindat-pack nil nil "ö"))) @@ -121,4 +104,62 @@ (should (equal (bindat-ip-to-string [192 168 0 1]) "192.168.0.1")) (should (equal (bindat-ip-to-string "\300\250\0\1") "192.168.0.1"))) +(defconst bindat-test--int-websocket-type + (bindat-type + :pack-var value + (n1 u8 + :pack-val (if (< value 126) value (if (< value 65536) 126 127))) + (n2 uint (pcase n1 (127 64) (126 16) (_ 0)) + :pack-val value) + :unpack-val (if (< n1 126) n1 n2))) + +(ert-deftest bindat-test--pack-val () + ;; This is intended to test the :(un)pack-val feature that offers + ;; control over the unpacked representation of the data. + (dolist (n '(0 42 125 126 127 128 150 255 5000 65535 65536 8769786876)) + (should + (equal (bindat-unpack bindat-test--int-websocket-type + (bindat-pack bindat-test--int-websocket-type n)) + n)))) + +(ert-deftest bindat-test--sint () + (dotimes (kind 32) + (let ((bitlen (* 8 (/ kind 2))) + (r (zerop (% kind 2)))) + (dotimes (_ 100) + (let* ((n (random (ash 1 bitlen))) + (i (- n (ash 1 (1- bitlen))))) + (should (equal (bindat-unpack + (bindat-type sint bitlen r) + (bindat-pack (bindat-type sint bitlen r) i)) + i)) + (when (>= i 0) + (should (equal (bindat-pack + (bindat-type if r (uintr bitlen) (uint bitlen)) i) + (bindat-pack (bindat-type sint bitlen r) i))) + (should (equal (bindat-unpack + (bindat-type if r (uintr bitlen) (uint bitlen)) + (bindat-pack (bindat-type sint bitlen r) i)) + i)))))))) + +(defconst bindat-test--LEB128 + (bindat-type + letrec ((loop + (struct :pack-var n + (head u8 + :pack-val (+ (logand n 127) (if (> n 127) 128 0))) + (tail if (< head 128) (unit 0) loop + :pack-val (ash n -7)) + :unpack-val (+ (logand head 127) (ash tail 7))))) + loop)) + +(ert-deftest bindat-test--recursive () + (dotimes (n 10) + (let ((max (ash 1 (* n 10)))) + (dotimes (_ 10) + (let ((n (random max))) + (should (equal (bindat-unpack bindat-test--LEB128 + (bindat-pack bindat-test--LEB128 n)) + n))))))) + ;;; bindat-tests.el ends here commit 1362a9fec4dff341a84c881ac17dbf1ee2cf82fd Author: Mattias Engdegård Date: Fri Mar 5 20:21:01 2021 +0100 Make lambda-lifting work again * lisp/emacs-lisp/cconv.el (cconv--analyze-use): Fix typo. * test/lisp/emacs-lisp/cconv-tests.el (cconv-convert-lambda-lifted): Add test case. diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el index 50a8bebf4c..bd0a3e87e6 100644 --- a/lisp/emacs-lisp/cconv.el +++ b/lisp/emacs-lisp/cconv.el @@ -612,7 +612,7 @@ FORM is the parent form that binds this var." (push (cons (cons binder form) :captured+mutated) cconv-var-classification)) (`(,(and binder `(,_ (function (lambda . ,_)))) nil nil nil t) - (push (cons (cons binder form) :lambda-candidates) + (push (cons (cons binder form) :lambda-candidate) cconv-var-classification)))) (defun cconv--analyze-function (args body env parentform) diff --git a/test/lisp/emacs-lisp/cconv-tests.el b/test/lisp/emacs-lisp/cconv-tests.el index 517373386e..5aeed0cc15 100644 --- a/test/lisp/emacs-lisp/cconv-tests.el +++ b/test/lisp/emacs-lisp/cconv-tests.el @@ -182,7 +182,14 @@ (should (eq (cconv-tests-cl-defsubst) 'cl-defsubst-result))) (ert-deftest cconv-convert-lambda-lifted () - "Bug#30872." + ;; Verify that lambda-lifting is actually performed at all. + (should (equal (cconv-closure-convert + '#'(lambda (x) (let ((f #'(lambda () (+ x 1)))) + (funcall f)))) + '#'(lambda (x) (let ((f #'(lambda (x) (+ x 1)))) + (funcall f x))))) + + ;; Bug#30872. (should (equal (funcall (byte-compile commit 1ff46018f6bdb9641d1044043e6038dfffc897ae Author: Tassilo Horn Date: Fri Mar 5 20:53:18 2021 +0100 Improve rcirc-authenticated-hook docstring * lisp/net/rcirc.el (rcirc-authenticated-hook): Improve docstring. diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el index 58cc8b1be5..c80cd49c00 100644 --- a/lisp/net/rcirc.el +++ b/lisp/net/rcirc.el @@ -329,7 +329,8 @@ Called with 5 arguments, PROCESS, SENDER, RESPONSE, TARGET and TEXT." :type 'hook) (defvar rcirc-authenticated-hook nil - "Hook run after successfully authenticated.") + "Hook run after successfully authenticated. +Functions in this hook are called with a single argument PROCESS.") (defcustom rcirc-always-use-server-buffer-flag nil "Non-nil means messages without a channel target will go to the server buffer." commit 03ada27cb81dabb87eff38f2d66fe8fc4a02da46 Author: Stefan Monnier Date: Fri Mar 5 13:31:16 2021 -0500 * lisp/emacs-lisp/bindat.el: Minor refactoring (bindat--unpack-str, bindat--unpack-strz, bindat--unpack-bits): New functions, extracted from `bindat--unpack-item`. (bindat--unpack-item): Use them. (bindat--align): New function. (bindat--unpack-group, bindat--length-group, bindat--pack-group): Use it. (bindat-get-field): Allow integers to index both lists (as returned by `repeat`) and vectors (as returned by `vec`). (bindat--pack-str, bindat--pack-bits): New functions, extracted from `bindat--pack-item`. (bindat--pack-item): Use them. * test/lisp/emacs-lisp/bindat-tests.el (struct-bindat): Place the fields in the order in which they appear in the structs. diff --git a/lisp/emacs-lisp/bindat.el b/lisp/emacs-lisp/bindat.el index b1b2144e3d..830e61f851 100644 --- a/lisp/emacs-lisp/bindat.el +++ b/lisp/emacs-lisp/bindat.el @@ -201,7 +201,7 @@ (defvar bindat-raw) (defvar bindat-idx) -(defun bindat--unpack-u8 () +(defsubst bindat--unpack-u8 () (prog1 (aref bindat-raw bindat-idx) (setq bindat-idx (1+ bindat-idx)))) @@ -230,47 +230,50 @@ (defun bindat--unpack-u64r () (logior (bindat--unpack-u32r) (ash (bindat--unpack-u32r) 32))) +(defun bindat--unpack-str (len) + (let ((s (substring bindat-raw bindat-idx (+ bindat-idx len)))) + (setq bindat-idx (+ bindat-idx len)) + (if (stringp s) s + (apply #'unibyte-string s)))) + +(defun bindat--unpack-strz (len) + (let ((i 0) s) + (while (and (< i len) (/= (aref bindat-raw (+ bindat-idx i)) 0)) + (setq i (1+ i))) + (setq s (substring bindat-raw bindat-idx (+ bindat-idx i))) + (setq bindat-idx (+ bindat-idx len)) + (if (stringp s) s + (apply #'unibyte-string s)))) + +(defun bindat--unpack-bits (len) + (let ((bits nil) (bnum (1- (* 8 len))) j m) + (while (>= bnum 0) + (if (= (setq m (bindat--unpack-u8)) 0) + (setq bnum (- bnum 8)) + (setq j 128) + (while (> j 0) + (if (/= 0 (logand m j)) + (setq bits (cons bnum bits))) + (setq bnum (1- bnum) + j (ash j -1))))) + bits)) + (defun bindat--unpack-item (type len &optional vectype) (if (eq type 'ip) (setq type 'vec len 4)) (pcase type - ((or 'u8 'byte) - (bindat--unpack-u8)) - ((or 'u16 'word 'short) - (bindat--unpack-u16)) + ((or 'u8 'byte) (bindat--unpack-u8)) + ((or 'u16 'word 'short) (bindat--unpack-u16)) ('u24 (bindat--unpack-u24)) - ((or 'u32 'dword 'long) - (bindat--unpack-u32)) + ((or 'u32 'dword 'long) (bindat--unpack-u32)) ('u64 (bindat--unpack-u64)) ('u16r (bindat--unpack-u16r)) ('u24r (bindat--unpack-u24r)) ('u32r (bindat--unpack-u32r)) ('u64r (bindat--unpack-u64r)) - ('bits - (let ((bits nil) (bnum (1- (* 8 len))) j m) - (while (>= bnum 0) - (if (= (setq m (bindat--unpack-u8)) 0) - (setq bnum (- bnum 8)) - (setq j 128) - (while (> j 0) - (if (/= 0 (logand m j)) - (setq bits (cons bnum bits))) - (setq bnum (1- bnum) - j (ash j -1))))) - bits)) - ('str - (let ((s (substring bindat-raw bindat-idx (+ bindat-idx len)))) - (setq bindat-idx (+ bindat-idx len)) - (if (stringp s) s - (apply #'unibyte-string s)))) - ('strz - (let ((i 0) s) - (while (and (< i len) (/= (aref bindat-raw (+ bindat-idx i)) 0)) - (setq i (1+ i))) - (setq s (substring bindat-raw bindat-idx (+ bindat-idx i))) - (setq bindat-idx (+ bindat-idx len)) - (if (stringp s) s - (apply #'unibyte-string s)))) + ('bits (bindat--unpack-bits len)) + ('str (bindat--unpack-str len)) + ('strz (bindat--unpack-strz len)) ('vec (let ((v (make-vector len 0)) (vlen 1)) (if (consp vectype) @@ -283,6 +286,9 @@ v)) (_ nil))) +(defsubst bindat--align (n len) + (* len (/ (+ n (1- len)) len))) ;Isn't there a simpler way? + (defun bindat--unpack-group (spec) (with-suppressed-warnings ((lexical struct last)) (defvar struct) (defvar last)) @@ -317,8 +323,7 @@ ('fill (setq bindat-idx (+ bindat-idx len))) ('align - (while (/= (% bindat-idx len) 0) - (setq bindat-idx (1+ bindat-idx)))) + (setq bindat-idx (bindat--align bindat-idx len))) ('struct (setq data (bindat--unpack-group (eval len t)))) ('repeat @@ -366,9 +371,8 @@ An integer value in the field list is taken as an array index, e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (while (and struct field) (setq struct (if (integerp (car field)) - (nth (car field) struct) - (let ((val (assq (car field) struct))) - (if (consp val) (cdr val))))) + (elt struct (car field)) + (cdr (assq (car field) struct)))) (setq field (cdr field))) struct) @@ -421,8 +425,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." ('fill (setq bindat-idx (+ bindat-idx len))) ('align - (while (/= (% bindat-idx len) 0) - (setq bindat-idx (1+ bindat-idx)))) + (setq bindat-idx (bindat--align bindat-idx len))) ('struct (bindat--length-group (if field (bindat-get-field struct field) struct) (eval len t))) @@ -460,7 +463,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." ;;;; Pack structured data into bindat-raw -(defun bindat--pack-u8 (v) +(defsubst bindat--pack-u8 (v) (aset bindat-raw bindat-idx (logand v 255)) (setq bindat-idx (1+ bindat-idx))) @@ -498,42 +501,41 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (bindat--pack-u32r v) (bindat--pack-u32r (ash v -32))) +(defun bindat--pack-str (len v) + (dotimes (i (min len (length v))) + (aset bindat-raw (+ bindat-idx i) (aref v i))) + (setq bindat-idx (+ bindat-idx len))) + +(defun bindat--pack-bits (len v) + (let ((bnum (1- (* 8 len))) j m) + (while (>= bnum 0) + (setq m 0) + (if (null v) + (setq bnum (- bnum 8)) + (setq j 128) + (while (> j 0) + (if (memq bnum v) + (setq m (logior m j))) + (setq bnum (1- bnum) + j (ash j -1)))) + (bindat--pack-u8 m)))) + (defun bindat--pack-item (v type len &optional vectype) (if (eq type 'ip) (setq type 'vec len 4)) (pcase type - ((guard (null v)) - (setq bindat-idx (+ bindat-idx len))) - ((or 'u8 'byte) - (bindat--pack-u8 v)) - ((or 'u16 'word 'short) - (bindat--pack-u16 v)) - ('u24 - (bindat--pack-u24 v)) - ((or 'u32 'dword 'long) - (bindat--pack-u32 v)) + ((guard (null v)) (setq bindat-idx (+ bindat-idx len))) + ((or 'u8 'byte) (bindat--pack-u8 v)) + ((or 'u16 'word 'short) (bindat--pack-u16 v)) + ('u24 (bindat--pack-u24 v)) + ((or 'u32 'dword 'long) (bindat--pack-u32 v)) ('u64 (bindat--pack-u64 v)) ('u16r (bindat--pack-u16r v)) ('u24r (bindat--pack-u24r v)) ('u32r (bindat--pack-u32r v)) ('u64r (bindat--pack-u64r v)) - ('bits - (let ((bnum (1- (* 8 len))) j m) - (while (>= bnum 0) - (setq m 0) - (if (null v) - (setq bnum (- bnum 8)) - (setq j 128) - (while (> j 0) - (if (memq bnum v) - (setq m (logior m j))) - (setq bnum (1- bnum) - j (ash j -1)))) - (bindat--pack-u8 m)))) - ((or 'str 'strz) - (dotimes (i (min len (length v))) - (aset bindat-raw (+ bindat-idx i) (aref v i))) - (setq bindat-idx (+ bindat-idx len))) + ('bits (bindat--pack-bits len v)) + ((or 'str 'strz) (bindat--pack-str len v)) ('vec (let ((l (length v)) (vlen 1)) (if (consp vectype) @@ -580,8 +582,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." ('fill (setq bindat-idx (+ bindat-idx len))) ('align - (while (/= (% bindat-idx len) 0) - (setq bindat-idx (1+ bindat-idx)))) + (setq bindat-idx (bindat--align bindat-idx len))) ('struct (bindat--pack-group (if field (bindat-get-field struct field) struct) (eval len t))) diff --git a/test/lisp/emacs-lisp/bindat-tests.el b/test/lisp/emacs-lisp/bindat-tests.el index 72883fc2ec..9c417c855c 100644 --- a/test/lisp/emacs-lisp/bindat-tests.el +++ b/test/lisp/emacs-lisp/bindat-tests.el @@ -1,4 +1,4 @@ -;;; bindat-tests.el --- tests for bindat.el -*- lexical-binding: t; coding: utf-8; -*- +;;; bindat-tests.el --- tests for bindat.el -*- lexical-binding: t -*- ;; Copyright (C) 2019-2021 Free Software Foundation, Inc. @@ -23,14 +23,14 @@ (require 'bindat) (require 'cl-lib) -(defvar header-bindat-spec +(defconst header-bindat-spec (bindat-spec (dest-ip ip) (src-ip ip) (dest-port u16) (src-port u16))) -(defvar data-bindat-spec +(defconst data-bindat-spec (bindat-spec (type u8) (opcode u8) @@ -39,7 +39,7 @@ (data vec (length)) (align 4))) -(defvar packet-bindat-spec +(defconst packet-bindat-spec (bindat-spec (header struct header-bindat-spec) (items u8) @@ -47,23 +47,23 @@ (item repeat (items) (struct data-bindat-spec)))) -(defvar struct-bindat +(defconst struct-bindat '((header (dest-ip . [192 168 1 100]) (src-ip . [192 168 1 101]) (dest-port . 284) (src-port . 5408)) (items . 2) - (item ((data . [1 2 3 4 5]) - (id . "ABCDEF") - (length . 5) + (item ((type . 2) (opcode . 3) - (type . 2)) - ((data . [6 7 8 9 10 11 12]) - (id . "BCDEFG") - (length . 7) + (length . 5) + (id . "ABCDEF") + (data . [1 2 3 4 5])) + ((type . 1) (opcode . 4) - (type . 1))))) + (length . 7) + (id . "BCDEFG") + (data . [6 7 8 9 10 11 12]))))) (ert-deftest bindat-test-pack () (should (equal commit c881e990e3a083d7c8b990a2004a3ae82b886b9d Author: Stefan Monnier Date: Fri Mar 5 12:39:27 2021 -0500 * lisp/emacs-lisp/gv.el (edebug-after): Don't run the getter in the setter This fixes bug#46573 which was introduced by commit d79cf638f278e50c22feb53d6ba556f5ce9d7853. The new code is a middle ground, which makes sure the instrumentation point is used (so the coverage checker won't have ghost unreachable instrumentation points) yet without artificially running the getter when we only need to run the setter. diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el index 4d2bcbfaf5..c9eac70d8f 100644 --- a/lisp/emacs-lisp/gv.el +++ b/lisp/emacs-lisp/gv.el @@ -306,8 +306,7 @@ The return value is the last VAL in the list. (gv-letplace (getter setter) place (funcall do `(edebug-after ,before ,index ,getter) (lambda (store) - `(progn (edebug-after ,before ,index ,getter) - ,(funcall setter store))))))) + `(edebug-after ,before ,index ,(funcall setter store))))))) ;;; The common generalized variables. commit d582356a7f704f8a209a3ef31d6ea970520c6224 Author: Stefan Monnier Date: Fri Mar 5 12:09:50 2021 -0500 * src/fns.c (Frandom): Handle bignum `limit`s (ccall2, get_random_bignum): New functions. diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi index 63e3e0bace..4c5f72126e 100644 --- a/doc/lispref/numbers.texi +++ b/doc/lispref/numbers.texi @@ -1250,7 +1250,7 @@ other strings to choose various seed values. This function returns a pseudo-random integer. Repeated calls return a series of pseudo-random integers. -If @var{limit} is a positive fixnum, the value is chosen to be +If @var{limit} is a positive integer, the value is chosen to be nonnegative and less than @var{limit}. Otherwise, the value might be any fixnum, i.e., any integer from @code{most-negative-fixnum} through @code{most-positive-fixnum} (@pxref{Integer Basics}). diff --git a/src/fns.c b/src/fns.c index 7914bd4779..b193ad648a 100644 --- a/src/fns.c +++ b/src/fns.c @@ -54,10 +54,55 @@ DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, return argument; } +static Lisp_Object +ccall2 (Lisp_Object (f) (ptrdiff_t nargs, Lisp_Object *args), + Lisp_Object arg1, Lisp_Object arg2) +{ + Lisp_Object args[2] = {arg1, arg2}; + return f (2, args); +} + +static Lisp_Object +get_random_bignum (Lisp_Object limit) +{ + /* This is a naive transcription into bignums of the fixnum algorithm. + I'd be quite surprised if that's anywhere near the best algorithm + for it. */ + while (true) + { + Lisp_Object val = make_fixnum (0); + Lisp_Object lim = limit; + int bits = 0; + int bitsperiteration = FIXNUM_BITS - 1; + do + { + /* Shift by one so it is a valid positive fixnum. */ + EMACS_INT rand = get_random () >> 1; + Lisp_Object lrand = make_fixnum (rand); + bits += bitsperiteration; + val = ccall2 (Flogior, + Fash (val, make_fixnum (bitsperiteration)), + lrand); + lim = Fash (lim, make_fixnum (- bitsperiteration)); + } + while (!EQ (lim, make_fixnum (0))); + /* Return the remainder, except reject the rare case where + get_random returns a number so close to INTMASK that the + remainder isn't random. */ + Lisp_Object remainder = Frem (val, limit); + if (!NILP (ccall2 (Fleq, + ccall2 (Fminus, val, remainder), + ccall2 (Fminus, + Fash (make_fixnum (1), make_fixnum (bits)), + limit)))) + return remainder; + } +} + DEFUN ("random", Frandom, Srandom, 0, 1, 0, doc: /* Return a pseudo-random integer. By default, return a fixnum; all fixnums are equally likely. -With positive fixnum LIMIT, return random integer in interval [0,LIMIT). +With positive integer LIMIT, return random integer in interval [0,LIMIT). With argument t, set the random number seed from the system's entropy pool if available, otherwise from less-random volatile data such as the time. With a string argument, set the seed based on the string's contents. @@ -71,6 +116,12 @@ See Info node `(elisp)Random Numbers' for more details. */) init_random (); else if (STRINGP (limit)) seed_random (SSDATA (limit), SBYTES (limit)); + if (BIGNUMP (limit)) + { + if (0 > mpz_sgn (*xbignum_val (limit))) + xsignal2 (Qwrong_type_argument, Qnatnump, limit); + return get_random_bignum (limit); + } val = get_random (); if (FIXNUMP (limit) && 0 < XFIXNUM (limit)) commit cb87eeff1bf88d9d1849c452e8b9953b06ada454 Author: Michael Albinus Date: Fri Mar 5 17:51:22 2021 +0100 Declare some completion predicates * lisp/filenotify.el (file-notify-handle-event): * lisp/net/dbus.el (dbus-handle-event): Declare `completion-predicate'. diff --git a/lisp/filenotify.el b/lisp/filenotify.el index 78571776a3..07871bb0b6 100644 --- a/lisp/filenotify.el +++ b/lisp/filenotify.el @@ -100,6 +100,7 @@ If it is registered in `file-notify-descriptors', a `stopped' event is sent." "Handle a file system monitoring event, coming from backends. If OBJECT is a filewatch event, call its callback. Otherwise, signal a `file-notify-error'." + (declare (completion ignore)) (interactive "e") (when file-notify-debug (message "file-notify-handle-event %S" object)) diff --git a/lisp/net/dbus.el b/lisp/net/dbus.el index a9de35c814..1e7f836d82 100644 --- a/lisp/net/dbus.el +++ b/lisp/net/dbus.el @@ -1144,6 +1144,7 @@ compound type arguments (TYPE VALUE) will be kept as is." EVENT is a D-Bus event, see `dbus-check-event'. HANDLER, being part of the event, is called with arguments ARGS (without type information). If the HANDLER returns a `dbus-error', it is propagated as return message." + (declare (completion ignore)) (interactive "e") (condition-case err (let (monitor args result) commit 986a919523cb963539cceadfda511eaf8a64d829 Author: Masahiro Nakamura Date: Fri Mar 5 17:46:53 2021 +0100 * doc/misc/tramp.texi (Remote shell setup): Fix reference. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 4636e73671..2c9348f6d0 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -2211,7 +2211,7 @@ be recomputed. To force @value{tramp} to recompute afresh, call By default, @value{tramp} uses the command @command{/bin/sh} for starting a shell on the remote host. This can be changed by setting -the connection property @t{"remote-shell"}; see @pxref{Predefined +the connection property @t{"remote-shell"}; see @ref{Predefined connection information}. If you want, for example, use @command{/usr/bin/zsh} on a remote host, you might apply commit 9f09083bcd68cbaa0b6c14d560ad81ba878cf7be Author: Masahiro Nakamura Date: Fri Mar 5 17:42:46 2021 +0100 * doc/misc/tramp.texi (Remote shell setup): Fix reference. (Do not merge) diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 0a968e3945..8eaac14763 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -2150,7 +2150,7 @@ be recomputed. To force @value{tramp} to recompute afresh, call Per default, @value{tramp} uses the command @command{/bin/sh} for starting a shell on the remote host. This can be changed by setting -the connection property @t{"remote-shell"}, see @xref{Predefined +the connection property @t{"remote-shell"}, see @ref{Predefined connection information}. If you want, for example, use @command{/usr/bin/zsh} on a remote host, you might apply commit 1b30431c0ec871658423ba080eb6c89df24e7232 Author: Lars Ingebrigtsen Date: Fri Mar 5 14:27:08 2021 +0100 Improve the documentation of :extra in cl-defmethod * doc/lispref/functions.texi (Generic Functions): Improve documentation of :extra (bug#46917). * lisp/emacs-lisp/cl-generic.el (cl-defmethod): Ditto. diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index 2a9b57f19f..64883bf0f6 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi @@ -1181,7 +1181,7 @@ This form defines a method like @code{cl-defmethod} does. @end table @end defmac -@defmac cl-defmethod name [qualifier] arguments [&context (expr spec)@dots{}] &rest [docstring] body +@defmac cl-defmethod name [extra] [qualifier] arguments [&context (expr spec)@dots{}] &rest [docstring] body This macro defines a particular implementation for the generic function called @var{name}. The implementation code is given by @var{body}. If present, @var{docstring} is the documentation string @@ -1267,6 +1267,10 @@ Parent type: @code{array}. @item font-object @end table +The optional @var{extra} element, expressed as @samp{:extra +@var{string}}, allows you to add more methods, distinguished by +@var{string}, for the same specializers and qualifiers. + The optional @var{qualifier} allows combining several applicable methods. If it is not present, the defined method is a @dfn{primary} method, responsible for providing the primary implementation of the @@ -1288,9 +1292,6 @@ This auxiliary method will run @emph{instead} of the primary method. The most specific of such methods will be run before any other method. Such methods normally use @code{cl-call-next-method}, described below, to invoke the other auxiliary or primary methods. -@item :extra @var{string} -This allows you to add more methods, distinguished by @var{string}, -for the same specializers and qualifiers. @end table Functions defined using @code{cl-defmethod} cannot be made diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index e78f88e30c..f5b8c7b662 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el @@ -455,8 +455,12 @@ all methods of NAME have to use the same set of arguments for dispatch. Each dispatch argument and TYPE are specified in ARGS where the corresponding formal argument appears as (VAR TYPE) rather than just VAR. -The optional second argument QUALIFIER is a specifier that -modifies how the method is combined with other methods, including: +The optional EXTRA element, on the form `:extra STRING', allows +you to add more methods for the same specializers and qualifiers. +These are distinguished by STRING. + +The optional argument QUALIFIER is a specifier that modifies how +the method is combined with other methods, including: :before - Method will be called before the primary :after - Method will be called after the primary :around - Method will be called around everything else @@ -473,7 +477,7 @@ method to be applicable. The set of acceptable TYPEs (also called \"specializers\") is defined \(and can be extended) by the various methods of `cl-generic-generalizers'. -\(fn NAME [QUALIFIER] ARGS &rest [DOCSTRING] BODY)" +\(fn NAME [EXTRA] [QUALIFIER] ARGS &rest [DOCSTRING] BODY)" (declare (doc-string cl--defmethod-doc-pos) (indent defun) (debug (&define ; this means we are defining something commit 51e78e91464601fc9adef1ca9c1c5ff0a23043ef Author: Mauro Aranda Date: Fri Mar 5 14:18:32 2021 +0100 Fix qualifiers order for loadhist-unload-element in elp.el * lisp/emacs-lisp/elp.el (loadhist-unload-element): The :extra qualifier is expected to come before the other qualifiers, so do that (bug#46917). diff --git a/lisp/emacs-lisp/elp.el b/lisp/emacs-lisp/elp.el index cc2927caf4..411ea2af69 100644 --- a/lisp/emacs-lisp/elp.el +++ b/lisp/emacs-lisp/elp.el @@ -583,7 +583,7 @@ displayed." ;; continue standard unloading nil) -(cl-defmethod loadhist-unload-element :before :extra "elp" ((x (head defun))) +(cl-defmethod loadhist-unload-element :extra "elp" :before ((x (head defun))) "Un-instrument before unloading a function." (elp-restore-function (cdr x))) commit 57758dcbac02d3477de7f1e30d3c53a9e647b9f3 Author: Stephen Berman Date: Fri Mar 5 14:08:17 2021 +0100 Restrict the version guesser to top-level headings * lisp/help-fns.el (help-fns--first-release): Restrict the version guesser to top-level section -- looking in all headings leads to false positives (bug#46889). diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 290bebf7e5..01d3756bf0 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -668,7 +668,7 @@ FILE is the file where FUNCTION was probably defined." ;; Almost all entries are of the form "* ... in Emacs NN.MM." ;; but there are also a few in the form "* Emacs NN.MM is a bug ;; fix release ...". - (if (not (re-search-backward "^\\*.* Emacs \\([0-9.]+[0-9]\\)" + (if (not (re-search-backward "^\\* .* Emacs \\([0-9.]+[0-9]\\)" nil t)) (message "Ref found in non-versioned section in %S" (file-name-nondirectory f)) commit ef61a6b636156a31a20bb4f002015e4e4611c041 Author: Lars Ingebrigtsen Date: Fri Mar 5 14:01:00 2021 +0100 Actually fill the correct paragraph in `lisp-fill-paragraph' * lisp/emacs-lisp/lisp-mode.el (lisp-fill-paragraph): Fix previous change here by actually filling the correct paragraph (bug#28937). diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 257ac7412e..4aa8ddcfa1 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -1371,7 +1371,8 @@ and initial semicolons." fill-column))) (save-restriction (save-excursion - (let ((ppss (syntax-ppss))) + (let ((ppss (syntax-ppss)) + (start (point))) ;; If we're in a string, then narrow (roughly) to that ;; string before filling. This avoids filling Lisp ;; statements that follow the string. @@ -1386,6 +1387,8 @@ and initial semicolons." t)) (narrow-to-region (ppss-comment-or-string-start ppss) (point)))) + ;; Move back to where we were. + (goto-char start) (fill-paragraph justify))))) ;; Never return nil. t)) commit fc83f3795174213a412920232c85377f2a30bb7f Author: Eli Zaretskii Date: Fri Mar 5 14:42:22 2021 +0200 Fix initialization of 'while-no-input-ignore-events' * src/keyboard.c (syms_of_keyboard_for_pdumper): Don't reset 'while-no-input-ignore-events' after loading the dump file. (Bug#46940) diff --git a/src/keyboard.c b/src/keyboard.c index d142d4c197..c3e4f5d36a 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -12389,8 +12389,6 @@ syms_of_keyboard_for_pdumper (void) eassert (initial_kboard == NULL); initial_kboard = allocate_kboard (Qt); - Vwhile_no_input_ignore_events = Qnil; - inhibit_record_char = false; } commit 0ddbacca7d45e68a3235489de94293335891806c Author: Basil L. Contovounesios Date: Fri Mar 5 11:02:20 2021 +0000 Don't override load-path in require-theme * lisp/custom.el (require-theme): Open-code 'require' error, because binding load-path can prevent other libraries from loading on error, such as debug.el, which gives a misleading error. (Bug#45068) diff --git a/lisp/custom.el b/lisp/custom.el index b9fccce583..85e5d65ffb 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1223,8 +1223,8 @@ provide FEATURE, signal an error. This cannot be suppressed." (file (locate-file (symbol-name feature) path '(".elc" ".el")))) (and file (require feature (file-name-sans-extension file) noerror)))) ((not noerror) - (let (load-path) - (require feature))))) + (signal 'file-missing `("Cannot open load file" "No such file or directory" + ,(symbol-name feature)))))) (defcustom custom-safe-themes '(default) "Themes that are considered safe to load. commit 77ec25122c9a7855657de564101c9fe763b91013 Author: Pip Cet Date: Thu Mar 4 21:06:13 2021 +0000 Don't ignore lexically-bound variables in a defvar (bug#46912) * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Walk the value form of a defvar. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index b51ba80155..b3325816c5 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -607,9 +607,12 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") (setq args (cddr args))) (cons fn (nreverse var-expr-list)))) - (`(defvar ,(and (pred symbolp) name) . ,_) - (push name byte-optimize--dynamic-vars) - form) + (`(defvar ,(and (pred symbolp) name) . ,rest) + (let ((optimized-rest (and rest + (cons (byte-optimize-form (car rest) nil) + (cdr rest))))) + (push name byte-optimize--dynamic-vars) + `(defvar ,name . ,optimized-rest))) (`(,(pred byte-code-function-p) . ,exps) (cons fn (mapcar #'byte-optimize-form exps))) commit 4c2820ce3f89b2c4b8c289e200da5f66fe6c2878 Author: Glenn Morris Date: Thu Mar 4 20:04:50 2021 -0800 * Makefile.in: Ensure non-info forms of doc/misc have an Emacs binary. diff --git a/Makefile.in b/Makefile.in index f56545948a..856c29a453 100644 --- a/Makefile.in +++ b/Makefile.in @@ -982,8 +982,6 @@ INFOS = lispref-info lispintro-info emacs-info misc-info PDFS = lispref-pdf lispintro-pdf emacs-pdf misc-pdf PSS = lispref-ps lispintro-ps emacs-ps misc-ps -## FIXME all of the misc- targets should really depend on lisp, -## like the info target. DOCS = $(DVIS) $(HTMLS) $(INFOS) $(PDFS) $(PSS) $(DOCS): $(MAKE) -C doc/$(subst -, ,$@) @@ -999,11 +997,14 @@ info-real: $(INFOS) pdf: $(PDFS) ps: $(PSS) -# The dependency is due to those doc/misc/ manuals that use .org sources. +# This dependency is due to those doc/misc/ manuals that use .org sources. # Depending on src is sufficient, but ends up being slow, since the # uncompiled lisp/org/*.el files are used to build the .texi files -# (which is slow even with the elc files). +# (which can be slow even with the elc files). misc-info: lisp +# Using src rather than lisp because one is less likely to get unnecessary +# rebuilds of stuff that is not strictly necessary for generating manuals. +misc-dvi misc-html misc-pdf misc-ps: src info-dir: ${srcdir}/info/dir commit 27428d22c8fd4f53a268484d235827122752d68a Author: Stefan Monnier Date: Thu Mar 4 18:20:56 2021 -0500 * lisp/emacs-lisp/cl-generic.el: Make `doc-string` prop work with qualifiers (cl--defmethod-doc-pos): New function. (cl-defmethod): Use it. diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index 89fc0b16d0..e78f88e30c 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el @@ -425,6 +425,16 @@ the specializer used will be the one returned by BODY." (defun cl-generic--method-qualifier-p (x) (not (listp x))) +(defun cl--defmethod-doc-pos () + "Return the index of the docstring for a `cl-defmethod'. +Presumes point is at the end of the `cl-defmethod' symbol." + (save-excursion + (let ((n 2)) + (while (and (ignore-errors (forward-sexp 1) t) + (not (eq (char-before) ?\)))) + (cl-incf n)) + n))) + ;;;###autoload (defmacro cl-defmethod (name args &rest body) "Define a new method for generic function NAME. @@ -464,7 +474,7 @@ The set of acceptable TYPEs (also called \"specializers\") is defined \(and can be extended) by the various methods of `cl-generic-generalizers'. \(fn NAME [QUALIFIER] ARGS &rest [DOCSTRING] BODY)" - (declare (doc-string 3) (indent defun) + (declare (doc-string cl--defmethod-doc-pos) (indent defun) (debug (&define ; this means we are defining something [&name [sexp ;Allow (setf ...) additionally to symbols. commit 0981712e5764c9e553d2160139cca6c83afb0946 Author: Lars Ingebrigtsen Date: Thu Mar 4 21:39:40 2021 +0100 Add a command in package mode for opening home pages directly * doc/emacs/package.texi (Package Menu): Document it. * lisp/emacs-lisp/package.el (package-browse-url): New command and keystroke (bug#46927). diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi index 038a31a35b..c2bd5cb9c2 100644 --- a/doc/emacs/package.texi +++ b/doc/emacs/package.texi @@ -126,6 +126,13 @@ line; typing @kbd{x} (see below) will delete the package. @xref{Package Files}, for information about what package deletion entails. +@item w +@kindex w @r{(Package Menu)} +@findex package-browse-url +Open the home page of the package on the current line in a browser +(@code{package-browse-url}). @code{browse-url} is used to open the +browser. + @item ~ @kindex ~ @r{(Package Menu)} @findex package-menu-mark-obsolete-for-deletion diff --git a/etc/NEWS b/etc/NEWS index b7799e728e..3522fce03a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1159,6 +1159,9 @@ equivalent to '(map (:sym sym))'. ** Package ++++ +*** New command 'package-browse-url' and keystroke 'w'. + +++ *** New commands to filter the package list. The filter commands are bound to the following keys: diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index c81992145d..0973963af2 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -2731,6 +2731,7 @@ either a full name or nil, and EMAIL is a valid email address." (define-key map "U" 'package-menu-mark-upgrades) (define-key map "r" 'revert-buffer) (define-key map "~" 'package-menu-mark-obsolete-for-deletion) + (define-key map "w" 'package-browse-url) (define-key map "x" 'package-menu-execute) (define-key map "h" 'package-menu-quick-help) (define-key map "H" #'package-menu-hide-package) @@ -2753,6 +2754,8 @@ either a full name or nil, and EMAIL is a valid email address." "Menu for `package-menu-mode'." '("Package" ["Describe Package" package-menu-describe-package :help "Display information about this package"] + ["Open Package Homepage" package-browse-url + :help "Open the homepage of this package"] ["Help" package-menu-quick-help :help "Show short key binding help for package-menu-mode"] "--" ["Refresh Package List" revert-buffer @@ -4160,6 +4163,22 @@ beginning of the line." (package-version-join (package-desc-version package-desc)) (package-desc-summary package-desc)))) +(defun package-browse-url (desc &optional secondary) + "Open the home page of the package under point in a browser. +`browse-url' is used to determine the browser to be used. +If SECONDARY (interactively, the prefix), use the secondary browser." + (interactive (list (tabulated-list-get-id) + current-prefix-arg) + package-menu-mode) + (unless desc + (user-error "No package here")) + (let ((url (cdr (assoc :url (package-desc-extras desc))))) + (unless url + (user-error "No home page for %s" (package-desc-name desc))) + (if secondary + (funcall browse-url-secondary-browser-function url) + (browse-url url)))) + ;;;; Introspection (defun package-get-descriptor (pkg-name) commit 8f603da44c62fd4c4904a4d1ac8f03fa862564cf Author: Eli Zaretskii Date: Thu Mar 4 15:30:10 2021 +0200 Update documentation of reading passwords * doc/emacs/mini.texi (Passwords): Update to match the modified implementation. (Bug#46902) Add indexing. diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi index 4b3f15650c..af9a84072c 100644 --- a/doc/emacs/mini.texi +++ b/doc/emacs/mini.texi @@ -785,6 +785,7 @@ can re-execute a command by calling @code{eval} with the @node Passwords @section Entering passwords +@cindex entering passwords Sometimes, you may need to enter a password into Emacs. For instance, when you tell Emacs to visit a file on another machine via a network @@ -795,7 +796,7 @@ access to the machine (@pxref{Remote Files}). displays a prompt in the echo area (such as @samp{Password: }); after you type the required password, press @key{RET} to submit it. To prevent others from seeing your password, every character you type is -displayed as a dot (@samp{.}) instead of its usual form. +displayed as an asterisk (@samp{*}) instead of its usual form. Most of the features and commands associated with the minibuffer @emph{cannot} be used when entering a password. There is no history commit fd9202304c8e08665c5dd468cdd56b523ffc7997 Author: Mauro Aranda Date: Thu Mar 4 08:34:58 2021 -0300 Make checkdoc work with qualified methods * lisp/emacs-lisp/checkdoc.el (checkdoc--next-docstring): Handle cl-defmethod in a case of its own. Check for the presence of qualifiers, and skip them accordingly until the docstring. * test/lisp/emacs-lisp/checkdoc-tests.el (checkdoc-cl-defmethod-qualified-ok) (checkdoc-cl-defmethod-with-extra-qualifier-ok) (checkdoc-cl-defmethod-with-extra-and-nil-args-ok): Add tests for the fix. diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index 75aefdc7ba..213ab43184 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -932,7 +932,7 @@ don't move point." ;; definition ends prematurely. (end-of-file))) (`(,(or 'defun 'defvar 'defcustom 'defmacro 'defconst 'defsubst 'defadvice - 'cl-defun 'cl-defgeneric 'cl-defmethod 'cl-defmacro) + 'cl-defun 'cl-defgeneric 'cl-defmacro) ,(pred symbolp) ;; Require an initializer, i.e. ignore single-argument `defvar' ;; forms, which never have a doc string. @@ -942,6 +942,25 @@ don't move point." ;; initializer or argument list. (forward-sexp 3) (skip-chars-forward " \n\t") + t) + (`(,'cl-defmethod + ,(pred symbolp) + . ,rest) + (down-list) + (forward-sexp (pcase (car rest) + ;; No qualifier, so skip like we would have skipped in + ;; the first clause of the outer `pcase'. + ((pred listp) 3) + (':extra + ;; Skip the :extra qualifier together with its string too. + ;; Skip any additional qualifier. + (if (memq (nth 2 rest) '(:around :before :after)) + 6 + 5)) + ;; Skip :before, :after or :around qualifier too. + ((or ':around ':before ':after) + 4))) + (skip-chars-forward " \n\t") t))) ;;;###autoload diff --git a/test/lisp/emacs-lisp/checkdoc-tests.el b/test/lisp/emacs-lisp/checkdoc-tests.el index 93015fbb10..7a7aa9fb3c 100644 --- a/test/lisp/emacs-lisp/checkdoc-tests.el +++ b/test/lisp/emacs-lisp/checkdoc-tests.el @@ -52,6 +52,33 @@ (insert "(cl-defmethod foo ((a (eql smthg)) (b list)) \"Return A+B.\")") (checkdoc-defun))) +(ert-deftest checkdoc-cl-defmethod-qualified-ok () + "Checkdoc should be happy with a `cl-defmethod' using qualifiers." + (with-temp-buffer + (emacs-lisp-mode) + (insert "(cl-defmethod test :around ((a (eql smthg))) \"Return A.\")") + (checkdoc-defun))) + +(ert-deftest checkdoc-cl-defmethod-with-extra-qualifier-ok () + "Checkdoc should be happy with a :extra qualified `cl-defmethod'." + (with-temp-buffer + (emacs-lisp-mode) + (insert "(cl-defmethod foo :extra \"foo\" ((a (eql smthg))) \"Return A.\")") + (checkdoc-defun)) + + (with-temp-buffer + (emacs-lisp-mode) + (insert + "(cl-defmethod foo :extra \"foo\" :after ((a (eql smthg))) \"Return A.\")") + (checkdoc-defun))) + +(ert-deftest checkdoc-cl-defmethod-with-extra-qualifier-and-nil-args-ok () + "Checkdoc should be happy with a 0-arity :extra qualified `cl-defmethod'." + (with-temp-buffer + (emacs-lisp-mode) + (insert "(cl-defmethod foo :extra \"foo\" () \"Return A.\")") + (checkdoc-defun))) + (ert-deftest checkdoc-cl-defun-with-key-ok () "Checkdoc should be happy with a cl-defun using &key." (with-temp-buffer commit 2d435224689ab8b02b64ce78b6e9d061fe48df22 Author: Lars Ingebrigtsen Date: Thu Mar 4 21:21:21 2021 +0100 Add "of" as a keyword in js-mode * lisp/progmodes/js.el (js--keyword-re): Add the "of" of "for ... of" in ECMAScript 2018 (bug#46924). diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 21bda08680..c233dcebe1 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -282,7 +282,7 @@ Match group 1 is the name of the macro.") "continue" "debugger" "default" "delete" "do" "else" "enum" "export" "extends" "final" "finally" "for" "function" "goto" "if" "implements" "import" "in" - "instanceof" "interface" "native" "new" "package" + "instanceof" "interface" "native" "new" "of" "package" "private" "protected" "public" "return" "static" "super" "switch" "synchronized" "throw" "throws" "transient" "try" "typeof" "var" "void" "let" commit 6ff90ef0bbd5ed6ff284a614352a17cf37d570fe Author: Matt Armstrong Date: Thu Mar 4 21:12:00 2021 +0100 Call the set_buffer_overlays_ setters * src/buffer.c (Fkill_buffer): Call set_buffer_overlays_before and set_buffer_overlays_after instead of setting the fields directly (bug#46914). diff --git a/src/buffer.c b/src/buffer.c index 5bd9b37702..03c10cc7ae 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1942,8 +1942,8 @@ cleaning up all windows currently displaying the buffer to be killed. */) } /* Since we've unlinked the markers, the overlays can't be here any more either. */ - b->overlays_before = NULL; - b->overlays_after = NULL; + set_buffer_overlays_before (b, NULL); + set_buffer_overlays_after (b, NULL); /* Reset the local variables, so that this buffer's local values won't be protected from GC. They would be protected commit 9e945092674ac2a7db46fecae30587ec2ca7cb05 Author: Glenn Morris Date: Thu Mar 4 10:47:09 2021 -0800 Generate info/dir directly from any org sources * Makefile.in (texi_misc): New variable. (srcdir_doc_info_dir_inputs): Use texi_misc. (${srcdir}/info/dir): No longer depend on info-real. diff --git a/Makefile.in b/Makefile.in index 71d38f1609..f56545948a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1007,12 +1007,13 @@ misc-info: lisp info-dir: ${srcdir}/info/dir -## Hopefully doc/misc/*.texi is not too long for some systems? +texi_misc = $(shell ${MAKE} --no-print-directory -s -C doc/misc echo-sources) + srcdir_doc_info_dir_inputs = \ ${srcdir}/doc/emacs/emacs.texi \ ${srcdir}/doc/lispintro/emacs-lisp-intro.texi \ ${srcdir}/doc/lispref/elisp.texi \ - $(sort $(wildcard ${srcdir}/doc/misc/*.texi)) + $(addprefix ${srcdir}/doc/misc/,${texi_misc}) info_dir_inputs = \ ../build-aux/dir_top \ $(subst ${srcdir}/doc/,,${srcdir_doc_info_dir_inputs}) @@ -1027,11 +1028,7 @@ info_dir_deps = \ ## FIXME it would be faster to use the install-info program if we have it, ## but then we would need to depend on info-real, which would ## slow down parallelization. - -## Now that some texi files are generated, this needs to depend on info. -## Sigh. FIXME: the minimum dependency is "generated doc/misc/*.texi". -## TODO build-aux/make-info-dir could parse org sources directly. -${srcdir}/info/dir: ${info_dir_deps} info-real +${srcdir}/info/dir: ${info_dir_deps} $(AM_V_at)${MKDIR_P} ${srcdir}/info $(AM_V_GEN)(cd ${srcdir}/doc && \ AWK='${AWK}' ../build-aux/make-info-dir ${info_dir_inputs} \ commit 4e83fd00bd97894338418db97121f267fa162608 Author: Glenn Morris Date: Thu Mar 4 10:44:07 2021 -0800 * doc/misc/Makefile.in (echo-sources): New phony target. diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in index ed33364440..87d87bf200 100644 --- a/doc/misc/Makefile.in +++ b/doc/misc/Makefile.in @@ -94,6 +94,15 @@ TEXI_FROM_ORG = ${ORG_SRC:.org=.texi} TARGETS_1 = $(INFO_INSTALL:ccmode=cc-mode) TARGETS = $(TARGETS_1:info.info=info) +texi_sources = $(addsuffix .texi,${TARGETS}) +texi_notgen = $(filter-out $(notdir ${TEXI_FROM_ORG}),${texi_sources}) +texi_and_org = $(notdir ${ORG_SRC}) ${texi_notgen} +SOURCES = $(sort ${texi_and_org}) +.PHONY: echo-sources +## Used by the top-level Makefile. +echo-sources: + @echo ${SOURCES} + DVI_TARGETS = $(TARGETS:=.dvi) HTML_TARGETS = $(TARGETS:=.html) PDF_TARGETS = $(TARGETS:=.pdf) commit bd443f4e9c50463524f48cf5c43f35f2cecd528a Author: Glenn Morris Date: Thu Mar 4 10:43:25 2021 -0800 * build-aux/make-info-dir: Handle .org input files. diff --git a/build-aux/make-info-dir b/build-aux/make-info-dir index ea26479cd9..256c9f025c 100755 --- a/build-aux/make-info-dir +++ b/build-aux/make-info-dir @@ -52,8 +52,11 @@ exec "${AWK-awk}" ' topic[ntopics++] = "Emacs misc features" topic[ntopics++] = "Emacs lisp libraries" topic[ntopics] = "Unknown category" + texinfo = 0 } + /^@dircategory / { + texinfo = 1 sub(/^@dircategory /, "") detexinfo() for (dircat = 0; dircat < ntopics && topic[dircat] != $0; dircat++) @@ -66,6 +69,33 @@ exec "${AWK-awk}" ' data[dircat] = data[dircat] $0 "\n" } } + + ## Org stuff. TODO we assume the order of the texinfo items. + { + ## TODO Check FILENAME suffix instead? + ## TODO Is this portable awk? + if (FNR == 1) texinfo = 0 + + ## If applied to the generated org.texi file, this picks up the examples. + ## Thanks for making life more difficult... + if (texinfo) next + + if (tolower($0) ~ /^#\+texinfo_dir_category/) { + sub(/^#[^:]*: /, "") + for (dircat = 0; dircat < ntopics && topic[dircat] != $0; dircat++) + continue; + } + if (tolower($0) ~ /^#\+texinfo_dir_title/) { + sub(/^#[^:]*: /, "") + ## Note this does not fill any long descriptions. + data[dircat] = data[dircat] sprintf("* %-30s", ($0 ". ")) + } + if (tolower($0) ~ /^#\+texinfo_dir_desc/) { + sub(/^#[^:]*: /, "") + data[dircat] = data[dircat] $0 ".\n" + } + } + END { for (dircat = 0; dircat <= ntopics; dircat++) if (data[dircat]) commit ee6527545d4d81e27cfd8b460881c57e2bc5c40a Author: Glenn Morris Date: Thu Mar 4 10:41:00 2021 -0800 ; Makefile.in: Update a comment. diff --git a/Makefile.in b/Makefile.in index a69c01b9c5..71d38f1609 100644 --- a/Makefile.in +++ b/Makefile.in @@ -999,6 +999,10 @@ info-real: $(INFOS) pdf: $(PDFS) ps: $(PSS) +# The dependency is due to those doc/misc/ manuals that use .org sources. +# Depending on src is sufficient, but ends up being slow, since the +# uncompiled lisp/org/*.el files are used to build the .texi files +# (which is slow even with the elc files). misc-info: lisp info-dir: ${srcdir}/info/dir @@ -1092,13 +1096,6 @@ uninstall-ps: $(UNINSTALL_PS) # would require changing every rule in doc/ that builds an info file, # and it's not worth it. This case is only relevant if you download a # release, then change the .texi files. - -# The dependency is due to those doc/misc/ manuals that use .org sources. -# I would have preferred to just add this to the misc-info target, -# but that gave parallel build errors. -# Depending on src is sufficient, but ends up being slow, since the -# uncompiled lisp/org/*.el files are used to build the .texi files -# (which is slow even with the elc files). ifneq ($(HAVE_MAKEINFO),no) info: info-real info-dir else commit 8e759d60cc234d4beb471dbb46f91d8ca3a20066 Author: Basil L. Contovounesios Date: Tue Mar 2 14:35:50 2021 +0000 Decouple require-theme from load-theme * lisp/custom.el (require-theme): Refashion after 'require', as a function for loading only named features. Do not call load-theme (bug#45068). * etc/NEWS: Update its announcement accordingly. * doc/lispref/customize.texi (Custom Themes): Document it. * etc/themes/modus-operandi-theme.el: * etc/themes/modus-vivendi-theme.el: Remove redundant calls to 'provide'. * test/lisp/custom-tests.el (custom-tests--with-temp-dir): New macro. (custom-theme--load-path): Use it. (custom-tests-require-theme): New test. diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi index 8fd12f7902..bc35982c17 100644 --- a/doc/lispref/customize.texi +++ b/doc/lispref/customize.texi @@ -1474,7 +1474,7 @@ To protect against loading themes containing malicious code, Emacs displays the source file and asks for confirmation from the user before loading any non-built-in theme for the first time. As such, themes are not ordinarily byte-compiled, and source files -always take precedence when Emacs is looking for a theme to load. +usually take precedence when Emacs is looking for a theme to load. The following functions are useful for programmatically enabling and disabling themes: @@ -1508,6 +1508,30 @@ confirmation before loading the theme, unless the optional argument @var{no-confirm} is non-@code{nil}. @end deffn +@defun require-theme feature &optional noerror +This function searches @code{custom-theme-load-path} for a file that +provides @var{feature} and then loads it. This is like the function +@code{require} (@pxref{Named Features}), except it searches +@code{custom-theme-load-path} instead of @code{load-path} +(@pxref{Library Search}). This can be useful in Custom themes that +need to load supporting Lisp files when @code{require} is unsuitable +for that. + +If @var{feature}, which should be a symbol, is not already present in +the current Emacs session according to @code{featurep}, then +@code{require-theme} searches for a file named @var{feature} with an +added @samp{.elc} or @samp{.el} suffix, in that order, in the +directories specified by @code{custom-theme-load-path}. + +If a file providing @var{feature} is successfully found and loaded, +then @code{require-theme} returns @var{feature}. The optional +argument @var{noerror} determines what happens if the search or +loading fails. If it is @code{nil}, the function signals an error; +otherwise, it returns @code{nil}. If the file loads successfully but +does not provide @var{feature}, then @code{require-theme} signals an +error; this cannot be suppressed. +@end defun + @deffn Command enable-theme theme This function enables the Custom theme named @var{theme}. It signals an error if no such theme has been loaded. diff --git a/etc/NEWS b/etc/NEWS index b8413ae080..b7799e728e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2528,11 +2528,11 @@ region's (or buffer's) end. This function can be used by modes to add elements to the 'choice' customization type of a variable. ---- ++++ ** New function 'require-theme'. -This function is used to load a theme or library stored in the -'custom-theme-load-path'. It is intended to work as a substitute for -'require' in those cases where that cannot be used. +This function is like 'require', but searches 'custom-theme-load-path' +instead of 'load-path'. It can be used by Custom themes to load +supporting Lisp files when 'require' is unsuitable. +++ ** New function 'file-modes-number-to-symbolic' to convert a numeric diff --git a/etc/themes/modus-operandi-theme.el b/etc/themes/modus-operandi-theme.el index 346000a093..9d6e9ad50f 100644 --- a/etc/themes/modus-operandi-theme.el +++ b/etc/themes/modus-operandi-theme.el @@ -4661,6 +4661,4 @@ Also bind `class' to ((class color) (min-colors 89))." (provide-theme 'modus-operandi) -(provide 'modus-operandi-theme) - ;;; modus-operandi-theme.el ends here diff --git a/etc/themes/modus-vivendi-theme.el b/etc/themes/modus-vivendi-theme.el index 73f07d644b..171313244b 100644 --- a/etc/themes/modus-vivendi-theme.el +++ b/etc/themes/modus-vivendi-theme.el @@ -4661,6 +4661,4 @@ Also bind `class' to ((class color) (min-colors 89))." (provide-theme 'modus-vivendi) -(provide 'modus-vivendi-theme) - ;;; modus-vivendi-theme.el ends here diff --git a/lisp/custom.el b/lisp/custom.el index 35ac4d8564..b9fccce583 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1200,29 +1200,31 @@ property `theme-feature' (which is usually a symbol created by (custom-check-theme theme) (provide (get theme 'theme-feature))) -(defun require-theme (theme &optional path) - "Load THEME stored in `custom-theme-load-path'. - -THEME is a symbol that corresponds to the file name without its file -type extension. That is assumed to be either '.el' or '.elc'. - -When THEME is an element of `custom-available-themes', load it and ask -for confirmation if it is not considered safe by `custom-safe-themes'. -Otherwise load the file indicated by THEME, if present. In the latter -case, the file is intended to work as the basis of a theme declared -with `deftheme'. - -If optional PATH is non-nil, it should be a list of directories -to search for THEME in, instead of `custom-theme-load-path'. -PATH should have the same form as `load-path' or `exec-path'." +(defun require-theme (feature &optional noerror) + "Load FEATURE from a file along `custom-theme-load-path'. + +This function is like `require', but searches along +`custom-theme-load-path' instead of `load-path'. It can be used +by Custom themes to load supporting Lisp files when `require' is +unsuitable. + +If FEATURE is not already loaded, search for a file named FEATURE +with an added `.elc' or `.el' suffix, in that order, in the +directories specified by `custom-theme-load-path'. + +Return FEATURE if the file is successfully found and loaded, or +if FEATURE was already loaded. If the file fails to load, signal +an error. If optional argument NOERROR is non-nil, return nil +instead of signaling an error. If the file loads but does not +provide FEATURE, signal an error. This cannot be suppressed." (cond - ((memq theme (custom-available-themes)) - (load-theme theme)) - ((let* ((dirs (or path (custom-theme--load-path))) - (file (unless (featurep theme) - (locate-file (symbol-name theme) dirs '(".el" ".elc"))))) - (when file - (load-file file)))))) + ((featurep feature) feature) + ((let* ((path (custom-theme--load-path)) + (file (locate-file (symbol-name feature) path '(".elc" ".el")))) + (and file (require feature (file-name-sans-extension file) noerror)))) + ((not noerror) + (let (load-path) + (require feature))))) (defcustom custom-safe-themes '(default) "Themes that are considered safe to load. diff --git a/test/lisp/custom-tests.el b/test/lisp/custom-tests.el index 09f79c1a08..02a9239824 100644 --- a/test/lisp/custom-tests.el +++ b/test/lisp/custom-tests.el @@ -24,70 +24,108 @@ (require 'wid-edit) (require 'cus-edit) -(require 'seq) ; For `seq-find'. + +(defmacro custom-tests--with-temp-dir (&rest body) + "Eval BODY with `temporary-file-directory' bound to a fresh directory. +Ensure the directory is recursively deleted after the fact." + (declare (debug t) (indent 0)) + (let ((dir (make-symbol "dir"))) + `(let ((,dir (file-name-as-directory (make-temp-file "custom-tests-" t)))) + (unwind-protect + (let ((temporary-file-directory ,dir)) + ,@body) + (delete-directory ,dir t))))) (ert-deftest custom-theme--load-path () "Test `custom-theme--load-path' behavior." - (let ((tmpdir (file-name-as-directory (make-temp-file "custom-tests-" t)))) - (unwind-protect - ;; Create all temporary files under the same deletable parent. - (let ((temporary-file-directory tmpdir)) - ;; Path is empty. - (let ((custom-theme-load-path ())) - (should (null (custom-theme--load-path)))) - - ;; Path comprises non-existent file. - (let* ((name (make-temp-name tmpdir)) - (custom-theme-load-path (list name))) - (should (not (file-exists-p name))) - (should (null (custom-theme--load-path)))) - - ;; Path comprises existing file. - (let* ((file (make-temp-file "file")) - (custom-theme-load-path (list file))) - (should (file-exists-p file)) - (should (not (file-directory-p file))) - (should (null (custom-theme--load-path)))) - - ;; Path comprises existing directory. - (let* ((dir (make-temp-file "dir" t)) - (custom-theme-load-path (list dir))) - (should (file-directory-p dir)) - (should (equal (custom-theme--load-path) custom-theme-load-path))) - - ;; Expand `custom-theme-directory' path element. - (let ((custom-theme-load-path '(custom-theme-directory))) - (let ((custom-theme-directory (make-temp-name tmpdir))) - (should (not (file-exists-p custom-theme-directory))) - (should (null (custom-theme--load-path)))) - (let ((custom-theme-directory (make-temp-file "file"))) - (should (file-exists-p custom-theme-directory)) - (should (not (file-directory-p custom-theme-directory))) - (should (null (custom-theme--load-path)))) - (let ((custom-theme-directory (make-temp-file "dir" t))) - (should (file-directory-p custom-theme-directory)) - (should (equal (custom-theme--load-path) - (list custom-theme-directory))))) - - ;; Expand t path element. - (let ((custom-theme-load-path '(t))) - (let ((data-directory (make-temp-name tmpdir))) - (should (not (file-exists-p data-directory))) - (should (null (custom-theme--load-path)))) - (let ((data-directory tmpdir) - (themedir (expand-file-name "themes" tmpdir))) - (should (not (file-exists-p themedir))) - (should (null (custom-theme--load-path))) - (with-temp-file themedir) - (should (file-exists-p themedir)) - (should (not (file-directory-p themedir))) - (should (null (custom-theme--load-path))) - (delete-file themedir) - (make-directory themedir) - (should (file-directory-p themedir)) - (should (equal (custom-theme--load-path) (list themedir)))))) - (when (file-directory-p tmpdir) - (delete-directory tmpdir t))))) + (custom-tests--with-temp-dir + ;; Path is empty. + (let ((custom-theme-load-path ())) + (should (null (custom-theme--load-path)))) + + ;; Path comprises non-existent file. + (let* ((name (make-temp-name temporary-file-directory)) + (custom-theme-load-path (list name))) + (should (not (file-exists-p name))) + (should (null (custom-theme--load-path)))) + + ;; Path comprises existing file. + (let* ((file (make-temp-file "file")) + (custom-theme-load-path (list file))) + (should (file-exists-p file)) + (should (not (file-directory-p file))) + (should (null (custom-theme--load-path)))) + + ;; Path comprises existing directory. + (let* ((dir (make-temp-file "dir" t)) + (custom-theme-load-path (list dir))) + (should (file-directory-p dir)) + (should (equal (custom-theme--load-path) custom-theme-load-path))) + + ;; Expand `custom-theme-directory' path element. + (let ((custom-theme-load-path '(custom-theme-directory))) + (let ((custom-theme-directory (make-temp-name temporary-file-directory))) + (should (not (file-exists-p custom-theme-directory))) + (should (null (custom-theme--load-path)))) + (let ((custom-theme-directory (make-temp-file "file"))) + (should (file-exists-p custom-theme-directory)) + (should (not (file-directory-p custom-theme-directory))) + (should (null (custom-theme--load-path)))) + (let ((custom-theme-directory (make-temp-file "dir" t))) + (should (file-directory-p custom-theme-directory)) + (should (equal (custom-theme--load-path) + (list custom-theme-directory))))) + + ;; Expand t path element. + (let ((custom-theme-load-path '(t))) + (let ((data-directory (make-temp-name temporary-file-directory))) + (should (not (file-exists-p data-directory))) + (should (null (custom-theme--load-path)))) + (let ((data-directory temporary-file-directory) + (themedir (expand-file-name "themes" temporary-file-directory))) + (should (not (file-exists-p themedir))) + (should (null (custom-theme--load-path))) + (with-temp-file themedir) + (should (file-exists-p themedir)) + (should (not (file-directory-p themedir))) + (should (null (custom-theme--load-path))) + (delete-file themedir) + (make-directory themedir) + (should (file-directory-p themedir)) + (should (equal (custom-theme--load-path) (list themedir))))))) + +(ert-deftest custom-tests-require-theme () + "Test `require-theme'." + (custom-tests--with-temp-dir + (let* ((default-directory temporary-file-directory) + (custom-theme-load-path (list default-directory)) + (load-path ())) + ;; Generate some `.el' and `.elc' files. + (with-temp-file "custom-tests--a.el" + (insert "(provide 'custom-tests--a)")) + (make-empty-file "custom-tests--b.el") + (with-temp-file "custom-tests--b.elc" + (byte-compile-insert-header nil (current-buffer)) + (insert "(provide 'custom-tests--b)")) + (make-empty-file "custom-tests--c.el") + (with-temp-file "custom-tests--d.elc" + (byte-compile-insert-header nil (current-buffer))) + ;; Load them. + (dolist (feature '(a b c d e)) + (should-not (featurep (intern (format "custom-tests--%s" feature))))) + (should (eq (require-theme 'custom-tests--a) 'custom-tests--a)) + (delete-file "custom-tests--a.el") + (dolist (feature '(custom-tests--a custom-tests--b)) + (should (eq (require-theme feature) feature)) + (should (featurep feature))) + (dolist (feature '(custom-tests--c custom-tests--d)) + (dolist (noerror '(nil t)) + (let ((err (should-error (require-theme feature noerror)))) + (should (string-search "failed to provide feature" (cadr err)))))) + (should-error (require-theme 'custom-tests--e) :type 'file-missing) + (should-not (require-theme 'custom-tests--e t)) + (dolist (feature '(custom-tests--c custom-tests--d custom-tests--e)) + (should-not (featurep feature)))))) (defcustom custom--test-user-option 'foo "User option for test." commit 358c6c9b95a5fd77edb1538f5fec5021a03de94a Author: Basil L. Contovounesios Date: Thu Mar 4 15:34:19 2021 +0000 ; Pacify warnings in last newsticker change. diff --git a/lisp/net/newst-backend.el b/lisp/net/newst-backend.el index 9096d681a8..418c1e2e96 100644 --- a/lisp/net/newst-backend.el +++ b/lisp/net/newst-backend.el @@ -39,10 +39,10 @@ (require 'iso8601) ;; Silence warnings +(defvar newsticker-groups) (defvar w3-mode-map) (defvar w3m-minor-mode-map) - (defvar newsticker--retrieval-timer-list nil "List of timers for news retrieval. This is an alist, each element consisting of (feed-name . timer).") @@ -2236,7 +2236,6 @@ If AGE is nil, the total number of items is returned." (defun newsticker-opml-export () "OPML subscription export. Export subscriptions to a buffer in OPML Format." - ;; FIXME: use newsticker-groups (interactive) (with-current-buffer (get-buffer-create "*OPML Export*") (erase-buffer) @@ -2311,7 +2310,7 @@ Export subscriptions to a buffer in OPML Format." (defun newsticker-opml-import (filename) "Import OPML data from FILENAME. -Feeds are added to 'newsticker-url-list and 'newsticker-groups +Feeds are added to `newsticker-url-list' and `newsticker-groups' preserving the outline structure." (interactive "fOPML file: ") (set-buffer (find-file-noselect filename)) commit b1011e9e95e204e8a97be8369d8a95bb3ddcec70 Author: Eli Zaretskii Date: Thu Mar 4 15:21:52 2021 +0200 ; * etc/NEWS: Fix wording of a recently added entry. diff --git a/etc/NEWS b/etc/NEWS index 8ecc6ac519..b8413ae080 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -358,21 +358,24 @@ summary of where Emacs is using memory currently. +++ *** New commands to cycle heading visibility. -Typing 'TAB' on a heading cycles the current section between "hide -all", "subheadings", and "show all" state. Typing 'S-TAB' anywhere in -the buffer cycles the whole buffer between "only top-level headings", -"all headings and subheadings", and "show all" states. +Typing 'TAB' on a heading line cycles the current section between +"hide all", "subheadings", and "show all" states. Typing 'S-TAB' +anywhere in the buffer cycles the whole buffer between "only top-level +headings", "all headings and subheadings", and "show all" states. *** New minor mode 'outline-cycle-minor-mode'. -It enables 'outline-minor-mode' with keys 'TAB' and 'S-TAB' activated -on headings to cycle heading visibility. Typing 'TAB' on a heading -cycles the current section between "hide all", "subheadings", and -"show all" state. Typing 'S-TAB' on a heading cycles the whole buffer -between "only top-level headings", "all headings and subheadings", and -"show all" states. Another new mode 'outline-cycle-highlight-minor-mode' -additionally puts highlighting on headings with standard outline faces, -this works well only when there are no conflicts with faces used -by major mode. +This mode is a variant of 'outline-minor-mode', with the difference +that 'TAB' and 'S-TAB' on heading lines cycle heading visibility. +Typing 'TAB' on a heading line cycles the current section between +"hide all", "subheadings", and "show all" states. Typing 'S-TAB' on a +heading line cycles the whole buffer between "only top-level +headings", "all headings and subheadings", and "show all" states. + +*** New minor mode 'outline-cycle-highlight-minor-mode'. +This mode is a variant of 'outline-cycle-minor-mode'. It puts +highlighting on heading lines using standard outline faces. This +works well only when there are no conflicts with faces used by the +major mode. * Changes in Specialized Modes and Packages in Emacs 28.1 commit ac42f719089a880bba418c95a7a16c4d7df392dd Author: Mauro Aranda Date: Thu Mar 4 10:16:02 2021 -0300 Remove copy-pasto from image-dired.el * lisp/image-dired.el (image-dired-dired-edit-comment-and-tags): Remove reference to widget-example-repeat. diff --git a/lisp/image-dired.el b/lisp/image-dired.el index 48f9cd0767..e4b53bd275 100644 --- a/lisp/image-dired.el +++ b/lisp/image-dired.el @@ -2553,7 +2553,6 @@ easy-to-use form." (let ((files (dired-get-marked-files))) (pop-to-buffer-same-window "*Image-Dired Edit Meta Data*") (kill-all-local-variables) - (make-local-variable 'widget-example-repeat) (let ((inhibit-read-only t)) (erase-buffer)) (remove-overlays) commit 986bf7ac0dbfee0522cbe1e89872309d3a4f182c Author: Mauro Aranda Date: Thu Mar 4 10:13:26 2021 -0300 Remove duplicated tests in checkdoc-tests.el * test/lisp/emacs-lisp/checkdoc-tests.el (checkdoc-cl-defmethod-ok) (checkdoc-cl-defmethod-with-types-ok, checkdoc-cl-defun-with-key-ok) (checkdoc-cl-defun-with-allow-other-keys-ok) (checkdoc-cl-defun-with-default-optional-value-ok) (checkdoc-cl-defun-with-destructuring-ok): This tests were duplicated, so keep one copy of them. Checked by diffing two files with the suspected tests, and supported by the fact that running occur with the regexp "^(ert-deftest" reported 14 matches, while the tests being run were 8. diff --git a/test/lisp/emacs-lisp/checkdoc-tests.el b/test/lisp/emacs-lisp/checkdoc-tests.el index cf7baf4ce4..93015fbb10 100644 --- a/test/lisp/emacs-lisp/checkdoc-tests.el +++ b/test/lisp/emacs-lisp/checkdoc-tests.el @@ -82,51 +82,6 @@ (insert "(cl-defun foo ((a b &optional c) d) \"Return A+B+C+D.\")") (checkdoc-defun))) -(ert-deftest checkdoc-cl-defmethod-ok () - "Checkdoc should be happy with a simple correct cl-defmethod." - (with-temp-buffer - (emacs-lisp-mode) - (insert "(cl-defmethod foo (a) \"Return A.\")") - (checkdoc-defun))) - -(ert-deftest checkdoc-cl-defmethod-with-types-ok () - "Checkdoc should be happy with a cl-defmethod using types." - (with-temp-buffer - (emacs-lisp-mode) - ;; this method matches if A is the symbol `smthg' and if b is a list: - (insert "(cl-defmethod foo ((a (eql smthg)) (b list)) \"Return A+B.\")") - (checkdoc-defun))) - -(ert-deftest checkdoc-cl-defun-with-key-ok () - "Checkdoc should be happy with a cl-defun using &key." - (with-temp-buffer - (emacs-lisp-mode) - (insert "(cl-defun foo (&key a (b 27)) \"Return :A+:B.\")") - (checkdoc-defun))) - -(ert-deftest checkdoc-cl-defun-with-allow-other-keys-ok () - "Checkdoc should be happy with a cl-defun using &allow-other-keys." - (with-temp-buffer - (emacs-lisp-mode) - (insert "(cl-defun foo (&key a &allow-other-keys) \"Return :A.\")") - (checkdoc-defun))) - -(ert-deftest checkdoc-cl-defun-with-default-optional-value-ok () - "Checkdoc should be happy with a cl-defun using default values for optional args." - (with-temp-buffer - (emacs-lisp-mode) - ;; B is optional and equals 1+a if not provided. HAS-BS is non-nil - ;; if B was provided in the call: - (insert "(cl-defun foo (a &optional (b (1+ a) has-bs)) \"Return A + B.\")") - (checkdoc-defun))) - -(ert-deftest checkdoc-cl-defun-with-destructuring-ok () - "Checkdoc should be happy with a cl-defun destructuring its arguments." - (with-temp-buffer - (emacs-lisp-mode) - (insert "(cl-defun foo ((a b &optional c) d) \"Return A+B+C+D.\")") - (checkdoc-defun))) - (ert-deftest checkdoc-tests--next-docstring () "Checks that the one-argument form of `defvar' works. See the comments in Bug#24998." commit 7b99fc0069c02e02a6b9b2418a373db376f99863 Author: Lars Ingebrigtsen Date: Thu Mar 4 12:11:08 2021 +0100 Make radio checkboxes work in eww * lisp/net/eww.el (eww-toggle-checkbox): Actually update the :checked values in the form. diff --git a/lisp/net/eww.el b/lisp/net/eww.el index c94fa03a07..32fe857e65 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -1595,9 +1595,9 @@ See URL `https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input'.") (goto-char (car elem)) (if (not (eq (cdr elem) input)) (progn - (plist-put input :checked nil) + (plist-put (cdr elem) :checked nil) (eww-update-field eww-form-checkbox-symbol)) - (plist-put input :checked t) + (plist-put (cdr elem) :checked t) (eww-update-field eww-form-checkbox-selected-symbol))))) (forward-char 1))))) commit ba33089d50a4f74b88cd7fc9d862d183d096c27d Author: Glenn Morris Date: Wed Mar 3 19:58:47 2021 -0800 Fix a doc/misc clean rule * doc/misc/Makefile.in (TEXI_FROM_ORG): New variable. (orgclean): Fix rule. diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in index 060bffa638..ed33364440 100644 --- a/doc/misc/Makefile.in +++ b/doc/misc/Makefile.in @@ -87,6 +87,7 @@ INFO_TARGETS = $(INFO_COMMON) efaq-w32 ## are not as well formatted as handwritten ones. ORG_SETUP = $(wildcard ${srcdir}/*-setup.org) ORG_SRC = $(filter-out ${ORG_SETUP},$(wildcard ${srcdir}/*.org)) +TEXI_FROM_ORG = ${ORG_SRC:.org=.texi} # There are some naming differences between the info targets and the other # targets, so let's resolve them here. @@ -278,7 +279,7 @@ infoclean: .PHONY: orgclean orgclean: - rm -f $(addprefix ${srcdir}/,${ORG_SRC:=.texi}) + rm -f ${TEXI_FROM_ORG} bootstrap-clean maintainer-clean: distclean infoclean orgclean commit a2ae2d28606cef40aa7d076febb0295fcc44be67 Author: Basil L. Contovounesios Date: Wed Mar 3 12:49:31 2021 +0000 Fix pcase dontcare pattern in cl--sm-macroexpand For discussion, see the following thread: https://lists.gnu.org/r/emacs-devel/2021-03/msg00119.html * lisp/emacs-lisp/cl-macs.el (cl--sm-macroexpand): Fix recently uncovered use of old name for pcase--dontcare. diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 91146c4d0e..c38dc44ff6 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -2298,7 +2298,7 @@ of `cl-symbol-macrolet' to additionally expand symbol macros." ;; The behavior of CL made sense in a dynamically scoped ;; language, but nowadays, lexical scoping semantics is more often ;; expected. - (`(,(or 'let 'let*) . ,(or `(,bindings . ,body) dontcare)) + (`(,(or 'let 'let*) . ,(or `(,bindings . ,body) pcase--dontcare)) (let ((nbs ()) (found nil)) (dolist (binding bindings) (let* ((var (if (symbolp binding) binding (car binding))) commit 88ca2280ba430ad2fa681c72cc6ba8216709e63f Author: Stefan Monnier Date: Wed Mar 3 18:40:03 2021 -0500 * lisp/emacs-lisp/pcase.el (pcase-defmacro): Fix `pcase-tests-macro` * lisp/emacs-lisp/radix-tree.el (radix-tree-leaf): Simplify accordingly. diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 4804180ac9..5342a0179d 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -436,7 +436,13 @@ for the result of evaluating EXP (first arg to `pcase'). (decl (assq 'declare body))) (when decl (setq body (remove decl body))) `(progn - (defun ,fsym ,args ,@body) + ;; FIXME: We use `eval-and-compile' here so that the pcase macro can be + ;; used in the same file where it's defined, but ideally, we should + ;; handle this using something similar to `overriding-plist-environment' + ;; but for `symbol-function' slots so compiling a file doesn't have the + ;; side-effect of defining the function. + (eval-and-compile + (defun ,fsym ,args ,@body)) (define-symbol-prop ',fsym 'edebug-form-spec ',(cadr (assq 'debug decl))) (define-symbol-prop ',name 'pcase-macroexpander #',fsym)))) diff --git a/lisp/emacs-lisp/radix-tree.el b/lisp/emacs-lisp/radix-tree.el index 0905ac608b..fb65975350 100644 --- a/lisp/emacs-lisp/radix-tree.el +++ b/lisp/emacs-lisp/radix-tree.el @@ -194,14 +194,13 @@ If not found, return nil." "Return an alist of all bindings in TREE for prefixes of STRING." (radix-tree--prefixes tree string 0 nil)) -(eval-and-compile - (pcase-defmacro radix-tree-leaf (vpat) - "Pattern which matches a radix-tree leaf. +(pcase-defmacro radix-tree-leaf (vpat) + "Pattern which matches a radix-tree leaf. The pattern VPAT is matched against the leaf's carried value." - ;; We used to use `(pred atom)', but `pcase' doesn't understand that - ;; `atom' is equivalent to the negation of `consp' and hence generates - ;; suboptimal code. - `(or `(t . ,,vpat) (and (pred (not consp)) ,vpat)))) + ;; We used to use `(pred atom)', but `pcase' doesn't understand that + ;; `atom' is equivalent to the negation of `consp' and hence generates + ;; suboptimal code. + `(or `(t . ,,vpat) (and (pred (not consp)) ,vpat))) (defun radix-tree-iter-subtrees (tree fun) "Apply FUN to every immediate subtree of radix TREE. commit b379420a5b005d0e12d12fc162aa34851d456c61 Author: Ulf Jasper Date: Wed Mar 3 21:10:34 2021 +0100 Preserve group structure on opml import and export. * lisp/net/newst-backend.el (newsticker--raw-url-list-defaults), (newsticker-url-list-defaults), (newsticker--get-news-by-url), (newsticker--sentinel-work), (newsticker--parse-atom-0.3), (newsticker--decode-rfc822-date), (newsticker--image-download-by-wget), (newsticker--image-save), (newsticker--image-download-by-url), (newsticker--cache-save), (newsticker--stat-num-items): Fix indentation. (newsticker-opml-export): Preserve group structure on export. (newsticker--opml-insert-elt), (newsticker--opml-insert-group), (newsticker--opml-insert-feed): New. (newsticker--opml-import-outlines): (newsticker-opml-import): Preserve group structure on import. (Fixes fourth issue in Bug#41376.) diff --git a/lisp/net/newst-backend.el b/lisp/net/newst-backend.el index f5b4761078..9096d681a8 100644 --- a/lisp/net/newst-backend.el +++ b/lisp/net/newst-backend.el @@ -66,35 +66,34 @@ considered to be running if the newsticker timer list is not empty." ;; Hard-coding URLs like this is a recipe for propagating obsolete info. (defconst newsticker--raw-url-list-defaults - '( - ("Debian Security Advisories" - "http://www.debian.org/security/dsa.en.rdf") + '(("Debian Security Advisories" + "http://www.debian.org/security/dsa.en.rdf") ("Debian Security Advisories - Long format" - "http://www.debian.org/security/dsa-long.en.rdf") + "http://www.debian.org/security/dsa-long.en.rdf") ("Emacs Wiki" - "https://www.emacswiki.org/emacs?action=rss" - nil - 3600) + "https://www.emacswiki.org/emacs?action=rss" + nil + 3600) ("LWN (Linux Weekly News)" - "https://lwn.net/headlines/rss") + "https://lwn.net/headlines/rss") ("Quote of the day" - "http://feeds.feedburner.com/quotationspage/qotd" - "07:00" - 86400) + "http://feeds.feedburner.com/quotationspage/qotd" + "07:00" + 86400) ("The Register" - "https://www.theregister.co.uk/headlines.rss") + "https://www.theregister.co.uk/headlines.rss") ("slashdot" - "http://rss.slashdot.org/Slashdot/slashdot" - nil - 3600) ;/. will ban you if under 3600 seconds! + "http://rss.slashdot.org/Slashdot/slashdot" + nil + 3600) ;/. will ban you if under 3600 seconds! ("Wired News" - "https://www.wired.com/feed/rss") + "https://www.wired.com/feed/rss") ("Heise News (german)" - "http://www.heise.de/newsticker/heise.rdf") + "http://www.heise.de/newsticker/heise.rdf") ("Tagesschau (german)" - "http://www.tagesschau.de/newsticker.rdf" - nil - 1800)) + "http://www.tagesschau.de/newsticker.rdf" + nil + 1800)) "Default URL list in raw form. This list is fed into defcustom via `newsticker--splicer'.") @@ -153,10 +152,10 @@ value effective." :group 'newsticker) (defcustom newsticker-url-list-defaults - '(("Emacs Wiki" - "https://www.emacswiki.org/emacs?action=rss" - nil - 3600)) + '(("Emacs Wiki" + "https://www.emacswiki.org/emacs?action=rss" + nil + 3600)) "A customizable list of news feeds to select from. These were mostly extracted from the Radio Community Server . @@ -680,8 +679,8 @@ See `newsticker-get-news'." (condition-case error-data (url-retrieve url 'newsticker--get-news-by-url-callback (list feed-name)) - (error (message "Error retrieving news from %s: %s" feed-name - error-data)))) + (error (message "Error retrieving news from %s: %s" feed-name + error-data)))) (force-mode-line-update)) (defun newsticker--get-news-by-url-callback (status feed-name) @@ -825,7 +824,7 @@ Argument BUFFER is the buffer of the retrieval process." (setq coding-system (intern (downcase (match-string 1)))) (setq coding-system (condition-case nil - (check-coding-system coding-system) + (check-coding-system coding-system) (coding-system-error (message "newsticker.el: ignoring coding system %s for %s" @@ -936,8 +935,8 @@ Argument BUFFER is the buffer of the retrieval process." ;; setup scrollable text (when (= 0 (length newsticker--process-ids)) (when (fboundp 'newsticker--ticker-text-setup) ;silence - ;compiler - ;warnings + ;compiler + ;warnings (newsticker--ticker-text-setup))) (setq newsticker--latest-update-time (current-time)) (when something-was-added @@ -945,8 +944,8 @@ Argument BUFFER is the buffer of the retrieval process." (newsticker--cache-save-feed (newsticker--cache-get-feed name-symbol)) (when (fboundp 'newsticker--buffer-set-uptodate) ;silence - ;compiler - ;warnings + ;compiler + ;warnings (newsticker--buffer-set-uptodate nil))) ;; kill the process buffer if wanted (unless newsticker-debug @@ -1107,8 +1106,8 @@ same as in `newsticker--parse-atom-1.0'." ;; time-fn (lambda (node) (newsticker--decode-rfc822-date - (car (xml-node-children - (car (xml-get-children node 'modified)))))) + (car (xml-node-children + (car (xml-get-children node 'modified)))))) ;; guid-fn (lambda (node) (newsticker--guid-to-string @@ -1679,7 +1678,7 @@ Sat, 07 Sep 2002 00:00:01 GMT (message "Cannot decode \"%s\": %s %s" rfc822-string (car error-data) (cdr error-data)) nil)))) - nil)) + nil)) (defun newsticker--lists-intersect-p (list1 list2) "Return t if LIST1 and LIST2 share elements." @@ -1738,27 +1737,27 @@ Save image as FILENAME in DIRECTORY, download it from URL." (let* ((proc-name (concat feed-name "-" filename)) (buffername (concat " *newsticker-wget-image-" proc-name "*")) (item (or (assoc feed-name newsticker-url-list) - (assoc feed-name newsticker-url-list-defaults) - (error - "Cannot get image for %s: Check newsticker-url-list" - feed-name))) + (assoc feed-name newsticker-url-list-defaults) + (error + "Cannot get image for %s: Check newsticker-url-list" + feed-name))) (wget-arguments (or (car (cdr (cdr (cdr (cdr item))))) newsticker-wget-arguments))) - (with-current-buffer (get-buffer-create buffername) - (erase-buffer) - ;; throw an error if there is an old wget-process around - (if (get-process feed-name) - (error "Another wget-process is running for image %s" - feed-name)) - ;; start wget - (let* ((args (append wget-arguments (list url))) - (proc (apply 'start-process proc-name buffername - newsticker-wget-name args))) - (set-process-coding-system proc 'no-conversion 'no-conversion) - (set-process-sentinel proc 'newsticker--image-sentinel) - (process-put proc 'nt-directory directory) - (process-put proc 'nt-feed-name feed-name) - (process-put proc 'nt-filename filename))))) + (with-current-buffer (get-buffer-create buffername) + (erase-buffer) + ;; throw an error if there is an old wget-process around + (if (get-process feed-name) + (error "Another wget-process is running for image %s" + feed-name)) + ;; start wget + (let* ((args (append wget-arguments (list url))) + (proc (apply 'start-process proc-name buffername + newsticker-wget-name args))) + (set-process-coding-system proc 'no-conversion 'no-conversion) + (set-process-sentinel proc 'newsticker--image-sentinel) + (process-put proc 'nt-directory directory) + (process-put proc 'nt-feed-name feed-name) + (process-put proc 'nt-filename filename))))) (defun newsticker--image-sentinel (process _event) "Sentinel for image-retrieving PROCESS caused by EVENT." @@ -1783,18 +1782,18 @@ Save image as FILENAME in DIRECTORY, download it from URL." "Save contents of BUFFER in DIRECTORY as FILE-NAME. Finally kill buffer." (with-current-buffer buffer - (let ((image-name (concat directory file-name))) - (set-buffer-file-coding-system 'no-conversion) - ;; make sure the cache dir exists - (unless (file-directory-p directory) - (make-directory directory)) - ;; write and close buffer - (let ((require-final-newline nil) - (backup-inhibited t) - (coding-system-for-write 'no-conversion)) - (write-region nil nil image-name nil 'quiet)) - (set-buffer-modified-p nil) - (kill-buffer buffer)))) + (let ((image-name (concat directory file-name))) + (set-buffer-file-coding-system 'no-conversion) + ;; make sure the cache dir exists + (unless (file-directory-p directory) + (make-directory directory)) + ;; write and close buffer + (let ((require-final-newline nil) + (backup-inhibited t) + (coding-system-for-write 'no-conversion)) + (write-region nil nil image-name nil 'quiet)) + (set-buffer-modified-p nil) + (kill-buffer buffer)))) (defun newsticker--image-remove (directory file-name) "In DIRECTORY remove FILE-NAME." @@ -1809,8 +1808,8 @@ Save image as FILENAME in DIRECTORY, download it from URL." (condition-case error-data (url-retrieve url 'newsticker--image-download-by-url-callback (list feed-name directory filename)) - (error (message "Error retrieving image from %s: %s" feed-name - error-data)))) + (error (message "Error retrieving image from %s: %s" feed-name + error-data)))) (force-mode-line-update)) (defun newsticker--image-download-by-url-callback (status feed-name directory filename) @@ -2147,11 +2146,11 @@ FEED is a symbol!" (concat newsticker-dir "/feeds")) (defun newsticker--cache-save () - "Save cache data for all feeds." - (unless (file-directory-p newsticker-dir) - (make-directory newsticker-dir t)) - (mapc 'newsticker--cache-save-feed newsticker--cache) - nil) + "Save cache data for all feeds." + (unless (file-directory-p newsticker-dir) + (make-directory newsticker-dir t)) + (mapc 'newsticker--cache-save-feed newsticker--cache) + nil) (defun newsticker--cache-save-feed (feed) "Save cache data for FEED." @@ -2217,7 +2216,7 @@ If AGES is nil, the total number of items is returned." (if (memq (newsticker--age (car items)) ages) (setq num (1+ num))) (if (memq (newsticker--age (car items)) '(new old immortal obsolete)) - (setq num (1+ num)))) + (setq num (1+ num)))) (setq items (cdr items))) num)) @@ -2240,36 +2239,64 @@ Export subscriptions to a buffer in OPML Format." ;; FIXME: use newsticker-groups (interactive) (with-current-buffer (get-buffer-create "*OPML Export*") + (erase-buffer) (set-buffer-file-coding-system 'utf-8) (insert (concat "\n" "\n" "\n" " \n" - " mySubscriptions\n" + " Emacs newsticker subscriptions\n" " " (format-time-string "%a, %d %b %Y %T %z") "\n" " " user-mail-address "\n" " " (user-full-name) "\n" " \n" " \n")) - (dolist (sub (append newsticker-url-list newsticker-url-list-defaults)) - (insert " \n")) - (insert " \n\n")) + (let ((feeds (append newsticker-url-list newsticker-url-list-defaults)) + ;; insert the feed groups and all feeds that are contained + (saved-feed-names (newsticker--opml-insert-elt newsticker-groups 2))) + ;; to be safe: insert all feeds that are not contained in any group + (dolist (f feeds) + (unless (seq-find (lambda (sfn) (string= (car f) sfn)) saved-feed-names) + (newsticker--opml-insert-feed (car f) 4))) + (insert " \n\n"))) (pop-to-buffer "*OPML Export*") (when (fboundp 'sgml-mode) (sgml-mode))) +(defun newsticker--opml-insert-elt (elt depth) + "Insert an OPML ELT with indentation level DEPTH." + (if (listp elt) + (newsticker--opml-insert-group elt (+ 2 depth)) + (newsticker--opml-insert-feed elt (+ 2 depth)))) + +(defun newsticker--opml-insert-group (group depth) + "Insert an OPML GROUP with indentation level DEPTH." + (let (saved-feeds) + (insert (make-string depth ? ) "\n") + (setq saved-feeds (mapcar (lambda (e) + (newsticker--opml-insert-elt e depth)) + (cdr group))) + (insert (make-string depth ? ) "\n") + (flatten-tree saved-feeds))) + +(defun newsticker--opml-insert-feed (feed-name depth) + "Insert an OPML FEED-NAME with indentation level DEPTH." + (let* ((feed-definition (seq-find (lambda (f) + (string= feed-name (car f))) + (append newsticker-url-list newsticker-url-list-defaults))) + (url (nth 1 feed-definition)) + (url-string (if (functionp url) (prin1-to-string url) + (xml-escape-string url)))) + (insert (make-string depth ? ) "\n")) + feed-name) + (defun newsticker--opml-import-outlines (outlines) - "Recursively import OUTLINES from OPML data. -Note that nested outlines are currently flattened -- i.e. grouping is -removed." - (mapc (lambda (outline) + "Recursively import OUTLINES from OPML data." + (mapcar (lambda (outline) (let ((name (xml-get-attribute outline 'text)) (url (xml-get-attribute outline 'xmlUrl)) (children (xml-get-children outline 'outline))) @@ -2277,18 +2304,27 @@ removed." (add-to-list 'newsticker-url-list (list name url nil nil nil) t)) (if children - (newsticker--opml-import-outlines children)))) - outlines)) + (append (list name) + (newsticker--opml-import-outlines children)) + name))) + outlines)) (defun newsticker-opml-import (filename) - "Import OPML data from FILENAME." + "Import OPML data from FILENAME. +Feeds are added to 'newsticker-url-list and 'newsticker-groups +preserving the outline structure." (interactive "fOPML file: ") (set-buffer (find-file-noselect filename)) (goto-char (point-min)) (let* ((node-list (xml-parse-region (point-min) (point-max))) + (title (car (xml-node-children + (car (xml-get-children + (car (xml-get-children (car node-list) 'head)) + 'title))))) (body (car (xml-get-children (car node-list) 'body))) - (outlines (xml-get-children body 'outline))) - (newsticker--opml-import-outlines outlines)) + (outlines (xml-get-children body 'outline)) + (imported-groups-data (newsticker--opml-import-outlines outlines))) + (add-to-list 'newsticker-groups (cons title imported-groups-data) t)) (customize-variable 'newsticker-url-list)) ;; ====================================================================== commit 6458e16f3381cbd076316d4f228369e31a328cc2 Author: Juri Linkov Date: Wed Mar 3 21:12:13 2021 +0200 New mode outline-cycle-minor-mode with Orgmode-like TAB cycling on headings * lisp/outline.el (outline-mode-cycle-map): New keymap from outline-mode-map. (outline-mode-map): Inherit from outline-mode-cycle-map. (outline-font-lock-keywords): Append keymap and face depending on 'outline-minor-mode-cycle' and 'outline-minor-mode-highlight'. (outline-minor-mode-cycle, outline-minor-mode-highlight): New variables. (outline-minor-mode-highlight-buffer): New function. (outline-minor-mode): Handle 'outline-minor-mode-cycle' and 'outline-minor-mode-highlight'. (outline-cycle-minor-mode, outline-cycle-highlight-minor-mode): New minor modes (bug#45147). * etc/compilation.txt: * etc/grep.txt: Enable outline-cycle-highlight-minor-mode. diff --git a/etc/NEWS b/etc/NEWS index 6babbbf5a7..8ecc6ac519 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -363,6 +363,17 @@ all", "subheadings", and "show all" state. Typing 'S-TAB' anywhere in the buffer cycles the whole buffer between "only top-level headings", "all headings and subheadings", and "show all" states. +*** New minor mode 'outline-cycle-minor-mode'. +It enables 'outline-minor-mode' with keys 'TAB' and 'S-TAB' activated +on headings to cycle heading visibility. Typing 'TAB' on a heading +cycles the current section between "hide all", "subheadings", and +"show all" state. Typing 'S-TAB' on a heading cycles the whole buffer +between "only top-level headings", "all headings and subheadings", and +"show all" states. Another new mode 'outline-cycle-highlight-minor-mode' +additionally puts highlighting on headings with standard outline faces, +this works well only when there are no conflicts with faces used +by major mode. + * Changes in Specialized Modes and Packages in Emacs 28.1 diff --git a/etc/compilation.txt b/etc/compilation.txt index e56d3b6847..05c04649be 100644 --- a/etc/compilation.txt +++ b/etc/compilation.txt @@ -692,3 +692,9 @@ COPYING PERMISSIONS: You should have received a copy of the GNU General Public License along with this program. If not, see . + + +;;; Local Variables: +;;; outline-regexp: "\\*\\_>" +;;; eval: (outline-cycle-highlight-minor-mode) +;;; End: diff --git a/etc/grep.txt b/etc/grep.txt index b5b78459b5..a54ebf8a3b 100644 --- a/etc/grep.txt +++ b/etc/grep.txt @@ -102,6 +102,7 @@ grep -nH -e "xyzxyz" ../info/* ../info/emacs-2 1205 inserts `xyzxyzxyzxyz' in the current buffer. +* Miscellaneous Copyright (C) 2005-2021 Free Software Foundation, Inc. @@ -124,4 +125,5 @@ COPYING PERMISSIONS: ;;; Local Variables: ;;; eval: (let ((inhibit-read-only t) (compilation-filter-start (point-min))) (save-excursion (goto-char (point-max)) (grep-filter) (set-buffer-modified-p nil))) ;;; buffer-read-only: t +;;; eval: (outline-cycle-highlight-minor-mode) ;;; End: diff --git a/lisp/outline.el b/lisp/outline.el index 57909b307b..640c0e06b9 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -175,23 +175,42 @@ in the file it applies to.") outline-mode-menu-bar-map)))))) map)) +(defvar outline-mode-cycle-map + (let ((map (make-sparse-keymap))) + (let ((tab-binding `(menu-item + "" outline-cycle + ;; Only takes effect if point is on a heading. + :filter ,(lambda (cmd) + (when (outline-on-heading-p) cmd))))) + (define-key map [tab] tab-binding) + (define-key map (kbd "TAB") tab-binding) + (define-key map (kbd "") #'outline-cycle-buffer)) + map) + "Keymap used by `outline-mode-map' and `outline-cycle-minor-mode'.") + (defvar outline-mode-map (let ((map (make-sparse-keymap))) + (set-keymap-parent map outline-mode-cycle-map) (define-key map "\C-c" outline-mode-prefix-map) (define-key map [menu-bar] outline-mode-menu-bar-map) - ;; Only takes effect if point is on a heading. - (define-key map (kbd "TAB") - `(menu-item "" outline-cycle - :filter ,(lambda (cmd) - (when (outline-on-heading-p) cmd)))) - (define-key map (kbd "") #'outline-cycle-buffer) map)) (defvar outline-font-lock-keywords '( ;; Highlight headings according to the level. (eval . (list (concat "^\\(?:" outline-regexp "\\).+") - 0 '(outline-font-lock-face) nil t))) + 0 '(if outline-minor-mode-cycle + (if outline-minor-mode-highlight + (list 'face (outline-font-lock-face) + 'keymap outline-mode-cycle-map) + (list 'face nil + 'keymap outline-mode-cycle-map)) + (outline-font-lock-face)) + nil + (if (or outline-minor-mode-cycle + outline-minor-mode-highlight) + 'append + t)))) "Additional expressions to highlight in Outline mode.") (defface outline-1 @@ -305,6 +324,35 @@ After that, changing the prefix key requires manipulating keymaps." (define-key outline-minor-mode-map val outline-mode-prefix-map) (set-default sym val))) +(defvar outline-minor-mode-cycle nil + "Enable cycling of headings in `outline-minor-mode'. +When point is on a heading line, then typing `TAB' cycles between `hide all', +`headings only' and `show all' (`outline-cycle'). Typing `S-TAB' on +a heading line cycles the whole buffer (`outline-cycle-buffer'). +Typing these keys anywhere outside heading lines uses their default bindings.") +;;;###autoload(put 'outline-minor-mode-cycle 'safe-local-variable 'booleanp) + +(defvar outline-minor-mode-highlight nil + "Highlight headings in `outline-minor-mode' using font-lock keywords. +Non-nil value works well only when outline font-lock keywords +don't conflict with the major mode's font-lock keywords.") +;;;###autoload(put 'outline-minor-mode-highlight 'safe-local-variable 'booleanp) + +(defun outline-minor-mode-highlight-buffer () + ;; Fallback to overlays when font-lock is unsupported. + (save-excursion + (goto-char (point-min)) + (let ((regexp (concat "^\\(?:" outline-regexp "\\).*$"))) + (while (re-search-forward regexp nil t) + (let ((overlay (make-overlay (match-beginning 0) + (match-end 0)))) + (overlay-put overlay 'outline-overlay t) + (when outline-minor-mode-highlight + (overlay-put overlay 'face (outline-font-lock-face))) + (when outline-minor-mode-cycle + (overlay-put overlay 'keymap outline-mode-cycle-map))) + (goto-char (match-end 0)))))) + ;;;###autoload (define-minor-mode outline-minor-mode "Toggle Outline minor mode. @@ -314,6 +362,12 @@ See the command `outline-mode' for more information on this mode." (cons outline-minor-mode-prefix outline-mode-prefix-map)) (if outline-minor-mode (progn + (when (or outline-minor-mode-cycle outline-minor-mode-highlight) + (if (and global-font-lock-mode (font-lock-specified-p major-mode)) + (progn + (font-lock-add-keywords nil outline-font-lock-keywords t) + (font-lock-flush)) + (outline-minor-mode-highlight-buffer))) ;; Turn off this mode if we change major modes. (add-hook 'change-major-mode-hook (lambda () (outline-minor-mode -1)) @@ -321,12 +375,43 @@ See the command `outline-mode' for more information on this mode." (setq-local line-move-ignore-invisible t) ;; Cause use of ellipses for invisible text. (add-to-invisibility-spec '(outline . t))) + (when (or outline-minor-mode-cycle outline-minor-mode-highlight) + (if font-lock-fontified + (font-lock-remove-keywords nil outline-font-lock-keywords)) + (remove-overlays nil nil 'outline-overlay t) + (font-lock-flush)) (setq line-move-ignore-invisible nil) ;; Cause use of ellipses for invisible text. (remove-from-invisibility-spec '(outline . t)) ;; When turning off outline mode, get rid of any outline hiding. (outline-show-all))) +;;;###autoload +(define-minor-mode outline-cycle-minor-mode + "Toggle Outline-Cycle minor mode. +Set the buffer-local variable `outline-minor-mode-cycle' to t +and enable `outline-minor-mode'." + nil nil nil + (if outline-cycle-minor-mode + (progn + (setq-local outline-minor-mode-cycle t) + (outline-minor-mode +1)) + (outline-minor-mode -1) + (kill-local-variable 'outline-minor-mode-cycle))) + +;;;###autoload +(define-minor-mode outline-cycle-highlight-minor-mode + "Toggle Outline-Cycle-Highlight minor mode. +Set the buffer-local variable `outline-minor-mode-highlight' to t +and enable `outline-cycle-minor-mode'." + nil nil nil + (if outline-cycle-highlight-minor-mode + (progn + (setq-local outline-minor-mode-highlight t) + (outline-cycle-minor-mode +1)) + (outline-cycle-minor-mode -1) + (kill-local-variable 'outline-minor-mode-highlight))) + (defvar-local outline-heading-alist () "Alist associating a heading for every possible level. Each entry is of the form (HEADING . LEVEL). commit 356636c6a1ebba3e95d0e6609ae0401992008ccf Author: Stefan Kangas Date: Wed Mar 3 19:54:37 2021 +0100 Make inversion.el obsolete (Bug#46841) * lisp/cedet/inversion.el: * test/lisp/cedet/inversion-tests.el: Move from here... * lisp/obsolete/inversion.el: * test/lisp/obsolete/inversion-tests.el: ...to here. * lisp/cedet/cedet.el (cedet-version): Make obsolete. * lisp/cedet/cedet-cscope.el (cedet-cscope-version-check): * lisp/cedet/cedet-global.el (cedet-gnu-global-version-check): * lisp/cedet/cedet-idutils.el (cedet-idutils-version-check): * lisp/cedet/ede/make.el (ede-make-check-version): Use 'version<' instead of 'inversion-check-version'. * lisp/cedet/semantic/db-file.el (semanticdb-load-database): Don't use 'inversion-test'. * lisp/cedet/semantic/ede-grammar.el (ede-proj-makefile-insert-variables): Don't add inversion to loadpath. * lisp/speedbar.el: Remove stale comment. diff --git a/etc/NEWS b/etc/NEWS index 73f136cfa7..6babbbf5a7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2259,7 +2259,10 @@ This is no longer supported, and setting this variable has no effect. Use macro 'with-current-buffer-window' with action alist entry 'body-function'. --- -** The metamail.el library is now marked obsolete. +** The inversion.el library is now obsolete. + +--- +** The metamail.el library is now obsolete. --- ** Some obsolete variable and function aliases in dbus.el have been removed. diff --git a/lisp/cedet/cedet-cscope.el b/lisp/cedet/cedet-cscope.el index 75a69db0a8..4d4a9f78d5 100644 --- a/lisp/cedet/cedet-cscope.el +++ b/lisp/cedet/cedet-cscope.el @@ -26,8 +26,6 @@ ;;; Code: -(declare-function inversion-check-version "inversion") - (defvar cedet-cscope-min-version "15.7" "Minimum version of CScope required.") @@ -139,7 +137,6 @@ If optional programmatic argument NOERROR is non-nil, then instead of throwing an error if CScope isn't available, return nil." (interactive) - (require 'inversion) (let ((b (condition-case nil (cedet-cscope-call (list "-V")) (error nil))) @@ -153,7 +150,7 @@ return nil." (goto-char (point-min)) (re-search-forward "cscope: version \\([0-9.]+\\)" nil t) (setq rev (match-string 1)) - (if (inversion-check-version rev nil cedet-cscope-min-version) + (if (version< rev cedet-cscope-min-version) (if noerror nil (error "Version of CScope is %s. Need at least %s" diff --git a/lisp/cedet/cedet-global.el b/lisp/cedet/cedet-global.el index 5878ec1f48..77b4474439 100644 --- a/lisp/cedet/cedet-global.el +++ b/lisp/cedet/cedet-global.el @@ -24,8 +24,6 @@ ;; ;; Basic support for calling GNU Global, and testing version numbers. -(declare-function inversion-check-version "inversion") - (defvar cedet-global-min-version "5.0" "Minimum version of GNU Global required.") @@ -143,7 +141,6 @@ If optional programmatic argument NOERROR is non-nil, then instead of throwing an error if Global isn't available, return nil." (interactive) - (require 'inversion) (let ((b (condition-case nil (cedet-gnu-global-call (list "--version")) (error nil))) @@ -157,7 +154,7 @@ return nil." (goto-char (point-min)) (re-search-forward "(?GNU GLOBAL)? \\([0-9.]+\\)" nil t) (setq rev (match-string 1)) - (if (inversion-check-version rev nil cedet-global-min-version) + (if (version< rev cedet-global-min-version) (if noerror nil (error "Version of GNU Global is %s. Need at least %s" diff --git a/lisp/cedet/cedet-idutils.el b/lisp/cedet/cedet-idutils.el index fc5e05af88..3e3d6a5e94 100644 --- a/lisp/cedet/cedet-idutils.el +++ b/lisp/cedet/cedet-idutils.el @@ -29,8 +29,6 @@ ;;; Code: -(declare-function inversion-check-version "inversion") - (defvar cedet-idutils-min-version "4.0" "Minimum version of ID Utils required.") @@ -167,7 +165,6 @@ If optional programmatic argument NOERROR is non-nil, then instead of throwing an error if Global isn't available, return nil." (interactive) - (require 'inversion) (let ((b (condition-case nil (cedet-idutils-fnid-call (list "--version")) (error nil))) @@ -182,7 +179,7 @@ return nil." (if (re-search-forward "fnid - \\([0-9.]+\\)" nil t) (setq rev (match-string 1)) (setq rev "0")) - (if (inversion-check-version rev nil cedet-idutils-min-version) + (if (version< rev cedet-idutils-min-version) (if noerror nil (error "Version of ID Utils is %s. Need at least %s" diff --git a/lisp/cedet/cedet.el b/lisp/cedet/cedet.el index caaec473a2..5d98a1939d 100644 --- a/lisp/cedet/cedet.el +++ b/lisp/cedet/cedet.el @@ -85,6 +85,7 @@ for the specified PACKAGE. LOADED VERSION is the version of PACKAGE currently loaded in Emacs memory and (presumably) running in this Emacs instance. Value is X if the package has not been loaded." + (declare (obsolete emacs-version "28.1")) (interactive) (require 'inversion) (with-output-to-temp-buffer "*CEDET*" diff --git a/lisp/cedet/ede/make.el b/lisp/cedet/ede/make.el index 4f86558c62..d9811ce52f 100644 --- a/lisp/cedet/ede/make.el +++ b/lisp/cedet/ede/make.el @@ -30,8 +30,6 @@ ;;; Code: -(declare-function inversion-check-version "inversion") - (defsubst ede--find-executable (exec) "Return an expanded file name for a program EXEC on the exec path." (declare (obsolete locate-file "28.1")) @@ -60,8 +58,7 @@ If NOERROR is nil, then throw an error on failure. Return t otherwise." (let ((b (get-buffer-create "*EDE Make Version*")) (cd default-directory) (rev nil) - (ans nil) - ) + (ans nil)) (with-current-buffer b ;; Setup, and execute make. (setq default-directory cd) @@ -70,18 +67,18 @@ If NOERROR is nil, then throw an error on failure. Return t otherwise." "--version") ;; Check the buffer for the string (goto-char (point-min)) - (when (looking-at "GNU Make\\(?: version\\)? \\([0-9][^,]+\\),") + (when (looking-at "GNU Make\\(?: version\\)? \\([0-9][^,[:space:]]+\\),?") (setq rev (match-string 1)) - (require 'inversion) - (setq ans (not (inversion-check-version rev nil ede-make-min-version)))) + (setq ans (not (version< rev ede-make-min-version)))) ;; Answer reporting. (when (and (called-interactively-p 'interactive) ans) (message "GNU Make version %s. Good enough for CEDET." rev)) (when (and (not noerror) (not ans)) - (error "EDE requires GNU Make version %s or later. Configure `ede-make-command' to fix" - ede-make-min-version)) + (error "EDE requires GNU Make version %s or later (found %s). Configure `ede-make-command' to fix" + ede-make-min-version + rev)) ans))) (provide 'ede/make) diff --git a/lisp/cedet/semantic.el b/lisp/cedet/semantic.el index 44bd4b0cd8..797ff753a6 100644 --- a/lisp/cedet/semantic.el +++ b/lisp/cedet/semantic.el @@ -57,6 +57,7 @@ excluded if a released version is required. It is assumed that if the current version is newer than that specified, everything passes. Exceptions occur when known incompatibilities are introduced." + (declare (obsolete emacs-version "28.1")) (require 'inversion) (inversion-test 'semantic (concat major "." minor diff --git a/lisp/cedet/semantic/db-file.el b/lisp/cedet/semantic/db-file.el index 59e9db9cc0..d99b94f49e 100644 --- a/lisp/cedet/semantic/db-file.el +++ b/lisp/cedet/semantic/db-file.el @@ -154,8 +154,6 @@ If DIRECTORY doesn't exist, create a new one." ;;; File IO -(declare-function inversion-test "inversion") - (defun semanticdb-load-database (filename) "Load the database FILENAME." (condition-case foo @@ -163,32 +161,19 @@ If DIRECTORY doesn't exist, create a new one." 'semanticdb-project-database-file)) (c (semanticdb-get-database-tables r)) (tv (oref r semantic-tag-version)) - (fv (oref r semanticdb-version)) - ) + (fv (oref r semanticdb-version))) ;; Restore the parent-db connection (while c (oset (car c) parent-db r) (setq c (cdr c))) (unless (and (equal semanticdb-file-version fv) (equal semantic-tag-version tv)) - ;; Try not to load inversion unless we need it: - (require 'inversion) - (if (not (inversion-test 'semanticdb-file fv)) - (when (inversion-test 'semantic-tag tv) - ;; Incompatible version. Flush tables. - (semanticdb-flush-database-tables r) - ;; Reset the version to new version. - (oset r semantic-tag-version semantic-tag-version) - ;; Warn user - (message "Semanticdb file is old. Starting over for %s" - filename)) - ;; Version is not ok. Flush whole system - (message "semanticdb file is old. Starting over for %s" - filename) - ;; This database is so old, we need to replace it. - ;; We also need to delete it from the instance tracker. - (delete-instance r) - (setq r nil))) + ;; Version is not ok. Flush whole system + (message "semanticdb file is old. Starting over for %s" filename) + ;; This database is so old, we need to replace it. + ;; We also need to delete it from the instance tracker. + (delete-instance r) + (setq r nil)) r) (error (message "Cache Error: [%s] %s, Restart" filename foo) diff --git a/lisp/cedet/semantic/ede-grammar.el b/lisp/cedet/semantic/ede-grammar.el index bd0795acbd..64fc07fe1b 100644 --- a/lisp/cedet/semantic/ede-grammar.el +++ b/lisp/cedet/semantic/ede-grammar.el @@ -162,10 +162,9 @@ Lays claim to all -by.el, and -wy.el files." "Insert variables needed by target THIS." (ede-proj-makefile-insert-loadpath-items (ede-proj-elisp-packages-to-loadpath - (list "eieio" "semantic" "inversion" "ede"))) + (list "eieio" "semantic" "ede"))) ;; eieio for object system needed in ede ;; semantic because it is - ;; Inversion for versioning system. ;; ede for project regeneration (ede-pmake-insert-variable-shared (concat (ede-pmake-varname this) "_SEMANTIC_GRAMMAR_EL") @@ -174,8 +173,7 @@ Lays claim to all -by.el, and -wy.el files." (with-current-buffer (find-file-noselect src) (concat (semantic-grammar-package) ".el"))) (oref this source) - " "))) - ) + " ")))) (cl-defmethod ede-proj-makefile-insert-rules :after ((this semantic-ede-proj-target-grammar)) "Insert rules needed by THIS target. diff --git a/lisp/cedet/inversion.el b/lisp/obsolete/inversion.el similarity index 95% rename from lisp/cedet/inversion.el rename to lisp/obsolete/inversion.el index 2ef7e0df96..f192d88868 100644 --- a/lisp/cedet/inversion.el +++ b/lisp/obsolete/inversion.el @@ -5,6 +5,7 @@ ;; Author: Eric M. Ludlam ;; Version: 1.3 ;; Keywords: OO, lisp +;; Obsolete-since: 28.1 ;; This file is part of GNU Emacs. @@ -524,31 +525,6 @@ The package should have VERSION available for download." (copy-file (cdr (car files)) dest)))))) -;;; How we upgrade packages in Emacs has yet to be ironed out. - -;; (defun inversion-upgrade-package (package &optional directory) -;; "Try to upgrade PACKAGE in DIRECTORY is available." -;; (interactive "sPackage to upgrade: ") -;; (if (stringp package) (setq package (intern package))) -;; (if (not directory) -;; ;; Hope that the package maintainer specified. -;; (setq directory (symbol-value (or (intern-soft -;; (concat (symbol-name package) -;; "-url")) -;; (intern-soft -;; (concat (symbol-name package) -;; "-directory")))))) -;; (let ((files (inversion-locate-package-files-and-split -;; package directory)) -;; (cver (inversion-package-version package)) -;; (newer nil)) -;; (mapc (lambda (f) -;; (if (inversion-< cver (inversion-decode-version (car f))) -;; (setq newer (cons f newer)))) -;; files) -;; newer -;; )) - (provide 'inversion) ;;; inversion.el ends here diff --git a/lisp/speedbar.el b/lisp/speedbar.el index 0e2a3749be..4a78562380 100644 --- a/lisp/speedbar.el +++ b/lisp/speedbar.el @@ -141,25 +141,6 @@ ;;; Code: -;; Note: `inversion-test' requires parts of the CEDET package that are -;; not included with Emacs. -;; -;; (defun speedbar-require-version (major minor &optional beta) -;; "Non-nil if this version of SPEEDBAR does not satisfy a specific version. -;; Arguments can be: -;; -;; (MAJOR MINOR &optional BETA) -;; -;; Values MAJOR and MINOR must be integers. BETA can be an integer, or -;; excluded if a released version is required. -;; -;; It is assumed that if the current version is newer than that specified, -;; everything passes. Exceptions occur when known incompatibilities are -;; introduced." -;; (inversion-test 'speedbar -;; (concat major "." minor -;; (when beta (concat "beta" beta))))) - (defvar speedbar-initial-expansion-mode-alist '(("buffers" speedbar-buffer-easymenu-definition speedbar-buffers-key-map speedbar-buffer-buttons) diff --git a/test/lisp/cedet/inversion-tests.el b/test/lisp/obsolete/inversion-tests.el similarity index 100% rename from test/lisp/cedet/inversion-tests.el rename to test/lisp/obsolete/inversion-tests.el commit 9ef8a3bfca192777e7cf8b4748d188249a517582 Author: Alan Mackenzie Date: Wed Mar 3 11:55:51 2021 +0000 C++ Mode: Handle "if constexpr (...)" with a simple statement correctly * lisp/progmodes/cc-engine.el (c-beginning-of-statement-1): Add a check and handling for c-block-stmt-hangon-key in the main loop. diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 079985a6bc..5a8b2f4f90 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -1184,6 +1184,15 @@ comment at the start of cc-engine.el for more info." ;; suitable error. (setq pre-stmt-found t) (throw 'loop nil)) + ;; Handle C++'s `constexpr', etc. + (if (save-excursion + (and (looking-at c-block-stmt-hangon-key) + (progn + (c-backward-syntactic-ws lim) + (c-safe (c-backward-sexp) t)) + (looking-at c-block-stmt-2-key) + (setq pos (point)))) + (goto-char pos)) (cond ;; Have we moved into a macro? ((and (not macro-start) commit 3ef6d04dcff86a7e2ed6552c1835b24d5bfc58b7 Author: Stefan Monnier Date: Tue Mar 2 15:57:45 2021 -0500 * lisp/emacs-lisp/pcase.el (pcase--u1): Fix typo diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index c565687896..4804180ac9 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -872,7 +872,7 @@ Otherwise, it defers to REST which is a list of branches of the form (if (not v) (pcase--u1 matches code (cons (list upat sym) vars) rest) ;; Non-linear pattern. Turn it into an `eq' test. - (setq (cddr v) 'used) + (setcdr (cdr v) 'used) (pcase--u1 (cons `(match ,sym . (pred (eql ,(cadr v)))) matches) code vars rest)))) commit 8dd588b1fb51bb9178bf34a6be9f35de84e95045 Author: Alan Mackenzie Date: Tue Mar 2 20:31:36 2021 +0000 CC Mode: Fix analysis of brace lists, particularly in C++ Mode Fix some alignment functionality in cc-align.el. * lisp/progmodes/cc-align.el (c-lineup-arglist-intro-after-paren): Align the next line under the previous entry rather than one to the right of the paren. (c-lineup-2nd-brace-entry-in-arglist): Take the anchor point from the brace-list-entry element, not the brace-list-intro one. * lisp/progmodes/cc-engine.el (c-looking-at-decl-block): Use c-looking-at-statement-block to test whether "struct A {" begins a brace list or a struct declaration. (c-looking-at-or-maybe-in-bracelist): Several detailed amendments, correctly to recognize brace lists. (c-looking-at-statement-block): No longer search for commas, as they are not reliable indicators of a brace list. Search now for a restricted set of keywords, since some can appear in brace lists in C++ mode. * lisp/progmodes/cc-langs.el (c-stmt-block-only-keywords) (c-stmt-block-only-keywords-regexp): New lang consts/vars. (c-pre-id-bracelist-kwds): New lang const. (c-pre-id-bracelist-key): Derive now from the above. (c-pre-brace-non-bracelist-key): New lang const/var. diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el index d14ef1744a..51d51deef7 100644 --- a/lisp/progmodes/cc-align.el +++ b/lisp/progmodes/cc-align.el @@ -274,8 +274,10 @@ statement-block-intro, statement-case-intro, arglist-intro." (save-excursion (beginning-of-line) (backward-up-list 1) + (forward-char) (skip-chars-forward " \t" (c-point 'eol)) - (vector (1+ (current-column))))) + (if (eolp) (skip-chars-backward " \t")) + (vector (current-column)))) (defun c-lineup-arglist-close-under-paren (langelem) "Line up a line under the enclosing open paren. @@ -1145,7 +1147,8 @@ Works with brace-list-intro." ; the line. (save-excursion ; "{" earlier on the line (goto-char (c-langelem-pos - (assq 'brace-list-intro c-syntactic-context))) + (assq 'brace-list-entry + c-syntactic-context))) (and (eq (c-backward-token-2 1 nil diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 4cf7af843b..079985a6bc 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -11410,7 +11410,9 @@ comment at the start of cc-engine.el for more info." ;; also might be part of a declarator expression. Currently ;; there's no such language. (not (or (looking-at c-symbol-start) - (looking-at c-type-decl-prefix-key)))))) + (looking-at c-type-decl-prefix-key) + (and (eq (char-after) ?{) + (not (c-looking-at-statement-block)))))))) ;; In Pike a list of modifiers may be followed by a brace ;; to make them apply to many identifiers. Note that the @@ -11817,15 +11819,17 @@ comment at the start of cc-engine.el for more info." ;; POINT, or nil if there is no such position, or we do not know it. LIM is ;; a backward search limit. ;; - ;; The determination of whether the brace starts a brace list is solely by - ;; the context of the brace, not by its contents. + ;; The determination of whether the brace starts a brace list is mainly by + ;; the context of the brace, not by its contents. In exceptional + ;; circumstances (e.g. "struct A {" in C++ Mode), the contents are examined, + ;; too. ;; ;; Here, "brace list" does not include the body of an enum. (save-excursion (let ((start (point)) (braceassignp 'dontknow) inexpr-brace-list bufpos macro-start res pos after-type-id-pos - in-paren parens-before-brace + pos2 in-paren parens-before-brace paren-state paren-pos) (setq res (c-backward-token-2 1 t lim)) @@ -11841,12 +11845,16 @@ comment at the start of cc-engine.el for more info." (goto-char paren-pos) (setq braceassignp 'c++-noassign in-paren 'in-paren)) - ((looking-at c-pre-id-bracelist-key) + ((looking-at c-pre-brace-non-bracelist-key) (setq braceassignp nil)) ((looking-at c-return-key)) ((and (looking-at c-symbol-start) (not (looking-at c-keywords-regexp))) - (setq after-type-id-pos (point))) + (if (save-excursion + (and (zerop (c-backward-token-2 1 t lim)) + (looking-at c-pre-id-bracelist-key))) + (setq braceassignp 'c++-noassign) + (setq after-type-id-pos (point)))) ((eq (char-after) ?\() (setq parens-before-brace t) nil) @@ -11860,8 +11868,13 @@ comment at the start of cc-engine.el for more info." (eq (char-after paren-pos) ?\() (setq in-paren 'in-paren) (goto-char paren-pos))) - ((looking-at c-pre-id-bracelist-key)) + ((looking-at c-pre-brace-non-bracelist-key)) ((looking-at c-return-key)) + ((and (looking-at c-symbol-start) + (not (looking-at c-keywords-regexp)) + (save-excursion + (and (zerop (c-backward-token-2 1 t lim)) + (looking-at c-pre-id-bracelist-key))))) (t (setq after-type-id-pos (point)) nil)))) (setq braceassignp 'c++-noassign)) @@ -11946,8 +11959,12 @@ comment at the start of cc-engine.el for more info." (cond (braceassignp ;; We've hit the beginning of the aggregate list. - (c-beginning-of-statement-1 containing-sexp) - (cons (point) (or in-paren inexpr-brace-list))) + (setq pos2 (point)) + (cons + (if (eq (c-beginning-of-statement-1 containing-sexp) 'same) + (point) + pos2) + (or in-paren inexpr-brace-list))) ((and after-type-id-pos (save-excursion (when (eq (char-after) ?\;) @@ -11959,34 +11976,36 @@ comment at the start of cc-engine.el for more info." (c-get-char-property (point) 'syntax-table)) (c-go-list-forward nil after-type-id-pos) (c-forward-syntactic-ws))) - (and - (or (not (looking-at c-class-key)) - (save-excursion - (goto-char (match-end 1)) - (c-forward-syntactic-ws) - (not (eq (point) after-type-id-pos)))) - (progn - (setq res - (c-forward-decl-or-cast-1 - (save-excursion (c-backward-syntactic-ws) (point)) - nil nil)) - (and (consp res) - (cond - ((eq (car res) after-type-id-pos)) - ((> (car res) after-type-id-pos) nil) - (t - (catch 'find-decl - (save-excursion - (goto-char (car res)) - (c-do-declarators - (point-max) t nil nil - (lambda (id-start _id-end _tok _not-top _func _init) - (cond - ((> id-start after-type-id-pos) - (throw 'find-decl nil)) - ((eq id-start after-type-id-pos) - (throw 'find-decl t))))) - nil))))))))) + (if (and (not (eq (point) after-type-id-pos)) + (or (not (looking-at c-class-key)) + (save-excursion + (goto-char (match-end 1)) + (c-forward-syntactic-ws) + (not (eq (point) after-type-id-pos))))) + (progn + (setq res + (c-forward-decl-or-cast-1 (c-point 'bosws) + nil nil)) + (and (consp res) + (cond + ((eq (car res) after-type-id-pos)) + ((> (car res) after-type-id-pos) nil) + (t + (catch 'find-decl + (save-excursion + (goto-char (car res)) + (c-do-declarators + (point-max) t nil nil + (lambda (id-start _id-end _tok _not-top _func _init) + (cond + ((> id-start after-type-id-pos) + (throw 'find-decl nil)) + ((eq id-start after-type-id-pos) + (throw 'find-decl t))))) + nil)))))) + (save-excursion + (goto-char start) + (not (c-looking-at-statement-block)))))) (cons bufpos (or in-paren inexpr-brace-list))) ((or (eq (char-after) ?\;) ;; Brace lists can't contain a semicolon, so we're done. @@ -12136,33 +12155,31 @@ comment at the start of cc-engine.el for more info." (defun c-looking-at-statement-block () ;; Point is at an opening brace. If this is a statement block (i.e. the ;; elements in the block are terminated by semicolons, or the block is - ;; empty, or the block contains a keyword) return non-nil. Otherwise, - ;; return nil. + ;; empty, or the block contains a characteristic keyword, or there is a + ;; nested statement block) return non-nil. Otherwise, return nil. (let ((here (point))) (prog1 (if (c-go-list-forward) (let ((there (point))) (backward-char) - (c-syntactic-skip-backward "^;," here t) + (c-syntactic-skip-backward "^;" here t) (cond - ((eq (char-before) ?\;) t) - ((eq (char-before) ?,) nil) - (t ; We're at (1+ here). - (cond - ((progn (c-forward-syntactic-ws) - (eq (point) (1- there)))) - ((c-syntactic-re-search-forward c-keywords-regexp there t)) - ((c-syntactic-re-search-forward "{" there t t) - (backward-char) - (c-looking-at-statement-block)) - (t nil))))) + ((eq (char-before) ?\;)) + ((progn (c-forward-syntactic-ws) + (eq (point) (1- there)))) + ((c-syntactic-re-search-forward + c-stmt-block-only-keywords-regexp there t)) + ((c-syntactic-re-search-forward "{" there t t) + (backward-char) + (c-looking-at-statement-block)) + (t nil))) (forward-char) (cond - ((c-syntactic-re-search-forward "[;,]" nil t t) - (eq (char-before) ?\;)) + ((c-syntactic-re-search-forward ";" nil t t)) ((progn (c-forward-syntactic-ws) (eobp))) - ((c-syntactic-re-search-forward c-keywords-regexp nil t t)) + ((c-syntactic-re-search-forward c-stmt-block-only-keywords-regexp + nil t t)) ((c-syntactic-re-search-forward "{" nil t t) (backward-char) (c-looking-at-statement-block)) diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 07479389c6..fa4e73087e 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -3098,6 +3098,36 @@ Note that Java specific rules are currently applied to tell this from t (c-make-keywords-re t (c-lang-const c-keywords))) (c-lang-defvar c-keywords-regexp (c-lang-const c-keywords-regexp)) +(c-lang-defconst c-stmt-block-only-keywords + "All keywords which unambiguously signify a statement block (as opposed to + a brace list) when occurring inside braces." + t (c--set-difference + (c-lang-const c-keywords) + (append (c-lang-const c-primary-expr-kwds) + (c-lang-const c-constant-kwds) + `(,@(when (c-major-mode-is 'c++-mode) + '("typeid" "dynamic_cast" "static_cast" "const_cast" + "reinterpret_cast" "alignof"))) + (c-lang-const c-type-modifier-prefix-kwds) + (c-lang-const c-overloadable-operators) + (c-lang-const c-template-typename-kwds) + `(,@(when (c-major-mode-is 'c++-mode) + '("reflexpr"))) + `(,@(when (c-major-mode-is '(c-mode c++-mode)) + '("sizeof"))) + (c-lang-const c-pre-lambda-tokens) + (c-lang-const c-block-decls-with-vars) + (c-lang-const c-primitive-type-kwds)) + :test 'string-equal)) + +(c-lang-defconst c-stmt-block-only-keywords-regexp + ;; A regexp matching a keyword in `c-stmt-block-only-keywords'. Such a + ;; match can start and end only at token boundaries. + t (concat "\\(^\\|\\=\\|[^" (c-lang-const c-symbol-chars) "]\\)" + (c-make-keywords-re t (c-lang-const c-stmt-block-only-keywords)))) +(c-lang-defvar c-stmt-block-only-keywords-regexp + (c-lang-const c-stmt-block-only-keywords-regexp)) + (c-lang-defconst c-keyword-member-alist ;; An alist with all the keywords in the cars. The cdr for each ;; keyword is a list of the symbols for the `*-kwds' lists that @@ -3650,13 +3680,25 @@ list." c t) (c-lang-defvar c-recognize-knr-p (c-lang-const c-recognize-knr-p)) +(c-lang-defconst c-pre-id-bracelist-kwds + "Keywords which, preceding an identifier and brace, signify a bracelist. +This is only used in c++-mode." + t nil + c++ '("new" "throw")) + (c-lang-defconst c-pre-id-bracelist-key - "A regexp matching tokens which, preceding an identifier, signify a bracelist. -" - t regexp-unmatchable - c++ "new\\([^[:alnum:]_$]\\|$\\)\\|&&?\\(\\S.\\|$\\)") + ;; A regexp matching keywords which, preceding an identifier and brace, + ;; signify a bracelist. Only used in c++-mode. + t (c-make-keywords-re t (c-lang-const c-pre-id-bracelist-kwds))) (c-lang-defvar c-pre-id-bracelist-key (c-lang-const c-pre-id-bracelist-key)) +(c-lang-defconst c-pre-brace-non-bracelist-key + "A regexp matching tokens which, preceding a brace, make it a non-bracelist." + t regexp-unmatchable + c++ "&&?\\(\\S.\\|$\\)") +(c-lang-defvar c-pre-brace-non-bracelist-key + (c-lang-const c-pre-brace-non-bracelist-key)) + (c-lang-defconst c-recognize-typeless-decls "Non-nil means function declarations without return type should be recognized. That can introduce an ambiguity with parenthesized macro commit aa14398aa14362095f1a42845015b9bab141c7d6 Author: Juri Linkov Date: Tue Mar 2 21:50:49 2021 +0200 * lisp/tab-bar.el: Minor stylistic fixes. (tab-bar-select-tab-modifiers): Use tab-bar--undefine-keys and tab-bar--define-keys instead of turning tab-bar-mode on/off. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index d93ee9c93f..917b5e496b 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -90,8 +90,8 @@ Possible modifier keys are `control', `meta', `shift', `hyper', `super' and (set-default sym val) ;; Reenable the tab-bar with new keybindings (when tab-bar-mode - (tab-bar-mode -1) - (tab-bar-mode 1))) + (tab-bar--undefine-keys) + (tab-bar--define-keys))) :group 'tab-bar :version "27.1") @@ -174,21 +174,22 @@ either 1 or 0 depending on the value of the customizable variable (if (> (length (funcall tab-bar-tabs-function frame)) tab-bar-show) 1 0)))) (defun tab-bar--update-tab-bar-lines (&optional frames) - "Update the `tab-bar-lines' parameter in frames. -Update the tab-bar-lines frame parameter. If the optional -parameter FRAMES is omitted, update only the currently selected -frame. If it is `t', update all frames as well as the default -for new frames. Otherwise FRAMES should be a list of frames to -update." + "Update the `tab-bar-lines' frame parameter in FRAMES. +If the optional parameter FRAMES is omitted, update only +the currently selected frame. If it is `t', update all frames +as well as the default for new frames. Otherwise FRAMES should be +a list of frames to update." (let ((frame-lst (cond ((null frames) (list (selected-frame))) ((eq frames t) (frame-list)) (t frames)))) - ;; Loop over all frames and update default-frame-alist + ;; Loop over all frames and update `tab-bar-lines' (dolist (frame frame-lst) (unless (frame-parameter frame 'tab-bar-lines-keep-state) - (set-frame-parameter frame 'tab-bar-lines (tab-bar--tab-bar-lines-for-frame frame))))) + (set-frame-parameter frame 'tab-bar-lines + (tab-bar--tab-bar-lines-for-frame frame))))) + ;; Update `default-frame-alist' (when (eq frames t) (setq default-frame-alist (cons (cons 'tab-bar-lines (if (and tab-bar-mode (eq tab-bar-show t)) 1 0)) @@ -200,7 +201,7 @@ update." ;; It's defined in C/cus-start, this stops the d-m-m macro defining it again. :variable tab-bar-mode - ;; Recalculate tab-bar-lines for all frames + ;; Recalculate `tab-bar-lines' for all frames (tab-bar--update-tab-bar-lines t) (when tab-bar-mode @@ -665,9 +666,9 @@ on the tab bar instead." (wc-history-forward . ,(gethash (or frame (selected-frame)) tab-bar-history-forward))))) (defun tab-bar--current-tab (&optional tab frame) - ;; `tab` here is an argument meaning 'use tab as template'. This is + ;; `tab' here is an argument meaning "use tab as template". This is ;; necessary when switching tabs, otherwise the destination tab - ;; inherit the current tab's `explicit-name` parameter. + ;; inherits the current tab's `explicit-name' parameter. (let* ((tab (or tab (assq 'current-tab (frame-parameter frame 'tabs)))) (tab-explicit-name (alist-get 'explicit-name tab))) `(current-tab @@ -909,9 +910,8 @@ on the tab bar specifying where to insert a new tab." (defcustom tab-bar-tab-post-open-functions nil "List of functions to call after creating a new tab. -The current tab is supplied as an argument. Any modifications -made to the tab argument will be applied after all functions are -called." +The current tab is supplied as an argument. Any modifications made +to the tab argument will be applied after all functions are called." :type '(repeat function) :group 'tab-bar :version "27.1") @@ -966,7 +966,7 @@ After the tab is created, the hooks in (cl-pushnew to-tab (nthcdr to-index tabs)) (when (eq to-index 0) - ;; pushnew handles the head of tabs but not frame-parameter + ;; `pushnew' handles the head of tabs but not frame-parameter (set-frame-parameter nil 'tabs tabs)) (run-hook-with-args 'tab-bar-tab-post-open-functions @@ -974,8 +974,8 @@ After the tab is created, the hooks in (when tab-bar-show (if (not tab-bar-mode) - ;; Switch on tab-bar-mode, since a tab was created - ;; Note: This also updates tab-bar-lines + ;; Turn on `tab-bar-mode' since a tab was created. + ;; Note: this also updates `tab-bar-lines'. (tab-bar-mode 1) (tab-bar--update-tab-bar-lines))) @@ -1026,10 +1026,10 @@ If `recent', select the most recently visited tab." "Defines what to do when the last tab is closed. If nil, do nothing and show a message, like closing the last window or frame. If `delete-frame', delete the containing frame, as a web browser would do. -If `tab-bar-mode-disable', disable tab-bar-mode so that tabs no longer show in -the frame. -If the value is a function, call that function with the tab to be closed as an - argument." +If `tab-bar-mode-disable', disable tab-bar-mode so that tabs no longer show +in the frame. +If the value is a function, call that function with the tab to be closed +as an argument." :type '(choice (const :tag "Do nothing and show message" nil) (const :tag "Close the containing frame" delete-frame) (const :tag "Disable tab-bar-mode" tab-bar-mode-disable) @@ -1040,7 +1040,7 @@ If the value is a function, call that function with the tab to be closed as an (defcustom tab-bar-tab-prevent-close-functions nil "List of functions to call to determine whether to close a tab. The tab to be closed and a boolean indicating whether or not it -is the only tab in the frame are supplied as arguments. If any +is the only tab in the frame are supplied as arguments. If any function returns a non-nil value, the tab will not be closed." :type '(repeat function) :group 'tab-bar @@ -1124,7 +1124,7 @@ for the last tab on a frame is determined by tab-bar-closed-tabs) (set-frame-parameter nil 'tabs (delq close-tab tabs))) - ;; Recalculate tab-bar-lines and update frames + ;; Recalculate `tab-bar-lines' and update frames (tab-bar--update-tab-bar-lines) (force-mode-line-update) @@ -1151,8 +1151,8 @@ for the last tab on a frame is determined by (run-hook-with-args-until-success 'tab-bar-tab-prevent-close-functions (nth index tabs) - ; last-tab-p logically can't ever be true if we - ; make it this far + ;; `last-tab-p' logically can't ever be true + ;; if we make it this far nil)) (push `((frame . ,(selected-frame)) (index . ,index) @@ -1723,7 +1723,6 @@ Like \\[find-file-other-frame] (which see), but creates a new tab." (defun find-file-read-only-other-tab (filename &optional wildcards) "Edit file FILENAME, in another tab, but don't allow changes. Like \\[find-file-other-frame] (which see), but creates a new tab. - Like \\[find-file-other-tab], but marks buffer as read-only. Use \\[read-only-mode] to permit editing." (interactive commit 20596a5ca29e879ca81a9209cd57a85a4ae690f2 Author: Stefan Monnier Date: Tue Mar 2 09:13:57 2021 -0500 * lisp/emacs-lisp/trace.el (trace-values): Work outside of traced function diff --git a/lisp/emacs-lisp/trace.el b/lisp/emacs-lisp/trace.el index fa07d62248..9354687b08 100644 --- a/lisp/emacs-lisp/trace.el +++ b/lisp/emacs-lisp/trace.el @@ -161,7 +161,7 @@ "Helper function to get internal values. You can call this function to add internal values in the trace buffer." (unless inhibit-trace - (with-current-buffer trace-buffer + (with-current-buffer (get-buffer-create trace-buffer) (goto-char (point-max)) (insert (trace-entry-message @@ -174,7 +174,7 @@ and CONTEXT is a string describing the dynamic context (e.g. values of some global variables)." (let ((print-circle t)) (format "%s%s%d -> %S%s\n" - (mapconcat 'char-to-string (make-string (1- level) ?|) " ") + (mapconcat 'char-to-string (make-string (max 0 (1- level)) ?|) " ") (if (> level 1) " " "") level ;; FIXME: Make it so we can click the function name to jump to its commit ed2b23ecc10925b5b29ab13949a5d154c7d0cbe6 Author: Lars Ingebrigtsen Date: Tue Mar 2 08:07:59 2021 +0100 Improve the 'dired-do-kill-lines' doc string * lisp/dired-aux.el (dired-do-kill-lines): Document the FMT parameter (bug#46867). (cherry picked from commit b9cb3b904008a80c69ab433f4851377967b100db) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index cef4de1f1c..6c7908118a 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -954,8 +954,13 @@ Dired buffer as a subdirectory, then it deletes that subdirectory from the buffer as well. To kill an entire subdirectory \(without killing its line in the parent directory), go to its directory header line and use this -command with a prefix argument (the value does not matter)." - ;; Returns count of killed lines. FMT="" suppresses message. +command with a prefix argument (the value does not matter). + +This function returns the number of killed lines. + +FMT is a format string used for messaging the user about the +killed lines, and defaults to \"Killed %d line%s.\" if not +present. A FMT of \"\" will suppress the messaging." (interactive "P") (if arg (if (dired-get-subdir) commit 6dee194535b4841714a33bb888bb94da6e1e9b1c Author: Dmitry Gutov Date: Tue Mar 2 15:16:34 2021 +0200 (ruby-find-library-file): Also recognize 'gem' statements * lisp/progmodes/ruby-mode.el (ruby-find-library-file): Also recognize 'gem' statements. diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index e7f407b636..3f8afd9705 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -1802,12 +1802,12 @@ FEATURE-NAME is a relative file name, file extension is optional. This commands delegates to `gem which', which searches both installed gems and the standard library. When called interactively, defaults to the feature name in the `require' -statement around point." +or `gem' statement around point." (interactive) (unless feature-name (let ((init (save-excursion (forward-line 0) - (when (looking-at "require [\"']\\(.*\\)[\"']") + (when (looking-at "\\(?:require\\| *gem\\) [\"']\\(.*?\\)[\"']") (match-string 1))))) (setq feature-name (read-string "Feature name: " init)))) (let ((out commit 2b069c67d7410703898dfab8b337359322fcf123 Author: Pip Cet Date: Sun Feb 28 19:43:09 2021 +0000 Compile closures that modify their bound vars correctly (Bug#46834) * lisp/emacs-lisp/bytecomp.el (byte-compile--reify-function): Don't move let bindings into the lambda. Don't reverse list of bindings. (byte-compile): Evaluate the return value if it was previously reified. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-reify-function): Add tests. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index a2fe37a1ee..4e00fe6121 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2785,16 +2785,12 @@ FUN should be either a `lambda' value or a `closure' value." (dolist (binding env) (cond ((consp binding) - ;; We check shadowing by the args, so that the `let' can be moved - ;; within the lambda, which can then be unfolded. FIXME: Some of those - ;; bindings might be unused in `body'. - (unless (memq (car binding) args) ;Shadowed. - (push `(,(car binding) ',(cdr binding)) renv))) + (push `(,(car binding) ',(cdr binding)) renv)) ((eq binding t)) (t (push `(defvar ,binding) body)))) (if (null renv) `(lambda ,args ,@preamble ,@body) - `(lambda ,args ,@preamble (let ,(nreverse renv) ,@body))))) + `(let ,renv (lambda ,args ,@preamble ,@body))))) ;;;###autoload (defun byte-compile (form) @@ -2819,23 +2815,27 @@ If FORM is a lambda or a macro, byte-compile it as a function." (if (symbolp form) form "provided")) fun) (t - (when (or (symbolp form) (eq (car-safe fun) 'closure)) - ;; `fun' is a function *value*, so try to recover its corresponding - ;; source code. - (setq lexical-binding (eq (car fun) 'closure)) - (setq fun (byte-compile--reify-function fun))) - ;; Expand macros. - (setq fun (byte-compile-preprocess fun)) - (setq fun (byte-compile-top-level fun nil 'eval)) - (if (symbolp form) - ;; byte-compile-top-level returns an *expression* equivalent to the - ;; `fun' expression, so we need to evaluate it, tho normally - ;; this is not needed because the expression is just a constant - ;; byte-code object, which is self-evaluating. - (setq fun (eval fun t))) - (if macro (push 'macro fun)) - (if (symbolp form) (fset form fun)) - fun)))))) + (let (final-eval) + (when (or (symbolp form) (eq (car-safe fun) 'closure)) + ;; `fun' is a function *value*, so try to recover its corresponding + ;; source code. + (setq lexical-binding (eq (car fun) 'closure)) + (setq fun (byte-compile--reify-function fun)) + (setq final-eval t)) + ;; Expand macros. + (setq fun (byte-compile-preprocess fun)) + (setq fun (byte-compile-top-level fun nil 'eval)) + (if (symbolp form) + ;; byte-compile-top-level returns an *expression* equivalent to the + ;; `fun' expression, so we need to evaluate it, tho normally + ;; this is not needed because the expression is just a constant + ;; byte-code object, which is self-evaluating. + (setq fun (eval fun t))) + (if final-eval + (setq fun (eval fun t))) + (if macro (push 'macro fun)) + (if (symbolp form) (fset form fun)) + fun))))))) (defun byte-compile-sexp (sexp) "Compile and return SEXP." diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el index fb84596ad3..03c267ccd0 100644 --- a/test/lisp/emacs-lisp/bytecomp-tests.el +++ b/test/lisp/emacs-lisp/bytecomp-tests.el @@ -1199,6 +1199,29 @@ interpreted and compiled." (should (equal (funcall (eval fun t)) '(c d))) (should (equal (funcall (byte-compile fun)) '(c d)))))) +(ert-deftest bytecomp-reify-function () + "Check that closures that modify their bound variables are +compiled correctly." + (cl-letf ((lexical-binding t) + ((symbol-function 'counter) nil)) + (let ((x 0)) + (defun counter () (cl-incf x)) + (should (equal (counter) 1)) + (should (equal (counter) 2)) + ;; byte compiling should not cause counter to always return the + ;; same value (bug#46834) + (byte-compile 'counter) + (should (equal (counter) 3)) + (should (equal (counter) 4))) + (let ((x 0)) + (let ((x 1)) + (defun counter () x) + (should (equal (counter) 1)) + ;; byte compiling should not cause the outer binding to shadow + ;; the inner one (bug#46834) + (byte-compile 'counter) + (should (equal (counter) 1)))))) + ;; Local Variables: ;; no-byte-compile: t ;; End: commit b9cb3b904008a80c69ab433f4851377967b100db Author: Lars Ingebrigtsen Date: Tue Mar 2 08:07:59 2021 +0100 Improve the dired-do-kill-lines doc string * lisp/dired-aux.el (dired-do-kill-lines): Document the FMT parameter (bug#46867). diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index a94bdf5b42..d5f4910876 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -1072,8 +1072,13 @@ To kill an entire subdirectory \(without killing its line in the parent directory), go to its directory header line and use this command with a prefix argument (the value does not matter). -To undo the killing, the undo command can be used as normally." - ;; Returns count of killed lines. FMT="" suppresses message. +To undo the killing, the undo command can be used as normally. + +This function returns the number of killed lines. + +FMT is a format string used for messaging the user about the +killed lines, and defaults to \"Killed %d line%s.\" if not +present. A FMT of \"\" will suppress the messaging." (interactive "P") (if arg (if (dired-get-subdir) commit 165353674e5fe7109ba9cbf526de0333902b7851 Author: Stefan Monnier Date: Mon Mar 1 23:57:34 2021 -0500 * lisp/emacs-lisp/pcase.el: Bind all the vars in `or` patterns Improve the handling of `or` patterns where not all sub-patterns bind the same set of variables. This used to be "unsupported" and behaved in somewhat unpredictable ways. (pcase--expand): Rewrite. (pcase-codegen): Delete. * doc/lispref/control.texi (pcase Macro): Adjust accordingly. Also remove the warning about "at least two" sub patterns. These work fine, AFAICT, and if not we should fix it. * test/lisp/emacs-lisp/pcase-tests.el (pcase-tests-or-vars): New test. diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 80e9eb7dd8..3388102f69 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -617,17 +617,13 @@ match, @code{and} matches. @item (or @var{pattern1} @var{pattern2}@dots{}) Attempts to match @var{pattern1}, @var{pattern2}, @dots{}, in order, until one of them succeeds. In that case, @code{or} likewise matches, -and the rest of the sub-patterns are not tested. (Note that there -must be at least two sub-patterns. -Simply @w{@code{(or @var{pattern1})}} signals error.) -@c Issue: Is this correct and intended? -@c Are there exceptions, qualifications? -@c (Btw, ``Please avoid it'' is a poor error message.) +and the rest of the sub-patterns are not tested. To present a consistent environment (@pxref{Intro Eval}) to @var{body-forms} (thus avoiding an evaluation error on match), -if any of the sub-patterns let-binds a set of symbols, -they @emph{must} all bind the same set of symbols. +the set of variables bound by the pattern is the union of the +variables bound by each sub-pattern. If a variable is not bound by +the sub-pattern that matched, then it is bound to @code{nil}. @ifnottex @anchor{rx in pcase} diff --git a/etc/NEWS b/etc/NEWS index d01b532193..73f136cfa7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -387,6 +387,11 @@ in text mode. The cursor still only actually blinks in GUI frames. *** New macro 'bindat-spec' to define specs, with Edebug support ** pcase ++++ +*** The 'or' pattern now binds the union of the vars of its sub-patterns +If a variable is not bound by the subpattern that matched, it gets bound +to nil. This was already sometimes the case, but it is now guaranteed. + +++ *** The 'pred' pattern can now take the form '(pred (not FUN))'. This is like '(pred (lambda (x) (not (FUN x))))' but results diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 0fa1b980a0..c565687896 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -326,69 +326,76 @@ of the elements of LIST is performed as if by `pcase-let'. (macroexp-let2 macroexp-copyable-p val exp (let* ((defs ()) (seen '()) - (codegen - (lambda (code vars) - (let ((prev (assq code seen))) - (if (not prev) - (let ((res (pcase-codegen code vars))) - (push (list code vars res) seen) - res) - ;; Since we use a tree-based pattern matching - ;; technique, the leaves (the places that contain the - ;; code to run once a pattern is matched) can get - ;; copied a very large number of times, so to avoid - ;; code explosion, we need to keep track of how many - ;; times we've used each leaf and move it - ;; to a separate function if that number is too high. - ;; - ;; We've already used this branch. So it is shared. - (let* ((code (car prev)) (cdrprev (cdr prev)) - (prevvars (car cdrprev)) (cddrprev (cdr cdrprev)) - (res (car cddrprev))) - (unless (symbolp res) - ;; This is the first repeat, so we have to move - ;; the branch to a separate function. - (let ((bsym - (make-symbol (format "pcase-%d" (length defs))))) - (push `(,bsym (lambda ,(mapcar #'car prevvars) ,@code)) - defs) - (setcar res 'funcall) - (setcdr res (cons bsym (mapcar #'cadr prevvars))) - (setcar (cddr prev) bsym) - (setq res bsym))) - (setq vars (copy-sequence vars)) - (let ((args (mapcar (lambda (pa) - (let ((v (assq (car pa) vars))) - (setq vars (delq v vars)) - (cadr v))) - prevvars))) - ;; If some of `vars' were not found in `prevvars', that's - ;; OK it just means those vars aren't present in all - ;; branches, so they can be used within the pattern - ;; (e.g. by a `guard/let/pred') but not in the branch. - ;; FIXME: But if some of `prevvars' are not in `vars' we - ;; should remove them from `prevvars'! - `(funcall ,res ,@args))))))) - (used-cases ()) (main (pcase--u - (mapcar (lambda (case) - `(,(pcase--match val (pcase--macroexpand (car case))) - ,(lambda (vars) - (unless (memq case used-cases) - ;; Keep track of the cases that are used. - (push case used-cases)) - (funcall - (if (pcase--small-branch-p (cdr case)) - ;; Don't bother sharing multiple - ;; occurrences of this leaf since it's small. - #'pcase-codegen - codegen) - (cdr case) - vars)))) - cases)))) + (mapcar + (lambda (case) + `(,(pcase--match val (pcase--macroexpand (car case))) + ,(lambda (vars) + (let ((prev (assq case seen)) + (code (cdr case))) + (unless prev + ;; Keep track of the cases that are used. + (push (setq prev (list case)) seen)) + (if (member code '(nil (nil))) nil + ;; Put `code' in the cdr just so that not all + ;; branches look identical (to avoid things like + ;; `macroexp--if' optimizing them too optimistically). + (let ((ph (list 'pcase--placeholder code))) + (setcdr prev (cons (cons vars ph) (cdr prev))) + ph)))))) + cases)))) + ;; Take care of the place holders now. + (dolist (branch seen) + (let ((code (cdar branch)) + (uses (cdr branch))) + ;; Find all the vars that are in scope (the union of the + ;; vars provided in each use case). + (let* ((allvarinfo '()) + (_ (dolist (use uses) + (dolist (v (car use)) + (let ((vi (assq (car v) allvarinfo))) + (if vi + (if (cddr v) (setcdr vi 'used)) + (push (cons (car v) (cddr v)) allvarinfo)))))) + (allvars (mapcar #'car allvarinfo)) + (ignores (mapcar (lambda (vi) (when (cdr vi) `(ignore ,(car vi)))) + allvarinfo))) + ;; Since we use a tree-based pattern matching + ;; technique, the leaves (the places that contain the + ;; code to run once a pattern is matched) can get + ;; copied a very large number of times, so to avoid + ;; code explosion, we need to keep track of how many + ;; times we've used each leaf and move it + ;; to a separate function if that number is too high. + (if (or (null (cdr uses)) (pcase--small-branch-p code)) + (dolist (use uses) + (let ((vars (car use)) + (placeholder (cdr use))) + ;; (cl-assert (eq (car placeholder) 'pcase--placeholder)) + (setcar placeholder 'let) + (setcdr placeholder + `(,(mapcar (lambda (v) (list v (cadr (assq v vars)))) + allvars) + ;; Try and silence some of the most common + ;; spurious "unused var" warnings. + ,@ignores + ,@code)))) + ;; Several occurrence of this non-small branch in the output. + (let ((bsym + (make-symbol (format "pcase-%d" (length defs))))) + (push `(,bsym (lambda ,allvars ,@ignores ,@code)) defs) + (dolist (use uses) + (let ((vars (car use)) + (placeholder (cdr use))) + ;; (cl-assert (eq (car placeholder) 'pcase--placeholder)) + (setcar placeholder 'funcall) + (setcdr placeholder + `(,bsym + ,@(mapcar (lambda (v) (cadr (assq v vars))) + allvars)))))))))) (dolist (case cases) - (unless (or (memq case used-cases) + (unless (or (assq case seen) (memq (car case) pcase--dontwarn-upats)) (message "pcase pattern %S shadowed by previous pcase pattern" (car case)))) @@ -445,20 +452,6 @@ for the result of evaluating EXP (first arg to `pcase'). (t `(match ,val . ,upat)))) -(defun pcase-codegen (code vars) - ;; Don't use let*, otherwise macroexp-let* may merge it with some surrounding - ;; let* which might prevent the setcar/setcdr in pcase--expand's fancy - ;; codegen from later metamorphosing this let into a funcall. - (if (null vars) - `(progn ,@code) - `(let ,(mapcar (lambda (b) (list (car b) (cadr b))) vars) - ;; Try and silence some of the most common spurious "unused - ;; var" warnings. - ,@(delq nil (mapcar (lambda (var) - (if (cddr var) `(ignore ,(car var)))) - vars)) - ,@code))) - (defun pcase--small-branch-p (code) (and (= 1 (length code)) (or (not (consp (car code))) diff --git a/test/lisp/emacs-lisp/pcase-tests.el b/test/lisp/emacs-lisp/pcase-tests.el index 6ddeb7b622..2120139ec1 100644 --- a/test/lisp/emacs-lisp/pcase-tests.el +++ b/test/lisp/emacs-lisp/pcase-tests.el @@ -85,13 +85,19 @@ (ert-deftest pcase-tests-bug46786 () (let ((self 'outer)) + (ignore self) (should (equal (cl-macrolet ((show-self () `(list 'self self))) - (pcase-let ((`(,self ,self2) '(inner "2"))) + (pcase-let ((`(,self ,_self2) '(inner "2"))) (show-self))) '(self inner))))) -;; Local Variables: -;; no-byte-compile: t -;; End: +(ert-deftest pcase-tests-or-vars () + (let ((f (lambda (v) + (pcase v + ((or (and 'b1 (let x1 4) (let x2 5)) + (and 'b2 (let y1 8) (let y2 9))) + (list x1 x2 y1 y2)))))) + (should (equal (funcall f 'b1) '(4 5 nil nil))) + (should (equal (funcall f 'b2) '(nil nil 8 9))))) ;;; pcase-tests.el ends here. commit bac0089fb8b15b71bd4bde00f6fd8e1c4b9fbd1d Author: Lars Ingebrigtsen Date: Mon Mar 1 22:41:42 2021 +0100 Fix previous completion-pcm--optimize-pattern fix * lisp/minibuffer.el (completion-pcm--optimize-pattern): Re-fix previous change. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index cd81f0f728..55825e32fc 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -3162,7 +3162,7 @@ or a symbol, see `completion-pcm--merge-completions'." (let ((n '())) (while p (pcase p - (`(,(or 'any 'any-delim) ,(or 'any 'point)) + (`(,(or 'any 'any-delim) ,(or 'any 'point) . ,_) (setq p (cdr p))) ;; This is not just a performance improvement: it turns a ;; terminating `point' into an implicit `any', which affects commit 7b62cda96e69c34cf51f300c02a08f5ea2bbb486 Author: Lars Ingebrigtsen Date: Mon Mar 1 22:38:17 2021 +0100 Fix warning in completion-pcm--optimize-pattern * lisp/minibuffer.el (completion-pcm--optimize-pattern): Remove unused variable. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index aacb8ab00b..cd81f0f728 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -3162,7 +3162,7 @@ or a symbol, see `completion-pcm--merge-completions'." (let ((n '())) (while p (pcase p - (`(,(or 'any 'any-delim) ,(or 'any 'point) . ,rest) + (`(,(or 'any 'any-delim) ,(or 'any 'point)) (setq p (cdr p))) ;; This is not just a performance improvement: it turns a ;; terminating `point' into an implicit `any', which affects diff --git a/test/lisp/minibuffer-tests.el b/test/lisp/minibuffer-tests.el index 7349b191ca..791e51cdcd 100644 --- a/test/lisp/minibuffer-tests.el +++ b/test/lisp/minibuffer-tests.el @@ -125,5 +125,11 @@ '(("completion1" "prefix1" #("suffix1" 0 7 (face shadow))))) (should (equal (get-text-property 19 'face) 'shadow)))) +(ert-deftest completion-pcm--optimize-pattern () + (should (equal (completion-pcm--optimize-pattern '("buf" point "f")) + '("buf" point "f"))) + (should (equal (completion-pcm--optimize-pattern '(any "" any)) + '(any)))) + (provide 'minibuffer-tests) ;;; minibuffer-tests.el ends here commit e5392d38ac27c4cf1674997ab38a453877e65109 Author: Lars Ingebrigtsen Date: Mon Mar 1 22:12:43 2021 +0100 Make easymenu downcase the menu symbol for greater backwards compat * lisp/cmuscheme.el (map): Revert previous fix. * lisp/woman.el (woman-dired-define-keys): Ditto. * lisp/emacs-lisp/easymenu.el (easy-menu-do-define): Downcase the menu name for greater backwards compatibility. diff --git a/lisp/cmuscheme.el b/lisp/cmuscheme.el index f41f2bf702..772891d5d3 100644 --- a/lisp/cmuscheme.el +++ b/lisp/cmuscheme.el @@ -132,7 +132,7 @@ (define-key scheme-mode-map "\C-c\C-l" 'scheme-load-file) (define-key scheme-mode-map "\C-c\C-k" 'scheme-compile-file) ;k for "kompile" -(let ((map (lookup-key scheme-mode-map [menu-bar Scheme]))) +(let ((map (lookup-key scheme-mode-map [menu-bar scheme]))) (define-key map [separator-eval] '("--")) (define-key map [compile-file] '("Compile Scheme File" . scheme-compile-file)) diff --git a/lisp/emacs-lisp/easymenu.el b/lisp/emacs-lisp/easymenu.el index faa69241f9..d3c3d5e65f 100644 --- a/lisp/emacs-lisp/easymenu.el +++ b/lisp/emacs-lisp/easymenu.el @@ -190,7 +190,11 @@ This is expected to be bound to a mouse event." (function-put symbol 'completion-predicate #'ignore)) (dolist (map (if (keymapp maps) (list maps) maps)) (define-key map - (vector 'menu-bar (easy-menu-intern (car menu))) + (vector 'menu-bar (if (symbolp (car menu)) + (car menu) + ;; If a string, then use the downcased + ;; version for greater backwards compatibiltiy. + (intern (downcase (car menu))))) (easy-menu-binding keymap (car menu)))))) (defun easy-menu-filter-return (menu &optional name) diff --git a/lisp/woman.el b/lisp/woman.el index 0a9f3665eb..d4f7e8c0db 100644 --- a/lisp/woman.el +++ b/lisp/woman.el @@ -1523,7 +1523,7 @@ Also make each path-info component into a list. (mapc 'woman-dired-define-key woman-dired-keys) (woman-dired-define-key-maybe "w") (woman-dired-define-key-maybe "W"))) - (define-key-after (lookup-key dired-mode-map [menu-bar Immediate]) + (define-key-after (lookup-key dired-mode-map [menu-bar immediate]) [woman] '("Read Man Page (WoMan)" . woman-dired-find-file) 'view)) (if (featurep 'dired) commit 0d827c7f52b92aaffe751cf937427938f1ac67de Author: Stefan Monnier Date: Mon Mar 1 15:35:51 2021 -0500 * lisp/emacs-lisp/pcase.el: Fix bug#46786 Revert commit a218c9861573b5ec4979ff2662f5c0343397e3ff, but in order to avoid the spurious warnings that this commit tried to squash, keep track of the vars used during the match so as to add corresponding annotations to explicitly silence the spurious warnings. To do this, we change the VARS used in `pcase-u` (and throughout the pcase code): they used to hold elements of the form (NAME . VAL) and now they hold elements of the form (NAME VAL . USED). (pcase--expand): Bind all vars instead of only those found via fgrep. (pcase-codegen): Silence "unused var" warnings for those vars that have already been referenced during the match itself. (pcase--funcall, pcase--eval): Record the vars that are used. (pcase--u1): Record the vars that are used via non-linear patterns. * lisp/textmodes/mhtml-mode.el (mhtml-forward): * lisp/vc/diff-mode.el (diff-goto-source): Silence newly discovered warnings. * test/lisp/emacs-lisp/pcase-tests.el (pcase-tests-bug46786): New test. diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index b1e1305edf..0fa1b980a0 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -328,8 +328,7 @@ of the elements of LIST is performed as if by `pcase-let'. (seen '()) (codegen (lambda (code vars) - (let ((vars (macroexp--fgrep vars code)) - (prev (assq code seen))) + (let ((prev (assq code seen))) (if (not prev) (let ((res (pcase-codegen code vars))) (push (list code vars res) seen) @@ -354,14 +353,14 @@ of the elements of LIST is performed as if by `pcase-let'. (push `(,bsym (lambda ,(mapcar #'car prevvars) ,@code)) defs) (setcar res 'funcall) - (setcdr res (cons bsym (mapcar #'cdr prevvars))) + (setcdr res (cons bsym (mapcar #'cadr prevvars))) (setcar (cddr prev) bsym) (setq res bsym))) (setq vars (copy-sequence vars)) (let ((args (mapcar (lambda (pa) (let ((v (assq (car pa) vars))) (setq vars (delq v vars)) - (cdr v))) + (cadr v))) prevvars))) ;; If some of `vars' were not found in `prevvars', that's ;; OK it just means those vars aren't present in all @@ -383,9 +382,7 @@ of the elements of LIST is performed as if by `pcase-let'. (if (pcase--small-branch-p (cdr case)) ;; Don't bother sharing multiple ;; occurrences of this leaf since it's small. - (lambda (code vars) - (pcase-codegen code - (macroexp--fgrep vars code))) + #'pcase-codegen codegen) (cdr case) vars)))) @@ -452,10 +449,15 @@ for the result of evaluating EXP (first arg to `pcase'). ;; Don't use let*, otherwise macroexp-let* may merge it with some surrounding ;; let* which might prevent the setcar/setcdr in pcase--expand's fancy ;; codegen from later metamorphosing this let into a funcall. - (if vars - `(let ,(mapcar (lambda (b) (list (car b) (cdr b))) vars) - ,@code) - `(progn ,@code))) + (if (null vars) + `(progn ,@code) + `(let ,(mapcar (lambda (b) (list (car b) (cadr b))) vars) + ;; Try and silence some of the most common spurious "unused + ;; var" warnings. + ,@(delq nil (mapcar (lambda (var) + (if (cddr var) `(ignore ,(car var)))) + vars)) + ,@code))) (defun pcase--small-branch-p (code) (and (= 1 (length code)) @@ -497,11 +499,14 @@ for the result of evaluating EXP (first arg to `pcase'). "Expand matcher for rules BRANCHES. Each BRANCH has the form (MATCH CODE . VARS) where CODE is the code generator for that branch. -VARS is the set of vars already bound by earlier matches. MATCH is the pattern that needs to be matched, of the form: (match VAR . PAT) (and MATCH ...) - (or MATCH ...)" + (or MATCH ...) +VARS is the set of vars already bound by earlier matches. +It is a list of (NAME VAL . USED) where NAME is the variable's symbol, +VAL is the expression to which it should be bound and USED is a boolean +recording whether the var has been referenced by earlier parts of the match." (when (setq branches (delq nil branches)) (let* ((carbranch (car branches)) (match (car carbranch)) (cdarbranch (cdr carbranch)) @@ -748,8 +753,11 @@ A and B can be one of: ((symbolp fun) `(,fun ,arg)) ((eq 'not (car-safe fun)) `(not ,(pcase--funcall (cadr fun) arg vars))) (t - (let* (;; `env' is an upper bound on the bindings we need. - (env (mapcar (lambda (x) (list (car x) (cdr x))) + (let* (;; `env' is hopefully an upper bound on the bindings we need, + ;; FIXME: See bug#46786 for a counter example :-( + (env (mapcar (lambda (x) + (setcdr (cdr x) 'used) + (list (car x) (cadr x))) (macroexp--fgrep vars fun))) (call (progn (when (assq arg env) @@ -757,7 +765,7 @@ A and B can be one of: (let ((newsym (gensym "x"))) (push (list newsym arg) env) (setq arg newsym))) - (if (functionp fun) + (if (or (functionp fun) (not (consp fun))) `(funcall #',fun ,arg) `(,@fun ,arg))))) (if (null env) @@ -770,10 +778,12 @@ A and B can be one of: (defun pcase--eval (exp vars) "Build an expression that will evaluate EXP." (let* ((found (assq exp vars))) - (if found (cdr found) + (if found (progn (setcdr (cdr found) 'used) (cadr found)) (let* ((env (macroexp--fgrep vars exp))) (if env - (macroexp-let* (mapcar (lambda (x) (list (car x) (cdr x))) + (macroexp-let* (mapcar (lambda (x) + (setcdr (cdr x) 'used) + (list (car x) (cadr x))) env) exp) exp))))) @@ -865,12 +875,14 @@ Otherwise, it defers to REST which is a list of branches of the form (pcase--u else-rest)))) ((and (symbolp upat) upat) (pcase--mark-used sym) - (if (not (assq upat vars)) - (pcase--u1 matches code (cons (cons upat sym) vars) rest) - ;; Non-linear pattern. Turn it into an `eq' test. - (pcase--u1 (cons `(match ,sym . (pred (eql ,(cdr (assq upat vars))))) - matches) - code vars rest))) + (let ((v (assq upat vars))) + (if (not v) + (pcase--u1 matches code (cons (list upat sym) vars) rest) + ;; Non-linear pattern. Turn it into an `eq' test. + (setq (cddr v) 'used) + (pcase--u1 (cons `(match ,sym . (pred (eql ,(cadr v)))) + matches) + code vars rest)))) ((eq (car-safe upat) 'app) ;; A upat of the form (app FUN PAT) (pcase--mark-used sym) diff --git a/lisp/textmodes/mhtml-mode.el b/lisp/textmodes/mhtml-mode.el index 32542d0400..2590538568 100644 --- a/lisp/textmodes/mhtml-mode.el +++ b/lisp/textmodes/mhtml-mode.el @@ -313,7 +313,7 @@ Prefix arg specifies how many times to move (default 1)." (interactive "P") (pcase (get-text-property (point) 'mhtml-submode) ('nil (sgml-skip-tag-forward arg)) - (submode (forward-sexp arg)))) + (_submode (forward-sexp arg)))) ;;;###autoload (define-derived-mode mhtml-mode html-mode diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 8bbab467af..342b4cc32b 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -2003,7 +2003,7 @@ revision of the file otherwise." (if event (posn-set-point (event-end event))) (let ((buffer (when event (current-buffer))) (reverse (not (save-excursion (beginning-of-line) (looking-at "[-<]"))))) - (pcase-let ((`(,buf ,line-offset ,pos ,src ,_dst ,switched) + (pcase-let ((`(,buf ,_line-offset ,pos ,src ,_dst ,_switched) (diff-find-source-location other-file reverse))) (pop-to-buffer buf) (goto-char (+ (car pos) (cdr src))) diff --git a/test/lisp/emacs-lisp/pcase-tests.el b/test/lisp/emacs-lisp/pcase-tests.el index 14384112b3..6ddeb7b622 100644 --- a/test/lisp/emacs-lisp/pcase-tests.el +++ b/test/lisp/emacs-lisp/pcase-tests.el @@ -83,6 +83,13 @@ (should (equal (funcall f t) 'left)) (should (equal (funcall f nil) 'right)))) +(ert-deftest pcase-tests-bug46786 () + (let ((self 'outer)) + (should (equal (cl-macrolet ((show-self () `(list 'self self))) + (pcase-let ((`(,self ,self2) '(inner "2"))) + (show-self))) + '(self inner))))) + ;; Local Variables: ;; no-byte-compile: t ;; End: commit 08b11a02f49da5ca0e4e58a32fa853df0c5e0214 Author: Mattias Engdegård Date: Mon Mar 1 20:52:39 2021 +0100 Fix multiple Calc defmath errors (bug#46750) Fix incorrect variable scoping in `let*`, `for` and `foreach`. Fix loop variable value in `foreach` (should be element, not tail). Fix function quoting, as in ('cons x y) -- didn't work at all. Reported by Stephan Neuhaus. * lisp/calc/calc-prog.el (math-define-exp, math-handle-foreach): * test/lisp/calc/calc-tests.el: (var-g, test1, test2, test3, test4) (test5, test6, test7, calc-defmath): Test various defmath forms. diff --git a/lisp/calc/calc-prog.el b/lisp/calc/calc-prog.el index 3097b09b01..dd221457f8 100644 --- a/lisp/calc/calc-prog.el +++ b/lisp/calc/calc-prog.el @@ -1985,22 +1985,37 @@ Redefine the corresponding command." (cons 'quote (math-define-lambda (nth 1 exp) math-exp-env)) exp)) - ((memq func '(let let* for foreach)) - (let ((head (nth 1 exp)) - (body (cdr (cdr exp)))) - (if (memq func '(let let*)) - () - (setq func (cdr (assq func '((for . math-for) - (foreach . math-foreach))))) - (if (not (listp (car head))) - (setq head (list head)))) - (macroexpand - (cons func - (cons (math-define-let head) - (math-define-body body - (nconc - (math-define-let-env head) - math-exp-env))))))) + ((eq func 'let) + (let ((bindings (nth 1 exp)) + (body (cddr exp))) + `(let ,(math-define-let bindings) + ,@(math-define-body + body (append (math-define-let-env bindings) + math-exp-env))))) + ((eq func 'let*) + ;; Rewrite in terms of `let'. + (let ((bindings (nth 1 exp)) + (body (cddr exp))) + (math-define-exp + (if (> (length bindings) 1) + `(let ,(list (car bindings)) + (let* ,(cdr bindings) ,@body)) + `(let ,bindings ,@body))))) + ((memq func '(for foreach)) + (let ((bindings (nth 1 exp)) + (body (cddr exp))) + (if (> (length bindings) 1) + ;; Rewrite as nested loops. + (math-define-exp + `(,func ,(list (car bindings)) + (,func ,(cdr bindings) ,@body))) + (let ((mac (cdr (assq func '((for . math-for) + (foreach . math-foreach)))))) + (macroexpand + `(,mac ,(math-define-let bindings) + ,@(math-define-body + body (append (math-define-let-env bindings) + math-exp-env)))))))) ((and (memq func '(setq setf)) (math-complicated-lhs (cdr exp))) (if (> (length exp) 3) @@ -2017,7 +2032,7 @@ Redefine the corresponding command." (math-define-cond (cdr exp)))) ((and (consp func) ; ('spam a b) == force use of plain spam (eq (car func) 'quote)) - (cons func (math-define-list (cdr exp)))) + (cons (cadr func) (math-define-list (cdr exp)))) ((symbolp func) (let ((args (math-define-list (cdr exp))) (prim (assq func math-prim-funcs))) @@ -2276,20 +2291,16 @@ Redefine the corresponding command." (defun math-handle-foreach (head body) (let ((var (nth 0 (car head))) + (loop-var (gensym "foreach")) (data (nth 1 (car head))) (body (if (cdr head) (list (math-handle-foreach (cdr head) body)) body))) - (cons 'let - (cons (list (list var data)) - (list - (cons 'while - (cons var - (append body - (list (list 'setq - var - (list 'cdr var))))))))))) - + `(let ((,loop-var ,data)) + (while ,loop-var + (let ((,var (car ,loop-var))) + ,@(append body + `((setq ,loop-var (cdr ,loop-var))))))))) (defun math-body-refers-to (body thing) (or (equal body thing) diff --git a/test/lisp/calc/calc-tests.el b/test/lisp/calc/calc-tests.el index bdcf78e020..c5aa5a31eb 100644 --- a/test/lisp/calc/calc-tests.el +++ b/test/lisp/calc/calc-tests.el @@ -707,6 +707,82 @@ An existing calc stack is reused, otherwise a new one is created." (var c var-c)))))) (calc-set-language nil))) +(defvar var-g) + +;; Test `let'. +(defmath test1 (x) + (let ((x (+ x 1)) + (y (+ x 3))) + (let ((z (+ y 6))) + (* x y z g)))) + +;; Test `let*'. +(defmath test2 (x) + (let* ((y (+ x 1)) + (z (+ y 3))) + (let* ((u (+ z 6))) + (* x y z u g)))) + +;; Test `for'. +(defmath test3 (x) + (let ((s 0)) + (for ((ii 1 x) + (jj 1 ii)) + (setq s (+ s (* ii jj)))) + s)) + +;; Test `for' with non-unit stride. +(defmath test4 (x) + (let ((l nil)) + (for ((ii 1 x 1) + (jj 1 10 ii)) + (setq l ('cons jj l))) ; Use Lisp `cons', not `calcFunc-cons'. + (reverse l))) + +;; Test `foreach'. +(defmath test5 (x) + (let ((s 0)) + (foreach ((a x) + (b a)) + (setq s (+ s b))) + s)) + +;; Test `break'. +(defmath test6 (x) + (let ((a (for ((ii 1 10)) + (when (= ii x) + (break (* ii 2))))) + (b (foreach ((e '(9 3 6))) + (when (= e x) + (break (- e 1)))))) + (* a b))) + +;; Test `return' from `for'. +(defmath test7 (x) + (for ((ii 1 10)) + (when (= ii x) + (return (* ii 2)))) + 5) + +(ert-deftest calc-defmath () + (let ((var-g 17)) + (should (equal (calcFunc-test1 2) (* 3 5 11 17))) + (should (equal (calcFunc-test2 2) (* 2 3 6 12 17)))) + (should (equal (calcFunc-test3 3) + (+ (* 1 1) + (* 2 1) (* 2 2) + (* 3 1) (* 3 2) (* 3 3)))) + (should (equal (calcFunc-test4 5) + '( 1 2 3 4 5 6 7 8 9 10 + 1 3 5 7 9 + 1 4 7 10 + 1 5 9 + 1 6))) + (should (equal (calcFunc-test5 '((2 3) (5) (7 11 13))) + (+ 2 3 5 7 11 13))) + (should (equal (calcFunc-test6 3) (* (* 3 2) (- 3 1)))) + (should (equal (calcFunc-test7 3) (* 3 2)))) + (provide 'calc-tests) ;;; calc-tests.el ends here commit 5f319423c8fdd06b90b076ff6001705884c51f70 Author: Mattias Engdegård Date: Mon Mar 1 16:40:31 2021 +0100 Remove references to old bignums from Calc manual * doc/misc/calc.texi: Remove references to the old Calc representation of big integers, outdated references to fixnums, an any text and examples that only made sense at the time. diff --git a/doc/misc/calc.texi b/doc/misc/calc.texi index c4ccea3caf..b409c1f9c4 100644 --- a/doc/misc/calc.texi +++ b/doc/misc/calc.texi @@ -6612,7 +6612,8 @@ further discussion of infinite and indeterminate values. @subsection Modes Tutorial Exercise 1 @noindent -Calc always stores its numbers in decimal, so even though one-third has +Calc always stores its floating-point numbers in decimal, +so even though one-third has an exact base-3 representation (@samp{3#0.1}), it is still stored as 0.3333333 (chopped off after 12 or however many decimal digits) inside the calculator's memory. When this inexact number is converted back @@ -18888,9 +18889,7 @@ Each possible value @expr{N} appears with equal probability. With no numeric prefix argument, the @kbd{k r} command takes its argument from the stack instead. Once again, if this is a positive integer @expr{M} -the result is a random integer less than @expr{M}. However, note that -while numeric prefix arguments are limited to six digits or so, an @expr{M} -taken from the stack can be arbitrarily large. If @expr{M} is negative, +the result is a random integer less than @expr{M}. If @expr{M} is negative, the result is a random integer in the range @texline @math{M < N \le 0}. @infoline @expr{M < N <= 0}. @@ -32240,7 +32239,7 @@ as the value of a function. You can use @code{return} anywhere inside the body of the function. @end itemize -Non-integer numbers (and extremely large integers) cannot be included +Non-integer numbers cannot be included directly into a @code{defmath} definition. This is because the Lisp reader will fail to parse them long before @code{defmath} ever gets control. Instead, use the notation, @samp{:"3.1415"}. In fact, any algebraic @@ -32374,7 +32373,7 @@ This expands to the pair of definitions, @noindent where in this case the latter function would never really be used! Note -that since the Calculator stores small integers as plain Lisp integers, +that since the Calculator stores integers as plain Lisp integers, the @code{math-add} function will work just as well as the native @code{+} even when the intent is to operate on native Lisp integers. @@ -32643,8 +32642,8 @@ Like @samp{integer}, but the argument must be non-negative. @item fixnum @findex fixnum -Like @samp{integer}, but the argument must fit into a native Lisp integer, -which on most systems means less than 2^23 in absolute value. The +Like @samp{integer}, but the argument must fit into a native Lisp fixnum, +which on most systems means less than 2^61 in absolute value. The argument is converted into Lisp-integer form if necessary. @item float @@ -32740,50 +32739,6 @@ Emacs Lisp function: count)) @end smallexample -If the input numbers are large, this function involves a fair amount -of arithmetic. A binary right shift is essentially a division by two; -recall that Calc stores integers in decimal form so bit shifts must -involve actual division. - -To gain a bit more efficiency, we could divide the integer into -@var{n}-bit chunks, each of which can be handled quickly because -they fit into Lisp integers. It turns out that Calc's arithmetic -routines are especially fast when dividing by an integer less than -1000, so we can set @var{n = 9} bits and use repeated division by 512: - -@smallexample -(defmath bcount ((natnum n)) - (interactive 1 "bcnt") - (let ((count 0)) - (while (not (fixnump n)) - (let ((qr (idivmod n 512))) - (setq count (+ count (bcount-fixnum (cdr qr))) - n (car qr)))) - (+ count (bcount-fixnum n)))) - -(defun bcount-fixnum (n) - (let ((count 0)) - (while (> n 0) - (setq count (+ count (logand n 1)) - n (ash n -1))) - count)) -@end smallexample - -@noindent -Note that the second function uses @code{defun}, not @code{defmath}. -Because this function deals only with native Lisp integers (``fixnums''), -it can use the actual Emacs @code{+} and related functions rather -than the slower but more general Calc equivalents which @code{defmath} -uses. - -The @code{idivmod} function does an integer division, returning both -the quotient and the remainder at once. Again, note that while it -might seem that @samp{(logand n 511)} and @samp{(ash n -9)} are -more efficient ways to split off the bottom nine bits of @code{n}, -actually they are less efficient because each operation is really -a division by 512 in disguise; @code{idivmod} allows us to do the -same thing with a single division by 512. - @node Sine Example, , Bit Counting Example, Example Definitions @subsubsection The Sine Function @@ -33042,9 +32997,7 @@ in this case it would be easier to call the low-level @code{math-add} function in Calc, if you can remember its name. In particular, note that a plain Lisp integer is acceptable to Calc -as a raw object. (All Lisp integers are accepted on input, but -integers of more than six decimal digits are converted to ``big-integer'' -form for output. @xref{Data Type Formats}.) +as a raw object. When it comes time to display the object, just use @samp{(calc-eval a)} to format it as a string. @@ -33308,31 +33261,11 @@ you can't prove this file will already be loaded. @subsubsection Data Type Formats @noindent -Integers are stored in either of two ways, depending on their magnitude. -Integers less than one million in absolute value are stored as standard -Lisp integers. This is the only storage format for Calc data objects -which is not a Lisp list. - -Large integers are stored as lists of the form @samp{(bigpos @var{d0} -@var{d1} @var{d2} @dots{})} for sufficiently large positive integers -(where ``sufficiently large'' depends on the machine), or -@samp{(bigneg @var{d0} @var{d1} @var{d2} @dots{})} for negative -integers. Each @var{d} is a base-@expr{10^n} ``digit'' (where again, -@expr{n} depends on the machine), a Lisp integer from 0 to -99@dots{}9. The least significant digit is @var{d0}; the last digit, -@var{dn}, which is always nonzero, is the most significant digit. For -example, the integer @mathit{-12345678} might be stored as -@samp{(bigneg 678 345 12)}. - -The distinction between small and large integers is entirely hidden from -the user. In @code{defmath} definitions, the Lisp predicate @code{integerp} -returns true for either kind of integer, and in general both big and small -integers are accepted anywhere the word ``integer'' is used in this manual. -If the distinction must be made, native Lisp integers are called @dfn{fixnums} -and large integers are called @dfn{bignums}. +Integers are stored as standard Lisp integers. This is the only +storage format for Calc data objects which is not a Lisp list. Fractions are stored as a list of the form, @samp{(frac @var{n} @var{d})} -where @var{n} is an integer (big or small) numerator, @var{d} is an +where @var{n} is an integer numerator, @var{d} is an integer denominator greater than one, and @var{n} and @var{d} are relatively prime. Note that fractions where @var{d} is one are automatically converted to plain integers by all math routines; fractions where @var{d} is negative @@ -33341,7 +33274,7 @@ are normalized by negating the numerator and denominator. Floating-point numbers are stored in the form, @samp{(float @var{mant} @var{exp})}, where @var{mant} (the ``mantissa'') is an integer less than @samp{10^@var{p}} in absolute value (@var{p} represents the current -precision), and @var{exp} (the ``exponent'') is a fixnum. The value of +precision), and @var{exp} (the ``exponent'') is an integer. The value of the float is @samp{@var{mant} * 10^@var{exp}}. For example, the number @mathit{-3.14} is stored as @samp{(float -314 -2) = -314*10^-2}. Other constraints are that the number 0.0 is always stored as @samp{(float 0 0)}, and, @@ -33736,7 +33669,7 @@ Returns true if @var{x} is an integer of any size. @end defun @defun fixnump x -Returns true if @var{x} is a native Lisp integer. +Returns true if @var{x} is a native Lisp fixnum. @end defun @defun natnump x @@ -33744,7 +33677,7 @@ Returns true if @var{x} is a nonnegative integer of any size. @end defun @defun fixnatnump x -Returns true if @var{x} is a nonnegative Lisp integer. +Returns true if @var{x} is a nonnegative Lisp fixnum. @end defun @defun num-integerp x @@ -33899,7 +33832,7 @@ converted to @samp{(math-equal x y)}. @defun equal-int x n Returns true if @var{x} and @var{n} are numerically equal, where @var{n} -is a fixnum which is not a multiple of 10. This will automatically be +is an integer which is not a multiple of 10. This will automatically be used by @code{defmath} in place of the more general @code{math-equal} whenever possible. @end defun @@ -33980,12 +33913,8 @@ respectively, instead. @defun normalize val (Full form: @code{math-normalize}.) -Reduce the value @var{val} to standard form. For example, if @var{val} -is a fixnum, it will be converted to a bignum if it is too large, and -if @var{val} is a bignum it will be normalized by clipping off trailing -(i.e., most-significant) zero digits and converting to a fixnum if it is -small. All the various data types are similarly converted to their standard -forms. Variables are left alone, but function calls are actually evaluated +Reduce the value @var{val} to standard form. +Variables are left alone, but function calls are actually evaluated in formulas. For example, normalizing @samp{(+ 2 (calcFunc-abs -4))} will return 6. @@ -34098,9 +34027,9 @@ integer rather than truncating. @end defun @defun fixnum n -Return the integer @var{n} as a fixnum, i.e., a native Lisp integer. -If @var{n} is outside the permissible range for Lisp integers (usually -24 binary bits) the result is undefined. +Return the integer @var{n} as a fixnum, i.e., a small Lisp integer. +If @var{n} is outside the permissible range for Lisp fixnums (usually +62 binary bits) the result is undefined. @end defun @defun sqr x commit ce7e78a2c09eadcbc180eb9678ed34c232a146b7 Author: Mattias Engdegård Date: Mon Mar 1 16:38:33 2021 +0100 * lisp/calc/calc-ext.el (math-equal-int): Work for bignums. diff --git a/lisp/calc/calc-ext.el b/lisp/calc/calc-ext.el index f4ddb840b5..24781ed6c8 100644 --- a/lisp/calc/calc-ext.el +++ b/lisp/calc/calc-ext.el @@ -2565,9 +2565,9 @@ If X is not an error form, return 1." ;;; True if A is numerically equal to the integer B. [P N S] [Public] ;;; B must not be a multiple of 10. (defun math-equal-int (a b) - (or (eq a b) + (or (eql a b) (and (eq (car-safe a) 'float) - (eq (nth 1 a) b) + (eql (nth 1 a) b) (= (nth 2 a) 0)))) commit e6a4ef48fd0b0ea4386069eb47d148c930856ce6 Author: Juri Linkov Date: Mon Mar 1 21:58:00 2021 +0200 * lisp/isearch.el: Minor doc fix. diff --git a/lisp/isearch.el b/lisp/isearch.el index 8aaf765429..e7926ac08c 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -26,7 +26,7 @@ ;; Instructions -;; For programmed use of isearch-mode, e.g. calling (`isearch-forward'), +;; For programmed use of isearch-mode, e.g. calling `isearch-forward', ;; isearch-mode behaves modally and does not return until the search ;; is completed. It uses a recursive-edit to behave this way. commit 6268c9ba6e2cad11837181a3e75c805b73619a0b Author: Juri Linkov Date: Mon Mar 1 21:56:42 2021 +0200 * lisp/tab-bar.el (tab-bar--define-keys): Add check for tab-bar-format-global. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index c3955913e2..d93ee9c93f 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -117,8 +117,9 @@ Possible modifier keys are `control', `meta', `shift', `hyper', `super' and ;; Replace default value with a condition that supports displaying ;; global-mode-string in the tab bar instead of the mode line. - (when (member '(global-mode-string ("" global-mode-string " ")) - mode-line-misc-info) + (when (and (memq 'tab-bar-format-global tab-bar-format) + (member '(global-mode-string ("" global-mode-string " ")) + mode-line-misc-info)) (setq mode-line-misc-info (append '(global-mode-string ("" (:eval (if (and tab-bar-mode commit 59e1867a1f2b6938cdabac8e3f52acc9e61e9e32 Author: Protesilaos Stavrou Date: Mon Mar 1 17:31:44 2021 +0200 Add 'require-theme' function * etc/NEWS: Document new function. * lisp/custom.el (require-theme): Add function. This follows from the discussion on bug#45068 where it became apparent that there was no equivalent mechanism to 'require' that read through the 'custom-theme-load-path'. diff --git a/etc/NEWS b/etc/NEWS index 3db276165f..d01b532193 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2506,6 +2506,12 @@ region's (or buffer's) end. This function can be used by modes to add elements to the 'choice' customization type of a variable. +--- +** New function 'require-theme'. +This function is used to load a theme or library stored in the +'custom-theme-load-path'. It is intended to work as a substitute for +'require' in those cases where that cannot be used. + +++ ** New function 'file-modes-number-to-symbolic' to convert a numeric file mode specification into symbolic form. diff --git a/lisp/custom.el b/lisp/custom.el index 833810718b..35ac4d8564 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1200,6 +1200,30 @@ property `theme-feature' (which is usually a symbol created by (custom-check-theme theme) (provide (get theme 'theme-feature))) +(defun require-theme (theme &optional path) + "Load THEME stored in `custom-theme-load-path'. + +THEME is a symbol that corresponds to the file name without its file +type extension. That is assumed to be either '.el' or '.elc'. + +When THEME is an element of `custom-available-themes', load it and ask +for confirmation if it is not considered safe by `custom-safe-themes'. +Otherwise load the file indicated by THEME, if present. In the latter +case, the file is intended to work as the basis of a theme declared +with `deftheme'. + +If optional PATH is non-nil, it should be a list of directories +to search for THEME in, instead of `custom-theme-load-path'. +PATH should have the same form as `load-path' or `exec-path'." + (cond + ((memq theme (custom-available-themes)) + (load-theme theme)) + ((let* ((dirs (or path (custom-theme--load-path))) + (file (unless (featurep theme) + (locate-file (symbol-name theme) dirs '(".el" ".elc"))))) + (when file + (load-file file)))))) + (defcustom custom-safe-themes '(default) "Themes that are considered safe to load. If the value is a list, each element should be either the SHA-256 commit ece8c1307acc2b5d15babfc99cbcf2367945e95b Author: Lars Ingebrigtsen Date: Mon Mar 1 20:48:20 2021 +0100 Fix woman.el menu alteration code * lisp/woman.el (woman-dired-define-keys): Fix naming of menu after dired menu changes. diff --git a/lisp/woman.el b/lisp/woman.el index d4f7e8c0db..0a9f3665eb 100644 --- a/lisp/woman.el +++ b/lisp/woman.el @@ -1523,7 +1523,7 @@ Also make each path-info component into a list. (mapc 'woman-dired-define-key woman-dired-keys) (woman-dired-define-key-maybe "w") (woman-dired-define-key-maybe "W"))) - (define-key-after (lookup-key dired-mode-map [menu-bar immediate]) + (define-key-after (lookup-key dired-mode-map [menu-bar Immediate]) [woman] '("Read Man Page (WoMan)" . woman-dired-find-file) 'view)) (if (featurep 'dired) commit 4d35faa1dbb430f87aa9d6f6b27ee9adeb343906 Author: Alan Mackenzie Date: Mon Mar 1 19:23:01 2021 +0000 CC Mode: Amend C-M-a/e to handle lambda function in C++ arglist * lisp/progmodes/cc-cmds.el (c-where-wrt-brace-construct): Reformulate latter part such that the least enclosing braces and parentheses are used when determining containment in such. c-beginning-of-decl-1 has been superseded by list movement and syntactic whitespace movement. (c-backward-to-nth-BOF-{): Work on least enclosing parens rather than parens at any level when moving back to an opening brace. (c-forward-to-nth-EOF-\;-or-}): Work on least enclosing parens, as above. Move the correction of point when in a "function trailer" to after the main loop, correcting a minor bug. diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el index 33a0360207..1754436d13 100644 --- a/lisp/progmodes/cc-cmds.el +++ b/lisp/progmodes/cc-cmds.el @@ -1639,7 +1639,7 @@ No indentation or other \"electric\" behavior is performed." ;; ;; This function might do hidden buffer changes. (save-excursion - (let* (kluge-start + (let* (knr-start knr-res decl-result brace-decl-p (start (point)) (paren-state (c-parse-state)) @@ -1670,63 +1670,39 @@ No indentation or other \"electric\" behavior is performed." (not (looking-at c-defun-type-name-decl-key)))))) 'at-function-end) (t - ;; Find the start of the current declaration. NOTE: If we're in the - ;; variables after a "struct/eval" type block, we don't get to the - ;; real declaration here - we detect and correct for this later. - - ;;If we're in the parameters' parens, move back out of them. - (if least-enclosing (goto-char least-enclosing)) - ;; Kluge so that c-beginning-of-decl-1 won't go back if we're already - ;; at a declaration. - (if (or (and (eolp) (not (eobp))) ; EOL is matched by "\\s>" - (not (looking-at -"\\([;#]\\|\\'\\|\\s(\\|\\s)\\|\\s\"\\|\\s\\\\|\\s$\\|\\s<\\|\\s>\\|\\s!\\)"))) - (forward-char)) - (setq kluge-start (point)) - ;; First approximation as to whether the current "header" we're in is - ;; one followed by braces. - (setq brace-decl-p - (save-excursion - (and (c-syntactic-re-search-forward "[;{]" nil t t) - (or (eq (char-before) ?\{) - (and c-recognize-knr-p - ;; Might have stopped on the - ;; ';' in a K&R argdecl. In - ;; that case the declaration - ;; should contain a block. - (c-in-knr-argdecl)))))) - (setq decl-result - (car (c-beginning-of-decl-1 - ;; NOTE: If we're in a K&R region, this might be the start - ;; of a parameter declaration, not the actual function. - ;; It might also leave us at a label or "label" like - ;; "private:". - (and least-enclosing ; LIMIT for c-b-of-decl-1 - (c-safe-position least-enclosing paren-state))))) - - ;; Has the declaration we've gone back to got braces? - (if (or (eq decl-result 'label) - (looking-at c-protection-key)) - (setq brace-decl-p nil)) - - (cond - ((or (eq decl-result 'label) ; e.g. "private:" or invalid syntax. - (= (point) kluge-start)) ; might be BOB or unbalanced parens. - 'outwith-function) - ((eq decl-result 'same) - (if brace-decl-p - (if (eq (point) start) - 'at-header + (if (and least-enclosing + (eq (char-after least-enclosing) ?\()) + (c-go-list-forward least-enclosing)) + (c-forward-syntactic-ws) + (setq knr-start (point)) + (if (c-syntactic-re-search-forward "{" nil t t) + (progn + (backward-char) + (cond + ((or (progn + (c-backward-syntactic-ws) + (<= (point) start)) + (and c-recognize-knr-p + (and (setq knr-res (c-in-knr-argdecl)) + (<= knr-res knr-start)))) 'in-header) - 'outwith-function)) - ((eq decl-result 'previous) - (if (and (not brace-decl-p) - (c-in-function-trailer-p)) - 'at-function-end - 'outwith-function)) - (t (error - "c-where-wrt-brace-construct: c-beginning-of-decl-1 returned %s" - decl-result)))))))) + ((and knr-res + (goto-char knr-res) + (c-backward-syntactic-ws))) ; Always returns nil. + ((and (eq (char-before) ?\)) + (c-go-list-backward)) + (c-syntactic-skip-backward "^;" start t) + (if (eq (point) start) + (if (progn (c-backward-syntactic-ws) + (memq (char-before) '(?\; ?} nil))) + (if (progn (c-forward-syntactic-ws) + (eq (point) start)) + 'at-header + 'outwith-function) + 'in-header) + 'outwith-function)) + (t 'outwith-function))) + 'outwith-function)))))) (defun c-backward-to-nth-BOF-{ (n where) ;; Skip to the opening brace of the Nth function before point. If @@ -1749,9 +1725,11 @@ No indentation or other \"electric\" behavior is performed." (goto-char (c-least-enclosing-brace (c-parse-state))) (setq n (1- n))) ((eq where 'in-header) - (c-syntactic-re-search-forward "{") - (backward-char) - (setq n (1- n))) + (let ((encl-paren (c-least-enclosing-brace (c-parse-state)))) + (if encl-paren (goto-char encl-paren)) + (c-syntactic-re-search-forward "{" nil t t) + (backward-char) + (setq n (1- n)))) ((memq where '(at-header outwith-function at-function-end in-trailer)) (c-syntactic-skip-backward "^}") (when (eq (char-before) ?\}) @@ -1965,21 +1943,24 @@ defun." ;; The actual movement is done below. (setq n (1- n))) ((memq where '(at-function-end outwith-function at-header in-header)) - (when (c-syntactic-re-search-forward "{" nil 'eob) + (if (eq where 'in-header) + (let ((pos (c-least-enclosing-brace (c-parse-state)))) + (if pos (c-go-list-forward pos)))) + (when (c-syntactic-re-search-forward "{" nil 'eob t) (backward-char) (forward-sexp) (setq n (1- n)))) (t (error "c-forward-to-nth-EOF-\\;-or-}: `where' is %s" where))) - (when (c-in-function-trailer-p) - (c-syntactic-re-search-forward ";" nil 'eob t)) - ;; Each time round the loop, go forward to a "}" at the outermost level. (while (and (> n 0) (not (eobp))) (when (c-syntactic-re-search-forward "{" nil 'eob) (backward-char) (forward-sexp) (setq n (1- n)))) + + (when (c-in-function-trailer-p) + (c-syntactic-re-search-forward ";" nil 'eob t)) n) (defun c-end-of-defun (&optional arg) commit d56b1f9e7cee077011fa1256c2965c2984a17282 Author: Stefan Monnier Date: Mon Mar 1 14:07:05 2021 -0500 * lisp/emacs-lisp/pcase.el (pcase--split-pred): Re-fix bug#14773 Adjust to calling convention of `macroexp--fgrep`. diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 95e5dd3ba0..b1e1305edf 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -661,7 +661,7 @@ A and B can be one of: ;; run, but we don't have the environment in which `pat' will ;; run, so we can't do a reliable verification. But let's try ;; and catch at least the easy cases such as (bug#14773). - (not (macroexp--fgrep (mapcar #'car vars) (cadr upat))))) + (not (macroexp--fgrep vars (cadr upat))))) '(:pcase--succeed . :pcase--fail)) ;; In case PAT is of the form (pred (not PRED)) ((and (eq 'pred (car-safe pat)) (eq 'not (car-safe (cadr pat)))) diff --git a/test/lisp/emacs-lisp/pcase-tests.el b/test/lisp/emacs-lisp/pcase-tests.el index e6f4c09750..14384112b3 100644 --- a/test/lisp/emacs-lisp/pcase-tests.el +++ b/test/lisp/emacs-lisp/pcase-tests.el @@ -75,6 +75,14 @@ (ert-deftest pcase-tests-vectors () (should (equal (pcase [1 2] (`[,x] 1) (`[,x ,y] (+ x y))) 3))) +(ert-deftest pcase-tests-bug14773 () + (let ((f (lambda (x) + (pcase 'dummy + ((and (let var x) (guard var)) 'left) + ((and (let var (not x)) (guard var)) 'right))))) + (should (equal (funcall f t) 'left)) + (should (equal (funcall f nil) 'right)))) + ;; Local Variables: ;; no-byte-compile: t ;; End: commit a0f60293d97cda858c033db4ae074e5e5560aab2 Author: Stefan Monnier Date: Mon Mar 1 12:18:49 2021 -0500 Fix misuses of `byte-compile-macro-environment` These seem to be left overs from Emacs<24 when `macroexpand-all` was implemented in the CL library and hence the macros's evaluation environment could come from different places depending on the circumstance (either `byte-compile-macro-environment`, or `cl-macro-environment`, or ...). `byte-compile-macro-environment` contains definitions which expand to code that is only understood by the rest of the byte-compiler, so using it for code which isn't being byte-compiled leads to errors such as references to non-existing function `internal--with-suppressed-warnings`. * lisp/emacs-lisp/cl-extra.el (cl-prettyexpand): Remove left-over binding from when `macroexpand-all` was implemented in the CL library. * lisp/emacs-lisp/ert.el (ert--expand-should-1): * lisp/emacs-lisp/cl-macs.el (cl--compile-time-too): Properly preserve the macroexpand-all-environment. (cl--macroexp-fboundp): Pay attention to `cl-macrolet` macros as well. diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el index 84199c1612..eabba27d22 100644 --- a/lisp/emacs-lisp/cl-extra.el +++ b/lisp/emacs-lisp/cl-extra.el @@ -94,7 +94,7 @@ strings case-insensitively." (defun cl--mapcar-many (cl-func cl-seqs &optional acc) (if (cdr (cdr cl-seqs)) (let* ((cl-res nil) - (cl-n (apply 'min (mapcar 'length cl-seqs))) + (cl-n (apply #'min (mapcar #'length cl-seqs))) (cl-i 0) (cl-args (copy-sequence cl-seqs)) cl-p1 cl-p2) @@ -131,7 +131,7 @@ strings case-insensitively." "Map a FUNCTION across one or more SEQUENCEs, returning a sequence. TYPE is the sequence type to return. \n(fn TYPE FUNCTION SEQUENCE...)" - (let ((cl-res (apply 'cl-mapcar cl-func cl-seq cl-rest))) + (let ((cl-res (apply #'cl-mapcar cl-func cl-seq cl-rest))) (and cl-type (cl-coerce cl-res cl-type)))) ;;;###autoload @@ -190,14 +190,14 @@ the elements themselves. "Like `cl-mapcar', but nconc's together the values returned by the function. \n(fn FUNCTION SEQUENCE...)" (if cl-rest - (apply 'nconc (apply 'cl-mapcar cl-func cl-seq cl-rest)) + (apply #'nconc (apply #'cl-mapcar cl-func cl-seq cl-rest)) (mapcan cl-func cl-seq))) ;;;###autoload (defun cl-mapcon (cl-func cl-list &rest cl-rest) "Like `cl-maplist', but nconc's together the values returned by the function. \n(fn FUNCTION LIST...)" - (apply 'nconc (apply 'cl-maplist cl-func cl-list cl-rest))) + (apply #'nconc (apply #'cl-maplist cl-func cl-list cl-rest))) ;;;###autoload (defun cl-some (cl-pred cl-seq &rest cl-rest) @@ -236,13 +236,13 @@ non-nil value. (defun cl-notany (cl-pred cl-seq &rest cl-rest) "Return true if PREDICATE is false of every element of SEQ or SEQs. \n(fn PREDICATE SEQ...)" - (not (apply 'cl-some cl-pred cl-seq cl-rest))) + (not (apply #'cl-some cl-pred cl-seq cl-rest))) ;;;###autoload (defun cl-notevery (cl-pred cl-seq &rest cl-rest) "Return true if PREDICATE is false of some element of SEQ or SEQs. \n(fn PREDICATE SEQ...)" - (not (apply 'cl-every cl-pred cl-seq cl-rest))) + (not (apply #'cl-every cl-pred cl-seq cl-rest))) ;;;###autoload (defun cl--map-keymap-recursively (cl-func-rec cl-map &optional cl-base) @@ -693,12 +693,11 @@ PROPLIST is a list of the sort returned by `symbol-plist'. "Expand macros in FORM and insert the pretty-printed result." (declare (advertised-calling-convention (form) "27.1")) (message "Expanding...") - (let ((byte-compile-macro-environment nil)) - (setq form (macroexpand-all form)) - (message "Formatting...") - (prog1 - (cl-prettyprint form) - (message "")))) + (setq form (macroexpand-all form)) + (message "Formatting...") + (prog1 + (cl-prettyprint form) + (message ""))) ;;; Integration into the online help system. diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 007466bbb0..91146c4d0e 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -723,7 +723,7 @@ If `eval' is in WHEN, BODY is evaluated when interpreted or at non-top-level. (defun cl--compile-time-too (form) (or (and (symbolp (car-safe form)) (get (car-safe form) 'byte-hunk-handler)) (setq form (macroexpand - form (cons '(cl-eval-when) byte-compile-macro-environment)))) + form (cons '(cl-eval-when) macroexpand-all-environment)))) (cond ((eq (car-safe form) 'progn) (cons 'progn (mapcar #'cl--compile-time-too (cdr form)))) ((eq (car-safe form) 'cl-eval-when) @@ -2481,12 +2481,12 @@ values. For compatibility, (cl-values A B C) is a synonym for (list A B C). '(nil byte-compile-inline-expand)) (error "%s already has a byte-optimizer, can't make it inline" (car spec))) - (put (car spec) 'byte-optimizer 'byte-compile-inline-expand))) + (put (car spec) 'byte-optimizer #'byte-compile-inline-expand))) ((eq (car-safe spec) 'notinline) (while (setq spec (cdr spec)) (if (eq (get (car spec) 'byte-optimizer) - 'byte-compile-inline-expand) + #'byte-compile-inline-expand) (put (car spec) 'byte-optimizer nil)))) ((eq (car-safe spec) 'optimize) @@ -3257,7 +3257,6 @@ does not contain SLOT-NAME." (signal 'cl-struct-unknown-slot (list struct-type slot-name)))) (defvar byte-compile-function-environment) -(defvar byte-compile-macro-environment) (defun cl--macroexp-fboundp (sym) "Return non-nil if SYM will be bound when we run the code. @@ -3265,7 +3264,7 @@ Of course, we really can't know that for sure, so it's just a heuristic." (or (fboundp sym) (and (macroexp-compiling-p) (or (cdr (assq sym byte-compile-function-environment)) - (cdr (assq sym byte-compile-macro-environment)))))) + (cdr (assq sym macroexpand-all-environment)))))) (pcase-dolist (`(,type . ,pred) ;; Mostly kept in alphabetical order. diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index a5c877e53a..155b6a9d4e 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -277,14 +277,7 @@ It should only be stopped when ran from inside ert--run-test-internal." (let ((form ;; catch macroexpansion errors (condition-case err - (macroexpand-all form - (append (bound-and-true-p - byte-compile-macro-environment) - (cond - ((boundp 'macroexpand-all-environment) - macroexpand-all-environment) - ((boundp 'cl-macro-environment) - cl-macro-environment)))) + (macroexpand-all form macroexpand-all-environment) (error `(signal ',(car err) ',(cdr err)))))) (cond ((or (atom form) (ert--special-operator-p (car form))) @@ -1550,7 +1543,7 @@ Ran \\([0-9]+\\) tests, \\([0-9]+\\) results as expected\ (message "------------------") (setq tests (sort tests (lambda (x y) (> (car x) (car y))))) (when (< high (length tests)) (setcdr (nthcdr (1- high) tests) nil)) - (message "%s" (mapconcat 'cdr tests "\n"))) + (message "%s" (mapconcat #'cdr tests "\n"))) ;; More details on hydra, where the logs are harder to get to. (when (and (getenv "EMACS_HYDRA_CI") (not (zerop (+ nunexpected nskipped)))) @@ -2077,7 +2070,7 @@ and how to display message." (ert-run-tests selector listener t))) ;;;###autoload -(defalias 'ert 'ert-run-tests-interactively) +(defalias 'ert #'ert-run-tests-interactively) ;;; Simple view mode for auxiliary information like stack traces or commit 6ad9b8d677fe136b9a0489eef0c2dd6a1f63917d Author: Stefan Monnier Date: Mon Mar 1 11:42:04 2021 -0500 * src/eval.c (init_eval_once): Bump max_specpdl_size (bug46818) Further testing seems to confirm my suspicion that the increase in the specpdl comes from the recent change to `pcase--if`. * lisp/international/mule-cmds.el (update-leim-list-file): Revert workaround. diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index e1dbf82ed4..e4bdf50f52 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -1312,13 +1312,8 @@ Each function is called with one arg, LEIM directory name.") (defun update-leim-list-file (&rest dirs) "Update LEIM list file in directories DIRS." - ;; bug#46818: This `let'-binding is not necessary, but - ;; it reduces the recursion depth during bootstrap (at which - ;; point some of the core ELisp files haven't been byte-compiled - ;; yet, which causes deeper-than-normal recursion). - (let ((vc-handled-backends nil)) - (dolist (function update-leim-list-functions) - (apply function dirs)))) + (dolist (function update-leim-list-functions) + (apply function dirs))) (defvar-local current-input-method nil "The current input method for multilingual text. diff --git a/src/eval.c b/src/eval.c index 542d7f686e..ddaa8edd81 100644 --- a/src/eval.c +++ b/src/eval.c @@ -219,7 +219,7 @@ void init_eval_once (void) { /* Don't forget to update docs (lispref node "Local Variables"). */ - max_specpdl_size = 1600; /* 1500 is not enough for cl-generic.el. */ + max_specpdl_size = 1800; /* See bug#46818. */ max_lisp_eval_depth = 800; Vrun_hooks = Qnil; pdumper_do_now_and_after_load (init_eval_once_for_pdumper); commit 5c26ea4cbcbf78766dc4b48d34f57fcfafd81cf0 Author: Glenn Morris Date: Mon Mar 1 06:27:02 2021 -0800 ; Auto-commit of loaddefs files. diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index 9924d62774..fa971b33c7 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -62,7 +62,7 @@ should return a grid vector array that is the new solution. ;;;### (autoloads nil "add-log" "vc/add-log.el" (0 0 0 0)) ;;; Generated autoloads from vc/add-log.el -(put 'change-log-default-name 'safe-local-variable 'string-or-null-p) +(put 'change-log-default-name 'safe-local-variable #'string-or-null-p) (defvar add-log-current-defun-function nil "\ If non-nil, function to guess name of surrounding function. @@ -1881,7 +1881,7 @@ specifies in the mode line. Activate Mouse Avoidance mode. See function `mouse-avoidance-mode' for possible values. Setting this variable directly does not take effect; -use either \\[customize] or the function `mouse-avoidance-mode'.") +use either \\[customize] or \\[mouse-avoidance-mode].") (custom-autoload 'mouse-avoidance-mode "avoid" nil) @@ -2529,7 +2529,7 @@ deletion, or > if it is flagged for displaying." t nil) (defalias 'edit-bookmarks 'bookmark-bmenu-list) (autoload 'bookmark-bmenu-search "bookmark" "\ -Incremental search of bookmarks, hiding the non-matches as we go." t nil) +Incremental search of bookmarks, hiding the non-matches as we go." '(bookmark-bmenu-mode) nil) (defvar menu-bar-bookmark-map (let ((map (make-sparse-keymap "Bookmark functions"))) (bindings--define-key map [load] '(menu-item "Load a Bookmark File..." bookmark-load :help "Load bookmarks from a bookmark file)")) (bindings--define-key map [write] '(menu-item "Save Bookmarks As..." bookmark-write :help "Write bookmarks to a file (reading the file name with the minibuffer)")) (bindings--define-key map [save] '(menu-item "Save Bookmarks" bookmark-save :help "Save currently defined bookmarks")) (bindings--define-key map [edit] '(menu-item "Edit Bookmark List" bookmark-bmenu-list :help "Display a list of existing bookmarks")) (bindings--define-key map [delete] '(menu-item "Delete Bookmark..." bookmark-delete :help "Delete a bookmark from the bookmark list")) (bindings--define-key map [delete-all] '(menu-item "Delete all Bookmarks..." bookmark-delete-all :help "Delete all bookmarks from the bookmark list")) (bindings--define-key map [rename] '(menu-item "Rename Bookmark..." bookmark-rename :help "Change the name of a bookmark")) (bindings--define-key map [locate] '(menu-item "Insert Location..." bookmark-locate :help "Insert the name of the file associated with a bookmark")) (bindings--define-key map [insert] '(menu-item "Insert Contents..." bookmark-insert :help "Insert the text of the file pointed to by a bookmark")) (bindings--define-key map [set] '(menu-item "Set Bookmark..." bookmark-set :help "Set a bookmark named inside a file.")) (bindings--define-key map [jump] '(menu-item "Jump to Bookmark..." bookmark-jump :help "Jump to a bookmark (a point in some file)")) map)) @@ -4410,11 +4410,6 @@ Returns a form where all lambdas don't have any free variables. \(fn FORM)" nil nil) -(autoload 'cconv-warnings-only "cconv" "\ -Add the warnings that closure conversion would encounter. - -\(fn FORM)" nil nil) - (register-definition-prefixes "cconv" '("cconv-")) ;;;*** @@ -5940,8 +5935,7 @@ span the needed amount of lines. Variables `cperl-pod-here-scan', `cperl-pod-here-fontify', `cperl-pod-face', `cperl-pod-head-face' control processing of POD and -here-docs sections. With capable Emaxen results of scan are used -for indentation too, otherwise they are used for highlighting only. +here-docs sections. Results of scan are used for indentation too. Variables controlling indentation style: `cperl-tab-always-indent' @@ -6405,9 +6399,9 @@ PACKAGE value appearing in the :package-version keyword. Since the user might see the value in an error message, a good choice is the official name of the package, such as MH-E or Gnus.") -(defalias 'customize-changed 'customize-changed-options) +(define-obsolete-function-alias 'customize-changed-options #'customize-changed "28.1") -(autoload 'customize-changed-options "cus-edit" "\ +(autoload 'customize-changed "cus-edit" "\ Customize all settings whose meanings have changed in Emacs itself. This includes new user options and faces, and new customization groups, as well as older options and faces whose meanings or @@ -6775,6 +6769,13 @@ If the HANDLER returns a `dbus-error', it is propagated as return message. \(fn EVENT)" t nil) +(autoload 'dbus-monitor "dbus" "\ +Invoke `dbus-register-monitor' interactively, and switch to the buffer. +BUS is either a Lisp keyword, `:system' or `:session', or a +string denoting the bus address. The value nil defaults to `:session'. + +\(fn &optional BUS)" t nil) + (register-definition-prefixes "dbus" '("dbus-")) ;;;*** @@ -7006,7 +7007,9 @@ The most useful commands are: \\[decipher-frequency-count] Display the frequency of each ciphertext letter \\[decipher-adjacency-list] Show adjacency list for current letter (lists letters appearing next to it) \\[decipher-make-checkpoint] Save the current cipher alphabet (checkpoint) -\\[decipher-restore-checkpoint] Restore a saved cipher alphabet (checkpoint)" t nil) +\\[decipher-restore-checkpoint] Restore a saved cipher alphabet (checkpoint) + +\(fn)" t nil) (register-definition-prefixes "decipher" '("decipher-")) @@ -7130,6 +7133,9 @@ KEYWORD-ARGS: :after-hook FORM A single lisp form which is evaluated after the mode hooks have been run. It should not be quoted. + :interactive BOOLEAN + Whether the derived mode should be `interactive' or not. + The default is t. BODY: forms to execute just before running the hooks for the new mode. Do not use `interactive' here. @@ -7475,13 +7481,13 @@ You can control what lines will be unwrapped by frobbing indicating the minimum and maximum length of an unwrapped citation line. If NODISPLAY is non-nil, don't redisplay the article buffer. -\(fn &optional NODISPLAY)" t nil) +\(fn &optional NODISPLAY)" '(gnus-article-mode gnus-summary-mode) nil) (autoload 'gnus-article-outlook-repair-attribution "deuglify" "\ Repair a broken attribution line. If NODISPLAY is non-nil, don't redisplay the article buffer. -\(fn &optional NODISPLAY)" t nil) +\(fn &optional NODISPLAY)" '(gnus-article-mode gnus-summary-mode) nil) (autoload 'gnus-outlook-deuglify-article "deuglify" "\ Full deuglify of broken Outlook (Express) articles. @@ -7489,10 +7495,10 @@ Treat \"smartquotes\", unwrap lines, repair attribution and rearrange citation. If NODISPLAY is non-nil, don't redisplay the article buffer. -\(fn &optional NODISPLAY)" t nil) +\(fn &optional NODISPLAY)" '(gnus-article-mode gnus-summary-mode) nil) (autoload 'gnus-article-outlook-deuglify-article "deuglify" "\ -Deuglify broken Outlook (Express) articles and redisplay." t nil) +Deuglify broken Outlook (Express) articles and redisplay." '(gnus-article-mode gnus-summary-mode) nil) (register-definition-prefixes "deuglify" '("gnus-")) @@ -7559,23 +7565,22 @@ This is a mode for searching a dictionary server implementing the protocol defined in RFC 2229. This is a quick reference to this mode describing the default key bindings: +\\ +* \\[dictionary-close] close the dictionary buffer +* \\[dictionary-help] display this help information +* \\[dictionary-search] ask for a new word to search +* \\[dictionary-lookup-definition] search the word at point +* \\[forward-button] or TAB place point to the next link +* \\[backward-button] or S-TAB place point to the prev link -* q close the dictionary buffer -* h display this help information -* s ask for a new word to search -* d search the word at point -* n or Tab place point to the next link -* p or S-Tab place point to the prev link +* \\[dictionary-match-words] ask for a pattern and list all matching words. +* \\[dictionary-select-dictionary] select the default dictionary +* \\[dictionary-select-strategy] select the default search strategy -* m ask for a pattern and list all matching words. -* D select the default dictionary -* M select the default search strategy - -* Return or Button2 visit that link -" nil nil) +* RET or visit that link" nil nil) (autoload 'dictionary "dictionary" "\ -Create a new dictonary buffer and install dictionary-mode." t nil) +Create a new dictionary buffer and install `dictionary-mode'." t nil) (autoload 'dictionary-search "dictionary" "\ Search the WORD in DICTIONARY if given or in all if nil. @@ -7606,7 +7611,7 @@ Display entries matching WORD or the current word if not given. Display tooltips for the current word. This function can be used to enable or disable the tooltip mode -for the current buffer (based on ARG). If global-tooltip-mode is +for the current buffer (based on ARG). If global-tooltip-mode is active it will overwrite that mode for the current buffer. \(fn &optional ARG)" t nil) @@ -7772,10 +7777,15 @@ Switches passed to `ls' for Dired. MUST contain the `l' option. May contain all other options that don't contradict `-l'; may contain even `F', `b', `i' and `s'. See also the variable `dired-ls-F-marks-symlinks' concerning the `F' switch. + +If you have files with names with embedded newline characters, adding +`b' to the switches will allow Dired to handle those files better. + Options that include embedded whitespace must be quoted like this: \"--option=value with spaces\"; you can use `combine-and-quote-strings' to produce the correct quoting of each option. + On systems such as MS-DOS and MS-Windows, which use `ls' emulation in Lisp, some of the `ls' switches are not supported; see the doc string of `insert-directory' in `ls-lisp.el' for more details.") @@ -7873,19 +7883,9 @@ directories again, type \\[dired-do-redisplay] to relist the file at point or th subdirectory, or type \\[dired-build-subdir-alist] to parse the buffer again for the directory tree. -Customization variables (rename this buffer and type \\[describe-variable] on each line -for more info): +See the `dired' customization group for a list of user options. - `dired-listing-switches' - `dired-trivial-filenames' - `dired-marker-char' - `dired-del-marker' - `dired-keep-marker-rename' - `dired-keep-marker-copy' - `dired-keep-marker-hardlink' - `dired-keep-marker-symlink' - -Hooks (use \\[describe-variable] to see their documentation): +This mode runs the following hooks: `dired-before-readin-hook' `dired-after-readin-hook' @@ -8266,6 +8266,13 @@ if some action was made, or nil if the URL is ignored.") ;;;### (autoloads nil "dns" "net/dns.el" (0 0 0 0)) ;;; Generated autoloads from net/dns.el +(autoload 'dns-query "dns" "\ +Query a DNS server for NAME of TYPE. +If FULL, return the entire record returned. +If REVERSE, look up an IP address. + +\(fn NAME &optional TYPE FULL REVERSE)" nil nil) + (register-definition-prefixes "dns" '("dns-")) ;;;*** @@ -8487,6 +8494,10 @@ BODY contains code to execute each time the mode is enabled or disabled. :lighter SPEC Same as the LIGHTER argument. :keymap MAP Same as the KEYMAP argument. :require SYM Same as in `defcustom'. +:interactive VAL Whether this mode should be a command or not. The default + is to make it one; use nil to avoid that. If VAL is a list, + it's interpreted as a list of major modes this minor mode + is useful in. :variable PLACE The location to use instead of the variable MODE to store the state of the mode. This can be simply a different named variable, or a generalized variable. @@ -8584,158 +8595,6 @@ CSS contains a list of syntax specifications of the form (CHAR . SYNTAX). (register-definition-prefixes "easy-mmode" '("easy-mmode-")) -;;;*** - -;;;### (autoloads nil "easymenu" "emacs-lisp/easymenu.el" (0 0 0 -;;;;;; 0)) -;;; Generated autoloads from emacs-lisp/easymenu.el - -(autoload 'easy-menu-define "easymenu" "\ -Define a pop-up menu and/or menu bar menu specified by MENU. -If SYMBOL is non-nil, define SYMBOL as a function to pop up the -submenu defined by MENU, with DOC as its doc string. - -MAPS, if non-nil, should be a keymap or a list of keymaps; add -the submenu defined by MENU to the keymap or each of the keymaps, -as a top-level menu bar item. - -The first element of MENU must be a string. It is the menu bar -item name. It may be followed by the following keyword argument -pairs: - - :filter FUNCTION - FUNCTION must be a function which, if called with one - argument---the list of the other menu items---returns the - items to actually display. - - :visible INCLUDE - INCLUDE is an expression. The menu is visible if the - expression evaluates to a non-nil value. `:included' is an - alias for `:visible'. - - :active ENABLE - ENABLE is an expression. The menu is enabled for selection - if the expression evaluates to a non-nil value. `:enable' is - an alias for `:active'. - - :label FORM - FORM is an expression that is dynamically evaluated and whose - value serves as the menu's label (the default is the first - element of MENU). - - :help HELP - HELP is a string, the help to display for the menu. - In a GUI this is a \"tooltip\" on the menu button. (Though - in Lucid :help is not shown for the top-level menu bar, only - for sub-menus.) - -The rest of the elements in MENU are menu items. -A menu item can be a vector of three elements: - - [NAME CALLBACK ENABLE] - -NAME is a string--the menu item name. - -CALLBACK is a command to run when the item is chosen, or an -expression to evaluate when the item is chosen. - -ENABLE is an expression; the item is enabled for selection if the -expression evaluates to a non-nil value. - -Alternatively, a menu item may have the form: - - [ NAME CALLBACK [ KEYWORD ARG ]... ] - -where NAME and CALLBACK have the same meanings as above, and each -optional KEYWORD and ARG pair should be one of the following: - - :keys KEYS - KEYS is a string; a keyboard equivalent to the menu item. - This is normally not needed because keyboard equivalents are - usually computed automatically. KEYS is expanded with - `substitute-command-keys' before it is used. - - :key-sequence KEYS - KEYS is a hint for speeding up Emacs's first display of the - menu. It should be nil if you know that the menu item has no - keyboard equivalent; otherwise it should be a string or - vector specifying a keyboard equivalent for the menu item. - - :active ENABLE - ENABLE is an expression; the item is enabled for selection - whenever this expression's value is non-nil. `:enable' is an - alias for `:active'. - - :visible INCLUDE - INCLUDE is an expression; this item is only visible if this - expression has a non-nil value. `:included' is an alias for - `:visible'. - - :label FORM - FORM is an expression that is dynamically evaluated and whose - value serves as the menu item's label (the default is NAME). - - :suffix FORM - FORM is an expression that is dynamically evaluated and whose - value is concatenated with the menu entry's label. - - :style STYLE - STYLE is a symbol describing the type of menu item; it should - be `toggle' (a checkbox), or `radio' (a radio button), or any - other value (meaning an ordinary menu item). - - :selected SELECTED - SELECTED is an expression; the checkbox or radio button is - selected whenever the expression's value is non-nil. - - :help HELP - HELP is a string, the help to display for the menu item. - -Alternatively, a menu item can be a string. Then that string -appears in the menu as unselectable text. A string consisting -solely of dashes is displayed as a menu separator. - -Alternatively, a menu item can be a list with the same format as -MENU. This is a submenu. - -\(fn SYMBOL MAPS DOC MENU)" nil t) - -(function-put 'easy-menu-define 'lisp-indent-function 'defun) - -(autoload 'easy-menu-do-define "easymenu" "\ - - -\(fn SYMBOL MAPS DOC MENU)" nil nil) - -(autoload 'easy-menu-create-menu "easymenu" "\ -Create a menu called MENU-NAME with items described in MENU-ITEMS. -MENU-NAME is a string, the name of the menu. MENU-ITEMS is a list of items -possibly preceded by keyword pairs as described in `easy-menu-define'. - -\(fn MENU-NAME MENU-ITEMS)" nil nil) - -(autoload 'easy-menu-change "easymenu" "\ -Change menu found at PATH as item NAME to contain ITEMS. -PATH is a list of strings for locating the menu that -should contain a submenu named NAME. -ITEMS is a list of menu items, as in `easy-menu-define'. -These items entirely replace the previous items in that submenu. - -If MAP is specified, it should normally be a keymap; nil stands for the local -menu-bar keymap. It can also be a symbol, which has earlier been used as the -first argument in a call to `easy-menu-define', or the value of such a symbol. - -If the menu located by PATH has no submenu named NAME, add one. -If the optional argument BEFORE is present, add it just before -the submenu named BEFORE, otherwise add it at the end of the menu. - -To implement dynamic menus, either call this from -`menu-bar-update-hook' or use a menu filter. - -\(fn PATH NAME ITEMS &optional BEFORE MAP)" nil nil) - -(register-definition-prefixes "easymenu" '("add-submenu" "easy-menu-")) - ;;;*** ;;;### (autoloads nil "ebnf-abn" "progmodes/ebnf-abn.el" (0 0 0 0)) @@ -9423,26 +9282,6 @@ an EDE controlled project. ;;;### (autoloads nil "edebug" "emacs-lisp/edebug.el" (0 0 0 0)) ;;; Generated autoloads from emacs-lisp/edebug.el -(defvar edebug-all-defs nil "\ -If non-nil, evaluating defining forms instruments for Edebug. -This applies to `eval-defun', `eval-region', `eval-buffer', and -`eval-current-buffer'. `eval-region' is also called by -`eval-last-sexp', and `eval-print-last-sexp'. - -You can use the command `edebug-all-defs' to toggle the value of this -variable. You may wish to make it local to each buffer with -\(make-local-variable \\='edebug-all-defs) in your -`emacs-lisp-mode-hook'.") - -(custom-autoload 'edebug-all-defs "edebug" t) - -(defvar edebug-all-forms nil "\ -Non-nil means evaluation of all forms will instrument for Edebug. -This doesn't apply to loading or evaluations in the minibuffer. -Use the command `edebug-all-forms' to toggle the value of this option.") - -(custom-autoload 'edebug-all-forms "edebug" t) - (autoload 'edebug-basic-spec "edebug" "\ Return t if SPEC uses only extant spec symbols. An extant spec symbol is a symbol that is not a function and has a @@ -9476,7 +9315,7 @@ Toggle edebugging of all definitions." t nil) (autoload 'edebug-all-forms "edebug" "\ Toggle edebugging of all forms." t nil) -(register-definition-prefixes "edebug" '("cancel-edebug-on-entry" "edebug" "get-edebug-spec" "global-edebug-")) +(register-definition-prefixes "edebug" '("arglist" "backquote-form" "def-declarations" "edebug" "function-form" "interactive" "lambda-" "name" "nested-backquote-form")) ;;;*** @@ -9498,9 +9337,9 @@ arguments after setting up the Ediff buffers. \(fn FILE-A FILE-B FILE-C &optional STARTUP-HOOKS)" t nil) -(defalias 'ediff3 'ediff-files3) +(defalias 'ediff3 #'ediff-files3) -(defalias 'ediff 'ediff-files) +(defalias 'ediff #'ediff-files) (autoload 'ediff-current-file "ediff" "\ Start ediff between current buffer and its file on disk. @@ -9526,7 +9365,7 @@ symbol describing the Ediff job type; it defaults to \(fn BUFFER-A BUFFER-B &optional STARTUP-HOOKS JOB-NAME)" t nil) -(defalias 'ebuffers 'ediff-buffers) +(defalias 'ebuffers #'ediff-buffers) (autoload 'ediff-buffers3 "ediff" "\ Run Ediff on three buffers, BUFFER-A, BUFFER-B, and BUFFER-C. @@ -9540,7 +9379,7 @@ symbol describing the Ediff job type; it defaults to \(fn BUFFER-A BUFFER-B BUFFER-C &optional STARTUP-HOOKS JOB-NAME)" t nil) -(defalias 'ebuffers3 'ediff-buffers3) +(defalias 'ebuffers3 #'ediff-buffers3) (autoload 'ediff-directories "ediff" "\ Run Ediff on a pair of directories, DIR1 and DIR2, comparing files that have @@ -9549,7 +9388,7 @@ expression; only file names that match the regexp are considered. \(fn DIR1 DIR2 REGEXP)" t nil) -(defalias 'edirs 'ediff-directories) +(defalias 'edirs #'ediff-directories) (autoload 'ediff-directory-revisions "ediff" "\ Run Ediff on a directory, DIR1, comparing its files with their revisions. @@ -9558,7 +9397,7 @@ names. Only the files that are under revision control are taken into account. \(fn DIR1 REGEXP)" t nil) -(defalias 'edir-revisions 'ediff-directory-revisions) +(defalias 'edir-revisions #'ediff-directory-revisions) (autoload 'ediff-directories3 "ediff" "\ Run Ediff on three directories, DIR1, DIR2, and DIR3, comparing files that @@ -9567,7 +9406,7 @@ regular expression; only file names that match the regexp are considered. \(fn DIR1 DIR2 DIR3 REGEXP)" t nil) -(defalias 'edirs3 'ediff-directories3) +(defalias 'edirs3 #'ediff-directories3) (autoload 'ediff-merge-directories "ediff" "\ Run Ediff on a pair of directories, DIR1 and DIR2, merging files that have @@ -9577,7 +9416,7 @@ MERGE-AUTOSTORE-DIR is the directory in which to store merged files. \(fn DIR1 DIR2 REGEXP &optional MERGE-AUTOSTORE-DIR)" t nil) -(defalias 'edirs-merge 'ediff-merge-directories) +(defalias 'edirs-merge #'ediff-merge-directories) (autoload 'ediff-merge-directories-with-ancestor "ediff" "\ Merge files in directories DIR1 and DIR2 using files in ANCESTOR-DIR as ancestors. @@ -9597,7 +9436,7 @@ MERGE-AUTOSTORE-DIR is the directory in which to store merged files. \(fn DIR1 REGEXP &optional MERGE-AUTOSTORE-DIR)" t nil) -(defalias 'edir-merge-revisions 'ediff-merge-directory-revisions) +(defalias 'edir-merge-revisions #'ediff-merge-directory-revisions) (autoload 'ediff-merge-directory-revisions-with-ancestor "ediff" "\ Run Ediff on a directory, DIR1, merging its files with their revisions and ancestors. @@ -9839,7 +9678,7 @@ Call `ediff-merge-directories-with-ancestor' with the next four command line arg (autoload 'ediff-show-registry "ediff-mult" "\ Display Ediff's registry." t nil) -(defalias 'eregistry 'ediff-show-registry) +(defalias 'eregistry #'ediff-show-registry) (register-definition-prefixes "ediff-mult" '("ediff-")) @@ -10866,10 +10705,6 @@ it has to be wrapped in `(eval (quote ...))'. (function-put 'ert-deftest 'lisp-indent-function '2) -(put 'ert-deftest 'lisp-indent-function 2) - -(put 'ert-info 'lisp-indent-function 1) - (autoload 'ert-run-tests-batch "ert" "\ Run the tests specified by SELECTOR, printing results to the terminal. @@ -10916,8 +10751,6 @@ Display the documentation for TEST-OR-TEST-NAME (a symbol or ert-test). ;;;### (autoloads nil "ert-x" "emacs-lisp/ert-x.el" (0 0 0 0)) ;;; Generated autoloads from emacs-lisp/ert-x.el -(put 'ert-with-test-buffer 'lisp-indent-function 1) - (autoload 'ert-kill-all-test-buffers "ert-x" "\ Kill all test buffers that are still live." t nil) @@ -12034,9 +11867,9 @@ INC may be passed as a numeric prefix argument. The actual adjustment made depends on the final component of the key-binding used to invoke the command, with all modifiers removed: - +, = Increase the default face height by one step - - Decrease the default face height by one step - 0 Reset the default face height to the global default + +, = Increase the height of the default face by one step + - Decrease the height of the default face by one step + 0 Reset the height of the default face to the global default After adjusting, continue to read input events and further adjust the face height as long as the input event read @@ -13931,7 +13764,7 @@ regular expression that can be used as an element of ;;;### (autoloads nil "generic-x" "generic-x.el" (0 0 0 0)) ;;; Generated autoloads from generic-x.el -(register-definition-prefixes "generic-x" '("default-generic-mode" "generic-")) +(register-definition-prefixes "generic-x" '("alias-generic-mode" "ansible-inventory-generic-mode" "apache-" "astap-generic-mode" "default-generic-mode" "etc-" "fvwm-generic-mode" "generic-" "hosts-generic-mode" "ibis-generic-mode" "java-" "mail" "named-" "pkginfo-generic-mode" "prototype-generic-mode" "rc-generic-mode" "rul-" "samba-generic-mode" "show-tabs-generic-mode" "spice-generic-mode" "vrml-generic-mode" "x-resource-generic-mode" "xmodmap-generic-mode")) ;;;*** @@ -14190,7 +14023,7 @@ Make the current buffer look like a nice article." nil nil) ;;; Generated autoloads from gnus/gnus-bookmark.el (autoload 'gnus-bookmark-set "gnus-bookmark" "\ -Set a bookmark for this article." t nil) +Set a bookmark for this article." '(gnus-article-mode gnus-summary-mode) nil) (autoload 'gnus-bookmark-jump "gnus-bookmark" "\ Jump to a Gnus bookmark (BMK-NAME). @@ -14296,7 +14129,7 @@ The value of `message-draft-headers' determines which headers are generated when the article is delayed. Remaining headers are generated when the article is sent. -\(fn DELAY)" t nil) +\(fn DELAY)" '(message-mode) nil) (autoload 'gnus-delay-send-queue "gnus-delay" "\ Send all the delayed messages that are due now." t nil) @@ -14440,13 +14273,13 @@ Insert a random Face header from `gnus-face-directory'." nil nil) Display gravatar in the From header. If gravatar is already displayed, remove it. -\(fn &optional FORCE)" t nil) +\(fn &optional FORCE)" '(gnus-article-mode gnus-summary-mode) nil) (autoload 'gnus-treat-mail-gravatar "gnus-gravatar" "\ Display gravatars in the Cc and To headers. If gravatars are already displayed, remove them. -\(fn &optional FORCE)" t nil) +\(fn &optional FORCE)" '(gnus-article-mode gnus-summary-mode) nil) (register-definition-prefixes "gnus-gravatar" '("gnus-gravatar-")) @@ -14724,15 +14557,15 @@ This is typically a function to add in (autoload 'gnus-treat-from-picon "gnus-picon" "\ Display picons in the From header. -If picons are already displayed, remove them." t nil) +If picons are already displayed, remove them." '(gnus-article-mode gnus-summary-mode) nil) (autoload 'gnus-treat-mail-picon "gnus-picon" "\ Display picons in the Cc and To headers. -If picons are already displayed, remove them." t nil) +If picons are already displayed, remove them." '(gnus-article-mode gnus-summary-mode) nil) (autoload 'gnus-treat-newsgroups-picon "gnus-picon" "\ Display picons in the Newsgroups and Followup-To headers. -If picons are already displayed, remove them." t nil) +If picons are already displayed, remove them." '(gnus-article-mode gnus-summary-mode) nil) (register-definition-prefixes "gnus-picon" '("gnus-picon-")) @@ -14864,7 +14697,7 @@ between gnus-sieve-region-start and gnus-sieve-region-end with \(gnus-sieve-script gnus-sieve-select-method gnus-sieve-crosspost). See the documentation for these variables and functions for details." t nil) -(autoload 'gnus-sieve-article-add-rule "gnus-sieve" nil t nil) +(autoload 'gnus-sieve-article-add-rule "gnus-sieve" nil '(gnus-article-mode gnus-summary-mode) nil) (register-definition-prefixes "gnus-sieve" '("gnus-sieve-")) @@ -15472,6 +15305,8 @@ arguments as NAME. DO is a function as defined in `gv-get'. (or (assq 'gv-setter defun-declarations-alist) (push (list 'gv-setter #'gv--setter-defun-declaration) defun-declarations-alist)) +(let ((spec (get 'compiler-macro 'edebug-declaration-spec))) (put 'gv-expander 'edebug-declaration-spec spec) (put 'gv-setter 'edebug-declaration-spec spec)) + (autoload 'gv-define-setter "gv" "\ Define a setter method for generalized variable NAME. This macro is an easy-to-use substitute for `gv-define-expander' that works @@ -15512,7 +15347,7 @@ The return value is the last VAL in the list. \(fn PLACE VAL PLACE VAL ...)" nil t) -(put 'gv-place 'edebug-form-spec 'edebug-match-form) +(def-edebug-elem-spec 'gv-place '(form)) (autoload 'gv-ref "gv" "\ Return a reference to PLACE. @@ -15993,7 +15828,7 @@ Add xrefs for symbols in `pp's output between FROM and TO. (define-obsolete-function-alias 'help-xref-interned 'describe-symbol "25.1") (autoload 'help-bookmark-jump "help-mode" "\ -Jump to help-mode bookmark BOOKMARK. +Jump to `help-mode' bookmark BOOKMARK. Handler function for record returned by `help-bookmark-make-record'. BOOKMARK is a bookmark name or a bookmark record. @@ -17029,7 +16864,7 @@ If optional arg OTHER-WINDOW is non-nil, then use another window. \(fn &optional OTHER-WINDOW)" t nil) -(register-definition-prefixes "ibuffer" '("filename" "ibuffer-" "locked" "mark" "mod" "name" "process" "read-only" "size")) +(register-definition-prefixes "ibuffer" '("filename" "ibuffer-" "locked" "mark" "mod" "name" "process" "read-only" "recency" "size")) ;;;*** @@ -18192,7 +18027,7 @@ element should come before the second. The arguments are cons cells; (custom-autoload 'imenu-sort-function "imenu" t) -(defvar imenu-generic-expression nil "\ +(defvar-local imenu-generic-expression nil "\ List of definition matchers for creating an Imenu index. Each element of this list should have the form @@ -18228,9 +18063,7 @@ characters which normally have \"symbol\" syntax are considered to have \"word\" syntax during matching.") (put 'imenu-generic-expression 'risky-local-variable t) -(make-variable-buffer-local 'imenu-generic-expression) - -(defvar imenu-create-index-function 'imenu-default-create-index-function "\ +(defvar-local imenu-create-index-function 'imenu-default-create-index-function "\ The function to use for creating an index alist of the current buffer. It should be a function that takes no arguments and returns @@ -18239,9 +18072,7 @@ called within a `save-excursion'. See `imenu--index-alist' for the format of the buffer index alist.") -(make-variable-buffer-local 'imenu-create-index-function) - -(defvar imenu-prev-index-position-function 'beginning-of-defun "\ +(defvar-local imenu-prev-index-position-function 'beginning-of-defun "\ Function for finding the next index position. If `imenu-create-index-function' is set to @@ -18252,18 +18083,14 @@ file. The function should leave point at the place to be connected to the index and it should return nil when it doesn't find another index.") -(make-variable-buffer-local 'imenu-prev-index-position-function) - -(defvar imenu-extract-index-name-function nil "\ +(defvar-local imenu-extract-index-name-function nil "\ Function for extracting the index item name, given a position. This function is called after `imenu-prev-index-position-function' finds a position for an index item, with point at that position. It should return the name for that index item.") -(make-variable-buffer-local 'imenu-extract-index-name-function) - -(defvar imenu-name-lookup-function nil "\ +(defvar-local imenu-name-lookup-function nil "\ Function to compare string with index item. This function will be called with two strings, and should return @@ -18274,18 +18101,28 @@ Set this to some other function for more advanced comparisons, such as \"begins with\" or \"name matches and number of arguments match\".") -(make-variable-buffer-local 'imenu-name-lookup-function) - -(defvar imenu-default-goto-function 'imenu-default-goto-function "\ +(defvar-local imenu-default-goto-function 'imenu-default-goto-function "\ The default function called when selecting an Imenu item. The function in this variable is called when selecting a normal index-item.") - -(make-variable-buffer-local 'imenu-default-goto-function) (put 'imenu--index-alist 'risky-local-variable t) -(make-variable-buffer-local 'imenu-syntax-alist) +(defvar-local imenu-syntax-alist nil "\ +Alist of syntax table modifiers to use while in `imenu--generic-function'. + +The car of the assocs may be either a character or a string and the +cdr is a syntax description appropriate for `modify-syntax-entry'. For +a string, all the characters in the string get the specified syntax. -(make-variable-buffer-local 'imenu-case-fold-search) +This is typically used to give word syntax to characters which +normally have symbol syntax to simplify `imenu-expression' +and speed-up matching.") + +(defvar-local imenu-case-fold-search t "\ +Defines whether `imenu--generic-function' should fold case when matching. + +This variable should be set (only) by initialization code +for modes which use `imenu--generic-function'. If it is not set, but +`font-lock-defaults' is set, then font-lock's setting is used.") (autoload 'imenu-add-to-menubar "imenu" "\ Add an `imenu' entry to the menu bar for the current buffer. @@ -20685,7 +20522,7 @@ to auto-complete your input based on the installed manual pages. (autoload 'man-follow "man" "\ Get a Un*x manual page of the item under point and put it in a buffer. -\(fn MAN-ARGS)" t nil) +\(fn MAN-ARGS)" '(man-common) nil) (autoload 'Man-bookmark-jump "man" "\ Default bookmark handler for Man buffers. @@ -20922,9 +20759,12 @@ which specify the range to operate on. Command to parse command line mailto: links. This is meant to be used for MIME handlers: Setting the handler for \"x-scheme-handler/mailto;\" to \"emacs -f message-mailto %u\" -will then start up Emacs ready to compose mail." t nil) +will then start up Emacs ready to compose mail. For emacsclient use + emacsclient -e '(message-mailto \"%u\")' -(register-definition-prefixes "message" '("message-" "nil")) +\(fn &optional URL)" t nil) + +(register-definition-prefixes "message" '("message-")) ;;;*** @@ -22202,7 +22042,8 @@ This affects the implicit sorting of lists of coding systems returned by operations such as `find-coding-systems-region'. \(fn CODING-SYSTEMS &rest BODY)" nil t) -(put 'with-coding-priority 'lisp-indent-function 1) + +(function-put 'with-coding-priority 'lisp-indent-function '1) (autoload 'detect-coding-with-language-environment "mule-util" "\ Detect a coding system for the text between FROM and TO with LANG-ENV. @@ -24585,7 +24426,6 @@ PATTERN matches. PATTERN can take one of the forms: (pred (not FUN)) matches if FUN called on EXPVAL returns nil. (app FUN PAT) matches if FUN called on EXPVAL matches PAT. (guard BOOLEXP) matches if BOOLEXP evaluates to non-nil. - (let PAT EXPR) matches if EXPR matches PAT. (and PAT...) matches if all the patterns match. (or PAT...) matches if any of the patterns matches. @@ -24595,7 +24435,7 @@ FUN in `pred' and `app' can take one of the forms: (F ARG1 .. ARGn) call F with ARG1..ARGn and EXPVAL as n+1'th argument -FUN, BOOLEXP, EXPR, and subsequent PAT can refer to variables +FUN, BOOLEXP, and subsequent PAT can refer to variables bound earlier in the pattern by a SYMBOL pattern. Additional patterns can be defined using `pcase-defmacro'. @@ -27428,6 +27268,34 @@ recently executed command not bound to an input event\". \(fn REPEAT-ARG)" t nil) +(defvar repeat-mode nil "\ +Non-nil if Repeat mode is enabled. +See the `repeat-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `repeat-mode'.") + +(custom-autoload 'repeat-mode "repeat" nil) + +(autoload 'repeat-mode "repeat" "\ +Toggle Repeat mode. +When Repeat mode is enabled, and the command symbol has the property named +`repeat-map', this map is activated temporarily for the next command. + +If called interactively, toggle `Repeat mode'. If the prefix argument +is positive, enable the mode, and if it is zero or negative, disable +the mode. + +If called from Lisp, toggle the mode if ARG is `toggle'. Enable the +mode if ARG is nil, omitted, or is a positive number. Disable the +mode if ARG is a negative number. + +The mode's hook is called both when the mode is enabled and when it is +disabled. + +\(fn &optional ARG)" t nil) + (register-definition-prefixes "repeat" '("repeat-")) ;;;*** @@ -28269,7 +28137,7 @@ Major mode for editing Ruby code. ;;;### (autoloads nil "ruler-mode" "ruler-mode.el" (0 0 0 0)) ;;; Generated autoloads from ruler-mode.el -(defvar ruler-mode nil "\ +(defvar-local ruler-mode nil "\ Non-nil if Ruler mode is enabled. Use the command `ruler-mode' to change this variable.") @@ -29433,6 +29301,12 @@ Equality is defined by TESTFN if non-nil or by `equal' if nil. \(fn SEQUENCE ELT &optional TESTFN)" nil nil) +(autoload 'seq-intersection "seq" "\ +Return a list of the elements that appear in both SEQUENCE1 and SEQUENCE2. +Equality is defined by TESTFN if non-nil or by `equal' if nil. + +\(fn SEQUENCE1 SEQUENCE2 &optional TESTFN)" nil nil) + (autoload 'seq-group-by "seq" "\ Apply FUNCTION to each element of SEQUENCE. Separate the elements of SEQUENCE into an alist using the results as @@ -31785,9 +31659,7 @@ disabled. \(fn &optional ARG)" t nil) -(defvar tab-line-exclude nil) - -(make-variable-buffer-local 'tab-line-exclude) +(defvar-local tab-line-exclude nil) (put 'global-tab-line-mode 'globalized-minor-mode t) @@ -35515,6 +35387,22 @@ first backend that could register the file is used. \(fn &optional VC-FILESET COMMENT)" t nil) +(autoload 'vc-ignore "vc" "\ +Ignore FILE under the VCS of DIRECTORY. + +Normally, FILE is a wildcard specification that matches the files +to be ignored. When REMOVE is non-nil, remove FILE from the list +of ignored files. + +DIRECTORY defaults to `default-directory' and is used to +determine the responsible VC backend. + +When called interactively, prompt for a FILE to ignore, unless a +prefix argument is given, in which case prompt for a file FILE to +remove from the list of ignored files. + +\(fn FILE &optional DIRECTORY REMOVE)" t nil) + (autoload 'vc-version-diff "vc" "\ Report diffs between revisions REV1 and REV2 in the repository history. This compares two revisions of the current fileset. @@ -36139,7 +36027,7 @@ Key bindings: ;;;### (autoloads nil "verilog-mode" "progmodes/verilog-mode.el" ;;;;;; (0 0 0 0)) ;;; Generated autoloads from progmodes/verilog-mode.el -(push (purecopy '(verilog-mode 2020 6 27 14326051)) package--builtin-versions) +(push (purecopy '(verilog-mode 2021 2 2 263931197)) package--builtin-versions) (autoload 'verilog-mode "verilog-mode" "\ Major mode for editing Verilog code. @@ -36888,13 +36776,11 @@ If nil, make an icon of the frame. If non-nil, delete the frame.") (custom-autoload 'view-remove-frame-by-deleting "view" t) -(defvar view-mode nil "\ +(defvar-local view-mode nil "\ Non-nil if View mode is enabled. Don't change this variable directly, you must change it by one of the functions that enable or disable view mode.") -(make-variable-buffer-local 'view-mode) - (autoload 'kill-buffer-if-not-modified "view" "\ Like `kill-buffer', but does nothing if the buffer is modified. @@ -38476,12 +38362,12 @@ Zone out, completely." t nil) ;;;;;; "cus-face.el" "cus-start.el" "custom.el" "dired-aux.el" "dired-x.el" ;;;;;; "electric.el" "emacs-lisp/backquote.el" "emacs-lisp/byte-run.el" ;;;;;; "emacs-lisp/cl-extra.el" "emacs-lisp/cl-macs.el" "emacs-lisp/cl-preloaded.el" -;;;;;; "emacs-lisp/cl-seq.el" "emacs-lisp/eieio-compat.el" "emacs-lisp/eieio-custom.el" -;;;;;; "emacs-lisp/eieio-opt.el" "emacs-lisp/float-sup.el" "emacs-lisp/lisp-mode.el" -;;;;;; "emacs-lisp/lisp.el" "emacs-lisp/macroexp.el" "emacs-lisp/map-ynp.el" -;;;;;; "emacs-lisp/nadvice.el" "emacs-lisp/syntax.el" "emacs-lisp/timer.el" -;;;;;; "env.el" "epa-hook.el" "erc/erc-autoaway.el" "erc/erc-button.el" -;;;;;; "erc/erc-capab.el" "erc/erc-dcc.el" "erc/erc-desktop-notifications.el" +;;;;;; "emacs-lisp/cl-seq.el" "emacs-lisp/easymenu.el" "emacs-lisp/eieio-compat.el" +;;;;;; "emacs-lisp/eieio-custom.el" "emacs-lisp/eieio-opt.el" "emacs-lisp/float-sup.el" +;;;;;; "emacs-lisp/lisp-mode.el" "emacs-lisp/lisp.el" "emacs-lisp/macroexp.el" +;;;;;; "emacs-lisp/map-ynp.el" "emacs-lisp/nadvice.el" "emacs-lisp/syntax.el" +;;;;;; "emacs-lisp/timer.el" "env.el" "epa-hook.el" "erc/erc-autoaway.el" +;;;;;; "erc/erc-button.el" "erc/erc-capab.el" "erc/erc-dcc.el" "erc/erc-desktop-notifications.el" ;;;;;; "erc/erc-ezbounce.el" "erc/erc-fill.el" "erc/erc-identd.el" ;;;;;; "erc/erc-imenu.el" "erc/erc-join.el" "erc/erc-list.el" "erc/erc-log.el" ;;;;;; "erc/erc-match.el" "erc/erc-menu.el" "erc/erc-netsplit.el" commit 8c93becb35dc387ec307f54406324593b1af1975 Author: Glenn Morris Date: Mon Mar 1 06:13:59 2021 -0800 ; Auto-commit of loaddefs files. diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index f0dc2680d3..a54a447340 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -12149,9 +12149,9 @@ INC may be passed as a numeric prefix argument. The actual adjustment made depends on the final component of the key-binding used to invoke the command, with all modifiers removed: - +, = Increase the default face height by one step - - Decrease the default face height by one step - 0 Reset the default face height to the global default + +, = Increase the height of the default face by one step + - Decrease the height of the default face by one step + 0 Reset the height of the default face to the global default After adjusting, continue to read input events and further adjust the face height as long as the input event read @@ -38652,19 +38652,10 @@ Zone out, completely." t nil) ;;;;;; "eshell/em-unix.el" "eshell/em-xtra.el" "facemenu.el" "faces.el" ;;;;;; "files.el" "font-core.el" "font-lock.el" "format.el" "frame.el" ;;;;;; "help.el" "hfy-cmap.el" "ibuf-ext.el" "indent.el" "international/characters.el" -;;;;;; "international/charprop.el" "international/charscript.el" -;;;;;; "international/cp51932.el" "international/eucjp-ms.el" "international/mule-cmds.el" -;;;;;; "international/mule-conf.el" "international/mule.el" "international/uni-bidi.el" -;;;;;; "international/uni-brackets.el" "international/uni-category.el" -;;;;;; "international/uni-combining.el" "international/uni-comment.el" -;;;;;; "international/uni-decimal.el" "international/uni-decomposition.el" -;;;;;; "international/uni-digit.el" "international/uni-lowercase.el" -;;;;;; "international/uni-mirrored.el" "international/uni-name.el" -;;;;;; "international/uni-numeric.el" "international/uni-old-name.el" -;;;;;; "international/uni-special-lowercase.el" "international/uni-special-titlecase.el" -;;;;;; "international/uni-special-uppercase.el" "international/uni-titlecase.el" -;;;;;; "international/uni-uppercase.el" "isearch.el" "jit-lock.el" -;;;;;; "jka-cmpr-hook.el" "language/burmese.el" "language/cham.el" +;;;;;; "international/charscript.el" "international/cp51932.el" +;;;;;; "international/eucjp-ms.el" "international/mule-cmds.el" +;;;;;; "international/mule-conf.el" "international/mule.el" "isearch.el" +;;;;;; "jit-lock.el" "jka-cmpr-hook.el" "language/burmese.el" "language/cham.el" ;;;;;; "language/chinese.el" "language/cyrillic.el" "language/czech.el" ;;;;;; "language/english.el" "language/ethiopic.el" "language/european.el" ;;;;;; "language/georgian.el" "language/greek.el" "language/hebrew.el" commit 70514c6374f8432c34d345216b4df6cf37151d9a Author: Matt Armstrong Date: Mon Mar 1 14:26:21 2021 +0100 Clean up obsolete comment * src/marker.c (unchain_marker): Clean up obsolete comment (bug#46836). Commit cf3164523b (* src/alloc.c: Avoid O(N²) complexity when unchaining markers (bug#24548)., 2018-03-23) removed the call from GC into unchain_marker, so there is no need to warn about it. diff --git a/src/marker.c b/src/marker.c index 5979151317..2b137b14c8 100644 --- a/src/marker.c +++ b/src/marker.c @@ -634,16 +634,15 @@ set_marker_restricted_both (Lisp_Object marker, Lisp_Object buffer, /* Detach a marker so that it no longer points anywhere and no longer slows down editing. Do not free the marker, though, as a change function could have inserted it into an undo list (Bug#30931). */ + void detach_marker (Lisp_Object marker) { Fset_marker (marker, Qnil, Qnil); } -/* Remove MARKER from the chain of whatever buffer it is in, - leaving it points to nowhere. This is called during garbage - collection, so we must be careful to ignore and preserve - mark bits, including those in chain fields of markers. */ +/* Remove MARKER from the chain of whatever buffer it is in. Set its + buffer NULL. */ void unchain_marker (register struct Lisp_Marker *marker) commit eb2a1e1d6c813156cbaa835bde29499f7605ea08 Author: F. Jason Park Date: Mon Mar 1 14:04:39 2021 +0100 Fix Bootstring skew parameter in puny.el * lisp/net/puny.el: change puny-skew to match value given in RFC3492. * test/lisp/net/puny-tests.el (puny-test-encode-domain) (puny-test-decode-domain): add regression case for popular domain. (bug#46838). diff --git a/lisp/net/puny.el b/lisp/net/puny.el index 6b3663a5fb..1cdefc08f0 100644 --- a/lisp/net/puny.el +++ b/lisp/net/puny.el @@ -75,7 +75,7 @@ For instance \"xn--bcher-kva\" => \"bücher\"." (defconst puny-damp 700) (defconst puny-tmin 1) (defconst puny-tmax 26) -(defconst puny-skew 28) +(defconst puny-skew 38) ;; 0-25 a-z ;; 26-36 0-9 diff --git a/test/lisp/net/puny-tests.el b/test/lisp/net/puny-tests.el index b37168f5ca..28c0d49cbe 100644 --- a/test/lisp/net/puny-tests.el +++ b/test/lisp/net/puny-tests.el @@ -39,10 +39,12 @@ (should (string= (puny-decode-string "xn--9dbdkw") "חנוך"))) (ert-deftest puny-test-encode-domain () - (should (string= (puny-encode-domain "åäö.se") "xn--4cab6c.se"))) + (should (string= (puny-encode-domain "åäö.se") "xn--4cab6c.se")) + (should (string= (puny-encode-domain "яндекс.рф") "xn--d1acpjx3f.xn--p1ai"))) (ert-deftest puny-test-decode-domain () - (should (string= (puny-decode-domain "xn--4cab6c.se") "åäö.se"))) + (should (string= (puny-decode-domain "xn--4cab6c.se") "åäö.se")) + (should (string= (puny-decode-domain "xn--d1acpjx3f.xn--p1ai") "яндекс.рф"))) (ert-deftest puny-highly-restrictive-domain-p () (should (puny-highly-restrictive-domain-p "foo.bar.org")) commit 5684f7995d07496fea4c38133dda81ee93ec9948 Author: Stefan Kangas Date: Mon Mar 1 04:21:11 2021 +0100 Convert various menus to easymenu * lisp/emacs-lisp/lisp-mode.el (lisp-mode-map): Move menu from here... (lisp-mode-menu): ...to here, and convert to easymenu. * lisp/progmodes/elisp-mode.el (lisp-interaction-mode-map): Move menu definition from here... (lisp-interaction-mode-menu): ...to here, and convert to easymenu. * lisp/replace.el (occur-menu-map): Convert to easymenu. diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 54089c4bc6..257ac7412e 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -740,25 +740,24 @@ font-lock keywords will not be case sensitive." ;;; Generic Lisp mode. (defvar lisp-mode-map - (let ((map (make-sparse-keymap)) - (menu-map (make-sparse-keymap "Lisp"))) + (let ((map (make-sparse-keymap))) (set-keymap-parent map lisp-mode-shared-map) (define-key map "\e\C-x" 'lisp-eval-defun) (define-key map "\C-c\C-z" 'run-lisp) - (bindings--define-key map [menu-bar lisp] (cons "Lisp" menu-map)) - (bindings--define-key menu-map [run-lisp] - '(menu-item "Run inferior Lisp" run-lisp - :help "Run an inferior Lisp process, input and output via buffer `*inferior-lisp*'")) - (bindings--define-key menu-map [ev-def] - '(menu-item "Eval defun" lisp-eval-defun - :help "Send the current defun to the Lisp process made by M-x run-lisp")) - (bindings--define-key menu-map [ind-sexp] - '(menu-item "Indent sexp" indent-sexp - :help "Indent each line of the list starting just after point")) map) "Keymap for ordinary Lisp mode. All commands in `lisp-mode-shared-map' are inherited by this map.") +(easy-menu-define lisp-mode-menu lisp-mode-map + "Menu for ordinary Lisp mode." + '("Lisp" + ["Indent sexp" indent-sexp + :help "Indent each line of the list starting just after point"] + ["Eval defun" lisp-eval-defun + :help "Send the current defun to the Lisp process made by M-x run-lisp"] + ["Run inferior Lisp" run-lisp + :help "Run an inferior Lisp process, input and output via buffer `*inferior-lisp*'"])) + (define-derived-mode lisp-mode lisp-data-mode "Lisp" "Major mode for editing Lisp code for Lisps other than GNU Emacs Lisp. Commands: diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index cfc8d8fcf8..cdf60859d0 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -893,35 +893,31 @@ non-nil result supersedes the xrefs produced by ;;; Elisp Interaction mode (defvar lisp-interaction-mode-map - (let ((map (make-sparse-keymap)) - (menu-map (make-sparse-keymap "Lisp-Interaction"))) + (let ((map (make-sparse-keymap))) (set-keymap-parent map lisp-mode-shared-map) (define-key map "\e\C-x" 'eval-defun) (define-key map "\e\C-q" 'indent-pp-sexp) (define-key map "\e\t" 'completion-at-point) (define-key map "\n" 'eval-print-last-sexp) - (bindings--define-key map [menu-bar lisp-interaction] - (cons "Lisp-Interaction" menu-map)) - (bindings--define-key menu-map [eval-defun] - '(menu-item "Evaluate Defun" eval-defun - :help "Evaluate the top-level form containing point, or after point")) - (bindings--define-key menu-map [eval-print-last-sexp] - '(menu-item "Evaluate and Print" eval-print-last-sexp - :help "Evaluate sexp before point; print value into current buffer")) - (bindings--define-key menu-map [edebug-defun-lisp-interaction] - '(menu-item "Instrument Function for Debugging" edebug-defun - :help "Evaluate the top level form point is in, stepping through with Edebug" - :keys "C-u C-M-x")) - (bindings--define-key menu-map [indent-pp-sexp] - '(menu-item "Indent or Pretty-Print" indent-pp-sexp - :help "Indent each line of the list starting just after point, or prettyprint it")) - (bindings--define-key menu-map [complete-symbol] - '(menu-item "Complete Lisp Symbol" completion-at-point - :help "Perform completion on Lisp symbol preceding point")) map) "Keymap for Lisp Interaction mode. All commands in `lisp-mode-shared-map' are inherited by this map.") +(easy-menu-define lisp-interaction-mode-menu lisp-interaction-mode-map + "Menu for Lisp Interaction mode." + '("Lisp-Interaction" + ["Complete Lisp Symbol" completion-at-point + :help "Perform completion on Lisp symbol preceding point"] + ["Indent or Pretty-Print" indent-pp-sexp + :help "Indent each line of the list starting just after point, or prettyprint it"] + ["Instrument Function for Debugging" edebug-defun + :help "Evaluate the top level form point is in, stepping through with Edebug" + :keys "C-u C-M-x"] + ["Evaluate and Print" eval-print-last-sexp + :help "Evaluate sexp before point; print value into current buffer"] + ["Evaluate Defun" eval-defun + :help "Evaluate the top-level form containing point, or after point"])) + (define-derived-mode lisp-interaction-mode emacs-lisp-mode "Lisp Interaction" "Major mode for typing and evaluating Lisp forms. Like Lisp mode except that \\[eval-print-last-sexp] evals the Lisp expression diff --git a/lisp/replace.el b/lisp/replace.el index eb7a439b54..f131d263ec 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -1104,51 +1104,39 @@ a previously found match." count))) -(defvar occur-menu-map - (let ((map (make-sparse-keymap))) - (bindings--define-key map [next-error-follow-minor-mode] - '(menu-item "Auto Occurrence Display" - next-error-follow-minor-mode - :help "Display another occurrence when moving the cursor" - :button (:toggle . (and (boundp 'next-error-follow-minor-mode) - next-error-follow-minor-mode)))) - (bindings--define-key map [separator-1] menu-bar-separator) - (bindings--define-key map [kill-this-buffer] - '(menu-item "Kill Occur Buffer" kill-this-buffer - :help "Kill the current *Occur* buffer")) - (bindings--define-key map [quit-window] - '(menu-item "Quit Occur Window" quit-window - :help "Quit the current *Occur* buffer. Bury it, and maybe delete the selected frame")) - (bindings--define-key map [revert-buffer] - '(menu-item "Revert Occur Buffer" revert-buffer - :help "Replace the text in the *Occur* buffer with the results of rerunning occur")) - (bindings--define-key map [clone-buffer] - '(menu-item "Clone Occur Buffer" clone-buffer - :help "Create and return a twin copy of the current *Occur* buffer")) - (bindings--define-key map [occur-rename-buffer] - '(menu-item "Rename Occur Buffer" occur-rename-buffer - :help "Rename the current *Occur* buffer to *Occur: original-buffer-name*.")) - (bindings--define-key map [occur-edit-buffer] - '(menu-item "Edit Occur Buffer" occur-edit-mode - :help "Edit the *Occur* buffer and apply changes to the original buffers.")) - (bindings--define-key map [separator-2] menu-bar-separator) - (bindings--define-key map [occur-mode-goto-occurrence-other-window] - '(menu-item "Go To Occurrence Other Window" occur-mode-goto-occurrence-other-window - :help "Go to the occurrence the current line describes, in another window")) - (bindings--define-key map [occur-mode-goto-occurrence] - '(menu-item "Go To Occurrence" occur-mode-goto-occurrence - :help "Go to the occurrence the current line describes")) - (bindings--define-key map [occur-mode-display-occurrence] - '(menu-item "Display Occurrence" occur-mode-display-occurrence - :help "Display in another window the occurrence the current line describes")) - (bindings--define-key map [occur-next] - '(menu-item "Move to Next Match" occur-next - :help "Move to the Nth (default 1) next match in an Occur mode buffer")) - (bindings--define-key map [occur-prev] - '(menu-item "Move to Previous Match" occur-prev - :help "Move to the Nth (default 1) previous match in an Occur mode buffer")) - map) - "Menu keymap for `occur-mode'.") +(easy-menu-define occur-menu-map nil + "Menu for `occur-mode'." + '("Occur" + ["Move to Previous Match" occur-prev + :help "Move to the Nth (default 1) previous match in an Occur mode buffer"] + ["Move to Next Match" occur-next + :help "Move to the Nth (default 1) next match in an Occur mode buffer"] + ["Display Occurrence" occur-mode-display-occurrence + :help "Display in another window the occurrence the current line describes"] + ["Go To Occurrence" occur-mode-goto-occurrence + :help "Go to the occurrence the current line describes"] + ["Go To Occurrence Other Window" occur-mode-goto-occurrence-other-window + :help "Go to the occurrence the current line describes, in another window"] + "---" + ["Edit Occur Buffer" occur-edit-mode + :help "Edit the *Occur* buffer and apply changes to the original buffers."] + ["Rename Occur Buffer" occur-rename-buffer + :help "Rename the current *Occur* buffer to *Occur: original-buffer-name*."] + ["Clone Occur Buffer" clone-buffer + :help "Create and return a twin copy of the current *Occur* buffer"] + ["Revert Occur Buffer" revert-buffer + :help "Replace the text in the *Occur* buffer with the results of rerunning occur"] + ["Quit Occur Window" quit-window + :help "Quit the current *Occur* buffer. Bury it, and maybe delete the selected frame"] + ["Kill Occur Buffer" kill-this-buffer + :help "Kill the current *Occur* buffer"] + "---" + ["Auto Occurrence Display" + next-error-follow-minor-mode + :help "Display another occurrence when moving the cursor" + :style toggle + :selected (and (boundp 'next-error-follow-minor-mode) + next-error-follow-minor-mode)])) (defvar occur-mode-map (let ((map (make-sparse-keymap))) commit 8bdaac34579fd270b5ba5403711e626fb03587d0 Author: Glenn Morris Date: Sun Feb 28 18:07:04 2021 -0800 Improve admin.el's Makefile in standalone manual tarfiles * admin/admin.el (make-manuals-dist-output-variables): Fix abs_top_builddir. Add EMACS. (make-manuals-dist--1): Respect case when replacing output variables. diff --git a/admin/admin.el b/admin/admin.el index 704c38d6f9..203cf10687 100644 --- a/admin/admin.el +++ b/admin/admin.el @@ -665,7 +665,8 @@ style=\"text-align:left\">") (defconst make-manuals-dist-output-variables '(("@\\(top_\\)?srcdir@" . ".") ; top_srcdir is wrong, but not used - ("@abs_top_builddir@" . "../../") ; only for in-tree builds + ("@abs_top_builddir@" . ".") ; wrong but unused + ("^\\(EMACS *=\\).*" . "\\1 emacs") ("^\\(\\(?:texinfo\\|buildinfo\\|emacs\\)dir *=\\).*" . "\\1 .") ("^\\(clean:.*\\)" . "\\1 infoclean") ("@MAKEINFO@" . "makeinfo") @@ -715,7 +716,8 @@ style=\"text-align:left\">") (string-match-p "\\.\\(eps\\|pdf\\)\\'" file))) (copy-file file stem))) (with-temp-buffer - (let ((outvars make-manuals-dist-output-variables)) + (let ((outvars make-manuals-dist-output-variables) + (case-fold-search nil)) (push `("@version@" . ,version) outvars) (insert-file-contents (format "../doc/%s/Makefile.in" type)) (dolist (cons outvars) commit 4825ea3c5d067accad1e714531799f1836b548b5 Author: Glenn Morris Date: Sun Feb 28 15:22:29 2021 -0800 info/dir needs generated texi files to exist * Makefile.in (misc-info): Depend on lisp. (${srcdir}/info/dir): Depend on info-real. (info): Simplify. diff --git a/Makefile.in b/Makefile.in index e11b07280c..a69c01b9c5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -999,6 +999,8 @@ info-real: $(INFOS) pdf: $(PDFS) ps: $(PSS) +misc-info: lisp + info-dir: ${srcdir}/info/dir ## Hopefully doc/misc/*.texi is not too long for some systems? @@ -1021,7 +1023,11 @@ info_dir_deps = \ ## FIXME it would be faster to use the install-info program if we have it, ## but then we would need to depend on info-real, which would ## slow down parallelization. -${srcdir}/info/dir: ${info_dir_deps} + +## Now that some texi files are generated, this needs to depend on info. +## Sigh. FIXME: the minimum dependency is "generated doc/misc/*.texi". +## TODO build-aux/make-info-dir could parse org sources directly. +${srcdir}/info/dir: ${info_dir_deps} info-real $(AM_V_at)${MKDIR_P} ${srcdir}/info $(AM_V_GEN)(cd ${srcdir}/doc && \ AWK='${AWK}' ../build-aux/make-info-dir ${info_dir_inputs} \ @@ -1093,10 +1099,11 @@ uninstall-ps: $(UNINSTALL_PS) # Depending on src is sufficient, but ends up being slow, since the # uncompiled lisp/org/*.el files are used to build the .texi files # (which is slow even with the elc files). -info: lisp - ifneq ($(HAVE_MAKEINFO),no) - $(MAKE) info-real info-dir - endif +ifneq ($(HAVE_MAKEINFO),no) +info: info-real info-dir +else +info: +endif ## build-aux/make-info-dir expects only certain dircategories. check-info: info commit 18e1455c8ae851791a047dc56eef972cc24e5b6c Author: Glenn Morris Date: Sun Feb 28 15:13:07 2021 -0800 Make generation of texi from org overwrite output * doc/misc/Makefile.in (org_template): Don't delete output. * lisp/org/ox-texinfo.el (org-texinfo-export-to-texinfo-batch): Overwrite existing output. diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in index 662537b451..060bffa638 100644 --- a/doc/misc/Makefile.in +++ b/doc/misc/Makefile.in @@ -237,7 +237,6 @@ emacs = "${EMACS}" -batch --no-site-file --no-site-lisp # things like org-setup's "version" macro work. Sigh. define org_template $(1:.org=.texi): $(1) - @rm -f $$@ $${AM_V_GEN}cd "$${srcdir}" && $${emacs} -l ox-texinfo \ -f org-texinfo-export-to-texinfo-batch $$(notdir $$<) $$(notdir $$@) endef diff --git a/lisp/org/ox-texinfo.el b/lisp/org/ox-texinfo.el index 78d58beadd..6e8d0d6214 100644 --- a/lisp/org/ox-texinfo.el +++ b/lisp/org/ox-texinfo.el @@ -1629,17 +1629,16 @@ Return output file's name." (defun org-texinfo-export-to-texinfo-batch () "Export Org file INFILE to Texinfo file OUTFILE, in batch mode. +Overwrites existing output file. Usage: emacs -batch -f org-texinfo-export-to-texinfo-batch INFILE OUTFILE" (or noninteractive (user-error "Batch mode use only")) (let ((infile (pop command-line-args-left)) (outfile (pop command-line-args-left)) - (org-export-coding-system org-texinfo-coding-system)) + (org-export-coding-system org-texinfo-coding-system) + (make-backup-files nil)) (unless (file-readable-p infile) (message "File `%s' not readable" infile) (kill-emacs 1)) - (when (file-exists-p outfile) - (message "File `%s' already exists" outfile) - (kill-emacs 1)) (with-temp-buffer (insert-file-contents infile) (org-export-to-file 'texinfo outfile)))) commit 63026d8af38da0a380ef3db40c2a9911fc196e26 Author: Glenn Morris Date: Sun Feb 28 14:27:28 2021 -0800 * doc/misc/modus-themes.org: Add copying markup. (Bug#45141) diff --git a/doc/misc/modus-themes.org b/doc/misc/modus-themes.org index 03cce5bf33..4a6150cf9d 100644 --- a/doc/misc/modus-themes.org +++ b/doc/misc/modus-themes.org @@ -8,6 +8,8 @@ #+MACRO: version-tag 0.13.0 #+MACRO: release-date 2020-10-08 +#+texinfo: @insertcopying + This manual, written by Protesilaos Stavrou, describes the customization options for the =modus-operandi= and =modus-vivendi= themes, and provides every other piece of information pertinent to them. @@ -17,6 +19,11 @@ released on {{{release-date}}}. Any reference to a newer feature which does not yet form part of the latest tagged commit, is explicitly marked as such. +* Copying +:PROPERTIES: +:copying: t +:END: + Copyright (C) 2020--2021 Free Software Foundation, Inc. #+begin_quote commit 19df5e78692f4bf496407c4b93cd580933d90ad7 Author: Glenn Morris Date: Sun Feb 28 14:26:46 2021 -0800 Update admins make-manuals for new output variable * admin/admin.el (make-manuals-dist-output-variables): Add abs_top_builddir. diff --git a/admin/admin.el b/admin/admin.el index d032c1ceb8..704c38d6f9 100644 --- a/admin/admin.el +++ b/admin/admin.el @@ -665,6 +665,7 @@ style=\"text-align:left\">") (defconst make-manuals-dist-output-variables '(("@\\(top_\\)?srcdir@" . ".") ; top_srcdir is wrong, but not used + ("@abs_top_builddir@" . "../../") ; only for in-tree builds ("^\\(\\(?:texinfo\\|buildinfo\\|emacs\\)dir *=\\).*" . "\\1 .") ("^\\(clean:.*\\)" . "\\1 infoclean") ("@MAKEINFO@" . "makeinfo") commit 150d06644ee841badec858ab3aae28e10a160791 Author: Stefan Kangas Date: Sun Feb 28 23:23:41 2021 +0100 Convert dired menus to easymenu * lisp/dired.el (dired-mode-map): Move menus from here... (dired-mode-subdir-menu, dired-mode-immediate-menu) (dired-mode-regexp-menu, dired-mode-mark-menu) (dired-mode-operate-menu): ...to here, and convert to easymenu. diff --git a/lisp/dired.el b/lisp/dired.el index cc006b42e4..11df93ec3b 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -1966,328 +1966,217 @@ Do so according to the former subdir alist OLD-SUBDIR-ALIST." (define-key map ":s" 'epa-dired-do-sign) (define-key map ":e" 'epa-dired-do-encrypt) - ;; Make menu bar items. - ;; No need to do this, now that top-level items are fewer. ;;;; ;; Get rid of the Edit menu bar item to save space. ;(define-key map [menu-bar edit] 'undefined) - (define-key map [menu-bar subdir] - (cons "Subdir" (make-sparse-keymap "Subdir"))) - - (define-key map [menu-bar subdir hide-all] - '(menu-item "Hide All" dired-hide-all - :help "Hide all subdirectories, leave only header lines")) - (define-key map [menu-bar subdir hide-subdir] - '(menu-item "Hide/UnHide Subdir" dired-hide-subdir - :help "Hide or unhide current directory listing")) - (define-key map [menu-bar subdir tree-down] - '(menu-item "Tree Down" dired-tree-down - :help "Go to first subdirectory header down the tree")) - (define-key map [menu-bar subdir tree-up] - '(menu-item "Tree Up" dired-tree-up - :help "Go to first subdirectory header up the tree")) - (define-key map [menu-bar subdir up] - '(menu-item "Up Directory" dired-up-directory - :help "Edit the parent directory")) - (define-key map [menu-bar subdir prev-subdir] - '(menu-item "Prev Subdir" dired-prev-subdir - :help "Go to previous subdirectory header line")) - (define-key map [menu-bar subdir next-subdir] - '(menu-item "Next Subdir" dired-next-subdir - :help "Go to next subdirectory header line")) - (define-key map [menu-bar subdir prev-dirline] - '(menu-item "Prev Dirline" dired-prev-dirline - :help "Move to next directory-file line")) - (define-key map [menu-bar subdir next-dirline] - '(menu-item "Next Dirline" dired-next-dirline - :help "Move to previous directory-file line")) - (define-key map [menu-bar subdir insert] - '(menu-item "Insert This Subdir" dired-maybe-insert-subdir - :help "Insert contents of subdirectory" - :enable (let ((f (dired-get-filename nil t))) - (and f (file-directory-p f))))) - (define-key map [menu-bar immediate] - (cons "Immediate" (make-sparse-keymap "Immediate"))) - - (define-key map - [menu-bar immediate image-dired-dired-display-external] - '(menu-item "Display Image Externally" image-dired-dired-display-external - :help "Display image in external viewer")) - (define-key map - [menu-bar immediate image-dired-dired-display-image] - '(menu-item "Display Image" image-dired-dired-display-image - :help "Display sized image in a separate window")) - (define-key map - [menu-bar immediate image-dired-dired-toggle-marked-thumbs] - '(menu-item "Toggle Image Thumbnails in This Buffer" image-dired-dired-toggle-marked-thumbs - :help "Add or remove image thumbnails in front of marked file names")) - - (define-key map [menu-bar immediate hide-details] - '(menu-item "Hide Details" dired-hide-details-mode - :help "Hide details in buffer" - :button (:toggle . dired-hide-details-mode))) - (define-key map [menu-bar immediate revert-buffer] - '(menu-item "Refresh" revert-buffer - :help "Update contents of shown directories")) - (define-key map [menu-bar immediate dired-number-of-marked-files] - '(menu-item "#Marked Files" dired-number-of-marked-files - :help "Display the number and size of the marked files")) - - (define-key map [menu-bar immediate dashes] - '("--")) - - (define-key map [menu-bar immediate isearch-filenames-regexp] - '(menu-item "Isearch Regexp in File Names..." dired-isearch-filenames-regexp - :help "Incrementally search for regexp in file names only")) - (define-key map [menu-bar immediate isearch-filenames] - '(menu-item "Isearch in File Names..." dired-isearch-filenames - :help "Incrementally search for string in file names only.")) - (define-key map [menu-bar immediate compare-directories] - '(menu-item "Compare Directories..." dired-compare-directories - :help "Mark files with different attributes in two Dired buffers")) - (define-key map [menu-bar immediate backup-diff] - '(menu-item "Compare with Backup" dired-backup-diff - :help "Diff file at cursor with its latest backup")) - (define-key map [menu-bar immediate diff] - '(menu-item "Diff..." dired-diff - :help "Compare file at cursor with another file")) - (define-key map [menu-bar immediate view] - '(menu-item "View This File" dired-view-file - :help "Examine file at cursor in read-only mode")) - (define-key map [menu-bar immediate display] - '(menu-item "Display in Other Window" dired-display-file - :help "Display file at cursor in other window")) - (define-key map [menu-bar immediate find-file-other-window] - '(menu-item "Find in Other Window" dired-find-file-other-window - :help "Edit file at cursor in other window")) - (define-key map [menu-bar immediate find-file] - '(menu-item "Find This File" dired-find-file - :help "Edit file at cursor")) - (define-key map [menu-bar immediate create-directory] - '(menu-item "Create Directory..." dired-create-directory - :help "Create a directory")) - (define-key map [menu-bar immediate create-empty-file] - '(menu-item "Create Empty file..." dired-create-empty-file - :help "Create an empty file")) - (define-key map [menu-bar immediate wdired-mode] - '(menu-item "Edit File Names" wdired-change-to-wdired-mode - :help "Put a Dired buffer in a mode in which filenames are editable" - :keys "C-x C-q" - :filter (lambda (x) (if (eq major-mode 'dired-mode) x)))) - - (define-key map [menu-bar regexp] - (cons "Regexp" (make-sparse-keymap "Regexp"))) - - (define-key map - [menu-bar regexp image-dired-mark-tagged-files] - '(menu-item "Mark From Image Tag..." image-dired-mark-tagged-files - :help "Mark files whose image tags matches regexp")) - - (define-key map [menu-bar regexp dashes-1] - '("--")) - - (define-key map [menu-bar regexp downcase] - '(menu-item "Downcase" dired-downcase - ;; When running on plain MS-DOS, there's only one - ;; letter-case for file names. - :enable (or (not (fboundp 'msdos-long-file-names)) - (msdos-long-file-names)) - :help "Rename marked files to lower-case name")) - (define-key map [menu-bar regexp upcase] - '(menu-item "Upcase" dired-upcase - :enable (or (not (fboundp 'msdos-long-file-names)) - (msdos-long-file-names)) - :help "Rename marked files to upper-case name")) - (define-key map [menu-bar regexp hardlink] - '(menu-item "Hardlink..." dired-do-hardlink-regexp - :help "Make hard links for files matching regexp")) - (define-key map [menu-bar regexp symlink] - '(menu-item "Symlink..." dired-do-symlink-regexp - :visible (fboundp 'make-symbolic-link) - :help "Make symbolic links for files matching regexp")) - (define-key map [menu-bar regexp rename] - '(menu-item "Rename..." dired-do-rename-regexp - :help "Rename marked files matching regexp")) - (define-key map [menu-bar regexp copy] - '(menu-item "Copy..." dired-do-copy-regexp - :help "Copy marked files matching regexp")) - (define-key map [menu-bar regexp flag] - '(menu-item "Flag..." dired-flag-files-regexp - :help "Flag files matching regexp for deletion")) - (define-key map [menu-bar regexp mark] - '(menu-item "Mark..." dired-mark-files-regexp - :help "Mark files matching regexp for future operations")) - (define-key map [menu-bar regexp mark-cont] - '(menu-item "Mark Containing..." dired-mark-files-containing-regexp - :help "Mark files whose contents matches regexp")) - - (define-key map [menu-bar mark] - (cons "Mark" (make-sparse-keymap "Mark"))) - - (define-key map [menu-bar mark prev] - '(menu-item "Previous Marked" dired-prev-marked-file - :help "Move to previous marked file")) - (define-key map [menu-bar mark next] - '(menu-item "Next Marked" dired-next-marked-file - :help "Move to next marked file")) - (define-key map [menu-bar mark marks] - '(menu-item "Change Marks..." dired-change-marks - :help "Replace marker with another character")) - (define-key map [menu-bar mark unmark-all] - '(menu-item "Unmark All" dired-unmark-all-marks)) - (define-key map [menu-bar mark symlinks] - '(menu-item "Mark Symlinks" dired-mark-symlinks - :visible (fboundp 'make-symbolic-link) - :help "Mark all symbolic links")) - (define-key map [menu-bar mark directories] - '(menu-item "Mark Directories" dired-mark-directories - :help "Mark all directories except `.' and `..'")) - (define-key map [menu-bar mark directory] - '(menu-item "Mark Old Backups" dired-clean-directory - :help "Flag old numbered backups for deletion")) - (define-key map [menu-bar mark executables] - '(menu-item "Mark Executables" dired-mark-executables - :help "Mark all executable files")) - (define-key map [menu-bar mark garbage-files] - '(menu-item "Flag Garbage Files" dired-flag-garbage-files - :help "Flag unneeded files for deletion")) - (define-key map [menu-bar mark backup-files] - '(menu-item "Flag Backup Files" dired-flag-backup-files - :help "Flag all backup files for deletion")) - (define-key map [menu-bar mark auto-save-files] - '(menu-item "Flag Auto-save Files" dired-flag-auto-save-files - :help "Flag auto-save files for deletion")) - (define-key map [menu-bar mark deletion] - '(menu-item "Flag" dired-flag-file-deletion - :help "Flag current line's file for deletion")) - (define-key map [menu-bar mark unmark] - '(menu-item "Unmark" dired-unmark - :help "Unmark or unflag current line's file")) - (define-key map [menu-bar mark mark] - '(menu-item "Mark" dired-mark - :help "Mark current line's file for future operations")) - (define-key map [menu-bar mark toggle-marks] - '(menu-item "Toggle Marks" dired-toggle-marks - :help "Mark unmarked files, unmark marked ones")) - - (define-key map [menu-bar operate] - (cons "Operate" (make-sparse-keymap "Operate"))) - - (define-key map - [menu-bar operate image-dired-delete-tag] - '(menu-item "Delete Image Tag..." image-dired-delete-tag - :help "Delete image tag from current or marked files")) - (define-key map - [menu-bar operate image-dired-tag-files] - '(menu-item "Add Image Tags..." image-dired-tag-files - :help "Add image tags to current or marked files")) - (define-key map - [menu-bar operate image-dired-dired-comment-files] - '(menu-item "Add Image Comment..." image-dired-dired-comment-files - :help "Add image comment to current or marked files")) - (define-key map - [menu-bar operate image-dired-display-thumbs] - '(menu-item "Display Image Thumbnails" image-dired-display-thumbs - :help "Display image thumbnails for current or marked image files")) - - (define-key map [menu-bar operate dashes-4] - '("--")) - - (define-key map - [menu-bar operate epa-dired-do-decrypt] - '(menu-item "Decrypt..." epa-dired-do-decrypt - :help "Decrypt current or marked files")) - - (define-key map - [menu-bar operate epa-dired-do-verify] - '(menu-item "Verify" epa-dired-do-verify - :help "Verify digital signature of current or marked files")) - - (define-key map - [menu-bar operate epa-dired-do-sign] - '(menu-item "Sign..." epa-dired-do-sign - :help "Create digital signature of current or marked files")) - - (define-key map - [menu-bar operate epa-dired-do-encrypt] - '(menu-item "Encrypt..." epa-dired-do-encrypt - :help "Encrypt current or marked files")) - - (define-key map [menu-bar operate dashes-3] - '("--")) - - (define-key map [menu-bar operate query-replace] - '(menu-item "Query Replace in Files..." dired-do-find-regexp-and-replace - :help "Replace regexp matches in marked files")) - (define-key map [menu-bar operate search] - '(menu-item "Search Files..." dired-do-find-regexp - :help "Search marked files for matches of regexp")) - (define-key map [menu-bar operate isearch-regexp] - '(menu-item "Isearch Regexp Files..." dired-do-isearch-regexp - :help "Incrementally search marked files for regexp")) - (define-key map [menu-bar operate isearch] - '(menu-item "Isearch Files..." dired-do-isearch - :help "Incrementally search marked files for string")) - (define-key map [menu-bar operate chown] - '(menu-item "Change Owner..." dired-do-chown - :visible (not (memq system-type '(ms-dos windows-nt))) - :help "Change the owner of marked files")) - (define-key map [menu-bar operate chgrp] - '(menu-item "Change Group..." dired-do-chgrp - :visible (not (memq system-type '(ms-dos windows-nt))) - :help "Change the group of marked files")) - (define-key map [menu-bar operate chmod] - '(menu-item "Change Mode..." dired-do-chmod - :help "Change mode (attributes) of marked files")) - (define-key map [menu-bar operate touch] - '(menu-item "Change Timestamp..." dired-do-touch - :help "Change timestamp of marked files")) - (define-key map [menu-bar operate load] - '(menu-item "Load" dired-do-load - :help "Load marked Emacs Lisp files")) - (define-key map [menu-bar operate compile] - '(menu-item "Byte-compile" dired-do-byte-compile - :help "Byte-compile marked Emacs Lisp files")) - (define-key map [menu-bar operate compress] - '(menu-item "Compress" dired-do-compress - :help "Compress/uncompress marked files")) - (define-key map [menu-bar operate print] - '(menu-item "Print..." dired-do-print - :help "Ask for print command and print marked files")) - (define-key map [menu-bar operate hardlink] - '(menu-item "Hardlink to..." dired-do-hardlink - :help "Make hard links for current or marked files")) - (define-key map [menu-bar operate symlink] - '(menu-item "Symlink to..." dired-do-symlink - :visible (fboundp 'make-symbolic-link) - :help "Make symbolic links for current or marked files")) - (define-key map [menu-bar operate async-command] - '(menu-item "Asynchronous Shell Command..." dired-do-async-shell-command - :help "Run a shell command asynchronously on current or marked files")) - (define-key map [menu-bar operate command] - '(menu-item "Shell Command..." dired-do-shell-command - :help "Run a shell command on current or marked files")) - (define-key map [menu-bar operate delete] - `(menu-item "Delete" - ,(let ((menu (make-sparse-keymap "Delete"))) - (define-key menu [delete-flagged] - '(menu-item "Delete Flagged Files" dired-do-flagged-delete - :help "Delete all files flagged for deletion (D)")) - (define-key menu [delete-marked] - '(menu-item "Delete Marked (Not Flagged) Files" dired-do-delete - :help "Delete current file or all marked files (excluding flagged files)")) - menu))) - (define-key map [menu-bar operate rename] - '(menu-item "Rename to..." dired-do-rename - :help "Rename current file or move marked files")) - (define-key map [menu-bar operate copy] - '(menu-item "Copy to..." dired-do-copy - :help "Copy current file or all marked files")) - map) "Local keymap for Dired mode buffers.") + +(easy-menu-define dired-mode-subdir-menu dired-mode-map + "Subdir menu for Dired mode." + '("Subdir" + ["Insert This Subdir" dired-maybe-insert-subdir + :help "Insert contents of subdirectory" + :enable (let ((f (dired-get-filename nil t))) + (and f (file-directory-p f)))] + ["Next Dirline" dired-next-dirline + :help "Move to previous directory-file line"] + ["Prev Dirline" dired-prev-dirline + :help "Move to next directory-file line"] + ["Next Subdir" dired-next-subdir + :help "Go to next subdirectory header line"] + ["Prev Subdir" dired-prev-subdir + :help "Go to previous subdirectory header line"] + ["Up Directory" dired-up-directory + :help "Edit the parent directory"] + ["Tree Up" dired-tree-up + :help "Go to first subdirectory header up the tree"] + ["Tree Down" dired-tree-down + :help "Go to first subdirectory header down the tree"] + ["Hide/UnHide Subdir" dired-hide-subdir + :help "Hide or unhide current directory listing"] + ["Hide All" dired-hide-all + :help "Hide all subdirectories, leave only header lines"])) + +(easy-menu-define dired-mode-immediate-menu dired-mode-map + "Immediate menu for Dired mode." + '("Immediate" + ["Edit File Names" wdired-change-to-wdired-mode + :help "Put a Dired buffer in a mode in which filenames are editable" + :keys "C-x C-q" + :filter (lambda (x) (if (eq major-mode 'dired-mode) x))] + ["Create Empty file..." dired-create-empty-file + :help "Create an empty file"] + ["Create Directory..." dired-create-directory + :help "Create a directory"] + ["Find This File" dired-find-file + :help "Edit file at cursor"] + ["Find in Other Window" dired-find-file-other-window + :help "Edit file at cursor in other window"] + ["Display in Other Window" dired-display-file + :help "Display file at cursor in other window"] + ["View This File" dired-view-file + :help "Examine file at cursor in read-only mode"] + ["Diff..." dired-diff + :help "Compare file at cursor with another file"] + ["Compare with Backup" dired-backup-diff + :help "Diff file at cursor with its latest backup"] + ["Compare Directories..." dired-compare-directories + :help "Mark files with different attributes in two Dired buffers"] + ["Isearch in File Names..." dired-isearch-filenames + :help "Incrementally search for string in file names only."] + ["Isearch Regexp in File Names..." dired-isearch-filenames-regexp + :help "Incrementally search for regexp in file names only"] + "---" + ["#Marked Files" dired-number-of-marked-files + :help "Display the number and size of the marked files"] + ["Refresh" revert-buffer + :help "Update contents of shown directories"] + ["Hide Details" dired-hide-details-mode + :help "Hide details in buffer" + :style toggle + :selected dired-hide-details-mode] + ["Toggle Image Thumbnails in This Buffer" image-dired-dired-toggle-marked-thumbs + :help "Add or remove image thumbnails in front of marked file names"] + ["Display Image" image-dired-dired-display-image + :help "Display sized image in a separate window"] + ["Display Image Externally" image-dired-dired-display-external + :help "Display image in external viewer"])) + +(easy-menu-define dired-mode-regexp-menu dired-mode-map + "Regexp menu for Dired mode." + '("Regexp" + ["Mark Containing..." dired-mark-files-containing-regexp + :help "Mark files whose contents matches regexp"] + ["Mark..." dired-mark-files-regexp + :help "Mark files matching regexp for future operations"] + ["Flag..." dired-flag-files-regexp + :help "Flag files matching regexp for deletion"] + ["Copy..." dired-do-copy-regexp + :help "Copy marked files matching regexp"] + ["Rename..." dired-do-rename-regexp + :help "Rename marked files matching regexp"] + ["Symlink..." dired-do-symlink-regexp + :visible (fboundp 'make-symbolic-link) + :help "Make symbolic links for files matching regexp"] + ["Hardlink..." dired-do-hardlink-regexp + :help "Make hard links for files matching regexp"] + ["Upcase" dired-upcase + :enable (or (not (fboundp 'msdos-long-file-names)) + (msdos-long-file-names)) + :help "Rename marked files to upper-case name"] + ["Downcase" dired-downcase + ;; When running on plain MS-DOS, there's only one + ;; letter-case for file names. + :enable (or (not (fboundp 'msdos-long-file-names)) + (msdos-long-file-names)) + :help "Rename marked files to lower-case name"] + "---" + ["Mark From Image Tag..." image-dired-mark-tagged-files + :help "Mark files whose image tags matches regexp"])) + +(easy-menu-define dired-mode-mark-menu dired-mode-map + "Mark menu for Dired mode." + '("Mark" + ["Toggle Marks" dired-toggle-marks + :help "Mark unmarked files, unmark marked ones"] + ["Mark" dired-mark + :help "Mark current line's file for future operations"] + ["Unmark" dired-unmark + :help "Unmark or unflag current line's file"] + ["Flag" dired-flag-file-deletion + :help "Flag current line's file for deletion"] + ["Flag Auto-save Files" dired-flag-auto-save-files + :help "Flag auto-save files for deletion"] + ["Flag Backup Files" dired-flag-backup-files + :help "Flag all backup files for deletion"] + ["Flag Garbage Files" dired-flag-garbage-files + :help "Flag unneeded files for deletion"] + ["Mark Executables" dired-mark-executables + :help "Mark all executable files"] + ["Mark Old Backups" dired-clean-directory + :help "Flag old numbered backups for deletion"] + ["Mark Directories" dired-mark-directories + :help "Mark all directories except `.' and `..'"] + ["Mark Symlinks" dired-mark-symlinks + :visible (fboundp 'make-symbolic-link) + :help "Mark all symbolic links"] + ["Unmark All" dired-unmark-all-marks] + ["Change Marks..." dired-change-marks + :help "Replace marker with another character"] + ["Next Marked" dired-next-marked-file + :help "Move to next marked file"] + ["Previous Marked" dired-prev-marked-file + :help "Move to previous marked file"])) + +(easy-menu-define dired-mode-operate-menu dired-mode-map + "Operate menu for Dired mode." + '("Operate" + ["Copy to..." dired-do-copy + :help "Copy current file or all marked files"] + ["Rename to..." dired-do-rename + :help "Rename current file or move marked files"] + ("Delete" + ["Delete Flagged Files" dired-do-flagged-delete + :help "Delete all files flagged for deletion (D)"] + ["Delete Marked (Not Flagged) Files" dired-do-delete + :help "Delete current file or all marked files (excluding flagged files)"]) + ["Shell Command..." dired-do-shell-command + :help "Run a shell command on current or marked files"] + ["Asynchronous Shell Command..." dired-do-async-shell-command + :help "Run a shell command asynchronously on current or marked files"] + ["Symlink to..." dired-do-symlink + :visible (fboundp 'make-symbolic-link) + :help "Make symbolic links for current or marked files"] + ["Hardlink to..." dired-do-hardlink + :help "Make hard links for current or marked files"] + ["Print..." dired-do-print + :help "Ask for print command and print marked files"] + ["Compress" dired-do-compress + :help "Compress/uncompress marked files"] + ["Byte-compile" dired-do-byte-compile + :help "Byte-compile marked Emacs Lisp files"] + ["Load" dired-do-load + :help "Load marked Emacs Lisp files"] + ["Change Timestamp..." dired-do-touch + :help "Change timestamp of marked files"] + ["Change Mode..." dired-do-chmod + :help "Change mode (attributes) of marked files"] + ["Change Group..." dired-do-chgrp + :visible (not (memq system-type '(ms-dos windows-nt))) + :help "Change the group of marked files"] + ["Change Owner..." dired-do-chown + :visible (not (memq system-type '(ms-dos windows-nt))) + :help "Change the owner of marked files"] + ["Isearch Files..." dired-do-isearch + :help "Incrementally search marked files for string"] + ["Isearch Regexp Files..." dired-do-isearch-regexp + :help "Incrementally search marked files for regexp"] + ["Search Files..." dired-do-find-regexp + :help "Search marked files for matches of regexp"] + ["Query Replace in Files..." dired-do-find-regexp-and-replace + :help "Replace regexp matches in marked files"] + "---" + ["Encrypt..." epa-dired-do-encrypt + :help "Encrypt current or marked files"] + ["Sign..." epa-dired-do-sign + :help "Create digital signature of current or marked files"] + ["Verify" epa-dired-do-verify + :help "Verify digital signature of current or marked files"] + ["Decrypt..." epa-dired-do-decrypt + :help "Decrypt current or marked files"] + "---" + ["Display Image Thumbnails" image-dired-display-thumbs + :help "Display image thumbnails for current or marked image files"] + ["Add Image Comment..." image-dired-dired-comment-files + :help "Add image comment to current or marked files"] + ["Add Image Tags..." image-dired-tag-files + :help "Add image tags to current or marked files"] + ["Delete Image Tag..." image-dired-delete-tag + :help "Delete image tag from current or marked files"])) + ;; Dired mode is suitable only for specially formatted data. (put 'dired-mode 'mode-class 'special) commit c8f19a4af6d90a2d7e580a4621dabc8deffeacd0 Author: Stefan Kangas Date: Sun Feb 28 22:21:39 2021 +0100 Convert hi-lock-menu to easymenu * lisp/hi-lock.el (hi-lock-menu): Convert to easymenu. diff --git a/lisp/hi-lock.el b/lisp/hi-lock.el index 0ad499b4db..68f8cc5054 100644 --- a/lisp/hi-lock.el +++ b/lisp/hi-lock.el @@ -254,39 +254,25 @@ that older functionality. This variable avoids multiple reminders.") Assumption is made if `hi-lock-mode' used in the *scratch* buffer while a library is being loaded.") -(defvar hi-lock-menu - (let ((map (make-sparse-keymap "Hi Lock"))) - (define-key-after map [highlight-regexp] - '(menu-item "Highlight Regexp..." highlight-regexp - :help "Highlight text matching PATTERN (a regexp).")) - - (define-key-after map [highlight-phrase] - '(menu-item "Highlight Phrase..." highlight-phrase - :help "Highlight text matching PATTERN (a regexp processed to match phrases).")) - - (define-key-after map [highlight-lines-matching-regexp] - '(menu-item "Highlight Lines..." highlight-lines-matching-regexp - :help "Highlight lines containing match of PATTERN (a regexp).")) - - (define-key-after map [highlight-symbol-at-point] - '(menu-item "Highlight Symbol at Point" highlight-symbol-at-point - :help "Highlight symbol found near point without prompting.")) - - (define-key-after map [unhighlight-regexp] - '(menu-item "Remove Highlighting..." unhighlight-regexp - :help "Remove previously entered highlighting pattern." - :enable hi-lock-interactive-patterns)) - - (define-key-after map [hi-lock-write-interactive-patterns] - '(menu-item "Patterns to Buffer" hi-lock-write-interactive-patterns - :help "Insert interactively added REGEXPs into buffer at point." - :enable hi-lock-interactive-patterns)) - - (define-key-after map [hi-lock-find-patterns] - '(menu-item "Patterns from Buffer" hi-lock-find-patterns - :help "Use patterns (if any) near top of buffer.")) - map) - "Menu for hi-lock mode.") +(easy-menu-define hi-lock-menu nil + "Menu for hi-lock mode." + '("Hi Lock" + ["Highlight Regexp..." highlight-regexp + :help "Highlight text matching PATTERN (a regexp)."] + ["Highlight Phrase..." highlight-phrase + :help "Highlight text matching PATTERN (a regexp processed to match phrases)."] + ["Highlight Lines..." highlight-lines-matching-regexp + :help "Highlight lines containing match of PATTERN (a regexp)."] + ["Highlight Symbol at Point" highlight-symbol-at-point + :help "Highlight symbol found near point without prompting."] + ["Remove Highlighting..." unhighlight-regexp + :help "Remove previously entered highlighting pattern." + :enable hi-lock-interactive-patterns] + ["Patterns to Buffer" hi-lock-write-interactive-patterns + :help "Insert interactively added REGEXPs into buffer at point." + :enable hi-lock-interactive-patterns] + ["Patterns from Buffer" hi-lock-find-patterns + :help "Use patterns (if any) near top of buffer."])) (defvar hi-lock-map (let ((map (make-sparse-keymap "Hi Lock"))) commit 56a85590766ec8592100db38937d10b096e9ce30 Author: Alan Mackenzie Date: Sun Feb 28 21:15:34 2021 +0000 Combine and reconcile two conflicting entries in NEWS on goto-line-history * etc/NEWS: Amend. * doc/lispref/minibuf.texi (Minibuffer History): Amend the entry about goto-line-history, which is now buffer local only after being so customized. diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index b60775d457..bbc834004b 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -701,8 +701,9 @@ A history list for numbers read by @code{read-number}. @end defvar @defvar goto-line-history -A history list for arguments to @code{goto-line}. This variable is -buffer local. +A history list for arguments to @code{goto-line}. This variable can +be made local in every buffer by customizing the user option +@code{goto-line-history-local}. @end defvar @c Less common: coding-system-history, input-method-history, diff --git a/etc/NEWS b/etc/NEWS index 883c0700ec..3db276165f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -305,10 +305,12 @@ Additionally, the function now accepts a HIST argument which can be used to specify a custom history variable. +++ -** Input history for 'goto-line' is now local to every buffer. -Each buffer will keep a separate history of line numbers used with -'goto-line'. This should help making faster the process of finding -line numbers that were previously jumped to. +** Input history for 'goto-line' can now be made local to every buffer. +In any event, line numbers used with 'goto-line' are kept in their own +history list. This should help make faster the process of finding +line numbers that were previously jumped to. By default, all buffers +share a single history list. To make every buffer have its own +history list, customize the user option 'goto-line-history-local'. +++ ** New command 'goto-line-relative' to use in a narrowed buffer. @@ -352,11 +354,6 @@ trying to be non-destructive. This command opens a new buffer called "*Memory Report*" and gives a summary of where Emacs is using memory currently. -+++ -** The history list for the 'goto-line' command is now a single list -for all buffers by default. You can configure a separate list for -each buffer by customizing the user option 'goto-line-history-local'. - ** Outline +++ commit f8ab343eb93741209953e0d314b7c133bee91dda Author: Mattias Engdegård Date: Sun Feb 28 19:02:15 2021 +0100 Declare more string predicates as pure * lisp/emacs-lisp/byte-opt.el (pure-fns): Treat string>, string-greaterp, string-empty-p, string-blank-p, string-prefix-p and string-suffix-p as pure functions in the compiler. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 9f0ba232a4..b51ba80155 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -1413,7 +1413,8 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") copysign isnan ldexp float logb floor ceiling round truncate ffloor fceiling fround ftruncate - string= string-equal string< string-lessp + string= string-equal string< string-lessp string> string-greaterp + string-empty-p string-blank-p string-prefix-p string-suffix-p string-search consp atom listp nlistp proper-list-p sequencep arrayp vectorp stringp bool-vector-p hash-table-p commit a286e02580cc4daf0e9edfc0086c517a1770dff4 Author: Basil L. Contovounesios Date: Sun Feb 28 16:29:05 2021 +0000 ; Fix process-lines-handling-status docstring. diff --git a/lisp/subr.el b/lisp/subr.el index 0c97c603a6..0b56347399 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2533,10 +2533,10 @@ use `start-file-process'." (defun process-lines-handling-status (program status-handler &rest args) "Execute PROGRAM with ARGS, returning its output as a list of lines. -If STATUS-HANDLER is non-NIL, it must be a function with one +If STATUS-HANDLER is non-nil, it must be a function with one argument, which will be called with the exit status of the program before the output is collected. If STATUS-HANDLER is -NIL, an error is signalled if the program returns with a non-zero +nil, an error is signaled if the program returns with a non-zero exit status." (with-temp-buffer (let ((status (apply #'call-process program nil (current-buffer) nil args))) @@ -2564,7 +2564,7 @@ Also see `process-lines-ignore-status'." "Execute PROGRAM with ARGS, returning its output as a list of lines. The exit status of the program is ignored. Also see `process-lines'." - (apply #'process-lines-handling-status program #'identity args)) + (apply #'process-lines-handling-status program #'ignore args)) (defun process-live-p (process) "Return non-nil if PROCESS is alive. commit 797f0ba2185c2c4cbfc1b733bbaa9402afe152a4 Author: Basil L. Contovounesios Date: Sun Feb 28 15:44:34 2021 +0000 ; Fix dired-switches-in-mode-line defcustom tags. diff --git a/lisp/dired.el b/lisp/dired.el index 4f1c3ded09..cc006b42e4 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -4240,7 +4240,8 @@ Possible values: * `as-is': Show full switches. * Integer: Show only the first N chars of full switches. * Function: Pass `dired-actual-switches' as arg and show result." - :group 'Dired-Plus + :group 'dired + :version "28.1" :type '(choice (const :tag "Indicate by name or date, else full" nil) (const :tag "Show full switches" as-is) commit c537b6384f240a7ab81731a8fb2e759ea2c30e60 Author: Stefan Kangas Date: Sun Feb 28 19:25:17 2021 +0100 Convert ibuffer menus to easymenu * lisp/ibuffer.el (ibuffer-mode-map): Move menu from here... (ibuffer-mode-mark-menu, ibuffer-mode-view-menu): ...to here. Convert to easymenu. (ibuffer-mode--groups-menu-definition): New function. Fix bug where "Kill filter by group named" and "Yank last killed filter group before" was overwritten and never shown in the menu. (ibuffer-mode-groups-popup): Convert to easymenu. (ibuffer-mode-operate-menu): Rename from 'ibuffer-mode-operate-map' and update uses. Convert to easymenu. (ibuffer-mode-operate-map): Make into obsolete alias for above renamed variable. diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el index 6dc1c7ebc2..7939bbb773 100644 --- a/lisp/ibuffer.el +++ b/lisp/ibuffer.el @@ -364,64 +364,6 @@ directory, like `default-directory'." (regexp :tag "From") (regexp :tag "To")))) -(defvar ibuffer-mode-groups-popup - (let ((groups-map (make-sparse-keymap "Filter Groups"))) - ;; Filter groups - - (define-key-after groups-map [filters-to-filter-group] - '(menu-item "Create filter group from current filters..." - ibuffer-filters-to-filter-group - :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers))) - (define-key-after groups-map [forward-filter-group] - '(menu-item "Move point to the next filter group" - ibuffer-forward-filter-group)) - (define-key-after groups-map [backward-filter-group] - '(menu-item "Move point to the previous filter group" - ibuffer-backward-filter-group)) - (define-key-after groups-map [jump-to-filter-group] - '(menu-item "Move point to a specific filter group..." - ibuffer-jump-to-filter-group)) - (define-key-after groups-map [kill-filter-group] - '(menu-item "Kill filter group named..." - ibuffer-kill-filter-group - :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups))) - (define-key-after groups-map [yank-filter-group] - '(menu-item "Yank last killed filter group before..." - ibuffer-yank-filter-group - :enable (and (featurep 'ibuf-ext) ibuffer-filter-group-kill-ring))) - (define-key-after groups-map [pop-filter-group] - '(menu-item "Remove top filter group" - ibuffer-pop-filter-group - :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups))) - (define-key-after groups-map [clear-filter-groups] - '(menu-item "Remove all filter groups" - ibuffer-clear-filter-groups - :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups))) - (define-key-after groups-map [pop-filter-group] - '(menu-item "Decompose filter group..." - ibuffer-pop-filter-group - :help "\"Unmake\" a filter group" - :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups))) - (define-key-after groups-map [save-filter-groups] - '(menu-item "Save current filter groups permanently..." - ibuffer-save-filter-groups - :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups) - :help "Use a mnemonic name to store current filter groups")) - (define-key-after groups-map [switch-to-saved-filter-groups] - '(menu-item "Restore permanently saved filters..." - ibuffer-switch-to-saved-filter-groups - :enable (and (featurep 'ibuf-ext) ibuffer-saved-filter-groups) - :help "Replace current filters with a saved stack")) - (define-key-after groups-map [delete-saved-filter-groups] - '(menu-item "Delete permanently saved filter groups..." - ibuffer-delete-saved-filter-groups - :enable (and (featurep 'ibuf-ext) ibuffer-saved-filter-groups))) - (define-key-after groups-map [set-filter-groups-by-mode] - '(menu-item "Set current filter groups to filter by mode" - ibuffer-set-filter-groups-by-mode)) - - groups-map)) - (defvar ibuffer--filter-map (let ((map (make-sparse-keymap))) (define-key map (kbd "RET") 'ibuffer-filter-by-mode) @@ -588,303 +530,233 @@ directory, like `default-directory'." (define-key map (kbd "C-x 5 RET") 'ibuffer-visit-buffer-other-frame) (define-key map (kbd "/") ibuffer--filter-map) - - (define-key map [menu-bar view] - (cons "View" (make-sparse-keymap "View"))) - - (define-key-after map [menu-bar view visit-buffer] - '(menu-item "View this buffer" ibuffer-visit-buffer)) - (define-key-after map [menu-bar view visit-buffer-other-window] - '(menu-item "View (other window)" ibuffer-visit-buffer-other-window)) - (define-key-after map [menu-bar view visit-buffer-other-frame] - '(menu-item "View (other frame)" ibuffer-visit-buffer-other-frame)) - (define-key-after map [menu-bar view ibuffer-update] - '(menu-item "Update" ibuffer-update - :help "Regenerate the list of buffers")) - (define-key-after map [menu-bar view switch-format] - '(menu-item "Switch display format" ibuffer-switch-format - :help "Toggle between available values of `ibuffer-formats'")) - - (define-key-after map [menu-bar view dashes] - '("--")) - - (define-key-after map [menu-bar view sort] - (cons "Sort" (make-sparse-keymap "Sort"))) - - (define-key-after map [menu-bar view sort do-sort-by-major-mode] - '(menu-item "Sort by major mode" ibuffer-do-sort-by-major-mode)) - (define-key-after map [menu-bar view sort do-sort-by-size] - '(menu-item "Sort by buffer size" ibuffer-do-sort-by-size)) - (define-key-after map [menu-bar view sort do-sort-by-alphabetic] - '(menu-item "Sort lexicographically" ibuffer-do-sort-by-alphabetic - :help "Sort by the alphabetic order of buffer name")) - (define-key-after map [menu-bar view sort do-sort-by-recency] - '(menu-item "Sort by view time" ibuffer-do-sort-by-recency - :help "Sort by the last time the buffer was displayed")) - (define-key-after map [menu-bar view sort dashes] - '("--")) - (define-key-after map [menu-bar view sort invert-sorting] - '(menu-item "Reverse sorting order" ibuffer-invert-sorting)) - (define-key-after map [menu-bar view sort toggle-sorting-mode] - '(menu-item "Switch sorting mode" ibuffer-toggle-sorting-mode - :help "Switch between the various sorting criteria")) - - (define-key-after map [menu-bar view filter] - (cons "Filter" (make-sparse-keymap "Filter"))) - - (define-key-after map [menu-bar view filter filter-disable] - '(menu-item "Disable all filtering" ibuffer-filter-disable - :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers))) - (define-key-after map [menu-bar view filter filter-by-mode] - '(menu-item "Add filter by any major mode..." ibuffer-filter-by-mode)) - (define-key-after map [menu-bar view filter filter-by-used-mode] - '(menu-item "Add filter by a major mode in use..." - ibuffer-filter-by-used-mode)) - (define-key-after map [menu-bar view filter filter-by-derived-mode] - '(menu-item "Add filter by derived mode..." - ibuffer-filter-by-derived-mode)) - (define-key-after map [menu-bar view filter filter-by-name] - '(menu-item "Add filter by buffer name..." ibuffer-filter-by-name)) - (define-key-after map [menu-bar view filter filter-by-starred-name] - '(menu-item "Add filter by starred buffer name..." - ibuffer-filter-by-starred-name - :help "List buffers whose names begin with a star")) - (define-key-after map [menu-bar view filter filter-by-filename] - '(menu-item "Add filter by full filename..." ibuffer-filter-by-filename - :help - (concat "For a buffer associated with file `/a/b/c.d', " - "list buffer if a given pattern matches `/a/b/c.d'"))) - (define-key-after map [menu-bar view filter filter-by-basename] - '(menu-item "Add filter by file basename..." - ibuffer-filter-by-basename - :help (concat "For a buffer associated with file `/a/b/c.d', " - "list buffer if a given pattern matches `c.d'"))) - (define-key-after map [menu-bar view filter filter-by-file-extension] - '(menu-item "Add filter by file name extension..." - ibuffer-filter-by-file-extension - :help (concat "For a buffer associated with file `/a/b/c.d', " - "list buffer if a given pattern matches `d'"))) - (define-key-after map [menu-bar view filter filter-by-directory] - '(menu-item "Add filter by filename's directory..." - ibuffer-filter-by-directory - :help - (concat "For a buffer associated with file `/a/b/c.d', " - "list buffer if a given pattern matches `/a/b'"))) - (define-key-after map [menu-bar view filter filter-by-size-lt] - '(menu-item "Add filter by size less than..." ibuffer-filter-by-size-lt)) - (define-key-after map [menu-bar view filter filter-by-size-gt] - '(menu-item "Add filter by size greater than..." - ibuffer-filter-by-size-gt)) - (define-key-after map [menu-bar view filter filter-by-modified] - '(menu-item "Add filter by modified buffer" ibuffer-filter-by-modified - :help "List buffers that are marked as modified")) - (define-key-after map [menu-bar view filter filter-by-visiting-file] - '(menu-item "Add filter by buffer visiting a file" - ibuffer-filter-by-visiting-file - :help "List buffers that are visiting files")) - (define-key-after map [menu-bar view filter filter-by-content] - '(menu-item "Add filter by content (regexp)..." - ibuffer-filter-by-content)) - (define-key-after map [menu-bar view filter filter-by-predicate] - '(menu-item "Add filter by Lisp predicate..." - ibuffer-filter-by-predicate)) - (define-key-after map [menu-bar view filter pop-filter] - '(menu-item "Remove top filter" ibuffer-pop-filter - :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers))) - (define-key-after map [menu-bar view filter and-filter] - '(menu-item "AND top two filters" ibuffer-and-filter - :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers - (cdr ibuffer-filtering-qualifiers)) - :help - "Create a new filter which is the logical AND of the top two filters")) - (define-key-after map [menu-bar view filter or-filter] - '(menu-item "OR top two filters" ibuffer-or-filter - :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers - (cdr ibuffer-filtering-qualifiers)) - :help - "Create a new filter which is the logical OR of the top two filters")) - (define-key-after map [menu-bar view filter negate-filter] - '(menu-item "Negate top filter" ibuffer-negate-filter - :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers))) - (define-key-after map [menu-bar view filter decompose-filter] - '(menu-item "Decompose top filter" ibuffer-decompose-filter - :enable (and (featurep 'ibuf-ext) - (memq (car ibuffer-filtering-qualifiers) '(or saved not))) - :help "Break down a complex filter like OR or NOT")) - (define-key-after map [menu-bar view filter exchange-filters] - '(menu-item "Swap top two filters" ibuffer-exchange-filters - :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers - (cdr ibuffer-filtering-qualifiers)))) - (define-key-after map [menu-bar view filter save-filters] - '(menu-item "Save current filters permanently..." ibuffer-save-filters - :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers) - :help "Use a mnemonic name to store current filter stack")) - (define-key-after map [menu-bar view filter switch-to-saved-filters] - '(menu-item "Restore permanently saved filters..." - ibuffer-switch-to-saved-filters - :enable (and (featurep 'ibuf-ext) ibuffer-saved-filters) - :help "Replace current filters with a saved stack")) - (define-key-after map [menu-bar view filter add-saved-filters] - '(menu-item "Add to permanently saved filters..." - ibuffer-add-saved-filters - :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers) - :help "Include already saved stack with current filters")) - (define-key-after map [menu-bar view filter delete-saved-filters] - '(menu-item "Delete permanently saved filters..." - ibuffer-delete-saved-filters - :enable (and (featurep 'ibuf-ext) ibuffer-saved-filters))) - - (define-key-after map [menu-bar view filter-groups] - (cons "Filter Groups" ibuffer-mode-groups-popup)) - - (define-key-after map [menu-bar view dashes2] - '("--")) - (define-key-after map [menu-bar view auto-mode] - '(menu-item "Auto Mode" ibuffer-auto-mode - :button (:toggle . ibuffer-auto-mode) - :help "Attempt to automatically update the Ibuffer buffer")) - - (define-key-after map [menu-bar mark] - (cons "Mark" (make-sparse-keymap "Mark"))) - - (define-key-after map [menu-bar mark toggle-marks] - '(menu-item "Toggle marks" ibuffer-toggle-marks - :help "Unmark marked buffers, and mark unmarked buffers")) - (define-key-after map [menu-bar mark change-marks] - '(menu-item "Change marks" ibuffer-change-marks - :help "Change OLD mark for marked buffers with NEW")) - (define-key-after map [menu-bar mark mark-forward] - '(menu-item "Mark" ibuffer-mark-forward - :help "Mark the buffer at point")) - (define-key-after map [menu-bar mark unmark-forward] - '(menu-item "Unmark" ibuffer-unmark-forward - :help "Unmark the buffer at point")) - (define-key-after map [menu-bar mark mark-by-mode] - '(menu-item "Mark by mode..." ibuffer-mark-by-mode - :help "Mark all buffers in a particular major mode")) - (define-key-after map [menu-bar mark mark-modified-buffers] - '(menu-item "Mark modified buffers" ibuffer-mark-modified-buffers - :help "Mark all buffers which have been modified")) - (define-key-after map [menu-bar mark mark-unsaved-buffers] - '(menu-item "Mark unsaved buffers" ibuffer-mark-unsaved-buffers - :help "Mark all buffers which have a file and are modified")) - (define-key-after map [menu-bar mark mark-read-only-buffers] - '(menu-item "Mark read-only buffers" ibuffer-mark-read-only-buffers - :help "Mark all buffers which are read-only")) - (define-key-after map [menu-bar mark mark-special-buffers] - '(menu-item "Mark special buffers" ibuffer-mark-special-buffers - :help "Mark all buffers whose name begins with a *")) - (define-key-after map [menu-bar mark mark-dired-buffers] - '(menu-item "Mark dired buffers" ibuffer-mark-dired-buffers - :help "Mark buffers in dired-mode")) - (define-key-after map [menu-bar mark mark-dissociated-buffers] - '(menu-item "Mark dissociated buffers" ibuffer-mark-dissociated-buffers - :help "Mark buffers with a non-existent associated file")) - (define-key-after map [menu-bar mark mark-help-buffers] - '(menu-item "Mark help buffers" ibuffer-mark-help-buffers - :help "Mark buffers in help-mode")) - (define-key-after map [menu-bar mark mark-compressed-file-buffers] - '(menu-item "Mark compressed file buffers" - ibuffer-mark-compressed-file-buffers - :help "Mark buffers which have a file that is compressed")) - (define-key-after map [menu-bar mark mark-old-buffers] - '(menu-item "Mark old buffers" ibuffer-mark-old-buffers - :help "Mark buffers which have not been viewed recently")) - (define-key-after map [menu-bar mark unmark-all] - '(menu-item "Unmark All" ibuffer-unmark-all)) - (define-key-after map [menu-bar mark unmark-all-marks] - '(menu-item "Unmark All buffers" ibuffer-unmark-all-marks)) - - (define-key-after map [menu-bar mark dashes] - '("--")) - - (define-key-after map [menu-bar mark mark-by-name-regexp] - '(menu-item "Mark by buffer name (regexp)..." ibuffer-mark-by-name-regexp - :help "Mark buffers whose name matches a regexp")) - (define-key-after map [menu-bar mark mark-by-mode-regexp] - '(menu-item "Mark by major mode (regexp)..." ibuffer-mark-by-mode-regexp - :help "Mark buffers whose major mode name matches a regexp")) - (define-key-after map [menu-bar mark mark-by-file-name-regexp] - '(menu-item "Mark by file name (regexp)..." - ibuffer-mark-by-file-name-regexp - :help "Mark buffers whose file name matches a regexp")) - (define-key-after map [menu-bar mark ibuffer-mark-by-content-regexp] - '(menu-item "Mark by content (regexp)..." - ibuffer-mark-by-content-regexp - :help "Mark buffers whose content matches a regexp")) - (define-key-after map [menu-bar mark mark-by-locked] - '(menu-item "Mark by locked buffers..." ibuffer-mark-by-locked - :help "Mark all locked buffers")) - map)) -(defvar ibuffer-mode-operate-map - (let ((operate-map (make-sparse-keymap "Operate"))) - (define-key-after operate-map [do-view] - '(menu-item "View" ibuffer-do-view)) - (define-key-after operate-map [do-view-other-frame] - '(menu-item "View (separate frame)" ibuffer-do-view-other-frame)) - (define-key-after operate-map [do-save] - '(menu-item "Save" ibuffer-do-save)) - (define-key-after operate-map [do-replace-regexp] - '(menu-item "Replace (regexp)..." ibuffer-do-replace-regexp - :help "Replace text inside marked buffers")) - (define-key-after operate-map [do-query-replace] - '(menu-item "Query Replace..." ibuffer-do-query-replace - :help "Replace text in marked buffers, asking each time")) - (define-key-after operate-map [do-query-replace-regexp] - '(menu-item "Query Replace (regexp)..." ibuffer-do-query-replace-regexp - :help "Replace text in marked buffers by regexp, asking each time")) - (define-key-after operate-map [do-print] - '(menu-item "Print" ibuffer-do-print)) - (define-key-after operate-map [do-toggle-modified] - '(menu-item "Toggle modification flag" ibuffer-do-toggle-modified)) - (define-key-after operate-map [do-toggle-read-only] - '(menu-item "Toggle read-only flag" ibuffer-do-toggle-read-only)) - (define-key-after operate-map [do-toggle-lock] - '(menu-item "Toggle lock flag" ibuffer-do-toggle-lock)) - (define-key-after operate-map [do-revert] - '(menu-item "Revert" ibuffer-do-revert - :help "Revert marked buffers to their associated file")) - (define-key-after operate-map [do-rename-uniquely] - '(menu-item "Rename Uniquely" ibuffer-do-rename-uniquely - :help "Rename marked buffers to a new, unique name")) - (define-key-after operate-map [do-delete] - '(menu-item "Kill" ibuffer-do-delete)) - (define-key-after operate-map [do-occur] - '(menu-item "List lines matching..." ibuffer-do-occur - :help "View all lines in marked buffers matching a regexp")) - (define-key-after operate-map [do-shell-command-pipe] - '(menu-item "Pipe to shell command..." ibuffer-do-shell-command-pipe - :help "For each marked buffer, send its contents to a shell command")) - (define-key-after operate-map [do-shell-command-pipe-replace] - '(menu-item "Pipe to shell command (replace)..." ibuffer-do-shell-command-pipe-replace - :help "For each marked buffer, replace its contents with output of shell command")) - (define-key-after operate-map [do-shell-command-file] - '(menu-item "Shell command on buffer's file..." ibuffer-do-shell-command-file - :help "For each marked buffer, run a shell command with its file as argument")) - (define-key-after operate-map [do-eval] - '(menu-item "Eval..." ibuffer-do-eval - :help "Evaluate a Lisp form in each marked buffer")) - (define-key-after operate-map [do-view-and-eval] - '(menu-item "Eval (viewing buffer)..." ibuffer-do-view-and-eval - :help "Evaluate a Lisp form in each marked buffer while viewing it")) - (define-key-after operate-map [diff-with-file] - '(menu-item "Diff with file" ibuffer-diff-with-file - :help "View the differences between this buffer and its file")) - - operate-map)) - -(define-key ibuffer-mode-groups-popup [kill-filter-group] - '(menu-item "Kill filter group" - ibuffer-kill-line - :enable (and (featurep 'ibuf-ext) - ibuffer-filter-groups))) -(define-key ibuffer-mode-groups-popup [yank-filter-group] - '(menu-item "Yank last killed filter group" - ibuffer-yank - :enable (and (featurep 'ibuf-ext) - ibuffer-filter-group-kill-ring))) +(defun ibuffer-mode--groups-menu-definition (&optional is-popup) + "Build the `ibuffer' \"Filter\" menu. Internal." + `("Filter Groups" + ["Create filter group from current filters..." + ibuffer-filters-to-filter-group + :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)] + ["Move point to the next filter group" + ibuffer-forward-filter-group] + ["Move point to the previous filter group" + ibuffer-backward-filter-group] + ["Move point to a specific filter group..." + ibuffer-jump-to-filter-group] + ,@(if is-popup + '(["Kill filter group" + ibuffer-kill-line + :enable (and (featurep 'ibuf-ext) + ibuffer-filter-groups)] + ["Yank last killed filter group" + ibuffer-yank + :enable (and (featurep 'ibuf-ext) + ibuffer-filter-group-kill-ring)]) + '(["Kill filter group named..." + ibuffer-kill-filter-group + :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups)] + ["Yank last killed filter group before..." + ibuffer-yank-filter-group + :enable (and (featurep 'ibuf-ext) ibuffer-filter-group-kill-ring)])) + ["Remove top filter group" + ibuffer-pop-filter-group + :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups)] + ["Remove all filter groups" + ibuffer-clear-filter-groups + :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups)] + ["Decompose filter group..." + ibuffer-pop-filter-group + :help "\"Unmake\" a filter group" + :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups)] + ["Save current filter groups permanently..." + ibuffer-save-filter-groups + :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups) + :help "Use a mnemonic name to store current filter groups"] + ["Restore permanently saved filters..." + ibuffer-switch-to-saved-filter-groups + :enable (and (featurep 'ibuf-ext) ibuffer-saved-filter-groups) + :help "Replace current filters with a saved stack"] + ["Delete permanently saved filter groups..." + ibuffer-delete-saved-filter-groups + :enable (and (featurep 'ibuf-ext) ibuffer-saved-filter-groups)] + ["Set current filter groups to filter by mode" + ibuffer-set-filter-groups-by-mode])) + +(easy-menu-define ibuffer-mode-groups-popup nil + "Menu for `ibuffer'." + (ibuffer-mode--groups-menu-definition 'is-popup)) + +(easy-menu-define ibuffer-mode-mark-menu ibuffer-mode-map + "Mark menu for `ibuffer'." + '("Mark" + ["Toggle marks" ibuffer-toggle-marks + :help "Unmark marked buffers, and mark unmarked buffers"] + ["Change marks" ibuffer-change-marks + :help "Change OLD mark for marked buffers with NEW"] + ["Mark" ibuffer-mark-forward + :help "Mark the buffer at point"] + ["Unmark" ibuffer-unmark-forward + :help "Unmark the buffer at point"] + ["Mark by mode..." ibuffer-mark-by-mode + :help "Mark all buffers in a particular major mode"] + ["Mark modified buffers" ibuffer-mark-modified-buffers + :help "Mark all buffers which have been modified"] + ["Mark unsaved buffers" ibuffer-mark-unsaved-buffers + :help "Mark all buffers which have a file and are modified"] + ["Mark read-only buffers" ibuffer-mark-read-only-buffers + :help "Mark all buffers which are read-only"] + ["Mark special buffers" ibuffer-mark-special-buffers + :help "Mark all buffers whose name begins with a *"] + ["Mark dired buffers" ibuffer-mark-dired-buffers + :help "Mark buffers in dired-mode"] + ["Mark dissociated buffers" ibuffer-mark-dissociated-buffers + :help "Mark buffers with a non-existent associated file"] + ["Mark help buffers" ibuffer-mark-help-buffers + :help "Mark buffers in help-mode"] + ["Mark compressed file buffers" ibuffer-mark-compressed-file-buffers + :help "Mark buffers which have a file that is compressed"] + ["Mark old buffers" ibuffer-mark-old-buffers + :help "Mark buffers which have not been viewed recently"] + ["Unmark All" ibuffer-unmark-all] + ["Unmark All buffers" ibuffer-unmark-all-marks] + "---" + ["Mark by buffer name (regexp)..." ibuffer-mark-by-name-regexp + :help "Mark buffers whose name matches a regexp"] + ["Mark by major mode (regexp)..." ibuffer-mark-by-mode-regexp + :help "Mark buffers whose major mode name matches a regexp"] + ["Mark by file name (regexp)..." ibuffer-mark-by-file-name-regexp + :help "Mark buffers whose file name matches a regexp"] + ["Mark by content (regexp)..." ibuffer-mark-by-content-regexp + :help "Mark buffers whose content matches a regexp"] + ["Mark by locked buffers..." ibuffer-mark-by-locked + :help "Mark all locked buffers"])) + +(easy-menu-define ibuffer-mode-view-menu ibuffer-mode-map + "View menu for `ibuffer'." + `("View" + ["View this buffer" ibuffer-visit-buffer] + ["View (other window)" ibuffer-visit-buffer-other-window] + ["View (other frame)" ibuffer-visit-buffer-other-frame] + ["Update" ibuffer-update + :help "Regenerate the list of buffers"] + ["Switch display format" ibuffer-switch-format + :help "Toggle between available values of `ibuffer-formats'"] + "---" + ("Sort" + ["Sort by major mode" ibuffer-do-sort-by-major-mode] + ["Sort by buffer size" ibuffer-do-sort-by-size] + ["Sort lexicographically" ibuffer-do-sort-by-alphabetic + :help "Sort by the alphabetic order of buffer name"] + ["Sort by view time" ibuffer-do-sort-by-recency + :help "Sort by the last time the buffer was displayed"] + "---" + ["Reverse sorting order" ibuffer-invert-sorting] + ["Switch sorting mode" ibuffer-toggle-sorting-mode + :help "Switch between the various sorting criteria"]) + ("Filter" + ["Disable all filtering" ibuffer-filter-disable + :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)] + ["Add filter by any major mode..." ibuffer-filter-by-mode] + ["Add filter by a major mode in use..." ibuffer-filter-by-used-mode] + ["Add filter by derived mode..." ibuffer-filter-by-derived-mode] + ["Add filter by buffer name..." ibuffer-filter-by-name] + ["Add filter by starred buffer name..." ibuffer-filter-by-starred-name + :help "List buffers whose names begin with a star"] + ["Add filter by full filename..." ibuffer-filter-by-filename + :help (concat "For a buffer associated with file `/a/b/c.d', " + "list buffer if a given pattern matches `/a/b/c.d'")] + ["Add filter by file basename..." ibuffer-filter-by-basename + :help (concat "For a buffer associated with file `/a/b/c.d', " + "list buffer if a given pattern matches `c.d'")] + ["Add filter by file name extension..." ibuffer-filter-by-file-extension + :help (concat "For a buffer associated with file `/a/b/c.d', " + "list buffer if a given pattern matches `d'")] + ["Add filter by filename's directory..." ibuffer-filter-by-directory + :help (concat "For a buffer associated with file `/a/b/c.d', " + "list buffer if a given pattern matches `/a/b'")] + ["Add filter by size less than..." ibuffer-filter-by-size-lt] + ["Add filter by size greater than..." ibuffer-filter-by-size-gt] + ["Add filter by modified buffer" ibuffer-filter-by-modified + :help "List buffers that are marked as modified"] + ["Add filter by buffer visiting a file" ibuffer-filter-by-visiting-file + :help "List buffers that are visiting files"] + ["Add filter by content (regexp)..." ibuffer-filter-by-content] + ["Add filter by Lisp predicate..." ibuffer-filter-by-predicate] + ["Remove top filter" ibuffer-pop-filter + :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)] + ["AND top two filters" ibuffer-and-filter + :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers + (cdr ibuffer-filtering-qualifiers)) + :help "Create a new filter which is the logical AND of the top two filters"] + ["OR top two filters" ibuffer-or-filter + :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers + (cdr ibuffer-filtering-qualifiers)) + :help "Create a new filter which is the logical OR of the top two filters"] + ["Negate top filter" ibuffer-negate-filter + :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)] + ["Decompose top filter" ibuffer-decompose-filter + :enable (and (featurep 'ibuf-ext) + (memq (car ibuffer-filtering-qualifiers) '(or saved not))) + :help "Break down a complex filter like OR or NOT"] + ["Swap top two filters" ibuffer-exchange-filters + :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers + (cdr ibuffer-filtering-qualifiers))] + ["Save current filters permanently..." ibuffer-save-filters + :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers) + :help "Use a mnemonic name to store current filter stack"] + ["Restore permanently saved filters..." ibuffer-switch-to-saved-filters + :enable (and (featurep 'ibuf-ext) ibuffer-saved-filters) + :help "Replace current filters with a saved stack"] + ["Add to permanently saved filters..." ibuffer-add-saved-filters + :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers) + :help "Include already saved stack with current filters"] + ["Delete permanently saved filters..." ibuffer-delete-saved-filters + :enable (and (featurep 'ibuf-ext) ibuffer-saved-filters)]) + ;; The "Filter Groups" menu: + ,(ibuffer-mode--groups-menu-definition) + "---" + ["Auto Mode" ibuffer-auto-mode + :style toggle + :selected ibuffer-auto-mode + :help "Attempt to automatically update the Ibuffer buffer"])) + +(define-obsolete-variable-alias 'ibuffer-mode-operate-map 'ibuffer-mode-operate-menu "28.1") +(easy-menu-define ibuffer-mode-operate-menu ibuffer-mode-map + "Operate menu for `ibuffer'." + '("Operate" + ["View" ibuffer-do-view] + ["View (separate frame)" ibuffer-do-view-other-frame] + ["Save" ibuffer-do-save] + ["Replace (regexp)..." ibuffer-do-replace-regexp + :help "Replace text inside marked buffers"] + ["Query Replace..." ibuffer-do-query-replace + :help "Replace text in marked buffers, asking each time"] + ["Query Replace (regexp)..." ibuffer-do-query-replace-regexp + :help "Replace text in marked buffers by regexp, asking each time"] + ["Print" ibuffer-do-print] + ["Toggle modification flag" ibuffer-do-toggle-modified] + ["Toggle read-only flag" ibuffer-do-toggle-read-only] + ["Toggle lock flag" ibuffer-do-toggle-lock] + ["Revert" ibuffer-do-revert + :help "Revert marked buffers to their associated file"] + ["Rename Uniquely" ibuffer-do-rename-uniquely + :help "Rename marked buffers to a new, unique name"] + ["Kill" ibuffer-do-delete] + ["List lines matching..." ibuffer-do-occur + :help "View all lines in marked buffers matching a regexp"] + ["Pipe to shell command..." ibuffer-do-shell-command-pipe + :help "For each marked buffer, send its contents to a shell command"] + ["Pipe to shell command (replace)..." ibuffer-do-shell-command-pipe-replace + :help "For each marked buffer, replace its contents with output of shell command"] + ["Shell command on buffer's file..." ibuffer-do-shell-command-file + :help "For each marked buffer, run a shell command with its file as argument"] + ["Eval..." ibuffer-do-eval + :help "Evaluate a Lisp form in each marked buffer"] + ["Eval (viewing buffer)..." ibuffer-do-view-and-eval + :help "Evaluate a Lisp form in each marked buffer while viewing it"] + ["Diff with file" ibuffer-diff-with-file + :help "View the differences between this buffer and its file"])) (defvar ibuffer-name-map (let ((map (make-sparse-keymap))) @@ -1025,7 +897,7 @@ width and the longest string in LIST." (goto-char eventpt) (ibuffer-set-mark ibuffer-marked-char)) (save-excursion - (popup-menu ibuffer-mode-operate-map))))) + (popup-menu ibuffer-mode-operate-menu))))) (setq buffer-read-only t) (if (= eventpt (point)) (goto-char origpt))))) @@ -2734,7 +2606,6 @@ will be inserted before the group at point." (setq-local ibuffer-tmp-hide-regexps nil) (setq-local ibuffer-tmp-show-regexps nil) (define-key ibuffer-mode-map [menu-bar edit] 'undefined) - (define-key ibuffer-mode-map [menu-bar operate] (cons "Operate" ibuffer-mode-operate-map)) (ibuffer-update-format) (when ibuffer-default-directory (setq default-directory ibuffer-default-directory)) commit 0fd206badc761df0a2eb18cd5d9c7506c3bd0d2a Author: Michael Albinus Date: Sun Feb 28 18:23:27 2021 +0100 Add `completion-predicate' to some Tramp commands * lisp/net/tramp-cmds.el (tramp-cleanup-this-connection) (tramp-rename-these-files): Add property `completion-predicate'. * lisp/net/tramp.el (tramp-command-completion-p): New defun. diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el index f0bbe31cea..2aacf266f2 100644 --- a/lisp/net/tramp-cmds.el +++ b/lisp/net/tramp-cmds.el @@ -144,11 +144,18 @@ When called interactively, a Tramp connection has to be selected." ;;;###tramp-autoload (defun tramp-cleanup-this-connection () "Flush all connection related objects of the current buffer's connection." + ;; (declare (completion tramp-command-completion-p))) (interactive) (and (tramp-tramp-file-p default-directory) (tramp-cleanup-connection (tramp-dissect-file-name default-directory 'noexpand)))) +;; Starting with Emacs 28.1, this can be replaced by the "(declare ...)" form. +;;;###tramp-autoload +(function-put + #'tramp-cleanup-this-connection 'completion-predicate + #'tramp-command-completion-p) + ;;;###tramp-autoload (defvar tramp-cleanup-all-connections-hook nil "List of functions to be called after all Tramp connections are cleaned up.") @@ -431,6 +438,7 @@ Interactively, TARGET is selected from `tramp-default-rename-alist' without confirmation if the prefix argument is non-nil. For details, see `tramp-rename-files'." + ;; (declare (completion tramp-command-completion-p)) (interactive (let ((source default-directory) target @@ -461,6 +469,11 @@ For details, see `tramp-rename-files'." (tramp-rename-files default-directory target)) +;; Starting with Emacs 28.1, this can be replaced by the "(declare ...)" form. +;;;###tramp-autoload +(function-put + #'tramp-rename-these-files 'completion-predicate #'tramp-command-completion-p) + ;; Tramp version is useful in a number of situations. ;;;###tramp-autoload diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index e99e43938f..14d5f8c3b6 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -2591,6 +2591,14 @@ Add operations defined in `HANDLER-alist' to `tramp-file-name-handler'." ;;; File name handler functions for completion mode: +;; This function takes action since Emacs 28.1, when +;; `read-extended-command-predicate' is set to +;; `command-completion-default-include-p'. +(defun tramp-command-completion-p (_symbol buffer) + "A predicate for Tramp interactive commands. +They are completed by \"M-x TAB\" only if the current buffer is remote." + (with-current-buffer buffer (tramp-tramp-file-p default-directory))) + (defun tramp-connectable-p (vec-or-filename) "Check, whether it is possible to connect the remote host w/o side-effects. This is true, if either the remote host is already connected, or if we are commit 277a254a42ad4ccf2223eaa788de37279e5e3958 Author: Kapuze Martin Date: Sun Feb 28 15:21:53 2021 +0100 Enable Python type hints and non-trivial base classes in wisent * admin/grammars/python.wy: Enable understanding Python type hints and non-trivial base classes (bug#46817). Copyright-paperwork-exempt: yes diff --git a/admin/grammars/python.wy b/admin/grammars/python.wy index aaa25ced20..9c8f4ac6a9 100644 --- a/admin/grammars/python.wy +++ b/admin/grammars/python.wy @@ -88,7 +88,7 @@ %package wisent-python-wy %provide semantic/wisent/python-wy -%expectedconflicts 4 +%expectedconflicts 5 %{ (declare-function wisent-python-reconstitute-function-tag @@ -184,6 +184,7 @@ %token ASSIGN "=" %token BACKQUOTE "`" %token AT "@" +%token FOLLOWS "->" ;; ----------------- @@ -808,12 +809,17 @@ decorators ;; funcdef: [decorators] 'def' NAME parameters ':' suite funcdef - : DEF NAME function_parameter_list COLON suite + : DEF NAME function_parameter_list return_type_hint COLON suite (wisent-python-reconstitute-function-tag - (FUNCTION-TAG $2 nil $3) $5) - | decorators DEF NAME function_parameter_list COLON suite + (FUNCTION-TAG $2 nil $3) $6) + | decorators DEF NAME function_parameter_list return_type_hint COLON suite (wisent-python-reconstitute-function-tag - (FUNCTION-TAG $3 nil $4 :decorators $1) $6) + (FUNCTION-TAG $3 nil $4 :decorators $1) $7) + ; + +return_type_hint + : ;;EMPTY + | FOLLOWS type ; function_parameter_list @@ -887,7 +893,7 @@ paren_classes ;; parser can parse general expressions, I don't see much benefit in ;; generating a string of expression as base class "name". paren_class - : dotted_name + : type ; ;;;**************************************************************************** @@ -1140,7 +1146,7 @@ fpdef_opt_test ;; fpdef: NAME | '(' fplist ')' fpdef - : NAME + : NAME type_hint (VARIABLE-TAG $1 nil nil) ;; Below breaks the parser. Don't know why, but my guess is that ;; LPAREN/RPAREN clashes with the ones in function_parameters. @@ -1160,6 +1166,15 @@ fpdef ;; | fpdef_list COMMA fpdef ;; ; +type_hint + : ;;EMPTY + | COLON type + ; + +type + : test + ; + ;; ['=' test] eq_test_opt : ;;EMPTY commit 05100407543deef4191ba0453ec4b89ef40dde90 Author: Lars Ingebrigtsen Date: Sun Feb 28 15:08:21 2021 +0100 Adjust cmuscheme.el menu bar after previous scheme.el change * lisp/cmuscheme.el (map): Adjust the keymap lookup after recent scheme.el change (bug#46820). diff --git a/lisp/cmuscheme.el b/lisp/cmuscheme.el index 772891d5d3..f41f2bf702 100644 --- a/lisp/cmuscheme.el +++ b/lisp/cmuscheme.el @@ -132,7 +132,7 @@ (define-key scheme-mode-map "\C-c\C-l" 'scheme-load-file) (define-key scheme-mode-map "\C-c\C-k" 'scheme-compile-file) ;k for "kompile" -(let ((map (lookup-key scheme-mode-map [menu-bar scheme]))) +(let ((map (lookup-key scheme-mode-map [menu-bar Scheme]))) (define-key map [separator-eval] '("--")) (define-key map [compile-file] '("Compile Scheme File" . scheme-compile-file)) commit bdea1883cc8feb8a607c3d05191e7dc8d12f0aa0 Author: Mattias Engdegård Date: Sun Feb 28 13:06:24 2021 +0100 Fix pcase 'rx' pattern match-data bug The pcase 'rx' pattern would in some cases allow the match data to be clobbered before it is read. For example: (pcase "PQR" ((and (rx (let a nonl)) (rx ?z)) (list 'one a)) ((rx (let b ?Q)) (list 'two b))) The above returned (two "P") instead of the correct (two "Q"). This occurred because the calls to string-match and match-string were presented as separate patterns to pcase, which would interleave them with other patterns. As a remedy, combine string matching and match-data extraction into a single pcase pattern. This introduces a slight inefficiency for two or more submatches as they are grouped into a list structure which then has to be destructured. Found by Stefan Monnier. See discussion at https://lists.gnu.org/archive/html/emacs-devel/2021-02/msg02010.html * lisp/emacs-lisp/rx.el (rx--reduce-right): New helper. (rx [pcase macro]): Combine string-match and match-string calls into a single pcase pattern. * test/lisp/emacs-lisp/rx-tests.el (rx-pcase): Add test cases. diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index ffc21951b6..56e588ee0d 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -1418,6 +1418,12 @@ into a plain rx-expression, collecting names into `rx--pcase-vars'." (cons head (mapcar #'rx--pcase-transform rest))) (_ rx))) +(defun rx--reduce-right (f l) + "Right-reduction on L by F. L must be non-empty." + (if (cdr l) + (funcall f (car l) (rx--reduce-right f (cdr l))) + (car l))) + ;;;###autoload (pcase-defmacro rx (&rest regexps) "A pattern that matches strings against `rx' REGEXPS in sexp form. @@ -1436,17 +1442,28 @@ following constructs: introduced by a previous (let REF ...) construct." (let* ((rx--pcase-vars nil) - (regexp (rx--to-expr (rx--pcase-transform (cons 'seq regexps))))) + (regexp (rx--to-expr (rx--pcase-transform (cons 'seq regexps)))) + (nvars (length rx--pcase-vars))) `(and (pred stringp) - ;; `pcase-let' takes a match for granted and discards all unnecessary - ;; conditions, which means that a `pred' clause cannot be used for - ;; the match condition. The following construct seems to survive. - (app (lambda (s) (string-match ,regexp s)) (pred identity)) - ,@(let ((i 0)) - (mapcar (lambda (name) - (setq i (1+ i)) - `(app (match-string ,i) ,name)) - (reverse rx--pcase-vars)))))) + ,(if (zerop nvars) + ;; No variables bound: a single predicate suffices. + `(pred (string-match ,regexp)) + ;; Pack the submatches into a dotted list which is then + ;; immediately destructured into individual variables again. + ;; This is of course slightly inefficient when NVARS > 1. + ;; A dotted list is used to reduce the number of conses + ;; to create and take apart. + `(app (lambda (s) + (and (string-match ,regexp s) + ,(rx--reduce-right + (lambda (a b) `(cons ,a ,b)) + (mapcar (lambda (i) `(match-string ,i s)) + (number-sequence 1 nvars))))) + ,(list '\` + (rx--reduce-right + #'cons + (mapcar (lambda (name) (list '\, name)) + (reverse rx--pcase-vars))))))))) ;; Obsolete internal symbol, used in old versions of the `flycheck' package. (define-obsolete-function-alias 'rx-submatch-n 'rx-to-string "27.1") diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el index fecdcf55af..2dd1bca22d 100644 --- a/test/lisp/emacs-lisp/rx-tests.el +++ b/test/lisp/emacs-lisp/rx-tests.el @@ -156,6 +156,8 @@ "....."))) (ert-deftest rx-pcase () + (should (equal (pcase "i18n" ((rx (let x (+ digit))) (list 'ok x))) + '(ok "18"))) (should (equal (pcase "a 1 2 3 1 1 b" ((rx (let u (+ digit)) space (let v (+ digit)) space @@ -176,6 +178,12 @@ ((rx nonl) 'wrong) (_ 'correct)) 'correct)) + (should (equal (pcase "PQR" + ((and (rx (let a nonl)) (rx ?z)) + (list 'one a)) + ((rx (let b ?Q)) + (list 'two b))) + '(two "Q"))) (should (equal (pcase-let (((rx ?B (let z nonl)) "ABC")) (list 'ok z)) '(ok "C"))) commit aad8ffafa89fe46ff5d63bd0127274f74019d50f Author: Stefan Monnier Date: Sat Feb 27 20:30:21 2021 -0500 * lisp/international/mule-cmds.el: Try and fix bug#46818 (update-leim-list-file): Reduce stack/pdl use. diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index e4bdf50f52..e1dbf82ed4 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -1312,8 +1312,13 @@ Each function is called with one arg, LEIM directory name.") (defun update-leim-list-file (&rest dirs) "Update LEIM list file in directories DIRS." - (dolist (function update-leim-list-functions) - (apply function dirs))) + ;; bug#46818: This `let'-binding is not necessary, but + ;; it reduces the recursion depth during bootstrap (at which + ;; point some of the core ELisp files haven't been byte-compiled + ;; yet, which causes deeper-than-normal recursion). + (let ((vc-handled-backends nil)) + (dolist (function update-leim-list-functions) + (apply function dirs)))) (defvar-local current-input-method nil "The current input method for multilingual text. commit ff09851a1fff745584de11cb67091a432eeff312 Author: Stefan Monnier Date: Sat Feb 27 20:22:58 2021 -0500 * lisp/emacs-lisp/macroexp.el: Rewrite the code warning about '(lambda ...) (macroexp--expand-all): Use `pcase--dontcare` so pcase generates slightly better code. Don't hardcode which functions takes function arguments; rely on a new `funarg-positions` symbol property instead. diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index 4d04bfa091..59ada5ec35 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -294,10 +294,12 @@ Assumes the caller has bound `macroexpand-all-environment'." macroexpand-all-environment) ;; Normal form; get its expansion, and then expand arguments. (setq form (macroexp-macroexpand form macroexpand-all-environment)) + ;; FIXME: It'd be nice to use `byte-optimize--pcase' here, but when + ;; I tried it, it broke the bootstrap :-( (pcase form (`(cond . ,clauses) (macroexp--cons 'cond (macroexp--all-clauses clauses) form)) - (`(condition-case . ,(or `(,err ,body . ,handlers) dontcare)) + (`(condition-case . ,(or `(,err ,body . ,handlers) pcase--dontcare)) (macroexp--cons 'condition-case (macroexp--cons err @@ -314,7 +316,8 @@ Assumes the caller has bound `macroexpand-all-environment'." (cdr form)) form)) (`(,(or 'function 'quote) . ,_) form) - (`(,(and fun (or 'let 'let*)) . ,(or `(,bindings . ,body) dontcare)) + (`(,(and fun (or 'let 'let*)) . ,(or `(,bindings . ,body) + pcase--dontcare)) (macroexp--cons fun (macroexp--cons (macroexp--all-clauses bindings 1) (if (null body) @@ -339,27 +342,7 @@ Assumes the caller has bound `macroexpand-all-environment'." form) (macroexp--expand-all newform)))) - ;; The following few cases are for normal function calls that - ;; are known to funcall one of their arguments. The byte - ;; compiler has traditionally handled these functions specially - ;; by treating a lambda expression quoted by `quote' as if it - ;; were quoted by `function'. We make the same transformation - ;; here, so that any code that cares about the difference will - ;; see the same transformation. - ;; First arg is a function: - (`(,(and fun (or 'funcall 'apply 'mapcar 'mapatoms 'mapconcat 'mapc)) - ',(and f `(lambda . ,_)) . ,args) - (macroexp-warn-and-return - (format "%s quoted with ' rather than with #'" - (list 'lambda (nth 1 f) '...)) - (macroexp--expand-all `(,fun #',f . ,args)))) - ;; Second arg is a function: - (`(,(and fun (or 'sort)) ,arg1 ',(and f `(lambda . ,_)) . ,args) - (macroexp-warn-and-return - (format "%s quoted with ' rather than with #'" - (list 'lambda (nth 1 f) '...)) - (macroexp--expand-all `(,fun ,arg1 #',f . ,args)))) - (`(funcall ,exp . ,args) + (`(funcall . ,(or `(,exp . ,args) pcase--dontcare)) (let ((eexp (macroexp--expand-all exp)) (eargs (macroexp--all-forms args))) ;; Rewrite (funcall #'foo bar) to (foo bar), in case `foo' @@ -368,10 +351,22 @@ Assumes the caller has bound `macroexpand-all-environment'." (`#',f (macroexp--expand-all `(,f . ,eargs))) (_ `(funcall ,eexp . ,eargs))))) (`(,func . ,_) - ;; Macro expand compiler macros. This cannot be delayed to - ;; byte-optimize-form because the output of the compiler-macro can - ;; use macros. - (let ((handler (function-get func 'compiler-macro))) + (let ((handler (function-get func 'compiler-macro)) + (funargs (function-get func 'funarg-positions))) + ;; Check functions quoted with ' rather than with #' + (dolist (funarg funargs) + (let ((arg (nth funarg form))) + (when (and (eq 'quote (car-safe arg)) + (eq 'lambda (car-safe (cadr arg)))) + (setcar (nthcdr funarg form) + (macroexp-warn-and-return + (format "%S quoted with ' rather than with #'" + (let ((f (cadr arg))) + (if (symbolp f) f `(lambda ,(nth 1 f) ...)))) + arg))))) + ;; Macro expand compiler macros. This cannot be delayed to + ;; byte-optimize-form because the output of the compiler-macro can + ;; use macros. (if (null handler) ;; No compiler macro. We just expand each argument (for ;; setq/setq-default this works alright because the variable names @@ -397,6 +392,18 @@ Assumes the caller has bound `macroexpand-all-environment'." (_ form)))) +;; Record which arguments expect functions, so we can warn when those +;; are accidentally quoted with ' rather than with #' +(dolist (f '(funcall apply mapcar mapatoms mapconcat mapc cl-mapcar maphash)) + (put f 'funarg-positions '(1))) +(dolist (f '( add-hook remove-hook advice-remove advice--remove-function + defalias fset global-set-key run-after-idle-timeout + set-process-filter set-process-sentinel sort)) + (put f 'funarg-positions '(2))) +(dolist (f '( advice-add define-key + run-at-time run-with-idle-timer run-with-timer )) + (put f 'funarg-positions '(3))) + ;;;###autoload (defun macroexpand-all (form &optional environment) "Return result of expanding macros at all levels in FORM. commit 9eff23573df263dd5e5a2d73888c16cb5853eb2f Author: Stefan Kangas Date: Sun Feb 28 01:51:31 2021 +0100 Convert text-mode menu to easymenu * lisp/textmodes/text-mode.el (text-mode-map): Move menu definition from here... (text-mode-menu): ...to here, and convert to easymenu. diff --git a/lisp/textmodes/text-mode.el b/lisp/textmodes/text-mode.el index ab9f7b9c7c..7836bd46bc 100644 --- a/lisp/textmodes/text-mode.el +++ b/lisp/textmodes/text-mode.el @@ -70,32 +70,31 @@ (defvar text-mode-map (let ((map (make-sparse-keymap))) (define-key map "\e\t" 'ispell-complete-word) - (define-key map [menu-bar text] - (cons "Text" (make-sparse-keymap "Text"))) - (bindings--define-key map [menu-bar text toggle-text-mode-auto-fill] - '(menu-item "Auto Fill" toggle-text-mode-auto-fill - :button (:toggle . (memq 'turn-on-auto-fill text-mode-hook)) - :help "Automatically fill text while typing in text modes (Auto Fill mode)")) - (bindings--define-key map [menu-bar text paragraph-indent-minor-mode] - '(menu-item "Paragraph Indent" paragraph-indent-minor-mode - :button (:toggle . (bound-and-true-p paragraph-indent-minor-mode)) - :help "Toggle paragraph indent minor mode")) - (bindings--define-key map [menu-bar text sep] menu-bar-separator) - (bindings--define-key map [menu-bar text center-region] - '(menu-item "Center Region" center-region - :help "Center the marked region" - :enable (region-active-p))) - (bindings--define-key map [menu-bar text center-paragraph] - '(menu-item "Center Paragraph" center-paragraph - :help "Center the current paragraph")) - (bindings--define-key map [menu-bar text center-line] - '(menu-item "Center Line" center-line - :help "Center the current line")) map) "Keymap for `text-mode'. Many other modes, such as `mail-mode', `outline-mode' and `indented-text-mode', inherit all the commands defined in this map.") +(easy-menu-define text-mode-menu text-mode-map + "Menu for `text-mode'." + '("Text" + ["Center Line" center-line + :help "Center the current line"] + ["Center Paragraph" center-paragraph + :help "Center the current paragraph"] + ["Center Region" center-region + :help "Center the marked region" + :enable (region-active-p)] + "---" + ["Paragraph Indent" paragraph-indent-minor-mode + :help "Toggle paragraph indent minor mode" + :style toggle + :selected (bound-and-true-p paragraph-indent-minor-mode)] + ["Auto Fill" toggle-text-mode-auto-fill + :help "Automatically fill text while typing in text modes (Auto Fill mode)" + :style toggle + :selected (memq 'turn-on-auto-fill text-mode-hook)])) + (define-derived-mode text-mode nil "Text" "Major mode for editing text written for humans to read. commit 9a110cb0d956ddf887e7d5ba9f0c2a67c9a1c6f0 Author: Stefan Kangas Date: Sun Feb 28 00:13:24 2021 +0100 ; Make function missed in previous change obsolete * lisp/play/handwrite.el (menu-bar-handwrite-map): Make unused function obsolete. diff --git a/lisp/play/handwrite.el b/lisp/play/handwrite.el index 3cc5d9c8dc..cc05823075 100644 --- a/lisp/play/handwrite.el +++ b/lisp/play/handwrite.el @@ -90,6 +90,7 @@ (define-key map [handwrite] '("Write by hand" . handwrite)) map)) (fset 'menu-bar-handwrite-map menu-bar-handwrite-map) +(make-obsolete 'menu-bar-handwrite-map nil "28.1") (make-obsolete-variable 'menu-bar-handwrite-map nil "28.1") ;; User definable variables commit 697aaafca35ab937e22030e1a6cb024c31953885 Author: Stefan Kangas Date: Sat Feb 27 23:34:33 2021 +0100 Convert isearch menu to easymenu * lisp/isearch.el (isearch-menu-bar-yank-map) (isearch-menu-bar-map, isearch-mode-map): Move menu definition from here... (isearch-menu-bar-map): ...to here, and convert to easymenu. * lisp/loadup.el ("emacs-lisp/easymenu"): Move before isearch.el. diff --git a/lisp/isearch.el b/lisp/isearch.el index 0d29438f4e..8aaf765429 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -527,159 +527,6 @@ This is like `describe-bindings', but displays only Isearch keys." '(isearch-tmm-menubar tmm-menubar menu-bar-open mouse-minor-mode-menu) "List of commands that can open a menu during Isearch.") -(defvar isearch-menu-bar-yank-map - (let ((map (make-sparse-keymap))) - (define-key map [isearch-yank-pop] - '(menu-item "Previous kill" isearch-yank-pop-only - :help "Replace previous yanked kill on search string")) - (define-key map [isearch-yank-kill] - '(menu-item "Current kill" isearch-yank-kill - :help "Append current kill to search string")) - (define-key map [isearch-yank-until-char] - '(menu-item "Until char..." isearch-yank-until-char - :help "Yank from point to specified character into search string")) - (define-key map [isearch-yank-line] - '(menu-item "Rest of line" isearch-yank-line - :help "Yank the rest of the current line on search string")) - (define-key map [isearch-yank-symbol-or-char] - '(menu-item "Symbol/char" - isearch-yank-symbol-or-char - :help "Yank next symbol or char on search string")) - (define-key map [isearch-yank-word-or-char] - '(menu-item "Word/char" - isearch-yank-word-or-char - :help "Yank next word or char on search string")) - (define-key map [isearch-yank-char] - '(menu-item "Char" isearch-yank-char - :help "Yank char at point on search string")) - map)) - -(defvar isearch-menu-bar-map - (let ((map (make-sparse-keymap "Isearch"))) - (define-key map [isearch-complete] - '(menu-item "Complete current search string" isearch-complete - :help "Complete current search string over search history")) - (define-key map [isearch-complete-separator] - '(menu-item "--")) - (define-key map [isearch-query-replace-regexp] - '(menu-item "Replace search string as regexp" isearch-query-replace-regexp - :help "Replace matches for current search string as regexp")) - (define-key map [isearch-query-replace] - '(menu-item "Replace search string" isearch-query-replace - :help "Replace matches for current search string")) - (define-key map [isearch-occur] - '(menu-item "Show all matches for search string" isearch-occur - :help "Show all matches for current search string")) - (define-key map [isearch-highlight-regexp] - '(menu-item "Highlight all matches for search string" - isearch-highlight-regexp - :help "Highlight all matches for current search string")) - (define-key map [isearch-search-replace-separator] - '(menu-item "--")) - (define-key map [isearch-transient-input-method] - '(menu-item "Turn on transient input method" - isearch-transient-input-method - :help "Turn on transient input method for search")) - (define-key map [isearch-toggle-specified-input-method] - '(menu-item "Turn on specific input method" - isearch-toggle-specified-input-method - :help "Turn on specific input method for search")) - (define-key map [isearch-toggle-input-method] - '(menu-item "Toggle input method" isearch-toggle-input-method - :help "Toggle input method for search")) - (define-key map [isearch-input-method-separator] - '(menu-item "--")) - (define-key map [isearch-char-by-name] - '(menu-item "Search for char by name" isearch-char-by-name - :help "Search for character by name")) - (define-key map [isearch-quote-char] - '(menu-item "Search for literal char" isearch-quote-char - :help "Search for literal char")) - (define-key map [isearch-special-char-separator] - '(menu-item "--")) - (define-key map [isearch-toggle-word] - '(menu-item "Word matching" isearch-toggle-word - :help "Word matching" - :button (:toggle - . (eq isearch-regexp-function 'word-search-regexp)))) - (define-key map [isearch-toggle-symbol] - '(menu-item "Symbol matching" isearch-toggle-symbol - :help "Symbol matching" - :button (:toggle - . (eq isearch-regexp-function - 'isearch-symbol-regexp)))) - (define-key map [isearch-toggle-regexp] - '(menu-item "Regexp matching" isearch-toggle-regexp - :help "Regexp matching" - :button (:toggle . isearch-regexp))) - (define-key map [isearch-toggle-invisible] - '(menu-item "Invisible text matching" isearch-toggle-invisible - :help "Invisible text matching" - :button (:toggle . isearch-invisible))) - (define-key map [isearch-toggle-char-fold] - '(menu-item "Character folding matching" isearch-toggle-char-fold - :help "Character folding matching" - :button (:toggle - . (eq isearch-regexp-function - 'char-fold-to-regexp)))) - (define-key map [isearch-toggle-case-fold] - '(menu-item "Case folding matching" isearch-toggle-case-fold - :help "Case folding matching" - :button (:toggle . isearch-case-fold-search))) - (define-key map [isearch-toggle-lax-whitespace] - '(menu-item "Lax whitespace matching" isearch-toggle-lax-whitespace - :help "Lax whitespace matching" - :button (:toggle . isearch-lax-whitespace))) - (define-key map [isearch-toggle-separator] - '(menu-item "--")) - (define-key map [isearch-yank-menu] - `(menu-item "Yank on search string" ,isearch-menu-bar-yank-map)) - (define-key map [isearch-edit-string] - '(menu-item "Edit current search string" isearch-edit-string - :help "Edit current search string")) - (define-key map [isearch-ring-retreat] - '(menu-item "Edit previous search string" isearch-ring-retreat - :help "Edit previous search string in Isearch history")) - (define-key map [isearch-ring-advance] - '(menu-item "Edit next search string" isearch-ring-advance - :help "Edit next search string in Isearch history")) - (define-key map [isearch-del-char] - '(menu-item "Delete last char from search string" isearch-del-char - :help "Delete last character from search string")) - (define-key map [isearch-delete-char] - '(menu-item "Undo last input item" isearch-delete-char - :help "Undo the effect of the last Isearch command")) - (define-key map [isearch-end-of-buffer] - '(menu-item "Go to last match" isearch-end-of-buffer - :help "Go to last occurrence of current search string")) - (define-key map [isearch-beginning-of-buffer] - '(menu-item "Go to first match" isearch-beginning-of-buffer - :help "Go to first occurrence of current search string")) - (define-key map [isearch-repeat-backward] - '(menu-item "Repeat search backward" isearch-repeat-backward - :help "Repeat current search backward")) - (define-key map [isearch-repeat-forward] - '(menu-item "Repeat search forward" isearch-repeat-forward - :help "Repeat current search forward")) - (define-key map [isearch-nonincremental] - '(menu-item "Nonincremental search" isearch-exit - :help "Start nonincremental search" - :visible (string-equal isearch-string ""))) - (define-key map [isearch-exit] - '(menu-item "Finish search" isearch-exit - :help "Finish search leaving point where it is" - :visible (not (string-equal isearch-string "")))) - (define-key map [isearch-abort] - '(menu-item "Remove characters not found" isearch-abort - :help "Quit current search" - :visible (not isearch-success))) - (define-key map [isearch-cancel] - `(menu-item "Cancel search" isearch-cancel - :help "Cancel current search and return to starting point" - :filter ,(lambda (binding) - (if isearch-success 'isearch-abort binding)))) - map)) - ;; Note: Before adding more key bindings to this map, please keep in ;; mind that any unbound key exits Isearch and runs the command bound ;; to it in the local or global map. So in effect every key unbound @@ -795,13 +642,116 @@ This is like `describe-bindings', but displays only Isearch keys." ;; The key translations defined in the C-x 8 prefix should add ;; characters to the search string. See iso-transl.el. (define-key map "\C-x8\r" 'isearch-char-by-name) - - (define-key map [menu-bar search-menu] - (list 'menu-item "Isearch" isearch-menu-bar-map)) - map) "Keymap for `isearch-mode'.") +(easy-menu-define isearch-menu-bar-map isearch-mode-map + "Menu for `isearch-mode'." + '("Isearch" + ["Cancel search" isearch-cancel + :help "Cancel current search and return to starting point" + :filter (lambda (binding) + (if isearch-success 'isearch-abort binding))] + ["Remove characters not found" isearch-abort + :help "Quit current search" + :visible (not isearch-success)] + ["Finish search" isearch-exit + :help "Finish search leaving point where it is" + :visible (not (string-equal isearch-string ""))] + ["Nonincremental search" isearch-exit + :help "Start nonincremental search" + :visible (string-equal isearch-string "")] + ["Repeat search forward" isearch-repeat-forward + :help "Repeat current search forward"] + ["Repeat search backward" isearch-repeat-backward + :help "Repeat current search backward"] + ["Go to first match" isearch-beginning-of-buffer + :help "Go to first occurrence of current search string"] + ["Go to last match" isearch-end-of-buffer + :help "Go to last occurrence of current search string"] + ["Undo last input item" isearch-delete-char + :help "Undo the effect of the last Isearch command"] + ["Delete last char from search string" isearch-del-char + :help "Delete last character from search string"] + ["Edit next search string" isearch-ring-advance + :help "Edit next search string in Isearch history"] + ["Edit previous search string" isearch-ring-retreat + :help "Edit previous search string in Isearch history"] + ["Edit current search string" isearch-edit-string + :help "Edit current search string"] + ("Yank on search string" + ["Char" isearch-yank-char + :help "Yank char at point on search string"] + ["Word/char" + isearch-yank-word-or-char + :help "Yank next word or char on search string"] + ["Symbol/char" + isearch-yank-symbol-or-char + :help "Yank next symbol or char on search string"] + ["Rest of line" isearch-yank-line + :help "Yank the rest of the current line on search string"] + ["Until char..." isearch-yank-until-char + :help "Yank from point to specified character into search string"] + ["Current kill" isearch-yank-kill + :help "Append current kill to search string"] + ["Previous kill" isearch-yank-pop-only + :help "Replace previous yanked kill on search string"]) + "---" + ["Lax whitespace matching" isearch-toggle-lax-whitespace + :help "Lax whitespace matching" + :style toggle + :selected isearch-lax-whitespace] + ["Case folding matching" isearch-toggle-case-fold + :help "Case folding matching" + :style toggle + :selected isearch-case-fold-search] + ["Character folding matching" isearch-toggle-char-fold + :help "Character folding matching" + :style toggle + :selected (eq isearch-regexp-function + 'char-fold-to-regexp)] + ["Invisible text matching" isearch-toggle-invisible + :help "Invisible text matching" + :style toggle + :selected isearch-invisible] + ["Regexp matching" isearch-toggle-regexp + :help "Regexp matching" + :style toggle + :selected isearch-regexp] + ["Symbol matching" isearch-toggle-symbol + :help "Symbol matching" + :style toggle + :selected (eq isearch-regexp-function + 'isearch-symbol-regexp)] + ["Word matching" isearch-toggle-word + :help "Word matching" + :style toggle + :selected (eq isearch-regexp-function 'word-search-regexp)] + "---" + ["Search for literal char" isearch-quote-char + :help "Search for literal char"] + ["Search for char by name" isearch-char-by-name + :help "Search for character by name"] + "---" + ["Toggle input method" isearch-toggle-input-method + :help "Toggle input method for search"] + ["Turn on specific input method" isearch-toggle-specified-input-method + :help "Turn on specific input method for search"] + ["Turn on transient input method" isearch-transient-input-method + :help "Turn on transient input method for search"] + "---" + ["Highlight all matches for search string" isearch-highlight-regexp + :help "Highlight all matches for current search string"] + ["Show all matches for search string" isearch-occur + :help "Show all matches for current search string"] + ["Replace search string" isearch-query-replace + :help "Replace matches for current search string"] + ["Replace search string as regexp" isearch-query-replace-regexp + :help "Replace matches for current search string as regexp"] + "---" + ["Complete current search string" isearch-complete + :help "Complete current search string over search history"])) + (defvar isearch-tool-bar-old-map nil "Variable holding the old local value of `tool-bar-map', if any.") diff --git a/lisp/loadup.el b/lisp/loadup.el index c16cd61594..1c385e3d2f 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -263,10 +263,10 @@ (load "scroll-bar")) (load "select") (load "emacs-lisp/timer") +(load "emacs-lisp/easymenu") (load "isearch") (load "rfn-eshadow") -(load "emacs-lisp/easymenu") (load "menu-bar") (load "tab-bar") (load "emacs-lisp/lisp") commit 46c501e762661081dd5eddd34ac8866970efefaa Author: Stefan Kangas Date: Sat Feb 27 23:26:59 2021 +0100 Checkdoc fixes in isearch.el * lisp/isearch.el (isearch--set-state, isearch-yank-pop-only) (isearch-search-and-update, isearch-complete-edit, isearch-search): Minor doc fixes. diff --git a/lisp/isearch.el b/lisp/isearch.el index 8266c4b7a0..0d29438f4e 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -26,7 +26,7 @@ ;; Instructions -;; For programmed use of isearch-mode, e.g. calling (isearch-forward), +;; For programmed use of isearch-mode, e.g. calling (`isearch-forward'), ;; isearch-mode behaves modally and does not return until the search ;; is completed. It uses a recursive-edit to behave this way. @@ -46,7 +46,7 @@ ;; exits and searches in the last search direction. ;; Exiting immediately from isearch uses isearch-edit-string instead -;; of nonincremental-search, if search-nonincremental-instead is non-nil. +;; of nonincremental-search, if `search-nonincremental-instead' is non-nil. ;; The name of this option should probably be changed if we decide to ;; keep the behavior. No point in forcing nonincremental search until ;; the last possible moment. @@ -1499,7 +1499,7 @@ REGEXP if non-nil says use the regexp search ring." (apply 'propertize string properties)) (defun isearch-update-from-string-properties (string) - "Update isearch properties from the isearch string" + "Update isearch properties from the isearch STRING." (when (plist-member (text-properties-at 0 string) 'isearch-case-fold-search) (setq isearch-case-fold-search (get-text-property 0 'isearch-case-fold-search string))) @@ -2536,7 +2536,7 @@ minibuffer to read a string from the `kill-ring' as `yank-pop' does." Unlike `isearch-yank-pop', when this command is called not immediately after a `isearch-yank-kill' or a `isearch-yank-pop-only', it only pops the last killed string instead of activating the minibuffer to read -a string from the `kill-ring' as `yank-pop' does. The prefix arg C-u +a string from the `kill-ring' as `yank-pop' does. The prefix arg \\[universal-argument] always reads a string from the `kill-ring' using the minibuffer." (interactive "P") (cond @@ -2695,7 +2695,7 @@ With argument, add COUNT copies of the character." string "")))))))) (defun isearch-search-and-update () - ;; Do the search and update the display. + "Do the search and update the display." (when (or isearch-success ;; Unsuccessful regexp search may become successful by ;; addition of characters which make isearch-string valid @@ -3227,7 +3227,7 @@ If there is no completion possible, say so and continue searching." ;; Message string (defun isearch-message (&optional c-q-hack ellipsis) - ;; Generate and print the message string. + "Generate and print the message string." ;; N.B.: This function should always be called with point at the ;; search point, because in certain (rare) circumstances, undesired @@ -3481,7 +3481,7 @@ Optional third argument, if t, means if fail just return nil (no error). pos1))) (defun isearch-search () - ;; Do the search with the current search string. + "Do the search with the current search string." (if (and (eq isearch-case-fold-search t) search-upper-case) (setq isearch-case-fold-search (isearch-no-upper-case-p isearch-string isearch-regexp))) commit 3b3b16ea17a6ce3169e32acf4aa4c020f4db71d7 Author: Juri Linkov Date: Sat Feb 27 22:09:33 2021 +0200 * lisp/tab-bar.el: Support displaying global-mode-string in the tab bar. * lisp/tab-bar.el (tab-bar--define-keys): Update global-mode-string in mode-line-misc-info with condition to disable global-mode-string in the mode line. (tab-bar-format): New variable. (tab-bar-format-history, tab-bar-format-add-tab) (tab-bar-format-tabs): New functions with body from 'tab-bar-make-keymap-1'. (tab-bar-format-align-right, tab-bar-format-global): New functions for 'tab-bar-format' list. (tab-bar-format-list): New utility function. (tab-bar-make-keymap-1): Just call 'tab-bar-format-list'. https://lists.gnu.org/archive/html/emacs-devel/2020-11/msg01210.html diff --git a/etc/NEWS b/etc/NEWS index 1e950b87dc..883c0700ec 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -493,6 +493,13 @@ value of 'tab-bar-show'. It can be used to enable/disable the tab bar individually on each frame independently from the value of 'tab-bar-mode' and 'tab-bar-show'. +--- +*** New variable 'tab-bar-format' defines a list of tab bar items. +When it contains 'tab-bar-format-global' (possibly appended after +'tab-bar-format-align-right'), then after enabling 'display-time-mode' +(or any other mode that uses 'global-mode-string') it displays time +aligned to the right on the tab bar instead of the mode line. + --- *** 'Mod-9' bound to 'tab-last' now switches to the last tab. It also supports a negative argument. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index c95559a1b7..c3955913e2 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -113,7 +113,21 @@ Possible modifier keys are `control', `meta', `shift', `hyper', `super' and (unless (global-key-binding [(control shift tab)]) (global-set-key [(control shift tab)] 'tab-previous)) (unless (global-key-binding [(control shift iso-lefttab)]) - (global-set-key [(control shift iso-lefttab)] 'tab-previous))) + (global-set-key [(control shift iso-lefttab)] 'tab-previous)) + + ;; Replace default value with a condition that supports displaying + ;; global-mode-string in the tab bar instead of the mode line. + (when (member '(global-mode-string ("" global-mode-string " ")) + mode-line-misc-info) + (setq mode-line-misc-info + (append '(global-mode-string + ("" (:eval (if (and tab-bar-mode + (memq 'tab-bar-format-global + tab-bar-format)) + "" global-mode-string)) + " ")) + (remove '(global-mode-string ("" global-mode-string " ")) + mode-line-misc-info))))) (defun tab-bar--undefine-keys () "Uninstall key bindings previously bound by `tab-bar--define-keys'." @@ -503,56 +517,111 @@ the formatted tab name to display in the tab bar." "")) 'face (if current-p 'tab-bar-tab 'tab-bar-tab-inactive)))) -(defun tab-bar-make-keymap-1 () - "Generate an actual keymap from `tab-bar-map', without caching." +(defvar tab-bar-format '(tab-bar-format-history + tab-bar-format-tabs + tab-bar-separator + tab-bar-format-add-tab) + "Template for displaying tab bar items. +Every item in the list is a function that returns +a string, or a list of menu-item elements, or nil. +When you add more items `tab-bar-format-align-right' and +`tab-bar-format-global' to the end, then after enabling +`display-time-mode' (or any other mode that uses `global-mode-string') +it will display time aligned to the right on the tab bar instead of +the mode line.") + +(defun tab-bar-format-history () + (when (and tab-bar-history-mode tab-bar-history-buttons-show) + `((sep-history-back menu-item ,(tab-bar-separator) ignore) + (history-back + menu-item ,tab-bar-back-button tab-bar-history-back + :help "Click to go back in tab history") + (sep-history-forward menu-item ,(tab-bar-separator) ignore) + (history-forward + menu-item ,tab-bar-forward-button tab-bar-history-forward + :help "Click to go forward in tab history")))) + +(defun tab-bar-format-tabs () (let ((separator (tab-bar-separator)) (tabs (funcall tab-bar-tabs-function)) (i 0)) - (append - '(keymap (mouse-1 . tab-bar-handle-mouse)) - (when (and tab-bar-history-mode tab-bar-history-buttons-show) - `((sep-history-back menu-item ,separator ignore) - (history-back - menu-item ,tab-bar-back-button tab-bar-history-back - :help "Click to go back in tab history") - (sep-history-forward menu-item ,separator ignore) - (history-forward - menu-item ,tab-bar-forward-button tab-bar-history-forward - :help "Click to go forward in tab history"))) - (mapcan - (lambda (tab) - (setq i (1+ i)) - (append - `((,(intern (format "sep-%i" i)) menu-item ,separator ignore)) - (cond - ((eq (car tab) 'current-tab) - `((current-tab - menu-item - ,(funcall tab-bar-tab-name-format-function tab i) - ignore - :help "Current tab"))) - (t - `((,(intern (format "tab-%i" i)) - menu-item - ,(funcall tab-bar-tab-name-format-function tab i) - ,(or - (alist-get 'binding tab) - `(lambda () - (interactive) - (tab-bar-select-tab ,i))) - :help "Click to visit tab")))) - `((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i))) - menu-item "" - ,(or - (alist-get 'close-binding tab) - `(lambda () - (interactive) - (tab-bar-close-tab ,i))))))) - tabs) - `((sep-add-tab menu-item ,separator ignore)) - (when (and tab-bar-new-button-show tab-bar-new-button) - `((add-tab menu-item ,tab-bar-new-button tab-bar-new-tab - :help "New tab")))))) + (mapcan + (lambda (tab) + (setq i (1+ i)) + (append + `((,(intern (format "sep-%i" i)) menu-item ,separator ignore)) + (cond + ((eq (car tab) 'current-tab) + `((current-tab + menu-item + ,(funcall tab-bar-tab-name-format-function tab i) + ignore + :help "Current tab"))) + (t + `((,(intern (format "tab-%i" i)) + menu-item + ,(funcall tab-bar-tab-name-format-function tab i) + ,(or + (alist-get 'binding tab) + `(lambda () + (interactive) + (tab-bar-select-tab ,i))) + :help "Click to visit tab")))) + `((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i))) + menu-item "" + ,(or + (alist-get 'close-binding tab) + `(lambda () + (interactive) + (tab-bar-close-tab ,i))))))) + tabs))) + +(defun tab-bar-format-add-tab () + (when (and tab-bar-new-button-show tab-bar-new-button) + `((add-tab menu-item ,tab-bar-new-button tab-bar-new-tab + :help "New tab")))) + +(defun tab-bar-format-align-right () + "Align the rest of tab bar items to the right." + (let* ((rest (cdr (memq 'tab-bar-format-align-right tab-bar-format))) + (rest (tab-bar-format-list rest)) + (rest (mapconcat (lambda (item) (nth 2 item)) rest "")) + (hpos (length rest)) + (str (propertize " " 'display `(space :align-to (- right ,hpos))))) + `((tab-bar-format-align-right menu-item ,str ignore)))) + +(defun tab-bar-format-global () + "Format `global-mode-string' to display it in the tab bar. +When `tab-bar-format-global' is added to `tab-bar-format' +(possibly appended after `tab-bar-format-align-right'), +then modes that display information on the mode line +using `global-mode-string' will display the same text +on the tab bar instead." + `((tab-bar-format-global + menu-item + ,(format-mode-line global-mode-string) + ignore))) + +(defun tab-bar-format-list (format-list) + (let ((i 0)) + (apply #'append + (mapcar + (lambda (format) + (setq i (1+ i)) + (cond + ((functionp format) + (let ((ret (funcall format))) + (when (stringp ret) + (setq ret `((,(intern (format "str-%i" i)) + menu-item ,ret ignore)))) + ret)))) + format-list)))) + +(defun tab-bar-make-keymap-1 () + "Generate an actual keymap from `tab-bar-map', without caching." + (append + '(keymap (mouse-1 . tab-bar-handle-mouse)) + (tab-bar-format-list tab-bar-format))) ;; Some window-configuration parameters don't need to be persistent. commit 53f6218cdc677cda38d23b9049c80ab84e7b4f31 Author: Juri Linkov Date: Sat Feb 27 22:00:51 2021 +0200 * lisp/subr.el (read-char-choice-with-read-key): New function. * lisp/subr.el (read-char-choice): Move most of the function body to 'read-char-choice-with-read-key'. (read-char-choice-with-read-key): New function with body from 'read-char-choice'. diff --git a/lisp/subr.el b/lisp/subr.el index 2323e5dce2..0c97c603a6 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2832,6 +2832,11 @@ This function is used by the `interactive' code letter `n'." Otherwise, use the minibuffer.") (defun read-char-choice (prompt chars &optional inhibit-keyboard-quit) + (if (not read-char-choice-use-read-key) + (read-char-from-minibuffer prompt chars) + (read-char-choice-with-read-key prompt chars inhibit-keyboard-quit))) + +(defun read-char-choice-with-read-key (prompt chars &optional inhibit-keyboard-quit) "Read and return one of CHARS, prompting for PROMPT. Any input that is not one of CHARS is ignored. @@ -2841,46 +2846,44 @@ keyboard-quit events while waiting for a valid input. If you bind the variable `help-form' to a non-nil value while calling this function, then pressing `help-char' causes it to evaluate `help-form' and display the result." - (if (not read-char-choice-use-read-key) - (read-char-from-minibuffer prompt chars) - (unless (consp chars) - (error "Called `read-char-choice' without valid char choices")) - (let (char done show-help (helpbuf " *Char Help*")) - (let ((cursor-in-echo-area t) - (executing-kbd-macro executing-kbd-macro) - (esc-flag nil)) - (save-window-excursion ; in case we call help-form-show - (while (not done) - (unless (get-text-property 0 'face prompt) - (setq prompt (propertize prompt 'face 'minibuffer-prompt))) - (setq char (let ((inhibit-quit inhibit-keyboard-quit)) - (read-key prompt))) - (and show-help (buffer-live-p (get-buffer helpbuf)) - (kill-buffer helpbuf)) - (cond - ((not (numberp char))) - ;; If caller has set help-form, that's enough. - ;; They don't explicitly have to add help-char to chars. - ((and help-form - (eq char help-char) - (setq show-help t) - (help-form-show))) - ((memq char chars) - (setq done t)) - ((and executing-kbd-macro (= char -1)) - ;; read-event returns -1 if we are in a kbd macro and - ;; there are no more events in the macro. Attempt to - ;; get an event interactively. - (setq executing-kbd-macro nil)) - ((not inhibit-keyboard-quit) - (cond - ((and (null esc-flag) (eq char ?\e)) - (setq esc-flag t)) - ((memq char '(?\C-g ?\e)) - (keyboard-quit)))))))) - ;; Display the question with the answer. But without cursor-in-echo-area. - (message "%s%s" prompt (char-to-string char)) - char))) + (unless (consp chars) + (error "Called `read-char-choice' without valid char choices")) + (let (char done show-help (helpbuf " *Char Help*")) + (let ((cursor-in-echo-area t) + (executing-kbd-macro executing-kbd-macro) + (esc-flag nil)) + (save-window-excursion ; in case we call help-form-show + (while (not done) + (unless (get-text-property 0 'face prompt) + (setq prompt (propertize prompt 'face 'minibuffer-prompt))) + (setq char (let ((inhibit-quit inhibit-keyboard-quit)) + (read-key prompt))) + (and show-help (buffer-live-p (get-buffer helpbuf)) + (kill-buffer helpbuf)) + (cond + ((not (numberp char))) + ;; If caller has set help-form, that's enough. + ;; They don't explicitly have to add help-char to chars. + ((and help-form + (eq char help-char) + (setq show-help t) + (help-form-show))) + ((memq char chars) + (setq done t)) + ((and executing-kbd-macro (= char -1)) + ;; read-event returns -1 if we are in a kbd macro and + ;; there are no more events in the macro. Attempt to + ;; get an event interactively. + (setq executing-kbd-macro nil)) + ((not inhibit-keyboard-quit) + (cond + ((and (null esc-flag) (eq char ?\e)) + (setq esc-flag t)) + ((memq char '(?\C-g ?\e)) + (keyboard-quit)))))))) + ;; Display the question with the answer. But without cursor-in-echo-area. + (message "%s%s" prompt (char-to-string char)) + char)) (defun sit-for (seconds &optional nodisp obsolete) "Redisplay, then wait for SECONDS seconds. Stop when input is available. commit 3a7702135377402015368c8307503b62c421655c Author: Stefan Kangas Date: Sat Feb 27 20:22:43 2021 +0100 ; Fix mistake in easymenu conversion * lisp/progmodes/elisp-mode.el (emacs-lisp-mode-menu): Use :style and :selected instead of :button. diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 048f657372..cfc8d8fcf8 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -149,8 +149,9 @@ All commands in `lisp-mode-shared-map' are inherited by this map.") ["Check Documentation Strings" checkdoc :help "Check documentation strings for style requirements"] ["Auto-Display Documentation Strings" eldoc-mode - :button (:toggle . (bound-and-true-p eldoc-mode)) - :help "Display the documentation string for the item under cursor"])) + :help "Display the documentation string for the item under cursor" + :style toggle + :selected (bound-and-true-p eldoc-mode)])) (defun emacs-lisp-byte-compile () "Byte compile the file containing the current buffer." commit 0f91948372466875884e1219ce51302f6b2dab6b Author: Stefan Kangas Date: Sat Feb 27 20:17:03 2021 +0100 Convert Buffer-menu-mode menu to easymenu * lisp/buff-menu.el (Buffer-menu-mode-map): Move menu definition from here... (Buffer-menu-mode-menu): ...to here, and convert to easymenu. diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el index 6df935fef8..340c926f8d 100644 --- a/lisp/buff-menu.el +++ b/lisp/buff-menu.el @@ -117,8 +117,7 @@ This is set by the prefix argument to `buffer-menu' and related commands.") (defvar Buffer-menu-mode-map - (let ((map (make-sparse-keymap)) - (menu-map (make-sparse-keymap))) + (let ((map (make-sparse-keymap))) (set-keymap-parent map tabulated-list-mode-map) (define-key map "v" 'Buffer-menu-select) (define-key map "2" 'Buffer-menu-2-window) @@ -152,82 +151,63 @@ commands.") (define-key map [mouse-2] 'Buffer-menu-mouse-select) (define-key map [follow-link] 'mouse-face) - - (define-key map [menu-bar Buffer-menu-mode] (cons (purecopy "Buffer-Menu") menu-map)) - (bindings--define-key menu-map [quit] - '(menu-item "Quit" quit-window - :help "Remove the buffer menu from the display")) - (bindings--define-key menu-map [rev] - '(menu-item "Refresh" revert-buffer - :help "Refresh the *Buffer List* buffer contents")) - (bindings--define-key menu-map [s0] menu-bar-separator) - (bindings--define-key menu-map [tf] - '(menu-item "Show Only File Buffers" Buffer-menu-toggle-files-only - :button (:toggle . Buffer-menu-files-only) - :help "Toggle whether the current buffer-menu displays only file buffers")) - (bindings--define-key menu-map [s1] menu-bar-separator) - ;; FIXME: The "Select" entries could use better names... - (bindings--define-key menu-map [sel] - '(menu-item "Select Marked" Buffer-menu-select - :help "Select this line's buffer; also display buffers marked with `>'")) - (bindings--define-key menu-map [bm2] - '(menu-item "Select Two" Buffer-menu-2-window - :help "Select this line's buffer, with previous buffer in second window")) - (bindings--define-key menu-map [bm1] - '(menu-item "Select Current" Buffer-menu-1-window - :help "Select this line's buffer, alone, in full frame")) - (bindings--define-key menu-map [ow] - '(menu-item "Select in Other Window" Buffer-menu-other-window - :help "Select this line's buffer in other window, leaving buffer menu visible")) - (bindings--define-key menu-map [tw] - '(menu-item "Select in Current Window" Buffer-menu-this-window - :help "Select this line's buffer in this window")) - (bindings--define-key menu-map [s2] menu-bar-separator) - (bindings--define-key menu-map [is] - '(menu-item "Regexp Isearch Marked Buffers..." Buffer-menu-isearch-buffers-regexp - :help "Search for a regexp through all marked buffers using Isearch")) - (bindings--define-key menu-map [ir] - '(menu-item "Isearch Marked Buffers..." Buffer-menu-isearch-buffers - :help "Search for a string through all marked buffers using Isearch")) - (bindings--define-key menu-map [mo] - '(menu-item "Multi Occur Marked Buffers..." Buffer-menu-multi-occur - :help "Show lines matching a regexp in marked buffers using Occur")) - (bindings--define-key menu-map [s3] menu-bar-separator) - (bindings--define-key menu-map [by] - '(menu-item "Bury" Buffer-menu-bury - :help "Bury the buffer listed on this line")) - (bindings--define-key menu-map [vt] - '(menu-item "Set Unmodified" Buffer-menu-not-modified - :help "Mark buffer on this line as unmodified (no changes to save)")) - (bindings--define-key menu-map [ex] - '(menu-item "Execute" Buffer-menu-execute - :help "Save and/or delete buffers marked with s or k commands")) - (bindings--define-key menu-map [s4] menu-bar-separator) - (bindings--define-key menu-map [delb] - '(menu-item "Mark for Delete and Move Backwards" Buffer-menu-delete-backwards - :help "Mark buffer on this line to be deleted by x command and move up one line")) - (bindings--define-key menu-map [del] - '(menu-item "Mark for Delete" Buffer-menu-delete - :help "Mark buffer on this line to be deleted by x command")) - - (bindings--define-key menu-map [sv] - '(menu-item "Mark for Save" Buffer-menu-save - :help "Mark buffer on this line to be saved by x command")) - (bindings--define-key menu-map [umk] - '(menu-item "Unmark" Buffer-menu-unmark - :help "Cancel all requested operations on buffer on this line and move down")) - (bindings--define-key menu-map [umkab] - '(menu-item "Remove marks..." Buffer-menu-unmark-all-buffers - :help "Cancel a requested operation on all buffers")) - (bindings--define-key menu-map [umka] - '(menu-item "Unmark all" Buffer-menu-unmark-all - :help "Cancel all requested operations on buffers")) - (bindings--define-key menu-map [mk] - '(menu-item "Mark" Buffer-menu-mark - :help "Mark buffer on this line for being displayed by v command")) map) "Local keymap for `Buffer-menu-mode' buffers.") +(easy-menu-define Buffer-menu-mode-menu Buffer-menu-mode-map + "Menu for `Buffer-menu-mode' buffers." + '("Buffer-Menu" + ["Mark" Buffer-menu-mark + :help "Mark buffer on this line for being displayed by v command"] + ["Unmark all" Buffer-menu-unmark-all + :help "Cancel all requested operations on buffers"] + ["Remove marks..." Buffer-menu-unmark-all-buffers + :help "Cancel a requested operation on all buffers"] + ["Unmark" Buffer-menu-unmark + :help "Cancel all requested operations on buffer on this line and move down"] + ["Mark for Save" Buffer-menu-save + :help "Mark buffer on this line to be saved by x command"] + ["Mark for Delete" Buffer-menu-delete + :help "Mark buffer on this line to be deleted by x command"] + ["Mark for Delete and Move Backwards" Buffer-menu-delete-backwards + :help "Mark buffer on this line to be deleted by x command and move up one line"] + "---" + ["Execute" Buffer-menu-execute + :help "Save and/or delete buffers marked with s or k commands"] + ["Set Unmodified" Buffer-menu-not-modified + :help "Mark buffer on this line as unmodified (no changes to save)"] + ["Bury" Buffer-menu-bury + :help "Bury the buffer listed on this line"] + "---" + ["Multi Occur Marked Buffers..." Buffer-menu-multi-occur + :help "Show lines matching a regexp in marked buffers using Occur"] + ["Isearch Marked Buffers..." Buffer-menu-isearch-buffers + :help "Search for a string through all marked buffers using Isearch"] + ["Regexp Isearch Marked Buffers..." Buffer-menu-isearch-buffers-regexp + :help "Search for a regexp through all marked buffers using Isearch"] + "---" + ;; FIXME: The "Select" entries could use better names... + ["Select in Current Window" Buffer-menu-this-window + :help "Select this line's buffer in this window"] + ["Select in Other Window" Buffer-menu-other-window + :help "Select this line's buffer in other window, leaving buffer menu visible"] + ["Select Current" Buffer-menu-1-window + :help "Select this line's buffer, alone, in full frame"] + ["Select Two" Buffer-menu-2-window + :help "Select this line's buffer, with previous buffer in second window"] + ["Select Marked" Buffer-menu-select + :help "Select this line's buffer; also display buffers marked with `>'"] + "---" + ["Show Only File Buffers" Buffer-menu-toggle-files-only + :help "Toggle whether the current buffer-menu displays only file buffers" + :style toggle + :selected Buffer-menu-files-only] + "---" + ["Refresh" revert-buffer + :help "Refresh the *Buffer List* buffer contents"] + ["Quit" quit-window + :help "Remove the buffer menu from the display"])) + (define-derived-mode Buffer-menu-mode tabulated-list-mode "Buffer Menu" "Major mode for Buffer Menu buffers. The Buffer Menu is invoked by the commands \\[list-buffers], commit b34d39170b67a7a285f7c8c2ea1b4128b531aad9 Author: Stefan Kangas Date: Sat Feb 27 18:43:20 2021 +0100 Minor fixes after preloading easymenu * lisp/cedet/ede/dired.el: * lisp/dired-x.el: * lisp/filesets.el: * lisp/follow.el: * lisp/gnus/gnus-registry.el: * lisp/net/eudc.el: * lisp/printing.el: * lisp/recentf.el: * lisp/speedbar.el: Remove redundant require of easymenu; it is now preloaded. * lisp/org/org.el: * lisp/progmodes/antlr-mode.el: * lisp/progmodes/vhdl-mode.el: * lisp/textmodes/reftex.el: Don't require easymenu in Emacs 28 or later. * etc/NEWS: Announce that 'easymenu' is now preloaded. diff --git a/etc/NEWS b/etc/NEWS index cb307675d1..1e950b87dc 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2387,6 +2387,9 @@ This can be used to control whether the defined mode is a command or not, and is useful when defining commands that aren't meant to be used by users directly. +--- +** The 'easymenu' library is now preloaded. + ** The 'values' variable is now obsolete. --- diff --git a/lisp/cedet/ede/dired.el b/lisp/cedet/ede/dired.el index 7eb42ed9de..8b9eae0b43 100644 --- a/lisp/cedet/ede/dired.el +++ b/lisp/cedet/ede/dired.el @@ -30,7 +30,6 @@ ;;; Code: -(require 'easymenu) (require 'dired) (require 'ede) diff --git a/lisp/dired-x.el b/lisp/dired-x.el index 1199de183f..5f31bc402f 100644 --- a/lisp/dired-x.el +++ b/lisp/dired-x.el @@ -236,8 +236,6 @@ to nil: a pipe using `zcat' or `gunzip -c' will be used." ;;; MENU BINDINGS -(require 'easymenu) - (when-let ((menu (lookup-key dired-mode-map [menu-bar]))) (easy-menu-add-item menu '("Operate") ["Find Files" dired-do-find-marked-files diff --git a/lisp/filesets.el b/lisp/filesets.el index 2ef13ae832..a51b6f8135 100644 --- a/lisp/filesets.el +++ b/lisp/filesets.el @@ -90,7 +90,6 @@ (require 'cl-lib) (require 'seq) -(require 'easymenu) ;;; Some variables diff --git a/lisp/follow.el b/lisp/follow.el index 069758747c..42e3b60ec4 100644 --- a/lisp/follow.el +++ b/lisp/follow.el @@ -201,7 +201,6 @@ ;;; Code: -(require 'easymenu) (eval-when-compile (require 'cl-lib)) ;;; Variables diff --git a/lisp/gnus/gnus-registry.el b/lisp/gnus/gnus-registry.el index 9a22256113..e3b9c19618 100644 --- a/lisp/gnus/gnus-registry.el +++ b/lisp/gnus/gnus-registry.el @@ -88,7 +88,6 @@ (require 'gnus-art) (require 'gnus-util) (require 'nnmail) -(require 'easymenu) (require 'registry) (defvar gnus-adaptive-word-syntax-table) diff --git a/lisp/net/eudc.el b/lisp/net/eudc.el index afdf7c9a43..4f048045d5 100644 --- a/lisp/net/eudc.el +++ b/lisp/net/eudc.el @@ -1052,8 +1052,6 @@ queries the server for the existing fields and displays a corresponding form." ;;{{{ Menus and keymaps -(require 'easymenu) - (defconst eudc-custom-generated-menu (cdr (custom-menu-create 'eudc))) (defconst eudc-tail-menu diff --git a/lisp/org/org.el b/lisp/org/org.el index fcf02f1329..41898dc202 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -4757,7 +4757,8 @@ This is for getting out of special buffers like capture.") ;; Other stuff we need. (require 'time-date) (unless (fboundp 'time-subtract) (defalias 'time-subtract 'subtract-time)) -(require 'easymenu) +(when (< emacs-major-version 28) ; preloaded in Emacs 28 + (require 'easymenu)) (require 'org-entities) (require 'org-faces) diff --git a/lisp/printing.el b/lisp/printing.el index 2f234b7b05..f6b9494e17 100644 --- a/lisp/printing.el +++ b/lisp/printing.el @@ -1014,7 +1014,6 @@ Please send all bug fixes and enhancements to (require 'lpr) (require 'ps-print) -(require 'easymenu) (and (string< ps-print-version "6.6.4") (error "`printing' requires `ps-print' package version 6.6.4 or later")) diff --git a/lisp/progmodes/antlr-mode.el b/lisp/progmodes/antlr-mode.el index d569bf898c..8a1d441773 100644 --- a/lisp/progmodes/antlr-mode.el +++ b/lisp/progmodes/antlr-mode.el @@ -84,7 +84,8 @@ (eval-when-compile (require 'cl-lib)) -(require 'easymenu) +(when (< emacs-major-version 28) ; preloaded in Emacs 28 + (require 'easymenu)) (require 'cc-mode) ;; More compile-time-macros diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el index c4de800e33..c8e55da642 100644 --- a/lisp/progmodes/vhdl-mode.el +++ b/lisp/progmodes/vhdl-mode.el @@ -2159,7 +2159,8 @@ your style, only those that are different from the default.") ;; mandatory (require 'compile) ; XEmacs -(require 'easymenu) +(when (< emacs-major-version 28) ; preloaded in Emacs 28 + (require 'easymenu)) (require 'hippie-exp) ;; optional (minimize warning messages during compile) diff --git a/lisp/recentf.el b/lisp/recentf.el index d39a523289..48b8e2b671 100644 --- a/lisp/recentf.el +++ b/lisp/recentf.el @@ -37,7 +37,6 @@ ;; ;;; Code: -(require 'easymenu) (require 'tree-widget) (require 'timer) diff --git a/lisp/speedbar.el b/lisp/speedbar.el index d64c72184e..0e2a3749be 100644 --- a/lisp/speedbar.el +++ b/lisp/speedbar.el @@ -106,7 +106,6 @@ ;;; TODO: ;; - Timeout directories we haven't visited in a while. -(require 'easymenu) (require 'dframe) (require 'ezimage) diff --git a/lisp/textmodes/reftex.el b/lisp/textmodes/reftex.el index be9b23677c..269d676c2b 100644 --- a/lisp/textmodes/reftex.el +++ b/lisp/textmodes/reftex.el @@ -51,7 +51,8 @@ ;;; Code: (eval-when-compile (require 'cl-lib)) -(require 'easymenu) +(when (< emacs-major-version 28) ; preloaded in Emacs 28 + (require 'easymenu)) (defvar reftex-tables-dirty t "Flag showing if tables need to be re-computed.") commit a4d7235f1a22701f53d3ea9eb6a9da3cbe0cb46a Author: Glenn Morris Date: Sat Feb 27 10:02:24 2021 -0800 Fix doc/misc Makefile for out-of-tree with relative path * doc/misc/Makefile.in (org_template): Fix for relative srcdir. diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in index d0225db9ba..662537b451 100644 --- a/doc/misc/Makefile.in +++ b/doc/misc/Makefile.in @@ -239,7 +239,7 @@ define org_template $(1:.org=.texi): $(1) @rm -f $$@ $${AM_V_GEN}cd "$${srcdir}" && $${emacs} -l ox-texinfo \ - -f org-texinfo-export-to-texinfo-batch $$< $$@ + -f org-texinfo-export-to-texinfo-batch $$(notdir $$<) $$(notdir $$@) endef $(foreach orgfile,${ORG_SRC},$(eval $(call org_template,$(orgfile)))) commit 27da93862fff36d095fa3a3c7f98e95ccce922fb Author: Glenn Morris Date: Sat Feb 27 09:31:29 2021 -0800 Improve Makefile treatment of org sources in doc/misc * doc/misc/Makefile.in (ORG_SETUP): New variable. (ORG_SRC): Use wildcard rather than hard-coding. (org_template): Adjust for input containing $srcdir and suffix. (org_setup_template): New template. diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in index 7c11f8c048..d0225db9ba 100644 --- a/doc/misc/Makefile.in +++ b/doc/misc/Makefile.in @@ -85,7 +85,8 @@ INFO_TARGETS = $(INFO_COMMON) efaq-w32 ## Some manuals have their source in .org format. ## This is discouraged because the .texi files it generates ## are not as well formatted as handwritten ones. -ORG_SRC = org modus-themes +ORG_SETUP = $(wildcard ${srcdir}/*-setup.org) +ORG_SRC = $(filter-out ${ORG_SETUP},$(wildcard ${srcdir}/*.org)) # There are some naming differences between the info targets and the other # targets, so let's resolve them here. @@ -235,7 +236,7 @@ emacs = "${EMACS}" -batch --no-site-file --no-site-lisp # Work in srcdir (and use abs_top_builddir) so that +setupfile and # things like org-setup's "version" macro work. Sigh. define org_template - $${srcdir}/$(1).texi: $${srcdir}/$(1).org + $(1:.org=.texi): $(1) @rm -f $$@ $${AM_V_GEN}cd "$${srcdir}" && $${emacs} -l ox-texinfo \ -f org-texinfo-export-to-texinfo-batch $$< $$@ @@ -243,7 +244,12 @@ endef $(foreach orgfile,${ORG_SRC},$(eval $(call org_template,$(orgfile)))) -${srcdir}/org.texi: ${srcdir}/org-setup.org +## foo.org depends on foo-setup.org, if the latter exists. +define org_setup_template + $(1:-setup.org=.texi): $(1) +endef + +$(foreach orgfile,${ORG_SETUP},$(eval $(call org_setup_template,$(orgfile)))) .PHONY: mostlyclean clean distclean bootstrap-clean maintainer-clean commit 082b431e62b5d1f835149874df95941268c8a763 Author: Stefan Monnier Date: Sat Feb 27 12:28:17 2021 -0500 * lisp/emacs-lisp/bytecomp.el: Fix minor regression introduced by pdump After `rm **/*.elc; make` we'd sometimes get loads and loads of unnecessary "Reloading ...". (byte-compile-refresh-preloaded): Don't reload files that are more recent than `temacs` but older than the `.pdmp` file. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index f85979579f..a2fe37a1ee 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -5225,8 +5225,9 @@ already up-to-date." "Reload any Lisp file that was changed since Emacs was dumped. Use with caution." (let* ((argv0 (car command-line-args)) - (emacs-file (executable-find argv0))) - (if (not (and emacs-file (file-executable-p emacs-file))) + (emacs-file (or (cdr (nth 2 (pdumper-stats))) + (executable-find argv0)))) + (if (not (and emacs-file (file-exists-p emacs-file))) (message "Can't find %s to refresh preloaded Lisp files" argv0) (dolist (f (reverse load-history)) (setq f (car f)) commit 2c639a35a6d71d190bea896bbeb14b279e8d8384 Author: Stefan Kangas Date: Sat Feb 27 18:22:59 2021 +0100 Don't require overlay; that's only needed in XEmacs * lisp/allout.el: * lisp/net/eudc.el: * lisp/org/org.el: Don't require overlay; that's only needed in XEmacs. diff --git a/lisp/allout.el b/lisp/allout.el index 7fcf41c430..3981fdd785 100644 --- a/lisp/allout.el +++ b/lisp/allout.el @@ -75,9 +75,6 @@ (declare-function epa-passphrase-callback-function "epa" (context key-id handback)) -;;;_* Dependency loads -(require 'overlay) - ;;;_* USER CUSTOMIZATION VARIABLES: ;;;_ > defgroup allout, allout-keybindings diff --git a/lisp/net/eudc.el b/lisp/net/eudc.el index f61929c9ef..afdf7c9a43 100644 --- a/lisp/net/eudc.el +++ b/lisp/net/eudc.el @@ -49,10 +49,6 @@ (require 'cl-lib) -(eval-and-compile - (if (not (fboundp 'make-overlay)) - (require 'overlay))) - (unless (fboundp 'custom-menu-create) (autoload 'custom-menu-create "cus-edit")) diff --git a/lisp/org/org.el b/lisp/org/org.el index e6a5cca939..fcf02f1329 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -4758,7 +4758,6 @@ This is for getting out of special buffers like capture.") (require 'time-date) (unless (fboundp 'time-subtract) (defalias 'time-subtract 'subtract-time)) (require 'easymenu) -(require 'overlay) (require 'org-entities) (require 'org-faces) commit a5ad6747c9da238bd2bcd335b9744ce9f4972ff1 Author: Stefan Monnier Date: Sat Feb 27 12:21:02 2021 -0500 * lisp/emacs-lisp/cconv.el: Fix uncaught brain farts in last change (cconv--convert-funcbody, cconv-convert): Use `macroexp--warn-wrap` properly. diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el index 7b525b72bd..50a8bebf4c 100644 --- a/lisp/emacs-lisp/cconv.el +++ b/lisp/emacs-lisp/cconv.el @@ -286,7 +286,7 @@ of converted forms." (let (and (pred stringp) msg) (cconv--warn-unused-msg arg "argument"))) (if (assq arg env) (push `(,arg . nil) env)) ;FIXME: Is it needed? - (push (lambda (body) `(macroexp--warn-wrap ,msg ,body)) wrappers)) + (push (lambda (body) (macroexp--warn-wrap msg body)) wrappers)) (_ (if (assq arg env) (push `(,arg . nil) env))))) (setq funcbody (mapcar (lambda (form) @@ -505,7 +505,7 @@ places where they originally did not directly appear." (newprotform (cconv-convert protected-form env extend))) `(condition-case ,var ,(if msg - `(macroexp--warn-wrap msg newprotform) + (macroexp--warn-wrap msg newprotform) newprotform) ,@(mapcar (lambda (handler) commit de33de1a660283f45a10acfaedef20c460553dbd Author: Lars Ingebrigtsen Date: Sat Feb 27 15:58:19 2021 +0100 Add sexp navigation commands to elisp-mode * lisp/progmodes/elisp-mode.el (emacs-lisp-mode-menu): Add some navigation commands (bug#24774). diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 70aa66cdd0..048f657372 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -88,7 +88,16 @@ All commands in `lisp-mode-shared-map' are inherited by this map.") ["Instrument Function for Debugging" edebug-defun :help "Evaluate the top level form point is in, stepping through with Edebug" :keys "C-u C-M-x"] - ["Linting" + ("Navigation" + ["Forward Sexp" forward-sexp + :help "Go to the next s-expression"] + ["Backward Sexp" backward-sexp + :help "Go to the previous s-expression"] + ["Beginning Of Defun" beginning-of-defun + :help "Go to the start of the current function definition"] + ["Up List" up-list + :help "Go one level up and forward"]) + ("Linting" ["Lint Defun" elint-defun :help "Lint the function at point"] ["Lint Buffer" elint-current-buffer @@ -96,8 +105,8 @@ All commands in `lisp-mode-shared-map' are inherited by this map.") ["Lint File..." elint-file :help "Lint a file"] ["Lint Directory..." elint-directory - :help "Lint a directory"]] - ["Profiling" + :help "Lint a directory"]) + ("Profiling" ;; Maybe this should be in a separate submenu from the ELP stuff? ["Start Native Profiler..." profiler-start :help "Start recording profiling information"] @@ -124,8 +133,8 @@ All commands in `lisp-mode-shared-map' are inherited by this map.") ["Remove Instrumentation for All Functions" elp-restore-all :help "Restore the original definitions of all functions being profiled"] ["Remove Instrumentation for Function..." elp-restore-function - :help "Restore an instrumented function to its original definition"]] - ["Tracing" + :help "Restore an instrumented function to its original definition"]) + ("Tracing" ["Trace Function..." trace-function :help "Trace the function given as an argument"] ["Trace Function Quietly..." trace-function-background @@ -134,7 +143,7 @@ All commands in `lisp-mode-shared-map' are inherited by this map.") ["Untrace All" untrace-all :help "Untrace all currently traced functions"] ["Untrace Function..." untrace-function - :help "Untrace function, and possibly activate all remaining advice"]] + :help "Untrace function, and possibly activate all remaining advice"]) ["Construct Regexp" re-builder :help "Construct a regexp interactively"] ["Check Documentation Strings" checkdoc commit cd411ecb28349f80d22488a2c2d0008eb6ad9a9e Author: Stefan Kangas Date: Sat Feb 27 15:15:29 2021 +0100 Convert emacs-lisp-mode menu to easy-menu-define * lisp/loadup.el: Preload easymenu. * lisp/progmodes/elisp-mode.el (emacs-lisp-mode-map): Convert menu to use easy-menu-define (bug#24774). diff --git a/lisp/emacs-lisp/easymenu.el b/lisp/emacs-lisp/easymenu.el index 8ddfb9e78e..faa69241f9 100644 --- a/lisp/emacs-lisp/easymenu.el +++ b/lisp/emacs-lisp/easymenu.el @@ -35,7 +35,6 @@ (defsubst easy-menu-intern (s) (if (stringp s) (intern s) s)) -;;;###autoload (defmacro easy-menu-define (symbol maps doc menu) "Define a pop-up menu and/or menu bar menu specified by MENU. If SYMBOL is non-nil, define SYMBOL as a function to pop up the @@ -166,7 +165,6 @@ This is expected to be bound to a mouse event." "")) (cons menu props))))) -;;;###autoload (defun easy-menu-do-define (symbol maps doc menu) ;; We can't do anything that might differ between Emacs dialects in ;; `easy-menu-define' in order to make byte compiled files @@ -218,7 +216,6 @@ If NAME is provided, it is used for the keymap." If it holds a list, this is expected to be a list of keys already seen in the menu we're processing. Else it means we're not processing a menu.") -;;;###autoload (defun easy-menu-create-menu (menu-name menu-items) "Create a menu called MENU-NAME with items described in MENU-ITEMS. MENU-NAME is a string, the name of the menu. MENU-ITEMS is a list of items @@ -474,7 +471,6 @@ When non-nil, NOEXP indicates that CALLBACK cannot be an expression (eval `(lambda () (interactive) ,callback) t))) command)) -;;;###autoload (defun easy-menu-change (path name items &optional before map) "Change menu found at PATH as item NAME to contain ITEMS. PATH is a list of strings for locating the menu that diff --git a/lisp/loadup.el b/lisp/loadup.el index d60aa2ead2..c16cd61594 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -266,6 +266,7 @@ (load "isearch") (load "rfn-eshadow") +(load "emacs-lisp/easymenu") (load "menu-bar") (load "tab-bar") (load "emacs-lisp/lisp") diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 37bed0c54e..70aa66cdd0 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -46,140 +46,103 @@ It has `lisp-mode-abbrev-table' as its parent." "Syntax table used in `emacs-lisp-mode'.") (defvar emacs-lisp-mode-map - (let ((map (make-sparse-keymap)) - (menu-map (make-sparse-keymap "Emacs-Lisp")) - (lint-map (make-sparse-keymap)) - (prof-map (make-sparse-keymap)) - (tracing-map (make-sparse-keymap))) + (let ((map (make-sparse-keymap))) (set-keymap-parent map lisp-mode-shared-map) (define-key map "\e\t" 'completion-at-point) (define-key map "\e\C-x" 'eval-defun) (define-key map "\e\C-q" 'indent-pp-sexp) - (bindings--define-key map [menu-bar emacs-lisp] - (cons "Emacs-Lisp" menu-map)) - (bindings--define-key menu-map [eldoc] - '(menu-item "Auto-Display Documentation Strings" eldoc-mode - :button (:toggle . (bound-and-true-p eldoc-mode)) - :help "Display the documentation string for the item under cursor")) - (bindings--define-key menu-map [checkdoc] - '(menu-item "Check Documentation Strings" checkdoc - :help "Check documentation strings for style requirements")) - (bindings--define-key menu-map [re-builder] - '(menu-item "Construct Regexp" re-builder - :help "Construct a regexp interactively")) - (bindings--define-key menu-map [tracing] (cons "Tracing" tracing-map)) - (bindings--define-key tracing-map [tr-a] - '(menu-item "Untrace All" untrace-all - :help "Untrace all currently traced functions")) - (bindings--define-key tracing-map [tr-uf] - '(menu-item "Untrace Function..." untrace-function - :help "Untrace function, and possibly activate all remaining advice")) - (bindings--define-key tracing-map [tr-sep] menu-bar-separator) - (bindings--define-key tracing-map [tr-q] - '(menu-item "Trace Function Quietly..." trace-function-background - :help "Trace the function with trace output going quietly to a buffer")) - (bindings--define-key tracing-map [tr-f] - '(menu-item "Trace Function..." trace-function - :help "Trace the function given as an argument")) - (bindings--define-key menu-map [profiling] (cons "Profiling" prof-map)) - (bindings--define-key prof-map [prof-restall] - '(menu-item "Remove Instrumentation for All Functions" elp-restore-all - :help "Restore the original definitions of all functions being profiled")) - (bindings--define-key prof-map [prof-restfunc] - '(menu-item "Remove Instrumentation for Function..." elp-restore-function - :help "Restore an instrumented function to its original definition")) - - (bindings--define-key prof-map [sep-rem] menu-bar-separator) - (bindings--define-key prof-map [prof-resall] - '(menu-item "Reset Counters for All Functions" elp-reset-all - :help "Reset the profiling information for all functions being profiled")) - (bindings--define-key prof-map [prof-resfunc] - '(menu-item "Reset Counters for Function..." elp-reset-function - :help "Reset the profiling information for a function")) - (bindings--define-key prof-map [prof-res] - '(menu-item "Show Profiling Results" elp-results - :help "Display current profiling results")) - (bindings--define-key prof-map [prof-pack] - '(menu-item "Instrument Package..." elp-instrument-package - :help "Instrument for profiling all function that start with a prefix")) - (bindings--define-key prof-map [prof-func] - '(menu-item "Instrument Function..." elp-instrument-function - :help "Instrument a function for profiling")) - ;; Maybe this should be in a separate submenu from the ELP stuff? - (bindings--define-key prof-map [sep-natprof] menu-bar-separator) - (bindings--define-key prof-map [prof-natprof-stop] - '(menu-item "Stop Native Profiler" profiler-stop - :help "Stop recording profiling information" - :enable (and (featurep 'profiler) - (profiler-running-p)))) - (bindings--define-key prof-map [prof-natprof-report] - '(menu-item "Show Profiler Report" profiler-report - :help "Show the current profiler report" - :enable (and (featurep 'profiler) - (profiler-running-p)))) - (bindings--define-key prof-map [prof-natprof-start] - '(menu-item "Start Native Profiler..." profiler-start - :help "Start recording profiling information")) - - (bindings--define-key menu-map [lint] (cons "Linting" lint-map)) - (bindings--define-key lint-map [lint-di] - '(menu-item "Lint Directory..." elint-directory - :help "Lint a directory")) - (bindings--define-key lint-map [lint-f] - '(menu-item "Lint File..." elint-file - :help "Lint a file")) - (bindings--define-key lint-map [lint-b] - '(menu-item "Lint Buffer" elint-current-buffer - :help "Lint the current buffer")) - (bindings--define-key lint-map [lint-d] - '(menu-item "Lint Defun" elint-defun - :help "Lint the function at point")) - (bindings--define-key menu-map [edebug-defun] - '(menu-item "Instrument Function for Debugging" edebug-defun - :help "Evaluate the top level form point is in, stepping through with Edebug" - :keys "C-u C-M-x")) - (bindings--define-key menu-map [separator-byte] menu-bar-separator) - (bindings--define-key menu-map [disas] - '(menu-item "Disassemble Byte Compiled Object..." disassemble - :help "Print disassembled code for OBJECT in a buffer")) - (bindings--define-key menu-map [byte-recompile] - '(menu-item "Byte-recompile Directory..." byte-recompile-directory - :help "Recompile every `.el' file in DIRECTORY that needs recompilation")) - (bindings--define-key menu-map [emacs-byte-compile-and-load] - '(menu-item "Byte-compile and Load" emacs-lisp-byte-compile-and-load - :help "Byte-compile the current file (if it has changed), then load compiled code")) - (bindings--define-key menu-map [byte-compile] - '(menu-item "Byte-compile This File" emacs-lisp-byte-compile - :help "Byte compile the file containing the current buffer")) - (bindings--define-key menu-map [separator-eval] menu-bar-separator) - (bindings--define-key menu-map [ielm] - '(menu-item "Interactive Expression Evaluation" ielm - :help "Interactively evaluate Emacs Lisp expressions")) - (bindings--define-key menu-map [eval-buffer] - '(menu-item "Evaluate Buffer" eval-buffer - :help "Execute the current buffer as Lisp code")) - (bindings--define-key menu-map [eval-region] - '(menu-item "Evaluate Region" eval-region - :help "Execute the region as Lisp code" - :enable mark-active)) - (bindings--define-key menu-map [eval-sexp] - '(menu-item "Evaluate Last S-expression" eval-last-sexp - :help "Evaluate sexp before point; print value in echo area")) - (bindings--define-key menu-map [separator-format] menu-bar-separator) - (bindings--define-key menu-map [comment-region] - '(menu-item "Comment Out Region" comment-region - :help "Comment or uncomment each line in the region" - :enable mark-active)) - (bindings--define-key menu-map [indent-region] - '(menu-item "Indent Region" indent-region - :help "Indent each nonblank line in the region" - :enable mark-active)) - (bindings--define-key menu-map [indent-line] - '(menu-item "Indent Line" lisp-indent-line)) map) "Keymap for Emacs Lisp mode. All commands in `lisp-mode-shared-map' are inherited by this map.") +(easy-menu-define emacs-lisp-mode-menu emacs-lisp-mode-map + "Menu for Emacs Lisp mode." + '("Emacs-Lisp" + ["Indent Line" lisp-indent-line] + ["Indent Region" indent-region + :help "Indent each nonblank line in the region" + :active mark-active] + ["Comment Out Region" comment-region + :help "Comment or uncomment each line in the region" + :active mark-active] + "---" + ["Evaluate Last S-expression" eval-last-sexp + :help "Evaluate sexp before point; print value in echo area"] + ["Evaluate Region" eval-region + :help "Execute the region as Lisp code" + :active mark-active] + ["Evaluate Buffer" eval-buffer + :help "Execute the current buffer as Lisp code"] + ["Interactive Expression Evaluation" ielm + :help "Interactively evaluate Emacs Lisp expressions"] + "---" + ["Byte-compile This File" emacs-lisp-byte-compile + :help "Byte compile the file containing the current buffer"] + ["Byte-compile and Load" emacs-lisp-byte-compile-and-load + :help "Byte-compile the current file (if it has changed), then load compiled code"] + ["Byte-recompile Directory..." byte-recompile-directory + :help "Recompile every `.el' file in DIRECTORY that needs recompilation"] + ["Disassemble Byte Compiled Object..." disassemble + :help "Print disassembled code for OBJECT in a buffer"] + "---" + ["Instrument Function for Debugging" edebug-defun + :help "Evaluate the top level form point is in, stepping through with Edebug" + :keys "C-u C-M-x"] + ["Linting" + ["Lint Defun" elint-defun + :help "Lint the function at point"] + ["Lint Buffer" elint-current-buffer + :help "Lint the current buffer"] + ["Lint File..." elint-file + :help "Lint a file"] + ["Lint Directory..." elint-directory + :help "Lint a directory"]] + ["Profiling" + ;; Maybe this should be in a separate submenu from the ELP stuff? + ["Start Native Profiler..." profiler-start + :help "Start recording profiling information"] + ["Show Profiler Report" profiler-report + :help "Show the current profiler report" + :active (and (featurep 'profiler) + (profiler-running-p))] + ["Stop Native Profiler" profiler-stop + :help "Stop recording profiling information" + :active (and (featurep 'profiler) + (profiler-running-p))] + "---" + ["Instrument Function..." elp-instrument-function + :help "Instrument a function for profiling"] + ["Instrument Package..." elp-instrument-package + :help "Instrument for profiling all function that start with a prefix"] + ["Show Profiling Results" elp-results + :help "Display current profiling results"] + ["Reset Counters for Function..." elp-reset-function + :help "Reset the profiling information for a function"] + ["Reset Counters for All Functions" elp-reset-all + :help "Reset the profiling information for all functions being profiled"] + "---" + ["Remove Instrumentation for All Functions" elp-restore-all + :help "Restore the original definitions of all functions being profiled"] + ["Remove Instrumentation for Function..." elp-restore-function + :help "Restore an instrumented function to its original definition"]] + ["Tracing" + ["Trace Function..." trace-function + :help "Trace the function given as an argument"] + ["Trace Function Quietly..." trace-function-background + :help "Trace the function with trace output going quietly to a buffer"] + "---" + ["Untrace All" untrace-all + :help "Untrace all currently traced functions"] + ["Untrace Function..." untrace-function + :help "Untrace function, and possibly activate all remaining advice"]] + ["Construct Regexp" re-builder + :help "Construct a regexp interactively"] + ["Check Documentation Strings" checkdoc + :help "Check documentation strings for style requirements"] + ["Auto-Display Documentation Strings" eldoc-mode + :button (:toggle . (bound-and-true-p eldoc-mode)) + :help "Display the documentation string for the item under cursor"])) + (defun emacs-lisp-byte-compile () "Byte compile the file containing the current buffer." (interactive nil emacs-lisp-mode) commit 36440b15d3552908614f0bd52f4defed8c1deed5 Author: Matt Armstrong Date: Mon Feb 22 16:40:05 2021 -0800 Remove unecessary unlock-buffer calls * lisp/files.el (revert-buffer-insert-file-contents--default-function): Remove vestigial call to `unlock-buffer'. * lisp/simple.el (primitive-undo): Assume unlock-buffer is always bound. (Bug#46701) diff --git a/lisp/files.el b/lisp/files.el index 68894ca2ce..e5fa1d8b22 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -6235,11 +6235,6 @@ an auto-save file." "Cannot revert unreadable file %s") file-name)) (t - ;; Bind buffer-file-name to nil - ;; so that we don't try to lock the file. - (let ((buffer-file-name nil)) - (or auto-save-p - (unlock-buffer))) (widen) (let ((coding-system-for-read ;; Auto-saved file should be read by Emacs's diff --git a/lisp/simple.el b/lisp/simple.el index 403861351c..f8050091d5 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -3043,8 +3043,7 @@ Return what remains of the list." (and (consp time) (equal (list (car time) (cdr time)) (visited-file-modtime)))) - (when (fboundp 'unlock-buffer) - (unlock-buffer)) + (unlock-buffer) (set-buffer-modified-p nil))) ;; Element (nil PROP VAL BEG . END) is property change. (`(nil . ,(or `(,prop ,val ,beg . ,end) pcase--dontcare)) commit 2c5f21541957e2420e54ab2a70883140811708f7 Author: Eli Zaretskii Date: Sat Feb 27 09:26:55 2021 +0200 Avoid crashes in Mew due to corrupted tool-bar label * src/gtkutil.c (update_frame_tool_bar): Don't keep around a 'char *' pointer to a Lisp string's contents when calling Lisp, because that could relocate string data; keep the Lisp string itself instead. This avoids crashes in Mew. (Bug#46791) diff --git a/src/gtkutil.c b/src/gtkutil.c index d824601be5..825fbe1d45 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -5019,11 +5019,10 @@ update_frame_tool_bar (struct frame *f) GtkWidget *wbutton = NULL; Lisp_Object specified_file; bool vert_only = ! NILP (PROP (TOOL_BAR_ITEM_VERT_ONLY)); - const char *label - = (EQ (style, Qimage) || (vert_only && horiz)) ? NULL - : STRINGP (PROP (TOOL_BAR_ITEM_LABEL)) - ? SSDATA (PROP (TOOL_BAR_ITEM_LABEL)) - : ""; + Lisp_Object label + = (EQ (style, Qimage) || (vert_only && horiz)) + ? Qnil + : PROP (TOOL_BAR_ITEM_LABEL); ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), j); @@ -5136,8 +5135,11 @@ update_frame_tool_bar (struct frame *f) /* If there is an existing widget, check if it's stale; if so, remove it and make a new tool item from scratch. */ - if (ti && xg_tool_item_stale_p (wbutton, stock_name, icon_name, - img, label, horiz)) + if (ti && xg_tool_item_stale_p (wbutton, stock_name, icon_name, img, + NILP (label) + ? NULL + : STRINGP (label) ? SSDATA (label) : "", + horiz)) { gtk_container_remove (GTK_CONTAINER (wtoolbar), GTK_WIDGET (ti)); @@ -5194,7 +5196,11 @@ update_frame_tool_bar (struct frame *f) #else if (w) gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin); #endif - ti = xg_make_tool_item (f, w, &wbutton, label, i, horiz, text_image); + ti = xg_make_tool_item (f, w, &wbutton, + NILP (label) + ? NULL + : STRINGP (label) ? SSDATA (label) : "", + i, horiz, text_image); gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, j); } commit f8b4623db3c9ff75907779881e5b52f246389719 Author: Lars Ingebrigtsen Date: Sat Feb 27 06:02:17 2021 +0100 Compute grep defaults earlier * lisp/progmodes/grep.el (grep): Always compute the defaults (bug#46801). (grep-highlight-matches): Clarify that it's not just used interactively. diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el index 3e92c69913..8c9a1b53b1 100644 --- a/lisp/progmodes/grep.el +++ b/lisp/progmodes/grep.el @@ -88,9 +88,9 @@ To make grep highlight matches even into a pipe, you need the option `always' that forces grep to use `--color=always' to unconditionally output escape sequences. -In interactive usage, the actual value of this variable is set up -by `grep-compute-defaults' when the default value is `auto-detect'. -To change the default value, use \\[customize] or call the function +If the value is `auto-detect' (the default), `grep' will call +`grep-compute-defaults' to compute the value. To change the +default value, use \\[customize] or call the function `grep-apply-setting'." :type '(choice (const :tag "Do not highlight matches with grep markers" nil) (const :tag "Highlight matches with grep markers" t) @@ -915,7 +915,10 @@ list is empty)." (if current-prefix-arg default grep-command) 'grep-history (if current-prefix-arg nil default)))))) - + ;; If called non-interactively, also compute the defaults if we + ;; haven't already. + (when (eq grep-highlight-matches 'auto-detect) + (grep-compute-defaults)) (grep--save-buffers) ;; Setting process-setup-function makes exit-message-function work ;; even when async processes aren't supported. commit 7ac99eeefe26b8a6b1faf25371b375b9dcb66d03 Author: Lars Ingebrigtsen Date: Sat Feb 27 05:43:06 2021 +0100 Change defcustom types of two non-standard hooks * lisp/erc/erc.el (erc-before-connect, erc-after-connect): Change type from 'hook to 'function (bug#34657). diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index dd7f50fb38..7ee409b735 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -2136,19 +2136,20 @@ If no buffer matches, return nil." (erc-current-nick-p nick))))) (defcustom erc-before-connect nil - "Hook called before connecting to a server. -This hook gets executed before `erc' actually invokes `erc-mode' -with your input data. The functions in here get called with three -parameters, SERVER, PORT and NICK." + "Functions called before connecting to a server. +The functions in this variable gets executed before `erc' +actually invokes `erc-mode' with your input data. The functions +in here get called with three parameters, SERVER, PORT and NICK." :group 'erc-hooks - :type 'hook) + :type '(repeat function)) (defcustom erc-after-connect nil - "Hook called after connecting to a server. -This hook gets executed when an end of MOTD has been received. All -functions in here get called with the parameters SERVER and NICK." + "Functions called after connecting to a server. +This functions in this variable gets executed when an end of MOTD +has been received. All functions in here get called with the +parameters SERVER and NICK." :group 'erc-hooks - :type 'hook) + :type '(repeat function)) ;;;###autoload (defun erc-select-read-args () commit c9f5c314ad2243ab98b4f779d8abfb87499aa3aa Author: F. Jason Park Date: Sat Feb 27 05:35:40 2021 +0100 Accept string argument in erc-add-to-input-ring * lisp/erc/erc-ring.el: (erc-add-to-input-ring) (erc-previous-command): Use existing API to grab input. * test/lisp/erc/erc-tests.el: (erc-ring-previous-command) See (bug#46339). diff --git a/lisp/erc/erc-ring.el b/lisp/erc/erc-ring.el index 71a9f8ef3d..028ab1eead 100644 --- a/lisp/erc/erc-ring.el +++ b/lisp/erc/erc-ring.el @@ -69,10 +69,13 @@ Call this function when setting up the mode." (setq erc-input-ring (make-ring comint-input-ring-size))) (setq erc-input-ring-index nil)) -(defun erc-add-to-input-ring (state) - "Add string S to the input ring and reset history position." +(defun erc-add-to-input-ring (state-or-string) + "Add STATE-OR-STRING to input ring and reset history position. +STATE-OR-STRING should be a string or an erc-input object." (unless erc-input-ring (erc-input-ring-setup)) - (ring-insert erc-input-ring (erc-input-string state)) + (ring-insert erc-input-ring (if (erc-input-p state-or-string) + (erc-input-string state-or-string) + state-or-string)) ; string (setq erc-input-ring-index nil)) (defun erc-clear-input-ring () @@ -101,11 +104,10 @@ containing a password." ;; area, push it on the history ring before moving back through ;; the input history, so it will be there when we return to the ;; front. - (if (null erc-input-ring-index) - (when (> (point-max) erc-input-marker) - (erc-add-to-input-ring (buffer-substring erc-input-marker - (point-max))) - (setq erc-input-ring-index 0))) + (when (and (null erc-input-ring-index) + (> (point-max) erc-input-marker)) + (erc-add-to-input-ring (erc-user-input)) + (setq erc-input-ring-index 0)) (setq erc-input-ring-index (if erc-input-ring-index (ring-plus1 erc-input-ring-index diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 26e14b98e9..d13397274a 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -23,6 +23,7 @@ (require 'ert) (require 'erc) +(require 'erc-ring) (ert-deftest erc--read-time-period () (cl-letf (((symbol-function 'read-string) (lambda (&rest _) ""))) @@ -45,3 +46,66 @@ (cl-letf (((symbol-function 'read-string) (lambda (&rest _) "1d"))) (should (equal (erc--read-time-period "foo: ") 86400)))) + +(ert-deftest erc-ring-previous-command-base-case () + (ert-info ("Create ring when nonexistent and do nothing") + (let (erc-input-ring + erc-input-ring-index) + (erc-previous-command) + (should (ring-p erc-input-ring)) + (should (zerop (ring-length erc-input-ring))) + (should-not erc-input-ring-index))) + (should-not erc-input-ring)) + +(ert-deftest erc-ring-previous-command () + (with-current-buffer (get-buffer-create "*#fake*") + (erc-mode) + (insert "\n\n") + (setq erc-input-marker (make-marker) ; these are all local + erc-insert-marker (make-marker) + erc-send-completed-hook nil) + (set-marker erc-insert-marker (point-max)) + (erc-display-prompt) + (should (= (point) erc-input-marker)) + (add-hook 'erc-pre-send-functions #'erc-add-to-input-ring nil t) + ;; + (cl-letf (((symbol-function 'erc-process-input-line) + (lambda (&rest _) + (insert-before-markers + (erc-display-message-highlight 'notice "echo: one\n")))) + ((symbol-function 'erc-command-no-process-p) + (lambda (&rest _) t))) + (ert-info ("Create ring, populate, recall") + (insert "/one") + (erc-send-current-line) + (should (ring-p erc-input-ring)) + (should (zerop (ring-member erc-input-ring "/one"))) ; equal + (should (save-excursion (forward-line -1) (goto-char (point-at-bol)) + (looking-at-p "[*]+ echo: one"))) + (should-not erc-input-ring-index) + (erc-bol) + (should (looking-at "$")) + (erc-previous-command) + (erc-bol) + (should (looking-at "/one")) + (should (zerop erc-input-ring-index))) + (ert-info ("Back to one") + (should (= (ring-length erc-input-ring) (1+ erc-input-ring-index))) + (erc-previous-command) + (should-not erc-input-ring-index) + (erc-bol) + (should (looking-at "$")) + (should (equal (ring-ref erc-input-ring 0) "/one"))) + (ert-info ("Swap input after prompt with previous (#bug46339)") + (insert "abc") + (erc-previous-command) + (should (= 1 erc-input-ring-index)) + (erc-bol) + (should (looking-at "/one")) + (should (equal (ring-ref erc-input-ring 0) "abc")) + (should (equal (ring-ref erc-input-ring 1) "/one")) + (erc-next-command) + (erc-bol) + (should (looking-at "abc"))))) + (when noninteractive + (kill-buffer "*#fake*"))) commit 2a9ce136eda80297ce53eed4333d1c98bffaa21a Author: Lars Ingebrigtsen Date: Sat Feb 27 05:23:45 2021 +0100 Add generated .texi files to .gitignore diff --git a/.gitignore b/.gitignore index dd4eab759c..ba8a65547f 100644 --- a/.gitignore +++ b/.gitignore @@ -253,6 +253,8 @@ doc/*/*/*.ps doc/emacs/emacsver.texi doc/man/emacs.1 doc/misc/cc-mode.ss +doc/misc/modus-themes.texi +doc/misc/org.texi etc/DOC etc/refcards/emacsver.tex gnustmp* commit b3d310fa9694807fc0e9c54f7ec4f6e3407402e1 Author: Glenn Morris Date: Fri Feb 26 19:32:38 2021 -0800 Fixes for doc/misc org source files * doc/misc/org-setup.org: Fix "version" file lookup. Add copyright. * doc/misc/modus-themes.org: Fix up doclicense include. * doc/misc/org.org: Remove non-working and unused "modification-time". Fix up doclicense include. Adjust setupfile inclusion. diff --git a/doc/misc/modus-themes.org b/doc/misc/modus-themes.org index db15db46b5..03cce5bf33 100644 --- a/doc/misc/modus-themes.org +++ b/doc/misc/modus-themes.org @@ -17,7 +17,7 @@ released on {{{release-date}}}. Any reference to a newer feature which does not yet form part of the latest tagged commit, is explicitly marked as such. -Copyright (C) 2020 Free Software Foundation, Inc. +Copyright (C) 2020--2021 Free Software Foundation, Inc. #+begin_quote Permission is granted to copy, distribute and/or modify this @@ -1952,4 +1952,4 @@ to produce such a port, feel welcome [[https://protesilaos.com/contact][to conta :CUSTOM_ID: h:3077c3d2-7f90-4228-8f0a-73124f4026f6 :END: -#+INCLUDE: fdl-1.3.txt src txt +#+texinfo: @include doclicense.texi diff --git a/doc/misc/org-setup.org b/doc/misc/org-setup.org index b83d16e7e5..d0392f10a2 100644 --- a/doc/misc/org-setup.org +++ b/doc/misc/org-setup.org @@ -1,4 +1,21 @@ -# SETUPFILE for manuals +# SETUPFILE for Org manual + +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file is part of GNU Emacs. +# +# GNU Emacs is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GNU Emacs is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Emacs. If not, see . # XXX: We cannot use TODO keyword as a node starts with "TODO". #+todo: REVIEW FIXME | DONE @@ -28,7 +45,7 @@ # returns major.minor version number. This is sufficient since bugfix # releases are not expected to add features and therefore imply manual # modifications. -#+macro: version (eval (with-current-buffer (find-file-noselect "../lisp/org.el") (org-with-point-at 1 (if (re-search-forward "Version: +\\([0-9.]+\\)" nil t) (mapconcat #'identity (cl-subseq (split-string (match-string-no-properties 1) "\\.") 0 2) ".") (error "Missing \"Version\" keyword in \"org.el\""))))) +#+macro: version (eval (with-current-buffer (find-file-noselect "../../lisp/org/org.el") (org-with-point-at 1 (if (re-search-forward "Version: +\\([0-9.]+\\)" nil t) (mapconcat #'identity (cl-subseq (split-string (match-string-no-properties 1) "\\.") 0 2) ".") (error "Missing \"Version\" keyword in \"org.el\""))))) # The "kbd" macro turns KBD into @kbd{KBD}. Additionally, it # encloses case-sensitive special keys (SPC, RET...) within @key{...}. diff --git a/doc/misc/org.org b/doc/misc/org.org index 5d4e3f26fa..f072b5e00e 100644 --- a/doc/misc/org.org +++ b/doc/misc/org.org @@ -1,7 +1,6 @@ #+title: The Org Manual #+subtitle: Release {{{version}}} #+author: The Org Mode Developers -#+date: {{{modification-time}}} #+language: en @@ -3244,7 +3243,7 @@ A link should be enclosed in double brackets and may contain descriptive text to be displayed instead of the URL (see [[*Link Format]]), for example: -: [[http://www.gnu.org/software/emacs/][GNU Emacs]] +: [[https://www.gnu.org/software/emacs/][GNU Emacs]] If the description is a file name or URL that points to an image, HTML export (see [[*HTML Export]]) inlines the image as a clickable button. If @@ -21233,7 +21232,7 @@ be complete if the ones above were not mentioned in this manual. :DESCRIPTION: The license for this documentation. :END: -#+include: fdl.org +#+texinfo: @include doclicense.texi * Main Index :PROPERTIES: @@ -21286,7 +21285,7 @@ modify this GNU manual." * Export Setup :noexport: -#+setupfile: doc-setup.org +#+setupfile: org-setup.org #+export_file_name: org.texi commit fddd63f8b854f6bfa91403f69ba694ccb54197bc Author: Glenn Morris Date: Fri Feb 26 19:28:43 2021 -0800 Distribute the real source for some doc/misc manuals (bug#45143) * doc/misc/modus-themes.texi, doc/misc/org.texi: Remove generated files from repository. * doc/misc/Makefile.in: Add rules for building .texi from .org. (ORG_SRC, abs_top_builddir, EMACS, emacs): New variables. (org_template): New template. (orgclean): New phony target. * Makefile.in (info): Depend on lisp. * lisp/org/ox-texinfo.el (org-texinfo-export-to-texinfo-batch): New function. * doc/misc/org.org, doc/misc/org-setup.org: New files. Import from https://code.orgmode.org d8e8a97a14. diff --git a/Makefile.in b/Makefile.in index 2068362299..e11b07280c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -982,6 +982,8 @@ INFOS = lispref-info lispintro-info emacs-info misc-info PDFS = lispref-pdf lispintro-pdf emacs-pdf misc-pdf PSS = lispref-ps lispintro-ps emacs-ps misc-ps +## FIXME all of the misc- targets should really depend on lisp, +## like the info target. DOCS = $(DVIS) $(HTMLS) $(INFOS) $(PDFS) $(PSS) $(DOCS): $(MAKE) -C doc/$(subst -, ,$@) @@ -1084,7 +1086,14 @@ uninstall-ps: $(UNINSTALL_PS) # would require changing every rule in doc/ that builds an info file, # and it's not worth it. This case is only relevant if you download a # release, then change the .texi files. -info: + +# The dependency is due to those doc/misc/ manuals that use .org sources. +# I would have preferred to just add this to the misc-info target, +# but that gave parallel build errors. +# Depending on src is sufficient, but ends up being slow, since the +# uncompiled lisp/org/*.el files are used to build the .texi files +# (which is slow even with the elc files). +info: lisp ifneq ($(HAVE_MAKEINFO),no) $(MAKE) info-real info-dir endif diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in index d627055ae1..7c11f8c048 100644 --- a/doc/misc/Makefile.in +++ b/doc/misc/Makefile.in @@ -82,6 +82,11 @@ INFO_INSTALL = $(INFO_COMMON) $(DOCMISC_W32) ## because the info files are pre-built in release tarfiles. INFO_TARGETS = $(INFO_COMMON) efaq-w32 +## Some manuals have their source in .org format. +## This is discouraged because the .texi files it generates +## are not as well formatted as handwritten ones. +ORG_SRC = org modus-themes + # There are some naming differences between the info targets and the other # targets, so let's resolve them here. TARGETS_1 = $(INFO_INSTALL:ccmode=cc-mode) @@ -221,6 +226,26 @@ gnus.pdf: $(gnus_deps) ${buildinfodir}/tramp.info tramp.html: ${srcdir}/trampver.texi +abs_top_builddir = @abs_top_builddir@ +EMACS = ${abs_top_builddir}/src/emacs +emacs = "${EMACS}" -batch --no-site-file --no-site-lisp + +# Generated .texi files go in srcdir so they can be included in the +# release tarfile along with the others. +# Work in srcdir (and use abs_top_builddir) so that +setupfile and +# things like org-setup's "version" macro work. Sigh. +define org_template + $${srcdir}/$(1).texi: $${srcdir}/$(1).org + @rm -f $$@ + $${AM_V_GEN}cd "$${srcdir}" && $${emacs} -l ox-texinfo \ + -f org-texinfo-export-to-texinfo-batch $$< $$@ +endef + +$(foreach orgfile,${ORG_SRC},$(eval $(call org_template,$(orgfile)))) + +${srcdir}/org.texi: ${srcdir}/org-setup.org + + .PHONY: mostlyclean clean distclean bootstrap-clean maintainer-clean mostlyclean: @@ -245,7 +270,12 @@ infoclean: $(buildinfodir)/$${file}-[1-9][0-9]; \ done -bootstrap-clean maintainer-clean: distclean infoclean +.PHONY: orgclean + +orgclean: + rm -f $(addprefix ${srcdir}/,${ORG_SRC:=.texi}) + +bootstrap-clean maintainer-clean: distclean infoclean orgclean .PHONY: install-dvi install-html install-pdf install-ps install-doc diff --git a/doc/misc/modus-themes.texi b/doc/misc/modus-themes.texi deleted file mode 100644 index b16aece2ee..0000000000 --- a/doc/misc/modus-themes.texi +++ /dev/null @@ -1,2834 +0,0 @@ -\input texinfo @c -*- texinfo -*- -@c %**start of header -@setfilename ../../info/modus-themes.info -@settitle Modus themes for GNU Emacs -@include docstyle.texi -@documentencoding UTF-8 -@documentlanguage en -@c %**end of header - -@include emacsver.texi - -@dircategory Emacs misc features -@direntry -* Modus Themes: (modus-themes). Highly accessible themes (WCAG AAA). -@end direntry - -@finalout -@titlepage -@title Modus themes for GNU Emacs -@author Protesilaos Stavrou (@email{info@@protesilaos.com}) -@end titlepage - -@ifnottex -@node Top -@top Modus themes for GNU Emacs - -This manual, written by Protesilaos Stavrou, describes the customization -options for the @samp{modus-operandi} and @samp{modus-vivendi} themes, and provides -every other piece of information pertinent to them. - -The documentation furnished herein corresponds to version 0.13.0, -released on 2020-10-08. Any reference to a newer feature which does -not yet form part of the latest tagged commit, is explicitly marked as -such. - -Copyright (C) 2020--2021 Free Software Foundation, Inc. - -@quotation -Permission is granted to copy, distribute and/or modify this -document under the terms of the GNU Free Documentation License, -Version 1.3 or any later version published by the Free Software -Foundation; with no Invariant Sections, with no Front-Cover Texts, -and with no Back-Cover Texts. - -@end quotation - -@end ifnottex - -@menu -* Overview:: -* Installation:: -* Enable and load:: -* Customization Options:: -* Advanced customization (do-it-yourself):: -* Face coverage:: -* Notes for individual packages:: -* Contributing:: -* Acknowledgements:: -* Meta:: -* External projects (ports):: -* GNU Free Documentation License:: - -@detailmenu ---- The Detailed Node Listing --- - -Overview - -* How do the themes look like:: -* Learn about the latest changes:: - -Installation - -* Install from the archives:: -* Install on GNU/Linux:: - -Install on GNU/Linux - -* Debian 11 Bullseye:: -* GNU Guix:: - -Enable and load - -* Load automatically:: -* Load at a given time or at sunset/sunrise:: -* Toggle between the themes on demand:: -* Configure options prior to loading:: - -Customization Options - -* Bold constructs:: Toggle bold constructs in code -* Slanted constructs:: Toggle slanted constructs (italics) in code -* Syntax highlighting:: Toggle subtle coloration in programming modes -* No mixed fonts:: Toggle mixing of font families -* Link underline:: Toggle underlined text in links -* Command prompts:: Choose among plain, subtle, or intense prompts -* Mode line:: Choose among plain, three-dimension, or moody-compliant styles -* Completion UIs:: Choose among standard, moderate, or opinionated looks -* Fringes:: Choose among plain, subtle, or intense fringe visibility -* Line highlighting:: Toggle intense style for current line highlighting -* Matching parentheses:: Toggle intense style for matching delimiters/parentheses -* Diffs:: Choose among intense, desaturated, or text-only diffs -* Org mode blocks:: Choose among plain, greyscale, or rainbow styles -* Heading styles:: Choose among several styles, also per heading level -* Scaled headings:: Toggle scaling of headings -* Headings' font:: Toggle proportionately spaced fonts in headings - -Scaled headings - -* Scaled heading sizes:: Specify rate of increase for scaled headings - -Advanced customization (do-it-yourself) - -* Tweak colors (DIY):: Declare your own palette overrides -* Font configs (DIY):: Optimise for mixed typeface buffers -* Org user faces (DIY):: Extend styles for org-mode keywords and priorities - -Face coverage - -* Supported packages:: Full list of covered face groups -* Covered indirectly:: -* Will NOT be supported:: - -Notes for individual packages - -* Note on company-mode overlay pop-up:: -* Note for ERC escaped color sequences:: -* Note for powerline or spaceline:: -* Note on shr colors:: -* Note for Helm grep:: -* Note on vc-annotate-background-mode:: - -Contributing - -* Sources of the themes:: -* Issues you can help with:: -* Merge requests:: Legal considerations for code patches - -@end detailmenu -@end menu - -@node Overview -@chapter Overview - -The Modus themes are designed for accessible readability. They conform -with the highest standard for color contrast between any given -combination of background and foreground values. This corresponds to -the WCAG AAA standard, which specifies a minimum rate of distance in -relative luminance of 7:1. - -Modus Operandi (@samp{modus-operandi}) is a light theme, while Modus Vivendi -(@samp{modus-vivendi}) is dark. Each theme's color palette is designed to -meet the needs of the numerous interfaces that are possible in the Emacs -computing environment. - -The overarching objective of this project is to always offer accessible -color combinations. There shall never be a compromise on this -principle. If there arises an inescapable trade-off between readability -and stylistic considerations, we will always opt for the former. - -To ensure that users have a consistently accessible experience, the -themes strive to achieve as close to full face coverage as possible -(see @ref{Face coverage}). - -Starting with version 0.12.0 and onwards, the themes are built into GNU -Emacs (current version is 0.13.0). - -@menu -* How do the themes look like:: -* Learn about the latest changes:: -@end menu - -@node How do the themes look like -@section How do the themes look like - -Check the web page with @uref{https://protesilaos.com/modus-themes-pictures/, the screen shots}. There are lots of scenarios on -display that draw attention to details and important aspects in the -design of the themes. They also showcase the numerous customization -options. - -@xref{Customization Options}. - -@node Learn about the latest changes -@section Learn about the latest changes - -Please refer to the @uref{https://protesilaos.com/modus-themes-changelog, web page with the change log}. It is comprehensive -and covers everything that goes into every tagged release of the themes. - -@node Installation -@chapter Installation - -The Modus themes are distributed with Emacs starting with version 28.1. -On older versions of Emacs, they can be installed using Emacs' package -manager or manually from their code repository. - -Modus Operandi (light theme) and Modus Vivendi (dark) are normally -distributed as standalone packages in Emacs-specific archives. There -also exist packages for GNU/Linux distributions. - -@menu -* Install from the archives:: -* Install on GNU/Linux:: -@end menu - -@node Install from the archives -@section Install from the archives - -@samp{modus-operandi-theme} and @samp{modus-vivendi-theme} are -available from the GNU ELPA archive, which is configured by default. - -Prior to querying any package archive, make sure to have updated the -index, with @samp{M-x package-refresh-contents}. Then all you need to do is -type @samp{M-x package-install} and specify the theme of your choice. - -@node Install on GNU/Linux -@section Install on GNU/Linux - -The themes are also available from the archives of some GNU/Linux -distributions. These should correspond to a tagged release rather than -building directly from the latest Git commit. It all depends on the -distro's packaging policies. - -@menu -* Debian 11 Bullseye:: -* GNU Guix:: -@end menu - -@node Debian 11 Bullseye -@subsection Debian 11 Bullseye - -The two themes are distributed as a single package for Debian and its -derivatives. Currently in the unstable and testing suites and should be -available in time for Debian 11 Bullseye (next stable). - -Get them with: - -@example -sudo apt install elpa-modus-themes -@end example - -@node GNU Guix -@subsection GNU Guix - -Users of either the Guix System (the distro) or just Guix (the package -manager) can get each theme as a standalone package. - -@example -guix package -i emacs-modus-operandi-theme -@end example - -And/or: - -@example -guix package -i emacs-modus-vivendi-theme -@end example - -@node Enable and load -@chapter Enable and load - -This section documents how to load the theme of your choice and how to -further control its initialization. It also includes some sample code -snippets that could help you in the task, especially if you intend to -use both Modus Operandi and Modus Vivendi. - -@menu -* Load automatically:: -* Load at a given time or at sunset/sunrise:: -* Toggle between the themes on demand:: -* Configure options prior to loading:: -@end menu - -@node Load automatically -@section Load automatically - -A simple way to load the theme from your Emacs initialization file is to -include either of the following expressions: - -@lisp -(load-theme 'modus-operandi t) ; Light theme -(load-theme 'modus-vivendi t) ; Dark theme -@end lisp - -Make sure to remove any other theme that is being loaded, otherwise you -might run into unexpected issues. - -Note that you can always @samp{M-x disable-theme} and specify an item. The -command does exactly what its name suggests. To deactivate all enabled -themes at once, in case you have multiple of them enabled, you may -evaluate the expression: - -@lisp -(mapc #'disable-theme custom-enabled-themes) -@end lisp - -@node Load at a given time or at sunset/sunrise -@section Load at a given time or at sunset/sunrise - -It is possible to schedule a time during the day at or after which a -given theme will be loaded.@footnote{Contributed on Reddit by user @samp{b3n} -@uref{https://www.reddit.com/r/emacs/comments/gdtqov/weekly_tipstricketc_thread/fq9186h/}.} - -@lisp -;; Light for the day -(load-theme 'modus-operandi t t) -(run-at-time "05:00" (* 60 60 24) - (lambda () - (enable-theme 'modus-operandi))) - -;; Dark for the night -(load-theme 'modus-vivendi t t) -(run-at-time "21:00" (* 60 60 24) - (lambda () - (enable-theme 'modus-vivendi))) -@end lisp - -A modified version of the above technique is to use the sunrise and -sunset as references, instead of specifying a fixed hour value.@footnote{Contributed directly by André Alexandre Gomes @uref{https://gitlab.com/aadcg}.} -If you set @samp{calendar-latitude} and @samp{calendar-longitude} (defined in the -built-in @samp{solar.el} library---read it with @samp{M-x find-library}), you can -automatically switch between both themes at the appropriate time-of-day. -Note that @emph{those calendar variables need to be set before loading the -themes}. - -@lisp -;; Define coordinates -(setq calendar-latitude 35.17 - calendar-longitude 33.36) - -;; Light at sunrise -(load-theme 'modus-operandi t t) -(run-at-time (nth 1 (split-string (sunrise-sunset))) - (* 60 60 24) - (lambda () - (enable-theme 'modus-operandi))) - -;; Dark at sunset -(load-theme 'modus-vivendi t t) -(run-at-time (nth 4 (split-string (sunrise-sunset))) - (* 60 60 24) - (lambda () - (enable-theme 'modus-vivendi))) -@end lisp - -For the sake of completeness, the @samp{load-theme} call in these snippets is -slightly different than the one shown in @ref{Load automatically}, because it -does not enable the theme directly: the subsequent @samp{enable-theme} does -that when needed. - -@node Toggle between the themes on demand -@section Toggle between the themes on demand - -With both themes available, it is possible to design a simple command to -switch between them on demand. - -@lisp -(defun modus-themes-toggle () - "Toggle between `modus-operandi' and `modus-vivendi' themes." - (interactive) - (if (eq (car custom-enabled-themes) 'modus-operandi) - (progn - (disable-theme 'modus-operandi) - (load-theme 'modus-vivendi t)) - (disable-theme 'modus-vivendi) - (load-theme 'modus-operandi t))) -@end lisp - -You could use @samp{(mapc #'disable-theme custom-enabled-themes)} instead of -disabling a single target, but you get the idea. - -@node Configure options prior to loading -@section Configure options prior to loading - -If you plan to use both themes and wish to apply styles consistently -(see @ref{Customization Options}), you could define wrapper functions around -the standard @samp{load-theme} command. These extend the simple function we -presented in @ref{Toggle between the themes on demand}. - -Here is a comprehensive setup (the values assigned to the variables are -just for the sake of this demonstration):@footnote{The @samp{defmacro} and @samp{dolist} -method were contributed on Reddit by user @samp{b3n}, -@uref{https://www.reddit.com/r/emacs/comments/gqsz8u/weekly_tipstricketc_thread/fsfakhg/}.} - -@lisp -(defmacro modus-themes-format-sexp (sexp &rest objects) - `(eval (read (format ,(format "%S" sexp) ,@@objects)))) - -(dolist (theme '("operandi" "vivendi")) - (modus-themes-format-sexp - (defun modus-%1$s-theme-load () - (setq modus-%1$s-theme-slanted-constructs t - modus-%1$s-theme-bold-constructs t - modus-%1$s-theme-fringes 'subtle ; @{nil,'subtle,'intense@} - modus-%1$s-theme-mode-line '3d ; @{nil,'3d,'moody@} - modus-%1$s-theme-faint-syntax nil - modus-%1$s-theme-intense-hl-line nil - modus-%1$s-theme-intense-paren-match nil - modus-%1$s-theme-no-link-underline t - modus-%1$s-theme-no-mixed-fonts nil - modus-%1$s-theme-prompts nil ; @{nil,'subtle,'intense@} - modus-%1$s-theme-completions 'moderate ; @{nil,'moderate,'opinionated@} - modus-%1$s-theme-diffs nil ; @{nil,'desaturated,'fg-only@} - modus-%1$s-theme-org-blocks 'greyscale ; @{nil,'greyscale,'rainbow@} - modus-%1$s-theme-headings ; Read further below in the manual for this one - '((1 . section) - (2 . line) - (t . rainbow-line-no-bold)) - modus-%1$s-theme-variable-pitch-headings nil - modus-%1$s-theme-scale-headings t - modus-%1$s-theme-scale-1 1.1 - modus-%1$s-theme-scale-2 1.15 - modus-%1$s-theme-scale-3 1.21 - modus-%1$s-theme-scale-4 1.27 - modus-%1$s-theme-scale-5 1.33) - (load-theme 'modus-%1$s t)) - theme)) - -(defun modus-themes-toggle () - "Toggle between `modus-operandi' and `modus-vivendi' themes." - (interactive) - (if (eq (car custom-enabled-themes) 'modus-operandi) - (progn - (disable-theme 'modus-operandi) - (modus-vivendi-theme-load)) - (disable-theme 'modus-vivendi) - (modus-operandi-theme-load))) -@end lisp - -@node Customization Options -@chapter Customization Options - -The Modus themes are highly configurable, though they should work well -without any further tweaks. - -By default, all customization options are set to @samp{nil}. - -All customization options need to be evaluated before loading their -theme (@pxref{Enable and load}). - -@menu -* Bold constructs:: Toggle bold constructs in code -* Slanted constructs:: Toggle slanted constructs (italics) in code -* Syntax highlighting:: Toggle subtle coloration in programming modes -* No mixed fonts:: Toggle mixing of font families -* Link underline:: Toggle underlined text in links -* Command prompts:: Choose among plain, subtle, or intense prompts -* Mode line:: Choose among plain, three-dimension, or moody-compliant styles -* Completion UIs:: Choose among standard, moderate, or opinionated looks -* Fringes:: Choose among plain, subtle, or intense fringe visibility -* Line highlighting:: Toggle intense style for current line highlighting -* Matching parentheses:: Toggle intense style for matching delimiters/parentheses -* Diffs:: Choose among intense, desaturated, or text-only diffs -* Org mode blocks:: Choose among plain, greyscale, or rainbow styles -* Heading styles:: Choose among several styles, also per heading level -* Scaled headings:: Toggle scaling of headings -* Headings' font:: Toggle proportionately spaced fonts in headings -@end menu - -@node Bold constructs -@section Option for more bold constructs - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-bold-constructs} -@item -@samp{modus-vivendi-theme-bold-constructs} -@end itemize - -Possible values: - -@enumerate -@item -@samp{nil} (default) -@item -@samp{t} -@end enumerate - -Display several constructs in bold weight. This concerns keywords and -other important aspects of code syntax. It also affects certain mode -line indicators and command-line prompts. - -The default is to only use a bold weight when it is required. - -Additionally, and while not necessary, to define the precise weight for -bold constructs, you can change the typographic intensity of the @samp{bold} -face. The standard is a bold weight. It requires no further -intervention. Assuming though that your typeface of choice supports a -``semibold'' weight, adding the following snippet to your init file should -suffice. - -@lisp -(set-face-attribute 'bold nil :weight 'semibold) -@end lisp - -Note that if you are switching themes, you need to re-evaluate this -expression after the new theme is loaded. - -@node Slanted constructs -@section Option for more slanted constructs - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-slanted-constructs} -@item -@samp{modus-vivendi-theme-slanted-constructs} -@end itemize - -Possible values: - -@enumerate -@item -@samp{nil} (default) -@item -@samp{t} -@end enumerate - -Choose to render more faces in slanted text (italics). This typically -affects documentation strings and code comments. - -The default is to not use italics unless it is absolutely necessary. - -@node Syntax highlighting -@section Option for faint code syntax highlighting - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-faint-syntax} -@item -@samp{modus-vivendi-theme-faint-syntax} -@end itemize - -Possible values: - -@enumerate -@item -@samp{nil} (default) -@item -@samp{t} -@end enumerate - -Use less saturated colors in programming modes for highlighting code -syntax. The default is to use saturated colors. - -This option essentially affects the font-lock faces, so it may also have -implications in other places that are hard-wired to rely directly on -them instead of specifying their own faces (which could inherit from -font-lock if that is the intent). The author is aware of @samp{vc-dir} as a -case in point. - -@node No mixed fonts -@section Option for no font mixing - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-no-mixed-fonts} -@item -@samp{modus-vivendi-theme-no-mixed-fonts} -@end itemize - -Possible values: - -@enumerate -@item -@samp{nil} (default) -@item -@samp{t} -@end enumerate - -By default, the themes configure some spacing-sensitive faces, such as -Org tables and code blocks, to always inherit from the @samp{fixed-pitch} face. -This is to ensure that those constructs remain monospaced when users opt -for something like the built-in @kbd{M-x variable-pitch-mode}. Otherwise the -layout would appear broken. To disable this behaviour, set the option -to @samp{t}. - -Users may prefer to use another package for handling mixed typeface -configurations, rather than letting the theme do it, perhaps because a -purpose-specific package has extra functionality. Two possible options -are @samp{org-variable-pitch} and @samp{mixed-pitch}. - -@node Link underline -@section Option for no link underline - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-no-link-underline} -@item -@samp{modus-vivendi-theme-no-link-underline} -@end itemize - -Possible values: - -@enumerate -@item -@samp{nil} (default) -@item -@samp{t} -@end enumerate - -Remove the underline effect from links, symbolic links, and buttons. -The default is to apply an underline. - -@node Command prompts -@section Option for command prompt styles - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-prompts} -@item -@samp{modus-vivendi-theme-prompts} -@end itemize - -Possible values: - -@enumerate -@item -@samp{nil} (default) -@item -@samp{subtle} -@item -@samp{intense} -@end enumerate - -The symbols ``subtle'' and ``intense'' will apply a combination of accented -background and foreground to the minibuffer and other REPL prompts (like -@samp{M-x shell} and @samp{M-x eshell}). The difference between the two is that the -latter has a more pronounced/noticeable effect than the former. - -The default does not use any background for such prompts, while relying -exclusively on an accented foreground color. - -@node Mode line -@section Option for mode line presentation - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-mode-line} -@item -@samp{modus-vivendi-theme-mode-line} -@end itemize - -Possible values: - -@enumerate -@item -@samp{nil} (default) -@item -@samp{3d} -@item -@samp{moody} -@end enumerate - -The default value (@samp{nil}) produces a two-dimensional effect both for the -active and inactive modelines. The differences between the two are -limited to distinct shades of greyscale values, with the active being -more intense than the inactive. - -A @samp{3d} symbol will make the active modeline look like a three-dimensional -rectangle. Inactive modelines remain 2D, though they are slightly toned -down relative to the default. This aesthetic is the same as what you -get when you run Emacs without any customizations (@kbd{emacs -Q} on the -command line). - -While @samp{moody} removes all box effects from the modelines and applies -underline and overline properties instead. It also tones down a bit the -inactive modelines. This is meant to optimize things for use with the -@uref{https://github.com/tarsius/moody, moody package} (hereinafter referred to as ``Moody''), though it can work -fine even without it. - -Note that Moody does not expose any faces that the themes could style -directly. Instead it re-purposes existing ones to render its tabs and -ribbons. As such, there may be cases where the contrast ratio falls -below the 7:1 target that the themes conform with (WCAG AAA). To hedge -against this, we configure a fallback foreground for the @samp{moody} option, -which will come into effect when the background of the modeline changes -to something less accessible, such as Moody ribbons (read the doc string -of @samp{set-face-attribute}, specifically @samp{:distant-foreground}). This fallback -comes into effect when Emacs determines that the background and -foreground of the given construct are too close to each other in terms -of color distance. In effect, users would need to experiment with the -variable @samp{face-near-same-color-threshold} to trigger the fallback color. -We find that a value of @samp{45000} would suffice, contrary to the default -@samp{30000}. Do not set the value too high, because that would have the -adverse effect of always overriding the default color (which has been -carefully designed to be highly accessible). - -Furthermore, because Moody expects an underline and overline instead of -a box style, it is recommended you also include this in your setup: - -@lisp -(setq x-underline-at-descent-line t) -@end lisp - -@node Completion UIs -@section Option for completion framework aesthetics - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-completions} -@item -@samp{modus-vivendi-theme-completions} -@end itemize - -Possible values: - -@enumerate -@item -@samp{nil} (default) -@item -@samp{moderate} -@item -@samp{opinionated} -@end enumerate - -This is a special option that has different effects depending on the -completion UI@. The interfaces can be grouped in two categories, based -on their default aesthetics: (i) those that only or mostly use -foreground colors for their interaction model, and (ii) those that -combine background and foreground values for some of their metaphors. -The former category encompasses Icomplete, Ido, Selectrum as well as -pattern matching styles like Orderless and Flx. The latter covers Helm, -Ivy, and similar. - -A value of @samp{nil} will respect the metaphors of each completion framework. - -The symbol @samp{moderate} will apply a combination of background and -foreground that is fairly subtle. For Icomplete and friends this -constitutes a departure from their default aesthetics, however the -difference is small. While Helm et al will appear slightly different -than their original looks, as they are toned down a bit. - -The symbol @samp{opinionated} will apply color combinations that refashion the -completion UI@. For the Icomplete camp this means that intense -background and foreground combinations are used: in effect their looks -emulate those of Ivy and co. in their original style. Whereas the other -group of packages will revert to an even more nuanced aesthetic with -some additional changes to the choice of hues. - -To appreciate the scope of this customization option, you should spend -some time with every one of the @samp{nil} (default), @samp{moderate}, and @samp{opinionated} -possibilities. - -@node Fringes -@section Option for fringe visibility - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-fringes} -@item -@samp{modus-vivendi-theme-fringes} -@end itemize - -Possible values: - -@enumerate -@item -@samp{nil} (default) -@item -@samp{subtle} -@item -@samp{intense} -@end enumerate - -The ``subtle'' symbol will apply a greyscale background that is visible, -yet close enough to the main background color. While the ``intense'' -symbol will use a more noticeable greyscale background. - -The default is to use the same color as that of the main background, -meaning that the fringes are not obvious though they still occupy the -space given to them by @samp{fringe-mode}. - -@node Line highlighting -@section Option for line highlighting (hl-line-mode) - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-intense-hl-line} -@item -@samp{modus-vivendi-theme-intense-hl-line} -@end itemize - -Possible values: - -@enumerate -@item -@samp{nil} (default) -@item -@samp{t} -@end enumerate - -Draw the current line of @samp{hl-line-mode} or its global equivalent in a more -prominent background color. This would also affect several packages -that enable @samp{hl-line-mode}, such as @samp{elfeed} and @samp{mu4e}. - -The default is to use a more subtle gray. - -@node Matching parentheses -@section Option for parenthesis matching (show-paren-mode) - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-intense-paren-match} -@item -@samp{modus-vivendi-theme-intense-paren-match} -@end itemize - -Possible values: - -@enumerate -@item -@samp{nil} (default) -@item -@samp{t} -@end enumerate - -Apply a more intense background to the matching parentheses (or -delimiters). This affects tools such as the built-in @samp{show-paren-mode}. -The default is to use a subtle warm color for the background of those -overlays. - -@node Diffs -@section Option for diff buffer looks - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-diffs} -@item -@samp{modus-vivendi-theme-diffs} -@end itemize - -Possible values: - -@enumerate -@item -@samp{nil} (default) -@item -@samp{desaturated} -@item -@samp{fg-only} -@end enumerate - -By default the themes will apply richly colored backgrounds to the -output of diffs, such as those of @samp{diff-mode}, @samp{ediff}, @samp{smerge-mode}, and -@samp{magit}. These are color combinations of an accented background and -foreground so that, for example, added lines have a pronounced green -background with an appropriate shade of green for the affected text. -Word-wise or ``refined'' changes follow this pattern but use different -shades of those colors to remain distinct. - -A @samp{desaturated} value tones down all relevant color values. It still -combines an accented background with an appropriate foreground, yet its -overall impression is very subtle. Refined changes are a bit more -intense to fulfil their intended function, though still less saturated -than default. - -While @samp{fg-only} will remove all accented backgrounds and instead rely on -color-coded text to denote changes. For instance, added lines use an -intense green foreground, while their background is the same as the rest -of the buffer. Word-wise highlights still use a background value which -is, nonetheless, more subtle than its default equivalent. - -Concerning @samp{magit}, an extra set of tweaks are introduced for the effect -of highlighting the current diff hunk, so as to remain consistent with -the overall experience of that mode. Expect changes that are consistent -with the overall intent of the aforementioned. - -@node Org mode blocks -@section Option for org-mode block styles - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-org-blocks} -@item -@samp{modus-vivendi-theme-org-blocks} -@end itemize - -Possible values: - -@enumerate -@item -@samp{nil} (default) -@item -@samp{greyscale} -@item -@samp{rainbow} -@end enumerate - -The default is to use the same background as the rest of the buffer for -the contents of the block. - -A value of @samp{greyscale} will apply a subtle neutral gray background to the -block's contents. It will also extend to the edge of the window the -background of the ``begin'' and ``end'' block delimiter lines (only relevant -for Emacs versions >= 27 where the 'extend' keyword is recognised by -@samp{set-face-attribute}). - -While @samp{rainbow} will instead use an accented background for the contents -of the block. The exact color will depend on the programming language -and is controlled by the @samp{org-src-block-faces} variable (refer to the -theme's source code for the current association list). This is most -suitable for users who work on literate programming documents that mix -and match several languages. - -Note that the ``rainbow'' blocks may require you to also reload the -major-mode so that the colors are applied properly: use @kbd{M-x org-mode} or -@kbd{M-x org-mode-restart} to refresh the buffer. Or start typing in each -code block (inefficient at scale, but it still works). - -@node Heading styles -@section Option for headings' overall style - -This is defined as an alist and, therefore, uses a different approach -than other customization options documented in this manual. - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-headings} -@item -@samp{modus-vivendi-theme-headings} -@end itemize - -Possible values, which can be specified for each heading level (examples -further below): - -@itemize -@item -nil (default fallback option---covers all heading levels) -@item -@samp{t} (default style for a single heading, when the fallback differs) -@item -@samp{no-bold} -@item -@samp{line} -@item -@samp{line-no-bold} -@item -@samp{rainbow} -@item -@samp{rainbow-line} -@item -@samp{rainbow-line-no-bold} -@item -@samp{highlight} -@item -@samp{highlight-no-bold} -@item -@samp{rainbow-highlight} -@item -@samp{rainbow-highlight-no-bold} -@item -@samp{section} -@item -@samp{section-no-bold} -@item -@samp{rainbow-section} -@item -@samp{rainbow-section-no-bold} -@end itemize - -To control faces per level from 1-8, use something like this (same for -@samp{modus-vivendi-theme-headings}): - -@lisp -(setq modus-operandi-theme-headings - '((1 . section) - (2 . line) - (3 . highlight) - (t . rainbow-no-bold))) -@end lisp - -The above uses the @samp{section} value for heading levels 1, the @samp{line} for -headings 2, @samp{highlight} for 3. All other levels fall back to -@samp{rainbow-line-no-bold}. - -To set a uniform value for all heading levels, use this pattern: - -@lisp -;; A given style for every heading -(setq modus-operandi-theme-headings - '((t . rainbow-line-no-bold))) - -;; Default aesthetic for every heading -(setq modus-operandi-theme-headings - '((t . nil))) -@end lisp - -The default style for headings uses a fairly desaturated foreground -value in combination with a bold typographic weight. To specify this -style for a given level N (assuming you wish to have another fallback -option), just specify the value @samp{t} like this: - -@lisp -(setq modus-operandi-theme-headings - '((1 . t) - (2 . line) - (t . rainbow-line-no-bold))) -@end lisp - -A description of all other possible styles: - -@itemize -@item -@samp{no-bold} retains the default text color while removing the typographic -weight. - -@item -@samp{line} is the same as the default plus an overline over the heading. - -@item -@samp{line-no-bold} is the same as @samp{line} without bold weight. - -@item -@samp{rainbow} uses a more colorful foreground in combination with bold -weight. - -@item -@samp{rainbow-line} is the same as @samp{rainbow} plus an overline. - -@item -@samp{rainbow-line-no-bold} is the same as @samp{rainbow-line} without the bold -weight. - -@item -@samp{highlight} retains the default style of a fairly desaturated foreground -combined with a bold weight and adds to it a subtle accented -background. - -@item -@samp{highlight-no-bold} is the same as @samp{highlight} without a bold weight. - -@item -@samp{rainbow-highlight} is the same as @samp{highlight} but with a more colorful -foreground. - -@item -@samp{rainbow-highlight-no-bold} is the same as @samp{rainbow-highlight} without a -bold weight. - -@item -@samp{section} retains the default looks and adds to them both an overline -and a slightly accented background. It is, in effect, a combination -of the @samp{line} and @samp{highlight} values. - -@item -@samp{section-no-bold} is the same as @samp{section} without a bold weight. - -@item -@samp{rainbow-section} is the same as @samp{section} but with a more colorful -foreground. - -@item -@samp{rainbow-section-no-bold} is the same as @samp{rainbow-section} without a bold -weight.`` -@end itemize - -@node Scaled headings -@section Option for scaled headings - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-scale-headings} -@item -@samp{modus-vivendi-theme-scale-headings} -@end itemize - -Possible values: - -@enumerate -@item -@samp{nil} (default) -@item -@samp{t} -@end enumerate - -Make headings larger in height relative to the main text. This is -noticeable in modes like Org. The default is to use the same size for -headings and body copy. - -@menu -* Scaled heading sizes:: Specify rate of increase for scaled headings -@end menu - -@node Scaled heading sizes -@subsection Control the scale of headings - -In addition to toggles for enabling scaled headings, users can also -specify a number of their own. - -@itemize -@item -If it is a floating point, say, @samp{1.5}, it is interpreted as a multiple -of the base font size. This is the recommended method. - -@item -If it is an integer, it is read as an absolute font height. The -number is basically the point size multiplied by ten. So if you want -it to be @samp{18pt} you must pass @samp{180}. Please understand that setting an -absolute value is discouraged, as it will break the layout when you -try to change font sizes with the built-in @samp{text-scale-adjust} command -(see @ref{Font configs (DIY), , Font configurations}). -@end itemize - -Below are the variables in their default values, using the floating -point paradigm. The numbers are very conservative, but you are free to -change them to your liking, such as @samp{1.2}, @samp{1.4}, @samp{1.6}, @samp{1.8}, @samp{2.0}---or use a -resource for finding a consistent scale: - -@lisp -(setq modus-operandi-theme-scale-1 1.05 - modus-operandi-theme-scale-2 1.1 - modus-operandi-theme-scale-3 1.15 - modus-operandi-theme-scale-4 1.2 - modus-operandi-theme-scale-5 1.3) - -(setq modus-vivendi-theme-scale-1 1.05 - modus-vivendi-theme-scale-2 1.1 - modus-vivendi-theme-scale-3 1.15 - modus-vivendi-theme-scale-4 1.2 - modus-vivendi-theme-scale-5 1.3) -@end lisp - -Note that in earlier versions of Org, scaling would only increase the -size of the heading, but not of keywords that were added to it, like -``TODO''. The issue has been fixed upstream: -@uref{https://protesilaos.com/codelog/2020-09-24-org-headings-adapt/}. - -@node Headings' font -@section Option for variable-pitch font in headings - -Symbol names: - -@itemize -@item -@samp{modus-operandi-theme-variable-pitch-headings} -@item -@samp{modus-vivendi-theme-variable-pitch-headings} -@end itemize - -Possible values: - -@enumerate -@item -@samp{nil} (default) -@item -@samp{t} -@end enumerate - -Choose to apply a proportionately spaced, else ``variable-pitch'', -typeface to headings (such as in Org mode). The default is to use the -main font family. - -@ref{Font configs (DIY), , Font configurations for Org (and others)}. - -@node Advanced customization (do-it-yourself) -@chapter Advanced customization (do-it-yourself) - -Unlike the predefined customization options which follow a -straightforward pattern of allowing the user to quickly specify their -preference, the themes also provide a more flexible, albeit difficult, -mechanism to control things with precision (see @ref{Customization Options}). - -This section is of interest only to users who are prepared to maintain -their own local tweaks and who are willing to deal with any possible -incompatibilities between versioned releases of the themes. As such, -they are labelled as ``do-it-yourself'' or ``DIY''. - -@menu -* Tweak colors (DIY):: Declare your own palette overrides -* Font configs (DIY):: Optimise for mixed typeface buffers -* Org user faces (DIY):: Extend styles for org-mode keywords and priorities -@end menu - -@node Tweak colors (DIY) -@section Full access to the themes' palette - -The variables are: - -@itemize -@item -@samp{modus-operandi-theme-override-colors-alist} -@item -@samp{modus-vivendi-theme-override-colors-alist} -@end itemize - -Users can specify an association list that maps the names of color -variables to hexadecimal RGB values (in the form of @samp{#RRGGBB}). This -means that it is possible to override the entire palette or subsets -thereof (see the source code for the actual names and values). - -Example: - -@lisp -;; Redefine the values of those three variables for the given theme -(setq modus-vivendi-theme-override-colors-alist - '(("magenta" . "#ffaabb") - ("magenta-alt" . "#ee88ff") - ("magenta-alt-other" . "#bbaaff"))) -@end lisp - -If you want to be creative, you can define a minor mode that refashions -the themes on demand. The following is a minor mode that gets activated -on demand. We combine it with the function to switch between Modus -Operandi and Modus Vivendi (@pxref{Toggle between the themes on demand}, for -a basic command, and/or @pxref{Configure options prior to loading}, for a more -comprehensive setup). - -@lisp -(define-minor-mode modus-themes-alt-mode - "Override Modus themes' palette variables with custom values. - -This is intended as a proof-of-concept. It is, nonetheless, a -perfectly accessible alternative, conforming with the design -principles of the Modus themes. It still is not as good as the -default colors." - :init-value nil - :global t - (if modus-themes-alt-mode - (setq modus-operandi-theme-override-colors-alist - '(("bg-main" . "#fefcf4") - ("bg-dim" . "#faf6ef") - ("bg-alt" . "#f7efe5") - ("bg-hl-line" . "#f4f0e3") - ("bg-active" . "#e8dfd1") - ("bg-inactive" . "#f6ece5") - ("bg-region" . "#c6bab1") - ("bg-header" . "#ede3e0") - ("bg-tab-bar" . "#dcd3d3") - ("bg-tab-active" . "#fdf6eb") - ("bg-tab-inactive" . "#c8bab8") - ("fg-unfocused" . "#55556f")) - modus-vivendi-theme-override-colors-alist - '(("bg-main" . "#100b17") - ("bg-dim" . "#161129") - ("bg-alt" . "#181732") - ("bg-hl-line" . "#191628") - ("bg-active" . "#282e46") - ("bg-inactive" . "#1a1e39") - ("bg-region" . "#393a53") - ("bg-header" . "#202037") - ("bg-tab-bar" . "#262b41") - ("bg-tab-active" . "#120f18") - ("bg-tab-inactive" . "#3a3a5a") - ("fg-unfocused" . "#9a9aab"))) - (setq modus-operandi-theme-override-colors-alist nil - modus-vivendi-theme-override-colors-alist nil))) - -(defun modus-themes-toggle (&optional arg) - "Toggle between `modus-operandi' and `modus-vivendi' themes. - -With optional \\[universal-argument] prefix, enable -`modus-themes-alt-mode' for the loaded theme." - (interactive "P") - (if arg - (modus-themes-alt-mode 1) - (modus-themes-alt-mode -1)) - (if (eq (car custom-enabled-themes) 'modus-operandi) - (progn - (disable-theme 'modus-operandi) - (load-theme 'modus-vivendi t)) - (disable-theme 'modus-vivendi) - (load-theme 'modus-operandi t))) -@end lisp - -@printindex cp - -@node Font configs (DIY) -@section Font configurations for Org (and others) - -The themes are designed to cope well with mixed font settings (@ref{No mixed fonts, , Option -for no font mixing}). Currently this applies to @samp{org-mode} and -@samp{markdown-mode}. - -In practice it means that the user can safely opt for a more -prose-friendly proportionately spaced typeface as their default, while -letting spacing-sensitive elements like tables and inline code always -use a monospaced font, by inheriting from the @samp{fixed-pitch} face. - -Users can try the built-in @kbd{M-x variable-pitch-mode} to see the effect in -action. - -To make everything use your desired font families, you need to configure -the @samp{variable-pitch} (proportional spacing) and @samp{fixed-pitch} (monospaced) -faces respectively. It may also be convenient to set your main typeface -by configuring the @samp{default} face the same way. - -Put something like this in your initialization file (make sure to read -the documentation of @samp{set-face-attribute}, with @kbd{M-x describe-function}): - -@lisp -;; Main typeface -(set-face-attribute 'default nil :family "DejaVu Sans Mono" :height 110) - -;; Proportionately spaced typeface -(set-face-attribute 'variable-pitch nil :family "DejaVu Serif" :height 1.0) - -;; Monospaced typeface -(set-face-attribute 'fixed-pitch nil :family "DejaVu Sans Mono" :height 1.0) -@end lisp - -Note the differences in the @samp{:height} property. The @samp{default} face must -specify an absolute value, which is the point size × 10. So if you want -to use a font at point size @samp{11}, you set the height at @samp{110}.@footnote{@samp{:height} -values do not need to be rounded to multiples of ten: the likes of @samp{115} -are perfectly valid—some typefaces will change to account for those -finer increments.} Whereas every other face must have a value that is -relative to the default, represented as a floating point (if you use an -integer, say, @samp{15} then that means an absolute height). This is of -paramount importantance: it ensures that all fonts can scale gracefully -when using something like the @samp{text-scale-adjust} command which only -operates on the base font size (i.e. the @samp{default} face's absolute -height). - -An alternative syntax for the @samp{default} face, is to pass all typeface -parameters directly to a @samp{font} property.@footnote{Has the benefit of -accepting @samp{fontconfig} parameters (GNU/Linux), such as @samp{"DejaVu Sans -Mono-11:hintstyle=hintslight:autohint=false"}. -@uref{https://www.freedesktop.org/software/fontconfig/fontconfig-user.html}} -Note that here we use a standard point size: - -@lisp -(set-face-attribute 'default nil :font "DejaVu Sans Mono-11") -@end lisp - -Again, remember to only ever specify an absolute height for the @samp{default}. - -@printindex cp - -@node Org user faces (DIY) -@section Org user faces (DIY) - -Users of @samp{org-mode} have the option to configure various keywords and -priority cookies to better match their workflow. User options are -@samp{org-todo-keyword-faces} and @samp{org-priority-faces}. - -As those are meant to be custom faces, it would be futile to have the -themes try to guess what each user would want to use, which keywords to -target, and so on. Instead, we can provide guidelines on how to -customize things to one's liking with the intent of retaining the -overall aesthetics of the theme. - -Please bear in mind that the end result of those is not controlled by -the active theme but by how Org maps faces to its constructs. Editing -those while @samp{org-mode} is active requires @kbd{M-x org-mode-restart} for changes -to take effect. - -Let us assume you wish to visually differentiate your keywords. You -have something like this: - -@lisp -(setq org-todo-keywords - '((sequence "TODO(t)" "|" "DONE(D)" "CANCEL(C)") - (sequence "MEET(m)" "|" "MET(M)") - (sequence "STUDY(s)" "|" "STUDIED(S)") - (sequence "WRITE(w)" "|" "WROTE(W)"))) -@end lisp - -You could then use a variant of the following to inherit from a face -that uses the styles you want and also to preserve the properties -applied by the @samp{org-todo} face: - -@lisp -(setq org-todo-keyword-faces - '(("MEET" . '(font-lock-preprocessor-face org-todo)) - ("STUDY" . '(font-lock-variable-name-face org-todo)) - ("WRITE" . '(font-lock-type-face org-todo)))) -@end lisp - -This will refashion the keywords you specify, while letting the other -items in @samp{org-todo-keywords} use their original styles (which are defined -in the @samp{org-todo} and @samp{org-done} faces). - -If you want back the defaults, try specifying just the @samp{org-todo} face: - -@lisp -(setq org-todo-keyword-faces - '(("MEET" . org-todo) - ("STUDY" . org-todo) - ("WRITE" . org-todo))) -@end lisp - -When you inherit from multiple faces, you need to quote the list as -shown further above. The order is important: the last item is applied -over the previous ones. If you do not want to blend multiple faces, you -do not need a quoted list. A pattern of @samp{keyword . face} would suffice. - -Both approaches can be used simultaneously, as illustrated in this -configuration of the priority cookies: - -@lisp -(setq org-priority-faces - '((?A . '(org-scheduled-today org-priority)) - (?B . org-priority) - (?C . '(shadow org-priority)))) -@end lisp - -To find all the faces that are loaded in your current Emacs session, use -@kbd{M-x list-faces-display}. Also try @kbd{M-x describe-variable} and then specify -the name of each of those Org variables demonstrated above. Their -documentation strings will offer you further guidance. - -Furthermore, consider reading the ``Notes for aspiring Emacs theme -developers'', published on 2020-08-28 by me (Protesilaos Stavrou): -@uref{https://protesilaos.com/codelog/2020-08-28-notes-emacs-theme-devs/}. - -@printindex cp - -@printindex cp - -@node Face coverage -@chapter Face coverage - -Modus Operandi and Modus Vivendi try to provide as close to full face -coverage as possible. This is necessary to ensure a consistently -accessible reading experience across all possible interfaces. - -@menu -* Supported packages:: Full list of covered face groups -* Covered indirectly:: -* Will NOT be supported:: -@end menu - -@node Supported packages -@section Full support for packages or face groups - -This list will always be updated to reflect the current state of the -project. The idea is to offer an overview of the known status of all -affected face groups. The items with an appended asterisk @samp{*} tend to -have lots of extensions, so the ``full support'' may not be 100% true… - -@itemize -@item -ace-window -@item -ag -@item -alert -@item -all-the-icons -@item -annotate -@item -anzu -@item -apropos -@item -apt-sources-list -@item -artbollocks-mode -@item -auctex and @TeX{} -@item -auto-dim-other-buffers -@item -avy -@item -awesome-tray -@item -binder -@item -bm -@item -bongo -@item -boon -@item -breakpoint (provided by the built-in @samp{gdb-mi.el} library) -@item -buffer-expose -@item -calendar and diary -@item -calfw -@item -centaur-tabs -@item -change-log and log-view (such as @samp{vc-print-log} and @samp{vc-print-root-log}) -@item -cider -@item -circe -@item -color-rg -@item -column-enforce-mode -@item -company-mode* -@item -company-posframe -@item -compilation-mode -@item -completions -@item -counsel* -@item -counsel-css -@item -counsel-notmuch -@item -counsel-org-capture-string -@item -cov -@item -cperl-mode -@item -csv-mode -@item -ctrlf -@item -custom (@kbd{M-x customize}) -@item -dap-mode -@item -dashboard (emacs-dashboard) -@item -deadgrep -@item -debbugs -@item -define-word -@item -deft -@item -dictionary -@item -diff-hl -@item -diff-mode -@item -dim-autoload -@item -dir-treeview -@item -dired -@item -dired-async -@item -dired-git -@item -dired-git-info -@item -dired-narrow -@item -dired-subtree -@item -diredfl -@item -disk-usage -@item -doom-modeline -@item -dynamic-ruler -@item -easy-jekyll -@item -easy-kill -@item -ebdb -@item -ediff -@item -eglot -@item -el-search -@item -eldoc-box -@item -elfeed -@item -elfeed-score -@item -emms -@item -enhanced-ruby-mode -@item -epa -@item -equake -@item -erc -@item -eros -@item -ert -@item -eshell -@item -eshell-fringe-status -@item -eshell-git-prompt -@item -eshell-prompt-extras (epe) -@item -eshell-syntax-highlighting -@item -evil* (evil-mode) -@item -evil-goggles -@item -evil-visual-mark-mode -@item -eww -@item -eyebrowse -@item -fancy-dabbrev -@item -flycheck -@item -flycheck-color-mode-line -@item -flycheck-indicator -@item -flycheck-posframe -@item -flymake -@item -flyspell -@item -flyspell-correct -@item -flx -@item -freeze-it -@item -frog-menu -@item -focus -@item -fold-this -@item -font-lock (generic syntax highlighting) -@item -forge -@item -fountain (fountain-mode) -@item -geiser -@item -git-commit -@item -git-gutter (and variants) -@item -git-lens -@item -git-rebase -@item -git-timemachine -@item -git-walktree -@item -gnus -@item -golden-ratio-scroll-screen -@item -helm* -@item -helm-ls-git -@item -helm-switch-shell -@item -helm-xref -@item -helpful -@item -highlight-blocks -@item -highlight-defined -@item -highlight-escape-sequences (@samp{hes-mode}) -@item -highlight-indentation -@item -highlight-numbers -@item -highlight-symbol -@item -highlight-tail -@item -highlight-thing -@item -hl-defined -@item -hl-fill-column -@item -hl-line-mode -@item -hl-todo -@item -hydra -@item -hyperlist -@item -ibuffer -@item -icomplete -@item -icomplete-vertical -@item -ido-mode -@item -iedit -@item -iflipb -@item -imenu-list -@item -indium -@item -info -@item -info-colors -@item -interaction-log -@item -ioccur -@item -isearch, occur, etc. -@item -ivy* -@item -ivy-posframe -@item -jira (org-jira) -@item -journalctl-mode -@item -js2-mode -@item -julia -@item -jupyter -@item -kaocha-runner -@item -keycast -@item -line numbers (@samp{display-line-numbers-mode} and global variant) -@item -lsp-mode -@item -lsp-ui -@item -magit -@item -magit-imerge -@item -man -@item -markdown-mode -@item -markup-faces (@samp{adoc-mode}) -@item -mentor -@item -messages -@item -minibuffer-line -@item -minimap -@item -modeline -@item -mood-line -@item -moody -@item -mpdel -@item -mu4e -@item -mu4e-conversation -@item -multiple-cursors -@item -neotree -@item -no-emoji -@item -notmuch -@item -num3-mode -@item -nxml-mode -@item -objed -@item -orderless -@item -org* -@item -org-journal -@item -org-noter -@item -org-pomodoro -@item -org-recur -@item -org-roam -@item -org-superstar -@item -org-table-sticky-header -@item -org-treescope -@item -origami -@item -outline-mode -@item -outline-minor-faces -@item -package (@kbd{M-x list-packages}) -@item -page-break-lines -@item -paradox -@item -paren-face -@item -parrot -@item -pass -@item -persp-mode -@item -perspective -@item -phi-grep -@item -phi-search -@item -pkgbuild-mode -@item -pomidor -@item -powerline -@item -powerline-evil -@item -proced -@item -prodigy -@item -racket-mode -@item -rainbow-blocks -@item -rainbow-identifiers -@item -rainbow-delimiters -@item -rcirc -@item -regexp-builder (also known as @samp{re-builder}) -@item -rg (rg.el) -@item -ripgrep -@item -rmail -@item -ruler-mode -@item -sallet -@item -selectrum -@item -semantic -@item -sesman -@item -shell-script-mode -@item -show-paren-mode -@item -side-notes -@item -skewer-mode -@item -smart-mode-line -@item -smartparens -@item -smerge -@item -spaceline -@item -speedbar -@item -spell-fu -@item -stripes -@item -suggest -@item -switch-window -@item -swiper -@item -swoop -@item -sx -@item -symbol-overlay -@item -syslog-mode -@item -table (built-in table.el) -@item -telephone-line -@item -term -@item -tomatinho -@item -transient (pop-up windows such as Magit's) -@item -trashed -@item -treemacs -@item -tty-menu -@item -tuareg -@item -typescript -@item -undo-tree -@item -vc (built-in mode line status for version control) -@item -vc-annotate (@kbd{C-x v g}) -@item -vdiff -@item -vimish-fold -@item -visible-mark -@item -visual-regexp -@item -volatile-highlights -@item -vterm -@item -wcheck-mode -@item -web-mode -@item -wgrep -@item -which-function-mode -@item -which-key -@item -whitespace-mode -@item -window-divider-mode -@item -winum -@item -writegood-mode -@item -woman -@item -xah-elisp-mode -@item -xref -@item -xterm-color (and ansi-colors) -@item -yaml-mode -@item -yasnippet -@item -ztree -@end itemize - -Plus many other miscellaneous faces that are provided by the upstream -GNU Emacs distribution. - -@node Covered indirectly -@section Covered indirectly - -These do not require any extra styles because they are configured to -inherit from some basic faces. Please confirm. - -@itemize -@item -edit-indirect -@item -evil-owl -@item -perl-mode -@item -php-mode -@item -rjsx-mode -@item -swift-mode -@end itemize - -@node Will NOT be supported -@section Will NOT be supported - -I have thus far identified a single package that does fit into the -overarching objective of this project: @uref{https://github.com/hlissner/emacs-solaire-mode, solaire}. It basically tries to -cast a less intense background on the main file-visiting buffers, so -that secondary elements like sidebars can have the default (pure -white/black) background. - -I will only cover this package if it ever supports the inverse effect: -less intense colors (but still accessible) for ancillary interfaces -and the intended styles for the content you are actually working on. - -@node Notes for individual packages -@chapter Notes for individual packages - -This section covers information that may be of interest to users of -individual packages. - -@menu -* Note on company-mode overlay pop-up:: -* Note for ERC escaped color sequences:: -* Note for powerline or spaceline:: -* Note on shr colors:: -* Note for Helm grep:: -* Note on vc-annotate-background-mode:: -@end menu - -@node Note on company-mode overlay pop-up -@section Note on company-mode overlay pop-up - -By default, the @samp{company-mode} pop-up that lists completion candidates is -drawn using an overlay. This creates alignment issues every time it is -placed above a piece of text that has a different height than the -default. - -The solution recommended by the project's maintainer is to use an -alternative front-end for drawing the pop-up which uses child frames -instead of overlays.@footnote{@uref{https://github.com/company-mode/company-mode/issues/1010}}@footnote{@uref{https://github.com/tumashu/company-posframe/}} - -@node Note for ERC escaped color sequences -@section Note for ERC escaped color sequences - -The built-in IRC client @samp{erc} has the ability to colorise any text using -escape sequences that start with @samp{^C} (inserted with @samp{C-q C-c}) and are -followed by a number for the foreground and background.@footnote{This page -explains the basics, though it is not specific to Emacs: -@uref{https://www.mirc.com/colors.html}} Possible numbers are 0-15, with the -first entry being the foreground and the second the background, -separated by a comma. Like this @samp{^C1,6}. The minimum setup is this: - -@lisp -(add-to-list 'erc-modules 'irccontrols) -(setq erc-interpret-controls-p t - erc-interpret-mirc-color t) -@end lisp - -As this allows users to make arbitrary combinations, it is impossible to -guarantee a consistently high contrast ratio. All we can we do is -provide guidance on the combinations that satisfy the accessibility -standard of the themes: - -@table @asis -@item Modus Operandi -Use foreground color 1 for all backgrounds from -2-15. Like so: @samp{C-q C-c1,N} where @samp{N} is the background. - -@item Modus Vivendi -Use foreground color 0 for all backgrounds from -2-13. Use foreground @samp{1} for backgrounds 14, 15. -@end table - -Colors 0 and 1 are white and black respectively. So combine them -together, if you must. - -@node Note for powerline or spaceline -@section Note for powerline or spaceline - -Both Powerline and Spaceline package users will likely need to use the -command @samp{powerline-reset} whenever they make changes to their themes -and/or modeline setup. - -@node Note on shr colors -@section Note on shr colors - -Emacs' HTML rendering mechanism (@samp{shr}) may need explicit configuration to -respect the theme's colors instead of whatever specifications the -webpage provides. Consult @kbd{C-h v shr-use-colors}. - -@node Note for Helm grep -@section Note for Helm grep - -There is one face from the Helm package that is meant to highlight the -matches of a grep or grep-like command (@samp{ag} or @samp{ripgrep}). It is -@samp{helm-grep-match}. However, this face can only apply when the user does -not pass @samp{--color=always} as a command-line option for their command. - -Here is the docstring for that face, which is defined in the -@samp{helm-grep.el} library (view a library with @samp{M-x find-library}). - -@quotation -Face used to highlight grep matches. Have no effect when grep backend -use ``--color='' - -@end quotation - -The user must either remove @samp{--color} from the flags passed to the grep -function, or explicitly use @samp{--color=never} (or equivalent). Helm -provides user-facing customization options for controlling the grep -function's parameters, such as @samp{helm-grep-default-command} and -@samp{helm-grep-git-grep-command}. - -When @samp{--color=always} is in effect, the grep output will use red text in -bold letter forms to present the matching part in the list of -candidates. That style still meets the contrast ratio target of >= 7:1 -(accessibility standard WCAG AAA), because it draws the reference to -ANSI color number 1 (red) from the already-supported array of -@samp{ansi-color-names-vector}. - -@node Note on vc-annotate-background-mode -@section Note on vc-annotate-background-mode - -Due to the unique way @samp{vc-annotate} (@kbd{C-x v g}) applies colors, support for -its background mode (@samp{vc-annotate-background-mode}) is disabled at the -theme level. - -Normally, such a drastic measure should not belong in a theme: assuming -the user's preferences is bad practice. However, it has been deemed -necessary in the interest of preserving color contrast accessibility -while still supporting a useful built-in tool. - -If there actually is a way to avoid such a course of action, without -prejudice to the accessibility standard of this project, then please -report as much or send patches (see @ref{Contributing}). - -@node Contributing -@chapter Contributing - -This section documents the canonical sources of the themes and the ways -in which you can contribute to their ongoing development. - -@menu -* Sources of the themes:: -* Issues you can help with:: -* Merge requests:: Legal considerations for code patches -@end menu - -@node Sources of the themes -@section Sources of the themes - -The @samp{modus-operandi} and @samp{modus-vivendi} themes are built into Emacs. -Currently they are in the project's @samp{master} branch, which is tracking the -next development release target. - -The source code of the themes is @uref{https://gitlab.com/protesilaos/modus-themes/, available on Gitlab}, for the time -being. A @uref{https://github.com/protesilaos/modus-themes/, mirror on Github} is also on offer. - -An HTML version of this manual is available as an extension to the -@uref{https://protesilaos.com/modus-themes/, author's personal website} (does not rely on any non-free code). - -@node Issues you can help with -@section Issues you can help with - -A few tasks you can help with: - -@itemize -@item -Suggest refinements to packages that are covered. -@item -Report packages not covered thus far. -@item -Report bugs, inconsistencies, shortcomings. -@item -Help expand the documentation of covered-but-not-styled packages. -@item -Suggest refinements to the color palette. -@item -Help expand this document or any other piece of documentation. -@item -Merge requests for code refinements. -@end itemize - -@xref{Merge requests, , Patches require copyright assignment to the FSF}. - -It would be great if your feedback also includes some screenshots, GIFs, -or short videos, as well as further instructions to reproduce a given -setup. Though this is not a requirement. - -Whatever you do, bear in mind the overarching objective of the Modus -themes: to keep a contrast ratio that is greater or equal to 7:1 between -background and foreground colors. If a compromise is ever necessary -between aesthetics and accessibility, it shall always be made in the -interest of the latter. - -@node Merge requests -@section Patches require copyright assignment to the FSF - -Code contributions are most welcome. For any major edit (more than 15 -lines, or so, in aggregate per person), you need to make a copyright -assignment to the Free Software Foundation. This is necessary because -the themes are part of the upstream Emacs distribution: the FSF must at -all times be in a position to enforce the GNU General Public License. - -Copyright assignment is a simple process. Check the request form below -(please adapt it accordingly). You must write an email to the address -mentioned in the form and then wait for the FSF to send you a legal -agreement. Sign the document and file it back to them. This could all -happen via email and take about a week. You are encouraged to go -through this process. You only need to do it once. It will allow you -to make contributions to Emacs in general. - -@example -Please email the following information to assign@@gnu.org, and we -will send you the assignment form for your past and future changes. - -Please use your full legal name (in ASCII characters) as the subject -line of the message. ----------------------------------------------------------------------- -REQUEST: SEND FORM FOR PAST AND FUTURE CHANGES - -[What is the name of the program or package you're contributing to?] - -GNU Emacs - -[Did you copy any files or text written by someone else in these changes? -Even if that material is free software, we need to know about it.] - -Copied a few snippets from the same files I edited. Their author, -Protesilaos Stavrou, has already assigned copyright to the Free Software -Foundation. - -[Do you have an employer who might have a basis to claim to own -your changes? Do you attend a school which might make such a claim?] - - -[For the copyright registration, what country are you a citizen of?] - - -[What year were you born?] - - -[Please write your email address here.] - - -[Please write your postal address here.] - - - - - -[Which files have you changed so far, and which new files have you written -so far?] - -Changed a couple of themes that are part of the Emacs source code: - -./etc/themes/modus-operandi-theme.el -./etc/themes/modus-vivendi-theme.el -@end example - -@node Acknowledgements -@chapter Acknowledgements - -The Modus themes are a collective effort. Every contribution counts. - -@table @asis -@item Author/maintainer -Protesilaos Stavrou. - -@item Code contributions -Anders Johansson, Basil L@. Contovounesios, -Markus Beppler, Matthew Stevenson. - -@item Ideas and user feedback -Aaron Jensen, Adam Spiers, Alex Griffin, -Alex Peitsinis, Alexey Shmalko, Anders Johansson, André Alexandre -Gomes, Arif Rezai, Basil L@. Contovounesios, Damien Cassou, Dario -Gjorgjevski, David Edmondson, Davor Rotim, Divan Santana, Gerry -Agbobada, Gianluca Recchia, Iris Garcia, Len Trigg, Manuel Uberti, -Mark Burton, Markus Beppler, Michael Goldenberg, Murilo Pereira, -Nicolas De Jaeghere, Pierre Téchoueyres, Roman Rudakov, Ryan Phillips, -Shreyas Ragavan, Tassilo Horn, Thibaut Verron, Trey Merkley, Uri -Sharf, Utkarsh Singh, Vincent Foley. As well as users: Ben, -Fourchaux, Fredrik, Moesasji, Nick, TheBlob42, dinko, doolio, jixiuf, -okamsn, tycho garen. - -@item Packaging -Dhavan Vaidya (Debian), Stefan Kangas (core Emacs), -Stefan Monnier (GNU Elpa). - -@item Inspiration for certain features -Fabrice Niessen (leuven-theme), -Bozhidar Batsov (zenburn-theme). -@end table - -@node Meta -@chapter Meta - -If you are curious about the principles that govern the development of -this project read the essay @uref{https://protesilaos.com/codelog/2020-03-17-design-modus-themes-emacs/, On the design of the Modus themes} -(2020-03-17). - -Here are some more publications for those interested in the kind of work -that goes into this project (sometimes the commits also include details -of this sort): - -@itemize -@item -@uref{https://protesilaos.com/codelog/2020-05-10-modus-operandi-palette-review/, Modus Operandi theme subtle palette review} (2020-05-10) -@item -@uref{https://protesilaos.com/codelog/2020-06-13-modus-vivendi-palette-review/, Modus Vivendi theme subtle palette review} (2020-06-13) -@item -@uref{https://protesilaos.com/codelog/2020-07-04-modus-themes-faint-colours/, Modus themes: new ``faint syntax'' option} (2020-07-04) -@item -@uref{https://protesilaos.com/codelog/2020-07-08-modus-themes-nuanced-colours/, Modus themes: major review of ``nuanced'' colours} (2020-07-08) -@item -@uref{https://protesilaos.com/codelog/2020-09-14-modus-themes-review-blues/, Modus themes: review of blue colours} (2020-09-14) -@end itemize - -And here are the canonical sources for this project's documentation: - -@table @asis -@item Manual -@uref{https://protesilaos.com/modus-themes} -@item Change Log -@uref{https://protesilaos.com/modus-themes-changelog} -@item Screenshots -@uref{https://protesilaos.com/modus-themes-pictures} -@end table - -@node External projects (ports) -@chapter External projects (ports) - -The present section documents projects that extend the scope of the -Modus themes. The following list will be updated whenever relevant -information is brought to my attention. If you already have or intend -to produce such a port, feel welcome @uref{https://protesilaos.com/contact, to contact me}. - -@table @asis -@item Modus exporter -This is @uref{https://github.com/polaris64/modus-exporter, an Elisp library written by Simon Pugnet}. -Licensed under the terms of the GNU General Public License. It is -meant to capture the color values of the active Modus theme (Operandi -or Vivendi) and output it as a valid theme for some other application. -@end table - -@node GNU Free Documentation License -@appendix GNU Free Documentation License - -@example - GNU Free Documentation License - Version 1.3, 3 November 2008 - - - Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. - - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -0. PREAMBLE - -The purpose of this License is to make a manual, textbook, or other -functional and useful document "free" in the sense of freedom: to -assure everyone the effective freedom to copy and redistribute it, -with or without modifying it, either commercially or noncommercially. -Secondarily, this License preserves for the author and publisher a way -to get credit for their work, while not being considered responsible -for modifications made by others. - -This License is a kind of "copyleft", which means that derivative -works of the document must themselves be free in the same sense. It -complements the GNU General Public License, which is a copyleft -license designed for free software. - -We have designed this License in order to use it for manuals for free -software, because free software needs free documentation: a free -program should come with manuals providing the same freedoms that the -software does. But this License is not limited to software manuals; -it can be used for any textual work, regardless of subject matter or -whether it is published as a printed book. We recommend this License -principally for works whose purpose is instruction or reference. - - -1. APPLICABILITY AND DEFINITIONS - -This License applies to any manual or other work, in any medium, that -contains a notice placed by the copyright holder saying it can be -distributed under the terms of this License. Such a notice grants a -world-wide, royalty-free license, unlimited in duration, to use that -work under the conditions stated herein. The "Document", below, -refers to any such manual or work. Any member of the public is a -licensee, and is addressed as "you". You accept the license if you -copy, modify or distribute the work in a way requiring permission -under copyright law. - -A "Modified Version" of the Document means any work containing the -Document or a portion of it, either copied verbatim, or with -modifications and/or translated into another language. - -A "Secondary Section" is a named appendix or a front-matter section of -the Document that deals exclusively with the relationship of the -publishers or authors of the Document to the Document's overall -subject (or to related matters) and contains nothing that could fall -directly within that overall subject. (Thus, if the Document is in -part a textbook of mathematics, a Secondary Section may not explain -any mathematics.) The relationship could be a matter of historical -connection with the subject or with related matters, or of legal, -commercial, philosophical, ethical or political position regarding -them. - -The "Invariant Sections" are certain Secondary Sections whose titles -are designated, as being those of Invariant Sections, in the notice -that says that the Document is released under this License. If a -section does not fit the above definition of Secondary then it is not -allowed to be designated as Invariant. The Document may contain zero -Invariant Sections. If the Document does not identify any Invariant -Sections then there are none. - -The "Cover Texts" are certain short passages of text that are listed, -as Front-Cover Texts or Back-Cover Texts, in the notice that says that -the Document is released under this License. A Front-Cover Text may -be at most 5 words, and a Back-Cover Text may be at most 25 words. - -A "Transparent" copy of the Document means a machine-readable copy, -represented in a format whose specification is available to the -general public, that is suitable for revising the document -straightforwardly with generic text editors or (for images composed of -pixels) generic paint programs or (for drawings) some widely available -drawing editor, and that is suitable for input to text formatters or -for automatic translation to a variety of formats suitable for input -to text formatters. A copy made in an otherwise Transparent file -format whose markup, or absence of markup, has been arranged to thwart -or discourage subsequent modification by readers is not Transparent. -An image format is not Transparent if used for any substantial amount -of text. A copy that is not "Transparent" is called "Opaque". - -Examples of suitable formats for Transparent copies include plain -ASCII without markup, Texinfo input format, LaTeX input format, SGML -or XML using a publicly available DTD, and standard-conforming simple -HTML, PostScript or PDF designed for human modification. Examples of -transparent image formats include PNG, XCF and JPG. Opaque formats -include proprietary formats that can be read and edited only by -proprietary word processors, SGML or XML for which the DTD and/or -processing tools are not generally available, and the -machine-generated HTML, PostScript or PDF produced by some word -processors for output purposes only. - -The "Title Page" means, for a printed book, the title page itself, -plus such following pages as are needed to hold, legibly, the material -this License requires to appear in the title page. For works in -formats which do not have any title page as such, "Title Page" means -the text near the most prominent appearance of the work's title, -preceding the beginning of the body of the text. - -The "publisher" means any person or entity that distributes copies of -the Document to the public. - -A section "Entitled XYZ" means a named subunit of the Document whose -title either is precisely XYZ or contains XYZ in parentheses following -text that translates XYZ in another language. (Here XYZ stands for a -specific section name mentioned below, such as "Acknowledgements", -"Dedications", "Endorsements", or "History".) To "Preserve the Title" -of such a section when you modify the Document means that it remains a -section "Entitled XYZ" according to this definition. - -The Document may include Warranty Disclaimers next to the notice which -states that this License applies to the Document. These Warranty -Disclaimers are considered to be included by reference in this -License, but only as regards disclaiming warranties: any other -implication that these Warranty Disclaimers may have is void and has -no effect on the meaning of this License. - -2. VERBATIM COPYING - -You may copy and distribute the Document in any medium, either -commercially or noncommercially, provided that this License, the -copyright notices, and the license notice saying this License applies -to the Document are reproduced in all copies, and that you add no -other conditions whatsoever to those of this License. You may not use -technical measures to obstruct or control the reading or further -copying of the copies you make or distribute. However, you may accept -compensation in exchange for copies. If you distribute a large enough -number of copies you must also follow the conditions in section 3. - -You may also lend copies, under the same conditions stated above, and -you may publicly display copies. - - -3. COPYING IN QUANTITY - -If you publish printed copies (or copies in media that commonly have -printed covers) of the Document, numbering more than 100, and the -Document's license notice requires Cover Texts, you must enclose the -copies in covers that carry, clearly and legibly, all these Cover -Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on -the back cover. Both covers must also clearly and legibly identify -you as the publisher of these copies. The front cover must present -the full title with all words of the title equally prominent and -visible. You may add other material on the covers in addition. -Copying with changes limited to the covers, as long as they preserve -the title of the Document and satisfy these conditions, can be treated -as verbatim copying in other respects. - -If the required texts for either cover are too voluminous to fit -legibly, you should put the first ones listed (as many as fit -reasonably) on the actual cover, and continue the rest onto adjacent -pages. - -If you publish or distribute Opaque copies of the Document numbering -more than 100, you must either include a machine-readable Transparent -copy along with each Opaque copy, or state in or with each Opaque copy -a computer-network location from which the general network-using -public has access to download using public-standard network protocols -a complete Transparent copy of the Document, free of added material. -If you use the latter option, you must take reasonably prudent steps, -when you begin distribution of Opaque copies in quantity, to ensure -that this Transparent copy will remain thus accessible at the stated -location until at least one year after the last time you distribute an -Opaque copy (directly or through your agents or retailers) of that -edition to the public. - -It is requested, but not required, that you contact the authors of the -Document well before redistributing any large number of copies, to -give them a chance to provide you with an updated version of the -Document. - - -4. MODIFICATIONS - -You may copy and distribute a Modified Version of the Document under -the conditions of sections 2 and 3 above, provided that you release -the Modified Version under precisely this License, with the Modified -Version filling the role of the Document, thus licensing distribution -and modification of the Modified Version to whoever possesses a copy -of it. In addition, you must do these things in the Modified Version: - -A. Use in the Title Page (and on the covers, if any) a title distinct - from that of the Document, and from those of previous versions - (which should, if there were any, be listed in the History section - of the Document). You may use the same title as a previous version - if the original publisher of that version gives permission. -B. List on the Title Page, as authors, one or more persons or entities - responsible for authorship of the modifications in the Modified - Version, together with at least five of the principal authors of the - Document (all of its principal authors, if it has fewer than five), - unless they release you from this requirement. -C. State on the Title page the name of the publisher of the - Modified Version, as the publisher. -D. Preserve all the copyright notices of the Document. -E. Add an appropriate copyright notice for your modifications - adjacent to the other copyright notices. -F. Include, immediately after the copyright notices, a license notice - giving the public permission to use the Modified Version under the - terms of this License, in the form shown in the Addendum below. -G. Preserve in that license notice the full lists of Invariant Sections - and required Cover Texts given in the Document's license notice. -H. Include an unaltered copy of this License. -I. Preserve the section Entitled "History", Preserve its Title, and add - to it an item stating at least the title, year, new authors, and - publisher of the Modified Version as given on the Title Page. If - there is no section Entitled "History" in the Document, create one - stating the title, year, authors, and publisher of the Document as - given on its Title Page, then add an item describing the Modified - Version as stated in the previous sentence. -J. Preserve the network location, if any, given in the Document for - public access to a Transparent copy of the Document, and likewise - the network locations given in the Document for previous versions - it was based on. These may be placed in the "History" section. - You may omit a network location for a work that was published at - least four years before the Document itself, or if the original - publisher of the version it refers to gives permission. -K. For any section Entitled "Acknowledgements" or "Dedications", - Preserve the Title of the section, and preserve in the section all - the substance and tone of each of the contributor acknowledgements - and/or dedications given therein. -L. Preserve all the Invariant Sections of the Document, - unaltered in their text and in their titles. Section numbers - or the equivalent are not considered part of the section titles. -M. Delete any section Entitled "Endorsements". Such a section - may not be included in the Modified Version. -N. Do not retitle any existing section to be Entitled "Endorsements" - or to conflict in title with any Invariant Section. -O. Preserve any Warranty Disclaimers. - -If the Modified Version includes new front-matter sections or -appendices that qualify as Secondary Sections and contain no material -copied from the Document, you may at your option designate some or all -of these sections as invariant. To do this, add their titles to the -list of Invariant Sections in the Modified Version's license notice. -These titles must be distinct from any other section titles. - -You may add a section Entitled "Endorsements", provided it contains -nothing but endorsements of your Modified Version by various -parties--for example, statements of peer review or that the text has -been approved by an organization as the authoritative definition of a -standard. - -You may add a passage of up to five words as a Front-Cover Text, and a -passage of up to 25 words as a Back-Cover Text, to the end of the list -of Cover Texts in the Modified Version. Only one passage of -Front-Cover Text and one of Back-Cover Text may be added by (or -through arrangements made by) any one entity. If the Document already -includes a cover text for the same cover, previously added by you or -by arrangement made by the same entity you are acting on behalf of, -you may not add another; but you may replace the old one, on explicit -permission from the previous publisher that added the old one. - -The author(s) and publisher(s) of the Document do not by this License -give permission to use their names for publicity for or to assert or -imply endorsement of any Modified Version. - - -5. COMBINING DOCUMENTS - -You may combine the Document with other documents released under this -License, under the terms defined in section 4 above for modified -versions, provided that you include in the combination all of the -Invariant Sections of all of the original documents, unmodified, and -list them all as Invariant Sections of your combined work in its -license notice, and that you preserve all their Warranty Disclaimers. - -The combined work need only contain one copy of this License, and -multiple identical Invariant Sections may be replaced with a single -copy. If there are multiple Invariant Sections with the same name but -different contents, make the title of each such section unique by -adding at the end of it, in parentheses, the name of the original -author or publisher of that section if known, or else a unique number. -Make the same adjustment to the section titles in the list of -Invariant Sections in the license notice of the combined work. - -In the combination, you must combine any sections Entitled "History" -in the various original documents, forming one section Entitled -"History"; likewise combine any sections Entitled "Acknowledgements", -and any sections Entitled "Dedications". You must delete all sections -Entitled "Endorsements". - - -6. COLLECTIONS OF DOCUMENTS - -You may make a collection consisting of the Document and other -documents released under this License, and replace the individual -copies of this License in the various documents with a single copy -that is included in the collection, provided that you follow the rules -of this License for verbatim copying of each of the documents in all -other respects. - -You may extract a single document from such a collection, and -distribute it individually under this License, provided you insert a -copy of this License into the extracted document, and follow this -License in all other respects regarding verbatim copying of that -document. - - -7. AGGREGATION WITH INDEPENDENT WORKS - -A compilation of the Document or its derivatives with other separate -and independent documents or works, in or on a volume of a storage or -distribution medium, is called an "aggregate" if the copyright -resulting from the compilation is not used to limit the legal rights -of the compilation's users beyond what the individual works permit. -When the Document is included in an aggregate, this License does not -apply to the other works in the aggregate which are not themselves -derivative works of the Document. - -If the Cover Text requirement of section 3 is applicable to these -copies of the Document, then if the Document is less than one half of -the entire aggregate, the Document's Cover Texts may be placed on -covers that bracket the Document within the aggregate, or the -electronic equivalent of covers if the Document is in electronic form. -Otherwise they must appear on printed covers that bracket the whole -aggregate. - - -8. TRANSLATION - -Translation is considered a kind of modification, so you may -distribute translations of the Document under the terms of section 4. -Replacing Invariant Sections with translations requires special -permission from their copyright holders, but you may include -translations of some or all Invariant Sections in addition to the -original versions of these Invariant Sections. You may include a -translation of this License, and all the license notices in the -Document, and any Warranty Disclaimers, provided that you also include -the original English version of this License and the original versions -of those notices and disclaimers. In case of a disagreement between -the translation and the original version of this License or a notice -or disclaimer, the original version will prevail. - -If a section in the Document is Entitled "Acknowledgements", -"Dedications", or "History", the requirement (section 4) to Preserve -its Title (section 1) will typically require changing the actual -title. - - -9. TERMINATION - -You may not copy, modify, sublicense, or distribute the Document -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense, or distribute it is void, and -will automatically terminate your rights under this License. - -However, if you cease all violation of this License, then your license -from a particular copyright holder is reinstated (a) provisionally, -unless and until the copyright holder explicitly and finally -terminates your license, and (b) permanently, if the copyright holder -fails to notify you of the violation by some reasonable means prior to -60 days after the cessation. - -Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - -Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, receipt of a copy of some or all of the same material does -not give you any rights to use it. - - -10. FUTURE REVISIONS OF THIS LICENSE - -The Free Software Foundation may publish new, revised versions of the -GNU Free Documentation License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in -detail to address new problems or concerns. See -https://www.gnu.org/licenses/. - -Each version of the License is given a distinguishing version number. -If the Document specifies that a particular numbered version of this -License "or any later version" applies to it, you have the option of -following the terms and conditions either of that specified version or -of any later version that has been published (not as a draft) by the -Free Software Foundation. If the Document does not specify a version -number of this License, you may choose any version ever published (not -as a draft) by the Free Software Foundation. If the Document -specifies that a proxy can decide which future versions of this -License can be used, that proxy's public statement of acceptance of a -version permanently authorizes you to choose that version for the -Document. - -11. RELICENSING - -"Massive Multiauthor Collaboration Site" (or "MMC Site") means any -World Wide Web server that publishes copyrightable works and also -provides prominent facilities for anybody to edit those works. A -public wiki that anybody can edit is an example of such a server. A -"Massive Multiauthor Collaboration" (or "MMC") contained in the site -means any set of copyrightable works thus published on the MMC site. - -"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 -license published by Creative Commons Corporation, a not-for-profit -corporation with a principal place of business in San Francisco, -California, as well as future copyleft versions of that license -published by that same organization. - -"Incorporate" means to publish or republish a Document, in whole or in -part, as part of another Document. - -An MMC is "eligible for relicensing" if it is licensed under this -License, and if all works that were first published under this License -somewhere other than this MMC, and subsequently incorporated in whole or -in part into the MMC, (1) had no cover texts or invariant sections, and -(2) were thus incorporated prior to November 1, 2008. - -The operator of an MMC Site may republish an MMC contained in the site -under CC-BY-SA on the same site at any time before August 1, 2009, -provided the MMC is eligible for relicensing. - - -ADDENDUM: How to use this License for your documents - -To use this License in a document you have written, include a copy of -the License in the document and put the following copyright and -license notices just after the title page: - - Copyright (c) YEAR YOUR NAME. - Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.3 - or any later version published by the Free Software Foundation; - with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. - A copy of the license is included in the section entitled "GNU - Free Documentation License". - -If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, -replace the "with...Texts." line with this: - - with the Invariant Sections being LIST THEIR TITLES, with the - Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. - -If you have Invariant Sections without Cover Texts, or some other -combination of the three, merge those two alternatives to suit the -situation. - -If your document contains nontrivial examples of program code, we -recommend releasing these examples in parallel under your choice of -free software license, such as the GNU General Public License, -to permit their use in free software. -@end example - -@bye diff --git a/doc/misc/org-setup.org b/doc/misc/org-setup.org new file mode 100644 index 0000000000..b83d16e7e5 --- /dev/null +++ b/doc/misc/org-setup.org @@ -0,0 +1,36 @@ +# SETUPFILE for manuals + +# XXX: We cannot use TODO keyword as a node starts with "TODO". +#+todo: REVIEW FIXME | DONE +#+property: header-args :eval no +#+startup: overview nologdone + +# Use proper quote and backtick for code sections in PDF output +# Cf. Texinfo manual 14.2 +#+texinfo_header: @set txicodequoteundirected +#+texinfo_header: @set txicodequotebacktick + +# Contact Info +#+texinfo_header: @set MAINTAINERSITE @uref{https://orgmode.org,maintainers webpage} +#+texinfo_header: @set MAINTAINER Bastien Guerry +#+texinfo_header: @set MAINTAINEREMAIL @email{bzg@gnu.org} +#+texinfo_header: @set MAINTAINERCONTACT @uref{mailto:bzg@gnu.org,contact the maintainer} + +#+options: H:4 num:t toc:t author:t \n:nil ::t |:t ^:nil -:t f:t *:t <:t e:t ':t +#+options: d:nil todo:nil pri:nil tags:not-in-toc stat:nil broken-links:mark +#+select_tags: export +#+exclude_tags: noexport + +#+macro: cite @@texinfo:@cite{@@$1@@texinfo:}@@ +#+macro: var @@texinfo:@var{@@$1@@texinfo:}@@ + +# The "version" macro extracts "Version" keyword from "org.el". It +# returns major.minor version number. This is sufficient since bugfix +# releases are not expected to add features and therefore imply manual +# modifications. +#+macro: version (eval (with-current-buffer (find-file-noselect "../lisp/org.el") (org-with-point-at 1 (if (re-search-forward "Version: +\\([0-9.]+\\)" nil t) (mapconcat #'identity (cl-subseq (split-string (match-string-no-properties 1) "\\.") 0 2) ".") (error "Missing \"Version\" keyword in \"org.el\""))))) + +# The "kbd" macro turns KBD into @kbd{KBD}. Additionally, it +# encloses case-sensitive special keys (SPC, RET...) within @key{...}. +#+macro: kbd (eval (let ((case-fold-search nil) (regexp (regexp-opt '("SPC" "RET" "LFD" "TAB" "BS" "ESC" "DELETE" "SHIFT" "Ctrl" "Meta" "Alt" "Cmd" "Super" "UP" "LEFT" "RIGHT" "DOWN") 'words))) (format "@@texinfo:@kbd{@@%s@@texinfo:}@@" (replace-regexp-in-string regexp "@@texinfo:@key{@@\\&@@texinfo:}@@" $1 t)))) + diff --git a/doc/misc/org.org b/doc/misc/org.org new file mode 100644 index 0000000000..5d4e3f26fa --- /dev/null +++ b/doc/misc/org.org @@ -0,0 +1,21905 @@ +#+title: The Org Manual +#+subtitle: Release {{{version}}} +#+author: The Org Mode Developers +#+date: {{{modification-time}}} +#+language: en + + +#+texinfo: @insertcopying + +* Introduction +:PROPERTIES: +:DESCRIPTION: Getting started. +:END: +#+cindex: introduction + +** Summary +:PROPERTIES: +:DESCRIPTION: Brief summary of what Org does. +:END: +#+cindex: summary + +Org is a mode for keeping notes, maintaining TODO lists, and project +planning with a fast and effective plain-text markup language. It +also is an authoring system with unique support for literate +programming and reproducible research. + +Org is implemented on top of Outline mode, which makes it possible to +keep the content of large files well structured. Visibility cycling +and structure editing help to work with the tree. Tables are easily +created with a built-in table editor. Plain text URL-like links +connect to websites, emails, Usenet messages, BBDB entries, and any +files related to the projects. + +Org develops organizational tasks around notes files that contain +lists or information about projects as plain text. Project planning +and task management make use of metadata which is part of an outline +node. Based on this data, specific entries can be extracted in +queries and create dynamic /agenda views/ that also integrate the +Emacs calendar and diary. Org can be used to implement many different +project planning schemes, such as David Allen's GTD system. + +Org files can serve as a single source authoring system with export to +many different formats such as HTML, LaTeX, Open Document, and +Markdown. New export backends can be derived from existing ones, or +defined from scratch. + +Org files can include source code blocks, which makes Org uniquely +suited for authoring technical documents with code examples. Org +source code blocks are fully functional; they can be evaluated in +place and their results can be captured in the file. This makes it +possible to create a single file reproducible research compendium. + +Org keeps simple things simple. When first fired up, it should feel +like a straightforward, easy to use outliner. Complexity is not +imposed, but a large amount of functionality is available when needed. +Org is a toolbox. Many users actually run only a---very +personal---fraction of Org's capabilities, and know that there is more +whenever they need it. + +All of this is achieved with strictly plain text files, the most +portable and future-proof file format. Org runs in Emacs. Emacs is +one of the most widely ported programs, so that Org mode is available +on every major platform. + +#+cindex: FAQ +There is a website for Org which provides links to the newest version +of Org, as well as additional information, frequently asked questions +(FAQ), links to tutorials, etc. This page is located at +[[https://orgmode.org]]. + +#+cindex: print edition +An earlier version (7.3) of this manual is available as a [[http://www.network-theory.co.uk/org/manual/][paperback +book from Network Theory Ltd.]]. + +** Installation +:PROPERTIES: +:DESCRIPTION: Installing Org. +:END: +#+cindex: installation + +Org is included in all recent distributions of GNU Emacs, so you +probably do not need to install it. Most users will simply activate +Org and begin exploring its many features. + +If, for one reason or another, you want to install Org on top of this +pre-packaged version, there are three ways to do it: + +- by using the Emacs package system; +- by downloading Org as an archive; or +- by using Org's git repository. + +We *strongly recommend* sticking to a single installation method. + +*** Using Emacs packaging system +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +Recent Emacs distributions include a packaging system which lets you +install Elisp libraries. You can install Org from the "package menu", +with {{{kbd(M-x list-packages)}}}. See [[info:emacs::Package Menu][Package Menu]]. + +#+attr_texinfo: :tag Important +#+begin_quote +You need to do this in a session where no =.org= file has been +visited, i.e., where no Org built-in function have been loaded. +Otherwise autoload Org functions will mess up the installation. +#+end_quote + +If you want to use Org's package repository, check out the [[https://orgmode.org/elpa.html][Org ELPA +page]]. + +*** Downloading Org as an archive +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +You can download Org latest release from [[https://orgmode.org/][Org's website]]. In this case, +make sure you set the load path correctly in your Emacs init file: + +#+begin_src emacs-lisp +(add-to-list 'load-path "~/path/to/orgdir/lisp") +#+end_src + +The downloaded archive contains contributed libraries that are not +included in Emacs. If you want to use them, add the =contrib/= +directory to your load path: + +#+begin_src emacs-lisp +(add-to-list 'load-path "~/path/to/orgdir/contrib/lisp" t) +#+end_src + +Optionally, you can compile the files and/or install them in your +system. Run =make help= to list compilation and installation options. + +*** Using Org's git repository +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +You can clone Org's repository and install Org like this: + +#+begin_example +$ cd ~/src/ +$ git clone https://code.orgmode.org/bzg/org-mode.git +$ cd org-mode/ +$ make autoloads +#+end_example + +Note that in this case, =make autoloads= is mandatory: it defines +Org's version in =org-version.el= and Org's autoloads in +=org-loaddefs.el=. + +Remember to add the correct load path as described in the method +above. + +You can also compile with =make=, generate the documentation with +=make doc=, create a local configuration with =make config= and +install Org with =make install=. Please run =make help= to get the +list of compilation/installation options. + +For more detailed explanations on Org's build system, please check the +Org Build System page on [[https://orgmode.org/worg/dev/org-build-system.html][Worg]]. + +** Activation +:PROPERTIES: +:DESCRIPTION: How to activate Org for certain buffers. +:END: +#+cindex: activation +#+cindex: autoload +#+cindex: ELPA +#+cindex: global key bindings +#+cindex: key bindings, global + +Org mode buffers need Font Lock to be turned on: this is the default +in Emacs[fn:1]. + +There are compatibility issues between Org mode and some other Elisp +packages (see [[*Packages that conflict with Org mode]]). Please take the +time to check the list. + +#+findex: org-agenda +#+findex: org-capture +#+findex: org-store-link +For a better experience, the three Org commands ~org-store-link~, +~org-capture~ and ~org-agenda~ ought to be accessible anywhere in +Emacs, not just in Org buffers. To that effect, you need to bind them +to globally available keys, like the ones reserved for users (see +[[info:elisp::Key Binding Conventions]]). Here are suggested bindings, +please modify the keys to your own liking. + +#+begin_src emacs-lisp +(global-set-key (kbd "C-c l") 'org-store-link) +(global-set-key (kbd "C-c a") 'org-agenda) +(global-set-key (kbd "C-c c") 'org-capture) +#+end_src + +#+cindex: Org mode, turning on +Files with the =.org= extension use Org mode by default. To turn on +Org mode in a file that does not have the extension =.org=, make the +first line of a file look like this: + +: MY PROJECTS -*- mode: org; -*- + +#+vindex: org-insert-mode-line-in-empty-file +#+texinfo: @noindent +which selects Org mode for this buffer no matter what the file's name +is. See also the variable ~org-insert-mode-line-in-empty-file~. + +Many commands in Org work on the region if the region is /active/. To +make use of this, you need to have Transient Mark mode turned on, +which is the default. If you do not like it, you can create an active +region by using the mouse to select a region, or pressing +{{{kbd(C-SPC)}}} twice before moving point. + +** Feedback +:PROPERTIES: +:DESCRIPTION: Bug reports, ideas, patches, etc. +:END: +#+cindex: feedback +#+cindex: bug reports +#+cindex: reporting a bug +#+cindex: maintainer +#+cindex: author + +If you find problems with Org, or if you have questions, remarks, or +ideas about it, please send an email to the Org mailing list +[[mailto:emacs-orgmode@gnu.org]]. You can subscribe to the list [[https://lists.gnu.org/mailman/listinfo/emacs-orgmode][from this +web page]]. If you are not a member of the mailing list, your mail will +be passed to the list after a moderator has approved it[fn:2]. We ask +you to read and respect the [[https://www.gnu.org/philosophy/kind-communication.html][GNU Kind Communications Guidelines]] when +sending messages on this mailing list. + +#+findex: org-version +#+findex: org-submit-bug-report +For bug reports, please first try to reproduce the bug with the latest +version of Org available---if you are running an outdated version, it +is quite possible that the bug has been fixed already. If the bug +persists, prepare a report and provide as much information as +possible, including the version information of Emacs ({{{kbd(M-x +emacs-version)}}}) and Org ({{{kbd(M-x org-version)}}}), as well as +the Org related setup in the Emacs init file. The easiest way to do +this is to use the command + +: M-x org-submit-bug-report + +#+texinfo: @noindent +which puts all this information into an Emacs mail buffer so that you +only need to add your description. If you are not sending the Email +from within Emacs, please copy and paste the content into your Email +program. + +Sometimes you might face a problem due to an error in your Emacs or +Org mode setup. Before reporting a bug, it is very helpful to start +Emacs with minimal customizations and reproduce the problem. Doing so +often helps you determine if the problem is with your customization or +with Org mode itself. You can start a typical minimal session with +a command like the example below. + +: $ emacs -Q -l /path/to/minimal-org.el + +However if you are using Org mode as distributed with Emacs, a minimal +setup is not necessary. In that case it is sufficient to start Emacs +as =emacs -Q=. The =minimal-org.el= setup file can have contents as +shown below. + +#+begin_src emacs-lisp +;;; Minimal setup to load latest `org-mode'. + +;; Activate debugging. +(setq debug-on-error t + debug-on-signal nil + debug-on-quit nil) + +;; Add latest Org mode to load path. +(add-to-list 'load-path (expand-file-name "/path/to/org-mode/lisp")) +(add-to-list 'load-path (expand-file-name "/path/to/org-mode/contrib/lisp" t)) +#+end_src + +If an error occurs, a "backtrace" can be very useful---see below on +how to create one. Often a small example file helps, along with clear +information about: + +1. What exactly did you do? +2. What did you expect to happen? +3. What happened instead? + +Thank you for helping to improve this program. + +*** How to create a useful backtrace +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: backtrace of an error +If working with Org produces an error with a message you do not +understand, you may have hit a bug. The best way to report this is by +providing, in addition to what was mentioned above, a backtrace. This +is information from the built-in debugger about where and how the +error occurred. Here is how to produce a useful backtrace: + +1. Reload uncompiled versions of all Org mode Lisp files. The + backtrace contains much more information if it is produced with + uncompiled code. To do this, use + + : C-u M-x org-reload + + #+texinfo: @noindent + or, from the menu: Org \rarr Refresh/Reload \rarr Reload Org uncompiled. + +2. Then, activate the debugger: + + : M-x toggle-debug-on-error + + #+texinfo: @noindent + or, from the menu: Options \rarr Enter Debugger on Error. + +3. Do whatever you have to do to hit the error. Do not forget to + document the steps you take. + +4. When you hit the error, a =*Backtrace*= buffer appears on the + screen. Save this buffer to a file---for example using {{{kbd(C-x + C-w)}}}---and attach it to your bug report. + +** Typesetting Conventions Used in this Manual +:PROPERTIES: +:DESCRIPTION: Typesetting conventions used in this manual. +:ALT_TITLE: Conventions +:END: + +*** TODO keywords, tags, properties, etc. +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +Org uses various syntactical elements: TODO keywords, tags, property +names, keywords, blocks, etc. In this manual we use the following +conventions: + +#+attr_texinfo: :sep , +- =TODO=, =WAITING= :: + + TODO keywords are written with all capitals, even if they are + user-defined. + +- =boss=, =ARCHIVE= :: + + Tags are case-sensitive. User-defined tags are written in + lowercase; built-in tags with special meaning are written as they + should appear in the document, usually with all capitals. + +- =Release=, =PRIORITY= :: + + User-defined properties are capitalized; built-in properties with + special meaning are written with all capitals. + +- =TITLE=, =BEGIN= ... =END= :: + + Keywords and blocks are written in uppercase to enhance their + readability, but you can use lowercase in your Org files. + +*** Key bindings and commands +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +The manual lists both the keys and the corresponding commands for +accessing a functionality. Org mode often uses the same key for +different functions, depending on context. The command that is bound +to such keys has a generic name, like ~org-metaright~. In the manual +we will, wherever possible, give the function that is internally +called by the generic command. For example, in the chapter on +document structure, {{{kbd(M-RIGHT)}}} will be listed to call +~org-do-demote~, while in the chapter on tables, it will be listed to +call ~org-table-move-column-right~. + +* Document Structure +:PROPERTIES: +:DESCRIPTION: A tree works like your brain. +:END: + +#+cindex: document structure +#+cindex: structure of document +Org is an outliner. Outlines allow a document to be organized in +a hierarchical structure, which, least for me, is the best +representation of notes and thoughts. An overview of this structure +is achieved by folding, i.e., hiding large parts of the document to +show only the general document structure and the parts currently being +worked on. Org greatly simplifies the use of outlines by compressing +the entire show and hide functionalities into a single command, +~org-cycle~, which is bound to the {{{kbd(TAB)}}} key. + +** Headlines +:PROPERTIES: +:DESCRIPTION: How to typeset Org tree headlines. +:END: +#+cindex: headlines +#+cindex: outline tree +#+vindex: org-special-ctrl-a/e +#+vindex: org-special-ctrl-k +#+vindex: org-ctrl-k-protect-subtree + +Headlines define the structure of an outline tree. Org headlines +start on the left margin[fn:3] with one or more stars followed by +a space. For example: + +#+begin_example +,* Top level headline +,** Second level +,*** Third level + some text +,*** Third level + more text +,* Another top level headline +#+end_example + +#+vindex: org-footnote-section +The name defined in ~org-footnote-section~ is reserved. Do not use it +as a title for your own headings. + +Some people find the many stars too noisy and would prefer an outline +that has whitespace followed by a single star as headline starters. +This can be achieved using a Org Indent minor mode. See [[*A Cleaner +Outline View]] for more information. + +Headlines are not numbered. However, you may want to dynamically +number some, or all, of them. See [[*Dynamic Headline Numbering]]. + +#+vindex: org-cycle-separator-lines +An empty line after the end of a subtree is considered part of it and +is hidden when the subtree is folded. However, if you leave at least +two empty lines, one empty line remains visible after folding the +subtree, in order to structure the collapsed view. See the variable +~org-cycle-separator-lines~ to modify this behavior. + +** Visibility Cycling +:PROPERTIES: +:DESCRIPTION: Show and hide, much simplified. +:END: +#+cindex: cycling, visibility +#+cindex: visibility cycling +#+cindex: trees, visibility +#+cindex: show hidden text +#+cindex: hide text + +*** Global and local cycling +:PROPERTIES: +:DESCRIPTION: Cycling through various visibility states. +:END: +#+cindex: subtree visibility states +#+cindex: subtree cycling +#+cindex: folded, subtree visibility state +#+cindex: children, subtree visibility state +#+cindex: subtree, subtree visibility state + +Outlines make it possible to hide parts of the text in the buffer. +Org uses just two commands, bound to {{{kbd(TAB)}}} and +{{{kbd(S-TAB)}}} to change the visibility in the buffer. + +#+attr_texinfo: :sep , +- {{{kbd(TAB)}}} (~org-cycle~) :: + + #+kindex: TAB + #+findex: org-cycle + /Subtree cycling/: Rotate current subtree among the states + + #+begin_example + ,-> FOLDED -> CHILDREN -> SUBTREE --. + '-----------------------------------' + #+end_example + + #+vindex: org-cycle-emulate-tab + Point must be on a headline for this to work[fn:4]. + +- {{{kbd(S-TAB)}}} (~org-global-cycle~), {{{kbd(C-u TAB)}}} :: + + #+cindex: global visibility states + #+cindex: global cycling + #+cindex: overview, global visibility state + #+cindex: contents, global visibility state + #+cindex: show all, global visibility state + #+kindex: C-u TAB + #+kindex: S-TAB + #+findex: org-global-cycle + /Global cycling/: Rotate the entire buffer among the states + + #+begin_example + ,-> OVERVIEW -> CONTENTS -> SHOW ALL --. + '--------------------------------------' + #+end_example + + When {{{kbd(S-TAB)}}} is called with a numeric prefix argument + {{{var(N)}}}, view contents only up to headlines of level + {{{var(N)}}}. + + Note that inside tables (see [[*Tables]]), {{{kbd(S-TAB)}}} jumps to the + previous field instead. + + #+vindex: org-cycle-global-at-bob + You can run global cycling using {{{kbd(TAB)}}} only if point is at + the very beginning of the buffer, but not on a headline, and + ~org-cycle-global-at-bob~ is set to a non-~nil~ value. + +- {{{kbd(C-u C-u TAB)}}} (~org-set-startup-visibility~) :: + + #+cindex: startup visibility + #+kindex: C-u C-u TAB + #+findex: org-set-startup-visibility + Switch back to the startup visibility of the buffer (see [[*Initial + visibility]]). + +- {{{kbd(C-u C-u C-u TAB)}}} (~outline-show-all~) :: + + #+cindex: show all, command + #+kindex: C-u C-u C-u TAB + #+findex: outline-show-all + Show all, including drawers. + +- {{{kbd(C-c C-r)}}} (~org-reveal~) :: + + #+cindex: revealing context + #+kindex: C-c C-r + #+findex: org-reveal + Reveal context around point, showing the current entry, the + following heading and the hierarchy above. It is useful for working + near a location that has been exposed by a sparse tree command (see + [[*Sparse Trees]]) or an agenda command (see [[*Commands in the Agenda + Buffer]]). With a prefix argument, show, on each level, all sibling + headings. With a double prefix argument, also show the entire + subtree of the parent. + +- {{{kbd(C-c C-k)}}} (~outline-show-branches~) :: + + #+cindex: show branches, command + #+kindex: C-c C-k + #+findex: outline-show-branches + Expose all the headings of the subtree, but not their bodies. + +- {{{kbd(C-c TAB)}}} (~outline-show-children~) :: + + #+cindex: show children, command + #+kindex: C-c TAB + #+findex: outline-show-children + Expose all direct children of the subtree. With a numeric prefix + argument {{{var(N)}}}, expose all children down to level + {{{var(N)}}}. + +- {{{kbd(C-c C-x b)}}} (~org-tree-to-indirect-buffer~) :: + + #+kindex: C-c C-x b + #+findex: org-tree-to-indirect-buffer + Show the current subtree in an indirect buffer[fn:5]. With + a numeric prefix argument {{{var(N)}}}, go up to level {{{var(N)}}} + and then take that tree. If {{{var(N)}}} is negative then go up + that many levels. With a {{{kbd(C-u)}}} prefix, do not remove the + previously used indirect buffer. + +- {{{kbd(C-c C-x v)}}} (~org-copy-visible~) :: + + #+kindex: C-c C-x v + #+findex: org-copy-visible + Copy the /visible/ text in the region into the kill ring. + +*** Initial visibility +:PROPERTIES: +:DESCRIPTION: Setting the initial visibility state. +:END: + +#+vindex: org-startup-folded +When Emacs first visits an Org file, the global state is set to +~showeverything~, i.e., all file content is visible[fn:6]. This can +be configured through the variable ~org-startup-folded~, or on +a per-file basis by adding one of the following lines anywhere in the +buffer: + +#+cindex: @samp{STARTUP}, keyword +#+begin_example +,#+STARTUP: overview +,#+STARTUP: content +,#+STARTUP: showall +,#+STARTUP: showeverything +#+end_example + +#+cindex: @samp{VISIBILITY}, property +Furthermore, any entries with a =VISIBILITY= property (see [[*Properties +and Columns]]) get their visibility adapted accordingly. Allowed values +for this property are =folded=, =children=, =content=, and =all=. + +- {{{kbd(C-u C-u TAB)}}} (~org-set-startup-visibility~) :: + + #+kindex: C-u C-u TAB + #+findex: org-set-startup-visibility + Switch back to the startup visibility of the buffer, i.e., whatever + is requested by startup options and =VISIBILITY= properties in + individual entries. + +*** Catching invisible edits +:PROPERTIES: +:DESCRIPTION: Preventing mistakes when editing invisible parts. +:END: +#+cindex: edits, catching invisible + +#+vindex: org-catch-invisible-edits +Sometimes you may inadvertently edit an invisible part of the buffer +and be confused on what has been edited and how to undo the mistake. +Setting ~org-catch-invisible-edits~ to non-~nil~ helps preventing +this. See the docstring of this option on how Org should catch +invisible edits and process them. + +** Motion +:PROPERTIES: +:DESCRIPTION: Jumping to other headlines. +:END: +#+cindex: motion, between headlines +#+cindex: jumping, to headlines +#+cindex: headline navigation + +The following commands jump to other headlines in the buffer. + +- {{{kbd(C-c C-n)}}} (~org-next-visible-heading~) :: + + #+kindex: C-c C-n + #+findex: org-next-visible-heading + Next heading. + +- {{{kbd(C-c C-p)}}} (~org-previous-visible-heading~) :: + + #+kindex: C-c C-p + #+findex: org-previous-visible-heading + Previous heading. + +- {{{kbd(C-c C-f)}}} (~org-forward-heading-same-level~) :: + + #+kindex: C-c C-f + #+findex: org-forward-heading-same-level + Next heading same level. + +- {{{kbd(C-c C-b)}}} (~org-backward-heading-same-level~) :: + + #+kindex: C-c C-b + #+findex: org-backward-heading-same-level + Previous heading same level. + +- {{{kbd(C-c C-u)}}} (~outline-up-heading~) :: + + #+kindex: C-c C-u + #+findex: outline-up-heading + Backward to higher level heading. + +- {{{kbd(C-c C-j)}}} (~org-goto~) :: + + #+kindex: C-c C-j + #+findex: org-goto + #+vindex: org-goto-auto-isearch + Jump to a different place without changing the current outline + visibility. Shows the document structure in a temporary buffer, + where you can use the following keys to find your destination: + + #+attr_texinfo: :columns 0.3 0.7 + | {{{kbd(TAB)}}} | Cycle visibility. | + | {{{kbd(DOWN)}}} / {{{kbd(UP)}}} | Next/previous visible headline. | + | {{{kbd(RET)}}} | Select this location. | + | {{{kbd(/)}}} | Do a Sparse-tree search | + + #+texinfo: @noindent + The following keys work if you turn off ~org-goto-auto-isearch~ + + #+attr_texinfo: :columns 0.3 0.7 + | {{{kbd(n)}}} / {{{kbd(p)}}} | Next/previous visible headline. | + | {{{kbd(f)}}} / {{{kbd(b)}}} | Next/previous headline same level. | + | {{{kbd(u)}}} | One level up. | + | {{{kbd(0)}}} ... {{{kbd(9)}}} | Digit argument. | + | {{{kbd(q)}}} | Quit. | + + #+vindex: org-goto-interface + #+texinfo: @noindent + See also the variable ~org-goto-interface~. + +** Structure Editing +:PROPERTIES: +:DESCRIPTION: Changing sequence and level of headlines. +:END: +#+cindex: structure editing +#+cindex: headline, promotion and demotion +#+cindex: promotion, of subtrees +#+cindex: demotion, of subtrees +#+cindex: subtree, cut and paste +#+cindex: pasting, of subtrees +#+cindex: cutting, of subtrees +#+cindex: copying, of subtrees +#+cindex: sorting, of subtrees +#+cindex: subtrees, cut and paste + +#+attr_texinfo: :sep , +- {{{kbd(M-RET)}}} (~org-meta-return~) :: + + #+kindex: M-RET + #+findex: org-meta-return + #+vindex: org-M-RET-may-split-line + Insert a new heading, item or row. + + If the command is used at the /beginning/ of a line, and if there is + a heading or a plain list item (see [[*Plain Lists]]) at point, the new + heading/item is created /before/ the current line. When used at the + beginning of a regular line of text, turn that line into a heading. + + When this command is used in the middle of a line, the line is split + and the rest of the line becomes the new item or headline. If you + do not want the line to be split, customize + ~org-M-RET-may-split-line~. + + Calling the command with a {{{kbd(C-u)}}} prefix unconditionally + inserts a new heading at the end of the current subtree, thus + preserving its contents. With a double {{{kbd(C-u C-u)}}} prefix, + the new heading is created at the end of the parent subtree instead. + +- {{{kbd(C-RET)}}} (~org-insert-heading-respect-content~) :: + + #+kindex: C-RET + #+findex: org-insert-heading-respect-content + Insert a new heading at the end of the current subtree. + +- {{{kbd(M-S-RET)}}} (~org-insert-todo-heading~) :: + + #+kindex: M-S-RET + #+findex: org-insert-todo-heading + #+vindex: org-treat-insert-todo-heading-as-state-change + Insert new TODO entry with same level as current heading. See also + the variable ~org-treat-insert-todo-heading-as-state-change~. + +- {{{kbd(C-S-RET)}}} (~org-insert-todo-heading-respect-content~) :: + + #+kindex: C-S-RET + #+findex: org-insert-todo-heading-respect-content + Insert new TODO entry with same level as current heading. Like + {{{kbd(C-RET)}}}, the new headline is inserted after the current + subtree. + +- {{{kbd(TAB)}}} (~org-cycle~) :: + + #+kindex: TAB + #+findex: org-cycle + In a new entry with no text yet, the first {{{kbd(TAB)}}} demotes + the entry to become a child of the previous one. The next + {{{kbd(TAB)}}} makes it a parent, and so on, all the way to top + level. Yet another {{{kbd(TAB)}}}, and you are back to the initial + level. + +- {{{kbd(M-LEFT)}}} (~org-do-promote~), {{{kbd(M-RIGHT)}}} (~org-do-demote~) :: + + #+kindex: M-LEFT + #+findex: org-do-promote + #+kindex: M-RIGHT + #+findex: org-do-demote + Promote or demote current heading by one level. + + #+cindex: region, active + #+cindex: active region + #+cindex: transient mark mode + When there is an active region---i.e., when Transient Mark mode is + active---promotion and demotion work on all headlines in the region. + To select a region of headlines, it is best to place both point and + mark at the beginning of a line, mark at the beginning of the first + headline, and point at the line just after the last headline to + change. + +- {{{kbd(M-S-LEFT)}}} (~org-promote-subtree~) :: + + #+kindex: M-S-LEFT + #+findex: org-promote-subtree + Promote the current subtree by one level. + +- {{{kbd(M-S-RIGHT)}}} (~org-demote-subtree~) :: + + #+kindex: M-S-RIGHT + #+findex: org-demote-subtree + Demote the current subtree by one level. + +- {{{kbd(M-UP)}}} (~org-move-subtree-up~) :: + + #+kindex: M-UP + #+findex: org-move-subtree-up + Move subtree up, i.e., swap with previous subtree of same level. + +- {{{kbd(M-DOWN)}}} (~org-move-subtree-down~) :: + + #+kindex: M-DOWN + #+findex: org-move-subtree-down + Move subtree down, i.e., swap with next subtree of same level. + +- {{{kbd(C-c @)}}} (~org-mark-subtree~) :: + + #+kindex: C-c @@ + #+findex: org-mark-subtree + Mark the subtree at point. Hitting repeatedly marks subsequent + subtrees of the same level as the marked subtree. + +- {{{kbd(C-c C-x C-w)}}} (~org-cut-subtree~) :: + + #+kindex: C-c C-x C-w + #+findex: org-cut-subtree + Kill subtree, i.e., remove it from buffer but save in kill ring. + With a numeric prefix argument N, kill N sequential subtrees. + +- {{{kbd(C-c C-x M-w)}}} (~org-copy-subtree~) :: + + #+kindex: C-c C-x M-w + #+findex: org-copy-subtree + Copy subtree to kill ring. With a numeric prefix argument N, copy + the N sequential subtrees. + +- {{{kbd(C-c C-x C-y)}}} (~org-paste-subtree~) :: + + #+kindex: C-c C-x C-y + #+findex: org-paste-subtree + Yank subtree from kill ring. This does modify the level of the + subtree to make sure the tree fits in nicely at the yank position. + The yank level can also be specified with a numeric prefix argument, + or by yanking after a headline marker like =****=. + +- {{{kbd(C-y)}}} (~org-yank~) :: + + #+kindex: C-y + #+findex: org-yank + #+vindex: org-yank-adjusted-subtrees + #+vindex: org-yank-folded-subtrees + Depending on the variables ~org-yank-adjusted-subtrees~ and + ~org-yank-folded-subtrees~, Org's internal ~yank~ command pastes + subtrees folded and in a clever way, using the same command as + {{{kbd(C-c C-x C-y)}}}. With the default settings, no level + adjustment takes place, but the yanked tree is folded unless doing + so would swallow text previously visible. Any prefix argument to + this command forces a normal ~yank~ to be executed, with the prefix + passed along. A good way to force a normal yank is {{{kbd(C-u + C-y)}}}. If you use ~yank-pop~ after a yank, it yanks previous kill + items plainly, without adjustment and folding. + +- {{{kbd(C-c C-x c)}}} (~org-clone-subtree-with-time-shift~) :: + + #+kindex: C-c C-x c + #+findex: org-clone-subtree-with-time-shift + Clone a subtree by making a number of sibling copies of it. You are + prompted for the number of copies to make, and you can also specify + if any timestamps in the entry should be shifted. This can be + useful, for example, to create a number of tasks related to a series + of lectures to prepare. For more details, see the docstring of the + command ~org-clone-subtree-with-time-shift~. + +- {{{kbd(C-c C-w)}}} (~org-refile~) :: + + #+kindex: C-c C-w + #+findex: org-refile + Refile entry or region to a different location. See [[*Refile and + Copy]]. + +- {{{kbd(C-c ^)}}} (~org-sort~) :: + + #+kindex: C-c ^ + #+findex: org-sort + Sort same-level entries. When there is an active region, all + entries in the region are sorted. Otherwise the children of the + current headline are sorted. The command prompts for the sorting + method, which can be alphabetically, numerically, by time---first + timestamp with active preferred, creation time, scheduled time, + deadline time---by priority, by TODO keyword---in the sequence the + keywords have been defined in the setup---or by the value of + a property. Reverse sorting is possible as well. You can also + supply your own function to extract the sorting key. With + a {{{kbd(C-u)}}} prefix, sorting is case-sensitive. + +- {{{kbd(C-x n s)}}} (~org-narrow-to-subtree~) :: + + #+kindex: C-x n s + #+findex: org-narrow-to-subtree + Narrow buffer to current subtree. + +- {{{kbd(C-x n b)}}} (~org-narrow-to-block~) :: + + #+kindex: C-x n b + #+findex: org-narrow-to-block + Narrow buffer to current block. + +- {{{kbd(C-x n w)}}} (~widen~) :: + + #+kindex: C-x n w + #+findex: widen + Widen buffer to remove narrowing. + +- {{{kbd(C-c *)}}} (~org-toggle-heading~) :: + + #+kindex: C-c * + #+findex: org-toggle-heading + Turn a normal line or plain list item into a headline---so that it + becomes a subheading at its location. Also turn a headline into + a normal line by removing the stars. If there is an active region, + turn all lines in the region into headlines. If the first line in + the region was an item, turn only the item lines into headlines. + Finally, if the first line is a headline, remove the stars from all + headlines in the region. + +Note that when point is inside a table (see [[*Tables]]), the Meta-Cursor +keys have different functionality. + +** Sparse Trees +:PROPERTIES: +:DESCRIPTION: Matches embedded in context. +:END: +#+cindex: sparse trees +#+cindex: trees, sparse +#+cindex: folding, sparse trees +#+cindex: occur, command + +#+vindex: org-show-context-detail +An important feature of Org mode is the ability to construct /sparse +trees/ for selected information in an outline tree, so that the entire +document is folded as much as possible, but the selected information +is made visible along with the headline structure above it[fn:7]. +Just try it out and you will see immediately how it works. + +Org mode contains several commands creating such trees, all these +commands can be accessed through a dispatcher: + +- {{{kbd(C-c /)}}} (~org-sparse-tree~) :: + + #+kindex: C-c / + #+findex: org-sparse-tree + This prompts for an extra key to select a sparse-tree creating + command. + +- {{{kbd(C-c / r)}}} or {{{kbd(C-c / /)}}} (~org-occur~) :: + + #+kindex: C-c / r + #+kindex: C-c / / + #+findex: org-occur + #+vindex: org-remove-highlights-with-change + Prompts for a regexp and shows a sparse tree with all matches. If + the match is in a headline, the headline is made visible. If the + match is in the body of an entry, headline and body are made + visible. In order to provide minimal context, also the full + hierarchy of headlines above the match is shown, as well as the + headline following the match. Each match is also highlighted; the + highlights disappear when the buffer is changed by an editing + command, or by pressing {{{kbd(C-c C-c)}}}[fn:8]. When called with + a {{{kbd(C-u)}}} prefix argument, previous highlights are kept, so + several calls to this command can be stacked. + +- {{{kbd(M-g n)}}} or {{{kbd(M-g M-n)}}} (~next-error~) :: + + #+kindex: M-g n + #+kindex: M-g M-n + #+findex: next-error + Jump to the next sparse tree match in this buffer. + +- {{{kbd(M-g p)}}} or {{{kbd(M-g M-p)}}} (~previous-error~) :: + + #+kindex: M-g p + #+kindex: M-g M-p + #+findex: previous-error + Jump to the previous sparse tree match in this buffer. + +#+vindex: org-agenda-custom-commands +For frequently used sparse trees of specific search strings, you can +use the variable ~org-agenda-custom-commands~ to define fast keyboard +access to specific sparse trees. These commands will then be +accessible through the agenda dispatcher (see [[*The Agenda Dispatcher]]). +For example: + +#+begin_src emacs-lisp +(setq org-agenda-custom-commands + '(("f" occur-tree "FIXME"))) +#+end_src + +#+texinfo: @noindent +defines the key {{{kbd(f)}}} as a shortcut for creating a sparse tree +matching the string =FIXME=. + +The other sparse tree commands select headings based on TODO keywords, +tags, or properties and are discussed later in this manual. + +#+kindex: C-c C-e C-v +#+cindex: printing sparse trees +#+cindex: visible text, printing +To print a sparse tree, you can use the Emacs command +~ps-print-buffer-with-faces~ which does not print invisible parts of +the document. Or you can use the command {{{kbd(C-c C-e C-v)}}} to +export only the visible part of the document and print the resulting +file. + +** Plain Lists +:PROPERTIES: +:DESCRIPTION: Additional structure within an entry. +:END: +#+cindex: plain lists +#+cindex: lists, plain +#+cindex: lists, ordered +#+cindex: ordered lists + +Within an entry of the outline tree, hand-formatted lists can provide +additional structure. They also provide a way to create lists of +checkboxes (see [[*Checkboxes]]). Org supports editing such lists, and +every exporter (see [[*Exporting]]) can parse and format them. + +Org knows ordered lists, unordered lists, and description lists. + +#+attr_texinfo: :indic @bullet +- /Unordered/ list items start with =-=, =+=, or =*=[fn:9] as bullets. + +- + #+vindex: org-plain-list-ordered-item-terminator + #+vindex: org-alphabetical-lists + /Ordered/ list items start with a numeral followed by either + a period or a right parenthesis[fn:10], such as =1.= or =1)=[fn:11] + If you want a list to start with a different value---e.g., + 20---start the text of the item with =[@20]=[fn:12]. Those + constructs can be used in any item of the list in order to enforce + a particular numbering. + +- /Description/ list items are unordered list items, and contain the + separator =::= to distinguish the description /term/ from the + description. + +Items belonging to the same list must have the same indentation on the +first line. In particular, if an ordered list reaches number =10.=, +then the 2-digit numbers must be written left-aligned with the other +numbers in the list. An item ends before the next line that is less +or equally indented than its bullet/number. + +A list ends whenever every item has ended, which means before any line +less or equally indented than items at top level. It also ends before +two blank lines. In that case, all items are closed. Here is an +example: + +#+begin_example +,* Lord of the Rings +My favorite scenes are (in this order) +1. The attack of the Rohirrim +2. Eowyn's fight with the witch king + + this was already my favorite scene in the book + + I really like Miranda Otto. +3. Peter Jackson being shot by Legolas + - on DVD only + He makes a really funny face when it happens. +But in the end, no individual scenes matter but the film as a whole. +Important actors in this film are: +- Elijah Wood :: He plays Frodo +- Sean Astin :: He plays Sam, Frodo's friend. I still remember him + very well from his role as Mikey Walsh in /The Goonies/. +#+end_example + +Org supports these lists by tuning filling and wrapping commands to +deal with them correctly, and by exporting them properly (see +[[*Exporting]]). Since indentation is what governs the structure of these +lists, many structural constructs like =#+BEGIN_= blocks can be +indented to signal that they belong to a particular item. + +#+vindex: org-list-demote-modify-bullet +#+vindex: org-list-indent-offset +If you find that using a different bullet for a sub-list---than that +used for the current list-level---improves readability, customize the +variable ~org-list-demote-modify-bullet~. To get a greater difference +of indentation between items and theirs sub-items, customize +~org-list-indent-offset~. + +#+vindex: org-list-automatic-rules +The following commands act on items when point is in the first line of +an item---the line with the bullet or number. Some of them imply the +application of automatic rules to keep list structure intact. If some +of these actions get in your way, configure ~org-list-automatic-rules~ +to disable them individually. + +#+attr_texinfo: :sep , +- {{{kbd(TAB)}}} (~org-cycle~) :: + + #+cindex: cycling, in plain lists + #+kindex: TAB + #+findex: org-cycle + #+vindex: org-cycle-include-plain-lists + Items can be folded just like headline levels. Normally this works + only if point is on a plain list item. For more details, see the + variable ~org-cycle-include-plain-lists~. If this variable is set + to ~integrate~, plain list items are treated like low-level + headlines. The level of an item is then given by the indentation of + the bullet/number. Items are always subordinate to real headlines, + however; the hierarchies remain completely separated. In a new item + with no text yet, the first {{{kbd(TAB)}}} demotes the item to + become a child of the previous one. Subsequent {{{kbd(TAB)}}}s move + the item to meaningful levels in the list and eventually get it back + to its initial position. + +- {{{kbd(M-RET)}}} (~org-insert-heading~) :: + + #+kindex: M-RET + #+findex: org-insert-heading + #+vindex: org-M-RET-may-split-line + Insert new item at current level. With a prefix argument, force + a new heading (see [[*Structure Editing]]). If this command is used in + the middle of an item, that item is /split/ in two, and the second + part becomes the new item[fn:13]. If this command is executed + /before item's body/, the new item is created /before/ the current + one. + +- {{{kbd(M-S-RET)}}} :: + + #+kindex: M-S-RET + Insert a new item with a checkbox (see [[*Checkboxes]]). + +- {{{kbd(S-UP)}}}, {{{kbd(S-DOWN)}}} :: + + #+kindex: S-UP + #+kindex: S-DOWN + #+cindex: shift-selection-mode + #+vindex: org-support-shift-select + #+vindex: org-list-use-circular-motion + Jump to the previous/next item in the current list, but only if + ~org-support-shift-select~ is off[fn:14]. If not, you can still use + paragraph jumping commands like {{{kbd(C-UP)}}} and + {{{kbd(C-DOWN)}}} to quite similar effect. + +- {{{kbd(M-UP)}}}, {{{kbd(M-DOWN)}}} :: + + #+kindex: M-UP + #+kindex: M-DOWN + Move the item including subitems up/down[fn:15], i.e., swap with + previous/next item of same indentation. If the list is ordered, + renumbering is automatic. + +- {{{kbd(M-LEFT)}}}, {{{kbd(M-RIGHT)}}} :: + + #+kindex: M-LEFT + #+kindex: M-RIGHT + Decrease/increase the indentation of an item, leaving children + alone. + +- {{{kbd(M-S-LEFT)}}}, {{{kbd(M-S-RIGHT)}}} :: + + #+kindex: M-S-LEFT + #+kindex: M-S-RIGHT + Decrease/increase the indentation of the item, including subitems. + Initially, the item tree is selected based on current indentation. + When these commands are executed several times in direct succession, + the initially selected region is used, even if the new indentation + would imply a different hierarchy. To use the new hierarchy, break + the command chain by moving point. + + As a special case, using this command on the very first item of + a list moves the whole list. This behavior can be disabled by + configuring ~org-list-automatic-rules~. The global indentation of + a list has no influence on the text /after/ the list. + +- {{{kbd(C-c C-c)}}} :: + + #+kindex: C-c C-c + If there is a checkbox (see [[*Checkboxes]]) in the item line, toggle + the state of the checkbox. In any case, verify bullets and + indentation consistency in the whole list. + +- {{{kbd(C-c -)}}} :: + + #+kindex: C-c - + #+vindex: org-plain-list-ordered-item-terminator + Cycle the entire list level through the different itemize/enumerate + bullets (=-=, =+=, =*=, =1.=, =1)=) or a subset of them, depending + on ~org-plain-list-ordered-item-terminator~, the type of list, and + its indentation. With a numeric prefix argument N, select the Nth + bullet from this list. If there is an active region when calling + this, all lines are converted to list items. With a prefix + argument, the selected text is changed into a single item. If the + first line already was a list item, any item marker is removed from + the list. Finally, even without an active region, a normal line is + converted into a list item. + +- {{{kbd(C-c *)}}} :: + + #+kindex: C-c * + Turn a plain list item into a headline---so that it becomes + a subheading at its location. See [[*Structure Editing]], for + a detailed explanation. + +- {{{kbd(C-c C-*)}}} :: + + #+kindex: C-c C-* + Turn the whole plain list into a subtree of the current heading. + Checkboxes (see [[*Checkboxes]]) become =TODO=, respectively =DONE=, + keywords when unchecked, respectively checked. + +- {{{kbd(S-LEFT)}}}, {{{kbd(S-RIGHT)}}} :: + + #+vindex: org-support-shift-select + #+kindex: S-LEFT + #+kindex: S-RIGHT + This command also cycles bullet styles when point is in on the + bullet or anywhere in an item line, details depending on + ~org-support-shift-select~. + +- {{{kbd(C-c ^)}}} :: + + #+kindex: C-c ^ + #+cindex: sorting, of plain list + Sort the plain list. Prompt for the sorting method: numerically, + alphabetically, by time, or by custom function. + +** Drawers +:PROPERTIES: +:DESCRIPTION: Tucking stuff away. +:END: +#+cindex: drawers +#+cindex: visibility cycling, drawers + +Sometimes you want to keep information associated with an entry, but +you normally do not want to see it. For this, Org mode has /drawers/. +They can contain anything but a headline and another drawer. Drawers +look like this: + +#+begin_example +,** This is a headline +Still outside the drawer +:DRAWERNAME: +This is inside the drawer. +:END: +After the drawer. +#+end_example + +#+kindex: C-c C-x d +#+findex: org-insert-drawer +You can interactively insert a drawer at point by calling +~org-insert-drawer~, which is bound to {{{kbd(C-c C-x d)}}}. With an +active region, this command puts the region inside the drawer. With +a prefix argument, this command calls ~org-insert-property-drawer~, +which creates a =PROPERTIES= drawer right below the current headline. +Org mode uses this special drawer for storing properties (see +[[*Properties and Columns]]). You cannot use it for anything else. + +Completion over drawer keywords is also possible using +{{{kbd(M-TAB)}}}[fn:16]. + +Visibility cycling (see [[*Visibility Cycling]]) on the headline hides and +shows the entry, but keep the drawer collapsed to a single line. In +order to look inside the drawer, you need to move point to the drawer +line and press {{{kbd(TAB)}}} there. + +You can also arrange for state change notes (see [[Tracking TODO state +changes]]) and clock times (see [[*Clocking Work Time]]) to be stored in +a =LOGBOOK= drawer. If you want to store a quick note there, in +a similar way to state changes, use + +- {{{kbd(C-c C-z)}}} :: + + #+kindex: C-c C-z + Add a time-stamped note to the =LOGBOOK= drawer. + +** Blocks +:PROPERTIES: +:DESCRIPTION: Folding blocks. +:END: +#+vindex: org-hide-block-startup +#+cindex: blocks, folding + +Org mode uses =#+BEGIN= ... =#+END= blocks for various purposes from +including source code examples (see [[*Literal Examples]]) to capturing +time logging information (see [[*Clocking Work Time]]). These blocks can +be folded and unfolded by pressing {{{kbd(TAB)}}} in the =#+BEGIN= +line. You can also get all blocks folded at startup by configuring +the variable ~org-hide-block-startup~ or on a per-file basis by using + +#+cindex: STARTUP, keyword +#+begin_example +,#+STARTUP: hideblocks +,#+STARTUP: nohideblocks +#+end_example + +* Tables +:PROPERTIES: +:DESCRIPTION: Pure magic for quick formatting. +:END: +#+cindex: tables +#+cindex: editing tables + +Org comes with a fast and intuitive table editor. Spreadsheet-like +calculations are supported using the Emacs Calc package (see [[info:calc][GNU Emacs +Calculator Manual]]). + +** Built-in Table Editor +:PROPERTIES: +:DESCRIPTION: Simple tables. +:END: +#+cindex: table editor, built-in + +#+cindex: header lines, in tables +#+cindex: horizontal rule, in tables +#+cindex: row separator, in tables +#+cindex: table syntax +Org makes it easy to format tables in plain ASCII. Any line with =|= +as the first non-whitespace character is considered part of a table. +=|= is also the column separator[fn:17]. Moreover, a line starting +with =|-= is a horizontal rule. It separates rows explicitly. Rows +before the first horizontal rule are header lines. A table might look +like this: + +#+begin_example +| Name | Phone | Age | +|-------+-------+-----| +| Peter | 1234 | 17 | +| Anna | 4321 | 25 | +#+end_example + +A table is re-aligned automatically each time you press +{{{kbd(TAB)}}}, {{{kbd(RET)}}} or {{{kbd(C-c C-c)}}} inside the table. +{{{kbd(TAB)}}} also moves to the next field---{{{kbd(RET)}}} to the +next row---and creates new table rows at the end of the table or +before horizontal lines. The indentation of the table is set by the +first line. Horizontal rules are automatically expanded on every +re-align to span the whole table width. So, to create the above +table, you would only type + +#+begin_example +|Name|Phone|Age| +|- +#+end_example + +#+texinfo: @noindent +and then press {{{kbd(TAB)}}} to align the table and start filling in +fields. Even faster would be to type =|Name|Phone|Age= followed by +{{{kbd(C-c RET)}}}. + +When typing text into a field, Org treats {{{kbd(DEL)}}}, +{{{kbd(Backspace)}}}, and all character keys in a special way, so that +inserting and deleting avoids shifting other fields. Also, when +typing /immediately/ after point was moved into a new field with +{{{kbd(TAB)}}}, {{{kbd(S-TAB)}}} or {{{kbd(RET)}}}, the field is +automatically made blank. If this behavior is too unpredictable for +you, configure the option ~org-table-auto-blank-field~. + +*** Creation and conversion +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +- {{{kbd(C-c |)}}} (~org-table-create-or-convert-from-region~) :: + + #+kindex: C-c | + #+findex: org-table-create-or-convert-from-region + Convert the active region to table. If every line contains at least + one {{{kbd(TAB)}}} character, the function assumes that the material + is tab separated. If every line contains a comma, comma-separated + values (CSV) are assumed. If not, lines are split at whitespace + into fields. You can use a prefix argument to force a specific + separator: {{{kbd(C-u)}}} forces CSV, {{{kbd(C-u C-u)}}} forces + {{{kbd(TAB)}}}, {{{kbd(C-u C-u C-u)}}} prompts for a regular + expression to match the separator, and a numeric argument + N indicates that at least N consecutive spaces, or alternatively + a {{{kbd(TAB)}}} will be the separator. + + If there is no active region, this command creates an empty Org + table. But it is easier just to start typing, like {{{kbd(| + N a m e | P h o n e | A g e RET | - TAB)}}}. + +*** Re-aligning and field motion +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +- {{{kbd(C-c C-c)}}} (~org-table-align~) :: + + #+kindex: C-c C-c + #+findex: org-table-align + Re-align the table without moving point. + +- {{{kbd(TAB)}}} (~org-table-next-field~) :: + + #+kindex: TAB + #+findex: org-table-next-field + Re-align the table, move to the next field. Creates a new row if + necessary. + +- {{{kbd(C-c SPC)}}} (~org-table-blank-field~) :: + + #+kindex: C-c SPC + #+findex: org-table-blank-field + Blank the field at point. + +- {{{kbd(S-TAB)}}} (~org-table-previous-field~) :: + + #+kindex: S-TAB + #+findex: org-table-previous-field + Re-align, move to previous field. + +- {{{kbd(RET)}}} (~org-table-next-row~) :: + + #+kindex: RET + #+findex: org-table-next-row + Re-align the table and move down to next row. Creates a new row if + necessary. At the beginning or end of a line, {{{kbd(RET)}}} still + inserts a new line, so it can be used to split a table. + +- {{{kbd(M-a)}}} (~org-table-beginning-of-field~) :: + + #+kindex: M-a + #+findex: org-table-beginning-of-field + Move to beginning of the current table field, or on to the previous + field. + +- {{{kbd(M-e)}}} (~org-table-end-of-field~) :: + + #+kindex: M-e + #+findex: org-table-end-of-field + Move to end of the current table field, or on to the next field. + +*** Column and row editing +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +- {{{kbd(M-LEFT)}}} (~org-table-move-column-left~) :: + + #+kindex: M-LEFT + #+findex: org-table-move-column-left + Move the current column left. + +- {{{kbd(M-RIGHT)}}} (~org-table-move-column-right~) :: + + #+kindex: M-RIGHT + #+findex: org-table-move-column-right + Move the current column right. + +- {{{kbd(M-S-LEFT)}}} (~org-table-delete-column~) :: + + #+kindex: M-S-LEFT + #+findex: org-table-delete-column + Kill the current column. + +- {{{kbd(M-S-RIGHT)}}} (~org-table-insert-column~) :: + + #+kindex: M-S-RIGHT + #+findex: org-table-insert-column + Insert a new column at point position. Move the recent column and + all cells to the right of this column to the right. + +- {{{kbd(M-UP)}}} (~org-table-move-row-up~) :: + + #+kindex: M-UP + #+findex: org-table-move-row-up + Move the current row up. + +- {{{kbd(M-DOWN)}}} (~org-table-move-row-down~) :: + + #+kindex: M-DOWN + #+findex: org-table-move-row-down + Move the current row down. + +- {{{kbd(M-S-UP)}}} (~org-table-kill-row~) :: + + #+kindex: M-S-UP + #+findex: org-table-kill-row + Kill the current row or horizontal line. + +- {{{kbd(S-UP)}}} (~org-table-move-cell-up~) :: + + #+kindex: S-UP + #+findex: org-table-move-cell-up + Move cell up by swapping with adjacent cell. + +- {{{kbd(S-DOWN)}}} (~org-table-move-cell-down~) :: + + #+kindex: S-DOWN + #+findex: org-table-move-cell-down + Move cell down by swapping with adjacent cell. + +- {{{kbd(S-LEFT)}}} (~org-table-move-cell-left~) :: + + #+kindex: S-LEFT + #+findex: org-table-move-cell-left + Move cell left by swapping with adjacent cell. + +- {{{kbd(S-RIGHT)}}} (~org-table-move-cell-right~) :: + + #+kindex: S-RIGHT + #+findex: org-table-move-cell-right + Move cell right by swapping with adjacent cell. + +- {{{kbd(M-S-DOWN)}}} (~org-table-insert-row~) :: + + #+kindex: M-S-DOWN + #+findex: org-table-insert-row + Insert a new row above the current row. With a prefix argument, the + line is created below the current one. + +- {{{kbd(C-c -)}}} (~org-table-insert-hline~) :: + + #+kindex: C-c - + #+findex: org-table-insert-hline + Insert a horizontal line below current row. With a prefix argument, + the line is created above the current line. + +- {{{kbd(C-c RET)}}} (~org-table-hline-and-move~) :: + + #+kindex: C-c RET + #+findex: org-table-hline-and-move + Insert a horizontal line below current row, and move point into the + row below that line. + +- {{{kbd(C-c ^)}}} (~org-table-sort-lines~) :: + + #+kindex: C-c ^ + #+findex: org-table-sort-lines + Sort the table lines in the region. The position of point indicates + the column to be used for sorting, and the range of lines is the + range between the nearest horizontal separator lines, or the entire + table. If point is before the first column, you are prompted for + the sorting column. If there is an active region, the mark + specifies the first line and the sorting column, while point should + be in the last line to be included into the sorting. The command + prompts for the sorting type, alphabetically, numerically, or by + time. You can sort in normal or reverse order. You can also supply + your own key extraction and comparison functions. When called with + a prefix argument, alphabetic sorting is case-sensitive. + +*** Regions +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +- {{{kbd(C-c C-x M-w)}}} (~org-table-copy-region~) :: + + #+kindex: C-c C-x M-w + #+findex: org-table-copy-region + Copy a rectangular region from a table to a special clipboard. + Point and mark determine edge fields of the rectangle. If there is + no active region, copy just the current field. The process ignores + horizontal separator lines. + +- {{{kbd(C-c C-x C-w)}}} (~org-table-cut-region~) :: + + #+kindex: C-c C-x C-w + #+findex: org-table-cut-region + Copy a rectangular region from a table to a special clipboard, and + blank all fields in the rectangle. So this is the "cut" operation. + +- {{{kbd(C-c C-x C-y)}}} (~org-table-paste-rectangle~) :: + + #+kindex: C-c C-x C-y + #+findex: org-table-paste-rectangle + Paste a rectangular region into a table. The upper left corner ends + up in the current field. All involved fields are overwritten. If + the rectangle does not fit into the present table, the table is + enlarged as needed. The process ignores horizontal separator lines. + +- {{{kbd(M-RET)}}} (~org-table-wrap-region~) :: + + #+kindex: M-RET + #+findex: org-table-wrap-region + Split the current field at point position and move the rest to the + line below. If there is an active region, and both point and mark + are in the same column, the text in the column is wrapped to minimum + width for the given number of lines. A numeric prefix argument may + be used to change the number of desired lines. If there is no + region, but you specify a prefix argument, the current field is made + blank, and the content is appended to the field above. + +*** Calculations +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: formula, in tables +#+cindex: calculations, in tables + +- {{{kbd(C-c +)}}} (~org-table-sum~) :: + + #+kindex: C-c + + #+findex: org-table-sum + Sum the numbers in the current column, or in the rectangle defined + by the active region. The result is shown in the echo area and can + be inserted with {{{kbd(C-y)}}}. + +- {{{kbd(S-RET)}}} (~org-table-copy-down~) :: + + #+kindex: S-RET + #+findex: org-table-copy-down + #+vindex: org-table-copy-increment + When current field is empty, copy from first non-empty field above. + When not empty, copy current field down to next row and move point + along with it. + + Depending on the variable ~org-table-copy-increment~, integer and + time stamp field values, and fields prefixed or suffixed with + a whole number, can be incremented during copy. Also, a ~0~ prefix + argument temporarily disables the increment. + + This key is also used by shift-selection and related modes (see + [[*Packages that conflict with Org mode]]). + +*** Miscellaneous +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +- {{{kbd(C-c `)}}} (~org-table-edit-field~) :: + + #+kindex: C-c ` + #+findex: org-table-edit-field + Edit the current field in a separate window. This is useful for + fields that are not fully visible (see [[*Column Width and Alignment]]). + When called with a {{{kbd(C-u)}}} prefix, just make the full field + visible, so that it can be edited in place. When called with two + {{{kbd(C-u)}}} prefixes, make the editor window follow point through + the table and always show the current field. The follow mode exits + automatically when point leaves the table, or when you repeat this + command with {{{kbd(C-u C-u C-c `)}}}. + +- {{{kbd(M-x org-table-import)}}} :: + + #+findex: org-table-import + Import a file as a table. The table should be TAB or whitespace + separated. Use, for example, to import a spreadsheet table or data + from a database, because these programs generally can write + TAB-separated text files. This command works by inserting the file + into the buffer and then converting the region to a table. Any + prefix argument is passed on to the converter, which uses it to + determine the separator. + +- {{{kbd(C-c |)}}} (~org-table-create-or-convert-from-region~) :: + + #+kindex: C-c | + #+findex: org-table-create-or-convert-from-region + Tables can also be imported by pasting tabular text into the Org + buffer, selecting the pasted text with {{{kbd(C-x C-x)}}} and then + using the {{{kbd(C-c |)}}} command (see [[*Creation and conversion]]). + +- {{{kbd(M-x org-table-export)}}} :: + + #+findex: org-table-export + #+vindex: org-table-export-default-format + Export the table, by default as a TAB-separated file. Use for data + exchange with, for example, spreadsheet or database programs. The + format used to export the file can be configured in the variable + ~org-table-export-default-format~. You may also use properties + =TABLE_EXPORT_FILE= and =TABLE_EXPORT_FORMAT= to specify the file + name and the format for table export in a subtree. Org supports + quite general formats for exported tables. The exporter format is + the same as the format used by Orgtbl radio tables, see [[*Translator + functions]], for a detailed description. + +- {{{kbd(M-x org-table-header-line-mode)}}} :: + + #+findex: org-table-header-line-mode + #+vindex: org-table-header-line-p + Turn on the display of the first data row of the table at point in + the window header line when this first row is not visible anymore in + the buffer. You can activate this minor mode by default by setting + the option ~org-table-header-line-p~ to ~t~. + +- {{{kbd(M-x org-table-transpose-table-at-point)}}} :: + + #+findex: org-table-transpose-table-at-point + Transpose the table at point and eliminate hlines. + +** Column Width and Alignment +:PROPERTIES: +:DESCRIPTION: Overrule the automatic settings. +:END: +#+cindex: narrow columns in tables +#+cindex: alignment in tables + +The width of columns is automatically determined by the table editor. +The alignment of a column is determined automatically from the +fraction of number-like versus non-number fields in the column. + +#+vindex: org-table-automatic-realign +Editing a field may modify alignment of the table. Moving +a contiguous row or column---i.e., using {{{kbd(TAB)}}} or +{{{kbd(RET)}}}---automatically re-aligns it. If you want to disable +this behavior, set ~org-table-automatic-realign~ to ~nil~. In any +case, you can always align manually a table: + +- {{{kbd(C-c C-c)}}} (~org-table-align~) :: + + #+kindex: C-c C-c + #+findex: org-table-align + Align the current table. + +#+vindex: org-startup-align-all-tables +Setting the option ~org-startup-align-all-tables~ re-aligns all tables +in a file upon visiting it. You can also set this option on +a per-file basis with: + +#+begin_example +,#+STARTUP: align +,#+STARTUP: noalign +#+end_example + +Sometimes a single field or a few fields need to carry more text, +leading to inconveniently wide columns. Maybe you want to hide away +several columns or display them with a fixed width, regardless of +content, as shown in the following example. + +#+begin_example +|---+---------------------+--------| |---+-------…+…| +| | <6> | | | | <6> …|…| +| 1 | one | some | ----\ | 1 | one …|…| +| 2 | two | boring | ----/ | 2 | two …|…| +| 3 | This is a long text | column | | 3 | This i…|…| +|---+---------------------+--------| |---+-------…+…| +#+end_example + +To set the width of a column, one field anywhere in the column may +contain just the string == where {{{var(N)}}} specifies the width +as a number of characters. You control displayed width of columns +with the following tools: + +- {{{kbd(C-c TAB)}}} (~org-table-toggle-column-width~) :: + + #+kindex: C-c TAB + #+findex: org-table-toggle-column-width + Shrink or expand current column. + + If a width cookie specifies a width W for the column, shrinking it + displays the first W visible characters only. Otherwise, the column + is shrunk to a single character. + + When called before the first column or after the last one, ask for + a list of column ranges to operate on. + +- {{{kbd(C-u C-c TAB)}}} (~org-table-shrink~) :: + + #+kindex: C-u C-c TAB + #+findex: org-table-shrink + Shrink all columns with a column width. Expand the others. + +- {{{kbd(C-u C-u C-c TAB)}}} (~org-table-expand~) :: + + #+kindex: C-u C-u C-c TAB + #+findex: org-table-expand + Expand all columns. + +To see the full text of a shrunk field, hold the mouse over it: +a tool-tip window then shows the full contents of the field. +Alternatively, {{{kbd(C-h .)}}} (~display-local-help~) reveals them, +too. For convenience, any change near the shrunk part of a column +expands it. + +#+vindex: org-startup-shrink-all-tables +Setting the option ~org-startup-shrink-all-tables~ shrinks all columns +containing a width cookie in a file the moment it is visited. You can +also set this option on a per-file basis with: + +: #+STARTUP: shrink + +If you would like to overrule the automatic alignment of number-rich +columns to the right and of string-rich columns to the left, you can +use ==, == or == in a similar fashion. You may also combine +alignment and field width like this: ==. + +Lines which only contain these formatting cookies are removed +automatically upon exporting the document. + +** Column Groups +:PROPERTIES: +:DESCRIPTION: Grouping to trigger vertical lines. +:END: +#+cindex: grouping columns in tables + +When Org exports tables, it does so by default without vertical lines +because that is visually more satisfying in general. Occasionally +however, vertical lines can be useful to structure a table into groups +of columns, much like horizontal lines can do for groups of rows. In +order to specify column groups, you can use a special row where the +first field contains only =/=. The further fields can either contain +=<= to indicate that this column should start a group, =>= to indicate +the end of a column, or =<>= (no space between =<= and =>=) to make +a column a group of its own. Upon export, boundaries between column +groups are marked with vertical lines. Here is an example: + +#+begin_example +| N | N^2 | N^3 | N^4 | sqrt(n) | sqrt[4](N) | +|---+-----+-----+-----+---------+------------| +| / | < | | > | < | > | +| 1 | 1 | 1 | 1 | 1 | 1 | +| 2 | 4 | 8 | 16 | 1.4142 | 1.1892 | +| 3 | 9 | 27 | 81 | 1.7321 | 1.3161 | +|---+-----+-----+-----+---------+------------| +,#+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1)::$6=sqrt(sqrt(($1))) +#+end_example + +It is also sufficient to just insert the column group starters after +every vertical line you would like to have: + +#+begin_example +| N | N^2 | N^3 | N^4 | sqrt(n) | sqrt[4](N) | +|---+-----+-----+-----+---------+------------| +| / | < | | | < | | +#+end_example + +** The Orgtbl Minor Mode +:PROPERTIES: +:DESCRIPTION: The table editor as minor mode. +:ALT_TITLE: Orgtbl Mode +:END: +#+cindex: Orgtbl mode +#+cindex: minor mode for tables + +#+findex: orgtbl-mode +If you like the intuitive way the Org table editor works, you might +also want to use it in other modes like Text mode or Mail mode. The +minor mode Orgtbl mode makes this possible. You can always toggle the +mode with {{{kbd(M-x orgtbl-mode)}}}. To turn it on by default, for +example in Message mode, use + +#+begin_src emacs-lisp +(add-hook 'message-mode-hook 'turn-on-orgtbl) +#+end_src + +Furthermore, with some special setup, it is possible to maintain +tables in arbitrary syntax with Orgtbl mode. For example, it is +possible to construct LaTeX tables with the underlying ease and power +of Orgtbl mode, including spreadsheet capabilities. For details, see +[[*Tables in Arbitrary Syntax]]. + +** The Spreadsheet +:PROPERTIES: +:DESCRIPTION: The table editor has spreadsheet capabilities. +:END: +#+cindex: calculations, in tables +#+cindex: spreadsheet capabilities +#+cindex: Calc package + +The table editor makes use of the Emacs Calc package to implement +spreadsheet-like capabilities. It can also evaluate Emacs Lisp forms +to derive fields from other fields. While fully featured, Org's +implementation is not identical to other spreadsheets. For example, +Org knows the concept of a /column formula/ that will be applied to +all non-header fields in a column without having to copy the formula +to each relevant field. There is also a formula debugger, and a +formula editor with features for highlighting fields in the table +corresponding to the references at point in the formula, moving these +references by arrow keys. + +*** References +:PROPERTIES: +:DESCRIPTION: How to refer to another field or range. +:END: +#+cindex: references + +To compute fields in the table from other fields, formulas must +reference other fields or ranges. In Org, fields can be referenced by +name, by absolute coordinates, and by relative coordinates. To find +out what the coordinates of a field are, press {{{kbd(C-c ?)}}} in +that field, or press {{{kbd(C-c })}}} to toggle the display of a grid. + +**** Field references +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: field references +#+cindex: references, to fields +Formulas can reference the value of another field in two ways. Like +in any other spreadsheet, you may reference fields with +a letter/number combination like =B3=, meaning the second field in the +third row. However, Org prefers to use another, more general +representation that looks like this:[fn:18] + +: @ROW$COLUMN + +Column specifications can be absolute like =$1=, =$2=, ..., =$N=, or +relative to the current column, i.e., the column of the field which is +being computed, like =$+1= or =$-2=. =$<= and =$>= are immutable +references to the first and last column, respectively, and you can use +=$>>>= to indicate the third column from the right. + +The row specification only counts data lines and ignores horizontal +separator lines, or "hlines". Like with columns, you can use absolute +row numbers =@1=, =@2=, ..., =@N=, and row numbers relative to the +current row like =@+3= or =@-1=. =@<= and =@>= are immutable +references the first and last row in the table, respectively. You may +also specify the row relative to one of the hlines: =@I= refers to the +first hline, =@II= to the second, etc. =@-I= refers to the first such +line above the current line, =@+I= to the first such line below the +current line. You can also write =@III+2= which is the second data +line after the third hline in the table. + +=@0= and =$0= refer to the current row and column, respectively, i.e., +to the row/column for the field being computed. Also, if you omit +either the column or the row part of the reference, the current +row/column is implied. + +Org's references with /unsigned/ numbers are fixed references in the +sense that if you use the same reference in the formula for two +different fields, the same field is referenced each time. Org's +references with /signed/ numbers are floating references because the +same reference operator can reference different fields depending on +the field being calculated by the formula. + +Here are a few examples: + +#+attr_texinfo: :columns 0.2 0.8 +| =@2$3= | 2nd row, 3rd column (same as =C2=) | +| =$5= | column 5 in the current row (same as =E&=) | +| =@2= | current column, row 2 | +| =@-1$-3= | field one row up, three columns to the left | +| =@-I$2= | field just under hline above current row, column 2 | +| =@>$5= | field in the last row, in column 5 | + +**** Range references +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: range references +#+cindex: references, to ranges +You may reference a rectangular range of fields by specifying two +field references connected by two dots =..=. The ends are included in +the range. If both fields are in the current row, you may simply use +=$2..$7=, but if at least one field is in a different row, you need to +use the general =@ROW$COLUMN= format at least for the first field, +i.e., the reference must start with =@= in order to be interpreted +correctly. Examples: + +#+attr_texinfo: :columns 0.2 0.8 +| =$1..$3= | first three fields in the current row | +| =$P..$Q= | range, using column names (see [[*Advanced features]]) | +| =$<<<..$>>= | start in third column, continue to the last but one | +| =@2$1..@4$3= | nine fields between these two fields (same as =A2..C4=) | +| =@-1$-2..@-1= | 3 fields in the row above, starting from 2 columns on the left | +| =@I..II= | between first and second hline, short for =@I..@II= | + +#+texinfo: @noindent +Range references return a vector of values that can be fed into Calc +vector functions. Empty fields in ranges are normally suppressed, so +that the vector contains only the non-empty fields. For other options +with the mode switches =E=, =N= and examples, see [[*Formula syntax for +Calc]]. + +**** Field coordinates in formulas +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: field coordinates +#+cindex: coordinates, of field +#+cindex: row, of field coordinates +#+cindex: column, of field coordinates +#+vindex: org-table-current-column +#+vindex: org-table-current-dline +One of the very first actions during evaluation of Calc formulas and +Lisp formulas is to substitute =@#= and =$#= in the formula with the +row or column number of the field where the current result will go to. +The traditional Lisp formula equivalents are ~org-table-current-dline~ +and ~org-table-current-column~. Examples: + +- =if(@# % 2, $#, string(""))= :: + + Insert column number on odd rows, set field to empty on even rows. + +- =$2 = '(identity remote(FOO, @@#$1))= :: + + Copy text or values of each row of column 1 of the table named + {{{var(FOO)}}} into column 2 of the current table. + +- =@3 = 2 * remote(FOO, @1$$#)= :: + + Insert the doubled value of each column of row 1 of the table + named {{{var(FOO)}}} into row 3 of the current table. + +#+texinfo: @noindent +For the second and third examples, table {{{var(FOO)}}} must have at +least as many rows or columns as the current table. Note that this is +inefficient[fn:19] for large number of rows. + +**** Named references +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: named references +#+cindex: references, named +#+cindex: name, of column or field +#+cindex: constants, in calculations +#+cindex: @samp{CONSTANTS}, keyword +#+vindex: org-table-formula-constants + +=$name= is interpreted as the name of a column, parameter or constant. +Constants are defined globally through the variable +~org-table-formula-constants~, and locally---for the file---through +a line like this example: + +: #+CONSTANTS: c=299792458. pi=3.14 eps=2.4e-6 + +#+vindex: constants-unit-system +#+pindex: constants.el +Also, properties (see [[*Properties and Columns]]) can be used as +constants in table formulas: for a property =Xyz= use the name +=$PROP_Xyz=, and the property will be searched in the current outline +entry and in the hierarchy above it. If you have the =constants.el= +package, it will also be used to resolve constants, including natural +constants like =$h= for Planck's constant, and units like =$km= for +kilometers[fn:20]. Column names and parameters can be specified in +special table lines. These are described below, see [[*Advanced +features]]. All names must start with a letter, and further consist +of letters and numbers. + +**** Remote references +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: remote references +#+cindex: references, remote +#+cindex: references, to a different table +#+cindex: name, of column or field +#+cindex: @samp{NAME}, keyword +You may also reference constants, fields and ranges from a different +table, either in the current file or even in a different file. The +syntax is + +: remote(NAME,REF) + +#+texinfo: @noindent +where {{{var(NAME)}}} can be the name of a table in the current file +as set by a =#+NAME:= line before the table. It can also be the ID of +an entry, even in a different file, and the reference then refers to +the first table in that entry. {{{var(REF)}}} is an absolute field or +range reference as described above for example =@3$3= or =$somename=, +valid in the referenced table. + +#+cindex: table indirection +When {{{var(NAME)}}} has the format =@ROW$COLUMN=, it is substituted +with the name or ID found in this field of the current table. For +example =remote($1, @@>$2)= \Rightarrow =remote(year_2013, @@>$1)=. The format +=B3= is not supported because it can not be distinguished from a plain +table name or ID. + +*** Formula syntax for Calc +:PROPERTIES: +:DESCRIPTION: Using Calc to compute stuff. +:END: +#+cindex: formula syntax, Calc +#+cindex: syntax, of formulas + +A formula can be any algebraic expression understood by the Emacs Calc +package. Note that Calc has the non-standard convention that =/= has +lower precedence than =*=, so that =a/b*c= is interpreted as +=(a/(b*c))=. Before evaluation by ~calc-eval~ (see [[info:calc#Calling Calc from Your Programs][Calling Calc from +Your Lisp Programs]]), variable substitution takes place according to +the rules described above. + +#+cindex: vectors, in table calculations +The range vectors can be directly fed into the Calc vector functions +like ~vmean~ and ~vsum~. + +#+cindex: format specifier, in spreadsheet +#+cindex: mode, for Calc +#+vindex: org-calc-default-modes +A formula can contain an optional mode string after a semicolon. This +string consists of flags to influence Calc and other modes during +execution. By default, Org uses the standard Calc modes (precision +12, angular units degrees, fraction and symbolic modes off). The +display format, however, has been changed to =(float 8)= to keep +tables compact. The default settings can be configured using the +variable ~org-calc-default-modes~. + +- =p20= :: + + Set the internal Calc calculation precision to 20 digits. + +- =n3=, =s3=, =e2=, =f4= :: + + Normal, scientific, engineering or fixed format of the result of + Calc passed back to Org. Calc formatting is unlimited in precision + as long as the Calc calculation precision is greater. + +- =D=, =R= :: + + Degree and radian angle modes of Calc. + +- =F=, =S= :: + + Fraction and symbolic modes of Calc. + +- =T=, =t=, =U= :: + + Duration computations in Calc or Lisp, [[*Durations and time values]]. + +- =E= :: + + If and how to consider empty fields. Without =E= empty fields in + range references are suppressed so that the Calc vector or Lisp list + contains only the non-empty fields. With =E= the empty fields are + kept. For empty fields in ranges or empty field references the + value =nan= (not a number) is used in Calc formulas and the empty + string is used for Lisp formulas. Add =N= to use 0 instead for both + formula types. For the value of a field the mode =N= has higher + precedence than =E=. + +- =N= :: + + Interpret all fields as numbers, use 0 for non-numbers. See the + next section to see how this is essential for computations with Lisp + formulas. In Calc formulas it is used only occasionally because + there number strings are already interpreted as numbers without =N=. + +- =L= :: + + Literal, for Lisp formulas only. See the next section. + +Unless you use large integer numbers or high-precision calculation and +display for floating point numbers you may alternatively provide +a ~printf~ format specifier to reformat the Calc result after it has +been passed back to Org instead of letting Calc already do the +formatting[fn:21]. A few examples: + +| =$1+$2= | Sum of first and second field | +| =$1+$2;%.2f= | Same, format result to two decimals | +| =exp($2)+exp($1)= | Math functions can be used | +| =$0;%.1f= | Reformat current cell to 1 decimal | +| =($3-32)*5/9= | Degrees F \to C conversion | +| =$c/$1/$cm= | Hz \to cm conversion, using =constants.el= | +| =tan($1);Dp3s1= | Compute in degrees, precision 3, display SCI 1 | +| =sin($1);Dp3%.1e= | Same, but use ~printf~ specifier for display | +| =vmean($2..$7)= | Compute column range mean, using vector function | +| =vmean($2..$7);EN= | Same, but treat empty fields as 0 | +| =taylor($3,x=7,2)= | Taylor series of $3, at x=7, second degree | + +Calc also contains a complete set of logical operations (see [[info:calc#Logical Operations][Logical +Operations]]). For example + +- =if($1 < 20, teen, string(""))= :: + + ="teen"= if age =$1= is less than 20, else the Org table result + field is set to empty with the empty string. + +- =if("$1" =​= "nan" || "$2" =​= "nan", string(""), $1 + $2); E f-1= :: + + Sum of the first two columns. When at least one of the input fields + is empty the Org table result field is set to empty. =E= is + required to not convert empty fields to 0. =f-1= is an optional + Calc format string similar to =%.1f= but leaves empty results empty. + +- =if(typeof(vmean($1..$7)) =​= 12, string(""), vmean($1..$7); E= :: + + Mean value of a range unless there is any empty field. Every field + in the range that is empty is replaced by =nan= which lets =vmean= + result in =nan=. Then =typeof == 12= detects the =nan= from ~vmean~ + and the Org table result field is set to empty. Use this when the + sample set is expected to never have missing values. + +- =if("$1..$7" =​= "[]", string(""), vmean($1..$7))= :: + + Mean value of a range with empty fields skipped. Every field in the + range that is empty is skipped. When all fields in the range are + empty the mean value is not defined and the Org table result field + is set to empty. Use this when the sample set can have a variable + size. + +- =vmean($1..$7); EN= :: + + To complete the example before: Mean value of a range with empty + fields counting as samples with value 0. Use this only when + incomplete sample sets should be padded with 0 to the full size. + +You can add your own Calc functions defined in Emacs Lisp with +~defmath~ and use them in formula syntax for Calc. + +*** Emacs Lisp forms as formulas +:PROPERTIES: +:DESCRIPTION: Writing formulas in Emacs Lisp. +:ALT_TITLE: Formula syntax for Lisp +:END: +#+cindex: Lisp forms, as table formulas + +It is also possible to write a formula in Emacs Lisp. This can be +useful for string manipulation and control structures, if Calc's +functionality is not enough. + +If a formula starts with a single-quote followed by an opening +parenthesis, then it is evaluated as a Lisp form. The evaluation +should return either a string or a number. Just as with Calc +formulas, you can specify modes and a ~printf~ format after +a semicolon. + +With Emacs Lisp forms, you need to be conscious about the way field +references are interpolated into the form. By default, a reference is +interpolated as a Lisp string (in double-quotes) containing the field. +If you provide the =N= mode switch, all referenced elements are +numbers---non-number fields will be zero---and interpolated as Lisp +numbers, without quotes. If you provide the =L= flag, all fields are +interpolated literally, without quotes. For example, if you want a +reference to be interpreted as a string by the Lisp form, enclose the +reference operator itself in double-quotes, like ="$3"=. Ranges are +inserted as space-separated fields, so you can embed them in list or +vector syntax. + +Here are a few examples---note how the =N= mode is used when we do +computations in Lisp: + +- ='(concat (substring $1 1 2) (substring $1 0 1) (substring $1 2))= :: + + Swap the first two characters of the content of column 1. + +- ='(+ $1 $2);N= :: + + Add columns 1 and 2, equivalent to Calc's =$1+$2=. + +- ='(apply '+ '($1..$4));N= :: + + Compute the sum of columns 1 to 4, like Calc's =vsum($1..$4)=. + +*** Durations and time values +:PROPERTIES: +:DESCRIPTION: How to compute durations and time values. +:END: +#+cindex: duration, computing +#+cindex: time, computing +#+vindex: org-table-duration-custom-format + +If you want to compute time values use the =T=, =t=, or =U= flag, +either in Calc formulas or Elisp formulas: + +#+begin_example +| Task 1 | Task 2 | Total | +|---------+----------+----------| +| 2:12 | 1:47 | 03:59:00 | +| 2:12 | 1:47 | 03:59 | +| 3:02:20 | -2:07:00 | 0.92 | +,#+TBLFM: @2$3=$1+$2;T::@3$3=$1+$2;U::@4$3=$1+$2;t +#+end_example + +Input duration values must be of the form =HH:MM[:SS]=, where seconds +are optional. With the =T= flag, computed durations are displayed as +=HH:MM:SS= (see the first formula above). With the =U= flag, seconds +are omitted so that the result is only =HH:MM= (see second formula +above). Zero-padding of the hours field depends upon the value of the +variable ~org-table-duration-hour-zero-padding~. + +With the =t= flag, computed durations are displayed according to the +value of the option ~org-table-duration-custom-format~, which defaults +to ~hours~ and displays the result as a fraction of hours (see the +third formula in the example above). + +Negative duration values can be manipulated as well, and integers are +considered as seconds in addition and subtraction. + +*** Field and range formulas +:PROPERTIES: +:DESCRIPTION: Formula for specific (ranges of) fields. +:END: +#+cindex: field formula +#+cindex: range formula +#+cindex: formula, for individual table field +#+cindex: formula, for range of fields + +To assign a formula to a particular field, type it directly into the +field, preceded by =:==, for example =vsum(@II..III)=. When you press +{{{kbd(TAB)}}} or {{{kbd(RET)}}} or {{{kbd(C-c C-c)}}} with point +still in the field, the formula is stored as the formula for this +field, evaluated, and the current field is replaced with the result. + +#+cindex: @samp{TBLFM}, keyword +Formulas are stored in a special =TBLFM= keyword located directly +below the table. If you type the equation in the fourth field of the +third data line in the table, the formula looks like =@3$4=$1+$2=. +When inserting/deleting/swapping column and rows with the appropriate +commands, /absolute references/ (but not relative ones) in stored +formulas are modified in order to still reference the same field. To +avoid this from happening, in particular in range references, anchor +ranges at the table borders (using =@<=, =@>=, =$<=, =$>=), or at +hlines using the =@I= notation. Automatic adaptation of field +references does not happen if you edit the table structure with normal +editing commands---you must fix the formulas yourself. + +Instead of typing an equation into the field, you may also use the +following command + +- {{{kbd(C-u C-c =)}}} (~org-table-eval-formula~) :: + + #+kindex: C-u C-c = + #+findex: org-table-eval-formula + Install a new formula for the current field. The command prompts + for a formula with default taken from the =TBLFM= keyword, + applies it to the current field, and stores it. + +The left-hand side of a formula can also be a special expression in +order to assign the formula to a number of different fields. There is +no keyboard shortcut to enter such range formulas. To add them, use +the formula editor (see [[*Editing and debugging formulas]]) or edit +the =TBLFM= keyword directly. + +- =$2== :: + + Column formula, valid for the entire column. This is so common that + Org treats these formulas in a special way, see [[*Column formulas]]. + +- =@3== :: + + Row formula, applies to all fields in the specified row. =@>== + means the last row. + +- =@1$2..@4$3== :: + + Range formula, applies to all fields in the given rectangular range. + This can also be used to assign a formula to some but not all fields + in a row. + +- =$NAME== :: + + Named field, see [[*Advanced features]]. + +*** Column formulas +:PROPERTIES: +:DESCRIPTION: Formulas valid for an entire column. +:END: +#+cindex: column formula +#+cindex: formula, for table column + +When you assign a formula to a simple column reference like =$3==, the +same formula is used in all fields of that column, with the following +very convenient exceptions: (i) If the table contains horizontal +separator hlines with rows above and below, everything before the +first such hline is considered part of the table /header/ and is not +modified by column formulas. Therefore a header is mandatory when you +use column formulas and want to add hlines to group rows, like for +example to separate a total row at the bottom from the summand rows +above. (ii) Fields that already get a value from a field/range +formula are left alone by column formulas. These conditions make +column formulas very easy to use. + +To assign a formula to a column, type it directly into any field in +the column, preceded by an equal sign, like ==$1+$2=. When you press +{{{kbd(TAB)}}} or {{{kbd(RET)}}} or {{{kbd(C-c C-c)}}} with point +still in the field, the formula is stored as the formula for the +current column, evaluated and the current field replaced with the +result. If the field contains only ===, the previously stored formula +for this column is used. For each column, Org only remembers the most +recently used formula. In the =TBLFM= keyword, column formulas look +like =$4=$1+$2=. The left-hand side of a column formula can not be +the name of column, it must be the numeric column reference or =$>=. + +Instead of typing an equation into the field, you may also use the +following command: + +- {{{kbd(C-c =)}}} (~org-table-eval-formula~) :: + + #+kindex: C-c = + #+findex: org-table-eval-formula + Install a new formula for the current column and replace current + field with the result of the formula. The command prompts for + a formula, with default taken from the =TBLFM= keyword, applies it + to the current field and stores it. With a numeric prefix argument, + e.g., {{{kbd(C-5 C-c =)}}}, the command applies it to that many + consecutive fields in the current column. + +*** Lookup functions +:PROPERTIES: +:DESCRIPTION: Lookup functions for searching tables. +:END: +#+cindex: lookup functions in tables +#+cindex: table lookup functions + +Org has three predefined Emacs Lisp functions for lookups in tables. + +- =(org-lookup-first VAL S-LIST R-LIST &optional PREDICATE)= :: + + #+findex: org-lookup-first + Searches for the first element {{{var(S)}}} in list + {{{var(S-LIST)}}} for which + #+begin_src emacs-lisp + (PREDICATE VAL S) + #+end_src + is non-~nil~; returns the value from the corresponding position in + list {{{var(R-LIST)}}}. The default {{{var(PREDICATE)}}} is + ~equal~. Note that the parameters {{{var(VAL)}}} and {{{var(S)}}} + are passed to {{{var(PREDICATE)}}} in the same order as the + corresponding parameters are in the call to ~org-lookup-first~, + where {{{var(VAL)}}} precedes {{{var(S-LIST)}}}. If + {{{var(R-LIST)}}} is ~nil~, the matching element {{{var(S)}}} of + {{{var(S-LIST)}}} is returned. + +- =(org-lookup-last VAL S-LIST R-LIST &optional PREDICATE)= :: + + #+findex: org-lookup-last + Similar to ~org-lookup-first~ above, but searches for the /last/ + element for which {{{var(PREDICATE)}}} is non-~nil~. + +- =(org-lookup-all VAL S-LIST R-LIST &optional PREDICATE)= :: + + #+findex: org-lookup-all + Similar to ~org-lookup-first~, but searches for /all/ elements for + which {{{var(PREDICATE)}}} is non-~nil~, and returns /all/ + corresponding values. This function can not be used by itself in + a formula, because it returns a list of values. However, powerful + lookups can be built when this function is combined with other Emacs + Lisp functions. + +If the ranges used in these functions contain empty fields, the =E= +mode for the formula should usually be specified: otherwise empty +fields are not included in {{{var(S-LIST)}}} and/or {{{var(R-LIST)}}} +which can, for example, result in an incorrect mapping from an element +of {{{var(S-LIST)}}} to the corresponding element of +{{{var(R-LIST)}}}. + +These three functions can be used to implement associative arrays, +count matching cells, rank results, group data, etc. For practical +examples see [[https://orgmode.org/worg/org-tutorials/org-lookups.html][this tutorial on Worg]]. + +*** Editing and debugging formulas +:PROPERTIES: +:DESCRIPTION: Fixing formulas. +:END: +#+cindex: formula editing +#+cindex: editing, of table formulas + +#+vindex: org-table-use-standard-references +You can edit individual formulas in the minibuffer or directly in the +field. Org can also prepare a special buffer with all active formulas +of a table. When offering a formula for editing, Org converts +references to the standard format (like =B3= or =D&=) if possible. If +you prefer to only work with the internal format (like =@3$2= or +=$4=), configure the variable ~org-table-use-standard-references~. + +- {{{kbd(C-c =)}}} or {{{kbd(C-u C-c =)}}} (~org-table-eval-formula~) :: + + #+kindex: C-c = + #+kindex: C-u C-c = + #+findex: org-table-eval-formula + Edit the formula associated with the current column/field in the + minibuffer. See [[*Column formulas]], and [[*Field and range formulas]]. + +- {{{kbd(C-u C-u C-c =)}}} (~org-table-eval-formula~) :: + + #+kindex: C-u C-u C-c = + #+findex: org-table-eval-formula + Re-insert the active formula (either a field formula, or a column + formula) into the current field, so that you can edit it directly in + the field. The advantage over editing in the minibuffer is that you + can use the command {{{kbd(C-c ?)}}}. + +- {{{kbd(C-c ?)}}} (~org-table-field-info~) :: + + #+kindex: C-c ? + #+findex: org-table-field-info + While editing a formula in a table field, highlight the field(s) + referenced by the reference at point position in the formula. + +- {{{kbd(C-c })}}} (~org-table-toggle-coordinate-overlays~) :: + + #+kindex: C-c @} + #+findex: org-table-toggle-coordinate-overlays + Toggle the display of row and column numbers for a table, using + overlays. These are updated each time the table is aligned; you can + force it with {{{kbd(C-c C-c)}}}. + +- {{{kbd(C-c {)}}} (~org-table-toggle-formula-debugger~) :: + + #+kindex: C-c @{ + #+findex: org-table-toggle-formula-debugger + Toggle the formula debugger on and off. See below. + +- {{{kbd(C-c ')}}} (~org-table-edit-formulas~) :: + + #+kindex: C-c ' + #+findex: org-table-edit-formulas + Edit all formulas for the current table in a special buffer, where + the formulas are displayed one per line. If the current field has + an active formula, point in the formula editor marks it. While + inside the special buffer, Org automatically highlights any field or + range reference at point position. You may edit, remove and add + formulas, and use the following commands: + + - {{{kbd(C-c C-c)}}} or {{{kbd(C-x C-s)}}} (~org-table-fedit-finish~) :: + + #+kindex: C-x C-s + #+kindex: C-c C-c + #+findex: org-table-fedit-finish + Exit the formula editor and store the modified formulas. With + {{{kbd(C-u)}}} prefix, also apply the new formulas to the + entire table. + + - {{{kbd(C-c C-q)}}} (~org-table-fedit-abort~) :: + + #+kindex: C-c C-q + #+findex: org-table-fedit-abort + Exit the formula editor without installing changes. + + - {{{kbd(C-c C-r)}}} (~org-table-fedit-toggle-ref-type~) :: + + #+kindex: C-c C-r + #+findex: org-table-fedit-toggle-ref-type + Toggle all references in the formula editor between standard (like + =B3=) and internal (like =@3$2=). + + - {{{kbd(TAB)}}} (~org-table-fedit-lisp-indent~) :: + + #+kindex: TAB + #+findex: org-table-fedit-lisp-indent + Pretty-print or indent Lisp formula at point. When in a line + containing a Lisp formula, format the formula according to Emacs + Lisp rules. Another {{{kbd(TAB)}}} collapses the formula back + again. In the open formula, {{{kbd(TAB)}}} re-indents just like + in Emacs Lisp mode. + + - {{{kbd(M-TAB)}}} (~lisp-complete-symbol~) :: + + #+kindex: M-TAB + #+findex: lisp-complete-symbol + Complete Lisp symbols, just like in Emacs Lisp mode. + + - {{{kbd(S-UP)}}}, {{{kbd(S-DOWN)}}}, {{{kbd(S-LEFT)}}}, {{{kbd(S-RIGHT)}}} :: + + #+kindex: S-UP + #+kindex: S-DOWN + #+kindex: S-LEFT + #+kindex: S-RIGHT + #+findex: org-table-fedit-ref-up + #+findex: org-table-fedit-ref-down + #+findex: org-table-fedit-ref-left + #+findex: org-table-fedit-ref-right + Shift the reference at point. For example, if the reference is + =B3= and you press {{{kbd(S-RIGHT)}}}, it becomes =C3=. This also + works for relative references and for hline references. + + - {{{kbd(M-S-UP)}}} (~org-table-fedit-line-up~) :: + + #+kindex: M-S-UP + #+findex: org-table-fedit-line-up + Move the test line for column formulas up in the Org buffer. + + - {{{kbd(M-S-DOWN)}}} (~org-table-fedit-line-down~) :: + + #+kindex: M-S-DOWN + #+findex: org-table-fedit-line-down + Move the test line for column formulas down in the Org buffer. + + - {{{kbd(M-UP)}}} (~org-table-fedit-scroll-up~) :: + + #+kindex: M-UP + #+findex: org-table-fedit-scroll-up + Scroll up the window displaying the table. + + - {{{kbd(M-DOWN)}}} (~org-table-fedit-scroll-down~) :: + + #+kindex: M-DOWN + #+findex: org-table-fedit-scroll-down + Scroll down the window displaying the table. + + - {{{kbd(C-c })}}} :: + + #+kindex: C-c @} + #+findex: org-table-toggle-coordinate-overlays + Turn the coordinate grid in the table on and off. + +Making a table field blank does not remove the formula associated with +the field, because that is stored in a different line---the =TBLFM= +keyword line. During the next recalculation, the field will be filled +again. To remove a formula from a field, you have to give an empty +reply when prompted for the formula, or to edit the =TBLFM= keyword. + +#+kindex: C-c C-c +You may edit the =TBLFM= keyword directly and re-apply the changed +equations with {{{kbd(C-c C-c)}}} in that line or with the normal +recalculation commands in the table. + +**** Using multiple =TBLFM= lines +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: multiple formula lines +#+cindex: @samp{TBLFM} keywords, multiple +#+cindex: @samp{TBLFM}, switching + +#+kindex: C-c C-c +You may apply the formula temporarily. This is useful when you want +to switch the formula applied to the table. Place multiple =TBLFM= +keywords right after the table, and then press {{{kbd(C-c C-c)}}} on +the formula to apply. Here is an example: + +#+begin_example +| x | y | +|---+---| +| 1 | | +| 2 | | +,#+TBLFM: $2=$1*1 +,#+TBLFM: $2=$1*2 +#+end_example + +#+texinfo: @noindent +Pressing {{{kbd(C-c C-c)}}} in the line of =#+TBLFM: $2=$1*2= yields: + +#+begin_example +| x | y | +|---+---| +| 1 | 2 | +| 2 | 4 | +,#+TBLFM: $2=$1*1 +,#+TBLFM: $2=$1*2 +#+end_example + +#+texinfo: @noindent +If you recalculate this table, with {{{kbd(C-u C-c *)}}}, for example, +you get the following result from applying only the first =TBLFM= +keyword. + +#+begin_example +| x | y | +|---+---| +| 1 | 1 | +| 2 | 2 | +,#+TBLFM: $2=$1*1 +,#+TBLFM: $2=$1*2 +#+end_example + +**** Debugging formulas +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: formula debugging +#+cindex: debugging, of table formulas + +When the evaluation of a formula leads to an error, the field content +becomes the string =#ERROR=. If you would like to see what is going +on during variable substitution and calculation in order to find +a bug, turn on formula debugging in the Tbl menu and repeat the +calculation, for example by pressing {{{kbd(C-u C-u C-c = RET)}}} in +a field. Detailed information are displayed. + +*** Updating the table +:PROPERTIES: +:DESCRIPTION: Recomputing all dependent fields. +:END: +#+cindex: recomputing table fields +#+cindex: updating, table + +Recalculation of a table is normally not automatic, but needs to be +triggered by a command. To make recalculation at least +semi-automatic, see [[*Advanced features]]. + +In order to recalculate a line of a table or the entire table, use the +following commands: + +- {{{kbd(C-c *)}}} (~org-table-recalculate~) :: + + #+kindex: C-c * + #+findex: org-table-recalculate + Recalculate the current row by first applying the stored column + formulas from left to right, and all field/range formulas in the + current row. + +- {{{kbd(C-u C-c *)}}} or {{{kbd(C-u C-c C-c)}}} :: + + #+kindex: C-u C-c * + #+kindex: C-u C-c C-c + Recompute the entire table, line by line. Any lines before the + first hline are left alone, assuming that these are part of the + table header. + +- {{{kbd(C-u C-u C-c *)}}} or {{{kbd(C-u C-u C-c C-c)}}} (~org-table-iterate~) :: + + #+kindex: C-u C-u C-c * + #+kindex: C-u C-u C-c C-c + #+findex: org-table-iterate + Iterate the table by recomputing it until no further changes occur. + This may be necessary if some computed fields use the value of other + fields that are computed /later/ in the calculation sequence. + +- {{{kbd(M-x org-table-recalculate-buffer-tables)}}} :: + + #+findex: org-table-recalculate-buffer-tables + Recompute all tables in the current buffer. + +- {{{kbd(M-x org-table-iterate-buffer-tables)}}} :: + + #+findex: org-table-iterate-buffer-tables + Iterate all tables in the current buffer, in order to converge + table-to-table dependencies. + +*** Advanced features +:PROPERTIES: +:DESCRIPTION: Field and column names, automatic recalculation... +:END: + +If you want the recalculation of fields to happen automatically, or if +you want to be able to assign /names/[fn:22] to fields and columns, +you need to reserve the first column of the table for special marking +characters. + +- {{{kbd(C-#)}}} (~org-table-rotate-recalc-marks~) :: + + #+kindex: C-# + #+findex: org-table-rotate-recalc-marks + Rotate the calculation mark in first column through the states =#=, + =*=, =!=, =$=. When there is an active region, change all marks in + the region. + +Here is an example of a table that collects exam results of students +and makes use of these features: + +#+begin_example +|---+---------+--------+--------+--------+-------+------| +| | Student | Prob 1 | Prob 2 | Prob 3 | Total | Note | +|---+---------+--------+--------+--------+-------+------| +| ! | | P1 | P2 | P3 | Tot | | +| # | Maximum | 10 | 15 | 25 | 50 | 10.0 | +| ^ | | m1 | m2 | m3 | mt | | +|---+---------+--------+--------+--------+-------+------| +| # | Peter | 10 | 8 | 23 | 41 | 8.2 | +| # | Sam | 2 | 4 | 3 | 9 | 1.8 | +|---+---------+--------+--------+--------+-------+------| +| | Average | | | | 25.0 | | +| ^ | | | | | at | | +| $ | max=50 | | | | | | +|---+---------+--------+--------+--------+-------+------| +,#+TBLFM: $6=vsum($P1..$P3)::$7=10*$Tot/$max;%.1f::$at=vmean(@-II..@-I);%.1f +#+end_example + +#+attr_texinfo: :tag Important +#+begin_quote +Please note that for these special tables, recalculating the table +with {{{kbd(C-u C-c *)}}} only affects rows that are marked =#= or +=*=, and fields that have a formula assigned to the field itself. The +column formulas are not applied in rows with empty first field. +#+end_quote + +#+cindex: marking characters, tables +The marking characters have the following meaning: + +- =!= :: + + The fields in this line define names for the columns, so that you + may refer to a column as =$Tot= instead of =$6=. + +- =^= :: + + This row defines names for the fields /above/ the row. With such + a definition, any formula in the table may use =$m1= to refer to the + value =10=. Also, if you assign a formula to a names field, it is + stored as =$name = ...=. + +- =_= :: + + Similar to =^=, but defines names for the fields in the row /below/. + +- =$= :: + + Fields in this row can define /parameters/ for formulas. For + example, if a field in a =$= row contains =max=50=, then formulas in + this table can refer to the value 50 using =$max=. Parameters work + exactly like constants, only that they can be defined on a per-table + basis. + +- =#= :: + + Fields in this row are automatically recalculated when pressing + {{{kbd(TAB)}}} or {{{kbd(RET)}}} or {{{kbd(S-TAB)}}} in this row. + Also, this row is selected for a global recalculation with + {{{kbd(C-u C-c *)}}}. Unmarked lines are left alone by this + command. + +- =*= :: + + Selects this line for global recalculation with {{{kbd(C-u C-c + *)}}}, but not for automatic recalculation. Use this when automatic + recalculation slows down editing too much. + +- =/= :: + + Do not export this line. Useful for lines that contain the + narrowing == markers or column group markers. + +Finally, just to whet your appetite for what can be done with the +fantastic Calc package, here is a table that computes the Taylor +series of degree n at location x for a couple of functions. + +#+begin_example +|---+-------------+---+-----+--------------------------------------| +| | Func | n | x | Result | +|---+-------------+---+-----+--------------------------------------| +| # | exp(x) | 1 | x | 1 + x | +| # | exp(x) | 2 | x | 1 + x + x^2 / 2 | +| # | exp(x) | 3 | x | 1 + x + x^2 / 2 + x^3 / 6 | +| # | x^2+sqrt(x) | 2 | x=0 | x*(0.5 / 0) + x^2 (2 - 0.25 / 0) / 2 | +| # | x^2+sqrt(x) | 2 | x=1 | 2 + 2.5 x - 2.5 + 0.875 (x - 1)^2 | +| * | tan(x) | 3 | x | 0.0175 x + 1.77e-6 x^3 | +|---+-------------+---+-----+--------------------------------------| +,#+TBLFM: $5=taylor($2,$4,$3);n3 +#+end_example + +** Org Plot +:PROPERTIES: +:DESCRIPTION: Plotting from Org tables. +:END: +#+cindex: graph, in tables +#+cindex: plot tables using Gnuplot + +Org Plot can produce graphs of information stored in Org tables, +either graphically or in ASCII art. + +*** Graphical plots using Gnuplot +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: @samp{PLOT}, keyword +Org Plot can produce 2D and 3D graphs of information stored in Org +tables using [[http://www.gnuplot.info/][Gnuplot]] and [[http://cars9.uchicago.edu/~ravel/software/gnuplot-mode.html][Gnuplot mode]]. To see this in action, ensure +that you have both Gnuplot and Gnuplot mode installed on your system, +then call {{{kbd(C-c \quot g)}}} or {{{kbd(M-x org-plot/gnuplot)}}} on the +following table. + +#+begin_example +,#+PLOT: title:"Citas" ind:1 deps:(3) type:2d with:histograms set:"yrange [0:]" +| Sede | Max cites | H-index | +|-----------+-----------+---------| +| Chile | 257.72 | 21.39 | +| Leeds | 165.77 | 19.68 | +| Sao Paolo | 71.00 | 11.50 | +| Stockholm | 134.19 | 14.33 | +| Morelia | 257.56 | 17.67 | +#+end_example + +Notice that Org Plot is smart enough to apply the table's headers as +labels. Further control over the labels, type, content, and +appearance of plots can be exercised through the =PLOT= keyword +preceding a table. See below for a complete list of Org Plot options. +For more information and examples see the [[https://orgmode.org/worg/org-tutorials/org-plot.html][Org Plot tutorial]]. + +**** Plot options +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +- =set= :: + + Specify any Gnuplot option to be set when graphing. + +- =title= :: + + Specify the title of the plot. + +- =ind= :: + + Specify which column of the table to use as the =x= axis. + +- =deps= :: + + Specify the columns to graph as a Lisp style list, surrounded by + parentheses and separated by spaces for example =dep:(3 4)= to graph + the third and fourth columns. Defaults to graphing all other + columns aside from the =ind= column. + +- =type= :: + + Specify whether the plot is =2d=, =3d=, or =grid=. + +- =with= :: + + Specify a =with= option to be inserted for every column being + plotted, e.g., =lines=, =points=, =boxes=, =impulses=. Defaults to + =lines=. + +- =file= :: + + If you want to plot to a file, specify + ="path/to/desired/output-file"=. + +- =labels= :: + + List of labels to be used for the =deps=. Defaults to the column + headers if they exist. + +- =line= :: + + Specify an entire line to be inserted in the Gnuplot script. + +- =map= :: + + When plotting =3d= or =grid= types, set this to =t= to graph a flat + mapping rather than a =3d= slope. + +- =timefmt= :: + + Specify format of Org mode timestamps as they will be parsed by + Gnuplot. Defaults to =%Y-%m-%d-%H:%M:%S=. + +- =script= :: + + If you want total control, you can specify a script file---place the + file name between double-quotes---which will be used to plot. + Before plotting, every instance of =$datafile= in the specified + script will be replaced with the path to the generated data file. + Note: even if you set this option, you may still want to specify the + plot type, as that can impact the content of the data file. + +*** ASCII bar plots +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +While point is on a column, typing {{{kbd(C-c " a)}}} or {{{kbd(M-x +orgtbl-ascii-plot)}}} create a new column containing an ASCII-art bars +plot. The plot is implemented through a regular column formula. When +the source column changes, the bar plot may be updated by refreshing +the table, for example typing {{{kbd(C-u C-c *)}}}. + +#+begin_example +| Sede | Max cites | | +|---------------+-----------+--------------| +| Chile | 257.72 | WWWWWWWWWWWW | +| Leeds | 165.77 | WWWWWWWh | +| Sao Paolo | 71.00 | WWW; | +| Stockholm | 134.19 | WWWWWW: | +| Morelia | 257.56 | WWWWWWWWWWWH | +| Rochefourchat | 0.00 | | +,#+TBLFM: $3='(orgtbl-ascii-draw $2 0.0 257.72 12) +#+end_example + +The formula is an Elisp call. + +#+attr_texinfo: :options orgtbl-ascii-draw value min max &optional width +#+begin_defun +Draw an ASCII bar in a table. + +{{{var(VALUE)}}} is the value to plot. + +{{{var(MIN)}}} is the value displayed as an empty bar. {{{var(MAX)}}} +is the value filling all the {{{var(WIDTH)}}}. Sources values outside +this range are displayed as =too small= or =too large=. + +{{{var(WIDTH)}}} is the number of characters of the bar plot. It +defaults to =12=. +#+end_defun + +* Hyperlinks +:PROPERTIES: +:DESCRIPTION: Notes in context. +:END: +#+cindex: hyperlinks + +Like HTML, Org provides support for links inside a file, external +links to other files, Usenet articles, emails, and much more. + +** Link Format +:PROPERTIES: +:DESCRIPTION: How links in Org are formatted. +:END: +#+cindex: link format +#+cindex: format, of links + +#+cindex: angle bracket links +#+cindex: plain links +Org recognizes plain URIs, possibly wrapped within angle +brackets[fn:23], and activate them as clickable links. + +#+cindex: bracket links +The general link format, however, looks like this: + +: [[LINK][DESCRIPTION]] + +#+texinfo: @noindent +or alternatively + +: [[LINK]] + +#+cindex: escape syntax, for links +#+cindex: backslashes, in links +Some =\=, =[= and =]= characters in the {{{var(LINK)}}} part need to +be "escaped", i.e., preceded by another =\= character. More +specifically, the following characters, and only them, must be +escaped: + +1. all =[= and =]= characters, +2. every =\= character preceding either =]= or =[=, +3. every =\= character at the end of the link. + +#+findex: org-link-escape +Functions inserting links (see [[*Handling Links]]) properly escape +ambiguous characters. You only need to bother about the rules above +when inserting directly, or yanking, a URI within square brackets. +When in doubt, you may use the function ~org-link-escape~, which turns +a link string into its escaped form. + +Once a link in the buffer is complete, with all brackets present, Org +changes the display so that =DESCRIPTION= is displayed instead of +=[[LINK][DESCRIPTION]]= and =LINK= is displayed instead of =[[LINK]]=. +Links are highlighted in the ~org-link~ face, which, by default, is an +underlined face. + +You can directly edit the visible part of a link. This can be either +the {{{var(LINK)}}} part, if there is no description, or the +{{{var(DESCRIPTION)}}} part otherwise. To also edit the invisible +{{{var(LINK)}}} part, use {{{kbd(C-c C-l)}}} with point on the link +(see [[*Handling Links]]). + +If you place point at the beginning or just behind the end of the +displayed text and press {{{kbd(BS)}}}, you remove +the---invisible---bracket at that location[fn:24]. This makes the link +incomplete and the internals are again displayed as plain text. +Inserting the missing bracket hides the link internals again. To show +the internal structure of all links, use the menu: Org \rarr Hyperlinks \rarr +Literal links. + +** Internal Links +:PROPERTIES: +:DESCRIPTION: Links to other places in the current file. +:END: +#+cindex: internal links +#+cindex: links, internal + +A link that does not look like a URL---i.e., does not start with +a known scheme or a file name---refers to the current document. You +can follow it with {{{kbd(C-c C-o)}}} when point is on the link, or +with a mouse click (see [[*Handling Links]]). + +#+cindex: @samp{CUSTOM_ID}, property +Org provides several refinements to internal navigation within +a document. Most notably, a construct like =[[#my-custom-id]]= +specifically targets the entry with the =CUSTOM_ID= property set to +=my-custom-id=. Also, an internal link looking like =[[*Some +section]]= points to a headline with the name =Some section=[fn:25]. + +#+cindex: targets, for links +When the link does not belong to any of the cases above, Org looks for +a /dedicated target/: the same string in double angular brackets, like +=<>=. + +#+cindex: @samp{NAME}, keyword +If no dedicated target exists, the link tries to match the exact name +of an element within the buffer. Naming is done, unsurprisingly, with +the =NAME= keyword, which has to be put in the line before the element +it refers to, as in the following example + +#+begin_example +,#+NAME: My Target +| a | table | +|----+------------| +| of | four cells | +#+end_example + +#+vindex: org-link-search-must-match-exact-headline +Ultimately, if none of the above succeeds, Org searches for a headline +that is exactly the link text but may also include a TODO keyword and +tags, or initiates a plain text search, according to the value of +~org-link-search-must-match-exact-headline~. + +Note that you must make sure custom IDs, dedicated targets, and names +are unique throughout the document. Org provides a linter to assist +you in the process, if needed. See [[*Org Syntax]]. + +During export, internal links are used to mark objects and assign them +a number. Marked objects are then referenced by links pointing to +them. In particular, links without a description appear as the number +assigned to the marked object[fn:26]. In the following excerpt from +an Org buffer + +#+begin_example +1. one item +2. <>another item +Here we refer to item [[target]]. +#+end_example + +#+texinfo: @noindent +The last sentence will appear as =Here we refer to item 2= when +exported. + +In non-Org files, the search looks for the words in the link text. In +the above example the search would be for =target=. + +Following a link pushes a mark onto Org's own mark ring. You can +return to the previous position with {{{kbd(C-c &)}}}. Using this +command several times in direct succession goes back to positions +recorded earlier. + +** Radio Targets +:PROPERTIES: +:DESCRIPTION: Make targets trigger links in plain text. +:END: +#+cindex: radio targets +#+cindex: targets, radio +#+cindex: links, radio targets + +Org can automatically turn any occurrences of certain target names in +normal text into a link. So without explicitly creating a link, the +text connects to the target radioing its position. Radio targets are +enclosed by triple angular brackets. For example, a target =<<>>= causes each occurrence of =my target= in normal text to +become activated as a link. The Org file is scanned automatically for +radio targets only when the file is first loaded into Emacs. To +update the target list during editing, press {{{kbd(C-c C-c)}}} with +point on or at a target. + +** External Links +:PROPERTIES: +:DESCRIPTION: URL-like links to the world. +:END: +#+cindex: links, external +#+cindex: external links +#+cindex: attachment links +#+cindex: BBDB links +#+cindex: Elisp links +#+cindex: file links +#+cindex: Gnus links +#+cindex: Help links +#+cindex: IRC links +#+cindex: Info links +#+cindex: MH-E links +#+cindex: Rmail links +#+cindex: shell links +#+cindex: URL links +#+cindex: Usenet links + +Org supports links to files, websites, Usenet and email messages, BBDB +database entries and links to both IRC conversations and their logs. +External links are URL-like locators. They start with a short +identifying string followed by a colon. There can be no space after +the colon. + +Here is the full set of built-in link types: + +- =file= :: + + File links. File name may be remote, absolute, or relative. + + Additionally, you can specify a line number, or a text search. + In Org files, you may link to a headline name, a custom ID, or a + code reference instead. + + As a special case, "file" prefix may be omitted if the file name + is complete, e.g., it starts with =./=, or =/=. + +- =attachment= :: + + Same as file links but for files and folders attached to the current + node (see [[*Attachments]]). Attachment links are intended to behave + exactly as file links but for files relative to the attachment + directory. + +- =bbdb= :: + + Link to a BBDB record, with possible regexp completion. + +- =docview= :: + + Link to a document opened with DocView mode. You may specify a page + number. + +- =doi= :: + + Link to an electronic resource, through its handle. + +- =elisp= :: + + Execute an Elisp command upon activation. + +- =gnus=, =rmail=, =mhe= :: + + Link to messages or folders from a given Emacs' MUA. + +- =help= :: + + Display documentation of a symbol in =*Help*= buffer. + +- =http=, =https= :: + + Web links. + +- =id= :: + + Link to a specific headline by its ID property, in an Org file. + +- =info= :: + + Link to an Info manual, or to a specific node. + +- =irc= :: + + Link to an IRC channel. + +- =mailto= :: + + Link to message composition. + +- =news= :: + + Usenet links. + +- =shell= :: + + Execute a shell command upon activation. + +The following table illustrates the link types above, along with their +options: + +| Link Type | Example | +|------------+----------------------------------------------------------| +| http | =http://staff.science.uva.nl/c.dominik/= | +| https | =https://orgmode.org/= | +| doi | =doi:10.1000/182= | +| file | =file:/home/dominik/images/jupiter.jpg= | +| | =/home/dominik/images/jupiter.jpg= (same as above) | +| | =file:papers/last.pdf= | +| | =./papers/last.pdf= (same as above) | +| | =file:/ssh:me@some.where:papers/last.pdf= (remote) | +| | =/ssh:me@some.where:papers/last.pdf= (same as above) | +| | =file:sometextfile::NNN= (jump to line number) | +| | =file:projects.org= | +| | =file:projects.org::some words= (text search)[fn:27] | +| | =file:projects.org::*task title= (headline search) | +| | =file:projects.org::#custom-id= (headline search) | +| attachment | =attachment:projects.org= | +| | =attachment:projects.org::some words= (text search) | +| docview | =docview:papers/last.pdf::NNN= | +| id | =id:B7423F4D-2E8A-471B-8810-C40F074717E9= | +| news | =news:comp.emacs= | +| mailto | =mailto:adent@galaxy.net= | +| mhe | =mhe:folder= (folder link) | +| | =mhe:folder#id= (message link) | +| rmail | =rmail:folder= (folder link) | +| | =rmail:folder#id= (message link) | +| gnus | =gnus:group= (group link) | +| | =gnus:group#id= (article link) | +| bbdb | =bbdb:R.*Stallman= (record with regexp) | +| irc | =irc:/irc.com/#emacs/bob= | +| help | =help:org-store-link= | +| info | =info:org#External links= | +| shell | =shell:ls *.org= | +| elisp | =elisp:(find-file "Elisp.org")= (Elisp form to evaluate) | +| | =elisp:org-agenda= (interactive Elisp command) | + +#+cindex: VM links +#+cindex: Wanderlust links +On top of these built-in link types, additional ones are available +through the =contrib/= directory (see [[*Installation]]). For example, +these links to VM or Wanderlust messages are available when you load +the corresponding libraries from the =contrib/= directory: + +| =vm:folder= | VM folder link | +| =vm:folder#id= | VM message link | +| =vm://myself@some.where.org/folder#id= | VM on remote machine | +| =vm-imap:account:folder= | VM IMAP folder link | +| =vm-imap:account:folder#id= | VM IMAP message link | +| =wl:folder= | Wanderlust folder link | +| =wl:folder#id= | Wanderlust message link | + +For information on customizing Org to add new link types, see [[*Adding +Hyperlink Types]]. + +A link should be enclosed in double brackets and may contain +descriptive text to be displayed instead of the URL (see [[*Link +Format]]), for example: + +: [[http://www.gnu.org/software/emacs/][GNU Emacs]] + +If the description is a file name or URL that points to an image, HTML +export (see [[*HTML Export]]) inlines the image as a clickable button. If +there is no description at all and the link points to an image, that +image is inlined into the exported HTML file. + +#+cindex: square brackets, around links +#+cindex: angular brackets, around links +#+cindex: plain text external links +Org also recognizes external links amid normal text and activates them +as links. If spaces must be part of the link (for example in +=bbdb:R.*Stallman=), or if you need to remove ambiguities about the +end of the link, enclose the link in square or angular brackets. + +** Handling Links +:PROPERTIES: +:DESCRIPTION: Creating, inserting and following. +:END: +#+cindex: links, handling + +Org provides methods to create a link in the correct syntax, to insert +it into an Org file, and to follow the link. + +#+findex: org-store-link +#+cindex: storing links +The main function is ~org-store-link~, called with {{{kbd(M-x +org-store-link)}}}. Because of its importance, we suggest to bind it +to a widely available key (see [[*Activation]]). It stores a link to the +current location. The link is stored for later insertion into an Org +buffer---see below. The kind of link that is created depends on the +current buffer: + +- /Org mode buffers/ :: + + For Org files, if there is a =<>= at point, the link points + to the target. Otherwise it points to the current headline, which + is also the description[fn:28]. + + #+vindex: org-id-link-to-org-use-id + #+cindex: @samp{CUSTOM_ID}, property + #+cindex: @samp{ID}, property + If the headline has a =CUSTOM_ID= property, store a link to this + custom ID. In addition or alternatively, depending on the value of + ~org-id-link-to-org-use-id~, create and/or use a globally unique + =ID= property for the link[fn:29]. So using this command in Org + buffers potentially creates two links: a human-readable link from + the custom ID, and one that is globally unique and works even if the + entry is moved from file to file. Later, when inserting the link, + you need to decide which one to use. + +- /Email/News clients: VM, Rmail, Wanderlust, MH-E, Gnus/ :: + + #+vindex: org-link-email-description-format + Pretty much all Emacs mail clients are supported. The link points + to the current article, or, in some Gnus buffers, to the group. The + description is constructed according to the variable + ~org-link-email-description-format~. By default, it refers to the + addressee and the subject. + +- /Web browsers: W3, W3M and EWW/ :: + + Here the link is the current URL, with the page title as the + description. + +- /Contacts: BBDB/ :: + + Links created in a BBDB buffer point to the current entry. + +- /Chat: IRC/ :: + + #+vindex: org-irc-links-to-logs + For IRC links, if the variable ~org-irc-link-to-logs~ is non-~nil~, + create a =file= style link to the relevant point in the logs for the + current conversation. Otherwise store an =irc= style link to the + user/channel/server under the point. + +- /Other files/ :: + + For any other file, the link points to the file, with a search + string (see [[*Search Options in File Links]]) pointing to the contents + of the current line. If there is an active region, the selected + words form the basis of the search string. You can write custom Lisp + functions to select the search string and perform the search for + particular file types (see [[*Custom Searches]]). + + You can also define dedicated links to other files. See [[*Adding + Hyperlink Types]]. + +- /Agenda view/ :: + + When point is in an agenda view, the created link points to the + entry referenced by the current line. + +From an Org buffer, the following commands create, navigate or, more +generally, act on links. + +#+attr_texinfo: :sep , +- {{{kbd(C-c C-l)}}} (~org-insert-link~) :: + + #+kindex: C-c C-l + #+findex: org-insert-link + #+cindex: link completion + #+cindex: completion, of links + #+cindex: inserting links + #+vindex: org-link-keep-stored-after-insertion + Insert a link[fn:30]. This prompts for a link to be inserted into + the buffer. You can just type a link, using text for an internal + link, or one of the link type prefixes mentioned in the examples + above. The link is inserted into the buffer, along with + a descriptive text[fn:31]. If some text was selected at this time, + it becomes the default description. + + - /Inserting stored links/ :: + + All links stored during the current session are part of the + history for this prompt, so you can access them with {{{kbd(UP)}}} + and {{{kbd(DOWN)}}} (or {{{kbd(M-p)}}}, {{{kbd(M-n)}}}). + + - /Completion support/ :: + + Completion with {{{kbd(TAB)}}} helps you to insert valid link + prefixes like =http= or =ftp=, including the prefixes defined + through link abbreviations (see [[*Link Abbreviations]]). If you + press {{{kbd(RET)}}} after inserting only the prefix, Org offers + specific completion support for some link types[fn:32]. For + example, if you type {{{kbd(f i l e RET)}}}---alternative access: + {{{kbd(C-u C-c C-l)}}}, see below---Org offers file name + completion, and after {{{kbd(b b d b RET)}}} you can complete + contact names. + +- {{{kbd(C-u C-c C-l)}}} :: + + #+cindex: file name completion + #+cindex: completion, of file names + #+kindex: C-u C-c C-l + When {{{kbd(C-c C-l)}}} is called with a {{{kbd(C-u)}}} prefix + argument, insert a link to a file. You may use file name completion + to select the name of the file. The path to the file is inserted + relative to the directory of the current Org file, if the linked + file is in the current directory or in a sub-directory of it, or if + the path is written relative to the current directory using =../=. + Otherwise an absolute path is used, if possible with =~/= for your + home directory. You can force an absolute path with two + {{{kbd(C-u)}}} prefixes. + +- {{{kbd(C-c C-l)}}} (with point on existing link) :: + + #+cindex: following links + When point is on an existing link, {{{kbd(C-c C-l)}}} allows you to + edit the link and description parts of the link. + +- {{{kbd(C-c C-o)}}} (~org-open-at-point~) :: + + #+kindex: C-c C-o + #+findex: org-open-at-point + #+vindex: org-file-apps + Open link at point. This launches a web browser for URL (using + ~browse-url-at-point~), run VM/MH-E/Wanderlust/Rmail/Gnus/BBDB for + the corresponding links, and execute the command in a shell link. + When point is on an internal link, this command runs the + corresponding search. When point is on the tags part of a headline, + it creates the corresponding tags view (see [[*Matching tags and + properties]]). If point is on a timestamp, it compiles the agenda for + that date. Furthermore, it visits text and remote files in =file= + links with Emacs and select a suitable application for local + non-text files. Classification of files is based on file extension + only. See option ~org-file-apps~. If you want to override the + default application and visit the file with Emacs, use + a {{{kbd(C-u)}}} prefix. If you want to avoid opening in Emacs, use + a {{{kbd(C-u C-u)}}} prefix. + + #+vindex: org-link-frame-setup + If point is on a headline, but not on a link, offer all links in the + headline and entry text. If you want to setup the frame + configuration for following links, customize ~org-link-frame-setup~. + +- {{{kbd(RET)}}} :: + + #+vindex: org-return-follows-link + #+kindex: RET + When ~org-return-follows-link~ is set, {{{kbd(RET)}}} also follows + the link at point. + +- {{{kbd(mouse-2)}}} or {{{kbd(mouse-1)}}} :: + + #+kindex: mouse-2 + #+kindex: mouse-1 + On links, {{{kbd(mouse-1)}}} and {{{kbd(mouse-2)}}} opens the link + just as {{{kbd(C-c C-o)}}} does. + +- {{{kbd(mouse-3)}}} :: + + #+vindex: org-link-use-indirect-buffer-for-internals + #+kindex: mouse-3 + Like {{{kbd(mouse-2)}}}, but force file links to be opened with + Emacs, and internal links to be displayed in another window[fn:33]. + +- {{{kbd(C-c %)}}} (~org-mark-ring-push~) :: + + #+kindex: C-c % + #+findex: org-mark-ring-push + #+cindex: mark ring + Push the current position onto the Org mark ring, to be able to + return easily. Commands following an internal link do this + automatically. + +- {{{kbd(C-c &)}}} (~org-mark-ring-goto~) :: + + #+kindex: C-c & + #+findex: org-mark-ring-goto + #+cindex: links, returning to + Jump back to a recorded position. A position is recorded by the + commands following internal links, and by {{{kbd(C-c %)}}}. Using + this command several times in direct succession moves through a ring + of previously recorded positions. + +- {{{kbd(C-c C-x C-n)}}} (~org-next-link~), {{{kbd(C-c C-x C-p)}}} (~org-previous-link~) :: + + #+kindex: C-c C-x C-p + #+findex: org-previous-link + #+kindex: C-c C-x C-n + #+findex: org-next-link + #+cindex: links, finding next/previous + Move forward/backward to the next link in the buffer. At the limit + of the buffer, the search fails once, and then wraps around. The + key bindings for this are really too long; you might want to bind + this also to {{{kbd(M-n)}}} and {{{kbd(M-p)}}}. + + #+begin_src emacs-lisp + (with-eval-after-load 'org + (define-key org-mode-map (kbd "M-n") 'org-next-link) + (define-key org-mode-map (kbd "M-p") 'org-previous-link)) + #+end_src + +** Using Links Outside Org +:PROPERTIES: +:DESCRIPTION: Linking from my C source code? +:END: + +#+findex: org-insert-link-global +#+findex: org-open-at-point-global +You can insert and follow links that have Org syntax not only in Org, +but in any Emacs buffer. For this, Org provides two functions: +~org-insert-link-global~ and ~org-open-at-point-global~. + +You might want to bind them to globally available keys. See +[[*Activation]] for some advice. + +** Link Abbreviations +:PROPERTIES: +:DESCRIPTION: Shortcuts for writing complex links. +:END: +#+cindex: link abbreviations +#+cindex: abbreviation, links + +Long URL can be cumbersome to type, and often many similar links are +needed in a document. For this you can use link abbreviations. An +abbreviated link looks like this + +: [[linkword:tag][description]] + +#+texinfo: @noindent +#+vindex: org-link-abbrev-alist +where the tag is optional. The /linkword/ must be a word, starting +with a letter, followed by letters, numbers, =-=, and =_=. +Abbreviations are resolved according to the information in the +variable ~org-link-abbrev-alist~ that relates the linkwords to +replacement text. Here is an example: + +#+begin_src emacs-lisp +(setq org-link-abbrev-alist + '(("bugzilla" . "http://10.1.2.9/bugzilla/show_bug.cgi?id=") + ("Nu Html Checker" . "https://validator.w3.org/nu/?doc=%h") + ("duckduckgo" . "https://duckduckgo.com/?q=%s") + ("omap" . "http://nominatim.openstreetmap.org/search?q=%s&polygon=1") + ("ads" . "https://ui.adsabs.harvard.edu/search/q=%20author%3A\"%s\""))) +#+end_src + +If the replacement text contains the string =%s=, it is replaced with +the tag. Using =%h= instead of =%s= percent-encodes the tag (see the +example above, where we need to encode the URL parameter). Using +=%(my-function)= passes the tag to a custom Lisp function, and replace +it by the resulting string. + +If the replacement text do not contain any specifier, it is simply +appended to the string in order to create the link. + +Instead of a string, you may also specify a Lisp function to create +the link. Such a function will be called with the tag as the only +argument. + +With the above setting, you could link to a specific bug with +=[[bugzilla:129]]=, search the web for =OrgMode= with =[[duckduckgo:OrgMode]]=, +show the map location of the Free Software Foundation =[[gmap:51 +Franklin Street, Boston]]= or of Carsten office =[[omap:Science Park 904, +Amsterdam, The Netherlands]]= and find out what the Org author is doing +besides Emacs hacking with =[[ads:Dominik,C]]=. + +If you need special abbreviations just for a single Org buffer, you +can define them in the file with + +#+cindex: @samp{LINK}, keyword +#+begin_example +,#+LINK: bugzilla http://10.1.2.9/bugzilla/show_bug.cgi?id= +,#+LINK: duckduckgo https://duckduckgo.com/?q=%s +#+end_example + +In-buffer completion (see [[*Completion]]) can be used after =[= to +complete link abbreviations. You may also define a Lisp function that +implements special (e.g., completion) support for inserting such a +link with {{{kbd(C-c C-l)}}}. Such a function should not accept any +arguments, and should return the full link with a prefix. You can set +the link completion function like this: + +#+begin_src emacs-lisp +(org-link-set-parameter "type" :complete #'some-completion-function) +#+end_src + +** Search Options in File Links +:PROPERTIES: +:DESCRIPTION: Linking to a specific location. +:ALT_TITLE: Search Options +:END: +#+cindex: search option in file links +#+cindex: file links, searching +#+cindex: attachment links, searching + +File links can contain additional information to make Emacs jump to a +particular location in the file when following a link. This can be a +line number or a search option after a double colon[fn:34]. For +example, when the command ~org-store-link~ creates a link (see +[[*Handling Links]]) to a file, it encodes the words in the current line +as a search string that can be used to find this line back later when +following the link with {{{kbd(C-c C-o)}}}. + +Note that all search options apply for Attachment links in the same +way that they apply for File links. + +Here is the syntax of the different ways to attach a search to a file +link, together with explanations for each: + +#+begin_example +[[file:~/code/main.c::255]] +[[file:~/xx.org::My Target]] +[[file:~/xx.org::*My Target]] +[[file:~/xx.org::#my-custom-id]] +[[file:~/xx.org::/regexp/]] +[[attachment:main.c::255]] +#+end_example + +- =255= :: + + Jump to line 255. + +- =My Target= :: + + Search for a link target =<>=, or do a text search for + =my target=, similar to the search in internal links, see [[*Internal + Links]]. In HTML export (see [[*HTML Export]]), such a file link becomes + a HTML reference to the corresponding named anchor in the linked + file. + +- =*My Target= :: + + In an Org file, restrict search to headlines. + +- =#my-custom-id= :: + + Link to a heading with a =CUSTOM_ID= property + +- =/REGEXP/= :: + + Do a regular expression search for {{{var(REGEXP)}}}. This uses the + Emacs command ~occur~ to list all matches in a separate window. If + the target file is in Org mode, ~org-occur~ is used to create + a sparse tree with the matches. + +As a degenerate case, a file link with an empty file name can be used +to search the current file. For example, =[[file:::find me]]= does +a search for =find me= in the current file, just as =[[find me]]= +would. + +** Custom Searches +:PROPERTIES: +:DESCRIPTION: When the default search is not enough. +:END: +#+cindex: custom search strings +#+cindex: search strings, custom + +The default mechanism for creating search strings and for doing the +actual search related to a file link may not work correctly in all +cases. For example, BibTeX database files have many entries like +~year="1993"~ which would not result in good search strings, because +the only unique identification for a BibTeX entry is the citation key. + +#+vindex: org-create-file-search-functions +#+vindex: org-execute-file-search-functions +If you come across such a problem, you can write custom functions to +set the right search string for a particular file type, and to do the +search for the string in the file. Using ~add-hook~, these functions +need to be added to the hook variables +~org-create-file-search-functions~ and +~org-execute-file-search-functions~. See the docstring for these +variables for more information. Org actually uses this mechanism for +BibTeX database files, and you can use the corresponding code as an +implementation example. See the file =ol-bibtex.el=. + +* TODO Items +:PROPERTIES: +:DESCRIPTION: Every tree branch can be a TODO item. +:END: +#+cindex: TODO items + +Org mode does not maintain TODO lists as separate documents[fn:35]. +Instead, TODO items are an integral part of the notes file, because +TODO items usually come up while taking notes! With Org mode, simply +mark any entry in a tree as being a TODO item. In this way, +information is not duplicated, and the entire context from which the +TODO item emerged is always present. + +Of course, this technique for managing TODO items scatters them +throughout your notes file. Org mode compensates for this by +providing methods to give you an overview of all the things that you +have to do. + +** Basic TODO Functionality +:PROPERTIES: +:DESCRIPTION: Marking and displaying TODO entries. +:ALT_TITLE: TODO Basics +:END: + +Any headline becomes a TODO item when it starts with the word =TODO=, +for example: + +: *** TODO Write letter to Sam Fortune + +The most important commands to work with TODO entries are: + +- {{{kbd(C-c C-t)}}} (~org-todo~) :: + + #+kindex: C-c C-t + #+cindex: cycling, of TODO states + Rotate the TODO state of the current item among + + #+begin_example + ,-> (unmarked) -> TODO -> DONE --. + '--------------------------------' + #+end_example + + If TODO keywords have fast access keys (see [[*Fast access to TODO + states]]), prompt for a TODO keyword through the fast selection + interface; this is the default behavior when + ~org-use-fast-todo-selection~ is non-~nil~. + + The same state changing can also be done "remotely" from the agenda + buffer with the {{{kbd(t)}}} command key (see [[*Commands in the + Agenda Buffer]]). + +- {{{kbd(S-RIGHT)}}} {{{kbd(S-LEFT)}}} :: + + #+kindex: S-RIGHT + #+kindex: S-LEFT + #+vindex: org-treat-S-cursor-todo-selection-as-state-change + Select the following/preceding TODO state, similar to cycling. + Useful mostly if more than two TODO states are possible (see + [[*Extended Use of TODO Keywords]]). See also [[*Packages that conflict + with Org mode]], for a discussion of the interaction with + shift-selection. See also the variable + ~org-treat-S-cursor-todo-selection-as-state-change~. + +- {{{kbd(C-c / t)}}} (~org-show-todo-tree~) :: + + #+kindex: C-c / t + #+cindex: sparse tree, for TODO + #+vindex: org-todo-keywords + #+findex: org-show-todo-tree + View TODO items in a /sparse tree/ (see [[*Sparse Trees]]). Folds the + entire buffer, but shows all TODO items---with not-DONE state---and + the headings hierarchy above them. With a prefix argument, or by + using {{{kbd(C-c / T)}}}, search for a specific TODO. You are + prompted for the keyword, and you can also give a list of keywords + like =KWD1|KWD2|...= to list entries that match any one of these + keywords. With a numeric prefix argument N, show the tree for the + Nth keyword in the variable ~org-todo-keywords~. With two prefix + arguments, find all TODO states, both un-done and done. + +- {{{kbd(M-x org-agenda t)}}} (~org-todo-list~) :: + + #+kindex: t @r{(Agenda dispatcher)} + Show the global TODO list. Collects the TODO items (with not-DONE + states) from all agenda files (see [[*Agenda Views]]) into a single + buffer. The new buffer is in Org Agenda mode, which provides + commands to examine and manipulate the TODO entries from the new + buffer (see [[*Commands in the Agenda Buffer]]). See [[*The global TODO + list]], for more information. + +- {{{kbd(S-M-RET)}}} (~org-insert-todo-heading~) :: + + #+kindex: S-M-RET + #+findex: org-insert-todo-heading + Insert a new TODO entry below the current one. + +#+vindex: org-todo-state-tags-triggers +Changing a TODO state can also trigger tag changes. See the docstring +of the option ~org-todo-state-tags-triggers~ for details. + +** Extended Use of TODO Keywords +:PROPERTIES: +:DESCRIPTION: Workflow and assignments. +:ALT_TITLE: TODO Extensions +:END: +#+cindex: extended TODO keywords + +#+vindex: org-todo-keywords +By default, marked TODO entries have one of only two states: TODO and +DONE. Org mode allows you to classify TODO items in more complex ways +with /TODO keywords/ (stored in ~org-todo-keywords~). With special +setup, the TODO keyword system can work differently in different +files. + +Note that /tags/ are another way to classify headlines in general and +TODO items in particular (see [[*Tags]]). + +*** TODO keywords as workflow states +:PROPERTIES: +:DESCRIPTION: From TODO to DONE in steps. +:ALT_TITLE: Workflow states +:END: +#+cindex: TODO workflow +#+cindex: workflow states as TODO keywords + +You can use TODO keywords to indicate different, possibly /sequential/ +states in the process of working on an item, for example[fn:36]: + +#+begin_src emacs-lisp +(setq org-todo-keywords + '((sequence "TODO" "FEEDBACK" "VERIFY" "|" "DONE" "DELEGATED"))) +#+end_src + +The vertical bar separates the TODO keywords (states that /need +action/) from the DONE states (which need /no further action/). If +you do not provide the separator bar, the last state is used as the +DONE state. + +#+cindex: completion, of TODO keywords +With this setup, the command {{{kbd(C-c C-t)}}} cycles an entry from +=TODO= to =FEEDBACK=, then to =VERIFY=, and finally to =DONE= and +=DELEGATED=. You may also use a numeric prefix argument to quickly +select a specific state. For example {{{kbd(C-3 C-c C-t)}}} changes +the state immediately to =VERIFY=. Or you can use {{{kbd(S-RIGHT)}}} +and {{{kbd(S-LEFT)}}} to go forward and backward through the states. +If you define many keywords, you can use in-buffer completion (see +[[*Completion]]) or a special one-key selection scheme (see [[*Fast +access to TODO states]]) to insert these words into the buffer. +Changing a TODO state can be logged with a timestamp, see [[*Tracking +TODO state changes]], for more information. + +*** TODO keywords as types +:PROPERTIES: +:DESCRIPTION: I do this, Fred does the rest. +:ALT_TITLE: TODO types +:END: +#+cindex: TODO types +#+cindex: names as TODO keywords +#+cindex: types as TODO keywords + +The second possibility is to use TODO keywords to indicate different +/types/ of action items. For example, you might want to indicate that +items are for "work" or "home". Or, when you work with several people +on a single project, you might want to assign action items directly to +persons, by using their names as TODO keywords. This type of +functionality is actually much better served by using tags (see +[[*Tags]]), so the TODO implementation is kept just for backward +compatibility. + +Using TODO types, it would be set up like this: + +#+begin_src emacs-lisp +(setq org-todo-keywords '((type "Fred" "Sara" "Lucy" "|" "DONE"))) +#+end_src + +In this case, different keywords do not indicate states, but +rather different types. So the normal work flow would be to assign +a task to a person, and later to mark it DONE. Org mode supports this +style by adapting the workings of the command {{{kbd(C-c +C-t)}}}[fn:37]. When used several times in succession, it still +cycles through all names, in order to first select the right type for +a task. But when you return to the item after some time and execute +{{{kbd(C-c C-t)}}} again, it will switch from any name directly to +=DONE=. Use prefix arguments or completion to quickly select +a specific name. You can also review the items of a specific TODO +type in a sparse tree by using a numeric prefix to {{{kbd(C-c / t)}}}. +For example, to see all things Lucy has to do, you would use +{{{kbd(C-3 C-c / t)}}}. To collect Lucy's items from all agenda files +into a single buffer, you would use the numeric prefix argument as +well when creating the global TODO list: {{{kbd(C-3 M-x org-agenda +t)}}}. + +*** Multiple keyword sets in one file +:PROPERTIES: +:DESCRIPTION: Mixing it all, still finding your way. +:ALT_TITLE: Multiple sets in one file +:END: +#+cindex: TODO keyword sets + +Sometimes you may want to use different sets of TODO keywords in +parallel. For example, you may want to have the basic TODO/DONE, but +also a workflow for bug fixing, and a separate state indicating that +an item has been canceled---so it is not DONE, but also does not +require action. Your setup would then look like this: + +#+begin_src emacs-lisp +(setq org-todo-keywords + '((sequence "TODO" "|" "DONE") + (sequence "REPORT" "BUG" "KNOWNCAUSE" "|" "FIXED") + (sequence "|" "CANCELED"))) +#+end_src + +The keywords should all be different, this helps Org mode keep track +of which subsequence should be used for a given entry. In this setup, +{{{kbd(C-c C-t)}}} only operates within a sub-sequence, so it switches +from =DONE= to (nothing) to =TODO=, and from =FIXED= to (nothing) to +=REPORT=. Therefore you need a mechanism to initially select the +correct sequence. In addition to typing a keyword or using completion +(see [[*Completion]]), you may also apply the following commands: + +#+attr_texinfo: :sep , +- {{{kbd(C-u C-u C-c C-t)}}}, {{{kbd(C-S-RIGHT)}}}, {{{kbd(C-S-LEFT)}}} :: + + #+kindex: C-S-RIGHT + #+kindex: C-S-LEFT + #+kindex: C-u C-u C-c C-t + These keys jump from one TODO sub-sequence to the next. In the + above example, {{{kbd(C-u C-u C-c C-t)}}} or {{{kbd(C-S-RIGHT)}}} + would jump from =TODO= or =DONE= to =REPORT=, and any of the words + in the second row to =CANCELED=. Note that the {{{kbd(C-S-)}}} key + binding conflict with shift-selection (see [[*Packages that conflict + with Org mode]]). + +- {{{kbd(S-RIGHT)}}}, {{{kbd(S-LEFT)}}} :: + + #+kindex: S-RIGHT + #+kindex: S-LEFT + {{{kbd(S-LEFT)}}} and {{{kbd(S-RIGHT)}}} walk through /all/ keywords + from all sub-sequences, so for example {{{kbd(S-RIGHT)}}} would + switch from =DONE= to =REPORT= in the example above. For + a discussion of the interaction with shift-selection, see [[*Packages + that conflict with Org mode]]. + +*** Fast access to TODO states +:PROPERTIES: +:DESCRIPTION: Single letter selection of state. +:END: + +If you would like to quickly change an entry to an arbitrary TODO +state instead of cycling through the states, you can set up keys for +single-letter access to the states. This is done by adding the +selection character after each keyword, in parentheses[fn:38]. For +example: + +#+begin_src emacs-lisp +(setq org-todo-keywords + '((sequence "TODO(t)" "|" "DONE(d)") + (sequence "REPORT(r)" "BUG(b)" "KNOWNCAUSE(k)" "|" "FIXED(f)") + (sequence "|" "CANCELED(c)"))) +#+end_src + +#+vindex: org-fast-tag-selection-include-todo +If you then press {{{kbd(C-c C-t)}}} followed by the selection key, +the entry is switched to this state. {{{kbd(SPC)}}} can be used to +remove any TODO keyword from an entry[fn:39]. + +*** Setting up keywords for individual files +:PROPERTIES: +:DESCRIPTION: Different files, different requirements. +:ALT_TITLE: Per-file keywords +:END: +#+cindex: keyword options +#+cindex: per-file keywords +#+cindex: @samp{TODO}, keyword +#+cindex: @samp{TYP_TODO}, keyword +#+cindex: @samp{SEQ_TODO}, keyword + +It can be very useful to use different aspects of the TODO mechanism +in different files. For file-local settings, you need to add special +lines to the file which set the keywords and interpretation for that +file only. For example, to set one of the two examples discussed +above, you need one of the following lines, starting in column zero +anywhere in the file: + +: #+TODO: TODO FEEDBACK VERIFY | DONE CANCELED + +You may also write =#+SEQ_TODO= to be explicit about the +interpretation, but it means the same as =#+TODO=, or + +: #+TYP_TODO: Fred Sara Lucy Mike | DONE + +A setup for using several sets in parallel would be: + +#+begin_example +,#+TODO: TODO | DONE +,#+TODO: REPORT BUG KNOWNCAUSE | FIXED +,#+TODO: | CANCELED +#+end_example + +#+cindex: completion, of option keywords +#+kindex: M-TAB +To make sure you are using the correct keyword, type =#+= into the +buffer and then use {{{kbd(M-TAB)}}} to complete it (see [[*Completion]]). + +#+cindex: DONE, final TODO keyword +Remember that the keywords after the vertical bar---or the last +keyword if no bar is there---must always mean that the item is DONE, +although you may use a different word. After changing one of these +lines, use {{{kbd(C-c C-c)}}} with point still in the line to make the +changes known to Org mode[fn:40]. + +*** Faces for TODO keywords +:PROPERTIES: +:DESCRIPTION: Highlighting states. +:END: +#+cindex: faces, for TODO keywords + +#+vindex: org-todo, face +#+vindex: org-done, face +#+vindex: org-todo-keyword-faces +Org mode highlights TODO keywords with special faces: ~org-todo~ for +keywords indicating that an item still has to be acted upon, and +~org-done~ for keywords indicating that an item is finished. If you +are using more than two different states, you might want to use +special faces for some of them. This can be done using the variable +~org-todo-keyword-faces~. For example: + +#+begin_src emacs-lisp +(setq org-todo-keyword-faces + '(("TODO" . org-warning) ("STARTED" . "yellow") + ("CANCELED" . (:foreground "blue" :weight bold)))) +#+end_src + +#+vindex: org-faces-easy-properties +While using a list with face properties as shown for =CANCELED= +/should/ work, this does not always seem to be the case. If +necessary, define a special face and use that. A string is +interpreted as a color. The variable ~org-faces-easy-properties~ +determines if that color is interpreted as a foreground or +a background color. + +*** TODO dependencies +:PROPERTIES: +:DESCRIPTION: When one task needs to wait for others. +:END: +#+cindex: TODO dependencies +#+cindex: dependencies, of TODO states + +#+vindex: org-enforce-todo-dependencies +#+cindex: @samp{ORDERED}, property +The structure of Org files---hierarchy and lists---makes it easy to +define TODO dependencies. Usually, a parent TODO task should not be +marked as done until all TODO subtasks, or children tasks, are marked +as done. Sometimes there is a logical sequence to (sub)tasks, so that +one subtask cannot be acted upon before all siblings above it have +been marked as done. If you customize the variable +~org-enforce-todo-dependencies~, Org blocks entries from changing +state to DONE while they have TODO children that are not DONE. +Furthermore, if an entry has a property =ORDERED=, each of its TODO +children is blocked until all earlier siblings are marked as done. +Here is an example: + +#+begin_example +,* TODO Blocked until (two) is done +,** DONE one +,** TODO two + +,* Parent +:PROPERTIES: +:ORDERED: t +:END: +,** TODO a +,** TODO b, needs to wait for (a) +,** TODO c, needs to wait for (a) and (b) +#+end_example + +#+cindex: TODO dependencies, @samp{NOBLOCKING} +#+cindex: @samp{NOBLOCKING}, property +You can ensure an entry is never blocked by using the =NOBLOCKING= +property (see [[*Properties and Columns]]): + +#+begin_example +,* This entry is never blocked +:PROPERTIES: +:NOBLOCKING: t +:END: +#+end_example + +- {{{kbd(C-c C-x o)}}} (~org-toggle-ordered-property~) :: + + #+kindex: C-c C-x o + #+findex: org-toggle-ordered-property + #+vindex: org-track-ordered-property-with-tag + Toggle the =ORDERED= property of the current entry. A property is + used for this behavior because this should be local to the current + entry, not inherited from entries above like a tag (see [[*Tags]]). + However, if you would like to /track/ the value of this property + with a tag for better visibility, customize the variable + ~org-track-ordered-property-with-tag~. + +- {{{kbd(C-u C-u C-u C-c C-t)}}} :: + + #+kindex: C-u C-u C-u C-u C-c C-t + Change TODO state, regardless of any state blocking. + +#+vindex: org-agenda-dim-blocked-tasks +If you set the variable ~org-agenda-dim-blocked-tasks~, TODO entries +that cannot be marked as done because of unmarked children are shown +in a dimmed font or even made invisible in agenda views (see [[*Agenda +Views]]). + +#+cindex: checkboxes and TODO dependencies +#+vindex: org-enforce-todo-dependencies +You can also block changes of TODO states by using checkboxes (see +[[*Checkboxes]]). If you set the variable +~org-enforce-todo-checkbox-dependencies~, an entry that has unchecked +checkboxes is blocked from switching to DONE. + +If you need more complex dependency structures, for example +dependencies between entries in different trees or files, check out +the contributed module =org-depend.el=. + +** Progress Logging +:PROPERTIES: +:DESCRIPTION: Dates and notes for progress. +:END: +#+cindex: progress logging +#+cindex: logging, of progress + +To record a timestamp and a note when changing a TODO state, call the +command ~org-todo~ with a prefix argument. + +- {{{kbd(C-u C-c C-t)}}} (~org-todo~) :: + + #+kindex: C-u C-c C-t + Prompt for a note and record a the time of the TODO state change. + The note is inserted as a list item below the headline, but can also + be placed into a drawer, see [[*Tracking TODO state changes]]. + +If you want to be more systematic, Org mode can automatically record a +timestamp and optionally a note when you mark a TODO item as DONE, or +even each time you change the state of a TODO item. This system is +highly configurable, settings can be on a per-keyword basis and can be +localized to a file or even a subtree. For information on how to +clock working time for a task, see [[*Clocking Work Time]]. + +*** Closing items +:PROPERTIES: +:DESCRIPTION: When was this entry marked as done? +:END: + +The most basic automatic logging is to keep track of /when/ a certain +TODO item was marked as done. This can be achieved with[fn:41] + +#+begin_src emacs-lisp +(setq org-log-done 'time) +#+end_src + +#+vindex: org-closed-keep-when-no-todo +#+texinfo: @noindent +Then each time you turn an entry from a TODO (not-done) state into any +of the DONE states, a line =CLOSED: [timestamp]= is inserted just +after the headline. If you turn the entry back into a TODO item +through further state cycling, that line is removed again. If you +turn the entry back to a non-TODO state (by pressing {{{kbd(C-c C-t +SPC)}}} for example), that line is also removed, unless you set +~org-closed-keep-when-no-todo~ to non-~nil~. If you want to record +a note along with the timestamp, use[fn:42] + +#+begin_src emacs-lisp +(setq org-log-done 'note) +#+end_src + +#+texinfo: @noindent +You are then prompted for a note, and that note is stored below the +entry with a =Closing Note= heading. + +*** Tracking TODO state changes +:PROPERTIES: +:DESCRIPTION: When did the status change? +:END: +#+cindex: drawer, for state change recording + +#+vindex: org-log-states-order-reversed +#+vindex: org-log-into-drawer +#+cindex: @samp{LOG_INTO_DRAWER}, property +You might want to automatically keep track of when a state change +occurred and maybe take a note about this change. You can either +record just a timestamp, or a time-stamped note. These records are +inserted after the headline as an itemized list, newest first[fn:43]. +When taking a lot of notes, you might want to get the notes out of the +way into a drawer (see [[*Drawers]]). Customize the variable +~org-log-into-drawer~ to get this behavior---the recommended drawer +for this is called =LOGBOOK=[fn:44]. You can also overrule the +setting of this variable for a subtree by setting a =LOG_INTO_DRAWER= +property. + +Since it is normally too much to record a note for every state, Org +mode expects configuration on a per-keyword basis for this. This is +achieved by adding special markers =!= (for a timestamp) or =@= (for +a note with timestamp) in parentheses after each keyword. For +example, with the setting + +#+begin_src emacs-lisp +(setq org-todo-keywords + '((sequence "TODO(t)" "WAIT(w@/!)" "|" "DONE(d!)" "CANCELED(c@)"))) +#+end_src + +#+texinfo: @noindent +To record a timestamp without a note for TODO keywords configured with +=@=, just type {{{kbd(C-c C-c)}}} to enter a blank note when prompted. + +#+vindex: org-log-done +You not only define global TODO keywords and fast access keys, but +also request that a time is recorded when the entry is set to =DONE=, +and that a note is recorded when switching to =WAIT= or +=CANCELED=[fn:45]. The setting for =WAIT= is even more special: the +=!= after the slash means that in addition to the note taken when +entering the state, a timestamp should be recorded when /leaving/ the +=WAIT= state, if and only if the /target/ state does not configure +logging for entering it. So it has no effect when switching from +=WAIT= to =DONE=, because =DONE= is configured to record a timestamp +only. But when switching from =WAIT= back to =TODO=, the =/!= in the +=WAIT= setting now triggers a timestamp even though =TODO= has no +logging configured. + +You can use the exact same syntax for setting logging preferences local +to a buffer: + +: #+TODO: TODO(t) WAIT(w@/!) | DONE(d!) CANCELED(c@) + +#+cindex: @samp{LOGGING}, property +In order to define logging settings that are local to a subtree or +a single item, define a =LOGGING= property in this entry. Any +non-empty =LOGGING= property resets all logging settings to ~nil~. +You may then turn on logging for this specific tree using =STARTUP= +keywords like =lognotedone= or =logrepeat=, as well as adding state +specific settings like =TODO(!)=. For example: + +#+begin_example +,* TODO Log each state with only a time + :PROPERTIES: + :LOGGING: TODO(!) WAIT(!) DONE(!) CANCELED(!) + :END: +,* TODO Only log when switching to WAIT, and when repeating + :PROPERTIES: + :LOGGING: WAIT(@) logrepeat + :END: +,* TODO No logging at all + :PROPERTIES: + :LOGGING: nil + :END: +#+end_example + +*** Tracking your habits +:PROPERTIES: +:DESCRIPTION: How consistent have you been? +:END: +#+cindex: habits +#+cindex: @samp{STYLE}, property + +Org has the ability to track the consistency of a special category of +TODO, called "habits." To use habits, you have to enable the ~habits~ +module by customizing the variable ~org-modules~. + +A habit has the following properties: + +1. The habit is a TODO item, with a TODO keyword representing an open + state. + +2. The property =STYLE= is set to the value =habit= (see [[*Properties + and Columns]]). + +3. The TODO has a scheduled date, usually with a =.+= style repeat + interval. A =++= style may be appropriate for habits with time + constraints, e.g., must be done on weekends, or a =+= style for an + unusual habit that can have a backlog, e.g., weekly reports. + +4. The TODO may also have minimum and maximum ranges specified by + using the syntax =.+2d/3d=, which says that you want to do the task + at least every three days, but at most every two days. + +5. State logging for the DONE state is enabled (see [[*Tracking TODO + state changes]]), in order for historical data to be represented in + the consistency graph. If it is not enabled it is not an error, + but the consistency graphs are largely meaningless. + +To give you an idea of what the above rules look like in action, here's an +actual habit with some history: + +#+begin_example +,** TODO Shave + SCHEDULED: <2009-10-17 Sat .+2d/4d> + :PROPERTIES: + :STYLE: habit + :LAST_REPEAT: [2009-10-19 Mon 00:36] + :END: + - State "DONE" from "TODO" [2009-10-15 Thu] + - State "DONE" from "TODO" [2009-10-12 Mon] + - State "DONE" from "TODO" [2009-10-10 Sat] + - State "DONE" from "TODO" [2009-10-04 Sun] + - State "DONE" from "TODO" [2009-10-02 Fri] + - State "DONE" from "TODO" [2009-09-29 Tue] + - State "DONE" from "TODO" [2009-09-25 Fri] + - State "DONE" from "TODO" [2009-09-19 Sat] + - State "DONE" from "TODO" [2009-09-16 Wed] + - State "DONE" from "TODO" [2009-09-12 Sat] +#+end_example + +What this habit says is: I want to shave at most every 2 days---given +by the =SCHEDULED= date and repeat interval---and at least every +4 days. If today is the 15th, then the habit first appears in the +agenda (see [[*Agenda Views]]) on Oct 17, after the minimum of 2 days has +elapsed, and will appear overdue on Oct 19, after four days have +elapsed. + +What's really useful about habits is that they are displayed along +with a consistency graph, to show how consistent you've been at +getting that task done in the past. This graph shows every day that +the task was done over the past three weeks, with colors for each day. +The colors used are: + +- Blue :: If the task was not to be done yet on that day. +- Green :: If the task could have been done on that day. +- Yellow :: If the task was going to be overdue the next day. +- Red :: If the task was overdue on that day. + +In addition to coloring each day, the day is also marked with an +asterisk if the task was actually done that day, and an exclamation +mark to show where the current day falls in the graph. + +There are several configuration variables that can be used to change +the way habits are displayed in the agenda. + +- ~org-habit-graph-column~ :: + + #+vindex: org-habit-graph-column + The buffer column at which the consistency graph should be drawn. + This overwrites any text in that column, so it is a good idea to + keep your habits' titles brief and to the point. + +- ~org-habit-preceding-days~ :: + + #+vindex: org-habit-preceding-days + The amount of history, in days before today, to appear in + consistency graphs. + +- ~org-habit-following-days~ :: + + #+vindex: org-habit-following-days + The number of days after today that appear in consistency graphs. + +- ~org-habit-show-habits-only-for-today~ :: + + #+vindex: org-habit-show-habits-only-for-today + If non-~nil~, only show habits in today's agenda view. The default + value is ~t~. Pressing {{{kbd(C-u K)}}} in the agenda toggles this + variable. + +Lastly, pressing {{{kbd(K)}}} in the agenda buffer causes habits to +temporarily be disabled and do not appear at all. Press {{{kbd(K)}}} +again to bring them back. They are also subject to tag filtering, if +you have habits which should only be done in certain contexts, for +example. + +** Priorities +:PROPERTIES: +:DESCRIPTION: Some things are more important than others. +:END: +#+cindex: priorities +#+cindex: priority cookie + +If you use Org mode extensively, you may end up with enough TODO items +that it starts to make sense to prioritize them. Prioritizing can be +done by placing a /priority cookie/ into the headline of a TODO item +right after the TODO keyword, like this: + +: *** TODO [#A] Write letter to Sam Fortune + +#+vindex: org-priority-faces +By default, Org mode supports three priorities: =A=, =B=, and =C=. +=A= is the highest priority. An entry without a cookie is treated as +equivalent if it had priority =B=. Priorities make a difference only +for sorting in the agenda (see [[*Weekly/daily agenda]]). Outside the +agenda, they have no inherent meaning to Org mode. The cookies are +displayed with the face defined by the variable ~org-priority-faces~, +which can be customized. + +You can also use numeric values for priorities, such as + +: *** TODO [#1] Write letter to Sam Fortune + +When using numeric priorities, you need to set ~org-priority-highest~, +~org-priority-lowest~ and ~org-priority-default~ to integers, which +must all be strictly inferior to 65. + +Priorities can be attached to any outline node; they do not need to be +TODO items. + +#+attr_texinfo: :sep ; +- {{{kbd(C-c \,)}}} (~org-priority~) :: + + #+kindex: C-c , + #+findex: org-priority + Set the priority of the current headline. The command prompts for + a priority character =A=, =B= or =C=. When you press {{{kbd(SPC)}}} + instead, the priority cookie, if one is set, is removed from the + headline. The priorities can also be changed "remotely" from the + agenda buffer with the {{{kbd(\,)}}} command (see [[*Commands in the + Agenda Buffer]]). + +- {{{kbd(S-UP)}}} (~org-priority-up~); {{{kbd(S-DOWN)}}} (~org-priority-down~) :: + + #+kindex: S-UP + #+kindex: S-DOWN + #+findex: org-priority-up + #+findex: org-priority-down + #+vindex: org-priority-start-cycle-with-default + Increase/decrease the priority of the current headline[fn:46]. Note + that these keys are also used to modify timestamps (see [[*Creating + Timestamps]]). See also [[*Packages that conflict with Org mode]], for + a discussion of the interaction with shift-selection. + +#+vindex: org-priority-highest +#+vindex: org-priority-lowest +#+vindex: org-priority-default +You can change the range of allowed priorities by setting the +variables ~org-priority-highest~, ~org-priority-lowest~, and +~org-priority-default~. For an individual buffer, you may set these +values (highest, lowest, default) like this (please make sure that the +highest priority is earlier in the alphabet than the lowest priority): + +#+cindex: @samp{PRIORITIES}, keyword +: #+PRIORITIES: A C B + +Or, using numeric values: + +: #+PRIORITIES: 1 10 5 + +** Breaking Down Tasks into Subtasks +:PROPERTIES: +:DESCRIPTION: Splitting a task into manageable pieces. +:ALT_TITLE: Breaking Down Tasks +:END: +#+cindex: tasks, breaking down +#+cindex: statistics, for TODO items + +#+vindex: org-agenda-todo-list-sublevels +It is often advisable to break down large tasks into smaller, +manageable subtasks. You can do this by creating an outline tree +below a TODO item, with detailed subtasks on the tree[fn:47]. To keep +an overview of the fraction of subtasks that have already been marked +as done, insert either =[/]= or =[%]= anywhere in the headline. These +cookies are updated each time the TODO status of a child changes, or +when pressing {{{kbd(C-c C-c)}}} on the cookie. For example: + +#+begin_example +,* Organize Party [33%] +,** TODO Call people [1/2] +,*** TODO Peter +,*** DONE Sarah +,** TODO Buy food +,** DONE Talk to neighbor +#+end_example + +#+cindex: @samp{COOKIE_DATA}, property +If a heading has both checkboxes and TODO children below it, the +meaning of the statistics cookie become ambiguous. Set the property +=COOKIE_DATA= to either =checkbox= or =todo= to resolve this issue. + +#+vindex: org-hierarchical-todo-statistics +If you would like to have the statistics cookie count any TODO entries +in the subtree (not just direct children), configure the variable +~org-hierarchical-todo-statistics~. To do this for a single subtree, +include the word =recursive= into the value of the =COOKIE_DATA= +property. + +#+begin_example org +,* Parent capturing statistics [2/20] + :PROPERTIES: + :COOKIE_DATA: todo recursive + :END: +#+end_example + +If you would like a TODO entry to automatically change to DONE when +all children are done, you can use the following setup: + +#+begin_src emacs-lisp +(defun org-summary-todo (n-done n-not-done) + "Switch entry to DONE when all subentries are done, to TODO otherwise." + (let (org-log-done org-log-states) ; turn off logging + (org-todo (if (= n-not-done 0) "DONE" "TODO")))) + +(add-hook 'org-after-todo-statistics-hook 'org-summary-todo) +#+end_src + +Another possibility is the use of checkboxes to identify (a hierarchy +of) a large number of subtasks (see [[*Checkboxes]]). + +** Checkboxes +:PROPERTIES: +:DESCRIPTION: Tick-off lists. +:END: +#+cindex: checkboxes + +#+vindex: org-list-automatic-rules +Every item in a plain list[fn:48] (see [[*Plain Lists]]) can be made into +a checkbox by starting it with the string =[ ]=. This feature is +similar to TODO items (see [[*TODO Items]]), but is more lightweight. +Checkboxes are not included into the global TODO list, so they are +often great to split a task into a number of simple steps. Or you can +use them in a shopping list. + +Here is an example of a checkbox list. + +#+begin_example +,* TODO Organize party [2/4] + - [-] call people [1/3] + - [ ] Peter + - [X] Sarah + - [ ] Sam + - [X] order food + - [ ] think about what music to play + - [X] talk to the neighbors +#+end_example + +Checkboxes work hierarchically, so if a checkbox item has children +that are checkboxes, toggling one of the children checkboxes makes the +parent checkbox reflect if none, some, or all of the children are +checked. + +#+cindex: statistics, for checkboxes +#+cindex: checkbox statistics +#+cindex: @samp{COOKIE_DATA}, property +#+vindex: org-hierarchical-checkbox-statistics +The =[2/4]= and =[1/3]= in the first and second line are cookies +indicating how many checkboxes present in this entry have been checked +off, and the total number of checkboxes present. This can give you an +idea on how many checkboxes remain, even without opening a folded +entry. The cookies can be placed into a headline or into (the first +line of) a plain list item. Each cookie covers checkboxes of direct +children structurally below the headline/item on which the cookie +appears[fn:49]. You have to insert the cookie yourself by typing +either =[/]= or =[%]=. With =[/]= you get an =n out of m= result, as +in the examples above. With =[%]= you get information about the +percentage of checkboxes checked (in the above example, this would be +=[50%]= and =[33%]=, respectively). In a headline, a cookie can count +either checkboxes below the heading or TODO states of children, and it +displays whatever was changed last. Set the property =COOKIE_DATA= to +either =checkbox= or =todo= to resolve this issue. + +#+cindex: blocking, of checkboxes +#+cindex: checkbox blocking +#+cindex: @samp{ORDERED}, property +If the current outline node has an =ORDERED= property, checkboxes must +be checked off in sequence, and an error is thrown if you try to check +off a box while there are unchecked boxes above it. + +The following commands work with checkboxes: + +- {{{kbd(C-c C-c)}}} (~org-toggle-checkbox~) :: + + #+kindex: C-c C-c + #+findex: org-toggle-checkbox + Toggle checkbox status or---with prefix argument---checkbox presence + at point. With a single prefix argument, add an empty checkbox or + remove the current one[fn:50]. With a double prefix argument, set + it to =[-]=, which is considered to be an intermediate state. + +- {{{kbd(C-c C-x C-b)}}} (~org-toggle-checkbox~) :: + + #+kindex: C-c C-x C-b + Toggle checkbox status or---with prefix argument---checkbox presence + at point. With double prefix argument, set it to =[-]=, which is + considered to be an intermediate state. + + - If there is an active region, toggle the first checkbox in the + region and set all remaining boxes to the same status as the + first. With a prefix argument, add or remove the checkbox for all + items in the region. + + - If point is in a headline, toggle checkboxes in the region between + this headline and the next---so /not/ the entire subtree. + + - If there is no active region, just toggle the checkbox at point. + +- {{{kbd(C-c C-x C-r)}}} (~org-toggle-radio-button~) :: + + #+kindex: C-c C-x C-r + #+findex: org-toggle-radio-button + #+cindex: radio button, checkbox as + Toggle checkbox status by using the checkbox of the item at point as + a radio button: when the checkbox is turned on, all other checkboxes + on the same level will be turned off. With a universal prefix + argument, toggle the presence of the checkbox. With a double prefix + argument, set it to =[-]=. + + #+findex: org-list-checkbox-radio-mode + {{{kbd(C-c C-c)}}} can be told to consider checkboxes as radio buttons by + setting =#+ATTR_ORG: :radio t= right before the list or by calling + {{{kbd(M-x org-list-checkbox-radio-mode)}}} to activate this minor mode. + +- {{{kbd(M-S-RET)}}} (~org-insert-todo-heading~) :: + + #+kindex: M-S-RET + #+findex: org-insert-todo-heading + Insert a new item with a checkbox. This works only if point is + already in a plain list item (see [[*Plain Lists]]). + +- {{{kbd(C-c C-x o)}}} (~org-toggle-ordered-property~) :: + + #+kindex: C-c C-x o + #+findex: org-toggle-ordered-property + #+vindex: org-track-ordered-property-with-tag + Toggle the =ORDERED= property of the entry, to toggle if checkboxes + must be checked off in sequence. A property is used for this + behavior because this should be local to the current entry, not + inherited like a tag. However, if you would like to /track/ the + value of this property with a tag for better visibility, customize + ~org-track-ordered-property-with-tag~. + +- {{{kbd(C-c #)}}} (~org-update-statistics-cookies~) :: + + #+kindex: C-c # + #+findex: org-update-statistics-cookies + Update the statistics cookie in the current outline entry. When + called with a {{{kbd(C-u)}}} prefix, update the entire file. + Checkbox statistic cookies are updated automatically if you toggle + checkboxes with {{{kbd(C-c C-c)}}} and make new ones with + {{{kbd(M-S-RET)}}}. TODO statistics cookies update when changing + TODO states. If you delete boxes/entries or add/change them by + hand, use this command to get things back into sync. + +* Tags +:PROPERTIES: +:DESCRIPTION: Tagging headlines and matching sets of tags. +:END: +#+cindex: tags +#+cindex: headline tagging +#+cindex: matching, tags +#+cindex: sparse tree, tag based + +An excellent way to implement labels and contexts for +cross-correlating information is to assign /tags/ to headlines. Org +mode has extensive support for tags. + +#+vindex: org-tag-faces +Every headline can contain a list of tags; they occur at the end of +the headline. Tags are normal words containing letters, numbers, =_=, +and =@=. Tags must be preceded and followed by a single colon, e.g., +=:work:=. Several tags can be specified, as in =:work:urgent:=. Tags +by default are in bold face with the same color as the headline. You +may specify special faces for specific tags using the variable +~org-tag-faces~, in much the same way as you can for TODO keywords +(see [[*Faces for TODO keywords]]). + +** Tag Inheritance +:PROPERTIES: +:DESCRIPTION: Tags use the tree structure of an outline. +:END: +#+cindex: tag inheritance +#+cindex: inheritance, of tags +#+cindex: sublevels, inclusion into tags match + +/Tags/ make use of the hierarchical structure of outline trees. If +a heading has a certain tag, all subheadings inherit the tag as well. +For example, in the list + +#+begin_example +,* Meeting with the French group :work: +,** Summary by Frank :boss:notes: +,*** TODO Prepare slides for him :action: +#+end_example + +#+texinfo: @noindent +the final heading has the tags =work=, =boss=, =notes=, and =action= +even though the final heading is not explicitly marked with those +tags. You can also set tags that all entries in a file should inherit +just as if these tags were defined in a hypothetical level zero that +surrounds the entire file. Use a line like this[fn:51] + +#+cindex: @samp{FILETAGS}, keyword +: #+FILETAGS: :Peter:Boss:Secret: + +#+vindex: org-use-tag-inheritance +#+vindex: org-tags-exclude-from-inheritance +To limit tag inheritance to specific tags, or to turn it off entirely, +use the variables ~org-use-tag-inheritance~ and +~org-tags-exclude-from-inheritance~. + +#+vindex: org-tags-match-list-sublevels +When a headline matches during a tags search while tag inheritance is +turned on, all the sublevels in the same tree---for a simple match +form---match as well[fn:52]. The list of matches may then become +very long. If you only want to see the first tags match in a subtree, +configure the variable ~org-tags-match-list-sublevels~ (not +recommended). + +#+vindex: org-agenda-use-tag-inheritance +Tag inheritance is relevant when the agenda search tries to match +a tag, either in the ~tags~ or ~tags-todo~ agenda types. In other +agenda types, ~org-use-tag-inheritance~ has no effect. Still, you may +want to have your tags correctly set in the agenda, so that tag +filtering works fine, with inherited tags. Set +~org-agenda-use-tag-inheritance~ to control this: the default value +includes all agenda types, but setting this to ~nil~ can really speed +up agenda generation. + +** Setting Tags +:PROPERTIES: +:DESCRIPTION: How to assign tags to a headline. +:END: +#+cindex: setting tags +#+cindex: tags, setting + +#+kindex: M-TAB +Tags can simply be typed into the buffer at the end of a headline. +After a colon, {{{kbd(M-TAB)}}} offers completion on tags. There is +also a special command for inserting tags: + +- {{{kbd(C-c C-q)}}} (~org-set-tags-command~) :: + + #+kindex: C-c C-q + #+findex: org-set-tags-command + #+cindex: completion, of tags + #+vindex: org-tags-column + Enter new tags for the current headline. Org mode either offers + completion or a special single-key interface for setting tags, see + below. After pressing {{{kbd(RET)}}}, the tags are inserted and + aligned to ~org-tags-column~. When called with a {{{kbd(C-u)}}} + prefix, all tags in the current buffer are aligned to that column, + just to make things look nice. Tags are automatically realigned + after promotion, demotion, and TODO state changes (see [[*Basic TODO + Functionality]]). + +- {{{kbd(C-c C-c)}}} (~org-set-tags-command~) :: + + #+kindex: C-c C-c + When point is in a headline, this does the same as {{{kbd(C-c + C-q)}}}. + +#+vindex: org-complete-tags-always-offer-all-agenda-tags +#+vindex: org-tag-alist +#+cindex: @samp{TAGS}, keyword +Org supports tag insertion based on a /list of tags/. By default this +list is constructed dynamically, containing all tags currently used in +the buffer[fn:53]. You may also globally specify a hard list of tags +with the variable ~org-tag-alist~. Finally you can set the default +tags for a given file using the =TAGS= keyword, like + +#+begin_example +,#+TAGS: @work @home @tennisclub +,#+TAGS: laptop car pc sailboat +#+end_example + +If you have globally defined your preferred set of tags using the +variable ~org-tag-alist~, but would like to use a dynamic tag list in +a specific file, add an empty =TAGS= keyword to that file: + +: #+TAGS: + +#+vindex: org-tag-persistent-alist +If you have a preferred set of tags that you would like to use in +every file, in addition to those defined on a per-file basis by =TAGS= +keyword, then you may specify a list of tags with the variable +~org-tag-persistent-alist~. You may turn this off on a per-file basis +by adding a =STARTUP= keyword to that file: + +: #+STARTUP: noptag + +By default Org mode uses the standard minibuffer completion facilities +for entering tags. However, it also implements another, quicker, tag +selection method called /fast tag selection/. This allows you to +select and deselect tags with just a single key press. For this to +work well you should assign unique letters to most of your commonly +used tags. You can do this globally by configuring the variable +~org-tag-alist~ in your Emacs init file. For example, you may find +the need to tag many items in different files with =@home=. In this +case you can set something like: + +#+begin_src emacs-lisp +(setq org-tag-alist '(("@work" . ?w) ("@home" . ?h) ("laptop" . ?l))) +#+end_src + +If the tag is only relevant to the file you are working on, then you +can instead set the =TAGS= keyword as: + +: #+TAGS: @work(w) @home(h) @tennisclub(t) laptop(l) pc(p) + +The tags interface shows the available tags in a splash window. If +you want to start a new line after a specific tag, insert =\n= into +the tag list + +: #+TAGS: @work(w) @home(h) @tennisclub(t) \n laptop(l) pc(p) + +#+texinfo: @noindent +or write them in two lines: + +#+begin_example +,#+TAGS: @work(w) @home(h) @tennisclub(t) +,#+TAGS: laptop(l) pc(p) +#+end_example + +You can also group together tags that are mutually exclusive by using +braces, as in: + +: #+TAGS: { @work(w) @home(h) @tennisclub(t) } laptop(l) pc(p) + +#+texinfo: @noindent +you indicate that at most one of =@work=, =@home=, and =@tennisclub= +should be selected. Multiple such groups are allowed. + +Do not forget to press {{{kbd(C-c C-c)}}} with point in one of these +lines to activate any changes. + +To set these mutually exclusive groups in the variable +~org-tags-alist~, you must use the dummy tags ~:startgroup~ and +~:endgroup~ instead of the braces. Similarly, you can use ~:newline~ +to indicate a line break. The previous example would be set globally +by the following configuration: + +#+begin_src emacs-lisp +(setq org-tag-alist '((:startgroup . nil) + ("@work" . ?w) ("@home" . ?h) + ("@tennisclub" . ?t) + (:endgroup . nil) + ("laptop" . ?l) ("pc" . ?p))) +#+end_src + +If at least one tag has a selection key then pressing {{{kbd(C-c +C-c)}}} automatically presents you with a special interface, listing +inherited tags, the tags of the current headline, and a list of all +valid tags with corresponding keys[fn:54]. + +Pressing keys assigned to tags adds or removes them from the list of +tags in the current line. Selecting a tag in a group of mutually +exclusive tags turns off any other tag from that group. + +In this interface, you can also use the following special keys: + +- {{{kbd(TAB)}}} :: + + #+kindex: TAB + Enter a tag in the minibuffer, even if the tag is not in the + predefined list. You can complete on all tags present in the + buffer. You can also add several tags: just separate them with + a comma. + +- {{{kbd(SPC)}}} :: + + #+kindex: SPC + Clear all tags for this line. + +- {{{kbd(RET)}}} :: + + #+kindex: RET + Accept the modified set. + +- {{{kbd(C-g)}}} :: + + #+kindex: C-g + Abort without installing changes. + +- {{{kbd(q)}}} :: + + #+kindex: q + If {{{kbd(q)}}} is not assigned to a tag, it aborts like + {{{kbd(C-g)}}}. + +- {{{kbd(!)}}} :: + + #+kindex: ! + Turn off groups of mutually exclusive tags. Use this to (as an + exception) assign several tags from such a group. + +- {{{kbd(C-c)}}} :: + + #+kindex: C-c C-c + Toggle auto-exit after the next change (see below). If you are + using expert mode, the first {{{kbd(C-c)}}} displays the selection + window. + +This method lets you assign tags to a headline with very few keys. +With the above setup, you could clear the current tags and set +=@home=, =laptop= and =pc= tags with just the following keys: +{{{kbd(C-c C-c SPC h l p RET)}}}. Switching from =@home= to =@work= +would be done with {{{kbd(C-c C-c w RET)}}} or alternatively with +{{{kbd(C-c C-c C-c w)}}}. Adding the non-predefined tag =sarah= could +be done with {{{kbd(C-c C-c TAB s a r a h RET)}}}. + +#+vindex: org-fast-tag-selection-single-key +If you find that most of the time you need only a single key press to +modify your list of tags, set the variable +~org-fast-tag-selection-single-key~. Then you no longer have to press +{{{kbd(RET)}}} to exit fast tag selection---it exits after the first +change. If you then occasionally need more keys, press {{{kbd(C-c)}}} +to turn off auto-exit for the current tag selection process (in +effect: start selection with {{{kbd(C-c C-c C-c)}}} instead of +{{{kbd(C-c C-c)}}}). If you set the variable to the value ~expert~, +the special window is not even shown for single-key tag selection, it +comes up only when you press an extra {{{kbd(C-c)}}}. + +** Tag Hierarchy +:PROPERTIES: +:DESCRIPTION: Create a hierarchy of tags. +:END: +#+cindex: group tags +#+cindex: tags, groups +#+cindex: tags hierarchy + +Tags can be defined in hierarchies. A tag can be defined as a /group +tag/ for a set of other tags. The group tag can be seen as the +"broader term" for its set of tags. Defining multiple group tags and +nesting them creates a tag hierarchy. + +One use-case is to create a taxonomy of terms (tags) that can be used +to classify nodes in a document or set of documents. + +When you search for a group tag, it return matches for all members in +the group and its subgroups. In an agenda view, filtering by a group +tag displays or hide headlines tagged with at least one of the members +of the group or any of its subgroups. This makes tag searches and +filters even more flexible. + +You can set group tags by using brackets and inserting a colon between +the group tag and its related tags---beware that all whitespaces are +mandatory so that Org can parse this line correctly: + +: #+TAGS: [ GTD : Control Persp ] + +In this example, =GTD= is the group tag and it is related to two other +tags: =Control=, =Persp=. Defining =Control= and =Persp= as group +tags creates a hierarchy of tags: + +#+begin_example +,#+TAGS: [ Control : Context Task ] +,#+TAGS: [ Persp : Vision Goal AOF Project ] +#+end_example + +That can conceptually be seen as a hierarchy of tags: + +- =GTD= + - =Persp= + - =Vision= + - =Goal= + - =AOF= + - =Project= + - =Control= + - =Context= + - =Task= + +You can use the ~:startgrouptag~, ~:grouptags~ and ~:endgrouptag~ +keyword directly when setting ~org-tag-alist~ directly: + +#+begin_src emacs-lisp +(setq org-tag-alist '((:startgrouptag) + ("GTD") + (:grouptags) + ("Control") + ("Persp") + (:endgrouptag) + (:startgrouptag) + ("Control") + (:grouptags) + ("Context") + ("Task") + (:endgrouptag))) +#+end_src + +The tags in a group can be mutually exclusive if using the same group +syntax as is used for grouping mutually exclusive tags together; using +curly brackets. + +: #+TAGS: { Context : @Home @Work @Call } + +When setting ~org-tag-alist~ you can use ~:startgroup~ and ~:endgroup~ +instead of ~:startgrouptag~ and ~:endgrouptag~ to make the tags +mutually exclusive. + +Furthermore, the members of a group tag can also be regular +expressions, creating the possibility of a more dynamic and rule-based +tag structure. The regular expressions in the group must be specified +within curly brackets. Here is an expanded example: + +#+begin_example +,#+TAGS: [ Vision : {V@.+} ] +,#+TAGS: [ Goal : {G@.+} ] +,#+TAGS: [ AOF : {AOF@.+} ] +,#+TAGS: [ Project : {P@.+} ] +#+end_example + +Searching for the tag =Project= now lists all tags also including +regular expression matches for =P@.+=, and similarly for tag searches +on =Vision=, =Goal= and =AOF=. For example, this would work well for +a project tagged with a common project-identifier, e.g., +=P@2014_OrgTags=. + +#+kindex: C-c C-x q +#+findex: org-toggle-tags-groups +#+vindex: org-group-tags +If you want to ignore group tags temporarily, toggle group tags +support with ~org-toggle-tags-groups~, bound to {{{kbd(C-c C-x q)}}}. +If you want to disable tag groups completely, set ~org-group-tags~ to +~nil~. + +** Tag Searches +:PROPERTIES: +:DESCRIPTION: Searching for combinations of tags. +:END: +#+cindex: tag searches +#+cindex: searching for tags + +Once a system of tags has been set up, it can be used to collect +related information into special lists. + +- {{{kbd(C-c / m)}}} or {{{kbd(C-c \)}}} (~org-match-sparse-tree~) :: + + #+kindex: C-c / m + #+kindex: C-c \ + #+findex: org-match-sparse-tree + Create a sparse tree with all headlines matching a tags search. + With a {{{kbd(C-u)}}} prefix argument, ignore headlines that are not + a TODO line. + +- {{{kbd(M-x org-agenda m)}}} (~org-tags-view~) :: + + #+kindex: m @r{(Agenda dispatcher)} + #+findex: org-tags-view + Create a global list of tag matches from all agenda files. See + [[*Matching tags and properties]]. + +- {{{kbd(M-x org-agenda M)}}} (~org-tags-view~) :: + + #+kindex: M @r{(Agenda dispatcher)} + #+vindex: org-tags-match-list-sublevels + Create a global list of tag matches from all agenda files, but check + only TODO items and force checking subitems (see the option + ~org-tags-match-list-sublevels~). + +These commands all prompt for a match string which allows basic +Boolean logic like =+boss+urgent-project1=, to find entries with tags +=boss= and =urgent=, but not =project1=, or =Kathy|Sally= to find +entries which are tagged, like =Kathy= or =Sally=. The full syntax of +the search string is rich and allows also matching against TODO +keywords, entry levels and properties. For a complete description +with many examples, see [[*Matching tags and properties]]. + +* Properties and Columns +:PROPERTIES: +:DESCRIPTION: Storing information about an entry. +:END: +#+cindex: properties + +A property is a key-value pair associated with an entry. Properties +can be set so they are associated with a single entry, with every +entry in a tree, or with the whole buffer. + +There are two main applications for properties in Org mode. First, +properties are like tags, but with a value. Imagine maintaining +a file where you document bugs and plan releases for a piece of +software. Instead of using tags like =release_1=, =release_2=, you +can use a property, say =Release=, that in different subtrees has +different values, such as =1.0= or =2.0=. Second, you can use +properties to implement (very basic) database capabilities in an Org +buffer. Imagine keeping track of your music CDs, where properties +could be things such as the album, artist, date of release, number of +tracks, and so on. + +Properties can be conveniently edited and viewed in column view (see +[[*Column View]]). + +** Property Syntax +:PROPERTIES: +:DESCRIPTION: How properties are spelled out. +:END: +#+cindex: property syntax +#+cindex: drawer, for properties + +Properties are key--value pairs. When they are associated with +a single entry or with a tree they need to be inserted into a special +drawer (see [[*Drawers]]) with the name =PROPERTIES=, which has to be +located right below a headline, and its planning line (see [[*Deadlines +and Scheduling]]) when applicable. Each property is specified on +a single line, with the key---surrounded by colons---first, and the +value after it. Keys are case-insensitive. Here is an example: + +#+begin_example +,* CD collection +,** Classic +,*** Goldberg Variations + :PROPERTIES: + :Title: Goldberg Variations + :Composer: J.S. Bach + :Artist: Glenn Gould + :Publisher: Deutsche Grammophon + :NDisks: 1 + :END: +#+end_example + +Depending on the value of ~org-use-property-inheritance~, a property +set this way is associated either with a single entry, or with the +sub-tree defined by the entry, see [[*Property Inheritance]]. + +You may define the allowed values for a particular property =Xyz= by +setting a property =Xyz_ALL=. This special property is /inherited/, +so if you set it in a level 1 entry, it applies to the entire tree. +When allowed values are defined, setting the corresponding property +becomes easier and is less prone to typing errors. For the example +with the CD collection, we can pre-define publishers and the number of +disks in a box like this: + +#+begin_example +,* CD collection + :PROPERTIES: + :NDisks_ALL: 1 2 3 4 + :Publisher_ALL: "Deutsche Grammophon" Philips EMI + :END: +#+end_example + +Properties can be inserted on buffer level. That means they apply +before the first headline and can be inherited by all entries in a +file. Property blocks defined before first headline needs to be +located at the top of the buffer, allowing only comments above. + +Properties can also be defined using lines like: + +#+cindex: @samp{_ALL} suffix, in properties +#+cindex: @samp{PROPERTY}, keyword +: #+PROPERTY: NDisks_ALL 1 2 3 4 + +#+cindex: @samp{+} suffix, in properties +If you want to add to the value of an existing property, append a =+= +to the property name. The following results in the property =var= +having the value =foo=1 bar=2=. + +#+begin_example +,#+PROPERTY: var foo=1 +,#+PROPERTY: var+ bar=2 +#+end_example + +It is also possible to add to the values of inherited properties. The +following results in the =Genres= property having the value =Classic +Baroque= under the =Goldberg Variations= subtree. + +#+begin_example +,* CD collection +,** Classic + :PROPERTIES: + :Genres: Classic + :END: +,*** Goldberg Variations + :PROPERTIES: + :Title: Goldberg Variations + :Composer: J.S. Bach + :Artist: Glenn Gould + :Publisher: Deutsche Grammophon + :NDisks: 1 + :Genres+: Baroque + :END: +#+end_example + +Note that a property can only have one entry per drawer. + +#+vindex: org-global-properties +Property values set with the global variable ~org-global-properties~ +can be inherited by all entries in all Org files. + +The following commands help to work with properties: + +#+attr_texinfo: :sep , +- {{{kbd(M-TAB)}}} (~pcomplete~) :: + + #+kindex: M-TAB + #+findex: pcomplete + After an initial colon in a line, complete property keys. All keys + used in the current file are offered as possible completions. + +- {{{kbd(C-c C-x p)}}} (~org-set-property~) :: + + #+kindex: C-c C-x p + #+findex: org-set-property + Set a property. This prompts for a property name and a value. If + necessary, the property drawer is created as well. + +- {{{kbd(C-u M-x org-insert-drawer)}}} :: + + #+findex: org-insert-drawer + Insert a property drawer into the current entry. The drawer is + inserted early in the entry, but after the lines with planning + information like deadlines. If before first headline the drawer is + inserted at the top of the drawer after any potential comments. + +- {{{kbd(C-c C-c)}}} (~org-property-action~) :: + + #+kindex: C-c C-c + #+findex: org-property-action + With point in a property drawer, this executes property commands. + +- {{{kbd(C-c C-c s)}}} (~org-set-property~) :: + + #+kindex: C-c C-c s + #+findex: org-set-property + Set a property in the current entry. Both the property and the + value can be inserted using completion. + +- {{{kbd(S-RIGHT)}}} (~org-property-next-allowed-values~), {{{kbd(S-LEFT)}}} (~org-property-previous-allowed-value~) :: + + #+kindex: S-RIGHT + #+kindex: S-LEFT + Switch property at point to the next/previous allowed value. + +- {{{kbd(C-c C-c d)}}} (~org-delete-property~) :: + + #+kindex: C-c C-c d + #+findex: org-delete-property + Remove a property from the current entry. + +- {{{kbd(C-c C-c D)}}} (~org-delete-property-globally~) :: + + #+kindex: C-c C-c D + #+findex: org-delete-property-globally + Globally remove a property, from all entries in the current file. + +- {{{kbd(C-c C-c c)}}} (~org-compute-property-at-point~) :: + + #+kindex: C-c C-c c + #+findex: org-compute-property-at-point + Compute the property at point, using the operator and scope from the + nearest column format definition. + +** Special Properties +:PROPERTIES: +:DESCRIPTION: Access to other Org mode features. +:END: +#+cindex: properties, special + +Special properties provide an alternative access method to Org mode +features, like the TODO state or the priority of an entry, discussed +in the previous chapters. This interface exists so that you can +include these states in a column view (see [[*Column View]]), or to use +them in queries. The following property names are special and should +not be used as keys in the properties drawer: + +#+cindex: @samp{ALLTAGS}, special property +#+cindex: @samp{BLOCKED}, special property +#+cindex: @samp{CLOCKSUM}, special property +#+cindex: @samp{CLOCKSUM_T}, special property +#+cindex: @samp{CLOSED}, special property +#+cindex: @samp{DEADLINE}, special property +#+cindex: @samp{FILE}, special property +#+cindex: @samp{ITEM}, special property +#+cindex: @samp{PRIORITY}, special property +#+cindex: @samp{SCHEDULED}, special property +#+cindex: @samp{TAGS}, special property +#+cindex: @samp{TIMESTAMP}, special property +#+cindex: @samp{TIMESTAMP_IA}, special property +#+cindex: @samp{TODO}, special property +| =ALLTAGS= | All tags, including inherited ones. | +| =BLOCKED= | ~t~ if task is currently blocked by children or siblings. | +| =CATEGORY= | The category of an entry. | +| =CLOCKSUM= | The sum of CLOCK intervals in the subtree. ~org-clock-sum~ | +| | must be run first to compute the values in the current buffer. | +| =CLOCKSUM_T= | The sum of CLOCK intervals in the subtree for today. | +| | ~org-clock-sum-today~ must be run first to compute the | +| | values in the current buffer. | +| =CLOSED= | When was this entry closed? | +| =DEADLINE= | The deadline timestamp. | +| =FILE= | The filename the entry is located in. | +| =ITEM= | The headline of the entry. | +| =PRIORITY= | The priority of the entry, a string with a single letter. | +| =SCHEDULED= | The scheduling timestamp. | +| =TAGS= | The tags defined directly in the headline. | +| =TIMESTAMP= | The first keyword-less timestamp in the entry. | +| =TIMESTAMP_IA= | The first inactive timestamp in the entry. | +| =TODO= | The TODO keyword of the entry. | + +** Property Searches +:PROPERTIES: +:DESCRIPTION: Matching property values. +:END: +#+cindex: properties, searching +#+cindex: searching, of properties + +To create sparse trees and special lists with selection based on +properties, the same commands are used as for tag searches (see [[*Tag +Searches]]). + +- {{{kbd(C-c / m)}}} or {{{kbd(C-c \)}}} (~org-match-sparse-tree~) :: + + #+kindex: C-c / m + #+kindex: C-c \ + #+findex: org-match-sparse-tree + Create a sparse tree with all matching entries. With + a {{{kbd(C-u)}}} prefix argument, ignore headlines that are not + a TODO line. + +- {{{kbd(M-x org-agenda m)}}} (~org-tags-view~) :: + + #+kindex: m @r{(Agenda dispatcher)} + #+findex: org-tags-view + Create a global list of tag/property matches from all agenda files. + +- {{{kbd(M-x org-agenda M)}}} (~org-tags-view~) :: + + #+kindex: M @r{(Agenda dispatcher)} + #+vindex: org-tags-match-list-sublevels + Create a global list of tag matches from all agenda files, but check + only TODO items and force checking of subitems (see the option + ~org-tags-match-list-sublevels~). + +The syntax for the search string is described in [[*Matching tags and +properties]]. + +There is also a special command for creating sparse trees based on a +single property: + +- {{{kbd(C-c / p)}}} :: + + #+kindex: C-c / p + Create a sparse tree based on the value of a property. This first + prompts for the name of a property, and then for a value. A sparse + tree is created with all entries that define this property with the + given value. If you enclose the value in curly braces, it is + interpreted as a regular expression and matched against the property + values. + +** Property Inheritance +:PROPERTIES: +:DESCRIPTION: Passing values down a tree. +:END: +#+cindex: properties, inheritance +#+cindex: inheritance, of properties + +#+vindex: org-use-property-inheritance +The outline structure of Org documents lends itself to an inheritance +model of properties: if the parent in a tree has a certain property, +the children can inherit this property. Org mode does not turn this +on by default, because it can slow down property searches +significantly and is often not needed. However, if you find +inheritance useful, you can turn it on by setting the variable +~org-use-property-inheritance~. It may be set to ~t~ to make all +properties inherited from the parent, to a list of properties that +should be inherited, or to a regular expression that matches inherited +properties. If a property has the value ~nil~, this is interpreted as +an explicit un-define of the property, so that inheritance search +stops at this value and returns ~nil~. + +Org mode has a few properties for which inheritance is hard-coded, at +least for the special applications for which they are used: + +- ~COLUMNS~ :: + + #+cindex: @samp{COLUMNS}, property + The =COLUMNS= property defines the format of column view (see + [[*Column View]]). It is inherited in the sense that the level where + a =COLUMNS= property is defined is used as the starting point for + a column view table, independently of the location in the subtree + from where columns view is turned on. + +- ~CATEGORY~ :: + + #+cindex: @samp{CATEGORY}, property + For agenda view, a category set through a =CATEGORY= property + applies to the entire subtree. + +- ~ARCHIVE~ :: + + #+cindex: @samp{ARCHIVE}, property + For archiving, the =ARCHIVE= property may define the archive + location for the entire subtree (see [[*Moving a tree to an archive + file]]). + +- ~LOGGING~ :: + + #+cindex: @samp{LOGGING}, property + The =LOGGING= property may define logging settings for an entry or + a subtree (see [[*Tracking TODO state changes]]). + +** Column View +:PROPERTIES: +:DESCRIPTION: Tabular viewing and editing. +:END: + +A great way to view and edit properties in an outline tree is /column +view/. In column view, each outline node is turned into a table row. +Columns in this table provide access to properties of the entries. +Org mode implements columns by overlaying a tabular structure over the +headline of each item. While the headlines have been turned into +a table row, you can still change the visibility of the outline tree. +For example, you get a compact table by switching to "contents" +view---{{{kbd(S-TAB)}}} {{{kbd(S-TAB)}}}, or simply {{{kbd(c)}}} +while column view is active---but you can still open, read, and edit +the entry below each headline. Or, you can switch to column view +after executing a sparse tree command and in this way get a table only +for the selected items. Column view also works in agenda buffers (see +[[*Agenda Views]]) where queries have collected selected items, possibly +from a number of files. + +*** Defining columns +:PROPERTIES: +:DESCRIPTION: The COLUMNS format property. +:END: +#+cindex: column view, for properties +#+cindex: properties, column view + +Setting up a column view first requires defining the columns. This is +done by defining a column format line. + +**** Scope of column definitions +:PROPERTIES: +:DESCRIPTION: Where defined, where valid? +:END: + +To specify a format that only applies to a specific tree, add +a =COLUMNS= property to the top node of that tree, for example: + +#+begin_example +,** Top node for columns view + :PROPERTIES: + :COLUMNS: %25ITEM %TAGS %PRIORITY %TODO + :END: +#+end_example + +A =COLUMNS= property within a property drawer before first headline +will apply to the entire file. As an addition to property drawers, +keywords can also be defined for an entire file using a line like: + +#+cindex: @samp{COLUMNS}, keyword +: #+COLUMNS: %25ITEM %TAGS %PRIORITY %TODO + +If a =COLUMNS= property is present in an entry, it defines columns for +the entry itself, and for the entire subtree below it. Since the +column definition is part of the hierarchical structure of the +document, you can define columns on level 1 that are general enough +for all sublevels, and more specific columns further down, when you +edit a deeper part of the tree. + +**** Column attributes +:PROPERTIES: +:DESCRIPTION: Appearance and content of a column. +:END: + +A column definition sets the attributes of a column. The general +definition looks like this: + +: %[WIDTH]PROPERTY[(TITLE)][{SUMMARY-TYPE}] + +#+texinfo: @noindent +Except for the percent sign and the property name, all items are +optional. The individual parts have the following meaning: + +- {{{var(WIDTH)}}} :: + + An integer specifying the width of the column in characters. If + omitted, the width is determined automatically. + +- {{{var(PROPERTY)}}} :: + + The property that should be edited in this column. Special + properties representing meta data are allowed here as well (see + [[*Special Properties]]). + +- {{{var(TITLE)}}} :: + + The header text for the column. If omitted, the property name is + used. + +- {{{var(SUMMARY-TYPE)}}} :: + + The summary type. If specified, the column values for parent nodes + are computed from the children[fn:55]. + + Supported summary types are: + + | =+= | Sum numbers in this column. | + | =+;%.1f= | Like =+=, but format result with =%.1f=. | + | =$= | Currency, short for =+;%.2f=. | + | =min= | Smallest number in column. | + | =max= | Largest number. | + | =mean= | Arithmetic mean of numbers. | + | =X= | Checkbox status, =[X]= if all children are =[X]=. | + | =X/= | Checkbox status, =[n/m]=. | + | =X%= | Checkbox status, =[n%]=. | + | =:= | Sum times, HH:MM, plain numbers are minutes. | + | =:min= | Smallest time value in column. | + | =:max= | Largest time value. | + | =:mean= | Arithmetic mean of time values. | + | =@min= | Minimum age[fn:56] (in days/hours/mins/seconds). | + | =@max= | Maximum age (in days/hours/mins/seconds). | + | =@mean= | Arithmetic mean of ages (in days/hours/mins/seconds). | + | =est+= | Add low-high estimates. | + + #+vindex: org-columns-summary-types + You can also define custom summary types by setting + ~org-columns-summary-types~. + +The =est+= summary type requires further explanation. It is used for +combining estimates, expressed as low-high ranges. For example, +instead of estimating a particular task will take 5 days, you might +estimate it as 5--6 days if you're fairly confident you know how much +work is required, or 1--10 days if you do not really know what needs +to be done. Both ranges average at 5.5 days, but the first represents +a more predictable delivery. + +When combining a set of such estimates, simply adding the lows and +highs produces an unrealistically wide result. Instead, =est+= adds +the statistical mean and variance of the subtasks, generating a final +estimate from the sum. For example, suppose you had ten tasks, each +of which was estimated at 0.5 to 2 days of work. Straight addition +produces an estimate of 5 to 20 days, representing what to expect if +everything goes either extremely well or extremely poorly. In +contrast, =est+= estimates the full job more realistically, at 10--15 +days. + +Here is an example for a complete columns definition, along with +allowed values[fn:57]. + +#+begin_example +:COLUMNS: %25ITEM %9Approved(Approved?){X} %Owner %11Status \ + %10Time_Estimate{:} %CLOCKSUM %CLOCKSUM_T +:Owner_ALL: Tammy Mark Karl Lisa Don +:Status_ALL: "In progress" "Not started yet" "Finished" "" +:Approved_ALL: "[ ]" "[X]" +#+end_example + +#+texinfo: @noindent +The first column, =%25ITEM=, means the first 25 characters of the item +itself, i.e., of the headline. You probably always should start the +column definition with the =ITEM= specifier. The other specifiers +create columns =Owner= with a list of names as allowed values, for +=Status= with four different possible values, and for a checkbox field +=Approved=. When no width is given after the =%= character, the +column is exactly as wide as it needs to be in order to fully display +all values. The =Approved= column does have a modified title +(=Approved?=, with a question mark). Summaries are created for the +=Time_Estimate= column by adding time duration expressions like HH:MM, +and for the =Approved= column, by providing an =[X]= status if all +children have been checked. The =CLOCKSUM= and =CLOCKSUM_T= columns +are special, they lists the sums of CLOCK intervals in the subtree, +either for all clocks or just for today. + +*** Using column view +:PROPERTIES: +:DESCRIPTION: How to create and use column view. +:END: + +**** Turning column view on or off +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +- {{{kbd(C-c C-x C-c)}}} (~org-columns~) :: + + #+kindex: C-c C-x C-c + #+vindex: org-columns + #+vindex: org-columns-default-format + Turn on column view. If point is before the first headline in the + file, column view is turned on for the entire file, using the + =#+COLUMNS= definition. If point is somewhere inside the outline, + this command searches the hierarchy, up from point, for a =COLUMNS= + property that defines a format. When one is found, the column view + table is established for the tree starting at the entry that + contains the =COLUMNS= property. If no such property is found, the + format is taken from the =#+COLUMNS= line or from the variable + ~org-columns-default-format~, and column view is established for the + current entry and its subtree. + +- {{{kbd(r)}}} or {{{kbd(g)}}} on a columns view line (~org-columns-redo~) :: + + #+kindex: r + #+kindex: g + #+findex: org-columns-redo + Recreate the column view, to include recent changes made in the + buffer. + +- {{{kbd(C-c C-c)}}} or {{{kbd(q)}}} on a columns view line (~org-columns-quit~) :: + + #+kindex: q + #+kindex: C-c C-c + #+findex: org-columns-quit + Exit column view. + +**** Editing values +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+attr_texinfo: :sep and +- {{{kbd(LEFT)}}}, {{{kbd(RIGHT)}}}, {{{kbd(UP)}}}, {{{kbd(DOWN)}}} :: + + Move through the column view from field to field. + +- {{{kbd(1..9\,0)}}} :: + + #+kindex: 1..9,0 + Directly select the Nth allowed value, {{{kbd(0)}}} selects the + 10th value. + +- {{{kbd(n)}}} or {{{kbd(S-RIGHT)}}} (~org-columns-next-allowed-value~) and {{{kbd(p)}}} or {{{kbd(S-LEFT)}}} (~org-columns-previous-allowed-value~) :: + + #+kindex: n + #+kindex: S-RIGHT + #+kindex: p + #+kindex: S-LEFT + #+findex: org-columns-next-allowed-value + #+findex: org-columns-previous-allowed-value + Switch to the next/previous allowed value of the field. For this, + you have to have specified allowed values for a property. + +- {{{kbd(e)}}} (~org-columns-edit-value~) :: + + #+kindex: e + #+findex: org-columns-edit-value + Edit the property at point. For the special properties, this + invokes the same interface that you normally use to change that + property. For example, the tag completion or fast selection + interface pops up when editing a =TAGS= property. + +- {{{kbd(C-c C-c)}}} (~org-columns-toggle-or-columns-quit~) :: + + #+kindex: C-c C-c + #+findex: org-columns-toggle-or-columns-quit + When there is a checkbox at point, toggle it. Else exit column + view. + +- {{{kbd(v)}}} (~org-columns-show-value~) :: + + #+kindex: v + #+findex: org-columns-show-value + View the full value of this property. This is useful if the width + of the column is smaller than that of the value. + +- {{{kbd(a)}}} (~org-columns-edit-allowed~) :: + + #+kindex: a + #+findex: org-columns-edit-allowed + Edit the list of allowed values for this property. If the list is + found in the hierarchy, the modified values is stored there. If no + list is found, the new value is stored in the first entry that is + part of the current column view. + +**** Modifying column view on-the-fly +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+attr_texinfo: :sep and +- {{{kbd(<)}}} (~org-columns-narrow~) and {{{kbd(>)}}} (~org-columns-widen~) :: + + #+kindex: < + #+kindex: > + #+findex: org-columns-narrow + #+findex: org-columns-widen + Make the column narrower/wider by one character. + +- {{{kbd(S-M-RIGHT)}}} (~org-columns-new~) :: + + #+kindex: S-M-RIGHT + #+findex: org-columns-new + Insert a new column, to the left of the current column. + +- {{{kbd(S-M-LEFT)}}} (~org-columns-delete~) :: + + #+kindex: S-M-LEFT + #+findex: org-columns-delete + Delete the current column. + +*** Capturing column view +:PROPERTIES: +:DESCRIPTION: A dynamic block for column view. +:END: + +Since column view is just an overlay over a buffer, it cannot be +exported or printed directly. If you want to capture a column view, +use a =columnview= dynamic block (see [[*Dynamic Blocks]]). The frame of +this block looks like this: + +#+cindex: @samp{BEGIN columnview} +#+begin_example +,* The column view +,#+BEGIN: columnview :hlines 1 :id "label" + +,#+END: +#+end_example + +This dynamic block has the following parameters: + +- =:id= :: + + This is the most important parameter. Column view is a feature that + is often localized to a certain (sub)tree, and the capture block + might be at a different location in the file. To identify the tree + whose view to capture, you can use four values: + + - =local= :: + + Use the tree in which the capture block is located. + + - =global= :: + + Make a global view, including all headings in the file. + + - =file:FILENAME= :: + + Run column view at the top of the {{{var(FILENAME)}}} file. + + - =LABEL= :: + + #+cindex: @samp{ID}, property + Call column view in the tree that has an =ID= property with the + value {{{var(LABEL)}}}. You can use {{{kbd(M-x org-id-copy)}}} to + create a globally unique ID for the current entry and copy it to + the kill-ring. + +- =:match= :: + + When set to a string, use this as a tags/property match filter to + select only a subset of the headlines in the scope set by the ~:id~ + parameter. + + +- =:hlines= :: + + When ~t~, insert an hline after every line. When a number N, insert + an hline before each headline with level ~<= N~. + +- =:vlines= :: + + When non-~nil~, force column groups to get vertical lines. + +- =:maxlevel= :: + + When set to a number, do not capture entries below this level. + +- =:skip-empty-rows= :: + + When non-~nil~, skip rows where the only non-empty specifier of + the column view is =ITEM=. + +- =:exclude-tags= :: + + List of tags to exclude from column view table: entries with these + tags will be excluded from the column view. + +- =:indent= :: + + When non-~nil~, indent each =ITEM= field according to its level. + +- =:format= :: + + Specify a column attribute (see [[*Column attributes]]) for the dynamic + block. + +The following commands insert or update the dynamic block: + +- ~org-columns-insert-dblock~ :: + + #+kindex: C-c C-x x + #+findex: org-columns-insert-dblock + Insert a dynamic block capturing a column view. Prompt for the + scope or ID of the view. + + This command can be invoked by calling + ~org-dynamic-block-insert-dblock~ ({{{kbd(C-c C-x x)}}}) and + selecting "columnview" (see [[*Dynamic Blocks]]). + +- {{{kbd(C-c C-c)}}} {{{kbd(C-c C-x C-u)}}} (~org-dblock-update~) :: + + #+kindex: C-c C-c + #+kindex: C-c C-x C-u + #+findex: org-dblock-update + Update dynamic block at point. point needs to be in the =#+BEGIN= + line of the dynamic block. + +- {{{kbd(C-u C-c C-x C-u)}}} (~org-update-all-dblocks~) :: + + #+kindex: C-u C-c C-x C-u + Update all dynamic blocks (see [[*Dynamic Blocks]]). This is useful if + you have several clock table blocks, column-capturing blocks or + other dynamic blocks in a buffer. + +You can add formulas to the column view table and you may add plotting +instructions in front of the table---these survive an update of the +block. If there is a =TBLFM= keyword after the table, the table is +recalculated automatically after an update. + +An alternative way to capture and process property values into a table +is provided by Eric Schulte's =org-collector.el=, which is +a contributed package[fn:58]. It provides a general API to collect +properties from entries in a certain scope, and arbitrary Lisp +expressions to process these values before inserting them into a table +or a dynamic block. + +* Dates and Times +:PROPERTIES: +:DESCRIPTION: Making items useful for planning. +:END: +#+cindex: dates +#+cindex: times +#+cindex: timestamp +#+cindex: date stamp + +To assist project planning, TODO items can be labeled with a date +and/or a time. The specially formatted string carrying the date and +time information is called a /timestamp/ in Org mode. This may be +a little confusing because timestamp is often used as indicating when +something was created or last changed. However, in Org mode this term +is used in a much wider sense. + +** Timestamps +:PROPERTIES: +:DESCRIPTION: Assigning a time to a tree entry. +:END: +#+cindex: timestamps +#+cindex: ranges, time +#+cindex: date stamps +#+cindex: deadlines +#+cindex: scheduling + +A timestamp is a specification of a date (possibly with a time or +a range of times) in a special format, either =<2003-09-16 Tue>= or +=<2003-09-16 Tue 09:39>= or =<2003-09-16 Tue 12:00-12:30>=[fn:59]. +A timestamp can appear anywhere in the headline or body of an Org tree +entry. Its presence causes entries to be shown on specific dates in +the agenda (see [[*Weekly/daily agenda]]). We distinguish: + +- Plain timestamp; Event; Appointment :: + + #+cindex: timestamp + #+cindex: appointment + A simple timestamp just assigns a date/time to an item. This is + just like writing down an appointment or event in a paper agenda. + In the agenda display, the headline of an entry associated with + a plain timestamp is shown exactly on that date. + + #+begin_example + ,* Meet Peter at the movies + <2006-11-01 Wed 19:15> + ,* Discussion on climate change + <2006-11-02 Thu 20:00-22:00> + #+end_example + +- Timestamp with repeater interval :: + + #+cindex: timestamp, with repeater interval + A timestamp may contain a /repeater interval/, indicating that it + applies not only on the given date, but again and again after + a certain interval of N days (d), weeks (w), months (m), or years + (y). The following shows up in the agenda every Wednesday: + + #+begin_example + ,* Pick up Sam at school + <2007-05-16 Wed 12:30 +1w> + #+end_example + +- Diary-style expression entries :: + + #+cindex: diary style timestamps + #+cindex: sexp timestamps + For more complex date specifications, Org mode supports using the + special expression diary entries implemented in the Emacs Calendar + package[fn:60]. For example, with optional time: + + #+begin_example + ,* 22:00-23:00 The nerd meeting on every 2nd Thursday of the month + <%%(diary-float t 4 2)> + #+end_example + +- Time/Date range :: + + #+cindex: timerange + #+cindex: date range + Two timestamps connected by =--= denote a range. The headline is + shown on the first and last day of the range, and on any dates that + are displayed and fall in the range. Here is an example: + + #+begin_example + ,** Meeting in Amsterdam + <2004-08-23 Mon>--<2004-08-26 Thu> + #+end_example + +- Inactive timestamp :: + + #+cindex: timestamp, inactive + #+cindex: inactive timestamp + Just like a plain timestamp, but with square brackets instead of + angular ones. These timestamps are inactive in the sense that they + do /not/ trigger an entry to show up in the agenda. + + #+begin_example + ,* Gillian comes late for the fifth time + [2006-11-01 Wed] + #+end_example + +** Creating Timestamps +:PROPERTIES: +:DESCRIPTION: Commands to insert timestamps. +:END: + +For Org mode to recognize timestamps, they need to be in the specific +format. All commands listed below produce timestamps in the correct +format. + +#+attr_texinfo: :sep , +- {{{kbd(C-c .)}}} (~org-time-stamp~) :: + + #+kindex: C-c . + #+findex: org-time-stamp + Prompt for a date and insert a corresponding timestamp. When point + is at an existing timestamp in the buffer, the command is used to + modify this timestamp instead of inserting a new one. When this + command is used twice in succession, a time range is inserted. + + #+kindex: C-u C-c . + #+vindex: org-time-stamp-rounding-minutes + When called with a prefix argument, use the alternative format which + contains date and time. The default time can be rounded to + multiples of 5 minutes. See the option + ~org-time-stamp-rounding-minutes~. + + #+kindex: C-u C-u C-c . + With two prefix arguments, insert an active timestamp with the + current time without prompting. + +- {{{kbd(C-c !)}}} (~org-time-stamp-inactive~) :: + + #+kindex: C-c ! + #+kindex: C-u C-c ! + #+kindex: C-u C-u C-c ! + #+findex: org-time-stamp-inactive + Like {{{kbd(C-c .)}}}, but insert an inactive timestamp that does + not cause an agenda entry. + +- {{{kbd(C-c C-c)}}} :: + + #+kindex: C-c C-c + Normalize timestamp, insert or fix day name if missing or wrong. + +- {{{kbd(C-c <)}}} (~org-date-from-calendar~) :: + + #+kindex: C-c < + #+findex: org-date-from-calendar + Insert a timestamp corresponding to point date in the calendar. + +- {{{kbd(C-c >)}}} (~org-goto-calendar~) :: + + #+kindex: C-c > + #+findex: org-goto-calendar + Access the Emacs calendar for the current date. If there is + a timestamp in the current line, go to the corresponding date + instead. + +- {{{kbd(C-c C-o)}}} (~org-open-at-point~) :: + + #+kindex: C-c C-o + #+findex: org-open-at-point + Access the agenda for the date given by the timestamp or -range at + point (see [[*Weekly/daily agenda]]). + +- {{{kbd(S-LEFT)}}} (~org-timestamp-down-day~), {{{kbd(S-RIGHT)}}} (~org-timestamp-up-day~) :: + + #+kindex: S-LEFT + #+kindex: S-RIGHT + #+findex: org-timestamp-down-day + #+findex: org-timestamp-up-day + Change date at point by one day. These key bindings conflict with + shift-selection and related modes (see [[*Packages that conflict with + Org mode]]). + +- {{{kbd(S-UP)}}} (~org-timestamp-up~), {{{kbd(S-DOWN)}}} (~org-timestamp-down~) :: + + #+kindex: S-UP + #+kindex: S-DOWN + On the beginning or enclosing bracket of a timestamp, change its + type. Within a timestamp, change the item under point. Point can + be on a year, month, day, hour or minute. When the timestamp + contains a time range like =15:30-16:30=, modifying the first time + also shifts the second, shifting the time block with constant + length. To change the length, modify the second time. Note that if + point is in a headline and not at a timestamp, these same keys + modify the priority of an item (see [[*Priorities]]). The key bindings + also conflict with shift-selection and related modes (see [[*Packages + that conflict with Org mode]]). + +- {{{kbd(C-c C-y)}}} (~org-evaluate-time-range~) :: + + #+kindex: C-c C-y + #+findex: org-evaluate-time-range + #+cindex: evaluate time range + Evaluate a time range by computing the difference between start and + end. With a prefix argument, insert result after the time range (in + a table: into the following column). + +*** The date/time prompt +:PROPERTIES: +:DESCRIPTION: How Org mode helps you enter dates and times. +:END: +#+cindex: date, reading in minibuffer +#+cindex: time, reading in minibuffer + +#+vindex: org-read-date-prefer-future +When Org mode prompts for a date/time, the default is shown in default +date/time format, and the prompt therefore seems to ask for a specific +format. But it in fact accepts date/time information in a variety of +formats. Generally, the information should start at the beginning of +the string. Org mode finds whatever information is in there and +derives anything you have not specified from the /default date and +time/. The default is usually the current date and time, but when +modifying an existing timestamp, or when entering the second stamp of +a range, it is taken from the stamp in the buffer. When filling in +information, Org mode assumes that most of the time you want to enter +a date in the future: if you omit the month/year and the given +day/month is /before/ today, it assumes that you mean a future +date[fn:61]. If the date has been automatically shifted into the +future, the time prompt shows this with =(=>F)=. + +For example, let's assume that today is *June 13, 2006*. Here is how +various inputs are interpreted, the items filled in by Org mode are in +*bold*. + +| =3-2-5= | \rArr{} 2003-02-05 | +| =2/5/3= | \rArr{} 2003-02-05 | +| =14= | \rArr{} *2006*-*06*-14 | +| =12= | \rArr{} *2006*-*07*-12 | +| =2/5= | \rArr{} *2007*-02-05 | +| =Fri= | \rArr{} nearest Friday (default date or later) | +| =sep 15= | \rArr{} *2006*-09-15 | +| =feb 15= | \rArr{} *2007*-02-15 | +| =sep 12 9= | \rArr{} 2009-09-12 | +| =12:45= | \rArr{} *2006*-*06*-*13* 12:45 | +| =22 sept 0:34= | \rArr{} *2006*-09-22 0:34 | +| =w4= | \rArr{} ISO week for of the current year *2006* | +| =2012 w4 fri= | \rArr{} Friday of ISO week 4 in 2012 | +| =2012-w04-5= | \rArr{} Same as above | + +Furthermore you can specify a relative date by giving, as the /first/ +thing in the input: a plus/minus sign, a number and a letter---=h=, +=d=, =w=, =m= or =y=---to indicate a change in hours, days, weeks, +months, or years. With =h= the date is relative to the current time, +with the other letters and a single plus or minus, the date is +relative to today at 00:00. With a double plus or minus, it is +relative to the default date. If instead of a single letter, you use +the abbreviation of day name, the date is the Nth such day, e.g.: + +| =+0= | \rArr{} today | +| =.= | \rArr{} today | +| =+2h= | \rArr{} two hours from now | +| =+4d= | \rArr{} four days from today | +| =+4= | \rArr{} same as +4d | +| =+2w= | \rArr{} two weeks from today | +| =++5= | \rArr{} five days from default date | +| =+2tue= | \rArr{} second Tuesday from now | + +#+vindex: parse-time-months +#+vindex: parse-time-weekdays +The function understands English month and weekday abbreviations. If +you want to use un-abbreviated names and/or other languages, configure +the variables ~parse-time-months~ and ~parse-time-weekdays~. + +#+vindex: org-read-date-force-compatible-dates +Not all dates can be represented in a given Emacs implementation. By +default Org mode forces dates into the compatibility range 1970--2037 +which works on all Emacs implementations. If you want to use dates +outside of this range, read the docstring of the variable +~org-read-date-force-compatible-dates~. + +You can specify a time range by giving start and end times or by +giving a start time and a duration (in HH:MM format). Use one or two +dash(es) as the separator in the former case and use =+= as the +separator in the latter case, e.g.: + +| =11am-1:15pm= | \rArr{} 11:00-13:15 | +| =11am--1:15pm= | \rArr{} same as above | +| =11am+2:15= | \rArr{} same as above | + +#+cindex: calendar, for selecting date +#+vindex: org-popup-calendar-for-date-prompt +Parallel to the minibuffer prompt, a calendar is popped up[fn:62]. +When you exit the date prompt, either by clicking on a date in the +calendar, or by pressing {{{kbd(RET)}}}, the date selected in the +calendar is combined with the information entered at the prompt. You +can control the calendar fully from the minibuffer: + +#+kindex: < +#+kindex: > +#+kindex: M-v +#+kindex: C-v +#+kindex: mouse-1 +#+kindex: S-RIGHT +#+kindex: S-LEFT +#+kindex: S-DOWN +#+kindex: S-UP +#+kindex: M-S-RIGHT +#+kindex: M-S-LEFT +#+kindex: RET +#+kindex: . +#+kindex: C-. +#+attr_texinfo: :columns 0.25 0.55 +| {{{kbd(RET)}}} | Choose date at point in calendar. | +| {{{kbd(mouse-1)}}} | Select date by clicking on it. | +| {{{kbd(S-RIGHT)}}} | One day forward. | +| {{{kbd(S-LEFT)}}} | One day backward. | +| {{{kbd(S-DOWN)}}} | One week forward. | +| {{{kbd(S-UP)}}} | One week backward. | +| {{{kbd(M-S-RIGHT)}}} | One month forward. | +| {{{kbd(M-S-LEFT)}}} | One month backward. | +| {{{kbd(>)}}} | Scroll calendar forward by one month. | +| {{{kbd(<)}}} | Scroll calendar backward by one month. | +| {{{kbd(M-v)}}} | Scroll calendar forward by 3 months. | +| {{{kbd(C-v)}}} | Scroll calendar backward by 3 months. | +| {{{kbd(C-.)}}} | Select today's date[fn:63] | + +#+vindex: org-read-date-display-live +The actions of the date/time prompt may seem complex, but I assure you +they will grow on you, and you will start getting annoyed by pretty +much any other way of entering a date/time out there. To help you +understand what is going on, the current interpretation of your input +is displayed live in the minibuffer[fn:64]. + +*** Custom time format +:PROPERTIES: +:DESCRIPTION: Making dates look different. +:END: +#+cindex: custom date/time format +#+cindex: time format, custom +#+cindex: date format, custom + +#+vindex: org-display-custom-times +#+vindex: org-time-stamp-custom-formats +Org mode uses the standard ISO notation for dates and times as it is +defined in ISO 8601. If you cannot get used to this and require +another representation of date and time to keep you happy, you can get +it by customizing the variables ~org-display-custom-times~ and +~org-time-stamp-custom-formats~. + +- {{{kbd(C-c C-x C-t)}}} (~org-toggle-time-stamp-overlays~) :: + + #+kindex: C-c C-x C-t + #+findex: org-toggle-time-stamp-overlays + Toggle the display of custom formats for dates and times. + +Org mode needs the default format for scanning, so the custom +date/time format does not /replace/ the default format. Instead, it +is put /over/ the default format using text properties. This has the +following consequences: + +- You cannot place point onto a timestamp anymore, only before or + after. + +- The {{{kbd(S-UP)}}} and {{{kbd(S-DOWN)}}} keys can no longer be used + to adjust each component of a timestamp. If point is at the + beginning of the stamp, {{{kbd(S-UP)}}} and {{{kbd(S-DOWN)}}} change + the stamp by one day, just like {{{kbd(S-LEFT)}}} + {{{kbd(S-RIGHT)}}}. At the end of the stamp, change the time by one + minute. + +- If the timestamp contains a range of clock times or a repeater, + these are not overlaid, but remain in the buffer as they were. + +- When you delete a timestamp character-by-character, it only + disappears from the buffer after /all/ (invisible) characters + belonging to the ISO timestamp have been removed. + +- If the custom timestamp format is longer than the default and you + are using dates in tables, table alignment will be messed up. If + the custom format is shorter, things do work as expected. + +** Deadlines and Scheduling +:PROPERTIES: +:DESCRIPTION: Planning your work. +:END: + +A timestamp may be preceded by special keywords to facilitate +planning. Both the timestamp and the keyword have to be positioned +immediately after the task they refer to. + +- =DEADLINE= :: + + #+cindex: @samp{DEADLINE} marker + Meaning: the task---most likely a TODO item, though not + necessarily---is supposed to be finished on that date. + + #+vindex: org-deadline-warning-days + On the deadline date, the task is listed in the agenda. In + addition, the agenda for /today/ carries a warning about the + approaching or missed deadline, starting ~org-deadline-warning-days~ + before the due date, and continuing until the entry is marked as + done. An example: + + #+begin_example + ,*** TODO write article about the Earth for the Guide + DEADLINE: <2004-02-29 Sun> + The editor in charge is [[bbdb:Ford Prefect]] + #+end_example + + #+vindex: org-agenda-skip-deadline-prewarning-if-scheduled + You can specify a different lead time for warnings for a specific + deadlines using the following syntax. Here is an example with + a warning period of 5 days =DEADLINE: <2004-02-29 Sun -5d>=. This + warning is deactivated if the task gets scheduled and you set + ~org-agenda-skip-deadline-prewarning-if-scheduled~ to ~t~. + +- =SCHEDULED= :: + + #+cindex: @samp{SCHEDULED} marker + Meaning: you are planning to start working on that task on the given + date. + + #+vindex: org-agenda-skip-scheduled-if-done + The headline is listed under the given date[fn:65]. In addition, + a reminder that the scheduled date has passed is present in the + compilation for /today/, until the entry is marked as done, i.e., + the task is automatically forwarded until completed. + + #+begin_example + ,*** TODO Call Trillian for a date on New Years Eve. + SCHEDULED: <2004-12-25 Sat> + #+end_example + + #+vindex: org-scheduled-delay-days + #+vindex: org-agenda-skip-scheduled-delay-if-deadline + If you want to /delay/ the display of this task in the agenda, use + =SCHEDULED: <2004-12-25 Sat -2d>=: the task is still scheduled on + the 25th but will appear two days later. In case the task contains + a repeater, the delay is considered to affect all occurrences; if + you want the delay to only affect the first scheduled occurrence of + the task, use =--2d= instead. See ~org-scheduled-delay-days~ and + ~org-agenda-skip-scheduled-delay-if-deadline~ for details on how to + control this globally or per agenda. + + #+attr_texinfo: :tag Important + #+begin_quote + Scheduling an item in Org mode should /not/ be understood in the + same way that we understand /scheduling a meeting/. Setting a date + for a meeting is just a simple appointment, you should mark this + entry with a simple plain timestamp, to get this item shown on the + date where it applies. This is a frequent misunderstanding by Org + users. In Org mode, /scheduling/ means setting a date when you want + to start working on an action item. + #+end_quote + +You may use timestamps with repeaters in scheduling and deadline +entries. Org mode issues early and late warnings based on the +assumption that the timestamp represents the /nearest instance/ of the +repeater. However, the use of diary expression entries like + +: <%%(diary-float t 42)> + +#+texinfo: @noindent +in scheduling and deadline timestamps is limited. Org mode does not +know enough about the internals of each function to issue early and +late warnings. However, it shows the item on each day where the +expression entry matches. + +*** Inserting deadlines or schedules +:PROPERTIES: +:DESCRIPTION: Planning items. +:ALT_TITLE: Inserting deadline/schedule +:END: + +The following commands allow you to quickly insert a deadline or to +schedule an item:[fn:66] + +- {{{kbd(C-c C-d)}}} (~org-deadline~) :: + + #+kindex: C-c C-d + #+findex: org-deadline + #+vindex: org-log-redeadline + Insert =DEADLINE= keyword along with a stamp. The insertion happens + in the line directly following the headline. Remove any =CLOSED= + timestamp . When called with a prefix argument, also remove any + existing deadline from the entry. Depending on the variable + ~org-log-redeadline~, take a note when changing an existing + deadline[fn:67]. + +- {{{kbd(C-c C-s)}}} (~org-schedule~) :: + + #+kindex: C-c C-s + #+findex: org-schedule + #+vindex: org-log-reschedule + Insert =SCHEDULED= keyword along with a stamp. The insertion + happens in the line directly following the headline. Remove any + =CLOSED= timestamp. When called with a prefix argument, also remove + the scheduling date from the entry. Depending on the variable + ~org-log-reschedule~, take a note when changing an existing + scheduling time[fn:68]. + +- {{{kbd(C-c / d)}}} (~org-check-deadlines~) :: + + #+kindex: C-c / d + #+findex: org-check-deadlines + #+cindex: sparse tree, for deadlines + #+vindex: org-deadline-warning-days + Create a sparse tree with all deadlines that are either past-due, or + which will become due within ~org-deadline-warning-days~. With + {{{kbd(C-u)}}} prefix, show all deadlines in the file. With + a numeric prefix, check that many days. For example, {{{kbd(C-1 C-c + / d)}}} shows all deadlines due tomorrow. + +- {{{kbd(C-c / b)}}} (~org-check-before-date~) :: + + #+kindex: C-c / b + #+findex: org-check-before-date + Sparse tree for deadlines and scheduled items before a given date. + +- {{{kbd(C-c / a)}}} (~org-check-after-date~) :: + + #+kindex: C-c / a + #+findex: org-check-after-date + Sparse tree for deadlines and scheduled items after a given date. + +Note that ~org-schedule~ and ~org-deadline~ supports setting the date +by indicating a relative time e.g., =+1d= sets the date to the next +day after today, and =--1w= sets the date to the previous week before +any current timestamp. + +*** Repeated tasks +:PROPERTIES: +:DESCRIPTION: Items that show up again and again. +:END: +#+cindex: tasks, repeated +#+cindex: repeated tasks + +Some tasks need to be repeated again and again. Org mode helps to +organize such tasks using a so-called repeater in a =DEADLINE=, +=SCHEDULED=, or plain timestamps[fn:69]. In the following example: + +#+begin_example +,** TODO Pay the rent + DEADLINE: <2005-10-01 Sat +1m> +#+end_example + +#+texinfo: @noindent +the =+1m= is a repeater; the intended interpretation is that the task +has a deadline on =<2005-10-01>= and repeats itself every (one) month +starting from that time. You can use yearly, monthly, weekly, daily +and hourly repeat cookies by using the =y=, =m=, =w=, =d= and =h= +letters. If you need both a repeater and a special warning period in +a deadline entry, the repeater should come first and the warning +period last + +: DEADLINE: <2005-10-01 Sat +1m -3d> + +#+vindex: org-todo-repeat-to-state +Deadlines and scheduled items produce entries in the agenda when they +are over-due, so it is important to be able to mark such an entry as +done once you have done so. When you mark a =DEADLINE= or +a =SCHEDULED= with the TODO keyword =DONE=, it no longer produces +entries in the agenda. The problem with this is, however, is that +then also the /next/ instance of the repeated entry will not be +active. Org mode deals with this in the following way: when you try +to mark such an entry as done, using {{{kbd(C-c C-t)}}}, it shifts the +base date of the repeating timestamp by the repeater interval, and +immediately sets the entry state back to TODO[fn:70]. In the example +above, setting the state to =DONE= would actually switch the date like +this: + +#+begin_example +,** TODO Pay the rent + DEADLINE: <2005-11-01 Tue +1m> +#+end_example + +To mark a task with a repeater as DONE, use {{{kbd(C-- 1 C-c C-t)}}}, +i.e., ~org-todo~ with a numeric prefix argument of =-1=. + +#+vindex: org-log-repeat +A timestamp[fn:71] is added under the deadline, to keep a record that +you actually acted on the previous instance of this deadline. + +As a consequence of shifting the base date, this entry is no longer +visible in the agenda when checking past dates, but all future +instances will be visible. + +With the =+1m= cookie, the date shift is always exactly one month. So +if you have not paid the rent for three months, marking this entry +DONE still keeps it as an overdue deadline. Depending on the task, +this may not be the best way to handle it. For example, if you forgot +to call your father for 3 weeks, it does not make sense to call him +3 times in a single day to make up for it. Finally, there are tasks, +like changing batteries, which should always repeat a certain time +/after/ the last time you did it. For these tasks, Org mode has +special repeaters =++= and =.+=. For example: + +#+begin_example +,** TODO Call Father + DEADLINE: <2008-02-10 Sun ++1w> + Marking this DONE shifts the date by at least one week, but also + by as many weeks as it takes to get this date into the future. + However, it stays on a Sunday, even if you called and marked it + done on Saturday. + +,** TODO Empty kitchen trash + DEADLINE: <2008-02-08 Fri 20:00 ++1d> + Marking this DONE shifts the date by at least one day, and also + by as many days as it takes to get the timestamp into the future. + Since there is a time in the timestamp, the next deadline in the + future will be on today's date if you complete the task before + 20:00. + +,** TODO Check the batteries in the smoke detectors + DEADLINE: <2005-11-01 Tue .+1m> + Marking this DONE shifts the date to one month after today. + +,** TODO Wash my hands + DEADLINE: <2019-04-05 08:00 Sun .+1h> + Marking this DONE shifts the date to exactly one hour from now. +#+end_example + +#+vindex: org-agenda-skip-scheduled-if-deadline-is-shown +You may have both scheduling and deadline information for a specific +task. If the repeater is set for the scheduling information only, you +probably want the repeater to be ignored after the deadline. If so, +set the variable ~org-agenda-skip-scheduled-if-deadline-is-shown~ to +~repeated-after-deadline~. However, any scheduling information +without a repeater is no longer relevant once the task is done, and +thus, removed upon repeating the task. If you want both scheduling +and deadline information to repeat after the same interval, set the +same repeater for both timestamps. + +An alternative to using a repeater is to create a number of copies of +a task subtree, with dates shifted in each copy. The command +{{{kbd(C-c C-x c)}}} was created for this purpose; it is described in +[[*Structure Editing]]. + +** Clocking Work Time +:PROPERTIES: +:DESCRIPTION: Tracking how long you spend on a task. +:END: +#+cindex: clocking time +#+cindex: time clocking + +Org mode allows you to clock the time you spend on specific tasks in +a project. When you start working on an item, you can start the +clock. When you stop working on that task, or when you mark the task +done, the clock is stopped and the corresponding time interval is +recorded. It also computes the total time spent on each +subtree[fn:72] of a project. And it remembers a history or tasks +recently clocked, so that you can jump quickly between a number of +tasks absorbing your time. + +To save the clock history across Emacs sessions, use: + +#+begin_src emacs-lisp +(setq org-clock-persist 'history) +(org-clock-persistence-insinuate) +#+end_src + +#+vindex: org-clock-persist +When you clock into a new task after resuming Emacs, the incomplete +clock[fn:73] is retrieved (see [[*Resolving idle time]]) and you are +prompted about what to do with it. + +*** Clocking commands +:PROPERTIES: +:DESCRIPTION: Starting and stopping a clock. +:END: + +#+attr_texinfo: :sep , +- {{{kbd(C-c C-x C-i)}}} (~org-clock-in~) :: + + #+kindex: C-c C-x C-i + #+findex: org-clock-in + #+vindex: org-clock-into-drawer + #+vindex: org-clock-continuously + #+cindex: @samp{LOG_INTO_DRAWER}, property + Start the clock on the current item (clock-in). This inserts the + =CLOCK= keyword together with a timestamp. If this is not the first + clocking of this item, the multiple =CLOCK= lines are wrapped into + a =LOGBOOK= drawer (see also the variable ~org-clock-into-drawer~). + You can also overrule the setting of this variable for a subtree by + setting a =CLOCK_INTO_DRAWER= or =LOG_INTO_DRAWER= property. When + called with a {{{kbd(C-u)}}} prefix argument, select the task from + a list of recently clocked tasks. With two {{{kbd(C-u C-u)}}} + prefixes, clock into the task at point and mark it as the default + task; the default task is always be available with letter + {{{kbd(d)}}} when selecting a clocking task. With three {{{kbd(C-u + C-u C-u)}}} prefixes, force continuous clocking by starting the + clock when the last clock stopped. + + #+cindex: @samp{CLOCK_MODELINE_TOTAL}, property + #+cindex: @samp{LAST_REPEAT}, property + #+vindex: org-clock-mode-line-total + #+vindex: org-clock-in-prepare-hook + While the clock is running, Org shows the current clocking time in + the mode line, along with the title of the task. The clock time + shown is all time ever clocked for this task and its children. If + the task has an effort estimate (see [[*Effort Estimates]]), the mode + line displays the current clocking time against it[fn:74]. If the + task is a repeating one (see [[*Repeated tasks]]), show only the time + since the last reset of the task[fn:75]. You can exercise more + control over show time with the =CLOCK_MODELINE_TOTAL= property. It + may have the values =current= to show only the current clocking + instance, =today= to show all time clocked on this tasks today---see + also the variable ~org-extend-today-until~, ~all~ to include all + time, or ~auto~ which is the default[fn:76]. Clicking with + {{{kbd(mouse-1)}}} onto the mode line entry pops up a menu with + clocking options. + +- {{{kbd(C-c C-x C-o)}}} (~org-clock-out~) :: + + #+kindex: C-c C-x C-o + #+findex: org-clock-out + #+vindex: org-log-note-clock-out + Stop the clock (clock-out). This inserts another timestamp at the + same location where the clock was last started. It also directly + computes the resulting time in inserts it after the time range as + ==>HH:MM=. See the variable ~org-log-note-clock-out~ for the + possibility to record an additional note together with the clock-out + timestamp[fn:77]. + +- {{{kbd(C-c C-x C-x)}}} (~org-clock-in-last~) :: + + #+kindex: C-c C-x C-x + #+findex: org-clock-in-last + #+vindex: org-clock-continuously + Re-clock the last clocked task. With one {{{kbd(C-u)}}} prefix + argument, select the task from the clock history. With two + {{{kbd(C-u)}}} prefixes, force continuous clocking by starting the + clock when the last clock stopped. + +- {{{kbd(C-c C-x C-e)}}} (~org-clock-modify-effort-estimate~) :: + + #+kindex: C-c C-x C-e + #+findex: org-clock-modify-effort-estimate + Update the effort estimate for the current clock task. + +- {{{kbd(C-c C-c)}}} or {{{kbd(C-c C-y)}}} (~org-evaluate-time-range~) :: + + #+kindex: C-c C-c + #+kindex: C-c C-y + #+findex: org-evaluate-time-range + Recompute the time interval after changing one of the timestamps. + This is only necessary if you edit the timestamps directly. If you + change them with {{{kbd(S-)}}} keys, the update is + automatic. + +- {{{kbd(C-S-UP)}}} (~org-clock-timestamps-up~), {{{kbd(C-S-DOWN)}}} (~org-clock-timestamps-down~) :: + + #+kindex: C-S-UP + #+findex: org-clock-timestamps-up + #+kindex: C-S-DOWN + #+findex: org-clock-timestamps-down + On CLOCK log lines, increase/decrease both timestamps so that the + clock duration keeps the same value. + +- {{{kbd(S-M-UP)}}} (~org-timestamp-up~), {{{kbd(S-M-DOWN)}}} (~org-timestamp-down~) :: + + #+kindex: S-M-UP + #+findex: org-clock-timestamp-up + #+kindex: S-M-DOWN + #+findex: org-clock-timestamp-down + On =CLOCK= log lines, increase/decrease the timestamp at point and + the one of the previous, or the next, clock timestamp by the same + duration. For example, if you hit {{{kbd(S-M-UP)}}} to increase + a clocked-out timestamp by five minutes, then the clocked-in + timestamp of the next clock is increased by five minutes. + +- {{{kbd(C-c C-t)}}} (~org-todo~) :: + + #+kindex: C-c C-t + #+findex: org-todo + Changing the TODO state of an item to DONE automatically stops the + clock if it is running in this same item. + +- {{{kbd(C-c C-x C-q)}}} (~org-clock-cancel~) :: + + #+kindex: C-c C-x C-q + #+findex: org-clock-cancel + Cancel the current clock. This is useful if a clock was started by + mistake, or if you ended up working on something else. + +- {{{kbd(C-c C-x C-j)}}} (~org-clock-goto~) :: + + #+kindex: C-c C-x C-j + #+findex: or-clock-goto + Jump to the headline of the currently clocked in task. With + a {{{kbd(C-u)}}} prefix argument, select the target task from a list + of recently clocked tasks. + +- {{{kbd(C-c C-x C-d)}}} (~org-clock-display~) :: + + #+kindex: C-c C-x C-d + #+findex: org-clock-display + #+vindex: org-remove-highlights-with-change + Display time summaries for each subtree in the current buffer. This + puts overlays at the end of each headline, showing the total time + recorded under that heading, including the time of any subheadings. + You can use visibility cycling to study the tree, but the overlays + disappear when you change the buffer (see variable + ~org-remove-highlights-with-change~) or press {{{kbd(C-c C-c)}}}. + +The {{{kbd(l)}}} key may be used in the agenda (see [[*Weekly/daily +agenda]]) to show which tasks have been worked on or closed during +a day. + +*Important:* note that both ~org-clock-out~ and ~org-clock-in-last~ +can have a global keybinding and do not modify the window disposition. + +*** The clock table +:PROPERTIES: +:DESCRIPTION: Detailed reports. +:END: +#+cindex: clocktable, dynamic block +#+cindex: report, of clocked time + +Org mode can produce quite complex reports based on the time clocking +information. Such a report is called a /clock table/, because it is +formatted as one or several Org tables. + +#+attr_texinfo: :sep , +- ~org-clock-report~ :: + + #+kindex: C-c C-x x + #+findex: org-clock-report + Insert or update a clock table. When called with a prefix argument, + jump to the first clock table in the current document and update it. + The clock table includes archived trees. + + This command can be invoked by calling + ~org-dynamic-block-insert-dblock~ ({{{kbd(C-c C-x x)}}}) and + selecting "clocktable" (see [[*Dynamic Blocks]]). + +- {{{kbd(C-c C-c)}}} or {{{kbd(C-c C-x C-u)}}} (~org-dblock-update~) :: + + #+kindex: C-c C-c + #+kindex: C-c C-x C-u + #+findex: org-dblock-update + Update dynamic block at point. Point needs to be in the =BEGIN= + line of the dynamic block. + +- {{{kbd(C-u C-c C-x C-u)}}} :: + + #+kindex: C-u C-c C-x C-u + Update all dynamic blocks (see [[*Dynamic Blocks]]). This is useful if + you have several clock table blocks in a buffer. + +- {{{kbd(S-LEFT)}}}, {{{kbd(S-RIGHT)}}} (~org-clocktable-try-shift~) :: + + #+kindex: S-LEFT + #+kindex: S-RIGHT + #+findex: org-clocktable-try-shift + Shift the current =:block= interval and update the table. Point + needs to be in the =#+BEGIN: clocktable= line for this command. If + =:block= is =today=, it is shifted to =today-1=, etc. + +Here is an example of the frame for a clock table as it is inserted +into the buffer by ~org-clock-report~: + +#+cindex: @samp{BEGIN clocktable} +#+begin_example +,#+BEGIN: clocktable :maxlevel 2 :emphasize nil :scope file +,#+END: clocktable +#+end_example + +#+vindex: org-clocktable-defaults +The =#+BEGIN= line contains options to define the scope, structure, +and formatting of the report. Defaults for all these options can be +configured in the variable ~org-clocktable-defaults~. + +First there are options that determine which clock entries are to +be selected: + +- =:maxlevel= :: + + Maximum level depth to which times are listed in the table. Clocks + at deeper levels are summed into the upper level. + +- =:scope= :: + + The scope to consider. This can be any of the following: + + | =nil= | the current buffer or narrowed region | + | =file= | the full current buffer | + | =subtree= | the subtree where the clocktable is located | + | =treeN= | the surrounding level N tree, for example =tree3= | + | =tree= | the surrounding level 1 tree | + | =agenda= | all agenda files | + | =("file" ...)= | scan these files | + | =FUNCTION= | scan files returned by calling {{{var(FUNCTION)}}} with no argument | + | =file-with-archives= | current file and its archives | + | =agenda-with-archives= | all agenda files, including archives | + +- =:block= :: + + The time block to consider. This block is specified either + absolutely, or relative to the current time and may be any of these + formats: + + | =2007-12-31= | New year eve 2007 | + | =2007-12= | December 2007 | + | =2007-W50= | ISO-week 50 in 2007 | + | =2007-Q2= | 2nd quarter in 2007 | + | =2007= | the year 2007 | + | =today=, =yesterday=, =today-N= | a relative day | + | =thisweek=, =lastweek=, =thisweek-N= | a relative week | + | =thismonth=, =lastmonth=, =thismonth-N= | a relative month | + | =thisyear=, =lastyear=, =thisyear-N= | a relative year | + | =untilnow=[fn:78] | all clocked time ever | + + #+vindex: org-clock-display-default-range + When this option is not set, Org falls back to the value in + ~org-clock-display-default-range~, which defaults to the current + year. + + Use {{{kbd(S-LEFT)}}} or {{{kbd(S-RIGHT)}}} to shift the time + interval. + +- =:tstart= :: + + A time string specifying when to start considering times. Relative + times like ="<-2w>"= can also be used. See [[*Matching tags and + properties]] for relative time syntax. + +- =:tend= :: + + A time string specifying when to stop considering times. Relative + times like =""= can also be used. See [[*Matching tags and + properties]] for relative time syntax. + +- =:wstart= :: + + The starting day of the week. The default is 1 for Monday. + +- =:mstart= :: + + The starting day of the month. The default is 1 for the first. + +- =:step= :: + + Set to =day=, =week=, =semimonth=, =month=, or =year= to split the + table into chunks. To use this, either =:block=, or =:tstart= and + =:tend= are required. + +- =:stepskip0= :: + + When non-~nil~, do not show steps that have zero time. + +- =:fileskip0= :: + + When non-~nil~, do not show table sections from files which did not + contribute. + +- =:match= :: + + A tags match to select entries that should contribute. See + [[*Matching tags and properties]] for the match syntax. + +#+findex: org-clocktable-write-default +Then there are options that determine the formatting of the table. +There options are interpreted by the function +~org-clocktable-write-default~, but you can specify your own function +using the =:formatter= parameter. + +- =:emphasize= :: + + When non-~nil~, emphasize level one and level two items. + +- =:lang= :: + + Language[fn:79] to use for descriptive cells like "Task". + +- =:link= :: + + Link the item headlines in the table to their origins. + +- =:narrow= :: + + An integer to limit the width of the headline column in the Org + table. If you write it like =50!=, then the headline is also + shortened in export. + +- =:indent= :: + + Indent each headline field according to its level. + +- =:hidefiles= :: + + Hide the file column when multiple files are used to produce the + table. + +- =:tcolumns= :: + + Number of columns to be used for times. If this is smaller than + =:maxlevel=, lower levels are lumped into one column. + +- =:level= :: + + Should a level number column be included? + +- =:sort= :: + + A cons cell containing the column to sort and a sorting type. E.g., + =:sort (1 . ?a)= sorts the first column alphabetically. + +- =:compact= :: + + Abbreviation for =:level nil :indent t :narrow 40! :tcolumns 1=. + All are overwritten except if there is an explicit =:narrow=. + +- =:timestamp= :: + + A timestamp for the entry, when available. Look for =SCHEDULED=, + =DEADLINE=, =TIMESTAMP= and =TIMESTAMP_IA= special properties (see + [[*Special Properties]]), in this order. + +- =:tags= :: + + When this flag is non-~nil~, show the headline's tags. + +- =:properties= :: + + List of properties shown in the table. Each property gets its own + column. + +- =:inherit-props= :: + + When this flag is non-~nil~, the values for =:properties= are + inherited. + +- =:formula= :: + + Content of a =TBLFM= keyword to be added and evaluated. As + a special case, =:formula %= adds a column with % time. If you do + not specify a formula here, any existing formula below the clock + table survives updates and is evaluated. + +- =:formatter= :: + + A function to format clock data and insert it into the buffer. + +To get a clock summary of the current level 1 tree, for the current +day, you could write: + +#+begin_example +,#+BEGIN: clocktable :maxlevel 2 :block today :scope tree1 :link t +,#+END: clocktable +#+end_example + +#+texinfo: @noindent +To use a specific time range you could write[fn:80] + +#+begin_example +,#+BEGIN: clocktable :tstart "<2006-08-10 Thu 10:00>" + :tend "<2006-08-10 Thu 12:00>" +,#+END: clocktable +#+end_example + +#+texinfo: @noindent +A range starting a week ago and ending right now could be written as + +#+begin_example +,#+BEGIN: clocktable :tstart "<-1w>" :tend "" +,#+END: clocktable +#+end_example + +#+texinfo: @noindent +A summary of the current subtree with % times would be + +#+begin_example +,#+BEGIN: clocktable :scope subtree :link t :formula % +,#+END: clocktable +#+end_example + +#+texinfo: @noindent +A horizontally compact representation of everything clocked during +last week would be + +#+begin_example +,#+BEGIN: clocktable :scope agenda :block lastweek :compact t +,#+END: clocktable +#+end_example + +*** Resolving idle time and continuous clocking +:PROPERTIES: +:DESCRIPTION: Resolving time when you've been idle. +:ALT_TITLE: Resolving idle time +:END: + +**** Resolving idle time +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: resolve idle time +#+cindex: idle, resolve, dangling + +If you clock in on a work item, and then walk away from your +computer---perhaps to take a phone call---you often need to +"resolve" the time you were away by either subtracting it from the +current clock, or applying it to another one. + +#+vindex: org-clock-idle-time +#+vindex: org-clock-x11idle-program-name +By customizing the variable ~org-clock-idle-time~ to some integer, +such as 10 or 15, Emacs can alert you when you get back to your +computer after being idle for that many minutes[fn:81], and ask what +you want to do with the idle time. There will be a question waiting +for you when you get back, indicating how much idle time has passed +constantly updated with the current amount, as well as a set of +choices to correct the discrepancy: + +- {{{kbd(k)}}} :: + + #+kindex: k + To keep some or all of the minutes and stay clocked in, press + {{{kbd(k)}}}. Org asks how many of the minutes to keep. Press + {{{kbd(RET)}}} to keep them all, effectively changing nothing, or + enter a number to keep that many minutes. + +- {{{kbd(K)}}} :: + + #+kindex: K + If you use the shift key and press {{{kbd(K)}}}, it keeps however + many minutes you request and then immediately clock out of that + task. If you keep all of the minutes, this is the same as just + clocking out of the current task. + +- {{{kbd(s)}}} :: + + #+kindex: s + To keep none of the minutes, use {{{kbd(s)}}} to subtract all the + away time from the clock, and then check back in from the moment you + returned. + +- {{{kbd(S)}}} :: + + #+kindex: S + To keep none of the minutes and just clock out at the start of the + away time, use the shift key and press {{{kbd(S)}}}. Remember that + using shift always leave you clocked out, no matter which option you + choose. + +- {{{kbd(C)}}} :: + + #+kindex: C + To cancel the clock altogether, use {{{kbd(C)}}}. Note that if + instead of canceling you subtract the away time, and the resulting + clock amount is less than a minute, the clock is still canceled + rather than cluttering up the log with an empty entry. + +What if you subtracted those away minutes from the current clock, and +now want to apply them to a new clock? Simply clock in to any task +immediately after the subtraction. Org will notice that you have +subtracted time "on the books", so to speak, and will ask if you want +to apply those minutes to the next task you clock in on. + +There is one other instance when this clock resolution magic occurs. +Say you were clocked in and hacking away, and suddenly your cat chased +a mouse who scared a hamster that crashed into your UPS's power +button! You suddenly lose all your buffers, but thanks to auto-save +you still have your recent Org mode changes, including your last clock +in. + +If you restart Emacs and clock into any task, Org will notice that you +have a dangling clock which was never clocked out from your last +session. Using that clock's starting time as the beginning of the +unaccounted-for period, Org will ask how you want to resolve that +time. The logic and behavior is identical to dealing with away time +due to idleness; it is just happening due to a recovery event rather +than a set amount of idle time. + +You can also check all the files visited by your Org agenda for +dangling clocks at any time using {{{kbd(M-x org-resolve-clocks +RET)}}} (or {{{kbd(C-c C-x C-z)}}}). + +**** Continuous clocking +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: continuous clocking + +#+vindex: org-clock-continuously +You may want to start clocking from the time when you clocked out the +previous task. To enable this systematically, set +~org-clock-continuously~ to non-~nil~. Each time you clock in, Org +retrieves the clock-out time of the last clocked entry for this +session, and start the new clock from there. + +If you only want this from time to time, use three universal prefix +arguments with ~org-clock-in~ and two {{{kbd(C-u C-u)}}} with +~org-clock-in-last~. + +**** Clocking out automatically after some idle time +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: auto clocking out after idle time + +#+vindex: org-clock-auto-clockout-timer +When you often forget to clock out before being idle and you don't +want to manually set the clocking time to take into account, you can +set ~org-clock-auto-clockout-timer~ to a number of seconds and add +=(org-clock-auto-clockout-insinuate)= to your =.emacs= file. + +When the clock is running and Emacs is idle for more than this number +of seconds, the clock will be clocked out automatically. + +Use =M-x org-clock-toggle-auto-clockout RET= to temporarily turn this +on or off. + +** Effort Estimates +:PROPERTIES: +:DESCRIPTION: Planning work effort in advance. +:END: +#+cindex: effort estimates +#+cindex: @samp{EFFORT}, property +#+vindex: org-effort-property + +If you want to plan your work in a very detailed way, or if you need +to produce offers with quotations of the estimated work effort, you +may want to assign effort estimates to entries. If you are also +clocking your work, you may later want to compare the planned effort +with the actual working time, a great way to improve planning +estimates. + +Effort estimates are stored in a special property =EFFORT=. Multiple +formats are supported, such as =3:12=, =1:23:45=, or =1d3h5min=; see +the file =org-duration.el= for more detailed information about the +format. + +You can set the effort for an entry with the following commands: + +- {{{kbd(C-c C-x e)}}} (~org-set-effort~) :: + + #+kindex: C-c C-x e + #+findex: org-set-effort + Set the effort estimate for the current entry. With a prefix + argument, set it to the next allowed value---see below. This + command is also accessible from the agenda with the {{{kbd(e)}}} + key. + +- {{{kbd(C-c C-x C-e)}}} (~org-clock-modify-effort-estimate~) :: + + #+kindex: C-c C-x C-e + #+findex: org-clock-modify-effort-estimate + Modify the effort estimate of the item currently being clocked. + +Clearly the best way to work with effort estimates is through column +view (see [[*Column View]]). You should start by setting up discrete +values for effort estimates, and a =COLUMNS= format that displays +these values together with clock sums---if you want to clock your +time. For a specific buffer you can use: + +#+begin_example +,#+PROPERTY: Effort_ALL 0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00 +,#+COLUMNS: %40ITEM(Task) %17Effort(Estimated Effort){:} %CLOCKSUM +#+end_example + +#+texinfo: @noindent +#+vindex: org-global-properties +#+vindex: org-columns-default-format +or, even better, you can set up these values globally by customizing +the variables ~org-global-properties~ and +~org-columns-default-format~. In particular if you want to use this +setup also in the agenda, a global setup may be advised. + +The way to assign estimates to individual items is then to switch to +column mode, and to use {{{kbd(S-RIGHT)}}} and {{{kbd(S-LEFT)}}} to +change the value. The values you enter are immediately summed up in +the hierarchy. In the column next to it, any clocked time is +displayed. + +#+vindex: org-agenda-columns-add-appointments-to-effort-sum +If you switch to column view in the daily/weekly agenda, the effort +column summarizes the estimated work effort for each day[fn:82], and +you can use this to find space in your schedule. To get an overview +of the entire part of the day that is committed, you can set the +option ~org-agenda-columns-add-appointments-to-effort-sum~. The +appointments on a day that take place over a specified time interval +are then also added to the load estimate of the day. + +Effort estimates can be used in secondary agenda filtering that is +triggered with the {{{kbd(/)}}} key in the agenda (see [[*Commands in +the Agenda Buffer]]). If you have these estimates defined consistently, +two or three key presses narrow down the list to stuff that fits into +an available time slot. + +** Taking Notes with a Relative Timer +:PROPERTIES: +:DESCRIPTION: Notes with a running timer. +:ALT_TITLE: Timers +:END: +#+cindex: relative timer +#+cindex: countdown timer + +Org provides two types of timers. There is a relative timer that +counts up, which can be useful when taking notes during, for example, +a meeting or a video viewing. There is also a countdown timer. + +The relative and countdown are started with separate commands. + +- {{{kbd(C-c C-x 0)}}} (~org-timer-start~) :: + + #+kindex: C-c C-x 0 + #+findex: org-timer-start + Start or reset the relative timer. By default, the timer is set + to 0. When called with a {{{kbd(C-u)}}} prefix, prompt the user for + a starting offset. If there is a timer string at point, this is + taken as the default, providing a convenient way to restart taking + notes after a break in the process. When called with a double + prefix argument {{{kbd(C-u C-u)}}}, change all timer strings in the + active region by a certain amount. This can be used to fix timer + strings if the timer was not started at exactly the right moment. + +- {{{kbd(C-c C-x ;)}}} (~org-timer-set-timer~) :: + + #+kindex: C-c C-x ; + #+findex: org-timer-set-timer + #+vindex: org-timer-default-timer + Start a countdown timer. The user is prompted for a duration. + ~org-timer-default-timer~ sets the default countdown value. Giving + a numeric prefix argument overrides this default value. This + command is available as {{{kbd(;)}}} in agenda buffers. + +Once started, relative and countdown timers are controlled with the +same commands. + +- {{{kbd(C-c C-x .)}}} (~org-timer~) :: + + #+kindex: C-c C-x . + #+findex: org-timer + Insert a relative time into the buffer. The first time you use + this, the timer starts. Using a prefix argument restarts it. + +- {{{kbd(C-c C-x -)}}} (~org-timer-item~) :: + + #+kindex: C-c C-x - + #+findex: org-timer-item + Insert a description list item with the current relative time. With + a prefix argument, first reset the timer to 0. + +- {{{kbd(M-RET)}}} (~org-insert-heading~) :: + + #+kindex: M-RET + #+findex: org-insert-heading + Once the timer list is started, you can also use {{{kbd(M-RET)}}} to + insert new timer items. + +- {{{kbd(C-c C-x \,)}}} (~org-timer-pause-or-continue~) :: + + #+kindex: C-c C-x , + #+findex: org-timer-pause-or-continue + Pause the timer, or continue it if it is already paused. + +- {{{kbd(C-c C-x _)}}} (~org-timer-stop~) :: + + #+kindex: C-c C-x _ + #+findex: org-timer-stop + Stop the timer. After this, you can only start a new timer, not + continue the old one. This command also removes the timer from the + mode line. + +* Refiling and Archiving +:PROPERTIES: +:DESCRIPTION: Moving and copying information with ease. +:END: +#+cindex: refiling notes +#+cindex: copying notes +#+cindex: archiving + +Once information is in the system, it may need to be moved around. +Org provides Refile, Copy and Archive commands for this. Refile and +Copy helps with moving and copying outlines. Archiving helps to keep +the system compact and fast. + +** Refile and Copy +:PROPERTIES: +:DESCRIPTION: Moving/copying a tree from one place to another. +:END: +#+cindex: refiling notes +#+cindex: copying notes + +When reviewing the captured data, you may want to refile or to copy +some of the entries into a different list, for example into a project. +Cutting, finding the right location, and then pasting the note is +cumbersome. To simplify this process, you can use the following +special command: + +- {{{kbd(C-c C-w)}}} (~org-refile~) :: + + #+kindex: C-c C-w + #+findex: org-refile + #+vindex: org-reverse-note-order + #+vindex: org-refile-targets + #+vindex: org-refile-use-outline-path + #+vindex: org-outline-path-complete-in-steps + #+vindex: org-refile-allow-creating-parent-nodes + #+vindex: org-log-refile + Refile the entry or region at point. This command offers possible + locations for refiling the entry and lets you select one with + completion. The item (or all items in the region) is filed below + the target heading as a subitem. Depending on + ~org-reverse-note-order~, it is either the first or last subitem. + + By default, all level 1 headlines in the current buffer are + considered to be targets, but you can have more complex definitions + across a number of files. See the variable ~org-refile-targets~ for + details. If you would like to select a location via + a file-path-like completion along the outline path, see the + variables ~org-refile-use-outline-path~ and + ~org-outline-path-complete-in-steps~. If you would like to be able + to create new nodes as new parents for refiling on the fly, check + the variable ~org-refile-allow-creating-parent-nodes~. When the + variable ~org-log-refile~[fn:83] is set, a timestamp or a note is + recorded whenever an entry is refiled. + +- {{{kbd(C-u C-c C-w)}}} :: + + #+kindex: C-u C-c C-w + Use the refile interface to jump to a heading. + +- {{{kbd(C-u C-u C-c C-w)}}} (~org-refile-goto-last-stored~) :: + + #+kindex: C-u C-u C-c C-w + #+findex: org-refile-goto-last-stored + Jump to the location where ~org-refile~ last moved a tree to. + +- {{{kbd(C-2 C-c C-w)}}} :: + + #+kindex: C-2 C-c C-w + Refile as the child of the item currently being clocked. + +- {{{kbd(C-3 C-c C-w)}}} :: + + #+kindex: C-3 C-c C-w + #+vindex: org-refile-keep + Refile and keep the entry in place. Also see ~org-refile-keep~ to + make this the default behavior, and beware that this may result in + duplicated =ID= properties. + +- {{{kbd(C-0 C-c C-w)}}} or {{{kbd(C-u C-u C-u C-c C-w)}}} (~org-refile-cache-clear~) :: + + #+kindex: C-u C-u C-u C-c C-w + #+kindex: C-0 C-c C-w + #+findex: org-refile-cache-clear + #+vindex: org-refile-use-cache + Clear the target cache. Caching of refile targets can be turned on + by setting ~org-refile-use-cache~. To make the command see new + possible targets, you have to clear the cache with this command. + +- {{{kbd(C-c M-w)}}} (~org-refile-copy~) :: + + #+kindex: C-c M-w + #+findex: org-refile-copy + Copying works like refiling, except that the original note is not + deleted. + +** Archiving +:PROPERTIES: +:DESCRIPTION: What to do with finished products. +:END: +#+cindex: archiving + +When a project represented by a (sub)tree is finished, you may want to +move the tree out of the way and to stop it from contributing to the +agenda. Archiving is important to keep your working files compact and +global searches like the construction of agenda views fast. + +- {{{kbd(C-c C-x C-a)}}} (~org-archive-subtree-default~) :: + + #+kindex: C-c C-x C-a + #+findex: org-archive-subtree-default + #+vindex: org-archive-default-command + Archive the current entry using the command specified in the + variable ~org-archive-default-command~. + +*** Moving a tree to an archive file +:PROPERTIES: +:DESCRIPTION: Moving a tree to an archive file. +:ALT_TITLE: Moving subtrees +:END: +#+cindex: external archiving + +The most common archiving action is to move a project tree to another +file, the archive file. + +- {{{kbd(C-c C-x C-s)}}} or short {{{kbd(C-c $)}}} (~org-archive-subtree~) :: + + #+kindex: C-c C-x C-s + #+kindex: C-c $ + #+findex: org-archive-subtree + #+vindex: org-archive-location + Archive the subtree starting at point position to the location given + by ~org-archive-location~. + +- {{{kbd(C-u C-c C-x C-s)}}} :: + + #+kindex: C-u C-c C-x C-s + Check if any direct children of the current headline could be moved + to the archive. To do this, check each subtree for open TODO + entries. If none is found, the command offers to move it to the + archive location. If point is /not/ on a headline when this command + is invoked, check level 1 trees. + +- {{{kbd(C-u C-u C-c C-x C-s)}}} :: + + #+kindex: C-u C-u C-c C-x C-s + As above, but check subtree for timestamps instead of TODO entries. + The command offers to archive the subtree if it /does/ contain + a timestamp, and that timestamp is in the past. + +#+cindex: archive locations +The default archive location is a file in the same directory as the +current file, with the name derived by appending =_archive= to the +current file name. You can also choose what heading to file archived +items under, with the possibility to add them to a datetree in a file. +For information and examples on how to specify the file and the +heading, see the documentation string of the variable +~org-archive-location~. + +There is also an in-buffer option for setting this variable, for +example: + +#+cindex: @samp{ARCHIVE}, keyword +: #+ARCHIVE: %s_done:: + +#+cindex: ARCHIVE, property +If you would like to have a special archive location for a single +entry or a (sub)tree, give the entry an =ARCHIVE= property with the +location as the value (see [[*Properties and Columns]]). + +#+vindex: org-archive-save-context-info +When a subtree is moved, it receives a number of special properties +that record context information like the file from where the entry +came, its outline path the archiving time etc. Configure the variable +~org-archive-save-context-info~ to adjust the amount of information +added. + +#+vindex: org-archive-subtree-save-file-p +When ~org-archive-subtree-save-file-p~ is non-~nil~, save the target +archive buffer. + +*** Internal archiving +:PROPERTIES: +:DESCRIPTION: Switch off a tree but keep it in the file. +:END: + +#+cindex: @samp{ARCHIVE}, tag +If you want to just switch off---for agenda views---certain subtrees +without moving them to a different file, you can use the =ARCHIVE= +tag. + +A headline that is marked with the =ARCHIVE= tag (see [[*Tags]]) stays at +its location in the outline tree, but behaves in the following way: + +- + #+vindex: org-cycle-open-archived-trees + It does not open when you attempt to do so with a visibility cycling + command (see [[*Visibility Cycling]]). You can force cycling archived + subtrees with {{{kbd(C-TAB)}}}, or by setting the option + ~org-cycle-open-archived-trees~. Also normal outline commands, like + ~outline-show-all~, open archived subtrees. + +- + #+vindex: org-sparse-tree-open-archived-trees + During sparse tree construction (see [[*Sparse Trees]]), matches in + archived subtrees are not exposed, unless you configure the option + ~org-sparse-tree-open-archived-trees~. + +- + #+vindex: org-agenda-skip-archived-trees + During agenda view construction (see [[*Agenda Views]]), the content of + archived trees is ignored unless you configure the option + ~org-agenda-skip-archived-trees~, in which case these trees are + always included. In the agenda you can press {{{kbd(v a)}}} to get + archives temporarily included. + +- + #+vindex: org-export-with-archived-trees + Archived trees are not exported (see [[*Exporting]]), only the headline + is. Configure the details using the variable + ~org-export-with-archived-trees~. + +- + #+vindex: org-columns-skip-archived-trees + Archived trees are excluded from column view unless the variable + ~org-columns-skip-archived-trees~ is configured to ~nil~. + +The following commands help manage the =ARCHIVE= tag: + +- {{{kbd(C-c C-x a)}}} (~org-toggle-archive-tag~) :: + + #+kindex: C-c C-x a + #+findex: org-toggle-archive-tag + Toggle the archive tag for the current headline. When the tag is + set, the headline changes to a shadowed face, and the subtree below + it is hidden. + +- {{{kbd(C-u C-c C-x a)}}} :: + + #+kindex: C-u C-c C-x a + Check if any direct children of the current headline should be + archived. To do this, check each subtree for open TODO entries. If + none is found, the command offers to set the =ARCHIVE= tag for the + child. If point is /not/ on a headline when this command is + invoked, check the level 1 trees. + +- {{{kbd(C-c C-TAB)}}} (~org-force-cycle-archived~) :: + + #+kindex: C-TAB + Cycle a tree even if it is tagged with =ARCHIVE=. + +- {{{kbd(C-c C-x A)}}} (~org-archive-to-archive-sibling~) :: + + #+kindex: C-c C-x A + #+findex: org-archive-to-archive-sibling + Move the current entry to the /Archive Sibling/. This is a sibling + of the entry with the heading =Archive= and the archive tag. The + entry becomes a child of that sibling and in this way retains a lot + of its original context, including inherited tags and approximate + position in the outline. + +* Capture and Attachments +:PROPERTIES: +:DESCRIPTION: Dealing with external data. +:END: +#+cindex: capture +#+cindex: attachments +#+cindex: RSS feeds +#+cindex: Atom feeds +#+cindex: protocols, for external access + +An important part of any organization system is the ability to quickly +capture new ideas and tasks, and to associate reference material with +them. Org does this using a process called /capture/. It also can +store files related to a task (/attachments/) in a special directory. +Finally, it can parse RSS feeds for information. To learn how to let +external programs (for example a web browser) trigger Org to capture +material, see [[*Protocols for External Access]]. + +** Capture +:PROPERTIES: +:DESCRIPTION: Capturing new stuff. +:END: +#+cindex: capture + +Capture lets you quickly store notes with little interruption of your +work flow. Org's method for capturing new items is heavily inspired +by John Wiegley's excellent Remember package. + +*** Setting up capture +:PROPERTIES: +:DESCRIPTION: Where notes will be stored. +:END: + +The following customization sets a default target file for notes. + +#+vindex: org-default-notes-file +#+begin_src emacs-lisp +(setq org-default-notes-file (concat org-directory "/notes.org")) +#+end_src + +You may also define a global key for capturing new material (see +[[*Activation]]). + +*** Using capture +:PROPERTIES: +:DESCRIPTION: Commands to invoke and terminate capture. +:END: + +- {{{kbd(M-x org-capture)}}} (~org-capture~) :: + + #+findex: org-capture + #+cindex: date tree + Display the capture templates menu. If you have templates defined + (see [[*Capture templates]]), it offers these templates for selection or + use a new Org outline node as the default template. It inserts the + template into the target file and switch to an indirect buffer + narrowed to this new node. You may then insert the information you + want. + +- {{{kbd(C-c C-c)}}} (~org-capture-finalize~) :: + + #+kindex: C-c C-c @r{(Capture buffer)} + #+findex: org-capture-finalize + Once you have finished entering information into the capture buffer, + {{{kbd(C-c C-c)}}} returns you to the window configuration before + the capture process, so that you can resume your work without + further distraction. When called with a prefix argument, finalize + and then jump to the captured item. + +- {{{kbd(C-c C-w)}}} (~org-capture-refile~) :: + + #+kindex: C-c C-w @r{(Capture buffer)} + #+findex: org-capture-refile + Finalize the capture process by refiling the note to a different + place (see [[*Refile and Copy]]). Please realize that this is a normal + refiling command that will be executed---so point position at the + moment you run this command is important. If you have inserted + a tree with a parent and children, first move point back to the + parent. Any prefix argument given to this command is passed on to + the ~org-refile~ command. + +- {{{kbd(C-c C-k)}}} (~org-capture-kill~) :: + + #+kindex: C-c C-k @r{(Capture buffer)} + #+findex: org-capture-kill + Abort the capture process and return to the previous state. + +#+kindex: k c @r{(Agenda)} +You can also call ~org-capture~ in a special way from the agenda, +using the {{{kbd(k c)}}} key combination. With this access, any +timestamps inserted by the selected capture template defaults to the +date at point in the agenda, rather than to the current date. + +To find the locations of the last stored capture, use ~org-capture~ +with prefix commands: + +- {{{kbd(C-u M-x org-capture)}}} :: + + Visit the target location of a capture template. You get to select + the template in the usual way. + +- {{{kbd(C-u C-u M-x org-capture)}}} :: + + Visit the last stored capture item in its buffer. + +#+vindex: org-capture-bookmark +#+vindex: org-capture-last-stored +You can also jump to the bookmark ~org-capture-last-stored~, which is +automatically created unless you set ~org-capture-bookmark~ to ~nil~. + +To insert the capture at point in an Org buffer, call ~org-capture~ +with a {{{kbd(C-0)}}} prefix argument. + +*** Capture templates +:PROPERTIES: +:DESCRIPTION: Define the outline of different note types. +:END: +#+cindex: templates, for Capture + +You can use templates for different types of capture items, and for +different target locations. The easiest way to create such templates +is through the customize interface. + +- {{{kbd(C)}}} :: + + #+kindex: C @r{(Capture menu} + #+vindex: org-capture-templates + Customize the variable ~org-capture-templates~. + +Before we give the formal description of template definitions, let's +look at an example. Say you would like to use one template to create +general TODO entries, and you want to put these entries under the +heading =Tasks= in your file =~/org/gtd.org=. Also, a date tree in +the file =journal.org= should capture journal entries. A possible +configuration would look like: + +#+begin_src emacs-lisp +(setq org-capture-templates + '(("t" "Todo" entry (file+headline "~/org/gtd.org" "Tasks") + "* TODO %?\n %i\n %a") + ("j" "Journal" entry (file+datetree "~/org/journal.org") + "* %?\nEntered on %U\n %i\n %a"))) +#+end_src + +If you then press {{{kbd(t)}}} from the capture menu, Org will prepare +the template for you like this: + +#+begin_example +,* TODO + [[file:LINK TO WHERE YOU INITIATED CAPTURE]] +#+end_example + +#+texinfo: @noindent +During expansion of the template, =%a= has been replaced by a link to +the location from where you called the capture command. This can be +extremely useful for deriving tasks from emails, for example. You +fill in the task definition, press {{{kbd(C-c C-c)}}} and Org returns +you to the same place where you started the capture process. + +To define special keys to capture to a particular template without +going through the interactive template selection, you can create your +key binding like this: + +#+begin_src emacs-lisp +(define-key global-map (kbd "C-c x") + (lambda () (interactive) (org-capture nil "x"))) +#+end_src + +**** Template elements +:PROPERTIES: +:DESCRIPTION: What is needed for a complete template entry. +:END: + +Now lets look at the elements of a template definition. Each entry in +~org-capture-templates~ is a list with the following items: + +- keys :: + + The keys that selects the template, as a string, characters only, + for example ="a"=, for a template to be selected with a single key, + or ="bt"= for selection with two keys. When using several keys, + keys using the same prefix key must be sequential in the list and + preceded by a 2-element entry explaining the prefix key, for + example: + + #+begin_src emacs-lisp + ("b" "Templates for marking stuff to buy") + #+end_src + + If you do not define a template for the {{{kbd(C)}}} key, this key + opens the Customize buffer for this complex variable. + +- description :: + + A short string describing the template, shown during selection. + +- type :: + + The type of entry, a symbol. Valid values are: + + - ~entry~ :: + + An Org mode node, with a headline. Will be filed as the child of + the target entry or as a top-level entry. The target file should + be an Org file. + + - ~item~ :: + + A plain list item, placed in the first plain list at the target + location. Again the target file should be an Org file. + + - ~checkitem~ :: + + A checkbox item. This only differs from the plain list item by + the default template. + + - ~table-line~ :: + + A new line in the first table at the target location. Where + exactly the line will be inserted depends on the properties + ~:prepend~ and ~:table-line-pos~ (see below). + + - ~plain~ :: + + Text to be inserted as it is. + +- target :: + + #+vindex: org-default-notes-file + #+vindex: org-directory + Specification of where the captured item should be placed. In Org + files, targets usually define a node. Entries will become children + of this node. Other types will be added to the table or list in the + body of this node. Most target specifications contain a file name. + If that file name is the empty string, it defaults to + ~org-default-notes-file~. A file can also be given as a variable or + as a function called with no argument. When an absolute path is not + specified for a target, it is taken as relative to ~org-directory~. + + Valid values are: + + - =(file "path/to/file")= :: + + Text will be placed at the beginning or end of that file. + + - =(id "id of existing org entry")= :: + + Filing as child of this entry, or in the body of the entry. + + - =(file+headline "filename" "node headline")= :: + + Fast configuration if the target heading is unique in the file. + + - =(file+olp "filename" "Level 1 heading" "Level 2" ...)= :: + + For non-unique headings, the full path is safer. + + - =(file+regexp "filename" "regexp to find location")= :: + + Use a regular expression to position point. + + - =(file+olp+datetree "filename" [ "Level 1 heading" ...])= :: + + This target[fn:84] creates a heading in a date tree[fn:85] for + today's date. If the optional outline path is given, the tree + will be built under the node it is pointing to, instead of at top + level. Check out the ~:time-prompt~ and ~:tree-type~ properties + below for additional options. + + - =(file+function "filename" function-finding-location)= :: + + A function to find the right location in the file. + + - =(clock)= :: + + File to the entry that is currently being clocked. + + - =(function function-finding-location)= :: + + Most general way: write your own function which both visits the + file and moves point to the right location. + +- template :: + + The template for creating the capture item. If you leave this + empty, an appropriate default template will be used. Otherwise this + is a string with escape codes, which will be replaced depending on + time and context of the capture call. You may also get this + template string from a file[fn:86], or dynamically, from a function + using either syntax: + + : (file "/path/to/template-file") + : (function FUNCTION-RETURNING-THE-TEMPLATE) + +- properties :: + + The rest of the entry is a property list of additional options. + Recognized properties are: + + - ~:prepend~ :: + + Normally new captured information will be appended at the target + location (last child, last table line, last list item, ...). + Setting this property changes that. + + - ~:immediate-finish~ :: + + When set, do not offer to edit the information, just file it away + immediately. This makes sense if the template only needs + information that can be added automatically. + + - ~:jump-to-captured~ :: + + When set, jump to the captured entry when finished. + + - ~:empty-lines~ :: + + Set this to the number of lines to insert before and after the new + item. Default 0, and the only other common value is 1. + + - ~:empty-lines-after~ :: + + Set this to the number of lines that should be inserted after the + new item. Overrides ~:empty-lines~ for the number of lines + inserted after. + + - ~:empty-lines-before~ :: + + Set this to the number of lines that should be inserted before the + new item. Overrides ~:empty-lines~ for the number lines inserted + before. + + - ~:clock-in~ :: + + Start the clock in this item. + + - ~:clock-keep~ :: + + Keep the clock running when filing the captured entry. + + - ~:clock-resume~ :: + + If starting the capture interrupted a clock, restart that clock + when finished with the capture. Note that ~:clock-keep~ has + precedence over ~:clock-resume~. When setting both to non-~nil~, + the current clock will run and the previous one will not be + resumed. + + - ~:time-prompt~ :: + + Prompt for a date/time to be used for date/week trees and when + filling the template. Without this property, capture uses the + current date and time. Even if this property has not been set, + you can force the same behavior by calling ~org-capture~ with + a {{{kbd(C-1)}}} prefix argument. + + - ~:tree-type~ :: + + Use ~week~ to make a week tree instead of the month-day tree, + i.e., place the headings for each day under a heading with the + current ISO week. Use ~month~ to group entries by month + only. Default is to group entries by day. + + - ~:unnarrowed~ :: + + Do not narrow the target buffer, simply show the full buffer. + Default is to narrow it so that you only see the new material. + + - ~:table-line-pos~ :: + + Specification of the location in the table where the new line + should be inserted. It should be a string like =II-3= meaning + that the new line should become the third line before the second + horizontal separator line. + + - ~:kill-buffer~ :: + + If the target file was not yet visited when capture was invoked, + kill the buffer again after capture is completed. + + - ~:no-save~ :: + + Do not save the target file after finishing the capture. + +**** Template expansion +:PROPERTIES: +:DESCRIPTION: Filling in information about time and context. +:END: + +In the template itself, special "%-escapes"[fn:87] allow dynamic +insertion of content. The templates are expanded in the order given +here: + +- =%[FILE]= :: + + Insert the contents of the file given by {{{var(FILE)}}}. + +- =%(EXP)= :: + + Evaluate Elisp expression {{{var(EXP)}}} and replace it with the + result. The {{{var(EXP)}}} form must return a string. Only + placeholders pre-existing within the template, or introduced with + =%[file]=, are expanded this way. Since this happens after + expanding non-interactive "%-escapes", those can be used to fill the + expression. + +- =%= :: + + The result of format-time-string on the {{{var(FORMAT)}}} + specification. + +- =%t= :: + + Timestamp, date only. + +- =%T= :: + + Timestamp, with date and time. + +- =%u=, =%U= :: + + Like =%t=, =%T= above, but inactive timestamps. + +- =%i= :: + + Initial content, the region when capture is called while the region + is active. If there is text before =%i= on the same line, such as + indentation, and =%i= is not inside a =%(exp)= form, that prefix is + added before every line in the inserted text. + +- =%a= :: + + Annotation, normally the link created with ~org-store-link~. + +- =%A= :: + + Like =%a=, but prompt for the description part. + +- =%l= :: + + Like =%a=, but only insert the literal link. + +- =%c= :: + + Current kill ring head. + +- =%x= :: + + Content of the X clipboard. + +- =%k= :: + + Title of the currently clocked task. + +- =%K= :: + + Link to the currently clocked task. + +- =%n= :: + + User name (taken from ~user-full-name~). + +- =%f= :: + + File visited by current buffer when org-capture was called. + +- =%F= :: + + Full path of the file or directory visited by current buffer. + +- =%:keyword= :: + + Specific information for certain link types, see below. + +- =%^g= :: + + Prompt for tags, with completion on tags in target file. + +- =%^G= :: + + Prompt for tags, with completion all tags in all agenda files. + +- =%^t= :: + + Like =%t=, but prompt for date. Similarly =%^T=, =%^u=, =%^U=. You + may define a prompt like =%^{Birthday}t=. + +- =%^C= :: + + Interactive selection of which kill or clip to use. + +- =%^L= :: + + Like =%^C=, but insert as link. + +- =%^{PROP}p= :: + + Prompt the user for a value for property {{{var(PROP)}}}. + +- =%^{PROMPT}= :: + + Prompt the user for a string and replace this sequence with it. You + may specify a default value and a completion table with + =%^{prompt|default|completion2|completion3...}=. The arrow keys + access a prompt-specific history. + +- =%\N= :: + + Insert the text entered at the {{{var(N)}}}th =%^{PROMPT}=, where + {{{var(N)}}} is a number, starting from 1. + +- =%?= :: + + After completing the template, position point here. + +#+vindex: org-store-link-props +For specific link types, the following keywords are defined[fn:88]: + +#+vindex: org-link-from-user-regexp +| Link type | Available keywords | +|--------------+----------------------------------------------------------| +| bbdb | =%:name=, =%:company= | +| irc | =%:server=, =%:port=, =%:nick= | +| mh, rmail | =%:type=, =%:subject=, =%:message-id= | +| | =%:from=, =%:fromname=, =%:fromaddress= | +| | =%:to=, =%:toname=, =%:toaddress= | +| | =%:date= (message date header field) | +| | =%:date-timestamp= (date as active timestamp) | +| | =%:date-timestamp-inactive= (date as inactive timestamp) | +| | =%:fromto= (either "to NAME" or "from NAME")[fn:89] | +| gnus | =%:group=, for messages also all email fields | +| w3, w3m | =%:url= | +| info | =%:file=, =%:node= | +| calendar | =%:date= | +| org-protocol | =%:link=, =%:description=, =%:annotation= | + +**** Templates in contexts +:PROPERTIES: +:DESCRIPTION: Only show a template in a specific context. +:END: + +#+vindex: org-capture-templates-contexts +To control whether a capture template should be accessible from +a specific context, you can customize +~org-capture-templates-contexts~. Let's say, for example, that you +have a capture template "p" for storing Gnus emails containing +patches. Then you would configure this option like this: + +#+begin_src emacs-lisp +(setq org-capture-templates-contexts + '(("p" (in-mode . "message-mode")))) +#+end_src + +You can also tell that the command key {{{kbd(p)}}} should refer to +another template. In that case, add this command key like this: + +#+begin_src emacs-lisp +(setq org-capture-templates-contexts + '(("p" "q" (in-mode . "message-mode")))) +#+end_src + +See the docstring of the variable for more information. + +** Attachments +:PROPERTIES: +:DESCRIPTION: Attach files to outlines. +:END: +#+cindex: attachments + +It is often useful to associate reference material with an outline +node. Small chunks of plain text can simply be stored in the subtree +of a project. Hyperlinks (see [[*Hyperlinks]]) can establish associations +with files that live elsewhere on a local, or even remote, computer, +like emails or source code files belonging to a project. + +Another method is /attachments/, which are files located in a +directory belonging to an outline node. Org uses directories either +named by a unique ID of each entry, or by a =DIR= property. + +*** Attachment defaults and dispatcher +:PROPERTIES: +:DESCRIPTION: How to access attachment commands +:END: + +By default, Org attach uses ID properties when adding attachments to +outline nodes. This makes working with attachments fully automated. +There is no decision needed for folder-name or location. ID-based +directories are by default located in the =data/= directory, which +lives in the same directory where your Org file lives[fn:90]. + +When attachments are made using ~org-attach~ a default tag =ATTACH= is +added to the node that gets the attachments. + +For more control over the setup, see [[*Attachment options]]. + +The following commands deal with attachments: + +- {{{kbd(C-c C-a)}}} (~org-attach~) :: + + #+kindex: C-c C-a + #+findex: org-attach + The dispatcher for commands related to the attachment system. After + these keys, a list of commands is displayed and you must press an + additional key to select a command: + + - {{{kbd(a)}}} (~org-attach-attach~) :: + + #+kindex: C-c C-a a + #+findex: org-attach-attach + #+vindex: org-attach-method + Select a file and move it into the task's attachment directory. + The file is copied, moved, or linked, depending on + ~org-attach-method~. Note that hard links are not supported on + all systems. + + - {{{kbd(c)}}}/{{{kbd(m)}}}/{{{kbd(l)}}} :: + + #+kindex: C-c C-a c + #+kindex: C-c C-a m + #+kindex: C-c C-a l + Attach a file using the copy/move/link method. Note that hard + links are not supported on all systems. + + - {{{kbd(b)}}} (~org-attach-buffer~) :: + + #+kindex: C-c C-a b + #+findex: org-attach-buffer + Select a buffer and save it as a file in the task's attachment + directory. + + - {{{kbd(n)}}} (~org-attach-new~) :: + + #+kindex: C-c C-a n + #+findex: org-attach-new + Create a new attachment as an Emacs buffer. + + - {{{kbd(z)}}} (~org-attach-sync~) :: + + #+kindex: C-c C-a z + #+findex: org-attach-sync + Synchronize the current task with its attachment directory, in + case you added attachments yourself. + + - {{{kbd(o)}}} (~org-attach-open~) :: + + #+kindex: C-c C-a o + #+findex: org-attach-open + #+vindex: org-file-apps + Open current task's attachment. If there is more than one, prompt + for a file name first. Opening follows the rules set by + ~org-file-apps~. For more details, see the information on + following hyperlinks (see [[*Handling Links]]). + + - {{{kbd(O)}}} (~org-attach-open-in-emacs~) :: + + #+kindex: C-c C-a O + #+findex: org-attach-open-in-emacs + Also open the attachment, but force opening the file in Emacs. + + - {{{kbd(f)}}} (~org-attach-reveal~) :: + + #+kindex: C-c C-a f + #+findex: org-attach-reveal + Open the current task's attachment directory. + + - {{{kbd(F)}}} (~org-attach-reveal-in-emacs~) :: + + #+kindex: C-c C-a F + #+findex: org-attach-reveal-in-emacs + Also open the directory, but force using Dired in Emacs. + + - {{{kbd(d)}}} (~org-attach-delete-one~) :: + + #+kindex: C-c C-a d + Select and delete a single attachment. + + - {{{kbd(D)}}} (~org-attach-delete-all~) :: + + #+kindex: C-c C-a D + Delete all of a task's attachments. A safer way is to open the + directory in Dired and delete from there. + + - {{{kbd(s)}}} (~org-attach-set-directory~) :: + + #+kindex: C-c C-a s + #+cindex: @samp{DIR}, property + Set a specific directory as the entry's attachment directory. + This works by putting the directory path into the =DIR= + property. + + - {{{kbd(S)}}} (~org-attach-unset-directory~) :: + + #+kindex: C-c C-a S + #+cindex: @samp{DIR}, property + Remove the attachment directory. This command removes the =DIR= + property and asks the user to either move content inside that + folder, if an =ID= property is set, delete the content, or to + leave the attachment directory as is but no longer attached to the + outline node. + +*** Attachment options +:PROPERTIES: +:DESCRIPTION: Configuring the attachment system +:END: + +There are a couple of options for attachments that are worth +mentioning. + +- ~org-attach-id-dir~ :: + #+vindex: org-attach-id-dir + The directory where attachments are stored when =ID= is used as + method. + +- ~org-attach-dir-relative~ :: + #+vindex: org-attach-dir-relative + When setting the =DIR= property on a node using {{{kbd(C-c C-a s)}}} + (~org-attach-set-directory~), absolute links are entered by default. + This option changes that to relative links. + +- ~org-attach-use-inheritance~ :: + #+vindex: org-attach-use-inheritance + By default folders attached to an outline node are inherited from + parents according to ~org-use-property-inheritance~. If one instead + want to set inheritance specifically for Org attach that can be done + using ~org-attach-use-inheritance~. Inheriting documents through + the node hierarchy makes a lot of sense in most cases. Especially + when using attachment links (see [[*Attachment links]]). The following + example shows one use case for attachment inheritance: + + #+begin_example + ,* Chapter A ... + :PROPERTIES: + :DIR: Chapter A/ + :END: + ,** Introduction + Some text + + #+NAME: Image 1 + [[attachment:image 1.jpg]] + #+end_example + + Without inheritance one would not be able to resolve the link to + =image 1.jpg=, since the link is inside a sub-heading to =Chapter + A=. + + Inheritance works the same way for both =ID= and =DIR= property. If + both properties are defined on the same headline then =DIR= takes + precedence. This is also true if inheritance is enabled. If =DIR= + is inherited from a parent node in the outline, that property still + takes precedence over an =ID= property defined on the node itself. + +- ~org-attach-method~ :: + #+vindex: org-attach-method + When attaching files using the dispatcher {{{kbd(C-c C-a)}}} it + defaults to copying files. The behavior can be changed by + customizing ~org-attach-method~. Options are Copy, Move/Rename, + Hard link or Symbolic link. + +- ~org-attach-preferred-new-method~ :: + #+vindex: org-attach-preferred-new-method + This customization lets you choose the default way to attach to + nodes without existing =ID= and =DIR= property. It defaults to ~id~ + but can also be set to ~dir~, ~ask~ or ~nil~. + +- ~org-attach-archive-delete~ :: + #+vindex: org-attach-archive-delete + Configure this to determine if attachments should be deleted or not + when a subtree that has attachments is archived. + +- ~org-attach-auto-tag~ :: + #+vindex: org-attach-auto-tag + When attaching files to a heading it will be assigned a tag + according to what is set here. + +- ~org-attach-id-to-path-function-list~ :: + #+vindex: org-attach-id-to-path-function-list + When =ID= is used for attachments, the ID is parsed into a part of a + directory-path. See ~org-attach-id-uuid-folder-format~ for the + default function. Define a new one and add it as first element in + ~org-attach-id-to-path-function-list~ if you want the folder + structure in any other way. All functions in this list will be + tried when resolving existing ID's into paths, to maintain backward + compatibility with existing folders in your system. + +- ~org-attach-store-link-p~ :: + #+vindex: org-attach-store-link-p + Stores a link to the file that is being attached. The link is + stored in ~org-stored-links~ for later insertion with {{{kbd(C-c + C-l)}}} (see [[*Handling Links]]). Depending on what option is set in + ~org-attach-store-link-p~, the link is stored to either the original + location as a file link, the attachment location as an attachment + link or to the attachment location as a file link. + +- ~org-attach-commands~ :: + #+vindex: org-attach-commands + List of all commands used in the attach dispatcher. + +- ~org-attach-expert~ :: + #+vindex: org-attach-expert + Do not show the splash buffer with the attach dispatcher when + ~org-attach-expert~ is set to non-~nil~. + +See customization group =Org Attach= if you want to change the +default settings. + +*** Attachment links +:PROPERTIES: +:DESCRIPTION: Hyperlink access to attachments +:END: + +Attached files and folders can be referenced using attachment links. +This makes it easy to refer to the material added to an outline node. +Especially if it was attached using the unique ID of the entry! + +#+begin_example +,* TODO Some task + :PROPERTIES: + :ID: 95d50008-c12e-479f-a4f2-cc0238205319 + :END: +See attached document for more information: [[attachment:info.org]] +#+end_example + +See [[*External Links]] for more information about these links. + +*** Automatic version-control with Git +:PROPERTIES: +:DESCRIPTION: Everything safely stored away +:END: + +If the directory attached to an outline node is a Git repository, Org +can be configured to automatically commit changes to that repository +when it sees them. + +To make Org mode take care of versioning of attachments for you, add +the following to your Emacs config: + +#+begin_src emacs-lisp + (require 'org-attach-git) +#+end_src + +*** Attach from Dired +:PROPERTIES: +:DESCRIPTION: Using dired to select an attachment +:END: +#+cindex: attach from Dired +#+findex: org-attach-dired-to-subtree + +It is possible to attach files to a subtree from a Dired buffer. To +use this feature, have one window in Dired mode containing the file(s) +to be attached and another window with point in the subtree that shall +get the attachments. In the Dired window, with point on a file, +{{{kbd(M-x org-attach-dired-to-subtree)}}} attaches the file to the +subtree using the attachment method set by variable +~org-attach-method~. When files are marked in the Dired window then +all marked files get attached. + +Add the following lines to the Emacs init file to have {{{kbd(C-c C-x +a)}}} attach files in Dired buffers. + +#+begin_src emacs-lisp +(add-hook 'dired-mode-hook + (lambda () + (define-key dired-mode-map + (kbd "C-c C-x a") + #'org-attach-dired-to-subtree))) +#+end_src + +The following code shows how to bind the previous command with +a specific attachment method. + +#+begin_src emacs-lisp +(add-hook 'dired-mode-hook + (lambda () + (define-key dired-mode-map (kbd "C-c C-x c") + (lambda () + (interactive) + (let ((org-attach-method 'cp)) + (call-interactively #'org-attach-dired-to-subtree)))))) +#+end_src + +** RSS Feeds +:PROPERTIES: +:DESCRIPTION: Getting input from RSS feeds. +:END: +#+cindex: RSS feeds +#+cindex: Atom feeds + +Org can add and change entries based on information found in RSS feeds +and Atom feeds. You could use this to make a task out of each new +podcast in a podcast feed. Or you could use a phone-based +note-creating service on the web to import tasks into Org. To access +feeds, configure the variable ~org-feed-alist~. The docstring of this +variable has detailed information. With the following + +#+begin_src emacs-lisp +(setq org-feed-alist + '(("Slashdot" + "http://rss.slashdot.org/Slashdot/slashdot" + "~/txt/org/feeds.org" "Slashdot Entries"))) +#+end_src + +#+texinfo: @noindent +new items from the feed provided by =rss.slashdot.org= result in new +entries in the file =~/org/feeds.org= under the heading =Slashdot +Entries=, whenever the following command is used: + +- {{{kbd(C-c C-x g)}}} (~org-feed-update-all~) :: + + #+kindex: C-c C-x g + Collect items from the feeds configured in ~org-feed-alist~ and act + upon them. + +- {{{kbd(C-c C-x G)}}} (~org-feed-goto-inbox~) :: + + #+kindex: C-c C-x G + Prompt for a feed name and go to the inbox configured for this feed. + +Under the same headline, Org creates a drawer =FEEDSTATUS= in which it +stores information about the status of items in the feed, to avoid +adding the same item several times. + +For more information, including how to read atom feeds, see +=org-feed.el= and the docstring of ~org-feed-alist~. + +* Agenda Views +:PROPERTIES: +:DESCRIPTION: Collecting information into views. +:END: +#+cindex: agenda views + +Due to the way Org works, TODO items, time-stamped items, and tagged +headlines can be scattered throughout a file or even a number of +files. To get an overview of open action items, or of events that are +important for a particular date, this information must be collected, +sorted and displayed in an organized way. + +Org can select items based on various criteria and display them in +a separate buffer. Six different view types are provided: + +- an /agenda/ that is like a calendar and shows information for + specific dates, + +- a /TODO list/ that covers all unfinished action items, + +- a /match view/, showings headlines based on the tags, properties, + and TODO state associated with them, + +- a /text search view/ that shows all entries from multiple files that + contain specified keywords, + +- a /stuck projects view/ showing projects that currently do not move + along, and + +- /custom views/ that are special searches and combinations of + different views. + +The extracted information is displayed in a special /agenda buffer/. +This buffer is read-only, but provides commands to visit the +corresponding locations in the original Org files, and even to edit +these files remotely. + +#+vindex: org-agenda-skip-comment-trees +#+vindex: org-agenda-skip-archived-trees +#+cindex: commented entries, in agenda views +#+cindex: archived entries, in agenda views +By default, the report ignores commented (see [[*Comment Lines]]) and +archived (see [[*Internal archiving]]) entries. You can override this by +setting ~org-agenda-skip-comment-trees~ and +~org-agenda-skip-archived-trees~ to ~nil~. + +#+vindex: org-agenda-window-setup +#+vindex: org-agenda-restore-windows-after-quit +Two variables control how the agenda buffer is displayed and whether +the window configuration is restored when the agenda exits: +~org-agenda-window-setup~ and ~org-agenda-restore-windows-after-quit~. + +** Agenda Files +:PROPERTIES: +:DESCRIPTION: Files being searched for agenda information. +:END: +#+cindex: agenda files +#+cindex: files for agenda + +#+vindex: org-agenda-files +The information to be shown is normally collected from all /agenda +files/, the files listed in the variable ~org-agenda-files~[fn:91]. +If a directory is part of this list, all files with the extension +=.org= in this directory are part of the list. + +Thus, even if you only work with a single Org file, that file should +be put into the list[fn:92]. You can customize ~org-agenda-files~, +but the easiest way to maintain it is through the following commands + +#+attr_texinfo: :sep and +- {{{kbd(C-c [)}}} (~org-agenda-file-to-front~) :: + + #+kindex: C-c [ + #+findex: org-agenda-file-to-front + #+cindex: files, adding to agenda list + Add current file to the list of agenda files. The file is added to + the front of the list. If it was already in the list, it is moved + to the front. With a prefix argument, file is added/moved to the + end. + +- {{{kbd(C-c ])}}} (~org-remove-file~) :: + + #+kindex: C-c ] + #+findex: org-remove-file + Remove current file from the list of agenda files. + +- {{{kbd(C-')}}} and {{{kbd(C-\,)}}} (~org-cycle-agenda-files~) :: + + #+kindex: C-' + #+kindex: C-, + #+findex: org-cycle-agenda-files + #+cindex: cycling, of agenda files + Cycle through agenda file list, visiting one file after the other. + +- {{{kbd(M-x org-switchb)}}} :: + + #+findex: org-switchb + Command to use an Iswitchb-like interface to switch to and between + Org buffers. + +#+texinfo: @noindent +The Org menu contains the current list of files and can be used to +visit any of them. + +If you would like to focus the agenda temporarily on a file not in +this list, or on just one file in the list, or even on only a subtree +in a file, then this can be done in different ways. For a single +agenda command, you may press {{{kbd(<)}}} once or several times in +the dispatcher (see [[*The Agenda Dispatcher]]). To restrict the agenda +scope for an extended period, use the following commands: + +- {{{kbd(C-c C-x <)}}} (~org-agenda-set-restriction-lock~) :: + + #+kindex: C-c C-x < + #+findex: org-agenda-set-restriction-lock + Restrict the agenda to the current subtree. If there already is + a restriction at point, remove it. When called with a universal + prefix argument or with point before the first headline in a file, + set the agenda scope to the entire file. This restriction remains + in effect until removed with {{{kbd(C-c C-x >)}}}, or by typing + either {{{kbd(<)}}} or {{{kbd(>)}}} in the agenda dispatcher. If + there is a window displaying an agenda view, the new restriction + takes effect immediately. + +- {{{kbd(C-c C-x >)}}} (~org-agenda-remove-restriction-lock~) :: + + #+kindex: C-c C-x > + #+findex: org-agenda-remove-restriction-lock + Remove the restriction created by {{{kbd(C-c C-x <)}}}. + +When working with Speedbar, you can use the following commands in the +Speedbar frame: + +- {{{kbd(<)}}} (~org-speedbar-set-agenda-restriction~) :: + + #+findex: org-speedbar-set-agenda-restriction + Restrict the agenda to the item---either an Org file or a subtree in + such a file---at point in the Speedbar frame. If agenda is already + restricted there, remove the restriction. If there is a window + displaying an agenda view, the new restriction takes effect + immediately. + +- {{{kbd(>)}}} (~org-agenda-remove-restriction-lock~) :: + + #+findex: org-agenda-remove-restriction-lock + Remove the restriction. + +** The Agenda Dispatcher +:PROPERTIES: +:DESCRIPTION: Keyboard access to agenda views. +:ALT_TITLE: Agenda Dispatcher +:END: +#+cindex: agenda dispatcher +#+cindex: dispatching agenda commands + +The views are created through a dispatcher, accessible with {{{kbd(M-x +org-agenda)}}}, or, better, bound to a global key (see [[*Activation]]). +It displays a menu from which an additional letter is required to +execute a command. The dispatcher offers the following default +commands: + +#+attr_texinfo: :sep , +- {{{kbd(a)}}} :: + + Create the calendar-like agenda (see [[*Weekly/daily agenda]]). + +- {{{kbd(t)}}}, {{{kbd(T)}}} :: + + Create a list of all TODO items (see [[*The global TODO list]]). + +- {{{kbd(m)}}}, {{{kbd(M)}}} :: + + Create a list of headlines matching a given expression (see + [[*Matching tags and properties]]). + +- {{{kbd(s)}}} :: + + #+kindex: s @r{(Agenda dispatcher)} + Create a list of entries selected by a boolean expression of + keywords and/or regular expressions that must or must not occur in + the entry. + +- {{{kbd(/)}}} :: + + #+kindex: / @r{(Agenda dispatcher)} + #+vindex: org-agenda-text-search-extra-files + Search for a regular expression in all agenda files and additionally + in the files listed in ~org-agenda-text-search-extra-files~. This + uses the Emacs command ~multi-occur~. A prefix argument can be used + to specify the number of context lines for each match, default is + 1. + +- {{{kbd(#)}}} :: + + Create a list of stuck projects (see [[*Stuck projects]]). + +- {{{kbd(!)}}} :: + + Configure the list of stuck projects (see [[*Stuck projects]]). + +- {{{kbd(<)}}} :: + + #+kindex: < @r{(Agenda dispatcher)} + Restrict an agenda command to the current buffer[fn:93]. If + narrowing is in effect restrict to the narrowed part of the buffer. + After pressing {{{kbd(<)}}}, you still need to press the character + selecting the command. + +- {{{kbd(< <)}}} :: + + #+kindex: < < @r{(Agenda dispatcher)} + If there is an active region, restrict the following agenda command + to the region. Otherwise, restrict it to the current + subtree[fn:94]. After pressing {{{kbd(< <)}}}, you still need to + press the character selecting the command. + +- {{{kbd(*)}}} :: + + #+kindex: * @r{(Agenda dispatcher)} + #+vindex: org-agenda-sticky + #+findex: org-toggle-sticky-agenda + Toggle sticky agenda views. By default, Org maintains only a single + agenda buffer and rebuilds it each time you change the view, to make + sure everything is always up to date. If you switch between views + often and the build time bothers you, you can turn on sticky agenda + buffers (make this the default by customizing the variable + ~org-agenda-sticky~). With sticky agendas, the dispatcher only + switches to the selected view, you need to update it by hand with + {{{kbd(r)}}} or {{{kbd(g)}}}. You can toggle sticky agenda view any + time with ~org-toggle-sticky-agenda~. + +You can also define custom commands that are accessible through the +dispatcher, just like the default commands. This includes the +possibility to create extended agenda buffers that contain several +blocks together, for example the weekly agenda, the global TODO list +and a number of special tags matches. See [[*Custom Agenda Views]]. + +** The Built-in Agenda Views +:PROPERTIES: +:DESCRIPTION: What is available out of the box? +:ALT_TITLE: Built-in Agenda Views +:END: + +In this section we describe the built-in views. + +*** Weekly/daily agenda +:PROPERTIES: +:DESCRIPTION: The calendar page with current tasks. +:END: +#+cindex: agenda +#+cindex: weekly agenda +#+cindex: daily agenda + +The purpose of the weekly/daily /agenda/ is to act like a page of +a paper agenda, showing all the tasks for the current week or day. + +- {{{kbd(M-x org-agenda a)}}} (~org-agenda-list~) :: + + #+kindex: a @r{(Agenda dispatcher)} + #+findex: org-agenda-list + #+cindex: org-agenda, command + Compile an agenda for the current week from a list of Org files. + The agenda shows the entries for each day. With a numeric prefix + argument[fn:95]---like {{{kbd(C-u 2 1 M-x org-agenda a)}}}---you may + set the number of days to be displayed. + +#+vindex: org-agenda-span +#+vindex: org-agenda-start-day +#+vindex: org-agenda-start-on-weekday +The default number of days displayed in the agenda is set by the +variable ~org-agenda-span~. This variable can be set to any number of +days you want to see by default in the agenda, or to a span name, such +a ~day~, ~week~, ~month~ or ~year~. For weekly agendas, the default +is to start on the previous Monday (see +~org-agenda-start-on-weekday~). You can also set the start date using +a date shift: =(setq org-agenda-start-day "+10d")= starts the agenda +ten days from today in the future. + +Remote editing from the agenda buffer means, for example, that you can +change the dates of deadlines and appointments from the agenda buffer. +The commands available in the Agenda buffer are listed in [[*Commands in +the Agenda Buffer]]. + +**** Calendar/Diary integration +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: calendar integration +#+cindex: diary integration + +Emacs contains the calendar and diary by Edward\nbsp{}M.\nbsp{}Reingold. The +calendar displays a three-month calendar with holidays from different +countries and cultures. The diary allows you to keep track of +anniversaries, lunar phases, sunrise/set, recurrent appointments +(weekly, monthly) and more. In this way, it is quite complementary to +Org. It can be very useful to combine output from Org with the diary. + +In order to include entries from the Emacs diary into Org mode's +agenda, you only need to customize the variable + +#+begin_src emacs-lisp +(setq org-agenda-include-diary t) +#+end_src + +#+texinfo: @noindent +After that, everything happens automatically. All diary entries +including holidays, anniversaries, etc., are included in the agenda +buffer created by Org mode. {{{kbd(SPC)}}}, {{{kbd(TAB)}}}, and +{{{kbd(RET)}}} can be used from the agenda buffer to jump to the diary +file in order to edit existing diary entries. The {{{kbd(i)}}} +command to insert new entries for the current date works in the agenda +buffer, as well as the commands {{{kbd(S)}}}, {{{kbd(M)}}}, and +{{{kbd(C)}}} to display Sunrise/Sunset times, show lunar phases and to +convert to other calendars, respectively. {{{kbd(c)}}} can be used to +switch back and forth between calendar and agenda. + +If you are using the diary only for expression entries and holidays, +it is faster to not use the above setting, but instead to copy or even +move the entries into an Org file. Org mode evaluates diary-style +expression entries, and does it faster because there is no overhead +for first creating the diary display. Note that the expression +entries must start at the left margin, no whitespace is allowed before +them, as seen in the following segment of an Org file:[fn:96] + +#+begin_example +,* Holidays + :PROPERTIES: + :CATEGORY: Holiday + :END: +%%(org-calendar-holiday) ; special function for holiday names + +,* Birthdays + :PROPERTIES: + :CATEGORY: Ann + :END: +%%(org-anniversary 1956 5 14) Arthur Dent is %d years old +%%(org-anniversary 1869 10 2) Mahatma Gandhi would be %d years old +#+end_example + +**** Anniversaries from BBDB +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: BBDB, anniversaries +#+cindex: anniversaries, from BBDB + +#+findex: org-bbdb-anniversaries +If you are using the Insidious Big Brother Database to store your +contacts, you very likely prefer to store anniversaries in BBDB rather +than in a separate Org or diary file. Org supports this and can show +BBDB anniversaries as part of the agenda. All you need to do is to +add the following to one of your agenda files: + +#+begin_example +,* Anniversaries + :PROPERTIES: + :CATEGORY: Anniv + :END: +%%(org-bbdb-anniversaries) +#+end_example + +You can then go ahead and define anniversaries for a BBDB record. +Basically, you need a field named =anniversary= for the BBDB record +which contains the date in the format =YYYY-MM-DD= or =MM-DD=, +followed by a space and the class of the anniversary (=birthday=, +=wedding=, or a format string). If you omit the class, it defaults to +=birthday=. Here are a few examples, the header for the file +=ol-bbdb.el= contains more detailed information. + +#+begin_example +1973-06-22 +06-22 +1955-08-02 wedding +2008-04-14 %s released version 6.01 of Org mode, %d years ago +#+end_example + +After a change to BBDB, or for the first agenda display during an +Emacs session, the agenda display suffers a short delay as Org updates +its hash with anniversaries. However, from then on things will be +very fast, much faster in fact than a long list of +=%%(diary-anniversary)= entries in an Org or Diary file. + +#+findex: org-bbdb-anniversaries-future +If you would like to see upcoming anniversaries with a bit of +forewarning, you can use the following instead: + +#+begin_example +,* Anniversaries + :PROPERTIES: + :CATEGORY: Anniv + :END: +%%(org-bbdb-anniversaries-future 3) +#+end_example + +That will give you three days' warning: on the anniversary date itself +and the two days prior. The argument is optional: if omitted, it +defaults to 7. + +**** Appointment reminders +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: @file{appt.el} +#+cindex: appointment reminders +#+cindex: appointment +#+cindex: reminders + +#+cindex: APPT_WARNTIME, keyword +Org can interact with Emacs appointments notification facility. To +add the appointments of your agenda files, use the command +~org-agenda-to-appt~. This command lets you filter through the list +of your appointments and add only those belonging to a specific +category or matching a regular expression. It also reads +a =APPT_WARNTIME= property which overrides the value of +~appt-message-warning-time~ for this appointment. See the docstring +for details. + +*** The global TODO list +:PROPERTIES: +:DESCRIPTION: All unfinished action items. +:ALT_TITLE: Global TODO list +:END: +#+cindex: global TODO list +#+cindex: TODO list, global + +The global TODO list contains all unfinished TODO items formatted and +collected into a single place. + +- {{{kbd(M-x org-agenda t)}}} (~org-todo-list~) :: + + #+kindex: t @r{(Agenda dispatcher)} + #+findex: org-todo-list + Show the global TODO list. This collects the TODO items from all + agenda files (see [[*Agenda Views]]) into a single buffer. By default, + this lists items with a state the is not a DONE state. The buffer + is in Agenda mode, so there are commands to examine and manipulate + the TODO entries directly from that buffer (see [[*Commands in the + Agenda Buffer]]). + +- {{{kbd(M-x org-agenda T)}}} (~org-todo-list~) :: + + #+kindex: T @r{(Agenda dispatcher)} + #+findex: org-todo-list + #+cindex: TODO keyword matching + #+vindex: org-todo-keywords + Like the above, but allows selection of a specific TODO keyword. + You can also do this by specifying a prefix argument to + {{{kbd(t)}}}. You are prompted for a keyword, and you may also + specify several keywords by separating them with =|= as the boolean + OR operator. With a numeric prefix, the Nth keyword in + ~org-todo-keywords~ is selected. + + #+kindex: r + The {{{kbd(r)}}} key in the agenda buffer regenerates it, and you + can give a prefix argument to this command to change the selected + TODO keyword, for example {{{kbd(3 r)}}}. If you often need + a search for a specific keyword, define a custom command for it (see + [[*The Agenda Dispatcher]]). + + Matching specific TODO keywords can also be done as part of a tags + search (see [[*Tag Searches]]). + +Remote editing of TODO items means that you can change the state of +a TODO entry with a single key press. The commands available in the +TODO list are described in [[*Commands in the Agenda Buffer]]. + +#+cindex: sublevels, inclusion into TODO list +Normally the global TODO list simply shows all headlines with TODO +keywords. This list can become very long. There are two ways to keep +it more compact: + +- + #+vindex: org-agenda-todo-ignore-scheduled + #+vindex: org-agenda-todo-ignore-deadlines + #+vindex: org-agenda-todo-ignore-timestamp + #+vindex: org-agenda-todo-ignore-with-date + Some people view a TODO item that has been /scheduled/ for execution + or have a /deadline/ (see [[*Timestamps]]) as no longer /open/. + Configure the variables ~org-agenda-todo-ignore-scheduled~ to + exclude some or all scheduled items from the global TODO list, + ~org-agenda-todo-ignore-deadlines~ to exclude some or all items with + a deadline set, ~org-agenda-todo-ignore-timestamp~ to exclude some + or all items with an active timestamp other than a DEADLINE or + a SCHEDULED timestamp and/or ~org-agenda-todo-ignore-with-date~ to + exclude items with at least one active timestamp. + +- + #+vindex: org-agenda-todo-list-sublevels + TODO items may have sublevels to break up the task into subtasks. + In such cases it may be enough to list only the highest level TODO + headline and omit the sublevels from the global list. Configure the + variable ~org-agenda-todo-list-sublevels~ to get this behavior. + +*** Matching tags and properties +:PROPERTIES: +:DESCRIPTION: Structured information with fine-tuned search. +:END: +#+cindex: matching, of tags +#+cindex: matching, of properties +#+cindex: tags view +#+cindex: match view + +If headlines in the agenda files are marked with /tags/ (see [[*Tags]]), +or have properties (see [[*Properties and Columns]]), you can select +headlines based on this metadata and collect them into an agenda +buffer. The match syntax described here also applies when creating +sparse trees with {{{kbd(C-c / m)}}}. + +- {{{kbd(M-x org-agenda m)}}} (~org-tags-view~) :: + + #+kindex: m @r{(Agenda dispatcher)} + #+findex: org-tags-view + Produce a list of all headlines that match a given set of tags. The + command prompts for a selection criterion, which is a boolean logic + expression with tags, like =+work+urgent-withboss= or =work|home= + (see [[*Tags]]). If you often need a specific search, define a custom + command for it (see [[*The Agenda Dispatcher]]). + +- {{{kbd(M-x org-agenda M)}}} (~org-tags-view~) :: + + #+kindex: M @r{(Agenda dispatcher)} + #+findex: org-tags-view + #+vindex: org-tags-match-list-sublevels + #+vindex: org-agenda-tags-todo-honor-ignore-options + Like {{{kbd(m)}}}, but only select headlines that are also TODO + items and force checking subitems (see the variable + ~org-tags-match-list-sublevels~). To exclude scheduled/deadline + items, see the variable ~org-agenda-tags-todo-honor-ignore-options~. + Matching specific TODO keywords together with a tags match is also + possible, see [[*Tag Searches]]. + +The commands available in the tags list are described in [[*Commands in +the Agenda Buffer]]. + +#+cindex: boolean logic, for agenda searches +A search string can use Boolean operators =&= for AND and =|= for OR. +=&= binds more strongly than =|=. Parentheses are currently not +implemented. Each element in the search is either a tag, a regular +expression matching tags, or an expression like =PROPERTY OPERATOR +VALUE= with a comparison operator, accessing a property value. Each +element may be preceded by =-= to select against it, and =+= is +syntactic sugar for positive selection. The AND operator =&= is +optional when =+= or =-= is present. Here are some examples, using +only tags. + +- =+work-boss= :: + + Select headlines tagged =work=, but discard those also tagged + =boss=. + +- =work|laptop= :: + + Selects lines tagged =work= or =laptop=. + +- =work|laptop+night= :: + + Like before, but require the =laptop= lines to be tagged also + =night=. + +#+cindex: regular expressions, with tags search +Instead of a tag, you may also specify a regular expression enclosed +in curly braces. For example, =work+{^boss.*}= matches headlines that +contain the tag =:work:= and any tag /starting/ with =boss=. + +#+cindex: group tags, as regular expressions +Group tags (see [[*Tag Hierarchy]]) are expanded as regular expressions. +E.g., if =work= is a group tag for the group =:work:lab:conf:=, then +searching for =work= also searches for ={\(?:work\|lab\|conf\)}= and +searching for =-work= searches for all headlines but those with one of +the tags in the group (i.e., =-{\(?:work\|lab\|conf\)}=). + +#+cindex: TODO keyword matching, with tags search +#+cindex: level, for tags/property match +#+cindex: category, for tags/property match +#+vindex: org-odd-levels-only +You may also test for properties (see [[*Properties and Columns]]) at the +same time as matching tags. The properties may be real properties, or +special properties that represent other metadata (see [[*Special +Properties]]). For example, the property =TODO= represents the TODO +keyword of the entry. Or, the property =LEVEL= represents the level +of an entry. So searching =+LEVEL=3+boss-TODO​="DONE"= lists all level +three headlines that have the tag =boss= and are /not/ marked with the +TODO keyword =DONE=. In buffers with ~org-odd-levels-only~ set, +=LEVEL= does not count the number of stars, but =LEVEL=2= corresponds +to 3 stars etc. + +Here are more examples: + +- =work+TODO​="WAITING"= :: + + Select =work=-tagged TODO lines with the specific TODO keyword + =WAITING=. + +- =work+TODO​="WAITING"|home+TODO​="WAITING"= :: + + Waiting tasks both at work and at home. + +When matching properties, a number of different operators can be used +to test the value of a property. Here is a complex example: + +#+begin_example ++work-boss+PRIORITY="A"+Coffee="unlimited"+Effort<2 + +With={Sarah|Denny}+SCHEDULED>="<2008-10-11>" +#+end_example + +#+texinfo: @noindent +The type of comparison depends on how the comparison value is written: + +- If the comparison value is a plain number, a numerical comparison is + done, and the allowed operators are =<=, ===, =>=, =<==, =>==, and + =<>=. + +- If the comparison value is enclosed in double-quotes, a string + comparison is done, and the same operators are allowed. + +- If the comparison value is enclosed in double-quotes /and/ angular + brackets (like =DEADLINE<​="<2008-12-24 18:30>"=), both values are + assumed to be date/time specifications in the standard Org way, and + the comparison is done accordingly. Valid values also include + =""= for now (including time), =""=, and =""= + for these days at 0:00 hours, i.e., without a time specification. + You can also use strings like ="<+5d>"= or ="<-2m>"= with units =d=, + =w=, =m=, and =y= for day, week, month, and year, respectively. + +- If the comparison value is enclosed in curly braces, a regexp match + is performed, with === meaning that the regexp matches the property + value, and =<>= meaning that it does not match. + +So the search string in the example finds entries tagged =work= but +not =boss=, which also have a priority value =A=, a =Coffee= property +with the value =unlimited=, an =EFFORT= property that is numerically +smaller than 2, a =With= property that is matched by the regular +expression =Sarah|Denny=, and that are scheduled on or after October +11, 2008. + +You can configure Org mode to use property inheritance during +a search, but beware that this can slow down searches considerably. +See [[*Property Inheritance]], for details. + +For backward compatibility, and also for typing speed, there is also +a different way to test TODO states in a search. For this, terminate +the tags/property part of the search string (which may include several +terms connected with =|=) with a =/= and then specify a Boolean +expression just for TODO keywords. The syntax is then similar to that +for tags, but should be applied with care: for example, a positive +selection on several TODO keywords cannot meaningfully be combined +with boolean AND. However, /negative selection/ combined with AND can +be meaningful. To make sure that only lines are checked that actually +have any TODO keyword (resulting in a speed-up), use {{{kbd(M-x +org-agenda M)}}}, or equivalently start the TODO part after the slash +with =!=. Using {{{kbd(M-x org-agenda M)}}} or =/!= does not match +TODO keywords in a DONE state. Examples: + +- =work/WAITING= :: + + Same as =work+TODO​="WAITING"=. + +- =work/!-WAITING-NEXT= :: + + Select =work=-tagged TODO lines that are neither =WAITING= nor + =NEXT=. + +- =work/!+WAITING|+NEXT= :: + + Select =work=-tagged TODO lines that are either =WAITING= or =NEXT=. + +*** Search view +:PROPERTIES: +:DESCRIPTION: Find entries by searching for text. +:END: +#+cindex: search view +#+cindex: text search +#+cindex: searching, for text + +This agenda view is a general text search facility for Org mode +entries. It is particularly useful to find notes. + +- {{{kbd(M-x org-agenda s)}}} (~org-search-view~) :: + + #+kindex: s @r{(Agenda dispatcher)} + #+findex: org-search-view + This is a special search that lets you select entries by matching + a substring or specific words using a boolean logic. + +For example, the search string =computer equipment= matches entries +that contain =computer equipment= as a substring, even if the two +words are separated by more space or a line break. + +Search view can also search for specific keywords in the entry, using +Boolean logic. The search string =+computer ++wifi -ethernet -{8\.11[bg]}= matches note entries that contain the +keywords =computer= and =wifi=, but not the keyword =ethernet=, and +which are also not matched by the regular expression =8\.11[bg]=, +meaning to exclude both =8.11b= and =8.11g=. The first =+= is +necessary to turn on boolean search, other =+= characters are +optional. For more details, see the docstring of the command +~org-search-view~. + +You can incrementally and conveniently adjust a boolean search from +the agenda search view with the following keys + +#+attr_texinfo: :columns 0.1 0.6 +| {{{kbd([)}}} | Add a positive search word | +| {{{kbd(])}}} | Add a negative search word | +| {{{kbd({)}}} | Add a positive regular expression | +| {{{kbd(})}}} | Add a negative regular expression | + +#+vindex: org-agenda-text-search-extra-files +Note that in addition to the agenda files, this command also searches +the files listed in ~org-agenda-text-search-extra-files~. + +*** Stuck projects +:PROPERTIES: +:DESCRIPTION: Find projects you need to review. +:END: +#+pindex: GTD, Getting Things Done + +If you are following a system like David Allen's GTD to organize your +work, one of the "duties" you have is a regular review to make sure +that all projects move along. A /stuck/ project is a project that has +no defined next actions, so it never shows up in the TODO lists Org +mode produces. During the review, you need to identify such projects +and define next actions for them. + +- {{{kbd(M-x org-agenda #)}}} (~org-agenda-list-stuck-projects~) :: + + #+kindex: # @r{(Agenda dispatcher)} + #+findex: org-agenda-list-stuck-projects + List projects that are stuck. + +- {{{kbd(M-x org-agenda !)}}} :: + + #+kindex: ! @r{(Agenda dispatcher)} + #+vindex: org-stuck-projects + Customize the variable ~org-stuck-projects~ to define what a stuck + project is and how to find it. + +You almost certainly need to configure this view before it works for +you. The built-in default assumes that all your projects are level-2 +headlines, and that a project is not stuck if it has at least one +entry marked with a TODO keyword =TODO= or =NEXT= or =NEXTACTION=. + +Let's assume that you, in your own way of using Org mode, identify +projects with a tag =:PROJECT:=, and that you use a TODO keyword +=MAYBE= to indicate a project that should not be considered yet. +Let's further assume that the TODO keyword =DONE= marks finished +projects, and that =NEXT= and =TODO= indicate next actions. The tag +=:@shop:= indicates shopping and is a next action even without the +NEXT tag. Finally, if the project contains the special word =IGNORE= +anywhere, it should not be listed either. In this case you would +start by identifying eligible projects with a tags/TODO match (see +[[*Tag Searches]]) =+PROJECT/-MAYBE-DONE=, and then check for =TODO=, +=NEXT=, =@shop=, and =IGNORE= in the subtree to identify projects that +are not stuck. The correct customization for this is: + +#+begin_src emacs-lisp +(setq org-stuck-projects + '("+PROJECT/-MAYBE-DONE" ("NEXT" "TODO") ("@shop") + "\\")) +#+end_src + +Note that if a project is identified as non-stuck, the subtree of this +entry is searched for stuck projects. + +** Presentation and Sorting +:PROPERTIES: +:DESCRIPTION: How agenda items are prepared for display. +:END: +#+cindex: presentation, of agenda items + +#+vindex: org-agenda-prefix-format +#+vindex: org-agenda-tags-column +Before displaying items in an agenda view, Org mode visually prepares +the items and sorts them. Each item occupies a single line. The line +starts with a /prefix/ that contains the /category/ (see [[*Categories]]) +of the item and other important information. You can customize in +which column tags are displayed through ~org-agenda-tags-column~. You +can also customize the prefix using the option +~org-agenda-prefix-format~. This prefix is followed by a cleaned-up +version of the outline headline associated with the item. + +*** Categories +:PROPERTIES: +:DESCRIPTION: Not all tasks are equal. +:END: +#+cindex: category +#+cindex: @samp{CATEGORY}, keyword + +The category is a broad label assigned to each agenda item. By +default, the category is simply derived from the file name, but you +can also specify it with a special line in the buffer, like +this: + +: #+CATEGORY: Thesis + +#+cindex: @samp{CATEGORY}, property +If you would like to have a special category for a single entry or +a (sub)tree, give the entry a =CATEGORY= property with the special +category you want to apply as the value. + +#+vindex: org-agenda-category-icon-alist +The display in the agenda buffer looks best if the category is not +longer than 10 characters. You can set up icons for category by +customizing the ~org-agenda-category-icon-alist~ variable. + +*** Time-of-day specifications +:PROPERTIES: +:DESCRIPTION: How the agenda knows the time. +:END: +#+cindex: time-of-day specification + +Org mode checks each agenda item for a time-of-day specification. The +time can be part of the timestamp that triggered inclusion into the +agenda, for example + +: <2005-05-10 Tue 19:00> + +#+texinfo: @noindent +Time ranges can be specified with two timestamps: + +: <2005-05-10 Tue 20:30>--<2005-05-10 Tue 22:15> + +#+vindex: org-agenda-search-headline-for-time +In the headline of the entry itself, a time(range)---like =12:45= or +a =8:30-1pm=---may also appear as plain text[fn:97]. + +If the agenda integrates the Emacs diary (see [[*Weekly/daily agenda]]), +time specifications in diary entries are recognized as well. + +For agenda display, Org mode extracts the time and displays it in +a standard 24 hour format as part of the prefix. The example times in +the previous paragraphs would end up in the agenda like this: + +#+begin_example + 8:30-13:00 Arthur Dent lies in front of the bulldozer +12:45...... Ford Prefect arrives and takes Arthur to the pub +19:00...... The Vogon reads his poem +20:30-22:15 Marvin escorts the Hitchhikers to the bridge +#+end_example + +#+cindex: time grid +If the agenda is in single-day mode, or for the display of today, the +timed entries are embedded in a time grid, like + +#+begin_example + 8:00...... ------------------ + 8:30-13:00 Arthur Dent lies in front of the bulldozer +10:00...... ------------------ +12:00...... ------------------ +12:45...... Ford Prefect arrives and takes Arthur to the pub +14:00...... ------------------ +16:00...... ------------------ +18:00...... ------------------ +19:00...... The Vogon reads his poem +20:00...... ------------------ +20:30-22:15 Marvin escorts the Hitchhikers to the bridge +#+end_example + +#+vindex: org-agenda-use-time-grid +#+vindex: org-agenda-time-grid +The time grid can be turned on and off with the variable +~org-agenda-use-time-grid~, and can be configured with +~org-agenda-time-grid~. + +*** Sorting of agenda items +:PROPERTIES: +:DESCRIPTION: The order of things. +:END: +#+cindex: sorting, of agenda items +#+cindex: priorities, of agenda items + +Before being inserted into a view, the items are sorted. How this is +done depends on the type of view. + +- + #+vindex: org-agenda-files + For the daily/weekly agenda, the items for each day are sorted. The + default order is to first collect all items containing an explicit + time-of-day specification. These entries are shown at the beginning + of the list, as a /schedule/ for the day. After that, items remain + grouped in categories, in the sequence given by ~org-agenda-files~. + Within each category, items are sorted by priority (see + [[*Priorities]]), which is composed of the base priority (2000 for + priority =A=, 1000 for =B=, and 0 for =C=), plus additional + increments for overdue scheduled or deadline items. + +- For the TODO list, items remain in the order of categories, but + within each category, sorting takes place according to priority (see + [[*Priorities]]). The priority used for sorting derives from the + priority cookie, with additions depending on how close an item is to + its due or scheduled date. + +- For tags matches, items are not sorted at all, but just appear in + the sequence in which they are found in the agenda files. + +#+vindex: org-agenda-sorting-strategy +Sorting can be customized using the variable +~org-agenda-sorting-strategy~, and may also include criteria based on +the estimated effort of an entry (see [[*Effort Estimates]]). + +*** Filtering/limiting agenda items +:PROPERTIES: +:DESCRIPTION: Dynamically narrow the agenda. +:END: + +#+vindex: org-agenda-category-filter-preset +#+vindex: org-agenda-tag-filter-preset +#+vindex: org-agenda-effort-filter-preset +#+vindex: org-agenda-regexp-filter-preset +Agenda built-in or custom commands are statically defined. Agenda +filters and limits allow to flexibly narrow down the list of agenda +entries. + +/Filters/ only change the visibility of items, are very fast and are +mostly used interactively[fn:98]. You can switch quickly between +different filters without having to recreate the agenda. /Limits/ on +the other hand take effect before the agenda buffer is populated, so +they are mostly useful when defined as local variables within custom +agenda commands. + +**** Filtering in the agenda +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: agenda filtering +#+cindex: filtering entries, in agenda +#+cindex: tag filtering, in agenda +#+cindex: category filtering, in agenda +#+cindex: top headline filtering, in agenda +#+cindex: effort filtering, in agenda +#+cindex: query editing, in agenda + +The general filtering command is ~org-agenda-filter~, bound to +{{{kbd(/)}}}. Before we introduce it, we describe commands for +individual filter types. All filtering commands handle prefix +arguments in the same way: A single {{{kbd(C-u)}}} prefix negates the +filter, so it removes lines selected by the filter. A double prefix +adds the new filter condition to the one(s) already in place, so +filter elements are accumulated. + +- {{{kbd(\)}}} (~org-agenda-filter-by-tag~) :: + + #+findex: org-agenda-filter-by-tag + Filter the agenda view with respect to a tag. You are prompted for + a tag selection letter; {{{kbd(SPC)}}} means any tag at all. + Pressing {{{kbd(TAB)}}} at that prompt offers completion to select a + tag, including any tags that do not have a selection character. The + command then hides all entries that do not contain or inherit this + tag. Pressing {{{kbd(+)}}} or {{{kbd(-)}}} at the prompt switches + between filtering for and against the next tag. To clear the + filter, press {{{kbd(\)}}} twice (once to call the command again, + and once at the prompt). + +- {{{kbd(<)}}} (~org-agenda-filter-by-category~) :: + + #+findex: org-agenda-filter-by-category + Filter by category of the line at point, and show only entries with + this category. When called with a prefix argument, hide all entries + with the category at point. To clear the filter, call this command + again by pressing {{{kbd(<)}}}. + +- {{{kbd(=)}}} (~org-agenda-filter-by-regexp~) :: + + #+findex: org-agenda-filter-by-regexp + Filter the agenda view by a regular expression: only show agenda + entries matching the regular expression the user entered. To clear + the filter, call the command again by pressing {{{kbd(=)}}}. + +- {{{kbd(_)}}} (~org-agenda-filter-by-effort~) :: + + #+findex: org-agenda-filter-by-effort + Filter the agenda view with respect to effort estimates, so select + tasks that take the right amount of time. You first need to set up + a list of efforts globally, for example + + #+begin_src emacs-lisp + (setq org-global-properties + '(("Effort_ALL". "0 0:10 0:30 1:00 2:00 3:00 4:00"))) + #+end_src + + #+vindex: org-sort-agenda-noeffort-is-high + You can then filter for an effort by first typing an operator, one + of {{{kbd(<)}}}, {{{kbd(>)}}} and {{{kbd(=)}}}, and then the + one-digit index of an effort estimate in your array of allowed + values, where {{{kbd(0)}}} means the 10th value. The filter then + restricts to entries with effort smaller-or-equal, equal, or + larger-or-equal than the selected value. For application of the + operator, entries without a defined effort are treated according to + the value of ~org-sort-agenda-noeffort-is-high~. To clear the + filter, press {{{kbd(_)}}} twice (once to call the command again, + and once at the first prompt). + +- {{{kbd(^)}}} (~org-agenda-filter-by-top-headline~) :: + + #+findex: org-agenda-filter-by-top-headline + Filter the current agenda view and only display items that fall + under the same top-level headline as the current entry. To clear + the filter, call this command again by pressing {{{kbd(^)}}}. + +- {{{kbd(/)}}} (~org-agenda-filter~) :: + + #+findex: org-agenda-filter + This is the unified interface to four of the five filter methods + described above. At the prompt, specify different filter elements + in a single string, with full completion support. For example, + + : +work-John+<0:10-/plot/ + + selects entries with category =work= and effort estimates below 10 + minutes, and deselects entries with tag =John= or matching the + regexp =plot=. You can leave =+= out if that does not lead to + ambiguities. The sequence of elements is arbitrary. The filter + syntax assumes that there is no overlap between categories and tags. + Otherwise, tags take priority. If you reply to the prompt with the + empty string, all filtering is removed. If a filter is specified, + it replaces all current filters. But if you call the command with + a double prefix argument, or if you add an additional =+= (e.g., + =++work=) to the front of the string, the new filter elements are + added to the active ones. A single prefix argument applies the + entire filter in a negative sense. + +- {{{kbd(|)}}} (~org-agenda-filter-remove-all~) :: + + Remove all filters in the current agenda view. + +**** Computed tag filtering +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+vindex: org-agenda-auto-exclude-function +If the variable ~org-agenda-auto-exclude-function~ is set to +a user-defined function, that function can select tags that should be +used as a tag filter when requested. The function will be called with +lower-case versions of all tags represented in the current view. The +function should return ="-tag"= if the filter should remove +entries with that tag, ="+tag"= if only entries with this tag should +be kept, or =nil= if that tag is irrelevant. For example, let's say +you use a =Net= tag to identify tasks which need network access, an +=Errand= tag for errands in town, and a =Call= tag for making phone +calls. You could auto-exclude these tags based on the availability of +the Internet, and outside of business hours, with something like this: + +#+begin_src emacs-lisp +(defun my-auto-exclude-fn (tag) + (when (cond ((string= tag "net") + (/= 0 (call-process "/sbin/ping" nil nil nil + "-c1" "-q" "-t1" "mail.gnu.org"))) + ((member tag '("errand" "call")) + (let ((hr (nth 2 (decode-time)))) + (or (< hr 8) (> hr 21))))) + (concat "-" tag))) + +(setq org-agenda-auto-exclude-function #'my-auto-exclude-fn) +#+end_src + +You can apply this self-adapting filter by using a triple prefix +argument to ~org-agenda-filter~, i.e.\nbsp{}press {{{kbd(C-u C-u C-u /)}}}, +or by pressing {{{kbd(RET)}}} in ~org-agenda-filter-by-tag~. + +**** Setting limits for the agenda +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: limits, in agenda + +Here is a list of options that you can set, either globally, or +locally in your custom agenda views (see [[*Custom Agenda Views]]). + +- ~org-agenda-max-entries~ :: + + #+vindex: org-agenda-max-entries + Limit the number of entries. + +- ~org-agenda-max-effort~ :: + + #+vindex: org-agenda-max-effort + Limit the duration of accumulated efforts (as minutes). + +- ~org-agenda-max-todos~ :: + + #+vindex: org-agenda-max-todos + Limit the number of entries with TODO keywords. + +- ~org-agenda-max-tags~ :: + + #+vindex: org-agenda-max-tags + Limit the number of tagged entries. + +When set to a positive integer, each option excludes entries from +other categories: for example, =(setq org-agenda-max-effort 100)= +limits the agenda to 100 minutes of effort and exclude any entry that +has no effort property. If you want to include entries with no effort +property, use a negative value for ~org-agenda-max-effort~. One +useful setup is to use ~org-agenda-max-entries~ locally in a custom +command. For example, this custom command displays the next five +entries with a =NEXT= TODO keyword. + +#+begin_src emacs-lisp +(setq org-agenda-custom-commands + '(("n" todo "NEXT" + ((org-agenda-max-entries 5))))) +#+end_src + +Once you mark one of these five entry as DONE, rebuilding the agenda +will again the next five entries again, including the first entry that +was excluded so far. + +You can also dynamically set temporary limits, which are lost when +rebuilding the agenda: + +- {{{kbd(~ )}}} (~org-agenda-limit-interactively~) :: + + #+findex: org-agenda-limit-interactively + This prompts for the type of limit to apply and its value. + +** Commands in the Agenda Buffer +:PROPERTIES: +:DESCRIPTION: Remote editing of Org trees. +:ALT_TITLE: Agenda Commands +:END: +#+cindex: commands, in agenda buffer + +Entries in the agenda buffer are linked back to the Org file or diary +file where they originate. You are not allowed to edit the agenda +buffer itself, but commands are provided to show and jump to the +original entry location, and to edit the Org files "remotely" from the +agenda buffer. In this way, all information is stored only once, +removing the risk that your agenda and note files may diverge. + +Some commands can be executed with mouse clicks on agenda lines. For +the other commands, point needs to be in the desired line. + +*** Motion +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: motion commands in agenda + +- {{{kbd(n)}}} (~org-agenda-next-line~) :: + + #+kindex: n + #+findex: org-agenda-next-line + Next line (same as {{{kbd(DOWN)}}} and {{{kbd(C-n)}}}). + +- {{{kbd(p)}}} (~org-agenda-previous-line~) :: + + #+kindex: p + #+findex: org-agenda-previous-line + Previous line (same as {{{kbd(UP)}}} and {{{kbd(C-p)}}}). + +*** View/Go to Org file +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: view file commands in agenda + +- {{{kbd(SPC)}}} or {{{kbd(mouse-3)}}} (~org-agenda-show-and-scroll-up~) :: + + #+kindex: SPC + #+kindex: mouse-3 + #+findex: org-agenda-show-and-scroll-up + Display the original location of the item in another window. + With a prefix argument, make sure that drawers stay folded. + +- {{{kbd(L)}}} (~org-agenda-recenter~) :: + + #+findex: org-agenda-recenter + Display original location and recenter that window. + +- {{{kbd(TAB)}}} or {{{kbd(mouse-2)}}} (~org-agenda-goto~) :: + + #+kindex: TAB + #+kindex: mouse-2 + #+findex: org-agenda-goto + Go to the original location of the item in another window. + +- {{{kbd(RET)}}} (~org-agenda-switch-to~) :: + + #+kindex: RET + #+findex: org-agenda-switch-to + Go to the original location of the item and delete other windows. + +- {{{kbd(F)}}} (~org-agenda-follow-mode~) :: + + #+kindex: F + #+findex: org-agenda-follow-mode + #+vindex: org-agenda-start-with-follow-mode + Toggle Follow mode. In Follow mode, as you move point through the + agenda buffer, the other window always shows the corresponding + location in the Org file. The initial setting for this mode in new + agenda buffers can be set with the variable + ~org-agenda-start-with-follow-mode~. + +- {{{kbd(C-c C-x b)}}} (~org-agenda-tree-to-indirect-buffer~) :: + + #+kindex: C-c C-x b + #+findex: org-agenda-tree-to-indirect-buffer + Display the entire subtree of the current item in an indirect + buffer. With a numeric prefix argument N, go up to level N and then + take that tree. If N is negative, go up that many levels. With + a {{{kbd(C-u)}}} prefix, do not remove the previously used indirect + buffer. + +- {{{kbd(C-c C-o)}}} (~org-agenda-open-link~) :: + + #+kindex: C-c C-o + #+findex: org-agenda-open-link + Follow a link in the entry. This offers a selection of any links in + the text belonging to the referenced Org node. If there is only one + link, follow it without a selection prompt. + +*** Change display +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: change agenda display +#+cindex: display changing, in agenda + +#+attr_texinfo: :sep , +- {{{kbd(A)}}} :: + + #+kindex: A + Interactively select another agenda view and append it to the + current view. + +- {{{kbd(o)}}} :: + + #+kindex: o + Delete other windows. + +- {{{kbd(v d)}}} or short {{{kbd(d)}}} (~org-agenda-day-view~) :: + + #+kindex: v d + #+kindex: d + #+findex: org-agenda-day-view + Switch to day view. When switching to day view, this setting + becomes the default for subsequent agenda refreshes. A numeric + prefix argument may be used to jump directly to a specific day of + the year. For example, {{{kbd(32 d)}}} jumps to February 1st. When + setting day view, a year may be encoded in the prefix argument as + well. For example, {{{kbd(200712 d)}}} jumps to January 12, 2007. + If such a year specification has only one or two digits, it is + expanded into one of the 30 next years or the last 69 years. + +- {{{kbd(v w)}}} or short {{{kbd(w)}}} (~org-agenda-week-view~) :: + + #+kindex: v w + #+kindex: w + #+findex: org-agenda-week-view + Switch to week view. When switching week view, this setting becomes + the default for subsequent agenda refreshes. A numeric prefix + argument may be used to jump directly to a specific day of the ISO + week. For example {{{kbd(9 w)}}} to ISO week number 9. When + setting week view, a year may be encoded in the prefix argument as + well. For example, {{{kbd(200712 w)}}} jumps to week 12 in 2007. + If such a year specification has only one or two digits, it is + expanded into one of the 30 next years or the last 69 years. + +- {{{kbd(v m)}}} (~org-agenda-month-view~) :: + + #+kindex: v m + #+findex: org-agenda-month-view + Switch to month view. Because month views are slow to create, they + do not become the default for subsequent agenda refreshes. + A numeric prefix argument may be used to jump directly to a specific + day of the month. When setting month view, a year may be encoded in + the prefix argument as well. For example, {{{kbd(200712 m)}}} jumps + to December, 2007. If such a year specification has only one or two + digits, it is expanded into one of the 30 next years or the last 69 + years. + +- {{{kbd(v y)}}} (~org-agenda-year-view~) :: + + #+kindex: v y + #+findex: org-agenda-year-view + Switch to year view. Because year views are slow to create, they do + not become the default for subsequent agenda refreshes. A numeric + prefix argument may be used to jump directly to a specific day of + the year. + +- {{{kbd(v SPC)}}} (~org-agenda-reset-view~) :: + + #+kindex: v SPC + #+findex: org-agenda-reset-view + #+vindex: org-agenda-span + Reset the current view to ~org-agenda-span~. + +- {{{kbd(f)}}} (~org-agenda-later~) :: + + #+kindex: f + #+findex: org-agenda-later + Go forward in time to display the span following the current one. + For example, if the display covers a week, switch to the following + week. With a prefix argument, repeat that many times. + +- {{{kbd(b)}}} (~org-agenda-earlier~) :: + + #+kindex: b + #+findex: org-agenda-earlier + Go backward in time to display earlier dates. + +- {{{kbd(.)}}} (~org-agenda-goto-today~) :: + + #+kindex: . + #+findex: org-agenda-goto-today + Go to today. + +- {{{kbd(j)}}} (~org-agenda-goto-date~) :: + + #+kindex: j + #+findex: org-agenda-goto-date + Prompt for a date and go there. + +- {{{kbd(J)}}} (~org-agenda-clock-goto~) :: + + #+kindex: J + #+findex: org-agenda-clock-goto + Go to the currently clocked-in task /in the agenda buffer/. + +- {{{kbd(D)}}} (~org-agenda-toggle-diary~) :: + + #+kindex: D + #+findex: org-agenda-toggle-diary + Toggle the inclusion of diary entries. See [[*Weekly/daily agenda]]. + +- {{{kbd(v l)}}} or {{{kbd(v L)}}} or short {{{kbd(l)}}} (~org-agenda-log-mode~) :: + + #+kindex: v l + #+kindex: l + #+kindex: v L + #+findex: org-agenda-log-mode + #+vindex: org-log-done + #+vindex: org-agenda-log-mode-items + Toggle Logbook mode. In Logbook mode, entries that were marked as + done while logging was on (see the variable ~org-log-done~) are + shown in the agenda, as are entries that have been clocked on that + day. You can configure the entry types that should be included in + log mode using the variable ~org-agenda-log-mode-items~. When + called with a {{{kbd(C-u)}}} prefix argument, show all possible + logbook entries, including state changes. When called with two + prefix arguments {{{kbd(C-u C-u)}}}, show only logging information, + nothing else. {{{kbd(v L)}}} is equivalent to {{{kbd(C-u v l)}}}. + +- {{{kbd(v [)}}} or short {{{kbd([)}}} (~org-agenda-manipulate-query-add~) :: + + #+kindex: v [ + #+kindex: [ + #+findex: org-agenda-manipulate-query-add + Include inactive timestamps into the current view. Only for + weekly/daily agenda. + +- {{{kbd(v a)}}} (~org-agenda-archives-mode~) :: + + #+kindex: v a + #+findex: org-agenda-archives-mode + Toggle Archives mode. In Archives mode, trees that are archived + (see [[*Internal archiving]]) are also scanned when producing the + agenda. To exit archives mode, press {{{kbd(v a)}}} again. + +- {{{kbd(v A)}}} :: + + #+kindex: v A + Toggle Archives mode. Include all archive files as well. + +- {{{kbd(v R)}}} or short {{{kbd(R)}}} (~org-agenda-clockreport-mode~) :: + + #+kindex: v R + #+kindex: R + #+findex: org-agenda-clockreport-mode + #+vindex: org-agenda-start-with-clockreport-mode + #+vindex: org-clock-report-include-clocking-task + Toggle Clockreport mode. In Clockreport mode, the daily/weekly + agenda always shows a table with the clocked times for the time span + and file scope covered by the current agenda view. The initial + setting for this mode in new agenda buffers can be set with the + variable ~org-agenda-start-with-clockreport-mode~. By using + a prefix argument when toggling this mode (i.e., {{{kbd(C-u R)}}}), + the clock table does not show contributions from entries that are + hidden by agenda filtering[fn:99]. See also the variable + ~org-clock-report-include-clocking-task~. + +- {{{kbd(v c)}}} :: + + #+kindex: v c + #+vindex: org-agenda-clock-consistency-checks + Show overlapping clock entries, clocking gaps, and other clocking + problems in the current agenda range. You can then visit clocking + lines and fix them manually. See the variable + ~org-agenda-clock-consistency-checks~ for information on how to + customize the definition of what constituted a clocking problem. To + return to normal agenda display, press {{{kbd(l)}}} to exit Logbook + mode. + +- {{{kbd(v E)}}} or short {{{kbd(E)}}} (~org-agenda-entry-text-mode~) :: + + #+kindex: v E + #+kindex: E + #+findex: org-agenda-entry-text-mode + #+vindex: org-agenda-start-with-entry-text-mode + #+vindex: org-agenda-entry-text-maxlines + Toggle entry text mode. In entry text mode, a number of lines from + the Org outline node referenced by an agenda line are displayed + below the line. The maximum number of lines is given by the + variable ~org-agenda-entry-text-maxlines~. Calling this command + with a numeric prefix argument temporarily modifies that number to + the prefix value. + +- {{{kbd(G)}}} (~org-agenda-toggle-time-grid~) :: + + #+kindex: G + #+vindex: org-agenda-use-time-grid + #+vindex: org-agenda-time-grid + Toggle the time grid on and off. See also the variables + ~org-agenda-use-time-grid~ and ~org-agenda-time-grid~. + +- {{{kbd(r)}}} (~org-agenda-redo~), {{{kbd(g)}}} :: + + #+kindex: r + #+kindex: g + #+findex: org-agenda-redo + Recreate the agenda buffer, for example to reflect the changes after + modification of the timestamps of items with {{{kbd(S-LEFT)}}} and + {{{kbd(S-RIGHT)}}}. When the buffer is the global TODO list, + a prefix argument is interpreted to create a selective list for + a specific TODO keyword. + +- {{{kbd(C-x C-s)}}} or short {{{kbd(s)}}} (~org-save-all-org-buffers~) :: + + #+kindex: C-x C-s + #+findex: org-save-all-org-buffers + #+kindex: s + Save all Org buffers in the current Emacs session, and also the + locations of IDs. + +- {{{kbd(C-c C-x C-c)}}} (~org-agenda-columns~) :: + + #+kindex: C-c C-x C-c + #+findex: org-agenda-columns + #+vindex: org-columns-default-format + Invoke column view (see [[*Column View]]) in the agenda buffer. The + column view format is taken from the entry at point, or, if there is + no entry at point, from the first entry in the agenda view. So + whatever the format for that entry would be in the original buffer + (taken from a property, from a =COLUMNS= keyword, or from the + default variable ~org-columns-default-format~) is used in the + agenda. + +- {{{kbd(C-c C-x >)}}} (~org-agenda-remove-restriction-lock~) :: + + #+kindex: C-c C-x > + #+findex: org-agenda-remove-restriction-lock + Remove the restriction lock on the agenda, if it is currently + restricted to a file or subtree (see [[*Agenda Files]]). + +- {{{kbd(M-UP)}}} (~org-agenda-drag-line-backward~) :: + + #+kindex: M-UP + #+findex: org-agenda-drag-line-backward + Drag the line at point backward one line. With a numeric prefix + argument, drag backward by that many lines. + + Moving agenda lines does not persist after an agenda refresh and + does not modify the contributing Org files. + +- {{{kbd(M-DOWN)}}} (~org-agenda-drag-line-forward~) :: + + #+kindex: M-DOWN + #+findex: org-agenda-drag-line-forward + Drag the line at point forward one line. With a numeric prefix + argument, drag forward by that many lines. + +*** Remote editing +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: remote editing, from agenda + +- {{{kbd(0--9)}}} :: + + Digit argument. + +- {{{kbd(C-_)}}} (~org-agenda-undo~) :: + + #+kindex: C-_ + #+findex: org-agenda-undo + #+cindex: undoing remote-editing events + #+cindex: remote editing, undo + Undo a change due to a remote editing command. The change is undone + both in the agenda buffer and in the remote buffer. + +- {{{kbd(t)}}} (~org-agenda-todo~) :: + + #+kindex: t + #+findex: org-agenda-todo + Change the TODO state of the item, both in the agenda and in the + original Org file. A prefix arg is passed through to the ~org-todo~ + command, so for example a {{{kbd(C-u)}}} prefix are will trigger + taking a note to document the state change. + +- {{{kbd(C-S-RIGHT)}}} (~org-agenda-todo-nextset~) :: + + #+kindex: C-S-RIGHT + #+findex: org-agenda-todo-nextset + Switch to the next set of TODO keywords. + +- {{{kbd(C-S-LEFT)}}}, ~org-agenda-todo-previousset~ :: + + #+kindex: C-S-LEFT + Switch to the previous set of TODO keywords. + +- {{{kbd(C-k)}}} (~org-agenda-kill~) :: + + #+kindex: C-k + #+findex: org-agenda-kill + #+vindex: org-agenda-confirm-kill + Delete the current agenda item along with the entire subtree + belonging to it in the original Org file. If the text to be deleted + remotely is longer than one line, the kill needs to be confirmed by + the user. See variable ~org-agenda-confirm-kill~. + +- {{{kbd(C-c C-w)}}} (~org-agenda-refile~) :: + + #+kindex: C-c C-w + #+findex: org-agenda-refile + Refile the entry at point. + +- {{{kbd(C-c C-x C-a)}}} or short {{{kbd(a)}}} (~org-agenda-archive-default-with-confirmation~) :: + + #+kindex: C-c C-x C-a + #+kindex: a + #+findex: org-agenda-archive-default-with-confirmation + #+vindex: org-archive-default-command + Archive the subtree corresponding to the entry at point using the + default archiving command set in ~org-archive-default-command~. + When using the {{{kbd(a)}}} key, confirmation is required. + +- {{{kbd(C-c C-x a)}}} (~org-agenda-toggle-archive-tag~) :: + + #+kindex: C-c C-x a + #+findex: org-agenda-toggle-archive-tag + Toggle the archive tag (see [[*Internal archiving]]) for the current + headline. + +- {{{kbd(C-c C-x A)}}} (~org-agenda-archive-to-archive-sibling~) :: + + #+kindex: C-c C-x A + #+findex: org-agenda-archive-to-archive-sibling + Move the subtree corresponding to the current entry to its /archive + sibling/. + +- {{{kbd(C-c C-x C-s)}}} or short {{{kbd($)}}} (~org-agenda-archive~) :: + + #+kindex: C-c C-x C-s + #+kindex: $ + #+findex: org-agenda-archive + Archive the subtree corresponding to the current headline. This + means the entry is moved to the configured archive location, most + likely a different file. + +- {{{kbd(T)}}} (~org-agenda-show-tags~) :: + + #+kindex: T + #+findex: org-agenda-show-tags + #+vindex: org-agenda-show-inherited-tags + Show all tags associated with the current item. This is useful if + you have turned off ~org-agenda-show-inherited-tags~, but still want + to see all tags of a headline occasionally. + +- {{{kbd(:)}}} (~org-agenda-set-tags~) :: + + #+kindex: : + #+findex: org-agenda-set-tags + Set tags for the current headline. If there is an active region in + the agenda, change a tag for all headings in the region. + +- {{{kbd(\,)}}} (~org-agenda-priority~) :: + + #+kindex: , + #+findex: org-agenda-priority + Set the priority for the current item. Org mode prompts for the + priority character. If you reply with {{{kbd(SPC)}}}, the priority + cookie is removed from the entry. + +- {{{kbd(+)}}} or {{{kbd(S-UP)}}} (~org-agenda-priority-up~) :: + + #+kindex: + + #+kindex: S-UP + #+findex: org-agenda-priority-up + Increase the priority of the current item. The priority is changed + in the original buffer, but the agenda is not resorted. Use the + {{{kbd(r)}}} key for this. + +- {{{kbd(-)}}} or {{{kbd(S-DOWN)}}} (~org-agenda-priority-down~) :: + + #+kindex: - + #+kindex: S-DOWN + #+findex: org-agenda-priority-down + Decrease the priority of the current item. + +- {{{kbd(C-c C-x e)}}} or short {{{kbd(e)}}} (~org-agenda-set-effort~) :: + + #+kindex: e + #+kindex: C-c C-x e + #+findex: org-agenda-set-effort + Set the effort property for the current item. + +- {{{kbd(C-c C-z)}}} or short {{{kbd(z)}}} (~org-agenda-add-note~) :: + + #+kindex: z + #+kindex: C-c C-z + #+findex: org-agenda-add-note + #+vindex: org-log-into-drawer + Add a note to the entry. This note is recorded, and then filed to + the same location where state change notes are put. Depending on + ~org-log-into-drawer~, this may be inside a drawer. + +- {{{kbd(C-c C-a)}}} (~org-attach~) :: + + #+kindex: C-c C-a + #+findex: org-attach + Dispatcher for all command related to attachments. + +- {{{kbd(C-c C-s)}}} (~org-agenda-schedule~) :: + + #+kindex: C-c C-s + #+findex: org-agenda-schedule + Schedule this item. With a prefix argument, remove the + scheduling timestamp + +- {{{kbd(C-c C-d)}}} (~org-agenda-deadline~) :: + + #+kindex: C-c C-d + #+findex: org-agenda-deadline + Set a deadline for this item. With a prefix argument, remove the + deadline. + +- {{{kbd(S-RIGHT)}}} (~org-agenda-do-date-later~) :: + + #+kindex: S-RIGHT + #+findex: org-agenda-do-date-later + Change the timestamp associated with the current line by one day + into the future. If the date is in the past, the first call to this + command moves it to today. With a numeric prefix argument, change + it by that many days. For example, {{{kbd(3 6 5 S-RIGHT)}}} changes + it by a year. With a {{{kbd(C-u)}}} prefix, change the time by one + hour. If you immediately repeat the command, it will continue to + change hours even without the prefix argument. With a double + {{{kbd(C-u C-u)}}} prefix, do the same for changing minutes. The + stamp is changed in the original Org file, but the change is not + directly reflected in the agenda buffer. Use {{{kbd(r)}}} or + {{{kbd(g)}}} to update the buffer. + +- {{{kbd(S-LEFT)}}} (~org-agenda-do-date-earlier~) :: + + #+kindex: S-LEFT + #+findex: org-agenda-do-date-earlier + Change the timestamp associated with the current line by one day + into the past. + +- {{{kbd(>)}}} (~org-agenda-date-prompt~) :: + + #+kindex: > + #+findex: org-agenda-date-prompt + Change the timestamp associated with the current line. The key + {{{kbd(>)}}} has been chosen, because it is the same as + {{{kbd(S-.)}}} on my keyboard. + +- {{{kbd(I)}}} (~org-agenda-clock-in~) :: + + #+kindex: I + #+findex: org-agenda-clock-in + Start the clock on the current item. If a clock is running already, + it is stopped first. + +- {{{kbd(O)}}} (~org-agenda-clock-out~) :: + + #+kindex: O + #+findex: org-agenda-clock-out + Stop the previously started clock. + +- {{{kbd(X)}}} (~org-agenda-clock-cancel~) :: + + #+kindex: X + #+findex: org-agenda-clock-cancel + Cancel the currently running clock. + +- {{{kbd(J)}}} (~org-agenda-clock-goto~) :: + + #+kindex: J + #+findex: org-agenda-clock-goto + Jump to the running clock in another window. + +- {{{kbd(k)}}} (~org-agenda-capture~) :: + + #+kindex: k + #+findex: org-agenda-capture + #+cindex: capturing, from agenda + #+vindex: org-capture-use-agenda-date + Like ~org-capture~, but use the date at point as the default date + for the capture template. See ~org-capture-use-agenda-date~ to make + this the default behavior of ~org-capture~. + +*** Bulk remote editing selected entries +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: remote editing, bulk, from agenda +#+vindex: org-agenda-bulk-custom-functions + +- {{{kbd(m)}}} (~org-agenda-bulk-mark~) :: + #+kindex: m + #+findex: org-agenda-bulk-mark + + Mark the entry at point for bulk action. If there is an active + region in the agenda, mark the entries in the region. With numeric + prefix argument, mark that many successive entries. + +- {{{kbd(*)}}} (~org-agenda-bulk-mark-all~) :: + #+kindex: * + #+findex: org-agenda-bulk-mark-all + + Mark all visible agenda entries for bulk action. + +- {{{kbd(u)}}} (~org-agenda-bulk-unmark~) :: + #+kindex: u + #+findex: org-agenda-bulk-unmark + + Unmark entry for bulk action. + +- {{{kbd(U)}}} (~org-agenda-bulk-remove-all-marks~) :: + #+kindex: U + #+findex: org-agenda-bulk-remove-all-marks + + Unmark all marked entries for bulk action. + +- {{{kbd(M-m)}}} (~org-agenda-bulk-toggle~) :: + #+kindex: M-m + #+findex: org-agenda-bulk-toggle + + Toggle mark of the entry at point for bulk action. + +- {{{kbd(M-*)}}} (~org-agenda-bulk-toggle-all~) :: + #+kindex: M-* + #+findex: org-agenda-bulk-toggle-all + + Toggle mark of every entry for bulk action. + +- {{{kbd(%)}}} (~org-agenda-bulk-mark-regexp~) :: + #+kindex: % + #+findex: org-agenda-bulk-mark-regexp + + Mark entries matching a regular expression for bulk action. + +- {{{kbd(B)}}} (~org-agenda-bulk-action~) :: + #+kindex: B + #+findex: org-agenda-bulk-action + #+vindex: org-agenda-bulk-persistent-marks + + Bulk action: act on all marked entries in the agenda. This prompts + for another key to select the action to be applied. The prefix + argument to {{{kbd(B)}}} is passed through to the {{{kbd(s)}}} and + {{{kbd(d)}}} commands, to bulk-remove these special timestamps. By + default, marks are removed after the bulk. If you want them to + persist, set ~org-agenda-bulk-persistent-marks~ to ~t~ or hit + {{{kbd(p)}}} at the prompt. + + - {{{kbd(p)}}} :: + + Toggle persistent marks. + + - {{{kbd($)}}} :: + + Archive all selected entries. + + - {{{kbd(A)}}} :: + + Archive entries by moving them to their respective archive + siblings. + + - {{{kbd(t)}}} :: + + Change TODO state. This prompts for a single TODO keyword and + changes the state of all selected entries, bypassing blocking and + suppressing logging notes---but not timestamps. + + - {{{kbd(+)}}} :: + + Add a tag to all selected entries. + + - {{{kbd(-)}}} :: + + Remove a tag from all selected entries. + + - {{{kbd(s)}}} :: + + Schedule all items to a new date. To shift existing schedule + dates by a fixed number of days, use something starting with + double plus at the prompt, for example =++8d= or =++2w=. + + - {{{kbd(d)}}} :: + + Set deadline to a specific date. + + - {{{kbd(r)}}} :: + + Prompt for a single refile target and move all entries. The + entries are no longer in the agenda; refresh ({{{kbd(g)}}}) to + bring them back. + + - {{{kbd(S)}}} :: + + Reschedule randomly into the coming N days. N is prompted for. + With a prefix argument ({{{kbd(C-u B S)}}}), scatter only across + weekdays. + + - {{{kbd(f)}}} :: + + #+vindex: org-agenda-bulk-custom-functions + Apply a function[fn:100] to marked entries. For example, the + function below sets the =CATEGORY= property of the entries to + =web=. + + #+begin_src emacs-lisp + (defun set-category () + (interactive "P") + (let ((marker (or (org-get-at-bol 'org-hd-marker) + (org-agenda-error)))) + (org-with-point-at marker + (org-back-to-heading t) + (org-set-property "CATEGORY" "web")))) + #+end_src + +*** Calendar commands +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: calendar commands, from agenda + +- {{{kbd(c)}}} (~org-agenda-goto-calendar~) :: + + #+kindex: c + #+findex: org-agenda-goto-calendar + Open the Emacs calendar and go to the date at point in the agenda. + +- {{{kbd(c)}}} (~org-calendar-goto-agenda~) :: + + #+kindex: c + #+findex: org-calendar-goto-agenda + When in the calendar, compute and show the Org agenda for the date + at point. + +- {{{kbd(i)}}} (~org-agenda-diary-entry~) :: + #+kindex: i + #+findex: org-agenda-diary-entry + + #+cindex: diary entries, creating from agenda + Insert a new entry into the diary, using the date at point and (for + block entries) the date at the mark. This adds to the Emacs diary + file[fn:101], in a way similar to the {{{kbd(i)}}} command in the + calendar. The diary file pops up in another window, where you can + add the entry. + + #+vindex: org-agenda-diary-file + If you configure ~org-agenda-diary-file~ to point to an Org file, + Org creates entries in that file instead. Most entries are stored + in a date-based outline tree that will later make it easy to archive + appointments from previous months/years. The tree is built under an + entry with a =DATE_TREE= property, or else with years as top-level + entries. Emacs prompts you for the entry text---if you specify it, + the entry is created in ~org-agenda-diary-file~ without further + interaction. If you directly press {{{kbd(RET)}}} at the prompt + without typing text, the target file is shown in another window for + you to finish the entry there. See also the {{{kbd(k r)}}} command. + +- {{{kbd(M)}}} (~org-agenda-phases-of-moon~) :: + + #+kindex: M + #+findex: org-agenda-phases-of-moon + Show the phases of the moon for the three months around current + date. + +- {{{kbd(S)}}} (~org-agenda-sunrise-sunset~) :: + + #+kindex: S + #+findex: org-agenda-sunrise-sunset + Show sunrise and sunset times. The geographical location must be + set with calendar variables, see the documentation for the Emacs + calendar. + +- {{{kbd(C)}}} (~org-agenda-convert-date~) :: + + #+kindex: C + #+findex: org-agenda-convert-date + Convert the date at point into many other cultural and historic + calendars. + +- {{{kbd(H)}}} (~org-agenda-holidays~) :: + + #+kindex: H + #+findex: org-agenda-holidays + Show holidays for three months around point date. + +*** Quit and exit +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +- {{{kbd(q)}}} (~org-agenda-quit~) :: + #+kindex: q + #+findex: org-agenda-quit + + Quit agenda, remove the agenda buffer. + +- {{{kbd(x)}}} (~org-agenda-exit~) :: + #+kindex: x + #+findex: org-agenda-exit + + #+cindex: agenda files, removing buffers + Exit agenda, remove the agenda buffer and all buffers loaded by + Emacs for the compilation of the agenda. Buffers created by the + user to visit Org files are not removed. + +** Custom Agenda Views +:PROPERTIES: +:DESCRIPTION: Defining special searches and views. +:END: +#+cindex: custom agenda views +#+cindex: agenda views, custom + +Custom agenda commands serve two purposes: to store and quickly access +frequently used TODO and tags searches, and to create special +composite agenda buffers. Custom agenda commands are accessible +through the dispatcher (see [[*The Agenda Dispatcher]]), just like the +default commands. + +*** Storing searches +:PROPERTIES: +:DESCRIPTION: Type once, use often. +:END: + +The first application of custom searches is the definition of keyboard +shortcuts for frequently used searches, either creating an agenda +buffer, or a sparse tree (the latter covering of course only the +current buffer). + +#+kindex: C @r{(Agenda dispatcher)} +#+vindex: org-agenda-custom-commands +#+cindex: agenda views, main example +#+cindex: agenda, as an agenda views +#+cindex: agenda*, as an agenda views +#+cindex: tags, as an agenda view +#+cindex: todo, as an agenda view +#+cindex: tags-todo +#+cindex: todo-tree +#+cindex: occur-tree +#+cindex: tags-tree +Custom commands are configured in the variable +~org-agenda-custom-commands~. You can customize this variable, for +example by pressing {{{kbd(C)}}} from the agenda dispatcher (see [[*The +Agenda Dispatcher]]). You can also directly set it with Emacs Lisp in +the Emacs init file. The following example contains all valid agenda +views: + +#+begin_src emacs-lisp +(setq org-agenda-custom-commands + '(("x" agenda) + ("y" agenda*) + ("w" todo "WAITING") + ("W" todo-tree "WAITING") + ("u" tags "+boss-urgent") + ("v" tags-todo "+boss-urgent") + ("U" tags-tree "+boss-urgent") + ("f" occur-tree "\\") + ("h" . "HOME+Name tags searches") ;description for "h" prefix + ("hl" tags "+home+Lisa") + ("hp" tags "+home+Peter") + ("hk" tags "+home+Kim"))) +#+end_src + +The initial string in each entry defines the keys you have to press +after the dispatcher command in order to access the command. Usually +this is just a single character, but if you have many similar +commands, you can also define two-letter combinations where the first +character is the same in several combinations and serves as a prefix +key[fn:102]. The second parameter is the search type, followed by the +string or regular expression to be used for the matching. The example +above will therefore define: + +- {{{kbd(x)}}} :: + + as a global search for agenda entries planned[fn:103] this week/day. + +- {{{kbd(y)}}} :: + + as the same search, but only for entries with an hour specification + like =[h]h:mm=---think of them as appointments. + +- {{{kbd(w)}}} :: + + as a global search for TODO entries with =WAITING= as the TODO + keyword. + +- {{{kbd(W)}}} :: + + as the same search, but only in the current buffer and displaying + the results as a sparse tree. + +- {{{kbd(u)}}} :: + + as a global tags search for headlines tagged =boss= but not + =urgent=. + +- {{{kbd(v)}}} :: + + The same search, but limiting it to headlines that are also TODO + items. + +- {{{kbd(U)}}} :: + + as the same search, but only in the current buffer and displaying + the result as a sparse tree. + +- {{{kbd(f)}}} :: + + to create a sparse tree (again, current buffer only) with all + entries containing the word =FIXME=. + +- {{{kbd(h)}}} :: + + as a prefix command for a =HOME= tags search where you have to press + an additional key ({{{kbd(l)}}}, {{{kbd(p)}}} or {{{kbd(k)}}}) to + select a name (Lisa, Peter, or Kim) as additional tag to match. + +Note that ~*-tree~ agenda views need to be called from an Org buffer +as they operate on the current buffer only. + +*** Block agenda +:PROPERTIES: +:DESCRIPTION: All the stuff you need in a single buffer. +:END: +#+cindex: block agenda +#+cindex: agenda, with block views + +Another possibility is the construction of agenda views that comprise +the results of /several/ commands, each of which creates a block in +the agenda buffer. The available commands include ~agenda~ for the +daily or weekly agenda (as created with {{{kbd(a)}}}) , ~alltodo~ for +the global TODO list (as constructed with {{{kbd(t)}}}), ~stuck~ for +the list of stuck projects (as obtained with {{{kbd(#)}}}) and the +matching commands discussed above: ~todo~, ~tags~, and ~tags-todo~. + +Here are two examples: + +#+begin_src emacs-lisp +(setq org-agenda-custom-commands + '(("h" "Agenda and Home-related tasks" + ((agenda "") + (tags-todo "home") + (tags "garden"))) + ("o" "Agenda and Office-related tasks" + ((agenda "") + (tags-todo "work") + (tags "office"))))) +#+end_src + +#+texinfo: @noindent +This defines {{{kbd(h)}}} to create a multi-block view for stuff you +need to attend to at home. The resulting agenda buffer contains your +agenda for the current week, all TODO items that carry the tag =home=, +and also all lines tagged with =garden=. Finally the command +{{{kbd(o)}}} provides a similar view for office tasks. + +*** Setting options for custom commands +:PROPERTIES: +:DESCRIPTION: Changing the rules. +:ALT_TITLE: Setting options +:END: +#+cindex: options, for custom agenda views + +#+vindex: org-agenda-custom-commands +Org mode contains a number of variables regulating agenda construction +and display. The global variables define the behavior for all agenda +commands, including the custom commands. However, if you want to +change some settings just for a single custom view, you can do so. +Setting options requires inserting a list of variable names and values +at the right spot in ~org-agenda-custom-commands~. For example: + +#+begin_src emacs-lisp +(setq org-agenda-custom-commands + '(("w" todo "WAITING" + ((org-agenda-sorting-strategy '(priority-down)) + (org-agenda-prefix-format " Mixed: "))) + ("U" tags-tree "+boss-urgent" + ((org-show-context-detail 'minimal))) + ("N" search "" + ((org-agenda-files '("~org/notes.org")) + (org-agenda-text-search-extra-files nil))))) +#+end_src + +#+texinfo: @noindent +Now the {{{kbd(w)}}} command sorts the collected entries only by +priority, and the prefix format is modified to just say =Mixed:= +instead of giving the category of the entry. The sparse tags tree of +{{{kbd(U)}}} now turns out ultra-compact, because neither the headline +hierarchy above the match, nor the headline following the match are +shown. The command {{{kbd(N)}}} does a text search limited to only +a single file. + +For command sets creating a block agenda, ~org-agenda-custom-commands~ +has two separate spots for setting options. You can add options that +should be valid for just a single command in the set, and options that +should be valid for all commands in the set. The former are just +added to the command entry; the latter must come after the list of +command entries. Going back to the block agenda example (see [[*Block +agenda]]), let's change the sorting strategy for the {{{kbd(h)}}} +commands to ~priority-down~, but let's sort the results for =garden= +tags query in the opposite order, ~priority-up~. This would look like +this: + +#+begin_src emacs-lisp +(setq org-agenda-custom-commands + '(("h" "Agenda and Home-related tasks" + ((agenda) + (tags-todo "home") + (tags "garden" + ((org-agenda-sorting-strategy '(priority-up))))) + ((org-agenda-sorting-strategy '(priority-down)))) + ("o" "Agenda and Office-related tasks" + ((agenda) + (tags-todo "work") + (tags "office"))))) +#+end_src + +As you see, the values and parentheses setting is a little complex. +When in doubt, use the customize interface to set this variable---it +fully supports its structure. Just one caveat: when setting options +in this interface, the /values/ are just Lisp expressions. So if the +value is a string, you need to add the double-quotes around the value +yourself. + +#+vindex: org-agenda-custom-commands-contexts +To control whether an agenda command should be accessible from +a specific context, you can customize +~org-agenda-custom-commands-contexts~. Let's say for example that you +have an agenda command {{{kbd(o)}}} displaying a view that you only +need when reading emails. Then you would configure this option like +this: + +#+begin_src emacs-lisp +(setq org-agenda-custom-commands-contexts + '(("o" (in-mode . "message-mode")))) +#+end_src + +You can also tell that the command key {{{kbd(o)}}} should refer to +another command key {{{kbd(r)}}}. In that case, add this command key +like this: + +#+begin_src emacs-lisp +(setq org-agenda-custom-commands-contexts + '(("o" "r" (in-mode . "message-mode")))) +#+end_src + +See the docstring of the variable for more information. + +** Exporting Agenda Views +:PROPERTIES: +:DESCRIPTION: Writing a view to a file. +:END: +#+cindex: agenda views, exporting + +If you are away from your computer, it can be very useful to have +a printed version of some agenda views to carry around. Org mode can +export custom agenda views as plain text, HTML[fn:104], Postscript, +PDF[fn:105], and iCalendar files. If you want to do this only +occasionally, use the following command: + +- {{{kbd(C-x C-w)}}} (~org-agenda-write~) :: + #+kindex: C-x C-w + #+findex: org-agenda-write + #+cindex: exporting agenda views + #+cindex: agenda views, exporting + + #+vindex: org-agenda-exporter-settings + Write the agenda view to a file. + +If you need to export certain agenda views frequently, you can +associate any custom agenda command with a list of output file +names[fn:106]. Here is an example that first defines custom commands +for the agenda and the global TODO list, together with a number of +files to which to export them. Then we define two block agenda +commands and specify file names for them as well. File names can be +relative to the current working directory, or absolute. + +#+begin_src emacs-lisp +(setq org-agenda-custom-commands + '(("X" agenda "" nil ("agenda.html" "agenda.ps")) + ("Y" alltodo "" nil ("todo.html" "todo.txt" "todo.ps")) + ("h" "Agenda and Home-related tasks" + ((agenda "") + (tags-todo "home") + (tags "garden")) + nil + ("~/views/home.html")) + ("o" "Agenda and Office-related tasks" + ((agenda) + (tags-todo "work") + (tags "office")) + nil + ("~/views/office.ps" "~/calendars/office.ics")))) +#+end_src + +The extension of the file name determines the type of export. If it +is =.html=, Org mode uses the htmlize package to convert the buffer to +HTML and save it to this file name. If the extension is =.ps=, +~ps-print-buffer-with-faces~ is used to produce Postscript output. If +the extension is =.ics=, iCalendar export is run export over all files +that were used to construct the agenda, and limit the export to +entries listed in the agenda. Any other extension produces a plain +ASCII file. + +The export files are /not/ created when you use one of those +commands interactively because this might use too much overhead. +Instead, there is a special command to produce /all/ specified +files in one step: + +- {{{kbd(e)}}} (~org-store-agenda-views~) :: + + #+kindex: e @r{(Agenda dispatcher)} + #+findex: org-store-agenda-views + Export all agenda views that have export file names associated with + them. + +You can use the options section of the custom agenda commands to also +set options for the export commands. For example: + +#+begin_src emacs-lisp +(setq org-agenda-custom-commands + '(("X" agenda "" + ((ps-number-of-columns 2) + (ps-landscape-mode t) + (org-agenda-prefix-format " [ ] ") + (org-agenda-with-colors nil) + (org-agenda-remove-tags t)) + ("theagenda.ps")))) +#+end_src + +#+texinfo: @noindent +#+vindex: org-agenda-exporter-settings +This command sets two options for the Postscript exporter, to make it +print in two columns in landscape format---the resulting page can be +cut in two and then used in a paper agenda. The remaining settings +modify the agenda prefix to omit category and scheduling information, +and instead include a checkbox to check off items. We also remove the +tags to make the lines compact, and we do not want to use colors for +the black-and-white printer. Settings specified in +~org-agenda-exporter-settings~ also apply, e.g., + +#+begin_src emacs-lisp +(setq org-agenda-exporter-settings + '((ps-number-of-columns 2) + (ps-landscape-mode t) + (org-agenda-add-entry-text-maxlines 5) + (htmlize-output-type 'css))) +#+end_src + +#+texinfo: @noindent +but the settings in ~org-agenda-custom-commands~ take precedence. + +From the command line you may also use: + +#+begin_src shell +emacs -eval (org-batch-store-agenda-views) -kill +#+end_src + +#+texinfo: @noindent +or, if you need to modify some parameters[fn:107] + +#+begin_src shell +emacs -eval '(org-batch-store-agenda-views \ + org-agenda-span (quote month) \ + org-agenda-start-day "2007-11-01" \ + org-agenda-include-diary nil \ + org-agenda-files (quote ("~/org/project.org")))' \ + -kill +#+end_src + +#+texinfo: @noindent +which creates the agenda views restricted to the file +=~/org/project.org=, without diary entries and with a 30-day extent. + +You can also extract agenda information in a way that allows further +processing by other programs. See [[*Extracting Agenda Information]], for +more information. + +** Using Column View in the Agenda +:PROPERTIES: +:DESCRIPTION: Using column view for collected entries. +:ALT_TITLE: Agenda Column View +:END: +#+cindex: column view, in agenda +#+cindex: agenda, column view + +Column view (see [[*Column View]]) is normally used to view and edit +properties embedded in the hierarchical structure of an Org file. It +can be quite useful to use column view also from the agenda, where +entries are collected by certain criteria. + +- {{{kbd(C-c C-x C-c)}}} (~org-agenda-columns~) :: + #+kindex: C-c C-x C-c + #+findex: org-agenda-columns + + Turn on column view in the agenda. + +To understand how to use this properly, it is important to realize +that the entries in the agenda are no longer in their proper outline +environment. This causes the following issues: + +1. + #+vindex: org-columns-default-format-for-agenda + #+vindex: org-columns-default-format + Org needs to make a decision which columns format to use. Since + the entries in the agenda are collected from different files, and + different files may have different columns formats, this is a + non-trivial problem. Org first checks if + ~org-overriding-columns-format~ is currently set, and if so, takes + the format from there. You should set this variable only in the + /local settings section/ of a custom agenda command (see [[*Custom + Agenda Views]]) to make it valid for that specific agenda view. If + no such binding exists, it checks, in sequence, + ~org-columns-default-format-for-agenda~, the format associated with + the first item in the agenda (through a property or a =#+COLUMNS= + setting in that buffer) and finally ~org-columns-default-format~. + +2. + #+cindex: @samp{CLOCKSUM}, special property + If any of the columns has a summary type defined (see [[*Column + attributes]]), turning on column view in the agenda visits all + relevant agenda files and make sure that the computations of this + property are up to date. This is also true for the special + =CLOCKSUM= property. Org then sums the values displayed in the + agenda. In the daily/weekly agenda, the sums cover a single day; + in all other views they cover the entire block. + + It is important to realize that the agenda may show the same entry + /twice/---for example as scheduled and as a deadline---and it may + show two entries from the same hierarchy (for example a /parent/ + and its /child/). In these cases, the summation in the agenda + leads to incorrect results because some values count double. + +3. When the column view in the agenda shows the =CLOCKSUM= property, + that is always the entire clocked time for this item. So even in + the daily/weekly agenda, the clocksum listed in column view may + originate from times outside the current view. This has the + advantage that you can compare these values with a column listing + the planned total effort for a task---one of the major + applications for column view in the agenda. If you want + information about clocked time in the displayed period use clock + table mode (press {{{kbd(R)}}} in the agenda). + +4. + #+cindex: @samp{CLOCKSUM_T}, special property + When the column view in the agenda shows the =CLOCKSUM_T= property, + that is always today's clocked time for this item. So even in the + weekly agenda, the clocksum listed in column view only originates + from today. This lets you compare the time you spent on a task for + today, with the time already spent---via =CLOCKSUM=---and with + the planned total effort for it. + +* Markup for Rich Contents +:PROPERTIES: +:DESCRIPTION: Compose beautiful documents. +:END: + +Org is primarily about organizing and searching through your +plain-text notes. However, it also provides a lightweight yet robust +markup language for rich text formatting and more. For instance, you +may want to center or emphasize text. Or you may need to insert +a formula or image in your writing. Org offers syntax for all of this +and more. Used in conjunction with the export framework (see +[[*Exporting]]), you can author beautiful documents in Org---like the fine +manual you are currently reading. + +** Paragraphs +:PROPERTIES: +:DESCRIPTION: The basic unit of text. +:END: + +#+cindex: paragraphs, markup rules +Paragraphs are separated by at least one empty line. If you need to +enforce a line break within a paragraph, use =\\= at the end of +a line. + +#+cindex: line breaks, markup rules +To preserve the line breaks, indentation and blank lines in a region, +but otherwise use normal formatting, you can use this construct, which +can also be used to format poetry. + +#+cindex: @samp{BEGIN_VERSE} +#+cindex: verse blocks +#+begin_example +,#+BEGIN_VERSE + Great clouds overhead + Tiny black birds rise and fall + Snow covers Emacs + + ---AlexSchroeder +,#+END_VERSE +#+end_example + +When quoting a passage from another document, it is customary to +format this as a paragraph that is indented on both the left and the +right margin. You can include quotations in Org documents like this: + +#+cindex: @samp{BEGIN_QUOTE} +#+cindex: quote blocks +#+begin_example +,#+BEGIN_QUOTE +Everything should be made as simple as possible, +but not any simpler ---Albert Einstein +,#+END_QUOTE +#+end_example + +If you would like to center some text, do it like this: + +#+cindex: @samp{BEGIN_CENTER} +#+cindex: center blocks +#+begin_example +,#+BEGIN_CENTER +Everything should be made as simple as possible, \\ +but not any simpler +,#+END_CENTER +#+end_example + +** Emphasis and Monospace +:PROPERTIES: +:DESCRIPTION: Bold, italic, etc. +:END: +#+cindex: underlined text, markup rules +#+cindex: bold text, markup rules +#+cindex: italic text, markup rules +#+cindex: verbatim text, markup rules +#+cindex: code text, markup rules +#+cindex: strike-through text, markup rules + +You can make words =*bold*=, =/italic/=, =_underlined_=, ==verbatim== +and =~code~=, and, if you must, =+strike-through+=. Text in the code +and verbatim string is not processed for Org specific syntax; it is +exported verbatim. + +#+vindex: org-fontify-emphasized-text +To turn off fontification for marked up text, you can set +~org-fontify-emphasized-text~ to ~nil~. To narrow down the list of +available markup syntax, you can customize ~org-emphasis-alist~. + +** Subscripts and Superscripts +:PROPERTIES: +:DESCRIPTION: Simple syntax for raising/lowering text. +:END: +#+cindex: subscript +#+cindex: superscript + +=^= and =_= are used to indicate super- and subscripts. To increase +the readability of ASCII text, it is not necessary, but OK, to +surround multi-character sub- and superscripts with curly braces. For +example + +#+begin_example +The radius of the sun is R_sun = 6.96 x 10^8 m. On the other hand, +the radius of Alpha Centauri is R_{Alpha Centauri} = 1.28 x R_{sun}. +#+end_example + +#+vindex: org-use-sub-superscripts +If you write a text where the underscore is often used in a different +context, Org's convention to always interpret these as subscripts can +get in your way. Configure the variable ~org-use-sub-superscripts~ to +change this convention. For example, when setting this variable to +~{}~, =a_b= is not interpreted as a subscript, but =a_{b}= is. + +You can set ~org-use-sub-superscripts~ in a file using the export +option =^:= (see [[*Export Settings][Export Settings]]). For example, =#+OPTIONS: ^:{}= +sets ~org-use-sub-superscripts~ to ~{}~ and limits super- and +subscripts to the curly bracket notation. + +You can also toggle the visual display of super- and subscripts: + +- {{{kbd(C-c C-x \)}}} (~org-toggle-pretty-entities~) :: + + #+kindex: C-c C-x \ + #+findex: org-toggle-pretty-entities + This command formats sub- and superscripts in a WYSIWYM way. + +#+vindex: org-pretty-entities +#+vindex: org-pretty-entities-include-sub-superscripts +Set both ~org-pretty-entities~ and +~org-pretty-entities-include-sub-superscripts~ to ~t~ to start with +super- and subscripts /visually/ interpreted as specified by the +option ~org-use-sub-superscripts~. + +** Special Symbols +:PROPERTIES: +:DESCRIPTION: Greek letters and other symbols. +:END: +#+cindex: math symbols +#+cindex: special symbols +#+cindex: entities + +You can use LaTeX-like syntax to insert special symbols---named +entities---like =\alpha= to indicate the Greek letter, or =\to= to indicate +an arrow. Completion for these symbols is available, just type =\= +and maybe a few letters, and press {{{kbd(M-TAB)}}} to see possible +completions. If you need such a symbol inside a word, terminate it +with a pair of curly brackets. For example + +#+begin_example +Pro tip: Given a circle \Gamma of diameter d, the length of its +circumference is \pi{}d. +#+end_example + +#+findex: org-entities-help +#+vindex: org-entities-user +A large number of entities is provided, with names taken from both +HTML and LaTeX; you can comfortably browse the complete list from +a dedicated buffer using the command ~org-entities-help~. It is also +possible to provide your own special symbols in the variable +~org-entities-user~. + +During export, these symbols are transformed into the native format of +the exporter back-end. Strings like =\alpha= are exported as =α= in +the HTML output, and as =\(\alpha\)= in the LaTeX output. Similarly, =\nbsp= +becomes = = in HTML and =~= in LaTeX. + +#+cindex: special symbols, in-buffer display +If you would like to see entities displayed as UTF-8 characters, use +the following command[fn:108]: + +- {{{kbd(C-c C-x \)}}} (~org-toggle-pretty-entities~) :: + #+kindex: C-c C-x \ + #+findex: org-toggle-pretty-entities + + Toggle display of entities as UTF-8 characters. This does not + change the buffer content which remains plain ASCII, but it overlays + the UTF-8 character for display purposes only. + +#+cindex: shy hyphen, special symbol +#+cindex: dash, special symbol +#+cindex: ellipsis, special symbol +In addition to regular entities defined above, Org exports in +a special way[fn:109] the following commonly used character +combinations: =\-= is treated as a shy hyphen, =--= and =---= are +converted into dashes, and =...= becomes a compact set of dots. + +** Embedded LaTeX +:PROPERTIES: +:DESCRIPTION: LaTeX can be freely used inside Org documents. +:END: +#+cindex: @TeX{} interpretation +#+cindex: @LaTeX{} interpretation + +Plain ASCII is normally sufficient for almost all note taking. +Exceptions include scientific notes, which often require mathematical +symbols and the occasional formula. LaTeX[fn:110] is widely used to +typeset scientific documents. Org mode supports embedding LaTeX code +into its files, because many academics are used to writing and reading +LaTeX source code, and because it can be readily processed to produce +pretty output for a number of export back-ends. + +*** LaTeX fragments +:PROPERTIES: +:DESCRIPTION: Complex formulas made easy. +:END: +#+cindex: @LaTeX{} fragments + +#+vindex: org-format-latex-header +Org mode can contain LaTeX math fragments, and it supports ways to +process these for several export back-ends. When exporting to LaTeX, +the code is left as it is. When exporting to HTML, Org can use either +[[http://www.mathjax.org][MathJax]] (see [[*Math formatting in HTML export]]) or transcode the math +into images (see [[*Previewing LaTeX fragments]]). + +LaTeX fragments do not need any special marking at all. The following +snippets are identified as LaTeX source code: + +- Environments of any kind[fn:111]. The only requirement is that the + =\begin= statement appears on a new line, preceded by only + whitespace. + +- Text within the usual LaTeX math delimiters. To avoid conflicts + with currency specifications, single =$= characters are only + recognized as math delimiters if the enclosed text contains at most + two line breaks, is directly attached to the =$= characters with no + whitespace in between, and if the closing =$= is followed by + whitespace, punctuation or a dash. For the other delimiters, there + is no such restriction, so when in doubt, use =\(...\)= as inline + math delimiters. + +#+texinfo: @noindent +For example: + +#+begin_example +\begin{equation} % arbitrary environments, +x=\sqrt{b} % even tables, figures +\end{equation} % etc + +If $a^2=b$ and \( b=2 \), then the solution must be +either $$ a=+\sqrt{2} $$ or \[ a=-\sqrt{2} \]. +#+end_example + +#+vindex: org-export-with-latex +LaTeX processing can be configured with the variable +~org-export-with-latex~. The default setting is ~t~ which means +MathJax for HTML, and no processing for ASCII and LaTeX back-ends. +You can also set this variable on a per-file basis using one of these +lines: + +| =#+OPTIONS: tex:t= | Do the right thing automatically (MathJax) | +| =#+OPTIONS: tex:nil= | Do not process LaTeX fragments at all | +| =#+OPTIONS: tex:verbatim= | Verbatim export, for jsMath or so | + +*** Previewing LaTeX fragments +:PROPERTIES: +:DESCRIPTION: What will this snippet look like? +:END: +#+cindex: @LaTeX{} fragments, preview + +#+vindex: org-preview-latex-default-process +If you have a working LaTeX installation and =dvipng=, =dvisvgm= or +=convert= installed[fn:112], LaTeX fragments can be processed to +produce images of the typeset expressions to be used for inclusion +while exporting to HTML (see [[*LaTeX fragments]]), or for inline +previewing within Org mode. + +#+vindex: org-format-latex-options +#+vindex: org-format-latex-header +You can customize the variables ~org-format-latex-options~ and +~org-format-latex-header~ to influence some aspects of the preview. +In particular, the ~:scale~ (and for HTML export, ~:html-scale~) +property of the former can be used to adjust the size of the preview +images. + +- {{{kbd(C-c C-x C-l)}}} (~org-latex-preview~) :: + #+kindex: C-c C-x C-l + #+findex: org-latex-preview + + Produce a preview image of the LaTeX fragment at point and overlay + it over the source code. If there is no fragment at point, process + all fragments in the current entry---between two headlines. + + When called with a single prefix argument, clear all images in the + current entry. Two prefix arguments produce a preview image for all + fragments in the buffer, while three of them clear all the images in + that buffer. + +#+vindex: org-startup-with-latex-preview +You can turn on the previewing of all LaTeX fragments in a file with + +: #+STARTUP: latexpreview + +To disable it, simply use + +: #+STARTUP: nolatexpreview + +*** Using CDLaTeX to enter math +:PROPERTIES: +:DESCRIPTION: Speed up entering of formulas. +:ALT_TITLE: CDLaTeX mode +:END: +#+cindex: CD@LaTeX{} + +CDLaTeX mode is a minor mode that is normally used in combination with +a major LaTeX mode like AUCTeX in order to speed-up insertion of +environments and math templates. Inside Org mode, you can make use of +some of the features of CDLaTeX mode. You need to install +=cdlatex.el= and =texmathp.el= (the latter comes also with AUCTeX) +using [[https://melpa.org/][MELPA]] with the [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Package-Installation.html][Emacs packaging system]] or alternatively from +[[https://staff.fnwi.uva.nl/c.dominik/Tools/cdlatex/]]. Do not use +CDLaTeX mode itself under Org mode, but use the special version Org +CDLaTeX minor mode that comes as part of Org. Turn it on for the +current buffer with {{{kbd(M-x org-cdlatex-mode)}}}, or for all Org +files with + +#+begin_src emacs-lisp +(add-hook 'org-mode-hook 'turn-on-org-cdlatex) +#+end_src + +When this mode is enabled, the following features are present (for +more details see the documentation of CDLaTeX mode): + +#+attr_texinfo: :sep , +- {{{kbd(C-c {)}}} :: + #+kindex: C-c @{ + + Insert an environment template. + +- {{{kbd(TAB)}}} :: + #+kindex: TAB + + The {{{kbd(TAB)}}} key expands the template if point is inside + a LaTeX fragment[fn:113]. For example, {{{kbd(TAB)}}} expands =fr= + to =\frac{}{}= and position point correctly inside the first brace. + Another {{{kbd(TAB)}}} gets you into the second brace. + + Even outside fragments, {{{kbd(TAB)}}} expands environment + abbreviations at the beginning of a line. For example, if you write + =equ= at the beginning of a line and press {{{kbd(TAB)}}}, this + abbreviation is expanded to an =equation= environment. To get + a list of all abbreviations, type {{{kbd(M-x + cdlatex-command-help)}}}. + +- {{{kbd(^)}}}, {{{kbd(_)}}} :: + #+kindex: _ + #+kindex: ^ + #+vindex: cdlatex-simplify-sub-super-scripts + + Pressing {{{kbd(_)}}} and {{{kbd(^)}}} inside a LaTeX fragment + inserts these characters together with a pair of braces. If you use + {{{kbd(TAB)}}} to move out of the braces, and if the braces surround + only a single character or macro, they are removed again (depending + on the variable ~cdlatex-simplify-sub-super-scripts~). + +- {{{kbd(`)}}} :: + #+kindex: ` + + Pressing the backquote followed by a character inserts math macros, + also outside LaTeX fragments. If you wait more than 1.5 seconds + after the backquote, a help window pops up. + +- {{{kbd(')}}} :: + #+kindex: ' + + Pressing the single-quote followed by another character modifies the + symbol before point with an accent or a font. If you wait more than + 1.5 seconds after the single-quote, a help window pops up. + Character modification works only inside LaTeX fragments; outside + the quote is normal. + +** Literal Examples +:PROPERTIES: +:DESCRIPTION: Source code examples with special formatting. +:END: +#+cindex: literal examples, markup rules +#+cindex: code line references, markup rules + +You can include literal examples that should not be subjected to +markup. Such examples are typeset in monospace, so this is well +suited for source code and similar examples. + +#+cindex: @samp{BEGIN_EXAMPLE} +#+cindex: example block +#+begin_example +,#+BEGIN_EXAMPLE + Some example from a text file. +,#+END_EXAMPLE +#+end_example + +#+cindex: comma escape, in literal examples +There is one limitation, however. You must insert a comma right +before lines starting with either =*=, =,*=, =#+= or =,#+=, as those +may be interpreted as outlines nodes or some other special syntax. +Org transparently strips these additional commas whenever it accesses +the contents of the block. + +#+begin_example +,#+BEGIN_EXAMPLE +,,* I am no real headline +,#+END_EXAMPLE +#+end_example + +For simplicity when using small examples, you can also start the +example lines with a colon followed by a space. There may also be +additional whitespace before the colon: + +#+begin_example +Here is an example + : Some example from a text file. +#+end_example + +#+cindex: formatting source code, markup rules +#+vindex: org-latex-listings +If the example is source code from a programming language, or any +other text that can be marked up by Font Lock in Emacs, you can ask +for the example to look like the fontified Emacs buffer[fn:114]. This +is done with the code block, where you also need to specify the name +of the major mode that should be used to fontify the example[fn:115], +see [[*Structure Templates]] for shortcuts to easily insert code blocks. + +#+cindex: @samp{BEGIN_SRC} +#+cindex: source block +#+begin_example +,#+BEGIN_SRC emacs-lisp + (defun org-xor (a b) + "Exclusive or." + (if a (not b) b)) + ,#+END_SRC +#+end_example + +Both in =example= and in =src= snippets, you can add a =-n= switch to +the end of the =#+BEGIN= line, to get the lines of the example +numbered. The =-n= takes an optional numeric argument specifying the +starting line number of the block. If you use a =+n= switch, the +numbering from the previous numbered snippet is continued in the +current one. The =+n= switch can also take a numeric argument. This +adds the value of the argument to the last line of the previous block +to determine the starting line number. + +#+begin_example +,#+BEGIN_SRC emacs-lisp -n 20 + ;; This exports with line number 20. + (message "This is line 21") +,#+END_SRC + +,#+BEGIN_SRC emacs-lisp +n 10 + ;; This is listed as line 31. + (message "This is line 32") +,#+END_SRC +#+end_example + +In literal examples, Org interprets strings like =(ref:name)= as +labels, and use them as targets for special hyperlinks like +=[[(name)]]=---i.e., the reference name enclosed in single parenthesis. +In HTML, hovering the mouse over such a link remote-highlights the +corresponding code line, which is kind of cool. + +You can also add a =-r= switch which /removes/ the labels from the +source code[fn:116]. With the =-n= switch, links to these references +are labeled by the line numbers from the code listing. Otherwise +links use the labels with no parentheses. Here is an example: + +#+begin_example -l "(dumb-reference:%s)" +,#+BEGIN_SRC emacs-lisp -n -r + (save-excursion (ref:sc) + (goto-char (point-min)) (ref:jump) +,#+END_SRC +In line [[(sc)]] we remember the current position. [[(jump)][Line (jump)]] +jumps to point-min. +#+end_example + +#+cindex: indentation, in source blocks +Source code and examples may be /indented/ in order to align nicely +with the surrounding text, and in particular with plain list structure +(see [[*Plain Lists]]). By default, Org only retains the relative +indentation between lines, e.g., when exporting the contents of the +block. However, you can use the =-i= switch to also preserve the +global indentation, if it does matter. See [[*Editing Source Code]]. + +#+vindex: org-coderef-label-format +If the syntax for the label format conflicts with the language syntax, +use a =-l= switch to change the format, for example + +: #+BEGIN_SRC pascal -n -r -l "((%s))" + +#+texinfo: @noindent +See also the variable ~org-coderef-label-format~. + +HTML export also allows examples to be published as text areas (see +[[*Text areas in HTML export]]). + +Because the =#+BEGIN= ... =#+END= patterns need to be added so often, +a shortcut is provided (see [[*Structure Templates]]). + +- {{{kbd(C-c ')}}} (~org-edit-special~) :: + + #+kindex: C-c ' + #+findex: org-edit-special + Edit the source code example at point in its native mode. This + works by switching to a temporary buffer with the source code. You + need to exit by pressing {{{kbd(C-c ')}}} again. The edited version + then replaces the old version in the Org buffer. Fixed-width + regions---where each line starts with a colon followed by + a space---are edited using Artist mode[fn:117] to allow creating + ASCII drawings easily. Using this command in an empty line creates + a new fixed-width region. + +#+cindex: storing link, in a source code buffer +Calling ~org-store-link~ (see [[*Handling Links]]) while editing a source +code example in a temporary buffer created with {{{kbd(C-c ')}}} +prompts for a label. Make sure that it is unique in the current +buffer, and insert it with the proper formatting like =(ref:label)= at +the end of the current line. Then the label is stored as a link +=(label)=, for retrieval with {{{kbd(C-c C-l)}}}. + +** Images +:PROPERTIES: +:DESCRIPTION: Display an image. +:END: + +#+cindex: inlining images +#+cindex: images, markup rules +An image is a link to an image file[fn:118] that does not have +a description part, for example + +: ./img/cat.jpg + +If you wish to define a caption for the image (see [[*Captions]]) and +maybe a label for internal cross references (see [[*Internal Links]]), +make sure that the link is on a line by itself and precede it with +=CAPTION= and =NAME= keywords as follows: + +#+begin_example +,#+CAPTION: This is the caption for the next figure link (or table) +,#+NAME: fig:SED-HR4049 +[[./img/a.jpg]] +#+end_example + +Such images can be displayed within the buffer with the following +command: + +- {{{kbd(C-c C-x C-v)}}} (~org-toggle-inline-images~) :: + + #+kindex: C-c C-x C-v + #+findex: org-toggle-inline-images + #+vindex: org-startup-with-inline-images + Toggle the inline display of linked images. When called with + a prefix argument, also display images that do have a link + description. You can ask for inline images to be displayed at + startup by configuring the variable + ~org-startup-with-inline-images~[fn:119]. + +** Captions +:PROPERTIES: +:DESCRIPTION: Describe tables, images... +:END: +#+cindex: captions, markup rules +#+cindex: @samp{CAPTION}, keyword + +You can assign a caption to a specific part of a document by inserting +a =CAPTION= keyword immediately before it: + +#+begin_example +,#+CAPTION: This is the caption for the next table (or link) +| ... | ... | +|-----+-----| +#+end_example + +Optionally, the caption can take the form: + +: #+CAPTION[Short caption]: Longer caption. + +Even though images and tables are prominent examples of captioned +structures, the same caption mechanism can apply to many +others---e.g., LaTeX equations, source code blocks. Depending on the +export back-end, those may or may not be handled. + +** Horizontal Rules +:PROPERTIES: +:DESCRIPTION: Make a line. +:END: + +#+cindex: horizontal rules, markup rules +A line consisting of only dashes, and at least 5 of them, is exported +as a horizontal line. + +** Creating Footnotes +:PROPERTIES: +:DESCRIPTION: Edit and read footnotes. +:END: +#+cindex: footnotes + +A footnote is started by a footnote marker in square brackets in +column 0, no indentation allowed. It ends at the next footnote +definition, headline, or after two consecutive empty lines. The +footnote reference is simply the marker in square brackets, inside +text. Markers always start with =fn:=. For example: + +#+begin_example +The Org homepage[fn:1] now looks a lot better than it used to. +... +[fn:1] The link is: https://orgmode.org +#+end_example + +Org mode extends the number-based syntax to /named/ footnotes and +optional inline definition. Here are the valid references: + +- =[fn:NAME]= :: + + A named footnote reference, where {{{var(NAME)}}} is a unique + label word, or, for simplicity of automatic creation, a number. + +- =[fn:: This is the inline definition of this footnote]= :: + + An anonymous footnote where the definition is given directly at the + reference point. + +- =[fn:NAME: a definition]= :: + + An inline definition of a footnote, which also specifies a name for + the note. Since Org allows multiple references to the same note, + you can then use =[fn:NAME]= to create additional references. + +#+vindex: org-footnote-auto-label +Footnote labels can be created automatically, or you can create names +yourself. This is handled by the variable ~org-footnote-auto-label~ +and its corresponding =STARTUP= keywords. See the docstring of that +variable for details. + +The following command handles footnotes: + +- {{{kbd(C-c C-x f)}}} :: + + The footnote action command. + + #+kindex: C-c C-x f + When point is on a footnote reference, jump to the definition. When + it is at a definition, jump to the---first---reference. + + #+vindex: org-footnote-define-inline + #+vindex: org-footnote-section + Otherwise, create a new footnote. Depending on the variable + ~org-footnote-define-inline~[fn:120], the definition is placed right + into the text as part of the reference, or separately into the + location determined by the variable ~org-footnote-section~. + + When this command is called with a prefix argument, a menu of + additional options is offered: + + #+attr_texinfo: :columns 0.1 0.9 + | {{{kbd(s)}}} | Sort the footnote definitions by reference sequence. | + | {{{kbd(r)}}} | Renumber the simple =fn:N= footnotes. | + | {{{kbd(S)}}} | Short for first {{{kbd(r)}}}, then {{{kbd(s)}}} action. | + | {{{kbd(n)}}} | Rename all footnotes into a =fn:1= ... =fn:n= sequence. | + | {{{kbd(d)}}} | Delete the footnote at point, including definition and references. | + + #+vindex: org-footnote-auto-adjust + Depending on the variable ~org-footnote-auto-adjust~[fn:121], + renumbering and sorting footnotes can be automatic after each + insertion or deletion. + +- {{{kbd(C-c C-c)}}} :: + + #+kindex: C-c C-c + If point is on a footnote reference, jump to the definition. If it + is at the definition, jump back to the reference. When called at + a footnote location with a prefix argument, offer the same menu as + {{{kbd(C-c C-x f)}}}. + +- {{{kbd(C-c C-o)}}} or {{{kbd(mouse-1/2)}}} :: + + #+kindex: C-c C-o + #+kindex: mouse-1 + #+kindex: mouse-2 + Footnote labels are also links to the corresponding definition or + reference, and you can use the usual commands to follow these links. + +* Exporting +:PROPERTIES: +:DESCRIPTION: Sharing and publishing notes. +:END: +#+cindex: exporting + +At some point you might want to print your notes, publish them on the +web, or share them with people not using Org. Org can convert and +export documents to a variety of other formats while retaining as much +structure (see [[*Document Structure]]) and markup (see [[*Markup for Rich +Contents]]) as possible. + +#+cindex: export back-end +The libraries responsible for translating Org files to other formats +are called /back-ends/. Org ships with support for the following +back-ends: + +- /ascii/ (ASCII format) +- /beamer/ (LaTeX Beamer format) +- /html/ (HTML format) +- /icalendar/ (iCalendar format) +- /latex/ (LaTeX format) +- /md/ (Markdown format) +- /odt/ (OpenDocument Text format) +- /org/ (Org format) +- /texinfo/ (Texinfo format) +- /man/ (Man page format) + +Users can install libraries for additional formats from the Emacs +packaging system. For easy discovery, these packages have a common +naming scheme: ~ox-NAME~, where {{{var(NAME)}}} is a format. For +example, ~ox-koma-letter~ for /koma-letter/ back-end. More libraries +can be found in the =contrib/= directory (see [[*Installation]]). + +#+vindex: org-export-backends +Org only loads back-ends for the following formats by default: ASCII, +HTML, iCalendar, LaTeX, and ODT. Additional back-ends can be loaded +in either of two ways: by configuring the ~org-export-backends~ +variable, or by requiring libraries in the Emacs init file. For +example, to load the Markdown back-end, add this to your Emacs config: + +#+begin_src emacs-lisp +(require 'ox-md) +#+end_src + +** The Export Dispatcher +:PROPERTIES: +:DESCRIPTION: The main interface. +:END: +#+cindex: dispatcher, for export commands +#+cindex: export, dispatcher + +The export dispatcher is the main interface for Org's exports. +A hierarchical menu presents the currently configured export formats. +Options are shown as easy toggle switches on the same screen. + +#+vindex: org-export-dispatch-use-expert-ui +Org also has a minimal prompt interface for the export dispatcher. +When the variable ~org-export-dispatch-use-expert-ui~ is set to +a non-~nil~ value, Org prompts in the minibuffer. To switch back to +the hierarchical menu, press {{{kbd(?)}}}. + +- {{{kbd(C-c C-e)}}} (~org-export~) :: + #+kindex: C-c C-e + #+findex: org-export + + Invokes the export dispatcher interface. The options show default + settings. The {{{kbd(C-u)}}} prefix argument preserves options from + the previous export, including any sub-tree selections. + +Org exports the entire buffer by default. If the Org buffer has an +active region, then Org exports just that region. + +Within the dispatcher interface, the following key combinations can +further alter what is exported, and how. + +- {{{kbd(C-a)}}} :: + #+kindex: C-c C-e C-a + + Toggle asynchronous export. Asynchronous export uses an external + Emacs process with a specially configured initialization file to + complete the exporting process in the background, without tying-up + Emacs. This is particularly useful when exporting long documents. + + Output from an asynchronous export is saved on the /export stack/. + To view this stack, call the export dispatcher with a double + {{{kbd(C-u)}}} prefix argument. If already in the export dispatcher + menu, {{{kbd(&)}}} displays the stack. + + #+vindex: org-export-in-background + You can make asynchronous export the default by setting + ~org-export-in-background~. + + #+vindex: org-export-async-init-file + You can set the initialization file used by the background process + by setting ~org-export-async-init-file~. + +- {{{kbd(C-b)}}} :: + #+kindex: C-c C-e C-b + + Toggle body-only export. Useful for excluding headers and footers + in the export. Affects only those back-end formats that have + sections like =...= in HTML. + +- {{{kbd(C-s)}}} :: + #+kindex: C-c C-e C-s + + Toggle sub-tree export. When turned on, Org exports only the + sub-tree starting from point position at the time the export + dispatcher was invoked. Org uses the top heading of this sub-tree + as the document's title. If point is not on a heading, Org uses the + nearest enclosing header. If point is in the document preamble, Org + signals an error and aborts export. + + #+vindex: org-export-initial-scope + To make sub-tree export the default, customize the variable + ~org-export-initial-scope~. + +- {{{kbd(C-v)}}} :: + #+kindex: C-c C-e C-v + + Toggle visible-only export. This is useful for exporting only + certain parts of an Org document by adjusting the visibility of + particular headings. + +** Export Settings +:PROPERTIES: +:DESCRIPTION: Common export settings. +:END: +#+cindex: options, for export +#+cindex: Export, settings + +#+cindex: @samp{OPTIONS}, keyword +Export options can be set: globally with variables; for an individual +file by making variables buffer-local with in-buffer settings (see +[[*Summary of In-Buffer Settings]]); by setting individual keywords or +specifying them in compact form with the =OPTIONS= keyword; or for +a tree by setting properties (see [[*Properties and Columns]]). Options +set at a specific level override options set at a more general level. + +#+cindex: @samp{SETUPFILE}, keyword +In-buffer settings may appear anywhere in the file, either directly or +indirectly through a file included using =#+SETUPFILE: filename or +URL= syntax. Option keyword sets tailored to a particular back-end +can be inserted from the export dispatcher (see [[*The Export +Dispatcher]]) using the =Insert template= command by pressing +{{{kbd(#)}}}. To insert keywords individually, a good way to make +sure the keyword is correct is to type =#+= and then to use +{{{kbd(M-TAB)}}}[fn:16] for completion. + +The export keywords available for every back-end, and their equivalent +global variables, include: + +- =AUTHOR= :: + + #+cindex: @samp{AUTHOR}, keyword + #+vindex: user-full-name + The document author (~user-full-name~). + +- =CREATOR= :: + + #+cindex: @samp{CREATOR}, keyword + #+vindex: org-expot-creator-string + Entity responsible for output generation + (~org-export-creator-string~). + +- =DATE= :: + + #+cindex: @samp{DATE}, keyword + #+vindex: org-export-date-timestamp-format + A date or a time-stamp[fn:122]. + +- =EMAIL= :: + + #+cindex: @samp{EMAIL}, keyword + #+vindex: user-mail-address + The email address (~user-mail-address~). + +- =LANGUAGE= :: + + #+cindex: @samp{LANGUAGE}, keyword + #+vindex: org-export-default-language + Language to use for translating certain strings + (~org-export-default-language~). With =#+LANGUAGE: fr=, for + example, Org translates =Table of contents= to the French =Table des + matières=[fn:123]. + +- =SELECT_TAGS= :: + + #+cindex: @samp{SELECT_TAGS}, keyword + #+vindex: org-export-select-tags + The default value is =("export")=. When a tree is tagged with + =export= (~org-export-select-tags~), Org selects that tree and its + sub-trees for export. Org excludes trees with =noexport= tags, see + below. When selectively exporting files with =export= tags set, Org + does not export any text that appears before the first headline. + +- =EXCLUDE_TAGS= :: + + #+cindex: @samp{EXCLUDE_TAGS}, keyword + #+vindex: org-export-exclude-tags + The default value is =("noexport")=. When a tree is tagged with + =noexport= (~org-export-exclude-tags~), Org excludes that tree and + its sub-trees from export. Entries tagged with =noexport= are + unconditionally excluded from the export, even if they have an + =export= tag. Even if a sub-tree is not exported, Org executes any + code blocks contained there. + +- =TITLE= :: + + #+cindex: @samp{TITLE}, keyword + #+cindex: document title + Org displays this title. For long titles, use multiple =#+TITLE= + lines. + +- =EXPORT_FILE_NAME= :: + + #+cindex: @samp{EXPORT_FILE_NAME}, keyword + The name of the output file to be generated. Otherwise, Org + generates the file name based on the buffer name and the extension + based on the back-end format. + +The =OPTIONS= keyword is a compact form. To configure multiple +options, use several =OPTIONS= lines. =OPTIONS= recognizes the +following arguments. + +- ~'~ :: + + #+vindex: org-export-with-smart-quotes + Toggle smart quotes (~org-export-with-smart-quotes~). Depending on + the language used, when activated, Org treats pairs of double quotes + as primary quotes, pairs of single quotes as secondary quotes, and + single quote marks as apostrophes. + +- ~*~ :: + + #+vindex: org-export-with-emphasize + Toggle emphasized text (~org-export-with-emphasize~). + +- ~-~ :: + + #+vindex: org-export-with-special-strings + Toggle conversion of special strings + (~org-export-with-special-strings~). + +- ~:~ :: + + #+vindex: org-export-with-fixed-width + Toggle fixed-width sections (~org-export-with-fixed-width~). + +- ~<~ :: + + #+vindex: org-export-with-timestamps + Toggle inclusion of time/date active/inactive stamps + (~org-export-with-timestamps~). + +- ~\n~ :: + + #+vindex: org-export-preserve-breaks + Toggles whether to preserve line breaks + (~org-export-preserve-breaks~). + +- ~^~ :: + + #+vindex: org-export-with-sub-superscripts + Toggle TeX-like syntax for sub- and superscripts. If you write + =^:{}=, =a_{b}= is interpreted, but the simple =a_b= is left as it + is (~org-export-with-sub-superscripts~). + +- ~arch~ :: + + #+vindex: org-export-with-archived-trees + Configure how archived trees are exported. When set to ~headline~, + the export process skips the contents and processes only the + headlines (~org-export-with-archived-trees~). + +- ~author~ :: + + #+vindex: org-export-with-author + Toggle inclusion of author name into exported file + (~org-export-with-author~). + +- ~broken-links~ :: + + #+vindex: org-export-with-broken-links + Toggles if Org should continue exporting upon finding a broken + internal link. When set to ~mark~, Org clearly marks the problem + link in the output (~org-export-with-broken-links~). + +- ~c~ :: + + #+vindex: org-export-with-clocks + Toggle inclusion of =CLOCK= keywords (~org-export-with-clocks~). + +- ~creator~ :: + + #+vindex: org-export-with-creator + Toggle inclusion of creator information in the exported file + (~org-export-with-creator~). + +- ~d~ :: + + #+vindex: org-export-with-drawers + Toggles inclusion of drawers, or list of drawers to include, or list + of drawers to exclude (~org-export-with-drawers~). + +- ~date~ :: + + #+vindex: org-export-with-date + Toggle inclusion of a date into exported file + (~org-export-with-date~). + +- ~e~ :: + + #+vindex: org-export-with-entities + Toggle inclusion of entities (~org-export-with-entities~). + +- ~email~ :: + + #+vindex: org-export-with-email + Toggle inclusion of the author's e-mail into exported file + (~org-export-with-email~). + +- ~f~ :: + + #+vindex: org-export-with-footnotes + Toggle the inclusion of footnotes (~org-export-with-footnotes~). + +- ~H~ :: + + #+vindex: org-export-headline-levels + Set the number of headline levels for export + (~org-export-headline-levels~). Below that level, headlines are + treated differently. In most back-ends, they become list items. + +- ~inline~ :: + + #+vindex: org-export-with-inlinetasks + Toggle inclusion of inlinetasks (~org-export-with-inlinetasks~). + +- ~num~ :: + + #+vindex: org-export-with-section-numbers + #+cindex: @samp{UNNUMBERED}, property + Toggle section-numbers (~org-export-with-section-numbers~). When + set to number N, Org numbers only those headlines at level N or + above. Set =UNNUMBERED= property to non-~nil~ to disable numbering + of heading and subheadings entirely. Moreover, when the value is + =notoc= the headline, and all its children, do not appear in the + table of contents either (see [[*Table of Contents]]). + +- ~p~ :: + + #+vindex: org-export-with-planning + Toggle export of planning information (~org-export-with-planning~). + "Planning information" comes from lines located right after the + headline and contain any combination of these cookies: =SCHEDULED=, + =DEADLINE=, or =CLOSED=. + +- ~pri~ :: + + #+vindex: org-export-with-priority + Toggle inclusion of priority cookies + (~org-export-with-priority~). + +- ~prop~ :: + + #+vindex: org-export-with-properties + Toggle inclusion of property drawers, or list the properties to + include (~org-export-with-properties~). + +- ~stat~ :: + + #+vindex: org-export-with-statistics-cookies + Toggle inclusion of statistics cookies + (~org-export-with-statistics-cookies~). + +- ~tags~ :: + + #+vindex: org-export-with-tags + Toggle inclusion of tags, may also be ~not-in-toc~ + (~org-export-with-tags~). + +- ~tasks~ :: + + #+vindex: org-export-with-tasks + Toggle inclusion of tasks (TODO items); or ~nil~ to remove all + tasks; or ~todo~ to remove done tasks; or list the keywords to keep + (~org-export-with-tasks~). + +- ~tex~ :: + + #+vindex: org-export-with-latex + ~nil~ does not export; ~t~ exports; ~verbatim~ keeps everything in + verbatim (~org-export-with-latex~). + +- ~timestamp~ :: + + #+vindex: org-export-time-stamp-file + Toggle inclusion of the creation time in the exported file + (~org-export-time-stamp-file~). + +- ~title~ :: + + #+vindex: org-export-with-title + Toggle inclusion of title (~org-export-with-title~). + +- ~toc~ :: + + #+vindex: org-export-with-toc + Toggle inclusion of the table of contents, or set the level limit + (~org-export-with-toc~). + +- ~todo~ :: + + #+vindex: org-export-with-todo-keywords + Toggle inclusion of TODO keywords into exported text + (~org-export-with-todo-keywords~). + +- ~|~ :: + + #+vindex: org-export-with-tables + Toggle inclusion of tables (~org-export-with-tables~). + +When exporting sub-trees, special node properties can override the +above keywords. These properties have an =EXPORT_= prefix. For +example, =DATE= becomes, =EXPORT_DATE= when used for a specific +sub-tree. Except for =SETUPFILE=, all other keywords listed above +have an =EXPORT_= equivalent. + +#+cindex: @samp{BIND}, keyword +#+vindex: org-export-allow-bind-keywords +If ~org-export-allow-bind-keywords~ is non-~nil~, Emacs variables can +become buffer-local during export by using the =BIND= keyword. Its +syntax is =#+BIND: variable value=. This is particularly useful for +in-buffer settings that cannot be changed using keywords. + +** Table of Contents +:PROPERTIES: +:DESCRIPTION: The if and where of the table of contents. +:END: +#+cindex: table of contents +#+cindex: list of tables +#+cindex: list of listings + +#+cindex: @samp{toc}, in @samp{OPTIONS} keyword +#+vindex: org-export-with-toc +The table of contents includes all headlines in the document. Its +depth is therefore the same as the headline levels in the file. If +you need to use a different depth, or turn it off entirely, set the +~org-export-with-toc~ variable accordingly. You can achieve the same +on a per file basis, using the following =toc= item in =OPTIONS= +keyword: + +#+begin_example +,#+OPTIONS: toc:2 (only include two levels in TOC) +,#+OPTIONS: toc:nil (no default TOC at all) +#+end_example + +#+cindex: excluding entries from table of contents +#+cindex: table of contents, exclude entries +Org includes both numbered and unnumbered headlines in the table of +contents[fn:124]. If you need to exclude an unnumbered headline, +along with all its children, set the =UNNUMBERED= property to =notoc= +value. + +#+begin_example +,* Subtree not numbered, not in table of contents either + :PROPERTIES: + :UNNUMBERED: notoc + :END: +#+end_example + +#+cindex: @samp{TOC}, keyword +Org normally inserts the table of contents directly before the first +headline of the file. To move the table of contents to a different +location, first turn off the default with ~org-export-with-toc~ +variable or with =#+OPTIONS: toc:nil=. Then insert =#+TOC: headlines +N= at the desired location(s). + +#+begin_example +,#+OPTIONS: toc:nil +... +,#+TOC: headlines 2 +#+end_example + +To adjust the table of contents depth for a specific section of the +Org document, append an additional =local= parameter. This parameter +becomes a relative depth for the current level. The following example +inserts a local table of contents, with direct children only. + +#+begin_example +,* Section +,#+TOC: headlines 1 local +#+end_example + +Note that for this feature to work properly in LaTeX export, the Org +file requires the inclusion of the titletoc package. Because of +compatibility issues, titletoc has to be loaded /before/ hyperref. +Customize the ~org-latex-default-packages-alist~ variable. + +The following example inserts a table of contents that links to the +children of the specified target. + +#+begin_example +,* Target + :PROPERTIES: + :CUSTOM_ID: TargetSection + :END: +,** Heading A +,** Heading B +,* Another section +,#+TOC: headlines 1 :target #TargetSection +#+end_example + +The =:target= attribute is supported in HTML, Markdown, ODT, and ASCII export. + +Use the =TOC= keyword to generate list of tables---respectively, all +listings---with captions. + +#+begin_example +,#+TOC: listings +,#+TOC: tables +#+end_example + +#+cindex: @samp{ALT_TITLE}, property +Normally Org uses the headline for its entry in the table of contents. +But with =ALT_TITLE= property, a different entry can be specified for +the table of contents. + +** Include Files +:PROPERTIES: +:DESCRIPTION: Include additional files into a document. +:END: +#+cindex: include files, during export +#+cindex: export, include files +#+cindex: @samp{INCLUDE}, keyword + +During export, you can include the content of another file. For +example, to include your =.emacs= file, you could use: + +: #+INCLUDE: "~/.emacs" src emacs-lisp + +#+texinfo: @noindent +The first parameter is the file name to include. The optional second +parameter specifies the block type: =example=, =export= or =src=. The +optional third parameter specifies the source code language to use for +formatting the contents. This is relevant to both =export= and =src= +block types. + +If an included file is specified as having a markup language, Org +neither checks for valid syntax nor changes the contents in any way. +For example and source blocks, Org code-escapes the contents before +inclusion. + +#+cindex: @samp{minlevel}, include +If an included file is not specified as having any markup language, +Org assumes it be in Org format and proceeds as usual with a few +exceptions. Org makes the footnote labels (see [[*Creating Footnotes]]) +in the included file local to that file. The contents of the included +file belong to the same structure---headline, item---containing the +=INCLUDE= keyword. In particular, headlines within the file become +children of the current section. That behavior can be changed by +providing an additional keyword parameter, =:minlevel=. It shifts the +headlines in the included file to become the lowest level. For +example, this syntax makes the included file a sibling of the current +top-level headline: + +: #+INCLUDE: "~/my-book/chapter2.org" :minlevel 1 + +#+cindex: @samp{lines}, include +Inclusion of only portions of files are specified using ranges +parameter with =:lines= keyword. The line at the upper end of the +range will not be included. The start and/or the end of the range may +be omitted to use the obvious defaults. + +| =#+INCLUDE: "~/.emacs" :lines "5-10"= | Include lines 5 to 10, 10 excluded | +| =#+INCLUDE: "~/.emacs" :lines "-10"= | Include lines 1 to 10, 10 excluded | +| =#+INCLUDE: "~/.emacs" :lines "10-"= | Include lines from 10 to EOF | + +Inclusions may specify a file-link to extract an object matched by +~org-link-search~[fn:125] (see [[*Search Options in File Links]]). The +ranges for =:lines= keyword are relative to the requested element. +Therefore, + +: #+INCLUDE: "./paper.org::*conclusion" :lines 1-20 + +#+texinfo: @noindent +includes the first 20 lines of the headline named =conclusion=. + +#+cindex: @samp{only-contents}, include +To extract only the contents of the matched object, set +=:only-contents= property to non-~nil~. This omits any planning lines +or property drawers. For example, to include the body of the heading +with the custom ID =theory=, you can use + +: #+INCLUDE: "./paper.org::#theory" :only-contents t + +The following command allows navigating to the included document: + +- {{{kbd(C-c ')}}} (~org-edit~special~) :: + #+kindex: C-c ' + #+findex: org-edit-special + + Visit the included file at point. + +** Macro Replacement +:PROPERTIES: +:DESCRIPTION: Use macros to create templates. +:END: +#+cindex: macro replacement, during export +#+cindex: @samp{MACRO}, keyword + +#+vindex: org-export-global-macros +Macros replace text snippets during export. Macros are defined +globally in ~org-export-global-macros~, or document-wise with the +following syntax: + +: #+MACRO: name replacement text; $1, $2 are arguments + +#+texinfo: @noindent +which can be referenced using ={{{name(arg1, arg2)}}}=[fn:126]. For +example + +#+begin_example +,#+MACRO: poem Rose is $1, violet's $2. Life's ordered: Org assists you. +{{{poem(red,blue)}}} +#+end_example + +#+texinfo: @noindent +becomes + +: Rose is red, violet's blue. Life's ordered: Org assists you. + +As a special case, Org parses any replacement text starting with +=(eval= as an Emacs Lisp expression and evaluates it accordingly. +Within such templates, arguments become strings. Thus, the following +macro + +: #+MACRO: gnustamp (eval (concat "GNU/" (capitalize $1))) + +#+texinfo: @noindent +turns ={{{gnustamp(linux)}}}= into =GNU/Linux= during export. + +Org recognizes macro references in following Org markup areas: +paragraphs, headlines, verse blocks, tables cells and lists. Org also +recognizes macro references in keywords, such as =CAPTION=, =TITLE=, +=AUTHOR=, =DATE=, and for some back-end specific export options. + +Org comes with following pre-defined macros: + +#+attr_texinfo: :sep ; +- ={{{keyword(NAME)}}}=; ={{{title}}}=; ={{{author}}}=; ={{{email}}}= :: + + #+cindex: @samp{keyword}, macro + #+cindex: @samp{title}, macro + #+cindex: @samp{author}, macro + #+cindex: @samp{email}, macro + The =keyword= macro collects all values from {{{var(NAME)}}} + keywords throughout the buffer, separated with white space. + =title=, =author= and =email= macros are shortcuts for, + respectively, ={{{keyword(TITLE)}}}=, ={{{keyword(AUTHOR)}}}= and + ={{{keyword(EMAIL)}}}=. + +- ={{{date}}}=; ={{{date(FORMAT)}}}= :: + + #+cindex: @samp{date}, macro + This macro refers to the =DATE= keyword. {{{var(FORMAT)}}} is an + optional argument to the =date= macro that is used only if =DATE= is + a single timestamp. {{{var(FORMAT)}}} should be a format string + understood by ~format-time-string~. + +- ={{{time(FORMAT)}}}=; ={{{modification-time(FORMAT, VC)}}}= :: + + #+cindex: @samp{time}, macro + #+cindex: @samp{modification-time}, macro + These macros refer to the document's date and time of export and + date and time of modification. {{{var(FORMAT)}}} is a string + understood by ~format-time-string~. If the second argument to the + ~modification-time~ macro is non-~nil~, Org uses =vc.el= to retrieve + the document's modification time from the version control system. + Otherwise Org reads the file attributes. + +- ={{{input-file}}}= :: + + #+cindex: @samp{input-file}, macro + This macro refers to the filename of the exported file. + +- ={{{property(PROPERTY-NAME)}}}=; ={{{property(PROPERTY-NAME, SEARCH OPTION)}}}= :: + + #+cindex: @samp{property}, macro + This macro returns the value of property {{{var(PROPERTY-NAME)}}} in + the current entry. If {{{var(SEARCH-OPTION)}}} (see [[*Search + Options in File Links]]) refers to a remote entry, use it instead. + +- ={{{n}}}=; ={{{n(NAME)}}}=; ={{{n(NAME, ACTION)}}}= :: + + #+cindex: @samp{n}, macro + #+cindex: counter, macro + This macro implements custom counters by returning the number of + times the macro has been expanded so far while exporting the buffer. + You can create more than one counter using different {{{var(NAME)}}} + values. If {{{var(ACTION)}}} is =-=, previous value of the counter + is held, i.e., the specified counter is not incremented. If the + value is a number, the specified counter is set to that value. If + it is any other non-empty string, the specified counter is reset + to 1. You may leave {{{var(NAME)}}} empty to reset the default + counter. + +#+cindex: @samp{results}, macro +Moreover, inline source blocks (see [[*Structure of Code Blocks]]) use the +special =results= macro to mark their output. As such, you are +advised against re-defining it, unless you know what you are doing. + +#+vindex: org-hide-macro-markers +The surrounding brackets can be made invisible by setting +~org-hide-macro-markers~ to a non-~nil~ value. + +Org expands macros at the very beginning of the export process. + +** Comment Lines +:PROPERTIES: +:DESCRIPTION: What will not be exported. +:END: +#+cindex: exporting, not + +#+cindex: comment lines +Lines starting with zero or more whitespace characters followed by one +=#= and a whitespace are treated as comments and, as such, are not +exported. + +#+cindex: @samp{BEGIN_COMMENT} +#+cindex: comment block +Likewise, regions surrounded by =#+BEGIN_COMMENT= ... =#+END_COMMENT= +are not exported. + +#+cindex: comment trees +Finally, a =COMMENT= keyword at the beginning of an entry, but after +any other keyword or priority cookie, comments out the entire subtree. +In this case, the subtree is not exported and no code block within it +is executed either[fn:127]. The command below helps changing the +comment status of a headline. + +- {{{kbd(C-c ;)}}} (~org-toggle-comment~) :: + #+kindex: C-c ; + #+findex: org-toggle-comment + + Toggle the =COMMENT= keyword at the beginning of an entry. + +** ASCII/Latin-1/UTF-8 export +:PROPERTIES: +:DESCRIPTION: Exporting to flat files with encoding. +:END: +#+cindex: ASCII export +#+cindex: Latin-1 export +#+cindex: UTF-8 export + +ASCII export produces an output file containing only plain ASCII +characters. This is the simplest and most direct text output. It +does not contain any Org markup. Latin-1 and UTF-8 export use +additional characters and symbols available in these encoding +standards. All three of these export formats offer the most basic of +text output for maximum portability. + +#+vindex: org-ascii-text-width +On export, Org fills and justifies text according to the text width +set in ~org-ascii-text-width~. + +#+vindex: org-ascii-links-to-notes +Org exports links using a footnote-like style where the descriptive +part is in the text and the link is in a note before the next heading. +See the variable ~org-ascii-links-to-notes~ for details. + +*** ASCII export commands +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+attr_texinfo: :sep , +- {{{kbd(C-c C-e t a)}}} (~org-ascii-export-to-ascii~), {{{kbd(C-c C-e t l)}}}, {{{kbd(C-c C-e t u)}}} :: + #+kindex: C-c C-e t a + #+kindex: C-c C-e t l + #+kindex: C-c C-e t u + #+findex: org-ascii-export-to-ascii + + Export as an ASCII file with a =.txt= extension. For =myfile.org=, + Org exports to =myfile.txt=, overwriting without warning. For + =myfile.txt=, Org exports to =myfile.txt.txt= in order to prevent + data loss. + +- {{{kbd(C-c C-e t A)}}} (~org-ascii-export-to-ascii~), {{{kbd(C-c C-e t L)}}}, {{{kbd(C-c C-e t U)}}} :: + #+kindex: C-c C-e t A + #+kindex: C-c C-e t L + #+kindex: C-c C-e t U + #+findex: org-ascii-export-as-ascii + + Export to a temporary buffer. Does not create a file. + +*** ASCII specific export settings +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +The ASCII export back-end has one extra keyword for customizing ASCII +output. Setting this keyword works similar to the general options +(see [[*Export Settings]]). + +- =SUBTITLE= :: + + #+cindex: @samp{SUBTITLE}, keyword + The document subtitle. For long subtitles, use multiple + =#+SUBTITLE= lines in the Org file. Org prints them on one + continuous line, wrapping into multiple lines if necessary. + +*** Header and sectioning structure +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +Org converts the first three outline levels into headlines for ASCII +export. The remaining levels are turned into lists. To change this +cut-off point where levels become lists, see [[*Export Settings]]. + +*** Quoting ASCII text +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +To insert text within the Org file by the ASCII back-end, use one the +following constructs, inline, keyword, or export block: + +#+cindex: @samp{ASCII}, keyword +#+cindex: @samp{BEGIN_EXPORT ascii} +#+begin_example +Inline text @@ascii:and additional text@@ within a paragraph. + +,#+ASCII: Some text + +,#+BEGIN_EXPORT ascii +Org exports text in this block only when using ASCII back-end. +,#+END_EXPORT +#+end_example + +*** ASCII specific attributes +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: @samp{ATTR_ASCII}, keyword +#+cindex: horizontal rules, in ASCII export + +ASCII back-end recognizes only one attribute, =:width=, which +specifies the width of a horizontal rule in number of characters. The +keyword and syntax for specifying widths is: + +#+begin_example +,#+ATTR_ASCII: :width 10 +----- +#+end_example + +*** ASCII special blocks +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+cindex: special blocks, in ASCII export +#+cindex: @samp{BEGIN_JUSTIFYLEFT} +#+cindex: @samp{BEGIN_JUSTIFYRIGHT} + +Besides =#+BEGIN_CENTER= blocks (see [[*Paragraphs]]), ASCII back-end has +these two left and right justification blocks: + +#+begin_example +,#+BEGIN_JUSTIFYLEFT +It's just a jump to the left... +,#+END_JUSTIFYLEFT + +,#+BEGIN_JUSTIFYRIGHT +...and then a step to the right. +,#+END_JUSTIFYRIGHT +#+end_example + +** Beamer Export +:PROPERTIES: +:DESCRIPTION: Producing presentations and slides. +:END: +#+cindex: Beamer export + +Org uses Beamer export to convert an Org file tree structure into +high-quality interactive slides for presentations. Beamer is a LaTeX +document class for creating presentations in PDF, HTML, and other +popular display formats. + +*** Beamer export commands +:PROPERTIES: +:DESCRIPTION: For creating Beamer documents. +:END: + +- {{{kbd(C-c C-e l b)}}} (~org-beamer-export-to-latex~) :: + #+kindex: C-c C-e l b + #+findex: org-beamer-export-to-latex + + Export as LaTeX file with a =.tex= extension. For =myfile.org=, Org + exports to =myfile.tex=, overwriting without warning. + +- {{{kbd(C-c C-e l B)}}} (~org-beamer-export-as-latex~) :: + #+kindex: C-c C-e l B + #+findex: org-beamer-export-as-latex + + Export to a temporary buffer. Does not create a file. + +- {{{kbd(C-c C-e l P)}}} (~org-beamer-export-to-pdf~) :: + #+kindex: C-c C-e l P + #+findex: org-beamer-export-to-pdf + + Export as LaTeX file and then convert it to PDF format. + +- {{{kbd(C-c C-e l O)}}} :: + #+kindex: C-c C-e l O + + Export as LaTeX file, convert it to PDF format, and then open the + PDF file. + +*** Beamer specific export settings +:PROPERTIES: +:DESCRIPTION: For customizing Beamer export. +:END: + +Beamer export back-end has several additional keywords for customizing +Beamer output. These keywords work similar to the general options +settings (see [[*Export Settings]]). + +- =BEAMER_THEME= :: + + #+cindex: @samp{BEAMER_THEME}, keyword + #+vindex: org-beamer-theme + The Beamer layout theme (~org-beamer-theme~). Use square brackets + for options. For example: + + : #+BEAMER_THEME: Rochester [height=20pt] + +- =BEAMER_FONT_THEME= :: + + #+cindex: @samp{BEAMER_FONT_THEME}, keyword + The Beamer font theme. + +- =BEAMER_INNER_THEME= :: + + #+cindex: @samp{BEAMER_INNER_THEME}, keyword + The Beamer inner theme. + +- =BEAMER_OUTER_THEME= :: + + #+cindex: @samp{BEAMER_OUTER_THEME}, keyword + The Beamer outer theme. + +- =BEAMER_HEADER= :: + + #+cindex: @samp{BEAMER_HEADER}, keyword + Arbitrary lines inserted in the preamble, just before the =hyperref= + settings. + +- =DESCRIPTION= :: + + #+cindex: @samp{DESCRIPTION}, keyword + The document description. For long descriptions, use multiple + =DESCRIPTION= keywords. By default, =hyperref= inserts + =DESCRIPTION= as metadata. Use ~org-latex-hyperref-template~ to + configure document metadata. Use ~org-latex-title-command~ to + configure typesetting of description as part of front matter. + +- =KEYWORDS= :: + + #+cindex: @samp{KEYWORDS}, keyword + The keywords for defining the contents of the document. Use + multiple =KEYWORDS= lines if necessary. By default, =hyperref= + inserts =KEYWORDS= as metadata. Use ~org-latex-hyperref-template~ + to configure document metadata. Use ~org-latex-title-command~ to + configure typesetting of keywords as part of front matter. + +- =SUBTITLE= :: + + #+cindex: @samp{SUBTITLE}, keyword + Document's subtitle. For typesetting, use + ~org-beamer-subtitle-format~ string. Use + ~org-latex-hyperref-template~ to configure document metadata. Use + ~org-latex-title-command~ to configure typesetting of subtitle as + part of front matter. + +*** Frames and Blocks in Beamer +:PROPERTIES: +:DESCRIPTION: For composing Beamer slides. +:END: + +Org transforms heading levels into Beamer's sectioning elements, +frames and blocks. Any Org tree with a not-too-deep-level nesting +should in principle be exportable as a Beamer presentation. + +- + #+vindex: org-beamer-frame-level + Org headlines become Beamer frames when the heading level in Org is + equal to ~org-beamer-frame-level~ or =H= value in a =OPTIONS= line + (see [[*Export Settings]]). + + #+cindex: @samp{BEAMER_ENV}, property + Org overrides headlines to frames conversion for the current tree of + an Org file if it encounters the =BEAMER_ENV= property set to + =frame= or =fullframe=. Org ignores whatever + ~org-beamer-frame-level~ happens to be for that headline level in + the Org tree. In Beamer terminology, a full frame is a frame + without its title. + +- Org exports a Beamer frame's objects as block environments. Org can + enforce wrapping in special block types when =BEAMER_ENV= property + is set[fn:128]. For valid values see + ~org-beamer-environments-default~. To add more values, see + ~org-beamer-environments-extra~. + #+vindex: org-beamer-environments-default + #+vindex: org-beamer-environments-extra + +- + #+cindex: @samp{BEAMER_REF}, property + If =BEAMER_ENV= is set to =appendix=, Org exports the entry as an + appendix. When set to =note=, Org exports the entry as a note + within the frame or between frames, depending on the entry's heading + level. When set to =noteNH=, Org exports the entry as a note + without its title. When set to =againframe=, Org exports the entry + with =\againframe= command, which makes setting the =BEAMER_REF= + property mandatory because =\againframe= needs frame to resume. + + When =ignoreheading= is set, Org export ignores the entry's headline + but not its content. This is useful for inserting content between + frames. It is also useful for properly closing a =column= + environment. @end itemize + + #+cindex: @samp{BEAMER_ACT}, property + #+cindex: @samp{BEAMER_OPT}, property + When =BEAMER_ACT= is set for a headline, Org export translates that + headline as an overlay or action specification. When enclosed in + square brackets, Org export makes the overlay specification + a default. Use =BEAMER_OPT= to set any options applicable to the + current Beamer frame or block. The Beamer export back-end wraps + with appropriate angular or square brackets. It also adds the + =fragile= option for any code that may require a verbatim block. + + #+cindex: @samp{BEAMER_COL}, property + To create a column on the Beamer slide, use the =BEAMER_COL= + property for its headline in the Org file. Set the value of + =BEAMER_COL= to a decimal number representing the fraction of the + total text width. Beamer export uses this value to set the column's + width and fills the column with the contents of the Org entry. If + the Org entry has no specific environment defined, Beamer export + ignores the heading. If the Org entry has a defined environment, + Beamer export uses the heading as title. Behind the scenes, Beamer + export automatically handles LaTeX column separations for contiguous + headlines. To manually adjust them for any unique configurations + needs, use the =BEAMER_ENV= property. + +*** Beamer specific syntax +:PROPERTIES: +:DESCRIPTION: For using in Org documents. +:END: + +Since Org's Beamer export back-end is an extension of the LaTeX +back-end, it recognizes other LaTeX specific syntax---for example, +=#+LATEX:= or =#+ATTR_LATEX:=. See [[*LaTeX Export]], for details. + +Beamer export wraps the table of contents generated with =toc:t= +=OPTION= keyword in a =frame= environment. Beamer export does not +wrap the table of contents generated with =TOC= keyword (see [[*Table of +Contents]]). Use square brackets for specifying options. + +: #+TOC: headlines [currentsection] + +Insert Beamer-specific code using the following constructs: + +#+cindex: @samp{BEAMER}, keyword +#+cindex: @samp{BEGIN_EXPORT beamer} +#+begin_example +,#+BEAMER: \pause + +,#+BEGIN_EXPORT beamer + Only Beamer export back-end exports this. +,#+END_BEAMER + +Text @@beamer:some code@@ within a paragraph. +#+end_example + +Inline constructs, such as the last one above, are useful for adding +overlay specifications to objects with ~bold~, ~item~, ~link~, +~radio-target~ and ~target~ types. Enclose the value in angular +brackets and place the specification at the beginning of the object as +shown in this example: + +: A *@@beamer:<2->@@useful* feature + +#+cindex: @samp{ATTR_BEAMER}, keyword +Beamer export recognizes the =ATTR_BEAMER= keyword with the following +attributes from Beamer configurations: =:environment= for changing +local Beamer environment, =:overlay= for specifying Beamer overlays in +angular or square brackets, and =:options= for inserting optional +arguments. + +#+begin_example +,#+ATTR_BEAMER: :environment nonindentlist +- item 1, not indented +- item 2, not indented +- item 3, not indented +#+end_example + +#+begin_example +,#+ATTR_BEAMER: :overlay <+-> +- item 1 +- item 2 +#+end_example + +#+begin_example +,#+ATTR_BEAMER: :options [Lagrange] +Let $G$ be a finite group, and let $H$ be +a subgroup of $G$. Then the order of $H$ divides the order of $G$. +#+end_example + +*** Editing support +:PROPERTIES: +:DESCRIPTION: Editing support. +:END: + +Org Beamer mode is a special minor mode for faster editing of Beamer +documents. + +: #+STARTUP: beamer + +- {{{kbd(C-c C-b)}}} (~org-beamer-select-environment~) :: + #+kindex: C-c C-b + #+findex: org-beamer-select-environment + + Org Beamer mode provides this key for quicker selections in Beamer + normal environments, and for selecting the =BEAMER_COL= property. + +*** A Beamer example +:PROPERTIES: +:DESCRIPTION: A complete presentation. +:END: + +Here is an example of an Org document ready for Beamer export. + +#+begin_example +,#+TITLE: Example Presentation +,#+AUTHOR: Carsten Dominik +,#+OPTIONS: H:2 toc:t num:t +,#+LATEX_CLASS: beamer +,#+LATEX_CLASS_OPTIONS: [presentation] +,#+BEAMER_THEME: Madrid +,#+COLUMNS: %45ITEM %10BEAMER_ENV(Env) %10BEAMER_ACT(Act) %4BEAMER_COL(Col) + +,* This is the first structural section + +,** Frame 1 +,*** Thanks to Eric Fraga :B_block: + :PROPERTIES: + :BEAMER_COL: 0.48 + :BEAMER_ENV: block + :END: + for the first viable Beamer setup in Org +,*** Thanks to everyone else :B_block: + :PROPERTIES: + :BEAMER_COL: 0.48 + :BEAMER_ACT: <2-> + :BEAMER_ENV: block + :END: + for contributing to the discussion +,**** This will be formatted as a beamer note :B_note: + :PROPERTIES: + :BEAMER_env: note + :END: +,** Frame 2 (where we will not use columns) +,*** Request + Please test this stuff! +#+end_example + +** HTML Export +:PROPERTIES: +:DESCRIPTION: Exporting to HTML. +:END: +#+cindex: HTML export + +Org mode contains an HTML exporter with extensive HTML formatting +compatible with XHTML 1.0 strict standard. + +*** HTML export commands +:PROPERTIES: +:DESCRIPTION: Invoking HTML export. +:END: + +- {{{kbd(C-c C-e h h)}}} (~org-html-export-to-html~) :: + #+kindex: C-c C-e h h + #+kindex: C-c C-e h o + #+findex: org-html-export-to-html + + Export as HTML file with a =.html= extension. For =myfile.org=, Org + exports to =myfile.html=, overwriting without warning. {{{kbd{C-c + C-e h o)}}} exports to HTML and opens it in a web browser. + +- {{{kbd(C-c C-e h H)}}} (~org-html-export-as-html~) :: + #+kindex: C-c C-e h H + #+findex: org-html-export-as-html + + Exports to a temporary buffer. Does not create a file. + +*** HTML specific export settings +:PROPERTIES: +:DESCRIPTION: Settings for HTML export. +:END: + +HTML export has a number of keywords, similar to the general options +settings described in [[*Export Settings]]. + +- =DESCRIPTION= :: + + #+cindex: @samp{DESCRIPTION}, keyword + This is the document's description, which the HTML exporter inserts + it as a HTML meta tag in the HTML file. For long descriptions, use + multiple =DESCRIPTION= lines. The exporter takes care of wrapping + the lines properly. + +- =HTML_DOCTYPE= :: + + #+cindex: @samp{HTML_DOCTYPE}, keyword + #+vindex: org-html-doctype + Specify the document type, for example: HTML5 (~org-html-doctype~). + +- =HTML_CONTAINER= :: + + #+cindex: @samp{HTML_CONTAINER}, keyword + #+vindex: org-html-container-element + Specify the HTML container, such as =div=, for wrapping sections and + elements (~org-html-container-element~). + +- =HTML_LINK_HOME= :: + + #+cindex: @samp{HTML_LINK_HOME}, keyword + #+vindex: org-html-link-home + The URL for home link (~org-html-link-home~). + +- =HTML_LINK_UP= :: + + #+cindex: @samp{HTML_LINK_UP}, keyword + #+vindex: org-html-link-up + The URL for the up link of exported HTML pages (~org-html-link-up~). + +- =HTML_MATHJAX= :: + + #+cindex: @samp{HTML_MATHJAX}, keyword + #+vindex: org-html-mathjax-options + Options for MathJax (~org-html-mathjax-options~). MathJax is used + to typeset LaTeX math in HTML documents. See [[*Math formatting in + HTML export]], for an example. + +- =HTML_HEAD= :: + + #+cindex: @samp{HTML_HEAD}, keyword + #+vindex: org-html-head + Arbitrary lines for appending to the HTML document's head + (~org-html-head~). + +- =HTML_HEAD_EXTRA= :: + + #+cindex: @samp{HTML_HEAD_EXTRA}, keyword + #+vindex: org-html-head-extra + More arbitrary lines for appending to the HTML document's head + (~org-html-head-extra~). + +- =KEYWORDS= :: + + #+cindex: @samp{KEYWORDS}, keyword + Keywords to describe the document's content. HTML exporter inserts + these keywords as HTML meta tags. For long keywords, use multiple + =KEYWORDS= lines. + +- =LATEX_HEADER= :: + + #+cindex: @samp{LATEX_HEADER}, keyword + Arbitrary lines for appending to the preamble; HTML exporter appends + when transcoding LaTeX fragments to images (see [[*Math formatting in + HTML export]]). + +- =SUBTITLE= :: + + #+cindex: @samp{SUBTITLE}, keyword + The document's subtitle. HTML exporter formats subtitle if document + type is =HTML5= and the CSS has a =subtitle= class. + +Some of these keywords are explained in more detail in the following +sections of the manual. + +*** HTML doctypes +:PROPERTIES: +:DESCRIPTION: Exporting various (X)HTML flavors. +:END: + +Org can export to various (X)HTML flavors. + +#+vindex: org-html-doctype +#+vindex: org-html-doctype-alist +Set the ~org-html-doctype~ variable for different (X)HTML variants. +Depending on the variant, the HTML exporter adjusts the syntax of HTML +conversion accordingly. Org includes the following ready-made +variants: + +- ~"html4-strict"~ +- ~"html4-transitional"~ +- ~"html4-frameset"~ +- ~"xhtml-strict"~ +- ~"xhtml-transitional"~ +- ~"xhtml-frameset"~ +- ~"xhtml-11"~ +- ~"html5"~ +- ~"xhtml5"~ + +#+texinfo: @noindent +See the variable ~org-html-doctype-alist~ for details. The default is +~"xhtml-strict"~. + +#+vindex: org-html-html5-fancy +#+cindex: @samp{HTML5}, export new elements +Org's HTML exporter does not by default enable new block elements +introduced with the HTML5 standard. To enable them, set +~org-html-html5-fancy~ to non-~nil~. Or use an =OPTIONS= line in the +file to set =html5-fancy=. + +HTML5 documents can now have arbitrary =#+BEGIN= ... =#+END= blocks. +For example: + +#+begin_example +,#+BEGIN_aside + Lorem ipsum +,#+END_aside +#+end_example + +#+texinfo: @noindent +exports to: + +#+begin_src html +

+#+end_src + +#+texinfo: @noindent +while this: + +#+begin_example +,#+ATTR_HTML: :controls controls :width 350 +,#+BEGIN_video +,#+HTML: +,#+HTML: +Your browser does not support the video tag. +,#+END_video +#+end_example + +#+texinfo: @noindent +exports to: + +#+begin_src html + +#+end_src + +#+vindex: org-html-html5-elements +When special blocks do not have a corresponding HTML5 element, the +HTML exporter reverts to standard translation (see +~org-html-html5-elements~). For example, =#+BEGIN_lederhosen= exports +to ~
~. + +Special blocks cannot have headlines. For the HTML exporter to wrap +the headline and its contents in ~
~ or ~
~ tags, set +the =HTML_CONTAINER= property for the headline. + +*** HTML preamble and postamble +:PROPERTIES: +:DESCRIPTION: Inserting preamble and postamble. +:END: +#+vindex: org-html-preamble +#+vindex: org-html-postamble +#+vindex: org-html-preamble-format +#+vindex: org-html-postamble-format +#+vindex: org-html-validation-link +#+vindex: org-export-creator-string +#+vindex: org-export-time-stamp-file + +The HTML exporter has delineations for preamble and postamble. The +default value for ~org-html-preamble~ is ~t~, which makes the HTML +exporter insert the preamble. See the variable +~org-html-preamble-format~ for the format string. + +Set ~org-html-preamble~ to a string to override the default format +string. If the string is a function, the HTML exporter expects the +function to return a string upon execution. The HTML exporter inserts +this string in the preamble. The HTML exporter does not insert +a preamble if ~org-html-preamble~ is set ~nil~. + +The default value for ~org-html-postamble~ is ~auto~, which makes the +HTML exporter build a postamble from looking up author's name, email +address, creator's name, and date. Set ~org-html-postamble~ to ~t~ to +insert the postamble in the format specified in the +~org-html-postamble-format~ variable. The HTML exporter does not +insert a postamble if ~org-html-postamble~ is set to ~nil~. + +*** Quoting HTML tags +:PROPERTIES: +:DESCRIPTION: Using direct HTML in Org files. +:END: + +The HTML export back-end transforms =<= and =>= to =<= and =>=. +To include raw HTML code in the Org file so the HTML export back-end +can insert that HTML code in the output, use this inline syntax: +=@@html:...@@=. For example: + +: @@html:@@bold text@@html:@@ + +#+cindex: @samp{HTML}, keyword +#+cindex: @samp{BEGIN_EXPORT html} +For larger raw HTML code blocks, use these HTML export code blocks: + +#+begin_example +,#+HTML: Literal HTML code for export + +,#+BEGIN_EXPORT html + All lines between these markers are exported literally +,#+END_EXPORT +#+end_example + +*** Headlines in HTML export +:PROPERTIES: +:DESCRIPTION: Formatting headlines. +:END: +#+cindex: headlines, in HTML export + +Headlines are exported to =

=, =

=, etc. Each headline gets the +=id= attribute from =CUSTOM_ID= property, or a unique generated value, +see [[*Internal Links]]. + +#+vindex: org-html-self-link-headlines +When ~org-html-self-link-headlines~ is set to a non-~nil~ value, the +text of the headlines is also wrapped in == tags. These tags have +a =href= attribute making the headlines link to themselves. + +*** Links in HTML export +:PROPERTIES: +:DESCRIPTION: Inserting and formatting links. +:END: +#+cindex: links, in HTML export +#+cindex: internal links, in HTML export +#+cindex: external links, in HTML export + +The HTML export back-end transforms Org's internal links (see +[[*Internal Links]]) to equivalent HTML links in the output. The back-end +similarly handles Org's automatic links created by radio targets (see +[[*Radio Targets]]) similarly. For Org links to external files, the +back-end transforms the links to /relative/ paths. + +#+vindex: org-html-link-org-files-as-html +For Org links to other =.org= files, the back-end automatically +changes the file extension to =.html= and makes file paths relative. +If the =.org= files have an equivalent =.html= version at the same +location, then the converted links should work without any further +manual intervention. However, to disable this automatic path +translation, set ~org-html-link-org-files-as-html~ to ~nil~. When +disabled, the HTML export back-end substitutes the ID-based links in +the HTML output. For more about linking files when publishing to +a directory, see [[*Publishing links]]. + +Org files can also have special directives to the HTML export +back-end. For example, by using =#+ATTR_HTML= lines to specify new +format attributes to ~~ or ~~ tags. This example shows +changing the link's title and style: + +#+cindex: @samp{ATTR_HTML}, keyword +#+begin_example +,#+ATTR_HTML: :title The Org mode homepage :style color:red; +[[https://orgmode.org]] +#+end_example + +*** Tables in HTML export +:PROPERTIES: +:DESCRIPTION: How to modify the formatting of tables. +:END: +#+cindex: tables, in HTML +#+vindex: org-export-html-table-tag + +The HTML export back-end uses ~org-html-table-default-attributes~ when +exporting Org tables to HTML. By default, the exporter does not draw +frames and cell borders. To change for this for a table, use the +following lines before the table in the Org file: + +#+cindex: @samp{CAPTION}, keyword +#+cindex: @samp{ATTR_HTML}, keyword +#+begin_example +,#+CAPTION: This is a table with lines around and between cells +,#+ATTR_HTML: :border 2 :rules all :frame border +#+end_example + +The HTML export back-end preserves column groupings in Org tables (see +[[*Column Groups]]) when exporting to HTML. + +Additional options for customizing tables for HTML export. + +- ~org-html-table-align-individual-fields~ :: + + #+vindex: org-html-table-align-individual-fields + Non-~nil~ attaches style attributes for alignment to each table + field. + +- ~org-html-table-caption-above~ :: + + #+vindex: org-html-table-caption-above + Non-~nil~ places caption string at the beginning of the table. + +- ~org-html-table-data-tags~ :: + + #+vindex: org-html-table-data-tags + Opening and ending tags for table data fields. + +- ~org-html-table-default-attributes~ :: + + #+vindex: org-html-table-default-attributes + Default attributes and values for table tags. + +- ~org-html-table-header-tags~ :: + + #+vindex: org-html-table-header-tags + Opening and ending tags for table's header fields. + +- ~org-html-table-row-tags~ :: + + #+vindex: org-html-table-row-tags + Opening and ending tags for table rows. + +- ~org-html-table-use-header-tags-for-first-column~ :: + + #+vindex: org-html-table-use-header-tags-for-first-column + Non-~nil~ formats column one in tables with header tags. + +*** Images in HTML export +:PROPERTIES: +:DESCRIPTION: How to insert figures into HTML output. +:END: +#+cindex: images, inline in HTML +#+cindex: inlining images in HTML + +The HTML export back-end has features to convert Org image links to +HTML inline images and HTML clickable image links. + +#+vindex: org-html-inline-images +When the link in the Org file has no description, the HTML export +back-end by default in-lines that image. For example: +=[[file:myimg.jpg]]= is in-lined, while =[[file:myimg.jpg][the image]]= links to the text, +=the image=. For more details, see the variable +~org-html-inline-images~. + +On the other hand, if the description part of the Org link is itself +another link, such as =file:= or =http:= URL pointing to an image, the +HTML export back-end in-lines this image and links to the main image. +This Org syntax enables the back-end to link low-resolution thumbnail +to the high-resolution version of the image, as shown in this example: + +: [[file:highres.jpg][file:thumb.jpg]] + +To change attributes of in-lined images, use =#+ATTR_HTML= lines in +the Org file. This example shows realignment to right, and adds ~alt~ +and ~title~ attributes in support of text viewers and modern web +accessibility standards. + +#+cindex: @samp{CAPTION}, keyword +#+cindex: @samp{ATTR_HTML}, keyword +#+begin_example +,#+CAPTION: A black cat stalking a spider +,#+ATTR_HTML: :alt cat/spider image :title Action! :align right +[[./img/a.jpg]] +#+end_example + +The HTML export back-end copies the =http= links from the Org file +as-is. + +*** Math formatting in HTML export +:PROPERTIES: +:DESCRIPTION: Beautiful math also on the web. +:END: +#+cindex: MathJax +#+cindex: dvipng +#+cindex: dvisvgm +#+cindex: ImageMagick + +#+vindex: org-html-mathjax-options~ +LaTeX math snippets (see [[*LaTeX fragments]]) can be displayed in two +different ways on HTML pages. The default is to use the [[http://www.mathjax.org][MathJax]], +which should work out of the box with Org[fn:129][fn:130]. Some MathJax +display options can be configured via ~org-html-mathjax-options~, or +in the buffer. For example, with the following settings, + +#+begin_example +,#+HTML_MATHJAX: align: left indent: 5em tagside: left font: Neo-Euler +,#+HTML_MATHJAX: cancel.js noErrors.js +#+end_example + +#+texinfo: @noindent +equation labels are displayed on the left margin and equations are +five em from the left margin. In addition, it loads the two MathJax +extensions =cancel.js= and =noErrors.js=[fn:131]. + +#+vindex: org-html-mathjax-template +See the docstring of ~org-html-mathjax-options~ for all supported +variables. The MathJax template can be configure via +~org-html-mathjax-template~. + +If you prefer, you can also request that LaTeX fragments are processed +into small images that will be inserted into the browser page. Before +the availability of MathJax, this was the default method for Org +files. This method requires that the dvipng program, dvisvgm or +ImageMagick suite is available on your system. You can still get this +processing with + +: #+OPTIONS: tex:dvipng + +: #+OPTIONS: tex:dvisvgm + +#+texinfo: @noindent +or + +: #+OPTIONS: tex:imagemagick + +*** Text areas in HTML export +:PROPERTIES: +:DESCRIPTION: An alternate way to show an example. +:END: + +#+cindex: text areas, in HTML +Before Org mode's Babel, one popular approach to publishing code in +HTML was by using =:textarea=. The advantage of this approach was +that copying and pasting was built into browsers with simple +JavaScript commands. Even editing before pasting was made simple. + +The HTML export back-end can create such text areas. It requires an +=#+ATTR_HTML= line as shown in the example below with the =:textarea= +option. This must be followed by either an example or a source code +block. Other Org block types do not honor the =:textarea= option. + +By default, the HTML export back-end creates a text area 80 characters +wide and height just enough to fit the content. Override these +defaults with =:width= and =:height= options on the =#+ATTR_HTML= +line. + +#+begin_example +,#+ATTR_HTML: :textarea t :width 40 +,#+BEGIN_EXAMPLE + (defun org-xor (a b) + "Exclusive or." + (if a (not b) b)) +,#+END_EXAMPLE +#+end_example + +*** CSS support +:PROPERTIES: +:DESCRIPTION: Changing the appearance of the output. +:END: +#+cindex: CSS, for HTML export +#+cindex: HTML export, CSS + +#+vindex: org-export-html-todo-kwd-class-prefix +#+vindex: org-export-html-tag-class-prefix +You can modify the CSS style definitions for the exported file. The +HTML exporter assigns the following special CSS classes[fn:132] to +appropriate parts of the document---your style specifications may +change these, in addition to any of the standard classes like for +headlines, tables, etc. + +| ~p.author~ | author information, including email | +| ~p.date~ | publishing date | +| ~p.creator~ | creator info, about org mode version | +| ~.title~ | document title | +| ~.subtitle~ | document subtitle | +| ~.todo~ | TODO keywords, all not-done states | +| ~.done~ | the DONE keywords, all states that count as done | +| ~.WAITING~ | each TODO keyword also uses a class named after itself | +| ~.timestamp~ | timestamp | +| ~.timestamp-kwd~ | keyword associated with a timestamp, like =SCHEDULED= | +| ~.timestamp-wrapper~ | span around keyword plus timestamp | +| ~.tag~ | tag in a headline | +| ~._HOME~ | each tag uses itself as a class, "@" replaced by "_" | +| ~.target~ | target for links | +| ~.linenr~ | the line number in a code example | +| ~.code-highlighted~ | for highlighting referenced code lines | +| ~div.outline-N~ | div for outline level N (headline plus text) | +| ~div.outline-text-N~ | extra div for text at outline level N | +| ~.section-number-N~ | section number in headlines, different for each level | +| ~.figure-number~ | label like "Figure 1:" | +| ~.table-number~ | label like "Table 1:" | +| ~.listing-number~ | label like "Listing 1:" | +| ~div.figure~ | how to format an in-lined image | +| ~pre.src~ | formatted source code | +| ~pre.example~ | normal example | +| ~p.verse~ | verse paragraph | +| ~div.footnotes~ | footnote section headline | +| ~p.footnote~ | footnote definition paragraph, containing a footnote | +| ~.footref~ | a footnote reference number (always a ) | +| ~.footnum~ | footnote number in footnote definition (always ) | +| ~.org-svg~ | default class for a linked =.svg= image | + +#+vindex: org-html-style-default +#+vindex: org-html-head +#+vindex: org-html-head-extra +#+cindex: @samp{HTML_INCLUDE_STYLE}, keyword +The HTML export back-end includes a compact default style in each +exported HTML file. To override the default style with another style, +use these keywords in the Org file. They will replace the global +defaults the HTML exporter uses. + +#+cindex: @samp{HTML_HEAD}, keyword +#+cindex: @samp{HTML_HEAD_EXTRA}, keyword +#+begin_example +,#+HTML_HEAD: +,#+HTML_HEAD_EXTRA: +#+end_example + +#+vindex: org-html-head-include-default-style +To just turn off the default style, customize +~org-html-head-include-default-style~ variable, or use this option +line in the Org file. + +#+cindex: @samp{html-style}, @samp{OPTIONS} item +: #+OPTIONS: html-style:nil + +For longer style definitions, either use several =HTML_HEAD= and +=HTML_HEAD_EXTRA= keywords, or use ~~ blocks +around them. Both of these approaches can avoid referring to an +external file. + +#+cindex: @samp{HTML_CONTAINER_CLASS}, property +#+cindex: @samp{HTML_HEADLINE_CLASS}, property +In order to add styles to a sub-tree, use the =HTML_CONTAINER_CLASS= +property to assign a class to the tree. In order to specify CSS +styles for a particular headline, you can use the ID specified in +a =CUSTOM_ID= property. You can also assign a specific class to +a headline with the =HTML_HEADLINE_CLASS= property. + +Never change the ~org-html-style-default~ constant. Instead use other +simpler ways of customizing as described above. + +*** JavaScript supported display of web pages +:PROPERTIES: +:DESCRIPTION: Info and folding in a web browser. +:ALT_TITLE: JavaScript support +:END: + +Sebastian Rose has written a JavaScript program especially designed to +allow two different ways of viewing HTML files created with Org. One +is an /Info/-like mode where each section is displayed separately and +navigation can be done with the {{{kbd(n)}}} and {{{kbd(p)}}} keys, and some other +keys as well, press {{{kbd(?)}}} for an overview of the available keys. The +second one has a /folding/ view, much like Org provides inside Emacs. +The script is available at https://orgmode.org/org-info.js and the +documentation at https://orgmode.org/worg/code/org-info-js/. The +script is hosted on https://orgmode.org, but for reliability, prefer +installing it on your own web server. + +To use this program, just add this line to the Org file: + +#+cindex: @samp{INFOJS_OPT}, keyword +: #+INFOJS_OPT: view:info toc:nil + +#+texinfo: @noindent +The HTML header now has the code needed to automatically invoke the +script. For setting options, use the syntax from the above line for +options described below: + +- =path:= :: + + The path to the script. The default is to grab the script from + [[https://orgmode.org/org-info.js]], but you might want to have a local + copy and use a path like =../scripts/org-info.js=. + +- =view:= :: + + Initial view when the website is first shown. Possible values are: + + | =info= | Info-like interface with one section per page | + | =overview= | Folding interface, initially showing only top-level | + | =content= | Folding interface, starting with all headlines visible | + | =showall= | Folding interface, all headlines and text visible | + +- =sdepth:= :: + + Maximum headline level still considered as an independent section + for info and folding modes. The default is taken from + ~org-export-headline-levels~, i.e., the =H= switch in =OPTIONS=. If + this is smaller than in ~org-export-headline-levels~, each + info/folding section can still contain child headlines. + +- =toc:= :: + + Should the table of contents /initially/ be visible? Even when + =nil=, you can always get to the "toc" with {{{kbd(i)}}}. + +- =tdepth:= :: + + The depth of the table of contents. The defaults are taken from the + variables ~org-export-headline-levels~ and ~org-export-with-toc~. + +- =ftoc:= :: + + Does the CSS of the page specify a fixed position for the "toc"? If + yes, the toc is displayed as a section. + +- =ltoc:= :: + + Should there be short contents (children) in each section? Make + this =above= if the section should be above initial text. + +- =mouse:= :: + + Headings are highlighted when the mouse is over them. Should be + =underline= (default) or a background color like =#cccccc=. + +- =buttons:= :: + + Should view-toggle buttons be everywhere? When =nil= (the default), + only one such button is present. + +#+vindex: org-infojs-options +#+vindex: org-export-html-use-infojs +You can choose default values for these options by customizing the +variable ~org-infojs-options~. If you always want to apply the script +to your pages, configure the variable ~org-export-html-use-infojs~. + +** LaTeX Export +:PROPERTIES: +:DESCRIPTION: Exporting to @LaTeX{} and processing to PDF. +:END: +#+cindex: @LaTeX{} export +#+cindex: PDF export + +The LaTeX export back-end can handle complex documents, incorporate +standard or custom LaTeX document classes, generate documents using +alternate LaTeX engines, and produce fully linked PDF files with +indexes, bibliographies, and tables of contents, destined for +interactive online viewing or high-quality print publication. + +While the details are covered in-depth in this section, here are some +quick references to variables for the impatient: for engines, see +~org-latex-compiler~; for build sequences, see +~org-latex-pdf-process~; for packages, see +~org-latex-default-packages-alist~ and ~org-latex-packages-alist~. + +An important note about the LaTeX export back-end: it is sensitive to +blank lines in the Org document. That's because LaTeX itself depends +on blank lines to tell apart syntactical elements, such as paragraphs. + +*** LaTeX/PDF export commands +:PROPERTIES: +:DESCRIPTION: For producing @LaTeX{} and PDF documents. +:END: + +- {{{kbd(C-c C-e l l)}}} (~org-latex-export-to-latex~) :: + + #+kindex: C-c C-e l l + #+findex: org-latex-export-to-latex~ + Export to a LaTeX file with a =.tex= extension. For =myfile.org=, + Org exports to =myfile.tex=, overwriting without warning. + +- {{{kbd(C-c C-e l L)}}} (~org-latex-export-as-latex~) :: + + #+kindex: C-c C-e l L + #+findex: org-latex-export-as-latex + Export to a temporary buffer. Do not create a file. + +- {{{kbd(C-c C-e l p)}}} (~org-latex-export-to-pdf~) :: + + #+kindex: C-c C-e l p + #+findex: org-latex-export-to-pdf + Export as LaTeX file and convert it to PDF file. + +- {{{kbd(C-c C-e l o)}}} :: + + #+kindex: C-c C-e l o + Export as LaTeX file and convert it to PDF, then open the PDF using + the default viewer. + +- {{{kbd(M-x org-export-region-as-latex)}}} :: + + Convert the region to LaTeX under the assumption that it was in Org + mode syntax before. This is a global command that can be invoked in + any buffer. + +#+vindex: org-latex-compiler +#+vindex: org-latex-bibtex-compiler +#+vindex: org-latex-default-packages-alist +#+cindex: pdflatex +#+cindex: xelatex +#+cindex: lualatex +#+cindex: @samp{LATEX_COMPILER}, keyword +The LaTeX export back-end can use any of these LaTeX engines: +=pdflatex=, =xelatex=, and =lualatex=. These engines compile LaTeX +files with different compilers, packages, and output options. The +LaTeX export back-end finds the compiler version to use from +~org-latex-compiler~ variable or the =#+LATEX_COMPILER= keyword in the +Org file. See the docstring for the +~org-latex-default-packages-alist~ for loading packages with certain +compilers. Also see ~org-latex-bibtex-compiler~ to set the +bibliography compiler[fn:133]. + +*** LaTeX specific export settings +:PROPERTIES: +:DESCRIPTION: Unique to this @LaTeX{} back-end. +:END: + +The LaTeX export back-end has several additional keywords for +customizing LaTeX output. Setting these keywords works similar to the +general options (see [[*Export Settings]]). + +#+attr_texinfo: :sep , +- =DESCRIPTION= :: + #+cindex: @samp{DESCRIPTION}, keyword + #+vindex: org-latex-hyperref-template + #+vindex: org-latex-title-command + The document's description. The description along with author name, + keywords, and related file metadata are inserted in the output file + by the hyperref package. See ~org-latex-hyperref-template~ for + customizing metadata items. See ~org-latex-title-command~ for + typesetting description into the document's front matter. Use + multiple =DESCRIPTION= keywords for long descriptions. + +- =LANGUAGE= :: + #+cindex: @samp{LANGUAGE}, keyword + #+vindex: org-latex-packages-alist + In order to be effective, the =babel= or =polyglossia= + packages---according to the LaTeX compiler used---must be loaded + with the appropriate language as argument. This can be accomplished + by modifying the ~org-latex-packages-alist~ variable, e.g., with the + following snippet: + + #+begin_src emacs-lisp + (add-to-list 'org-latex-packages-alist + '("AUTO" "babel" t ("pdflatex"))) + (add-to-list 'org-latex-packages-alist + '("AUTO" "polyglossia" t ("xelatex" "lualatex"))) + #+end_src + +- =LATEX_CLASS= :: + + #+cindex: @samp{LATEX_CLASS}, keyword + #+vindex: org-latex-default-class + #+vindex: org-latex-classes + This is LaTeX document class, such as /article/, /report/, /book/, + and so on, which contain predefined preamble and headline level + mapping that the LaTeX export back-end needs. The back-end reads + the default class name from the ~org-latex-default-class~ variable. + Org has /article/ as the default class. A valid default class must + be an element of ~org-latex-classes~. + +- =LATEX_CLASS_OPTIONS= :: + + #+cindex: @samp{LATEX_CLASS_OPTIONS}, keyword + Options the LaTeX export back-end uses when calling the LaTeX + document class. + +- =LATEX_COMPILER= :: + + #+cindex: @samp{LATEX_COMPILER}, keyword + #+vindex: org-latex-compiler + The compiler, such as =pdflatex=, =xelatex=, =lualatex=, for + producing the PDF. See ~org-latex-compiler~. + +- =LATEX_HEADER=, =LATEX_HEADER_EXTRA= :: + + #+cindex: @samp{LATEX_HEADER}, keyword + #+cindex: @samp{LATEX_HEADER_EXTRA}, keyword + #+vindex: org-latex-classes + Arbitrary lines to add to the document's preamble, before the + hyperref settings. See ~org-latex-classes~ for adjusting the + structure and order of the LaTeX headers. + +- =KEYWORDS= :: + + #+cindex: @samp{KEYWORDS}, keyword + #+vindex: org-latex-hyperref-template + #+vindex: org-latex-title-command + The keywords for the document. The description along with author + name, keywords, and related file metadata are inserted in the output + file by the hyperref package. See ~org-latex-hyperref-template~ for + customizing metadata items. See ~org-latex-title-command~ for + typesetting description into the document's front matter. Use + multiple =KEYWORDS= lines if necessary. + +- =SUBTITLE= :: + + #+cindex: @samp{SUBTITLE}, keyword + #+vindex: org-latex-subtitle-separate + #+vindex: org-latex-subtitle-format + The document's subtitle. It is typeset as per + ~org-latex-subtitle-format~. If ~org-latex-subtitle-separate~ is + non-~nil~, it is typed outside of the ~\title~ macro. See + ~org-latex-hyperref-template~ for customizing metadata items. See + ~org-latex-title-command~ for typesetting description into the + document's front matter. + +The following sections have further details. + +*** LaTeX header and sectioning structure +:PROPERTIES: +:DESCRIPTION: Setting up the export file structure. +:ALT_TITLE: LaTeX header and sectioning +:END: +#+cindex: @LaTeX{} class +#+cindex: @LaTeX{} sectioning structure +#+cindex: @LaTeX{} header +#+cindex: header, for @LaTeX{} files +#+cindex: sectioning structure, for @LaTeX{} export + +The LaTeX export back-end converts the first three of Org's outline +levels into LaTeX headlines. The remaining Org levels are exported as +lists. To change this globally for the cut-off point between levels +and lists, (see [[*Export Settings]]). + +By default, the LaTeX export back-end uses the /article/ class. + +#+vindex: org-latex-default-class +#+vindex: org-latex-classes +#+vindex: org-latex-default-packages-alist +#+vindex: org-latex-packages-alist +To change the default class globally, edit ~org-latex-default-class~. +To change the default class locally in an Org file, add option lines +=#+LATEX_CLASS: myclass=. To change the default class for just a part +of the Org file, set a sub-tree property, =EXPORT_LATEX_CLASS=. The +class name entered here must be valid member of ~org-latex-classes~. +This variable defines a header template for each class into which the +exporter splices the values of ~org-latex-default-packages-alist~ and +~org-latex-packages-alist~. Use the same three variables to define +custom sectioning or custom classes. + +#+cindex: @samp{LATEX_CLASS}, keyword +#+cindex: @samp{LATEX_CLASS_OPTIONS}, keyword +#+cindex: @samp{EXPORT_LATEX_CLASS}, property +#+cindex: @samp{EXPORT_LATEX_CLASS_OPTIONS}, property +The LaTeX export back-end sends the =LATEX_CLASS_OPTIONS= keyword and +=EXPORT_LATEX_CLASS_OPTIONS= property as options to the LaTeX +~\documentclass~ macro. The options and the syntax for specifying +them, including enclosing them in square brackets, follow LaTeX +conventions. + +: #+LATEX_CLASS_OPTIONS: [a4paper,11pt,twoside,twocolumn] + +#+cindex: @samp{LATEX_HEADER}, keyword +#+cindex: @samp{LATEX_HEADER_EXTRA}, keyword +The LaTeX export back-end appends values from =LATEX_HEADER= and +=LATEX_HEADER_EXTRA= keywords to the LaTeX header. The docstring for +~org-latex-classes~ explains in more detail. Also note that LaTeX +export back-end does not append =LATEX_HEADER_EXTRA= to the header +when previewing LaTeX snippets (see [[*Previewing LaTeX fragments]]). + +A sample Org file with the above headers: + +#+begin_example +,#+LATEX_CLASS: article +,#+LATEX_CLASS_OPTIONS: [a4paper] +,#+LATEX_HEADER: \usepackage{xyz} + +,* Headline 1 + some text +,* Headline 2 + some more text +#+end_example + +*** Quoting LaTeX code +:PROPERTIES: +:DESCRIPTION: Incorporating literal @LaTeX{} code. +:END: + +The LaTeX export back-end can insert any arbitrary LaTeX code, see +[[*Embedded LaTeX]]. There are three ways to embed such code in the Org +file and they all use different quoting syntax. + +#+cindex: inline, in @LaTeX{} export +Inserting in-line quoted with @ symbols: + +: Code embedded in-line @@latex:any arbitrary LaTeX code@@ in a paragraph. + +#+cindex: @samp{LATEX}, keyword +Inserting as one or more keyword lines in the Org file: + +: #+LATEX: any arbitrary LaTeX code + +#+cindex: @samp{BEGIN_EXPORT latex} +Inserting as an export block in the Org file, where the back-end +exports any code between begin and end markers: + +#+begin_example +,#+BEGIN_EXPORT latex + any arbitrary LaTeX code +,#+END_EXPORT +#+end_example + +*** Tables in LaTeX export +:PROPERTIES: +:DESCRIPTION: Options for exporting tables to @LaTeX{}. +:END: +#+cindex: tables, in @LaTeX{} export + +The LaTeX export back-end can pass several LaTeX attributes for table +contents and layout. Besides specifying a label (see [[*Internal Links]]) +and a caption (see [[*Captions]]), the other valid LaTeX attributes +include: + +#+attr_texinfo: :sep , +- =:mode= :: + + #+vindex: org-latex-default-table-mode + The LaTeX export back-end wraps the table differently depending on + the mode for accurate rendering of math symbols. Mode is either + =table=, =math=, =inline-math= or =verbatim=. + + For =math= or =inline-math= mode, LaTeX export back-end wraps the + table in a math environment, but every cell in it is exported as-is. + The LaTeX export back-end determines the default mode from + ~org-latex-default-table-mode~. The LaTeX export back-end merges + contiguous tables in the same mode into a single environment. + +- =:environment= :: + + #+vindex: org-latex-default-table-environment + Set the default LaTeX table environment for the LaTeX export + back-end to use when exporting Org tables. Common LaTeX table + environments are provided by these packages: tabularx, longtable, + array, tabu, and bmatrix. For packages, such as tabularx and tabu, + or any newer replacements, include them in the + ~org-latex-packages-alist~ variable so the LaTeX export back-end can + insert the appropriate load package headers in the converted LaTeX + file. Look in the docstring for the ~org-latex-packages-alist~ + variable for configuring these packages for LaTeX snippet previews, + if any. + +- =:caption= :: + + Use =CAPTION= keyword to set a simple caption for a table (see + [[*Captions]]). For custom captions, use =:caption= attribute, which + accepts raw LaTeX code. =:caption= value overrides =CAPTION= value. + +- =:float=, =:placement= :: + + The table environments by default are not floats in LaTeX. To make + them floating objects use =:float= with one of the following + options: =sideways=, =multicolumn=, =t=, and =nil=. + + LaTeX floats can also have additional layout =:placement= + attributes. These are the usual =[h t b p ! H]= permissions + specified in square brackets. Note that for =:float sideways= + tables, the LaTeX export back-end ignores =:placement= attributes. + +- =:align=, =:font=, =:width= :: + + The LaTeX export back-end uses these attributes for regular tables + to set their alignments, fonts, and widths. + +- =:spread= :: + + When =:spread= is non-~nil~, the LaTeX export back-end spreads or + shrinks the table by the =:width= for tabu and longtabu + environments. =:spread= has no effect if =:width= is not set. + +- =:booktabs=, =:center=, =:rmlines= :: + + #+vindex: org-latex-tables-booktabs + #+vindex: org-latex-tables-centered + All three commands are toggles. =:booktabs= brings in modern + typesetting enhancements to regular tables. The booktabs package + has to be loaded through ~org-latex-packages-alist~. =:center= is + for centering the table. =:rmlines= removes all but the very first + horizontal line made of ASCII characters from "table.el" tables + only. + +- =:math-prefix=, =:math-suffix=, =:math-arguments= :: + + The LaTeX export back-end inserts =:math-prefix= string value in + a math environment before the table. The LaTeX export back-end + inserts =:math-suffix= string value in a math environment after the + table. The LaTeX export back-end inserts =:math-arguments= string + value between the macro name and the table's contents. + =:math-arguments= comes in use for matrix macros that require more + than one argument, such as =qbordermatrix=. + +LaTeX table attributes help formatting tables for a wide range of +situations, such as matrix product or spanning multiple pages: + +#+begin_example +,#+ATTR_LATEX: :environment longtable :align l|lp{3cm}r|l +| ... | ... | +| ... | ... | + +,#+ATTR_LATEX: :mode math :environment bmatrix :math-suffix \times +| a | b | +| c | d | +,#+ATTR_LATEX: :mode math :environment bmatrix +| 1 | 2 | +| 3 | 4 | +#+end_example + +Set the caption with the LaTeX command +=\bicaption{HeadingA}{HeadingB}=: + +#+begin_example +,#+ATTR_LATEX: :caption \bicaption{HeadingA}{HeadingB} +| ... | ... | +| ... | ... | +#+end_example + +*** Images in LaTeX export +:PROPERTIES: +:DESCRIPTION: How to insert figures into @LaTeX{} output. +:END: +#+cindex: images, inline in LaTeX +#+cindex: inlining images in LaTeX +#+cindex: @samp{ATTR_LATEX}, keyword + +The LaTeX export back-end processes image links in Org files that do +not have descriptions, such as these links =[[file:img.jpg]]= or +=[[./img.jpg]]=, as direct image insertions in the final PDF output. In +the PDF, they are no longer links but actual images embedded on the +page. The LaTeX export back-end uses =\includegraphics= macro to +insert the image. But for TikZ (http://sourceforge.net/projects/pgf/) +images, the back-end uses an ~\input~ macro wrapped within +a ~tikzpicture~ environment. + +For specifying image =:width=, =:height=, =:scale= and other =:options=, +use this syntax: + +#+begin_example +,#+ATTR_LATEX: :width 5cm :options angle=90 +[[./img/sed-hr4049.pdf]] +#+end_example + +A =:scale= attribute overrides both =:width= and =:height= attributes. + +For custom commands for captions, use the =:caption= attribute. It +overrides the default =#+CAPTION= value: + +#+begin_example +,#+ATTR_LATEX: :caption \bicaption{HeadingA}{HeadingB} +[[./img/sed-hr4049.pdf]] +#+end_example + +When captions follow the method as described in [[*Captions]], the LaTeX +export back-end wraps the picture in a floating =figure= environment. +To float an image without specifying a caption, set the =:float= +attribute to one of the following: + +- =t= :: + + For a standard =figure= environment; used by default whenever an + image has a caption. + +- =multicolumn= :: + + To span the image across multiple columns of a page; the back-end + wraps the image in a =figure*= environment. + +- =wrap= :: + + For text to flow around the image on the right; the figure occupies + the left half of the page. + +- =sideways= :: + + For a new page with the image sideways, rotated ninety degrees, in + a =sidewaysfigure= environment; overrides =:placement= setting. + +- =nil= :: + + To avoid a =:float= even if using a caption. + +Use the =placement= attribute to modify a floating environment's +placement. + +#+begin_example +,#+ATTR_LATEX: :float wrap :width 0.38\textwidth :placement {r}{0.4\textwidth} +[[./img/hst.png]] +#+end_example + +#+vindex: org-latex-images-centered +#+cindex: center image in LaTeX export +#+cindex: image, centering in LaTeX export +The LaTeX export back-end centers all images by default. Setting +=:center= to =nil= disables centering. To disable centering globally, +set ~org-latex-images-centered~ to =t=. + +Set the =:comment-include= attribute to non-~nil~ value for the LaTeX +export back-end to comment out the =\includegraphics= macro. + +*** Plain lists in LaTeX export +:PROPERTIES: +:DESCRIPTION: Attributes specific to lists. +:END: + +#+cindex: plain lists, in @LaTeX{} export +#+cindex: @samp{ATTR_LATEX}, keyword +The LaTeX export back-end accepts the =environment= and =options= +attributes for plain lists. Both attributes work together for +customizing lists, as shown in the examples: + +#+begin_example +,#+LATEX_HEADER: \usepackage[inline]{enumitem} +Some ways to say "Hello": +,#+ATTR_LATEX: :environment itemize* +,#+ATTR_LATEX: :options [label={}, itemjoin={,}, itemjoin*={, and}] +- Hola +- Bonjour +- Guten Tag. +#+end_example + +Since LaTeX supports only four levels of nesting for lists, use an +external package, such as =enumitem= in LaTeX, for levels deeper than +four: + +#+begin_example +,#+LATEX_HEADER: \usepackage{enumitem} +,#+LATEX_HEADER: \renewlist{itemize}{itemize}{9} +,#+LATEX_HEADER: \setlist[itemize]{label=$\circ$} +- One + - Two + - Three + - Four + - Five +#+end_example + +*** Source blocks in LaTeX export +:PROPERTIES: +:DESCRIPTION: Attributes specific to source code blocks. +:END: +#+cindex: source blocks, in @LaTeX{} export +#+cindex: @samp{ATTR_LATEX}, keyword + +The LaTeX export back-end can make source code blocks into floating +objects through the attributes =:float= and =:options=. For =:float=: + +- =t= :: + + Makes a source block float; by default floats any source block with + a caption. + +- =multicolumn= :: + + Spans the source block across multiple columns of a page. + +- =nil= :: + + Avoids a =:float= even if using a caption; useful for source code + blocks that may not fit on a page. + +#+begin_example +,#+ATTR_LATEX: :float nil +,#+BEGIN_SRC emacs-lisp + Lisp code that may not fit in a single page. +,#+END_SRC +#+end_example + +#+vindex: org-latex-listings-options +#+vindex: org-latex-minted-options +The LaTeX export back-end passes string values in =:options= to LaTeX +packages for customization of that specific source block. In the +example below, the =:options= are set for Minted. Minted is a source +code highlighting LaTeX package with many configurable options. + +#+begin_example +,#+ATTR_LATEX: :options commentstyle=\bfseries +,#+BEGIN_SRC emacs-lisp + (defun Fib (n) + (if (< n 2) n (+ (Fib (- n 1)) (Fib (- n 2))))) +,#+END_SRC +#+end_example + +To apply similar configuration options for all source blocks in +a file, use the ~org-latex-listings-options~ and +~org-latex-minted-options~ variables. + +*** Example blocks in LaTeX export +:PROPERTIES: +:DESCRIPTION: Attributes specific to example blocks. +:END: +#+cindex: example blocks, in @LaTeX{} export +#+cindex: verbatim blocks, in @LaTeX{} export +#+cindex: @samp{ATTR_LATEX}, keyword + +The LaTeX export back-end wraps the contents of example blocks in +a =verbatim= environment. To change this behavior to use another +environment globally, specify an appropriate export filter (see +[[*Advanced Export Configuration]]). To change this behavior to use +another environment for each block, use the =:environment= parameter +to specify a custom environment. + +#+begin_example +,#+ATTR_LATEX: :environment myverbatim +,#+BEGIN_EXAMPLE + This sentence is false. +,#+END_EXAMPLE +#+end_example + +*** Special blocks in LaTeX export +:PROPERTIES: +:DESCRIPTION: Attributes specific to special blocks. +:END: + +#+cindex: special blocks, in @LaTeX{} export +#+cindex: abstract, in @LaTeX{} export +#+cindex: proof, in @LaTeX{} export +#+cindex: @samp{ATTR_LATEX}, keyword + +For other special blocks in the Org file, the LaTeX export back-end +makes a special environment of the same name. The back-end also takes +=:options=, if any, and appends as-is to that environment's opening +string. For example: + +#+begin_example +,#+BEGIN_abstract + We demonstrate how to solve the Syracuse problem. +,#+END_abstract + +,#+ATTR_LATEX: :options [Proof of important theorem] +,#+BEGIN_proof + ... + Therefore, any even number greater than 2 is the sum of two primes. +,#+END_proof +#+end_example + +#+texinfo: @noindent +exports to + +#+begin_example +\begin{abstract} + We demonstrate how to solve the Syracuse problem. +\end{abstract} + +\begin{proof}[Proof of important theorem] + ... + Therefore, any even number greater than 2 is the sum of two primes. +\end{proof} +#+end_example + +If you need to insert a specific caption command, use =:caption= +attribute. It overrides standard =CAPTION= value, if any. For +example: + +#+begin_example +,#+ATTR_LATEX: :caption \MyCaption{HeadingA} +,#+BEGIN_proof + ... +,#+END_proof +#+end_example + +*** Horizontal rules in LaTeX export +:PROPERTIES: +:DESCRIPTION: Attributes specific to horizontal rules. +:END: +#+cindex: horizontal rules, in @LaTeX{} export +#+cindex: @samp{ATTR_LATEX}, keyword + +The LaTeX export back-end converts horizontal rules by the specified +=:width= and =:thickness= attributes. For example: + +#+begin_example +,#+ATTR_LATEX: :width .6\textwidth :thickness 0.8pt +----- +#+end_example + +** Markdown Export +:PROPERTIES: +:DESCRIPTION: Exporting to Markdown. +:END: +#+cindex: Markdown export + +The Markdown export back-end, "md", converts an Org file to Markdown +format, as defined at http://daringfireball.net/projects/markdown/. + +Since it is built on top of the HTML back-end (see [[*HTML Export]]), it +converts every Org construct not defined in Markdown syntax, such as +tables, to HTML. + +*** Markdown export commands +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +- {{{kbd(C-c C-e m m)}}} (~org-md-export-to-markdown~) :: + + #+kindex: C-c C-c m m + #+findex: org-md-export-to-markdown + Export to a text file with Markdown syntax. For =myfile.org=, Org + exports to =myfile.md=, overwritten without warning. + +- {{{kbd(C-c C-e m M)}}} (~org-md-export-as-markdown~) :: + + #+kindex: C-c C-c m M + #+findex: org-md-export-as-markdown + Export to a temporary buffer. Does not create a file. + +- {{{kbd(C-c C-e m o)}}} :: + + #+kindex: C-c C-e m o + Export as a text file with Markdown syntax, then open it. + +*** Header and sectioning structure +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+vindex: org-md-headline-style +Based on ~org-md-headline-style~, Markdown export can generate +headlines of both /atx/ and /setext/ types. /atx/ limits headline +levels to two whereas /setext/ limits headline levels to six. Beyond +these limits, the export back-end converts headlines to lists. To set +a limit to a level before the absolute limit (see [[*Export Settings]]). + +** OpenDocument Text Export +:PROPERTIES: +:DESCRIPTION: Exporting to OpenDocument Text. +:END: +#+cindex: ODT +#+cindex: OpenDocument +#+cindex: export, OpenDocument +#+cindex: LibreOffice + +The ODT export back-end handles creating of OpenDocument Text (ODT) +format. Documents created by this exporter use the +{{{cite(OpenDocument-v1.2 specification)}}}[fn:134] and are compatible +with LibreOffice 3.4. + +*** Pre-requisites for ODT export +:PROPERTIES: +:DESCRIPTION: Required packages. +:END: +#+cindex: zip + +The ODT export back-end relies on the zip program to create the final +compressed ODT output. Check if =zip= is locally available and +executable. Without it, export cannot finish. + +*** ODT export commands +:PROPERTIES: +:DESCRIPTION: Invoking export. +:END: + +- {{{kbd(C-c C-e o o)}}} (~org-export-to-odt~) :: + + #+kindex: C-c C-e o o + #+findex: org-export-to-odt + Export as OpenDocument Text file. + + #+cindex: @samp{EXPORT_FILE_NAME}, property + #+vindex: org-odt-preferred-output-format + + If ~org-odt-preferred-output-format~ is specified, the ODT export + back-end automatically converts the exported file to that format. + + For =myfile.org=, Org exports to =myfile.odt=, overwriting without + warning. The ODT export back-end exports a region only if a region + was active. + + If the selected region is a single tree, the ODT export back-end + makes the tree head the document title. Incidentally, {{{kbd(C-c + @)}}} selects the current sub-tree. If the tree head entry has, or + inherits, an =EXPORT_FILE_NAME= property, the ODT export back-end + uses that for file name. + +- {{{kbd(C-c C-e o O)}}} :: + + #+kindex: C-c C-e o O + Export as an OpenDocument Text file and open the resulting file. + + #+vindex: org-export-odt-preferred-output-format + If ~org-export-odt-preferred-output-format~ is specified, open the + converted file instead. See [[*Automatically exporting to other + formats]]. + +*** ODT specific export settings +:PROPERTIES: +:DESCRIPTION: Configuration options. +:END: + +The ODT export back-end has several additional keywords for +customizing ODT output. Setting these keywords works similar to the +general options (see [[*Export Settings]]). + +- =DESCRIPTION= :: + + #+cindex: @samp{DESCRIPTION}, keyword + This is the document's description, which the ODT export back-end + inserts as document metadata. For long descriptions, use multiple + lines, prefixed with =DESCRIPTION=. + +- =KEYWORDS= :: + + #+cindex: @samp{KEYWORDS}, keyword + The keywords for the document. The ODT export back-end inserts the + description along with author name, keywords, and related file + metadata as metadata in the output file. Use multiple =KEYWORDS= if + necessary. + +- =ODT_STYLES_FILE= :: + + #+cindex: @samp{ODT_STYLES_FILE}, keyword + #+vindex: org-odt-styles-file + The ODT export back-end uses the ~org-odt-styles-file~ by default. + See [[*Applying custom styles]] for details. + +- =SUBTITLE= :: + + #+cindex: @samp{SUBTITLE}, keyword + The document subtitle. + +*** Extending ODT export +:PROPERTIES: +:DESCRIPTION: Producing DOC, PDF files. +:END: + +The ODT export back-end can produce documents in other formats besides +ODT using a specialized ODT converter process. Its common interface +works with popular converters to produce formats such as =doc=, or +convert a document from one format, say =csv=, to another format, say +=xls=. + +#+cindex: @file{unoconv} +#+vindex: org-odt-convert-process +Customize ~org-odt-convert-process~ variable to point to =unoconv=, +which is the ODT's preferred converter. Working installations of +LibreOffice would already have =unoconv= installed. Alternatively, +other converters may be substituted here. See [[*Configuring +a document converter]]. + +**** Automatically exporting to other formats +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+vindex: org-odt-preferred-output-format +If ODT format is just an intermediate step to get to other formats, +such as =doc=, =docx=, =rtf=, or =pdf=, etc., then extend the ODT +export back-end to directly produce that format. Specify the final +format in the ~org-odt-preferred-output-format~ variable. This is one +way to extend (see [[*ODT export commands]]). + +**** Converting between document formats +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +The Org export back-end is made to be inter-operable with a wide range +of text document format converters. Newer generation converters, such +as LibreOffice and Pandoc, can handle hundreds of formats at once. +Org provides a consistent interaction with whatever converter is +installed. Here are some generic commands: + +- {{{kbd(M-x org-odt-convert)}}} :: + + #+findex: org-odt-convert + Convert an existing document from one format to another. With + a prefix argument, opens the newly produced file. + +*** Applying custom styles +:PROPERTIES: +:DESCRIPTION: Styling the output. +:END: +#+cindex: styles, custom +#+cindex: template, custom + +The ODT export back-end comes with many OpenDocument styles (see +[[*Working with OpenDocument style files]]). To expand or further +customize these built-in style sheets, either edit the style sheets +directly or generate them using an application such as LibreOffice. +The example here shows creating a style using LibreOffice. + +**** Applying custom styles: the easy way +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +1. Create a sample =example.org= file with settings as shown below, + and export it to ODT format. + + : #+OPTIONS: H:10 num:t + +2. Open the above =example.odt= using LibreOffice. Use the /Stylist/ + to locate the target styles, which typically have the "Org" prefix. + Open one, modify, and save as either OpenDocument Text (ODT) or + OpenDocument Template (OTT) file. + +3. + #+vindex: org-odt-styles-file + Customize the variable ~org-odt-styles-file~ and point it to the + newly created file. For additional configuration options, see + [[x-overriding-factory-styles][Overriding factory styles]]. + + #+cindex: @samp{ODT_STYLES_FILE}, keyword + To apply an ODT style to a particular file, use the + =ODT_STYLES_FILE= keyword as shown in the example below: + + : #+ODT_STYLES_FILE: "/path/to/example.ott" + + #+texinfo: @noindent + or + + : #+ODT_STYLES_FILE: ("/path/to/file.ott" ("styles.xml" "image/hdr.png")) + +**** Using third-party styles and templates +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +The ODT export back-end relies on many templates and style names. +Using third-party styles and templates can lead to mismatches. +Templates derived from built in ODT templates and styles seem to have +fewer problems. + +*** Links in ODT export +:PROPERTIES: +:DESCRIPTION: Handling and formatting links. +:END: +#+cindex: links, in ODT export + +ODT exporter creates native cross-references for internal links. It +creates Internet-style links for all other links. + +A link with no description and pointing to a regular, un-itemized, +outline heading is replaced with a cross-reference and section number +of the heading. + +A =\ref{label}=-style reference to an image, table etc., is replaced +with a cross-reference and sequence number of the labeled entity. See +[[*Labels and captions in ODT export]]. + +*** Tables in ODT export +:PROPERTIES: +:DESCRIPTION: Org tables conversions. +:END: + +#+cindex: tables, in ODT export + +The ODT export back-end handles native Org mode tables (see [[*Tables]]) +and simple =table.el= tables. Complex =table.el= tables having column +or row spans are not supported. Such tables are stripped from the +exported document. + +By default, the ODT export back-end exports a table with top and +bottom frames and with ruled lines separating row and column groups +(see [[*Column Groups]]). All tables are typeset to occupy the same +width. The ODT export back-end honors any table alignments and +relative widths for columns (see [[*Column Width and Alignment]]). + +Note that the ODT export back-end interprets column widths as weighted +ratios, the default weight being 1. + +#+cindex: @samp{ATTR_ODT}, keyword +Specifying =:rel-width= property on an =ATTR_ODT= line controls the +width of the table. For example: + +#+begin_example +,#+ATTR_ODT: :rel-width 50 +| Area/Month | Jan | Feb | Mar | Sum | +|---------------+-------+-------+-------+-------| +| / | < | | | < | +| | | | | | +| North America | 1 | 21 | 926 | 948 | +| Middle East | 6 | 75 | 844 | 925 | +| Asia Pacific | 9 | 27 | 790 | 826 | +|---------------+-------+-------+-------+-------| +| Sum | 16 | 123 | 2560 | 2699 | +#+end_example + +On export, the above table takes 50% of text width area. The exporter +sizes the columns in the ratio: 13:5:5:5:6. The first column is +left-aligned and rest of the columns, right-aligned. Vertical rules +separate the header and the last column. Horizontal rules separate +the header and the last row. + +For even more customization, create custom table styles and associate +them with a table using the =ATTR_ODT= keyword. See [[*Customizing +tables in ODT export]]. + +*** Images in ODT export +:PROPERTIES: +:DESCRIPTION: Inserting images. +:END: +#+cindex: images, embedding in ODT +#+cindex: embedding images in ODT + +**** Embedding images +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +The ODT export back-end processes image links in Org files that do not +have descriptions, such as these links =[[file:img.jpg]]= or =[[./img.jpg]]=, +as direct image insertions in the final output. Either of these +examples works: + +: [[file:img.png]] + +: [[./img.png]] + +**** Embedding clickable images +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +For clickable images, provide a link whose description is another link +to an image file. For example, to embed an image +=org-mode-unicorn.png= which when clicked jumps to https://orgmode.org +website, do the following + +: [[https://orgmode.org][./org-mode-unicorn.png]] + +**** Sizing and scaling of embedded images +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: @samp{ATTR_ODT}, keyword + +Control the size and scale of the embedded images with the =ATTR_ODT= +attribute. + +#+cindex: identify, ImageMagick +#+vindex: org-odt-pixels-per-inch +The ODT export back-end starts with establishing the size of the image +in the final document. The dimensions of this size are measured in +centimeters. The back-end then queries the image file for its +dimensions measured in pixels. For this measurement, the back-end +relies on ImageMagick's identify program or Emacs ~create-image~ and +~image-size~ API. ImageMagick is the preferred choice for large file +sizes or frequent batch operations. The back-end then converts the +pixel dimensions using ~org-odt-pixels-per-inch~ into the familiar 72 +dpi or 96 dpi. The default value for this is in +~display-pixels-per-inch~, which can be tweaked for better results +based on the capabilities of the output device. Here are some common +image scaling operations: + +- Explicitly size the image :: + + To embed =img.png= as a 10 cm x 10 cm image, do the following: + + #+begin_example + ,#+ATTR_ODT: :width 10 :height 10 + [[./img.png]] + #+end_example + +- Scale the image :: + + To embed =img.png= at half its size, do the following: + + #+begin_example + ,#+ATTR_ODT: :scale 0.5 + [[./img.png]] + #+end_example + +- Scale the image to a specific width :: + + To embed =img.png= with a width of 10 cm while retaining the + original height:width ratio, do the following: + + #+begin_example + ,#+ATTR_ODT: :width 10 + [[./img.png]] + #+end_example + +- Scale the image to a specific height :: + + To embed =img.png= with a height of 10 cm while retaining the + original height:width ratio, do the following: + + #+begin_example + ,#+ATTR_ODT: :height 10 + [[./img.png]] + #+end_example + +**** Anchoring of images +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: @samp{ATTR_ODT}, keyword +The ODT export back-end can anchor images to =as-char=, =paragraph=, +or =page=. Set the preferred anchor using the =:anchor= property of +the =ATTR_ODT= line. + +To create an image that is anchored to a page: + +#+begin_example +,#+ATTR_ODT: :anchor page +[[./img.png]] +#+end_example + +*** Math formatting in ODT export +:PROPERTIES: +:DESCRIPTION: Formatting @LaTeX{} fragments. +:END: + +The ODT exporter has special support for handling math. + +**** LaTeX math snippets +:PROPERTIES: +:DESCRIPTION: Embedding in @LaTeX{} format. +:END: + +LaTeX math snippets (see [[*LaTeX fragments]]) can be embedded in the ODT +document in one of the following ways: + +- MathML :: + + #+cindex: MathML + Add this line to the Org file. This option is activated on + a per-file basis. + + : #+OPTIONS: tex:t + + With this option, LaTeX fragments are first converted into MathML + fragments using an external LaTeX-to-MathML converter program. The + resulting MathML fragments are then embedded as an OpenDocument + Formula in the exported document. + + #+vindex: org-latex-to-mathml-convert-command + #+vindex: org-latex-to-mathml-jar-file + You can specify the LaTeX-to-MathML converter by customizing the + variables ~org-latex-to-mathml-convert-command~ and + ~org-latex-to-mathml-jar-file~. + + If you prefer to use MathToWeb[fn:135] as your converter, you can + configure the above variables as shown below. + + #+begin_src emacs-lisp + (setq org-latex-to-mathml-convert-command + "java -jar %j -unicode -force -df %o %I" + org-latex-to-mathml-jar-file + "/path/to/mathtoweb.jar") + #+end_src + + #+texinfo: @noindent + or, to use LaTeX​ML[fn:136] instead, + + #+begin_src emacs-lisp + (setq org-latex-to-mathml-convert-command + "latexmlmath \"%i\" --presentationmathml=%o") + #+end_src + + To quickly verify the reliability of the LaTeX-to-MathML + converter, use the following commands: + + - {{{kbd(M-x org-export-as-odf)}}} :: + + Convert a LaTeX math snippet to an OpenDocument formula (=.odf=) + file. + + - {{{kbd(M-x org-export-as-odf-and-open)}}} :: + + Convert a LaTeX math snippet to an OpenDocument formula (=.odf=) + file and open the formula file with the system-registered + application. + +- PNG images :: + + #+cindex: dvipng + #+cindex: dvisvgm + #+cindex: ImageMagick + Add this line to the Org file. This option is activated on + a per-file basis. + + : #+OPTIONS: tex:dvipng + + : #+OPTIONS: tex:dvisvgm + + #+texinfo: @noindent + or + + : #+OPTIONS: tex:imagemagick + + Under this option, LaTeX fragments are processed into PNG or SVG + images and the resulting images are embedded in the exported + document. This method requires dvipng program, dvisvgm or + ImageMagick programs. + +**** MathML and OpenDocument formula files +:PROPERTIES: +:DESCRIPTION: Embedding in native format. +:END: + +When embedding LaTeX math snippets in ODT documents is not reliable, +there is one more option to try. Embed an equation by linking to its +MathML (=.mml=) source or its OpenDocument formula (=.odf=) file as +shown below: + +: [[./equation.mml]] + +#+texinfo: @noindent +or + +: [[./equation.odf]] + +*** Labels and captions in ODT export +:PROPERTIES: +:DESCRIPTION: Rendering objects. +:END: + +ODT format handles labeling and captioning of objects based on their +types. Inline images, tables, LaTeX fragments, and Math formulas are +numbered and captioned separately. Each object also gets a unique +sequence number based on its order of first appearance in the Org +file. Each category has its own sequence. A caption is just a label +applied to these objects. + +#+begin_example +,#+CAPTION: Bell curve +,#+NAME: fig:SED-HR4049 +[[./img/a.png]] +#+end_example + +When rendered, it may show as follows in the exported document: + +: Figure 2: Bell curve + +#+vindex: org-odt-category-map-alist +To modify the category component of the caption, customize the option +~org-odt-category-map-alist~. For example, to tag embedded images +with the string "Illustration" instead of the default string "Figure", +use the following setting: + +#+begin_src emacs-lisp +(setq org-odt-category-map-alist + '(("__Figure__" "Illustration" "value" "Figure" org-odt--enumerable-image-p))) +#+end_src + +With the above modification, the previous example changes to: + +: Illustration 2: Bell curve + +*** Literal examples in ODT export +:PROPERTIES: +:DESCRIPTION: For source code and example blocks. +:END: + +The ODT export back-end supports literal examples (see [[*Literal +Examples]]) with full fontification. Internally, the ODT export +back-end relies on =htmlfontify.el= to generate the style definitions +needed for fancy listings. The auto-generated styles get =OrgSrc= +prefix and inherit colors from the faces used by Emacs Font Lock +library for that source language. + +#+vindex: org-odt-fontify-srcblocks +For custom fontification styles, customize the +~org-odt-create-custom-styles-for-srcblocks~ option. + +#+vindex: org-odt-create-custom-styles-for-srcblocks +To turn off fontification of literal examples, customize the +~org-odt-fontify-srcblocks~ option. + +*** Advanced topics in ODT export +:PROPERTIES: +:DESCRIPTION: For power users. +:END: + +The ODT export back-end has extensive features useful for power users +and frequent uses of ODT formats. + +**** Configuring a document converter +:PROPERTIES: +:DESCRIPTION: Registering a document converter. +:UNNUMBERED: notoc +:END: +#+cindex: convert +#+cindex: doc, docx, rtf +#+cindex: converter + +The ODT export back-end works with popular converters with little or +no extra configuration. See [[*Extending ODT export]]. The following is +for unsupported converters or tweaking existing defaults. + +- Register the converter :: + + #+vindex: org-export-odt-convert-processes + Add the name of the converter to the ~org-odt-convert-processes~ + variable. Note that it also requires how the converter is invoked + on the command line. See the variable's docstring for details. + +- Configure its capabilities :: + + #+vindex: org-export-odt-convert-capabilities + Specify which formats the converter can handle by customizing the + variable ~org-odt-convert-capabilities~. Use the entry for the + default values in this variable for configuring the new converter. + Also see its docstring for details. + +- Choose the converter :: + + #+vindex: org-export-odt-convert-process + Select the newly added converter as the preferred one by customizing + the option ~org-odt-convert-process~. + +**** Working with OpenDocument style files +:PROPERTIES: +:DESCRIPTION: Exploring internals. +:UNNUMBERED: notoc +:END: +#+cindex: styles, custom +#+cindex: template, custom + +This section explores the internals of the ODT exporter; the means by which +it produces styled documents; the use of automatic and custom OpenDocument +styles. + +The ODT exporter relies on two files for generating its output. These +files are bundled with the distribution under the directory pointed to +by the variable ~org-odt-styles-dir~. The two files are: + +- =OrgOdtStyles.xml= <> :: + + This file contributes to the =styles.xml= file of the final ODT + document. This file gets modified for the following purposes: + + 1. To control outline numbering based on user settings; + + 2. To add styles generated by =htmlfontify.el= for fontification of + code blocks. + +- =OrgOdtContentTemplate.xml= <> :: + + This file contributes to the =content.xml= file of the final ODT + document. The contents of the Org outline are inserted between the + == ... == elements of this file. + + Apart from serving as a template file for the final =content.xml=, + the file serves the following purposes: + + 1. It contains automatic styles for formatting of tables which are + referenced by the exporter; + + 2. It contains == ... == + elements that control numbering of tables, images, equations, and + similar entities. + +<> The following two variables control +the location from where the ODT exporter picks up the custom styles +and content template files. Customize these variables to override the +factory styles used by the exporter. + +- ~org-odt-styles-file~ :: + + The ODT export back-end uses the file pointed to by this variable, + such as =styles.xml=, for the final output. It can take one of the + following values: + + - =FILE.xml= :: + + Use this file instead of the default =styles.xml= + + - =FILE.odt= or =FILE.ott= :: + + Use the =styles.xml= contained in the specified OpenDocument + Text or Template file + + - =FILE.odt= or =FILE.ott= and a subset of included files :: + + Use the =styles.xml= contained in the specified OpenDocument Text + or Template file. Additionally extract the specified member files + and embed those within the final ODT document. + + Use this option if the =styles.xml= file references additional + files like header and footer images. + + - ~nil~ :: + + Use the default =styles.xml=. + +- ~org-odt-content-template-file~ :: + + Use this variable to specify the blank =content.xml= used in the + final output. + +**** Creating one-off styles +:PROPERTIES: +:DESCRIPTION: Customizing styles, highlighting... +:UNNUMBERED: notoc +:END: + +The ODT export back-end can read embedded raw OpenDocument XML from +the Org file. Such direct formatting is useful for one-off instances. + +- Embedding ODT tags as part of regular text :: + + Enclose OpenDocument syntax in =@@odt:...@@= for inline markup. For + example, to highlight a region of text do the following: + + #+begin_example + @@odt:This is highlighted + text@@. But this is regular text. + #+end_example + + *Hint:* To see the above example in action, edit the =styles.xml= + (see [[x-orgodtstyles-xml][Factory styles]]) and add a custom /Highlight/ style as shown + below: + + #+begin_example + + + + #+end_example + +- Embedding a one-line OpenDocument XML :: + + #+cindex: @samp{ODT}, keyword + The ODT export back-end can read one-liner options with =#+ODT:= in + the Org file. For example, to force a page break: + + #+begin_example + ,#+ODT: + #+end_example + + *Hint:* To see the above example in action, edit your + =styles.xml= (see [[x-orgodtstyles-xml][Factory styles]]) and add a custom =PageBreak= + style as shown below. + + #+begin_example + + + + #+end_example + +- Embedding a block of OpenDocument XML :: + + The ODT export back-end can also read ODT export blocks for + OpenDocument XML. Such blocks use the =#+BEGIN_EXPORT odt= + ... =#+END_EXPORT= constructs. + + For example, to create a one-off paragraph that uses bold text, do + the following: + + #+begin_example + ,#+BEGIN_EXPORT odt + + This paragraph is specially formatted and uses bold text. + + ,#+END_EXPORT + #+end_example + +**** Customizing tables in ODT export +:PROPERTIES: +:DESCRIPTION: Defining table templates. +:UNNUMBERED: notoc +:END: +#+cindex: tables, in ODT export +#+cindex: @samp{ATTR_ODT}, keyword + +Override the default table format by specifying a custom table style +with the =#+ATTR_ODT= line. For a discussion on default formatting of +tables, see [[*Tables in ODT export]]. + +This feature closely mimics the way table templates are defined in the +OpenDocument-v1.2 specification[fn:137]. + +#+vindex: org-odt-table-styles +For quick preview of this feature, install the settings below and export the +table that follows: + +#+begin_src emacs-lisp +(setq org-export-odt-table-styles + (append org-export-odt-table-styles + '(("TableWithHeaderRowAndColumn" "Custom" + ((use-first-row-styles . t) + (use-first-column-styles . t))) + ("TableWithFirstRowandLastRow" "Custom" + ((use-first-row-styles . t) + (use-last-row-styles . t)))))) +#+end_src + +#+begin_example +,#+ATTR_ODT: :style TableWithHeaderRowAndColumn +| Name | Phone | Age | +| Peter | 1234 | 17 | +| Anna | 4321 | 25 | +#+end_example + +The example above used =Custom= template and installed two table +styles =TableWithHeaderRowAndColumn= and +=TableWithFirstRowandLastRow=. *Important:* The OpenDocument styles +needed for producing the above template were pre-defined. They are +available in the section marked =Custom Table Template= in +=OrgOdtContentTemplate.xml= (see [[x-orgodtcontenttemplate-xml][Factory styles]]). For adding new +templates, define new styles there. + +To use this feature proceed as follows: + +1. Create a table template[fn:138]. + + A table template is set of =table-cell= and =paragraph= styles for + each of the following table cell categories: + + - Body + - First column + - Last column + - First row + - Last row + - Even row + - Odd row + - Even column + - Odd Column + + The names for the above styles must be chosen based on the name of + the table template using a well-defined convention. + + The naming convention is better illustrated with an example. For + a table template with the name =Custom=, the needed style names are + listed in the following table. + + | Cell type | Cell style | Paragraph style | + |--------------+------------------------------+-----------------------------------| + | Body | =CustomTableCell= | =CustomTableParagraph= | + | First column | =CustomFirstColumnTableCell= | =CustomFirstColumnTableParagraph= | + | Last column | =CustomLastColumnTableCell= | =CustomLastColumnTableParagraph= | + | First row | =CustomFirstRowTableCell= | =CustomFirstRowTableParagraph= | + | Last row | =CustomLastRowTableCell= | =CustomLastRowTableParagraph= | + | Even row | =CustomEvenRowTableCell= | =CustomEvenRowTableParagraph= | + | Odd row | =CustomOddRowTableCell= | =CustomOddRowTableParagraph= | + | Even column | =CustomEvenColumnTableCell= | =CustomEvenColumnTableParagraph= | + | Odd column | =CustomOddColumnTableCell= | =CustomOddColumnTableParagraph= | + + To create a table template with the name =Custom=, define the above + styles in the == ... + == element of the content template file + (see [[x-orgodtcontenttemplate-xml][Factory styles]]). + +2. Define a table style[fn:139]. + + #+vindex: org-odt-table-styles + To define a table style, create an entry for the style in the + variable ~org-odt-table-styles~ and specify the following: + + - the name of the table template created in step (1), + - the set of cell styles in that template that are to be activated. + + For example, the entry below defines two different table styles + =TableWithHeaderRowAndColumn= and =TableWithFirstRowandLastRow= + based on the same template =Custom=. The styles achieve their + intended effect by selectively activating the individual cell + styles in that template. + + #+begin_src emacs-lisp + (setq org-export-odt-table-styles + (append org-export-odt-table-styles + '(("TableWithHeaderRowAndColumn" "Custom" + ((use-first-row-styles . t) + (use-first-column-styles . t))) + ("TableWithFirstRowandLastRow" "Custom" + ((use-first-row-styles . t) + (use-last-row-styles . t)))))) + #+end_src + +3. Associate a table with the table style. + + To do this, specify the table style created in step (2) as part of + the =ATTR_ODT= line as shown below. + + #+begin_example + ,#+ATTR_ODT: :style TableWithHeaderRowAndColumn + | Name | Phone | Age | + | Peter | 1234 | 17 | + | Anna | 4321 | 25 | + #+end_example + +**** Validating OpenDocument XML +:PROPERTIES: +:DESCRIPTION: Debugging corrupted OpenDocument files. +:UNNUMBERED: notoc +:END: + +Sometimes ODT format files may not open due to =.odt= file corruption. +To verify if such a file is corrupt, validate it against the +OpenDocument Relax NG Compact (RNC) syntax schema. But first the +=.odt= files have to be decompressed using =zip=. Note that =.odt= +files are ZIP archives: [[info:emacs::File Archives]]. The contents of +ODT files are in XML. For general help with validation---and +schema-sensitive editing---of XML files: [[info:nxml-mode::Introduction]]. + +#+vindex: org-export-odt-schema-dir +Customize ~org-odt-schema-dir~ to point to a directory with +OpenDocument RNC files and the needed schema-locating rules. The ODT +export back-end takes care of updating the +~rng-schema-locating-files~. + +** Org Export +:PROPERTIES: +:DESCRIPTION: Exporting to Org. +:END: + +#+cindex: Org export +/org/ export back-end creates a normalized version of the Org document +in current buffer. The exporter evaluates Babel code (see [[*Evaluating +Code Blocks]]) and removes content specific to other back-ends. + +*** Org export commands +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +- {{{kbd(C-c C-e O o)}}} (~org-org-export-to-org~) :: + + #+kindex: C-c C-e O o + #+findex: org-org-export-to-org + Export as an Org file with a =.org= extension. For =myfile.org=, + Org exports to =myfile.org.org=, overwriting without warning. + +- {{{kbd(C-c C-e O v)}}} (~~) :: + + #+kindex: C-c C-e O v + Export to an Org file, then open it. + +** Texinfo Export +:PROPERTIES: +:DESCRIPTION: Exporting to Texinfo. +:END: + +*** Texinfo export commands +:PROPERTIES: +:DESCRIPTION: Invoking commands. +:END: + +- {{{kbd(C-c C-e i t)}}} (~org-texinfo-export-to-texinfo~) :: + + #+kindex: C-c C-e i t + #+findex: org-texinfo-export-to-texinfo + Export as a Texinfo file with =.texi= extension. For =myfile.org=, + Org exports to =myfile.texi=, overwriting without warning. + +- {{{kbd(C-c C-e i i)}}} (~org-texinfo-export-to-info~) :: + + #+kindex: C-c C-e i i + #+findex: org-texinfo-export-to-info + #+vindex: org-texinfo-info-process + Export to Texinfo format first and then process it to make an Info + file. To generate other formats, such as DocBook, customize the + ~org-texinfo-info-process~ variable. + +*** Texinfo specific export settings +:PROPERTIES: +:DESCRIPTION: Setting the environment. +:END: + +The Texinfo export back-end has several additional keywords for +customizing Texinfo output. Setting these keywords works similar to +the general options (see [[*Export Settings]]). + +- =SUBTITLE= :: + + #+cindex: @samp{SUBTITLE}, keyword + The document subtitle. + +- =SUBAUTHOR= :: + + #+cindex: @samp{SUBAUTHOR}, keyword + Additional authors for the document. + +- =TEXINFO_FILENAME= :: + + #+cindex: @samp{TEXINFO_FILENAME}, keyword + The Texinfo filename. + +- =TEXINFO_CLASS= :: + + #+cindex: @samp{TEXINFO_CLASS}, keyword + #+vindex: org-texinfo-default-class + The default document class (~org-texinfo-default-class~), which must + be a member of ~org-texinfo-classes~. + +- =TEXINFO_HEADER= :: + + #+cindex: @samp{TEXINFO_HEADER}, keyword + Arbitrary lines inserted at the end of the header. + +- =TEXINFO_POST_HEADER= :: + + #+cindex: @samp{TEXINFO_POST_HEADER}, keyword + Arbitrary lines inserted after the end of the header. + +- =TEXINFO_DIR_CATEGORY= :: + + #+cindex: @samp{TEXINFO_DIR_CATEGORY}, keyword + The directory category of the document. + +- =TEXINFO_DIR_TITLE= :: + + #+cindex: @samp{TEXINFO_DIR_TITLE}, keyword + The directory title of the document. + +- =TEXINFO_DIR_DESC= :: + + #+cindex: @samp{TEXINFO_DIR_DESC}, keyword + The directory description of the document. + +- =TEXINFO_PRINTED_TITLE= :: + + #+cindex: @samp{TEXINFO_PRINTED_TITLE}, keyword + The printed title of the document. + +*** Texinfo file header +:PROPERTIES: +:DESCRIPTION: Generating the header. +:END: + +#+cindex: @samp{TEXINFO_FILENAME}, keyword +After creating the header for a Texinfo file, the Texinfo back-end +automatically generates a name and destination path for the Info file. +To override this default with a more sensible path and name, specify +the =TEXINFO_FILENAME= keyword. + +#+vindex: org-texinfo-coding-system +#+cindex: @samp{TEXINFO_HEADER}, keyword +Along with the output's file name, the Texinfo header also contains +language details (see [[*Export Settings]]) and encoding system as set in +the ~org-texinfo-coding-system~ variable. Insert =TEXINFO_HEADER= +keywords for each additional command in the header, for example: + +: #+TEXINFO_HEADER: @synindex + +#+cindex: @samp{TEXINFO_CLASS}, keyword +#+vindex: org-texinfo-classes +Instead of repeatedly installing the same set of commands, define +a class in ~org-texinfo-classes~ once, and then activate it in the +document by setting the =TEXINFO_CLASS= keyword to that class. + +*** Texinfo title and copyright page +:PROPERTIES: +:DESCRIPTION: Creating preamble pages. +:END: + +#+cindex: @samp{TEXINFO_PRINTED_TITLE}, keyword +The default template for hard copy output has a title page with +=TITLE= and =AUTHOR= keywords (see [[*Export Settings]]). To replace the +regular title with something different for the printed version, use +the =TEXINFO_PRINTED_TITLE= and =SUBTITLE= keywords. Both expect raw +Texinfo code for setting their values. + +#+cindex: @samp{SUBAUTHOR}, keyword +If one =AUTHOR= line is not sufficient, add multiple =SUBAUTHOR= +keywords. They have to be set in raw Texinfo code. + +#+begin_example +,#+AUTHOR: Jane Smith +,#+SUBAUTHOR: John Doe +,#+TEXINFO_PRINTED_TITLE: This Long Title@@inlinefmt{tex,@*} Is Broken in @TeX{} +#+end_example + +#+cindex: @samp{COPYING}, property +Copying material is defined in a dedicated headline with a non-~nil~ +=COPYING= property. The back-end inserts the contents within +a =@copying= command at the beginning of the document. The heading +itself does not appear in the structure of the document. + +Copyright information is printed on the back of the title page. + +#+begin_example +,* Legalese + :PROPERTIES: + :COPYING: t + :END: + + This is a short example of a complete Texinfo file, version 1.0. + + Copyright \copy 2016 Free Software Foundation, Inc. +#+end_example + +*** Info directory file +:PROPERTIES: +:DESCRIPTION: Installing a manual in Info file hierarchy. +:END: + +#+cindex: @samp{dir} file, in Texinfo export +#+cindex: Info directory file, in Texinfo export +#+cindex: @code{install-info}, in Texinfo export + +#+cindex: @samp{TEXINFO_DIR_CATEGORY}, keyword +#+cindex: @samp{TEXINFO_DIR_TITLE}, keyword +#+cindex: @samp{TEXINFO_DIR_DESC}, keyword +The end result of the Texinfo export process is the creation of an +Info file. This Info file's metadata has variables for category, +title, and description: =TEXINFO_DIR_CATEGORY=, =TEXINFO_DIR_TITLE=, +and =TEXINFO_DIR_DESC= keywords that establish where in the Info +hierarchy the file fits. + +Here is an example that writes to the Info directory file: + +#+begin_example +,#+TEXINFO_DIR_CATEGORY: Emacs +,#+TEXINFO_DIR_TITLE: Org Mode: (org) +,#+TEXINFO_DIR_DESC: Outline-based notes management and organizer +#+end_example + +*** Headings and sectioning structure +:PROPERTIES: +:DESCRIPTION: Building document structure. +:END: + +#+vindex: org-texinfo-classes +#+vindex: org-texinfo-default-class +#+cindex: @samp{TEXINFO_CLASS}, keyword +The Texinfo export back-end uses a pre-defined scheme to convert Org +headlines to equivalent Texinfo structuring commands. A scheme like +this maps top-level headlines to numbered chapters tagged as +~@chapter~ and lower-level headlines to unnumbered chapters tagged as +~@unnumbered~. To override such mappings to introduce ~@part~ or +other Texinfo structuring commands, define a new class in +~org-texinfo-classes~. Activate the new class with the +=TEXINFO_CLASS= keyword. When no new class is defined and activated, +the Texinfo export back-end defaults to the +~org-texinfo-default-class~. + +If an Org headline's level has no associated Texinfo structuring +command, or is below a certain threshold (see [[*Export Settings]]), then +the Texinfo export back-end makes it into a list item. + +#+cindex: @samp{APPENDIX}, property +The Texinfo export back-end makes any headline with a non-~nil~ +=APPENDIX= property into an appendix. This happens independent of the +Org headline level or the =TEXINFO_CLASS= keyword. + +#+cindex: @samp{ALT_TITLE}, property +#+cindex: @samp{DESCRIPTION}, property +The Texinfo export back-end creates a menu entry after the Org +headline for each regular sectioning structure. To override this with +a shorter menu entry, use the =ALT_TITLE= property (see [[*Table of +Contents]]). Texinfo menu entries also have an option for a longer +=DESCRIPTION= property. Here's an example that uses both to override +the default menu entry: + +#+begin_example +,* Controlling Screen Display + :PROPERTIES: + :ALT_TITLE: Display + :DESCRIPTION: Controlling Screen Display + :END: +#+end_example + +#+cindex: Top node, in Texinfo export +The text before the first headline belongs to the /Top/ node, i.e., +the node in which a reader enters an Info manual. As such, it is +expected not to appear in printed output generated from the =.texi= +file. See [[info:texinfo::The Top Node]], for more information. + +*** Indices +:PROPERTIES: +:DESCRIPTION: Creating indices. +:END: + +#+cindex: @samp{CINDEX}, keyword +#+cindex: concept index, in Texinfo export +#+cindex: @samp{FINDEX}, keyword +#+cindex: function index, in Texinfo export +#+cindex: @samp{KINDEX}, keyword +#+cindex: keystroke index, in Texinfo export +#+cindex: @samp{PINDEX}, keyword +#+cindex: program index, in Texinfo export +#+cindex: @samp{TINDEX}, keyword +#+cindex: data type index, in Texinfo export +#+cindex: @samp{VINDEX}, keyword +#+cindex: variable index, in Texinfo export +The Texinfo export back-end recognizes these indexing keywords if used +in the Org file: =CINDEX=, =FINDEX=, =KINDEX=, =PINDEX=, =TINDEX= and +=VINDEX=. Write their value as verbatim Texinfo code; in particular, +={=, =}= and =@= characters need to be escaped with =@= if they do not +belong to a Texinfo command. + +: #+CINDEX: Defining indexing entries + +#+cindex: @samp{INDEX}, property +For the back-end to generate an index entry for a headline, set the +=INDEX= property to =cp= or =vr=. These abbreviations come from +Texinfo that stand for concept index and variable index. The Texinfo +manual has abbreviations for all other kinds of indexes. The back-end +exports the headline as an unnumbered chapter or section command, and +then inserts the index after its contents. + +#+begin_example +,* Concept Index + :PROPERTIES: + :INDEX: cp + :END: +#+end_example + +*** Quoting Texinfo code +:PROPERTIES: +:DESCRIPTION: Incorporating literal Texinfo code. +:END: + +Use any of the following three methods to insert or escape raw Texinfo +code: + +#+cindex: @samp{TEXINFO}, keyword +#+cindex: @samp{BEGIN_EXPORT texinfo} +#+begin_example +Richard @@texinfo:@sc{@@Stallman@@texinfo:}@@ commence' GNU. + +,#+TEXINFO: @need800 +This paragraph is preceded by... + +,#+BEGIN_EXPORT texinfo + @auindex Johnson, Mark + @auindex Lakoff, George +,#+END_EXPORT +#+end_example + +*** Plain lists in Texinfo export +:PROPERTIES: +:DESCRIPTION: List attributes. +:END: + +#+cindex: @samp{ATTR_TEXINFO}, keyword +#+cindex: two-column tables, in Texinfo export +#+cindex: table-type, Texinfo attribute +The Texinfo export back-end by default converts description lists in +the Org file using the default command =@table=, which results in +a table with two columns. To change this behavior, set =:table-type= +attribute to either =ftable= or =vtable= value. For more information, +see [[info:texinfo::Two-column Tables]]. + +#+vindex: org-texinfo-table-default-markup +#+cindex: indic, Texinfo attribute +The Texinfo export back-end by default also applies a text highlight +based on the defaults stored in ~org-texinfo-table-default-markup~. +To override the default highlight command, specify another one with +the =:indic= attribute. + +#+cindex: multiple items in Texinfo lists +#+cindex: sep, Texinfo attribute +Org syntax is limited to one entry per list item. Nevertheless, the +Texinfo export back-end can split that entry according to any text +provided through the =:sep= attribute. Each part then becomes a new +entry in the first column of the table. + +The following example illustrates all the attributes above: + +#+begin_example +,#+ATTR_TEXINFO: :table-type vtable :sep , :indic asis +- foo, bar :: This is the common text for variables foo and bar. +#+end_example + +#+texinfo: @noindent +becomes + +#+begin_example +@vtable @asis +@item foo +@itemx bar +This is the common text for variables foo and bar. +@end table +#+end_example + +#+cindex: lettered lists, in Texinfo export +#+cindex: enum, Texinfo attribute +Ordered lists are numbered when exported to Texinfo format. Such +numbering obeys any counter (see [[*Plain Lists]]) in the first item of +the list. The =:enum= attribute also let you start the list at +a specific number, or switch to a lettered list, as illustrated here + +#+begin_example +#+ATTR_TEXINFO: :enum A +1. Alpha +2. Bravo +3. Charlie +#+end_example + +*** Tables in Texinfo export +:PROPERTIES: +:DESCRIPTION: Table attributes. +:END: + +#+cindex: @samp{ATTR_TEXINFO}, keyword +When exporting tables, the Texinfo export back-end uses the widest +cell width in each column. To override this and instead specify as +fractions of line length, use the =:columns= attribute. See example +below. + +#+begin_example +,#+ATTR_TEXINFO: :columns .5 .5 +| a cell | another cell | +#+end_example + +*** Images in Texinfo export +:PROPERTIES: +:DESCRIPTION: Image attributes. +:END: + +#+cindex: @samp{ATTR_TEXINFO}, keyword +Insert a file link to the image in the Org file, and the Texinfo +export back-end inserts the image. These links must have the usual +supported image extensions and no descriptions. To scale the image, +use =:width= and =:height= attributes. For alternate text, use =:alt= +and specify the text using Texinfo code, as shown in the example: + +#+begin_example +,#+ATTR_TEXINFO: :width 1in :alt Alternate @i{text} +[[ridt.pdf]] +#+end_example + +*** Quotations in Texinfo export +:PROPERTIES: +:DESCRIPTION: Quote block attributes. +:END: + +#+cindex: @samp{ATTR_TEXINFO}, keyword +You can write the text of a quotation within a quote block (see +[[*Paragraphs]]). You may also emphasize some text at the beginning of +the quotation with the =:tag= attribute. + +#+begin_example +,#+ATTR_TEXINFO: :tag Warning +,#+BEGIN_QUOTE +Striking your thumb with a hammer may cause severe pain and discomfort. +,#+END_QUOTE +#+end_example + +To specify the author of the quotation, use the =:author= attribute. + +#+begin_example +,#+ATTR_TEXINFO: :author King Arthur +,#+BEGIN_QUOTE +The Lady of the Lake, her arm clad in the purest shimmering samite, +held aloft Excalibur from the bosom of the water, signifying by divine +providence that I, Arthur, was to carry Excalibur. That is why I am +your king. +,#+END_QUOTE +#+end_example + +*** Special blocks in Texinfo export +:PROPERTIES: +:DESCRIPTION: Special block attributes. +:END: + +#+cindex: @samp{ATTR_TEXINFO}, keyword + +The Texinfo export back-end converts special blocks to commands with +the same name. It also adds any =:options= attributes to the end of +the command, as shown in this example: + +#+begin_example +,#+ATTR_TEXINFO: :options org-org-export-to-org ... +,#+BEGIN_defun + A somewhat obsessive function name. +,#+END_defun +#+end_example + +#+texinfo: @noindent +becomes + +#+begin_example +@defun org-org-export-to-org ... + A somewhat obsessive function name. +@end defun +#+end_example + +*** A Texinfo example +:PROPERTIES: +:DESCRIPTION: Processing Org to Texinfo. +:END: + +Here is a more detailed example Org file. See +[[info:texinfo::GNU Sample Texts]] for an equivalent example using +Texinfo code. + +#+begin_example +,#+TITLE: GNU Sample {{{version}}} +,#+SUBTITLE: for version {{{version}}}, {{{updated}}} +,#+AUTHOR: A.U. Thor +,#+EMAIL: bug-sample@gnu.org + +,#+OPTIONS: ':t toc:t author:t email:t +,#+LANGUAGE: en + +,#+MACRO: version 2.0 +,#+MACRO: updated last updated 4 March 2014 + +,#+TEXINFO_FILENAME: sample.info +,#+TEXINFO_HEADER: @syncodeindex pg cp + +,#+TEXINFO_DIR_CATEGORY: Texinfo documentation system +,#+TEXINFO_DIR_TITLE: sample: (sample) +,#+TEXINFO_DIR_DESC: Invoking sample + +,#+TEXINFO_PRINTED_TITLE: GNU Sample + +This manual is for GNU Sample (version {{{version}}}, +{{{updated}}}). + +,* Copying + :PROPERTIES: + :COPYING: t + :END: + + This manual is for GNU Sample (version {{{version}}}, + {{{updated}}}), which is an example in the Texinfo documentation. + + Copyright \copy 2016 Free Software Foundation, Inc. + + ,#+BEGIN_QUOTE + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with no Invariant Sections, with no Front-Cover Texts, + and with no Back-Cover Texts. A copy of the license is included in + the section entitled "GNU Free Documentation License". + ,#+END_QUOTE + +,* Invoking sample + + ,#+PINDEX: sample + ,#+CINDEX: invoking @command{sample} + + This is a sample manual. There is no sample program to invoke, but + if there were, you could see its basic usage and command line + options here. + +,* GNU Free Documentation License + :PROPERTIES: + :APPENDIX: t + :END: + + ,#+INCLUDE: fdl.org + +,* Index + :PROPERTIES: + :INDEX: cp + :END: +#+end_example + +** iCalendar Export +:PROPERTIES: +:DESCRIPTION: Exporting to iCalendar. +:END: +#+cindex: iCalendar export + +A large part of Org mode's interoperability success is its ability to +easily export to or import from external applications. The iCalendar +export back-end takes calendar data from Org files and exports to the +standard iCalendar format. + +#+vindex: org-icalendar-include-todo +#+vindex: org-icalendar-use-deadline +#+vindex: org-icalendar-use-scheduled +The iCalendar export back-end can also incorporate TODO entries based +on the configuration of the ~org-icalendar-include-todo~ variable. +The back-end exports plain timestamps as =VEVENT=, TODO items as +=VTODO=, and also create events from deadlines that are in non-TODO +items. The back-end uses the deadlines and scheduling dates in Org +TODO items for setting the start and due dates for the iCalendar TODO +entry. Consult the ~org-icalendar-use-deadline~ and +~org-icalendar-use-scheduled~ variables for more details. + +#+vindex: org-icalendar-categories +#+vindex: org-icalendar-alarm-time +For tags on the headline, the iCalendar export back-end makes them +into iCalendar categories. To tweak the inheritance of tags and TODO +states, configure the variable ~org-icalendar-categories~. To assign +clock alarms based on time, configure the ~org-icalendar-alarm-time~ +variable. + +#+vindex: org-icalendar-store-UID +#+cindex: @samp{ID}, property +The iCalendar format standard requires globally unique identifier---or +UID---for each entry. The iCalendar export back-end creates UIDs +during export. To save a copy of the UID in the Org file set the +variable ~org-icalendar-store-UID~. The back-end looks for the =ID= +property of the entry for re-using the same UID for subsequent +exports. + +Since a single Org entry can result in multiple iCalendar +entries---timestamp, deadline, scheduled item, or TODO item---Org adds +prefixes to the UID, depending on which part of the Org entry +triggered the creation of the iCalendar entry. Prefixing ensures UIDs +remains unique, yet enable synchronization programs trace the +connections. + +- {{{kbd(C-c C-e c f)}}} (~org-icalendar-export-to-ics~) :: + + #+kindex: C-c C-e c f + #+findex: org-icalendar-export-to-ics + Create iCalendar entries from the current Org buffer and store them + in the same directory, using a file extension =.ics=. + +- {{{kbd(C-c C-e c a)}}} (~org-icalendar-export-agenda-files~) :: + + #+kindex: C-c C-e c a + #+findex: org-icalendar-export-agenda-files + Create iCalendar entries from Org files in ~org-agenda-files~ and + store in a separate iCalendar file for each Org file. + +- {{{kbd(C-c C-e c c)}}} (~org-icalendar-combine-agenda-files~) :: + + #+kindex: C-c C-e c c + #+findex: org-icalendar-combine-agenda-files + #+vindex: org-icalendar-combined-agenda-file + Create a combined iCalendar file from Org files in + ~org-agenda-files~ and write it to + ~org-icalendar-combined-agenda-file~ file name. + +#+cindex: @samp{SUMMARY}, property +#+cindex: @samp{DESCRIPTION}, property +#+cindex: @samp{LOCATION}, property +#+cindex: @samp{TIMEZONE}, property +#+cindex: @samp{CLASS}, property +The iCalendar export back-end includes =SUMMARY=, =DESCRIPTION=, +=LOCATION=, =TIMEZONE= and =CLASS= properties from the Org entries +when exporting. To force the back-end to inherit the =LOCATION=, +=TIMEZONE= and =CLASS= properties, configure the +~org-use-property-inheritance~ variable. + +#+vindex: org-icalendar-include-body +When Org entries do not have =SUMMARY=, =DESCRIPTION=, =LOCATION= and +=CLASS= properties, the iCalendar export back-end derives the summary +from the headline, and derives the description from the body of the +Org item. The ~org-icalendar-include-body~ variable limits the +maximum number of characters of the content are turned into its +description. + +The =TIMEZONE= property can be used to specify a per-entry time zone, +and is applied to any entry with timestamp information. Time zones +should be specified as per the IANA time zone database format, e.g., +=Asia/Almaty=. Alternately, the property value can be =UTC=, to force +UTC time for this entry only. + +The =CLASS= property can be used to specify a per-entry visibility +class or access restrictions, and is applied to any entry with class +information. The iCalendar standard defines three visibility classes: +- =PUBLIC= :: The entry is publicly visible (this is the default). +- =CONFIDENTIAL= :: Only a limited group of clients get access to the + event. +- =PRIVATE= :: The entry can be retrieved only by its owner. +The server should treat unknown class properties the same as +=PRIVATE=. + +Exporting to iCalendar format depends in large part on the +capabilities of the destination application. Some are more lenient +than others. Consult the Org mode FAQ for advice on specific +applications. + +** Other Built-in Back-ends +:PROPERTIES: +:DESCRIPTION: Exporting to a man page. +:END: + +Other export back-ends included with Org are: + +- =ox-man.el=: Export to a man page. + +To activate such back-ends, either customize ~org-export-backends~ or +load directly with =(require 'ox-man)=. On successful load, the +back-end adds new keys in the export dispatcher (see [[*The Export +Dispatcher]]). + +Follow the comment section of such files, for example, =ox-man.el=, +for usage and configuration details. + +** Advanced Export Configuration +:PROPERTIES: +:DESCRIPTION: Fine-tuning the export output. +:END: + +*** Hooks +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+vindex: org-export-before-processing-hook +#+vindex: org-export-before-parsing-hook +The export process executes two hooks before the actual exporting +begins. The first hook, ~org-export-before-processing-hook~, runs +before any expansions of macros, Babel code, and include keywords in +the buffer. The second hook, ~org-export-before-parsing-hook~, runs +before the buffer is parsed. + +Functions added to these hooks are called with a single argument: the +export back-end actually used, as a symbol. You may use them for +heavy duty structural modifications of the document. For example, you +can remove every headline in the buffer during export like this: + +#+begin_src emacs-lisp +(defun my-headline-removal (backend) + "Remove all headlines in the current buffer. +BACKEND is the export back-end being used, as a symbol." + (org-map-entries + (lambda () (delete-region (point) (line-beginning-position 2))))) + +(add-hook 'org-export-before-parsing-hook 'my-headline-removal) +#+end_src + +*** Filters +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: Filters, exporting +Filters are lists of functions to be applied to certain parts for +a given back-end. The output from the first function in the filter is +passed on to the next function in the filter. The final output is the +output from the final function in the filter. + +The Org export process has many filter sets applicable to different +types of objects, plain text, parse trees, export options, and final +output formats. The filters are named after the element type or +object type: ~org-export-filter-TYPE-functions~, where {{{var(TYPE)}}} +is the type targeted by the filter. Valid types are: + +#+attr_texinfo: :columns 0.33 0.33 0.33 +| body | bold | babel-call | +| center-block | clock | code | +| diary-sexp | drawer | dynamic-block | +| entity | example-block | export-block | +| export-snippet | final-output | fixed-width | +| footnote-definition | footnote-reference | headline | +| horizontal-rule | inline-babel-call | inline-src-block | +| inlinetask | italic | item | +| keyword | latex-environment | latex-fragment | +| line-break | link | node-property | +| options | paragraph | parse-tree | +| plain-list | plain-text | planning | +| property-drawer | quote-block | radio-target | +| section | special-block | src-block | +| statistics-cookie | strike-through | subscript | +| superscript | table | table-cell | +| table-row | target | timestamp | +| underline | verbatim | verse-block | + +Here is an example filter that replaces non-breaking spaces ~ ~ in the +Org buffer with =~= for the LaTeX back-end. + +#+begin_src emacs-lisp +(defun my-latex-filter-nobreaks (text backend info) + "Ensure \" \" are properly handled in LaTeX export." + (when (org-export-derived-backend-p backend 'latex) + (replace-regexp-in-string " " "~" text))) + +(add-to-list 'org-export-filter-plain-text-functions + 'my-latex-filter-nobreaks) +#+end_src + +A filter requires three arguments: the code to be transformed, the +name of the back-end, and some optional information about the export +process. The third argument can be safely ignored. Note the use of +~org-export-derived-backend-p~ predicate that tests for /latex/ +back-end or any other back-end, such as /beamer/, derived from +/latex/. + +*** Defining filters for individual files +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +The Org export can filter not just for back-ends, but also for +specific files through the =BIND= keyword. Here is an example with +two filters; one removes brackets from time stamps, and the other +removes strike-through text. The filter functions are defined in +a code block in the same Org file, which is a handy location for +debugging. + +#+begin_example +,#+BIND: org-export-filter-timestamp-functions (tmp-f-timestamp) +,#+BIND: org-export-filter-strike-through-functions (tmp-f-strike-through) +,#+BEGIN_SRC emacs-lisp :exports results :results none + (defun tmp-f-timestamp (s backend info) + (replace-regexp-in-string "&[lg]t;\\|[][]" "" s)) + (defun tmp-f-strike-through (s backend info) "") +,#+END_SRC +#+end_example + +*** Extending an existing back-end +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +Some parts of the conversion process can be extended for certain +elements so as to introduce a new or revised translation. That is how +the HTML export back-end was extended to handle Markdown format. The +extensions work seamlessly so any aspect of filtering not done by the +extended back-end is handled by the original back-end. Of all the +export customization in Org, extending is very powerful as it operates +at the parser level. + +For this example, make the /ascii/ back-end display the language used +in a source code block. Also make it display only when some attribute +is non-~nil~, like the following: + +: #+ATTR_ASCII: :language t + +Then extend ASCII back-end with a custom "my-ascii" back-end. + +#+begin_src emacs-lisp +(defun my-ascii-src-block (src-block contents info) + "Transcode a SRC-BLOCK element from Org to ASCII. +CONTENTS is nil. INFO is a plist used as a communication +channel." + (if (not (org-export-read-attribute :attr_ascii src-block :language)) + (org-export-with-backend 'ascii src-block contents info) + (concat + (format ",--[ %s ]--\n%s`----" + (org-element-property :language src-block) + (replace-regexp-in-string + "^" "| " + (org-element-normalize-string + (org-export-format-code-default src-block info))))))) + +(org-export-define-derived-backend 'my-ascii 'ascii + :translate-alist '((src-block . my-ascii-src-block))) +#+end_src + +The ~my-ascii-src-block~ function looks at the attribute above the +current element. If not true, hands over to /ascii/ back-end. If +true, which it is in this example, it creates a box around the code +and leaves room for the inserting a string for language. The last +form creates the new back-end that springs to action only when +translating ~src-block~ type elements. + +To use the newly defined back-end, evaluate the following from an Org +buffer: + +#+begin_src emacs-lisp +(org-export-to-buffer 'my-ascii "*Org MY-ASCII Export*") +#+end_src + +Further steps to consider would be an interactive function, +self-installing an item in the export dispatcher menu, and other +user-friendly improvements. + +** Export in Foreign Buffers +:PROPERTIES: +:DESCRIPTION: Author tables and lists in Org syntax. +:END: + +The export back-ends in Org often include commands to convert selected +regions. A convenient feature of this in-place conversion is that the +exported output replaces the original source. Here are such +functions: + +- ~org-ascii-convert-region-to-ascii~ :: + + #+findex: org-ascii-convert-region-to-ascii + Convert the selected region into ASCII. + +- ~org-ascii-convert-region-to-utf8~ :: + + #+findex: org-ascii-convert-region-to-utf8 + Convert the selected region into UTF-8. + +- ~org-html-convert-region-to-html~ :: + + #+findex: org-html-convert-region-to-html + Convert the selected region into HTML. + +- ~org-latex-convert-region-to-latex~ :: + + #+findex: org-latex-convert-region-to-latex + Convert the selected region into LaTeX. + +- ~org-texinfo-convert-region-to-texinfo~ :: + + #+findex: org-texinfo-convert-region-to-texinfo + Convert the selected region into Texinfo. + +- ~org-md-convert-region-to-md~ :: + + #+findex: org-md-convert-region-to-md + Convert the selected region into Markdown. + +In-place conversions are particularly handy for quick conversion of +tables and lists in foreign buffers. For example, in an HTML buffer, +write a list in Org syntax, select it, and convert it to HTML with +{{{kbd(M-x org-html-convert-region-to-html)}}}. + +*** Exporting to minimal HTML +:PROPERTIES: +:DESCRIPTION: Exporting HTML without CSS, Javascript, etc. +:ALT_TITLE: Bare HTML +:END: + +If you want to output a minimal HTML file, with no CSS, no Javascript, +no preamble or postamble, here are the variable you would need to set: + +#+vindex: org-html-head +#+vindex: org-html-head-extra +#+vindex: org-html-head-include-default-style +#+vindex: org-html-head-include-scripts +#+vindex: org-html-preamble +#+vindex: org-html-postamble +#+vindex: org-html-use-infojs +#+begin_src emacs-lisp +(setq org-html-head "" + org-html-head-extra "" + org-html-head-include-default-style nil + org-html-head-include-scripts nil + org-html-preamble nil + org-html-postamble nil + org-html-use-infojs nil) +#+end_src + +* Publishing +:PROPERTIES: +:DESCRIPTION: Create a web site of linked Org files. +:END: +#+cindex: publishing + +Org includes a publishing management system that allows you to +configure automatic HTML conversion of /projects/ composed of +interlinked Org files. You can also configure Org to automatically +upload your exported HTML pages and related attachments, such as +images and source code files, to a web server. + +You can also use Org to convert files into PDF, or even combine HTML +and PDF conversion so that files are available in both formats on the +server. + +Publishing has been contributed to Org by David O'Toole. + +** Configuration +:PROPERTIES: +:DESCRIPTION: Defining projects. +:END: +Publishing needs significant configuration to specify files, +destination and many other properties of a project. + +*** The variable ~org-publish-project-alist~ +:PROPERTIES: +:DESCRIPTION: The central configuration variable. +:ALT_TITLE: Project alist +:END: +#+cindex: projects, for publishing + +#+vindex: org-publish-project-alist +Publishing is configured almost entirely through setting the value of +one variable, called ~org-publish-project-alist~. Each element of the +list configures one project, and may be in one of the two following +forms: + +#+begin_src emacs-lisp +("project-name" :property value :property value ...) +#+end_src + +#+texinfo: @noindent +i.e., a well-formed property list with alternating keys and values, +or: + +#+begin_src emacs-lisp +("project-name" :components ("project-name" "project-name" ...)) +#+end_src + +In both cases, projects are configured by specifying property values. +A project defines the set of files that are to be published, as well +as the publishing configuration to use when publishing those files. +When a project takes the second form listed above, the individual +members of the ~:components~ property are taken to be sub-projects, +which group together files requiring different publishing options. +When you publish such a "meta-project", all the components are also +published, in the sequence given. + +*** Sources and destinations for files +:PROPERTIES: +:DESCRIPTION: From here to there. +:ALT_TITLE: Sources and destinations +:END: +#+cindex: directories, for publishing + +Most properties are optional, but some should always be set. In +particular, Org needs to know where to look for source files, and +where to put published files. + +- ~:base-directory~ :: + + Directory containing publishing source files. + +- ~:publishing-directory~ :: + + Directory where output files are published. You can directly + publish to a webserver using a file name syntax appropriate for the + Emacs tramp package. Or you can publish to a local directory and + use external tools to upload your website (see [[*Uploading Files]]). + +- ~:preparation-function~ :: + + Function or list of functions to be called before starting the + publishing process, for example, to run =make= for updating files to + be published. Each preparation function is called with a single + argument, the project property list. + +- ~:completion-function~ :: + + Function or list of functions called after finishing the publishing + process, for example, to change permissions of the resulting files. + Each completion function is called with a single argument, the + project property list. + +*** Selecting files +:PROPERTIES: +:DESCRIPTION: What files are part of the project? +:END: +#+cindex: files, selecting for publishing + +By default, all files with extension =.org= in the base directory are +considered part of the project. This can be modified by setting the +following properties + +- ~:base-extension~ :: + + Extension---without the dot---of source files. This actually is + a regular expression. Set this to the symbol ~any~ if you want to + get all files in ~:base-directory~, even without extension. + +- ~:exclude~ :: + + Regular expression to match file names that should not be published, + even though they have been selected on the basis of their extension. + +- ~:include~ :: + + List of files to be included regardless of ~:base-extension~ and + ~:exclude~. + +- ~:recursive~ :: + + Non-~nil~ means, check base-directory recursively for files to + publish. + +*** Publishing action +:PROPERTIES: +:DESCRIPTION: Setting the function doing the publishing. +:END: +#+cindex: action, for publishing + +Publishing means that a file is copied to the destination directory +and possibly transformed in the process. The default transformation +is to export Org files as HTML files, and this is done by the function +~org-publish-org-to-html~ which calls the HTML exporter (see [[*HTML +Export]]). But you can also publish your content as PDF files using +~org-publish-org-to-pdf~, or as ASCII, Texinfo, etc., using the +corresponding functions. + +If you want to publish the Org file as an =.org= file but with +/archived/, /commented/, and /tag-excluded/ trees removed, use +~org-publish-org-to-org~. This produces =file.org= and put it in the +publishing directory. If you want a htmlized version of this file, +set the parameter ~:htmlized-source~ to ~t~. It produces +=file.org.html= in the publishing directory[fn:140]. + +Other files like images only need to be copied to the publishing +destination; for this you can use ~org-publish-attachment~. For +non-Org files, you always need to specify the publishing function: + +- ~:publishing-function~ :: + + Function executing the publication of a file. This may also be + a list of functions, which are all called in turn. + +- ~:htmlized-source~ :: + + Non-~nil~ means, publish htmlized source. + +The function must accept three arguments: a property list containing +at least a ~:publishing-directory~ property, the name of the file to +be published, and the path to the publishing directory of the output +file. It should take the specified file, make the necessary +transformation, if any, and place the result into the destination +folder. + +*** Options for the exporters +:PROPERTIES: +:DESCRIPTION: Tweaking HTML/@LaTeX{} export. +:ALT_TITLE: Publishing options +:END: +#+cindex: options, for publishing +#+cindex: publishing options + +The property list can be used to set many export options for the HTML +and LaTeX exporters. In most cases, these properties correspond to +user variables in Org. The table below lists these properties along +with the variable they belong to. See the documentation string for +the respective variable for details. + +#+vindex: org-publish-project-alist +When a property is given a value in ~org-publish-project-alist~, its +setting overrides the value of the corresponding user variable, if +any, during publishing. Options set within a file (see [[*Export +Settings]]), however, override everything. + +**** Generic properties +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +| ~:archived-trees~ | ~org-export-with-archived-trees~ | +| ~:exclude-tags~ | ~org-export-exclude-tags~ | +| ~:headline-levels~ | ~org-export-headline-levels~ | +| ~:language~ | ~org-export-default-language~ | +| ~:preserve-breaks~ | ~org-export-preserve-breaks~ | +| ~:section-numbers~ | ~org-export-with-section-numbers~ | +| ~:select-tags~ | ~org-export-select-tags~ | +| ~:with-author~ | ~org-export-with-author~ | +| ~:with-broken-links~ | ~org-export-with-broken-links~ | +| ~:with-clocks~ | ~org-export-with-clocks~ | +| ~:with-creator~ | ~org-export-with-creator~ | +| ~:with-date~ | ~org-export-with-date~ | +| ~:with-drawers~ | ~org-export-with-drawers~ | +| ~:with-email~ | ~org-export-with-email~ | +| ~:with-emphasize~ | ~org-export-with-emphasize~ | +| ~:with-fixed-width~ | ~org-export-with-fixed-width~ | +| ~:with-footnotes~ | ~org-export-with-footnotes~ | +| ~:with-latex~ | ~org-export-with-latex~ | +| ~:with-planning~ | ~org-export-with-planning~ | +| ~:with-priority~ | ~org-export-with-priority~ | +| ~:with-properties~ | ~org-export-with-properties~ | +| ~:with-special-strings~ | ~org-export-with-special-strings~ | +| ~:with-sub-superscript~ | ~org-export-with-sub-superscripts~ | +| ~:with-tables~ | ~org-export-with-tables~ | +| ~:with-tags~ | ~org-export-with-tags~ | +| ~:with-tasks~ | ~org-export-with-tasks~ | +| ~:with-timestamps~ | ~org-export-with-timestamps~ | +| ~:with-title~ | ~org-export-with-title~ | +| ~:with-toc~ | ~org-export-with-toc~ | +| ~:with-todo-keywords~ | ~org-export-with-todo-keywords~ | + +**** ASCII specific properties +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +| ~:ascii-bullets~ | ~org-ascii-bullets~ | +| ~:ascii-caption-above~ | ~org-ascii-caption-above~ | +| ~:ascii-charset~ | ~org-ascii-charset~ | +| ~:ascii-global-margin~ | ~org-ascii-global-margin~ | +| ~:ascii-format-drawer-function~ | ~org-ascii-format-drawer-function~ | +| ~:ascii-format-inlinetask-function~ | ~org-ascii-format-inlinetask-function~ | +| ~:ascii-headline-spacing~ | ~org-ascii-headline-spacing~ | +| ~:ascii-indented-line-width~ | ~org-ascii-indented-line-width~ | +| ~:ascii-inlinetask-width~ | ~org-ascii-inlinetask-width~ | +| ~:ascii-inner-margin~ | ~org-ascii-inner-margin~ | +| ~:ascii-links-to-notes~ | ~org-ascii-links-to-notes~ | +| ~:ascii-list-margin~ | ~org-ascii-list-margin~ | +| ~:ascii-paragraph-spacing~ | ~org-ascii-paragraph-spacing~ | +| ~:ascii-quote-margin~ | ~org-ascii-quote-margin~ | +| ~:ascii-table-keep-all-vertical-lines~ | ~org-ascii-table-keep-all-vertical-lines~ | +| ~:ascii-table-use-ascii-art~ | ~org-ascii-table-use-ascii-art~ | +| ~:ascii-table-widen-columns~ | ~org-ascii-table-widen-columns~ | +| ~:ascii-text-width~ | ~org-ascii-text-width~ | +| ~:ascii-underline~ | ~org-ascii-underline~ | +| ~:ascii-verbatim-format~ | ~org-ascii-verbatim-format~ | + +**** Beamer specific properties +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +| ~:beamer-theme~ | ~org-beamer-theme~ | +| ~:beamer-column-view-format~ | ~org-beamer-column-view-format~ | +| ~:beamer-environments-extra~ | ~org-beamer-environments-extra~ | +| ~:beamer-frame-default-options~ | ~org-beamer-frame-default-options~ | +| ~:beamer-outline-frame-options~ | ~org-beamer-outline-frame-options~ | +| ~:beamer-outline-frame-title~ | ~org-beamer-outline-frame-title~ | +| ~:beamer-subtitle-format~ | ~org-beamer-subtitle-format~ | + +**** HTML specific properties +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +| ~:html-allow-name-attribute-in-anchors~ | ~org-html-allow-name-attribute-in-anchors~ | +| ~:html-checkbox-type~ | ~org-html-checkbox-type~ | +| ~:html-container~ | ~org-html-container-element~ | +| ~:html-divs~ | ~org-html-divs~ | +| ~:html-doctype~ | ~org-html-doctype~ | +| ~:html-extension~ | ~org-html-extension~ | +| ~:html-footnote-format~ | ~org-html-footnote-format~ | +| ~:html-footnote-separator~ | ~org-html-footnote-separator~ | +| ~:html-footnotes-section~ | ~org-html-footnotes-section~ | +| ~:html-format-drawer-function~ | ~org-html-format-drawer-function~ | +| ~:html-format-headline-function~ | ~org-html-format-headline-function~ | +| ~:html-format-inlinetask-function~ | ~org-html-format-inlinetask-function~ | +| ~:html-head-extra~ | ~org-html-head-extra~ | +| ~:html-head-include-default-style~ | ~org-html-head-include-default-style~ | +| ~:html-head-include-scripts~ | ~org-html-head-include-scripts~ | +| ~:html-head~ | ~org-html-head~ | +| ~:html-home/up-format~ | ~org-html-home/up-format~ | +| ~:html-html5-fancy~ | ~org-html-html5-fancy~ | +| ~:html-indent~ | ~org-html-indent~ | +| ~:html-infojs-options~ | ~org-html-infojs-options~ | +| ~:html-infojs-template~ | ~org-html-infojs-template~ | +| ~:html-inline-image-rules~ | ~org-html-inline-image-rules~ | +| ~:html-inline-images~ | ~org-html-inline-images~ | +| ~:html-link-home~ | ~org-html-link-home~ | +| ~:html-link-org-files-as-html~ | ~org-html-link-org-files-as-html~ | +| ~:html-link-up~ | ~org-html-link-up~ | +| ~:html-link-use-abs-url~ | ~org-html-link-use-abs-url~ | +| ~:html-mathjax-options~ | ~org-html-mathjax-options~ | +| ~:html-mathjax-template~ | ~org-html-mathjax-template~ | +| ~:html-equation-reference-format~ | ~org-html-equation-reference-format~ | +| ~:html-metadata-timestamp-format~ | ~org-html-metadata-timestamp-format~ | +| ~:html-postamble-format~ | ~org-html-postamble-format~ | +| ~:html-postamble~ | ~org-html-postamble~ | +| ~:html-preamble-format~ | ~org-html-preamble-format~ | +| ~:html-preamble~ | ~org-html-preamble~ | +| ~:html-self-link-headlines~ | ~org-html-self-link-headlines~ | +| ~:html-table-align-individual-field~ | ~de{org-html-table-align-individual-fields~ | +| ~:html-table-attributes~ | ~org-html-table-default-attributes~ | +| ~:html-table-caption-above~ | ~org-html-table-caption-above~ | +| ~:html-table-data-tags~ | ~org-html-table-data-tags~ | +| ~:html-table-header-tags~ | ~org-html-table-header-tags~ | +| ~:html-table-row-tags~ | ~org-html-table-row-tags~ | +| ~:html-table-use-header-tags-for-first-column~ | ~org-html-table-use-header-tags-for-first-column~ | +| ~:html-tag-class-prefix~ | ~org-html-tag-class-prefix~ | +| ~:html-text-markup-alist~ | ~org-html-text-markup-alist~ | +| ~:html-todo-kwd-class-prefix~ | ~org-html-todo-kwd-class-prefix~ | +| ~:html-toplevel-hlevel~ | ~org-html-toplevel-hlevel~ | +| ~:html-use-infojs~ | ~org-html-use-infojs~ | +| ~:html-validation-link~ | ~org-html-validation-link~ | +| ~:html-viewport~ | ~org-html-viewport~ | +| ~:html-wrap-src-lines~ | ~org-html-wrap-src-lines~ | +| ~:html-xml-declaration~ | ~org-html-xml-declaration~ | + +**** LaTeX specific properties +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +| ~:latex-active-timestamp-format~ | ~org-latex-active-timestamp-format~ | +| ~:latex-caption-above~ | ~org-latex-caption-above~ | +| ~:latex-classes~ | ~org-latex-classes~ | +| ~:latex-class~ | ~org-latex-default-class~ | +| ~:latex-compiler~ | ~org-latex-compiler~ | +| ~:latex-default-figure-position~ | ~org-latex-default-figure-position~ | +| ~:latex-default-table-environment~ | ~org-latex-default-table-environment~ | +| ~:latex-default-table-mode~ | ~org-latex-default-table-mode~ | +| ~:latex-diary-timestamp-format~ | ~org-latex-diary-timestamp-format~ | +| ~:latex-footnote-defined-format~ | ~org-latex-footnote-defined-format~ | +| ~:latex-footnote-separator~ | ~org-latex-footnote-separator~ | +| ~:latex-format-drawer-function~ | ~org-latex-format-drawer-function~ | +| ~:latex-format-headline-function~ | ~org-latex-format-headline-function~ | +| ~:latex-format-inlinetask-function~ | ~org-latex-format-inlinetask-function~ | +| ~:latex-hyperref-template~ | ~org-latex-hyperref-template~ | +| ~:latex-image-default-height~ | ~org-latex-image-default-height~ | +| ~:latex-image-default-option~ | ~org-latex-image-default-option~ | +| ~:latex-image-default-width~ | ~org-latex-image-default-width~ | +| ~:latex-images-centered~ | ~org-latex-images-centered~ | +| ~:latex-inactive-timestamp-format~ | ~org-latex-inactive-timestamp-format~ | +| ~:latex-inline-image-rules~ | ~org-latex-inline-image-rules~ | +| ~:latex-link-with-unknown-path-format~ | ~org-latex-link-with-unknown-path-format~ | +| ~:latex-listings-langs~ | ~org-latex-listings-langs~ | +| ~:latex-listings-options~ | ~org-latex-listings-options~ | +| ~:latex-listings~ | ~org-latex-listings~ | +| ~:latex-minted-langs~ | ~org-latex-minted-langs~ | +| ~:latex-minted-options~ | ~org-latex-minted-options~ | +| ~:latex-prefer-user-labels~ | ~org-latex-prefer-user-labels~ | +| ~:latex-subtitle-format~ | ~org-latex-subtitle-format~ | +| ~:latex-subtitle-separate~ | ~org-latex-subtitle-separate~ | +| ~:latex-table-scientific-notation~ | ~org-latex-table-scientific-notation~ | +| ~:latex-tables-booktabs~ | ~org-latex-tables-booktabs~ | +| ~:latex-tables-centered~ | ~org-latex-tables-centered~ | +| ~:latex-text-markup-alist~ | ~org-latex-text-markup-alist~ | +| ~:latex-title-command~ | ~org-latex-title-command~ | +| ~:latex-toc-command~ | ~org-latex-toc-command~ | + +**** Markdown specific properties +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +| ~:md-footnote-format~ | ~org-md-footnote-format~ | +| ~:md-footnotes-section~ | ~org-md-footnotes-section~ | +| ~:md-headline-style~ | ~org-md-headline-style~ | + +**** ODT specific properties +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +| ~:odt-content-template-file~ | ~org-odt-content-template-file~ | +| ~:odt-display-outline-level~ | ~org-odt-display-outline-level~ | +| ~:odt-fontify-srcblocks~ | ~org-odt-fontify-srcblocks~ | +| ~:odt-format-drawer-function~ | ~org-odt-format-drawer-function~ | +| ~:odt-format-headline-function~ | ~org-odt-format-headline-function~ | +| ~:odt-format-inlinetask-function~ | ~org-odt-format-inlinetask-function~ | +| ~:odt-inline-formula-rules~ | ~org-odt-inline-formula-rules~ | +| ~:odt-inline-image-rules~ | ~org-odt-inline-image-rules~ | +| ~:odt-pixels-per-inch~ | ~org-odt-pixels-per-inch~ | +| ~:odt-styles-file~ | ~org-odt-styles-file~ | +| ~:odt-table-styles~ | ~org-odt-table-styles~ | +| ~:odt-use-date-fields~ | ~org-odt-use-date-fields~ | + +**** Texinfo specific properties +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +| ~:texinfo-active-timestamp-format~ | ~org-texinfo-active-timestamp-format~ | +| ~:texinfo-classes~ | ~org-texinfo-classes~ | +| ~:texinfo-class~ | ~org-texinfo-default-class~ | +| ~:texinfo-table-default-markup~ | ~org-texinfo-table-default-markup~ | +| ~:texinfo-diary-timestamp-format~ | ~org-texinfo-diary-timestamp-format~ | +| ~:texinfo-filename~ | ~org-texinfo-filename~ | +| ~:texinfo-format-drawer-function~ | ~org-texinfo-format-drawer-function~ | +| ~:texinfo-format-headline-function~ | ~org-texinfo-format-headline-function~ | +| ~:texinfo-format-inlinetask-function~ | ~org-texinfo-format-inlinetask-function~ | +| ~:texinfo-inactive-timestamp-format~ | ~org-texinfo-inactive-timestamp-format~ | +| ~:texinfo-link-with-unknown-path-format~ | ~org-texinfo-link-with-unknown-path-format~ | +| ~:texinfo-node-description-column~ | ~org-texinfo-node-description-column~ | +| ~:texinfo-table-scientific-notation~ | ~org-texinfo-table-scientific-notation~ | +| ~:texinfo-tables-verbatim~ | ~org-texinfo-tables-verbatim~ | +| ~:texinfo-text-markup-alist~ | ~org-texinfo-text-markup-alist~ | + +*** Publishing links +:PROPERTIES: +:DESCRIPTION: Which links keep working after publishing? +:END: +#+cindex: links, publishing + +To create a link from one Org file to another, you would use something +like =[[file:foo.org][The foo]]= or simply =[[file:foo.org]]= (see [[*External Links]]). When +published, this link becomes a link to =foo.html=. You can thus +interlink the pages of your "Org web" project and the links will work +as expected when you publish them to HTML. If you also publish the +Org source file and want to link to it, use an =http= link instead of +a =file:= link, because =file= links are converted to link to the +corresponding =.html= file. + +You may also link to related files, such as images. Provided you are +careful with relative file names, and provided you have also +configured Org to upload the related files, these links will work too. +See [[*Example: complex publishing configuration]], for an example of this +usage. + +Eventually, links between published documents can contain some search +options (see [[*Search Options in File Links]]), which will be resolved to +the appropriate location in the linked file. For example, once +published to HTML, the following links all point to a dedicated anchor +in =foo.html=. + +#+begin_example +[[file:foo.org::*heading]] +[[file:foo.org::#custom-id]] +[[file:foo.org::target]] +#+end_example + +*** Generating a sitemap +:PROPERTIES: +:DESCRIPTION: Generating a list of all pages. +:ALT_TITLE: Site map +:END: +#+cindex: sitemap, of published pages + +The following properties may be used to control publishing of +a map of files for a given project. + +- ~:auto-sitemap~ :: + + When non-~nil~, publish a sitemap during + ~org-publish-current-project~ or ~org-publish-all~. + +- ~:sitemap-filename~ :: + + Filename for output of sitemap. Defaults to =sitemap.org=, which + becomes =sitemap.html=. + +- ~:sitemap-title~ :: + + Title of sitemap page. Defaults to name of file. + +- ~:sitemap-format-entry~ :: + + #+findex: org-publish-find-date + #+findex: org-publish-find-property + #+findex: org-publish-find-title + With this option one can tell how a site-map entry is formatted in + the site-map. It is a function called with three arguments: the + file or directory name relative to base directory of the project, + the site-map style and the current project. It is expected to + return a string. Default value turns file names into links and use + document titles as descriptions. For specific formatting needs, one + can use ~org-publish-find-date~, ~org-publish-find-title~ and + ~org-publish-find-property~, to retrieve additional information + about published documents. + +- ~:sitemap-function~ :: + + Plug-in function to use for generation of the sitemap. It is called + with two arguments: the title of the site-map and a representation + of the files and directories involved in the project as a nested + list, which can further be transformed using ~org-list-to-generic~, + ~org-list-to-subtree~ and alike. Default value generates a plain + list of links to all files in the project. + +- ~:sitemap-sort-folders~ :: + + Where folders should appear in the sitemap. Set this to ~first~ + (default) or ~last~ to display folders first or last, respectively. + When set to ~ignore~, folders are ignored altogether. Any other + value mixes files and folders. This variable has no effect when + site-map style is ~tree~. + +- ~:sitemap-sort-files~ :: + + How the files are sorted in the site map. Set this to + ~alphabetically~ (default), ~chronologically~ or + ~anti-chronologically~. ~chronologically~ sorts the files with + older date first while ~anti-chronologically~ sorts the files with + newer date first. ~alphabetically~ sorts the files alphabetically. + The date of a file is retrieved with ~org-publish-find-date~. + +- ~:sitemap-ignore-case~ :: + + Should sorting be case-sensitive? Default ~nil~. + +- ~:sitemap-file-entry-format~ :: + + With this option one can tell how a sitemap's entry is formatted in + the sitemap. This is a format string with some escape sequences: + ~%t~ stands for the title of the file, ~%a~ stands for the author of + the file and ~%d~ stands for the date of the file. The date is + retrieved with the ~org-publish-find-date~ function and formatted + with ~org-publish-sitemap-date-format~. Default ~%t~. + +- ~:sitemap-date-format~ :: + + Format string for the ~format-time-string~ function that tells how + a sitemap entry's date is to be formatted. This property bypasses + ~org-publish-sitemap-date-format~ which defaults to ~%Y-%m-%d~. + +*** Generating an index +:PROPERTIES: +:DESCRIPTION: An index that reaches across pages. +:END: +#+cindex: index, in a publishing project + +Org mode can generate an index across the files of a publishing project. + +- ~:makeindex~ :: + + When non-~nil~, generate in index in the file =theindex.org= and + publish it as =theindex.html=. + +The file is created when first publishing a project with the +~:makeindex~ set. The file only contains a statement =#+INCLUDE: +"theindex.inc"=. You can then build around this include statement by +adding a title, style information, etc. + +#+cindex: @samp{INDEX}, keyword +Index entries are specified with =INDEX= keyword. An entry that +contains an exclamation mark creates a sub item. + +#+begin_example +,*** Curriculum Vitae +,#+INDEX: CV +,#+INDEX: Application!CV +#+end_example + +** Uploading Files +:PROPERTIES: +:DESCRIPTION: How to get files up on the server. +:END: +#+cindex: rsync +#+cindex: unison + +For those people already utilizing third party sync tools such as +Rsync or Unison, it might be preferable not to use the built-in remote +publishing facilities of Org mode which rely heavily on Tramp. Tramp, +while very useful and powerful, tends not to be so efficient for +multiple file transfer and has been known to cause problems under +heavy usage. + +Specialized synchronization utilities offer several advantages. In +addition to timestamp comparison, they also do content and +permissions/attribute checks. For this reason you might prefer to +publish your web to a local directory---possibly even /in place/ with +your Org files---and then use Unison or Rsync to do the +synchronization with the remote host. + +Since Unison, for example, can be configured as to which files to +transfer to a certain remote destination, it can greatly simplify the +project publishing definition. Simply keep all files in the correct +location, process your Org files with ~org-publish~ and let the +synchronization tool do the rest. You do not need, in this scenario, +to include attachments such as JPG, CSS or PNG files in the project +definition since the third-party tool syncs them. + +Publishing to a local directory is also much faster than to a remote +one, so that you can afford more easily to republish entire projects. +If you set ~org-publish-use-timestamps-flag~ to ~nil~, you gain the +main benefit of re-including any changed external files such as source +example files you might include with =INCLUDE= keyword. The timestamp +mechanism in Org is not smart enough to detect if included files have +been modified. + +** Sample Configuration +:PROPERTIES: +:DESCRIPTION: Example projects. +:END: + +Below we provide two example configurations. The first one is +a simple project publishing only a set of Org files. The second +example is more complex, with a multi-component project. + +*** Example: simple publishing configuration +:PROPERTIES: +:DESCRIPTION: One-component publishing. +:ALT_TITLE: Simple example +:END: + +This example publishes a set of Org files to the =public_html= +directory on the local machine. + +#+begin_src emacs-lisp +(setq org-publish-project-alist + '(("org" + :base-directory "~/org/" + :publishing-directory "~/public_html" + :section-numbers nil + :table-of-contents nil + :style ""))) +#+end_src + +*** Example: complex publishing configuration +:PROPERTIES: +:DESCRIPTION: A multi-component publishing example. +:ALT_TITLE: Complex example +:END: + +This more complicated example publishes an entire website, including +Org files converted to HTML, image files, Emacs Lisp source code, and +style sheets. The publishing directory is remote and private files +are excluded. + +To ensure that links are preserved, care should be taken to replicate +your directory structure on the web server, and to use relative file +paths. For example, if your Org files are kept in =~/org/= and your +publishable images in =~/images/=, you would link to an image with + +: file:../images/myimage.png + +On the web server, the relative path to the image should be the same. +You can accomplish this by setting up an =images/= folder in the right +place on the web server, and publishing images to it. + +#+begin_src emacs-lisp +(setq org-publish-project-alist + '(("orgfiles" + :base-directory "~/org/" + :base-extension "org" + :publishing-directory "/ssh:user@host:~/html/notebook/" + :publishing-function org-html-publish-to-html + :exclude "PrivatePage.org" ;; regexp + :headline-levels 3 + :section-numbers nil + :with-toc nil + :html-head "" + :html-preamble t) + + ("images" + :base-directory "~/images/" + :base-extension "jpg\\|gif\\|png" + :publishing-directory "/ssh:user@host:~/html/images/" + :publishing-function org-publish-attachment) + + ("other" + :base-directory "~/other/" + :base-extension "css\\|el" + :publishing-directory "/ssh:user@host:~/html/other/" + :publishing-function org-publish-attachment) + ("website" :components ("orgfiles" "images" "other")))) +#+end_src + +** Triggering Publication +:PROPERTIES: +:DESCRIPTION: Publication commands. +:END: + +Once properly configured, Org can publish with the following commands: + +- {{{kbd(C-c C-e P x)}}} (~org-publish~) :: + + #+kindex: C-c C-e P x + #+findex: org-publish + Prompt for a specific project and publish all files that belong to + it. + +- {{{kbd(C-c C-e P p)}}} (~org-publish-current-project~) :: + + #+kindex: C-c C-e P p + #+findex: org-publish-current-project + Publish the project containing the current file. + +- {{{kbd(C-c C-e P f)}}} (~org-publish-current-file~) :: + + #+kindex: C-c C-e P f + #+findex: org-publish-current-file + Publish only the current file. + +- {{{kbd(C-c C-e P a)}}} (~org-publish-all~) :: + + #+kindex: C-c C-e P a + #+findex: org-publish-all + Publish every project. + +#+vindex: org-publish-use-timestamps-flag +Org uses timestamps to track when a file has changed. The above +functions normally only publish changed files. You can override this +and force publishing of all files by giving a prefix argument to any +of the commands above, or by customizing the variable +~org-publish-use-timestamps-flag~. This may be necessary in +particular if files include other files via =SETUPFILE= or =INCLUDE= +keywords. + +* Working with Source Code +:PROPERTIES: +:DESCRIPTION: Export, evaluate, and tangle code blocks. +:END: +#+cindex: source code, working with + +Source code here refers to any plain text collection of computer +instructions, possibly with comments, written using a human-readable +programming language. Org can manage source code in an Org document +when the source code is identified with begin and end markers. +Working with source code begins with identifying source code blocks. +A source code block can be placed almost anywhere in an Org document; +it is not restricted to the preamble or the end of the document. +However, Org cannot manage a source code block if it is placed inside +an Org comment or within a fixed width section. + +Here is an example source code block in the Emacs Lisp language: + +#+begin_example +,#+BEGIN_SRC emacs-lisp + (defun org-xor (a b) + "Exclusive or." + (if a (not b) b)) +,#+END_SRC +#+end_example + +Source code blocks are one of many Org block types, which also include +"center", "comment", "dynamic", "example", "export", "quote", +"special", and "verse". This section pertains to blocks between +=#+BEGIN_SRC= and =#+END_SRC=. + +Details of Org's facilities for working with source code are described +in the following sections. + +** Features Overview +:PROPERTIES: +:DESCRIPTION: Enjoy the versatility of source blocks. +:END: + +Org can manage the source code in the block delimited by =#+BEGIN_SRC= +... =#+END_SRC= in several ways that can simplify housekeeping tasks +essential to modern source code maintenance. Org can edit, format, +extract, export, and publish source code blocks. Org can also compile +and execute a source code block, then capture the results. The Org +mode literature sometimes refers to source code blocks as /live code/ +blocks because they can alter the content of the Org document or the +material that it exports. Users can control how live they want each +source code block by tweaking the header arguments (see [[*Using Header +Arguments]]) for compiling, execution, extraction, and exporting. + +For editing and formatting a source code block, Org uses an +appropriate Emacs major mode that includes features specifically +designed for source code in that language. + +Org can extract one or more source code blocks and write them to one +or more source files---a process known as /tangling/ in literate +programming terminology. + +For exporting and publishing, Org's back-ends can format a source code +block appropriately, often with native syntax highlighting. + +For executing and compiling a source code block, the user can +configure Org to select the appropriate compiler. Org provides +facilities to collect the result of the execution or compiler output, +insert it into the Org document, and/or export it. In addition to +text results, Org can insert links to other data types, including +audio, video, and graphics. Org can also link a compiler error +message to the appropriate line in the source code block. + +An important feature of Org's management of source code blocks is the +ability to pass variables, functions, and results to one another using +a common syntax for source code blocks in any language. Although most +literate programming facilities are restricted to one language or +another, Org's language-agnostic approach lets the literate programmer +match each programming task with the appropriate computer language and +to mix them all together in a single Org document. This +interoperability among languages explains why Org's source code +management facility was named /Org Babel/ by its originators, Eric +Schulte and Dan Davison. + +Org mode fulfills the promise of easy verification and maintenance of +publishing reproducible research by keeping text, data, code, +configuration settings of the execution environment, the results of +the execution, and associated narratives, claims, references, and +internal and external links in a single Org document. + +** Structure of Code Blocks +:PROPERTIES: +:DESCRIPTION: Code block syntax described. +:END: +#+cindex: code block, structure +#+cindex: source code, block structure +#+cindex: @samp{NAME} keyword, in source blocks +#+cindex: @samp{BEGIN_SRC} + +Org offers two ways to structure source code in Org documents: in +a source code block, and directly inline. Both specifications are +shown below. + +A source code block conforms to this structure: + +#+begin_example +,#+NAME: +,#+BEGIN_SRC
+ +,#+END_SRC +#+end_example + +Do not be put-off by having to remember the source block syntax. Org +mode offers a command for wrapping existing text in a block (see +[[*Structure Templates]]). Org also works with other completion systems +in Emacs, some of which predate Org and have custom domain-specific +languages for defining templates. Regular use of templates reduces +errors, increases accuracy, and maintains consistency. + +#+cindex: source code, inline +An inline code block conforms to this structure: + +: src_{} + +#+texinfo: @noindent +or + +: src_[
]{} + +- =#+NAME: = :: + + Optional. Names the source block so it can be called, like + a function, from other source blocks or inline code to evaluate or + to capture the results. Code from other blocks, other files, and + from table formulas (see [[*The Spreadsheet]]) can use the name to + reference a source block. This naming serves the same purpose as + naming Org tables. Org mode requires unique names. For duplicate + names, Org mode's behavior is undefined. + +- =#+BEGIN_SRC= ... =#+END_SRC= :: + + Mandatory. They mark the start and end of a block that Org + requires. The =#+BEGIN_SRC= line takes additional arguments, as + described next. + +- == :: + + #+cindex: language, in code blocks + Mandatory. It is the identifier of the source code language in the + block. See [[*Languages]], for identifiers of supported languages. + +- == :: + + #+cindex: switches, in code blocks + Optional. Switches provide finer control of the code execution, + export, and format (see the discussion of switches in [[*Literal + Examples]]). + +- =
= :: + + #+cindex: header arguments, in code blocks + Optional. Heading arguments control many aspects of evaluation, + export and tangling of code blocks (see [[*Using Header Arguments]]). + Using Org's properties feature, header arguments can be selectively + applied to the entire buffer or specific sub-trees of the Org + document. + +- == :: + + Source code in the dialect of the specified language identifier. + +** Using Header Arguments +:PROPERTIES: +:DESCRIPTION: Different ways to set header arguments. +:END: + +Org comes with many header arguments common to all languages. New +header arguments are added for specific languages as they become +available for use in source code blocks. A header argument is +specified with an initial colon followed by the argument's name in +lowercase. + +Since header arguments can be set in several ways, Org prioritizes +them in case of overlaps or conflicts by giving local settings +a higher priority. Header values in function calls, for example, +override header values from global defaults. + +*** System-wide header arguments +:PROPERTIES: +:UNNUMBERED: notoc +:END: +#+vindex: org-babel-default-header-args + +#+vindex: org-babel-default-header-args +System-wide values of header arguments can be specified by customizing +the ~org-babel-default-header-args~ variable, which defaults to the +following values: + +#+begin_example +:session => "none" +:results => "replace" +:exports => "code" +:cache => "no" +:noweb => "no" +#+end_example + +The example below sets =:noweb= header arguments to =yes=, which makes +Org expand =:noweb= references by default. + +#+begin_src emacs-lisp +(setq org-babel-default-header-args + (cons '(:noweb . "yes") + (assq-delete-all :noweb org-babel-default-header-args))) +#+end_src + +#+cindex: language specific default header arguments +#+cindex: default header arguments per language +Each language can have separate default header arguments by +customizing the variable ~org-babel-default-header-args:~, where +{{{var()}}} is the name of the language. For details, see the +language-specific online documentation at +https://orgmode.org/worg/org-contrib/babel/. + +*** Header arguments in Org mode properties +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +For header arguments applicable to the buffer, use =PROPERTY= keyword +anywhere in the Org file (see [[*Property Syntax]]). + +The following example makes all the R code blocks execute in the same +session. Setting =:results= to =silent= ignores the results of +executions for all blocks, not just R code blocks; no results inserted +for any block. + +#+begin_example +,#+PROPERTY: header-args:R :session *R* +,#+PROPERTY: header-args :results silent +#+end_example + +#+vindex: org-use-property-inheritance +Header arguments set through Org's property drawers (see [[*Property +Syntax]]) apply at the sub-tree level on down. Since these property +drawers can appear anywhere in the file hierarchy, Org uses outermost +call or source block to resolve the values. Org ignores +~org-use-property-inheritance~ setting. + +In this example, =:cache= defaults to =yes= for all code blocks in the +sub-tree. + +#+begin_example +,* sample header + :PROPERTIES: + :header-args: :cache yes + :END: +#+end_example + +#+kindex: C-c C-x p +#+findex: org-set-property +Properties defined through ~org-set-property~ function, bound to +{{{kbd(C-c C-x p)}}}, apply to all active languages. They override +properties set in ~org-babel-default-header-args~. + +#+cindex: language specific header arguments properties +#+cindex: header arguments per language +Language-specific header arguments are also read from properties +=header-args:= where {{{var()}}} is the language +identifier. For example, + +#+begin_example +,* Heading + :PROPERTIES: + :header-args:clojure: :session *clojure-1* + :header-args:R: :session *R* + :END: +,** Subheading + :PROPERTIES: + :header-args:clojure: :session *clojure-2* + :END: +#+end_example + +#+texinfo: @noindent +would force separate sessions for Clojure blocks in =Heading= and +=Subheading=, but use the same session for all R blocks. Blocks in +=Subheading= inherit settings from =Heading=. + +*** Code block specific header arguments +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +Header arguments are most commonly set at the source code block level, +on the =#+BEGIN_SRC= line. Arguments set at this level take +precedence over those set in the ~org-babel-default-header-args~ +variable, and also those set as header properties. + +In the following example, setting =:results= to =silent= makes it +ignore results of the code execution. Setting =:exports= to =code= +exports only the body of the code block to HTML or LaTeX. + +#+begin_example +,#+NAME: factorial +,#+BEGIN_SRC haskell :results silent :exports code :var n=0 + fac 0 = 1 + fac n = n * fac (n-1) +,#+END_SRC +#+end_example + +The same header arguments in an inline code block: + +: src_haskell[:exports both]{fac 5} + +#+cindex: @samp{HEADER}, keyword +Code block header arguments can span multiple lines using =#+HEADER:= +on each line. Note that Org currently accepts the plural spelling of +=#+HEADER:= only as a convenience for backward-compatibility. It may +be removed at some point. + +Multi-line header arguments on an unnamed code block: + +#+begin_example +,#+HEADER: :var data1=1 +,#+BEGIN_SRC emacs-lisp :var data2=2 + (message "data1:%S, data2:%S" data1 data2) +,#+END_SRC + +,#+RESULTS: +: data1:1, data2:2 +#+end_example + +Multi-line header arguments on a named code block: + +#+begin_example +,#+NAME: named-block +,#+HEADER: :var data=2 +,#+BEGIN_SRC emacs-lisp + (message "data:%S" data) +,#+END_SRC + +,#+RESULTS: named-block + : data:2 +#+end_example + +*** Header arguments in function calls +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +Header arguments in function calls are the most specific and override +all other settings in case of an overlap. They get the highest +priority. Two =#+CALL:= examples are shown below. For the complete +syntax of =CALL= keyword, see [[*Evaluating Code Blocks]]. + +In this example, =:exports results= header argument is applied to the +evaluation of the =#+CALL:= line. + +: #+CALL: factorial(n=5) :exports results + +In this example, =:session special= header argument is applied to the +evaluation of =factorial= code block. + +: #+CALL: factorial[:session special](n=5) + +** Environment of a Code Block +:PROPERTIES: +:DESCRIPTION: Arguments, sessions, working directory... +:END: + +*** Passing arguments +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: passing arguments to code blocks +#+cindex: arguments, in code blocks +#+cindex: @samp{var}, header argument +Use =var= for passing arguments to source code blocks. The specifics +of variables in code blocks vary by the source language and are +covered in the language-specific documentation. The syntax for =var=, +however, is the same for all languages. This includes declaring +a variable, and assigning a default value. + +The following syntax is used to pass arguments to code blocks using +the =var= header argument. + +: :var NAME=ASSIGN + +#+texinfo: @noindent +{{{var(NAME)}}} is the name of the variable bound in the code block +body. {{{var(ASSIGN)}}} is a literal value, such as a string, +a number, a reference to a table, a list, a literal example, another +code block---with or without arguments---or the results of evaluating +a code block. + +Here are examples of passing values by reference: + +- table :: + + A table named with a =NAME= keyword. + + #+begin_example + ,#+NAME: example-table + | 1 | + | 2 | + | 3 | + | 4 | + + ,#+NAME: table-length + ,#+BEGIN_SRC emacs-lisp :var table=example-table + (length table) + ,#+END_SRC + + ,#+RESULTS: table-length + : 4 + #+end_example + + When passing a table, you can treat specially the row, or the + column, containing labels for the columns, or the rows, in the + table. + + #+cindex: @samp{colnames}, header argument + The =colnames= header argument accepts =yes=, =no=, or =nil= values. + The default value is =nil=: if an input table has column + names---because the second row is a horizontal rule---then Org + removes the column names, processes the table, puts back the column + names, and then writes the table to the results block. Using =yes=, + Org does the same to the first row, even if the initial table does + not contain any horizontal rule. When set to =no=, Org does not + pre-process column names at all. + + #+begin_example + ,#+NAME: less-cols + | a | + |---| + | b | + | c | + + ,#+BEGIN_SRC python :var tab=less-cols :colnames nil + return [[val + '*' for val in row] for row in tab] + ,#+END_SRC + + ,#+RESULTS: + | a | + |----| + | b* | + | c* | + #+end_example + + #+cindex: @samp{rownames}, header argument + Similarly, the =rownames= header argument can take two values: =yes= + or =no=. When set to =yes=, Org removes the first column, processes + the table, puts back the first column, and then writes the table to + the results block. The default is =no=, which means Org does not + pre-process the first column. Note that Emacs Lisp code blocks + ignore =rownames= header argument because of the ease of + table-handling in Emacs. + + #+begin_example + ,#+NAME: with-rownames + | one | 1 | 2 | 3 | 4 | 5 | + | two | 6 | 7 | 8 | 9 | 10 | + + ,#+BEGIN_SRC python :var tab=with-rownames :rownames yes + return [[val + 10 for val in row] for row in tab] + ,#+END_SRC + + ,#+RESULTS: + | one | 11 | 12 | 13 | 14 | 15 | + | two | 16 | 17 | 18 | 19 | 20 | + #+end_example + +- list :: + + A simple named list. + + #+begin_example + ,#+NAME: example-list + - simple + - not + - nested + - list + + ,#+BEGIN_SRC emacs-lisp :var x=example-list + (print x) + ,#+END_SRC + + ,#+RESULTS: + | simple | list | + #+end_example + + Note that only the top level list items are passed along. Nested + list items are ignored. + +- code block without arguments :: + + A code block name, as assigned by =NAME= keyword from the example + above, optionally followed by parentheses. + + #+begin_example + ,#+BEGIN_SRC emacs-lisp :var length=table-length() + (* 2 length) + ,#+END_SRC + + ,#+RESULTS: + : 8 + #+end_example + +- code block with arguments :: + + A code block name, as assigned by =NAME= keyword, followed by + parentheses and optional arguments passed within the parentheses. + + #+begin_example + ,#+NAME: double + ,#+BEGIN_SRC emacs-lisp :var input=8 + (* 2 input) + ,#+END_SRC + + ,#+RESULTS: double + : 16 + + ,#+NAME: squared + ,#+BEGIN_SRC emacs-lisp :var input=double(input=1) + (* input input) + ,#+END_SRC + + ,#+RESULTS: squared + : 4 + #+end_example + +- literal example :: + + A literal example block named with a =NAME= keyword. + + #+begin_example + ,#+NAME: literal-example + ,#+BEGIN_EXAMPLE + A literal example + on two lines + ,#+END_EXAMPLE + + ,#+NAME: read-literal-example + ,#+BEGIN_SRC emacs-lisp :var x=literal-example + (concatenate #'string x " for you.") + ,#+END_SRC + + ,#+RESULTS: read-literal-example + : A literal example + : on two lines for you. + #+end_example + +Indexing variable values enables referencing portions of a variable. +Indexes are 0 based with negative values counting backwards from the +end. If an index is separated by commas then each subsequent section +indexes as the next dimension. Note that this indexing occurs +/before/ other table-related header arguments are applied, such as +=hlines=, =colnames= and =rownames=. The following example assigns +the last cell of the first row the table =example-table= to the +variable =data=: + +#+begin_example +,#+NAME: example-table +| 1 | a | +| 2 | b | +| 3 | c | +| 4 | d | + +,#+BEGIN_SRC emacs-lisp :var data=example-table[0,-1] + data +,#+END_SRC + +,#+RESULTS: +: a +#+end_example + +Two integers separated by a colon reference a range of variable +values. In that case the entire inclusive range is referenced. For +example the following assigns the middle three rows of =example-table= +to =data=. + +#+begin_example +,#+NAME: example-table +| 1 | a | +| 2 | b | +| 3 | c | +| 4 | d | +| 5 | 3 | + +,#+BEGIN_SRC emacs-lisp :var data=example-table[1:3] + data +,#+END_SRC + +,#+RESULTS: +| 2 | b | +| 3 | c | +| 4 | d | +#+end_example + +To pick the entire range, use an empty index, or the single character +=*=. =0:-1= does the same thing. Example below shows how to +reference the first column only. + +#+begin_example +,#+NAME: example-table +| 1 | a | +| 2 | b | +| 3 | c | +| 4 | d | + +,#+BEGIN_SRC emacs-lisp :var data=example-table[,0] + data +,#+END_SRC + +,#+RESULTS: +| 1 | 2 | 3 | 4 | +#+end_example + +Index referencing can be used for tables and code blocks. Index +referencing can handle any number of dimensions. Commas delimit +multiple dimensions, as shown below. + +#+begin_example +,#+NAME: 3D +,#+BEGIN_SRC emacs-lisp + '(((1 2 3) (4 5 6) (7 8 9)) + ((10 11 12) (13 14 15) (16 17 18)) + ((19 20 21) (22 23 24) (25 26 27))) +,#+END_SRC + +,#+BEGIN_SRC emacs-lisp :var data=3D[1,,1] + data +,#+END_SRC + +,#+RESULTS: +| 11 | 14 | 17 | +#+end_example + +Note that row names and column names are not removed prior to variable +indexing. You need to take them into account, even when =colnames= or +=rownames= header arguments remove them. + +Emacs lisp code can also set the values for variables. To +differentiate a value from Lisp code, Org interprets any value +starting with =(=, =[=, ='= or =`= as Emacs Lisp code. The result of +evaluating that code is then assigned to the value of that variable. +The following example shows how to reliably query and pass the file +name of the Org mode buffer to a code block using headers. We need +reliability here because the file's name could change once the code in +the block starts executing. + +#+begin_example +,#+BEGIN_SRC sh :var filename=(buffer-file-name) :exports both + wc -w $filename +,#+END_SRC +#+end_example + +Note that values read from tables and lists are not mistakenly +evaluated as Emacs Lisp code, as illustrated in the following example. + +#+begin_example +,#+NAME: table +| (a b c) | + +,#+HEADER: :var data=table[0,0] +,#+BEGIN_SRC perl + $data +,#+END_SRC + +,#+RESULTS: +: (a b c) +#+end_example + +*** Using sessions +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: using sessions in code blocks +#+cindex: @samp{session}, header argument +Two code blocks can share the same environment. The =session= header +argument is for running multiple source code blocks under one session. +Org runs code blocks with the same session name in the same +interpreter process. + +- =none= :: + + Default. Each code block gets a new interpreter process to execute. + The process terminates once the block is evaluated. + +- {{{var(STRING)}}} :: + + Any string besides =none= turns that string into the name of that + session. For example, =:session STRING= names it =STRING=. If + =session= has no value, then the session name is derived from the + source language identifier. Subsequent blocks with the same source + code language use the same session. Depending on the language, + state variables, code from other blocks, and the overall interpreted + environment may be shared. Some interpreted languages support + concurrent sessions when subsequent source code language blocks + change session names. + +Only languages that provide interactive evaluation can have session +support. Not all languages provide this support, such as C and ditaa. +Even languages, such as Python and Haskell, that do support +interactive evaluation impose limitations on allowable language +constructs that can run interactively. Org inherits those limitations +for those code blocks running in a session. + +*** Choosing a working directory +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: working directory, in a code block +#+cindex: @samp{dir}, header argument +#+cindex: @samp{mkdirp}, header argument +The =dir= header argument specifies the default directory during code +block execution. If it is absent, then the directory associated with +the current buffer is used. In other words, supplying =:dir +DIRECTORY= temporarily has the same effect as changing the current +directory with {{{kbd(M-x cd RET DIRECTORY)}}}, and then not setting +=dir=. Under the surface, =dir= simply sets the value of the Emacs +variable ~default-directory~. Setting =mkdirp= header argument to +a non-~nil~ value creates the directory, if necessary. + +For example, to save the plot file in the =Work/= folder of the home +directory---notice tilde is expanded: + +#+begin_example +,#+BEGIN_SRC R :file myplot.png :dir ~/Work + matplot(matrix(rnorm(100), 10), type="l") +,#+END_SRC +#+end_example + +To evaluate the code block on a remote machine, supply a remote +directory name using Tramp syntax. For example: + +#+begin_example +,#+BEGIN_SRC R :file plot.png :dir /scp:dand@yakuba.princeton.edu: + plot(1:10, main=system("hostname", intern=TRUE)) +,#+END_SRC +#+end_example + +Org first captures the text results as usual for insertion in the Org +file. Then Org also inserts a link to the remote file, thanks to +Emacs Tramp. Org constructs the remote path to the file name from +=dir= and ~default-directory~, as illustrated here: + +: [[file:/scp:dand@yakuba.princeton.edu:/home/dand/plot.png][plot.png]] + +When =dir= is used with =session=, Org sets the starting directory for +a new session. But Org does not alter the directory of an already +existing session. + +Do not use =dir= with =:exports results= or with =:exports both= to +avoid Org inserting incorrect links to remote files. That is because +Org does not expand ~default directory~ to avoid some underlying +portability issues. + +*** Inserting headers and footers +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: headers, in code blocks +#+cindex: footers, in code blocks +#+cindex: @samp{prologue}, header argument +The =prologue= header argument is for appending to the top of the code +block for execution, like a reset instruction. For example, you may +use =:prologue "reset"= in a Gnuplot code block or, for every such +block: + +#+begin_src emacs-lisp +(add-to-list 'org-babel-default-header-args:gnuplot + '((:prologue . "reset"))) + +#+end_src + +#+cindex: @samp{epilogue}, header argument +Likewise, the value of the =epilogue= header argument is for appending +to the end of the code block for execution. + +** Evaluating Code Blocks +:PROPERTIES: +:DESCRIPTION: Place results of evaluation in the Org buffer. +:END: +#+cindex: code block, evaluating +#+cindex: source code, evaluating +#+cindex: @samp{RESULTS}, keyword + +A note about security: With code evaluation comes the risk of harm. +Org safeguards by prompting for user's permission before executing any +code in the source block. To customize this safeguard, or disable it, +see [[*Code Evaluation and Security Issues]]. + +*** How to evaluate source code +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +Org captures the results of the code block evaluation and inserts them +in the Org file, right after the code block. The insertion point is +after a newline and the =RESULTS= keyword. Org creates the =RESULTS= +keyword if one is not already there. + +By default, Org enables only Emacs Lisp code blocks for execution. +See [[*Languages]] to enable other languages. + +#+kindex: C-c C-c +#+kindex: C-c C-v e +#+findex: org-babel-execute-src-block +Org provides many ways to execute code blocks. {{{kbd(C-c C-c)}}} or +{{{kbd(C-c C-v e)}}} with the point on a code block[fn:141] calls the +~org-babel-execute-src-block~ function, which executes the code in the +block, collects the results, and inserts them in the buffer. + +#+cindex: @samp{CALL}, keyword +#+vindex: org-babel-inline-result-wrap +By calling a named code block[fn:142] from an Org mode buffer or +a table. Org can call the named code blocks from the current Org mode +buffer or from the "Library of Babel" (see [[*Library of Babel]]). + +The syntax for =CALL= keyword is: + +#+begin_example +,#+CALL: () +,#+CALL: []() +#+end_example + +The syntax for inline named code blocks is: + +#+begin_example +... call_() ... +... call_[]()[] ... +#+end_example + +When inline syntax is used, the result is wrapped based on the +variable ~org-babel-inline-result-wrap~, which by default is set to +~"=%s="~ to produce verbatim text suitable for markup. + +- == :: + + This is the name of the code block (see [[*Structure of Code Blocks]]) + to be evaluated in the current document. If the block is located in + another file, start == with the file name followed by + a colon. For example, in order to execute a block named =clear-data= + in =file.org=, you can write the following: + + : #+CALL: file.org:clear-data() + +- == :: + + Org passes arguments to the code block using standard function call + syntax. For example, a =#+CALL:= line that passes =4= to a code + block named =double=, which declares the header argument =:var n=2=, + would be written as: + + : #+CALL: double(n=4) + + #+texinfo: @noindent + Note how this function call syntax is different from the header + argument syntax. + +- == :: + + Org passes inside header arguments to the named code block using the + header argument syntax. Inside header arguments apply to code block + evaluation. For example, =[:results output]= collects results + printed to stdout during code execution of that block. Note how + this header argument syntax is different from the function call + syntax. + +- == :: + + End header arguments affect the results returned by the code block. + For example, =:results html= wraps the results in a =#+BEGIN_EXPORT + html= block before inserting the results in the Org buffer. + +*** Limit code block evaluation +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: @samp{eval}, header argument +#+cindex: control code block evaluation +The =eval= header argument can limit evaluation of specific code +blocks and =CALL= keyword. It is useful for protection against +evaluating untrusted code blocks by prompting for a confirmation. + +- =never= or =no= :: + + Org never evaluates the source code. + +- =query= :: + + Org prompts the user for permission to evaluate the source code. + +- =never-export= or =no-export= :: + + Org does not evaluate the source code when exporting, yet the user + can evaluate it interactively. + +- =query-export= :: + + Org prompts the user for permission to evaluate the source code + during export. + +If =eval= header argument is not set, then Org determines whether to +evaluate the source code from the ~org-confirm-babel-evaluate~ +variable (see [[*Code Evaluation and Security Issues]]). + +*** Cache results of evaluation +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: @samp{cache}, header argument +#+cindex: cache results of code evaluation +The =cache= header argument is for caching results of evaluating code +blocks. Caching results can avoid re-evaluating a code block that +have not changed since the previous run. To benefit from the cache +and avoid redundant evaluations, the source block must have a result +already present in the buffer, and neither the header +arguments---including the value of =var= references---nor the text of +the block itself has changed since the result was last computed. This +feature greatly helps avoid long-running calculations. For some edge +cases, however, the cached results may not be reliable. + +The caching feature is best for when code blocks are pure functions, +that is functions that return the same value for the same input +arguments (see [[*Environment of a Code Block]]), and that do not have +side effects, and do not rely on external variables other than the +input arguments. Functions that depend on a timer, file system +objects, and random number generators are clearly unsuitable for +caching. + +A note of warning: when =cache= is used in a session, caching may +cause unexpected results. + +When the caching mechanism tests for any source code changes, it does +not expand noweb style references (see [[*Noweb Reference Syntax]]). + +The =cache= header argument can have one of two values: =yes= or =no=. + +- =no= :: + + Default. No caching of results; code block evaluated every time. + +- =yes= :: + + Whether to run the code or return the cached results is determined + by comparing the SHA1 hash value of the combined code block and + arguments passed to it. This hash value is packed on the + =#+RESULTS:= line from previous evaluation. When hash values match, + Org does not evaluate the code block. When hash values mismatch, + Org evaluates the code block, inserts the results, recalculates the + hash value, and updates =#+RESULTS:= line. + +In this example, both functions are cached. But =caller= runs only if +the result from =random= has changed since the last run. + +#+begin_example +,#+NAME: random +,#+BEGIN_SRC R :cache yes + runif(1) +,#+END_SRC + +,#+RESULTS[a2a72cd647ad44515fab62e144796432793d68e1]: random +0.4659510825295 + +,#+NAME: caller +,#+BEGIN_SRC emacs-lisp :var x=random :cache yes + x +,#+END_SRC + +,#+RESULTS[bec9c8724e397d5df3b696502df3ed7892fc4f5f]: caller +0.254227238707244 +#+end_example + +** Results of Evaluation +:PROPERTIES: +:DESCRIPTION: Choosing a results type, post-processing... +:END: +#+cindex: code block, results of evaluation +#+cindex: source code, results of evaluation + +#+cindex: @samp{results}, header argument +How Org handles results of a code block execution depends on many +header arguments working together. The primary determinant, however, +is the =results= header argument. It accepts four classes of options. +Each code block can take only one option per class: + +- Collection :: + + For how the results should be collected from the code block; + +- Type :: + + For which type of result the code block will return; affects how Org + processes and inserts results in the Org buffer; + +- Format :: + + For the result; affects how Org processes results; + +- Handling :: + + For inserting results once they are properly formatted. + +*** Collection +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +Collection options specify the results. Choose one of the options; +they are mutually exclusive. + +- =value= :: + + Default for most Babel libraries[fn:142]. Functional mode. Org + gets the value by wrapping the code in a function definition in the + language of the source block. That is why when using =:results + value=, code should execute like a function and return a value. For + languages like Python, an explicit ~return~ statement is mandatory + when using =:results value=. Result is the value returned by the + last statement in the code block. + + When evaluating the code block in a session (see [[*Environment of + a Code Block]]), Org passes the code to an interpreter running as an + interactive Emacs inferior process. Org gets the value from the + source code interpreter's last statement output. Org has to use + language-specific methods to obtain the value. For example, from + the variable ~_~ in Ruby, and the value of ~.Last.value~ in R. + +- =output= :: + + Scripting mode. Org passes the code to an external process running + the interpreter. Org returns the contents of the standard output + stream as text results. + + When using a session, Org passes the code to the interpreter running + as an interactive Emacs inferior process. Org concatenates any text + output from the interpreter and returns the collection as a result. + +*** Type +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +Type tells what result types to expect from the execution of the code +block. Choose one of the options; they are mutually exclusive. The +default behavior is to automatically determine the result type. + +#+attr_texinfo: :sep , +- =table=, =vector= :: + + Interpret the results as an Org table. If the result is a single + value, create a table with one row and one column. Usage example: + =:results value table=. + + #+cindex: @samp{hlines}, header argument + In-between each table row or below the table headings, sometimes + results have horizontal lines, which are also known as "hlines". + The =hlines= argument with the default =no= value strips such lines + from the input table. For most code, this is desirable, or else + those =hline= symbols raise unbound variable errors. A =yes= + accepts such lines, as demonstrated in the following example. + + #+begin_example + ,#+NAME: many-cols + | a | b | c | + |---+---+---| + | d | e | f | + |---+---+---| + | g | h | i | + + ,#+NAME: no-hline + ,#+BEGIN_SRC python :var tab=many-cols :hlines no + return tab + ,#+END_SRC + + ,#+RESULTS: no-hline + | a | b | c | + | d | e | f | + | g | h | i | + + ,#+NAME: hlines + ,#+BEGIN_SRC python :var tab=many-cols :hlines yes + return tab + ,#+END_SRC + + ,#+RESULTS: hlines + | a | b | c | + |---+---+---| + | d | e | f | + |---+---+---| + | g | h | i | + #+end_example + +- =list= :: + + Interpret the results as an Org list. If the result is a single + value, create a list of one element. + +- =scalar=, =verbatim= :: + + Interpret literally and insert as quoted text. Do not create + a table. Usage example: =:results value verbatim=. + +- =file= :: + + Interpret as a filename. Save the results of execution of the code + block to that file, then insert a link to it. You can control both + the filename and the description associated to the link. + + #+cindex: @samp{file}, header argument + #+cindex: @samp{output-dir}, header argument + Org first tries to generate the filename from the value of the + =file= header argument and the directory specified using the + =output-dir= header arguments. If =output-dir= is not specified, + Org assumes it is the current directory. + + #+begin_example + ,#+BEGIN_SRC asymptote :results value file :file circle.pdf :output-dir img/ + size(2cm); + draw(unitcircle); + ,#+END_SRC + #+end_example + + #+cindex: @samp{file-ext}, header argument + If =file= header argument is missing, Org generates the base name of + the output file from the name of the code block, and its extension + from the =file-ext= header argument. In that case, both the name + and the extension are mandatory. + + #+begin_example + ,#+name: circle + ,#+BEGIN_SRC asymptote :results value file :file-ext pdf + size(2cm); + draw(unitcircle); + ,#+END_SRC + #+end_example + + #+cindex: @samp{file-desc}, header argument + The =file-desc= header argument defines the description (see + [[*Link Format]]) for the link. If =file-desc= is present but has no value, + the =file= value is used as the link description. When this + argument is not present, the description is omitted. + + #+cindex: @samp{sep}, header argument + By default, Org assumes that a table written to a file has + TAB-delimited output. You can choose a different separator with + the =sep= header argument. + + #+cindex: @samp{file-mode}, header argument + The =file-mode= header argument defines the file permissions. To + make it executable, use =:file-mode (identity #o755)=. + + #+begin_example + ,#+BEGIN_SRC shell :results file :file script.sh :file-mode (identity #o755) + echo "#!/bin/bash" + echo "echo Hello World" + ,#+END_SRC + #+end_example + +*** Format +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +Format pertains to the type of the result returned by the code block. +Choose one of the options; they are mutually exclusive. The default +follows from the type specified above. + +#+attr_texinfo: :sep , +- =code= :: + + Result enclosed in a code block. Useful for parsing. Usage + example: =:results value code=. + +- =drawer= :: + + Result wrapped in a =RESULTS= drawer. Useful for containing =raw= + or =org= results for later scripting and automated processing. + Usage example: =:results value drawer=. + +- =html= :: + + Results enclosed in a =BEGIN_EXPORT html= block. Usage example: + =:results value html=. + +- =latex= :: + + Results enclosed in a =BEGIN_EXPORT latex= block. Usage example: + =:results value latex=. + +- =link=, =graphics= :: + + When used along with =file= type, the result is a link to the file + specified in =:file= header argument. However, unlike plain =file= + type, nothing is written to the disk. The block is used for its + side-effects only, as in the following example: + + #+begin_example + ,#+begin_src shell :results file link :file "download.tar.gz" + wget -c "http://example.com/download.tar.gz" + ,#+end_src + #+end_example + +- =org= :: + + Results enclosed in a =BEGIN_SRC org= block. For comma-escape, + either {{{kbd(TAB)}}} in the block, or export the file. Usage + example: =:results value org=. + +- =pp= :: + + Result converted to pretty-print source code. Enclosed in a code + block. Languages supported: Emacs Lisp, Python, and Ruby. Usage + example: =:results value pp=. + +- =raw= :: + + Interpreted as raw Org mode. Inserted directly into the buffer. + Aligned if it is a table. Usage example: =:results value raw=. + +#+cindex: @samp{wrap}, header argument +The =wrap= header argument unconditionally marks the results block by +appending strings to =#+BEGIN_= and =#+END_=. If no string is +specified, Org wraps the results in a =#+BEGIN_results= +... =#+END_results= block. It takes precedent over the =results= +value listed above. E.g., + +#+begin_example +,#+BEGIN_SRC emacs-lisp :results html :wrap EXPORT markdown +"Welcome back to the 90's" +,#+END_SRC + +,#+RESULTS: +,#+BEGIN_EXPORT markdown +Welcome back to the 90's +,#+END_EXPORT +#+end_example + +*** Handling +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +Handling options after collecting the results. + +- =silent= :: + + Do not insert results in the Org mode buffer, but echo them in the + minibuffer. Usage example: =:results output silent=. + +- =replace= :: + + Default. Insert results in the Org buffer. Remove previous + results. Usage example: =:results output replace=. + +- =append= :: + + Append results to the Org buffer. Latest results are at the bottom. + Does not remove previous results. Usage example: =:results output + append=. + +- =prepend= :: + + Prepend results to the Org buffer. Latest results are at the top. + Does not remove previous results. Usage example: =:results output + prepend=. + +*** Post-processing +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: @samp{post}, header argument +#+cindex: @samp{*this*}, in @samp{post} header argument +The =post= header argument is for post-processing results from block +evaluation. When =post= has any value, Org binds the results to +~*this*~ variable for easy passing to =var= header argument +specifications (see [[*Environment of a Code Block]]). That makes results +available to other code blocks, or even for direct Emacs Lisp code +execution. + +The following two examples illustrate =post= header argument in +action. The first one shows how to attach an =ATTR_LATEX= keyword +using =post=. + +#+begin_example +,#+NAME: attr_wrap +,#+BEGIN_SRC sh :var data="" :var width="\\textwidth" :results output + echo "#+ATTR_LATEX: :width $width" + echo "$data" +,#+END_SRC + +,#+HEADER: :file /tmp/it.png +,#+BEGIN_SRC dot :post attr_wrap(width="5cm", data=*this*) :results drawer + digraph{ + a -> b; + b -> c; + c -> a; + } +,#+end_src + +,#+RESULTS: +:RESULTS: +,#+ATTR_LATEX :width 5cm +[[file:/tmp/it.png]] +:END: +#+end_example + +The second example shows use of =colnames= header argument in =post= +to pass data between code blocks. + +#+begin_example +,#+NAME: round-tbl +,#+BEGIN_SRC emacs-lisp :var tbl="" fmt="%.3f" + (mapcar (lambda (row) + (mapcar (lambda (cell) + (if (numberp cell) + (format fmt cell) + cell)) + row)) + tbl) +,#+end_src + +,#+BEGIN_SRC R :colnames yes :post round-tbl[:colnames yes](*this*) + set.seed(42) + data.frame(foo=rnorm(1)) +,#+END_SRC + +,#+RESULTS: +| foo | +|-------| +| 1.371 | +#+end_example + +** Exporting Code Blocks +:PROPERTIES: +:DESCRIPTION: Export contents and/or results. +:END: +#+cindex: code block, exporting +#+cindex: source code, exporting + +It is possible to export the /code/ of code blocks, the /results/ of +code block evaluation, /both/ the code and the results of code block +evaluation, or /none/. Org defaults to exporting /code/ for most +languages. For some languages, such as ditaa, Org defaults to +/results/. To export just the body of code blocks, see [[*Literal +Examples]]. To selectively export sub-trees of an Org document, see +[[*Exporting]]. + +#+cindex: @samp{exports}, header argument +The =exports= header argument is to specify if that part of the Org +file is exported to, say, HTML or LaTeX formats. + +- =code= :: + + The default. The body of code is included into the exported file. + Example: =:exports code=. + +- =results= :: + + The results of evaluation of the code is included in the exported + file. Example: =:exports results=. + +- =both= :: + + Both the code and results of evaluation are included in the exported + file. Example: =:exports both=. + +- =none= :: + + Neither the code nor the results of evaluation is included in the + exported file. Whether the code is evaluated at all depends on + other options. Example: =:exports none=. + +#+vindex: org-export-use-babel +To stop Org from evaluating code blocks to speed exports, use the +header argument =:eval never-export= (see [[*Evaluating Code Blocks]]). +To stop Org from evaluating code blocks for greater security, set the +~org-export-use-babel~ variable to ~nil~, but understand that header +arguments will have no effect. + +Turning off evaluation comes in handy when batch processing. For +example, markup languages for wikis, which have a high risk of +untrusted code. Stopping code block evaluation also stops evaluation +of all header arguments of the code block. This may not be desirable +in some circumstances. So during export, to allow evaluation of just +the header arguments but not any code evaluation in the source block, +set =:eval never-export= (see [[*Evaluating Code Blocks]]). + +Org never evaluates code blocks in commented sub-trees when exporting +(see [[*Comment Lines]]). On the other hand, Org does evaluate code +blocks in sub-trees excluded from export (see [[*Export Settings]]). + +** Extracting Source Code +:PROPERTIES: +:DESCRIPTION: Create pure source code files. +:END: +#+cindex: tangling +#+cindex: source code, extracting +#+cindex: code block, extracting source code + +Extracting source code from code blocks is a basic task in literate +programming. Org has features to make this easy. In literate +programming parlance, documents on creation are /woven/ with code and +documentation, and on export, the code is tangled for execution by +a computer. Org facilitates weaving and tangling for producing, +maintaining, sharing, and exporting literate programming documents. +Org provides extensive customization options for extracting source +code. + +When Org tangles code blocks, it expands, merges, and transforms them. +Then Org recomposes them into one or more separate files, as +configured through the options. During this tangling process, Org +expands variables in the source code, and resolves any noweb style +references (see [[*Noweb Reference Syntax]]). + +*** Header arguments +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+cindex: @samp{tangle}, header argument +The =tangle= header argument specifies if the code block is exported +to source file(s). + +- =yes= :: + + Export the code block to source file. The file name for the source + file is derived from the name of the Org file, and the file + extension is derived from the source code language identifier. + Example: =:tangle yes=. + +- =no= :: + + The default. Do not extract the code in a source code file. + Example: =:tangle no=. + +- {{{var(FILENAME)}}} :: + + Export the code block to source file whose file name is derived from + any string passed to the =tangle= header argument. Org derives the + file name as being relative to the directory of the Org file's + location. Example: =:tangle FILENAME=. + +#+cindex: @samp{mkdirp}, header argument +The =mkdirp= header argument creates parent directories for tangled +files if the directory does not exist. A =yes= value enables +directory creation whereas =no= inhibits it. + +#+cindex: @samp{comments}, header argument +The =comments= header argument controls inserting comments into +tangled files. These are above and beyond whatever comments may +already exist in the code block. + +- =no= :: + + The default. Do not insert any extra comments during tangling. + +- =link= :: + + Wrap the code block in comments. Include links pointing back to the + place in the Org file from where the code was tangled. + +- =yes= :: + + Kept for backward compatibility; same as =link=. + +- =org= :: + + Nearest headline text from Org file is inserted as comment. The + exact text that is inserted is picked from the leading context of + the source block. + +- =both= :: + + Includes both =link= and =org= options. + +- =noweb= :: + + Includes =link= option, expands noweb references (see [[*Noweb + Reference Syntax]]), and wraps them in link comments inside the body + of the code block. + +#+cindex: @samp{padline}, header argument +The =padline= header argument controls insertion of newlines to pad +source code in the tangled file. + +- =yes= :: + + Default. Insert a newline before and after each code block in the + tangled file. + +- =no= :: + + Do not insert newlines to pad the tangled code blocks. + +#+cindex: @samp{shebang}, header argument +The =shebang= header argument can turn results into executable script +files. By setting it to a string value---for example, =:shebang +"#!/bin/bash"=---Org inserts that string as the first line of the +tangled file that the code block is extracted to. Org then turns on +the tangled file's executable permission. + +#+cindex: @samp{tangle-mode}, header argument +The =tangle-mode= header argument specifies what permissions to set +for tangled files by ~set-file-modes~. For example, to make +a read-only tangled file, use =:tangle-mode (identity #o444)=. To +make it executable, use =:tangle-mode (identity #o755)=. It also +overrides executable permission granted by =shebang=. When multiple +source code blocks tangle to a single file with different and +conflicting =tangle-mode= header arguments, Org's behavior is +undefined. + +#+cindex: @samp{no-expand}, header argument +By default Org expands code blocks during tangling. The =no-expand= +header argument turns off such expansions. Note that one side-effect +of expansion by ~org-babel-expand-src-block~ also assigns values (see +[[*Environment of a Code Block]]) to variables. Expansions also replace +noweb references with their targets (see [[*Noweb Reference Syntax]]). +Some of these expansions may cause premature assignment, hence this +option. This option makes a difference only for tangling. It has no +effect when exporting since code blocks for execution have to be +expanded anyway. + +*** Functions +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +- ~org-babel-tangle~ :: + + #+findex: org-babel-tangle + #+kindex: C-c C-v t + Tangle the current file. Bound to {{{kbd(C-c C-v t)}}}. + + With prefix argument only tangle the current code block. + +- ~org-babel-tangle-file~ :: + + #+findex: org-babel-tangle-file + #+kindex: C-c C-v f + Choose a file to tangle. Bound to {{{kbd(C-c C-v f)}}}. + +*** Hooks +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +- ~org-babel-post-tangle-hook~ :: + + #+vindex: org-babel-post-tangle-hook + This hook is run from within code files tangled by + ~org-babel-tangle~, making it suitable for post-processing, + compilation, and evaluation of code in the tangled files. + +*** Jumping between code and Org +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +#+findex: org-babel-tangle-jump-to-org +Debuggers normally link errors and messages back to the source code. +But for tangled files, we want to link back to the Org file, not to +the tangled source file. To make this extra jump, Org uses +~org-babel-tangle-jump-to-org~ function with two additional source +code block header arguments: + +1. Set =padline= to true---this is the default setting. +2. Set =comments= to =link=, which makes Org insert links to the Org + file. + +** Languages +:PROPERTIES: +:DESCRIPTION: List of supported code block languages. +:END: +#+cindex: babel, languages +#+cindex: source code, languages +#+cindex: code block, languages + +Code blocks in the following languages are supported. + +#+attr_texinfo: :columns 0.25 0.25 0.25 0.20 +| Language | Identifier | Language | Identifier | +|------------+---------------+----------------+--------------| +| Asymptote | =asymptote= | Lisp | =lisp= | +| Awk | =awk= | Lua | =lua= | +| C | =C= | MATLAB | =matlab= | +| C++ | =C++=[fn:143] | Mscgen | =mscgen= | +| Clojure | =clojure= | Objective Caml | =ocaml= | +| CSS | =css= | Octave | =octave= | +| D | =D=[fn:144] | Org mode | =org= | +| ditaa | =ditaa= | Oz | =oz= | +| Emacs Calc | =calc= | Perl | =perl= | +| Emacs Lisp | =emacs-lisp= | Plantuml | =plantuml= | +| Eshell | =eshell= | Processing.js | =processing= | +| Fortran | =fortran= | Python | =python= | +| Gnuplot | =gnuplot= | R | =R= | +| GNU Screen | =screen= | Ruby | =ruby= | +| Graphviz | =dot= | Sass | =sass= | +| Haskell | =haskell= | Scheme | =scheme= | +| Java | =java= | Sed | =sed= | +| Javascript | =js= | shell | =sh= | +| LaTeX | =latex= | SQL | =sql= | +| Ledger | =ledger= | SQLite | =sqlite= | +| Lilypond | =lilypond= | Vala | =vala= | + +Additional documentation for some languages is at +https://orgmode.org/worg/org-contrib/babel/languages.html. + +#+vindex: org-babel-load-languages +By default, only Emacs Lisp is enabled for evaluation. To enable or +disable other languages, customize the ~org-babel-load-languages~ +variable either through the Emacs customization interface, or by +adding code to the init file as shown next. + +In this example, evaluation is disabled for Emacs Lisp, and enabled +for R. + +#+begin_src emacs-lisp +(org-babel-do-load-languages + 'org-babel-load-languages + '((emacs-lisp . nil) + (R . t))) +#+end_src + +Note that this is not the only way to enable a language. Org also +enables languages when loaded with ~require~ statement. For example, +the following enables execution of Clojure code blocks: + +#+begin_src emacs-lisp +(require 'ob-clojure) +#+end_src + +** Editing Source Code +:PROPERTIES: +:DESCRIPTION: Language major-mode editing. +:END: +#+cindex: code block, editing +#+cindex: source code, editing + +#+kindex: C-c ' +Use {{{kbd(C-c ')}}} to edit the current code block. It opens a new +major mode edit buffer containing the body of the source code block, +ready for any edits. Use {{{kbd(C-c ')}}} again to close the buffer +and return to the Org buffer. + +#+kindex: C-x C-s +#+vindex: org-edit-src-auto-save-idle-delay +#+cindex: auto-save, in code block editing +{{{kbd(C-x C-s)}}} saves the buffer and updates the contents of the +Org buffer. Set ~org-edit-src-auto-save-idle-delay~ to save the base +buffer after a certain idle delay time. Set +~org-edit-src-turn-on-auto-save~ to auto-save this buffer into +a separate file using Auto-save mode. + +While editing the source code in the major mode, the Org Src minor +mode remains active. It provides these customization variables as +described below. For even more variables, look in the customization +group ~org-edit-structure~. + +- ~org-src-lang-modes~ :: + + #+vindex: org-src-lang-modes + If an Emacs major-mode named ~-mode~ exists, where + {{{var()}}} is the language identifier from code block's + header line, then the edit buffer uses that major mode. Use this + variable to arbitrarily map language identifiers to major modes. + +- ~org-src-window-setup~ :: + + #+vindex: org-src-window-setup + For specifying Emacs window arrangement when the new edit buffer is + created. + +- ~org-src-preserve-indentation~ :: + + #+cindex: indentation, in code blocks + #+vindex: org-src-preserve-indentation + Default is ~nil~. Source code is indented. This indentation + applies during export or tangling, and depending on the context, may + alter leading spaces and tabs. When non-~nil~, source code is + aligned with the leftmost column. No lines are modified during + export or tangling, which is very useful for white-space sensitive + languages, such as Python. + +- ~org-src-ask-before-returning-to-edit-buffer~ :: + + #+vindex: org-src-ask-before-returning-to-edit-buffer + When ~nil~, Org returns to the edit buffer without further prompts. + The default prompts for a confirmation. + +#+vindex: org-src-fontify-natively +#+vindex: org-src-block-faces +Set ~org-src-fontify-natively~ to non-~nil~ to turn on native code +fontification in the /Org/ buffer. Fontification of code blocks can +give visual separation of text and code on the display page. To +further customize the appearance of ~org-block~ for specific +languages, customize ~org-src-block-faces~. The following example +shades the background of regular blocks, and colors source blocks only +for Python and Emacs Lisp languages. + +#+begin_src emacs-lisp +(require 'color) +(set-face-attribute 'org-block nil :background + (color-darken-name + (face-attribute 'default :background) 3)) + +(setq org-src-block-faces '(("emacs-lisp" (:background "#EEE2FF")) + ("python" (:background "#E5FFB8")))) +#+end_src + +** Noweb Reference Syntax +:PROPERTIES: +:DESCRIPTION: Literate programming in Org mode. +:END: +#+cindex: code block, noweb reference +#+cindex: syntax, noweb +#+cindex: source code, noweb reference + +#+cindex: @samp{noweb-ref}, header argument +Source code blocks can include references to other source code blocks, +using a noweb[fn:145] style syntax: + +: <> + +#+texinfo: @noindent +where {{{var(CODE-BLOCK-ID)}}} refers to either the =NAME= of a single +source code block, or a collection of one or more source code blocks +sharing the same =noweb-ref= header argument (see [[*Using Header +Arguments]]). Org can replace such references with the source code of +the block or blocks being referenced, or, in the case of a single +source code block named with =NAME=, with the results of an evaluation +of that block. + +#+cindex: @samp{noweb}, header argument +The =noweb= header argument controls expansion of noweb syntax +references. Expansions occur when source code blocks are evaluated, +tangled, or exported. + +- =no= :: + + Default. No expansion of noweb syntax references in the body of the + code when evaluating, tangling, or exporting. + +- =yes= :: + + Expansion of noweb syntax references in the body of the code block + when evaluating, tangling, or exporting. + +- =tangle= :: + + Expansion of noweb syntax references in the body of the code block + when tangling. No expansion when evaluating or exporting. + +- =no-export= :: + + Expansion of noweb syntax references in the body of the code block + when evaluating or tangling. No expansion when exporting. + +- =strip-export= :: + + Expansion of noweb syntax references in the body of the code block + when expanding prior to evaluating or tangling. Removes noweb + syntax references when exporting. + +- =eval= :: + + Expansion of noweb syntax references in the body of the code block + only before evaluating. + +In the most simple case, the contents of a single source block is +inserted within other blocks. Thus, in following example, + +#+begin_example +,#+NAME: initialization +,#+BEGIN_SRC emacs-lisp + (setq sentence "Never a foot too far, even.") +,#+END_SRC + +,#+BEGIN_SRC emacs-lisp :noweb yes + <> + (reverse sentence) +,#+END_SRC +#+end_example + +#+texinfo: @noindent +the second code block is expanded as + +#+begin_example +,#+BEGIN_SRC emacs-lisp :noweb yes + (setq sentence "Never a foot too far, even.") + (reverse sentence) +,#+END_SRC +#+end_example + +You may also include the contents of multiple blocks sharing a common +=noweb-ref= header argument, which can be set at the file, sub-tree, +or code block level. In the example Org file shown next, the body of +the source code in each block is extracted for concatenation to a pure +code file when tangled. + +#+begin_example +,#+BEGIN_SRC sh :tangle yes :noweb yes :shebang #!/bin/sh + <> +,#+END_SRC +,* the mount point of the fullest disk + :PROPERTIES: + :header-args: :noweb-ref fullest-disk + :END: + +,** query all mounted disks +,#+BEGIN_SRC sh + df \ +,#+END_SRC + +,** strip the header row +,#+BEGIN_SRC sh + |sed '1d' \ +,#+END_SRC + +,** output mount point of fullest disk +,#+BEGIN_SRC sh + |awk '{if (u < +$5) {u = +$5; m = $6}} END {print m}' +,#+END_SRC +#+end_example + +#+cindex: @samp{noweb-sep}, header argument +By default a newline separates each noweb reference concatenation. To +use a different separator, edit the =noweb-sep= header argument. + +Alternatively, Org can include the results of evaluation of a single +code block rather than its body. Evaluation occurs when parentheses, +possibly including arguments, are appended to the code block name, as +shown below. + +: <> + +Note that in this case, a code block name set by =NAME= keyword is +required; the reference set by =noweb-ref= will not work when +evaluation is desired. + +Here is an example that demonstrates how the exported content changes +when noweb style references are used with parentheses versus without. +Given: + +#+begin_example +,#+NAME: some-code +,#+BEGIN_SRC python :var num=0 :results output :exports none + print(num*10) +,#+END_SRC +#+end_example + +#+texinfo: @noindent +this code block: + +#+begin_example +,#+BEGIN_SRC text :noweb yes + <> +,#+END_SRC +#+end_example + +#+texinfo: @noindent +expands to: + +: print(num*10) + +Below, a similar noweb style reference is used, but with parentheses, +while setting a variable =num= to 10: + +#+begin_example +,#+BEGIN_SRC text :noweb yes + <> +,#+END_SRC +#+end_example + +#+texinfo: @noindent +Note that the expansion now contains the results of the code block +=some-code=, not the code block itself: + +: 100 + +Noweb insertions honor prefix characters that appear before the noweb +syntax reference. This behavior is illustrated in the following +example. Because the =<>= noweb reference appears behind the +SQL comment syntax, each line of the expanded noweb reference is +commented. With: + +#+begin_example +,#+NAME: example +,#+BEGIN_SRC text + this is the + multi-line body of example +,#+END_SRC +#+end_example + +#+texinfo: @noindent +this code block: + +#+begin_example +,#+BEGIN_SRC sql :noweb yes + ---<> +,#+END_SRC +#+end_example + +#+texinfo: @noindent +expands to: + +#+begin_example +,#+BEGIN_SRC sql :noweb yes + ---this is the + ---multi-line body of example +,#+END_SRC +#+end_example + +Since this change does not affect noweb replacement text without +newlines in them, inline noweb references are acceptable. + +This feature can also be used for management of indentation in +exported code snippets. With: + +#+begin_example +,#+NAME: if-true +,#+BEGIN_SRC python :exports none + print('do things when true') +,#+end_src + +,#+name: if-false +,#+begin_src python :exports none + print('do things when false') +,#+end_src +#+end_example + +#+texinfo: @noindent +this code block: + +#+begin_example +,#+begin_src python :noweb yes :results output + if true: + <> + else: + <> +,#+end_src +#+end_example + +#+texinfo: @noindent +expands to: + +#+begin_example +if true: + print('do things when true') +else: + print('do things when false') +#+end_example + +When in doubt about the outcome of a source code block expansion, you +can preview the results with the following command: + +- {{{kbd(C-c C-v v)}}} or {{{kbd(C-c C-v C-v)}}} (~org-babel-expand-src-block~) :: + + #+findex: org-babel-expand-src-block + #+kindex: C-c C-v v + #+kindex: C-c C-v C-v + Expand the current source code block according to its header + arguments and pop open the results in a preview buffer. + +** Library of Babel +:PROPERTIES: +:DESCRIPTION: Use and contribute to a library of useful code blocks. +:END: +#+cindex: babel, library of +#+cindex: source code, library +#+cindex: code block, library + +The "Library of Babel" is a collection of code blocks. Like +a function library, these code blocks can be called from other Org +files. A collection of useful code blocks is available on [[https://orgmode.org/worg/library-of-babel.html][Worg]]. For +remote code block evaluation syntax, see [[*Evaluating Code Blocks]]. + +#+kindex: C-c C-v i +#+findex: org-babel-lob-ingest +For any user to add code to the library, first save the code in +regular code blocks of an Org file, and then load the Org file with +~org-babel-lob-ingest~, which is bound to {{{kbd(C-c C-v i)}}}. + +** Key bindings and Useful Functions +:PROPERTIES: +:DESCRIPTION: Work quickly with code blocks. +:END: +#+cindex: code block, key bindings + +Many common Org mode key sequences are re-bound depending on +the context. + +Active key bindings in code blocks: + +#+kindex: C-c C-c +#+findex: org-babel-execute-src-block +#+kindex: C-c C-o +#+findex: org-babel-open-src-block-result +#+kindex: M-UP +#+findex: org-babel-load-in-session +#+kindex: M-DOWN +#+findex: org-babel-pop-to-session +#+attr_texinfo: :columns 0.2 0.55 +| Key binding | Function | +|--------------------+-----------------------------------| +| {{{kbd(C-c C-c)}}} | ~org-babel-execute-src-block~ | +| {{{kbd(C-c C-o)}}} | ~org-babel-open-src-block-result~ | +| {{{kbd(M-UP)}}} | ~org-babel-load-in-session~ | +| {{{kbd(M-DOWN)}}} | ~org-babel-pop-to-session~ | + +Active key bindings in Org mode buffer: + +#+kindex: C-c C-v p +#+kindex: C-c C-v C-p +#+kindex: C-c C-v n +#+kindex: C-c C-v C-n +#+kindex: C-c C-v e +#+kindex: C-c C-v C-e +#+kindex: C-c C-v o +#+kindex: C-c C-v C-o +#+kindex: C-c C-v v +#+kindex: C-c C-v C-v +#+kindex: C-c C-v u +#+kindex: C-c C-v C-u +#+kindex: C-c C-v g +#+kindex: C-c C-v C-g +#+kindex: C-c C-v r +#+kindex: C-c C-v C-r +#+kindex: C-c C-v b +#+kindex: C-c C-v C-b +#+kindex: C-c C-v s +#+kindex: C-c C-v C-s +#+kindex: C-c C-v d +#+kindex: C-c C-v C-d +#+kindex: C-c C-v t +#+kindex: C-c C-v C-t +#+kindex: C-c C-v f +#+kindex: C-c C-v C-f +#+kindex: C-c C-v c +#+kindex: C-c C-v C-c +#+kindex: C-c C-v j +#+kindex: C-c C-v C-j +#+kindex: C-c C-v l +#+kindex: C-c C-v C-l +#+kindex: C-c C-v i +#+kindex: C-c C-v C-i +#+kindex: C-c C-v I +#+kindex: C-c C-v C-I +#+kindex: C-c C-v z +#+kindex: C-c C-v C-z +#+kindex: C-c C-v a +#+kindex: C-c C-v C-a +#+kindex: C-c C-v h +#+kindex: C-c C-v C-h +#+kindex: C-c C-v x +#+kindex: C-c C-v C-x +#+findex: org-babel-previous-src-block +#+findex: org-babel-next-src-block +#+findex: org-babel-execute-maybe +#+findex: org-babel-open-src-block-result +#+findex: org-babel-expand-src-block +#+findex: org-babel-goto-src-block-head +#+findex: org-babel-goto-named-src-block +#+findex: org-babel-goto-named-result +#+findex: org-babel-execute-buffer +#+findex: org-babel-execute-subtree +#+findex: org-babel-demarcate-block +#+findex: org-babel-tangle +#+findex: org-babel-tangle-file +#+findex: org-babel-check-src-block +#+findex: org-babel-insert-header-arg +#+findex: org-babel-load-in-session +#+findex: org-babel-lob-ingest +#+findex: org-babel-view-src-block-info +#+findex: org-babel-switch-to-session-with-code +#+findex: org-babel-sha1-hash +#+findex: org-babel-describe-bindings +#+findex: org-babel-do-key-sequence-in-edit-buffer +#+attr_texinfo: :columns 0.45 0.55 +| Key binding | Function | +|------------------------------------------------+--------------------------------------------| +| {{{kbd(C-c C-v p)}}} or {{{kbd(C-c C-v C-p)}}} | ~org-babel-previous-src-block~ | +| {{{kbd(C-c C-v n)}}} or {{{kbd(C-c C-v C-n)}}} | ~org-babel-next-src-block~ | +| {{{kbd(C-c C-v e)}}} or {{{kbd(C-c C-v C-e)}}} | ~org-babel-execute-maybe~ | +| {{{kbd(C-c C-v o)}}} or {{{kbd(C-c C-v C-o)}}} | ~org-babel-open-src-block-result~ | +| {{{kbd(C-c C-v v)}}} or {{{kbd(C-c C-v C-v)}}} | ~org-babel-expand-src-block~ | +| {{{kbd(C-c C-v u)}}} or {{{kbd(C-c C-v C-u)}}} | ~org-babel-goto-src-block-head~ | +| {{{kbd(C-c C-v g)}}} or {{{kbd(C-c C-v C-g)}}} | ~org-babel-goto-named-src-block~ | +| {{{kbd(C-c C-v r)}}} or {{{kbd(C-c C-v C-r)}}} | ~org-babel-goto-named-result~ | +| {{{kbd(C-c C-v b)}}} or {{{kbd(C-c C-v C-b)}}} | ~org-babel-execute-buffer~ | +| {{{kbd(C-c C-v s)}}} or {{{kbd(C-c C-v C-s)}}} | ~org-babel-execute-subtree~ | +| {{{kbd(C-c C-v d)}}} or {{{kbd(C-c C-v C-d)}}} | ~org-babel-demarcate-block~ | +| {{{kbd(C-c C-v t)}}} or {{{kbd(C-c C-v C-t)}}} | ~org-babel-tangle~ | +| {{{kbd(C-c C-v f)}}} or {{{kbd(C-c C-v C-f)}}} | ~org-babel-tangle-file~ | +| {{{kbd(C-c C-v c)}}} or {{{kbd(C-c C-v C-c)}}} | ~org-babel-check-src-block~ | +| {{{kbd(C-c C-v j)}}} or {{{kbd(C-c C-v C-j)}}} | ~org-babel-insert-header-arg~ | +| {{{kbd(C-c C-v l)}}} or {{{kbd(C-c C-v C-l)}}} | ~org-babel-load-in-session~ | +| {{{kbd(C-c C-v i)}}} or {{{kbd(C-c C-v C-i)}}} | ~org-babel-lob-ingest~ | +| {{{kbd(C-c C-v I)}}} or {{{kbd(C-c C-v C-I)}}} | ~org-babel-view-src-block-info~ | +| {{{kbd(C-c C-v z)}}} or {{{kbd(C-c C-v C-z)}}} | ~org-babel-switch-to-session-with-code~ | +| {{{kbd(C-c C-v a)}}} or {{{kbd(C-c C-v C-a)}}} | ~org-babel-sha1-hash~ | +| {{{kbd(C-c C-v h)}}} or {{{kbd(C-c C-v C-h)}}} | ~org-babel-describe-bindings~ | +| {{{kbd(C-c C-v x)}}} or {{{kbd(C-c C-v C-x)}}} | ~org-babel-do-key-sequence-in-edit-buffer~ | + +** Batch Execution +:PROPERTIES: +:DESCRIPTION: Call functions from the command line. +:END: +#+cindex: code block, batch execution +#+cindex: source code, batch execution + +Org mode features, including working with source code facilities can +be invoked from the command line. This enables building shell scripts +for batch processing, running automated system tasks, and expanding +Org mode's usefulness. + +The sample script shows batch processing of multiple files using +~org-babel-tangle~. + +#+begin_example +#!/bin/sh +# Tangle files with Org mode +# +emacs -Q --batch --eval " + (progn + (require 'ob-tangle) + (dolist (file command-line-args-left) + (with-current-buffer (find-file-noselect file) + (org-babel-tangle)))) + " "$@" +#+end_example + +* Miscellaneous +:PROPERTIES: +:DESCRIPTION: All the rest which did not fit elsewhere. +:END: + +** Completion +:PROPERTIES: +:DESCRIPTION: @kbd{M-@key{TAB}} guesses completions. +:END: +#+cindex: completion, of @TeX{} symbols +#+cindex: completion, of TODO keywords +#+cindex: completion, of dictionary words +#+cindex: completion, of option keywords +#+cindex: completion, of tags +#+cindex: completion, of property keys +#+cindex: completion, of link abbreviations +#+cindex: @TeX{} symbol completion +#+cindex: TODO keywords completion +#+cindex: dictionary word completion +#+cindex: option keyword completion +#+cindex: tag completion +#+cindex: link abbreviations, completion of + +Org has in-buffer completions. Unlike minibuffer completions, which +are useful for quick command interactions, Org's in-buffer completions +are more suitable for content creation in Org documents. Type one or +more letters and invoke the hot key to complete the text in-place. +Depending on the context and the keys, Org offers different types of +completions. No minibuffer is involved. Such mode-specific hot keys +have become an integral part of Emacs and Org provides several +shortcuts. + +- {{{kbd(M-TAB)}}} :: + #+kindex: M-TAB + + Complete word at point. + + - At the beginning of an empty headline, complete TODO keywords. + + - After =\=, complete TeX symbols supported by the exporter. + + - After =:= in a headline, complete tags. Org deduces the list of + tags from the =TAGS= in-buffer option (see [[*Setting Tags]]), the + variable ~org-tag-alist~, or from all tags used in the current + buffer. + + - After =:= and not in a headline, complete property keys. The list + of keys is constructed dynamically from all keys used in the + current buffer. + + - After =[[=, complete link abbreviations (see [[*Link Abbreviations]]). + + - After =[[*=, complete headlines in the current buffer so that they + can be used in search links like: =[[*find this headline]]= + + - After =#+=, complete the special keywords like =TYP_TODO= or + file-specific =OPTIONS=. After option keyword is complete, + pressing {{{kbd(M-TAB)}}} again inserts example settings for this + keyword. + + - After =STARTUP= keyword, complete startup items. + + - When point is anywhere else, complete dictionary words using + Ispell. + +** Structure Templates +:PROPERTIES: +:DESCRIPTION: Quick insertion of structural elements. +:END: +#+cindex: template insertion +#+cindex: insertion, of templates + +With just a few keystrokes, it is possible to insert empty structural +blocks, such as =#+BEGIN_SRC= ... =#+END_SRC=, or to wrap existing +text in such a block. + +- {{{kbd(C-c C-\,)}}} (~org-insert-structure-template~) :: + + #+findex: org-insert-structure-template + #+kindex: C-c C-, + Prompt for a type of block structure, and insert the block at point. + If the region is active, it is wrapped in the block. First prompts + the user for keys, which are used to look up a structure type from + the variable below. If the key is {{{kbd(TAB)}}}, {{{kbd(RET)}}}, + or {{{kbd(SPC)}}}, the user is prompted to enter a block type. + +#+vindex: org-structure-template-alist +Available structure types are defined in +~org-structure-template-alist~, see the docstring for adding or +changing values. + +#+cindex: Tempo +#+cindex: template expansion +#+cindex: insertion, of templates +#+vindex: org-tempo-keywords-alist +Org Tempo expands snippets to structures defined in +~org-structure-template-alist~ and ~org-tempo-keywords-alist~. For +example, {{{kbd(< s TAB)}}} creates a code block. Enable it by +customizing ~org-modules~ or add =(require 'org-tempo)= to your Emacs +init file[fn:146]. + +#+attr_texinfo: :columns 0.1 0.9 +| {{{kbd(a)}}} | =#+BEGIN_EXPORT ascii= ... =#+END_EXPORT= | +| {{{kbd(c)}}} | =#+BEGIN_CENTER= ... =#+END_CENTER= | +| {{{kbd(C)}}} | =#+BEGIN_COMMENT= ... =#+END_COMMENT= | +| {{{kbd(e)}}} | =#+BEGIN_EXAMPLE= ... =#+END_EXAMPLE= | +| {{{kbd(E)}}} | =#+BEGIN_EXPORT= ... =#+END_EXPORT= | +| {{{kbd(h)}}} | =#+BEGIN_EXPORT html= ... =#+END_EXPORT= | +| {{{kbd(l)}}} | =#+BEGIN_EXPORT latex= ... =#+END_EXPORT= | +| {{{kbd(q)}}} | =#+BEGIN_QUOTE= ... =#+END_QUOTE= | +| {{{kbd(s)}}} | =#+BEGIN_SRC= ... =#+END_SRC= | +| {{{kbd(v)}}} | =#+BEGIN_VERSE= ... =#+END_VERSE= | + +** Speed Keys +:PROPERTIES: +:DESCRIPTION: Electric commands at the beginning of a headline. +:END: +#+cindex: speed keys + +Single keystrokes can execute custom commands in an Org file when +point is on a headline. Without the extra burden of a meta or +modifier key, Speed Keys can speed navigation or execute custom +commands. Besides faster navigation, Speed Keys may come in handy on +small mobile devices that do not have full keyboards. Speed Keys may +also work on TTY devices known for their problems when entering Emacs +key chords. + +#+vindex: org-use-speed-commands +By default, Org has Speed Keys disabled. To activate Speed Keys, set +the variable ~org-use-speed-commands~ to a non-~nil~ value. To +trigger a Speed Key, point must be at the beginning of an Org +headline, before any of the stars. + +#+vindex: org-speed-commands-user +#+findex: org-speed-command-help +Org comes with a pre-defined list of Speed Keys. To add or modify +Speed Keys, customize the variable, ~org-speed-commands-user~. For +more details, see the variable's docstring. With Speed Keys +activated, {{{kbd(M-x org-speed-command-help)}}}, or {{{kbd(?)}}} when +point is at the beginning of an Org headline, shows currently active +Speed Keys, including the user-defined ones. + +** A Cleaner Outline View +:PROPERTIES: +:DESCRIPTION: Getting rid of leading stars in the outline. +:ALT_TITLE: Clean View +:END: +#+cindex: hiding leading stars +#+cindex: dynamic indentation +#+cindex: odd-levels-only outlines +#+cindex: clean outline view + +Org's outline with stars and no indents can look cluttered for short +documents. For /book-like/ long documents, the effect is not as +noticeable. Org provides an alternate stars and indentation scheme, +as shown on the right in the following table. It displays only one +star and indents text to line up with the heading: + +#+begin_example +,* Top level headline | * Top level headline +,** Second level | * Second level +,*** Third level | * Third level +some text | some text +,*** Third level | * Third level +more text | more text +,* Another top level headline | * Another top level headline +#+end_example + +Org can achieve this in two ways, (1) by just displaying the buffer in +this way without changing it, or (2) by actually indenting every line +in the desired amount with hard spaces and hiding leading stars. + +*** Org Indent Mode + +#+cindex: Indent mode +#+findex: org-indent-mode +To display the buffer in the indented view, activate Org Indent minor +mode, using {{{kbd(M-x org-indent-mode)}}}. Text lines that are not +headlines are prefixed with virtual spaces to vertically align with +the headline text[fn:147]. + +#+vindex: org-indent-indentation-per-level +To make more horizontal space, the headlines are shifted by two +characters. Configure ~org-indent-indentation-per-level~ variable for +a different number. + +#+vindex: org-indent-mode-turns-on-hiding-stars +#+vindex: org-indent-mode-turns-off-org-adapt-indentation +By default, Org Indent mode turns off ~org-adapt-indentation~ and does +hide leading stars by locally setting ~org-hide-leading-stars~ to ~t~: +only one star on each headline is visible, the rest are masked with +the same font color as the background. If you want to customize this +default behavior, see ~org-indent-mode-turns-on-hiding-stars~ and +~org-indent-mode-turns-off-org-adapt-indentation~. + +#+vindex: org-startup-indented +To globally turn on Org Indent mode for all files, customize the +variable ~org-startup-indented~. To control it for individual files, +use =STARTUP= keyword as follows: + +: #+STARTUP: indent +: #+STARTUP: noindent + +*** Hard indentation + +It is possible to use hard spaces to achieve the indentation instead, +if the bare ASCII file should have the indented look also outside +Emacs[fn:148]. With Org's support, you have to indent all lines to +line up with the outline headers. You would use these +settings[fn:149]: + + #+begin_src emacs-lisp + (setq org-adapt-indentation t + org-hide-leading-stars t + org-odd-levels-only t) + #+end_src + +- /Indentation of text below headlines/ (~org-adapt-indentation~) :: + + #+vindex: org-adapt-indentation + The first setting modifies paragraph filling, line wrapping, and + structure editing commands to preserving or adapting the indentation + as appropriate. + +- /Hiding leading stars/ (~org-hide-leading-stars~) :: + + #+vindex: org-hide-leading-stars + #+vindex: org-hide, face + The second setting makes leading stars invisible by applying the + face ~org-hide~ to them. For per-file preference, use these file + =STARTUP= options: + + #+begin_example + ,#+STARTUP: hidestars + ,#+STARTUP: showstars + #+end_example + +- /Odd levels/ (~org-odd-levels-only~) :: + + #+vindex: org-odd-levels-only + The third setting makes Org use only odd levels, 1, 3, 5, ..., in + the outline to create more indentation. On a per-file level, + control this with: + + #+begin_example + ,#+STARTUP: odd + ,#+STARTUP: oddeven + #+end_example + + To convert a file between single and double stars layouts, use + {{{kbd(M-x org-convert-to-odd-levels)}}} and {{{kbd(M-x + org-convert-to-oddeven-levels)}}}. + +** Execute commands in the active region +:PROPERTIES: +:DESCRIPTION: Execute commands on multiple items in Org or agenda view. +:END: + +#+vindex: org-loop-over-headlines-in-active-region +When in an Org buffer and the region is active, some commands will +apply to all the subtrees in the active region. For example, hitting +{{{kbd(C-c C-s)}}} when multiple headlines are within the active region will +successively prompt you for a new schedule date and time. To disable +this, set the option ~org-loop-over-headlines-in-active-region~ to +non-~t~, activate the region and run the command normally. + +#+vindex: org-agenda-loop-over-headlines-in-active-region +~org-agenda-loop-over-headlines-in-active-region~ is the equivalent +option of the agenda buffer, where you can also use [[*Bulk remote editing selected entries][bulk editing of +selected entries]]. + +Not all commands can loop in the active region and what subtrees or +headlines are considered can be refined: see the docstrings of these +options for more details. + +** Dynamic Headline Numbering +:PROPERTIES: +:DESCRIPTION: Display and update outline numbering. +:END: + +#+cindex: Org Num mode +#+cindex: number headlines +The Org Num minor mode, toggled with {{{kbd(M-x org-num-mode)}}}, +displays outline numbering on top of headlines. It also updates it +automatically upon changes to the structure of the document. + +#+vindex: org-num-max-level +#+vindex: org-num-skip-tags +#+vindex: org-num-skip-commented +#+vindex: org-num-skip-unnumbered +By default, all headlines are numbered. You can limit numbering to +specific headlines according to their level, tags, =COMMENT= keyword, +or =UNNUMBERED= property. Set ~org-num-max-level~, +~org-num-skip-tags~, ~org-num-skip-commented~, +~org-num-skip-unnumbered~, or ~org-num-skip-footnotes~ accordingly. + +#+vindex: org-num-skip-footnotes +If ~org-num-skip-footnotes~ is non-~nil~, footnotes sections (see +[[*Creating Footnotes]]) are not numbered either. + +#+vindex: org-num-face +#+vindex: org-num-format-function +You can control how the numbering is displayed by setting +~org-num-face~ and ~org-num-format-function~. + +#+vindex: org-startup-numerated +You can also turn this mode globally for all Org files by setting the +option ~org-startup-numerated~ to =t=, or locally on a file by using +=#+startup: num=. + +** The Very Busy {{{kbd(C-c C-c)}}} Key +:PROPERTIES: +:DESCRIPTION: When in doubt, press @kbd{C-c C-c}. +:END: +#+kindex: C-c C-c +#+cindex: @kbd{C-c C-c}, overview + +The {{{kbd(C-c C-c)}}} key in Org serves many purposes depending on +the context. It is probably the most over-worked, multi-purpose key +combination in Org. Its uses are well documented throughout this +manual, but here is a consolidated list for easy reference. + +- If column view (see [[*Column View]]) is on, exit column view. + +- If any highlights shown in the buffer from the creation of a sparse + tree, or from clock display, remove such highlights. + +- If point is in one of the special =KEYWORD= lines, scan the buffer + for these lines and update the information. Also reset the Org file + cache used to temporary store the contents of URLs used as values + for keywords like =SETUPFILE=. + +- If point is inside a table, realign the table. + +- If point is on a =TBLFM= keyword, re-apply the formulas to the + entire table. + +- If the current buffer is a capture buffer, close the note and file + it. With a prefix argument, also jump to the target location after + saving the note. + +- If point is on a =<<>>=, update radio targets and + corresponding links in this buffer. + +- If point is on a property line or at the start or end of a property + drawer, offer property commands. + +- If point is at a footnote reference, go to the corresponding + definition, and /vice versa/. + +- If point is on a statistics cookie, update it. + +- If point is in a plain list item with a checkbox, toggle the status + of the checkbox. + +- If point is on a numbered item in a plain list, renumber the ordered + list. + +- If point is on the =#+BEGIN= line of a dynamic block, the block is + updated. + +- If point is at a timestamp, fix the day name in the timestamp. + +** Summary of In-Buffer Settings +:PROPERTIES: +:DESCRIPTION: Overview of keywords. +:ALT_TITLE: In-buffer Settings +:END: +#+cindex: in-buffer settings +#+cindex: special keywords + +In-buffer settings start with =#+=, followed by a keyword, a colon, +and then a word for each setting. Org accepts multiple settings on +the same line. Org also accepts multiple lines for a keyword. This +manual describes these settings throughout. A summary follows here. + +#+cindex: refresh set-up +{{{kbd(C-c C-c)}}} activates any changes to the in-buffer settings. +Closing and reopening the Org file in Emacs also activates the +changes. + +#+attr_texinfo: :sep , +- =#+ARCHIVE: %s_done::= :: + + #+cindex: @samp{ARCHIVE}, keyword + #+vindex: org-archive-location + Sets the archive location of the agenda file. The corresponding + variable is ~org-archive-location~. + +- =#+CATEGORY= :: + + #+cindex: @samp{CATEGORY}, keyword + Sets the category of the agenda file, which applies to the entire + document. + +- =#+COLUMNS: %25ITEM ...= :: + + #+cindex: @samp{COLUMNS}, property + Set the default format for columns view. This format applies when + columns view is invoked in locations where no =COLUMNS= property + applies. + +- =#+CONSTANTS: name1=value1 ...= :: + + #+cindex: @samp{CONSTANTS}, keyword + #+vindex: org-table-formula-constants + #+vindex: org-table-formula + Set file-local values for constants that table formulas can use. + This line sets the local variable + ~org-table-formula-constants-local~. The global version of this + variable is ~org-table-formula-constants~. + +- =#+FILETAGS: :tag1:tag2:tag3:= :: + + #+cindex: @samp{FILETAGS}, keyword + Set tags that all entries in the file inherit from, including the + top-level entries. + +- =#+LINK: linkword replace= :: + + #+cindex: @samp{LINK}, keyword + #+vindex: org-link-abbrev-alist + Each line specifies one abbreviation for one link. Use multiple + =LINK= keywords for more, see [[*Link Abbreviations]]. The + corresponding variable is ~org-link-abbrev-alist~. + +- =#+PRIORITIES: highest lowest default= :: + + #+cindex: @samp{PRIORITIES}, keyword + #+vindex: org-priority-highest + #+vindex: org-priority-lowest + #+vindex: org-priority-default + This line sets the limits and the default for the priorities. All + three must be either letters A--Z or numbers 0--9. The highest + priority must have a lower ASCII number than the lowest priority. + +- =#+PROPERTY: Property_Name Value= :: + + #+cindex: @samp{PROPERTY}, keyword + This line sets a default inheritance value for entries in the + current buffer, most useful for specifying the allowed values of + a property. + +- =#+SETUPFILE: file= :: + + #+cindex: @samp{SETUPFILE}, keyword + The setup file or a URL pointing to such file is for additional + in-buffer settings. Org loads this file and parses it for any + settings in it only when Org opens the main file. If URL is + specified, the contents are downloaded and stored in a temporary + file cache. {{{kbd(C-c C-c)}}} on the settings line parses and + loads the file, and also resets the temporary file cache. Org also + parses and loads the document during normal exporting process. Org + parses the contents of this document as if it was included in the + buffer. It can be another Org file. To visit the file---not + a URL---use {{{kbd(C-c ')}}} while point is on the line with the + file name. + +- =#+STARTUP:= :: + + #+cindex: @samp{STARTUP}, keyword + Startup options Org uses when first visiting a file. + + #+vindex: org-startup-folded + The first set of options deals with the initial visibility of the + outline tree. The corresponding variable for global default + settings is ~org-startup-folded~ with a default value of + ~showeverything~. + + | =overview= | Top-level headlines only. | + | =content= | All headlines. | + | =showall= | No folding on any entry. | + | =showeverything= | Show even drawer contents. | + + #+vindex: org-startup-indented + Dynamic virtual indentation is controlled by the variable + ~org-startup-indented~[fn:150]. + + | =indent= | Start with Org Indent mode turned on. | + | =noindent= | Start with Org Indent mode turned off. | + + #+vindex: org-startup-numerated + Dynamic virtual numeration of headlines is controlled by the variable + ~org-startup-numerated~. + + | =num= | Start with Org num mode turned on. | + | =nonum= | Start with Org num mode turned off. | + + #+vindex: org-startup-align-all-tables + Aligns tables consistently upon visiting a file. The + corresponding variable is ~org-startup-align-all-tables~ with + ~nil~ as default value. + + | =align= | Align all tables. | + | =noalign= | Do not align tables on startup. | + + #+vindex: org-startup-shrink-all-tables + Shrink table columns with a width cookie. The corresponding + variable is ~org-startup-shrink-all-tables~ with ~nil~ as + default value. + + #+vindex: org-startup-with-inline-images + When visiting a file, inline images can be automatically + displayed. The corresponding variable is + ~org-startup-with-inline-images~, with a default value ~nil~ to + avoid delays when visiting a file. + + | =inlineimages= | Show inline images. | + | =noinlineimages= | Do not show inline images on startup. | + + #+vindex: org-log-done + #+vindex: org-log-note-clock-out + #+vindex: org-log-repeat + Logging the closing and reopening of TODO items and clock + intervals can be configured using these options (see variables + ~org-log-done~, ~org-log-note-clock-out~, and ~org-log-repeat~). + + | =logdone= | Record a timestamp when an item is marked as done. | + | =lognotedone= | Record timestamp and a note when DONE. | + | =nologdone= | Do not record when items are marked as done. | + | =logrepeat= | Record a time when reinstating a repeating item. | + | =lognoterepeat= | Record a note when reinstating a repeating item. | + | =nologrepeat= | Do not record when reinstating repeating item. | + | =lognoteclock-out= | Record a note when clocking out. | + | =nolognoteclock-out= | Do not record a note when clocking out. | + | =logreschedule= | Record a timestamp when scheduling time changes. | + | =lognotereschedule= | Record a note when scheduling time changes. | + | =nologreschedule= | Do not record when a scheduling date changes. | + | =logredeadline= | Record a timestamp when deadline changes. | + | =lognoteredeadline= | Record a note when deadline changes. | + | =nologredeadline= | Do not record when a deadline date changes. | + | =logrefile= | Record a timestamp when refiling. | + | =lognoterefile= | Record a note when refiling. | + | =nologrefile= | Do not record when refiling. | + + #+vindex: org-hide-leading-stars + #+vindex: org-odd-levels-only + Here are the options for hiding leading stars in outline + headings, and for indenting outlines. The corresponding + variables are ~org-hide-leading-stars~ and + ~org-odd-levels-only~, both with a default setting ~nil~ + (meaning =showstars= and =oddeven=). + + | =hidestars= | Make all but one of the stars starting a headline invisible. | + | =showstars= | Show all stars starting a headline. | + | =indent= | Virtual indentation according to outline level. | + | =noindent= | No virtual indentation according to outline level. | + | =odd= | Allow only odd outline levels (1, 3, ...). | + | =oddeven= | Allow all outline levels. | + + #+vindex: org-put-time-stamp-overlays + #+vindex: org-time-stamp-overlay-formats + To turn on custom format overlays over timestamps (variables + ~org-put-time-stamp-overlays~ and + ~org-time-stamp-overlay-formats~), use: + + | =customtime= | Overlay custom time format. | + + #+vindex: constants-unit-system + The following options influence the table spreadsheet (variable + ~constants-unit-system~). + + | =constcgs= | =constants.el= should use the c-g-s unit system. | + | =constSI= | =constants.el= should use the SI unit system. | + + #+vindex: org-footnote-define-inline + #+vindex: org-footnote-auto-label + #+vindex: org-footnote-auto-adjust + To influence footnote settings, use the following keywords. The + corresponding variables are ~org-footnote-define-inline~, + ~org-footnote-auto-label~, and ~org-footnote-auto-adjust~. + + | =fninline= | Define footnotes inline. | + | =fnnoinline= | Define footnotes in separate section. | + | =fnlocal= | Define footnotes near first reference, but not inline. | + | =fnprompt= | Prompt for footnote labels. | + | =fnauto= | Create =[fn:1]=-like labels automatically (default). | + | =fnconfirm= | Offer automatic label for editing or confirmation. | + | =fnadjust= | Automatically renumber and sort footnotes. | + | =nofnadjust= | Do not renumber and sort automatically. | + + #+vindex: org-hide-block-startup + To hide blocks on startup, use these keywords. The + corresponding variable is ~org-hide-block-startup~. + + | =hideblocks= | Hide all begin/end blocks on startup. | + | =nohideblocks= | Do not hide blocks on startup. | + + #+vindex: org-pretty-entities + The display of entities as UTF-8 characters is governed by the + variable ~org-pretty-entities~ and the keywords + + | =entitiespretty= | Show entities as UTF-8 characters where possible. | + | =entitiesplain= | Leave entities plain. | + +- =#+TAGS: TAG1(c1) TAG2(c2)= :: + + #+cindex: @samp{TAGS}, keyword + #+vindex: org-tag-alist + These lines (several such lines are allowed) specify the valid tags + in this file, and (potentially) the corresponding /fast tag + selection/ keys. The corresponding variable is ~org-tag-alist~. + +- =#+TODO:=, =#+SEQ_TODO:=, =#+TYP_TODO:= :: + + #+cindex: @samp{SEQ_TODO}, keyword + #+cindex: @samp{TODO}, keyword + #+cindex: @samp{TYP_TODO}, keyword + #+vindex: org-todo-keywords + These lines set the TODO keywords and their interpretation in the + current file. The corresponding variable is ~org-todo-keywords~. + +** Org Syntax +:PROPERTIES: +:DESCRIPTION: Formal description of Org's syntax. +:END: + +A reference document providing a formal description of Org's syntax is +available as [[https://orgmode.org/worg/dev/org-syntax.html][a draft on Worg]], written and maintained by Nicolas +Goaziou. It defines Org's core internal concepts such as "headlines", +"sections", "affiliated keywords", "(greater) elements" and "objects". +Each part of an Org document belongs to one of the previous +categories. + +To explore the abstract structure of an Org buffer, run this in +a buffer: + +: M-: (org-element-parse-buffer) + +#+texinfo: @noindent +It outputs a list containing the buffer's content represented as an +abstract structure. The export engine relies on the information +stored in this list. Most interactive commands---e.g., for structure +editing---also rely on the syntactic meaning of the surrounding +context. + +#+cindex: syntax checker +#+cindex: linter +#+findex: org-lint +You can probe the syntax of your documents with the command + +: M-x org-lint + +#+texinfo: @noindent +It runs a number of checks to find common mistakes. It then displays +their location in a dedicated buffer, along with a description and +a "trust level", since false-positive are possible. From there, you +can operate on the reports with the following keys: + +#+attr_texinfo: :columns 0.22 0.78 +| {{{kbd(C-j)}}}, {{{kbd(TAB)}}} | Display the offending line | +| {{{kbd(RET)}}} | Move point to the offending line | +| {{{kbd(g)}}} | Check the document again | +| {{{kbd(h)}}} | Hide all reports from the same checker | +| {{{kbd(i)}}} | Also remove them from all subsequent checks | +| {{{kbd(S)}}} | Sort reports by the column at point | + +** Context Dependent Documentation +:PROPERTIES: +:DESCRIPTION: Read documentation about current syntax. +:ALT_TITLE: Documentation Access +:END: +#+cindex: documentation +#+cindex: Info + +#+findex: org-info-find-node +#+kindex: C-c C-x I +{{{kbd(C-c C-x I)}}} in an Org file tries to open a suitable section +of the Org manual depending on the syntax at point. For example, +using it on a headline displays "Document Structure" section. + +{{{kbd(q)}}} closes the Info window. + +** Escape Character +:PROPERTIES: +:DESCRIPTION: Prevent Org from interpreting your writing. +:END: + +#+cindex: escape character +#+cindex: zero width space +You may sometimes want to write text that looks like Org syntax, but +should really read as plain text. Org may use a specific escape +character in some situations, i.e., a backslash in macros (see [[*Macro +Replacement]]) and links (see [[*Link Format]]), or a comma in source and +example blocks (see [[*Literal Examples]]). In the general case, however, +we suggest to use the zero width space. You can insert one with any +of the following: + +: C-x 8 zero width space +: C-x 8 200B + +For example, in order to write =[[1,2]]= as-is in your document, you +may write instead + +: [X[1,2]] + +where =X= denotes the zero width space character. + +** Code Evaluation and Security Issues +:PROPERTIES: +:DESCRIPTION: Org files evaluate in-line code. +:ALT_TITLE: Code Evaluation Security +:END: + +Unlike plain text, running code comes with risk. Each source code +block, in terms of risk, is equivalent to an executable file. Org +therefore puts a few confirmation prompts by default. This is to +alert the casual user from accidentally running untrusted code. + +For users who do not run code blocks or write code regularly, Org's +default settings should suffice. However, some users may want to +tweak the prompts for fewer interruptions. To weigh the risks of +automatic execution of code blocks, here are some details about code +evaluation. + +Org evaluates code in the following circumstances: + +- /Source code blocks/ :: + + Org evaluates source code blocks in an Org file during export. Org + also evaluates a source code block with the {{{kbd(C-c C-c)}}} key + chord. Users exporting or running code blocks must load files only + from trusted sources. Be wary of customizing variables that remove + or alter default security measures. + + #+attr_texinfo: :options org-confirm-babel-evaluate + #+begin_defopt + When ~t~, Org prompts the user for confirmation before executing + each code block. When ~nil~, Org executes code blocks without + prompting the user for confirmation. When this option is set to + a custom function, Org invokes the function with these two + arguments: the source code language and the body of the code block. + The custom function must return either a ~t~ or ~nil~, which + determines if the user is prompted. Each source code language can + be handled separately through this function argument. + #+end_defopt + + For example, here is how to execute ditaa code blocks without + prompting: + + #+begin_src emacs-lisp + (defun my-org-confirm-babel-evaluate (lang body) + (not (string= lang "ditaa"))) ;don't ask for ditaa + (setq org-confirm-babel-evaluate #'my-org-confirm-babel-evaluate) + #+end_src + +- /Following =shell= and =elisp= links/ :: + + Org has two link types that can directly evaluate code (see + [[*External Links]]). Because such code is not visible, these links + have a potential risk. Org therefore prompts the user when it + encounters such links. The customization variables are: + + #+attr_texinfo: :options org-link-shell-confirm-function + #+begin_defopt + Function that prompts the user before executing a shell link. + #+end_defopt + + #+attr_texinfo: :options org-link-elisp-confirm-function + #+begin_defopt + Function that prompts the user before executing an Emacs Lisp link. + #+end_defopt + +- /Formulas in tables/ :: + + Formulas in tables (see [[*The Spreadsheet]]) are code that is evaluated + either by the Calc interpreter, or by the Emacs Lisp interpreter. + +** Interaction with Other Packages +:PROPERTIES: +:DESCRIPTION: With other Emacs packages. +:ALT_TITLE: Interaction +:END: +#+cindex: packages, interaction with other + +Org's compatibility and the level of interaction with other Emacs +packages are documented here. + +*** Packages that Org cooperates with +:PROPERTIES: +:DESCRIPTION: Packages Org cooperates with. +:ALT_TITLE: Cooperation +:END: + +- =calc.el= by Dave Gillespie :: + #+cindex: @file{calc.el} + + Org uses the Calc package for implementing spreadsheet functionality + in its tables (see [[*The Spreadsheet]]). Org also uses Calc for + embedded calculations. See [[info:calc::Embedded Mode][GNU Emacs Calc Manual]]. + +- =constants.el= by Carsten Dominik :: + #+cindex: @file{constants.el} + #+vindex: org-table-formula-constants + + Org can use names for constants in formulas in tables. Org can also + use calculation suffixes for units, such as =M= for =Mega=. For + a standard collection of such constants, install the =constants= + package. Install version 2.0 of this package, available at + [[http://www.astro.uva.nl/~dominik/Tools]]. Org checks if the function + ~constants-get~ has been autoloaded. Installation instructions are + in the file =constants.el=. + +- =cdlatex.el= by Carsten Dominik :: + #+cindex: @file{cdlatex.el} + + Org mode can make use of the CDLaTeX package to efficiently enter + LaTeX fragments into Org files. See [[*Using CDLaTeX to enter math]]. + +- =imenu.el= by Ake Stenhoff and Lars Lindberg :: + #+cindex: @file{imenu.el} + + Imenu creates dynamic menus based on an index of items in a file. + Org mode supports Imenu menus. Enable it with a mode hook as + follows: + + #+begin_src emacs-lisp + (add-hook 'org-mode-hook + (lambda () (imenu-add-to-menubar "Imenu"))) + #+end_src + + #+vindex: org-imenu-depth + By default the index is two levels deep---you can modify the + depth using the option ~org-imenu-depth~. + +- =speedbar.el= by Eric\nbsp{}M.\nbsp{}Ludlam :: + #+cindex: @file{speedbar.el} + + Speedbar package creates a special Emacs frame for displaying files + and index items in files. Org mode supports Speedbar; users can + drill into Org files directly from the Speedbar. The {{{kbd(<)}}} + in the Speedbar frame tweaks the agenda commands to that file or to + a subtree. + +- =table.el= by Takaaki Ota :: + #+cindex: table editor, @file{table.el} + #+cindex: @file{table.el} + + Complex ASCII tables with automatic line wrapping, column- and + row-spanning, and alignment can be created using the Emacs table + package by Takaaki Ota. Org mode recognizes such tables and exports + them properly. {{{kbd(C-c ')}}} to edit these tables in a special + buffer, much like Org's code blocks. Because of interference with + other Org mode functionality, Takaaki Ota tables cannot be edited + directly in the Org buffer. + + - {{{kbd(C-c ')}}} (~org-edit-special~) :: + + #+kindex: C-c ' + #+findex: org-edit-special + Edit a =table.el= table. Works when point is in a =table.el= + table. + + - {{{kbd(C-c ~​)}}} (~org-table-create-with-table.el~) :: + + #+kindex: C-c ~ + #+findex: org-table-create-with-table.el + Insert a =table.el= table. If there is already a table at point, + this command converts it between the =table.el= format and the Org + mode format. See the documentation string of the command + ~org-convert-table~ for the restrictions under which this is + possible. + +*** Packages that conflict with Org mode +:PROPERTIES: +:DESCRIPTION: Packages that lead to conflicts. +:ALT_TITLE: Conflicts +:END: + +#+cindex: shift-selection +#+vindex: org-support-shift-select +In Emacs, shift-selection combines motions of point with shift key to +enlarge regions. Emacs sets this mode by default. This conflicts +with Org's use of {{{kbd(S-)}}} commands to change timestamps, +TODO keywords, priorities, and item bullet types, etc. Since +{{{kbd(S-)}}} commands outside of specific contexts do not do +anything, Org offers the variable ~org-support-shift-select~ for +customization. Org mode accommodates shift selection by (i) making it +available outside of the special contexts where special commands +apply, and (ii) extending an existing active region even if point +moves across a special context. + +- =cua.el= by Kim\nbsp{}F.\nbsp{}Storm :: + + #+cindex: @file{cua.el} + #+vindex: org-replace-disputed-keys + Org key bindings conflict with {{{kbd(S-)}}} keys used by + CUA mode. For Org to relinquish these bindings to CUA mode, + configure the variable ~org-replace-disputed-keys~. When set, Org + moves the following key bindings in Org files, and in the agenda + buffer---but not during date selection. + + #+attr_texinfo: :columns 0.4 0.4 + | {{{kbd(S-UP)}}} \rArr{} {{{kbd(M-p)}}} | {{{kbd(S-DOWN)}}} \rArr{} {{{kbd(M-n)}}} | + | {{{kbd(S-LEFT)}}} \rArr{} {{{kbd(M--)}}} | {{{kbd(S-RIGHT)}}} \rArr{} {{{kbd(M-+)}}} | + | {{{kbd(C-S-LEFT)}}} \rArr{} {{{kbd(M-S--)}}} | {{{kbd(C-S-RIGHT)}}} \rArr{} {{{kbd(M-S-+)}}} | + + #+vindex: org-disputed-keys + Yes, these are unfortunately more difficult to remember. If you + want to have other replacement keys, look at the variable + ~org-disputed-keys~. + +- =ecomplete.el= by Lars Magne Ingebrigtsen :: + + #+cindex: @file{ecomplete.el} + Ecomplete provides "electric" address completion in address header + lines in message buffers. Sadly Orgtbl mode cuts Ecomplete's power + supply: no completion happens when Orgtbl mode is enabled in message + buffers while entering text in address header lines. If one wants + to use ecomplete one should /not/ follow the advice to automagically + turn on Orgtbl mode in message buffers (see [[*The Orgtbl Minor Mode]]), + but instead---after filling in the message headers---turn on Orgtbl + mode manually when needed in the messages body. + +- =filladapt.el= by Kyle Jones :: + + #+cindex: @file{filladapt.el} + Org mode tries to do the right thing when filling paragraphs, list + items and other elements. Many users reported problems using both + =filladapt.el= and Org mode, so a safe thing to do is to disable + filladapt like this: + + #+begin_src emacs-lisp + (add-hook 'org-mode-hook 'turn-off-filladapt-mode) + #+end_src + +- =viper.el= by Michael Kifer :: + #+cindex: @file{viper.el} + #+kindex: C-c / + + Viper uses {{{kbd(C-c /)}}} and therefore makes this key not access + the corresponding Org mode command ~org-sparse-tree~. You need to + find another key for this command, or override the key in + ~viper-vi-global-user-map~ with + + #+begin_src emacs-lisp + (define-key viper-vi-global-user-map "C-c /" 'org-sparse-tree) + #+end_src + +- =windmove.el= by Hovav Shacham :: + #+cindex: @file{windmove.el} + + This package also uses the {{{kbd(S-)}}} keys, so everything + written in the paragraph above about CUA mode also applies here. If + you want to make the windmove function active in locations where Org + mode does not have special functionality on {{{kbd(S-)}}}, + add this to your configuration: + + #+begin_src emacs-lisp + ;; Make windmove work in Org mode: + (add-hook 'org-shiftup-final-hook 'windmove-up) + (add-hook 'org-shiftleft-final-hook 'windmove-left) + (add-hook 'org-shiftdown-final-hook 'windmove-down) + (add-hook 'org-shiftright-final-hook 'windmove-right) + #+end_src + +- =yasnippet.el= :: + + #+cindex: @file{yasnippet.el} + The way Org mode binds the {{{kbd(TAB)}}} key (binding to ~[tab]~ + instead of ~"\t"~) overrules YASnippet's access to this key. The + following code fixed this problem: + + #+begin_src emacs-lisp + (add-hook 'org-mode-hook + (lambda () + (setq-local yas/trigger-key [tab]) + (define-key yas/keymap [tab] 'yas/next-field-or-maybe-expand))) + #+end_src + + The latest version of YASnippet does not play well with Org mode. + If the above code does not fix the conflict, start by defining + the following function: + + #+begin_src emacs-lisp + (defun yas/org-very-safe-expand () + (let ((yas/fallback-behavior 'return-nil)) (yas/expand))) + #+end_src + + Then, tell Org mode to use that function: + + #+begin_src emacs-lisp + (add-hook 'org-mode-hook + (lambda () + (make-variable-buffer-local 'yas/trigger-key) + (setq yas/trigger-key [tab]) + (add-to-list 'org-tab-first-hook 'yas/org-very-safe-expand) + (define-key yas/keymap [tab] 'yas/next-field))) + #+end_src +** Using Org on a TTY +:PROPERTIES: +:DESCRIPTION: Using Org on a tty. +:ALT_TITLE: TTY Keys +:END: +#+cindex: tty key bindings + +Org provides alternative key bindings for TTY and modern mobile +devices that cannot perform movement commands on point and key +bindings with modifier keys. Some of these workarounds may be more +cumbersome than necessary. Users should look into customizing these +further based on their usage needs. For example, the normal +{{{kbd(S-)}}} for editing timestamp might be better with +{{{kbd(C-c .)}}} chord. + +#+attr_texinfo: :columns 0.2 0.28 0.15 0.21 +| Default | Alternative 1 | Speed key | Alternative 2 | +|----------------------+--------------------------+--------------+----------------------| +| {{{kbd(S-TAB)}}} | {{{kbd(C-u TAB)}}} | {{{kbd(C)}}} | | +| {{{kbd(M-LEFT)}}} | {{{kbd(C-c C-x l)}}} | {{{kbd(l)}}} | {{{kbd(Esc LEFT)}}} | +| {{{kbd(M-S-LEFT)}}} | {{{kbd(C-c C-x L)}}} | {{{kbd(L)}}} | | +| {{{kbd(M-RIGHT)}}} | {{{kbd(C-c C-x r)}}} | {{{kbd(r)}}} | {{{kbd(Esc RIGHT)}}} | +| {{{kbd(M-S-RIGHT)}}} | {{{kbd(C-c C-x R)}}} | {{{kbd(R)}}} | | +| {{{kbd(M-UP)}}} | {{{kbd(C-c C-x u)}}} | | {{{kbd(Esc UP)}}} | +| {{{kbd(M-S-UP)}}} | {{{kbd(C-c C-x U)}}} | {{{kbd(U)}}} | | +| {{{kbd(M-DOWN)}}} | {{{kbd(C-c C-x d)}}} | | {{{kbd(Esc DOWN)}}} | +| {{{kbd(M-S-DOWN)}}} | {{{kbd(C-c C-x D)}}} | {{{kbd(D)}}} | | +| {{{kbd(S-RET)}}} | {{{kbd(C-c C-x c)}}} | | | +| {{{kbd(M-RET)}}} | {{{kbd(C-c C-x m)}}} | | {{{kbd(Esc RET)}}} | +| {{{kbd(M-S-RET)}}} | {{{kbd(C-c C-x M)}}} | | | +| {{{kbd(S-LEFT)}}} | {{{kbd(C-c LEFT)}}} | | | +| {{{kbd(S-RIGHT)}}} | {{{kbd(C-c RIGHT)}}} | | | +| {{{kbd(S-UP)}}} | {{{kbd(C-c UP)}}} | | | +| {{{kbd(S-DOWN)}}} | {{{kbd(C-c DOWN)}}} | | | +| {{{kbd(C-S-LEFT)}}} | {{{kbd(C-c C-x LEFT)}}} | | | +| {{{kbd(C-S-RIGHT)}}} | {{{kbd(C-c C-x RIGHT)}}} | | | + +** Protocols for External Access +:PROPERTIES: +:DESCRIPTION: External access to Emacs and Org. +:ALT_TITLE: Protocols +:END: +#+cindex: protocols, for external access + +Org protocol is a tool to trigger custom actions in Emacs from +external applications. Any application that supports calling external +programs with an URL as argument may be used with this functionality. +For example, you can configure bookmarks in your web browser to send a +link to the current page to Org and create a note from it using +capture (see [[*Capture]]). You can also create a bookmark that tells +Emacs to open the local source file of a remote website you are +browsing. + +#+cindex: Org protocol, set-up +#+cindex: Installing Org protocol +In order to use Org protocol from an application, you need to register +=org-protocol://= as a valid scheme-handler. External calls are +passed to Emacs through the =emacsclient= command, so you also need to +ensure an Emacs server is running. More precisely, when the +application calls + +: emacsclient org-protocol://PROTOCOL?key1=val1&key2=val2 + +#+texinfo: @noindent +Emacs calls the handler associated to {{{var(PROTOCOL)}}} with +argument =(:key1 val1 :key2 val2)=. + +#+cindex: protocol, new protocol +#+cindex: defining new protocols +Org protocol comes with three predefined protocols, detailed in the +following sections. Configure ~org-protocol-protocol-alist~ to define +your own. + +*** The ~store-link~ protocol +:PROPERTIES: +:DESCRIPTION: Store a link, push URL to kill-ring. +:END: +#+cindex: store-link protocol +#+cindex: protocol, store-link + +Using the ~store-link~ handler, you can copy links, to that they can +be inserted using {{{kbd(M-x org-insert-link)}}} or yanking. More +precisely, the command + +: emacsclient org-protocol://store-link?url=URL&title=TITLE + +#+texinfo: @noindent +stores the following link: + +: [[URL][TITLE]] + +In addition, {{{var(URL)}}} is pushed on the kill-ring for yanking. +You need to encode {{{var(URL)}}} and {{{var(TITLE)}}} if they contain +slashes, and probably quote those for the shell. + +To use this feature from a browser, add a bookmark with an arbitrary +name, e.g., =Org: store-link= and enter this as /Location/: + +#+begin_example +javascript:location.href='org-protocol://store-link?url='+ + encodeURIComponent(location.href); +#+end_example + +*** The ~capture~ protocol +:PROPERTIES: +:DESCRIPTION: Fill a buffer with external information. +:END: +#+cindex: capture protocol +#+cindex: protocol, capture + +Activating the "capture" handler pops up a =Capture= buffer in Emacs, +using acapture template. + +: emacsclient org-protocol://capture?template=X?url=URL?title=TITLE?body=BODY + +To use this feature, add a bookmark with an arbitrary name, e.g., +=Org: capture=, and enter this as =Location=: + +#+begin_example +javascript:location.href='org-protocol://capture?template=x'+ + '&url='+encodeURIComponent(window.location.href)+ + '&title='+encodeURIComponent(document.title)+ + '&body='+encodeURIComponent(window.getSelection()); +#+end_example + +#+vindex: org-protocol-default-template-key +The capture template to be used can be specified in the bookmark (like +=X= above). If unspecified, the template key is set in the variable +~org-protocol-default-template-key~. The following template +placeholders are available: + +#+begin_example +%:link The URL +%:description The webpage title +%:annotation Equivalent to [[%:link][%:description]] +%i The selected text +#+end_example + +*** The ~open-source~ protocol +:PROPERTIES: +:DESCRIPTION: Edit published contents. +:END: +#+cindex: open-source protocol +#+cindex: protocol, open-source + +The ~open-source~ handler is designed to help with editing local +sources when reading a document. To that effect, you can use +a bookmark with the following location: + +#+begin_example +javascript:location.href='org-protocol://open-source?&url='+ + encodeURIComponent(location.href) +#+end_example + +#+vindex: org-protocol-project-alist +The variable ~org-protocol-project-alist~ maps URLs to local file +names, by stripping URL parameters from the end and replacing the +~:base-url~ with ~:working-directory~ and ~:online-suffix~ with +~:working-suffix~. For example, assuming you own a local copy of +=https://orgmode.org/worg/= contents at =/home/user/worg=, you can set +~org-protocol-project-alist~ to the following + +#+begin_src emacs-lisp +(setq org-protocol-project-alist + '(("Worg" + :base-url "https://orgmode.org/worg/" + :working-directory "/home/user/worg/" + :online-suffix ".html" + :working-suffix ".org"))) +#+end_src + +#+texinfo: @noindent +If you are now browsing +=https://orgmode.org/worg/org-contrib/org-protocol.html= and find +a typo or have an idea about how to enhance the documentation, simply +click the bookmark and start editing. + +#+cindex: rewritten URL in open-source protocol +#+cindex: protocol, open-source rewritten URL +However, such mapping may not always yield the desired results. +Suppose you maintain an online store located at =http://example.com/=. +The local sources reside in =/home/user/example/=. It is common +practice to serve all products in such a store through one file and +rewrite URLs that do not match an existing file on the server. That +way, a request to =http://example.com/print/posters.html= might be +rewritten on the server to something like +=http://example.com/shop/products.php/posters.html.php=. The +~open-source~ handler probably cannot find a file named +=/home/user/example/print/posters.html.php= and fails. + +Such an entry in ~org-protocol-project-alist~ may hold an additional +property ~:rewrites~. This property is a list of cons cells, each of +which maps a regular expression to a path relative to the +~:working-directory~. + +Now map the URL to the path =/home/user/example/products.php= by +adding ~:rewrites~ rules like this: + +#+begin_src emacs-lisp +(setq org-protocol-project-alist + '(("example.com" + :base-url "http://example.com/" + :working-directory "/home/user/example/" + :online-suffix ".php" + :working-suffix ".php" + :rewrites (("example.com/print/" . "products.php") + ("example.com/$" . "index.php"))))) +#+end_src + +#+texinfo: @noindent +Since =example.com/$= is used as a regular expression, it maps +=http://example.com/=, =https://example.com=, +=http://www.example.com/= and similar to +=/home/user/example/index.php=. + +The ~:rewrites~ rules are searched as a last resort if and only if no +existing file name is matched. + +#+cindex: protocol, open-source, set-up mapping +#+cindex: mappings in open-source protocol +#+findex: org-protocol-create +#+findex: org-protocol-create-for-org +Two functions can help you filling ~org-protocol-project-alist~ with +valid contents: ~org-protocol-create~ and +~org-protocol-create-for-org~. The latter is of use if you're editing +an Org file that is part of a publishing project. +** Org Crypt +:PROPERTIES: +:DESCRIPTION: Encrypting Org files. +:END: + +Org Crypt encrypts the text of an entry, but not the headline, or +properties. Behind the scene, it uses the Emacs EasyPG library to +encrypt and decrypt files. + +#+vindex: org-crypt-tag-matcher +Any text below a headline that has a =crypt= tag is automatically +encrypted when the file is saved. To use a different tag, customize +the ~org-crypt-tag-matcher~ setting. + +Here is a suggestion for Org Crypt settings in Emacs init file: + +#+begin_src emacs-lisp +(require 'org-crypt) +(org-crypt-use-before-save-magic) +(setq org-tags-exclude-from-inheritance '("crypt")) + +(setq org-crypt-key nil) +;; GPG key to use for encryption +;; Either the Key ID or set to nil to use symmetric encryption. + +(setq auto-save-default nil) +;; Auto-saving does not cooperate with org-crypt.el: so you need to +;; turn it off if you plan to use org-crypt.el quite often. Otherwise, +;; you'll get an (annoying) message each time you start Org. + +;; To turn it off only locally, you can insert this: +;; +;; # -*- buffer-auto-save-file-name: nil; -*- +#+end_src + +It's possible to use different keys for different headings by +specifying the respective key as property =CRYPTKEY=, e.g.: + +#+begin_example +,* Totally secret :crypt: + :PROPERTIES: + :CRYPTKEY: 0x0123456789012345678901234567890123456789 + :END: +#+end_example + +Excluding the =crypt= tag from inheritance prevents already encrypted +text from being encrypted again. + +** Org Mobile +:PROPERTIES: +:DESCRIPTION: Viewing and capture on a mobile device. +:END: +#+cindex: smartphone + +Org Mobile is a protocol for synchronizing Org files between Emacs and +other applications, e.g., on mobile devices. It enables offline-views +and capture support for an Org mode system that is rooted on a "real" +computer. The external application can also record changes to +existing entries. + +This appendix describes Org's support for agenda view formats +compatible with Org Mobile. It also describes synchronizing changes, +such as to notes, between the mobile application and the computer. + +To change tags and TODO states in the mobile application, first +customize the variables ~org-todo-keywords~, ~org-tag-alist~ and +~org-tag-persistent-alist~. These should cover all the important tags +and TODO keywords, even if Org files use only some of them. Though +the mobile application is expected to support in-buffer settings, it +is required to understand TODO states /sets/ (see [[*Setting up keywords +for individual files]]) and /mutually exclusive/ tags (see [[*Setting +Tags]]) only for those set in these variables. + +*** Setting up the staging area +:PROPERTIES: +:DESCRIPTION: For the mobile device. +:END: + +#+vindex: org-mobile-directory +The mobile application needs access to a file directory on +a server[fn:151] to interact with Emacs. Pass its location through +the ~org-mobile-directory~ variable. If you can mount that directory +locally just set the variable to point to that directory: + +#+begin_src emacs-lisp +(setq org-mobile-directory "~/orgmobile/") +#+end_src + +Alternatively, by using TRAMP (see [[info:tramp][TRAMP User Manual]]), +~org-mobile-directory~ may point to a remote directory accessible +through, for example, SSH, SCP, or DAVS: + +#+begin_src emacs-lisp +(setq org-mobile-directory "/davs:user@remote.host:/org/webdav/") +#+end_src + +#+vindex: org-mobile-encryption +With a public server, consider encrypting the files. Org also +requires OpenSSL installed on the local computer. To turn on +encryption, set the same password in the mobile application and in +Emacs. Set the password in the variable +~org-mobile-use-encryption~[fn:152]. Note that even after the mobile +application encrypts the file contents, the file name remains visible +on the file systems of the local computer, the server, and the mobile +device. + +*** Pushing to the mobile application +:PROPERTIES: +:DESCRIPTION: Uploading Org files and agendas. +:END: + +#+findex: org-mobile-push +#+vindex: org-mobile-files +The command ~org-mobile-push~ copies files listed in +~org-mobile-files~ into the staging area. Files include agenda files +(as listed in ~org-agenda-files~). Customize ~org-mobile-files~ to +add other files. File names are staged with paths relative to +~org-directory~, so all files should be inside this directory[fn:153]. + +Push creates a special Org file =agendas.org= with custom agenda views +defined by the user[fn:154]. + +Finally, Org writes the file =index.org=, containing links to other +files. The mobile application reads this file first from the server +to determine what other files to download for agendas. For faster +downloads, it is expected to only read files whose checksums[fn:155] +have changed. + +*** Pulling from the mobile application +:PROPERTIES: +:DESCRIPTION: Integrating captured and flagged items. +:END: + +#+findex: org-mobile-pull +The command ~org-mobile-pull~ synchronizes changes with the server. +More specifically, it first pulls the Org files for viewing. It then +appends captured entries and pointers to flagged or changed entries to +the file =mobileorg.org= on the server. Org ultimately integrates its +data in an inbox file format, through the following steps: + +1. + #+vindex: org-mobile-inbox-for-pull + Org moves all entries found in =mobileorg.org=[fn:156] and appends + them to the file pointed to by the variable + ~org-mobile-inbox-for-pull~. It should reside neither in the + staging area nor on the server. Each captured entry and each + editing event is a top-level entry in the inbox file. + +2. + #+cindex: @samp{FLAGGED}, tag + After moving the entries, Org processes changes to the shared + files. Some of them are applied directly and without user + interaction. Examples include changes to tags, TODO state, + headline and body text. Entries requiring further action are + tagged as =FLAGGED=. Org marks entries with problems with an error + message in the inbox. They have to be resolved manually. + +3. Org generates an agenda view for flagged entries for user + intervention to clean up. For notes stored in flagged entries, Org + displays them in the echo area when point is on the corresponding + agenda item. + + - {{{kbd(?)}}} :: + + Pressing {{{kbd(?)}}} displays the entire flagged note in another + window. Org also pushes it to the kill ring. To store flagged + note as a normal note, use {{{kbd(? z C-y C-c C-c)}}}. Pressing + {{{kbd(?)}}} twice does these things: first it removes the + =FLAGGED= tag; second, it removes the flagged note from the + property drawer; third, it signals that manual editing of the + flagged entry is now finished. + +#+kindex: ? @r{(Agenda dispatcher)} +From the agenda dispatcher, {{{kbd(?)}}} returns to the view to finish +processing flagged entries. Note that these entries may not be the +most recent since the mobile application searches files that were last +pulled. To get an updated agenda view with changes since the last +pull, pull again. + +* Hacking +:PROPERTIES: +:DESCRIPTION: How to hack your way around. +:APPENDIX: t +:END: +#+cindex: hacking + +This appendix describes some ways a user can extend the functionality +of Org. + +** Hooks +:PROPERTIES: +:DESCRIPTION: How to reach into Org's internals. +:END: +#+cindex: hooks + +Org has a large number of hook variables for adding functionality. +This appendix illustrates using a few. A complete list of hooks with +documentation is maintained by the Worg project at +https://orgmode.org/worg/doc.html#hooks. + +** Add-on Packages +:PROPERTIES: +:DESCRIPTION: Available extensions. +:END: +#+cindex: add-on packages + +Various authors wrote a large number of add-on packages for Org. + +These packages are not part of Emacs, but they are distributed as +contributed packages with the separate release available at +https://orgmode.org. See the =contrib/README= file in the source code +directory for a list of contributed files. Worg page with more +information is at: https://orgmode.org/worg/org-contrib/. + +** Adding Hyperlink Types +:PROPERTIES: +:DESCRIPTION: New custom link types. +:END: +#+cindex: hyperlinks, adding new types + +Org has many built-in hyperlink types (see [[*Hyperlinks]]), and an +interface for adding new link types. The following example shows the +process of adding Org links to Unix man pages, which look like this + +: [[man:printf][The printf manual]] + +#+texinfo: @noindent +The following =ol-man.el= file implements it + +#+begin_src emacs-lisp +;;; ol-man.el - Support for links to man pages in Org mode +(require 'ol) + +(org-link-set-parameters "man" + :follow #'org-man-open + :export #'org-man-export + :store #'org-man-store-link) + +(defcustom org-man-command 'man + "The Emacs command to be used to display a man page." + :group 'org-link + :type '(choice (const man) (const woman))) + +(defun org-man-open (path _) + "Visit the manpage on PATH. +PATH should be a topic that can be thrown at the man command." + (funcall org-man-command path)) + +(defun org-man-store-link () + "Store a link to a man page." + (when (memq major-mode '(Man-mode woman-mode)) + ;; This is a man page, we do make this link. + (let* ((page (org-man-get-page-name)) + (link (concat "man:" page)) + (description (format "Man page for %s" page))) + (org-link-store-props + :type "man" + :link link + :description description)))) + +(defun org-man-get-page-name () + "Extract the page name from the buffer name." + ;; This works for both `Man-mode' and `woman-mode'. + (if (string-match " \\(\\S-+\\)\\*" (buffer-name)) + (match-string 1 (buffer-name)) + (error "Cannot create link to this man page"))) + +(defun org-man-export (link description format _) + "Export a man page link from Org files." + (let ((path (format "http://man.he.net/?topic=%s§ion=all" link)) + (desc (or description link))) + (pcase format + (`html (format "%s" path desc)) + (`latex (format "\\href{%s}{%s}" path desc)) + (`texinfo (format "@uref{%s,%s}" path desc)) + (`ascii (format "%s (%s)" desc path)) + (t path)))) + +(provide ol-man) +;;; ol-man.el ends here +#+end_src + +#+texinfo: @noindent +To activate links to man pages in Org, enter this in the Emacs init +file: + +#+begin_src emacs-lisp +(require 'ol-man) +#+end_src + +#+texinfo: @noindent +A review of =ol-man.el=: + +1. First, =(require 'ol)= ensures that =ol.el= is loaded. + +2. + + #+findex: org-link-set-parameters + #+vindex: org-link-parameters + Then ~org-link-set-parameters~ defines a new link type with =man= + prefix and associates functions for following, exporting and + storing such links. See the variable ~org-link-parameters~ for + a complete list of possible associations. + +3. The rest of the file implements necessary variables and functions. + + For example, ~org-man-store-link~ is responsible for storing a link + when ~org-store-link~ (see [[*Handling Links]]) is called from a buffer + displaying a man page. It first checks if the major mode is + appropriate. If check fails, the function returns ~nil~, which + means it isn't responsible for creating a link to the current + buffer. Otherwise the function makes a link string by combining + the =man:= prefix with the man topic. It also provides a default + description. The function ~org-insert-link~ can insert it back + into an Org buffer later on. + +** Adding Export Back-ends +:PROPERTIES: +:DESCRIPTION: How to write new export back-ends. +:END: +#+cindex: Export, writing back-ends + +Org's export engine makes it easy for writing new back-ends. The +framework on which the engine was built makes it easy to derive new +back-ends from existing ones. + +#+findex: org-export-define-backend +#+findex: org-export-define-derived-backend +The two main entry points to the export engine are: +~org-export-define-backend~ and ~org-export-define-derived-backend~. +To grok these functions, see =ox-latex.el= for an example of defining +a new back-end from scratch, and =ox-beamer.el= for an example of +deriving from an existing engine. + +For creating a new back-end from scratch, first set its name as +a symbol in an alist consisting of elements and export functions. To +make the back-end visible to the export dispatcher, set ~:menu-entry~ +keyword. For export options specific to this back-end, set the +~:options-alist~. + +For creating a new back-end from an existing one, set +~:translate-alist~ to an alist of export functions. This alist +replaces the parent back-end functions. + +For complete documentation, see [[https://orgmode.org/worg/dev/org-export-reference.html][the Org Export Reference on Worg]]. + +** Tables in Arbitrary Syntax +:PROPERTIES: +:DESCRIPTION: Orgtbl for LaTeX and other programs. +:END: +#+cindex: tables, in other modes +#+cindex: lists, in other modes +#+cindex: Orgtbl mode + +Due to Org's success in handling tables with Orgtbl, a frequently +requested feature is the use of Org's table functions in other modes, +e.g., LaTeX. This would be hard to do in a general way without +complicated customization nightmares. Moreover, that would take Org +away from its simplicity roots that Orgtbl has proven. There is, +however, an alternate approach to accomplishing the same. + +This approach involves implementing a custom /translate/ function that +operates on a native Org /source table/ to produce a table in another +format. This strategy would keep the excellently working Orgtbl +simple and isolate complications, if any, confined to the translate +function. To add more alien table formats, we just add more translate +functions. Also the burden of developing custom translate functions +for new table formats is in the hands of those who know those formats +best. + +*** Radio tables +:PROPERTIES: +:DESCRIPTION: Sending and receiving radio tables. +:END: +#+cindex: radio tables + +Radio tables are target locations for translated tables that are not near +their source. Org finds the target location and inserts the translated +table. + +The key to finding the target location is the magic words =BEGIN/END +RECEIVE ORGTBL=. They have to appear as comments in the current mode. +If the mode is C, then: + +#+begin_example +/* BEGIN RECEIVE ORGTBL table_name */ +/* END RECEIVE ORGTBL table_name */ +#+end_example + +At the location of source, Org needs a special line to direct Orgtbl +to translate and to find the target for inserting the translated +table. For example: + +#+cindex: @samp{ORGTBL}, keyword +: #+ORGTBL: SEND table_name translation_function arguments ... + +#+texinfo: @noindent +=table_name= is the table's reference name, which is also used in the +receiver lines, and the =translation_function= is the Lisp function +that translates. This line, in addition, may also contain alternating +key and value arguments at the end. The translation function gets +these values as a property list. A few standard parameters are +already recognized and acted upon before the translation function is +called: + +- =:skip N= :: + + Skip the first N lines of the table. Hlines do count; include them + if they are to be skipped. + +- =:skipcols (n1 n2 ...)= :: + + List of columns to be skipped. First Org automatically discards + columns with calculation marks and then sends the table to the + translator function, which then skips columns as specified in + =skipcols=. + +To keep the source table intact in the buffer without being disturbed +when the source file is compiled or otherwise being worked on, use one +of these strategies: + +- Place the table in a block comment. For example, in C mode you + could wrap the table between =/*= and =*/= lines. + +- Put the table after an "end" statement. For example ~\bye~ in TeX + and ~\end{document}~ in LaTeX. + +- Comment and un-comment each line of the table during edits. The + {{{kbd(M-x orgtbl-toggle-comment)}}} command makes toggling easy. + +*** A LaTeX example of radio tables +:PROPERTIES: +:DESCRIPTION: Step by step, almost a tutorial. +:ALT_TITLE: A LaTeX example +:END: +#+cindex: @LaTeX{}, and Orgtbl mode + +To wrap a source table in LaTeX, use the =comment= environment +provided by =comment.sty=[fn:157]. To activate it, put +~\usepackage{comment}~ in the document header. Orgtbl mode inserts +a radio table skeleton[fn:158] with the command {{{kbd(M-x +orgtbl-insert-radio-table)}}}, which prompts for a table name. For +example, if =salesfigures= is the name, the template inserts: + +#+begin_example +% BEGIN RECEIVE ORGTBL salesfigures +% END RECEIVE ORGTBL salesfigures +\begin{comment} +,#+ORGTBL: SEND salesfigures orgtbl-to-latex +| | | +\end{comment} +#+end_example + +#+vindex: LaTeX-verbatim-environments +#+texinfo: @noindent +The line =#+ORGTBL: SEND= tells Orgtbl mode to use the function +~orgtbl-to-latex~ to convert the table to LaTeX format, then insert +the table at the target (receive) location named =salesfigures=. Now +the table is ready for data entry. It can even use spreadsheet +features[fn:159]: + +#+begin_example +% BEGIN RECEIVE ORGTBL salesfigures +% END RECEIVE ORGTBL salesfigures +\begin{comment} +,#+ORGTBL: SEND salesfigures orgtbl-to-latex +| Month | Days | Nr sold | per day | +|-------+------+---------+---------| +| Jan | 23 | 55 | 2.4 | +| Feb | 21 | 16 | 0.8 | +| March | 22 | 278 | 12.6 | +,#+TBLFM: $4=$3/$2;%.1f +% $ (optional extra dollar to keep Font Lock happy, see footnote) +\end{comment} +#+end_example + +After editing, {{{kbd(C-c C-c)}}} inserts the translated table at the +target location, between the two marker lines. + +For hand-made custom tables, note that the translator needs to skip +the first two lines of the source table. Also the command has to +/splice/ out the target table without the header and footer. + +#+begin_example +\begin{tabular}{lrrr} +Month & \multicolumn{1}{c}{Days} & Nr.\ sold & per day\\ +% BEGIN RECEIVE ORGTBL salesfigures +% END RECEIVE ORGTBL salesfigures +\end{tabular} +% +\begin{comment} +,#+ORGTBL: SEND salesfigures orgtbl-to-latex :splice t :skip 2 +| Month | Days | Nr sold | per day | +|-------+------+---------+---------| +| Jan | 23 | 55 | 2.4 | +| Feb | 21 | 16 | 0.8 | +| March | 22 | 278 | 12.6 | +,#+TBLFM: $4=$3/$2;%.1f +\end{comment} +#+end_example + +The LaTeX translator function ~orgtbl-to-latex~ is already part of +Orgtbl mode and uses a =tabular= environment to typeset the table and +marks horizontal lines with ~\hline~. For additional parameters to +control output, see [[*Translator functions]]: + +- =:splice BOOLEAN= :: + + When {{{var(BOOLEAN}}} is non-~nil~, return only table body lines; + i.e., not wrapped in =tabular= environment. Default is ~nil~. + +- =:fmt FMT= :: + + Format string to warp each field. It should contain =%s= for the + original field value. For example, to wrap each field value in + dollar symbol, you could use =:fmt "$%s$"=. Format can also wrap + a property list with column numbers and formats, for example =:fmt + (2 "$%s$" 4 "%s\\%%")=. In place of a string, a function of one + argument can be used; the function must return a formatted string. + +- =:efmt EFMT= :: + + Format numbers as exponentials. The spec should have =%s= twice for + inserting mantissa and exponent, for example ="%s\\times10^{%s}"=. This + may also be a property list with column numbers and formats, for + example =:efmt (2 "$%s\\times10^{%s}$" 4 "$%s\\cdot10^{%s}$")=. After + {{{var(EFMT)}}} has been applied to a value, {{{var(FMT)}}}---see + above---is also applied. Functions with two arguments can be + supplied instead of strings. By default, no special formatting is + applied. + +*** Translator functions +:PROPERTIES: +:DESCRIPTION: Copy and modify. +:END: +#+cindex: HTML, and Orgtbl mode +#+cindex: translator function + +#+findex: orgtbl-to-csv +#+findex: orgtbl-to-tsv +#+findex: orgtbl-to-latex +#+findex: orgtbl-to-html +#+findex: orgtbl-to-texinfo +#+findex: orgtbl-to-unicode +#+findex: orgtbl-to-orgtbl +#+findex: orgtbl-to-generic +Orgtbl mode has built-in translator functions: ~orgtbl-to-csv~ +(comma-separated values), ~orgtbl-to-tsv~ (TAB-separated values), +~orgtbl-to-latex~, ~orgtbl-to-html~, ~orgtbl-to-texinfo~, +~orgtbl-to-unicode~ and ~orgtbl-to-orgtbl~. They use the generic +translator, ~orgtbl-to-generic~, which delegates translations to +various export back-ends. + +Properties passed to the function through the =ORGTBL SEND= line take +precedence over properties defined inside the function. For example, +this overrides the default LaTeX line endings, ~\\~, with ~\\[2mm]~: + +: #+ORGTBL: SEND test orgtbl-to-latex :lend " \\\\[2mm]" + +For a new language translator, define a converter function. It can be +a generic function, such as shown in this example. It marks +a beginning and ending of a table with =!BTBL!= and =!ETBL!=; +a beginning and ending of lines with =!BL!= and =!EL!=; and uses a TAB +for a field separator: + +#+begin_src emacs-lisp +(defun orgtbl-to-language (table params) + "Convert the orgtbl-mode TABLE to language." + (orgtbl-to-generic + table + (org-combine-plists + '(:tstart "!BTBL!" :tend "!ETBL!" :lstart "!BL!" :lend "!EL!" :sep "\t") + params))) +#+end_src + +#+texinfo: @noindent +The documentation for the ~orgtbl-to-generic~ function shows +a complete list of parameters, each of which can be passed through to +~orgtbl-to-latex~, ~orgtbl-to-texinfo~, and any other function using +that generic function. + +For complicated translations the generic translator function could be +replaced by a custom translator function. Such a custom function must +take two arguments and return a single string containing the formatted +table. The first argument is the table whose lines are a list of +fields or the symbol ~hline~. The second argument is the property +list consisting of parameters specified in the =#+ORGTBL: SEND= line. +Please share your translator functions by posting them to the Org +users mailing list, at mailto:emacs-orgmode@gnu.org. + +** Dynamic Blocks +:PROPERTIES: +:DESCRIPTION: Automatically filled blocks. +:END: +#+cindex: dynamic blocks + +Org supports /dynamic blocks/ in Org documents. They are inserted +with begin and end markers like any other code block, but the contents +are updated automatically by a user function. + +#+kindex: C-c C-x x +#+findex: org-dynamic-block-insert-dblock +You can insert a dynamic block with ~org-dynamic-block-insert-dblock~, +which is bound to {{{kbd(C-c C-x x)}}} by default. For example, +{{{kbd(C-c C-x x c l o c k t a b l e RET)}}} inserts a table that +updates the work time (see [[*Clocking Work Time]]). + +Dynamic blocks can have names and function parameters. The syntax is +similar to source code block specifications: + +#+begin_example +,#+BEGIN: myblock :parameter1 value1 :parameter2 value2 ... + ... +,#+END: +#+end_example + +These commands update dynamic blocks: + +- {{{kbd(C-c C-x C-u)}}} (~org-dblock-update~) :: + + #+kindex: C-c C-x C-u + #+findex: org-dblock-update + Update dynamic block at point. + +- {{{kbd(C-u C-c C-x C-u)}}} :: + + #+kindex: C-u C-c C-x C-u + Update all dynamic blocks in the current file. + +Before updating a dynamic block, Org removes content between the +=BEGIN= and =END= markers. Org then reads the parameters on the +=BEGIN= line for passing to the writer function as a plist. The +previous content of the dynamic block becomes erased from the buffer +and appended to the plist under ~:content~. + +The syntax for naming a writer function with a dynamic block labeled +=myblock= is: ~org-dblock-write:myblock~. + +The following is an example of a dynamic block and a block writer function +that updates the time when the function was last run: + +#+begin_example +,#+BEGIN: block-update-time :format "on %m/%d/%Y at %H:%M" + ... +,#+END: +#+end_example + +#+texinfo: @noindent +The dynamic block's writer function: + +#+begin_src emacs-lisp +(defun org-dblock-write:block-update-time (params) + (let ((fmt (or (plist-get params :format) "%d. %m. %Y"))) + (insert "Last block update at: " + (format-time-string fmt)))) +#+end_src + +To keep dynamic blocks up-to-date in an Org file, use the function, +~org-update-all-dblocks~ in hook, such as ~before-save-hook~. The +~org-update-all-dblocks~ function does not run if the file is not in +Org mode. + +#+findex: org-narrow-to-block +Dynamic blocks, like any other block, can be narrowed with +~org-narrow-to-block~. + +** Special Agenda Views +:PROPERTIES: +:DESCRIPTION: Customized views. +:END: +#+cindex: agenda views, user-defined + +#+vindex: org-agenda-skip-function +#+vindex: org-agenda-skip-function-global +Org provides a special hook to further limit items in agenda views: +~agenda~, ~agenda*~[fn:160], ~todo~, ~alltodo~, ~tags~, ~tags-todo~, +~tags-tree~. Specify a custom function that tests inclusion of every +matched item in the view. This function can also skip as much as is +needed. + +For a global condition applicable to agenda views, use the +~org-agenda-skip-function-global~ variable. Org uses a global +condition with ~org-agenda-skip-function~ for custom searching. + +This example defines a function for a custom view showing TODO items +with =waiting= status. Manually this is a multi-step search process, +but with a custom view, this can be automated as follows: + +The custom function searches the subtree for the =waiting= tag and +returns ~nil~ on match. Otherwise it gives the location from where +the search continues. + +#+begin_src emacs-lisp +(defun my-skip-unless-waiting () + "Skip trees that are not waiting" + (let ((subtree-end (save-excursion (org-end-of-subtree t)))) + (if (re-search-forward ":waiting:" subtree-end t) + nil ; tag found, do not skip + subtree-end))) ; tag not found, continue after end of subtree +#+end_src + +To use this custom function in a custom agenda command: + +#+begin_src emacs-lisp +(org-add-agenda-custom-command + '("b" todo "PROJECT" + ((org-agenda-skip-function 'my-skip-unless-waiting) + (org-agenda-overriding-header "Projects waiting for something: ")))) +#+end_src + +#+vindex: org-agenda-overriding-header +Note that this also binds ~org-agenda-overriding-header~ to a more +meaningful string suitable for the agenda view. + +#+vindex: org-odd-levels-only +#+vindex: org-agenda-skip-function +Search for entries with a limit set on levels for the custom search. +This is a general approach to creating custom searches in Org. To +include all levels, use =LEVEL>0=[fn:161]. Then to selectively pick +the matched entries, use ~org-agenda-skip-function~, which also +accepts Lisp forms, such as ~org-agenda-skip-entry-if~ and +~org-agenda-skip-subtree-if~. For example: + +- =(org-agenda-skip-entry-if 'scheduled)= :: + + Skip current entry if it has been scheduled. + +- =(org-agenda-skip-entry-if 'notscheduled)= :: + + Skip current entry if it has not been scheduled. + +- =(org-agenda-skip-entry-if 'deadline)= :: + + Skip current entry if it has a deadline. + +- =(org-agenda-skip-entry-if 'scheduled 'deadline)= :: + + Skip current entry if it has a deadline, or if it is scheduled. + +- =(org-agenda-skip-entry-if 'todo '("TODO" "WAITING"))= :: + + Skip current entry if the TODO keyword is TODO or WAITING. + +- =(org-agenda-skip-entry-if 'todo 'done)= :: + + Skip current entry if the TODO keyword marks a DONE state. + +- =(org-agenda-skip-entry-if 'timestamp)= :: + + Skip current entry if it has any timestamp, may also be deadline or + scheduled. + +- =(org-agenda-skip-entry-if 'regexp "regular expression")= :: + + Skip current entry if the regular expression matches in the entry. + +- =(org-agenda-skip-entry-if 'notregexp "regular expression")= :: + + Skip current entry unless the regular expression matches. + +- =(org-agenda-skip-subtree-if 'regexp "regular expression")= :: + + Same as above, but check and skip the entire subtree. + +The following is an example of a search for =waiting= without the +special function: + +#+begin_src emacs-lisp +(org-add-agenda-custom-command + '("b" todo "PROJECT" + ((org-agenda-skip-function '(org-agenda-skip-subtree-if + 'regexp ":waiting:")) + (org-agenda-overriding-header "Projects waiting for something: ")))) +#+end_src + +** Speeding Up Your Agendas +:PROPERTIES: +:DESCRIPTION: Tips on how to speed up your agendas. +:END: +#+cindex: agenda views, optimization + +Some agenda commands slow down when the Org files grow in size or +number. Here are tips to speed up: + +- Reduce the number of Org agenda files to avoid slowdowns due to hard drive + accesses. + +- Reduce the number of DONE and archived headlines so agenda + operations that skip over these can finish faster. + +- Do not dim blocked tasks: + #+vindex: org-agenda-dim-blocked-tasks + + #+begin_src emacs-lisp + (setq org-agenda-dim-blocked-tasks nil) + #+end_src + +- Stop preparing agenda buffers on startup: + #+vindex: org-startup-folded + #+vindex: org-agenda-inhibit-startup + + #+begin_src emacs-lisp + (setq org-agenda-inhibit-startup t) + #+end_src + +- Disable tag inheritance for agendas: + #+vindex: org-agenda-show-inherited-tags + #+vindex: org-agenda-use-tag-inheritance + + #+begin_src emacs-lisp + (setq org-agenda-use-tag-inheritance nil) + #+end_src + +These options can be applied to selected agenda views. For more +details about generation of agenda views, see the docstrings for the +relevant variables, and this [[https://orgmode.org/worg/agenda-optimization.html][dedicated Worg page]] for agenda +optimization. + +** Extracting Agenda Information +:PROPERTIES: +:DESCRIPTION: Post-processing agenda information. +:END: +#+cindex: agenda, pipe +#+cindex: scripts, for agenda processing + +Org provides commands to access agendas through Emacs batch mode. +Through this command-line interface, agendas are automated for further +processing or printing. + +#+vindex: org-agenda-custom-commands +#+findex: org-batch-agenda +~org-batch-agenda~ creates an agenda view in ASCII and outputs to +standard output. This command takes one string parameter. When +string consists of a single character, Org uses it as a key to +~org-agenda-custom-commands~. These are the same ones available +through the agenda dispatcher (see [[*The Agenda Dispatcher]]). + +This example command line directly prints the TODO list to the printer: + +: emacs -batch -l ~/.emacs -eval '(org-batch-agenda "t")' | lpr + +When the string parameter length is two or more characters, Org +matches it with tags/TODO strings. For example, this example command +line prints items tagged with =shop=, but excludes items tagged with +=NewYork=: + +#+begin_example +emacs -batch -l ~/.emacs \ + -eval '(org-batch-agenda "+shop-NewYork")' | lpr +#+end_example + +#+texinfo: @noindent +An example showing on-the-fly parameter modifications: + +#+begin_example +emacs -batch -l ~/.emacs \ + -eval '(org-batch-agenda "a" \ + org-agenda-span (quote month) \ + org-agenda-include-diary nil \ + org-agenda-files (quote ("~/org/project.org")))' \ + | lpr +#+end_example + +#+texinfo: @noindent +which produces an agenda for the next 30 days from just the +=~/org/projects.org= file. + +#+findex: org-batch-agenda-csv +For structured processing of agenda output, use ~org-batch-agenda-csv~ +with the following fields: + +- category :: The category of the item +- head :: The headline, without TODO keyword, TAGS and PRIORITY +- type :: The type of the agenda entry, can be + + | ~todo~ | selected in TODO match | + | ~tagsmatch~ | selected in tags match | + | ~diary~ | imported from diary | + | ~deadline~ | a deadline | + | ~scheduled~ | scheduled | + | ~timestamp~ | appointment, selected by timestamp | + | ~closed~ | entry was closed on date | + | ~upcoming-deadline~ | warning about nearing deadline | + | ~past-scheduled~ | forwarded scheduled item | + | ~block~ | entry has date block including date | + +- todo :: The TODO keyword, if any +- tags :: All tags including inherited ones, separated by colons +- date :: The relevant date, like =2007-2-14= +- time :: The time, like =15:00-16:50= +- extra :: String with extra planning info +- priority-l :: The priority letter if any was given +- priority-n :: The computed numerical priority + +If the selection of the agenda item was based on a timestamp, +including those items with =DEADLINE= and =SCHEDULED= keywords, then +Org includes date and time in the output. + +If the selection of the agenda item was based on a timestamp (or +deadline/scheduled), then Org includes date and time in the output. + +Here is an example of a post-processing script in Perl. It takes the +CSV output from Emacs and prints with a checkbox: + +#+begin_src perl +#!/usr/bin/perl + +# define the Emacs command to run +$cmd = "emacs -batch -l ~/.emacs -eval '(org-batch-agenda-csv \"t\")'"; + +# run it and capture the output +$agenda = qx{$cmd 2>/dev/null}; + +# loop over all lines +foreach $line (split(/\n/,$agenda)) { + # get the individual values + ($category,$head,$type,$todo,$tags,$date,$time,$extra, + $priority_l,$priority_n) = split(/,/,$line); + # process and print + print "[ ] $head\n"; +} +#+end_src + +** Using the Property API +:PROPERTIES: +:DESCRIPTION: Writing programs that use entry properties. +:END: +#+cindex: API, for properties +#+cindex: properties, API + +Here is a description of the functions that can be used to work with +properties. + +#+attr_texinfo: :options org-entry-properties &optional pom which +#+begin_defun +Get all properties of the entry at point-or-marker {{{var(POM)}}}. +This includes the TODO keyword, the tags, time strings for deadline, +scheduled, and clocking, and any additional properties defined in the +entry. The return value is an alist. Keys may occur multiple times +if the property key was used several times. {{{var(POM)}}} may also +be ~nil~, in which case the current entry is used. If +{{{var(WHICH)}}} is ~nil~ or ~all~, get all properties. If +{{{var(WHICH)}}} is ~special~ or ~standard~, only get that subclass. +#+end_defun + +#+vindex: org-use-property-inheritance +#+findex: org-insert-property-drawer +#+attr_texinfo: :options org-entry-get pom property &optional inherit +#+begin_defun +Get value of {{{var(PROPERTY)}}} for entry at point-or-marker +{{{var(POM)}}}. By default, this only looks at properties defined +locally in the entry. If {{{var(INHERIT)}}} is non-~nil~ and the +entry does not have the property, then also check higher levels of the +hierarchy. If {{{var(INHERIT)}}} is the symbol ~selective~, use +inheritance if and only if the setting of +~org-use-property-inheritance~ selects {{{var(PROPERTY)}}} for +inheritance. +#+end_defun + +#+attr_texinfo: :options org-entry-delete pom property +#+begin_defun +Delete the property {{{var(PROPERTY)}}} from entry at point-or-marker +{{{var(POM)}}}. +#+end_defun + +#+attr_texinfo: :options org-entry-put pom property value +#+begin_defun +Set {{{var(PROPERTY)}}} to {{{var(VALUES)}}} for entry at +point-or-marker POM. +#+end_defun + +#+attr_texinfo: :options org-buffer-property-keys &optional include-specials +#+begin_defun +Get all property keys in the current buffer. +#+end_defun + +#+attr_texinfo: :options org-insert-property-drawer +#+begin_defun +Insert a property drawer for the current entry. Also +#+end_defun + +#+attr_texinfo: :options org-entry-put-multivalued-property pom property &rest values +#+begin_defun +Set {{{var(PROPERTY)}}} at point-or-marker {{{var(POM)}}} to +{{{var(VALUES)}}}. {{{var(VALUES)}}} should be a list of strings. +They are concatenated, with spaces as separators. +#+end_defun + +#+attr_texinfo: :options org-entry-get-multivalued-property pom property +#+begin_defun +Treat the value of the property {{{var(PROPERTY)}}} as +a whitespace-separated list of values and return the values as a list +of strings. +#+end_defun + +#+attr_texinfo: :options org-entry-add-to-multivalued-property pom property value +#+begin_defun +Treat the value of the property {{{var(PROPERTY)}}} as +a whitespace-separated list of values and make sure that +{{{var(VALUE)}}} is in this list. +#+end_defun + +#+attr_texinfo: :options org-entry-remove-from-multivalued-property pom property value +#+begin_defun +Treat the value of the property {{{var(PROPERTY)}}} as +a whitespace-separated list of values and make sure that +{{{var(VALUE)}}} is /not/ in this list. +#+end_defun + +#+attr_texinfo: :options org-entry-member-in-multivalued-property pom property value +#+begin_defun +Treat the value of the property {{{var(PROPERTY)}}} as +a whitespace-separated list of values and check if {{{var(VALUE)}}} is +in this list. +#+end_defun + +#+attr_texinfo: :options org-property-allowed-value-functions +#+begin_defopt +Hook for functions supplying allowed values for a specific property. +The functions must take a single argument, the name of the property, +and return a flat list of allowed values. If =:ETC= is one of the +values, use the values as completion help, but allow also other values +to be entered. The functions must return ~nil~ if they are not +responsible for this property. +#+end_defopt + +** Using the Mapping API +:PROPERTIES: +:DESCRIPTION: Mapping over all or selected entries. +:END: +#+cindex: API, for mapping +#+cindex: mapping entries, API + +Org has sophisticated mapping capabilities to find all entries +satisfying certain criteria. Internally, this functionality is used +to produce agenda views, but there is also an API that can be used to +execute arbitrary functions for each or selected entries. The main +entry point for this API is: + +#+attr_texinfo: :options org-map-entries func &optional match scope &rest skip +#+begin_defun +Call {{{var(FUNC)}}} at each headline selected by {{{var(MATCH)}}} in +{{{var(SCOPE)}}}. + +{{{var(FUNC)}}} is a function or a Lisp form. With point positioned +at the beginning of the headline, call the function without arguments. +Org returns an alist of return values of calls to the function. + +To avoid preserving point, Org wraps the call to {{{var(FUNC)}}} in +~save-excursion~ form. After evaluation, Org moves point to the end +of the line that was just processed. Search continues from that point +forward. This may not always work as expected under some conditions, +such as if the current sub-tree was removed by a previous archiving +operation. In such rare circumstances, Org skips the next entry +entirely when it should not. To stop Org from such skips, make +{{{var(FUNC)}}} set the variable ~org-map-continue-from~ to a specific +buffer position. + +{{{var(MATCH)}}} is a tags/property/TODO match. Org iterates only +matched headlines. Org iterates over all headlines when +{{{var(MATCH)}}} is ~nil~ or ~t~. + +{{{var(SCOPE)}}} determines the scope of this command. It can be any +of: + +- ~nil~ :: + + The current buffer, respecting the restriction, if any. + +- ~tree~ :: + + The subtree started with the entry at point. + +- ~region~ :: + + The entries within the active region, if any. + +- ~file~ :: + + The current buffer, without restriction. + +- ~file-with-archives~ :: + + The current buffer, and any archives associated with it. + +- ~agenda~ :: + + All agenda files. + +- ~agenda-with-archives~ :: + + All agenda files with any archive files associated with them. + +- list of filenames :: + + If this is a list, all files in the list are scanned. + +#+texinfo: @noindent +The remaining arguments are treated as settings for the scanner's +skipping facilities. Valid arguments are: + +- ~archive~ :: + + Skip trees with the =ARCHIVE= tag. + +- ~comment~ :: + + Skip trees with the COMMENT keyword. + +- function or Lisp form :: + + #+vindex: org-agenda-skip-function + Used as value for ~org-agenda-skip-function~, so whenever the + function returns ~t~, {{{var(FUNC)}}} is called for that entry and + search continues from the point where the function leaves it. +#+end_defun + +The mapping routine can call any arbitrary function, even functions +that change meta data or query the property API (see [[*Using the +Property API]]). Here are some handy functions: + +#+attr_texinfo: :options org-todo &optional arg +#+begin_defun +Change the TODO state of the entry. See the docstring of the +functions for the many possible values for the argument +{{{var(ARG)}}}. +#+end_defun + +#+attr_texinfo: :options org-priority &optional action +#+begin_defun +Change the priority of the entry. See the docstring of this function +for the possible values for {{{var(ACTION)}}}. +#+end_defun + +#+attr_texinfo: :options org-toggle-tag tag &optional onoff +#+begin_defun +Toggle the tag {{{var(TAG)}}} in the current entry. Setting +{{{var(ONOFF)}}} to either ~on~ or ~off~ does not toggle tag, but +ensure that it is either on or off. +#+end_defun + +#+attr_texinfo: :options org-promote +#+begin_defun +Promote the current entry. +#+end_defun + +#+attr_texinfo: :options org-demote +#+begin_defun +Demote the current entry. +#+end_defun + +This example turns all entries tagged with =TOMORROW= into TODO +entries with keyword =UPCOMING=. Org ignores entries in comment trees +and archive trees. + +#+begin_src emacs-lisp +(org-map-entries '(org-todo "UPCOMING") + "+TOMORROW" 'file 'archive 'comment) +#+end_src + +The following example counts the number of entries with TODO keyword +=WAITING=, in all agenda files. + +#+begin_src emacs-lisp +(length (org-map-entries t "/+WAITING" 'agenda)) +#+end_src + +* History and Acknowledgments +:PROPERTIES: +:DESCRIPTION: How Org came into being. +:APPENDIX: t +:END: + +** From Carsten +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +Org was born in 2003, out of frustration over the user interface of +the Emacs Outline mode. I was trying to organize my notes and +projects, and using Emacs seemed to be the natural way to go. +However, having to remember eleven different commands with two or +three keys per command, only to hide and show parts of the outline +tree, that seemed entirely unacceptable to me. Also, when using +outlines to take notes, I constantly wanted to restructure the tree, +organizing it parallel to my thoughts and plans. /Visibility cycling/ +and /structure editing/ were originally implemented in the package +=outline-magic.el=, but quickly moved to the more general =org.el=. +As this environment became comfortable for project planning, the next +step was adding /TODO entries/, basic /timestamps/, and /table +support/. These areas highlighted the two main goals that Org still +has today: to be a new, outline-based, plain text mode with innovative +and intuitive editing features, and to incorporate project planning +functionality directly into a notes file. + +Since the first release, literally thousands of emails to me or to the +[[mailto:emacs-orgmode@gnu.org][mailing list]] have provided a constant stream of bug reports, feedback, +new ideas, and sometimes patches and add-on code. Many thanks to +everyone who has helped to improve this package. I am trying to keep +here a list of the people who had significant influence in shaping one +or more aspects of Org. The list may not be complete, if I have +forgotten someone, please accept my apologies and let me know. + +Before I get to this list, a few special mentions are in order: + +- Bastien Guerry :: + + Bastien has written a large number of extensions to Org (most of + them integrated into the core by now), including the LaTeX exporter + and the plain list parser. His support during the early days was + central to the success of this project. Bastien also invented Worg, + helped establishing the Web presence of Org, and sponsored hosting + costs for the orgmode.org website. Bastien stepped in as maintainer + of Org between 2011 and 2013, at a time when I desperately needed + a break. + +- Eric Schulte and Dan Davison :: + + Eric and Dan are jointly responsible for the Org Babel system, which + turns Org into a multi-language environment for evaluating code and + doing literate programming and reproducible research. This has + become one of Org's killer features that define what Org is today. + +- John Wiegley :: + + John has contributed a number of great ideas and patches directly to + Org, including the attachment system (=org-attach.el=), integration + with Apple Mail (=org-mac-message.el=), hierarchical dependencies of + TODO items, habit tracking (=org-habits.el=), and encryption + (=org-crypt.el=). Also, the capture system is really an extended + copy of his great =remember.el=. + +- Sebastian Rose :: + + Without Sebastian, the HTML/XHTML publishing of Org would be the + pitiful work of an ignorant amateur. Sebastian has pushed this part + of Org onto a much higher level. He also wrote =org-info.js=, + a JavaScript program for displaying webpages derived from Org using + an Info-like or a folding interface with single-key navigation. + +See below for the full list of contributions! Again, please let me +know what I am missing here! + +** From Bastien +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +I (Bastien) have been maintaining Org between 2011 and 2013. This +appendix would not be complete without adding a few more +acknowledgments and thanks. + +I am first grateful to Carsten for his trust while handing me over the +maintainership of Org. His unremitting support is what really helped +me getting more confident over time, with both the community and the +code. + +When I took over maintainership, I knew I would have to make Org more +collaborative than ever, as I would have to rely on people that are +more knowledgeable than I am on many parts of the code. Here is +a list of the persons I could rely on, they should really be +considered co-maintainers, either of the code or the community: + +- Eric Schulte :: + + Eric is maintaining the Babel parts of Org. His reactivity here + kept me away from worrying about possible bugs here and let me focus + on other parts. + +- Nicolas Goaziou :: + + Nicolas is maintaining the consistency of the deepest parts of Org. + His work on =org-element.el= and =ox.el= has been outstanding, and + it opened the doors for many new ideas and features. He rewrote + many of the old exporters to use the new export engine, and helped + with documenting this major change. More importantly (if that's + possible), he has been more than reliable during all the work done + for Org 8.0, and always very reactive on the mailing list. + +- Achim Gratz :: + + Achim rewrote the building process of Org, turning some /ad hoc/ + tools into a flexible and conceptually clean process. He patiently + coped with the many hiccups that such a change can create for users. + +- Nick Dokos :: + + The Org mode mailing list would not be such a nice place without + Nick, who patiently helped users so many times. It is impossible to + overestimate such a great help, and the list would not be so active + without him. + +I received support from so many users that it is clearly impossible to +be fair when shortlisting a few of them, but Org's history would not +be complete if the ones above were not mentioned in this manual. + +** List of Contributions +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +- Russell Adams came up with the idea for drawers. + +- Thomas Baumann wrote =ol-bbdb.el= and =ol-mhe.el=. + +- Christophe Bataillon created the great unicorn logo that we use on + the Org mode website. + +- Alex Bochannek provided a patch for rounding timestamps. + +- Jan Böcker wrote =ol-docview.el=. + +- Brad Bozarth showed how to pull RSS feed data into Org files. + +- Tom Breton wrote =org-choose.el=. + +- Charles Cave's suggestion sparked the implementation of templates + for Remember, which are now templates for capture. + +- Pavel Chalmoviansky influenced the agenda treatment of items with + specified time. + +- Gregory Chernov patched support for Lisp forms into table + calculations and improved XEmacs compatibility, in particular by + porting =nouline.el= to XEmacs. + +- Sacha Chua suggested copying some linking code from Planner. + +- Baoqiu Cui contributed the DocBook exporter. + +- Eddward DeVilla proposed and tested checkbox statistics. He also + came up with the idea of properties, and that there should be an API + for them. + +- Nick Dokos tracked down several nasty bugs. + +- Kees Dullemond used to edit projects lists directly in HTML and so + inspired some of the early development, including HTML export. He + also asked for a way to narrow wide table columns. + +- Thomas\nbsp{}S.\nbsp{}Dye contributed documentation on Worg and helped + integrating the Org Babel documentation into the manual. + +- Christian Egli converted the documentation into Texinfo format, + inspired the agenda, patched CSS formatting into the HTML exporter, + and wrote =org-taskjuggler.el=. + +- David Emery provided a patch for custom CSS support in exported HTML + agendas. + +- Nic Ferrier contributed mailcap and XOXO support. + +- Miguel\nbsp{}A.\nbsp{}Figueroa-Villanueva implemented hierarchical checkboxes. + +- John Foerch figured out how to make incremental search show context + around a match in a hidden outline tree. + +- Raimar Finken wrote =org-git-line.el=. + +- Mikael Fornius works as a mailing list moderator. + +- Austin Frank works as a mailing list moderator. + +- Eric Fraga drove the development of Beamer export with ideas and + testing. + +- Barry Gidden did proofreading the manual in preparation for the book + publication through Network Theory Ltd. + +- Niels Giesen had the idea to automatically archive DONE trees. + +- Nicolas Goaziou rewrote much of the plain list code. + +- Kai Grossjohann pointed out key-binding conflicts with other + packages. + +- Brian Gough of Network Theory Ltd publishes the Org mode manual as + a book. + +- Bernt Hansen has driven much of the support for auto-repeating + tasks, task state change logging, and the clocktable. His clear + explanations have been critical when we started to adopt the Git + version control system. + +- Manuel Hermenegildo has contributed various ideas, small fixes and + patches. + +- Phil Jackson wrote =ol-irc.el=. + +- Scott Jaderholm proposed footnotes, control over whitespace between + folded entries, and column view for properties. + +- Matt Jones wrote MobileOrg Android. + +- Tokuya Kameshima wrote =org-wl.el= and =org-mew.el=. + +- Shidai Liu ("Leo") asked for embedded LaTeX and tested it. He also + provided frequent feedback and some patches. + +- Matt Lundin has proposed last-row references for table formulas and + named invisible anchors. He has also worked a lot on the FAQ. + +- David Maus wrote =org-atom.el=, maintains the issues file for Org, + and is a prolific contributor on the mailing list with competent + replies, small fixes and patches. + +- Jason\nbsp{}F.\nbsp{}McBrayer suggested agenda export to CSV format. + +- Max Mikhanosha came up with the idea of refiling. + +- Dmitri Minaev sent a patch to set priority limits on a per-file + basis. + +- Stefan Monnier provided a patch to keep the Emacs Lisp compiler + happy. + +- Richard Moreland wrote MobileOrg for the iPhone. + +- Rick Moynihan proposed allowing multiple TODO sequences in a file + and being able to quickly restrict the agenda to a subtree. + +- Todd Neal provided patches for links to Info files and Elisp forms. + +- Greg Newman refreshed the unicorn logo into its current form. + +- Tim O'Callaghan suggested in-file links, search options for general + file links, and tags. + +- Osamu Okano wrote =orgcard2ref.pl=, a Perl program to create a text + version of the reference card. + +- Takeshi Okano translated the manual and David O'Toole's tutorial + into Japanese. + +- Oliver Oppitz suggested multi-state TODO items. + +- Scott Otterson sparked the introduction of descriptive text for + links, among other things. + +- Pete Phillips helped during the development of the TAGS feature, + and provided frequent feedback. + +- Martin Pohlack provided the code snippet to bundle character + insertion into bundles of 20 for undo. + +- T.\nbsp{}V.\nbsp{}Raman reported bugs and suggested improvements. + +- Matthias Rempe (Oelde) provided ideas, Windows support, and quality + control. + +- Paul Rivier provided the basic implementation of named footnotes. + He also acted as mailing list moderator for some time. + +- Kevin Rogers contributed code to access VM files on remote hosts. + +- Frank Ruell solved the mystery of the =keymapp nil= bug, a conflict + with =allout.el=. + +- Jason Riedy generalized the send-receive mechanism for Orgtbl + tables with extensive patches. + +- Philip Rooke created the Org reference card, provided lots of + feedback, developed and applied standards to the Org documentation. + +- Christian Schlauer proposed angular brackets around links, among + other things. + +- Paul Sexton wrote =org-ctags.el=. + +- Tom Shannon's =organizer-mode.el= inspired linking to VM/BBDB/Gnus. + +- Ilya Shlyakhter proposed the Archive Sibling, line numbering in + literal examples, and remote highlighting for referenced code lines. + +- Stathis Sideris wrote the =ditaa.jar= ASCII to PNG converter that is + now packaged into Org's =contrib/= directory. + +- Daniel Sinder came up with the idea of internal archiving by locking + subtrees. + +- Dale Smith proposed link abbreviations. + +- James TD Smith has contributed a large number of patches for + useful tweaks and features. + +- Adam Spiers asked for global linking commands, inspired the link + extension system, added support for Mairix, and proposed the mapping + API. + +- Ulf Stegemann created the table to translate special symbols to + HTML, LaTeX, UTF-8, Latin-1 and ASCII. + +- Andy Stewart contributed code to =ol-w3m.el=, to copy + HTML content with links transformation to Org syntax. + +- David O'Toole wrote =org-publish.el= and drafted the + manual chapter about publishing. + +- Jambunathan\nbsp{}K.\nbsp{}contributed the ODT exporter. + +- Sebastien Vauban reported many issues with LaTeX and Beamer export + and enabled source code highlighting in Gnus. + +- Stefan Vollmar organized a video-recorded talk at the + Max-Planck-Institute for Neurology. He also inspired the creation + of a concept index for HTML export. + +- Jürgen Vollmer contributed code generating the table of contents in + HTML output. + +- Samuel Wales has provided important feedback and bug reports. + +- Chris Wallace provided a patch implementing the =QUOTE= block. + +- David Wainberg suggested archiving, and improvements to the + linking system. + +- Carsten Wimmer suggested some changes and helped fix a bug in + linking to Gnus. + +- Roland Winkler requested additional key bindings to make Org work on + a TTY. + +- Piotr Zielinski wrote =org-mouse.el=, proposed agenda + blocks and contributed various ideas and code snippets. + +- Marco Wahl wrote =ol-eww.el=. + +* GNU Free Documentation License +:PROPERTIES: +:APPENDIX: t +:DESCRIPTION: The license for this documentation. +:END: + +#+include: fdl.org + +* Main Index +:PROPERTIES: +:INDEX: cp +:DESCRIPTION: An index of Org's concepts and features. +:END: + +* Key Index +:PROPERTIES: +:DESCRIPTION: Key bindings and where they are described. +:INDEX: ky +:END: + +* Command and Function Index +:PROPERTIES: +:DESCRIPTION: Command names and some internal functions. +:INDEX: fn +:END: + +* Variable Index +:PROPERTIES: +:DESCRIPTION: Variables mentioned in the manual. +:INDEX: vr +:END: + +This is not a complete index of variables and faces, only the ones +that are mentioned in the manual. For a more complete list, use +{{{kbd(M-x org-customize)}}} and then click yourself through the tree. + +* Copying +:PROPERTIES: +:copying: t +:END: + +This manual is for Org version {{{version}}}. + +Copyright \copy 2004--2021 Free Software Foundation, Inc. + +#+begin_quote +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, with the Front-Cover Texts being "A GNU Manual," +and with the Back-Cover Texts as in (a) below. A copy of the license +is included in the section entitled "GNU Free Documentation License." + +(a) The FSF's Back-Cover Text is: "You have the freedom to copy and +modify this GNU manual." +#+end_quote + +* Export Setup :noexport: + +#+setupfile: doc-setup.org + +#+export_file_name: org.texi + +#+texinfo_dir_category: Emacs editing modes +#+texinfo_dir_title: Org Mode: (org) +#+texinfo_dir_desc: Outline-based notes management and organizer + +* Footnotes + +[fn:1] If you do not use Font Lock globally turn it on in Org buffer +with =(add-hook 'org-mode-hook 'turn-on-font-lock)=. + +[fn:2] Please consider subscribing to the mailing list in order to +minimize the work the mailing list moderators have to do. + +[fn:3] See the variables ~org-special-ctrl-a/e~, ~org-special-ctrl-k~, +and ~org-ctrl-k-protect-subtree~ to configure special behavior of +{{{kbd(C-a)}}}, {{{kbd(C-e)}}}, and {{{kbd(C-k)}}} in headlines. Note +also that clocking only works with headings indented less than 30 +stars. + +[fn:4] See, however, the option ~org-cycle-emulate-tab~. + +[fn:5] The indirect buffer contains the entire buffer, but is narrowed +to the current tree. Editing the indirect buffer also changes the +original buffer, but without affecting visibility in that buffer. For +more information about indirect buffers, see [[info:emacs#Indirect Buffers][GNU Emacs Manual]]. + +[fn:6] When ~org-agenda-inhibit-startup~ is non-~nil~, Org does not +honor the default visibility state when first opening a file for the +agenda (see [[*Speeding Up Your Agendas]]). + +[fn:7] See also the variable ~org-show-context-detail~ to decide how +much context is shown around each match. + +[fn:8] This depends on the option ~org-remove-highlights-with-change~. + +[fn:9] When using =*= as a bullet, lines must be indented so that they +are not interpreted as headlines. Also, when you are hiding leading +stars to get a clean outline view, plain list items starting with +a star may be hard to distinguish from true headlines. In short: even +though =*= is supported, it may be better to not use it for plain list +items. + +[fn:10] You can filter out any of them by configuring +~org-plain-list-ordered-item-terminator~. + +[fn:11] You can also get =a.=, =A.=, =a)= and =A)= by configuring +~org-list-allow-alphabetical~. To minimize confusion with normal +text, those are limited to one character only. Beyond that limit, +bullets automatically become numbers. + +[fn:12] If there's a checkbox in the item, the cookie must be put +/before/ the checkbox. If you have activated alphabetical lists, you +can also use counters like =[@b]=. + +[fn:13] If you do not want the item to be split, customize the +variable ~org-M-RET-may-split-line~. + +[fn:14] If you want to cycle around items that way, you may customize +~org-list-use-circular-motion~. + +[fn:15] See ~org-list-use-circular-motion~ for a cyclic behavior. + +[fn:16] Many desktops intercept {{{kbd(M-TAB)}}} to switch windows. +Use {{{kbd(C-M-i)}}} or {{{kbd(ESC TAB)}}} instead. + +[fn:17] To insert a vertical bar into a table field, use =\vert= or, +inside a word =abc\vert{}def=. + +[fn:18] Org understands references typed by the user as =B4=, but it +does not use this syntax when offering a formula for editing. You can +customize this behavior using the variable +~org-table-use-standard-references~. + +[fn:19] The computation time scales as O(N^2) because table +{{{var(FOO)}}} is parsed for each field to be copied. + +[fn:20] The file =constants.el= can supply the values of constants in +two different unit systems, =SI= and =cgs=. Which one is used depends +on the value of the variable ~constants-unit-system~. You can use the +=STARTUP= options =constSI= and =constcgs= to set this value for the +current buffer. + +[fn:21] The printf reformatting is limited in precision because the +value passed to it is converted into an "integer" or "double". The +"integer" is limited in size by truncating the signed value to 32 +bits. The "double" is limited in precision to 64 bits overall which +leaves approximately 16 significant decimal digits. + +[fn:22] Such names must start with an alphabetic character and use +only alphanumeric/underscore characters. + +[fn:23] Plain URIs are recognized only for a well-defined set of +schemes. See [[*External Links]]. Unlike URI syntax, they cannot contain +parenthesis or white spaces, either. URIs within angle brackets have +no such limitation. + +[fn:24] More accurately, the precise behavior depends on how point +arrived there---see [[info:elisp#Invisible Text][Invisible Text]]. + +[fn:25] To insert a link targeting a headline, in-buffer completion +can be used. Just type a star followed by a few optional letters into +the buffer and press {{{kbd(M-TAB)}}}. All headlines in the current +buffer are offered as completions. + +[fn:26] When targeting a =NAME= keyword, the =CAPTION= keyword is +mandatory in order to get proper numbering (see [[*Captions]]). + +[fn:27] The actual behavior of the search depends on the value of the +variable ~org-link-search-must-match-exact-headline~. If its value is +~nil~, then a fuzzy text search is done. If it is ~t~, then only the +exact headline is matched, ignoring spaces and statistic cookies. If +the value is ~query-to-create~, then an exact headline is searched; if +it is not found, then the user is queried to create it. + +[fn:28] If the headline contains a timestamp, it is removed from the +link, which results in a wrong link---you should avoid putting +a timestamp in the headline. + +[fn:29] The Org Id library must first be loaded, either through +~org-customize~, by enabling ~id~ in ~org-modules~, or by adding +=(require 'org-id)= in your Emacs init file. + +[fn:30] Note that you do not have to use this command to insert +a link. Links in Org are plain text, and you can type or paste them +straight into the buffer. By using this command, the links are +automatically enclosed in double brackets, and you will be asked for +the optional descriptive text. + +[fn:31] After insertion of a stored link, the link will be removed +from the list of stored links. To keep it in the list for later use, +use a triple {{{kbd(C-u)}}} prefix argument to {{{kbd(C-c C-l)}}}, or +configure the option ~org-link-keep-stored-after-insertion~. + +[fn:32] This works if a function has been defined in the ~:complete~ +property of a link in ~org-link-parameters~. + +[fn:33] See the variable ~org-link-use-indirect-buffer-for-internals~. + +[fn:34] For backward compatibility, line numbers can also follow a +single colon. + +[fn:35] Of course, you can make a document that contains only long +lists of TODO items, but this is not required. + +[fn:36] Changing the variable ~org-todo-keywords~ only becomes +effective after restarting Org mode in a buffer. + +[fn:37] This is also true for the {{{kbd(t)}}} command in the agenda +buffer. + +[fn:38] All characters are allowed except =@=, =^= and =!=, which have +a special meaning here. + +[fn:39] Check also the variable ~org-fast-tag-selection-include-todo~, +it allows you to change the TODO state through the tags interface (see +[[*Setting Tags]]), in case you like to mingle the two concepts. Note +that this means you need to come up with unique keys across both sets +of keywords. + +[fn:40] Org mode parses these lines only when Org mode is activated +after visiting a file. {{{kbd(C-c C-c)}}} with point in a line +starting with =#+= is simply restarting Org mode for the current +buffer. + +[fn:41] The corresponding in-buffer setting is: =#+STARTUP: logdone=. + +[fn:42] The corresponding in-buffer setting is: =#+STARTUP: +lognotedone=. + +[fn:43] See the variable ~org-log-states-order-reversed~. + +[fn:44] Note that the =LOGBOOK= drawer is unfolded when pressing +{{{kbd(SPC)}}} in the agenda to show an entry---use {{{kbd(C-u +SPC)}}} to keep it folded here. + +[fn:45] It is possible that Org mode records two timestamps when you +are using both ~org-log-done~ and state change logging. However, it +never prompts for two notes: if you have configured both, the state +change recording note takes precedence and cancel the closing note. + +[fn:46] See also the option ~org-priority-start-cycle-with-default~. + +[fn:47] To keep subtasks out of the global TODO list, see the option +~org-agenda-todo-list-sublevels~. + +[fn:48] With the exception of description lists. But you can allow it +by modifying ~org-list-automatic-rules~ accordingly. + +[fn:49] Set the variable ~org-hierarchical-checkbox-statistics~ if you +want such cookies to count all checkboxes below the cookie, not just +those belonging to direct children. + +[fn:50] {{{kbd(C-u C-c C-c)}}} on the /first/ item of a list with no +checkbox adds checkboxes to the rest of the list. + +[fn:51] As with all these in-buffer settings, pressing {{{kbd(C-c +C-c)}}} activates any changes in the line. + +[fn:52] This is only true if the search does not involve more complex +tests including properties (see [[*Property Searches]]). + +[fn:53] To extend this default list to all tags used in all agenda +files (see [[*Agenda Views]]), customize the variable +~org-complete-tags-always-offer-all-agenda-tags~. + +[fn:54] Keys are automatically assigned to tags that have no +configured keys. + +[fn:55] If more than one summary type applies to the same property, +the parent values are computed according to the first of them. + +[fn:56] An age can be defined as a duration, using units defined in +~org-duration-units~, e.g., =3d 1h=. If any value in the column is as +such, the summary is also expressed as a duration. + +[fn:57] Please note that the =COLUMNS= definition must be on a single +line; it is wrapped here only because of formatting constraints. + +[fn:58] Contributed packages are not part of Emacs, but are +distributed with the main distribution of Org---visit +[[https://orgmode.org]]. + +[fn:59] The Org date format is inspired by the standard ISO 8601 +date/time format. To use an alternative format, see [[*Custom time +format]]. The day name is optional when you type the date yourself. +However, any date inserted or modified by Org adds that day name, for +reading convenience. + +[fn:60] When working with the standard diary expression functions, you +need to be very careful with the order of the arguments. That order +depends evilly on the variable ~calendar-date-style~. For example, to +specify a date December 12, 2005, the call might look like +=(diary-date 12 1 2005)= or =(diary-date 1 12 2005)= or =(diary-date +2005 12 1)=, depending on the settings. This has been the source of +much confusion. Org mode users can resort to special versions of +these functions like ~org-date~ or ~org-anniversary~. These work just +like the corresponding ~diary-~ functions, but with stable ISO order +of arguments (year, month, day) wherever applicable, independent of +the value of ~calendar-date-style~. + +[fn:61] See the variable ~org-read-date-prefer-future~. You may set +that variable to the symbol ~time~ to even make a time before now +shift the date to tomorrow. + +[fn:62] If you do not need/want the calendar, configure the variable +~org-popup-calendar-for-date-prompt~. + +[fn:63] You can also use the calendar command {{{kbd(.)}}} to jump to +today's date, but if you are inserting an hour specification for your +timestamp, {{{kbd(.)}}} will then insert a dot after the hour. By contrast, +{{{kbd(C-.)}}} will always jump to today's date. + +[fn:64] If you find this distracting, turn off the display with +~org-read-date-display-live~. + +[fn:65] It will still be listed on that date after it has been marked +as done. If you do not like this, set the variable +~org-agenda-skip-scheduled-if-done~. + +[fn:66] The =SCHEDULED= and =DEADLINE= dates are inserted on the line +right below the headline. Do not put any text between this line and +the headline. + +[fn:67] Note the corresponding =STARTUP= options =logredeadline=, +=lognoteredeadline=, and =nologredeadline=. + +[fn:68] Note the corresponding =STARTUP= options =logreschedule=, +=lognotereschedule=, and =nologreschedule=. + +[fn:69] Org does not repeat inactive timestamps, however. See +[[*Timestamps]]. + +[fn:70] In fact, the target state is taken from, in this sequence, the +=REPEAT_TO_STATE= property, the variable ~org-todo-repeat-to-state~ if +it is a string, the previous TODO state if ~org-todo-repeat-to-state~ +is ~t~, or the first state of the TODO state sequence. + +[fn:71] You can change this using the option ~org-log-repeat~, or the +=STARTUP= options =logrepeat=, =lognoterepeat=, and =nologrepeat=. +With =lognoterepeat=, you will also be prompted for a note. + +[fn:72] Clocking only works if all headings are indented with less +than 30 stars. This is a hard-coded limitation of ~lmax~ in +~org-clock-sum~. + +[fn:73] To resume the clock under the assumption that you have worked +on this task while outside Emacs, use =(setq org-clock-persist t)=. + +[fn:74] To add an effort estimate "on the fly", hook a function doing +this to ~org-clock-in-prepare-hook~. + +[fn:75] The last reset of the task is recorded by the =LAST_REPEAT= +property. + +[fn:76] See also the variable ~org-clock-mode-line-total~. + +[fn:77] The corresponding in-buffer setting is: =#+STARTUP: +lognoteclock-out=. + +[fn:78] When using ~:step~, ~untilnow~ starts from the beginning of +2003, not the beginning of time. + +[fn:79] Language terms can be set through the variable +~org-clock-clocktable-language-setup~. + +[fn:80] Note that all parameters must be specified in a single +line---the line is broken here only to fit it into the manual. + +[fn:81] On computers using macOS, idleness is based on actual user +idleness, not just Emacs' idle time. For X11, you can install +a utility program =x11idle.c=, available in the =contrib/scripts/= +directory of the Org Git distribution, or install the xprintidle +package and set it to the variable ~org-clock-x11idle-program-name~ if +you are running Debian, to get the same general treatment of idleness. +On other systems, idle time refers to Emacs idle time only. + +[fn:82] Please note the pitfalls of summing hierarchical data in +a flat list (see [[*Using Column View in the Agenda]]). + +[fn:83] Note the corresponding =STARTUP= options =logrefile=, +=lognoterefile=, and =nologrefile=. + +[fn:84] Org used to offer four different targets for date/week tree +capture. Now, Org automatically translates these to use +~file+olp+datetree~, applying the ~:time-prompt~ and ~:tree-type~ +properties. Please rewrite your date/week-tree targets using +~file+olp+datetree~ since the older targets are now deprecated. + +[fn:85] A date tree is an outline structure with years on the highest +level, months or ISO weeks as sublevels and then dates on the lowest +level. Tags are allowed in the tree structure. + +[fn:86] When the file name is not absolute, Org assumes it is relative +to ~org-directory~. + +[fn:87] If you need one of these sequences literally, escape the =%= +with a backslash. + +[fn:88] If you define your own link types (see [[*Adding Hyperlink +Types]]), any property you store with ~org-store-link-props~ can be +accessed in capture templates in a similar way. + +[fn:89] This is always the other, not the user. See the variable +~org-link-from-user-regexp~. + +[fn:90] If you move entries or Org files from one directory to +another, you may want to configure ~org-attach-id-dir~ to contain +an absolute path. + +[fn:91] If the value of that variable is not a list, but a single file +name, then the list of agenda files in maintained in that external +file. + +[fn:92] When using the dispatcher, pressing {{{kbd(<)}}} before +selecting a command actually limits the command to the current file, +and ignores ~org-agenda-files~ until the next dispatcher command. + +[fn:93] For backward compatibility, you can also press {{{kbd(1)}}} to +restrict to the current buffer. + +[fn:94] For backward compatibility, you can also press {{{kbd(0)}}} to +restrict to the current region/subtree. + +[fn:95] For backward compatibility, the universal prefix argument +{{{kbd(C-u)}}} causes all TODO entries to be listed before the agenda. +This feature is deprecated, use the dedicated TODO list, or a block +agenda instead (see [[*Block agenda]]). + +[fn:96] The variable ~org-anniversary~ used in the example is just +like ~diary-anniversary~, but the argument order is always according +to ISO and therefore independent of the value of +~calendar-date-style~. + +[fn:97] You can, however, disable this by setting +~org-agenda-search-headline-for-time~ variable to a ~nil~ value. + +[fn:98] Custom agenda commands can preset a filter by binding one of +the variables ~org-agenda-tag-filter-preset~, +~org-agenda-category-filter-preset~, ~org-agenda-effort-filter-preset~ +or ~org-agenda-regexp-filter-preset~ as an option. This filter is +then applied to the view and persists as a basic filter through +refreshes and more secondary filtering. The filter is a global +property of the entire agenda view---in a block agenda, you should +only set this in the global options section, not in the section of an +individual block. + +[fn:99] Only tags filtering is respected here, effort filtering is +ignored. + +[fn:100] You can also create persistent custom functions through +~org-agenda-bulk-custom-functions~. + +[fn:101] This file is parsed for the agenda when +~org-agenda-include-diary~ is set. + +[fn:102] You can provide a description for a prefix key by inserting +a cons cell with the prefix and the description. + +[fn:103] /Planned/ means here that these entries have some planning +information attached to them, like a time-stamp, a scheduled or +a deadline string. See ~org-agenda-entry-types~ on how to set what +planning information is taken into account. + +[fn:104] For HTML you need to install Hrvoje Nikšić's =htmlize.el= +as an Emacs package from MELPA or from [[https://github.com/hniksic/emacs-htmlize][Hrvoje Nikšić's repository]]. + +[fn:105] To create PDF output, the Ghostscript ps2pdf utility must be +installed on the system. Selecting a PDF file also creates the +postscript file. + +[fn:106] If you want to store standard views like the weekly agenda or +the global TODO list as well, you need to define custom commands for +them in order to be able to specify file names. + +[fn:107] Quoting depends on the system you use, please check the FAQ +for examples. + +[fn:108] You can turn this on by default by setting the variable +~org-pretty-entities~, or on a per-file base with the =STARTUP= option +=entitiespretty=. + +[fn:109] This behavior can be disabled with =-= export setting (see +[[*Export Settings]]). + +[fn:110] LaTeX is a macro system based on Donald\nbsp{}E.\nbsp{}Knuth's TeX +system. Many of the features described here as "LaTeX" are really +from TeX, but for simplicity I am blurring this distinction. + +[fn:111] When MathJax is used, only the environments recognized by +MathJax are processed. When dvipng, dvisvgm, or ImageMagick suite is +used to create images, any LaTeX environment is handled. + +[fn:112] These are respectively available at +[[http://sourceforge.net/projects/dvipng/]], [[http://dvisvgm.bplaced.net/]] +and from the ImageMagick suite. Choose the converter by setting the +variable ~org-preview-latex-default-process~ accordingly. + +[fn:113] Org mode has a method to test if point is inside such +a fragment, see the documentation of the function +~org-inside-LaTeX-fragment-p~. + +[fn:114] This works automatically for the HTML backend (it requires +version 1.34 of the =htmlize.el= package, which you need to install). +Fontified code chunks in LaTeX can be achieved using either the +[[https://www.ctan.org/pkg/listings][listings]] package or the [[https://www.ctan.org/pkg/minted][minted]] package. Refer to +~org-export-latex-listings~ for details. + +[fn:115] Source code in code blocks may also be evaluated either +interactively or on export. See [[*Working with Source Code]] for more +information on evaluating code blocks. + +[fn:116] Adding =-k= to =-n -r= /keeps/ the labels in the source code +while using line numbers for the links, which might be useful to +explain those in an Org mode example code. + +[fn:117] You may select a different mode with the variable +~org-edit-fixed-width-region-mode~. + +[fn:118] What Emacs considers to be an image depends on +~image-file-name-extensions~ and ~image-file-name-regexps~. + +[fn:119] The variable ~org-startup-with-inline-images~ can be set +within a buffer with the =STARTUP= options =inlineimages= and +=noinlineimages=. + +[fn:120] The corresponding in-buffer setting is: =#+STARTUP: fninline= +or =#+STARTUP: nofninline=. + +[fn:121] The corresponding in-buffer options are =#+STARTUP: fnadjust= +and =#+STARTUP: nofnadjust=. + +[fn:122] The variable ~org-export-date-timestamp-format~ defines how +this timestamp are exported. + +[fn:123] DEFINITION NOT FOUND. + +[fn:124] At the moment, some export back-ends do not obey this +specification. For example, LaTeX export excludes every unnumbered +headline from the table of contents. + +[fn:125] Note that ~org-link-search-must-match-exact-headline~ is +locally bound to non-~nil~. Therefore, ~org-link-search~ only matches +headlines and named elements. + +[fn:126] Since commas separate the arguments, commas within arguments +have to be escaped with the backslash character. So only those +backslash characters before a comma need escaping with another +backslash character. + +[fn:127] For a less drastic behavior, consider using a select tag (see +[[*Export Settings]]) instead. + +[fn:128] If =BEAMER_ENV= is set, Org export adds =B_environment= tag +to make it visible. The tag serves as a visual aid and has no +semantic relevance. + +[fn:129] By default Org loads MathJax from [[https://cdnjs.com][cdnjs.com]] as recommended by +[[http://www.mathjax.org][MathJax]]. + +[fn:130] Please note that exported formulas are part of an HTML +document, and that signs such as =<=, =>=, or =&= have special +meanings. See [[http://docs.mathjax.org/en/latest/tex.html#tex-and-latex-in-html-documents][MathJax TeX and LaTeX support]]. + +[fn:131] See [[http://docs.mathjax.org/en/latest/tex.html#tex-extensions][TeX and LaTeX extensions]] in the [[http://docs.mathjax.org][MathJax manual]] to learn +about extensions. + +[fn:132] If the classes on TODO keywords and tags lead to conflicts, +use the variables ~org-html-todo-kwd-class-prefix~ and +~org-html-tag-class-prefix~ to make them unique. + +[fn:133] This does not allow setting different bibliography compilers +for different files. However, "smart" LaTeX compilation systems, such +as latexmk, can select the correct bibliography compiler. + +[fn:134] See [[http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html][Open Document Format for Office Applications +(OpenDocument) Version 1.2]]. + +[fn:135] See [[http://www.mathtoweb.com/cgi-bin/mathtoweb_home.pl][MathToWeb]]. + +[fn:136] See [[http://dlmf.nist.gov/LaTeXML/]]. + +[fn:137] [[http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html][OpenDocument-v1.2 Specification]] + +[fn:138] See the == element of the +OpenDocument-v1.2 specification. + +[fn:139] See the attributes =table:template-name=, +=table:use-first-row-styles=, =table:use-last-row-styles=, +=table:use-first-column-styles=, =table:use-last-column-styles=, +=table:use-banding-rows-styles=, and =table:use-banding-column-styles= +of the == element in the OpenDocument-v1.2 specification. + +[fn:140] If the publishing directory is the same as the source +directory, =file.org= is exported as =file.org.org=, so you probably +do not want to do this. + +[fn:141] The option ~org-babel-no-eval-on-ctrl-c-ctrl-c~ can be used +to remove code evaluation from the {{{kbd(C-c C-c)}}} key binding. + +[fn:142] Actually, the constructs =call_()= and =src_{}= +are not evaluated when they appear in a keyword (see [[*Summary of +In-Buffer Settings]]). + +[fn:143] C++ language is handled in =ob-C.el=. Even though the +identifier for such source blocks is =C++=, you activate it by loading +the C language. + +[fn:144] D language is handled in =ob-C.el=. Even though the +identifier for such source blocks is =D=, you activate it by loading +the C language. + +[fn:145] For noweb literate programming details, see +http://www.cs.tufts.edu/~nr/noweb/. + +[fn:146] For more information, please refer to the commentary section +in =org-tempo.el=. + +[fn:147] Org Indent mode also sets ~wrap-prefix~ correctly for +indenting and wrapping long lines of headlines or text. This minor +mode also handles Visual Line mode and directly applied settings +through ~word-wrap~. + +[fn:148] This works, but requires extra effort. Org Indent mode is +more convenient for most applications. + +[fn:149] ~org-adapt-indentation~ can also be set to ='headline-data=, +in which case only data lines below the headline will be indented. + +[fn:150] Note that Org Indent mode also sets the ~wrap-prefix~ +property, such that Visual Line mode (or purely setting ~word-wrap~) +wraps long lines, including headlines, correctly indented. + +[fn:151] For a server to host files, consider using a WebDAV server, +such as [[https://nextcloud.com][Nextcloud]]. Additional help is at this [[https://orgmode.org/worg/org-faq.html#mobileorg_webdav][FAQ entry]]. + +[fn:152] If Emacs is configured for safe storing of passwords, then +configure the variable ~org-mobile-encryption-password~; please read +the docstring of that variable. + +[fn:153] Symbolic links in ~org-directory~ need to have the same name +as their targets. + +[fn:154] While creating the agendas, Org mode forces =ID= properties +on all referenced entries, so that these entries can be uniquely +identified if Org Mobile flags them for further action. To avoid +setting properties configure the variable +~org-mobile-force-id-on-agenda-items~ to ~nil~. Org mode then relies +on outline paths, assuming they are unique. + +[fn:155] Checksums are stored automatically in the file +=checksums.dat=. + +[fn:156] The file will be empty after this operation. + +[fn:157] https://www.ctan.org/pkg/comment + +[fn:158] By default this works only for LaTeX, HTML, and Texinfo. +Configure the variable ~orgtbl-radio-table-templates~ to install +templates for other modes. + +[fn:159] If the =TBLFM= keyword contains an odd number of dollar +characters, this may cause problems with Font Lock in LaTeX mode. As +shown in the example you can fix this by adding an extra line inside +the =comment= environment that is used to balance the dollar +expressions. If you are using AUCTeX with the font-latex library, +a much better solution is to add the =comment= environment to the +variable ~LaTeX-verbatim-environments~. + +[fn:160] The ~agenda*~ view is the same as ~agenda~ except that it +only considers /appointments/, i.e., scheduled and deadline items that +have a time specification =[h]h:mm= in their time-stamps. + +[fn:161] Note that, for ~org-odd-levels-only~, a level number +corresponds to order in the hierarchy, not to the number of stars. diff --git a/doc/misc/org.texi b/doc/misc/org.texi deleted file mode 100644 index 8902d62887..0000000000 --- a/doc/misc/org.texi +++ /dev/null @@ -1,23148 +0,0 @@ -\input texinfo @c -*- texinfo -*- -@c %**start of header -@setfilename org.info -@settitle The Org Manual -@documentencoding UTF-8 -@documentlanguage en -@set txicodequoteundirected -@set txicodequotebacktick -@set MAINTAINERSITE @uref{https://orgmode.org,maintainers webpage} -@set MAINTAINER Bastien Guerry -@set MAINTAINEREMAIL @email{bzg@gnu.org} -@set MAINTAINERCONTACT @uref{mailto:bzg@gnu.org,contact the maintainer} -@c %**end of header - -@copying -This manual is for Org version 9.4. - -Copyright @copyright{} 2004--2021 Free Software Foundation, Inc. - -@quotation -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.3 or -any later version published by the Free Software Foundation; with no -Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,'' -and with the Back-Cover Texts as in (a) below. A copy of the license -is included in the section entitled ``GNU Free Documentation License.'' - -(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and -modify this GNU manual.'' - -@end quotation -@end copying - -@dircategory Emacs editing modes -@direntry -* Org Mode: (org). Outline-based notes management and organizer. -@end direntry - -@finalout -@titlepage -@title The Org Manual -@subtitle Release 9.4 -@author The Org Mode Developers -@page -@vskip 0pt plus 1filll -@insertcopying -@end titlepage - -@contents - -@ifnottex -@node Top -@top The Org Manual - -@insertcopying -@end ifnottex - -@menu -* Introduction:: Getting started. -* Document Structure:: A tree works like your brain. -* Tables:: Pure magic for quick formatting. -* Hyperlinks:: Notes in context. -* TODO Items:: Every tree branch can be a TODO item. -* Tags:: Tagging headlines and matching sets of tags. -* Properties and Columns:: Storing information about an entry. -* Dates and Times:: Making items useful for planning. -* Refiling and Archiving:: Moving and copying information with ease. -* Capture and Attachments:: Dealing with external data. -* Agenda Views:: Collecting information into views. -* Markup for Rich Contents:: Compose beautiful documents. -* Exporting:: Sharing and publishing notes. -* Publishing:: Create a web site of linked Org files. -* Working with Source Code:: Export, evaluate, and tangle code blocks. -* Miscellaneous:: All the rest which did not fit elsewhere. -* Hacking:: How to hack your way around. -* History and Acknowledgments:: How Org came into being. -* GNU Free Documentation License:: The license for this documentation. -* Main Index:: An index of Org's concepts and features. -* Key Index:: Key bindings and where they are described. -* Command and Function Index:: Command names and some internal functions. -* Variable Index:: Variables mentioned in the manual. - -@detailmenu ---- The Detailed Node Listing --- - -Introduction - -* Summary:: Brief summary of what Org does. -* Installation:: Installing Org. -* Activation:: How to activate Org for certain buffers. -* Feedback:: Bug reports, ideas, patches, etc. -* Conventions:: Typesetting conventions used in this manual. - -Document Structure - -* Headlines:: How to typeset Org tree headlines. -* Visibility Cycling:: Show and hide, much simplified. -* Motion:: Jumping to other headlines. -* Structure Editing:: Changing sequence and level of headlines. -* Sparse Trees:: Matches embedded in context. -* Plain Lists:: Additional structure within an entry. -* Drawers:: Tucking stuff away. -* Blocks:: Folding blocks. - -Visibility Cycling - -* Global and local cycling:: Cycling through various visibility states. -* Initial visibility:: Setting the initial visibility state. -* Catching invisible edits:: Preventing mistakes when editing invisible parts. - -Tables - -* Built-in Table Editor:: Simple tables. -* Column Width and Alignment:: Overrule the automatic settings. -* Column Groups:: Grouping to trigger vertical lines. -* Orgtbl Mode:: The table editor as minor mode. -* The Spreadsheet:: The table editor has spreadsheet capabilities. -* Org Plot:: Plotting from Org tables. - -The Spreadsheet - -* References:: How to refer to another field or range. -* Formula syntax for Calc:: Using Calc to compute stuff. -* Formula syntax for Lisp:: Writing formulas in Emacs Lisp. -* Durations and time values:: How to compute durations and time values. -* Field and range formulas:: Formula for specific (ranges of) fields. -* Column formulas:: Formulas valid for an entire column. -* Lookup functions:: Lookup functions for searching tables. -* Editing and debugging formulas:: Fixing formulas. -* Updating the table:: Recomputing all dependent fields. -* Advanced features:: Field and column names, automatic recalculation... - -Hyperlinks - -* Link Format:: How links in Org are formatted. -* Internal Links:: Links to other places in the current file. -* Radio Targets:: Make targets trigger links in plain text. -* External Links:: URL-like links to the world. -* Handling Links:: Creating, inserting and following. -* Using Links Outside Org:: Linking from my C source code? -* Link Abbreviations:: Shortcuts for writing complex links. -* Search Options:: Linking to a specific location. -* Custom Searches:: When the default search is not enough. - -TODO Items - -* TODO Basics:: Marking and displaying TODO entries. -* TODO Extensions:: Workflow and assignments. -* Progress Logging:: Dates and notes for progress. -* Priorities:: Some things are more important than others. -* Breaking Down Tasks:: Splitting a task into manageable pieces. -* Checkboxes:: Tick-off lists. - -TODO Extensions - -* Workflow states:: From TODO to DONE in steps. -* TODO types:: I do this, Fred does the rest. -* Multiple sets in one file:: Mixing it all, still finding your way. -* Fast access to TODO states:: Single letter selection of state. -* Per-file keywords:: Different files, different requirements. -* Faces for TODO keywords:: Highlighting states. -* TODO dependencies:: When one task needs to wait for others. - -Progress Logging - -* Closing items:: When was this entry marked as done? -* Tracking TODO state changes:: When did the status change? -* Tracking your habits:: How consistent have you been? - -Tags - -* Tag Inheritance:: Tags use the tree structure of an outline. -* Setting Tags:: How to assign tags to a headline. -* Tag Hierarchy:: Create a hierarchy of tags. -* Tag Searches:: Searching for combinations of tags. - -Properties and Columns - -* Property Syntax:: How properties are spelled out. -* Special Properties:: Access to other Org mode features. -* Property Searches:: Matching property values. -* Property Inheritance:: Passing values down a tree. -* Column View:: Tabular viewing and editing. - -Column View - -* Defining columns:: The COLUMNS format property. -* Using column view:: How to create and use column view. -* Capturing column view:: A dynamic block for column view. - -Defining columns - -* Scope of column definitions:: Where defined, where valid? -* Column attributes:: Appearance and content of a column. - -Dates and Times - -* Timestamps:: Assigning a time to a tree entry. -* Creating Timestamps:: Commands to insert timestamps. -* Deadlines and Scheduling:: Planning your work. -* Clocking Work Time:: Tracking how long you spend on a task. -* Effort Estimates:: Planning work effort in advance. -* Timers:: Notes with a running timer. - -Creating Timestamps - -* The date/time prompt:: How Org mode helps you enter dates and times. -* Custom time format:: Making dates look different. - -Deadlines and Scheduling - -* Inserting deadline/schedule:: Planning items. -* Repeated tasks:: Items that show up again and again. - -Clocking Work Time - -* Clocking commands:: Starting and stopping a clock. -* The clock table:: Detailed reports. -* Resolving idle time:: Resolving time when you've been idle. - -Refiling and Archiving - -* Refile and Copy:: Moving/copying a tree from one place to another. -* Archiving:: What to do with finished products. - -Archiving - -* Moving subtrees:: Moving a tree to an archive file. -* Internal archiving:: Switch off a tree but keep it in the file. - -Capture and Attachments - -* Capture:: Capturing new stuff. -* Attachments:: Attach files to outlines. -* RSS Feeds:: Getting input from RSS feeds. - -Capture - -* Setting up capture:: Where notes will be stored. -* Using capture:: Commands to invoke and terminate capture. -* Capture templates:: Define the outline of different note types. - -Capture templates - -* Template elements:: What is needed for a complete template entry. -* Template expansion:: Filling in information about time and context. -* Templates in contexts:: Only show a template in a specific context. - -Attachments - -* Attachment defaults and dispatcher:: How to access attachment commands -* Attachment options:: Configuring the attachment system -* Attachment links:: Hyperlink access to attachments -* Automatic version-control with Git:: Everything safely stored away -* Attach from Dired:: Using dired to select an attachment - -Agenda Views - -* Agenda Files:: Files being searched for agenda information. -* Agenda Dispatcher:: Keyboard access to agenda views. -* Built-in Agenda Views:: What is available out of the box? -* Presentation and Sorting:: How agenda items are prepared for display. -* Agenda Commands:: Remote editing of Org trees. -* Custom Agenda Views:: Defining special searches and views. -* Exporting Agenda Views:: Writing a view to a file. -* Agenda Column View:: Using column view for collected entries. - -Built-in Agenda Views - -* Weekly/daily agenda:: The calendar page with current tasks. -* Global TODO list:: All unfinished action items. -* Matching tags and properties:: Structured information with fine-tuned search. -* Search view:: Find entries by searching for text. -* Stuck projects:: Find projects you need to review. - -Presentation and Sorting - -* Categories:: Not all tasks are equal. -* Time-of-day specifications:: How the agenda knows the time. -* Sorting of agenda items:: The order of things. -* Filtering/limiting agenda items:: Dynamically narrow the agenda. - -Custom Agenda Views - -* Storing searches:: Type once, use often. -* Block agenda:: All the stuff you need in a single buffer. -* Setting options:: Changing the rules. - -Markup for Rich Contents - -* Paragraphs:: The basic unit of text. -* Emphasis and Monospace:: Bold, italic, etc. -* Subscripts and Superscripts:: Simple syntax for raising/lowering text. -* Special Symbols:: Greek letters and other symbols. -* Embedded @LaTeX{}:: LaTeX can be freely used inside Org documents. -* Literal Examples:: Source code examples with special formatting. -* Images:: Display an image. -* Captions:: Describe tables, images... -* Horizontal Rules:: Make a line. -* Creating Footnotes:: Edit and read footnotes. - -Embedded @LaTeX{} - -* @LaTeX{} fragments:: Complex formulas made easy. -* Previewing @LaTeX{} fragments:: What will this snippet look like? -* CD@LaTeX{} mode:: Speed up entering of formulas. - -Exporting - -* The Export Dispatcher:: The main interface. -* Export Settings:: Common export settings. -* Table of Contents:: The if and where of the table of contents. -* Include Files:: Include additional files into a document. -* Macro Replacement:: Use macros to create templates. -* Comment Lines:: What will not be exported. -* ASCII/Latin-1/UTF-8 export:: Exporting to flat files with encoding. -* Beamer Export:: Producing presentations and slides. -* HTML Export:: Exporting to HTML. -* @LaTeX{} Export:: Exporting to @LaTeX{} and processing to PDF. -* Markdown Export:: Exporting to Markdown. -* OpenDocument Text Export:: Exporting to OpenDocument Text. -* Org Export:: Exporting to Org. -* Texinfo Export:: Exporting to Texinfo. -* iCalendar Export:: Exporting to iCalendar. -* Other Built-in Back-ends:: Exporting to a man page. -* Advanced Export Configuration:: Fine-tuning the export output. -* Export in Foreign Buffers:: Author tables and lists in Org syntax. - -Beamer Export - -* Beamer export commands:: For creating Beamer documents. -* Beamer specific export settings:: For customizing Beamer export. -* Frames and Blocks in Beamer:: For composing Beamer slides. -* Beamer specific syntax:: For using in Org documents. -* Editing support:: Editing support. -* A Beamer example:: A complete presentation. - -HTML Export - -* HTML export commands:: Invoking HTML export. -* HTML specific export settings:: Settings for HTML export. -* HTML doctypes:: Exporting various (X)HTML flavors. -* HTML preamble and postamble:: Inserting preamble and postamble. -* Quoting HTML tags:: Using direct HTML in Org files. -* Headlines in HTML export:: Formatting headlines. -* Links in HTML export:: Inserting and formatting links. -* Tables in HTML export:: How to modify the formatting of tables. -* Images in HTML export:: How to insert figures into HTML output. -* Math formatting in HTML export:: Beautiful math also on the web. -* Text areas in HTML export:: An alternate way to show an example. -* CSS support:: Changing the appearance of the output. -* JavaScript support:: Info and folding in a web browser. - -@LaTeX{} Export - -* @LaTeX{}/PDF export commands:: For producing @LaTeX{} and PDF documents. -* @LaTeX{} specific export settings:: Unique to this @LaTeX{} back-end. -* @LaTeX{} header and sectioning:: Setting up the export file structure. -* Quoting @LaTeX{} code:: Incorporating literal @LaTeX{} code. -* Tables in @LaTeX{} export:: Options for exporting tables to @LaTeX{}. -* Images in @LaTeX{} export:: How to insert figures into @LaTeX{} output. -* Plain lists in @LaTeX{} export:: Attributes specific to lists. -* Source blocks in @LaTeX{} export:: Attributes specific to source code blocks. -* Example blocks in @LaTeX{} export:: Attributes specific to example blocks. -* Special blocks in @LaTeX{} export:: Attributes specific to special blocks. -* Horizontal rules in @LaTeX{} export:: Attributes specific to horizontal rules. - -OpenDocument Text Export - -* Pre-requisites for ODT export:: Required packages. -* ODT export commands:: Invoking export. -* ODT specific export settings:: Configuration options. -* Extending ODT export:: Producing DOC, PDF files. -* Applying custom styles:: Styling the output. -* Links in ODT export:: Handling and formatting links. -* Tables in ODT export:: Org tables conversions. -* Images in ODT export:: Inserting images. -* Math formatting in ODT export:: Formatting @LaTeX{} fragments. -* Labels and captions in ODT export:: Rendering objects. -* Literal examples in ODT export:: For source code and example blocks. -* Advanced topics in ODT export:: For power users. - -Math formatting in ODT export - -* @LaTeX{} math snippets:: Embedding in @LaTeX{} format. -* MathML and OpenDocument formula files:: Embedding in native format. - -Texinfo Export - -* Texinfo export commands:: Invoking commands. -* Texinfo specific export settings:: Setting the environment. -* Texinfo file header:: Generating the header. -* Texinfo title and copyright page:: Creating preamble pages. -* Info directory file:: Installing a manual in Info file hierarchy. -* Headings and sectioning structure:: Building document structure. -* Indices:: Creating indices. -* Quoting Texinfo code:: Incorporating literal Texinfo code. -* Plain lists in Texinfo export:: List attributes. -* Tables in Texinfo export:: Table attributes. -* Images in Texinfo export:: Image attributes. -* Quotations in Texinfo export:: Quote block attributes. -* Special blocks in Texinfo export:: Special block attributes. -* A Texinfo example:: Processing Org to Texinfo. - -Export in Foreign Buffers - -* Bare HTML:: Exporting HTML without CSS, Javascript, etc. - -Publishing - -* Configuration:: Defining projects. -* Uploading Files:: How to get files up on the server. -* Sample Configuration:: Example projects. -* Triggering Publication:: Publication commands. - -Configuration - -* Project alist:: The central configuration variable. -* Sources and destinations:: From here to there. -* Selecting files:: What files are part of the project? -* Publishing action:: Setting the function doing the publishing. -* Publishing options:: Tweaking HTML/@LaTeX{} export. -* Publishing links:: Which links keep working after publishing? -* Site map:: Generating a list of all pages. -* Generating an index:: An index that reaches across pages. - -Sample Configuration - -* Simple example:: One-component publishing. -* Complex example:: A multi-component publishing example. - -Working with Source Code - -* Features Overview:: Enjoy the versatility of source blocks. -* Structure of Code Blocks:: Code block syntax described. -* Using Header Arguments:: Different ways to set header arguments. -* Environment of a Code Block:: Arguments, sessions, working directory... -* Evaluating Code Blocks:: Place results of evaluation in the Org buffer. -* Results of Evaluation:: Choosing a results type, post-processing... -* Exporting Code Blocks:: Export contents and/or results. -* Extracting Source Code:: Create pure source code files. -* Languages:: List of supported code block languages. -* Editing Source Code:: Language major-mode editing. -* Noweb Reference Syntax:: Literate programming in Org mode. -* Library of Babel:: Use and contribute to a library of useful code blocks. -* Key bindings and Useful Functions:: Work quickly with code blocks. -* Batch Execution:: Call functions from the command line. - -Miscellaneous - -* Completion:: @kbd{M-@key{TAB}} guesses completions. -* Structure Templates:: Quick insertion of structural elements. -* Speed Keys:: Electric commands at the beginning of a headline. -* Clean View:: Getting rid of leading stars in the outline. -* Execute commands in the active region:: Execute commands on multiple items in Org or agenda view. -* Dynamic Headline Numbering:: Display and update outline numbering. -* The Very Busy @kbd{C-c C-c} Key:: When in doubt, press @kbd{C-c C-c}. -* In-buffer Settings:: Overview of keywords. -* Org Syntax:: Formal description of Org's syntax. -* Documentation Access:: Read documentation about current syntax. -* Escape Character:: Prevent Org from interpreting your writing. -* Code Evaluation Security:: Org files evaluate in-line code. -* Interaction:: With other Emacs packages. -* TTY Keys:: Using Org on a tty. -* Protocols:: External access to Emacs and Org. -* Org Crypt:: Encrypting Org files. -* Org Mobile:: Viewing and capture on a mobile device. - -Clean View - -* Org Indent Mode:: -* Hard indentation:: - -Interaction - -* Cooperation:: Packages Org cooperates with. -* Conflicts:: Packages that lead to conflicts. - -Protocols - -* The @code{store-link} protocol:: Store a link, push URL to kill-ring. -* The @code{capture} protocol:: Fill a buffer with external information. -* The @code{open-source} protocol:: Edit published contents. - -Org Mobile - -* Setting up the staging area:: For the mobile device. -* Pushing to the mobile application:: Uploading Org files and agendas. -* Pulling from the mobile application:: Integrating captured and flagged items. - -Hacking - -* Hooks: Hooks (2). How to reach into Org's internals. -* Add-on Packages:: Available extensions. -* Adding Hyperlink Types:: New custom link types. -* Adding Export Back-ends:: How to write new export back-ends. -* Tables in Arbitrary Syntax:: Orgtbl for LaTeX and other programs. -* Dynamic Blocks:: Automatically filled blocks. -* Special Agenda Views:: Customized views. -* Speeding Up Your Agendas:: Tips on how to speed up your agendas. -* Extracting Agenda Information:: Post-processing agenda information. -* Using the Property API:: Writing programs that use entry properties. -* Using the Mapping API:: Mapping over all or selected entries. - -Tables in Arbitrary Syntax - -* Radio tables:: Sending and receiving radio tables. -* A @LaTeX{} example:: Step by step, almost a tutorial. -* Translator functions:: Copy and modify. - -@end detailmenu -@end menu - -@node Introduction -@chapter Introduction - -@cindex introduction - -@menu -* Summary:: Brief summary of what Org does. -* Installation:: Installing Org. -* Activation:: How to activate Org for certain buffers. -* Feedback:: Bug reports, ideas, patches, etc. -* Conventions:: Typesetting conventions used in this manual. -@end menu - -@node Summary -@section Summary - -@cindex summary - -Org is a mode for keeping notes, maintaining TODO lists, and project -planning with a fast and effective plain-text markup language. It -also is an authoring system with unique support for literate -programming and reproducible research. - -Org is implemented on top of Outline mode, which makes it possible to -keep the content of large files well structured. Visibility cycling -and structure editing help to work with the tree. Tables are easily -created with a built-in table editor. Plain text URL-like links -connect to websites, emails, Usenet messages, BBDB entries, and any -files related to the projects. - -Org develops organizational tasks around notes files that contain -lists or information about projects as plain text. Project planning -and task management make use of metadata which is part of an outline -node. Based on this data, specific entries can be extracted in -queries and create dynamic @emph{agenda views} that also integrate the -Emacs calendar and diary. Org can be used to implement many different -project planning schemes, such as David Allen's GTD system. - -Org files can serve as a single source authoring system with export to -many different formats such as HTML, @LaTeX{}, Open Document, and -Markdown. New export backends can be derived from existing ones, or -defined from scratch. - -Org files can include source code blocks, which makes Org uniquely -suited for authoring technical documents with code examples. Org -source code blocks are fully functional; they can be evaluated in -place and their results can be captured in the file. This makes it -possible to create a single file reproducible research compendium. - -Org keeps simple things simple. When first fired up, it should feel -like a straightforward, easy to use outliner. Complexity is not -imposed, but a large amount of functionality is available when needed. -Org is a toolbox. Many users actually run only a---very -personal---fraction of Org's capabilities, and know that there is more -whenever they need it. - -All of this is achieved with strictly plain text files, the most -portable and future-proof file format. Org runs in Emacs. Emacs is -one of the most widely ported programs, so that Org mode is available -on every major platform. - -@cindex FAQ -There is a website for Org which provides links to the newest version -of Org, as well as additional information, frequently asked questions -(FAQ), links to tutorials, etc. This page is located at -@uref{https://orgmode.org}. - -@cindex print edition -An earlier version (7.3) of this manual is available as a @uref{http://www.network-theory.co.uk/org/manual/, paperback -book from Network Theory Ltd.}. - -@node Installation -@section Installation - -@cindex installation - -Org is included in all recent distributions of GNU Emacs, so you -probably do not need to install it. Most users will simply activate -Org and begin exploring its many features. - -If, for one reason or another, you want to install Org on top of this -pre-packaged version, there are three ways to do it: - -@itemize -@item -by using the Emacs package system; -@item -by downloading Org as an archive; or -@item -by using Org's git repository. -@end itemize - -We @strong{strongly recommend} sticking to a single installation method. - -@anchor{Using Emacs packaging system} -@subheading Using Emacs packaging system - -Recent Emacs distributions include a packaging system which lets you -install Elisp libraries. You can install Org from the ``package menu'', -with @kbd{M-x list-packages}. See @ref{Package Menu,Package Menu,,emacs,}. - -@quotation Important -You need to do this in a session where no @samp{.org} file has been -visited, i.e., where no Org built-in function have been loaded. -Otherwise autoload Org functions will mess up the installation. - -@end quotation - -If you want to use Org's package repository, check out the @uref{https://orgmode.org/elpa.html, Org ELPA -page}. - -@anchor{Downloading Org as an archive} -@subheading Downloading Org as an archive - -You can download Org latest release from @uref{https://orgmode.org/, Org's website}. In this case, -make sure you set the load path correctly in your Emacs init file: - -@lisp -(add-to-list 'load-path "~/path/to/orgdir/lisp") -@end lisp - -The downloaded archive contains contributed libraries that are not -included in Emacs. If you want to use them, add the @samp{contrib/} -directory to your load path: - -@lisp -(add-to-list 'load-path "~/path/to/orgdir/contrib/lisp" t) -@end lisp - -Optionally, you can compile the files and/or install them in your -system. Run @samp{make help} to list compilation and installation options. - -@anchor{Using Org's git repository} -@subheading Using Org's git repository - -You can clone Org's repository and install Org like this: - -@example -$ cd ~/src/ -$ git clone https://code.orgmode.org/bzg/org-mode.git -$ cd org-mode/ -$ make autoloads -@end example - -Note that in this case, @samp{make autoloads} is mandatory: it defines -Org's version in @samp{org-version.el} and Org's autoloads in -@samp{org-loaddefs.el}. - -Remember to add the correct load path as described in the method -above. - -You can also compile with @samp{make}, generate the documentation with -@samp{make doc}, create a local configuration with @samp{make config} and -install Org with @samp{make install}. Please run @samp{make help} to get the -list of compilation/installation options. - -For more detailed explanations on Org's build system, please check the -Org Build System page on @uref{https://orgmode.org/worg/dev/org-build-system.html, Worg}. - -@node Activation -@section Activation - -@cindex activation -@cindex autoload -@cindex ELPA -@cindex global key bindings -@cindex key bindings, global - -Org mode buffers need Font Lock to be turned on: this is the default -in Emacs@footnote{If you do not use Font Lock globally turn it on in Org buffer -with @samp{(add-hook 'org-mode-hook 'turn-on-font-lock)}.}. - -There are compatibility issues between Org mode and some other Elisp -packages (see @ref{Conflicts}). Please take the -time to check the list. - -@findex org-agenda -@findex org-capture -@findex org-store-link -For a better experience, the three Org commands @code{org-store-link}, -@code{org-capture} and @code{org-agenda} ought to be accessible anywhere in -Emacs, not just in Org buffers. To that effect, you need to bind them -to globally available keys, like the ones reserved for users (see -@ref{Key Binding Conventions,,,elisp,}). Here are suggested bindings, -please modify the keys to your own liking. - -@lisp -(global-set-key (kbd "C-c l") 'org-store-link) -(global-set-key (kbd "C-c a") 'org-agenda) -(global-set-key (kbd "C-c c") 'org-capture) -@end lisp - -@cindex Org mode, turning on -Files with the @samp{.org} extension use Org mode by default. To turn on -Org mode in a file that does not have the extension @samp{.org}, make the -first line of a file look like this: - -@example -MY PROJECTS -*- mode: org; -*- -@end example - - -@vindex org-insert-mode-line-in-empty-file -@noindent -which selects Org mode for this buffer no matter what the file's name -is. See also the variable @code{org-insert-mode-line-in-empty-file}. - -Many commands in Org work on the region if the region is @emph{active}. To -make use of this, you need to have Transient Mark mode turned on, -which is the default. If you do not like it, you can create an active -region by using the mouse to select a region, or pressing -@kbd{C-@key{SPC}} twice before moving point. - -@node Feedback -@section Feedback - -@cindex feedback -@cindex bug reports -@cindex reporting a bug -@cindex maintainer -@cindex author - -If you find problems with Org, or if you have questions, remarks, or -ideas about it, please send an email to the Org mailing list -@email{emacs-orgmode@@gnu.org}. You can subscribe to the list @uref{https://lists.gnu.org/mailman/listinfo/emacs-orgmode, from this -web page}. If you are not a member of the mailing list, your mail will -be passed to the list after a moderator has approved it@footnote{Please consider subscribing to the mailing list in order to -minimize the work the mailing list moderators have to do.}. We ask -you to read and respect the @uref{https://www.gnu.org/philosophy/kind-communication.html, GNU Kind Communications Guidelines} when -sending messages on this mailing list. - -@findex org-version -@findex org-submit-bug-report -For bug reports, please first try to reproduce the bug with the latest -version of Org available---if you are running an outdated version, it -is quite possible that the bug has been fixed already. If the bug -persists, prepare a report and provide as much information as -possible, including the version information of Emacs (@kbd{M-x emacs-version}) and Org (@kbd{M-x org-version}), as well as -the Org related setup in the Emacs init file. The easiest way to do -this is to use the command - -@example -M-x org-submit-bug-report -@end example - - -@noindent -which puts all this information into an Emacs mail buffer so that you -only need to add your description. If you are not sending the Email -from within Emacs, please copy and paste the content into your Email -program. - -Sometimes you might face a problem due to an error in your Emacs or -Org mode setup. Before reporting a bug, it is very helpful to start -Emacs with minimal customizations and reproduce the problem. Doing so -often helps you determine if the problem is with your customization or -with Org mode itself. You can start a typical minimal session with -a command like the example below. - -@example -$ emacs -Q -l /path/to/minimal-org.el -@end example - - -However if you are using Org mode as distributed with Emacs, a minimal -setup is not necessary. In that case it is sufficient to start Emacs -as @samp{emacs -Q}. The @samp{minimal-org.el} setup file can have contents as -shown below. - -@lisp -;;; Minimal setup to load latest `org-mode'. - -;; Activate debugging. -(setq debug-on-error t - debug-on-signal nil - debug-on-quit nil) - -;; Add latest Org mode to load path. -(add-to-list 'load-path (expand-file-name "/path/to/org-mode/lisp")) -(add-to-list 'load-path (expand-file-name "/path/to/org-mode/contrib/lisp" t)) -@end lisp - -If an error occurs, a ``backtrace'' can be very useful---see below on -how to create one. Often a small example file helps, along with clear -information about: - -@enumerate -@item -What exactly did you do? -@item -What did you expect to happen? -@item -What happened instead? -@end enumerate - -Thank you for helping to improve this program. - -@anchor{How to create a useful backtrace} -@subheading How to create a useful backtrace - -@cindex backtrace of an error -If working with Org produces an error with a message you do not -understand, you may have hit a bug. The best way to report this is by -providing, in addition to what was mentioned above, a backtrace. This -is information from the built-in debugger about where and how the -error occurred. Here is how to produce a useful backtrace: - -@enumerate -@item -Reload uncompiled versions of all Org mode Lisp files. The -backtrace contains much more information if it is produced with -uncompiled code. To do this, use - -@example -C-u M-x org-reload -@end example - - -@noindent -or, from the menu: Org @arrow{} Refresh/Reload @arrow{} Reload Org uncompiled. - -@item -Then, activate the debugger: - -@example -M-x toggle-debug-on-error -@end example - - -@noindent -or, from the menu: Options @arrow{} Enter Debugger on Error. - -@item -Do whatever you have to do to hit the error. Do not forget to -document the steps you take. - -@item -When you hit the error, a @samp{*Backtrace*} buffer appears on the -screen. Save this buffer to a file---for example using @kbd{C-x C-w}---and attach it to your bug report. -@end enumerate - -@node Conventions -@section Typesetting Conventions Used in this Manual - - - -@anchor{TODO keywords tags properties etc} -@subheading TODO keywords, tags, properties, etc. - -Org uses various syntactical elements: TODO keywords, tags, property -names, keywords, blocks, etc. In this manual we use the following -conventions: - -@table @asis -@item @samp{TODO} -@itemx @samp{WAITING} -TODO keywords are written with all capitals, even if they are -user-defined. - -@item @samp{boss} -@itemx @samp{ARCHIVE} -Tags are case-sensitive. User-defined tags are written in -lowercase; built-in tags with special meaning are written as they -should appear in the document, usually with all capitals. - -@item @samp{Release} -@itemx @samp{PRIORITY} -User-defined properties are capitalized; built-in properties with -special meaning are written with all capitals. - -@item @samp{TITLE} -@itemx @samp{BEGIN} @dots{} @samp{END} -Keywords and blocks are written in uppercase to enhance their -readability, but you can use lowercase in your Org files. -@end table - -@anchor{Key bindings and commands} -@subheading Key bindings and commands - -The manual lists both the keys and the corresponding commands for -accessing a functionality. Org mode often uses the same key for -different functions, depending on context. The command that is bound -to such keys has a generic name, like @code{org-metaright}. In the manual -we will, wherever possible, give the function that is internally -called by the generic command. For example, in the chapter on -document structure, @kbd{M-@key{RIGHT}} will be listed to call -@code{org-do-demote}, while in the chapter on tables, it will be listed to -call @code{org-table-move-column-right}. - -@node Document Structure -@chapter Document Structure - -@cindex document structure -@cindex structure of document -Org is an outliner. Outlines allow a document to be organized in -a hierarchical structure, which, least for me, is the best -representation of notes and thoughts. An overview of this structure -is achieved by folding, i.e., hiding large parts of the document to -show only the general document structure and the parts currently being -worked on. Org greatly simplifies the use of outlines by compressing -the entire show and hide functionalities into a single command, -@code{org-cycle}, which is bound to the @kbd{@key{TAB}} key. - -@menu -* Headlines:: How to typeset Org tree headlines. -* Visibility Cycling:: Show and hide, much simplified. -* Motion:: Jumping to other headlines. -* Structure Editing:: Changing sequence and level of headlines. -* Sparse Trees:: Matches embedded in context. -* Plain Lists:: Additional structure within an entry. -* Drawers:: Tucking stuff away. -* Blocks:: Folding blocks. -@end menu - -@node Headlines -@section Headlines - -@cindex headlines -@cindex outline tree -@vindex org-special-ctrl-a/e -@vindex org-special-ctrl-k -@vindex org-ctrl-k-protect-subtree - -Headlines define the structure of an outline tree. Org headlines -start on the left margin@footnote{See the variables @code{org-special-ctrl-a/e}, @code{org-special-ctrl-k}, -and @code{org-ctrl-k-protect-subtree} to configure special behavior of -@kbd{C-a}, @kbd{C-e}, and @kbd{C-k} in headlines. Note -also that clocking only works with headings indented less than 30 -stars.} with one or more stars followed by -a space. For example: - -@example -* Top level headline -** Second level -*** Third level - some text -*** Third level - more text -* Another top level headline -@end example - -@vindex org-footnote-section -The name defined in @code{org-footnote-section} is reserved. Do not use it -as a title for your own headings. - -Some people find the many stars too noisy and would prefer an outline -that has whitespace followed by a single star as headline starters. -This can be achieved using a Org Indent minor mode. See @ref{Clean View} for more information. - -Headlines are not numbered. However, you may want to dynamically -number some, or all, of them. See @ref{Dynamic Headline Numbering}. - -@vindex org-cycle-separator-lines -An empty line after the end of a subtree is considered part of it and -is hidden when the subtree is folded. However, if you leave at least -two empty lines, one empty line remains visible after folding the -subtree, in order to structure the collapsed view. See the variable -@code{org-cycle-separator-lines} to modify this behavior. - -@node Visibility Cycling -@section Visibility Cycling - -@cindex cycling, visibility -@cindex visibility cycling -@cindex trees, visibility -@cindex show hidden text -@cindex hide text - -@menu -* Global and local cycling:: Cycling through various visibility states. -* Initial visibility:: Setting the initial visibility state. -* Catching invisible edits:: Preventing mistakes when editing invisible parts. -@end menu - -@node Global and local cycling -@subsection Global and local cycling - -@cindex subtree visibility states -@cindex subtree cycling -@cindex folded, subtree visibility state -@cindex children, subtree visibility state -@cindex subtree, subtree visibility state - -Outlines make it possible to hide parts of the text in the buffer. -Org uses just two commands, bound to @kbd{@key{TAB}} and -@kbd{S-@key{TAB}} to change the visibility in the buffer. - -@table @asis -@item @kbd{@key{TAB}} (@code{org-cycle}) -@kindex TAB -@findex org-cycle -@emph{Subtree cycling}: Rotate current subtree among the states - -@example -,-> FOLDED -> CHILDREN -> SUBTREE --. -'-----------------------------------' -@end example - -@vindex org-cycle-emulate-tab -Point must be on a headline for this to work@footnote{See, however, the option @code{org-cycle-emulate-tab}.}. - -@item @kbd{S-@key{TAB}} (@code{org-global-cycle}) -@itemx @kbd{C-u @key{TAB}} -@cindex global visibility states -@cindex global cycling -@cindex overview, global visibility state -@cindex contents, global visibility state -@cindex show all, global visibility state -@kindex C-u TAB -@kindex S-TAB -@findex org-global-cycle -@emph{Global cycling}: Rotate the entire buffer among the states - -@example -,-> OVERVIEW -> CONTENTS -> SHOW ALL --. -'--------------------------------------' -@end example - -When @kbd{S-@key{TAB}} is called with a numeric prefix argument -@var{N}, view contents only up to headlines of level -@var{N}. - -Note that inside tables (see @ref{Tables}), @kbd{S-@key{TAB}} jumps to the -previous field instead. - -@vindex org-cycle-global-at-bob -You can run global cycling using @kbd{@key{TAB}} only if point is at -the very beginning of the buffer, but not on a headline, and -@code{org-cycle-global-at-bob} is set to a non-@code{nil} value. - -@item @kbd{C-u C-u @key{TAB}} (@code{org-set-startup-visibility}) -@cindex startup visibility -@kindex C-u C-u TAB -@findex org-set-startup-visibility -Switch back to the startup visibility of the buffer (see @ref{Initial visibility}). - -@item @kbd{C-u C-u C-u @key{TAB}} (@code{outline-show-all}) -@cindex show all, command -@kindex C-u C-u C-u TAB -@findex outline-show-all -Show all, including drawers. - -@item @kbd{C-c C-r} (@code{org-reveal}) -@cindex revealing context -@kindex C-c C-r -@findex org-reveal -Reveal context around point, showing the current entry, the -following heading and the hierarchy above. It is useful for working -near a location that has been exposed by a sparse tree command (see -@ref{Sparse Trees}) or an agenda command (see @ref{Agenda Commands}). With a prefix argument, show, on each level, all sibling -headings. With a double prefix argument, also show the entire -subtree of the parent. - -@item @kbd{C-c C-k} (@code{outline-show-branches}) -@cindex show branches, command -@kindex C-c C-k -@findex outline-show-branches -Expose all the headings of the subtree, but not their bodies. - -@item @kbd{C-c @key{TAB}} (@code{outline-show-children}) -@cindex show children, command -@kindex C-c TAB -@findex outline-show-children -Expose all direct children of the subtree. With a numeric prefix -argument @var{N}, expose all children down to level -@var{N}. - -@item @kbd{C-c C-x b} (@code{org-tree-to-indirect-buffer}) -@kindex C-c C-x b -@findex org-tree-to-indirect-buffer -Show the current subtree in an indirect buffer@footnote{The indirect buffer contains the entire buffer, but is narrowed -to the current tree. Editing the indirect buffer also changes the -original buffer, but without affecting visibility in that buffer. For -more information about indirect buffers, see @ref{Indirect Buffers,GNU Emacs Manual,,emacs,}.}. With -a numeric prefix argument @var{N}, go up to level @var{N} -and then take that tree. If @var{N} is negative then go up -that many levels. With a @kbd{C-u} prefix, do not remove the -previously used indirect buffer. - -@item @kbd{C-c C-x v} (@code{org-copy-visible}) -@kindex C-c C-x v -@findex org-copy-visible -Copy the @emph{visible} text in the region into the kill ring. -@end table - -@node Initial visibility -@subsection Initial visibility - -@vindex org-startup-folded -When Emacs first visits an Org file, the global state is set to -@code{showeverything}, i.e., all file content is visible@footnote{When @code{org-agenda-inhibit-startup} is non-@code{nil}, Org does not -honor the default visibility state when first opening a file for the -agenda (see @ref{Speeding Up Your Agendas}).}. This can -be configured through the variable @code{org-startup-folded}, or on -a per-file basis by adding one of the following lines anywhere in the -buffer: - -@cindex @samp{STARTUP}, keyword -@example -#+STARTUP: overview -#+STARTUP: content -#+STARTUP: showall -#+STARTUP: showeverything -@end example - -@cindex @samp{VISIBILITY}, property -Furthermore, any entries with a @samp{VISIBILITY} property (see @ref{Properties and Columns}) get their visibility adapted accordingly. Allowed values -for this property are @samp{folded}, @samp{children}, @samp{content}, and @samp{all}. - -@table @asis -@item @kbd{C-u C-u @key{TAB}} (@code{org-set-startup-visibility}) -@kindex C-u C-u TAB -@findex org-set-startup-visibility -Switch back to the startup visibility of the buffer, i.e., whatever -is requested by startup options and @samp{VISIBILITY} properties in -individual entries. -@end table - -@node Catching invisible edits -@subsection Catching invisible edits - -@cindex edits, catching invisible - -@vindex org-catch-invisible-edits -Sometimes you may inadvertently edit an invisible part of the buffer -and be confused on what has been edited and how to undo the mistake. -Setting @code{org-catch-invisible-edits} to non-@code{nil} helps preventing -this. See the docstring of this option on how Org should catch -invisible edits and process them. - -@node Motion -@section Motion - -@cindex motion, between headlines -@cindex jumping, to headlines -@cindex headline navigation - -The following commands jump to other headlines in the buffer. - -@table @asis -@item @kbd{C-c C-n} (@code{org-next-visible-heading}) -@kindex C-c C-n -@findex org-next-visible-heading -Next heading. - -@item @kbd{C-c C-p} (@code{org-previous-visible-heading}) -@kindex C-c C-p -@findex org-previous-visible-heading -Previous heading. - -@item @kbd{C-c C-f} (@code{org-forward-heading-same-level}) -@kindex C-c C-f -@findex org-forward-heading-same-level -Next heading same level. - -@item @kbd{C-c C-b} (@code{org-backward-heading-same-level}) -@kindex C-c C-b -@findex org-backward-heading-same-level -Previous heading same level. - -@item @kbd{C-c C-u} (@code{outline-up-heading}) -@kindex C-c C-u -@findex outline-up-heading -Backward to higher level heading. - -@item @kbd{C-c C-j} (@code{org-goto}) -@kindex C-c C-j -@findex org-goto -@vindex org-goto-auto-isearch -Jump to a different place without changing the current outline -visibility. Shows the document structure in a temporary buffer, -where you can use the following keys to find your destination: - -@multitable @columnfractions 0.3 0.7 -@item @kbd{@key{TAB}} -@tab Cycle visibility. -@item @kbd{@key{DOWN}} / @kbd{@key{UP}} -@tab Next/previous visible headline. -@item @kbd{@key{RET}} -@tab Select this location. -@item @kbd{/} -@tab Do a Sparse-tree search -@end multitable - -@noindent -The following keys work if you turn off @code{org-goto-auto-isearch} - -@multitable @columnfractions 0.3 0.7 -@item @kbd{n} / @kbd{p} -@tab Next/previous visible headline. -@item @kbd{f} / @kbd{b} -@tab Next/previous headline same level. -@item @kbd{u} -@tab One level up. -@item @kbd{0} @dots{} @kbd{9} -@tab Digit argument. -@item @kbd{q} -@tab Quit. -@end multitable - -@vindex org-goto-interface -@noindent -See also the variable @code{org-goto-interface}. -@end table - -@node Structure Editing -@section Structure Editing - -@cindex structure editing -@cindex headline, promotion and demotion -@cindex promotion, of subtrees -@cindex demotion, of subtrees -@cindex subtree, cut and paste -@cindex pasting, of subtrees -@cindex cutting, of subtrees -@cindex copying, of subtrees -@cindex sorting, of subtrees -@cindex subtrees, cut and paste - -@table @asis -@item @kbd{M-@key{RET}} (@code{org-meta-return}) -@kindex M-RET -@findex org-meta-return -@vindex org-M-RET-may-split-line -Insert a new heading, item or row. - -If the command is used at the @emph{beginning} of a line, and if there is -a heading or a plain list item (see @ref{Plain Lists}) at point, the new -heading/item is created @emph{before} the current line. When used at the -beginning of a regular line of text, turn that line into a heading. - -When this command is used in the middle of a line, the line is split -and the rest of the line becomes the new item or headline. If you -do not want the line to be split, customize -@code{org-M-RET-may-split-line}. - -Calling the command with a @kbd{C-u} prefix unconditionally -inserts a new heading at the end of the current subtree, thus -preserving its contents. With a double @kbd{C-u C-u} prefix, -the new heading is created at the end of the parent subtree instead. - -@item @kbd{C-@key{RET}} (@code{org-insert-heading-respect-content}) -@kindex C-RET -@findex org-insert-heading-respect-content -Insert a new heading at the end of the current subtree. - -@item @kbd{M-S-@key{RET}} (@code{org-insert-todo-heading}) -@kindex M-S-RET -@findex org-insert-todo-heading -@vindex org-treat-insert-todo-heading-as-state-change -Insert new TODO entry with same level as current heading. See also -the variable @code{org-treat-insert-todo-heading-as-state-change}. - -@item @kbd{C-S-@key{RET}} (@code{org-insert-todo-heading-respect-content}) -@kindex C-S-RET -@findex org-insert-todo-heading-respect-content -Insert new TODO entry with same level as current heading. Like -@kbd{C-@key{RET}}, the new headline is inserted after the current -subtree. - -@item @kbd{@key{TAB}} (@code{org-cycle}) -@kindex TAB -@findex org-cycle -In a new entry with no text yet, the first @kbd{@key{TAB}} demotes -the entry to become a child of the previous one. The next -@kbd{@key{TAB}} makes it a parent, and so on, all the way to top -level. Yet another @kbd{@key{TAB}}, and you are back to the initial -level. - -@item @kbd{M-@key{LEFT}} (@code{org-do-promote}) -@itemx @kbd{M-@key{RIGHT}} (@code{org-do-demote}) -@kindex M-LEFT -@findex org-do-promote -@kindex M-RIGHT -@findex org-do-demote -Promote or demote current heading by one level. - -@cindex region, active -@cindex active region -@cindex transient mark mode -When there is an active region---i.e., when Transient Mark mode is -active---promotion and demotion work on all headlines in the region. -To select a region of headlines, it is best to place both point and -mark at the beginning of a line, mark at the beginning of the first -headline, and point at the line just after the last headline to -change. - -@item @kbd{M-S-@key{LEFT}} (@code{org-promote-subtree}) -@kindex M-S-LEFT -@findex org-promote-subtree -Promote the current subtree by one level. - -@item @kbd{M-S-@key{RIGHT}} (@code{org-demote-subtree}) -@kindex M-S-RIGHT -@findex org-demote-subtree -Demote the current subtree by one level. - -@item @kbd{M-@key{UP}} (@code{org-move-subtree-up}) -@kindex M-UP -@findex org-move-subtree-up -Move subtree up, i.e., swap with previous subtree of same level. - -@item @kbd{M-@key{DOWN}} (@code{org-move-subtree-down}) -@kindex M-DOWN -@findex org-move-subtree-down -Move subtree down, i.e., swap with next subtree of same level. - -@item @kbd{C-c @@} (@code{org-mark-subtree}) -@kindex C-c @@ -@findex org-mark-subtree -Mark the subtree at point. Hitting repeatedly marks subsequent -subtrees of the same level as the marked subtree. - -@item @kbd{C-c C-x C-w} (@code{org-cut-subtree}) -@kindex C-c C-x C-w -@findex org-cut-subtree -Kill subtree, i.e., remove it from buffer but save in kill ring. -With a numeric prefix argument N, kill N sequential subtrees. - -@item @kbd{C-c C-x M-w} (@code{org-copy-subtree}) -@kindex C-c C-x M-w -@findex org-copy-subtree -Copy subtree to kill ring. With a numeric prefix argument N, copy -the N sequential subtrees. - -@item @kbd{C-c C-x C-y} (@code{org-paste-subtree}) -@kindex C-c C-x C-y -@findex org-paste-subtree -Yank subtree from kill ring. This does modify the level of the -subtree to make sure the tree fits in nicely at the yank position. -The yank level can also be specified with a numeric prefix argument, -or by yanking after a headline marker like @samp{****}. - -@item @kbd{C-y} (@code{org-yank}) -@kindex C-y -@findex org-yank -@vindex org-yank-adjusted-subtrees -@vindex org-yank-folded-subtrees -Depending on the variables @code{org-yank-adjusted-subtrees} and -@code{org-yank-folded-subtrees}, Org's internal @code{yank} command pastes -subtrees folded and in a clever way, using the same command as -@kbd{C-c C-x C-y}. With the default settings, no level -adjustment takes place, but the yanked tree is folded unless doing -so would swallow text previously visible. Any prefix argument to -this command forces a normal @code{yank} to be executed, with the prefix -passed along. A good way to force a normal yank is @kbd{C-u C-y}. If you use @code{yank-pop} after a yank, it yanks previous kill -items plainly, without adjustment and folding. - -@item @kbd{C-c C-x c} (@code{org-clone-subtree-with-time-shift}) -@kindex C-c C-x c -@findex org-clone-subtree-with-time-shift -Clone a subtree by making a number of sibling copies of it. You are -prompted for the number of copies to make, and you can also specify -if any timestamps in the entry should be shifted. This can be -useful, for example, to create a number of tasks related to a series -of lectures to prepare. For more details, see the docstring of the -command @code{org-clone-subtree-with-time-shift}. - -@item @kbd{C-c C-w} (@code{org-refile}) -@kindex C-c C-w -@findex org-refile -Refile entry or region to a different location. See @ref{Refile and Copy}. - -@item @kbd{C-c ^} (@code{org-sort}) -@kindex C-c ^ -@findex org-sort -Sort same-level entries. When there is an active region, all -entries in the region are sorted. Otherwise the children of the -current headline are sorted. The command prompts for the sorting -method, which can be alphabetically, numerically, by time---first -timestamp with active preferred, creation time, scheduled time, -deadline time---by priority, by TODO keyword---in the sequence the -keywords have been defined in the setup---or by the value of -a property. Reverse sorting is possible as well. You can also -supply your own function to extract the sorting key. With -a @kbd{C-u} prefix, sorting is case-sensitive. - -@item @kbd{C-x n s} (@code{org-narrow-to-subtree}) -@kindex C-x n s -@findex org-narrow-to-subtree -Narrow buffer to current subtree. - -@item @kbd{C-x n b} (@code{org-narrow-to-block}) -@kindex C-x n b -@findex org-narrow-to-block -Narrow buffer to current block. - -@item @kbd{C-x n w} (@code{widen}) -@kindex C-x n w -@findex widen -Widen buffer to remove narrowing. - -@item @kbd{C-c *} (@code{org-toggle-heading}) -@kindex C-c * -@findex org-toggle-heading -Turn a normal line or plain list item into a headline---so that it -becomes a subheading at its location. Also turn a headline into -a normal line by removing the stars. If there is an active region, -turn all lines in the region into headlines. If the first line in -the region was an item, turn only the item lines into headlines. -Finally, if the first line is a headline, remove the stars from all -headlines in the region. -@end table - -Note that when point is inside a table (see @ref{Tables}), the Meta-Cursor -keys have different functionality. - -@node Sparse Trees -@section Sparse Trees - -@cindex sparse trees -@cindex trees, sparse -@cindex folding, sparse trees -@cindex occur, command - -@vindex org-show-context-detail -An important feature of Org mode is the ability to construct @emph{sparse -trees} for selected information in an outline tree, so that the entire -document is folded as much as possible, but the selected information -is made visible along with the headline structure above it@footnote{See also the variable @code{org-show-context-detail} to decide how -much context is shown around each match.}. -Just try it out and you will see immediately how it works. - -Org mode contains several commands creating such trees, all these -commands can be accessed through a dispatcher: - -@table @asis -@item @kbd{C-c /} (@code{org-sparse-tree}) -@kindex C-c / -@findex org-sparse-tree -This prompts for an extra key to select a sparse-tree creating -command. - -@item @kbd{C-c / r} or @kbd{C-c / /} (@code{org-occur}) -@kindex C-c / r -@kindex C-c / / -@findex org-occur -@vindex org-remove-highlights-with-change -Prompts for a regexp and shows a sparse tree with all matches. If -the match is in a headline, the headline is made visible. If the -match is in the body of an entry, headline and body are made -visible. In order to provide minimal context, also the full -hierarchy of headlines above the match is shown, as well as the -headline following the match. Each match is also highlighted; the -highlights disappear when the buffer is changed by an editing -command, or by pressing @kbd{C-c C-c}@footnote{This depends on the option @code{org-remove-highlights-with-change}.}. When called with -a @kbd{C-u} prefix argument, previous highlights are kept, so -several calls to this command can be stacked. - -@item @kbd{M-g n} or @kbd{M-g M-n} (@code{next-error}) -@kindex M-g n -@kindex M-g M-n -@findex next-error -Jump to the next sparse tree match in this buffer. - -@item @kbd{M-g p} or @kbd{M-g M-p} (@code{previous-error}) -@kindex M-g p -@kindex M-g M-p -@findex previous-error -Jump to the previous sparse tree match in this buffer. -@end table - -@vindex org-agenda-custom-commands -For frequently used sparse trees of specific search strings, you can -use the variable @code{org-agenda-custom-commands} to define fast keyboard -access to specific sparse trees. These commands will then be -accessible through the agenda dispatcher (see @ref{Agenda Dispatcher}). -For example: - -@lisp -(setq org-agenda-custom-commands - '(("f" occur-tree "FIXME"))) -@end lisp - -@noindent -defines the key @kbd{f} as a shortcut for creating a sparse tree -matching the string @samp{FIXME}. - -The other sparse tree commands select headings based on TODO keywords, -tags, or properties and are discussed later in this manual. - -@kindex C-c C-e C-v -@cindex printing sparse trees -@cindex visible text, printing -To print a sparse tree, you can use the Emacs command -@code{ps-print-buffer-with-faces} which does not print invisible parts of -the document. Or you can use the command @kbd{C-c C-e C-v} to -export only the visible part of the document and print the resulting -file. - -@node Plain Lists -@section Plain Lists - -@cindex plain lists -@cindex lists, plain -@cindex lists, ordered -@cindex ordered lists - -Within an entry of the outline tree, hand-formatted lists can provide -additional structure. They also provide a way to create lists of -checkboxes (see @ref{Checkboxes}). Org supports editing such lists, and -every exporter (see @ref{Exporting}) can parse and format them. - -Org knows ordered lists, unordered lists, and description lists. - -@itemize -@item -@emph{Unordered} list items start with @samp{-}, @samp{+}, or @samp{*}@footnote{When using @samp{*} as a bullet, lines must be indented so that they -are not interpreted as headlines. Also, when you are hiding leading -stars to get a clean outline view, plain list items starting with -a star may be hard to distinguish from true headlines. In short: even -though @samp{*} is supported, it may be better to not use it for plain list -items.} as bullets. - -@item -@vindex org-plain-list-ordered-item-terminator -@vindex org-alphabetical-lists -@emph{Ordered} list items start with a numeral followed by either -a period or a right parenthesis@footnote{You can filter out any of them by configuring -@code{org-plain-list-ordered-item-terminator}.}, such as @samp{1.} or @samp{1)}@footnote{You can also get @samp{a.}, @samp{A.}, @samp{a)} and @samp{A)} by configuring -@code{org-list-allow-alphabetical}. To minimize confusion with normal -text, those are limited to one character only. Beyond that limit, -bullets automatically become numbers.} -If you want a list to start with a different value---e.g., -20---start the text of the item with @samp{[@@20]}@footnote{If there's a checkbox in the item, the cookie must be put -@emph{before} the checkbox. If you have activated alphabetical lists, you -can also use counters like @samp{[@@b]}.}. Those -constructs can be used in any item of the list in order to enforce -a particular numbering. - -@item -@emph{Description} list items are unordered list items, and contain the -separator @samp{::} to distinguish the description @emph{term} from the -description. -@end itemize - -Items belonging to the same list must have the same indentation on the -first line. In particular, if an ordered list reaches number @samp{10.}, -then the 2-digit numbers must be written left-aligned with the other -numbers in the list. An item ends before the next line that is less -or equally indented than its bullet/number. - -A list ends whenever every item has ended, which means before any line -less or equally indented than items at top level. It also ends before -two blank lines. In that case, all items are closed. Here is an -example: - -@example -* Lord of the Rings -My favorite scenes are (in this order) -1. The attack of the Rohirrim -2. Eowyn's fight with the witch king - + this was already my favorite scene in the book - + I really like Miranda Otto. -3. Peter Jackson being shot by Legolas - - on DVD only - He makes a really funny face when it happens. -But in the end, no individual scenes matter but the film as a whole. -Important actors in this film are: -- Elijah Wood :: He plays Frodo -- Sean Astin :: He plays Sam, Frodo's friend. I still remember him - very well from his role as Mikey Walsh in /The Goonies/. -@end example - -Org supports these lists by tuning filling and wrapping commands to -deal with them correctly, and by exporting them properly (see -@ref{Exporting}). Since indentation is what governs the structure of these -lists, many structural constructs like @samp{#+BEGIN_} blocks can be -indented to signal that they belong to a particular item. - -@vindex org-list-demote-modify-bullet -@vindex org-list-indent-offset -If you find that using a different bullet for a sub-list---than that -used for the current list-level---improves readability, customize the -variable @code{org-list-demote-modify-bullet}. To get a greater difference -of indentation between items and theirs sub-items, customize -@code{org-list-indent-offset}. - -@vindex org-list-automatic-rules -The following commands act on items when point is in the first line of -an item---the line with the bullet or number. Some of them imply the -application of automatic rules to keep list structure intact. If some -of these actions get in your way, configure @code{org-list-automatic-rules} -to disable them individually. - -@table @asis -@item @kbd{@key{TAB}} (@code{org-cycle}) -@cindex cycling, in plain lists -@kindex TAB -@findex org-cycle -@vindex org-cycle-include-plain-lists -Items can be folded just like headline levels. Normally this works -only if point is on a plain list item. For more details, see the -variable @code{org-cycle-include-plain-lists}. If this variable is set -to @code{integrate}, plain list items are treated like low-level -headlines. The level of an item is then given by the indentation of -the bullet/number. Items are always subordinate to real headlines, -however; the hierarchies remain completely separated. In a new item -with no text yet, the first @kbd{@key{TAB}} demotes the item to -become a child of the previous one. Subsequent @kbd{@key{TAB}}s move -the item to meaningful levels in the list and eventually get it back -to its initial position. - -@item @kbd{M-@key{RET}} (@code{org-insert-heading}) -@kindex M-RET -@findex org-insert-heading -@vindex org-M-RET-may-split-line -Insert new item at current level. With a prefix argument, force -a new heading (see @ref{Structure Editing}). If this command is used in -the middle of an item, that item is @emph{split} in two, and the second -part becomes the new item@footnote{If you do not want the item to be split, customize the -variable @code{org-M-RET-may-split-line}.}. If this command is executed -@emph{before item's body}, the new item is created @emph{before} the current -one. - -@item @kbd{M-S-@key{RET}} -@kindex M-S-RET -Insert a new item with a checkbox (see @ref{Checkboxes}). - -@item @kbd{S-@key{UP}} -@itemx @kbd{S-@key{DOWN}} -@kindex S-UP -@kindex S-DOWN -@cindex shift-selection-mode -@vindex org-support-shift-select -@vindex org-list-use-circular-motion -Jump to the previous/next item in the current list, but only if -@code{org-support-shift-select} is off@footnote{If you want to cycle around items that way, you may customize -@code{org-list-use-circular-motion}.}. If not, you can still use -paragraph jumping commands like @kbd{C-@key{UP}} and -@kbd{C-@key{DOWN}} to quite similar effect. - -@item @kbd{M-@key{UP}} -@itemx @kbd{M-@key{DOWN}} -@kindex M-UP -@kindex M-DOWN -Move the item including subitems up/down@footnote{See @code{org-list-use-circular-motion} for a cyclic behavior.}, i.e., swap with -previous/next item of same indentation. If the list is ordered, -renumbering is automatic. - -@item @kbd{M-@key{LEFT}} -@itemx @kbd{M-@key{RIGHT}} -@kindex M-LEFT -@kindex M-RIGHT -Decrease/increase the indentation of an item, leaving children -alone. - -@item @kbd{M-S-@key{LEFT}} -@itemx @kbd{M-S-@key{RIGHT}} -@kindex M-S-LEFT -@kindex M-S-RIGHT -Decrease/increase the indentation of the item, including subitems. -Initially, the item tree is selected based on current indentation. -When these commands are executed several times in direct succession, -the initially selected region is used, even if the new indentation -would imply a different hierarchy. To use the new hierarchy, break -the command chain by moving point. - -As a special case, using this command on the very first item of -a list moves the whole list. This behavior can be disabled by -configuring @code{org-list-automatic-rules}. The global indentation of -a list has no influence on the text @emph{after} the list. - -@item @kbd{C-c C-c} -@kindex C-c C-c -If there is a checkbox (see @ref{Checkboxes}) in the item line, toggle -the state of the checkbox. In any case, verify bullets and -indentation consistency in the whole list. - -@item @kbd{C-c -} -@kindex C-c - -@vindex org-plain-list-ordered-item-terminator -Cycle the entire list level through the different itemize/enumerate -bullets (@samp{-}, @samp{+}, @samp{*}, @samp{1.}, @samp{1)}) or a subset of them, depending -on @code{org-plain-list-ordered-item-terminator}, the type of list, and -its indentation. With a numeric prefix argument N, select the Nth -bullet from this list. If there is an active region when calling -this, all lines are converted to list items. With a prefix -argument, the selected text is changed into a single item. If the -first line already was a list item, any item marker is removed from -the list. Finally, even without an active region, a normal line is -converted into a list item. - -@item @kbd{C-c *} -@kindex C-c * -Turn a plain list item into a headline---so that it becomes -a subheading at its location. See @ref{Structure Editing}, for -a detailed explanation. - -@item @kbd{C-c C-*} -@kindex C-c C-* -Turn the whole plain list into a subtree of the current heading. -Checkboxes (see @ref{Checkboxes}) become @samp{TODO}, respectively @samp{DONE}, -keywords when unchecked, respectively checked. - -@item @kbd{S-@key{LEFT}} -@itemx @kbd{S-@key{RIGHT}} -@vindex org-support-shift-select -@kindex S-LEFT -@kindex S-RIGHT -This command also cycles bullet styles when point is in on the -bullet or anywhere in an item line, details depending on -@code{org-support-shift-select}. - -@item @kbd{C-c ^} -@kindex C-c ^ -@cindex sorting, of plain list -Sort the plain list. Prompt for the sorting method: numerically, -alphabetically, by time, or by custom function. -@end table - -@node Drawers -@section Drawers - -@cindex drawers -@cindex visibility cycling, drawers - -Sometimes you want to keep information associated with an entry, but -you normally do not want to see it. For this, Org mode has @emph{drawers}. -They can contain anything but a headline and another drawer. Drawers -look like this: - -@example -** This is a headline -Still outside the drawer -:DRAWERNAME: -This is inside the drawer. -:END: -After the drawer. -@end example - -@kindex C-c C-x d -@findex org-insert-drawer -You can interactively insert a drawer at point by calling -@code{org-insert-drawer}, which is bound to @kbd{C-c C-x d}. With an -active region, this command puts the region inside the drawer. With -a prefix argument, this command calls @code{org-insert-property-drawer}, -which creates a @samp{PROPERTIES} drawer right below the current headline. -Org mode uses this special drawer for storing properties (see -@ref{Properties and Columns}). You cannot use it for anything else. - -Completion over drawer keywords is also possible using -@kbd{M-@key{TAB}}@footnote{Many desktops intercept @kbd{M-@key{TAB}} to switch windows. -Use @kbd{C-M-i} or @kbd{@key{ESC} @key{TAB}} instead.}. - -Visibility cycling (see @ref{Visibility Cycling}) on the headline hides and -shows the entry, but keep the drawer collapsed to a single line. In -order to look inside the drawer, you need to move point to the drawer -line and press @kbd{@key{TAB}} there. - -You can also arrange for state change notes (see @ref{Tracking TODO state changes}) and clock times (see @ref{Clocking Work Time}) to be stored in -a @samp{LOGBOOK} drawer. If you want to store a quick note there, in -a similar way to state changes, use - -@table @asis -@item @kbd{C-c C-z} -@kindex C-c C-z -Add a time-stamped note to the @samp{LOGBOOK} drawer. -@end table - -@node Blocks -@section Blocks - -@vindex org-hide-block-startup -@cindex blocks, folding - -Org mode uses @samp{#+BEGIN} @dots{} @samp{#+END} blocks for various purposes from -including source code examples (see @ref{Literal Examples}) to capturing -time logging information (see @ref{Clocking Work Time}). These blocks can -be folded and unfolded by pressing @kbd{@key{TAB}} in the @samp{#+BEGIN} -line. You can also get all blocks folded at startup by configuring -the variable @code{org-hide-block-startup} or on a per-file basis by using - -@cindex STARTUP, keyword -@example -#+STARTUP: hideblocks -#+STARTUP: nohideblocks -@end example - -@node Tables -@chapter Tables - -@cindex tables -@cindex editing tables - -Org comes with a fast and intuitive table editor. Spreadsheet-like -calculations are supported using the Emacs Calc package (see @ref{Top,GNU Emacs -Calculator Manual,,calc,}). - -@menu -* Built-in Table Editor:: Simple tables. -* Column Width and Alignment:: Overrule the automatic settings. -* Column Groups:: Grouping to trigger vertical lines. -* Orgtbl Mode:: The table editor as minor mode. -* The Spreadsheet:: The table editor has spreadsheet capabilities. -* Org Plot:: Plotting from Org tables. -@end menu - -@node Built-in Table Editor -@section Built-in Table Editor - -@cindex table editor, built-in - -@cindex header lines, in tables -@cindex horizontal rule, in tables -@cindex row separator, in tables -@cindex table syntax -Org makes it easy to format tables in plain ASCII@. Any line with @samp{|} -as the first non-whitespace character is considered part of a table. -@samp{|} is also the column separator@footnote{To insert a vertical bar into a table field, use @samp{\vert} or, -inside a word @samp{abc\vert@{@}def}.}. Moreover, a line starting -with @samp{|-} is a horizontal rule. It separates rows explicitly. Rows -before the first horizontal rule are header lines. A table might look -like this: - -@example -| Name | Phone | Age | -|-------+-------+-----| -| Peter | 1234 | 17 | -| Anna | 4321 | 25 | -@end example - -A table is re-aligned automatically each time you press -@kbd{@key{TAB}}, @kbd{@key{RET}} or @kbd{C-c C-c} inside the table. -@kbd{@key{TAB}} also moves to the next field---@kbd{@key{RET}} to the -next row---and creates new table rows at the end of the table or -before horizontal lines. The indentation of the table is set by the -first line. Horizontal rules are automatically expanded on every -re-align to span the whole table width. So, to create the above -table, you would only type - -@example -|Name|Phone|Age| -|- -@end example - -@noindent -and then press @kbd{@key{TAB}} to align the table and start filling in -fields. Even faster would be to type @samp{|Name|Phone|Age} followed by -@kbd{C-c @key{RET}}. - -When typing text into a field, Org treats @kbd{DEL}, -@kbd{Backspace}, and all character keys in a special way, so that -inserting and deleting avoids shifting other fields. Also, when -typing @emph{immediately} after point was moved into a new field with -@kbd{@key{TAB}}, @kbd{S-@key{TAB}} or @kbd{@key{RET}}, the field is -automatically made blank. If this behavior is too unpredictable for -you, configure the option @code{org-table-auto-blank-field}. - -@anchor{Creation and conversion} -@subheading Creation and conversion - -@table @asis -@item @kbd{C-c |} (@code{org-table-create-or-convert-from-region}) -@kindex C-c | -@findex org-table-create-or-convert-from-region -Convert the active region to table. If every line contains at least -one @kbd{@key{TAB}} character, the function assumes that the material -is tab separated. If every line contains a comma, comma-separated -values (CSV) are assumed. If not, lines are split at whitespace -into fields. You can use a prefix argument to force a specific -separator: @kbd{C-u} forces CSV, @kbd{C-u C-u} forces -@kbd{@key{TAB}}, @kbd{C-u C-u C-u} prompts for a regular -expression to match the separator, and a numeric argument -N indicates that at least N consecutive spaces, or alternatively -a @kbd{@key{TAB}} will be the separator. - -If there is no active region, this command creates an empty Org -table. But it is easier just to start typing, like @kbd{| N a m e | P h o n e | A g e @key{RET} | - @key{TAB}}. -@end table - -@anchor{Re-aligning and field motion} -@subheading Re-aligning and field motion - -@table @asis -@item @kbd{C-c C-c} (@code{org-table-align}) -@kindex C-c C-c -@findex org-table-align -Re-align the table without moving point. - -@item @kbd{@key{TAB}} (@code{org-table-next-field}) -@kindex TAB -@findex org-table-next-field -Re-align the table, move to the next field. Creates a new row if -necessary. - -@item @kbd{C-c @key{SPC}} (@code{org-table-blank-field}) -@kindex C-c SPC -@findex org-table-blank-field -Blank the field at point. - -@item @kbd{S-@key{TAB}} (@code{org-table-previous-field}) -@kindex S-TAB -@findex org-table-previous-field -Re-align, move to previous field. - -@item @kbd{@key{RET}} (@code{org-table-next-row}) -@kindex RET -@findex org-table-next-row -Re-align the table and move down to next row. Creates a new row if -necessary. At the beginning or end of a line, @kbd{@key{RET}} still -inserts a new line, so it can be used to split a table. - -@item @kbd{M-a} (@code{org-table-beginning-of-field}) -@kindex M-a -@findex org-table-beginning-of-field -Move to beginning of the current table field, or on to the previous -field. - -@item @kbd{M-e} (@code{org-table-end-of-field}) -@kindex M-e -@findex org-table-end-of-field -Move to end of the current table field, or on to the next field. -@end table - -@anchor{Column and row editing} -@subheading Column and row editing - -@table @asis -@item @kbd{M-@key{LEFT}} (@code{org-table-move-column-left}) -@kindex M-LEFT -@findex org-table-move-column-left -Move the current column left. - -@item @kbd{M-@key{RIGHT}} (@code{org-table-move-column-right}) -@kindex M-RIGHT -@findex org-table-move-column-right -Move the current column right. - -@item @kbd{M-S-@key{LEFT}} (@code{org-table-delete-column}) -@kindex M-S-LEFT -@findex org-table-delete-column -Kill the current column. - -@item @kbd{M-S-@key{RIGHT}} (@code{org-table-insert-column}) -@kindex M-S-RIGHT -@findex org-table-insert-column -Insert a new column at point position. Move the recent column and -all cells to the right of this column to the right. - -@item @kbd{M-@key{UP}} (@code{org-table-move-row-up}) -@kindex M-UP -@findex org-table-move-row-up -Move the current row up. - -@item @kbd{M-@key{DOWN}} (@code{org-table-move-row-down}) -@kindex M-DOWN -@findex org-table-move-row-down -Move the current row down. - -@item @kbd{M-S-@key{UP}} (@code{org-table-kill-row}) -@kindex M-S-UP -@findex org-table-kill-row -Kill the current row or horizontal line. - -@item @kbd{S-@key{UP}} (@code{org-table-move-cell-up}) -@kindex S-UP -@findex org-table-move-cell-up -Move cell up by swapping with adjacent cell. - -@item @kbd{S-@key{DOWN}} (@code{org-table-move-cell-down}) -@kindex S-DOWN -@findex org-table-move-cell-down -Move cell down by swapping with adjacent cell. - -@item @kbd{S-@key{LEFT}} (@code{org-table-move-cell-left}) -@kindex S-LEFT -@findex org-table-move-cell-left -Move cell left by swapping with adjacent cell. - -@item @kbd{S-@key{RIGHT}} (@code{org-table-move-cell-right}) -@kindex S-RIGHT -@findex org-table-move-cell-right -Move cell right by swapping with adjacent cell. - -@item @kbd{M-S-@key{DOWN}} (@code{org-table-insert-row}) -@kindex M-S-DOWN -@findex org-table-insert-row -Insert a new row above the current row. With a prefix argument, the -line is created below the current one. - -@item @kbd{C-c -} (@code{org-table-insert-hline}) -@kindex C-c - -@findex org-table-insert-hline -Insert a horizontal line below current row. With a prefix argument, -the line is created above the current line. - -@item @kbd{C-c @key{RET}} (@code{org-table-hline-and-move}) -@kindex C-c RET -@findex org-table-hline-and-move -Insert a horizontal line below current row, and move point into the -row below that line. - -@item @kbd{C-c ^} (@code{org-table-sort-lines}) -@kindex C-c ^ -@findex org-table-sort-lines -Sort the table lines in the region. The position of point indicates -the column to be used for sorting, and the range of lines is the -range between the nearest horizontal separator lines, or the entire -table. If point is before the first column, you are prompted for -the sorting column. If there is an active region, the mark -specifies the first line and the sorting column, while point should -be in the last line to be included into the sorting. The command -prompts for the sorting type, alphabetically, numerically, or by -time. You can sort in normal or reverse order. You can also supply -your own key extraction and comparison functions. When called with -a prefix argument, alphabetic sorting is case-sensitive. -@end table - -@anchor{Regions} -@subheading Regions - -@table @asis -@item @kbd{C-c C-x M-w} (@code{org-table-copy-region}) -@kindex C-c C-x M-w -@findex org-table-copy-region -Copy a rectangular region from a table to a special clipboard. -Point and mark determine edge fields of the rectangle. If there is -no active region, copy just the current field. The process ignores -horizontal separator lines. - -@item @kbd{C-c C-x C-w} (@code{org-table-cut-region}) -@kindex C-c C-x C-w -@findex org-table-cut-region -Copy a rectangular region from a table to a special clipboard, and -blank all fields in the rectangle. So this is the ``cut'' operation. - -@item @kbd{C-c C-x C-y} (@code{org-table-paste-rectangle}) -@kindex C-c C-x C-y -@findex org-table-paste-rectangle -Paste a rectangular region into a table. The upper left corner ends -up in the current field. All involved fields are overwritten. If -the rectangle does not fit into the present table, the table is -enlarged as needed. The process ignores horizontal separator lines. - -@item @kbd{M-@key{RET}} (@code{org-table-wrap-region}) -@kindex M-RET -@findex org-table-wrap-region -Split the current field at point position and move the rest to the -line below. If there is an active region, and both point and mark -are in the same column, the text in the column is wrapped to minimum -width for the given number of lines. A numeric prefix argument may -be used to change the number of desired lines. If there is no -region, but you specify a prefix argument, the current field is made -blank, and the content is appended to the field above. -@end table - -@anchor{Calculations} -@subheading Calculations - -@cindex formula, in tables -@cindex calculations, in tables - -@table @asis -@item @kbd{C-c +} (@code{org-table-sum}) -@kindex C-c + -@findex org-table-sum -Sum the numbers in the current column, or in the rectangle defined -by the active region. The result is shown in the echo area and can -be inserted with @kbd{C-y}. - -@item @kbd{S-@key{RET}} (@code{org-table-copy-down}) -@kindex S-RET -@findex org-table-copy-down -@vindex org-table-copy-increment -When current field is empty, copy from first non-empty field above. -When not empty, copy current field down to next row and move point -along with it. - -Depending on the variable @code{org-table-copy-increment}, integer and -time stamp field values, and fields prefixed or suffixed with -a whole number, can be incremented during copy. Also, a @code{0} prefix -argument temporarily disables the increment. - -This key is also used by shift-selection and related modes (see -@ref{Conflicts}). -@end table - -@anchor{Miscellaneous (1)} -@subheading Miscellaneous - -@table @asis -@item @kbd{C-c `} (@code{org-table-edit-field}) -@kindex C-c ` -@findex org-table-edit-field -Edit the current field in a separate window. This is useful for -fields that are not fully visible (see @ref{Column Width and Alignment}). -When called with a @kbd{C-u} prefix, just make the full field -visible, so that it can be edited in place. When called with two -@kbd{C-u} prefixes, make the editor window follow point through -the table and always show the current field. The follow mode exits -automatically when point leaves the table, or when you repeat this -command with @kbd{C-u C-u C-c `}. - -@item @kbd{M-x org-table-import} -@findex org-table-import -Import a file as a table. The table should be TAB or whitespace -separated. Use, for example, to import a spreadsheet table or data -from a database, because these programs generally can write -TAB-separated text files. This command works by inserting the file -into the buffer and then converting the region to a table. Any -prefix argument is passed on to the converter, which uses it to -determine the separator. - -@item @kbd{C-c |} (@code{org-table-create-or-convert-from-region}) -@kindex C-c | -@findex org-table-create-or-convert-from-region -Tables can also be imported by pasting tabular text into the Org -buffer, selecting the pasted text with @kbd{C-x C-x} and then -using the @kbd{C-c |} command (see @ref{Creation and conversion}). - -@item @kbd{M-x org-table-export} -@findex org-table-export -@vindex org-table-export-default-format -Export the table, by default as a TAB-separated file. Use for data -exchange with, for example, spreadsheet or database programs. The -format used to export the file can be configured in the variable -@code{org-table-export-default-format}. You may also use properties -@samp{TABLE_EXPORT_FILE} and @samp{TABLE_EXPORT_FORMAT} to specify the file -name and the format for table export in a subtree. Org supports -quite general formats for exported tables. The exporter format is -the same as the format used by Orgtbl radio tables, see @ref{Translator functions}, for a detailed description. - -@item @kbd{M-x org-table-header-line-mode} -@findex org-table-header-line-mode -@vindex org-table-header-line-p -Turn on the display of the first data row of the table at point in -the window header line when this first row is not visible anymore in -the buffer. You can activate this minor mode by default by setting -the option @code{org-table-header-line-p} to @code{t}. - -@item @kbd{M-x org-table-transpose-table-at-point} -@findex org-table-transpose-table-at-point -Transpose the table at point and eliminate hlines. -@end table - -@node Column Width and Alignment -@section Column Width and Alignment - -@cindex narrow columns in tables -@cindex alignment in tables - -The width of columns is automatically determined by the table editor. -The alignment of a column is determined automatically from the -fraction of number-like versus non-number fields in the column. - -@vindex org-table-automatic-realign -Editing a field may modify alignment of the table. Moving -a contiguous row or column---i.e., using @kbd{@key{TAB}} or -@kbd{@key{RET}}---automatically re-aligns it. If you want to disable -this behavior, set @code{org-table-automatic-realign} to @code{nil}. In any -case, you can always align manually a table: - -@table @asis -@item @kbd{C-c C-c} (@code{org-table-align}) -@kindex C-c C-c -@findex org-table-align -Align the current table. -@end table - -@vindex org-startup-align-all-tables -Setting the option @code{org-startup-align-all-tables} re-aligns all tables -in a file upon visiting it. You can also set this option on -a per-file basis with: - -@example -#+STARTUP: align -#+STARTUP: noalign -@end example - -Sometimes a single field or a few fields need to carry more text, -leading to inconveniently wide columns. Maybe you want to hide away -several columns or display them with a fixed width, regardless of -content, as shown in the following example. - -@example -|---+---------------------+--------| |---+-------…+…| -| | <6> | | | | <6> …|…| -| 1 | one | some | ----\ | 1 | one …|…| -| 2 | two | boring | ----/ | 2 | two …|…| -| 3 | This is a long text | column | | 3 | This i…|…| -|---+---------------------+--------| |---+-------…+…| -@end example - -To set the width of a column, one field anywhere in the column may -contain just the string @samp{} where @var{N} specifies the width -as a number of characters. You control displayed width of columns -with the following tools: - -@table @asis -@item @kbd{C-c @key{TAB}} (@code{org-table-toggle-column-width}) -@kindex C-c TAB -@findex org-table-toggle-column-width -Shrink or expand current column. - -If a width cookie specifies a width W for the column, shrinking it -displays the first W visible characters only. Otherwise, the column -is shrunk to a single character. - -When called before the first column or after the last one, ask for -a list of column ranges to operate on. - -@item @kbd{C-u C-c @key{TAB}} (@code{org-table-shrink}) -@kindex C-u C-c TAB -@findex org-table-shrink -Shrink all columns with a column width. Expand the others. - -@item @kbd{C-u C-u C-c @key{TAB}} (@code{org-table-expand}) -@kindex C-u C-u C-c TAB -@findex org-table-expand -Expand all columns. -@end table - -To see the full text of a shrunk field, hold the mouse over it: -a tool-tip window then shows the full contents of the field. -Alternatively, @kbd{C-h .} (@code{display-local-help}) reveals them, -too. For convenience, any change near the shrunk part of a column -expands it. - -@vindex org-startup-shrink-all-tables -Setting the option @code{org-startup-shrink-all-tables} shrinks all columns -containing a width cookie in a file the moment it is visited. You can -also set this option on a per-file basis with: - -@example -#+STARTUP: shrink -@end example - - -If you would like to overrule the automatic alignment of number-rich -columns to the right and of string-rich columns to the left, you can -use @samp{}, @samp{} or @samp{} in a similar fashion. You may also combine -alignment and field width like this: @samp{}. - -Lines which only contain these formatting cookies are removed -automatically upon exporting the document. - -@node Column Groups -@section Column Groups - -@cindex grouping columns in tables - -When Org exports tables, it does so by default without vertical lines -because that is visually more satisfying in general. Occasionally -however, vertical lines can be useful to structure a table into groups -of columns, much like horizontal lines can do for groups of rows. In -order to specify column groups, you can use a special row where the -first field contains only @samp{/}. The further fields can either contain -@samp{<} to indicate that this column should start a group, @samp{>} to indicate -the end of a column, or @samp{<>} (no space between @samp{<} and @samp{>}) to make -a column a group of its own. Upon export, boundaries between column -groups are marked with vertical lines. Here is an example: - -@example -| N | N^2 | N^3 | N^4 | sqrt(n) | sqrt[4](N) | -|---+-----+-----+-----+---------+------------| -| / | < | | > | < | > | -| 1 | 1 | 1 | 1 | 1 | 1 | -| 2 | 4 | 8 | 16 | 1.4142 | 1.1892 | -| 3 | 9 | 27 | 81 | 1.7321 | 1.3161 | -|---+-----+-----+-----+---------+------------| -#+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1)::$6=sqrt(sqrt(($1))) -@end example - -It is also sufficient to just insert the column group starters after -every vertical line you would like to have: - -@example -| N | N^2 | N^3 | N^4 | sqrt(n) | sqrt[4](N) | -|---+-----+-----+-----+---------+------------| -| / | < | | | < | | -@end example - -@node Orgtbl Mode -@section The Orgtbl Minor Mode - -@cindex Orgtbl mode -@cindex minor mode for tables - -@findex orgtbl-mode -If you like the intuitive way the Org table editor works, you might -also want to use it in other modes like Text mode or Mail mode. The -minor mode Orgtbl mode makes this possible. You can always toggle the -mode with @kbd{M-x orgtbl-mode}. To turn it on by default, for -example in Message mode, use - -@lisp -(add-hook 'message-mode-hook 'turn-on-orgtbl) -@end lisp - -Furthermore, with some special setup, it is possible to maintain -tables in arbitrary syntax with Orgtbl mode. For example, it is -possible to construct @LaTeX{} tables with the underlying ease and power -of Orgtbl mode, including spreadsheet capabilities. For details, see -@ref{Tables in Arbitrary Syntax}. - -@node The Spreadsheet -@section The Spreadsheet - -@cindex calculations, in tables -@cindex spreadsheet capabilities -@cindex Calc package - -The table editor makes use of the Emacs Calc package to implement -spreadsheet-like capabilities. It can also evaluate Emacs Lisp forms -to derive fields from other fields. While fully featured, Org's -implementation is not identical to other spreadsheets. For example, -Org knows the concept of a @emph{column formula} that will be applied to -all non-header fields in a column without having to copy the formula -to each relevant field. There is also a formula debugger, and a -formula editor with features for highlighting fields in the table -corresponding to the references at point in the formula, moving these -references by arrow keys. - -@menu -* References:: How to refer to another field or range. -* Formula syntax for Calc:: Using Calc to compute stuff. -* Formula syntax for Lisp:: Writing formulas in Emacs Lisp. -* Durations and time values:: How to compute durations and time values. -* Field and range formulas:: Formula for specific (ranges of) fields. -* Column formulas:: Formulas valid for an entire column. -* Lookup functions:: Lookup functions for searching tables. -* Editing and debugging formulas:: Fixing formulas. -* Updating the table:: Recomputing all dependent fields. -* Advanced features:: Field and column names, automatic recalculation... -@end menu - -@node References -@subsection References - -@cindex references - -To compute fields in the table from other fields, formulas must -reference other fields or ranges. In Org, fields can be referenced by -name, by absolute coordinates, and by relative coordinates. To find -out what the coordinates of a field are, press @kbd{C-c ?} in -that field, or press @kbd{C-c @}} to toggle the display of a grid. - -@anchor{Field references} -@subsubheading Field references - -@cindex field references -@cindex references, to fields -Formulas can reference the value of another field in two ways. Like -in any other spreadsheet, you may reference fields with -a letter/number combination like @samp{B3}, meaning the second field in the -third row. However, Org prefers to use another, more general -representation that looks like this:@footnote{Org understands references typed by the user as @samp{B4}, but it -does not use this syntax when offering a formula for editing. You can -customize this behavior using the variable -@code{org-table-use-standard-references}.} - -@example -@@ROW$COLUMN -@end example - - -Column specifications can be absolute like @samp{$1}, @samp{$2}, @dots{}, @samp{$N}, or -relative to the current column, i.e., the column of the field which is -being computed, like @samp{$+1} or @samp{$-2}. @samp{$<} and @samp{$>} are immutable -references to the first and last column, respectively, and you can use -@samp{$>>>} to indicate the third column from the right. - -The row specification only counts data lines and ignores horizontal -separator lines, or ``hlines''. Like with columns, you can use absolute -row numbers @samp{@@1}, @samp{@@2}, @dots{}, @samp{@@N}, and row numbers relative to the -current row like @samp{@@+3} or @samp{@@-1}. @samp{@@<} and @samp{@@>} are immutable -references the first and last row in the table, respectively. You may -also specify the row relative to one of the hlines: @samp{@@I} refers to the -first hline, @samp{@@II} to the second, etc. @samp{@@-I} refers to the first such -line above the current line, @samp{@@+I} to the first such line below the -current line. You can also write @samp{@@III+2} which is the second data -line after the third hline in the table. - -@samp{@@0} and @samp{$0} refer to the current row and column, respectively, i.e., -to the row/column for the field being computed. Also, if you omit -either the column or the row part of the reference, the current -row/column is implied. - -Org's references with @emph{unsigned} numbers are fixed references in the -sense that if you use the same reference in the formula for two -different fields, the same field is referenced each time. Org's -references with @emph{signed} numbers are floating references because the -same reference operator can reference different fields depending on -the field being calculated by the formula. - -Here are a few examples: - -@multitable @columnfractions 0.2 0.8 -@item @samp{@@2$3} -@tab 2nd row, 3rd column (same as @samp{C2}) -@item @samp{$5} -@tab column 5 in the current row (same as @samp{E&}) -@item @samp{@@2} -@tab current column, row 2 -@item @samp{@@-1$-3} -@tab field one row up, three columns to the left -@item @samp{@@-I$2} -@tab field just under hline above current row, column 2 -@item @samp{@@>$5} -@tab field in the last row, in column 5 -@end multitable - -@anchor{Range references} -@subsubheading Range references - -@cindex range references -@cindex references, to ranges -You may reference a rectangular range of fields by specifying two -field references connected by two dots @samp{..}. The ends are included in -the range. If both fields are in the current row, you may simply use -@samp{$2..$7}, but if at least one field is in a different row, you need to -use the general @samp{@@ROW$COLUMN} format at least for the first field, -i.e., the reference must start with @samp{@@} in order to be interpreted -correctly. Examples: - -@multitable @columnfractions 0.2 0.8 -@item @samp{$1..$3} -@tab first three fields in the current row -@item @samp{$P..$Q} -@tab range, using column names (see @ref{Advanced features}) -@item @samp{$<<<..$>>} -@tab start in third column, continue to the last but one -@item @samp{@@2$1..@@4$3} -@tab nine fields between these two fields (same as @samp{A2..C4}) -@item @samp{@@-1$-2..@@-1} -@tab 3 fields in the row above, starting from 2 columns on the left -@item @samp{@@I..II} -@tab between first and second hline, short for @samp{@@I..@@II} -@end multitable - -@noindent -Range references return a vector of values that can be fed into Calc -vector functions. Empty fields in ranges are normally suppressed, so -that the vector contains only the non-empty fields. For other options -with the mode switches @samp{E}, @samp{N} and examples, see @ref{Formula syntax for Calc}. - -@anchor{Field coordinates in formulas} -@subsubheading Field coordinates in formulas - -@cindex field coordinates -@cindex coordinates, of field -@cindex row, of field coordinates -@cindex column, of field coordinates -@vindex org-table-current-column -@vindex org-table-current-dline -One of the very first actions during evaluation of Calc formulas and -Lisp formulas is to substitute @samp{@@#} and @samp{$#} in the formula with the -row or column number of the field where the current result will go to. -The traditional Lisp formula equivalents are @code{org-table-current-dline} -and @code{org-table-current-column}. Examples: - -@table @asis -@item @samp{if(@@# % 2, $#, string(""))} -Insert column number on odd rows, set field to empty on even rows. - -@item @samp{$2 = '(identity remote(FOO, @@@@#$1))} -Copy text or values of each row of column 1 of the table named -@var{FOO} into column 2 of the current table. - -@item @samp{@@3 = 2 * remote(FOO, @@1$$#)} -Insert the doubled value of each column of row 1 of the table -named @var{FOO} into row 3 of the current table. -@end table - -@noindent -For the second and third examples, table @var{FOO} must have at -least as many rows or columns as the current table. Note that this is -inefficient@footnote{The computation time scales as O(N^2) because table -@var{FOO} is parsed for each field to be copied.} for large number of rows. - -@anchor{Named references} -@subsubheading Named references - -@cindex named references -@cindex references, named -@cindex name, of column or field -@cindex constants, in calculations -@cindex @samp{CONSTANTS}, keyword -@vindex org-table-formula-constants - -@samp{$name} is interpreted as the name of a column, parameter or constant. -Constants are defined globally through the variable -@code{org-table-formula-constants}, and locally---for the file---through -a line like this example: - -@example -#+CONSTANTS: c=299792458. pi=3.14 eps=2.4e-6 -@end example - - -@vindex constants-unit-system -@pindex constants.el -Also, properties (see @ref{Properties and Columns}) can be used as -constants in table formulas: for a property @samp{Xyz} use the name -@samp{$PROP_Xyz}, and the property will be searched in the current outline -entry and in the hierarchy above it. If you have the @samp{constants.el} -package, it will also be used to resolve constants, including natural -constants like @samp{$h} for Planck's constant, and units like @samp{$km} for -kilometers@footnote{The file @samp{constants.el} can supply the values of constants in -two different unit systems, @samp{SI} and @samp{cgs}. Which one is used depends -on the value of the variable @code{constants-unit-system}. You can use the -@samp{STARTUP} options @samp{constSI} and @samp{constcgs} to set this value for the -current buffer.}. Column names and parameters can be specified in -special table lines. These are described below, see @ref{Advanced features}. All names must start with a letter, and further consist -of letters and numbers. - -@anchor{Remote references} -@subsubheading Remote references - -@cindex remote references -@cindex references, remote -@cindex references, to a different table -@cindex name, of column or field -@cindex @samp{NAME}, keyword -You may also reference constants, fields and ranges from a different -table, either in the current file or even in a different file. The -syntax is - -@example -remote(NAME,REF) -@end example - - -@noindent -where @var{NAME} can be the name of a table in the current file -as set by a @samp{#+NAME:} line before the table. It can also be the ID of -an entry, even in a different file, and the reference then refers to -the first table in that entry. @var{REF} is an absolute field or -range reference as described above for example @samp{@@3$3} or @samp{$somename}, -valid in the referenced table. - -@cindex table indirection -When @var{NAME} has the format @samp{@@ROW$COLUMN}, it is substituted -with the name or ID found in this field of the current table. For -example @samp{remote($1, @@@@>$2)} @result{} @samp{remote(year_2013, @@@@>$1)}. The format -@samp{B3} is not supported because it can not be distinguished from a plain -table name or ID@. - -@node Formula syntax for Calc -@subsection Formula syntax for Calc - -@cindex formula syntax, Calc -@cindex syntax, of formulas - -A formula can be any algebraic expression understood by the Emacs Calc -package. Note that Calc has the non-standard convention that @samp{/} has -lower precedence than @samp{*}, so that @samp{a/b*c} is interpreted as -@samp{(a/(b*c))}. Before evaluation by @code{calc-eval} (see @ref{Calling Calc from Your Programs,Calling Calc from -Your Lisp Programs,,calc,}), variable substitution takes place according to -the rules described above. - -@cindex vectors, in table calculations -The range vectors can be directly fed into the Calc vector functions -like @code{vmean} and @code{vsum}. - -@cindex format specifier, in spreadsheet -@cindex mode, for Calc -@vindex org-calc-default-modes -A formula can contain an optional mode string after a semicolon. This -string consists of flags to influence Calc and other modes during -execution. By default, Org uses the standard Calc modes (precision -12, angular units degrees, fraction and symbolic modes off). The -display format, however, has been changed to @samp{(float 8)} to keep -tables compact. The default settings can be configured using the -variable @code{org-calc-default-modes}. - -@table @asis -@item @samp{p20} -Set the internal Calc calculation precision to 20 digits. - -@item @samp{n3}, @samp{s3}, @samp{e2}, @samp{f4} -Normal, scientific, engineering or fixed format of the result of -Calc passed back to Org. Calc formatting is unlimited in precision -as long as the Calc calculation precision is greater. - -@item @samp{D}, @samp{R} -Degree and radian angle modes of Calc. - -@item @samp{F}, @samp{S} -Fraction and symbolic modes of Calc. - -@item @samp{T}, @samp{t}, @samp{U} -Duration computations in Calc or Lisp, @ref{Durations and time values}. - -@item @samp{E} -If and how to consider empty fields. Without @samp{E} empty fields in -range references are suppressed so that the Calc vector or Lisp list -contains only the non-empty fields. With @samp{E} the empty fields are -kept. For empty fields in ranges or empty field references the -value @samp{nan} (not a number) is used in Calc formulas and the empty -string is used for Lisp formulas. Add @samp{N} to use 0 instead for both -formula types. For the value of a field the mode @samp{N} has higher -precedence than @samp{E}. - -@item @samp{N} -Interpret all fields as numbers, use 0 for non-numbers. See the -next section to see how this is essential for computations with Lisp -formulas. In Calc formulas it is used only occasionally because -there number strings are already interpreted as numbers without @samp{N}. - -@item @samp{L} -Literal, for Lisp formulas only. See the next section. -@end table - -Unless you use large integer numbers or high-precision calculation and -display for floating point numbers you may alternatively provide -a @code{printf} format specifier to reformat the Calc result after it has -been passed back to Org instead of letting Calc already do the -formatting@footnote{The printf reformatting is limited in precision because the -value passed to it is converted into an ``integer'' or ``double''. The -``integer'' is limited in size by truncating the signed value to 32 -bits. The ``double'' is limited in precision to 64 bits overall which -leaves approximately 16 significant decimal digits.}. A few examples: - -@multitable {aaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{$1+$2} -@tab Sum of first and second field -@item @samp{$1+$2;%.2f} -@tab Same, format result to two decimals -@item @samp{exp($2)+exp($1)} -@tab Math functions can be used -@item @samp{$0;%.1f} -@tab Reformat current cell to 1 decimal -@item @samp{($3-32)*5/9} -@tab Degrees F @arrow{} C conversion -@item @samp{$c/$1/$cm} -@tab Hz @arrow{} cm conversion, using @samp{constants.el} -@item @samp{tan($1);Dp3s1} -@tab Compute in degrees, precision 3, display SCI 1 -@item @samp{sin($1);Dp3%.1e} -@tab Same, but use @code{printf} specifier for display -@item @samp{vmean($2..$7)} -@tab Compute column range mean, using vector function -@item @samp{vmean($2..$7);EN} -@tab Same, but treat empty fields as 0 -@item @samp{taylor($3,x=7,2)} -@tab Taylor series of $3, at x=7, second degree -@end multitable - -Calc also contains a complete set of logical operations (see @ref{Logical Operations,Logical -Operations,,calc,}). For example - -@table @asis -@item @samp{if($1 < 20, teen, string(""))} -@samp{"teen"} if age @samp{$1} is less than 20, else the Org table result -field is set to empty with the empty string. - -@item @samp{if("$1" =​= "nan" || "$2" =​= "nan", string(""), $1 + $2); E f-1} -Sum of the first two columns. When at least one of the input fields -is empty the Org table result field is set to empty. @samp{E} is -required to not convert empty fields to 0. @samp{f-1} is an optional -Calc format string similar to @samp{%.1f} but leaves empty results empty. - -@item @samp{if(typeof(vmean($1..$7)) =​= 12, string(""), vmean($1..$7); E} -Mean value of a range unless there is any empty field. Every field -in the range that is empty is replaced by @samp{nan} which lets @samp{vmean} -result in @samp{nan}. Then @samp{typeof =} 12= detects the @samp{nan} from @code{vmean} -and the Org table result field is set to empty. Use this when the -sample set is expected to never have missing values. - -@item @samp{if("$1..$7" =​= "[]", string(""), vmean($1..$7))} -Mean value of a range with empty fields skipped. Every field in the -range that is empty is skipped. When all fields in the range are -empty the mean value is not defined and the Org table result field -is set to empty. Use this when the sample set can have a variable -size. - -@item @samp{vmean($1..$7); EN} -To complete the example before: Mean value of a range with empty -fields counting as samples with value 0. Use this only when -incomplete sample sets should be padded with 0 to the full size. -@end table - -You can add your own Calc functions defined in Emacs Lisp with -@code{defmath} and use them in formula syntax for Calc. - -@node Formula syntax for Lisp -@subsection Emacs Lisp forms as formulas - -@cindex Lisp forms, as table formulas - -It is also possible to write a formula in Emacs Lisp. This can be -useful for string manipulation and control structures, if Calc's -functionality is not enough. - -If a formula starts with a single-quote followed by an opening -parenthesis, then it is evaluated as a Lisp form. The evaluation -should return either a string or a number. Just as with Calc -formulas, you can specify modes and a @code{printf} format after -a semicolon. - -With Emacs Lisp forms, you need to be conscious about the way field -references are interpolated into the form. By default, a reference is -interpolated as a Lisp string (in double-quotes) containing the field. -If you provide the @samp{N} mode switch, all referenced elements are -numbers---non-number fields will be zero---and interpolated as Lisp -numbers, without quotes. If you provide the @samp{L} flag, all fields are -interpolated literally, without quotes. For example, if you want a -reference to be interpreted as a string by the Lisp form, enclose the -reference operator itself in double-quotes, like @samp{"$3"}. Ranges are -inserted as space-separated fields, so you can embed them in list or -vector syntax. - -Here are a few examples---note how the @samp{N} mode is used when we do -computations in Lisp: - -@table @asis -@item @samp{'(concat (substring $1 1 2) (substring $1 0 1) (substring $1 2))} -Swap the first two characters of the content of column 1. - -@item @samp{'(+ $1 $2);N} -Add columns 1 and 2, equivalent to Calc's @samp{$1+$2}. - -@item @samp{'(apply '+ '($1..$4));N} -Compute the sum of columns 1 to 4, like Calc's @samp{vsum($1..$4)}. -@end table - -@node Durations and time values -@subsection Durations and time values - -@cindex duration, computing -@cindex time, computing -@vindex org-table-duration-custom-format - -If you want to compute time values use the @samp{T}, @samp{t}, or @samp{U} flag, -either in Calc formulas or Elisp formulas: - -@example -| Task 1 | Task 2 | Total | -|---------+----------+----------| -| 2:12 | 1:47 | 03:59:00 | -| 2:12 | 1:47 | 03:59 | -| 3:02:20 | -2:07:00 | 0.92 | -#+TBLFM: @@2$3=$1+$2;T::@@3$3=$1+$2;U::@@4$3=$1+$2;t -@end example - -Input duration values must be of the form @samp{HH:MM[:SS]}, where seconds -are optional. With the @samp{T} flag, computed durations are displayed as -@samp{HH:MM:SS} (see the first formula above). With the @samp{U} flag, seconds -are omitted so that the result is only @samp{HH:MM} (see second formula -above). Zero-padding of the hours field depends upon the value of the -variable @code{org-table-duration-hour-zero-padding}. - -With the @samp{t} flag, computed durations are displayed according to the -value of the option @code{org-table-duration-custom-format}, which defaults -to @code{hours} and displays the result as a fraction of hours (see the -third formula in the example above). - -Negative duration values can be manipulated as well, and integers are -considered as seconds in addition and subtraction. - -@node Field and range formulas -@subsection Field and range formulas - -@cindex field formula -@cindex range formula -@cindex formula, for individual table field -@cindex formula, for range of fields - -To assign a formula to a particular field, type it directly into the -field, preceded by @samp{:=}, for example @samp{vsum(@@II..III)}. When you press -@kbd{@key{TAB}} or @kbd{@key{RET}} or @kbd{C-c C-c} with point -still in the field, the formula is stored as the formula for this -field, evaluated, and the current field is replaced with the result. - -@cindex @samp{TBLFM}, keyword -Formulas are stored in a special @samp{TBLFM} keyword located directly -below the table. If you type the equation in the fourth field of the -third data line in the table, the formula looks like @samp{@@3$4=$1+$2}. -When inserting/deleting/swapping column and rows with the appropriate -commands, @emph{absolute references} (but not relative ones) in stored -formulas are modified in order to still reference the same field. To -avoid this from happening, in particular in range references, anchor -ranges at the table borders (using @samp{@@<}, @samp{@@>}, @samp{$<}, @samp{$>}), or at -hlines using the @samp{@@I} notation. Automatic adaptation of field -references does not happen if you edit the table structure with normal -editing commands---you must fix the formulas yourself. - -Instead of typing an equation into the field, you may also use the -following command - -@table @asis -@item @kbd{C-u C-c =} (@code{org-table-eval-formula}) -@kindex C-u C-c = -@findex org-table-eval-formula -Install a new formula for the current field. The command prompts -for a formula with default taken from the @samp{TBLFM} keyword, -applies it to the current field, and stores it. -@end table - -The left-hand side of a formula can also be a special expression in -order to assign the formula to a number of different fields. There is -no keyboard shortcut to enter such range formulas. To add them, use -the formula editor (see @ref{Editing and debugging formulas}) or edit -the @samp{TBLFM} keyword directly. - -@table @asis -@item @samp{$2=} -Column formula, valid for the entire column. This is so common that -Org treats these formulas in a special way, see @ref{Column formulas}. - -@item @samp{@@3=} -Row formula, applies to all fields in the specified row. @samp{@@>=} -means the last row. - -@item @samp{@@1$2..@@4$3=} -Range formula, applies to all fields in the given rectangular range. -This can also be used to assign a formula to some but not all fields -in a row. - -@item @samp{$NAME=} -Named field, see @ref{Advanced features}. -@end table - -@node Column formulas -@subsection Column formulas - -@cindex column formula -@cindex formula, for table column - -When you assign a formula to a simple column reference like @samp{$3=}, the -same formula is used in all fields of that column, with the following -very convenient exceptions: (i) If the table contains horizontal -separator hlines with rows above and below, everything before the -first such hline is considered part of the table @emph{header} and is not -modified by column formulas. Therefore a header is mandatory when you -use column formulas and want to add hlines to group rows, like for -example to separate a total row at the bottom from the summand rows -above. (ii) Fields that already get a value from a field/range -formula are left alone by column formulas. These conditions make -column formulas very easy to use. - -To assign a formula to a column, type it directly into any field in -the column, preceded by an equal sign, like @samp{=$1+$2}. When you press -@kbd{@key{TAB}} or @kbd{@key{RET}} or @kbd{C-c C-c} with point -still in the field, the formula is stored as the formula for the -current column, evaluated and the current field replaced with the -result. If the field contains only @samp{=}, the previously stored formula -for this column is used. For each column, Org only remembers the most -recently used formula. In the @samp{TBLFM} keyword, column formulas look -like @samp{$4=$1+$2}. The left-hand side of a column formula can not be -the name of column, it must be the numeric column reference or @samp{$>}. - -Instead of typing an equation into the field, you may also use the -following command: - -@table @asis -@item @kbd{C-c =} (@code{org-table-eval-formula}) -@kindex C-c = -@findex org-table-eval-formula -Install a new formula for the current column and replace current -field with the result of the formula. The command prompts for -a formula, with default taken from the @samp{TBLFM} keyword, applies it -to the current field and stores it. With a numeric prefix argument, -e.g., @kbd{C-5 C-c =}, the command applies it to that many -consecutive fields in the current column. -@end table - -@node Lookup functions -@subsection Lookup functions - -@cindex lookup functions in tables -@cindex table lookup functions - -Org has three predefined Emacs Lisp functions for lookups in tables. - -@table @asis -@item @samp{(org-lookup-first VAL S-LIST R-LIST &optional PREDICATE)} -@findex org-lookup-first -Searches for the first element @var{S} in list -@var{S-LIST} for which -@lisp -(PREDICATE VAL S) -@end lisp -is non-@code{nil}; returns the value from the corresponding position in -list @var{R-LIST}. The default @var{PREDICATE} is -@code{equal}. Note that the parameters @var{VAL} and @var{S} -are passed to @var{PREDICATE} in the same order as the -corresponding parameters are in the call to @code{org-lookup-first}, -where @var{VAL} precedes @var{S-LIST}. If -@var{R-LIST} is @code{nil}, the matching element @var{S} of -@var{S-LIST} is returned. - -@item @samp{(org-lookup-last VAL S-LIST R-LIST &optional PREDICATE)} -@findex org-lookup-last -Similar to @code{org-lookup-first} above, but searches for the @emph{last} -element for which @var{PREDICATE} is non-@code{nil}. - -@item @samp{(org-lookup-all VAL S-LIST R-LIST &optional PREDICATE)} -@findex org-lookup-all -Similar to @code{org-lookup-first}, but searches for @emph{all} elements for -which @var{PREDICATE} is non-@code{nil}, and returns @emph{all} -corresponding values. This function can not be used by itself in -a formula, because it returns a list of values. However, powerful -lookups can be built when this function is combined with other Emacs -Lisp functions. -@end table - -If the ranges used in these functions contain empty fields, the @samp{E} -mode for the formula should usually be specified: otherwise empty -fields are not included in @var{S-LIST} and/or @var{R-LIST} -which can, for example, result in an incorrect mapping from an element -of @var{S-LIST} to the corresponding element of -@var{R-LIST}. - -These three functions can be used to implement associative arrays, -count matching cells, rank results, group data, etc. For practical -examples see @uref{https://orgmode.org/worg/org-tutorials/org-lookups.html, this tutorial on Worg}. - -@node Editing and debugging formulas -@subsection Editing and debugging formulas - -@cindex formula editing -@cindex editing, of table formulas - -@vindex org-table-use-standard-references -You can edit individual formulas in the minibuffer or directly in the -field. Org can also prepare a special buffer with all active formulas -of a table. When offering a formula for editing, Org converts -references to the standard format (like @samp{B3} or @samp{D&}) if possible. If -you prefer to only work with the internal format (like @samp{@@3$2} or -@samp{$4}), configure the variable @code{org-table-use-standard-references}. - -@table @asis -@item @kbd{C-c =} or @kbd{C-u C-c =} (@code{org-table-eval-formula}) -@kindex C-c = -@kindex C-u C-c = -@findex org-table-eval-formula -Edit the formula associated with the current column/field in the -minibuffer. See @ref{Column formulas}, and @ref{Field and range formulas}. - -@item @kbd{C-u C-u C-c =} (@code{org-table-eval-formula}) -@kindex C-u C-u C-c = -@findex org-table-eval-formula -Re-insert the active formula (either a field formula, or a column -formula) into the current field, so that you can edit it directly in -the field. The advantage over editing in the minibuffer is that you -can use the command @kbd{C-c ?}. - -@item @kbd{C-c ?} (@code{org-table-field-info}) -@kindex C-c ? -@findex org-table-field-info -While editing a formula in a table field, highlight the field(s) -referenced by the reference at point position in the formula. - -@item @kbd{C-c @}} (@code{org-table-toggle-coordinate-overlays}) -@kindex C-c @} -@findex org-table-toggle-coordinate-overlays -Toggle the display of row and column numbers for a table, using -overlays. These are updated each time the table is aligned; you can -force it with @kbd{C-c C-c}. - -@item @kbd{C-c @{} (@code{org-table-toggle-formula-debugger}) -@kindex C-c @{ -@findex org-table-toggle-formula-debugger -Toggle the formula debugger on and off. See below. - -@item @kbd{C-c '} (@code{org-table-edit-formulas}) -@kindex C-c ' -@findex org-table-edit-formulas -Edit all formulas for the current table in a special buffer, where -the formulas are displayed one per line. If the current field has -an active formula, point in the formula editor marks it. While -inside the special buffer, Org automatically highlights any field or -range reference at point position. You may edit, remove and add -formulas, and use the following commands: - -@table @asis -@item @kbd{C-c C-c} or @kbd{C-x C-s} (@code{org-table-fedit-finish}) -@kindex C-x C-s -@kindex C-c C-c -@findex org-table-fedit-finish -Exit the formula editor and store the modified formulas. With -@kbd{C-u} prefix, also apply the new formulas to the -entire table. - -@item @kbd{C-c C-q} (@code{org-table-fedit-abort}) -@kindex C-c C-q -@findex org-table-fedit-abort -Exit the formula editor without installing changes. - -@item @kbd{C-c C-r} (@code{org-table-fedit-toggle-ref-type}) -@kindex C-c C-r -@findex org-table-fedit-toggle-ref-type -Toggle all references in the formula editor between standard (like -@samp{B3}) and internal (like @samp{@@3$2}). - -@item @kbd{@key{TAB}} (@code{org-table-fedit-lisp-indent}) -@kindex TAB -@findex org-table-fedit-lisp-indent -Pretty-print or indent Lisp formula at point. When in a line -containing a Lisp formula, format the formula according to Emacs -Lisp rules. Another @kbd{@key{TAB}} collapses the formula back -again. In the open formula, @kbd{@key{TAB}} re-indents just like -in Emacs Lisp mode. - -@item @kbd{M-@key{TAB}} (@code{lisp-complete-symbol}) -@kindex M-TAB -@findex lisp-complete-symbol -Complete Lisp symbols, just like in Emacs Lisp mode. - -@item @kbd{S-@key{UP}}, @kbd{S-@key{DOWN}}, @kbd{S-@key{LEFT}}, @kbd{S-@key{RIGHT}} -@kindex S-UP -@kindex S-DOWN -@kindex S-LEFT -@kindex S-RIGHT -@findex org-table-fedit-ref-up -@findex org-table-fedit-ref-down -@findex org-table-fedit-ref-left -@findex org-table-fedit-ref-right -Shift the reference at point. For example, if the reference is -@samp{B3} and you press @kbd{S-@key{RIGHT}}, it becomes @samp{C3}. This also -works for relative references and for hline references. - -@item @kbd{M-S-@key{UP}} (@code{org-table-fedit-line-up}) -@kindex M-S-UP -@findex org-table-fedit-line-up -Move the test line for column formulas up in the Org buffer. - -@item @kbd{M-S-@key{DOWN}} (@code{org-table-fedit-line-down}) -@kindex M-S-DOWN -@findex org-table-fedit-line-down -Move the test line for column formulas down in the Org buffer. - -@item @kbd{M-@key{UP}} (@code{org-table-fedit-scroll-up}) -@kindex M-UP -@findex org-table-fedit-scroll-up -Scroll up the window displaying the table. - -@item @kbd{M-@key{DOWN}} (@code{org-table-fedit-scroll-down}) -@kindex M-DOWN -@findex org-table-fedit-scroll-down -Scroll down the window displaying the table. - -@item @kbd{C-c @}} -@kindex C-c @} -@findex org-table-toggle-coordinate-overlays -Turn the coordinate grid in the table on and off. -@end table -@end table - -Making a table field blank does not remove the formula associated with -the field, because that is stored in a different line---the @samp{TBLFM} -keyword line. During the next recalculation, the field will be filled -again. To remove a formula from a field, you have to give an empty -reply when prompted for the formula, or to edit the @samp{TBLFM} keyword. - -@kindex C-c C-c -You may edit the @samp{TBLFM} keyword directly and re-apply the changed -equations with @kbd{C-c C-c} in that line or with the normal -recalculation commands in the table. - -@anchor{Using multiple @samp{TBLFM} lines} -@subsubheading Using multiple @samp{TBLFM} lines - -@cindex multiple formula lines -@cindex @samp{TBLFM} keywords, multiple -@cindex @samp{TBLFM}, switching - -@kindex C-c C-c -You may apply the formula temporarily. This is useful when you want -to switch the formula applied to the table. Place multiple @samp{TBLFM} -keywords right after the table, and then press @kbd{C-c C-c} on -the formula to apply. Here is an example: - -@example -| x | y | -|---+---| -| 1 | | -| 2 | | -#+TBLFM: $2=$1*1 -#+TBLFM: $2=$1*2 -@end example - -@noindent -Pressing @kbd{C-c C-c} in the line of @samp{#+TBLFM: $2=$1*2} yields: - -@example -| x | y | -|---+---| -| 1 | 2 | -| 2 | 4 | -#+TBLFM: $2=$1*1 -#+TBLFM: $2=$1*2 -@end example - -@noindent -If you recalculate this table, with @kbd{C-u C-c *}, for example, -you get the following result from applying only the first @samp{TBLFM} -keyword. - -@example -| x | y | -|---+---| -| 1 | 1 | -| 2 | 2 | -#+TBLFM: $2=$1*1 -#+TBLFM: $2=$1*2 -@end example - -@anchor{Debugging formulas} -@subsubheading Debugging formulas - -@cindex formula debugging -@cindex debugging, of table formulas - -When the evaluation of a formula leads to an error, the field content -becomes the string @samp{#ERROR}. If you would like to see what is going -on during variable substitution and calculation in order to find -a bug, turn on formula debugging in the Tbl menu and repeat the -calculation, for example by pressing @kbd{C-u C-u C-c = @key{RET}} in -a field. Detailed information are displayed. - -@node Updating the table -@subsection Updating the table - -@cindex recomputing table fields -@cindex updating, table - -Recalculation of a table is normally not automatic, but needs to be -triggered by a command. To make recalculation at least -semi-automatic, see @ref{Advanced features}. - -In order to recalculate a line of a table or the entire table, use the -following commands: - -@table @asis -@item @kbd{C-c *} (@code{org-table-recalculate}) -@kindex C-c * -@findex org-table-recalculate -Recalculate the current row by first applying the stored column -formulas from left to right, and all field/range formulas in the -current row. - -@item @kbd{C-u C-c *} or @kbd{C-u C-c C-c} -@kindex C-u C-c * -@kindex C-u C-c C-c -Recompute the entire table, line by line. Any lines before the -first hline are left alone, assuming that these are part of the -table header. - -@item @kbd{C-u C-u C-c *} or @kbd{C-u C-u C-c C-c} (@code{org-table-iterate}) -@kindex C-u C-u C-c * -@kindex C-u C-u C-c C-c -@findex org-table-iterate -Iterate the table by recomputing it until no further changes occur. -This may be necessary if some computed fields use the value of other -fields that are computed @emph{later} in the calculation sequence. - -@item @kbd{M-x org-table-recalculate-buffer-tables} -@findex org-table-recalculate-buffer-tables -Recompute all tables in the current buffer. - -@item @kbd{M-x org-table-iterate-buffer-tables} -@findex org-table-iterate-buffer-tables -Iterate all tables in the current buffer, in order to converge -table-to-table dependencies. -@end table - -@node Advanced features -@subsection Advanced features - -If you want the recalculation of fields to happen automatically, or if -you want to be able to assign @emph{names}@footnote{Such names must start with an alphabetic character and use -only alphanumeric/underscore characters.} to fields and columns, -you need to reserve the first column of the table for special marking -characters. - -@table @asis -@item @kbd{C-#} (@code{org-table-rotate-recalc-marks}) -@kindex C-# -@findex org-table-rotate-recalc-marks -Rotate the calculation mark in first column through the states @samp{#}, -@samp{*}, @samp{!}, @samp{$}. When there is an active region, change all marks in -the region. -@end table - -Here is an example of a table that collects exam results of students -and makes use of these features: - -@example -|---+---------+--------+--------+--------+-------+------| -| | Student | Prob 1 | Prob 2 | Prob 3 | Total | Note | -|---+---------+--------+--------+--------+-------+------| -| ! | | P1 | P2 | P3 | Tot | | -| # | Maximum | 10 | 15 | 25 | 50 | 10.0 | -| ^ | | m1 | m2 | m3 | mt | | -|---+---------+--------+--------+--------+-------+------| -| # | Peter | 10 | 8 | 23 | 41 | 8.2 | -| # | Sam | 2 | 4 | 3 | 9 | 1.8 | -|---+---------+--------+--------+--------+-------+------| -| | Average | | | | 25.0 | | -| ^ | | | | | at | | -| $ | max=50 | | | | | | -|---+---------+--------+--------+--------+-------+------| -#+TBLFM: $6=vsum($P1..$P3)::$7=10*$Tot/$max;%.1f::$at=vmean(@@-II..@@-I);%.1f -@end example - -@quotation Important -Please note that for these special tables, recalculating the table -with @kbd{C-u C-c *} only affects rows that are marked @samp{#} or -@samp{*}, and fields that have a formula assigned to the field itself. The -column formulas are not applied in rows with empty first field. - -@end quotation - -@cindex marking characters, tables -The marking characters have the following meaning: - -@table @asis -@item @samp{!} -The fields in this line define names for the columns, so that you -may refer to a column as @samp{$Tot} instead of @samp{$6}. - -@item @samp{^} -This row defines names for the fields @emph{above} the row. With such -a definition, any formula in the table may use @samp{$m1} to refer to the -value @samp{10}. Also, if you assign a formula to a names field, it is -stored as @samp{$name = ...}. - -@item @samp{_} -Similar to @samp{^}, but defines names for the fields in the row @emph{below}. - -@item @samp{$} -Fields in this row can define @emph{parameters} for formulas. For -example, if a field in a @samp{$} row contains @samp{max=50}, then formulas in -this table can refer to the value 50 using @samp{$max}. Parameters work -exactly like constants, only that they can be defined on a per-table -basis. - -@item @samp{#} -Fields in this row are automatically recalculated when pressing -@kbd{@key{TAB}} or @kbd{@key{RET}} or @kbd{S-@key{TAB}} in this row. -Also, this row is selected for a global recalculation with -@kbd{C-u C-c *}. Unmarked lines are left alone by this -command. - -@item @samp{*} -Selects this line for global recalculation with @kbd{C-u C-c *}, but not for automatic recalculation. Use this when automatic -recalculation slows down editing too much. - -@item @samp{/} -Do not export this line. Useful for lines that contain the -narrowing @samp{} markers or column group markers. -@end table - -Finally, just to whet your appetite for what can be done with the -fantastic Calc package, here is a table that computes the Taylor -series of degree n at location x for a couple of functions. - -@example -|---+-------------+---+-----+--------------------------------------| -| | Func | n | x | Result | -|---+-------------+---+-----+--------------------------------------| -| # | exp(x) | 1 | x | 1 + x | -| # | exp(x) | 2 | x | 1 + x + x^2 / 2 | -| # | exp(x) | 3 | x | 1 + x + x^2 / 2 + x^3 / 6 | -| # | x^2+sqrt(x) | 2 | x=0 | x*(0.5 / 0) + x^2 (2 - 0.25 / 0) / 2 | -| # | x^2+sqrt(x) | 2 | x=1 | 2 + 2.5 x - 2.5 + 0.875 (x - 1)^2 | -| * | tan(x) | 3 | x | 0.0175 x + 1.77e-6 x^3 | -|---+-------------+---+-----+--------------------------------------| -#+TBLFM: $5=taylor($2,$4,$3);n3 -@end example - -@node Org Plot -@section Org Plot - -@cindex graph, in tables -@cindex plot tables using Gnuplot - -Org Plot can produce graphs of information stored in Org tables, -either graphically or in ASCII art. - -@anchor{Graphical plots using Gnuplot} -@subheading Graphical plots using Gnuplot - -@cindex @samp{PLOT}, keyword -Org Plot can produce 2D and 3D graphs of information stored in Org -tables using @uref{http://www.gnuplot.info/, Gnuplot} and @uref{http://cars9.uchicago.edu/~ravel/software/gnuplot-mode.html, Gnuplot mode}. To see this in action, ensure -that you have both Gnuplot and Gnuplot mode installed on your system, -then call @kbd{C-c " g} or @kbd{M-x org-plot/gnuplot} on the -following table. - -@example -#+PLOT: title:"Citas" ind:1 deps:(3) type:2d with:histograms set:"yrange [0:]" -| Sede | Max cites | H-index | -|-----------+-----------+---------| -| Chile | 257.72 | 21.39 | -| Leeds | 165.77 | 19.68 | -| Sao Paolo | 71.00 | 11.50 | -| Stockholm | 134.19 | 14.33 | -| Morelia | 257.56 | 17.67 | -@end example - -Notice that Org Plot is smart enough to apply the table's headers as -labels. Further control over the labels, type, content, and -appearance of plots can be exercised through the @samp{PLOT} keyword -preceding a table. See below for a complete list of Org Plot options. -For more information and examples see the @uref{https://orgmode.org/worg/org-tutorials/org-plot.html, Org Plot tutorial}. - -@anchor{Plot options} -@subsubheading Plot options - -@table @asis -@item @samp{set} -Specify any Gnuplot option to be set when graphing. - -@item @samp{title} -Specify the title of the plot. - -@item @samp{ind} -Specify which column of the table to use as the @samp{x} axis. - -@item @samp{deps} -Specify the columns to graph as a Lisp style list, surrounded by -parentheses and separated by spaces for example @samp{dep:(3 4)} to graph -the third and fourth columns. Defaults to graphing all other -columns aside from the @samp{ind} column. - -@item @samp{type} -Specify whether the plot is @samp{2d}, @samp{3d}, or @samp{grid}. - -@item @samp{with} -Specify a @samp{with} option to be inserted for every column being -plotted, e.g., @samp{lines}, @samp{points}, @samp{boxes}, @samp{impulses}. Defaults to -@samp{lines}. - -@item @samp{file} -If you want to plot to a file, specify -@samp{"path/to/desired/output-file"}. - -@item @samp{labels} -List of labels to be used for the @samp{deps}. Defaults to the column -headers if they exist. - -@item @samp{line} -Specify an entire line to be inserted in the Gnuplot script. - -@item @samp{map} -When plotting @samp{3d} or @samp{grid} types, set this to @samp{t} to graph a flat -mapping rather than a @samp{3d} slope. - -@item @samp{timefmt} -Specify format of Org mode timestamps as they will be parsed by -Gnuplot. Defaults to @samp{%Y-%m-%d-%H:%M:%S}. - -@item @samp{script} -If you want total control, you can specify a script file---place the -file name between double-quotes---which will be used to plot. -Before plotting, every instance of @samp{$datafile} in the specified -script will be replaced with the path to the generated data file. -Note: even if you set this option, you may still want to specify the -plot type, as that can impact the content of the data file. -@end table - -@anchor{ASCII bar plots} -@subheading ASCII bar plots - -While point is on a column, typing @kbd{C-c `` a} or @kbd{M-x orgtbl-ascii-plot} create a new column containing an ASCII-art bars -plot. The plot is implemented through a regular column formula. When -the source column changes, the bar plot may be updated by refreshing -the table, for example typing @kbd{C-u C-c *}. - -@example -| Sede | Max cites | | -|---------------+-----------+--------------| -| Chile | 257.72 | WWWWWWWWWWWW | -| Leeds | 165.77 | WWWWWWWh | -| Sao Paolo | 71.00 | WWW; | -| Stockholm | 134.19 | WWWWWW: | -| Morelia | 257.56 | WWWWWWWWWWWH | -| Rochefourchat | 0.00 | | -#+TBLFM: $3='(orgtbl-ascii-draw $2 0.0 257.72 12) -@end example - -The formula is an Elisp call. - -@defun orgtbl-ascii-draw value min max &optional width -Draw an ASCII bar in a table. - -@var{VALUE} is the value to plot. - -@var{MIN} is the value displayed as an empty bar. @var{MAX} -is the value filling all the @var{WIDTH}. Sources values outside -this range are displayed as @samp{too small} or @samp{too large}. - -@var{WIDTH} is the number of characters of the bar plot. It -defaults to @samp{12}. -@end defun - -@node Hyperlinks -@chapter Hyperlinks - -@cindex hyperlinks - -Like HTML, Org provides support for links inside a file, external -links to other files, Usenet articles, emails, and much more. - -@menu -* Link Format:: How links in Org are formatted. -* Internal Links:: Links to other places in the current file. -* Radio Targets:: Make targets trigger links in plain text. -* External Links:: URL-like links to the world. -* Handling Links:: Creating, inserting and following. -* Using Links Outside Org:: Linking from my C source code? -* Link Abbreviations:: Shortcuts for writing complex links. -* Search Options:: Linking to a specific location. -* Custom Searches:: When the default search is not enough. -@end menu - -@node Link Format -@section Link Format - -@cindex link format -@cindex format, of links - -@cindex angle bracket links -@cindex plain links -Org recognizes plain URIs, possibly wrapped within angle -brackets@footnote{Plain URIs are recognized only for a well-defined set of -schemes. See @ref{External Links}. Unlike URI syntax, they cannot contain -parenthesis or white spaces, either. URIs within angle brackets have -no such limitation.}, and activate them as clickable links. - -@cindex bracket links -The general link format, however, looks like this: - -@example -[[LINK][DESCRIPTION]] -@end example - - -@noindent -or alternatively - -@example -[[LINK]] -@end example - - -@cindex escape syntax, for links -@cindex backslashes, in links -Some @samp{\}, @samp{[} and @samp{]} characters in the @var{LINK} part need to -be ``escaped'', i.e., preceded by another @samp{\} character. More -specifically, the following characters, and only them, must be -escaped: - -@enumerate -@item -all @samp{[} and @samp{]} characters, -@item -every @samp{\} character preceding either @samp{]} or @samp{[}, -@item -every @samp{\} character at the end of the link. -@end enumerate - -@findex org-link-escape -Functions inserting links (see @ref{Handling Links}) properly escape -ambiguous characters. You only need to bother about the rules above -when inserting directly, or yanking, a URI within square brackets. -When in doubt, you may use the function @code{org-link-escape}, which turns -a link string into its escaped form. - -Once a link in the buffer is complete, with all brackets present, Org -changes the display so that @samp{DESCRIPTION} is displayed instead of -@samp{[[LINK][DESCRIPTION]]} and @samp{LINK} is displayed instead of @samp{[[LINK]]}. -Links are highlighted in the @code{org-link} face, which, by default, is an -underlined face. - -You can directly edit the visible part of a link. This can be either -the @var{LINK} part, if there is no description, or the -@var{DESCRIPTION} part otherwise. To also edit the invisible -@var{LINK} part, use @kbd{C-c C-l} with point on the link -(see @ref{Handling Links}). - -If you place point at the beginning or just behind the end of the -displayed text and press @kbd{@key{BS}}, you remove -the---invisible---bracket at that location@footnote{More accurately, the precise behavior depends on how point -arrived there---see @ref{Invisible Text,Invisible Text,,elisp,}.}. This makes the link -incomplete and the internals are again displayed as plain text. -Inserting the missing bracket hides the link internals again. To show -the internal structure of all links, use the menu: Org @arrow{} Hyperlinks @arrow{} -Literal links. - -@node Internal Links -@section Internal Links - -@cindex internal links -@cindex links, internal - -A link that does not look like a URL---i.e., does not start with -a known scheme or a file name---refers to the current document. You -can follow it with @kbd{C-c C-o} when point is on the link, or -with a mouse click (see @ref{Handling Links}). - -@cindex @samp{CUSTOM_ID}, property -Org provides several refinements to internal navigation within -a document. Most notably, a construct like @samp{[[#my-custom-id]]} -specifically targets the entry with the @samp{CUSTOM_ID} property set to -@samp{my-custom-id}. Also, an internal link looking like @samp{[[*Some -section]]} points to a headline with the name @samp{Some section}@footnote{To insert a link targeting a headline, in-buffer completion -can be used. Just type a star followed by a few optional letters into -the buffer and press @kbd{M-@key{TAB}}. All headlines in the current -buffer are offered as completions.}. - -@cindex targets, for links -When the link does not belong to any of the cases above, Org looks for -a @emph{dedicated target}: the same string in double angular brackets, like -@samp{<>}. - -@cindex @samp{NAME}, keyword -If no dedicated target exists, the link tries to match the exact name -of an element within the buffer. Naming is done, unsurprisingly, with -the @samp{NAME} keyword, which has to be put in the line before the element -it refers to, as in the following example - -@example -#+NAME: My Target -| a | table | -|----+------------| -| of | four cells | -@end example - -@vindex org-link-search-must-match-exact-headline -Ultimately, if none of the above succeeds, Org searches for a headline -that is exactly the link text but may also include a TODO keyword and -tags, or initiates a plain text search, according to the value of -@code{org-link-search-must-match-exact-headline}. - -Note that you must make sure custom IDs, dedicated targets, and names -are unique throughout the document. Org provides a linter to assist -you in the process, if needed. See @ref{Org Syntax}. - -During export, internal links are used to mark objects and assign them -a number. Marked objects are then referenced by links pointing to -them. In particular, links without a description appear as the number -assigned to the marked object@footnote{When targeting a @samp{NAME} keyword, the @samp{CAPTION} keyword is -mandatory in order to get proper numbering (see @ref{Captions}).}. In the following excerpt from -an Org buffer - -@example -1. one item -2. <>another item -Here we refer to item [[target]]. -@end example - -@noindent -The last sentence will appear as @samp{Here we refer to item 2} when -exported. - -In non-Org files, the search looks for the words in the link text. In -the above example the search would be for @samp{target}. - -Following a link pushes a mark onto Org's own mark ring. You can -return to the previous position with @kbd{C-c &}. Using this -command several times in direct succession goes back to positions -recorded earlier. - -@node Radio Targets -@section Radio Targets - -@cindex radio targets -@cindex targets, radio -@cindex links, radio targets - -Org can automatically turn any occurrences of certain target names in -normal text into a link. So without explicitly creating a link, the -text connects to the target radioing its position. Radio targets are -enclosed by triple angular brackets. For example, a target @samp{<<>>} causes each occurrence of @samp{my target} in normal text to -become activated as a link. The Org file is scanned automatically for -radio targets only when the file is first loaded into Emacs. To -update the target list during editing, press @kbd{C-c C-c} with -point on or at a target. - -@node External Links -@section External Links - -@cindex links, external -@cindex external links -@cindex attachment links -@cindex BBDB links -@cindex Elisp links -@cindex file links -@cindex Gnus links -@cindex Help links -@cindex IRC links -@cindex Info links -@cindex MH-E links -@cindex Rmail links -@cindex shell links -@cindex URL links -@cindex Usenet links - -Org supports links to files, websites, Usenet and email messages, BBDB -database entries and links to both IRC conversations and their logs. -External links are URL-like locators. They start with a short -identifying string followed by a colon. There can be no space after -the colon. - -Here is the full set of built-in link types: - -@table @asis -@item @samp{file} -File links. File name may be remote, absolute, or relative. - -Additionally, you can specify a line number, or a text search. -In Org files, you may link to a headline name, a custom ID, or a -code reference instead. - -As a special case, ``file'' prefix may be omitted if the file name -is complete, e.g., it starts with @samp{./}, or @samp{/}. - -@item @samp{attachment} -Same as file links but for files and folders attached to the current -node (see @ref{Attachments}). Attachment links are intended to behave -exactly as file links but for files relative to the attachment -directory. - -@item @samp{bbdb} -Link to a BBDB record, with possible regexp completion. - -@item @samp{docview} -Link to a document opened with DocView mode. You may specify a page -number. - -@item @samp{doi} -Link to an electronic resource, through its handle. - -@item @samp{elisp} -Execute an Elisp command upon activation. - -@item @samp{gnus}, @samp{rmail}, @samp{mhe} -Link to messages or folders from a given Emacs' MUA@. - -@item @samp{help} -Display documentation of a symbol in @samp{*Help*} buffer. - -@item @samp{http}, @samp{https} -Web links. - -@item @samp{id} -Link to a specific headline by its ID property, in an Org file. - -@item @samp{info} -Link to an Info manual, or to a specific node. - -@item @samp{irc} -Link to an IRC channel. - -@item @samp{mailto} -Link to message composition. - -@item @samp{news} -Usenet links. - -@item @samp{shell} -Execute a shell command upon activation. -@end table - -The following table illustrates the link types above, along with their -options: - -@multitable {aaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@headitem Link Type -@tab Example -@item http -@tab @samp{http://staff.science.uva.nl/c.dominik/} -@item https -@tab @samp{https://orgmode.org/} -@item doi -@tab @samp{doi:10.1000/182} -@item file -@tab @samp{file:/home/dominik/images/jupiter.jpg} -@item -@tab @samp{/home/dominik/images/jupiter.jpg} (same as above) -@item -@tab @samp{file:papers/last.pdf} -@item -@tab @samp{./papers/last.pdf} (same as above) -@item -@tab @samp{file:/ssh:me@@some.where:papers/last.pdf} (remote) -@item -@tab @samp{/ssh:me@@some.where:papers/last.pdf} (same as above) -@item -@tab @samp{file:sometextfile::NNN} (jump to line number) -@item -@tab @samp{file:projects.org} -@item -@tab @samp{file:projects.org::some words} (text search)@footnote{The actual behavior of the search depends on the value of the -variable @code{org-link-search-must-match-exact-headline}. If its value is -@code{nil}, then a fuzzy text search is done. If it is @code{t}, then only the -exact headline is matched, ignoring spaces and statistic cookies. If -the value is @code{query-to-create}, then an exact headline is searched; if -it is not found, then the user is queried to create it.} -@item -@tab @samp{file:projects.org::*task title} (headline search) -@item -@tab @samp{file:projects.org::#custom-id} (headline search) -@item attachment -@tab @samp{attachment:projects.org} -@item -@tab @samp{attachment:projects.org::some words} (text search) -@item docview -@tab @samp{docview:papers/last.pdf::NNN} -@item id -@tab @samp{id:B7423F4D-2E8A-471B-8810-C40F074717E9} -@item news -@tab @samp{news:comp.emacs} -@item mailto -@tab @samp{mailto:adent@@galaxy.net} -@item mhe -@tab @samp{mhe:folder} (folder link) -@item -@tab @samp{mhe:folder#id} (message link) -@item rmail -@tab @samp{rmail:folder} (folder link) -@item -@tab @samp{rmail:folder#id} (message link) -@item gnus -@tab @samp{gnus:group} (group link) -@item -@tab @samp{gnus:group#id} (article link) -@item bbdb -@tab @samp{bbdb:R.*Stallman} (record with regexp) -@item irc -@tab @samp{irc:/irc.com/#emacs/bob} -@item help -@tab @samp{help:org-store-link} -@item info -@tab @samp{info:org#External links} -@item shell -@tab @samp{shell:ls *.org} -@item elisp -@tab @samp{elisp:(find-file "Elisp.org")} (Elisp form to evaluate) -@item -@tab @samp{elisp:org-agenda} (interactive Elisp command) -@end multitable - -@cindex VM links -@cindex Wanderlust links -On top of these built-in link types, additional ones are available -through the @samp{contrib/} directory (see @ref{Installation}). For example, -these links to VM or Wanderlust messages are available when you load -the corresponding libraries from the @samp{contrib/} directory: - -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{vm:folder} -@tab VM folder link -@item @samp{vm:folder#id} -@tab VM message link -@item @samp{vm://myself@@some.where.org/folder#id} -@tab VM on remote machine -@item @samp{vm-imap:account:folder} -@tab VM IMAP folder link -@item @samp{vm-imap:account:folder#id} -@tab VM IMAP message link -@item @samp{wl:folder} -@tab Wanderlust folder link -@item @samp{wl:folder#id} -@tab Wanderlust message link -@end multitable - -For information on customizing Org to add new link types, see @ref{Adding Hyperlink Types}. - -A link should be enclosed in double brackets and may contain -descriptive text to be displayed instead of the URL (see @ref{Link Format}), for example: - -@example -[[https://www.gnu.org/software/emacs/][GNU Emacs]] -@end example - - -If the description is a file name or URL that points to an image, HTML -export (see @ref{HTML Export}) inlines the image as a clickable button. If -there is no description at all and the link points to an image, that -image is inlined into the exported HTML file. - -@cindex square brackets, around links -@cindex angular brackets, around links -@cindex plain text external links -Org also recognizes external links amid normal text and activates them -as links. If spaces must be part of the link (for example in -@samp{bbdb:R.*Stallman}), or if you need to remove ambiguities about the -end of the link, enclose the link in square or angular brackets. - -@node Handling Links -@section Handling Links - -@cindex links, handling - -Org provides methods to create a link in the correct syntax, to insert -it into an Org file, and to follow the link. - -@findex org-store-link -@cindex storing links -The main function is @code{org-store-link}, called with @kbd{M-x org-store-link}. Because of its importance, we suggest to bind it -to a widely available key (see @ref{Activation}). It stores a link to the -current location. The link is stored for later insertion into an Org -buffer---see below. The kind of link that is created depends on the -current buffer: - -@table @asis -@item @emph{Org mode buffers} -For Org files, if there is a @samp{<>} at point, the link points -to the target. Otherwise it points to the current headline, which -is also the description@footnote{If the headline contains a timestamp, it is removed from the -link, which results in a wrong link---you should avoid putting -a timestamp in the headline.}. - -@vindex org-id-link-to-org-use-id -@cindex @samp{CUSTOM_ID}, property -@cindex @samp{ID}, property -If the headline has a @samp{CUSTOM_ID} property, store a link to this -custom ID@. In addition or alternatively, depending on the value of -@code{org-id-link-to-org-use-id}, create and/or use a globally unique -@samp{ID} property for the link@footnote{The Org Id library must first be loaded, either through -@code{org-customize}, by enabling @code{id} in @code{org-modules}, or by adding -@samp{(require 'org-id)} in your Emacs init file.}. So using this command in Org -buffers potentially creates two links: a human-readable link from -the custom ID, and one that is globally unique and works even if the -entry is moved from file to file. Later, when inserting the link, -you need to decide which one to use. - -@item @emph{Email/News clients: VM, Rmail, Wanderlust, MH-E, Gnus} -@vindex org-link-email-description-format -Pretty much all Emacs mail clients are supported. The link points -to the current article, or, in some Gnus buffers, to the group. The -description is constructed according to the variable -@code{org-link-email-description-format}. By default, it refers to the -addressee and the subject. - -@item @emph{Web browsers: W3, W3M and EWW} -Here the link is the current URL, with the page title as the -description. - -@item @emph{Contacts: BBDB} -Links created in a BBDB buffer point to the current entry. - -@item @emph{Chat: IRC} -@vindex org-irc-links-to-logs -For IRC links, if the variable @code{org-irc-link-to-logs} is non-@code{nil}, -create a @samp{file} style link to the relevant point in the logs for the -current conversation. Otherwise store an @samp{irc} style link to the -user/channel/server under the point. - -@item @emph{Other files} -For any other file, the link points to the file, with a search -string (see @ref{Search Options}) pointing to the contents -of the current line. If there is an active region, the selected -words form the basis of the search string. You can write custom Lisp -functions to select the search string and perform the search for -particular file types (see @ref{Custom Searches}). - -You can also define dedicated links to other files. See @ref{Adding Hyperlink Types}. - -@item @emph{Agenda view} -When point is in an agenda view, the created link points to the -entry referenced by the current line. -@end table - -From an Org buffer, the following commands create, navigate or, more -generally, act on links. - -@table @asis -@item @kbd{C-c C-l} (@code{org-insert-link}) -@kindex C-c C-l -@findex org-insert-link -@cindex link completion -@cindex completion, of links -@cindex inserting links -@vindex org-link-keep-stored-after-insertion -Insert a link@footnote{Note that you do not have to use this command to insert -a link. Links in Org are plain text, and you can type or paste them -straight into the buffer. By using this command, the links are -automatically enclosed in double brackets, and you will be asked for -the optional descriptive text.}. This prompts for a link to be inserted into -the buffer. You can just type a link, using text for an internal -link, or one of the link type prefixes mentioned in the examples -above. The link is inserted into the buffer, along with -a descriptive text@footnote{After insertion of a stored link, the link will be removed -from the list of stored links. To keep it in the list for later use, -use a triple @kbd{C-u} prefix argument to @kbd{C-c C-l}, or -configure the option @code{org-link-keep-stored-after-insertion}.}. If some text was selected at this time, -it becomes the default description. - -@table @asis -@item @emph{Inserting stored links} -All links stored during the current session are part of the -history for this prompt, so you can access them with @kbd{@key{UP}} -and @kbd{@key{DOWN}} (or @kbd{M-p}, @kbd{M-n}). - -@item @emph{Completion support} -Completion with @kbd{@key{TAB}} helps you to insert valid link -prefixes like @samp{http} or @samp{ftp}, including the prefixes defined -through link abbreviations (see @ref{Link Abbreviations}). If you -press @kbd{@key{RET}} after inserting only the prefix, Org offers -specific completion support for some link types@footnote{This works if a function has been defined in the @code{:complete} -property of a link in @code{org-link-parameters}.}. For -example, if you type @kbd{f i l e @key{RET}}---alternative access: -@kbd{C-u C-c C-l}, see below---Org offers file name -completion, and after @kbd{b b d b @key{RET}} you can complete -contact names. -@end table - -@item @kbd{C-u C-c C-l} -@cindex file name completion -@cindex completion, of file names -@kindex C-u C-c C-l -When @kbd{C-c C-l} is called with a @kbd{C-u} prefix -argument, insert a link to a file. You may use file name completion -to select the name of the file. The path to the file is inserted -relative to the directory of the current Org file, if the linked -file is in the current directory or in a sub-directory of it, or if -the path is written relative to the current directory using @samp{../}. -Otherwise an absolute path is used, if possible with @samp{~/} for your -home directory. You can force an absolute path with two -@kbd{C-u} prefixes. - -@item @kbd{C-c C-l} (with point on existing link) -@cindex following links -When point is on an existing link, @kbd{C-c C-l} allows you to -edit the link and description parts of the link. - -@item @kbd{C-c C-o} (@code{org-open-at-point}) -@kindex C-c C-o -@findex org-open-at-point -@vindex org-file-apps -Open link at point. This launches a web browser for URL (using -@code{browse-url-at-point}), run VM/MH-E/Wanderlust/Rmail/Gnus/BBDB for -the corresponding links, and execute the command in a shell link. -When point is on an internal link, this command runs the -corresponding search. When point is on the tags part of a headline, -it creates the corresponding tags view (see @ref{Matching tags and properties}). If point is on a timestamp, it compiles the agenda for -that date. Furthermore, it visits text and remote files in @samp{file} -links with Emacs and select a suitable application for local -non-text files. Classification of files is based on file extension -only. See option @code{org-file-apps}. If you want to override the -default application and visit the file with Emacs, use -a @kbd{C-u} prefix. If you want to avoid opening in Emacs, use -a @kbd{C-u C-u} prefix. - -@vindex org-link-frame-setup -If point is on a headline, but not on a link, offer all links in the -headline and entry text. If you want to setup the frame -configuration for following links, customize @code{org-link-frame-setup}. - -@item @kbd{@key{RET}} -@vindex org-return-follows-link -@kindex RET -When @code{org-return-follows-link} is set, @kbd{@key{RET}} also follows -the link at point. - -@item @kbd{mouse-2} or @kbd{mouse-1} -@kindex mouse-2 -@kindex mouse-1 -On links, @kbd{mouse-1} and @kbd{mouse-2} opens the link -just as @kbd{C-c C-o} does. - -@item @kbd{mouse-3} -@vindex org-link-use-indirect-buffer-for-internals -@kindex mouse-3 -Like @kbd{mouse-2}, but force file links to be opened with -Emacs, and internal links to be displayed in another window@footnote{See the variable @code{org-link-use-indirect-buffer-for-internals}.}. - -@item @kbd{C-c %} (@code{org-mark-ring-push}) -@kindex C-c % -@findex org-mark-ring-push -@cindex mark ring -Push the current position onto the Org mark ring, to be able to -return easily. Commands following an internal link do this -automatically. - -@item @kbd{C-c &} (@code{org-mark-ring-goto}) -@kindex C-c & -@findex org-mark-ring-goto -@cindex links, returning to -Jump back to a recorded position. A position is recorded by the -commands following internal links, and by @kbd{C-c %}. Using -this command several times in direct succession moves through a ring -of previously recorded positions. - -@item @kbd{C-c C-x C-n} (@code{org-next-link}) -@itemx @kbd{C-c C-x C-p} (@code{org-previous-link}) -@kindex C-c C-x C-p -@findex org-previous-link -@kindex C-c C-x C-n -@findex org-next-link -@cindex links, finding next/previous -Move forward/backward to the next link in the buffer. At the limit -of the buffer, the search fails once, and then wraps around. The -key bindings for this are really too long; you might want to bind -this also to @kbd{M-n} and @kbd{M-p}. - -@lisp -(with-eval-after-load 'org - (define-key org-mode-map (kbd "M-n") 'org-next-link) - (define-key org-mode-map (kbd "M-p") 'org-previous-link)) -@end lisp -@end table - -@node Using Links Outside Org -@section Using Links Outside Org - -@findex org-insert-link-global -@findex org-open-at-point-global -You can insert and follow links that have Org syntax not only in Org, -but in any Emacs buffer. For this, Org provides two functions: -@code{org-insert-link-global} and @code{org-open-at-point-global}. - -You might want to bind them to globally available keys. See -@ref{Activation} for some advice. - -@node Link Abbreviations -@section Link Abbreviations - -@cindex link abbreviations -@cindex abbreviation, links - -Long URL can be cumbersome to type, and often many similar links are -needed in a document. For this you can use link abbreviations. An -abbreviated link looks like this - -@example -[[linkword:tag][description]] -@end example - - -@noindent -@vindex org-link-abbrev-alist -where the tag is optional. The @emph{linkword} must be a word, starting -with a letter, followed by letters, numbers, @samp{-}, and @samp{_}. -Abbreviations are resolved according to the information in the -variable @code{org-link-abbrev-alist} that relates the linkwords to -replacement text. Here is an example: - -@lisp -(setq org-link-abbrev-alist - '(("bugzilla" . "http://10.1.2.9/bugzilla/show_bug.cgi?id=") - ("Nu Html Checker" . "https://validator.w3.org/nu/?doc=%h") - ("duckduckgo" . "https://duckduckgo.com/?q=%s") - ("omap" . "http://nominatim.openstreetmap.org/search?q=%s&polygon=1") - ("ads" . "https://ui.adsabs.harvard.edu/search/q=%20author%3A\"%s\""))) -@end lisp - -If the replacement text contains the string @samp{%s}, it is replaced with -the tag. Using @samp{%h} instead of @samp{%s} percent-encodes the tag (see the -example above, where we need to encode the URL parameter). Using -@samp{%(my-function)} passes the tag to a custom Lisp function, and replace -it by the resulting string. - -If the replacement text do not contain any specifier, it is simply -appended to the string in order to create the link. - -Instead of a string, you may also specify a Lisp function to create -the link. Such a function will be called with the tag as the only -argument. - -With the above setting, you could link to a specific bug with -@samp{[[bugzilla:129]]}, search the web for @samp{OrgMode} with @samp{[[duckduckgo:OrgMode]]}, -show the map location of the Free Software Foundation @samp{[[gmap:51 -Franklin Street, Boston]]} or of Carsten office @samp{[[omap:Science Park 904, -Amsterdam, The Netherlands]]} and find out what the Org author is doing -besides Emacs hacking with @samp{[[ads:Dominik,C]]}. - -If you need special abbreviations just for a single Org buffer, you -can define them in the file with - -@cindex @samp{LINK}, keyword -@example -#+LINK: bugzilla http://10.1.2.9/bugzilla/show_bug.cgi?id= -#+LINK: duckduckgo https://duckduckgo.com/?q=%s -@end example - -In-buffer completion (see @ref{Completion}) can be used after @samp{[} to -complete link abbreviations. You may also define a Lisp function that -implements special (e.g., completion) support for inserting such a -link with @kbd{C-c C-l}. Such a function should not accept any -arguments, and should return the full link with a prefix. You can set -the link completion function like this: - -@lisp -(org-link-set-parameter "type" :complete #'some-completion-function) -@end lisp - -@node Search Options -@section Search Options in File Links - -@cindex search option in file links -@cindex file links, searching -@cindex attachment links, searching - -File links can contain additional information to make Emacs jump to a -particular location in the file when following a link. This can be a -line number or a search option after a double colon@footnote{For backward compatibility, line numbers can also follow a -single colon.}. For -example, when the command @code{org-store-link} creates a link (see -@ref{Handling Links}) to a file, it encodes the words in the current line -as a search string that can be used to find this line back later when -following the link with @kbd{C-c C-o}. - -Note that all search options apply for Attachment links in the same -way that they apply for File links. - -Here is the syntax of the different ways to attach a search to a file -link, together with explanations for each: - -@example -[[file:~/code/main.c::255]] -[[file:~/xx.org::My Target]] -[[file:~/xx.org::*My Target]] -[[file:~/xx.org::#my-custom-id]] -[[file:~/xx.org::/regexp/]] -[[attachment:main.c::255]] -@end example - -@table @asis -@item @samp{255} -Jump to line 255. - -@item @samp{My Target} -Search for a link target @samp{<>}, or do a text search for -@samp{my target}, similar to the search in internal links, see @ref{Internal Links}. In HTML export (see @ref{HTML Export}), such a file link becomes -a HTML reference to the corresponding named anchor in the linked -file. - -@item @samp{*My Target} -In an Org file, restrict search to headlines. - -@item @samp{#my-custom-id} -Link to a heading with a @samp{CUSTOM_ID} property - -@item @samp{/REGEXP/} -Do a regular expression search for @var{REGEXP}. This uses the -Emacs command @code{occur} to list all matches in a separate window. If -the target file is in Org mode, @code{org-occur} is used to create -a sparse tree with the matches. -@end table - -As a degenerate case, a file link with an empty file name can be used -to search the current file. For example, @samp{[[file:::find me]]} does -a search for @samp{find me} in the current file, just as @samp{[[find me]]} -would. - -@node Custom Searches -@section Custom Searches - -@cindex custom search strings -@cindex search strings, custom - -The default mechanism for creating search strings and for doing the -actual search related to a file link may not work correctly in all -cases. For example, Bib@TeX{} database files have many entries like -@code{year="1993"} which would not result in good search strings, because -the only unique identification for a Bib@TeX{} entry is the citation key. - -@vindex org-create-file-search-functions -@vindex org-execute-file-search-functions -If you come across such a problem, you can write custom functions to -set the right search string for a particular file type, and to do the -search for the string in the file. Using @code{add-hook}, these functions -need to be added to the hook variables -@code{org-create-file-search-functions} and -@code{org-execute-file-search-functions}. See the docstring for these -variables for more information. Org actually uses this mechanism for -Bib@TeX{} database files, and you can use the corresponding code as an -implementation example. See the file @samp{ol-bibtex.el}. - -@node TODO Items -@chapter TODO Items - -@cindex TODO items - -Org mode does not maintain TODO lists as separate documents@footnote{Of course, you can make a document that contains only long -lists of TODO items, but this is not required.}. -Instead, TODO items are an integral part of the notes file, because -TODO items usually come up while taking notes! With Org mode, simply -mark any entry in a tree as being a TODO item. In this way, -information is not duplicated, and the entire context from which the -TODO item emerged is always present. - -Of course, this technique for managing TODO items scatters them -throughout your notes file. Org mode compensates for this by -providing methods to give you an overview of all the things that you -have to do. - -@menu -* TODO Basics:: Marking and displaying TODO entries. -* TODO Extensions:: Workflow and assignments. -* Progress Logging:: Dates and notes for progress. -* Priorities:: Some things are more important than others. -* Breaking Down Tasks:: Splitting a task into manageable pieces. -* Checkboxes:: Tick-off lists. -@end menu - -@node TODO Basics -@section Basic TODO Functionality - -Any headline becomes a TODO item when it starts with the word @samp{TODO}, -for example: - -@example -*** TODO Write letter to Sam Fortune -@end example - - -The most important commands to work with TODO entries are: - -@table @asis -@item @kbd{C-c C-t} (@code{org-todo}) -@kindex C-c C-t -@cindex cycling, of TODO states -Rotate the TODO state of the current item among - -@example -,-> (unmarked) -> TODO -> DONE --. -'--------------------------------' -@end example - -If TODO keywords have fast access keys (see @ref{Fast access to TODO states}), prompt for a TODO keyword through the fast selection -interface; this is the default behavior when -@code{org-use-fast-todo-selection} is non-@code{nil}. - -The same state changing can also be done ``remotely'' from the agenda -buffer with the @kbd{t} command key (see @ref{Agenda Commands}). - -@item @kbd{S-@key{RIGHT}} @kbd{S-@key{LEFT}} -@kindex S-RIGHT -@kindex S-LEFT -@vindex org-treat-S-cursor-todo-selection-as-state-change -Select the following/preceding TODO state, similar to cycling. -Useful mostly if more than two TODO states are possible (see -@ref{TODO Extensions}). See also @ref{Conflicts}, for a discussion of the interaction with -shift-selection. See also the variable -@code{org-treat-S-cursor-todo-selection-as-state-change}. - -@item @kbd{C-c / t} (@code{org-show-todo-tree}) -@kindex C-c / t -@cindex sparse tree, for TODO -@vindex org-todo-keywords -@findex org-show-todo-tree -View TODO items in a @emph{sparse tree} (see @ref{Sparse Trees}). Folds the -entire buffer, but shows all TODO items---with not-DONE state---and -the headings hierarchy above them. With a prefix argument, or by -using @kbd{C-c / T}, search for a specific TODO@. You are -prompted for the keyword, and you can also give a list of keywords -like @samp{KWD1|KWD2|...} to list entries that match any one of these -keywords. With a numeric prefix argument N, show the tree for the -Nth keyword in the variable @code{org-todo-keywords}. With two prefix -arguments, find all TODO states, both un-done and done. - -@item @kbd{M-x org-agenda t} (@code{org-todo-list}) -@kindex t @r{(Agenda dispatcher)} -Show the global TODO list. Collects the TODO items (with not-DONE -states) from all agenda files (see @ref{Agenda Views}) into a single -buffer. The new buffer is in Org Agenda mode, which provides -commands to examine and manipulate the TODO entries from the new -buffer (see @ref{Agenda Commands}). See @ref{Global TODO list}, for more information. - -@item @kbd{S-M-@key{RET}} (@code{org-insert-todo-heading}) -@kindex S-M-RET -@findex org-insert-todo-heading -Insert a new TODO entry below the current one. -@end table - -@vindex org-todo-state-tags-triggers -Changing a TODO state can also trigger tag changes. See the docstring -of the option @code{org-todo-state-tags-triggers} for details. - -@node TODO Extensions -@section Extended Use of TODO Keywords - -@cindex extended TODO keywords - -@vindex org-todo-keywords -By default, marked TODO entries have one of only two states: TODO and -DONE@. Org mode allows you to classify TODO items in more complex ways -with @emph{TODO keywords} (stored in @code{org-todo-keywords}). With special -setup, the TODO keyword system can work differently in different -files. - -Note that @emph{tags} are another way to classify headlines in general and -TODO items in particular (see @ref{Tags}). - -@menu -* Workflow states:: From TODO to DONE in steps. -* TODO types:: I do this, Fred does the rest. -* Multiple sets in one file:: Mixing it all, still finding your way. -* Fast access to TODO states:: Single letter selection of state. -* Per-file keywords:: Different files, different requirements. -* Faces for TODO keywords:: Highlighting states. -* TODO dependencies:: When one task needs to wait for others. -@end menu - -@node Workflow states -@subsection TODO keywords as workflow states - -@cindex TODO workflow -@cindex workflow states as TODO keywords - -You can use TODO keywords to indicate different, possibly @emph{sequential} -states in the process of working on an item, for example@footnote{Changing the variable @code{org-todo-keywords} only becomes -effective after restarting Org mode in a buffer.}: - -@lisp -(setq org-todo-keywords - '((sequence "TODO" "FEEDBACK" "VERIFY" "|" "DONE" "DELEGATED"))) -@end lisp - -The vertical bar separates the TODO keywords (states that @emph{need -action}) from the DONE states (which need @emph{no further action}). If -you do not provide the separator bar, the last state is used as the -DONE state. - -@cindex completion, of TODO keywords -With this setup, the command @kbd{C-c C-t} cycles an entry from -@samp{TODO} to @samp{FEEDBACK}, then to @samp{VERIFY}, and finally to @samp{DONE} and -@samp{DELEGATED}. You may also use a numeric prefix argument to quickly -select a specific state. For example @kbd{C-3 C-c C-t} changes -the state immediately to @samp{VERIFY}. Or you can use @kbd{S-@key{RIGHT}} -and @kbd{S-@key{LEFT}} to go forward and backward through the states. -If you define many keywords, you can use in-buffer completion (see -@ref{Completion}) or a special one-key selection scheme (see @ref{Fast access to TODO states}) to insert these words into the buffer. -Changing a TODO state can be logged with a timestamp, see @ref{Tracking TODO state changes}, for more information. - -@node TODO types -@subsection TODO keywords as types - -@cindex TODO types -@cindex names as TODO keywords -@cindex types as TODO keywords - -The second possibility is to use TODO keywords to indicate different -@emph{types} of action items. For example, you might want to indicate that -items are for ``work'' or ``home''. Or, when you work with several people -on a single project, you might want to assign action items directly to -persons, by using their names as TODO keywords. This type of -functionality is actually much better served by using tags (see -@ref{Tags}), so the TODO implementation is kept just for backward -compatibility. - -Using TODO types, it would be set up like this: - -@lisp -(setq org-todo-keywords '((type "Fred" "Sara" "Lucy" "|" "DONE"))) -@end lisp - -In this case, different keywords do not indicate states, but -rather different types. So the normal work flow would be to assign -a task to a person, and later to mark it DONE@. Org mode supports this -style by adapting the workings of the command @kbd{C-c C-t}@footnote{This is also true for the @kbd{t} command in the agenda -buffer.}. When used several times in succession, it still -cycles through all names, in order to first select the right type for -a task. But when you return to the item after some time and execute -@kbd{C-c C-t} again, it will switch from any name directly to -@samp{DONE}. Use prefix arguments or completion to quickly select -a specific name. You can also review the items of a specific TODO -type in a sparse tree by using a numeric prefix to @kbd{C-c / t}. -For example, to see all things Lucy has to do, you would use -@kbd{C-3 C-c / t}. To collect Lucy's items from all agenda files -into a single buffer, you would use the numeric prefix argument as -well when creating the global TODO list: @kbd{C-3 M-x org-agenda t}. - -@node Multiple sets in one file -@subsection Multiple keyword sets in one file - -@cindex TODO keyword sets - -Sometimes you may want to use different sets of TODO keywords in -parallel. For example, you may want to have the basic TODO/DONE, but -also a workflow for bug fixing, and a separate state indicating that -an item has been canceled---so it is not DONE, but also does not -require action. Your setup would then look like this: - -@lisp -(setq org-todo-keywords - '((sequence "TODO" "|" "DONE") - (sequence "REPORT" "BUG" "KNOWNCAUSE" "|" "FIXED") - (sequence "|" "CANCELED"))) -@end lisp - -The keywords should all be different, this helps Org mode keep track -of which subsequence should be used for a given entry. In this setup, -@kbd{C-c C-t} only operates within a sub-sequence, so it switches -from @samp{DONE} to (nothing) to @samp{TODO}, and from @samp{FIXED} to (nothing) to -@samp{REPORT}. Therefore you need a mechanism to initially select the -correct sequence. In addition to typing a keyword or using completion -(see @ref{Completion}), you may also apply the following commands: - -@table @asis -@item @kbd{C-u C-u C-c C-t} -@itemx @kbd{C-S-@key{RIGHT}} -@itemx @kbd{C-S-@key{LEFT}} -@kindex C-S-RIGHT -@kindex C-S-LEFT -@kindex C-u C-u C-c C-t -These keys jump from one TODO sub-sequence to the next. In the -above example, @kbd{C-u C-u C-c C-t} or @kbd{C-S-@key{RIGHT}} -would jump from @samp{TODO} or @samp{DONE} to @samp{REPORT}, and any of the words -in the second row to @samp{CANCELED}. Note that the @kbd{C-S-} key -binding conflict with shift-selection (see @ref{Conflicts}). - -@item @kbd{S-@key{RIGHT}} -@itemx @kbd{S-@key{LEFT}} -@kindex S-RIGHT -@kindex S-LEFT -@kbd{S-@key{LEFT}} and @kbd{S-@key{RIGHT}} walk through @emph{all} keywords -from all sub-sequences, so for example @kbd{S-@key{RIGHT}} would -switch from @samp{DONE} to @samp{REPORT} in the example above. For -a discussion of the interaction with shift-selection, see @ref{Conflicts}. -@end table - -@node Fast access to TODO states -@subsection Fast access to TODO states - -If you would like to quickly change an entry to an arbitrary TODO -state instead of cycling through the states, you can set up keys for -single-letter access to the states. This is done by adding the -selection character after each keyword, in parentheses@footnote{All characters are allowed except @samp{@@}, @samp{^} and @samp{!}, which have -a special meaning here.}. For -example: - -@lisp -(setq org-todo-keywords - '((sequence "TODO(t)" "|" "DONE(d)") - (sequence "REPORT(r)" "BUG(b)" "KNOWNCAUSE(k)" "|" "FIXED(f)") - (sequence "|" "CANCELED(c)"))) -@end lisp - -@vindex org-fast-tag-selection-include-todo -If you then press @kbd{C-c C-t} followed by the selection key, -the entry is switched to this state. @kbd{@key{SPC}} can be used to -remove any TODO keyword from an entry@footnote{Check also the variable @code{org-fast-tag-selection-include-todo}, -it allows you to change the TODO state through the tags interface (see -@ref{Setting Tags}), in case you like to mingle the two concepts. Note -that this means you need to come up with unique keys across both sets -of keywords.}. - -@node Per-file keywords -@subsection Setting up keywords for individual files - -@cindex keyword options -@cindex per-file keywords -@cindex @samp{TODO}, keyword -@cindex @samp{TYP_TODO}, keyword -@cindex @samp{SEQ_TODO}, keyword - -It can be very useful to use different aspects of the TODO mechanism -in different files. For file-local settings, you need to add special -lines to the file which set the keywords and interpretation for that -file only. For example, to set one of the two examples discussed -above, you need one of the following lines, starting in column zero -anywhere in the file: - -@example -#+TODO: TODO FEEDBACK VERIFY | DONE CANCELED -@end example - - -You may also write @samp{#+SEQ_TODO} to be explicit about the -interpretation, but it means the same as @samp{#+TODO}, or - -@example -#+TYP_TODO: Fred Sara Lucy Mike | DONE -@end example - - -A setup for using several sets in parallel would be: - -@example -#+TODO: TODO | DONE -#+TODO: REPORT BUG KNOWNCAUSE | FIXED -#+TODO: | CANCELED -@end example - -@cindex completion, of option keywords -@kindex M-TAB -To make sure you are using the correct keyword, type @samp{#+} into the -buffer and then use @kbd{M-@key{TAB}} to complete it (see @ref{Completion}). - -@cindex DONE, final TODO keyword -Remember that the keywords after the vertical bar---or the last -keyword if no bar is there---must always mean that the item is DONE, -although you may use a different word. After changing one of these -lines, use @kbd{C-c C-c} with point still in the line to make the -changes known to Org mode@footnote{Org mode parses these lines only when Org mode is activated -after visiting a file. @kbd{C-c C-c} with point in a line -starting with @samp{#+} is simply restarting Org mode for the current -buffer.}. - -@node Faces for TODO keywords -@subsection Faces for TODO keywords - -@cindex faces, for TODO keywords - -@vindex org-todo, face -@vindex org-done, face -@vindex org-todo-keyword-faces -Org mode highlights TODO keywords with special faces: @code{org-todo} for -keywords indicating that an item still has to be acted upon, and -@code{org-done} for keywords indicating that an item is finished. If you -are using more than two different states, you might want to use -special faces for some of them. This can be done using the variable -@code{org-todo-keyword-faces}. For example: - -@lisp -(setq org-todo-keyword-faces - '(("TODO" . org-warning) ("STARTED" . "yellow") - ("CANCELED" . (:foreground "blue" :weight bold)))) -@end lisp - -@vindex org-faces-easy-properties -While using a list with face properties as shown for @samp{CANCELED} -@emph{should} work, this does not always seem to be the case. If -necessary, define a special face and use that. A string is -interpreted as a color. The variable @code{org-faces-easy-properties} -determines if that color is interpreted as a foreground or -a background color. - -@node TODO dependencies -@subsection TODO dependencies - -@cindex TODO dependencies -@cindex dependencies, of TODO states - -@vindex org-enforce-todo-dependencies -@cindex @samp{ORDERED}, property -The structure of Org files---hierarchy and lists---makes it easy to -define TODO dependencies. Usually, a parent TODO task should not be -marked as done until all TODO subtasks, or children tasks, are marked -as done. Sometimes there is a logical sequence to (sub)tasks, so that -one subtask cannot be acted upon before all siblings above it have -been marked as done. If you customize the variable -@code{org-enforce-todo-dependencies}, Org blocks entries from changing -state to DONE while they have TODO children that are not DONE@. -Furthermore, if an entry has a property @samp{ORDERED}, each of its TODO -children is blocked until all earlier siblings are marked as done. -Here is an example: - -@example -* TODO Blocked until (two) is done -** DONE one -** TODO two - -* Parent -:PROPERTIES: -:ORDERED: t -:END: -** TODO a -** TODO b, needs to wait for (a) -** TODO c, needs to wait for (a) and (b) -@end example - -@cindex TODO dependencies, @samp{NOBLOCKING} -@cindex @samp{NOBLOCKING}, property -You can ensure an entry is never blocked by using the @samp{NOBLOCKING} -property (see @ref{Properties and Columns}): - -@example -* This entry is never blocked -:PROPERTIES: -:NOBLOCKING: t -:END: -@end example - -@table @asis -@item @kbd{C-c C-x o} (@code{org-toggle-ordered-property}) -@kindex C-c C-x o -@findex org-toggle-ordered-property -@vindex org-track-ordered-property-with-tag -Toggle the @samp{ORDERED} property of the current entry. A property is -used for this behavior because this should be local to the current -entry, not inherited from entries above like a tag (see @ref{Tags}). -However, if you would like to @emph{track} the value of this property -with a tag for better visibility, customize the variable -@code{org-track-ordered-property-with-tag}. - -@item @kbd{C-u C-u C-u C-c C-t} -@kindex C-u C-u C-u C-u C-c C-t -Change TODO state, regardless of any state blocking. -@end table - -@vindex org-agenda-dim-blocked-tasks -If you set the variable @code{org-agenda-dim-blocked-tasks}, TODO entries -that cannot be marked as done because of unmarked children are shown -in a dimmed font or even made invisible in agenda views (see @ref{Agenda Views}). - -@cindex checkboxes and TODO dependencies -@vindex org-enforce-todo-dependencies -You can also block changes of TODO states by using checkboxes (see -@ref{Checkboxes}). If you set the variable -@code{org-enforce-todo-checkbox-dependencies}, an entry that has unchecked -checkboxes is blocked from switching to DONE@. - -If you need more complex dependency structures, for example -dependencies between entries in different trees or files, check out -the contributed module @samp{org-depend.el}. - -@node Progress Logging -@section Progress Logging - -@cindex progress logging -@cindex logging, of progress - -To record a timestamp and a note when changing a TODO state, call the -command @code{org-todo} with a prefix argument. - -@table @asis -@item @kbd{C-u C-c C-t} (@code{org-todo}) -@kindex C-u C-c C-t -Prompt for a note and record a the time of the TODO state change. -The note is inserted as a list item below the headline, but can also -be placed into a drawer, see @ref{Tracking TODO state changes}. -@end table - -If you want to be more systematic, Org mode can automatically record a -timestamp and optionally a note when you mark a TODO item as DONE, or -even each time you change the state of a TODO item. This system is -highly configurable, settings can be on a per-keyword basis and can be -localized to a file or even a subtree. For information on how to -clock working time for a task, see @ref{Clocking Work Time}. - -@menu -* Closing items:: When was this entry marked as done? -* Tracking TODO state changes:: When did the status change? -* Tracking your habits:: How consistent have you been? -@end menu - -@node Closing items -@subsection Closing items - -The most basic automatic logging is to keep track of @emph{when} a certain -TODO item was marked as done. This can be achieved with@footnote{The corresponding in-buffer setting is: @samp{#+STARTUP: logdone}.} - -@lisp -(setq org-log-done 'time) -@end lisp - -@vindex org-closed-keep-when-no-todo -@noindent -Then each time you turn an entry from a TODO (not-done) state into any -of the DONE states, a line @samp{CLOSED: [timestamp]} is inserted just -after the headline. If you turn the entry back into a TODO item -through further state cycling, that line is removed again. If you -turn the entry back to a non-TODO state (by pressing @kbd{C-c C-t @key{SPC}} for example), that line is also removed, unless you set -@code{org-closed-keep-when-no-todo} to non-@code{nil}. If you want to record -a note along with the timestamp, use@footnote{The corresponding in-buffer setting is: @samp{#+STARTUP: -lognotedone}.} - -@lisp -(setq org-log-done 'note) -@end lisp - -@noindent -You are then prompted for a note, and that note is stored below the -entry with a @samp{Closing Note} heading. - -@node Tracking TODO state changes -@subsection Tracking TODO state changes - -@cindex drawer, for state change recording - -@vindex org-log-states-order-reversed -@vindex org-log-into-drawer -@cindex @samp{LOG_INTO_DRAWER}, property -You might want to automatically keep track of when a state change -occurred and maybe take a note about this change. You can either -record just a timestamp, or a time-stamped note. These records are -inserted after the headline as an itemized list, newest first@footnote{See the variable @code{org-log-states-order-reversed}.}. -When taking a lot of notes, you might want to get the notes out of the -way into a drawer (see @ref{Drawers}). Customize the variable -@code{org-log-into-drawer} to get this behavior---the recommended drawer -for this is called @samp{LOGBOOK}@footnote{Note that the @samp{LOGBOOK} drawer is unfolded when pressing -@kbd{@key{SPC}} in the agenda to show an entry---use @kbd{C-u @key{SPC}} to keep it folded here.}. You can also overrule the -setting of this variable for a subtree by setting a @samp{LOG_INTO_DRAWER} -property. - -Since it is normally too much to record a note for every state, Org -mode expects configuration on a per-keyword basis for this. This is -achieved by adding special markers @samp{!} (for a timestamp) or @samp{@@} (for -a note with timestamp) in parentheses after each keyword. For -example, with the setting - -@lisp -(setq org-todo-keywords - '((sequence "TODO(t)" "WAIT(w@@/!)" "|" "DONE(d!)" "CANCELED(c@@)"))) -@end lisp - -@noindent -To record a timestamp without a note for TODO keywords configured with -@samp{@@}, just type @kbd{C-c C-c} to enter a blank note when prompted. - -@vindex org-log-done -You not only define global TODO keywords and fast access keys, but -also request that a time is recorded when the entry is set to @samp{DONE}, -and that a note is recorded when switching to @samp{WAIT} or -@samp{CANCELED}@footnote{It is possible that Org mode records two timestamps when you -are using both @code{org-log-done} and state change logging. However, it -never prompts for two notes: if you have configured both, the state -change recording note takes precedence and cancel the closing note.}. The setting for @samp{WAIT} is even more special: the -@samp{!} after the slash means that in addition to the note taken when -entering the state, a timestamp should be recorded when @emph{leaving} the -@samp{WAIT} state, if and only if the @emph{target} state does not configure -logging for entering it. So it has no effect when switching from -@samp{WAIT} to @samp{DONE}, because @samp{DONE} is configured to record a timestamp -only. But when switching from @samp{WAIT} back to @samp{TODO}, the @samp{/!} in the -@samp{WAIT} setting now triggers a timestamp even though @samp{TODO} has no -logging configured. - -You can use the exact same syntax for setting logging preferences local -to a buffer: - -@example -#+TODO: TODO(t) WAIT(w@@/!) | DONE(d!) CANCELED(c@@) -@end example - - -@cindex @samp{LOGGING}, property -In order to define logging settings that are local to a subtree or -a single item, define a @samp{LOGGING} property in this entry. Any -non-empty @samp{LOGGING} property resets all logging settings to @code{nil}. -You may then turn on logging for this specific tree using @samp{STARTUP} -keywords like @samp{lognotedone} or @samp{logrepeat}, as well as adding state -specific settings like @samp{TODO(!)}. For example: - -@example -* TODO Log each state with only a time - :PROPERTIES: - :LOGGING: TODO(!) WAIT(!) DONE(!) CANCELED(!) - :END: -* TODO Only log when switching to WAIT, and when repeating - :PROPERTIES: - :LOGGING: WAIT(@@) logrepeat - :END: -* TODO No logging at all - :PROPERTIES: - :LOGGING: nil - :END: -@end example - -@node Tracking your habits -@subsection Tracking your habits - -@cindex habits -@cindex @samp{STYLE}, property - -Org has the ability to track the consistency of a special category of -TODO, called ``habits.'' To use habits, you have to enable the @code{habits} -module by customizing the variable @code{org-modules}. - -A habit has the following properties: - -@enumerate -@item -The habit is a TODO item, with a TODO keyword representing an open -state. - -@item -The property @samp{STYLE} is set to the value @samp{habit} (see @ref{Properties and Columns}). - -@item -The TODO has a scheduled date, usually with a @samp{.+} style repeat -interval. A @samp{++} style may be appropriate for habits with time -constraints, e.g., must be done on weekends, or a @samp{+} style for an -unusual habit that can have a backlog, e.g., weekly reports. - -@item -The TODO may also have minimum and maximum ranges specified by -using the syntax @samp{.+2d/3d}, which says that you want to do the task -at least every three days, but at most every two days. - -@item -State logging for the DONE state is enabled (see @ref{Tracking TODO state changes}), in order for historical data to be represented in -the consistency graph. If it is not enabled it is not an error, -but the consistency graphs are largely meaningless. -@end enumerate - -To give you an idea of what the above rules look like in action, here's an -actual habit with some history: - -@example -** TODO Shave - SCHEDULED: <2009-10-17 Sat .+2d/4d> - :PROPERTIES: - :STYLE: habit - :LAST_REPEAT: [2009-10-19 Mon 00:36] - :END: - - State "DONE" from "TODO" [2009-10-15 Thu] - - State "DONE" from "TODO" [2009-10-12 Mon] - - State "DONE" from "TODO" [2009-10-10 Sat] - - State "DONE" from "TODO" [2009-10-04 Sun] - - State "DONE" from "TODO" [2009-10-02 Fri] - - State "DONE" from "TODO" [2009-09-29 Tue] - - State "DONE" from "TODO" [2009-09-25 Fri] - - State "DONE" from "TODO" [2009-09-19 Sat] - - State "DONE" from "TODO" [2009-09-16 Wed] - - State "DONE" from "TODO" [2009-09-12 Sat] -@end example - -What this habit says is: I want to shave at most every 2 days---given -by the @samp{SCHEDULED} date and repeat interval---and at least every -4 days. If today is the 15th, then the habit first appears in the -agenda (see @ref{Agenda Views}) on Oct 17, after the minimum of 2 days has -elapsed, and will appear overdue on Oct 19, after four days have -elapsed. - -What's really useful about habits is that they are displayed along -with a consistency graph, to show how consistent you've been at -getting that task done in the past. This graph shows every day that -the task was done over the past three weeks, with colors for each day. -The colors used are: - -@table @asis -@item Blue -If the task was not to be done yet on that day. -@item Green -If the task could have been done on that day. -@item Yellow -If the task was going to be overdue the next day. -@item Red -If the task was overdue on that day. -@end table - -In addition to coloring each day, the day is also marked with an -asterisk if the task was actually done that day, and an exclamation -mark to show where the current day falls in the graph. - -There are several configuration variables that can be used to change -the way habits are displayed in the agenda. - -@table @asis -@item @code{org-habit-graph-column} -@vindex org-habit-graph-column -The buffer column at which the consistency graph should be drawn. -This overwrites any text in that column, so it is a good idea to -keep your habits' titles brief and to the point. - -@item @code{org-habit-preceding-days} -@vindex org-habit-preceding-days -The amount of history, in days before today, to appear in -consistency graphs. - -@item @code{org-habit-following-days} -@vindex org-habit-following-days -The number of days after today that appear in consistency graphs. - -@item @code{org-habit-show-habits-only-for-today} -@vindex org-habit-show-habits-only-for-today -If non-@code{nil}, only show habits in today's agenda view. The default -value is @code{t}. Pressing @kbd{C-u K} in the agenda toggles this -variable. -@end table - -Lastly, pressing @kbd{K} in the agenda buffer causes habits to -temporarily be disabled and do not appear at all. Press @kbd{K} -again to bring them back. They are also subject to tag filtering, if -you have habits which should only be done in certain contexts, for -example. - -@node Priorities -@section Priorities - -@cindex priorities -@cindex priority cookie - -If you use Org mode extensively, you may end up with enough TODO items -that it starts to make sense to prioritize them. Prioritizing can be -done by placing a @emph{priority cookie} into the headline of a TODO item -right after the TODO keyword, like this: - -@example -*** TODO [#A] Write letter to Sam Fortune -@end example - - -@vindex org-priority-faces -By default, Org mode supports three priorities: @samp{A}, @samp{B}, and @samp{C}. -@samp{A} is the highest priority. An entry without a cookie is treated as -equivalent if it had priority @samp{B}. Priorities make a difference only -for sorting in the agenda (see @ref{Weekly/daily agenda}). Outside the -agenda, they have no inherent meaning to Org mode. The cookies are -displayed with the face defined by the variable @code{org-priority-faces}, -which can be customized. - -You can also use numeric values for priorities, such as - -@example -*** TODO [#1] Write letter to Sam Fortune -@end example - - -When using numeric priorities, you need to set @code{org-priority-highest}, -@code{org-priority-lowest} and @code{org-priority-default} to integers, which -must all be strictly inferior to 65. - -Priorities can be attached to any outline node; they do not need to be -TODO items. - -@table @asis -@item @kbd{C-c ,} (@code{org-priority}) -@kindex C-c , -@findex org-priority -Set the priority of the current headline. The command prompts for -a priority character @samp{A}, @samp{B} or @samp{C}. When you press @kbd{@key{SPC}} -instead, the priority cookie, if one is set, is removed from the -headline. The priorities can also be changed ``remotely'' from the -agenda buffer with the @kbd{,} command (see @ref{Agenda Commands}). - -@item @kbd{S-@key{UP}} (@code{org-priority-up}) -@itemx @kbd{S-@key{DOWN}} (@code{org-priority-down}) -@kindex S-UP -@kindex S-DOWN -@findex org-priority-up -@findex org-priority-down -@vindex org-priority-start-cycle-with-default -Increase/decrease the priority of the current headline@footnote{See also the option @code{org-priority-start-cycle-with-default}.}. Note -that these keys are also used to modify timestamps (see @ref{Creating Timestamps}). See also @ref{Conflicts}, for -a discussion of the interaction with shift-selection. -@end table - -@vindex org-priority-highest -@vindex org-priority-lowest -@vindex org-priority-default -You can change the range of allowed priorities by setting the -variables @code{org-priority-highest}, @code{org-priority-lowest}, and -@code{org-priority-default}. For an individual buffer, you may set these -values (highest, lowest, default) like this (please make sure that the -highest priority is earlier in the alphabet than the lowest priority): - -@cindex @samp{PRIORITIES}, keyword -@example -#+PRIORITIES: A C B -@end example - - -Or, using numeric values: - -@example -#+PRIORITIES: 1 10 5 -@end example - -@node Breaking Down Tasks -@section Breaking Down Tasks into Subtasks - -@cindex tasks, breaking down -@cindex statistics, for TODO items - -@vindex org-agenda-todo-list-sublevels -It is often advisable to break down large tasks into smaller, -manageable subtasks. You can do this by creating an outline tree -below a TODO item, with detailed subtasks on the tree@footnote{To keep subtasks out of the global TODO list, see the option -@code{org-agenda-todo-list-sublevels}.}. To keep -an overview of the fraction of subtasks that have already been marked -as done, insert either @samp{[/]} or @samp{[%]} anywhere in the headline. These -cookies are updated each time the TODO status of a child changes, or -when pressing @kbd{C-c C-c} on the cookie. For example: - -@example -* Organize Party [33%] -** TODO Call people [1/2] -*** TODO Peter -*** DONE Sarah -** TODO Buy food -** DONE Talk to neighbor -@end example - -@cindex @samp{COOKIE_DATA}, property -If a heading has both checkboxes and TODO children below it, the -meaning of the statistics cookie become ambiguous. Set the property -@samp{COOKIE_DATA} to either @samp{checkbox} or @samp{todo} to resolve this issue. - -@vindex org-hierarchical-todo-statistics -If you would like to have the statistics cookie count any TODO entries -in the subtree (not just direct children), configure the variable -@code{org-hierarchical-todo-statistics}. To do this for a single subtree, -include the word @samp{recursive} into the value of the @samp{COOKIE_DATA} -property. - -@example -* Parent capturing statistics [2/20] - :PROPERTIES: - :COOKIE_DATA: todo recursive - :END: -@end example - -If you would like a TODO entry to automatically change to DONE when -all children are done, you can use the following setup: - -@lisp -(defun org-summary-todo (n-done n-not-done) - "Switch entry to DONE when all subentries are done, to TODO otherwise." - (let (org-log-done org-log-states) ; turn off logging - (org-todo (if (= n-not-done 0) "DONE" "TODO")))) - -(add-hook 'org-after-todo-statistics-hook 'org-summary-todo) -@end lisp - -Another possibility is the use of checkboxes to identify (a hierarchy -of) a large number of subtasks (see @ref{Checkboxes}). - -@node Checkboxes -@section Checkboxes - -@cindex checkboxes - -@vindex org-list-automatic-rules -Every item in a plain list@footnote{With the exception of description lists. But you can allow it -by modifying @code{org-list-automatic-rules} accordingly.} (see @ref{Plain Lists}) can be made into -a checkbox by starting it with the string @samp{[ ]}. This feature is -similar to TODO items (see @ref{TODO Items}), but is more lightweight. -Checkboxes are not included into the global TODO list, so they are -often great to split a task into a number of simple steps. Or you can -use them in a shopping list. - -Here is an example of a checkbox list. - -@example -* TODO Organize party [2/4] - - [-] call people [1/3] - - [ ] Peter - - [X] Sarah - - [ ] Sam - - [X] order food - - [ ] think about what music to play - - [X] talk to the neighbors -@end example - -Checkboxes work hierarchically, so if a checkbox item has children -that are checkboxes, toggling one of the children checkboxes makes the -parent checkbox reflect if none, some, or all of the children are -checked. - -@cindex statistics, for checkboxes -@cindex checkbox statistics -@cindex @samp{COOKIE_DATA}, property -@vindex org-hierarchical-checkbox-statistics -The @samp{[2/4]} and @samp{[1/3]} in the first and second line are cookies -indicating how many checkboxes present in this entry have been checked -off, and the total number of checkboxes present. This can give you an -idea on how many checkboxes remain, even without opening a folded -entry. The cookies can be placed into a headline or into (the first -line of) a plain list item. Each cookie covers checkboxes of direct -children structurally below the headline/item on which the cookie -appears@footnote{Set the variable @code{org-hierarchical-checkbox-statistics} if you -want such cookies to count all checkboxes below the cookie, not just -those belonging to direct children.}. You have to insert the cookie yourself by typing -either @samp{[/]} or @samp{[%]}. With @samp{[/]} you get an @samp{n out of m} result, as -in the examples above. With @samp{[%]} you get information about the -percentage of checkboxes checked (in the above example, this would be -@samp{[50%]} and @samp{[33%]}, respectively). In a headline, a cookie can count -either checkboxes below the heading or TODO states of children, and it -displays whatever was changed last. Set the property @samp{COOKIE_DATA} to -either @samp{checkbox} or @samp{todo} to resolve this issue. - -@cindex blocking, of checkboxes -@cindex checkbox blocking -@cindex @samp{ORDERED}, property -If the current outline node has an @samp{ORDERED} property, checkboxes must -be checked off in sequence, and an error is thrown if you try to check -off a box while there are unchecked boxes above it. - -The following commands work with checkboxes: - -@table @asis -@item @kbd{C-c C-c} (@code{org-toggle-checkbox}) -@kindex C-c C-c -@findex org-toggle-checkbox -Toggle checkbox status or---with prefix argument---checkbox presence -at point. With a single prefix argument, add an empty checkbox or -remove the current one@footnote{@kbd{C-u C-c C-c} on the @emph{first} item of a list with no -checkbox adds checkboxes to the rest of the list.}. With a double prefix argument, set -it to @samp{[-]}, which is considered to be an intermediate state. - -@item @kbd{C-c C-x C-b} (@code{org-toggle-checkbox}) -@kindex C-c C-x C-b -Toggle checkbox status or---with prefix argument---checkbox presence -at point. With double prefix argument, set it to @samp{[-]}, which is -considered to be an intermediate state. - -@itemize -@item -If there is an active region, toggle the first checkbox in the -region and set all remaining boxes to the same status as the -first. With a prefix argument, add or remove the checkbox for all -items in the region. - -@item -If point is in a headline, toggle checkboxes in the region between -this headline and the next---so @emph{not} the entire subtree. - -@item -If there is no active region, just toggle the checkbox at point. -@end itemize - -@item @kbd{C-c C-x C-r} (@code{org-toggle-radio-button}) -@kindex C-c C-x C-r -@findex org-toggle-radio-button -@cindex radio button, checkbox as -Toggle checkbox status by using the checkbox of the item at point as -a radio button: when the checkbox is turned on, all other checkboxes -on the same level will be turned off. With a universal prefix -argument, toggle the presence of the checkbox. With a double prefix -argument, set it to @samp{[-]}. - -@findex org-list-checkbox-radio-mode -@kbd{C-c C-c} can be told to consider checkboxes as radio buttons by -setting @samp{#+ATTR_ORG: :radio t} right before the list or by calling -@kbd{M-x org-list-checkbox-radio-mode} to activate this minor mode. - -@item @kbd{M-S-@key{RET}} (@code{org-insert-todo-heading}) -@kindex M-S-RET -@findex org-insert-todo-heading -Insert a new item with a checkbox. This works only if point is -already in a plain list item (see @ref{Plain Lists}). - -@item @kbd{C-c C-x o} (@code{org-toggle-ordered-property}) -@kindex C-c C-x o -@findex org-toggle-ordered-property -@vindex org-track-ordered-property-with-tag -Toggle the @samp{ORDERED} property of the entry, to toggle if checkboxes -must be checked off in sequence. A property is used for this -behavior because this should be local to the current entry, not -inherited like a tag. However, if you would like to @emph{track} the -value of this property with a tag for better visibility, customize -@code{org-track-ordered-property-with-tag}. - -@item @kbd{C-c #} (@code{org-update-statistics-cookies}) -@kindex C-c # -@findex org-update-statistics-cookies -Update the statistics cookie in the current outline entry. When -called with a @kbd{C-u} prefix, update the entire file. -Checkbox statistic cookies are updated automatically if you toggle -checkboxes with @kbd{C-c C-c} and make new ones with -@kbd{M-S-@key{RET}}. TODO statistics cookies update when changing -TODO states. If you delete boxes/entries or add/change them by -hand, use this command to get things back into sync. -@end table - -@node Tags -@chapter Tags - -@cindex tags -@cindex headline tagging -@cindex matching, tags -@cindex sparse tree, tag based - -An excellent way to implement labels and contexts for -cross-correlating information is to assign @emph{tags} to headlines. Org -mode has extensive support for tags. - -@vindex org-tag-faces -Every headline can contain a list of tags; they occur at the end of -the headline. Tags are normal words containing letters, numbers, @samp{_}, -and @samp{@@}. Tags must be preceded and followed by a single colon, e.g., -@samp{:work:}. Several tags can be specified, as in @samp{:work:urgent:}. Tags -by default are in bold face with the same color as the headline. You -may specify special faces for specific tags using the variable -@code{org-tag-faces}, in much the same way as you can for TODO keywords -(see @ref{Faces for TODO keywords}). - -@menu -* Tag Inheritance:: Tags use the tree structure of an outline. -* Setting Tags:: How to assign tags to a headline. -* Tag Hierarchy:: Create a hierarchy of tags. -* Tag Searches:: Searching for combinations of tags. -@end menu - -@node Tag Inheritance -@section Tag Inheritance - -@cindex tag inheritance -@cindex inheritance, of tags -@cindex sublevels, inclusion into tags match - -@emph{Tags} make use of the hierarchical structure of outline trees. If -a heading has a certain tag, all subheadings inherit the tag as well. -For example, in the list - -@example -* Meeting with the French group :work: -** Summary by Frank :boss:notes: -*** TODO Prepare slides for him :action: -@end example - -@noindent -the final heading has the tags @samp{work}, @samp{boss}, @samp{notes}, and @samp{action} -even though the final heading is not explicitly marked with those -tags. You can also set tags that all entries in a file should inherit -just as if these tags were defined in a hypothetical level zero that -surrounds the entire file. Use a line like this@footnote{As with all these in-buffer settings, pressing @kbd{C-c C-c} activates any changes in the line.} - -@cindex @samp{FILETAGS}, keyword -@example -#+FILETAGS: :Peter:Boss:Secret: -@end example - - -@vindex org-use-tag-inheritance -@vindex org-tags-exclude-from-inheritance -To limit tag inheritance to specific tags, or to turn it off entirely, -use the variables @code{org-use-tag-inheritance} and -@code{org-tags-exclude-from-inheritance}. - -@vindex org-tags-match-list-sublevels -When a headline matches during a tags search while tag inheritance is -turned on, all the sublevels in the same tree---for a simple match -form---match as well@footnote{This is only true if the search does not involve more complex -tests including properties (see @ref{Property Searches}).}. The list of matches may then become -very long. If you only want to see the first tags match in a subtree, -configure the variable @code{org-tags-match-list-sublevels} (not -recommended). - -@vindex org-agenda-use-tag-inheritance -Tag inheritance is relevant when the agenda search tries to match -a tag, either in the @code{tags} or @code{tags-todo} agenda types. In other -agenda types, @code{org-use-tag-inheritance} has no effect. Still, you may -want to have your tags correctly set in the agenda, so that tag -filtering works fine, with inherited tags. Set -@code{org-agenda-use-tag-inheritance} to control this: the default value -includes all agenda types, but setting this to @code{nil} can really speed -up agenda generation. - -@node Setting Tags -@section Setting Tags - -@cindex setting tags -@cindex tags, setting - -@kindex M-TAB -Tags can simply be typed into the buffer at the end of a headline. -After a colon, @kbd{M-@key{TAB}} offers completion on tags. There is -also a special command for inserting tags: - -@table @asis -@item @kbd{C-c C-q} (@code{org-set-tags-command}) -@kindex C-c C-q -@findex org-set-tags-command -@cindex completion, of tags -@vindex org-tags-column -Enter new tags for the current headline. Org mode either offers -completion or a special single-key interface for setting tags, see -below. After pressing @kbd{@key{RET}}, the tags are inserted and -aligned to @code{org-tags-column}. When called with a @kbd{C-u} -prefix, all tags in the current buffer are aligned to that column, -just to make things look nice. Tags are automatically realigned -after promotion, demotion, and TODO state changes (see @ref{TODO Basics}). - -@item @kbd{C-c C-c} (@code{org-set-tags-command}) -@kindex C-c C-c -When point is in a headline, this does the same as @kbd{C-c C-q}. -@end table - -@vindex org-complete-tags-always-offer-all-agenda-tags -@vindex org-tag-alist -@cindex @samp{TAGS}, keyword -Org supports tag insertion based on a @emph{list of tags}. By default this -list is constructed dynamically, containing all tags currently used in -the buffer@footnote{To extend this default list to all tags used in all agenda -files (see @ref{Agenda Views}), customize the variable -@code{org-complete-tags-always-offer-all-agenda-tags}.}. You may also globally specify a hard list of tags -with the variable @code{org-tag-alist}. Finally you can set the default -tags for a given file using the @samp{TAGS} keyword, like - -@example -#+TAGS: @@work @@home @@tennisclub -#+TAGS: laptop car pc sailboat -@end example - -If you have globally defined your preferred set of tags using the -variable @code{org-tag-alist}, but would like to use a dynamic tag list in -a specific file, add an empty @samp{TAGS} keyword to that file: - -@example -#+TAGS: -@end example - - -@vindex org-tag-persistent-alist -If you have a preferred set of tags that you would like to use in -every file, in addition to those defined on a per-file basis by @samp{TAGS} -keyword, then you may specify a list of tags with the variable -@code{org-tag-persistent-alist}. You may turn this off on a per-file basis -by adding a @samp{STARTUP} keyword to that file: - -@example -#+STARTUP: noptag -@end example - - -By default Org mode uses the standard minibuffer completion facilities -for entering tags. However, it also implements another, quicker, tag -selection method called @emph{fast tag selection}. This allows you to -select and deselect tags with just a single key press. For this to -work well you should assign unique letters to most of your commonly -used tags. You can do this globally by configuring the variable -@code{org-tag-alist} in your Emacs init file. For example, you may find -the need to tag many items in different files with @samp{@@home}. In this -case you can set something like: - -@lisp -(setq org-tag-alist '(("@@work" . ?w) ("@@home" . ?h) ("laptop" . ?l))) -@end lisp - -If the tag is only relevant to the file you are working on, then you -can instead set the @samp{TAGS} keyword as: - -@example -#+TAGS: @@work(w) @@home(h) @@tennisclub(t) laptop(l) pc(p) -@end example - - -The tags interface shows the available tags in a splash window. If -you want to start a new line after a specific tag, insert @samp{\n} into -the tag list - -@example -#+TAGS: @@work(w) @@home(h) @@tennisclub(t) \n laptop(l) pc(p) -@end example - - -@noindent -or write them in two lines: - -@example -#+TAGS: @@work(w) @@home(h) @@tennisclub(t) -#+TAGS: laptop(l) pc(p) -@end example - -You can also group together tags that are mutually exclusive by using -braces, as in: - -@example -#+TAGS: @{ @@work(w) @@home(h) @@tennisclub(t) @} laptop(l) pc(p) -@end example - - -@noindent -you indicate that at most one of @samp{@@work}, @samp{@@home}, and @samp{@@tennisclub} -should be selected. Multiple such groups are allowed. - -Do not forget to press @kbd{C-c C-c} with point in one of these -lines to activate any changes. - -To set these mutually exclusive groups in the variable -@code{org-tags-alist}, you must use the dummy tags @code{:startgroup} and -@code{:endgroup} instead of the braces. Similarly, you can use @code{:newline} -to indicate a line break. The previous example would be set globally -by the following configuration: - -@lisp -(setq org-tag-alist '((:startgroup . nil) - ("@@work" . ?w) ("@@home" . ?h) - ("@@tennisclub" . ?t) - (:endgroup . nil) - ("laptop" . ?l) ("pc" . ?p))) -@end lisp - -If at least one tag has a selection key then pressing @kbd{C-c C-c} automatically presents you with a special interface, listing -inherited tags, the tags of the current headline, and a list of all -valid tags with corresponding keys@footnote{Keys are automatically assigned to tags that have no -configured keys.}. - -Pressing keys assigned to tags adds or removes them from the list of -tags in the current line. Selecting a tag in a group of mutually -exclusive tags turns off any other tag from that group. - -In this interface, you can also use the following special keys: - -@table @asis -@item @kbd{@key{TAB}} -@kindex TAB -Enter a tag in the minibuffer, even if the tag is not in the -predefined list. You can complete on all tags present in the -buffer. You can also add several tags: just separate them with -a comma. - -@item @kbd{@key{SPC}} -@kindex SPC -Clear all tags for this line. - -@item @kbd{@key{RET}} -@kindex RET -Accept the modified set. - -@item @kbd{C-g} -@kindex C-g -Abort without installing changes. - -@item @kbd{q} -@kindex q -If @kbd{q} is not assigned to a tag, it aborts like -@kbd{C-g}. - -@item @kbd{!} -@kindex ! -Turn off groups of mutually exclusive tags. Use this to (as an -exception) assign several tags from such a group. - -@item @kbd{C-c} -@kindex C-c C-c -Toggle auto-exit after the next change (see below). If you are -using expert mode, the first @kbd{C-c} displays the selection -window. -@end table - -This method lets you assign tags to a headline with very few keys. -With the above setup, you could clear the current tags and set -@samp{@@home}, @samp{laptop} and @samp{pc} tags with just the following keys: -@kbd{C-c C-c @key{SPC} h l p @key{RET}}. Switching from @samp{@@home} to @samp{@@work} -would be done with @kbd{C-c C-c w @key{RET}} or alternatively with -@kbd{C-c C-c C-c w}. Adding the non-predefined tag @samp{sarah} could -be done with @kbd{C-c C-c @key{TAB} s a r a h @key{RET}}. - -@vindex org-fast-tag-selection-single-key -If you find that most of the time you need only a single key press to -modify your list of tags, set the variable -@code{org-fast-tag-selection-single-key}. Then you no longer have to press -@kbd{@key{RET}} to exit fast tag selection---it exits after the first -change. If you then occasionally need more keys, press @kbd{C-c} -to turn off auto-exit for the current tag selection process (in -effect: start selection with @kbd{C-c C-c C-c} instead of -@kbd{C-c C-c}). If you set the variable to the value @code{expert}, -the special window is not even shown for single-key tag selection, it -comes up only when you press an extra @kbd{C-c}. - -@node Tag Hierarchy -@section Tag Hierarchy - -@cindex group tags -@cindex tags, groups -@cindex tags hierarchy - -Tags can be defined in hierarchies. A tag can be defined as a @emph{group -tag} for a set of other tags. The group tag can be seen as the -``broader term'' for its set of tags. Defining multiple group tags and -nesting them creates a tag hierarchy. - -One use-case is to create a taxonomy of terms (tags) that can be used -to classify nodes in a document or set of documents. - -When you search for a group tag, it return matches for all members in -the group and its subgroups. In an agenda view, filtering by a group -tag displays or hide headlines tagged with at least one of the members -of the group or any of its subgroups. This makes tag searches and -filters even more flexible. - -You can set group tags by using brackets and inserting a colon between -the group tag and its related tags---beware that all whitespaces are -mandatory so that Org can parse this line correctly: - -@example -#+TAGS: [ GTD : Control Persp ] -@end example - - -In this example, @samp{GTD} is the group tag and it is related to two other -tags: @samp{Control}, @samp{Persp}. Defining @samp{Control} and @samp{Persp} as group -tags creates a hierarchy of tags: - -@example -#+TAGS: [ Control : Context Task ] -#+TAGS: [ Persp : Vision Goal AOF Project ] -@end example - -That can conceptually be seen as a hierarchy of tags: - -@itemize -@item -@samp{GTD} -@itemize -@item -@samp{Persp} -@itemize -@item -@samp{Vision} -@item -@samp{Goal} -@item -@samp{AOF} -@item -@samp{Project} -@end itemize -@item -@samp{Control} -@itemize -@item -@samp{Context} -@item -@samp{Task} -@end itemize -@end itemize -@end itemize - -You can use the @code{:startgrouptag}, @code{:grouptags} and @code{:endgrouptag} -keyword directly when setting @code{org-tag-alist} directly: - -@lisp -(setq org-tag-alist '((:startgrouptag) - ("GTD") - (:grouptags) - ("Control") - ("Persp") - (:endgrouptag) - (:startgrouptag) - ("Control") - (:grouptags) - ("Context") - ("Task") - (:endgrouptag))) -@end lisp - -The tags in a group can be mutually exclusive if using the same group -syntax as is used for grouping mutually exclusive tags together; using -curly brackets. - -@example -#+TAGS: @{ Context : @@Home @@Work @@Call @} -@end example - - -When setting @code{org-tag-alist} you can use @code{:startgroup} and @code{:endgroup} -instead of @code{:startgrouptag} and @code{:endgrouptag} to make the tags -mutually exclusive. - -Furthermore, the members of a group tag can also be regular -expressions, creating the possibility of a more dynamic and rule-based -tag structure. The regular expressions in the group must be specified -within curly brackets. Here is an expanded example: - -@example -#+TAGS: [ Vision : @{V@@.+@} ] -#+TAGS: [ Goal : @{G@@.+@} ] -#+TAGS: [ AOF : @{AOF@@.+@} ] -#+TAGS: [ Project : @{P@@.+@} ] -@end example - -Searching for the tag @samp{Project} now lists all tags also including -regular expression matches for @samp{P@@.+}, and similarly for tag searches -on @samp{Vision}, @samp{Goal} and @samp{AOF}. For example, this would work well for -a project tagged with a common project-identifier, e.g., -@samp{P@@2014_OrgTags}. - -@kindex C-c C-x q -@findex org-toggle-tags-groups -@vindex org-group-tags -If you want to ignore group tags temporarily, toggle group tags -support with @code{org-toggle-tags-groups}, bound to @kbd{C-c C-x q}. -If you want to disable tag groups completely, set @code{org-group-tags} to -@code{nil}. - -@node Tag Searches -@section Tag Searches - -@cindex tag searches -@cindex searching for tags - -Once a system of tags has been set up, it can be used to collect -related information into special lists. - -@table @asis -@item @kbd{C-c / m} or @kbd{C-c \} (@code{org-match-sparse-tree}) -@kindex C-c / m -@kindex C-c \ -@findex org-match-sparse-tree -Create a sparse tree with all headlines matching a tags search. -With a @kbd{C-u} prefix argument, ignore headlines that are not -a TODO line. - -@item @kbd{M-x org-agenda m} (@code{org-tags-view}) -@kindex m @r{(Agenda dispatcher)} -@findex org-tags-view -Create a global list of tag matches from all agenda files. See -@ref{Matching tags and properties}. - -@item @kbd{M-x org-agenda M} (@code{org-tags-view}) -@kindex M @r{(Agenda dispatcher)} -@vindex org-tags-match-list-sublevels -Create a global list of tag matches from all agenda files, but check -only TODO items and force checking subitems (see the option -@code{org-tags-match-list-sublevels}). -@end table - -These commands all prompt for a match string which allows basic -Boolean logic like @samp{+boss+urgent-project1}, to find entries with tags -@samp{boss} and @samp{urgent}, but not @samp{project1}, or @samp{Kathy|Sally} to find -entries which are tagged, like @samp{Kathy} or @samp{Sally}. The full syntax of -the search string is rich and allows also matching against TODO -keywords, entry levels and properties. For a complete description -with many examples, see @ref{Matching tags and properties}. - -@node Properties and Columns -@chapter Properties and Columns - -@cindex properties - -A property is a key-value pair associated with an entry. Properties -can be set so they are associated with a single entry, with every -entry in a tree, or with the whole buffer. - -There are two main applications for properties in Org mode. First, -properties are like tags, but with a value. Imagine maintaining -a file where you document bugs and plan releases for a piece of -software. Instead of using tags like @samp{release_1}, @samp{release_2}, you -can use a property, say @samp{Release}, that in different subtrees has -different values, such as @samp{1.0} or @samp{2.0}. Second, you can use -properties to implement (very basic) database capabilities in an Org -buffer. Imagine keeping track of your music CDs, where properties -could be things such as the album, artist, date of release, number of -tracks, and so on. - -Properties can be conveniently edited and viewed in column view (see -@ref{Column View}). - -@menu -* Property Syntax:: How properties are spelled out. -* Special Properties:: Access to other Org mode features. -* Property Searches:: Matching property values. -* Property Inheritance:: Passing values down a tree. -* Column View:: Tabular viewing and editing. -@end menu - -@node Property Syntax -@section Property Syntax - -@cindex property syntax -@cindex drawer, for properties - -Properties are key--value pairs. When they are associated with -a single entry or with a tree they need to be inserted into a special -drawer (see @ref{Drawers}) with the name @samp{PROPERTIES}, which has to be -located right below a headline, and its planning line (see @ref{Deadlines and Scheduling}) when applicable. Each property is specified on -a single line, with the key---surrounded by colons---first, and the -value after it. Keys are case-insensitive. Here is an example: - -@example -* CD collection -** Classic -*** Goldberg Variations - :PROPERTIES: - :Title: Goldberg Variations - :Composer: J.S. Bach - :Artist: Glenn Gould - :Publisher: Deutsche Grammophon - :NDisks: 1 - :END: -@end example - -Depending on the value of @code{org-use-property-inheritance}, a property -set this way is associated either with a single entry, or with the -sub-tree defined by the entry, see @ref{Property Inheritance}. - -You may define the allowed values for a particular property @samp{Xyz} by -setting a property @samp{Xyz_ALL}. This special property is @emph{inherited}, -so if you set it in a level 1 entry, it applies to the entire tree. -When allowed values are defined, setting the corresponding property -becomes easier and is less prone to typing errors. For the example -with the CD collection, we can pre-define publishers and the number of -disks in a box like this: - -@example -* CD collection - :PROPERTIES: - :NDisks_ALL: 1 2 3 4 - :Publisher_ALL: "Deutsche Grammophon" Philips EMI - :END: -@end example - -Properties can be inserted on buffer level. That means they apply -before the first headline and can be inherited by all entries in a -file. Property blocks defined before first headline needs to be -located at the top of the buffer, allowing only comments above. - -Properties can also be defined using lines like: - -@cindex @samp{_ALL} suffix, in properties -@cindex @samp{PROPERTY}, keyword -@example -#+PROPERTY: NDisks_ALL 1 2 3 4 -@end example - - -@cindex @samp{+} suffix, in properties -If you want to add to the value of an existing property, append a @samp{+} -to the property name. The following results in the property @samp{var} -having the value @samp{foo=1 bar=2}. - -@example -#+PROPERTY: var foo=1 -#+PROPERTY: var+ bar=2 -@end example - -It is also possible to add to the values of inherited properties. The -following results in the @samp{Genres} property having the value @samp{Classic -Baroque} under the @samp{Goldberg Variations} subtree. - -@example -* CD collection -** Classic - :PROPERTIES: - :Genres: Classic - :END: -*** Goldberg Variations - :PROPERTIES: - :Title: Goldberg Variations - :Composer: J.S. Bach - :Artist: Glenn Gould - :Publisher: Deutsche Grammophon - :NDisks: 1 - :Genres+: Baroque - :END: -@end example - -Note that a property can only have one entry per drawer. - -@vindex org-global-properties -Property values set with the global variable @code{org-global-properties} -can be inherited by all entries in all Org files. - -The following commands help to work with properties: - -@table @asis -@item @kbd{M-@key{TAB}} (@code{pcomplete}) -@kindex M-TAB -@findex pcomplete -After an initial colon in a line, complete property keys. All keys -used in the current file are offered as possible completions. - -@item @kbd{C-c C-x p} (@code{org-set-property}) -@kindex C-c C-x p -@findex org-set-property -Set a property. This prompts for a property name and a value. If -necessary, the property drawer is created as well. - -@item @kbd{C-u M-x org-insert-drawer} -@findex org-insert-drawer -Insert a property drawer into the current entry. The drawer is -inserted early in the entry, but after the lines with planning -information like deadlines. If before first headline the drawer is -inserted at the top of the drawer after any potential comments. - -@item @kbd{C-c C-c} (@code{org-property-action}) -@kindex C-c C-c -@findex org-property-action -With point in a property drawer, this executes property commands. - -@item @kbd{C-c C-c s} (@code{org-set-property}) -@kindex C-c C-c s -@findex org-set-property -Set a property in the current entry. Both the property and the -value can be inserted using completion. - -@item @kbd{S-@key{RIGHT}} (@code{org-property-next-allowed-values}) -@itemx @kbd{S-@key{LEFT}} (@code{org-property-previous-allowed-value}) -@kindex S-RIGHT -@kindex S-LEFT -Switch property at point to the next/previous allowed value. - -@item @kbd{C-c C-c d} (@code{org-delete-property}) -@kindex C-c C-c d -@findex org-delete-property -Remove a property from the current entry. - -@item @kbd{C-c C-c D} (@code{org-delete-property-globally}) -@kindex C-c C-c D -@findex org-delete-property-globally -Globally remove a property, from all entries in the current file. - -@item @kbd{C-c C-c c} (@code{org-compute-property-at-point}) -@kindex C-c C-c c -@findex org-compute-property-at-point -Compute the property at point, using the operator and scope from the -nearest column format definition. -@end table - -@node Special Properties -@section Special Properties - -@cindex properties, special - -Special properties provide an alternative access method to Org mode -features, like the TODO state or the priority of an entry, discussed -in the previous chapters. This interface exists so that you can -include these states in a column view (see @ref{Column View}), or to use -them in queries. The following property names are special and should -not be used as keys in the properties drawer: - -@cindex @samp{ALLTAGS}, special property -@cindex @samp{BLOCKED}, special property -@cindex @samp{CLOCKSUM}, special property -@cindex @samp{CLOCKSUM_T}, special property -@cindex @samp{CLOSED}, special property -@cindex @samp{DEADLINE}, special property -@cindex @samp{FILE}, special property -@cindex @samp{ITEM}, special property -@cindex @samp{PRIORITY}, special property -@cindex @samp{SCHEDULED}, special property -@cindex @samp{TAGS}, special property -@cindex @samp{TIMESTAMP}, special property -@cindex @samp{TIMESTAMP_IA}, special property -@cindex @samp{TODO}, special property -@multitable {aaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{ALLTAGS} -@tab All tags, including inherited ones. -@item @samp{BLOCKED} -@tab @code{t} if task is currently blocked by children or siblings. -@item @samp{CATEGORY} -@tab The category of an entry. -@item @samp{CLOCKSUM} -@tab The sum of CLOCK intervals in the subtree. @code{org-clock-sum} -@item -@tab must be run first to compute the values in the current buffer. -@item @samp{CLOCKSUM_T} -@tab The sum of CLOCK intervals in the subtree for today. -@item -@tab @code{org-clock-sum-today} must be run first to compute the -@item -@tab values in the current buffer. -@item @samp{CLOSED} -@tab When was this entry closed? -@item @samp{DEADLINE} -@tab The deadline timestamp. -@item @samp{FILE} -@tab The filename the entry is located in. -@item @samp{ITEM} -@tab The headline of the entry. -@item @samp{PRIORITY} -@tab The priority of the entry, a string with a single letter. -@item @samp{SCHEDULED} -@tab The scheduling timestamp. -@item @samp{TAGS} -@tab The tags defined directly in the headline. -@item @samp{TIMESTAMP} -@tab The first keyword-less timestamp in the entry. -@item @samp{TIMESTAMP_IA} -@tab The first inactive timestamp in the entry. -@item @samp{TODO} -@tab The TODO keyword of the entry. -@end multitable - -@node Property Searches -@section Property Searches - -@cindex properties, searching -@cindex searching, of properties - -To create sparse trees and special lists with selection based on -properties, the same commands are used as for tag searches (see @ref{Tag Searches}). - -@table @asis -@item @kbd{C-c / m} or @kbd{C-c \} (@code{org-match-sparse-tree}) -@kindex C-c / m -@kindex C-c \ -@findex org-match-sparse-tree -Create a sparse tree with all matching entries. With -a @kbd{C-u} prefix argument, ignore headlines that are not -a TODO line. - -@item @kbd{M-x org-agenda m} (@code{org-tags-view}) -@kindex m @r{(Agenda dispatcher)} -@findex org-tags-view -Create a global list of tag/property matches from all agenda files. - -@item @kbd{M-x org-agenda M} (@code{org-tags-view}) -@kindex M @r{(Agenda dispatcher)} -@vindex org-tags-match-list-sublevels -Create a global list of tag matches from all agenda files, but check -only TODO items and force checking of subitems (see the option -@code{org-tags-match-list-sublevels}). -@end table - -The syntax for the search string is described in @ref{Matching tags and properties}. - -There is also a special command for creating sparse trees based on a -single property: - -@table @asis -@item @kbd{C-c / p} -@kindex C-c / p -Create a sparse tree based on the value of a property. This first -prompts for the name of a property, and then for a value. A sparse -tree is created with all entries that define this property with the -given value. If you enclose the value in curly braces, it is -interpreted as a regular expression and matched against the property -values. -@end table - -@node Property Inheritance -@section Property Inheritance - -@cindex properties, inheritance -@cindex inheritance, of properties - -@vindex org-use-property-inheritance -The outline structure of Org documents lends itself to an inheritance -model of properties: if the parent in a tree has a certain property, -the children can inherit this property. Org mode does not turn this -on by default, because it can slow down property searches -significantly and is often not needed. However, if you find -inheritance useful, you can turn it on by setting the variable -@code{org-use-property-inheritance}. It may be set to @code{t} to make all -properties inherited from the parent, to a list of properties that -should be inherited, or to a regular expression that matches inherited -properties. If a property has the value @code{nil}, this is interpreted as -an explicit un-define of the property, so that inheritance search -stops at this value and returns @code{nil}. - -Org mode has a few properties for which inheritance is hard-coded, at -least for the special applications for which they are used: - -@table @asis -@item @code{COLUMNS} -@cindex @samp{COLUMNS}, property -The @samp{COLUMNS} property defines the format of column view (see -@ref{Column View}). It is inherited in the sense that the level where -a @samp{COLUMNS} property is defined is used as the starting point for -a column view table, independently of the location in the subtree -from where columns view is turned on. - -@item @code{CATEGORY} -@cindex @samp{CATEGORY}, property -For agenda view, a category set through a @samp{CATEGORY} property -applies to the entire subtree. - -@item @code{ARCHIVE} -@cindex @samp{ARCHIVE}, property -For archiving, the @samp{ARCHIVE} property may define the archive -location for the entire subtree (see @ref{Moving subtrees}). - -@item @code{LOGGING} -@cindex @samp{LOGGING}, property -The @samp{LOGGING} property may define logging settings for an entry or -a subtree (see @ref{Tracking TODO state changes}). -@end table - -@node Column View -@section Column View - -A great way to view and edit properties in an outline tree is @emph{column -view}. In column view, each outline node is turned into a table row. -Columns in this table provide access to properties of the entries. -Org mode implements columns by overlaying a tabular structure over the -headline of each item. While the headlines have been turned into -a table row, you can still change the visibility of the outline tree. -For example, you get a compact table by switching to ``contents'' -view---@kbd{S-@key{TAB}} @kbd{S-@key{TAB}}, or simply @kbd{c} -while column view is active---but you can still open, read, and edit -the entry below each headline. Or, you can switch to column view -after executing a sparse tree command and in this way get a table only -for the selected items. Column view also works in agenda buffers (see -@ref{Agenda Views}) where queries have collected selected items, possibly -from a number of files. - -@menu -* Defining columns:: The COLUMNS format property. -* Using column view:: How to create and use column view. -* Capturing column view:: A dynamic block for column view. -@end menu - -@node Defining columns -@subsection Defining columns - -@cindex column view, for properties -@cindex properties, column view - -Setting up a column view first requires defining the columns. This is -done by defining a column format line. - -@menu -* Scope of column definitions:: Where defined, where valid? -* Column attributes:: Appearance and content of a column. -@end menu - -@node Scope of column definitions -@subsubsection Scope of column definitions - -To specify a format that only applies to a specific tree, add -a @samp{COLUMNS} property to the top node of that tree, for example: - -@example -** Top node for columns view - :PROPERTIES: - :COLUMNS: %25ITEM %TAGS %PRIORITY %TODO - :END: -@end example - -A @samp{COLUMNS} property within a property drawer before first headline -will apply to the entire file. As an addition to property drawers, -keywords can also be defined for an entire file using a line like: - -@cindex @samp{COLUMNS}, keyword -@example -#+COLUMNS: %25ITEM %TAGS %PRIORITY %TODO -@end example - - -If a @samp{COLUMNS} property is present in an entry, it defines columns for -the entry itself, and for the entire subtree below it. Since the -column definition is part of the hierarchical structure of the -document, you can define columns on level 1 that are general enough -for all sublevels, and more specific columns further down, when you -edit a deeper part of the tree. - -@node Column attributes -@subsubsection Column attributes - -A column definition sets the attributes of a column. The general -definition looks like this: - -@example -%[WIDTH]PROPERTY[(TITLE)][@{SUMMARY-TYPE@}] -@end example - - -@noindent -Except for the percent sign and the property name, all items are -optional. The individual parts have the following meaning: - -@table @asis -@item @var{WIDTH} -An integer specifying the width of the column in characters. If -omitted, the width is determined automatically. - -@item @var{PROPERTY} -The property that should be edited in this column. Special -properties representing meta data are allowed here as well (see -@ref{Special Properties}). - -@item @var{TITLE} -The header text for the column. If omitted, the property name is -used. - -@item @var{SUMMARY-TYPE} -The summary type. If specified, the column values for parent nodes -are computed from the children@footnote{If more than one summary type applies to the same property, -the parent values are computed according to the first of them.}. - -Supported summary types are: - -@multitable {aaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{+} -@tab Sum numbers in this column. -@item @samp{+;%.1f} -@tab Like @samp{+}, but format result with @samp{%.1f}. -@item @samp{$} -@tab Currency, short for @samp{+;%.2f}. -@item @samp{min} -@tab Smallest number in column. -@item @samp{max} -@tab Largest number. -@item @samp{mean} -@tab Arithmetic mean of numbers. -@item @samp{X} -@tab Checkbox status, @samp{[X]} if all children are @samp{[X]}. -@item @samp{X/} -@tab Checkbox status, @samp{[n/m]}. -@item @samp{X%} -@tab Checkbox status, @samp{[n%]}. -@item @samp{:} -@tab Sum times, HH:MM, plain numbers are minutes. -@item @samp{:min} -@tab Smallest time value in column. -@item @samp{:max} -@tab Largest time value. -@item @samp{:mean} -@tab Arithmetic mean of time values. -@item @samp{@@min} -@tab Minimum age@footnote{An age can be defined as a duration, using units defined in -@code{org-duration-units}, e.g., @samp{3d 1h}. If any value in the column is as -such, the summary is also expressed as a duration.} (in days/hours/mins/seconds). -@item @samp{@@max} -@tab Maximum age (in days/hours/mins/seconds). -@item @samp{@@mean} -@tab Arithmetic mean of ages (in days/hours/mins/seconds). -@item @samp{est+} -@tab Add low-high estimates. -@end multitable - -@vindex org-columns-summary-types -You can also define custom summary types by setting -@code{org-columns-summary-types}. -@end table - -The @samp{est+} summary type requires further explanation. It is used for -combining estimates, expressed as low-high ranges. For example, -instead of estimating a particular task will take 5 days, you might -estimate it as 5--6 days if you're fairly confident you know how much -work is required, or 1--10 days if you do not really know what needs -to be done. Both ranges average at 5.5 days, but the first represents -a more predictable delivery. - -When combining a set of such estimates, simply adding the lows and -highs produces an unrealistically wide result. Instead, @samp{est+} adds -the statistical mean and variance of the subtasks, generating a final -estimate from the sum. For example, suppose you had ten tasks, each -of which was estimated at 0.5 to 2 days of work. Straight addition -produces an estimate of 5 to 20 days, representing what to expect if -everything goes either extremely well or extremely poorly. In -contrast, @samp{est+} estimates the full job more realistically, at 10--15 -days. - -Here is an example for a complete columns definition, along with -allowed values@footnote{Please note that the @samp{COLUMNS} definition must be on a single -line; it is wrapped here only because of formatting constraints.}. - -@example -:COLUMNS: %25ITEM %9Approved(Approved?)@{X@} %Owner %11Status \ - %10Time_Estimate@{:@} %CLOCKSUM %CLOCKSUM_T -:Owner_ALL: Tammy Mark Karl Lisa Don -:Status_ALL: "In progress" "Not started yet" "Finished" "" -:Approved_ALL: "[ ]" "[X]" -@end example - -@noindent -The first column, @samp{%25ITEM}, means the first 25 characters of the item -itself, i.e., of the headline. You probably always should start the -column definition with the @samp{ITEM} specifier. The other specifiers -create columns @samp{Owner} with a list of names as allowed values, for -@samp{Status} with four different possible values, and for a checkbox field -@samp{Approved}. When no width is given after the @samp{%} character, the -column is exactly as wide as it needs to be in order to fully display -all values. The @samp{Approved} column does have a modified title -(@samp{Approved?}, with a question mark). Summaries are created for the -@samp{Time_Estimate} column by adding time duration expressions like HH:MM, -and for the @samp{Approved} column, by providing an @samp{[X]} status if all -children have been checked. The @samp{CLOCKSUM} and @samp{CLOCKSUM_T} columns -are special, they lists the sums of CLOCK intervals in the subtree, -either for all clocks or just for today. - -@node Using column view -@subsection Using column view - - - -@anchor{Turning column view on or off} -@subsubheading Turning column view on or off - -@table @asis -@item @kbd{C-c C-x C-c} (@code{org-columns}) -@kindex C-c C-x C-c -@vindex org-columns -@vindex org-columns-default-format -Turn on column view. If point is before the first headline in the -file, column view is turned on for the entire file, using the -@samp{#+COLUMNS} definition. If point is somewhere inside the outline, -this command searches the hierarchy, up from point, for a @samp{COLUMNS} -property that defines a format. When one is found, the column view -table is established for the tree starting at the entry that -contains the @samp{COLUMNS} property. If no such property is found, the -format is taken from the @samp{#+COLUMNS} line or from the variable -@code{org-columns-default-format}, and column view is established for the -current entry and its subtree. - -@item @kbd{r} or @kbd{g} on a columns view line (@code{org-columns-redo}) -@kindex r -@kindex g -@findex org-columns-redo -Recreate the column view, to include recent changes made in the -buffer. - -@item @kbd{C-c C-c} or @kbd{q} on a columns view line (@code{org-columns-quit}) -@kindex q -@kindex C-c C-c -@findex org-columns-quit -Exit column view. -@end table - -@anchor{Editing values} -@subsubheading Editing values - -@table @asis -@item @kbd{@key{LEFT}}, @kbd{@key{RIGHT}}, @kbd{@key{UP}}, @kbd{@key{DOWN}} -Move through the column view from field to field. - -@item @kbd{1..9,0} -@kindex 1..9,0 -Directly select the Nth allowed value, @kbd{0} selects the -10th value. - -@item @kbd{n} or @kbd{S-@key{RIGHT}} (@code{org-columns-next-allowed-value}) -@itemx @kbd{p} or @kbd{S-@key{LEFT}} (@code{org-columns-previous-allowed-value}) -@kindex n -@kindex S-RIGHT -@kindex p -@kindex S-LEFT -@findex org-columns-next-allowed-value -@findex org-columns-previous-allowed-value -Switch to the next/previous allowed value of the field. For this, -you have to have specified allowed values for a property. - -@item @kbd{e} (@code{org-columns-edit-value}) -@kindex e -@findex org-columns-edit-value -Edit the property at point. For the special properties, this -invokes the same interface that you normally use to change that -property. For example, the tag completion or fast selection -interface pops up when editing a @samp{TAGS} property. - -@item @kbd{C-c C-c} (@code{org-columns-toggle-or-columns-quit}) -@kindex C-c C-c -@findex org-columns-toggle-or-columns-quit -When there is a checkbox at point, toggle it. Else exit column -view. - -@item @kbd{v} (@code{org-columns-show-value}) -@kindex v -@findex org-columns-show-value -View the full value of this property. This is useful if the width -of the column is smaller than that of the value. - -@item @kbd{a} (@code{org-columns-edit-allowed}) -@kindex a -@findex org-columns-edit-allowed -Edit the list of allowed values for this property. If the list is -found in the hierarchy, the modified values is stored there. If no -list is found, the new value is stored in the first entry that is -part of the current column view. -@end table - -@anchor{Modifying column view on-the-fly} -@subsubheading Modifying column view on-the-fly - -@table @asis -@item @kbd{<} (@code{org-columns-narrow}) -@itemx @kbd{>} (@code{org-columns-widen}) -@kindex < -@kindex > -@findex org-columns-narrow -@findex org-columns-widen -Make the column narrower/wider by one character. - -@item @kbd{S-M-@key{RIGHT}} (@code{org-columns-new}) -@kindex S-M-RIGHT -@findex org-columns-new -Insert a new column, to the left of the current column. - -@item @kbd{S-M-@key{LEFT}} (@code{org-columns-delete}) -@kindex S-M-LEFT -@findex org-columns-delete -Delete the current column. -@end table - -@node Capturing column view -@subsection Capturing column view - -Since column view is just an overlay over a buffer, it cannot be -exported or printed directly. If you want to capture a column view, -use a @samp{columnview} dynamic block (see @ref{Dynamic Blocks}). The frame of -this block looks like this: - -@cindex @samp{BEGIN columnview} -@example -* The column view -#+BEGIN: columnview :hlines 1 :id "label" - -#+END: -@end example - -This dynamic block has the following parameters: - -@table @asis -@item @samp{:id} -This is the most important parameter. Column view is a feature that -is often localized to a certain (sub)tree, and the capture block -might be at a different location in the file. To identify the tree -whose view to capture, you can use four values: - -@table @asis -@item @samp{local} -Use the tree in which the capture block is located. - -@item @samp{global} -Make a global view, including all headings in the file. - -@item @samp{file:FILENAME} -Run column view at the top of the @var{FILENAME} file. - -@item @samp{LABEL} -@cindex @samp{ID}, property -Call column view in the tree that has an @samp{ID} property with the -value @var{LABEL}. You can use @kbd{M-x org-id-copy} to -create a globally unique ID for the current entry and copy it to -the kill-ring. -@end table - -@item @samp{:match} -When set to a string, use this as a tags/property match filter to -select only a subset of the headlines in the scope set by the @code{:id} -parameter. -@end table - - -@table @asis -@item @samp{:hlines} -When @code{t}, insert an hline after every line. When a number N, insert -an hline before each headline with level @code{<= N}. - -@item @samp{:vlines} -When non-@code{nil}, force column groups to get vertical lines. - -@item @samp{:maxlevel} -When set to a number, do not capture entries below this level. - -@item @samp{:skip-empty-rows} -When non-@code{nil}, skip rows where the only non-empty specifier of -the column view is @samp{ITEM}. - -@item @samp{:exclude-tags} -List of tags to exclude from column view table: entries with these -tags will be excluded from the column view. - -@item @samp{:indent} -When non-@code{nil}, indent each @samp{ITEM} field according to its level. - -@item @samp{:format} -Specify a column attribute (see @ref{Column attributes}) for the dynamic -block. -@end table - -The following commands insert or update the dynamic block: - -@table @asis -@item @code{org-columns-insert-dblock} -@kindex C-c C-x x -@findex org-columns-insert-dblock -Insert a dynamic block capturing a column view. Prompt for the -scope or ID of the view. - -This command can be invoked by calling -@code{org-dynamic-block-insert-dblock} (@kbd{C-c C-x x}) and -selecting ``columnview'' (see @ref{Dynamic Blocks}). - -@item @kbd{C-c C-c} @kbd{C-c C-x C-u} (@code{org-dblock-update}) -@kindex C-c C-c -@kindex C-c C-x C-u -@findex org-dblock-update -Update dynamic block at point. point needs to be in the @samp{#+BEGIN} -line of the dynamic block. - -@item @kbd{C-u C-c C-x C-u} (@code{org-update-all-dblocks}) -@kindex C-u C-c C-x C-u -Update all dynamic blocks (see @ref{Dynamic Blocks}). This is useful if -you have several clock table blocks, column-capturing blocks or -other dynamic blocks in a buffer. -@end table - -You can add formulas to the column view table and you may add plotting -instructions in front of the table---these survive an update of the -block. If there is a @samp{TBLFM} keyword after the table, the table is -recalculated automatically after an update. - -An alternative way to capture and process property values into a table -is provided by Eric Schulte's @samp{org-collector.el}, which is -a contributed package@footnote{Contributed packages are not part of Emacs, but are -distributed with the main distribution of Org---visit -@uref{https://orgmode.org}.}. It provides a general API to collect -properties from entries in a certain scope, and arbitrary Lisp -expressions to process these values before inserting them into a table -or a dynamic block. - -@node Dates and Times -@chapter Dates and Times - -@cindex dates -@cindex times -@cindex timestamp -@cindex date stamp - -To assist project planning, TODO items can be labeled with a date -and/or a time. The specially formatted string carrying the date and -time information is called a @emph{timestamp} in Org mode. This may be -a little confusing because timestamp is often used as indicating when -something was created or last changed. However, in Org mode this term -is used in a much wider sense. - -@menu -* Timestamps:: Assigning a time to a tree entry. -* Creating Timestamps:: Commands to insert timestamps. -* Deadlines and Scheduling:: Planning your work. -* Clocking Work Time:: Tracking how long you spend on a task. -* Effort Estimates:: Planning work effort in advance. -* Timers:: Notes with a running timer. -@end menu - -@node Timestamps -@section Timestamps - -@cindex timestamps -@cindex ranges, time -@cindex date stamps -@cindex deadlines -@cindex scheduling - -A timestamp is a specification of a date (possibly with a time or -a range of times) in a special format, either @samp{<2003-09-16 Tue>} or -@samp{<2003-09-16 Tue 09:39>} or @samp{<2003-09-16 Tue 12:00-12:30>}@footnote{The Org date format is inspired by the standard ISO 8601 -date/time format. To use an alternative format, see @ref{Custom time format}. The day name is optional when you type the date yourself. -However, any date inserted or modified by Org adds that day name, for -reading convenience.}. -A timestamp can appear anywhere in the headline or body of an Org tree -entry. Its presence causes entries to be shown on specific dates in -the agenda (see @ref{Weekly/daily agenda}). We distinguish: - -@table @asis -@item Plain timestamp; Event; Appointment -@cindex timestamp -@cindex appointment -A simple timestamp just assigns a date/time to an item. This is -just like writing down an appointment or event in a paper agenda. -In the agenda display, the headline of an entry associated with -a plain timestamp is shown exactly on that date. - -@example -* Meet Peter at the movies - <2006-11-01 Wed 19:15> -* Discussion on climate change - <2006-11-02 Thu 20:00-22:00> -@end example - -@item Timestamp with repeater interval -@cindex timestamp, with repeater interval -A timestamp may contain a @emph{repeater interval}, indicating that it -applies not only on the given date, but again and again after -a certain interval of N days (d), weeks (w), months (m), or years -(y). The following shows up in the agenda every Wednesday: - -@example -* Pick up Sam at school - <2007-05-16 Wed 12:30 +1w> -@end example - -@item Diary-style expression entries -@cindex diary style timestamps -@cindex sexp timestamps -For more complex date specifications, Org mode supports using the -special expression diary entries implemented in the Emacs Calendar -package@footnote{When working with the standard diary expression functions, you -need to be very careful with the order of the arguments. That order -depends evilly on the variable @code{calendar-date-style}. For example, to -specify a date December 12, 2005, the call might look like -@samp{(diary-date 12 1 2005)} or @samp{(diary-date 1 12 2005)} or @samp{(diary-date -2005 12 1)}, depending on the settings. This has been the source of -much confusion. Org mode users can resort to special versions of -these functions like @code{org-date} or @code{org-anniversary}. These work just -like the corresponding @code{diary-} functions, but with stable ISO order -of arguments (year, month, day) wherever applicable, independent of -the value of @code{calendar-date-style}.}. For example, with optional time: - -@example -* 22:00-23:00 The nerd meeting on every 2nd Thursday of the month - <%%(diary-float t 4 2)> -@end example - -@item Time/Date range -@cindex timerange -@cindex date range -Two timestamps connected by @samp{--} denote a range. The headline is -shown on the first and last day of the range, and on any dates that -are displayed and fall in the range. Here is an example: - -@example -** Meeting in Amsterdam - <2004-08-23 Mon>--<2004-08-26 Thu> -@end example - -@item Inactive timestamp -@cindex timestamp, inactive -@cindex inactive timestamp -Just like a plain timestamp, but with square brackets instead of -angular ones. These timestamps are inactive in the sense that they -do @emph{not} trigger an entry to show up in the agenda. - -@example -* Gillian comes late for the fifth time - [2006-11-01 Wed] -@end example -@end table - -@node Creating Timestamps -@section Creating Timestamps - -For Org mode to recognize timestamps, they need to be in the specific -format. All commands listed below produce timestamps in the correct -format. - -@table @asis -@item @kbd{C-c .} (@code{org-time-stamp}) -@kindex C-c . -@findex org-time-stamp -Prompt for a date and insert a corresponding timestamp. When point -is at an existing timestamp in the buffer, the command is used to -modify this timestamp instead of inserting a new one. When this -command is used twice in succession, a time range is inserted. - -@kindex C-u C-c . -@vindex org-time-stamp-rounding-minutes -When called with a prefix argument, use the alternative format which -contains date and time. The default time can be rounded to -multiples of 5 minutes. See the option -@code{org-time-stamp-rounding-minutes}. - -@kindex C-u C-u C-c . -With two prefix arguments, insert an active timestamp with the -current time without prompting. - -@item @kbd{C-c !} (@code{org-time-stamp-inactive}) -@kindex C-c ! -@kindex C-u C-c ! -@kindex C-u C-u C-c ! -@findex org-time-stamp-inactive -Like @kbd{C-c .}, but insert an inactive timestamp that does -not cause an agenda entry. - -@item @kbd{C-c C-c} -@kindex C-c C-c -Normalize timestamp, insert or fix day name if missing or wrong. - -@item @kbd{C-c <} (@code{org-date-from-calendar}) -@kindex C-c < -@findex org-date-from-calendar -Insert a timestamp corresponding to point date in the calendar. - -@item @kbd{C-c >} (@code{org-goto-calendar}) -@kindex C-c > -@findex org-goto-calendar -Access the Emacs calendar for the current date. If there is -a timestamp in the current line, go to the corresponding date -instead. - -@item @kbd{C-c C-o} (@code{org-open-at-point}) -@kindex C-c C-o -@findex org-open-at-point -Access the agenda for the date given by the timestamp or -range at -point (see @ref{Weekly/daily agenda}). - -@item @kbd{S-@key{LEFT}} (@code{org-timestamp-down-day}) -@itemx @kbd{S-@key{RIGHT}} (@code{org-timestamp-up-day}) -@kindex S-LEFT -@kindex S-RIGHT -@findex org-timestamp-down-day -@findex org-timestamp-up-day -Change date at point by one day. These key bindings conflict with -shift-selection and related modes (see @ref{Conflicts}). - -@item @kbd{S-@key{UP}} (@code{org-timestamp-up}) -@itemx @kbd{S-@key{DOWN}} (@code{org-timestamp-down}) -@kindex S-UP -@kindex S-DOWN -On the beginning or enclosing bracket of a timestamp, change its -type. Within a timestamp, change the item under point. Point can -be on a year, month, day, hour or minute. When the timestamp -contains a time range like @samp{15:30-16:30}, modifying the first time -also shifts the second, shifting the time block with constant -length. To change the length, modify the second time. Note that if -point is in a headline and not at a timestamp, these same keys -modify the priority of an item (see @ref{Priorities}). The key bindings -also conflict with shift-selection and related modes (see @ref{Conflicts}). - -@item @kbd{C-c C-y} (@code{org-evaluate-time-range}) -@kindex C-c C-y -@findex org-evaluate-time-range -@cindex evaluate time range -Evaluate a time range by computing the difference between start and -end. With a prefix argument, insert result after the time range (in -a table: into the following column). -@end table - -@menu -* The date/time prompt:: How Org mode helps you enter dates and times. -* Custom time format:: Making dates look different. -@end menu - -@node The date/time prompt -@subsection The date/time prompt - -@cindex date, reading in minibuffer -@cindex time, reading in minibuffer - -@vindex org-read-date-prefer-future -When Org mode prompts for a date/time, the default is shown in default -date/time format, and the prompt therefore seems to ask for a specific -format. But it in fact accepts date/time information in a variety of -formats. Generally, the information should start at the beginning of -the string. Org mode finds whatever information is in there and -derives anything you have not specified from the @emph{default date and -time}. The default is usually the current date and time, but when -modifying an existing timestamp, or when entering the second stamp of -a range, it is taken from the stamp in the buffer. When filling in -information, Org mode assumes that most of the time you want to enter -a date in the future: if you omit the month/year and the given -day/month is @emph{before} today, it assumes that you mean a future -date@footnote{See the variable @code{org-read-date-prefer-future}. You may set -that variable to the symbol @code{time} to even make a time before now -shift the date to tomorrow.}. If the date has been automatically shifted into the -future, the time prompt shows this with @samp{(=>F)}. - -For example, let's assume that today is @strong{June 13, 2006}. Here is how -various inputs are interpreted, the items filled in by Org mode are in -@strong{bold}. - -@multitable {aaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{3-2-5} -@tab @result{} 2003-02-05 -@item @samp{2/5/3} -@tab @result{} 2003-02-05 -@item @samp{14} -@tab @result{} @strong{2006}-@strong{06}-14 -@item @samp{12} -@tab @result{} @strong{2006}-@strong{07}-12 -@item @samp{2/5} -@tab @result{} @strong{2007}-02-05 -@item @samp{Fri} -@tab @result{} nearest Friday (default date or later) -@item @samp{sep 15} -@tab @result{} @strong{2006}-09-15 -@item @samp{feb 15} -@tab @result{} @strong{2007}-02-15 -@item @samp{sep 12 9} -@tab @result{} 2009-09-12 -@item @samp{12:45} -@tab @result{} @strong{2006}-@strong{06}-@strong{13} 12:45 -@item @samp{22 sept 0:34} -@tab @result{} @strong{2006}-09-22 0:34 -@item @samp{w4} -@tab @result{} ISO week for of the current year @strong{2006} -@item @samp{2012 w4 fri} -@tab @result{} Friday of ISO week 4 in 2012 -@item @samp{2012-w04-5} -@tab @result{} Same as above -@end multitable - -Furthermore you can specify a relative date by giving, as the @emph{first} -thing in the input: a plus/minus sign, a number and a letter---@samp{d}, -@samp{w}, @samp{m} or @samp{y}---to indicate change in days, weeks, months, or -years. With a single plus or minus, the date is always relative to -today. With a double plus or minus, it is relative to the default -date. If instead of a single letter, you use the abbreviation of day -name, the date is the Nth such day, e.g.: - -@multitable {aaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{+0} -@tab @result{} today -@item @samp{.} -@tab @result{} today -@item @samp{+4d} -@tab @result{} four days from today -@item @samp{+4} -@tab @result{} same as +4d -@item @samp{+2w} -@tab @result{} two weeks from today -@item @samp{++5} -@tab @result{} five days from default date -@item @samp{+2tue} -@tab @result{} second Tuesday from now -@end multitable - -@vindex parse-time-months -@vindex parse-time-weekdays -The function understands English month and weekday abbreviations. If -you want to use un-abbreviated names and/or other languages, configure -the variables @code{parse-time-months} and @code{parse-time-weekdays}. - -@vindex org-read-date-force-compatible-dates -Not all dates can be represented in a given Emacs implementation. By -default Org mode forces dates into the compatibility range 1970--2037 -which works on all Emacs implementations. If you want to use dates -outside of this range, read the docstring of the variable -@code{org-read-date-force-compatible-dates}. - -You can specify a time range by giving start and end times or by -giving a start time and a duration (in HH:MM format). Use one or two -dash(es) as the separator in the former case and use @samp{+} as the -separator in the latter case, e.g.: - -@multitable {aaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaa} -@item @samp{11am-1:15pm} -@tab @result{} 11:00-13:15 -@item @samp{11am--1:15pm} -@tab @result{} same as above -@item @samp{11am+2:15} -@tab @result{} same as above -@end multitable - -@cindex calendar, for selecting date -@vindex org-popup-calendar-for-date-prompt -Parallel to the minibuffer prompt, a calendar is popped up@footnote{If you do not need/want the calendar, configure the variable -@code{org-popup-calendar-for-date-prompt}.}. -When you exit the date prompt, either by clicking on a date in the -calendar, or by pressing @kbd{@key{RET}}, the date selected in the -calendar is combined with the information entered at the prompt. You -can control the calendar fully from the minibuffer: - -@kindex < -@kindex > -@kindex M-v -@kindex C-v -@kindex mouse-1 -@kindex S-RIGHT -@kindex S-LEFT -@kindex S-DOWN -@kindex S-UP -@kindex M-S-RIGHT -@kindex M-S-LEFT -@kindex RET -@kindex . -@kindex C-. -@multitable @columnfractions 0.25 0.55 -@item @kbd{@key{RET}} -@tab Choose date at point in calendar. -@item @kbd{mouse-1} -@tab Select date by clicking on it. -@item @kbd{S-@key{RIGHT}} -@tab One day forward. -@item @kbd{S-@key{LEFT}} -@tab One day backward. -@item @kbd{S-@key{DOWN}} -@tab One week forward. -@item @kbd{S-@key{UP}} -@tab One week backward. -@item @kbd{M-S-@key{RIGHT}} -@tab One month forward. -@item @kbd{M-S-@key{LEFT}} -@tab One month backward. -@item @kbd{>} -@tab Scroll calendar forward by one month. -@item @kbd{<} -@tab Scroll calendar backward by one month. -@item @kbd{M-v} -@tab Scroll calendar forward by 3 months. -@item @kbd{C-v} -@tab Scroll calendar backward by 3 months. -@item @kbd{C-.} -@tab Select today's date@footnote{You can also use the calendar command @kbd{.} to jump to -today's date, but if you are inserting an hour specification for your -timestamp, @kbd{.} will then insert a dot after the hour. By contrast, -@kbd{C-.} will always jump to today's date.} -@end multitable - -@vindex org-read-date-display-live -The actions of the date/time prompt may seem complex, but I assure you -they will grow on you, and you will start getting annoyed by pretty -much any other way of entering a date/time out there. To help you -understand what is going on, the current interpretation of your input -is displayed live in the minibuffer@footnote{If you find this distracting, turn off the display with -@code{org-read-date-display-live}.}. - -@node Custom time format -@subsection Custom time format - -@cindex custom date/time format -@cindex time format, custom -@cindex date format, custom - -@vindex org-display-custom-times -@vindex org-time-stamp-custom-formats -Org mode uses the standard ISO notation for dates and times as it is -defined in ISO 8601. If you cannot get used to this and require -another representation of date and time to keep you happy, you can get -it by customizing the variables @code{org-display-custom-times} and -@code{org-time-stamp-custom-formats}. - -@table @asis -@item @kbd{C-c C-x C-t} (@code{org-toggle-time-stamp-overlays}) -@kindex C-c C-x C-t -@findex org-toggle-time-stamp-overlays -Toggle the display of custom formats for dates and times. -@end table - -Org mode needs the default format for scanning, so the custom -date/time format does not @emph{replace} the default format. Instead, it -is put @emph{over} the default format using text properties. This has the -following consequences: - -@itemize -@item -You cannot place point onto a timestamp anymore, only before or -after. - -@item -The @kbd{S-@key{UP}} and @kbd{S-@key{DOWN}} keys can no longer be used -to adjust each component of a timestamp. If point is at the -beginning of the stamp, @kbd{S-@key{UP}} and @kbd{S-@key{DOWN}} change -the stamp by one day, just like @kbd{S-@key{LEFT}} -@kbd{S-@key{RIGHT}}. At the end of the stamp, change the time by one -minute. - -@item -If the timestamp contains a range of clock times or a repeater, -these are not overlaid, but remain in the buffer as they were. - -@item -When you delete a timestamp character-by-character, it only -disappears from the buffer after @emph{all} (invisible) characters -belonging to the ISO timestamp have been removed. - -@item -If the custom timestamp format is longer than the default and you -are using dates in tables, table alignment will be messed up. If -the custom format is shorter, things do work as expected. -@end itemize - -@node Deadlines and Scheduling -@section Deadlines and Scheduling - -A timestamp may be preceded by special keywords to facilitate -planning. Both the timestamp and the keyword have to be positioned -immediately after the task they refer to. - -@table @asis -@item @samp{DEADLINE} -@cindex @samp{DEADLINE} marker -Meaning: the task---most likely a TODO item, though not -necessarily---is supposed to be finished on that date. - -@vindex org-deadline-warning-days -On the deadline date, the task is listed in the agenda. In -addition, the agenda for @emph{today} carries a warning about the -approaching or missed deadline, starting @code{org-deadline-warning-days} -before the due date, and continuing until the entry is marked as -done. An example: - -@example -*** TODO write article about the Earth for the Guide - DEADLINE: <2004-02-29 Sun> - The editor in charge is [[bbdb:Ford Prefect]] -@end example - -@vindex org-agenda-skip-deadline-prewarning-if-scheduled -You can specify a different lead time for warnings for a specific -deadlines using the following syntax. Here is an example with -a warning period of 5 days @samp{DEADLINE: <2004-02-29 Sun -5d>}. This -warning is deactivated if the task gets scheduled and you set -@code{org-agenda-skip-deadline-prewarning-if-scheduled} to @code{t}. - -@item @samp{SCHEDULED} -@cindex @samp{SCHEDULED} marker -Meaning: you are planning to start working on that task on the given -date. - -@vindex org-agenda-skip-scheduled-if-done -The headline is listed under the given date@footnote{It will still be listed on that date after it has been marked -as done. If you do not like this, set the variable -@code{org-agenda-skip-scheduled-if-done}.}. In addition, -a reminder that the scheduled date has passed is present in the -compilation for @emph{today}, until the entry is marked as done, i.e., -the task is automatically forwarded until completed. - -@example -*** TODO Call Trillian for a date on New Years Eve. - SCHEDULED: <2004-12-25 Sat> -@end example - -@vindex org-scheduled-delay-days -@vindex org-agenda-skip-scheduled-delay-if-deadline -If you want to @emph{delay} the display of this task in the agenda, use -@samp{SCHEDULED: <2004-12-25 Sat -2d>}: the task is still scheduled on -the 25th but will appear two days later. In case the task contains -a repeater, the delay is considered to affect all occurrences; if -you want the delay to only affect the first scheduled occurrence of -the task, use @samp{--2d} instead. See @code{org-scheduled-delay-days} and -@code{org-agenda-skip-scheduled-delay-if-deadline} for details on how to -control this globally or per agenda. - -@quotation Important -Scheduling an item in Org mode should @emph{not} be understood in the -same way that we understand @emph{scheduling a meeting}. Setting a date -for a meeting is just a simple appointment, you should mark this -entry with a simple plain timestamp, to get this item shown on the -date where it applies. This is a frequent misunderstanding by Org -users. In Org mode, @emph{scheduling} means setting a date when you want -to start working on an action item. - -@end quotation -@end table - -You may use timestamps with repeaters in scheduling and deadline -entries. Org mode issues early and late warnings based on the -assumption that the timestamp represents the @emph{nearest instance} of the -repeater. However, the use of diary expression entries like - -@example -<%%(diary-float t 42)> -@end example - - -@noindent -in scheduling and deadline timestamps is limited. Org mode does not -know enough about the internals of each function to issue early and -late warnings. However, it shows the item on each day where the -expression entry matches. - -@menu -* Inserting deadline/schedule:: Planning items. -* Repeated tasks:: Items that show up again and again. -@end menu - -@node Inserting deadline/schedule -@subsection Inserting deadlines or schedules - -The following commands allow you to quickly insert a deadline or to -schedule an item:@footnote{The @samp{SCHEDULED} and @samp{DEADLINE} dates are inserted on the line -right below the headline. Do not put any text between this line and -the headline.} - -@table @asis -@item @kbd{C-c C-d} (@code{org-deadline}) -@kindex C-c C-d -@findex org-deadline -@vindex org-log-redeadline -Insert @samp{DEADLINE} keyword along with a stamp. The insertion happens -in the line directly following the headline. Remove any @samp{CLOSED} -timestamp . When called with a prefix argument, also remove any -existing deadline from the entry. Depending on the variable -@code{org-log-redeadline}, take a note when changing an existing -deadline@footnote{Note the corresponding @samp{STARTUP} options @samp{logredeadline}, -@samp{lognoteredeadline}, and @samp{nologredeadline}.}. - -@item @kbd{C-c C-s} (@code{org-schedule}) -@kindex C-c C-s -@findex org-schedule -@vindex org-log-reschedule -Insert @samp{SCHEDULED} keyword along with a stamp. The insertion -happens in the line directly following the headline. Remove any -@samp{CLOSED} timestamp. When called with a prefix argument, also remove -the scheduling date from the entry. Depending on the variable -@code{org-log-reschedule}, take a note when changing an existing -scheduling time@footnote{Note the corresponding @samp{STARTUP} options @samp{logreschedule}, -@samp{lognotereschedule}, and @samp{nologreschedule}.}. - -@item @kbd{C-c / d} (@code{org-check-deadlines}) -@kindex C-c / d -@findex org-check-deadlines -@cindex sparse tree, for deadlines -@vindex org-deadline-warning-days -Create a sparse tree with all deadlines that are either past-due, or -which will become due within @code{org-deadline-warning-days}. With -@kbd{C-u} prefix, show all deadlines in the file. With -a numeric prefix, check that many days. For example, @kbd{C-1 C-c / d} shows all deadlines due tomorrow. - -@item @kbd{C-c / b} (@code{org-check-before-date}) -@kindex C-c / b -@findex org-check-before-date -Sparse tree for deadlines and scheduled items before a given date. - -@item @kbd{C-c / a} (@code{org-check-after-date}) -@kindex C-c / a -@findex org-check-after-date -Sparse tree for deadlines and scheduled items after a given date. -@end table - -Note that @code{org-schedule} and @code{org-deadline} supports setting the date -by indicating a relative time e.g., @samp{+1d} sets the date to the next -day after today, and @samp{--1w} sets the date to the previous week before -any current timestamp. - -@node Repeated tasks -@subsection Repeated tasks - -@cindex tasks, repeated -@cindex repeated tasks - -Some tasks need to be repeated again and again. Org mode helps to -organize such tasks using a so-called repeater in a @samp{DEADLINE}, -@samp{SCHEDULED}, or plain timestamps@footnote{Org does not repeat inactive timestamps, however. See -@ref{Timestamps}.}. In the following example: - -@example -** TODO Pay the rent - DEADLINE: <2005-10-01 Sat +1m> -@end example - -@noindent -the @samp{+1m} is a repeater; the intended interpretation is that the task -has a deadline on @samp{<2005-10-01>} and repeats itself every (one) month -starting from that time. You can use yearly, monthly, weekly, daily -and hourly repeat cookies by using the @samp{y}, @samp{m}, @samp{w}, @samp{d} and @samp{h} -letters. If you need both a repeater and a special warning period in -a deadline entry, the repeater should come first and the warning -period last - -@example -DEADLINE: <2005-10-01 Sat +1m -3d> -@end example - - -@vindex org-todo-repeat-to-state -Deadlines and scheduled items produce entries in the agenda when they -are over-due, so it is important to be able to mark such an entry as -done once you have done so. When you mark a @samp{DEADLINE} or -a @samp{SCHEDULED} with the TODO keyword @samp{DONE}, it no longer produces -entries in the agenda. The problem with this is, however, is that -then also the @emph{next} instance of the repeated entry will not be -active. Org mode deals with this in the following way: when you try -to mark such an entry as done, using @kbd{C-c C-t}, it shifts the -base date of the repeating timestamp by the repeater interval, and -immediately sets the entry state back to TODO@footnote{In fact, the target state is taken from, in this sequence, the -@samp{REPEAT_TO_STATE} property, the variable @code{org-todo-repeat-to-state} if -it is a string, the previous TODO state if @code{org-todo-repeat-to-state} -is @code{t}, or the first state of the TODO state sequence.}. In the example -above, setting the state to @samp{DONE} would actually switch the date like -this: - -@example -** TODO Pay the rent - DEADLINE: <2005-11-01 Tue +1m> -@end example - -To mark a task with a repeater as DONE, use @kbd{C-- 1 C-c C-t}, -i.e., @code{org-todo} with a numeric prefix argument of @samp{-1}. - -@vindex org-log-repeat -A timestamp@footnote{You can change this using the option @code{org-log-repeat}, or the -@samp{STARTUP} options @samp{logrepeat}, @samp{lognoterepeat}, and @samp{nologrepeat}. -With @samp{lognoterepeat}, you will also be prompted for a note.} is added under the deadline, to keep a record that -you actually acted on the previous instance of this deadline. - -As a consequence of shifting the base date, this entry is no longer -visible in the agenda when checking past dates, but all future -instances will be visible. - -With the @samp{+1m} cookie, the date shift is always exactly one month. So -if you have not paid the rent for three months, marking this entry -DONE still keeps it as an overdue deadline. Depending on the task, -this may not be the best way to handle it. For example, if you forgot -to call your father for 3 weeks, it does not make sense to call him -3 times in a single day to make up for it. Finally, there are tasks, -like changing batteries, which should always repeat a certain time -@emph{after} the last time you did it. For these tasks, Org mode has -special repeaters @samp{++} and @samp{.+}. For example: - -@example -** TODO Call Father - DEADLINE: <2008-02-10 Sun ++1w> - Marking this DONE shifts the date by at least one week, but also - by as many weeks as it takes to get this date into the future. - However, it stays on a Sunday, even if you called and marked it - done on Saturday. - -** TODO Empty kitchen trash - DEADLINE: <2008-02-08 Fri 20:00 ++1d> - Marking this DONE shifts the date by at least one day, and also - by as many days as it takes to get the timestamp into the future. - Since there is a time in the timestamp, the next deadline in the - future will be on today's date if you complete the task before - 20:00. - -** TODO Check the batteries in the smoke detectors - DEADLINE: <2005-11-01 Tue .+1m> - Marking this DONE shifts the date to one month after today. - -** TODO Wash my hands - DEADLINE: <2019-04-05 08:00 Sun .+1h> - Marking this DONE shifts the date to exactly one hour from now. -@end example - -@vindex org-agenda-skip-scheduled-if-deadline-is-shown -You may have both scheduling and deadline information for a specific -task. If the repeater is set for the scheduling information only, you -probably want the repeater to be ignored after the deadline. If so, -set the variable @code{org-agenda-skip-scheduled-if-deadline-is-shown} to -@code{repeated-after-deadline}. However, any scheduling information -without a repeater is no longer relevant once the task is done, and -thus, removed upon repeating the task. If you want both scheduling -and deadline information to repeat after the same interval, set the -same repeater for both timestamps. - -An alternative to using a repeater is to create a number of copies of -a task subtree, with dates shifted in each copy. The command -@kbd{C-c C-x c} was created for this purpose; it is described in -@ref{Structure Editing}. - -@node Clocking Work Time -@section Clocking Work Time - -@cindex clocking time -@cindex time clocking - -Org mode allows you to clock the time you spend on specific tasks in -a project. When you start working on an item, you can start the -clock. When you stop working on that task, or when you mark the task -done, the clock is stopped and the corresponding time interval is -recorded. It also computes the total time spent on each -subtree@footnote{Clocking only works if all headings are indented with less -than 30 stars. This is a hard-coded limitation of @code{lmax} in -@code{org-clock-sum}.} of a project. And it remembers a history or tasks -recently clocked, so that you can jump quickly between a number of -tasks absorbing your time. - -To save the clock history across Emacs sessions, use: - -@lisp -(setq org-clock-persist 'history) -(org-clock-persistence-insinuate) -@end lisp - -@vindex org-clock-persist -When you clock into a new task after resuming Emacs, the incomplete -clock@footnote{To resume the clock under the assumption that you have worked -on this task while outside Emacs, use @samp{(setq org-clock-persist t)}.} is retrieved (see @ref{Resolving idle time (1)}) and you are -prompted about what to do with it. - -@menu -* Clocking commands:: Starting and stopping a clock. -* The clock table:: Detailed reports. -* Resolving idle time:: Resolving time when you've been idle. -@end menu - -@node Clocking commands -@subsection Clocking commands - -@table @asis -@item @kbd{C-c C-x C-i} (@code{org-clock-in}) -@kindex C-c C-x C-i -@findex org-clock-in -@vindex org-clock-into-drawer -@vindex org-clock-continuously -@cindex @samp{LOG_INTO_DRAWER}, property -Start the clock on the current item (clock-in). This inserts the -@samp{CLOCK} keyword together with a timestamp. If this is not the first -clocking of this item, the multiple @samp{CLOCK} lines are wrapped into -a @samp{LOGBOOK} drawer (see also the variable @code{org-clock-into-drawer}). -You can also overrule the setting of this variable for a subtree by -setting a @samp{CLOCK_INTO_DRAWER} or @samp{LOG_INTO_DRAWER} property. When -called with a @kbd{C-u} prefix argument, select the task from -a list of recently clocked tasks. With two @kbd{C-u C-u} -prefixes, clock into the task at point and mark it as the default -task; the default task is always be available with letter -@kbd{d} when selecting a clocking task. With three @kbd{C-u C-u C-u} prefixes, force continuous clocking by starting the -clock when the last clock stopped. - -@cindex @samp{CLOCK_MODELINE_TOTAL}, property -@cindex @samp{LAST_REPEAT}, property -@vindex org-clock-mode-line-total -@vindex org-clock-in-prepare-hook -While the clock is running, Org shows the current clocking time in -the mode line, along with the title of the task. The clock time -shown is all time ever clocked for this task and its children. If -the task has an effort estimate (see @ref{Effort Estimates}), the mode -line displays the current clocking time against it@footnote{To add an effort estimate ``on the fly'', hook a function doing -this to @code{org-clock-in-prepare-hook}.}. If the -task is a repeating one (see @ref{Repeated tasks}), show only the time -since the last reset of the task@footnote{The last reset of the task is recorded by the @samp{LAST_REPEAT} -property.}. You can exercise more -control over show time with the @samp{CLOCK_MODELINE_TOTAL} property. It -may have the values @samp{current} to show only the current clocking -instance, @samp{today} to show all time clocked on this tasks today---see -also the variable @code{org-extend-today-until}, @code{all} to include all -time, or @code{auto} which is the default@footnote{See also the variable @code{org-clock-mode-line-total}.}. Clicking with -@kbd{mouse-1} onto the mode line entry pops up a menu with -clocking options. - -@item @kbd{C-c C-x C-o} (@code{org-clock-out}) -@kindex C-c C-x C-o -@findex org-clock-out -@vindex org-log-note-clock-out -Stop the clock (clock-out). This inserts another timestamp at the -same location where the clock was last started. It also directly -computes the resulting time in inserts it after the time range as -@samp{=>HH:MM}. See the variable @code{org-log-note-clock-out} for the -possibility to record an additional note together with the clock-out -timestamp@footnote{The corresponding in-buffer setting is: @samp{#+STARTUP: -lognoteclock-out}.}. - -@item @kbd{C-c C-x C-x} (@code{org-clock-in-last}) -@kindex C-c C-x C-x -@findex org-clock-in-last -@vindex org-clock-continuously -Re-clock the last clocked task. With one @kbd{C-u} prefix -argument, select the task from the clock history. With two -@kbd{C-u} prefixes, force continuous clocking by starting the -clock when the last clock stopped. - -@item @kbd{C-c C-x C-e} (@code{org-clock-modify-effort-estimate}) -@kindex C-c C-x C-e -@findex org-clock-modify-effort-estimate -Update the effort estimate for the current clock task. - -@item @kbd{C-c C-c} or @kbd{C-c C-y} (@code{org-evaluate-time-range}) -@kindex C-c C-c -@kindex C-c C-y -@findex org-evaluate-time-range -Recompute the time interval after changing one of the timestamps. -This is only necessary if you edit the timestamps directly. If you -change them with @kbd{S-} keys, the update is -automatic. - -@item @kbd{C-S-@key{UP}} (@code{org-clock-timestamps-up}) -@itemx @kbd{C-S-@key{DOWN}} (@code{org-clock-timestamps-down}) -@kindex C-S-UP -@findex org-clock-timestamps-up -@kindex C-S-DOWN -@findex org-clock-timestamps-down -On CLOCK log lines, increase/decrease both timestamps so that the -clock duration keeps the same value. - -@item @kbd{S-M-@key{UP}} (@code{org-timestamp-up}) -@itemx @kbd{S-M-@key{DOWN}} (@code{org-timestamp-down}) -@kindex S-M-UP -@findex org-clock-timestamp-up -@kindex S-M-DOWN -@findex org-clock-timestamp-down -On @samp{CLOCK} log lines, increase/decrease the timestamp at point and -the one of the previous, or the next, clock timestamp by the same -duration. For example, if you hit @kbd{S-M-@key{UP}} to increase -a clocked-out timestamp by five minutes, then the clocked-in -timestamp of the next clock is increased by five minutes. - -@item @kbd{C-c C-t} (@code{org-todo}) -@kindex C-c C-t -@findex org-todo -Changing the TODO state of an item to DONE automatically stops the -clock if it is running in this same item. - -@item @kbd{C-c C-x C-q} (@code{org-clock-cancel}) -@kindex C-c C-x C-q -@findex org-clock-cancel -Cancel the current clock. This is useful if a clock was started by -mistake, or if you ended up working on something else. - -@item @kbd{C-c C-x C-j} (@code{org-clock-goto}) -@kindex C-c C-x C-j -@findex or-clock-goto -Jump to the headline of the currently clocked in task. With -a @kbd{C-u} prefix argument, select the target task from a list -of recently clocked tasks. - -@item @kbd{C-c C-x C-d} (@code{org-clock-display}) -@kindex C-c C-x C-d -@findex org-clock-display -@vindex org-remove-highlights-with-change -Display time summaries for each subtree in the current buffer. This -puts overlays at the end of each headline, showing the total time -recorded under that heading, including the time of any subheadings. -You can use visibility cycling to study the tree, but the overlays -disappear when you change the buffer (see variable -@code{org-remove-highlights-with-change}) or press @kbd{C-c C-c}. -@end table - -The @kbd{l} key may be used in the agenda (see @ref{Weekly/daily agenda}) to show which tasks have been worked on or closed during -a day. - -@strong{Important:} note that both @code{org-clock-out} and @code{org-clock-in-last} -can have a global keybinding and do not modify the window disposition. - -@node The clock table -@subsection The clock table - -@cindex clocktable, dynamic block -@cindex report, of clocked time - -Org mode can produce quite complex reports based on the time clocking -information. Such a report is called a @emph{clock table}, because it is -formatted as one or several Org tables. - -@table @asis -@item @code{org-clock-report} -@kindex C-c C-x x -@findex org-clock-report -Insert or update a clock table. When called with a prefix argument, -jump to the first clock table in the current document and update it. -The clock table includes archived trees. - -This command can be invoked by calling -@code{org-dynamic-block-insert-dblock} (@kbd{C-c C-x x}) and -selecting ``clocktable'' (see @ref{Dynamic Blocks}). - -@item @kbd{C-c C-c} or @kbd{C-c C-x C-u} (@code{org-dblock-update}) -@kindex C-c C-c -@kindex C-c C-x C-u -@findex org-dblock-update -Update dynamic block at point. Point needs to be in the @samp{BEGIN} -line of the dynamic block. - -@item @kbd{C-u C-c C-x C-u} -@kindex C-u C-c C-x C-u -Update all dynamic blocks (see @ref{Dynamic Blocks}). This is useful if -you have several clock table blocks in a buffer. - -@item @kbd{S-@key{LEFT}} -@itemx @kbd{S-@key{RIGHT}} (@code{org-clocktable-try-shift}) -@kindex S-LEFT -@kindex S-RIGHT -@findex org-clocktable-try-shift -Shift the current @samp{:block} interval and update the table. Point -needs to be in the @samp{#+BEGIN: clocktable} line for this command. If -@samp{:block} is @samp{today}, it is shifted to @samp{today-1}, etc. -@end table - -Here is an example of the frame for a clock table as it is inserted -into the buffer by @code{org-clock-report}: - -@cindex @samp{BEGIN clocktable} -@example -#+BEGIN: clocktable :maxlevel 2 :emphasize nil :scope file -#+END: clocktable -@end example - -@vindex org-clocktable-defaults -The @samp{#+BEGIN} line contains options to define the scope, structure, -and formatting of the report. Defaults for all these options can be -configured in the variable @code{org-clocktable-defaults}. - -First there are options that determine which clock entries are to -be selected: - -@table @asis -@item @samp{:maxlevel} -Maximum level depth to which times are listed in the table. Clocks -at deeper levels are summed into the upper level. - -@item @samp{:scope} -The scope to consider. This can be any of the following: - -@multitable {aaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{nil} -@tab the current buffer or narrowed region -@item @samp{file} -@tab the full current buffer -@item @samp{subtree} -@tab the subtree where the clocktable is located -@item @samp{treeN} -@tab the surrounding level N tree, for example @samp{tree3} -@item @samp{tree} -@tab the surrounding level 1 tree -@item @samp{agenda} -@tab all agenda files -@item @samp{("file" ...)} -@tab scan these files -@item @samp{FUNCTION} -@tab scan files returned by calling @var{FUNCTION} with no argument -@item @samp{file-with-archives} -@tab current file and its archives -@item @samp{agenda-with-archives} -@tab all agenda files, including archives -@end multitable - -@item @samp{:block} -The time block to consider. This block is specified either -absolutely, or relative to the current time and may be any of these -formats: - -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaa} -@item @samp{2007-12-31} -@tab New year eve 2007 -@item @samp{2007-12} -@tab December 2007 -@item @samp{2007-W50} -@tab ISO-week 50 in 2007 -@item @samp{2007-Q2} -@tab 2nd quarter in 2007 -@item @samp{2007} -@tab the year 2007 -@item @samp{today}, @samp{yesterday}, @samp{today-N} -@tab a relative day -@item @samp{thisweek}, @samp{lastweek}, @samp{thisweek-N} -@tab a relative week -@item @samp{thismonth}, @samp{lastmonth}, @samp{thismonth-N} -@tab a relative month -@item @samp{thisyear}, @samp{lastyear}, @samp{thisyear-N} -@tab a relative year -@item @samp{untilnow}@footnote{When using @code{:step}, @code{untilnow} starts from the beginning of -2003, not the beginning of time.} -@tab all clocked time ever -@end multitable - -@vindex org-clock-display-default-range -When this option is not set, Org falls back to the value in -@code{org-clock-display-default-range}, which defaults to the current -year. - -Use @kbd{S-@key{LEFT}} or @kbd{S-@key{RIGHT}} to shift the time -interval. - -@item @samp{:tstart} -A time string specifying when to start considering times. Relative -times like @samp{"<-2w>"} can also be used. See @ref{Matching tags and properties} for relative time syntax. - -@item @samp{:tend} -A time string specifying when to stop considering times. Relative -times like @samp{""} can also be used. See @ref{Matching tags and properties} for relative time syntax. - -@item @samp{:wstart} -The starting day of the week. The default is 1 for Monday. - -@item @samp{:mstart} -The starting day of the month. The default is 1 for the first. - -@item @samp{:step} -Set to @samp{day}, @samp{week}, @samp{semimonth}, @samp{month}, or @samp{year} to split the -table into chunks. To use this, either @samp{:block}, or @samp{:tstart} and -@samp{:tend} are required. - -@item @samp{:stepskip0} -When non-@code{nil}, do not show steps that have zero time. - -@item @samp{:fileskip0} -When non-@code{nil}, do not show table sections from files which did not -contribute. - -@item @samp{:match} -A tags match to select entries that should contribute. See -@ref{Matching tags and properties} for the match syntax. -@end table - -@findex org-clocktable-write-default -Then there are options that determine the formatting of the table. -There options are interpreted by the function -@code{org-clocktable-write-default}, but you can specify your own function -using the @samp{:formatter} parameter. - -@table @asis -@item @samp{:emphasize} -When non-@code{nil}, emphasize level one and level two items. - -@item @samp{:lang} -Language@footnote{Language terms can be set through the variable -@code{org-clock-clocktable-language-setup}.} to use for descriptive cells like ``Task''. - -@item @samp{:link} -Link the item headlines in the table to their origins. - -@item @samp{:narrow} -An integer to limit the width of the headline column in the Org -table. If you write it like @samp{50!}, then the headline is also -shortened in export. - -@item @samp{:indent} -Indent each headline field according to its level. - -@item @samp{:hidefiles} -Hide the file column when multiple files are used to produce the -table. - -@item @samp{:tcolumns} -Number of columns to be used for times. If this is smaller than -@samp{:maxlevel}, lower levels are lumped into one column. - -@item @samp{:level} -Should a level number column be included? - -@item @samp{:sort} -A cons cell containing the column to sort and a sorting type. E.g., -@samp{:sort (1 . ?a)} sorts the first column alphabetically. - -@item @samp{:compact} -Abbreviation for @samp{:level nil :indent t :narrow 40! :tcolumns 1}. -All are overwritten except if there is an explicit @samp{:narrow}. - -@item @samp{:timestamp} -A timestamp for the entry, when available. Look for @samp{SCHEDULED}, -@samp{DEADLINE}, @samp{TIMESTAMP} and @samp{TIMESTAMP_IA} special properties (see -@ref{Special Properties}), in this order. - -@item @samp{:tags} -When this flag is non-@code{nil}, show the headline's tags. - -@item @samp{:properties} -List of properties shown in the table. Each property gets its own -column. - -@item @samp{:inherit-props} -When this flag is non-@code{nil}, the values for @samp{:properties} are -inherited. - -@item @samp{:formula} -Content of a @samp{TBLFM} keyword to be added and evaluated. As -a special case, @samp{:formula %} adds a column with % time. If you do -not specify a formula here, any existing formula below the clock -table survives updates and is evaluated. - -@item @samp{:formatter} -A function to format clock data and insert it into the buffer. -@end table - -To get a clock summary of the current level 1 tree, for the current -day, you could write: - -@example -#+BEGIN: clocktable :maxlevel 2 :block today :scope tree1 :link t -#+END: clocktable -@end example - -@noindent -To use a specific time range you could write@footnote{Note that all parameters must be specified in a single -line---the line is broken here only to fit it into the manual.} - -@example -#+BEGIN: clocktable :tstart "<2006-08-10 Thu 10:00>" - :tend "<2006-08-10 Thu 12:00>" -#+END: clocktable -@end example - -@noindent -A range starting a week ago and ending right now could be written as - -@example -#+BEGIN: clocktable :tstart "<-1w>" :tend "" -#+END: clocktable -@end example - -@noindent -A summary of the current subtree with % times would be - -@example -#+BEGIN: clocktable :scope subtree :link t :formula % -#+END: clocktable -@end example - -@noindent -A horizontally compact representation of everything clocked during -last week would be - -@example -#+BEGIN: clocktable :scope agenda :block lastweek :compact t -#+END: clocktable -@end example - -@node Resolving idle time -@subsection Resolving idle time and continuous clocking - - - -@anchor{Resolving idle time (1)} -@subsubheading Resolving idle time - -@cindex resolve idle time -@cindex idle, resolve, dangling - -If you clock in on a work item, and then walk away from your -computer---perhaps to take a phone call---you often need to -``resolve'' the time you were away by either subtracting it from the -current clock, or applying it to another one. - -@vindex org-clock-idle-time -@vindex org-clock-x11idle-program-name -By customizing the variable @code{org-clock-idle-time} to some integer, -such as 10 or 15, Emacs can alert you when you get back to your -computer after being idle for that many minutes@footnote{On computers using macOS, idleness is based on actual user -idleness, not just Emacs' idle time. For X11, you can install -a utility program @samp{x11idle.c}, available in the @samp{contrib/scripts/} -directory of the Org Git distribution, or install the xprintidle -package and set it to the variable @code{org-clock-x11idle-program-name} if -you are running Debian, to get the same general treatment of idleness. -On other systems, idle time refers to Emacs idle time only.}, and ask what -you want to do with the idle time. There will be a question waiting -for you when you get back, indicating how much idle time has passed -constantly updated with the current amount, as well as a set of -choices to correct the discrepancy: - -@table @asis -@item @kbd{k} -@kindex k -To keep some or all of the minutes and stay clocked in, press -@kbd{k}. Org asks how many of the minutes to keep. Press -@kbd{@key{RET}} to keep them all, effectively changing nothing, or -enter a number to keep that many minutes. - -@item @kbd{K} -@kindex K -If you use the shift key and press @kbd{K}, it keeps however -many minutes you request and then immediately clock out of that -task. If you keep all of the minutes, this is the same as just -clocking out of the current task. - -@item @kbd{s} -@kindex s -To keep none of the minutes, use @kbd{s} to subtract all the -away time from the clock, and then check back in from the moment you -returned. - -@item @kbd{S} -@kindex S -To keep none of the minutes and just clock out at the start of the -away time, use the shift key and press @kbd{S}. Remember that -using shift always leave you clocked out, no matter which option you -choose. - -@item @kbd{C} -@kindex C -To cancel the clock altogether, use @kbd{C}. Note that if -instead of canceling you subtract the away time, and the resulting -clock amount is less than a minute, the clock is still canceled -rather than cluttering up the log with an empty entry. -@end table - -What if you subtracted those away minutes from the current clock, and -now want to apply them to a new clock? Simply clock in to any task -immediately after the subtraction. Org will notice that you have -subtracted time ``on the books'', so to speak, and will ask if you want -to apply those minutes to the next task you clock in on. - -There is one other instance when this clock resolution magic occurs. -Say you were clocked in and hacking away, and suddenly your cat chased -a mouse who scared a hamster that crashed into your UPS's power -button! You suddenly lose all your buffers, but thanks to auto-save -you still have your recent Org mode changes, including your last clock -in. - -If you restart Emacs and clock into any task, Org will notice that you -have a dangling clock which was never clocked out from your last -session. Using that clock's starting time as the beginning of the -unaccounted-for period, Org will ask how you want to resolve that -time. The logic and behavior is identical to dealing with away time -due to idleness; it is just happening due to a recovery event rather -than a set amount of idle time. - -You can also check all the files visited by your Org agenda for -dangling clocks at any time using @kbd{M-x org-resolve-clocks @key{RET}} (or @kbd{C-c C-x C-z}). - -@anchor{Continuous clocking} -@subsubheading Continuous clocking - -@cindex continuous clocking - -@vindex org-clock-continuously -You may want to start clocking from the time when you clocked out the -previous task. To enable this systematically, set -@code{org-clock-continuously} to non-@code{nil}. Each time you clock in, Org -retrieves the clock-out time of the last clocked entry for this -session, and start the new clock from there. - -If you only want this from time to time, use three universal prefix -arguments with @code{org-clock-in} and two @kbd{C-u C-u} with -@code{org-clock-in-last}. - -@anchor{Clocking out automatically after some idle time} -@subsubheading Clocking out automatically after some idle time - -@cindex auto clocking out after idle time - -@vindex org-clock-auto-clockout-timer -When you often forget to clock out before being idle and you don't -want to manually set the clocking time to take into account, you can -set @code{org-clock-auto-clockout-timer} to a number of seconds and add -@samp{(org-clock-auto-clockout-insinuate)} to your @samp{.emacs} file. - -When the clock is running and Emacs is idle for more than this number -of seconds, the clock will be clocked out automatically. - -Use @samp{M-x org-clock-toggle-auto-clockout RET} to temporarily turn this -on or off. - -@node Effort Estimates -@section Effort Estimates - -@cindex effort estimates -@cindex @samp{EFFORT}, property -@vindex org-effort-property - -If you want to plan your work in a very detailed way, or if you need -to produce offers with quotations of the estimated work effort, you -may want to assign effort estimates to entries. If you are also -clocking your work, you may later want to compare the planned effort -with the actual working time, a great way to improve planning -estimates. - -Effort estimates are stored in a special property @samp{EFFORT}. Multiple -formats are supported, such as @samp{3:12}, @samp{1:23:45}, or @samp{1d3h5min}; see -the file @samp{org-duration.el} for more detailed information about the -format. - -You can set the effort for an entry with the following commands: - -@table @asis -@item @kbd{C-c C-x e} (@code{org-set-effort}) -@kindex C-c C-x e -@findex org-set-effort -Set the effort estimate for the current entry. With a prefix -argument, set it to the next allowed value---see below. This -command is also accessible from the agenda with the @kbd{e} -key. - -@item @kbd{C-c C-x C-e} (@code{org-clock-modify-effort-estimate}) -@kindex C-c C-x C-e -@findex org-clock-modify-effort-estimate -Modify the effort estimate of the item currently being clocked. -@end table - -Clearly the best way to work with effort estimates is through column -view (see @ref{Column View}). You should start by setting up discrete -values for effort estimates, and a @samp{COLUMNS} format that displays -these values together with clock sums---if you want to clock your -time. For a specific buffer you can use: - -@example -#+PROPERTY: Effort_ALL 0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00 -#+COLUMNS: %40ITEM(Task) %17Effort(Estimated Effort)@{:@} %CLOCKSUM -@end example - -@noindent -@vindex org-global-properties -@vindex org-columns-default-format -or, even better, you can set up these values globally by customizing -the variables @code{org-global-properties} and -@code{org-columns-default-format}. In particular if you want to use this -setup also in the agenda, a global setup may be advised. - -The way to assign estimates to individual items is then to switch to -column mode, and to use @kbd{S-@key{RIGHT}} and @kbd{S-@key{LEFT}} to -change the value. The values you enter are immediately summed up in -the hierarchy. In the column next to it, any clocked time is -displayed. - -@vindex org-agenda-columns-add-appointments-to-effort-sum -If you switch to column view in the daily/weekly agenda, the effort -column summarizes the estimated work effort for each day@footnote{Please note the pitfalls of summing hierarchical data in -a flat list (see @ref{Agenda Column View}).}, and -you can use this to find space in your schedule. To get an overview -of the entire part of the day that is committed, you can set the -option @code{org-agenda-columns-add-appointments-to-effort-sum}. The -appointments on a day that take place over a specified time interval -are then also added to the load estimate of the day. - -Effort estimates can be used in secondary agenda filtering that is -triggered with the @kbd{/} key in the agenda (see @ref{Agenda Commands}). If you have these estimates defined consistently, -two or three key presses narrow down the list to stuff that fits into -an available time slot. - -@node Timers -@section Taking Notes with a Relative Timer - -@cindex relative timer -@cindex countdown timer - -Org provides two types of timers. There is a relative timer that -counts up, which can be useful when taking notes during, for example, -a meeting or a video viewing. There is also a countdown timer. - -The relative and countdown are started with separate commands. - -@table @asis -@item @kbd{C-c C-x 0} (@code{org-timer-start}) -@kindex C-c C-x 0 -@findex org-timer-start -Start or reset the relative timer. By default, the timer is set -to 0. When called with a @kbd{C-u} prefix, prompt the user for -a starting offset. If there is a timer string at point, this is -taken as the default, providing a convenient way to restart taking -notes after a break in the process. When called with a double -prefix argument @kbd{C-u C-u}, change all timer strings in the -active region by a certain amount. This can be used to fix timer -strings if the timer was not started at exactly the right moment. - -@item @kbd{C-c C-x ;} (@code{org-timer-set-timer}) -@kindex C-c C-x ; -@findex org-timer-set-timer -@vindex org-timer-default-timer -Start a countdown timer. The user is prompted for a duration. -@code{org-timer-default-timer} sets the default countdown value. Giving -a numeric prefix argument overrides this default value. This -command is available as @kbd{;} in agenda buffers. -@end table - -Once started, relative and countdown timers are controlled with the -same commands. - -@table @asis -@item @kbd{C-c C-x .} (@code{org-timer}) -@kindex C-c C-x . -@findex org-timer -Insert a relative time into the buffer. The first time you use -this, the timer starts. Using a prefix argument restarts it. - -@item @kbd{C-c C-x -} (@code{org-timer-item}) -@kindex C-c C-x - -@findex org-timer-item -Insert a description list item with the current relative time. With -a prefix argument, first reset the timer to 0. - -@item @kbd{M-@key{RET}} (@code{org-insert-heading}) -@kindex M-RET -@findex org-insert-heading -Once the timer list is started, you can also use @kbd{M-@key{RET}} to -insert new timer items. - -@item @kbd{C-c C-x ,} (@code{org-timer-pause-or-continue}) -@kindex C-c C-x , -@findex org-timer-pause-or-continue -Pause the timer, or continue it if it is already paused. - -@item @kbd{C-c C-x _} (@code{org-timer-stop}) -@kindex C-c C-x _ -@findex org-timer-stop -Stop the timer. After this, you can only start a new timer, not -continue the old one. This command also removes the timer from the -mode line. -@end table - -@node Refiling and Archiving -@chapter Refiling and Archiving - -@cindex refiling notes -@cindex copying notes -@cindex archiving - -Once information is in the system, it may need to be moved around. -Org provides Refile, Copy and Archive commands for this. Refile and -Copy helps with moving and copying outlines. Archiving helps to keep -the system compact and fast. - -@menu -* Refile and Copy:: Moving/copying a tree from one place to another. -* Archiving:: What to do with finished products. -@end menu - -@node Refile and Copy -@section Refile and Copy - -@cindex refiling notes -@cindex copying notes - -When reviewing the captured data, you may want to refile or to copy -some of the entries into a different list, for example into a project. -Cutting, finding the right location, and then pasting the note is -cumbersome. To simplify this process, you can use the following -special command: - -@table @asis -@item @kbd{C-c C-w} (@code{org-refile}) -@kindex C-c C-w -@findex org-refile -@vindex org-reverse-note-order -@vindex org-refile-targets -@vindex org-refile-use-outline-path -@vindex org-outline-path-complete-in-steps -@vindex org-refile-allow-creating-parent-nodes -@vindex org-log-refile -Refile the entry or region at point. This command offers possible -locations for refiling the entry and lets you select one with -completion. The item (or all items in the region) is filed below -the target heading as a subitem. Depending on -@code{org-reverse-note-order}, it is either the first or last subitem. - -By default, all level 1 headlines in the current buffer are -considered to be targets, but you can have more complex definitions -across a number of files. See the variable @code{org-refile-targets} for -details. If you would like to select a location via -a file-path-like completion along the outline path, see the -variables @code{org-refile-use-outline-path} and -@code{org-outline-path-complete-in-steps}. If you would like to be able -to create new nodes as new parents for refiling on the fly, check -the variable @code{org-refile-allow-creating-parent-nodes}. When the -variable @code{org-log-refile}@footnote{Note the corresponding @samp{STARTUP} options @samp{logrefile}, -@samp{lognoterefile}, and @samp{nologrefile}.} is set, a timestamp or a note is -recorded whenever an entry is refiled. - -@item @kbd{C-u C-c C-w} -@kindex C-u C-c C-w -Use the refile interface to jump to a heading. - -@item @kbd{C-u C-u C-c C-w} (@code{org-refile-goto-last-stored}) -@kindex C-u C-u C-c C-w -@findex org-refile-goto-last-stored -Jump to the location where @code{org-refile} last moved a tree to. - -@item @kbd{C-2 C-c C-w} -@kindex C-2 C-c C-w -Refile as the child of the item currently being clocked. - -@item @kbd{C-3 C-c C-w} -@kindex C-3 C-c C-w -@vindex org-refile-keep -Refile and keep the entry in place. Also see @code{org-refile-keep} to -make this the default behavior, and beware that this may result in -duplicated @samp{ID} properties. - -@item @kbd{C-0 C-c C-w} or @kbd{C-u C-u C-u C-c C-w} (@code{org-refile-cache-clear}) -@kindex C-u C-u C-u C-c C-w -@kindex C-0 C-c C-w -@findex org-refile-cache-clear -@vindex org-refile-use-cache -Clear the target cache. Caching of refile targets can be turned on -by setting @code{org-refile-use-cache}. To make the command see new -possible targets, you have to clear the cache with this command. - -@item @kbd{C-c M-w} (@code{org-refile-copy}) -@kindex C-c M-w -@findex org-refile-copy -Copying works like refiling, except that the original note is not -deleted. -@end table - -@node Archiving -@section Archiving - -@cindex archiving - -When a project represented by a (sub)tree is finished, you may want to -move the tree out of the way and to stop it from contributing to the -agenda. Archiving is important to keep your working files compact and -global searches like the construction of agenda views fast. - -@table @asis -@item @kbd{C-c C-x C-a} (@code{org-archive-subtree-default}) -@kindex C-c C-x C-a -@findex org-archive-subtree-default -@vindex org-archive-default-command -Archive the current entry using the command specified in the -variable @code{org-archive-default-command}. -@end table - -@menu -* Moving subtrees:: Moving a tree to an archive file. -* Internal archiving:: Switch off a tree but keep it in the file. -@end menu - -@node Moving subtrees -@subsection Moving a tree to an archive file - -@cindex external archiving - -The most common archiving action is to move a project tree to another -file, the archive file. - -@table @asis -@item @kbd{C-c C-x C-s} or short @kbd{C-c $} (@code{org-archive-subtree}) -@kindex C-c C-x C-s -@kindex C-c $ -@findex org-archive-subtree -@vindex org-archive-location -Archive the subtree starting at point position to the location given -by @code{org-archive-location}. - -@item @kbd{C-u C-c C-x C-s} -@kindex C-u C-c C-x C-s -Check if any direct children of the current headline could be moved -to the archive. To do this, check each subtree for open TODO -entries. If none is found, the command offers to move it to the -archive location. If point is @emph{not} on a headline when this command -is invoked, check level 1 trees. - -@item @kbd{C-u C-u C-c C-x C-s} -@kindex C-u C-u C-c C-x C-s -As above, but check subtree for timestamps instead of TODO entries. -The command offers to archive the subtree if it @emph{does} contain -a timestamp, and that timestamp is in the past. -@end table - -@cindex archive locations -The default archive location is a file in the same directory as the -current file, with the name derived by appending @samp{_archive} to the -current file name. You can also choose what heading to file archived -items under, with the possibility to add them to a datetree in a file. -For information and examples on how to specify the file and the -heading, see the documentation string of the variable -@code{org-archive-location}. - -There is also an in-buffer option for setting this variable, for -example: - -@cindex @samp{ARCHIVE}, keyword -@example -#+ARCHIVE: %s_done:: -@end example - - -@cindex ARCHIVE, property -If you would like to have a special archive location for a single -entry or a (sub)tree, give the entry an @samp{ARCHIVE} property with the -location as the value (see @ref{Properties and Columns}). - -@vindex org-archive-save-context-info -When a subtree is moved, it receives a number of special properties -that record context information like the file from where the entry -came, its outline path the archiving time etc. Configure the variable -@code{org-archive-save-context-info} to adjust the amount of information -added. - -@vindex org-archive-subtree-save-file-p -When @code{org-archive-subtree-save-file-p} is non-@code{nil}, save the target -archive buffer. - -@node Internal archiving -@subsection Internal archiving - -@cindex @samp{ARCHIVE}, tag -If you want to just switch off---for agenda views---certain subtrees -without moving them to a different file, you can use the @samp{ARCHIVE} -tag. - -A headline that is marked with the @samp{ARCHIVE} tag (see @ref{Tags}) stays at -its location in the outline tree, but behaves in the following way: - -@itemize -@item -@vindex org-cycle-open-archived-trees -It does not open when you attempt to do so with a visibility cycling -command (see @ref{Visibility Cycling}). You can force cycling archived -subtrees with @kbd{C-@key{TAB}}, or by setting the option -@code{org-cycle-open-archived-trees}. Also normal outline commands, like -@code{outline-show-all}, open archived subtrees. - -@item -@vindex org-sparse-tree-open-archived-trees -During sparse tree construction (see @ref{Sparse Trees}), matches in -archived subtrees are not exposed, unless you configure the option -@code{org-sparse-tree-open-archived-trees}. - -@item -@vindex org-agenda-skip-archived-trees -During agenda view construction (see @ref{Agenda Views}), the content of -archived trees is ignored unless you configure the option -@code{org-agenda-skip-archived-trees}, in which case these trees are -always included. In the agenda you can press @kbd{v a} to get -archives temporarily included. - -@item -@vindex org-export-with-archived-trees -Archived trees are not exported (see @ref{Exporting}), only the headline -is. Configure the details using the variable -@code{org-export-with-archived-trees}. - -@item -@vindex org-columns-skip-archived-trees -Archived trees are excluded from column view unless the variable -@code{org-columns-skip-archived-trees} is configured to @code{nil}. -@end itemize - -The following commands help manage the @samp{ARCHIVE} tag: - -@table @asis -@item @kbd{C-c C-x a} (@code{org-toggle-archive-tag}) -@kindex C-c C-x a -@findex org-toggle-archive-tag -Toggle the archive tag for the current headline. When the tag is -set, the headline changes to a shadowed face, and the subtree below -it is hidden. - -@item @kbd{C-u C-c C-x a} -@kindex C-u C-c C-x a -Check if any direct children of the current headline should be -archived. To do this, check each subtree for open TODO entries. If -none is found, the command offers to set the @samp{ARCHIVE} tag for the -child. If point is @emph{not} on a headline when this command is -invoked, check the level 1 trees. - -@item @kbd{C-c C-@key{TAB}} (@code{org-force-cycle-archived}) -@kindex C-TAB -Cycle a tree even if it is tagged with @samp{ARCHIVE}. - -@item @kbd{C-c C-x A} (@code{org-archive-to-archive-sibling}) -@kindex C-c C-x A -@findex org-archive-to-archive-sibling -Move the current entry to the @emph{Archive Sibling}. This is a sibling -of the entry with the heading @samp{Archive} and the archive tag. The -entry becomes a child of that sibling and in this way retains a lot -of its original context, including inherited tags and approximate -position in the outline. -@end table - -@node Capture and Attachments -@chapter Capture and Attachments - -@cindex capture -@cindex attachments -@cindex RSS feeds -@cindex Atom feeds -@cindex protocols, for external access - -An important part of any organization system is the ability to quickly -capture new ideas and tasks, and to associate reference material with -them. Org does this using a process called @emph{capture}. It also can -store files related to a task (@emph{attachments}) in a special directory. -Finally, it can parse RSS feeds for information. To learn how to let -external programs (for example a web browser) trigger Org to capture -material, see @ref{Protocols}. - -@menu -* Capture:: Capturing new stuff. -* Attachments:: Attach files to outlines. -* RSS Feeds:: Getting input from RSS feeds. -@end menu - -@node Capture -@section Capture - -@cindex capture - -Capture lets you quickly store notes with little interruption of your -work flow. Org's method for capturing new items is heavily inspired -by John Wiegley's excellent Remember package. - -@menu -* Setting up capture:: Where notes will be stored. -* Using capture:: Commands to invoke and terminate capture. -* Capture templates:: Define the outline of different note types. -@end menu - -@node Setting up capture -@subsection Setting up capture - -The following customization sets a default target file for notes. - -@vindex org-default-notes-file -@lisp -(setq org-default-notes-file (concat org-directory "/notes.org")) -@end lisp - -You may also define a global key for capturing new material (see -@ref{Activation}). - -@node Using capture -@subsection Using capture - -@table @asis -@item @kbd{M-x org-capture} (@code{org-capture}) -@findex org-capture -@cindex date tree -Display the capture templates menu. If you have templates defined -(see @ref{Capture templates}), it offers these templates for selection or -use a new Org outline node as the default template. It inserts the -template into the target file and switch to an indirect buffer -narrowed to this new node. You may then insert the information you -want. - -@item @kbd{C-c C-c} (@code{org-capture-finalize}) -@kindex C-c C-c @r{(Capture buffer)} -@findex org-capture-finalize -Once you have finished entering information into the capture buffer, -@kbd{C-c C-c} returns you to the window configuration before -the capture process, so that you can resume your work without -further distraction. When called with a prefix argument, finalize -and then jump to the captured item. - -@item @kbd{C-c C-w} (@code{org-capture-refile}) -@kindex C-c C-w @r{(Capture buffer)} -@findex org-capture-refile -Finalize the capture process by refiling the note to a different -place (see @ref{Refile and Copy}). Please realize that this is a normal -refiling command that will be executed---so point position at the -moment you run this command is important. If you have inserted -a tree with a parent and children, first move point back to the -parent. Any prefix argument given to this command is passed on to -the @code{org-refile} command. - -@item @kbd{C-c C-k} (@code{org-capture-kill}) -@kindex C-c C-k @r{(Capture buffer)} -@findex org-capture-kill -Abort the capture process and return to the previous state. -@end table - -@kindex k c @r{(Agenda)} -You can also call @code{org-capture} in a special way from the agenda, -using the @kbd{k c} key combination. With this access, any -timestamps inserted by the selected capture template defaults to the -date at point in the agenda, rather than to the current date. - -To find the locations of the last stored capture, use @code{org-capture} -with prefix commands: - -@table @asis -@item @kbd{C-u M-x org-capture} -Visit the target location of a capture template. You get to select -the template in the usual way. - -@item @kbd{C-u C-u M-x org-capture} -Visit the last stored capture item in its buffer. -@end table - -@vindex org-capture-bookmark -@vindex org-capture-last-stored -You can also jump to the bookmark @code{org-capture-last-stored}, which is -automatically created unless you set @code{org-capture-bookmark} to @code{nil}. - -To insert the capture at point in an Org buffer, call @code{org-capture} -with a @kbd{C-0} prefix argument. - -@node Capture templates -@subsection Capture templates - -@cindex templates, for Capture - -You can use templates for different types of capture items, and for -different target locations. The easiest way to create such templates -is through the customize interface. - -@table @asis -@item @kbd{C} -@kindex C @r{(Capture menu} -@vindex org-capture-templates -Customize the variable @code{org-capture-templates}. -@end table - -Before we give the formal description of template definitions, let's -look at an example. Say you would like to use one template to create -general TODO entries, and you want to put these entries under the -heading @samp{Tasks} in your file @samp{~/org/gtd.org}. Also, a date tree in -the file @samp{journal.org} should capture journal entries. A possible -configuration would look like: - -@lisp -(setq org-capture-templates - '(("t" "Todo" entry (file+headline "~/org/gtd.org" "Tasks") - "* TODO %?\n %i\n %a") - ("j" "Journal" entry (file+datetree "~/org/journal.org") - "* %?\nEntered on %U\n %i\n %a"))) -@end lisp - -If you then press @kbd{t} from the capture menu, Org will prepare -the template for you like this: - -@example -* TODO - [[file:LINK TO WHERE YOU INITIATED CAPTURE]] -@end example - -@noindent -During expansion of the template, @samp{%a} has been replaced by a link to -the location from where you called the capture command. This can be -extremely useful for deriving tasks from emails, for example. You -fill in the task definition, press @kbd{C-c C-c} and Org returns -you to the same place where you started the capture process. - -To define special keys to capture to a particular template without -going through the interactive template selection, you can create your -key binding like this: - -@lisp -(define-key global-map (kbd "C-c x") - (lambda () (interactive) (org-capture nil "x"))) -@end lisp - -@menu -* Template elements:: What is needed for a complete template entry. -* Template expansion:: Filling in information about time and context. -* Templates in contexts:: Only show a template in a specific context. -@end menu - -@node Template elements -@subsubsection Template elements - -Now lets look at the elements of a template definition. Each entry in -@code{org-capture-templates} is a list with the following items: - -@table @asis -@item keys -The keys that selects the template, as a string, characters only, -for example @samp{"a"}, for a template to be selected with a single key, -or @samp{"bt"} for selection with two keys. When using several keys, -keys using the same prefix key must be sequential in the list and -preceded by a 2-element entry explaining the prefix key, for -example: - -@lisp -("b" "Templates for marking stuff to buy") -@end lisp - -If you do not define a template for the @kbd{C} key, this key -opens the Customize buffer for this complex variable. - -@item description -A short string describing the template, shown during selection. - -@item type -The type of entry, a symbol. Valid values are: - -@table @asis -@item @code{entry} -An Org mode node, with a headline. Will be filed as the child of -the target entry or as a top-level entry. The target file should -be an Org file. - -@item @code{item} -A plain list item, placed in the first plain list at the target -location. Again the target file should be an Org file. - -@item @code{checkitem} -A checkbox item. This only differs from the plain list item by -the default template. - -@item @code{table-line} -A new line in the first table at the target location. Where -exactly the line will be inserted depends on the properties -@code{:prepend} and @code{:table-line-pos} (see below). - -@item @code{plain} -Text to be inserted as it is. -@end table - -@item target -@vindex org-default-notes-file -@vindex org-directory -Specification of where the captured item should be placed. In Org -files, targets usually define a node. Entries will become children -of this node. Other types will be added to the table or list in the -body of this node. Most target specifications contain a file name. -If that file name is the empty string, it defaults to -@code{org-default-notes-file}. A file can also be given as a variable or -as a function called with no argument. When an absolute path is not -specified for a target, it is taken as relative to @code{org-directory}. - -Valid values are: - -@table @asis -@item @samp{(file "path/to/file")} -Text will be placed at the beginning or end of that file. - -@item @samp{(id "id of existing org entry")} -Filing as child of this entry, or in the body of the entry. - -@item @samp{(file+headline "filename" "node headline")} -Fast configuration if the target heading is unique in the file. - -@item @samp{(file+olp "filename" "Level 1 heading" "Level 2" ...)} -For non-unique headings, the full path is safer. - -@item @samp{(file+regexp "filename" "regexp to find location")} -Use a regular expression to position point. - -@item @samp{(file+olp+datetree "filename" [ "Level 1 heading" ...])} -This target@footnote{Org used to offer four different targets for date/week tree -capture. Now, Org automatically translates these to use -@code{file+olp+datetree}, applying the @code{:time-prompt} and @code{:tree-type} -properties. Please rewrite your date/week-tree targets using -@code{file+olp+datetree} since the older targets are now deprecated.} creates a heading in a date tree@footnote{A date tree is an outline structure with years on the highest -level, months or ISO weeks as sublevels and then dates on the lowest -level. Tags are allowed in the tree structure.} for -today's date. If the optional outline path is given, the tree -will be built under the node it is pointing to, instead of at top -level. Check out the @code{:time-prompt} and @code{:tree-type} properties -below for additional options. - -@item @samp{(file+function "filename" function-finding-location)} -A function to find the right location in the file. - -@item @samp{(clock)} -File to the entry that is currently being clocked. - -@item @samp{(function function-finding-location)} -Most general way: write your own function which both visits the -file and moves point to the right location. -@end table - -@item template -The template for creating the capture item. If you leave this -empty, an appropriate default template will be used. Otherwise this -is a string with escape codes, which will be replaced depending on -time and context of the capture call. You may also get this -template string from a file@footnote{When the file name is not absolute, Org assumes it is relative -to @code{org-directory}.}, or dynamically, from a function -using either syntax: - -@example -(file "/path/to/template-file") -(function FUNCTION-RETURNING-THE-TEMPLATE) -@end example - -@item properties -The rest of the entry is a property list of additional options. -Recognized properties are: - -@table @asis -@item @code{:prepend} -Normally new captured information will be appended at the target -location (last child, last table line, last list item, @dots{}). -Setting this property changes that. - -@item @code{:immediate-finish} -When set, do not offer to edit the information, just file it away -immediately. This makes sense if the template only needs -information that can be added automatically. - -@item @code{:jump-to-captured} -When set, jump to the captured entry when finished. - -@item @code{:empty-lines} -Set this to the number of lines to insert before and after the new -item. Default 0, and the only other common value is 1. - -@item @code{:empty-lines-after} -Set this to the number of lines that should be inserted after the -new item. Overrides @code{:empty-lines} for the number of lines -inserted after. - -@item @code{:empty-lines-before} -Set this to the number of lines that should be inserted before the -new item. Overrides @code{:empty-lines} for the number lines inserted -before. - -@item @code{:clock-in} -Start the clock in this item. - -@item @code{:clock-keep} -Keep the clock running when filing the captured entry. - -@item @code{:clock-resume} -If starting the capture interrupted a clock, restart that clock -when finished with the capture. Note that @code{:clock-keep} has -precedence over @code{:clock-resume}. When setting both to non-@code{nil}, -the current clock will run and the previous one will not be -resumed. - -@item @code{:time-prompt} -Prompt for a date/time to be used for date/week trees and when -filling the template. Without this property, capture uses the -current date and time. Even if this property has not been set, -you can force the same behavior by calling @code{org-capture} with -a @kbd{C-1} prefix argument. - -@item @code{:tree-type} -Use @code{week} to make a week tree instead of the month-day tree, -i.e., place the headings for each day under a heading with the -current ISO week. Use @code{month} to group entries by month -only. Default is to group entries by day. - -@item @code{:unnarrowed} -Do not narrow the target buffer, simply show the full buffer. -Default is to narrow it so that you only see the new material. - -@item @code{:table-line-pos} -Specification of the location in the table where the new line -should be inserted. It should be a string like @samp{II-3} meaning -that the new line should become the third line before the second -horizontal separator line. - -@item @code{:kill-buffer} -If the target file was not yet visited when capture was invoked, -kill the buffer again after capture is completed. - -@item @code{:no-save} -Do not save the target file after finishing the capture. -@end table -@end table - -@node Template expansion -@subsubsection Template expansion - -In the template itself, special ``%-escapes''@footnote{If you need one of these sequences literally, escape the @samp{%} -with a backslash.} allow dynamic -insertion of content. The templates are expanded in the order given -here: - -@table @asis -@item @samp{%[FILE]} -Insert the contents of the file given by @var{FILE}. - -@item @samp{%(EXP)} -Evaluate Elisp expression @var{EXP} and replace it with the -result. The @var{EXP} form must return a string. Only -placeholders pre-existing within the template, or introduced with -@samp{%[file]}, are expanded this way. Since this happens after -expanding non-interactive ``%-escapes'', those can be used to fill the -expression. - -@item @samp{%} -The result of format-time-string on the @var{FORMAT} -specification. - -@item @samp{%t} -Timestamp, date only. - -@item @samp{%T} -Timestamp, with date and time. - -@item @samp{%u}, @samp{%U} -Like @samp{%t}, @samp{%T} above, but inactive timestamps. - -@item @samp{%i} -Initial content, the region when capture is called while the region -is active. If there is text before @samp{%i} on the same line, such as -indentation, and @samp{%i} is not inside a @samp{%(exp)} form, that prefix is -added before every line in the inserted text. - -@item @samp{%a} -Annotation, normally the link created with @code{org-store-link}. - -@item @samp{%A} -Like @samp{%a}, but prompt for the description part. - -@item @samp{%l} -Like @samp{%a}, but only insert the literal link. - -@item @samp{%c} -Current kill ring head. - -@item @samp{%x} -Content of the X clipboard. - -@item @samp{%k} -Title of the currently clocked task. - -@item @samp{%K} -Link to the currently clocked task. - -@item @samp{%n} -User name (taken from @code{user-full-name}). - -@item @samp{%f} -File visited by current buffer when org-capture was called. - -@item @samp{%F} -Full path of the file or directory visited by current buffer. - -@item @samp{%:keyword} -Specific information for certain link types, see below. - -@item @samp{%^g} -Prompt for tags, with completion on tags in target file. - -@item @samp{%^G} -Prompt for tags, with completion all tags in all agenda files. - -@item @samp{%^t} -Like @samp{%t}, but prompt for date. Similarly @samp{%^T}, @samp{%^u}, @samp{%^U}. You -may define a prompt like @samp{%^@{Birthday@}t}. - -@item @samp{%^C} -Interactive selection of which kill or clip to use. - -@item @samp{%^L} -Like @samp{%^C}, but insert as link. - -@item @samp{%^@{PROP@}p} -Prompt the user for a value for property @var{PROP}. - -@item @samp{%^@{PROMPT@}} -Prompt the user for a string and replace this sequence with it. You -may specify a default value and a completion table with -@samp{%^@{prompt|default|completion2|completion3...@}}. The arrow keys -access a prompt-specific history. - -@item @samp{%\N} -Insert the text entered at the @var{N}th @samp{%^@{PROMPT@}}, where -@var{N} is a number, starting from 1. - -@item @samp{%?} -After completing the template, position point here. -@end table - -@vindex org-store-link-props -For specific link types, the following keywords are defined@footnote{If you define your own link types (see @ref{Adding Hyperlink Types}), any property you store with @code{org-store-link-props} can be -accessed in capture templates in a similar way.}: - -@vindex org-link-from-user-regexp -@multitable {aaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@headitem Link type -@tab Available keywords -@item bbdb -@tab @samp{%:name}, @samp{%:company} -@item irc -@tab @samp{%:server}, @samp{%:port}, @samp{%:nick} -@item mh, rmail -@tab @samp{%:type}, @samp{%:subject}, @samp{%:message-id} -@item -@tab @samp{%:from}, @samp{%:fromname}, @samp{%:fromaddress} -@item -@tab @samp{%:to}, @samp{%:toname}, @samp{%:toaddress} -@item -@tab @samp{%:date} (message date header field) -@item -@tab @samp{%:date-timestamp} (date as active timestamp) -@item -@tab @samp{%:date-timestamp-inactive} (date as inactive timestamp) -@item -@tab @samp{%:fromto} (either ``to NAME'' or ``from NAME'')@footnote{This is always the other, not the user. See the variable -@code{org-link-from-user-regexp}.} -@item gnus -@tab @samp{%:group}, for messages also all email fields -@item w3, w3m -@tab @samp{%:url} -@item info -@tab @samp{%:file}, @samp{%:node} -@item calendar -@tab @samp{%:date} -@item org-protocol -@tab @samp{%:link}, @samp{%:description}, @samp{%:annotation} -@end multitable - -@node Templates in contexts -@subsubsection Templates in contexts - -@vindex org-capture-templates-contexts -To control whether a capture template should be accessible from -a specific context, you can customize -@code{org-capture-templates-contexts}. Let's say, for example, that you -have a capture template ``p'' for storing Gnus emails containing -patches. Then you would configure this option like this: - -@lisp -(setq org-capture-templates-contexts - '(("p" (in-mode . "message-mode")))) -@end lisp - -You can also tell that the command key @kbd{p} should refer to -another template. In that case, add this command key like this: - -@lisp -(setq org-capture-templates-contexts - '(("p" "q" (in-mode . "message-mode")))) -@end lisp - -See the docstring of the variable for more information. - -@node Attachments -@section Attachments - -@cindex attachments - -It is often useful to associate reference material with an outline -node. Small chunks of plain text can simply be stored in the subtree -of a project. Hyperlinks (see @ref{Hyperlinks}) can establish associations -with files that live elsewhere on a local, or even remote, computer, -like emails or source code files belonging to a project. - -Another method is @emph{attachments}, which are files located in a -directory belonging to an outline node. Org uses directories either -named by a unique ID of each entry, or by a @samp{DIR} property. - -@menu -* Attachment defaults and dispatcher:: How to access attachment commands -* Attachment options:: Configuring the attachment system -* Attachment links:: Hyperlink access to attachments -* Automatic version-control with Git:: Everything safely stored away -* Attach from Dired:: Using dired to select an attachment -@end menu - -@node Attachment defaults and dispatcher -@subsection Attachment defaults and dispatcher - -By default, Org attach uses ID properties when adding attachments to -outline nodes. This makes working with attachments fully automated. -There is no decision needed for folder-name or location. ID-based -directories are by default located in the @samp{data/} directory, which -lives in the same directory where your Org file lives@footnote{If you move entries or Org files from one directory to -another, you may want to configure @code{org-attach-id-dir} to contain -an absolute path.}. - -When attachments are made using @code{org-attach} a default tag @samp{ATTACH} is -added to the node that gets the attachments. - -For more control over the setup, see @ref{Attachment options}. - -The following commands deal with attachments: - -@table @asis -@item @kbd{C-c C-a} (@code{org-attach}) -@kindex C-c C-a -@findex org-attach -The dispatcher for commands related to the attachment system. After -these keys, a list of commands is displayed and you must press an -additional key to select a command: - -@table @asis -@item @kbd{a} (@code{org-attach-attach}) -@kindex C-c C-a a -@findex org-attach-attach -@vindex org-attach-method -Select a file and move it into the task's attachment directory. -The file is copied, moved, or linked, depending on -@code{org-attach-method}. Note that hard links are not supported on -all systems. - -@item @kbd{c}/@kbd{m}/@kbd{l} -@kindex C-c C-a c -@kindex C-c C-a m -@kindex C-c C-a l -Attach a file using the copy/move/link method. Note that hard -links are not supported on all systems. - -@item @kbd{b} (@code{org-attach-buffer}) -@kindex C-c C-a b -@findex org-attach-buffer -Select a buffer and save it as a file in the task's attachment -directory. - -@item @kbd{n} (@code{org-attach-new}) -@kindex C-c C-a n -@findex org-attach-new -Create a new attachment as an Emacs buffer. - -@item @kbd{z} (@code{org-attach-sync}) -@kindex C-c C-a z -@findex org-attach-sync -Synchronize the current task with its attachment directory, in -case you added attachments yourself. - -@item @kbd{o} (@code{org-attach-open}) -@kindex C-c C-a o -@findex org-attach-open -@vindex org-file-apps -Open current task's attachment. If there is more than one, prompt -for a file name first. Opening follows the rules set by -@code{org-file-apps}. For more details, see the information on -following hyperlinks (see @ref{Handling Links}). - -@item @kbd{O} (@code{org-attach-open-in-emacs}) -@kindex C-c C-a O -@findex org-attach-open-in-emacs -Also open the attachment, but force opening the file in Emacs. - -@item @kbd{f} (@code{org-attach-reveal}) -@kindex C-c C-a f -@findex org-attach-reveal -Open the current task's attachment directory. - -@item @kbd{F} (@code{org-attach-reveal-in-emacs}) -@kindex C-c C-a F -@findex org-attach-reveal-in-emacs -Also open the directory, but force using Dired in Emacs. - -@item @kbd{d} (@code{org-attach-delete-one}) -@kindex C-c C-a d -Select and delete a single attachment. - -@item @kbd{D} (@code{org-attach-delete-all}) -@kindex C-c C-a D -Delete all of a task's attachments. A safer way is to open the -directory in Dired and delete from there. - -@item @kbd{s} (@code{org-attach-set-directory}) -@kindex C-c C-a s -@cindex @samp{DIR}, property -Set a specific directory as the entry's attachment directory. -This works by putting the directory path into the @samp{DIR} -property. - -@item @kbd{S} (@code{org-attach-unset-directory}) -@kindex C-c C-a S -@cindex @samp{DIR}, property -Remove the attachment directory. This command removes the @samp{DIR} -property and asks the user to either move content inside that -folder, if an @samp{ID} property is set, delete the content, or to -leave the attachment directory as is but no longer attached to the -outline node. -@end table -@end table - -@node Attachment options -@subsection Attachment options - -There are a couple of options for attachments that are worth -mentioning. - -@table @asis -@item @code{org-attach-id-dir} -@vindex org-attach-id-dir -The directory where attachments are stored when @samp{ID} is used as -method. - -@item @code{org-attach-dir-relative} -@vindex org-attach-dir-relative -When setting the @samp{DIR} property on a node using @kbd{C-c C-a s} -(@code{org-attach-set-directory}), absolute links are entered by default. -This option changes that to relative links. - -@item @code{org-attach-use-inheritance} -@vindex org-attach-use-inheritance -By default folders attached to an outline node are inherited from -parents according to @code{org-use-property-inheritance}. If one instead -want to set inheritance specifically for Org attach that can be done -using @code{org-attach-use-inheritance}. Inheriting documents through -the node hierarchy makes a lot of sense in most cases. Especially -when using attachment links (see @ref{Attachment links}). The following -example shows one use case for attachment inheritance: - -@example -* Chapter A ... - :PROPERTIES: - :DIR: Chapter A/ - :END: -** Introduction -Some text - -#+NAME: Image 1 -[[attachment:image 1.jpg]] -@end example - -Without inheritance one would not be able to resolve the link to -@samp{image 1.jpg}, since the link is inside a sub-heading to @samp{Chapter - A}. - -Inheritance works the same way for both @samp{ID} and @samp{DIR} property. If -both properties are defined on the same headline then @samp{DIR} takes -precedence. This is also true if inheritance is enabled. If @samp{DIR} -is inherited from a parent node in the outline, that property still -takes precedence over an @samp{ID} property defined on the node itself. - -@item @code{org-attach-method} -@vindex org-attach-method -When attaching files using the dispatcher @kbd{C-c C-a} it -defaults to copying files. The behavior can be changed by -customizing @code{org-attach-method}. Options are Copy, Move/Rename, -Hard link or Symbolic link. - -@item @code{org-attach-preferred-new-method} -@vindex org-attach-preferred-new-method -This customization lets you choose the default way to attach to -nodes without existing @samp{ID} and @samp{DIR} property. It defaults to @code{id} -but can also be set to @code{dir}, @code{ask} or @code{nil}. - -@item @code{org-attach-archive-delete} -@vindex org-attach-archive-delete -Configure this to determine if attachments should be deleted or not -when a subtree that has attachments is archived. - -@item @code{org-attach-auto-tag} -@vindex org-attach-auto-tag -When attaching files to a heading it will be assigned a tag -according to what is set here. - -@item @code{org-attach-id-to-path-function-list} -@vindex org-attach-id-to-path-function-list -When @samp{ID} is used for attachments, the ID is parsed into a part of a -directory-path. See @code{org-attach-id-uuid-folder-format} for the -default function. Define a new one and add it as first element in -@code{org-attach-id-to-path-function-list} if you want the folder -structure in any other way. All functions in this list will be -tried when resolving existing ID's into paths, to maintain backward -compatibility with existing folders in your system. - -@item @code{org-attach-store-link-p} -@vindex org-attach-store-link-p -Stores a link to the file that is being attached. The link is -stored in @code{org-stored-links} for later insertion with @kbd{C-c C-l} (see @ref{Handling Links}). Depending on what option is set in -@code{org-attach-store-link-p}, the link is stored to either the original -location as a file link, the attachment location as an attachment -link or to the attachment location as a file link. - -@item @code{org-attach-commands} -@vindex org-attach-commands -List of all commands used in the attach dispatcher. - -@item @code{org-attach-expert} -@vindex org-attach-expert -Do not show the splash buffer with the attach dispatcher when -@code{org-attach-expert} is set to non-@code{nil}. -@end table - -See customization group @samp{Org Attach} if you want to change the -default settings. - -@node Attachment links -@subsection Attachment links - -Attached files and folders can be referenced using attachment links. -This makes it easy to refer to the material added to an outline node. -Especially if it was attached using the unique ID of the entry! - -@example -* TODO Some task - :PROPERTIES: - :ID: 95d50008-c12e-479f-a4f2-cc0238205319 - :END: -See attached document for more information: [[attachment:info.org]] -@end example - -See @ref{External Links} for more information about these links. - -@node Automatic version-control with Git -@subsection Automatic version-control with Git - -If the directory attached to an outline node is a Git repository, Org -can be configured to automatically commit changes to that repository -when it sees them. - -To make Org mode take care of versioning of attachments for you, add -the following to your Emacs config: - -@lisp -(require 'org-attach-git) -@end lisp - -@node Attach from Dired -@subsection Attach from Dired - -@cindex attach from Dired -@findex org-attach-dired-to-subtree - -It is possible to attach files to a subtree from a Dired buffer. To -use this feature, have one window in Dired mode containing the file(s) -to be attached and another window with point in the subtree that shall -get the attachments. In the Dired window, with point on a file, -@kbd{M-x org-attach-dired-to-subtree} attaches the file to the -subtree using the attachment method set by variable -@code{org-attach-method}. When files are marked in the Dired window then -all marked files get attached. - -Add the following lines to the Emacs init file to have @kbd{C-c C-x a} attach files in Dired buffers. - -@lisp -(add-hook 'dired-mode-hook - (lambda () - (define-key dired-mode-map - (kbd "C-c C-x a") - #'org-attach-dired-to-subtree))) -@end lisp - -The following code shows how to bind the previous command with -a specific attachment method. - -@lisp -(add-hook 'dired-mode-hook - (lambda () - (define-key dired-mode-map (kbd "C-c C-x c") - (lambda () - (interactive) - (let ((org-attach-method 'cp)) - (call-interactively #'org-attach-dired-to-subtree)))))) -@end lisp - -@node RSS Feeds -@section RSS Feeds - -@cindex RSS feeds -@cindex Atom feeds - -Org can add and change entries based on information found in RSS feeds -and Atom feeds. You could use this to make a task out of each new -podcast in a podcast feed. Or you could use a phone-based -note-creating service on the web to import tasks into Org. To access -feeds, configure the variable @code{org-feed-alist}. The docstring of this -variable has detailed information. With the following - -@lisp -(setq org-feed-alist - '(("Slashdot" - "http://rss.slashdot.org/Slashdot/slashdot" - "~/txt/org/feeds.org" "Slashdot Entries"))) -@end lisp - -@noindent -new items from the feed provided by @samp{rss.slashdot.org} result in new -entries in the file @samp{~/org/feeds.org} under the heading @samp{Slashdot -Entries}, whenever the following command is used: - -@table @asis -@item @kbd{C-c C-x g} (@code{org-feed-update-all}) -@kindex C-c C-x g -Collect items from the feeds configured in @code{org-feed-alist} and act -upon them. - -@item @kbd{C-c C-x G} (@code{org-feed-goto-inbox}) -@kindex C-c C-x G -Prompt for a feed name and go to the inbox configured for this feed. -@end table - -Under the same headline, Org creates a drawer @samp{FEEDSTATUS} in which it -stores information about the status of items in the feed, to avoid -adding the same item several times. - -For more information, including how to read atom feeds, see -@samp{org-feed.el} and the docstring of @code{org-feed-alist}. - -@node Agenda Views -@chapter Agenda Views - -@cindex agenda views - -Due to the way Org works, TODO items, time-stamped items, and tagged -headlines can be scattered throughout a file or even a number of -files. To get an overview of open action items, or of events that are -important for a particular date, this information must be collected, -sorted and displayed in an organized way. - -Org can select items based on various criteria and display them in -a separate buffer. Six different view types are provided: - -@itemize -@item -an @emph{agenda} that is like a calendar and shows information for -specific dates, - -@item -a @emph{TODO list} that covers all unfinished action items, - -@item -a @emph{match view}, showings headlines based on the tags, properties, -and TODO state associated with them, - -@item -a @emph{text search view} that shows all entries from multiple files that -contain specified keywords, - -@item -a @emph{stuck projects view} showing projects that currently do not move -along, and - -@item -@emph{custom views} that are special searches and combinations of -different views. -@end itemize - -The extracted information is displayed in a special @emph{agenda buffer}. -This buffer is read-only, but provides commands to visit the -corresponding locations in the original Org files, and even to edit -these files remotely. - -@vindex org-agenda-skip-comment-trees -@vindex org-agenda-skip-archived-trees -@cindex commented entries, in agenda views -@cindex archived entries, in agenda views -By default, the report ignores commented (see @ref{Comment Lines}) and -archived (see @ref{Internal archiving}) entries. You can override this by -setting @code{org-agenda-skip-comment-trees} and -@code{org-agenda-skip-archived-trees} to @code{nil}. - -@vindex org-agenda-window-setup -@vindex org-agenda-restore-windows-after-quit -Two variables control how the agenda buffer is displayed and whether -the window configuration is restored when the agenda exits: -@code{org-agenda-window-setup} and @code{org-agenda-restore-windows-after-quit}. - -@menu -* Agenda Files:: Files being searched for agenda information. -* Agenda Dispatcher:: Keyboard access to agenda views. -* Built-in Agenda Views:: What is available out of the box? -* Presentation and Sorting:: How agenda items are prepared for display. -* Agenda Commands:: Remote editing of Org trees. -* Custom Agenda Views:: Defining special searches and views. -* Exporting Agenda Views:: Writing a view to a file. -* Agenda Column View:: Using column view for collected entries. -@end menu - -@node Agenda Files -@section Agenda Files - -@cindex agenda files -@cindex files for agenda - -@vindex org-agenda-files -The information to be shown is normally collected from all @emph{agenda -files}, the files listed in the variable @code{org-agenda-files}@footnote{If the value of that variable is not a list, but a single file -name, then the list of agenda files in maintained in that external -file.}. -If a directory is part of this list, all files with the extension -@samp{.org} in this directory are part of the list. - -Thus, even if you only work with a single Org file, that file should -be put into the list@footnote{When using the dispatcher, pressing @kbd{<} before -selecting a command actually limits the command to the current file, -and ignores @code{org-agenda-files} until the next dispatcher command.}. You can customize @code{org-agenda-files}, -but the easiest way to maintain it is through the following commands - -@table @asis -@item @kbd{C-c [} (@code{org-agenda-file-to-front}) -@kindex C-c [ -@findex org-agenda-file-to-front -@cindex files, adding to agenda list -Add current file to the list of agenda files. The file is added to -the front of the list. If it was already in the list, it is moved -to the front. With a prefix argument, file is added/moved to the -end. - -@item @kbd{C-c ]} (@code{org-remove-file}) -@kindex C-c ] -@findex org-remove-file -Remove current file from the list of agenda files. - -@item @kbd{C-'} -@itemx @kbd{C-,} (@code{org-cycle-agenda-files}) -@kindex C-' -@kindex C-, -@findex org-cycle-agenda-files -@cindex cycling, of agenda files -Cycle through agenda file list, visiting one file after the other. - -@item @kbd{M-x org-switchb} -@findex org-switchb -Command to use an Iswitchb-like interface to switch to and between -Org buffers. -@end table - -@noindent -The Org menu contains the current list of files and can be used to -visit any of them. - -If you would like to focus the agenda temporarily on a file not in -this list, or on just one file in the list, or even on only a subtree -in a file, then this can be done in different ways. For a single -agenda command, you may press @kbd{<} once or several times in -the dispatcher (see @ref{Agenda Dispatcher}). To restrict the agenda -scope for an extended period, use the following commands: - -@table @asis -@item @kbd{C-c C-x <} (@code{org-agenda-set-restriction-lock}) -@kindex C-c C-x < -@findex org-agenda-set-restriction-lock -Restrict the agenda to the current subtree. If there already is -a restriction at point, remove it. When called with a universal -prefix argument or with point before the first headline in a file, -set the agenda scope to the entire file. This restriction remains -in effect until removed with @kbd{C-c C-x >}, or by typing -either @kbd{<} or @kbd{>} in the agenda dispatcher. If -there is a window displaying an agenda view, the new restriction -takes effect immediately. - -@item @kbd{C-c C-x >} (@code{org-agenda-remove-restriction-lock}) -@kindex C-c C-x > -@findex org-agenda-remove-restriction-lock -Remove the restriction created by @kbd{C-c C-x <}. -@end table - -When working with Speedbar, you can use the following commands in the -Speedbar frame: - -@table @asis -@item @kbd{<} (@code{org-speedbar-set-agenda-restriction}) -@findex org-speedbar-set-agenda-restriction -Restrict the agenda to the item---either an Org file or a subtree in -such a file---at point in the Speedbar frame. If agenda is already -restricted there, remove the restriction. If there is a window -displaying an agenda view, the new restriction takes effect -immediately. - -@item @kbd{>} (@code{org-agenda-remove-restriction-lock}) -@findex org-agenda-remove-restriction-lock -Remove the restriction. -@end table - -@node Agenda Dispatcher -@section The Agenda Dispatcher - -@cindex agenda dispatcher -@cindex dispatching agenda commands - -The views are created through a dispatcher, accessible with @kbd{M-x org-agenda}, or, better, bound to a global key (see @ref{Activation}). -It displays a menu from which an additional letter is required to -execute a command. The dispatcher offers the following default -commands: - -@table @asis -@item @kbd{a} -Create the calendar-like agenda (see @ref{Weekly/daily agenda}). - -@item @kbd{t} -@itemx @kbd{T} -Create a list of all TODO items (see @ref{Global TODO list}). - -@item @kbd{m} -@itemx @kbd{M} -Create a list of headlines matching a given expression (see -@ref{Matching tags and properties}). - -@item @kbd{s} -@kindex s @r{(Agenda dispatcher)} -Create a list of entries selected by a boolean expression of -keywords and/or regular expressions that must or must not occur in -the entry. - -@item @kbd{/} -@kindex / @r{(Agenda dispatcher)} -@vindex org-agenda-text-search-extra-files -Search for a regular expression in all agenda files and additionally -in the files listed in @code{org-agenda-text-search-extra-files}. This -uses the Emacs command @code{multi-occur}. A prefix argument can be used -to specify the number of context lines for each match, default is -@enumerate -@item -@end enumerate - -@item @kbd{#} -Create a list of stuck projects (see @ref{Stuck projects}). - -@item @kbd{!} -Configure the list of stuck projects (see @ref{Stuck projects}). - -@item @kbd{<} -@kindex < @r{(Agenda dispatcher)} -Restrict an agenda command to the current buffer@footnote{For backward compatibility, you can also press @kbd{1} to -restrict to the current buffer.}. If -narrowing is in effect restrict to the narrowed part of the buffer. -After pressing @kbd{<}, you still need to press the character -selecting the command. - -@item @kbd{< <} -@kindex < < @r{(Agenda dispatcher)} -If there is an active region, restrict the following agenda command -to the region. Otherwise, restrict it to the current -subtree@footnote{For backward compatibility, you can also press @kbd{0} to -restrict to the current region/subtree.}. After pressing @kbd{< <}, you still need to -press the character selecting the command. - -@item @kbd{*} -@kindex * @r{(Agenda dispatcher)} -@vindex org-agenda-sticky -@findex org-toggle-sticky-agenda -Toggle sticky agenda views. By default, Org maintains only a single -agenda buffer and rebuilds it each time you change the view, to make -sure everything is always up to date. If you switch between views -often and the build time bothers you, you can turn on sticky agenda -buffers (make this the default by customizing the variable -@code{org-agenda-sticky}). With sticky agendas, the dispatcher only -switches to the selected view, you need to update it by hand with -@kbd{r} or @kbd{g}. You can toggle sticky agenda view any -time with @code{org-toggle-sticky-agenda}. -@end table - -You can also define custom commands that are accessible through the -dispatcher, just like the default commands. This includes the -possibility to create extended agenda buffers that contain several -blocks together, for example the weekly agenda, the global TODO list -and a number of special tags matches. See @ref{Custom Agenda Views}. - -@node Built-in Agenda Views -@section The Built-in Agenda Views - -In this section we describe the built-in views. - -@menu -* Weekly/daily agenda:: The calendar page with current tasks. -* Global TODO list:: All unfinished action items. -* Matching tags and properties:: Structured information with fine-tuned search. -* Search view:: Find entries by searching for text. -* Stuck projects:: Find projects you need to review. -@end menu - -@node Weekly/daily agenda -@subsection Weekly/daily agenda - -@cindex agenda -@cindex weekly agenda -@cindex daily agenda - -The purpose of the weekly/daily @emph{agenda} is to act like a page of -a paper agenda, showing all the tasks for the current week or day. - -@table @asis -@item @kbd{M-x org-agenda a} (@code{org-agenda-list}) -@kindex a @r{(Agenda dispatcher)} -@findex org-agenda-list -@cindex org-agenda, command -Compile an agenda for the current week from a list of Org files. -The agenda shows the entries for each day. With a numeric prefix -argument@footnote{For backward compatibility, the universal prefix argument -@kbd{C-u} causes all TODO entries to be listed before the agenda. -This feature is deprecated, use the dedicated TODO list, or a block -agenda instead (see @ref{Block agenda}).}---like @kbd{C-u 2 1 M-x org-agenda a}---you may -set the number of days to be displayed. -@end table - -@vindex org-agenda-span -@vindex org-agenda-start-day -@vindex org-agenda-start-on-weekday -The default number of days displayed in the agenda is set by the -variable @code{org-agenda-span}. This variable can be set to any number of -days you want to see by default in the agenda, or to a span name, such -a @code{day}, @code{week}, @code{month} or @code{year}. For weekly agendas, the default -is to start on the previous Monday (see -@code{org-agenda-start-on-weekday}). You can also set the start date using -a date shift: @samp{(setq org-agenda-start-day "+10d")} starts the agenda -ten days from today in the future. - -Remote editing from the agenda buffer means, for example, that you can -change the dates of deadlines and appointments from the agenda buffer. -The commands available in the Agenda buffer are listed in @ref{Agenda Commands}. - -@anchor{Calendar/Diary integration} -@subsubheading Calendar/Diary integration - -@cindex calendar integration -@cindex diary integration - -Emacs contains the calendar and diary by Edward@tie{}M@.@tie{}Reingold. The -calendar displays a three-month calendar with holidays from different -countries and cultures. The diary allows you to keep track of -anniversaries, lunar phases, sunrise/set, recurrent appointments -(weekly, monthly) and more. In this way, it is quite complementary to -Org. It can be very useful to combine output from Org with the diary. - -In order to include entries from the Emacs diary into Org mode's -agenda, you only need to customize the variable - -@lisp -(setq org-agenda-include-diary t) -@end lisp - -@noindent -After that, everything happens automatically. All diary entries -including holidays, anniversaries, etc., are included in the agenda -buffer created by Org mode. @kbd{@key{SPC}}, @kbd{@key{TAB}}, and -@kbd{@key{RET}} can be used from the agenda buffer to jump to the diary -file in order to edit existing diary entries. The @kbd{i} -command to insert new entries for the current date works in the agenda -buffer, as well as the commands @kbd{S}, @kbd{M}, and -@kbd{C} to display Sunrise/Sunset times, show lunar phases and to -convert to other calendars, respectively. @kbd{c} can be used to -switch back and forth between calendar and agenda. - -If you are using the diary only for expression entries and holidays, -it is faster to not use the above setting, but instead to copy or even -move the entries into an Org file. Org mode evaluates diary-style -expression entries, and does it faster because there is no overhead -for first creating the diary display. Note that the expression -entries must start at the left margin, no whitespace is allowed before -them, as seen in the following segment of an Org file:@footnote{The variable @code{org-anniversary} used in the example is just -like @code{diary-anniversary}, but the argument order is always according -to ISO and therefore independent of the value of -@code{calendar-date-style}.} - -@example -* Holidays - :PROPERTIES: - :CATEGORY: Holiday - :END: -%%(org-calendar-holiday) ; special function for holiday names - -* Birthdays - :PROPERTIES: - :CATEGORY: Ann - :END: -%%(org-anniversary 1956 5 14) Arthur Dent is %d years old -%%(org-anniversary 1869 10 2) Mahatma Gandhi would be %d years old -@end example - -@anchor{Anniversaries from BBDB} -@subsubheading Anniversaries from BBDB - -@cindex BBDB, anniversaries -@cindex anniversaries, from BBDB - -@findex org-bbdb-anniversaries -If you are using the Insidious Big Brother Database to store your -contacts, you very likely prefer to store anniversaries in BBDB rather -than in a separate Org or diary file. Org supports this and can show -BBDB anniversaries as part of the agenda. All you need to do is to -add the following to one of your agenda files: - -@example -* Anniversaries - :PROPERTIES: - :CATEGORY: Anniv - :END: -%%(org-bbdb-anniversaries) -@end example - -You can then go ahead and define anniversaries for a BBDB record. -Basically, you need a field named @samp{anniversary} for the BBDB record -which contains the date in the format @samp{YYYY-MM-DD} or @samp{MM-DD}, -followed by a space and the class of the anniversary (@samp{birthday}, -@samp{wedding}, or a format string). If you omit the class, it defaults to -@samp{birthday}. Here are a few examples, the header for the file -@samp{ol-bbdb.el} contains more detailed information. - -@example -1973-06-22 -06-22 -1955-08-02 wedding -2008-04-14 %s released version 6.01 of Org mode, %d years ago -@end example - -After a change to BBDB, or for the first agenda display during an -Emacs session, the agenda display suffers a short delay as Org updates -its hash with anniversaries. However, from then on things will be -very fast, much faster in fact than a long list of -@samp{%%(diary-anniversary)} entries in an Org or Diary file. - -@findex org-bbdb-anniversaries-future -If you would like to see upcoming anniversaries with a bit of -forewarning, you can use the following instead: - -@example -* Anniversaries - :PROPERTIES: - :CATEGORY: Anniv - :END: -%%(org-bbdb-anniversaries-future 3) -@end example - -That will give you three days' warning: on the anniversary date itself -and the two days prior. The argument is optional: if omitted, it -defaults to 7. - -@anchor{Appointment reminders} -@subsubheading Appointment reminders - -@cindex @file{appt.el} -@cindex appointment reminders -@cindex appointment -@cindex reminders - -@cindex APPT_WARNTIME, keyword -Org can interact with Emacs appointments notification facility. To -add the appointments of your agenda files, use the command -@code{org-agenda-to-appt}. This command lets you filter through the list -of your appointments and add only those belonging to a specific -category or matching a regular expression. It also reads -a @samp{APPT_WARNTIME} property which overrides the value of -@code{appt-message-warning-time} for this appointment. See the docstring -for details. - -@node Global TODO list -@subsection The global TODO list - -@cindex global TODO list -@cindex TODO list, global - -The global TODO list contains all unfinished TODO items formatted and -collected into a single place. - -@table @asis -@item @kbd{M-x org-agenda t} (@code{org-todo-list}) -@kindex t @r{(Agenda dispatcher)} -@findex org-todo-list -Show the global TODO list. This collects the TODO items from all -agenda files (see @ref{Agenda Views}) into a single buffer. By default, -this lists items with a state the is not a DONE state. The buffer -is in Agenda mode, so there are commands to examine and manipulate -the TODO entries directly from that buffer (see @ref{Agenda Commands}). - -@item @kbd{M-x org-agenda T} (@code{org-todo-list}) -@kindex T @r{(Agenda dispatcher)} -@findex org-todo-list -@cindex TODO keyword matching -@vindex org-todo-keywords -Like the above, but allows selection of a specific TODO keyword. -You can also do this by specifying a prefix argument to -@kbd{t}. You are prompted for a keyword, and you may also -specify several keywords by separating them with @samp{|} as the boolean -OR operator. With a numeric prefix, the Nth keyword in -@code{org-todo-keywords} is selected. - -@kindex r -The @kbd{r} key in the agenda buffer regenerates it, and you -can give a prefix argument to this command to change the selected -TODO keyword, for example @kbd{3 r}. If you often need -a search for a specific keyword, define a custom command for it (see -@ref{Agenda Dispatcher}). - -Matching specific TODO keywords can also be done as part of a tags -search (see @ref{Tag Searches}). -@end table - -Remote editing of TODO items means that you can change the state of -a TODO entry with a single key press. The commands available in the -TODO list are described in @ref{Agenda Commands}. - -@cindex sublevels, inclusion into TODO list -Normally the global TODO list simply shows all headlines with TODO -keywords. This list can become very long. There are two ways to keep -it more compact: - -@itemize -@item -@vindex org-agenda-todo-ignore-scheduled -@vindex org-agenda-todo-ignore-deadlines -@vindex org-agenda-todo-ignore-timestamp -@vindex org-agenda-todo-ignore-with-date -Some people view a TODO item that has been @emph{scheduled} for execution -or have a @emph{deadline} (see @ref{Timestamps}) as no longer @emph{open}. -Configure the variables @code{org-agenda-todo-ignore-scheduled} to -exclude some or all scheduled items from the global TODO list, -@code{org-agenda-todo-ignore-deadlines} to exclude some or all items with -a deadline set, @code{org-agenda-todo-ignore-timestamp} to exclude some -or all items with an active timestamp other than a DEADLINE or -a SCHEDULED timestamp and/or @code{org-agenda-todo-ignore-with-date} to -exclude items with at least one active timestamp. - -@item -@vindex org-agenda-todo-list-sublevels -TODO items may have sublevels to break up the task into subtasks. -In such cases it may be enough to list only the highest level TODO -headline and omit the sublevels from the global list. Configure the -variable @code{org-agenda-todo-list-sublevels} to get this behavior. -@end itemize - -@node Matching tags and properties -@subsection Matching tags and properties - -@cindex matching, of tags -@cindex matching, of properties -@cindex tags view -@cindex match view - -If headlines in the agenda files are marked with @emph{tags} (see @ref{Tags}), -or have properties (see @ref{Properties and Columns}), you can select -headlines based on this metadata and collect them into an agenda -buffer. The match syntax described here also applies when creating -sparse trees with @kbd{C-c / m}. - -@table @asis -@item @kbd{M-x org-agenda m} (@code{org-tags-view}) -@kindex m @r{(Agenda dispatcher)} -@findex org-tags-view -Produce a list of all headlines that match a given set of tags. The -command prompts for a selection criterion, which is a boolean logic -expression with tags, like @samp{+work+urgent-withboss} or @samp{work|home} -(see @ref{Tags}). If you often need a specific search, define a custom -command for it (see @ref{Agenda Dispatcher}). - -@item @kbd{M-x org-agenda M} (@code{org-tags-view}) -@kindex M @r{(Agenda dispatcher)} -@findex org-tags-view -@vindex org-tags-match-list-sublevels -@vindex org-agenda-tags-todo-honor-ignore-options -Like @kbd{m}, but only select headlines that are also TODO -items and force checking subitems (see the variable -@code{org-tags-match-list-sublevels}). To exclude scheduled/deadline -items, see the variable @code{org-agenda-tags-todo-honor-ignore-options}. -Matching specific TODO keywords together with a tags match is also -possible, see @ref{Tag Searches}. -@end table - -The commands available in the tags list are described in @ref{Agenda Commands}. - -@cindex boolean logic, for agenda searches -A search string can use Boolean operators @samp{&} for AND and @samp{|} for OR@. -@samp{&} binds more strongly than @samp{|}. Parentheses are currently not -implemented. Each element in the search is either a tag, a regular -expression matching tags, or an expression like @samp{PROPERTY OPERATOR -VALUE} with a comparison operator, accessing a property value. Each -element may be preceded by @samp{-} to select against it, and @samp{+} is -syntactic sugar for positive selection. The AND operator @samp{&} is -optional when @samp{+} or @samp{-} is present. Here are some examples, using -only tags. - -@table @asis -@item @samp{+work-boss} -Select headlines tagged @samp{work}, but discard those also tagged -@samp{boss}. - -@item @samp{work|laptop} -Selects lines tagged @samp{work} or @samp{laptop}. - -@item @samp{work|laptop+night} -Like before, but require the @samp{laptop} lines to be tagged also -@samp{night}. -@end table - -@cindex regular expressions, with tags search -Instead of a tag, you may also specify a regular expression enclosed -in curly braces. For example, @samp{work+@{^boss.*@}} matches headlines that -contain the tag @samp{:work:} and any tag @emph{starting} with @samp{boss}. - -@cindex group tags, as regular expressions -Group tags (see @ref{Tag Hierarchy}) are expanded as regular expressions. -E.g., if @samp{work} is a group tag for the group @samp{:work:lab:conf:}, then -searching for @samp{work} also searches for @samp{@{\(?:work\|lab\|conf\)@}} and -searching for @samp{-work} searches for all headlines but those with one of -the tags in the group (i.e., @samp{-@{\(?:work\|lab\|conf\)@}}). - -@cindex TODO keyword matching, with tags search -@cindex level, for tags/property match -@cindex category, for tags/property match -@vindex org-odd-levels-only -You may also test for properties (see @ref{Properties and Columns}) at the -same time as matching tags. The properties may be real properties, or -special properties that represent other metadata (see @ref{Special Properties}). For example, the property @samp{TODO} represents the TODO -keyword of the entry. Or, the property @samp{LEVEL} represents the level -of an entry. So searching @samp{+LEVEL=3+boss-TODO​="DONE"} lists all level -three headlines that have the tag @samp{boss} and are @emph{not} marked with the -TODO keyword @samp{DONE}. In buffers with @code{org-odd-levels-only} set, -@samp{LEVEL} does not count the number of stars, but @samp{LEVEL=2} corresponds -to 3 stars etc. - -Here are more examples: - -@table @asis -@item @samp{work+TODO​="WAITING"} -Select @samp{work}-tagged TODO lines with the specific TODO keyword -@samp{WAITING}. - -@item @samp{work+TODO​="WAITING"|home+TODO​="WAITING"} -Waiting tasks both at work and at home. -@end table - -When matching properties, a number of different operators can be used -to test the value of a property. Here is a complex example: - -@example -+work-boss+PRIORITY="A"+Coffee="unlimited"+Effort<2 - +With=@{Sarah|Denny@}+SCHEDULED>="<2008-10-11>" -@end example - -@noindent -The type of comparison depends on how the comparison value is written: - -@itemize -@item -If the comparison value is a plain number, a numerical comparison is -done, and the allowed operators are @samp{<}, @samp{=}, @samp{>}, @samp{<=}, @samp{>=}, and -@samp{<>}. - -@item -If the comparison value is enclosed in double-quotes, a string -comparison is done, and the same operators are allowed. - -@item -If the comparison value is enclosed in double-quotes @emph{and} angular -brackets (like @samp{DEADLINE<​="<2008-12-24 18:30>"}), both values are -assumed to be date/time specifications in the standard Org way, and -the comparison is done accordingly. Valid values also include -@samp{""} for now (including time), @samp{""}, and @samp{""} -for these days at 0:00 hours, i.e., without a time specification. -You can also use strings like @samp{"<+5d>"} or @samp{"<-2m>"} with units @samp{d}, -@samp{w}, @samp{m}, and @samp{y} for day, week, month, and year, respectively. - -@item -If the comparison value is enclosed in curly braces, a regexp match -is performed, with @samp{=} meaning that the regexp matches the property -value, and @samp{<>} meaning that it does not match. -@end itemize - -So the search string in the example finds entries tagged @samp{work} but -not @samp{boss}, which also have a priority value @samp{A}, a @samp{Coffee} property -with the value @samp{unlimited}, an @samp{EFFORT} property that is numerically -smaller than 2, a @samp{With} property that is matched by the regular -expression @samp{Sarah|Denny}, and that are scheduled on or after October -11, 2008. - -You can configure Org mode to use property inheritance during -a search, but beware that this can slow down searches considerably. -See @ref{Property Inheritance}, for details. - -For backward compatibility, and also for typing speed, there is also -a different way to test TODO states in a search. For this, terminate -the tags/property part of the search string (which may include several -terms connected with @samp{|}) with a @samp{/} and then specify a Boolean -expression just for TODO keywords. The syntax is then similar to that -for tags, but should be applied with care: for example, a positive -selection on several TODO keywords cannot meaningfully be combined -with boolean AND@. However, @emph{negative selection} combined with AND can -be meaningful. To make sure that only lines are checked that actually -have any TODO keyword (resulting in a speed-up), use @kbd{M-x org-agenda M}, or equivalently start the TODO part after the slash -with @samp{!}. Using @kbd{M-x org-agenda M} or @samp{/!} does not match -TODO keywords in a DONE state. Examples: - -@table @asis -@item @samp{work/WAITING} -Same as @samp{work+TODO​="WAITING"}. - -@item @samp{work/!-WAITING-NEXT} -Select @samp{work}-tagged TODO lines that are neither @samp{WAITING} nor -@samp{NEXT}. - -@item @samp{work/!+WAITING|+NEXT} -Select @samp{work}-tagged TODO lines that are either @samp{WAITING} or @samp{NEXT}. -@end table - -@node Search view -@subsection Search view - -@cindex search view -@cindex text search -@cindex searching, for text - -This agenda view is a general text search facility for Org mode -entries. It is particularly useful to find notes. - -@table @asis -@item @kbd{M-x org-agenda s} (@code{org-search-view}) -@kindex s @r{(Agenda dispatcher)} -@findex org-search-view -This is a special search that lets you select entries by matching -a substring or specific words using a boolean logic. -@end table - -For example, the search string @samp{computer equipment} matches entries -that contain @samp{computer equipment} as a substring, even if the two -words are separated by more space or a line break. - -Search view can also search for specific keywords in the entry, using -Boolean logic. The search string @samp{+computer -+wifi -ethernet -@{8\.11[bg]@}} matches note entries that contain the -keywords @samp{computer} and @samp{wifi}, but not the keyword @samp{ethernet}, and -which are also not matched by the regular expression @samp{8\.11[bg]}, -meaning to exclude both @samp{8.11b} and @samp{8.11g}. The first @samp{+} is -necessary to turn on boolean search, other @samp{+} characters are -optional. For more details, see the docstring of the command -@code{org-search-view}. - -You can incrementally and conveniently adjust a boolean search from -the agenda search view with the following keys - -@multitable @columnfractions 0.1 0.6 -@item @kbd{[} -@tab Add a positive search word -@item @kbd{]} -@tab Add a negative search word -@item @kbd{@{} -@tab Add a positive regular expression -@item @kbd{@}} -@tab Add a negative regular expression -@end multitable - -@vindex org-agenda-text-search-extra-files -Note that in addition to the agenda files, this command also searches -the files listed in @code{org-agenda-text-search-extra-files}. - -@node Stuck projects -@subsection Stuck projects - -@pindex GTD, Getting Things Done - -If you are following a system like David Allen's GTD to organize your -work, one of the ``duties'' you have is a regular review to make sure -that all projects move along. A @emph{stuck} project is a project that has -no defined next actions, so it never shows up in the TODO lists Org -mode produces. During the review, you need to identify such projects -and define next actions for them. - -@table @asis -@item @kbd{M-x org-agenda #} (@code{org-agenda-list-stuck-projects}) -@kindex # @r{(Agenda dispatcher)} -@findex org-agenda-list-stuck-projects -List projects that are stuck. - -@item @kbd{M-x org-agenda !} -@kindex ! @r{(Agenda dispatcher)} -@vindex org-stuck-projects -Customize the variable @code{org-stuck-projects} to define what a stuck -project is and how to find it. -@end table - -You almost certainly need to configure this view before it works for -you. The built-in default assumes that all your projects are level-2 -headlines, and that a project is not stuck if it has at least one -entry marked with a TODO keyword @samp{TODO} or @samp{NEXT} or @samp{NEXTACTION}. - -Let's assume that you, in your own way of using Org mode, identify -projects with a tag @samp{:PROJECT:}, and that you use a TODO keyword -@samp{MAYBE} to indicate a project that should not be considered yet. -Let's further assume that the TODO keyword @samp{DONE} marks finished -projects, and that @samp{NEXT} and @samp{TODO} indicate next actions. The tag -@samp{:@@shop:} indicates shopping and is a next action even without the -NEXT tag. Finally, if the project contains the special word @samp{IGNORE} -anywhere, it should not be listed either. In this case you would -start by identifying eligible projects with a tags/TODO match (see -@ref{Tag Searches}) @samp{+PROJECT/-MAYBE-DONE}, and then check for @samp{TODO}, -@samp{NEXT}, @samp{@@shop}, and @samp{IGNORE} in the subtree to identify projects that -are not stuck. The correct customization for this is: - -@lisp -(setq org-stuck-projects - '("+PROJECT/-MAYBE-DONE" ("NEXT" "TODO") ("@@shop") - "\\")) -@end lisp - -Note that if a project is identified as non-stuck, the subtree of this -entry is searched for stuck projects. - -@node Presentation and Sorting -@section Presentation and Sorting - -@cindex presentation, of agenda items - -@vindex org-agenda-prefix-format -@vindex org-agenda-tags-column -Before displaying items in an agenda view, Org mode visually prepares -the items and sorts them. Each item occupies a single line. The line -starts with a @emph{prefix} that contains the @emph{category} (see @ref{Categories}) -of the item and other important information. You can customize in -which column tags are displayed through @code{org-agenda-tags-column}. You -can also customize the prefix using the option -@code{org-agenda-prefix-format}. This prefix is followed by a cleaned-up -version of the outline headline associated with the item. - -@menu -* Categories:: Not all tasks are equal. -* Time-of-day specifications:: How the agenda knows the time. -* Sorting of agenda items:: The order of things. -* Filtering/limiting agenda items:: Dynamically narrow the agenda. -@end menu - -@node Categories -@subsection Categories - -@cindex category -@cindex @samp{CATEGORY}, keyword - -The category is a broad label assigned to each agenda item. By -default, the category is simply derived from the file name, but you -can also specify it with a special line in the buffer, like -this: - -@example -#+CATEGORY: Thesis -@end example - - -@cindex @samp{CATEGORY}, property -If you would like to have a special category for a single entry or -a (sub)tree, give the entry a @samp{CATEGORY} property with the special -category you want to apply as the value. - -@vindex org-agenda-category-icon-alist -The display in the agenda buffer looks best if the category is not -longer than 10 characters. You can set up icons for category by -customizing the @code{org-agenda-category-icon-alist} variable. - -@node Time-of-day specifications -@subsection Time-of-day specifications - -@cindex time-of-day specification - -Org mode checks each agenda item for a time-of-day specification. The -time can be part of the timestamp that triggered inclusion into the -agenda, for example - -@example -<2005-05-10 Tue 19:00> -@end example - - -@noindent -Time ranges can be specified with two timestamps: - -@example -<2005-05-10 Tue 20:30>--<2005-05-10 Tue 22:15> -@end example - - -@vindex org-agenda-search-headline-for-time -In the headline of the entry itself, a time(range)---like @samp{12:45} or -a @samp{8:30-1pm}---may also appear as plain text@footnote{You can, however, disable this by setting -@code{org-agenda-search-headline-for-time} variable to a @code{nil} value.}. - -If the agenda integrates the Emacs diary (see @ref{Weekly/daily agenda}), -time specifications in diary entries are recognized as well. - -For agenda display, Org mode extracts the time and displays it in -a standard 24 hour format as part of the prefix. The example times in -the previous paragraphs would end up in the agenda like this: - -@example - 8:30-13:00 Arthur Dent lies in front of the bulldozer -12:45...... Ford Prefect arrives and takes Arthur to the pub -19:00...... The Vogon reads his poem -20:30-22:15 Marvin escorts the Hitchhikers to the bridge -@end example - -@cindex time grid -If the agenda is in single-day mode, or for the display of today, the -timed entries are embedded in a time grid, like - -@example - 8:00...... ------------------ - 8:30-13:00 Arthur Dent lies in front of the bulldozer -10:00...... ------------------ -12:00...... ------------------ -12:45...... Ford Prefect arrives and takes Arthur to the pub -14:00...... ------------------ -16:00...... ------------------ -18:00...... ------------------ -19:00...... The Vogon reads his poem -20:00...... ------------------ -20:30-22:15 Marvin escorts the Hitchhikers to the bridge -@end example - -@vindex org-agenda-use-time-grid -@vindex org-agenda-time-grid -The time grid can be turned on and off with the variable -@code{org-agenda-use-time-grid}, and can be configured with -@code{org-agenda-time-grid}. - -@node Sorting of agenda items -@subsection Sorting of agenda items - -@cindex sorting, of agenda items -@cindex priorities, of agenda items - -Before being inserted into a view, the items are sorted. How this is -done depends on the type of view. - -@itemize -@item -@vindex org-agenda-files -For the daily/weekly agenda, the items for each day are sorted. The -default order is to first collect all items containing an explicit -time-of-day specification. These entries are shown at the beginning -of the list, as a @emph{schedule} for the day. After that, items remain -grouped in categories, in the sequence given by @code{org-agenda-files}. -Within each category, items are sorted by priority (see -@ref{Priorities}), which is composed of the base priority (2000 for -priority @samp{A}, 1000 for @samp{B}, and 0 for @samp{C}), plus additional -increments for overdue scheduled or deadline items. - -@item -For the TODO list, items remain in the order of categories, but -within each category, sorting takes place according to priority (see -@ref{Priorities}). The priority used for sorting derives from the -priority cookie, with additions depending on how close an item is to -its due or scheduled date. - -@item -For tags matches, items are not sorted at all, but just appear in -the sequence in which they are found in the agenda files. -@end itemize - -@vindex org-agenda-sorting-strategy -Sorting can be customized using the variable -@code{org-agenda-sorting-strategy}, and may also include criteria based on -the estimated effort of an entry (see @ref{Effort Estimates}). - -@node Filtering/limiting agenda items -@subsection Filtering/limiting agenda items - -@vindex org-agenda-category-filter-preset -@vindex org-agenda-tag-filter-preset -@vindex org-agenda-effort-filter-preset -@vindex org-agenda-regexp-filter-preset -Agenda built-in or custom commands are statically defined. Agenda -filters and limits allow to flexibly narrow down the list of agenda -entries. - -@emph{Filters} only change the visibility of items, are very fast and are -mostly used interactively@footnote{Custom agenda commands can preset a filter by binding one of -the variables @code{org-agenda-tag-filter-preset}, -@code{org-agenda-category-filter-preset}, @code{org-agenda-effort-filter-preset} -or @code{org-agenda-regexp-filter-preset} as an option. This filter is -then applied to the view and persists as a basic filter through -refreshes and more secondary filtering. The filter is a global -property of the entire agenda view---in a block agenda, you should -only set this in the global options section, not in the section of an -individual block.}. You can switch quickly between -different filters without having to recreate the agenda. @emph{Limits} on -the other hand take effect before the agenda buffer is populated, so -they are mostly useful when defined as local variables within custom -agenda commands. - -@anchor{Filtering in the agenda} -@subsubheading Filtering in the agenda - -@cindex agenda filtering -@cindex filtering entries, in agenda -@cindex tag filtering, in agenda -@cindex category filtering, in agenda -@cindex top headline filtering, in agenda -@cindex effort filtering, in agenda -@cindex query editing, in agenda - -The general filtering command is @code{org-agenda-filter}, bound to -@kbd{/}. Before we introduce it, we describe commands for -individual filter types. All filtering commands handle prefix -arguments in the same way: A single @kbd{C-u} prefix negates the -filter, so it removes lines selected by the filter. A double prefix -adds the new filter condition to the one(s) already in place, so -filter elements are accumulated. - -@table @asis -@item @kbd{\} (@code{org-agenda-filter-by-tag}) -@findex org-agenda-filter-by-tag -Filter the agenda view with respect to a tag. You are prompted for -a tag selection letter; @kbd{@key{SPC}} means any tag at all. -Pressing @kbd{@key{TAB}} at that prompt offers completion to select a -tag, including any tags that do not have a selection character. The -command then hides all entries that do not contain or inherit this -tag. Pressing @kbd{+} or @kbd{-} at the prompt switches -between filtering for and against the next tag. To clear the -filter, press @kbd{\} twice (once to call the command again, -and once at the prompt). - -@item @kbd{<} (@code{org-agenda-filter-by-category}) -@findex org-agenda-filter-by-category -Filter by category of the line at point, and show only entries with -this category. When called with a prefix argument, hide all entries -with the category at point. To clear the filter, call this command -again by pressing @kbd{<}. - -@item @kbd{=} (@code{org-agenda-filter-by-regexp}) -@findex org-agenda-filter-by-regexp -Filter the agenda view by a regular expression: only show agenda -entries matching the regular expression the user entered. To clear -the filter, call the command again by pressing @kbd{=}. - -@item @kbd{_} (@code{org-agenda-filter-by-effort}) -@findex org-agenda-filter-by-effort -Filter the agenda view with respect to effort estimates, so select -tasks that take the right amount of time. You first need to set up -a list of efforts globally, for example - -@lisp -(setq org-global-properties - '(("Effort_ALL". "0 0:10 0:30 1:00 2:00 3:00 4:00"))) -@end lisp - -@vindex org-sort-agenda-noeffort-is-high -You can then filter for an effort by first typing an operator, one -of @kbd{<}, @kbd{>} and @kbd{=}, and then the -one-digit index of an effort estimate in your array of allowed -values, where @kbd{0} means the 10th value. The filter then -restricts to entries with effort smaller-or-equal, equal, or -larger-or-equal than the selected value. For application of the -operator, entries without a defined effort are treated according to -the value of @code{org-sort-agenda-noeffort-is-high}. To clear the -filter, press @kbd{_} twice (once to call the command again, -and once at the first prompt). - -@item @kbd{^} (@code{org-agenda-filter-by-top-headline}) -@findex org-agenda-filter-by-top-headline -Filter the current agenda view and only display items that fall -under the same top-level headline as the current entry. To clear -the filter, call this command again by pressing @kbd{^}. - -@item @kbd{/} (@code{org-agenda-filter}) -@findex org-agenda-filter -This is the unified interface to four of the five filter methods -described above. At the prompt, specify different filter elements -in a single string, with full completion support. For example, - -@example -+work-John+<0:10-/plot/ -@end example - - -selects entries with category @samp{work} and effort estimates below 10 -minutes, and deselects entries with tag @samp{John} or matching the -regexp @samp{plot}. You can leave @samp{+} out if that does not lead to -ambiguities. The sequence of elements is arbitrary. The filter -syntax assumes that there is no overlap between categories and tags. -Otherwise, tags take priority. If you reply to the prompt with the -empty string, all filtering is removed. If a filter is specified, -it replaces all current filters. But if you call the command with -a double prefix argument, or if you add an additional @samp{+} (e.g., -@samp{++work}) to the front of the string, the new filter elements are -added to the active ones. A single prefix argument applies the -entire filter in a negative sense. - -@item @kbd{|} (@code{org-agenda-filter-remove-all}) -Remove all filters in the current agenda view. -@end table - -@anchor{Computed tag filtering} -@subsubheading Computed tag filtering - -@vindex org-agenda-auto-exclude-function -If the variable @code{org-agenda-auto-exclude-function} is set to -a user-defined function, that function can select tags that should be -used as a tag filter when requested. The function will be called with -lower-case versions of all tags represented in the current view. The -function should return @samp{"-tag"} if the filter should remove -entries with that tag, @samp{"+tag"} if only entries with this tag should -be kept, or @samp{nil} if that tag is irrelevant. For example, let's say -you use a @samp{Net} tag to identify tasks which need network access, an -@samp{Errand} tag for errands in town, and a @samp{Call} tag for making phone -calls. You could auto-exclude these tags based on the availability of -the Internet, and outside of business hours, with something like this: - -@lisp -(defun my-auto-exclude-fn (tag) - (when (cond ((string= tag "net") - (/= 0 (call-process "/sbin/ping" nil nil nil - "-c1" "-q" "-t1" "mail.gnu.org"))) - ((member tag '("errand" "call")) - (let ((hr (nth 2 (decode-time)))) - (or (< hr 8) (> hr 21))))) - (concat "-" tag))) - -(setq org-agenda-auto-exclude-function #'my-auto-exclude-fn) -@end lisp - -You can apply this self-adapting filter by using a triple prefix -argument to @code{org-agenda-filter}, i.e.@tie{}press @kbd{C-u C-u C-u /}, -or by pressing @kbd{@key{RET}} in @code{org-agenda-filter-by-tag}. - -@anchor{Setting limits for the agenda} -@subsubheading Setting limits for the agenda - -@cindex limits, in agenda - -Here is a list of options that you can set, either globally, or -locally in your custom agenda views (see @ref{Custom Agenda Views}). - -@table @asis -@item @code{org-agenda-max-entries} -@vindex org-agenda-max-entries -Limit the number of entries. - -@item @code{org-agenda-max-effort} -@vindex org-agenda-max-effort -Limit the duration of accumulated efforts (as minutes). - -@item @code{org-agenda-max-todos} -@vindex org-agenda-max-todos -Limit the number of entries with TODO keywords. - -@item @code{org-agenda-max-tags} -@vindex org-agenda-max-tags -Limit the number of tagged entries. -@end table - -When set to a positive integer, each option excludes entries from -other categories: for example, @samp{(setq org-agenda-max-effort 100)} -limits the agenda to 100 minutes of effort and exclude any entry that -has no effort property. If you want to include entries with no effort -property, use a negative value for @code{org-agenda-max-effort}. One -useful setup is to use @code{org-agenda-max-entries} locally in a custom -command. For example, this custom command displays the next five -entries with a @samp{NEXT} TODO keyword. - -@lisp -(setq org-agenda-custom-commands - '(("n" todo "NEXT" - ((org-agenda-max-entries 5))))) -@end lisp - -Once you mark one of these five entry as DONE, rebuilding the agenda -will again the next five entries again, including the first entry that -was excluded so far. - -You can also dynamically set temporary limits, which are lost when -rebuilding the agenda: - -@table @asis -@item @kbd{~} (@code{org-agenda-limit-interactively}) -@findex org-agenda-limit-interactively -This prompts for the type of limit to apply and its value. -@end table - -@node Agenda Commands -@section Commands in the Agenda Buffer - -@cindex commands, in agenda buffer - -Entries in the agenda buffer are linked back to the Org file or diary -file where they originate. You are not allowed to edit the agenda -buffer itself, but commands are provided to show and jump to the -original entry location, and to edit the Org files ``remotely'' from the -agenda buffer. In this way, all information is stored only once, -removing the risk that your agenda and note files may diverge. - -Some commands can be executed with mouse clicks on agenda lines. For -the other commands, point needs to be in the desired line. - -@anchor{Motion (1)} -@subheading Motion - -@cindex motion commands in agenda - -@table @asis -@item @kbd{n} (@code{org-agenda-next-line}) -@kindex n -@findex org-agenda-next-line -Next line (same as @kbd{@key{DOWN}} and @kbd{C-n}). - -@item @kbd{p} (@code{org-agenda-previous-line}) -@kindex p -@findex org-agenda-previous-line -Previous line (same as @kbd{@key{UP}} and @kbd{C-p}). -@end table - -@anchor{View/Go to Org file} -@subheading View/Go to Org file - -@cindex view file commands in agenda - -@table @asis -@item @kbd{@key{SPC}} or @kbd{mouse-3} (@code{org-agenda-show-and-scroll-up}) -@kindex SPC -@kindex mouse-3 -@findex org-agenda-show-and-scroll-up -Display the original location of the item in another window. -With a prefix argument, make sure that drawers stay folded. - -@item @kbd{L} (@code{org-agenda-recenter}) -@findex org-agenda-recenter -Display original location and recenter that window. - -@item @kbd{@key{TAB}} or @kbd{mouse-2} (@code{org-agenda-goto}) -@kindex TAB -@kindex mouse-2 -@findex org-agenda-goto -Go to the original location of the item in another window. - -@item @kbd{@key{RET}} (@code{org-agenda-switch-to}) -@kindex RET -@findex org-agenda-switch-to -Go to the original location of the item and delete other windows. - -@item @kbd{F} (@code{org-agenda-follow-mode}) -@kindex F -@findex org-agenda-follow-mode -@vindex org-agenda-start-with-follow-mode -Toggle Follow mode. In Follow mode, as you move point through the -agenda buffer, the other window always shows the corresponding -location in the Org file. The initial setting for this mode in new -agenda buffers can be set with the variable -@code{org-agenda-start-with-follow-mode}. - -@item @kbd{C-c C-x b} (@code{org-agenda-tree-to-indirect-buffer}) -@kindex C-c C-x b -@findex org-agenda-tree-to-indirect-buffer -Display the entire subtree of the current item in an indirect -buffer. With a numeric prefix argument N, go up to level N and then -take that tree. If N is negative, go up that many levels. With -a @kbd{C-u} prefix, do not remove the previously used indirect -buffer. - -@item @kbd{C-c C-o} (@code{org-agenda-open-link}) -@kindex C-c C-o -@findex org-agenda-open-link -Follow a link in the entry. This offers a selection of any links in -the text belonging to the referenced Org node. If there is only one -link, follow it without a selection prompt. -@end table - -@anchor{Change display} -@subheading Change display - -@cindex change agenda display -@cindex display changing, in agenda - -@table @asis -@item @kbd{A} -@kindex A -Interactively select another agenda view and append it to the -current view. - -@item @kbd{o} -@kindex o -Delete other windows. - -@item @kbd{v d} or short @kbd{d} (@code{org-agenda-day-view}) -@kindex v d -@kindex d -@findex org-agenda-day-view -Switch to day view. When switching to day view, this setting -becomes the default for subsequent agenda refreshes. A numeric -prefix argument may be used to jump directly to a specific day of -the year. For example, @kbd{32 d} jumps to February 1st. When -setting day view, a year may be encoded in the prefix argument as -well. For example, @kbd{200712 d} jumps to January 12, 2007. -If such a year specification has only one or two digits, it is -expanded into one of the 30 next years or the last 69 years. - -@item @kbd{v w} or short @kbd{w} (@code{org-agenda-week-view}) -@kindex v w -@kindex w -@findex org-agenda-week-view -Switch to week view. When switching week view, this setting becomes -the default for subsequent agenda refreshes. A numeric prefix -argument may be used to jump directly to a specific day of the ISO -week. For example @kbd{9 w} to ISO week number 9. When -setting week view, a year may be encoded in the prefix argument as -well. For example, @kbd{200712 w} jumps to week 12 in 2007. -If such a year specification has only one or two digits, it is -expanded into one of the 30 next years or the last 69 years. - -@item @kbd{v m} (@code{org-agenda-month-view}) -@kindex v m -@findex org-agenda-month-view -Switch to month view. Because month views are slow to create, they -do not become the default for subsequent agenda refreshes. -A numeric prefix argument may be used to jump directly to a specific -day of the month. When setting month view, a year may be encoded in -the prefix argument as well. For example, @kbd{200712 m} jumps -to December, 2007. If such a year specification has only one or two -digits, it is expanded into one of the 30 next years or the last 69 -years. - -@item @kbd{v y} (@code{org-agenda-year-view}) -@kindex v y -@findex org-agenda-year-view -Switch to year view. Because year views are slow to create, they do -not become the default for subsequent agenda refreshes. A numeric -prefix argument may be used to jump directly to a specific day of -the year. - -@item @kbd{v @key{SPC}} (@code{org-agenda-reset-view}) -@kindex v SPC -@findex org-agenda-reset-view -@vindex org-agenda-span -Reset the current view to @code{org-agenda-span}. - -@item @kbd{f} (@code{org-agenda-later}) -@kindex f -@findex org-agenda-later -Go forward in time to display the span following the current one. -For example, if the display covers a week, switch to the following -week. With a prefix argument, repeat that many times. - -@item @kbd{b} (@code{org-agenda-earlier}) -@kindex b -@findex org-agenda-earlier -Go backward in time to display earlier dates. - -@item @kbd{.} (@code{org-agenda-goto-today}) -@kindex . -@findex org-agenda-goto-today -Go to today. - -@item @kbd{j} (@code{org-agenda-goto-date}) -@kindex j -@findex org-agenda-goto-date -Prompt for a date and go there. - -@item @kbd{J} (@code{org-agenda-clock-goto}) -@kindex J -@findex org-agenda-clock-goto -Go to the currently clocked-in task @emph{in the agenda buffer}. - -@item @kbd{D} (@code{org-agenda-toggle-diary}) -@kindex D -@findex org-agenda-toggle-diary -Toggle the inclusion of diary entries. See @ref{Weekly/daily agenda}. - -@item @kbd{v l} or @kbd{v L} or short @kbd{l} (@code{org-agenda-log-mode}) -@kindex v l -@kindex l -@kindex v L -@findex org-agenda-log-mode -@vindex org-log-done -@vindex org-agenda-log-mode-items -Toggle Logbook mode. In Logbook mode, entries that were marked as -done while logging was on (see the variable @code{org-log-done}) are -shown in the agenda, as are entries that have been clocked on that -day. You can configure the entry types that should be included in -log mode using the variable @code{org-agenda-log-mode-items}. When -called with a @kbd{C-u} prefix argument, show all possible -logbook entries, including state changes. When called with two -prefix arguments @kbd{C-u C-u}, show only logging information, -nothing else. @kbd{v L} is equivalent to @kbd{C-u v l}. - -@item @kbd{v [} or short @kbd{[} (@code{org-agenda-manipulate-query-add}) -@kindex v [ -@kindex [ -@findex org-agenda-manipulate-query-add -Include inactive timestamps into the current view. Only for -weekly/daily agenda. - -@item @kbd{v a} (@code{org-agenda-archives-mode}) -@kindex v a -@findex org-agenda-archives-mode -Toggle Archives mode. In Archives mode, trees that are archived -(see @ref{Internal archiving}) are also scanned when producing the -agenda. To exit archives mode, press @kbd{v a} again. - -@item @kbd{v A} -@kindex v A -Toggle Archives mode. Include all archive files as well. - -@item @kbd{v R} or short @kbd{R} (@code{org-agenda-clockreport-mode}) -@kindex v R -@kindex R -@findex org-agenda-clockreport-mode -@vindex org-agenda-start-with-clockreport-mode -@vindex org-clock-report-include-clocking-task -Toggle Clockreport mode. In Clockreport mode, the daily/weekly -agenda always shows a table with the clocked times for the time span -and file scope covered by the current agenda view. The initial -setting for this mode in new agenda buffers can be set with the -variable @code{org-agenda-start-with-clockreport-mode}. By using -a prefix argument when toggling this mode (i.e., @kbd{C-u R}), -the clock table does not show contributions from entries that are -hidden by agenda filtering@footnote{Only tags filtering is respected here, effort filtering is -ignored.}. See also the variable -@code{org-clock-report-include-clocking-task}. - -@item @kbd{v c} -@kindex v c -@vindex org-agenda-clock-consistency-checks -Show overlapping clock entries, clocking gaps, and other clocking -problems in the current agenda range. You can then visit clocking -lines and fix them manually. See the variable -@code{org-agenda-clock-consistency-checks} for information on how to -customize the definition of what constituted a clocking problem. To -return to normal agenda display, press @kbd{l} to exit Logbook -mode. - -@item @kbd{v E} or short @kbd{E} (@code{org-agenda-entry-text-mode}) -@kindex v E -@kindex E -@findex org-agenda-entry-text-mode -@vindex org-agenda-start-with-entry-text-mode -@vindex org-agenda-entry-text-maxlines -Toggle entry text mode. In entry text mode, a number of lines from -the Org outline node referenced by an agenda line are displayed -below the line. The maximum number of lines is given by the -variable @code{org-agenda-entry-text-maxlines}. Calling this command -with a numeric prefix argument temporarily modifies that number to -the prefix value. - -@item @kbd{G} (@code{org-agenda-toggle-time-grid}) -@kindex G -@vindex org-agenda-use-time-grid -@vindex org-agenda-time-grid -Toggle the time grid on and off. See also the variables -@code{org-agenda-use-time-grid} and @code{org-agenda-time-grid}. - -@item @kbd{r} (@code{org-agenda-redo}) -@itemx @kbd{g} -@kindex r -@kindex g -@findex org-agenda-redo -Recreate the agenda buffer, for example to reflect the changes after -modification of the timestamps of items with @kbd{S-@key{LEFT}} and -@kbd{S-@key{RIGHT}}. When the buffer is the global TODO list, -a prefix argument is interpreted to create a selective list for -a specific TODO keyword. - -@item @kbd{C-x C-s} or short @kbd{s} (@code{org-save-all-org-buffers}) -@kindex C-x C-s -@findex org-save-all-org-buffers -@kindex s -Save all Org buffers in the current Emacs session, and also the -locations of IDs. - -@item @kbd{C-c C-x C-c} (@code{org-agenda-columns}) -@kindex C-c C-x C-c -@findex org-agenda-columns -@vindex org-columns-default-format -Invoke column view (see @ref{Column View}) in the agenda buffer. The -column view format is taken from the entry at point, or, if there is -no entry at point, from the first entry in the agenda view. So -whatever the format for that entry would be in the original buffer -(taken from a property, from a @samp{COLUMNS} keyword, or from the -default variable @code{org-columns-default-format}) is used in the -agenda. - -@item @kbd{C-c C-x >} (@code{org-agenda-remove-restriction-lock}) -@kindex C-c C-x > -@findex org-agenda-remove-restriction-lock -Remove the restriction lock on the agenda, if it is currently -restricted to a file or subtree (see @ref{Agenda Files}). - -@item @kbd{M-@key{UP}} (@code{org-agenda-drag-line-backward}) -@kindex M-UP -@findex org-agenda-drag-line-backward -Drag the line at point backward one line. With a numeric prefix -argument, drag backward by that many lines. - -Moving agenda lines does not persist after an agenda refresh and -does not modify the contributing Org files. - -@item @kbd{M-@key{DOWN}} (@code{org-agenda-drag-line-forward}) -@kindex M-DOWN -@findex org-agenda-drag-line-forward -Drag the line at point forward one line. With a numeric prefix -argument, drag forward by that many lines. -@end table - -@anchor{Remote editing} -@subheading Remote editing - -@cindex remote editing, from agenda - -@table @asis -@item @kbd{0--9} -Digit argument. - -@item @kbd{C-_} (@code{org-agenda-undo}) -@kindex C-_ -@findex org-agenda-undo -@cindex undoing remote-editing events -@cindex remote editing, undo -Undo a change due to a remote editing command. The change is undone -both in the agenda buffer and in the remote buffer. - -@item @kbd{t} (@code{org-agenda-todo}) -@kindex t -@findex org-agenda-todo -Change the TODO state of the item, both in the agenda and in the -original Org file. A prefix arg is passed through to the @code{org-todo} -command, so for example a @kbd{C-u} prefix are will trigger -taking a note to document the state change. - -@item @kbd{C-S-@key{RIGHT}} (@code{org-agenda-todo-nextset}) -@kindex C-S-RIGHT -@findex org-agenda-todo-nextset -Switch to the next set of TODO keywords. - -@item @kbd{C-S-@key{LEFT}}, @code{org-agenda-todo-previousset} -@kindex C-S-LEFT -Switch to the previous set of TODO keywords. - -@item @kbd{C-k} (@code{org-agenda-kill}) -@kindex C-k -@findex org-agenda-kill -@vindex org-agenda-confirm-kill -Delete the current agenda item along with the entire subtree -belonging to it in the original Org file. If the text to be deleted -remotely is longer than one line, the kill needs to be confirmed by -the user. See variable @code{org-agenda-confirm-kill}. - -@item @kbd{C-c C-w} (@code{org-agenda-refile}) -@kindex C-c C-w -@findex org-agenda-refile -Refile the entry at point. - -@item @kbd{C-c C-x C-a} or short @kbd{a} (@code{org-agenda-archive-default-with-confirmation}) -@kindex C-c C-x C-a -@kindex a -@findex org-agenda-archive-default-with-confirmation -@vindex org-archive-default-command -Archive the subtree corresponding to the entry at point using the -default archiving command set in @code{org-archive-default-command}. -When using the @kbd{a} key, confirmation is required. - -@item @kbd{C-c C-x a} (@code{org-agenda-toggle-archive-tag}) -@kindex C-c C-x a -@findex org-agenda-toggle-archive-tag -Toggle the archive tag (see @ref{Internal archiving}) for the current -headline. - -@item @kbd{C-c C-x A} (@code{org-agenda-archive-to-archive-sibling}) -@kindex C-c C-x A -@findex org-agenda-archive-to-archive-sibling -Move the subtree corresponding to the current entry to its @emph{archive -sibling}. - -@item @kbd{C-c C-x C-s} or short @kbd{$} (@code{org-agenda-archive}) -@kindex C-c C-x C-s -@kindex $ -@findex org-agenda-archive -Archive the subtree corresponding to the current headline. This -means the entry is moved to the configured archive location, most -likely a different file. - -@item @kbd{T} (@code{org-agenda-show-tags}) -@kindex T -@findex org-agenda-show-tags -@vindex org-agenda-show-inherited-tags -Show all tags associated with the current item. This is useful if -you have turned off @code{org-agenda-show-inherited-tags}, but still want -to see all tags of a headline occasionally. - -@item @kbd{:} (@code{org-agenda-set-tags}) -@kindex : -@findex org-agenda-set-tags -Set tags for the current headline. If there is an active region in -the agenda, change a tag for all headings in the region. - -@item @kbd{,} (@code{org-agenda-priority}) -@kindex , -@findex org-agenda-priority -Set the priority for the current item. Org mode prompts for the -priority character. If you reply with @kbd{@key{SPC}}, the priority -cookie is removed from the entry. - -@item @kbd{+} or @kbd{S-@key{UP}} (@code{org-agenda-priority-up}) -@kindex + -@kindex S-UP -@findex org-agenda-priority-up -Increase the priority of the current item. The priority is changed -in the original buffer, but the agenda is not resorted. Use the -@kbd{r} key for this. - -@item @kbd{-} or @kbd{S-@key{DOWN}} (@code{org-agenda-priority-down}) -@kindex - -@kindex S-DOWN -@findex org-agenda-priority-down -Decrease the priority of the current item. - -@item @kbd{C-c C-x e} or short @kbd{e} (@code{org-agenda-set-effort}) -@kindex e -@kindex C-c C-x e -@findex org-agenda-set-effort -Set the effort property for the current item. - -@item @kbd{C-c C-z} or short @kbd{z} (@code{org-agenda-add-note}) -@kindex z -@kindex C-c C-z -@findex org-agenda-add-note -@vindex org-log-into-drawer -Add a note to the entry. This note is recorded, and then filed to -the same location where state change notes are put. Depending on -@code{org-log-into-drawer}, this may be inside a drawer. - -@item @kbd{C-c C-a} (@code{org-attach}) -@kindex C-c C-a -@findex org-attach -Dispatcher for all command related to attachments. - -@item @kbd{C-c C-s} (@code{org-agenda-schedule}) -@kindex C-c C-s -@findex org-agenda-schedule -Schedule this item. With a prefix argument, remove the -scheduling timestamp - -@item @kbd{C-c C-d} (@code{org-agenda-deadline}) -@kindex C-c C-d -@findex org-agenda-deadline -Set a deadline for this item. With a prefix argument, remove the -deadline. - -@item @kbd{S-@key{RIGHT}} (@code{org-agenda-do-date-later}) -@kindex S-RIGHT -@findex org-agenda-do-date-later -Change the timestamp associated with the current line by one day -into the future. If the date is in the past, the first call to this -command moves it to today. With a numeric prefix argument, change -it by that many days. For example, @kbd{3 6 5 S-@key{RIGHT}} changes -it by a year. With a @kbd{C-u} prefix, change the time by one -hour. If you immediately repeat the command, it will continue to -change hours even without the prefix argument. With a double -@kbd{C-u C-u} prefix, do the same for changing minutes. The -stamp is changed in the original Org file, but the change is not -directly reflected in the agenda buffer. Use @kbd{r} or -@kbd{g} to update the buffer. - -@item @kbd{S-@key{LEFT}} (@code{org-agenda-do-date-earlier}) -@kindex S-LEFT -@findex org-agenda-do-date-earlier -Change the timestamp associated with the current line by one day -into the past. - -@item @kbd{>} (@code{org-agenda-date-prompt}) -@kindex > -@findex org-agenda-date-prompt -Change the timestamp associated with the current line. The key -@kbd{>} has been chosen, because it is the same as -@kbd{S-.} on my keyboard. - -@item @kbd{I} (@code{org-agenda-clock-in}) -@kindex I -@findex org-agenda-clock-in -Start the clock on the current item. If a clock is running already, -it is stopped first. - -@item @kbd{O} (@code{org-agenda-clock-out}) -@kindex O -@findex org-agenda-clock-out -Stop the previously started clock. - -@item @kbd{X} (@code{org-agenda-clock-cancel}) -@kindex X -@findex org-agenda-clock-cancel -Cancel the currently running clock. - -@item @kbd{J} (@code{org-agenda-clock-goto}) -@kindex J -@findex org-agenda-clock-goto -Jump to the running clock in another window. - -@item @kbd{k} (@code{org-agenda-capture}) -@kindex k -@findex org-agenda-capture -@cindex capturing, from agenda -@vindex org-capture-use-agenda-date -Like @code{org-capture}, but use the date at point as the default date -for the capture template. See @code{org-capture-use-agenda-date} to make -this the default behavior of @code{org-capture}. -@end table - -@anchor{Bulk remote editing selected entries} -@subheading Bulk remote editing selected entries - -@cindex remote editing, bulk, from agenda -@vindex org-agenda-bulk-custom-functions - -@table @asis -@item @kbd{m} (@code{org-agenda-bulk-mark}) -@kindex m -@findex org-agenda-bulk-mark - -Mark the entry at point for bulk action. If there is an active -region in the agenda, mark the entries in the region. With numeric -prefix argument, mark that many successive entries. - -@item @kbd{*} (@code{org-agenda-bulk-mark-all}) -@kindex * -@findex org-agenda-bulk-mark-all - -Mark all visible agenda entries for bulk action. - -@item @kbd{u} (@code{org-agenda-bulk-unmark}) -@kindex u -@findex org-agenda-bulk-unmark - -Unmark entry for bulk action. - -@item @kbd{U} (@code{org-agenda-bulk-remove-all-marks}) -@kindex U -@findex org-agenda-bulk-remove-all-marks - -Unmark all marked entries for bulk action. - -@item @kbd{M-m} (@code{org-agenda-bulk-toggle}) -@kindex M-m -@findex org-agenda-bulk-toggle - -Toggle mark of the entry at point for bulk action. - -@item @kbd{M-*} (@code{org-agenda-bulk-toggle-all}) -@kindex M-* -@findex org-agenda-bulk-toggle-all - -Toggle mark of every entry for bulk action. - -@item @kbd{%} (@code{org-agenda-bulk-mark-regexp}) -@kindex % -@findex org-agenda-bulk-mark-regexp - -Mark entries matching a regular expression for bulk action. - -@item @kbd{B} (@code{org-agenda-bulk-action}) -@kindex B -@findex org-agenda-bulk-action -@vindex org-agenda-bulk-persistent-marks - -Bulk action: act on all marked entries in the agenda. This prompts -for another key to select the action to be applied. The prefix -argument to @kbd{B} is passed through to the @kbd{s} and -@kbd{d} commands, to bulk-remove these special timestamps. By -default, marks are removed after the bulk. If you want them to -persist, set @code{org-agenda-bulk-persistent-marks} to @code{t} or hit -@kbd{p} at the prompt. - -@table @asis -@item @kbd{p} -Toggle persistent marks. - -@item @kbd{$} -Archive all selected entries. - -@item @kbd{A} -Archive entries by moving them to their respective archive -siblings. - -@item @kbd{t} -Change TODO state. This prompts for a single TODO keyword and -changes the state of all selected entries, bypassing blocking and -suppressing logging notes---but not timestamps. - -@item @kbd{+} -Add a tag to all selected entries. - -@item @kbd{-} -Remove a tag from all selected entries. - -@item @kbd{s} -Schedule all items to a new date. To shift existing schedule -dates by a fixed number of days, use something starting with -double plus at the prompt, for example @samp{++8d} or @samp{++2w}. - -@item @kbd{d} -Set deadline to a specific date. - -@item @kbd{r} -Prompt for a single refile target and move all entries. The -entries are no longer in the agenda; refresh (@kbd{g}) to -bring them back. - -@item @kbd{S} -Reschedule randomly into the coming N days. N is prompted for. -With a prefix argument (@kbd{C-u B S}), scatter only across -weekdays. - -@item @kbd{f} -@vindex org-agenda-bulk-custom-functions -Apply a function@footnote{You can also create persistent custom functions through -@code{org-agenda-bulk-custom-functions}.} to marked entries. For example, the -function below sets the @samp{CATEGORY} property of the entries to -@samp{web}. - -@lisp -(defun set-category () - (interactive "P") - (let ((marker (or (org-get-at-bol 'org-hd-marker) - (org-agenda-error)))) - (org-with-point-at marker - (org-back-to-heading t) - (org-set-property "CATEGORY" "web")))) -@end lisp -@end table -@end table - -@anchor{Calendar commands} -@subheading Calendar commands - -@cindex calendar commands, from agenda - -@table @asis -@item @kbd{c} (@code{org-agenda-goto-calendar}) -@kindex c -@findex org-agenda-goto-calendar -Open the Emacs calendar and go to the date at point in the agenda. - -@item @kbd{c} (@code{org-calendar-goto-agenda}) -@kindex c -@findex org-calendar-goto-agenda -When in the calendar, compute and show the Org agenda for the date -at point. - -@item @kbd{i} (@code{org-agenda-diary-entry}) -@kindex i -@findex org-agenda-diary-entry - -@cindex diary entries, creating from agenda -Insert a new entry into the diary, using the date at point and (for -block entries) the date at the mark. This adds to the Emacs diary -file@footnote{This file is parsed for the agenda when -@code{org-agenda-include-diary} is set.}, in a way similar to the @kbd{i} command in the -calendar. The diary file pops up in another window, where you can -add the entry. - -@vindex org-agenda-diary-file -If you configure @code{org-agenda-diary-file} to point to an Org file, -Org creates entries in that file instead. Most entries are stored -in a date-based outline tree that will later make it easy to archive -appointments from previous months/years. The tree is built under an -entry with a @samp{DATE_TREE} property, or else with years as top-level -entries. Emacs prompts you for the entry text---if you specify it, -the entry is created in @code{org-agenda-diary-file} without further -interaction. If you directly press @kbd{@key{RET}} at the prompt -without typing text, the target file is shown in another window for -you to finish the entry there. See also the @kbd{k r} command. - -@item @kbd{M} (@code{org-agenda-phases-of-moon}) -@kindex M -@findex org-agenda-phases-of-moon -Show the phases of the moon for the three months around current -date. - -@item @kbd{S} (@code{org-agenda-sunrise-sunset}) -@kindex S -@findex org-agenda-sunrise-sunset -Show sunrise and sunset times. The geographical location must be -set with calendar variables, see the documentation for the Emacs -calendar. - -@item @kbd{C} (@code{org-agenda-convert-date}) -@kindex C -@findex org-agenda-convert-date -Convert the date at point into many other cultural and historic -calendars. - -@item @kbd{H} (@code{org-agenda-holidays}) -@kindex H -@findex org-agenda-holidays -Show holidays for three months around point date. -@end table - -@anchor{Quit and exit} -@subheading Quit and exit - -@table @asis -@item @kbd{q} (@code{org-agenda-quit}) -@kindex q -@findex org-agenda-quit - -Quit agenda, remove the agenda buffer. - -@item @kbd{x} (@code{org-agenda-exit}) -@kindex x -@findex org-agenda-exit - -@cindex agenda files, removing buffers -Exit agenda, remove the agenda buffer and all buffers loaded by -Emacs for the compilation of the agenda. Buffers created by the -user to visit Org files are not removed. -@end table - -@node Custom Agenda Views -@section Custom Agenda Views - -@cindex custom agenda views -@cindex agenda views, custom - -Custom agenda commands serve two purposes: to store and quickly access -frequently used TODO and tags searches, and to create special -composite agenda buffers. Custom agenda commands are accessible -through the dispatcher (see @ref{Agenda Dispatcher}), just like the -default commands. - -@menu -* Storing searches:: Type once, use often. -* Block agenda:: All the stuff you need in a single buffer. -* Setting options:: Changing the rules. -@end menu - -@node Storing searches -@subsection Storing searches - -The first application of custom searches is the definition of keyboard -shortcuts for frequently used searches, either creating an agenda -buffer, or a sparse tree (the latter covering of course only the -current buffer). - -@kindex C @r{(Agenda dispatcher)} -@vindex org-agenda-custom-commands -@cindex agenda views, main example -@cindex agenda, as an agenda views -@cindex agenda*, as an agenda views -@cindex tags, as an agenda view -@cindex todo, as an agenda view -@cindex tags-todo -@cindex todo-tree -@cindex occur-tree -@cindex tags-tree -Custom commands are configured in the variable -@code{org-agenda-custom-commands}. You can customize this variable, for -example by pressing @kbd{C} from the agenda dispatcher (see @ref{Agenda Dispatcher}). You can also directly set it with Emacs Lisp in -the Emacs init file. The following example contains all valid agenda -views: - -@lisp -(setq org-agenda-custom-commands - '(("x" agenda) - ("y" agenda*) - ("w" todo "WAITING") - ("W" todo-tree "WAITING") - ("u" tags "+boss-urgent") - ("v" tags-todo "+boss-urgent") - ("U" tags-tree "+boss-urgent") - ("f" occur-tree "\\") - ("h" . "HOME+Name tags searches") ;description for "h" prefix - ("hl" tags "+home+Lisa") - ("hp" tags "+home+Peter") - ("hk" tags "+home+Kim"))) -@end lisp - -The initial string in each entry defines the keys you have to press -after the dispatcher command in order to access the command. Usually -this is just a single character, but if you have many similar -commands, you can also define two-letter combinations where the first -character is the same in several combinations and serves as a prefix -key@footnote{You can provide a description for a prefix key by inserting -a cons cell with the prefix and the description.}. The second parameter is the search type, followed by the -string or regular expression to be used for the matching. The example -above will therefore define: - -@table @asis -@item @kbd{x} -as a global search for agenda entries planned@footnote{@emph{Planned} means here that these entries have some planning -information attached to them, like a time-stamp, a scheduled or -a deadline string. See @code{org-agenda-entry-types} on how to set what -planning information is taken into account.} this week/day. - -@item @kbd{y} -as the same search, but only for entries with an hour specification -like @samp{[h]h:mm}---think of them as appointments. - -@item @kbd{w} -as a global search for TODO entries with @samp{WAITING} as the TODO -keyword. - -@item @kbd{W} -as the same search, but only in the current buffer and displaying -the results as a sparse tree. - -@item @kbd{u} -as a global tags search for headlines tagged @samp{boss} but not -@samp{urgent}. - -@item @kbd{v} -The same search, but limiting it to headlines that are also TODO -items. - -@item @kbd{U} -as the same search, but only in the current buffer and displaying -the result as a sparse tree. - -@item @kbd{f} -to create a sparse tree (again, current buffer only) with all -entries containing the word @samp{FIXME}. - -@item @kbd{h} -as a prefix command for a @samp{HOME} tags search where you have to press -an additional key (@kbd{l}, @kbd{p} or @kbd{k}) to -select a name (Lisa, Peter, or Kim) as additional tag to match. -@end table - -Note that @code{*-tree} agenda views need to be called from an Org buffer -as they operate on the current buffer only. - -@node Block agenda -@subsection Block agenda - -@cindex block agenda -@cindex agenda, with block views - -Another possibility is the construction of agenda views that comprise -the results of @emph{several} commands, each of which creates a block in -the agenda buffer. The available commands include @code{agenda} for the -daily or weekly agenda (as created with @kbd{a}) , @code{alltodo} for -the global TODO list (as constructed with @kbd{t}), @code{stuck} for -the list of stuck projects (as obtained with @kbd{#}) and the -matching commands discussed above: @code{todo}, @code{tags}, and @code{tags-todo}. - -Here are two examples: - -@lisp -(setq org-agenda-custom-commands - '(("h" "Agenda and Home-related tasks" - ((agenda "") - (tags-todo "home") - (tags "garden"))) - ("o" "Agenda and Office-related tasks" - ((agenda "") - (tags-todo "work") - (tags "office"))))) -@end lisp - -@noindent -This defines @kbd{h} to create a multi-block view for stuff you -need to attend to at home. The resulting agenda buffer contains your -agenda for the current week, all TODO items that carry the tag @samp{home}, -and also all lines tagged with @samp{garden}. Finally the command -@kbd{o} provides a similar view for office tasks. - -@node Setting options -@subsection Setting options for custom commands - -@cindex options, for custom agenda views - -@vindex org-agenda-custom-commands -Org mode contains a number of variables regulating agenda construction -and display. The global variables define the behavior for all agenda -commands, including the custom commands. However, if you want to -change some settings just for a single custom view, you can do so. -Setting options requires inserting a list of variable names and values -at the right spot in @code{org-agenda-custom-commands}. For example: - -@lisp -(setq org-agenda-custom-commands - '(("w" todo "WAITING" - ((org-agenda-sorting-strategy '(priority-down)) - (org-agenda-prefix-format " Mixed: "))) - ("U" tags-tree "+boss-urgent" - ((org-show-context-detail 'minimal))) - ("N" search "" - ((org-agenda-files '("~org/notes.org")) - (org-agenda-text-search-extra-files nil))))) -@end lisp - -@noindent -Now the @kbd{w} command sorts the collected entries only by -priority, and the prefix format is modified to just say @samp{Mixed:} -instead of giving the category of the entry. The sparse tags tree of -@kbd{U} now turns out ultra-compact, because neither the headline -hierarchy above the match, nor the headline following the match are -shown. The command @kbd{N} does a text search limited to only -a single file. - -For command sets creating a block agenda, @code{org-agenda-custom-commands} -has two separate spots for setting options. You can add options that -should be valid for just a single command in the set, and options that -should be valid for all commands in the set. The former are just -added to the command entry; the latter must come after the list of -command entries. Going back to the block agenda example (see @ref{Block agenda}), let's change the sorting strategy for the @kbd{h} -commands to @code{priority-down}, but let's sort the results for @samp{garden} -tags query in the opposite order, @code{priority-up}. This would look like -this: - -@lisp -(setq org-agenda-custom-commands - '(("h" "Agenda and Home-related tasks" - ((agenda) - (tags-todo "home") - (tags "garden" - ((org-agenda-sorting-strategy '(priority-up))))) - ((org-agenda-sorting-strategy '(priority-down)))) - ("o" "Agenda and Office-related tasks" - ((agenda) - (tags-todo "work") - (tags "office"))))) -@end lisp - -As you see, the values and parentheses setting is a little complex. -When in doubt, use the customize interface to set this variable---it -fully supports its structure. Just one caveat: when setting options -in this interface, the @emph{values} are just Lisp expressions. So if the -value is a string, you need to add the double-quotes around the value -yourself. - -@vindex org-agenda-custom-commands-contexts -To control whether an agenda command should be accessible from -a specific context, you can customize -@code{org-agenda-custom-commands-contexts}. Let's say for example that you -have an agenda command @kbd{o} displaying a view that you only -need when reading emails. Then you would configure this option like -this: - -@lisp -(setq org-agenda-custom-commands-contexts - '(("o" (in-mode . "message-mode")))) -@end lisp - -You can also tell that the command key @kbd{o} should refer to -another command key @kbd{r}. In that case, add this command key -like this: - -@lisp -(setq org-agenda-custom-commands-contexts - '(("o" "r" (in-mode . "message-mode")))) -@end lisp - -See the docstring of the variable for more information. - -@node Exporting Agenda Views -@section Exporting Agenda Views - -@cindex agenda views, exporting - -If you are away from your computer, it can be very useful to have -a printed version of some agenda views to carry around. Org mode can -export custom agenda views as plain text, HTML@footnote{For HTML you need to install Hrvoje Nikšić's @samp{htmlize.el} -as an Emacs package from MELPA or from @uref{https://github.com/hniksic/emacs-htmlize, Hrvoje Nikšić's repository}.}, Postscript, -PDF@footnote{To create PDF output, the Ghostscript ps2pdf utility must be -installed on the system. Selecting a PDF file also creates the -postscript file.}, and iCalendar files. If you want to do this only -occasionally, use the following command: - -@table @asis -@item @kbd{C-x C-w} (@code{org-agenda-write}) -@kindex C-x C-w -@findex org-agenda-write -@cindex exporting agenda views -@cindex agenda views, exporting - -@vindex org-agenda-exporter-settings -Write the agenda view to a file. -@end table - -If you need to export certain agenda views frequently, you can -associate any custom agenda command with a list of output file -names@footnote{If you want to store standard views like the weekly agenda or -the global TODO list as well, you need to define custom commands for -them in order to be able to specify file names.}. Here is an example that first defines custom commands -for the agenda and the global TODO list, together with a number of -files to which to export them. Then we define two block agenda -commands and specify file names for them as well. File names can be -relative to the current working directory, or absolute. - -@lisp -(setq org-agenda-custom-commands - '(("X" agenda "" nil ("agenda.html" "agenda.ps")) - ("Y" alltodo "" nil ("todo.html" "todo.txt" "todo.ps")) - ("h" "Agenda and Home-related tasks" - ((agenda "") - (tags-todo "home") - (tags "garden")) - nil - ("~/views/home.html")) - ("o" "Agenda and Office-related tasks" - ((agenda) - (tags-todo "work") - (tags "office")) - nil - ("~/views/office.ps" "~/calendars/office.ics")))) -@end lisp - -The extension of the file name determines the type of export. If it -is @samp{.html}, Org mode uses the htmlize package to convert the buffer to -HTML and save it to this file name. If the extension is @samp{.ps}, -@code{ps-print-buffer-with-faces} is used to produce Postscript output. If -the extension is @samp{.ics}, iCalendar export is run export over all files -that were used to construct the agenda, and limit the export to -entries listed in the agenda. Any other extension produces a plain -ASCII file. - -The export files are @emph{not} created when you use one of those -commands interactively because this might use too much overhead. -Instead, there is a special command to produce @emph{all} specified -files in one step: - -@table @asis -@item @kbd{e} (@code{org-store-agenda-views}) -@kindex e @r{(Agenda dispatcher)} -@findex org-store-agenda-views -Export all agenda views that have export file names associated with -them. -@end table - -You can use the options section of the custom agenda commands to also -set options for the export commands. For example: - -@lisp -(setq org-agenda-custom-commands - '(("X" agenda "" - ((ps-number-of-columns 2) - (ps-landscape-mode t) - (org-agenda-prefix-format " [ ] ") - (org-agenda-with-colors nil) - (org-agenda-remove-tags t)) - ("theagenda.ps")))) -@end lisp - -@noindent -@vindex org-agenda-exporter-settings -This command sets two options for the Postscript exporter, to make it -print in two columns in landscape format---the resulting page can be -cut in two and then used in a paper agenda. The remaining settings -modify the agenda prefix to omit category and scheduling information, -and instead include a checkbox to check off items. We also remove the -tags to make the lines compact, and we do not want to use colors for -the black-and-white printer. Settings specified in -@code{org-agenda-exporter-settings} also apply, e.g., - -@lisp -(setq org-agenda-exporter-settings - '((ps-number-of-columns 2) - (ps-landscape-mode t) - (org-agenda-add-entry-text-maxlines 5) - (htmlize-output-type 'css))) -@end lisp - -@noindent -but the settings in @code{org-agenda-custom-commands} take precedence. - -From the command line you may also use: - -@example -emacs -eval (org-batch-store-agenda-views) -kill -@end example - -@noindent -or, if you need to modify some parameters@footnote{Quoting depends on the system you use, please check the FAQ -for examples.} - -@example -emacs -eval '(org-batch-store-agenda-views \ - org-agenda-span (quote month) \ - org-agenda-start-day "2007-11-01" \ - org-agenda-include-diary nil \ - org-agenda-files (quote ("~/org/project.org")))' \ - -kill -@end example - -@noindent -which creates the agenda views restricted to the file -@samp{~/org/project.org}, without diary entries and with a 30-day extent. - -You can also extract agenda information in a way that allows further -processing by other programs. See @ref{Extracting Agenda Information}, for -more information. - -@node Agenda Column View -@section Using Column View in the Agenda - -@cindex column view, in agenda -@cindex agenda, column view - -Column view (see @ref{Column View}) is normally used to view and edit -properties embedded in the hierarchical structure of an Org file. It -can be quite useful to use column view also from the agenda, where -entries are collected by certain criteria. - -@table @asis -@item @kbd{C-c C-x C-c} (@code{org-agenda-columns}) -@kindex C-c C-x C-c -@findex org-agenda-columns - -Turn on column view in the agenda. -@end table - -To understand how to use this properly, it is important to realize -that the entries in the agenda are no longer in their proper outline -environment. This causes the following issues: - -@enumerate -@item -@vindex org-columns-default-format-for-agenda -@vindex org-columns-default-format -Org needs to make a decision which columns format to use. Since -the entries in the agenda are collected from different files, and -different files may have different columns formats, this is a -non-trivial problem. Org first checks if -@code{org-overriding-columns-format} is currently set, and if so, takes -the format from there. You should set this variable only in the -@emph{local settings section} of a custom agenda command (see @ref{Custom Agenda Views}) to make it valid for that specific agenda view. If -no such binding exists, it checks, in sequence, -@code{org-columns-default-format-for-agenda}, the format associated with -the first item in the agenda (through a property or a @samp{#+COLUMNS} -setting in that buffer) and finally @code{org-columns-default-format}. - -@item -@cindex @samp{CLOCKSUM}, special property -If any of the columns has a summary type defined (see @ref{Column attributes}), turning on column view in the agenda visits all -relevant agenda files and make sure that the computations of this -property are up to date. This is also true for the special -@samp{CLOCKSUM} property. Org then sums the values displayed in the -agenda. In the daily/weekly agenda, the sums cover a single day; -in all other views they cover the entire block. - -It is important to realize that the agenda may show the same entry -@emph{twice}---for example as scheduled and as a deadline---and it may -show two entries from the same hierarchy (for example a @emph{parent} -and its @emph{child}). In these cases, the summation in the agenda -leads to incorrect results because some values count double. - -@item -When the column view in the agenda shows the @samp{CLOCKSUM} property, -that is always the entire clocked time for this item. So even in -the daily/weekly agenda, the clocksum listed in column view may -originate from times outside the current view. This has the -advantage that you can compare these values with a column listing -the planned total effort for a task---one of the major -applications for column view in the agenda. If you want -information about clocked time in the displayed period use clock -table mode (press @kbd{R} in the agenda). - -@item -@cindex @samp{CLOCKSUM_T}, special property -When the column view in the agenda shows the @samp{CLOCKSUM_T} property, -that is always today's clocked time for this item. So even in the -weekly agenda, the clocksum listed in column view only originates -from today. This lets you compare the time you spent on a task for -today, with the time already spent---via @samp{CLOCKSUM}---and with -the planned total effort for it. -@end enumerate - -@node Markup for Rich Contents -@chapter Markup for Rich Contents - -Org is primarily about organizing and searching through your -plain-text notes. However, it also provides a lightweight yet robust -markup language for rich text formatting and more. For instance, you -may want to center or emphasize text. Or you may need to insert -a formula or image in your writing. Org offers syntax for all of this -and more. Used in conjunction with the export framework (see -@ref{Exporting}), you can author beautiful documents in Org---like the fine -manual you are currently reading. - -@menu -* Paragraphs:: The basic unit of text. -* Emphasis and Monospace:: Bold, italic, etc. -* Subscripts and Superscripts:: Simple syntax for raising/lowering text. -* Special Symbols:: Greek letters and other symbols. -* Embedded @LaTeX{}:: LaTeX can be freely used inside Org documents. -* Literal Examples:: Source code examples with special formatting. -* Images:: Display an image. -* Captions:: Describe tables, images... -* Horizontal Rules:: Make a line. -* Creating Footnotes:: Edit and read footnotes. -@end menu - -@node Paragraphs -@section Paragraphs - -@cindex paragraphs, markup rules -Paragraphs are separated by at least one empty line. If you need to -enforce a line break within a paragraph, use @samp{\\} at the end of -a line. - -@cindex line breaks, markup rules -To preserve the line breaks, indentation and blank lines in a region, -but otherwise use normal formatting, you can use this construct, which -can also be used to format poetry. - -@cindex @samp{BEGIN_VERSE} -@cindex verse blocks -@example -#+BEGIN_VERSE - Great clouds overhead - Tiny black birds rise and fall - Snow covers Emacs - - ---AlexSchroeder -#+END_VERSE -@end example - -When quoting a passage from another document, it is customary to -format this as a paragraph that is indented on both the left and the -right margin. You can include quotations in Org documents like this: - -@cindex @samp{BEGIN_QUOTE} -@cindex quote blocks -@example -#+BEGIN_QUOTE -Everything should be made as simple as possible, -but not any simpler ---Albert Einstein -#+END_QUOTE -@end example - -If you would like to center some text, do it like this: - -@cindex @samp{BEGIN_CENTER} -@cindex center blocks -@example -#+BEGIN_CENTER -Everything should be made as simple as possible, \\ -but not any simpler -#+END_CENTER -@end example - -@node Emphasis and Monospace -@section Emphasis and Monospace - -@cindex underlined text, markup rules -@cindex bold text, markup rules -@cindex italic text, markup rules -@cindex verbatim text, markup rules -@cindex code text, markup rules -@cindex strike-through text, markup rules - -You can make words @samp{*bold*}, @samp{/italic/}, @samp{_underlined_}, @samp{=verbatim=} -and @samp{~code~}, and, if you must, @samp{+strike-through+}. Text in the code -and verbatim string is not processed for Org specific syntax; it is -exported verbatim. - -@vindex org-fontify-emphasized-text -To turn off fontification for marked up text, you can set -@code{org-fontify-emphasized-text} to @code{nil}. To narrow down the list of -available markup syntax, you can customize @code{org-emphasis-alist}. - -@node Subscripts and Superscripts -@section Subscripts and Superscripts - -@cindex subscript -@cindex superscript - -@samp{^} and @samp{_} are used to indicate super- and subscripts. To increase -the readability of ASCII text, it is not necessary, but OK, to -surround multi-character sub- and superscripts with curly braces. For -example - -@example -The radius of the sun is R_sun = 6.96 x 10^8 m. On the other hand, -the radius of Alpha Centauri is R_@{Alpha Centauri@} = 1.28 x R_@{sun@}. -@end example - -@vindex org-use-sub-superscripts -If you write a text where the underscore is often used in a different -context, Org's convention to always interpret these as subscripts can -get in your way. Configure the variable @code{org-use-sub-superscripts} to -change this convention. For example, when setting this variable to -@code{@{@}}, @samp{a_b} is not interpreted as a subscript, but @samp{a_@{b@}} is. - -You can set @code{org-use-sub-superscripts} in a file using the export -option @samp{^:} (see @ref{Export Settings}). For example, @samp{#+OPTIONS: ^:@{@}} -sets @code{org-use-sub-superscripts} to @code{@{@}} and limits super- and -subscripts to the curly bracket notation. - -You can also toggle the visual display of super- and subscripts: - -@table @asis -@item @kbd{C-c C-x \} (@code{org-toggle-pretty-entities}) -@kindex C-c C-x \ -@findex org-toggle-pretty-entities -This command formats sub- and superscripts in a WYSIWYM way. -@end table - -@vindex org-pretty-entities -@vindex org-pretty-entities-include-sub-superscripts -Set both @code{org-pretty-entities} and -@code{org-pretty-entities-include-sub-superscripts} to @code{t} to start with -super- and subscripts @emph{visually} interpreted as specified by the -option @code{org-use-sub-superscripts}. - -@node Special Symbols -@section Special Symbols - -@cindex math symbols -@cindex special symbols -@cindex entities - -You can use @LaTeX{}-like syntax to insert special symbols---named -entities---like @samp{\alpha} to indicate the Greek letter, or @samp{\to} to indicate -an arrow. Completion for these symbols is available, just type @samp{\} -and maybe a few letters, and press @kbd{M-@key{TAB}} to see possible -completions. If you need such a symbol inside a word, terminate it -with a pair of curly brackets. For example - -@example -Pro tip: Given a circle \Gamma of diameter d, the length of its -circumference is \pi@{@}d. -@end example - -@findex org-entities-help -@vindex org-entities-user -A large number of entities is provided, with names taken from both -HTML and @LaTeX{}; you can comfortably browse the complete list from -a dedicated buffer using the command @code{org-entities-help}. It is also -possible to provide your own special symbols in the variable -@code{org-entities-user}. - -During export, these symbols are transformed into the native format of -the exporter back-end. Strings like @samp{\alpha} are exported as @samp{α} in -the HTML output, and as @samp{\(\alpha\)} in the @LaTeX{} output. Similarly, @samp{\nbsp} -becomes @samp{ } in HTML and @samp{~} in @LaTeX{}. - -@cindex special symbols, in-buffer display -If you would like to see entities displayed as UTF-8 characters, use -the following command@footnote{You can turn this on by default by setting the variable -@code{org-pretty-entities}, or on a per-file base with the @samp{STARTUP} option -@samp{entitiespretty}.}: - -@table @asis -@item @kbd{C-c C-x \} (@code{org-toggle-pretty-entities}) -@kindex C-c C-x \ -@findex org-toggle-pretty-entities - -Toggle display of entities as UTF-8 characters. This does not -change the buffer content which remains plain ASCII, but it overlays -the UTF-8 character for display purposes only. -@end table - -@cindex shy hyphen, special symbol -@cindex dash, special symbol -@cindex ellipsis, special symbol -In addition to regular entities defined above, Org exports in -a special way@footnote{This behavior can be disabled with @samp{-} export setting (see -@ref{Export Settings}).} the following commonly used character -combinations: @samp{\-} is treated as a shy hyphen, @samp{--} and @samp{---} are -converted into dashes, and @samp{...} becomes a compact set of dots. - -@node Embedded @LaTeX{} -@section Embedded @LaTeX{} - -@cindex @TeX{} interpretation -@cindex @LaTeX{} interpretation - -Plain ASCII is normally sufficient for almost all note taking. -Exceptions include scientific notes, which often require mathematical -symbols and the occasional formula. @LaTeX{}@footnote{@LaTeX{} is a macro system based on Donald@tie{}E@.@tie{}Knuth's @TeX{} -system. Many of the features described here as ``@LaTeX{}'' are really -from @TeX{}, but for simplicity I am blurring this distinction.} is widely used to -typeset scientific documents. Org mode supports embedding @LaTeX{} code -into its files, because many academics are used to writing and reading -@LaTeX{} source code, and because it can be readily processed to produce -pretty output for a number of export back-ends. - -@menu -* @LaTeX{} fragments:: Complex formulas made easy. -* Previewing @LaTeX{} fragments:: What will this snippet look like? -* CD@LaTeX{} mode:: Speed up entering of formulas. -@end menu - -@node @LaTeX{} fragments -@subsection @LaTeX{} fragments - -@cindex @LaTeX{} fragments - -@vindex org-format-latex-header -Org mode can contain @LaTeX{} math fragments, and it supports ways to -process these for several export back-ends. When exporting to @LaTeX{}, -the code is left as it is. When exporting to HTML, Org can use either -@uref{http://www.mathjax.org, MathJax} (see @ref{Math formatting in HTML export}) or transcode the math -into images (see @ref{Previewing @LaTeX{} fragments}). - -@LaTeX{} fragments do not need any special marking at all. The following -snippets are identified as @LaTeX{} source code: - -@itemize -@item -Environments of any kind@footnote{When MathJax is used, only the environments recognized by -MathJax are processed. When dvipng, dvisvgm, or ImageMagick suite is -used to create images, any @LaTeX{} environment is handled.}. The only requirement is that the -@samp{\begin} statement appears on a new line, preceded by only -whitespace. - -@item -Text within the usual @LaTeX{} math delimiters. To avoid conflicts -with currency specifications, single @samp{$} characters are only -recognized as math delimiters if the enclosed text contains at most -two line breaks, is directly attached to the @samp{$} characters with no -whitespace in between, and if the closing @samp{$} is followed by -whitespace, punctuation or a dash. For the other delimiters, there -is no such restriction, so when in doubt, use @samp{\(...\)} as inline -math delimiters. -@end itemize - -@noindent -For example: - -@example -\begin@{equation@} % arbitrary environments, -x=\sqrt@{b@} % even tables, figures -\end@{equation@} % etc - -If $a^2=b$ and \( b=2 \), then the solution must be -either $$ a=+\sqrt@{2@} $$ or \[ a=-\sqrt@{2@} \]. -@end example - -@vindex org-export-with-latex -@LaTeX{} processing can be configured with the variable -@code{org-export-with-latex}. The default setting is @code{t} which means -MathJax for HTML, and no processing for ASCII and @LaTeX{} back-ends. -You can also set this variable on a per-file basis using one of these -lines: - -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{#+OPTIONS: tex:t} -@tab Do the right thing automatically (MathJax) -@item @samp{#+OPTIONS: tex:nil} -@tab Do not process @LaTeX{} fragments at all -@item @samp{#+OPTIONS: tex:verbatim} -@tab Verbatim export, for jsMath or so -@end multitable - -@node Previewing @LaTeX{} fragments -@subsection Previewing @LaTeX{} fragments - -@cindex @LaTeX{} fragments, preview - -@vindex org-preview-latex-default-process -If you have a working @LaTeX{} installation and @samp{dvipng}, @samp{dvisvgm} or -@samp{convert} installed@footnote{These are respectively available at -@uref{http://sourceforge.net/projects/dvipng/}, @uref{http://dvisvgm.bplaced.net/} -and from the ImageMagick suite. Choose the converter by setting the -variable @code{org-preview-latex-default-process} accordingly.}, @LaTeX{} fragments can be processed to -produce images of the typeset expressions to be used for inclusion -while exporting to HTML (see @ref{@LaTeX{} fragments}), or for inline -previewing within Org mode. - -@vindex org-format-latex-options -@vindex org-format-latex-header -You can customize the variables @code{org-format-latex-options} and -@code{org-format-latex-header} to influence some aspects of the preview. -In particular, the @code{:scale} (and for HTML export, @code{:html-scale}) -property of the former can be used to adjust the size of the preview -images. - -@table @asis -@item @kbd{C-c C-x C-l} (@code{org-latex-preview}) -@kindex C-c C-x C-l -@findex org-latex-preview - -Produce a preview image of the @LaTeX{} fragment at point and overlay -it over the source code. If there is no fragment at point, process -all fragments in the current entry---between two headlines. - -When called with a single prefix argument, clear all images in the -current entry. Two prefix arguments produce a preview image for all -fragments in the buffer, while three of them clear all the images in -that buffer. -@end table - -@vindex org-startup-with-latex-preview -You can turn on the previewing of all @LaTeX{} fragments in a file with - -@example -#+STARTUP: latexpreview -@end example - - -To disable it, simply use - -@example -#+STARTUP: nolatexpreview -@end example - -@node CD@LaTeX{} mode -@subsection Using CD@LaTeX{} to enter math - -@cindex CD@LaTeX{} - -CD@LaTeX{} mode is a minor mode that is normally used in combination with -a major @LaTeX{} mode like AUC@TeX{} in order to speed-up insertion of -environments and math templates. Inside Org mode, you can make use of -some of the features of CD@LaTeX{} mode. You need to install -@samp{cdlatex.el} and @samp{texmathp.el} (the latter comes also with AUC@TeX{}) -using @uref{https://melpa.org/, MELPA} with the @uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Package-Installation.html, Emacs packaging system} or alternatively from -@uref{https://staff.fnwi.uva.nl/c.dominik/Tools/cdlatex/}. Do not use -CD@LaTeX{} mode itself under Org mode, but use the special version Org -CD@LaTeX{} minor mode that comes as part of Org. Turn it on for the -current buffer with @kbd{M-x org-cdlatex-mode}, or for all Org -files with - -@lisp -(add-hook 'org-mode-hook 'turn-on-org-cdlatex) -@end lisp - -When this mode is enabled, the following features are present (for -more details see the documentation of CD@LaTeX{} mode): - -@table @asis -@item @kbd{C-c @{} -@kindex C-c @{ - -Insert an environment template. - -@item @kbd{@key{TAB}} -@kindex TAB - -The @kbd{@key{TAB}} key expands the template if point is inside -a @LaTeX{} fragment@footnote{Org mode has a method to test if point is inside such -a fragment, see the documentation of the function -@code{org-inside-LaTeX-fragment-p}.}. For example, @kbd{@key{TAB}} expands @samp{fr} -to @samp{\frac@{@}@{@}} and position point correctly inside the first brace. -Another @kbd{@key{TAB}} gets you into the second brace. - -Even outside fragments, @kbd{@key{TAB}} expands environment -abbreviations at the beginning of a line. For example, if you write -@samp{equ} at the beginning of a line and press @kbd{@key{TAB}}, this -abbreviation is expanded to an @samp{equation} environment. To get -a list of all abbreviations, type @kbd{M-x cdlatex-command-help}. - -@item @kbd{^} -@itemx @kbd{_} -@kindex _ -@kindex ^ -@vindex cdlatex-simplify-sub-super-scripts - -Pressing @kbd{_} and @kbd{^} inside a @LaTeX{} fragment -inserts these characters together with a pair of braces. If you use -@kbd{@key{TAB}} to move out of the braces, and if the braces surround -only a single character or macro, they are removed again (depending -on the variable @code{cdlatex-simplify-sub-super-scripts}). - -@item @kbd{`} -@kindex ` - -Pressing the backquote followed by a character inserts math macros, -also outside @LaTeX{} fragments. If you wait more than 1.5 seconds -after the backquote, a help window pops up. - -@item @kbd{'} -@kindex ' - -Pressing the single-quote followed by another character modifies the -symbol before point with an accent or a font. If you wait more than -1.5 seconds after the single-quote, a help window pops up. -Character modification works only inside @LaTeX{} fragments; outside -the quote is normal. -@end table - -@node Literal Examples -@section Literal Examples - -@cindex literal examples, markup rules -@cindex code line references, markup rules - -You can include literal examples that should not be subjected to -markup. Such examples are typeset in monospace, so this is well -suited for source code and similar examples. - -@cindex @samp{BEGIN_EXAMPLE} -@cindex example block -@example -#+BEGIN_EXAMPLE - Some example from a text file. -#+END_EXAMPLE -@end example - -@cindex comma escape, in literal examples -There is one limitation, however. You must insert a comma right -before lines starting with either @samp{*}, @samp{,*}, @samp{#+} or @samp{,#+}, as those -may be interpreted as outlines nodes or some other special syntax. -Org transparently strips these additional commas whenever it accesses -the contents of the block. - -@example -#+BEGIN_EXAMPLE -,* I am no real headline -#+END_EXAMPLE -@end example - -For simplicity when using small examples, you can also start the -example lines with a colon followed by a space. There may also be -additional whitespace before the colon: - -@example -Here is an example - : Some example from a text file. -@end example - -@cindex formatting source code, markup rules -@vindex org-latex-listings -If the example is source code from a programming language, or any -other text that can be marked up by Font Lock in Emacs, you can ask -for the example to look like the fontified Emacs buffer@footnote{This works automatically for the HTML backend (it requires -version 1.34 of the @samp{htmlize.el} package, which you need to install). -Fontified code chunks in @LaTeX{} can be achieved using either the -@uref{https://www.ctan.org/pkg/listings, listings} package or the @uref{https://www.ctan.org/pkg/minted, minted} package. Refer to -@code{org-export-latex-listings} for details.}. This -is done with the code block, where you also need to specify the name -of the major mode that should be used to fontify the example@footnote{Source code in code blocks may also be evaluated either -interactively or on export. See @ref{Working with Source Code} for more -information on evaluating code blocks.}, -see @ref{Structure Templates} for shortcuts to easily insert code blocks. - -@cindex @samp{BEGIN_SRC} -@cindex source block -@example -#+BEGIN_SRC emacs-lisp - (defun org-xor (a b) - "Exclusive or." - (if a (not b) b)) - #+END_SRC -@end example - -Both in @samp{example} and in @samp{src} snippets, you can add a @samp{-n} switch to -the end of the @samp{#+BEGIN} line, to get the lines of the example -numbered. The @samp{-n} takes an optional numeric argument specifying the -starting line number of the block. If you use a @samp{+n} switch, the -numbering from the previous numbered snippet is continued in the -current one. The @samp{+n} switch can also take a numeric argument. This -adds the value of the argument to the last line of the previous block -to determine the starting line number. - -@example -#+BEGIN_SRC emacs-lisp -n 20 - ;; This exports with line number 20. - (message "This is line 21") -#+END_SRC - -#+BEGIN_SRC emacs-lisp +n 10 - ;; This is listed as line 31. - (message "This is line 32") -#+END_SRC -@end example - -In literal examples, Org interprets strings like @samp{(ref:name)} as -labels, and use them as targets for special hyperlinks like -@samp{[[(name)]]}---i.e., the reference name enclosed in single parenthesis. -In HTML, hovering the mouse over such a link remote-highlights the -corresponding code line, which is kind of cool. - -You can also add a @samp{-r} switch which @emph{removes} the labels from the -source code@footnote{Adding @samp{-k} to @samp{-n -r} @emph{keeps} the labels in the source code -while using line numbers for the links, which might be useful to -explain those in an Org mode example code.}. With the @samp{-n} switch, links to these references -are labeled by the line numbers from the code listing. Otherwise -links use the labels with no parentheses. Here is an example: - -@example -#+BEGIN_SRC emacs-lisp -n -r - (save-excursion (ref:sc) - (goto-char (point-min)) (ref:jump) -#+END_SRC -In line [[(sc)]] we remember the current position. [[(jump)][Line (jump)]] -jumps to point-min. -@end example - -@cindex indentation, in source blocks -Source code and examples may be @emph{indented} in order to align nicely -with the surrounding text, and in particular with plain list structure -(see @ref{Plain Lists}). By default, Org only retains the relative -indentation between lines, e.g., when exporting the contents of the -block. However, you can use the @samp{-i} switch to also preserve the -global indentation, if it does matter. See @ref{Editing Source Code}. - -@vindex org-coderef-label-format -If the syntax for the label format conflicts with the language syntax, -use a @samp{-l} switch to change the format, for example - -@example -#+BEGIN_SRC pascal -n -r -l "((%s))" -@end example - - -@noindent -See also the variable @code{org-coderef-label-format}. - -HTML export also allows examples to be published as text areas (see -@ref{Text areas in HTML export}). - -Because the @samp{#+BEGIN} @dots{} @samp{#+END} patterns need to be added so often, -a shortcut is provided (see @ref{Structure Templates}). - -@table @asis -@item @kbd{C-c '} (@code{org-edit-special}) -@kindex C-c ' -@findex org-edit-special -Edit the source code example at point in its native mode. This -works by switching to a temporary buffer with the source code. You -need to exit by pressing @kbd{C-c '} again. The edited version -then replaces the old version in the Org buffer. Fixed-width -regions---where each line starts with a colon followed by -a space---are edited using Artist mode@footnote{You may select a different mode with the variable -@code{org-edit-fixed-width-region-mode}.} to allow creating -ASCII drawings easily. Using this command in an empty line creates -a new fixed-width region. -@end table - -@cindex storing link, in a source code buffer -Calling @code{org-store-link} (see @ref{Handling Links}) while editing a source -code example in a temporary buffer created with @kbd{C-c '} -prompts for a label. Make sure that it is unique in the current -buffer, and insert it with the proper formatting like @samp{(ref:label)} at -the end of the current line. Then the label is stored as a link -@samp{(label)}, for retrieval with @kbd{C-c C-l}. - -@node Images -@section Images - -@cindex inlining images -@cindex images, markup rules -An image is a link to an image file@footnote{What Emacs considers to be an image depends on -@code{image-file-name-extensions} and @code{image-file-name-regexps}.} that does not have -a description part, for example - -@example -./img/cat.jpg -@end example - - -If you wish to define a caption for the image (see @ref{Captions}) and -maybe a label for internal cross references (see @ref{Internal Links}), -make sure that the link is on a line by itself and precede it with -@samp{CAPTION} and @samp{NAME} keywords as follows: - -@example -#+CAPTION: This is the caption for the next figure link (or table) -#+NAME: fig:SED-HR4049 -[[./img/a.jpg]] -@end example - -Such images can be displayed within the buffer with the following -command: - -@table @asis -@item @kbd{C-c C-x C-v} (@code{org-toggle-inline-images}) -@kindex C-c C-x C-v -@findex org-toggle-inline-images -@vindex org-startup-with-inline-images -Toggle the inline display of linked images. When called with -a prefix argument, also display images that do have a link -description. You can ask for inline images to be displayed at -startup by configuring the variable -@code{org-startup-with-inline-images}@footnote{The variable @code{org-startup-with-inline-images} can be set -within a buffer with the @samp{STARTUP} options @samp{inlineimages} and -@samp{noinlineimages}.}. -@end table - -@node Captions -@section Captions - -@cindex captions, markup rules -@cindex @samp{CAPTION}, keyword - -You can assign a caption to a specific part of a document by inserting -a @samp{CAPTION} keyword immediately before it: - -@example -#+CAPTION: This is the caption for the next table (or link) -| ... | ... | -|-----+-----| -@end example - -Optionally, the caption can take the form: - -@example -#+CAPTION[Short caption]: Longer caption. -@end example - - -Even though images and tables are prominent examples of captioned -structures, the same caption mechanism can apply to many -others---e.g., @LaTeX{} equations, source code blocks. Depending on the -export back-end, those may or may not be handled. - -@node Horizontal Rules -@section Horizontal Rules - -@cindex horizontal rules, markup rules -A line consisting of only dashes, and at least 5 of them, is exported -as a horizontal line. - -@node Creating Footnotes -@section Creating Footnotes - -@cindex footnotes - -A footnote is started by a footnote marker in square brackets in -column 0, no indentation allowed. It ends at the next footnote -definition, headline, or after two consecutive empty lines. The -footnote reference is simply the marker in square brackets, inside -text. Markers always start with @samp{fn:}. For example: - -@example -The Org homepage[fn:1] now looks a lot better than it used to. -... -[fn:1] The link is: https://orgmode.org -@end example - -Org mode extends the number-based syntax to @emph{named} footnotes and -optional inline definition. Here are the valid references: - -@table @asis -@item @samp{[fn:NAME]} -A named footnote reference, where @var{NAME} is a unique -label word, or, for simplicity of automatic creation, a number. - -@item @samp{[fn:: This is the inline definition of this footnote]} -An anonymous footnote where the definition is given directly at the -reference point. - -@item @samp{[fn:NAME: a definition]} -An inline definition of a footnote, which also specifies a name for -the note. Since Org allows multiple references to the same note, -you can then use @samp{[fn:NAME]} to create additional references. -@end table - -@vindex org-footnote-auto-label -Footnote labels can be created automatically, or you can create names -yourself. This is handled by the variable @code{org-footnote-auto-label} -and its corresponding @samp{STARTUP} keywords. See the docstring of that -variable for details. - -The following command handles footnotes: - -@table @asis -@item @kbd{C-c C-x f} -The footnote action command. - -@kindex C-c C-x f -When point is on a footnote reference, jump to the definition. When -it is at a definition, jump to the---first---reference. - -@vindex org-footnote-define-inline -@vindex org-footnote-section -Otherwise, create a new footnote. Depending on the variable -@code{org-footnote-define-inline}@footnote{The corresponding in-buffer setting is: @samp{#+STARTUP: fninline} -or @samp{#+STARTUP: nofninline}.}, the definition is placed right -into the text as part of the reference, or separately into the -location determined by the variable @code{org-footnote-section}. - -When this command is called with a prefix argument, a menu of -additional options is offered: - -@multitable @columnfractions 0.1 0.9 -@item @kbd{s} -@tab Sort the footnote definitions by reference sequence. -@item @kbd{r} -@tab Renumber the simple @samp{fn:N} footnotes. -@item @kbd{S} -@tab Short for first @kbd{r}, then @kbd{s} action. -@item @kbd{n} -@tab Rename all footnotes into a @samp{fn:1} @dots{} @samp{fn:n} sequence. -@item @kbd{d} -@tab Delete the footnote at point, including definition and references. -@end multitable - -@vindex org-footnote-auto-adjust -Depending on the variable @code{org-footnote-auto-adjust}@footnote{The corresponding in-buffer options are @samp{#+STARTUP: fnadjust} -and @samp{#+STARTUP: nofnadjust}.}, -renumbering and sorting footnotes can be automatic after each -insertion or deletion. - -@item @kbd{C-c C-c} -@kindex C-c C-c -If point is on a footnote reference, jump to the definition. If it -is at the definition, jump back to the reference. When called at -a footnote location with a prefix argument, offer the same menu as -@kbd{C-c C-x f}. - -@item @kbd{C-c C-o} or @kbd{mouse-1/2} -@kindex C-c C-o -@kindex mouse-1 -@kindex mouse-2 -Footnote labels are also links to the corresponding definition or -reference, and you can use the usual commands to follow these links. -@end table - -@node Exporting -@chapter Exporting - -@cindex exporting - -At some point you might want to print your notes, publish them on the -web, or share them with people not using Org. Org can convert and -export documents to a variety of other formats while retaining as much -structure (see @ref{Document Structure}) and markup (see @ref{Markup for Rich Contents}) as possible. - -@cindex export back-end -The libraries responsible for translating Org files to other formats -are called @emph{back-ends}. Org ships with support for the following -back-ends: - -@itemize -@item -@emph{ascii} (ASCII format) -@item -@emph{beamer} (@LaTeX{} Beamer format) -@item -@emph{html} (HTML format) -@item -@emph{icalendar} (iCalendar format) -@item -@emph{latex} (@LaTeX{} format) -@item -@emph{md} (Markdown format) -@item -@emph{odt} (OpenDocument Text format) -@item -@emph{org} (Org format) -@item -@emph{texinfo} (Texinfo format) -@item -@emph{man} (Man page format) -@end itemize - -Users can install libraries for additional formats from the Emacs -packaging system. For easy discovery, these packages have a common -naming scheme: @code{ox-NAME}, where @var{NAME} is a format. For -example, @code{ox-koma-letter} for @emph{koma-letter} back-end. More libraries -can be found in the @samp{contrib/} directory (see @ref{Installation}). - -@vindex org-export-backends -Org only loads back-ends for the following formats by default: ASCII, -HTML, iCalendar, @LaTeX{}, and ODT@. Additional back-ends can be loaded -in either of two ways: by configuring the @code{org-export-backends} -variable, or by requiring libraries in the Emacs init file. For -example, to load the Markdown back-end, add this to your Emacs config: - -@lisp -(require 'ox-md) -@end lisp - -@menu -* The Export Dispatcher:: The main interface. -* Export Settings:: Common export settings. -* Table of Contents:: The if and where of the table of contents. -* Include Files:: Include additional files into a document. -* Macro Replacement:: Use macros to create templates. -* Comment Lines:: What will not be exported. -* ASCII/Latin-1/UTF-8 export:: Exporting to flat files with encoding. -* Beamer Export:: Producing presentations and slides. -* HTML Export:: Exporting to HTML. -* @LaTeX{} Export:: Exporting to @LaTeX{} and processing to PDF. -* Markdown Export:: Exporting to Markdown. -* OpenDocument Text Export:: Exporting to OpenDocument Text. -* Org Export:: Exporting to Org. -* Texinfo Export:: Exporting to Texinfo. -* iCalendar Export:: Exporting to iCalendar. -* Other Built-in Back-ends:: Exporting to a man page. -* Advanced Export Configuration:: Fine-tuning the export output. -* Export in Foreign Buffers:: Author tables and lists in Org syntax. -@end menu - -@node The Export Dispatcher -@section The Export Dispatcher - -@cindex dispatcher, for export commands -@cindex export, dispatcher - -The export dispatcher is the main interface for Org's exports. -A hierarchical menu presents the currently configured export formats. -Options are shown as easy toggle switches on the same screen. - -@vindex org-export-dispatch-use-expert-ui -Org also has a minimal prompt interface for the export dispatcher. -When the variable @code{org-export-dispatch-use-expert-ui} is set to -a non-@code{nil} value, Org prompts in the minibuffer. To switch back to -the hierarchical menu, press @kbd{?}. - -@table @asis -@item @kbd{C-c C-e} (@code{org-export}) -@kindex C-c C-e -@findex org-export - -Invokes the export dispatcher interface. The options show default -settings. The @kbd{C-u} prefix argument preserves options from -the previous export, including any sub-tree selections. -@end table - -Org exports the entire buffer by default. If the Org buffer has an -active region, then Org exports just that region. - -Within the dispatcher interface, the following key combinations can -further alter what is exported, and how. - -@table @asis -@item @kbd{C-a} -@kindex C-c C-e C-a - -Toggle asynchronous export. Asynchronous export uses an external -Emacs process with a specially configured initialization file to -complete the exporting process in the background, without tying-up -Emacs. This is particularly useful when exporting long documents. - -Output from an asynchronous export is saved on the @emph{export stack}. -To view this stack, call the export dispatcher with a double -@kbd{C-u} prefix argument. If already in the export dispatcher -menu, @kbd{&} displays the stack. - -@vindex org-export-in-background -You can make asynchronous export the default by setting -@code{org-export-in-background}. - -@vindex org-export-async-init-file -You can set the initialization file used by the background process -by setting @code{org-export-async-init-file}. - -@item @kbd{C-b} -@kindex C-c C-e C-b - -Toggle body-only export. Useful for excluding headers and footers -in the export. Affects only those back-end formats that have -sections like @samp{...} in HTML@. - -@item @kbd{C-s} -@kindex C-c C-e C-s - -Toggle sub-tree export. When turned on, Org exports only the -sub-tree starting from point position at the time the export -dispatcher was invoked. Org uses the top heading of this sub-tree -as the document's title. If point is not on a heading, Org uses the -nearest enclosing header. If point is in the document preamble, Org -signals an error and aborts export. - -@vindex org-export-initial-scope -To make sub-tree export the default, customize the variable -@code{org-export-initial-scope}. - -@item @kbd{C-v} -@kindex C-c C-e C-v - -Toggle visible-only export. This is useful for exporting only -certain parts of an Org document by adjusting the visibility of -particular headings. -@end table - -@node Export Settings -@section Export Settings - -@cindex options, for export -@cindex Export, settings - -@cindex @samp{OPTIONS}, keyword -Export options can be set: globally with variables; for an individual -file by making variables buffer-local with in-buffer settings (see -@ref{In-buffer Settings}); by setting individual keywords or -specifying them in compact form with the @samp{OPTIONS} keyword; or for -a tree by setting properties (see @ref{Properties and Columns}). Options -set at a specific level override options set at a more general level. - -@cindex @samp{SETUPFILE}, keyword -In-buffer settings may appear anywhere in the file, either directly or -indirectly through a file included using @samp{#+SETUPFILE: filename or -URL} syntax. Option keyword sets tailored to a particular back-end -can be inserted from the export dispatcher (see @ref{The Export Dispatcher}) using the @samp{Insert template} command by pressing -@kbd{#}. To insert keywords individually, a good way to make -sure the keyword is correct is to type @samp{#+} and then to use -@kbd{M-@key{TAB}}@footnote{Many desktops intercept @kbd{M-@key{TAB}} to switch windows. -Use @kbd{C-M-i} or @kbd{@key{ESC} @key{TAB}} instead.} for completion. - -The export keywords available for every back-end, and their equivalent -global variables, include: - -@table @asis -@item @samp{AUTHOR} -@cindex @samp{AUTHOR}, keyword -@vindex user-full-name -The document author (@code{user-full-name}). - -@item @samp{CREATOR} -@cindex @samp{CREATOR}, keyword -@vindex org-expot-creator-string -Entity responsible for output generation -(@code{org-export-creator-string}). - -@item @samp{DATE} -@cindex @samp{DATE}, keyword -@vindex org-export-date-timestamp-format -A date or a time-stamp@footnote{The variable @code{org-export-date-timestamp-format} defines how -this timestamp are exported.}. - -@item @samp{EMAIL} -@cindex @samp{EMAIL}, keyword -@vindex user-mail-address -The email address (@code{user-mail-address}). - -@item @samp{LANGUAGE} -@cindex @samp{LANGUAGE}, keyword -@vindex org-export-default-language -Language to use for translating certain strings -(@code{org-export-default-language}). With @samp{#+LANGUAGE: fr}, for -example, Org translates @samp{Table of contents} to the French @samp{Table des - matières}@footnote{DEFINITION NOT FOUND@.}. - -@item @samp{SELECT_TAGS} -@cindex @samp{SELECT_TAGS}, keyword -@vindex org-export-select-tags -The default value is @samp{("export")}. When a tree is tagged with -@samp{export} (@code{org-export-select-tags}), Org selects that tree and its -sub-trees for export. Org excludes trees with @samp{noexport} tags, see -below. When selectively exporting files with @samp{export} tags set, Org -does not export any text that appears before the first headline. - -@item @samp{EXCLUDE_TAGS} -@cindex @samp{EXCLUDE_TAGS}, keyword -@vindex org-export-exclude-tags -The default value is @samp{("noexport")}. When a tree is tagged with -@samp{noexport} (@code{org-export-exclude-tags}), Org excludes that tree and -its sub-trees from export. Entries tagged with @samp{noexport} are -unconditionally excluded from the export, even if they have an -@samp{export} tag. Even if a sub-tree is not exported, Org executes any -code blocks contained there. - -@item @samp{TITLE} -@cindex @samp{TITLE}, keyword -@cindex document title -Org displays this title. For long titles, use multiple @samp{#+TITLE} -lines. - -@item @samp{EXPORT_FILE_NAME} -@cindex @samp{EXPORT_FILE_NAME}, keyword -The name of the output file to be generated. Otherwise, Org -generates the file name based on the buffer name and the extension -based on the back-end format. -@end table - -The @samp{OPTIONS} keyword is a compact form. To configure multiple -options, use several @samp{OPTIONS} lines. @samp{OPTIONS} recognizes the -following arguments. - -@table @asis -@item @code{'} -@vindex org-export-with-smart-quotes -Toggle smart quotes (@code{org-export-with-smart-quotes}). Depending on -the language used, when activated, Org treats pairs of double quotes -as primary quotes, pairs of single quotes as secondary quotes, and -single quote marks as apostrophes. - -@item @code{*} -@vindex org-export-with-emphasize -Toggle emphasized text (@code{org-export-with-emphasize}). - -@item @code{-} -@vindex org-export-with-special-strings -Toggle conversion of special strings -(@code{org-export-with-special-strings}). - -@item @code{:} -@vindex org-export-with-fixed-width -Toggle fixed-width sections (@code{org-export-with-fixed-width}). - -@item @code{<} -@vindex org-export-with-timestamps -Toggle inclusion of time/date active/inactive stamps -(@code{org-export-with-timestamps}). - -@item @code{\n} -@vindex org-export-preserve-breaks -Toggles whether to preserve line breaks -(@code{org-export-preserve-breaks}). - -@item @code{^} -@vindex org-export-with-sub-superscripts -Toggle @TeX{}-like syntax for sub- and superscripts. If you write -@samp{^:@{@}}, @samp{a_@{b@}} is interpreted, but the simple @samp{a_b} is left as it -is (@code{org-export-with-sub-superscripts}). - -@item @code{arch} -@vindex org-export-with-archived-trees -Configure how archived trees are exported. When set to @code{headline}, -the export process skips the contents and processes only the -headlines (@code{org-export-with-archived-trees}). - -@item @code{author} -@vindex org-export-with-author -Toggle inclusion of author name into exported file -(@code{org-export-with-author}). - -@item @code{broken-links} -@vindex org-export-with-broken-links -Toggles if Org should continue exporting upon finding a broken -internal link. When set to @code{mark}, Org clearly marks the problem -link in the output (@code{org-export-with-broken-links}). - -@item @code{c} -@vindex org-export-with-clocks -Toggle inclusion of @samp{CLOCK} keywords (@code{org-export-with-clocks}). - -@item @code{creator} -@vindex org-export-with-creator -Toggle inclusion of creator information in the exported file -(@code{org-export-with-creator}). - -@item @code{d} -@vindex org-export-with-drawers -Toggles inclusion of drawers, or list of drawers to include, or list -of drawers to exclude (@code{org-export-with-drawers}). - -@item @code{date} -@vindex org-export-with-date -Toggle inclusion of a date into exported file -(@code{org-export-with-date}). - -@item @code{e} -@vindex org-export-with-entities -Toggle inclusion of entities (@code{org-export-with-entities}). - -@item @code{email} -@vindex org-export-with-email -Toggle inclusion of the author's e-mail into exported file -(@code{org-export-with-email}). - -@item @code{f} -@vindex org-export-with-footnotes -Toggle the inclusion of footnotes (@code{org-export-with-footnotes}). - -@item @code{H} -@vindex org-export-headline-levels -Set the number of headline levels for export -(@code{org-export-headline-levels}). Below that level, headlines are -treated differently. In most back-ends, they become list items. - -@item @code{inline} -@vindex org-export-with-inlinetasks -Toggle inclusion of inlinetasks (@code{org-export-with-inlinetasks}). - -@item @code{num} -@vindex org-export-with-section-numbers -@cindex @samp{UNNUMBERED}, property -Toggle section-numbers (@code{org-export-with-section-numbers}). When -set to number N, Org numbers only those headlines at level N or -above. Set @samp{UNNUMBERED} property to non-@code{nil} to disable numbering -of heading and subheadings entirely. Moreover, when the value is -@samp{notoc} the headline, and all its children, do not appear in the -table of contents either (see @ref{Table of Contents}). - -@item @code{p} -@vindex org-export-with-planning -Toggle export of planning information (@code{org-export-with-planning}). -``Planning information'' comes from lines located right after the -headline and contain any combination of these cookies: @samp{SCHEDULED}, -@samp{DEADLINE}, or @samp{CLOSED}. - -@item @code{pri} -@vindex org-export-with-priority -Toggle inclusion of priority cookies -(@code{org-export-with-priority}). - -@item @code{prop} -@vindex org-export-with-properties -Toggle inclusion of property drawers, or list the properties to -include (@code{org-export-with-properties}). - -@item @code{stat} -@vindex org-export-with-statistics-cookies -Toggle inclusion of statistics cookies -(@code{org-export-with-statistics-cookies}). - -@item @code{tags} -@vindex org-export-with-tags -Toggle inclusion of tags, may also be @code{not-in-toc} -(@code{org-export-with-tags}). - -@item @code{tasks} -@vindex org-export-with-tasks -Toggle inclusion of tasks (TODO items); or @code{nil} to remove all -tasks; or @code{todo} to remove done tasks; or list the keywords to keep -(@code{org-export-with-tasks}). - -@item @code{tex} -@vindex org-export-with-latex -@code{nil} does not export; @code{t} exports; @code{verbatim} keeps everything in -verbatim (@code{org-export-with-latex}). - -@item @code{timestamp} -@vindex org-export-time-stamp-file -Toggle inclusion of the creation time in the exported file -(@code{org-export-time-stamp-file}). - -@item @code{title} -@vindex org-export-with-title -Toggle inclusion of title (@code{org-export-with-title}). - -@item @code{toc} -@vindex org-export-with-toc -Toggle inclusion of the table of contents, or set the level limit -(@code{org-export-with-toc}). - -@item @code{todo} -@vindex org-export-with-todo-keywords -Toggle inclusion of TODO keywords into exported text -(@code{org-export-with-todo-keywords}). - -@item @code{|} -@vindex org-export-with-tables -Toggle inclusion of tables (@code{org-export-with-tables}). -@end table - -When exporting sub-trees, special node properties can override the -above keywords. These properties have an @samp{EXPORT_} prefix. For -example, @samp{DATE} becomes, @samp{EXPORT_DATE} when used for a specific -sub-tree. Except for @samp{SETUPFILE}, all other keywords listed above -have an @samp{EXPORT_} equivalent. - -@cindex @samp{BIND}, keyword -@vindex org-export-allow-bind-keywords -If @code{org-export-allow-bind-keywords} is non-@code{nil}, Emacs variables can -become buffer-local during export by using the @samp{BIND} keyword. Its -syntax is @samp{#+BIND: variable value}. This is particularly useful for -in-buffer settings that cannot be changed using keywords. - -@node Table of Contents -@section Table of Contents - -@cindex table of contents -@cindex list of tables -@cindex list of listings - -@cindex @samp{toc}, in @samp{OPTIONS} keyword -@vindex org-export-with-toc -The table of contents includes all headlines in the document. Its -depth is therefore the same as the headline levels in the file. If -you need to use a different depth, or turn it off entirely, set the -@code{org-export-with-toc} variable accordingly. You can achieve the same -on a per file basis, using the following @samp{toc} item in @samp{OPTIONS} -keyword: - -@example -#+OPTIONS: toc:2 (only include two levels in TOC) -#+OPTIONS: toc:nil (no default TOC at all) -@end example - -@cindex excluding entries from table of contents -@cindex table of contents, exclude entries -Org includes both numbered and unnumbered headlines in the table of -contents@footnote{At the moment, some export back-ends do not obey this -specification. For example, @LaTeX{} export excludes every unnumbered -headline from the table of contents.}. If you need to exclude an unnumbered headline, -along with all its children, set the @samp{UNNUMBERED} property to @samp{notoc} -value. - -@example -* Subtree not numbered, not in table of contents either - :PROPERTIES: - :UNNUMBERED: notoc - :END: -@end example - -@cindex @samp{TOC}, keyword -Org normally inserts the table of contents directly before the first -headline of the file. To move the table of contents to a different -location, first turn off the default with @code{org-export-with-toc} -variable or with @samp{#+OPTIONS: toc:nil}. Then insert @samp{#+TOC: headlines -N} at the desired location(s). - -@example -#+OPTIONS: toc:nil -... -#+TOC: headlines 2 -@end example - -To adjust the table of contents depth for a specific section of the -Org document, append an additional @samp{local} parameter. This parameter -becomes a relative depth for the current level. The following example -inserts a local table of contents, with direct children only. - -@example -* Section -#+TOC: headlines 1 local -@end example - -Note that for this feature to work properly in @LaTeX{} export, the Org -file requires the inclusion of the titletoc package. Because of -compatibility issues, titletoc has to be loaded @emph{before} hyperref. -Customize the @code{org-latex-default-packages-alist} variable. - -The following example inserts a table of contents that links to the -children of the specified target. - -@example -* Target - :PROPERTIES: - :CUSTOM_ID: TargetSection - :END: -** Heading A -** Heading B -* Another section -#+TOC: headlines 1 :target #TargetSection -@end example - -The @samp{:target} attribute is supported in HTML, Markdown, ODT, and ASCII export. - -Use the @samp{TOC} keyword to generate list of tables---respectively, all -listings---with captions. - -@example -#+TOC: listings -#+TOC: tables -@end example - -@cindex @samp{ALT_TITLE}, property -Normally Org uses the headline for its entry in the table of contents. -But with @samp{ALT_TITLE} property, a different entry can be specified for -the table of contents. - -@node Include Files -@section Include Files - -@cindex include files, during export -@cindex export, include files -@cindex @samp{INCLUDE}, keyword - -During export, you can include the content of another file. For -example, to include your @samp{.emacs} file, you could use: - -@example -#+INCLUDE: "~/.emacs" src emacs-lisp -@end example - - -@noindent -The first parameter is the file name to include. The optional second -parameter specifies the block type: @samp{example}, @samp{export} or @samp{src}. The -optional third parameter specifies the source code language to use for -formatting the contents. This is relevant to both @samp{export} and @samp{src} -block types. - -If an included file is specified as having a markup language, Org -neither checks for valid syntax nor changes the contents in any way. -For example and source blocks, Org code-escapes the contents before -inclusion. - -@cindex @samp{minlevel}, include -If an included file is not specified as having any markup language, -Org assumes it be in Org format and proceeds as usual with a few -exceptions. Org makes the footnote labels (see @ref{Creating Footnotes}) -in the included file local to that file. The contents of the included -file belong to the same structure---headline, item---containing the -@samp{INCLUDE} keyword. In particular, headlines within the file become -children of the current section. That behavior can be changed by -providing an additional keyword parameter, @samp{:minlevel}. It shifts the -headlines in the included file to become the lowest level. For -example, this syntax makes the included file a sibling of the current -top-level headline: - -@example -#+INCLUDE: "~/my-book/chapter2.org" :minlevel 1 -@end example - - -@cindex @samp{lines}, include -Inclusion of only portions of files are specified using ranges -parameter with @samp{:lines} keyword. The line at the upper end of the -range will not be included. The start and/or the end of the range may -be omitted to use the obvious defaults. - -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{#+INCLUDE: "~/.emacs" :lines "5-10"} -@tab Include lines 5 to 10, 10 excluded -@item @samp{#+INCLUDE: "~/.emacs" :lines "-10"} -@tab Include lines 1 to 10, 10 excluded -@item @samp{#+INCLUDE: "~/.emacs" :lines "10-"} -@tab Include lines from 10 to EOF -@end multitable - -Inclusions may specify a file-link to extract an object matched by -@code{org-link-search}@footnote{Note that @code{org-link-search-must-match-exact-headline} is -locally bound to non-@code{nil}. Therefore, @code{org-link-search} only matches -headlines and named elements.} (see @ref{Search Options}). The -ranges for @samp{:lines} keyword are relative to the requested element. -Therefore, - -@example -#+INCLUDE: "./paper.org::*conclusion" :lines 1-20 -@end example - - -@noindent -includes the first 20 lines of the headline named @samp{conclusion}. - -@cindex @samp{only-contents}, include -To extract only the contents of the matched object, set -@samp{:only-contents} property to non-@code{nil}. This omits any planning lines -or property drawers. For example, to include the body of the heading -with the custom ID @samp{theory}, you can use - -@example -#+INCLUDE: "./paper.org::#theory" :only-contents t -@end example - - -The following command allows navigating to the included document: - -@table @asis -@item @kbd{C-c '} (@code{org-edit~special}) -@kindex C-c ' -@findex org-edit-special - -Visit the included file at point. -@end table - -@node Macro Replacement -@section Macro Replacement - -@cindex macro replacement, during export -@cindex @samp{MACRO}, keyword - -@vindex org-export-global-macros -Macros replace text snippets during export. Macros are defined -globally in @code{org-export-global-macros}, or document-wise with the -following syntax: - -@example -#+MACRO: name replacement text; $1, $2 are arguments -@end example - - -@noindent -which can be referenced using @samp{@{@{@{name(arg1, arg2)@}@}@}}@footnote{Since commas separate the arguments, commas within arguments -have to be escaped with the backslash character. So only those -backslash characters before a comma need escaping with another -backslash character.}. For -example - -@example -#+MACRO: poem Rose is $1, violet's $2. Life's ordered: Org assists you. -@{@{@{poem(red,blue)@}@}@} -@end example - -@noindent -becomes - -@example -Rose is red, violet's blue. Life's ordered: Org assists you. -@end example - - -As a special case, Org parses any replacement text starting with -@samp{(eval} as an Emacs Lisp expression and evaluates it accordingly. -Within such templates, arguments become strings. Thus, the following -macro - -@example -#+MACRO: gnustamp (eval (concat "GNU/" (capitalize $1))) -@end example - - -@noindent -turns @samp{@{@{@{gnustamp(linux)@}@}@}} into @samp{GNU/Linux} during export. - -Org recognizes macro references in following Org markup areas: -paragraphs, headlines, verse blocks, tables cells and lists. Org also -recognizes macro references in keywords, such as @samp{CAPTION}, @samp{TITLE}, -@samp{AUTHOR}, @samp{DATE}, and for some back-end specific export options. - -Org comes with following pre-defined macros: - -@table @asis -@item @samp{@{@{@{keyword(NAME)@}@}@}} -@itemx @samp{@{@{@{title@}@}@}} -@itemx @samp{@{@{@{author@}@}@}} -@itemx @samp{@{@{@{email@}@}@}} -@cindex @samp{keyword}, macro -@cindex @samp{title}, macro -@cindex @samp{author}, macro -@cindex @samp{email}, macro -The @samp{keyword} macro collects all values from @var{NAME} -keywords throughout the buffer, separated with white space. -@samp{title}, @samp{author} and @samp{email} macros are shortcuts for, -respectively, @samp{@{@{@{keyword(TITLE)@}@}@}}, @samp{@{@{@{keyword(AUTHOR)@}@}@}} and -@samp{@{@{@{keyword(EMAIL)@}@}@}}. - -@item @samp{@{@{@{date@}@}@}} -@itemx @samp{@{@{@{date(FORMAT)@}@}@}} -@cindex @samp{date}, macro -This macro refers to the @samp{DATE} keyword. @var{FORMAT} is an -optional argument to the @samp{date} macro that is used only if @samp{DATE} is -a single timestamp. @var{FORMAT} should be a format string -understood by @code{format-time-string}. - -@item @samp{@{@{@{time(FORMAT)@}@}@}} -@itemx @samp{@{@{@{modification-time(FORMAT, VC)@}@}@}} -@cindex @samp{time}, macro -@cindex @samp{modification-time}, macro -These macros refer to the document's date and time of export and -date and time of modification. @var{FORMAT} is a string -understood by @code{format-time-string}. If the second argument to the -@code{modification-time} macro is non-@code{nil}, Org uses @samp{vc.el} to retrieve -the document's modification time from the version control system. -Otherwise Org reads the file attributes. - -@item @samp{@{@{@{input-file@}@}@}} -@cindex @samp{input-file}, macro -This macro refers to the filename of the exported file. - -@item @samp{@{@{@{property(PROPERTY-NAME)@}@}@}} -@itemx @samp{@{@{@{property(PROPERTY-NAME, SEARCH OPTION)@}@}@}} -@cindex @samp{property}, macro -This macro returns the value of property @var{PROPERTY-NAME} in -the current entry. If @var{SEARCH-OPTION} (see @ref{Search Options}) refers to a remote entry, use it instead. - -@item @samp{@{@{@{n@}@}@}} -@itemx @samp{@{@{@{n(NAME)@}@}@}} -@itemx @samp{@{@{@{n(NAME, ACTION)@}@}@}} -@cindex @samp{n}, macro -@cindex counter, macro -This macro implements custom counters by returning the number of -times the macro has been expanded so far while exporting the buffer. -You can create more than one counter using different @var{NAME} -values. If @var{ACTION} is @samp{-}, previous value of the counter -is held, i.e., the specified counter is not incremented. If the -value is a number, the specified counter is set to that value. If -it is any other non-empty string, the specified counter is reset -to 1. You may leave @var{NAME} empty to reset the default -counter. -@end table - -@cindex @samp{results}, macro -Moreover, inline source blocks (see @ref{Structure of Code Blocks}) use the -special @samp{results} macro to mark their output. As such, you are -advised against re-defining it, unless you know what you are doing. - -@vindex org-hide-macro-markers -The surrounding brackets can be made invisible by setting -@code{org-hide-macro-markers} to a non-@code{nil} value. - -Org expands macros at the very beginning of the export process. - -@node Comment Lines -@section Comment Lines - -@cindex exporting, not - -@cindex comment lines -Lines starting with zero or more whitespace characters followed by one -@samp{#} and a whitespace are treated as comments and, as such, are not -exported. - -@cindex @samp{BEGIN_COMMENT} -@cindex comment block -Likewise, regions surrounded by @samp{#+BEGIN_COMMENT} @dots{} @samp{#+END_COMMENT} -are not exported. - -@cindex comment trees -Finally, a @samp{COMMENT} keyword at the beginning of an entry, but after -any other keyword or priority cookie, comments out the entire subtree. -In this case, the subtree is not exported and no code block within it -is executed either@footnote{For a less drastic behavior, consider using a select tag (see -@ref{Export Settings}) instead.}. The command below helps changing the -comment status of a headline. - -@table @asis -@item @kbd{C-c ;} (@code{org-toggle-comment}) -@kindex C-c ; -@findex org-toggle-comment - -Toggle the @samp{COMMENT} keyword at the beginning of an entry. -@end table - -@node ASCII/Latin-1/UTF-8 export -@section ASCII/Latin-1/UTF-8 export - -@cindex ASCII export -@cindex Latin-1 export -@cindex UTF-8 export - -ASCII export produces an output file containing only plain ASCII -characters. This is the simplest and most direct text output. It -does not contain any Org markup. Latin-1 and UTF-8 export use -additional characters and symbols available in these encoding -standards. All three of these export formats offer the most basic of -text output for maximum portability. - -@vindex org-ascii-text-width -On export, Org fills and justifies text according to the text width -set in @code{org-ascii-text-width}. - -@vindex org-ascii-links-to-notes -Org exports links using a footnote-like style where the descriptive -part is in the text and the link is in a note before the next heading. -See the variable @code{org-ascii-links-to-notes} for details. - -@anchor{ASCII export commands} -@subheading ASCII export commands - -@table @asis -@item @kbd{C-c C-e t a} (@code{org-ascii-export-to-ascii}) -@itemx @kbd{C-c C-e t l} -@itemx @kbd{C-c C-e t u} -@kindex C-c C-e t a -@kindex C-c C-e t l -@kindex C-c C-e t u -@findex org-ascii-export-to-ascii - -Export as an ASCII file with a @samp{.txt} extension. For @samp{myfile.org}, -Org exports to @samp{myfile.txt}, overwriting without warning. For -@samp{myfile.txt}, Org exports to @samp{myfile.txt.txt} in order to prevent -data loss. - -@item @kbd{C-c C-e t A} (@code{org-ascii-export-to-ascii}) -@itemx @kbd{C-c C-e t L} -@itemx @kbd{C-c C-e t U} -@kindex C-c C-e t A -@kindex C-c C-e t L -@kindex C-c C-e t U -@findex org-ascii-export-as-ascii - -Export to a temporary buffer. Does not create a file. -@end table - -@anchor{ASCII specific export settings} -@subheading ASCII specific export settings - -The ASCII export back-end has one extra keyword for customizing ASCII -output. Setting this keyword works similar to the general options -(see @ref{Export Settings}). - -@table @asis -@item @samp{SUBTITLE} -@cindex @samp{SUBTITLE}, keyword -The document subtitle. For long subtitles, use multiple -@samp{#+SUBTITLE} lines in the Org file. Org prints them on one -continuous line, wrapping into multiple lines if necessary. -@end table - -@anchor{Header and sectioning structure} -@subheading Header and sectioning structure - -Org converts the first three outline levels into headlines for ASCII -export. The remaining levels are turned into lists. To change this -cut-off point where levels become lists, see @ref{Export Settings}. - -@anchor{Quoting ASCII text} -@subheading Quoting ASCII text - -To insert text within the Org file by the ASCII back-end, use one the -following constructs, inline, keyword, or export block: - -@cindex @samp{ASCII}, keyword -@cindex @samp{BEGIN_EXPORT ascii} -@example -Inline text @@@@ascii:and additional text@@@@ within a paragraph. - -#+ASCII: Some text - -#+BEGIN_EXPORT ascii -Org exports text in this block only when using ASCII back-end. -#+END_EXPORT -@end example - -@anchor{ASCII specific attributes} -@subheading ASCII specific attributes - -@cindex @samp{ATTR_ASCII}, keyword -@cindex horizontal rules, in ASCII export - -ASCII back-end recognizes only one attribute, @samp{:width}, which -specifies the width of a horizontal rule in number of characters. The -keyword and syntax for specifying widths is: - -@example -#+ATTR_ASCII: :width 10 ------ -@end example - -@anchor{ASCII special blocks} -@subheading ASCII special blocks - -@cindex special blocks, in ASCII export -@cindex @samp{BEGIN_JUSTIFYLEFT} -@cindex @samp{BEGIN_JUSTIFYRIGHT} - -Besides @samp{#+BEGIN_CENTER} blocks (see @ref{Paragraphs}), ASCII back-end has -these two left and right justification blocks: - -@example -#+BEGIN_JUSTIFYLEFT -It's just a jump to the left... -#+END_JUSTIFYLEFT - -#+BEGIN_JUSTIFYRIGHT -...and then a step to the right. -#+END_JUSTIFYRIGHT -@end example - -@node Beamer Export -@section Beamer Export - -@cindex Beamer export - -Org uses Beamer export to convert an Org file tree structure into -high-quality interactive slides for presentations. Beamer is a @LaTeX{} -document class for creating presentations in PDF, HTML, and other -popular display formats. - -@menu -* Beamer export commands:: For creating Beamer documents. -* Beamer specific export settings:: For customizing Beamer export. -* Frames and Blocks in Beamer:: For composing Beamer slides. -* Beamer specific syntax:: For using in Org documents. -* Editing support:: Editing support. -* A Beamer example:: A complete presentation. -@end menu - -@node Beamer export commands -@subsection Beamer export commands - -@table @asis -@item @kbd{C-c C-e l b} (@code{org-beamer-export-to-latex}) -@kindex C-c C-e l b -@findex org-beamer-export-to-latex - -Export as @LaTeX{} file with a @samp{.tex} extension. For @samp{myfile.org}, Org -exports to @samp{myfile.tex}, overwriting without warning. - -@item @kbd{C-c C-e l B} (@code{org-beamer-export-as-latex}) -@kindex C-c C-e l B -@findex org-beamer-export-as-latex - -Export to a temporary buffer. Does not create a file. - -@item @kbd{C-c C-e l P} (@code{org-beamer-export-to-pdf}) -@kindex C-c C-e l P -@findex org-beamer-export-to-pdf - -Export as @LaTeX{} file and then convert it to PDF format. - -@item @kbd{C-c C-e l O} -@kindex C-c C-e l O - -Export as @LaTeX{} file, convert it to PDF format, and then open the -PDF file. -@end table - -@node Beamer specific export settings -@subsection Beamer specific export settings - -Beamer export back-end has several additional keywords for customizing -Beamer output. These keywords work similar to the general options -settings (see @ref{Export Settings}). - -@table @asis -@item @samp{BEAMER_THEME} -@cindex @samp{BEAMER_THEME}, keyword -@vindex org-beamer-theme -The Beamer layout theme (@code{org-beamer-theme}). Use square brackets -for options. For example: - -@example -#+BEAMER_THEME: Rochester [height=20pt] -@end example - -@item @samp{BEAMER_FONT_THEME} -@cindex @samp{BEAMER_FONT_THEME}, keyword -The Beamer font theme. - -@item @samp{BEAMER_INNER_THEME} -@cindex @samp{BEAMER_INNER_THEME}, keyword -The Beamer inner theme. - -@item @samp{BEAMER_OUTER_THEME} -@cindex @samp{BEAMER_OUTER_THEME}, keyword -The Beamer outer theme. - -@item @samp{BEAMER_HEADER} -@cindex @samp{BEAMER_HEADER}, keyword -Arbitrary lines inserted in the preamble, just before the @samp{hyperref} -settings. - -@item @samp{DESCRIPTION} -@cindex @samp{DESCRIPTION}, keyword -The document description. For long descriptions, use multiple -@samp{DESCRIPTION} keywords. By default, @samp{hyperref} inserts -@samp{DESCRIPTION} as metadata. Use @code{org-latex-hyperref-template} to -configure document metadata. Use @code{org-latex-title-command} to -configure typesetting of description as part of front matter. - -@item @samp{KEYWORDS} -@cindex @samp{KEYWORDS}, keyword -The keywords for defining the contents of the document. Use -multiple @samp{KEYWORDS} lines if necessary. By default, @samp{hyperref} -inserts @samp{KEYWORDS} as metadata. Use @code{org-latex-hyperref-template} -to configure document metadata. Use @code{org-latex-title-command} to -configure typesetting of keywords as part of front matter. - -@item @samp{SUBTITLE} -@cindex @samp{SUBTITLE}, keyword -Document's subtitle. For typesetting, use -@code{org-beamer-subtitle-format} string. Use -@code{org-latex-hyperref-template} to configure document metadata. Use -@code{org-latex-title-command} to configure typesetting of subtitle as -part of front matter. -@end table - -@node Frames and Blocks in Beamer -@subsection Frames and Blocks in Beamer - -Org transforms heading levels into Beamer's sectioning elements, -frames and blocks. Any Org tree with a not-too-deep-level nesting -should in principle be exportable as a Beamer presentation. - -@itemize -@item -@vindex org-beamer-frame-level -Org headlines become Beamer frames when the heading level in Org is -equal to @code{org-beamer-frame-level} or @samp{H} value in a @samp{OPTIONS} line -(see @ref{Export Settings}). - -@cindex @samp{BEAMER_ENV}, property -Org overrides headlines to frames conversion for the current tree of -an Org file if it encounters the @samp{BEAMER_ENV} property set to -@samp{frame} or @samp{fullframe}. Org ignores whatever -@code{org-beamer-frame-level} happens to be for that headline level in -the Org tree. In Beamer terminology, a full frame is a frame -without its title. - -@item -Org exports a Beamer frame's objects as block environments. Org can -enforce wrapping in special block types when @samp{BEAMER_ENV} property -is set@footnote{If @samp{BEAMER_ENV} is set, Org export adds @samp{B_environment} tag -to make it visible. The tag serves as a visual aid and has no -semantic relevance.}. For valid values see -@code{org-beamer-environments-default}. To add more values, see -@code{org-beamer-environments-extra}. -@vindex org-beamer-environments-default -@vindex org-beamer-environments-extra - -@item -@cindex @samp{BEAMER_REF}, property -If @samp{BEAMER_ENV} is set to @samp{appendix}, Org exports the entry as an -appendix. When set to @samp{note}, Org exports the entry as a note -within the frame or between frames, depending on the entry's heading -level. When set to @samp{noteNH}, Org exports the entry as a note -without its title. When set to @samp{againframe}, Org exports the entry -with @samp{\againframe} command, which makes setting the @samp{BEAMER_REF} -property mandatory because @samp{\againframe} needs frame to resume. - -When @samp{ignoreheading} is set, Org export ignores the entry's headline -but not its content. This is useful for inserting content between -frames. It is also useful for properly closing a @samp{column} -environment. @@end itemize - -@cindex @samp{BEAMER_ACT}, property -@cindex @samp{BEAMER_OPT}, property -When @samp{BEAMER_ACT} is set for a headline, Org export translates that -headline as an overlay or action specification. When enclosed in -square brackets, Org export makes the overlay specification -a default. Use @samp{BEAMER_OPT} to set any options applicable to the -current Beamer frame or block. The Beamer export back-end wraps -with appropriate angular or square brackets. It also adds the -@samp{fragile} option for any code that may require a verbatim block. - -@cindex @samp{BEAMER_COL}, property -To create a column on the Beamer slide, use the @samp{BEAMER_COL} -property for its headline in the Org file. Set the value of -@samp{BEAMER_COL} to a decimal number representing the fraction of the -total text width. Beamer export uses this value to set the column's -width and fills the column with the contents of the Org entry. If -the Org entry has no specific environment defined, Beamer export -ignores the heading. If the Org entry has a defined environment, -Beamer export uses the heading as title. Behind the scenes, Beamer -export automatically handles @LaTeX{} column separations for contiguous -headlines. To manually adjust them for any unique configurations -needs, use the @samp{BEAMER_ENV} property. -@end itemize - -@node Beamer specific syntax -@subsection Beamer specific syntax - -Since Org's Beamer export back-end is an extension of the @LaTeX{} -back-end, it recognizes other @LaTeX{} specific syntax---for example, -@samp{#+LATEX:} or @samp{#+ATTR_LATEX:}. See @ref{@LaTeX{} Export}, for details. - -Beamer export wraps the table of contents generated with @samp{toc:t} -@samp{OPTION} keyword in a @samp{frame} environment. Beamer export does not -wrap the table of contents generated with @samp{TOC} keyword (see @ref{Table of Contents}). Use square brackets for specifying options. - -@example -#+TOC: headlines [currentsection] -@end example - - -Insert Beamer-specific code using the following constructs: - -@cindex @samp{BEAMER}, keyword -@cindex @samp{BEGIN_EXPORT beamer} -@example -#+BEAMER: \pause - -#+BEGIN_EXPORT beamer - Only Beamer export back-end exports this. -#+END_BEAMER - -Text @@@@beamer:some code@@@@ within a paragraph. -@end example - -Inline constructs, such as the last one above, are useful for adding -overlay specifications to objects with @code{bold}, @code{item}, @code{link}, -@code{radio-target} and @code{target} types. Enclose the value in angular -brackets and place the specification at the beginning of the object as -shown in this example: - -@example -A *@@@@beamer:<2->@@@@useful* feature -@end example - - -@cindex @samp{ATTR_BEAMER}, keyword -Beamer export recognizes the @samp{ATTR_BEAMER} keyword with the following -attributes from Beamer configurations: @samp{:environment} for changing -local Beamer environment, @samp{:overlay} for specifying Beamer overlays in -angular or square brackets, and @samp{:options} for inserting optional -arguments. - -@example -#+ATTR_BEAMER: :environment nonindentlist -- item 1, not indented -- item 2, not indented -- item 3, not indented -@end example - -@example -#+ATTR_BEAMER: :overlay <+-> -- item 1 -- item 2 -@end example - -@example -#+ATTR_BEAMER: :options [Lagrange] -Let $G$ be a finite group, and let $H$ be -a subgroup of $G$. Then the order of $H$ divides the order of $G$. -@end example - -@node Editing support -@subsection Editing support - -Org Beamer mode is a special minor mode for faster editing of Beamer -documents. - -@example -#+STARTUP: beamer -@end example - - -@table @asis -@item @kbd{C-c C-b} (@code{org-beamer-select-environment}) -@kindex C-c C-b -@findex org-beamer-select-environment - -Org Beamer mode provides this key for quicker selections in Beamer -normal environments, and for selecting the @samp{BEAMER_COL} property. -@end table - -@node A Beamer example -@subsection A Beamer example - -Here is an example of an Org document ready for Beamer export. - -@example -#+TITLE: Example Presentation -#+AUTHOR: Carsten Dominik -#+OPTIONS: H:2 toc:t num:t -#+LATEX_CLASS: beamer -#+LATEX_CLASS_OPTIONS: [presentation] -#+BEAMER_THEME: Madrid -#+COLUMNS: %45ITEM %10BEAMER_ENV(Env) %10BEAMER_ACT(Act) %4BEAMER_COL(Col) - -* This is the first structural section - -** Frame 1 -*** Thanks to Eric Fraga :B_block: - :PROPERTIES: - :BEAMER_COL: 0.48 - :BEAMER_ENV: block - :END: - for the first viable Beamer setup in Org -*** Thanks to everyone else :B_block: - :PROPERTIES: - :BEAMER_COL: 0.48 - :BEAMER_ACT: <2-> - :BEAMER_ENV: block - :END: - for contributing to the discussion -**** This will be formatted as a beamer note :B_note: - :PROPERTIES: - :BEAMER_env: note - :END: -** Frame 2 (where we will not use columns) -*** Request - Please test this stuff! -@end example - -@node HTML Export -@section HTML Export - -@cindex HTML export - -Org mode contains an HTML exporter with extensive HTML formatting -compatible with XHTML 1.0 strict standard. - -@menu -* HTML export commands:: Invoking HTML export. -* HTML specific export settings:: Settings for HTML export. -* HTML doctypes:: Exporting various (X)HTML flavors. -* HTML preamble and postamble:: Inserting preamble and postamble. -* Quoting HTML tags:: Using direct HTML in Org files. -* Headlines in HTML export:: Formatting headlines. -* Links in HTML export:: Inserting and formatting links. -* Tables in HTML export:: How to modify the formatting of tables. -* Images in HTML export:: How to insert figures into HTML output. -* Math formatting in HTML export:: Beautiful math also on the web. -* Text areas in HTML export:: An alternate way to show an example. -* CSS support:: Changing the appearance of the output. -* JavaScript support:: Info and folding in a web browser. -@end menu - -@node HTML export commands -@subsection HTML export commands - -@table @asis -@item @kbd{C-c C-e h h} (@code{org-html-export-to-html}) -@kindex C-c C-e h h -@kindex C-c C-e h o -@findex org-html-export-to-html - -Export as HTML file with a @samp{.html} extension. For @samp{myfile.org}, Org -exports to @samp{myfile.html}, overwriting without warning. @{@{@{kbd@{C-c -C-e h o)@}@}@} exports to HTML and opens it in a web browser. - -@item @kbd{C-c C-e h H} (@code{org-html-export-as-html}) -@kindex C-c C-e h H -@findex org-html-export-as-html - -Exports to a temporary buffer. Does not create a file. -@end table - -@node HTML specific export settings -@subsection HTML specific export settings - -HTML export has a number of keywords, similar to the general options -settings described in @ref{Export Settings}. - -@table @asis -@item @samp{DESCRIPTION} -@cindex @samp{DESCRIPTION}, keyword -This is the document's description, which the HTML exporter inserts -it as a HTML meta tag in the HTML file. For long descriptions, use -multiple @samp{DESCRIPTION} lines. The exporter takes care of wrapping -the lines properly. - -@item @samp{HTML_DOCTYPE} -@cindex @samp{HTML_DOCTYPE}, keyword -@vindex org-html-doctype -Specify the document type, for example: HTML5 (@code{org-html-doctype}). - -@item @samp{HTML_CONTAINER} -@cindex @samp{HTML_CONTAINER}, keyword -@vindex org-html-container-element -Specify the HTML container, such as @samp{div}, for wrapping sections and -elements (@code{org-html-container-element}). - -@item @samp{HTML_LINK_HOME} -@cindex @samp{HTML_LINK_HOME}, keyword -@vindex org-html-link-home -The URL for home link (@code{org-html-link-home}). - -@item @samp{HTML_LINK_UP} -@cindex @samp{HTML_LINK_UP}, keyword -@vindex org-html-link-up -The URL for the up link of exported HTML pages (@code{org-html-link-up}). - -@item @samp{HTML_MATHJAX} -@cindex @samp{HTML_MATHJAX}, keyword -@vindex org-html-mathjax-options -Options for MathJax (@code{org-html-mathjax-options}). MathJax is used -to typeset @LaTeX{} math in HTML documents. See @ref{Math formatting in HTML export}, for an example. - -@item @samp{HTML_HEAD} -@cindex @samp{HTML_HEAD}, keyword -@vindex org-html-head -Arbitrary lines for appending to the HTML document's head -(@code{org-html-head}). - -@item @samp{HTML_HEAD_EXTRA} -@cindex @samp{HTML_HEAD_EXTRA}, keyword -@vindex org-html-head-extra -More arbitrary lines for appending to the HTML document's head -(@code{org-html-head-extra}). - -@item @samp{KEYWORDS} -@cindex @samp{KEYWORDS}, keyword -Keywords to describe the document's content. HTML exporter inserts -these keywords as HTML meta tags. For long keywords, use multiple -@samp{KEYWORDS} lines. - -@item @samp{LATEX_HEADER} -@cindex @samp{LATEX_HEADER}, keyword -Arbitrary lines for appending to the preamble; HTML exporter appends -when transcoding @LaTeX{} fragments to images (see @ref{Math formatting in HTML export}). - -@item @samp{SUBTITLE} -@cindex @samp{SUBTITLE}, keyword -The document's subtitle. HTML exporter formats subtitle if document -type is @samp{HTML5} and the CSS has a @samp{subtitle} class. -@end table - -Some of these keywords are explained in more detail in the following -sections of the manual. - -@node HTML doctypes -@subsection HTML doctypes - -Org can export to various (X)HTML flavors. - -@vindex org-html-doctype -@vindex org-html-doctype-alist -Set the @code{org-html-doctype} variable for different (X)HTML variants. -Depending on the variant, the HTML exporter adjusts the syntax of HTML -conversion accordingly. Org includes the following ready-made -variants: - -@itemize -@item -@code{"html4-strict"} -@item -@code{"html4-transitional"} -@item -@code{"html4-frameset"} -@item -@code{"xhtml-strict"} -@item -@code{"xhtml-transitional"} -@item -@code{"xhtml-frameset"} -@item -@code{"xhtml-11"} -@item -@code{"html5"} -@item -@code{"xhtml5"} -@end itemize - -@noindent -See the variable @code{org-html-doctype-alist} for details. The default is -@code{"xhtml-strict"}. - -@vindex org-html-html5-fancy -@cindex @samp{HTML5}, export new elements -Org's HTML exporter does not by default enable new block elements -introduced with the HTML5 standard. To enable them, set -@code{org-html-html5-fancy} to non-@code{nil}. Or use an @samp{OPTIONS} line in the -file to set @samp{html5-fancy}. - -HTML5 documents can now have arbitrary @samp{#+BEGIN} @dots{} @samp{#+END} blocks. -For example: - -@example -#+BEGIN_aside - Lorem ipsum -#+END_aside -@end example - -@noindent -exports to: - -@example - -@end example - -@noindent -while this: - -@example -#+ATTR_HTML: :controls controls :width 350 -#+BEGIN_video -#+HTML: -#+HTML: -Your browser does not support the video tag. -#+END_video -@end example - -@noindent -exports to: - -@example - -@end example - -@vindex org-html-html5-elements -When special blocks do not have a corresponding HTML5 element, the -HTML exporter reverts to standard translation (see -@code{org-html-html5-elements}). For example, @samp{#+BEGIN_lederhosen} exports -to @code{
}. - -Special blocks cannot have headlines. For the HTML exporter to wrap -the headline and its contents in @code{
} or @code{
} tags, set -the @samp{HTML_CONTAINER} property for the headline. - -@node HTML preamble and postamble -@subsection HTML preamble and postamble - -@vindex org-html-preamble -@vindex org-html-postamble -@vindex org-html-preamble-format -@vindex org-html-postamble-format -@vindex org-html-validation-link -@vindex org-export-creator-string -@vindex org-export-time-stamp-file - -The HTML exporter has delineations for preamble and postamble. The -default value for @code{org-html-preamble} is @code{t}, which makes the HTML -exporter insert the preamble. See the variable -@code{org-html-preamble-format} for the format string. - -Set @code{org-html-preamble} to a string to override the default format -string. If the string is a function, the HTML exporter expects the -function to return a string upon execution. The HTML exporter inserts -this string in the preamble. The HTML exporter does not insert -a preamble if @code{org-html-preamble} is set @code{nil}. - -The default value for @code{org-html-postamble} is @code{auto}, which makes the -HTML exporter build a postamble from looking up author's name, email -address, creator's name, and date. Set @code{org-html-postamble} to @code{t} to -insert the postamble in the format specified in the -@code{org-html-postamble-format} variable. The HTML exporter does not -insert a postamble if @code{org-html-postamble} is set to @code{nil}. - -@node Quoting HTML tags -@subsection Quoting HTML tags - -The HTML export back-end transforms @samp{<} and @samp{>} to @samp{<} and @samp{>}. -To include raw HTML code in the Org file so the HTML export back-end -can insert that HTML code in the output, use this inline syntax: -@samp{@@@@html:...@@@@}. For example: - -@example -@@@@html:@@@@bold text@@@@html:@@@@ -@end example - - -@cindex @samp{HTML}, keyword -@cindex @samp{BEGIN_EXPORT html} -For larger raw HTML code blocks, use these HTML export code blocks: - -@example -#+HTML: Literal HTML code for export - -#+BEGIN_EXPORT html - All lines between these markers are exported literally -#+END_EXPORT -@end example - -@node Headlines in HTML export -@subsection Headlines in HTML export - -@cindex headlines, in HTML export - -Headlines are exported to @samp{

}, @samp{

}, etc. Each headline gets the -@samp{id} attribute from @samp{CUSTOM_ID} property, or a unique generated value, -see @ref{Internal Links}. - -@vindex org-html-self-link-headlines -When @code{org-html-self-link-headlines} is set to a non-@code{nil} value, the -text of the headlines is also wrapped in @samp{} tags. These tags have -a @samp{href} attribute making the headlines link to themselves. - -@node Links in HTML export -@subsection Links in HTML export - -@cindex links, in HTML export -@cindex internal links, in HTML export -@cindex external links, in HTML export - -The HTML export back-end transforms Org's internal links (see -@ref{Internal Links}) to equivalent HTML links in the output. The back-end -similarly handles Org's automatic links created by radio targets (see -@ref{Radio Targets}) similarly. For Org links to external files, the -back-end transforms the links to @emph{relative} paths. - -@vindex org-html-link-org-files-as-html -For Org links to other @samp{.org} files, the back-end automatically -changes the file extension to @samp{.html} and makes file paths relative. -If the @samp{.org} files have an equivalent @samp{.html} version at the same -location, then the converted links should work without any further -manual intervention. However, to disable this automatic path -translation, set @code{org-html-link-org-files-as-html} to @code{nil}. When -disabled, the HTML export back-end substitutes the ID-based links in -the HTML output. For more about linking files when publishing to -a directory, see @ref{Publishing links}. - -Org files can also have special directives to the HTML export -back-end. For example, by using @samp{#+ATTR_HTML} lines to specify new -format attributes to @code{} or @code{} tags. This example shows -changing the link's title and style: - -@cindex @samp{ATTR_HTML}, keyword -@example -#+ATTR_HTML: :title The Org mode homepage :style color:red; -[[https://orgmode.org]] -@end example - -@node Tables in HTML export -@subsection Tables in HTML export - -@cindex tables, in HTML -@vindex org-export-html-table-tag - -The HTML export back-end uses @code{org-html-table-default-attributes} when -exporting Org tables to HTML@. By default, the exporter does not draw -frames and cell borders. To change for this for a table, use the -following lines before the table in the Org file: - -@cindex @samp{CAPTION}, keyword -@cindex @samp{ATTR_HTML}, keyword -@example -#+CAPTION: This is a table with lines around and between cells -#+ATTR_HTML: :border 2 :rules all :frame border -@end example - -The HTML export back-end preserves column groupings in Org tables (see -@ref{Column Groups}) when exporting to HTML@. - -Additional options for customizing tables for HTML export. - -@table @asis -@item @code{org-html-table-align-individual-fields} -@vindex org-html-table-align-individual-fields -Non-@code{nil} attaches style attributes for alignment to each table -field. - -@item @code{org-html-table-caption-above} -@vindex org-html-table-caption-above -Non-@code{nil} places caption string at the beginning of the table. - -@item @code{org-html-table-data-tags} -@vindex org-html-table-data-tags -Opening and ending tags for table data fields. - -@item @code{org-html-table-default-attributes} -@vindex org-html-table-default-attributes -Default attributes and values for table tags. - -@item @code{org-html-table-header-tags} -@vindex org-html-table-header-tags -Opening and ending tags for table's header fields. - -@item @code{org-html-table-row-tags} -@vindex org-html-table-row-tags -Opening and ending tags for table rows. - -@item @code{org-html-table-use-header-tags-for-first-column} -@vindex org-html-table-use-header-tags-for-first-column -Non-@code{nil} formats column one in tables with header tags. -@end table - -@node Images in HTML export -@subsection Images in HTML export - -@cindex images, inline in HTML -@cindex inlining images in HTML - -The HTML export back-end has features to convert Org image links to -HTML inline images and HTML clickable image links. - -@vindex org-html-inline-images -When the link in the Org file has no description, the HTML export -back-end by default in-lines that image. For example: -@samp{[[file:myimg.jpg]]} is in-lined, while @samp{[[file:myimg.jpg][the image]]} links to the text, -@samp{the image}. For more details, see the variable -@code{org-html-inline-images}. - -On the other hand, if the description part of the Org link is itself -another link, such as @samp{file:} or @samp{http:} URL pointing to an image, the -HTML export back-end in-lines this image and links to the main image. -This Org syntax enables the back-end to link low-resolution thumbnail -to the high-resolution version of the image, as shown in this example: - -@example -[[file:highres.jpg][file:thumb.jpg]] -@end example - - -To change attributes of in-lined images, use @samp{#+ATTR_HTML} lines in -the Org file. This example shows realignment to right, and adds @code{alt} -and @code{title} attributes in support of text viewers and modern web -accessibility standards. - -@cindex @samp{CAPTION}, keyword -@cindex @samp{ATTR_HTML}, keyword -@example -#+CAPTION: A black cat stalking a spider -#+ATTR_HTML: :alt cat/spider image :title Action! :align right -[[./img/a.jpg]] -@end example - -The HTML export back-end copies the @samp{http} links from the Org file -as-is. - -@node Math formatting in HTML export -@subsection Math formatting in HTML export - -@cindex MathJax -@cindex dvipng -@cindex dvisvgm -@cindex ImageMagick - -@vindex org-html-mathjax-options~ -@LaTeX{} math snippets (see @ref{@LaTeX{} fragments}) can be displayed in two -different ways on HTML pages. The default is to use the @uref{http://www.mathjax.org, MathJax}, -which should work out of the box with Org@footnote{By default Org loads MathJax from @uref{https://cdnjs.com, cdnjs.com} as recommended by -@uref{http://www.mathjax.org, MathJax}.}@footnote{Please note that exported formulas are part of an HTML -document, and that signs such as @samp{<}, @samp{>}, or @samp{&} have special -meanings. See @uref{http://docs.mathjax.org/en/latest/tex.html#tex-and-latex-in-html-documents, MathJax @TeX{} and @LaTeX{} support}.}. Some MathJax -display options can be configured via @code{org-html-mathjax-options}, or -in the buffer. For example, with the following settings, - -@example -#+HTML_MATHJAX: align: left indent: 5em tagside: left font: Neo-Euler -#+HTML_MATHJAX: cancel.js noErrors.js -@end example - -@noindent -equation labels are displayed on the left margin and equations are -five em from the left margin. In addition, it loads the two MathJax -extensions @samp{cancel.js} and @samp{noErrors.js}@footnote{See @uref{http://docs.mathjax.org/en/latest/tex.html#tex-extensions, @TeX{} and @LaTeX{} extensions} in the @uref{http://docs.mathjax.org, MathJax manual} to learn -about extensions.}. - -@vindex org-html-mathjax-template -See the docstring of @code{org-html-mathjax-options} for all supported -variables. The MathJax template can be configure via -@code{org-html-mathjax-template}. - -If you prefer, you can also request that @LaTeX{} fragments are processed -into small images that will be inserted into the browser page. Before -the availability of MathJax, this was the default method for Org -files. This method requires that the dvipng program, dvisvgm or -ImageMagick suite is available on your system. You can still get this -processing with - -@example -#+OPTIONS: tex:dvipng -@end example - - -@example -#+OPTIONS: tex:dvisvgm -@end example - - -@noindent -or - -@example -#+OPTIONS: tex:imagemagick -@end example - -@node Text areas in HTML export -@subsection Text areas in HTML export - -@cindex text areas, in HTML -Before Org mode's Babel, one popular approach to publishing code in -HTML was by using @samp{:textarea}. The advantage of this approach was -that copying and pasting was built into browsers with simple -JavaScript commands. Even editing before pasting was made simple. - -The HTML export back-end can create such text areas. It requires an -@samp{#+ATTR_HTML} line as shown in the example below with the @samp{:textarea} -option. This must be followed by either an example or a source code -block. Other Org block types do not honor the @samp{:textarea} option. - -By default, the HTML export back-end creates a text area 80 characters -wide and height just enough to fit the content. Override these -defaults with @samp{:width} and @samp{:height} options on the @samp{#+ATTR_HTML} -line. - -@example -#+ATTR_HTML: :textarea t :width 40 -#+BEGIN_EXAMPLE - (defun org-xor (a b) - "Exclusive or." - (if a (not b) b)) -#+END_EXAMPLE -@end example - -@node CSS support -@subsection CSS support - -@cindex CSS, for HTML export -@cindex HTML export, CSS - -@vindex org-export-html-todo-kwd-class-prefix -@vindex org-export-html-tag-class-prefix -You can modify the CSS style definitions for the exported file. The -HTML exporter assigns the following special CSS classes@footnote{If the classes on TODO keywords and tags lead to conflicts, -use the variables @code{org-html-todo-kwd-class-prefix} and -@code{org-html-tag-class-prefix} to make them unique.} to -appropriate parts of the document---your style specifications may -change these, in addition to any of the standard classes like for -headlines, tables, etc. - -@multitable {aaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @code{p.author} -@tab author information, including email -@item @code{p.date} -@tab publishing date -@item @code{p.creator} -@tab creator info, about org mode version -@item @code{.title} -@tab document title -@item @code{.subtitle} -@tab document subtitle -@item @code{.todo} -@tab TODO keywords, all not-done states -@item @code{.done} -@tab the DONE keywords, all states that count as done -@item @code{.WAITING} -@tab each TODO keyword also uses a class named after itself -@item @code{.timestamp} -@tab timestamp -@item @code{.timestamp-kwd} -@tab keyword associated with a timestamp, like @samp{SCHEDULED} -@item @code{.timestamp-wrapper} -@tab span around keyword plus timestamp -@item @code{.tag} -@tab tag in a headline -@item @code{._HOME} -@tab each tag uses itself as a class, ``@@'' replaced by ``_'' -@item @code{.target} -@tab target for links -@item @code{.linenr} -@tab the line number in a code example -@item @code{.code-highlighted} -@tab for highlighting referenced code lines -@item @code{div.outline-N} -@tab div for outline level N (headline plus text) -@item @code{div.outline-text-N} -@tab extra div for text at outline level N -@item @code{.section-number-N} -@tab section number in headlines, different for each level -@item @code{.figure-number} -@tab label like ``Figure 1:'' -@item @code{.table-number} -@tab label like ``Table 1:'' -@item @code{.listing-number} -@tab label like ``Listing 1:'' -@item @code{div.figure} -@tab how to format an in-lined image -@item @code{pre.src} -@tab formatted source code -@item @code{pre.example} -@tab normal example -@item @code{p.verse} -@tab verse paragraph -@item @code{div.footnotes} -@tab footnote section headline -@item @code{p.footnote} -@tab footnote definition paragraph, containing a footnote -@item @code{.footref} -@tab a footnote reference number (always a ) -@item @code{.footnum} -@tab footnote number in footnote definition (always ) -@item @code{.org-svg} -@tab default class for a linked @samp{.svg} image -@end multitable - -@vindex org-html-style-default -@vindex org-html-head -@vindex org-html-head-extra -@cindex @samp{HTML_INCLUDE_STYLE}, keyword -The HTML export back-end includes a compact default style in each -exported HTML file. To override the default style with another style, -use these keywords in the Org file. They will replace the global -defaults the HTML exporter uses. - -@cindex @samp{HTML_HEAD}, keyword -@cindex @samp{HTML_HEAD_EXTRA}, keyword -@example -#+HTML_HEAD: -#+HTML_HEAD_EXTRA: -@end example - -@vindex org-html-head-include-default-style -To just turn off the default style, customize -@code{org-html-head-include-default-style} variable, or use this option -line in the Org file. - -@cindex @samp{html-style}, @samp{OPTIONS} item -@example -#+OPTIONS: html-style:nil -@end example - - -For longer style definitions, either use several @samp{HTML_HEAD} and -@samp{HTML_HEAD_EXTRA} keywords, or use @code{} blocks -around them. Both of these approaches can avoid referring to an -external file. - -@cindex @samp{HTML_CONTAINER_CLASS}, property -@cindex @samp{HTML_HEADLINE_CLASS}, property -In order to add styles to a sub-tree, use the @samp{HTML_CONTAINER_CLASS} -property to assign a class to the tree. In order to specify CSS -styles for a particular headline, you can use the ID specified in -a @samp{CUSTOM_ID} property. You can also assign a specific class to -a headline with the @samp{HTML_HEADLINE_CLASS} property. - -Never change the @code{org-html-style-default} constant. Instead use other -simpler ways of customizing as described above. - -@node JavaScript support -@subsection JavaScript supported display of web pages - -Sebastian Rose has written a JavaScript program especially designed to -allow two different ways of viewing HTML files created with Org. One -is an @emph{Info}-like mode where each section is displayed separately and -navigation can be done with the @kbd{n} and @kbd{p} keys, and some other -keys as well, press @kbd{?} for an overview of the available keys. The -second one has a @emph{folding} view, much like Org provides inside Emacs. -The script is available at @uref{https://orgmode.org/org-info.js} and the -documentation at @uref{https://orgmode.org/worg/code/org-info-js/}. The -script is hosted on @uref{https://orgmode.org}, but for reliability, prefer -installing it on your own web server. - -To use this program, just add this line to the Org file: - -@cindex @samp{INFOJS_OPT}, keyword -@example -#+INFOJS_OPT: view:info toc:nil -@end example - - -@noindent -The HTML header now has the code needed to automatically invoke the -script. For setting options, use the syntax from the above line for -options described below: - -@table @asis -@item @samp{path:} -The path to the script. The default is to grab the script from -@uref{https://orgmode.org/org-info.js}, but you might want to have a local -copy and use a path like @samp{../scripts/org-info.js}. - -@item @samp{view:} -Initial view when the website is first shown. Possible values are: - -@multitable {aaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{info} -@tab Info-like interface with one section per page -@item @samp{overview} -@tab Folding interface, initially showing only top-level -@item @samp{content} -@tab Folding interface, starting with all headlines visible -@item @samp{showall} -@tab Folding interface, all headlines and text visible -@end multitable - -@item @samp{sdepth:} -Maximum headline level still considered as an independent section -for info and folding modes. The default is taken from -@code{org-export-headline-levels}, i.e., the @samp{H} switch in @samp{OPTIONS}. If -this is smaller than in @code{org-export-headline-levels}, each -info/folding section can still contain child headlines. - -@item @samp{toc:} -Should the table of contents @emph{initially} be visible? Even when -@samp{nil}, you can always get to the ``toc'' with @kbd{i}. - -@item @samp{tdepth:} -The depth of the table of contents. The defaults are taken from the -variables @code{org-export-headline-levels} and @code{org-export-with-toc}. - -@item @samp{ftoc:} -Does the CSS of the page specify a fixed position for the ``toc''? If -yes, the toc is displayed as a section. - -@item @samp{ltoc:} -Should there be short contents (children) in each section? Make -this @samp{above} if the section should be above initial text. - -@item @samp{mouse:} -Headings are highlighted when the mouse is over them. Should be -@samp{underline} (default) or a background color like @samp{#cccccc}. - -@item @samp{buttons:} -Should view-toggle buttons be everywhere? When @samp{nil} (the default), -only one such button is present. -@end table - -@vindex org-infojs-options -@vindex org-export-html-use-infojs -You can choose default values for these options by customizing the -variable @code{org-infojs-options}. If you always want to apply the script -to your pages, configure the variable @code{org-export-html-use-infojs}. - -@node @LaTeX{} Export -@section @LaTeX{} Export - -@cindex @LaTeX{} export -@cindex PDF export - -The @LaTeX{} export back-end can handle complex documents, incorporate -standard or custom @LaTeX{} document classes, generate documents using -alternate @LaTeX{} engines, and produce fully linked PDF files with -indexes, bibliographies, and tables of contents, destined for -interactive online viewing or high-quality print publication. - -While the details are covered in-depth in this section, here are some -quick references to variables for the impatient: for engines, see -@code{org-latex-compiler}; for build sequences, see -@code{org-latex-pdf-process}; for packages, see -@code{org-latex-default-packages-alist} and @code{org-latex-packages-alist}. - -An important note about the @LaTeX{} export back-end: it is sensitive to -blank lines in the Org document. That's because @LaTeX{} itself depends -on blank lines to tell apart syntactical elements, such as paragraphs. - -@menu -* @LaTeX{}/PDF export commands:: For producing @LaTeX{} and PDF documents. -* @LaTeX{} specific export settings:: Unique to this @LaTeX{} back-end. -* @LaTeX{} header and sectioning:: Setting up the export file structure. -* Quoting @LaTeX{} code:: Incorporating literal @LaTeX{} code. -* Tables in @LaTeX{} export:: Options for exporting tables to @LaTeX{}. -* Images in @LaTeX{} export:: How to insert figures into @LaTeX{} output. -* Plain lists in @LaTeX{} export:: Attributes specific to lists. -* Source blocks in @LaTeX{} export:: Attributes specific to source code blocks. -* Example blocks in @LaTeX{} export:: Attributes specific to example blocks. -* Special blocks in @LaTeX{} export:: Attributes specific to special blocks. -* Horizontal rules in @LaTeX{} export:: Attributes specific to horizontal rules. -@end menu - -@node @LaTeX{}/PDF export commands -@subsection @LaTeX{}/PDF export commands - -@table @asis -@item @kbd{C-c C-e l l} (@code{org-latex-export-to-latex}) -@kindex C-c C-e l l -@findex org-latex-export-to-latex~ -Export to a @LaTeX{} file with a @samp{.tex} extension. For @samp{myfile.org}, -Org exports to @samp{myfile.tex}, overwriting without warning. - -@item @kbd{C-c C-e l L} (@code{org-latex-export-as-latex}) -@kindex C-c C-e l L -@findex org-latex-export-as-latex -Export to a temporary buffer. Do not create a file. - -@item @kbd{C-c C-e l p} (@code{org-latex-export-to-pdf}) -@kindex C-c C-e l p -@findex org-latex-export-to-pdf -Export as @LaTeX{} file and convert it to PDF file. - -@item @kbd{C-c C-e l o} -@kindex C-c C-e l o -Export as @LaTeX{} file and convert it to PDF, then open the PDF using -the default viewer. - -@item @kbd{M-x org-export-region-as-latex} -Convert the region to @LaTeX{} under the assumption that it was in Org -mode syntax before. This is a global command that can be invoked in -any buffer. -@end table - -@vindex org-latex-compiler -@vindex org-latex-bibtex-compiler -@vindex org-latex-default-packages-alist -@cindex pdflatex -@cindex xelatex -@cindex lualatex -@cindex @samp{LATEX_COMPILER}, keyword -The @LaTeX{} export back-end can use any of these @LaTeX{} engines: -@samp{pdflatex}, @samp{xelatex}, and @samp{lualatex}. These engines compile @LaTeX{} -files with different compilers, packages, and output options. The -@LaTeX{} export back-end finds the compiler version to use from -@code{org-latex-compiler} variable or the @samp{#+LATEX_COMPILER} keyword in the -Org file. See the docstring for the -@code{org-latex-default-packages-alist} for loading packages with certain -compilers. Also see @code{org-latex-bibtex-compiler} to set the -bibliography compiler@footnote{This does not allow setting different bibliography compilers -for different files. However, ``smart'' @LaTeX{} compilation systems, such -as latexmk, can select the correct bibliography compiler.}. - -@node @LaTeX{} specific export settings -@subsection @LaTeX{} specific export settings - -The @LaTeX{} export back-end has several additional keywords for -customizing @LaTeX{} output. Setting these keywords works similar to the -general options (see @ref{Export Settings}). - -@table @asis -@item @samp{DESCRIPTION} -@cindex @samp{DESCRIPTION}, keyword -@vindex org-latex-hyperref-template -@vindex org-latex-title-command -The document's description. The description along with author name, -keywords, and related file metadata are inserted in the output file -by the hyperref package. See @code{org-latex-hyperref-template} for -customizing metadata items. See @code{org-latex-title-command} for -typesetting description into the document's front matter. Use -multiple @samp{DESCRIPTION} keywords for long descriptions. - -@item @samp{LANGUAGE} -@cindex @samp{LANGUAGE}, keyword -@vindex org-latex-packages-alist -In order to be effective, the @samp{babel} or @samp{polyglossia} -packages---according to the @LaTeX{} compiler used---must be loaded -with the appropriate language as argument. This can be accomplished -by modifying the @code{org-latex-packages-alist} variable, e.g., with the -following snippet: - -@lisp -(add-to-list 'org-latex-packages-alist - '("AUTO" "babel" t ("pdflatex"))) -(add-to-list 'org-latex-packages-alist - '("AUTO" "polyglossia" t ("xelatex" "lualatex"))) -@end lisp - -@item @samp{LATEX_CLASS} -@cindex @samp{LATEX_CLASS}, keyword -@vindex org-latex-default-class -@vindex org-latex-classes -This is @LaTeX{} document class, such as @emph{article}, @emph{report}, @emph{book}, -and so on, which contain predefined preamble and headline level -mapping that the @LaTeX{} export back-end needs. The back-end reads -the default class name from the @code{org-latex-default-class} variable. -Org has @emph{article} as the default class. A valid default class must -be an element of @code{org-latex-classes}. - -@item @samp{LATEX_CLASS_OPTIONS} -@cindex @samp{LATEX_CLASS_OPTIONS}, keyword -Options the @LaTeX{} export back-end uses when calling the @LaTeX{} -document class. - -@item @samp{LATEX_COMPILER} -@cindex @samp{LATEX_COMPILER}, keyword -@vindex org-latex-compiler -The compiler, such as @samp{pdflatex}, @samp{xelatex}, @samp{lualatex}, for -producing the PDF@. See @code{org-latex-compiler}. - -@item @samp{LATEX_HEADER} -@itemx @samp{LATEX_HEADER_EXTRA} -@cindex @samp{LATEX_HEADER}, keyword -@cindex @samp{LATEX_HEADER_EXTRA}, keyword -@vindex org-latex-classes -Arbitrary lines to add to the document's preamble, before the -hyperref settings. See @code{org-latex-classes} for adjusting the -structure and order of the @LaTeX{} headers. - -@item @samp{KEYWORDS} -@cindex @samp{KEYWORDS}, keyword -@vindex org-latex-hyperref-template -@vindex org-latex-title-command -The keywords for the document. The description along with author -name, keywords, and related file metadata are inserted in the output -file by the hyperref package. See @code{org-latex-hyperref-template} for -customizing metadata items. See @code{org-latex-title-command} for -typesetting description into the document's front matter. Use -multiple @samp{KEYWORDS} lines if necessary. - -@item @samp{SUBTITLE} -@cindex @samp{SUBTITLE}, keyword -@vindex org-latex-subtitle-separate -@vindex org-latex-subtitle-format -The document's subtitle. It is typeset as per -@code{org-latex-subtitle-format}. If @code{org-latex-subtitle-separate} is -non-@code{nil}, it is typed outside of the @code{\title} macro. See -@code{org-latex-hyperref-template} for customizing metadata items. See -@code{org-latex-title-command} for typesetting description into the -document's front matter. -@end table - -The following sections have further details. - -@node @LaTeX{} header and sectioning -@subsection @LaTeX{} header and sectioning structure - -@cindex @LaTeX{} class -@cindex @LaTeX{} sectioning structure -@cindex @LaTeX{} header -@cindex header, for @LaTeX{} files -@cindex sectioning structure, for @LaTeX{} export - -The @LaTeX{} export back-end converts the first three of Org's outline -levels into @LaTeX{} headlines. The remaining Org levels are exported as -lists. To change this globally for the cut-off point between levels -and lists, (see @ref{Export Settings}). - -By default, the @LaTeX{} export back-end uses the @emph{article} class. - -@vindex org-latex-default-class -@vindex org-latex-classes -@vindex org-latex-default-packages-alist -@vindex org-latex-packages-alist -To change the default class globally, edit @code{org-latex-default-class}. -To change the default class locally in an Org file, add option lines -@samp{#+LATEX_CLASS: myclass}. To change the default class for just a part -of the Org file, set a sub-tree property, @samp{EXPORT_LATEX_CLASS}. The -class name entered here must be valid member of @code{org-latex-classes}. -This variable defines a header template for each class into which the -exporter splices the values of @code{org-latex-default-packages-alist} and -@code{org-latex-packages-alist}. Use the same three variables to define -custom sectioning or custom classes. - -@cindex @samp{LATEX_CLASS}, keyword -@cindex @samp{LATEX_CLASS_OPTIONS}, keyword -@cindex @samp{EXPORT_LATEX_CLASS}, property -@cindex @samp{EXPORT_LATEX_CLASS_OPTIONS}, property -The @LaTeX{} export back-end sends the @samp{LATEX_CLASS_OPTIONS} keyword and -@samp{EXPORT_LATEX_CLASS_OPTIONS} property as options to the @LaTeX{} -@code{\documentclass} macro. The options and the syntax for specifying -them, including enclosing them in square brackets, follow @LaTeX{} -conventions. - -@example -#+LATEX_CLASS_OPTIONS: [a4paper,11pt,twoside,twocolumn] -@end example - - -@cindex @samp{LATEX_HEADER}, keyword -@cindex @samp{LATEX_HEADER_EXTRA}, keyword -The @LaTeX{} export back-end appends values from @samp{LATEX_HEADER} and -@samp{LATEX_HEADER_EXTRA} keywords to the @LaTeX{} header. The docstring for -@code{org-latex-classes} explains in more detail. Also note that @LaTeX{} -export back-end does not append @samp{LATEX_HEADER_EXTRA} to the header -when previewing @LaTeX{} snippets (see @ref{Previewing @LaTeX{} fragments}). - -A sample Org file with the above headers: - -@example -#+LATEX_CLASS: article -#+LATEX_CLASS_OPTIONS: [a4paper] -#+LATEX_HEADER: \usepackage@{xyz@} - -* Headline 1 - some text -* Headline 2 - some more text -@end example - -@node Quoting @LaTeX{} code -@subsection Quoting @LaTeX{} code - -The @LaTeX{} export back-end can insert any arbitrary @LaTeX{} code, see -@ref{Embedded @LaTeX{}}. There are three ways to embed such code in the Org -file and they all use different quoting syntax. - -@cindex inline, in @LaTeX{} export -Inserting in-line quoted with @@ symbols: - -@example -Code embedded in-line @@@@latex:any arbitrary LaTeX code@@@@ in a paragraph. -@end example - - -@cindex @samp{LATEX}, keyword -Inserting as one or more keyword lines in the Org file: - -@example -#+LATEX: any arbitrary LaTeX code -@end example - - -@cindex @samp{BEGIN_EXPORT latex} -Inserting as an export block in the Org file, where the back-end -exports any code between begin and end markers: - -@example -#+BEGIN_EXPORT latex - any arbitrary LaTeX code -#+END_EXPORT -@end example - -@node Tables in @LaTeX{} export -@subsection Tables in @LaTeX{} export - -@cindex tables, in @LaTeX{} export - -The @LaTeX{} export back-end can pass several @LaTeX{} attributes for table -contents and layout. Besides specifying a label (see @ref{Internal Links}) -and a caption (see @ref{Captions}), the other valid @LaTeX{} attributes -include: - -@table @asis -@item @samp{:mode} -@vindex org-latex-default-table-mode -The @LaTeX{} export back-end wraps the table differently depending on -the mode for accurate rendering of math symbols. Mode is either -@samp{table}, @samp{math}, @samp{inline-math} or @samp{verbatim}. - -For @samp{math} or @samp{inline-math} mode, @LaTeX{} export back-end wraps the -table in a math environment, but every cell in it is exported as-is. -The @LaTeX{} export back-end determines the default mode from -@code{org-latex-default-table-mode}. The @LaTeX{} export back-end merges -contiguous tables in the same mode into a single environment. - -@item @samp{:environment} -@vindex org-latex-default-table-environment -Set the default @LaTeX{} table environment for the @LaTeX{} export -back-end to use when exporting Org tables. Common @LaTeX{} table -environments are provided by these packages: tabularx, longtable, -array, tabu, and bmatrix. For packages, such as tabularx and tabu, -or any newer replacements, include them in the -@code{org-latex-packages-alist} variable so the @LaTeX{} export back-end can -insert the appropriate load package headers in the converted @LaTeX{} -file. Look in the docstring for the @code{org-latex-packages-alist} -variable for configuring these packages for @LaTeX{} snippet previews, -if any. - -@item @samp{:caption} -Use @samp{CAPTION} keyword to set a simple caption for a table (see -@ref{Captions}). For custom captions, use @samp{:caption} attribute, which -accepts raw @LaTeX{} code. @samp{:caption} value overrides @samp{CAPTION} value. - -@item @samp{:float} -@itemx @samp{:placement} -The table environments by default are not floats in @LaTeX{}. To make -them floating objects use @samp{:float} with one of the following -options: @samp{sideways}, @samp{multicolumn}, @samp{t}, and @samp{nil}. - -@LaTeX{} floats can also have additional layout @samp{:placement} -attributes. These are the usual @samp{[h t b p ! H]} permissions -specified in square brackets. Note that for @samp{:float sideways} -tables, the @LaTeX{} export back-end ignores @samp{:placement} attributes. - -@item @samp{:align} -@itemx @samp{:font} -@itemx @samp{:width} -The @LaTeX{} export back-end uses these attributes for regular tables -to set their alignments, fonts, and widths. - -@item @samp{:spread} -When @samp{:spread} is non-@code{nil}, the @LaTeX{} export back-end spreads or -shrinks the table by the @samp{:width} for tabu and longtabu -environments. @samp{:spread} has no effect if @samp{:width} is not set. - -@item @samp{:booktabs} -@itemx @samp{:center} -@itemx @samp{:rmlines} -@vindex org-latex-tables-booktabs -@vindex org-latex-tables-centered -All three commands are toggles. @samp{:booktabs} brings in modern -typesetting enhancements to regular tables. The booktabs package -has to be loaded through @code{org-latex-packages-alist}. @samp{:center} is -for centering the table. @samp{:rmlines} removes all but the very first -horizontal line made of ASCII characters from ``table.el'' tables -only. - -@item @samp{:math-prefix} -@itemx @samp{:math-suffix} -@itemx @samp{:math-arguments} -The @LaTeX{} export back-end inserts @samp{:math-prefix} string value in -a math environment before the table. The @LaTeX{} export back-end -inserts @samp{:math-suffix} string value in a math environment after the -table. The @LaTeX{} export back-end inserts @samp{:math-arguments} string -value between the macro name and the table's contents. -@samp{:math-arguments} comes in use for matrix macros that require more -than one argument, such as @samp{qbordermatrix}. -@end table - -@LaTeX{} table attributes help formatting tables for a wide range of -situations, such as matrix product or spanning multiple pages: - -@example -#+ATTR_LATEX: :environment longtable :align l|lp@{3cm@}r|l -| ... | ... | -| ... | ... | - -#+ATTR_LATEX: :mode math :environment bmatrix :math-suffix \times -| a | b | -| c | d | -#+ATTR_LATEX: :mode math :environment bmatrix -| 1 | 2 | -| 3 | 4 | -@end example - -Set the caption with the @LaTeX{} command -@samp{\bicaption@{HeadingA@}@{HeadingB@}}: - -@example -#+ATTR_LATEX: :caption \bicaption@{HeadingA@}@{HeadingB@} -| ... | ... | -| ... | ... | -@end example - -@node Images in @LaTeX{} export -@subsection Images in @LaTeX{} export - -@cindex images, inline in LaTeX -@cindex inlining images in LaTeX -@cindex @samp{ATTR_LATEX}, keyword - -The @LaTeX{} export back-end processes image links in Org files that do -not have descriptions, such as these links @samp{[[file:img.jpg]]} or -@samp{[[./img.jpg]]}, as direct image insertions in the final PDF output. In -the PDF, they are no longer links but actual images embedded on the -page. The @LaTeX{} export back-end uses @samp{\includegraphics} macro to -insert the image. But for TikZ (@uref{http://sourceforge.net/projects/pgf/}) -images, the back-end uses an @code{\input} macro wrapped within -a @code{tikzpicture} environment. - -For specifying image @samp{:width}, @samp{:height}, @samp{:scale} and other @samp{:options}, -use this syntax: - -@example -#+ATTR_LATEX: :width 5cm :options angle=90 -[[./img/sed-hr4049.pdf]] -@end example - -A @samp{:scale} attribute overrides both @samp{:width} and @samp{:height} attributes. - -For custom commands for captions, use the @samp{:caption} attribute. It -overrides the default @samp{#+CAPTION} value: - -@example -#+ATTR_LATEX: :caption \bicaption@{HeadingA@}@{HeadingB@} -[[./img/sed-hr4049.pdf]] -@end example - -When captions follow the method as described in @ref{Captions}, the @LaTeX{} -export back-end wraps the picture in a floating @samp{figure} environment. -To float an image without specifying a caption, set the @samp{:float} -attribute to one of the following: - -@table @asis -@item @samp{t} -For a standard @samp{figure} environment; used by default whenever an -image has a caption. - -@item @samp{multicolumn} -To span the image across multiple columns of a page; the back-end -wraps the image in a @samp{figure*} environment. - -@item @samp{wrap} -For text to flow around the image on the right; the figure occupies -the left half of the page. - -@item @samp{sideways} -For a new page with the image sideways, rotated ninety degrees, in -a @samp{sidewaysfigure} environment; overrides @samp{:placement} setting. - -@item @samp{nil} -To avoid a @samp{:float} even if using a caption. -@end table - -Use the @samp{placement} attribute to modify a floating environment's -placement. - -@example -#+ATTR_LATEX: :float wrap :width 0.38\textwidth :placement @{r@}@{0.4\textwidth@} -[[./img/hst.png]] -@end example - -@vindex org-latex-images-centered -@cindex center image in LaTeX export -@cindex image, centering in LaTeX export -The @LaTeX{} export back-end centers all images by default. Setting -@samp{:center} to @samp{nil} disables centering. To disable centering globally, -set @code{org-latex-images-centered} to @samp{t}. - -Set the @samp{:comment-include} attribute to non-@code{nil} value for the @LaTeX{} -export back-end to comment out the @samp{\includegraphics} macro. - -@node Plain lists in @LaTeX{} export -@subsection Plain lists in @LaTeX{} export - -@cindex plain lists, in @LaTeX{} export -@cindex @samp{ATTR_LATEX}, keyword -The @LaTeX{} export back-end accepts the @samp{environment} and @samp{options} -attributes for plain lists. Both attributes work together for -customizing lists, as shown in the examples: - -@example -#+LATEX_HEADER: \usepackage[inline]@{enumitem@} -Some ways to say "Hello": -#+ATTR_LATEX: :environment itemize* -#+ATTR_LATEX: :options [label=@{@}, itemjoin=@{,@}, itemjoin*=@{, and@}] -- Hola -- Bonjour -- Guten Tag. -@end example - -Since @LaTeX{} supports only four levels of nesting for lists, use an -external package, such as @samp{enumitem} in @LaTeX{}, for levels deeper than -four: - -@example -#+LATEX_HEADER: \usepackage@{enumitem@} -#+LATEX_HEADER: \renewlist@{itemize@}@{itemize@}@{9@} -#+LATEX_HEADER: \setlist[itemize]@{label=$\circ$@} -- One - - Two - - Three - - Four - - Five -@end example - -@node Source blocks in @LaTeX{} export -@subsection Source blocks in @LaTeX{} export - -@cindex source blocks, in @LaTeX{} export -@cindex @samp{ATTR_LATEX}, keyword - -The @LaTeX{} export back-end can make source code blocks into floating -objects through the attributes @samp{:float} and @samp{:options}. For @samp{:float}: - -@table @asis -@item @samp{t} -Makes a source block float; by default floats any source block with -a caption. - -@item @samp{multicolumn} -Spans the source block across multiple columns of a page. - -@item @samp{nil} -Avoids a @samp{:float} even if using a caption; useful for source code -blocks that may not fit on a page. -@end table - -@example -#+ATTR_LATEX: :float nil -#+BEGIN_SRC emacs-lisp - Lisp code that may not fit in a single page. -#+END_SRC -@end example - -@vindex org-latex-listings-options -@vindex org-latex-minted-options -The @LaTeX{} export back-end passes string values in @samp{:options} to @LaTeX{} -packages for customization of that specific source block. In the -example below, the @samp{:options} are set for Minted. Minted is a source -code highlighting @LaTeX{} package with many configurable options. - -@example -#+ATTR_LATEX: :options commentstyle=\bfseries -#+BEGIN_SRC emacs-lisp - (defun Fib (n) - (if (< n 2) n (+ (Fib (- n 1)) (Fib (- n 2))))) -#+END_SRC -@end example - -To apply similar configuration options for all source blocks in -a file, use the @code{org-latex-listings-options} and -@code{org-latex-minted-options} variables. - -@node Example blocks in @LaTeX{} export -@subsection Example blocks in @LaTeX{} export - -@cindex example blocks, in @LaTeX{} export -@cindex verbatim blocks, in @LaTeX{} export -@cindex @samp{ATTR_LATEX}, keyword - -The @LaTeX{} export back-end wraps the contents of example blocks in -a @samp{verbatim} environment. To change this behavior to use another -environment globally, specify an appropriate export filter (see -@ref{Advanced Export Configuration}). To change this behavior to use -another environment for each block, use the @samp{:environment} parameter -to specify a custom environment. - -@example -#+ATTR_LATEX: :environment myverbatim -#+BEGIN_EXAMPLE - This sentence is false. -#+END_EXAMPLE -@end example - -@node Special blocks in @LaTeX{} export -@subsection Special blocks in @LaTeX{} export - -@cindex special blocks, in @LaTeX{} export -@cindex abstract, in @LaTeX{} export -@cindex proof, in @LaTeX{} export -@cindex @samp{ATTR_LATEX}, keyword - -For other special blocks in the Org file, the @LaTeX{} export back-end -makes a special environment of the same name. The back-end also takes -@samp{:options}, if any, and appends as-is to that environment's opening -string. For example: - -@example -#+BEGIN_abstract - We demonstrate how to solve the Syracuse problem. -#+END_abstract - -#+ATTR_LATEX: :options [Proof of important theorem] -#+BEGIN_proof - ... - Therefore, any even number greater than 2 is the sum of two primes. -#+END_proof -@end example - -@noindent -exports to - -@example -\begin@{abstract@} - We demonstrate how to solve the Syracuse problem. -\end@{abstract@} - -\begin@{proof@}[Proof of important theorem] - ... - Therefore, any even number greater than 2 is the sum of two primes. -\end@{proof@} -@end example - -If you need to insert a specific caption command, use @samp{:caption} -attribute. It overrides standard @samp{CAPTION} value, if any. For -example: - -@example -#+ATTR_LATEX: :caption \MyCaption@{HeadingA@} -#+BEGIN_proof - ... -#+END_proof -@end example - -@node Horizontal rules in @LaTeX{} export -@subsection Horizontal rules in @LaTeX{} export - -@cindex horizontal rules, in @LaTeX{} export -@cindex @samp{ATTR_LATEX}, keyword - -The @LaTeX{} export back-end converts horizontal rules by the specified -@samp{:width} and @samp{:thickness} attributes. For example: - -@example -#+ATTR_LATEX: :width .6\textwidth :thickness 0.8pt ------ -@end example - -@node Markdown Export -@section Markdown Export - -@cindex Markdown export - -The Markdown export back-end, ``md'', converts an Org file to Markdown -format, as defined at @uref{http://daringfireball.net/projects/markdown/}. - -Since it is built on top of the HTML back-end (see @ref{HTML Export}), it -converts every Org construct not defined in Markdown syntax, such as -tables, to HTML@. - -@anchor{Markdown export commands} -@subheading Markdown export commands - -@table @asis -@item @kbd{C-c C-e m m} (@code{org-md-export-to-markdown}) -@kindex C-c C-c m m -@findex org-md-export-to-markdown -Export to a text file with Markdown syntax. For @samp{myfile.org}, Org -exports to @samp{myfile.md}, overwritten without warning. - -@item @kbd{C-c C-e m M} (@code{org-md-export-as-markdown}) -@kindex C-c C-c m M -@findex org-md-export-as-markdown -Export to a temporary buffer. Does not create a file. - -@item @kbd{C-c C-e m o} -@kindex C-c C-e m o -Export as a text file with Markdown syntax, then open it. -@end table - -@anchor{Header and sectioning structure (1)} -@subheading Header and sectioning structure - -@vindex org-md-headline-style -Based on @code{org-md-headline-style}, Markdown export can generate -headlines of both @emph{atx} and @emph{setext} types. @emph{atx} limits headline -levels to two whereas @emph{setext} limits headline levels to six. Beyond -these limits, the export back-end converts headlines to lists. To set -a limit to a level before the absolute limit (see @ref{Export Settings}). - -@node OpenDocument Text Export -@section OpenDocument Text Export - -@cindex ODT -@cindex OpenDocument -@cindex export, OpenDocument -@cindex LibreOffice - -The ODT export back-end handles creating of OpenDocument Text (ODT) -format. Documents created by this exporter use the -@cite{OpenDocument-v1.2 specification}@footnote{See @uref{http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html, Open Document Format for Office Applications -(OpenDocument) Version 1.2}.} and are compatible -with LibreOffice 3.4. - -@menu -* Pre-requisites for ODT export:: Required packages. -* ODT export commands:: Invoking export. -* ODT specific export settings:: Configuration options. -* Extending ODT export:: Producing DOC, PDF files. -* Applying custom styles:: Styling the output. -* Links in ODT export:: Handling and formatting links. -* Tables in ODT export:: Org tables conversions. -* Images in ODT export:: Inserting images. -* Math formatting in ODT export:: Formatting @LaTeX{} fragments. -* Labels and captions in ODT export:: Rendering objects. -* Literal examples in ODT export:: For source code and example blocks. -* Advanced topics in ODT export:: For power users. -@end menu - -@node Pre-requisites for ODT export -@subsection Pre-requisites for ODT export - -@cindex zip - -The ODT export back-end relies on the zip program to create the final -compressed ODT output. Check if @samp{zip} is locally available and -executable. Without it, export cannot finish. - -@node ODT export commands -@subsection ODT export commands - -@table @asis -@item @kbd{C-c C-e o o} (@code{org-export-to-odt}) -@kindex C-c C-e o o -@findex org-export-to-odt -Export as OpenDocument Text file. - -@cindex @samp{EXPORT_FILE_NAME}, property -@vindex org-odt-preferred-output-format - -If @code{org-odt-preferred-output-format} is specified, the ODT export -back-end automatically converts the exported file to that format. - -For @samp{myfile.org}, Org exports to @samp{myfile.odt}, overwriting without -warning. The ODT export back-end exports a region only if a region -was active. - -If the selected region is a single tree, the ODT export back-end -makes the tree head the document title. Incidentally, @kbd{C-c @@} selects the current sub-tree. If the tree head entry has, or -inherits, an @samp{EXPORT_FILE_NAME} property, the ODT export back-end -uses that for file name. - -@item @kbd{C-c C-e o O} -@kindex C-c C-e o O -Export as an OpenDocument Text file and open the resulting file. - -@vindex org-export-odt-preferred-output-format -If @code{org-export-odt-preferred-output-format} is specified, open the -converted file instead. See @ref{Automatically exporting to other formats}. -@end table - -@node ODT specific export settings -@subsection ODT specific export settings - -The ODT export back-end has several additional keywords for -customizing ODT output. Setting these keywords works similar to the -general options (see @ref{Export Settings}). - -@table @asis -@item @samp{DESCRIPTION} -@cindex @samp{DESCRIPTION}, keyword -This is the document's description, which the ODT export back-end -inserts as document metadata. For long descriptions, use multiple -lines, prefixed with @samp{DESCRIPTION}. - -@item @samp{KEYWORDS} -@cindex @samp{KEYWORDS}, keyword -The keywords for the document. The ODT export back-end inserts the -description along with author name, keywords, and related file -metadata as metadata in the output file. Use multiple @samp{KEYWORDS} if -necessary. - -@item @samp{ODT_STYLES_FILE} -@cindex @samp{ODT_STYLES_FILE}, keyword -@vindex org-odt-styles-file -The ODT export back-end uses the @code{org-odt-styles-file} by default. -See @ref{Applying custom styles} for details. - -@item @samp{SUBTITLE} -@cindex @samp{SUBTITLE}, keyword -The document subtitle. -@end table - -@node Extending ODT export -@subsection Extending ODT export - -The ODT export back-end can produce documents in other formats besides -ODT using a specialized ODT converter process. Its common interface -works with popular converters to produce formats such as @samp{doc}, or -convert a document from one format, say @samp{csv}, to another format, say -@samp{xls}. - -@cindex @file{unoconv} -@vindex org-odt-convert-process -Customize @code{org-odt-convert-process} variable to point to @samp{unoconv}, -which is the ODT's preferred converter. Working installations of -LibreOffice would already have @samp{unoconv} installed. Alternatively, -other converters may be substituted here. See @ref{Configuring a document converter}. - -@anchor{Automatically exporting to other formats} -@subsubheading Automatically exporting to other formats - -@vindex org-odt-preferred-output-format -If ODT format is just an intermediate step to get to other formats, -such as @samp{doc}, @samp{docx}, @samp{rtf}, or @samp{pdf}, etc., then extend the ODT -export back-end to directly produce that format. Specify the final -format in the @code{org-odt-preferred-output-format} variable. This is one -way to extend (see @ref{ODT export commands}). - -@anchor{Converting between document formats} -@subsubheading Converting between document formats - -The Org export back-end is made to be inter-operable with a wide range -of text document format converters. Newer generation converters, such -as LibreOffice and Pandoc, can handle hundreds of formats at once. -Org provides a consistent interaction with whatever converter is -installed. Here are some generic commands: - -@table @asis -@item @kbd{M-x org-odt-convert} -@findex org-odt-convert -Convert an existing document from one format to another. With -a prefix argument, opens the newly produced file. -@end table - -@node Applying custom styles -@subsection Applying custom styles - -@cindex styles, custom -@cindex template, custom - -The ODT export back-end comes with many OpenDocument styles (see -@ref{Working with OpenDocument style files}). To expand or further -customize these built-in style sheets, either edit the style sheets -directly or generate them using an application such as LibreOffice. -The example here shows creating a style using LibreOffice. - -@anchor{Applying custom styles the easy way} -@subsubheading Applying custom styles: the easy way - -@enumerate -@item -Create a sample @samp{example.org} file with settings as shown below, -and export it to ODT format. - -@example -#+OPTIONS: H:10 num:t -@end example - -@item -Open the above @samp{example.odt} using LibreOffice. Use the @emph{Stylist} -to locate the target styles, which typically have the ``Org'' prefix. -Open one, modify, and save as either OpenDocument Text (ODT) or -OpenDocument Template (OTT) file. - -@item -@vindex org-odt-styles-file -Customize the variable @code{org-odt-styles-file} and point it to the -newly created file. For additional configuration options, see -@ref{x-overriding-factory-styles, , Overriding factory styles}. - -@cindex @samp{ODT_STYLES_FILE}, keyword -To apply an ODT style to a particular file, use the -@samp{ODT_STYLES_FILE} keyword as shown in the example below: - -@example -#+ODT_STYLES_FILE: "/path/to/example.ott" -@end example - - -@noindent -or - -@example -#+ODT_STYLES_FILE: ("/path/to/file.ott" ("styles.xml" "image/hdr.png")) -@end example -@end enumerate - -@anchor{Using third-party styles and templates} -@subsubheading Using third-party styles and templates - -The ODT export back-end relies on many templates and style names. -Using third-party styles and templates can lead to mismatches. -Templates derived from built in ODT templates and styles seem to have -fewer problems. - -@node Links in ODT export -@subsection Links in ODT export - -@cindex links, in ODT export - -ODT exporter creates native cross-references for internal links. It -creates Internet-style links for all other links. - -A link with no description and pointing to a regular, un-itemized, -outline heading is replaced with a cross-reference and section number -of the heading. - -A @samp{\ref@{label@}}-style reference to an image, table etc., is replaced -with a cross-reference and sequence number of the labeled entity. See -@ref{Labels and captions in ODT export}. - -@node Tables in ODT export -@subsection Tables in ODT export - -@cindex tables, in ODT export - -The ODT export back-end handles native Org mode tables (see @ref{Tables}) -and simple @samp{table.el} tables. Complex @samp{table.el} tables having column -or row spans are not supported. Such tables are stripped from the -exported document. - -By default, the ODT export back-end exports a table with top and -bottom frames and with ruled lines separating row and column groups -(see @ref{Column Groups}). All tables are typeset to occupy the same -width. The ODT export back-end honors any table alignments and -relative widths for columns (see @ref{Column Width and Alignment}). - -Note that the ODT export back-end interprets column widths as weighted -ratios, the default weight being 1. - -@cindex @samp{ATTR_ODT}, keyword -Specifying @samp{:rel-width} property on an @samp{ATTR_ODT} line controls the -width of the table. For example: - -@example -#+ATTR_ODT: :rel-width 50 -| Area/Month | Jan | Feb | Mar | Sum | -|---------------+-------+-------+-------+-------| -| / | < | | | < | -| | | | | | -| North America | 1 | 21 | 926 | 948 | -| Middle East | 6 | 75 | 844 | 925 | -| Asia Pacific | 9 | 27 | 790 | 826 | -|---------------+-------+-------+-------+-------| -| Sum | 16 | 123 | 2560 | 2699 | -@end example - -On export, the above table takes 50% of text width area. The exporter -sizes the columns in the ratio: 13:5:5:5:6. The first column is -left-aligned and rest of the columns, right-aligned. Vertical rules -separate the header and the last column. Horizontal rules separate -the header and the last row. - -For even more customization, create custom table styles and associate -them with a table using the @samp{ATTR_ODT} keyword. See @ref{Customizing tables in ODT export}. - -@node Images in ODT export -@subsection Images in ODT export - -@cindex images, embedding in ODT -@cindex embedding images in ODT - -@anchor{Embedding images} -@subsubheading Embedding images - -The ODT export back-end processes image links in Org files that do not -have descriptions, such as these links @samp{[[file:img.jpg]]} or @samp{[[./img.jpg]]}, -as direct image insertions in the final output. Either of these -examples works: - -@example -[[file:img.png]] -@end example - - -@example -[[./img.png]] -@end example - -@anchor{Embedding clickable images} -@subsubheading Embedding clickable images - -For clickable images, provide a link whose description is another link -to an image file. For example, to embed an image -@samp{org-mode-unicorn.png} which when clicked jumps to @uref{https://orgmode.org} -website, do the following - -@example -[[https://orgmode.org][./org-mode-unicorn.png]] -@end example - -@anchor{Sizing and scaling of embedded images} -@subsubheading Sizing and scaling of embedded images - -@cindex @samp{ATTR_ODT}, keyword - -Control the size and scale of the embedded images with the @samp{ATTR_ODT} -attribute. - -@cindex identify, ImageMagick -@vindex org-odt-pixels-per-inch -The ODT export back-end starts with establishing the size of the image -in the final document. The dimensions of this size are measured in -centimeters. The back-end then queries the image file for its -dimensions measured in pixels. For this measurement, the back-end -relies on ImageMagick's identify program or Emacs @code{create-image} and -@code{image-size} API@. ImageMagick is the preferred choice for large file -sizes or frequent batch operations. The back-end then converts the -pixel dimensions using @code{org-odt-pixels-per-inch} into the familiar 72 -dpi or 96 dpi. The default value for this is in -@code{display-pixels-per-inch}, which can be tweaked for better results -based on the capabilities of the output device. Here are some common -image scaling operations: - -@table @asis -@item Explicitly size the image -To embed @samp{img.png} as a 10 cm x 10 cm image, do the following: - -@example -#+ATTR_ODT: :width 10 :height 10 -[[./img.png]] -@end example - -@item Scale the image -To embed @samp{img.png} at half its size, do the following: - -@example -#+ATTR_ODT: :scale 0.5 -[[./img.png]] -@end example - -@item Scale the image to a specific width -To embed @samp{img.png} with a width of 10 cm while retaining the -original height:width ratio, do the following: - -@example -#+ATTR_ODT: :width 10 -[[./img.png]] -@end example - -@item Scale the image to a specific height -To embed @samp{img.png} with a height of 10 cm while retaining the -original height:width ratio, do the following: - -@example -#+ATTR_ODT: :height 10 -[[./img.png]] -@end example -@end table - -@anchor{Anchoring of images} -@subsubheading Anchoring of images - -@cindex @samp{ATTR_ODT}, keyword -The ODT export back-end can anchor images to @samp{as-char}, @samp{paragraph}, -or @samp{page}. Set the preferred anchor using the @samp{:anchor} property of -the @samp{ATTR_ODT} line. - -To create an image that is anchored to a page: - -@example -#+ATTR_ODT: :anchor page -[[./img.png]] -@end example - -@node Math formatting in ODT export -@subsection Math formatting in ODT export - -The ODT exporter has special support for handling math. - -@menu -* @LaTeX{} math snippets:: Embedding in @LaTeX{} format. -* MathML and OpenDocument formula files:: Embedding in native format. -@end menu - -@node @LaTeX{} math snippets -@subsubsection @LaTeX{} math snippets - -@LaTeX{} math snippets (see @ref{@LaTeX{} fragments}) can be embedded in the ODT -document in one of the following ways: - -@table @asis -@item MathML -@cindex MathML -Add this line to the Org file. This option is activated on -a per-file basis. - -@example -#+OPTIONS: tex:t -@end example - - -With this option, @LaTeX{} fragments are first converted into MathML -fragments using an external @LaTeX{}-to-MathML converter program. The -resulting MathML fragments are then embedded as an OpenDocument -Formula in the exported document. - -@vindex org-latex-to-mathml-convert-command -@vindex org-latex-to-mathml-jar-file -You can specify the @LaTeX{}-to-MathML converter by customizing the -variables @code{org-latex-to-mathml-convert-command} and -@code{org-latex-to-mathml-jar-file}. - -If you prefer to use MathToWeb@footnote{See @uref{http://www.mathtoweb.com/cgi-bin/mathtoweb_home.pl, MathToWeb}.} as your converter, you can -configure the above variables as shown below. - -@lisp -(setq org-latex-to-mathml-convert-command - "java -jar %j -unicode -force -df %o %I" - org-latex-to-mathml-jar-file - "/path/to/mathtoweb.jar") -@end lisp - -@noindent -or, to use @LaTeX{}​ML@footnote{See @uref{http://dlmf.nist.gov/LaTeXML/}.} instead, - -@lisp -(setq org-latex-to-mathml-convert-command - "latexmlmath \"%i\" --presentationmathml=%o") -@end lisp - -To quickly verify the reliability of the @LaTeX{}-to-MathML -converter, use the following commands: - -@table @asis -@item @kbd{M-x org-export-as-odf} -Convert a @LaTeX{} math snippet to an OpenDocument formula (@samp{.odf}) -file. - -@item @kbd{M-x org-export-as-odf-and-open} -Convert a @LaTeX{} math snippet to an OpenDocument formula (@samp{.odf}) -file and open the formula file with the system-registered -application. -@end table - -@item PNG images -@cindex dvipng -@cindex dvisvgm -@cindex ImageMagick -Add this line to the Org file. This option is activated on -a per-file basis. - -@example -#+OPTIONS: tex:dvipng -@end example - - -@example -#+OPTIONS: tex:dvisvgm -@end example - - -@noindent -or - -@example -#+OPTIONS: tex:imagemagick -@end example - - -Under this option, @LaTeX{} fragments are processed into PNG or SVG -images and the resulting images are embedded in the exported -document. This method requires dvipng program, dvisvgm or -ImageMagick programs. -@end table - -@node MathML and OpenDocument formula files -@subsubsection MathML and OpenDocument formula files - -When embedding @LaTeX{} math snippets in ODT documents is not reliable, -there is one more option to try. Embed an equation by linking to its -MathML (@samp{.mml}) source or its OpenDocument formula (@samp{.odf}) file as -shown below: - -@example -[[./equation.mml]] -@end example - - -@noindent -or - -@example -[[./equation.odf]] -@end example - -@node Labels and captions in ODT export -@subsection Labels and captions in ODT export - -ODT format handles labeling and captioning of objects based on their -types. Inline images, tables, @LaTeX{} fragments, and Math formulas are -numbered and captioned separately. Each object also gets a unique -sequence number based on its order of first appearance in the Org -file. Each category has its own sequence. A caption is just a label -applied to these objects. - -@example -#+CAPTION: Bell curve -#+NAME: fig:SED-HR4049 -[[./img/a.png]] -@end example - -When rendered, it may show as follows in the exported document: - -@example -Figure 2: Bell curve -@end example - - -@vindex org-odt-category-map-alist -To modify the category component of the caption, customize the option -@code{org-odt-category-map-alist}. For example, to tag embedded images -with the string ``Illustration'' instead of the default string ``Figure'', -use the following setting: - -@lisp -(setq org-odt-category-map-alist - '(("__Figure__" "Illustration" "value" "Figure" org-odt--enumerable-image-p))) -@end lisp - -With the above modification, the previous example changes to: - -@example -Illustration 2: Bell curve -@end example - -@node Literal examples in ODT export -@subsection Literal examples in ODT export - -The ODT export back-end supports literal examples (see @ref{Literal Examples}) with full fontification. Internally, the ODT export -back-end relies on @samp{htmlfontify.el} to generate the style definitions -needed for fancy listings. The auto-generated styles get @samp{OrgSrc} -prefix and inherit colors from the faces used by Emacs Font Lock -library for that source language. - -@vindex org-odt-fontify-srcblocks -For custom fontification styles, customize the -@code{org-odt-create-custom-styles-for-srcblocks} option. - -@vindex org-odt-create-custom-styles-for-srcblocks -To turn off fontification of literal examples, customize the -@code{org-odt-fontify-srcblocks} option. - -@node Advanced topics in ODT export -@subsection Advanced topics in ODT export - -The ODT export back-end has extensive features useful for power users -and frequent uses of ODT formats. - -@anchor{Configuring a document converter} -@subsubheading Configuring a document converter - -@cindex convert -@cindex doc, docx, rtf -@cindex converter - -The ODT export back-end works with popular converters with little or -no extra configuration. See @ref{Extending ODT export}. The following is -for unsupported converters or tweaking existing defaults. - -@table @asis -@item Register the converter -@vindex org-export-odt-convert-processes -Add the name of the converter to the @code{org-odt-convert-processes} -variable. Note that it also requires how the converter is invoked -on the command line. See the variable's docstring for details. - -@item Configure its capabilities -@vindex org-export-odt-convert-capabilities -Specify which formats the converter can handle by customizing the -variable @code{org-odt-convert-capabilities}. Use the entry for the -default values in this variable for configuring the new converter. -Also see its docstring for details. - -@item Choose the converter -@vindex org-export-odt-convert-process -Select the newly added converter as the preferred one by customizing -the option @code{org-odt-convert-process}. -@end table - -@anchor{Working with OpenDocument style files} -@subsubheading Working with OpenDocument style files - -@cindex styles, custom -@cindex template, custom - -This section explores the internals of the ODT exporter; the means by which -it produces styled documents; the use of automatic and custom OpenDocument -styles. - -The ODT exporter relies on two files for generating its output. These -files are bundled with the distribution under the directory pointed to -by the variable @code{org-odt-styles-dir}. The two files are: - -@table @asis -@item @samp{OrgOdtStyles.xml} @anchor{x-orgodtstyles-xml} -This file contributes to the @samp{styles.xml} file of the final ODT -document. This file gets modified for the following purposes: - -@enumerate -@item -To control outline numbering based on user settings; - -@item -To add styles generated by @samp{htmlfontify.el} for fontification of -code blocks. -@end enumerate - -@item @samp{OrgOdtContentTemplate.xml} @anchor{x-orgodtcontenttemplate-xml} -This file contributes to the @samp{content.xml} file of the final ODT -document. The contents of the Org outline are inserted between the -@samp{} @dots{} @samp{} elements of this file. - -Apart from serving as a template file for the final @samp{content.xml}, -the file serves the following purposes: - -@enumerate -@item -It contains automatic styles for formatting of tables which are -referenced by the exporter; - -@item -It contains @samp{} @dots{} @samp{} -elements that control numbering of tables, images, equations, and -similar entities. -@end enumerate -@end table - -@anchor{x-overriding-factory-styles} The following two variables control -the location from where the ODT exporter picks up the custom styles -and content template files. Customize these variables to override the -factory styles used by the exporter. - -@table @asis -@item @code{org-odt-styles-file} -The ODT export back-end uses the file pointed to by this variable, -such as @samp{styles.xml}, for the final output. It can take one of the -following values: - -@table @asis -@item @samp{FILE.xml} -Use this file instead of the default @samp{styles.xml} - -@item @samp{FILE.odt} or @samp{FILE.ott} -Use the @samp{styles.xml} contained in the specified OpenDocument -Text or Template file - -@item @samp{FILE.odt} or @samp{FILE.ott} and a subset of included files -Use the @samp{styles.xml} contained in the specified OpenDocument Text -or Template file. Additionally extract the specified member files -and embed those within the final ODT document. - -Use this option if the @samp{styles.xml} file references additional -files like header and footer images. - -@item @code{nil} -Use the default @samp{styles.xml}. -@end table - -@item @code{org-odt-content-template-file} -Use this variable to specify the blank @samp{content.xml} used in the -final output. -@end table - -@anchor{Creating one-off styles} -@subsubheading Creating one-off styles - -The ODT export back-end can read embedded raw OpenDocument XML from -the Org file. Such direct formatting is useful for one-off instances. - -@table @asis -@item Embedding ODT tags as part of regular text -Enclose OpenDocument syntax in @samp{@@@@odt:...@@@@} for inline markup. For -example, to highlight a region of text do the following: - -@example -@@@@odt:This is highlighted -text@@@@. But this is regular text. -@end example - -@strong{Hint:} To see the above example in action, edit the @samp{styles.xml} -(see @ref{x-orgodtstyles-xml, , Factory styles}) and add a custom @emph{Highlight} style as shown -below: - -@example - - - -@end example - -@item Embedding a one-line OpenDocument XML -@cindex @samp{ODT}, keyword -The ODT export back-end can read one-liner options with @samp{#+ODT:} in -the Org file. For example, to force a page break: - -@example -#+ODT: -@end example - -@strong{Hint:} To see the above example in action, edit your -@samp{styles.xml} (see @ref{x-orgodtstyles-xml, , Factory styles}) and add a custom @samp{PageBreak} -style as shown below. - -@example - - - -@end example - -@item Embedding a block of OpenDocument XML -The ODT export back-end can also read ODT export blocks for -OpenDocument XML@. Such blocks use the @samp{#+BEGIN_EXPORT odt} -@dots{} @samp{#+END_EXPORT} constructs. - -For example, to create a one-off paragraph that uses bold text, do -the following: - -@example -#+BEGIN_EXPORT odt - - This paragraph is specially formatted and uses bold text. - -#+END_EXPORT -@end example -@end table - -@anchor{Customizing tables in ODT export} -@subsubheading Customizing tables in ODT export - -@cindex tables, in ODT export -@cindex @samp{ATTR_ODT}, keyword - -Override the default table format by specifying a custom table style -with the @samp{#+ATTR_ODT} line. For a discussion on default formatting of -tables, see @ref{Tables in ODT export}. - -This feature closely mimics the way table templates are defined in the -OpenDocument-v1.2 specification@footnote{@uref{http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html, OpenDocument-v1.2 Specification}}. - -@vindex org-odt-table-styles -For quick preview of this feature, install the settings below and export the -table that follows: - -@lisp -(setq org-export-odt-table-styles - (append org-export-odt-table-styles - '(("TableWithHeaderRowAndColumn" "Custom" - ((use-first-row-styles . t) - (use-first-column-styles . t))) - ("TableWithFirstRowandLastRow" "Custom" - ((use-first-row-styles . t) - (use-last-row-styles . t)))))) -@end lisp - -@example -#+ATTR_ODT: :style TableWithHeaderRowAndColumn -| Name | Phone | Age | -| Peter | 1234 | 17 | -| Anna | 4321 | 25 | -@end example - -The example above used @samp{Custom} template and installed two table -styles @samp{TableWithHeaderRowAndColumn} and -@samp{TableWithFirstRowandLastRow}. @strong{Important:} The OpenDocument styles -needed for producing the above template were pre-defined. They are -available in the section marked @samp{Custom Table Template} in -@samp{OrgOdtContentTemplate.xml} (see @ref{x-orgodtcontenttemplate-xml, , Factory styles}). For adding new -templates, define new styles there. - -To use this feature proceed as follows: - -@enumerate -@item -Create a table template@footnote{See the @samp{} element of the -OpenDocument-v1.2 specification.}. - -A table template is set of @samp{table-cell} and @samp{paragraph} styles for -each of the following table cell categories: - -@itemize -@item -Body -@item -First column -@item -Last column -@item -First row -@item -Last row -@item -Even row -@item -Odd row -@item -Even column -@item -Odd Column -@end itemize - -The names for the above styles must be chosen based on the name of -the table template using a well-defined convention. - -The naming convention is better illustrated with an example. For -a table template with the name @samp{Custom}, the needed style names are -listed in the following table. - -@multitable {aaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@headitem Cell type -@tab Cell style -@tab Paragraph style -@item Body -@tab @samp{CustomTableCell} -@tab @samp{CustomTableParagraph} -@item First column -@tab @samp{CustomFirstColumnTableCell} -@tab @samp{CustomFirstColumnTableParagraph} -@item Last column -@tab @samp{CustomLastColumnTableCell} -@tab @samp{CustomLastColumnTableParagraph} -@item First row -@tab @samp{CustomFirstRowTableCell} -@tab @samp{CustomFirstRowTableParagraph} -@item Last row -@tab @samp{CustomLastRowTableCell} -@tab @samp{CustomLastRowTableParagraph} -@item Even row -@tab @samp{CustomEvenRowTableCell} -@tab @samp{CustomEvenRowTableParagraph} -@item Odd row -@tab @samp{CustomOddRowTableCell} -@tab @samp{CustomOddRowTableParagraph} -@item Even column -@tab @samp{CustomEvenColumnTableCell} -@tab @samp{CustomEvenColumnTableParagraph} -@item Odd column -@tab @samp{CustomOddColumnTableCell} -@tab @samp{CustomOddColumnTableParagraph} -@end multitable - -To create a table template with the name @samp{Custom}, define the above -styles in the @samp{} @dots{} -@samp{} element of the content template file -(see @ref{x-orgodtcontenttemplate-xml, , Factory styles}). - -@item -Define a table style@footnote{See the attributes @samp{table:template-name}, -@samp{table:use-first-row-styles}, @samp{table:use-last-row-styles}, -@samp{table:use-first-column-styles}, @samp{table:use-last-column-styles}, -@samp{table:use-banding-rows-styles}, and @samp{table:use-banding-column-styles} -of the @samp{} element in the OpenDocument-v1.2 specification.}. - -@vindex org-odt-table-styles -To define a table style, create an entry for the style in the -variable @code{org-odt-table-styles} and specify the following: - -@itemize -@item -the name of the table template created in step (1), -@item -the set of cell styles in that template that are to be activated. -@end itemize - -For example, the entry below defines two different table styles -@samp{TableWithHeaderRowAndColumn} and @samp{TableWithFirstRowandLastRow} -based on the same template @samp{Custom}. The styles achieve their -intended effect by selectively activating the individual cell -styles in that template. - -@lisp -(setq org-export-odt-table-styles - (append org-export-odt-table-styles - '(("TableWithHeaderRowAndColumn" "Custom" - ((use-first-row-styles . t) - (use-first-column-styles . t))) - ("TableWithFirstRowandLastRow" "Custom" - ((use-first-row-styles . t) - (use-last-row-styles . t)))))) -@end lisp - -@item -Associate a table with the table style. - -To do this, specify the table style created in step (2) as part of -the @samp{ATTR_ODT} line as shown below. - -@example -#+ATTR_ODT: :style TableWithHeaderRowAndColumn -| Name | Phone | Age | -| Peter | 1234 | 17 | -| Anna | 4321 | 25 | -@end example -@end enumerate - -@anchor{Validating OpenDocument XML} -@subsubheading Validating OpenDocument XML - -Sometimes ODT format files may not open due to @samp{.odt} file corruption. -To verify if such a file is corrupt, validate it against the -OpenDocument Relax NG Compact (RNC) syntax schema. But first the -@samp{.odt} files have to be decompressed using @samp{zip}. Note that @samp{.odt} -files are ZIP archives: @ref{File Archives,,,emacs,}. The contents of -ODT files are in XML@. For general help with validation---and -schema-sensitive editing---of XML files: @ref{Introduction,,,nxml-mode,}. - -@vindex org-export-odt-schema-dir -Customize @code{org-odt-schema-dir} to point to a directory with -OpenDocument RNC files and the needed schema-locating rules. The ODT -export back-end takes care of updating the -@code{rng-schema-locating-files}. - -@node Org Export -@section Org Export - -@cindex Org export -@emph{org} export back-end creates a normalized version of the Org document -in current buffer. The exporter evaluates Babel code (see @ref{Evaluating Code Blocks}) and removes content specific to other back-ends. - -@anchor{Org export commands} -@subheading Org export commands - -@table @asis -@item @kbd{C-c C-e O o} (@code{org-org-export-to-org}) -@kindex C-c C-e O o -@findex org-org-export-to-org -Export as an Org file with a @samp{.org} extension. For @samp{myfile.org}, -Org exports to @samp{myfile.org.org}, overwriting without warning. - -@item @kbd{C-c C-e O v} (~~) -@kindex C-c C-e O v -Export to an Org file, then open it. -@end table - -@node Texinfo Export -@section Texinfo Export - -@menu -* Texinfo export commands:: Invoking commands. -* Texinfo specific export settings:: Setting the environment. -* Texinfo file header:: Generating the header. -* Texinfo title and copyright page:: Creating preamble pages. -* Info directory file:: Installing a manual in Info file hierarchy. -* Headings and sectioning structure:: Building document structure. -* Indices:: Creating indices. -* Quoting Texinfo code:: Incorporating literal Texinfo code. -* Plain lists in Texinfo export:: List attributes. -* Tables in Texinfo export:: Table attributes. -* Images in Texinfo export:: Image attributes. -* Quotations in Texinfo export:: Quote block attributes. -* Special blocks in Texinfo export:: Special block attributes. -* A Texinfo example:: Processing Org to Texinfo. -@end menu - -@node Texinfo export commands -@subsection Texinfo export commands - -@table @asis -@item @kbd{C-c C-e i t} (@code{org-texinfo-export-to-texinfo}) -@kindex C-c C-e i t -@findex org-texinfo-export-to-texinfo -Export as a Texinfo file with @samp{.texi} extension. For @samp{myfile.org}, -Org exports to @samp{myfile.texi}, overwriting without warning. - -@item @kbd{C-c C-e i i} (@code{org-texinfo-export-to-info}) -@kindex C-c C-e i i -@findex org-texinfo-export-to-info -@vindex org-texinfo-info-process -Export to Texinfo format first and then process it to make an Info -file. To generate other formats, such as DocBook, customize the -@code{org-texinfo-info-process} variable. -@end table - -@node Texinfo specific export settings -@subsection Texinfo specific export settings - -The Texinfo export back-end has several additional keywords for -customizing Texinfo output. Setting these keywords works similar to -the general options (see @ref{Export Settings}). - -@table @asis -@item @samp{SUBTITLE} -@cindex @samp{SUBTITLE}, keyword -The document subtitle. - -@item @samp{SUBAUTHOR} -@cindex @samp{SUBAUTHOR}, keyword -Additional authors for the document. - -@item @samp{TEXINFO_FILENAME} -@cindex @samp{TEXINFO_FILENAME}, keyword -The Texinfo filename. - -@item @samp{TEXINFO_CLASS} -@cindex @samp{TEXINFO_CLASS}, keyword -@vindex org-texinfo-default-class -The default document class (@code{org-texinfo-default-class}), which must -be a member of @code{org-texinfo-classes}. - -@item @samp{TEXINFO_HEADER} -@cindex @samp{TEXINFO_HEADER}, keyword -Arbitrary lines inserted at the end of the header. - -@item @samp{TEXINFO_POST_HEADER} -@cindex @samp{TEXINFO_POST_HEADER}, keyword -Arbitrary lines inserted after the end of the header. - -@item @samp{TEXINFO_DIR_CATEGORY} -@cindex @samp{TEXINFO_DIR_CATEGORY}, keyword -The directory category of the document. - -@item @samp{TEXINFO_DIR_TITLE} -@cindex @samp{TEXINFO_DIR_TITLE}, keyword -The directory title of the document. - -@item @samp{TEXINFO_DIR_DESC} -@cindex @samp{TEXINFO_DIR_DESC}, keyword -The directory description of the document. - -@item @samp{TEXINFO_PRINTED_TITLE} -@cindex @samp{TEXINFO_PRINTED_TITLE}, keyword -The printed title of the document. -@end table - -@node Texinfo file header -@subsection Texinfo file header - -@cindex @samp{TEXINFO_FILENAME}, keyword -After creating the header for a Texinfo file, the Texinfo back-end -automatically generates a name and destination path for the Info file. -To override this default with a more sensible path and name, specify -the @samp{TEXINFO_FILENAME} keyword. - -@vindex org-texinfo-coding-system -@cindex @samp{TEXINFO_HEADER}, keyword -Along with the output's file name, the Texinfo header also contains -language details (see @ref{Export Settings}) and encoding system as set in -the @code{org-texinfo-coding-system} variable. Insert @samp{TEXINFO_HEADER} -keywords for each additional command in the header, for example: - -@example -#+TEXINFO_HEADER: @@synindex -@end example - - -@cindex @samp{TEXINFO_CLASS}, keyword -@vindex org-texinfo-classes -Instead of repeatedly installing the same set of commands, define -a class in @code{org-texinfo-classes} once, and then activate it in the -document by setting the @samp{TEXINFO_CLASS} keyword to that class. - -@node Texinfo title and copyright page -@subsection Texinfo title and copyright page - -@cindex @samp{TEXINFO_PRINTED_TITLE}, keyword -The default template for hard copy output has a title page with -@samp{TITLE} and @samp{AUTHOR} keywords (see @ref{Export Settings}). To replace the -regular title with something different for the printed version, use -the @samp{TEXINFO_PRINTED_TITLE} and @samp{SUBTITLE} keywords. Both expect raw -Texinfo code for setting their values. - -@cindex @samp{SUBAUTHOR}, keyword -If one @samp{AUTHOR} line is not sufficient, add multiple @samp{SUBAUTHOR} -keywords. They have to be set in raw Texinfo code. - -@example -#+AUTHOR: Jane Smith -#+SUBAUTHOR: John Doe -#+TEXINFO_PRINTED_TITLE: This Long Title@@@@inlinefmt@{tex,@@*@} Is Broken in @@TeX@{@} -@end example - -@cindex @samp{COPYING}, property -Copying material is defined in a dedicated headline with a non-@code{nil} -@samp{COPYING} property. The back-end inserts the contents within -a @samp{@@copying} command at the beginning of the document. The heading -itself does not appear in the structure of the document. - -Copyright information is printed on the back of the title page. - -@example -* Legalese - :PROPERTIES: - :COPYING: t - :END: - - This is a short example of a complete Texinfo file, version 1.0. - - Copyright \copy 2016 Free Software Foundation, Inc. -@end example - -@node Info directory file -@subsection Info directory file - -@cindex @samp{dir} file, in Texinfo export -@cindex Info directory file, in Texinfo export -@cindex @code{install-info}, in Texinfo export - -@cindex @samp{TEXINFO_DIR_CATEGORY}, keyword -@cindex @samp{TEXINFO_DIR_TITLE}, keyword -@cindex @samp{TEXINFO_DIR_DESC}, keyword -The end result of the Texinfo export process is the creation of an -Info file. This Info file's metadata has variables for category, -title, and description: @samp{TEXINFO_DIR_CATEGORY}, @samp{TEXINFO_DIR_TITLE}, -and @samp{TEXINFO_DIR_DESC} keywords that establish where in the Info -hierarchy the file fits. - -Here is an example that writes to the Info directory file: - -@example -#+TEXINFO_DIR_CATEGORY: Emacs -#+TEXINFO_DIR_TITLE: Org Mode: (org) -#+TEXINFO_DIR_DESC: Outline-based notes management and organizer -@end example - -@node Headings and sectioning structure -@subsection Headings and sectioning structure - -@vindex org-texinfo-classes -@vindex org-texinfo-default-class -@cindex @samp{TEXINFO_CLASS}, keyword -The Texinfo export back-end uses a pre-defined scheme to convert Org -headlines to equivalent Texinfo structuring commands. A scheme like -this maps top-level headlines to numbered chapters tagged as -@code{@@chapter} and lower-level headlines to unnumbered chapters tagged as -@code{@@unnumbered}. To override such mappings to introduce @code{@@part} or -other Texinfo structuring commands, define a new class in -@code{org-texinfo-classes}. Activate the new class with the -@samp{TEXINFO_CLASS} keyword. When no new class is defined and activated, -the Texinfo export back-end defaults to the -@code{org-texinfo-default-class}. - -If an Org headline's level has no associated Texinfo structuring -command, or is below a certain threshold (see @ref{Export Settings}), then -the Texinfo export back-end makes it into a list item. - -@cindex @samp{APPENDIX}, property -The Texinfo export back-end makes any headline with a non-@code{nil} -@samp{APPENDIX} property into an appendix. This happens independent of the -Org headline level or the @samp{TEXINFO_CLASS} keyword. - -@cindex @samp{ALT_TITLE}, property -@cindex @samp{DESCRIPTION}, property -The Texinfo export back-end creates a menu entry after the Org -headline for each regular sectioning structure. To override this with -a shorter menu entry, use the @samp{ALT_TITLE} property (see @ref{Table of Contents}). Texinfo menu entries also have an option for a longer -@samp{DESCRIPTION} property. Here's an example that uses both to override -the default menu entry: - -@example -* Controlling Screen Display - :PROPERTIES: - :ALT_TITLE: Display - :DESCRIPTION: Controlling Screen Display - :END: -@end example - -@cindex Top node, in Texinfo export -The text before the first headline belongs to the @emph{Top} node, i.e., -the node in which a reader enters an Info manual. As such, it is -expected not to appear in printed output generated from the @samp{.texi} -file. See @ref{The Top Node,,,texinfo,}, for more information. - -@node Indices -@subsection Indices - -@cindex @samp{CINDEX}, keyword -@cindex concept index, in Texinfo export -@cindex @samp{FINDEX}, keyword -@cindex function index, in Texinfo export -@cindex @samp{KINDEX}, keyword -@cindex keystroke index, in Texinfo export -@cindex @samp{PINDEX}, keyword -@cindex program index, in Texinfo export -@cindex @samp{TINDEX}, keyword -@cindex data type index, in Texinfo export -@cindex @samp{VINDEX}, keyword -@cindex variable index, in Texinfo export -The Texinfo export back-end recognizes these indexing keywords if used -in the Org file: @samp{CINDEX}, @samp{FINDEX}, @samp{KINDEX}, @samp{PINDEX}, @samp{TINDEX} and -@samp{VINDEX}. Write their value as verbatim Texinfo code; in particular, -@samp{@{}, @samp{@}} and @samp{@@} characters need to be escaped with @samp{@@} if they do not -belong to a Texinfo command. - -@example -#+CINDEX: Defining indexing entries -@end example - - -@cindex @samp{INDEX}, property -For the back-end to generate an index entry for a headline, set the -@samp{INDEX} property to @samp{cp} or @samp{vr}. These abbreviations come from -Texinfo that stand for concept index and variable index. The Texinfo -manual has abbreviations for all other kinds of indexes. The back-end -exports the headline as an unnumbered chapter or section command, and -then inserts the index after its contents. - -@example -* Concept Index - :PROPERTIES: - :INDEX: cp - :END: -@end example - -@node Quoting Texinfo code -@subsection Quoting Texinfo code - -Use any of the following three methods to insert or escape raw Texinfo -code: - -@cindex @samp{TEXINFO}, keyword -@cindex @samp{BEGIN_EXPORT texinfo} -@example -Richard @@@@texinfo:@@sc@{@@@@Stallman@@@@texinfo:@}@@@@ commence' GNU. - -#+TEXINFO: @@need800 -This paragraph is preceded by... - -#+BEGIN_EXPORT texinfo - @@auindex Johnson, Mark - @@auindex Lakoff, George -#+END_EXPORT -@end example - -@node Plain lists in Texinfo export -@subsection Plain lists in Texinfo export - -@cindex @samp{ATTR_TEXINFO}, keyword -@cindex two-column tables, in Texinfo export -@cindex table-type, Texinfo attribute -The Texinfo export back-end by default converts description lists in -the Org file using the default command @samp{@@table}, which results in -a table with two columns. To change this behavior, set @samp{:table-type} -attribute to either @samp{ftable} or @samp{vtable} value. For more information, -see @ref{Two-column Tables,,,texinfo,}. - -@vindex org-texinfo-table-default-markup -@cindex indic, Texinfo attribute -The Texinfo export back-end by default also applies a text highlight -based on the defaults stored in @code{org-texinfo-table-default-markup}. -To override the default highlight command, specify another one with -the @samp{:indic} attribute. - -@cindex multiple items in Texinfo lists -@cindex sep, Texinfo attribute -Org syntax is limited to one entry per list item. Nevertheless, the -Texinfo export back-end can split that entry according to any text -provided through the @samp{:sep} attribute. Each part then becomes a new -entry in the first column of the table. - -The following example illustrates all the attributes above: - -@example -#+ATTR_TEXINFO: :table-type vtable :sep , :indic asis -- foo, bar :: This is the common text for variables foo and bar. -@end example - -@noindent -becomes - -@example -@@vtable @@asis -@@item foo -@@itemx bar -This is the common text for variables foo and bar. -@@end table -@end example - -@cindex lettered lists, in Texinfo export -@cindex enum, Texinfo attribute -Ordered lists are numbered when exported to Texinfo format. Such -numbering obeys any counter (see @ref{Plain Lists}) in the first item of -the list. The @samp{:enum} attribute also let you start the list at -a specific number, or switch to a lettered list, as illustrated here - -@example -#+ATTR_TEXINFO: :enum A -1. Alpha -2. Bravo -3. Charlie -@end example - -@node Tables in Texinfo export -@subsection Tables in Texinfo export - -@cindex @samp{ATTR_TEXINFO}, keyword -When exporting tables, the Texinfo export back-end uses the widest -cell width in each column. To override this and instead specify as -fractions of line length, use the @samp{:columns} attribute. See example -below. - -@example -#+ATTR_TEXINFO: :columns .5 .5 -| a cell | another cell | -@end example - -@node Images in Texinfo export -@subsection Images in Texinfo export - -@cindex @samp{ATTR_TEXINFO}, keyword -Insert a file link to the image in the Org file, and the Texinfo -export back-end inserts the image. These links must have the usual -supported image extensions and no descriptions. To scale the image, -use @samp{:width} and @samp{:height} attributes. For alternate text, use @samp{:alt} -and specify the text using Texinfo code, as shown in the example: - -@example -#+ATTR_TEXINFO: :width 1in :alt Alternate @@i@{text@} -[[ridt.pdf]] -@end example - -@node Quotations in Texinfo export -@subsection Quotations in Texinfo export - -@cindex @samp{ATTR_TEXINFO}, keyword -You can write the text of a quotation within a quote block (see -@ref{Paragraphs}). You may also emphasize some text at the beginning of -the quotation with the @samp{:tag} attribute. - -@example -#+ATTR_TEXINFO: :tag Warning -#+BEGIN_QUOTE -Striking your thumb with a hammer may cause severe pain and discomfort. -#+END_QUOTE -@end example - -To specify the author of the quotation, use the @samp{:author} attribute. - -@example -#+ATTR_TEXINFO: :author King Arthur -#+BEGIN_QUOTE -The Lady of the Lake, her arm clad in the purest shimmering samite, -held aloft Excalibur from the bosom of the water, signifying by divine -providence that I, Arthur, was to carry Excalibur. That is why I am -your king. -#+END_QUOTE -@end example - -@node Special blocks in Texinfo export -@subsection Special blocks in Texinfo export - -@cindex @samp{ATTR_TEXINFO}, keyword - -The Texinfo export back-end converts special blocks to commands with -the same name. It also adds any @samp{:options} attributes to the end of -the command, as shown in this example: - -@example -#+ATTR_TEXINFO: :options org-org-export-to-org ... -#+BEGIN_defun - A somewhat obsessive function name. -#+END_defun -@end example - -@noindent -becomes - -@example -@@defun org-org-export-to-org ... - A somewhat obsessive function name. -@@end defun -@end example - -@node A Texinfo example -@subsection A Texinfo example - -Here is a more detailed example Org file. See -@ref{GNU Sample Texts,,,texinfo,} for an equivalent example using -Texinfo code. - -@example -#+TITLE: GNU Sample @{@{@{version@}@}@} -#+SUBTITLE: for version @{@{@{version@}@}@}, @{@{@{updated@}@}@} -#+AUTHOR: A.U. Thor -#+EMAIL: bug-sample@@gnu.org - -#+OPTIONS: ':t toc:t author:t email:t -#+LANGUAGE: en - -#+MACRO: version 2.0 -#+MACRO: updated last updated 4 March 2014 - -#+TEXINFO_FILENAME: sample.info -#+TEXINFO_HEADER: @@syncodeindex pg cp - -#+TEXINFO_DIR_CATEGORY: Texinfo documentation system -#+TEXINFO_DIR_TITLE: sample: (sample) -#+TEXINFO_DIR_DESC: Invoking sample - -#+TEXINFO_PRINTED_TITLE: GNU Sample - -This manual is for GNU Sample (version @{@{@{version@}@}@}, -@{@{@{updated@}@}@}). - -* Copying - :PROPERTIES: - :COPYING: t - :END: - - This manual is for GNU Sample (version @{@{@{version@}@}@}, - @{@{@{updated@}@}@}), which is an example in the Texinfo documentation. - - Copyright \copy 2016 Free Software Foundation, Inc. - - #+BEGIN_QUOTE - Permission is granted to copy, distribute and/or modify this - document under the terms of the GNU Free Documentation License, - Version 1.3 or any later version published by the Free Software - Foundation; with no Invariant Sections, with no Front-Cover Texts, - and with no Back-Cover Texts. A copy of the license is included in - the section entitled "GNU Free Documentation License". - #+END_QUOTE - -* Invoking sample - - #+PINDEX: sample - #+CINDEX: invoking @@command@{sample@} - - This is a sample manual. There is no sample program to invoke, but - if there were, you could see its basic usage and command line - options here. - -* GNU Free Documentation License - :PROPERTIES: - :APPENDIX: t - :END: - - #+INCLUDE: fdl.org - -* Index - :PROPERTIES: - :INDEX: cp - :END: -@end example - -@node iCalendar Export -@section iCalendar Export - -@cindex iCalendar export - -A large part of Org mode's interoperability success is its ability to -easily export to or import from external applications. The iCalendar -export back-end takes calendar data from Org files and exports to the -standard iCalendar format. - -@vindex org-icalendar-include-todo -@vindex org-icalendar-use-deadline -@vindex org-icalendar-use-scheduled -The iCalendar export back-end can also incorporate TODO entries based -on the configuration of the @code{org-icalendar-include-todo} variable. -The back-end exports plain timestamps as @samp{VEVENT}, TODO items as -@samp{VTODO}, and also create events from deadlines that are in non-TODO -items. The back-end uses the deadlines and scheduling dates in Org -TODO items for setting the start and due dates for the iCalendar TODO -entry. Consult the @code{org-icalendar-use-deadline} and -@code{org-icalendar-use-scheduled} variables for more details. - -@vindex org-icalendar-categories -@vindex org-icalendar-alarm-time -For tags on the headline, the iCalendar export back-end makes them -into iCalendar categories. To tweak the inheritance of tags and TODO -states, configure the variable @code{org-icalendar-categories}. To assign -clock alarms based on time, configure the @code{org-icalendar-alarm-time} -variable. - -@vindex org-icalendar-store-UID -@cindex @samp{ID}, property -The iCalendar format standard requires globally unique identifier---or -UID---for each entry. The iCalendar export back-end creates UIDs -during export. To save a copy of the UID in the Org file set the -variable @code{org-icalendar-store-UID}. The back-end looks for the @samp{ID} -property of the entry for re-using the same UID for subsequent -exports. - -Since a single Org entry can result in multiple iCalendar -entries---timestamp, deadline, scheduled item, or TODO item---Org adds -prefixes to the UID, depending on which part of the Org entry -triggered the creation of the iCalendar entry. Prefixing ensures UIDs -remains unique, yet enable synchronization programs trace the -connections. - -@table @asis -@item @kbd{C-c C-e c f} (@code{org-icalendar-export-to-ics}) -@kindex C-c C-e c f -@findex org-icalendar-export-to-ics -Create iCalendar entries from the current Org buffer and store them -in the same directory, using a file extension @samp{.ics}. - -@item @kbd{C-c C-e c a} (@code{org-icalendar-export-agenda-files}) -@kindex C-c C-e c a -@findex org-icalendar-export-agenda-files -Create iCalendar entries from Org files in @code{org-agenda-files} and -store in a separate iCalendar file for each Org file. - -@item @kbd{C-c C-e c c} (@code{org-icalendar-combine-agenda-files}) -@kindex C-c C-e c c -@findex org-icalendar-combine-agenda-files -@vindex org-icalendar-combined-agenda-file -Create a combined iCalendar file from Org files in -@code{org-agenda-files} and write it to -@code{org-icalendar-combined-agenda-file} file name. -@end table - -@cindex @samp{SUMMARY}, property -@cindex @samp{DESCRIPTION}, property -@cindex @samp{LOCATION}, property -@cindex @samp{TIMEZONE}, property -@cindex @samp{CLASS}, property -The iCalendar export back-end includes @samp{SUMMARY}, @samp{DESCRIPTION}, -@samp{LOCATION}, @samp{TIMEZONE} and @samp{CLASS} properties from the Org entries -when exporting. To force the back-end to inherit the @samp{LOCATION}, -@samp{TIMEZONE} and @samp{CLASS} properties, configure the -@code{org-use-property-inheritance} variable. - -@vindex org-icalendar-include-body -When Org entries do not have @samp{SUMMARY}, @samp{DESCRIPTION}, @samp{LOCATION} and -@samp{CLASS} properties, the iCalendar export back-end derives the summary -from the headline, and derives the description from the body of the -Org item. The @code{org-icalendar-include-body} variable limits the -maximum number of characters of the content are turned into its -description. - -The @samp{TIMEZONE} property can be used to specify a per-entry time zone, -and is applied to any entry with timestamp information. Time zones -should be specified as per the IANA time zone database format, e.g., -@samp{Asia/Almaty}. Alternately, the property value can be @samp{UTC}, to force -UTC time for this entry only. - -The @samp{CLASS} property can be used to specify a per-entry visibility -class or access restrictions, and is applied to any entry with class -information. The iCalendar standard defines three visibility classes: -@table @asis -@item @samp{PUBLIC} -The entry is publicly visible (this is the default). -@item @samp{CONFIDENTIAL} -Only a limited group of clients get access to the -event. -@item @samp{PRIVATE} -The entry can be retrieved only by its owner. -@end table -The server should treat unknown class properties the same as -@samp{PRIVATE}. - -Exporting to iCalendar format depends in large part on the -capabilities of the destination application. Some are more lenient -than others. Consult the Org mode FAQ for advice on specific -applications. - -@node Other Built-in Back-ends -@section Other Built-in Back-ends - -Other export back-ends included with Org are: - -@itemize -@item -@samp{ox-man.el}: Export to a man page. -@end itemize - -To activate such back-ends, either customize @code{org-export-backends} or -load directly with @samp{(require 'ox-man)}. On successful load, the -back-end adds new keys in the export dispatcher (see @ref{The Export Dispatcher}). - -Follow the comment section of such files, for example, @samp{ox-man.el}, -for usage and configuration details. - -@node Advanced Export Configuration -@section Advanced Export Configuration - - - -@anchor{Hooks} -@subheading Hooks - -@vindex org-export-before-processing-hook -@vindex org-export-before-parsing-hook -The export process executes two hooks before the actual exporting -begins. The first hook, @code{org-export-before-processing-hook}, runs -before any expansions of macros, Babel code, and include keywords in -the buffer. The second hook, @code{org-export-before-parsing-hook}, runs -before the buffer is parsed. - -Functions added to these hooks are called with a single argument: the -export back-end actually used, as a symbol. You may use them for -heavy duty structural modifications of the document. For example, you -can remove every headline in the buffer during export like this: - -@lisp -(defun my-headline-removal (backend) - "Remove all headlines in the current buffer. -BACKEND is the export back-end being used, as a symbol." - (org-map-entries - (lambda () (delete-region (point) (line-beginning-position 2))))) - -(add-hook 'org-export-before-parsing-hook 'my-headline-removal) -@end lisp - -@anchor{Filters} -@subheading Filters - -@cindex Filters, exporting -Filters are lists of functions to be applied to certain parts for -a given back-end. The output from the first function in the filter is -passed on to the next function in the filter. The final output is the -output from the final function in the filter. - -The Org export process has many filter sets applicable to different -types of objects, plain text, parse trees, export options, and final -output formats. The filters are named after the element type or -object type: @code{org-export-filter-TYPE-functions}, where @var{TYPE} -is the type targeted by the filter. Valid types are: - -@multitable @columnfractions 0.33 0.33 0.33 -@item body -@tab bold -@tab babel-call -@item center-block -@tab clock -@tab code -@item diary-sexp -@tab drawer -@tab dynamic-block -@item entity -@tab example-block -@tab export-block -@item export-snippet -@tab final-output -@tab fixed-width -@item footnote-definition -@tab footnote-reference -@tab headline -@item horizontal-rule -@tab inline-babel-call -@tab inline-src-block -@item inlinetask -@tab italic -@tab item -@item keyword -@tab latex-environment -@tab latex-fragment -@item line-break -@tab link -@tab node-property -@item options -@tab paragraph -@tab parse-tree -@item plain-list -@tab plain-text -@tab planning -@item property-drawer -@tab quote-block -@tab radio-target -@item section -@tab special-block -@tab src-block -@item statistics-cookie -@tab strike-through -@tab subscript -@item superscript -@tab table -@tab table-cell -@item table-row -@tab target -@tab timestamp -@item underline -@tab verbatim -@tab verse-block -@end multitable - -Here is an example filter that replaces non-breaking spaces @code{ } in the -Org buffer with @samp{~} for the @LaTeX{} back-end. - -@lisp -(defun my-latex-filter-nobreaks (text backend info) - "Ensure \" \" are properly handled in LaTeX export." - (when (org-export-derived-backend-p backend 'latex) - (replace-regexp-in-string " " "~" text))) - -(add-to-list 'org-export-filter-plain-text-functions - 'my-latex-filter-nobreaks) -@end lisp - -A filter requires three arguments: the code to be transformed, the -name of the back-end, and some optional information about the export -process. The third argument can be safely ignored. Note the use of -@code{org-export-derived-backend-p} predicate that tests for @emph{latex} -back-end or any other back-end, such as @emph{beamer}, derived from -@emph{latex}. - -@anchor{Defining filters for individual files} -@subheading Defining filters for individual files - -The Org export can filter not just for back-ends, but also for -specific files through the @samp{BIND} keyword. Here is an example with -two filters; one removes brackets from time stamps, and the other -removes strike-through text. The filter functions are defined in -a code block in the same Org file, which is a handy location for -debugging. - -@example -#+BIND: org-export-filter-timestamp-functions (tmp-f-timestamp) -#+BIND: org-export-filter-strike-through-functions (tmp-f-strike-through) -#+BEGIN_SRC emacs-lisp :exports results :results none - (defun tmp-f-timestamp (s backend info) - (replace-regexp-in-string "&[lg]t;\\|[][]" "" s)) - (defun tmp-f-strike-through (s backend info) "") -#+END_SRC -@end example - -@anchor{Extending an existing back-end} -@subheading Extending an existing back-end - -Some parts of the conversion process can be extended for certain -elements so as to introduce a new or revised translation. That is how -the HTML export back-end was extended to handle Markdown format. The -extensions work seamlessly so any aspect of filtering not done by the -extended back-end is handled by the original back-end. Of all the -export customization in Org, extending is very powerful as it operates -at the parser level. - -For this example, make the @emph{ascii} back-end display the language used -in a source code block. Also make it display only when some attribute -is non-@code{nil}, like the following: - -@example -#+ATTR_ASCII: :language t -@end example - - -Then extend ASCII back-end with a custom ``my-ascii'' back-end. - -@lisp -(defun my-ascii-src-block (src-block contents info) - "Transcode a SRC-BLOCK element from Org to ASCII. -CONTENTS is nil. INFO is a plist used as a communication -channel." - (if (not (org-export-read-attribute :attr_ascii src-block :language)) - (org-export-with-backend 'ascii src-block contents info) - (concat - (format ",--[ %s ]--\n%s`----" - (org-element-property :language src-block) - (replace-regexp-in-string - "^" "| " - (org-element-normalize-string - (org-export-format-code-default src-block info))))))) - -(org-export-define-derived-backend 'my-ascii 'ascii - :translate-alist '((src-block . my-ascii-src-block))) -@end lisp - -The @code{my-ascii-src-block} function looks at the attribute above the -current element. If not true, hands over to @emph{ascii} back-end. If -true, which it is in this example, it creates a box around the code -and leaves room for the inserting a string for language. The last -form creates the new back-end that springs to action only when -translating @code{src-block} type elements. - -To use the newly defined back-end, evaluate the following from an Org -buffer: - -@lisp -(org-export-to-buffer 'my-ascii "*Org MY-ASCII Export*") -@end lisp - -Further steps to consider would be an interactive function, -self-installing an item in the export dispatcher menu, and other -user-friendly improvements. - -@node Export in Foreign Buffers -@section Export in Foreign Buffers - -The export back-ends in Org often include commands to convert selected -regions. A convenient feature of this in-place conversion is that the -exported output replaces the original source. Here are such -functions: - -@table @asis -@item @code{org-ascii-convert-region-to-ascii} -@findex org-ascii-convert-region-to-ascii -Convert the selected region into ASCII@. - -@item @code{org-ascii-convert-region-to-utf8} -@findex org-ascii-convert-region-to-utf8 -Convert the selected region into UTF-8. - -@item @code{org-html-convert-region-to-html} -@findex org-html-convert-region-to-html -Convert the selected region into HTML@. - -@item @code{org-latex-convert-region-to-latex} -@findex org-latex-convert-region-to-latex -Convert the selected region into @LaTeX{}. - -@item @code{org-texinfo-convert-region-to-texinfo} -@findex org-texinfo-convert-region-to-texinfo -Convert the selected region into Texinfo. - -@item @code{org-md-convert-region-to-md} -@findex org-md-convert-region-to-md -Convert the selected region into Markdown. -@end table - -In-place conversions are particularly handy for quick conversion of -tables and lists in foreign buffers. For example, in an HTML buffer, -write a list in Org syntax, select it, and convert it to HTML with -@kbd{M-x org-html-convert-region-to-html}. - -@menu -* Bare HTML:: Exporting HTML without CSS, Javascript, etc. -@end menu - -@node Bare HTML -@subsection Exporting to minimal HTML - -If you want to output a minimal HTML file, with no CSS, no Javascript, -no preamble or postamble, here are the variable you would need to set: - -@vindex org-html-head -@vindex org-html-head-extra -@vindex org-html-head-include-default-style -@vindex org-html-head-include-scripts -@vindex org-html-preamble -@vindex org-html-postamble -@vindex org-html-use-infojs -@lisp -(setq org-html-head "" - org-html-head-extra "" - org-html-head-include-default-style nil - org-html-head-include-scripts nil - org-html-preamble nil - org-html-postamble nil - org-html-use-infojs nil) -@end lisp - -@node Publishing -@chapter Publishing - -@cindex publishing - -Org includes a publishing management system that allows you to -configure automatic HTML conversion of @emph{projects} composed of -interlinked Org files. You can also configure Org to automatically -upload your exported HTML pages and related attachments, such as -images and source code files, to a web server. - -You can also use Org to convert files into PDF, or even combine HTML -and PDF conversion so that files are available in both formats on the -server. - -Publishing has been contributed to Org by David O'Toole. - -@menu -* Configuration:: Defining projects. -* Uploading Files:: How to get files up on the server. -* Sample Configuration:: Example projects. -* Triggering Publication:: Publication commands. -@end menu - -@node Configuration -@section Configuration - -Publishing needs significant configuration to specify files, -destination and many other properties of a project. - -@menu -* Project alist:: The central configuration variable. -* Sources and destinations:: From here to there. -* Selecting files:: What files are part of the project? -* Publishing action:: Setting the function doing the publishing. -* Publishing options:: Tweaking HTML/@LaTeX{} export. -* Publishing links:: Which links keep working after publishing? -* Site map:: Generating a list of all pages. -* Generating an index:: An index that reaches across pages. -@end menu - -@node Project alist -@subsection The variable @code{org-publish-project-alist} - -@cindex projects, for publishing - -@vindex org-publish-project-alist -Publishing is configured almost entirely through setting the value of -one variable, called @code{org-publish-project-alist}. Each element of the -list configures one project, and may be in one of the two following -forms: - -@lisp -("project-name" :property value :property value ...) -@end lisp - -@noindent -i.e., a well-formed property list with alternating keys and values, -or: - -@lisp -("project-name" :components ("project-name" "project-name" ...)) -@end lisp - -In both cases, projects are configured by specifying property values. -A project defines the set of files that are to be published, as well -as the publishing configuration to use when publishing those files. -When a project takes the second form listed above, the individual -members of the @code{:components} property are taken to be sub-projects, -which group together files requiring different publishing options. -When you publish such a ``meta-project'', all the components are also -published, in the sequence given. - -@node Sources and destinations -@subsection Sources and destinations for files - -@cindex directories, for publishing - -Most properties are optional, but some should always be set. In -particular, Org needs to know where to look for source files, and -where to put published files. - -@table @asis -@item @code{:base-directory} -Directory containing publishing source files. - -@item @code{:publishing-directory} -Directory where output files are published. You can directly -publish to a webserver using a file name syntax appropriate for the -Emacs tramp package. Or you can publish to a local directory and -use external tools to upload your website (see @ref{Uploading Files}). - -@item @code{:preparation-function} -Function or list of functions to be called before starting the -publishing process, for example, to run @samp{make} for updating files to -be published. Each preparation function is called with a single -argument, the project property list. - -@item @code{:completion-function} -Function or list of functions called after finishing the publishing -process, for example, to change permissions of the resulting files. -Each completion function is called with a single argument, the -project property list. -@end table - -@node Selecting files -@subsection Selecting files - -@cindex files, selecting for publishing - -By default, all files with extension @samp{.org} in the base directory are -considered part of the project. This can be modified by setting the -following properties - -@table @asis -@item @code{:base-extension} -Extension---without the dot---of source files. This actually is -a regular expression. Set this to the symbol @code{any} if you want to -get all files in @code{:base-directory}, even without extension. - -@item @code{:exclude} -Regular expression to match file names that should not be published, -even though they have been selected on the basis of their extension. - -@item @code{:include} -List of files to be included regardless of @code{:base-extension} and -@code{:exclude}. - -@item @code{:recursive} -Non-@code{nil} means, check base-directory recursively for files to -publish. -@end table - -@node Publishing action -@subsection Publishing action - -@cindex action, for publishing - -Publishing means that a file is copied to the destination directory -and possibly transformed in the process. The default transformation -is to export Org files as HTML files, and this is done by the function -@code{org-publish-org-to-html} which calls the HTML exporter (see @ref{HTML Export}). But you can also publish your content as PDF files using -@code{org-publish-org-to-pdf}, or as ASCII, Texinfo, etc., using the -corresponding functions. - -If you want to publish the Org file as an @samp{.org} file but with -@emph{archived}, @emph{commented}, and @emph{tag-excluded} trees removed, use -@code{org-publish-org-to-org}. This produces @samp{file.org} and put it in the -publishing directory. If you want a htmlized version of this file, -set the parameter @code{:htmlized-source} to @code{t}. It produces -@samp{file.org.html} in the publishing directory@footnote{If the publishing directory is the same as the source -directory, @samp{file.org} is exported as @samp{file.org.org}, so you probably -do not want to do this.}. - -Other files like images only need to be copied to the publishing -destination; for this you can use @code{org-publish-attachment}. For -non-Org files, you always need to specify the publishing function: - -@table @asis -@item @code{:publishing-function} -Function executing the publication of a file. This may also be -a list of functions, which are all called in turn. - -@item @code{:htmlized-source} -Non-@code{nil} means, publish htmlized source. -@end table - -The function must accept three arguments: a property list containing -at least a @code{:publishing-directory} property, the name of the file to -be published, and the path to the publishing directory of the output -file. It should take the specified file, make the necessary -transformation, if any, and place the result into the destination -folder. - -@node Publishing options -@subsection Options for the exporters - -@cindex options, for publishing -@cindex publishing options - -The property list can be used to set many export options for the HTML -and @LaTeX{} exporters. In most cases, these properties correspond to -user variables in Org. The table below lists these properties along -with the variable they belong to. See the documentation string for -the respective variable for details. - -@vindex org-publish-project-alist -When a property is given a value in @code{org-publish-project-alist}, its -setting overrides the value of the corresponding user variable, if -any, during publishing. Options set within a file (see @ref{Export Settings}), however, override everything. - -@anchor{Generic properties} -@subsubheading Generic properties - -@multitable {aaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @code{:archived-trees} -@tab @code{org-export-with-archived-trees} -@item @code{:exclude-tags} -@tab @code{org-export-exclude-tags} -@item @code{:headline-levels} -@tab @code{org-export-headline-levels} -@item @code{:language} -@tab @code{org-export-default-language} -@item @code{:preserve-breaks} -@tab @code{org-export-preserve-breaks} -@item @code{:section-numbers} -@tab @code{org-export-with-section-numbers} -@item @code{:select-tags} -@tab @code{org-export-select-tags} -@item @code{:with-author} -@tab @code{org-export-with-author} -@item @code{:with-broken-links} -@tab @code{org-export-with-broken-links} -@item @code{:with-clocks} -@tab @code{org-export-with-clocks} -@item @code{:with-creator} -@tab @code{org-export-with-creator} -@item @code{:with-date} -@tab @code{org-export-with-date} -@item @code{:with-drawers} -@tab @code{org-export-with-drawers} -@item @code{:with-email} -@tab @code{org-export-with-email} -@item @code{:with-emphasize} -@tab @code{org-export-with-emphasize} -@item @code{:with-fixed-width} -@tab @code{org-export-with-fixed-width} -@item @code{:with-footnotes} -@tab @code{org-export-with-footnotes} -@item @code{:with-latex} -@tab @code{org-export-with-latex} -@item @code{:with-planning} -@tab @code{org-export-with-planning} -@item @code{:with-priority} -@tab @code{org-export-with-priority} -@item @code{:with-properties} -@tab @code{org-export-with-properties} -@item @code{:with-special-strings} -@tab @code{org-export-with-special-strings} -@item @code{:with-sub-superscript} -@tab @code{org-export-with-sub-superscripts} -@item @code{:with-tables} -@tab @code{org-export-with-tables} -@item @code{:with-tags} -@tab @code{org-export-with-tags} -@item @code{:with-tasks} -@tab @code{org-export-with-tasks} -@item @code{:with-timestamps} -@tab @code{org-export-with-timestamps} -@item @code{:with-title} -@tab @code{org-export-with-title} -@item @code{:with-toc} -@tab @code{org-export-with-toc} -@item @code{:with-todo-keywords} -@tab @code{org-export-with-todo-keywords} -@end multitable - -@anchor{ASCII specific properties} -@subsubheading ASCII specific properties - -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @code{:ascii-bullets} -@tab @code{org-ascii-bullets} -@item @code{:ascii-caption-above} -@tab @code{org-ascii-caption-above} -@item @code{:ascii-charset} -@tab @code{org-ascii-charset} -@item @code{:ascii-global-margin} -@tab @code{org-ascii-global-margin} -@item @code{:ascii-format-drawer-function} -@tab @code{org-ascii-format-drawer-function} -@item @code{:ascii-format-inlinetask-function} -@tab @code{org-ascii-format-inlinetask-function} -@item @code{:ascii-headline-spacing} -@tab @code{org-ascii-headline-spacing} -@item @code{:ascii-indented-line-width} -@tab @code{org-ascii-indented-line-width} -@item @code{:ascii-inlinetask-width} -@tab @code{org-ascii-inlinetask-width} -@item @code{:ascii-inner-margin} -@tab @code{org-ascii-inner-margin} -@item @code{:ascii-links-to-notes} -@tab @code{org-ascii-links-to-notes} -@item @code{:ascii-list-margin} -@tab @code{org-ascii-list-margin} -@item @code{:ascii-paragraph-spacing} -@tab @code{org-ascii-paragraph-spacing} -@item @code{:ascii-quote-margin} -@tab @code{org-ascii-quote-margin} -@item @code{:ascii-table-keep-all-vertical-lines} -@tab @code{org-ascii-table-keep-all-vertical-lines} -@item @code{:ascii-table-use-ascii-art} -@tab @code{org-ascii-table-use-ascii-art} -@item @code{:ascii-table-widen-columns} -@tab @code{org-ascii-table-widen-columns} -@item @code{:ascii-text-width} -@tab @code{org-ascii-text-width} -@item @code{:ascii-underline} -@tab @code{org-ascii-underline} -@item @code{:ascii-verbatim-format} -@tab @code{org-ascii-verbatim-format} -@end multitable - -@anchor{Beamer specific properties} -@subsubheading Beamer specific properties - -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @code{:beamer-theme} -@tab @code{org-beamer-theme} -@item @code{:beamer-column-view-format} -@tab @code{org-beamer-column-view-format} -@item @code{:beamer-environments-extra} -@tab @code{org-beamer-environments-extra} -@item @code{:beamer-frame-default-options} -@tab @code{org-beamer-frame-default-options} -@item @code{:beamer-outline-frame-options} -@tab @code{org-beamer-outline-frame-options} -@item @code{:beamer-outline-frame-title} -@tab @code{org-beamer-outline-frame-title} -@item @code{:beamer-subtitle-format} -@tab @code{org-beamer-subtitle-format} -@end multitable - -@anchor{HTML specific properties} -@subsubheading HTML specific properties - -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @code{:html-allow-name-attribute-in-anchors} -@tab @code{org-html-allow-name-attribute-in-anchors} -@item @code{:html-checkbox-type} -@tab @code{org-html-checkbox-type} -@item @code{:html-container} -@tab @code{org-html-container-element} -@item @code{:html-divs} -@tab @code{org-html-divs} -@item @code{:html-doctype} -@tab @code{org-html-doctype} -@item @code{:html-extension} -@tab @code{org-html-extension} -@item @code{:html-footnote-format} -@tab @code{org-html-footnote-format} -@item @code{:html-footnote-separator} -@tab @code{org-html-footnote-separator} -@item @code{:html-footnotes-section} -@tab @code{org-html-footnotes-section} -@item @code{:html-format-drawer-function} -@tab @code{org-html-format-drawer-function} -@item @code{:html-format-headline-function} -@tab @code{org-html-format-headline-function} -@item @code{:html-format-inlinetask-function} -@tab @code{org-html-format-inlinetask-function} -@item @code{:html-head-extra} -@tab @code{org-html-head-extra} -@item @code{:html-head-include-default-style} -@tab @code{org-html-head-include-default-style} -@item @code{:html-head-include-scripts} -@tab @code{org-html-head-include-scripts} -@item @code{:html-head} -@tab @code{org-html-head} -@item @code{:html-home/up-format} -@tab @code{org-html-home/up-format} -@item @code{:html-html5-fancy} -@tab @code{org-html-html5-fancy} -@item @code{:html-indent} -@tab @code{org-html-indent} -@item @code{:html-infojs-options} -@tab @code{org-html-infojs-options} -@item @code{:html-infojs-template} -@tab @code{org-html-infojs-template} -@item @code{:html-inline-image-rules} -@tab @code{org-html-inline-image-rules} -@item @code{:html-inline-images} -@tab @code{org-html-inline-images} -@item @code{:html-link-home} -@tab @code{org-html-link-home} -@item @code{:html-link-org-files-as-html} -@tab @code{org-html-link-org-files-as-html} -@item @code{:html-link-up} -@tab @code{org-html-link-up} -@item @code{:html-link-use-abs-url} -@tab @code{org-html-link-use-abs-url} -@item @code{:html-mathjax-options} -@tab @code{org-html-mathjax-options} -@item @code{:html-mathjax-template} -@tab @code{org-html-mathjax-template} -@item @code{:html-equation-reference-format} -@tab @code{org-html-equation-reference-format} -@item @code{:html-metadata-timestamp-format} -@tab @code{org-html-metadata-timestamp-format} -@item @code{:html-postamble-format} -@tab @code{org-html-postamble-format} -@item @code{:html-postamble} -@tab @code{org-html-postamble} -@item @code{:html-preamble-format} -@tab @code{org-html-preamble-format} -@item @code{:html-preamble} -@tab @code{org-html-preamble} -@item @code{:html-self-link-headlines} -@tab @code{org-html-self-link-headlines} -@item @code{:html-table-align-individual-field} -@tab @code{de@{org-html-table-align-individual-fields} -@item @code{:html-table-attributes} -@tab @code{org-html-table-default-attributes} -@item @code{:html-table-caption-above} -@tab @code{org-html-table-caption-above} -@item @code{:html-table-data-tags} -@tab @code{org-html-table-data-tags} -@item @code{:html-table-header-tags} -@tab @code{org-html-table-header-tags} -@item @code{:html-table-row-tags} -@tab @code{org-html-table-row-tags} -@item @code{:html-table-use-header-tags-for-first-column} -@tab @code{org-html-table-use-header-tags-for-first-column} -@item @code{:html-tag-class-prefix} -@tab @code{org-html-tag-class-prefix} -@item @code{:html-text-markup-alist} -@tab @code{org-html-text-markup-alist} -@item @code{:html-todo-kwd-class-prefix} -@tab @code{org-html-todo-kwd-class-prefix} -@item @code{:html-toplevel-hlevel} -@tab @code{org-html-toplevel-hlevel} -@item @code{:html-use-infojs} -@tab @code{org-html-use-infojs} -@item @code{:html-validation-link} -@tab @code{org-html-validation-link} -@item @code{:html-viewport} -@tab @code{org-html-viewport} -@item @code{:html-wrap-src-lines} -@tab @code{org-html-wrap-src-lines} -@item @code{:html-xml-declaration} -@tab @code{org-html-xml-declaration} -@end multitable - -@anchor{@LaTeX{} specific properties} -@subsubheading @LaTeX{} specific properties - -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @code{:latex-active-timestamp-format} -@tab @code{org-latex-active-timestamp-format} -@item @code{:latex-caption-above} -@tab @code{org-latex-caption-above} -@item @code{:latex-classes} -@tab @code{org-latex-classes} -@item @code{:latex-class} -@tab @code{org-latex-default-class} -@item @code{:latex-compiler} -@tab @code{org-latex-compiler} -@item @code{:latex-default-figure-position} -@tab @code{org-latex-default-figure-position} -@item @code{:latex-default-table-environment} -@tab @code{org-latex-default-table-environment} -@item @code{:latex-default-table-mode} -@tab @code{org-latex-default-table-mode} -@item @code{:latex-diary-timestamp-format} -@tab @code{org-latex-diary-timestamp-format} -@item @code{:latex-footnote-defined-format} -@tab @code{org-latex-footnote-defined-format} -@item @code{:latex-footnote-separator} -@tab @code{org-latex-footnote-separator} -@item @code{:latex-format-drawer-function} -@tab @code{org-latex-format-drawer-function} -@item @code{:latex-format-headline-function} -@tab @code{org-latex-format-headline-function} -@item @code{:latex-format-inlinetask-function} -@tab @code{org-latex-format-inlinetask-function} -@item @code{:latex-hyperref-template} -@tab @code{org-latex-hyperref-template} -@item @code{:latex-image-default-height} -@tab @code{org-latex-image-default-height} -@item @code{:latex-image-default-option} -@tab @code{org-latex-image-default-option} -@item @code{:latex-image-default-width} -@tab @code{org-latex-image-default-width} -@item @code{:latex-images-centered} -@tab @code{org-latex-images-centered} -@item @code{:latex-inactive-timestamp-format} -@tab @code{org-latex-inactive-timestamp-format} -@item @code{:latex-inline-image-rules} -@tab @code{org-latex-inline-image-rules} -@item @code{:latex-link-with-unknown-path-format} -@tab @code{org-latex-link-with-unknown-path-format} -@item @code{:latex-listings-langs} -@tab @code{org-latex-listings-langs} -@item @code{:latex-listings-options} -@tab @code{org-latex-listings-options} -@item @code{:latex-listings} -@tab @code{org-latex-listings} -@item @code{:latex-minted-langs} -@tab @code{org-latex-minted-langs} -@item @code{:latex-minted-options} -@tab @code{org-latex-minted-options} -@item @code{:latex-prefer-user-labels} -@tab @code{org-latex-prefer-user-labels} -@item @code{:latex-subtitle-format} -@tab @code{org-latex-subtitle-format} -@item @code{:latex-subtitle-separate} -@tab @code{org-latex-subtitle-separate} -@item @code{:latex-table-scientific-notation} -@tab @code{org-latex-table-scientific-notation} -@item @code{:latex-tables-booktabs} -@tab @code{org-latex-tables-booktabs} -@item @code{:latex-tables-centered} -@tab @code{org-latex-tables-centered} -@item @code{:latex-text-markup-alist} -@tab @code{org-latex-text-markup-alist} -@item @code{:latex-title-command} -@tab @code{org-latex-title-command} -@item @code{:latex-toc-command} -@tab @code{org-latex-toc-command} -@end multitable - -@anchor{Markdown specific properties} -@subsubheading Markdown specific properties - -@multitable {aaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @code{:md-footnote-format} -@tab @code{org-md-footnote-format} -@item @code{:md-footnotes-section} -@tab @code{org-md-footnotes-section} -@item @code{:md-headline-style} -@tab @code{org-md-headline-style} -@end multitable - -@anchor{ODT specific properties} -@subsubheading ODT specific properties - -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @code{:odt-content-template-file} -@tab @code{org-odt-content-template-file} -@item @code{:odt-display-outline-level} -@tab @code{org-odt-display-outline-level} -@item @code{:odt-fontify-srcblocks} -@tab @code{org-odt-fontify-srcblocks} -@item @code{:odt-format-drawer-function} -@tab @code{org-odt-format-drawer-function} -@item @code{:odt-format-headline-function} -@tab @code{org-odt-format-headline-function} -@item @code{:odt-format-inlinetask-function} -@tab @code{org-odt-format-inlinetask-function} -@item @code{:odt-inline-formula-rules} -@tab @code{org-odt-inline-formula-rules} -@item @code{:odt-inline-image-rules} -@tab @code{org-odt-inline-image-rules} -@item @code{:odt-pixels-per-inch} -@tab @code{org-odt-pixels-per-inch} -@item @code{:odt-styles-file} -@tab @code{org-odt-styles-file} -@item @code{:odt-table-styles} -@tab @code{org-odt-table-styles} -@item @code{:odt-use-date-fields} -@tab @code{org-odt-use-date-fields} -@end multitable - -@anchor{Texinfo specific properties} -@subsubheading Texinfo specific properties - -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @code{:texinfo-active-timestamp-format} -@tab @code{org-texinfo-active-timestamp-format} -@item @code{:texinfo-classes} -@tab @code{org-texinfo-classes} -@item @code{:texinfo-class} -@tab @code{org-texinfo-default-class} -@item @code{:texinfo-table-default-markup} -@tab @code{org-texinfo-table-default-markup} -@item @code{:texinfo-diary-timestamp-format} -@tab @code{org-texinfo-diary-timestamp-format} -@item @code{:texinfo-filename} -@tab @code{org-texinfo-filename} -@item @code{:texinfo-format-drawer-function} -@tab @code{org-texinfo-format-drawer-function} -@item @code{:texinfo-format-headline-function} -@tab @code{org-texinfo-format-headline-function} -@item @code{:texinfo-format-inlinetask-function} -@tab @code{org-texinfo-format-inlinetask-function} -@item @code{:texinfo-inactive-timestamp-format} -@tab @code{org-texinfo-inactive-timestamp-format} -@item @code{:texinfo-link-with-unknown-path-format} -@tab @code{org-texinfo-link-with-unknown-path-format} -@item @code{:texinfo-node-description-column} -@tab @code{org-texinfo-node-description-column} -@item @code{:texinfo-table-scientific-notation} -@tab @code{org-texinfo-table-scientific-notation} -@item @code{:texinfo-tables-verbatim} -@tab @code{org-texinfo-tables-verbatim} -@item @code{:texinfo-text-markup-alist} -@tab @code{org-texinfo-text-markup-alist} -@end multitable - -@node Publishing links -@subsection Publishing links - -@cindex links, publishing - -To create a link from one Org file to another, you would use something -like @samp{[[file:foo.org][The foo]]} or simply @samp{[[file:foo.org]]} (see @ref{External Links}). When -published, this link becomes a link to @samp{foo.html}. You can thus -interlink the pages of your ``Org web'' project and the links will work -as expected when you publish them to HTML@. If you also publish the -Org source file and want to link to it, use an @samp{http} link instead of -a @samp{file:} link, because @samp{file} links are converted to link to the -corresponding @samp{.html} file. - -You may also link to related files, such as images. Provided you are -careful with relative file names, and provided you have also -configured Org to upload the related files, these links will work too. -See @ref{Complex example}, for an example of this -usage. - -Eventually, links between published documents can contain some search -options (see @ref{Search Options}), which will be resolved to -the appropriate location in the linked file. For example, once -published to HTML, the following links all point to a dedicated anchor -in @samp{foo.html}. - -@example -[[file:foo.org::*heading]] -[[file:foo.org::#custom-id]] -[[file:foo.org::target]] -@end example - -@node Site map -@subsection Generating a sitemap - -@cindex sitemap, of published pages - -The following properties may be used to control publishing of -a map of files for a given project. - -@table @asis -@item @code{:auto-sitemap} -When non-@code{nil}, publish a sitemap during -@code{org-publish-current-project} or @code{org-publish-all}. - -@item @code{:sitemap-filename} -Filename for output of sitemap. Defaults to @samp{sitemap.org}, which -becomes @samp{sitemap.html}. - -@item @code{:sitemap-title} -Title of sitemap page. Defaults to name of file. - -@item @code{:sitemap-format-entry} -@findex org-publish-find-date -@findex org-publish-find-property -@findex org-publish-find-title -With this option one can tell how a site-map entry is formatted in -the site-map. It is a function called with three arguments: the -file or directory name relative to base directory of the project, -the site-map style and the current project. It is expected to -return a string. Default value turns file names into links and use -document titles as descriptions. For specific formatting needs, one -can use @code{org-publish-find-date}, @code{org-publish-find-title} and -@code{org-publish-find-property}, to retrieve additional information -about published documents. - -@item @code{:sitemap-function} -Plug-in function to use for generation of the sitemap. It is called -with two arguments: the title of the site-map and a representation -of the files and directories involved in the project as a nested -list, which can further be transformed using @code{org-list-to-generic}, -@code{org-list-to-subtree} and alike. Default value generates a plain -list of links to all files in the project. - -@item @code{:sitemap-sort-folders} -Where folders should appear in the sitemap. Set this to @code{first} -(default) or @code{last} to display folders first or last, respectively. -When set to @code{ignore}, folders are ignored altogether. Any other -value mixes files and folders. This variable has no effect when -site-map style is @code{tree}. - -@item @code{:sitemap-sort-files} -How the files are sorted in the site map. Set this to -@code{alphabetically} (default), @code{chronologically} or -@code{anti-chronologically}. @code{chronologically} sorts the files with -older date first while @code{anti-chronologically} sorts the files with -newer date first. @code{alphabetically} sorts the files alphabetically. -The date of a file is retrieved with @code{org-publish-find-date}. - -@item @code{:sitemap-ignore-case} -Should sorting be case-sensitive? Default @code{nil}. - -@item @code{:sitemap-file-entry-format} -With this option one can tell how a sitemap's entry is formatted in -the sitemap. This is a format string with some escape sequences: -@code{%t} stands for the title of the file, @code{%a} stands for the author of -the file and @code{%d} stands for the date of the file. The date is -retrieved with the @code{org-publish-find-date} function and formatted -with @code{org-publish-sitemap-date-format}. Default @code{%t}. - -@item @code{:sitemap-date-format} -Format string for the @code{format-time-string} function that tells how -a sitemap entry's date is to be formatted. This property bypasses -@code{org-publish-sitemap-date-format} which defaults to @code{%Y-%m-%d}. -@end table - -@node Generating an index -@subsection Generating an index - -@cindex index, in a publishing project - -Org mode can generate an index across the files of a publishing project. - -@table @asis -@item @code{:makeindex} -When non-@code{nil}, generate in index in the file @samp{theindex.org} and -publish it as @samp{theindex.html}. -@end table - -The file is created when first publishing a project with the -@code{:makeindex} set. The file only contains a statement @samp{#+INCLUDE: -"theindex.inc"}. You can then build around this include statement by -adding a title, style information, etc. - -@cindex @samp{INDEX}, keyword -Index entries are specified with @samp{INDEX} keyword. An entry that -contains an exclamation mark creates a sub item. - -@example -*** Curriculum Vitae -#+INDEX: CV -#+INDEX: Application!CV -@end example - -@node Uploading Files -@section Uploading Files - -@cindex rsync -@cindex unison - -For those people already utilizing third party sync tools such as -Rsync or Unison, it might be preferable not to use the built-in remote -publishing facilities of Org mode which rely heavily on Tramp. Tramp, -while very useful and powerful, tends not to be so efficient for -multiple file transfer and has been known to cause problems under -heavy usage. - -Specialized synchronization utilities offer several advantages. In -addition to timestamp comparison, they also do content and -permissions/attribute checks. For this reason you might prefer to -publish your web to a local directory---possibly even @emph{in place} with -your Org files---and then use Unison or Rsync to do the -synchronization with the remote host. - -Since Unison, for example, can be configured as to which files to -transfer to a certain remote destination, it can greatly simplify the -project publishing definition. Simply keep all files in the correct -location, process your Org files with @code{org-publish} and let the -synchronization tool do the rest. You do not need, in this scenario, -to include attachments such as JPG, CSS or PNG files in the project -definition since the third-party tool syncs them. - -Publishing to a local directory is also much faster than to a remote -one, so that you can afford more easily to republish entire projects. -If you set @code{org-publish-use-timestamps-flag} to @code{nil}, you gain the -main benefit of re-including any changed external files such as source -example files you might include with @samp{INCLUDE} keyword. The timestamp -mechanism in Org is not smart enough to detect if included files have -been modified. - -@node Sample Configuration -@section Sample Configuration - -Below we provide two example configurations. The first one is -a simple project publishing only a set of Org files. The second -example is more complex, with a multi-component project. - -@menu -* Simple example:: One-component publishing. -* Complex example:: A multi-component publishing example. -@end menu - -@node Simple example -@subsection Example: simple publishing configuration - -This example publishes a set of Org files to the @samp{public_html} -directory on the local machine. - -@lisp -(setq org-publish-project-alist - '(("org" - :base-directory "~/org/" - :publishing-directory "~/public_html" - :section-numbers nil - :table-of-contents nil - :style ""))) -@end lisp - -@node Complex example -@subsection Example: complex publishing configuration - -This more complicated example publishes an entire website, including -Org files converted to HTML, image files, Emacs Lisp source code, and -style sheets. The publishing directory is remote and private files -are excluded. - -To ensure that links are preserved, care should be taken to replicate -your directory structure on the web server, and to use relative file -paths. For example, if your Org files are kept in @samp{~/org/} and your -publishable images in @samp{~/images/}, you would link to an image with - -@example -file:../images/myimage.png -@end example - - -On the web server, the relative path to the image should be the same. -You can accomplish this by setting up an @samp{images/} folder in the right -place on the web server, and publishing images to it. - -@lisp -(setq org-publish-project-alist - '(("orgfiles" - :base-directory "~/org/" - :base-extension "org" - :publishing-directory "/ssh:user@@host:~/html/notebook/" - :publishing-function org-html-publish-to-html - :exclude "PrivatePage.org" ;; regexp - :headline-levels 3 - :section-numbers nil - :with-toc nil - :html-head "" - :html-preamble t) - - ("images" - :base-directory "~/images/" - :base-extension "jpg\\|gif\\|png" - :publishing-directory "/ssh:user@@host:~/html/images/" - :publishing-function org-publish-attachment) - - ("other" - :base-directory "~/other/" - :base-extension "css\\|el" - :publishing-directory "/ssh:user@@host:~/html/other/" - :publishing-function org-publish-attachment) - ("website" :components ("orgfiles" "images" "other")))) -@end lisp - -@node Triggering Publication -@section Triggering Publication - -Once properly configured, Org can publish with the following commands: - -@table @asis -@item @kbd{C-c C-e P x} (@code{org-publish}) -@kindex C-c C-e P x -@findex org-publish -Prompt for a specific project and publish all files that belong to -it. - -@item @kbd{C-c C-e P p} (@code{org-publish-current-project}) -@kindex C-c C-e P p -@findex org-publish-current-project -Publish the project containing the current file. - -@item @kbd{C-c C-e P f} (@code{org-publish-current-file}) -@kindex C-c C-e P f -@findex org-publish-current-file -Publish only the current file. - -@item @kbd{C-c C-e P a} (@code{org-publish-all}) -@kindex C-c C-e P a -@findex org-publish-all -Publish every project. -@end table - -@vindex org-publish-use-timestamps-flag -Org uses timestamps to track when a file has changed. The above -functions normally only publish changed files. You can override this -and force publishing of all files by giving a prefix argument to any -of the commands above, or by customizing the variable -@code{org-publish-use-timestamps-flag}. This may be necessary in -particular if files include other files via @samp{SETUPFILE} or @samp{INCLUDE} -keywords. - -@node Working with Source Code -@chapter Working with Source Code - -@cindex source code, working with - -Source code here refers to any plain text collection of computer -instructions, possibly with comments, written using a human-readable -programming language. Org can manage source code in an Org document -when the source code is identified with begin and end markers. -Working with source code begins with identifying source code blocks. -A source code block can be placed almost anywhere in an Org document; -it is not restricted to the preamble or the end of the document. -However, Org cannot manage a source code block if it is placed inside -an Org comment or within a fixed width section. - -Here is an example source code block in the Emacs Lisp language: - -@example -#+BEGIN_SRC emacs-lisp - (defun org-xor (a b) - "Exclusive or." - (if a (not b) b)) -#+END_SRC -@end example - -Source code blocks are one of many Org block types, which also include -``center'', ``comment'', ``dynamic'', ``example'', ``export'', ``quote'', -``special'', and ``verse''. This section pertains to blocks between -@samp{#+BEGIN_SRC} and @samp{#+END_SRC}. - -Details of Org's facilities for working with source code are described -in the following sections. - -@menu -* Features Overview:: Enjoy the versatility of source blocks. -* Structure of Code Blocks:: Code block syntax described. -* Using Header Arguments:: Different ways to set header arguments. -* Environment of a Code Block:: Arguments, sessions, working directory... -* Evaluating Code Blocks:: Place results of evaluation in the Org buffer. -* Results of Evaluation:: Choosing a results type, post-processing... -* Exporting Code Blocks:: Export contents and/or results. -* Extracting Source Code:: Create pure source code files. -* Languages:: List of supported code block languages. -* Editing Source Code:: Language major-mode editing. -* Noweb Reference Syntax:: Literate programming in Org mode. -* Library of Babel:: Use and contribute to a library of useful code blocks. -* Key bindings and Useful Functions:: Work quickly with code blocks. -* Batch Execution:: Call functions from the command line. -@end menu - -@node Features Overview -@section Features Overview - -Org can manage the source code in the block delimited by @samp{#+BEGIN_SRC} -@dots{} @samp{#+END_SRC} in several ways that can simplify housekeeping tasks -essential to modern source code maintenance. Org can edit, format, -extract, export, and publish source code blocks. Org can also compile -and execute a source code block, then capture the results. The Org -mode literature sometimes refers to source code blocks as @emph{live code} -blocks because they can alter the content of the Org document or the -material that it exports. Users can control how live they want each -source code block by tweaking the header arguments (see @ref{Using Header Arguments}) for compiling, execution, extraction, and exporting. - -For editing and formatting a source code block, Org uses an -appropriate Emacs major mode that includes features specifically -designed for source code in that language. - -Org can extract one or more source code blocks and write them to one -or more source files---a process known as @emph{tangling} in literate -programming terminology. - -For exporting and publishing, Org's back-ends can format a source code -block appropriately, often with native syntax highlighting. - -For executing and compiling a source code block, the user can -configure Org to select the appropriate compiler. Org provides -facilities to collect the result of the execution or compiler output, -insert it into the Org document, and/or export it. In addition to -text results, Org can insert links to other data types, including -audio, video, and graphics. Org can also link a compiler error -message to the appropriate line in the source code block. - -An important feature of Org's management of source code blocks is the -ability to pass variables, functions, and results to one another using -a common syntax for source code blocks in any language. Although most -literate programming facilities are restricted to one language or -another, Org's language-agnostic approach lets the literate programmer -match each programming task with the appropriate computer language and -to mix them all together in a single Org document. This -interoperability among languages explains why Org's source code -management facility was named @emph{Org Babel} by its originators, Eric -Schulte and Dan Davison. - -Org mode fulfills the promise of easy verification and maintenance of -publishing reproducible research by keeping text, data, code, -configuration settings of the execution environment, the results of -the execution, and associated narratives, claims, references, and -internal and external links in a single Org document. - -@node Structure of Code Blocks -@section Structure of Code Blocks - -@cindex code block, structure -@cindex source code, block structure -@cindex @samp{NAME} keyword, in source blocks -@cindex @samp{BEGIN_SRC} - -Org offers two ways to structure source code in Org documents: in -a source code block, and directly inline. Both specifications are -shown below. - -A source code block conforms to this structure: - -@example -#+NAME: -#+BEGIN_SRC
- -#+END_SRC -@end example - -Do not be put-off by having to remember the source block syntax. Org -mode offers a command for wrapping existing text in a block (see -@ref{Structure Templates}). Org also works with other completion systems -in Emacs, some of which predate Org and have custom domain-specific -languages for defining templates. Regular use of templates reduces -errors, increases accuracy, and maintains consistency. - -@cindex source code, inline -An inline code block conforms to this structure: - -@example -src_@{@} -@end example - - -@noindent -or - -@example -src_[
]@{@} -@end example - - -@table @asis -@item @samp{#+NAME: } -Optional. Names the source block so it can be called, like -a function, from other source blocks or inline code to evaluate or -to capture the results. Code from other blocks, other files, and -from table formulas (see @ref{The Spreadsheet}) can use the name to -reference a source block. This naming serves the same purpose as -naming Org tables. Org mode requires unique names. For duplicate -names, Org mode's behavior is undefined. - -@item @samp{#+BEGIN_SRC} @dots{} @samp{#+END_SRC} -Mandatory. They mark the start and end of a block that Org -requires. The @samp{#+BEGIN_SRC} line takes additional arguments, as -described next. - -@item @samp{} -@cindex language, in code blocks -Mandatory. It is the identifier of the source code language in the -block. See @ref{Languages}, for identifiers of supported languages. - -@item @samp{} -@cindex switches, in code blocks -Optional. Switches provide finer control of the code execution, -export, and format (see the discussion of switches in @ref{Literal Examples}). - -@item @samp{
} -@cindex header arguments, in code blocks -Optional. Heading arguments control many aspects of evaluation, -export and tangling of code blocks (see @ref{Using Header Arguments}). -Using Org's properties feature, header arguments can be selectively -applied to the entire buffer or specific sub-trees of the Org -document. - -@item @samp{} -Source code in the dialect of the specified language identifier. -@end table - -@node Using Header Arguments -@section Using Header Arguments - -Org comes with many header arguments common to all languages. New -header arguments are added for specific languages as they become -available for use in source code blocks. A header argument is -specified with an initial colon followed by the argument's name in -lowercase. - -Since header arguments can be set in several ways, Org prioritizes -them in case of overlaps or conflicts by giving local settings -a higher priority. Header values in function calls, for example, -override header values from global defaults. - -@anchor{System-wide header arguments} -@subheading System-wide header arguments - -@vindex org-babel-default-header-args - -@vindex org-babel-default-header-args -System-wide values of header arguments can be specified by customizing -the @code{org-babel-default-header-args} variable, which defaults to the -following values: - -@example -:session => "none" -:results => "replace" -:exports => "code" -:cache => "no" -:noweb => "no" -@end example - -The example below sets @samp{:noweb} header arguments to @samp{yes}, which makes -Org expand @samp{:noweb} references by default. - -@lisp -(setq org-babel-default-header-args - (cons '(:noweb . "yes") - (assq-delete-all :noweb org-babel-default-header-args))) -@end lisp - -@cindex language specific default header arguments -@cindex default header arguments per language -Each language can have separate default header arguments by -customizing the variable @code{org-babel-default-header-args:}, where -@var{} is the name of the language. For details, see the -language-specific online documentation at -@uref{https://orgmode.org/worg/org-contrib/babel/}. - -@anchor{Header arguments in Org mode properties} -@subheading Header arguments in Org mode properties - -For header arguments applicable to the buffer, use @samp{PROPERTY} keyword -anywhere in the Org file (see @ref{Property Syntax}). - -The following example makes all the R code blocks execute in the same -session. Setting @samp{:results} to @samp{silent} ignores the results of -executions for all blocks, not just R code blocks; no results inserted -for any block. - -@example -#+PROPERTY: header-args:R :session *R* -#+PROPERTY: header-args :results silent -@end example - -@vindex org-use-property-inheritance -Header arguments set through Org's property drawers (see @ref{Property Syntax}) apply at the sub-tree level on down. Since these property -drawers can appear anywhere in the file hierarchy, Org uses outermost -call or source block to resolve the values. Org ignores -@code{org-use-property-inheritance} setting. - -In this example, @samp{:cache} defaults to @samp{yes} for all code blocks in the -sub-tree. - -@example -* sample header - :PROPERTIES: - :header-args: :cache yes - :END: -@end example - -@kindex C-c C-x p -@findex org-set-property -Properties defined through @code{org-set-property} function, bound to -@kbd{C-c C-x p}, apply to all active languages. They override -properties set in @code{org-babel-default-header-args}. - -@cindex language specific header arguments properties -@cindex header arguments per language -Language-specific header arguments are also read from properties -@samp{header-args:} where @var{} is the language -identifier. For example, - -@example -* Heading - :PROPERTIES: - :header-args:clojure: :session *clojure-1* - :header-args:R: :session *R* - :END: -** Subheading - :PROPERTIES: - :header-args:clojure: :session *clojure-2* - :END: -@end example - -@noindent -would force separate sessions for Clojure blocks in @samp{Heading} and -@samp{Subheading}, but use the same session for all R blocks. Blocks in -@samp{Subheading} inherit settings from @samp{Heading}. - -@anchor{Code block specific header arguments} -@subheading Code block specific header arguments - -Header arguments are most commonly set at the source code block level, -on the @samp{#+BEGIN_SRC} line. Arguments set at this level take -precedence over those set in the @code{org-babel-default-header-args} -variable, and also those set as header properties. - -In the following example, setting @samp{:results} to @samp{silent} makes it -ignore results of the code execution. Setting @samp{:exports} to @samp{code} -exports only the body of the code block to HTML or @LaTeX{}. - -@example -#+NAME: factorial -#+BEGIN_SRC haskell :results silent :exports code :var n=0 - fac 0 = 1 - fac n = n * fac (n-1) -#+END_SRC -@end example - -The same header arguments in an inline code block: - -@example -src_haskell[:exports both]@{fac 5@} -@end example - - -@cindex @samp{HEADER}, keyword -Code block header arguments can span multiple lines using @samp{#+HEADER:} -on each line. Note that Org currently accepts the plural spelling of -@samp{#+HEADER:} only as a convenience for backward-compatibility. It may -be removed at some point. - -Multi-line header arguments on an unnamed code block: - -@example -#+HEADER: :var data1=1 -#+BEGIN_SRC emacs-lisp :var data2=2 - (message "data1:%S, data2:%S" data1 data2) -#+END_SRC - -#+RESULTS: -: data1:1, data2:2 -@end example - -Multi-line header arguments on a named code block: - -@example -#+NAME: named-block -#+HEADER: :var data=2 -#+BEGIN_SRC emacs-lisp - (message "data:%S" data) -#+END_SRC - -#+RESULTS: named-block - : data:2 -@end example - -@anchor{Header arguments in function calls} -@subheading Header arguments in function calls - -Header arguments in function calls are the most specific and override -all other settings in case of an overlap. They get the highest -priority. Two @samp{#+CALL:} examples are shown below. For the complete -syntax of @samp{CALL} keyword, see @ref{Evaluating Code Blocks}. - -In this example, @samp{:exports results} header argument is applied to the -evaluation of the @samp{#+CALL:} line. - -@example -#+CALL: factorial(n=5) :exports results -@end example - - -In this example, @samp{:session special} header argument is applied to the -evaluation of @samp{factorial} code block. - -@example -#+CALL: factorial[:session special](n=5) -@end example - -@node Environment of a Code Block -@section Environment of a Code Block - - - -@anchor{Passing arguments} -@subheading Passing arguments - -@cindex passing arguments to code blocks -@cindex arguments, in code blocks -@cindex @samp{var}, header argument -Use @samp{var} for passing arguments to source code blocks. The specifics -of variables in code blocks vary by the source language and are -covered in the language-specific documentation. The syntax for @samp{var}, -however, is the same for all languages. This includes declaring -a variable, and assigning a default value. - -The following syntax is used to pass arguments to code blocks using -the @samp{var} header argument. - -@example -:var NAME=ASSIGN -@end example - - -@noindent -@var{NAME} is the name of the variable bound in the code block -body. @var{ASSIGN} is a literal value, such as a string, -a number, a reference to a table, a list, a literal example, another -code block---with or without arguments---or the results of evaluating -a code block. - -Here are examples of passing values by reference: - -@table @asis -@item table -A table named with a @samp{NAME} keyword. - -@example -#+NAME: example-table -| 1 | -| 2 | -| 3 | -| 4 | - -#+NAME: table-length -#+BEGIN_SRC emacs-lisp :var table=example-table - (length table) -#+END_SRC - -#+RESULTS: table-length -: 4 -@end example - -When passing a table, you can treat specially the row, or the -column, containing labels for the columns, or the rows, in the -table. - -@cindex @samp{colnames}, header argument -The @samp{colnames} header argument accepts @samp{yes}, @samp{no}, or @samp{nil} values. -The default value is @samp{nil}: if an input table has column -names---because the second row is a horizontal rule---then Org -removes the column names, processes the table, puts back the column -names, and then writes the table to the results block. Using @samp{yes}, -Org does the same to the first row, even if the initial table does -not contain any horizontal rule. When set to @samp{no}, Org does not -pre-process column names at all. - -@example -#+NAME: less-cols -| a | -|---| -| b | -| c | - -#+BEGIN_SRC python :var tab=less-cols :colnames nil - return [[val + '*' for val in row] for row in tab] -#+END_SRC - -#+RESULTS: -| a | -|----| -| b* | -| c* | -@end example - -@cindex @samp{rownames}, header argument -Similarly, the @samp{rownames} header argument can take two values: @samp{yes} -or @samp{no}. When set to @samp{yes}, Org removes the first column, processes -the table, puts back the first column, and then writes the table to -the results block. The default is @samp{no}, which means Org does not -pre-process the first column. Note that Emacs Lisp code blocks -ignore @samp{rownames} header argument because of the ease of -table-handling in Emacs. - -@example -#+NAME: with-rownames -| one | 1 | 2 | 3 | 4 | 5 | -| two | 6 | 7 | 8 | 9 | 10 | - -#+BEGIN_SRC python :var tab=with-rownames :rownames yes - return [[val + 10 for val in row] for row in tab] -#+END_SRC - -#+RESULTS: -| one | 11 | 12 | 13 | 14 | 15 | -| two | 16 | 17 | 18 | 19 | 20 | -@end example - -@item list -A simple named list. - -@example -#+NAME: example-list -- simple - - not - - nested -- list - -#+BEGIN_SRC emacs-lisp :var x=example-list - (print x) -#+END_SRC - -#+RESULTS: -| simple | list | -@end example - -Note that only the top level list items are passed along. Nested -list items are ignored. - -@item code block without arguments -A code block name, as assigned by @samp{NAME} keyword from the example -above, optionally followed by parentheses. - -@example -#+BEGIN_SRC emacs-lisp :var length=table-length() - (* 2 length) -#+END_SRC - -#+RESULTS: -: 8 -@end example - -@item code block with arguments -A code block name, as assigned by @samp{NAME} keyword, followed by -parentheses and optional arguments passed within the parentheses. - -@example -#+NAME: double -#+BEGIN_SRC emacs-lisp :var input=8 - (* 2 input) -#+END_SRC - -#+RESULTS: double -: 16 - -#+NAME: squared -#+BEGIN_SRC emacs-lisp :var input=double(input=1) - (* input input) -#+END_SRC - -#+RESULTS: squared -: 4 -@end example - -@item literal example -A literal example block named with a @samp{NAME} keyword. - -@example -#+NAME: literal-example -#+BEGIN_EXAMPLE - A literal example - on two lines -#+END_EXAMPLE - -#+NAME: read-literal-example -#+BEGIN_SRC emacs-lisp :var x=literal-example - (concatenate #'string x " for you.") -#+END_SRC - -#+RESULTS: read-literal-example -: A literal example -: on two lines for you. -@end example -@end table - -Indexing variable values enables referencing portions of a variable. -Indexes are 0 based with negative values counting backwards from the -end. If an index is separated by commas then each subsequent section -indexes as the next dimension. Note that this indexing occurs -@emph{before} other table-related header arguments are applied, such as -@samp{hlines}, @samp{colnames} and @samp{rownames}. The following example assigns -the last cell of the first row the table @samp{example-table} to the -variable @samp{data}: - -@example -#+NAME: example-table -| 1 | a | -| 2 | b | -| 3 | c | -| 4 | d | - -#+BEGIN_SRC emacs-lisp :var data=example-table[0,-1] - data -#+END_SRC - -#+RESULTS: -: a -@end example - -Two integers separated by a colon reference a range of variable -values. In that case the entire inclusive range is referenced. For -example the following assigns the middle three rows of @samp{example-table} -to @samp{data}. - -@example -#+NAME: example-table -| 1 | a | -| 2 | b | -| 3 | c | -| 4 | d | -| 5 | 3 | - -#+BEGIN_SRC emacs-lisp :var data=example-table[1:3] - data -#+END_SRC - -#+RESULTS: -| 2 | b | -| 3 | c | -| 4 | d | -@end example - -To pick the entire range, use an empty index, or the single character -@samp{*}. @samp{0:-1} does the same thing. Example below shows how to -reference the first column only. - -@example -#+NAME: example-table -| 1 | a | -| 2 | b | -| 3 | c | -| 4 | d | - -#+BEGIN_SRC emacs-lisp :var data=example-table[,0] - data -#+END_SRC - -#+RESULTS: -| 1 | 2 | 3 | 4 | -@end example - -Index referencing can be used for tables and code blocks. Index -referencing can handle any number of dimensions. Commas delimit -multiple dimensions, as shown below. - -@example -#+NAME: 3D -#+BEGIN_SRC emacs-lisp - '(((1 2 3) (4 5 6) (7 8 9)) - ((10 11 12) (13 14 15) (16 17 18)) - ((19 20 21) (22 23 24) (25 26 27))) -#+END_SRC - -#+BEGIN_SRC emacs-lisp :var data=3D[1,,1] - data -#+END_SRC - -#+RESULTS: -| 11 | 14 | 17 | -@end example - -Note that row names and column names are not removed prior to variable -indexing. You need to take them into account, even when @samp{colnames} or -@samp{rownames} header arguments remove them. - -Emacs lisp code can also set the values for variables. To -differentiate a value from Lisp code, Org interprets any value -starting with @samp{(}, @samp{[}, @samp{'} or @samp{`} as Emacs Lisp code. The result of -evaluating that code is then assigned to the value of that variable. -The following example shows how to reliably query and pass the file -name of the Org mode buffer to a code block using headers. We need -reliability here because the file's name could change once the code in -the block starts executing. - -@example -#+BEGIN_SRC sh :var filename=(buffer-file-name) :exports both - wc -w $filename -#+END_SRC -@end example - -Note that values read from tables and lists are not mistakenly -evaluated as Emacs Lisp code, as illustrated in the following example. - -@example -#+NAME: table -| (a b c) | - -#+HEADER: :var data=table[0,0] -#+BEGIN_SRC perl - $data -#+END_SRC - -#+RESULTS: -: (a b c) -@end example - -@anchor{Using sessions} -@subheading Using sessions - -@cindex using sessions in code blocks -@cindex @samp{session}, header argument -Two code blocks can share the same environment. The @samp{session} header -argument is for running multiple source code blocks under one session. -Org runs code blocks with the same session name in the same -interpreter process. - -@table @asis -@item @samp{none} -Default. Each code block gets a new interpreter process to execute. -The process terminates once the block is evaluated. - -@item @var{STRING} -Any string besides @samp{none} turns that string into the name of that -session. For example, @samp{:session STRING} names it @samp{STRING}. If -@samp{session} has no value, then the session name is derived from the -source language identifier. Subsequent blocks with the same source -code language use the same session. Depending on the language, -state variables, code from other blocks, and the overall interpreted -environment may be shared. Some interpreted languages support -concurrent sessions when subsequent source code language blocks -change session names. -@end table - -Only languages that provide interactive evaluation can have session -support. Not all languages provide this support, such as C and ditaa. -Even languages, such as Python and Haskell, that do support -interactive evaluation impose limitations on allowable language -constructs that can run interactively. Org inherits those limitations -for those code blocks running in a session. - -@anchor{Choosing a working directory} -@subheading Choosing a working directory - -@cindex working directory, in a code block -@cindex @samp{dir}, header argument -@cindex @samp{mkdirp}, header argument -The @samp{dir} header argument specifies the default directory during code -block execution. If it is absent, then the directory associated with -the current buffer is used. In other words, supplying @samp{:dir -DIRECTORY} temporarily has the same effect as changing the current -directory with @kbd{M-x cd @key{RET} DIRECTORY}, and then not setting -@samp{dir}. Under the surface, @samp{dir} simply sets the value of the Emacs -variable @code{default-directory}. Setting @samp{mkdirp} header argument to -a non-@code{nil} value creates the directory, if necessary. - -For example, to save the plot file in the @samp{Work/} folder of the home -directory---notice tilde is expanded: - -@example -#+BEGIN_SRC R :file myplot.png :dir ~/Work - matplot(matrix(rnorm(100), 10), type="l") -#+END_SRC -@end example - -To evaluate the code block on a remote machine, supply a remote -directory name using Tramp syntax. For example: - -@example -#+BEGIN_SRC R :file plot.png :dir /scp:dand@@yakuba.princeton.edu: - plot(1:10, main=system("hostname", intern=TRUE)) -#+END_SRC -@end example - -Org first captures the text results as usual for insertion in the Org -file. Then Org also inserts a link to the remote file, thanks to -Emacs Tramp. Org constructs the remote path to the file name from -@samp{dir} and @code{default-directory}, as illustrated here: - -@example -[[file:/scp:dand@@yakuba.princeton.edu:/home/dand/plot.png][plot.png]] -@end example - - -When @samp{dir} is used with @samp{session}, Org sets the starting directory for -a new session. But Org does not alter the directory of an already -existing session. - -Do not use @samp{dir} with @samp{:exports results} or with @samp{:exports both} to -avoid Org inserting incorrect links to remote files. That is because -Org does not expand @code{default directory} to avoid some underlying -portability issues. - -@anchor{Inserting headers and footers} -@subheading Inserting headers and footers - -@cindex headers, in code blocks -@cindex footers, in code blocks -@cindex @samp{prologue}, header argument -The @samp{prologue} header argument is for appending to the top of the code -block for execution, like a reset instruction. For example, you may -use @samp{:prologue "reset"} in a Gnuplot code block or, for every such -block: - -@lisp -(add-to-list 'org-babel-default-header-args:gnuplot - '((:prologue . "reset"))) - -@end lisp - -@cindex @samp{epilogue}, header argument -Likewise, the value of the @samp{epilogue} header argument is for appending -to the end of the code block for execution. - -@node Evaluating Code Blocks -@section Evaluating Code Blocks - -@cindex code block, evaluating -@cindex source code, evaluating -@cindex @samp{RESULTS}, keyword - -A note about security: With code evaluation comes the risk of harm. -Org safeguards by prompting for user's permission before executing any -code in the source block. To customize this safeguard, or disable it, -see @ref{Code Evaluation Security}. - -@anchor{How to evaluate source code} -@subheading How to evaluate source code - -Org captures the results of the code block evaluation and inserts them -in the Org file, right after the code block. The insertion point is -after a newline and the @samp{RESULTS} keyword. Org creates the @samp{RESULTS} -keyword if one is not already there. - -By default, Org enables only Emacs Lisp code blocks for execution. -See @ref{Languages} to enable other languages. - -@kindex C-c C-c -@kindex C-c C-v e -@findex org-babel-execute-src-block -Org provides many ways to execute code blocks. @kbd{C-c C-c} or -@kbd{C-c C-v e} with the point on a code block@footnote{The option @code{org-babel-no-eval-on-ctrl-c-ctrl-c} can be used -to remove code evaluation from the @kbd{C-c C-c} key binding.} calls the -@code{org-babel-execute-src-block} function, which executes the code in the -block, collects the results, and inserts them in the buffer. - -@cindex @samp{CALL}, keyword -@vindex org-babel-inline-result-wrap -By calling a named code block@footnote{Actually, the constructs @samp{call_()} and @samp{src_@{@}} -are not evaluated when they appear in a keyword (see @ref{In-buffer Settings}).} from an Org mode buffer or -a table. Org can call the named code blocks from the current Org mode -buffer or from the ``Library of Babel'' (see @ref{Library of Babel}). - -The syntax for @samp{CALL} keyword is: - -@example -#+CALL: () -#+CALL: []() -@end example - -The syntax for inline named code blocks is: - -@example -... call_() ... -... call_[]()[] ... -@end example - -When inline syntax is used, the result is wrapped based on the -variable @code{org-babel-inline-result-wrap}, which by default is set to -@code{"=%s="} to produce verbatim text suitable for markup. - -@table @asis -@item @samp{} -This is the name of the code block (see @ref{Structure of Code Blocks}) -to be evaluated in the current document. If the block is located in -another file, start @samp{} with the file name followed by -a colon. For example, in order to execute a block named @samp{clear-data} -in @samp{file.org}, you can write the following: - -@example -#+CALL: file.org:clear-data() -@end example - -@item @samp{} -Org passes arguments to the code block using standard function call -syntax. For example, a @samp{#+CALL:} line that passes @samp{4} to a code -block named @samp{double}, which declares the header argument @samp{:var n=2}, -would be written as: - -@example -#+CALL: double(n=4) -@end example - - -@noindent -Note how this function call syntax is different from the header -argument syntax. - -@item @samp{} -Org passes inside header arguments to the named code block using the -header argument syntax. Inside header arguments apply to code block -evaluation. For example, @samp{[:results output]} collects results -printed to stdout during code execution of that block. Note how -this header argument syntax is different from the function call -syntax. - -@item @samp{} -End header arguments affect the results returned by the code block. -For example, @samp{:results html} wraps the results in a @samp{#+BEGIN_EXPORT - html} block before inserting the results in the Org buffer. -@end table - -@anchor{Limit code block evaluation} -@subheading Limit code block evaluation - -@cindex @samp{eval}, header argument -@cindex control code block evaluation -The @samp{eval} header argument can limit evaluation of specific code -blocks and @samp{CALL} keyword. It is useful for protection against -evaluating untrusted code blocks by prompting for a confirmation. - -@table @asis -@item @samp{never} or @samp{no} -Org never evaluates the source code. - -@item @samp{query} -Org prompts the user for permission to evaluate the source code. - -@item @samp{never-export} or @samp{no-export} -Org does not evaluate the source code when exporting, yet the user -can evaluate it interactively. - -@item @samp{query-export} -Org prompts the user for permission to evaluate the source code -during export. -@end table - -If @samp{eval} header argument is not set, then Org determines whether to -evaluate the source code from the @code{org-confirm-babel-evaluate} -variable (see @ref{Code Evaluation Security}). - -@anchor{Cache results of evaluation} -@subheading Cache results of evaluation - -@cindex @samp{cache}, header argument -@cindex cache results of code evaluation -The @samp{cache} header argument is for caching results of evaluating code -blocks. Caching results can avoid re-evaluating a code block that -have not changed since the previous run. To benefit from the cache -and avoid redundant evaluations, the source block must have a result -already present in the buffer, and neither the header -arguments---including the value of @samp{var} references---nor the text of -the block itself has changed since the result was last computed. This -feature greatly helps avoid long-running calculations. For some edge -cases, however, the cached results may not be reliable. - -The caching feature is best for when code blocks are pure functions, -that is functions that return the same value for the same input -arguments (see @ref{Environment of a Code Block}), and that do not have -side effects, and do not rely on external variables other than the -input arguments. Functions that depend on a timer, file system -objects, and random number generators are clearly unsuitable for -caching. - -A note of warning: when @samp{cache} is used in a session, caching may -cause unexpected results. - -When the caching mechanism tests for any source code changes, it does -not expand noweb style references (see @ref{Noweb Reference Syntax}). - -The @samp{cache} header argument can have one of two values: @samp{yes} or @samp{no}. - -@table @asis -@item @samp{no} -Default. No caching of results; code block evaluated every time. - -@item @samp{yes} -Whether to run the code or return the cached results is determined -by comparing the SHA1 hash value of the combined code block and -arguments passed to it. This hash value is packed on the -@samp{#+RESULTS:} line from previous evaluation. When hash values match, -Org does not evaluate the code block. When hash values mismatch, -Org evaluates the code block, inserts the results, recalculates the -hash value, and updates @samp{#+RESULTS:} line. -@end table - -In this example, both functions are cached. But @samp{caller} runs only if -the result from @samp{random} has changed since the last run. - -@example -#+NAME: random -#+BEGIN_SRC R :cache yes - runif(1) -#+END_SRC - -#+RESULTS[a2a72cd647ad44515fab62e144796432793d68e1]: random -0.4659510825295 - -#+NAME: caller -#+BEGIN_SRC emacs-lisp :var x=random :cache yes - x -#+END_SRC - -#+RESULTS[bec9c8724e397d5df3b696502df3ed7892fc4f5f]: caller -0.254227238707244 -@end example - -@node Results of Evaluation -@section Results of Evaluation - -@cindex code block, results of evaluation -@cindex source code, results of evaluation - -@cindex @samp{results}, header argument -How Org handles results of a code block execution depends on many -header arguments working together. The primary determinant, however, -is the @samp{results} header argument. It accepts four classes of options. -Each code block can take only one option per class: - -@table @asis -@item Collection -For how the results should be collected from the code block; - -@item Type -For which type of result the code block will return; affects how Org -processes and inserts results in the Org buffer; - -@item Format -For the result; affects how Org processes results; - -@item Handling -For inserting results once they are properly formatted. -@end table - -@anchor{Collection} -@subheading Collection - -Collection options specify the results. Choose one of the options; -they are mutually exclusive. - -@table @asis -@item @samp{value} -Default for most Babel libraries@footnote{Actually, the constructs @samp{call_()} and @samp{src_@{@}} -are not evaluated when they appear in a keyword (see @ref{In-buffer Settings}).}. Functional mode. Org -gets the value by wrapping the code in a function definition in the -language of the source block. That is why when using @samp{:results - value}, code should execute like a function and return a value. For -languages like Python, an explicit @code{return} statement is mandatory -when using @samp{:results value}. Result is the value returned by the -last statement in the code block. - -When evaluating the code block in a session (see @ref{Environment of a Code Block}), Org passes the code to an interpreter running as an -interactive Emacs inferior process. Org gets the value from the -source code interpreter's last statement output. Org has to use -language-specific methods to obtain the value. For example, from -the variable @code{_} in Ruby, and the value of @code{.Last.value} in R@. - -@item @samp{output} -Scripting mode. Org passes the code to an external process running -the interpreter. Org returns the contents of the standard output -stream as text results. - -When using a session, Org passes the code to the interpreter running -as an interactive Emacs inferior process. Org concatenates any text -output from the interpreter and returns the collection as a result. -@end table - -@anchor{Type} -@subheading Type - -Type tells what result types to expect from the execution of the code -block. Choose one of the options; they are mutually exclusive. The -default behavior is to automatically determine the result type. - -@table @asis -@item @samp{table} -@itemx @samp{vector} -Interpret the results as an Org table. If the result is a single -value, create a table with one row and one column. Usage example: -@samp{:results value table}. - -@cindex @samp{hlines}, header argument -In-between each table row or below the table headings, sometimes -results have horizontal lines, which are also known as ``hlines''. -The @samp{hlines} argument with the default @samp{no} value strips such lines -from the input table. For most code, this is desirable, or else -those @samp{hline} symbols raise unbound variable errors. A @samp{yes} -accepts such lines, as demonstrated in the following example. - -@example -#+NAME: many-cols -| a | b | c | -|---+---+---| -| d | e | f | -|---+---+---| -| g | h | i | - -#+NAME: no-hline -#+BEGIN_SRC python :var tab=many-cols :hlines no - return tab -#+END_SRC - -#+RESULTS: no-hline -| a | b | c | -| d | e | f | -| g | h | i | - -#+NAME: hlines -#+BEGIN_SRC python :var tab=many-cols :hlines yes - return tab -#+END_SRC - -#+RESULTS: hlines -| a | b | c | -|---+---+---| -| d | e | f | -|---+---+---| -| g | h | i | -@end example - -@item @samp{list} -Interpret the results as an Org list. If the result is a single -value, create a list of one element. - -@item @samp{scalar} -@itemx @samp{verbatim} -Interpret literally and insert as quoted text. Do not create -a table. Usage example: @samp{:results value verbatim}. - -@item @samp{file} -Interpret as a filename. Save the results of execution of the code -block to that file, then insert a link to it. You can control both -the filename and the description associated to the link. - -@cindex @samp{file}, header argument -@cindex @samp{output-dir}, header argument -Org first tries to generate the filename from the value of the -@samp{file} header argument and the directory specified using the -@samp{output-dir} header arguments. If @samp{output-dir} is not specified, -Org assumes it is the current directory. - -@example -#+BEGIN_SRC asymptote :results value file :file circle.pdf :output-dir img/ - size(2cm); - draw(unitcircle); -#+END_SRC -@end example - -@cindex @samp{file-ext}, header argument -If @samp{file} header argument is missing, Org generates the base name of -the output file from the name of the code block, and its extension -from the @samp{file-ext} header argument. In that case, both the name -and the extension are mandatory. - -@example -#+name: circle -#+BEGIN_SRC asymptote :results value file :file-ext pdf - size(2cm); - draw(unitcircle); -#+END_SRC -@end example - -@cindex @samp{file-desc}, header argument -The @samp{file-desc} header argument defines the description (see -@ref{Link Format}) for the link. If @samp{file-desc} is present but has no value, -the @samp{file} value is used as the link description. When this -argument is not present, the description is omitted. - -@cindex @samp{sep}, header argument -By default, Org assumes that a table written to a file has -TAB-delimited output. You can choose a different separator with -the @samp{sep} header argument. - -@cindex @samp{file-mode}, header argument -The @samp{file-mode} header argument defines the file permissions. To -make it executable, use @samp{:file-mode (identity #o755)}. - -@example -#+BEGIN_SRC shell :results file :file script.sh :file-mode (identity #o755) - echo "#!/bin/bash" - echo "echo Hello World" -#+END_SRC -@end example -@end table - -@anchor{Format} -@subheading Format - -Format pertains to the type of the result returned by the code block. -Choose one of the options; they are mutually exclusive. The default -follows from the type specified above. - -@table @asis -@item @samp{code} -Result enclosed in a code block. Useful for parsing. Usage -example: @samp{:results value code}. - -@item @samp{drawer} -Result wrapped in a @samp{RESULTS} drawer. Useful for containing @samp{raw} -or @samp{org} results for later scripting and automated processing. -Usage example: @samp{:results value drawer}. - -@item @samp{html} -Results enclosed in a @samp{BEGIN_EXPORT html} block. Usage example: -@samp{:results value html}. - -@item @samp{latex} -Results enclosed in a @samp{BEGIN_EXPORT latex} block. Usage example: -@samp{:results value latex}. - -@item @samp{link} -@itemx @samp{graphics} -When used along with @samp{file} type, the result is a link to the file -specified in @samp{:file} header argument. However, unlike plain @samp{file} -type, nothing is written to the disk. The block is used for its -side-effects only, as in the following example: - -@example -#+begin_src shell :results file link :file "download.tar.gz" -wget -c "http://example.com/download.tar.gz" -#+end_src -@end example - -@item @samp{org} -Results enclosed in a @samp{BEGIN_SRC org} block. For comma-escape, -either @kbd{@key{TAB}} in the block, or export the file. Usage -example: @samp{:results value org}. - -@item @samp{pp} -Result converted to pretty-print source code. Enclosed in a code -block. Languages supported: Emacs Lisp, Python, and Ruby. Usage -example: @samp{:results value pp}. - -@item @samp{raw} -Interpreted as raw Org mode. Inserted directly into the buffer. -Aligned if it is a table. Usage example: @samp{:results value raw}. -@end table - -@cindex @samp{wrap}, header argument -The @samp{wrap} header argument unconditionally marks the results block by -appending strings to @samp{#+BEGIN_} and @samp{#+END_}. If no string is -specified, Org wraps the results in a @samp{#+BEGIN_results} -@dots{} @samp{#+END_results} block. It takes precedent over the @samp{results} -value listed above. E.g., - -@example -#+BEGIN_SRC emacs-lisp :results html :wrap EXPORT markdown -"Welcome back to the 90's" -#+END_SRC - -#+RESULTS: -#+BEGIN_EXPORT markdown -Welcome back to the 90's -#+END_EXPORT -@end example - -@anchor{Handling} -@subheading Handling - -Handling options after collecting the results. - -@table @asis -@item @samp{silent} -Do not insert results in the Org mode buffer, but echo them in the -minibuffer. Usage example: @samp{:results output silent}. - -@item @samp{replace} -Default. Insert results in the Org buffer. Remove previous -results. Usage example: @samp{:results output replace}. - -@item @samp{append} -Append results to the Org buffer. Latest results are at the bottom. -Does not remove previous results. Usage example: @samp{:results output - append}. - -@item @samp{prepend} -Prepend results to the Org buffer. Latest results are at the top. -Does not remove previous results. Usage example: @samp{:results output - prepend}. -@end table - -@anchor{Post-processing} -@subheading Post-processing - -@cindex @samp{post}, header argument -@cindex @samp{*this*}, in @samp{post} header argument -The @samp{post} header argument is for post-processing results from block -evaluation. When @samp{post} has any value, Org binds the results to -@code{*this*} variable for easy passing to @samp{var} header argument -specifications (see @ref{Environment of a Code Block}). That makes results -available to other code blocks, or even for direct Emacs Lisp code -execution. - -The following two examples illustrate @samp{post} header argument in -action. The first one shows how to attach an @samp{ATTR_LATEX} keyword -using @samp{post}. - -@example -#+NAME: attr_wrap -#+BEGIN_SRC sh :var data="" :var width="\\textwidth" :results output - echo "#+ATTR_LATEX: :width $width" - echo "$data" -#+END_SRC - -#+HEADER: :file /tmp/it.png -#+BEGIN_SRC dot :post attr_wrap(width="5cm", data=*this*) :results drawer - digraph@{ - a -> b; - b -> c; - c -> a; - @} -#+end_src - -#+RESULTS: -:RESULTS: -#+ATTR_LATEX :width 5cm -[[file:/tmp/it.png]] -:END: -@end example - -The second example shows use of @samp{colnames} header argument in @samp{post} -to pass data between code blocks. - -@example -#+NAME: round-tbl -#+BEGIN_SRC emacs-lisp :var tbl="" fmt="%.3f" - (mapcar (lambda (row) - (mapcar (lambda (cell) - (if (numberp cell) - (format fmt cell) - cell)) - row)) - tbl) -#+end_src - -#+BEGIN_SRC R :colnames yes :post round-tbl[:colnames yes](*this*) - set.seed(42) - data.frame(foo=rnorm(1)) -#+END_SRC - -#+RESULTS: -| foo | -|-------| -| 1.371 | -@end example - -@node Exporting Code Blocks -@section Exporting Code Blocks - -@cindex code block, exporting -@cindex source code, exporting - -It is possible to export the @emph{code} of code blocks, the @emph{results} of -code block evaluation, @emph{both} the code and the results of code block -evaluation, or @emph{none}. Org defaults to exporting @emph{code} for most -languages. For some languages, such as ditaa, Org defaults to -@emph{results}. To export just the body of code blocks, see @ref{Literal Examples}. To selectively export sub-trees of an Org document, see -@ref{Exporting}. - -@cindex @samp{exports}, header argument -The @samp{exports} header argument is to specify if that part of the Org -file is exported to, say, HTML or @LaTeX{} formats. - -@table @asis -@item @samp{code} -The default. The body of code is included into the exported file. -Example: @samp{:exports code}. - -@item @samp{results} -The results of evaluation of the code is included in the exported -file. Example: @samp{:exports results}. - -@item @samp{both} -Both the code and results of evaluation are included in the exported -file. Example: @samp{:exports both}. - -@item @samp{none} -Neither the code nor the results of evaluation is included in the -exported file. Whether the code is evaluated at all depends on -other options. Example: @samp{:exports none}. -@end table - -@vindex org-export-use-babel -To stop Org from evaluating code blocks to speed exports, use the -header argument @samp{:eval never-export} (see @ref{Evaluating Code Blocks}). -To stop Org from evaluating code blocks for greater security, set the -@code{org-export-use-babel} variable to @code{nil}, but understand that header -arguments will have no effect. - -Turning off evaluation comes in handy when batch processing. For -example, markup languages for wikis, which have a high risk of -untrusted code. Stopping code block evaluation also stops evaluation -of all header arguments of the code block. This may not be desirable -in some circumstances. So during export, to allow evaluation of just -the header arguments but not any code evaluation in the source block, -set @samp{:eval never-export} (see @ref{Evaluating Code Blocks}). - -Org never evaluates code blocks in commented sub-trees when exporting -(see @ref{Comment Lines}). On the other hand, Org does evaluate code -blocks in sub-trees excluded from export (see @ref{Export Settings}). - -@node Extracting Source Code -@section Extracting Source Code - -@cindex tangling -@cindex source code, extracting -@cindex code block, extracting source code - -Extracting source code from code blocks is a basic task in literate -programming. Org has features to make this easy. In literate -programming parlance, documents on creation are @emph{woven} with code and -documentation, and on export, the code is tangled for execution by -a computer. Org facilitates weaving and tangling for producing, -maintaining, sharing, and exporting literate programming documents. -Org provides extensive customization options for extracting source -code. - -When Org tangles code blocks, it expands, merges, and transforms them. -Then Org recomposes them into one or more separate files, as -configured through the options. During this tangling process, Org -expands variables in the source code, and resolves any noweb style -references (see @ref{Noweb Reference Syntax}). - -@anchor{Header arguments} -@subheading Header arguments - -@cindex @samp{tangle}, header argument -The @samp{tangle} header argument specifies if the code block is exported -to source file(s). - -@table @asis -@item @samp{yes} -Export the code block to source file. The file name for the source -file is derived from the name of the Org file, and the file -extension is derived from the source code language identifier. -Example: @samp{:tangle yes}. - -@item @samp{no} -The default. Do not extract the code in a source code file. -Example: @samp{:tangle no}. - -@item @var{FILENAME} -Export the code block to source file whose file name is derived from -any string passed to the @samp{tangle} header argument. Org derives the -file name as being relative to the directory of the Org file's -location. Example: @samp{:tangle FILENAME}. -@end table - -@cindex @samp{mkdirp}, header argument -The @samp{mkdirp} header argument creates parent directories for tangled -files if the directory does not exist. A @samp{yes} value enables -directory creation whereas @samp{no} inhibits it. - -@cindex @samp{comments}, header argument -The @samp{comments} header argument controls inserting comments into -tangled files. These are above and beyond whatever comments may -already exist in the code block. - -@table @asis -@item @samp{no} -The default. Do not insert any extra comments during tangling. - -@item @samp{link} -Wrap the code block in comments. Include links pointing back to the -place in the Org file from where the code was tangled. - -@item @samp{yes} -Kept for backward compatibility; same as @samp{link}. - -@item @samp{org} -Nearest headline text from Org file is inserted as comment. The -exact text that is inserted is picked from the leading context of -the source block. - -@item @samp{both} -Includes both @samp{link} and @samp{org} options. - -@item @samp{noweb} -Includes @samp{link} option, expands noweb references (see @ref{Noweb Reference Syntax}), and wraps them in link comments inside the body -of the code block. -@end table - -@cindex @samp{padline}, header argument -The @samp{padline} header argument controls insertion of newlines to pad -source code in the tangled file. - -@table @asis -@item @samp{yes} -Default. Insert a newline before and after each code block in the -tangled file. - -@item @samp{no} -Do not insert newlines to pad the tangled code blocks. -@end table - -@cindex @samp{shebang}, header argument -The @samp{shebang} header argument can turn results into executable script -files. By setting it to a string value---for example, @samp{:shebang -"#!/bin/bash"}---Org inserts that string as the first line of the -tangled file that the code block is extracted to. Org then turns on -the tangled file's executable permission. - -@cindex @samp{tangle-mode}, header argument -The @samp{tangle-mode} header argument specifies what permissions to set -for tangled files by @code{set-file-modes}. For example, to make -a read-only tangled file, use @samp{:tangle-mode (identity #o444)}. To -make it executable, use @samp{:tangle-mode (identity #o755)}. It also -overrides executable permission granted by @samp{shebang}. When multiple -source code blocks tangle to a single file with different and -conflicting @samp{tangle-mode} header arguments, Org's behavior is -undefined. - -@cindex @samp{no-expand}, header argument -By default Org expands code blocks during tangling. The @samp{no-expand} -header argument turns off such expansions. Note that one side-effect -of expansion by @code{org-babel-expand-src-block} also assigns values (see -@ref{Environment of a Code Block}) to variables. Expansions also replace -noweb references with their targets (see @ref{Noweb Reference Syntax}). -Some of these expansions may cause premature assignment, hence this -option. This option makes a difference only for tangling. It has no -effect when exporting since code blocks for execution have to be -expanded anyway. - -@anchor{Functions} -@subheading Functions - -@table @asis -@item @code{org-babel-tangle} -@findex org-babel-tangle -@kindex C-c C-v t -Tangle the current file. Bound to @kbd{C-c C-v t}. - -With prefix argument only tangle the current code block. - -@item @code{org-babel-tangle-file} -@findex org-babel-tangle-file -@kindex C-c C-v f -Choose a file to tangle. Bound to @kbd{C-c C-v f}. -@end table - -@anchor{Hooks (1)} -@subheading Hooks - -@table @asis -@item @code{org-babel-post-tangle-hook} -@vindex org-babel-post-tangle-hook -This hook is run from within code files tangled by -@code{org-babel-tangle}, making it suitable for post-processing, -compilation, and evaluation of code in the tangled files. -@end table - -@anchor{Jumping between code and Org} -@subheading Jumping between code and Org - -@findex org-babel-tangle-jump-to-org -Debuggers normally link errors and messages back to the source code. -But for tangled files, we want to link back to the Org file, not to -the tangled source file. To make this extra jump, Org uses -@code{org-babel-tangle-jump-to-org} function with two additional source -code block header arguments: - -@enumerate -@item -Set @samp{padline} to true---this is the default setting. -@item -Set @samp{comments} to @samp{link}, which makes Org insert links to the Org -file. -@end enumerate - -@node Languages -@section Languages - -@cindex babel, languages -@cindex source code, languages -@cindex code block, languages - -Code blocks in the following languages are supported. - -@multitable @columnfractions 0.25 0.25 0.25 0.20 -@headitem Language -@tab Identifier -@tab Language -@tab Identifier -@item Asymptote -@tab @samp{asymptote} -@tab Lisp -@tab @samp{lisp} -@item Awk -@tab @samp{awk} -@tab Lua -@tab @samp{lua} -@item C -@tab @samp{C} -@tab MATLAB -@tab @samp{matlab} -@item C++ -@tab @samp{C++}@footnote{C++ language is handled in @samp{ob-C.el}. Even though the -identifier for such source blocks is @samp{C++}, you activate it by loading -the C language.} -@tab Mscgen -@tab @samp{mscgen} -@item Clojure -@tab @samp{clojure} -@tab Objective Caml -@tab @samp{ocaml} -@item CSS -@tab @samp{css} -@tab Octave -@tab @samp{octave} -@item D -@tab @samp{D}@footnote{D language is handled in @samp{ob-C.el}. Even though the -identifier for such source blocks is @samp{D}, you activate it by loading -the C language.} -@tab Org mode -@tab @samp{org} -@item ditaa -@tab @samp{ditaa} -@tab Oz -@tab @samp{oz} -@item Emacs Calc -@tab @samp{calc} -@tab Perl -@tab @samp{perl} -@item Emacs Lisp -@tab @samp{emacs-lisp} -@tab Plantuml -@tab @samp{plantuml} -@item Eshell -@tab @samp{eshell} -@tab Processing.js -@tab @samp{processing} -@item Fortran -@tab @samp{fortran} -@tab Python -@tab @samp{python} -@item Gnuplot -@tab @samp{gnuplot} -@tab R -@tab @samp{R} -@item GNU Screen -@tab @samp{screen} -@tab Ruby -@tab @samp{ruby} -@item Graphviz -@tab @samp{dot} -@tab Sass -@tab @samp{sass} -@item Haskell -@tab @samp{haskell} -@tab Scheme -@tab @samp{scheme} -@item Java -@tab @samp{java} -@tab Sed -@tab @samp{sed} -@item Javascript -@tab @samp{js} -@tab shell -@tab @samp{sh} -@item @LaTeX{} -@tab @samp{latex} -@tab SQL -@tab @samp{sql} -@item Ledger -@tab @samp{ledger} -@tab SQLite -@tab @samp{sqlite} -@item Lilypond -@tab @samp{lilypond} -@tab Vala -@tab @samp{vala} -@end multitable - -Additional documentation for some languages is at -@uref{https://orgmode.org/worg/org-contrib/babel/languages.html}. - -@vindex org-babel-load-languages -By default, only Emacs Lisp is enabled for evaluation. To enable or -disable other languages, customize the @code{org-babel-load-languages} -variable either through the Emacs customization interface, or by -adding code to the init file as shown next. - -In this example, evaluation is disabled for Emacs Lisp, and enabled -for R@. - -@lisp -(org-babel-do-load-languages - 'org-babel-load-languages - '((emacs-lisp . nil) - (R . t))) -@end lisp - -Note that this is not the only way to enable a language. Org also -enables languages when loaded with @code{require} statement. For example, -the following enables execution of Clojure code blocks: - -@lisp -(require 'ob-clojure) -@end lisp - -@node Editing Source Code -@section Editing Source Code - -@cindex code block, editing -@cindex source code, editing - -@kindex C-c ' -Use @kbd{C-c '} to edit the current code block. It opens a new -major mode edit buffer containing the body of the source code block, -ready for any edits. Use @kbd{C-c '} again to close the buffer -and return to the Org buffer. - -@kindex C-x C-s -@vindex org-edit-src-auto-save-idle-delay -@cindex auto-save, in code block editing -@kbd{C-x C-s} saves the buffer and updates the contents of the -Org buffer. Set @code{org-edit-src-auto-save-idle-delay} to save the base -buffer after a certain idle delay time. Set -@code{org-edit-src-turn-on-auto-save} to auto-save this buffer into -a separate file using Auto-save mode. - -While editing the source code in the major mode, the Org Src minor -mode remains active. It provides these customization variables as -described below. For even more variables, look in the customization -group @code{org-edit-structure}. - -@table @asis -@item @code{org-src-lang-modes} -@vindex org-src-lang-modes -If an Emacs major-mode named @code{-mode} exists, where -@var{} is the language identifier from code block's -header line, then the edit buffer uses that major mode. Use this -variable to arbitrarily map language identifiers to major modes. - -@item @code{org-src-window-setup} -@vindex org-src-window-setup -For specifying Emacs window arrangement when the new edit buffer is -created. - -@item @code{org-src-preserve-indentation} -@cindex indentation, in code blocks -@vindex org-src-preserve-indentation -Default is @code{nil}. Source code is indented. This indentation -applies during export or tangling, and depending on the context, may -alter leading spaces and tabs. When non-@code{nil}, source code is -aligned with the leftmost column. No lines are modified during -export or tangling, which is very useful for white-space sensitive -languages, such as Python. - -@item @code{org-src-ask-before-returning-to-edit-buffer} -@vindex org-src-ask-before-returning-to-edit-buffer -When @code{nil}, Org returns to the edit buffer without further prompts. -The default prompts for a confirmation. -@end table - -@vindex org-src-fontify-natively -@vindex org-src-block-faces -Set @code{org-src-fontify-natively} to non-@code{nil} to turn on native code -fontification in the @emph{Org} buffer. Fontification of code blocks can -give visual separation of text and code on the display page. To -further customize the appearance of @code{org-block} for specific -languages, customize @code{org-src-block-faces}. The following example -shades the background of regular blocks, and colors source blocks only -for Python and Emacs Lisp languages. - -@lisp -(require 'color) -(set-face-attribute 'org-block nil :background - (color-darken-name - (face-attribute 'default :background) 3)) - -(setq org-src-block-faces '(("emacs-lisp" (:background "#EEE2FF")) - ("python" (:background "#E5FFB8")))) -@end lisp - -@node Noweb Reference Syntax -@section Noweb Reference Syntax - -@cindex code block, noweb reference -@cindex syntax, noweb -@cindex source code, noweb reference - -@cindex @samp{noweb-ref}, header argument -Source code blocks can include references to other source code blocks, -using a noweb@footnote{For noweb literate programming details, see -@uref{http://www.cs.tufts.edu/~nr/noweb/}.} style syntax: - -@example -<> -@end example - - -@noindent -where @var{CODE-BLOCK-ID} refers to either the @samp{NAME} of a single -source code block, or a collection of one or more source code blocks -sharing the same @samp{noweb-ref} header argument (see @ref{Using Header Arguments}). Org can replace such references with the source code of -the block or blocks being referenced, or, in the case of a single -source code block named with @samp{NAME}, with the results of an evaluation -of that block. - -@cindex @samp{noweb}, header argument -The @samp{noweb} header argument controls expansion of noweb syntax -references. Expansions occur when source code blocks are evaluated, -tangled, or exported. - -@table @asis -@item @samp{no} -Default. No expansion of noweb syntax references in the body of the -code when evaluating, tangling, or exporting. - -@item @samp{yes} -Expansion of noweb syntax references in the body of the code block -when evaluating, tangling, or exporting. - -@item @samp{tangle} -Expansion of noweb syntax references in the body of the code block -when tangling. No expansion when evaluating or exporting. - -@item @samp{no-export} -Expansion of noweb syntax references in the body of the code block -when evaluating or tangling. No expansion when exporting. - -@item @samp{strip-export} -Expansion of noweb syntax references in the body of the code block -when expanding prior to evaluating or tangling. Removes noweb -syntax references when exporting. - -@item @samp{eval} -Expansion of noweb syntax references in the body of the code block -only before evaluating. -@end table - -In the most simple case, the contents of a single source block is -inserted within other blocks. Thus, in following example, - -@example -#+NAME: initialization -#+BEGIN_SRC emacs-lisp - (setq sentence "Never a foot too far, even.") -#+END_SRC - -#+BEGIN_SRC emacs-lisp :noweb yes - <> - (reverse sentence) -#+END_SRC -@end example - -@noindent -the second code block is expanded as - -@example -#+BEGIN_SRC emacs-lisp :noweb yes - (setq sentence "Never a foot too far, even.") - (reverse sentence) -#+END_SRC -@end example - -You may also include the contents of multiple blocks sharing a common -@samp{noweb-ref} header argument, which can be set at the file, sub-tree, -or code block level. In the example Org file shown next, the body of -the source code in each block is extracted for concatenation to a pure -code file when tangled. - -@example -#+BEGIN_SRC sh :tangle yes :noweb yes :shebang #!/bin/sh - <> -#+END_SRC -* the mount point of the fullest disk - :PROPERTIES: - :header-args: :noweb-ref fullest-disk - :END: - -** query all mounted disks -#+BEGIN_SRC sh - df \ -#+END_SRC - -** strip the header row -#+BEGIN_SRC sh - |sed '1d' \ -#+END_SRC - -** output mount point of fullest disk -#+BEGIN_SRC sh - |awk '@{if (u < +$5) @{u = +$5; m = $6@}@} END @{print m@}' -#+END_SRC -@end example - -@cindex @samp{noweb-sep}, header argument -By default a newline separates each noweb reference concatenation. To -use a different separator, edit the @samp{noweb-sep} header argument. - -Alternatively, Org can include the results of evaluation of a single -code block rather than its body. Evaluation occurs when parentheses, -possibly including arguments, are appended to the code block name, as -shown below. - -@example -<> -@end example - - -Note that in this case, a code block name set by @samp{NAME} keyword is -required; the reference set by @samp{noweb-ref} will not work when -evaluation is desired. - -Here is an example that demonstrates how the exported content changes -when noweb style references are used with parentheses versus without. -Given: - -@example -#+NAME: some-code -#+BEGIN_SRC python :var num=0 :results output :exports none - print(num*10) -#+END_SRC -@end example - -@noindent -this code block: - -@example -#+BEGIN_SRC text :noweb yes - <> -#+END_SRC -@end example - -@noindent -expands to: - -@example -print(num*10) -@end example - - -Below, a similar noweb style reference is used, but with parentheses, -while setting a variable @samp{num} to 10: - -@example -#+BEGIN_SRC text :noweb yes - <> -#+END_SRC -@end example - -@noindent -Note that the expansion now contains the results of the code block -@samp{some-code}, not the code block itself: - -@example -100 -@end example - - -Noweb insertions honor prefix characters that appear before the noweb -syntax reference. This behavior is illustrated in the following -example. Because the @samp{<>} noweb reference appears behind the -SQL comment syntax, each line of the expanded noweb reference is -commented. With: - -@example -#+NAME: example -#+BEGIN_SRC text - this is the - multi-line body of example -#+END_SRC -@end example - -@noindent -this code block: - -@example -#+BEGIN_SRC sql :noweb yes - ---<> -#+END_SRC -@end example - -@noindent -expands to: - -@example -#+BEGIN_SRC sql :noweb yes - ---this is the - ---multi-line body of example -#+END_SRC -@end example - -Since this change does not affect noweb replacement text without -newlines in them, inline noweb references are acceptable. - -This feature can also be used for management of indentation in -exported code snippets. With: - -@example -#+NAME: if-true -#+BEGIN_SRC python :exports none - print('do things when true') -#+end_src - -#+name: if-false -#+begin_src python :exports none - print('do things when false') -#+end_src -@end example - -@noindent -this code block: - -@example -#+begin_src python :noweb yes :results output - if true: - <> - else: - <> -#+end_src -@end example - -@noindent -expands to: - -@example -if true: - print('do things when true') -else: - print('do things when false') -@end example - -When in doubt about the outcome of a source code block expansion, you -can preview the results with the following command: - -@table @asis -@item @kbd{C-c C-v v} or @kbd{C-c C-v C-v} (@code{org-babel-expand-src-block}) -@findex org-babel-expand-src-block -@kindex C-c C-v v -@kindex C-c C-v C-v -Expand the current source code block according to its header -arguments and pop open the results in a preview buffer. -@end table - -@node Library of Babel -@section Library of Babel - -@cindex babel, library of -@cindex source code, library -@cindex code block, library - -The ``Library of Babel'' is a collection of code blocks. Like -a function library, these code blocks can be called from other Org -files. A collection of useful code blocks is available on @uref{https://orgmode.org/worg/library-of-babel.html, Worg}. For -remote code block evaluation syntax, see @ref{Evaluating Code Blocks}. - -@kindex C-c C-v i -@findex org-babel-lob-ingest -For any user to add code to the library, first save the code in -regular code blocks of an Org file, and then load the Org file with -@code{org-babel-lob-ingest}, which is bound to @kbd{C-c C-v i}. - -@node Key bindings and Useful Functions -@section Key bindings and Useful Functions - -@cindex code block, key bindings - -Many common Org mode key sequences are re-bound depending on -the context. - -Active key bindings in code blocks: - -@kindex C-c C-c -@findex org-babel-execute-src-block -@kindex C-c C-o -@findex org-babel-open-src-block-result -@kindex M-UP -@findex org-babel-load-in-session -@kindex M-DOWN -@findex org-babel-pop-to-session -@multitable @columnfractions 0.2 0.55 -@headitem Key binding -@tab Function -@item @kbd{C-c C-c} -@tab @code{org-babel-execute-src-block} -@item @kbd{C-c C-o} -@tab @code{org-babel-open-src-block-result} -@item @kbd{M-@key{UP}} -@tab @code{org-babel-load-in-session} -@item @kbd{M-@key{DOWN}} -@tab @code{org-babel-pop-to-session} -@end multitable - -Active key bindings in Org mode buffer: - -@kindex C-c C-v p -@kindex C-c C-v C-p -@kindex C-c C-v n -@kindex C-c C-v C-n -@kindex C-c C-v e -@kindex C-c C-v C-e -@kindex C-c C-v o -@kindex C-c C-v C-o -@kindex C-c C-v v -@kindex C-c C-v C-v -@kindex C-c C-v u -@kindex C-c C-v C-u -@kindex C-c C-v g -@kindex C-c C-v C-g -@kindex C-c C-v r -@kindex C-c C-v C-r -@kindex C-c C-v b -@kindex C-c C-v C-b -@kindex C-c C-v s -@kindex C-c C-v C-s -@kindex C-c C-v d -@kindex C-c C-v C-d -@kindex C-c C-v t -@kindex C-c C-v C-t -@kindex C-c C-v f -@kindex C-c C-v C-f -@kindex C-c C-v c -@kindex C-c C-v C-c -@kindex C-c C-v j -@kindex C-c C-v C-j -@kindex C-c C-v l -@kindex C-c C-v C-l -@kindex C-c C-v i -@kindex C-c C-v C-i -@kindex C-c C-v I -@kindex C-c C-v C-I -@kindex C-c C-v z -@kindex C-c C-v C-z -@kindex C-c C-v a -@kindex C-c C-v C-a -@kindex C-c C-v h -@kindex C-c C-v C-h -@kindex C-c C-v x -@kindex C-c C-v C-x -@findex org-babel-previous-src-block -@findex org-babel-next-src-block -@findex org-babel-execute-maybe -@findex org-babel-open-src-block-result -@findex org-babel-expand-src-block -@findex org-babel-goto-src-block-head -@findex org-babel-goto-named-src-block -@findex org-babel-goto-named-result -@findex org-babel-execute-buffer -@findex org-babel-execute-subtree -@findex org-babel-demarcate-block -@findex org-babel-tangle -@findex org-babel-tangle-file -@findex org-babel-check-src-block -@findex org-babel-insert-header-arg -@findex org-babel-load-in-session -@findex org-babel-lob-ingest -@findex org-babel-view-src-block-info -@findex org-babel-switch-to-session-with-code -@findex org-babel-sha1-hash -@findex org-babel-describe-bindings -@findex org-babel-do-key-sequence-in-edit-buffer -@multitable @columnfractions 0.45 0.55 -@headitem Key binding -@tab Function -@item @kbd{C-c C-v p} or @kbd{C-c C-v C-p} -@tab @code{org-babel-previous-src-block} -@item @kbd{C-c C-v n} or @kbd{C-c C-v C-n} -@tab @code{org-babel-next-src-block} -@item @kbd{C-c C-v e} or @kbd{C-c C-v C-e} -@tab @code{org-babel-execute-maybe} -@item @kbd{C-c C-v o} or @kbd{C-c C-v C-o} -@tab @code{org-babel-open-src-block-result} -@item @kbd{C-c C-v v} or @kbd{C-c C-v C-v} -@tab @code{org-babel-expand-src-block} -@item @kbd{C-c C-v u} or @kbd{C-c C-v C-u} -@tab @code{org-babel-goto-src-block-head} -@item @kbd{C-c C-v g} or @kbd{C-c C-v C-g} -@tab @code{org-babel-goto-named-src-block} -@item @kbd{C-c C-v r} or @kbd{C-c C-v C-r} -@tab @code{org-babel-goto-named-result} -@item @kbd{C-c C-v b} or @kbd{C-c C-v C-b} -@tab @code{org-babel-execute-buffer} -@item @kbd{C-c C-v s} or @kbd{C-c C-v C-s} -@tab @code{org-babel-execute-subtree} -@item @kbd{C-c C-v d} or @kbd{C-c C-v C-d} -@tab @code{org-babel-demarcate-block} -@item @kbd{C-c C-v t} or @kbd{C-c C-v C-t} -@tab @code{org-babel-tangle} -@item @kbd{C-c C-v f} or @kbd{C-c C-v C-f} -@tab @code{org-babel-tangle-file} -@item @kbd{C-c C-v c} or @kbd{C-c C-v C-c} -@tab @code{org-babel-check-src-block} -@item @kbd{C-c C-v j} or @kbd{C-c C-v C-j} -@tab @code{org-babel-insert-header-arg} -@item @kbd{C-c C-v l} or @kbd{C-c C-v C-l} -@tab @code{org-babel-load-in-session} -@item @kbd{C-c C-v i} or @kbd{C-c C-v C-i} -@tab @code{org-babel-lob-ingest} -@item @kbd{C-c C-v I} or @kbd{C-c C-v C-I} -@tab @code{org-babel-view-src-block-info} -@item @kbd{C-c C-v z} or @kbd{C-c C-v C-z} -@tab @code{org-babel-switch-to-session-with-code} -@item @kbd{C-c C-v a} or @kbd{C-c C-v C-a} -@tab @code{org-babel-sha1-hash} -@item @kbd{C-c C-v h} or @kbd{C-c C-v C-h} -@tab @code{org-babel-describe-bindings} -@item @kbd{C-c C-v x} or @kbd{C-c C-v C-x} -@tab @code{org-babel-do-key-sequence-in-edit-buffer} -@end multitable - -@node Batch Execution -@section Batch Execution - -@cindex code block, batch execution -@cindex source code, batch execution - -Org mode features, including working with source code facilities can -be invoked from the command line. This enables building shell scripts -for batch processing, running automated system tasks, and expanding -Org mode's usefulness. - -The sample script shows batch processing of multiple files using -@code{org-babel-tangle}. - -@example -#!/bin/sh -# Tangle files with Org mode -# -emacs -Q --batch --eval " - (progn - (require 'ob-tangle) - (dolist (file command-line-args-left) - (with-current-buffer (find-file-noselect file) - (org-babel-tangle)))) - " "$@@" -@end example - -@node Miscellaneous -@chapter Miscellaneous - -@menu -* Completion:: @kbd{M-@key{TAB}} guesses completions. -* Structure Templates:: Quick insertion of structural elements. -* Speed Keys:: Electric commands at the beginning of a headline. -* Clean View:: Getting rid of leading stars in the outline. -* Execute commands in the active region:: Execute commands on multiple items in Org or agenda view. -* Dynamic Headline Numbering:: Display and update outline numbering. -* The Very Busy @kbd{C-c C-c} Key:: When in doubt, press @kbd{C-c C-c}. -* In-buffer Settings:: Overview of keywords. -* Org Syntax:: Formal description of Org's syntax. -* Documentation Access:: Read documentation about current syntax. -* Escape Character:: Prevent Org from interpreting your writing. -* Code Evaluation Security:: Org files evaluate in-line code. -* Interaction:: With other Emacs packages. -* TTY Keys:: Using Org on a tty. -* Protocols:: External access to Emacs and Org. -* Org Crypt:: Encrypting Org files. -* Org Mobile:: Viewing and capture on a mobile device. -@end menu - -@node Completion -@section Completion - -@cindex completion, of @TeX{} symbols -@cindex completion, of TODO keywords -@cindex completion, of dictionary words -@cindex completion, of option keywords -@cindex completion, of tags -@cindex completion, of property keys -@cindex completion, of link abbreviations -@cindex @TeX{} symbol completion -@cindex TODO keywords completion -@cindex dictionary word completion -@cindex option keyword completion -@cindex tag completion -@cindex link abbreviations, completion of - -Org has in-buffer completions. Unlike minibuffer completions, which -are useful for quick command interactions, Org's in-buffer completions -are more suitable for content creation in Org documents. Type one or -more letters and invoke the hot key to complete the text in-place. -Depending on the context and the keys, Org offers different types of -completions. No minibuffer is involved. Such mode-specific hot keys -have become an integral part of Emacs and Org provides several -shortcuts. - -@table @asis -@item @kbd{M-@key{TAB}} -@kindex M-TAB - -Complete word at point. - -@itemize -@item -At the beginning of an empty headline, complete TODO keywords. - -@item -After @samp{\}, complete @TeX{} symbols supported by the exporter. - -@item -After @samp{:} in a headline, complete tags. Org deduces the list of -tags from the @samp{TAGS} in-buffer option (see @ref{Setting Tags}), the -variable @code{org-tag-alist}, or from all tags used in the current -buffer. - -@item -After @samp{:} and not in a headline, complete property keys. The list -of keys is constructed dynamically from all keys used in the -current buffer. - -@item -After @samp{[[}, complete link abbreviations (see @ref{Link Abbreviations}). - -@item -After @samp{[[*}, complete headlines in the current buffer so that they -can be used in search links like: @samp{[[*find this headline]]} - -@item -After @samp{#+}, complete the special keywords like @samp{TYP_TODO} or -file-specific @samp{OPTIONS}. After option keyword is complete, -pressing @kbd{M-@key{TAB}} again inserts example settings for this -keyword. - -@item -After @samp{STARTUP} keyword, complete startup items. - -@item -When point is anywhere else, complete dictionary words using -Ispell. -@end itemize -@end table - -@node Structure Templates -@section Structure Templates - -@cindex template insertion -@cindex insertion, of templates - -With just a few keystrokes, it is possible to insert empty structural -blocks, such as @samp{#+BEGIN_SRC} @dots{} @samp{#+END_SRC}, or to wrap existing -text in such a block. - -@table @asis -@item @kbd{C-c C-,} (@code{org-insert-structure-template}) -@findex org-insert-structure-template -@kindex C-c C-, -Prompt for a type of block structure, and insert the block at point. -If the region is active, it is wrapped in the block. First prompts -the user for keys, which are used to look up a structure type from -the variable below. If the key is @kbd{@key{TAB}}, @kbd{@key{RET}}, -or @kbd{@key{SPC}}, the user is prompted to enter a block type. -@end table - -@vindex org-structure-template-alist -Available structure types are defined in -@code{org-structure-template-alist}, see the docstring for adding or -changing values. - -@cindex Tempo -@cindex template expansion -@cindex insertion, of templates -@vindex org-tempo-keywords-alist -Org Tempo expands snippets to structures defined in -@code{org-structure-template-alist} and @code{org-tempo-keywords-alist}. For -example, @kbd{< s @key{TAB}} creates a code block. Enable it by -customizing @code{org-modules} or add @samp{(require 'org-tempo)} to your Emacs -init file@footnote{For more information, please refer to the commentary section -in @samp{org-tempo.el}.}. - -@multitable @columnfractions 0.1 0.9 -@item @kbd{a} -@tab @samp{#+BEGIN_EXPORT ascii} @dots{} @samp{#+END_EXPORT} -@item @kbd{c} -@tab @samp{#+BEGIN_CENTER} @dots{} @samp{#+END_CENTER} -@item @kbd{C} -@tab @samp{#+BEGIN_COMMENT} @dots{} @samp{#+END_COMMENT} -@item @kbd{e} -@tab @samp{#+BEGIN_EXAMPLE} @dots{} @samp{#+END_EXAMPLE} -@item @kbd{E} -@tab @samp{#+BEGIN_EXPORT} @dots{} @samp{#+END_EXPORT} -@item @kbd{h} -@tab @samp{#+BEGIN_EXPORT html} @dots{} @samp{#+END_EXPORT} -@item @kbd{l} -@tab @samp{#+BEGIN_EXPORT latex} @dots{} @samp{#+END_EXPORT} -@item @kbd{q} -@tab @samp{#+BEGIN_QUOTE} @dots{} @samp{#+END_QUOTE} -@item @kbd{s} -@tab @samp{#+BEGIN_SRC} @dots{} @samp{#+END_SRC} -@item @kbd{v} -@tab @samp{#+BEGIN_VERSE} @dots{} @samp{#+END_VERSE} -@end multitable - -@node Speed Keys -@section Speed Keys - -@cindex speed keys - -Single keystrokes can execute custom commands in an Org file when -point is on a headline. Without the extra burden of a meta or -modifier key, Speed Keys can speed navigation or execute custom -commands. Besides faster navigation, Speed Keys may come in handy on -small mobile devices that do not have full keyboards. Speed Keys may -also work on TTY devices known for their problems when entering Emacs -key chords. - -@vindex org-use-speed-commands -By default, Org has Speed Keys disabled. To activate Speed Keys, set -the variable @code{org-use-speed-commands} to a non-@code{nil} value. To -trigger a Speed Key, point must be at the beginning of an Org -headline, before any of the stars. - -@vindex org-speed-commands-user -@findex org-speed-command-help -Org comes with a pre-defined list of Speed Keys. To add or modify -Speed Keys, customize the variable, @code{org-speed-commands-user}. For -more details, see the variable's docstring. With Speed Keys -activated, @kbd{M-x org-speed-command-help}, or @kbd{?} when -point is at the beginning of an Org headline, shows currently active -Speed Keys, including the user-defined ones. - -@node Clean View -@section A Cleaner Outline View - -@cindex hiding leading stars -@cindex dynamic indentation -@cindex odd-levels-only outlines -@cindex clean outline view - -Org's outline with stars and no indents can look cluttered for short -documents. For @emph{book-like} long documents, the effect is not as -noticeable. Org provides an alternate stars and indentation scheme, -as shown on the right in the following table. It displays only one -star and indents text to line up with the heading: - -@example -* Top level headline | * Top level headline -** Second level | * Second level -*** Third level | * Third level -some text | some text -*** Third level | * Third level -more text | more text -* Another top level headline | * Another top level headline -@end example - -Org can achieve this in two ways, (1) by just displaying the buffer in -this way without changing it, or (2) by actually indenting every line -in the desired amount with hard spaces and hiding leading stars. - -@menu -* Org Indent Mode:: -* Hard indentation:: -@end menu - -@node Org Indent Mode -@subsection Org Indent Mode - -@cindex Indent mode -@findex org-indent-mode -To display the buffer in the indented view, activate Org Indent minor -mode, using @kbd{M-x org-indent-mode}. Text lines that are not -headlines are prefixed with virtual spaces to vertically align with -the headline text@footnote{Org Indent mode also sets @code{wrap-prefix} correctly for -indenting and wrapping long lines of headlines or text. This minor -mode also handles Visual Line mode and directly applied settings -through @code{word-wrap}.}. - -@vindex org-indent-indentation-per-level -To make more horizontal space, the headlines are shifted by two -characters. Configure @code{org-indent-indentation-per-level} variable for -a different number. - -@vindex org-indent-mode-turns-on-hiding-stars -@vindex org-indent-mode-turns-off-org-adapt-indentation -By default, Org Indent mode turns off @code{org-adapt-indentation} and does -hide leading stars by locally setting @code{org-hide-leading-stars} to @code{t}: -only one star on each headline is visible, the rest are masked with -the same font color as the background. If you want to customize this -default behavior, see @code{org-indent-mode-turns-on-hiding-stars} and -@code{org-indent-mode-turns-off-org-adapt-indentation}. - -@vindex org-startup-indented -To globally turn on Org Indent mode for all files, customize the -variable @code{org-startup-indented}. To control it for individual files, -use @samp{STARTUP} keyword as follows: - -@example -#+STARTUP: indent -#+STARTUP: noindent -@end example - -@node Hard indentation -@subsection Hard indentation - -It is possible to use hard spaces to achieve the indentation instead, -if the bare ASCII file should have the indented look also outside -Emacs@footnote{This works, but requires extra effort. Org Indent mode is -more convenient for most applications.}. With Org's support, you have to indent all lines to -line up with the outline headers. You would use these -settings@footnote{@code{org-adapt-indentation} can also be set to @samp{'headline-data}, -in which case only data lines below the headline will be indented.}: - -@lisp -(setq org-adapt-indentation t - org-hide-leading-stars t - org-odd-levels-only t) -@end lisp - -@table @asis -@item @emph{Indentation of text below headlines} (@code{org-adapt-indentation}) -@vindex org-adapt-indentation -The first setting modifies paragraph filling, line wrapping, and -structure editing commands to preserving or adapting the indentation -as appropriate. - -@item @emph{Hiding leading stars} (@code{org-hide-leading-stars}) -@vindex org-hide-leading-stars -@vindex org-hide, face -The second setting makes leading stars invisible by applying the -face @code{org-hide} to them. For per-file preference, use these file -@samp{STARTUP} options: - -@example -#+STARTUP: hidestars -#+STARTUP: showstars -@end example - -@item @emph{Odd levels} (@code{org-odd-levels-only}) -@vindex org-odd-levels-only -The third setting makes Org use only odd levels, 1, 3, 5, @dots{}, in -the outline to create more indentation. On a per-file level, -control this with: - -@example -#+STARTUP: odd -#+STARTUP: oddeven -@end example - -To convert a file between single and double stars layouts, use -@kbd{M-x org-convert-to-odd-levels} and @kbd{M-x org-convert-to-oddeven-levels}. -@end table - -@node Execute commands in the active region -@section Execute commands in the active region - -@vindex org-loop-over-headlines-in-active-region -When in an Org buffer and the region is active, some commands will -apply to all the subtrees in the active region. For example, hitting -@kbd{C-c C-s} when multiple headlines are within the active region will -successively prompt you for a new schedule date and time. To disable -this, set the option @code{org-loop-over-headlines-in-active-region} to -non-@code{t}, activate the region and run the command normally. - -@vindex org-agenda-loop-over-headlines-in-active-region -@code{org-agenda-loop-over-headlines-in-active-region} is the equivalent -option of the agenda buffer, where you can also use @ref{Bulk remote editing selected entries, , bulk editing of -selected entries}. - -Not all commands can loop in the active region and what subtrees or -headlines are considered can be refined: see the docstrings of these -options for more details. - -@node Dynamic Headline Numbering -@section Dynamic Headline Numbering - -@cindex Org Num mode -@cindex number headlines -The Org Num minor mode, toggled with @kbd{M-x org-num-mode}, -displays outline numbering on top of headlines. It also updates it -automatically upon changes to the structure of the document. - -@vindex org-num-max-level -@vindex org-num-skip-tags -@vindex org-num-skip-commented -@vindex org-num-skip-unnumbered -By default, all headlines are numbered. You can limit numbering to -specific headlines according to their level, tags, @samp{COMMENT} keyword, -or @samp{UNNUMBERED} property. Set @code{org-num-max-level}, -@code{org-num-skip-tags}, @code{org-num-skip-commented}, -@code{org-num-skip-unnumbered}, or @code{org-num-skip-footnotes} accordingly. - -@vindex org-num-skip-footnotes -If @code{org-num-skip-footnotes} is non-@code{nil}, footnotes sections (see -@ref{Creating Footnotes}) are not numbered either. - -@vindex org-num-face -@vindex org-num-format-function -You can control how the numbering is displayed by setting -@code{org-num-face} and @code{org-num-format-function}. - -@vindex org-startup-numerated -You can also turn this mode globally for all Org files by setting the -option @code{org-startup-numerated} to @samp{t}, or locally on a file by using -@samp{#+startup: num}. - -@node The Very Busy @kbd{C-c C-c} Key -@section The Very Busy @kbd{C-c C-c} Key - -@kindex C-c C-c -@cindex @kbd{C-c C-c}, overview - -The @kbd{C-c C-c} key in Org serves many purposes depending on -the context. It is probably the most over-worked, multi-purpose key -combination in Org. Its uses are well documented throughout this -manual, but here is a consolidated list for easy reference. - -@itemize -@item -If column view (see @ref{Column View}) is on, exit column view. - -@item -If any highlights shown in the buffer from the creation of a sparse -tree, or from clock display, remove such highlights. - -@item -If point is in one of the special @samp{KEYWORD} lines, scan the buffer -for these lines and update the information. Also reset the Org file -cache used to temporary store the contents of URLs used as values -for keywords like @samp{SETUPFILE}. - -@item -If point is inside a table, realign the table. - -@item -If point is on a @samp{TBLFM} keyword, re-apply the formulas to the -entire table. - -@item -If the current buffer is a capture buffer, close the note and file -it. With a prefix argument, also jump to the target location after -saving the note. - -@item -If point is on a @samp{<<>>}, update radio targets and -corresponding links in this buffer. - -@item -If point is on a property line or at the start or end of a property -drawer, offer property commands. - -@item -If point is at a footnote reference, go to the corresponding -definition, and @emph{vice versa}. - -@item -If point is on a statistics cookie, update it. - -@item -If point is in a plain list item with a checkbox, toggle the status -of the checkbox. - -@item -If point is on a numbered item in a plain list, renumber the ordered -list. - -@item -If point is on the @samp{#+BEGIN} line of a dynamic block, the block is -updated. - -@item -If point is at a timestamp, fix the day name in the timestamp. -@end itemize - -@node In-buffer Settings -@section Summary of In-Buffer Settings - -@cindex in-buffer settings -@cindex special keywords - -In-buffer settings start with @samp{#+}, followed by a keyword, a colon, -and then a word for each setting. Org accepts multiple settings on -the same line. Org also accepts multiple lines for a keyword. This -manual describes these settings throughout. A summary follows here. - -@cindex refresh set-up -@kbd{C-c C-c} activates any changes to the in-buffer settings. -Closing and reopening the Org file in Emacs also activates the -changes. - -@table @asis -@item @samp{#+ARCHIVE: %s_done::} -@cindex @samp{ARCHIVE}, keyword -@vindex org-archive-location -Sets the archive location of the agenda file. The corresponding -variable is @code{org-archive-location}. - -@item @samp{#+CATEGORY} -@cindex @samp{CATEGORY}, keyword -Sets the category of the agenda file, which applies to the entire -document. - -@item @samp{#+COLUMNS: %25ITEM ...} -@cindex @samp{COLUMNS}, property -Set the default format for columns view. This format applies when -columns view is invoked in locations where no @samp{COLUMNS} property -applies. - -@item @samp{#+CONSTANTS: name1=value1 ...} -@cindex @samp{CONSTANTS}, keyword -@vindex org-table-formula-constants -@vindex org-table-formula -Set file-local values for constants that table formulas can use. -This line sets the local variable -@code{org-table-formula-constants-local}. The global version of this -variable is @code{org-table-formula-constants}. - -@item @samp{#+FILETAGS: :tag1:tag2:tag3:} -@cindex @samp{FILETAGS}, keyword -Set tags that all entries in the file inherit from, including the -top-level entries. - -@item @samp{#+LINK: linkword replace} -@cindex @samp{LINK}, keyword -@vindex org-link-abbrev-alist -Each line specifies one abbreviation for one link. Use multiple -@samp{LINK} keywords for more, see @ref{Link Abbreviations}. The -corresponding variable is @code{org-link-abbrev-alist}. - -@item @samp{#+PRIORITIES: highest lowest default} -@cindex @samp{PRIORITIES}, keyword -@vindex org-priority-highest -@vindex org-priority-lowest -@vindex org-priority-default -This line sets the limits and the default for the priorities. All -three must be either letters A--Z or numbers 0--9. The highest -priority must have a lower ASCII number than the lowest priority. - -@item @samp{#+PROPERTY: Property_Name Value} -@cindex @samp{PROPERTY}, keyword -This line sets a default inheritance value for entries in the -current buffer, most useful for specifying the allowed values of -a property. - -@item @samp{#+SETUPFILE: file} -@cindex @samp{SETUPFILE}, keyword -The setup file or a URL pointing to such file is for additional -in-buffer settings. Org loads this file and parses it for any -settings in it only when Org opens the main file. If URL is -specified, the contents are downloaded and stored in a temporary -file cache. @kbd{C-c C-c} on the settings line parses and -loads the file, and also resets the temporary file cache. Org also -parses and loads the document during normal exporting process. Org -parses the contents of this document as if it was included in the -buffer. It can be another Org file. To visit the file---not -a URL---use @kbd{C-c '} while point is on the line with the -file name. - -@item @samp{#+STARTUP:} -@cindex @samp{STARTUP}, keyword -Startup options Org uses when first visiting a file. - -@vindex org-startup-folded -The first set of options deals with the initial visibility of the -outline tree. The corresponding variable for global default -settings is @code{org-startup-folded} with a default value of -@code{showeverything}. - -@multitable {aaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{overview} -@tab Top-level headlines only. -@item @samp{content} -@tab All headlines. -@item @samp{showall} -@tab No folding on any entry. -@item @samp{showeverything} -@tab Show even drawer contents. -@end multitable - -@vindex org-startup-indented -Dynamic virtual indentation is controlled by the variable -@code{org-startup-indented}@footnote{Note that Org Indent mode also sets the @code{wrap-prefix} -property, such that Visual Line mode (or purely setting @code{word-wrap}) -wraps long lines, including headlines, correctly indented.}. - -@multitable {aaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{indent} -@tab Start with Org Indent mode turned on. -@item @samp{noindent} -@tab Start with Org Indent mode turned off. -@end multitable - -@vindex org-startup-numerated -Dynamic virtual numeration of headlines is controlled by the variable -@code{org-startup-numerated}. - -@multitable {aaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{num} -@tab Start with Org num mode turned on. -@item @samp{nonum} -@tab Start with Org num mode turned off. -@end multitable - -@vindex org-startup-align-all-tables -Aligns tables consistently upon visiting a file. The -corresponding variable is @code{org-startup-align-all-tables} with -@code{nil} as default value. - -@multitable {aaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{align} -@tab Align all tables. -@item @samp{noalign} -@tab Do not align tables on startup. -@end multitable - -@vindex org-startup-shrink-all-tables -Shrink table columns with a width cookie. The corresponding -variable is @code{org-startup-shrink-all-tables} with @code{nil} as -default value. - -@vindex org-startup-with-inline-images -When visiting a file, inline images can be automatically -displayed. The corresponding variable is -@code{org-startup-with-inline-images}, with a default value @code{nil} to -avoid delays when visiting a file. - -@multitable {aaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{inlineimages} -@tab Show inline images. -@item @samp{noinlineimages} -@tab Do not show inline images on startup. -@end multitable - -@vindex org-log-done -@vindex org-log-note-clock-out -@vindex org-log-repeat -Logging the closing and reopening of TODO items and clock -intervals can be configured using these options (see variables -@code{org-log-done}, @code{org-log-note-clock-out}, and @code{org-log-repeat}). - -@multitable {aaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{logdone} -@tab Record a timestamp when an item is marked as done. -@item @samp{lognotedone} -@tab Record timestamp and a note when DONE@. -@item @samp{nologdone} -@tab Do not record when items are marked as done. -@item @samp{logrepeat} -@tab Record a time when reinstating a repeating item. -@item @samp{lognoterepeat} -@tab Record a note when reinstating a repeating item. -@item @samp{nologrepeat} -@tab Do not record when reinstating repeating item. -@item @samp{lognoteclock-out} -@tab Record a note when clocking out. -@item @samp{nolognoteclock-out} -@tab Do not record a note when clocking out. -@item @samp{logreschedule} -@tab Record a timestamp when scheduling time changes. -@item @samp{lognotereschedule} -@tab Record a note when scheduling time changes. -@item @samp{nologreschedule} -@tab Do not record when a scheduling date changes. -@item @samp{logredeadline} -@tab Record a timestamp when deadline changes. -@item @samp{lognoteredeadline} -@tab Record a note when deadline changes. -@item @samp{nologredeadline} -@tab Do not record when a deadline date changes. -@item @samp{logrefile} -@tab Record a timestamp when refiling. -@item @samp{lognoterefile} -@tab Record a note when refiling. -@item @samp{nologrefile} -@tab Do not record when refiling. -@end multitable - -@vindex org-hide-leading-stars -@vindex org-odd-levels-only -Here are the options for hiding leading stars in outline -headings, and for indenting outlines. The corresponding -variables are @code{org-hide-leading-stars} and -@code{org-odd-levels-only}, both with a default setting @code{nil} -(meaning @samp{showstars} and @samp{oddeven}). - -@multitable {aaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{hidestars} -@tab Make all but one of the stars starting a headline invisible. -@item @samp{showstars} -@tab Show all stars starting a headline. -@item @samp{indent} -@tab Virtual indentation according to outline level. -@item @samp{noindent} -@tab No virtual indentation according to outline level. -@item @samp{odd} -@tab Allow only odd outline levels (1, 3, @dots{}). -@item @samp{oddeven} -@tab Allow all outline levels. -@end multitable - -@vindex org-put-time-stamp-overlays -@vindex org-time-stamp-overlay-formats -To turn on custom format overlays over timestamps (variables -@code{org-put-time-stamp-overlays} and -@code{org-time-stamp-overlay-formats}), use: - -@multitable {aaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{customtime} -@tab Overlay custom time format. -@end multitable - -@vindex constants-unit-system -The following options influence the table spreadsheet (variable -@code{constants-unit-system}). - -@multitable {aaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{constcgs} -@tab @samp{constants.el} should use the c-g-s unit system. -@item @samp{constSI} -@tab @samp{constants.el} should use the SI unit system. -@end multitable - -@vindex org-footnote-define-inline -@vindex org-footnote-auto-label -@vindex org-footnote-auto-adjust -To influence footnote settings, use the following keywords. The -corresponding variables are @code{org-footnote-define-inline}, -@code{org-footnote-auto-label}, and @code{org-footnote-auto-adjust}. - -@multitable {aaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{fninline} -@tab Define footnotes inline. -@item @samp{fnnoinline} -@tab Define footnotes in separate section. -@item @samp{fnlocal} -@tab Define footnotes near first reference, but not inline. -@item @samp{fnprompt} -@tab Prompt for footnote labels. -@item @samp{fnauto} -@tab Create @samp{[fn:1]}-like labels automatically (default). -@item @samp{fnconfirm} -@tab Offer automatic label for editing or confirmation. -@item @samp{fnadjust} -@tab Automatically renumber and sort footnotes. -@item @samp{nofnadjust} -@tab Do not renumber and sort automatically. -@end multitable - -@vindex org-hide-block-startup -To hide blocks on startup, use these keywords. The -corresponding variable is @code{org-hide-block-startup}. - -@multitable {aaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{hideblocks} -@tab Hide all begin/end blocks on startup. -@item @samp{nohideblocks} -@tab Do not hide blocks on startup. -@end multitable - -@vindex org-pretty-entities -The display of entities as UTF-8 characters is governed by the -variable @code{org-pretty-entities} and the keywords - -@multitable {aaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @samp{entitiespretty} -@tab Show entities as UTF-8 characters where possible. -@item @samp{entitiesplain} -@tab Leave entities plain. -@end multitable - -@item @samp{#+TAGS: TAG1(c1) TAG2(c2)} -@cindex @samp{TAGS}, keyword -@vindex org-tag-alist -These lines (several such lines are allowed) specify the valid tags -in this file, and (potentially) the corresponding @emph{fast tag -selection} keys. The corresponding variable is @code{org-tag-alist}. - -@item @samp{#+TODO:} -@itemx @samp{#+SEQ_TODO:} -@itemx @samp{#+TYP_TODO:} -@cindex @samp{SEQ_TODO}, keyword -@cindex @samp{TODO}, keyword -@cindex @samp{TYP_TODO}, keyword -@vindex org-todo-keywords -These lines set the TODO keywords and their interpretation in the -current file. The corresponding variable is @code{org-todo-keywords}. -@end table - -@node Org Syntax -@section Org Syntax - -A reference document providing a formal description of Org's syntax is -available as @uref{https://orgmode.org/worg/dev/org-syntax.html, a draft on Worg}, written and maintained by Nicolas -Goaziou. It defines Org's core internal concepts such as ``headlines'', -``sections'', ``affiliated keywords'', ``(greater) elements'' and ``objects''. -Each part of an Org document belongs to one of the previous -categories. - -To explore the abstract structure of an Org buffer, run this in -a buffer: - -@example -M-: (org-element-parse-buffer) -@end example - - -@noindent -It outputs a list containing the buffer's content represented as an -abstract structure. The export engine relies on the information -stored in this list. Most interactive commands---e.g., for structure -editing---also rely on the syntactic meaning of the surrounding -context. - -@cindex syntax checker -@cindex linter -@findex org-lint -You can probe the syntax of your documents with the command - -@example -M-x org-lint -@end example - - -@noindent -It runs a number of checks to find common mistakes. It then displays -their location in a dedicated buffer, along with a description and -a ``trust level'', since false-positive are possible. From there, you -can operate on the reports with the following keys: - -@multitable @columnfractions 0.22 0.78 -@item @kbd{C-j}, @kbd{@key{TAB}} -@tab Display the offending line -@item @kbd{@key{RET}} -@tab Move point to the offending line -@item @kbd{g} -@tab Check the document again -@item @kbd{h} -@tab Hide all reports from the same checker -@item @kbd{i} -@tab Also remove them from all subsequent checks -@item @kbd{S} -@tab Sort reports by the column at point -@end multitable - -@node Documentation Access -@section Context Dependent Documentation - -@cindex documentation -@cindex Info - -@findex org-info-find-node -@kindex C-c C-x I -@kbd{C-c C-x I} in an Org file tries to open a suitable section -of the Org manual depending on the syntax at point. For example, -using it on a headline displays ``Document Structure'' section. - -@kbd{q} closes the Info window. - -@node Escape Character -@section Escape Character - -@cindex escape character -@cindex zero width space -You may sometimes want to write text that looks like Org syntax, but -should really read as plain text. Org may use a specific escape -character in some situations, i.e., a backslash in macros (see @ref{Macro Replacement}) and links (see @ref{Link Format}), or a comma in source and -example blocks (see @ref{Literal Examples}). In the general case, however, -we suggest to use the zero width space. You can insert one with any -of the following: - -@example -C-x 8 zero width space -C-x 8 200B -@end example - - -For example, in order to write @samp{[[1,2]]} as-is in your document, you -may write instead - -@example -[X[1,2]] -@end example - - -where @samp{X} denotes the zero width space character. - -@node Code Evaluation Security -@section Code Evaluation and Security Issues - -Unlike plain text, running code comes with risk. Each source code -block, in terms of risk, is equivalent to an executable file. Org -therefore puts a few confirmation prompts by default. This is to -alert the casual user from accidentally running untrusted code. - -For users who do not run code blocks or write code regularly, Org's -default settings should suffice. However, some users may want to -tweak the prompts for fewer interruptions. To weigh the risks of -automatic execution of code blocks, here are some details about code -evaluation. - -Org evaluates code in the following circumstances: - -@table @asis -@item @emph{Source code blocks} -Org evaluates source code blocks in an Org file during export. Org -also evaluates a source code block with the @kbd{C-c C-c} key -chord. Users exporting or running code blocks must load files only -from trusted sources. Be wary of customizing variables that remove -or alter default security measures. - -@defopt org-confirm-babel-evaluate -When @code{t}, Org prompts the user for confirmation before executing -each code block. When @code{nil}, Org executes code blocks without -prompting the user for confirmation. When this option is set to -a custom function, Org invokes the function with these two -arguments: the source code language and the body of the code block. -The custom function must return either a @code{t} or @code{nil}, which -determines if the user is prompted. Each source code language can -be handled separately through this function argument. -@end defopt - -For example, here is how to execute ditaa code blocks without -prompting: - -@lisp -(defun my-org-confirm-babel-evaluate (lang body) - (not (string= lang "ditaa"))) ;don't ask for ditaa -(setq org-confirm-babel-evaluate #'my-org-confirm-babel-evaluate) -@end lisp - -@item @emph{Following @samp{shell} and @samp{elisp} links} -Org has two link types that can directly evaluate code (see -@ref{External Links}). Because such code is not visible, these links -have a potential risk. Org therefore prompts the user when it -encounters such links. The customization variables are: - -@defopt org-link-shell-confirm-function -Function that prompts the user before executing a shell link. -@end defopt - -@defopt org-link-elisp-confirm-function -Function that prompts the user before executing an Emacs Lisp link. -@end defopt - -@item @emph{Formulas in tables} -Formulas in tables (see @ref{The Spreadsheet}) are code that is evaluated -either by the Calc interpreter, or by the Emacs Lisp interpreter. -@end table - -@node Interaction -@section Interaction with Other Packages - -@cindex packages, interaction with other - -Org's compatibility and the level of interaction with other Emacs -packages are documented here. - -@menu -* Cooperation:: Packages Org cooperates with. -* Conflicts:: Packages that lead to conflicts. -@end menu - -@node Cooperation -@subsection Packages that Org cooperates with - -@table @asis -@item @samp{calc.el} by Dave Gillespie -@cindex @file{calc.el} - -Org uses the Calc package for implementing spreadsheet functionality -in its tables (see @ref{The Spreadsheet}). Org also uses Calc for -embedded calculations. See @ref{Embedded Mode,GNU Emacs Calc Manual,,calc,}. - -@item @samp{constants.el} by Carsten Dominik -@cindex @file{constants.el} -@vindex org-table-formula-constants - -Org can use names for constants in formulas in tables. Org can also -use calculation suffixes for units, such as @samp{M} for @samp{Mega}. For -a standard collection of such constants, install the @samp{constants} -package. Install version 2.0 of this package, available at -@uref{http://www.astro.uva.nl/~dominik/Tools}. Org checks if the function -@code{constants-get} has been autoloaded. Installation instructions are -in the file @samp{constants.el}. - -@item @samp{cdlatex.el} by Carsten Dominik -@cindex @file{cdlatex.el} - -Org mode can make use of the CD@LaTeX{} package to efficiently enter -@LaTeX{} fragments into Org files. See @ref{CD@LaTeX{} mode}. - -@item @samp{imenu.el} by Ake Stenhoff and Lars Lindberg -@cindex @file{imenu.el} - -Imenu creates dynamic menus based on an index of items in a file. -Org mode supports Imenu menus. Enable it with a mode hook as -follows: - -@lisp -(add-hook 'org-mode-hook - (lambda () (imenu-add-to-menubar "Imenu"))) -@end lisp - -@vindex org-imenu-depth -By default the index is two levels deep---you can modify the -depth using the option @code{org-imenu-depth}. - -@item @samp{speedbar.el} by Eric@tie{}M@.@tie{}Ludlam -@cindex @file{speedbar.el} - -Speedbar package creates a special Emacs frame for displaying files -and index items in files. Org mode supports Speedbar; users can -drill into Org files directly from the Speedbar. The @kbd{<} -in the Speedbar frame tweaks the agenda commands to that file or to -a subtree. - -@item @samp{table.el} by Takaaki Ota -@cindex table editor, @file{table.el} -@cindex @file{table.el} - -Complex ASCII tables with automatic line wrapping, column- and -row-spanning, and alignment can be created using the Emacs table -package by Takaaki Ota. Org mode recognizes such tables and exports -them properly. @kbd{C-c '} to edit these tables in a special -buffer, much like Org's code blocks. Because of interference with -other Org mode functionality, Takaaki Ota tables cannot be edited -directly in the Org buffer. - -@table @asis -@item @kbd{C-c '} (@code{org-edit-special}) -@kindex C-c ' -@findex org-edit-special -Edit a @samp{table.el} table. Works when point is in a @samp{table.el} -table. - -@item @kbd{C-c ~​} (@code{org-table-create-with-table.el}) -@kindex C-c ~ -@findex org-table-create-with-table.el -Insert a @samp{table.el} table. If there is already a table at point, -this command converts it between the @samp{table.el} format and the Org -mode format. See the documentation string of the command -@code{org-convert-table} for the restrictions under which this is -possible. -@end table -@end table - -@node Conflicts -@subsection Packages that conflict with Org mode - -@cindex shift-selection -@vindex org-support-shift-select -In Emacs, shift-selection combines motions of point with shift key to -enlarge regions. Emacs sets this mode by default. This conflicts -with Org's use of @kbd{S-} commands to change timestamps, -TODO keywords, priorities, and item bullet types, etc. Since -@kbd{S-} commands outside of specific contexts do not do -anything, Org offers the variable @code{org-support-shift-select} for -customization. Org mode accommodates shift selection by (i) making it -available outside of the special contexts where special commands -apply, and (ii) extending an existing active region even if point -moves across a special context. - -@table @asis -@item @samp{cua.el} by Kim@tie{}F@.@tie{}Storm -@cindex @file{cua.el} -@vindex org-replace-disputed-keys -Org key bindings conflict with @kbd{S-} keys used by -CUA mode. For Org to relinquish these bindings to CUA mode, -configure the variable @code{org-replace-disputed-keys}. When set, Org -moves the following key bindings in Org files, and in the agenda -buffer---but not during date selection. - -@multitable @columnfractions 0.4 0.4 -@item @kbd{S-@key{UP}} @result{} @kbd{M-p} -@tab @kbd{S-@key{DOWN}} @result{} @kbd{M-n} -@item @kbd{S-@key{LEFT}} @result{} @kbd{M--} -@tab @kbd{S-@key{RIGHT}} @result{} @kbd{M-+} -@item @kbd{C-S-@key{LEFT}} @result{} @kbd{M-S--} -@tab @kbd{C-S-@key{RIGHT}} @result{} @kbd{M-S-+} -@end multitable - -@vindex org-disputed-keys -Yes, these are unfortunately more difficult to remember. If you -want to have other replacement keys, look at the variable -@code{org-disputed-keys}. - -@item @samp{ecomplete.el} by Lars Magne Ingebrigtsen -@cindex @file{ecomplete.el} -Ecomplete provides ``electric'' address completion in address header -lines in message buffers. Sadly Orgtbl mode cuts Ecomplete's power -supply: no completion happens when Orgtbl mode is enabled in message -buffers while entering text in address header lines. If one wants -to use ecomplete one should @emph{not} follow the advice to automagically -turn on Orgtbl mode in message buffers (see @ref{Orgtbl Mode}), -but instead---after filling in the message headers---turn on Orgtbl -mode manually when needed in the messages body. - -@item @samp{filladapt.el} by Kyle Jones -@cindex @file{filladapt.el} -Org mode tries to do the right thing when filling paragraphs, list -items and other elements. Many users reported problems using both -@samp{filladapt.el} and Org mode, so a safe thing to do is to disable -filladapt like this: - -@lisp -(add-hook 'org-mode-hook 'turn-off-filladapt-mode) -@end lisp - -@item @samp{viper.el} by Michael Kifer -@cindex @file{viper.el} -@kindex C-c / - -Viper uses @kbd{C-c /} and therefore makes this key not access -the corresponding Org mode command @code{org-sparse-tree}. You need to -find another key for this command, or override the key in -@code{viper-vi-global-user-map} with - -@lisp -(define-key viper-vi-global-user-map "C-c /" 'org-sparse-tree) -@end lisp - -@item @samp{windmove.el} by Hovav Shacham -@cindex @file{windmove.el} - -This package also uses the @kbd{S-} keys, so everything -written in the paragraph above about CUA mode also applies here. If -you want to make the windmove function active in locations where Org -mode does not have special functionality on @kbd{S-}, -add this to your configuration: - -@lisp -;; Make windmove work in Org mode: -(add-hook 'org-shiftup-final-hook 'windmove-up) -(add-hook 'org-shiftleft-final-hook 'windmove-left) -(add-hook 'org-shiftdown-final-hook 'windmove-down) -(add-hook 'org-shiftright-final-hook 'windmove-right) -@end lisp - -@item @samp{yasnippet.el} -@cindex @file{yasnippet.el} -The way Org mode binds the @kbd{@key{TAB}} key (binding to @code{[tab]} -instead of @code{"\t"}) overrules YASnippet's access to this key. The -following code fixed this problem: - -@lisp -(add-hook 'org-mode-hook - (lambda () - (setq-local yas/trigger-key [tab]) - (define-key yas/keymap [tab] 'yas/next-field-or-maybe-expand))) -@end lisp - -The latest version of YASnippet does not play well with Org mode. -If the above code does not fix the conflict, start by defining -the following function: - -@lisp -(defun yas/org-very-safe-expand () - (let ((yas/fallback-behavior 'return-nil)) (yas/expand))) -@end lisp - -Then, tell Org mode to use that function: - -@lisp -(add-hook 'org-mode-hook - (lambda () - (make-variable-buffer-local 'yas/trigger-key) - (setq yas/trigger-key [tab]) - (add-to-list 'org-tab-first-hook 'yas/org-very-safe-expand) - (define-key yas/keymap [tab] 'yas/next-field))) -@end lisp -@end table - -@node TTY Keys -@section Using Org on a TTY - -@cindex tty key bindings - -Org provides alternative key bindings for TTY and modern mobile -devices that cannot perform movement commands on point and key -bindings with modifier keys. Some of these workarounds may be more -cumbersome than necessary. Users should look into customizing these -further based on their usage needs. For example, the normal -@kbd{S-} for editing timestamp might be better with -@kbd{C-c .} chord. - -@multitable @columnfractions 0.2 0.28 0.15 0.21 -@headitem Default -@tab Alternative 1 -@tab Speed key -@tab Alternative 2 -@item @kbd{S-@key{TAB}} -@tab @kbd{C-u @key{TAB}} -@tab @kbd{C} -@tab -@item @kbd{M-@key{LEFT}} -@tab @kbd{C-c C-x l} -@tab @kbd{l} -@tab @kbd{Esc @key{LEFT}} -@item @kbd{M-S-@key{LEFT}} -@tab @kbd{C-c C-x L} -@tab @kbd{L} -@tab -@item @kbd{M-@key{RIGHT}} -@tab @kbd{C-c C-x r} -@tab @kbd{r} -@tab @kbd{Esc @key{RIGHT}} -@item @kbd{M-S-@key{RIGHT}} -@tab @kbd{C-c C-x R} -@tab @kbd{R} -@tab -@item @kbd{M-@key{UP}} -@tab @kbd{C-c C-x u} -@tab -@tab @kbd{Esc @key{UP}} -@item @kbd{M-S-@key{UP}} -@tab @kbd{C-c C-x U} -@tab @kbd{U} -@tab -@item @kbd{M-@key{DOWN}} -@tab @kbd{C-c C-x d} -@tab -@tab @kbd{Esc @key{DOWN}} -@item @kbd{M-S-@key{DOWN}} -@tab @kbd{C-c C-x D} -@tab @kbd{D} -@tab -@item @kbd{S-@key{RET}} -@tab @kbd{C-c C-x c} -@tab -@tab -@item @kbd{M-@key{RET}} -@tab @kbd{C-c C-x m} -@tab -@tab @kbd{Esc @key{RET}} -@item @kbd{M-S-@key{RET}} -@tab @kbd{C-c C-x M} -@tab -@tab -@item @kbd{S-@key{LEFT}} -@tab @kbd{C-c @key{LEFT}} -@tab -@tab -@item @kbd{S-@key{RIGHT}} -@tab @kbd{C-c @key{RIGHT}} -@tab -@tab -@item @kbd{S-@key{UP}} -@tab @kbd{C-c @key{UP}} -@tab -@tab -@item @kbd{S-@key{DOWN}} -@tab @kbd{C-c @key{DOWN}} -@tab -@tab -@item @kbd{C-S-@key{LEFT}} -@tab @kbd{C-c C-x @key{LEFT}} -@tab -@tab -@item @kbd{C-S-@key{RIGHT}} -@tab @kbd{C-c C-x @key{RIGHT}} -@tab -@tab -@end multitable - -@node Protocols -@section Protocols for External Access - -@cindex protocols, for external access - -Org protocol is a tool to trigger custom actions in Emacs from -external applications. Any application that supports calling external -programs with an URL as argument may be used with this functionality. -For example, you can configure bookmarks in your web browser to send a -link to the current page to Org and create a note from it using -capture (see @ref{Capture}). You can also create a bookmark that tells -Emacs to open the local source file of a remote website you are -browsing. - -@cindex Org protocol, set-up -@cindex Installing Org protocol -In order to use Org protocol from an application, you need to register -@samp{org-protocol://} as a valid scheme-handler. External calls are -passed to Emacs through the @samp{emacsclient} command, so you also need to -ensure an Emacs server is running. More precisely, when the -application calls - -@example -emacsclient org-protocol://PROTOCOL?key1=val1&key2=val2 -@end example - - -@noindent -Emacs calls the handler associated to @var{PROTOCOL} with -argument @samp{(:key1 val1 :key2 val2)}. - -@cindex protocol, new protocol -@cindex defining new protocols -Org protocol comes with three predefined protocols, detailed in the -following sections. Configure @code{org-protocol-protocol-alist} to define -your own. - -@menu -* The @code{store-link} protocol:: Store a link, push URL to kill-ring. -* The @code{capture} protocol:: Fill a buffer with external information. -* The @code{open-source} protocol:: Edit published contents. -@end menu - -@node The @code{store-link} protocol -@subsection The @code{store-link} protocol - -@cindex store-link protocol -@cindex protocol, store-link - -Using the @code{store-link} handler, you can copy links, to that they can -be inserted using @kbd{M-x org-insert-link} or yanking. More -precisely, the command - -@example -emacsclient org-protocol://store-link?url=URL&title=TITLE -@end example - - -@noindent -stores the following link: - -@example -[[URL][TITLE]] -@end example - - -In addition, @var{URL} is pushed on the kill-ring for yanking. -You need to encode @var{URL} and @var{TITLE} if they contain -slashes, and probably quote those for the shell. - -To use this feature from a browser, add a bookmark with an arbitrary -name, e.g., @samp{Org: store-link} and enter this as @emph{Location}: - -@example -javascript:location.href='org-protocol://store-link?url='+ - encodeURIComponent(location.href); -@end example - -@node The @code{capture} protocol -@subsection The @code{capture} protocol - -@cindex capture protocol -@cindex protocol, capture - -Activating the ``capture'' handler pops up a @samp{Capture} buffer in Emacs, -using acapture template. - -@example -emacsclient org-protocol://capture?template=X?url=URL?title=TITLE?body=BODY -@end example - - -To use this feature, add a bookmark with an arbitrary name, e.g., -@samp{Org: capture}, and enter this as @samp{Location}: - -@example -javascript:location.href='org-protocol://capture?template=x'+ - '&url='+encodeURIComponent(window.location.href)+ - '&title='+encodeURIComponent(document.title)+ - '&body='+encodeURIComponent(window.getSelection()); -@end example - -@vindex org-protocol-default-template-key -The capture template to be used can be specified in the bookmark (like -@samp{X} above). If unspecified, the template key is set in the variable -@code{org-protocol-default-template-key}. The following template -placeholders are available: - -@example -%:link The URL -%:description The webpage title -%:annotation Equivalent to [[%:link][%:description]] -%i The selected text -@end example - -@node The @code{open-source} protocol -@subsection The @code{open-source} protocol - -@cindex open-source protocol -@cindex protocol, open-source - -The @code{open-source} handler is designed to help with editing local -sources when reading a document. To that effect, you can use -a bookmark with the following location: - -@example -javascript:location.href='org-protocol://open-source?&url='+ - encodeURIComponent(location.href) -@end example - -@vindex org-protocol-project-alist -The variable @code{org-protocol-project-alist} maps URLs to local file -names, by stripping URL parameters from the end and replacing the -@code{:base-url} with @code{:working-directory} and @code{:online-suffix} with -@code{:working-suffix}. For example, assuming you own a local copy of -@samp{https://orgmode.org/worg/} contents at @samp{/home/user/worg}, you can set -@code{org-protocol-project-alist} to the following - -@lisp -(setq org-protocol-project-alist - '(("Worg" - :base-url "https://orgmode.org/worg/" - :working-directory "/home/user/worg/" - :online-suffix ".html" - :working-suffix ".org"))) -@end lisp - -@noindent -If you are now browsing -@samp{https://orgmode.org/worg/org-contrib/org-protocol.html} and find -a typo or have an idea about how to enhance the documentation, simply -click the bookmark and start editing. - -@cindex rewritten URL in open-source protocol -@cindex protocol, open-source rewritten URL -However, such mapping may not always yield the desired results. -Suppose you maintain an online store located at @samp{http://example.com/}. -The local sources reside in @samp{/home/user/example/}. It is common -practice to serve all products in such a store through one file and -rewrite URLs that do not match an existing file on the server. That -way, a request to @samp{http://example.com/print/posters.html} might be -rewritten on the server to something like -@samp{http://example.com/shop/products.php/posters.html.php}. The -@code{open-source} handler probably cannot find a file named -@samp{/home/user/example/print/posters.html.php} and fails. - -Such an entry in @code{org-protocol-project-alist} may hold an additional -property @code{:rewrites}. This property is a list of cons cells, each of -which maps a regular expression to a path relative to the -@code{:working-directory}. - -Now map the URL to the path @samp{/home/user/example/products.php} by -adding @code{:rewrites} rules like this: - -@lisp -(setq org-protocol-project-alist - '(("example.com" - :base-url "http://example.com/" - :working-directory "/home/user/example/" - :online-suffix ".php" - :working-suffix ".php" - :rewrites (("example.com/print/" . "products.php") - ("example.com/$" . "index.php"))))) -@end lisp - -@noindent -Since @samp{example.com/$} is used as a regular expression, it maps -@samp{http://example.com/}, @samp{https://example.com}, -@samp{http://www.example.com/} and similar to -@samp{/home/user/example/index.php}. - -The @code{:rewrites} rules are searched as a last resort if and only if no -existing file name is matched. - -@cindex protocol, open-source, set-up mapping -@cindex mappings in open-source protocol -@findex org-protocol-create -@findex org-protocol-create-for-org -Two functions can help you filling @code{org-protocol-project-alist} with -valid contents: @code{org-protocol-create} and -@code{org-protocol-create-for-org}. The latter is of use if you're editing -an Org file that is part of a publishing project. - -@node Org Crypt -@section Org Crypt - -Org Crypt encrypts the text of an entry, but not the headline, or -properties. Behind the scene, it uses the Emacs EasyPG library to -encrypt and decrypt files. - -@vindex org-crypt-tag-matcher -Any text below a headline that has a @samp{crypt} tag is automatically -encrypted when the file is saved. To use a different tag, customize -the @code{org-crypt-tag-matcher} setting. - -Here is a suggestion for Org Crypt settings in Emacs init file: - -@lisp -(require 'org-crypt) -(org-crypt-use-before-save-magic) -(setq org-tags-exclude-from-inheritance '("crypt")) - -(setq org-crypt-key nil) -;; GPG key to use for encryption -;; Either the Key ID or set to nil to use symmetric encryption. - -(setq auto-save-default nil) -;; Auto-saving does not cooperate with org-crypt.el: so you need to -;; turn it off if you plan to use org-crypt.el quite often. Otherwise, -;; you'll get an (annoying) message each time you start Org. - -;; To turn it off only locally, you can insert this: -;; -;; # -*- buffer-auto-save-file-name: nil; -*- -@end lisp - -It's possible to use different keys for different headings by -specifying the respective key as property @samp{CRYPTKEY}, e.g.: - -@example -* Totally secret :crypt: - :PROPERTIES: - :CRYPTKEY: 0x0123456789012345678901234567890123456789 - :END: -@end example - -Excluding the @samp{crypt} tag from inheritance prevents already encrypted -text from being encrypted again. - -@node Org Mobile -@section Org Mobile - -@cindex smartphone - -Org Mobile is a protocol for synchronizing Org files between Emacs and -other applications, e.g., on mobile devices. It enables offline-views -and capture support for an Org mode system that is rooted on a ``real'' -computer. The external application can also record changes to -existing entries. - -This appendix describes Org's support for agenda view formats -compatible with Org Mobile. It also describes synchronizing changes, -such as to notes, between the mobile application and the computer. - -To change tags and TODO states in the mobile application, first -customize the variables @code{org-todo-keywords}, @code{org-tag-alist} and -@code{org-tag-persistent-alist}. These should cover all the important tags -and TODO keywords, even if Org files use only some of them. Though -the mobile application is expected to support in-buffer settings, it -is required to understand TODO states @emph{sets} (see @ref{Per-file keywords}) and @emph{mutually exclusive} tags (see @ref{Setting Tags}) only for those set in these variables. - -@menu -* Setting up the staging area:: For the mobile device. -* Pushing to the mobile application:: Uploading Org files and agendas. -* Pulling from the mobile application:: Integrating captured and flagged items. -@end menu - -@node Setting up the staging area -@subsection Setting up the staging area - -@vindex org-mobile-directory -The mobile application needs access to a file directory on -a server@footnote{For a server to host files, consider using a WebDAV server, -such as @uref{https://nextcloud.com, Nextcloud}. Additional help is at this @uref{https://orgmode.org/worg/org-faq.html#mobileorg_webdav, FAQ entry}.} to interact with Emacs. Pass its location through -the @code{org-mobile-directory} variable. If you can mount that directory -locally just set the variable to point to that directory: - -@lisp -(setq org-mobile-directory "~/orgmobile/") -@end lisp - -Alternatively, by using TRAMP (see @ref{Top,TRAMP User Manual,,tramp,}), -@code{org-mobile-directory} may point to a remote directory accessible -through, for example, SSH, SCP, or DAVS: - -@lisp -(setq org-mobile-directory "/davs:user@@remote.host:/org/webdav/") -@end lisp - -@vindex org-mobile-encryption -With a public server, consider encrypting the files. Org also -requires OpenSSL installed on the local computer. To turn on -encryption, set the same password in the mobile application and in -Emacs. Set the password in the variable -@code{org-mobile-use-encryption}@footnote{If Emacs is configured for safe storing of passwords, then -configure the variable @code{org-mobile-encryption-password}; please read -the docstring of that variable.}. Note that even after the mobile -application encrypts the file contents, the file name remains visible -on the file systems of the local computer, the server, and the mobile -device. - -@node Pushing to the mobile application -@subsection Pushing to the mobile application - -@findex org-mobile-push -@vindex org-mobile-files -The command @code{org-mobile-push} copies files listed in -@code{org-mobile-files} into the staging area. Files include agenda files -(as listed in @code{org-agenda-files}). Customize @code{org-mobile-files} to -add other files. File names are staged with paths relative to -@code{org-directory}, so all files should be inside this directory@footnote{Symbolic links in @code{org-directory} need to have the same name -as their targets.}. - -Push creates a special Org file @samp{agendas.org} with custom agenda views -defined by the user@footnote{While creating the agendas, Org mode forces @samp{ID} properties -on all referenced entries, so that these entries can be uniquely -identified if Org Mobile flags them for further action. To avoid -setting properties configure the variable -@code{org-mobile-force-id-on-agenda-items} to @code{nil}. Org mode then relies -on outline paths, assuming they are unique.}. - -Finally, Org writes the file @samp{index.org}, containing links to other -files. The mobile application reads this file first from the server -to determine what other files to download for agendas. For faster -downloads, it is expected to only read files whose checksums@footnote{Checksums are stored automatically in the file -@samp{checksums.dat}.} -have changed. - -@node Pulling from the mobile application -@subsection Pulling from the mobile application - -@findex org-mobile-pull -The command @code{org-mobile-pull} synchronizes changes with the server. -More specifically, it first pulls the Org files for viewing. It then -appends captured entries and pointers to flagged or changed entries to -the file @samp{mobileorg.org} on the server. Org ultimately integrates its -data in an inbox file format, through the following steps: - -@enumerate -@item -@vindex org-mobile-inbox-for-pull -Org moves all entries found in @samp{mobileorg.org}@footnote{The file will be empty after this operation.} and appends -them to the file pointed to by the variable -@code{org-mobile-inbox-for-pull}. It should reside neither in the -staging area nor on the server. Each captured entry and each -editing event is a top-level entry in the inbox file. - -@item -@cindex @samp{FLAGGED}, tag -After moving the entries, Org processes changes to the shared -files. Some of them are applied directly and without user -interaction. Examples include changes to tags, TODO state, -headline and body text. Entries requiring further action are -tagged as @samp{FLAGGED}. Org marks entries with problems with an error -message in the inbox. They have to be resolved manually. - -@item -Org generates an agenda view for flagged entries for user -intervention to clean up. For notes stored in flagged entries, Org -displays them in the echo area when point is on the corresponding -agenda item. - -@table @asis -@item @kbd{?} -Pressing @kbd{?} displays the entire flagged note in another -window. Org also pushes it to the kill ring. To store flagged -note as a normal note, use @kbd{? z C-y C-c C-c}. Pressing -@kbd{?} twice does these things: first it removes the -@samp{FLAGGED} tag; second, it removes the flagged note from the -property drawer; third, it signals that manual editing of the -flagged entry is now finished. -@end table -@end enumerate - -@kindex ? @r{(Agenda dispatcher)} -From the agenda dispatcher, @kbd{?} returns to the view to finish -processing flagged entries. Note that these entries may not be the -most recent since the mobile application searches files that were last -pulled. To get an updated agenda view with changes since the last -pull, pull again. - -@node Hacking -@appendix Hacking - -@cindex hacking - -This appendix describes some ways a user can extend the functionality -of Org. - -@menu -* Hooks: Hooks (2). How to reach into Org's internals. -* Add-on Packages:: Available extensions. -* Adding Hyperlink Types:: New custom link types. -* Adding Export Back-ends:: How to write new export back-ends. -* Tables in Arbitrary Syntax:: Orgtbl for LaTeX and other programs. -* Dynamic Blocks:: Automatically filled blocks. -* Special Agenda Views:: Customized views. -* Speeding Up Your Agendas:: Tips on how to speed up your agendas. -* Extracting Agenda Information:: Post-processing agenda information. -* Using the Property API:: Writing programs that use entry properties. -* Using the Mapping API:: Mapping over all or selected entries. -@end menu - -@node Hooks (2) -@appendixsec Hooks - -@cindex hooks - -Org has a large number of hook variables for adding functionality. -This appendix illustrates using a few. A complete list of hooks with -documentation is maintained by the Worg project at -@uref{https://orgmode.org/worg/doc.html#hooks}. - -@node Add-on Packages -@appendixsec Add-on Packages - -@cindex add-on packages - -Various authors wrote a large number of add-on packages for Org. - -These packages are not part of Emacs, but they are distributed as -contributed packages with the separate release available at -@uref{https://orgmode.org}. See the @samp{contrib/README} file in the source code -directory for a list of contributed files. Worg page with more -information is at: @uref{https://orgmode.org/worg/org-contrib/}. - -@node Adding Hyperlink Types -@appendixsec Adding Hyperlink Types - -@cindex hyperlinks, adding new types - -Org has many built-in hyperlink types (see @ref{Hyperlinks}), and an -interface for adding new link types. The following example shows the -process of adding Org links to Unix man pages, which look like this - -@example -[[man:printf][The printf manual]] -@end example - - -@noindent -The following @samp{ol-man.el} file implements it - -@lisp -;;; ol-man.el - Support for links to man pages in Org mode -(require 'ol) - -(org-link-set-parameters "man" - :follow #'org-man-open - :export #'org-man-export - :store #'org-man-store-link) - -(defcustom org-man-command 'man - "The Emacs command to be used to display a man page." - :group 'org-link - :type '(choice (const man) (const woman))) - -(defun org-man-open (path _) - "Visit the manpage on PATH. -PATH should be a topic that can be thrown at the man command." - (funcall org-man-command path)) - -(defun org-man-store-link () - "Store a link to a man page." - (when (memq major-mode '(Man-mode woman-mode)) - ;; This is a man page, we do make this link. - (let* ((page (org-man-get-page-name)) - (link (concat "man:" page)) - (description (format "Man page for %s" page))) - (org-link-store-props - :type "man" - :link link - :description description)))) - -(defun org-man-get-page-name () - "Extract the page name from the buffer name." - ;; This works for both `Man-mode' and `woman-mode'. - (if (string-match " \\(\\S-+\\)\\*" (buffer-name)) - (match-string 1 (buffer-name)) - (error "Cannot create link to this man page"))) - -(defun org-man-export (link description format _) - "Export a man page link from Org files." - (let ((path (format "http://man.he.net/?topic=%s§ion=all" link)) - (desc (or description link))) - (pcase format - (`html (format "%s" path desc)) - (`latex (format "\\href@{%s@}@{%s@}" path desc)) - (`texinfo (format "@@uref@{%s,%s@}" path desc)) - (`ascii (format "%s (%s)" desc path)) - (t path)))) - -(provide ol-man) -;;; ol-man.el ends here -@end lisp - -@noindent -To activate links to man pages in Org, enter this in the Emacs init -file: - -@lisp -(require 'ol-man) -@end lisp - -@noindent -A review of @samp{ol-man.el}: - -@enumerate -@item -First, @samp{(require 'ol)} ensures that @samp{ol.el} is loaded. - -@item -@findex org-link-set-parameters -@vindex org-link-parameters -Then @code{org-link-set-parameters} defines a new link type with @samp{man} -prefix and associates functions for following, exporting and -storing such links. See the variable @code{org-link-parameters} for -a complete list of possible associations. - -@item -The rest of the file implements necessary variables and functions. - -For example, @code{org-man-store-link} is responsible for storing a link -when @code{org-store-link} (see @ref{Handling Links}) is called from a buffer -displaying a man page. It first checks if the major mode is -appropriate. If check fails, the function returns @code{nil}, which -means it isn't responsible for creating a link to the current -buffer. Otherwise the function makes a link string by combining -the @samp{man:} prefix with the man topic. It also provides a default -description. The function @code{org-insert-link} can insert it back -into an Org buffer later on. -@end enumerate - -@node Adding Export Back-ends -@appendixsec Adding Export Back-ends - -@cindex Export, writing back-ends - -Org's export engine makes it easy for writing new back-ends. The -framework on which the engine was built makes it easy to derive new -back-ends from existing ones. - -@findex org-export-define-backend -@findex org-export-define-derived-backend -The two main entry points to the export engine are: -@code{org-export-define-backend} and @code{org-export-define-derived-backend}. -To grok these functions, see @samp{ox-latex.el} for an example of defining -a new back-end from scratch, and @samp{ox-beamer.el} for an example of -deriving from an existing engine. - -For creating a new back-end from scratch, first set its name as -a symbol in an alist consisting of elements and export functions. To -make the back-end visible to the export dispatcher, set @code{:menu-entry} -keyword. For export options specific to this back-end, set the -@code{:options-alist}. - -For creating a new back-end from an existing one, set -@code{:translate-alist} to an alist of export functions. This alist -replaces the parent back-end functions. - -For complete documentation, see @uref{https://orgmode.org/worg/dev/org-export-reference.html, the Org Export Reference on Worg}. - -@node Tables in Arbitrary Syntax -@appendixsec Tables in Arbitrary Syntax - -@cindex tables, in other modes -@cindex lists, in other modes -@cindex Orgtbl mode - -Due to Org's success in handling tables with Orgtbl, a frequently -requested feature is the use of Org's table functions in other modes, -e.g., @LaTeX{}. This would be hard to do in a general way without -complicated customization nightmares. Moreover, that would take Org -away from its simplicity roots that Orgtbl has proven. There is, -however, an alternate approach to accomplishing the same. - -This approach involves implementing a custom @emph{translate} function that -operates on a native Org @emph{source table} to produce a table in another -format. This strategy would keep the excellently working Orgtbl -simple and isolate complications, if any, confined to the translate -function. To add more alien table formats, we just add more translate -functions. Also the burden of developing custom translate functions -for new table formats is in the hands of those who know those formats -best. - -@menu -* Radio tables:: Sending and receiving radio tables. -* A @LaTeX{} example:: Step by step, almost a tutorial. -* Translator functions:: Copy and modify. -@end menu - -@node Radio tables -@appendixsubsec Radio tables - -@cindex radio tables - -Radio tables are target locations for translated tables that are not near -their source. Org finds the target location and inserts the translated -table. - -The key to finding the target location is the magic words @samp{BEGIN/END -RECEIVE ORGTBL}. They have to appear as comments in the current mode. -If the mode is C, then: - -@example -/* BEGIN RECEIVE ORGTBL table_name */ -/* END RECEIVE ORGTBL table_name */ -@end example - -At the location of source, Org needs a special line to direct Orgtbl -to translate and to find the target for inserting the translated -table. For example: - -@cindex @samp{ORGTBL}, keyword -@example -#+ORGTBL: SEND table_name translation_function arguments ... -@end example - - -@noindent -@samp{table_name} is the table's reference name, which is also used in the -receiver lines, and the @samp{translation_function} is the Lisp function -that translates. This line, in addition, may also contain alternating -key and value arguments at the end. The translation function gets -these values as a property list. A few standard parameters are -already recognized and acted upon before the translation function is -called: - -@table @asis -@item @samp{:skip N} -Skip the first N lines of the table. Hlines do count; include them -if they are to be skipped. - -@item @samp{:skipcols (n1 n2 ...)} -List of columns to be skipped. First Org automatically discards -columns with calculation marks and then sends the table to the -translator function, which then skips columns as specified in -@samp{skipcols}. -@end table - -To keep the source table intact in the buffer without being disturbed -when the source file is compiled or otherwise being worked on, use one -of these strategies: - -@itemize -@item -Place the table in a block comment. For example, in C mode you -could wrap the table between @samp{/*} and @samp{*/} lines. - -@item -Put the table after an ``end'' statement. For example @code{\bye} in @TeX{} -and @code{\end@{document@}} in @LaTeX{}. - -@item -Comment and un-comment each line of the table during edits. The -@kbd{M-x orgtbl-toggle-comment} command makes toggling easy. -@end itemize - -@node A @LaTeX{} example -@appendixsubsec A @LaTeX{} example of radio tables - -@cindex @LaTeX{}, and Orgtbl mode - -To wrap a source table in @LaTeX{}, use the @samp{comment} environment -provided by @samp{comment.sty}@footnote{@uref{https://www.ctan.org/pkg/comment}}. To activate it, put -@code{\usepackage@{comment@}} in the document header. Orgtbl mode inserts -a radio table skeleton@footnote{By default this works only for @LaTeX{}, HTML, and Texinfo. -Configure the variable @code{orgtbl-radio-table-templates} to install -templates for other modes.} with the command @kbd{M-x orgtbl-insert-radio-table}, which prompts for a table name. For -example, if @samp{salesfigures} is the name, the template inserts: - -@example -% BEGIN RECEIVE ORGTBL salesfigures -% END RECEIVE ORGTBL salesfigures -\begin@{comment@} -#+ORGTBL: SEND salesfigures orgtbl-to-latex -| | | -\end@{comment@} -@end example - -@vindex LaTeX-verbatim-environments -@noindent -The line @samp{#+ORGTBL: SEND} tells Orgtbl mode to use the function -@code{orgtbl-to-latex} to convert the table to @LaTeX{} format, then insert -the table at the target (receive) location named @samp{salesfigures}. Now -the table is ready for data entry. It can even use spreadsheet -features@footnote{If the @samp{TBLFM} keyword contains an odd number of dollar -characters, this may cause problems with Font Lock in @LaTeX{} mode. As -shown in the example you can fix this by adding an extra line inside -the @samp{comment} environment that is used to balance the dollar -expressions. If you are using AUC@TeX{} with the font-latex library, -a much better solution is to add the @samp{comment} environment to the -variable @code{LaTeX-verbatim-environments}.}: - -@example -% BEGIN RECEIVE ORGTBL salesfigures -% END RECEIVE ORGTBL salesfigures -\begin@{comment@} -#+ORGTBL: SEND salesfigures orgtbl-to-latex -| Month | Days | Nr sold | per day | -|-------+------+---------+---------| -| Jan | 23 | 55 | 2.4 | -| Feb | 21 | 16 | 0.8 | -| March | 22 | 278 | 12.6 | -#+TBLFM: $4=$3/$2;%.1f -% $ (optional extra dollar to keep Font Lock happy, see footnote) -\end@{comment@} -@end example - -After editing, @kbd{C-c C-c} inserts the translated table at the -target location, between the two marker lines. - -For hand-made custom tables, note that the translator needs to skip -the first two lines of the source table. Also the command has to -@emph{splice} out the target table without the header and footer. - -@example -\begin@{tabular@}@{lrrr@} -Month & \multicolumn@{1@}@{c@}@{Days@} & Nr.\ sold & per day\\ -% BEGIN RECEIVE ORGTBL salesfigures -% END RECEIVE ORGTBL salesfigures -\end@{tabular@} -% -\begin@{comment@} -#+ORGTBL: SEND salesfigures orgtbl-to-latex :splice t :skip 2 -| Month | Days | Nr sold | per day | -|-------+------+---------+---------| -| Jan | 23 | 55 | 2.4 | -| Feb | 21 | 16 | 0.8 | -| March | 22 | 278 | 12.6 | -#+TBLFM: $4=$3/$2;%.1f -\end@{comment@} -@end example - -The @LaTeX{} translator function @code{orgtbl-to-latex} is already part of -Orgtbl mode and uses a @samp{tabular} environment to typeset the table and -marks horizontal lines with @code{\hline}. For additional parameters to -control output, see @ref{Translator functions}: - -@table @asis -@item @samp{:splice BOOLEAN} -When @{@{@{var(BOOLEAN@}@}@} is non-@code{nil}, return only table body lines; -i.e., not wrapped in @samp{tabular} environment. Default is @code{nil}. - -@item @samp{:fmt FMT} -Format string to warp each field. It should contain @samp{%s} for the -original field value. For example, to wrap each field value in -dollar symbol, you could use @samp{:fmt "$%s$"}. Format can also wrap -a property list with column numbers and formats, for example @samp{:fmt - (2 "$%s$" 4 "%s\\%%")}. In place of a string, a function of one -argument can be used; the function must return a formatted string. - -@item @samp{:efmt EFMT} -Format numbers as exponentials. The spec should have @samp{%s} twice for -inserting mantissa and exponent, for example @samp{"%s\\times10^@{%s@}"}. This -may also be a property list with column numbers and formats, for -example @samp{:efmt (2 "$%s\\times10^@{%s@}$" 4 "$%s\\cdot10^@{%s@}$")}. After -@var{EFMT} has been applied to a value, @var{FMT}---see -above---is also applied. Functions with two arguments can be -supplied instead of strings. By default, no special formatting is -applied. -@end table - -@node Translator functions -@appendixsubsec Translator functions - -@cindex HTML, and Orgtbl mode -@cindex translator function - -@findex orgtbl-to-csv -@findex orgtbl-to-tsv -@findex orgtbl-to-latex -@findex orgtbl-to-html -@findex orgtbl-to-texinfo -@findex orgtbl-to-unicode -@findex orgtbl-to-orgtbl -@findex orgtbl-to-generic -Orgtbl mode has built-in translator functions: @code{orgtbl-to-csv} -(comma-separated values), @code{orgtbl-to-tsv} (TAB-separated values), -@code{orgtbl-to-latex}, @code{orgtbl-to-html}, @code{orgtbl-to-texinfo}, -@code{orgtbl-to-unicode} and @code{orgtbl-to-orgtbl}. They use the generic -translator, @code{orgtbl-to-generic}, which delegates translations to -various export back-ends. - -Properties passed to the function through the @samp{ORGTBL SEND} line take -precedence over properties defined inside the function. For example, -this overrides the default @LaTeX{} line endings, @code{\\}, with @code{\\[2mm]}: - -@example -#+ORGTBL: SEND test orgtbl-to-latex :lend " \\\\[2mm]" -@end example - - -For a new language translator, define a converter function. It can be -a generic function, such as shown in this example. It marks -a beginning and ending of a table with @samp{!BTBL!} and @samp{!ETBL!}; -a beginning and ending of lines with @samp{!BL!} and @samp{!EL!}; and uses a TAB -for a field separator: - -@lisp -(defun orgtbl-to-language (table params) - "Convert the orgtbl-mode TABLE to language." - (orgtbl-to-generic - table - (org-combine-plists - '(:tstart "!BTBL!" :tend "!ETBL!" :lstart "!BL!" :lend "!EL!" :sep "\t") - params))) -@end lisp - -@noindent -The documentation for the @code{orgtbl-to-generic} function shows -a complete list of parameters, each of which can be passed through to -@code{orgtbl-to-latex}, @code{orgtbl-to-texinfo}, and any other function using -that generic function. - -For complicated translations the generic translator function could be -replaced by a custom translator function. Such a custom function must -take two arguments and return a single string containing the formatted -table. The first argument is the table whose lines are a list of -fields or the symbol @code{hline}. The second argument is the property -list consisting of parameters specified in the @samp{#+ORGTBL: SEND} line. -Please share your translator functions by posting them to the Org -users mailing list, at @email{emacs-orgmode@@gnu.org}. - -@node Dynamic Blocks -@appendixsec Dynamic Blocks - -@cindex dynamic blocks - -Org supports @emph{dynamic blocks} in Org documents. They are inserted -with begin and end markers like any other code block, but the contents -are updated automatically by a user function. - -@kindex C-c C-x x -@findex org-dynamic-block-insert-dblock -You can insert a dynamic block with @code{org-dynamic-block-insert-dblock}, -which is bound to @kbd{C-c C-x x} by default. For example, -@kbd{C-c C-x x c l o c k t a b l e @key{RET}} inserts a table that -updates the work time (see @ref{Clocking Work Time}). - -Dynamic blocks can have names and function parameters. The syntax is -similar to source code block specifications: - -@example -#+BEGIN: myblock :parameter1 value1 :parameter2 value2 ... - ... -#+END: -@end example - -These commands update dynamic blocks: - -@table @asis -@item @kbd{C-c C-x C-u} (@code{org-dblock-update}) -@kindex C-c C-x C-u -@findex org-dblock-update -Update dynamic block at point. - -@item @kbd{C-u C-c C-x C-u} -@kindex C-u C-c C-x C-u -Update all dynamic blocks in the current file. -@end table - -Before updating a dynamic block, Org removes content between the -@samp{BEGIN} and @samp{END} markers. Org then reads the parameters on the -@samp{BEGIN} line for passing to the writer function as a plist. The -previous content of the dynamic block becomes erased from the buffer -and appended to the plist under @code{:content}. - -The syntax for naming a writer function with a dynamic block labeled -@samp{myblock} is: @code{org-dblock-write:myblock}. - -The following is an example of a dynamic block and a block writer function -that updates the time when the function was last run: - -@example -#+BEGIN: block-update-time :format "on %m/%d/%Y at %H:%M" - ... -#+END: -@end example - -@noindent -The dynamic block's writer function: - -@lisp -(defun org-dblock-write:block-update-time (params) - (let ((fmt (or (plist-get params :format) "%d. %m. %Y"))) - (insert "Last block update at: " - (format-time-string fmt)))) -@end lisp - -To keep dynamic blocks up-to-date in an Org file, use the function, -@code{org-update-all-dblocks} in hook, such as @code{before-save-hook}. The -@code{org-update-all-dblocks} function does not run if the file is not in -Org mode. - -@findex org-narrow-to-block -Dynamic blocks, like any other block, can be narrowed with -@code{org-narrow-to-block}. - -@node Special Agenda Views -@appendixsec Special Agenda Views - -@cindex agenda views, user-defined - -@vindex org-agenda-skip-function -@vindex org-agenda-skip-function-global -Org provides a special hook to further limit items in agenda views: -@code{agenda}, @code{agenda*}@footnote{The @code{agenda*} view is the same as @code{agenda} except that it -only considers @emph{appointments}, i.e., scheduled and deadline items that -have a time specification @samp{[h]h:mm} in their time-stamps.}, @code{todo}, @code{alltodo}, @code{tags}, @code{tags-todo}, -@code{tags-tree}. Specify a custom function that tests inclusion of every -matched item in the view. This function can also skip as much as is -needed. - -For a global condition applicable to agenda views, use the -@code{org-agenda-skip-function-global} variable. Org uses a global -condition with @code{org-agenda-skip-function} for custom searching. - -This example defines a function for a custom view showing TODO items -with @samp{waiting} status. Manually this is a multi-step search process, -but with a custom view, this can be automated as follows: - -The custom function searches the subtree for the @samp{waiting} tag and -returns @code{nil} on match. Otherwise it gives the location from where -the search continues. - -@lisp -(defun my-skip-unless-waiting () - "Skip trees that are not waiting" - (let ((subtree-end (save-excursion (org-end-of-subtree t)))) - (if (re-search-forward ":waiting:" subtree-end t) - nil ; tag found, do not skip - subtree-end))) ; tag not found, continue after end of subtree -@end lisp - -To use this custom function in a custom agenda command: - -@lisp -(org-add-agenda-custom-command - '("b" todo "PROJECT" - ((org-agenda-skip-function 'my-skip-unless-waiting) - (org-agenda-overriding-header "Projects waiting for something: ")))) -@end lisp - -@vindex org-agenda-overriding-header -Note that this also binds @code{org-agenda-overriding-header} to a more -meaningful string suitable for the agenda view. - -@vindex org-odd-levels-only -@vindex org-agenda-skip-function -Search for entries with a limit set on levels for the custom search. -This is a general approach to creating custom searches in Org. To -include all levels, use @samp{LEVEL>0}@footnote{Note that, for @code{org-odd-levels-only}, a level number -corresponds to order in the hierarchy, not to the number of stars.}. Then to selectively pick -the matched entries, use @code{org-agenda-skip-function}, which also -accepts Lisp forms, such as @code{org-agenda-skip-entry-if} and -@code{org-agenda-skip-subtree-if}. For example: - -@table @asis -@item @samp{(org-agenda-skip-entry-if 'scheduled)} -Skip current entry if it has been scheduled. - -@item @samp{(org-agenda-skip-entry-if 'notscheduled)} -Skip current entry if it has not been scheduled. - -@item @samp{(org-agenda-skip-entry-if 'deadline)} -Skip current entry if it has a deadline. - -@item @samp{(org-agenda-skip-entry-if 'scheduled 'deadline)} -Skip current entry if it has a deadline, or if it is scheduled. - -@item @samp{(org-agenda-skip-entry-if 'todo '("TODO" "WAITING"))} -Skip current entry if the TODO keyword is TODO or WAITING@. - -@item @samp{(org-agenda-skip-entry-if 'todo 'done)} -Skip current entry if the TODO keyword marks a DONE state. - -@item @samp{(org-agenda-skip-entry-if 'timestamp)} -Skip current entry if it has any timestamp, may also be deadline or -scheduled. - -@item @samp{(org-agenda-skip-entry-if 'regexp "regular expression")} -Skip current entry if the regular expression matches in the entry. - -@item @samp{(org-agenda-skip-entry-if 'notregexp "regular expression")} -Skip current entry unless the regular expression matches. - -@item @samp{(org-agenda-skip-subtree-if 'regexp "regular expression")} -Same as above, but check and skip the entire subtree. -@end table - -The following is an example of a search for @samp{waiting} without the -special function: - -@lisp -(org-add-agenda-custom-command - '("b" todo "PROJECT" - ((org-agenda-skip-function '(org-agenda-skip-subtree-if - 'regexp ":waiting:")) - (org-agenda-overriding-header "Projects waiting for something: ")))) -@end lisp - -@node Speeding Up Your Agendas -@appendixsec Speeding Up Your Agendas - -@cindex agenda views, optimization - -Some agenda commands slow down when the Org files grow in size or -number. Here are tips to speed up: - -@itemize -@item -Reduce the number of Org agenda files to avoid slowdowns due to hard drive -accesses. - -@item -Reduce the number of DONE and archived headlines so agenda -operations that skip over these can finish faster. - -@item -Do not dim blocked tasks: -@vindex org-agenda-dim-blocked-tasks - -@lisp -(setq org-agenda-dim-blocked-tasks nil) -@end lisp - -@item -Stop preparing agenda buffers on startup: -@vindex org-startup-folded -@vindex org-agenda-inhibit-startup - -@lisp -(setq org-agenda-inhibit-startup t) -@end lisp - -@item -Disable tag inheritance for agendas: -@vindex org-agenda-show-inherited-tags -@vindex org-agenda-use-tag-inheritance - -@lisp -(setq org-agenda-use-tag-inheritance nil) -@end lisp -@end itemize - -These options can be applied to selected agenda views. For more -details about generation of agenda views, see the docstrings for the -relevant variables, and this @uref{https://orgmode.org/worg/agenda-optimization.html, dedicated Worg page} for agenda -optimization. - -@node Extracting Agenda Information -@appendixsec Extracting Agenda Information - -@cindex agenda, pipe -@cindex scripts, for agenda processing - -Org provides commands to access agendas through Emacs batch mode. -Through this command-line interface, agendas are automated for further -processing or printing. - -@vindex org-agenda-custom-commands -@findex org-batch-agenda -@code{org-batch-agenda} creates an agenda view in ASCII and outputs to -standard output. This command takes one string parameter. When -string consists of a single character, Org uses it as a key to -@code{org-agenda-custom-commands}. These are the same ones available -through the agenda dispatcher (see @ref{Agenda Dispatcher}). - -This example command line directly prints the TODO list to the printer: - -@example -emacs -batch -l ~/.emacs -eval '(org-batch-agenda "t")' | lpr -@end example - - -When the string parameter length is two or more characters, Org -matches it with tags/TODO strings. For example, this example command -line prints items tagged with @samp{shop}, but excludes items tagged with -@samp{NewYork}: - -@example -emacs -batch -l ~/.emacs \ - -eval '(org-batch-agenda "+shop-NewYork")' | lpr -@end example - -@noindent -An example showing on-the-fly parameter modifications: - -@example -emacs -batch -l ~/.emacs \ - -eval '(org-batch-agenda "a" \ - org-agenda-span (quote month) \ - org-agenda-include-diary nil \ - org-agenda-files (quote ("~/org/project.org")))' \ - | lpr -@end example - -@noindent -which produces an agenda for the next 30 days from just the -@samp{~/org/projects.org} file. - -@findex org-batch-agenda-csv -For structured processing of agenda output, use @code{org-batch-agenda-csv} -with the following fields: - -@table @asis -@item category -The category of the item -@item head -The headline, without TODO keyword, TAGS and PRIORITY -@item type -The type of the agenda entry, can be - -@multitable {aaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} -@item @code{todo} -@tab selected in TODO match -@item @code{tagsmatch} -@tab selected in tags match -@item @code{diary} -@tab imported from diary -@item @code{deadline} -@tab a deadline -@item @code{scheduled} -@tab scheduled -@item @code{timestamp} -@tab appointment, selected by timestamp -@item @code{closed} -@tab entry was closed on date -@item @code{upcoming-deadline} -@tab warning about nearing deadline -@item @code{past-scheduled} -@tab forwarded scheduled item -@item @code{block} -@tab entry has date block including date -@end multitable - -@item todo -The TODO keyword, if any -@item tags -All tags including inherited ones, separated by colons -@item date -The relevant date, like @samp{2007-2-14} -@item time -The time, like @samp{15:00-16:50} -@item extra -String with extra planning info -@item priority-l -The priority letter if any was given -@item priority-n -The computed numerical priority -@end table - -If the selection of the agenda item was based on a timestamp, -including those items with @samp{DEADLINE} and @samp{SCHEDULED} keywords, then -Org includes date and time in the output. - -If the selection of the agenda item was based on a timestamp (or -deadline/scheduled), then Org includes date and time in the output. - -Here is an example of a post-processing script in Perl. It takes the -CSV output from Emacs and prints with a checkbox: - -@example -#!/usr/bin/perl - -# define the Emacs command to run -$cmd = "emacs -batch -l ~/.emacs -eval '(org-batch-agenda-csv \"t\")'"; - -# run it and capture the output -$agenda = qx@{$cmd 2>/dev/null@}; - -# loop over all lines -foreach $line (split(/\n/,$agenda)) @{ - # get the individual values - ($category,$head,$type,$todo,$tags,$date,$time,$extra, - $priority_l,$priority_n) = split(/,/,$line); - # process and print - print "[ ] $head\n"; -@} -@end example - -@node Using the Property API -@appendixsec Using the Property API - -@cindex API, for properties -@cindex properties, API - -Here is a description of the functions that can be used to work with -properties. - -@defun org-entry-properties &optional pom which -Get all properties of the entry at point-or-marker @var{POM}. -This includes the TODO keyword, the tags, time strings for deadline, -scheduled, and clocking, and any additional properties defined in the -entry. The return value is an alist. Keys may occur multiple times -if the property key was used several times. @var{POM} may also -be @code{nil}, in which case the current entry is used. If -@var{WHICH} is @code{nil} or @code{all}, get all properties. If -@var{WHICH} is @code{special} or @code{standard}, only get that subclass. -@end defun - -@vindex org-use-property-inheritance -@findex org-insert-property-drawer -@defun org-entry-get pom property &optional inherit -Get value of @var{PROPERTY} for entry at point-or-marker -@var{POM}. By default, this only looks at properties defined -locally in the entry. If @var{INHERIT} is non-@code{nil} and the -entry does not have the property, then also check higher levels of the -hierarchy. If @var{INHERIT} is the symbol @code{selective}, use -inheritance if and only if the setting of -@code{org-use-property-inheritance} selects @var{PROPERTY} for -inheritance. -@end defun - -@defun org-entry-delete pom property -Delete the property @var{PROPERTY} from entry at point-or-marker -@var{POM}. -@end defun - -@defun org-entry-put pom property value -Set @var{PROPERTY} to @var{VALUES} for entry at -point-or-marker POM@. -@end defun - -@defun org-buffer-property-keys &optional include-specials -Get all property keys in the current buffer. -@end defun - -@defun org-insert-property-drawer -Insert a property drawer for the current entry. Also -@end defun - -@defun org-entry-put-multivalued-property pom property &rest values -Set @var{PROPERTY} at point-or-marker @var{POM} to -@var{VALUES}. @var{VALUES} should be a list of strings. -They are concatenated, with spaces as separators. -@end defun - -@defun org-entry-get-multivalued-property pom property -Treat the value of the property @var{PROPERTY} as -a whitespace-separated list of values and return the values as a list -of strings. -@end defun - -@defun org-entry-add-to-multivalued-property pom property value -Treat the value of the property @var{PROPERTY} as -a whitespace-separated list of values and make sure that -@var{VALUE} is in this list. -@end defun - -@defun org-entry-remove-from-multivalued-property pom property value -Treat the value of the property @var{PROPERTY} as -a whitespace-separated list of values and make sure that -@var{VALUE} is @emph{not} in this list. -@end defun - -@defun org-entry-member-in-multivalued-property pom property value -Treat the value of the property @var{PROPERTY} as -a whitespace-separated list of values and check if @var{VALUE} is -in this list. -@end defun - -@defopt org-property-allowed-value-functions -Hook for functions supplying allowed values for a specific property. -The functions must take a single argument, the name of the property, -and return a flat list of allowed values. If @samp{:ETC} is one of the -values, use the values as completion help, but allow also other values -to be entered. The functions must return @code{nil} if they are not -responsible for this property. -@end defopt - -@node Using the Mapping API -@appendixsec Using the Mapping API - -@cindex API, for mapping -@cindex mapping entries, API - -Org has sophisticated mapping capabilities to find all entries -satisfying certain criteria. Internally, this functionality is used -to produce agenda views, but there is also an API that can be used to -execute arbitrary functions for each or selected entries. The main -entry point for this API is: - -@defun org-map-entries func &optional match scope &rest skip -Call @var{FUNC} at each headline selected by @var{MATCH} in -@var{SCOPE}. - -@var{FUNC} is a function or a Lisp form. With point positioned -at the beginning of the headline, call the function without arguments. -Org returns an alist of return values of calls to the function. - -To avoid preserving point, Org wraps the call to @var{FUNC} in -@code{save-excursion} form. After evaluation, Org moves point to the end -of the line that was just processed. Search continues from that point -forward. This may not always work as expected under some conditions, -such as if the current sub-tree was removed by a previous archiving -operation. In such rare circumstances, Org skips the next entry -entirely when it should not. To stop Org from such skips, make -@var{FUNC} set the variable @code{org-map-continue-from} to a specific -buffer position. - -@var{MATCH} is a tags/property/TODO match. Org iterates only -matched headlines. Org iterates over all headlines when -@var{MATCH} is @code{nil} or @code{t}. - -@var{SCOPE} determines the scope of this command. It can be any -of: - -@table @asis -@item @code{nil} -The current buffer, respecting the restriction, if any. - -@item @code{tree} -The subtree started with the entry at point. - -@item @code{region} -The entries within the active region, if any. - -@item @code{file} -The current buffer, without restriction. - -@item @code{file-with-archives} -The current buffer, and any archives associated with it. - -@item @code{agenda} -All agenda files. - -@item @code{agenda-with-archives} -All agenda files with any archive files associated with them. - -@item list of filenames -If this is a list, all files in the list are scanned. -@end table - -@noindent -The remaining arguments are treated as settings for the scanner's -skipping facilities. Valid arguments are: - -@table @asis -@item @code{archive} -Skip trees with the @samp{ARCHIVE} tag. - -@item @code{comment} -Skip trees with the COMMENT keyword. - -@item function or Lisp form -@vindex org-agenda-skip-function -Used as value for @code{org-agenda-skip-function}, so whenever the -function returns @code{t}, @var{FUNC} is called for that entry and -search continues from the point where the function leaves it. -@end table -@end defun - -The mapping routine can call any arbitrary function, even functions -that change meta data or query the property API (see @ref{Using the Property API}). Here are some handy functions: - -@defun org-todo &optional arg -Change the TODO state of the entry. See the docstring of the -functions for the many possible values for the argument -@var{ARG}. -@end defun - -@defun org-priority &optional action -Change the priority of the entry. See the docstring of this function -for the possible values for @var{ACTION}. -@end defun - -@defun org-toggle-tag tag &optional onoff -Toggle the tag @var{TAG} in the current entry. Setting -@var{ONOFF} to either @code{on} or @code{off} does not toggle tag, but -ensure that it is either on or off. -@end defun - -@defun org-promote -Promote the current entry. -@end defun - -@defun org-demote -Demote the current entry. -@end defun - -This example turns all entries tagged with @samp{TOMORROW} into TODO -entries with keyword @samp{UPCOMING}. Org ignores entries in comment trees -and archive trees. - -@lisp -(org-map-entries '(org-todo "UPCOMING") - "+TOMORROW" 'file 'archive 'comment) -@end lisp - -The following example counts the number of entries with TODO keyword -@samp{WAITING}, in all agenda files. - -@lisp -(length (org-map-entries t "/+WAITING" 'agenda)) -@end lisp - -@node History and Acknowledgments -@appendix History and Acknowledgments - - - -@anchor{From Carsten} -@appendixsec From Carsten - -Org was born in 2003, out of frustration over the user interface of -the Emacs Outline mode. I was trying to organize my notes and -projects, and using Emacs seemed to be the natural way to go. -However, having to remember eleven different commands with two or -three keys per command, only to hide and show parts of the outline -tree, that seemed entirely unacceptable to me. Also, when using -outlines to take notes, I constantly wanted to restructure the tree, -organizing it parallel to my thoughts and plans. @emph{Visibility cycling} -and @emph{structure editing} were originally implemented in the package -@samp{outline-magic.el}, but quickly moved to the more general @samp{org.el}. -As this environment became comfortable for project planning, the next -step was adding @emph{TODO entries}, basic @emph{timestamps}, and @emph{table -support}. These areas highlighted the two main goals that Org still -has today: to be a new, outline-based, plain text mode with innovative -and intuitive editing features, and to incorporate project planning -functionality directly into a notes file. - -Since the first release, literally thousands of emails to me or to the -@email{emacs-orgmode@@gnu.org, mailing list} have provided a constant stream of bug reports, feedback, -new ideas, and sometimes patches and add-on code. Many thanks to -everyone who has helped to improve this package. I am trying to keep -here a list of the people who had significant influence in shaping one -or more aspects of Org. The list may not be complete, if I have -forgotten someone, please accept my apologies and let me know. - -Before I get to this list, a few special mentions are in order: - -@table @asis -@item Bastien Guerry -Bastien has written a large number of extensions to Org (most of -them integrated into the core by now), including the @LaTeX{} exporter -and the plain list parser. His support during the early days was -central to the success of this project. Bastien also invented Worg, -helped establishing the Web presence of Org, and sponsored hosting -costs for the orgmode.org website. Bastien stepped in as maintainer -of Org between 2011 and 2013, at a time when I desperately needed -a break. - -@item Eric Schulte and Dan Davison -Eric and Dan are jointly responsible for the Org Babel system, which -turns Org into a multi-language environment for evaluating code and -doing literate programming and reproducible research. This has -become one of Org's killer features that define what Org is today. - -@item John Wiegley -John has contributed a number of great ideas and patches directly to -Org, including the attachment system (@samp{org-attach.el}), integration -with Apple Mail (@samp{org-mac-message.el}), hierarchical dependencies of -TODO items, habit tracking (@samp{org-habits.el}), and encryption -(@samp{org-crypt.el}). Also, the capture system is really an extended -copy of his great @samp{remember.el}. - -@item Sebastian Rose -Without Sebastian, the HTML/XHTML publishing of Org would be the -pitiful work of an ignorant amateur. Sebastian has pushed this part -of Org onto a much higher level. He also wrote @samp{org-info.js}, -a JavaScript program for displaying webpages derived from Org using -an Info-like or a folding interface with single-key navigation. -@end table - -See below for the full list of contributions! Again, please let me -know what I am missing here! - -@anchor{From Bastien} -@appendixsec From Bastien - -I (Bastien) have been maintaining Org between 2011 and 2013. This -appendix would not be complete without adding a few more -acknowledgments and thanks. - -I am first grateful to Carsten for his trust while handing me over the -maintainership of Org. His unremitting support is what really helped -me getting more confident over time, with both the community and the -code. - -When I took over maintainership, I knew I would have to make Org more -collaborative than ever, as I would have to rely on people that are -more knowledgeable than I am on many parts of the code. Here is -a list of the persons I could rely on, they should really be -considered co-maintainers, either of the code or the community: - -@table @asis -@item Eric Schulte -Eric is maintaining the Babel parts of Org. His reactivity here -kept me away from worrying about possible bugs here and let me focus -on other parts. - -@item Nicolas Goaziou -Nicolas is maintaining the consistency of the deepest parts of Org. -His work on @samp{org-element.el} and @samp{ox.el} has been outstanding, and -it opened the doors for many new ideas and features. He rewrote -many of the old exporters to use the new export engine, and helped -with documenting this major change. More importantly (if that's -possible), he has been more than reliable during all the work done -for Org 8.0, and always very reactive on the mailing list. - -@item Achim Gratz -Achim rewrote the building process of Org, turning some @emph{ad hoc} -tools into a flexible and conceptually clean process. He patiently -coped with the many hiccups that such a change can create for users. - -@item Nick Dokos -The Org mode mailing list would not be such a nice place without -Nick, who patiently helped users so many times. It is impossible to -overestimate such a great help, and the list would not be so active -without him. -@end table - -I received support from so many users that it is clearly impossible to -be fair when shortlisting a few of them, but Org's history would not -be complete if the ones above were not mentioned in this manual. - -@anchor{List of Contributions} -@appendixsec List of Contributions - -@itemize -@item -Russell Adams came up with the idea for drawers. - -@item -Thomas Baumann wrote @samp{ol-bbdb.el} and @samp{ol-mhe.el}. - -@item -Christophe Bataillon created the great unicorn logo that we use on -the Org mode website. - -@item -Alex Bochannek provided a patch for rounding timestamps. - -@item -Jan Böcker wrote @samp{ol-docview.el}. - -@item -Brad Bozarth showed how to pull RSS feed data into Org files. - -@item -Tom Breton wrote @samp{org-choose.el}. - -@item -Charles Cave's suggestion sparked the implementation of templates -for Remember, which are now templates for capture. - -@item -Pavel Chalmoviansky influenced the agenda treatment of items with -specified time. - -@item -Gregory Chernov patched support for Lisp forms into table -calculations and improved XEmacs compatibility, in particular by -porting @samp{nouline.el} to XEmacs. - -@item -Sacha Chua suggested copying some linking code from Planner. - -@item -Baoqiu Cui contributed the DocBook exporter. - -@item -Eddward DeVilla proposed and tested checkbox statistics. He also -came up with the idea of properties, and that there should be an API -for them. - -@item -Nick Dokos tracked down several nasty bugs. - -@item -Kees Dullemond used to edit projects lists directly in HTML and so -inspired some of the early development, including HTML export. He -also asked for a way to narrow wide table columns. - -@item -Thomas@tie{}S@.@tie{}Dye contributed documentation on Worg and helped -integrating the Org Babel documentation into the manual. - -@item -Christian Egli converted the documentation into Texinfo format, -inspired the agenda, patched CSS formatting into the HTML exporter, -and wrote @samp{org-taskjuggler.el}. - -@item -David Emery provided a patch for custom CSS support in exported HTML -agendas. - -@item -Nic Ferrier contributed mailcap and XOXO support. - -@item -Miguel@tie{}A@.@tie{}Figueroa-Villanueva implemented hierarchical checkboxes. - -@item -John Foerch figured out how to make incremental search show context -around a match in a hidden outline tree. - -@item -Raimar Finken wrote @samp{org-git-line.el}. - -@item -Mikael Fornius works as a mailing list moderator. - -@item -Austin Frank works as a mailing list moderator. - -@item -Eric Fraga drove the development of Beamer export with ideas and -testing. - -@item -Barry Gidden did proofreading the manual in preparation for the book -publication through Network Theory Ltd. - -@item -Niels Giesen had the idea to automatically archive DONE trees. - -@item -Nicolas Goaziou rewrote much of the plain list code. - -@item -Kai Grossjohann pointed out key-binding conflicts with other -packages. - -@item -Brian Gough of Network Theory Ltd publishes the Org mode manual as -a book. - -@item -Bernt Hansen has driven much of the support for auto-repeating -tasks, task state change logging, and the clocktable. His clear -explanations have been critical when we started to adopt the Git -version control system. - -@item -Manuel Hermenegildo has contributed various ideas, small fixes and -patches. - -@item -Phil Jackson wrote @samp{ol-irc.el}. - -@item -Scott Jaderholm proposed footnotes, control over whitespace between -folded entries, and column view for properties. - -@item -Matt Jones wrote MobileOrg Android. - -@item -Tokuya Kameshima wrote @samp{org-wl.el} and @samp{org-mew.el}. - -@item -Shidai Liu (``Leo'') asked for embedded @LaTeX{} and tested it. He also -provided frequent feedback and some patches. - -@item -Matt Lundin has proposed last-row references for table formulas and -named invisible anchors. He has also worked a lot on the FAQ@. - -@item -David Maus wrote @samp{org-atom.el}, maintains the issues file for Org, -and is a prolific contributor on the mailing list with competent -replies, small fixes and patches. - -@item -Jason@tie{}F@.@tie{}McBrayer suggested agenda export to CSV format. - -@item -Max Mikhanosha came up with the idea of refiling. - -@item -Dmitri Minaev sent a patch to set priority limits on a per-file -basis. - -@item -Stefan Monnier provided a patch to keep the Emacs Lisp compiler -happy. - -@item -Richard Moreland wrote MobileOrg for the iPhone. - -@item -Rick Moynihan proposed allowing multiple TODO sequences in a file -and being able to quickly restrict the agenda to a subtree. - -@item -Todd Neal provided patches for links to Info files and Elisp forms. - -@item -Greg Newman refreshed the unicorn logo into its current form. - -@item -Tim O'Callaghan suggested in-file links, search options for general -file links, and tags. - -@item -Osamu Okano wrote @samp{orgcard2ref.pl}, a Perl program to create a text -version of the reference card. - -@item -Takeshi Okano translated the manual and David O'Toole's tutorial -into Japanese. - -@item -Oliver Oppitz suggested multi-state TODO items. - -@item -Scott Otterson sparked the introduction of descriptive text for -links, among other things. - -@item -Pete Phillips helped during the development of the TAGS feature, -and provided frequent feedback. - -@item -Martin Pohlack provided the code snippet to bundle character -insertion into bundles of 20 for undo. - -@item -T@.@tie{}V@.@tie{}Raman reported bugs and suggested improvements. - -@item -Matthias Rempe (Oelde) provided ideas, Windows support, and quality -control. - -@item -Paul Rivier provided the basic implementation of named footnotes. -He also acted as mailing list moderator for some time. - -@item -Kevin Rogers contributed code to access VM files on remote hosts. - -@item -Frank Ruell solved the mystery of the @samp{keymapp nil} bug, a conflict -with @samp{allout.el}. - -@item -Jason Riedy generalized the send-receive mechanism for Orgtbl -tables with extensive patches. - -@item -Philip Rooke created the Org reference card, provided lots of -feedback, developed and applied standards to the Org documentation. - -@item -Christian Schlauer proposed angular brackets around links, among -other things. - -@item -Paul Sexton wrote @samp{org-ctags.el}. - -@item -Tom Shannon's @samp{organizer-mode.el} inspired linking to VM/BBDB/Gnus. - -@item -Ilya Shlyakhter proposed the Archive Sibling, line numbering in -literal examples, and remote highlighting for referenced code lines. - -@item -Stathis Sideris wrote the @samp{ditaa.jar} ASCII to PNG converter that is -now packaged into Org's @samp{contrib/} directory. - -@item -Daniel Sinder came up with the idea of internal archiving by locking -subtrees. - -@item -Dale Smith proposed link abbreviations. - -@item -James TD Smith has contributed a large number of patches for -useful tweaks and features. - -@item -Adam Spiers asked for global linking commands, inspired the link -extension system, added support for Mairix, and proposed the mapping -API@. - -@item -Ulf Stegemann created the table to translate special symbols to -HTML, @LaTeX{}, UTF-8, Latin-1 and ASCII@. - -@item -Andy Stewart contributed code to @samp{ol-w3m.el}, to copy -HTML content with links transformation to Org syntax. - -@item -David O'Toole wrote @samp{org-publish.el} and drafted the -manual chapter about publishing. - -@item -Jambunathan@tie{}K@.@tie{}contributed the ODT exporter. - -@item -Sebastien Vauban reported many issues with @LaTeX{} and Beamer export -and enabled source code highlighting in Gnus. - -@item -Stefan Vollmar organized a video-recorded talk at the -Max-Planck-Institute for Neurology. He also inspired the creation -of a concept index for HTML export. - -@item -Jürgen Vollmer contributed code generating the table of contents in -HTML output. - -@item -Samuel Wales has provided important feedback and bug reports. - -@item -Chris Wallace provided a patch implementing the @samp{QUOTE} block. - -@item -David Wainberg suggested archiving, and improvements to the -linking system. - -@item -Carsten Wimmer suggested some changes and helped fix a bug in -linking to Gnus. - -@item -Roland Winkler requested additional key bindings to make Org work on -a TTY@. - -@item -Piotr Zielinski wrote @samp{org-mouse.el}, proposed agenda -blocks and contributed various ideas and code snippets. - -@item -Marco Wahl wrote @samp{ol-eww.el}. -@end itemize - -@node GNU Free Documentation License -@appendix GNU Free Documentation License - -@center Version 1.3, 3 November 2008 - -@display -Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. -@uref{https://fsf.org/} - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. -@end display - -@enumerate 0 -@item -PREAMBLE - -The purpose of this License is to make a manual, textbook, or other -functional and useful document @dfn{free} -in the sense of freedom: to assure everyone the effective freedom -to copy and redistribute it, with or without modifying it, either -commercially or noncommercially. Secondarily, this License -preserves for the author and publisher a way to get credit for -their work, while not being considered responsible for -modifications made by others. - -This License is a kind of ``copyleft'', which means that derivative -works of the document must themselves be free in the same sense. -It complements the GNU General Public License, which is a copyleft -license designed for free software. - -We have designed this License in order to use it for manuals for -free software, because free software needs free documentation: -a free program should come with manuals providing the same freedoms -that the software does. But this License is not limited to -software manuals; it can be used for any textual work, regardless -of subject matter or whether it is published as a printed book. We -recommend this License principally for works whose purpose is -instruction or reference. - -@item -APPLICABILITY AND DEFINITIONS - -This License applies to any manual or other work, in any medium, -that contains a notice placed by the copyright holder saying it can -be distributed under the terms of this License. Such a notice -grants a world-wide, royalty-free license, unlimited in duration, -to use that work under the conditions stated herein. The -``Document'', below, refers to any such manual or work. Any member -of the public is a licensee, and is addressed as ``you''. You accept -the license if you copy, modify or distribute the work in a way -requiring permission under copyright law. - -A ``Modified Version'' of the Document means any work containing the -Document or a portion of it, either copied verbatim, or with -modifications and/or translated into another language. - -A ``Secondary Section'' is a named appendix or a front-matter section -of the Document that deals exclusively with the relationship of the -publishers or authors of the Document to the Document's overall -subject (or to related matters) and contains nothing that could -fall directly within that overall subject. (Thus, if the Document -is in part a textbook of mathematics, a Secondary Section may not -explain any mathematics.) The relationship could be a matter of -historical connection with the subject or with related matters, or -of legal, commercial, philosophical, ethical or political position -regarding them. - -The ``Invariant Sections'' are certain Secondary Sections whose -titles are designated, as being those of Invariant Sections, in the -notice that says that the Document is released under this License. -If a section does not fit the above definition of Secondary then it -is not allowed to be designated as Invariant. The Document may -contain zero Invariant Sections. If the Document does not identify -any Invariant Sections then there are none. - -The ``Cover Texts'' are certain short passages of text that are -listed, as Front-Cover Texts or Back-Cover Texts, in the notice -that says that the Document is released under this License. -A Front-Cover Text may be at most 5 words, and a Back-Cover Text -may be at most 25 words. - -A ``Transparent'' copy of the Document means a machine-readable copy, -represented in a format whose specification is available to the -general public, that is suitable for revising the document -straightforwardly with generic text editors or (for images composed -of pixels) generic paint programs or (for drawings) some widely -available drawing editor, and that is suitable for input to text -formatters or for automatic translation to a variety of formats -suitable for input to text formatters. A copy made in an otherwise -Transparent file format whose markup, or absence of markup, has -been arranged to thwart or discourage subsequent modification by -readers is not Transparent. An image format is not Transparent if -used for any substantial amount of text. A copy that is not -``Transparent'' is called ``Opaque''. - -Examples of suitable formats for Transparent copies include plain -ASCII without markup, Texinfo input format, @LaTeX{} input format, -SGML or XML using a publicly available DTD, and standard-conforming -simple HTML, PostScript or PDF designed for human modification. -Examples of transparent image formats include PNG, XCF and JPG@. -Opaque formats include proprietary formats that can be read and -edited only by proprietary word processors, SGML or XML for which -the DTD and/or processing tools are not generally available, and -the machine-generated HTML, PostScript or PDF produced by some word -processors for output purposes only. - -The ``Title Page'' means, for a printed book, the title page itself, -plus such following pages as are needed to hold, legibly, the -material this License requires to appear in the title page. For -works in formats which do not have any title page as such, ``Title -Page'' means the text near the most prominent appearance of the -work's title, preceding the beginning of the body of the text. - -The ``publisher'' means any person or entity that distributes copies -of the Document to the public. - -A section ``Entitled XYZ'' means a named subunit of the Document -whose title either is precisely XYZ or contains XYZ in parentheses -following text that translates XYZ in another language. (Here XYZ -stands for a specific section name mentioned below, such as -``Acknowledgements'', ``Dedications'', ``Endorsements'', or ``History''.) -To ``Preserve the Title'' of such a section when you modify the -Document means that it remains a section ``Entitled XYZ'' according -to this definition. - -The Document may include Warranty Disclaimers next to the notice -which states that this License applies to the Document. These -Warranty Disclaimers are considered to be included by reference in -this License, but only as regards disclaiming warranties: any other -implication that these Warranty Disclaimers may have is void and -has no effect on the meaning of this License. - -@item -VERBATIM COPYING - -You may copy and distribute the Document in any medium, either -commercially or noncommercially, provided that this License, the -copyright notices, and the license notice saying this License -applies to the Document are reproduced in all copies, and that you -add no other conditions whatsoever to those of this License. You -may not use technical measures to obstruct or control the reading -or further copying of the copies you make or distribute. However, -you may accept compensation in exchange for copies. If you -distribute a large enough number of copies you must also follow the -conditions in section 3. - -You may also lend copies, under the same conditions stated above, -and you may publicly display copies. - -@item -COPYING IN QUANTITY - -If you publish printed copies (or copies in media that commonly -have printed covers) of the Document, numbering more than 100, and -the Document's license notice requires Cover Texts, you must -enclose the copies in covers that carry, clearly and legibly, all -these Cover Texts: Front-Cover Texts on the front cover, and -Back-Cover Texts on the back cover. Both covers must also clearly -and legibly identify you as the publisher of these copies. The -front cover must present the full title with all words of the title -equally prominent and visible. You may add other material on the -covers in addition. Copying with changes limited to the covers, as -long as they preserve the title of the Document and satisfy these -conditions, can be treated as verbatim copying in other respects. - -If the required texts for either cover are too voluminous to fit -legibly, you should put the first ones listed (as many as fit -reasonably) on the actual cover, and continue the rest onto -adjacent pages. - -If you publish or distribute Opaque copies of the Document -numbering more than 100, you must either include a machine-readable -Transparent copy along with each Opaque copy, or state in or with -each Opaque copy a computer-network location from which the general -network-using public has access to download using public-standard -network protocols a complete Transparent copy of the Document, free -of added material. If you use the latter option, you must take -reasonably prudent steps, when you begin distribution of Opaque -copies in quantity, to ensure that this Transparent copy will -remain thus accessible at the stated location until at least one -year after the last time you distribute an Opaque copy (directly or -through your agents or retailers) of that edition to the public. - -It is requested, but not required, that you contact the authors of -the Document well before redistributing any large number of copies, -to give them a chance to provide you with an updated version of the -Document. - -@item -MODIFICATIONS - -You may copy and distribute a Modified Version of the Document -under the conditions of sections 2 and 3 above, provided that you -release the Modified Version under precisely this License, with the -Modified Version filling the role of the Document, thus licensing -distribution and modification of the Modified Version to whoever -possesses a copy of it. In addition, you must do these things in -the Modified Version: - -@enumerate A -@item -Use in the Title Page (and on the covers, if any) a title -distinct from that of the Document, and from those of previous -versions (which should, if there were any, be listed in the -History section of the Document). You may use the same title as -a previous version if the original publisher of that version -gives permission. - -@item -List on the Title Page, as authors, one or more persons or -entities responsible for authorship of the modifications in the -Modified Version, together with at least five of the principal -authors of the Document (all of its principal authors, if it has -fewer than five), unless they release you from this requirement. - -@item -State on the Title page the name of the publisher of the -Modified Version, as the publisher. - -@item -Preserve all the copyright notices of the Document. - -@item -Add an appropriate copyright notice for your modifications -adjacent to the other copyright notices. - -@item -Include, immediately after the copyright notices, a license -notice giving the public permission to use the Modified Version -under the terms of this License, in the form shown in the -Addendum below. - -@item -Preserve in that license notice the full lists of Invariant -Sections and required Cover Texts given in the Document's -license notice. - -@item -Include an unaltered copy of this License. - -@item -Preserve the section Entitled ``History'', Preserve its Title, and -add to it an item stating at least the title, year, new authors, -and publisher of the Modified Version as given on the Title -Page. If there is no section Entitled ``History'' in the Document, -create one stating the title, year, authors, and publisher of -the Document as given on its Title Page, then add an item -describing the Modified Version as stated in the previous -sentence. - -@item -Preserve the network location, if any, given in the Document -for public access to a Transparent copy of the Document, and -likewise the network locations given in the Document for -previous versions it was based on. These may be placed in the -``History'' section. You may omit a network location for a work -that was published at least four years before the Document -itself, or if the original publisher of the version it refers -to gives permission. - -@item -For any section Entitled ``Acknowledgements'' or ``Dedications'', -Preserve the Title of the section, and preserve in the section -all the substance and tone of each of the contributor -acknowledgements and/or dedications given therein. - -@item -Preserve all the Invariant Sections of the Document, unaltered -in their text and in their titles. Section numbers or the -equivalent are not considered part of the section titles. - -@item -Delete any section Entitled ``Endorsements''. Such a section may -not be included in the Modified Version. - -@item -Do not retitle any existing section to be Entitled -``Endorsements'' or to conflict in title with any Invariant -Section. - -@item -Preserve any Warranty Disclaimers. -@end enumerate - -If the Modified Version includes new front-matter sections or -appendices that qualify as Secondary Sections and contain no material -copied from the Document, you may at your option designate some or all -of these sections as invariant. To do this, add their titles to the -list of Invariant Sections in the Modified Version's license notice. -These titles must be distinct from any other section titles. - -You may add a section Entitled ``Endorsements'', provided it contains -nothing but endorsements of your Modified Version by various -parties---for example, statements of peer review or that the text has -been approved by an organization as the authoritative definition of a -standard. - -You may add a passage of up to five words as a Front-Cover Text, and a -passage of up to 25 words as a Back-Cover Text, to the end of the list -of Cover Texts in the Modified Version. Only one passage of -Front-Cover Text and one of Back-Cover Text may be added by (or -through arrangements made by) any one entity. If the Document already -includes a cover text for the same cover, previously added by you or -by arrangement made by the same entity you are acting on behalf of, -you may not add another; but you may replace the old one, on explicit -permission from the previous publisher that added the old one. - -The author(s) and publisher(s) of the Document do not by this License -give permission to use their names for publicity for or to assert or -imply endorsement of any Modified Version. - -@item -COMBINING DOCUMENTS - -You may combine the Document with other documents released under -this License, under the terms defined in section 4 above for -modified versions, provided that you include in the combination all -of the Invariant Sections of all of the original documents, -unmodified, and list them all as Invariant Sections of your -combined work in its license notice, and that you preserve all -their Warranty Disclaimers. - -The combined work need only contain one copy of this License, and -multiple identical Invariant Sections may be replaced with a single -copy. If there are multiple Invariant Sections with the same name -but different contents, make the title of each such section unique -by adding at the end of it, in parentheses, the name of the -original author or publisher of that section if known, or else -a unique number. Make the same adjustment to the section titles in -the list of Invariant Sections in the license notice of the -combined work. - -In the combination, you must combine any sections Entitled -``History'' in the various original documents, forming one section -Entitled ``History''; likewise combine any sections Entitled -``Acknowledgements'', and any sections Entitled ``Dedications''. You -must delete all sections Entitled ``Endorsements.'' - -@item -COLLECTIONS OF DOCUMENTS - -You may make a collection consisting of the Document and other -documents released under this License, and replace the individual -copies of this License in the various documents with a single copy -that is included in the collection, provided that you follow the -rules of this License for verbatim copying of each of the documents -in all other respects. - -You may extract a single document from such a collection, and -distribute it individually under this License, provided you insert -a copy of this License into the extracted document, and follow this -License in all other respects regarding verbatim copying of that -document. - -@item -AGGREGATION WITH INDEPENDENT WORKS - -A compilation of the Document or its derivatives with other -separate and independent documents or works, in or on a volume of -a storage or distribution medium, is called an ``aggregate'' if the -copyright resulting from the compilation is not used to limit the -legal rights of the compilation's users beyond what the individual -works permit. When the Document is included in an aggregate, this -License does not apply to the other works in the aggregate which -are not themselves derivative works of the Document. - -If the Cover Text requirement of section 3 is applicable to these -copies of the Document, then if the Document is less than one half -of the entire aggregate, the Document's Cover Texts may be placed -on covers that bracket the Document within the aggregate, or the -electronic equivalent of covers if the Document is in electronic -form. Otherwise they must appear on printed covers that bracket -the whole aggregate. - -@item -TRANSLATION - -Translation is considered a kind of modification, so you may -distribute translations of the Document under the terms of -section 4. Replacing Invariant Sections with translations requires -special permission from their copyright holders, but you may -include translations of some or all Invariant Sections in addition -to the original versions of these Invariant Sections. You may -include a translation of this License, and all the license notices -in the Document, and any Warranty Disclaimers, provided that you -also include the original English version of this License and the -original versions of those notices and disclaimers. In case of -a disagreement between the translation and the original version of -this License or a notice or disclaimer, the original version will -prevail. - -If a section in the Document is Entitled ``Acknowledgements'', -``Dedications'', or ``History'', the requirement (section 4) to -Preserve its Title (section 1) will typically require changing the -actual title. - -@item -TERMINATION - -You may not copy, modify, sublicense, or distribute the Document -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense, or distribute it is void, -and will automatically terminate your rights under this License. - -However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the -copyright holder fails to notify you of the violation by some -reasonable means prior to 60 days after the cessation. - -Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from -that copyright holder, and you cure the violation prior to 30 days -after your receipt of the notice. - -Termination of your rights under this section does not terminate -the licenses of parties who have received copies or rights from you -under this License. If your rights have been terminated and not -permanently reinstated, receipt of a copy of some or all of the -same material does not give you any rights to use it. - -@item -FUTURE REVISIONS OF THIS LICENSE - -The Free Software Foundation may publish new, revised versions of -the GNU Free Documentation License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. See -@uref{https://www.gnu.org/copyleft/}. - -Each version of the License is given a distinguishing version -number. If the Document specifies that a particular numbered -version of this License ``or any later version'' applies to it, you -have the option of following the terms and conditions either of -that specified version or of any later version that has been -published (not as a draft) by the Free Software Foundation. If -the Document does not specify a version number of this License, -you may choose any version ever published (not as a draft) by the -Free Software Foundation. If the Document specifies that a proxy -can decide which future versions of this License can be used, that -proxy's public statement of acceptance of a version permanently -authorizes you to choose that version for the Document. - -@item -RELICENSING - -``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any -World Wide Web server that publishes copyrightable works and also -provides prominent facilities for anybody to edit those works. -A public wiki that anybody can edit is an example of such -a server. A ``Massive Multiauthor Collaboration'' (or ``MMC'') -contained in the site means any set of copyrightable works thus -published on the MMC site. - -``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0 -license published by Creative Commons Corporation, -a not-for-profit corporation with a principal place of business in -San Francisco, California, as well as future copyleft versions of -that license published by that same organization. - -``Incorporate'' means to publish or republish a Document, in whole -or in part, as part of another Document. - -An MMC is ``eligible for relicensing'' if it is licensed under this -License, and if all works that were first published under this -License somewhere other than this MMC, and subsequently -incorporated in whole or in part into the MMC, (1) had no cover -texts or invariant sections, and (2) were thus incorporated prior -to November 1, 2008. - -The operator of an MMC Site may republish an MMC contained in the -site under CC-BY-SA on the same site at any time before August 1, -2009, provided the MMC is eligible for relicensing. -@end enumerate - -@page - -@anchor{ADDENDUM How to use this License for your documents} -@appendixsec ADDENDUM: How to use this License for your documents - -To use this License in a document you have written, include a copy of -the License in the document and put the following copyright and -license notices just after the title page: - -@example -Copyright (C) YEAR YOUR NAME. -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, no Front-Cover Texts, and no Back-Cover -Texts. A copy of the license is included in the section entitled ``GNU -Free Documentation License''. -@end example - -If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, -replace the ``with@dots{}Texts.''@tie{}line with this: - -@example -with the Invariant Sections being LIST THEIR TITLES, with -the Front-Cover Texts being LIST, and with the Back-Cover Texts -being LIST. -@end example - -If you have Invariant Sections without Cover Texts, or some other -combination of the three, merge those two alternatives to suit the -situation. - -If your document contains nontrivial examples of program code, we -recommend releasing these examples in parallel under your choice of -free software license, such as the GNU General Public License, to -permit their use in free software. - -@node Main Index -@chapter Main Index - -@printindex cp - -@node Key Index -@chapter Key Index - -@printindex ky - -@node Command and Function Index -@chapter Command and Function Index - -@printindex fn - -@node Variable Index -@chapter Variable Index - -This is not a complete index of variables and faces, only the ones -that are mentioned in the manual. For a more complete list, use -@kbd{M-x org-customize} and then click yourself through the tree. - -@printindex vr - -@bye diff --git a/lisp/org/ox-texinfo.el b/lisp/org/ox-texinfo.el index cf080549a6..78d58beadd 100644 --- a/lisp/org/ox-texinfo.el +++ b/lisp/org/ox-texinfo.el @@ -1627,6 +1627,23 @@ Return output file's name." (org-export-to-file 'texinfo outfile async subtreep visible-only body-only ext-plist))) +(defun org-texinfo-export-to-texinfo-batch () + "Export Org file INFILE to Texinfo file OUTFILE, in batch mode. +Usage: emacs -batch -f org-texinfo-export-to-texinfo-batch INFILE OUTFILE" + (or noninteractive (user-error "Batch mode use only")) + (let ((infile (pop command-line-args-left)) + (outfile (pop command-line-args-left)) + (org-export-coding-system org-texinfo-coding-system)) + (unless (file-readable-p infile) + (message "File `%s' not readable" infile) + (kill-emacs 1)) + (when (file-exists-p outfile) + (message "File `%s' already exists" outfile) + (kill-emacs 1)) + (with-temp-buffer + (insert-file-contents infile) + (org-export-to-file 'texinfo outfile)))) + ;;;###autoload (defun org-texinfo-export-to-info (&optional async subtreep visible-only body-only ext-plist) commit 3984044ad3f481b0c67e906a405176ae276dd44d Author: Protesilaos Stavrou Date: Fri Feb 26 19:27:57 2021 -0800 Import org source file for modus-themes manual * doc/misc/modus-themes.org: New file. Import from https://gitlab.com/protesilaos/modus-themes 515180ac. diff --git a/doc/misc/modus-themes.org b/doc/misc/modus-themes.org new file mode 100644 index 0000000000..db15db46b5 --- /dev/null +++ b/doc/misc/modus-themes.org @@ -0,0 +1,1955 @@ +#+TITLE: Modus themes for GNU Emacs +#+AUTHOR: Protesilaos Stavrou +#+EMAIL: info@protesilaos.com +#+TEXINFO_DIR_CATEGORY: Emacs misc features +#+TEXINFO_DIR_TITLE: Modus Themes: (modus-themes) +#+TEXINFO_DIR_DESC: Highly accessible themes (WCAG AAA) +#+OPTIONS: ':t toc:nil author:t email:t +#+MACRO: version-tag 0.13.0 +#+MACRO: release-date 2020-10-08 + +This manual, written by Protesilaos Stavrou, describes the customization +options for the =modus-operandi= and =modus-vivendi= themes, and provides +every other piece of information pertinent to them. + +The documentation furnished herein corresponds to version {{{version-tag}}}, +released on {{{release-date}}}. Any reference to a newer feature which does +not yet form part of the latest tagged commit, is explicitly marked as +such. + +Copyright (C) 2020 Free Software Foundation, Inc. + +#+begin_quote +Permission is granted to copy, distribute and/or modify this +document under the terms of the GNU Free Documentation License, +Version 1.3 or any later version published by the Free Software +Foundation; with no Invariant Sections, with no Front-Cover Texts, +and with no Back-Cover Texts. +#+end_quote + +#+TOC: headlines 8 insert TOC here, with eight headline levels + +* Overview +:PROPERTIES: +:CUSTOM_ID: h:f0f3dbcb-602d-40cf-b918-8f929c441baf +:END: + +The Modus themes are designed for accessible readability. They conform +with the highest standard for color contrast between any given +combination of background and foreground values. This corresponds to +the WCAG AAA standard, which specifies a minimum rate of distance in +relative luminance of 7:1. + +Modus Operandi (=modus-operandi=) is a light theme, while Modus Vivendi +(=modus-vivendi=) is dark. Each theme's color palette is designed to +meet the needs of the numerous interfaces that are possible in the Emacs +computing environment. + +The overarching objective of this project is to always offer accessible +color combinations. There shall never be a compromise on this +principle. If there arises an inescapable trade-off between readability +and stylistic considerations, we will always opt for the former. + +To ensure that users have a consistently accessible experience, the +themes strive to achieve as close to full face coverage as possible +(see [[#h:a9c8f29d-7f72-4b54-b74b-ddefe15d6a19][Face coverage]]). + +Starting with version 0.12.0 and onwards, the themes are built into GNU +Emacs (current version is {{{version-tag}}}). + +** How do the themes look like +:PROPERTIES: +:CUSTOM_ID: h:69b92089-069c-4ba1-9d94-cc3415fc4f87 +:END: + +Check the web page with [[https://protesilaos.com/modus-themes-pictures/][the screen shots]]. There are lots of scenarios +on display that draw attention to details and important aspects in the +design of the themes. They also showcase the numerous customization +options. + +[[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization options]]. + +** Learn about the latest changes +:PROPERTIES: +:CUSTOM_ID: h:2cc37c36-6c1a-48b2-a010-1050b270ee18 +:END: + +Please refer to the [[https://protesilaos.com/modus-themes-changelog][web page with the change log]]. It is comprehensive +and covers everything that goes into every tagged release of the themes. + +* Installation +:PROPERTIES: +:CUSTOM_ID: h:1af85373-7f81-4c35-af25-afcef490c111 +:END: + +The Modus themes are distributed with Emacs starting with version 28.1. +On older versions of Emacs, they can be installed using Emacs' package +manager or manually from their code repository. + +Modus Operandi (light theme) and Modus Vivendi (dark) are normally +distributed as standalone packages in Emacs-specific archives. There +also exist packages for GNU/Linux distributions. + +** Install from the archives +:PROPERTIES: +:CUSTOM_ID: h:c4b10085-149f-43e2-bd4d-347f33aee054 +:END: + +=modus-operandi-theme= and =modus-vivendi-theme= are available from GNU the +ELPA archive, which is configured by default. + +Prior to querying any package archive, make sure to have updated the +index, with =M-x package-refresh-contents=. Then all you need to do is +type =M-x package-install= and specify the theme of your choice. + +** Install on GNU/Linux +:PROPERTIES: +:CUSTOM_ID: h:da640eb1-95dd-4e86-bb4e-1027b27885f0 +:END: + +The themes are also available from the archives of some GNU/Linux +distributions. These should correspond to a tagged release rather than +building directly from the latest Git commit. It all depends on the +distro's packaging policies. + +*** Debian 11 Bullseye +:PROPERTIES: +:CUSTOM_ID: h:7e570360-9ee6-4bc5-8c04-9dc11418a3e4 +:END: + +The two themes are distributed as a single package for Debian and its +derivatives. Currently in the unstable and testing suites and should be +available in time for Debian 11 Bullseye (next stable). + +Get them with: + +#+begin_src sh +sudo apt install elpa-modus-themes +#+end_src + +*** GNU Guix +:PROPERTIES: +:CUSTOM_ID: h:a4ca52cd-869f-46a5-9e16-4d9665f5b88e +:END: + +Users of either the Guix System (the distro) or just Guix (the package +manager) can get each theme as a standalone package. + +#+begin_src sh +guix package -i emacs-modus-operandi-theme +#+end_src + +And/or: + +#+begin_src sh +guix package -i emacs-modus-vivendi-theme +#+end_src + +* Enable and load +:PROPERTIES: +:CUSTOM_ID: h:3f3c3728-1b34-437d-9d0c-b110f5b161a9 +:END: + +This section documents how to load the theme of your choice and how to +further control its initialization. It also includes some sample code +snippets that could help you in the task, especially if you intend to +use both Modus Operandi and Modus Vivendi. + +** Load automatically +:PROPERTIES: +:CUSTOM_ID: h:1777c247-1b56-46b7-a4ce-54e720b33d06 +:END: + +A simple way to load the theme from your Emacs initialization file is to +include either of the following expressions: + +#+BEGIN_SRC emacs-lisp +(load-theme 'modus-operandi t) ; Light theme +(load-theme 'modus-vivendi t) ; Dark theme +#+END_SRC + +Make sure to remove any other theme that is being loaded, otherwise you +might run into unexpected issues. + +Note that you can always =M-x disable-theme= and specify an item. The +command does exactly what its name suggests. To deactivate all enabled +themes at once, in case you have multiple of them enabled, you may +evaluate the expression: + +#+begin_src emacs-lisp +(mapc #'disable-theme custom-enabled-themes) +#+end_src + +** Load at a given time or at sunset/sunrise +:PROPERTIES: +:CUSTOM_ID: h:4e936e31-e9eb-4b50-8fdd-45d827a03cca +:END: + +It is possible to schedule a time during the day at or after which a +given theme will be loaded.[fn:: Contributed on Reddit by user =b3n=, +https://www.reddit.com/r/emacs/comments/gdtqov/weekly_tipstricketc_thread/fq9186h/.] + +#+begin_src emacs-lisp +;; Light for the day +(load-theme 'modus-operandi t t) +(run-at-time "05:00" (* 60 60 24) + (lambda () + (enable-theme 'modus-operandi))) + +;; Dark for the night +(load-theme 'modus-vivendi t t) +(run-at-time "21:00" (* 60 60 24) + (lambda () + (enable-theme 'modus-vivendi))) +#+end_src + +A modified version of the above technique is to use the sunrise and +sunset as references, instead of specifying a fixed hour value.[fn:: +Contributed directly by André Alexandre Gomes https://gitlab.com/aadcg.] +If you set =calendar-latitude= and =calendar-longitude= (defined in the +built-in =solar.el= library---read it with =M-x find-library=), you can +automatically switch between both themes at the appropriate time-of-day. +Note that /those calendar variables need to be set before loading the +themes/. + +#+begin_src emacs-lisp +;; Define coordinates +(setq calendar-latitude 35.17 + calendar-longitude 33.36) + +;; Light at sunrise +(load-theme 'modus-operandi t t) +(run-at-time (nth 1 (split-string (sunrise-sunset))) + (* 60 60 24) + (lambda () + (enable-theme 'modus-operandi))) + +;; Dark at sunset +(load-theme 'modus-vivendi t t) +(run-at-time (nth 4 (split-string (sunrise-sunset))) + (* 60 60 24) + (lambda () + (enable-theme 'modus-vivendi))) +#+end_src + +For the sake of completeness, the =load-theme= call in these snippets is +slightly different than the one shown in [[#h:1777c247-1b56-46b7-a4ce-54e720b33d06][Load automatically]], because it +does not enable the theme directly: the subsequent =enable-theme= does +that when needed. + +** Toggle between the themes on demand +:PROPERTIES: +:CUSTOM_ID: h:2a0895a6-3281-4e55-8aa1-8a737555821e +:END: + +With both themes available, it is possible to design a simple command to +switch between them on demand. + +#+begin_src emacs-lisp +(defun modus-themes-toggle () + "Toggle between `modus-operandi' and `modus-vivendi' themes." + (interactive) + (if (eq (car custom-enabled-themes) 'modus-operandi) + (progn + (disable-theme 'modus-operandi) + (load-theme 'modus-vivendi t)) + (disable-theme 'modus-vivendi) + (load-theme 'modus-operandi t))) +#+end_src + +You could use =(mapc #'disable-theme custom-enabled-themes)= instead of +disabling a single target, but you get the idea. + +** Configure options prior to loading +:PROPERTIES: +:CUSTOM_ID: h:a897b302-8e10-4a26-beab-3caaee1e1193 +:END: + +If you plan to use both themes and wish to apply styles consistently +(see [[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization Options]]), you could define wrapper functions around +the standard =load-theme= command. These extend the simple function we +presented in [[#h:2a0895a6-3281-4e55-8aa1-8a737555821e][Toggle between the themes on demand]]. + +Here is a comprehensive setup (the values assigned to the variables are +just for the sake of this demonstration):[fn:: The =defmacro= and =dolist= +method were contributed on Reddit by user =b3n= +https://www.reddit.com/r/emacs/comments/gqsz8u/weekly_tipstricketc_thread/fsfakhg/.] + +#+begin_src emacs-lisp +(defmacro modus-themes-format-sexp (sexp &rest objects) + `(eval (read (format ,(format "%S" sexp) ,@objects)))) + +(dolist (theme '("operandi" "vivendi")) + (modus-themes-format-sexp + (defun modus-%1$s-theme-load () + (setq modus-%1$s-theme-slanted-constructs t + modus-%1$s-theme-bold-constructs t + modus-%1$s-theme-fringes 'subtle ; {nil,'subtle,'intense} + modus-%1$s-theme-mode-line '3d ; {nil,'3d,'moody} + modus-%1$s-theme-syntax 'alt-syntax ; {nil,faint,'yellow-comments,'green-strings,'yellow-comments-green-strings,'alt-syntax,'alt-syntax-yellow-comments} + modus-%1$s-theme-intense-hl-line nil + modus-%1$s-theme-intense-paren-match nil + modus-%1$s-theme-links 'faint ; {nil,'faint,'neutral-underline,'faint-neutral-underline,'no-underline} + modus-%1$s-theme-no-mixed-fonts nil + modus-%1$s-theme-prompts nil ; {nil,'subtle,'intense} + modus-%1$s-theme-completions 'moderate ; {nil,'moderate,'opinionated} + modus-%1$s-theme-diffs nil ; {nil,'desaturated,'fg-only} + modus-%1$s-theme-org-blocks 'grayscale ; {nil,'grayscale,'rainbow} + modus-%1$s-theme-headings ; Read further below in the manual for this one + '((1 . section) + (2 . line) + (t . rainbow-line-no-bold)) + modus-%1$s-theme-variable-pitch-headings nil + modus-%1$s-theme-scale-headings t + modus-%1$s-theme-scale-1 1.1 + modus-%1$s-theme-scale-2 1.15 + modus-%1$s-theme-scale-3 1.21 + modus-%1$s-theme-scale-4 1.27 + modus-%1$s-theme-scale-5 1.33) + (load-theme 'modus-%1$s t)) + theme)) + +(defun modus-themes-toggle () + "Toggle between `modus-operandi' and `modus-vivendi' themes." + (interactive) + (if (eq (car custom-enabled-themes) 'modus-operandi) + (progn + (disable-theme 'modus-operandi) + (modus-vivendi-theme-load)) + (disable-theme 'modus-vivendi) + (modus-operandi-theme-load))) +#+end_src + +* Customization Options +:PROPERTIES: +:CUSTOM_ID: h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f +:END: + +The Modus themes are highly configurable, though they should work well +without any further tweaks. + +By default, all customization options are set to =nil=. + +All customization options need to be evaluated before loading their +theme (see [[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]]). + +** Option for more bold constructs +:PROPERTIES: +:ALT_TITLE: Bold constructs +:DESCRIPTION: Toggle bold constructs in code +:CUSTOM_ID: h:b25714f6-0fbe-41f6-89b5-6912d304091e +:END: + +Symbol names: + ++ =modus-operandi-theme-bold-constructs= ++ =modus-vivendi-theme-bold-constructs= + +Possible values: + +1. =nil= (default) +2. =t= + +Display several constructs in bold weight. This concerns keywords and +other important aspects of code syntax. It also affects certain mode +line indicators and command-line prompts. + +The default is to only use a bold weight when it is required. + +Additionally, and while not necessary, to define the precise weight for +bold constructs, you can change the typographic intensity of the =bold= +face. The standard is a bold weight. It requires no further +intervention. Assuming though that your typeface of choice supports a +"semibold" weight, adding the following snippet to your init file should +suffice. + +#+begin_src emacs-lisp +(set-face-attribute 'bold nil :weight 'semibold) +#+end_src + +Note that if you are switching themes, you need to re-evaluate this +expression after the new theme is loaded. + +** Option for more slanted constructs +:PROPERTIES: +:ALT_TITLE: Slanted constructs +:DESCRIPTION: Toggle slanted constructs (italics) in code +:CUSTOM_ID: h:977c900d-0d6d-4dbb-82d9-c2aae69543d6 +:END: + +Symbol names: + ++ =modus-operandi-theme-slanted-constructs= ++ =modus-vivendi-theme-slanted-constructs= + +Possible values: + +1. =nil= (default) +2. =t= + +Choose to render more faces in slanted text (italics). This typically +affects documentation strings and code comments. + +The default is to not use italics unless it is absolutely necessary. + +** Option for faint code syntax highlighting (deprecated for ~0.14.0~) +:PROPERTIES: +:ALT_TITLE: Faint syntax +:DESCRIPTION: Toggle subtle coloration in code (deprecated for 0.14.0) +:CUSTOM_ID: h:741379fe-7203-4dad-a7f8-ab71f61b43e6 +:END: + +Symbol names: + ++ =modus-operandi-theme-faint-syntax= ++ =modus-vivendi-theme-faint-syntax= + +Possible values: + +1. =nil= (default) +2. =t= + +Use less saturated colors in programming modes for highlighting code +syntax. The default is to use saturated colors. + +This option essentially affects the font-lock faces, so it may also have +implications in other places that are hard-wired to rely directly on +them instead of specifying their own faces (which could inherit from +font-lock if that is the intent). The author is aware of =vc-dir= as a +case in point. + +** Option for syntax highlighting +:PROPERTIES: +:ALT_TITLE: Syntax styles +:DESCRIPTION: Choose the overall aesthetic of code syntax +:CUSTOM_ID: h:c119d7b2-fcd4-4e44-890e-5e25733d5e52 +:END: + +This option supersedes the "faint syntax" one ahead of version =0.14.0= +([[#h:741379fe-7203-4dad-a7f8-ab71f61b43e6][Option for faint code syntax highlighting]]). + +Symbol names: + ++ =modus-operandi-theme-syntax= ++ =modus-vivendi-theme-syntax= + +Possible values: + +1. =nil= (default) +2. =faint= +3. =yellow-comments= +4. =green-strings= +5. =yellow-comments-green-strings= +6. =alt-syntax= +7. =alt-syntax-yellow-comments= + +The default style (nil) for code syntax highlighting is a balanced +combination of colors on the cyan-blue-magenta side of the spectrum. +There is little to no use of greens, yellows, or reds, except when it is +necessary. + +Option =faint= is like the default in terms of the choice of palette but +applies desaturated color values. + +Option =yellow-comments= applies a yellow tint to comments. The rest of +the syntax is the same as the default. + +Option =green-strings= replaces the blue/cyan/cold color variants in +strings with greener alternatives. The rest of the syntax remains the +same. + +Option =yellow-comments-green-strings= combines yellow comments with green +strings and the rest of the default syntax highlighting style. + +Option =alt-syntax= expands the color palette and applies new color +combinations. Strings are green. Doc strings are magenta tinted. +Comments are gray. + +Option =alt-syntax-yellow-comments= combines =alt-syntax= with +=yellow-comments=. + +** Option for no font mixing +:PROPERTIES: +:ALT_TITLE: No mixed fonts +:DESCRIPTION: Toggle mixing of font families +:CUSTOM_ID: h:115e6c23-ee35-4a16-8cef-e2fcbb08e28b +:END: + +Symbol names: + ++ =modus-operandi-theme-no-mixed-fonts= ++ =modus-vivendi-theme-no-mixed-fonts= + +Possible values: + +1. =nil= (default) +2. =t= + +By default, the themes configure some spacing-sensitive faces, such as +Org tables and code blocks, to always inherit from the =fixed-pitch= face. +This is to ensure that those constructs remain monospaced when users opt +for something like the built-in =M-x variable-pitch-mode=. Otherwise the +layout would appear broken. To disable this behaviour, set the option +to =t=. + +Users may prefer to use another package for handling mixed typeface +configurations, rather than letting the theme do it, perhaps because a +purpose-specific package has extra functionality. Two possible options +are =org-variable-pitch= and =mixed-pitch=. + +** Option for no link underline (deprecated for ~0.14.0~) +:PROPERTIES: +:ALT_TITLE: Link underline +:DESCRIPTION: Toggle underlined text in links (deprecated for 0.14.0) +:CUSTOM_ID: h:a1a639e9-d247-414c-a0ad-08adadcbc6c1 +:END: + +Note: deprecated ahead of version =0.14.0= ([[#h:c119d7b2-fcd4-4e44-890e-5e25733d5e52][Option for links]]). + +Symbol names: + ++ =modus-operandi-theme-no-link-underline= ++ =modus-vivendi-theme-no-link-underline= + +Possible values: + +1. =nil= (default) +2. =t= + +Remove the underline effect from links, symbolic links, and buttons. +The default is to apply an underline. + +** Option for links +:PROPERTIES: +:ALT_TITLE: Link styles +:DESCRIPTION: Choose color intensity or no underline for links +:CUSTOM_ID: h:c119d7b2-fcd4-4e44-890e-5e25733d5e52 +:END: + +This option supersedes the "no link underline" one ahead of version +=0.14.0= ([[#h:a1a639e9-d247-414c-a0ad-08adadcbc6c1][Option for no link underline]]). + +Symbol names: + ++ =modus-operandi-theme-links= ++ =modus-vivendi-theme-links= + +Possible values: + +1. =nil= (default) +2. =faint= +3. =neutral-underline= +4. =faint-neutral-underline= +5. =no-underline= + +The default style (nil) for links is to apply an underline and a +saturated color to the affected text. The color of the two is the +same, which makes the link fairly prominent. + +Option =faint= follows the same approach as the default, but uses less +intense colors. + +Option =neutral-underline= changes the underline's color to a subtle +gray, while retaining the default text color. + +Option =faint-neutral-underline= combines a desaturated text color with a +subtle gray underline. + +Option =no-underline= removes link underlines altogether, while keeping +their text color the same as the default. + +** Option for command prompt styles +:PROPERTIES: +:ALT_TITLE: Command prompts +:DESCRIPTION: Choose among plain, subtle, or intense prompts +:CUSTOM_ID: h:db5a9a7c-2928-4a28-b0f0-6f2b9bd52ba1 +:END: + +Symbol names: + ++ =modus-operandi-theme-prompts= ++ =modus-vivendi-theme-prompts= + +Possible values: + +1. =nil= (default) +2. =subtle= +3. =intense= + +The symbols "subtle" and "intense" will apply a combination of accented +background and foreground to the minibuffer and other REPL prompts (like +=M-x shell= and =M-x eshell=). The difference between the two is that the +latter has a more pronounced/noticeable effect than the former. + +The default does not use any background for such prompts, while relying +exclusively on an accented foreground color. + +** Option for mode line presentation +:PROPERTIES: +:ALT_TITLE: Mode line +:DESCRIPTION: Choose among plain, three-dimension, or moody-compliant styles +:CUSTOM_ID: h:27943af6-d950-42d0-bc23-106e43f50a24 +:END: + +Symbol names: + ++ =modus-operandi-theme-mode-line= ++ =modus-vivendi-theme-mode-line= + +Possible values: + +1. =nil= (default) +2. =3d= +3. =moody= + +The default value (=nil=) produces a two-dimensional effect both for the +active and inactive modelines. The differences between the two are +limited to distinct shades of grayscale values, with the active being +more intense than the inactive. + +A =3d= symbol will make the active modeline look like a three-dimensional +rectangle. Inactive modelines remain 2D, though they are slightly toned +down relative to the default. This aesthetic is the same as what you +get when you run Emacs without any customizations (=emacs -Q= on the +command line). + +While =moody= removes all box effects from the modelines and applies +underline and overline properties instead. It also tones down a bit the +inactive modelines. This is meant to optimize things for use with the +[[https://github.com/tarsius/moody][moody package]] (hereinafter referred to as "Moody"), though it can work +fine even without it. + +Note that Moody does not expose any faces that the themes could style +directly. Instead it re-purposes existing ones to render its tabs and +ribbons. As such, there may be cases where the contrast ratio falls +below the 7:1 target that the themes conform with (WCAG AAA). To hedge +against this, we configure a fallback foreground for the =moody= option, +which will come into effect when the background of the modeline changes +to something less accessible, such as Moody ribbons (read the doc string +of =set-face-attribute=, specifically =:distant-foreground=). This fallback +comes into effect when Emacs determines that the background and +foreground of the given construct are too close to each other in terms +of color distance. In effect, users would need to experiment with the +variable =face-near-same-color-threshold= to trigger the fallback color. +We find that a value of =45000= would suffice, contrary to the default +=30000=. Do not set the value too high, because that would have the +adverse effect of always overriding the default color (which has been +carefully designed to be highly accessible). + +Furthermore, because Moody expects an underline and overline instead of +a box style, it is recommended you also include this in your setup: + +#+begin_src emacs-lisp +(setq x-underline-at-descent-line t) +#+end_src + +** Option for completion framework aesthetics +:PROPERTIES: +:ALT_TITLE: Completion UIs +:DESCRIPTION: Choose among standard, moderate, or opinionated looks +:CUSTOM_ID: h:f1c20c02-7b34-4c35-9c65-99170efb2882 +:END: + +Symbol names: + ++ =modus-operandi-theme-completions= ++ =modus-vivendi-theme-completions= + +Possible values: + +1. =nil= (default) +2. =moderate= +3. =opinionated= + +This is a special option that has different effects depending on the +completion UI. The interfaces can be grouped in two categories, based +on their default aesthetics: (i) those that only or mostly use +foreground colors for their interaction model, and (ii) those that +combine background and foreground values for some of their metaphors. +The former category encompasses Icomplete, Ido, Selectrum as well as +pattern matching styles like Orderless and Flx. The latter covers Helm, +Ivy, and similar. + +A value of =nil= will respect the metaphors of each completion framework. + +The symbol =moderate= will apply a combination of background and +foreground that is fairly subtle. For Icomplete and friends this +constitutes a departure from their default aesthetics, however the +difference is small. While Helm et al will appear slightly different +than their original looks, as they are toned down a bit. + +The symbol =opinionated= will apply color combinations that refashion the +completion UI. For the Icomplete camp this means that intense +background and foreground combinations are used: in effect their looks +emulate those of Ivy and co. in their original style. Whereas the other +group of packages will revert to an even more nuanced aesthetic with +some additional changes to the choice of hues. + +To appreciate the scope of this customization option, you should spend +some time with every one of the =nil= (default), =moderate=, and =opinionated= +possibilities. + +** Option for fringe visibility +:PROPERTIES: +:ALT_TITLE: Fringes +:DESCRIPTION: Choose among plain, subtle, or intense fringe visibility +:CUSTOM_ID: h:1983c3fc-74f6-44f3-b917-967c403bebae +:END: + +Symbol names: + ++ =modus-operandi-theme-fringes= ++ =modus-vivendi-theme-fringes= + +Possible values: + +1. =nil= (default) +2. =subtle= +3. =intense= + +The "subtle" symbol will apply a grayscale background that is visible, +yet close enough to the main background color. While the "intense" +symbol will use a more noticeable grayscale background. + +The default is to use the same color as that of the main background, +meaning that the fringes are not obvious though they still occupy the +space given to them by =fringe-mode=. + +** Option for line highlighting (hl-line-mode) +:PROPERTIES: +:ALT_TITLE: Line highlighting +:DESCRIPTION: Toggle intense style for current line highlighting +:CUSTOM_ID: h:1dba1cfe-d079-4c13-a810-f768e8789177 +:END: + +Symbol names: + ++ =modus-operandi-theme-intense-hl-line= ++ =modus-vivendi-theme-intense-hl-line= + +Possible values: + +1. =nil= (default) +2. =t= + +Draw the current line of =hl-line-mode= or its global equivalent in a more +prominent background color. This would also affect several packages +that enable =hl-line-mode=, such as =elfeed= and =mu4e=. + +The default is to use a more subtle gray. + +** Option for parenthesis matching (show-paren-mode) +:PROPERTIES: +:ALT_TITLE: Matching parentheses +:DESCRIPTION: Toggle intense style for matching delimiters/parentheses +:CUSTOM_ID: h:e66a7e4d-a512-4bc7-9f86-fbbb5923bf37 +:END: + +Symbol names: + ++ =modus-operandi-theme-intense-paren-match= ++ =modus-vivendi-theme-intense-paren-match= + +Possible values: + +1. =nil= (default) +2. =t= + +Apply a more intense background to the matching parentheses (or +delimiters). This affects tools such as the built-in =show-paren-mode=. +The default is to use a subtle warm color for the background of those +overlays. + +** Option for diff buffer looks +:PROPERTIES: +:ALT_TITLE: Diffs +:DESCRIPTION: Choose among intense, desaturated, or text-only diffs +:CUSTOM_ID: h:ea7ac54f-5827-49bd-b09f-62424b3b6427 +:END: + +Symbol names: + ++ =modus-operandi-theme-diffs= ++ =modus-vivendi-theme-diffs= + +Possible values: + +1. =nil= (default) +2. =desaturated= +2. =fg-only= + +By default the themes will apply richly colored backgrounds to the +output of diffs, such as those of =diff-mode=, =ediff=, =smerge-mode=, and +=magit=. These are color combinations of an accented background and +foreground so that, for example, added lines have a pronounced green +background with an appropriate shade of green for the affected text. +Word-wise or "refined" changes follow this pattern but use different +shades of those colors to remain distinct. + +A =desaturated= value tones down all relevant color values. It still +combines an accented background with an appropriate foreground, yet its +overall impression is very subtle. Refined changes are a bit more +intense to fulfil their intended function, though still less saturated +than default. + +While =fg-only= will remove all accented backgrounds and instead rely on +color-coded text to denote changes. For instance, added lines use an +intense green foreground, while their background is the same as the rest +of the buffer. Word-wise highlights still use a background value which +is, nonetheless, more subtle than its default equivalent. + +Concerning =magit=, an extra set of tweaks are introduced for the effect +of highlighting the current diff hunk, so as to remain consistent with +the overall experience of that mode. Expect changes that are consistent +with the overall intent of the aforementioned. + +** Option for org-mode block styles +:PROPERTIES: +:ALT_TITLE: Org mode blocks +:DESCRIPTION: Choose among plain, grayscale, or rainbow styles +:CUSTOM_ID: h:b7e328c0-3034-4db7-9cdf-d5ba12081ca2 +:END: + +Symbol names: + ++ =modus-operandi-theme-org-blocks= ++ =modus-vivendi-theme-org-blocks= + +Possible values: + +1. =nil= (default) +2. =grayscale= +3. =rainbow= + +The default is to use the same background as the rest of the buffer for +the contents of the block. + +A value of =grayscale= will apply a subtle neutral gray background to the +block's contents. It will also extend to the edge of the window the +background of the "begin" and "end" block delimiter lines (only relevant +for Emacs versions >= 27 where the 'extend' keyword is recognised by +=set-face-attribute=). + +While =rainbow= will instead use an accented background for the contents +of the block. The exact color will depend on the programming language +and is controlled by the =org-src-block-faces= variable (refer to the +theme's source code for the current association list). This is most +suitable for users who work on literate programming documents that mix +and match several languages. + +Note that the "rainbow" blocks may require you to also reload the +major-mode so that the colors are applied properly: use =M-x org-mode= or +=M-x org-mode-restart= to refresh the buffer. Or start typing in each +code block (inefficient at scale, but it still works). + +** Option for headings' overall style +:PROPERTIES: +:ALT_TITLE: Heading styles +:DESCRIPTION: Choose among several styles, also per heading level +:CUSTOM_ID: h:271eff19-97aa-4090-9415-a6463c2f9ae1 +:END: + +This is defined as an alist and, therefore, uses a different approach +than other customization options documented in this manual. + +Symbol names: + ++ =modus-operandi-theme-headings= ++ =modus-vivendi-theme-headings= + +Possible values, which can be specified for each heading level (examples +further below): + ++ nil (default fallback option---covers all heading levels) ++ =t= (default style for a single heading, when the fallback differs) ++ =no-bold= ++ =line= ++ =line-no-bold= ++ =rainbow= ++ =rainbow-line= ++ =rainbow-line-no-bold= ++ =highlight= ++ =highlight-no-bold= ++ =rainbow-highlight= ++ =rainbow-highlight-no-bold= ++ =section= ++ =section-no-bold= ++ =rainbow-section= ++ =rainbow-section-no-bold= + +To control faces per level from 1-8, use something like this (same for +=modus-vivendi-theme-headings=): + +#+begin_src emacs-lisp +(setq modus-operandi-theme-headings + '((1 . section) + (2 . line) + (3 . highlight) + (t . rainbow-no-bold))) +#+end_src + +The above uses the =section= value for heading levels 1, the =line= for +headings 2, =highlight= for 3. All other levels fall back to +=rainbow-line-no-bold=. + +To set a uniform value for all heading levels, use this pattern: + +#+begin_src emacs-lisp +;; A given style for every heading +(setq modus-operandi-theme-headings + '((t . rainbow-line-no-bold))) + +;; Default aesthetic for every heading +(setq modus-operandi-theme-headings + '((t . nil))) +#+end_src + +The default style for headings uses a fairly desaturated foreground +value in combination with a bold typographic weight. To specify this +style for a given level N (assuming you wish to have another fallback +option), just specify the value =t= like this: + +#+begin_src emacs-lisp +(setq modus-operandi-theme-headings + '((1 . t) + (2 . line) + (t . rainbow-line-no-bold))) +#+end_src + +A description of all other possible styles: + ++ =no-bold= retains the default text color while removing the typographic + weight. + ++ =line= is the same as the default plus an overline over the heading. + ++ =line-no-bold= is the same as =line= without bold weight. + ++ =rainbow= uses a more colorful foreground in combination with bold + weight. + ++ =rainbow-line= is the same as =rainbow= plus an overline. + ++ =rainbow-line-no-bold= is the same as =rainbow-line= without the bold + weight. + ++ =highlight= retains the default style of a fairly desaturated foreground + combined with a bold weight and adds to it a subtle accented + background. + ++ =highlight-no-bold= is the same as =highlight= without a bold weight. + ++ =rainbow-highlight= is the same as =highlight= but with a more colorful + foreground. + ++ =rainbow-highlight-no-bold= is the same as =rainbow-highlight= without a + bold weight. + ++ =section= retains the default looks and adds to them both an overline + and a slightly accented background. It is, in effect, a combination + of the =line= and =highlight= values. + ++ =section-no-bold= is the same as =section= without a bold weight. + ++ =rainbow-section= is the same as =section= but with a more colorful + foreground. + ++ =rainbow-section-no-bold= is the same as =rainbow-section= without a bold + weight." + +** Option for scaled headings +:PROPERTIES: +:ALT_TITLE: Scaled headings +:DESCRIPTION: Toggle scaling of headings +:CUSTOM_ID: h:075eb022-37a6-41a4-a040-cc189f6bfa1f +:END: + +Symbol names: + ++ =modus-operandi-theme-scale-headings= ++ =modus-vivendi-theme-scale-headings= + +Possible values: + +1. =nil= (default) +2. =t= + +Make headings larger in height relative to the main text. This is +noticeable in modes like Org. The default is to use the same size for +headings and body copy. + +*** Control the scale of headings +:PROPERTIES: +:ALT_TITLE: Scaled heading sizes +:DESCRIPTION: Specify rate of increase for scaled headings +:CUSTOM_ID: h:6868baa1-beba-45ed-baa5-5fd68322ccb3 +:END: + +In addition to toggles for enabling scaled headings, users can also +specify a number of their own. + ++ If it is a floating point, say, =1.5=, it is interpreted as a multiple + of the base font size. This is the recommended method. + ++ If it is an integer, it is read as an absolute font height. The + number is basically the point size multiplied by ten. So if you want + it to be =18pt= you must pass =180=. Please understand that setting an + absolute value is discouraged, as it will break the layout when you + try to change font sizes with the built-in =text-scale-adjust= command + (see [[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations]]). + +Below are the variables in their default values, using the floating +point paradigm. The numbers are very conservative, but you are free to +change them to your liking, such as =1.2=, =1.4=, =1.6=, =1.8=, =2.0=---or use a +resource for finding a consistent scale: + +#+begin_src emacs-lisp +(setq modus-operandi-theme-scale-1 1.05 + modus-operandi-theme-scale-2 1.1 + modus-operandi-theme-scale-3 1.15 + modus-operandi-theme-scale-4 1.2 + modus-operandi-theme-scale-5 1.3) + +(setq modus-vivendi-theme-scale-1 1.05 + modus-vivendi-theme-scale-2 1.1 + modus-vivendi-theme-scale-3 1.15 + modus-vivendi-theme-scale-4 1.2 + modus-vivendi-theme-scale-5 1.3) +#+end_src + +Note that in earlier versions of Org, scaling would only increase the +size of the heading, but not of keywords that were added to it, like +"TODO". The issue has been fixed upstream: +. + +** Option for variable-pitch font in headings +:PROPERTIES: +:ALT_TITLE: Headings' font +:DESCRIPTION: Toggle proportionately spaced fonts in headings +:CUSTOM_ID: h:97caca76-fa13-456c-aef1-a2aa165ea274 +:END: + +Symbol names: + ++ =modus-operandi-theme-variable-pitch-headings= ++ =modus-vivendi-theme-variable-pitch-headings= + +Possible values: + +1. =nil= (default) +2. =t= + +Choose to apply a proportionately spaced, else "variable-pitch", +typeface to headings (such as in Org mode). The default is to use the +main font family. + +[[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations for Org (and others)]]. + +* Advanced customization (do-it-yourself) +:PROPERTIES: +:INDEX: cp +:CUSTOM_ID: h:f4651d55-8c07-46aa-b52b-bed1e53463bb +:END: + +Unlike the predefined customization options which follow a +straightforward pattern of allowing the user to quickly specify their +preference, the themes also provide a more flexible, albeit difficult, +mechanism to control things with precision (see [[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization Options]]). + +This section is of interest only to users who are prepared to maintain +their own local tweaks and who are willing to deal with any possible +incompatibilities between versioned releases of the themes. As such, +they are labelled as "do-it-yourself" or "DIY". + +** Full access to the themes' palette +:PROPERTIES: +:ALT_TITLE: Tweak colors (DIY) +:DESCRIPTION: Declare your own palette overrides +:CUSTOM_ID: h:1487c631-f4fe-490d-8d58-d72ffa3bd474 +:END: + +The variables are: + ++ =modus-operandi-theme-override-colors-alist= ++ =modus-vivendi-theme-override-colors-alist= + +Users can specify an association list that maps the names of color +variables to hexadecimal RGB values (in the form of =#RRGGBB=). This +means that it is possible to override the entire palette or subsets +thereof (see the source code for the actual names and values). + +Example: + +#+begin_src emacs-lisp +;; Redefine the values of those three variables for the given theme +(setq modus-vivendi-theme-override-colors-alist + '(("magenta" . "#ffaabb") + ("magenta-alt" . "#ee88ff") + ("magenta-alt-other" . "#bbaaff"))) +#+end_src + +If you want to be creative, you can define a minor mode that refashions +the themes on demand. The following is a minor mode that gets activated +on demand. We combine it with the function to switch between Modus +Operandi and Modus Vivendi (see [[#h:2a0895a6-3281-4e55-8aa1-8a737555821e][Toggle between the themes on demand]] for +a basic command, and/or [[*Configure options prior to loading][Configure options prior to loading]] for a more +comprehensive setup). + +#+begin_src emacs-lisp +(define-minor-mode modus-themes-alt-mode + "Override Modus themes' palette variables with custom values. + +This is intended as a proof-of-concept. It is, nonetheless, a +perfectly accessible alternative, conforming with the design +principles of the Modus themes. It still is not as good as the +default colors." + :init-value nil + :global t + (if modus-themes-alt-mode + (setq modus-operandi-theme-override-colors-alist + '(("bg-main" . "#fefcf4") + ("bg-dim" . "#faf6ef") + ("bg-alt" . "#f7efe5") + ("bg-hl-line" . "#f4f0e3") + ("bg-active" . "#e8dfd1") + ("bg-inactive" . "#f6ece5") + ("bg-region" . "#c6bab1") + ("bg-header" . "#ede3e0") + ("bg-tab-bar" . "#dcd3d3") + ("bg-tab-active" . "#fdf6eb") + ("bg-tab-inactive" . "#c8bab8") + ("fg-unfocused" . "#55556f")) + modus-vivendi-theme-override-colors-alist + '(("bg-main" . "#100b17") + ("bg-dim" . "#161129") + ("bg-alt" . "#181732") + ("bg-hl-line" . "#191628") + ("bg-active" . "#282e46") + ("bg-inactive" . "#1a1e39") + ("bg-region" . "#393a53") + ("bg-header" . "#202037") + ("bg-tab-bar" . "#262b41") + ("bg-tab-active" . "#120f18") + ("bg-tab-inactive" . "#3a3a5a") + ("fg-unfocused" . "#9a9aab"))) + (setq modus-operandi-theme-override-colors-alist nil + modus-vivendi-theme-override-colors-alist nil))) + +(defun modus-themes-toggle (&optional arg) + "Toggle between `modus-operandi' and `modus-vivendi' themes. + +With optional \\[universal-argument] prefix, enable +`modus-themes-alt-mode' for the loaded theme." + (interactive "P") + (if arg + (modus-themes-alt-mode 1) + (modus-themes-alt-mode -1)) + (if (eq (car custom-enabled-themes) 'modus-operandi) + (progn + (disable-theme 'modus-operandi) + (load-theme 'modus-vivendi t)) + (disable-theme 'modus-vivendi) + (load-theme 'modus-operandi t))) +#+end_src + +** Font configurations for Org (and others) +:PROPERTIES: +:ALT_TITLE: Font configs (DIY) +:DESCRIPTION: Optimise for mixed typeface buffers +:CUSTOM_ID: h:defcf4fc-8fa8-4c29-b12e-7119582cc929 +:END: + +The themes are designed to cope well with mixed font settings ([[#h:115e6c23-ee35-4a16-8cef-e2fcbb08e28b][Option +for no font mixing]]). Currently this applies to =org-mode= and +=markdown-mode=. + +In practice it means that the user can safely opt for a more +prose-friendly proportionately spaced typeface as their default, while +letting spacing-sensitive elements like tables and inline code always +use a monospaced font, by inheriting from the =fixed-pitch= face. + +Users can try the built-in =M-x variable-pitch-mode= to see the effect in +action. + +To make everything use your desired font families, you need to configure +the =variable-pitch= (proportional spacing) and =fixed-pitch= (monospaced) +faces respectively. It may also be convenient to set your main typeface +by configuring the =default= face the same way. + +Put something like this in your initialization file (make sure to read +the documentation of =set-face-attribute=, with =M-x describe-function=): + +#+begin_src emacs-lisp +;; Main typeface +(set-face-attribute 'default nil :family "DejaVu Sans Mono" :height 110) + +;; Proportionately spaced typeface +(set-face-attribute 'variable-pitch nil :family "DejaVu Serif" :height 1.0) + +;; Monospaced typeface +(set-face-attribute 'fixed-pitch nil :family "DejaVu Sans Mono" :height 1.0) +#+end_src + +Note the differences in the =:height= property. The =default= face must +specify an absolute value, which is the point size × 10. So if you want +to use a font at point size =11=, you set the height at =110=.[fn:: =:height= +values do not need to be rounded to multiples of ten: the likes of =115= +are perfectly valid—some typefaces will change to account for those +finer increments.] Whereas every other face must have a value that is +relative to the default, represented as a floating point (if you use an +integer, say, =15= then that means an absolute height). This is of +paramount importance: it ensures that all fonts can scale gracefully +when using something like the =text-scale-adjust= command which only +operates on the base font size (i.e. the =default= face's absolute +height). + +An alternative syntax for the =default= face, is to pass all typeface +parameters directly to a =font= property.[fn:: Has the benefit of +accepting =fontconfig= parameters (GNU/Linux), such as ="DejaVu Sans +Mono-11:hintstyle=hintslight:autohint=false"=. +https://www.freedesktop.org/software/fontconfig/fontconfig-user.html] +Note that here we use a standard point size: + +#+begin_src emacs-lisp +(set-face-attribute 'default nil :font "DejaVu Sans Mono-11") +#+end_src + +Again, remember to only ever specify an absolute height for the =default=. + +** Org user faces (DIY) +:PROPERTIES: +:DESCRIPTION: Extend styles for org-mode keywords and priorities +:CUSTOM_ID: h:89f0678d-c5c3-4a57-a526-668b2bb2d7ad +:END: + +Users of =org-mode= have the option to configure various keywords and +priority cookies to better match their workflow. User options are +=org-todo-keyword-faces= and =org-priority-faces=. + +As those are meant to be custom faces, it would be futile to have the +themes try to guess what each user would want to use, which keywords to +target, and so on. Instead, we can provide guidelines on how to +customize things to one's liking with the intent of retaining the +overall aesthetics of the theme. + +Please bear in mind that the end result of those is not controlled by +the active theme but by how Org maps faces to its constructs. Editing +those while =org-mode= is active requires =M-x org-mode-restart= for changes +to take effect. + +Let us assume you wish to visually differentiate your keywords. You +have something like this: + +#+begin_src emacs-lisp +(setq org-todo-keywords + '((sequence "TODO(t)" "|" "DONE(D)" "CANCEL(C)") + (sequence "MEET(m)" "|" "MET(M)") + (sequence "STUDY(s)" "|" "STUDIED(S)") + (sequence "WRITE(w)" "|" "WROTE(W)"))) +#+end_src + +You could then use a variant of the following to inherit from a face +that uses the styles you want and also to preserve the properties +applied by the =org-todo= face: + +#+begin_src emacs-lisp +(setq org-todo-keyword-faces + '(("MEET" . '(font-lock-preprocessor-face org-todo)) + ("STUDY" . '(font-lock-variable-name-face org-todo)) + ("WRITE" . '(font-lock-type-face org-todo)))) +#+end_src + +This will refashion the keywords you specify, while letting the other +items in =org-todo-keywords= use their original styles (which are defined +in the =org-todo= and =org-done= faces). + +If you want back the defaults, try specifying just the =org-todo= face: + +#+begin_src emacs-lisp +(setq org-todo-keyword-faces + '(("MEET" . org-todo) + ("STUDY" . org-todo) + ("WRITE" . org-todo))) +#+end_src + +When you inherit from multiple faces, you need to quote the list as +shown further above. The order is important: the last item is applied +over the previous ones. If you do not want to blend multiple faces, you +do not need a quoted list. A pattern of =keyword . face= would suffice. + +Both approaches can be used simultaneously, as illustrated in this +configuration of the priority cookies: + +#+begin_src emacs-lisp +(setq org-priority-faces + '((?A . '(org-scheduled-today org-priority)) + (?B . org-priority) + (?C . '(shadow org-priority)))) +#+end_src + +To find all the faces that are loaded in your current Emacs session, use +=M-x list-faces-display=. Also try =M-x describe-variable= and then specify +the name of each of those Org variables demonstrated above. Their +documentation strings will offer you further guidance. + +Furthermore, consider reading the "Notes for aspiring Emacs theme +developers", published on 2020-08-28 by me (Protesilaos Stavrou): +https://protesilaos.com/codelog/2020-08-28-notes-emacs-theme-devs/. + +* Face coverage +:PROPERTIES: +:CUSTOM_ID: h:a9c8f29d-7f72-4b54-b74b-ddefe15d6a19 +:END: + +Modus Operandi and Modus Vivendi try to provide as close to full face +coverage as possible. This is necessary to ensure a consistently +accessible reading experience across all possible interfaces. + +** Full support for packages or face groups +:PROPERTIES: +:ALT_TITLE: Supported packages +:DESCRIPTION: Full list of covered face groups +:CUSTOM_ID: h:60ed4275-60d6-49f8-9287-9a64e54bea0e +:END: + +This list will always be updated to reflect the current state of the +project. The idea is to offer an overview of the known status of all +affected face groups. The items with an appended asterisk =*= tend to +have lots of extensions, so the "full support" may not be 100% true… + ++ ace-window ++ ag ++ alert ++ all-the-icons ++ annotate ++ anzu ++ apropos ++ apt-sources-list ++ artbollocks-mode ++ auctex and TeX ++ auto-dim-other-buffers ++ avy ++ awesome-tray ++ binder ++ bm ++ bongo ++ boon ++ breakpoint (provided by the built-in =gdb-mi.el= library) ++ buffer-expose ++ calendar and diary ++ calfw ++ centaur-tabs ++ change-log and log-view (such as =vc-print-log= and =vc-print-root-log=) ++ cider ++ circe ++ color-rg ++ column-enforce-mode ++ company-mode* ++ company-posframe ++ compilation-mode ++ completions ++ counsel* ++ counsel-css ++ counsel-notmuch ++ counsel-org-capture-string ++ cov ++ cperl-mode ++ csv-mode ++ ctrlf ++ custom (=M-x customize=) ++ dap-mode ++ dashboard (emacs-dashboard) ++ deadgrep ++ debbugs ++ define-word ++ deft ++ dictionary ++ diff-hl ++ diff-mode ++ dim-autoload ++ dir-treeview ++ dired ++ dired-async ++ dired-git ++ dired-git-info ++ dired-narrow ++ dired-subtree ++ diredfl ++ disk-usage ++ doom-modeline ++ dynamic-ruler ++ easy-jekyll ++ easy-kill ++ ebdb ++ ediff ++ eglot ++ el-search ++ eldoc-box ++ elfeed ++ elfeed-score ++ emms ++ enhanced-ruby-mode ++ epa ++ equake ++ erc ++ eros ++ ert ++ eshell ++ eshell-fringe-status ++ eshell-git-prompt ++ eshell-prompt-extras (epe) ++ eshell-syntax-highlighting ++ evil* (evil-mode) ++ evil-goggles ++ evil-visual-mark-mode ++ eww ++ eyebrowse ++ fancy-dabbrev ++ flycheck ++ flycheck-color-mode-line ++ flycheck-indicator ++ flycheck-posframe ++ flymake ++ flyspell ++ flyspell-correct ++ flx ++ freeze-it ++ frog-menu ++ focus ++ fold-this ++ font-lock (generic syntax highlighting) ++ forge ++ fountain (fountain-mode) ++ geiser ++ git-commit ++ git-gutter (and variants) ++ git-lens ++ git-rebase ++ git-timemachine ++ git-walktree ++ gnus ++ golden-ratio-scroll-screen ++ helm* ++ helm-ls-git ++ helm-switch-shell ++ helm-xref ++ helpful ++ highlight-blocks ++ highlight-defined ++ highlight-escape-sequences (=hes-mode=) ++ highlight-indentation ++ highlight-numbers ++ highlight-symbol ++ highlight-tail ++ highlight-thing ++ hl-defined ++ hl-fill-column ++ hl-line-mode ++ hl-todo ++ hydra ++ hyperlist ++ ibuffer ++ icomplete ++ icomplete-vertical ++ ido-mode ++ iedit ++ iflipb ++ imenu-list ++ indium ++ info ++ info-colors ++ interaction-log ++ ioccur ++ isearch, occur, etc. ++ ivy* ++ ivy-posframe ++ jira (org-jira) ++ journalctl-mode ++ js2-mode ++ julia ++ jupyter ++ kaocha-runner ++ keycast ++ line numbers (=display-line-numbers-mode= and global variant) ++ lsp-mode ++ lsp-ui ++ magit ++ magit-imerge ++ make-mode ++ man ++ markdown-mode ++ markup-faces (=adoc-mode=) ++ mentor ++ messages ++ minibuffer-line ++ minimap ++ modeline ++ mood-line ++ moody ++ mpdel ++ mu4e ++ mu4e-conversation ++ multiple-cursors ++ neotree ++ no-emoji ++ notmuch ++ num3-mode ++ nxml-mode ++ objed ++ orderless ++ org* ++ org-journal ++ org-noter ++ org-pomodoro ++ org-recur ++ org-roam ++ org-superstar ++ org-table-sticky-header ++ org-treescope ++ origami ++ outline-mode ++ outline-minor-faces ++ package (=M-x list-packages=) ++ page-break-lines ++ paradox ++ paren-face ++ parrot ++ pass ++ pdf-tools ++ persp-mode ++ perspective ++ phi-grep ++ phi-search ++ pkgbuild-mode ++ pomidor ++ popup ++ powerline ++ powerline-evil ++ proced ++ prodigy ++ racket-mode ++ rainbow-blocks ++ rainbow-identifiers ++ rainbow-delimiters ++ rcirc ++ regexp-builder (also known as =re-builder=) ++ rg (rg.el) ++ ripgrep ++ rmail ++ ruler-mode ++ sallet ++ selectrum ++ semantic ++ sesman ++ shell-script-mode ++ show-paren-mode ++ shr ++ side-notes ++ sieve-mode ++ skewer-mode ++ smart-mode-line ++ smartparens ++ smerge ++ spaceline ++ speedbar ++ spell-fu ++ stripes ++ suggest ++ switch-window ++ swiper ++ swoop ++ sx ++ symbol-overlay ++ syslog-mode ++ table (built-in table.el) ++ telephone-line ++ term ++ tomatinho ++ transient (pop-up windows such as Magit's) ++ trashed ++ treemacs ++ tty-menu ++ tuareg ++ typescript ++ undo-tree ++ vc (built-in mode line status for version control) ++ vc-annotate (=C-x v g=) ++ vdiff ++ vimish-fold ++ visible-mark ++ visual-regexp ++ volatile-highlights ++ vterm ++ wcheck-mode ++ web-mode ++ wgrep ++ which-function-mode ++ which-key ++ whitespace-mode ++ window-divider-mode ++ winum ++ writegood-mode ++ woman ++ xah-elisp-mode ++ xref ++ xterm-color (and ansi-colors) ++ yaml-mode ++ yasnippet ++ ztree + +Plus many other miscellaneous faces that are provided by the upstream +GNU Emacs distribution. + +** Indirectly covered packages +:PROPERTIES: +:CUSTOM_ID: h:2cb359c7-3a84-4262-bab3-dcdc1d0034d7 +:END: + +These do not require any extra styles because they are configured to +inherit from some basic faces. Please confirm. + ++ edit-indirect ++ evil-owl ++ i3wm-config-mode ++ perl-mode ++ php-mode ++ rjsx-mode ++ swift-mode + +** Will NOT be supported +:PROPERTIES: +:CUSTOM_ID: h:6c6e8d94-6782-47fc-9eef-ad78671e9eea +:END: + +I have thus far identified a single package that does fit into the +overarching objective of this project: [[https://github.com/hlissner/emacs-solaire-mode][solaire]]. It basically tries to +cast a less intense background on the main file-visiting buffers, so +that secondary elements like sidebars can have the default (pure +white/black) background. + +I will only cover this package if it ever supports the inverse effect: +less intense colors (but still accessible) for ancillary interfaces +and the intended styles for the content you are actually working on. + +* Notes for individual packages +:PROPERTIES: +:CUSTOM_ID: h:4c4d901a-84d7-4f20-bd99-0808c2b06eba +:END: + +This section covers information that may be of interest to users of +individual packages. + +** Note on company-mode overlay pop-up +:PROPERTIES: +:CUSTOM_ID: h:20cef8c4-d11f-4053-8b2c-2872925780b1 +:END: + +By default, the =company-mode= pop-up that lists completion candidates is +drawn using an overlay. This creates alignment issues every time it is +placed above a piece of text that has a different height than the +default. + +The solution recommended by the project's maintainer is to use an +alternative front-end for drawing the pop-up which uses child frames +instead of overlays.[fn:: +https://github.com/company-mode/company-mode/issues/1010][fn:: +https://github.com/tumashu/company-posframe/] + +** Note for ERC escaped color sequences +:PROPERTIES: +:CUSTOM_ID: h:98bdf319-1e32-4469-8a01-771200fba65c +:END: + +The built-in IRC client =erc= has the ability to colorise any text using +escape sequences that start with =^C= (inserted with =C-q C-c=) and are +followed by a number for the foreground and background.[fn:: This page +explains the basics, though it is not specific to Emacs: +https://www.mirc.com/colors.html] Possible numbers are 0-15, with the +first entry being the foreground and the second the background, +separated by a comma. Like this =^C1,6=. The minimum setup is this: + +#+begin_src emacs-lisp +(add-to-list 'erc-modules 'irccontrols) +(setq erc-interpret-controls-p t + erc-interpret-mirc-color t) +#+end_src + +As this allows users to make arbitrary combinations, it is impossible to +guarantee a consistently high contrast ratio. All we can we do is +provide guidance on the combinations that satisfy the accessibility +standard of the themes: + ++ Modus Operandi :: Use foreground color 1 for all backgrounds from + 2-15. Like so: =C-q C-c1,N= where =N= is the background. + ++ Modus Vivendi :: Use foreground color 0 for all backgrounds from + 2-13. Use foreground =1= for backgrounds 14, 15. + +Colors 0 and 1 are white and black respectively. So combine them +together, if you must. + +** Note for powerline or spaceline +:PROPERTIES: +:CUSTOM_ID: h:9130a8ba-d8e3-41be-a58b-3cb1eb7b6d17 +:END: + +Both Powerline and Spaceline package users will likely need to use the +command =powerline-reset= whenever they make changes to their themes +and/or modeline setup. + +** Note on shr colors +:PROPERTIES: +:CUSTOM_ID: h:4cc767dc-ffef-4c5c-9f10-82eb7b8921bf +:END: + +Emacs' HTML rendering mechanism (=shr=) may need explicit configuration to +respect the theme's colors instead of whatever specifications the +webpage provides. Consult =C-h v shr-use-colors=. + +** Note for Helm grep +:PROPERTIES: +:CUSTOM_ID: h:d28879a2-8e4b-4525-986e-14c0f873d229 +:END: + +There is one face from the Helm package that is meant to highlight the +matches of a grep or grep-like command (=ag= or =ripgrep=). It is +=helm-grep-match=. However, this face can only apply when the user does +not pass =--color=always= as a command-line option for their command. + +Here is the docstring for that face, which is defined in the +=helm-grep.el= library (view a library with =M-x find-library=). + +#+begin_quote +Face used to highlight grep matches. Have no effect when grep backend +use "--color=" +#+end_quote + +The user must either remove =--color= from the flags passed to the grep +function, or explicitly use =--color=never= (or equivalent). Helm +provides user-facing customization options for controlling the grep +function's parameters, such as =helm-grep-default-command= and +=helm-grep-git-grep-command=. + +When =--color=always= is in effect, the grep output will use red text in +bold letter forms to present the matching part in the list of +candidates. That style still meets the contrast ratio target of >= 7:1 +(accessibility standard WCAG AAA), because it draws the reference to +ANSI color number 1 (red) from the already-supported array of +=ansi-color-names-vector=. + +** Note on vc-annotate-background-mode +:PROPERTIES: +:CUSTOM_ID: h:5095cbd1-e17a-419c-93e8-951c186362a3 +:END: + +Due to the unique way =vc-annotate= (=C-x v g=) applies colors, support for +its background mode (=vc-annotate-background-mode=) is disabled at the +theme level. + +Normally, such a drastic measure should not belong in a theme: assuming +the user's preferences is bad practice. However, it has been deemed +necessary in the interest of preserving color contrast accessibility +while still supporting a useful built-in tool. + +If there actually is a way to avoid such a course of action, without +prejudice to the accessibility standard of this project, then please +report as much or send patches (see [[#h:9c3cd842-14b7-44d7-84b2-a5c8bc3fc3b1][Contributing]]). + +* Contributing +:PROPERTIES: +:CUSTOM_ID: h:9c3cd842-14b7-44d7-84b2-a5c8bc3fc3b1 +:END: + +This section documents the canonical sources of the themes and the ways +in which you can contribute to their ongoing development. + +** Sources of the themes +:PROPERTIES: +:CUSTOM_ID: h:89504f1c-c9a1-4bd9-ab39-78fd0eddb47c +:END: + +The =modus-operandi= and =modus-vivendi= themes are built into Emacs. +Currently they are in the project's =master= branch, which is tracking the +next development release target. + +The source code of the themes is [[https://gitlab.com/protesilaos/modus-themes/][available on Gitlab]], for the time +being. A [[https://github.com/protesilaos/modus-themes/][mirror on Github]] is also on offer. + +An HTML version of this manual is available as an extension to the +[[https://protesilaos.com/modus-themes/][author's personal website]] (does not rely on any non-free code). + +** Issues you can help with +:PROPERTIES: +:CUSTOM_ID: h:6536c8d5-3f98-43ab-a787-b94120e735e8 +:END: + +A few tasks you can help with: + ++ Suggest refinements to packages that are covered. ++ Report packages not covered thus far. ++ Report bugs, inconsistencies, shortcomings. ++ Help expand the documentation of covered-but-not-styled packages. ++ Suggest refinements to the color palette. ++ Help expand this document or any other piece of documentation. ++ Merge requests for code refinements. + +[[#h:111773e2-f26f-4b68-8c4f-9794ca6b9633][Patches require copyright assignment to the FSF]]. + +It would be great if your feedback also includes some screenshots, GIFs, +or short videos, as well as further instructions to reproduce a given +setup. Though this is not a requirement. + +Whatever you do, bear in mind the overarching objective of the Modus +themes: to keep a contrast ratio that is greater or equal to 7:1 between +background and foreground colors. If a compromise is ever necessary +between aesthetics and accessibility, it shall always be made in the +interest of the latter. + +** Patches require copyright assignment to the FSF +:PROPERTIES: +:ALT_TITLE: Merge requests +:DESCRIPTION: Legal considerations for code patches +:CUSTOM_ID: h:111773e2-f26f-4b68-8c4f-9794ca6b9633 +:END: + +Code contributions are most welcome. For any major edit (more than 15 +lines, or so, in aggregate per person), you need to make a copyright +assignment to the Free Software Foundation. This is necessary because +the themes are part of the upstream Emacs distribution: the FSF must at +all times be in a position to enforce the GNU General Public License. + +Copyright assignment is a simple process. Check the request form below +(please adapt it accordingly). You must write an email to the address +mentioned in the form and then wait for the FSF to send you a legal +agreement. Sign the document and file it back to them. This could all +happen via email and take about a week. You are encouraged to go +through this process. You only need to do it once. It will allow you +to make contributions to Emacs in general. + +#+begin_example text +Please email the following information to assign@gnu.org, and we +will send you the assignment form for your past and future changes. + +Please use your full legal name (in ASCII characters) as the subject +line of the message. +---------------------------------------------------------------------- +REQUEST: SEND FORM FOR PAST AND FUTURE CHANGES + +[What is the name of the program or package you're contributing to?] + +GNU Emacs + +[Did you copy any files or text written by someone else in these changes? +Even if that material is free software, we need to know about it.] + +Copied a few snippets from the same files I edited. Their author, +Protesilaos Stavrou, has already assigned copyright to the Free Software +Foundation. + +[Do you have an employer who might have a basis to claim to own +your changes? Do you attend a school which might make such a claim?] + + +[For the copyright registration, what country are you a citizen of?] + + +[What year were you born?] + + +[Please write your email address here.] + + +[Please write your postal address here.] + + + + + +[Which files have you changed so far, and which new files have you written +so far?] + +Changed a couple of themes that are part of the Emacs source code: + +./etc/themes/modus-operandi-theme.el +./etc/themes/modus-vivendi-theme.el +#+end_example + +* Acknowledgements +:PROPERTIES: +:CUSTOM_ID: h:95c3da23-217f-404e-b5f3-56c75760ebcf +:END: + +The Modus themes are a collective effort. Every contribution counts. + ++ Author/maintainer :: Protesilaos Stavrou. + ++ Contributions to code or documentation :: Anders Johansson, Basil + L. Contovounesios, Eli Zaretskii, Madhavan Krishnan, Markus Beppler, + Matthew Stevenson, Shreyas Ragavan, Stefan Kangas, Vincent Murphy. + ++ Ideas and user feedback :: Aaron Jensen, Adam Spiers, Alex Griffin, + Alex Peitsinis, Alexey Shmalko, Anders Johansson, André Alexandre + Gomes, Arif Rezai, Basil L. Contovounesios, Damien Cassou, Dario + Gjorgjevski, David Edmondson, Davor Rotim, Divan Santana, Gerry + Agbobada, Gianluca Recchia, Ilja Kocken, Iris Garcia, Len Trigg, + Manuel Uberti, Mark Burton, Markus Beppler, Michael Goldenberg, Murilo + Pereira, Nicolas De Jaeghere, Paul Poloskov, Pierre Téchoueyres, Roman + Rudakov, Ryan Phillips, Shreyas Ragavan, Simon Pugnet, Tassilo Horn, + Thibaut Verron, Trey Merkley, Togan Muftuoglu, Uri Sharf, Utkarsh + Singh, Vincent Foley. As well as users: Ben, Eugene, Fourchaux, + Fredrik, Moesasji, Nick, TheBlob42, bepolymathe, dinko, doolio, + jixiuf, okamsn, tycho garen. + ++ Packaging :: Dhavan Vaidya (Debian), Stefan Kangas (core Emacs), + Stefan Monnier (GNU Elpa). + ++ Inspiration for certain features :: Bozhidar Batsov (zenburn-theme), + Fabrice Niessen (leuven-theme). + +* Meta +:PROPERTIES: +:CUSTOM_ID: h:13752581-4378-478c-af17-165b6e76bc1b +:END: + +If you are curious about the principles that govern the development of +this project read the essay [[https://protesilaos.com/codelog/2020-03-17-design-modus-themes-emacs/][On the design of the Modus themes]] +(2020-03-17). + +Here are some more publications for those interested in the kind of work +that goes into this project (sometimes the commits also include details +of this sort): + ++ [[https://protesilaos.com/codelog/2020-05-10-modus-operandi-palette-review/][Modus Operandi theme subtle palette review]] (2020-05-10) ++ [[https://protesilaos.com/codelog/2020-06-13-modus-vivendi-palette-review/][Modus Vivendi theme subtle palette review]] (2020-06-13) ++ [[https://protesilaos.com/codelog/2020-07-04-modus-themes-faint-colours/][Modus themes: new "faint syntax" option]] (2020-07-04) ++ [[https://protesilaos.com/codelog/2020-07-08-modus-themes-nuanced-colours/][Modus themes: major review of "nuanced" colours]] (2020-07-08) ++ [[https://protesilaos.com/codelog/2020-09-14-modus-themes-review-blues/][Modus themes: review of blue colours]] (2020-09-14) + +And here are the canonical sources for this project's documentation: + ++ Manual :: ++ Change Log :: ++ Screenshots :: + +* External projects (ports) +:PROPERTIES: +:CUSTOM_ID: h:21adb7c8-2208-41e8-803c-052e42e2c05d +:END: + +The present section documents projects that extend the scope of the +Modus themes. The following list will be updated whenever relevant +information is brought to my attention. If you already have or intend +to produce such a port, feel welcome [[https://protesilaos.com/contact][to contact me]]. + ++ Modus exporter :: This is [[https://github.com/polaris64/modus-exporter][an Elisp library written by Simon Pugnet]]. + Licensed under the terms of the GNU General Public License. It is + meant to capture the color values of the active Modus theme (Operandi + or Vivendi) and output it as a valid theme for some other application. + +* GNU Free Documentation License +:PROPERTIES: +:APPENDIX: t +:CUSTOM_ID: h:3077c3d2-7f90-4228-8f0a-73124f4026f6 +:END: + +#+INCLUDE: fdl-1.3.txt src txt commit 3b1fb6186b2ddc0b34103cffa8bb6c1607926acd Author: Stefan Kangas Date: Sat Feb 27 03:23:39 2021 +0100 Use lexical-binding in progmodes/icon.el * lisp/progmodes/icon.el: Use lexical-binding. (electric-icon-brace): Very minor cleanup. diff --git a/lisp/progmodes/icon.el b/lisp/progmodes/icon.el index d81fe1c753..e9a21d4a0c 100644 --- a/lisp/progmodes/icon.el +++ b/lisp/progmodes/icon.el @@ -1,4 +1,4 @@ -;;; icon.el --- mode for editing Icon code +;;; icon.el --- mode for editing Icon code -*- lexical-binding: t -*- ;; Copyright (C) 1989, 2001-2021 Free Software Foundation, Inc. @@ -197,12 +197,11 @@ with no args, if that value is non-nil." (progn (insert last-command-event) (icon-indent-line) - (if icon-auto-newline - (progn - (newline) - ;; (newline) may have done auto-fill - (setq insertpos (- (point) 2)) - (icon-indent-line))) + (when icon-auto-newline + (newline) + ;; (newline) may have done auto-fill + (setq insertpos (- (point) 2)) + (icon-indent-line)) (save-excursion (if insertpos (goto-char (1+ insertpos))) (delete-char -1)))) commit 9abee2acda2aacf96f770a43a8707a6e45b3ac32 Author: Stefan Kangas Date: Sat Feb 27 03:14:04 2021 +0100 Convert change-log-mode menu to easy-menu-define * lisp/vc/add-log.el (change-log-mode-map): Move menu from here... (change-log-mode-menu): ...to here; convert to easy-menu-define. diff --git a/lisp/vc/add-log.el b/lisp/vc/add-log.el index fafd7f9c46..6b38806651 100644 --- a/lisp/vc/add-log.el +++ b/lisp/vc/add-log.el @@ -569,29 +569,27 @@ Compatibility function for \\[next-error] invocations." (select-window change-log-find-window))))) (defvar change-log-mode-map - (let ((map (make-sparse-keymap)) - (menu-map (make-sparse-keymap))) + (let ((map (make-sparse-keymap))) (define-key map [?\C-c ?\C-p] #'add-log-edit-prev-comment) (define-key map [?\C-c ?\C-n] #'add-log-edit-next-comment) (define-key map [?\C-c ?\C-f] #'change-log-find-file) (define-key map [?\C-c ?\C-c] #'change-log-goto-source) - (define-key map [menu-bar changelog] (cons "ChangeLog" menu-map)) - (define-key menu-map [gs] - '(menu-item "Go To Source" change-log-goto-source - :help "Go to source location of ChangeLog tag near point")) - (define-key menu-map [ff] - '(menu-item "Find File" change-log-find-file - :help "Visit the file for the change under point")) - (define-key menu-map [sep] '("--")) - (define-key menu-map [nx] - '(menu-item "Next Log-Edit Comment" add-log-edit-next-comment - :help "Cycle forward through Log-Edit mode comment history")) - (define-key menu-map [pr] - '(menu-item "Previous Log-Edit Comment" add-log-edit-prev-comment - :help "Cycle backward through Log-Edit mode comment history")) map) "Keymap for Change Log major mode.") +(easy-menu-define change-log-mode-menu change-log-mode-map + "Menu for Change Log major mode." + '("ChangeLog" + ["Previous Log-Edit Comment" add-log-edit-prev-comment + :help "Cycle backward through Log-Edit mode comment history"] + ["Next Log-Edit Comment" add-log-edit-next-comment + :help "Cycle forward through Log-Edit mode comment history"] + "---" + ["Find File" change-log-find-file + :help "Visit the file for the change under point"] + ["Go To Source" change-log-goto-source + :help "Go to source location of ChangeLog tag near point"])) + ;; It used to be called change-log-time-zone-rule but really should be ;; called add-log-time-zone-rule since it's only used from add-log-* code. (defvaralias 'change-log-time-zone-rule 'add-log-time-zone-rule) commit a350ae058caedcb7be7d332564817954e3624e60 Author: Stefan Monnier Date: Fri Feb 26 20:24:52 2021 -0500 * lisp/emacs-lisp/cconv.el: Improve line-nb info of unused var warnings Instead of warning about unused vars during the analysis phase of closure conversion, do it in the actual closure conversion by annotating the code with "unused" warnings, so that the warnings get emitted later by the bytecomp phase, like all other warnings, at which point the line-number info is a bit less imprecise. Take advantage of this change to wrap the expressions of unused let-bound vars inside (ignore ...) so the byte-compiler can better optimize them away. Finally, promote `macroexp--warn-and-return` to "official" status by removing its "--" marker. (cconv-captured+mutated, cconv-lambda-candidates): Remove vars. (cconv-var-classification): New var to replace them. (cconv-warnings-only): Delete function. (cconv--warn-unused-msg, cconv--var-classification): New functions. (cconv--convert-funcbody): Add warnings for unused args. (cconv-convert): Add warnings for unused vars in `let` and `condition-case`. (cconv--analyze-use): Don't emit an "unused var" warning any more, but instead remember the fact in `cconv-var-classification`. * lisp/emacs-lisp/bytecomp.el (byte-compile-force-lexical-warnings): Remove variable. (byte-compile-preprocess): Remove corresponding case. * lisp/emacs-lisp/pcase.el (pcase--if): Don't throw away `test` effects. (\`): * lisp/emacs-lisp/cl-macs.el (cl--do-arglist): Use `car-safe` instead of `car`, so it can more easily be removed by the optimizer if the result is not used. * lisp/emacs-lisp/macroexp.el (macroexp--warn-wrap): New function. (macroexp-warn-and-return): Rename from `macroexp--warn-and-return`. diff --git a/etc/NEWS b/etc/NEWS index f8f41e21e2..cb307675d1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -374,6 +374,10 @@ the buffer cycles the whole buffer between "only top-level headings", *** New function 'macroexp-file-name' to know the name of the current file --- *** New function 'macroexp-compiling-p' to know if we're compiling. +--- +*** New function 'macroexp-warn-and-return' to help emit warnings. +This used to be named 'macroexp--warn-and-return' and has proved useful +and well-behaved enough to lose the "internal" marker. ** 'blink-cursor-mode' is now enabled by default regardless of the UI. It used to be enabled when Emacs is started in GUI mode but not when started diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index 6451d7fb62..119d39713f 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el @@ -247,7 +247,7 @@ The return value is undefined. #'(lambda (x) (let ((f (cdr (assq (car x) macro-declarations-alist)))) (if f (apply (car f) name arglist (cdr x)) - (macroexp--warn-and-return + (macroexp-warn-and-return (format-message "Unknown macro property %S in %S" (car x) name) @@ -320,7 +320,7 @@ The return value is undefined. body))) nil) (t - (macroexp--warn-and-return + (macroexp-warn-and-return (format-message "Unknown defun property `%S' in %S" (car x) name) nil))))) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 7aae8c0c6a..f85979579f 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2422,8 +2422,6 @@ list that represents a doc string reference. byte-compile-output nil byte-compile-jump-tables nil)))) -(defvar byte-compile-force-lexical-warnings nil) - (defun byte-compile-preprocess (form &optional _for-effect) (setq form (macroexpand-all form byte-compile-macro-environment)) ;; FIXME: We should run byte-optimize-form here, but it currently does not @@ -2434,7 +2432,6 @@ list that represents a doc string reference. ;; (setq form (byte-optimize-form form for-effect))) (cond (lexical-binding (cconv-closure-convert form)) - (byte-compile-force-lexical-warnings (cconv-warnings-only form)) (t form))) ;; byte-hunk-handlers cannot call this! diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el index e79583974a..7b525b72bd 100644 --- a/lisp/emacs-lisp/cconv.el +++ b/lisp/emacs-lisp/cconv.el @@ -121,19 +121,22 @@ (defconst cconv-liftwhen 6 "Try to do lambda lifting if the number of arguments + free variables is less than this number.") -;; List of all the variables that are both captured by a closure -;; and mutated. Each entry in the list takes the form -;; (BINDER . PARENTFORM) where BINDER is the (VAR VAL) that introduces the -;; variable (or is just (VAR) for variables not introduced by let). -(defvar cconv-captured+mutated) - -;; List of candidates for lambda lifting. -;; Each candidate has the form (BINDER . PARENTFORM). A candidate -;; is a variable that is only passed to `funcall' or `apply'. -(defvar cconv-lambda-candidates) - -;; Alist associating to each function body the list of its free variables. -(defvar cconv-freevars-alist) +(defvar cconv-var-classification + ;; Alist mapping variables to a given class. + ;; The keys are of the form (BINDER . PARENTFORM) where BINDER + ;; is the (VAR VAL) that introduces it (or is just (VAR) for variables + ;; not introduced by let). + ;; The class can be one of: + ;; - :unused + ;; - :lambda-candidate + ;; - :captured+mutated + ;; - nil for "normal" variables, which would then just not appear + ;; in the alist at all. + ) + +(defvar cconv-freevars-alist + ;; Alist associating to each function body the list of its free variables. + ) ;;;###autoload (defun cconv-closure-convert (form) @@ -144,25 +147,13 @@ is less than this number.") Returns a form where all lambdas don't have any free variables." ;; (message "Entering cconv-closure-convert...") (let ((cconv-freevars-alist '()) - (cconv-lambda-candidates '()) - (cconv-captured+mutated '())) + (cconv-var-classification '())) ;; Analyze form - fill these variables with new information. (cconv-analyze-form form '()) (setq cconv-freevars-alist (nreverse cconv-freevars-alist)) (prog1 (cconv-convert form nil nil) ; Env initially empty. (cl-assert (null cconv-freevars-alist))))) -;;;###autoload -(defun cconv-warnings-only (form) - "Add the warnings that closure conversion would encounter." - (let ((cconv-freevars-alist '()) - (cconv-lambda-candidates '()) - (cconv-captured+mutated '())) - ;; Analyze form - fill these variables with new information. - (cconv-analyze-form form '()) - ;; But don't perform the closure conversion. - form)) - (defconst cconv--dummy-var (make-symbol "ignored")) (defun cconv--set-diff (s1 s2) @@ -261,28 +252,55 @@ Returns a form where all lambdas don't have any free variables." (nthcdr 3 mapping))))) new-env)) +(defun cconv--warn-unused-msg (var varkind) + (unless (or ;; Uninterned symbols typically come from macro-expansion, so + ;; it is often non-trivial for the programmer to avoid such + ;; unused vars. + (not (intern-soft var)) + (eq ?_ (aref (symbol-name var) 0)) + ;; As a special exception, ignore "ignore". + (eq var 'ignored)) + (let ((suggestions (help-uni-confusable-suggestions (symbol-name var)))) + (format "Unused lexical %s `%S'%s" + varkind var + (if suggestions (concat "\n " suggestions) ""))))) + +(define-inline cconv--var-classification (binder form) + (inline-quote + (alist-get (cons ,binder ,form) cconv-var-classification + nil nil #'equal))) + (defun cconv--convert-funcbody (funargs funcbody env parentform) "Run `cconv-convert' on FUNCBODY, the forms of a lambda expression. PARENTFORM is the form containing the lambda expression. ENV is a lexical environment (same format as for `cconv-convert'), not including FUNARGS, the function's argument list. Return a list of converted forms." - (let ((letbind ())) + (let ((wrappers ())) (dolist (arg funargs) - (if (not (member (cons (list arg) parentform) cconv-captured+mutated)) - (if (assq arg env) (push `(,arg . nil) env)) - (push `(,arg . (car-safe ,arg)) env) - (push `(,arg (list ,arg)) letbind))) + (pcase (cconv--var-classification (list arg) parentform) + (:captured+mutated + (push `(,arg . (car-safe ,arg)) env) + (push (lambda (body) `(let ((,arg (list ,arg))) ,body)) wrappers)) + ((and :unused + (let (and (pred stringp) msg) + (cconv--warn-unused-msg arg "argument"))) + (if (assq arg env) (push `(,arg . nil) env)) ;FIXME: Is it needed? + (push (lambda (body) `(macroexp--warn-wrap ,msg ,body)) wrappers)) + (_ + (if (assq arg env) (push `(,arg . nil) env))))) (setq funcbody (mapcar (lambda (form) (cconv-convert form env nil)) funcbody)) - (if letbind + (if wrappers (let ((special-forms '())) ;; Keep special forms at the beginning of the body. (while (or (stringp (car funcbody)) ;docstring. (memq (car-safe (car funcbody)) '(interactive declare))) (push (pop funcbody) special-forms)) - `(,@(nreverse special-forms) (let ,letbind . ,funcbody))) + (let ((body (macroexp-progn funcbody))) + (dolist (wrapper wrappers) (setq body (funcall wrapper body))) + `(,@(nreverse special-forms) ,@(macroexp-unprogn body)))) funcbody))) (defun cconv-convert (form env extend) @@ -340,46 +358,58 @@ places where they originally did not directly appear." (setq value (cadr binder)) (car binder))) (new-val - (cond - ;; Check if var is a candidate for lambda lifting. - ((and (member (cons binder form) cconv-lambda-candidates) - (progn - (cl-assert (and (eq (car value) 'function) - (eq (car (cadr value)) 'lambda))) - (cl-assert (equal (cddr (cadr value)) - (caar cconv-freevars-alist))) - ;; Peek at the freevars to decide whether to λ-lift. - (let* ((fvs (cdr (car cconv-freevars-alist))) - (fun (cadr value)) - (funargs (cadr fun)) - (funcvars (append fvs funargs))) + (pcase (cconv--var-classification binder form) + ;; Check if var is a candidate for lambda lifting. + ((and :lambda-candidate + (guard + (progn + (cl-assert (and (eq (car value) 'function) + (eq (car (cadr value)) 'lambda))) + (cl-assert (equal (cddr (cadr value)) + (caar cconv-freevars-alist))) + ;; Peek at the freevars to decide whether to λ-lift. + (let* ((fvs (cdr (car cconv-freevars-alist))) + (fun (cadr value)) + (funargs (cadr fun)) + (funcvars (append fvs funargs))) ; lambda lifting condition - (and fvs (>= cconv-liftwhen (length funcvars)))))) + (and fvs (>= cconv-liftwhen + (length funcvars))))))) ; Lift. - (let* ((fvs (cdr (pop cconv-freevars-alist))) - (fun (cadr value)) - (funargs (cadr fun)) - (funcvars (append fvs funargs)) - (funcbody (cddr fun)) - (funcbody-env ())) - (push `(,var . (apply-partially ,var . ,fvs)) new-env) - (dolist (fv fvs) - (cl-pushnew fv new-extend) - (if (and (eq 'car-safe (car-safe (cdr (assq fv env)))) - (not (memq fv funargs))) - (push `(,fv . (car-safe ,fv)) funcbody-env))) - `(function (lambda ,funcvars . - ,(cconv--convert-funcbody - funargs funcbody funcbody-env value))))) + (let* ((fvs (cdr (pop cconv-freevars-alist))) + (fun (cadr value)) + (funargs (cadr fun)) + (funcvars (append fvs funargs)) + (funcbody (cddr fun)) + (funcbody-env ())) + (push `(,var . (apply-partially ,var . ,fvs)) new-env) + (dolist (fv fvs) + (cl-pushnew fv new-extend) + (if (and (eq 'car-safe (car-safe (cdr (assq fv env)))) + (not (memq fv funargs))) + (push `(,fv . (car-safe ,fv)) funcbody-env))) + `(function (lambda ,funcvars . + ,(cconv--convert-funcbody + funargs funcbody funcbody-env value))))) ;; Check if it needs to be turned into a "ref-cell". - ((member (cons binder form) cconv-captured+mutated) + (:captured+mutated ;; Declared variable is mutated and captured. (push `(,var . (car-safe ,var)) new-env) `(list ,(cconv-convert value env extend))) + ;; Check if it needs to be turned into a "ref-cell". + (:unused + ;; Declared variable is unused. + (if (assq var new-env) (push `(,var) new-env)) ;FIXME:Needed? + (let ((newval + `(ignore ,(cconv-convert value env extend))) + (msg (cconv--warn-unused-msg var "variable"))) + (if (null msg) newval + (macroexp--warn-wrap msg newval)))) + ;; Normal default case. - (t + (_ (if (assq var new-env) (push `(,var) new-env)) (cconv-convert value env extend))))) @@ -464,22 +494,28 @@ places where they originally did not directly appear." ; condition-case (`(condition-case ,var ,protected-form . ,handlers) - `(condition-case ,var - ,(cconv-convert protected-form env extend) - ,@(let* ((cm (and var (member (cons (list var) form) - cconv-captured+mutated))) - (newenv - (cond (cm (cons `(,var . (car-save ,var)) env)) - ((assq var env) (cons `(,var) env)) - (t env)))) - (mapcar + (let* ((class (and var (cconv--var-classification (list var) form))) + (newenv + (cond ((eq class :captured+mutated) + (cons `(,var . (car-save ,var)) env)) + ((assq var env) (cons `(,var) env)) + (t env))) + (msg (when (eq class :unused) + (cconv--warn-unused-msg var "variable"))) + (newprotform (cconv-convert protected-form env extend))) + `(condition-case ,var + ,(if msg + `(macroexp--warn-wrap msg newprotform) + newprotform) + ,@(mapcar (lambda (handler) `(,(car handler) ,@(let ((body (mapcar (lambda (form) (cconv-convert form newenv extend)) (cdr handler)))) - (if (not cm) body + (if (not (eq class :captured+mutated)) + body `((let ((,var (list ,var))) ,@body)))))) handlers)))) @@ -563,29 +599,21 @@ FORM is the parent form that binds this var." (`(,_ nil nil nil nil) nil) (`((,(and var (guard (eq ?_ (aref (symbol-name var) 0)))) . ,_) ,_ ,_ ,_ ,_) + ;; FIXME: Convert this warning to use `macroexp--warn-wrap' + ;; so as to give better position information. (byte-compile-warn "%s `%S' not left unused" varkind var))) (pcase vardata - (`((,var . ,_) nil ,_ ,_ nil) - ;; FIXME: This gives warnings in the wrong order, with imprecise line - ;; numbers and without function name info. - (unless (or ;; Uninterned symbols typically come from macro-expansion, so - ;; it is often non-trivial for the programmer to avoid such - ;; unused vars. - (not (intern-soft var)) - (eq ?_ (aref (symbol-name var) 0)) - ;; As a special exception, ignore "ignore". - (eq var 'ignored)) - (let ((suggestions (help-uni-confusable-suggestions (symbol-name var)))) - (byte-compile-warn "Unused lexical %s `%S'%s" - varkind var - (if suggestions (concat "\n " suggestions) ""))))) + (`(,binder nil ,_ ,_ nil) + (push (cons (cons binder form) :unused) cconv-var-classification)) ;; If it's unused, there's no point converting it into a cons-cell, even if ;; it's captured and mutated. (`(,binder ,_ t t ,_) - (push (cons binder form) cconv-captured+mutated)) + (push (cons (cons binder form) :captured+mutated) + cconv-var-classification)) (`(,(and binder `(,_ (function (lambda . ,_)))) nil nil nil t) - (push (cons binder form) cconv-lambda-candidates)))) + (push (cons (cons binder form) :lambda-candidates) + cconv-var-classification)))) (defun cconv--analyze-function (args body env parentform) (let* ((newvars nil) @@ -638,8 +666,7 @@ Analyze lambdas if they are suitable for lambda lifting. - ENV is an alist mapping each enclosing lexical variable to its info. I.e. each element has the form (VAR . (READ MUTATED CAPTURED CALLED)). This function does not return anything but instead fills the -`cconv-captured+mutated' and `cconv-lambda-candidates' variables -and updates the data stored in ENV." +`cconv-var-classification' variable and updates the data stored in ENV." (pcase form ; let special form (`(,(and (or 'let* 'let) letsym) ,binders . ,body-forms) diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index 279b9d137c..89fc0b16d0 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el @@ -487,7 +487,7 @@ The set of acceptable TYPEs (also called \"specializers\") is defined (or (not (fboundp 'byte-compile-warning-enabled-p)) (byte-compile-warning-enabled-p 'obsolete name)) (let* ((obsolete (get name 'byte-obsolete-info))) - (macroexp--warn-and-return + (macroexp-warn-and-return (macroexp--obsolete-warning name obsolete "generic function") nil))) ;; You could argue that `defmethod' modifies rather than defines the diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index b852d825c7..007466bbb0 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -565,7 +565,7 @@ its argument list allows full Common Lisp conventions." ,(length (cl-ldiff args p))) exactarg (not (eq args p))))) (while (and args (not (memq (car args) cl--lambda-list-keywords))) - (let ((poparg (list (if (or (cdr args) (not exactarg)) 'pop 'car) + (let ((poparg (list (if (or (cdr args) (not exactarg)) 'pop 'car-safe) restarg))) (cl--do-arglist (pop args) @@ -2393,7 +2393,7 @@ by EXPANSION, and (setq NAME ...) will act like (setf EXPANSION ...). (append bindings venv)) macroexpand-all-environment)))) (if malformed-bindings - (macroexp--warn-and-return + (macroexp-warn-and-return (format-message "Malformed `cl-symbol-macrolet' binding(s): %S" (nreverse malformed-bindings)) expansion) @@ -3032,7 +3032,7 @@ Supported keywords for slots are: forms) (when (cl-oddp (length desc)) (push - (macroexp--warn-and-return + (macroexp-warn-and-return (format "Missing value for option `%S' of slot `%s' in struct %s!" (car (last desc)) slot name) 'nil) @@ -3041,7 +3041,7 @@ Supported keywords for slots are: (not (keywordp (car desc)))) (let ((kw (car defaults))) (push - (macroexp--warn-and-return + (macroexp-warn-and-return (format " I'll take `%s' to be an option rather than a default value." kw) 'nil) diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index a8361c0d4b..e7727fd3fc 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el @@ -729,7 +729,7 @@ Argument FN is the function calling this verifier." (pcase slot ((and (or `',name (and name (pred keywordp))) (guard (not (memq name eieio--known-slot-names)))) - (macroexp--warn-and-return + (macroexp-warn-and-return (format-message "Unknown slot `%S'" name) exp 'compile-only)) (_ exp)))) (gv-setter eieio-oset)) diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index d3e5d03edb..910023b841 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -269,7 +269,7 @@ This method is obsolete." (lambda (whole) (if (not (stringp (car slots))) whole - (macroexp--warn-and-return + (macroexp-warn-and-return (format "Obsolete name arg %S to constructor %S" (car slots) (car whole)) ;; Keep the name arg, for backward compatibility, diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el index 2b213e2065..3d8054950c 100644 --- a/lisp/emacs-lisp/gv.el +++ b/lisp/emacs-lisp/gv.el @@ -593,7 +593,7 @@ binding mode." ;; dynamic binding mode as well. (eq (car-safe code) 'cons)) code - (macroexp--warn-and-return + (macroexp-warn-and-return "Use of gv-ref probably requires lexical-binding" code)))) diff --git a/lisp/emacs-lisp/inline.el b/lisp/emacs-lisp/inline.el index d6106fe35d..36d71a8c04 100644 --- a/lisp/emacs-lisp/inline.el +++ b/lisp/emacs-lisp/inline.el @@ -262,7 +262,7 @@ See Info node `(elisp)Defining Functions' for more details." '(throw 'inline--just-use ;; FIXME: This would inf-loop by calling us right back when ;; macroexpand-all recurses to expand inline--form. - ;; (macroexp--warn-and-return (format ,@args) + ;; (macroexp-warn-and-return (format ,@args) ;; inline--form) inline--form)) diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index d52aee5a4a..4d04bfa091 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -135,28 +135,33 @@ Other uses risk returning non-nil value that point to the wrong file." (defvar macroexp--warned (make-hash-table :test #'equal :weakness 'key)) -(defun macroexp--warn-and-return (msg form &optional compile-only) +(defun macroexp--warn-wrap (msg form) (let ((when-compiled (lambda () (byte-compile-warn "%s" msg)))) - (cond - ((null msg) form) - ((macroexp-compiling-p) - (if (and (consp form) (gethash form macroexp--warned)) - ;; Already wrapped this exp with a warning: avoid inf-looping - ;; where we keep adding the same warning onto `form' because - ;; macroexpand-all gets right back to macroexpanding `form'. - form - (puthash form form macroexp--warned) - `(progn - (macroexp--funcall-if-compiled ',when-compiled) - ,form))) - (t - (unless compile-only - (message "%sWarning: %s" - (if (stringp load-file-name) - (concat (file-relative-name load-file-name) ": ") - "") - msg)) - form)))) + `(progn + (macroexp--funcall-if-compiled ',when-compiled) + ,form))) + +(define-obsolete-function-alias 'macroexp--warn-and-return + #'macroexp-warn-and-return "28.1") +(defun macroexp-warn-and-return (msg form &optional compile-only) + (cond + ((null msg) form) + ((macroexp-compiling-p) + (if (and (consp form) (gethash form macroexp--warned)) + ;; Already wrapped this exp with a warning: avoid inf-looping + ;; where we keep adding the same warning onto `form' because + ;; macroexpand-all gets right back to macroexpanding `form'. + form + (puthash form form macroexp--warned) + (macroexp--warn-wrap msg form))) + (t + (unless compile-only + (message "%sWarning: %s" + (if (stringp load-file-name) + (concat (file-relative-name load-file-name) ": ") + "") + msg)) + form))) (defun macroexp--obsolete-warning (fun obsolescence-data type) (let ((instead (car obsolescence-data)) @@ -205,7 +210,7 @@ Other uses risk returning non-nil value that point to the wrong file." (byte-compile-warning-enabled-p 'obsolete (car form)))) (let* ((fun (car form)) (obsolete (get fun 'byte-obsolete-info))) - (macroexp--warn-and-return + (macroexp-warn-and-return (macroexp--obsolete-warning fun obsolete (if (symbolp (symbol-function fun)) @@ -260,7 +265,7 @@ Other uses risk returning non-nil value that point to the wrong file." values (cdr values)))) (setq arglist (cdr arglist))) (if values - (macroexp--warn-and-return + (macroexp-warn-and-return (format (if (eq values 'too-few) "attempt to open-code `%s' with too few arguments" "attempt to open-code `%s' with too many arguments") @@ -314,7 +319,7 @@ Assumes the caller has bound `macroexpand-all-environment'." (macroexp--cons (macroexp--all-clauses bindings 1) (if (null body) (macroexp-unprogn - (macroexp--warn-and-return + (macroexp-warn-and-return (format "Empty %s body" fun) nil t)) (macroexp--all-forms body)) @@ -344,13 +349,13 @@ Assumes the caller has bound `macroexpand-all-environment'." ;; First arg is a function: (`(,(and fun (or 'funcall 'apply 'mapcar 'mapatoms 'mapconcat 'mapc)) ',(and f `(lambda . ,_)) . ,args) - (macroexp--warn-and-return + (macroexp-warn-and-return (format "%s quoted with ' rather than with #'" (list 'lambda (nth 1 f) '...)) (macroexp--expand-all `(,fun #',f . ,args)))) ;; Second arg is a function: (`(,(and fun (or 'sort)) ,arg1 ',(and f `(lambda . ,_)) . ,args) - (macroexp--warn-and-return + (macroexp-warn-and-return (format "%s quoted with ' rather than with #'" (list 'lambda (nth 1 f) '...)) (macroexp--expand-all `(,fun ,arg1 #',f . ,args)))) diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index c7288b7fa2..95e5dd3ba0 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -469,8 +469,10 @@ for the result of evaluating EXP (first arg to `pcase'). ;; the depth of the generated tree. (defun pcase--if (test then else) (cond - ((eq else :pcase--dontcare) then) - ((eq then :pcase--dontcare) (debug) else) ;Can/should this ever happen? + ((eq else :pcase--dontcare) `(progn (ignore ,test) ,then)) + ;; This happens very rarely. Known case: + ;; (pcase EXP ((and 1 pcase--dontcare) FOO)) + ((eq then :pcase--dontcare) `(progn (ignore ,test) ,else)) (t (macroexp-if test then else)))) ;; Note about MATCH: @@ -845,7 +847,7 @@ Otherwise, it defers to REST which is a list of branches of the form ((memq upat '(t _)) (let ((code (pcase--u1 matches code vars rest))) (if (eq upat '_) code - (macroexp--warn-and-return + (macroexp-warn-and-return "Pattern t is deprecated. Use `_' instead" code)))) ((eq upat 'pcase--dontcare) :pcase--dontcare) @@ -971,8 +973,8 @@ The predicate is the logical-AND of: (nreverse upats)))) ((consp qpat) `(and (pred consp) - (app car ,(list '\` (car qpat))) - (app cdr ,(list '\` (cdr qpat))))) + (app car-safe ,(list '\` (car qpat))) + (app cdr-safe ,(list '\` (cdr qpat))))) ((or (stringp qpat) (numberp qpat) (symbolp qpat)) `',qpat) ;; In all other cases just raise an error so we can't break ;; backward compatibility when adding \` support for other diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 20c7f20d04..37bed0c54e 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -1406,6 +1406,7 @@ which see." (interactive "P") (cond (edebug-it (require 'edebug) + (defvar edebug-all-defs) (eval-defun (not edebug-all-defs))) (t (if (null eval-expression-debug-on-error) commit 99340ad17a826c61895b3e1ed6928b36fbfeac60 Author: Stefan Monnier Date: Fri Feb 26 16:51:15 2021 -0500 lisp/vc/*.el: Use lexical-bindings in all the files Also remove some redundant `:group` arguments. * lisp/vc/vc.el (vc-ignore): Autoload. * lisp/vc/pcvs-util.el (cvs-every, cvs-union, cvs-map): Delete functions. * lisp/vc/cvs-status.el: Require `cl-lib` at runtime. (cvs-tree-tags-insert): Use `cl-mapcar` and `cl-every` instead. * lisp/vc/pcvs.el: Require `cl-lib` at runtime. (cvs-do-removal): Use `cl-every` instead. * lisp/vc/ediff-init.el: Require `ediff-util` (for `ediff-cleanup-mess` and `ediff-default-suspend-function`). * lisp/vc/pcvs-info.el (cvs-fileinfo<): Remove unused vars `subtypea` and `subtypeb`. * lisp/vc/vc-git.el: * lisp/vc/vc-bzr.el: Require `vc-dispatcher` at runtime for `vc-do-async-command`. diff --git a/lisp/vc/add-log.el b/lisp/vc/add-log.el index 19765e0da3..fafd7f9c46 100644 --- a/lisp/vc/add-log.el +++ b/lisp/vc/add-log.el @@ -1,4 +1,4 @@ -;;; add-log.el --- change log maintenance commands for Emacs +;;; add-log.el --- change log maintenance commands for Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 1985-1986, 1988, 1993-1994, 1997-1998, 2000-2021 Free ;; Software Foundation, Inc. @@ -49,15 +49,13 @@ (defcustom change-log-default-name nil "Name of a change log file for \\[add-change-log-entry]." :type '(choice (const :tag "default" nil) - string) - :group 'change-log) + string)) ;;;###autoload -(put 'change-log-default-name 'safe-local-variable 'string-or-null-p) +(put 'change-log-default-name 'safe-local-variable #'string-or-null-p) (defcustom change-log-mode-hook nil "Normal hook run by `change-log-mode'." - :type 'hook - :group 'change-log) + :type 'hook) ;; Many modes set this variable, so avoid warnings. ;;;###autoload @@ -66,16 +64,14 @@ It is called by `add-log-current-defun' with no argument, and should return the function's name as a string, or nil if point is outside a function." - :type '(choice (const nil) function) - :group 'change-log) + :type '(choice (const nil) function)) ;;;###autoload (defcustom add-log-full-name nil "Full name of user, for inclusion in ChangeLog daily headers. This defaults to the value returned by the function `user-full-name'." :type '(choice (const :tag "Default" nil) - string) - :group 'change-log) + string)) ;;;###autoload (defcustom add-log-mailing-address nil @@ -86,8 +82,7 @@ will be recognized as referring to the same user; when creating a new ChangeLog entry, one element will be chosen at random." :type '(choice (const :tag "Default" nil) (string :tag "String") - (repeat :tag "List of Strings" string)) - :group 'change-log) + (repeat :tag "List of Strings" string))) (defcustom add-log-time-format 'add-log-iso8601-time-string "Function that defines the time format. @@ -98,8 +93,7 @@ and `current-time-string' are two valid values." add-log-iso8601-time-string) (const :tag "Old format, as returned by `current-time-string'" current-time-string) - (function :tag "Other")) - :group 'change-log) + (function :tag "Other"))) (defcustom add-log-keep-changes-together nil "If non-nil, normally keep day's log entries for one file together. @@ -130,14 +124,12 @@ and in the former: The NEW-ENTRY arg to `add-change-log-entry' can override the effect of this variable." :version "20.3" - :type 'boolean - :group 'change-log) + :type 'boolean) (defcustom add-log-always-start-new-record nil "If non-nil, `add-change-log-entry' will always start a new record." :version "22.1" - :type 'boolean - :group 'change-log) + :type 'boolean) (defvar add-log-buffer-file-name-function 'buffer-file-name "If non-nil, function to call to identify the full filename of a buffer. @@ -149,15 +141,13 @@ use `buffer-file-name'.") This function is called with one argument, the value of variable `buffer-file-name' in that buffer. If this is nil, the default is to use the file's name relative to the directory of the change log file." - :type '(choice (const nil) function) - :group 'change-log) + :type '(choice (const nil) function)) (defcustom change-log-version-info-enabled nil "If non-nil, enable recording version numbers with the changes." :version "21.1" - :type 'boolean - :group 'change-log) + :type 'boolean) (defcustom change-log-version-number-regexp-list (let ((re "\\([0-9]+\\.[0-9.]+\\)")) @@ -170,64 +160,54 @@ use the file's name relative to the directory of the change log file." The version number must be in group 1. Note: The search is conducted only within 10%, at the beginning of the file." :version "21.1" - :type '(repeat regexp) - :group 'change-log) + :type '(repeat regexp)) (defcustom change-log-directory-files '(".bzr" ".git" ".hg" ".svn") "List of files that cause `find-change-log' to stop in containing directory. This applies if no pre-existing ChangeLog is found. If nil, then in such a case simply use the directory containing the changed file." :version "26.1" - :type '(repeat file) - :group 'change-log) + :type '(repeat file)) (defface change-log-date '((t (:inherit font-lock-string-face))) "Face used to highlight dates in date lines." - :version "21.1" - :group 'change-log) + :version "21.1") (defface change-log-name '((t (:inherit font-lock-constant-face))) "Face for highlighting author names." - :version "21.1" - :group 'change-log) + :version "21.1") (defface change-log-email '((t (:inherit font-lock-variable-name-face))) "Face for highlighting author email addresses." - :version "21.1" - :group 'change-log) + :version "21.1") (defface change-log-file '((t (:inherit font-lock-function-name-face))) "Face for highlighting file names." - :version "21.1" - :group 'change-log) + :version "21.1") (defface change-log-list '((t (:inherit font-lock-keyword-face))) "Face for highlighting parenthesized lists of functions or variables." - :version "21.1" - :group 'change-log) + :version "21.1") (defface change-log-conditionals '((t (:inherit font-lock-variable-name-face))) "Face for highlighting conditionals of the form `[...]'." - :version "21.1" - :group 'change-log) + :version "21.1") (defface change-log-function '((t (:inherit font-lock-variable-name-face))) "Face for highlighting items of the form `<....>'." - :version "21.1" - :group 'change-log) + :version "21.1") (defface change-log-acknowledgment '((t (:inherit font-lock-comment-face))) "Face for highlighting acknowledgments." - :version "21.1" - :group 'change-log) + :version "21.1") (define-obsolete-face-alias 'change-log-acknowledgement 'change-log-acknowledgment "24.3") @@ -519,7 +499,7 @@ try to visit the file for the change under `point' instead." change-log-find-tail) (setq change-log-find-tail (condition-case nil - (apply 'change-log-goto-source-1 + (apply #'change-log-goto-source-1 (append change-log-find-head change-log-find-tail)) (error (format-message @@ -556,7 +536,7 @@ try to visit the file for the change under `point' instead." file (find-file-noselect file))) (condition-case nil (setq change-log-find-tail - (apply 'change-log-goto-source-1 change-log-find-head)) + (apply #'change-log-goto-source-1 change-log-find-head)) (error (format-message "Cannot find matches for tag `%s' in file `%s'" tag file))))))))) @@ -569,7 +549,7 @@ Compatibility function for \\[next-error] invocations." (count (abs argp)) ; how many cycles (down (< argp 0)) ; are we going down? (is argp negative?) (up (not down)) - (search-function (if up 're-search-forward 're-search-backward))) + (search-function (if up #'re-search-forward #'re-search-backward))) ;; set the starting position (goto-char (cond (reset (point-min)) @@ -591,10 +571,10 @@ Compatibility function for \\[next-error] invocations." (defvar change-log-mode-map (let ((map (make-sparse-keymap)) (menu-map (make-sparse-keymap))) - (define-key map [?\C-c ?\C-p] 'add-log-edit-prev-comment) - (define-key map [?\C-c ?\C-n] 'add-log-edit-next-comment) - (define-key map [?\C-c ?\C-f] 'change-log-find-file) - (define-key map [?\C-c ?\C-c] 'change-log-goto-source) + (define-key map [?\C-c ?\C-p] #'add-log-edit-prev-comment) + (define-key map [?\C-c ?\C-n] #'add-log-edit-next-comment) + (define-key map [?\C-c ?\C-f] #'change-log-find-file) + (define-key map [?\C-c ?\C-c] #'change-log-goto-source) (define-key map [menu-bar changelog] (cons "ChangeLog" menu-map)) (define-key menu-map [gs] '(menu-item "Go To Source" change-log-goto-source @@ -814,7 +794,7 @@ means to put log entries in a suitably named buffer." :type 'boolean :version "27.1") -(put 'add-log-dont-create-changelog-file 'safe-local-variable 'booleanp) +(put 'add-log-dont-create-changelog-file 'safe-local-variable #'booleanp) (defun add-log--pseudo-changelog-buffer-name (changelog-file-name) "Compute a suitable name for a non-file visiting ChangeLog buffer. @@ -1220,8 +1200,7 @@ file were isearch was started." "Heuristic regexp used by `add-log-current-defun' for unknown major modes. The regexp's first submatch is placed in the ChangeLog entry, in parentheses." - :type 'regexp - :group 'change-log) + :type 'regexp) (declare-function c-cpp-define-name "cc-cmds" ()) (declare-function c-defun-name "cc-cmds" ()) diff --git a/lisp/vc/compare-w.el b/lisp/vc/compare-w.el index 932dcd7892..4c1d9eaad5 100644 --- a/lisp/vc/compare-w.el +++ b/lisp/vc/compare-w.el @@ -1,4 +1,4 @@ -;;; compare-w.el --- compare text between windows for Emacs +;;; compare-w.el --- compare text between windows for Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 1986, 1989, 1993, 1997, 2001-2021 Free Software ;; Foundation, Inc. @@ -52,19 +52,16 @@ any text before that point. If the function returns the same value for both windows, then the whitespace is considered to match, and is skipped." :version "24.4" ; added \240 - :type '(choice regexp function) - :group 'compare-windows) + :type '(choice regexp function)) (defcustom compare-ignore-whitespace nil "Non-nil means command `compare-windows' ignores whitespace." :type 'boolean - :group 'compare-windows :version "22.1") (defcustom compare-ignore-case nil "Non-nil means command `compare-windows' ignores case differences." - :type 'boolean - :group 'compare-windows) + :type 'boolean) (defcustom compare-windows-sync 'compare-windows-sync-default-function "Function or regexp that is used to synchronize points in two @@ -92,7 +89,6 @@ If the value of this variable is nil (option \"No sync\"), then no synchronization is performed, and the function `ding' is called to beep or flash the screen when points are mismatched." :type '(choice function regexp (const :tag "No sync" nil)) - :group 'compare-windows :version "22.1") (defcustom compare-windows-sync-string-size 32 @@ -104,7 +100,6 @@ difference regions more coarse-grained. The default value 32 is good for the most cases." :type 'integer - :group 'compare-windows :version "22.1") (defcustom compare-windows-recenter nil @@ -115,7 +110,6 @@ matching points side-by-side. The value `(-1 0)' is useful if windows are split vertically, and the value `((4) (4))' for horizontally split windows." :type '(list sexp sexp) - :group 'compare-windows :version "22.1") (defcustom compare-windows-highlight t @@ -127,19 +121,16 @@ out all highlighting later with the command `compare-windows-dehighlight'." :type '(choice (const :tag "No highlighting" nil) (const :tag "Persistent highlighting" persistent) (other :tag "Highlight until next command" t)) - :group 'compare-windows :version "22.1") (defface compare-windows-removed '((t :inherit diff-removed)) "Face for highlighting `compare-windows' differing regions in the other window." - :group 'compare-windows :version "25.1") (defface compare-windows-added '((t :inherit diff-added)) "Face for highlighting `compare-windows' differing regions in current window." - :group 'compare-windows :version "25.1") (define-obsolete-face-alias 'compare-windows 'compare-windows-added "25.1") @@ -159,7 +150,6 @@ out all highlighting later with the command `compare-windows-dehighlight'." (function-item :tag "Next window" compare-windows-get-next-window) (function :tag "Your function")) - :group 'compare-windows :version "25.1") (defun compare-windows-get-recent-window () @@ -389,7 +379,7 @@ on third call it again advances points to the next difference and so on." (setq p1 (1+ p1))))) (when p12s ;; use closest matching points (i.e. points with minimal sum) - (setq p12 (cdr (assq (apply 'min (mapcar 'car p12s)) p12s))) + (setq p12 (cdr (assq (apply #'min (mapcar #'car p12s)) p12s))) (goto-char (car p12)) (compare-windows-highlight op1 (car p12) (current-buffer) w1 op2 (cadr p12) b2 w2)) @@ -416,7 +406,7 @@ on third call it again advances points to the next difference and so on." (overlay-put compare-windows-overlay2 'window w2) (if (not (eq compare-windows-highlight 'persistent)) ;; Remove highlighting before next command is executed - (add-hook 'pre-command-hook 'compare-windows-dehighlight) + (add-hook 'pre-command-hook #'compare-windows-dehighlight) (when compare-windows-overlay1 (push (copy-overlay compare-windows-overlay1) compare-windows-overlays1) (delete-overlay compare-windows-overlay1)) @@ -427,9 +417,9 @@ on third call it again advances points to the next difference and so on." (defun compare-windows-dehighlight () "Remove highlighting created by function `compare-windows-highlight'." (interactive) - (remove-hook 'pre-command-hook 'compare-windows-dehighlight) - (mapc 'delete-overlay compare-windows-overlays1) - (mapc 'delete-overlay compare-windows-overlays2) + (remove-hook 'pre-command-hook #'compare-windows-dehighlight) + (mapc #'delete-overlay compare-windows-overlays1) + (mapc #'delete-overlay compare-windows-overlays2) (and compare-windows-overlay1 (delete-overlay compare-windows-overlay1)) (and compare-windows-overlay2 (delete-overlay compare-windows-overlay2))) diff --git a/lisp/vc/cvs-status.el b/lisp/vc/cvs-status.el index 26fb6206c8..63b886362b 100644 --- a/lisp/vc/cvs-status.el +++ b/lisp/vc/cvs-status.el @@ -28,7 +28,7 @@ ;;; Code: -(eval-when-compile (require 'cl-lib)) +(require 'cl-lib) (require 'pcvs-util) ;;; @@ -169,7 +169,7 @@ name type) -(defsubst cvs-status-vl-to-str (vl) (mapconcat 'number-to-string vl ".")) +(defsubst cvs-status-vl-to-str (vl) (mapconcat #'number-to-string vl ".")) (defun cvs-tag->string (tag) (if (stringp tag) tag @@ -283,7 +283,7 @@ BEWARE: because of stability issues, this is not a symmetric operation." tree1 (list (cons (cvs-tag-make (butlast vl2)) tree2))))))))) (defun cvs-tag-make-tag (tag) - (let ((vl (mapcar 'string-to-number (split-string (nth 2 tag) "\\.")))) + (let ((vl (mapcar #'string-to-number (split-string (nth 2 tag) "\\.")))) (cvs-tag-make vl (nth 0 tag) (intern (nth 1 tag))))) (defun cvs-tags->tree (tags) @@ -450,10 +450,10 @@ Optional prefix ARG chooses between two representations." (tags nil) (cvs-tree-nomerge (if arg (not cvs-tree-nomerge) cvs-tree-nomerge))) (while (listp (setq tags (cvs-status-get-tags))) - (let ((tags (mapcar 'cvs-tag-make-tag tags)) + (let ((tags (mapcar #'cvs-tag-make-tag tags)) ;;(pt (save-excursion (forward-line -1) (point))) ) - (setq tags (sort tags 'cvs-tag-lessp)) + (setq tags (sort tags #'cvs-tag-lessp)) (let* ((first (car tags)) (prev (if (cvs-tag-p first) (list (car (cvs-tag->vlist first))) nil))) @@ -472,7 +472,7 @@ Optional prefix ARG chooses between two representations." (nprev (if (and cvs-tree-nomerge next (equal vlist (cvs-tag->vlist next))) prev vlist))) - (cvs-map (lambda (v _p) v) nprev prev))) + (cl-mapcar (lambda (v _p) v) nprev prev))) (after (save-excursion (newline) (cvs-tree-tags-insert (cdr tags) nprev))) @@ -484,7 +484,7 @@ Optional prefix ARG chooses between two representations." (as after (cdr as))) ((and (null as) (null vs) (null ps)) (let ((revname (cvs-status-vl-to-str vlist))) - (if (cvs-every 'identity (cvs-map 'equal prev vlist)) + (if (cl-every #'identity (cl-mapcar #'equal prev vlist)) (insert (make-string (+ 4 (length revname)) ? ) (or (cvs-tag->name tag) "")) (insert " " revname ": " (or (cvs-tag->name tag) ""))))) @@ -500,7 +500,7 @@ Optional prefix ARG chooses between two representations." (if next-eq (cons nil cvs-tree-char-space) (cons t cvs-tree-char-eob)) (cons nil (if (and (eq (cvs-tag->type tag) 'branch) - (cvs-every 'null as)) + (cl-every #'null as)) cvs-tree-char-space cvs-tree-char-hbar)))))) (insert (cdr na+char)) diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 7a47420181..8bbab467af 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -739,7 +739,7 @@ start and end positions." "Restrict the view to the current hunk. If the prefix ARG is given, restrict the view to the current file instead." (interactive "P") - (apply 'narrow-to-region + (apply #'narrow-to-region (if arg (diff-bounds-of-file) (diff-bounds-of-hunk))) (setq-local diff-narrowed-to (if arg 'file 'hunk))) @@ -770,7 +770,7 @@ If the prefix ARG is given, restrict the view to the current file instead." file-bounds hunk-bounds)) (inhibit-read-only t)) - (apply 'kill-region bounds) + (apply #'kill-region bounds) (goto-char (car bounds)) (ignore-errors (diff-beginning-of-hunk t))))) @@ -828,7 +828,7 @@ data such as \"Index: ...\" and such." (error "No hunks") (diff-beginning-of-hunk t) (let ((inhibit-read-only t)) - (apply 'kill-region (diff-bounds-of-file))) + (apply #'kill-region (diff-bounds-of-file))) (ignore-errors (diff-beginning-of-hunk t)))) (defun diff-kill-junk () @@ -1810,7 +1810,7 @@ Whitespace differences are ignored." (if (> (- (car forw) orig) (- orig (car back))) back forw) (or back forw)))) -(define-obsolete-function-alias 'diff-xor 'xor "27.1") +(define-obsolete-function-alias 'diff-xor #'xor "27.1") (defun diff-find-source-location (&optional other-file reverse noprompt) "Find current diff location within the source file. @@ -1984,7 +1984,7 @@ With a prefix argument, try to REVERSE the hunk." (diff-hunk-kill) (diff-hunk-next))))) -(defalias 'diff-mouse-goto-source 'diff-goto-source) +(defalias 'diff-mouse-goto-source #'diff-goto-source) (defun diff-goto-source (&optional other-file event) "Jump to the corresponding source line. @@ -2080,7 +2080,7 @@ For use in `add-log-current-defun-function'." (write-region (concat lead (car new)) nil file2 nil 'nomessage) (with-temp-buffer (let ((status - (apply 'call-process + (apply #'call-process `(,diff-command nil t nil ,@opts ,file1 ,file2)))) (pcase status diff --git a/lisp/vc/diff.el b/lisp/vc/diff.el index 7c4931b4b8..7bb1151602 100644 --- a/lisp/vc/diff.el +++ b/lisp/vc/diff.el @@ -45,14 +45,12 @@ This variable is also used in the `vc-diff' command (and related commands) if the backend-specific diff switch variable isn't set (`vc-git-diff-switches' for git, for instance), and `vc-diff-switches' isn't set." - :type '(choice string (repeat string)) - :group 'diff) + :type '(choice string (repeat string))) ;;;###autoload (defcustom diff-command (purecopy "diff") "The command to use to run diff." - :type 'string - :group 'diff) + :type 'string) ;; prompt if prefix arg present (defun diff-switches () @@ -60,7 +58,7 @@ set (`vc-git-diff-switches' for git, for instance), and (read-string "Diff switches: " (if (stringp diff-switches) diff-switches - (mapconcat 'identity diff-switches " "))))) + (mapconcat #'identity diff-switches " "))))) (defun diff-sentinel (code &optional old-temp-file new-temp-file) "Code run when the diff process exits. @@ -165,7 +163,7 @@ returns the buffer used." (let* ((old-alt (diff-file-local-copy old)) (new-alt (diff-file-local-copy new)) (command - (mapconcat 'identity + (mapconcat #'identity `(,diff-command ;; Use explicitly specified switches ,@switches @@ -200,7 +198,7 @@ returns the buffer used." (if (and (not no-async) (fboundp 'make-process)) (let ((proc (start-process "Diff" buf shell-file-name shell-command-switch command))) - (set-process-filter proc 'diff-process-filter) + (set-process-filter proc #'diff-process-filter) (set-process-sentinel proc (lambda (proc _msg) (with-current-buffer (process-buffer proc) diff --git a/lisp/vc/ediff-diff.el b/lisp/vc/ediff-diff.el index fde9d4338f..b93dfc814c 100644 --- a/lisp/vc/ediff-diff.el +++ b/lisp/vc/ediff-diff.el @@ -87,7 +87,7 @@ options after the default ones. This variable is not for customizing the look of the differences produced by the command \\[ediff-show-diff-output]. Use the variable `ediff-custom-diff-options' for that." - :set 'ediff-set-diff-options + :set #'ediff-set-diff-options :type 'string) (ediff-defvar-local ediff-ignore-case nil diff --git a/lisp/vc/ediff-help.el b/lisp/vc/ediff-help.el index 84bf063aed..a5bb953b6d 100644 --- a/lisp/vc/ediff-help.el +++ b/lisp/vc/ediff-help.el @@ -156,7 +156,7 @@ the value of this variable and the variables `ediff-help-message-*' in ;; the keymap that defines clicks over the quick help regions (defvar ediff-help-region-map (make-sparse-keymap)) -(define-key ediff-help-region-map [mouse-2] 'ediff-help-for-quick-help) +(define-key ediff-help-region-map [mouse-2] #'ediff-help-for-quick-help) ;; runs in the control buffer (defun ediff-set-help-overlays () diff --git a/lisp/vc/ediff-init.el b/lisp/vc/ediff-init.el index 3f33e6aae2..17c4202d64 100644 --- a/lisp/vc/ediff-init.el +++ b/lisp/vc/ediff-init.el @@ -25,6 +25,7 @@ ;;; Code: (require 'cl-lib) +(require 'ediff-util) ;; Start compiler pacifier (defvar ediff-metajob-name) @@ -1181,8 +1182,8 @@ this variable represents.") (put ediff-fine-diff-face-Ancestor 'ediff-help-echo "A `refinement' of the current difference region") -(add-hook 'ediff-quit-hook 'ediff-cleanup-mess) -(add-hook 'ediff-suspend-hook 'ediff-default-suspend-function) +(add-hook 'ediff-quit-hook #'ediff-cleanup-mess) +(add-hook 'ediff-suspend-hook #'ediff-default-suspend-function) ;;; Overlays @@ -1312,7 +1313,8 @@ This default should work without changes." (defun ediff-paint-background-regions-in-one-buffer (buf-type unhighlight) (let ((diff-vector (eval (ediff-get-symbol-from-alist - buf-type ediff-difference-vector-alist))) + buf-type ediff-difference-vector-alist) + t)) overl diff-num) (mapcar (lambda (rec) (setq overl (ediff-get-diff-overlay-from-diff-record rec) diff --git a/lisp/vc/ediff-merg.el b/lisp/vc/ediff-merg.el index 826cad9cc1..ad4ef473f8 100644 --- a/lisp/vc/ediff-merg.el +++ b/lisp/vc/ediff-merg.el @@ -194,7 +194,7 @@ Buffer B." (defun ediff-set-merge-mode () (normal-mode t) - (remove-hook 'write-file-functions 'ediff-set-merge-mode t)) + (remove-hook 'write-file-functions #'ediff-set-merge-mode t)) ;; Go over all diffs starting with DIFF-NUM and copy regions into buffer C diff --git a/lisp/vc/ediff-mult.el b/lisp/vc/ediff-mult.el index d32c18be8f..49b2890a16 100644 --- a/lisp/vc/ediff-mult.el +++ b/lisp/vc/ediff-mult.el @@ -147,15 +147,15 @@ Useful commands (type ? to hide them and free up screen): (defvar ediff-dir-diffs-buffer-map (let ((map (make-sparse-keymap))) (suppress-keymap map) - (define-key map "q" 'ediff-bury-dir-diffs-buffer) - (define-key map " " 'next-line) - (define-key map "n" 'next-line) - (define-key map "\C-?" 'previous-line) - (define-key map "p" 'previous-line) - (define-key map "C" 'ediff-dir-diff-copy-file) - (define-key map [mouse-2] 'ediff-dir-diff-copy-file) - (define-key map [delete] 'previous-line) - (define-key map [backspace] 'previous-line) + (define-key map "q" #'ediff-bury-dir-diffs-buffer) + (define-key map " " #'next-line) + (define-key map "n" #'next-line) + (define-key map "\C-?" #'previous-line) + (define-key map "p" #'previous-line) + (define-key map "C" #'ediff-dir-diff-copy-file) + (define-key map [mouse-2] #'ediff-dir-diff-copy-file) + (define-key map [delete] #'previous-line) + (define-key map [backspace] #'previous-line) map) "The keymap to be installed in the buffer showing differences between directories.") @@ -413,12 +413,11 @@ Toggled by ediff-toggle-verbose-help-meta-buffer" ) '(menu-item "Show Manual" ediff-documentation :help "Display Ediff's manual")) - (or (ediff-one-filegroup-metajob) - (progn - (define-key ediff-meta-buffer-map "=" nil) - (define-key ediff-meta-buffer-map "==" 'ediff-meta-mark-equal-files) - (define-key ediff-meta-buffer-map "=m" 'ediff-meta-mark-equal-files) - (define-key ediff-meta-buffer-map "=h" 'ediff-meta-mark-equal-files))) + (unless (ediff-one-filegroup-metajob) + (define-key ediff-meta-buffer-map "=" nil) + (define-key ediff-meta-buffer-map "==" #'ediff-meta-mark-equal-files) + (define-key ediff-meta-buffer-map "=m" #'ediff-meta-mark-equal-files) + (define-key ediff-meta-buffer-map "=h" #'ediff-meta-mark-equal-files)) (define-key menu-map [ediff-next-meta-item] @@ -430,7 +429,7 @@ Toggled by ediff-toggle-verbose-help-meta-buffer" ) (if ediff-no-emacs-help-in-control-buffer - (define-key ediff-meta-buffer-map "\C-h" 'ediff-previous-meta-item)) + (define-key ediff-meta-buffer-map "\C-h" #'ediff-previous-meta-item)) (define-key ediff-meta-buffer-map [mouse-2] ediff-meta-action-function) (use-local-map ediff-meta-buffer-map) @@ -633,7 +632,7 @@ behavior." difflist (delete "." difflist) ;; copying is needed because sort sorts via side effects difflist (sort (ediff-copy-list (delete ".." difflist)) - 'string-lessp)) + #'string-lessp)) (setq difflist (mapcar (lambda (elt) (cons elt 1)) difflist)) @@ -837,14 +836,14 @@ behavior." (ediff-draw-dir-diffs ediff-dir-difference-list)) (define-key ediff-meta-buffer-map "h" 'ediff-mark-for-hiding-at-pos) - (define-key ediff-meta-buffer-map "x" 'ediff-hide-marked-sessions) + (define-key ediff-meta-buffer-map "x" #'ediff-hide-marked-sessions) (define-key - ediff-meta-buffer-map "m" 'ediff-mark-for-operation-at-pos) + ediff-meta-buffer-map "m" #'ediff-mark-for-operation-at-pos) (define-key ediff-meta-buffer-map "u" nil) (define-key - ediff-meta-buffer-map "um" 'ediff-unmark-all-for-operation) + ediff-meta-buffer-map "um" #'ediff-unmark-all-for-operation) (define-key - ediff-meta-buffer-map "uh" 'ediff-unmark-all-for-hiding) + ediff-meta-buffer-map "uh" #'ediff-unmark-all-for-hiding) (define-key ediff-meta-buffer-map [menu-bar ediff-meta-mode ediff-hide-marked-sessions] @@ -877,7 +876,7 @@ behavior." '(menu-item "Collect diffs" ediff-collect-custom-diffs :help "Collect custom diffs of marked sessions in buffer `*Ediff Multifile Diffs*'")) (define-key - ediff-meta-buffer-map "P" 'ediff-collect-custom-diffs)) + ediff-meta-buffer-map "P" #'ediff-collect-custom-diffs)) ((ediff-patch-metajob jobname) (define-key ediff-meta-buffer-map [menu-bar ediff-meta-mode ediff-meta-show-patch] @@ -885,8 +884,8 @@ behavior." :help "Show the multi-file patch associated with this group session")) (define-key ediff-meta-buffer-map "P" 'ediff-meta-show-patch))) - (define-key ediff-meta-buffer-map "^" 'ediff-up-meta-hierarchy) - (define-key ediff-meta-buffer-map "D" 'ediff-show-dir-diffs) + (define-key ediff-meta-buffer-map "^" #'ediff-up-meta-hierarchy) + (define-key ediff-meta-buffer-map "D" #'ediff-show-dir-diffs) (define-key ediff-meta-buffer-map [menu-bar ediff-meta-mode ediff-up-meta-hierarchy] @@ -2128,7 +2127,7 @@ all marked sessions must be active." )) ;;;###autoload -(defalias 'eregistry 'ediff-show-registry) +(defalias 'eregistry #'ediff-show-registry) ;; If meta-buf doesn't exist, it is created. In that case, id doesn't have a ;; parent meta-buf diff --git a/lisp/vc/ediff-util.el b/lisp/vc/ediff-util.el index 9909dcd542..fc6dcf68a4 100644 --- a/lisp/vc/ediff-util.el +++ b/lisp/vc/ediff-util.el @@ -123,106 +123,106 @@ to invocation.") (setq ediff-mode-map (make-sparse-keymap)) (suppress-keymap ediff-mode-map) - (define-key ediff-mode-map [mouse-2] 'ediff-help-for-quick-help) - (define-key ediff-mode-map "\C-m" 'ediff-help-for-quick-help) + (define-key ediff-mode-map [mouse-2] #'ediff-help-for-quick-help) + (define-key ediff-mode-map "\C-m" #'ediff-help-for-quick-help) - (define-key ediff-mode-map "p" 'ediff-previous-difference) - (define-key ediff-mode-map "\C-?" 'ediff-previous-difference) - (define-key ediff-mode-map [delete] 'ediff-previous-difference) + (define-key ediff-mode-map "p" #'ediff-previous-difference) + (define-key ediff-mode-map "\C-?" #'ediff-previous-difference) + (define-key ediff-mode-map [delete] #'ediff-previous-difference) (define-key ediff-mode-map "\C-h" (if ediff-no-emacs-help-in-control-buffer - 'ediff-previous-difference nil)) - (define-key ediff-mode-map [backspace] 'ediff-previous-difference) - (define-key ediff-mode-map [?\S-\ ] 'ediff-previous-difference) - (define-key ediff-mode-map "n" 'ediff-next-difference) - (define-key ediff-mode-map " " 'ediff-next-difference) - (define-key ediff-mode-map "j" 'ediff-jump-to-difference) + #'ediff-previous-difference nil)) + (define-key ediff-mode-map [backspace] #'ediff-previous-difference) + (define-key ediff-mode-map [?\S-\ ] #'ediff-previous-difference) + (define-key ediff-mode-map "n" #'ediff-next-difference) + (define-key ediff-mode-map " " #'ediff-next-difference) + (define-key ediff-mode-map "j" #'ediff-jump-to-difference) (define-key ediff-mode-map "g" nil) - (define-key ediff-mode-map "ga" 'ediff-jump-to-difference-at-point) - (define-key ediff-mode-map "gb" 'ediff-jump-to-difference-at-point) - (define-key ediff-mode-map "q" 'ediff-quit) - (define-key ediff-mode-map "D" 'ediff-show-diff-output) - (define-key ediff-mode-map "z" 'ediff-suspend) - (define-key ediff-mode-map "\C-l" 'ediff-recenter) - (define-key ediff-mode-map "|" 'ediff-toggle-split) - (define-key ediff-mode-map "h" 'ediff-toggle-hilit) + (define-key ediff-mode-map "ga" #'ediff-jump-to-difference-at-point) + (define-key ediff-mode-map "gb" #'ediff-jump-to-difference-at-point) + (define-key ediff-mode-map "q" #'ediff-quit) + (define-key ediff-mode-map "D" #'ediff-show-diff-output) + (define-key ediff-mode-map "z" #'ediff-suspend) + (define-key ediff-mode-map "\C-l" #'ediff-recenter) + (define-key ediff-mode-map "|" #'ediff-toggle-split) + (define-key ediff-mode-map "h" #'ediff-toggle-hilit) (or ediff-word-mode - (define-key ediff-mode-map "@" 'ediff-toggle-autorefine)) + (define-key ediff-mode-map "@" #'ediff-toggle-autorefine)) (if ediff-narrow-job - (define-key ediff-mode-map "%" 'ediff-toggle-narrow-region)) - (define-key ediff-mode-map "~" 'ediff-swap-buffers) - (define-key ediff-mode-map "v" 'ediff-scroll-vertically) - (define-key ediff-mode-map "\C-v" 'ediff-scroll-vertically) - (define-key ediff-mode-map "^" 'ediff-scroll-vertically) - (define-key ediff-mode-map "\M-v" 'ediff-scroll-vertically) - (define-key ediff-mode-map "V" 'ediff-scroll-vertically) - (define-key ediff-mode-map "<" 'ediff-scroll-horizontally) - (define-key ediff-mode-map ">" 'ediff-scroll-horizontally) - (define-key ediff-mode-map "i" 'ediff-status-info) - (define-key ediff-mode-map "E" 'ediff-documentation) - (define-key ediff-mode-map "?" 'ediff-toggle-help) - (define-key ediff-mode-map "!" 'ediff-update-diffs) - (define-key ediff-mode-map "M" 'ediff-show-current-session-meta-buffer) - (define-key ediff-mode-map "R" 'ediff-show-registry) + (define-key ediff-mode-map "%" #'ediff-toggle-narrow-region)) + (define-key ediff-mode-map "~" #'ediff-swap-buffers) + (define-key ediff-mode-map "v" #'ediff-scroll-vertically) + (define-key ediff-mode-map "\C-v" #'ediff-scroll-vertically) + (define-key ediff-mode-map "^" #'ediff-scroll-vertically) + (define-key ediff-mode-map "\M-v" #'ediff-scroll-vertically) + (define-key ediff-mode-map "V" #'ediff-scroll-vertically) + (define-key ediff-mode-map "<" #'ediff-scroll-horizontally) + (define-key ediff-mode-map ">" #'ediff-scroll-horizontally) + (define-key ediff-mode-map "i" #'ediff-status-info) + (define-key ediff-mode-map "E" #'ediff-documentation) + (define-key ediff-mode-map "?" #'ediff-toggle-help) + (define-key ediff-mode-map "!" #'ediff-update-diffs) + (define-key ediff-mode-map "M" #'ediff-show-current-session-meta-buffer) + (define-key ediff-mode-map "R" #'ediff-show-registry) (or ediff-word-mode - (define-key ediff-mode-map "*" 'ediff-make-or-kill-fine-diffs)) + (define-key ediff-mode-map "*" #'ediff-make-or-kill-fine-diffs)) (define-key ediff-mode-map "a" nil) (define-key ediff-mode-map "b" nil) (define-key ediff-mode-map "r" nil) (cond (ediff-merge-job ;; Will barf if no ancestor - (define-key ediff-mode-map "/" 'ediff-toggle-show-ancestor) + (define-key ediff-mode-map "/" #'ediff-toggle-show-ancestor) ;; In merging, we allow only A->C and B->C copying. - (define-key ediff-mode-map "a" 'ediff-copy-A-to-C) - (define-key ediff-mode-map "b" 'ediff-copy-B-to-C) - (define-key ediff-mode-map "r" 'ediff-restore-diff-in-merge-buffer) - (define-key ediff-mode-map "s" 'ediff-shrink-window-C) - (define-key ediff-mode-map "+" 'ediff-combine-diffs) + (define-key ediff-mode-map "a" #'ediff-copy-A-to-C) + (define-key ediff-mode-map "b" #'ediff-copy-B-to-C) + (define-key ediff-mode-map "r" #'ediff-restore-diff-in-merge-buffer) + (define-key ediff-mode-map "s" #'ediff-shrink-window-C) + (define-key ediff-mode-map "+" #'ediff-combine-diffs) (define-key ediff-mode-map "$" nil) - (define-key ediff-mode-map "$$" 'ediff-toggle-show-clashes-only) - (define-key ediff-mode-map "$*" 'ediff-toggle-skip-changed-regions) - (define-key ediff-mode-map "&" 'ediff-re-merge)) + (define-key ediff-mode-map "$$" #'ediff-toggle-show-clashes-only) + (define-key ediff-mode-map "$*" #'ediff-toggle-skip-changed-regions) + (define-key ediff-mode-map "&" #'ediff-re-merge)) (ediff-3way-comparison-job - (define-key ediff-mode-map "ab" 'ediff-copy-A-to-B) - (define-key ediff-mode-map "ba" 'ediff-copy-B-to-A) - (define-key ediff-mode-map "ac" 'ediff-copy-A-to-C) - (define-key ediff-mode-map "bc" 'ediff-copy-B-to-C) + (define-key ediff-mode-map "ab" #'ediff-copy-A-to-B) + (define-key ediff-mode-map "ba" #'ediff-copy-B-to-A) + (define-key ediff-mode-map "ac" #'ediff-copy-A-to-C) + (define-key ediff-mode-map "bc" #'ediff-copy-B-to-C) (define-key ediff-mode-map "c" nil) - (define-key ediff-mode-map "ca" 'ediff-copy-C-to-A) - (define-key ediff-mode-map "cb" 'ediff-copy-C-to-B) - (define-key ediff-mode-map "ra" 'ediff-restore-diff) - (define-key ediff-mode-map "rb" 'ediff-restore-diff) - (define-key ediff-mode-map "rc" 'ediff-restore-diff) - (define-key ediff-mode-map "C" 'ediff-toggle-read-only)) + (define-key ediff-mode-map "ca" #'ediff-copy-C-to-A) + (define-key ediff-mode-map "cb" #'ediff-copy-C-to-B) + (define-key ediff-mode-map "ra" #'ediff-restore-diff) + (define-key ediff-mode-map "rb" #'ediff-restore-diff) + (define-key ediff-mode-map "rc" #'ediff-restore-diff) + (define-key ediff-mode-map "C" #'ediff-toggle-read-only)) (t ; 2-way comparison - (define-key ediff-mode-map "a" 'ediff-copy-A-to-B) - (define-key ediff-mode-map "b" 'ediff-copy-B-to-A) - (define-key ediff-mode-map "ra" 'ediff-restore-diff) - (define-key ediff-mode-map "rb" 'ediff-restore-diff)) + (define-key ediff-mode-map "a" #'ediff-copy-A-to-B) + (define-key ediff-mode-map "b" #'ediff-copy-B-to-A) + (define-key ediff-mode-map "ra" #'ediff-restore-diff) + (define-key ediff-mode-map "rb" #'ediff-restore-diff)) ) ; cond - (define-key ediff-mode-map "G" 'ediff-submit-report) + (define-key ediff-mode-map "G" #'ediff-submit-report) (define-key ediff-mode-map "#" nil) - (define-key ediff-mode-map "#h" 'ediff-toggle-regexp-match) - (define-key ediff-mode-map "#f" 'ediff-toggle-regexp-match) - (define-key ediff-mode-map "#c" 'ediff-toggle-ignore-case) + (define-key ediff-mode-map "#h" #'ediff-toggle-regexp-match) + (define-key ediff-mode-map "#f" #'ediff-toggle-regexp-match) + (define-key ediff-mode-map "#c" #'ediff-toggle-ignore-case) (or ediff-word-mode - (define-key ediff-mode-map "##" 'ediff-toggle-skip-similar)) + (define-key ediff-mode-map "##" #'ediff-toggle-skip-similar)) (define-key ediff-mode-map "o" nil) - (define-key ediff-mode-map "A" 'ediff-toggle-read-only) - (define-key ediff-mode-map "B" 'ediff-toggle-read-only) + (define-key ediff-mode-map "A" #'ediff-toggle-read-only) + (define-key ediff-mode-map "B" #'ediff-toggle-read-only) (define-key ediff-mode-map "w" nil) - (define-key ediff-mode-map "wa" 'ediff-save-buffer) - (define-key ediff-mode-map "wb" 'ediff-save-buffer) - (define-key ediff-mode-map "wd" 'ediff-save-buffer) - (define-key ediff-mode-map "=" 'ediff-inferior-compare-regions) + (define-key ediff-mode-map "wa" #'ediff-save-buffer) + (define-key ediff-mode-map "wb" #'ediff-save-buffer) + (define-key ediff-mode-map "wd" #'ediff-save-buffer) + (define-key ediff-mode-map "=" #'ediff-inferior-compare-regions) (if (and (fboundp 'ediff-show-patch-diagnostics) (ediff-patch-job)) - (define-key ediff-mode-map "P" 'ediff-show-patch-diagnostics)) + (define-key ediff-mode-map "P" #'ediff-show-patch-diagnostics)) (if ediff-3way-job (progn - (define-key ediff-mode-map "wc" 'ediff-save-buffer) - (define-key ediff-mode-map "gc" 'ediff-jump-to-difference-at-point) + (define-key ediff-mode-map "wc" #'ediff-save-buffer) + (define-key ediff-mode-map "gc" #'ediff-jump-to-difference-at-point) )) - (define-key ediff-mode-map "m" 'ediff-toggle-wide-display) + (define-key ediff-mode-map "m" #'ediff-toggle-wide-display) ;; Allow ediff-mode-map to be referenced indirectly (fset 'ediff-mode-map ediff-mode-map) diff --git a/lisp/vc/ediff-wind.el b/lisp/vc/ediff-wind.el index 47ef37a19e..fc6ea944ae 100644 --- a/lisp/vc/ediff-wind.el +++ b/lisp/vc/ediff-wind.el @@ -1043,8 +1043,8 @@ create a new splittable frame if none is found." (with-current-buffer ctl-buffer (let* ((frame-A (window-frame ediff-window-A)) (frame-A-parameters (frame-parameters frame-A)) - (frame-A-top (eval (cdr (assoc 'top frame-A-parameters)))) - (frame-A-left (eval (cdr (assoc 'left frame-A-parameters)))) + (frame-A-top (eval (cdr (assoc 'top frame-A-parameters)) t)) + (frame-A-left (eval (cdr (assoc 'left frame-A-parameters)) t)) (frame-A-width (frame-width frame-A)) (ctl-frame ediff-control-frame) horizontal-adjustment upward-adjustment @@ -1105,7 +1105,7 @@ It assumes that it is called from within the control buffer." (cw (frame-char-width frame-A)) (wd (- (/ (display-pixel-width) cw) 5))) (setq ediff-wide-display-orig-parameters - (list (cons 'left (max 0 (eval (cdr (assoc 'left frame-A-params))))) + (list (cons 'left (max 0 (eval (cdr (assoc 'left frame-A-params)) t))) (cons 'width (cdr (assoc 'width frame-A-params)))) ediff-wide-display-frame frame-A) (modify-frame-parameters diff --git a/lisp/vc/ediff.el b/lisp/vc/ediff.el index ed375738b4..3536cbf738 100644 --- a/lisp/vc/ediff.el +++ b/lisp/vc/ediff.el @@ -264,7 +264,7 @@ arguments after setting up the Ediff buffers." 'ediff-files3)) ;;;###autoload -(defalias 'ediff3 'ediff-files3) +(defalias 'ediff3 #'ediff-files3) (defvar-local ediff--magic-file-name nil "Name of file where buffer's content was saved. @@ -359,7 +359,7 @@ has been saved (if not in `buffer-file-name')." (declare-function diff-latest-backup-file "diff" (fn)) ;;;###autoload -(defalias 'ediff 'ediff-files) +(defalias 'ediff #'ediff-files) ;;;###autoload (defun ediff-current-file () @@ -442,7 +442,7 @@ symbol describing the Ediff job type; it defaults to (ediff-buffers-internal buffer-A buffer-B nil startup-hooks job-name)) ;;;###autoload -(defalias 'ebuffers 'ediff-buffers) +(defalias 'ebuffers #'ediff-buffers) ;;;###autoload @@ -479,7 +479,7 @@ symbol describing the Ediff job type; it defaults to (ediff-buffers-internal buffer-A buffer-B buffer-C startup-hooks job-name)) ;;;###autoload -(defalias 'ebuffers3 'ediff-buffers3) +(defalias 'ebuffers3 #'ediff-buffers3) @@ -556,7 +556,7 @@ the same name in both. The third argument, REGEXP, is nil or a regular expression; only file names that match the regexp are considered." (interactive (let ((dir-A (ediff-get-default-directory-name)) - (default-regexp (eval ediff-default-filtering-regexp)) + (default-regexp (eval ediff-default-filtering-regexp t)) f) (list (setq f (read-directory-name "Directory A to compare: " dir-A nil 'must-match)) @@ -570,14 +570,14 @@ expression; only file names that match the regexp are considered." default-regexp) nil 'ediff-filtering-regexp-history - (eval ediff-default-filtering-regexp)) + (eval ediff-default-filtering-regexp t)) ))) (ediff-directories-internal dir1 dir2 nil regexp #'ediff-files 'ediff-directories )) ;;;###autoload -(defalias 'edirs 'ediff-directories) +(defalias 'edirs #'ediff-directories) ;;;###autoload @@ -587,7 +587,7 @@ The second argument, REGEXP, is a regular expression that filters the file names. Only the files that are under revision control are taken into account." (interactive (let ((dir-A (ediff-get-default-directory-name)) - (default-regexp (eval ediff-default-filtering-regexp)) + (default-regexp (eval ediff-default-filtering-regexp t)) ) (list (read-directory-name "Directory to compare with revision:" dir-A nil 'must-match) @@ -596,14 +596,14 @@ names. Only the files that are under revision control are taken into account." "Filter filenames through regular expression" default-regexp) nil 'ediff-filtering-regexp-history - (eval ediff-default-filtering-regexp)) + (eval ediff-default-filtering-regexp t)) ))) (ediff-directory-revisions-internal - dir1 regexp 'ediff-revision 'ediff-directory-revisions + dir1 regexp #'ediff-revision 'ediff-directory-revisions )) ;;;###autoload -(defalias 'edir-revisions 'ediff-directory-revisions) +(defalias 'edir-revisions #'ediff-directory-revisions) ;;;###autoload @@ -614,7 +614,7 @@ regular expression; only file names that match the regexp are considered." (interactive (let ((dir-A (ediff-get-default-directory-name)) - (default-regexp (eval ediff-default-filtering-regexp)) + (default-regexp (eval ediff-default-filtering-regexp t)) f) (list (setq f (read-directory-name "Directory A to compare:" dir-A nil)) (setq f (read-directory-name "Directory B to compare:" @@ -632,14 +632,14 @@ regular expression; only file names that match the regexp are considered." default-regexp) nil 'ediff-filtering-regexp-history - (eval ediff-default-filtering-regexp)) + (eval ediff-default-filtering-regexp t)) ))) (ediff-directories-internal dir1 dir2 dir3 regexp #'ediff-files3 'ediff-directories3 )) ;;;###autoload -(defalias 'edirs3 'ediff-directories3) +(defalias 'edirs3 #'ediff-directories3) ;;;###autoload (defun ediff-merge-directories (dir1 dir2 regexp &optional merge-autostore-dir) @@ -649,7 +649,7 @@ expression; only file names that match the regexp are considered. MERGE-AUTOSTORE-DIR is the directory in which to store merged files." (interactive (let ((dir-A (ediff-get-default-directory-name)) - (default-regexp (eval ediff-default-filtering-regexp)) + (default-regexp (eval ediff-default-filtering-regexp t)) f) (list (setq f (read-directory-name "Directory A to merge:" dir-A nil 'must-match)) @@ -663,7 +663,7 @@ MERGE-AUTOSTORE-DIR is the directory in which to store merged files." default-regexp) nil 'ediff-filtering-regexp-history - (eval ediff-default-filtering-regexp)) + (eval ediff-default-filtering-regexp t)) ))) (ediff-directories-internal dir1 dir2 nil regexp #'ediff-merge-files 'ediff-merge-directories @@ -671,7 +671,7 @@ MERGE-AUTOSTORE-DIR is the directory in which to store merged files." )) ;;;###autoload -(defalias 'edirs-merge 'ediff-merge-directories) +(defalias 'edirs-merge #'ediff-merge-directories) ;;;###autoload (defun ediff-merge-directories-with-ancestor (dir1 dir2 ancestor-dir regexp @@ -685,7 +685,7 @@ only file names that match the regexp are considered. MERGE-AUTOSTORE-DIR is the directory in which to store merged files." (interactive (let ((dir-A (ediff-get-default-directory-name)) - (default-regexp (eval ediff-default-filtering-regexp)) + (default-regexp (eval ediff-default-filtering-regexp t)) f) (list (setq f (read-directory-name "Directory A to merge:" dir-A nil)) (setq f (read-directory-name "Directory B to merge:" @@ -703,7 +703,7 @@ MERGE-AUTOSTORE-DIR is the directory in which to store merged files." default-regexp) nil 'ediff-filtering-regexp-history - (eval ediff-default-filtering-regexp)) + (eval ediff-default-filtering-regexp t)) ))) (ediff-directories-internal dir1 dir2 ancestor-dir regexp @@ -720,7 +720,7 @@ names. Only the files that are under revision control are taken into account. MERGE-AUTOSTORE-DIR is the directory in which to store merged files." (interactive (let ((dir-A (ediff-get-default-directory-name)) - (default-regexp (eval ediff-default-filtering-regexp)) + (default-regexp (eval ediff-default-filtering-regexp t)) ) (list (read-directory-name "Directory to merge with revisions:" dir-A nil 'must-match) @@ -729,15 +729,15 @@ MERGE-AUTOSTORE-DIR is the directory in which to store merged files." default-regexp) nil 'ediff-filtering-regexp-history - (eval ediff-default-filtering-regexp)) + (eval ediff-default-filtering-regexp t)) ))) (ediff-directory-revisions-internal - dir1 regexp 'ediff-merge-revisions 'ediff-merge-directory-revisions + dir1 regexp #'ediff-merge-revisions 'ediff-merge-directory-revisions nil merge-autostore-dir )) ;;;###autoload -(defalias 'edir-merge-revisions 'ediff-merge-directory-revisions) +(defalias 'edir-merge-revisions #'ediff-merge-directory-revisions) ;;;###autoload (defun ediff-merge-directory-revisions-with-ancestor (dir1 regexp @@ -749,7 +749,7 @@ names. Only the files that are under revision control are taken into account. MERGE-AUTOSTORE-DIR is the directory in which to store merged files." (interactive (let ((dir-A (ediff-get-default-directory-name)) - (default-regexp (eval ediff-default-filtering-regexp)) + (default-regexp (eval ediff-default-filtering-regexp t)) ) (list (read-directory-name "Directory to merge with revisions and ancestors:" @@ -759,10 +759,10 @@ MERGE-AUTOSTORE-DIR is the directory in which to store merged files." default-regexp) nil 'ediff-filtering-regexp-history - (eval ediff-default-filtering-regexp)) + (eval ediff-default-filtering-regexp t)) ))) (ediff-directory-revisions-internal - dir1 regexp 'ediff-merge-revisions-with-ancestor + dir1 regexp #'ediff-merge-revisions-with-ancestor 'ediff-merge-directory-revisions-with-ancestor nil merge-autostore-dir )) diff --git a/lisp/vc/emerge.el b/lisp/vc/emerge.el index d2d419ac78..8f7affeea4 100644 --- a/lisp/vc/emerge.el +++ b/lisp/vc/emerge.el @@ -79,90 +79,75 @@ but can be invoked directly in `fast' mode." ;; way they number lines of a file. (defcustom emerge-diff-program "diff" "Name of the program which compares two files." - :type 'string - :group 'emerge) + :type 'string) (defcustom emerge-diff3-program "diff3" "Name of the program which compares three files. Its arguments are the ancestor file and the two variant files." - :type 'string - :group 'emerge) + :type 'string) (defcustom emerge-diff-options "" "Options to pass to `emerge-diff-program' and `emerge-diff3-program'." - :type 'string - :group 'emerge) + :type 'string) (defcustom emerge-match-diff-line (let ((x "\\([0-9]+\\)\\(\\|,\\([0-9]+\\)\\)")) (concat "^" x "\\([acd]\\)" x "$")) "Pattern to match lines produced by diff that describe differences. This is as opposed to lines from the source files." - :type 'regexp - :group 'emerge) + :type 'regexp) (defcustom emerge-diff-ok-lines-regexp "^\\([0-9,]+[acd][0-9,]+$\\|[<>] \\|---\\)" "Regexp that matches normal output lines from `emerge-diff-program'. Lines that do not match are assumed to be error messages." - :type 'regexp - :group 'emerge) + :type 'regexp) (defcustom emerge-diff3-ok-lines-regexp "^\\([1-3]:\\|====\\| \\)" "Regexp that matches normal output lines from `emerge-diff3-program'. Lines that do not match are assumed to be error messages." - :type 'regexp - :group 'emerge) + :type 'regexp) (defcustom emerge-rcs-ci-program "ci" "Name of the program that checks in RCS revisions." - :type 'string - :group 'emerge) + :type 'string) (defcustom emerge-rcs-co-program "co" "Name of the program that checks out RCS revisions." - :type 'string - :group 'emerge) + :type 'string) (defcustom emerge-process-local-variables nil "Non-nil if Emerge should process local-variables lists in merge buffers. \(You can explicitly request processing the local-variables by executing `(hack-local-variables)'.)" - :type 'boolean - :group 'emerge) + :type 'boolean) (defcustom emerge-execute-line-deletions nil "If non-nil: `emerge-execute-line' makes no output if an input was deleted. It concludes that an input version has been deleted when an ancestor entry is present, only one A or B entry is present, and an output entry is present. If nil: In such circumstances, the A or B file that is present will be copied to the designated output file." - :type 'boolean - :group 'emerge) + :type 'boolean) (defcustom emerge-before-flag "vvvvvvvvvvvvvvvvvvvv\n" "Flag placed above the highlighted block of code. Must end with newline. Must be set before Emerge is loaded, or emerge-new-flags must be run after setting." - :type 'string - :group 'emerge) + :type 'string) (defcustom emerge-after-flag "^^^^^^^^^^^^^^^^^^^^\n" "Flag placed below the highlighted block of code. Must end with newline. Must be set before Emerge is loaded, or emerge-new-flags must be run after setting." - :type 'string - :group 'emerge) + :type 'string) ;; Hook variables (defcustom emerge-startup-hook nil "Hook to run in the merge buffer after the merge has been set up." - :type 'hook - :group 'emerge) + :type 'hook) (defcustom emerge-select-hook nil "Hook to run after a difference has been selected. The variable `n' holds the (internal) number of the difference." - :type 'hook - :group 'emerge) + :type 'hook) (defcustom emerge-unselect-hook nil "Hook to run after a difference has been unselected. The variable `n' holds the (internal) number of the difference." - :type 'hook - :group 'emerge) + :type 'hook) ;; Variables to control the default directories of the arguments to ;; Emerge commands. @@ -171,8 +156,7 @@ The variable `n' holds the (internal) number of the difference." "If nil, default dir for filenames in emerge is `default-directory'. If non-nil, filenames complete in the directory of the last argument of the same type to an `emerge-files...' command." - :type 'boolean - :group 'emerge) + :type 'boolean) (defvar emerge-last-dir-A nil "Last directory for the first file of an `emerge-files...' command.") @@ -235,15 +219,13 @@ depend on the flags." (defcustom emerge-min-visible-lines 3 "Number of lines that we want to show above and below the flags when we are displaying a difference." - :type 'integer - :group 'emerge) + :type 'integer) (defcustom emerge-temp-file-prefix (expand-file-name "emerge" temporary-file-directory) "Prefix to put on Emerge temporary file names. Do not start with `~/' or `~USERNAME/'." - :type 'string - :group 'emerge) + :type 'string) (make-obsolete-variable 'emerge-temp-file-prefix "customize `temporary-file-directory' instead." @@ -251,8 +233,7 @@ Do not start with `~/' or `~USERNAME/'." (defcustom emerge-temp-file-mode 384 ; u=rw only "Mode for Emerge temporary files." - :type 'integer - :group 'emerge) + :type 'integer) (make-obsolete-variable 'emerge-temp-file-mode "it has no effect, temporary files are always private." @@ -268,8 +249,7 @@ The template is inserted as a string, with the following interpolations: Don't forget to end the template with a newline. Note that this variable can be made local to a particular merge buffer by giving a prefix argument to `emerge-set-combine-versions-template'." - :type 'string - :group 'emerge) + :type 'string) ;; Build keymaps @@ -294,8 +274,7 @@ Makes Emerge commands directly available.") (defcustom emerge-command-prefix "\C-c\C-c" "Command prefix for Emerge commands in `edit' mode. Must be set before Emerge is loaded." - :type 'string - :group 'emerge) + :type 'string) ;; This function sets up the fixed keymaps. It is executed when the first ;; Emerge is done to allow the user maximum time to set up the global keymap. @@ -1245,8 +1224,7 @@ Otherwise, the A or B file present is copied to the output file." (defcustom emerge-merge-directories-filename-regexp "[^.]" "Regexp describing files to be processed by `emerge-merge-directories'." - :type 'regexp - :group 'emerge) + :type 'regexp) ;;;###autoload (defun emerge-merge-directories (a-dir b-dir ancestor-dir output-dir) @@ -3070,8 +3048,7 @@ See also `auto-save-file-name-p'." (defcustom emerge-metachars nil "No longer used. Emerge now uses `shell-quote-argument'." - :type '(choice (const nil) regexp) - :group 'emerge) + :type '(choice (const nil) regexp)) (make-obsolete-variable 'emerge-metachars nil "26.1") (provide 'emerge) diff --git a/lisp/vc/pcvs-defs.el b/lisp/vc/pcvs-defs.el index 2ee3da7027..54ef06960f 100644 --- a/lisp/vc/pcvs-defs.el +++ b/lisp/vc/pcvs-defs.el @@ -1,4 +1,4 @@ -;;; pcvs-defs.el --- variable definitions for PCL-CVS +;;; pcvs-defs.el --- variable definitions for PCL-CVS -*- lexical-binding: t; -*- ;; Copyright (C) 1991-2021 Free Software Foundation, Inc. @@ -71,7 +71,6 @@ versions, such as the one in SunOS-4.") (defcustom cvs-cvsrc-file (convert-standard-filename "~/.cvsrc") "Path to your cvsrc file." - :group 'pcl-cvs :type '(file)) (defvar cvs-shared-start 4 @@ -96,24 +95,20 @@ If t, they will be removed from the *cvs* buffer after every command. If `delayed', they will be removed from the *cvs* buffer before every command. If `status', they will only be removed after a `cvs-mode-status' command. Else, they will never be automatically removed from the *cvs* buffer." - :group 'pcl-cvs :type '(choice (const nil) (const status) (const delayed) (const t))) (defcustom cvs-auto-remove-directories 'handled "If `all', directory entries will never be shown. If `handled', only non-handled directories will be shown. If `empty', only non-empty directories will be shown." - :group 'pcl-cvs :type '(choice (const :tag "No" nil) (const all) (const handled) (const empty))) (defcustom cvs-auto-revert t "Non-nil if changed files should automatically be reverted." - :group 'pcl-cvs :type '(boolean)) (defcustom cvs-sort-ignore-file t "Non-nil if `cvs-mode-ignore' should sort the .cvsignore automatically." - :group 'pcl-cvs :type '(boolean)) (defcustom cvs-force-dir-tag t @@ -121,7 +116,6 @@ If `empty', only non-empty directories will be shown." Tagging should generally be applied a directory at a time, but sometimes it is useful to be able to tag a single file. The normal way to do that is to use `cvs-mode-force-command' so as to temporarily override the restrictions." - :group 'pcl-cvs :type '(boolean)) (defcustom cvs-default-ignore-marks nil @@ -130,7 +124,6 @@ Normally they run on the files that are marked (with `cvs-mode-mark'), or the file under the cursor if no files are marked. If this variable is set to a non-nil value they will by default run on the file on the current line. See also `cvs-invert-ignore-marks'." - :group 'pcl-cvs :type '(boolean)) (defcustom cvs-invert-ignore-marks @@ -143,7 +136,6 @@ current line. See also `cvs-invert-ignore-marks'." "List of cvs commands that invert the default ignore-mark behavior. Commands in this set will use the opposite default from the one set in `cvs-default-ignore-marks'." - :group 'pcl-cvs :type '(set (const "diff") (const "tag") (const "ignore"))) @@ -154,7 +146,6 @@ Non-nil means that PCL-CVS will ask confirmation before removing files except for files whose content can readily be recovered from the repository. A value of `list' means that the list of files to be deleted will be displayed when asking for confirmation." - :group 'pcl-cvs :type '(choice (const list) (const t) (const nil))) @@ -162,7 +153,6 @@ displayed when asking for confirmation." (defcustom cvs-add-default-message nil "Default message to use when adding files. If set to nil, `cvs-mode-add' will always prompt for a message." - :group 'pcl-cvs :type '(choice (const :tag "Prompt" nil) (string))) @@ -171,7 +161,6 @@ If set to nil, `cvs-mode-add' will always prompt for a message." If non-nil, `cvs-mode-find-file' will place the cursor at the beginning of the modified area. If the file is not locally modified, this will obviously have no effect." - :group 'pcl-cvs :type '(boolean)) (defcustom cvs-buffer-name-alist @@ -193,7 +182,6 @@ POSTPROC is a function that should be executed when the command terminates The CMD used for `cvs-mode-commit' is \"message\". For that special case, POSTPROC is called just after MODE with special arguments." - :group 'pcl-cvs :type '(repeat (list (choice (const "diff") (const "status") @@ -236,7 +224,6 @@ Output from cvs is placed here for asynchronous commands.") '(cvs-ediff-diff . cvs-ediff-merge) '(cvs-emerge-diff . cvs-emerge-merge)) "Pair of functions to be used for resp. diff'ing and merg'ing interactively." - :group 'pcl-cvs :type '(choice (const :tag "Ediff" (cvs-ediff-diff . cvs-ediff-merge)) (const :tag "Emerge" (cvs-emerge-diff . cvs-emerge-merge)))) @@ -255,7 +242,6 @@ Alternatives are: `samedir': reuse any cvs buffer displaying the same directory `subdir': or reuse any cvs buffer displaying any sub- or super- directory `always': reuse any cvs buffer." - :group 'pcl-cvs :type '(choice (const always) (const subdir) (const samedir) (const current))) (defvar cvs-temp-buffer nil @@ -424,8 +410,7 @@ This variable is buffer local and only used in the *cvs* buffer.") (defcustom cvs-minor-mode-prefix "\C-xc" "Prefix key for the `cvs-mode' bindings in `cvs-minor-mode'." - :type 'string - :group 'pcl-cvs) + :type 'string) (easy-mmode-defmap cvs-minor-mode-map `((,cvs-minor-mode-prefix . cvs-mode-map) diff --git a/lisp/vc/pcvs-info.el b/lisp/vc/pcvs-info.el index e1197176af..21fe98daca 100644 --- a/lisp/vc/pcvs-info.el +++ b/lisp/vc/pcvs-info.el @@ -1,4 +1,4 @@ -;;; pcvs-info.el --- internal representation of a fileinfo entry +;;; pcvs-info.el --- internal representation of a fileinfo entry -*- lexical-binding: t; -*- ;; Copyright (C) 1991-2021 Free Software Foundation, Inc. @@ -384,8 +384,8 @@ For use by the ewoc package." The ordering defined by this function is such that directories are sorted alphabetically, and inside every directory the DIRCHANGE fileinfo will appear first, followed by all files (alphabetically)." - (let ((subtypea (cvs-fileinfo->subtype a)) - (subtypeb (cvs-fileinfo->subtype b))) + (let ( ;; (subtypea (cvs-fileinfo->subtype a)) + ) ;; (subtypeb (cvs-fileinfo->subtype b)) (cond ;; Sort according to directories. ((string< (cvs-fileinfo->dir a) (cvs-fileinfo->dir b)) t) diff --git a/lisp/vc/pcvs-parse.el b/lisp/vc/pcvs-parse.el index a95ea0d99d..d0b2e898b0 100644 --- a/lisp/vc/pcvs-parse.el +++ b/lisp/vc/pcvs-parse.el @@ -186,7 +186,7 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'." (let ((type (if (consp type) (car type) type)) (subtype (if (consp type) (cdr type)))) (when dir (setq cvs-current-dir dir)) - (apply 'cvs-create-fileinfo type + (apply #'cvs-create-fileinfo type (concat cvs-current-subdir (or dir cvs-current-dir)) file (cvs-parse-msg) :subtype subtype keys)))) diff --git a/lisp/vc/pcvs-util.el b/lisp/vc/pcvs-util.el index 57da7bf730..75d9fe9bee 100644 --- a/lisp/vc/pcvs-util.el +++ b/lisp/vc/pcvs-util.el @@ -1,4 +1,4 @@ -;;; pcvs-util.el --- utility functions for PCL-CVS +;;; pcvs-util.el --- utility functions for PCL-CVS -*- lexical-binding: t; -*- ;; Copyright (C) 1991-2021 Free Software Foundation, Inc. @@ -33,27 +33,9 @@ ;;;; (defsubst cvs-car (x) (if (consp x) (car x) x)) -(defalias 'cvs-cdr 'cdr-safe) +(defalias 'cvs-cdr #'cdr-safe) (defsubst cvs-append (&rest xs) - (apply 'append (mapcar (lambda (x) (if (listp x) x (list x))) xs))) - -(defsubst cvs-every (-cvs-every-f -cvs-every-l) - (while (consp -cvs-every-l) - (unless (funcall -cvs-every-f (pop -cvs-every-l)) - (setq -cvs-every-l t))) - (not -cvs-every-l)) - -(defun cvs-union (xs ys) - (let ((zs ys)) - (dolist (x xs zs) - (unless (member x ys) (push x zs))))) - -(defun cvs-map (-cvs-map-f &rest -cvs-map-ls) - (let ((accum ())) - (while (not (cvs-every 'null -cvs-map-ls)) - (push (apply -cvs-map-f (mapcar 'car -cvs-map-ls)) accum) - (setq -cvs-map-ls (mapcar 'cdr -cvs-map-ls))) - (nreverse accum))) + (apply #'append (mapcar (lambda (x) (if (listp x) x (list x))) xs))) (defun cvs-first (l &optional n) (if (null n) (car l) @@ -146,7 +128,7 @@ If NOREUSE is non-nil, always return a new buffer." "Insert a list of STRINGS into the current buffer. Uses columns to keep the listing readable but compact." (when (consp strings) - (let* ((length (apply 'max (mapcar 'length strings))) + (let* ((length (apply #'max (mapcar #'length strings))) (wwidth (1- (window-width))) (columns (min ;; At least 2 columns; at least 2 spaces between columns. @@ -174,7 +156,7 @@ arguments. If ARGS is not a list, no argument will be passed." (condition-case nil (with-temp-buffer (if args - (apply 'call-process + (apply #'call-process file nil t nil (when (listp args) args)) (insert-file-contents file)) (goto-char (point-min)) @@ -182,7 +164,7 @@ arguments. If ARGS is not a list, no argument will be passed." (if oneline (line-end-position) (point-max)))) (file-error nil))) -(define-obsolete-function-alias 'cvs-string-prefix-p 'string-prefix-p "24.3") +(define-obsolete-function-alias 'cvs-string-prefix-p #'string-prefix-p "24.3") ;;;; ;;;; file names diff --git a/lisp/vc/pcvs.el b/lisp/vc/pcvs.el index 1a42c67cb1..6e039cc625 100644 --- a/lisp/vc/pcvs.el +++ b/lisp/vc/pcvs.el @@ -115,7 +115,7 @@ ;;; Code: -(eval-when-compile (require 'cl-lib)) +(require 'cl-lib) (require 'ewoc) ;Ewoc was once cookie (require 'pcvs-defs) (require 'pcvs-util) @@ -513,7 +513,7 @@ If non-nil, NEW means to create a new buffer no matter what." (let* ((dir+files+rest (if (or (null fis) (not single-dir)) ;; not single-dir mode: just process the whole thing - (list "" (mapcar 'cvs-fileinfo->full-name fis) nil) + (list "" (mapcar #'cvs-fileinfo->full-name fis) nil) ;; single-dir mode: extract the same-dir-elements (let ((dir (cvs-fileinfo->dir (car fis)))) ;; output the concerned dir so the parser can translate paths @@ -2135,11 +2135,11 @@ Returns a list of FIS that should be `cvs remove'd." (eq (cvs-fileinfo->type fi) 'UNKNOWN)) (cvs-mode-marked filter cmd)))) (silent (or (not cvs-confirm-removals) - (cvs-every (lambda (fi) - (or (not (file-exists-p - (cvs-fileinfo->full-name fi))) - (cvs-applicable-p fi 'safe-rm))) - files))) + (cl-every (lambda (fi) + (or (not (file-exists-p + (cvs-fileinfo->full-name fi))) + (cvs-applicable-p fi 'safe-rm))) + files))) (tmpbuf (cvs-temp-buffer))) (when (and (not silent) (equal cvs-confirm-removals 'list)) (with-current-buffer tmpbuf diff --git a/lisp/vc/vc-annotate.el b/lisp/vc/vc-annotate.el index b0435ab53e..07b2800c2d 100644 --- a/lisp/vc/vc-annotate.el +++ b/lisp/vc/vc-annotate.el @@ -164,18 +164,18 @@ List of factors, used to expand/compress the time scale. See `vc-annotate'." (defvar vc-annotate-mode-map (let ((m (make-sparse-keymap))) - (define-key m "a" 'vc-annotate-revision-previous-to-line) - (define-key m "d" 'vc-annotate-show-diff-revision-at-line) - (define-key m "=" 'vc-annotate-show-diff-revision-at-line) - (define-key m "D" 'vc-annotate-show-changeset-diff-revision-at-line) - (define-key m "f" 'vc-annotate-find-revision-at-line) - (define-key m "j" 'vc-annotate-revision-at-line) - (define-key m "l" 'vc-annotate-show-log-revision-at-line) - (define-key m "n" 'vc-annotate-next-revision) - (define-key m "p" 'vc-annotate-prev-revision) - (define-key m "w" 'vc-annotate-working-revision) - (define-key m "v" 'vc-annotate-toggle-annotation-visibility) - (define-key m "\C-m" 'vc-annotate-goto-line) + (define-key m "a" #'vc-annotate-revision-previous-to-line) + (define-key m "d" #'vc-annotate-show-diff-revision-at-line) + (define-key m "=" #'vc-annotate-show-diff-revision-at-line) + (define-key m "D" #'vc-annotate-show-changeset-diff-revision-at-line) + (define-key m "f" #'vc-annotate-find-revision-at-line) + (define-key m "j" #'vc-annotate-revision-at-line) + (define-key m "l" #'vc-annotate-show-log-revision-at-line) + (define-key m "n" #'vc-annotate-next-revision) + (define-key m "p" #'vc-annotate-prev-revision) + (define-key m "w" #'vc-annotate-working-revision) + (define-key m "v" #'vc-annotate-toggle-annotation-visibility) + (define-key m "\C-m" #'vc-annotate-goto-line) m) "Local keymap used for VC-Annotate mode.") diff --git a/lisp/vc/vc-bzr.el b/lisp/vc/vc-bzr.el index d1385ea778..de5a90dc60 100644 --- a/lisp/vc/vc-bzr.el +++ b/lisp/vc/vc-bzr.el @@ -45,9 +45,9 @@ ;;; Code: +(require 'vc-dispatcher) (eval-when-compile (require 'cl-lib) - (require 'vc-dispatcher) (require 'vc-dir)) ; vc-dir-at-event (declare-function vc-deduce-fileset "vc" @@ -66,7 +66,6 @@ (defcustom vc-bzr-program "bzr" "Name of the bzr command (excluding any arguments)." - :group 'vc-bzr :type 'string) (defcustom vc-bzr-diff-switches nil @@ -75,8 +74,7 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." :type '(choice (const :tag "Unspecified" nil) (const :tag "None" t) (string :tag "Argument String") - (repeat :tag "Argument List" :value ("") string)) - :group 'vc-bzr) + (repeat :tag "Argument List" :value ("") string))) (defcustom vc-bzr-annotate-switches nil "String or list of strings specifying switches for bzr annotate under VC. @@ -85,15 +83,13 @@ If nil, use the value of `vc-annotate-switches'. If t, use no switches." (const :tag "None" t) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "25.1" - :group 'vc-bzr) + :version "25.1") (defcustom vc-bzr-log-switches nil "String or list of strings specifying switches for bzr log under VC." :type '(choice (const :tag "None" nil) (string :tag "Argument String") - (repeat :tag "Argument List" :value ("") string)) - :group 'vc-bzr) + (repeat :tag "Argument List" :value ("") string))) (defcustom vc-bzr-status-switches (ignore-errors @@ -108,7 +104,6 @@ The option \"--no-classify\" should be present if your bzr supports it." :type '(choice (const :tag "None" nil) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :group 'vc-bzr :version "24.1") ;; since v0.9, bzr supports removing the progress indicators @@ -122,7 +117,7 @@ prepends `vc-bzr-status-switches' to ARGS." `("BZR_PROGRESS_BAR=none" ; Suppress progress output (bzr >=0.9) "LC_MESSAGES=C" ; Force English output ,@process-environment))) - (apply 'vc-do-command (or buffer "*vc*") okstatus vc-bzr-program + (apply #'vc-do-command (or buffer "*vc*") okstatus vc-bzr-program file-or-list bzr-command (if (and (string-equal "status" bzr-command) vc-bzr-status-switches) @@ -144,7 +139,7 @@ Use the current Bzr root directory as the ROOT argument to ,@process-environment)) (root (vc-bzr-root default-directory)) (buffer (format "*vc-bzr : %s*" (expand-file-name root)))) - (apply 'vc-do-async-command buffer root + (apply #'vc-do-async-command buffer root vc-bzr-program bzr-command args) buffer)) @@ -267,7 +262,8 @@ in the repository root directory of FILE." ;; If there is no parent, this must be a new repo. ;; If file is in dirstate, can only be added (b#8025). ((or (not (match-beginning 4)) - (eq (char-after (match-beginning 4)) ?a)) 'added) + (eq (char-after (match-beginning 4)) ?a)) + 'added) ((or (and (eql (string-to-number (match-string 3)) (file-attribute-size (file-attributes file))) (equal (match-string 5) @@ -280,7 +276,7 @@ in the repository root directory of FILE." (memq ?x (mapcar - 'identity + #'identity (file-attribute-modes (file-attributes file)))))) (if (eq (char-after (match-beginning 7)) @@ -374,13 +370,13 @@ If PROMPT is non-nil, prompt for the Bzr command to run." command (cadr args) args (cddr args))) (require 'vc-dispatcher) - (let ((buf (apply 'vc-bzr-async-command command args))) + (let ((buf (apply #'vc-bzr-async-command command args))) (with-current-buffer buf (vc-run-delayed (vc-compilation-mode 'bzr) (setq-local compile-command (concat vc-bzr-program " " command " " - (if args (mapconcat 'identity args " ") ""))))) + (if args (mapconcat #'identity args " ") ""))))) (vc-set-async-update buf)))) (defun vc-bzr-pull (prompt) @@ -424,7 +420,7 @@ default if it is available." (vc-bzr-program (car cmd)) (command (cadr cmd)) (args (cddr cmd))) - (let ((buf (apply 'vc-bzr-async-command command args))) + (let ((buf (apply #'vc-bzr-async-command command args))) (with-current-buffer buf (vc-run-delayed (vc-compilation-mode 'bzr))) (vc-set-async-update buf)))) @@ -512,7 +508,7 @@ in the branch repository (or whose status not be determined)." (unless (re-search-forward "^<<<<<<< " nil t) (vc-bzr-command "resolve" nil 0 buffer-file-name) ;; Remove the hook so that it is not called multiple times. - (remove-hook 'after-save-hook 'vc-bzr-resolve-when-done t)))) + (remove-hook 'after-save-hook #'vc-bzr-resolve-when-done t)))) (defun vc-bzr-find-file-hook () (when (and buffer-file-name @@ -529,7 +525,7 @@ in the branch repository (or whose status not be determined)." ;; but the one in `bzr pull' isn't, so it would be good to provide an ;; elisp function to remerge from the .BASE/OTHER/THIS files. (smerge-start-session) - (add-hook 'after-save-hook 'vc-bzr-resolve-when-done nil t) + (add-hook 'after-save-hook #'vc-bzr-resolve-when-done nil t) (vc-message-unresolved-conflicts buffer-file-name))) (defun vc-bzr-version-dirstate (dir) @@ -643,7 +639,7 @@ Returns nil if unable to find this information." ;; Could run `bzr status' in the directory and see if it succeeds, but ;; that's relatively expensive. -(defalias 'vc-bzr-responsible-p 'vc-bzr-root +(defalias 'vc-bzr-responsible-p #'vc-bzr-root "Return non-nil if FILE is (potentially) controlled by bzr. The criterion is that there is a `.bzr' directory in the same or a superior directory.") @@ -664,7 +660,7 @@ or a superior directory.") (defun vc-bzr-checkin (files comment &optional _rev) "Check FILES in to bzr with log message COMMENT." - (apply 'vc-bzr-command "commit" nil 0 files + (apply #'vc-bzr-command "commit" nil 0 files (cons "-m" (log-edit-extract-headers `(("Author" . ,(vc-bzr--sanitize-header "--author")) ("Date" . ,(vc-bzr--sanitize-header "--commit-time")) @@ -699,7 +695,7 @@ or a superior directory.") (defvar log-view-expanded-log-entry-function) (define-derived-mode vc-bzr-log-view-mode log-view-mode "Bzr-Log-View" - (remove-hook 'log-view-mode-hook 'vc-bzr-log-view-mode) ;Deactivate the hack. + (remove-hook 'log-view-mode-hook #'vc-bzr-log-view-mode) ;Deactivate the hack. (require 'add-log) (setq-local log-view-per-file-logs nil) (setq-local log-view-file-re regexp-unmatchable) @@ -745,7 +741,7 @@ If LIMIT is non-nil, show no more than this many entries." ;; the log display may not what the user wants - but I see no other ;; way of getting the above regexps working. (with-current-buffer buffer - (apply 'vc-bzr-command "log" buffer 'async files + (apply #'vc-bzr-command "log" buffer 'async files (append (if shortlog '("--line") '("--long")) ;; The extra complications here when start-revision and limit @@ -761,7 +757,8 @@ If LIMIT is non-nil, show no more than this many entries." ;; This means we don't have to use --no-aliases. ;; Is -c any different to -r in this case? "-r%s" - "-r..%s") start-revision))) + "-r..%s") + start-revision))) (if (eq vc-log-view-type 'with-diff) (list "-p")) (when limit (list "-l" (format "%s" limit))) ;; There is no sensible way to combine --limit and --forward, @@ -782,7 +779,7 @@ If LIMIT is non-nil, show no more than this many entries." (defun vc-bzr-expanded-log-entry (revision) (with-temp-buffer - (apply 'vc-bzr-command "log" t nil nil + (apply #'vc-bzr-command "log" t nil nil (append (list "--long" (format "-r%s" revision)) (if (stringp vc-bzr-log-switches) @@ -795,11 +792,11 @@ If LIMIT is non-nil, show no more than this many entries." (buffer-substring (match-end 0) (point-max))))) (defun vc-bzr-log-incoming (buffer remote-location) - (apply 'vc-bzr-command "missing" buffer 'async nil + (apply #'vc-bzr-command "missing" buffer 'async nil (list "--theirs-only" (unless (string= remote-location "") remote-location)))) (defun vc-bzr-log-outgoing (buffer remote-location) - (apply 'vc-bzr-command "missing" buffer 'async nil + (apply #'vc-bzr-command "missing" buffer 'async nil (list "--mine-only" (unless (string= remote-location "") remote-location)))) (defun vc-bzr-show-log-entry (revision) @@ -830,7 +827,7 @@ If LIMIT is non-nil, show no more than this many entries." (append ;; Only add --diff-options if there are any diff switches. (unless (zerop (length switches)) - (list "--diff-options" (mapconcat 'identity switches " "))) + (list "--diff-options" (mapconcat #'identity switches " "))) ;; This `when' is just an optimization because bzr-1.2 is *much* ;; faster when the revision argument is not given. (when (or rev1 rev2) @@ -995,7 +992,7 @@ stream. Standard error output is discarded." (defun vc-bzr-dir-status-files (dir files update-function) "Return a list of conses (file . state) for DIR." - (apply 'vc-bzr-command "status" (current-buffer) 'async dir "-v" "-S" files) + (apply #'vc-bzr-command "status" (current-buffer) 'async dir "-v" "-S" files) (vc-run-delayed (vc-bzr-after-dir-status update-function ;; "bzr status" results are relative to @@ -1010,15 +1007,15 @@ stream. Standard error output is discarded." (defvar vc-bzr-shelve-map (let ((map (make-sparse-keymap))) ;; Turn off vc-dir marking - (define-key map [mouse-2] 'ignore) - - (define-key map [down-mouse-3] 'vc-bzr-shelve-menu) - (define-key map "\C-k" 'vc-bzr-shelve-delete-at-point) - (define-key map "=" 'vc-bzr-shelve-show-at-point) - (define-key map "\C-m" 'vc-bzr-shelve-show-at-point) - (define-key map "A" 'vc-bzr-shelve-apply-and-keep-at-point) - (define-key map "P" 'vc-bzr-shelve-apply-at-point) - (define-key map "S" 'vc-bzr-shelve-snapshot) + (define-key map [mouse-2] #'ignore) + + (define-key map [down-mouse-3] #'vc-bzr-shelve-menu) + (define-key map "\C-k" #'vc-bzr-shelve-delete-at-point) + (define-key map "=" #'vc-bzr-shelve-show-at-point) + (define-key map "\C-m" #'vc-bzr-shelve-show-at-point) + (define-key map "A" #'vc-bzr-shelve-apply-and-keep-at-point) + (define-key map "P" #'vc-bzr-shelve-apply-at-point) + (define-key map "S" #'vc-bzr-shelve-snapshot) map)) (defvar vc-bzr-shelve-menu-map @@ -1211,7 +1208,7 @@ stream. Standard error output is discarded." (let ((vc-bzr-revisions '()) (default-directory (file-name-directory (car files)))) (with-temp-buffer - (apply 'vc-bzr-command "log" t 0 files + (apply #'vc-bzr-command "log" t 0 files (append '("--line") (if (stringp vc-bzr-log-switches) (list vc-bzr-log-switches) diff --git a/lisp/vc/vc-cvs.el b/lisp/vc/vc-cvs.el index 0adb5328bc..ef607133e8 100644 --- a/lisp/vc/vc-cvs.el +++ b/lisp/vc/vc-cvs.el @@ -76,8 +76,7 @@ (repeat :tag "Argument List" :value ("") string)) - :version "22.1" - :group 'vc-cvs) + :version "22.1") (defcustom vc-cvs-register-switches nil "Switches for registering a file into CVS. @@ -88,8 +87,7 @@ If t, use no switches." (const :tag "None" t) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "21.1" - :group 'vc-cvs) + :version "21.1") (defcustom vc-cvs-diff-switches nil "String or list of strings specifying switches for CVS diff under VC. @@ -98,8 +96,7 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." (const :tag "None" t) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "21.1" - :group 'vc-cvs) + :version "21.1") (defcustom vc-cvs-annotate-switches nil "String or list of strings specifying switches for cvs annotate under VC. @@ -109,22 +106,19 @@ switches." (const :tag "None" t) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "25.1" - :group 'vc-cvs) + :version "25.1") (defcustom vc-cvs-header '("$Id\ $") "Header keywords to be inserted by `vc-insert-headers'." :version "24.1" ; no longer consult the obsolete vc-header-alist - :type '(repeat string) - :group 'vc-cvs) + :type '(repeat string)) (defcustom vc-cvs-use-edit t "Non-nil means to use `cvs edit' to \"check out\" a file. This is only meaningful if you don't use the implicit checkout model \(i.e. if you have $CVSREAD set)." :type 'boolean - :version "21.1" - :group 'vc-cvs) + :version "21.1") (defcustom vc-cvs-stay-local 'only-file "Non-nil means use local operations when possible for remote repositories. @@ -151,16 +145,14 @@ except for hosts matched by these regular expressions." (regexp :format " stay local,\n%t: %v" :tag "if it matches") (repeat :format "%v%i\n" :inline t (regexp :tag "or")))) - :version "23.1" - :group 'vc-cvs) + :version "23.1") (defcustom vc-cvs-sticky-date-format-string "%c" "Format string for mode-line display of sticky date. Format is according to `format-time-string'. Only used if `vc-cvs-sticky-tag-display' is t." :type '(string) - :version "22.1" - :group 'vc-cvs) + :version "22.1") (defcustom vc-cvs-sticky-tag-display t "Specify the mode-line display of sticky tags. @@ -198,8 +190,7 @@ displayed. Date and time is displayed for sticky dates. See also variable `vc-cvs-sticky-date-format-string'." :type '(choice boolean function) - :version "22.1" - :group 'vc-cvs) + :version "22.1") ;;; ;;; Internal variables @@ -310,7 +301,7 @@ to the CVS command." (vc-cvs-could-register file) (push (directory-file-name (file-name-directory file)) dirs))) (if dirs (vc-cvs-register dirs))) - (apply 'vc-cvs-command nil 0 files + (apply #'vc-cvs-command nil 0 files "add" (and comment (string-match "[^\t\n ]" comment) (concat "-m" comment)) @@ -346,12 +337,12 @@ its parents." (error "%s is not a valid symbolic tag name" rev) ;; If the input revision is a valid symbolic tag name, we create it ;; as a branch, commit and switch to it. - (apply 'vc-cvs-command nil 0 files "tag" "-b" (list rev)) - (apply 'vc-cvs-command nil 0 files "update" "-r" (list rev)) + (apply #'vc-cvs-command nil 0 files "tag" "-b" (list rev)) + (apply #'vc-cvs-command nil 0 files "update" "-r" (list rev)) (mapc (lambda (file) (vc-file-setprop file 'vc-cvs-sticky-tag rev)) files))) (let ((status (apply - 'vc-cvs-command nil 1 files + #'vc-cvs-command nil 1 files "ci" (if rev (concat "-r" rev)) (concat "-m" (car (log-edit-extract-headers nil comment))) (vc-switches 'CVS 'checkin)))) @@ -378,7 +369,7 @@ its parents." (vc-file-setprop (car files) 'vc-working-revision (vc-parse-buffer "^\\(new\\|initial\\) revision: \\([0-9.]+\\)" 2)) - (mapc 'vc-file-clearprops files)) + (mapc #'vc-file-clearprops files)) ;; Anyway, forget the checkout model of the file, because we might have ;; guessed wrong when we found the file. After commit, we can ;; tell it from the permissions of the file (see @@ -391,7 +382,7 @@ its parents." (vc-cvs-command nil 0 files "update" "-A")))) (defun vc-cvs-find-revision (file rev buffer) - (apply 'vc-cvs-command + (apply #'vc-cvs-command buffer 0 file "-Q" ; suppress diagnostic output "update" @@ -416,7 +407,7 @@ REV is the revision to check out." (if (equal file buffer-file-name) (read-only-mode -1)))) ;; Check out a particular revision (or recreate the file). (vc-file-setprop file 'vc-working-revision nil) - (apply 'vc-cvs-command nil 0 file + (apply #'vc-cvs-command nil 0 file "-w" "update" (when rev @@ -600,7 +591,7 @@ Remaining arguments are ignored." ;; This used to append diff-switches and vc-diff-switches, ;; which was consistent with the vc-diff-switches doc at that ;; time, but not with the actual behavior of any other VC diff. - (apply 'vc-do-command (or buffer "*vc-diff*") 1 "diff" nil + (apply #'vc-do-command (or buffer "*vc-diff*") 1 "diff" nil ;; Not a CVS diff, does not use vc-cvs-diff-switches. (append (vc-switches nil 'diff) (list (file-relative-name file-oldvers) @@ -608,7 +599,7 @@ Remaining arguments are ignored." (setq status 0)) (push file invoke-cvs-diff-list))))) (when invoke-cvs-diff-list - (setq status (apply 'vc-cvs-command (or buffer "*vc-diff*") + (setq status (apply #'vc-cvs-command (or buffer "*vc-diff*") (if async 'async 1) invoke-cvs-diff-list "diff" (and oldvers (concat "-r" oldvers)) @@ -787,7 +778,7 @@ If UPDATE is non-nil, then update (resynch) any affected buffers." "A wrapper around `vc-do-command' for use in vc-cvs.el. The difference to vc-do-command is that this function always invokes `cvs', and that it passes `vc-cvs-global-switches' to it before FLAGS." - (apply 'vc-do-command (or buffer "*vc*") okstatus "cvs" files + (apply #'vc-do-command (or buffer "*vc*") okstatus "cvs" files (if (stringp vc-cvs-global-switches) (cons vc-cvs-global-switches flags) (append vc-cvs-global-switches @@ -816,7 +807,7 @@ individually should stay local." (setq default nil stay-local (cdr stay-local))) (when (consp stay-local) (setq stay-local - (mapconcat 'identity stay-local "\\|"))) + (mapconcat #'identity stay-local "\\|"))) (if (if (string-match stay-local hostname) default (not default)) 'yes 'no)))))))))))) diff --git a/lisp/vc/vc-dav.el b/lisp/vc/vc-dav.el index 88f46eff05..5fd8d8e503 100644 --- a/lisp/vc/vc-dav.el +++ b/lisp/vc/vc-dav.el @@ -1,4 +1,4 @@ -;;; vc-dav.el --- vc.el support for WebDAV +;;; vc-dav.el --- vc.el support for WebDAV -*- lexical-binding: t; -*- ;; Copyright (C) 2001, 2004-2021 Free Software Foundation, Inc. @@ -64,7 +64,7 @@ For a list of possible values, see `vc-state'." 'edited (cdr (car locks))))))) -(defun vc-dav-checkout-model (url) +(defun vc-dav-checkout-model (_url) "Indicate whether URL needs to be \"checked out\" before it can be edited. See `vc-checkout-model' for a list of possible values." ;; The only thing we can support with webdav is 'locking @@ -72,21 +72,21 @@ See `vc-checkout-model' for a list of possible values." ;; This should figure out the version # of the file somehow. What is ;; the most appropriate property in WebDAV to look at for this? -(defun vc-dav-workfile-version (url) +(defun vc-dav-workfile-version (_url) "Return the current workfile version of URL." "Unknown") -(defun vc-dav-register (url &optional _comment) +(defun vc-dav-register (_url &optional _comment) "Register URL in the DAV backend." ;; Do we need to do anything here? FIXME? ) -(defun vc-dav-checkin (url comment &optional _rev) +(defun vc-dav-checkin (_url _comment &optional _rev) "Commit changes in URL to WebDAV. COMMENT is used as a check-in comment." ;; This should PUT the resource and release any locks that we hold. ) -(defun vc-dav-checkout (url &optional rev destfile) +(defun vc-dav-checkout (_url &optional _rev _destfile) "Check out revision REV of URL into the working area. If EDITABLE is non-nil URL should be writable by the user and if @@ -101,7 +101,7 @@ write the contents to. ;; This should LOCK the resource. ) -(defun vc-dav-revert (url &optional contents-done) +(defun vc-dav-revert (_url &optional _contents-done) "Revert URL back to the current workfile version. If optional arg CONTENTS-DONE is non-nil, then the contents of FILE @@ -112,11 +112,11 @@ only needs to update the status of URL within the backend. ;; Should UNLOCK the file. ) -(defun vc-dav-print-log (url) +(defun vc-dav-print-log (_url) "Insert the revision log of URL into the *vc* buffer." ) -(defun vc-dav-diff (url &optional rev1 rev2 buffer async) +(defun vc-dav-diff (_url &optional _rev1 _rev2 _buffer _async) "Insert the diff for URL into the *vc-diff* buffer. If REV1 and REV2 are non-nil report differences from REV1 to REV2. If REV1 is nil, use the current workfile version as the older version. @@ -135,11 +135,11 @@ It should return a status of either 0 (no differences found), or ;; This should use url-dav-get-properties with a depth of `1' to get ;; all the properties. -(defun vc-dav-dir-state (url) +(defun vc-dav-dir-state (_url) "find the version control state of all files in DIR in a fast way." ) -(defun vc-dav-responsible-p (url) +(defun vc-dav-responsible-p (_url) "Return non-nil if DAV considers itself `responsible' for URL." ;; Check for DAV support on the web server. t) diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index 46fbf44861..eb8cf8192c 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -302,67 +302,67 @@ See `run-hooks'." (defvar vc-dir-mode-map (let ((map (make-sparse-keymap))) ;; VC commands - (define-key map "v" 'vc-next-action) ;; C-x v v - (define-key map "=" 'vc-diff) ;; C-x v = - (define-key map "D" 'vc-root-diff) ;; C-x v D - (define-key map "i" 'vc-register) ;; C-x v i - (define-key map "+" 'vc-update) ;; C-x v + + (define-key map "v" #'vc-next-action) ;; C-x v v + (define-key map "=" #'vc-diff) ;; C-x v = + (define-key map "D" #'vc-root-diff) ;; C-x v D + (define-key map "i" #'vc-register) ;; C-x v i + (define-key map "+" #'vc-update) ;; C-x v + ;; I'd prefer some kind of symmetry with vc-update: - (define-key map "P" 'vc-push) ;; C-x v P - (define-key map "l" 'vc-print-log) ;; C-x v l - (define-key map "L" 'vc-print-root-log) ;; C-x v L - (define-key map "I" 'vc-log-incoming) ;; C-x v I - (define-key map "O" 'vc-log-outgoing) ;; C-x v O + (define-key map "P" #'vc-push) ;; C-x v P + (define-key map "l" #'vc-print-log) ;; C-x v l + (define-key map "L" #'vc-print-root-log) ;; C-x v L + (define-key map "I" #'vc-log-incoming) ;; C-x v I + (define-key map "O" #'vc-log-outgoing) ;; C-x v O ;; More confusing than helpful, probably - ;;(define-key map "R" 'vc-revert) ;; u is taken by vc-dir-unmark. - ;;(define-key map "A" 'vc-annotate) ;; g is taken by revert-buffer + ;;(define-key map "R" #'vc-revert) ;; u is taken by vc-dir-unmark. + ;;(define-key map "A" #'vc-annotate) ;; g is taken by revert-buffer ;; bound by `special-mode'. ;; Marking. - (define-key map "m" 'vc-dir-mark) - (define-key map "d" 'vc-dir-clean-files) - (define-key map "M" 'vc-dir-mark-all-files) - (define-key map "u" 'vc-dir-unmark) - (define-key map "U" 'vc-dir-unmark-all-files) - (define-key map "\C-?" 'vc-dir-unmark-file-up) - (define-key map "\M-\C-?" 'vc-dir-unmark-all-files) + (define-key map "m" #'vc-dir-mark) + (define-key map "d" #'vc-dir-clean-files) + (define-key map "M" #'vc-dir-mark-all-files) + (define-key map "u" #'vc-dir-unmark) + (define-key map "U" #'vc-dir-unmark-all-files) + (define-key map "\C-?" #'vc-dir-unmark-file-up) + (define-key map "\M-\C-?" #'vc-dir-unmark-all-files) ;; Movement. - (define-key map "n" 'vc-dir-next-line) - (define-key map " " 'vc-dir-next-line) - (define-key map "\t" 'vc-dir-next-directory) - (define-key map "p" 'vc-dir-previous-line) - (define-key map [?\S-\ ] 'vc-dir-previous-line) - (define-key map [backtab] 'vc-dir-previous-directory) + (define-key map "n" #'vc-dir-next-line) + (define-key map " " #'vc-dir-next-line) + (define-key map "\t" #'vc-dir-next-directory) + (define-key map "p" #'vc-dir-previous-line) + (define-key map [?\S-\ ] #'vc-dir-previous-line) + (define-key map [backtab] #'vc-dir-previous-directory) ;;; Rebind paragraph-movement commands. - (define-key map "\M-}" 'vc-dir-next-directory) - (define-key map "\M-{" 'vc-dir-previous-directory) - (define-key map [C-down] 'vc-dir-next-directory) - (define-key map [C-up] 'vc-dir-previous-directory) + (define-key map "\M-}" #'vc-dir-next-directory) + (define-key map "\M-{" #'vc-dir-previous-directory) + (define-key map [C-down] #'vc-dir-next-directory) + (define-key map [C-up] #'vc-dir-previous-directory) ;; The remainder. - (define-key map "f" 'vc-dir-find-file) - (define-key map "e" 'vc-dir-find-file) ; dired-mode compatibility - (define-key map "\C-m" 'vc-dir-find-file) - (define-key map "o" 'vc-dir-find-file-other-window) - (define-key map "\C-o" 'vc-dir-display-file) - (define-key map "\C-c\C-c" 'vc-dir-kill-dir-status-process) - (define-key map [down-mouse-3] 'vc-dir-menu) + (define-key map "f" #'vc-dir-find-file) + (define-key map "e" #'vc-dir-find-file) ; dired-mode compatibility + (define-key map "\C-m" #'vc-dir-find-file) + (define-key map "o" #'vc-dir-find-file-other-window) + (define-key map "\C-o" #'vc-dir-display-file) + (define-key map "\C-c\C-c" #'vc-dir-kill-dir-status-process) + (define-key map [down-mouse-3] #'vc-dir-menu) (define-key map [follow-link] 'mouse-face) - (define-key map "x" 'vc-dir-hide-up-to-date) - (define-key map [?\C-k] 'vc-dir-kill-line) - (define-key map "S" 'vc-dir-search) ;; FIXME: Maybe use A like dired? - (define-key map "Q" 'vc-dir-query-replace-regexp) - (define-key map (kbd "M-s a C-s") 'vc-dir-isearch) - (define-key map (kbd "M-s a M-C-s") 'vc-dir-isearch-regexp) - (define-key map "G" 'vc-dir-ignore) + (define-key map "x" #'vc-dir-hide-up-to-date) + (define-key map [?\C-k] #'vc-dir-kill-line) + (define-key map "S" #'vc-dir-search) ;; FIXME: Maybe use A like dired? + (define-key map "Q" #'vc-dir-query-replace-regexp) + (define-key map (kbd "M-s a C-s") #'vc-dir-isearch) + (define-key map (kbd "M-s a M-C-s") #'vc-dir-isearch-regexp) + (define-key map "G" #'vc-dir-ignore) (let ((branch-map (make-sparse-keymap))) (define-key map "B" branch-map) - (define-key branch-map "c" 'vc-create-tag) - (define-key branch-map "l" 'vc-print-branch-log) - (define-key branch-map "s" 'vc-retrieve-tag)) + (define-key branch-map "c" #'vc-create-tag) + (define-key branch-map "l" #'vc-print-branch-log) + (define-key branch-map "s" #'vc-retrieve-tag)) (let ((mark-map (make-sparse-keymap))) (define-key map "*" mark-map) - (define-key mark-map "r" 'vc-dir-mark-registered-files)) + (define-key mark-map "r" #'vc-dir-mark-registered-files)) ;; Hook up the menu. (define-key map [menu-bar vc-dir-mode] @@ -506,7 +506,7 @@ If NOINSERT, ignore elements on ENTRIES which are not in the ewoc." (t (unless noinsert (ewoc-enter-before vc-ewoc node - (apply 'vc-dir-create-fileinfo entry))) + (apply #'vc-dir-create-fileinfo entry))) (setq entries (cdr entries)) (setq entry (car entries)))))) (t @@ -522,7 +522,7 @@ If NOINSERT, ignore elements on ENTRIES which are not in the ewoc." vc-ewoc node (vc-dir-create-fileinfo rd nil nil nil entrydir)))) ;; Now insert the node itself. (ewoc-enter-before vc-ewoc node - (apply 'vc-dir-create-fileinfo entry))) + (apply #'vc-dir-create-fileinfo entry))) (setq entries (cdr entries) entry (car entries)))))) ;; We're past the last node, all remaining entries go to the end. (unless (or node noinsert) @@ -538,10 +538,10 @@ If NOINSERT, ignore elements on ENTRIES which are not in the ewoc." vc-ewoc (vc-dir-create-fileinfo rd nil nil nil entrydir)))) ;; Now insert the node itself. (ewoc-enter-last vc-ewoc - (apply 'vc-dir-create-fileinfo entry)))))) + (apply #'vc-dir-create-fileinfo entry)))))) (when to-remove (let ((inhibit-read-only t)) - (apply 'ewoc-delete vc-ewoc (nreverse to-remove))))))) + (apply #'ewoc-delete vc-ewoc (nreverse to-remove))))))) (defun vc-dir-busy () (and (buffer-live-p vc-dir-process-buffer) @@ -882,7 +882,7 @@ system; see `vc-dir-delete-file'." The files will also be marked as deleted in the version control system." (interactive) - (mapc 'vc-delete-file (or (vc-dir-marked-files) + (mapc #'vc-delete-file (or (vc-dir-marked-files) (list (vc-dir-current-file))))) (defun vc-dir-find-file () @@ -912,13 +912,13 @@ system." "Search for a string through all marked buffers using Isearch." (interactive) (multi-isearch-files - (mapcar 'car (vc-dir-marked-only-files-and-states)))) + (mapcar #'car (vc-dir-marked-only-files-and-states)))) (defun vc-dir-isearch-regexp () "Search for a regexp through all marked buffers using Isearch." (interactive) (multi-isearch-files-regexp - (mapcar 'car (vc-dir-marked-only-files-and-states)))) + (mapcar #'car (vc-dir-marked-only-files-and-states)))) (defun vc-dir-search (regexp) "Search through all marked files for a match for REGEXP. @@ -943,13 +943,13 @@ with the command \\[tags-loop-continue]." (query-replace-read-args "Query replace regexp in marked files" t t))) (list (nth 0 common) (nth 1 common) (nth 2 common)))) - (dolist (file (mapcar 'car (vc-dir-marked-only-files-and-states))) + (dolist (file (mapcar #'car (vc-dir-marked-only-files-and-states))) (let ((buffer (get-file-buffer file))) (if (and buffer (with-current-buffer buffer buffer-read-only)) (error "File `%s' is visited read-only" file)))) (fileloop-initialize-replace - from to (mapcar 'car (vc-dir-marked-only-files-and-states)) + from to (mapcar #'car (vc-dir-marked-only-files-and-states)) (if (equal from (downcase from)) nil 'default) delimited) (fileloop-continue)) @@ -1161,7 +1161,7 @@ the *vc-dir* buffer. (add-to-list 'vc-dir-buffers (current-buffer)) ;; Make sure that if the directory buffer is killed, the update ;; process running in the background is also killed. - (add-hook 'kill-buffer-query-functions 'vc-dir-kill-query nil t) + (add-hook 'kill-buffer-query-functions #'vc-dir-kill-query nil t) (hack-dir-local-variables-non-file-buffer) (vc-dir-refresh))) @@ -1276,7 +1276,7 @@ Throw an error if another update process is in progress." vc-ewoc 'vc-dir-fileinfo->needs-update))) (if remaining (vc-dir-refresh-files - (mapcar 'vc-dir-fileinfo->name remaining)) + (mapcar #'vc-dir-fileinfo->name remaining)) (setq mode-line-process nil) (run-hooks 'vc-dir-refresh-hook)))))))))))) @@ -1330,7 +1330,7 @@ state of item at point, if any." (ewoc-delete vc-ewoc crt)) (setq crt prev))))) -(defalias 'vc-dir-hide-up-to-date 'vc-dir-hide-state) +(defalias 'vc-dir-hide-up-to-date #'vc-dir-hide-state) (defun vc-dir-kill-line () "Remove the current line from display." @@ -1366,7 +1366,7 @@ state of item at point, if any." (unless (vc-compatible-state (cdr crt) state) (error "When applying VC operations to multiple files, the files are required\nto be in similar VC states.\n%s in state %s clashes with %s in state %s" (car crt) (cdr crt) (caar only-files-list) state))) - (setq only-files-list (mapcar 'car only-files-list)) + (setq only-files-list (mapcar #'car only-files-list)) (when (and state (not (eq state 'unregistered))) (setq model (vc-checkout-model vc-dir-backend only-files-list)))) (list vc-dir-backend files only-files-list state model))) @@ -1437,13 +1437,13 @@ These are the commands available for use in the file status buffer: (defvar vc-dir-status-mouse-map (let ((map (make-sparse-keymap))) - (define-key map [mouse-2] 'vc-dir-toggle-mark) + (define-key map [mouse-2] #'vc-dir-toggle-mark) map) "Local keymap for toggling mark.") (defvar vc-dir-filename-mouse-map (let ((map (make-sparse-keymap))) - (define-key map [mouse-2] 'vc-dir-find-file-other-window) + (define-key map [mouse-2] #'vc-dir-find-file-other-window) map) "Local keymap for visiting a file.") diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el index 2573964c42..2b477dff0a 100644 --- a/lisp/vc/vc-dispatcher.el +++ b/lisp/vc/vc-dispatcher.el @@ -242,7 +242,7 @@ CODE should be a function of no arguments." ((or (null proc) (eq (process-status proc) 'exit)) ;; Make sure we've read the process's output before going further. (when proc (accept-process-output proc)) - (if (functionp code) (funcall code) (eval code))) + (if (functionp code) (funcall code) (eval code t))) ;; If a process is running, add CODE to the sentinel ((eq (process-status proc) 'run) (vc-set-mode-line-busy-indicator) @@ -267,7 +267,7 @@ and is passed 3 arguments: the COMMAND, the FILES and the FLAGS.") (defun vc-delistify (filelist) "Smash a FILELIST into a file list string suitable for info messages." ;; FIXME what about file names with spaces? - (if (not filelist) "." (mapconcat 'identity filelist " "))) + (if (not filelist) "." (mapconcat #'identity filelist " "))) (defcustom vc-tor nil "If non-nil, communicate with the repository site via Tor. @@ -331,7 +331,7 @@ case, and the process object in the asynchronous case." ;; Run asynchronously. (let ((proc (let ((process-connection-type nil)) - (apply 'start-file-process command (current-buffer) + (apply #'start-file-process command (current-buffer) command squeezed)))) (when vc-command-messages (let ((inhibit-message (eq (selected-window) (active-minibuffer-window)))) @@ -339,7 +339,7 @@ case, and the process object in the asynchronous case." ;; Get rid of the default message insertion, in case we don't ;; set a sentinel explicitly. (set-process-sentinel proc #'ignore) - (set-process-filter proc 'vc-process-filter) + (set-process-filter proc #'vc-process-filter) (setq status proc) (when vc-command-messages (vc-run-delayed @@ -351,7 +351,7 @@ case, and the process object in the asynchronous case." (let ((inhibit-message (eq (selected-window) (active-minibuffer-window)))) (message "Running in foreground: %s" full-command))) (let ((buffer-undo-list t)) - (setq status (apply 'process-file command nil t nil squeezed))) + (setq status (apply #'process-file command nil t nil squeezed))) (when (and (not (eq t okstatus)) (or (not (integerp status)) (and okstatus (< okstatus status)))) @@ -394,7 +394,7 @@ Display the buffer in some window, but don't select it." (insert "\"...\n") ;; Run in the original working directory. (let ((default-directory dir)) - (apply 'vc-do-command t 'async command nil args))) + (apply #'vc-do-command t 'async command nil args))) (setq window (display-buffer buffer)) (if window (set-window-start window new-window-start)) diff --git a/lisp/vc/vc-filewise.el b/lisp/vc/vc-filewise.el index ee73aa6f93..e1b042a742 100644 --- a/lisp/vc/vc-filewise.el +++ b/lisp/vc/vc-filewise.el @@ -1,4 +1,4 @@ -;;; vc-filewise.el --- common functions for file-oriented back ends. +;;; vc-filewise.el --- common functions for file-oriented back ends. -*- lexical-binding: t; -*- ;; Copyright (C) 1992-1996, 1998-2021 Free Software Foundation, Inc. diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index 25ae26d746..465ed8735c 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -106,6 +106,7 @@ ;;; Code: (require 'cl-lib) +(require 'vc-dispatcher) (eval-when-compile (require 'subr-x) ; for string-trim-right (require 'vc) @@ -658,29 +659,29 @@ or an empty string if none." (defvar vc-git-stash-shared-map (let ((map (make-sparse-keymap))) - (define-key map "S" 'vc-git-stash-snapshot) - (define-key map "C" 'vc-git-stash) + (define-key map "S" #'vc-git-stash-snapshot) + (define-key map "C" #'vc-git-stash) map)) (defvar vc-git-stash-map (let ((map (make-sparse-keymap))) (set-keymap-parent map vc-git-stash-shared-map) ;; Turn off vc-dir marking - (define-key map [mouse-2] 'ignore) - - (define-key map [down-mouse-3] 'vc-git-stash-menu) - (define-key map "\C-k" 'vc-git-stash-delete-at-point) - (define-key map "=" 'vc-git-stash-show-at-point) - (define-key map "\C-m" 'vc-git-stash-show-at-point) - (define-key map "A" 'vc-git-stash-apply-at-point) - (define-key map "P" 'vc-git-stash-pop-at-point) + (define-key map [mouse-2] #'ignore) + + (define-key map [down-mouse-3] #'vc-git-stash-menu) + (define-key map "\C-k" #'vc-git-stash-delete-at-point) + (define-key map "=" #'vc-git-stash-show-at-point) + (define-key map "\C-m" #'vc-git-stash-show-at-point) + (define-key map "A" #'vc-git-stash-apply-at-point) + (define-key map "P" #'vc-git-stash-pop-at-point) map)) (defvar vc-git-stash-button-map (let ((map (make-sparse-keymap))) (set-keymap-parent map vc-git-stash-shared-map) - (define-key map [mouse-2] 'push-button) - (define-key map "\C-m" 'push-button) + (define-key map [mouse-2] #'push-button) + (define-key map "\C-m" #'push-button) map)) (defconst vc-git-stash-shared-help @@ -871,7 +872,7 @@ The car of the list is the current branch." (when dlist (vc-git-command nil 0 dlist "add")))) -(defalias 'vc-git-responsible-p 'vc-git-root) +(defalias 'vc-git-responsible-p #'vc-git-root) (defun vc-git-unregister (file) (vc-git-command nil 0 file "rm" "-f" "--cached" "--")) @@ -905,9 +906,9 @@ If toggling on, also insert its message into the buffer." (defvar vc-git-log-edit-mode-map (let ((map (make-sparse-keymap "Git-Log-Edit"))) - (define-key map "\C-c\C-s" 'vc-git-log-edit-toggle-signoff) - (define-key map "\C-c\C-n" 'vc-git-log-edit-toggle-no-verify) - (define-key map "\C-c\C-e" 'vc-git-log-edit-toggle-amend) + (define-key map "\C-c\C-s" #'vc-git-log-edit-toggle-signoff) + (define-key map "\C-c\C-n" #'vc-git-log-edit-toggle-no-verify) + (define-key map "\C-c\C-e" #'vc-git-log-edit-toggle-amend) map)) (define-derived-mode vc-git-log-edit-mode log-edit-mode "Log-Edit/git" @@ -941,7 +942,7 @@ It is based on `log-edit-mode', and has Git-specific extensions.") (lambda (value) (when (equal value "yes") (list argument))))) ;; When operating on the whole tree, better pass "-a" than ".", since "." ;; fails when we're committing a merge. - (apply 'vc-git-command nil 0 (if only files) + (apply #'vc-git-command nil 0 (if only files) (nconc (if msg-file (list "commit" "-F" (file-local-name msg-file)) (list "commit" "-m")) @@ -1024,13 +1025,13 @@ If PROMPT is non-nil, prompt for the Git command to run." args (cddr args))) (setq args (nconc args extra-args)) (require 'vc-dispatcher) - (apply 'vc-do-async-command buffer root git-program command args) + (apply #'vc-do-async-command buffer root git-program command args) (with-current-buffer buffer (vc-run-delayed (vc-compilation-mode 'git) (setq-local compile-command (concat git-program " " command " " - (mapconcat 'identity args " "))) + (mapconcat #'identity args " "))) (setq-local compilation-directory root) ;; Either set `compilation-buffer-name-function' locally to nil ;; or use `compilation-arguments' to set `name-function'. @@ -1068,7 +1069,7 @@ This prompts for a branch to merge from." branches (cons "FETCH_HEAD" branches)) nil t))) - (apply 'vc-do-async-command buffer root vc-git-program "merge" + (apply #'vc-do-async-command buffer root vc-git-program "merge" (list merge-source)) (with-current-buffer buffer (vc-run-delayed (vc-compilation-mode 'git))) (vc-set-async-update buffer))) @@ -1115,7 +1116,7 @@ This prompts for a branch to merge from." (vc-git-command nil 0 nil "reset")) (vc-resynch-buffer buffer-file-name t t) ;; Remove the hook so that it is not called multiple times. - (remove-hook 'after-save-hook 'vc-git-resolve-when-done t)))) + (remove-hook 'after-save-hook #'vc-git-resolve-when-done t)))) (defun vc-git-find-file-hook () "Activate `smerge-mode' if there is a conflict." @@ -1126,7 +1127,7 @@ This prompts for a branch to merge from." (re-search-forward "^<<<<<<< " nil 'noerror))) (smerge-start-session) (when vc-git-resolve-conflicts - (add-hook 'after-save-hook 'vc-git-resolve-when-done nil 'local)) + (add-hook 'after-save-hook #'vc-git-resolve-when-done nil 'local)) (vc-message-unresolved-conflicts buffer-file-name))) ;;; HISTORY FUNCTIONS @@ -1154,7 +1155,7 @@ If LIMIT is a revision string, use it as an end-revision." ;; read-only. (let ((inhibit-read-only t)) (with-current-buffer buffer - (apply 'vc-git-command buffer + (apply #'vc-git-command buffer 'async files (append '("log" "--no-color") @@ -1224,11 +1225,11 @@ log entries." (read-shell-command "Search log with command: " (format "%s %s" vc-git-program - (mapconcat 'identity args " ")) + (mapconcat #'identity args " ")) 'vc-git-history) " " t)))) (vc-setup-buffer buffer) - (apply 'vc-git-command buffer 'async nil args))) + (apply #'vc-git-command buffer 'async nil args))) (defun vc-git-mergebase (rev1 &optional rev2) (unless rev2 (setq rev2 "HEAD")) @@ -1299,7 +1300,7 @@ or BRANCH^ (where \"^\" can be repeated)." (defun vc-git-expanded-log-entry (revision) (with-temp-buffer - (apply 'vc-git-command t nil nil (list "log" revision "-1" "--")) + (apply #'vc-git-command t nil nil (list "log" revision "-1" "--")) (goto-char (point-min)) (unless (eobp) ;; Indent the expanded log entry. @@ -1415,7 +1416,7 @@ This requires git 1.8.4 or later, for the \"-L\" option of \"git log\"." (vc-git-command (or buffer "*vc-diff*") 1 files "difftool" "--exit-code" "--no-prompt" "-x" (concat "diff " - (mapconcat 'identity + (mapconcat #'identity (vc-switches nil 'diff) " ")) rev1 rev2 "--")))) @@ -1776,7 +1777,7 @@ The difference to vc-do-command is that this function always invokes ,@(when revert-buffer-in-progress-p '("GIT_OPTIONAL_LOCKS=0"))) process-environment))) - (apply 'vc-do-command (or buffer "*vc*") okstatus vc-git-program + (apply #'vc-do-command (or buffer "*vc*") okstatus vc-git-program ;; https://debbugs.gnu.org/16897 (unless (and (not (cdr-safe file-or-list)) (let ((file (or (car-safe file-or-list) @@ -1810,10 +1811,10 @@ The difference to vc-do-command is that this function always invokes ,@(when revert-buffer-in-progress-p '("GIT_OPTIONAL_LOCKS=0"))) process-environment))) - (apply 'process-file vc-git-program nil buffer nil "--no-pager" command args))) + (apply #'process-file vc-git-program nil buffer nil "--no-pager" command args))) (defun vc-git--out-ok (command &rest args) - (zerop (apply 'vc-git--call '(t nil) command args))) + (zerop (apply #'vc-git--call '(t nil) command args))) (defun vc-git--run-command-string (file &rest args) "Run a git command on FILE and return its output as string. @@ -1821,7 +1822,7 @@ FILE can be nil." (let* ((ok t) (str (with-output-to-string (with-current-buffer standard-output - (unless (apply 'vc-git--out-ok + (unless (apply #'vc-git--out-ok (if file (append args (list (file-relative-name file))) diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index adb0fce875..9faed10f38 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -124,8 +124,7 @@ :type '(choice (const :tag "None" nil) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "22.2" - :group 'vc-hg) + :version "22.2") (defcustom vc-hg-diff-switches t ; Hg doesn't support common args like -u "String or list of strings specifying switches for Hg diff under VC. @@ -134,8 +133,7 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." (const :tag "None" t) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "23.1" - :group 'vc-hg) + :version "23.1") (defcustom vc-hg-annotate-switches '("-u" "--follow") "String or list of strings specifying switches for hg annotate under VC. @@ -145,8 +143,7 @@ switches." (const :tag "None" t) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "25.1" - :group 'vc-hg) + :version "25.1") (defcustom vc-hg-revert-switches nil "String or list of strings specifying switches for hg revert @@ -154,13 +151,11 @@ under VC." :type '(choice (const :tag "None" nil) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "27.1" - :group 'vc-hg) + :version "27.1") (defcustom vc-hg-program "hg" "Name of the Mercurial executable (excluding any arguments)." - :type 'string - :group 'vc-hg) + :type 'string) (defcustom vc-hg-root-log-format `(,(concat "{rev}:{ifeq(branch, 'default','', '{branch}')}" @@ -183,7 +178,6 @@ REGEXP is a regular expression matching the resulting Mercurial output, and KEYWORDS is a list of `font-lock-keywords' for highlighting the Log View buffer." :type '(list string regexp (repeat sexp)) - :group 'vc-hg :version "24.5") (defcustom vc-hg-create-bookmark t @@ -311,8 +305,7 @@ If no list entry produces a useful revision, return `nil'." (const :tag "Active bookmark" builtin-active-bookmark) (string :tag "Hg template") (function :tag "Custom"))) - :version "26.1" - :group 'vc-hg) + :version "26.1") (defcustom vc-hg-use-file-version-for-mode-line-version nil "When enabled, the modeline contains revision information for the visited file. @@ -320,8 +313,7 @@ When not, the revision in the modeline is for the repository working copy. `nil' is the much faster setting for large repositories." :type 'boolean - :version "26.1" - :group 'vc-hg) + :version "26.1") (defun vc-hg--active-bookmark-internal (rev) (when (equal rev ".") @@ -413,8 +405,7 @@ specific file to query." "String or list of strings specifying switches for hg log under VC." :type '(choice (const :tag "None" nil) (string :tag "Argument String") - (repeat :tag "Argument List" :value ("") string)) - :group 'vc-hg) + (repeat :tag "Argument List" :value ("") string))) (autoload 'vc-setup-buffer "vc-dispatcher") @@ -442,7 +433,7 @@ If LIMIT is non-nil, show no more than this many entries." (let ((inhibit-read-only t)) (with-current-buffer buffer - (apply 'vc-hg-command buffer 'async files "log" + (apply #'vc-hg-command buffer 'async files "log" (nconc (when start-revision (list (format "-r%s:0" start-revision))) (when limit (list "-l" (format "%s" limit))) @@ -666,8 +657,7 @@ directly instead of always running Mercurial. We try to be safe against Mercurial data structure format changes and always fall back to running Mercurial directly." :type 'boolean - :version "26.1" - :group 'vc-hg) + :version "26.1") (defsubst vc-hg--read-u8 () "Read and advance over an unsigned byte. @@ -1177,7 +1167,7 @@ hg binary." "Create a new Mercurial repository." (vc-hg-command nil 0 nil "init")) -(defalias 'vc-hg-responsible-p 'vc-hg-root) +(defalias 'vc-hg-responsible-p #'vc-hg-root) (defun vc-hg-unregister (file) "Unregister FILE from hg." @@ -1200,7 +1190,7 @@ If toggling on, also insert its message into the buffer." (defvar vc-hg-log-edit-mode-map (let ((map (make-sparse-keymap "Hg-Log-Edit"))) - (define-key map "\C-c\C-e" 'vc-hg-log-edit-toggle-amend) + (define-key map "\C-c\C-e" #'vc-hg-log-edit-toggle-amend) map)) (define-derived-mode vc-hg-log-edit-mode log-edit-mode "Log-Edit/hg" @@ -1214,7 +1204,7 @@ REV is ignored." (lambda (value) (when (equal value "yes") (list "--amend"))))) - (apply 'vc-hg-command nil 0 files + (apply #'vc-hg-command nil 0 files (nconc (list "commit" "-m") (log-edit-extract-headers `(("Author" . "--user") ("Date" . "--date") @@ -1252,7 +1242,7 @@ REV is the revision to check out into WORKFILE." (unless (re-search-forward "^<<<<<<< " nil t) (vc-hg-command nil 0 buffer-file-name "resolve" "-m") ;; Remove the hook so that it is not called multiple times. - (remove-hook 'after-save-hook 'vc-hg-resolve-when-done t)))) + (remove-hook 'after-save-hook #'vc-hg-resolve-when-done t)))) (defun vc-hg-find-file-hook () (when (and buffer-file-name @@ -1268,7 +1258,7 @@ REV is the revision to check out into WORKFILE." ;; Hg may not recognize "conflict" as a state, but we can do better. (vc-file-setprop buffer-file-name 'vc-state 'conflict) (smerge-start-session) - (add-hook 'after-save-hook 'vc-hg-resolve-when-done nil t) + (add-hook 'after-save-hook #'vc-hg-resolve-when-done nil t) (vc-message-unresolved-conflicts buffer-file-name))) @@ -1443,7 +1433,7 @@ commands, which only operated on marked files." (apply #'vc-hg-command nil 0 nil command - (apply 'nconc + (apply #'nconc (mapcar (lambda (arg) (list "-r" arg)) marked-list))) (let* ((root (vc-hg-root default-directory)) (buffer (format "*vc-hg : %s*" (expand-file-name root))) @@ -1463,18 +1453,18 @@ commands, which only operated on marked files." (setq hg-program (car args) command (cadr args) args (cddr args))) - (apply 'vc-do-async-command buffer root hg-program command args) + (apply #'vc-do-async-command buffer root hg-program command args) (with-current-buffer buffer (vc-run-delayed (dolist (cmd post-processing) - (apply 'vc-do-command buffer nil hg-program nil cmd)) + (apply #'vc-do-command buffer nil hg-program nil cmd)) (vc-compilation-mode 'hg) (setq-local compile-command (concat hg-program " " command " " - (mapconcat 'identity args " ") + (mapconcat #'identity args " ") (mapconcat (lambda (args) (concat " && " hg-program " " - (mapconcat 'identity + (mapconcat #'identity args " "))) post-processing ""))) (setq-local compilation-directory root) @@ -1525,7 +1515,7 @@ This runs the command \"hg merge\"." ;; Disable pager. (process-environment (cons "HGPLAIN=1" process-environment)) (branch (vc-read-revision "Revision to merge: "))) - (apply 'vc-do-async-command buffer root vc-hg-program + (apply #'vc-do-async-command buffer root vc-hg-program (append '("--config" "ui.report_untrusted=0" "merge") (unless (string= branch "") (list branch)))) (with-current-buffer buffer (vc-run-delayed (vc-compilation-mode 'hg))) @@ -1540,7 +1530,8 @@ This function differs from vc-do-command in that it invokes ;; Disable pager. (let ((process-environment (cons "HGPLAIN=1" process-environment)) (flags (append '("--config" "ui.report_untrusted=0") flags))) - (apply 'vc-do-command (or buffer "*vc*") okstatus vc-hg-program file-or-list + (apply #'vc-do-command (or buffer "*vc*") + okstatus vc-hg-program file-or-list (if (stringp vc-hg-global-switches) (cons vc-hg-global-switches flags) (append vc-hg-global-switches diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el index f910f9d549..4b3c829a2c 100644 --- a/lisp/vc/vc-hooks.el +++ b/lisp/vc/vc-hooks.el @@ -50,50 +50,42 @@ (defface vc-up-to-date-state '((default :inherit vc-state-base)) "Face for VC modeline state when the file is up to date." - :version "25.1" - :group 'vc-faces) + :version "25.1") (defface vc-needs-update-state '((default :inherit vc-state-base)) "Face for VC modeline state when the file needs update." - :version "25.1" - :group 'vc-faces) + :version "25.1") (defface vc-locked-state '((default :inherit vc-state-base)) "Face for VC modeline state when the file locked." - :version "25.1" - :group 'vc-faces) + :version "25.1") (defface vc-locally-added-state '((default :inherit vc-state-base)) "Face for VC modeline state when the file is locally added." - :version "25.1" - :group 'vc-faces) + :version "25.1") (defface vc-conflict-state '((default :inherit vc-state-base)) "Face for VC modeline state when the file contains merge conflicts." - :version "25.1" - :group 'vc-faces) + :version "25.1") (defface vc-removed-state '((default :inherit vc-state-base)) "Face for VC modeline state when the file was removed from the VC system." - :version "25.1" - :group 'vc-faces) + :version "25.1") (defface vc-missing-state '((default :inherit vc-state-base)) "Face for VC modeline state when the file is missing from the file system." - :version "25.1" - :group 'vc-faces) + :version "25.1") (defface vc-edited-state '((default :inherit vc-state-base)) "Face for VC modeline state when the file is edited." - :version "25.1" - :group 'vc-faces) + :version "25.1") ;; Customization Variables (the rest is in vc.el) @@ -871,31 +863,31 @@ In the latter case, VC mode is deactivated for this buffer." ;; (autoload 'vc-prefix-map "vc" nil nil 'keymap) (defvar vc-prefix-map (let ((map (make-sparse-keymap))) - (define-key map "a" 'vc-update-change-log) - (define-key map "b" 'vc-switch-backend) - (define-key map "d" 'vc-dir) - (define-key map "g" 'vc-annotate) - (define-key map "G" 'vc-ignore) - (define-key map "h" 'vc-region-history) - (define-key map "i" 'vc-register) - (define-key map "l" 'vc-print-log) - (define-key map "L" 'vc-print-root-log) - (define-key map "I" 'vc-log-incoming) - (define-key map "O" 'vc-log-outgoing) - (define-key map "ML" 'vc-log-mergebase) - (define-key map "MD" 'vc-diff-mergebase) - (define-key map "m" 'vc-merge) - (define-key map "r" 'vc-retrieve-tag) - (define-key map "s" 'vc-create-tag) - (define-key map "u" 'vc-revert) - (define-key map "v" 'vc-next-action) - (define-key map "+" 'vc-update) + (define-key map "a" #'vc-update-change-log) + (define-key map "b" #'vc-switch-backend) + (define-key map "d" #'vc-dir) + (define-key map "g" #'vc-annotate) + (define-key map "G" #'vc-ignore) + (define-key map "h" #'vc-region-history) + (define-key map "i" #'vc-register) + (define-key map "l" #'vc-print-log) + (define-key map "L" #'vc-print-root-log) + (define-key map "I" #'vc-log-incoming) + (define-key map "O" #'vc-log-outgoing) + (define-key map "ML" #'vc-log-mergebase) + (define-key map "MD" #'vc-diff-mergebase) + (define-key map "m" #'vc-merge) + (define-key map "r" #'vc-retrieve-tag) + (define-key map "s" #'vc-create-tag) + (define-key map "u" #'vc-revert) + (define-key map "v" #'vc-next-action) + (define-key map "+" #'vc-update) ;; I'd prefer some kind of symmetry with vc-update: - (define-key map "P" 'vc-push) - (define-key map "=" 'vc-diff) - (define-key map "D" 'vc-root-diff) - (define-key map "~" 'vc-revision-other-window) - (define-key map "x" 'vc-delete-file) + (define-key map "P" #'vc-push) + (define-key map "=" #'vc-diff) + (define-key map "D" #'vc-root-diff) + (define-key map "~" #'vc-revision-other-window) + (define-key map "x" #'vc-delete-file) map)) (fset 'vc-prefix-map vc-prefix-map) (define-key ctl-x-map "v" 'vc-prefix-map) diff --git a/lisp/vc/vc-mtn.el b/lisp/vc/vc-mtn.el index 3b610a1e4f..ea69893071 100644 --- a/lisp/vc/vc-mtn.el +++ b/lisp/vc/vc-mtn.el @@ -46,8 +46,7 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." (const :tag "None" t) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "23.1" - :group 'vc-mtn) + :version "23.1") (defcustom vc-mtn-annotate-switches nil "String or list of strings specifying switches for mtn annotate under VC. @@ -57,13 +56,11 @@ switches." (const :tag "None" t) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "25.1" - :group 'vc-mtn) + :version "25.1") (defcustom vc-mtn-program "mtn" "Name of the monotone executable." - :type 'string - :group 'vc-mtn) + :type 'string) ;; Clear up the cache to force vc-call to check again and discover ;; new functions when we reload this file. @@ -115,7 +112,7 @@ switches." (let ((process-environment ;; Avoid localization of messages so we can parse the output. (cons "LC_MESSAGES=C" process-environment))) - (apply 'vc-do-command (or buffer "*vc*") okstatus vc-mtn-program + (apply #'vc-do-command (or buffer "*vc*") okstatus vc-mtn-program files flags))) (defun vc-mtn-state (file) @@ -176,8 +173,7 @@ switches." '(("\\`[^:/#]*[:/#]" . "")) ;Drop the host part. "Rewrite rules to shorten Mtn's revision names on the mode-line." :type '(repeat (cons regexp string)) - :version "22.2" - :group 'vc-mtn) + :version "22.2") (defun vc-mtn-mode-line-string (file) "Return a string for `vc-mode-line' to put in the mode line for FILE." @@ -203,7 +199,7 @@ switches." (declare-function log-edit-extract-headers "log-edit" (headers string)) (defun vc-mtn-checkin (files comment &optional _rev) - (apply 'vc-mtn-command nil 0 files + (apply #'vc-mtn-command nil 0 files (nconc (list "commit" "-m") (log-edit-extract-headers '(("Author" . "--author") ("Date" . "--date")) @@ -227,7 +223,7 @@ switches." _SHORTLOG is ignored. If START-REVISION is non-nil, it is the newest revision to show. If LIMIT is non-nil, show no more than this many entries." - (apply 'vc-mtn-command buffer 0 files "log" + (apply #'vc-mtn-command buffer 0 files "log" (append (when start-revision (list "--from" (format "%s" start-revision))) (when limit (list "--last" (format "%s" limit)))))) @@ -258,7 +254,7 @@ If LIMIT is non-nil, show no more than this many entries." (defun vc-mtn-diff (files &optional rev1 rev2 buffer _async) "Get a difference report using monotone between two revisions of FILES." - (apply 'vc-mtn-command (or buffer "*vc-diff*") + (apply #'vc-mtn-command (or buffer "*vc-diff*") 1 ; bug#21969 files "diff" (append diff --git a/lisp/vc/vc-rcs.el b/lisp/vc/vc-rcs.el index 8d64ee5cc5..6ffc1a8a2f 100644 --- a/lisp/vc/vc-rcs.el +++ b/lisp/vc/vc-rcs.el @@ -58,8 +58,7 @@ If nil, VC itself computes this value when it is first needed." :type '(choice (const :tag "Auto" nil) (string :tag "Specified") - (const :tag "Unknown" unknown)) - :group 'vc-rcs) + (const :tag "Unknown" unknown))) (defcustom vc-rcs-register-switches nil "Switches for registering a file in RCS. @@ -70,8 +69,7 @@ If t, use no switches." (const :tag "None" t) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "21.1" - :group 'vc-rcs) + :version "21.1") (defcustom vc-rcs-diff-switches nil "String or list of strings specifying switches for RCS diff under VC. @@ -80,21 +78,18 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." (const :tag "None" t) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "21.1" - :group 'vc-rcs) + :version "21.1") (defcustom vc-rcs-header '("$Id\ $") "Header keywords to be inserted by `vc-insert-headers'." :type '(repeat string) - :version "24.1" ; no longer consult the obsolete vc-header-alist - :group 'vc-rcs) + :version "24.1") ; no longer consult the obsolete vc-header-alist (defcustom vc-rcsdiff-knows-brief nil "Indicates whether rcsdiff understands the --brief option. The value is either `yes', `no', or nil. If it is nil, VC tries to use --brief and sets this variable to remember whether it worked." - :type '(choice (const :tag "Work out" nil) (const yes) (const no)) - :group 'vc-rcs) + :type '(choice (const :tag "Work out" nil) (const yes) (const no))) ;; This needs to be autoloaded because vc-rcs-registered uses it (via ;; vc-default-registered), and vc-hooks needs to be able to check @@ -109,8 +104,7 @@ For a description of possible values, see `vc-check-master-templates'." (repeat :tag "User-specified" (choice string function))) - :version "21.1" - :group 'vc-rcs) + :version "21.1") ;;; Properties of the backend @@ -379,7 +373,7 @@ whether to remove it." "Retrieve a copy of a saved version of FILE. If FILE is a directory, attempt the checkout for all registered files beneath it." (if (file-directory-p file) - (mapc 'vc-rcs-checkout (vc-expand-dirs (list file) 'RCS)) + (mapc #'vc-rcs-checkout (vc-expand-dirs (list file) 'RCS)) (let ((file-buffer (get-file-buffer file)) switches) (message "Checking out %s..." file) @@ -445,7 +439,7 @@ attempt the checkout for all registered files beneath it." "Revert FILE to the version it was based on. If FILE is a directory, revert all registered files beneath it." (if (file-directory-p file) - (mapc 'vc-rcs-revert (vc-expand-dirs (list file) 'RCS)) + (mapc #'vc-rcs-revert (vc-expand-dirs (list file) 'RCS)) (vc-do-command "*vc*" 0 "co" (vc-master-name file) "-f" (concat (if (eq (vc-state file) 'edited) "-u" "-r") (vc-working-revision file))))) @@ -488,7 +482,7 @@ The changes are between FIRST-VERSION and SECOND-VERSION." If FILE is a directory, steal the lock on all registered files beneath it. Needs RCS 5.6.2 or later for -M." (if (file-directory-p file) - (mapc 'vc-rcs-steal-lock (vc-expand-dirs (list file) 'RCS)) + (mapc #'vc-rcs-steal-lock (vc-expand-dirs (list file) 'RCS)) (vc-do-command "*vc*" 0 "rcs" (vc-master-name file) "-M" (concat "-u" rev)) ;; Do a real checkout after stealing the lock, so that we see ;; expanded headers. @@ -539,7 +533,7 @@ Remaining arguments are ignored. If FILE is a directory the operation is applied to all registered files beneath it." (vc-do-command (or buffer "*vc*") 0 "rlog" - (mapcar 'vc-master-name (vc-expand-dirs files 'RCS))) + (mapcar #'vc-master-name (vc-expand-dirs files 'RCS))) (with-current-buffer (or buffer "*vc*") (vc-rcs-print-log-cleanup)) (when limit 'limit-unsupported)) @@ -1344,7 +1338,7 @@ The `:insn' key is a keyword to distinguish it as a vc-rcs.el extension." (push `(,(to-eol) ,(k-semi 'date (lambda () - (let ((ls (mapcar 'string-to-number + (let ((ls (mapcar #'string-to-number (split-string (buffer-substring-no-properties b e) diff --git a/lisp/vc/vc-sccs.el b/lisp/vc/vc-sccs.el index 3d3f404805..92cce5f13a 100644 --- a/lisp/vc/vc-sccs.el +++ b/lisp/vc/vc-sccs.el @@ -55,8 +55,7 @@ If t, use no switches." (const :tag "None" t) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "21.1" - :group 'vc-sccs) + :version "21.1") (defcustom vc-sccs-diff-switches nil "String or list of strings specifying switches for SCCS diff under VC. @@ -65,14 +64,12 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." (const :tag "None" t) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "21.1" - :group 'vc-sccs) + :version "21.1") (defcustom vc-sccs-header '("%W%") "Header keywords to be inserted by `vc-insert-headers'." :type '(repeat string) - :version "24.1" ; no longer consult the obsolete vc-header-alist - :group 'vc-sccs) + :version "24.1") ; no longer consult the obsolete vc-header-alist ;; This needs to be autoloaded because vc-sccs-registered uses it (via ;; vc-default-registered), and vc-hooks needs to be able to check @@ -87,8 +84,7 @@ For a description of possible values, see `vc-check-master-templates'." (repeat :tag "User-specified" (choice string function))) - :version "21.1" - :group 'vc-sccs) + :version "21.1") ;;; @@ -163,7 +159,7 @@ For a description of possible values, see `vc-check-master-templates'." "Write the SCCS version of input file FILE to output file OUTFILE. Optional string REV is a revision." (with-temp-buffer - (apply 'vc-sccs-do-command t 0 "get" (vc-master-name file) + (apply #'vc-sccs-do-command t 0 "get" (vc-master-name file) (append '("-s" "-p" "-k") ; -k: no keyword expansion (if rev (list (concat "-r" rev))))) (write-region nil nil outfile nil 'silent))) @@ -185,7 +181,7 @@ Optional string REV is a revision." (defun vc-sccs-do-command (buffer okstatus command file-or-list &rest flags) ;; (let ((load-path (append vc-sccs-path load-path))) ;; (apply 'vc-do-command buffer okstatus command file-or-list flags)) - (apply 'vc-do-command (or buffer "*vc*") okstatus "sccs" file-or-list command flags)) + (apply #'vc-do-command (or buffer "*vc*") okstatus "sccs" file-or-list command flags)) (defun vc-sccs-create-repo () "Create a new SCCS repository." @@ -207,7 +203,7 @@ to the SCCS command." (let ((vc-master-name (or project-file (format (car vc-sccs-master-templates) dirname basename)))) - (apply 'vc-sccs-do-command nil 0 "admin" vc-master-name + (apply #'vc-sccs-do-command nil 0 "admin" vc-master-name "-fb" (concat "-i" (file-relative-name file)) (and comment (concat "-y" comment)) @@ -225,14 +221,14 @@ to the SCCS command." (defun vc-sccs-checkin (files comment &optional rev) "SCCS-specific version of `vc-backend-checkin'." (dolist (file (vc-expand-dirs files 'SCCS)) - (apply 'vc-sccs-do-command nil 0 "delta" (vc-master-name file) + (apply #'vc-sccs-do-command nil 0 "delta" (vc-master-name file) (if rev (concat "-r" rev)) (concat "-y" comment) (vc-switches 'SCCS 'checkin)) (vc-sccs-do-command nil 0 "get" (vc-master-name file)))) (defun vc-sccs-find-revision (file rev buffer) - (apply 'vc-sccs-do-command + (apply #'vc-sccs-do-command buffer 0 "get" (vc-master-name file) "-s" ;; suppress diagnostic output "-p" @@ -247,7 +243,7 @@ If FILE is a directory, all version-controlled files beneath are checked out. EDITABLE non-nil means that the file should be writable and locked. REV is the revision to check out." (if (file-directory-p file) - (mapc 'vc-sccs-checkout (vc-expand-dirs (list file) 'SCCS)) + (mapc #'vc-sccs-checkout (vc-expand-dirs (list file) 'SCCS)) (let ((file-buffer (get-file-buffer file)) switches) (message "Checking out %s..." file) @@ -267,7 +263,7 @@ locked. REV is the revision to check out." (and rev (or (string= rev "") (not (stringp rev))) (setq rev nil)) - (apply 'vc-sccs-do-command nil 0 "get" (vc-master-name file) + (apply #'vc-sccs-do-command nil 0 "get" (vc-master-name file) "-e" (and rev (concat "-r" (vc-sccs-lookup-triple file rev))) switches)))) @@ -277,7 +273,7 @@ locked. REV is the revision to check out." "Revert FILE to the version it was based on. If FILE is a directory, revert all subfiles." (if (file-directory-p file) - (mapc 'vc-sccs-revert (vc-expand-dirs (list file) 'SCCS)) + (mapc #'vc-sccs-revert (vc-expand-dirs (list file) 'SCCS)) (vc-sccs-do-command nil 0 "unget" (vc-master-name file)) (vc-sccs-do-command nil 0 "get" (vc-master-name file)) ;; Checking out explicit revisions is not supported under SCCS, yet. @@ -288,7 +284,7 @@ revert all subfiles." (defun vc-sccs-steal-lock (file &optional rev) "Steal the lock on the current workfile for FILE and revision REV." (if (file-directory-p file) - (mapc 'vc-sccs-steal-lock (vc-expand-dirs (list file) 'SCCS)) + (mapc #'vc-sccs-steal-lock (vc-expand-dirs (list file) 'SCCS)) (vc-sccs-do-command nil 0 "unget" (vc-master-name file) "-n" (if rev (concat "-r" rev))) (vc-sccs-do-command nil 0 "get" @@ -309,7 +305,7 @@ revert all subfiles." "Print commit log associated with FILES into specified BUFFER. Remaining arguments are ignored." (setq files (vc-expand-dirs files 'SCCS)) - (vc-sccs-do-command buffer 0 "prs" (mapcar 'vc-master-name files)) + (vc-sccs-do-command buffer 0 "prs" (mapcar #'vc-master-name files)) (when limit 'limit-unsupported)) (autoload 'vc-setup-buffer "vc-dispatcher") @@ -338,7 +334,7 @@ Remaining arguments are ignored." (fake-command (format "diff%s %s" (if fake-flags - (concat " " (mapconcat 'identity fake-flags " ")) + (concat " " (mapconcat #'identity fake-flags " ")) "") (vc-delistify files))) (status 0) @@ -362,7 +358,7 @@ Remaining arguments are ignored." (cons "LC_MESSAGES=C" process-environment)) (w32-quote-process-args t) (this-status - (apply 'process-file "diff" nil t nil + (apply #'process-file "diff" nil t nil (append (vc-switches 'SCCS 'diff) (list (file-local-name oldfile) (or newfile diff --git a/lisp/vc/vc-src.el b/lisp/vc/vc-src.el index 201d69d79a..faba5bce2b 100644 --- a/lisp/vc/vc-src.el +++ b/lisp/vc/vc-src.el @@ -97,13 +97,11 @@ If nil, VC itself computes this value when it is first needed." :type '(choice (const :tag "Auto" nil) (string :tag "Specified") - (const :tag "Unknown" unknown)) - :group 'vc-src) + (const :tag "Unknown" unknown))) (defcustom vc-src-program "src" "Name of the SRC executable (excluding any arguments)." - :type 'string - :group 'vc-src) + :type 'string) (defcustom vc-src-diff-switches nil "String or list of strings specifying switches for SRC diff under VC. @@ -111,8 +109,7 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." :type '(choice (const :tag "Unspecified" nil) (const :tag "None" t) (string :tag "Argument String") - (repeat :tag "Argument List" :value ("") string)) - :group 'vc-src) + (repeat :tag "Argument List" :value ("") string))) ;; This needs to be autoloaded because vc-src-registered uses it (via ;; vc-default-registered), and vc-hooks needs to be able to check @@ -126,8 +123,7 @@ For a description of possible values, see `vc-check-master-templates'." '("%s.src/%s,v")) (repeat :tag "User-specified" (choice string - function))) - :group 'vc-src) + function)))) ;;; Properties of the backend @@ -221,7 +217,7 @@ This function differs from vc-do-command in that it invokes `vc-src-program'." (setq file-list (list "--" file-or-list))) (file-or-list (setq file-list (cons "--" file-or-list)))) - (apply 'vc-do-command (or buffer "*vc*") 0 vc-src-program file-list flags))) + (apply #'vc-do-command (or buffer "*vc*") 0 vc-src-program file-list flags))) (defun vc-src-working-revision (file) "SRC-specific version of `vc-working-revision'." @@ -275,7 +271,7 @@ REV is the revision to check out into WORKFILE." "Revert FILE to the version it was based on. If FILE is a directory, revert all registered files beneath it." (if (file-directory-p file) - (mapc 'vc-src-revert (vc-expand-dirs (list file) 'SRC)) + (mapc #'vc-src-revert (vc-expand-dirs (list file) 'SRC)) (vc-src-command nil file "co"))) (defun vc-src-modify-change-comment (files rev comment) @@ -290,8 +286,7 @@ directory the operation is applied to all registered files beneath it." "String or list of strings specifying switches for src log under VC." :type '(choice (const :tag "None" nil) (string :tag "Argument String") - (repeat :tag "Argument List" :value ("") string)) - :group 'vc-src) + (repeat :tag "Argument List" :value ("") string))) (defun vc-src-print-log (files buffer &optional shortlog _start-revision limit) "Print commit log associated with FILES into specified BUFFER. @@ -307,7 +302,7 @@ If LIMIT is non-nil, show no more than this many entries." (let ((inhibit-read-only t)) (with-current-buffer buffer - (apply 'vc-src-command buffer files (if shortlog "list" "log") + (apply #'vc-src-command buffer files (if shortlog "list" "log") (nconc ;;(when start-revision (list (format "%s-1" start-revision))) (when limit (list "-l" (format "%s" limit))) diff --git a/lisp/vc/vc-svn.el b/lisp/vc/vc-svn.el index 22becc91cd..c30920dd15 100644 --- a/lisp/vc/vc-svn.el +++ b/lisp/vc/vc-svn.el @@ -47,8 +47,7 @@ ;; FIXME there is also svnadmin. (defcustom vc-svn-program "svn" "Name of the SVN executable." - :type 'string - :group 'vc-svn) + :type 'string) ;; Might be nice if svn defaulted to non-interactive if stdin not tty. ;; https://svn.haxx.se/dev/archive-2008-05/0762.shtml @@ -64,8 +63,7 @@ hanging while prompting for authorization." (repeat :tag "Argument List" :value ("") string)) - :version "24.4" - :group 'vc-svn) + :version "24.4") (defcustom vc-svn-register-switches nil "Switches for registering a file into SVN. @@ -76,8 +74,7 @@ If t, use no switches." (const :tag "None" t) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "22.1" - :group 'vc-svn) + :version "22.1") (defcustom vc-svn-diff-switches t ;`svn' doesn't support common args like -c or -b. @@ -92,8 +89,7 @@ If you want to force an empty list of arguments, use t." (repeat :tag "Argument List" :value ("") string)) - :version "22.1" - :group 'vc-svn) + :version "22.1") (defcustom vc-svn-annotate-switches nil "String or list of strings specifying switches for svn annotate under VC. @@ -103,14 +99,12 @@ switches." (const :tag "None" t) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "25.1" - :group 'vc-svn) + :version "25.1") (defcustom vc-svn-header '("$Id\ $") "Header keywords to be inserted by `vc-insert-headers'." :version "24.1" ; no longer consult the obsolete vc-header-alist - :type '(repeat string) - :group 'vc-svn) + :type '(repeat string)) ;; We want to autoload it for use by the autoloaded version of ;; vc-svn-registered, but we want the value to be compiled at startup, not @@ -305,19 +299,19 @@ RESULT is a list of conses (FILE . STATE) for directory DIR." The COMMENT argument is ignored This does an add but not a commit. Passes either `vc-svn-register-switches' or `vc-register-switches' to the SVN command." - (apply 'vc-svn-command nil 0 files "add" (vc-switches 'SVN 'register))) + (apply #'vc-svn-command nil 0 files "add" (vc-switches 'SVN 'register))) (defun vc-svn-root (file) (vc-find-root file vc-svn-admin-directory)) -(defalias 'vc-svn-responsible-p 'vc-svn-root) +(defalias 'vc-svn-responsible-p #'vc-svn-root) (declare-function log-edit-extract-headers "log-edit" (headers string)) (defun vc-svn-checkin (files comment &optional _extra-args-ignored) "SVN-specific version of `vc-backend-checkin'." (let ((status (apply - 'vc-svn-command nil 1 files "ci" + #'vc-svn-command nil 1 files "ci" (nconc (cons "-m" (log-edit-extract-headers nil comment)) (vc-switches 'SVN 'checkin))))) (set-buffer "*vc*") @@ -345,7 +339,7 @@ to the SVN command." (defun vc-svn-find-revision (file rev buffer) "SVN-specific retrieval of a specified version into a buffer." (let (process-file-side-effects) - (apply 'vc-svn-command + (apply #'vc-svn-command buffer 0 file "cat" (and rev (not (string= rev "")) @@ -391,7 +385,7 @@ DIRECTORY or absolute." nil ;; Check out a particular version (or recreate the file). (vc-file-setprop file 'vc-working-revision nil) - (apply 'vc-svn-command nil 0 file + (apply #'vc-svn-command nil 0 file "update" (cond ((null rev) "-rBASE") @@ -563,27 +557,27 @@ If LIMIT is non-nil, show no more than this many entries." (goto-char (point-min)) (if files (dolist (file files) - (insert "Working file: " file "\n") - (apply - 'vc-svn-command - buffer - 'async - (list file) - "log" - (append - (list - (if start-revision - (format "-r%s:1" start-revision) - ;; By default Subversion only shows the log up to the - ;; working revision, whereas we also want the log of the - ;; subsequent commits. At least that's what the - ;; vc-cvs.el code does. - "-rHEAD:0")) - (if (eq vc-log-view-type 'with-diff) - (list "--diff")) - (when limit (list "--limit" (format "%s" limit)))))) + (insert "Working file: " file "\n") + (apply + #'vc-svn-command + buffer + 'async + (list file) + "log" + (append + (list + (if start-revision + (format "-r%s:1" start-revision) + ;; By default Subversion only shows the log up to the + ;; working revision, whereas we also want the log of the + ;; subsequent commits. At least that's what the + ;; vc-cvs.el code does. + "-rHEAD:0")) + (if (eq vc-log-view-type 'with-diff) + (list "--diff")) + (when limit (list "--limit" (format "%s" limit)))))) ;; Dump log for the entire directory. - (apply 'vc-svn-command buffer 0 nil "log" + (apply #'vc-svn-command buffer 0 nil "log" (append (list (if start-revision (format "-r%s" start-revision) "-rHEAD:0")) @@ -611,8 +605,8 @@ If LIMIT is non-nil, show no more than this many entries." (if vc-svn-diff-switches (vc-switches 'SVN 'diff) (list (concat "--diff-cmd=" diff-command) "-x" - (mapconcat 'identity (vc-switches nil 'diff) " "))))) - (apply 'vc-svn-command buffer + (mapconcat #'identity (vc-switches nil 'diff) " "))))) + (apply #'vc-svn-command buffer (if async 'async 0) files "diff" (append @@ -671,7 +665,7 @@ NAME is assumed to be a URL." "A wrapper around `vc-do-command' for use in vc-svn.el. The difference to vc-do-command is that this function always invokes `svn', and that it passes `vc-svn-global-switches' to it before FLAGS." - (apply 'vc-do-command (or buffer "*vc*") okstatus vc-svn-program file-or-list + (apply #'vc-do-command (or buffer "*vc*") okstatus vc-svn-program file-or-list (if (stringp vc-svn-global-switches) (cons vc-svn-global-switches flags) (append vc-svn-global-switches flags)))) @@ -683,7 +677,7 @@ and that it passes `vc-svn-global-switches' to it before FLAGS." (unless (re-search-forward "^<<<<<<< " nil t) (vc-svn-command nil 0 buffer-file-name "resolved") ;; Remove the hook so that it is not called multiple times. - (remove-hook 'after-save-hook 'vc-svn-resolve-when-done t)))) + (remove-hook 'after-save-hook #'vc-svn-resolve-when-done t)))) ;; Inspired by vc-arch-find-file-hook. (defun vc-svn-find-file-hook () @@ -696,7 +690,7 @@ and that it passes `vc-svn-global-switches' to it before FLAGS." ;; There are conflict markers. (progn (smerge-start-session) - (add-hook 'after-save-hook 'vc-svn-resolve-when-done nil t)) + (add-hook 'after-save-hook #'vc-svn-resolve-when-done nil t)) ;; There are no conflict markers. This is problematic: maybe it means ;; the conflict has been resolved and we should immediately call "svn ;; resolved", or it means that the file's type does not allow Svn to diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 00976a07d4..b926c3819d 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -1425,6 +1425,7 @@ first backend that could register the file is used." (let ((vc-handled-backends (list backend))) (call-interactively 'vc-register))) +;;;###autoload (defun vc-ignore (file &optional directory remove) "Ignore FILE under the VCS of DIRECTORY. commit 2987376bc358b069ee27f4b0757491f1a8157bf2 Author: Stefan Monnier Date: Fri Feb 26 15:34:30 2021 -0500 * lisp/cedet/semantic/idle.el: Fix compilation warning (eldoc-last-message): Remove var declaration. (eldoc-message): Remove function declaration. (semantic--eldoc-info): Rename from semantic-idle-summary-idle-function. Make it usable on `eldoc-documentation-functions`. (semantic-idle-summary-mode): Use `eldoc-mode`. (semantic-idle-summary-refresh-echo-area): Delete function. diff --git a/lisp/cedet/semantic/idle.el b/lisp/cedet/semantic/idle.el index 5af4607abb..0f997474de 100644 --- a/lisp/cedet/semantic/idle.el +++ b/lisp/cedet/semantic/idle.el @@ -47,8 +47,6 @@ ;; For the semantic-find-tags-by-name macro. (eval-when-compile (require 'semantic/find)) -(defvar eldoc-last-message) -(declare-function eldoc-message "eldoc") (declare-function semantic-analyze-unsplit-name "semantic/analyze/fcn") (declare-function semantic-complete-analyze-inline-idle "semantic/complete") (declare-function semanticdb-deep-find-tags-by-name "semantic/db-find") @@ -730,8 +728,8 @@ specific to a major mode. For example, in jde mode: :group 'semantic :type 'hook) -(defun semantic-idle-summary-idle-function () - "Display a tag summary of the lexical token under the cursor. +(defun semantic--eldoc-info (_callback &rest _) + "Return the eldoc info for the current symbol. Call `semantic-idle-summary-current-symbol-info' for getting the current tag to display information." (or (eq major-mode 'emacs-lisp-mode) @@ -741,21 +739,7 @@ current tag to display information." ((semantic-tag-p found) (funcall semantic-idle-summary-function found nil t))))) - ;; Show the message with eldoc functions - (unless (and str (boundp 'eldoc-echo-area-use-multiline-p) - eldoc-echo-area-use-multiline-p) - (let ((w (1- (window-width (minibuffer-window))))) - (if (> (length str) w) - (setq str (substring str 0 w))))) - ;; I borrowed some bits from eldoc to shorten the - ;; message. - (when semantic-idle-truncate-long-summaries - (let ((ea-width (1- (window-width (minibuffer-window)))) - (strlen (length str))) - (when (> strlen ea-width) - (setq str (substring str 0 ea-width))))) - ;; Display it - (eldoc-message str)))) + str))) (define-minor-mode semantic-idle-summary-mode "Toggle Semantic Idle Summary mode. @@ -764,30 +748,16 @@ When this minor mode is enabled, the echo area displays a summary of the lexical token at point whenever Emacs is idle." :group 'semantic :group 'semantic-modes - (if semantic-idle-summary-mode - ;; Enable the mode - (progn - (unless (and (featurep 'semantic) (semantic-active-p)) - ;; Disable minor mode if semantic stuff not available - (setq semantic-idle-summary-mode nil) - (error "Buffer %s was not set up for parsing" - (buffer-name))) - (require 'eldoc) - (semantic-idle-scheduler-add 'semantic-idle-summary-idle-function) - (add-hook 'pre-command-hook 'semantic-idle-summary-refresh-echo-area t)) - ;; Disable the mode - (semantic-idle-scheduler-remove 'semantic-idle-summary-idle-function) - (remove-hook 'pre-command-hook 'semantic-idle-summary-refresh-echo-area t))) - -(defun semantic-idle-summary-refresh-echo-area () - (and semantic-idle-summary-mode - eldoc-last-message - (if (and (not executing-kbd-macro) - (not (and (boundp 'edebug-active) edebug-active)) - (not cursor-in-echo-area) - (not (eq (selected-window) (minibuffer-window)))) - (eldoc-message eldoc-last-message) - (setq eldoc-last-message nil)))) + (remove-hook 'eldoc-documentation-functions #'semantic--eldoc-info t) + (when semantic-idle-summary-mode + ;; Enable the mode + (unless (and (featurep 'semantic) (semantic-active-p)) + ;; Disable minor mode if semantic stuff not available + (setq semantic-idle-summary-mode nil) + (error "Buffer %s was not set up for parsing" + (buffer-name))) + (add-hook 'eldoc-documentation-functions #'semantic--eldoc-info nil t) + (eldoc-mode 1))) (semantic-add-minor-mode 'semantic-idle-summary-mode "") @@ -1092,7 +1062,7 @@ be called." ;; mouse-3 pops up a context menu (define-key map [ header-line mouse-3 ] - 'semantic-idle-breadcrumbs--popup-menu) + #'semantic-idle-breadcrumbs--popup-menu) map) "Keymap for semantic idle breadcrumbs minor mode.") commit 49bad2a0a662794089506a964cb7b470aff13826 Author: Stefan Monnier Date: Fri Feb 26 15:19:31 2021 -0500 * lisp/cedet/semantic/analyze*.el: Use lexical-binding * lisp/cedet/semantic/analyze.el: Use lexical-binding. Rename the dynbound var `prefixtypes` to `semantic--prefixtypes`. (semantic--prefixtypes): Declare var. * lisp/cedet/semantic/analyze/complete.el: Use lexical-binding. (semantic--prefixtypes): Declare var. (semantic-analyze-possible-completions-default): Remove unused var `any`. Rename `prefixtypes` to `semantic--prefixtypes`. * lisp/cedet/semantic/analyze/debug.el: Use lexical-binding. (semantic-analyzer-debug-global-symbol): Remove no-op use of `prefixtypes`. * lisp/cedet/semantic/analyze/refs.el: * lisp/cedet/semantic/analyze/fcn.el: Use lexical-binding. diff --git a/lisp/cedet/semantic/analyze.el b/lisp/cedet/semantic/analyze.el index c0a054dafc..1a4be11c78 100644 --- a/lisp/cedet/semantic/analyze.el +++ b/lisp/cedet/semantic/analyze.el @@ -1,4 +1,4 @@ -;;; semantic/analyze.el --- Analyze semantic tags against local context +;;; semantic/analyze.el --- Analyze semantic tags against local context -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2005, 2007-2021 Free Software Foundation, Inc. @@ -167,7 +167,7 @@ of the parent function.") ;; Simple methods against the context classes. ;; (cl-defmethod semantic-analyze-type-constraint - ((context semantic-analyze-context) &optional desired-type) + ((_context semantic-analyze-context) &optional desired-type) "Return a type constraint for completing :prefix in CONTEXT. Optional argument DESIRED-TYPE may be a non-type tag to analyze." (when (semantic-tag-p desired-type) @@ -344,8 +344,8 @@ This function knows of flags: (setq tagtype (cons tmptype tagtype)) (when miniscope (let ((rawscope - (apply 'append - (mapcar 'semantic-tag-type-members tagtype)))) + (apply #'append + (mapcar #'semantic-tag-type-members tagtype)))) (oset miniscope fullscope rawscope))) ) (setq s (cdr s))) @@ -437,6 +437,8 @@ to provide a large number of non-cached analysis for filtering symbols." (:override))) ) +(defvar semantic--prefixtypes) + (defun semantic-analyze-current-symbol-default (analyzehookfcn position) "Call ANALYZEHOOKFCN on the analyzed symbol at POSITION." (let* ((semantic-analyze-error-stack nil) @@ -453,14 +455,14 @@ to provide a large number of non-cached analysis for filtering symbols." (catch 'unfindable ;; If debug on error is on, allow debugging in this fcn. (setq prefix (semantic-analyze-find-tag-sequence - prefix scope 'prefixtypes 'unfindable))) + prefix scope 'semantic--prefixtypes 'unfindable))) ;; Debug on error is off. Capture errors and move on (condition-case err ;; NOTE: This line is duplicated in ;; semantic-analyzer-debug-global-symbol ;; You will need to update both places. (setq prefix (semantic-analyze-find-tag-sequence - prefix scope 'prefixtypes)) + prefix scope 'semantic--prefixtypes)) (error (semantic-analyze-push-error err)))) ;;(message "Analysis took %.2f sec" (semantic-elapsed-time LLstart nil)) @@ -531,7 +533,7 @@ Returns an object based on symbol `semantic-analyze-context'." (bounds (nth 2 prefixandbounds)) ;; @todo - vv too early to really know this answer! vv (prefixclass (semantic-ctxt-current-class-list)) - (prefixtypes nil) + (semantic--prefixtypes nil) (scope (semantic-calculate-scope position)) (function nil) (fntag nil) @@ -611,13 +613,13 @@ Returns an object based on symbol `semantic-analyze-context'." (if debug-on-error (catch 'unfindable (setq prefix (semantic-analyze-find-tag-sequence - prefix scope 'prefixtypes 'unfindable)) + prefix scope 'semantic--prefixtypes 'unfindable)) ;; If there's an alias, dereference it and analyze ;; sequence again. (when (setq newseq (semantic-analyze-dereference-alias prefix)) (setq prefix (semantic-analyze-find-tag-sequence - newseq scope 'prefixtypes 'unfindable)))) + newseq scope 'semantic--prefixtypes 'unfindable)))) ;; Debug on error is off. Capture errors and move on (condition-case err ;; NOTE: This line is duplicated in @@ -625,11 +627,11 @@ Returns an object based on symbol `semantic-analyze-context'." ;; You will need to update both places. (progn (setq prefix (semantic-analyze-find-tag-sequence - prefix scope 'prefixtypes)) + prefix scope 'semantic--prefixtypes)) (when (setq newseq (semantic-analyze-dereference-alias prefix)) (setq prefix (semantic-analyze-find-tag-sequence - newseq scope 'prefixtypes)))) + newseq scope 'semantic--prefixtypes)))) (error (semantic-analyze-push-error err)))) ) @@ -650,7 +652,7 @@ Returns an object based on symbol `semantic-analyze-context'." :prefix prefix :prefixclass prefixclass :bounds bounds - :prefixtypes prefixtypes + :prefixtypes semantic--prefixtypes :errors semantic-analyze-error-stack))) ;; No function, try assignment @@ -670,7 +672,7 @@ Returns an object based on symbol `semantic-analyze-context'." :bounds bounds :prefix prefix :prefixclass prefixclass - :prefixtypes prefixtypes + :prefixtypes semantic--prefixtypes :errors semantic-analyze-error-stack))) ;; TODO: Identify return value condition. @@ -686,7 +688,7 @@ Returns an object based on symbol `semantic-analyze-context'." :bounds bounds :prefix prefix :prefixclass prefixclass - :prefixtypes prefixtypes + :prefixtypes semantic--prefixtypes :errors semantic-analyze-error-stack))) (t (setq context-return nil)) @@ -750,7 +752,7 @@ Some useful functions are found in `semantic-format-tag-functions'." :group 'semantic :type semantic-format-tag-custom-list) -(defun semantic-analyze-princ-sequence (sequence &optional prefix buff) +(defun semantic-analyze-princ-sequence (sequence &optional prefix _buff) "Send the tag SEQUENCE to standard out. Use PREFIX as a label. Use BUFF as a source of override methods." diff --git a/lisp/cedet/semantic/analyze/complete.el b/lisp/cedet/semantic/analyze/complete.el index e8139ab1ae..ccf405d62e 100644 --- a/lisp/cedet/semantic/analyze/complete.el +++ b/lisp/cedet/semantic/analyze/complete.el @@ -1,4 +1,4 @@ -;;; semantic/analyze/complete.el --- Smart Completions +;;; semantic/analyze/complete.el --- Smart Completions -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. @@ -45,7 +45,7 @@ "For the tag TYPE, return any constant symbols of TYPE. Used as options when completing.") -(defun semantic-analyze-type-constants-default (type) +(defun semantic-analyze-type-constants-default (_type) "Do nothing with TYPE." nil) @@ -54,7 +54,7 @@ Used as options when completing.") (let ((origc tags)) ;; Accept only tags that are of the datatype specified by ;; the desired classes. - (setq tags (apply 'nconc ;; All input lists are permutable. + (setq tags (apply #'nconc ;; All input lists are permutable. (mapcar (lambda (class) (semantic-find-tags-by-class class origc)) classlist))) @@ -109,6 +109,8 @@ in a buffer." (when (called-interactively-p 'any) (error "Buffer was not parsed by Semantic.")))) +(defvar semantic--prefixtypes) + (defun semantic-analyze-possible-completions-default (context &optional flags) "Default method for producing smart completions. Argument CONTEXT is an object specifying the locally derived context. @@ -121,14 +123,14 @@ FLAGS can be any number of: (desired-type (semantic-analyze-type-constraint a)) (desired-class (oref a prefixclass)) (prefix (oref a prefix)) - (prefixtypes (oref a prefixtypes)) + (semantic--prefixtypes (oref a prefixtypes)) (completetext nil) (completetexttype nil) (scope (oref a scope)) (localvar (when scope (oref scope localvar))) (origc nil) (c nil) - (any nil) + ;; (any nil) (do-typeconstraint (not (memq 'no-tc flags))) (do-longprefix (not (memq 'no-longprefix flags))) (do-unique (not (memq 'no-unique flags))) @@ -138,7 +140,7 @@ FLAGS can be any number of: ;; If we are not doing the long prefix, shorten all the key ;; elements. (setq prefix (list (car (reverse prefix))) - prefixtypes nil)) + semantic--prefixtypes nil)) ;; Calculate what our prefix string is so that we can ;; find all our matching text. @@ -155,7 +157,7 @@ FLAGS can be any number of: ;; The prefixtypes should always be at least 1 less than ;; the prefix since the type is never looked up for the last ;; item when calculating a sequence. - (setq completetexttype (car (reverse prefixtypes))) + (setq completetexttype (car (reverse semantic--prefixtypes))) (when (or (not completetexttype) (not (and (semantic-tag-p completetexttype) (eq (semantic-tag-class completetexttype) 'type)))) diff --git a/lisp/cedet/semantic/analyze/debug.el b/lisp/cedet/semantic/analyze/debug.el index 4947368757..58d6644f9a 100644 --- a/lisp/cedet/semantic/analyze/debug.el +++ b/lisp/cedet/semantic/analyze/debug.el @@ -1,4 +1,4 @@ -;;; semantic/analyze/debug.el --- Debug the analyzer +;;; semantic/analyze/debug.el --- Debug the analyzer -*- lexical-binding: t; -*- ;;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -109,11 +109,11 @@ Argument COMP are possible completions here." (condition-case err (with-current-buffer origbuf (let* ((position (or (cdr-safe (oref ctxt bounds)) (point))) - (prefixtypes nil) ; Used as type return + ;; (semantic--prefixtypes nil) ; Used as type return (scope (semantic-calculate-scope position)) ) (semantic-analyze-find-tag-sequence - (list prefix "") scope 'prefixtypes) + (list prefix "") scope) ;; 'semantic--prefixtypes ) ) (error (setq finderr err))) @@ -149,7 +149,7 @@ path was setup incorrectly.\n") (semantic-analyzer-debug-add-buttons) )) -(defun semantic-analyzer-debug-missing-datatype (ctxt idx comp) +(defun semantic-analyzer-debug-missing-datatype (ctxt idx _comp) "Debug why we can't find a datatype entry for CTXT prefix at IDX. Argument COMP are possible completions here." (let* ((prefixitem (nth idx (oref ctxt prefix))) diff --git a/lisp/cedet/semantic/analyze/fcn.el b/lisp/cedet/semantic/analyze/fcn.el index 10d11c33eb..d47e8976e5 100644 --- a/lisp/cedet/semantic/analyze/fcn.el +++ b/lisp/cedet/semantic/analyze/fcn.el @@ -1,4 +1,4 @@ -;;; semantic/analyze/fcn.el --- Analyzer support functions. +;;; semantic/analyze/fcn.el --- Analyzer support functions. -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. @@ -55,7 +55,7 @@ Return the string representing the compound name.") (defun semantic-analyze-unsplit-name-default (namelist) "Concatenate the names in NAMELIST with a . between." - (mapconcat 'identity namelist ".")) + (mapconcat #'identity namelist ".")) ;;; SELECTING ;; diff --git a/lisp/cedet/semantic/analyze/refs.el b/lisp/cedet/semantic/analyze/refs.el index a39ff6f673..31cbb9e117 100644 --- a/lisp/cedet/semantic/analyze/refs.el +++ b/lisp/cedet/semantic/analyze/refs.el @@ -1,4 +1,4 @@ -;;; semantic/analyze/refs.el --- Analysis of the references between tags. +;;; semantic/analyze/refs.el --- Analysis of the references between tags. -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -296,7 +296,7 @@ Only works for tags in the global namespace." (let* ((classmatch (semantic-tag-class tag)) (RES (semanticdb-find-tags-collector - (lambda (table tags) + (lambda (_table tags) (semantic-find-tags-by-class classmatch tags) ;; @todo - Add parent check also. ) commit 496fa1c03b1b3ce4aa9872751e9fac45167766c2 Author: Michael Albinus Date: Fri Feb 26 18:37:14 2021 +0100 Fix Tramp manual * doc/misc/tramp.texi (External methods): Mention "about-args". (Remote shell setup): Use sshx. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 609d08c336..4636e73671 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -1182,7 +1182,7 @@ of the configured system storage. Optional flags to the different @option{rclone} operations could be passed as connection property, @xref{Predefined connection information}. Supported properties are @t{"mount-args"}, -@t{"copyto-args"} and @t{"moveto-args"}. +@t{"copyto-args"}, @t{"moveto-args"} and @t{"about-args"}. Access via @option{rclone} is slow. If you have an alternative method for accessing the system storage, you should use it. @@ -2218,7 +2218,7 @@ connection information}. If you want, for example, use @lisp @group (add-to-list 'tramp-connection-properties - (list (regexp-quote "@trampfn{ssh,user@@host,}") + (list (regexp-quote "@trampfn{sshx,user@@host,}") "remote-shell" "/usr/bin/zsh")) @end group @end lisp commit a2c740f185821a5307fe5de447bc64e823d7a836 Author: Stefan Kangas Date: Fri Feb 26 17:09:57 2021 +0100 ; * test/lisp/progmodes/f90-tests.el: Remove stale comment. diff --git a/test/lisp/progmodes/f90-tests.el b/test/lisp/progmodes/f90-tests.el index b3d12229d8..330eab38c4 100644 --- a/test/lisp/progmodes/f90-tests.el +++ b/test/lisp/progmodes/f90-tests.el @@ -22,9 +22,6 @@ ;;; Commentary: -;; This file does not have "test" in the name, because it lives under -;; a test/ directory, so that would be superfluous. - ;;; Code: (require 'ert) commit e95b3e4d1d7372beb576b2a12f80d331742e4f7d Author: Stefan Kangas Date: Fri Feb 26 17:05:18 2021 +0100 * lisp/progmodes/dcl-mode.el: Minor doc fixes. diff --git a/lisp/progmodes/dcl-mode.el b/lisp/progmodes/dcl-mode.el index 6ffceb444c..14eefdca1e 100644 --- a/lisp/progmodes/dcl-mode.el +++ b/lisp/progmodes/dcl-mode.el @@ -93,10 +93,10 @@ Presently this includes some syntax, .OP.erators, and \"f$\" lexicals.") (defcustom dcl-basic-offset 4 "Number of columns to indent a block in DCL. A block is the commands between THEN-ELSE-ENDIF and between the commands -dcl-block-begin-regexp and dcl-block-end-regexp. +`dcl-block-begin-regexp' and `dcl-block-end-regexp'. The meaning of this variable may be changed if -dcl-calc-command-indent-function is set to a function." +`dcl-calc-command-indent-function' is set to a function." :type 'integer) @@ -105,7 +105,7 @@ dcl-calc-command-indent-function is set to a function." A continuation line is a line that follows a line ending with `-'. The meaning of this variable may be changed if -dcl-calc-cont-indent-function is set to a function." +`dcl-calc-cont-indent-function' is set to a function." :type 'integer) @@ -121,7 +121,7 @@ A command line is a line that starts with `$'." (defcustom dcl-margin-label-offset 2 "Number of columns to indent a margin label in DCL. A margin label is a label that doesn't begin or end a block, i.e. it -doesn't match dcl-block-begin-regexp or dcl-block-end-regexp." +doesn't match `dcl-block-begin-regexp' or `dcl-block-end-regexp'." :type 'integer) @@ -169,8 +169,8 @@ If this variable is nil, the indentation is calculated as CUR-INDENT + EXTRA-INDENT. This package includes two functions suitable for this: - dcl-calc-command-indent-multiple - dcl-calc-command-indent-hang" + `dcl-calc-command-indent-multiple' + `dcl-calc-command-indent-hang'" :type '(choice (const nil) function)) @@ -187,7 +187,7 @@ If this variable is nil, the indentation is calculated as CUR-INDENT + EXTRA-INDENT. This package includes one function suitable for this: - dcl-calc-cont-indent-relative" + `dcl-calc-cont-indent-relative'" :type 'function) @@ -349,10 +349,10 @@ optionally followed by a comment, followed by a newline." (list "endif" "else" dcl-label-r) "Regexps that can trigger an electric reindent. A list of regexps that will trigger a reindent if the last letter -is defined as dcl-electric-character. +is defined as `dcl-electric-character'. E.g.: if this list contains `endif', the key `f' is defined as -dcl-electric-character and you have just typed the `f' in +`dcl-electric-character' and you have just typed the `f' in `endif', the line will be reindented." :type '(repeat regexp)) @@ -376,7 +376,7 @@ dcl-electric-character and you have just typed the `f' in (comment-start curval) (comment-start-skip curval) ) - "Options and default values for dcl-set-option. + "Options and default values for `dcl-set-option'. An alist with option variables and functions or keywords to get a default value for the option. @@ -390,8 +390,8 @@ toggle the opposite of the current value (for t/nil)") (mapcar (lambda (option-assoc) (format "%s" (car option-assoc))) dcl-option-alist) - "The history list for dcl-set-option. -Preloaded with all known option names from dcl-option-alist") + "The history list for `dcl-set-option'. +Preloaded with all known option names from `dcl-option-alist'") ;; Must be defined after dcl-cmd-r @@ -855,7 +855,7 @@ Returns one of the following symbols: ;;;--------------------------------------------------------------------------- (defun dcl-show-line-type () - "Test dcl-get-line-type." + "Test `dcl-get-line-type'." (interactive) (let ((type (dcl-get-line-type))) (cond @@ -900,8 +900,7 @@ $ if cond $ then $ if cond $ then -$ ! etc -" +$ ! etc" ;; calculate indentation if it's an interesting indent-type, ;; otherwise return nil to get the default indentation (let ((indent)) @@ -930,8 +929,7 @@ $ xxx If you use this function you will probably want to add \"then\" to dcl-electric-reindent-regexps and define the key \"n\" as -dcl-electric-character. -" +dcl-electric-character." (let ((case-fold-search t)) (save-excursion (cond @@ -974,17 +972,17 @@ see if the current lines should be indented. Analyze the current line to see if it should be `outdented'. Calculate the indentation of the current line, either with the default -method or by calling dcl-calc-command-indent-function if it is +method or by calling `dcl-calc-command-indent-function' if it is non-nil. If the current line should be outdented, calculate its indentation, either with the default method or by calling -dcl-calc-command-indent-function if it is non-nil. +`dcl-calc-command-indent-function' if it is non-nil. Rules for default indentation: -If it is the first line in the buffer, indent dcl-margin-offset. +If it is the first line in the buffer, indent `dcl-margin-offset'. Go to the previous command line with a command on it. Find out how much it is indented (cur-indent). @@ -992,7 +990,7 @@ Look at the first word on the line to see if the indentation should be adjusted. Skip margin-label, continuations and comments while looking for the first word. Save this buffer position as `last-point'. If the first word after a label is SUBROUTINE, set extra-indent to -dcl-margin-offset. +`dcl-margin-offset'. First word extra-indent THEN +dcl-basic-offset @@ -1149,8 +1147,7 @@ Indented lines will align with either: * the innermost nonclosed parenthesis $ if ((a.eq.b .and. - d.eq.c .or. f$function(xxxx, - - yyy))) -" + yyy)))" (let ((case-fold-search t) indent) (save-excursion @@ -1330,7 +1327,7 @@ Adjusts indentation on the current line. Data lines are not indented." ;;;------------------------------------------------------------------------- (defun dcl-indent-command () - "Indents the complete command line that point is on. + "Indent the complete command line that point is on. This includes continuation lines." (interactive "*") (let ((type (dcl-get-line-type))) @@ -1377,7 +1374,7 @@ the lines indentation; otherwise insert a tab." ;;;------------------------------------------------------------------------- (defun dcl-electric-character (arg) - "Inserts a character and indents if necessary. + "Insert a character and indent if necessary. Insert a character if the user gave a numeric argument or the flag `dcl-electric-characters' is not set. If an argument was given, insert that many characters. @@ -1791,8 +1788,8 @@ Set or update the value of VAR in the current buffers ;;;------------------------------------------------------------------------- (defun dcl-save-all-options () - "Save all dcl-mode options for this buffer. -Saves or updates all dcl-mode related options in a `Local Variables:' + "Save all `dcl-mode' options for this buffer. +Saves or updates all `dcl-mode' related options in a `Local Variables:' section at the end of the current buffer." (interactive "*") (mapcar (lambda (option-assoc) commit ffdb0a2d8e64980d63b7c1c6c71ac6e2d26b4fb2 Author: Stefan Kangas Date: Fri Feb 26 16:23:45 2021 +0100 Convert some more progmode menus to easy-menu-define * lisp/progmodes/dcl-mode.el (dcl-mode-map): * lisp/progmodes/icon.el (icon-mode-map): * lisp/progmodes/scheme.el (scheme-mode-map): Move menu definitions from here... * lisp/progmodes/dcl-mode.el (dcl-mode-menu): * lisp/progmodes/icon.el (icon-mode-menu) * lisp/progmodes/scheme.el (scheme-mode-menu): ...to here, and use easy-menu-define. * lisp/progmodes/icon.el (icon-mode-map, icon-mode-syntax-table): Simplify. diff --git a/lisp/progmodes/dcl-mode.el b/lisp/progmodes/dcl-mode.el index 4a8a20a296..6ffceb444c 100644 --- a/lisp/progmodes/dcl-mode.el +++ b/lisp/progmodes/dcl-mode.el @@ -286,49 +286,30 @@ See `imenu-generic-expression' for details." (define-key map "\C-c\C-o" 'dcl-set-option) (define-key map "\C-c\C-f" 'tempo-forward-mark) (define-key map "\C-c\C-b" 'tempo-backward-mark) - - (define-key map [menu-bar] (make-sparse-keymap)) - (define-key map [menu-bar dcl] - (cons "DCL" (make-sparse-keymap "DCL"))) - - ;; Define these in bottom-up order - (define-key map [menu-bar dcl tempo-backward-mark] - '("Previous template mark" . tempo-backward-mark)) - (define-key map [menu-bar dcl tempo-forward-mark] - '("Next template mark" . tempo-forward-mark)) - (define-key map [menu-bar dcl tempo-complete-tag] - '("Complete template tag" . tempo-complete-tag)) - (define-key map [menu-bar dcl dcl-separator-tempo] - '("--")) - (define-key map [menu-bar dcl dcl-save-all-options] - '("Save all options" . dcl-save-all-options)) - (define-key map [menu-bar dcl dcl-save-nondefault-options] - '("Save changed options" . dcl-save-nondefault-options)) - (define-key map [menu-bar dcl dcl-set-option] - '("Set option" . dcl-set-option)) - (define-key map [menu-bar dcl dcl-separator-option] - '("--")) - (define-key map [menu-bar dcl dcl-delete-indentation] - '("Delete indentation" . dcl-delete-indentation)) - (define-key map [menu-bar dcl dcl-split-line] - '("Split line" . dcl-split-line)) - (define-key map [menu-bar dcl dcl-indent-command] - '("Indent command" . dcl-indent-command)) - (define-key map [menu-bar dcl dcl-tab] - '("Indent line/insert tab" . dcl-tab)) - (define-key map [menu-bar dcl dcl-back-to-indentation] - '("Back to indentation" . dcl-back-to-indentation)) - (define-key map [menu-bar dcl dcl-forward-command] - '("End of statement" . dcl-forward-command)) - (define-key map [menu-bar dcl dcl-backward-command] - '("Beginning of statement" . dcl-backward-command)) - (define-key map [menu-bar dcl dcl-separator-movement] - '("--")) - (define-key map [menu-bar dcl imenu] - '("Buffer index menu" . imenu)) map) "Keymap used in DCL-mode buffers.") +(easy-menu-define dcl-mode-menu dcl-mode-map + "Menu for DCL-mode buffers." + '("DCL" + ["Buffer index menu" imenu] + "---" + ["Beginning of statement" dcl-backward-command] + ["End of statement" dcl-forward-command] + ["Back to indentation" dcl-back-to-indentation] + ["Indent line/insert tab" dcl-tab] + ["Indent command" dcl-indent-command] + ["Split line" dcl-split-line] + ["Delete indentation" dcl-delete-indentation] + "---" + ["Set option" dcl-set-option] + ["Save changed options" dcl-save-nondefault-options] + ["Save all options" dcl-save-all-options] + "---" + ["Complete template tag" tempo-complete-tag] + ["Next template mark" tempo-forward-mark] + ["Previous template mark" tempo-backward-mark])) + (defcustom dcl-ws-r "\\([ \t]*-[ \t]*\\(!.*\\)*\n\\)*[ \t]*" "Regular expression describing white space in a DCL command line. diff --git a/lisp/progmodes/icon.el b/lisp/progmodes/icon.el index a36f020439..d81fe1c753 100644 --- a/lisp/progmodes/icon.el +++ b/lisp/progmodes/icon.el @@ -31,53 +31,48 @@ "Abbrev table in use in Icon-mode buffers.") (define-abbrev-table 'icon-mode-abbrev-table ()) -(defvar icon-mode-map () - "Keymap used in Icon mode.") -(if icon-mode-map - () +(defvar icon-mode-map (let ((map (make-sparse-keymap "Icon"))) - (setq icon-mode-map (make-sparse-keymap)) - (define-key icon-mode-map "{" 'electric-icon-brace) - (define-key icon-mode-map "}" 'electric-icon-brace) - (define-key icon-mode-map "\e\C-h" 'mark-icon-function) - (define-key icon-mode-map "\e\C-a" 'beginning-of-icon-defun) - (define-key icon-mode-map "\e\C-e" 'end-of-icon-defun) - (define-key icon-mode-map "\e\C-q" 'indent-icon-exp) - (define-key icon-mode-map "\177" 'backward-delete-char-untabify) - - (define-key icon-mode-map [menu-bar] (make-sparse-keymap "Icon")) - (define-key icon-mode-map [menu-bar icon] - (cons "Icon" map)) - (define-key map [beginning-of-icon-defun] '("Beginning of function" . beginning-of-icon-defun)) - (define-key map [end-of-icon-defun] '("End of function" . end-of-icon-defun)) - (define-key map [comment-region] '("Comment Out Region" . comment-region)) - (define-key map [indent-region] '("Indent Region" . indent-region)) - (define-key map [indent-line] '("Indent Line" . icon-indent-command)) - (put 'eval-region 'menu-enable 'mark-active) - (put 'comment-region 'menu-enable 'mark-active) - (put 'indent-region 'menu-enable 'mark-active))) - -(defvar icon-mode-syntax-table nil - "Syntax table in use in Icon-mode buffers.") + (define-key map "{" 'electric-icon-brace) + (define-key map "}" 'electric-icon-brace) + (define-key map "\e\C-h" 'mark-icon-function) + (define-key map "\e\C-a" 'beginning-of-icon-defun) + (define-key map "\e\C-e" 'end-of-icon-defun) + (define-key map "\e\C-q" 'indent-icon-exp) + (define-key map "\177" 'backward-delete-char-untabify) + map) + "Keymap used in Icon mode.") -(if icon-mode-syntax-table - () - (setq icon-mode-syntax-table (make-syntax-table)) - (modify-syntax-entry ?\\ "\\" icon-mode-syntax-table) - (modify-syntax-entry ?# "<" icon-mode-syntax-table) - (modify-syntax-entry ?\n ">" icon-mode-syntax-table) - (modify-syntax-entry ?$ "." icon-mode-syntax-table) - (modify-syntax-entry ?/ "." icon-mode-syntax-table) - (modify-syntax-entry ?* "." icon-mode-syntax-table) - (modify-syntax-entry ?+ "." icon-mode-syntax-table) - (modify-syntax-entry ?- "." icon-mode-syntax-table) - (modify-syntax-entry ?= "." icon-mode-syntax-table) - (modify-syntax-entry ?% "." icon-mode-syntax-table) - (modify-syntax-entry ?< "." icon-mode-syntax-table) - (modify-syntax-entry ?> "." icon-mode-syntax-table) - (modify-syntax-entry ?& "." icon-mode-syntax-table) - (modify-syntax-entry ?| "." icon-mode-syntax-table) - (modify-syntax-entry ?\' "\"" icon-mode-syntax-table)) +(easy-menu-define icon-mode-menu icon-mode-map + "Menu for Icon mode." + '("Icon" + ["Beginning of function" beginning-of-icon-defun] + ["Comment Out Region" comment-region + :enable mark-active] + ["End of function" end-of-icon-defun] + ["Indent Line" icon-indent-command] + ["Indent Region" indent-region + :enable mark-active])) + +(defvar icon-mode-syntax-table + (let ((table (make-syntax-table))) + (modify-syntax-entry ?\\ "\\" table) + (modify-syntax-entry ?# "<" table) + (modify-syntax-entry ?\n ">" table) + (modify-syntax-entry ?$ "." table) + (modify-syntax-entry ?/ "." table) + (modify-syntax-entry ?* "." table) + (modify-syntax-entry ?+ "." table) + (modify-syntax-entry ?- "." table) + (modify-syntax-entry ?= "." table) + (modify-syntax-entry ?% "." table) + (modify-syntax-entry ?< "." table) + (modify-syntax-entry ?> "." table) + (modify-syntax-entry ?& "." table) + (modify-syntax-entry ?| "." table) + (modify-syntax-entry ?\' "\"" table) + table) + "Syntax table in use in Icon-mode buffers.") (defgroup icon nil "Mode for editing Icon code." diff --git a/lisp/progmodes/scheme.el b/lisp/progmodes/scheme.el index a899de7e59..72ac2d95a2 100644 --- a/lisp/progmodes/scheme.el +++ b/lisp/progmodes/scheme.el @@ -162,25 +162,26 @@ (defvar scheme-mode-line-process "") (defvar scheme-mode-map - (let ((smap (make-sparse-keymap)) - (map (make-sparse-keymap "Scheme"))) - (set-keymap-parent smap lisp-mode-shared-map) - (define-key smap [menu-bar scheme] (cons "Scheme" map)) - (define-key map [run-scheme] '("Run Inferior Scheme" . run-scheme)) - (define-key map [uncomment-region] - '("Uncomment Out Region" . (lambda (beg end) - (interactive "r") - (comment-region beg end '(4))))) - (define-key map [comment-region] '("Comment Out Region" . comment-region)) - (define-key map [indent-region] '("Indent Region" . indent-region)) - (define-key map [indent-line] '("Indent Line" . lisp-indent-line)) - (put 'comment-region 'menu-enable 'mark-active) - (put 'uncomment-region 'menu-enable 'mark-active) - (put 'indent-region 'menu-enable 'mark-active) - smap) + (let ((map (make-sparse-keymap))) + (set-keymap-parent map lisp-mode-shared-map) + map) "Keymap for Scheme mode. All commands in `lisp-mode-shared-map' are inherited by this map.") +(easy-menu-define scheme-mode-menu scheme-mode-map + "Menu for Scheme mode." + '("Scheme" + ["Indent Line" lisp-indent-line] + ["Indent Region" indent-region + :enable mark-active] + ["Comment Out Region" comment-region + :enable mark-active] + ["Uncomment Out Region" (lambda (beg end) + (interactive "r") + (comment-region beg end '(4))) + :enable mark-active] + ["Run Inferior Scheme" run-scheme])) + ;; Used by cmuscheme (defun scheme-mode-commands (map) ;;(define-key map "\t" 'indent-for-tab-command) ; default commit 47f2a39f427f2e7bfd3de371316e3a2c47841340 Author: Stefan Kangas Date: Fri Feb 26 16:09:14 2021 +0100 Convert simula-mode menu to easy-menu-define * lisp/progmodes/simula.el (simula-mode-map): Move menu definition from here... (simula-mode-menu): ...to here, and use easy-menu-define. (simula-popup-menu): Declare unused function obsolete. diff --git a/lisp/progmodes/simula.el b/lisp/progmodes/simula.el index fab600f83f..ef157ce4ab 100644 --- a/lisp/progmodes/simula.el +++ b/lisp/progmodes/simula.el @@ -270,48 +270,25 @@ for SIMULA mode to function correctly." (define-key map ":" 'simula-electric-label) (define-key map "\e\C-q" 'simula-indent-exp) (define-key map "\t" 'simula-indent-command) - - (define-key map [menu-bar simula] - (cons "SIMULA" (make-sparse-keymap "SIMULA"))) - (define-key map [menu-bar simula indent-exp] - '("Indent Expression" . simula-indent-exp)) - (define-key map [menu-bar simula indent-line] - '("Indent Line" . simula-indent-command)) - (define-key map [menu-bar simula separator-navigate] - '("--")) - (define-key map [menu-bar simula backward-stmt] - '("Previous Statement" . simula-previous-statement)) - (define-key map [menu-bar simula forward-stmt] - '("Next Statement" . simula-next-statement)) - (define-key map [menu-bar simula backward-up] - '("Backward Up Level" . simula-backward-up-level)) - (define-key map [menu-bar simula forward-down] - '("Forward Down Statement" . simula-forward-down-level)) - - (put 'simula-next-statement 'menu-enable '(not (eobp))) - (put 'simula-previous-statement 'menu-enable '(not (bobp))) - (put 'simula-forward-down-level 'menu-enable '(not (eobp))) - (put 'simula-backward-up-level 'menu-enable '(not (bobp))) - (put 'simula-indent-command 'menu-enable '(not buffer-read-only)) - (put 'simula-indent-exp 'menu-enable '(not buffer-read-only)) - - ;; RMS: mouse-3 should not select this menu. mouse-3's global - ;; definition is useful in SIMULA mode and we should not interfere - ;; with that. The menu is mainly for beginners, and for them, - ;; the menubar requires less memory than a special click. - ;; in Lucid Emacs, we want the menu to popup when the 3rd button is - ;; hit. In 19.10 and beyond this is done automatically if we put - ;; the menu on mode-popup-menu variable, see c-common-init [cc-mode.el] - ;;(if (not (boundp 'mode-popup-menu)) - ;; (define-key simula-mode-map 'button3 'simula-popup-menu)) map) "Keymap used in `simula-mode'.") -;; menus for Lucid -(defun simula-popup-menu (_e) - "Pops up the SIMULA menu." - (interactive "@e") - (popup-menu (cons (concat mode-name " Mode Commands") simula-mode-menu))) +(easy-menu-define simula-mode-menu simula-mode-map + "Menu for `simula-mode'." + '("SIMULA" + ["Forward Down Statement" simula-forward-down-level + :enable (not (eobp))] + ["Backward Up Level" simula-backward-up-level + :enable (not (bobp))] + ["Next Statement" simula-next-statement + :enable (not (eobp))] + ["Previous Statement" simula-previous-statement + :enable (not (bobp))] + "---" + ["Indent Line" simula-indent-command + :enable (not buffer-read-only)] + ["Indent Expression" simula-indent-exp + :enable (not buffer-read-only)])) ;;;###autoload (define-derived-mode simula-mode prog-mode "Simula" @@ -1600,7 +1577,7 @@ If not nil and not t, move to limit of search and return nil." ("!\\|\\" ";" comment)) nil 'case-insensitive))) -;; defuns for submitting bug reports +;; obsolete (defconst simula-mode-help-address "bug-gnu-emacs@gnu.org" "Address accepting submission of `simula-mode' bug reports.") @@ -1611,6 +1588,12 @@ If not nil and not t, move to limit of search and return nil." (define-obsolete-function-alias 'simula-submit-bug-report 'report-emacs-bug "24.4") +(defun simula-popup-menu (_e) + "Pops up the SIMULA menu." + (declare (obsolete simula-mode-menu "28.1")) + (interactive "@e") + (popup-menu (cons (concat mode-name " Mode Commands") simula-mode-menu))) + (provide 'simula) ;;; simula.el ends here commit 1205301e0959bd2ae5b18361818d38985af3e6a1 Author: Stefan Kangas Date: Fri Feb 26 15:59:56 2021 +0100 Fix syntax highlighting of easy-menu-define docstrings * lisp/emacs-lisp/easymenu.el (easy-menu-define): Add doc-string declaration for correct syntax highlighting. diff --git a/lisp/emacs-lisp/easymenu.el b/lisp/emacs-lisp/easymenu.el index b49d886ede..8ddfb9e78e 100644 --- a/lisp/emacs-lisp/easymenu.el +++ b/lisp/emacs-lisp/easymenu.el @@ -143,7 +143,7 @@ solely of dashes is displayed as a menu separator. Alternatively, a menu item can be a list with the same format as MENU. This is a submenu." - (declare (indent defun) (debug (symbolp body))) + (declare (indent defun) (debug (symbolp body)) (doc-string 3)) `(progn ,(if symbol `(defvar ,symbol nil ,doc)) (easy-menu-do-define (quote ,symbol) ,maps ,doc ,menu))) commit 54af0d4298fbd60692a7b5339b5b909242909bf4 Author: Stefan Kangas Date: Fri Feb 26 15:50:41 2021 +0100 Remove redundant requires of easymenu * lisp/allout.el: * lisp/emacs-lisp/edebug.el: * lisp/emacs-lisp/ert.el: * lisp/erc/erc-menu.el: * lisp/help-mode.el: * lisp/net/dictionary.el: * lisp/nxml/rng-nxml.el: * lisp/progmodes/ebrowse.el: * lisp/progmodes/meta-mode.el: * lisp/progmodes/prolog.el: * lisp/progmodes/ps-mode.el: * lisp/progmodes/vera-mode.el: * lisp/wid-browse.el: Remove redundant require of easymenu. We only use the autoloaded macro 'easy-menu-define' here. diff --git a/lisp/allout.el b/lisp/allout.el index ff0b67556e..7fcf41c430 100644 --- a/lisp/allout.el +++ b/lisp/allout.el @@ -1206,7 +1206,6 @@ Also refresh various data structures that hinge on the regexp." (defvar allout-mode-navigation-menu) (defvar allout-mode-misc-menu) (defun allout-produce-mode-menubar-entries () - (require 'easymenu) (easy-menu-define allout-mode-exposure-menu allout-mode-map-value "Allout outline exposure menu." diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 45e76c751f..6f3c7d6688 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -4369,10 +4369,6 @@ It is removed when you hit any char." (set variable (not (symbol-value variable))) (message "%s: %s" variable (symbol-value variable))) -;; We have to require easymenu (even for Emacs 18) just so -;; the easy-menu-define macro call is compiled correctly. -(require 'easymenu) - (defconst edebug-mode-menus '("Edebug" ["Stop" edebug-stop t] diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index 96c1a02dbc..a5c877e53a 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -60,7 +60,6 @@ (require 'cl-lib) (require 'debug) (require 'backtrace) -(require 'easymenu) (require 'ewoc) (require 'find-func) (require 'pp) diff --git a/lisp/erc/erc-menu.el b/lisp/erc/erc-menu.el index 3995a0564a..0e334e93bd 100644 --- a/lisp/erc/erc-menu.el +++ b/lisp/erc/erc-menu.el @@ -28,7 +28,6 @@ ;;; Code: (require 'erc) -(require 'easymenu) (defgroup erc-menu nil "ERC menu support." diff --git a/lisp/help-mode.el b/lisp/help-mode.el index 6fd3d40fe3..e6a5fe8a80 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -30,7 +30,6 @@ ;;; Code: (require 'cl-lib) -(eval-when-compile (require 'easymenu)) (defvar help-mode-map (let ((map (make-sparse-keymap))) diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el index c6af4e66e3..aba3698a53 100644 --- a/lisp/net/dictionary.el +++ b/lisp/net/dictionary.el @@ -35,7 +35,6 @@ ;;; Code: (require 'cl-lib) -(require 'easymenu) (require 'custom) (require 'dictionary-connection) (require 'button) diff --git a/lisp/nxml/rng-nxml.el b/lisp/nxml/rng-nxml.el index 7d74fd3c8a..7ea6fb2e49 100644 --- a/lisp/nxml/rng-nxml.el +++ b/lisp/nxml/rng-nxml.el @@ -24,7 +24,6 @@ ;;; Code: -(require 'easymenu) (require 'xmltok) (require 'nxml-util) (require 'nxml-ns) diff --git a/lisp/progmodes/ebrowse.el b/lisp/progmodes/ebrowse.el index a174d4851e..40bdaad574 100644 --- a/lisp/progmodes/ebrowse.el +++ b/lisp/progmodes/ebrowse.el @@ -35,7 +35,6 @@ (require 'cl-lib) (require 'seq) -(require 'easymenu) (require 'view) (require 'ebuff-menu) diff --git a/lisp/progmodes/meta-mode.el b/lisp/progmodes/meta-mode.el index 46b0949c13..a59014827e 100644 --- a/lisp/progmodes/meta-mode.el +++ b/lisp/progmodes/meta-mode.el @@ -88,8 +88,6 @@ ;;; Code: -(require 'easymenu) - (defgroup meta-font nil "Major mode for editing Metafont or MetaPost sources." :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el index 9f5f9ed6d3..29cce51e22 100644 --- a/lisp/progmodes/prolog.el +++ b/lisp/progmodes/prolog.el @@ -267,7 +267,6 @@ (require 'shell) ) -(require 'easymenu) (require 'align) (defgroup prolog nil diff --git a/lisp/progmodes/ps-mode.el b/lisp/progmodes/ps-mode.el index 15fd2e8439..598f748f5b 100644 --- a/lisp/progmodes/ps-mode.el +++ b/lisp/progmodes/ps-mode.el @@ -39,7 +39,6 @@ "Peter Kleiweg , bug-gnu-emacs@gnu.org") (require 'comint) -(require 'easymenu) (require 'smie) ;; Define core `PostScript' group. diff --git a/lisp/progmodes/vera-mode.el b/lisp/progmodes/vera-mode.el index c2e1719d54..036b2f447b 100644 --- a/lisp/progmodes/vera-mode.el +++ b/lisp/progmodes/vera-mode.el @@ -119,8 +119,6 @@ If nil, TAB always indents current line." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Menu -(require 'easymenu) - (easy-menu-define vera-mode-menu vera-mode-map "Menu keymap for Vera Mode." '("Vera" diff --git a/lisp/wid-browse.el b/lisp/wid-browse.el index 124cb04486..39b3221762 100644 --- a/lisp/wid-browse.el +++ b/lisp/wid-browse.el @@ -27,7 +27,6 @@ ;;; Code: -(require 'easymenu) (require 'wid-edit) (defgroup widget-browse nil commit f83775b4d34f48b44481bc1f4f9e78a83556c2f1 Author: Stefan Kangas Date: Fri Feb 26 05:43:53 2021 +0100 Remove check for missing easymenu from cperl-mode.el * lisp/progmodes/cperl-mode.el (cperl-menu): Don't wrap definition in condition-case; easymenu always exists in Emacs. (easymenu): Remove redundant require. diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index db142c0dc3..6b22228397 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -1044,166 +1044,161 @@ versions of Emacs." map) "Keymap used in CPerl mode.") -(defvar cperl-menu) (defvar cperl-lazy-installed) (defvar cperl-old-style nil) -(condition-case nil - (progn - (require 'easymenu) - (easy-menu-define - cperl-menu cperl-mode-map "Menu for CPerl mode" - '("Perl" - ["Beginning of function" beginning-of-defun t] - ["End of function" end-of-defun t] - ["Mark function" mark-defun t] - ["Indent expression" cperl-indent-exp t] - ["Fill paragraph/comment" fill-paragraph t] - "----" - ["Line up a construction" cperl-lineup (use-region-p)] - ["Invert if/unless/while etc" cperl-invert-if-unless t] - ("Regexp" - ["Beautify" cperl-beautify-regexp - cperl-use-syntax-table-text-property] - ["Beautify one level deep" (cperl-beautify-regexp 1) - cperl-use-syntax-table-text-property] - ["Beautify a group" cperl-beautify-level - cperl-use-syntax-table-text-property] - ["Beautify a group one level deep" (cperl-beautify-level 1) - cperl-use-syntax-table-text-property] - ["Contract a group" cperl-contract-level - cperl-use-syntax-table-text-property] - ["Contract groups" cperl-contract-levels - cperl-use-syntax-table-text-property] - "----" - ["Find next interpolated" cperl-next-interpolated-REx - (next-single-property-change (point-min) 'REx-interpolated)] - ["Find next interpolated (no //o)" - cperl-next-interpolated-REx-0 - (or (text-property-any (point-min) (point-max) 'REx-interpolated t) - (text-property-any (point-min) (point-max) 'REx-interpolated 1))] - ["Find next interpolated (neither //o nor whole-REx)" - cperl-next-interpolated-REx-1 - (text-property-any (point-min) (point-max) 'REx-interpolated t)]) - ["Insert spaces if needed to fix style" cperl-find-bad-style t] - ["Refresh \"hard\" constructions" cperl-find-pods-heres t] - "----" - ["Indent region" cperl-indent-region (use-region-p)] - ["Comment region" cperl-comment-region (use-region-p)] - ["Uncomment region" cperl-uncomment-region (use-region-p)] - "----" - ["Run" mode-compile (fboundp 'mode-compile)] - ["Kill" mode-compile-kill (and (fboundp 'mode-compile-kill) - (get-buffer "*compilation*"))] - ["Next error" next-error (get-buffer "*compilation*")] - ["Check syntax" cperl-check-syntax (fboundp 'mode-compile)] - "----" - ["Debugger" cperl-db t] - "----" - ("Tools" - ["Imenu" imenu (fboundp 'imenu)] - ["Imenu on Perl Info" cperl-imenu-on-info (featurep 'imenu)] - "----" - ["Ispell PODs" cperl-pod-spell - ;; Better not to update syntaxification here: - ;; debugging syntaxification can be broken by this??? - (or - (get-text-property (point-min) 'in-pod) - (< (progn - (and cperl-syntaxify-for-menu - (cperl-update-syntaxification (point-max))) - (next-single-property-change (point-min) 'in-pod nil (point-max))) - (point-max)))] - ["Ispell HERE-DOCs" cperl-here-doc-spell - (< (progn - (and cperl-syntaxify-for-menu - (cperl-update-syntaxification (point-max))) - (next-single-property-change (point-min) 'here-doc-group nil (point-max))) - (point-max))] - ["Narrow to this HERE-DOC" cperl-narrow-to-here-doc - (eq 'here-doc (progn - (and cperl-syntaxify-for-menu - (cperl-update-syntaxification (point))) - (get-text-property (point) 'syntax-type)))] - ["Select this HERE-DOC or POD section" - cperl-select-this-pod-or-here-doc - (memq (progn - (and cperl-syntaxify-for-menu - (cperl-update-syntaxification (point))) - (get-text-property (point) 'syntax-type)) - '(here-doc pod))] - "----" - ["CPerl pretty print (experimental)" cperl-ps-print - (fboundp 'ps-extend-face-list)] - "----" - ["Syntaxify region" cperl-find-pods-heres-region - (use-region-p)] - ["Profile syntaxification" cperl-time-fontification t] - ["Debug errors in delayed fontification" cperl-emulate-lazy-lock t] - ["Debug unwind for syntactic scan" cperl-toggle-set-debug-unwind t] - ["Debug backtrace on syntactic scan (BEWARE!!!)" - (cperl-toggle-set-debug-unwind nil t) t] - "----" - ["Class Hierarchy from TAGS" cperl-tags-hier-init t] - ;;["Update classes" (cperl-tags-hier-init t) tags-table-list] - ("Tags" - ;; ["Create tags for current file" cperl-etags t] - ;; ["Add tags for current file" (cperl-etags t) t] - ;; ["Create tags for Perl files in directory" (cperl-etags nil t) t] - ;; ["Add tags for Perl files in directory" (cperl-etags t t) t] - ;; ["Create tags for Perl files in (sub)directories" - ;; (cperl-etags nil 'recursive) t] - ;; ["Add tags for Perl files in (sub)directories" - ;; (cperl-etags t 'recursive) t]) - ;; ;;? cperl-write-tags (&optional file erase recurse dir inbuffer) - ["Create tags for current file" (cperl-write-tags nil t) t] - ["Add tags for current file" (cperl-write-tags) t] - ["Create tags for Perl files in directory" - (cperl-write-tags nil t nil t) t] - ["Add tags for Perl files in directory" - (cperl-write-tags nil nil nil t) t] - ["Create tags for Perl files in (sub)directories" - (cperl-write-tags nil t t t) t] - ["Add tags for Perl files in (sub)directories" - (cperl-write-tags nil nil t t) t])) - ("Perl docs" - ["Define word at point" imenu-go-find-at-position - (fboundp 'imenu-go-find-at-position)] - ["Help on function" cperl-info-on-command t] - ["Help on function at point" cperl-info-on-current-command t] - ["Help on symbol at point" cperl-get-help t] - ["Perldoc" cperl-perldoc t] - ["Perldoc on word at point" cperl-perldoc-at-point t] - ["View manpage of POD in this file" cperl-build-manpage t] - ["Auto-help on" cperl-lazy-install - (not cperl-lazy-installed)] - ["Auto-help off" cperl-lazy-unstall - cperl-lazy-installed]) - ("Toggle..." - ["Auto newline" cperl-toggle-auto-newline t] - ["Electric parens" cperl-toggle-electric t] - ["Electric keywords" cperl-toggle-abbrev t] - ["Fix whitespace on indent" cperl-toggle-construct-fix t] - ["Auto-help on Perl constructs" cperl-toggle-autohelp t] - ["Auto fill" auto-fill-mode t]) - ("Indent styles..." - ["CPerl" (cperl-set-style "CPerl") t] - ["PBP" (cperl-set-style "PBP") t] - ["PerlStyle" (cperl-set-style "PerlStyle") t] - ["GNU" (cperl-set-style "GNU") t] - ["C++" (cperl-set-style "C++") t] - ["K&R" (cperl-set-style "K&R") t] - ["BSD" (cperl-set-style "BSD") t] - ["Whitesmith" (cperl-set-style "Whitesmith") t] - ["Memorize Current" (cperl-set-style "Current") t] - ["Memorized" (cperl-set-style-back) cperl-old-style]) - ("Micro-docs" - ["Tips" (describe-variable 'cperl-tips) t] - ["Problems" (describe-variable 'cperl-problems) t] - ["Speed" (describe-variable 'cperl-speed) t] - ["Praise" (describe-variable 'cperl-praise) t] - ["Faces" (describe-variable 'cperl-tips-faces) t] - ["CPerl mode" (describe-function 'cperl-mode) t])))) - (error nil)) +(easy-menu-define cperl-menu cperl-mode-map + "Menu for CPerl mode." + '("Perl" + ["Beginning of function" beginning-of-defun t] + ["End of function" end-of-defun t] + ["Mark function" mark-defun t] + ["Indent expression" cperl-indent-exp t] + ["Fill paragraph/comment" fill-paragraph t] + "----" + ["Line up a construction" cperl-lineup (use-region-p)] + ["Invert if/unless/while etc" cperl-invert-if-unless t] + ("Regexp" + ["Beautify" cperl-beautify-regexp + cperl-use-syntax-table-text-property] + ["Beautify one level deep" (cperl-beautify-regexp 1) + cperl-use-syntax-table-text-property] + ["Beautify a group" cperl-beautify-level + cperl-use-syntax-table-text-property] + ["Beautify a group one level deep" (cperl-beautify-level 1) + cperl-use-syntax-table-text-property] + ["Contract a group" cperl-contract-level + cperl-use-syntax-table-text-property] + ["Contract groups" cperl-contract-levels + cperl-use-syntax-table-text-property] + "----" + ["Find next interpolated" cperl-next-interpolated-REx + (next-single-property-change (point-min) 'REx-interpolated)] + ["Find next interpolated (no //o)" + cperl-next-interpolated-REx-0 + (or (text-property-any (point-min) (point-max) 'REx-interpolated t) + (text-property-any (point-min) (point-max) 'REx-interpolated 1))] + ["Find next interpolated (neither //o nor whole-REx)" + cperl-next-interpolated-REx-1 + (text-property-any (point-min) (point-max) 'REx-interpolated t)]) + ["Insert spaces if needed to fix style" cperl-find-bad-style t] + ["Refresh \"hard\" constructions" cperl-find-pods-heres t] + "----" + ["Indent region" cperl-indent-region (use-region-p)] + ["Comment region" cperl-comment-region (use-region-p)] + ["Uncomment region" cperl-uncomment-region (use-region-p)] + "----" + ["Run" mode-compile (fboundp 'mode-compile)] + ["Kill" mode-compile-kill (and (fboundp 'mode-compile-kill) + (get-buffer "*compilation*"))] + ["Next error" next-error (get-buffer "*compilation*")] + ["Check syntax" cperl-check-syntax (fboundp 'mode-compile)] + "----" + ["Debugger" cperl-db t] + "----" + ("Tools" + ["Imenu" imenu (fboundp 'imenu)] + ["Imenu on Perl Info" cperl-imenu-on-info (featurep 'imenu)] + "----" + ["Ispell PODs" cperl-pod-spell + ;; Better not to update syntaxification here: + ;; debugging syntaxification can be broken by this??? + (or + (get-text-property (point-min) 'in-pod) + (< (progn + (and cperl-syntaxify-for-menu + (cperl-update-syntaxification (point-max))) + (next-single-property-change (point-min) 'in-pod nil (point-max))) + (point-max)))] + ["Ispell HERE-DOCs" cperl-here-doc-spell + (< (progn + (and cperl-syntaxify-for-menu + (cperl-update-syntaxification (point-max))) + (next-single-property-change (point-min) 'here-doc-group nil (point-max))) + (point-max))] + ["Narrow to this HERE-DOC" cperl-narrow-to-here-doc + (eq 'here-doc (progn + (and cperl-syntaxify-for-menu + (cperl-update-syntaxification (point))) + (get-text-property (point) 'syntax-type)))] + ["Select this HERE-DOC or POD section" + cperl-select-this-pod-or-here-doc + (memq (progn + (and cperl-syntaxify-for-menu + (cperl-update-syntaxification (point))) + (get-text-property (point) 'syntax-type)) + '(here-doc pod))] + "----" + ["CPerl pretty print (experimental)" cperl-ps-print + (fboundp 'ps-extend-face-list)] + "----" + ["Syntaxify region" cperl-find-pods-heres-region + (use-region-p)] + ["Profile syntaxification" cperl-time-fontification t] + ["Debug errors in delayed fontification" cperl-emulate-lazy-lock t] + ["Debug unwind for syntactic scan" cperl-toggle-set-debug-unwind t] + ["Debug backtrace on syntactic scan (BEWARE!!!)" + (cperl-toggle-set-debug-unwind nil t) t] + "----" + ["Class Hierarchy from TAGS" cperl-tags-hier-init t] + ;;["Update classes" (cperl-tags-hier-init t) tags-table-list] + ("Tags" + ;; ["Create tags for current file" cperl-etags t] + ;; ["Add tags for current file" (cperl-etags t) t] + ;; ["Create tags for Perl files in directory" (cperl-etags nil t) t] + ;; ["Add tags for Perl files in directory" (cperl-etags t t) t] + ;; ["Create tags for Perl files in (sub)directories" + ;; (cperl-etags nil 'recursive) t] + ;; ["Add tags for Perl files in (sub)directories" + ;; (cperl-etags t 'recursive) t]) + ;; ;;? cperl-write-tags (&optional file erase recurse dir inbuffer) + ["Create tags for current file" (cperl-write-tags nil t) t] + ["Add tags for current file" (cperl-write-tags) t] + ["Create tags for Perl files in directory" + (cperl-write-tags nil t nil t) t] + ["Add tags for Perl files in directory" + (cperl-write-tags nil nil nil t) t] + ["Create tags for Perl files in (sub)directories" + (cperl-write-tags nil t t t) t] + ["Add tags for Perl files in (sub)directories" + (cperl-write-tags nil nil t t) t])) + ("Perl docs" + ["Define word at point" imenu-go-find-at-position + (fboundp 'imenu-go-find-at-position)] + ["Help on function" cperl-info-on-command t] + ["Help on function at point" cperl-info-on-current-command t] + ["Help on symbol at point" cperl-get-help t] + ["Perldoc" cperl-perldoc t] + ["Perldoc on word at point" cperl-perldoc-at-point t] + ["View manpage of POD in this file" cperl-build-manpage t] + ["Auto-help on" cperl-lazy-install + (not cperl-lazy-installed)] + ["Auto-help off" cperl-lazy-unstall + cperl-lazy-installed]) + ("Toggle..." + ["Auto newline" cperl-toggle-auto-newline t] + ["Electric parens" cperl-toggle-electric t] + ["Electric keywords" cperl-toggle-abbrev t] + ["Fix whitespace on indent" cperl-toggle-construct-fix t] + ["Auto-help on Perl constructs" cperl-toggle-autohelp t] + ["Auto fill" auto-fill-mode t]) + ("Indent styles..." + ["CPerl" (cperl-set-style "CPerl") t] + ["PBP" (cperl-set-style "PBP") t] + ["PerlStyle" (cperl-set-style "PerlStyle") t] + ["GNU" (cperl-set-style "GNU") t] + ["C++" (cperl-set-style "C++") t] + ["K&R" (cperl-set-style "K&R") t] + ["BSD" (cperl-set-style "BSD") t] + ["Whitesmith" (cperl-set-style "Whitesmith") t] + ["Memorize Current" (cperl-set-style "Current") t] + ["Memorized" (cperl-set-style-back) cperl-old-style]) + ("Micro-docs" + ["Tips" (describe-variable 'cperl-tips) t] + ["Problems" (describe-variable 'cperl-problems) t] + ["Speed" (describe-variable 'cperl-speed) t] + ["Praise" (describe-variable 'cperl-praise) t] + ["Faces" (describe-variable 'cperl-tips-faces) t] + ["CPerl mode" (describe-function 'cperl-mode) t]))) (autoload 'c-macro-expand "cmacexp" "Display the result of expanding all C macros occurring in the region. commit 752278834b3d317a65135cdaa392b0468ce7372c Author: Basil L. Contovounesios Date: Sat Feb 20 18:55:12 2021 +0000 Function-quote completion property of declare form For discussion, see the following thread: https://lists.gnu.org/r/emacs-devel/2021-02/msg01666.html * lisp/emacs-lisp/byte-run.el (byte-run--set-completion): Quote with 'function' for syntactical consistency with other declare form properties. This allows writing (declare (completion foo)) instead of (declare (completion 'foo)). * lisp/emacs-lisp/easymenu.el (easy-menu-do-define): * lisp/gnus/gnus-sum.el (gnus-summary-make-menu-bar): Prefer function-put over put for function symbols. * lisp/subr.el (ignore, undefined): Remove #'-quoting from declare form; it is no longer needed. diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index afe94bb035..6451d7fb62 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el @@ -149,7 +149,7 @@ The return value of this function is not used." (defalias 'byte-run--set-completion #'(lambda (f _args val) (list 'function-put (list 'quote f) - ''completion-predicate val))) + ''completion-predicate (list 'function val)))) (defalias 'byte-run--set-modes #'(lambda (f _args &rest val) diff --git a/lisp/emacs-lisp/easymenu.el b/lisp/emacs-lisp/easymenu.el index bcd5cfd99b..b49d886ede 100644 --- a/lisp/emacs-lisp/easymenu.el +++ b/lisp/emacs-lisp/easymenu.el @@ -184,12 +184,12 @@ This is expected to be bound to a mouse event." (funcall (or (plist-get (get symbol 'menu-prop) :filter) - 'identity) + #'identity) (symbol-function symbol))) symbol)))) ;; These symbols are commands, but not interesting for users ;; to `M-x TAB'. - (put symbol 'completion-predicate 'ignore)) + (function-put symbol 'completion-predicate #'ignore)) (dolist (map (if (keymapp maps) (list maps) maps)) (define-key map (vector 'menu-bar (easy-menu-intern (car menu))) diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index 4065cf0834..ee74f01393 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -2517,7 +2517,7 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs)))) (let ((gnus-summary-show-article-charset-alist `((1 . ,cs)))) (gnus-summary-show-article 1)))) - (put command 'completion-predicate 'ignore) + (function-put command 'completion-predicate #'ignore) `[,(symbol-name cs) ,command t])) (sort (coding-system-list) #'string<))))) ("Washing" diff --git a/lisp/subr.el b/lisp/subr.el index cc8b85b1d3..2323e5dce2 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -375,7 +375,7 @@ PREFIX is a string, and defaults to \"g\"." "Do nothing and return nil. This function accepts any number of ARGUMENTS, but ignores them. Also see `always'." - (declare (completion #'ignore)) + (declare (completion ignore)) (interactive) nil) @@ -923,7 +923,7 @@ For an approximate inverse of this, see `key-description'." (defun undefined () "Beep to tell the user this binding is undefined." - (declare (completion #'ignore)) + (declare (completion ignore)) (interactive) (ding) (if defining-kbd-macro commit 70f2d658e42120c289c4a3c043b5d5b1331bc183 Author: Mattias Engdegård Date: Fri Feb 26 09:52:16 2021 +0100 Fix pcase rx pattern bugs Two unrelated bugs: A missing type check caused an error in rx patterns for non-string match targets, and rx patterns did not work at all in pcase-let or pcase-let*. Second bug reported by Basil Contovounesios and Ag Ibragimov; fixes proposed by Stefan Monnier. Discussion and explanation in thread at https://lists.gnu.org/archive/html/emacs-devel/2021-02/msg01924.html * lisp/emacs-lisp/rx.el (rx): Add (pred stringp) to avoid type errors, and replace the `pred` clause for the actual match with something that works with pcase-let(*) without being optimised away. * test/lisp/emacs-lisp/rx-tests.el (rx-pcase): Add test cases. diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index 58584f300c..ffc21951b6 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -1437,7 +1437,11 @@ following constructs: construct." (let* ((rx--pcase-vars nil) (regexp (rx--to-expr (rx--pcase-transform (cons 'seq regexps))))) - `(and (pred (string-match ,regexp)) + `(and (pred stringp) + ;; `pcase-let' takes a match for granted and discards all unnecessary + ;; conditions, which means that a `pred' clause cannot be used for + ;; the match condition. The following construct seems to survive. + (app (lambda (s) (string-match ,regexp s)) (pred identity)) ,@(let ((i 0)) (mapcar (lambda (name) (setq i (1+ i)) diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el index 12bf4f7978..fecdcf55af 100644 --- a/test/lisp/emacs-lisp/rx-tests.el +++ b/test/lisp/emacs-lisp/rx-tests.el @@ -171,7 +171,17 @@ (should (equal (pcase "abc" ((rx (? (let x alpha)) (?? (let y alnum)) ?c) (list x y))) - '("a" "b")))) + '("a" "b"))) + (should (equal (pcase 'not-a-string + ((rx nonl) 'wrong) + (_ 'correct)) + 'correct)) + (should (equal (pcase-let (((rx ?B (let z nonl)) "ABC")) + (list 'ok z)) + '(ok "C"))) + (should (equal (pcase-let* (((rx ?E (let z nonl)) "DEF")) + (list 'ok z)) + '(ok "F")))) (ert-deftest rx-kleene () "Test greedy and non-greedy repetition operators." commit 7a23915618816ccdda03823412991e77003e3e1b Author: Stefan Kangas Date: Fri Feb 26 05:46:26 2021 +0100 * lisp/tooltip.el (tooltip): Doc fix for GTK. diff --git a/lisp/tooltip.el b/lisp/tooltip.el index 4a37e404b2..bb53a138d8 100644 --- a/lisp/tooltip.el +++ b/lisp/tooltip.el @@ -138,7 +138,10 @@ of the `tooltip' face are used instead." :inherit variable-pitch) (t :inherit variable-pitch)) - "Face for tooltips." + "Face for tooltips. + +When using the GTK toolkit, this face will only be used if +`x-gtk-use-system-tooltips' is non-nil." :group 'tooltip :group 'basic-faces) commit 6bf56a3614ccd23a31e34ae997b2a6bb0d158489 Author: Eli Zaretskii Date: Thu Feb 25 20:58:44 2021 +0200 Fix documentation of a recent change * src/fns.c (Fyes_or_no_p): Don't use braces around one-line block. (syms_of_fns) : Improve the wording of the doc string. * etc/NEWS: Improve wording of the entry about 'use-short-answers'. diff --git a/etc/NEWS b/etc/NEWS index 1ec080a6db..f8f41e21e2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2416,8 +2416,9 @@ use the function 'read-key' to read a character instead of using the minibuffer. --- ** New variable 'use-short-answers' to use 'y-or-n-p' instead of 'yes-or-no-p'. -This relieves of the need to define an alias that maps one to another -in the init file. The same variable also affects the function 'read-answer'. +This eliminates the need to define an alias that maps one to another +in the init file. The same variable also controls whether the +function 'read-answer' accepts short answers. +++ ** 'set-window-configuration' now takes an optional 'dont-set-frame' diff --git a/src/fns.c b/src/fns.c index 79b5a1e993..7914bd4779 100644 --- a/src/fns.c +++ b/src/fns.c @@ -2874,9 +2874,7 @@ if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil. */) } if (use_short_answers) - { - return call1 (intern ("y-or-n-p"), prompt); - } + return call1 (intern ("y-or-n-p"), prompt); AUTO_STRING (yes_or_no, "(yes or no) "); prompt = CALLN (Fconcat, prompt, yes_or_no); @@ -5911,10 +5909,10 @@ this variable. */); DEFVAR_BOOL ("use-short-answers", use_short_answers, doc: /* Non-nil means `yes-or-no-p' uses shorter answers "y" or "n". -It's discouraged to use single-key answers because `yes-or-no-p' is -intended to be used when it's thought that you should not respond too -quickly, so you take time and perhaps think more about the answer. -When non-nil, then `yes-or-no-p' uses `y-or-n-p' to read an answer. +When non-nil, `yes-or-no-p' will use `y-or-n-p' to read the answer. +We recommend against setting this variable non-nil, because `yes-or-no-p' +is intended to be used when users are expected not to respond too +quickly, but to take their time and perhaps think about the answer. The same variable also affects the function `read-answer'. */); use_short_answers = false; commit 297c0e0306f111c1e7564b2bb49a7e1a925a55bb Author: Juri Linkov Date: Thu Feb 25 20:45:40 2021 +0200 New variable 'use-short-answers' to use 'y-or-n-p' instead of 'yes-or-no-p' * lisp/cus-start.el: Add use-short-answers. * lisp/emacs-lisp/map-ynp.el (read-answer): Handle use-short-answers. (read-answer-short): Add use-short-answers to docstring. * src/fns.c (Fyes_or_no_p): Call y-or-n-p if use_short_answers is true. (syms_of_fns): Add DEFVAR_BOOL use-short-answers (bug#46594). diff --git a/etc/NEWS b/etc/NEWS index caa366aaef..1ec080a6db 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2414,6 +2414,11 @@ and display the result. When non-nil, then functions 'read-char-choice' and 'y-or-n-p' (respectively) use the function 'read-key' to read a character instead of using the minibuffer. +--- +** New variable 'use-short-answers' to use 'y-or-n-p' instead of 'yes-or-no-p'. +This relieves of the need to define an alias that maps one to another +in the init file. The same variable also affects the function 'read-answer'. + +++ ** 'set-window-configuration' now takes an optional 'dont-set-frame' parameter which, when non-nil, instructs the function not to select diff --git a/lisp/cus-start.el b/lisp/cus-start.el index c0a4a6dda0..7b05f5796a 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -302,6 +302,7 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of ;; fns.c (use-dialog-box menu boolean "21.1") (use-file-dialog menu boolean "22.1") + (use-short-answers menu boolean "28.1") (focus-follows-mouse frames (choice (const :tag "Off (nil)" :value nil) diff --git a/lisp/emacs-lisp/map-ynp.el b/lisp/emacs-lisp/map-ynp.el index 14112a1c14..86a0c76fd1 100644 --- a/lisp/emacs-lisp/map-ynp.el +++ b/lisp/emacs-lisp/map-ynp.el @@ -265,7 +265,8 @@ C-g to quit (cancel the whole command); "If non-nil, `read-answer' accepts single-character answers. If t, accept short (single key-press) answers to the question. If nil, require long answers. If `auto', accept short answers if -the function cell of `yes-or-no-p' is set to `y-or-n-p'." +`use-short-answers' is non-nil, or the function cell of `yes-or-no-p' +is set to `y-or-n-p'." :type '(choice (const :tag "Accept short answers" t) (const :tag "Require long answer" nil) (const :tag "Guess preference" auto)) @@ -304,7 +305,8 @@ Return a long answer even in case of accepting short ones. When `use-dialog-box' is t, pop up a dialog window to get user input." (let* ((short (if (eq read-answer-short 'auto) - (eq (symbol-function 'yes-or-no-p) 'y-or-n-p) + (or use-short-answers + (eq (symbol-function 'yes-or-no-p) 'y-or-n-p)) read-answer-short)) (answers-with-help (if (assoc "help" answers) diff --git a/src/fns.c b/src/fns.c index c16f9c6399..79b5a1e993 100644 --- a/src/fns.c +++ b/src/fns.c @@ -2873,6 +2873,11 @@ if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil. */) return obj; } + if (use_short_answers) + { + return call1 (intern ("y-or-n-p"), prompt); + } + AUTO_STRING (yes_or_no, "(yes or no) "); prompt = CALLN (Fconcat, prompt, yes_or_no); @@ -5904,6 +5909,15 @@ that disables the use of a file dialog, regardless of the value of this variable. */); use_file_dialog = true; + DEFVAR_BOOL ("use-short-answers", use_short_answers, + doc: /* Non-nil means `yes-or-no-p' uses shorter answers "y" or "n". +It's discouraged to use single-key answers because `yes-or-no-p' is +intended to be used when it's thought that you should not respond too +quickly, so you take time and perhaps think more about the answer. +When non-nil, then `yes-or-no-p' uses `y-or-n-p' to read an answer. +The same variable also affects the function `read-answer'. */); + use_short_answers = false; + defsubr (&Sidentity); defsubr (&Srandom); defsubr (&Slength); commit 056b468f74ff0aab41febaf6dbd4db23f3bebba2 Author: Alan Third Date: Wed Feb 24 09:52:42 2021 +0000 Fix freeze on older macOS's (bug#46687) * src/nsterm.m ([EmacsView windowDidChangeBackingProperties:]): ([EmacsView viewWillDraw]): Only run this code when actually drawing to an offscreen bitmap. diff --git a/src/nsterm.m b/src/nsterm.m index 88317f8839..bf175bbd18 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -8411,13 +8411,16 @@ - (void)windowDidChangeBackingProperties:(NSNotification *)notification { NSTRACE ("EmacsView windowDidChangeBackingProperties:]"); - NSRect frame = [self frame]; + if ([self wantsUpdateLayer]) + { + NSRect frame = [self frame]; - [surface release]; - surface = nil; + [surface release]; + surface = nil; - ns_clear_frame (emacsframe); - expose_frame (emacsframe, 0, 0, NSWidth (frame), NSHeight (frame)); + ns_clear_frame (emacsframe); + expose_frame (emacsframe, 0, 0, NSWidth (frame), NSHeight (frame)); + } } #endif /* NS_DRAW_TO_BUFFER */ @@ -8480,7 +8483,7 @@ - (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect } -#ifdef NS_IMPL_COCOA +#ifdef NS_DRAW_TO_BUFFER /* If the frame has been garbaged but the toolkit wants to draw, for example when resizing the frame, we end up with a blank screen. Sometimes this results in an unpleasant flicker, so try to @@ -8488,7 +8491,8 @@ - (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect - (void)viewWillDraw { if (FRAME_GARBAGED_P (emacsframe) - && !redisplaying_p) + && !redisplaying_p + && [self wantsUpdateLayer]) { /* If there is IO going on when redisplay is run here Emacs crashes. I think it's because this code will always be run @@ -8505,10 +8509,8 @@ - (void)viewWillDraw waiting_for_input = owfi; } } -#endif -#ifdef NS_DRAW_TO_BUFFER - (BOOL)wantsUpdateLayer { #if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 commit 90ac40570280f4f423b55a2d9eea5a44317a66e3 Author: Robert Pluim Date: Thu Feb 25 16:39:34 2021 +0100 Re-enable network-stream-tests.el :nowait t tests After the fix for Bug#46709, these no longer fail in the absence of a working Internet connection * test/lisp/net/network-stream-tests.el (internet-is-working): Remove defvar, it's no longer needed in this file. * test/lisp/net/network-stream-tests.el (connect-to-tls-ipv4-nowait): (connect-to-tls-ipv6-nowait): (open-network-stream-tls-nowait): (open-gnutls-stream-new-api-nowait): (open-gnutls-stream-old-api-nowait): Remove check for internet-is-working. diff --git a/test/lisp/net/network-stream-tests.el b/test/lisp/net/network-stream-tests.el index cc43992f0f..1a4cc744f0 100644 --- a/test/lisp/net/network-stream-tests.el +++ b/test/lisp/net/network-stream-tests.el @@ -32,13 +32,6 @@ ;; it pulls in nsm, which then makes the :nowait t' tests fail unless ;; we disable the nsm, which we do by binding 'network-security-level' -;; Check if the Internet seems to be working. Mainly to pacify -;; Debian's CI system. -(defvar internet-is-working - (progn - (require 'dns) - (dns-query "google.com"))) - (ert-deftest make-local-unix-server () (skip-unless (featurep 'make-network-process '(:family local))) (let* ((file (make-temp-name "/tmp/server-test")) @@ -298,7 +291,6 @@ (ert-deftest connect-to-tls-ipv4-nowait () (skip-unless (executable-find "gnutls-serv")) (skip-unless (gnutls-available-p)) - (skip-unless internet-is-working) (let ((server (make-tls-server 44331)) (times 0) (network-security-level 'low) @@ -342,7 +334,6 @@ (ert-deftest connect-to-tls-ipv6-nowait () (skip-unless (executable-find "gnutls-serv")) (skip-unless (gnutls-available-p)) - (skip-unless internet-is-working) (skip-unless (not (eq system-type 'windows-nt))) (skip-unless (featurep 'make-network-process '(:family ipv6))) (let ((server (make-tls-server 44333)) @@ -427,7 +418,6 @@ (ert-deftest open-network-stream-tls-nowait () (skip-unless (executable-find "gnutls-serv")) (skip-unless (gnutls-available-p)) - (skip-unless internet-is-working) (let ((server (make-tls-server 44335)) (times 0) (network-security-level 'low) @@ -656,7 +646,6 @@ (ert-deftest open-gnutls-stream-new-api-nowait () (skip-unless (executable-find "gnutls-serv")) (skip-unless (gnutls-available-p)) - (skip-unless internet-is-working) (let ((server (make-tls-server 44668)) (times 0) (network-security-level 'low) @@ -695,7 +684,6 @@ (ert-deftest open-gnutls-stream-old-api-nowait () (skip-unless (executable-find "gnutls-serv")) (skip-unless (gnutls-available-p)) - (skip-unless internet-is-working) (let ((server (make-tls-server 44669)) (times 0) (network-security-level 'low) commit d84d69dfbc5f64e9020ce38d2cbd60fe39cb27b9 Author: Robert Pluim Date: Thu Feb 25 16:36:56 2021 +0100 Don't crash if gnutls_handshake fails In some situations involving Internet access not being fully functional, gnutls_handshake returns a fatal error, which we were ignoring, causing us to call gnutls_handshake again. Now we check for the error and return it to the caller. * src/gnutls.c (gnutls_try_handshake): Return immediately if gnutls_handshake returns a fatal error (Bug#46709). diff --git a/src/gnutls.c b/src/gnutls.c index aa245ee5c3..4d5a909db0 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -625,6 +625,8 @@ gnutls_try_handshake (struct Lisp_Process *proc) while ((ret = gnutls_handshake (state)) < 0) { + if (gnutls_error_is_fatal (ret)) + return emacs_gnutls_handle_error (state, ret); do ret = gnutls_handshake (state); while (ret == GNUTLS_E_INTERRUPTED); commit 6c5e86fc175f06a7d37649d4130cf39fc0702278 Author: Robert Pluim Date: Thu Feb 25 16:33:47 2021 +0100 * Specify 'ipv4 when testing ipv4 in network-stream-tests.el * test/lisp/net/network-stream-tests.el (connect-to-tls-ipv4-nowait): Specify :family 'ipv4. diff --git a/test/lisp/net/network-stream-tests.el b/test/lisp/net/network-stream-tests.el index 0fb24d2701..cc43992f0f 100644 --- a/test/lisp/net/network-stream-tests.el +++ b/test/lisp/net/network-stream-tests.el @@ -315,6 +315,7 @@ :name "bar" :buffer (generate-new-buffer "*foo*") :nowait t + :family 'ipv4 :tls-parameters (cons 'gnutls-x509pki (gnutls-boot-parameters commit a1673d329643073233114c22d6d2c1af8dffa51b Author: Robert Pluim Date: Tue Feb 23 15:21:26 2021 +0100 ; * src/xfaces.c (realize_gui_face): Correct formatting * src/xfaces.c (realize_gui_face): Correct code formatting. diff --git a/src/xfaces.c b/src/xfaces.c index 4b020001c3..ab4440f46a 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -6034,10 +6034,11 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] face->box = FACE_RAISED_BOX; else if (EQ (value, Qpressed_button)) face->box = FACE_SUNKEN_BOX; - else if (EQ (value, Qflat_button)) { - face->box = FACE_SIMPLE_BOX; - face->box_color = face->background; - } + else if (EQ (value, Qflat_button)) + { + face->box = FACE_SIMPLE_BOX; + face->box_color = face->background; + } } } } commit 4d43b9a0b0ba2a2f233d81165c6d410a7de61d1d Author: Stefan Kangas Date: Thu Feb 25 12:54:58 2021 +0100 Convert epa-key-list-mode menu to easy-menu-define * lisp/epa.el (epa-key-list-mode-map): Move menu from here... (epa-key-list-mode-menu): ...to here, and convert to easy-menu-define. diff --git a/lisp/epa.el b/lisp/epa.el index 572c947e4b..bbfa2c188c 100644 --- a/lisp/epa.el +++ b/lisp/epa.el @@ -183,8 +183,7 @@ You should bind this variable with `let', but do not set it globally.") (defvar epa-last-coding-system-specified nil) (defvar epa-key-list-mode-map - (let ((keymap (make-sparse-keymap)) - (menu-map (make-sparse-keymap))) + (let ((keymap (make-sparse-keymap))) (define-key keymap "\C-m" 'epa-show-key) (define-key keymap [?\t] 'forward-button) (define-key keymap [backtab] 'backward-button) @@ -204,38 +203,32 @@ You should bind this variable with `let', but do not set it globally.") (define-key keymap [?\S-\ ] 'scroll-down-command) (define-key keymap [delete] 'scroll-down-command) (define-key keymap "q" 'epa-exit-buffer) - (define-key keymap [menu-bar epa-key-list-mode] (cons "Keys" menu-map)) - (define-key menu-map [epa-key-list-unmark-key] - '(menu-item "Unmark Key" epa-unmark-key - :help "Unmark a key")) - (define-key menu-map [epa-key-list-mark-key] - '(menu-item "Mark Key" epa-mark-key - :help "Mark a key")) - (define-key menu-map [separator-epa-file] '(menu-item "--")) - (define-key menu-map [epa-verify-file] - '(menu-item "Verify File..." epa-verify-file - :help "Verify FILE")) - (define-key menu-map [epa-sign-file] - '(menu-item "Sign File..." epa-sign-file - :help "Sign FILE by SIGNERS keys selected")) - (define-key menu-map [epa-decrypt-file] - '(menu-item "Decrypt File..." epa-decrypt-file - :help "Decrypt FILE")) - (define-key menu-map [epa-encrypt-file] - '(menu-item "Encrypt File..." epa-encrypt-file - :help "Encrypt FILE for RECIPIENTS")) - (define-key menu-map [separator-epa-key-list] '(menu-item "--")) - (define-key menu-map [epa-key-list-delete-keys] - '(menu-item "Delete Keys" epa-delete-keys - :help "Delete Marked Keys")) - (define-key menu-map [epa-key-list-import-keys] - '(menu-item "Import Keys" epa-import-keys - :help "Import keys from a file")) - (define-key menu-map [epa-key-list-export-keys] - '(menu-item "Export Keys" epa-export-keys - :help "Export marked keys to a file")) keymap)) +(easy-menu-define epa-key-list-mode-menu epa-key-list-mode-map + "Menu for `epa-key-list-mode'." + '("Keys" + ["Export Keys" epa-export-keys + :help "Export marked keys to a file"] + ["Import Keys" epa-import-keys + :help "Import keys from a file"] + ["Delete Keys" epa-delete-keys + :help "Delete Marked Keys"] + "---" + ["Encrypt File..." epa-encrypt-file + :help "Encrypt file for recipients"] + ["Decrypt File..." epa-decrypt-file + :help "Decrypt file"] + ["Sign File..." epa-sign-file + :help "Sign file by signers keys selected"] + ["Verify File..." epa-verify-file + :help "Verify file"] + "---" + ["Mark Key" epa-mark-key + :help "Mark a key"] + ["Unmark Key" epa-unmark-key + :help "Unmark a key"])) + (defvar epa-key-mode-map (let ((keymap (make-sparse-keymap))) (define-key keymap "q" 'epa-exit-buffer) commit 4b1ace22be661c15a52bc84c0ee8c0c8c5fe8595 Author: Stefan Monnier Date: Wed Feb 24 23:08:47 2021 -0500 Remove last remaining external uses of `edebug-form-spec` * lisp/emacs-lisp/gv.el (gv-place): Use `def-edebug-elem-spec`. * lisp/obsolete/erc-compat.el (erc-define-minor-mode): Remove redundant `edebug-form-spec`. diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el index cbbed06d7c..2b213e2065 100644 --- a/lisp/emacs-lisp/gv.el +++ b/lisp/emacs-lisp/gv.el @@ -315,7 +315,7 @@ The return value is the last VAL in the list. ;; Autoload this `put' since a user might use C-u C-M-x on an expression ;; containing a non-trivial `push' even before gv.el was loaded. ;;;###autoload -(put 'gv-place 'edebug-form-spec '(form)) ;So-called "indirect spec". +(def-edebug-elem-spec 'gv-place '(form)) ;; CL did the equivalent of: ;;(gv-define-macroexpand edebug-after (lambda (before index place) place)) diff --git a/lisp/obsolete/erc-compat.el b/lisp/obsolete/erc-compat.el index 3a1699adac..9972e927e6 100644 --- a/lisp/obsolete/erc-compat.el +++ b/lisp/obsolete/erc-compat.el @@ -32,7 +32,6 @@ ;;;###autoload(autoload 'erc-define-minor-mode "erc-compat") (defalias 'erc-define-minor-mode #'define-minor-mode) -(put 'erc-define-minor-mode 'edebug-form-spec 'define-minor-mode) (defun erc-decode-coding-string (s coding-system) "Decode S using CODING-SYSTEM." diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el index 869529ab2d..023c90cca5 100644 --- a/lisp/progmodes/etags.el +++ b/lisp/progmodes/etags.el @@ -1604,11 +1604,11 @@ that do nothing." ;; This might be a neat idea, but it's too hairy at the moment. ;;(defmacro tags-with-syntax (&rest body) +;; (declare (debug t)) ;; `(with-syntax-table ;; (with-current-buffer (find-file-noselect (file-of-tag)) ;; (syntax-table)) ;; ,@body)) -;;(put 'tags-with-syntax 'edebug-form-spec '(&rest form)) ;; exact file name match, i.e. searched tag must match complete file ;; name including directories parts if there are some. commit 8114a84b21b2463ea35db7f3a18fd3804396f47e Author: Stefan Monnier Date: Wed Feb 24 18:39:06 2021 -0500 * test/lisp/emacs-lisp/macroexp-tests.el (macroexp--tests-file-name): Add case Add use of `macroexp-file-name` from a macro called from within a function, which works thanks to eager-macroexpansion (so the macro is expanded which the file is being loaded rather than only later when the function is called). * test/lisp/emacs-lisp/macroexp-resources/m1.el (macroexp--m1-tests-file-name): New function. diff --git a/test/lisp/emacs-lisp/macroexp-resources/m1.el b/test/lisp/emacs-lisp/macroexp-resources/m1.el index a2fe6ecf2e..96b5f7091a 100644 --- a/test/lisp/emacs-lisp/macroexp-resources/m1.el +++ b/test/lisp/emacs-lisp/macroexp-resources/m1.el @@ -29,5 +29,8 @@ (eval-when-compile (defconst macroexp--m1-tests-comp-filename (macroexp-file-name))) +(defun macroexp--m1-tests-file-name () + (macroexp--test-get-file-name)) + (provide 'm1) ;;; m1.el ends here diff --git a/test/lisp/emacs-lisp/macroexp-tests.el b/test/lisp/emacs-lisp/macroexp-tests.el index 0b26f109b9..89d3882d1d 100644 --- a/test/lisp/emacs-lisp/macroexp-tests.el +++ b/test/lisp/emacs-lisp/macroexp-tests.el @@ -34,6 +34,8 @@ (defconst macroexp--tests-filename (macroexp-file-name)) +(defmacro macroexp--test-get-file-name () (macroexp-file-name)) + (ert-deftest macroexp--tests-file-name () (should (string-match "\\`macroexp-tests.elc?\\'" @@ -44,10 +46,13 @@ (with-current-buffer (find-file-noselect (expand-file-name "m1.el" rsrc-dir)) (defvar macroexp--m1-tests-filename) + (declare-function macroexp--m1-tests-file-name "m1" ()) ;; `macroexp-file-name' should work with `eval-buffer'. (eval-buffer) (should (equal "m1.el" (file-name-nondirectory macroexp--m1-tests-filename))) + (should (equal "m1.el" + (file-name-nondirectory (macroexp--m1-tests-file-name)))) (search-forward "macroexp--m1-tests-filename") (makunbound 'macroexp--m1-tests-filename) ;; `macroexp-file-name' should also work with `eval-defun'. commit d527bc4b7d2f69d8b3ae76be78fb9610419bd800 Author: Stefan Monnier Date: Wed Feb 24 18:12:18 2021 -0500 * test/lisp/emacs-lisp/macroexp-tests.el (macroexp--tests-file-name): New test * test/lisp/emacs-lisp/macroexp-resources/m1.el: * test/lisp/emacs-lisp/macroexp-resources/m2.el: New files. diff --git a/test/lisp/emacs-lisp/macroexp-resources/m1.el b/test/lisp/emacs-lisp/macroexp-resources/m1.el new file mode 100644 index 0000000000..a2fe6ecf2e --- /dev/null +++ b/test/lisp/emacs-lisp/macroexp-resources/m1.el @@ -0,0 +1,33 @@ +;;; m1.el --- Some sample code for macroexp-tests -*- lexical-binding: t; -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Stefan Monnier +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; + +;;; Code: + +(defconst macroexp--m1-tests-filename (macroexp-file-name)) + +(eval-when-compile + (defconst macroexp--m1-tests-comp-filename (macroexp-file-name))) + +(provide 'm1) +;;; m1.el ends here diff --git a/test/lisp/emacs-lisp/macroexp-resources/m2.el b/test/lisp/emacs-lisp/macroexp-resources/m2.el new file mode 100644 index 0000000000..4f2b96d8ca --- /dev/null +++ b/test/lisp/emacs-lisp/macroexp-resources/m2.el @@ -0,0 +1,33 @@ +;;; m2.el --- More sample code for macroexp-tests -*- lexical-binding: t; -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Stefan Monnier +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; + +;;; Code: + +(defconst macroexp--m2-tests-filename (macroexp-file-name)) + +(byte-compile-file (expand-file-name + "m1.el" (file-name-directory macroexp--m2-tests-filename))) + +(provide 'm2) +;;; m2.el ends here diff --git a/test/lisp/emacs-lisp/macroexp-tests.el b/test/lisp/emacs-lisp/macroexp-tests.el index 1124e3b8d9..0b26f109b9 100644 --- a/test/lisp/emacs-lisp/macroexp-tests.el +++ b/test/lisp/emacs-lisp/macroexp-tests.el @@ -1,6 +1,6 @@ ;;; macroexp-tests.el --- Tests for macroexp.el -*- lexical-binding: t; -*- -;; Copyright (C) 2021 Stefan Monnier +;; Copyright (C) 2021 Free Software Foundation, Inc. ;; Author: Stefan Monnier ;; Keywords: @@ -32,5 +32,36 @@ (should (equal (macroexp--fgrep '((x) (y)) '#2=([r] ((a x)) a b c d . #2#)) '((x))))) +(defconst macroexp--tests-filename (macroexp-file-name)) + +(ert-deftest macroexp--tests-file-name () + (should (string-match + "\\`macroexp-tests.elc?\\'" + (file-name-nondirectory macroexp--tests-filename))) + (let ((rsrc-dir (expand-file-name + "macroexp-resources" + (file-name-directory macroexp--tests-filename)))) + (with-current-buffer + (find-file-noselect (expand-file-name "m1.el" rsrc-dir)) + (defvar macroexp--m1-tests-filename) + ;; `macroexp-file-name' should work with `eval-buffer'. + (eval-buffer) + (should (equal "m1.el" + (file-name-nondirectory macroexp--m1-tests-filename))) + (search-forward "macroexp--m1-tests-filename") + (makunbound 'macroexp--m1-tests-filename) + ;; `macroexp-file-name' should also work with `eval-defun'. + (eval-defun nil) + (should (equal "m1.el" + (file-name-nondirectory macroexp--m1-tests-filename)))) + + ;; Test the case where we load a file which byte-compiles another. + (defvar macroexp--m1-tests-comp-filename) + (makunbound 'macroexp--m1-tests-comp-filename) + (load (expand-file-name "m2.el" rsrc-dir)) + (should (equal "m1.el" + (file-name-nondirectory macroexp--m1-tests-comp-filename))))) + + (provide 'macroexp-tests) ;;; macroexp-tests.el ends here commit 97ab85c78ed2ce22ec8c72482f460890a01b00c2 Author: Lars Ingebrigtsen Date: Wed Feb 24 23:55:05 2021 +0100 Include a "make check-maybe" in the admin/emake script diff --git a/admin/emake b/admin/emake index d9aa4ea74b..e95b17dbdc 100755 --- a/admin/emake +++ b/admin/emake @@ -83,3 +83,9 @@ do [[ "X${REPLY:0:3}" == "X " ]] && C="\033[1;31m" [[ "X$C" == "X" ]] && printf "%s\n" "$REPLY" || printf "$C%s\033[0m\n" "$REPLY" done + +# Run a "make check" on all test files belonging to files that have +# changed since last time. +make -j$cores check-maybe 2>&1 | \ + sed -n '/contained unexpected results/,$p' | \ + egrep --line-buffered -v "^make" commit db09267de338461d7f3dcddba61d1b8904e7259e Author: Basil L. Contovounesios Date: Wed Feb 24 22:34:06 2021 +0000 ; Fix recent obsoletion warning in cl.el. diff --git a/lisp/obsolete/cl.el b/lisp/obsolete/cl.el index f91cfaa34c..09f9ab7b7f 100644 --- a/lisp/obsolete/cl.el +++ b/lisp/obsolete/cl.el @@ -438,7 +438,7 @@ definitions, or lack thereof). (let ((func `(cl-function (lambda ,(cadr x) (cl-block ,(car x) ,@(cddr x)))))) - (when (cl--compiling-file) + (when (macroexp-compiling-p) ;; Bug#411. It would be nice to fix this. (and (get (car x) 'byte-compile) (error "Byte-compiling a redefinition of `%s' \ commit 2bbc2262cd0c4629ec8fc517e6cc5a387913e8cc Author: Basil L. Contovounesios Date: Wed Feb 24 22:20:10 2021 +0000 ; Add :version tags to recent newsticker options. diff --git a/lisp/net/newst-treeview.el b/lisp/net/newst-treeview.el index c0b5e34f68..2e207be20f 100644 --- a/lisp/net/newst-treeview.el +++ b/lisp/net/newst-treeview.el @@ -122,12 +122,14 @@ applies to newsticker only." (defcustom newsticker-treeview-use-feed-name-from-url-list-in-treeview t "Use the feed names from 'newsticker-url-list' for display in treeview." + :version "28.1" :type 'boolean :group 'newsticker-treeview) (defcustom newsticker-treeview-use-feed-name-from-url-list-in-itemview t "Use feed names from 'newsticker-url-list' in itemview." + :version "28.1" :type 'boolean :group 'newsticker-treeview) commit b7f67d432ba9d4a3247fa9553093ab1db82e00fe Author: Stefan Monnier Date: Wed Feb 24 17:16:00 2021 -0500 * lisp/emacs-lisp/macroexp.el (macroexp-file-name): Work in `eval-buffer` Rely on `current-load-list` instead of `load-file-name`. * lisp/emacs-lisp/bytecomp.el (byte-compile-close-variables): Change the var we override accordingly. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 26fab31b96..7aae8c0c6a 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -1731,7 +1731,7 @@ It is too wide if it has any lines longer than the largest of ;; This is used in `macroexp-file-name' to make sure that ;; loading file A which does (byte-compile-file B) won't ;; cause macro calls in B to think they come from A. - (load-file-name nil) + (current-load-list (list nil)) ) ,@body)) diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index a6b0985e6c..d52aee5a4a 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -127,7 +127,11 @@ A non-nil result is expected to be reliable when called from a macro in order to find the file in which the macro's call was found, and it should be reliable as well when used at the top-level of a file. Other uses risk returning non-nil value that point to the wrong file." - (or load-file-name (bound-and-true-p byte-compile-current-file))) + ;; `eval-buffer' binds `current-load-list' but not `load-file-name', + ;; so prefer using it over using `load-file-name'. + (let ((file (car (last current-load-list)))) + (or (if (stringp file) file) + (bound-and-true-p byte-compile-current-file)))) (defvar macroexp--warned (make-hash-table :test #'equal :weakness 'key)) commit 46b54e5bb42f26a57f6cdbedf83bd80c6c717a4f Author: Lars Ingebrigtsen Date: Wed Feb 24 20:32:09 2021 +0100 Improve quail-update-leim-list-file error messaging * lisp/international/quail.el (quail-update-leim-list-file): Give a better error message. diff --git a/lisp/international/quail.el b/lisp/international/quail.el index 67ea00665f..f52747084b 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el @@ -3066,28 +3066,31 @@ of each directory." ;; Don't get fooled by commented-out code. (while (re-search-forward "^[ \t]*(quail-define-package" nil t) (goto-char (match-beginning 0)) - (condition-case nil - (let ((form (read (current-buffer)))) - (with-current-buffer list-buf - (insert - (format "(register-input-method + (let (form) + (condition-case err + (progn + (setq form (read (current-buffer))) + (with-current-buffer list-buf + (insert + (format "(register-input-method %S %S '%s %S %S %S)\n" - (nth 1 form) ; PACKAGE-NAME - (nth 2 form) ; LANGUAGE - 'quail-use-package ; ACTIVATE-FUNC - (nth 3 form) ; PACKAGE-TITLE - (progn ; PACKAGE-DESCRIPTION (one line) - (string-match ".*" (nth 5 form)) - (match-string 0 (nth 5 form))) - (file-relative-name ; PACKAGE-FILENAME - (file-name-sans-extension (car pkg-list)) - (car dirnames)))))) - (error - ;; Ignore the remaining contents of this file. - (goto-char (point-max)) - (message "Some part of \"%s\" is broken" (car pkg-list)))))) + (nth 1 form) ; PACKAGE-NAME + (nth 2 form) ; LANGUAGE + 'quail-use-package ; ACTIVATE-FUNC + (nth 3 form) ; PACKAGE-TITLE + (progn ; PACKAGE-DESCRIPTION (one line) + (string-match ".*" (nth 5 form)) + (match-string 0 (nth 5 form))) + (file-relative-name ; PACKAGE-FILENAME + (file-name-sans-extension (car pkg-list)) + (car dirnames)))))) + (error + ;; Ignore the remaining contents of this file. + (goto-char (point-max)) + (message "Some part of \"%s\" is broken: %s in %s" + (car pkg-list) err form)))))) (setq pkg-list (cdr pkg-list))) (setq quail-dirs (cdr quail-dirs) dirnames (cdr dirnames)))) commit 8fd97b1de0b1b0b563133cbb4d4f258bbb936257 Author: Lars Ingebrigtsen Date: Wed Feb 24 20:31:31 2021 +0100 Fix warning generated by indian.el + quail.el * lisp/leim/quail/indian.el (quail-define-indian-trans-package): Reintroduce kludge to fix automatic detection by Quail. diff --git a/lisp/leim/quail/indian.el b/lisp/leim/quail/indian.el index 5240393d0c..251b18c988 100644 --- a/lisp/leim/quail/indian.el +++ b/lisp/leim/quail/indian.el @@ -312,7 +312,10 @@ Full key sequences are listed below:") (defun quail-define-inscript-package (char-tables key-tables pkgname lang title docstring) - (quail-define-package pkgname lang title nil docstring + ;; This is a funcall to avoid `quail-update-leim-list-file' + ;; determining that this is a quail definition (it searches for + ;; "(quail-define-package"). + (funcall #'quail-define-package pkgname lang title nil docstring nil nil nil t nil nil nil nil) (let (char-table key-table char key) (while (and char-tables key-tables) commit 65f458ba5eaf7dd2fcd9526b85f3e6a846016171 Author: Juri Linkov Date: Wed Feb 24 20:52:27 2021 +0200 * lisp/tab-bar.el: Move aliases down closer to keybindings. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 3b1fc89f30..c95559a1b7 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -1278,26 +1278,6 @@ and can restore them." (remove-hook 'pre-command-hook 'tab-bar-history--pre-change) (remove-hook 'window-configuration-change-hook 'tab-bar--history-change))) - -;;; Short aliases - -(defalias 'tab-new 'tab-bar-new-tab) -(defalias 'tab-new-to 'tab-bar-new-tab-to) -(defalias 'tab-duplicate 'tab-bar-duplicate-tab) -(defalias 'tab-close 'tab-bar-close-tab) -(defalias 'tab-close-other 'tab-bar-close-other-tabs) -(defalias 'tab-undo 'tab-bar-undo-close-tab) -(defalias 'tab-select 'tab-bar-select-tab) -(defalias 'tab-switch 'tab-bar-switch-to-tab) -(defalias 'tab-next 'tab-bar-switch-to-next-tab) -(defalias 'tab-previous 'tab-bar-switch-to-prev-tab) -(defalias 'tab-last 'tab-bar-switch-to-last-tab) -(defalias 'tab-recent 'tab-bar-switch-to-recent-tab) -(defalias 'tab-move 'tab-bar-move-tab) -(defalias 'tab-move-to 'tab-bar-move-tab-to) -(defalias 'tab-rename 'tab-bar-rename-tab) -(defalias 'tab-list 'tab-switcher) - ;;; Non-graphical access to frame-local tabs (named window configurations) @@ -1703,6 +1683,26 @@ When `switch-to-buffer-obey-display-actions' is non-nil, nil "[other-tab]") (message "Display next command buffer in a new tab...")) + +;;; Short aliases and keybindings + +(defalias 'tab-new 'tab-bar-new-tab) +(defalias 'tab-new-to 'tab-bar-new-tab-to) +(defalias 'tab-duplicate 'tab-bar-duplicate-tab) +(defalias 'tab-close 'tab-bar-close-tab) +(defalias 'tab-close-other 'tab-bar-close-other-tabs) +(defalias 'tab-undo 'tab-bar-undo-close-tab) +(defalias 'tab-select 'tab-bar-select-tab) +(defalias 'tab-switch 'tab-bar-switch-to-tab) +(defalias 'tab-next 'tab-bar-switch-to-next-tab) +(defalias 'tab-previous 'tab-bar-switch-to-prev-tab) +(defalias 'tab-last 'tab-bar-switch-to-last-tab) +(defalias 'tab-recent 'tab-bar-switch-to-recent-tab) +(defalias 'tab-move 'tab-bar-move-tab) +(defalias 'tab-move-to 'tab-bar-move-tab-to) +(defalias 'tab-rename 'tab-bar-rename-tab) +(defalias 'tab-list 'tab-switcher) + (define-key tab-prefix-map "n" 'tab-duplicate) (define-key tab-prefix-map "N" 'tab-new-to) (define-key tab-prefix-map "2" 'tab-new) commit 24be523fde01e61ab8bff785f272645b59dc60f3 Author: Juri Linkov Date: Wed Feb 24 20:51:04 2021 +0200 * lisp/tab-bar.el (tab-switch): New defalias to 'tab-bar-switch-to-tab'. (tab-prefix-map): Bind "O" to 'tab-previous'. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 0893a98e60..3b1fc89f30 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -1288,6 +1288,7 @@ and can restore them." (defalias 'tab-close-other 'tab-bar-close-other-tabs) (defalias 'tab-undo 'tab-bar-undo-close-tab) (defalias 'tab-select 'tab-bar-select-tab) +(defalias 'tab-switch 'tab-bar-switch-to-tab) (defalias 'tab-next 'tab-bar-switch-to-next-tab) (defalias 'tab-previous 'tab-bar-switch-to-prev-tab) (defalias 'tab-last 'tab-bar-switch-to-last-tab) @@ -1708,10 +1709,11 @@ When `switch-to-buffer-obey-display-actions' is non-nil, (define-key tab-prefix-map "1" 'tab-close-other) (define-key tab-prefix-map "0" 'tab-close) (define-key tab-prefix-map "o" 'tab-next) +(define-key tab-prefix-map "O" 'tab-previous) (define-key tab-prefix-map "m" 'tab-move) (define-key tab-prefix-map "M" 'tab-move-to) (define-key tab-prefix-map "r" 'tab-rename) -(define-key tab-prefix-map "\r" 'tab-bar-select-tab-by-name) +(define-key tab-prefix-map "\r" 'tab-switch) (define-key tab-prefix-map "b" 'switch-to-buffer-other-tab) (define-key tab-prefix-map "f" 'find-file-other-tab) (define-key tab-prefix-map "\C-f" 'find-file-other-tab) commit 2766f9fdb95a1a4418020d32ce3f0cbd262f7cee Author: Stefan Monnier Date: Wed Feb 24 13:52:45 2021 -0500 * lisp/emacs-lisp/macroexp.el (macroexp-file-name): New function. Yes, finally: a function that tells you the name of the file where the code is located. Finding this name is non-trivial in practice, as evidenced by the "4 shift/reduce conflicts" warning when compiling CEDET's python.el, because its `wisent-source` got it wrong in that case, thinking the grammar came from `python.el` instead of `python-wy.el`. While at it, also made `macroexp-compiling-p` public, since it's useful at various places. (macroexp-compiling-p): Rename from `macroexp--compiling-p`. * lisp/emacs-lisp/bytecomp.el (byte-compile-close-variables): Bind `load-file-name` to nil so we can distinguish a load that calls the byte compiler from a byte compilation which causes a load. * lisp/cedet/semantic/wisent/python.el (wisent-python--expected-conflicts): Remove; it was just a workaround. * lisp/subr.el (do-after-load-evaluation): Avoid `byte-compile--` vars. * lisp/cedet/semantic/fw.el (semantic-alias-obsolete): Use `macroexp-compiling-p` and `macroexp-file-name`. * lisp/cedet/semantic/wisent/comp.el (wisent-source): Use `macroexp-file-name` (wisent-total-conflicts): Tighten regexp. * lisp/emacs-lisp/cl-lib.el (cl--compiling-file): Delete function and variable. Use `macroexp-compiling-p` instead. * lisp/progmodes/flymake.el (flymake-log): * lisp/emacs-lisp/package.el (package-get-version): * lisp/emacs-lisp/ert-x.el (ert-resource-directory): Use `macroexp-file-name`. diff --git a/etc/NEWS b/etc/NEWS index 2bad41f5ee..caa366aaef 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -369,6 +369,12 @@ the buffer cycles the whole buffer between "only top-level headings", * Changes in Specialized Modes and Packages in Emacs 28.1 +** Macroexp +--- +*** New function 'macroexp-file-name' to know the name of the current file +--- +*** New function 'macroexp-compiling-p' to know if we're compiling. + ** 'blink-cursor-mode' is now enabled by default regardless of the UI. It used to be enabled when Emacs is started in GUI mode but not when started in text mode. The cursor still only actually blinks in GUI frames. diff --git a/lisp/cedet/semantic/fw.el b/lisp/cedet/semantic/fw.el index 91944c44f5..3c36c6cb9f 100644 --- a/lisp/cedet/semantic/fw.el +++ b/lisp/cedet/semantic/fw.el @@ -189,14 +189,13 @@ will throw a warning when it encounters this symbol." (when (and (mode-local--function-overload-p newfn) (not (mode-local--overload-obsoleted-by newfn)) ;; Only throw this warning when byte compiling things. - (boundp 'byte-compile-current-file) - byte-compile-current-file - (not (string-match "cedet" byte-compile-current-file)) + (macroexp-compiling-p) + (not (string-match "cedet" (macroexp-file-name))) ) (make-obsolete-overload oldfnalias newfn when) (byte-compile-warn "%s: `%s' obsoletes overload `%s'" - byte-compile-current-file + (macroexp-file-name) newfn (with-suppressed-warnings ((obsolete semantic-overload-symbol-from-function)) (semantic-overload-symbol-from-function oldfnalias))))) @@ -211,8 +210,7 @@ will throw a warning when it encounters this symbol." (defvaralias oldvaralias newvar) (error ;; Only throw this warning when byte compiling things. - (when (and (boundp 'byte-compile-current-file) - byte-compile-current-file) + (when (macroexp-compiling-p) (byte-compile-warn "variable `%s' obsoletes, but isn't alias of `%s'" newvar oldvaralias) diff --git a/lisp/cedet/semantic/wisent/comp.el b/lisp/cedet/semantic/wisent/comp.el index 755d30a371..7a64fe2fec 100644 --- a/lisp/cedet/semantic/wisent/comp.el +++ b/lisp/cedet/semantic/wisent/comp.el @@ -159,13 +159,9 @@ Its name is defined in constant `wisent-log-buffer-name'." '(with-current-buffer (wisent-log-buffer) (erase-buffer))) -(defvar byte-compile-current-file) - (defun wisent-source () "Return the current source file name or nil." - (let ((source (or (and (boundp 'byte-compile-current-file) - byte-compile-current-file) - load-file-name (buffer-file-name)))) + (let ((source (macroexp-file-name))) (if source (file-relative-name source)))) @@ -2241,7 +2237,7 @@ there are any reduce/reduce conflicts." ;; output warnings. (and src (intern (format "wisent-%s--expected-conflicts" - (replace-regexp-in-string "\\.el$" "" src)))))) + (replace-regexp-in-string "\\.el\\'" "" src)))))) (when (or (not (zerop rrc-total)) (and (not (zerop src-total)) (not (= src-total (or wisent-expected-conflicts 0))) diff --git a/lisp/cedet/semantic/wisent/python.el b/lisp/cedet/semantic/wisent/python.el index 74f190c086..7769ad1961 100644 --- a/lisp/cedet/semantic/wisent/python.el +++ b/lisp/cedet/semantic/wisent/python.el @@ -33,11 +33,6 @@ ;; for optional functionality (require 'python nil t) -;; Tell wisent how many shift/reduce conflicts are to be expected by -;; this grammar. -(eval-and-compile - (defconst wisent-python--expected-conflicts 4)) - (require 'semantic/wisent) (require 'semantic/wisent/python-wy) (require 'semantic/find) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index c0683babcf..26fab31b96 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -1727,6 +1727,11 @@ It is too wide if it has any lines longer than the largest of ;; (byte-compile-generate-emacs19-bytecodes ;; byte-compile-generate-emacs19-bytecodes) (byte-compile-warnings byte-compile-warnings) + ;; Indicate that we're not currently loading some file. + ;; This is used in `macroexp-file-name' to make sure that + ;; loading file A which does (byte-compile-file B) won't + ;; cause macro calls in B to think they come from A. + (load-file-name nil) ) ,@body)) diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el index f06452ea17..7f7eb96342 100644 --- a/lisp/emacs-lisp/cl-lib.el +++ b/lisp/emacs-lisp/cl-lib.el @@ -232,13 +232,8 @@ one value. ;;; Declarations. -(defvar cl--compiling-file nil) -(defun cl--compiling-file () - (or cl--compiling-file - (and (boundp 'byte-compile--outbuffer) - (bufferp (symbol-value 'byte-compile--outbuffer)) - (equal (buffer-name (symbol-value 'byte-compile--outbuffer)) - " *Compiler Output*")))) +(define-obsolete-function-alias 'cl--compiling-file + #'macroexp-compiling-p "28.1") (defvar cl--proclaims-deferred nil) @@ -253,7 +248,7 @@ one value. Puts `(cl-eval-when (compile load eval) ...)' around the declarations so that they are registered at compile-time as well as run-time." (let ((body (mapcar (lambda (x) `(cl-proclaim ',x)) specs))) - (if (cl--compiling-file) `(cl-eval-when (compile load eval) ,@body) + (if (macroexp-compiling-p) `(cl-eval-when (compile load eval) ,@body) `(progn ,@body)))) ; Avoid loading cl-macs.el for cl-eval-when. diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index b9a8a3f112..b852d825c7 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -545,7 +545,7 @@ its argument list allows full Common Lisp conventions." (let ((p (memq '&body args))) (if p (setcar p '&rest))) (if (memq '&environment args) (error "&environment used incorrectly")) (let ((restarg (memq '&rest args)) - (safety (if (cl--compiling-file) cl--optimize-safety 3)) + (safety (if (macroexp-compiling-p) cl--optimize-safety 3)) (keys t) (laterarg nil) (exactarg nil) minarg) (or num (setq num 0)) @@ -709,7 +709,7 @@ If `eval' is in WHEN, BODY is evaluated when interpreted or at non-top-level. \(fn (WHEN...) BODY...)" (declare (indent 1) (debug (sexp body))) - (if (and (fboundp 'cl--compiling-file) (cl--compiling-file) + (if (and (macroexp-compiling-p) (not cl--not-toplevel) (not (boundp 'for-effect))) ;Horrible kludge. (let ((comp (or (memq 'compile when) (memq :compile-toplevel when))) (cl--not-toplevel t)) @@ -738,7 +738,7 @@ If `eval' is in WHEN, BODY is evaluated when interpreted or at non-top-level. "Like `progn', but evaluates the body at load time. The result of the body appears to the compiler as a quoted constant." (declare (debug (form &optional sexp))) - (if (cl--compiling-file) + (if (macroexp-compiling-p) (let* ((temp (cl-gentemp "--cl-load-time--")) (set `(setq ,temp ,form))) (if (and (fboundp 'byte-compile-file-form-defmumble) @@ -2455,7 +2455,7 @@ values. For compatibility, (cl-values A B C) is a synonym for (list A B C). (defmacro cl-the (type form) "Return FORM. If type-checking is enabled, assert that it is of TYPE." (declare (indent 1) (debug (cl-type-spec form))) - (if (not (or (not (cl--compiling-file)) + (if (not (or (not (macroexp-compiling-p)) (< cl--optimize-speed 3) (= cl--optimize-safety 3))) form @@ -2522,7 +2522,7 @@ For instance will turn off byte-compile warnings in the function. See Info node `(cl)Declarations' for details." - (if (cl--compiling-file) + (if (macroexp-compiling-p) (while specs (if (listp cl--declare-stack) (push (car specs) cl--declare-stack)) (cl--do-proclaim (pop specs) nil))) @@ -2859,7 +2859,7 @@ Supported keywords for slots are: (copier (intern (format "copy-%s" name))) (predicate (intern (format "%s-p" name))) (print-func nil) (print-auto nil) - (safety (if (cl--compiling-file) cl--optimize-safety 3)) + (safety (if (macroexp-compiling-p) cl--optimize-safety 3)) (include nil) ;; There are 4 types of structs: ;; - `vector' type: means we should use a vector, which can come @@ -3263,7 +3263,7 @@ does not contain SLOT-NAME." "Return non-nil if SYM will be bound when we run the code. Of course, we really can't know that for sure, so it's just a heuristic." (or (fboundp sym) - (and (cl--compiling-file) + (and (macroexp-compiling-p) (or (cdr (assq sym byte-compile-function-environment)) (cdr (assq sym byte-compile-macro-environment)))))) @@ -3359,7 +3359,7 @@ Of course, we really can't know that for sure, so it's just a heuristic." "Verify that FORM is of type TYPE; signal an error if not. STRING is an optional description of the desired type." (declare (debug (place cl-type-spec &optional stringp))) - (and (or (not (cl--compiling-file)) + (and (or (not (macroexp-compiling-p)) (< cl--optimize-speed 3) (= cl--optimize-safety 3)) (macroexp-let2 macroexp-copyable-p temp form `(progn (or (cl-typep ,temp ',type) @@ -3379,7 +3379,7 @@ Other args STRING and ARGS... are arguments to be passed to `error'. They are not evaluated unless the assertion fails. If STRING is omitted, a default message listing FORM itself is used." (declare (debug (form &rest form))) - (and (or (not (cl--compiling-file)) + (and (or (not (macroexp-compiling-p)) (< cl--optimize-speed 3) (= cl--optimize-safety 3)) (let ((sargs (and show-args (delq nil (mapcar (lambda (x) diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index a095ad0f6d..d3e5d03edb 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -233,7 +233,7 @@ This method is obsolete." ,@(when eieio-backward-compatibility (let ((f (intern (format "%s-child-p" name)))) - `((defalias ',f ',testsym2) + `((defalias ',f #',testsym2) (make-obsolete ',f ,(format "use (cl-typep ... \\='%s) instead" name) "25.1")))) @@ -288,8 +288,8 @@ created by the :initarg tag." (declare (debug (form symbolp))) `(eieio-oref ,obj (quote ,slot))) -(defalias 'slot-value 'eieio-oref) -(defalias 'set-slot-value 'eieio-oset) +(defalias 'slot-value #'eieio-oref) +(defalias 'set-slot-value #'eieio-oset) (make-obsolete 'set-slot-value "use (setf (slot-value ..) ..) instead" "25.1") (defmacro oref-default (obj slot) @@ -418,7 +418,7 @@ If EXTRA, include that in the string returned to represent the symbol." (cl-check-type obj eieio-object) (eieio-class-name (eieio--object-class obj))) (define-obsolete-function-alias - 'object-class-name 'eieio-object-class-name "24.4") + 'object-class-name #'eieio-object-class-name "24.4") (defun eieio-class-parents (class) ;; FIXME: What does "(overload of variable)" mean here? @@ -446,7 +446,7 @@ The CLOS function `class-direct-subclasses' is aliased to this function." (defmacro eieio-class-parent (class) "Return first parent class to CLASS. (overload of variable)." `(car (eieio-class-parents ,class))) -(define-obsolete-function-alias 'class-parent 'eieio-class-parent "24.4") +(define-obsolete-function-alias 'class-parent #'eieio-class-parent "24.4") (defun same-class-p (obj class) "Return t if OBJ is of class-type CLASS." @@ -461,7 +461,7 @@ The CLOS function `class-direct-subclasses' is aliased to this function." ;; class will be checked one layer down (child-of-class-p (eieio--object-class obj) class)) ;; Backwards compatibility -(defalias 'obj-of-class-p 'object-of-class-p) +(defalias 'obj-of-class-p #'object-of-class-p) (defun child-of-class-p (child class) "Return non-nil if CHILD class is a subclass of CLASS." @@ -665,7 +665,7 @@ This class is not stored in the `parent' slot of a class vector." (setq eieio-default-superclass (cl--find-class 'eieio-default-superclass)) (define-obsolete-function-alias 'standard-class - 'eieio-default-superclass "26.1") + #'eieio-default-superclass "26.1") (cl-defgeneric make-instance (class &rest initargs) "Make a new instance of CLASS based on INITARGS. @@ -972,12 +972,12 @@ this object." This may create or delete slots, but does not affect the return value of `eq'." (error "EIEIO: `change-class' is unimplemented")) -(define-obsolete-function-alias 'change-class 'eieio-change-class "26.1") +(define-obsolete-function-alias 'change-class #'eieio-change-class "26.1") ;; Hook ourselves into help system for describing classes and methods. ;; FIXME: This is not actually needed any more since we can click on the ;; hyperlink from the constructor's docstring to see the type definition. -(add-hook 'help-fns-describe-function-functions 'eieio-help-constructor) +(add-hook 'help-fns-describe-function-functions #'eieio-help-constructor) (provide 'eieio) diff --git a/lisp/emacs-lisp/ert-x.el b/lisp/emacs-lisp/ert-x.el index bf9aff67a6..1191fb8f8d 100644 --- a/lisp/emacs-lisp/ert-x.el +++ b/lisp/emacs-lisp/ert-x.el @@ -367,8 +367,7 @@ different resource directory naming scheme, set the variable name will be trimmed using `string-trim' with arguments `ert-resource-directory-trim-left-regexp' and `ert-resource-directory-trim-right-regexp'." - `(let* ((testfile ,(or (bound-and-true-p byte-compile-current-file) - (and load-in-progress load-file-name) + `(let* ((testfile ,(or (macroexp-file-name) buffer-file-name)) (default-directory (file-name-directory testfile))) (file-truename diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index 0934e43e66..a6b0985e6c 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -112,7 +112,7 @@ and also to avoid outputting the warning during normal execution." (funcall (eval (cadr form))) (byte-compile-constant nil))) -(defun macroexp--compiling-p () +(defun macroexp-compiling-p () "Return non-nil if we're macroexpanding for the compiler." ;; FIXME: ¡¡Major Ugly Hack!! To determine whether the output of this ;; macro-expansion will be processed by the byte-compiler, we check @@ -120,13 +120,22 @@ and also to avoid outputting the warning during normal execution." (member '(declare-function . byte-compile-macroexpand-declare-function) macroexpand-all-environment)) +(defun macroexp-file-name () + "Return the name of the file from which the code comes. +Returns nil when we do not know. +A non-nil result is expected to be reliable when called from a macro in order +to find the file in which the macro's call was found, and it should be +reliable as well when used at the top-level of a file. +Other uses risk returning non-nil value that point to the wrong file." + (or load-file-name (bound-and-true-p byte-compile-current-file))) + (defvar macroexp--warned (make-hash-table :test #'equal :weakness 'key)) (defun macroexp--warn-and-return (msg form &optional compile-only) (let ((when-compiled (lambda () (byte-compile-warn "%s" msg)))) (cond ((null msg) form) - ((macroexp--compiling-p) + ((macroexp-compiling-p) (if (and (consp form) (gethash form macroexp--warned)) ;; Already wrapped this exp with a warning: avoid inf-looping ;; where we keep adding the same warning onto `form' because diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 092befa1f2..c81992145d 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -4024,10 +4024,7 @@ The return value is a string (or nil in case we can't find it)." ;; the version at compile time and hardcodes it into the .elc file! (declare (pure t)) ;; Hack alert! - (let ((file - (or (if (boundp 'byte-compile-current-file) byte-compile-current-file) - load-file-name - buffer-file-name))) + (let ((file (or (macroexp-file-name) buffer-file-name))) (cond ((null file) nil) ;; Packages are normally installed into directories named "-", diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index d01803282a..bd308e0220 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -287,8 +287,7 @@ LEVEL is passed to `display-warning', which is used to display the warning. If this form is included in a byte-compiled file, the generated warning contains an indication of the file that generated it." - (let* ((compile-file (and (boundp 'byte-compile-current-file) - (symbol-value 'byte-compile-current-file))) + (let* ((compile-file (macroexp-file-name)) (sublog (if (and compile-file (not load-file-name)) diff --git a/lisp/subr.el b/lisp/subr.el index 2ad31b656e..cc8b85b1d3 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2097,7 +2097,7 @@ can do the job." ,(if append `(setq ,sym (append ,sym (list ,x))) `(push ,x ,sym)))))) - (if (not (macroexp--compiling-p)) + (if (not (macroexp-compiling-p)) code `(progn (macroexp--funcall-if-compiled ',warnfun) @@ -3335,7 +3335,7 @@ to `accept-change-group' or `cancel-change-group'." ;; insertions are ever merged/combined, so we use such a "boundary" ;; only when the last change was an insertion and we use the position ;; of the last insertion. - (when (numberp (caar buffer-undo-list)) + (when (numberp (car-safe (car buffer-undo-list))) (push (cons (caar buffer-undo-list) (caar buffer-undo-list)) buffer-undo-list)))))) @@ -5045,14 +5045,10 @@ This function is called directly from the C code." obarray)) (msg (format "Package %s is deprecated" package)) (fun (lambda (msg) (message "%s" msg)))) - ;; Cribbed from cl--compiling-file. (when (or (not (fboundp 'byte-compile-warning-enabled-p)) (byte-compile-warning-enabled-p 'obsolete package)) (cond - ((and (boundp 'byte-compile--outbuffer) - (bufferp (symbol-value 'byte-compile--outbuffer)) - (equal (buffer-name (symbol-value 'byte-compile--outbuffer)) - " *Compiler Output*")) + ((bound-and-true-p byte-compile-current-file) ;; Don't warn about obsolete files using other obsolete files. (unless (and (stringp byte-compile-current-file) (string-match-p "/obsolete/[^/]*\\'" commit 654cb8e6b7fbdca32f07609cafe906e2470cc73d Author: Ulf Jasper Date: Wed Feb 24 19:26:37 2021 +0100 Add options to use feed names from newticker-url-list * lisp/net/newst-treeview.el (newsticker-treeview-use-feed-name-from-url-list-in-treeview): New. (newsticker-treeview-use-feed-name-from-url-list-in-itemview): New. (newsticker--treeview-item-show): Show feed name from newsticker-url-list if wanted. (newsticker--treeview-propertize-tag): Add argument 'tooltip'. (newsticker--treeview-tree-get-tag): Usefeed name from newsticker-url-list if wanted. (Fixes third issue in Bug#41376.) diff --git a/lisp/net/newst-treeview.el b/lisp/net/newst-treeview.el index 618a791c57..c0b5e34f68 100644 --- a/lisp/net/newst-treeview.el +++ b/lisp/net/newst-treeview.el @@ -119,6 +119,18 @@ applies to newsticker only." :type 'boolean :group 'newsticker-treeview) +(defcustom newsticker-treeview-use-feed-name-from-url-list-in-treeview + t + "Use the feed names from 'newsticker-url-list' for display in treeview." + :type 'boolean + :group 'newsticker-treeview) + +(defcustom newsticker-treeview-use-feed-name-from-url-list-in-itemview + t + "Use feed names from 'newsticker-url-list' in itemview." + :type 'boolean + :group 'newsticker-treeview) + (defvar newsticker-groups '("Feeds") "List of feed groups, used in the treeview frontend. @@ -738,11 +750,14 @@ for the button." (img (newsticker--image-read feed-name-symbol nil 40))) (if (and (display-images-p) img) (newsticker--insert-image img (car item)) - (insert (newsticker--real-feed-name feed-name-symbol)))) + (insert (if newsticker-treeview-use-feed-name-from-url-list-in-itemview + (symbol-name feed-name-symbol) + (newsticker--real-feed-name feed-name-symbol))))) (add-text-properties (point-min) (point) (list 'face 'newsticker-feed-face 'mouse-face 'highlight - 'help-echo "Visit in web browser." + 'help-echo (concat (newsticker--real-feed-name feed-name-symbol) + "\nClick to visit in web browser.") :nt-link (newsticker--link item) 'keymap newsticker--treeview-url-keymap)) (setq pos (point)) @@ -933,10 +948,10 @@ Optional arguments CHANGED-WIDGET and EVENT are ignored." (newsticker-treeview-mode))) (defun newsticker--treeview-propertize-tag (tag &optional num-new nt-id feed - vfeed) + vfeed tooltip) "Return propertized copy of string TAG. Optional argument NUM-NEW is used for choosing face, other -arguments NT-ID, FEED, and VFEED are added as properties." +arguments NT-ID, FEED, VFEED and TOOLTIP are added as properties." ;;(message "newsticker--treeview-propertize-tag `%s' %s" feed nt-id) (let ((face 'newsticker-treeview-face) (map (make-sparse-keymap))) @@ -950,14 +965,14 @@ arguments NT-ID, FEED, and VFEED are added as properties." :nt-id nt-id :nt-feed feed :nt-vfeed vfeed - 'help-echo tag + 'help-echo tooltip 'mouse-face 'highlight))) (defun newsticker--treeview-tree-get-tag (feed-name vfeed-name &optional nt-id) "Return a tag string for either FEED-NAME or, if it is nil, for VFEED-NAME. Optional argument NT-ID is added to the tag's properties." - (let (tag (num-new 0)) + (let (tag tooltip (num-new 0)) (cond (vfeed-name (cond ((string= vfeed-name "new") (setq num-new (newsticker--stat-num-items-total 'new)) @@ -970,18 +985,29 @@ Optional argument NT-ID is added to the tag's properties." (setq tag (format "Obsolete items (%d)" num-new))) ((string= vfeed-name "all") (setq num-new (newsticker--stat-num-items-total)) - (setq tag (format "All items (%d)" num-new))))) + (setq tag (format "All items (%d)" num-new)))) + (setq tooltip tag)) (feed-name (setq num-new (newsticker--stat-num-items-for-group (intern feed-name) 'new 'immortal)) (setq tag (format "%s (%d)" - (newsticker--real-feed-name (intern feed-name)) - num-new)))) + (if newsticker-treeview-use-feed-name-from-url-list-in-itemview + feed-name + (newsticker--real-feed-name (intern feed-name))) + num-new)) + (setq tooltip + (if (newsticker--group-get-group feed-name) + tag + (format "%s (%d)\n%s" + feed-name + num-new + (newsticker--real-feed-name (intern feed-name))))))) (if tag (newsticker--treeview-propertize-tag tag num-new nt-id - feed-name vfeed-name)))) + feed-name vfeed-name + tooltip)))) (defun newsticker--stat-num-items-for-group (feed-name-symbol &rest ages) "Count number of items in feed FEED-NAME-SYMBOL that have an age matching AGES." commit 1f5ed3edc6244a26697ff5584431ff546aeaf9a4 Author: Lars Ingebrigtsen Date: Wed Feb 24 18:29:25 2021 +0100 Fix wisent/python.el grammar warning * lisp/cedet/semantic/wisent/python.el: Fix warning about shift/reduce conflicts in the Python grammar. diff --git a/lisp/cedet/semantic/wisent/python.el b/lisp/cedet/semantic/wisent/python.el index 7769ad1961..74f190c086 100644 --- a/lisp/cedet/semantic/wisent/python.el +++ b/lisp/cedet/semantic/wisent/python.el @@ -33,6 +33,11 @@ ;; for optional functionality (require 'python nil t) +;; Tell wisent how many shift/reduce conflicts are to be expected by +;; this grammar. +(eval-and-compile + (defconst wisent-python--expected-conflicts 4)) + (require 'semantic/wisent) (require 'semantic/wisent/python-wy) (require 'semantic/find) commit d56fbc375d46d2adf681a50ebbf6e9edee2a99f2 Author: Lars Ingebrigtsen Date: Wed Feb 24 18:13:03 2021 +0100 Fix warning generated by indian.el + quail.el * lisp/leim/quail/indian.el (quail-define-indian-trans-package): Reintroduce kludge to fix automatic detection by Quail. diff --git a/lisp/leim/quail/indian.el b/lisp/leim/quail/indian.el index 2e36508273..5240393d0c 100644 --- a/lisp/leim/quail/indian.el +++ b/lisp/leim/quail/indian.el @@ -39,7 +39,10 @@ (defun quail-define-indian-trans-package (hashtbls pkgname lang title doc) - (quail-define-package pkgname lang title t doc + ;; This is a funcall to avoid `quail-update-leim-list-file' + ;; determining that this is a quail definition (it searches for + ;; "(quail-define-package"). + (funcall #'quail-define-package pkgname lang title t doc nil nil nil nil nil nil t nil) (maphash (lambda (key val) commit b0b4609be03dc2fdbaf8350b9572a56303a27a61 Author: Lars Ingebrigtsen Date: Wed Feb 24 17:58:38 2021 +0100 Remove the "Documentation:" line from the variable help * lisp/help-fns.el (describe-variable): Remove the "Documentation:" line (bug#46702). This makes the help text more compact and seems easier to read, too. diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 7244695094..290bebf7e5 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -1162,7 +1162,6 @@ it is displayed along with the global value." (with-current-buffer standard-output (help-fns--ensure-empty-line)) - (princ "Documentation:\n") (with-current-buffer standard-output (insert (or doc "Not documented as a variable.")))) commit e21d6fdb2ce249e1b2b22bfa7778e486ff141222 Author: Lars Ingebrigtsen Date: Wed Feb 24 17:53:53 2021 +0100 Fix Calc menu item for vector dot products * lisp/calc/calc-menu.el (calc-vectors-menu): Use the correct function `calc-times' instead of the non-existent `calc-mult' function (bug#46710). diff --git a/lisp/calc/calc-menu.el b/lisp/calc/calc-menu.el index 16cca05533..ac14e36c63 100644 --- a/lisp/calc/calc-menu.el +++ b/lisp/calc/calc-menu.el @@ -781,7 +781,7 @@ :active (>= (calc-stack-size) 2) :help "The cross product in R^3"] ["(2:) dot (1:)" - calc-mult + calc-times :keys "*" :active (>= (calc-stack-size) 2) :help "The dot product"] commit b7a2b2bdd9ced60e1b59207935f67c05ea707f3d Author: Doug Davis Date: Wed Feb 24 17:43:49 2021 +0100 Interactive tag byte compilation functions in emacs-lisp-mode * lisp/progmodes/elisp-mode.el (emacs-lisp-byte-compile) (emacs-lisp-byte-compile-and-load): Add interactive tagging (bug#46721). diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 397eb269a7..20c7f20d04 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -182,14 +182,14 @@ All commands in `lisp-mode-shared-map' are inherited by this map.") (defun emacs-lisp-byte-compile () "Byte compile the file containing the current buffer." - (interactive) + (interactive nil emacs-lisp-mode) (if buffer-file-name (byte-compile-file buffer-file-name) (error "The buffer must be saved in a file first"))) (defun emacs-lisp-byte-compile-and-load () "Byte-compile the current file (if it has changed), then load compiled code." - (interactive) + (interactive nil emacs-lisp-mode) (or buffer-file-name (error "The buffer must be saved in a file first")) (require 'bytecomp) commit a2a63642656ff9bc851b40909458f9f79c104c5e Author: Miha Rihtaršič Date: Wed Feb 24 17:38:56 2021 +0100 Run all functions in `prefix-command-echo-keystrokes-functions' * lisp/simple.el (internal-echo-keystrokes-prefix): Really run all functions in `prefix-command-echo-keystrokes-functions' (bug#46727). Copyright-paperwork-exempt: yes diff --git a/lisp/simple.el b/lisp/simple.el index 1dfc3374ad..403861351c 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -4670,7 +4670,7 @@ see other processes running on the system, use `list-system-processes'." (setq prefix-command--last-echo (let ((strs nil)) (run-hook-wrapped 'prefix-command-echo-keystrokes-functions - (lambda (fun) (push (funcall fun) strs))) + (lambda (fun) (push (funcall fun) strs) nil)) (setq strs (delq nil strs)) (when strs (mapconcat #'identity strs " ")))))) commit 7c48c83dabeabc807acf4b84d1a0fc6a2ee5ae87 Author: Protesilaos Stavrou Date: Wed Feb 24 17:18:26 2021 +0100 Use named faces in shortdoc * shortdoc.el (shortdoc-heading): Define new face for headings. (shortdoc-display-group): Apply new heading face. (shortdoc--display-function): Use existing face for section text. * etc/NEWS: Document new face (bug#46748). diff --git a/etc/NEWS b/etc/NEWS index 5df8ee140c..2bad41f5ee 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1734,6 +1734,10 @@ If this is bound to something non-nil, functions like This is a plain 2D button, but uses the background color instead of the foreground color. +--- +*** New face 'shortdoc-heading'. +Applies to headings of shortdoc sections. + +++ *** New predicate functions 'length<', 'length>' and 'length='. Using these functions may be more efficient than using 'length' (if diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index 39e69f5aab..789d6325e9 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -40,6 +40,11 @@ (t :height 0.1 :inverse-video t :extend t)) "Face used to separate sections.") +(defface shortdoc-heading + '((t :inherit variable-pitch :height 1.3 :weight bold)) + "Face used for a heading." + :version "28.1") + (defface shortdoc-section '((t :inherit variable-pitch)) "Face used for a section.") @@ -1107,7 +1112,7 @@ There can be any number of :example/:result elements." (insert "\n")) (insert (propertize (concat (substitute-command-keys data) "\n\n") - 'face '(variable-pitch (:height 1.3 :weight bold)) + 'face 'shortdoc-heading 'shortdoc-section t))) ;; There may be functions not yet defined in the data. ((fboundp (car data)) @@ -1175,7 +1180,7 @@ function's documentation in the Info manual"))) (prin1 value (current-buffer))) (insert "\n " single-arrow " " (propertize "[it depends]" - 'face 'variable-pitch) + 'face 'shortdoc-section) "\n")) (:no-value (if (stringp value) commit 4aa9db733730a6780c244fcaf6f51b73fd84777e Author: Utkarsh Singh Date: Tue Feb 23 16:41:14 2021 +0100 Use sh-mode for PKGBUILD files * lisp/files.el (auto-mode-alist): Use sh-mode for PKGBUILD files (bug#46660). Copyright-paperwork-exempt: yes diff --git a/lisp/files.el b/lisp/files.el index 68e883513c..68894ca2ce 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -2723,6 +2723,7 @@ since only a single case-insensitive search through the alist is made." ("\\.scm\\.[0-9]*\\'" . scheme-mode) ("\\.[ckz]?sh\\'\\|\\.shar\\'\\|/\\.z?profile\\'" . sh-mode) ("\\.bash\\'" . sh-mode) + ("/PKGBUILD\\'" . sh-mode) ("\\(/\\|\\`\\)\\.\\(bash_\\(profile\\|history\\|log\\(in\\|out\\)\\)\\|z?log\\(in\\|out\\)\\)\\'" . sh-mode) ("\\(/\\|\\`\\)\\.\\(shrc\\|zshrc\\|m?kshrc\\|bashrc\\|t?cshrc\\|esrc\\)\\'" . sh-mode) ("\\(/\\|\\`\\)\\.\\([kz]shenv\\|xinitrc\\|startxrc\\|xsession\\)\\'" . sh-mode) commit ac45f314547ed9904ddc387157d3f4ba0c5fe1d2 Author: Eli Zaretskii Date: Wed Feb 24 17:55:28 2021 +0200 Fix dangerous code in xdisp.c * src/xdisp.c (move_it_to, display_line): Make sure ZV_BYTE is greater than 1 before fetching previous byte. diff --git a/src/xdisp.c b/src/xdisp.c index cd3455aefc..cc0a689ba3 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10052,7 +10052,7 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos && (IT_CHARPOS (*it) > to_charpos || (IT_CHARPOS (*it) == to_charpos && to_charpos == ZV - && FETCH_BYTE (ZV_BYTE - 1) != '\n'))) + && (ZV_BYTE <= 1 || FETCH_BYTE (ZV_BYTE - 1) != '\n')))) { reached = 9; goto out; @@ -24118,7 +24118,8 @@ display_line (struct it *it, int cursor_vpos) the logical order. */ if (IT_BYTEPOS (*it) > BEG_BYTE) row->ends_at_zv_p = - IT_BYTEPOS (*it) >= ZV_BYTE && FETCH_BYTE (ZV_BYTE - 1) != '\n'; + IT_BYTEPOS (*it) >= ZV_BYTE + && (ZV_BYTE <= 1 || FETCH_BYTE (ZV_BYTE - 1) != '\n'); else row->ends_at_zv_p = false; break; commit eef185dfc82330198b77b46cf7e48f8142c55ea2 Author: Eli Zaretskii Date: Wed Feb 24 17:43:08 2021 +0200 Better support for 'truncate-line' non-nil in the mini-window * src/xdisp.c (resize_mini_window): Resize the mini-window when multi-line text is displayed under truncate-lines non-nil in the minibuffer. (Bug#46718) diff --git a/src/xdisp.c b/src/xdisp.c index f86d3527b3..cd3455aefc 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -11857,18 +11857,27 @@ resize_mini_window (struct window *w, bool exact_p) max_height = clip_to_bounds (unit, max_height, windows_height); /* Find out the height of the text in the window. */ - if (it.line_wrap == TRUNCATE) - height = unit; - else - { - last_height = 0; - move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS); - if (it.max_ascent == 0 && it.max_descent == 0) - height = it.current_y + last_height; - else - height = it.current_y + it.max_ascent + it.max_descent; - height -= min (it.extra_line_spacing, it.max_extra_line_spacing); + last_height = 0; + move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS); + /* If move_it_to moved to the next visible line after EOB, + account for the height of the last full line. */ + if (it.max_ascent == 0 && it.max_descent == 0) + { + height = it.current_y; + /* Don't add the last line's height if lines are truncated + and the text doesn't end in a newline. + FIXME: if the text ends in a newline from a display + property or an overlay string, they lose: the mini-window + might not show the last empty line. */ + if (!(it.line_wrap == TRUNCATE + && it.current_x <= it.first_visible_x + && ZV_BYTE > 1 + && FETCH_BYTE (ZV_BYTE - 1) != '\n')) + height += last_height; } + else + height = it.current_y + it.max_ascent + it.max_descent; + height -= min (it.extra_line_spacing, it.max_extra_line_spacing); /* Compute a suitable window start. */ if (height > max_height) commit 91b37381eaa8db64965249b5a3a377c51d0afa1b Author: Protesilaos Stavrou Date: Wed Feb 24 11:18:38 2021 +0200 Specify the Emacs version of new vc-dir faces * vc-dir.el (vc-dir-header) (vc-dir-header-value) (vc-dir-directory) (vc-dir-file) (vc-dir-mark-indicator) (vc-dir-status-warning) (vc-dir-status-edited) (vc-dir-status-up-to-date) (vc-dir-status-ignored): Add version 28.1. (Bug#46745) diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index a416474e16..46fbf44861 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -56,39 +56,48 @@ See `run-hooks'." (defface vc-dir-header '((t :inherit font-lock-type-face)) "Face for headers in VC-dir buffers." - :group 'vc) + :group 'vc + :version "28.1") (defface vc-dir-header-value '((t :inherit font-lock-variable-name-face)) "Face for header values in VC-dir buffers." - :group 'vc) + :group 'vc + :version "28.1") (defface vc-dir-directory '((t :inherit font-lock-comment-delimiter-face)) "Face for directories in VC-dir buffers." - :group 'vc) + :group 'vc + :version "28.1") (defface vc-dir-file '((t :inherit font-lock-function-name-face)) "Face for files in VC-dir buffers." - :group 'vc) + :group 'vc + :version "28.1") (defface vc-dir-mark-indicator '((t :inherit font-lock-type-face)) "Face for mark indicators in VC-dir buffers." - :group 'vc) + :group 'vc + :version "28.1") (defface vc-dir-status-warning '((t :inherit font-lock-warning-face)) "Face for warning status in VC-dir buffers." - :group 'vc) + :group 'vc + :version "28.1") (defface vc-dir-status-edited '((t :inherit font-lock-variable-name-face)) "Face for edited status in VC-dir buffers." - :group 'vc) + :group 'vc + :version "28.1") (defface vc-dir-status-up-to-date '((t :inherit font-lock-builtin-face)) "Face for up-to-date status in VC-dir buffers." - :group 'vc) + :group 'vc + :version "28.1") (defface vc-dir-status-ignored '((t :inherit shadow)) "Face for ignored or empty values in VC-dir buffers." - :group 'vc) + :group 'vc + :version "28.1") ;; Used to store information for the files displayed in the directory buffer. ;; Each item displayed corresponds to one of these defstructs. commit 6172454ff36a23b903352ef099f15de7d013a3c9 Author: Juri Linkov Date: Tue Feb 23 21:05:30 2021 +0200 Small fixes * lisp/emacs-lisp/seq.el (seq-contains): Move the ‘declare’ form after the docstring. * lisp/misc.el (copy-from-above-command): Fix whitespace regexp. diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 55ce6d9426..adfce95017 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -393,9 +393,9 @@ found or not." count)) (cl-defgeneric seq-contains (sequence elt &optional testfn) - (declare (obsolete seq-contains-p "27.1")) "Return the first element in SEQUENCE that is equal to ELT. Equality is defined by TESTFN if non-nil or by `equal' if nil." + (declare (obsolete seq-contains-p "27.1")) (seq-some (lambda (e) (when (funcall (or testfn #'equal) elt e) e)) diff --git a/lisp/misc.el b/lisp/misc.el index 09f6011f98..39ec9497d7 100644 --- a/lisp/misc.el +++ b/lisp/misc.el @@ -41,7 +41,7 @@ The characters copied are inserted in the buffer before point." (save-excursion (beginning-of-line) (backward-char 1) - (skip-chars-backward "\ \t\n") + (skip-chars-backward " \t\n") (move-to-column cc) ;; Default is enough to copy the whole rest of the line. (setq n (if arg (prefix-numeric-value arg) (point-max))) commit 29c0b640ba7bd076345d654fc5c393062eab83af Author: Juri Linkov Date: Tue Feb 23 21:01:31 2021 +0200 * lisp/tab-line.el (tab-line-tab-name-format-function): New defcustom. (tab-line-tab-name-format-default): New function as the default value. (tab-line-format-template): Funcall tab-line-tab-name-format-function. This is like recently added tab-bar-tab-name-format-function. diff --git a/etc/NEWS b/etc/NEWS index 122ac508c8..5df8ee140c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -501,6 +501,9 @@ It also supports a negative argument. --- *** New user option 'tab-bar-tab-name-format-function'. +--- +*** New user option 'tab-line-tab-name-format-function'. + --- *** The tabs in the tab line can now be scrolled using horizontal scroll. If your mouse or trackpad supports it, you can now scroll tabs when diff --git a/lisp/tab-line.el b/lisp/tab-line.el index 1bdddc2c83..903862a3e8 100644 --- a/lisp/tab-line.el +++ b/lisp/tab-line.el @@ -430,42 +430,56 @@ variable `tab-line-tabs-function'." next-buffers))) +(defcustom tab-line-tab-name-format-function #'tab-line-tab-name-format-default + "Function to format a tab name. +Function gets two arguments: the tab and a list of all tabs, and +should return the formatted tab name to display in the tab line." + :type 'function + :initialize 'custom-initialize-default + :set (lambda (sym val) + (set-default sym val) + (force-mode-line-update)) + :group 'tab-line + :version "28.1") + +(defun tab-line-tab-name-format-default (tab tabs) + (let* ((buffer-p (bufferp tab)) + (selected-p (if buffer-p + (eq tab (window-buffer)) + (cdr (assq 'selected tab)))) + (name (if buffer-p + (funcall tab-line-tab-name-function tab tabs) + (cdr (assq 'name tab)))) + (face (if selected-p + (if (eq (selected-window) (old-selected-window)) + 'tab-line-tab-current + 'tab-line-tab) + 'tab-line-tab-inactive))) + (dolist (fn tab-line-tab-face-functions) + (setf face (funcall fn tab tabs face buffer-p selected-p))) + (apply 'propertize + (concat (propertize name 'keymap tab-line-tab-map) + (or (and (or buffer-p (assq 'buffer tab) (assq 'close tab)) + tab-line-close-button-show + (not (eq tab-line-close-button-show + (if selected-p 'non-selected 'selected))) + tab-line-close-button) + "")) + `( + tab ,tab + ,@(if selected-p '(selected t)) + face ,face + mouse-face tab-line-highlight)))) + (defun tab-line-format-template (tabs) "Template for displaying tab line for selected window." - (let* ((selected-buffer (window-buffer)) - (separator (or tab-line-separator (if window-system " " "|"))) + (let* ((separator (or tab-line-separator (if window-system " " "|"))) (hscroll (window-parameter nil 'tab-line-hscroll)) (strings (mapcar (lambda (tab) - (let* ((buffer-p (bufferp tab)) - (selected-p (if buffer-p - (eq tab selected-buffer) - (cdr (assq 'selected tab)))) - (name (if buffer-p - (funcall tab-line-tab-name-function tab tabs) - (cdr (assq 'name tab)))) - (face (if selected-p - (if (eq (selected-window) (old-selected-window)) - 'tab-line-tab-current - 'tab-line-tab) - 'tab-line-tab-inactive))) - (dolist (fn tab-line-tab-face-functions) - (setf face (funcall fn tab tabs face buffer-p selected-p))) - (concat - separator - (apply 'propertize - (concat (propertize name 'keymap tab-line-tab-map) - (or (and (or buffer-p (assq 'buffer tab) (assq 'close tab)) - tab-line-close-button-show - (not (eq tab-line-close-button-show - (if selected-p 'non-selected 'selected))) - tab-line-close-button) "")) - `( - tab ,tab - ,@(if selected-p '(selected t)) - face ,face - mouse-face tab-line-highlight))))) + (concat separator + (funcall tab-line-tab-name-format-function tab tabs))) tabs)) (hscroll-data (tab-line-auto-hscroll strings hscroll))) (setq hscroll (nth 1 hscroll-data)) commit 0b9fda1fd92e92b65836cbb2f3dd0761ab837d55 Author: Juri Linkov Date: Tue Feb 23 20:57:31 2021 +0200 * lisp/tab-bar.el (tab-prefix-map): Bind "n" to 'tab-duplicate'. (tab-bar-separator): New function. (tab-bar-make-keymap-1): Use it. diff --git a/etc/NEWS b/etc/NEWS index 236c8a9730..122ac508c8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -483,13 +483,13 @@ value of 'tab-bar-show'. It can be used to enable/disable the tab bar individually on each frame independently from the value of 'tab-bar-mode' and 'tab-bar-show'. ---- -*** New command 'tab-duplicate'. - --- *** 'Mod-9' bound to 'tab-last' now switches to the last tab. It also supports a negative argument. +--- +*** New command 'tab-duplicate' bound to 'C-x t n'. + --- *** 'C-x t N' creates a new tab at the specified absolute position. It also supports a negative argument. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 41844e6f5c..0893a98e60 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -379,6 +379,9 @@ and `tab-bar-select-tab-modifiers'." (defvar tab-bar-separator nil "String that delimits tabs.") +(defun tab-bar-separator () + (or tab-bar-separator (if window-system " " "|"))) + (defcustom tab-bar-tab-name-function #'tab-bar-tab-name-current "Function to get a tab name. @@ -502,9 +505,9 @@ the formatted tab name to display in the tab bar." (defun tab-bar-make-keymap-1 () "Generate an actual keymap from `tab-bar-map', without caching." - (let* ((separator (or tab-bar-separator (if window-system " " "|"))) - (i 0) - (tabs (funcall tab-bar-tabs-function))) + (let ((separator (tab-bar-separator)) + (tabs (funcall tab-bar-tabs-function)) + (i 0)) (append '(keymap (mouse-1 . tab-bar-handle-mouse)) (when (and tab-bar-history-mode tab-bar-history-buttons-show) @@ -1699,6 +1702,7 @@ When `switch-to-buffer-obey-display-actions' is non-nil, nil "[other-tab]") (message "Display next command buffer in a new tab...")) +(define-key tab-prefix-map "n" 'tab-duplicate) (define-key tab-prefix-map "N" 'tab-new-to) (define-key tab-prefix-map "2" 'tab-new) (define-key tab-prefix-map "1" 'tab-close-other) commit a1333fe6cfb3abe6ec2111dca43b059510984906 Merge: 7271b11457 07235678a4 Author: Ulf Jasper Date: Tue Feb 23 19:43:56 2021 +0100 Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs commit 7271b11457507d490bcd42c634b56bfd2d716c78 Author: Ulf Jasper Date: Tue Feb 23 19:31:32 2021 +0100 Leave other windows unchanged, use search instead of re-search * lisp/net/newst-backend.el (newsticker-customize-feed): Leave other windws unchanged. Use search instead of re-search. diff --git a/lisp/net/newst-backend.el b/lisp/net/newst-backend.el index c2809ea918..f5b4761078 100644 --- a/lisp/net/newst-backend.el +++ b/lisp/net/newst-backend.el @@ -651,8 +651,7 @@ If URL is nil it is searched at point." (list (completing-read "Name of feed or group to edit: " (mapcar #'car newsticker-url-list)))) (customize-variable 'newsticker-url-list) - (delete-other-windows) - (when (re-search-forward (concat "Label: " feed-name) nil t) + (when (search-forward (concat "Label: " feed-name) nil t) (forward-line -1))) (defun newsticker-customize () commit 5ae02894640bc7bd5a88610e11c7bdce9040c3fe Author: Ulf Jasper Date: Tue Feb 23 19:23:50 2021 +0100 Fix invalid interactive-statement * lisp/net/newst-backend.el (newsticker-customize): Fix invalid interactive-statement. diff --git a/lisp/net/newst-backend.el b/lisp/net/newst-backend.el index 4ff950fc5c..c2809ea918 100644 --- a/lisp/net/newst-backend.el +++ b/lisp/net/newst-backend.el @@ -649,8 +649,7 @@ If URL is nil it is searched at point." "Open customization buffer for `newsticker-url-list' and jump to FEED-NAME." (interactive (list (completing-read "Name of feed or group to edit: " - (append (mapcar #'car newsticker-url-list) - nil t feed-name)))) + (mapcar #'car newsticker-url-list)))) (customize-variable 'newsticker-url-list) (delete-other-windows) (when (re-search-forward (concat "Label: " feed-name) nil t) commit 07235678a4d30f56cec67fe6e9098e8541ab9ad1 Author: Stefan Monnier Date: Tue Feb 23 12:14:59 2021 -0500 * test/: Use lexical-binding the few remaining files * test/manual/biditest.el: Use lexical-binding. (biditest-generate-testfile): Remove unused var `levels`. * test/manual/image-circular-tests.el: Use lexical-binding. * test/manual/image-size-tests.el: Use lexical-binding. (image-size-tests): Check `fboundp` before calling `imagemagick-types`. * test/manual/redisplay-testsuite.el: Use lexical-binding. * test/manual/cedet/cedet-utests.el: Use lexical-binding. Use `with-current-buffer`. (cedet-utest): Test `fboundp` i.s.o `featurep` to silence warning. (srecode-map-save-file): Declare var. (pulse-test): Test `fboundp` before calling `pulse-available-p`. Declare `pulse-momentary-highlight-overlay` since it's not autoloaded. * test/manual/cedet/semantic-tests.el: Use lexical-binding. Use `with-current-buffer`. (semanticdb-ebrowse-dump): Remove unused var `ab`. (semanticdb-test-gnu-global): Don't use obsolete "name" arg to constructor. (cedet-utest-directory): Declare var. diff --git a/test/manual/biditest.el b/test/manual/biditest.el index dc78ef55b0..a77fc15880 100644 --- a/test/manual/biditest.el +++ b/test/manual/biditest.el @@ -1,4 +1,4 @@ -;;; biditest.el --- test bidi reordering in GNU Emacs display engine. +;;; biditest.el --- test bidi reordering in GNU Emacs display engine. -*- lexical-binding: t; -*- ;; Copyright (C) 2013-2021 Free Software Foundation, Inc. @@ -54,7 +54,7 @@ The resulting file should be viewed with `inhibit-bidi-mirroring' set to t." (resolved-paragraph (match-string 3)) ;; FIXME: Should compare LEVELS with what the display ;; engine actually produced. - (levels (match-string 4)) + ;;(levels (match-string 4)) (indices (match-string 5))) (setq codes (split-string codes " ") indices (split-string indices " ")) @@ -120,4 +120,4 @@ BidiCharacterTest.txt file." (interactive) (message "%s" (bidi-resolved-levels))) -(define-key global-map [f8] 'bidi-levels) +(define-key global-map [f8] #'bidi-levels) diff --git a/test/manual/cedet/cedet-utests.el b/test/manual/cedet/cedet-utests.el index e421054102..d68b5b8c09 100644 --- a/test/manual/cedet/cedet-utests.el +++ b/test/manual/cedet/cedet-utests.el @@ -1,4 +1,4 @@ -;;; cedet-utests.el --- Run all unit tests in the CEDET suite. +;;; cedet-utests.el --- Run all unit tests in the CEDET suite. -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -120,9 +120,9 @@ EXIT-ON-ERROR causes the test suite to exit on an error, instead of just logging the error." (interactive) - (if (or (not (featurep 'semantic/db-mode)) - (not (semanticdb-minor-mode-p))) - (error "CEDET Tests require semantic-mode to be enabled")) + (unless (and (fboundp 'semanticdb-minor-mode-p) + (semanticdb-minor-mode-p)) + (error "CEDET Tests require semantic-mode to be enabled")) (dolist (L cedet-utest-libs) (load-file (expand-file-name (concat L ".el") cedet-utest-directory))) (cedet-utest-log-setup "ALL TESTS") @@ -170,6 +170,8 @@ of just logging the error." (declare (obsolete nil "27.1")) noninteractive) +(defvar srecode-map-save-file) + ;;;###autoload (defun cedet-utest-batch () "Run the CEDET unit test in BATCH mode." @@ -178,6 +180,7 @@ of just logging the error." (condition-case err (when (catch 'cedet-utest-exit-on-error ;; Get basic semantic features up. + ;; FIXME: I can't see any such function in our code! (semantic-load-enable-minimum-features) ;; Disables all caches related to semantic DB so all ;; tests run as if we have bootstrapped CEDET for the @@ -231,8 +234,7 @@ Optional argument TITLE is the title of this testing session." (setq cedet-utest-frame (make-frame cedet-utest-frame-parameters))) (when (or (not cedet-utest-buffer) (not (buffer-live-p cedet-utest-buffer))) (setq cedet-utest-buffer (get-buffer-create "*CEDET utest log*"))) - (save-excursion - (set-buffer cedet-utest-buffer) + (with-current-buffer cedet-utest-buffer (setq cedet-utest-last-log-item nil) (when (not cedet-running-master-tests) (erase-buffer)) @@ -254,7 +256,7 @@ Argument START and END bound the time being calculated." (- (car (cdr end)) (car (cdr start))) (/ (- (car (cdr (cdr end))) (car (cdr (cdr start)))) 1000000.0))) -(defun cedet-utest-log-shutdown (title &optional errorcondition) +(defun cedet-utest-log-shutdown (title &optional _errorcondition) "Shut-down a larger test suite. TITLE is the section that is done. ERRORCONDITION is some error that may have occurred during testing." @@ -274,8 +276,7 @@ ERRORCONDITION is some error that may have occurred during testing." (message " Elapsed Time %.2f Seconds\n" (cedet-utest-elapsed-time startime endtime))) - (save-excursion - (set-buffer cedet-utest-buffer) + (with-current-buffer cedet-utest-buffer (goto-char (point-max)) (insert "\n>> Test Suite " title " ended at @ " (format-time-string "%c" endtime) "\n" @@ -305,12 +306,11 @@ ERRORCONDITION is some error that may have occurred during testing." "Hook run after the current log command was run." (if noninteractive (message "") - (save-excursion - (set-buffer cedet-utest-buffer) + (with-current-buffer cedet-utest-buffer (goto-char (point-max)) (insert "\n\n"))) (setq cedet-utest-last-log-item nil) - (remove-hook 'post-command-hook 'cedet-utest-post-command-hook) + (remove-hook 'post-command-hook #'cedet-utest-post-command-hook) ) (defun cedet-utest-add-log-item-start (item) @@ -318,12 +318,11 @@ ERRORCONDITION is some error that may have occurred during testing." (unless (equal item cedet-utest-last-log-item) (setq cedet-utest-last-log-item item) ;; This next line makes sure we clear out status during logging. - (add-hook 'post-command-hook 'cedet-utest-post-command-hook) + (add-hook 'post-command-hook #'cedet-utest-post-command-hook) (if noninteractive (message " - Running %s ..." item) - (save-excursion - (set-buffer cedet-utest-buffer) + (with-current-buffer cedet-utest-buffer (goto-char (point-max)) (when (not (bolp)) (insert "\n")) (insert "Running " item " ... ") @@ -343,8 +342,7 @@ Optional argument PRECR indicates to prefix the done msg w/ a newline." (message " * %s {%s}" (or err "done") notes) (message " * %s" (or err "done"))) ;; Interactive-mode - insert into the buffer. - (save-excursion - (set-buffer cedet-utest-buffer) + (with-current-buffer cedet-utest-buffer (goto-char (point-max)) (when precr (insert "\n")) (if err @@ -378,12 +376,11 @@ Optional argument PRECR indicates to prefix the done msg w/ a newline." "Log the text string FORMAT. The rest of the ARGS are used to fill in FORMAT with `format'." (if noninteractive - (apply 'message format args) - (save-excursion - (set-buffer cedet-utest-buffer) + (apply #'message format args) + (with-current-buffer cedet-utest-buffer (goto-char (point-max)) (when (not (bolp)) (insert "\n")) - (insert (apply 'format format args)) + (insert (apply #'format format args)) (insert "\n") (sit-for 0) )) @@ -396,11 +393,15 @@ The rest of the ARGS are used to fill in FORMAT with `format'." "Test the lightening function for pulsing a line. When optional NO-ERROR don't throw an error if we can't run tests." (interactive) - (if (or (not pulse-flag) (not (pulse-available-p))) + (if (not (and (bound-and-true-p pulse-flag) + (fboundp 'pulse-available-p) + (pulse-available-p))) (if no-error nil (error (concat "Pulse test only works on versions of Emacs" " that support pulsing"))) + (declare-function pulse-momentary-highlight-overlay + "pulse.el" (o &optional face)) ;; Run the tests (when (called-interactively-p 'interactive) (message " Pulse one line.") diff --git a/test/manual/cedet/semantic-tests.el b/test/manual/cedet/semantic-tests.el index 3d72fa2965..61f1d118fd 100644 --- a/test/manual/cedet/semantic-tests.el +++ b/test/manual/cedet/semantic-tests.el @@ -1,4 +1,4 @@ -;;; semantic-utest.el --- Miscellaneous Semantic tests. +;;; semantic-utest.el --- Miscellaneous Semantic tests. -*- lexical-binding: t; -*- ;;; Copyright (C) 2003-2004, 2007-2021 Free Software Foundation, Inc. @@ -64,10 +64,12 @@ run the test again"))) "Find the first loaded ebrowse table, and dump out the contents." (interactive) (let ((db semanticdb-database-list) - (ab nil)) + ;; (ab nil) + ) (while db (when (semanticdb-project-database-ebrowse-p (car db)) - (setq ab (data-debug-new-buffer "*EBROWSE Database*")) + ;; (setq ab + (data-debug-new-buffer "*EBROWSE Database*") ;;) (data-debug-insert-thing (car db) "*" "") (setq db nil) ) @@ -100,7 +102,7 @@ If optional arg STANDARDFILE is non-nil, use a standard file w/ global enabled." (set-buffer (find-file-noselect semanticdb-test-gnu-global-startfile))) (semanticdb-enable-gnu-global-in-buffer)))) - (let* ((db (semanticdb-project-database-global "global")) + (let* ((db (semanticdb-project-database-global)) ;; "global" (tab (semanticdb-file-table db (buffer-file-name))) (result (semanticdb-deep-find-tags-for-completion-method tab searchfor)) ) @@ -127,8 +129,7 @@ Optional argument ARG specifies not to use color." (princ (car fns)) (princ ":\n ") (let ((s (funcall (car fns) tag par (not arg)))) - (save-excursion - (set-buffer "*format-tag*") + (with-current-buffer "*format-tag*" (goto-char (point-max)) (insert s))) (setq fns (cdr fns)))) @@ -163,7 +164,7 @@ Optional argument ARG specifies not to use color." "Test `semantic-idle-scheduler-work-parse-neighboring-files' and time it." (interactive) (let ((start (current-time)) - (junk (semantic-idle-scheduler-work-parse-neighboring-files))) + (_junk (semantic-idle-scheduler-work-parse-neighboring-files))) (message "Work took %.2f seconds." (semantic-elapsed-time start nil)))) ;;; From semantic-lex: @@ -210,6 +211,8 @@ Analyze the area between BEG and END." (semantic-lex-spp-table-write-slot-value (semantic-lex-spp-save-table)))) +(defvar cedet-utest-directory) ;From test/manual/cedet/cedet-utests.el? + (defun semantic-lex-spp-write-utest () "Unit test using the test spp file to test the slot write fcn." (interactive) @@ -258,7 +261,7 @@ tag that contains point, and return that." (Lcount 0)) (when (semantic-tag-p target) (semantic-symref-hits-in-region - target (lambda (start end prefix) (setq Lcount (1+ Lcount))) + target (lambda (_start _end _prefix) (setq Lcount (1+ Lcount))) (semantic-tag-start tag) (semantic-tag-end tag)) (when (called-interactively-p 'interactive) diff --git a/test/manual/image-circular-tests.el b/test/manual/image-circular-tests.el index 3d1d23234b..7abb94dee6 100644 --- a/test/manual/image-circular-tests.el +++ b/test/manual/image-circular-tests.el @@ -1,4 +1,4 @@ -;;; image-circular-tests.el --- test image functions with circular objects +;;; image-circular-tests.el --- test image functions with circular objects -*- lexical-binding: t; -*- ;; Copyright (C) 2019, 2021 Free Software Foundation, Inc. diff --git a/test/manual/image-size-tests.el b/test/manual/image-size-tests.el index 489b397293..f7c2bf7fc0 100644 --- a/test/manual/image-size-tests.el +++ b/test/manual/image-size-tests.el @@ -1,4 +1,4 @@ -;;; image-size-tests.el -- tests for image scaling +;;; image-size-tests.el -- tests for image scaling -*- lexical-binding: t; -*- ;; Copyright (C) 2017-2021 Free Software Foundation, Inc. @@ -45,7 +45,8 @@ (= (cdr size) height)))) (defun image-size-tests () - (unless (imagemagick-types) + (unless (and (fboundp 'imagemagick-types) + (imagemagick-types)) (error "This only makes sense if ImageMagick is installed")) ;; Test the image that's wider than it is tall. ;; Default sizes. diff --git a/test/manual/redisplay-testsuite.el b/test/manual/redisplay-testsuite.el index 48f3788b54..8e90f2d7a5 100644 --- a/test/manual/redisplay-testsuite.el +++ b/test/manual/redisplay-testsuite.el @@ -1,4 +1,4 @@ -;;; redisplay-testsuite.el --- Test suite for redisplay. +;;; redisplay-testsuite.el --- Test suite for redisplay. -*- lexical-binding: t; -*- ;; Copyright (C) 2009-2021 Free Software Foundation, Inc. commit a283996fc728e249816d3bd43a6da1f3c0eab837 Author: Ulf Jasper Date: Tue Feb 23 17:33:46 2021 +0100 Add command for customizing current newsticker feed * lisp/net/newst-backend.el (newsticker-customize-feed): New. (newsticker--insert-bytes): Add documentation string. (newsticker--decode-iso8601-date): Fix documentation string. * lisp/net/newst-treeview.el (newsticker-treeview-customize-current-feed): New. (newsticker-treeview-mode-map): Add key for new command 'newsticker-treeview-customize-current-feed'. (Fixes second issue in Bug#41376.) diff --git a/lisp/net/newst-backend.el b/lisp/net/newst-backend.el index ea96012af2..4ff950fc5c 100644 --- a/lisp/net/newst-backend.el +++ b/lisp/net/newst-backend.el @@ -645,6 +645,17 @@ If URL is nil it is searched at point." (add-to-list 'newsticker-url-list (list name url nil nil nil) t) (customize-variable 'newsticker-url-list)) +(defun newsticker-customize-feed (feed-name) + "Open customization buffer for `newsticker-url-list' and jump to FEED-NAME." + (interactive + (list (completing-read "Name of feed or group to edit: " + (append (mapcar #'car newsticker-url-list) + nil t feed-name)))) + (customize-variable 'newsticker-url-list) + (delete-other-windows) + (when (re-search-forward (concat "Label: " feed-name) nil t) + (forward-line -1))) + (defun newsticker-customize () "Open the newsticker customization group." (interactive) @@ -1548,6 +1559,7 @@ argument, which is one of the items in ITEMLIST." ;; ====================================================================== (defun newsticker--insert-bytes (bytes) + "Decode BYTES and insert in current buffer." (insert (decode-coding-string bytes 'binary))) (defun newsticker--remove-whitespace (string) @@ -1587,7 +1599,7 @@ This function calls `message' with arguments STRING and ARGS, if (apply 'message string args))) (defun newsticker--decode-iso8601-date (string) - "Return ISO8601-STRING in format like `encode-time'. + "Return ISO8601-encoded STRING in format like `encode-time'. Converts from ISO-8601 to Emacs representation. If no time zone is present, this function defaults to universal time." (if string diff --git a/lisp/net/newst-treeview.el b/lisp/net/newst-treeview.el index a2d4d89ee5..618a791c57 100644 --- a/lisp/net/newst-treeview.el +++ b/lisp/net/newst-treeview.el @@ -1434,6 +1434,15 @@ Move to next item unless DONT-PROCEED is non-nil." newsticker--treeview-current-vfeed) (newsticker--treeview-get-selected-item))) +(defun newsticker-treeview-customize-current-feed () + "Open customization buffer for `newsticker-url-list' and move to current feed." + (interactive) + (let ((cur-feed (or newsticker--treeview-current-feed + newsticker--treeview-current-vfeed))) + (if (newsticker--group-get-group cur-feed) + (message "Cannot customize groups. Please select a feed.") + (newsticker-customize-feed cur-feed)))) + (defun newsticker--treeview-set-current-node (node) "Make NODE the current node." (with-current-buffer (newsticker--treeview-tree-buffer) @@ -1995,6 +2004,7 @@ Return t if groups have changed, nil otherwise." (define-key map " " 'newsticker-treeview-next-page) (define-key map "a" 'newsticker-add-url) (define-key map "b" 'newsticker-treeview-browse-url-item) + (define-key map "c" 'newsticker-treeview-customize-current-feed) (define-key map "F" 'newsticker-treeview-prev-feed) (define-key map "f" 'newsticker-treeview-next-feed) (define-key map "g" 'newsticker-treeview-get-news) commit 57084098f49351a59f1b9a350a4b6ffee9eab3ae Author: Michael Albinus Date: Tue Feb 23 16:04:22 2021 +0100 ; Fix tramp.texi typos diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 53f67b191c..609d08c336 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -494,7 +494,7 @@ and the return value of @code{(system-name)} as default host name. Therefore, it is convenient to open a file as @file{@trampfn{sudo,,/path/to/file}}. -The method @option{sg} stands for ``switch group''; here the username +The method @option{sg} stands for ``switch group''; here the user name is used as the group to change to. The default host name is the same. @@ -562,7 +562,7 @@ of the local file name is the share exported by the remote host, @cindex @option{mtp} method On systems which have @acronym{GVFS, the GNOME Virtual File System} -installed , its offered methods can be used by @value{tramp}. +installed, its offered methods can be used by @value{tramp}. Examples are @file{@trampfn{sftp,user@@host,/path/to/file}}, @file{@trampfn{afp,user@@host,/path/to/file}} (accessing Apple's AFP file system), @file{@trampfn{dav,user@@host,/path/to/file}}, commit 228fd92fb389eeaf2ec0bbca51da0569fce28ee7 Author: Robert Pluim Date: Tue Feb 23 14:21:26 2021 +0100 * doc/misc/tramp.texi: Grammar/style fixes * doc/misc/tramp.texi (Overview): (Obtaining @value{tramp}): (Quick Start Guide): (Configuration): (Connection types): (Inline methods): (External methods): (Password handling): (Predefined connection information): (Remote shell setup): (Remote processes): (Frequently Asked Questions): (External packages): (Traces and Profiles): Grammar/style fixes. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index e745af2a7d..53f67b191c 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -223,7 +223,7 @@ presented here to illustrate the steps involved: @kbd{C-x C-f} to initiate find-file, enter part of the @value{tramp} file name, then hit @kbd{@key{TAB}} for completion. If this is the -first time connection to that host, here's what happens: +first time connecting to that host, here's what happens: @itemize @item @@ -250,17 +250,17 @@ message. If @value{tramp} does not receive any messages within a timeout period (a minute, for example), then @value{tramp} responds with an error -message about not finding the remote shell prompt. If any messages -from the remote host, @value{tramp} displays them in the buffer. +message about not finding the remote shell prompt. If there are any +messages from the remote host, @value{tramp} displays them in the +buffer. For any @samp{login failed} message from the remote host, -@value{tramp} aborts the login attempt, and repeats the login steps -again. +@value{tramp} aborts the login attempt, and repeats the login steps. @item -Upon successful login and @value{tramp} recognizes the shell prompt +Upon successful login, if @value{tramp} recognizes the shell prompt from the remote host, @value{tramp} prepares the shell environment by -turning off echoing, setting shell prompt, and other housekeeping +turning off echoing, setting the shell prompt, and other housekeeping chores. @strong{Note} that for the remote shell, @value{tramp} invokes @@ -282,8 +282,8 @@ contents from the remote host. For inline transfers, @value{tramp} sends a command, such as @samp{mimencode -b /path/to/remote/file}, waits until the output has -accumulated in the buffer, decodes that output to produce the file's -contents. +accumulated in the buffer, then decodes that output to produce the +file's contents. For external transfers, @value{tramp} sends a command as follows: @example @@ -335,7 +335,7 @@ versions packaged with Emacs can be retrieved by @end lisp @value{tramp} is also available as @uref{https://elpa.gnu.org, GNU -ELPA} package. Besides the standalone releases, further minor version +ELPA} package. Besides the standalone releases, further minor versions of @value{tramp} will appear on GNU ELPA, until the next @value{tramp} release appears. These minor versions have a four-number string, like ``2.4.5.1''. @@ -345,7 +345,7 @@ Development versions contain new and incomplete features. The development version of @value{tramp} is always the version number of the next release, plus the suffix ``-pre'', like ``2.4.4-pre''. -One way to obtain @value{tramp} from Git server is to visit the +One way to obtain @value{tramp} from the Git server is to visit the Savannah project page at the following URL and then clicking on the Git link in the navigation bar at the top. @@ -363,7 +363,7 @@ $ git clone git://git.savannah.gnu.org/tramp.git @end example @noindent -From behind a firewall: +From behind a proxy: @example @group @@ -411,7 +411,7 @@ $ autoconf @end ifset @ifclear installchapter See the file @file{INSTALL} in that directory for further information -how to install @value{tramp}. +on how to install @value{tramp}. @end ifclear @@ -419,16 +419,16 @@ how to install @value{tramp}. @chapter Short introduction how to use @value{tramp} @cindex quick start guide -@value{tramp} extends the Emacs file name syntax by a remote -component. A remote file name looks always like +@value{tramp} extends the Emacs file name syntax by adding a remote +component. A remote file name always looks like @file{@trampfn{method,user@@host,/path/to/file}}. You can use remote files exactly like ordinary files, that means you -could open a file or directory by @kbd{C-x C-f +can open a file or directory by @kbd{C-x C-f @trampfn{method,user@@host,/path/to/file} @key{RET}}, edit the file, and save it. You can also mix local files and remote files in file operations with two arguments, like @code{copy-file} or -@code{rename-file}. And finally, you can run even processes on a +@code{rename-file}. And finally, you can even run processes on a remote host, when the buffer you call the process from has a remote @code{default-directory}. @@ -437,26 +437,26 @@ remote host, when the buffer you call the process from has a remote @section File name syntax @cindex file name syntax -Remote file names are prepended by the @code{method}, @code{user} and -@code{host} parts. All of them, and also the local file name part, -are optional, in case of a missing part a default value is assumed. -The default value for an empty local file name part is the remote -user's home directory. The shortest remote file name is -@file{@trampfn{-,,}}, therefore. The @samp{-} notation for the -default method is used for syntactical reasons, @ref{Default Method}. +Remote file names have @code{method}, @code{user} and @code{host} +parts prepended. All of them, and also the local file name part, are +optional, in case of a missing part a default value is assumed. The +default value for an empty local file name part is the remote user's +home directory. The shortest remote file name is thus +@file{@trampfn{-,,}}. The @samp{-} notation for the default method is +used for syntactical reasons, @ref{Default Method}. The @code{method} part describes the connection method used to reach the remote host, see below. The @code{user} part is the user name for accessing the remote host. For the @option{smb} method, this could also require a domain name, in -this case it is written as @code{user%domain}. +which case it is written as @code{user%domain}. -The @code{host} part must be a host name which could be resolved on +The @code{host} part must be a host name which can be resolved on your local host. It could be a short host name, a fully qualified domain name, an IPv4 or IPv6 address, @ref{File name syntax}. Some -connection methods support also a notation of the port to be used, in -this case it is written as @code{host#port}. +connection methods also support a notation for the port to be used, in +which case it is written as @code{host#port}. @anchor{Quick Start Guide: @option{ssh} and @option{plink} methods} @@ -470,9 +470,9 @@ If your local host runs an SSH client, and the remote host runs an SSH server, the simplest remote file name is @file{@trampfn{ssh,user@@host,/path/to/file}}. The remote file name @file{@trampfn{ssh,,}} opens a remote connection to yourself on the -local host, and is taken often for testing @value{tramp}. +local host, and is often used for testing @value{tramp}. -On MS Windows, PuTTY is often used as SSH client. Its @command{plink} +On MS Windows, PuTTY is often used as the SSH client. Its @command{plink} method can be used there to open a connection to a remote host running an @command{ssh} server: @file{@trampfn{plink,user@@host,/path/to/file}}. @@ -488,14 +488,14 @@ an @command{ssh} server: @cindex @option{sg} method Sometimes, it is necessary to work on your local host under different -permissions. For this, you could use the @option{su} or @option{sudo} +permissions. For this, you can use the @option{su} or @option{sudo} connection method. Both methods use @samp{root} as default user name and the return value of @code{(system-name)} as default host name. Therefore, it is convenient to open a file as @file{@trampfn{sudo,,/path/to/file}}. -The method @option{sg} stands for ``switch group''; the changed group -must be used here as user name. The default host name is the same. +The method @option{sg} stands for ``switch group''; here the username +is used as the group to change to. The default host name is the same. @anchor{Quick Start Guide: @option{ssh}, @option{plink}, @option{su}, @option{sudo} and @option{sg} methods} @@ -509,9 +509,9 @@ must be used here as user name. The default host name is the same. @cindex method @option{sudo} @cindex @option{sudo} method -If the @option{su} or @option{sudo} option shall be performed on -another host, it could be comnbined with a leading @option{ssh} or -@option{plink} option. That means, @value{tramp} connects first to +If the @option{su} or @option{sudo} option should be performed on +another host, it can be comnbined with a leading @option{ssh} or +@option{plink} option. That means that @value{tramp} connects first to the other host with non-administrative credentials, and changes to administrative credentials on that host afterwards. In a simple case, the syntax looks like @@ -527,8 +527,8 @@ the syntax looks like The @option{sudoedit} method is similar to the @option{sudo} method. However, it is a different implementation: it does not keep an open session running in the background. This is for security reasons; on -the backside this method is less performant than the @option{sudo} -method, it is restricted to the @samp{localhost} only, and it does not +the backside this method has worse performance than the @option{sudo} +method, it is restricted to @samp{localhost} only, and it does not support external processes. @@ -561,9 +561,9 @@ of the local file name is the share exported by the remote host, @cindex method @option{mtp} @cindex @option{mtp} method -On systems, which have installed @acronym{GVFS, the GNOME Virtual File -System}, its offered methods could be used by @value{tramp}. Examples -are @file{@trampfn{sftp,user@@host,/path/to/file}}, +On systems which have @acronym{GVFS, the GNOME Virtual File System} +installed , its offered methods can be used by @value{tramp}. +Examples are @file{@trampfn{sftp,user@@host,/path/to/file}}, @file{@trampfn{afp,user@@host,/path/to/file}} (accessing Apple's AFP file system), @file{@trampfn{dav,user@@host,/path/to/file}}, @file{@trampfn{davs,user@@host,/path/to/file}} (for WebDAV shares) and @@ -580,10 +580,10 @@ file system), @file{@trampfn{dav,user@@host,/path/to/file}}, @cindex @option{nextcloud} method @cindex nextcloud -@acronym{GVFS}-based methods include also @acronym{GNOME} Online +@acronym{GVFS}-based methods also include @acronym{GNOME} Online Accounts, which support the @option{Files} service. These are the Google Drive file system, and the OwnCloud/NextCloud file system. The -file name syntax is here always +file name syntax here is always @file{@trampfn{gdrive,john.doe@@gmail.com,/path/to/file}} (@samp{john.doe@@gmail.com} stands here for your Google Drive account), or @file{@trampfn{nextcloud,user@@host#8081,/path/to/file}} @@ -608,7 +608,7 @@ needed. The file name syntax is @file{@trampfn{adb,,/path/to/file}}. A convenient way to access system storages is the @command{rclone} program. If you have configured a storage in @command{rclone} under a -name @samp{storage} (for example), you could access it via the remote +name @samp{storage} (for example), you can access it via the remote file name syntax @file{@trampfn{rclone,storage,/path/to/file}}. User names are not needed. @@ -630,7 +630,7 @@ For changing the connection type and file access method from the defaults to one of several other options, @xref{Connection types}. @strong{Note} that some user options described in these examples are -not auto loaded by Emacs. All examples require @value{tramp} is +not auto loaded by Emacs. All examples require @value{tramp} to be installed and loaded: @lisp @@ -638,7 +638,7 @@ installed and loaded: @end lisp For functions used to configure @value{tramp}, the following clause -might be used in your init file: +may be used in your init file: @lisp (with-eval-after-load 'tramp (tramp-change-syntax 'simplified)) @@ -693,13 +693,13 @@ methods. While these methods do see better performance when actually transferring files, the overhead of the cryptographic negotiation at startup may drown out the improvement in file transfer times. -External methods should be configured such a way that they don't -require a password (with @command{ssh-agent}, or such alike). Modern +External methods should be configured in such a way that they don't +require a password (with @command{ssh-agent}, or similar). Modern @command{scp} implementations offer options to reuse existing -@command{ssh} connections, which will be enabled by default if -available. If it isn't possible, you should consider @ref{Password -handling}, otherwise you will be prompted for a password every copy -action. +@command{ssh} connections, which @value{tramp} enables by default if +available. If that is not possible, you should consider @ref{Password +handling}, otherwise you will be prompted for a password for every +copy action. @node Inline methods @@ -727,17 +727,17 @@ usability of one of the commands defined in reliable command it finds. @value{tramp}'s search path can be customized, see @ref{Remote programs}. -In case none of the commands are unavailable, @value{tramp} first -transfers a small Perl program to the remote host, and then tries that -program for encoding and decoding. +In case none of the commands are available, @value{tramp} first +transfers a small Perl program to the remote host, and then tries to +use that program for encoding and decoding. @vindex tramp-inline-compress-start-size @vindex tramp-inline-compress-commands -To increase transfer speeds for large text files, use compression -before encoding. The user option -@code{tramp-inline-compress-start-size} specifies the file size for -such optimization. This feature depends on the availability and -usability of one of the commands defined in +To increase transfer speeds for large text files, @value{tramp} can +use compression before encoding. The user option +@code{tramp-inline-compress-start-size} specifies the file size above +which to use this optimization. This feature depends on the +availability and usability of one of the commands defined in @code{tramp-inline-compress-commands}. @table @asis @@ -747,6 +747,8 @@ usability of one of the commands defined in @command{rsh} is an option for connecting to hosts within local networks since @command{rsh} is not as secure as other methods. +There should be no reason to use it, as @command{ssh} is a both a +complete replacement and ubiquitous. @item @option{ssh} @cindex method @option{ssh} @@ -784,7 +786,7 @@ Similar to @option{su} method, @option{sudo} uses @command{sudo}. @command{sudo} must have sufficient rights to start a shell. For security reasons, a @option{sudo} connection is disabled after a -predefined timeout (5 minutes per default). This can be changed, see +predefined timeout (5 minutes by default). This can be changed, see @ref{Predefined connection information}. @item @option{doas} @@ -1183,7 +1185,7 @@ information}. Supported properties are @t{"mount-args"}, @t{"copyto-args"} and @t{"moveto-args"}. Access via @option{rclone} is slow. If you have an alternative method -for accessing the system storage, you shall prefer this. +for accessing the system storage, you should use it. @ref{GVFS-based methods} for example, methods @option{gdrive} and @option{nextcloud}. @@ -1908,10 +1910,10 @@ machine melancholia#4711 port davs login daniel%BIZARRE password geheim @end example @vindex auth-source-save-behavior -If there doesn't exist a proper entry, the password is read +If no proper entry exists, the password is read interactively. After successful login (verification of the password), -it is offered to save a corresponding entry for further use by -@code{auth-source} backends which support this. This could be changed +Emacs offers to save a corresponding entry for further use by +@code{auth-source} backends which support this. This can be changed by setting the user option @code{auth-source-save-behavior} to @code{nil}. @vindex auth-source-debug @@ -2037,10 +2039,10 @@ properties are listed here: @itemize @item @t{"login-program"} -The property @t{"login-program"} keeps the program to be called in -order to connect the remote host. Sometimes, the program might have -another name on your host, or it is located on another path. In this -case, you can overwrite the default value, which is special for every +The property @t{"login-program"} stores the program to be used to +connect to the remote host. Sometimes, the program might have another +name on your host, or it might be located in another path. In this case, +you can overwrite the default value, which is special for every connection method. It is used in all connection methods of @file{tramp-sh.el}. @@ -2093,12 +2095,12 @@ Connections using the @option{smb} method check, whether the remote host supports posix commands. If the remote host runs Samba, it confirms this capability. However, some very old Samba versions have errors in their implementation. In order to suppress the posix -commands for those hosts, the property @t{"posix"} shall be set to +commands for those hosts, the property @t{"posix"} should be set to @code{nil}. The default value of this property is @code{t} (not specified in @code{tramp-methods}). If the remote host runs native MS Windows, -there is no effect of this property. +this propery has no effect. @item @t{"mount-args"}@* @t{"copyto-args"}@* @@ -2207,7 +2209,7 @@ be recomputed. To force @value{tramp} to recompute afresh, call @subsection Changing the default remote or local shell @cindex zsh setup -Per default, @value{tramp} uses the command @command{/bin/sh} for +By default, @value{tramp} uses the command @command{/bin/sh} for starting a shell on the remote host. This can be changed by setting the connection property @t{"remote-shell"}; see @pxref{Predefined connection information}. If you want, for example, use @@ -2232,7 +2234,7 @@ This approach has also the advantage, that settings in trouble with the shell prompt due to set zle options will be avoided. Similar problems can happen with the local shell Tramp uses to create -a process. Per default, it uses the command @command{/bin/sh} for +a process. By default, it uses the command @command{/bin/sh} for this, which could also be a link to another shell. In order to overwrite this, you might apply @@ -2332,7 +2334,7 @@ prompts, for which @value{tramp} uses @code{tramp-wrong-passwd-regexp}. @value{tramp} uses the user option @code{tramp-terminal-type} to set the remote environment variable @env{TERM} for the shells it runs. -Per default, it is @t{"dumb"}, but this could be changed. A dumb +By default, it is @t{"dumb"}, but this could be changed. A dumb terminal is best suited to run the background sessions of @value{tramp}. However, running interactive remote shells might require a different setting. This could be achieved by tweaking the @@ -3216,19 +3218,19 @@ host when the variable @code{default-directory} is remote: @end lisp @vindex process-file-return-signal-string -@code{process-file} shall return either the exit code of the process, -or a string describing the signal, when the process has been -interrupted. Since it cannot be determined reliably whether a remote -process has been interrupted, @code{process-file} returns always the -exit code. When the user option +For a local process, @code{process-file} returns either the exit code +of the process, or a string describing a signal, when the process has +been interrupted. Since it cannot be determined reliably whether a +remote process has been interrupted, @code{process-file} will always +returns the exit code for it. When the user option @code{process-file-return-signal-string} is non-@code{nil}, -@code{process-file} regards all exit codes greater than 128 as an +@code{process-file} treats all exit codes greater than 128 as an indication that the process has been interrupted, and returns a -respective string. +corresponding string. -Remote processes do not apply to @acronym{GVFS} (see @ref{GVFS-based -methods}) because the remote file system is mounted on the local host -and @value{tramp} just accesses by changing the +This remote process handling does not apply to @acronym{GVFS} (see +@ref{GVFS-based methods}) because the remote file system is mounted on +the local host and @value{tramp} accesses it by changing the @code{default-directory}. @value{tramp} starts a remote process when a command is executed in a @@ -3239,7 +3241,7 @@ integrated to work with @value{tramp}: @file{shell.el}, @vindex INSIDE_EMACS@r{, environment variable} @value{tramp} always modifies the @env{INSIDE_EMACS} environment -variable for remote processes. Per default, this environment variable +variable for remote processes. By default, this environment variable shows the Emacs version. @value{tramp} adds its own version string, so it looks like @samp{27.2,tramp:2.4.5.1}. However, other packages might also add their name to this environment variable, like @@ -3294,8 +3296,8 @@ local @file{.emacs} file: @vindex ENV@r{, environment variable} Setting the @env{ENV} environment variable instructs some shells to -read an initialization file. Per default, @value{tramp} has disabled -this. You could overwrite this behavior by evaluating +read an initialization file. By default, @value{tramp} disables +this. You can override this behavior by evaluating @lisp @group @@ -4385,7 +4387,7 @@ this @code{nil} setting: @vindex ProxyCommand@r{, ssh option} @vindex ProxyJump@r{, ssh option} -This shall also be set to @code{nil} if you use the +This should also be set to @code{nil} if you use the @option{ProxyCommand} or @option{ProxyJump} options in your @command{ssh} configuration. @@ -4955,9 +4957,9 @@ I get an error @samp{Remote file error: Forbidden reentrant call of Tramp} Timers, process filters and sentinels, and other event based functions can run at any time, when a remote file operation is still running. This can cause @value{tramp} to block. When such a situation is -detected, this error is triggered. It shall be fixed in the -respective function (an error report will help), but for the time -being you can suppress this error by the following code in your +detected, this error is triggered. It should be fixed in the +respective function (sending an error report will help), but for the +time being you can suppress this error by the following code in your @file{~/.emacs}: @lisp @@ -5140,9 +5142,9 @@ sending a string to a process, or waiting for process output. They can run any remote file operation, which would conflict with the already running remote file operation, if the same connection is affected. @value{tramp} detects this situation, and raises the -@code{remote-file-error} error. A timer function shall avoid this -situation. At least, it shall protect itself against this error, by -wrapping the timer function body with +@code{remote-file-error} error. A timer function should avoid this +situation. As a minimum, it should protect itself against this error, by +wrapping the timer function body as follows: @lisp @group @@ -5194,8 +5196,8 @@ Other navigation keys are described in @ref{Outline Visibility, , , emacs}. @end ifinfo -@value{tramp} handles errors internally. But to get a Lisp backtrace, -both the error and the signal have to be set as follows: +@value{tramp} handles errors internally. Hence, to get a Lisp backtrace, +the following settings are required: @lisp @group @@ -5209,15 +5211,15 @@ backtraces are also added to the @value{tramp} debug buffer in case of errors. In very rare cases it could happen, that @value{tramp} blocks Emacs. -Killing Emacs does not allow to inspect the debug buffer. In that -case, you might instruct @value{tramp} to mirror the debug buffer to -file: +Killing Emacs does not allow inspecting the debug buffer. In that +case, you can instruct @value{tramp} to mirror the debug buffer to +a file: @lisp (customize-set-variable 'tramp-debug-to-file t) @end lisp -The debug buffer is written as file in your +The debug buffer is written as a file in your @code{temporary-file-directory}, which is usually @file{/tmp/}. Use this option with care, because it could decrease the performance of @value{tramp} actions. commit 4cb24e44ca49d6acc0354a9a486463bd710796d7 Author: Robert Pluim Date: Tue Feb 23 14:07:32 2021 +0100 * lisp/net/dictionary-connection.el: Grammar fixes * lisp/net/dictionary-connection.el: Grammar fix (dictionary-connection-open): Use active voice. (dictionary-connection-status): Reword and improve formatting. diff --git a/lisp/net/dictionary-connection.el b/lisp/net/dictionary-connection.el index 83125742be..b874c488a8 100644 --- a/lisp/net/dictionary-connection.el +++ b/lisp/net/dictionary-connection.el @@ -22,7 +22,7 @@ ;;; Commentary: -;; dictionary-connection allows to handle TCP-based connections in +;; dictionary-connection allows handling TCP-based connections in ;; client mode where text-based information is exchanged. There is ;; special support for handling CR LF (and the usual CR LF . CR LF ;; terminator). @@ -68,7 +68,7 @@ (defun dictionary-connection-open (server port) "Open a connection to SERVER at PORT. -A data structure identifying the connection is returned" +Return a data structure identifying the connection." (let ((process-buffer (generate-new-buffer (format " connection to %s:%s" server @@ -82,11 +82,11 @@ A data structure identifying the connection is returned" (defun dictionary-connection-status (connection) "Return the status of the CONNECTION. Possible return values are the symbols: -nil: argument is no connection object -'none: argument has no connection -'up: connection is open and buffer is existing -'down: connection is closed -'alone: connection is not associated with a buffer" + nil: argument is not a connection object + 'none: argument is not connected + 'up: connection is open and buffer is existing + 'down: connection is closed + 'alone: connection is not associated with a buffer" (when (dictionary-connection-p connection) (let ((process (dictionary-connection-process connection)) (buffer (dictionary-connection-buffer connection))) commit 7788129c3adb328ce838282ebc303368e2392d5d Author: Robert Pluim Date: Tue Feb 23 13:47:49 2021 +0100 Make message-mailto work for emacsclient * doc/misc/message.texi (System Mailer Setup): Add index entry. Mention option to use emacsclient. * etc/NEWS: Mention emacsclient option for 'mailto:' handling. * etc/emacs-mail.desktop: Add example using emacsclient. * lisp/gnus/message.el (message-mailto): Add optional url argument so we can call it from emacsclient. diff --git a/doc/misc/message.texi b/doc/misc/message.texi index be6c9a419b..1497c710e4 100644 --- a/doc/misc/message.texi +++ b/doc/misc/message.texi @@ -540,6 +540,7 @@ better than you do. @node System Mailer Setup @section System Mailer Setup @cindex mailto: +@cindex System Mailer Emacs can be set up as the system mailer, so that Emacs is opened when you click on @samp{mailto:} links in other programs. @@ -548,10 +549,11 @@ How this is done varies from system to system, but commonly there's a way to set the default application for a @acronym{MIME} type, and the relevant type here is @samp{x-scheme-handler/mailto;}. -The application to start should be @samp{"emacs -f message-mailto %u"}. +The application to start should be @w{@samp{emacs -f message-mailto %u}}. This will start Emacs, and then run the @code{message-mailto} command. It will parse the given @acronym{URL}, and set up a Message -buffer with the given parameters. +buffer with the given parameters. If you prefer to use emacsclient, +use @w{@samp{emacsclient -e '(message-mailto "%u")'}} as the application. For instance, @samp{mailto:larsi@@gnus.org?subject=This+is+a+test} will open a Message buffer with the @samp{To:} header filled in with diff --git a/etc/NEWS b/etc/NEWS index 2411ddb830..236c8a9730 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -830,10 +830,12 @@ instances. Emacs can be defined as a handler for the "x-scheme-handler/mailto" MIME type with the following command: "emacs -f message-mailto %u". An "emacs-mail.desktop" file has been included, suitable for -installing in desktop directories like "/usr/share/applications". +installing in desktop directories like "/usr/share/applications" or +"~/.local/share/applications". Clicking on a 'mailto:' link in other applications will then open Emacs with headers filled out according to the link, e.g. -"mailto:larsi@gnus.org?subject=This+is+a+test". +"mailto:larsi@gnus.org?subject=This+is+a+test". If you prefer +emacsclient, use "emacsclient -e '(message-mailto "%u")'" --- *** Change to default value of 'message-draft-headers' user option. diff --git a/etc/emacs-mail.desktop b/etc/emacs-mail.desktop index 3a96b9ec8c..0c5fab1dd1 100644 --- a/etc/emacs-mail.desktop +++ b/etc/emacs-mail.desktop @@ -2,6 +2,8 @@ Categories=Network;Email; Comment=GNU Emacs is an extensible, customizable text editor - and more Exec=emacs -f message-mailto %u +# If you prefer to use emacsclient, use this instead +#Exec=emacsclient -e '(message-mailto "%u")' Icon=emacs Name=Emacs (Mail) MimeType=x-scheme-handler/mailto; diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index ee98099e08..1e0362a3bf 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -8891,15 +8891,16 @@ used to take the screenshot." retval)) ;;;###autoload -(defun message-mailto () +(defun message-mailto (&optional url) "Command to parse command line mailto: links. This is meant to be used for MIME handlers: Setting the handler for \"x-scheme-handler/mailto;\" to \"emacs -f message-mailto %u\" -will then start up Emacs ready to compose mail." +will then start up Emacs ready to compose mail. For emacsclient use + emacsclient -e '(message-mailto \"%u\")'" (interactive) ;; Send email (message-mail) - (message-mailto-1 (pop command-line-args-left))) + (message-mailto-1 (or url (pop command-line-args-left)))) (defun message-mailto-1 (url) (let ((args (message-parse-mailto-url url))) commit 7ebdecfcdfc59f34b4751bcd69b4efabec7be48c Author: Alan Mackenzie Date: Tue Feb 23 11:16:24 2021 +0000 CC Mode: Fix bug in "state cache" invalidation function. * lisp/progmodes/cc-engine.el (c-invalidate-state-cache-1): Rewrite part of it, following the code in c-parse-state-1, to get a proper setting of c-state-cache-good-pos. diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 9038c7bd95..4cf7af843b 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -4319,38 +4319,29 @@ mhtml-mode." (setq c-state-nonlit-pos-cache-limit (1- here))) (c-truncate-lit-pos-cache here) - ;; `c-state-cache': - ;; Case 1: if `here' is in a literal containing point-min, everything - ;; becomes (or is already) nil. - (if (or (null c-state-cache-good-pos) - (< here (c-state-get-min-scan-pos))) - (setq c-state-cache nil - c-state-cache-good-pos nil - c-state-min-scan-pos nil) - - ;; Truncate `c-state-cache' and set `c-state-cache-good-pos' to a value - ;; below `here'. To maintain its consistency, we may need to insert a new - ;; brace pair. - (let ((here-bol (c-point 'bol here)) - too-high-pa ; recorded {/(/[ next above or just below here, or nil. - dropped-cons) ; was the last removed element a brace pair? - ;; The easy bit - knock over-the-top bits off `c-state-cache'. - (while (and c-state-cache - (>= (c-state-cache-top-paren) here)) - (setq dropped-cons (consp (car c-state-cache)) - too-high-pa (c-state-cache-top-lparen) - c-state-cache (cdr c-state-cache))) - - ;; Do we need to add in an earlier brace pair, having lopped one off? - (if (and dropped-cons - (<= too-high-pa here)) - (c-append-lower-brace-pair-to-state-cache too-high-pa here here-bol)) - (if (and c-state-cache-good-pos (< here c-state-cache-good-pos)) - (setq c-state-cache-good-pos - (or (save-excursion - (goto-char here) - (c-literal-start)) - here))))) + (cond + ;; `c-state-cache': + ;; Case 1: if `here' is in a literal containing point-min, everything + ;; becomes (or is already) nil. + ((or (null c-state-cache-good-pos) + (< here (c-state-get-min-scan-pos))) + (setq c-state-cache nil + c-state-cache-good-pos nil + c-state-min-scan-pos nil)) + + ;; Case 2: `here' is below `c-state-cache-good-pos', so we need to amend + ;; the entire `c-state-cache' data. + ((< here c-state-cache-good-pos) + (let* ((res (c-remove-stale-state-cache-backwards here)) + (good-pos (car res)) + (scan-backward-pos (cadr res)) + (scan-forward-p (car (cddr res)))) + (if scan-backward-pos + (c-append-lower-brace-pair-to-state-cache scan-backward-pos here)) + (setq c-state-cache-good-pos + (if scan-forward-p + (c-append-to-state-cache good-pos here) + good-pos))))) ;; The brace-pair desert marker: (when (car c-state-brace-pair-desert) commit b03d9d2c13085b23cf50cbb651ea2c592fe3739d Author: Stefan Kangas Date: Tue Feb 23 03:51:12 2021 +0100 Convert some more menus to easy-menu-define * lisp/tar-mode.el (tar-mode-map): * lisp/textmodes/sgml-mode.el (sgml-mode-map, html-mode-map): * lisp/wdired.el (wdired-mode-map): Move menus from here... * lisp/tar-mode.el (tar-mode-immediate-menu, tar-mode-mark-menu) * lisp/textmodes/sgml-mode.el (sgml-mode-menu, html-mode-menu): * lisp/wdired.el (wdired-mode-menu): ...to here, and convert to easy-menu-define. diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el index 89a71ac2b8..59f7c87e99 100644 --- a/lisp/tar-mode.el +++ b/lisp/tar-mode.el @@ -635,54 +635,38 @@ For instance, if mode is #o700, then it produces `rwx------'." ;; Let mouse-1 follow the link. (define-key map [follow-link] 'mouse-face) - ;; Make menu bar items. - ;; Get rid of the Edit menu bar item to save space. (define-key map [menu-bar edit] 'undefined) - (define-key map [menu-bar immediate] - (cons "Immediate" (make-sparse-keymap "Immediate"))) - - (define-key map [menu-bar immediate woman] - '("Read Man Page (WoMan)" . woman-tar-extract-file)) - (define-key map [menu-bar immediate view] - '("View This File" . tar-view)) - (define-key map [menu-bar immediate display] - '("Display in Other Window" . tar-display-other-window)) - (define-key map [menu-bar immediate find-file-other-window] - '("Find in Other Window" . tar-extract-other-window)) - (define-key map [menu-bar immediate find-file] - '("Find This File" . tar-extract)) - - (define-key map [menu-bar mark] - (cons "Mark" (make-sparse-keymap "Mark"))) - - (define-key map [menu-bar mark unmark-all] - '("Unmark All" . tar-clear-modification-flags)) - (define-key map [menu-bar mark deletion] - '("Flag" . tar-flag-deleted)) - (define-key map [menu-bar mark unmark] - '("Unflag" . tar-unflag)) - - (define-key map [menu-bar operate] - (cons "Operate" (make-sparse-keymap "Operate"))) - - (define-key map [menu-bar operate chown] - '("Change Owner..." . tar-chown-entry)) - (define-key map [menu-bar operate chgrp] - '("Change Group..." . tar-chgrp-entry)) - (define-key map [menu-bar operate chmod] - '("Change Mode..." . tar-chmod-entry)) - (define-key map [menu-bar operate rename] - '("Rename to..." . tar-rename-entry)) - (define-key map [menu-bar operate copy] - '("Copy to..." . tar-copy)) - (define-key map [menu-bar operate expunge] - '("Expunge Marked Files" . tar-expunge)) - map) "Local keymap for Tar mode listings.") +(easy-menu-define tar-mode-immediate-menu tar-mode-map + "Immediate menu for Tar mode." + '("Immediate" + ["Find This File" tar-extract] + ["Find in Other Window" tar-extract-other-window] + ["Display in Other Window" tar-display-other-window] + ["View This File" tar-view] + ["Read Man Page (WoMan)" woman-tar-extract-file])) + +(easy-menu-define tar-mode-mark-menu tar-mode-map + "Mark menu for Tar mode." + '("Mark" + ["Unflag" tar-unflag] + ["Flag" tar-flag-deleted] + ["Unmark All" tar-clear-modification-flags])) + +(easy-menu-define tar-mode-operate-menu tar-mode-map + "Operate menu for Tar mode." + '("Operate" + ["Expunge Marked Files" tar-expunge] + ["Copy to..." tar-copy] + ["Rename to..." tar-rename-entry] + ["Change Mode..." tar-chmod-entry] + ["Change Group..." tar-chgrp-entry] + ["Change Owner..." tar-chown-entry])) + ;; tar mode is suitable only for specially formatted data. (put 'tar-mode 'mode-class 'special) diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el index 7051f520b9..876347bc81 100644 --- a/lisp/textmodes/sgml-mode.el +++ b/lisp/textmodes/sgml-mode.el @@ -117,8 +117,7 @@ definitions. So we normally turn it off.") This takes effect when first loading the `sgml-mode' library.") (defvar sgml-mode-map - (let ((map (make-keymap)) ;`sparse' doesn't allow binding to charsets. - (menu-map (make-sparse-keymap "SGML"))) + (let ((map (make-keymap))) ;`sparse' doesn't allow binding to charsets. (define-key map "\C-c\C-i" 'sgml-tags-invisible) (define-key map "/" 'sgml-slash) (define-key map "\C-c\C-n" 'sgml-name-char) @@ -153,26 +152,24 @@ This takes effect when first loading the `sgml-mode' library.") (map (nth 1 map))) (while (< (setq c (1+ c)) 256) (aset map c 'sgml-maybe-name-self))) - (define-key map [menu-bar sgml] (cons "SGML" menu-map)) - (define-key menu-map [sgml-validate] '("Validate" . sgml-validate)) - (define-key menu-map [sgml-name-8bit-mode] - '("Toggle 8 Bit Insertion" . sgml-name-8bit-mode)) - (define-key menu-map [sgml-tags-invisible] - '("Toggle Tag Visibility" . sgml-tags-invisible)) - (define-key menu-map [sgml-tag-help] - '("Describe Tag" . sgml-tag-help)) - (define-key menu-map [sgml-delete-tag] - '("Delete Tag" . sgml-delete-tag)) - (define-key menu-map [sgml-skip-tag-forward] - '("Forward Tag" . sgml-skip-tag-forward)) - (define-key menu-map [sgml-skip-tag-backward] - '("Backward Tag" . sgml-skip-tag-backward)) - (define-key menu-map [sgml-attributes] - '("Insert Attributes" . sgml-attributes)) - (define-key menu-map [sgml-tag] '("Insert Tag" . sgml-tag)) map) "Keymap for SGML mode. See also `sgml-specials'.") +(easy-menu-define sgml-mode-menu sgml-mode-map + "Menu for SGML mode." + '("SGML" + ["Insert Tag" sgml-tag] + ["Insert Attributes" sgml-attributes] + ["Backward Tag" sgml-skip-tag-backward] + ["Forward Tag" sgml-skip-tag-forward] + ["Delete Tag" sgml-delete-tag] + ["Describe Tag" sgml-tag-help] + "---" + ["Toggle Tag Visibility" sgml-tags-invisible] + ["Toggle 8 Bit Insertion" sgml-name-8bit-mode] + "---" + ["Validate" sgml-validate])) + (defun sgml-make-syntax-table (specials) (let ((table (make-syntax-table text-mode-syntax-table))) (modify-syntax-entry ?< "(>" table) @@ -1788,8 +1785,7 @@ This defaults to `sgml-quick-keys'. This takes effect when first loading the library.") (defvar html-mode-map - (let ((map (make-sparse-keymap)) - (menu-map (make-sparse-keymap "HTML"))) + (let ((map (make-sparse-keymap))) (set-keymap-parent map sgml-mode-map) (define-key map "\C-c6" 'html-headline-6) (define-key map "\C-c5" 'html-headline-5) @@ -1826,34 +1822,35 @@ This takes effect when first loading the library.") (define-key map "\C-cs" 'html-span)) (define-key map "\C-c\C-s" 'html-autoview-mode) (define-key map "\C-c\C-v" 'browse-url-of-buffer) - (define-key map [menu-bar html] (cons "HTML" menu-map)) - (define-key menu-map [html-autoview-mode] - '("Toggle Autoviewing" . html-autoview-mode)) - (define-key menu-map [browse-url-of-buffer] - '("View Buffer Contents" . browse-url-of-buffer)) - (define-key menu-map [nil] '("--")) - ;;(define-key menu-map "6" '("Heading 6" . html-headline-6)) - ;;(define-key menu-map "5" '("Heading 5" . html-headline-5)) - ;;(define-key menu-map "4" '("Heading 4" . html-headline-4)) - (define-key menu-map "3" '("Heading 3" . html-headline-3)) - (define-key menu-map "2" '("Heading 2" . html-headline-2)) - (define-key menu-map "1" '("Heading 1" . html-headline-1)) - (define-key menu-map "l" '("Radio Buttons" . html-radio-buttons)) - (define-key menu-map "c" '("Checkboxes" . html-checkboxes)) - (define-key menu-map "l" '("List Item" . html-list-item)) - (define-key menu-map "u" '("Unordered List" . html-unordered-list)) - (define-key menu-map "o" '("Ordered List" . html-ordered-list)) - (define-key menu-map "-" '("Horizontal Rule" . html-horizontal-rule)) - (define-key menu-map "\n" '("Line Break" . html-line)) - (define-key menu-map "\r" '("Paragraph" . html-paragraph)) - (define-key menu-map "i" '("Image" . html-image)) - (define-key menu-map "h" '("Href Anchor URL" . html-href-anchor)) - (define-key menu-map "f" '("Href Anchor File" . html-href-anchor-file)) - (define-key menu-map "n" '("Name Anchor" . html-name-anchor)) - (define-key menu-map "#" '("ID Anchor" . html-id-anchor)) map) "Keymap for commands for use in HTML mode.") +(easy-menu-define html-mode-menu html-mode-map + "Menu for HTML mode." + '("HTML" + ["ID Anchor" html-id-anchor] + ["Name Anchor" html-name-anchor] + ["Href Anchor File" html-href-anchor-file] + ["Href Anchor URL" html-href-anchor] + ["Image" html-image] + ["Paragraph" html-paragraph] + ["Line Break" html-line] + ["Horizontal Rule" html-horizontal-rule] + ["Ordered List" html-ordered-list] + ["Unordered List" html-unordered-list] + ["List Item" html-list-item] + ["Checkboxes" html-checkboxes] + ["Radio Buttons" html-radio-buttons] + ["Heading 1" html-headline-1] + ["Heading 2" html-headline-2] + ["Heading 3" html-headline-3] + ;; ["Heading 4" html-headline-4] + ;; ["Heading 5" html-headline-5] + ;; ["Heading 6" html-headline-6] + "---" + ["View Buffer Contents" browse-url-of-buffer] + ["Toggle Autoviewing" html-autoview-mode])) + (defvar html-face-tag-alist '((bold . "strong") (italic . "em") diff --git a/lisp/wdired.el b/lisp/wdired.el index 3829ff1f97..c495d8de34 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -176,26 +176,21 @@ nonexistent directory will fail." (define-key map "\C-p" 'wdired-previous-line) (define-key map [down] 'wdired-next-line) (define-key map "\C-n" 'wdired-next-line) - - (define-key map [menu-bar wdired] - (cons "WDired" (make-sparse-keymap "WDired"))) - (define-key map [menu-bar wdired wdired-customize] - '("Options" . wdired-customize)) - (define-key map [menu-bar wdired dashes] - '("--")) - (define-key map [menu-bar wdired wdired-abort-changes] - '(menu-item "Abort Changes" wdired-abort-changes - :help "Abort changes and return to dired mode")) - (define-key map [menu-bar wdired wdired-finish-edit] - '("Commit Changes" . wdired-finish-edit)) - (define-key map [remap upcase-word] 'wdired-upcase-word) (define-key map [remap capitalize-word] 'wdired-capitalize-word) (define-key map [remap downcase-word] 'wdired-downcase-word) - map) "Keymap used in `wdired-mode'.") +(easy-menu-define wdired-mode-menu wdired-mode-map + "Menu for `wdired-mode'." + '("WDired" + ["Commit Changes" wdired-finish-edit] + ["Abort Changes" wdired-abort-changes + :help "Abort changes and return to Dired mode"] + "---" + ["Options" wdired-customize])) + (defvar wdired-mode-hook nil "Hooks run when changing to WDired mode.") commit 9202106a990d3e82d41ae831fd28419ab55f3cab Author: Stefan Kangas Date: Tue Feb 23 03:24:31 2021 +0100 Improve easymenu.el Commentary section * lisp/emacs-lisp/easymenu.el: Improve Commentary section. diff --git a/lisp/emacs-lisp/easymenu.el b/lisp/emacs-lisp/easymenu.el index 39b3193b2f..bcd5cfd99b 100644 --- a/lisp/emacs-lisp/easymenu.el +++ b/lisp/emacs-lisp/easymenu.el @@ -23,6 +23,9 @@ ;;; Commentary: +;; The `easy-menu-define' macro provides a convenient way to define +;; pop-up menus and/or menu bar menus. +;; ;; This is compatible with easymenu.el by Per Abrahamsen ;; but it is much simpler as it doesn't try to support other Emacs versions. ;; The code was mostly derived from lmenu.el. commit efe42c2b63de8ef5da3e6cb5f576fb5f6eea0281 Author: Stefan Monnier Date: Mon Feb 22 17:38:58 2021 -0500 * lisp/progmodes/antlr-mode.el: Fix bootstrap failure (antlr-mode): Remove compatibility code with older CC-mode. This somehow appears to fix the error: In antlr-mode: progmodes/antlr-mode.el:2426:20: Error: `c-init-language-vars' defined after use in (c-init-language-vars) (missing `require' of a library file?) progmodes/antlr-mode.el:2427:26: Warning: c-init-language-vars called with 0 arguments, but requires 1 No idea what caused the error to appear after the previous patch either. diff --git a/lisp/progmodes/antlr-mode.el b/lisp/progmodes/antlr-mode.el index 3ae017b2a0..d569bf898c 100644 --- a/lisp/progmodes/antlr-mode.el +++ b/lisp/progmodes/antlr-mode.el @@ -2418,16 +2418,7 @@ the default language." (cadr (assq antlr-language antlr-language-alist))))) ;; indentation, for the C engine ------------------------------------------- (setq c-buffer-is-cc-mode antlr-language) - (cond ((fboundp 'c-init-language-vars-for) ; cc-mode 5.30.5+ - (c-init-language-vars-for antlr-language)) - ((fboundp 'c-init-c-language-vars) ; cc-mode 5.30 to 5.30.4 - (c-init-c-language-vars) ; not perfect, but OK - (setq c-recognize-knr-p nil)) - ((fboundp 'c-init-language-vars) ; cc-mode 5.29 - (let ((init-fn 'c-init-language-vars)) - (funcall init-fn))) ; is a function in v5.29 - (t ; cc-mode upto 5.28 - (antlr-c-init-language-vars))) ; do it myself + (c-init-language-vars-for antlr-language) (c-basic-common-init antlr-language (or antlr-indent-style "gnu")) (set (make-local-variable 'outline-regexp) "[^#\n\^M]") (set (make-local-variable 'outline-level) #'c-outline-level) ;TODO: define own @@ -2471,6 +2462,6 @@ Used in `antlr-mode'. Also a useful function in `java-mode-hook'." (provide 'antlr-mode) -;;; Local IspellPersDict: .ispell_antlr +;; Local IspellPersDict: .ispell_antlr ;;; antlr-mode.el ends here commit 97eec9db79443f99eecfd84af73e5249748b9796 Author: Lars Ingebrigtsen Date: Mon Feb 22 23:30:04 2021 +0100 Do mode tagging in decipher.el diff --git a/lisp/play/decipher.el b/lisp/play/decipher.el index 9b2626b19d..47ed6e28b5 100644 --- a/lisp/play/decipher.el +++ b/lisp/play/decipher.el @@ -292,7 +292,7 @@ The most useful commands are: (defun decipher-keypress () "Enter a plaintext or ciphertext character." - (interactive) + (interactive nil decipher-mode) (let ((decipher-function 'decipher-set-map) buffer-read-only) ;Make buffer writable (save-excursion @@ -346,7 +346,7 @@ The most useful commands are: (defun decipher-undo () "Undo a change in Decipher mode." - (interactive) + (interactive nil decipher-mode) ;; If we don't get all the way thru, make last-command indicate that ;; for the following command. (setq this-command t) @@ -487,7 +487,7 @@ The most useful commands are: This records the current alphabet so you can return to it later. You may have any number of checkpoints. Type `\\[decipher-restore-checkpoint]' to restore a checkpoint." - (interactive "sCheckpoint description: ") + (interactive "sCheckpoint description: " decipher-mode) (or (stringp desc) (setq desc "")) (let (alphabet @@ -514,7 +514,7 @@ If point is not on a checkpoint line, moves to the first checkpoint line. If point is on a checkpoint, restores that checkpoint. Type `\\[decipher-make-checkpoint]' to make a checkpoint." - (interactive) + (interactive nil decipher-mode) (beginning-of-line) (if (looking-at "%!\\([A-Z ]+\\)!") ;; Restore this checkpoint: @@ -542,7 +542,7 @@ Type `\\[decipher-make-checkpoint]' to make a checkpoint." This fills any blanks in the cipher alphabet with the unused letters in alphabetical order. Use this when you have a keyword cipher and you have determined the keyword." - (interactive) + (interactive nil decipher-mode) (let ((cipher-char ?A) (ptr decipher-alphabet) buffer-read-only ;Make buffer writable @@ -559,7 +559,7 @@ you have determined the keyword." (defun decipher-show-alphabet () "Display the current cipher alphabet in the message line." - (interactive) + (interactive nil decipher-mode) (message "%s" (mapconcat (lambda (a) (concat @@ -572,7 +572,7 @@ you have determined the keyword." "Reprocess the buffer using the alphabet from the top. This regenerates all deciphered plaintext and clears the undo list. You should use this if you edit the ciphertext." - (interactive) + (interactive nil decipher-mode) (message "Reprocessing buffer...") (let (alphabet buffer-read-only ;Make buffer writable @@ -616,13 +616,13 @@ You should use this if you edit the ciphertext." (defun decipher-frequency-count () "Display the frequency count in the statistics buffer." - (interactive) + (interactive nil decipher-mode) (decipher-analyze) (decipher-display-regexp "^A" "^[A-Z][A-Z]")) (defun decipher-digram-list () "Display the list of digrams in the statistics buffer." - (interactive) + (interactive nil decipher-mode) (decipher-analyze) (decipher-display-regexp "[A-Z][A-Z] +[0-9]" "^$")) @@ -639,7 +639,7 @@ words, and ends 3 words (`*' represents a space). X comes before 8 different letters, after 7 different letters, and is next to a total of 11 different letters. It occurs 14 times, making up 9% of the ciphertext." - (interactive (list (upcase (following-char)))) + (interactive (list (upcase (following-char))) decipher-mode) (decipher-analyze) (let (start end) (with-current-buffer (decipher-stats-buffer) commit 11e22452b0ab6f2ea7679665ed8e9abcbc03eae9 Author: Lars Ingebrigtsen Date: Mon Feb 22 23:27:53 2021 +0100 Do mode tagging in bubbles.el diff --git a/lisp/play/bubbles.el b/lisp/play/bubbles.el index dddd19fa0a..50f65a1215 100644 --- a/lisp/play/bubbles.el +++ b/lisp/play/bubbles.el @@ -772,41 +772,41 @@ static char * dot3d_xpm[] = { (defun bubbles-set-graphics-theme-ascii () "Set graphics theme to `ascii'." - (interactive) + (interactive nil bubbles-mode) (setq bubbles-graphics-theme 'ascii) (bubbles--update-faces-or-images)) (defun bubbles-set-graphics-theme-circles () "Set graphics theme to `circles'." - (interactive) + (interactive nil bubbles-mode) (setq bubbles-graphics-theme 'circles) (bubbles--initialize-images) (bubbles--update-faces-or-images)) (defun bubbles-set-graphics-theme-squares () "Set graphics theme to `squares'." - (interactive) + (interactive nil bubbles-mode) (setq bubbles-graphics-theme 'squares) (bubbles--initialize-images) (bubbles--update-faces-or-images)) (defun bubbles-set-graphics-theme-diamonds () "Set graphics theme to `diamonds'." - (interactive) + (interactive nil bubbles-mode) (setq bubbles-graphics-theme 'diamonds) (bubbles--initialize-images) (bubbles--update-faces-or-images)) (defun bubbles-set-graphics-theme-balls () "Set graphics theme to `balls'." - (interactive) + (interactive nil bubbles-mode) (setq bubbles-graphics-theme 'balls) (bubbles--initialize-images) (bubbles--update-faces-or-images)) (defun bubbles-set-graphics-theme-emacs () "Set graphics theme to `emacs'." - (interactive) + (interactive nil bubbles-mode) (setq bubbles-graphics-theme 'emacs) (bubbles--initialize-images) (bubbles--update-faces-or-images)) @@ -914,7 +914,7 @@ columns on its right towards the left. (defun bubbles-quit () "Quit Bubbles." - (interactive) + (interactive nil bubbles-mode) (message "bubbles-quit") (bury-buffer)) @@ -1165,7 +1165,7 @@ Use optional parameter POS instead of point if given." (defun bubbles-plop () "Remove active bubbles region." - (interactive) + (interactive nil bubbles-mode) (when (and bubbles--playing (> bubbles--neighborhood-score 0)) (setq bubbles--save-data (list bubbles--score (buffer-string))) @@ -1249,7 +1249,7 @@ Use optional parameter POS instead of point if given." (defun bubbles-undo () "Undo last move." - (interactive) + (interactive nil bubbles-mode) (when bubbles--save-data (let ((inhibit-read-only t) (pos (point))) commit 79d585c2befb81ac5480a9577eaeb6e8915cae23 Author: Stefan Monnier Date: Mon Feb 22 16:54:59 2021 -0500 * lisp/obsolete: Use lexical-binding Use lexical-binding in all the lisp/obsolete/*.el files. While at it, removed redundant :group arguments and used #' to quote functions. Commented out the key bindings which the #' revealed to lead to non-existing commands, and replaced those revealed to be obsolete. * lisp/obsolete/cl-compat.el: Use cl-lib. * lisp/obsolete/cust-print.el: Assume `defalias` exists. (with-custom-print): Use `declare`. * lisp/obsolete/iswitchb.el (iswitchb-init-XEmacs-trick) (iswitchb-xemacs-backspacekey): Remove functions. * lisp/obsolete/landmark.el (landmark, landmark-nslify-wts): Prefer `apply` to `eval`. * lisp/obsolete/longlines.el (longlines-mode): Don't use `add-to-list` on a hook. * lisp/obsolete/pgg-gpg.el (pgg-gpg-process-region): Use `clear-string`. * lisp/obsolete/pgg-pgp.el (pgg-pgp-encrypt-region): Remove oddly unused var `passphrase`. (pgg-pgp-verify-region): Declare var `jam-zcat-filename-list`. * lisp/obsolete/pgg-pgp5.el (pgg-pgp5-encrypt-region): Remove oddly unused var `passphrase`. (pgg-pgp5-verify-region): Declare var `jam-zcat-filename-list`. * lisp/obsolete/pgg.el: Remove some XEmacs compatibility code. (pgg-run-at-time, pgg-cancel-timer, pgg-clear-string): Remove functions. Use their core equivalent instead. * lisp/obsolete/rcompile.el (remote-compile): Remove unused vars `l`, `l-host`, `l-user`, and `localname`. * lisp/obsolete/starttls.el (starttls-any-program-available): Use `define-obsolete-function-alias`. * lisp/obsolete/tls.el (tls-format-message): Delete function, use `format-message` instead. * lisp/obsolete/url-ns.el (url-ns-prefs): Use `with-current-buffer` and `dlet`. * lisp/obsolete/vip.el (vip-escape-to-emacs): Remove unused var `key`. (vip-command-argument, vip-read-string, ex-delete, ex-line): Remove unused var `conditions`. (ex-map): Use a closure instead of `eval`. (ex-set): Make it an alias of `set-variable`. (ex-substitute): Remove unused var `cont`. * lisp/obsolete/abbrevlist.el: * lisp/obsolete/bruce.el: * lisp/obsolete/cc-compat.el: * lisp/obsolete/cl-compat.el: * lisp/obsolete/cl.el: * lisp/obsolete/complete.el: * lisp/obsolete/crisp.el: * lisp/obsolete/cust-print.el: * lisp/obsolete/erc-compat.el: * lisp/obsolete/erc-hecomplete.el: * lisp/obsolete/eudcb-ph.el: * lisp/obsolete/fast-lock.el: * lisp/obsolete/gs.el: * lisp/obsolete/gulp.el: * lisp/obsolete/html2text.el: * lisp/obsolete/info-edit.el: * lisp/obsolete/iswitchb.el: * lisp/obsolete/landmark.el: * lisp/obsolete/lazy-lock.el: * lisp/obsolete/longlines.el: * lisp/obsolete/mailpost.el: * lisp/obsolete/mantemp.el: * lisp/obsolete/meese.el: * lisp/obsolete/messcompat.el: * lisp/obsolete/metamail.el: * lisp/obsolete/mouse-sel.el: * lisp/obsolete/nnir.el: * lisp/obsolete/old-emacs-lock.el: * lisp/obsolete/otodo-mode.el: * lisp/obsolete/patcomp.el: * lisp/obsolete/pc-mode.el: * lisp/obsolete/pc-select.el: * lisp/obsolete/pgg-def.el: * lisp/obsolete/pgg-gpg.el: * lisp/obsolete/pgg-parse.el: * lisp/obsolete/pgg-pgp.el: * lisp/obsolete/pgg-pgp5.el: * lisp/obsolete/pgg.el: * lisp/obsolete/rcompile.el: * lisp/obsolete/s-region.el: * lisp/obsolete/sb-image.el: * lisp/obsolete/sregex.el: * lisp/obsolete/starttls.el: * lisp/obsolete/sup-mouse.el: * lisp/obsolete/terminal.el: * lisp/obsolete/tls.el: * lisp/obsolete/tpu-edt.el: * lisp/obsolete/tpu-extras.el: * lisp/obsolete/tpu-mapper.el: * lisp/obsolete/url-ns.el: * lisp/obsolete/vc-arch.el: * lisp/obsolete/vi.el: * lisp/obsolete/vip.el: * lisp/obsolete/ws-mode.el: * lisp/obsolete/yow.el: Use lexical-binding. diff --git a/lisp/obsolete/abbrevlist.el b/lisp/obsolete/abbrevlist.el index 1d517dbd11..c9c0956903 100644 --- a/lisp/obsolete/abbrevlist.el +++ b/lisp/obsolete/abbrevlist.el @@ -1,4 +1,4 @@ -;;; abbrevlist.el --- list one abbrev table alphabetically ordered +;;; abbrevlist.el --- list one abbrev table alphabetically ordered -*- lexical-binding: t; -*- ;; Copyright (C) 1986, 1992, 2001-2021 Free Software Foundation, Inc. ;; Suggested by a previous version by Gildea. @@ -38,7 +38,7 @@ (function (lambda (abbrev) (setq abbrev-list (cons abbrev abbrev-list)))) abbrev-table) - (setq abbrev-list (sort abbrev-list 'string-lessp)) + (setq abbrev-list (sort abbrev-list #'string-lessp)) (while abbrev-list (if (> (+ first-column 40) (window-width)) (progn diff --git a/lisp/obsolete/bruce.el b/lisp/obsolete/bruce.el index 398f315c5d..4aa6cd200e 100644 --- a/lisp/obsolete/bruce.el +++ b/lisp/obsolete/bruce.el @@ -1,4 +1,4 @@ -;;; bruce.el --- bruce phrase utility for overloading the Communications +;;; bruce.el --- bruce phrase utility for overloading the Communications -*- lexical-binding: t; -*- ;;; Decency Act snoops, if any. ;; Copyright (C) 1988, 1993, 1997, 2001-2021 Free Software Foundation, @@ -113,13 +113,11 @@ (defcustom bruce-phrases-file "~/bruce.lines" "Keep your favorite phrases here." - :type 'file - :group 'bruce) + :type 'file) (defcustom bruce-phrase-default-count 15 "Default number of phrases to insert." - :type 'integer - :group 'bruce) + :type 'integer) ;;;###autoload (defun bruce () diff --git a/lisp/obsolete/cc-compat.el b/lisp/obsolete/cc-compat.el index 96b036e892..037a8e9e87 100644 --- a/lisp/obsolete/cc-compat.el +++ b/lisp/obsolete/cc-compat.el @@ -1,4 +1,4 @@ -;;; cc-compat.el --- cc-mode compatibility with c-mode.el confusion +;;; cc-compat.el --- cc-mode compatibility with c-mode.el confusion -*- lexical-binding: t; -*- ;; Copyright (C) 1985, 1987, 1992-2021 Free Software Foundation, Inc. @@ -156,7 +156,7 @@ This is in addition to c-continued-statement-offset.") (if bracep 0 c-indent-level))))) -(defun cc-substatement-open-offset (langelem) +(defun cc-substatement-open-offset (_langelem) (+ c-continued-statement-offset c-continued-brace-offset)) diff --git a/lisp/obsolete/cl-compat.el b/lisp/obsolete/cl-compat.el index 4abedf3e62..619bc06122 100644 --- a/lisp/obsolete/cl-compat.el +++ b/lisp/obsolete/cl-compat.el @@ -1,4 +1,4 @@ -;;; cl-compat.el --- Common Lisp extensions for GNU Emacs Lisp (compatibility) +;;; cl-compat.el --- Common Lisp extensions for GNU Emacs Lisp (compatibility) -*- lexical-binding: t; -*- ;; Copyright (C) 1993, 2001-2021 Free Software Foundation, Inc. @@ -46,31 +46,23 @@ ;;; Code: -;; This used to be: -;; (or (featurep 'cl) (require 'cl)) -;; which just has the effect of fooling the byte-compiler into not -;; loading cl when compiling. However, that leads to some bogus -;; compiler warnings. Loading cl when compiling cannot do any harm, -;; because for a long time bootstrap-emacs contained 'cl, due to being -;; dumped from uncompiled files that eval-when-compile'd cl. So every -;; file was compiled with 'cl loaded. -(require 'cl) +(require 'cl-lib) ;;; Keyword routines not supported by new package. (defmacro defkeyword (x &optional doc) - (list* 'defconst x (list 'quote x) (and doc (list doc)))) + (cl-list* 'defconst x (list 'quote x) (and doc (list doc)))) (defun keyword-of (sym) (or (keywordp sym) (keywordp (intern (format ":%s" sym))))) -;;; Multiple values. Note that the new package uses a different -;;; convention for multiple values. The following definitions -;;; emulate the old convention; all function names have been changed -;;; by capitalizing the first letter: Values, Multiple-value-*, -;;; to avoid conflict with the new-style definitions in cl-macs. +;; Multiple values. Note that the new package uses a different +;; convention for multiple values. The following definitions +;; emulate the old convention; all function names have been changed +;; by capitalizing the first letter: Values, Multiple-value-*, +;; to avoid conflict with the new-style definitions in cl-macs. (defvar *mvalues-values* nil) @@ -79,7 +71,7 @@ (car val-forms)) (defun Values-list (val-forms) - (apply 'values val-forms)) + (apply #'cl-values val-forms)) (defmacro Multiple-value-list (form) (list 'let* (list '(*mvalues-values* nil) (list '*mvalues-temp* form)) @@ -95,7 +87,7 @@ (defmacro Multiple-value-bind (vars form &rest body) (declare (indent 2)) - (list* 'multiple-value-bind vars (list 'Multiple-value-list form) body)) + (cl-list* 'multiple-value-bind vars (list 'Multiple-value-list form) body)) (defmacro Multiple-value-setq (vars form) (declare (indent 2)) @@ -103,17 +95,16 @@ (defmacro Multiple-value-prog1 (form &rest body) (declare (indent 1)) - (list 'prog1 form (list* 'let '((*mvalues-values* nil)) body))) + (list 'prog1 form (cl-list* 'let '((*mvalues-values* nil)) body))) ;;; Routines for parsing keyword arguments. (defun build-klist (arglist keys &optional allow-others) - (let ((res (Multiple-value-call 'mapcar* 'cons (unzip-lists arglist)))) + (let ((res (Multiple-value-call #'cl-mapcar 'cons (unzip-lists arglist)))) (or allow-others - (with-suppressed-warnings ((obsolete set-difference)) - (let ((bad (set-difference (mapcar 'car res) keys))) - (if bad (error "Bad keywords: %s not in %s" bad keys))))) + (let ((bad (cl-set-difference (mapcar #'car res) keys))) + (if bad (error "Bad keywords: %s not in %s" bad keys)))) res)) (defun extract-from-klist (klist key &optional def) @@ -131,18 +122,16 @@ (funcall (or test 'eql) item elt)))) (defun safe-idiv (a b) - (with-suppressed-warnings ((obsolete signum)) - (let* ((q (/ (abs a) (abs b))) - (s (* (signum a) (signum b)))) - (Values q (- a (* s q b)) s)))) + (let* ((q (/ (abs a) (abs b))) + (s (* (cl-signum a) (cl-signum b)))) + (Values q (- a (* s q b)) s))) ;; Internal routines. (defun pair-with-newsyms (oldforms) - (with-suppressed-warnings ((obsolete mapcar*)) - (let ((newsyms (mapcar (lambda (x) (make-symbol "--cl-var--")) oldforms))) - (Values (mapcar* 'list newsyms oldforms) newsyms)))) + (let ((newsyms (mapcar (lambda (_) (make-symbol "--cl-var--")) oldforms))) + (Values (cl-mapcar #'list newsyms oldforms) newsyms))) (defun zip-lists (evens odds) (cl-mapcan 'list evens odds)) @@ -154,7 +143,7 @@ (Values (nreverse e) (nreverse o)))) (defun reassemble-argslists (list) - (let ((n (apply 'min (mapcar 'length list))) (res nil)) + (let ((n (apply #'min (mapcar #'length list))) (res nil)) (while (>= (setq n (1- n)) 0) (setq res (cons (mapcar (function (lambda (x) (elt x n))) list) res))) res)) diff --git a/lisp/obsolete/cl.el b/lisp/obsolete/cl.el index 95af29bb87..f91cfaa34c 100644 --- a/lisp/obsolete/cl.el +++ b/lisp/obsolete/cl.el @@ -331,7 +331,7 @@ The two cases that are handled are: (cddr f)))) (if (and cl-closure-vars (cl--expr-contains-any body cl-closure-vars)) - (let* ((new (mapcar 'cl-gensym cl-closure-vars)) + (let* ((new (mapcar #'cl-gensym cl-closure-vars)) (sub (cl-pairlis cl-closure-vars new)) (decls nil)) (while (or (stringp (car body)) (eq (car-safe (car body)) 'interactive)) @@ -446,7 +446,7 @@ will not work - use `labels' instead" (symbol-name (car x)))) ;; FIXME This affects the rest of the file, when it ;; should be restricted to the flet body. (and (boundp 'byte-compile-function-environment) - (push (cons (car x) (eval func)) + (push (cons (car x) (eval func t)) byte-compile-function-environment))) (list `(symbol-function ',(car x)) func))) bindings) @@ -630,10 +630,10 @@ You can replace this macro with `gv-letplace'." ;;; Additional compatibility code. ;; For names that were clean but really aren't needed any more. -(define-obsolete-function-alias 'cl-macroexpand 'macroexpand "24.3") +(define-obsolete-function-alias 'cl-macroexpand #'macroexpand "24.3") (define-obsolete-variable-alias 'cl-macro-environment 'macroexpand-all-environment "24.3") -(define-obsolete-function-alias 'cl-macroexpand-all 'macroexpand-all "24.3") +(define-obsolete-function-alias 'cl-macroexpand-all #'macroexpand-all "24.3") ;;; Hash tables. ;; This is just kept for compatibility with code byte-compiled by Emacs-20. @@ -652,22 +652,22 @@ You can replace this macro with `gv-letplace'." (defvar cl-builtin-maphash (symbol-function 'maphash)) (make-obsolete-variable 'cl-builtin-maphash nil "24.3") -(define-obsolete-function-alias 'cl-map-keymap 'map-keymap "24.3") -(define-obsolete-function-alias 'cl-copy-tree 'copy-tree "24.3") -(define-obsolete-function-alias 'cl-gethash 'gethash "24.3") -(define-obsolete-function-alias 'cl-puthash 'puthash "24.3") -(define-obsolete-function-alias 'cl-remhash 'remhash "24.3") -(define-obsolete-function-alias 'cl-clrhash 'clrhash "24.3") -(define-obsolete-function-alias 'cl-maphash 'maphash "24.3") -(define-obsolete-function-alias 'cl-make-hash-table 'make-hash-table "24.3") -(define-obsolete-function-alias 'cl-hash-table-p 'hash-table-p "24.3") -(define-obsolete-function-alias 'cl-hash-table-count 'hash-table-count "24.3") +(define-obsolete-function-alias 'cl-map-keymap #'map-keymap "24.3") +(define-obsolete-function-alias 'cl-copy-tree #'copy-tree "24.3") +(define-obsolete-function-alias 'cl-gethash #'gethash "24.3") +(define-obsolete-function-alias 'cl-puthash #'puthash "24.3") +(define-obsolete-function-alias 'cl-remhash #'remhash "24.3") +(define-obsolete-function-alias 'cl-clrhash #'clrhash "24.3") +(define-obsolete-function-alias 'cl-maphash #'maphash "24.3") +(define-obsolete-function-alias 'cl-make-hash-table #'make-hash-table "24.3") +(define-obsolete-function-alias 'cl-hash-table-p #'hash-table-p "24.3") +(define-obsolete-function-alias 'cl-hash-table-count #'hash-table-count "24.3") (define-obsolete-function-alias 'cl-map-keymap-recursively - 'cl--map-keymap-recursively "24.3") -(define-obsolete-function-alias 'cl-map-intervals 'cl--map-intervals "24.3") -(define-obsolete-function-alias 'cl-map-extents 'cl--map-overlays "24.3") -(define-obsolete-function-alias 'cl-set-getf 'cl--set-getf "24.3") + #'cl--map-keymap-recursively "24.3") +(define-obsolete-function-alias 'cl-map-intervals #'cl--map-intervals "24.3") +(define-obsolete-function-alias 'cl-map-extents #'cl--map-overlays "24.3") +(define-obsolete-function-alias 'cl-set-getf #'cl--set-getf "24.3") (defun cl-maclisp-member (item list) (declare (obsolete member "24.3")) diff --git a/lisp/obsolete/complete.el b/lisp/obsolete/complete.el index 735e1e0b6a..1c1167db89 100644 --- a/lisp/obsolete/complete.el +++ b/lisp/obsolete/complete.el @@ -1,4 +1,4 @@ -;;; complete.el --- partial completion mechanism plus other goodies +;;; complete.el --- partial completion mechanism plus other goodies -*- lexical-binding: t; -*- ;; Copyright (C) 1990-1993, 1999-2021 Free Software Foundation, Inc. @@ -102,14 +102,12 @@ If non-nil and non-t, the first character is taken literally only for file name completion." :type '(choice (const :tag "delimiter" nil) (const :tag "literal" t) - (other :tag "find-file" find-file)) - :group 'partial-completion) + (other :tag "find-file" find-file))) (defcustom PC-meta-flag t "If non-nil, TAB means PC completion and M-TAB means normal completion. Otherwise, TAB means normal completion and M-TAB means Partial Completion." - :type 'boolean - :group 'partial-completion) + :type 'boolean) (defcustom PC-word-delimiters "-_. " "A string of characters treated as word delimiters for completion. @@ -119,19 +117,16 @@ If `^' is in this string, it must not come first. If `-' is in this string, it must come first or right after `]'. In other words, if S is this string, then `[S]' must be a valid Emacs regular expression (not containing character ranges like `a-z')." - :type 'string - :group 'partial-completion) + :type 'string) (defcustom PC-include-file-path '("/usr/include" "/usr/local/include") "A list of directories in which to look for include files. If nil, means use the colon-separated path in the variable $INCPATH instead." - :type '(repeat directory) - :group 'partial-completion) + :type '(repeat directory)) (defcustom PC-disable-includes nil "If non-nil, include-file support in \\[find-file] is disabled." - :type 'boolean - :group 'partial-completion) + :type 'boolean) (defvar PC-default-bindings t "If non-nil, default partial completion key bindings are suppressed.") @@ -146,36 +141,36 @@ If nil, means use the colon-separated path in the variable $INCPATH instead." (cond ((not bind) ;; These bindings are the default bindings. It would be better to ;; restore the previous bindings. - (define-key read-expression-map "\e\t" 'lisp-complete-symbol) + (define-key read-expression-map "\e\t" #'completion-at-point) - (define-key completion-map "\t" 'minibuffer-complete) - (define-key completion-map " " 'minibuffer-complete-word) - (define-key completion-map "?" 'minibuffer-completion-help) + (define-key completion-map "\t" #'minibuffer-complete) + (define-key completion-map " " #'minibuffer-complete-word) + (define-key completion-map "?" #'minibuffer-completion-help) - (define-key must-match-map "\r" 'minibuffer-complete-and-exit) - (define-key must-match-map "\n" 'minibuffer-complete-and-exit) + (define-key must-match-map "\r" #'minibuffer-complete-and-exit) + (define-key must-match-map "\n" #'minibuffer-complete-and-exit) (define-key global-map [remap lisp-complete-symbol] nil)) (PC-default-bindings - (define-key read-expression-map "\e\t" 'PC-lisp-complete-symbol) + (define-key read-expression-map "\e\t" #'PC-lisp-complete-symbol) - (define-key completion-map "\t" 'PC-complete) - (define-key completion-map " " 'PC-complete-word) - (define-key completion-map "?" 'PC-completion-help) + (define-key completion-map "\t" #'PC-complete) + (define-key completion-map " " #'PC-complete-word) + (define-key completion-map "?" #'PC-completion-help) - (define-key completion-map "\e\t" 'PC-complete) - (define-key completion-map "\e " 'PC-complete-word) - (define-key completion-map "\e\r" 'PC-force-complete-and-exit) - (define-key completion-map "\e\n" 'PC-force-complete-and-exit) - (define-key completion-map "\e?" 'PC-completion-help) + (define-key completion-map "\e\t" #'PC-complete) + (define-key completion-map "\e " #'PC-complete-word) + (define-key completion-map "\e\r" #'PC-force-complete-and-exit) + (define-key completion-map "\e\n" #'PC-force-complete-and-exit) + (define-key completion-map "\e?" #'PC-completion-help) - (define-key must-match-map "\r" 'PC-complete-and-exit) - (define-key must-match-map "\n" 'PC-complete-and-exit) + (define-key must-match-map "\r" #'PC-complete-and-exit) + (define-key must-match-map "\n" #'PC-complete-and-exit) - (define-key must-match-map "\e\r" 'PC-complete-and-exit) - (define-key must-match-map "\e\n" 'PC-complete-and-exit) + (define-key must-match-map "\e\r" #'PC-complete-and-exit) + (define-key must-match-map "\e\n" #'PC-complete-and-exit) - (define-key global-map [remap lisp-complete-symbol] 'PC-lisp-complete-symbol))))) + (define-key global-map [remap lisp-complete-symbol] #'PC-lisp-complete-symbol))))) (defvar PC-do-completion-end nil "Internal variable used by `PC-do-completion'.") @@ -212,14 +207,15 @@ see), so that if it is neither nil nor t, Emacs shows the `*Completions*' buffer only on the second attempt to complete. That is, if TAB finds nothing to complete, the first TAB just says \"Next char not unique\" and the second TAB brings up the `*Completions*' buffer." - :global t :group 'partial-completion + :global t ;; Deal with key bindings... (PC-bindings partial-completion-mode) ;; Deal with include file feature... (cond ((not partial-completion-mode) - (remove-hook 'find-file-not-found-functions 'PC-look-for-include-file)) + (remove-hook 'find-file-not-found-functions + #'PC-look-for-include-file)) ((not PC-disable-includes) - (add-hook 'find-file-not-found-functions 'PC-look-for-include-file))) + (add-hook 'find-file-not-found-functions #'PC-look-for-include-file))) ;; Adjust the completion selection in *Completion* buffers to the way ;; we work. The default minibuffer completion code only completes the ;; text before point and leaves the text after point alone (new in @@ -229,9 +225,9 @@ second TAB brings up the `*Completions*' buffer." ;; to trick choose-completion into replacing the whole minibuffer text ;; rather than only the text before point. --Stef (funcall - (if partial-completion-mode 'add-hook 'remove-hook) + (if partial-completion-mode #'add-hook #'remove-hook) 'choose-completion-string-functions - (lambda (choice buffer &rest ignored) + (lambda (_choice buffer &rest _) ;; When completing M-: (lisp- ) with point before the ), it is ;; not appropriate to go to point-max (unlike the filename case). (if (and (not PC-goto-end) @@ -648,7 +644,7 @@ GOTO-END is non-nil, however, it instead replaces up to END." (when (string-match regex x) (push x p))) (setq basestr (try-completion "" p))) - (setq basestr (mapconcat 'list str "-")) + (setq basestr (mapconcat #'list str "-")) (delete-region beg end) (setq end (+ beg (length basestr))) (insert basestr)))) @@ -672,7 +668,7 @@ GOTO-END is non-nil, however, it instead replaces up to END." (setq PC-ignored-regexp (concat "\\(" (mapconcat - 'regexp-quote + #'regexp-quote (setq PC-ignored-extensions completion-ignored-extensions) "\\|") @@ -815,7 +811,7 @@ GOTO-END is non-nil, however, it instead replaces up to END." (eq mode 'help)) (let ((prompt-end (minibuffer-prompt-end))) (with-output-to-temp-buffer "*Completions*" - (display-completion-list (sort helpposs 'string-lessp)) + (display-completion-list (sort helpposs #'string-lessp)) (setq PC-do-completion-end end PC-goto-end goto-end) (with-current-buffer standard-output @@ -1093,7 +1089,7 @@ absolute rather than relative to some directory on the SEARCH-PATH." file-lists)))) (setq search-path (cdr search-path)))) ;; Compress out duplicates while building complete list (slloooow!) - (let ((sorted (sort (apply 'nconc file-lists) + (let ((sorted (sort (apply #'nconc file-lists) (lambda (x y) (not (string-lessp x y))))) compressed) (while sorted diff --git a/lisp/obsolete/crisp.el b/lisp/obsolete/crisp.el index 91ff899c84..69bf3ed12b 100644 --- a/lisp/obsolete/crisp.el +++ b/lisp/obsolete/crisp.el @@ -1,4 +1,4 @@ -;;; crisp.el --- CRiSP/Brief Emacs emulator +;;; crisp.el --- CRiSP/Brief Emacs emulator -*- lexical-binding: t; -*- ;; Copyright (C) 1997-1999, 2001-2021 Free Software Foundation, Inc. @@ -66,63 +66,63 @@ (defvar crisp-mode-map (let ((map (make-sparse-keymap))) - (define-key map [(f1)] 'other-window) + (define-key map [(f1)] #'other-window) - (define-key map [(f2) (down)] 'enlarge-window) - (define-key map [(f2) (left)] 'shrink-window-horizontally) - (define-key map [(f2) (right)] 'enlarge-window-horizontally) - (define-key map [(f2) (up)] 'shrink-window) - (define-key map [(f3) (down)] 'split-window-below) - (define-key map [(f3) (right)] 'split-window-right) + (define-key map [(f2) (down)] #'enlarge-window) + (define-key map [(f2) (left)] #'shrink-window-horizontally) + (define-key map [(f2) (right)] #'enlarge-window-horizontally) + (define-key map [(f2) (up)] #'shrink-window) + (define-key map [(f3) (down)] #'split-window-below) + (define-key map [(f3) (right)] #'split-window-right) - (define-key map [(f4)] 'delete-window) - (define-key map [(control f4)] 'delete-other-windows) + (define-key map [(f4)] #'delete-window) + (define-key map [(control f4)] #'delete-other-windows) - (define-key map [(f5)] 'search-forward-regexp) - (define-key map [(f19)] 'search-forward-regexp) - (define-key map [(meta f5)] 'search-backward-regexp) + (define-key map [(f5)] #'search-forward-regexp) + (define-key map [(f19)] #'search-forward-regexp) + (define-key map [(meta f5)] #'search-backward-regexp) - (define-key map [(f6)] 'query-replace) + (define-key map [(f6)] #'query-replace) - (define-key map [(f7)] 'start-kbd-macro) - (define-key map [(meta f7)] 'end-kbd-macro) + (define-key map [(f7)] #'start-kbd-macro) + (define-key map [(meta f7)] #'end-kbd-macro) - (define-key map [(f8)] 'call-last-kbd-macro) - (define-key map [(meta f8)] 'save-kbd-macro) + (define-key map [(f8)] #'call-last-kbd-macro) + ;;(define-key map [(meta f8)] #'save-kbd-macro) ;FIXME:Unknown command? - (define-key map [(f9)] 'find-file) - (define-key map [(meta f9)] 'load-library) + (define-key map [(f9)] #'find-file) + (define-key map [(meta f9)] #'load-library) - (define-key map [(f10)] 'execute-extended-command) - (define-key map [(meta f10)] 'compile) + (define-key map [(f10)] #'execute-extended-command) + (define-key map [(meta f10)] #'compile) - (define-key map [(SunF37)] 'kill-buffer) - (define-key map [(kp-add)] 'crisp-copy-line) - (define-key map [(kp-subtract)] 'crisp-kill-line) + (define-key map [(SunF37)] #'kill-buffer) + (define-key map [(kp-add)] #'crisp-copy-line) + (define-key map [(kp-subtract)] #'crisp-kill-line) ;; just to cover all the bases (GNU Emacs, for instance) - (define-key map [(f24)] 'crisp-kill-line) - (define-key map [(insert)] 'crisp-yank-clipboard) - (define-key map [(f16)] 'crisp-set-clipboard) ; copy on Sun5 kbd - (define-key map [(f20)] 'crisp-kill-region) ; cut on Sun5 kbd - (define-key map [(f18)] 'crisp-yank-clipboard) ; paste on Sun5 kbd + (define-key map [(f24)] #'crisp-kill-line) + (define-key map [(insert)] #'crisp-yank-clipboard) + (define-key map [(f16)] #'crisp-set-clipboard) ; copy on Sun5 kbd + (define-key map [(f20)] #'crisp-kill-region) ; cut on Sun5 kbd + (define-key map [(f18)] #'crisp-yank-clipboard) ; paste on Sun5 kbd - (define-key map [(control f)] 'fill-paragraph-or-region) + ;; (define-key map [(control f)] #'fill-paragraph-or-region) (define-key map [(meta d)] (lambda () (interactive) (beginning-of-line) (kill-line))) - (define-key map [(meta e)] 'find-file) - (define-key map [(meta g)] 'goto-line) - (define-key map [(meta h)] 'help) - (define-key map [(meta i)] 'overwrite-mode) - (define-key map [(meta j)] 'bookmark-jump) - (define-key map [(meta l)] 'crisp-mark-line) - (define-key map [(meta m)] 'set-mark-command) - (define-key map [(meta n)] 'bury-buffer) - (define-key map [(meta p)] 'crisp-unbury-buffer) - (define-key map [(meta u)] 'undo) - (define-key map [(f14)] 'undo) - (define-key map [(meta w)] 'save-buffer) - (define-key map [(meta x)] 'crisp-meta-x-wrapper) + (define-key map [(meta e)] #'find-file) + (define-key map [(meta g)] #'goto-line) + (define-key map [(meta h)] #'help) + (define-key map [(meta i)] #'overwrite-mode) + (define-key map [(meta j)] #'bookmark-jump) + (define-key map [(meta l)] #'crisp-mark-line) + (define-key map [(meta m)] #'set-mark-command) + (define-key map [(meta n)] #'bury-buffer) + (define-key map [(meta p)] #'crisp-unbury-buffer) + (define-key map [(meta u)] #'undo) + (define-key map [(f14)] #'undo) + (define-key map [(meta w)] #'save-buffer) + (define-key map [(meta x)] #'crisp-meta-x-wrapper) (define-key map [(meta ?0)] (lambda () (interactive) (bookmark-set "0"))) @@ -154,21 +154,21 @@ (interactive) (bookmark-set "9"))) - (define-key map [(shift delete)] 'kill-word) - (define-key map [(shift backspace)] 'backward-kill-word) - (define-key map [(control left)] 'backward-word) - (define-key map [(control right)] 'forward-word) + (define-key map [(shift delete)] #'kill-word) + (define-key map [(shift backspace)] #'backward-kill-word) + (define-key map [(control left)] #'backward-word) + (define-key map [(control right)] #'forward-word) - (define-key map [(home)] 'crisp-home) + (define-key map [(home)] #'crisp-home) (define-key map [(control home)] (lambda () (interactive) (move-to-window-line 0))) - (define-key map [(meta home)] 'beginning-of-line) - (define-key map [(end)] 'crisp-end) + (define-key map [(meta home)] #'beginning-of-line) + (define-key map [(end)] #'crisp-end) (define-key map [(control end)] (lambda () (interactive) (move-to-window-line -1))) - (define-key map [(meta end)] 'end-of-line) + (define-key map [(meta end)] #'end-of-line) map) "Local keymap for CRiSP emulation mode. All the bindings are done here instead of globally to try and be @@ -179,8 +179,7 @@ nice to the world.") (defcustom crisp-mode-mode-line-string " *CRiSP*" "String to display in the mode line when CRiSP emulation mode is enabled." - :type 'string - :group 'crisp) + :type 'string) ;;;###autoload (defcustom crisp-mode nil @@ -190,20 +189,18 @@ indicates CRiSP mode is enabled. Setting this variable directly does not take effect; use either M-x customize or the function `crisp-mode'." - :set (lambda (symbol value) (crisp-mode (if value 1 0))) - :initialize 'custom-initialize-default + :set (lambda (_symbol value) (crisp-mode (if value 1 0))) + :initialize #'custom-initialize-default :require 'crisp :version "20.4" - :type 'boolean - :group 'crisp) + :type 'boolean) (defcustom crisp-override-meta-x t "Controls overriding the normal Emacs M-x key binding in the CRiSP emulator. Normally the CRiSP emulator rebinds M-x to `save-buffers-exit-emacs', and provides the usual M-x functionality on the F10 key. If this variable is non-nil, M-x will exit Emacs." - :type 'boolean - :group 'crisp) + :type 'boolean) (defcustom crisp-load-scroll-all nil "Controls loading of the Scroll Lock in the CRiSP emulator. @@ -212,18 +209,15 @@ package when enabling the CRiSP emulator. If this variable is nil when you start the CRiSP emulator, it does not load the scroll-all package." - :type 'boolean - :group 'crisp) + :type 'boolean) (defcustom crisp-load-hook nil "Hooks to run after loading the CRiSP emulator package." - :type 'hook - :group 'crisp) + :type 'hook) (defcustom crisp-mode-hook nil "Hook run by the function `crisp-mode'." - :type 'hook - :group 'crisp) + :type 'hook) (defconst crisp-version "1.34" "The version of the CRiSP emulator.") @@ -370,11 +364,11 @@ normal CRiSP binding) and when it is nil M-x will run (if crisp-load-scroll-all (require 'scroll-all)) (if (featurep 'scroll-all) - (define-key crisp-mode-map [(meta f1)] 'scroll-all-mode)))) + (define-key crisp-mode-map [(meta f1)] #'scroll-all-mode)))) ;; People might use Apropos on `brief'. ;;;###autoload -(defalias 'brief-mode 'crisp-mode) +(defalias 'brief-mode #'crisp-mode) (run-hooks 'crisp-load-hook) (provide 'crisp) diff --git a/lisp/obsolete/cust-print.el b/lisp/obsolete/cust-print.el index c7342b61ae..01fcd38199 100644 --- a/lisp/obsolete/cust-print.el +++ b/lisp/obsolete/cust-print.el @@ -1,4 +1,4 @@ -;;; cust-print.el --- handles print-level and print-circle +;;; cust-print.el --- handles print-level and print-circle -*- lexical-binding: t; -*- ;; Copyright (C) 1992, 2001-2021 Free Software Foundation, Inc. @@ -118,9 +118,6 @@ ;; Emacs 18 doesn't have defalias. ;; Provide def for byte compiler. -(eval-and-compile - (or (fboundp 'defalias) (fset 'defalias 'fset))) - ;; Variables: ;;========================================================= @@ -141,8 +138,7 @@ If non-nil, components at levels equal to or greater than `print-level' are printed simply as `#'. The object to be printed is at level 0, and if the object is a list or vector, its top-level components are at level 1." - :type '(choice (const nil) integer) - :group 'cust-print) + :type '(choice (const nil) integer)) (defcustom print-circle nil @@ -157,14 +153,12 @@ If non-nil, shared substructures anywhere in the structure are printed with `#N=' before the first occurrence (in the order of the print representation) and `#N#' in place of each subsequent occurrence, where N is a positive decimal integer." - :type 'boolean - :group 'cust-print) + :type 'boolean) (defcustom custom-print-vectors nil "Non-nil if printing of vectors should obey `print-level' and `print-length'." - :type 'boolean - :group 'cust-print) + :type 'boolean) ;; Custom printers @@ -201,7 +195,7 @@ Any pair that has the same PREDICATE is first removed." (cust-print-update-custom-printers)) -(defun cust-print-use-custom-printer (object) +(defun cust-print-use-custom-printer (_object) ;; Default function returns nil. nil) @@ -231,11 +225,11 @@ Any pair that has the same PREDICATE is first removed." (defalias (car symbol-pair) (symbol-function (car (cdr symbol-pair))))) -(defun cust-print-original-princ (object &optional stream)) ; dummy def +(defun cust-print-original-princ (_object &optional _stream) nil) ; dummy def ;; Save emacs routines. (if (not (fboundp 'cust-print-original-prin1)) - (mapc 'cust-print-set-function-cell + (mapc #'cust-print-set-function-cell '((cust-print-original-prin1 prin1) (cust-print-original-princ princ) (cust-print-original-print print) @@ -243,14 +237,15 @@ Any pair that has the same PREDICATE is first removed." (cust-print-original-format format) (cust-print-original-message message) (cust-print-original-error error)))) - +(declare-function cust-print-original-format "cust-print") +(declare-function cust-print-original-message "cust-print") (defun custom-print-install () "Replace print functions with general, customizable, Lisp versions. The Emacs subroutines are saved away, and you can reinstall them by running `custom-print-uninstall'." (interactive) - (mapc 'cust-print-set-function-cell + (mapc #'cust-print-set-function-cell '((prin1 custom-prin1) (princ custom-princ) (print custom-print) @@ -264,7 +259,7 @@ by running `custom-print-uninstall'." (defun custom-print-uninstall () "Reset print functions to their Emacs subroutines." (interactive) - (mapc 'cust-print-set-function-cell + (mapc #'cust-print-set-function-cell '((prin1 cust-print-original-prin1) (princ cust-print-original-princ) (print cust-print-original-print) @@ -275,22 +270,20 @@ by running `custom-print-uninstall'." )) t) -(defalias 'custom-print-funcs-installed-p 'custom-print-installed-p) +(defalias 'custom-print-funcs-installed-p #'custom-print-installed-p) (defun custom-print-installed-p () "Return t if custom-print is currently installed, nil otherwise." (eq (symbol-function 'custom-prin1) (symbol-function 'prin1))) -(put 'with-custom-print-funcs 'edebug-form-spec '(body)) -(put 'with-custom-print 'edebug-form-spec '(body)) - -(defalias 'with-custom-print-funcs 'with-custom-print) (defmacro with-custom-print (&rest body) "Temporarily install the custom print package while executing BODY." + (declare (debug t)) `(unwind-protect (progn (custom-print-install) ,@body) (custom-print-uninstall))) +(defalias 'with-custom-print-funcs #'with-custom-print) ;; Lisp replacements for prin1 and princ, and for some subrs that use them @@ -369,7 +362,7 @@ vector, or symbol args. The format specification for such args should be `%s' in any case, so a string argument will also work. The string is generated with `custom-prin1-to-string', which quotes quotable characters." - (apply 'cust-print-original-format fmt + (apply #'cust-print-original-format fmt (mapcar (function (lambda (arg) (if (or (listp arg) (vectorp arg) (symbolp arg)) (custom-prin1-to-string arg) @@ -393,7 +386,7 @@ See `custom-format' for the details." ;; because the echo area requires special handling ;; to avoid duplicating the output. ;; cust-print-original-message does it right. - (apply 'cust-print-original-message fmt + (apply #'cust-print-original-message fmt (mapcar (function (lambda (arg) (if (or (listp arg) (vectorp arg) (symbolp arg)) (custom-prin1-to-string arg) @@ -406,7 +399,7 @@ See `custom-format' for the details." This is the custom-print replacement for the standard `error'. See `custom-format' for the details." - (signal 'error (list (apply 'custom-format fmt args)))) + (signal 'error (list (apply #'custom-format fmt args)))) @@ -417,9 +410,9 @@ See `custom-format' for the details." (defvar circle-table) (defvar cust-print-current-level) -(defun cust-print-original-printer (object)) ; One of the standard printers. -(defun cust-print-low-level-prin (object)) ; Used internally. -(defun cust-print-prin (object)) ; Call this to print recursively. +(defun cust-print-original-printer (_object) nil) ; One of the standard printers. +(defun cust-print-low-level-prin (_object) nil) ; Used internally. +(defun cust-print-prin (_object) nil) ; Call this to print recursively. (defun cust-print-top-level (object stream emacs-printer) ;; Set up for printing. diff --git a/lisp/obsolete/erc-compat.el b/lisp/obsolete/erc-compat.el index 203ef079c1..3a1699adac 100644 --- a/lisp/obsolete/erc-compat.el +++ b/lisp/obsolete/erc-compat.el @@ -1,4 +1,4 @@ -;;; erc-compat.el --- ERC compatibility code for XEmacs +;;; erc-compat.el --- ERC compatibility code for XEmacs -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2003, 2005-2021 Free Software Foundation, Inc. @@ -31,7 +31,7 @@ (require 'format-spec) ;;;###autoload(autoload 'erc-define-minor-mode "erc-compat") -(defalias 'erc-define-minor-mode 'define-minor-mode) +(defalias 'erc-define-minor-mode #'define-minor-mode) (put 'erc-define-minor-mode 'edebug-form-spec 'define-minor-mode) (defun erc-decode-coding-string (s coding-system) @@ -73,7 +73,7 @@ are placed. Note that this should end with a directory separator.") (defun erc-replace-match-subexpression-in-string - (newtext string match subexp start &optional fixedcase literal) + (newtext string _match subexp _start &optional fixedcase literal) "Replace the subexpression SUBEXP of the last match in STRING with NEWTEXT. MATCH is the text which matched the subexpression (see `match-string'). START is the beginning position of the last match (see `match-beginning'). diff --git a/lisp/obsolete/erc-hecomplete.el b/lisp/obsolete/erc-hecomplete.el index fce79f7f34..36b08d56f7 100644 --- a/lisp/obsolete/erc-hecomplete.el +++ b/lisp/obsolete/erc-hecomplete.el @@ -1,4 +1,4 @@ -;;; erc-hecomplete.el --- Provides Nick name completion for ERC +;;; erc-hecomplete.el --- Provides Nick name completion for ERC -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2002, 2004, 2006-2021 Free Software Foundation, ;; Inc. @@ -39,8 +39,8 @@ ;;;###autoload (autoload 'erc-hecomplete-mode "erc-hecomplete" nil t) (define-erc-module hecomplete nil "Complete nick at point." - ((add-hook 'erc-complete-functions 'erc-hecomplete)) - ((remove-hook 'erc-complete-functions 'erc-hecomplete))) + ((add-hook 'erc-complete-functions #'erc-hecomplete)) + ((remove-hook 'erc-complete-functions #'erc-hecomplete))) (defun erc-hecomplete () "Complete nick at point. @@ -70,15 +70,13 @@ or you may use an arbitrary lisp expression." erc-nick-completion-exclude-myself) (repeat :tag "List" (string :tag "Nick")) function - sexp) - :group 'erc-hecomplete) + sexp)) (defcustom erc-nick-completion-ignore-case t "Non-nil means don't consider case significant in nick completion. Case will be automatically corrected when non-nil. For instance if you type \"dely TAB\" the word completes and changes to \"delYsid\"." - :group 'erc-hecomplete :type 'boolean) (defun erc-nick-completion-exclude-myself () @@ -95,7 +93,6 @@ typing \"f o TAB\" will directly give you foobar. Use this with (defcustom erc-nick-completion-postfix ": " "When `erc-complete' is used in the first word after the prompt, add this string when a unique expansion was found." - :group 'erc-hecomplete :type 'string) (defun erc-command-list () diff --git a/lisp/obsolete/eudcb-ph.el b/lisp/obsolete/eudcb-ph.el index c7212e3fdb..187879ce2f 100644 --- a/lisp/obsolete/eudcb-ph.el +++ b/lisp/obsolete/eudcb-ph.el @@ -1,4 +1,4 @@ -;;; eudcb-ph.el --- Emacs Unified Directory Client - CCSO PH/QI Backend +;;; eudcb-ph.el --- Emacs Unified Directory Client - CCSO PH/QI Backend -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2021 Free Software Foundation, Inc. @@ -69,7 +69,7 @@ defaulting to `eudc-default-return-attributes'." query " ")) (if return-fields - (concat " return " (mapconcat 'symbol-name return-fields " "))))) + (concat " return " (mapconcat #'symbol-name return-fields " "))))) (and (> (length request) 6) (eudc-ph-do-request request) (eudc-ph-parse-query-result return-fields)))) @@ -189,7 +189,7 @@ SERVER is either a string naming the server or a list (NAME PORT)." (with-current-buffer (process-buffer process) (eudc-ph-send-command process "quit") (eudc-ph-read-response process) - (run-at-time 2 nil 'delete-process process))) + (run-at-time 2 nil #'delete-process process))) (defun eudc-ph-send-command (process command) (goto-char (point-max)) diff --git a/lisp/obsolete/fast-lock.el b/lisp/obsolete/fast-lock.el index 7f2cd4b770..baed8be766 100644 --- a/lisp/obsolete/fast-lock.el +++ b/lisp/obsolete/fast-lock.el @@ -438,8 +438,7 @@ See `fast-lock-mode'." ;; Flag so that a cache will be saved later even if the file is never saved. (setq fast-lock-cache-timestamp nil)) -(defalias 'fast-lock-after-unfontify-buffer - 'ignore) +(defalias 'fast-lock-after-unfontify-buffer #'ignore) ;; Miscellaneous Functions: @@ -456,7 +455,7 @@ See `fast-lock-mode'." (defun fast-lock-save-caches-before-kill-emacs () ;; Do `fast-lock-save-cache's if `kill-emacs' is on `fast-lock-save-events'. (when (memq 'kill-emacs fast-lock-save-events) - (mapcar 'fast-lock-save-cache (buffer-list)))) + (mapcar #'fast-lock-save-cache (buffer-list)))) (defun fast-lock-cache-directory (directory create) "Return usable directory based on DIRECTORY. @@ -517,7 +516,7 @@ See `fast-lock-cache-directory'." (function (lambda (c) (or (cdr (assq c chars-alist)) (list c)))))) (concat (file-name-as-directory (expand-file-name directory)) - (mapconcat 'char-to-string (apply 'append (mapcar mapchars bufile)) "") + (mapconcat #'char-to-string (apply #'append (mapcar mapchars bufile)) "") ".flc")))) ;; Font Lock Cache Processing Functions: @@ -718,7 +717,7 @@ See `fast-lock-get-face-properties'." (defvar font-lock-inhibit-thing-lock nil)) (unless (fboundp 'font-lock-compile-keywords) - (defalias 'font-lock-compile-keywords 'identity)) + (defalias 'font-lock-compile-keywords #'identity)) (unless (fboundp 'font-lock-eval-keywords) (defun font-lock-eval-keywords (keywords) @@ -740,10 +739,10 @@ See `fast-lock-get-face-properties'." ;; Install ourselves: -(add-hook 'after-save-hook 'fast-lock-save-cache-after-save-file) -(add-hook 'kill-buffer-hook 'fast-lock-save-cache-before-kill-buffer) +(add-hook 'after-save-hook #'fast-lock-save-cache-after-save-file) +(add-hook 'kill-buffer-hook #'fast-lock-save-cache-before-kill-buffer) (unless noninteractive - (add-hook 'kill-emacs-hook 'fast-lock-save-caches-before-kill-emacs)) + (add-hook 'kill-emacs-hook #'fast-lock-save-caches-before-kill-emacs)) ;;;###autoload (when (fboundp 'add-minor-mode) diff --git a/lisp/obsolete/gs.el b/lisp/obsolete/gs.el index 6ab3fc5938..5a82c6b05f 100644 --- a/lisp/obsolete/gs.el +++ b/lisp/obsolete/gs.el @@ -1,4 +1,4 @@ -;;; gs.el --- interface to Ghostscript +;;; gs.el --- interface to Ghostscript -*- lexical-binding: t; -*- ;; Copyright (C) 1998, 2001-2021 Free Software Foundation, Inc. @@ -205,7 +205,7 @@ the form \"WINDOW-ID PIXMAP-ID\". Value is non-nil if successful." (gs-set-ghostview-window-prop frame spec img-width img-height) (gs-set-ghostview-colors-window-prop frame pixel-colors) (setenv "GHOSTVIEW" window-and-pixmap-id) - (setq gs (apply 'start-process "gs" "*GS*" gs-program + (setq gs (apply #'start-process "gs" "*GS*" gs-program (gs-options gs-device file))) (set-process-query-on-exit-flag gs nil) gs) diff --git a/lisp/obsolete/gulp.el b/lisp/obsolete/gulp.el index 0fbaa1cc4f..6ec2f4f772 100644 --- a/lisp/obsolete/gulp.el +++ b/lisp/obsolete/gulp.el @@ -1,4 +1,4 @@ -;;; gulp.el --- ask for updates for Lisp packages +;;; gulp.el --- ask for updates for Lisp packages -*- lexical-binding: t; -*- ;; Copyright (C) 1996, 2001-2021 Free Software Foundation, Inc. @@ -37,18 +37,15 @@ (defcustom gulp-discard "^;+ *Maintainer: *\\(FSF\\|emacs-devel@gnu\\.org\\) *$" "The regexp matching the packages not requiring the request for updates." :version "24.4" ; added emacs-devel - :type 'regexp - :group 'gulp) + :type 'regexp) (defcustom gulp-tmp-buffer "*gulp*" "The name of the temporary buffer." - :type 'string - :group 'gulp) + :type 'string) (defcustom gulp-max-len 2000 "Distance into a Lisp source file to scan for keywords." - :type 'integer - :group 'gulp) + :type 'integer) (defcustom gulp-request-header (concat @@ -57,8 +54,7 @@ I'm going to start pretesting a new version of GNU Emacs soon, so I'd like to ask if you have any updates for the Emacs packages you work on. You're listed as the maintainer of the following package(s):\n\n") "The starting text of a gulp message." - :type 'string - :group 'gulp) + :type 'string) (defcustom gulp-request-end (concat @@ -75,8 +71,7 @@ of information to include. Thanks.") "The closing text in a gulp message." - :type 'string - :group 'gulp) + :type 'string) (declare-function mail-subject "sendmail" ()) (declare-function mail-send "sendmail" ()) diff --git a/lisp/obsolete/html2text.el b/lisp/obsolete/html2text.el index f01561bd12..be0553cb3a 100644 --- a/lisp/obsolete/html2text.el +++ b/lisp/obsolete/html2text.el @@ -1,4 +1,4 @@ -;;; html2text.el --- a simple html to plain text converter -*- coding: utf-8 -*- +;;; html2text.el --- a simple html to plain text converter -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. diff --git a/lisp/obsolete/info-edit.el b/lisp/obsolete/info-edit.el index c8a187c08e..c53616d80e 100644 --- a/lisp/obsolete/info-edit.el +++ b/lisp/obsolete/info-edit.el @@ -36,7 +36,7 @@ (define-obsolete-variable-alias 'Info-edit-map 'Info-edit-mode-map "24.1") (defvar Info-edit-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map text-mode-map) - (define-key map "\C-c\C-c" 'Info-cease-edit) + (define-key map "\C-c\C-c" #'Info-cease-edit) map) "Local keymap used within `e' command of Info.") diff --git a/lisp/obsolete/iswitchb.el b/lisp/obsolete/iswitchb.el index 58cada1374..a7fd6ccb5f 100644 --- a/lisp/obsolete/iswitchb.el +++ b/lisp/obsolete/iswitchb.el @@ -1,4 +1,4 @@ -;;; iswitchb.el --- switch between buffers using substrings +;;; iswitchb.el --- switch between buffers using substrings -*- lexical-binding: t; -*- ;; Copyright (C) 1996-1997, 2000-2021 Free Software Foundation, Inc. @@ -258,8 +258,7 @@ "Non-nil if searching of buffer names should ignore case. If this is non-nil but the user input has any upper case letters, matching is temporarily case sensitive." - :type 'boolean - :group 'iswitchb) + :type 'boolean) (defcustom iswitchb-buffer-ignore '("^ ") @@ -267,8 +266,7 @@ is temporarily case sensitive." For example, traditional behavior is not to list buffers whose names begin with a space, for which the regexp is `^ '. See the source file for example functions that filter buffer names." - :type '(repeat (choice regexp function)) - :group 'iswitchb) + :type '(repeat (choice regexp function))) (put 'iswitchb-buffer-ignore 'risky-local-variable t) (defcustom iswitchb-max-to-show nil @@ -277,8 +275,7 @@ If this value is N, and N is greater than the number of matching buffers, the first N/2 and the last N/2 matching buffers are shown. This can greatly speed up iswitchb if you have a multitude of buffers open." - :type '(choice (const :tag "Show all" nil) integer) - :group 'iswitchb) + :type '(choice (const :tag "Show all" nil) integer)) (defcustom iswitchb-use-virtual-buffers nil "If non-nil, refer to past buffers when none match. @@ -289,8 +286,7 @@ enabled if this variable is configured to a non-nil value." :set (function (lambda (sym value) (if value (recentf-mode 1)) - (set sym value))) - :group 'iswitchb) + (set sym value)))) (defvar iswitchb-virtual-buffers nil) @@ -299,8 +295,7 @@ enabled if this variable is configured to a non-nil value." The most useful values are `iswitchb-completion-help', which pops up a window with completion alternatives, or `iswitchb-next-match' or `iswitchb-prev-match', which cycle the buffer list." - :type 'hook - :group 'iswitchb) + :type 'hook) ;; Examples for setting the value of iswitchb-buffer-ignore ;;(defun iswitchb-ignore-c-mode (name) @@ -328,46 +323,38 @@ Possible values: (const display) (const otherframe) (const maybe-frame) - (const always-frame)) - :group 'iswitchb) + (const always-frame))) (defcustom iswitchb-regexp nil "Non-nil means that `iswitchb' will do regexp matching. Value can be toggled within `iswitchb' using `iswitchb-toggle-regexp'." - :type 'boolean - :group 'iswitchb) + :type 'boolean) (defcustom iswitchb-newbuffer t "Non-nil means create new buffer if no buffer matches substring. See also `iswitchb-prompt-newbuffer'." - :type 'boolean - :group 'iswitchb) + :type 'boolean) (defcustom iswitchb-prompt-newbuffer t "Non-nil means prompt user to confirm before creating new buffer. See also `iswitchb-newbuffer'." - :type 'boolean - :group 'iswitchb) + :type 'boolean) (defcustom iswitchb-use-faces t "Non-nil means use font-lock faces for showing first match." - :type 'boolean - :group 'iswitchb) + :type 'boolean) (defcustom iswitchb-use-frame-buffer-list nil "Non-nil means use the currently selected frame's buffer list." - :type 'boolean - :group 'iswitchb) + :type 'boolean) (defcustom iswitchb-make-buflist-hook nil "Hook to run when list of matching buffers is created." - :type 'hook - :group 'iswitchb) + :type 'hook) (defcustom iswitchb-delim "," "Delimiter to put between buffer names when displaying results." - :type 'string - :group 'iswitchb) + :type 'string) (defcustom iswitchb-all-frames 'visible "Argument to pass to `walk-windows' when iswitchb is finding buffers. @@ -375,8 +362,7 @@ See documentation of `walk-windows' for useful values." :type '(choice (const :tag "Selected frame only" nil) (const :tag "All existing frames" t) (const :tag "All visible frames" visible) - (const :tag "All frames on this terminal" 0)) - :group 'iswitchb) + (const :tag "All frames on this terminal" 0))) (defcustom iswitchb-minibuffer-setup-hook nil "Iswitchb-specific customization of minibuffer setup. @@ -387,37 +373,32 @@ For instance: \\='\(lambda () (set (make-local-variable \\='max-mini-window-height) 3))) will constrain the minibuffer to a maximum height of 3 lines when iswitchb is running." - :type 'hook - :group 'iswitchb) + :type 'hook) (defface iswitchb-single-match '((t (:inherit font-lock-comment-face))) "Iswitchb face for single matching buffer name." - :version "22.1" - :group 'iswitchb) + :version "22.1") (defface iswitchb-current-match '((t (:inherit font-lock-function-name-face))) "Iswitchb face for current matching buffer name." - :version "22.1" - :group 'iswitchb) + :version "22.1") (defface iswitchb-virtual-matches '((t (:inherit font-lock-builtin-face))) "Iswitchb face for matching virtual buffer names. See also `iswitchb-use-virtual-buffers'." - :version "22.1" - :group 'iswitchb) + :version "22.1") (defface iswitchb-invalid-regexp '((t (:inherit font-lock-warning-face))) "Iswitchb face for indicating invalid regexp. " - :version "22.1" - :group 'iswitchb) + :version "22.1") ;; Do we need the variable iswitchb-use-mycompletion? @@ -465,18 +446,18 @@ interfere with other minibuffer usage.") (defvar iswitchb-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map minibuffer-local-map) - (define-key map "?" 'iswitchb-completion-help) - (define-key map "\C-s" 'iswitchb-next-match) - (define-key map "\C-r" 'iswitchb-prev-match) - (define-key map [?\C-.] 'iswitchb-next-match) - (define-key map [?\C-,] 'iswitchb-prev-match) - (define-key map "\t" 'iswitchb-complete) - (define-key map "\C-j" 'iswitchb-select-buffer-text) - (define-key map "\C-t" 'iswitchb-toggle-regexp) - (define-key map "\C-x\C-f" 'iswitchb-find-file) - (define-key map "\C-c" 'iswitchb-toggle-case) - (define-key map "\C-k" 'iswitchb-kill-buffer) - (define-key map "\C-m" 'iswitchb-exit-minibuffer) + (define-key map "?" #'iswitchb-completion-help) + (define-key map "\C-s" #'iswitchb-next-match) + (define-key map "\C-r" #'iswitchb-prev-match) + (define-key map [?\C-.] #'iswitchb-next-match) + (define-key map [?\C-,] #'iswitchb-prev-match) + (define-key map "\t" #'iswitchb-complete) + (define-key map "\C-j" #'iswitchb-select-buffer-text) + (define-key map "\C-t" #'iswitchb-toggle-regexp) + (define-key map "\C-x\C-f" #'iswitchb-find-file) + (define-key map "\C-c" #'iswitchb-toggle-case) + (define-key map "\C-k" #'iswitchb-kill-buffer) + (define-key map "\C-m" #'iswitchb-exit-minibuffer) map) "Minibuffer keymap for `iswitchb-buffer'.") @@ -596,17 +577,17 @@ the selection process begins. Used by isearchb.el." (let ((map (copy-keymap minibuffer-local-map)) buf-sel iswitchb-final-text icomplete-mode) ; prevent icomplete starting up - (define-key map "?" 'iswitchb-completion-help) - (define-key map "\C-s" 'iswitchb-next-match) - (define-key map "\C-r" 'iswitchb-prev-match) - (define-key map "\t" 'iswitchb-complete) - (define-key map "\C-j" 'iswitchb-select-buffer-text) - (define-key map "\C-t" 'iswitchb-toggle-regexp) - (define-key map "\C-x\C-f" 'iswitchb-find-file) - (define-key map "\C-n" 'iswitchb-toggle-ignore) - (define-key map "\C-c" 'iswitchb-toggle-case) - (define-key map "\C-k" 'iswitchb-kill-buffer) - (define-key map "\C-m" 'iswitchb-exit-minibuffer) + (define-key map "?" #'iswitchb-completion-help) + (define-key map "\C-s" #'iswitchb-next-match) + (define-key map "\C-r" #'iswitchb-prev-match) + (define-key map "\t" #'iswitchb-complete) + (define-key map "\C-j" #'iswitchb-select-buffer-text) + (define-key map "\C-t" #'iswitchb-toggle-regexp) + (define-key map "\C-x\C-f" #'iswitchb-find-file) + (define-key map "\C-n" #'iswitchb-toggle-ignore) + (define-key map "\C-c" #'iswitchb-toggle-case) + (define-key map "\C-k" #'iswitchb-kill-buffer) + (define-key map "\C-m" #'iswitchb-exit-minibuffer) (setq iswitchb-mode-map map) (run-hooks 'iswitchb-define-mode-map-hook) @@ -946,9 +927,9 @@ If `iswitchb-change-word-sub' cannot be found in WORD, return nil." (if iswitchb-regexp subs (regexp-quote subs))) - (setq res (mapcar 'iswitchb-word-matching-substring lis)) + (setq res (mapcar #'iswitchb-word-matching-substring lis)) (setq res (delq nil res)) ;; remove any nil elements (shouldn't happen) - (setq alist (mapcar 'iswitchb-makealist res)) ;; could use an OBARRAY + (setq alist (mapcar #'iswitchb-makealist res)) ;; could use an OBARRAY ;; try-completion returns t if there is an exact match. (let ((completion-ignore-case (iswitchb-case))) @@ -1148,43 +1129,6 @@ For details of keybindings, do `\\[describe-function] iswitchb'." (setq iswitchb-method 'otherframe) (iswitchb)) -;;; XEmacs hack for showing default buffer - -;; The first time we enter the minibuffer, Emacs puts up the default -;; buffer to switch to, but XEmacs doesn't -- presumably there is a -;; subtle difference in the two versions of post-command-hook. The -;; default is shown for both whenever we delete all of our text -;; though, indicating its just a problem the first time we enter the -;; function. To solve this, we use another entry hook for emacs to -;; show the default the first time we enter the minibuffer. - -(defun iswitchb-init-XEmacs-trick () - "Display default buffer when first entering minibuffer. -This is a hack for XEmacs, and should really be handled by `iswitchb-exhibit'." - (if (iswitchb-entryfn-p) - (progn - (iswitchb-exhibit) - (goto-char (point-min))))) - -;; add this hook for XEmacs only. -(if (featurep 'xemacs) - (add-hook 'iswitchb-minibuffer-setup-hook - 'iswitchb-init-XEmacs-trick)) - -;;; XEmacs / backspace key -;; For some reason, if the backspace key is pressed in XEmacs, the -;; line gets confused, so I've added a simple key definition to make -;; backspace act like the normal delete key. - -(defun iswitchb-xemacs-backspacekey () - "Bind backspace to `backward-delete-char'." - (define-key iswitchb-mode-map '[backspace] 'backward-delete-char) - (define-key iswitchb-mode-map '[(meta backspace)] 'backward-kill-word)) - -(if (featurep 'xemacs) - (add-hook 'iswitchb-define-mode-map-hook - 'iswitchb-xemacs-backspacekey)) - ;;; ICOMPLETE TYPE CODE (defun iswitchb-exhibit () @@ -1273,7 +1217,7 @@ Modified from `icomplete-completions'." iswitchb-virtual-buffers))) (setq head (cdr head))) (setq iswitchb-virtual-buffers (nreverse iswitchb-virtual-buffers) - comps (mapcar 'car iswitchb-virtual-buffers)) + comps (mapcar #'car iswitchb-virtual-buffers)) (let ((comp comps)) (while comp (put-text-property 0 (length (car comp)) @@ -1323,8 +1267,9 @@ Modified from `icomplete-completions'." (most-len (length most)) most-is-exact (alternatives - (mapconcat (if most 'iswitchb-output-completion - 'identity) comps iswitchb-delim))) + (mapconcat (if most #'iswitchb-output-completion + #'identity) + comps iswitchb-delim))) (concat @@ -1356,8 +1301,8 @@ Modified from `icomplete-completions'." Copied from `icomplete-minibuffer-setup-hook'." (when (iswitchb-entryfn-p) (set (make-local-variable 'iswitchb-use-mycompletion) t) - (add-hook 'pre-command-hook 'iswitchb-pre-command nil t) - (add-hook 'post-command-hook 'iswitchb-post-command nil t) + (add-hook 'pre-command-hook #'iswitchb-pre-command nil t) + (add-hook 'post-command-hook #'iswitchb-post-command nil t) (run-hooks 'iswitchb-minibuffer-setup-hook))) (defun iswitchb-pre-command () @@ -1416,10 +1361,10 @@ See the variable `iswitchb-case' for details." Iswitchb mode is a global minor mode that enables switching between buffers using substrings. See `iswitchb' for details." - nil nil iswitchb-global-map :global t :group 'iswitchb + nil nil iswitchb-global-map :global t (if iswitchb-mode - (add-hook 'minibuffer-setup-hook 'iswitchb-minibuffer-setup) - (remove-hook 'minibuffer-setup-hook 'iswitchb-minibuffer-setup))) + (add-hook 'minibuffer-setup-hook #'iswitchb-minibuffer-setup) + (remove-hook 'minibuffer-setup-hook #'iswitchb-minibuffer-setup))) (provide 'iswitchb) diff --git a/lisp/obsolete/landmark.el b/lisp/obsolete/landmark.el index ae15109bea..cc4fd19c38 100644 --- a/lisp/obsolete/landmark.el +++ b/lisp/obsolete/landmark.el @@ -163,51 +163,50 @@ (defcustom landmark-mode-hook nil "If non-nil, its value is called on entry to Landmark mode." - :type 'hook - :group 'landmark) + :type 'hook) (defvar landmark-mode-map (let ((map (make-sparse-keymap))) ;; Key bindings for cursor motion. - (define-key map "y" 'landmark-move-nw) ; y - (define-key map "u" 'landmark-move-ne) ; u - (define-key map "b" 'landmark-move-sw) ; b - (define-key map "n" 'landmark-move-se) ; n - (define-key map "h" 'backward-char) ; h - (define-key map "l" 'forward-char) ; l - (define-key map "j" 'landmark-move-down) ; j - (define-key map "k" 'landmark-move-up) ; k - - (define-key map [kp-7] 'landmark-move-nw) - (define-key map [kp-9] 'landmark-move-ne) - (define-key map [kp-1] 'landmark-move-sw) - (define-key map [kp-3] 'landmark-move-se) - (define-key map [kp-4] 'backward-char) - (define-key map [kp-6] 'forward-char) - (define-key map [kp-2] 'landmark-move-down) - (define-key map [kp-8] 'landmark-move-up) - - (define-key map "\C-n" 'landmark-move-down) ; C-n - (define-key map "\C-p" 'landmark-move-up) ; C-p + (define-key map "y" #'landmark-move-nw) ; y + (define-key map "u" #'landmark-move-ne) ; u + (define-key map "b" #'landmark-move-sw) ; b + (define-key map "n" #'landmark-move-se) ; n + (define-key map "h" #'backward-char) ; h + (define-key map "l" #'forward-char) ; l + (define-key map "j" #'landmark-move-down) ; j + (define-key map "k" #'landmark-move-up) ; k + + (define-key map [kp-7] #'landmark-move-nw) + (define-key map [kp-9] #'landmark-move-ne) + (define-key map [kp-1] #'landmark-move-sw) + (define-key map [kp-3] #'landmark-move-se) + (define-key map [kp-4] #'backward-char) + (define-key map [kp-6] #'forward-char) + (define-key map [kp-2] #'landmark-move-down) + (define-key map [kp-8] #'landmark-move-up) + + (define-key map "\C-n" #'landmark-move-down) ; C-n + (define-key map "\C-p" #'landmark-move-up) ; C-p ;; Key bindings for entering Human moves. - (define-key map "X" 'landmark-human-plays) ; X - (define-key map "x" 'landmark-human-plays) ; x - - (define-key map " " 'landmark-start-robot) ; SPC - (define-key map [down-mouse-1] 'landmark-start-robot) - (define-key map [drag-mouse-1] 'landmark-click) - (define-key map [mouse-1] 'landmark-click) - (define-key map [down-mouse-2] 'landmark-click) - (define-key map [mouse-2] 'landmark-mouse-play) - (define-key map [drag-mouse-2] 'landmark-mouse-play) - - (define-key map [remap previous-line] 'landmark-move-up) - (define-key map [remap next-line] 'landmark-move-down) - (define-key map [remap beginning-of-line] 'landmark-beginning-of-line) - (define-key map [remap end-of-line] 'landmark-end-of-line) - (define-key map [remap undo] 'landmark-human-takes-back) - (define-key map [remap advertised-undo] 'landmark-human-takes-back) + (define-key map "X" #'landmark-human-plays) ; X + (define-key map "x" #'landmark-human-plays) ; x + + (define-key map " " #'landmark-start-robot) ; SPC + (define-key map [down-mouse-1] #'landmark-start-robot) + (define-key map [drag-mouse-1] #'landmark-click) + (define-key map [mouse-1] #'landmark-click) + (define-key map [down-mouse-2] #'landmark-click) + (define-key map [mouse-2] #'landmark-mouse-play) + (define-key map [drag-mouse-2] #'landmark-mouse-play) + + (define-key map [remap previous-line] #'landmark-move-up) + (define-key map [remap next-line] #'landmark-move-down) + (define-key map [remap beginning-of-line] #'landmark-beginning-of-line) + (define-key map [remap end-of-line] #'landmark-end-of-line) + (define-key map [remap undo] #'landmark-human-takes-back) + (define-key map [remap advertised-undo] #'landmark-human-takes-back) map) "Local keymap to use in Landmark mode.") @@ -219,14 +218,12 @@ (defface landmark-font-lock-face-O '((((class color)) :foreground "red") (t :weight bold)) "Face to use for Emacs's O." - :version "22.1" - :group 'landmark) + :version "22.1") (defface landmark-font-lock-face-X '((((class color)) :foreground "green") (t :weight bold)) "Face to use for your X." - :version "22.1" - :group 'landmark) + :version "22.1") (defvar landmark-font-lock-keywords '(("O" . 'landmark-font-lock-face-O) @@ -1132,12 +1129,10 @@ this program to add a random element to the way moves were made.") "If non-nil, print \"One moment please\" when a new board is generated. The drawback of this is you don't see how many moves the last run took because it is overwritten by \"One moment please\"." - :type 'boolean - :group 'landmark) + :type 'boolean) (defcustom landmark-output-moves t "If non-nil, output number of moves so far on a move-by-move basis." - :type 'boolean - :group 'landmark) + :type 'boolean) (defun landmark-weights-debug () @@ -1153,7 +1148,7 @@ because it is overwritten by \"One moment please\"." (defun landmark-print-distance () (insert (format "tree: %S \n" (landmark-calc-distance-of-robot-from 'landmark-tree))) - (mapc 'landmark-print-distance-int landmark-directions)) + (mapc #'landmark-print-distance-int landmark-directions)) ;;(setq direction 'landmark-n) @@ -1166,10 +1161,10 @@ because it is overwritten by \"One moment please\"." (defun landmark-nslify-wts () (interactive) - (let ((l (apply 'append (mapcar 'landmark-nslify-wts-int landmark-directions)))) + (let ((l (apply #'append (mapcar #'landmark-nslify-wts-int landmark-directions)))) (insert (format "set data_value WTS \n %s \n" l)) (insert (format "/* max: %S min: %S */" - (eval (cons 'max l)) (eval (cons 'min l)))))) + (apply #'max l) (apply #'min l))))) (defun landmark-print-wts-int (direction) (mapc (lambda (target-direction) @@ -1184,7 +1179,7 @@ because it is overwritten by \"One moment please\"." (interactive) (with-current-buffer "*landmark-wts*" (insert "==============================\n") - (mapc 'landmark-print-wts-int landmark-directions))) + (mapc #'landmark-print-wts-int landmark-directions))) (defun landmark-print-moves (moves) (interactive) @@ -1204,7 +1199,7 @@ because it is overwritten by \"One moment please\"." (interactive) (with-current-buffer "*landmark-y,s,noise*" (insert "==============================\n") - (mapc 'landmark-print-y-s-noise-int landmark-directions))) + (mapc #'landmark-print-y-s-noise-int landmark-directions))) (defun landmark-print-smell-int (direction) (insert (format "%S: smell: %S \n" @@ -1216,7 +1211,7 @@ because it is overwritten by \"One moment please\"." (with-current-buffer "*landmark-smell*" (insert "==============================\n") (insert (format "tree: %S \n" (get 'z 't))) - (mapc 'landmark-print-smell-int landmark-directions))) + (mapc #'landmark-print-smell-int landmark-directions))) (defun landmark-print-w0-int (direction) (insert (format "%S: w0: %S \n" @@ -1227,7 +1222,7 @@ because it is overwritten by \"One moment please\"." (interactive) (with-current-buffer "*landmark-w0*" (insert "==============================\n") - (mapc 'landmark-print-w0-int landmark-directions))) + (mapc #'landmark-print-w0-int landmark-directions))) (defun landmark-blackbox () (with-current-buffer "*landmark-blackbox*" @@ -1252,36 +1247,31 @@ because it is overwritten by \"One moment please\"." (defun landmark-print-wts-blackbox () (interactive) - (mapc 'landmark-print-wts-int landmark-directions)) + (mapc #'landmark-print-wts-int landmark-directions)) ;;;_ - learning parameters (defcustom landmark-bound 0.005 "The maximum that w0j may be." - :type 'number - :group 'landmark) + :type 'number) (defcustom landmark-c 1.0 "A factor applied to modulate the increase in wij. Used in the function landmark-update-normal-weights." - :type 'number - :group 'landmark) + :type 'number) (defcustom landmark-c-naught 0.5 "A factor applied to modulate the increase in w0j. Used in the function landmark-update-naught-weights." - :type 'number - :group 'landmark) + :type 'number) (defvar landmark-initial-w0 0.0) (defvar landmark-initial-wij 0.0) (defcustom landmark-no-payoff 0 "The amount of simulation cycles that have occurred with no movement. Used to move the robot when he is stuck in a rut for some reason." - :type 'integer - :group 'landmark) + :type 'integer) (defcustom landmark-max-stall-time 2 "The maximum number of cycles that the robot can remain stuck in a place. After this limit is reached, landmark-random-move is called to push him out of it." - :type 'integer - :group 'landmark) + :type 'integer) ;;;_ + Randomizing functions @@ -1346,7 +1336,8 @@ push him out of it." (put 'landmark-e 'y (/ landmark-board-height 2)) (put 'landmark-e 'sym 4) - (mapc 'landmark-plot-internal '(landmark-n landmark-s landmark-e landmark-w landmark-tree))) + (mapc #'landmark-plot-internal + '(landmark-n landmark-s landmark-e landmark-w landmark-tree))) @@ -1434,7 +1425,7 @@ push him out of it." ;;;_ + Functions to move robot (defun landmark-confidence-for (target-direction) - (apply '+ + (apply #'+ (get target-direction 'w0) (mapcar (lambda (direction) (* @@ -1494,13 +1485,13 @@ push him out of it." (landmark-random-move) (progn (landmark-calc-confidences) - (mapc 'landmark-y landmark-directions) + (mapc #'landmark-y landmark-directions) (landmark-move))) (landmark-calc-payoff) - (mapc 'landmark-update-normal-weights landmark-directions) - (mapc 'landmark-update-naught-weights landmark-directions) + (mapc #'landmark-update-normal-weights landmark-directions) + (mapc #'landmark-update-naught-weights landmark-directions) (if landmark-debug (landmark-weights-debug))) (landmark-terminate-game nil)) @@ -1536,8 +1527,8 @@ If the game is finished, this command requests for another game." (landmark-calc-payoff) - (mapc 'landmark-update-normal-weights landmark-directions) - (mapc 'landmark-update-naught-weights landmark-directions) + (mapc #'landmark-update-normal-weights landmark-directions) + (mapc #'landmark-update-naught-weights landmark-directions) (landmark-amble-robot) ))))))) @@ -1576,7 +1567,7 @@ If the game is finished, this command requests for another game." (if (not save-weights) (progn - (mapc 'landmark-fix-weights-for landmark-directions) + (mapc #'landmark-fix-weights-for landmark-directions) (dolist (direction landmark-directions) (put direction 'w0 landmark-initial-w0))) (message "Weights preserved for this run.")) @@ -1618,7 +1609,7 @@ If the game is finished, this command requests for another game." ;;;_ + landmark-test-run () ;;;###autoload -(defalias 'landmark-repeat 'landmark-test-run) +(defalias 'landmark-repeat #'landmark-test-run) ;;;###autoload (defun landmark-test-run () "Run 100 Landmark games, each time saving the weights from the previous game." @@ -1670,13 +1661,13 @@ Use \\[describe-mode] for more info." (if landmark-one-moment-please (message "One moment, please...")) (landmark-start-game landmark-n landmark-m) - (eval (cons 'landmark-init - (cond - ((= parg 1) '(t nil)) - ((= parg 2) '(t t)) - ((= parg 3) '(nil t)) - ((= parg 4) '(nil nil)) - (t '(nil t)))))))) + (apply #'landmark-init + (cond + ((= parg 1) '(t nil)) + ((= parg 2) '(t t)) + ((= parg 3) '(nil t)) + ((= parg 4) '(nil nil)) + (t '(nil t))))))) ;;;_ + Local variables diff --git a/lisp/obsolete/lazy-lock.el b/lisp/obsolete/lazy-lock.el index 452be30818..34bf85f864 100644 --- a/lisp/obsolete/lazy-lock.el +++ b/lisp/obsolete/lazy-lock.el @@ -554,30 +554,30 @@ verbosity is controlled via the variable `lazy-lock-stealth-verbose'." ;; Add hook if lazy-lock.el is fontifying on scrolling or is deferring. (when (or fontifying defer-change defer-scroll defer-context) (add-hook 'window-scroll-functions (if defer-scroll - 'lazy-lock-defer-after-scroll - 'lazy-lock-fontify-after-scroll) + #'lazy-lock-defer-after-scroll + #'lazy-lock-fontify-after-scroll) nil t)) ;; ;; Add hook if lazy-lock.el is fontifying and is not deferring changes. (when (and fontifying (not defer-change) (not defer-context)) - (add-hook 'before-change-functions 'lazy-lock-arrange-before-change nil t)) + (add-hook 'before-change-functions #'lazy-lock-arrange-before-change nil t)) ;; ;; Replace Font Lock mode hook. - (remove-hook 'after-change-functions 'font-lock-after-change-function t) + (remove-hook 'after-change-functions #'font-lock-after-change-function t) (add-hook 'after-change-functions (cond ((and defer-change defer-context) - 'lazy-lock-defer-rest-after-change) + #'lazy-lock-defer-rest-after-change) (defer-change - 'lazy-lock-defer-line-after-change) + #'lazy-lock-defer-line-after-change) (defer-context - 'lazy-lock-fontify-rest-after-change) + #'lazy-lock-fontify-rest-after-change) (t - 'lazy-lock-fontify-line-after-change)) + #'lazy-lock-fontify-line-after-change)) nil t) ;; ;; Add package-specific hook. - (add-hook 'outline-view-change-hook 'lazy-lock-fontify-after-visage nil t) - (add-hook 'hs-hide-hook 'lazy-lock-fontify-after-visage nil t)) + (add-hook 'outline-view-change-hook #'lazy-lock-fontify-after-visage nil t) + (add-hook 'hs-hide-hook #'lazy-lock-fontify-after-visage nil t)) (defun lazy-lock-install-timers (dtime stime) ;; Schedule or re-schedule the deferral and stealth timers. @@ -590,13 +590,13 @@ verbosity is controlled via the variable `lazy-lock-stealth-verbose'." (when (cdr defer) (cancel-timer (cdr defer))) (setcar lazy-lock-timers (cons dtime (and dtime - (run-with-idle-timer dtime t 'lazy-lock-fontify-after-defer)))))) + (run-with-idle-timer dtime t #'lazy-lock-fontify-after-defer)))))) (unless (eq stime (car (cdr lazy-lock-timers))) (let ((stealth (cdr lazy-lock-timers))) (when (cdr stealth) (cancel-timer (cdr stealth))) (setcdr lazy-lock-timers (cons stime (and stime - (run-with-idle-timer stime t 'lazy-lock-fontify-after-idle))))))) + (run-with-idle-timer stime t #'lazy-lock-fontify-after-idle))))))) (defun lazy-lock-unstall () ;; @@ -614,21 +614,21 @@ verbosity is controlled via the variable `lazy-lock-stealth-verbose'." (save-restriction (widen) (lazy-lock-fontify-region (point-min) (point-max)))))) - (add-hook 'after-change-functions 'font-lock-after-change-function nil t)) + (add-hook 'after-change-functions #'font-lock-after-change-function nil t)) ;; ;; Remove the text properties. (lazy-lock-after-unfontify-buffer) ;; ;; Remove the fontification hooks. - (remove-hook 'window-scroll-functions 'lazy-lock-fontify-after-scroll t) - (remove-hook 'window-scroll-functions 'lazy-lock-defer-after-scroll t) - (remove-hook 'before-change-functions 'lazy-lock-arrange-before-change t) - (remove-hook 'after-change-functions 'lazy-lock-fontify-line-after-change t) - (remove-hook 'after-change-functions 'lazy-lock-fontify-rest-after-change t) - (remove-hook 'after-change-functions 'lazy-lock-defer-line-after-change t) - (remove-hook 'after-change-functions 'lazy-lock-defer-rest-after-change t) - (remove-hook 'outline-view-change-hook 'lazy-lock-fontify-after-visage t) - (remove-hook 'hs-hide-hook 'lazy-lock-fontify-after-visage t)) + (remove-hook 'window-scroll-functions #'lazy-lock-fontify-after-scroll t) + (remove-hook 'window-scroll-functions #'lazy-lock-defer-after-scroll t) + (remove-hook 'before-change-functions #'lazy-lock-arrange-before-change t) + (remove-hook 'after-change-functions #'lazy-lock-fontify-line-after-change t) + (remove-hook 'after-change-functions #'lazy-lock-fontify-rest-after-change t) + (remove-hook 'after-change-functions #'lazy-lock-defer-line-after-change t) + (remove-hook 'after-change-functions #'lazy-lock-defer-rest-after-change t) + (remove-hook 'outline-view-change-hook #'lazy-lock-fontify-after-visage t) + (remove-hook 'hs-hide-hook #'lazy-lock-fontify-after-visage t)) ;; Hook functions. @@ -724,7 +724,7 @@ verbosity is controlled via the variable `lazy-lock-stealth-verbose'." (defalias 'lazy-lock-fontify-line-after-change ;; Called from `after-change-functions'. ;; Fontify the current change. - 'font-lock-after-change-function) + #'font-lock-after-change-function) (defun lazy-lock-fontify-rest-after-change (beg end old-len) ;; Called from `after-change-functions'. @@ -783,10 +783,10 @@ verbosity is controlled via the variable `lazy-lock-stealth-verbose'." (setq lazy-lock-buffers (cdr lazy-lock-buffers))))) ;; Add hook if fontification should now be defer-driven in this buffer. (when (and lazy-lock-mode lazy-lock-defer-on-scrolling - (memq 'lazy-lock-fontify-after-scroll window-scroll-functions) + (memq #'lazy-lock-fontify-after-scroll window-scroll-functions) (not (or (input-pending-p) (lazy-lock-unfontified-p)))) - (remove-hook 'window-scroll-functions 'lazy-lock-fontify-after-scroll t) - (add-hook 'window-scroll-functions 'lazy-lock-defer-after-scroll nil t))) + (remove-hook 'window-scroll-functions #'lazy-lock-fontify-after-scroll t) + (add-hook 'window-scroll-functions #'lazy-lock-defer-after-scroll nil t))) (defun lazy-lock-fontify-after-idle () ;; Called from `timer-idle-list'. diff --git a/lisp/obsolete/longlines.el b/lisp/obsolete/longlines.el index f274dfb926..9676d6b28e 100644 --- a/lisp/obsolete/longlines.el +++ b/lisp/obsolete/longlines.el @@ -1,4 +1,4 @@ -;;; longlines.el --- automatically wrap long lines -*- coding:utf-8 -*- +;;; longlines.el --- automatically wrap long lines -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2001, 2004-2021 Free Software Foundation, Inc. @@ -48,7 +48,6 @@ Otherwise, you can perform filling using `fill-paragraph' or `auto-fill-mode'. In any case, the soft newlines will be removed when the file is saved to disk." - :group 'longlines :type 'boolean) (defcustom longlines-wrap-follows-window-size nil @@ -60,7 +59,6 @@ with differing widths. If the value is an integer, that specifies the distance from the right edge of the window at which wrapping occurs. For any other non-nil value, wrapping occurs 2 characters from the right edge." - :group 'longlines :type 'boolean) (defcustom longlines-show-hard-newlines nil @@ -68,13 +66,11 @@ non-nil value, wrapping occurs 2 characters from the right edge." \(The variable `longlines-show-effect' controls what they look like.) You can also enable the display temporarily, using the command `longlines-show-hard-newlines'." - :group 'longlines :type 'boolean) (defcustom longlines-show-effect (propertize "¶\n" 'face 'escape-glyph) "A string to display when showing hard newlines. This is used when `longlines-show-hard-newlines' is on." - :group 'longlines :type 'string) ;;; Internal variables @@ -110,23 +106,23 @@ always call `fill-paragraph' to fill individual paragraphs. If the variable `longlines-show-hard-newlines' is non-nil, hard newlines are indicated with a symbol." - :group 'longlines :lighter " ll" + :lighter " ll" (if longlines-mode ;; Turn on longlines mode (progn (use-hard-newlines 1 'never) (set (make-local-variable 'require-final-newline) nil) (add-to-list 'buffer-file-format 'longlines) - (add-hook 'change-major-mode-hook 'longlines-mode-off nil t) - (add-hook 'before-revert-hook 'longlines-before-revert-hook nil t) + (add-hook 'change-major-mode-hook #'longlines-mode-off nil t) + (add-hook 'before-revert-hook #'longlines-before-revert-hook nil t) (make-local-variable 'buffer-substring-filters) (make-local-variable 'longlines-auto-wrap) (set (make-local-variable 'isearch-search-fun-function) - 'longlines-search-function) + #'longlines-search-function) (set (make-local-variable 'replace-search-function) - 'longlines-search-forward) + #'longlines-search-forward) (set (make-local-variable 'replace-re-search-function) - 'longlines-re-search-forward) + #'longlines-re-search-forward) (add-to-list 'buffer-substring-filters 'longlines-encode-string) (when longlines-wrap-follows-window-size (let ((dw (if (and (integerp longlines-wrap-follows-window-size) @@ -138,7 +134,7 @@ newlines are indicated with a symbol." (set (make-local-variable 'fill-column) (- (window-width) dw))) (add-hook 'window-configuration-change-hook - 'longlines-window-change-function nil t)) + #'longlines-window-change-function nil t)) (let ((buffer-undo-list t) (inhibit-read-only t) (inhibit-modification-hooks t) @@ -160,21 +156,22 @@ newlines are indicated with a symbol." ;; Hacks to make longlines play nice with various modes. (cond ((eq major-mode 'mail-mode) - (add-hook 'mail-setup-hook 'longlines-decode-buffer nil t) + (declare-function mail-indent-citation "sendmail" ()) + (add-hook 'mail-setup-hook #'longlines-decode-buffer nil t) (or mail-citation-hook - (add-hook 'mail-citation-hook 'mail-indent-citation nil t)) - (add-hook 'mail-citation-hook 'longlines-decode-region nil t)) + (add-hook 'mail-citation-hook #'mail-indent-citation nil t)) + (add-hook 'mail-citation-hook #'longlines-decode-region nil t)) ((eq major-mode 'message-mode) - (add-hook 'message-setup-hook 'longlines-decode-buffer nil t) + (add-hook 'message-setup-hook #'longlines-decode-buffer nil t) (make-local-variable 'message-indent-citation-function) (if (not (listp message-indent-citation-function)) (setq message-indent-citation-function (list message-indent-citation-function))) - (add-to-list 'message-indent-citation-function - 'longlines-decode-region t))) + (add-hook 'message-indent-citation-function + #'longlines-decode-region t t))) - (add-hook 'after-change-functions 'longlines-after-change-function nil t) - (add-hook 'post-command-hook 'longlines-post-command-function nil t) + (add-hook 'after-change-functions #'longlines-after-change-function nil t) + (add-hook 'post-command-hook #'longlines-post-command-function nil t) (when longlines-auto-wrap (auto-fill-mode 0))) ;; Turn off longlines mode @@ -190,12 +187,12 @@ newlines are indicated with a symbol." (widen) (longlines-encode-region (point-min) (point-max)) (setq longlines-decoded nil)))) - (remove-hook 'change-major-mode-hook 'longlines-mode-off t) - (remove-hook 'after-change-functions 'longlines-after-change-function t) - (remove-hook 'post-command-hook 'longlines-post-command-function t) - (remove-hook 'before-revert-hook 'longlines-before-revert-hook t) + (remove-hook 'change-major-mode-hook #'longlines-mode-off t) + (remove-hook 'after-change-functions #'longlines-after-change-function t) + (remove-hook 'post-command-hook #'longlines-post-command-function t) + (remove-hook 'before-revert-hook #'longlines-before-revert-hook t) (remove-hook 'window-configuration-change-hook - 'longlines-window-change-function t) + #'longlines-window-change-function t) (when longlines-wrap-follows-window-size (kill-local-variable 'fill-column)) (kill-local-variable 'isearch-search-fun-function) @@ -482,17 +479,17 @@ This is called by `window-configuration-change-hook'." ;;; Loading and saving (defun longlines-before-revert-hook () - (add-hook 'after-revert-hook 'longlines-after-revert-hook nil t) + (add-hook 'after-revert-hook #'longlines-after-revert-hook nil t) (longlines-mode 0)) (defun longlines-after-revert-hook () - (remove-hook 'after-revert-hook 'longlines-after-revert-hook t) + (remove-hook 'after-revert-hook #'longlines-after-revert-hook t) (longlines-mode 1)) (add-to-list 'format-alist (list 'longlines "Automatically wrap long lines." nil nil - 'longlines-encode-region t nil)) + #'longlines-encode-region t nil)) ;;; Unloading diff --git a/lisp/obsolete/mailpost.el b/lisp/obsolete/mailpost.el index 2f74faf1d6..5b3a76e2f7 100644 --- a/lisp/obsolete/mailpost.el +++ b/lisp/obsolete/mailpost.el @@ -1,4 +1,4 @@ -;;; mailpost.el --- RMAIL coupler to /usr/uci/post mailer +;;; mailpost.el --- RMAIL coupler to /usr/uci/post mailer -*- lexical-binding: t; -*- ;; This is in the public domain ;; since Delp distributed it in 1986 without a copyright notice. @@ -76,7 +76,7 @@ site-init." (with-current-buffer errbuf (erase-buffer)))) (with-file-modes 384 (setq temfile (make-temp-file ",rpost"))) - (apply 'call-process + (apply #'call-process (append (list (if (boundp 'post-mail-program) post-mail-program "/usr/uci/lib/mh/post") diff --git a/lisp/obsolete/mantemp.el b/lisp/obsolete/mantemp.el index 287a5a732c..97e70f2984 100644 --- a/lisp/obsolete/mantemp.el +++ b/lisp/obsolete/mantemp.el @@ -1,4 +1,4 @@ -;;; mantemp.el --- create manual template instantiations from g++ 2.7.2 output +;;; mantemp.el --- create manual template instantiations from g++ 2.7.2 output -*- lexical-binding: t; -*- ;; Copyright (C) 1996, 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/obsolete/meese.el b/lisp/obsolete/meese.el index 81739dfa6c..7443bacc8b 100644 --- a/lisp/obsolete/meese.el +++ b/lisp/obsolete/meese.el @@ -1,4 +1,4 @@ -;;; meese.el --- protect the impressionable young minds of America +;;; meese.el --- protect the impressionable young minds of America -*- lexical-binding: t; -*- ;; This is in the public domain on account of being distributed since ;; 1985 or 1986 without a copyright notice. diff --git a/lisp/obsolete/messcompat.el b/lisp/obsolete/messcompat.el index fa73dc7a0f..be252395e4 100644 --- a/lisp/obsolete/messcompat.el +++ b/lisp/obsolete/messcompat.el @@ -1,4 +1,4 @@ -;;; messcompat.el --- making message mode compatible with mail mode +;;; messcompat.el --- making message mode compatible with mail mode -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. diff --git a/lisp/obsolete/metamail.el b/lisp/obsolete/metamail.el index ef97e8aa55..72237239dd 100644 --- a/lisp/obsolete/metamail.el +++ b/lisp/obsolete/metamail.el @@ -1,4 +1,4 @@ -;;; metamail.el --- Metamail interface for GNU Emacs +;;; metamail.el --- Metamail interface for GNU Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 1993, 1996, 2001-2021 Free Software Foundation, Inc. @@ -44,13 +44,11 @@ (defcustom metamail-program-name "metamail" "Metamail program name." - :type 'string - :group 'metamail) + :type 'string) (defcustom metamail-mailer-name "emacs" "Mailer name set to MM_MAILER environment variable." - :type 'string - :group 'metamail) + :type 'string) (defvar metamail-environment '("KEYHEADS=*" "MM_QUIET=1") "Environment variables passed to `metamail'. @@ -65,8 +63,7 @@ It is not expected to be altered globally by `set' or `setq'. Instead, change its value temporary using `let' or `let*' form. `-m MAILER' argument is automatically generated from the `metamail-mailer-name' variable." - :type '(repeat (string :tag "Switch")) - :group 'metamail) + :type '(repeat (string :tag "Switch"))) ;;;###autoload (defun metamail-interpret-header () @@ -193,7 +190,7 @@ redisplayed as output is inserted." (list "-m" (or metamail-mailer-name "emacs")) (list metafile)))) ;; `metamail' may not delete the temporary file! - (condition-case error + (condition-case nil (delete-file metafile) (error nil)) ))) diff --git a/lisp/obsolete/mouse-sel.el b/lisp/obsolete/mouse-sel.el index 608596e882..36d9dc658c 100644 --- a/lisp/obsolete/mouse-sel.el +++ b/lisp/obsolete/mouse-sel.el @@ -1,4 +1,4 @@ -;;; mouse-sel.el --- multi-click selection support +;;; mouse-sel.el --- multi-click selection support -*- lexical-binding: t; -*- ;; Copyright (C) 1993-1995, 2001-2021 Free Software Foundation, Inc. @@ -146,20 +146,17 @@ If non-nil, \\[mouse-select] and \\[mouse-extend] will leave point at the end of the region nearest to where the mouse last was. If nil, point will always be placed at the beginning of the region." - :type 'boolean - :group 'mouse-sel) + :type 'boolean) (defcustom mouse-sel-cycle-clicks t "If non-nil, \\[mouse-select] cycles the click-counts after 4 clicks." - :type 'boolean - :group 'mouse-sel) + :type 'boolean) (defcustom mouse-sel-default-bindings t "Control mouse bindings." :type '(choice (const :tag "none" nil) (const :tag "cut and paste" interprogram-cut-paste) - (other :tag "default bindings" t)) - :group 'mouse-sel) + (other :tag "default bindings" t))) ;;=== Key bindings ======================================================== @@ -216,14 +213,13 @@ the mouse position (or point, if `mouse-yank-at-point' is non-nil). - mouse-2 while selecting or extending copies selection to the kill ring; mouse-1 or mouse-3 kills it." :global t - :group 'mouse-sel (if mouse-sel-mode (progn ;; If mouse-2 has never been done by the user, initialize the ;; `event-kind' property to ensure that `follow-link' clicks ;; are interpreted correctly. (put 'mouse-2 'event-kind 'mouse-click) - (add-hook 'x-lost-selection-functions 'mouse-sel-lost-selection-hook) + (add-hook 'x-lost-selection-functions #'mouse-sel-lost-selection-hook) (when mouse-sel-default-bindings ;; Save original bindings and replace them with new ones. (setq mouse-sel-original-bindings @@ -240,7 +236,7 @@ kill ring; mouse-1 or mouse-3 kills it." #'mouse-sel--ignore)))) ;; Restore original bindings - (remove-hook 'x-lost-selection-functions 'mouse-sel-lost-selection-hook) + (remove-hook 'x-lost-selection-functions #'mouse-sel-lost-selection-hook) (dolist (binding mouse-sel-original-bindings) (global-set-key (car binding) (cdr binding))) ;; Restore the old values of these variables, diff --git a/lisp/obsolete/nnir.el b/lisp/obsolete/nnir.el index 147efed005..337d83ccca 100644 --- a/lisp/obsolete/nnir.el +++ b/lisp/obsolete/nnir.el @@ -228,8 +228,7 @@ with three items unique to nnir summary buffers: If nil this will use `gnus-summary-line-format'." :version "24.1" - :type '(choice (const :tag "gnus-summary-line-format" nil) string) - :group 'nnir) + :type '(choice (const :tag "gnus-summary-line-format" nil) string)) (defcustom nnir-ignored-newsgroups "" @@ -237,8 +236,7 @@ If nil this will use `gnus-summary-line-format'." Any newsgroup in the active file matching this regexp will be skipped when searching." :version "24.1" - :type '(regexp) - :group 'nnir) + :type '(regexp)) (defcustom nnir-imap-default-search-key "whole message" "The default IMAP search key for an nnir search. @@ -246,19 +244,16 @@ Must be one of the keys in `nnir-imap-search-arguments'. To use raw imap queries by default set this to \"imap\"." :version "24.1" :type `(choice ,@(mapcar (lambda (elem) (list 'const (car elem))) - nnir-imap-search-arguments)) - :group 'nnir) + nnir-imap-search-arguments))) (defcustom nnir-swish++-configuration-file (expand-file-name "~/Mail/swish++.conf") "Configuration file for swish++." - :type '(file) - :group 'nnir) + :type '(file)) (defcustom nnir-swish++-program "search" "Name of swish++ search executable." - :type '(string) - :group 'nnir) + :type '(string)) (defcustom nnir-swish++-additional-switches '() "A list of strings, to be given as additional arguments to swish++. @@ -267,8 +262,7 @@ Note that this should be a list. I.e., do NOT use the following: (setq nnir-swish++-additional-switches \"-i -w\") ; wrong Instead, use this: (setq nnir-swish++-additional-switches \\='(\"-i\" \"-w\"))" - :type '(repeat (string)) - :group 'nnir) + :type '(repeat (string))) (defcustom nnir-swish++-remove-prefix (concat (getenv "HOME") "/Mail/") "The prefix to remove from swish++ file names to get group names. @@ -277,8 +271,7 @@ expression. This variable is very similar to `nnir-namazu-remove-prefix', except that it is for swish++, not Namazu." - :type '(regexp) - :group 'nnir) + :type '(regexp)) ;; Swish-E. ;; URL: http://swish-e.org/ @@ -293,21 +286,18 @@ that it is for swish++, not Namazu." This could be a server parameter. It is never consulted once `nnir-swish-e-index-files', which should be used instead, has been customized." - :type '(file) - :group 'nnir) + :type '(file)) (defcustom nnir-swish-e-index-files (list nnir-swish-e-index-file) "List of index files for swish-e. This could be a server parameter." - :type '(repeat (file)) - :group 'nnir) + :type '(repeat (file))) (defcustom nnir-swish-e-program "swish-e" "Name of swish-e search executable. This cannot be a server parameter." - :type '(string) - :group 'nnir) + :type '(string)) (defcustom nnir-swish-e-additional-switches '() "A list of strings, to be given as additional arguments to swish-e. @@ -318,8 +308,7 @@ Instead, use this: (setq nnir-swish-e-additional-switches \\='(\"-i\" \"-w\")) This could be a server parameter." - :type '(repeat (string)) - :group 'nnir) + :type '(repeat (string))) (defcustom nnir-swish-e-remove-prefix (concat (getenv "HOME") "/Mail/") "The prefix to remove from swish-e file names to get group names. @@ -330,15 +319,13 @@ This variable is very similar to `nnir-namazu-remove-prefix', except that it is for swish-e, not Namazu. This could be a server parameter." - :type '(regexp) - :group 'nnir) + :type '(regexp)) ;; HyREX engine, see (defcustom nnir-hyrex-program "nnir-search" "Name of the nnir-search executable." - :type '(string) - :group 'nnir) + :type '(string)) (defcustom nnir-hyrex-additional-switches '() "A list of strings, to be given as additional arguments for nnir-search. @@ -346,13 +333,11 @@ Note that this should be a list. I.e., do NOT use the following: (setq nnir-hyrex-additional-switches \"-ddl ddl.xml -c nnir\") ; wrong ! Instead, use this: (setq nnir-hyrex-additional-switches \\='(\"-ddl\" \"ddl.xml\" \"-c\" \"nnir\"))" - :type '(repeat (string)) - :group 'nnir) + :type '(repeat (string))) (defcustom nnir-hyrex-index-directory (getenv "HOME") "Index directory for HyREX." - :type '(directory) - :group 'nnir) + :type '(directory)) (defcustom nnir-hyrex-remove-prefix (concat (getenv "HOME") "/Mail/") "The prefix to remove from HyREX file names to get group names. @@ -364,20 +349,17 @@ setting: (setq nnir-hyrex-remove-prefix \"/home/john/Mail/\") Note the trailing slash. Removing this prefix gives \"mail/misc/42\". `nnir' knows to remove the \"/42\" and to replace \"/\" with \".\" to arrive at the correct group name, \"mail.misc\"." - :type '(directory) - :group 'nnir) + :type '(directory)) ;; Namazu engine, see (defcustom nnir-namazu-program "namazu" "Name of Namazu search executable." - :type '(string) - :group 'nnir) + :type '(string)) (defcustom nnir-namazu-index-directory (expand-file-name "~/Mail/namazu/") "Index directory for Namazu." - :type '(directory) - :group 'nnir) + :type '(directory)) (defcustom nnir-namazu-additional-switches '() "A list of strings, to be given as additional arguments to namazu. @@ -388,8 +370,7 @@ Note that this should be a list. I.e., do NOT use the following: (setq nnir-namazu-additional-switches \"-i -w\") ; wrong Instead, use this: (setq nnir-namazu-additional-switches \\='(\"-i\" \"-w\"))" - :type '(repeat (string)) - :group 'nnir) + :type '(repeat (string))) (defcustom nnir-namazu-remove-prefix (concat (getenv "HOME") "/Mail/") "The prefix to remove from Namazu file names to get group names. @@ -401,14 +382,12 @@ setting: (setq nnir-namazu-remove-prefix \"/home/john/Mail/\") Note the trailing slash. Removing this prefix gives \"mail/misc/42\". `nnir' knows to remove the \"/42\" and to replace \"/\" with \".\" to arrive at the correct group name, \"mail.misc\"." - :type '(directory) - :group 'nnir) + :type '(directory)) (defcustom nnir-notmuch-program "notmuch" "Name of notmuch search executable." :version "24.1" - :type '(string) - :group 'nnir) + :type '(string)) (defcustom nnir-notmuch-additional-switches '() "A list of strings, to be given as additional arguments to notmuch. @@ -418,8 +397,7 @@ Note that this should be a list. I.e., do NOT use the following: Instead, use this: (setq nnir-notmuch-additional-switches \\='(\"-i\" \"-w\"))" :version "24.1" - :type '(repeat (string)) - :group 'nnir) + :type '(repeat (string))) (defcustom nnir-notmuch-remove-prefix (regexp-quote (or (getenv "MAILDIR") (expand-file-name "~/Mail"))) @@ -430,8 +408,7 @@ expression. This variable is very similar to `nnir-namazu-remove-prefix', except that it is for notmuch, not Namazu." :version "27.1" - :type '(regexp) - :group 'nnir) + :type '(regexp)) (defcustom nnir-notmuch-filter-group-names-function nil "Whether and how to use Gnus group names as \"path:\" search terms. @@ -457,7 +434,7 @@ like so: `((imap nnir-run-imap ((criteria "Imap Search in" ; Prompt - ,(mapcar 'car nnir-imap-search-arguments) ; alist for completing + ,(mapcar #'car nnir-imap-search-arguments) ; alist for completing nil ; allow any user input nil ; initial value nnir-imap-search-argument-history ; the history to use @@ -495,7 +472,6 @@ Add an entry here when adding a new search engine.") (defcustom nnir-method-default-engines '((nnimap . imap)) "Alist of default search engines keyed by server method." :version "27.1" - :group 'nnir :type `(repeat (cons (choice (const nnimap) (const nntp) (const nnspool) (const nneething) (const nndir) (const nnmbox) (const nnml) (const nnmh) (const nndraft) @@ -573,7 +549,7 @@ extensions." (or groups (gnus-server-get-active srv nnir-ignored-newsgroups)))) (message "Opening server %s" server) (apply - 'vconcat + #'vconcat (catch 'found (mapcar #'(lambda (group) @@ -1214,7 +1190,7 @@ construct path: search terms (see the variable (error "No directory found in method specification of server %s" server)) (apply - 'vconcat + #'vconcat (mapcar (lambda (x) (let ((group x) artlist) @@ -1247,7 +1223,7 @@ construct path: search terms (see the variable (error "Cannot locate directory for group")) (save-excursion (apply - 'call-process "find" nil t + #'call-process "find" nil t "find" group "-maxdepth" "1" "-type" "f" "-name" "[0-9]*" "-exec" "grep" @@ -1260,7 +1236,8 @@ construct path: search terms (see the variable (let* ((path (split-string (buffer-substring (point) - (line-end-position)) "/" t)) + (line-end-position)) + "/" t)) (art (string-to-number (car (last path))))) (while (string= "." (car path)) (setq path (cdr path))) @@ -1359,7 +1336,7 @@ Query for the specs, or use SPECS." (query-spec (or (cdr (assq 'nnir-query-spec specs)) (apply - 'append + #'append (list (cons 'query (read-string "Query: " nil 'nnir-search-history))) (when nnir-extra-parms @@ -1370,7 +1347,7 @@ Query for the specs, or use SPECS." (list (cons 'nnir-query-spec query-spec) (cons 'nnir-group-spec group-spec)))) -(define-obsolete-function-alias 'nnir-get-active 'gnus-server-get-active "28.1") +(define-obsolete-function-alias 'nnir-get-active #'gnus-server-get-active "28.1") ;; The end. (provide 'nnir) diff --git a/lisp/obsolete/old-emacs-lock.el b/lisp/obsolete/old-emacs-lock.el index 07bccd9071..90ff93e03b 100644 --- a/lisp/obsolete/old-emacs-lock.el +++ b/lisp/obsolete/old-emacs-lock.el @@ -1,4 +1,4 @@ -;;; emacs-lock.el --- prevents you from exiting Emacs if a buffer is locked +;;; emacs-lock.el --- prevents you from exiting Emacs if a buffer is locked -*- lexical-binding: t; -*- ;; Copyright (C) 1994, 1997, 2001-2021 Free Software Foundation, Inc. @@ -90,12 +90,12 @@ If the buffer is locked, signal error and display its name." (setq emacs-lock-from-exiting t))) (unless noninteractive - (add-hook 'kill-emacs-hook 'check-emacs-lock)) -(add-hook 'kill-buffer-hook 'emacs-lock-check-buffer-lock) -(add-hook 'shell-mode-hook 'emacs-lock-was-buffer-locked) -(add-hook 'shell-mode-hook 'emacs-lock-shell-sentinel) -(add-hook 'telnet-mode-hook 'emacs-lock-was-buffer-locked) -(add-hook 'telnet-mode-hook 'emacs-lock-shell-sentinel) + (add-hook 'kill-emacs-hook #'check-emacs-lock)) +(add-hook 'kill-buffer-hook #'emacs-lock-check-buffer-lock) +(add-hook 'shell-mode-hook #'emacs-lock-was-buffer-locked) +(add-hook 'shell-mode-hook #'emacs-lock-shell-sentinel) +(add-hook 'telnet-mode-hook #'emacs-lock-was-buffer-locked) +(add-hook 'telnet-mode-hook #'emacs-lock-shell-sentinel) (provide 'emacs-lock) diff --git a/lisp/obsolete/otodo-mode.el b/lisp/obsolete/otodo-mode.el index 58c385adad..add17b265b 100644 --- a/lisp/obsolete/otodo-mode.el +++ b/lisp/obsolete/otodo-mode.el @@ -1,4 +1,4 @@ -;;; todo-mode.el --- major mode for editing TODO list files +;;; todo-mode.el --- major mode for editing TODO list files -*- lexical-binding: t; -*- ;; Copyright (C) 1997, 1999, 2001-2021 Free Software Foundation, Inc. @@ -280,26 +280,21 @@ every day and it may also be marked on every day of the calendar. Using \"&%%(equal (calendar-current-date) date)\" instead will only show and mark todo entries for today, but may slow down processing of the diary file somewhat." - :type 'string - :group 'todo) + :type 'string) (defcustom todo-file-do (locate-user-emacs-file "todo-do" ".todo-do") "TODO mode list file." :version "24.4" ; added locate-user-emacs-file - :type 'file - :group 'todo) + :type 'file) (defcustom todo-file-done (locate-user-emacs-file "todo-done" ".todo-done") "TODO mode archive file." :version "24.4" ; added locate-user-emacs-file - :type 'file - :group 'todo) + :type 'file) (defcustom todo-mode-hook nil "TODO mode hooks." - :type 'hook - :group 'todo) + :type 'hook) (defcustom todo-edit-mode-hook nil "TODO Edit mode hooks." - :type 'hook - :group 'todo) + :type 'hook) (defcustom todo-insert-threshold 0 "TODO mode insertion accuracy. @@ -314,8 +309,7 @@ your item just before that point. If you set the threshold to, e.g. 8, it will stop as soon as the window size drops below that amount and will insert the item in the approximate center of that window." - :type 'integer - :group 'todo) + :type 'integer) (defvar todo-edit-buffer " *TODO Edit*" "TODO Edit buffer name.") (defcustom todo-file-top (locate-user-emacs-file "todo-top" ".todo-top") @@ -324,32 +318,26 @@ window." Not in TODO format, but diary compatible. Automatically generated when `todo-save-top-priorities' is non-nil." :version "24.4" ; added locate-user-emacs-file - :type 'string - :group 'todo) + :type 'string) (defcustom todo-print-function 'ps-print-buffer-with-faces "Function to print the current buffer." - :type 'symbol - :group 'todo) + :type 'symbol) (defcustom todo-show-priorities 1 "Default number of priorities to show by \\[todo-top-priorities]. 0 means show all entries." - :type 'integer - :group 'todo) + :type 'integer) (defcustom todo-print-priorities 0 "Default number of priorities to print by \\[todo-print]. 0 means print all entries." - :type 'integer - :group 'todo) + :type 'integer) (defcustom todo-remove-separator t "Non-nil to remove category separators in\ \\[todo-top-priorities] and \\[todo-print]." - :type 'boolean - :group 'todo) + :type 'boolean) (defcustom todo-save-top-priorities-too t "Non-nil makes `todo-save' automatically save top-priorities in `todo-file-top'." - :type 'boolean - :group 'todo) + :type 'boolean) ;; Thanks for the ISO time stamp format go to Karl Eichwalder ;; My format string for the appt.el package is "%3b %2d, %y, %02I:%02M%p". @@ -358,17 +346,14 @@ Automatically generated when `todo-save-top-priorities' is non-nil." "%:y-%02m-%02d %02H:%02M" "TODO mode time string format for done entries. For details see the variable `time-stamp-format'." - :type 'string - :group 'todo) + :type 'string) (defcustom todo-entry-prefix-function 'todo-entry-timestamp-initials "Function producing text to insert at start of todo entry." - :type 'symbol - :group 'todo) + :type 'symbol) (defcustom todo-initials (or (getenv "INITIALS") (user-login-name)) "Initials of todo item author." - :type 'string - :group 'todo) + :type 'string) (defun todo-entry-timestamp-initials () "Prepend timestamp and your initials to the head of a TODO entry." @@ -395,25 +380,25 @@ Use `todo-categories' instead.") (defvar todo-mode-map (let ((map (make-keymap))) (suppress-keymap map t) - (define-key map "+" 'todo-forward-category) - (define-key map "-" 'todo-backward-category) - (define-key map "d" 'todo-file-item) ;done/delete - (define-key map "e" 'todo-edit-item) - (define-key map "E" 'todo-edit-multiline) - (define-key map "f" 'todo-file-item) - (define-key map "i" 'todo-insert-item) - (define-key map "I" 'todo-insert-item-here) - (define-key map "j" 'todo-jump-to-category) - (define-key map "k" 'todo-delete-item) - (define-key map "l" 'todo-lower-item) - (define-key map "n" 'todo-forward-item) - (define-key map "p" 'todo-backward-item) - (define-key map "P" 'todo-print) - (define-key map "q" 'todo-quit) - (define-key map "r" 'todo-raise-item) - (define-key map "s" 'todo-save) - (define-key map "S" 'todo-save-top-priorities) - (define-key map "t" 'todo-top-priorities) + (define-key map "+" #'todo-forward-category) + (define-key map "-" #'todo-backward-category) + (define-key map "d" #'todo-file-item) ;done/delete + (define-key map "e" #'todo-edit-item) + (define-key map "E" #'todo-edit-multiline) + (define-key map "f" #'todo-file-item) + (define-key map "i" #'todo-insert-item) + (define-key map "I" #'todo-insert-item-here) + (define-key map "j" #'todo-jump-to-category) + (define-key map "k" #'todo-delete-item) + (define-key map "l" #'todo-lower-item) + (define-key map "n" #'todo-forward-item) + (define-key map "p" #'todo-backward-item) + (define-key map "P" #'todo-print) + (define-key map "q" #'todo-quit) + (define-key map "r" #'todo-raise-item) + (define-key map "s" #'todo-save) + (define-key map "S" #'todo-save-top-priorities) + (define-key map "t" #'todo-top-priorities) map) "TODO mode keymap.") @@ -451,7 +436,7 @@ Use `todo-categories' instead.") (search-forward-regexp (concat "^" todo-category-end)) (narrow-to-region begin (line-beginning-position)) (goto-char (point-min))))) -(defalias 'todo-cat-slct 'todo-category-select) +(defalias 'todo-cat-slct #'todo-category-select) (defun todo-forward-category () "Go forward to TODO list of next category." @@ -459,7 +444,7 @@ Use `todo-categories' instead.") (setq todo-category-number (mod (1+ todo-category-number) (length todo-categories))) (todo-category-select)) -(defalias 'todo-cmd-forw 'todo-forward-category) +(defalias 'todo-cmd-forw #'todo-forward-category) (defun todo-backward-category () "Go back to TODO list of previous category." @@ -467,14 +452,14 @@ Use `todo-categories' instead.") (setq todo-category-number (mod (1- todo-category-number) (length todo-categories))) (todo-category-select)) -(defalias 'todo-cmd-back 'todo-backward-category) +(defalias 'todo-cmd-back #'todo-backward-category) (defun todo-backward-item () "Select previous entry of TODO list." (interactive) (search-backward-regexp (concat "^" (regexp-quote todo-prefix)) nil t) (message "")) -(defalias 'todo-cmd-prev 'todo-backward-item) +(defalias 'todo-cmd-prev #'todo-backward-item) (defun todo-forward-item (&optional count) "Select COUNT-th next entry of TODO list." @@ -485,7 +470,7 @@ Use `todo-categories' instead.") nil 'goto-end count) (beginning-of-line) (message "")) -(defalias 'todo-cmd-next 'todo-forward-item) +(defalias 'todo-cmd-next #'todo-forward-item) (defun todo-save () "Save the TODO list." @@ -494,7 +479,7 @@ Use `todo-categories' instead.") (save-restriction (save-buffer))) (if todo-save-top-priorities-too (todo-save-top-priorities))) -(defalias 'todo-cmd-save 'todo-save) +(defalias 'todo-cmd-save #'todo-save) (defun todo-quit () "Done with TODO list for now." @@ -503,7 +488,7 @@ Use `todo-categories' instead.") (todo-save) (message "") (bury-buffer)) -(defalias 'todo-cmd-done 'todo-quit) +(defalias 'todo-cmd-done #'todo-quit) (defun todo-edit-item () "Edit current TODO list entry." @@ -518,7 +503,7 @@ Use `todo-categories' instead.") (todo-backward-item) (message "")))) (error "No TODO list entry to edit"))) -(defalias 'todo-cmd-edit 'todo-edit-item) +(defalias 'todo-cmd-edit #'todo-edit-item) (defun todo-edit-multiline () "Set up a buffer for editing a multiline TODO list entry." @@ -622,7 +607,7 @@ category." (category (if arg (todo-completing-read) current-category))) (todo-add-item-non-interactively new-item category)))) -(defalias 'todo-cmd-inst 'todo-insert-item) +(defalias 'todo-cmd-inst #'todo-insert-item) (defun todo-insert-item-here () "Insert a new TODO list entry directly above the entry at point. @@ -650,7 +635,7 @@ If point is on an empty line, insert the entry there." (setq todo-previous-answer (y-or-n-p (format-message "More important than `%s'? " item))))) todo-previous-answer) -(defalias 'todo-ask-p 'todo-more-important-p) +(defalias 'todo-ask-p #'todo-more-important-p) (defun todo-delete-item () "Delete current TODO list entry." @@ -664,7 +649,7 @@ If point is on an empty line, insert the entry there." (todo-backward-item)) (message "")) (error "No TODO list entry to delete"))) -(defalias 'todo-cmd-kill 'todo-delete-item) +(defalias 'todo-cmd-kill #'todo-delete-item) (defun todo-raise-item () "Raise priority of current entry." @@ -677,7 +662,7 @@ If point is on an empty line, insert the entry there." (insert item "\n")) (message "")) (error "No TODO list entry to raise"))) -(defalias 'todo-cmd-rais 'todo-raise-item) +(defalias 'todo-cmd-rais #'todo-raise-item) (defun todo-lower-item () "Lower priority of current entry." @@ -691,7 +676,7 @@ If point is on an empty line, insert the entry there." (insert item "\n")) (message "")) (error "No TODO list entry to lower"))) -(defalias 'todo-cmd-lowr 'todo-lower-item) +(defalias 'todo-cmd-lowr #'todo-lower-item) (defun todo-file-item (&optional comment) "File the current TODO list entry away, annotated with an optional COMMENT." diff --git a/lisp/obsolete/patcomp.el b/lisp/obsolete/patcomp.el index 8545f0721f..2c35cb0700 100644 --- a/lisp/obsolete/patcomp.el +++ b/lisp/obsolete/patcomp.el @@ -1,4 +1,4 @@ -;;; patcomp.el --- used by patch files to update Emacs releases +;;; patcomp.el --- used by patch files to update Emacs releases -*- lexical-binding: t; -*- ;; This file is part of GNU Emacs. diff --git a/lisp/obsolete/pc-mode.el b/lisp/obsolete/pc-mode.el index d4c90c2b29..cf0bc28b11 100644 --- a/lisp/obsolete/pc-mode.el +++ b/lisp/obsolete/pc-mode.el @@ -1,4 +1,4 @@ -;;; pc-mode.el --- emulate certain key bindings used on PCs +;;; pc-mode.el --- emulate certain key bindings used on PCs -*- lexical-binding: t; -*- ;; Copyright (C) 1995, 2001-2021 Free Software Foundation, Inc. @@ -40,16 +40,16 @@ C-Escape does list-buffers." (define-key function-key-map [delete] "\C-d") (define-key function-key-map [M-delete] [?\M-d]) (define-key function-key-map [C-delete] [?\M-d]) - (global-set-key [C-M-delete] 'kill-sexp) - (global-set-key [C-backspace] 'backward-kill-word) - (global-set-key [M-backspace] 'undo) + (global-set-key [C-M-delete] #'kill-sexp) + (global-set-key [C-backspace] #'backward-kill-word) + (global-set-key [M-backspace] #'undo) - (global-set-key [C-escape] 'list-buffers) + (global-set-key [C-escape] #'list-buffers) - (global-set-key [home] 'beginning-of-line) - (global-set-key [end] 'end-of-line) - (global-set-key [C-home] 'beginning-of-buffer) - (global-set-key [C-end] 'end-of-buffer)) + (global-set-key [home] #'beginning-of-line) + (global-set-key [end] #'end-of-line) + (global-set-key [C-home] #'beginning-of-buffer) + (global-set-key [C-end] #'end-of-buffer)) (provide 'pc-mode) diff --git a/lisp/obsolete/pc-select.el b/lisp/obsolete/pc-select.el index 3f18488109..59828759e6 100644 --- a/lisp/obsolete/pc-select.el +++ b/lisp/obsolete/pc-select.el @@ -1,4 +1,4 @@ -;;; pc-select.el --- emulate mark, cut, copy and paste from Motif +;;; pc-select.el --- emulate mark, cut, copy and paste from Motif -*- lexical-binding: t; -*- ;;; (or MAC GUI or MS-windoze (bah)) look-and-feel ;;; including key bindings. @@ -94,25 +94,21 @@ The scroll commands normally generate an error if you try to scroll past the top or bottom of the buffer. This is annoying when selecting text with these commands. If you set this variable to non-nil, these errors are suppressed." - :type 'boolean - :group 'pc-select) + :type 'boolean) (defcustom pc-select-selection-keys-only nil "Non-nil means only bind the basic selection keys when started. Other keys that emulate pc-behavior will be untouched. This gives mostly Emacs-like behavior with only the selection keys enabled." - :type 'boolean - :group 'pc-select) + :type 'boolean) (defcustom pc-select-meta-moves-sexps nil "Non-nil means move sexp-wise with Meta key, otherwise move word-wise." - :type 'boolean - :group 'pc-select) + :type 'boolean) (defcustom pc-selection-mode-hook nil "The hook to run when PC Selection mode is toggled." - :type 'hook - :group 'pc-select) + :type 'hook) (defvar pc-select-saved-settings-alist nil "The values of the variables before PC Selection mode was toggled on. @@ -320,7 +316,6 @@ but before calling PC Selection mode): ;; FIXME: bring pc-bindings-mode here ? nil nil nil - :group 'pc-select :global t (if pc-selection-mode diff --git a/lisp/obsolete/pgg-def.el b/lisp/obsolete/pgg-def.el index 425093832f..4d30e32614 100644 --- a/lisp/obsolete/pgg-def.el +++ b/lisp/obsolete/pgg-def.el @@ -1,4 +1,4 @@ -;;; pgg-def.el --- functions/macros for defining PGG functions +;;; pgg-def.el --- functions/macros for defining PGG functions -*- lexical-binding: t; -*- ;; Copyright (C) 1999, 2002-2021 Free Software Foundation, Inc. @@ -32,47 +32,39 @@ (defcustom pgg-default-scheme 'gpg "Default PGP scheme." - :group 'pgg :type '(choice (const :tag "GnuPG" gpg) (const :tag "PGP 5" pgp5) (const :tag "PGP" pgp))) (defcustom pgg-default-user-id (user-login-name) "User ID of your default identity." - :group 'pgg :type 'string) (defcustom pgg-default-keyserver-address "subkeys.pgp.net" "Host name of keyserver." - :group 'pgg :type 'string) (defcustom pgg-query-keyserver nil "Whether PGG queries keyservers for missing keys when verifying messages." :version "22.1" - :group 'pgg :type 'boolean) (defcustom pgg-encrypt-for-me t "If t, encrypt all outgoing messages with user's public key." - :group 'pgg :type 'boolean) (defcustom pgg-cache-passphrase t "If t, cache passphrase." - :group 'pgg :type 'boolean) (defcustom pgg-passphrase-cache-expiry 16 "How many seconds the passphrase is cached. Whether the passphrase is cached at all is controlled by `pgg-cache-passphrase'." - :group 'pgg :type 'integer) (defcustom pgg-passphrase-coding-system nil "Coding system to encode passphrase." - :group 'pgg :type 'coding-system) (defvar pgg-messages-coding-system nil diff --git a/lisp/obsolete/pgg-gpg.el b/lisp/obsolete/pgg-gpg.el index 90255fe2f7..d06a485b97 100644 --- a/lisp/obsolete/pgg-gpg.el +++ b/lisp/obsolete/pgg-gpg.el @@ -1,4 +1,4 @@ -;;; pgg-gpg.el --- GnuPG support for PGG. +;;; pgg-gpg.el --- GnuPG support for PGG. -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2000, 2002-2021 Free Software Foundation, Inc. @@ -37,23 +37,19 @@ (defcustom pgg-gpg-program "gpg" "The GnuPG executable." - :group 'pgg-gpg :type 'string) (defcustom pgg-gpg-extra-args nil "Extra arguments for every GnuPG invocation." - :group 'pgg-gpg :type '(repeat (string :tag "Argument"))) (defcustom pgg-gpg-recipient-argument "--recipient" "GnuPG option to specify recipient." - :group 'pgg-gpg :type '(choice (const :tag "New `--recipient' option" "--recipient") (const :tag "Old `--remote-user' option" "--remote-user"))) (defcustom pgg-gpg-use-agent t "Whether to use gnupg agent for key caching." - :group 'pgg-gpg :type 'boolean) (defvar pgg-gpg-user-id nil @@ -97,7 +93,7 @@ passphrase-with-newline (coding-system-change-eol-conversion pgg-passphrase-coding-system 'unix))) - (pgg-clear-string passphrase-with-newline)) + (clear-string passphrase-with-newline)) (setq encoded-passphrase-with-new-line passphrase-with-newline passphrase-with-newline nil)) (process-send-string process encoded-passphrase-with-new-line)) @@ -125,9 +121,9 @@ (if (= 127 exit-status) (error "%s could not be found" program)))) (if passphrase-with-newline - (pgg-clear-string passphrase-with-newline)) + (clear-string passphrase-with-newline)) (if encoded-passphrase-with-new-line - (pgg-clear-string encoded-passphrase-with-new-line)) + (clear-string encoded-passphrase-with-new-line)) (if (and process (eq 'run (process-status process))) (interrupt-process process)) (if (file-exists-p output-file-name) diff --git a/lisp/obsolete/pgg-parse.el b/lisp/obsolete/pgg-parse.el index edb5d4f677..2c76365a41 100644 --- a/lisp/obsolete/pgg-parse.el +++ b/lisp/obsolete/pgg-parse.el @@ -1,4 +1,4 @@ -;;; pgg-parse.el --- OpenPGP packet parsing +;;; pgg-parse.el --- OpenPGP packet parsing -*- lexical-binding: t; -*- ;; Copyright (C) 1999, 2002-2021 Free Software Foundation, Inc. @@ -44,14 +44,12 @@ (defcustom pgg-parse-public-key-algorithm-alist '((1 . RSA) (2 . RSA-E) (3 . RSA-S) (16 . ELG-E) (17 . DSA) (20 . ELG)) "Alist of the assigned number to the public key algorithm." - :group 'pgg-parse :type '(repeat (cons (sexp :tag "Number") (sexp :tag "Type")))) (defcustom pgg-parse-symmetric-key-algorithm-alist '((1 . IDEA) (2 . 3DES) (4 . CAST5) (5 . SAFER-SK128)) "Alist of the assigned number to the symmetric key algorithm." - :group 'pgg-parse :type '(repeat (cons (sexp :tag "Number") (sexp :tag "Type")))) @@ -59,7 +57,6 @@ '((1 . MD5) (2 . SHA1) (3 . RIPEMD160) (5 . MD2) (8 . SHA256) (9 . SHA384) (10 . SHA512)) "Alist of the assigned number to the cryptographic hash algorithm." - :group 'pgg-parse :type '(repeat (cons (sexp :tag "Number") (sexp :tag "Type")))) @@ -68,7 +65,6 @@ (1 . ZIP) (2 . ZLIB)) "Alist of the assigned number to the compression algorithm." - :group 'pgg-parse :type '(repeat (cons (sexp :tag "Number") (sexp :tag "Type")))) @@ -87,13 +83,11 @@ (48 . "Certification revocation signature") (64 . "Timestamp signature.")) "Alist of the assigned number to the signature type." - :group 'pgg-parse :type '(repeat (cons (sexp :tag "Number") (sexp :tag "Type")))) (defcustom pgg-ignore-packet-checksum t; XXX "If non-nil checksum of each ascii armored packet will be ignored." - :group 'pgg-parse :type 'boolean) (defvar pgg-armor-header-lines @@ -148,7 +142,7 @@ ;; `(string-to-number-list (pgg-read-body-string ,ptag)) ) -(defalias 'pgg-skip-bytes 'forward-char) +(defalias 'pgg-skip-bytes #'forward-char) (defmacro pgg-skip-header (ptag) `(pgg-skip-bytes (nth 2 ,ptag))) @@ -345,7 +339,7 @@ ;; 100 to 110 = internal or user-defined )) -(defun pgg-parse-signature-packet (ptag) +(defun pgg-parse-signature-packet (_ptag) (let* ((signature-version (pgg-byte-after)) (result (list (cons 'version signature-version))) hashed-material field n) @@ -411,7 +405,7 @@ pgg-parse-hash-algorithm-alist))) result)) -(defun pgg-parse-public-key-encrypted-session-key-packet (ptag) +(defun pgg-parse-public-key-encrypted-session-key-packet (_ptag) (let (result) (pgg-set-alist result 'version (pgg-read-byte)) @@ -425,7 +419,7 @@ pgg-parse-public-key-algorithm-alist))) result)) -(defun pgg-parse-symmetric-key-encrypted-session-key-packet (ptag) +(defun pgg-parse-symmetric-key-encrypted-session-key-packet (_ptag) (let (result) (pgg-set-alist result 'version @@ -436,7 +430,7 @@ pgg-parse-symmetric-key-algorithm-alist))) result)) -(defun pgg-parse-public-key-packet (ptag) +(defun pgg-parse-public-key-packet (_ptag) (let* ((key-version (pgg-read-byte)) (result (list (cons 'version key-version))) field) diff --git a/lisp/obsolete/pgg-pgp.el b/lisp/obsolete/pgg-pgp.el index e02032a6a5..665be0b2e2 100644 --- a/lisp/obsolete/pgg-pgp.el +++ b/lisp/obsolete/pgg-pgp.el @@ -1,4 +1,4 @@ -;;; pgg-pgp.el --- PGP 2.* and 6.* support for PGG. +;;; pgg-pgp.el --- PGP 2.* and 6.* support for PGG. -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2000, 2002-2021 Free Software Foundation, Inc. @@ -35,23 +35,19 @@ (defcustom pgg-pgp-program "pgp" "PGP 2.* and 6.* executable." - :group 'pgg-pgp :type 'string) (defcustom pgg-pgp-shell-file-name "/bin/sh" "File name to load inferior shells from. Bourne shell or its equivalent \(not tcsh) is needed for \"2>\"." - :group 'pgg-pgp :type 'string) (defcustom pgg-pgp-shell-command-switch "-c" "Switch used to have the shell execute its command line argument." - :group 'pgg-pgp :type 'string) (defcustom pgg-pgp-extra-args nil "Extra arguments for every PGP invocation." - :group 'pgg-pgp :type '(choice (const :tag "None" nil) (string :tag "Arguments"))) @@ -112,7 +108,7 @@ Bourne shell or its equivalent \(not tcsh) is needed for \"2>\"." (delete-file errors-file-name) (file-error nil))))) -(defun pgg-pgp-lookup-key (string &optional type) +(defun pgg-pgp-lookup-key (string &optional _type) "Search keys associated with STRING." (let ((args (list "+batchmode" "+language=en" "-kv" string))) (with-current-buffer (get-buffer-create pgg-output-buffer) @@ -133,7 +129,7 @@ Bourne shell or its equivalent \(not tcsh) is needed for \"2>\"." (defun pgg-pgp-encrypt-region (start end recipients &optional sign passphrase) "Encrypt the current region between START and END." (let* ((pgg-pgp-user-id (or pgg-pgp-user-id pgg-default-user-id)) - (passphrase (or passphrase + (_passphrase (or passphrase (when sign (pgg-read-passphrase (format "PGP passphrase for %s: " @@ -143,10 +139,11 @@ Bourne shell or its equivalent \(not tcsh) is needed for \"2>\"." (concat "+encrypttoself=off +verbose=1 +batchmode +language=us -fate " (if (or recipients pgg-encrypt-for-me) - (mapconcat 'shell-quote-argument + (mapconcat #'shell-quote-argument (append recipients (if pgg-encrypt-for-me - (list pgg-pgp-user-id))) " ")) + (list pgg-pgp-user-id))) + " ")) (if sign (concat " -s -u " (shell-quote-argument pgg-pgp-user-id)))))) (pgg-pgp-process-region start end nil pgg-pgp-program args) (pgg-process-when-success nil))) @@ -203,6 +200,7 @@ passphrase cache or user." (let* ((orig-file (pgg-make-temp-file "pgg")) (args "+verbose=1 +batchmode +language=us")) (with-file-modes 448 + (defvar jam-zcat-filename-list) (let ((coding-system-for-write 'binary) jka-compr-compression-info-list jam-zcat-filename-list) (write-region start end orig-file))) diff --git a/lisp/obsolete/pgg-pgp5.el b/lisp/obsolete/pgg-pgp5.el index 42ff1ca2bd..d952317241 100644 --- a/lisp/obsolete/pgg-pgp5.el +++ b/lisp/obsolete/pgg-pgp5.el @@ -1,4 +1,4 @@ -;;; pgg-pgp5.el --- PGP 5.* support for PGG. +;;; pgg-pgp5.el --- PGP 5.* support for PGG. -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2000, 2002-2021 Free Software Foundation, Inc. @@ -35,38 +35,31 @@ (defcustom pgg-pgp5-pgpe-program "pgpe" "PGP 5.* `pgpe' executable." - :group 'pgg-pgp5 :type 'string) (defcustom pgg-pgp5-pgps-program "pgps" "PGP 5.* `pgps' executable." - :group 'pgg-pgp5 :type 'string) (defcustom pgg-pgp5-pgpk-program "pgpk" "PGP 5.* `pgpk' executable." - :group 'pgg-pgp5 :type 'string) (defcustom pgg-pgp5-pgpv-program "pgpv" "PGP 5.* `pgpv' executable." - :group 'pgg-pgp5 :type 'string) (defcustom pgg-pgp5-shell-file-name "/bin/sh" "File name to load inferior shells from. Bourne shell or its equivalent \(not tcsh) is needed for \"2>\"." - :group 'pgg-pgp5 :type 'string) (defcustom pgg-pgp5-shell-command-switch "-c" "Switch used to have the shell execute its command line argument." - :group 'pgg-pgp5 :type 'string) (defcustom pgg-pgp5-extra-args nil "Extra arguments for every PGP 5.* invocation." - :group 'pgg-pgp5 :type '(choice (const :tag "None" nil) (string :tag "Arguments"))) @@ -128,7 +121,7 @@ Bourne shell or its equivalent \(not tcsh) is needed for \"2>\"." (delete-file errors-file-name) (file-error nil))))) -(defun pgg-pgp5-lookup-key (string &optional type) +(defun pgg-pgp5-lookup-key (string &optional _type) "Search keys associated with STRING." (let ((args (list "+language=en" "-l" string))) (with-current-buffer (get-buffer-create pgg-output-buffer) @@ -145,7 +138,7 @@ Bourne shell or its equivalent \(not tcsh) is needed for \"2>\"." (defun pgg-pgp5-encrypt-region (start end recipients &optional sign passphrase) "Encrypt the current region between START and END." (let* ((pgg-pgp5-user-id (or pgg-pgp5-user-id pgg-default-user-id)) - (passphrase (or passphrase + (_passphrase (or passphrase (when sign (pgg-read-passphrase (format "PGP passphrase for %s: " @@ -209,6 +202,7 @@ Bourne shell or its equivalent \(not tcsh) is needed for \"2>\"." (let ((orig-file (pgg-make-temp-file "pgg")) (args '("+verbose=1" "+batchmode=1" "+language=us"))) (with-file-modes 448 + (defvar jam-zcat-filename-list) ;Not sure where this comes from. (let ((coding-system-for-write 'binary) jka-compr-compression-info-list jam-zcat-filename-list) (write-region start end orig-file))) diff --git a/lisp/obsolete/pgg.el b/lisp/obsolete/pgg.el index 03d4465d7b..5ed59933f2 100644 --- a/lisp/obsolete/pgg.el +++ b/lisp/obsolete/pgg.el @@ -27,33 +27,16 @@ (require 'pgg-def) (require 'pgg-parse) -(autoload 'run-at-time "timer") (eval-when-compile (require 'cl-lib)) ;;; @ utility functions ;;; -(eval-and-compile - (if (featurep 'xemacs) - (progn - (defun pgg-run-at-time (time repeat function &rest args) - "Emulating function run as `run-at-time'. -TIME should be nil meaning now, or a number of seconds from now. -Return an itimer object which can be used in either `delete-itimer' -or `cancel-timer'." - (pgg-run-at-time-1 time repeat function args)) - (defun pgg-cancel-timer (timer) - "Emulate cancel-timer for xemacs." - (let ((delete-itimer 'delete-itimer)) - (funcall delete-itimer timer)))) - (defalias 'pgg-run-at-time 'run-at-time) - (defalias 'pgg-cancel-timer 'cancel-timer))) - (defun pgg-invoke (func scheme &rest args) (progn (require (intern (format "pgg-%s" scheme))) - (apply 'funcall (intern (format "pgg-%s-%s" scheme func)) args))) + (apply #'funcall (intern (format "pgg-%s-%s" scheme func)) args))) (defmacro pgg-save-coding-system (start end &rest body) (declare (indent 2) (debug t)) @@ -153,16 +136,9 @@ regulate cache behavior." (set (intern key pgg-passphrase-cache) passphrase) (set (intern key pgg-pending-timers) - (pgg-run-at-time pgg-passphrase-cache-expiry nil - #'pgg-remove-passphrase-from-cache - key notruncate)))) - -(if (fboundp 'clear-string) - (defalias 'pgg-clear-string 'clear-string) - (defun pgg-clear-string (string) - (fillarray string ?_))) - -(declare-function pgg-clear-string "pgg" (string)) + (run-at-time pgg-passphrase-cache-expiry nil + #'pgg-remove-passphrase-from-cache + key notruncate)))) (defun pgg-remove-passphrase-from-cache (key &optional notruncate) "Omit passphrase associated with KEY in time-limited passphrase cache. @@ -182,10 +158,10 @@ regulate cache behavior." (interned-timer-key (intern-soft key pgg-pending-timers)) (old-timer (symbol-value interned-timer-key))) (when passphrase - (pgg-clear-string passphrase) + (clear-string passphrase) (unintern key pgg-passphrase-cache)) (when old-timer - (pgg-cancel-timer old-timer) + (cancel-timer old-timer) (unintern interned-timer-key pgg-pending-timers)))) (defmacro pgg-convert-lbt-region (start end lbt) diff --git a/lisp/obsolete/rcompile.el b/lisp/obsolete/rcompile.el index 29931d9bda..d7020f0d07 100644 --- a/lisp/obsolete/rcompile.el +++ b/lisp/obsolete/rcompile.el @@ -1,4 +1,4 @@ -;;; rcompile.el --- run a compilation on a remote machine +;;; rcompile.el --- run a compilation on a remote machine -*- lexical-binding: t; -*- ;; Copyright (C) 1993-1994, 2001-2021 Free Software Foundation, Inc. @@ -76,14 +76,12 @@ (defcustom remote-compile-host nil "Host for remote compilations." - :type '(choice string (const nil)) - :group 'remote-compile) + :type '(choice string (const nil))) (defcustom remote-compile-user nil "User for remote compilations. nil means use the value returned by \\[user-login-name]." - :type '(choice string (const nil)) - :group 'remote-compile) + :type '(choice string (const nil))) (defcustom remote-compile-run-before nil "Command to run before compilation. @@ -91,18 +89,15 @@ This can be used for setting up environment variables, since rsh does not invoke the shell as a login shell and files like .login \(tcsh) and .bash_profile \(bash) are not run. nil means run no commands." - :type '(choice string (const nil)) - :group 'remote-compile) + :type '(choice string (const nil))) (defcustom remote-compile-prompt-for-host nil "Non-nil means prompt for host if not available from filename." - :type 'boolean - :group 'remote-compile) + :type 'boolean) (defcustom remote-compile-prompt-for-user nil "Non-nil means prompt for user if not available from filename." - :type 'boolean - :group 'remote-compile) + :type 'boolean) ;;;; internal variables @@ -123,7 +118,7 @@ nil means run no commands." "Compile the current buffer's directory on HOST. Log in as USER. See \\[compile]." (interactive - (let (host user command prompt l l-host l-user) + (let (host user command prompt) ;; l l-host l-user (setq prompt (if (stringp remote-compile-host) (format "Compile on host (default %s): " remote-compile-host) @@ -153,7 +148,7 @@ See \\[compile]." (setq remote-compile-user user)) ((null remote-compile-user) (setq remote-compile-user (user-login-name)))) - (let* (localname ;; Pacify byte-compiler. + (let* (;; localname ;; Pacify byte-compiler. (compile-command (format "%s %s -l %s \"(%scd %s; %s)\"" remote-shell-program diff --git a/lisp/obsolete/s-region.el b/lisp/obsolete/s-region.el index bcb5279d11..4d4c39e9b1 100644 --- a/lisp/obsolete/s-region.el +++ b/lisp/obsolete/s-region.el @@ -1,4 +1,4 @@ -;;; s-region.el --- set region using shift key +;;; s-region.el --- set region using shift key -*- lexical-binding: t; -*- ;; Copyright (C) 1994-1995, 2001-2021 Free Software Foundation, Inc. @@ -112,11 +112,11 @@ to global keymap." [M-next] [M-previous] [M-home] [M-end])) (or (global-key-binding [C-insert]) - (global-set-key [C-insert] 'copy-region-as-kill)) + (global-set-key [C-insert] #'copy-region-as-kill)) (or (global-key-binding [S-delete]) - (global-set-key [S-delete] 'kill-region)) + (global-set-key [S-delete] #'kill-region)) (or (global-key-binding [S-insert]) - (global-set-key [S-insert] 'yank)) + (global-set-key [S-insert] #'yank)) (provide 's-region) diff --git a/lisp/obsolete/sb-image.el b/lisp/obsolete/sb-image.el index 53ecfb7f26..e9a507f008 100644 --- a/lisp/obsolete/sb-image.el +++ b/lisp/obsolete/sb-image.el @@ -1,4 +1,4 @@ -;;; sb-image --- Image management for speedbar +;;; sb-image --- Image management for speedbar -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2003, 2005-2019, 2021 Free Software Foundation, ;; Inc. diff --git a/lisp/obsolete/sregex.el b/lisp/obsolete/sregex.el index ac5f62dd67..96d6b7aebf 100644 --- a/lisp/obsolete/sregex.el +++ b/lisp/obsolete/sregex.el @@ -1,4 +1,4 @@ -;;; sregex.el --- symbolic regular expressions +;;; sregex.el --- symbolic regular expressions -*- lexical-binding: t; -*- ;; Copyright (C) 1997-1998, 2000-2021 Free Software Foundation, Inc. @@ -246,15 +246,15 @@ (defvar sregex--current-sregex nil) (defun sregex-info () nil) (defmacro sregex-save-match-data (&rest forms) (cons 'save-match-data forms)) -(defun sregex-replace-match (r &optional f l str subexp x) +(defun sregex-replace-match (r &optional f l str subexp _x) (replace-match r f l str subexp)) -(defun sregex-match-string (c &optional i x) (match-string c i)) -(defun sregex-match-string-no-properties (count &optional in-string sregex) +(defun sregex-match-string (c &optional i _x) (match-string c i)) +(defun sregex-match-string-no-properties (count &optional in-string _sregex) (match-string-no-properties count in-string)) -(defun sregex-match-beginning (count &optional sregex) (match-beginning count)) -(defun sregex-match-end (count &optional sregex) (match-end count)) -(defun sregex-match-data (&optional sregex) (match-data)) -(defun sregex-backref-num (n &optional sregex) n) +(defun sregex-match-beginning (count &optional _sregex) (match-beginning count)) +(defun sregex-match-end (count &optional _sregex) (match-end count)) +(defun sregex-match-data (&optional _sregex) (match-data)) +(defun sregex-backref-num (n &optional _sregex) n) (defun sregex (&rest exps) @@ -525,23 +525,23 @@ has one of the following forms: (concat "\\(?:" re "\\)") re)))) -(defun sregex--group (exps combine) (concat "\\(" (sregex--sequence exps nil) "\\)")) +(defun sregex--group (exps _combine) (concat "\\(" (sregex--sequence exps nil) "\\)")) -(defun sregex--backref (exps combine) (concat "\\" (int-to-string (car exps)))) -(defun sregex--opt (exps combine) (concat (sregex--sequence exps 'suffix) "?")) -(defun sregex--0+ (exps combine) (concat (sregex--sequence exps 'suffix) "*")) -(defun sregex--1+ (exps combine) (concat (sregex--sequence exps 'suffix) "+")) +(defun sregex--backref (exps _combine) (concat "\\" (int-to-string (car exps)))) +(defun sregex--opt (exps _combine) (concat (sregex--sequence exps 'suffix) "?")) +(defun sregex--0+ (exps _combine) (concat (sregex--sequence exps 'suffix) "*")) +(defun sregex--1+ (exps _combine) (concat (sregex--sequence exps 'suffix) "+")) -(defun sregex--char (exps combine) (sregex--char-aux nil exps)) -(defun sregex--not-char (exps combine) (sregex--char-aux t exps)) +(defun sregex--char (exps _combine) (sregex--char-aux nil exps)) +(defun sregex--not-char (exps _combine) (sregex--char-aux t exps)) -(defun sregex--syntax (exps combine) (format "\\s%c" (car exps))) -(defun sregex--not-syntax (exps combine) (format "\\S%c" (car exps))) +(defun sregex--syntax (exps _combine) (format "\\s%c" (car exps))) +(defun sregex--not-syntax (exps _combine) (format "\\S%c" (car exps))) (defun sregex--regex (exps combine) (if combine (concat "\\(?:" (car exps) "\\)") (car exps))) -(defun sregex--repeat (exps combine) +(defun sregex--repeat (exps _combine) (let* ((min (or (pop exps) 0)) (minstr (number-to-string min)) (max (pop exps))) diff --git a/lisp/obsolete/starttls.el b/lisp/obsolete/starttls.el index 451c7eb2ff..0ca486324f 100644 --- a/lisp/obsolete/starttls.el +++ b/lisp/obsolete/starttls.el @@ -1,4 +1,4 @@ -;;; starttls.el --- STARTTLS functions +;;; starttls.el --- STARTTLS functions -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. @@ -126,28 +126,24 @@ This program is used when GnuTLS is used, i.e. when `starttls-use-gnutls' is non-nil." :version "22.1" - :type 'string - :group 'starttls) + :type 'string) (defcustom starttls-program "starttls" "The program to run in a subprocess to open an TLSv1 connection. This program is used when the `starttls' command is used, i.e. when `starttls-use-gnutls' is nil." - :type 'string - :group 'starttls) + :type 'string) (defcustom starttls-use-gnutls (not (executable-find starttls-program)) "Whether to use GnuTLS instead of the `starttls' command." :version "22.1" - :type 'boolean - :group 'starttls) + :type 'boolean) (defcustom starttls-extra-args nil "Extra arguments to `starttls-program'. These apply when the `starttls' command is used, i.e. when `starttls-use-gnutls' is nil." - :type '(repeat string) - :group 'starttls) + :type '(repeat string)) (defcustom starttls-extra-arguments nil "Extra arguments to `starttls-gnutls-program'. @@ -157,14 +153,12 @@ For example, non-TLS compliant servers may require \(\"--protocols\" \"ssl3\"). Invoke \"gnutls-cli --help\" to find out which parameters are available." :version "22.1" - :type '(repeat string) - :group 'starttls) + :type '(repeat string)) (defcustom starttls-process-connection-type nil "Value for `process-connection-type' to use when starting STARTTLS process." :version "22.1" - :type 'boolean - :group 'starttls) + :type 'boolean) (defcustom starttls-connect "- Simple Client Mode:\n\n" "Regular expression indicating successful connection. @@ -173,8 +167,7 @@ The default is what GnuTLS's \"gnutls-cli\" outputs." ;; in the application read/write phase. If the logic, or the string ;; itself, is modified, this must be updated. :version "22.1" - :type 'regexp - :group 'starttls) + :type 'regexp) (defcustom starttls-failure "\\*\\*\\* Handshake has failed" "Regular expression indicating failed TLS handshake. @@ -182,8 +175,7 @@ The default is what GnuTLS's \"gnutls-cli\" outputs." ;; GnuTLS cli.c:do_handshake() prints this string on failure. If the ;; logic, or the string itself, is modified, this must be updated. :version "22.1" - :type 'regexp - :group 'starttls) + :type 'regexp) (defcustom starttls-success "- Compression: " "Regular expression indicating completed TLS handshakes. @@ -193,8 +185,7 @@ The default is what GnuTLS's \"gnutls-cli\" outputs." ;; last. If that logic, or the string itself, is modified, this ;; must be updated. :version "22.1" - :type 'regexp - :group 'starttls) + :type 'regexp) (defun starttls-negotiate-gnutls (process) "Negotiate TLS on PROCESS opened by `open-starttls-stream'. @@ -296,9 +287,8 @@ GnuTLS requires a port number." starttls-gnutls-program starttls-program)))) -(defalias 'starttls-any-program-available 'starttls-available-p) -(make-obsolete 'starttls-any-program-available 'starttls-available-p - "2011-08-02") +(define-obsolete-function-alias 'starttls-any-program-available + #'starttls-available-p "2011-08-02") (provide 'starttls) diff --git a/lisp/obsolete/sup-mouse.el b/lisp/obsolete/sup-mouse.el index f3db27f567..4e312e968b 100644 --- a/lisp/obsolete/sup-mouse.el +++ b/lisp/obsolete/sup-mouse.el @@ -1,4 +1,4 @@ -;;; sup-mouse.el --- supdup mouse support for lisp machines +;;; sup-mouse.el --- supdup mouse support for lisp machines -*- lexical-binding: t; -*- ;; Copyright (C) 1985-1986, 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/obsolete/terminal.el b/lisp/obsolete/terminal.el index bde656dfa6..d28c4a172f 100644 --- a/lisp/obsolete/terminal.el +++ b/lisp/obsolete/terminal.el @@ -1,4 +1,4 @@ -;;; terminal.el --- terminal emulator for GNU Emacs +;;; terminal.el --- terminal emulator for GNU Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 1986-1989, 1993-1994, 2001-2021 Free Software ;; Foundation, Inc. @@ -58,22 +58,19 @@ to the emulator program itself. Type this character twice to send it through the emulator. Type ? after typing it for a list of possible commands. This variable is local to each terminal-emulator buffer." - :type 'character - :group 'terminal) + :type 'character) (defcustom terminal-scrolling t ;;>> Setting this to t sort-of defeats my whole aim in writing this package... "If non-nil, the terminal-emulator will losingly `scroll' when output occurs past the bottom of the screen. If nil, output will win and `wrap' to the top of the screen. This variable is local to each terminal-emulator buffer." - :type 'boolean - :group 'terminal) + :type 'boolean) (defcustom terminal-more-processing t "If non-nil, do more-processing. This variable is local to each terminal-emulator buffer." - :type 'boolean - :group 'terminal) + :type 'boolean) ;; If you are the sort of loser who uses scrolling without more breaks ;; and expects to actually see anything, you should probably set this to @@ -84,8 +81,7 @@ terminal-emulator before a screen redisplay is forced. Set this to a large value for greater throughput, set it smaller for more frequent updates but overall slower performance." - :type 'integer - :group 'terminal) + :type 'integer) (defvar terminal-more-break-insertion "*** More break -- Press space to continue ***") @@ -94,7 +90,7 @@ performance." (if terminal-meta-map nil (let ((map (make-sparse-keymap))) - (define-key map [t] 'te-pass-through) + (define-key map [t] #'te-pass-through) (setq terminal-meta-map map))) (defvar terminal-map nil) @@ -104,8 +100,8 @@ performance." ;; Prevent defining [menu-bar] as te-pass-through ;; so we allow the global menu bar to be visible. (define-key map [menu-bar] (make-sparse-keymap)) - (define-key map [t] 'te-pass-through) - (define-key map [switch-frame] 'handle-switch-frame) + (define-key map [t] #'te-pass-through) + (define-key map [switch-frame] #'handle-switch-frame) (define-key map "\e" terminal-meta-map) ;;(define-key map "\C-l" ;; (lambda () (interactive) (te-pass-through) (redraw-display))) @@ -115,22 +111,22 @@ performance." (if terminal-escape-map nil (let ((map (make-sparse-keymap))) - (define-key map [t] 'undefined) + (define-key map [t] #'undefined) (let ((s "0")) (while (<= (aref s 0) ?9) - (define-key map s 'digit-argument) + (define-key map s #'digit-argument) (aset s 0 (1+ (aref s 0))))) - (define-key map "b" 'switch-to-buffer) - (define-key map "o" 'other-window) - (define-key map "e" 'te-set-escape-char) - (define-key map "\C-l" 'redraw-display) - (define-key map "\C-o" 'te-flush-pending-output) - (define-key map "m" 'te-toggle-more-processing) - (define-key map "x" 'te-escape-extended-command) + (define-key map "b" #'switch-to-buffer) + (define-key map "o" #'other-window) + (define-key map "e" #'te-set-escape-char) + (define-key map "\C-l" #'redraw-display) + (define-key map "\C-o" #'te-flush-pending-output) + (define-key map "m" #'te-toggle-more-processing) + (define-key map "x" #'te-escape-extended-command) ;;>> What use is this? Why is it in the default terminal-emulator map? - (define-key map "w" 'te-edit) - (define-key map "?" 'te-escape-help) - (define-key map (char-to-string help-char) 'te-escape-help) + (define-key map "w" #'te-edit) + (define-key map "?" #'te-escape-help) + (define-key map (char-to-string help-char) #'te-escape-help) (setq terminal-escape-map map))) (defvar te-escape-command-alist nil) @@ -161,14 +157,14 @@ performance." (if terminal-more-break-map nil (let ((map (make-sparse-keymap))) - (define-key map [t] 'te-more-break-unread) - (define-key map (char-to-string help-char) 'te-more-break-help) - (define-key map " " 'te-more-break-resume) - (define-key map "\C-l" 'redraw-display) - (define-key map "\C-o" 'te-more-break-flush-pending-output) + (define-key map [t] #'te-more-break-unread) + (define-key map (char-to-string help-char) #'te-more-break-help) + (define-key map " " #'te-more-break-resume) + (define-key map "\C-l" #'redraw-display) + (define-key map "\C-o" #'te-more-break-flush-pending-output) ;;>>> this isn't right - ;(define-key map "\^?" 'te-more-break-flush-pending-output) ;DEL - (define-key map "\r" 'te-more-break-advance-one-line) + ;(define-key map "\^?" #'te-more-break-flush-pending-output) ;DEL + (define-key map "\r" #'te-more-break-advance-one-line) (setq terminal-more-break-map map))) @@ -525,7 +521,7 @@ lets you type a terminal emulator command." (if terminal-edit-map nil (setq terminal-edit-map (make-sparse-keymap)) - (define-key terminal-edit-map "\C-c\C-c" 'terminal-cease-edit)) + (define-key terminal-edit-map "\C-c\C-c" #'terminal-cease-edit)) ;; Terminal Edit mode is suitable only for specially formatted data. (put 'terminal-edit-mode 'mode-class 'special) @@ -1140,10 +1136,10 @@ subprocess started." ;; Then finally start the program we wanted. (format "%s; exec %s" te-stty-string - (mapconcat 'te-quote-arg-for-sh + (mapconcat #'te-quote-arg-for-sh (cons program args) " ")))) - (set-process-filter te-process 'te-filter) - (set-process-sentinel te-process 'te-sentinel)) + (set-process-filter te-process #'te-filter) + (set-process-sentinel te-process #'te-sentinel)) (error (fundamental-mode) (signal (car err) (cdr err)))) (setq inhibit-quit t) ;sport death @@ -1151,8 +1147,8 @@ subprocess started." (run-hooks 'terminal-mode-hook) (message "Entering Emacs terminal-emulator... Type %s %s for help" (single-key-description terminal-escape-char) - (mapconcat 'single-key-description - (where-is-internal 'te-escape-help terminal-escape-map t) + (mapconcat #'single-key-description + (where-is-internal #'te-escape-help terminal-escape-map t) " "))) @@ -1292,7 +1288,7 @@ in the directory specified by `te-terminfo-directory'." (directory-file-name te-terminfo-directory)) process-environment))) (set-process-sentinel (start-process "tic" nil "tic" file-name) - 'te-tic-sentinel)))) + #'te-tic-sentinel)))) (directory-file-name te-terminfo-directory)) (defun te-create-termcap () diff --git a/lisp/obsolete/tls.el b/lisp/obsolete/tls.el index 67a497f941..5cba18d789 100644 --- a/lisp/obsolete/tls.el +++ b/lisp/obsolete/tls.el @@ -1,4 +1,4 @@ -;;; tls.el --- TLS/SSL support via wrapper around GnuTLS +;;; tls.el --- TLS/SSL support via wrapper around GnuTLS -*- lexical-binding: t; -*- ;; Copyright (C) 1996-1999, 2002-2021 Free Software Foundation, Inc. @@ -70,8 +70,7 @@ Client data stream begins after the last character this matches. The default matches the output of \"gnutls-cli\" (version 2.0.1)." :version "22.2" - :type 'regexp - :group 'tls) + :type 'regexp) (defcustom tls-program '("gnutls-cli --x509cafile %t -p %p %h" @@ -104,22 +103,19 @@ successful negotiation." (repeat :inline t :tag "Other" (string))) (list :tag "List of commands" (repeat :tag "Command" (string)))) - :version "26.1" ; remove s_client - :group 'tls) + :version "26.1") (defcustom tls-process-connection-type nil "Value for `process-connection-type' to use when starting TLS process." :version "22.1" - :type 'boolean - :group 'tls) + :type 'boolean) (defcustom tls-success "- Handshake was completed\\|SSL handshake has read " "Regular expression indicating completed TLS handshakes. The default is what GnuTLS's \"gnutls-cli\" outputs." ;; or OpenSSL's \"openssl s_client\" :version "22.1" - :type 'regexp - :group 'tls) + :type 'regexp) (defcustom tls-checktrust nil "Indicate if certificates should be checked against trusted root certs. @@ -137,8 +133,7 @@ consider trustworthy, e.g.: :type '(choice (const :tag "Always" t) (const :tag "Never" nil) (const :tag "Ask" ask)) - :version "23.1" ;; No Gnus - :group 'tls) + :version "23.1") (defcustom tls-untrusted "- Peer's certificate is NOT trusted\\|Verify return code: \\([^0] \\|.[^ ]\\)" @@ -147,8 +142,7 @@ The default is what GnuTLS's \"gnutls-cli\" returns in the event of unsuccessful verification." ;; or OpenSSL's \"openssl s_client\" :type 'regexp - :version "23.1" ;; No Gnus - :group 'tls) + :version "23.1") (defcustom tls-hostmismatch "# The hostname in the certificate does NOT match" @@ -158,20 +152,13 @@ name of the host you are connecting to, gnutls-cli issues a warning to this effect. There is no such feature in openssl. Set this to nil if you want to ignore host name mismatches." :type 'regexp - :version "23.1" ;; No Gnus - :group 'tls) + :version "23.1") (defcustom tls-certtool-program "certtool" "Name of GnuTLS certtool. Used by `tls-certificate-information'." :version "22.1" - :type 'string - :group 'tls) - -(defalias 'tls-format-message - (if (fboundp 'format-message) 'format-message - ;; for Emacs < 25, and XEmacs, don't worry about quote translation. - 'format)) + :type 'string) (defun tls-certificate-information (der) "Parse X.509 certificate in DER format into an assoc list." @@ -272,7 +259,7 @@ Fourth arg PORT is an integer specifying a port to connect to." (message "The certificate presented by `%s' is \ NOT trusted." host)) (not (yes-or-no-p - (tls-format-message "\ + (format-message "\ The certificate presented by `%s' is NOT trusted. Accept anyway? " host))))) (and tls-hostmismatch (save-excursion diff --git a/lisp/obsolete/tpu-edt.el b/lisp/obsolete/tpu-edt.el index 78d88cf377..1340618f05 100644 --- a/lisp/obsolete/tpu-edt.el +++ b/lisp/obsolete/tpu-edt.el @@ -1,4 +1,4 @@ -;;; tpu-edt.el --- Emacs emulating TPU emulating EDT +;;; tpu-edt.el --- Emacs emulating TPU emulating EDT -*- lexical-binding: t; -*- ;; Copyright (C) 1993-1995, 2000-2021 Free Software Foundation, Inc. @@ -289,18 +289,15 @@ ;;; (defcustom tpu-kill-buffers-silently nil "If non-nil, TPU-edt kills modified buffers without asking." - :type 'boolean - :group 'tpu) + :type 'boolean) (defcustom tpu-percent-scroll 75 "Percentage of the screen to scroll for next/previous screen commands." - :type 'integer - :group 'tpu) + :type 'integer) (defcustom tpu-pan-columns 16 "Number of columns the tpu-pan functions scroll left or right." - :type 'integer - :group 'tpu) + :type 'integer) ;;; @@ -313,17 +310,17 @@ ;; that term/*.el does its job to map the escape sequence to the right ;; key-symbol. - (define-key map [up] 'tpu-move-to-beginning) ; up-arrow - (define-key map [down] 'tpu-move-to-end) ; down-arrow - (define-key map [right] 'end-of-line) ; right-arrow - (define-key map [left] 'beginning-of-line) ; left-arrow + (define-key map [up] #'tpu-move-to-beginning) ; up-arrow + (define-key map [down] #'tpu-move-to-end) ; down-arrow + (define-key map [right] #'end-of-line) ; right-arrow + (define-key map [left] #'beginning-of-line) ; left-arrow ;; (define-key map [find] nil) ; Find ;; (define-key map [insert] nil) ; Insert Here - (define-key map [delete] 'tpu-store-text) ; Remove - (define-key map [select] 'tpu-unselect) ; Select - (define-key map [prior] 'tpu-previous-window) ; Prev Screen - (define-key map [next] 'tpu-next-window) ; Next Screen + (define-key map [delete] #'tpu-store-text) ; Remove + (define-key map [select] #'tpu-unselect) ; Select + (define-key map [prior] #'tpu-previous-window) ; Prev Screen + (define-key map [next] #'tpu-next-window) ; Next Screen ;; (define-key map [f1] nil) ; F1 ;; (define-key map [f2] nil) ; F2 @@ -339,45 +336,45 @@ ;; (define-key map [f12] nil) ; F12 ;; (define-key map [f13] nil) ; F13 ;; (define-key map [f14] nil) ; F14 - (define-key map [help] 'describe-bindings) ; HELP + (define-key map [help] #'describe-bindings) ; HELP ;; (define-key map [menu] nil) ; DO - (define-key map [f17] 'tpu-drop-breadcrumb) ; F17 + (define-key map [f17] #'tpu-drop-breadcrumb) ; F17 ;; (define-key map [f18] nil) ; F18 ;; (define-key map [f19] nil) ; F19 ;; (define-key map [f20] nil) ; F20 - (define-key map [kp-f1] 'keyboard-quit) ; PF1 - (define-key map [kp-f2] 'help-for-help) ; PF2 - (define-key map [kp-f3] 'tpu-search) ; PF3 - (define-key map [kp-f4] 'tpu-undelete-lines) ; PF4 - (define-key map [kp-0] 'open-line) ; KP0 - (define-key map [kp-1] 'tpu-change-case) ; KP1 - (define-key map [kp-2] 'tpu-delete-to-eol) ; KP2 - (define-key map [kp-3] 'tpu-special-insert) ; KP3 - (define-key map [kp-4] 'tpu-move-to-end) ; KP4 - (define-key map [kp-5] 'tpu-move-to-beginning) ; KP5 - (define-key map [kp-6] 'tpu-paste) ; KP6 - (define-key map [kp-7] 'execute-extended-command) ; KP7 - (define-key map [kp-8] 'tpu-fill) ; KP8 - (define-key map [kp-9] 'tpu-replace) ; KP9 - (define-key map [kp-subtract] 'tpu-undelete-words) ; KP- - (define-key map [kp-separator] 'tpu-undelete-char) ; KP, - (define-key map [kp-decimal] 'tpu-unselect) ; KP. - (define-key map [kp-enter] 'tpu-substitute) ; KPenter + (define-key map [kp-f1] #'keyboard-quit) ; PF1 + (define-key map [kp-f2] #'help-for-help) ; PF2 + (define-key map [kp-f3] #'tpu-search) ; PF3 + (define-key map [kp-f4] #'tpu-undelete-lines) ; PF4 + (define-key map [kp-0] #'open-line) ; KP0 + (define-key map [kp-1] #'tpu-change-case) ; KP1 + (define-key map [kp-2] #'tpu-delete-to-eol) ; KP2 + (define-key map [kp-3] #'tpu-special-insert) ; KP3 + (define-key map [kp-4] #'tpu-move-to-end) ; KP4 + (define-key map [kp-5] #'tpu-move-to-beginning) ; KP5 + (define-key map [kp-6] #'tpu-paste) ; KP6 + (define-key map [kp-7] #'execute-extended-command) ; KP7 + (define-key map [kp-8] #'tpu-fill) ; KP8 + (define-key map [kp-9] #'tpu-replace) ; KP9 + (define-key map [kp-subtract] #'tpu-undelete-words) ; KP- + (define-key map [kp-separator] #'tpu-undelete-char) ; KP, + (define-key map [kp-decimal] #'tpu-unselect) ; KP. + (define-key map [kp-enter] #'tpu-substitute) ; KPenter ;; - (define-key map "\C-A" 'tpu-toggle-overwrite-mode) ; ^A + (define-key map "\C-A" #'tpu-toggle-overwrite-mode) ; ^A ;; (define-key map "\C-B" nil) ; ^B ;; (define-key map "\C-C" nil) ; ^C ;; (define-key map "\C-D" nil) ; ^D ;; (define-key map "\C-E" nil) ; ^E - (define-key map "\C-F" 'set-visited-file-name) ; ^F - (define-key map "\C-g" 'keyboard-quit) ; safety first - (define-key map "\C-h" 'delete-other-windows) ; BS - (define-key map "\C-i" 'other-window) ; TAB + (define-key map "\C-F" #'set-visited-file-name) ; ^F + (define-key map "\C-g" #'keyboard-quit) ; safety first + (define-key map "\C-h" #'delete-other-windows) ; BS + (define-key map "\C-i" #'other-window) ; TAB ;; (define-key map "\C-J" nil) ; ^J - (define-key map "\C-K" 'tpu-define-macro-key) ; ^K - (define-key map "\C-l" 'downcase-region) ; ^L + (define-key map "\C-K" #'tpu-define-macro-key) ; ^K + (define-key map "\C-l" #'downcase-region) ; ^L ;; (define-key map "\C-M" nil) ; ^M ;; (define-key map "\C-N" nil) ; ^N ;; (define-key map "\C-O" nil) ; ^O @@ -385,104 +382,104 @@ ;; (define-key map "\C-Q" nil) ; ^Q ;; (define-key map "\C-R" nil) ; ^R ;; (define-key map "\C-S" nil) ; ^S - (define-key map "\C-T" 'tpu-toggle-control-keys) ; ^T - (define-key map "\C-u" 'upcase-region) ; ^U + (define-key map "\C-T" #'tpu-toggle-control-keys) ; ^T + (define-key map "\C-u" #'upcase-region) ; ^U ;; (define-key map "\C-V" nil) ; ^V - (define-key map "\C-w" 'tpu-write-current-buffers) ; ^W + (define-key map "\C-w" #'tpu-write-current-buffers) ; ^W ;; (define-key map "\C-X" nil) ; ^X ;; (define-key map "\C-Y" nil) ; ^Y ;; (define-key map "\C-Z" nil) ; ^Z - (define-key map " " 'undo) ; SPC + (define-key map " " #'undo) ; SPC ;; (define-key map "!" nil) ; ! ;; (define-key map "#" nil) ; # - (define-key map "$" 'tpu-add-at-eol) ; $ - (define-key map "%" 'tpu-goto-percent) ; % + (define-key map "$" #'tpu-add-at-eol) ; $ + (define-key map "%" #'tpu-goto-percent) ; % ;; (define-key map "&" nil) ; & ;; (define-key map "(" nil) ; ( ;; (define-key map ")" nil) ; ) - (define-key map "*" 'tpu-toggle-regexp) ; * + (define-key map "*" #'tpu-toggle-regexp) ; * ;; (define-key map "+" nil) ; + - (define-key map "," 'tpu-goto-breadcrumb) ; , - (define-key map "-" 'negative-argument) ; - - (define-key map "." 'tpu-drop-breadcrumb) ; . - (define-key map "/" 'tpu-emacs-replace) ; / - (define-key map "0" 'digit-argument) ; 0 - (define-key map "1" 'digit-argument) ; 1 - (define-key map "2" 'digit-argument) ; 2 - (define-key map "3" 'digit-argument) ; 3 - (define-key map "4" 'digit-argument) ; 4 - (define-key map "5" 'digit-argument) ; 5 - (define-key map "6" 'digit-argument) ; 6 - (define-key map "7" 'digit-argument) ; 7 - (define-key map "8" 'digit-argument) ; 8 - (define-key map "9" 'digit-argument) ; 9 + (define-key map "," #'tpu-goto-breadcrumb) ; , + (define-key map "-" #'negative-argument) ; - + (define-key map "." #'tpu-drop-breadcrumb) ; . + (define-key map "/" #'tpu-emacs-replace) ; / + (define-key map "0" #'digit-argument) ; 0 + (define-key map "1" #'digit-argument) ; 1 + (define-key map "2" #'digit-argument) ; 2 + (define-key map "3" #'digit-argument) ; 3 + (define-key map "4" #'digit-argument) ; 4 + (define-key map "5" #'digit-argument) ; 5 + (define-key map "6" #'digit-argument) ; 6 + (define-key map "7" #'digit-argument) ; 7 + (define-key map "8" #'digit-argument) ; 8 + (define-key map "9" #'digit-argument) ; 9 ;; (define-key map ":" nil) ; : - (define-key map ";" 'tpu-trim-line-ends) ; ; + (define-key map ";" #'tpu-trim-line-ends) ; ; ;; (define-key map "<" nil) ; < ;; (define-key map "=" nil) ; = ;; (define-key map ">" nil) ; > - (define-key map "?" 'tpu-spell-check) ; ? - ;; (define-key map "A" 'tpu-toggle-newline-and-indent) ; A - ;; (define-key map "B" 'tpu-next-buffer) ; B - ;; (define-key map "C" 'repeat-complex-command) ; C - ;; (define-key map "D" 'shell-command) ; D - ;; (define-key map "E" 'tpu-exit) ; E - ;; (define-key map "F" 'tpu-cursor-free-mode) ; F - ;; (define-key map "G" 'tpu-get) ; G + (define-key map "?" #'tpu-spell-check) ; ? + ;; (define-key map "A" #'tpu-toggle-newline-and-indent) ; A + ;; (define-key map "B" #'tpu-next-buffer) ; B + ;; (define-key map "C" #'repeat-complex-command) ; C + ;; (define-key map "D" #'shell-command) ; D + ;; (define-key map "E" #'tpu-exit) ; E + ;; (define-key map "F" #'tpu-cursor-free-mode) ; F + ;; (define-key map "G" #'tpu-get) ; G ;; (define-key map "H" nil) ; H - ;; (define-key map "I" 'tpu-include) ; I - ;; (define-key map "K" 'tpu-kill-buffer) ; K - (define-key map "L" 'tpu-what-line) ; L - ;; (define-key map "M" 'buffer-menu) ; M - ;; (define-key map "N" 'tpu-next-file-buffer) ; N - ;; (define-key map "O" 'occur) ; O - (define-key map "P" 'lpr-buffer) ; P - ;; (define-key map "Q" 'tpu-quit) ; Q - ;; (define-key map "R" 'tpu-toggle-rectangle) ; R - ;; (define-key map "S" 'replace) ; S - ;; (define-key map "T" 'tpu-line-to-top-of-window) ; T - ;; (define-key map "U" 'undo) ; U - ;; (define-key map "V" 'tpu-version) ; V - ;; (define-key map "W" 'save-buffer) ; W - ;; (define-key map "X" 'tpu-save-all-buffers-kill-emacs) ; X - ;; (define-key map "Y" 'copy-region-as-kill) ; Y - ;; (define-key map "Z" 'suspend-emacs) ; Z - (define-key map "[" 'blink-matching-open) ; [ + ;; (define-key map "I" #'tpu-include) ; I + ;; (define-key map "K" #'tpu-kill-buffer) ; K + (define-key map "L" #'tpu-what-line) ; L + ;; (define-key map "M" #'buffer-menu) ; M + ;; (define-key map "N" #'tpu-next-file-buffer) ; N + ;; (define-key map "O" #'occur) ; O + (define-key map "P" #'lpr-buffer) ; P + ;; (define-key map "Q" #'tpu-quit) ; Q + ;; (define-key map "R" #'tpu-toggle-rectangle) ; R + ;; (define-key map "S" #'replace) ; S + ;; (define-key map "T" #'tpu-line-to-top-of-window) ; T + ;; (define-key map "U" #'undo) ; U + ;; (define-key map "V" #'tpu-version) ; V + ;; (define-key map "W" #'save-buffer) ; W + ;; (define-key map "X" #'tpu-save-all-buffers-kill-emacs) ; X + ;; (define-key map "Y" #'copy-region-as-kill) ; Y + ;; (define-key map "Z" #'suspend-emacs) ; Z + (define-key map "[" #'blink-matching-open) ; [ ;; (define-key map "\\" nil) ; \ - (define-key map "]" 'blink-matching-open) ; ] - (define-key map "^" 'tpu-add-at-bol) ; ^ - (define-key map "_" 'split-window-below) ; - - (define-key map "`" 'what-line) ; ` - (define-key map "a" 'tpu-toggle-newline-and-indent) ; a - (define-key map "b" 'tpu-next-buffer) ; b - (define-key map "c" 'repeat-complex-command) ; c - (define-key map "d" 'shell-command) ; d - (define-key map "e" 'tpu-exit) ; e - (define-key map "f" 'tpu-cursor-free-mode) ; f - (define-key map "g" 'tpu-get) ; g + (define-key map "]" #'blink-matching-open) ; ] + (define-key map "^" #'tpu-add-at-bol) ; ^ + (define-key map "_" #'split-window-below) ; - + (define-key map "`" #'what-line) ; ` + (define-key map "a" #'tpu-toggle-newline-and-indent) ; a + (define-key map "b" #'tpu-next-buffer) ; b + (define-key map "c" #'repeat-complex-command) ; c + (define-key map "d" #'shell-command) ; d + (define-key map "e" #'tpu-exit) ; e + (define-key map "f" #'tpu-cursor-free-mode) ; f + (define-key map "g" #'tpu-get) ; g ;; (define-key map "h" nil) ; h - (define-key map "i" 'tpu-include) ; i - (define-key map "k" 'tpu-kill-buffer) ; k - (define-key map "l" 'goto-line) ; l - (define-key map "m" 'buffer-menu) ; m - (define-key map "n" 'tpu-next-file-buffer) ; n - (define-key map "o" 'occur) ; o - (define-key map "p" 'lpr-region) ; p - (define-key map "q" 'tpu-quit) ; q - (define-key map "r" 'tpu-toggle-rectangle) ; r - (define-key map "s" 'replace) ; s - (define-key map "t" 'tpu-line-to-top-of-window) ; t - (define-key map "u" 'undo) ; u - (define-key map "v" 'tpu-version) ; v - (define-key map "w" 'save-buffer) ; w - (define-key map "x" 'tpu-save-all-buffers-kill-emacs) ; x - (define-key map "y" 'copy-region-as-kill) ; y - (define-key map "z" 'suspend-emacs) ; z + (define-key map "i" #'tpu-include) ; i + (define-key map "k" #'tpu-kill-buffer) ; k + (define-key map "l" #'goto-line) ; l + (define-key map "m" #'buffer-menu) ; m + (define-key map "n" #'tpu-next-file-buffer) ; n + (define-key map "o" #'occur) ; o + (define-key map "p" #'lpr-region) ; p + (define-key map "q" #'tpu-quit) ; q + (define-key map "r" #'tpu-toggle-rectangle) ; r + (define-key map "s" #'replace) ; s + (define-key map "t" #'tpu-line-to-top-of-window) ; t + (define-key map "u" #'undo) ; u + (define-key map "v" #'tpu-version) ; v + (define-key map "w" #'save-buffer) ; w + (define-key map "x" #'tpu-save-all-buffers-kill-emacs) ; x + (define-key map "y" #'copy-region-as-kill) ; y + (define-key map "z" #'suspend-emacs) ; z ;; (define-key map "{" nil) ; { - (define-key map "|" 'split-window-right) ; | + (define-key map "|" #'split-window-right) ; | ;; (define-key map "}" nil) ; } - (define-key map "~" 'exchange-point-and-mark) ; ~ - (define-key map "\177" 'delete-window) ; OP.") @@ -492,12 +489,12 @@ GOLD is the ASCII 7-bit escape sequence OP.") ;; Previously defined in CSI-map. We now presume that term/*.el does ;; its job to map the escape sequence to the right key-symbol. - (define-key map [find] 'tpu-search) ; Find - (define-key map [insert] 'tpu-paste) ; Insert Here - (define-key map [delete] 'tpu-cut) ; Remove - (define-key map [select] 'tpu-select) ; Select - (define-key map [prior] 'tpu-scroll-window-down) ; Prev Screen - (define-key map [next] 'tpu-scroll-window-up) ; Next Screen + (define-key map [find] #'tpu-search) ; Find + (define-key map [insert] #'tpu-paste) ; Insert Here + (define-key map [delete] #'tpu-cut) ; Remove + (define-key map [select] #'tpu-select) ; Select + (define-key map [prior] #'tpu-scroll-window-down) ; Prev Screen + (define-key map [next] #'tpu-scroll-window-up) ; Next Screen ;; (define-key map [f1] nil) ; F1 ;; (define-key map [f2] nil) ; F2 @@ -508,14 +505,14 @@ GOLD is the ASCII 7-bit escape sequence OP.") ;; (define-key map [f7] nil) ; F7 ;; (define-key map [f8] nil) ; F8 ;; (define-key map [f9] nil) ; F9 - (define-key map [f10] 'tpu-exit) ; F10 - (define-key map [f11] 'tpu-insert-escape) ; F11 (ESC) - (define-key map [f12] 'tpu-next-beginning-of-line) ; F12 (BS) - (define-key map [f13] 'tpu-delete-previous-word) ; F13 (LF) - (define-key map [f14] 'tpu-toggle-overwrite-mode) ; F14 - (define-key map [help] 'tpu-help) ; HELP - (define-key map [menu] 'execute-extended-command) ; DO - (define-key map [f17] 'tpu-goto-breadcrumb) ; F17 + (define-key map [f10] #'tpu-exit) ; F10 + (define-key map [f11] #'tpu-insert-escape) ; F11 (ESC) + (define-key map [f12] #'tpu-next-beginning-of-line) ; F12 (BS) + (define-key map [f13] #'tpu-delete-previous-word) ; F13 (LF) + (define-key map [f14] #'tpu-toggle-overwrite-mode) ; F14 + (define-key map [help] #'tpu-help) ; HELP + (define-key map [menu] #'execute-extended-command) ; DO + (define-key map [f17] #'tpu-goto-breadcrumb) ; F17 ;; (define-key map [f18] nil) ; F18 ;; (define-key map [f19] nil) ; F19 ;; (define-key map [f20] nil) ; F20 @@ -525,28 +522,28 @@ GOLD is the ASCII 7-bit escape sequence OP.") ;; its job to map the escape sequence to the right key-symbol. (define-key map [kp-f1] tpu-gold-map) ; GOLD map ;; - (define-key map [up] 'tpu-previous-line) ; up - (define-key map [down] 'tpu-next-line) ; down - (define-key map [right] 'tpu-forward-char) ; right - (define-key map [left] 'tpu-backward-char) ; left - - (define-key map [kp-f2] 'tpu-help) ; PF2 - (define-key map [kp-f3] 'tpu-search-again) ; PF3 - (define-key map [kp-f4] 'tpu-delete-current-line) ; PF4 - (define-key map [kp-0] 'tpu-line) ; KP0 - (define-key map [kp-1] 'tpu-word) ; KP1 - (define-key map [kp-2] 'tpu-end-of-line) ; KP2 - (define-key map [kp-3] 'tpu-char) ; KP3 - (define-key map [kp-4] 'tpu-advance-direction) ; KP4 - (define-key map [kp-5] 'tpu-backup-direction) ; KP5 - (define-key map [kp-6] 'tpu-cut) ; KP6 - (define-key map [kp-7] 'tpu-page) ; KP7 - (define-key map [kp-8] 'tpu-scroll-window) ; KP8 - (define-key map [kp-9] 'tpu-append-region) ; KP9 - (define-key map [kp-subtract] 'tpu-delete-current-word) ; KP- - (define-key map [kp-separator] 'tpu-delete-current-char) ; KP, - (define-key map [kp-decimal] 'tpu-select) ; KP. - (define-key map [kp-enter] 'newline) ; KPenter + (define-key map [up] #'tpu-previous-line) ; up + (define-key map [down] #'tpu-next-line) ; down + (define-key map [right] #'tpu-forward-char) ; right + (define-key map [left] #'tpu-backward-char) ; left + + (define-key map [kp-f2] #'tpu-help) ; PF2 + (define-key map [kp-f3] #'tpu-search-again) ; PF3 + (define-key map [kp-f4] #'tpu-delete-current-line) ; PF4 + (define-key map [kp-0] #'tpu-line) ; KP0 + (define-key map [kp-1] #'tpu-word) ; KP1 + (define-key map [kp-2] #'tpu-end-of-line) ; KP2 + (define-key map [kp-3] #'tpu-char) ; KP3 + (define-key map [kp-4] #'tpu-advance-direction) ; KP4 + (define-key map [kp-5] #'tpu-backup-direction) ; KP5 + (define-key map [kp-6] #'tpu-cut) ; KP6 + (define-key map [kp-7] #'tpu-page) ; KP7 + (define-key map [kp-8] #'tpu-scroll-window) ; KP8 + (define-key map [kp-9] #'tpu-append-region) ; KP9 + (define-key map [kp-subtract] #'tpu-delete-current-word) ; KP- + (define-key map [kp-separator] #'tpu-delete-current-char) ; KP, + (define-key map [kp-decimal] #'tpu-select) ; KP. + (define-key map [kp-enter] #'newline) ; KPenter map) "TPU-edt global keymap.") @@ -883,7 +880,7 @@ With argument, fill and justify." if no region is selected." (interactive) (let ((m (tpu-mark))) - (apply 'ispell-region + (apply #'ispell-region (if m (if (> m (point)) (list (point) m) (list m (point))) @@ -970,14 +967,14 @@ and the total number of lines in the buffer." ;;;###autoload (define-minor-mode tpu-edt-mode "Toggle TPU/edt emulation on or off." - :global t :group 'tpu + :global t (if tpu-edt-mode (tpu-edt-on) (tpu-edt-off))) -(defalias 'TPU-EDT-MODE 'tpu-edt-mode) +(defalias 'TPU-EDT-MODE #'tpu-edt-mode) ;;;###autoload -(defalias 'tpu-edt 'tpu-edt-on) -(defalias 'TPU-EDT 'tpu-edt-on) +(defalias 'tpu-edt #'tpu-edt-on) +(defalias 'TPU-EDT #'tpu-edt-on) ;; Note: The following functions have no `tpu-' prefix. This is unavoidable. ;; The real TPU/edt editor has interactive commands with these names, @@ -985,42 +982,42 @@ and the total number of lines in the buffer." ;; to work. Therefore it really is necessary to define these functions, ;; even in cases where they redefine existing Emacs functions. -(defalias 'exit 'tpu-exit) -(defalias 'EXIT 'tpu-exit) +(defalias 'exit #'tpu-exit) +(defalias 'EXIT #'tpu-exit) -(defalias 'Get 'tpu-get) -(defalias 'GET 'tpu-get) +(defalias 'Get #'tpu-get) +(defalias 'GET #'tpu-get) -(defalias 'include 'tpu-include) -(defalias 'INCLUDE 'tpu-include) +(defalias 'include #'tpu-include) +(defalias 'INCLUDE #'tpu-include) -(defalias 'quit 'tpu-quit) -(defalias 'QUIT 'tpu-quit) +(defalias 'quit #'tpu-quit) +(defalias 'QUIT #'tpu-quit) -(defalias 'spell 'tpu-spell-check) -(defalias 'SPELL 'tpu-spell-check) +(defalias 'spell #'tpu-spell-check) +(defalias 'SPELL #'tpu-spell-check) -(defalias 'what\ line 'tpu-what-line) -(defalias 'WHAT\ LINE 'tpu-what-line) +(defalias 'what\ line #'tpu-what-line) +(defalias 'WHAT\ LINE #'tpu-what-line) -(defalias 'replace 'tpu-lm-replace) -(defalias 'REPLACE 'tpu-lm-replace) +(defalias 'replace #'tpu-lm-replace) +(defalias 'REPLACE #'tpu-lm-replace) -(defalias 'help 'tpu-help) -(defalias 'HELP 'tpu-help) +(defalias 'help #'tpu-help) +(defalias 'HELP #'tpu-help) -(defalias 'set\ cursor\ free 'tpu-set-cursor-free) -(defalias 'SET\ CURSOR\ FREE 'tpu-set-cursor-free) +(defalias 'set\ cursor\ free #'tpu-set-cursor-free) +(defalias 'SET\ CURSOR\ FREE #'tpu-set-cursor-free) -(defalias 'set\ cursor\ bound 'tpu-set-cursor-bound) -(defalias 'SET\ CURSOR\ BOUND 'tpu-set-cursor-bound) +(defalias 'set\ cursor\ bound #'tpu-set-cursor-bound) +(defalias 'SET\ CURSOR\ BOUND #'tpu-set-cursor-bound) -(defalias 'set\ scroll\ margins 'tpu-set-scroll-margins) -(defalias 'SET\ SCROLL\ MARGINS 'tpu-set-scroll-margins) +(defalias 'set\ scroll\ margins #'tpu-set-scroll-margins) +(defalias 'SET\ SCROLL\ MARGINS #'tpu-set-scroll-margins) ;; Real TPU error messages end in periods. ;; Define this to avoid openly flouting Emacs coding standards. -(defalias 'tpu-error 'error) +(defalias 'tpu-error #'error) ;;; @@ -1227,7 +1224,7 @@ and the total number of lines in the buffer." "Bind a set of keystrokes to a single key, or key combination." (interactive) (setq tpu-saved-control-r (global-key-binding "\C-r")) - (global-set-key "\C-r" 'tpu-end-define-macro-key) + (global-set-key "\C-r" #'tpu-end-define-macro-key) (start-kbd-macro nil)) @@ -1361,18 +1358,18 @@ If an argument is specified, don't set the search direction." (if (not arg) (setq tpu-searching-forward tpu-advance)) (cond (tpu-searching-forward (cond (tpu-regexp-p - (fset 'tpu-emacs-search 're-search-forward) - (fset 'tpu-emacs-rev-search 're-search-backward)) + (fset 'tpu-emacs-search #'re-search-forward) + (fset 'tpu-emacs-rev-search #'re-search-backward)) (t - (fset 'tpu-emacs-search 'search-forward) - (fset 'tpu-emacs-rev-search 'search-backward)))) + (fset 'tpu-emacs-search #'search-forward) + (fset 'tpu-emacs-rev-search #'search-backward)))) (t (cond (tpu-regexp-p - (fset 'tpu-emacs-search 're-search-backward) - (fset 'tpu-emacs-rev-search 're-search-forward)) + (fset 'tpu-emacs-search #'re-search-backward) + (fset 'tpu-emacs-rev-search #'re-search-forward)) (t - (fset 'tpu-emacs-search 'search-backward) - (fset 'tpu-emacs-rev-search 'search-forward)))))) + (fset 'tpu-emacs-search #'search-backward) + (fset 'tpu-emacs-rev-search #'search-forward)))))) (defun tpu-search-internal (pat &optional quiet) "Search for a string or regular expression." @@ -2203,18 +2200,18 @@ Accepts a prefix argument for the number of tpu-pan-columns to scroll." ;; Standard Emacs settings under xterm in function-key-map map ;; "\eOM" to [kp-enter] and [kp-enter] to RET, but since the output of the map ;; is not fed back into the map, the key stays as kp-enter :-(. -(define-key minibuffer-local-map [kp-enter] 'exit-minibuffer) +(define-key minibuffer-local-map [kp-enter] #'exit-minibuffer) ;; These are not necessary because they are inherited. ;; (define-key minibuffer-local-ns-map [kp-enter] 'exit-minibuffer) ;; (define-key minibuffer-local-completion-map [kp-enter] 'exit-minibuffer) -(define-key minibuffer-local-must-match-map [kp-enter] 'minibuffer-complete-and-exit) +(define-key minibuffer-local-must-match-map [kp-enter] #'minibuffer-complete-and-exit) ;;; ;;; Minibuffer map additions to set search direction ;;; -(define-key minibuffer-local-map [kp-4] 'tpu-search-forward-exit) ;KP4 -(define-key minibuffer-local-map [kp-5] 'tpu-search-backward-exit) ;KP5 +(define-key minibuffer-local-map [kp-4] #'tpu-search-forward-exit) ;KP4 +(define-key minibuffer-local-map [kp-5] #'tpu-search-backward-exit) ;KP5 ;;; @@ -2223,19 +2220,19 @@ Accepts a prefix argument for the number of tpu-pan-columns to scroll." (defvar tpu-control-keys-map (let ((map (make-sparse-keymap))) - (define-key map "\C-\\" 'quoted-insert) ; ^\ - (define-key map "\C-a" 'tpu-toggle-overwrite-mode) ; ^A - (define-key map "\C-b" 'repeat-complex-command) ; ^B - (define-key map "\C-e" 'tpu-current-end-of-line) ; ^E - (define-key map "\C-h" 'tpu-next-beginning-of-line) ; ^H (BS) - (define-key map "\C-j" 'tpu-delete-previous-word) ; ^J (LF) - (define-key map "\C-k" 'tpu-define-macro-key) ; ^K - (define-key map "\C-l" 'tpu-insert-formfeed) ; ^L (FF) - (define-key map "\C-r" 'recenter) ; ^R - (define-key map "\C-u" 'tpu-delete-to-bol) ; ^U - (define-key map "\C-v" 'tpu-quoted-insert) ; ^V - (define-key map "\C-w" 'redraw-display) ; ^W - (define-key map "\C-z" 'tpu-exit) ; ^Z + (define-key map "\C-\\" #'quoted-insert) ; ^\ + (define-key map "\C-a" #'tpu-toggle-overwrite-mode) ; ^A + (define-key map "\C-b" #'repeat-complex-command) ; ^B + (define-key map "\C-e" #'tpu-current-end-of-line) ; ^E + (define-key map "\C-h" #'tpu-next-beginning-of-line) ; ^H (BS) + (define-key map "\C-j" #'tpu-delete-previous-word) ; ^J (LF) + (define-key map "\C-k" #'tpu-define-macro-key) ; ^K + (define-key map "\C-l" #'tpu-insert-formfeed) ; ^L (FF) + (define-key map "\C-r" #'recenter) ; ^R + (define-key map "\C-u" #'tpu-delete-to-bol) ; ^U + (define-key map "\C-v" #'tpu-quoted-insert) ; ^V + (define-key map "\C-w" #'redraw-display) ; ^W + (define-key map "\C-z" #'tpu-exit) ; ^Z map)) (defun tpu-set-control-keys () @@ -2285,18 +2282,18 @@ Accepts a prefix argument for the number of tpu-pan-columns to scroll." (defun tpu-arrow-history nil "Modify minibuffer maps to use arrows for history recall." (interactive) - (dolist (cur (where-is-internal 'tpu-previous-line)) - (define-key read-expression-map cur 'tpu-previous-history-element) - (define-key minibuffer-local-map cur 'tpu-previous-history-element) + (dolist (cur (where-is-internal #'tpu-previous-line)) + (define-key read-expression-map cur #'tpu-previous-history-element) + (define-key minibuffer-local-map cur #'tpu-previous-history-element) ;; These are inherited anyway. --Stef ;; (define-key minibuffer-local-ns-map cur 'tpu-previous-history-element) ;; (define-key minibuffer-local-completion-map cur 'tpu-previous-history-element) ;; (define-key minibuffer-local-must-match-map cur 'tpu-previous-history-element) ) - (dolist (cur (where-is-internal 'tpu-next-line)) - (define-key read-expression-map cur 'tpu-next-history-element) - (define-key minibuffer-local-map cur 'tpu-next-history-element) + (dolist (cur (where-is-internal #'tpu-next-line)) + (define-key read-expression-map cur #'tpu-next-history-element) + (define-key minibuffer-local-map cur #'tpu-next-history-element) ;; These are inherited anyway. --Stef ;; (define-key minibuffer-local-ns-map cur 'tpu-next-history-element) ;; (define-key minibuffer-local-completion-map cur 'tpu-next-history-element) @@ -2382,7 +2379,7 @@ If FILE is nil, try to load a default file. The default file names are (use-global-map global-map) ;; Then do the normal TPU setup. (transient-mark-mode t) - (add-hook 'post-command-hook 'tpu-search-highlight) + (add-hook 'post-command-hook #'tpu-search-highlight) (tpu-set-mode-line t) (tpu-advance-direction) ;; set page delimiter, display line truncation, and scrolling like TPU @@ -2406,7 +2403,7 @@ If FILE is nil, try to load a default file. The default file names are "Turn off TPU/edt emulation. Note that the keypad is left on." (interactive) (tpu-reset-control-keys nil) - (remove-hook 'post-command-hook 'tpu-search-highlight) + (remove-hook 'post-command-hook #'tpu-search-highlight) (tpu-set-mode-line nil) (while tpu-edt-old-global-values (let ((varval (pop tpu-edt-old-global-values))) diff --git a/lisp/obsolete/tpu-extras.el b/lisp/obsolete/tpu-extras.el index 10b9c89372..5d59945c56 100644 --- a/lisp/obsolete/tpu-extras.el +++ b/lisp/obsolete/tpu-extras.el @@ -1,4 +1,4 @@ -;;; tpu-extras.el --- scroll margins and free cursor mode for TPU-edt +;;; tpu-extras.el --- scroll margins and free cursor mode for TPU-edt -*- lexical-binding: t; -*- ;; Copyright (C) 1993-1995, 2000-2021 Free Software Foundation, Inc. @@ -144,12 +144,12 @@ the previous line when starting from a line beginning." ;;; Hooks -- Set cursor free in picture mode. ;;; Clean up when writing a file from cursor free mode. -(add-hook 'picture-mode-hook 'tpu-set-cursor-free) +(add-hook 'picture-mode-hook #'tpu-set-cursor-free) (defun tpu-trim-line-ends-if-needed () "Eliminate whitespace at ends of lines, if the cursor is free." (if (and (buffer-modified-p) tpu-cursor-free-mode) (tpu-trim-line-ends))) -(add-hook 'before-save-hook 'tpu-trim-line-ends-if-needed) +(add-hook 'before-save-hook #'tpu-trim-line-ends-if-needed) ;;; Utility routines for implementing scroll margins diff --git a/lisp/obsolete/tpu-mapper.el b/lisp/obsolete/tpu-mapper.el index 2735820ae4..d23068ac46 100644 --- a/lisp/obsolete/tpu-mapper.el +++ b/lisp/obsolete/tpu-mapper.el @@ -1,4 +1,4 @@ -;;; tpu-mapper.el --- create a TPU-edt X-windows keymap file +;;; tpu-mapper.el --- create a TPU-edt X-windows keymap file -*- lexical-binding: t; -*- ;; Copyright (C) 1993-1995, 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/obsolete/url-ns.el b/lisp/obsolete/url-ns.el index fff3be9545..b62ad82999 100644 --- a/lisp/obsolete/url-ns.el +++ b/lisp/obsolete/url-ns.el @@ -1,4 +1,4 @@ -;;; url-ns.el --- Various netscape-ish functions for proxy definitions +;;; url-ns.el --- Various netscape-ish functions for proxy definitions -*- lexical-binding: t; -*- ;; Copyright (C) 1997-1999, 2004-2021 Free Software Foundation, Inc. @@ -55,9 +55,9 @@ (if (or (/= (length netc) (length ipc)) (/= (length ipc) (length maskc))) nil - (setq netc (mapcar 'string-to-number netc) - ipc (mapcar 'string-to-number ipc) - maskc (mapcar 'string-to-number maskc)) + (setq netc (mapcar #'string-to-number netc) + ipc (mapcar #'string-to-number ipc) + maskc (mapcar #'string-to-number maskc)) (and (= (logand (nth 0 netc) (nth 0 maskc)) (logand (nth 0 ipc) (nth 0 maskc))) @@ -79,24 +79,23 @@ (if (not (and (file-exists-p file) (file-readable-p file))) (message "Could not open %s for reading" file) - (save-excursion - (let ((false nil) - (true t)) - (setq url-ns-user-prefs (make-hash-table :size 13 :test 'equal)) - (set-buffer (get-buffer-create " *ns-parse*")) - (erase-buffer) - (insert-file-contents file) - (goto-char (point-min)) - (while (re-search-forward "^//" nil t) - (replace-match ";;")) - (goto-char (point-min)) - (while (re-search-forward "^user_pref(" nil t) - (replace-match "(url-ns-set-user-pref ")) - (goto-char (point-min)) - (while (re-search-forward "\"," nil t) - (replace-match "\"")) - (goto-char (point-min)) - (eval-buffer))))) + (setq url-ns-user-prefs (make-hash-table :size 13 :test 'equal)) + (with-current-buffer (get-buffer-create " *ns-parse*") + (erase-buffer) + (insert-file-contents file) + (goto-char (point-min)) + (while (re-search-forward "^//" nil t) + (replace-match ";;")) + (goto-char (point-min)) + (while (re-search-forward "^user_pref(" nil t) + (replace-match "(url-ns-set-user-pref ")) + (goto-char (point-min)) + (while (re-search-forward "\"," nil t) + (replace-match "\"")) + (goto-char (point-min)) + (with-suppressed-warnings ((lexical true false)) + (dlet ((false nil) (true t)) + (eval-buffer)))))) (defun url-ns-set-user-pref (key val) (puthash key val url-ns-user-prefs)) diff --git a/lisp/obsolete/vc-arch.el b/lisp/obsolete/vc-arch.el index 80a2094d80..00e7d26cd7 100644 --- a/lisp/obsolete/vc-arch.el +++ b/lisp/obsolete/vc-arch.el @@ -81,8 +81,7 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." (const :tag "None" t) (string :tag "Argument String") (repeat :tag "Argument List" :value ("") string)) - :version "23.1" - :group 'vc-arch) + :version "23.1") (define-obsolete-variable-alias 'vc-arch-command 'vc-arch-program "23.1") @@ -92,8 +91,7 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." (setq candidates (cdr candidates))) (or (car candidates) "tla")) "Name of the Arch executable." - :type 'string - :group 'vc-arch) + :type 'string) ;; Clear up the cache to force vc-call to check again and discover ;; new functions when we reload this file. @@ -341,7 +339,7 @@ CALLBACK expects (ENTRIES &optional MORE-TO-COME); see ("--" . permissions-changed) ("-/" . permissions-changed) ;directory )) - (state-map-regexp (regexp-opt (mapcar 'car state-map) t)) + (state-map-regexp (regexp-opt (mapcar #'car state-map) t)) (entry-regexp (concat "^" state-map-regexp " \\(.*\\)$")) result) (goto-char (point-min)) @@ -387,8 +385,7 @@ CALLBACK expects (ENTRIES &optional MORE-TO-COME); see (defcustom vc-arch-mode-line-rewrite '(("\\`.*--\\(.*--.*\\)--\\(v?\\).*-\\([0-9]+\\)\\'" . "\\2\\3[\\1]")) "Rewrite rules to shorten Arch's revision names on the mode-line." - :type '(repeat (cons regexp string)) - :group 'vc-arch) + :type '(repeat (cons regexp string))) (defun vc-arch-mode-line-string (file) "Return a string for `vc-mode-line' to put in the mode line for FILE." @@ -420,7 +417,7 @@ CALLBACK expects (ENTRIES &optional MORE-TO-COME); see ;; The .rej file is obsolete. (condition-case nil (delete-file rej) (error nil)) ;; Remove the hook so that it is not called multiple times. - (remove-hook 'after-save-hook 'vc-arch-delete-rej-if-obsolete t)))))) + (remove-hook 'after-save-hook #'vc-arch-delete-rej-if-obsolete t)))))) (defun vc-arch-find-file-hook () (let ((rej (concat buffer-file-name ".rej"))) @@ -433,7 +430,7 @@ CALLBACK expects (ENTRIES &optional MORE-TO-COME); see (condition-case nil (delete-file rej) (error nil)) (smerge-mode 1) (add-hook 'after-save-hook - 'vc-arch-delete-rej-if-obsolete nil t) + #'vc-arch-delete-rej-if-obsolete nil t) (message "There are unresolved conflicts in this file"))) (message "There are unresolved conflicts in %s" (file-name-nondirectory rej)))))) @@ -488,11 +485,11 @@ CALLBACK expects (ENTRIES &optional MORE-TO-COME); see (defun vc-arch-rename-file (old new) (vc-arch-command nil 0 new "mv" (file-relative-name old))) -(defalias 'vc-arch-responsible-p 'vc-arch-root) +(defalias 'vc-arch-responsible-p #'vc-arch-root) (defun vc-arch-command (buffer okstatus file &rest flags) "A wrapper around `vc-do-command' for use in vc-arch.el." - (apply 'vc-do-command (or buffer "*vc*") okstatus vc-arch-program file flags)) + (apply #'vc-do-command (or buffer "*vc*") okstatus vc-arch-program file flags)) ;;; Completion of versions and revisions. @@ -571,7 +568,7 @@ CALLBACK expects (ENTRIES &optional MORE-TO-COME); see (when (string-match "-\\([0-9]+\\)\\'" f) (cons (string-to-number (match-string 1 f)) f))) (directory-files dir nil nil 'nosort))) - 'car-less-than-car)) + #'car-less-than-car)) (subdirs nil)) (when (cddr revs) (dotimes (_i (/ (length revs) 2)) @@ -600,26 +597,26 @@ CALLBACK expects (ENTRIES &optional MORE-TO-COME); see (let* ((archives (directory-files rl-dir 'full directory-files-no-dot-files-regexp)) (categories - (apply 'append + (apply #'append (mapcar (lambda (dir) (when (file-directory-p dir) (directory-files dir 'full directory-files-no-dot-files-regexp))) archives))) (branches - (apply 'append + (apply #'append (mapcar (lambda (dir) (when (file-directory-p dir) (directory-files dir 'full directory-files-no-dot-files-regexp))) categories))) (versions - (apply 'append + (apply #'append (mapcar (lambda (dir) (when (file-directory-p dir) (directory-files dir 'full "--.*--"))) branches)))) - (mapc 'vc-arch-trim-one-revlib versions)) + (mapc #'vc-arch-trim-one-revlib versions)) )) (defvar vc-arch-extra-menu-map diff --git a/lisp/obsolete/vi.el b/lisp/obsolete/vi.el index eee00b43a2..91baa4d28e 100644 --- a/lisp/obsolete/vi.el +++ b/lisp/obsolete/vi.el @@ -1,4 +1,4 @@ -;;; vi.el --- major mode for emulating "vi" editor under GNU Emacs +;;; vi.el --- major mode for emulating "vi" editor under GNU Emacs -*- lexical-binding: t; -*- ;; This file is in the public domain because the authors distributed it ;; without a copyright notice before the US signed the Bern Convention. @@ -48,7 +48,7 @@ (defvar vi-mode-old-case-fold) (if (null (where-is-internal 'vi-switch-mode (current-local-map))) - (define-key ctl-x-map "~" 'vi-switch-mode)) + (define-key ctl-x-map "~" #'vi-switch-mode)) (defvar vi-tilde-map nil "Keymap used for \\[vi-switch-mode] prefix key. Link to various major modes.") @@ -56,24 +56,24 @@ (if vi-tilde-map nil (setq vi-tilde-map (make-keymap)) - (define-key vi-tilde-map "a" 'abbrev-mode) - (define-key vi-tilde-map "c" 'c-mode) - (define-key vi-tilde-map "d" 'vi-debugging) - (define-key vi-tilde-map "e" 'emacs-lisp-mode) - (define-key vi-tilde-map "f" 'auto-fill-mode) - (define-key vi-tilde-map "g" 'prolog-mode) - (define-key vi-tilde-map "h" 'hanoi) - (define-key vi-tilde-map "i" 'info-mode) - (define-key vi-tilde-map "l" 'lisp-mode) - (define-key vi-tilde-map "n" 'nroff-mode) - (define-key vi-tilde-map "o" 'overwrite-mode) - (define-key vi-tilde-map "O" 'outline-mode) - (define-key vi-tilde-map "P" 'picture-mode) - (define-key vi-tilde-map "r" 'vi-readonly-mode) - (define-key vi-tilde-map "t" 'text-mode) - (define-key vi-tilde-map "v" 'vi-mode) - (define-key vi-tilde-map "x" 'tex-mode) - (define-key vi-tilde-map "~" 'vi-back-to-old-mode)) + (define-key vi-tilde-map "a" #'abbrev-mode) + (define-key vi-tilde-map "c" #'c-mode) + (define-key vi-tilde-map "d" #'vi-debugging) + (define-key vi-tilde-map "e" #'emacs-lisp-mode) + (define-key vi-tilde-map "f" #'auto-fill-mode) + (define-key vi-tilde-map "g" #'prolog-mode) + (define-key vi-tilde-map "h" #'hanoi) + ;; (define-key vi-tilde-map "i" #'info-mode) + (define-key vi-tilde-map "l" #'lisp-mode) + (define-key vi-tilde-map "n" #'nroff-mode) + (define-key vi-tilde-map "o" #'overwrite-mode) + (define-key vi-tilde-map "O" #'outline-mode) + (define-key vi-tilde-map "P" #'picture-mode) + (define-key vi-tilde-map "r" #'vi-readonly-mode) + (define-key vi-tilde-map "t" #'text-mode) + (define-key vi-tilde-map "v" #'vi-mode) + (define-key vi-tilde-map "x" #'tex-mode) + (define-key vi-tilde-map "~" #'vi-back-to-old-mode)) (defun vi-switch-mode (arg mode-char) "Switch the major mode of current buffer as specified by the following char \\{vi-tilde-map}" @@ -123,143 +123,143 @@ command extensions.") (put 'vi-undefined 'suppress-keymap t) (if vi-com-map nil (setq vi-com-map (make-keymap)) -;;(fillarray vi-com-map 'vi-undefined) - (define-key vi-com-map "\C-@" 'vi-mark-region) ; extension - (define-key vi-com-map "\C-a" 'vi-ask-for-info) ; extension - (define-key vi-com-map "\C-b" 'vi-backward-windowful) - (define-key vi-com-map "\C-c" 'vi-do-old-mode-C-c-command) ; extension - (define-key vi-com-map "\C-d" 'vi-scroll-down-window) - (define-key vi-com-map "\C-e" 'vi-expose-line-below) - (define-key vi-com-map "\C-f" 'vi-forward-windowful) - (define-key vi-com-map "\C-g" 'keyboard-quit) - (define-key vi-com-map "\C-i" 'indent-relative-first-indent-point) ; TAB - (define-key vi-com-map "\C-j" 'vi-next-line) ; LFD - (define-key vi-com-map "\C-k" 'vi-kill-line) ; extension - (define-key vi-com-map "\C-l" 'recenter) - (define-key vi-com-map "\C-m" 'vi-next-line-first-nonwhite) ; RET - (define-key vi-com-map "\C-n" 'vi-next-line) - (define-key vi-com-map "\C-o" 'vi-split-open-line) - (define-key vi-com-map "\C-p" 'previous-line) - (define-key vi-com-map "\C-q" 'vi-query-replace) ; extension - (define-key vi-com-map "\C-r" 'vi-isearch-backward) ; modification - (define-key vi-com-map "\C-s" 'vi-isearch-forward) ; extension - (define-key vi-com-map "\C-t" 'vi-transpose-objects) ; extension - (define-key vi-com-map "\C-u" 'vi-scroll-up-window) - (define-key vi-com-map "\C-v" 'scroll-up-command) ; extension - (define-key vi-com-map "\C-w" 'vi-kill-region) ; extension +;;(fillarray vi-com-map #'vi-undefined) + (define-key vi-com-map "\C-@" #'vi-mark-region) ; extension + (define-key vi-com-map "\C-a" #'vi-ask-for-info) ; extension + (define-key vi-com-map "\C-b" #'vi-backward-windowful) + (define-key vi-com-map "\C-c" #'vi-do-old-mode-C-c-command) ; extension + (define-key vi-com-map "\C-d" #'vi-scroll-down-window) + (define-key vi-com-map "\C-e" #'vi-expose-line-below) + (define-key vi-com-map "\C-f" #'vi-forward-windowful) + (define-key vi-com-map "\C-g" #'keyboard-quit) + (define-key vi-com-map "\C-i" #'indent-relative-first-indent-point) ; TAB + (define-key vi-com-map "\C-j" #'vi-next-line) ; LFD + (define-key vi-com-map "\C-k" #'vi-kill-line) ; extension + (define-key vi-com-map "\C-l" #'recenter) + (define-key vi-com-map "\C-m" #'vi-next-line-first-nonwhite) ; RET + (define-key vi-com-map "\C-n" #'vi-next-line) + (define-key vi-com-map "\C-o" #'vi-split-open-line) + (define-key vi-com-map "\C-p" #'previous-line) + (define-key vi-com-map "\C-q" #'vi-query-replace) ; extension + (define-key vi-com-map "\C-r" #'vi-isearch-backward) ; modification + (define-key vi-com-map "\C-s" #'vi-isearch-forward) ; extension + (define-key vi-com-map "\C-t" #'vi-transpose-objects) ; extension + (define-key vi-com-map "\C-u" #'vi-scroll-up-window) + (define-key vi-com-map "\C-v" #'scroll-up-command) ; extension + (define-key vi-com-map "\C-w" #'vi-kill-region) ; extension (define-key vi-com-map "\C-x" 'Control-X-prefix) ; extension - (define-key vi-com-map "\C-y" 'vi-expose-line-above) - (define-key vi-com-map "\C-z" 'suspend-emacs) + (define-key vi-com-map "\C-y" #'vi-expose-line-above) + (define-key vi-com-map "\C-z" #'suspend-emacs) (define-key vi-com-map "\e" 'ESC-prefix); C-[ (ESC) - (define-key vi-com-map "\C-\\" 'vi-unimplemented) - (define-key vi-com-map "\C-]" 'find-tag) - (define-key vi-com-map "\C-^" 'vi-locate-def) ; extension - (define-key vi-com-map "\C-_" 'vi-undefined) - - (define-key vi-com-map " " 'forward-char) - (define-key vi-com-map "!" 'vi-operator) - (define-key vi-com-map "\"" 'vi-char-argument) - (define-key vi-com-map "#" 'universal-argument) ; extension - (define-key vi-com-map "$" 'end-of-line) - (define-key vi-com-map "%" 'vi-find-matching-paren) - (define-key vi-com-map "&" 'vi-unimplemented) - (define-key vi-com-map "'" 'vi-goto-line-mark) - (define-key vi-com-map "(" 'backward-sexp) - (define-key vi-com-map ")" 'forward-sexp) - (define-key vi-com-map "*" 'vi-name-last-change-or-macro) ; extension - (define-key vi-com-map "+" 'vi-next-line-first-nonwhite) - (define-key vi-com-map "," 'vi-reverse-last-find-char) - (define-key vi-com-map "-" 'vi-previous-line-first-nonwhite) - (define-key vi-com-map "." 'vi-redo-last-change-command) - (define-key vi-com-map "/" 'vi-search-forward) - (define-key vi-com-map "0" 'beginning-of-line) - - (define-key vi-com-map "1" 'vi-digit-argument) - (define-key vi-com-map "2" 'vi-digit-argument) - (define-key vi-com-map "3" 'vi-digit-argument) - (define-key vi-com-map "4" 'vi-digit-argument) - (define-key vi-com-map "5" 'vi-digit-argument) - (define-key vi-com-map "6" 'vi-digit-argument) - (define-key vi-com-map "7" 'vi-digit-argument) - (define-key vi-com-map "8" 'vi-digit-argument) - (define-key vi-com-map "9" 'vi-digit-argument) - - (define-key vi-com-map ":" 'vi-ex-cmd) - (define-key vi-com-map ";" 'vi-repeat-last-find-char) - (define-key vi-com-map "<" 'vi-operator) - (define-key vi-com-map "=" 'vi-operator) - (define-key vi-com-map ">" 'vi-operator) - (define-key vi-com-map "?" 'vi-search-backward) - (define-key vi-com-map "@" 'vi-call-named-change-or-macro) ; extension - - (define-key vi-com-map "A" 'vi-append-at-end-of-line) - (define-key vi-com-map "B" 'vi-backward-blank-delimited-word) - (define-key vi-com-map "C" 'vi-change-rest-of-line) - (define-key vi-com-map "D" 'vi-kill-line) - (define-key vi-com-map "E" 'vi-end-of-blank-delimited-word) - (define-key vi-com-map "F" 'vi-backward-find-char) - (define-key vi-com-map "G" 'vi-goto-line) - (define-key vi-com-map "H" 'vi-home-window-line) - (define-key vi-com-map "I" 'vi-insert-before-first-nonwhite) - (define-key vi-com-map "J" 'vi-join-lines) - (define-key vi-com-map "K" 'vi-undefined) - (define-key vi-com-map "L" 'vi-last-window-line) - (define-key vi-com-map "M" 'vi-middle-window-line) - (define-key vi-com-map "N" 'vi-reverse-last-search) - (define-key vi-com-map "O" 'vi-open-above) - (define-key vi-com-map "P" 'vi-put-before) - (define-key vi-com-map "Q" 'vi-quote-words) ; extension - (define-key vi-com-map "R" 'vi-replace-chars) - (define-key vi-com-map "S" 'vi-substitute-lines) - (define-key vi-com-map "T" 'vi-backward-upto-char) - (define-key vi-com-map "U" 'vi-unimplemented) - (define-key vi-com-map "V" 'vi-undefined) - (define-key vi-com-map "W" 'vi-forward-blank-delimited-word) - (define-key vi-com-map "X" 'call-last-kbd-macro) ; modification/extension - (define-key vi-com-map "Y" 'vi-yank-line) + (define-key vi-com-map "\C-\\" #'vi-unimplemented) + (define-key vi-com-map "\C-]" #'xref-find-definitions) + (define-key vi-com-map "\C-^" #'vi-locate-def) ; extension + (define-key vi-com-map "\C-_" #'vi-undefined) + + (define-key vi-com-map " " #'forward-char) + (define-key vi-com-map "!" #'vi-operator) + (define-key vi-com-map "\"" #'vi-char-argument) + (define-key vi-com-map "#" #'universal-argument) ; extension + (define-key vi-com-map "$" #'end-of-line) + (define-key vi-com-map "%" #'vi-find-matching-paren) + (define-key vi-com-map "&" #'vi-unimplemented) + (define-key vi-com-map "'" #'vi-goto-line-mark) + (define-key vi-com-map "(" #'backward-sexp) + (define-key vi-com-map ")" #'forward-sexp) + (define-key vi-com-map "*" #'vi-name-last-change-or-macro) ; extension + (define-key vi-com-map "+" #'vi-next-line-first-nonwhite) + (define-key vi-com-map "," #'vi-reverse-last-find-char) + (define-key vi-com-map "-" #'vi-previous-line-first-nonwhite) + (define-key vi-com-map "." #'vi-redo-last-change-command) + (define-key vi-com-map "/" #'vi-search-forward) + (define-key vi-com-map "0" #'beginning-of-line) + + (define-key vi-com-map "1" #'vi-digit-argument) + (define-key vi-com-map "2" #'vi-digit-argument) + (define-key vi-com-map "3" #'vi-digit-argument) + (define-key vi-com-map "4" #'vi-digit-argument) + (define-key vi-com-map "5" #'vi-digit-argument) + (define-key vi-com-map "6" #'vi-digit-argument) + (define-key vi-com-map "7" #'vi-digit-argument) + (define-key vi-com-map "8" #'vi-digit-argument) + (define-key vi-com-map "9" #'vi-digit-argument) + + (define-key vi-com-map ":" #'vi-ex-cmd) + (define-key vi-com-map ";" #'vi-repeat-last-find-char) + (define-key vi-com-map "<" #'vi-operator) + (define-key vi-com-map "=" #'vi-operator) + (define-key vi-com-map ">" #'vi-operator) + (define-key vi-com-map "?" #'vi-search-backward) + (define-key vi-com-map "@" #'vi-call-named-change-or-macro) ; extension + + (define-key vi-com-map "A" #'vi-append-at-end-of-line) + (define-key vi-com-map "B" #'vi-backward-blank-delimited-word) + (define-key vi-com-map "C" #'vi-change-rest-of-line) + (define-key vi-com-map "D" #'vi-kill-line) + (define-key vi-com-map "E" #'vi-end-of-blank-delimited-word) + (define-key vi-com-map "F" #'vi-backward-find-char) + (define-key vi-com-map "G" #'vi-goto-line) + (define-key vi-com-map "H" #'vi-home-window-line) + (define-key vi-com-map "I" #'vi-insert-before-first-nonwhite) + (define-key vi-com-map "J" #'vi-join-lines) + (define-key vi-com-map "K" #'vi-undefined) + (define-key vi-com-map "L" #'vi-last-window-line) + (define-key vi-com-map "M" #'vi-middle-window-line) + (define-key vi-com-map "N" #'vi-reverse-last-search) + (define-key vi-com-map "O" #'vi-open-above) + (define-key vi-com-map "P" #'vi-put-before) + (define-key vi-com-map "Q" #'vi-quote-words) ; extension + (define-key vi-com-map "R" #'vi-replace-chars) + (define-key vi-com-map "S" #'vi-substitute-lines) + (define-key vi-com-map "T" #'vi-backward-upto-char) + (define-key vi-com-map "U" #'vi-unimplemented) + (define-key vi-com-map "V" #'vi-undefined) + (define-key vi-com-map "W" #'vi-forward-blank-delimited-word) + (define-key vi-com-map "X" #'call-last-kbd-macro) ; modification/extension + (define-key vi-com-map "Y" #'vi-yank-line) (define-key vi-com-map "Z" (make-sparse-keymap)) ;allow below prefix command - (define-key vi-com-map "ZZ" 'vi-save-all-and-exit) - - (define-key vi-com-map "[" 'vi-unimplemented) - (define-key vi-com-map "\\" 'vi-operator) ; extension for vi-narrow-op - (define-key vi-com-map "]" 'vi-unimplemented) - (define-key vi-com-map "^" 'back-to-indentation) - (define-key vi-com-map "_" 'vi-undefined) - (define-key vi-com-map "`" 'vi-goto-char-mark) - - (define-key vi-com-map "a" 'vi-insert-after) - (define-key vi-com-map "b" 'backward-word) - (define-key vi-com-map "c" 'vi-operator) - (define-key vi-com-map "d" 'vi-operator) - (define-key vi-com-map "e" 'vi-end-of-word) - (define-key vi-com-map "f" 'vi-forward-find-char) - (define-key vi-com-map "g" 'vi-beginning-of-buffer) ; extension - (define-key vi-com-map "h" 'backward-char) - (define-key vi-com-map "i" 'vi-insert-before) - (define-key vi-com-map "j" 'vi-next-line) - (define-key vi-com-map "k" 'previous-line) - (define-key vi-com-map "l" 'forward-char) - (define-key vi-com-map "m" 'vi-set-mark) - (define-key vi-com-map "n" 'vi-repeat-last-search) - (define-key vi-com-map "o" 'vi-open-below) - (define-key vi-com-map "p" 'vi-put-after) - (define-key vi-com-map "q" 'vi-replace) - (define-key vi-com-map "r" 'vi-replace-1-char) - (define-key vi-com-map "s" 'vi-substitute-chars) - (define-key vi-com-map "t" 'vi-forward-upto-char) - (define-key vi-com-map "u" 'undo) - (define-key vi-com-map "v" 'vi-verify-spelling) - (define-key vi-com-map "w" 'vi-forward-word) - (define-key vi-com-map "x" 'vi-kill-char) - (define-key vi-com-map "y" 'vi-operator) - (define-key vi-com-map "z" 'vi-adjust-window) - - (define-key vi-com-map "{" 'backward-paragraph) - (define-key vi-com-map "|" 'vi-goto-column) - (define-key vi-com-map "}" 'forward-paragraph) - (define-key vi-com-map "~" 'vi-change-case) - (define-key vi-com-map "\177" 'delete-backward-char)) + (define-key vi-com-map "ZZ" #'vi-save-all-and-exit) + + (define-key vi-com-map "[" #'vi-unimplemented) + (define-key vi-com-map "\\" #'vi-operator) ; extension for vi-narrow-op + (define-key vi-com-map "]" #'vi-unimplemented) + (define-key vi-com-map "^" #'back-to-indentation) + (define-key vi-com-map "_" #'vi-undefined) + (define-key vi-com-map "`" #'vi-goto-char-mark) + + (define-key vi-com-map "a" #'vi-insert-after) + (define-key vi-com-map "b" #'backward-word) + (define-key vi-com-map "c" #'vi-operator) + (define-key vi-com-map "d" #'vi-operator) + (define-key vi-com-map "e" #'vi-end-of-word) + (define-key vi-com-map "f" #'vi-forward-find-char) + (define-key vi-com-map "g" #'vi-beginning-of-buffer) ; extension + (define-key vi-com-map "h" #'backward-char) + (define-key vi-com-map "i" #'vi-insert-before) + (define-key vi-com-map "j" #'vi-next-line) + (define-key vi-com-map "k" #'previous-line) + (define-key vi-com-map "l" #'forward-char) + (define-key vi-com-map "m" #'vi-set-mark) + (define-key vi-com-map "n" #'vi-repeat-last-search) + (define-key vi-com-map "o" #'vi-open-below) + (define-key vi-com-map "p" #'vi-put-after) + (define-key vi-com-map "q" #'vi-replace) + (define-key vi-com-map "r" #'vi-replace-1-char) + (define-key vi-com-map "s" #'vi-substitute-chars) + (define-key vi-com-map "t" #'vi-forward-upto-char) + (define-key vi-com-map "u" #'undo) + (define-key vi-com-map "v" #'vi-verify-spelling) + (define-key vi-com-map "w" #'vi-forward-word) + (define-key vi-com-map "x" #'vi-kill-char) + (define-key vi-com-map "y" #'vi-operator) + (define-key vi-com-map "z" #'vi-adjust-window) + + (define-key vi-com-map "{" #'backward-paragraph) + (define-key vi-com-map "|" #'vi-goto-column) + (define-key vi-com-map "}" #'forward-paragraph) + (define-key vi-com-map "~" #'vi-change-case) + (define-key vi-com-map "\177" #'delete-backward-char)) (put 'backward-char 'point-moving-unit 'char) (put 'vi-next-line 'point-moving-unit 'line) @@ -1182,7 +1182,7 @@ SPECIAL FEATURE: char argument can be used to specify shift amount(1-9)." (defun vi-narrow-op (motion-command arg) "Narrow to region specified by MOTION-COMMAND with ARG." (let* ((range (vi-effective-range motion-command arg)) - (begin (car range)) (end (cdr range)) reg) + (begin (car range)) (end (cdr range))) (if (= begin end) nil ; point not moved, abort op (narrow-to-region begin end)))) diff --git a/lisp/obsolete/vip.el b/lisp/obsolete/vip.el index 08085e51d7..16906b68a6 100644 --- a/lisp/obsolete/vip.el +++ b/lisp/obsolete/vip.el @@ -1,4 +1,4 @@ -;;; vip.el --- a VI Package for GNU Emacs +;;; vip.el --- a VI Package for GNU Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 1986-1988, 1992-1993, 1998, 2001-2021 Free Software ;; Foundation, Inc. @@ -95,13 +95,11 @@ (defcustom vip-shift-width 8 "The number of columns shifted by > and < command." - :type 'integer - :group 'vip) + :type 'integer) (defcustom vip-re-replace nil "If t then do regexp replace, if nil then do string replace." - :type 'boolean - :group 'vip) + :type 'boolean) (defvar vip-d-char nil "The character remembered by the vi \"r\" command.") @@ -120,13 +118,11 @@ (defcustom vip-search-wrap-around t "If t, search wraps around." - :type 'boolean - :group 'vip) + :type 'boolean) (defcustom vip-re-search nil "If t, search is reg-exp search, otherwise vanilla search." - :type 'boolean - :group 'vip) + :type 'boolean) (defvar vip-s-string nil "Last vip search string.") @@ -136,24 +132,20 @@ (defcustom vip-case-fold-search nil "If t, search ignores cases." - :type 'boolean - :group 'vip) + :type 'boolean) (defcustom vip-re-query-replace nil "If t then do regexp replace, if nil then do string replace." - :type 'boolean - :group 'vip) + :type 'boolean) (defcustom vip-open-with-indent nil "If t, indent when open a new line." - :type 'boolean - :group 'vip) + :type 'boolean) (defcustom vip-help-in-insert-mode nil "If t then C-h is bound to help-command in insert mode. If nil then it is bound to `delete-backward-char'." - :type 'boolean - :group 'vip) + :type 'boolean) (defvar vip-quote-string "> " "String inserted at the beginning of region.") @@ -169,131 +161,131 @@ If nil then it is bound to `delete-backward-char'." (defvar vip-mode-map (let ((map (make-keymap))) - (define-key map "\C-a" 'beginning-of-line) - (define-key map "\C-b" 'vip-scroll-back) - (define-key map "\C-c" 'vip-ctl-c) - (define-key map "\C-d" 'vip-scroll-up) - (define-key map "\C-e" 'vip-scroll-up-one) - (define-key map "\C-f" 'vip-scroll) - (define-key map "\C-g" 'vip-keyboard-quit) - (define-key map "\C-h" 'help-command) - (define-key map "\C-m" 'vip-scroll-back) - (define-key map "\C-n" 'vip-other-window) - (define-key map "\C-o" 'vip-open-line-at-point) - (define-key map "\C-u" 'vip-scroll-down) - (define-key map "\C-x" 'vip-ctl-x) - (define-key map "\C-y" 'vip-scroll-down-one) - (define-key map "\C-z" 'vip-change-mode-to-emacs) - (define-key map "\e" 'vip-ESC) - - (define-key map [?\S-\ ] 'vip-scroll-back) - (define-key map " " 'vip-scroll) - (define-key map "!" 'vip-command-argument) - (define-key map "\"" 'vip-command-argument) - (define-key map "#" 'vip-command-argument) - (define-key map "$" 'vip-goto-eol) - (define-key map "%" 'vip-paren-match) - (define-key map "&" 'vip-nil) - (define-key map "'" 'vip-goto-mark-and-skip-white) - (define-key map "(" 'vip-backward-sentence) - (define-key map ")" 'vip-forward-sentence) - (define-key map "*" 'call-last-kbd-macro) - (define-key map "+" 'vip-next-line-at-bol) - (define-key map "," 'vip-repeat-find-opposite) - (define-key map "-" 'vip-previous-line-at-bol) - (define-key map "." 'vip-repeat) - (define-key map "/" 'vip-search-forward) - - (define-key map "0" 'vip-beginning-of-line) - (define-key map "1" 'vip-digit-argument) - (define-key map "2" 'vip-digit-argument) - (define-key map "3" 'vip-digit-argument) - (define-key map "4" 'vip-digit-argument) - (define-key map "5" 'vip-digit-argument) - (define-key map "6" 'vip-digit-argument) - (define-key map "7" 'vip-digit-argument) - (define-key map "8" 'vip-digit-argument) - (define-key map "9" 'vip-digit-argument) - - (define-key map ":" 'vip-ex) - (define-key map ";" 'vip-repeat-find) - (define-key map "<" 'vip-command-argument) - (define-key map "=" 'vip-command-argument) - (define-key map ">" 'vip-command-argument) - (define-key map "?" 'vip-search-backward) - (define-key map "@" 'vip-nil) - - (define-key map "A" 'vip-Append) - (define-key map "B" 'vip-backward-Word) - (define-key map "C" 'vip-ctl-c-equivalent) - (define-key map "D" 'vip-kill-line) - (define-key map "E" 'vip-end-of-Word) - (define-key map "F" 'vip-find-char-backward) - (define-key map "G" 'vip-goto-line) - (define-key map "H" 'vip-window-top) - (define-key map "I" 'vip-Insert) - (define-key map "J" 'vip-join-lines) - (define-key map "K" 'vip-kill-buffer) - (define-key map "L" 'vip-window-bottom) - (define-key map "M" 'vip-window-middle) - (define-key map "N" 'vip-search-Next) - (define-key map "O" 'vip-Open-line) - (define-key map "P" 'vip-Put-back) - (define-key map "Q" 'vip-query-replace) - (define-key map "R" 'vip-replace-string) - (define-key map "S" 'vip-switch-to-buffer-other-window) - (define-key map "T" 'vip-goto-char-backward) - (define-key map "U" 'vip-nil) - (define-key map "V" 'vip-find-file-other-window) - (define-key map "W" 'vip-forward-Word) - (define-key map "X" 'vip-ctl-x-equivalent) - (define-key map "Y" 'vip-yank-line) - (define-key map "ZZ" 'save-buffers-kill-emacs) - - (define-key map "[" 'vip-nil) - (define-key map "\\" 'vip-escape-to-emacs) - (define-key map "]" 'vip-nil) - (define-key map "^" 'vip-bol-and-skip-white) - (define-key map "_" 'vip-nil) - (define-key map "`" 'vip-goto-mark) - - (define-key map "a" 'vip-append) - (define-key map "b" 'vip-backward-word) - (define-key map "c" 'vip-command-argument) - (define-key map "d" 'vip-command-argument) - (define-key map "e" 'vip-end-of-word) - (define-key map "f" 'vip-find-char-forward) - (define-key map "g" 'vip-info-on-file) - (define-key map "h" 'vip-backward-char) - (define-key map "i" 'vip-insert) - (define-key map "j" 'vip-next-line) - (define-key map "k" 'vip-previous-line) - (define-key map "l" 'vip-forward-char) - (define-key map "m" 'vip-mark-point) - (define-key map "n" 'vip-search-next) - (define-key map "o" 'vip-open-line) - (define-key map "p" 'vip-put-back) - (define-key map "q" 'vip-nil) - (define-key map "r" 'vip-replace-char) - (define-key map "s" 'vip-switch-to-buffer) - (define-key map "t" 'vip-goto-char-forward) - (define-key map "u" 'vip-undo) - (define-key map "v" 'vip-find-file) - (define-key map "w" 'vip-forward-word) - (define-key map "x" 'vip-delete-char) - (define-key map "y" 'vip-command-argument) - (define-key map "zH" 'vip-line-to-top) - (define-key map "zM" 'vip-line-to-middle) - (define-key map "zL" 'vip-line-to-bottom) - (define-key map "z\C-m" 'vip-line-to-top) - (define-key map "z." 'vip-line-to-middle) - (define-key map "z-" 'vip-line-to-bottom) - - (define-key map "{" 'vip-backward-paragraph) - (define-key map "|" 'vip-goto-col) - (define-key map "}" 'vip-forward-paragraph) - (define-key map "~" 'vip-nil) - (define-key map "\177" 'vip-delete-backward-char) + (define-key map "\C-a" #'beginning-of-line) + (define-key map "\C-b" #'vip-scroll-back) + (define-key map "\C-c" #'vip-ctl-c) + (define-key map "\C-d" #'vip-scroll-up) + (define-key map "\C-e" #'vip-scroll-up-one) + (define-key map "\C-f" #'vip-scroll) + (define-key map "\C-g" #'vip-keyboard-quit) + (define-key map "\C-h" #'help-command) + (define-key map "\C-m" #'vip-scroll-back) + (define-key map "\C-n" #'vip-other-window) + (define-key map "\C-o" #'vip-open-line-at-point) + (define-key map "\C-u" #'vip-scroll-down) + (define-key map "\C-x" #'vip-ctl-x) + (define-key map "\C-y" #'vip-scroll-down-one) + (define-key map "\C-z" #'vip-change-mode-to-emacs) + (define-key map "\e" #'vip-ESC) + + (define-key map [?\S-\ ] #'vip-scroll-back) + (define-key map " " #'vip-scroll) + (define-key map "!" #'vip-command-argument) + (define-key map "\"" #'vip-command-argument) + (define-key map "#" #'vip-command-argument) + (define-key map "$" #'vip-goto-eol) + (define-key map "%" #'vip-paren-match) + (define-key map "&" #'vip-nil) + (define-key map "'" #'vip-goto-mark-and-skip-white) + (define-key map "(" #'vip-backward-sentence) + (define-key map ")" #'vip-forward-sentence) + (define-key map "*" #'call-last-kbd-macro) + (define-key map "+" #'vip-next-line-at-bol) + (define-key map "," #'vip-repeat-find-opposite) + (define-key map "-" #'vip-previous-line-at-bol) + (define-key map "." #'vip-repeat) + (define-key map "/" #'vip-search-forward) + + (define-key map "0" #'vip-beginning-of-line) + (define-key map "1" #'vip-digit-argument) + (define-key map "2" #'vip-digit-argument) + (define-key map "3" #'vip-digit-argument) + (define-key map "4" #'vip-digit-argument) + (define-key map "5" #'vip-digit-argument) + (define-key map "6" #'vip-digit-argument) + (define-key map "7" #'vip-digit-argument) + (define-key map "8" #'vip-digit-argument) + (define-key map "9" #'vip-digit-argument) + + (define-key map ":" #'vip-ex) + (define-key map ";" #'vip-repeat-find) + (define-key map "<" #'vip-command-argument) + (define-key map "=" #'vip-command-argument) + (define-key map ">" #'vip-command-argument) + (define-key map "?" #'vip-search-backward) + (define-key map "@" #'vip-nil) + + (define-key map "A" #'vip-Append) + (define-key map "B" #'vip-backward-Word) + (define-key map "C" #'vip-ctl-c-equivalent) + (define-key map "D" #'vip-kill-line) + (define-key map "E" #'vip-end-of-Word) + (define-key map "F" #'vip-find-char-backward) + (define-key map "G" #'vip-goto-line) + (define-key map "H" #'vip-window-top) + (define-key map "I" #'vip-Insert) + (define-key map "J" #'vip-join-lines) + (define-key map "K" #'vip-kill-buffer) + (define-key map "L" #'vip-window-bottom) + (define-key map "M" #'vip-window-middle) + (define-key map "N" #'vip-search-Next) + (define-key map "O" #'vip-Open-line) + (define-key map "P" #'vip-Put-back) + (define-key map "Q" #'vip-query-replace) + (define-key map "R" #'vip-replace-string) + (define-key map "S" #'vip-switch-to-buffer-other-window) + (define-key map "T" #'vip-goto-char-backward) + (define-key map "U" #'vip-nil) + (define-key map "V" #'vip-find-file-other-window) + (define-key map "W" #'vip-forward-Word) + (define-key map "X" #'vip-ctl-x-equivalent) + (define-key map "Y" #'vip-yank-line) + (define-key map "ZZ" #'save-buffers-kill-emacs) + + (define-key map "[" #'vip-nil) + (define-key map "\\" #'vip-escape-to-emacs) + (define-key map "]" #'vip-nil) + (define-key map "^" #'vip-bol-and-skip-white) + (define-key map "_" #'vip-nil) + (define-key map "`" #'vip-goto-mark) + + (define-key map "a" #'vip-append) + (define-key map "b" #'vip-backward-word) + (define-key map "c" #'vip-command-argument) + (define-key map "d" #'vip-command-argument) + (define-key map "e" #'vip-end-of-word) + (define-key map "f" #'vip-find-char-forward) + (define-key map "g" #'vip-info-on-file) + (define-key map "h" #'vip-backward-char) + (define-key map "i" #'vip-insert) + (define-key map "j" #'vip-next-line) + (define-key map "k" #'vip-previous-line) + (define-key map "l" #'vip-forward-char) + (define-key map "m" #'vip-mark-point) + (define-key map "n" #'vip-search-next) + (define-key map "o" #'vip-open-line) + (define-key map "p" #'vip-put-back) + (define-key map "q" #'vip-nil) + (define-key map "r" #'vip-replace-char) + (define-key map "s" #'vip-switch-to-buffer) + (define-key map "t" #'vip-goto-char-forward) + (define-key map "u" #'vip-undo) + (define-key map "v" #'vip-find-file) + (define-key map "w" #'vip-forward-word) + (define-key map "x" #'vip-delete-char) + (define-key map "y" #'vip-command-argument) + (define-key map "zH" #'vip-line-to-top) + (define-key map "zM" #'vip-line-to-middle) + (define-key map "zL" #'vip-line-to-bottom) + (define-key map "z\C-m" #'vip-line-to-top) + (define-key map "z." #'vip-line-to-middle) + (define-key map "z-" #'vip-line-to-bottom) + + (define-key map "{" #'vip-backward-paragraph) + (define-key map "|" #'vip-goto-col) + (define-key map "}" #'vip-forward-paragraph) + (define-key map "~" #'vip-nil) + (define-key map "\177" #'vip-delete-backward-char) map)) (defun vip-version () @@ -306,8 +298,8 @@ If nil then it is bound to `delete-backward-char'." ;;;###autoload (defun vip-setup () "Set up bindings for C-x 7 and C-z that are useful for VIP users." - (define-key ctl-x-map "7" 'vip-buffer-in-two-windows) - (global-set-key "\C-z" 'vip-change-mode-to-vi)) + (define-key ctl-x-map "7" #'vip-buffer-in-two-windows) + (global-set-key "\C-z" #'vip-change-mode-to-vi)) (defmacro vip-loop (count body) "(COUNT BODY) Execute BODY COUNT times." @@ -375,13 +367,13 @@ No message." vip-emacs-local-map))) (vip-change-mode-line "Insert") (use-local-map vip-insert-local-map) - (define-key vip-insert-local-map "\e" 'vip-change-mode-to-vi) - (define-key vip-insert-local-map "\C-z" 'vip-ESC) + (define-key vip-insert-local-map "\e" #'vip-change-mode-to-vi) + (define-key vip-insert-local-map "\C-z" #'vip-ESC) (define-key vip-insert-local-map "\C-h" - (if vip-help-in-insert-mode 'help-command - 'delete-backward-char)) + (if vip-help-in-insert-mode #'help-command + #'delete-backward-char)) (define-key vip-insert-local-map "\C-w" - 'vip-delete-backward-word)) + #'vip-delete-backward-word)) ((eq new-mode 'emacs-mode) (vip-change-mode-line "Emacs:") (use-local-map vip-emacs-local-map))) @@ -461,13 +453,13 @@ Type `n' to quit this window for now.\n") ARG is used as the prefix value for the executed command. If EVENTS is a list of events, which become the beginning of the command." (interactive "P") - (let (com key (old-map (current-local-map))) + (let (com (old-map (current-local-map))) (if events (setq unread-command-events (append events unread-command-events))) (setq prefix-arg arg) (use-local-map vip-emacs-local-map) (unwind-protect - (setq com (key-binding (setq key (read-key-sequence nil)))) + (setq com (key-binding (read-key-sequence nil))) (use-local-map old-map)) (command-execute com prefix-arg) (setq prefix-arg nil) ;; reset prefix arg @@ -617,7 +609,7 @@ obtained so far, and COM is the command part obtained so far." (defun vip-command-argument (arg) "Accept a motion command as an argument." (interactive "P") - (condition-case conditions + (condition-case nil (vip-prefix-arg-com last-command-event (cond ((null arg) nil) @@ -918,11 +910,11 @@ each line in the region." (defun vip-read-string (prompt &optional init) (setq vip-save-minibuffer-local-map (copy-keymap minibuffer-local-map)) - (define-key minibuffer-local-map "\C-h" 'backward-char) - (define-key minibuffer-local-map "\C-w" 'backward-word) - (define-key minibuffer-local-map "\e" 'exit-minibuffer) + (define-key minibuffer-local-map "\C-h" #'backward-char) + (define-key minibuffer-local-map "\C-w" #'backward-word) + (define-key minibuffer-local-map "\e" #'exit-minibuffer) (let (str) - (condition-case conditions + (condition-case nil (setq str (read-string prompt init)) (quit (setq minibuffer-local-map vip-save-minibuffer-local-map) @@ -2651,7 +2643,7 @@ a token has type \(command, address, end-mark) and value." (progn (with-output-to-temp-buffer " *delete text*" (princ (buffer-substring (point) (mark)))) - (condition-case conditions + (condition-case nil (vip-read-string "[Hit return to continue] ") (quit (save-excursion (kill-buffer " *delete text*")) @@ -2759,7 +2751,7 @@ a token has type \(command, address, end-mark) and value." (progn (with-output-to-temp-buffer " *text*" (princ (buffer-substring (point) (mark)))) - (condition-case conditions + (condition-case nil (progn (vip-read-string "[Hit return to continue] ") (ex-line-subr com (point) (mark))) @@ -2829,12 +2821,9 @@ a token has type \(command, address, end-mark) and value." (define-key ex-map char (or (lookup-key vip-mode-map char) 'vip-nil))) (define-key vip-mode-map char - (eval - (list 'quote - (cons 'lambda - (list '(count) - '(interactive "p") - (list 'execute-kbd-macro string 'count)))))))) + (lambda (count) + (interactive "p") + (execute-kbd-macro string count))))) (defun ex-unmap () "ex unmap" @@ -2892,10 +2881,7 @@ a token has type \(command, address, end-mark) and value." (with-no-warnings (insert-file file))))) -(defun ex-set () - (eval (list 'setq - (read-variable "Variable: ") - (eval (read-minibuffer "Value: "))))) +(defalias 'ex-set #'set-variable) (defun ex-shell () "ex shell" @@ -2935,7 +2921,7 @@ vip-s-string" (setq ex-addresses (cons (car ex-addresses) ex-addresses))))) ;(setq G opt-g) (let ((beg (car ex-addresses)) (end (car (cdr ex-addresses))) - (cont t) eol-mark) + eol-mark) ;;(cont t) (save-excursion (vip-enlarge-region beg end) (let ((limit (save-excursion diff --git a/lisp/obsolete/ws-mode.el b/lisp/obsolete/ws-mode.el index d1ced86c46..235a1d7e43 100644 --- a/lisp/obsolete/ws-mode.el +++ b/lisp/obsolete/ws-mode.el @@ -41,144 +41,144 @@ (defvar wordstar-C-k-map (let ((map (make-keymap))) (define-key map " " ()) - (define-key map "0" 'ws-set-marker-0) - (define-key map "1" 'ws-set-marker-1) - (define-key map "2" 'ws-set-marker-2) - (define-key map "3" 'ws-set-marker-3) - (define-key map "4" 'ws-set-marker-4) - (define-key map "5" 'ws-set-marker-5) - (define-key map "6" 'ws-set-marker-6) - (define-key map "7" 'ws-set-marker-7) - (define-key map "8" 'ws-set-marker-8) - (define-key map "9" 'ws-set-marker-9) - (define-key map "b" 'ws-begin-block) - (define-key map "\C-b" 'ws-begin-block) - (define-key map "c" 'ws-copy-block) - (define-key map "\C-c" 'ws-copy-block) - (define-key map "d" 'save-buffers-kill-emacs) - (define-key map "\C-d" 'save-buffers-kill-emacs) - (define-key map "f" 'find-file) - (define-key map "\C-f" 'find-file) - (define-key map "h" 'ws-show-markers) - (define-key map "\C-h" 'ws-show-markers) - (define-key map "i" 'ws-indent-block) - (define-key map "\C-i" 'ws-indent-block) - (define-key map "k" 'ws-end-block) - (define-key map "\C-k" 'ws-end-block) - (define-key map "p" 'ws-print-block) - (define-key map "\C-p" 'ws-print-block) - (define-key map "q" 'kill-emacs) - (define-key map "\C-q" 'kill-emacs) - (define-key map "r" 'insert-file) - (define-key map "\C-r" 'insert-file) - (define-key map "s" 'save-some-buffers) - (define-key map "\C-s" 'save-some-buffers) - (define-key map "t" 'ws-mark-word) - (define-key map "\C-t" 'ws-mark-word) - (define-key map "u" 'ws-exdent-block) - (define-key map "\C-u" 'keyboard-quit) - (define-key map "v" 'ws-move-block) - (define-key map "\C-v" 'ws-move-block) - (define-key map "w" 'ws-write-block) - (define-key map "\C-w" 'ws-write-block) - (define-key map "x" 'save-buffers-kill-emacs) - (define-key map "\C-x" 'save-buffers-kill-emacs) - (define-key map "y" 'ws-delete-block) - (define-key map "\C-y" 'ws-delete-block) + (define-key map "0" #'ws-set-marker-0) + (define-key map "1" #'ws-set-marker-1) + (define-key map "2" #'ws-set-marker-2) + (define-key map "3" #'ws-set-marker-3) + (define-key map "4" #'ws-set-marker-4) + (define-key map "5" #'ws-set-marker-5) + (define-key map "6" #'ws-set-marker-6) + (define-key map "7" #'ws-set-marker-7) + (define-key map "8" #'ws-set-marker-8) + (define-key map "9" #'ws-set-marker-9) + (define-key map "b" #'ws-begin-block) + (define-key map "\C-b" #'ws-begin-block) + (define-key map "c" #'ws-copy-block) + (define-key map "\C-c" #'ws-copy-block) + (define-key map "d" #'save-buffers-kill-emacs) + (define-key map "\C-d" #'save-buffers-kill-emacs) + (define-key map "f" #'find-file) + (define-key map "\C-f" #'find-file) + (define-key map "h" #'ws-show-markers) + (define-key map "\C-h" #'ws-show-markers) + (define-key map "i" #'ws-indent-block) + (define-key map "\C-i" #'ws-indent-block) + (define-key map "k" #'ws-end-block) + (define-key map "\C-k" #'ws-end-block) + (define-key map "p" #'ws-print-block) + (define-key map "\C-p" #'ws-print-block) + (define-key map "q" #'kill-emacs) + (define-key map "\C-q" #'kill-emacs) + (define-key map "r" #'insert-file) + (define-key map "\C-r" #'insert-file) + (define-key map "s" #'save-some-buffers) + (define-key map "\C-s" #'save-some-buffers) + (define-key map "t" #'ws-mark-word) + (define-key map "\C-t" #'ws-mark-word) + (define-key map "u" #'ws-exdent-block) + (define-key map "\C-u" #'keyboard-quit) + (define-key map "v" #'ws-move-block) + (define-key map "\C-v" #'ws-move-block) + (define-key map "w" #'ws-write-block) + (define-key map "\C-w" #'ws-write-block) + (define-key map "x" #'save-buffers-kill-emacs) + (define-key map "\C-x" #'save-buffers-kill-emacs) + (define-key map "y" #'ws-delete-block) + (define-key map "\C-y" #'ws-delete-block) map)) (defvar wordstar-C-o-map (let ((map (make-keymap))) (define-key map " " ()) - (define-key map "c" 'wordstar-center-line) - (define-key map "\C-c" 'wordstar-center-line) - (define-key map "b" 'switch-to-buffer) - (define-key map "\C-b" 'switch-to-buffer) - (define-key map "j" 'justify-current-line) - (define-key map "\C-j" 'justify-current-line) - (define-key map "k" 'kill-buffer) - (define-key map "\C-k" 'kill-buffer) - (define-key map "l" 'list-buffers) - (define-key map "\C-l" 'list-buffers) - (define-key map "m" 'auto-fill-mode) - (define-key map "\C-m" 'auto-fill-mode) - (define-key map "r" 'set-fill-column) - (define-key map "\C-r" 'set-fill-column) - (define-key map "\C-u" 'keyboard-quit) - (define-key map "wd" 'delete-other-windows) - (define-key map "wh" 'split-window-right) - (define-key map "wo" 'other-window) - (define-key map "wv" 'split-window-below) + (define-key map "c" #'wordstar-center-line) + (define-key map "\C-c" #'wordstar-center-line) + (define-key map "b" #'switch-to-buffer) + (define-key map "\C-b" #'switch-to-buffer) + (define-key map "j" #'justify-current-line) + (define-key map "\C-j" #'justify-current-line) + (define-key map "k" #'kill-buffer) + (define-key map "\C-k" #'kill-buffer) + (define-key map "l" #'list-buffers) + (define-key map "\C-l" #'list-buffers) + (define-key map "m" #'auto-fill-mode) + (define-key map "\C-m" #'auto-fill-mode) + (define-key map "r" #'set-fill-column) + (define-key map "\C-r" #'set-fill-column) + (define-key map "\C-u" #'keyboard-quit) + (define-key map "wd" #'delete-other-windows) + (define-key map "wh" #'split-window-right) + (define-key map "wo" #'other-window) + (define-key map "wv" #'split-window-below) map)) (defvar wordstar-C-q-map (let ((map (make-keymap))) (define-key map " " ()) - (define-key map "0" 'ws-find-marker-0) - (define-key map "1" 'ws-find-marker-1) - (define-key map "2" 'ws-find-marker-2) - (define-key map "3" 'ws-find-marker-3) - (define-key map "4" 'ws-find-marker-4) - (define-key map "5" 'ws-find-marker-5) - (define-key map "6" 'ws-find-marker-6) - (define-key map "7" 'ws-find-marker-7) - (define-key map "8" 'ws-find-marker-8) - (define-key map "9" 'ws-find-marker-9) - (define-key map "a" 'ws-query-replace) - (define-key map "\C-a" 'ws-query-replace) - (define-key map "b" 'ws-goto-block-begin) - (define-key map "\C-b" 'ws-goto-block-begin) - (define-key map "c" 'end-of-buffer) - (define-key map "\C-c" 'end-of-buffer) - (define-key map "d" 'end-of-line) - (define-key map "\C-d" 'end-of-line) - (define-key map "f" 'ws-search) - (define-key map "\C-f" 'ws-search) - (define-key map "k" 'ws-goto-block-end) - (define-key map "\C-k" 'ws-goto-block-end) - (define-key map "l" 'ws-undo) - (define-key map "\C-l" 'ws-undo) - (define-key map "p" 'ws-last-cursorp) - (define-key map "\C-p" 'ws-last-cursorp) - (define-key map "r" 'beginning-of-buffer) - (define-key map "\C-r" 'beginning-of-buffer) - (define-key map "s" 'beginning-of-line) - (define-key map "\C-s" 'beginning-of-line) - (define-key map "\C-u" 'keyboard-quit) - (define-key map "w" 'ws-last-error) - (define-key map "\C-w" 'ws-last-error) - (define-key map "y" 'ws-kill-eol) - (define-key map "\C-y" 'ws-kill-eol) - (define-key map "\177" 'ws-kill-bol) + (define-key map "0" #'ws-find-marker-0) + (define-key map "1" #'ws-find-marker-1) + (define-key map "2" #'ws-find-marker-2) + (define-key map "3" #'ws-find-marker-3) + (define-key map "4" #'ws-find-marker-4) + (define-key map "5" #'ws-find-marker-5) + (define-key map "6" #'ws-find-marker-6) + (define-key map "7" #'ws-find-marker-7) + (define-key map "8" #'ws-find-marker-8) + (define-key map "9" #'ws-find-marker-9) + (define-key map "a" #'ws-query-replace) + (define-key map "\C-a" #'ws-query-replace) + (define-key map "b" #'ws-goto-block-begin) + (define-key map "\C-b" #'ws-goto-block-begin) + (define-key map "c" #'end-of-buffer) + (define-key map "\C-c" #'end-of-buffer) + (define-key map "d" #'end-of-line) + (define-key map "\C-d" #'end-of-line) + (define-key map "f" #'ws-search) + (define-key map "\C-f" #'ws-search) + (define-key map "k" #'ws-goto-block-end) + (define-key map "\C-k" #'ws-goto-block-end) + (define-key map "l" #'ws-undo) + (define-key map "\C-l" #'ws-undo) + ;; (define-key map "p" #'ws-last-cursorp) + ;; (define-key map "\C-p" #'ws-last-cursorp) + (define-key map "r" #'beginning-of-buffer) + (define-key map "\C-r" #'beginning-of-buffer) + (define-key map "s" #'beginning-of-line) + (define-key map "\C-s" #'beginning-of-line) + (define-key map "\C-u" #'keyboard-quit) + (define-key map "w" #'ws-last-error) + (define-key map "\C-w" #'ws-last-error) + (define-key map "y" #'ws-kill-eol) + (define-key map "\C-y" #'ws-kill-eol) + (define-key map "\177" #'ws-kill-bol) map)) (defvar wordstar-mode-map (let ((map (make-keymap))) - (define-key map "\C-a" 'backward-word) - (define-key map "\C-b" 'fill-paragraph) - (define-key map "\C-c" 'scroll-up-command) - (define-key map "\C-d" 'forward-char) - (define-key map "\C-e" 'previous-line) - (define-key map "\C-f" 'forward-word) - (define-key map "\C-g" 'delete-char) - (define-key map "\C-h" 'backward-char) - (define-key map "\C-i" 'indent-for-tab-command) - (define-key map "\C-j" 'help-for-help) + (define-key map "\C-a" #'backward-word) + (define-key map "\C-b" #'fill-paragraph) + (define-key map "\C-c" #'scroll-up-command) + (define-key map "\C-d" #'forward-char) + (define-key map "\C-e" #'previous-line) + (define-key map "\C-f" #'forward-word) + (define-key map "\C-g" #'delete-char) + (define-key map "\C-h" #'backward-char) + (define-key map "\C-i" #'indent-for-tab-command) + (define-key map "\C-j" #'help-for-help) (define-key map "\C-k" wordstar-C-k-map) - (define-key map "\C-l" 'ws-repeat-search) - (define-key map "\C-n" 'open-line) + (define-key map "\C-l" #'ws-repeat-search) + (define-key map "\C-n" #'open-line) (define-key map "\C-o" wordstar-C-o-map) - (define-key map "\C-p" 'quoted-insert) + (define-key map "\C-p" #'quoted-insert) (define-key map "\C-q" wordstar-C-q-map) - (define-key map "\C-r" 'scroll-down-command) - (define-key map "\C-s" 'backward-char) - (define-key map "\C-t" 'kill-word) - (define-key map "\C-u" 'keyboard-quit) - (define-key map "\C-v" 'overwrite-mode) - (define-key map "\C-w" 'scroll-down-line) - (define-key map "\C-x" 'next-line) - (define-key map "\C-y" 'kill-complete-line) - (define-key map "\C-z" 'scroll-up-line) + (define-key map "\C-r" #'scroll-down-command) + (define-key map "\C-s" #'backward-char) + (define-key map "\C-t" #'kill-word) + (define-key map "\C-u" #'keyboard-quit) + (define-key map "\C-v" #'overwrite-mode) + (define-key map "\C-w" #'scroll-down-line) + (define-key map "\C-x" #'next-line) + (define-key map "\C-y" #'kill-complete-line) + (define-key map "\C-z" #'scroll-up-line) map)) ;; wordstar-C-j-map not yet implemented diff --git a/lisp/obsolete/yow.el b/lisp/obsolete/yow.el index 76485f989c..ca8de4f922 100644 --- a/lisp/obsolete/yow.el +++ b/lisp/obsolete/yow.el @@ -1,4 +1,4 @@ -;;; yow.el --- quote random zippyisms +;;; yow.el --- quote random zippyisms -*- lexical-binding: t; -*- ;; Copyright (C) 1993-1995, 2000-2021 Free Software Foundation, Inc. @@ -39,8 +39,7 @@ (defcustom yow-file (expand-file-name "yow.lines" data-directory) "File containing pertinent pinhead phrases." - :type 'file - :group 'yow) + :type 'file) (defconst yow-load-message "Am I CONSING yet?...") (defconst yow-after-load-message "I have SEEN the CONSING!!") commit 59698d924e541b1768a61caafd0dfa40b5ed4b34 Author: Lars Ingebrigtsen Date: Mon Feb 22 22:39:27 2021 +0100 Mention the problems with newlines in Dired * doc/emacs/dired.texi (Dired Enter): Mention newlines and what to do about them. * lisp/dired.el (dired-listing-switches): Mention newlines (bug#46705). diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi index 34d12acc34..f57606dc79 100644 --- a/doc/emacs/dired.texi +++ b/doc/emacs/dired.texi @@ -129,6 +129,12 @@ options (that is, single characters) requiring no arguments, and long options (starting with @samp{--}) whose arguments are specified with @samp{=}. + Dired does not handle files that have names with embedded newline +characters well. If you have many such files, you may consider adding +@samp{-b} to @code{dired-listing-switches}. This will quote all +special characters and allow Dired to handle them better. (You can +also use the @kbd{C-u C-x d} command to add @samp{-b} temporarily.) + @vindex dired-switches-in-mode-line Dired displays in the mode line an indication of what were the switches used to invoke @command{ls}. By default, Dired will try to diff --git a/lisp/dired.el b/lisp/dired.el index 553fb64da0..4f1c3ded09 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -60,10 +60,15 @@ May contain all other options that don't contradict `-l'; may contain even `F', `b', `i' and `s'. See also the variable `dired-ls-F-marks-symlinks' concerning the `F' switch. + +If you have files with names with embedded newline characters, adding +`b' to the switches will allow Dired to handle those files better. + Options that include embedded whitespace must be quoted like this: \"--option=value with spaces\"; you can use `combine-and-quote-strings' to produce the correct quoting of each option. + On systems such as MS-DOS and MS-Windows, which use `ls' emulation in Lisp, some of the `ls' switches are not supported; see the doc string of `insert-directory' in `ls-lisp.el' for more details." commit 77e194971c5370856a63cf02397d79f85d6b342b Author: Lars Ingebrigtsen Date: Mon Feb 22 22:34:03 2021 +0100 Buttonize function values in help (and add a blank line) * lisp/help-fns.el (describe-variable): Add a newline for better readability (bug#46702). This also has the side effect of buttonizing `function-references-like-this' in the "Its value is" part. * lisp/help-mode.el (help-make-xrefs): Adjust comments. diff --git a/lisp/help-fns.el b/lisp/help-fns.el index ceb6bc0901..7244695094 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -1026,7 +1026,7 @@ it is displayed along with the global value." (princ (if file-name (progn (princ (format-message - " is a variable defined in `%s'.\n" + " is a variable defined in `%s'.\n\n" (if (eq file-name 'C-source) "C source code" (help-fns-short-filename file-name)))) diff --git a/lisp/help-mode.el b/lisp/help-mode.el index 30a1ce053c..6fd3d40fe3 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -476,8 +476,7 @@ that." (with-current-buffer (or buffer (current-buffer)) (save-excursion (goto-char (point-min)) - ;; Skip the header-type info, though it might be useful to parse - ;; it at some stage (e.g. "function in `library'"). + ;; Skip the first bit, which has already been buttonized. (forward-paragraph) (let ((old-modified (buffer-modified-p))) (let ((stab (syntax-table)) commit abd8c9b4d71651b00552d3d5dea119f22adf3874 Author: Basil L. Contovounesios Date: Mon Feb 22 20:31:06 2021 +0000 ; Fix last change in test-custom-libs.el. diff --git a/test/misc/test-custom-libs.el b/test/misc/test-custom-libs.el index aa8eeb7858..cc2be99dea 100644 --- a/test/misc/test-custom-libs.el +++ b/test/misc/test-custom-libs.el @@ -36,10 +36,10 @@ ;; - lisp/term/ns-win.el ;; - lisp/org/org-num.el (ert-deftest test-custom-libs () - ;; This test is very slow, and IMO not worth the time it takes. - (skip-unless (not (getenv "EMACS_HYDRA_CI"))) :tags '(:expensive-test) :expected-result :failed ; FIXME: See above. + ;; This test is very slow, and IMO not worth the time it takes. + (skip-unless (not (getenv "EMACS_HYDRA_CI"))) (skip-unless (file-readable-p custom-test-admin-cus-test)) (load custom-test-admin-cus-test) (cus-test-libs t) commit 69caa111c290eb1f02013c407f4ac2549b172c36 Author: Stefan Monnier Date: Mon Feb 22 12:22:19 2021 -0500 * lisp/progmodes/antlr-mode.el: Remove XEmacs compatibility (cond-emacs-xemacs, cond-emacs-xemacs-macfn, defunx, ignore-errors-x): Remove those functions and macros. Replace every use with the result of their use. (antlr-default-directory): Remove function, use the `default-directory` variable instead. (antlr-read-shell-command): Remove function, use `read-shell-command` instead. (antlr-with-displaying-help-buffer): Remove function, by inlining it at its only call site. (antlr-end-of-rule, antlr-beginning-of-rule, antlr-end-of-body) (antlr-beginning-of-body): Mark them as movement commands. diff --git a/lisp/progmodes/antlr-mode.el b/lisp/progmodes/antlr-mode.el index 56eeeeef37..3ae017b2a0 100644 --- a/lisp/progmodes/antlr-mode.el +++ b/lisp/progmodes/antlr-mode.el @@ -87,80 +87,6 @@ (require 'easymenu) (require 'cc-mode) -;; Just to get the rid of the byte compiler warning. The code for -;; this function and its friends are too complex for their own good. -(declare-function cond-emacs-xemacs-macfn "antlr-mode" (args &optional msg)) - -;; General Emacs/XEmacs-compatibility compile-time macros -(eval-when-compile - (defmacro cond-emacs-xemacs (&rest args) - (cond-emacs-xemacs-macfn - args "`cond-emacs-xemacs' must return exactly one element")) - (defun cond-emacs-xemacs-macfn (args &optional msg) - (if (atom args) args - (and (eq (car args) :@) (null msg) ; (:@ ...spliced...) - (setq args (cdr args) - msg "(:@ ....) must return exactly one element")) - (let ((ignore (if (featurep 'xemacs) :EMACS :XEMACS)) - (mode :BOTH) code) - (while (consp args) - (if (memq (car args) '(:EMACS :XEMACS :BOTH)) (setq mode (pop args))) - (if (atom args) - (or args (error "Used selector %s without elements" mode)) - (or (eq ignore mode) - (push (cond-emacs-xemacs-macfn (car args)) code)) - (pop args))) - (cond (msg (if (or args (cdr code)) (error msg) (car code))) - ((or (null args) (eq ignore mode)) (nreverse code)) - (t (nconc (nreverse code) args)))))) - ;; Emacs/XEmacs-compatibility `defun': remove interactive "_" for Emacs, use - ;; existing functions when they are `fboundp', provide shortcuts if they are - ;; known to be defined in a specific Emacs branch (for short .elc) - (defmacro defunx (name arglist &rest definition) - (let ((xemacsp (featurep 'xemacs)) reuses) - (while (memq (car definition) - '(:try :emacs-and-try :xemacs-and-try)) - (if (eq (pop definition) (if xemacsp :xemacs-and-try :emacs-and-try)) - (setq reuses (car definition) - definition nil) - (push (pop definition) reuses))) - (if (and reuses (symbolp reuses)) - `(defalias ',name ',reuses) - (let* ((docstring (if (stringp (car definition)) (pop definition))) - (spec (and (not xemacsp) - (eq (car-safe (car definition)) 'interactive) - (null (cddar definition)) - (cadar definition)))) - (if (and (stringp spec) - (not (string-equal spec "")) - (eq (aref spec 0) ?_)) - (setq definition - (cons (if (string-equal spec "_") - '(interactive) - `(interactive ,(substring spec 1))) - (cdr definition)))) - (if (null reuses) - `(defun ,name ,arglist ,docstring - ,@(cond-emacs-xemacs-macfn definition)) - ;; no dynamic docstring in this case - `(eval-and-compile ; no warnings in Emacs - (defalias ',name - (cond ,@(mapcar (lambda (func) `((fboundp ',func) ',func)) - (nreverse reuses)) - (t ,(if definition - `(lambda ,arglist ,docstring - ,@(cond-emacs-xemacs-macfn definition)) - 'ignore)))))))))) - (defmacro ignore-errors-x (&rest body) - (let ((specials '((scan-sexps . 4) (scan-lists . 5))) - spec nils) - (if (and (featurep 'xemacs) - (null (cdr body)) (consp (car body)) - (setq spec (assq (caar body) specials)) - (>= (setq nils (- (cdr spec) (length (car body)))) 0)) - `(,@(car body) ,@(make-list nils nil) t) - `(ignore-errors ,@body))))) - ;; More compile-time-macros (eval-when-compile (defmacro save-buffer-state-x (&rest body) ; similar to EMACS/lazy-lock.el @@ -693,9 +619,7 @@ imenu." (easy-menu-define antlr-mode-menu antlr-mode-map "Major mode menu." `("Antlr" - ,@(if (cond-emacs-xemacs - :EMACS antlr-options-use-submenus - :XEMACS antlr-options-use-submenus) + ,@(if antlr-options-use-submenus `(("Insert File Option" :filter ,(lambda (x) (antlr-options-menu-filter 1 x))) ("Insert Grammar Option" @@ -800,31 +724,27 @@ in the grammar's actions and semantic predicates, see Do not change.") (defface antlr-keyword - (cond-emacs-xemacs - '((((class color) (background light)) - (:foreground "black" :EMACS :weight bold :XEMACS :bold t)) - (t :inherit font-lock-keyword-face))) + '((((class color) (background light)) + (:foreground "black" :weight bold)) + (t :inherit font-lock-keyword-face)) "ANTLR keywords.") (defface antlr-syntax - (cond-emacs-xemacs - '((((class color) (background light)) - (:foreground "black" :EMACS :weight bold :XEMACS :bold t)) - (t :inherit font-lock-constant-face))) + '((((class color) (background light)) + (:foreground "black" :weight bold)) + (t :inherit font-lock-constant-face)) "ANTLR syntax symbols like :, |, (, ), ....") (defface antlr-ruledef - (cond-emacs-xemacs - '((((class color) (background light)) - (:foreground "blue" :EMACS :weight bold :XEMACS :bold t)) - (t :inherit font-lock-function-name-face))) + '((((class color) (background light)) + (:foreground "blue" :weight bold)) + (t :inherit font-lock-function-name-face)) "ANTLR rule references (definition).") (defface antlr-tokendef - (cond-emacs-xemacs - '((((class color) (background light)) - (:foreground "blue" :EMACS :weight bold :XEMACS :bold t)) - (t :inherit font-lock-function-name-face))) + '((((class color) (background light)) + (:foreground "blue" :weight bold)) + (t :inherit font-lock-function-name-face)) "ANTLR token references (definition).") (defface antlr-ruleref @@ -838,10 +758,9 @@ Do not change.") "ANTLR token references (usage).") (defface antlr-literal - (cond-emacs-xemacs - '((((class color) (background light)) - (:foreground "brown4" :EMACS :weight bold :XEMACS :bold t)) - (t :inherit font-lock-string-face))) + '((((class color) (background light)) + (:foreground "brown4" :weight bold)) + (t :inherit font-lock-string-face)) "ANTLR special literal tokens. It is used to highlight strings matched by the first regexp group of `antlr-font-lock-literal-regexp'.") @@ -859,50 +778,48 @@ group. The string matched by the first group is highlighted with "Regexp matching class headers.") (defvar antlr-font-lock-additional-keywords - (cond-emacs-xemacs - `((antlr-invalidate-context-cache) - ("\\$setType[ \t]*(\\([A-Za-z\300-\326\330-\337]\\sw*\\))" - (1 'antlr-tokendef)) - ("\\$\\sw+" (0 'antlr-keyword)) - ;; the tokens are already fontified as string/docstrings: - (,(lambda (limit) - (if antlr-font-lock-literal-regexp - (antlr-re-search-forward antlr-font-lock-literal-regexp limit))) - (1 'antlr-literal t) - :XEMACS (0 nil)) ; XEmacs bug workaround - (,(lambda (limit) - (antlr-re-search-forward antlr-class-header-regexp limit)) - (1 'antlr-keyword) - (2 'antlr-ruledef) - (3 'antlr-keyword) - (4 (if (member (match-string 4) '("Lexer" "Parser" "TreeParser")) - 'antlr-keyword - 'font-lock-type-face))) - (,(lambda (limit) - (antlr-re-search-forward - "\\<\\(header\\|options\\|tokens\\|exception\\|catch\\|returns\\)\\>" - limit)) + `((antlr-invalidate-context-cache) + ("\\$setType[ \t]*(\\([A-Za-z\300-\326\330-\337]\\sw*\\))" + (1 'antlr-tokendef)) + ("\\$\\sw+" (0 'antlr-keyword)) + ;; the tokens are already fontified as string/docstrings: + (,(lambda (limit) + (if antlr-font-lock-literal-regexp + (antlr-re-search-forward antlr-font-lock-literal-regexp limit))) + (1 'antlr-literal t)) + (,(lambda (limit) + (antlr-re-search-forward antlr-class-header-regexp limit)) + (1 'antlr-keyword) + (2 'antlr-ruledef) + (3 'antlr-keyword) + (4 (if (member (match-string 4) '("Lexer" "Parser" "TreeParser")) + 'antlr-keyword + 'font-lock-type-face))) + (,(lambda (limit) + (antlr-re-search-forward + "\\<\\(header\\|options\\|tokens\\|exception\\|catch\\|returns\\)\\>" + limit)) (1 'antlr-keyword)) - (,(lambda (limit) - (antlr-re-search-forward - "^\\(private\\|public\\|protected\\)\\>[ \t]*\\(\\(\\sw+[ \t]*\\(:\\)?\\)\\)?" - limit)) - (1 'font-lock-type-face) ; not XEmacs's java level-3 fruit salad + (,(lambda (limit) + (antlr-re-search-forward + "^\\(private\\|public\\|protected\\)\\>[ \t]*\\(\\(\\sw+[ \t]*\\(:\\)?\\)\\)?" + limit)) + (1 'font-lock-type-face) ; not XEmacs's java level-3 fruit salad (3 (if (antlr-upcase-p (char-after (match-beginning 3))) 'antlr-tokendef 'antlr-ruledef) nil t) (4 'antlr-syntax nil t)) - (,(lambda (limit) - (antlr-re-search-forward "^\\(\\sw+\\)[ \t]*\\(:\\)?" limit)) + (,(lambda (limit) + (antlr-re-search-forward "^\\(\\sw+\\)[ \t]*\\(:\\)?" limit)) (1 (if (antlr-upcase-p (char-after (match-beginning 0))) 'antlr-tokendef 'antlr-ruledef) nil t) (2 'antlr-syntax nil t)) - (,(lambda (limit) - ;; v:ruleref and v:"literal" is allowed... - (antlr-re-search-forward "\\(\\sw+\\)[ \t]*\\([=:]\\)?" limit)) + (,(lambda (limit) + ;; v:ruleref and v:"literal" is allowed... + (antlr-re-search-forward "\\(\\sw+\\)[ \t]*\\([=:]\\)?" limit)) (1 (if (match-beginning 2) (if (eq (char-after (match-beginning 2)) ?=) 'antlr-default @@ -911,9 +828,9 @@ group. The string matched by the first group is highlighted with 'antlr-tokenref 'antlr-ruleref))) (2 'antlr-default nil t)) - (,(lambda (limit) - (antlr-re-search-forward "[|&:;(~]\\|)\\([*+?]\\|=>\\)?" limit)) - (0 'antlr-syntax)))) + (,(lambda (limit) + (antlr-re-search-forward "[|&:;(~]\\|)\\([*+?]\\|=>\\)?" limit)) + (0 'antlr-syntax))) "Font-lock keywords for ANTLR's normal grammar code. See `antlr-font-lock-keywords-alist' for the keywords of actions.") @@ -979,26 +896,6 @@ Used for `antlr-slow-syntactic-context'.") ;;; Syntax functions -- Emacs vs XEmacs dependent, part 1 ;;;=========================================================================== -;; From help.el (XEmacs-21.1), without `copy-syntax-table' -(defunx antlr-default-directory () - :xemacs-and-try default-directory - "Return `default-directory'." - default-directory) - -;; Check Emacs-21.1 simple.el, `shell-command'. -(defunx antlr-read-shell-command (prompt &optional initial-input history) - :xemacs-and-try read-shell-command - "Read a string from the minibuffer, using `shell-command-history'." - (read-from-minibuffer prompt initial-input nil nil - (or history 'shell-command-history))) - -(defunx antlr-with-displaying-help-buffer (thunk &optional _name) - :xemacs-and-try with-displaying-help-buffer - "Make a help buffer and call `thunk' there." - (with-output-to-temp-buffer "*Help*" - (save-excursion (funcall thunk)))) - - ;;;=========================================================================== ;;; Context cache ;;;=========================================================================== @@ -1011,26 +908,18 @@ Used for `antlr-slow-syntactic-context'.") ;;;(defvar antlr-statistics-cache 0) ;;;(defvar antlr-statistics-inval 0) -(defunx antlr-invalidate-context-cache (&rest _dummies) +(defun antlr-invalidate-context-cache (&rest _dummies) ;; checkdoc-params: (dummies) "Invalidate context cache for syntactical context information." - :XEMACS ; XEmacs bug workaround - (with-current-buffer (get-buffer-create " ANTLR XEmacs bug workaround") - (buffer-syntactic-context-depth) - nil) - :EMACS ;;; (cl-incf antlr-statistics-inval) (setq antlr-slow-context-cache nil)) -(defunx antlr-syntactic-context () +(defun antlr-syntactic-context () "Return some syntactic context information. Return `string' if point is within a string, `block-comment' or `comment' is point is within a comment or the depth within all parenthesis-syntax delimiters at point otherwise. WARNING: this may alter `match-data'." - :XEMACS - (or (buffer-syntactic-context) (buffer-syntactic-context-depth)) - :EMACS (let ((orig (point)) diff state ;; Arg, Emacs's (buffer-modified-tick) changes with font-lock. Use ;; hack that `loudly' is bound during font-locking => cache use will @@ -1049,9 +938,9 @@ WARNING: this may alter `match-data'." (if (>= orig antlr-slow-cache-diff-threshold) (beginning-of-defun) (goto-char (point-min))) -;;; (cond ((and diff (< diff 0)) (cl-incf antlr-statistics-full-neg)) -;;; ((and diff (>= diff 3000)) (cl-incf antlr-statistics-full-diff)) -;;; (t (cl-incf antlr-statistics-full-other))) + ;; (cond ((and diff (< diff 0)) (cl-incf antlr-statistics-full-neg)) + ;; ((and diff (>= diff 3000)) (cl-incf antlr-statistics-full-diff)) + ;; (t (cl-incf antlr-statistics-full-other))) (setq state (parse-partial-sexp (point) orig))) (goto-char orig) (if antlr-slow-context-cache @@ -1063,52 +952,52 @@ WARNING: this may alter `match-data'." ((nth 4 state) 'comment) ; block-comment? -- we don't care (t (car state))))) -;;; (cl-incf (aref antlr-statistics 2)) -;;; (unless (and (eq (current-buffer) -;;; (caar antlr-slow-context-cache)) -;;; (eq (buffer-modified-tick) -;;; (cdar antlr-slow-context-cache))) -;;; (cl-incf (aref antlr-statistics 1)) -;;; (setq antlr-slow-context-cache nil)) -;;; (let* ((orig (point)) -;;; (base (cadr antlr-slow-context-cache)) -;;; (curr (cddr antlr-slow-context-cache)) -;;; (state (cond ((eq orig (car curr)) (cdr curr)) -;;; ((eq orig (car base)) (cdr base)))) -;;; diff diff2) -;;; (unless state -;;; (cl-incf (aref antlr-statistics 3)) -;;; (when curr -;;; (if (< (setq diff (abs (- orig (car curr)))) -;;; (setq diff2 (abs (- orig (car base))))) -;;; (setq state curr) -;;; (setq state base -;;; diff diff2)) -;;; (if (or (>= (1+ diff) (point)) (>= diff 3000)) -;;; (setq state nil))) ; start from bod/bob -;;; (if state -;;; (setq state -;;; (parse-partial-sexp (car state) orig nil nil (cdr state))) -;;; (if (>= orig 3000) (beginning-of-defun) (goto-char (point-min))) -;;; (cl-incf (aref antlr-statistics 4)) -;;; (setq cw (list orig (point) base curr)) -;;; (setq state (parse-partial-sexp (point) orig))) -;;; (goto-char orig) -;;; (if antlr-slow-context-cache -;;; (setcdr (cdr antlr-slow-context-cache) (cons orig state)) -;;; (setq antlr-slow-context-cache -;;; (cons (cons (current-buffer) (buffer-modified-tick)) -;;; (cons (cons orig state) (cons orig state)))))) -;;; (cond ((nth 3 state) 'string) -;;; ((nth 4 state) 'comment) ; block-comment? -- we don't care -;;; (t (car state))))) - -;;; (beginning-of-defun) -;;; (let ((state (parse-partial-sexp (point) orig))) -;;; (goto-char orig) -;;; (cond ((nth 3 state) 'string) -;;; ((nth 4 state) 'comment) ; block-comment? -- we don't care -;;; (t (car state)))))) +;; (cl-incf (aref antlr-statistics 2)) +;; (unless (and (eq (current-buffer) +;; (caar antlr-slow-context-cache)) +;; (eq (buffer-modified-tick) +;; (cdar antlr-slow-context-cache))) +;; (cl-incf (aref antlr-statistics 1)) +;; (setq antlr-slow-context-cache nil)) +;; (let* ((orig (point)) +;; (base (cadr antlr-slow-context-cache)) +;; (curr (cddr antlr-slow-context-cache)) +;; (state (cond ((eq orig (car curr)) (cdr curr)) +;; ((eq orig (car base)) (cdr base)))) +;; diff diff2) +;; (unless state +;; (cl-incf (aref antlr-statistics 3)) +;; (when curr +;; (if (< (setq diff (abs (- orig (car curr)))) +;; (setq diff2 (abs (- orig (car base))))) +;; (setq state curr) +;; (setq state base +;; diff diff2)) +;; (if (or (>= (1+ diff) (point)) (>= diff 3000)) +;; (setq state nil))) ; start from bod/bob +;; (if state +;; (setq state +;; (parse-partial-sexp (car state) orig nil nil (cdr state))) +;; (if (>= orig 3000) (beginning-of-defun) (goto-char (point-min))) +;; (cl-incf (aref antlr-statistics 4)) +;; (setq cw (list orig (point) base curr)) +;; (setq state (parse-partial-sexp (point) orig))) +;; (goto-char orig) +;; (if antlr-slow-context-cache +;; (setcdr (cdr antlr-slow-context-cache) (cons orig state)) +;; (setq antlr-slow-context-cache +;; (cons (cons (current-buffer) (buffer-modified-tick)) +;; (cons (cons orig state) (cons orig state)))))) +;; (cond ((nth 3 state) 'string) +;; ((nth 4 state) 'comment) ; block-comment? -- we don't care +;; (t (car state))))) + +;; (beginning-of-defun) +;; (let ((state (parse-partial-sexp (point) orig))) +;; (goto-char orig) +;; (cond ((nth 3 state) 'string) +;; ((nth 4 state) 'comment) ; block-comment? -- we don't care +;; (t (car state)))))) ;;;=========================================================================== @@ -1162,7 +1051,7 @@ strings and actions/semantic predicates." (defsubst antlr-skip-sexps (count) "Skip the next COUNT balanced expressions and the comments after it. Return position before the comments after the last expression." - (goto-char (or (ignore-errors-x (scan-sexps (point) count)) (point-max))) + (goto-char (or (ignore-errors (scan-sexps (point) count)) (point-max))) (prog1 (point) (antlr-c-forward-sws))) @@ -1351,33 +1240,33 @@ rule." (with-syntax-table antlr-action-syntax-table (not (antlr-outside-rule-p))))) -(defunx antlr-end-of-rule (&optional arg) +(defun antlr-end-of-rule (&optional arg) "Move forward to next end of rule. Do it ARG [default: 1] many times. A grammar class header and the file prelude are also considered as a rule. Negative argument ARG means move back to ARGth preceding end of rule. If ARG is zero, run `antlr-end-of-body'." - (interactive "_p") + (interactive "^p") (if (zerop arg) (antlr-end-of-body) (with-syntax-table antlr-action-syntax-table (antlr-next-rule arg nil)))) -(defunx antlr-beginning-of-rule (&optional arg) +(defun antlr-beginning-of-rule (&optional arg) "Move backward to preceding beginning of rule. Do it ARG many times. A grammar class header and the file prelude are also considered as a rule. Negative argument ARG means move forward to ARGth next beginning of rule. If ARG is zero, run `antlr-beginning-of-body'." - (interactive "_p") + (interactive "^p") (if (zerop arg) (antlr-beginning-of-body) (with-syntax-table antlr-action-syntax-table (antlr-next-rule (- arg) t)))) -(defunx antlr-end-of-body (&optional msg) +(defun antlr-end-of-body (&optional msg) "Move to position after the `;' of the current rule. A grammar class header is also considered as a rule. With optional prefix arg MSG, move to `:'." - (interactive "_") + (interactive "^") (with-syntax-table antlr-action-syntax-table (let ((orig (point))) (if (antlr-outside-rule-p) @@ -1396,9 +1285,9 @@ prefix arg MSG, move to `:'." (error msg)) (antlr-c-forward-sws)))))) -(defunx antlr-beginning-of-body () +(defun antlr-beginning-of-body () "Move to the first element after the `:' of the current rule." - (interactive "_") + (interactive "^") (antlr-end-of-body "Class headers and the file prelude are without `:'")) @@ -1446,7 +1335,7 @@ Display a message unless optional argument SILENT is non-nil." (with-syntax-table antlr-action-syntax-table (antlr-invalidate-context-cache) (while (antlr-re-search-forward regexp nil) - (let ((beg (ignore-errors-x (scan-sexps (point) -1)))) + (let ((beg (ignore-errors (scan-sexps (point) -1)))) (when beg (if diff ; braces are visible (if (> (point) (+ beg diff)) @@ -1639,7 +1528,7 @@ like \(AREA . PLACE), see `antlr-option-location'." (cond ((null pos) 'error) ((looking-at "options[ \t\n]*{") (goto-char (match-end 0)) - (setq pos (ignore-errors-x (scan-lists (point) 1 1))) + (setq pos (ignore-errors (scan-lists (point) 1 1))) (antlr-option-location orig min0 max0 (point) (if pos (1- pos) (point-max)) @@ -2195,9 +2084,9 @@ Use prefix argument ARG to return \(COMMAND FILE SAVED)." (setq glibs (car (antlr-superclasses-glibs supers (car (antlr-directory-dependencies - (antlr-default-directory))))))) - (list (antlr-read-shell-command "Run Antlr on current file with: " - (concat antlr-tool-command glibs " ")) + default-directory)))))) + (list (read-shell-command "Run Antlr on current file with: " + (concat antlr-tool-command glibs " ")) buffer-file-name supers))) @@ -2219,7 +2108,7 @@ Also insert strings PRE and POST before and after the variable." "Insert Makefile rules in the current buffer at point. IN-MAKEFILE is non-nil, if the current buffer is the Makefile. See command `antlr-show-makefile-rules' for detail." - (let* ((dirname (antlr-default-directory)) + (let* ((dirname default-directory) (deps0 (antlr-directory-dependencies dirname)) (classes (car deps0)) ; CLASS -> (FILE . EVOCAB) ... (deps (cdr deps0)) ; FILE -> (c . s) (ev . iv) . LANGUAGE @@ -2298,7 +2187,9 @@ commentary with value `antlr-help-unknown-file-text' is added. The *Help* buffer always starts with the text in `antlr-help-rules-intro'." (interactive) (if (null (derived-mode-p 'makefile-mode)) - (antlr-with-displaying-help-buffer 'antlr-insert-makefile-rules) + (with-output-to-temp-buffer "*Help*" + (save-excursion + (antlr-insert-makefile-rules))) (push-mark) (antlr-insert-makefile-rules t))) commit 8933cf86a1c64fc3302188629356084bcbfc65dc Author: Juri Linkov Date: Mon Feb 22 19:12:43 2021 +0200 * lisp/tab-bar.el: 'C-x t N' bound to tab-new-to supports a negative argument * lisp/tab-bar.el (tab-bar-new-tab-to): Negative TO-INDEX counts tabs from the end of the tab bar. (tab-bar-new-tab): Fix docstring to add reference to 'tab-bar-new-tab-to'. (tab-prefix-map): Bind "N" to tab-new-to. diff --git a/etc/NEWS b/etc/NEWS index 983a75133f..2411ddb830 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -490,6 +490,10 @@ independently from the value of 'tab-bar-mode' and 'tab-bar-show'. *** 'Mod-9' bound to 'tab-last' now switches to the last tab. It also supports a negative argument. +--- +*** 'C-x t N' creates a new tab at the specified absolute position. +It also supports a negative argument. + --- *** 'C-x t M' moves the current tab to the specified absolute position. It also supports a negative argument. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index ddb716c15e..41844e6f5c 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -847,7 +847,9 @@ called." "Add a new tab at the absolute position TO-INDEX. TO-INDEX counts from 1. If no TO-INDEX is specified, then add a new tab at the position specified by `tab-bar-new-tab-to'. - +Negative TO-INDEX counts tabs from the end of the tab bar. +Argument addressing is absolute in contrast to `tab-bar-new-tab' +where argument addressing is relative. After the tab is created, the hooks in `tab-bar-tab-post-open-functions' are run." (interactive "P") @@ -874,15 +876,19 @@ After the tab is created, the hooks in (when from-index (setf (nth from-index tabs) from-tab)) - (let ((to-tab (tab-bar--current-tab)) - (to-index (or (if to-index (1- to-index)) - (pcase tab-bar-new-tab-to - ('leftmost 0) - ('rightmost (length tabs)) - ('left (or from-index 1)) - ('right (1+ (or from-index 0))) - ((pred functionp) - (funcall tab-bar-new-tab-to)))))) + (let* ((to-tab (tab-bar--current-tab)) + (to-index (and to-index (prefix-numeric-value to-index))) + (to-index (or (if to-index + (if (< to-index 0) + (+ (length tabs) (1+ to-index)) + (1- to-index))) + (pcase tab-bar-new-tab-to + ('leftmost 0) + ('rightmost (length tabs)) + ('left (or from-index 1)) + ('right (1+ (or from-index 0))) + ((pred functionp) + (funcall tab-bar-new-tab-to)))))) (setq to-index (max 0 (min (or to-index 0) (length tabs)))) (cl-pushnew to-tab (nthcdr to-index tabs)) @@ -907,7 +913,11 @@ After the tab is created, the hooks in (defun tab-bar-new-tab (&optional arg) "Create a new tab ARG positions to the right. If a negative ARG, create a new tab ARG positions to the left. -If ARG is zero, create a new tab in place of the current tab." +If ARG is zero, create a new tab in place of the current tab. +If no ARG is specified, then add a new tab at the position +specified by `tab-bar-new-tab-to'. +Argument addressing is relative in contrast to `tab-bar-new-tab-to' +where argument addressing is absolute." (interactive "P") (if arg (let* ((tabs (funcall tab-bar-tabs-function)) @@ -1689,6 +1699,7 @@ When `switch-to-buffer-obey-display-actions' is non-nil, nil "[other-tab]") (message "Display next command buffer in a new tab...")) +(define-key tab-prefix-map "N" 'tab-new-to) (define-key tab-prefix-map "2" 'tab-new) (define-key tab-prefix-map "1" 'tab-close-other) (define-key tab-prefix-map "0" 'tab-close) commit 6e90768143ff47e96a70d91534344161a1d85f46 Author: Juri Linkov Date: Mon Feb 22 19:08:16 2021 +0200 * lisp/tab-bar.el: 'C-x t M' bound to tab-move-to supports a negative argument * lisp/tab-bar.el (tab-bar-move-tab-to): Negative TO-INDEX counts tabs from the end of the tab bar. (tab-bar-move-tab): Fix docstring to add reference to tab-bar-move-tab-to. (tab-prefix-map): Bind "M" to tab-move-to. diff --git a/etc/NEWS b/etc/NEWS index ca0d71567d..983a75133f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -488,6 +488,11 @@ independently from the value of 'tab-bar-mode' and 'tab-bar-show'. --- *** 'Mod-9' bound to 'tab-last' now switches to the last tab. +It also supports a negative argument. + +--- +*** 'C-x t M' moves the current tab to the specified absolute position. +It also supports a negative argument. --- *** New user option 'tab-bar-tab-name-format-function'. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index db2376d9ef..ddb716c15e 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -759,12 +759,17 @@ most recent, and so on." (defun tab-bar-move-tab-to (to-index &optional from-index) "Move tab from FROM-INDEX position to new position at TO-INDEX. FROM-INDEX defaults to the current tab index. -FROM-INDEX and TO-INDEX count from 1." +FROM-INDEX and TO-INDEX count from 1. +Negative TO-INDEX counts tabs from the end of the tab bar. +Argument addressing is absolute in contrast to `tab-bar-move-tab' +where argument addressing is relative." (interactive "P") (let* ((tabs (funcall tab-bar-tabs-function)) (from-index (or from-index (1+ (tab-bar--current-tab-index tabs)))) (from-tab (nth (1- from-index) tabs)) - (to-index (max 0 (min (1- (or to-index 1)) (1- (length tabs)))))) + (to-index (if to-index (prefix-numeric-value to-index) 1)) + (to-index (if (< to-index 0) (+ (length tabs) (1+ to-index)) to-index)) + (to-index (max 0 (min (1- to-index) (1- (length tabs)))))) (setq tabs (delq from-tab tabs)) (cl-pushnew from-tab (nthcdr to-index tabs)) (set-frame-parameter nil 'tabs tabs) @@ -772,7 +777,9 @@ FROM-INDEX and TO-INDEX count from 1." (defun tab-bar-move-tab (&optional arg) "Move the current tab ARG positions to the right. -If a negative ARG, move the current tab ARG positions to the left." +If a negative ARG, move the current tab ARG positions to the left. +Argument addressing is relative in contrast to `tab-bar-move-tab-to' +where argument addressing is absolute." (interactive "p") (let* ((tabs (funcall tab-bar-tabs-function)) (from-index (or (tab-bar--current-tab-index tabs) 0)) @@ -1687,6 +1694,7 @@ When `switch-to-buffer-obey-display-actions' is non-nil, (define-key tab-prefix-map "0" 'tab-close) (define-key tab-prefix-map "o" 'tab-next) (define-key tab-prefix-map "m" 'tab-move) +(define-key tab-prefix-map "M" 'tab-move-to) (define-key tab-prefix-map "r" 'tab-rename) (define-key tab-prefix-map "\r" 'tab-bar-select-tab-by-name) (define-key tab-prefix-map "b" 'switch-to-buffer-other-tab) commit ffdb91c6b344b6b341e75ae981ebdb3e66b94130 Author: Juri Linkov Date: Mon Feb 22 19:03:42 2021 +0200 'Mod-9' bound to 'tab-last' now switches to the last tab like in web browsers * lisp/tab-bar.el (tab-bar--define-keys): Rebind 0 from tab-bar-switch-to-recent-tab to its alias tab-recent. Bind 9 to tab-last. (tab-bar-switch-to-last-tab): New command. (tab-last): New alias to tab-bar-switch-to-last-tab. (tab-bar-switch-to-tab, tab-bar-undo-close-tab): Fix docstrings to avoid mentioning the term "last" for "most recently used" meaning. diff --git a/etc/NEWS b/etc/NEWS index c4f4c1d9d8..ca0d71567d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -486,6 +486,9 @@ independently from the value of 'tab-bar-mode' and 'tab-bar-show'. --- *** New command 'tab-duplicate'. +--- +*** 'Mod-9' bound to 'tab-last' now switches to the last tab. + --- *** New user option 'tab-bar-tab-name-format-function'. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 8326104240..db2376d9ef 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -100,11 +100,13 @@ Possible modifier keys are `control', `meta', `shift', `hyper', `super' and "Install key bindings for switching between tabs if the user has configured them." (when tab-bar-select-tab-modifiers (global-set-key (vector (append tab-bar-select-tab-modifiers (list ?0))) - 'tab-bar-switch-to-recent-tab) - (dotimes (i 9) + 'tab-recent) + (dotimes (i 8) (global-set-key (vector (append tab-bar-select-tab-modifiers (list (+ i 1 ?0)))) - 'tab-bar-select-tab))) + 'tab-bar-select-tab)) + (global-set-key (vector (append tab-bar-select-tab-modifiers (list ?9))) + 'tab-last)) ;; Don't override user customized key bindings (unless (global-key-binding [(control tab)]) (global-set-key [(control tab)] 'tab-next)) @@ -720,6 +722,12 @@ ARG counts from 1." (setq arg 1)) (tab-bar-switch-to-next-tab (- arg))) +(defun tab-bar-switch-to-last-tab (&optional arg) + "Switch to the last tab or ARGth tab from the end of the tab bar." + (interactive "p") + (tab-bar-select-tab (- (length (funcall tab-bar-tabs-function)) + (1- (or arg 1))))) + (defun tab-bar-switch-to-recent-tab (&optional arg) "Switch to ARGth most recently visited tab." (interactive "p") @@ -734,7 +742,8 @@ ARG counts from 1." "Switch to the tab by NAME. Default values are tab names sorted by recency, so you can use \ \\\\[next-history-element] -to get the name of the last visited tab, the second last, and so on." +to get the name of the most recently visited tab, the second +most recent, and so on." (interactive (let* ((recent-tabs (mapcar (lambda (tab) (alist-get 'name tab)) @@ -1070,7 +1079,7 @@ for the last tab on a frame is determined by (message "Deleted all other tabs"))))) (defun tab-bar-undo-close-tab () - "Restore the last closed tab." + "Restore the most recently closed tab." (interactive) ;; Pop out closed tabs that were on already deleted frames (while (and tab-bar-closed-tabs @@ -1261,6 +1270,7 @@ and can restore them." (defalias 'tab-select 'tab-bar-select-tab) (defalias 'tab-next 'tab-bar-switch-to-next-tab) (defalias 'tab-previous 'tab-bar-switch-to-prev-tab) +(defalias 'tab-last 'tab-bar-switch-to-last-tab) (defalias 'tab-recent 'tab-bar-switch-to-recent-tab) (defalias 'tab-move 'tab-bar-move-tab) (defalias 'tab-move-to 'tab-bar-move-tab-to) commit 2601aa9105d935441ed25370feeeae3e717cc791 Author: Juri Linkov Date: Mon Feb 22 18:56:47 2021 +0200 * lisp/tab-bar.el (tab-bar--undefine-keys): New function from tab-bar-mode. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index dba79fbd81..8326104240 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -113,6 +113,15 @@ Possible modifier keys are `control', `meta', `shift', `hyper', `super' and (unless (global-key-binding [(control shift iso-lefttab)]) (global-set-key [(control shift iso-lefttab)] 'tab-previous))) +(defun tab-bar--undefine-keys () + "Uninstall key bindings previously bound by `tab-bar--define-keys'." + (when (eq (global-key-binding [(control tab)]) 'tab-next) + (global-unset-key [(control tab)])) + (when (eq (global-key-binding [(control shift tab)]) 'tab-previous) + (global-unset-key [(control shift tab)])) + (when (eq (global-key-binding [(control shift iso-lefttab)]) 'tab-previous) + (global-unset-key [(control shift iso-lefttab)]))) + (defun tab-bar--load-buttons () "Load the icons for the tab buttons." (when (and tab-bar-new-button @@ -181,13 +190,7 @@ update." (tab-bar--load-buttons)) (if tab-bar-mode (tab-bar--define-keys) - ;; Unset only keys bound by tab-bar - (when (eq (global-key-binding [(control tab)]) 'tab-next) - (global-unset-key [(control tab)])) - (when (eq (global-key-binding [(control shift tab)]) 'tab-previous) - (global-unset-key [(control shift tab)])) - (when (eq (global-key-binding [(control shift iso-lefttab)]) 'tab-previous) - (global-unset-key [(control shift iso-lefttab)])))) + (tab-bar--undefine-keys))) (defun tab-bar-handle-mouse (event) "Text-mode emulation of switching tabs on the tab bar. commit 8d5dfafab7dc40d4b74dc0b56d1b314fd8cac390 Author: Stefan Monnier Date: Mon Feb 22 11:54:17 2021 -0500 Prefer `declare` over a `put` of `list-indent-function`. While at it, I enabled lexical-binding in the affected files. * lisp/cedet/semantic/sb.el: Enable lexical-binding. (semantic-sb-with-tag-buffer): Use `declare`. * lisp/cedet/semantic/bovine/el.el: Enable lexical-binding. (semantic-elisp-setup-form-parser): Use `declare`. * lisp/emacs-lisp/ert.el: * lisp/emacs-lisp/ert-x.el: Remove redundant `put`. * lisp/emulation/cua-rect.el: Enable lexical-binding. (cua--rectangle-operation, cua--rectangle-aux-replace): Use `declare`. * lisp/mh-e/mh-acros.el: Enable lexical-binding. (mh-do-in-gnu-emacs, mh-do-in-xemacs, mh-funcall-if-exists, defun-mh) (defmacro-mh, with-mh-folder-updating, mh-in-show-buffer) (mh-do-at-event-location, mh-iterate-on-messages-in-region) (mh-iterate-on-range): Use `declare`. * lisp/mh-e/mh-compat.el: Enable lexical-binding. (mh-flet): Use `declare`. * lisp/mh-e/mh-e.el: Enable lexical-binding. (defgroup-mh, defcustom-mh, defface-mh): Use `declare`. * lisp/net/sieve.el: Enable lexical-binding. Remove redundant :group args. (sieve-activate, sieve-remove, sieve-edit-script): Remove unused arg from the interactive spec. (sieve-deactivate-all): Remove unused var `name`. (sieve-change-region): Use `declare`. * lisp/obsolete/fast-lock.el: Enable lexical-binding. Remove redundant :group args. Remove XEmacs compat code. (save-buffer-state): Remove macro. (fast-lock-add-properties): Use `with-silent-modifications` instead. * lisp/obsolete/lazy-lock.el: Enable lexical-binding. Remove redundant :group args. (do-while): Use `declare`. (save-buffer-state): Remove macro. (lazy-lock-fontify-rest-after-change, lazy-lock-defer-line-after-change) (lazy-lock-defer-rest-after-change, lazy-lock-after-fontify-buffer) (lazy-lock-after-unfontify-buffer, lazy-lock-fontify-region): Use `with-silent-modifications` instead. * lisp/obsolete/pgg.el: Enable lexical-binding. Remove XEmacs compat code. (pgg-save-coding-system, pgg-as-lbt, pgg-process-when-success): Use `declare`. (pgg-add-passphrase-to-cache): Remove unused var `new-timer`. (pgg-decrypt-region): Remove unused var `buf`. * lisp/org/org-agenda.el (org-let, org-let2): Move from org-macs and use `declare`. * lisp/org/org-macs.el (org-let, org-let2): Move these functions that are inherently harmful to your karma to the only package that uses them. (org-scroll): Use `pcase` to avoid `eval` and use more readable syntax for those integers standing for events. * lisp/progmodes/antlr-mode.el: Enable lexical-binding. (save-buffer-state-x): Use `declare` and `with-silent-modifications`. * lisp/international/mule-util.el (with-coding-priority): * lisp/cedet/ede/proj-comp.el (proj-comp-insert-variable-once): * lisp/org/org-element.el (org-element-map): * test/lisp/emacs-lisp/bytecomp-tests.el (test-byte-comp-compile-and-load): * test/lisp/emacs-lisp/generator-tests.el (cps-testcase): Use `declare`. diff --git a/lisp/cedet/ede/proj-comp.el b/lisp/cedet/ede/proj-comp.el index ba52784a7a..397354ad9c 100644 --- a/lisp/cedet/ede/proj-comp.el +++ b/lisp/cedet/ede/proj-comp.el @@ -248,6 +248,7 @@ This will prevent rules from creating duplicate variables or rules." (defmacro proj-comp-insert-variable-once (varname &rest body) "Add VARNAME into the current Makefile if it doesn't exist. Execute BODY in a location where a value can be placed." + (declare (indent 1) (debug (sexp body))) `(let ((addcr t) (v ,varname)) (unless (re-search-backward (concat "^" v "\\s-*=") nil t) (insert v "=") @@ -255,7 +256,6 @@ Execute BODY in a location where a value can be placed." (if addcr (insert "\n")) (goto-char (point-max))) )) -(put 'proj-comp-insert-variable-once 'lisp-indent-function 1) (cl-defmethod ede-proj-makefile-insert-variables ((this ede-compilation-program)) "Insert variables needed by the compiler THIS." diff --git a/lisp/cedet/semantic/bovine/el.el b/lisp/cedet/semantic/bovine/el.el index dc61734902..4d94d34323 100644 --- a/lisp/cedet/semantic/bovine/el.el +++ b/lisp/cedet/semantic/bovine/el.el @@ -1,4 +1,4 @@ -;;; semantic/bovine/el.el --- Semantic details for Emacs Lisp +;;; semantic/bovine/el.el --- Semantic details for Emacs Lisp -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2005, 2007-2021 Free Software Foundation, Inc. @@ -169,10 +169,10 @@ where: - FORM is an Elisp form read from the current buffer. - START and END are the beginning and end location of the corresponding data in the current buffer." + (declare (indent 1)) (let ((sym (make-symbol "sym"))) `(dolist (,sym ',symbols) (put ,sym 'semantic-elisp-form-parser #',parser)))) -(put 'semantic-elisp-setup-form-parser 'lisp-indent-function 1) (defmacro semantic-elisp-reuse-form-parser (symbol &rest symbols) "Reuse the form parser of SYMBOL for forms identified by SYMBOLS. @@ -210,7 +210,7 @@ Return a bovination list to use." ;;; Form parsers ;; (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (semantic-tag-new-function (symbol-name (nth 2 form)) nil @@ -234,7 +234,7 @@ Return a bovination list to use." ) (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (semantic-tag-new-function (symbol-name (nth 1 form)) nil @@ -256,7 +256,7 @@ Return a bovination list to use." ) (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (let ((doc (semantic-elisp-form-to-doc-string (nth 3 form)))) (semantic-tag-new-variable (symbol-name (nth 1 form)) @@ -274,7 +274,7 @@ Return a bovination list to use." ) (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (let ((doc (semantic-elisp-form-to-doc-string (nth 3 form)))) (semantic-tag-new-variable (symbol-name (nth 1 form)) @@ -290,7 +290,7 @@ Return a bovination list to use." (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (let ((doc (semantic-elisp-form-to-doc-string (nth 3 form)))) (semantic-tag-new-variable (symbol-name (nth 1 form)) @@ -307,7 +307,7 @@ Return a bovination list to use." (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (let ((doc (semantic-elisp-form-to-doc-string (nth 3 form)))) (semantic-tag (symbol-name (nth 1 form)) @@ -321,7 +321,7 @@ Return a bovination list to use." (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (semantic-tag-new-function (symbol-name (cadr (cadr form))) nil nil @@ -333,7 +333,7 @@ Return a bovination list to use." ) (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (let* ((a2 (nth 2 form)) (a3 (nth 3 form)) (args (if (listp a2) a2 a3)) @@ -353,7 +353,7 @@ Return a bovination list to use." ) (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (semantic-tag-new-function (symbol-name (nth 1 form)) nil @@ -363,7 +363,7 @@ Return a bovination list to use." ) (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (let ((docpart (nthcdr 4 form))) (semantic-tag-new-type (symbol-name (nth 1 form)) @@ -381,7 +381,7 @@ Return a bovination list to use." ) (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (let ((slots (nthcdr 2 form))) ;; Skip doc string if present. (and (stringp (car slots)) @@ -399,7 +399,7 @@ Return a bovination list to use." ) (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (semantic-tag-new-function (symbol-name (nth 1 form)) nil nil @@ -410,7 +410,7 @@ Return a bovination list to use." ) (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (let ((args (nth 3 form))) (semantic-tag-new-function (symbol-name (nth 1 form)) @@ -424,7 +424,7 @@ Return a bovination list to use." ) (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (semantic-tag-new-variable (symbol-name (nth 2 form)) nil @@ -437,7 +437,7 @@ Return a bovination list to use." ) (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (let ((name (nth 1 form))) (semantic-tag-new-include (symbol-name (if (eq (car-safe name) 'quote) @@ -449,7 +449,7 @@ Return a bovination list to use." ) (semantic-elisp-setup-form-parser - (lambda (form start end) + (lambda (form _start _end) (let ((name (nth 1 form))) (semantic-tag-new-package (symbol-name (if (eq (car-safe name) 'quote) @@ -500,7 +500,7 @@ into Emacs Lisp's memory." "")))) (define-mode-local-override semantic-documentation-for-tag - emacs-lisp-mode (tag &optional nosnarf) + emacs-lisp-mode (tag &optional _nosnarf) "Return the documentation string for TAG. Optional argument NOSNARF is ignored." (let ((d (semantic-tag-docstring tag))) @@ -577,7 +577,7 @@ Override function for `semantic-tag-protection'." ((string= prot "protected") 'protected)))) (define-mode-local-override semantic-tag-static-p - emacs-lisp-mode (tag &optional parent) + emacs-lisp-mode (tag &optional _parent) "Return non-nil if TAG is static in PARENT class. Overrides `semantic-nonterminal-static'." ;; This can only be true (theoretically) in a class where it is assigned. @@ -588,7 +588,7 @@ Overrides `semantic-nonterminal-static'." ;; Emacs lisp is very different from C,C++ which most context parsing ;; functions are written. Support them here. (define-mode-local-override semantic-up-context emacs-lisp-mode - (&optional point bounds-type) + (&optional _point _bounds-type) "Move up one context in an Emacs Lisp function. A Context in many languages is a block with its own local variables. In Emacs, we will move up lists and stop when one starts with one of @@ -652,7 +652,7 @@ define-mode-overload\\)\ (define-mode-local-override semantic-get-local-variables emacs-lisp-mode - (&optional point) + (&optional _point) "Return a list of local variables for POINT. Scan backwards from point at each successive function. For all occurrences of `let' or `let*', grab those variable names." diff --git a/lisp/cedet/semantic/sb.el b/lisp/cedet/semantic/sb.el index d7cd8e1940..debdfd1dc0 100644 --- a/lisp/cedet/semantic/sb.el +++ b/lisp/cedet/semantic/sb.el @@ -1,4 +1,4 @@ -;;; semantic/sb.el --- Semantic tag display for speedbar +;;; semantic/sb.el --- Semantic tag display for speedbar -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. @@ -73,10 +73,10 @@ use the `speedbar-line-file' to get this info if needed." (defmacro semantic-sb-with-tag-buffer (tag &rest forms) "Set the current buffer to the origin of TAG and execute FORMS. Restore the old current buffer when completed." + (declare (indent 1) (debug t)) `(save-excursion (semantic-sb-tag-set-buffer ,tag) ,@forms)) -(put 'semantic-sb-with-tag-buffer 'lisp-indent-function 1) ;;; Button Generation ;; @@ -294,7 +294,7 @@ TEXT TOKEN and INDENT are the details." (t (error "Ooops... not sure what to do"))) (speedbar-center-buffer-smartly)) -(defun semantic-sb-token-jump (text token indent) +(defun semantic-sb-token-jump (_text token indent) "Jump to the location specified in token. TEXT TOKEN and INDENT are the details." (let ((file diff --git a/lisp/emacs-lisp/ert-x.el b/lisp/emacs-lisp/ert-x.el index d058d3dda0..bf9aff67a6 100644 --- a/lisp/emacs-lisp/ert-x.el +++ b/lisp/emacs-lisp/ert-x.el @@ -102,15 +102,6 @@ the name of the test and the result of NAME-FORM." (indent 1)) `(ert--call-with-test-buffer ,name-form (lambda () ,@body))) -;; We use these `put' forms in addition to the (declare (indent)) in -;; the defmacro form since the `declare' alone does not lead to -;; correct indentation before the .el/.elc file is loaded. -;; Autoloading these `put' forms solves this. -;;;###autoload -(progn - ;; TODO(ohler): Figure out what these mean and make sure they are correct. - (put 'ert-with-test-buffer 'lisp-indent-function 1)) - ;;;###autoload (defun ert-kill-all-test-buffers () "Kill all test buffers that are still live." diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index e08fa7ac7b..96c1a02dbc 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -81,15 +81,13 @@ Use nil for no limit (caution: backtrace lines can be very long)." :background "green1") (((class color) (background dark)) :background "green3")) - "Face used for expected results in the ERT results buffer." - :group 'ert) + "Face used for expected results in the ERT results buffer.") (defface ert-test-result-unexpected '((((class color) (background light)) :background "red1") (((class color) (background dark)) :background "red3")) - "Face used for unexpected results in the ERT results buffer." - :group 'ert) + "Face used for unexpected results in the ERT results buffer.") ;;; Copies/reimplementations of cl functions. @@ -224,16 +222,6 @@ it has to be wrapped in `(eval (quote ...))'. :body (lambda () ,@body))) ',name)))) -;; We use these `put' forms in addition to the (declare (indent)) in -;; the defmacro form since the `declare' alone does not lead to -;; correct indentation before the .el/.elc file is loaded. -;; Autoloading these `put' forms solves this. -;;;###autoload -(progn - ;; TODO(ohler): Figure out what these mean and make sure they are correct. - (put 'ert-deftest 'lisp-indent-function 2) - (put 'ert-info 'lisp-indent-function 1)) - (defvar ert--find-test-regexp (concat "^\\s-*(ert-deftest" find-function-space-re diff --git a/lisp/emulation/cua-rect.el b/lisp/emulation/cua-rect.el index be2d7c0fd8..b734fd15a2 100644 --- a/lisp/emulation/cua-rect.el +++ b/lisp/emulation/cua-rect.el @@ -1,4 +1,4 @@ -;;; cua-rect.el --- CUA unified rectangle support +;;; cua-rect.el --- CUA unified rectangle support -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -575,6 +575,7 @@ Set undo boundary if UNDO is non-nil. Rectangle is padded if PAD = t or numeric and (cua--rectangle-virtual-edges) Perform auto-tabify after operation if TABIFY is non-nil. Mark is kept if keep-clear is 'keep and cleared if keep-clear is 'clear." + (declare (indent 4)) (let* ((inhibit-field-text-motion t) (start (cua--rectangle-top)) (end (cua--rectangle-bot)) @@ -645,8 +646,6 @@ Mark is kept if keep-clear is 'keep and cleared if keep-clear is 'clear." (cua--keep-active))) (setq cua--buffer-and-point-before-command nil))) -(put 'cua--rectangle-operation 'lisp-indent-function 4) - (defun cua--delete-rectangle () (let ((lines 0)) (if (not (cua--rectangle-virtual-edges)) @@ -1220,6 +1219,7 @@ The numbers are formatted according to the FORMAT string." ;;; Replace/rearrange text in current rectangle (defun cua--rectangle-aux-replace (width adjust keep replace pad format-fct &optional setup-fct) + (declare (indent 4)) ;; Process text inserted by calling SETUP-FCT or current rectangle if nil. ;; Then call FORMAT-FCT on text (if non-nil); takes two args: start and end. ;; Fill to WIDTH characters if > 0 or fill to current width if == 0. @@ -1279,8 +1279,6 @@ The numbers are formatted according to the FORMAT string." (if keep (cua--rectangle-resized))))) -(put 'cua--rectangle-aux-replace 'lisp-indent-function 4) - (defun cua--left-fill-rectangle (_start _end) (beginning-of-line) (while (< (point) (point-max)) diff --git a/lisp/international/mule-util.el b/lisp/international/mule-util.el index 580bd293e7..55449599fe 100644 --- a/lisp/international/mule-util.el +++ b/lisp/international/mule-util.el @@ -278,14 +278,13 @@ Optional 5th argument NIL-FOR-TOO-LONG non-nil means return nil CODING-SYSTEMS is a list of coding systems. See `set-coding-system-priority'. This affects the implicit sorting of lists of coding systems returned by operations such as `find-coding-systems-region'." + (declare (indent 1) (debug t)) (let ((current (make-symbol "current"))) `(let ((,current (coding-system-priority-list))) (apply #'set-coding-system-priority ,coding-systems) (unwind-protect (progn ,@body) (apply #'set-coding-system-priority ,current))))) -;;;###autoload(put 'with-coding-priority 'lisp-indent-function 1) -(put 'with-coding-priority 'edebug-form-spec t) ;;;###autoload (defun detect-coding-with-language-environment (from to lang-env) diff --git a/lisp/mh-e/mh-acros.el b/lisp/mh-e/mh-acros.el index af6f2f1ab0..dd953ee9df 100644 --- a/lisp/mh-e/mh-acros.el +++ b/lisp/mh-e/mh-acros.el @@ -1,4 +1,4 @@ -;;; mh-acros.el --- macros used in MH-E +;;; mh-acros.el --- macros used in MH-E -*- lexical-binding: t; -*- ;; Copyright (C) 2004, 2006-2021 Free Software Foundation, Inc. @@ -49,20 +49,19 @@ ;;;###mh-autoload (defmacro mh-do-in-gnu-emacs (&rest body) "Execute BODY if in GNU Emacs." - (declare (debug t)) + (declare (debug t) (indent defun)) (unless (featurep 'xemacs) `(progn ,@body))) -(put 'mh-do-in-gnu-emacs 'lisp-indent-hook 'defun) ;;;###mh-autoload (defmacro mh-do-in-xemacs (&rest body) "Execute BODY if in XEmacs." - (declare (debug t)) + (declare (debug t) (indent defun)) (when (featurep 'xemacs) `(progn ,@body))) -(put 'mh-do-in-xemacs 'lisp-indent-hook 'defun) ;;;###mh-autoload (defmacro mh-funcall-if-exists (function &rest args) "Call FUNCTION with ARGS as parameters if it exists." + (declare (debug (symbolp body))) ;; FIXME: Not clear when this should be used. If the function happens ;; not to exist at compile-time (e.g. because the corresponding package ;; wasn't loaded), then it won't ever be used :-( @@ -75,25 +74,24 @@ "Create function NAME. If FUNCTION exists, then NAME becomes an alias for FUNCTION. Otherwise, create function NAME with ARG-LIST and BODY." + (declare (indent defun) (doc-string 4) + (debug (&define name symbolp sexp def-body))) `(defalias ',name (if (fboundp ',function) ',function (lambda ,arg-list ,@body)))) -(put 'defun-mh 'lisp-indent-function 'defun) -(put 'defun-mh 'doc-string-elt 4) ;;;###mh-autoload (defmacro defmacro-mh (name macro arg-list &rest body) "Create macro NAME. If MACRO exists, then NAME becomes an alias for MACRO. Otherwise, create macro NAME with ARG-LIST and BODY." + (declare (indent defun) (doc-string 4) + (debug (&define name symbolp sexp def-body))) (let ((defined-p (fboundp macro))) (if defined-p `(defalias ',name ',macro) `(defmacro ,name ,arg-list ,@body)))) -(put 'defmacro-mh 'lisp-indent-function 'defun) -(put 'defmacro-mh 'doc-string-elt 4) - ;;; Miscellaneous @@ -127,7 +125,7 @@ Execute BODY, which can modify the folder buffer without having to worry about file locking or the read-only flag, and return its result. If SAVE-MODIFICATION-FLAG is non-nil, the buffer's modification flag is unchanged, otherwise it is cleared." - (declare (debug t)) + (declare (debug t) (indent defun)) (setq save-modification-flag (car save-modification-flag)) ; CL style `(prog1 (let ((mh-folder-updating-mod-flag (buffer-modified-p)) @@ -139,14 +137,13 @@ is unchanged, otherwise it is cleared." (mh-set-folder-modified-p mh-folder-updating-mod-flag))) ,@(if (not save-modification-flag) '((mh-set-folder-modified-p nil))))) -(put 'with-mh-folder-updating 'lisp-indent-hook 'defun) ;;;###mh-autoload (defmacro mh-in-show-buffer (show-buffer &rest body) "Format is (mh-in-show-buffer (SHOW-BUFFER) &body BODY). Display buffer SHOW-BUFFER in other window and execute BODY in it. Stronger than `save-excursion', weaker than `save-window-excursion'." - (declare (debug t)) + (declare (debug t) (indent defun)) (setq show-buffer (car show-buffer)) ; CL style `(let ((mh-in-show-buffer-saved-window (selected-window))) (switch-to-buffer-other-window ,show-buffer) @@ -155,7 +152,6 @@ Stronger than `save-excursion', weaker than `save-window-excursion'." (progn ,@body) (select-window mh-in-show-buffer-saved-window)))) -(put 'mh-in-show-buffer 'lisp-indent-hook 'defun) ;;;###mh-autoload (defmacro mh-do-at-event-location (event &rest body) @@ -163,7 +159,7 @@ Stronger than `save-excursion', weaker than `save-window-excursion'." After BODY has been executed return to original window. The modification flag of the buffer in the event window is preserved." - (declare (debug t)) + (declare (debug t) (indent defun)) (let ((event-window (make-symbol "event-window")) (event-position (make-symbol "event-position")) (original-window (make-symbol "original-window")) @@ -190,7 +186,6 @@ preserved." (goto-char ,original-position) (set-marker ,original-position nil) (select-window ,original-window)))))) -(put 'mh-do-at-event-location 'lisp-indent-hook 'defun) @@ -209,7 +204,7 @@ VAR is bound to the message on the current line as we loop starting from BEGIN till END. In each step BODY is executed. If VAR is nil then the loop is executed without any binding." - (declare (debug (symbolp body))) + (declare (debug (symbolp body)) (indent defun)) (unless (symbolp var) (error "Can not bind the non-symbol %s" var)) (let ((binding-needed-flag var)) @@ -221,7 +216,6 @@ If VAR is nil then the loop is executed without any binding." (let ,(if binding-needed-flag `((,var (mh-get-msg-num t))) ()) ,@body)) (forward-line 1))))) -(put 'mh-iterate-on-messages-in-region 'lisp-indent-hook 'defun) ;;;###mh-autoload (defmacro mh-iterate-on-range (var range &rest body) @@ -235,7 +229,7 @@ a string. In each iteration, BODY is executed. The parameter RANGE is usually created with `mh-interactive-range' in order to provide a uniform interface to MH-E functions." - (declare (debug (symbolp body))) + (declare (debug (symbolp body)) (indent defun)) (unless (symbolp var) (error "Can not bind the non-symbol %s" var)) (let ((binding-needed-flag var) @@ -263,7 +257,6 @@ MH-E functions." (when (gethash v ,seq-hash-table) (let ,(if binding-needed-flag `((,var v)) ()) ,@body)))))))) -(put 'mh-iterate-on-range 'lisp-indent-hook 'defun) (defmacro mh-dlet* (binders &rest body) "Like `let*' but always dynamically scoped." diff --git a/lisp/mh-e/mh-compat.el b/lisp/mh-e/mh-compat.el index 07bf03b30e..6d657afa3e 100644 --- a/lisp/mh-e/mh-compat.el +++ b/lisp/mh-e/mh-compat.el @@ -1,4 +1,4 @@ -;;; mh-compat.el --- make MH-E compatible with various versions of Emacs +;;; mh-compat.el --- make MH-E compatible with various versions of Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 2006-2021 Free Software Foundation, Inc. @@ -83,6 +83,7 @@ This is an analogue of a dynamically scoped `let' that operates on the function cell of FUNCs rather than their value cell. \(fn ((FUNC ARGLIST BODY...) ...) FORM...)" + (declare (indent 1) (debug ((&rest (sexp sexp &rest form)) &rest form))) (if (fboundp 'cl-letf) `(cl-letf ,(mapcar (lambda (binding) `((symbol-function ',(car binding)) @@ -90,9 +91,6 @@ the function cell of FUNCs rather than their value cell. bindings) ,@body) `(flet ,bindings ,@body))) -(put 'mh-flet 'lisp-indent-function 1) -(put 'mh-flet 'edebug-form-spec - '((&rest (sexp sexp &rest form)) &rest form)) (defun mh-display-color-cells (&optional display) "Return the number of color cells supported by DISPLAY. diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el index 2eb7fbaa20..eaf8eb5565 100644 --- a/lisp/mh-e/mh-e.el +++ b/lisp/mh-e/mh-e.el @@ -1,4 +1,4 @@ -;;; mh-e.el --- GNU Emacs interface to the MH mail system +;;; mh-e.el --- GNU Emacs interface to the MH mail system -*- lexical-binding: t; -*- ;; Copyright (C) 1985-1988, 1990, 1992-1995, 1997, 1999-2021 Free ;; Software Foundation, Inc. @@ -695,9 +695,8 @@ See documentation for `defgroup' for a description of the arguments SYMBOL, MEMBERS, DOC and ARGS. This macro is used by Emacs versions that lack the :package-version keyword, introduced in Emacs 22." - (declare (doc-string 3)) + (declare (doc-string 3) (indent defun)) `(defgroup ,symbol ,members ,doc ,@(mh-strip-package-version args))) -(put 'defgroup-mh 'lisp-indent-function 'defun) (defmacro defcustom-mh (symbol value doc &rest args) "Declare SYMBOL as a customizable variable that defaults to VALUE. @@ -705,9 +704,8 @@ See documentation for `defcustom' for a description of the arguments SYMBOL, VALUE, DOC and ARGS. This macro is used by Emacs versions that lack the :package-version keyword, introduced in Emacs 22." - (declare (doc-string 3)) + (declare (doc-string 3) (indent defun)) `(defcustom ,symbol ,value ,doc ,@(mh-strip-package-version args))) -(put 'defcustom-mh 'lisp-indent-function 'defun) (defmacro defface-mh (face spec doc &rest args) "Declare FACE as a customizable face that defaults to SPEC. @@ -715,9 +713,8 @@ See documentation for `defface' for a description of the arguments FACE, SPEC, DOC and ARGS. This macro is used by Emacs versions that lack the :package-version keyword, introduced in Emacs 22." - (declare (doc-string 3)) + (declare (doc-string 3) (indent defun)) `(defface ,face ,spec ,doc ,@(mh-strip-package-version args))) -(put 'defface-mh 'lisp-indent-function 'defun) diff --git a/lisp/net/sieve.el b/lisp/net/sieve.el index ca100267f6..595d63331a 100644 --- a/lisp/net/sieve.el +++ b/lisp/net/sieve.el @@ -1,4 +1,4 @@ -;;; sieve.el --- Utilities to manage sieve scripts +;;; sieve.el --- Utilities to manage sieve scripts -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. @@ -69,13 +69,11 @@ (defcustom sieve-new-script "" "Name of name script indicator." - :type 'string - :group 'sieve) + :type 'string) (defcustom sieve-buffer "*sieve*" "Name of sieve management buffer." - :type 'string - :group 'sieve) + :type 'string) (defcustom sieve-template "\ require \"fileinto\"; @@ -91,8 +89,7 @@ require \"fileinto\"; # } " "Template sieve script." - :type 'string - :group 'sieve) + :type 'string) ;; Internal variables: @@ -104,31 +101,36 @@ require \"fileinto\"; ;; Sieve-manage mode: +;; This function is defined by `easy-menu-define' but it's only done +;; at run time and the compiler is not aware of it. +;; FIXME: This is arguably a bug/problem in `easy-menu-define'. +(declare-function sieve-manage-mode-menu "sieve") + (defvar sieve-manage-mode-map (let ((map (make-sparse-keymap))) ;; various - (define-key map "?" 'sieve-help) - (define-key map "h" 'sieve-help) + (define-key map "?" #'sieve-help) + (define-key map "h" #'sieve-help) ;; activating - (define-key map "m" 'sieve-activate) - (define-key map "u" 'sieve-deactivate) - (define-key map "\M-\C-?" 'sieve-deactivate-all) + (define-key map "m" #'sieve-activate) + (define-key map "u" #'sieve-deactivate) + (define-key map "\M-\C-?" #'sieve-deactivate-all) ;; navigation keys - (define-key map "\C-p" 'sieve-prev-line) - (define-key map [up] 'sieve-prev-line) - (define-key map "\C-n" 'sieve-next-line) - (define-key map [down] 'sieve-next-line) - (define-key map " " 'sieve-next-line) - (define-key map "n" 'sieve-next-line) - (define-key map "p" 'sieve-prev-line) - (define-key map "\C-m" 'sieve-edit-script) - (define-key map "f" 'sieve-edit-script) - (define-key map "o" 'sieve-edit-script-other-window) - (define-key map "r" 'sieve-remove) - (define-key map "q" 'sieve-bury-buffer) - (define-key map "Q" 'sieve-manage-quit) - (define-key map [(down-mouse-2)] 'sieve-edit-script) - (define-key map [(down-mouse-3)] 'sieve-manage-mode-menu) + (define-key map "\C-p" #'sieve-prev-line) + (define-key map [up] #'sieve-prev-line) + (define-key map "\C-n" #'sieve-next-line) + (define-key map [down] #'sieve-next-line) + (define-key map " " #'sieve-next-line) + (define-key map "n" #'sieve-next-line) + (define-key map "p" #'sieve-prev-line) + (define-key map "\C-m" #'sieve-edit-script) + (define-key map "f" #'sieve-edit-script) + ;; (define-key map "o" #'sieve-edit-script-other-window) + (define-key map "r" #'sieve-remove) + (define-key map "q" #'sieve-bury-buffer) + (define-key map "Q" #'sieve-manage-quit) + (define-key map [(down-mouse-2)] #'sieve-edit-script) + (define-key map [(down-mouse-3)] #'sieve-manage-mode-menu) map) "Keymap for `sieve-manage-mode'.") @@ -159,8 +161,8 @@ require \"fileinto\"; (interactive) (bury-buffer)) -(defun sieve-activate (&optional pos) - (interactive "d") +(defun sieve-activate (&optional _pos) + (interactive) (let ((name (sieve-script-at-point)) err) (when (or (null name) (string-equal name sieve-new-script)) (error "No sieve script at point")) @@ -171,20 +173,20 @@ require \"fileinto\"; (message "Activating script %s...done" name) (message "Activating script %s...failed: %s" name (nth 2 err))))) -(defun sieve-deactivate-all (&optional pos) - (interactive "d") - (let ((name (sieve-script-at-point)) err) - (message "Deactivating scripts...") - (setq err (sieve-manage-setactive "" sieve-manage-buffer)) +(defun sieve-deactivate-all (&optional _pos) + (interactive) + (message "Deactivating scripts...") + (let (;; (name (sieve-script-at-point)) + (err (sieve-manage-setactive "" sieve-manage-buffer))) (sieve-refresh-scriptlist) (if (sieve-manage-ok-p err) (message "Deactivating scripts...done") (message "Deactivating scripts...failed: %s" (nth 2 err))))) -(defalias 'sieve-deactivate 'sieve-deactivate-all) +(defalias 'sieve-deactivate #'sieve-deactivate-all) -(defun sieve-remove (&optional pos) - (interactive "d") +(defun sieve-remove (&optional _pos) + (interactive) (let ((name (sieve-script-at-point)) err) (when (or (null name) (string-equal name sieve-new-script)) (error "No sieve script at point")) @@ -195,8 +197,8 @@ require \"fileinto\"; (sieve-refresh-scriptlist) (message "Removing sieve script %s...done" name))) -(defun sieve-edit-script (&optional pos) - (interactive "d") +(defun sieve-edit-script (&optional _pos) + (interactive) (let ((name (sieve-script-at-point))) (unless name (error "No sieve script at point")) @@ -224,11 +226,11 @@ require \"fileinto\"; (defmacro sieve-change-region (&rest body) "Turns off sieve-region before executing BODY, then re-enables it after. Used to bracket operations which move point in the sieve-buffer." + (declare (indent 0) (debug t)) `(progn (sieve-highlight nil) ,@body (sieve-highlight t))) -(put 'sieve-change-region 'lisp-indent-function 0) (defun sieve-next-line (&optional arg) (interactive) diff --git a/lisp/obsolete/fast-lock.el b/lisp/obsolete/fast-lock.el index 8848c89c62..7f2cd4b770 100644 --- a/lisp/obsolete/fast-lock.el +++ b/lisp/obsolete/fast-lock.el @@ -1,4 +1,4 @@ -;;; fast-lock.el --- automagic text properties caching for fast Font Lock mode +;;; fast-lock.el --- automagic text properties caching for fast Font Lock mode -*- lexical-binding: t; -*- ;; Copyright (C) 1994-1998, 2001-2021 Free Software Foundation, Inc. @@ -190,18 +190,6 @@ (defvar font-lock-face-list) (eval-when-compile - ;; We use this to preserve or protect things when modifying text properties. - (defmacro save-buffer-state (varlist &rest body) - "Bind variables according to VARLIST and eval BODY restoring buffer state." - `(let* (,@(append varlist - '((modified (buffer-modified-p)) (buffer-undo-list t) - (inhibit-read-only t) (inhibit-point-motion-hooks t) - (inhibit-modification-hooks t) - deactivate-mark buffer-file-name buffer-file-truename))) - ,@body - (when (and (not modified) (buffer-modified-p)) - (set-buffer-modified-p nil)))) - (put 'save-buffer-state 'lisp-indent-function 1) ;; ;; We use this to verify that a face should be saved. (defmacro fast-lock-save-facep (face) @@ -244,8 +232,7 @@ for buffers in Rmail mode, and size is irrelevant otherwise." (symbol :tag "name")) (radio :tag "Size" (const :tag "none" nil) - (integer :tag "size"))))) - :group 'fast-lock) + (integer :tag "size")))))) (defcustom fast-lock-cache-directories '("~/.emacs-flc") ; - `internal', keep each file's Font Lock cache file in the same file. @@ -271,8 +258,7 @@ to avoid the possibility of using the cache of another user." :type '(repeat (radio (directory :tag "directory") (cons :tag "Matching" (regexp :tag "regexp") - (directory :tag "directory")))) - :group 'fast-lock) + (directory :tag "directory"))))) (put 'fast-lock-cache-directories 'risky-local-variable t) (defcustom fast-lock-save-events '(kill-buffer kill-emacs) @@ -282,23 +268,20 @@ If concurrent editing sessions use the same associated cache file for a file's buffer, then you should add `save-buffer' to this list." :type '(set (const :tag "buffer saving" save-buffer) (const :tag "buffer killing" kill-buffer) - (const :tag "emacs killing" kill-emacs)) - :group 'fast-lock) + (const :tag "emacs killing" kill-emacs))) (defcustom fast-lock-save-others t "If non-nil, save Font Lock cache files irrespective of file owner. If nil, means only buffer files known to be owned by you can have associated Font Lock cache files saved. Ownership may be unknown for networked files." - :type 'boolean - :group 'fast-lock) + :type 'boolean) (defcustom fast-lock-verbose font-lock-verbose "If non-nil, means show status messages for cache processing. If a number, only buffers greater than this size have processing messages." :type '(choice (const :tag "never" nil) (other :tag "always" t) - (integer :tag "size")) - :group 'fast-lock) + (integer :tag "size"))) (defvar fast-lock-save-faces (when (featurep 'xemacs) @@ -581,7 +564,7 @@ See `fast-lock-cache-directory'." (defun fast-lock-cache-data (version timestamp syntactic-keywords syntactic-properties keywords face-properties - &rest ignored) + &rest _ignored) ;; Find value of syntactic keywords in case it is a symbol. (setq font-lock-syntactic-keywords (font-lock-eval-keywords font-lock-syntactic-keywords)) @@ -708,86 +691,26 @@ See `fast-lock-get-face-properties'." "Add `syntax-table' and `face' text properties to the current buffer. Any existing `syntax-table' and `face' text properties are removed first. See `fast-lock-get-face-properties'." - (save-buffer-state (plist regions) - (save-restriction - (widen) - (font-lock-unfontify-region (point-min) (point-max)) - ;; - ;; Set the `syntax-table' property for each start/end region. - (while syntactic-properties - (setq plist (list 'syntax-table (car (car syntactic-properties))) - regions (cdr (car syntactic-properties)) - syntactic-properties (cdr syntactic-properties)) - (while regions - (add-text-properties (nth 0 regions) (nth 1 regions) plist) - (setq regions (nthcdr 2 regions)))) - ;; - ;; Set the `face' property for each start/end region. - (while face-properties - (setq plist (list 'face (car (car face-properties))) - regions (cdr (car face-properties)) - face-properties (cdr face-properties)) - (while regions - (add-text-properties (nth 0 regions) (nth 1 regions) plist) - (setq regions (nthcdr 2 regions))))))) + (with-silent-modifications + (let ((inhibit-point-motion-hooks t)) + (save-restriction + (widen) + (font-lock-unfontify-region (point-min) (point-max)) + ;; + ;; Set the `syntax-table' property for each start/end region. + (pcase-dolist (`(,plist . ,regions) syntactic-properties) + (while regions + (add-text-properties (nth 0 regions) (nth 1 regions) plist) + (setq regions (nthcdr 2 regions)))) + ;; + ;; Set the `face' property for each start/end region. + (pcase-dolist (`(,plist . ,regions) face-properties) + (while regions + (add-text-properties (nth 0 regions) (nth 1 regions) plist) + (setq regions (nthcdr 2 regions)))))))) ;; Functions for XEmacs: -(when (featurep 'xemacs) - ;; - ;; It would be better to use XEmacs' `map-extents' over extents with a - ;; `font-lock' property, but `face' properties are on different extents. - (defun fast-lock-get-face-properties () - "Return a list of `face' text properties in the current buffer. -Each element of the list is of the form (VALUE START1 END1 START2 END2 ...) -where VALUE is a `face' property value and STARTx and ENDx are positions. -Only those `face' VALUEs in `fast-lock-save-faces' are returned." - (save-restriction - (widen) - (let ((properties ()) cell) - (map-extents - (function (lambda (extent ignore) - (let ((value (extent-face extent))) - ;; We're only interested if it's one of `fast-lock-save-faces'. - (when (and value (fast-lock-save-facep value)) - (let ((start (extent-start-position extent)) - (end (extent-end-position extent))) - ;; Make or add to existing list of regions with the same - ;; `face' property value. - (if (setq cell (assoc value properties)) - (setcdr cell (cons start (cons end (cdr cell)))) - (push (list value start end) properties)))) - ;; Return nil to keep `map-extents' going. - nil)))) - properties))) - ;; - ;; XEmacs does not support the `syntax-table' text property. - (defalias 'fast-lock-get-syntactic-properties - 'ignore) - ;; - ;; Make extents just like XEmacs' font-lock.el does. - (defun fast-lock-add-properties (syntactic-properties face-properties) - "Set `face' text properties in the current buffer. -Any existing `face' text properties are removed first. -See `fast-lock-get-face-properties'." - (save-restriction - (widen) - (font-lock-unfontify-region (point-min) (point-max)) - ;; Set the `face' property, etc., for each start/end region. - (while face-properties - (let ((face (car (car face-properties))) - (regions (cdr (car face-properties)))) - (while regions - (font-lock-set-face (nth 0 regions) (nth 1 regions) face) - (setq regions (nthcdr 2 regions))) - (setq face-properties (cdr face-properties)))) - ;; XEmacs does not support the `syntax-table' text property. - )) - ;; - ;; XEmacs 19.12 font-lock.el's `font-lock-fontify-buffer' runs a hook. - (add-hook 'font-lock-after-fontify-buffer-hook - 'fast-lock-after-fontify-buffer)) - (unless (boundp 'font-lock-syntactic-keywords) (defvar font-lock-syntactic-keywords nil)) @@ -802,7 +725,7 @@ See `fast-lock-get-face-properties'." (if (symbolp keywords) (font-lock-eval-keywords (if (fboundp keywords) (funcall keywords) - (eval keywords))) + (eval keywords t))) keywords))) (unless (fboundp 'font-lock-value-in-major-mode) diff --git a/lisp/obsolete/lazy-lock.el b/lisp/obsolete/lazy-lock.el index e1a01913be..452be30818 100644 --- a/lisp/obsolete/lazy-lock.el +++ b/lisp/obsolete/lazy-lock.el @@ -1,4 +1,4 @@ -;;; lazy-lock.el --- lazy demand-driven fontification for fast Font Lock mode +;;; lazy-lock.el --- lazy demand-driven fontification for fast Font Lock mode -*- lexical-binding: t; -*- ;; Copyright (C) 1994-1998, 2001-2021 Free Software Foundation, Inc. @@ -270,30 +270,14 @@ (eval-when-compile (require 'cl-lib)) (eval-when-compile - ;; We use this to preserve or protect things when modifying text properties. - (defmacro save-buffer-state (varlist &rest body) - "Bind variables according to VARLIST and eval BODY restoring buffer state." - `(let* (,@(append varlist - '((modified (buffer-modified-p)) - (buffer-undo-list t) - (inhibit-read-only t) - (inhibit-point-motion-hooks t) - (inhibit-modification-hooks t) - deactivate-mark - buffer-file-name - buffer-file-truename))) - ,@body - (when (and (not modified) (buffer-modified-p)) - (restore-buffer-modified-p nil)))) - (put 'save-buffer-state 'lisp-indent-function 1) ;; ;; We use this for clarity and speed. Naughty but nice. (defmacro do-while (test &rest body) "(do-while TEST BODY...): eval BODY... and repeat if TEST yields non-nil. The order of execution is thus BODY, TEST, BODY, TEST and so on until TEST returns nil." - `(while (progn ,@body ,test))) - (put 'do-while 'lisp-indent-function (get 'while 'lisp-indent-function))) + (declare (indent 1) (debug t)) + `(while (progn ,@body ,test)))) (defgroup lazy-lock nil "Font Lock support mode to fontify lazily." @@ -326,8 +310,7 @@ The value of this variable is used when Lazy Lock mode is turned on." (symbol :tag "name")) (radio :tag "Size" (const :tag "none" nil) - (integer :tag "size"))))) - :group 'lazy-lock) + (integer :tag "size")))))) (defcustom lazy-lock-defer-on-the-fly t "If non-nil, means fontification after a change should be deferred. @@ -346,8 +329,7 @@ The value of this variable is used when Lazy Lock mode is turned on." (set :menu-tag "mode specific" :tag "modes" :value (not) (const :tag "Except" not) - (repeat :inline t (symbol :tag "mode")))) - :group 'lazy-lock) + (repeat :inline t (symbol :tag "mode"))))) (defcustom lazy-lock-defer-on-scrolling nil "If non-nil, means fontification after a scroll should be deferred. @@ -371,8 +353,7 @@ makes little sense if `lazy-lock-defer-contextually' is non-nil.) The value of this variable is used when Lazy Lock mode is turned on." :type '(choice (const :tag "never" nil) (const :tag "always" t) - (other :tag "eventually" eventually)) - :group 'lazy-lock) + (other :tag "eventually" eventually))) (defcustom lazy-lock-defer-contextually 'syntax-driven "If non-nil, means deferred fontification should be syntactically true. @@ -389,8 +370,7 @@ buffer mode's syntax table, i.e., only if `font-lock-keywords-only' is nil. The value of this variable is used when Lazy Lock mode is turned on." :type '(choice (const :tag "never" nil) (const :tag "always" t) - (other :tag "syntax-driven" syntax-driven)) - :group 'lazy-lock) + (other :tag "syntax-driven" syntax-driven))) (defcustom lazy-lock-defer-time 0.25 "Time in seconds to delay before beginning deferred fontification. @@ -401,8 +381,7 @@ variables `lazy-lock-defer-on-the-fly', `lazy-lock-defer-on-scrolling' and The value of this variable is used when Lazy Lock mode is turned on." :type '(choice (const :tag "never" nil) - (number :tag "seconds")) - :group 'lazy-lock) + (number :tag "seconds"))) (defcustom lazy-lock-stealth-time 30 "Time in seconds to delay before beginning stealth fontification. @@ -411,16 +390,14 @@ If nil, means stealth fontification is never performed. The value of this variable is used when Lazy Lock mode is turned on." :type '(choice (const :tag "never" nil) - (number :tag "seconds")) - :group 'lazy-lock) + (number :tag "seconds"))) (defcustom lazy-lock-stealth-lines (if font-lock-maximum-decoration 100 250) "Maximum size of a chunk of stealth fontification. Each iteration of stealth fontification can fontify this number of lines. To speed up input response during stealth fontification, at the cost of stealth taking longer to fontify, you could reduce the value of this variable." - :type '(integer :tag "lines") - :group 'lazy-lock) + :type '(integer :tag "lines")) (defcustom lazy-lock-stealth-load (if (condition-case nil (load-average) (error)) 200) @@ -435,8 +412,7 @@ See also `lazy-lock-stealth-nice'." :type (if (condition-case nil (load-average) (error)) '(choice (const :tag "never" nil) (integer :tag "load")) - '(const :format "%t: unsupported\n" nil)) - :group 'lazy-lock) + '(const :format "%t: unsupported\n" nil))) (defcustom lazy-lock-stealth-nice 0.125 "Time in seconds to pause between chunks of stealth fontification. @@ -447,14 +423,12 @@ To reduce machine load during stealth fontification, at the cost of stealth taking longer to fontify, you could increase the value of this variable. See also `lazy-lock-stealth-load'." :type '(choice (const :tag "never" nil) - (number :tag "seconds")) - :group 'lazy-lock) + (number :tag "seconds"))) (defcustom lazy-lock-stealth-verbose (and (not lazy-lock-defer-contextually) (not (null font-lock-verbose))) "If non-nil, means stealth fontification should show status messages." - :type 'boolean - :group 'lazy-lock) + :type 'boolean) ;; User Functions: @@ -682,7 +656,7 @@ verbosity is controlled via the variable `lazy-lock-stealth-verbose'." ;; result in an unnecessary trigger after this if we did not cancel it now. (set-window-redisplay-end-trigger window nil)) -(defun lazy-lock-defer-after-scroll (window window-start) +(defun lazy-lock-defer-after-scroll (window _window-start) ;; Called from `window-scroll-functions'. ;; Defer fontification following the scroll. Save the current buffer so that ;; we subsequently fontify in all windows showing the buffer. @@ -758,29 +732,29 @@ verbosity is controlled via the variable `lazy-lock-stealth-verbose'." ;; buffer. Save the current buffer so that we subsequently fontify in all ;; windows showing the buffer. (lazy-lock-fontify-line-after-change beg end old-len) - (save-buffer-state nil + (with-silent-modifications (unless (memq (current-buffer) lazy-lock-buffers) (push (current-buffer) lazy-lock-buffers)) (save-restriction (widen) (remove-text-properties end (point-max) '(lazy-lock nil))))) -(defun lazy-lock-defer-line-after-change (beg end old-len) +(defun lazy-lock-defer-line-after-change (beg end _old-len) ;; Called from `after-change-functions'. ;; Defer fontification of the current change. Save the current buffer so ;; that we subsequently fontify in all windows showing the buffer. - (save-buffer-state nil + (with-silent-modifications (unless (memq (current-buffer) lazy-lock-buffers) (push (current-buffer) lazy-lock-buffers)) (remove-text-properties (max (1- beg) (point-min)) (min (1+ end) (point-max)) '(lazy-lock nil)))) -(defun lazy-lock-defer-rest-after-change (beg end old-len) +(defun lazy-lock-defer-rest-after-change (beg _end _old-len) ;; Called from `after-change-functions'. ;; Defer fontification of the rest of the buffer. Save the current buffer so ;; that we subsequently fontify in all windows showing the buffer. - (save-buffer-state nil + (with-silent-modifications (unless (memq (current-buffer) lazy-lock-buffers) (push (current-buffer) lazy-lock-buffers)) (save-restriction @@ -868,14 +842,14 @@ verbosity is controlled via the variable `lazy-lock-stealth-verbose'." ;; Called from `font-lock-after-fontify-buffer'. ;; Mark the current buffer as fontified. ;; This is a conspiracy hack between lazy-lock.el and font-lock.el. - (save-buffer-state nil + (with-silent-modifications (add-text-properties (point-min) (point-max) '(lazy-lock t)))) (defun lazy-lock-after-unfontify-buffer () ;; Called from `font-lock-after-unfontify-buffer'. ;; Mark the current buffer as unfontified. ;; This is a conspiracy hack between lazy-lock.el and font-lock.el. - (save-buffer-state nil + (with-silent-modifications (remove-text-properties (point-min) (point-max) '(lazy-lock nil)))) ;; Fontification functions. @@ -888,27 +862,27 @@ verbosity is controlled via the variable `lazy-lock-stealth-verbose'." (widen) (when (setq beg (text-property-any beg end 'lazy-lock nil)) (save-excursion - (save-match-data - (save-buffer-state - (next) - ;; Find successive unfontified regions between BEG and END. - (condition-case data - (do-while beg - (setq next (or (text-property-any beg end 'lazy-lock t) end)) - ;; Make sure the region end points are at beginning of line. - (goto-char beg) - (unless (bolp) - (beginning-of-line) - (setq beg (point))) - (goto-char next) - (unless (bolp) - (forward-line) - (setq next (point))) - ;; Fontify the region, then flag it as fontified. - (font-lock-fontify-region beg next) - (add-text-properties beg next '(lazy-lock t)) - (setq beg (text-property-any next end 'lazy-lock nil))) - ((error quit) (message "Fontifying region...%s" data))))))))) + (with-silent-modifications + (let ((inhibit-point-motion-hooks t)) + ;; Find successive unfontified regions between BEG and END. + (condition-case data + (do-while beg + (let ((next (or (text-property-any beg end 'lazy-lock t) + end))) + ;; Make sure the region end points are at beginning of line. + (goto-char beg) + (unless (bolp) + (beginning-of-line) + (setq beg (point))) + (goto-char next) + (unless (bolp) + (forward-line) + (setq next (point))) + ;; Fontify the region, then flag it as fontified. + (font-lock-fontify-region beg next) + (add-text-properties beg next '(lazy-lock t)) + (setq beg (text-property-any next end 'lazy-lock nil)))) + ((error quit) (message "Fontifying region...%s" data))))))))) (defun lazy-lock-fontify-chunk () ;; Fontify the nearest chunk, for stealth, in the current buffer. @@ -1036,8 +1010,8 @@ verbosity is controlled via the variable `lazy-lock-stealth-verbose'." ;; Install ourselves: -(add-hook 'window-size-change-functions 'lazy-lock-fontify-after-resize) -(add-hook 'redisplay-end-trigger-functions 'lazy-lock-fontify-after-trigger) +(add-hook 'window-size-change-functions #'lazy-lock-fontify-after-resize) +(add-hook 'redisplay-end-trigger-functions #'lazy-lock-fontify-after-trigger) (unless (assq 'lazy-lock-mode minor-mode-alist) (setq minor-mode-alist (append minor-mode-alist '((lazy-lock-mode nil))))) diff --git a/lisp/obsolete/pgg.el b/lisp/obsolete/pgg.el index ec93eeb93f..03d4465d7b 100644 --- a/lisp/obsolete/pgg.el +++ b/lisp/obsolete/pgg.el @@ -1,4 +1,4 @@ -;;; pgg.el --- glue for the various PGP implementations. +;;; pgg.el --- glue for the various PGP implementations. -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2000, 2002-2021 Free Software Foundation, Inc. @@ -34,68 +34,6 @@ ;;; @ utility functions ;;; -(eval-when-compile - (when (featurep 'xemacs) - (defmacro pgg-run-at-time-1 (time repeat function args) - (if (condition-case nil - (let ((delete-itimer 'delete-itimer) - (itimer-driver-start 'itimer-driver-start) - (itimer-value 'itimer-value) - (start-itimer 'start-itimer)) - (unless (or (symbol-value 'itimer-process) - (symbol-value 'itimer-timer)) - (funcall itimer-driver-start)) - ;; Check whether there is a bug to which the difference of - ;; the present time and the time when the itimer driver was - ;; woken up is subtracted from the initial itimer value. - (let* ((inhibit-quit t) - (ctime (current-time)) - (itimer-timer-last-wakeup - (prog1 - ctime - (setcar ctime (1- (car ctime))))) - (itimer-list nil) - (itimer (funcall start-itimer "pgg-run-at-time" - 'ignore 5))) - (sleep-for 0.1) ;; Accept the timeout interrupt. - (prog1 - (> (funcall itimer-value itimer) 0) - (funcall delete-itimer itimer)))) - (error nil)) - `(let ((time ,time)) - (apply #'start-itimer "pgg-run-at-time" - ,function (if time (max time 1e-9) 1e-9) - ,repeat nil t ,args)) - `(let ((time ,time) - (itimers (list nil))) - (setcar - itimers - (apply #'start-itimer "pgg-run-at-time" - (lambda (itimers repeat function &rest args) - (let ((itimer (car itimers))) - (if repeat - (progn - (set-itimer-function - itimer - (lambda (itimer repeat function &rest args) - (set-itimer-restart itimer repeat) - (set-itimer-function itimer function) - (set-itimer-function-arguments itimer args) - (apply function args))) - (set-itimer-function-arguments - itimer - (append (list itimer repeat function) args))) - (set-itimer-function - itimer - (lambda (itimer function &rest args) - (delete-itimer itimer) - (apply function args))) - (set-itimer-function-arguments - itimer - (append (list itimer function) args))))) - 1e-9 (if time (max time 1e-9) 1e-9) - nil t itimers ,repeat ,function ,args))))))) - (eval-and-compile (if (featurep 'xemacs) (progn @@ -117,9 +55,8 @@ or `cancel-timer'." (require (intern (format "pgg-%s" scheme))) (apply 'funcall (intern (format "pgg-%s-%s" scheme func)) args))) -(put 'pgg-save-coding-system 'lisp-indent-function 2) - (defmacro pgg-save-coding-system (start end &rest body) + (declare (indent 2) (debug t)) `(if (called-interactively-p 'interactive) (let ((buffer (current-buffer))) (with-temp-buffer @@ -209,7 +146,7 @@ regulate cache behavior." (let* ((key (if notruncate key (pgg-truncate-key-identifier key))) (interned-timer-key (intern-soft key pgg-pending-timers)) (old-timer (symbol-value interned-timer-key)) - new-timer) + ) ;; new-timer (when old-timer (cancel-timer old-timer) (unintern interned-timer-key pgg-pending-timers)) @@ -265,9 +202,8 @@ regulate cache behavior." (while (re-search-forward "\r$" pgg-conversion-end t) (replace-match "")))))) -(put 'pgg-as-lbt 'lisp-indent-function 3) - (defmacro pgg-as-lbt (start end lbt &rest body) + (declare (indent 3) (debug t)) `(let ((inhibit-read-only t) buffer-read-only buffer-undo-list) @@ -277,9 +213,8 @@ regulate cache behavior." (push nil buffer-undo-list) (ignore-errors (undo)))) -(put 'pgg-process-when-success 'lisp-indent-function 0) - (defmacro pgg-process-when-success (&rest body) + (declare (indent 0) (debug t)) `(with-current-buffer pgg-output-buffer (if (zerop (buffer-size)) nil ,@body t))) @@ -377,7 +312,7 @@ passphrase cache or user." If optional PASSPHRASE is not specified, it will be obtained from the passphrase cache or user." (interactive "r") - (let* ((buf (current-buffer)) + (let* (;; (buf (current-buffer)) (status (pgg-save-coding-system start end (pgg-invoke "decrypt-region" (or pgg-scheme pgg-default-scheme) diff --git a/lisp/org/org-agenda.el b/lisp/org/org-agenda.el index b9799d2abe..8a4aa2b1be 100644 --- a/lisp/org/org-agenda.el +++ b/lisp/org/org-agenda.el @@ -3224,6 +3224,15 @@ s Search for keywords M Like m, but only TODO entries (defvar org-agenda-overriding-cmd nil) (defvar org-agenda-overriding-arguments nil) (defvar org-agenda-overriding-cmd-arguments nil) + +(defun org-let (list &rest body) ;FIXME: So many kittens are suffering here. + (declare (indent 1)) + (eval (cons 'let (cons list body)))) + +(defun org-let2 (list1 list2 &rest body) ;FIXME: Where did our karma go? + (declare (indent 2)) + (eval (cons 'let (cons list1 (list (cons 'let (cons list2 body))))))) + (defun org-agenda-run-series (name series) "Run agenda NAME as a SERIES of agenda commands." (org-let (nth 1 series) '(org-agenda-prepare name)) diff --git a/lisp/org/org-element.el b/lisp/org/org-element.el index b7319d638e..31f5f78eae 100644 --- a/lisp/org/org-element.el +++ b/lisp/org/org-element.el @@ -4206,6 +4206,7 @@ looking into captions: (lambda (b) (and (org-element-map b \\='latex-snippet #\\='identity nil t) b)) nil nil nil t)" + (declare (indent 2)) ;; Ensure TYPES and NO-RECURSION are a list, even of one element. (let* ((types (if (listp types) types (list types))) (no-recursion (if (listp no-recursion) no-recursion @@ -4299,7 +4300,6 @@ looking into captions: (funcall --walk-tree data) ;; Return value in a proper order. (nreverse --acc))))) -(put 'org-element-map 'lisp-indent-function 2) ;; The following functions are internal parts of the parser. ;; diff --git a/lisp/org/org-macs.el b/lisp/org/org-macs.el index 56afdf6ef1..ac6691db0d 100644 --- a/lisp/org/org-macs.el +++ b/lisp/org/org-macs.el @@ -627,18 +627,10 @@ program is needed for, so that the error message can be more informative." (let ((message-log-max nil)) (apply #'message args))) -(defun org-let (list &rest body) - (eval (cons 'let (cons list body)))) -(put 'org-let 'lisp-indent-function 1) - -(defun org-let2 (list1 list2 &rest body) - (eval (cons 'let (cons list1 (list (cons 'let (cons list2 body))))))) -(put 'org-let2 'lisp-indent-function 2) - (defun org-eval (form) "Eval FORM and return result." (condition-case error - (eval form) + (eval form t) (error (format "%%![Error: %s]" error)))) (defvar org-outline-regexp) ; defined in org.el @@ -1241,31 +1233,29 @@ Return 0. if S is not recognized as a valid value." When ADDITIONAL-KEYS is not nil, also include SPC and DEL in the allowed keys for scrolling, as expected in the export dispatch window." - (let ((scrlup (if additional-keys '(?\s 22) 22)) - (scrldn (if additional-keys `(?\d 134217846) 134217846))) - (eval - `(cl-case ,key - ;; C-n - (14 (if (not (pos-visible-in-window-p (point-max))) - (ignore-errors (scroll-up 1)) - (message "End of buffer") - (sit-for 1))) - ;; C-p - (16 (if (not (pos-visible-in-window-p (point-min))) - (ignore-errors (scroll-down 1)) - (message "Beginning of buffer") - (sit-for 1))) - ;; SPC or - (,scrlup - (if (not (pos-visible-in-window-p (point-max))) - (scroll-up nil) - (message "End of buffer") - (sit-for 1))) - ;; DEL - (,scrldn (if (not (pos-visible-in-window-p (point-min))) - (scroll-down nil) - (message "Beginning of buffer") - (sit-for 1))))))) + (let ((scrlup (if additional-keys '(?\s ?\C-v) ?\C-v)) + (scrldn (if additional-keys `(?\d ?\M-v) ?\M-v))) + (pcase key + (?\C-n (if (not (pos-visible-in-window-p (point-max))) + (ignore-errors (scroll-up 1)) + (message "End of buffer") + (sit-for 1))) + (?\C-p (if (not (pos-visible-in-window-p (point-min))) + (ignore-errors (scroll-down 1)) + (message "Beginning of buffer") + (sit-for 1))) + ;; SPC or + ((guard (memq key scrlup)) + (if (not (pos-visible-in-window-p (point-max))) + (scroll-up nil) + (message "End of buffer") + (sit-for 1))) + ;; DEL + ((guard (memq key scrldn)) + (if (not (pos-visible-in-window-p (point-min))) + (scroll-down nil) + (message "Beginning of buffer") + (sit-for 1)))))) (provide 'org-macs) diff --git a/lisp/progmodes/antlr-mode.el b/lisp/progmodes/antlr-mode.el index d92c8c35b1..56eeeeef37 100644 --- a/lisp/progmodes/antlr-mode.el +++ b/lisp/progmodes/antlr-mode.el @@ -1,4 +1,4 @@ -;;; antlr-mode.el --- major mode for ANTLR grammar files +;;; antlr-mode.el --- major mode for ANTLR grammar files -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. @@ -164,18 +164,10 @@ ;; More compile-time-macros (eval-when-compile (defmacro save-buffer-state-x (&rest body) ; similar to EMACS/lazy-lock.el - (let ((modified (with-no-warnings (gensym "save-buffer-state-x-modified-")))) - `(let ((,modified (buffer-modified-p))) - (unwind-protect - (let ((buffer-undo-list t) (inhibit-read-only t) - ,@(unless (featurep 'xemacs) - '((inhibit-point-motion-hooks t) deactivate-mark)) - (inhibit-modification-hooks t) - buffer-file-name buffer-file-truename) - ,@body) - (and (not ,modified) (buffer-modified-p) - (set-buffer-modified-p nil))))))) -(put 'save-buffer-state-x 'lisp-indent-function 0) + (declare (debug t) (indent 0)) + `(let ((inhibit-point-motion-hooks t)) + (with-silent-modifications + ,@body)))) (defvar outline-level) (defvar imenu-use-markers) @@ -188,7 +180,7 @@ ;; Additional to the `defalias' below, we must set `antlr-c-forward-sws' to ;; `c-forward-syntactic-ws' when `c-forward-sws' is not defined after requiring ;; cc-mode. -(defalias 'antlr-c-forward-sws 'c-forward-sws) +(defalias 'antlr-c-forward-sws #'c-forward-sws) ;;;;########################################################################## @@ -231,7 +223,6 @@ value of `antlr-language' if the first group in the string matched by REGEXP in `antlr-language-limit-n-regexp' is one of the OPTION-VALUEs. An OPTION-VALUE of nil denotes the fallback element. MODELINE-STRING is also displayed in the mode line next to \"Antlr\"." - :group 'antlr :type '(repeat (group :value (java-mode "") (function :tag "Major mode") (string :tag "Mode line string") @@ -245,7 +236,6 @@ also displayed in the mode line next to \"Antlr\"." Looks like \(LIMIT . REGEXP). Search for REGEXP from the beginning of the buffer to LIMIT and use the first group in the matched string to set the language according to `antlr-language-alist'." - :group 'antlr :type '(cons (choice :tag "Limit" (const :tag "No" nil) (integer :value 0)) regexp)) @@ -259,7 +249,6 @@ the language according to `antlr-language-alist'." If nil, the actions with their surrounding braces are hidden. If a number, do not hide the braces, only hide the contents if its length is greater than this number." - :group 'antlr :type '(choice (const :tag "Completely hidden" nil) (integer :tag "Hidden if longer than" :value 3))) @@ -268,7 +257,6 @@ greater than this number." If nil, no continuation line of a block comment is changed. If t, they are changed according to `c-indentation-line'. When not nil and not t, they are only changed by \\[antlr-indent-command]." - :group 'antlr :type '(radio (const :tag "No" nil) (const :tag "Always" t) (sexp :tag "With TAB" :format "%t" :value tab))) @@ -282,7 +270,6 @@ The first element whose MAJOR-MODE is nil or equal to `major-mode' and whose REGEXP is nil or matches variable `buffer-file-name' is used to set `tab-width' and `indent-tabs-mode'. This is useful to support both ANTLR's and Java's indentation styles. Used by `antlr-set-tabs'." - :group 'antlr :type '(repeat (group :value (antlr-mode nil 8 nil) (choice (const :tag "All" nil) (function :tag "Major mode")) @@ -294,14 +281,12 @@ ANTLR's and Java's indentation styles. Used by `antlr-set-tabs'." "If non-nil, cc-mode indentation style used for `antlr-mode'. See `c-set-style' and for details, where the most interesting part in `c-style-alist' is the value of `c-basic-offset'." - :group 'antlr :type '(choice (const nil) regexp)) (defcustom antlr-indent-item-regexp "[]}):;|&]" ; & is local ANTLR extension (SGML's and-connector) "Regexp matching lines which should be indented by one TAB less. See `antlr-indent-line' and command \\[antlr-indent-command]." - :group 'antlr :type 'regexp) (defcustom antlr-indent-at-bol-alist @@ -316,7 +301,6 @@ If `antlr-language' equals to a MODE, the line starting at the first non-whitespace is matched by the corresponding REGEXP, and the line is part of a header action, indent the line at column 0 instead according to the normal rules of `antlr-indent-line'." - :group 'antlr :type '(repeat (cons (function :tag "Major mode") regexp))) ;; adopt indentation to cc-engine @@ -337,7 +321,6 @@ to the normal rules of `antlr-indent-line'." "Non-nil, if the major mode menu should include option submenus. If nil, the menu just includes a command to insert options. Otherwise, it includes four submenus to insert file/grammar/rule/subrule options." - :group 'antlr :type 'boolean) (defcustom antlr-tool-version 20701 @@ -349,7 +332,6 @@ version correct option values when using \\[antlr-insert-option]. Don't use a number smaller than 20600 since the stored history of Antlr's options starts with v2.06.00, see `antlr-options-alists'. You can make this variable buffer-local." - :group 'antlr :type 'integer) (defcustom antlr-options-auto-colon t @@ -358,7 +340,6 @@ A `:' is only inserted if this value is non-nil, if a rule or subrule option is inserted with \\[antlr-insert-option], if there was no rule or subrule options section before, and if a `:' is not already present after the section, ignoring whitespace, comments and the init action." - :group 'antlr :type 'boolean) (defcustom antlr-options-style nil @@ -369,7 +350,6 @@ identifier. The only style symbol used in the default value of `antlr-options-alist' is `language-as-string'. See also `antlr-read-value'." - :group 'antlr :type '(repeat (symbol :tag "Style symbol"))) (defcustom antlr-options-push-mark t @@ -380,7 +360,6 @@ number, only set mark if point was outside the options area before and the number of lines between point and the insert position is greater than this value. Otherwise, only set mark if point was outside the options area before." - :group 'antlr :type '(radio (const :tag "No" nil) (const :tag "Always" t) (integer :tag "Lines between" :value 10) @@ -391,7 +370,6 @@ options area before." This string is only used if the option to insert did not exist before or if there was no `=' after it. In other words, the spacing around an existing `=' won't be changed when changing an option value." - :group 'antlr :type 'string) @@ -576,13 +554,11 @@ AS-STRING is non-nil and is either t or a symbol which is a member of "Command used in \\[antlr-run-tool] to run the Antlr tool. This variable should include all options passed to Antlr except the option \"-glib\" which is automatically suggested if necessary." - :group 'antlr :type 'string) (defcustom antlr-ask-about-save t "If not nil, \\[antlr-run-tool] asks which buffers to save. Otherwise, it saves all modified buffers before running without asking." - :group 'antlr :type 'boolean) (defcustom antlr-makefile-specification @@ -604,7 +580,6 @@ Then, GEN-VAR is a string with the name of the variable which contains the file names of all makefile rules. GEN-VAR-FORMAT is a format string producing the variable of each target with substitution COUNT/%d where COUNT starts with 1. GEN-SEP is used to separate long variable values." - :group 'antlr :type '(list (string :tag "Rule separator") (choice (const :tag "Direct targets" nil) @@ -683,7 +658,6 @@ DIRECTORY is the name of the current directory.") "Non-nil, if a \"Index\" menu should be added to the menubar. If it is a string, it is used instead \"Index\". Requires package imenu." - :group 'antlr :type '(choice (const :tag "No menu" nil) (const :tag "Index menu" t) (string :tag "Other menu name"))) @@ -780,7 +754,6 @@ bound to `antlr-language'. For example, with value ((java-mode . 2) (c++-mode . 0)) Java actions are fontified with level 2 and C++ actions are not fontified at all." - :group 'antlr :type '(choice (const :tag "None" none) (const :tag "Inherit" inherit) (const :tag "Default" nil) @@ -824,52 +797,45 @@ in the grammar's actions and semantic predicates, see (defface antlr-default '((t nil)) "Face to prevent strings from language dependent highlighting. -Do not change." - :group 'antlr) +Do not change.") (defface antlr-keyword (cond-emacs-xemacs '((((class color) (background light)) (:foreground "black" :EMACS :weight bold :XEMACS :bold t)) (t :inherit font-lock-keyword-face))) - "ANTLR keywords." - :group 'antlr) + "ANTLR keywords.") (defface antlr-syntax (cond-emacs-xemacs '((((class color) (background light)) (:foreground "black" :EMACS :weight bold :XEMACS :bold t)) (t :inherit font-lock-constant-face))) - "ANTLR syntax symbols like :, |, (, ), ...." - :group 'antlr) + "ANTLR syntax symbols like :, |, (, ), ....") (defface antlr-ruledef (cond-emacs-xemacs '((((class color) (background light)) (:foreground "blue" :EMACS :weight bold :XEMACS :bold t)) (t :inherit font-lock-function-name-face))) - "ANTLR rule references (definition)." - :group 'antlr) + "ANTLR rule references (definition).") (defface antlr-tokendef (cond-emacs-xemacs '((((class color) (background light)) (:foreground "blue" :EMACS :weight bold :XEMACS :bold t)) (t :inherit font-lock-function-name-face))) - "ANTLR token references (definition)." - :group 'antlr) + "ANTLR token references (definition).") (defface antlr-ruleref '((((class color) (background light)) (:foreground "blue4")) (t :inherit font-lock-type-face)) - "ANTLR rule references (usage)." - :group 'antlr) + "ANTLR rule references (usage).") (defface antlr-tokenref '((((class color) (background light)) (:foreground "orange4")) (t :inherit font-lock-type-face)) - "ANTLR token references (usage)." - :group 'antlr) + "ANTLR token references (usage).") (defface antlr-literal (cond-emacs-xemacs @@ -878,8 +844,7 @@ Do not change." (t :inherit font-lock-string-face))) "ANTLR special literal tokens. It is used to highlight strings matched by the first regexp group of -`antlr-font-lock-literal-regexp'." - :group 'antlr) +`antlr-font-lock-literal-regexp'.") (defcustom antlr-font-lock-literal-regexp "\"\\(\\sw\\(\\sw\\|-\\)*\\)\"" "Regexp matching literals with special syntax highlighting, or nil. @@ -887,7 +852,6 @@ If nil, there is no special syntax highlighting for some literals. Otherwise, it should be a regular expression which must contain a regexp group. The string matched by the first group is highlighted with `antlr-font-lock-literal-face'." - :group 'antlr :type '(choice (const :tag "None" nil) regexp)) (defvar antlr-class-header-regexp @@ -1016,15 +980,6 @@ Used for `antlr-slow-syntactic-context'.") ;;;=========================================================================== ;; From help.el (XEmacs-21.1), without `copy-syntax-table' -(defmacro antlr-with-syntax-table (syntab &rest body) - "Evaluate BODY with the syntax table SYNTAB." - `(let ((stab (syntax-table))) - (unwind-protect - (progn (set-syntax-table ,syntab) ,@body) - (set-syntax-table stab)))) -(put 'antlr-with-syntax-table 'lisp-indent-function 1) -(put 'antlr-with-syntax-table 'edebug-form-spec '(form body)) - (defunx antlr-default-directory () :xemacs-and-try default-directory "Return `default-directory'." @@ -1229,7 +1184,8 @@ See `antlr-font-lock-additional-keywords', `antlr-language' and antlr-font-lock-keywords-alist)) (if (eq antlr-font-lock-maximum-decoration 'inherit) font-lock-maximum-decoration - antlr-font-lock-maximum-decoration))))))) + antlr-font-lock-maximum-decoration))) + t)))) ;;;=========================================================================== @@ -1248,7 +1204,7 @@ IF TOKENREFS-ONLY is non-nil, just return alist with tokenref names." (continue t)) ;; The generic imenu function searches backward, which is slower ;; and more likely not to work during editing. - (antlr-with-syntax-table antlr-action-syntax-table + (with-syntax-table antlr-action-syntax-table (antlr-invalidate-context-cache) (goto-char (point-min)) (antlr-skip-file-prelude t) @@ -1392,7 +1348,7 @@ Move to the beginning of the current rule if point is inside a rule." A grammar class header and the file prelude are also considered as a rule." (save-excursion - (antlr-with-syntax-table antlr-action-syntax-table + (with-syntax-table antlr-action-syntax-table (not (antlr-outside-rule-p))))) (defunx antlr-end-of-rule (&optional arg) @@ -1403,7 +1359,7 @@ rule. If ARG is zero, run `antlr-end-of-body'." (interactive "_p") (if (zerop arg) (antlr-end-of-body) - (antlr-with-syntax-table antlr-action-syntax-table + (with-syntax-table antlr-action-syntax-table (antlr-next-rule arg nil)))) (defunx antlr-beginning-of-rule (&optional arg) @@ -1414,7 +1370,7 @@ of rule. If ARG is zero, run `antlr-beginning-of-body'." (interactive "_p") (if (zerop arg) (antlr-beginning-of-body) - (antlr-with-syntax-table antlr-action-syntax-table + (with-syntax-table antlr-action-syntax-table (antlr-next-rule (- arg) t)))) (defunx antlr-end-of-body (&optional msg) @@ -1422,7 +1378,7 @@ of rule. If ARG is zero, run `antlr-beginning-of-body'." A grammar class header is also considered as a rule. With optional prefix arg MSG, move to `:'." (interactive "_") - (antlr-with-syntax-table antlr-action-syntax-table + (with-syntax-table antlr-action-syntax-table (let ((orig (point))) (if (antlr-outside-rule-p) (error "Outside an ANTLR rule")) @@ -1458,7 +1414,7 @@ If non-nil, TRANSFORM is used on literals instead of `downcase-region'." (let ((literals 0)) (save-excursion (goto-char (point-min)) - (antlr-with-syntax-table antlr-action-syntax-table + (with-syntax-table antlr-action-syntax-table (antlr-invalidate-context-cache) (while (antlr-re-search-forward "\"\\(\\sw\\(\\sw\\|-\\)*\\)\"" nil) (funcall transform (match-beginning 0) (match-end 0)) @@ -1487,7 +1443,7 @@ Display a message unless optional argument SILENT is non-nil." (antlr-hide-actions 0 t) (save-excursion (goto-char (point-min)) - (antlr-with-syntax-table antlr-action-syntax-table + (with-syntax-table antlr-action-syntax-table (antlr-invalidate-context-cache) (while (antlr-re-search-forward regexp nil) (let ((beg (ignore-errors-x (scan-sexps (point) -1)))) @@ -1708,7 +1664,7 @@ is undefined." (widen) (if (eq requested 1) 1 - (antlr-with-syntax-table antlr-action-syntax-table + (with-syntax-table antlr-action-syntax-table (antlr-invalidate-context-cache) (let* ((orig (point)) (outsidep (antlr-outside-rule-p)) @@ -2086,7 +2042,7 @@ its export vocabulary is used as an import vocabulary." (unless buffer-file-name (error "Grammar buffer does not visit a file")) (let (classes export-vocabs import-vocabs superclasses default-vocab) - (antlr-with-syntax-table antlr-action-syntax-table + (with-syntax-table antlr-action-syntax-table (goto-char (point-min)) (while (antlr-re-search-forward antlr-class-header-regexp nil) ;; parse class definition -------------------------------------------- @@ -2385,7 +2341,7 @@ to a lesser extent, `antlr-tab-offset-alist'." (skip-chars-forward " \t") (setq boi (point)) ;; check syntax at beginning of indentation ---------------------------- - (antlr-with-syntax-table antlr-action-syntax-table + (with-syntax-table antlr-action-syntax-table (antlr-invalidate-context-cache) (setq syntax (antlr-syntactic-context)) (cond ((symbolp syntax) @@ -2481,7 +2437,7 @@ ANTLR's syntax and influences the auto indentation, see (interactive "*P") (if (or arg (save-excursion (skip-chars-backward " \t") (not (bolp))) - (antlr-with-syntax-table antlr-action-syntax-table + (with-syntax-table antlr-action-syntax-table (antlr-invalidate-context-cache) (let ((context (antlr-syntactic-context))) (not (and (numberp context) @@ -2524,7 +2480,7 @@ ANTLR's syntax and influences the auto indentation, see (while settings (when (boundp (car settings)) (ignore-errors - (set (car settings) (eval (cadr settings))))) + (set (car settings) (eval (cadr settings) t)))) (setq settings (cddr settings))))) (defun antlr-language-option (search) @@ -2583,8 +2539,8 @@ the default language." (antlr-c-init-language-vars))) ; do it myself (c-basic-common-init antlr-language (or antlr-indent-style "gnu")) (set (make-local-variable 'outline-regexp) "[^#\n\^M]") - (set (make-local-variable 'outline-level) 'c-outline-level) ;TODO: define own - (set (make-local-variable 'indent-line-function) 'antlr-indent-line) + (set (make-local-variable 'outline-level) #'c-outline-level) ;TODO: define own + (set (make-local-variable 'indent-line-function) #'antlr-indent-line) (set (make-local-variable 'indent-region-function) nil) ; too lazy (setq comment-start "// " comment-end "" @@ -2594,7 +2550,7 @@ the default language." (when (featurep 'xemacs) (easy-menu-add antlr-mode-menu)) (set (make-local-variable 'imenu-create-index-function) - 'antlr-imenu-create-index-function) + #'antlr-imenu-create-index-function) (set (make-local-variable 'imenu-generic-expression) t) ; fool stupid test (and antlr-imenu-name ; there should be a global variable... (fboundp 'imenu-add-to-menubar) diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el index 0b70c11b29..fb84596ad3 100644 --- a/test/lisp/emacs-lisp/bytecomp-tests.el +++ b/test/lisp/emacs-lisp/bytecomp-tests.el @@ -495,6 +495,7 @@ Subtests signal errors if something goes wrong." (insert "\n")))) (defun test-byte-comp-compile-and-load (compile &rest forms) + (declare (indent 1)) (let ((elfile nil) (elcfile nil)) (unwind-protect @@ -513,7 +514,6 @@ Subtests signal errors if something goes wrong." (load elfile nil 'nomessage)) (when elfile (delete-file elfile)) (when elcfile (delete-file elcfile))))) -(put 'test-byte-comp-compile-and-load 'lisp-indent-function 1) (ert-deftest test-byte-comp-macro-expansion () (test-byte-comp-compile-and-load t diff --git a/test/lisp/emacs-lisp/generator-tests.el b/test/lisp/emacs-lisp/generator-tests.el index ffcd16ad09..a1b9f64fdb 100644 --- a/test/lisp/emacs-lisp/generator-tests.el +++ b/test/lisp/emacs-lisp/generator-tests.el @@ -45,6 +45,7 @@ BODY twice: once using ordinary `eval' and once using lambda-generators. The test ensures that the two forms produce identical output." + (declare (indent 1)) `(progn (ert-deftest ,name () (should @@ -62,8 +63,6 @@ identical output." (let ((cps-inhibit-atomic-optimization t)) (iter-lambda () (iter-yield (progn ,@body))))))))))) -(put 'cps-testcase 'lisp-indent-function 1) - (defvar *cps-test-i* nil) (defun cps-get-test-i () *cps-test-i*) commit f1fa35f0914f5de6d0dbfde9cd00cc7ab1b20ebd Author: Lars Ingebrigtsen Date: Mon Feb 22 16:47:38 2021 +0100 Fix ANSI coloring problem in large outputs in eshell * lisp/ansi-color.el (ansi-color-apply-on-region): Ensure that we fontize from where we left off, and don't skip to the end of the region (bug#46332). diff --git a/lisp/ansi-color.el b/lisp/ansi-color.el index e5bfccdb8b..44dc0351d4 100644 --- a/lisp/ansi-color.el +++ b/lisp/ansi-color.el @@ -429,7 +429,8 @@ being deleted." ;; positions that overlap regions previously colored; these ;; `codes' should not be applied to that overlap, so we need ;; to know where they should really start. - (setq ansi-color-context-region (if codes (list codes end-marker))))) + (setq ansi-color-context-region + (if codes (list codes (copy-marker (point))))))) ;; Clean up our temporary markers. (unless (eq start-marker (cadr ansi-color-context-region)) (set-marker start-marker nil)) commit f8d87590592544cacbeed091f3557e02bb0e63ce Author: Julian Scheid Date: Mon Feb 22 16:06:03 2021 +0100 cl-extra: Fix docstring retrieval * lisp/emacs-lisp/cl-extra.el (cl--describe-class-slots): Fix docstring retrieval (bug#46662). diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el index 28ce6b115a..84199c1612 100644 --- a/lisp/emacs-lisp/cl-extra.el +++ b/lisp/emacs-lisp/cl-extra.el @@ -898,8 +898,8 @@ Outputs to the current buffer." (list (cl-prin1-to-string (cl--slot-descriptor-name slot)) (cl-prin1-to-string (cl--slot-descriptor-type slot)) (cl-prin1-to-string (cl--slot-descriptor-initform slot)) - (let ((doc (alist-get :documentation - (cl--slot-descriptor-props slot)))) + (let ((doc (plist-get (cl--slot-descriptor-props slot) + :documentation))) (if (not doc) "" (setq has-doc t) (substitute-command-keys doc))))) commit a728135a2b551917588425d9758c6cc932cb591b Author: Robert Pluim Date: Mon Feb 22 15:05:48 2021 +0100 Skip tests that require Internet when there's no Internet Bug#46641 The network-stream-tests actually work fine when the local machine has no IP at all, but cause a crash in the GnuTLS library when there is an IP configured but the interface is down. * test/lisp/net/network-stream-tests.el (internet-is-working): New defvar, checks if we can resolve "google.com". (connect-to-tls-ipv4-nowait, connect-to-tls-ipv6-nowait) (open-network-stream-tls-nowait, open-gnutls-stream-new-api-nowait) (open-gnutls-stream-old-api-nowait): Use it to check for working Internet access. * test/src/process-tests.el (internet-is-working): New defvar, checks if we can resolve "google.com". (lookup-family-specification, lookup-unicode-domains) (unibyte-domain-name, lookup-google, non-existent-lookup-failure): Use it to check for working Internet access. diff --git a/test/lisp/net/network-stream-tests.el b/test/lisp/net/network-stream-tests.el index e0a06a28ee..0fb24d2701 100644 --- a/test/lisp/net/network-stream-tests.el +++ b/test/lisp/net/network-stream-tests.el @@ -32,6 +32,13 @@ ;; it pulls in nsm, which then makes the :nowait t' tests fail unless ;; we disable the nsm, which we do by binding 'network-security-level' +;; Check if the Internet seems to be working. Mainly to pacify +;; Debian's CI system. +(defvar internet-is-working + (progn + (require 'dns) + (dns-query "google.com"))) + (ert-deftest make-local-unix-server () (skip-unless (featurep 'make-network-process '(:family local))) (let* ((file (make-temp-name "/tmp/server-test")) @@ -291,6 +298,7 @@ (ert-deftest connect-to-tls-ipv4-nowait () (skip-unless (executable-find "gnutls-serv")) (skip-unless (gnutls-available-p)) + (skip-unless internet-is-working) (let ((server (make-tls-server 44331)) (times 0) (network-security-level 'low) @@ -333,6 +341,7 @@ (ert-deftest connect-to-tls-ipv6-nowait () (skip-unless (executable-find "gnutls-serv")) (skip-unless (gnutls-available-p)) + (skip-unless internet-is-working) (skip-unless (not (eq system-type 'windows-nt))) (skip-unless (featurep 'make-network-process '(:family ipv6))) (let ((server (make-tls-server 44333)) @@ -417,6 +426,7 @@ (ert-deftest open-network-stream-tls-nowait () (skip-unless (executable-find "gnutls-serv")) (skip-unless (gnutls-available-p)) + (skip-unless internet-is-working) (let ((server (make-tls-server 44335)) (times 0) (network-security-level 'low) @@ -645,6 +655,7 @@ (ert-deftest open-gnutls-stream-new-api-nowait () (skip-unless (executable-find "gnutls-serv")) (skip-unless (gnutls-available-p)) + (skip-unless internet-is-working) (let ((server (make-tls-server 44668)) (times 0) (network-security-level 'low) @@ -683,6 +694,7 @@ (ert-deftest open-gnutls-stream-old-api-nowait () (skip-unless (executable-find "gnutls-serv")) (skip-unless (gnutls-available-p)) + (skip-unless internet-is-working) (let ((server (make-tls-server 44669)) (times 0) (network-security-level 'low) diff --git a/test/src/process-tests.el b/test/src/process-tests.el index e62bcb3f7c..17aef30a43 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -348,8 +348,7 @@ See Bug#30460." invocation-directory)) :stop t)))) -;; All the following tests require working DNS, which appears not to -;; be the case for hydra.nixos.org, so disable them there for now. +;; The following tests require working DNS ;; This will need updating when IANA assign more IPv6 global ranges. (defun ipv6-is-available () @@ -360,9 +359,16 @@ See Bug#30460." (= (logand (aref elt 0) #xe000) #x2000))) (network-interface-list)))) +;; Check if the Internet seems to be working. Mainly to pacify +;; Debian's CI system. +(defvar internet-is-working + (progn + (require 'dns) + (dns-query "google.com"))) + (ert-deftest lookup-family-specification () "`network-lookup-address-info' should only accept valid family symbols." - (skip-unless (not (getenv "EMACS_HYDRA_CI"))) + (skip-unless internet-is-working) (with-timeout (60 (ert-fail "Test timed out")) (should-error (network-lookup-address-info "localhost" 'both)) (should (network-lookup-address-info "localhost" 'ipv4)) @@ -371,20 +377,20 @@ See Bug#30460." (ert-deftest lookup-unicode-domains () "Unicode domains should fail." - (skip-unless (not (getenv "EMACS_HYDRA_CI"))) + (skip-unless internet-is-working) (with-timeout (60 (ert-fail "Test timed out")) (should-error (network-lookup-address-info "faß.de")) (should (network-lookup-address-info (puny-encode-domain "faß.de"))))) (ert-deftest unibyte-domain-name () "Unibyte domain names should work." - (skip-unless (not (getenv "EMACS_HYDRA_CI"))) + (skip-unless internet-is-working) (with-timeout (60 (ert-fail "Test timed out")) (should (network-lookup-address-info (string-to-unibyte "google.com"))))) (ert-deftest lookup-google () "Check that we can look up google IP addresses." - (skip-unless (not (getenv "EMACS_HYDRA_CI"))) + (skip-unless internet-is-working) (with-timeout (60 (ert-fail "Test timed out")) (let ((addresses-both (network-lookup-address-info "google.com")) (addresses-v4 (network-lookup-address-info "google.com" 'ipv4))) @@ -396,10 +402,12 @@ See Bug#30460." (ert-deftest non-existent-lookup-failure () "Check that looking up non-existent domain returns nil." - (skip-unless (not (getenv "EMACS_HYDRA_CI"))) + (skip-unless internet-is-working) (with-timeout (60 (ert-fail "Test timed out")) (should (eq nil (network-lookup-address-info "emacs.invalid"))))) +;; End of tests requiring DNS + (defmacro process-tests--ignore-EMFILE (&rest body) "Evaluate BODY, ignoring EMFILE errors." (declare (indent 0) (debug t)) commit 934dcc21572e3f0e5357d84050e04b23d41a18f9 Author: Robert Pluim Date: Mon Feb 22 14:47:41 2021 +0100 Fix hang when running dns-query with no working internet * lisp/net/dns.el (dns-set-servers): reduce the timeout and retry count when using 'nslookup' for "localhost". (dns-query): Check to see if we actually managed to initiate a dns request before starting a busy-wait for the result. diff --git a/lisp/net/dns.el b/lisp/net/dns.el index 2045d4dfca..90776e3c6f 100644 --- a/lisp/net/dns.el +++ b/lisp/net/dns.el @@ -332,7 +332,7 @@ Parses \"/etc/resolv.conf\" or calls \"nslookup\"." (setq dns-servers (nreverse dns-servers)))) (when (executable-find "nslookup") (with-temp-buffer - (call-process "nslookup" nil t nil "localhost") + (call-process "nslookup" nil t nil "-retry=0" "-timeout=2" "localhost") (goto-char (point-min)) (when (re-search-forward "^Address:[ \t]*\\([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+\\|[[:xdigit:]:]*\\)" nil t) @@ -492,19 +492,22 @@ If REVERSE, look up an IP address." (dns-get-txt-answer (dns-get 'answers result)) (dns-get 'data answer)))))))))) +;;;###autoload (defun dns-query (name &optional type full reverse) "Query a DNS server for NAME of TYPE. If FULL, return the entire record returned. If REVERSE, look up an IP address." - (let ((result nil)) - (dns-query-asynchronous - name - (lambda (response) - (setq result (list response))) - type full reverse) - ;; Loop until we get the callback. - (while (not result) - (sleep-for 0.01)) + (let* ((result nil) + (query-started + (dns-query-asynchronous + name + (lambda (response) + (setq result (list response))) + type full reverse))) + (if query-started + ;; Loop until we get the callback. + (while (not result) + (sleep-for 0.01))) (car result))) (provide 'dns) commit 0c170c64b178da1df05d953d993e992b8bdc2502 Author: Lars Ingebrigtsen Date: Mon Feb 22 15:47:30 2021 +0100 Simplify comint-watch-for-password-prompt * lisp/comint.el (comint-watch-for-password-prompt): Simplify by using `string-trim'. diff --git a/lisp/comint.el b/lisp/comint.el index ea69c3b1f1..5c307febe2 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -104,6 +104,7 @@ (require 'ring) (require 'ansi-color) (require 'regexp-opt) ;For regexp-opt-charset. +(eval-when-compile (require 'subr-x)) ;; Buffer Local Variables: ;;============================================================================ @@ -2430,14 +2431,11 @@ This function could be in the list `comint-output-filter-functions'." (when (let ((case-fold-search t)) (string-match comint-password-prompt-regexp (replace-regexp-in-string "\r" "" string))) - (when (string-match "^[ \n\r\t\v\f\b\a]+" string) - (setq string (replace-match "" t t string))) - (when (string-match "\n+\\'" string) - (setq string (replace-match "" t t string))) (let ((comint--prompt-recursion-depth (1+ comint--prompt-recursion-depth))) (if (> comint--prompt-recursion-depth 10) (message "Password prompt recursion too deep") - (comint-send-invisible string))))) + (comint-send-invisible + (string-trim string "[ \n\r\t\v\f\b\a]+" "\n+")))))) ;; Low-level process communication commit c1712f55070d1fe861517d2c1a9fe53622f0e6a6 Author: Lars Ingebrigtsen Date: Mon Feb 22 15:32:34 2021 +0100 Fix prompt for the `M-S-x' command * lisp/simple.el (read-extended-command): Further kludge the hard-coded "M-x" prompt for the new `M-S-x' command. diff --git a/lisp/simple.el b/lisp/simple.el index 26710e6d53..1dfc3374ad 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1980,7 +1980,9 @@ This function uses the `read-extended-command-predicate' user option." ;; but actually a prompt other than "M-x" would be confusing, ;; because "M-x" is a well-known prompt to read a command ;; and it serves as a shorthand for "Extended command: ". - "M-x ") + (if (memq 'shift (event-modifiers last-command-event)) + "M-X " + "M-x ")) (lambda (string pred action) (if (and suggest-key-bindings (eq action 'metadata)) '(metadata commit 331e49df4577f6c3542a9fcf7275f7c6eff3250d Author: Stefan Kangas Date: Mon Feb 22 12:17:41 2021 +0100 Prefer mailing lists to newsgroups in FAQ * doc/misc/efaq.texi (Real meaning of copyleft) (Guidelines for mailing list postings, Mailing list archives) (Packages that do not come with Emacs): Prefer mailing lists to newsgroups. (Bug#46633) diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi index 6f0a81b4f8..53a3af4b78 100644 --- a/doc/misc/efaq.texi +++ b/doc/misc/efaq.texi @@ -323,8 +323,8 @@ Free Software Foundation, and related organizations. @menu * Real meaning of copyleft:: -* Guidelines for newsgroup postings:: -* Newsgroup archives:: +* Guidelines for mailing list postings:: +* Mailing list archives:: * Reporting bugs:: * Unsubscribing from Emacs lists:: * Contacting the FSF:: @@ -343,9 +343,10 @@ There has never been a copyright infringement case involving the GPL to set any precedents. Although legal actions have been brought against companies for violating the terms of the GPL, so far all have been settled out of court (in favor of the plaintiffs). Please take any -discussion regarding this issue to the newsgroup -@uref{news:gnu.misc.discuss}, which was created to hold the extensive -flame wars on the subject. +discussion regarding this issue to +@uref{https://lists.gnu.org/mailman/listinfo/gnu-misc-discuss, the +gnu-misc-discuss mailing list}, which was created to hold the +extensive flame wars on the subject. RMS writes: @@ -359,54 +360,60 @@ distribute any version of Emacs or a related program, and give the recipients the same freedom that you enjoyed. @end quotation -@node Guidelines for newsgroup postings -@section What are appropriate messages for the various Emacs newsgroups? +@node Guidelines for mailing list postings +@section What are appropriate messages for the various Emacs mailing lists? @cindex Newsgroups, appropriate messages for @cindex GNU newsgroups, appropriate messages for +@cindex GNU mailing lists, appropriate messages for @cindex Usenet groups, appropriate messages for @cindex Mailing lists, appropriate messages for -@cindex Posting messages to newsgroups +@cindex Posting messages to mailing lists @cindex GNU mailing lists The Emacs mailing lists are described at @uref{https://savannah.gnu.org/mail/?group=emacs, the Emacs Savannah -page}. Some of them are gatewayed to newsgroups. +page}. -The newsgroup @uref{news:comp.emacs} is for discussion of Emacs programs -in general. The newsgroup @uref{news:gnu.emacs.help} is specifically -for GNU Emacs. It therefore makes no sense to cross-post to both -groups, since only one can be appropriate to any question. +Messages advocating ``non-free'' software are considered unacceptable +on any of the GNU mailing lists, except for +@url{https://lists.gnu.org/mailman/listinfo/gnu-misc-discuss, the +gnu-misc-discuss mailing list} which was created to hold the extensive +flame-wars on the subject. -Messages advocating ``non-free'' software are considered unacceptable on -any of the @code{gnu.*} newsgroups except for @uref{news:gnu.misc.discuss}, -which was created to hold the extensive flame-wars on the subject. -``Non-free'' software includes any software for which the end user can't -freely modify the source code and exchange enhancements. Be careful to -remove the @code{gnu.*} groups from the @samp{Newsgroups:} line when -posting a followup that recommends such software. +``Non-free'' software includes any software for which the end user +can't freely modify the source code and exchange enhancements. Be +careful to remove any GNU mailing lists from @samp{Cc:} when posting a +reply that recommends such software. -@uref{news:gnu.emacs.bug} is a place where bug reports appear, but avoid -posting bug reports to this newsgroup directly (@pxref{Reporting bugs}). +@url{https://lists.gnu.org/mailman/listinfo/bug-gnu-emacs, The +bug-gnu-emacs list} is a place where bug reports appear, but we +recommend using the commands @kbd{M-x report-emacs-bug} or @kbd{M-x +submit-emacs-patch} if at all possible (@pxref{Reporting bugs}). + +Some GNU mailing lists are gatewayed to (Usenet) newsgroups. +For example, sending an email to +@url{https://lists.gnu.org/mailman/listinfo/bug-gnu-emacs, The +bug-gnu-emacs list} has the effect of posting on the newsgroup +@uref{news:gnu.emacs.help}). Finally, we recommend reading the @url{https://www.gnu.org/philosophy/kind-communication.html, GNU Kind Communications Guidelines} before posting to any GNU lists or newsgroups. -@node Newsgroup archives -@section Where can I get old postings to @uref{news:gnu.emacs.help} and other GNU groups? -@cindex Archived postings from @code{gnu.emacs.help} -@cindex Usenet archives for GNU groups -@cindex Old Usenet postings for GNU groups +@node Mailing list archives +@section Where can I read archives for @code{help-gnu-emacs} and other GNU lists? +@cindex Archived postings from @code{help-gnu-emacs} +@cindex Old mailing list posts for GNU lists +@cindex Mailing list archives for GNU lists The FSF has maintained archives of all of the GNU mailing lists for many years, although there may be some unintentional gaps in coverage. The archive can be browsed over the web at @uref{https://lists.gnu.org/r/, the GNU mail archive}. -Web-based Usenet search services, such as -@uref{https://groups.google.com/groups/dir?q=gnu&, Google}, also -archive the @code{gnu.*} groups. +Some web-based Usenet search services also archive the @code{gnu.*} +newsgroups. @node Reporting bugs @section Where should I report bugs and other problems with Emacs? @@ -419,39 +426,25 @@ The correct way to report Emacs bugs is to use the command @kbd{M-x report-emacs-bug}. It sets up a mail buffer with the essential information and the correct e-mail address, @email{bug-gnu-emacs@@gnu.org}. -Anything sent there also appears in the -newsgroup @uref{news:gnu.emacs.bug}, but please use e-mail instead of -news to submit the bug report. This ensures a reliable return address -so you can be contacted for further details. Be sure to read the ``Bugs'' section of the Emacs manual before reporting a bug! The manual describes in detail how to submit a useful bug report (@pxref{Bugs, , Reporting Bugs, emacs, The GNU Emacs Manual}). (@xref{Emacs manual}, if you don't know how to read the manual.) -RMS says: - -@quotation Sending bug reports to -@url{https://lists.gnu.org/mailman/listinfo/help-gnu-emacs, -the help-gnu-emacs mailing list} -(which has the effect of posting on @uref{news:gnu.emacs.help}) is -undesirable because it takes the time of an unnecessarily large group -of people, most of whom are just users and have no idea how to fix -these problem. -@url{https://lists.gnu.org/mailman/listinfo/bug-gnu-emacs, The -bug-gnu-emacs list} reaches a much smaller group of people who are +@url{https://lists.gnu.org/mailman/listinfo/help-gnu-emacs, the +help-gnu-emacs mailing list} is undesirable because it takes the time +of an unnecessarily large group of people, most of whom are just users +and have no idea how to fix these +problem. @url{https://lists.gnu.org/mailman/listinfo/bug-gnu-emacs, +The bug-gnu-emacs list} reaches a much smaller group of people who are more likely to know what to do and have expressed a wish to receive more messages about Emacs than the others. -@end quotation - -RMS says it is sometimes fine to post to @uref{news:gnu.emacs.help}: -@quotation If you have reported a bug and you don't hear about a possible fix, then after a suitable delay (such as a week) it is okay to post on -@code{gnu.emacs.help} asking if anyone can help you. -@end quotation +@code{help-gnu-emacs@@gnu.org} asking if anyone can help you. If you are unsure whether you have found a bug, consider the following non-exhaustive list, courtesy of RMS: @@ -463,6 +456,11 @@ is a bug. If Lisp code does not do what the documentation says it does, that is a bug. @end quotation +Anything sent to @email{bug-gnu-emacs@@gnu.org} also appears in the +newsgroup @uref{news:gnu.emacs.bug}, but please use e-mail instead of +news to submit the bug report. This ensures a reliable return address +so you can be contacted for further details. + @node Unsubscribing from Emacs lists @section How do I unsubscribe from a mailing list? @cindex Unsubscribing from GNU mailing lists @@ -3531,10 +3529,8 @@ installing any nonfree software, we recommend for your freedom's sake that you stay away from it. The @uref{https://lists.gnu.org/mailman/listinfo/gnu-emacs-sources, -GNU Emacs sources mailing list}, which is gatewayed to the -@uref{news:gnu.emacs.sources, Emacs sources newsgroup} (although the -connection between the two can be unreliable) is an official place -where people can post or announce their extensions to Emacs. +GNU Emacs sources mailing list} is an official place where people can +post or announce their extensions to Emacs. The @uref{https://emacswiki.org, Emacs Wiki} contains pointers to some additional extensions. @uref{https://wikemacs.org, WikEmacs} is an commit 7466b10346a3fdde2d3735d6ac09556569c24e5a Author: Stefan Kangas Date: Mon Feb 22 11:56:12 2021 +0100 Improve wrong number of args error message in propertize * src/editfns.c (Fpropertize): Improve error message. (syms_of_editfns) : New DEFSYM. * test/src/editfns-tests.el (propertize/error-wrong-number-of-args): New test. diff --git a/src/editfns.c b/src/editfns.c index 991f79abac..fb20fc9655 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2945,7 +2945,7 @@ usage: (propertize STRING &rest PROPERTIES) */) /* Number of args must be odd. */ if ((nargs & 1) == 0) - error ("Wrong number of arguments"); + xsignal2 (Qwrong_number_of_arguments, Qpropertize, make_fixnum (nargs)); properties = string = Qnil; @@ -4448,6 +4448,7 @@ syms_of_editfns (void) { DEFSYM (Qbuffer_access_fontify_functions, "buffer-access-fontify-functions"); DEFSYM (Qwall, "wall"); + DEFSYM (Qpropertize, "propertize"); DEFVAR_LISP ("inhibit-field-text-motion", Vinhibit_field_text_motion, doc: /* Non-nil means text motion commands don't notice fields. */); diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el index dcec971c12..ea80da4819 100644 --- a/test/src/editfns-tests.el +++ b/test/src/editfns-tests.el @@ -128,6 +128,10 @@ (format (concat "%-3d/" s) 12) #("12 /X" 4 5 (prop "val")))))) +(ert-deftest propertize/error-even-number-of-args () + "Number of args for `propertize' must be odd." + (should-error (propertize "foo" 'bar) :type 'wrong-number-of-arguments)) + ;; Tests for bug#5131. (defun transpose-test-reverse-word (start end) "Reverse characters in a word by transposing pairs of characters." commit 88a02e4c89b1ff6047f13602bb8486706e3adeb4 Author: Mattias Engdegård Date: Mon Feb 22 11:37:29 2021 +0100 Fix compilation of closures with nontrivial doc strings * lisp/emacs-lisp/bytecomp.el (byte-compile-make-closure): Use the supplied doc string if it's a literal; fall back to the old slow way of building a closure otherwise. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 69a63b169c..c0683babcf 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -3818,20 +3818,37 @@ discarding." docstring-exp)) ;Otherwise, we don't need a closure. (cl-assert (byte-code-function-p fun)) (byte-compile-form - ;; Use symbols V0, V1 ... as placeholders for closure variables: - ;; they should be short (to save space in the .elc file), yet - ;; distinct when disassembled. - (let* ((dummy-vars (mapcar (lambda (i) (intern (format "V%d" i))) - (number-sequence 0 (1- (length env))))) - (proto-fun - (apply #'make-byte-code - (aref fun 0) (aref fun 1) - ;; Prepend dummy cells to the constant vector, - ;; to get the indices right when disassembling. - (vconcat dummy-vars (aref fun 2)) - (mapcar (lambda (i) (aref fun i)) - (number-sequence 3 (1- (length fun))))))) - `(make-closure ,proto-fun ,@env)))))) + (if (or (not docstring-exp) (stringp docstring-exp)) + ;; Use symbols V0, V1 ... as placeholders for closure variables: + ;; they should be short (to save space in the .elc file), yet + ;; distinct when disassembled. + (let* ((dummy-vars (mapcar (lambda (i) (intern (format "V%d" i))) + (number-sequence 0 (1- (length env))))) + (opt-args (mapcar (lambda (i) (aref fun i)) + (number-sequence 4 (1- (length fun))))) + (proto-fun + (apply #'make-byte-code + (aref fun 0) (aref fun 1) + ;; Prepend dummy cells to the constant vector, + ;; to get the indices right when disassembling. + (vconcat dummy-vars (aref fun 2)) + (aref fun 3) + (if docstring-exp + (cons docstring-exp (cdr opt-args)) + opt-args)))) + `(make-closure ,proto-fun ,@env)) + ;; Nontrivial doc string expression: create a bytecode object + ;; from small pieces at run time. + `(make-byte-code + ',(aref fun 0) ',(aref fun 1) + (vconcat (vector . ,env) ',(aref fun 2)) + ,@(let ((rest (nthcdr 3 (mapcar (lambda (x) `',x) fun)))) + (if docstring-exp + `(,(car rest) + ,docstring-exp + ,@(cddr rest)) + rest)))) + )))) (defun byte-compile-get-closed-var (form) "Byte-compile the special `internal-get-closed-var' form." commit 0fb6f05bcb179e2f5332776c59b1503f625059b9 Author: Lars Ingebrigtsen Date: Mon Feb 22 05:10:13 2021 +0100 Fix up previous conf-mode.el and nroff-mode.el change slightly * lisp/textmodes/conf-mode.el (conf-mode-map): Remove variable now unused. * lisp/textmodes/nroff-mode.el (nroff-mode-map): Remove variable now unused. diff --git a/lisp/textmodes/conf-mode.el b/lisp/textmodes/conf-mode.el index 8225f0a0fe..5f34ae152d 100644 --- a/lisp/textmodes/conf-mode.el +++ b/lisp/textmodes/conf-mode.el @@ -63,8 +63,7 @@ not align (only setting space according to `conf-assignment-space')." :type 'boolean) (defvar conf-mode-map - (let ((map (make-sparse-keymap)) - (menu-map (make-sparse-keymap))) + (let ((map (make-sparse-keymap))) (define-key map "\C-c\C-u" 'conf-unix-mode) (define-key map "\C-c\C-w" 'conf-windows-mode) (define-key map "\C-c\C-j" 'conf-javaprop-mode) diff --git a/lisp/textmodes/nroff-mode.el b/lisp/textmodes/nroff-mode.el index cd321501f0..7d9b414bf0 100644 --- a/lisp/textmodes/nroff-mode.el +++ b/lisp/textmodes/nroff-mode.el @@ -46,8 +46,7 @@ :type 'boolean) (defvar nroff-mode-map - (let ((map (make-sparse-keymap)) - (menu-map (make-sparse-keymap))) + (let ((map (make-sparse-keymap))) (define-key map "\t" 'tab-to-tab-stop) (define-key map "\e?" 'nroff-count-text-lines) (define-key map "\n" 'nroff-electric-newline) commit 80df15baf33094063989dd08b1c2d8dd8304d6ce Author: Glenn Morris Date: Sun Feb 21 19:11:19 2021 -0800 * test/misc/test-custom-libs.el (test-custom-libs): Skip on hydra. diff --git a/test/misc/test-custom-libs.el b/test/misc/test-custom-libs.el index 70f043d129..aa8eeb7858 100644 --- a/test/misc/test-custom-libs.el +++ b/test/misc/test-custom-libs.el @@ -36,6 +36,8 @@ ;; - lisp/term/ns-win.el ;; - lisp/org/org-num.el (ert-deftest test-custom-libs () + ;; This test is very slow, and IMO not worth the time it takes. + (skip-unless (not (getenv "EMACS_HYDRA_CI"))) :tags '(:expensive-test) :expected-result :failed ; FIXME: See above. (skip-unless (file-readable-p custom-test-admin-cus-test)) commit af17b74a7a45e3f73d3539538b82d0187c329a2e Author: Glenn Morris Date: Sun Feb 21 18:58:14 2021 -0800 * test/misc/test-custom-noloads.el (custom-test-load): Unstable. diff --git a/test/misc/test-custom-noloads.el b/test/misc/test-custom-noloads.el index e999fe2abb..6fa6a6c90d 100644 --- a/test/misc/test-custom-noloads.el +++ b/test/misc/test-custom-noloads.el @@ -35,7 +35,7 @@ ;; FIXME: Multiple failures here. (ert-deftest custom-test-load () - :tags '(:expensive-test) + :tags '(:expensive-test :unstable) :expected-result :failed ; FIXME: See above. (skip-unless (file-readable-p custom-test-admin-cus-test)) (load custom-test-admin-cus-test) commit 02f846ce9efe47bc43c364dc06593bae6415c505 Author: Stefan Kangas Date: Mon Feb 22 02:24:25 2021 +0100 Convert some textmodes menus to easy-menu-define * lisp/textmodes/artist.el (artist-menu-map): Convert menu definition to easy-menu-define. * lisp/textmodes/conf-mode.el (conf-mode-map): * lisp/textmodes/nroff-mode.el (nroff-mode-map): Move menu definition from here... * lisp/textmodes/conf-mode.el (conf-mode-menu): * lisp/textmodes/nroff-mode.el (nroff-mode-menu): ...to here, and convert to use easy-menu-define. diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el index e66adb43e7..9a886d2397 100644 --- a/lisp/textmodes/artist.el +++ b/lisp/textmodes/artist.el @@ -481,50 +481,6 @@ This variable is initialized by the `artist-make-prev-next-op-alist' function.") (defvar artist-arrow-point-1 nil) (defvar artist-arrow-point-2 nil) -(defvar artist-menu-map - (let ((map (make-sparse-keymap))) - (define-key map [spray-chars] - '(menu-item "Characters for Spray" artist-select-spray-chars - :help "Choose characters for sprayed by the spray-can")) - (define-key map [borders] - '(menu-item "Draw Shape Borders" artist-toggle-borderless-shapes - :help "Toggle whether shapes are drawn with borders" - :button (:toggle . (not artist-borderless-shapes)))) - (define-key map [trimming] - '(menu-item "Trim Line Endings" artist-toggle-trim-line-endings - :help "Toggle trimming of line-endings" - :button (:toggle . artist-trim-line-endings))) - (define-key map [rubber-band] - '(menu-item "Rubber-banding" artist-toggle-rubber-banding - :help "Toggle rubber-banding" - :button (:toggle . artist-rubber-banding))) - (define-key map [set-erase] - '(menu-item "Character to Erase..." artist-select-erase-char - :help "Choose a specific character to erase")) - (define-key map [set-line] - '(menu-item "Character for Line..." artist-select-line-char - :help "Choose the character to insert when drawing lines")) - (define-key map [set-fill] - '(menu-item "Character for Fill..." artist-select-fill-char - :help "Choose the character to insert when filling in shapes")) - (define-key map [artist-separator] '(menu-item "--")) - (dolist (op '(("Vaporize" artist-select-op-vaporize-lines vaporize-lines) - ("Erase" artist-select-op-erase-rectangle erase-rect) - ("Spray-can" artist-select-op-spray-set-size spray-get-size) - ("Text" artist-select-op-text-overwrite text-ovwrt) - ("Ellipse" artist-select-op-circle circle) - ("Poly-line" artist-select-op-straight-poly-line spolyline) - ("Square" artist-select-op-square square) - ("Rectangle" artist-select-op-rectangle rectangle) - ("Line" artist-select-op-straight-line s-line) - ("Pen" artist-select-op-pen-line pen-line))) - (define-key map (vector (nth 2 op)) - `(menu-item ,(nth 0 op) - ,(nth 1 op) - :help ,(format "Draw using the %s style" (nth 0 op)) - :button (:radio . (eq artist-curr-go ',(nth 2 op)))))) - map)) - (defvar artist-mode-map (let ((map (make-sparse-keymap))) (setq artist-mode-map (make-sparse-keymap)) @@ -577,10 +533,50 @@ This variable is initialized by the `artist-make-prev-next-op-alist' function.") (define-key map "\C-c\C-a\C-y" 'artist-select-op-paste) (define-key map "\C-c\C-af" 'artist-select-op-flood-fill) (define-key map "\C-c\C-a\C-b" 'artist-submit-bug-report) - (define-key map [menu-bar artist] (cons "Artist" artist-menu-map)) map) "Keymap for `artist-mode'.") +(easy-menu-define artist-menu-map artist-mode-map + "Menu for `artist-mode'." + `("Artist" + ,@(mapcar + (lambda (op) + `[,(nth 0 op) ,(nth 1 op) + :help ,(format "Draw using the %s style" (nth 0 op)) + :style radio + :selected (eq artist-curr-go ',(nth 2 op))]) + '(("Vaporize" artist-select-op-vaporize-lines vaporize-lines) + ("Erase" artist-select-op-erase-rectangle erase-rect) + ("Spray-can" artist-select-op-spray-set-size spray-get-size) + ("Text" artist-select-op-text-overwrite text-ovwrt) + ("Ellipse" artist-select-op-circle circle) + ("Poly-line" artist-select-op-straight-poly-line spolyline) + ("Square" artist-select-op-square square) + ("Rectangle" artist-select-op-rectangle rectangle) + ("Line" artist-select-op-straight-line s-line) + ("Pen" artist-select-op-pen-line pen-line))) + "---" + ["Character for Fill..." artist-select-fill-char + :help "Choose the character to insert when filling in shapes"] + ["Character for Line..." artist-select-line-char + :help "Choose the character to insert when drawing lines"] + ["Character to Erase..." artist-select-erase-char + :help "Choose a specific character to erase"] + ["Rubber-banding" artist-toggle-rubber-banding + :help "Toggle rubber-banding" + :style toggle + :selected artist-rubber-banding] + ["Trim Line Endings" artist-toggle-trim-line-endings + :help "Toggle trimming of line-endings" + :style toggle + :selected artist-trim-line-endings] + ["Draw Shape Borders" artist-toggle-borderless-shapes + :help "Toggle whether shapes are drawn with borders" + :style toggle + :selected (not artist-borderless-shapes)] + ["Characters for Spray" artist-select-spray-chars + :help "Choose characters for sprayed by the spray-can"])) + (defvar artist-replacement-table (make-vector 256 0) "Replacement table for `artist-replace-char'.") diff --git a/lisp/textmodes/conf-mode.el b/lisp/textmodes/conf-mode.el index d88964aa4f..8225f0a0fe 100644 --- a/lisp/textmodes/conf-mode.el +++ b/lisp/textmodes/conf-mode.el @@ -78,52 +78,46 @@ not align (only setting space according to `conf-assignment-space')." (define-key map "\C-c\"" 'conf-quote-normal) (define-key map "\C-c'" 'conf-quote-normal) (define-key map "\C-c\C-a" 'conf-align-assignments) - (define-key map [menu-bar sh-script] (cons "Conf" menu-map)) - (define-key menu-map [conf-windows-mode] - '(menu-item "Windows mode" - conf-windows-mode - :help "Conf Mode starter for Windows style Conf files" - :button (:radio . (eq major-mode 'conf-windows-mode)))) - (define-key menu-map [conf-javaprop-mode] - '(menu-item "Java properties mode" - conf-javaprop-mode - :help "Conf Mode starter for Java properties files" - :button (:radio . (eq major-mode 'conf-javaprop-mode)))) - (define-key menu-map [conf-space-keywords] - '(menu-item "Space keywords mode..." - conf-space-keywords - :help "Enter Conf Space mode using regexp KEYWORDS to match the keywords" - :button (:radio . (eq major-mode 'conf-space-keywords)))) - (define-key menu-map [conf-ppd-mode] - '(menu-item "PPD mode" - conf-ppd-mode - :help "Conf Mode starter for Adobe/CUPS PPD files" - :button (:radio . (eq major-mode 'conf-ppd-mode)))) - (define-key menu-map [conf-colon-mode] - '(menu-item "Colon mode" - conf-colon-mode - :help "Conf Mode starter for Colon files" - :button (:radio . (eq major-mode 'conf-colon-mode)))) - (define-key menu-map [conf-unix-mode] - '(menu-item "Unix mode" - conf-unix-mode - :help "Conf Mode starter for Unix style Conf files" - :button (:radio . (eq major-mode 'conf-unix-mode)))) - (define-key menu-map [conf-xdefaults-mode] - '(menu-item "Xdefaults mode" - conf-xdefaults-mode - :help "Conf Mode starter for Xdefaults files" - :button (:radio . (eq major-mode 'conf-xdefaults-mode)))) - (define-key menu-map [c-s0] '("--")) - (define-key menu-map [conf-quote-normal] - '(menu-item "Set quote syntax normal" conf-quote-normal - :help "Set the syntax of \\=' and \" to punctuation")) - (define-key menu-map [conf-align-assignments] - '(menu-item "Align assignments" conf-align-assignments - :help "Align assignments")) map) "Local keymap for `conf-mode' buffers.") +(easy-menu-define conf-mode-menu conf-mode-map + "Menu for `conf-mode'." + '("Conf" + ["Align assignments" conf-align-assignments + :help "Align assignments"] + ["Set quote syntax normal" conf-quote-normal + :help "Set the syntax of \\=' and \" to punctuation"] + "---" + ["Xdefaults mode" conf-xdefaults-mode + :help "Conf Mode starter for Xdefaults files" + :style radio + :selected (eq major-mode 'conf-xdefaults-mode)] + ["Unix mode" conf-unix-mode + :help "Conf Mode starter for Unix style Conf files" + :style radio + :selected (eq major-mode 'conf-unix-mode)] + ["Colon mode" conf-colon-mode + :help "Conf Mode starter for Colon files" + :style radio + :selected (eq major-mode 'conf-colon-mode)] + ["PPD mode" conf-ppd-mode + :help "Conf Mode starter for Adobe/CUPS PPD files" + :style radio + :selected (eq major-mode 'conf-ppd-mode)] + ["Space keywords mode..." conf-space-keywords + :help "Enter Conf Space mode using regexp KEYWORDS to match the keywords" + :style radio + :selected (eq major-mode 'conf-space-keywords)] + ["Java properties mode" conf-javaprop-mode + :help "Conf Mode starter for Java properties files" + :style radio + :selected (eq major-mode 'conf-javaprop-mode)] + ["Windows mode" conf-windows-mode + :help "Conf Mode starter for Windows style Conf files" + :style radio + :selected (eq major-mode 'conf-windows-mode)])) + (defvar conf-mode-syntax-table (let ((table (make-syntax-table))) (modify-syntax-entry ?= "." table) diff --git a/lisp/textmodes/nroff-mode.el b/lisp/textmodes/nroff-mode.el index e7d852be3c..cd321501f0 100644 --- a/lisp/textmodes/nroff-mode.el +++ b/lisp/textmodes/nroff-mode.el @@ -54,30 +54,27 @@ (define-key map "\en" 'nroff-forward-text-line) (define-key map "\ep" 'nroff-backward-text-line) (define-key map "\C-c\C-c" 'nroff-view) - (define-key map [menu-bar nroff-mode] (cons "Nroff" menu-map)) - (define-key menu-map [nn] - '(menu-item "Newline" nroff-electric-newline - :help "Insert newline for nroff mode; special if nroff-electric mode")) - (define-key menu-map [nc] - '(menu-item "Count text lines" nroff-count-text-lines - :help "Count lines in region, except for nroff request lines.")) - (define-key menu-map [nf] - '(menu-item "Forward text line" nroff-forward-text-line - :help "Go forward one nroff text line, skipping lines of nroff requests")) - (define-key menu-map [nb] - '(menu-item "Backward text line" nroff-backward-text-line - :help "Go backward one nroff text line, skipping lines of nroff requests")) - (define-key menu-map [ne] - '(menu-item "Electric newline mode" - nroff-electric-mode - :help "Auto insert closing requests if necessary" - :button (:toggle . nroff-electric-mode))) - (define-key menu-map [npm] - '(menu-item "Preview as man page" nroff-view - :help "Run man on this file.")) map) "Major mode keymap for `nroff-mode'.") +(easy-menu-define nroff-mode-menu nroff-mode-map + "Menu for `nroff-mode'." + '("Nroff" + ["Preview as man page" nroff-view + :help "Run man on this file."] + ["Electric newline mode" nroff-electric-mode + :help "Auto insert closing requests if necessary" + :style toggle + :selected nroff-electric-mode] + ["Backward text line" nroff-backward-text-line + :help "Go backward one nroff text line, skipping lines of nroff requests"] + ["Forward text line" nroff-forward-text-line + :help "Go forward one nroff text line, skipping lines of nroff requests"] + ["Count text lines" nroff-count-text-lines + :help "Count lines in region, except for nroff request lines."] + ["Newline" nroff-electric-newline + :help "Insert newline for nroff mode; special if nroff-electric mode"])) + (defvar nroff-mode-syntax-table (let ((st (copy-syntax-table text-mode-syntax-table))) ;; " isn't given string quote syntax in text-mode but it commit d0c47652e527397cae96444c881bf60455c763c1 Author: Mattias Engdegård Date: Sun Feb 21 15:24:41 2021 +0100 Faster, more compact, and readable closure creation Simplify closure creation by calling a single function at run time instead of putting it together from small pieces. This is faster (by about a factor 2), takes less space on disk and in memory, and makes internal functions somewhat readable in disassembly listings again. This is done by creating a prototype function at compile-time whose closure variables are placeholder values V0, V1... which can be seen in the disassembly. The prototype is then cloned at run time using the new make-closure function that replaces the placeholders with the actual closure variables. * lisp/emacs-lisp/bytecomp.el (byte-compile-make-closure): Generate call to make-closure from a prototype function. * src/alloc.c (Fmake_closure): New function. (syms_of_alloc): Defsubr it. * src/data.c (syms_of_data): Defsym byte-code-function-p. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 1b0906b50b..69a63b169c 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -3817,15 +3817,21 @@ discarding." (cl-assert (or (> (length env) 0) docstring-exp)) ;Otherwise, we don't need a closure. (cl-assert (byte-code-function-p fun)) - (byte-compile-form `(make-byte-code - ',(aref fun 0) ',(aref fun 1) - (vconcat (vector . ,env) ',(aref fun 2)) - ,@(let ((rest (nthcdr 3 (mapcar (lambda (x) `',x) fun)))) - (if docstring-exp - `(,(car rest) - ,docstring-exp - ,@(cddr rest)) - rest))))))) + (byte-compile-form + ;; Use symbols V0, V1 ... as placeholders for closure variables: + ;; they should be short (to save space in the .elc file), yet + ;; distinct when disassembled. + (let* ((dummy-vars (mapcar (lambda (i) (intern (format "V%d" i))) + (number-sequence 0 (1- (length env))))) + (proto-fun + (apply #'make-byte-code + (aref fun 0) (aref fun 1) + ;; Prepend dummy cells to the constant vector, + ;; to get the indices right when disassembling. + (vconcat dummy-vars (aref fun 2)) + (mapcar (lambda (i) (aref fun i)) + (number-sequence 3 (1- (length fun))))))) + `(make-closure ,proto-fun ,@env)))))) (defun byte-compile-get-closed-var (form) "Byte-compile the special `internal-get-closed-var' form." diff --git a/src/alloc.c b/src/alloc.c index b86ed4ed26..e72fc4c433 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -3498,6 +3498,38 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT return val; } +DEFUN ("make-closure", Fmake_closure, Smake_closure, 1, MANY, 0, + doc: /* Create a byte-code closure from PROTOTYPE and CLOSURE-VARS. +Return a copy of PROTOTYPE, a byte-code object, with CLOSURE-VARS +replacing the elements in the beginning of the constant-vector. +usage: (make-closure PROTOTYPE &rest CLOSURE-VARS) */) + (ptrdiff_t nargs, Lisp_Object *args) +{ + Lisp_Object protofun = args[0]; + CHECK_TYPE (COMPILEDP (protofun), Qbyte_code_function_p, protofun); + + /* Create a copy of the constant vector, filling it with the closure + variables in the beginning. (The overwritten part should just + contain placeholder values.) */ + Lisp_Object proto_constvec = AREF (protofun, COMPILED_CONSTANTS); + ptrdiff_t constsize = ASIZE (proto_constvec); + ptrdiff_t nvars = nargs - 1; + if (nvars > constsize) + error ("Closure vars do not fit in constvec"); + Lisp_Object constvec = make_uninit_vector (constsize); + memcpy (XVECTOR (constvec)->contents, args + 1, nvars * word_size); + memcpy (XVECTOR (constvec)->contents + nvars, + XVECTOR (proto_constvec)->contents + nvars, + (constsize - nvars) * word_size); + + /* Return a copy of the prototype function with the new constant vector. */ + ptrdiff_t protosize = PVSIZE (protofun); + struct Lisp_Vector *v = allocate_vectorlike (protosize, false); + v->header = XVECTOR (protofun)->header; + memcpy (v->contents, XVECTOR (protofun)->contents, protosize * word_size); + v->contents[COMPILED_CONSTANTS] = constvec; + return make_lisp_ptr (v, Lisp_Vectorlike); +} /*********************************************************************** @@ -7573,6 +7605,7 @@ N should be nonnegative. */); defsubr (&Srecord); defsubr (&Sbool_vector); defsubr (&Smake_byte_code); + defsubr (&Smake_closure); defsubr (&Smake_list); defsubr (&Smake_vector); defsubr (&Smake_record); diff --git a/src/data.c b/src/data.c index 9af9131b12..0fa491b17a 100644 --- a/src/data.c +++ b/src/data.c @@ -3989,6 +3989,8 @@ syms_of_data (void) DEFSYM (Qinteractive_form, "interactive-form"); DEFSYM (Qdefalias_fset_function, "defalias-fset-function"); + DEFSYM (Qbyte_code_function_p, "byte-code-function-p"); + defsubr (&Sindirect_variable); defsubr (&Sinteractive_form); defsubr (&Scommand_modes); commit 2790c6a572a905359c60f055c682b28ef5c8ff0d Author: Stefan Kangas Date: Fri Feb 19 12:31:56 2021 +0100 Run admin/cus-tests.el tests from test suite * test/Makefile.in (SUBDIRS): Run tests in new directory "misc", intended for tests not belonging to any one file. * test/misc/test-custom-deps.el: * test/misc/test-custom-libs.el: * test/misc/test-custom-noloads.el: * test/misc/test-custom-opts.el: New files. * test/lisp/custom-tests.el (custom--test-local-option): Move test to above new file test-custom-opts.el. * admin/cus-test.el: Document running tests from regular test suite. * test/file-organization.org (Test Files): Document new test directory "misc" for tests not belonging to any one file. diff --git a/admin/cus-test.el b/admin/cus-test.el index afd5f4ceae..30b5f65561 100644 --- a/admin/cus-test.el +++ b/admin/cus-test.el @@ -37,6 +37,13 @@ ;; ;; src/emacs -batch -l admin/cus-test.el -f cus-test-noloads ;; +;; or as a part of the test suite with +;; +;; make -C test test-custom-opts +;; make -C test test-custom-deps +;; make -C test test-custom-libs +;; make -C test test-custom-noloads +;; ;; in the emacs source directory. ;; ;; For interactive use: Load this file. Then diff --git a/test/Makefile.in b/test/Makefile.in index ff228d1261..48bbe8712b 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -257,7 +257,7 @@ endef $(foreach test,${TESTS},$(eval $(call test_template,${test}))) ## Get the tests for only a specific directory. -SUBDIRS = $(sort $(shell find lib-src lisp src -type d ! -path "*resources*" -print)) +SUBDIRS = $(sort $(shell find lib-src lisp misc src -type d ! -path "*resources*" -print)) define subdir_template .PHONY: check-$(subst /,-,$(1)) diff --git a/test/file-organization.org b/test/file-organization.org index 7cf5b88d6d..d1f92da432 100644 --- a/test/file-organization.org +++ b/test/file-organization.org @@ -43,6 +43,10 @@ Similarly, tests of features implemented in C should reside in ~-tests.el~ added to the base-name of the tested source file. Thus, tests for ~src/fileio.c~ should be in ~test/src/fileio-tests.el~. +Some tests do not belong to any one particular file. Such tests +should be put in the ~misc~ directory and be given a descriptive name +that does /not/ end with ~-tests.el~. + There are also some test materials that cannot be run automatically (i.e. via ert). These should be placed in ~/test/manual~; they are not run by the "make check" command and its derivatives. diff --git a/test/lisp/custom-tests.el b/test/lisp/custom-tests.el index 10854c71d5..09f79c1a08 100644 --- a/test/lisp/custom-tests.el +++ b/test/lisp/custom-tests.el @@ -145,17 +145,6 @@ (widget-apply field :value-to-internal origvalue) "bar")))))) -(defconst custom-test-admin-cus-test - (expand-file-name "admin/cus-test.el" source-directory)) - -(declare-function cus-test-opts custom-test-admin-cus-test) - -(ert-deftest check-for-wrong-custom-types () - :tags '(:expensive-test) - (skip-unless (file-readable-p custom-test-admin-cus-test)) - (load custom-test-admin-cus-test) - (should (null (cus-test-opts t)))) - (ert-deftest custom-test-enable-theme-keeps-settings () "Test that enabling a theme doesn't change its settings." (let* ((custom-theme-load-path `(,(ert-resource-directory))) diff --git a/test/misc/test-custom-deps.el b/test/misc/test-custom-deps.el new file mode 100644 index 0000000000..f072adddcb --- /dev/null +++ b/test/misc/test-custom-deps.el @@ -0,0 +1,42 @@ +;;; test-custom-deps.el --- Test custom deps -*- lexical-binding:t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; The command `cus-test-deps' loads all (!) custom dependencies and +;; reports about load errors. + +;;; Code: + +(require 'ert) + +(defconst custom-test-admin-cus-test + (expand-file-name "admin/cus-test.el" source-directory)) + +(declare-function cus-test-deps custom-test-admin-cus-test) +(defvar cus-test-deps-errors) ; from admin/cus-tests.el + +(ert-deftest test-custom-deps () + :tags '(:expensive-test) + (skip-unless (file-readable-p custom-test-admin-cus-test)) + (load custom-test-admin-cus-test) + (cus-test-deps) + (should-not cus-test-deps-errors)) + +;;; test-custom-deps.el ends here diff --git a/test/misc/test-custom-libs.el b/test/misc/test-custom-libs.el new file mode 100644 index 0000000000..70f043d129 --- /dev/null +++ b/test/misc/test-custom-libs.el @@ -0,0 +1,46 @@ +;;; test-custom-libs.el --- Test custom loads -*- lexical-binding:t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; This file runs for all libraries with autoloads separate emacs +;; processes of the form "emacs -batch -l LIB". + +;;; Code: + +(require 'ert) + +(defconst custom-test-admin-cus-test + (expand-file-name "admin/cus-test.el" source-directory)) + +(declare-function cus-test-libs custom-test-admin-cus-test) +(defvar cus-test-libs-errors) ; from admin/cus-tests.el + +;; FIXME: Currently fails for: +;; - lisp/term/ns-win.el +;; - lisp/org/org-num.el +(ert-deftest test-custom-libs () + :tags '(:expensive-test) + :expected-result :failed ; FIXME: See above. + (skip-unless (file-readable-p custom-test-admin-cus-test)) + (load custom-test-admin-cus-test) + (cus-test-libs t) + (should-not cus-test-libs-errors)) + +;;; test-custom-deps.el ends here diff --git a/test/misc/test-custom-noloads.el b/test/misc/test-custom-noloads.el new file mode 100644 index 0000000000..e999fe2abb --- /dev/null +++ b/test/misc/test-custom-noloads.el @@ -0,0 +1,45 @@ +;;; test-custom-deps.el --- Test custom noloads -*- lexical-binding:t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; The command `cus-test-noloads' returns a list of variables which +;; are somewhere declared as custom options, but not loaded by +;; `custom-load-symbol'. + +;;; Code: + +(require 'ert) + +(defconst custom-test-admin-cus-test + (expand-file-name "admin/cus-test.el" source-directory)) + +(declare-function cus-test-noloads custom-test-admin-cus-test) +(defvar cus-test-vars-not-cus-loaded) ; from admin/cus-tests.el + +;; FIXME: Multiple failures here. +(ert-deftest custom-test-load () + :tags '(:expensive-test) + :expected-result :failed ; FIXME: See above. + (skip-unless (file-readable-p custom-test-admin-cus-test)) + (load custom-test-admin-cus-test) + (cus-test-noloads) + (should-not cus-test-vars-not-cus-loaded)) + +;;; test-custom-deps.el ends here diff --git a/test/misc/test-custom-opts.el b/test/misc/test-custom-opts.el new file mode 100644 index 0000000000..fa6b9e66ae --- /dev/null +++ b/test/misc/test-custom-opts.el @@ -0,0 +1,39 @@ +;;; test-custom-opts.el --- Test custom opts -*- lexical-binding:t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; The command `cus-test-opts' tests many (all?) custom options. + +;;; Code: + +(require 'ert) + +(defconst custom-test-admin-cus-test + (expand-file-name "admin/cus-test.el" source-directory)) + +(declare-function cus-test-opts custom-test-admin-cus-test) + +(ert-deftest check-for-wrong-custom-opts () + :tags '(:expensive-test) + (skip-unless (file-readable-p custom-test-admin-cus-test)) + (load custom-test-admin-cus-test) + (should (null (cus-test-opts t)))) + +;;; test-custom-opts.el ends here commit ff759b1d0a901e5408a9dfea6c6bc77d1ae1dbf3 Author: Stefan Kangas Date: Sun Feb 21 11:19:57 2021 +0100 Fix interactive mode tagging for man and woman * lisp/man.el (man-common): New mode inheriting special-mode. (Man-mode): * lisp/woman.el (woman-mode): Inherit from man-common. * lisp/man.el (man-follow, Man-update-manpage) (Man-fontify-manpage, Man-cleanup-manpage, Man-next-section) (Man-previous-section, Man-goto-section) (Man-goto-see-also-section, Man-follow-manual-reference) (Man-kill, Man-goto-page, Man-next-manpage) (Man-previous-manpage): Change interactive mode tag to man-common. This was discussed in: https://lists.gnu.org/r/emacs-devel/2021-02/msg01619.html diff --git a/lisp/man.el b/lisp/man.el index 70b8aa8eb2..abb9bbad8f 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -1024,7 +1024,7 @@ to auto-complete your input based on the installed manual pages." ;;;###autoload (defun man-follow (man-args) "Get a Un*x manual page of the item under point and put it in a buffer." - (interactive (list (Man-default-man-entry)) Man-mode) + (interactive (list (Man-default-man-entry)) man-common) (if (or (not man-args) (string= man-args "")) (error "No item under point") @@ -1143,7 +1143,7 @@ Return the buffer in which the manpage will appear." (defun Man-update-manpage () "Reformat current manpage by calling the man command again synchronously." - (interactive nil Man-mode) + (interactive nil man-common) (when (eq Man-arguments nil) ;;this shouldn't happen unless it is not in a Man buffer." (error "Man-arguments not initialized")) @@ -1239,7 +1239,7 @@ See the variable `Man-notify-method' for the different notification behaviors." (defun Man-fontify-manpage () "Convert overstriking and underlining to the correct fonts. Same for the ANSI bold and normal escape sequences." - (interactive nil Man-mode) + (interactive nil man-common) (goto-char (point-min)) ;; Fontify ANSI escapes. (let ((ansi-color-apply-face-function #'ansi-color-apply-text-property-face) @@ -1355,7 +1355,7 @@ default type, `Man-xref-man-page' is used for the buttons." Normally skip any jobs that should have been done by the sed script, but when called interactively, do those jobs even if the sed script would have done them." - (interactive "p" Man-mode) + (interactive "p" man-common) (if (or interactive (not Man-sed-script)) (progn (goto-char (point-min)) @@ -1527,7 +1527,14 @@ manpage command." (defvar bookmark-make-record-function) -(define-derived-mode Man-mode special-mode "Man" +(define-derived-mode man-common special-mode "Man Shared" + "Parent mode for `Man-mode' like modes. +This mode is here to be inherited by modes that need to use +commands from `Man-mode'. Used by `woman'. +(In itself, this mode currently does nothing.)" + :interactive nil) + +(define-derived-mode Man-mode man-common "Man" "A mode for browsing Un*x manual pages. The following man commands are available in the buffer. Try @@ -1723,7 +1730,7 @@ The following key bindings are currently in effect in the buffer: (defun Man-next-section (n) "Move point to Nth next section (default 1)." - (interactive "p" Man-mode) + (interactive "p" man-common) (let ((case-fold-search nil) (start (point))) (if (looking-at Man-heading-regexp) @@ -1739,7 +1746,7 @@ The following key bindings are currently in effect in the buffer: (defun Man-previous-section (n) "Move point to Nth previous section (default 1)." - (interactive "p" Man-mode) + (interactive "p" man-common) (let ((case-fold-search nil)) (if (looking-at Man-heading-regexp) (forward-line -1)) @@ -1771,7 +1778,7 @@ Returns t if section is found, nil otherwise." (chosen (completing-read prompt Man--sections nil nil nil nil default))) (list chosen)) - Man-mode) + man-common) (setq Man--last-section section) (unless (Man-find-section section) (error "Section %s not found" section))) @@ -1780,7 +1787,7 @@ Returns t if section is found, nil otherwise." (defun Man-goto-see-also-section () "Move point to the \"SEE ALSO\" section. Actually the section moved to is described by `Man-see-also-regexp'." - (interactive nil Man-mode) + (interactive nil man-common) (if (not (Man-find-section Man-see-also-regexp)) (error "%s" (concat "No " Man-see-also-regexp " section found in the current manpage")))) @@ -1835,7 +1842,7 @@ Specify which REFERENCE to use; default is based on word at point." (chosen (completing-read prompt Man--refpages nil nil nil nil defaults))) chosen))) - Man-mode) + man-common) (if (not Man--refpages) (error "Can't find any references in the current manpage") (setq Man--last-refpage reference) @@ -1844,7 +1851,7 @@ Specify which REFERENCE to use; default is based on word at point." (defun Man-kill () "Kill the buffer containing the manpage." - (interactive nil Man-mode) + (interactive nil man-common) (quit-window t)) (defun Man-goto-page (page &optional noerror) @@ -1856,7 +1863,7 @@ Specify which REFERENCE to use; default is based on word at point." (error "You're looking at the only manpage in the buffer") (list (read-minibuffer (format "Go to manpage [1-%d]: " (length Man-page-list)))))) - Man-mode) + man-common) (if (and (not Man-page-list) (not noerror)) (error "Not a man page buffer")) (when Man-page-list @@ -1878,7 +1885,7 @@ Specify which REFERENCE to use; default is based on word at point." (defun Man-next-manpage () "Find the next manpage entry in the buffer." - (interactive nil Man-mode) + (interactive nil man-common) (if (= (length Man-page-list) 1) (error "This is the only manpage in the buffer")) (if (< Man-current-page (length Man-page-list)) @@ -1889,7 +1896,7 @@ Specify which REFERENCE to use; default is based on word at point." (defun Man-previous-manpage () "Find the previous manpage entry in the buffer." - (interactive nil Man-mode) + (interactive nil man-common) (if (= (length Man-page-list) 1) (error "This is the only manpage in the buffer")) (if (> Man-current-page 1) diff --git a/lisp/woman.el b/lisp/woman.el index 98f1a47d24..d4f7e8c0db 100644 --- a/lisp/woman.el +++ b/lisp/woman.el @@ -1856,13 +1856,15 @@ Argument EVENT is the invoking mouse event." (defvar bookmark-make-record-function) -(define-derived-mode woman-mode special-mode "WoMan" +(define-derived-mode woman-mode man-common "WoMan" "Turn on (most of) Man mode to browse a buffer formatted by WoMan. WoMan is an ELisp emulation of much of the functionality of the Emacs `man' command running the standard UN*X man and ?roff programs. WoMan author: F.J.Wright@Maths.QMW.ac.uk See `Man-mode' for additional details. \\{woman-mode-map}" + ;; FIXME: Should all this just be re-arranged so that this can just + ;; inherit `man-common' and be done with it? (let ((Man-build-page-list (symbol-function 'Man-build-page-list)) (Man-strip-page-headers (symbol-function 'Man-strip-page-headers)) (Man-unindent (symbol-function 'Man-unindent)) commit 24166be166ccda48353b395174da7e2bb1ca7659 Author: Lars Ingebrigtsen Date: Sun Feb 21 19:26:39 2021 +0100 Declare that `ignore' and `undefined' shouldn't be completed over * lisp/subr.el (ignore, undefined): Declare that these shouldn't be completed over. diff --git a/lisp/subr.el b/lisp/subr.el index cf70b249cf..2ad31b656e 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -375,6 +375,7 @@ PREFIX is a string, and defaults to \"g\"." "Do nothing and return nil. This function accepts any number of ARGUMENTS, but ignores them. Also see `always'." + (declare (completion #'ignore)) (interactive) nil) @@ -922,6 +923,7 @@ For an approximate inverse of this, see `key-description'." (defun undefined () "Beep to tell the user this binding is undefined." + (declare (completion #'ignore)) (interactive) (ding) (if defining-kbd-macro commit d15a42ac453c47c4da8ba1a66170dee106541d63 Author: Lars Ingebrigtsen Date: Sun Feb 21 14:03:13 2021 +0100 Use `undefined' instead of `ignore' in wdired * lisp/wdired.el (wdired-mode-map): Use `undefined' here instead of `ignore' to give the user more feedback. diff --git a/lisp/wdired.el b/lisp/wdired.el index a096abd106..3829ff1f97 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -169,9 +169,9 @@ nonexistent directory will fail." (define-key map "\C-c\C-k" 'wdired-abort-changes) (define-key map "\C-c\C-[" 'wdired-abort-changes) (define-key map "\C-x\C-q" 'wdired-exit) - (define-key map "\C-m" 'ignore) - (define-key map "\C-j" 'ignore) - (define-key map "\C-o" 'ignore) + (define-key map "\C-m" 'undefined) + (define-key map "\C-j" 'undefined) + (define-key map "\C-o" 'undefined) (define-key map [up] 'wdired-previous-line) (define-key map "\C-p" 'wdired-previous-line) (define-key map [down] 'wdired-next-line) commit 908f251e19dc64c75000f87bc6db4e9a8852d1ad Author: Basil L. Contovounesios Date: Thu Feb 11 12:00:05 2021 +0000 Fix json.el encoding of confusable object keys * lisp/json.el (json-encode-string): Clarify commentary. (json--encode-stringlike): New function that covers a subset of json-encode. (json-encode-key): Use it for more efficient encoding and validation, and to avoid mishandling confusable keys like boolean symbols (bug#42545). (json-encode-array): Make it clearer that argument can be a list. (json-encode): Reuse json-encode-keyword and json--encode-stringlike for a subset of the dispatch logic. (json-pretty-print): Ensure confusable keys like ":a" survive a decoding/encoding roundtrip (bug#24252, bug#45032). * test/lisp/json-tests.el (test-json-encode-string) (test-json-encode-hash-table, test-json-encode-alist) (test-json-encode-plist, test-json-pretty-print-object): Test encoding of confusable keys. diff --git a/lisp/json.el b/lisp/json.el index 1f1f608eab..f20123fcfb 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -438,7 +438,8 @@ Initialized lazily by `json-encode-string'.") ;; This seems to afford decent performance gains. (setq-local inhibit-modification-hooks t) (setq json--string-buffer (current-buffer)))) - (insert ?\" (substring-no-properties string)) ; see bug#43549 + ;; Strip `read-only' property (bug#43549). + (insert ?\" (substring-no-properties string)) (goto-char (1+ (point-min))) (while (re-search-forward (rx json--escape) nil 'move) (let ((char (preceding-char))) @@ -452,14 +453,20 @@ Initialized lazily by `json-encode-string'.") ;; Empty buffer for next invocation. (delete-and-extract-region (point-min) (point-max))))) +(defun json--encode-stringlike (object) + "Return OBJECT encoded as a JSON string, or nil if not possible." + (cond ((stringp object) (json-encode-string object)) + ((keywordp object) (json-encode-string + (substring (symbol-name object) 1))) + ((symbolp object) (json-encode-string (symbol-name object))))) + (defun json-encode-key (object) "Return a JSON representation of OBJECT. If the resulting JSON object isn't a valid JSON object key, this signals `json-key-format'." - (let ((encoded (json-encode object))) - (unless (stringp (json-read-from-string encoded)) - (signal 'json-key-format (list object))) - encoded)) + ;; Encoding must be a JSON string. + (or (json--encode-stringlike object) + (signal 'json-key-format (list object)))) ;;; Objects @@ -652,11 +659,10 @@ become JSON objects." ;; Array encoding (defun json-encode-array (array) - "Return a JSON representation of ARRAY." + "Return a JSON representation of ARRAY. +ARRAY can also be a list." (if (and json-encoding-pretty-print - (if (listp array) - array - (> (length array) 0))) + (not (length= array 0))) (concat "[" (json--with-indentation @@ -737,15 +743,9 @@ you will get the following structure returned: OBJECT should have a structure like one returned by `json-read'. If an error is detected during encoding, an error based on `json-error' is signaled." - (cond ((eq object t) (json-encode-keyword object)) - ((eq object json-null) (json-encode-keyword object)) - ((eq object json-false) (json-encode-keyword object)) - ((stringp object) (json-encode-string object)) - ((keywordp object) (json-encode-string - (substring (symbol-name object) 1))) + (cond ((json-encode-keyword object)) ((listp object) (json-encode-list object)) - ((symbolp object) (json-encode-string - (symbol-name object))) + ((json--encode-stringlike object)) ((numberp object) (json-encode-number object)) ((arrayp object) (json-encode-array object)) ((hash-table-p object) (json-encode-hash-table object)) @@ -774,6 +774,8 @@ With prefix argument MINIMIZE, minimize it instead." (json-null :json-null) ;; Ensure that ordering is maintained. (json-object-type 'alist) + ;; Ensure that keys survive roundtrip (bug#24252, bug#42545). + (json-key-type 'string) (orig-buf (current-buffer)) error) ;; Strategy: Repeatedly `json-read' from the original buffer and diff --git a/test/lisp/json-tests.el b/test/lisp/json-tests.el index 11b61d8b47..9886dc0d45 100644 --- a/test/lisp/json-tests.el +++ b/test/lisp/json-tests.el @@ -421,12 +421,21 @@ Point is moved to beginning of the buffer." "\"\\nasdфыв\\u001f\u007ffgh\\t\""))) (ert-deftest test-json-encode-key () - (should (equal (json-encode-key "") "\"\"")) (should (equal (json-encode-key '##) "\"\"")) (should (equal (json-encode-key :) "\"\"")) - (should (equal (json-encode-key "foo") "\"foo\"")) - (should (equal (json-encode-key 'foo) "\"foo\"")) - (should (equal (json-encode-key :foo) "\"foo\"")) + (should (equal (json-encode-key "") "\"\"")) + (should (equal (json-encode-key 'a) "\"a\"")) + (should (equal (json-encode-key :a) "\"a\"")) + (should (equal (json-encode-key "a") "\"a\"")) + (should (equal (json-encode-key t) "\"t\"")) + (should (equal (json-encode-key :t) "\"t\"")) + (should (equal (json-encode-key "t") "\"t\"")) + (should (equal (json-encode-key nil) "\"nil\"")) + (should (equal (json-encode-key :nil) "\"nil\"")) + (should (equal (json-encode-key "nil") "\"nil\"")) + (should (equal (json-encode-key ":a") "\":a\"")) + (should (equal (json-encode-key ":t") "\":t\"")) + (should (equal (json-encode-key ":nil") "\":nil\"")) (should (equal (should-error (json-encode-key 5)) '(json-key-format 5))) (should (equal (should-error (json-encode-key ["foo"])) @@ -572,6 +581,39 @@ Point is moved to beginning of the buffer." (should (equal (json-encode-hash-table #s(hash-table)) "{}")) (should (equal (json-encode-hash-table #s(hash-table data (a 1))) "{\"a\":1}")) + (should (equal (json-encode-hash-table #s(hash-table data (t 1))) + "{\"t\":1}")) + (should (equal (json-encode-hash-table #s(hash-table data (nil 1))) + "{\"nil\":1}")) + (should (equal (json-encode-hash-table #s(hash-table data (:a 1))) + "{\"a\":1}")) + (should (equal (json-encode-hash-table #s(hash-table data (:t 1))) + "{\"t\":1}")) + (should (equal (json-encode-hash-table #s(hash-table data (:nil 1))) + "{\"nil\":1}")) + (should (equal (json-encode-hash-table + #s(hash-table test equal data ("a" 1))) + "{\"a\":1}")) + (should (equal (json-encode-hash-table + #s(hash-table test equal data ("t" 1))) + "{\"t\":1}")) + (should (equal (json-encode-hash-table + #s(hash-table test equal data ("nil" 1))) + "{\"nil\":1}")) + (should (equal (json-encode-hash-table + #s(hash-table test equal data (":a" 1))) + "{\":a\":1}")) + (should (equal (json-encode-hash-table + #s(hash-table test equal data (":t" 1))) + "{\":t\":1}")) + (should (equal (json-encode-hash-table + #s(hash-table test equal data (":nil" 1))) + "{\":nil\":1}")) + (should (member (json-encode-hash-table #s(hash-table data (t 2 :nil 1))) + '("{\"nil\":1,\"t\":2}" "{\"t\":2,\"nil\":1}"))) + (should (member (json-encode-hash-table + #s(hash-table test equal data (:t 2 ":t" 1))) + '("{\":t\":1,\"t\":2}" "{\"t\":2,\":t\":1}"))) (should (member (json-encode-hash-table #s(hash-table data (b 2 a 1))) '("{\"a\":1,\"b\":2}" "{\"b\":2,\"a\":1}"))) (should (member (json-encode-hash-table #s(hash-table data (c 3 b 2 a 1))) @@ -638,7 +680,16 @@ Point is moved to beginning of the buffer." (let ((json-encoding-object-sort-predicate nil) (json-encoding-pretty-print nil)) (should (equal (json-encode-alist ()) "{}")) - (should (equal (json-encode-alist '((a . 1))) "{\"a\":1}")) + (should (equal (json-encode-alist '((a . 1) (t . 2) (nil . 3))) + "{\"a\":1,\"t\":2,\"nil\":3}")) + (should (equal (json-encode-alist '((:a . 1) (:t . 2) (:nil . 3))) + "{\"a\":1,\"t\":2,\"nil\":3}")) + (should (equal (json-encode-alist '(("a" . 1) ("t" . 2) ("nil" . 3))) + "{\"a\":1,\"t\":2,\"nil\":3}")) + (should (equal (json-encode-alist '((":a" . 1) (":t" . 2) (":nil" . 3))) + "{\":a\":1,\":t\":2,\":nil\":3}")) + (should (equal (json-encode-alist '((t . 1) (:nil . 2) (":nil" . 3))) + "{\"t\":1,\"nil\":2,\":nil\":3}")) (should (equal (json-encode-alist '((b . 2) (a . 1))) "{\"b\":2,\"a\":1}")) (should (equal (json-encode-alist '((c . 3) (b . 2) (a . 1))) "{\"c\":3,\"b\":2,\"a\":1}")))) @@ -687,8 +738,14 @@ Point is moved to beginning of the buffer." (should (equal (json-encode-plist ()) "{}")) (should (equal (json-encode-plist '(:a 1)) "{\"a\":1}")) (should (equal (json-encode-plist '(:b 2 :a 1)) "{\"b\":2,\"a\":1}")) - (should (equal (json-encode-plist '(:c 3 :b 2 :a 1)) - "{\"c\":3,\"b\":2,\"a\":1}")))) + (should (equal (json-encode-plist '(":d" 4 "c" 3 b 2 :a 1)) + "{\":d\":4,\"c\":3,\"b\":2,\"a\":1}")) + (should (equal (json-encode-plist '(nil 2 t 1)) + "{\"nil\":2,\"t\":1}")) + (should (equal (json-encode-plist '(:nil 2 :t 1)) + "{\"nil\":2,\"t\":1}")) + (should (equal (json-encode-plist '(":nil" 4 "nil" 3 ":t" 2 "t" 1)) + "{\":nil\":4,\"nil\":3,\":t\":2,\"t\":1}")))) (ert-deftest test-json-encode-plist-pretty () (let ((json-encoding-object-sort-predicate nil) @@ -950,7 +1007,13 @@ nil, ORIGINAL should stay unchanged by pretty-printing." ;; Nested array. (json-tests-equal-pretty-print "{\"key\":[1,2]}" - "{\n \"key\": [\n 1,\n 2\n ]\n}")) + "{\n \"key\": [\n 1,\n 2\n ]\n}") + ;; Confusable keys (bug#24252, bug#42545). + (json-tests-equal-pretty-print + (concat "{\"t\":1,\"nil\":2,\":t\":3,\":nil\":4," + "\"null\":5,\":json-null\":6,\":json-false\":7}") + (concat "{\n \"t\": 1,\n \"nil\": 2,\n \":t\": 3,\n \":nil\": 4," + "\n \"null\": 5,\n \":json-null\": 6,\n \":json-false\": 7\n}"))) (ert-deftest test-json-pretty-print-array () ;; Empty. commit 767608ef56044af63712206325d177b0caf279df Author: Stefan Kangas Date: Sun Feb 21 10:23:12 2021 +0100 Make unused variable menu-bar-handwrite-map obsolete * lisp/play/handwrite.el (menu-bar-handwrite-map): Make unused variable obsolete. diff --git a/lisp/play/handwrite.el b/lisp/play/handwrite.el index 98da26c2e6..3cc5d9c8dc 100644 --- a/lisp/play/handwrite.el +++ b/lisp/play/handwrite.el @@ -90,7 +90,7 @@ (define-key map [handwrite] '("Write by hand" . handwrite)) map)) (fset 'menu-bar-handwrite-map menu-bar-handwrite-map) - +(make-obsolete-variable 'menu-bar-handwrite-map nil "28.1") ;; User definable variables commit 1b9e233493a65952060d1678cec5f149d10f90e4 Author: Stefan Kangas Date: Sun Feb 21 10:19:23 2021 +0100 Convert bubbles menu to easy-menu-define * lisp/play/bubbles.el (bubbles-game-theme-menu) (bubbles-graphics-theme-menu, bubbles-menu, bubbles-mode-map): Move menu definition from here... (bubbles-menu): ...to here, and convert to easy-menu-define. diff --git a/lisp/play/bubbles.el b/lisp/play/bubbles.el index dc93ef9031..dddd19fa0a 100644 --- a/lisp/play/bubbles.el +++ b/lisp/play/bubbles.el @@ -811,78 +811,7 @@ static char * dot3d_xpm[] = { (bubbles--initialize-images) (bubbles--update-faces-or-images)) -;; game theme menu -(defvar bubbles-game-theme-menu - (let ((menu (make-sparse-keymap "Game Theme"))) - (define-key menu [bubbles-set-game-userdefined] - (list 'menu-item "User defined" 'bubbles-set-game-userdefined - :button '(:radio . (eq bubbles-game-theme 'user-defined)))) - (define-key menu [bubbles-set-game-hard] - (list 'menu-item "Hard" 'bubbles-set-game-hard - :button '(:radio . (eq bubbles-game-theme 'hard)))) - (define-key menu [bubbles-set-game-difficult] - (list 'menu-item "Difficult" 'bubbles-set-game-difficult - :button '(:radio . (eq bubbles-game-theme 'difficult)))) - (define-key menu [bubbles-set-game-medium] - (list 'menu-item "Medium" 'bubbles-set-game-medium - :button '(:radio . (eq bubbles-game-theme 'medium)))) - (define-key menu [bubbles-set-game-easy] - (list 'menu-item "Easy" 'bubbles-set-game-easy - :button '(:radio . (eq bubbles-game-theme 'easy)))) - menu) - "Map for bubbles game theme menu.") - -;; graphics theme menu -(defvar bubbles-graphics-theme-menu - (let ((menu (make-sparse-keymap "Graphics Theme"))) - (define-key menu [bubbles-set-graphics-theme-ascii] - (list 'menu-item "ASCII" 'bubbles-set-graphics-theme-ascii - :button '(:radio . (eq bubbles-graphics-theme 'ascii)))) - (define-key menu [bubbles-set-graphics-theme-emacs] - (list 'menu-item "Emacs" 'bubbles-set-graphics-theme-emacs - :button '(:radio . (eq bubbles-graphics-theme 'emacs)))) - (define-key menu [bubbles-set-graphics-theme-balls] - (list 'menu-item "Balls" 'bubbles-set-graphics-theme-balls - :button '(:radio . (eq bubbles-graphics-theme 'balls)))) - (define-key menu [bubbles-set-graphics-theme-diamonds] - (list 'menu-item "Diamonds" 'bubbles-set-graphics-theme-diamonds - :button '(:radio . (eq bubbles-graphics-theme 'diamonds)))) - (define-key menu [bubbles-set-graphics-theme-squares] - (list 'menu-item "Squares" 'bubbles-set-graphics-theme-squares - :button '(:radio . (eq bubbles-graphics-theme 'squares)))) - (define-key menu [bubbles-set-graphics-theme-circles] - (list 'menu-item "Circles" 'bubbles-set-graphics-theme-circles - :button '(:radio . (eq bubbles-graphics-theme 'circles)))) - menu) - "Map for bubbles graphics theme menu.") - -;; menu -(defvar bubbles-menu - (let ((menu (make-sparse-keymap "Bubbles"))) - (define-key menu [bubbles-quit] - (list 'menu-item "Quit" 'bubbles-quit)) - (define-key menu [bubbles] - (list 'menu-item "New game" 'bubbles)) - (define-key menu [bubbles-separator-1] - '("--")) - (define-key menu [bubbles-save-settings] - (list 'menu-item "Save all settings" 'bubbles-save-settings)) - (define-key menu [bubbles-customize] - (list 'menu-item "Edit all settings" 'bubbles-customize)) - (define-key menu [bubbles-game-theme-menu] - (list 'menu-item "Game Theme" bubbles-game-theme-menu)) - (define-key menu [bubbles-graphics-theme-menu] - (list 'menu-item "Graphics Theme" bubbles-graphics-theme-menu - :enable 'bubbles--playing)) - (define-key menu [bubbles-separator-2] - '("--")) - (define-key menu [bubbles-undo] - (list 'menu-item "Undo last move" 'bubbles-undo - :enable '(and bubbles--playing (listp buffer-undo-list)))) - menu) - "Map for bubbles menu.") - -;; bubbles mode map + (defvar bubbles-mode-map (let ((map (make-sparse-keymap 'bubbles-mode-map))) ;; (suppress-keymap map t) @@ -897,12 +826,59 @@ static char * dot3d_xpm[] = { (define-key map "n" 'next-line) (define-key map "f" 'forward-char) (define-key map "b" 'backward-char) - ;; bind menu to mouse - (define-key map [down-mouse-3] bubbles-menu) - ;; Put menu in menu-bar - (define-key map [menu-bar Bubbles] (cons "Bubbles" bubbles-menu)) map) - "Mode map for bubbles.") + "Mode map for `bubbles'.") + +(easy-menu-define bubbles-menu bubbles-mode-map + "Menu for `bubbles'." + '("Bubbles" + ["Undo last move" bubbles-undo + :enable '(and bubbles--playing (listp buffer-undo-list))] + "---" + ("Graphics Theme" + :enable bubbles--playing + ["Circles" bubbles-set-graphics-theme-circles + :style radio + :selected (eq bubbles-graphics-theme 'circles)] + ["Squares" bubbles-set-graphics-theme-squares + :style radio + :selected (eq bubbles-graphics-theme 'squares)] + ["Diamonds" bubbles-set-graphics-theme-diamonds + :style radio + :selected (eq bubbles-graphics-theme 'diamonds)] + ["Balls" bubbles-set-graphics-theme-balls + :style radio + :selected (eq bubbles-graphics-theme 'balls)] + ["Emacs" bubbles-set-graphics-theme-emacs + :style radio + :selected (eq bubbles-graphics-theme 'emacs)] + ["ASCII" bubbles-set-graphics-theme-ascii + :style radio + :selected (eq bubbles-graphics-theme 'ascii)]) + ("Game Theme" + ["Easy" bubbles-set-game-easy + :style radio + :selected (eq bubbles-game-theme 'easy)] + ["Medium" bubbles-set-game-medium + :style radio + :selected (eq bubbles-game-theme 'medium)] + ["Difficult" bubbles-set-game-difficult + :style radio + :selected (eq bubbles-game-theme 'difficult)] + ["Hard" bubbles-set-game-hard + :style radio + :selected (eq bubbles-game-theme 'hard)] + ["User defined" bubbles-set-game-userdefined + :style radio + :selected (eq bubbles-game-theme 'user-defined)]) + ["Edit all settings" bubbles-customize] + ["Save all settings" bubbles-save-settings] + "---" + ["New game" bubbles] + ["Quit" bubbles-quit])) + +;; bind menu to mouse +(define-key bubbles-mode-map [down-mouse-3] bubbles-menu) (define-derived-mode bubbles-mode nil "Bubbles" "Major mode for playing bubbles. commit 669b911c6660120c73b7760063d490872240a727 Author: Stefan Kangas Date: Sun Feb 21 10:10:03 2021 +0100 ; Fix previous easy-menu-define conversion * lisp/emacs-lisp/re-builder.el (reb-mode-menu): * lisp/progmodes/make-mode.el (makefile-mode-menu): Replace :button attribute with :style and :selected. diff --git a/lisp/emacs-lisp/re-builder.el b/lisp/emacs-lisp/re-builder.el index 7f404c8296..455fcac701 100644 --- a/lisp/emacs-lisp/re-builder.el +++ b/lisp/emacs-lisp/re-builder.el @@ -250,9 +250,9 @@ Except for Lisp syntax this is the same as `reb-regexp'.") ["Change target buffer..." reb-change-target-buffer :help "Change the target buffer and display it in the target window"] ["Case sensitive" reb-toggle-case - :button (:toggle . (with-current-buffer - reb-target-buffer - (null case-fold-search))) + :style toggle + :selected (with-current-buffer reb-target-buffer + (null case-fold-search)) :help "Toggle case sensitivity of searches for RE Builder target buffer"] "---" ["Quit" reb-quit diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el index d444ce2999..3f466e1150 100644 --- a/lisp/progmodes/make-mode.el +++ b/lisp/progmodes/make-mode.el @@ -631,22 +631,28 @@ The function must satisfy this calling convention: ("Switch Makefile Type" ["GNU make" makefile-gmake-mode :help "An adapted `makefile-mode' that knows about GNU make" - :button (:radio . (eq major-mode 'makefile-gmake-mode))] + :style radio + :selected (eq major-mode 'makefile-gmake-mode)] ["Automake" makefile-automake-mode :help "An adapted `makefile-mode' that knows about automake" - :button (:radio . (eq major-mode 'makefile-automake-mode))] + :style radio + :selected (eq major-mode 'makefile-automake-mode)] ["BSD" makefile-bsdmake-mode :help "An adapted `makefile-mode' that knows about BSD make" - :button (:radio . (eq major-mode 'makefile-bsdmake-mode))] + :style radio + :selected (eq major-mode 'makefile-bsdmake-mode)] ["Classic" makefile-mode :help "`makefile-mode' with no special functionality" - :button (:radio . (eq major-mode 'makefile-mode))] + :style radio + :selected (eq major-mode 'makefile-mode)] ["Imake" makefile-imake-mode :help "An adapted `makefile-mode' that knows about imake" - :button (:radio . (eq major-mode 'makefile-imake-mode))] + :style radio + :selected (eq major-mode 'makefile-imake-mode)] ["Makepp" makefile-makepp-mode :help "An adapted `makefile-mode' that knows about makepp" - :button (:radio . (eq major-mode 'makefile-makepp-mode))]))) + :style radio + :selected (eq major-mode 'makefile-makepp-mode)]))) (defvar makefile-browser-map commit df932bef91122b8400299b83b774c8c5e5ee4d75 Author: Stefan Kangas Date: Sun Feb 21 10:02:43 2021 +0100 * etc/NEWS.19: Add entry for 'easy-menu-define'. diff --git a/etc/NEWS.19 b/etc/NEWS.19 index f2cef62971..fd91c0842f 100644 --- a/etc/NEWS.19 +++ b/etc/NEWS.19 @@ -4011,6 +4011,7 @@ The third component is now determined on the basis of the names of the existing executable files. This means that version.el is not altered by building Emacs. +** New macro 'easy-menu-define' * Changes in 19.22. commit 2c26eb11159b0acc2e3e74f9d1a96e615e86a40b Author: Stefan Kangas Date: Sun Feb 21 08:24:44 2021 +0100 Convert some progmodes menus to easy-menu-define * lisp/progmodes/asm-mode.el (asm-mode-map): * lisp/progmodes/grep.el (grep-mode-map): * lisp/progmodes/m4-mode.el (m4-mode-map): * lisp/progmodes/sh-script.el (sh-mode-map): Move menu definition from here... * lisp/progmodes/asm-mode.el (asm-mode-menu): * lisp/progmodes/grep.el (grep-menu-map): * lisp/progmodes/m4-mode.el (m4-mode-menu): * lisp/progmodes/sh-script.el (sh-mode-menu): ...to here, and rewrite using easy-menu-define. diff --git a/lisp/progmodes/asm-mode.el b/lisp/progmodes/asm-mode.el index 99b2ec6d87..2f7d7bf796 100644 --- a/lisp/progmodes/asm-mode.el +++ b/lisp/progmodes/asm-mode.el @@ -73,19 +73,19 @@ ;; Note that the comment character isn't set up until asm-mode is called. (define-key map ":" 'asm-colon) (define-key map "\C-c;" 'comment-region) - (define-key map [menu-bar asm-mode] (cons "Asm" (make-sparse-keymap))) - (define-key map [menu-bar asm-mode comment-region] - '(menu-item "Comment Region" comment-region - :help "Comment or uncomment each line in the region")) - (define-key map [menu-bar asm-mode newline-and-indent] - '(menu-item "Insert Newline and Indent" newline-and-indent - :help "Insert a newline, then indent according to major mode")) - (define-key map [menu-bar asm-mode asm-colon] - '(menu-item "Insert Colon" asm-colon - :help "Insert a colon; if it follows a label, delete the label's indentation")) map) "Keymap for Asm mode.") +(easy-menu-define asm-mode-menu asm-mode-map + "Menu for Asm mode." + '("Asm" + ["Insert Colon" asm-colon + :help "Insert a colon; if it follows a label, delete the label's indentation"] + ["Insert Newline and Indent" newline-and-indent + :help "Insert a newline, then indent according to major mode"] + ["Comment Region" comment-region + :help "Comment or uncomment each line in the region"])) + (defconst asm-font-lock-keywords (append '(("^\\(\\(\\sw\\|\\s_\\)+\\)\\>:?[ \t]*\\(\\sw+\\(\\.\\sw+\\)*\\)?" diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el index d6ee8bb423..3e92c69913 100644 --- a/lisp/progmodes/grep.el +++ b/lisp/progmodes/grep.el @@ -279,57 +279,39 @@ See `compilation-error-screen-columns'." (define-key map "}" 'compilation-next-file) (define-key map "\t" 'compilation-next-error) (define-key map [backtab] 'compilation-previous-error) - - ;; Set up the menu-bar - (define-key map [menu-bar grep] - (cons "Grep" (make-sparse-keymap "Grep"))) - - (define-key map [menu-bar grep grep-find-toggle-abbreviation] - '(menu-item "Toggle command abbreviation" - grep-find-toggle-abbreviation - :help "Toggle showing verbose command options")) - (define-key map [menu-bar grep compilation-separator3] '("----")) - (define-key map [menu-bar grep compilation-kill-compilation] - '(menu-item "Kill Grep" kill-compilation - :help "Kill the currently running grep process")) - (define-key map [menu-bar grep compilation-separator2] '("----")) - (define-key map [menu-bar grep compilation-compile] - '(menu-item - "Compile..." compile - :help - "Compile the program including the current buffer. Default: run `make'")) - (define-key map [menu-bar grep compilation-rgrep] - '(menu-item "Recursive grep..." rgrep - :help "User-friendly recursive grep in directory tree")) - (define-key map [menu-bar grep compilation-lgrep] - '(menu-item "Local grep..." lgrep - :help "User-friendly grep in a directory")) - (define-key map [menu-bar grep compilation-grep-find] - '(menu-item "Grep via Find..." grep-find - :help "Run grep via find, with user-specified args")) - (define-key map [menu-bar grep compilation-grep] - '(menu-item - "Another grep..." grep - :help - "Run grep, with user-specified args, and collect output in a buffer.")) - (define-key map [menu-bar grep compilation-recompile] - '(menu-item "Repeat grep" recompile - :help "Run grep again")) - (define-key map [menu-bar grep compilation-separator1] '("----")) - (define-key map [menu-bar grep compilation-first-error] - '(menu-item - "First Match" first-error - :help "Restart at the first match, visit corresponding location")) - (define-key map [menu-bar grep compilation-previous-error] - '(menu-item "Previous Match" previous-error - :help "Visit the previous match and corresponding location")) - (define-key map [menu-bar grep compilation-next-error] - '(menu-item "Next Match" next-error - :help "Visit the next match and corresponding location")) map) "Keymap for grep buffers. `compilation-minor-mode-map' is a cdr of this.") +(easy-menu-define grep-menu-map grep-mode-map + "Menu for grep buffers." + '("Grep" + ["Next Match" next-error + :help "Visit the next match and corresponding location"] + ["Previous Match" previous-error + :help "Visit the previous match and corresponding location"] + ["First Match" first-error + :help "Restart at the first match, visit corresponding location"] + "----" + ["Repeat grep" recompile + :help "Run grep again"] + ["Another grep..." grep + :help "Run grep, with user-specified args, and collect output in a buffer."] + ["Grep via Find..." grep-find + :help "Run grep via find, with user-specified args"] + ["Local grep..." lgrep + :help "User-friendly grep in a directory"] + ["Recursive grep..." rgrep + :help "User-friendly recursive grep in directory tree"] + ["Compile..." compile + :help "Compile the program including the current buffer. Default: run `make'"] + "----" + ["Kill Grep" kill-compilation + :help "Kill the currently running grep process"] + "----" + ["Toggle command abbreviation" grep-find-toggle-abbreviation + :help "Toggle showing verbose command options"])) + (defvar grep-mode-tool-bar-map ;; When bootstrapping, tool-bar-map is not properly initialized yet, ;; so don't do anything. diff --git a/lisp/progmodes/m4-mode.el b/lisp/progmodes/m4-mode.el index 7dfaed4428..d9c09f6fe6 100644 --- a/lisp/progmodes/m4-mode.el +++ b/lisp/progmodes/m4-mode.el @@ -122,22 +122,22 @@ If m4 is not in your PATH, set this to an absolute file name." (string-to-syntax ".")))))) (defvar m4-mode-map - (let ((map (make-sparse-keymap)) - (menu-map (make-sparse-keymap))) + (let ((map (make-sparse-keymap))) (define-key map "\C-c\C-b" 'm4-m4-buffer) (define-key map "\C-c\C-r" 'm4-m4-region) (define-key map "\C-c\C-c" 'comment-region) - (define-key map [menu-bar m4-mode] (cons "M4" menu-map)) - (define-key menu-map [m4c] - '(menu-item "Comment Region" comment-region - :help "Comment Region")) - (define-key menu-map [m4b] - '(menu-item "M4 Buffer" m4-m4-buffer - :help "Send contents of the current buffer to m4")) - (define-key menu-map [m4r] - '(menu-item "M4 Region" m4-m4-region - :help "Send contents of the current region to m4")) - map)) + map) + "Keymap for M4 Mode.") + +(easy-menu-define m4-mode-menu m4-mode-map + "Menu for M4 Mode." + '("M4" + ["M4 Region" m4-m4-region + :help "Send contents of the current region to m4"] + ["M4 Buffer" m4-m4-buffer + :help "Send contents of the current buffer to m4"] + ["Comment Region" comment-region + :help "Comment Region"])) (defun m4-m4-buffer () "Send contents of the current buffer to m4." diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index f588ad99c9..ba59f9c661 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -403,8 +403,7 @@ This is buffer-local in every such buffer.") "Syntax-table used in Shell-Script mode. See `sh-feature'.") (defvar sh-mode-map - (let ((map (make-sparse-keymap)) - (menu-map (make-sparse-keymap))) + (let ((map (make-sparse-keymap))) (define-key map "\C-c(" 'sh-function) (define-key map "\C-c\C-w" 'sh-while) (define-key map "\C-c\C-u" 'sh-until) @@ -434,74 +433,57 @@ This is buffer-local in every such buffer.") (define-key map "\C-c:" 'sh-set-shell) (define-key map [remap backward-sentence] 'sh-beginning-of-command) (define-key map [remap forward-sentence] 'sh-end-of-command) - (define-key map [menu-bar sh-script] (cons "Sh-Script" menu-map)) - (define-key menu-map [smie-config-guess] - '(menu-item "Learn buffer indentation" smie-config-guess - :help "Learn how to indent the buffer the way it currently is.")) - (define-key menu-map [smie-config-show-indent] - '(menu-item "Show indentation" smie-config-show-indent - :help "Show the how the current line would be indented")) - (define-key menu-map [smie-config-set-indent] - '(menu-item "Set indentation" smie-config-set-indent - :help "Set the indentation for the current line")) - - (define-key menu-map [sh-pair] - '(menu-item "Insert braces and quotes in pairs" - electric-pair-mode - :button (:toggle . (bound-and-true-p electric-pair-mode)) - :help "Inserting a brace or quote automatically inserts the matching pair")) - - (define-key menu-map [sh-s0] '("--")) - ;; Insert - (define-key menu-map [sh-function] - '(menu-item "Function..." sh-function - :help "Insert a function definition")) - (define-key menu-map [sh-add] - '(menu-item "Addition..." sh-add - :help "Insert an addition of VAR and prefix DELTA for Bourne (type) shell")) - (define-key menu-map [sh-until] - '(menu-item "Until Loop" sh-until - :help "Insert an until loop")) - (define-key menu-map [sh-repeat] - '(menu-item "Repeat Loop" sh-repeat - :help "Insert a repeat loop definition")) - (define-key menu-map [sh-while] - '(menu-item "While Loop" sh-while - :help "Insert a while loop")) - (define-key menu-map [sh-getopts] - '(menu-item "Options Loop" sh-while-getopts - :help "Insert a while getopts loop.")) - (define-key menu-map [sh-indexed-loop] - '(menu-item "Indexed Loop" sh-indexed-loop - :help "Insert an indexed loop from 1 to n.")) - (define-key menu-map [sh-select] - '(menu-item "Select Statement" sh-select - :help "Insert a select statement ")) - (define-key menu-map [sh-if] - '(menu-item "If Statement" sh-if - :help "Insert an if statement")) - (define-key menu-map [sh-for] - '(menu-item "For Loop" sh-for - :help "Insert a for loop")) - (define-key menu-map [sh-case] - '(menu-item "Case Statement" sh-case - :help "Insert a case/switch statement")) - (define-key menu-map [sh-s1] '("--")) - (define-key menu-map [sh-exec] - '(menu-item "Execute region" sh-execute-region - :help "Pass optional header and region to a subshell for noninteractive execution")) - (define-key menu-map [sh-exec-interpret] - '(menu-item "Execute script..." executable-interpret - :help "Run script with user-specified args, and collect output in a buffer")) - (define-key menu-map [sh-set-shell] - '(menu-item "Set shell type..." sh-set-shell - :help "Set this buffer's shell to SHELL (a string)")) - (define-key menu-map [sh-backslash-region] - '(menu-item "Backslash region" sh-backslash-region - :help "Insert, align, or delete end-of-line backslashes on the lines in the region.")) map) "Keymap used in Shell-Script mode.") +(easy-menu-define sh-mode-menu sh-mode-map + "Menu for Shell-Script mode." + '("Sh-Script" + ["Backslash region" sh-backslash-region + :help "Insert, align, or delete end-of-line backslashes on the lines in the region."] + ["Set shell type..." sh-set-shell + :help "Set this buffer's shell to SHELL (a string)"] + ["Execute script..." executable-interpret + :help "Run script with user-specified args, and collect output in a buffer"] + ["Execute region" sh-execute-region + :help "Pass optional header and region to a subshell for noninteractive execution"] + "---" + ;; Insert + ["Case Statement" sh-case + :help "Insert a case/switch statement"] + ["For Loop" sh-for + :help "Insert a for loop"] + ["If Statement" sh-if + :help "Insert an if statement"] + ["Select Statement" sh-select + :help "Insert a select statement "] + ["Indexed Loop" sh-indexed-loop + :help "Insert an indexed loop from 1 to n."] + ["Options Loop" sh-while-getopts + :help "Insert a while getopts loop."] + ["While Loop" sh-while + :help "Insert a while loop"] + ["Repeat Loop" sh-repeat + :help "Insert a repeat loop definition"] + ["Until Loop" sh-until + :help "Insert an until loop"] + ["Addition..." sh-add + :help "Insert an addition of VAR and prefix DELTA for Bourne (type) shell"] + ["Function..." sh-function + :help "Insert a function definition"] + "---" + ;; Other + ["Insert braces and quotes in pairs" electric-pair-mode + :style toggle + :selected (bound-and-true-p electric-pair-mode) + :help "Inserting a brace or quote automatically inserts the matching pair"] + ["Set indentation" smie-config-set-indent + :help "Set the indentation for the current line"] + ["Show indentation" smie-config-show-indent + :help "Show the how the current line would be indented"] + ["Learn buffer indentation" smie-config-guess + :help "Learn how to indent the buffer the way it currently is."])) + (defvar sh-skeleton-pair-default-alist '((?\( _ ?\)) (?\)) (?\[ ?\s _ ?\s ?\]) (?\]) (?{ _ ?}) (?\})) commit 3010794753ddbb652d4362fcdf74aabf424144d1 Author: Michael Albinus Date: Sun Feb 21 10:24:56 2021 +0100 Clarification of password handling in Tramp manual * doc/misc/tramp.texi (Password handling): Describe, how to suppress `auth-sources' for Tramp. (Remote shell setup, Remote processes) (Cleanup remote connections, Frequently Asked Questions): Handle reference to Emacs manual. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 6d60215734..e745af2a7d 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -1927,6 +1927,25 @@ file, you must customize @code{ange-ftp-netrc-filename}: (customize-set-variable 'ange-ftp-netrc-filename "~/.authinfo.gpg") @end lisp +In case you do not want to use an authentication file for +@value{tramp} passwords, use connection-local variables +@ifinfo +(@pxref{Connection Variables, , , emacs}) +@end ifinfo +like this: + +@lisp +@group +(connection-local-set-profile-variables + 'remote-without-auth-sources '((auth-sources . nil))) +@end group + +@group +(connection-local-set-profiles + '(:application tramp) 'remote-without-auth-sources) +@end group +@end lisp + @anchor{Caching passwords} @subsection Caching passwords @@ -2345,10 +2364,16 @@ fi Another possibility is to check the environment variable @env{INSIDE_EMACS}. Like for all subprocesses of Emacs, this is set -to the version of the parent Emacs process, @xref{Interactive Shell, , -, emacs}. @value{tramp} adds its own package version to this string, -which could be used for further tests in an inferior shell. The -string of that environment variable looks always like +to the version of the parent Emacs +@ifinfo +process, @xref{Interactive Shell, , , emacs}. +@end ifinfo +@ifnotinfo +process. +@end ifnotinfo +@value{tramp} adds its own package version to this string, which could +be used for further tests in an inferior shell. The string of that +environment variable looks always like @example @group @@ -3473,10 +3498,13 @@ uid=0(root) gid=0(root) groups=0(root) @cindex @code{gdb} @cindex @code{perldb} -@file{gud.el} provides a unified interface to symbolic debuggers +@file{gud.el} provides a unified interface to symbolic @ifinfo -(@ref{Debuggers, , , emacs}). +debuggers (@pxref{Debuggers, , , emacs}). @end ifinfo +@ifnotinfo +debuggers. +@end ifnotinfo @value{tramp} can run debug on remote hosts by calling @code{gdb} with a remote file name: @@ -3637,9 +3665,15 @@ minibuffer. Each connection is of the format Flushing remote connections also cleans the password cache (@pxref{Password handling}), file cache, connection cache -(@pxref{Connection caching}), and recentf cache (@pxref{File -Conveniences, , , emacs}). It also deletes session timers -(@pxref{Predefined connection information}) and connection buffers. +(@pxref{Connection caching}), and recentf +@ifinfo +cache (@pxref{File Conveniences, , , emacs}). +@end ifinfo +@ifnotinfo +cache. +@end ifnotinfo +It also deletes session timers (@pxref{Predefined connection +information}) and connection buffers. If @var{keep-debug} is non-@code{nil}, the debug buffer is kept. A non-@code{nil} @var{keep-password} preserves the password cache. @@ -4544,10 +4578,16 @@ HISTFILE=/dev/null @item Where are remote files trashed to? -Emacs can trash file instead of deleting them, @ref{Misc File Ops, -Trashing , , emacs}. Remote files are always trashed to the local -trash, except remote encrypted files (@pxref{Keeping files -encrypted}), which are deleted anyway. +Emacs can trash file instead of deleting +@ifinfo +them, @ref{Misc File Ops, Trashing , , emacs}. +@end ifinfo +@ifnotinfo +them. +@end ifnotinfo +Remote files are always trashed to the local trash, except remote +encrypted files (@pxref{Keeping files encrypted}), which are deleted +anyway. If Emacs is configured to use the XDG conventions for the trash directory, remote files cannot be restored with the respective tools, commit e6842038c9c48131503804b139872bd565a245d9 Author: Alan Third Date: Sat Feb 20 20:40:56 2021 +0000 Fix memory leak * src/nsterm.m ([EmacsSurface dealloc]): Release will remove all objects and free the memory. diff --git a/src/nsterm.m b/src/nsterm.m index 6551694abe..88317f8839 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -9767,7 +9767,7 @@ - (void) dealloc for (id object in cache) CFRelease ((IOSurfaceRef)object); - [cache removeAllObjects]; + [cache release]; [super dealloc]; } commit cf95b53405772d2f5bd5da91e57184f3de28a7f4 Author: Stefan Kangas Date: Sat Feb 20 17:43:03 2021 +0100 Convert makefile-mode menu to easy-menu-define * lisp/progmodes/make-mode.el (makefile-mode-map): Move menu definition from here... (makefile-mode-menu): ...to here, and rewrite using easy-menu-define. diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el index 3d1e7d634a..d444ce2999 100644 --- a/lisp/progmodes/make-mode.el +++ b/lisp/progmodes/make-mode.el @@ -573,8 +573,7 @@ The function must satisfy this calling convention: "Abbrev table in use in Makefile buffers.") (defvar makefile-mode-map - (let ((map (make-sparse-keymap)) - (opt-map (make-sparse-keymap))) + (let ((map (make-sparse-keymap))) ;; set up the keymap (define-key map "\C-c:" 'makefile-insert-target-ref) (if makefile-electric-keys @@ -599,72 +598,56 @@ The function must satisfy this calling convention: (define-key map "\M-p" 'makefile-previous-dependency) (define-key map "\M-n" 'makefile-next-dependency) (define-key map "\e\t" 'completion-at-point) - - ;; Make menus. - (define-key map [menu-bar makefile-mode] - (cons "Makefile" (make-sparse-keymap "Makefile"))) - - (define-key map [menu-bar makefile-mode makefile-type] - (cons "Switch Makefile Type" opt-map)) - (define-key opt-map [makefile-makepp-mode] - '(menu-item "Makepp" makefile-makepp-mode - :help "An adapted `makefile-mode' that knows about makepp" - :button (:radio . (eq major-mode 'makefile-makepp-mode)))) - (define-key opt-map [makefile-imake-mode] - '(menu-item "Imake" makefile-imake-mode - :help "An adapted `makefile-mode' that knows about imake" - :button (:radio . (eq major-mode 'makefile-imake-mode)))) - (define-key opt-map [makefile-mode] - '(menu-item "Classic" makefile-mode - :help "`makefile-mode' with no special functionality" - :button (:radio . (eq major-mode 'makefile-mode)))) - (define-key opt-map [makefile-bsdmake-mode] - '(menu-item "BSD" makefile-bsdmake-mode - :help "An adapted `makefile-mode' that knows about BSD make" - :button (:radio . (eq major-mode 'makefile-bsdmake-mode)))) - (define-key opt-map [makefile-automake-mode] - '(menu-item "Automake" makefile-automake-mode - :help "An adapted `makefile-mode' that knows about automake" - :button (:radio . (eq major-mode 'makefile-automake-mode)))) - (define-key opt-map [makefile-gmake-mode] - '(menu-item "GNU make" makefile-gmake-mode - :help "An adapted `makefile-mode' that knows about GNU make" - :button (:radio . (eq major-mode 'makefile-gmake-mode)))) - (define-key map [menu-bar makefile-mode browse] - '(menu-item "Pop up Makefile Browser" makefile-switch-to-browser - ;; XXX: this needs a better string, the function is not documented... - :help "Pop up Makefile Browser")) - (define-key map [menu-bar makefile-mode overview] - '(menu-item "Up To Date Overview" makefile-create-up-to-date-overview - :help "Create a buffer containing an overview of the state of all known targets")) - ;; Target related - (define-key map [menu-bar makefile-mode separator1] '("----")) - (define-key map [menu-bar makefile-mode pickup-file] - '(menu-item "Pick File Name as Target" makefile-pickup-filenames-as-targets - :help "Scan the current directory for filenames to use as targets")) - (define-key map [menu-bar makefile-mode function] - '(menu-item "Insert GNU make function" makefile-insert-gmake-function - :help "Insert a GNU make function call")) - (define-key map [menu-bar makefile-mode pickup] - '(menu-item "Find Targets and Macros" makefile-pickup-everything - :help "Notice names of all macros and targets in Makefile")) - (define-key map [menu-bar makefile-mode complete] - '(menu-item "Complete Target or Macro" completion-at-point - :help "Perform completion on Makefile construct preceding point")) - (define-key map [menu-bar makefile-mode backslash] - '(menu-item "Backslash Region" makefile-backslash-region - :help "Insert, align, or delete end-of-line backslashes on the lines in the region")) - ;; Motion - (define-key map [menu-bar makefile-mode separator] '("----")) - (define-key map [menu-bar makefile-mode prev] - '(menu-item "Move to Previous Dependency" makefile-previous-dependency - :help "Move point to the beginning of the previous dependency line")) - (define-key map [menu-bar makefile-mode next] - '(menu-item "Move to Next Dependency" makefile-next-dependency - :help "Move point to the beginning of the next dependency line")) map) "The keymap that is used in Makefile mode.") +(easy-menu-define makefile-mode-menu makefile-mode-map + "Menu for Makefile mode." + '("Makefile" + ;; Motion + ["Move to Next Dependency" makefile-next-dependency + :help "Move point to the beginning of the next dependency line"] + ["Move to Previous Dependency" makefile-previous-dependency + :help "Move point to the beginning of the previous dependency line"] + "----" + ;; Target related + ["Backslash Region" makefile-backslash-region + :help "Insert, align, or delete end-of-line backslashes on the lines in the region"] + ["Complete Target or Macro" completion-at-point + :help "Perform completion on Makefile construct preceding point"] + ["Find Targets and Macros" makefile-pickup-everything + :help "Notice names of all macros and targets in Makefile"] + ["Insert GNU make function" makefile-insert-gmake-function + :help "Insert a GNU make function call"] + ["Pick File Name as Target" makefile-pickup-filenames-as-targets + :help "Scan the current directory for filenames to use as targets"] + "----" + ;; Other. + ["Up To Date Overview" makefile-create-up-to-date-overview + :help "Create a buffer containing an overview of the state of all known targets"] + ["Pop up Makefile Browser" makefile-switch-to-browser + ;; XXX: this needs a better string, the function is not documented... + :help "Pop up Makefile Browser"] + ("Switch Makefile Type" + ["GNU make" makefile-gmake-mode + :help "An adapted `makefile-mode' that knows about GNU make" + :button (:radio . (eq major-mode 'makefile-gmake-mode))] + ["Automake" makefile-automake-mode + :help "An adapted `makefile-mode' that knows about automake" + :button (:radio . (eq major-mode 'makefile-automake-mode))] + ["BSD" makefile-bsdmake-mode + :help "An adapted `makefile-mode' that knows about BSD make" + :button (:radio . (eq major-mode 'makefile-bsdmake-mode))] + ["Classic" makefile-mode + :help "`makefile-mode' with no special functionality" + :button (:radio . (eq major-mode 'makefile-mode))] + ["Imake" makefile-imake-mode + :help "An adapted `makefile-mode' that knows about imake" + :button (:radio . (eq major-mode 'makefile-imake-mode))] + ["Makepp" makefile-makepp-mode + :help "An adapted `makefile-mode' that knows about makepp" + :button (:radio . (eq major-mode 'makefile-makepp-mode))]))) + (defvar makefile-browser-map (let ((map (make-sparse-keymap))) commit a6234bb5b4cfa9f073e324f01210adf368abc4f1 Author: F. Jason Park Date: Sat Feb 20 06:50:30 2021 -0800 Mute noisy test fixture for socks.el * test/lisp/net/socks-tests.el: (socks-tests-perform-hello-world-http-request): Bind 'inhibit-message' non-nil when in batch mode. (Bug#46342) diff --git a/test/lisp/net/socks-tests.el b/test/lisp/net/socks-tests.el index 9a2dcba9da..71bdd74890 100644 --- a/test/lisp/net/socks-tests.el +++ b/test/lisp/net/socks-tests.el @@ -173,6 +173,7 @@ Vectors must match verbatim. Strings are considered regex patterns.") (goto-char (point-min)) (should (search-forward "Hello World" nil t)) (setq done t))) + (inhibit-message noninteractive) (buf (url-http url cb '(nil))) (proc (get-buffer-process buf)) (attempts 10)) commit 496bed5cf4c9dc02f18741e3eacfaca78c373db6 Author: Lars Ingebrigtsen Date: Sat Feb 20 15:43:26 2021 +0100 Change command-completion-using-modes-p to defun * lisp/simple.el (command-completion-using-modes-p): Change into a defun for now because of a build problem. diff --git a/lisp/simple.el b/lisp/simple.el index 121b4d35a7..26710e6d53 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1994,7 +1994,7 @@ This function uses the `read-extended-command-predicate' user option." (funcall read-extended-command-predicate sym buffer))))) t nil 'extended-command-history)))) -(define-inline command-completion-using-modes-p (symbol buffer) +(defun command-completion-using-modes-p (symbol buffer) "Say whether SYMBOL has been marked as a mode-specific command in BUFFER." ;; Check the modes. (let ((modes (command-modes symbol))) commit 006d0ae396de59bce95bc0a3ff4648caee87babd Author: Lars Ingebrigtsen Date: Sat Feb 20 15:37:24 2021 +0100 Mention `M-S-x' in the Emacs manual. * doc/emacs/m-x.texi (M-x): Mention `M-S-x' in the Emacs manual. diff --git a/doc/emacs/m-x.texi b/doc/emacs/m-x.texi index c51f10a47a..d35a835154 100644 --- a/doc/emacs/m-x.texi +++ b/doc/emacs/m-x.texi @@ -58,6 +58,14 @@ Modes}). By default, no commands are excluded, but you can customize the option @code{read-extended-command-predicate} to exclude those irrelevant commands from completion results. +@kindex M-S-x + Conversely, Emacs can exclude all commands except those that are +particularly relevant to the current buffer. The @kbd{M-S-x} (that's +``meta shift x'') command works just like @kbd{M-x}, but instead of +listing all (or most) of the commands Emacs knows about, it will only +list the commands that have been marked as ``belonging'' to the +current major mode, or any enabled minor modes. + To cancel the @kbd{M-x} and not run a command, type @kbd{C-g} instead of entering the command name. This takes you back to command level. commit c4bbe02cc48f781a31d1709b61fcd218c5eb8b43 Author: Stefan Kangas Date: Sat Feb 20 15:25:32 2021 +0100 * lisp/help.el (help-for-help-internal): Doc fix; use imperative. diff --git a/lisp/help.el b/lisp/help.el index 48b9d79b18..88265680f9 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -216,7 +216,7 @@ I METHOD Describe a specific input method, or RET for current. k KEYS Display the full documentation for the key sequence. K KEYS Show the Emacs manual's section for the command bound to KEYS. l Show last 300 input keystrokes (lossage). -L LANG-ENV Describes a specific language environment, or RET for current. +L LANG-ENV Describe a specific language environment, or RET for current. m Display documentation of current minor modes and current major mode, including their special commands. n Display news of recent Emacs changes. commit 4c4c2eab7eaf81f87f8513a40b8a38a1c071cfe6 Author: Eli Zaretskii Date: Sat Feb 20 16:24:03 2021 +0200 ; Fix typos in last change * etc/NEWS: Improve wording. * lisp/simple.el (execute-extended-command-for-buffer): Fix typo. diff --git a/etc/NEWS b/etc/NEWS index b623b13b34..c4f4c1d9d8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -255,7 +255,7 @@ commands. The new keystrokes are 'C-x x g' ('revert-buffer'), ** New command 'execute-extended-command-for-buffer'. This new command, bound to 'M-S-x', works like 'execute-extended-command', but limits the set of commands to the -commands that have been determined to be particularly of use to the +commands that have been determined to be particularly useful with the current mode. +++ diff --git a/lisp/simple.el b/lisp/simple.el index 0e3a1ee905..121b4d35a7 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -2195,8 +2195,8 @@ invoking, give a prefix argument to `execute-extended-command'." (defun execute-extended-command-for-buffer (prefixarg &optional command-name typed) - "Query usert for a command relevant for the current mode and then execute it. -This is like `execute-extended-command', but limits the + "Query user for a command relevant for the current mode, and then execute it. +This is like `execute-extended-command', but it limits the completions to commands that are particularly relevant to the current buffer. This includes commands that have been marked as being specially designed for the current major mode (and enabled commit e3e3133f800cf4395dc4594b791276498e426c34 Author: Lars Ingebrigtsen Date: Sat Feb 20 15:12:45 2021 +0100 Add a new command for mode-specific commands * doc/lispref/commands.texi (Interactive Call): Document it. * lisp/simple.el (command-completion-using-modes-p): Refactored out into its own function for reuse... (command-completion-default-include-p): ... from here. (execute-extended-command-for-buffer): New command and keystroke (`M-S-x'). diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 1c762c27e8..8199ece110 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -851,6 +851,15 @@ non-@code{nil} if the command is to be included when completing in that buffer. @end deffn +@deffn Command execute-extended-command-for-buffer prefix-argument +This is like @code{execute-extended-command}, but limits the commands +offered for completion to those commands that are of particular +relevance to the current major mode (and enabled minor modes). This +includes commands that are tagged with the modes (@pxref{Using +Interactive}), and also commands that are bound to locally active +keymaps. +@end deffn + @node Distinguish Interactive @section Distinguish Interactive Calls @cindex distinguish interactive calls diff --git a/etc/NEWS b/etc/NEWS index c0c292aebc..b623b13b34 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -251,6 +251,13 @@ commands. The new keystrokes are 'C-x x g' ('revert-buffer'), * Editing Changes in Emacs 28.1 ++++ +** New command 'execute-extended-command-for-buffer'. +This new command, bound to 'M-S-x', works like +'execute-extended-command', but limits the set of commands to the +commands that have been determined to be particularly of use to the +current mode. + +++ ** New user option 'read-extended-command-predicate'. This option controls how 'M-x' performs completion of commands when diff --git a/lisp/simple.el b/lisp/simple.el index 7c0b6e1d74..0e3a1ee905 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1994,6 +1994,26 @@ This function uses the `read-extended-command-predicate' user option." (funcall read-extended-command-predicate sym buffer))))) t nil 'extended-command-history)))) +(define-inline command-completion-using-modes-p (symbol buffer) + "Say whether SYMBOL has been marked as a mode-specific command in BUFFER." + ;; Check the modes. + (let ((modes (command-modes symbol))) + ;; Common case: Just a single mode. + (if (null (cdr modes)) + (or (provided-mode-derived-p + (buffer-local-value 'major-mode buffer) (car modes)) + (memq (car modes) + (buffer-local-value 'local-minor-modes buffer)) + (memq (car modes) global-minor-modes)) + ;; Uncommon case: Multiple modes. + (apply #'provided-mode-derived-p + (buffer-local-value 'major-mode buffer) + modes) + (seq-intersection modes + (buffer-local-value 'local-minor-modes buffer) + #'eq) + (seq-intersection modes global-minor-modes #'eq)))) + (defun command-completion-default-include-p (symbol buffer) "Say whether SYMBOL should be offered as a completion. If there's a `completion-predicate' for SYMBOL, the result from @@ -2004,24 +2024,8 @@ BUFFER." (if (get symbol 'completion-predicate) ;; An explicit completion predicate takes precedence. (funcall (get symbol 'completion-predicate) symbol buffer) - ;; Check the modes. - (let ((modes (command-modes symbol))) - (or (null modes) - ;; Common case: Just a single mode. - (if (null (cdr modes)) - (or (provided-mode-derived-p - (buffer-local-value 'major-mode buffer) (car modes)) - (memq (car modes) - (buffer-local-value 'local-minor-modes buffer)) - (memq (car modes) global-minor-modes)) - ;; Uncommon case: Multiple modes. - (apply #'provided-mode-derived-p - (buffer-local-value 'major-mode buffer) - modes) - (seq-intersection modes - (buffer-local-value 'local-minor-modes buffer) - #'eq) - (seq-intersection modes global-minor-modes #'eq)))))) + (or (null (command-modes symbol)) + (command-completion-using-modes-p symbol buffer)))) (defun command-completion-with-modes-p (modes buffer) "Say whether MODES are in action in BUFFER. @@ -2189,6 +2193,38 @@ invoking, give a prefix argument to `execute-extended-command'." suggest-key-bindings 2)))))))) +(defun execute-extended-command-for-buffer (prefixarg &optional + command-name typed) + "Query usert for a command relevant for the current mode and then execute it. +This is like `execute-extended-command', but limits the +completions to commands that are particularly relevant to the +current buffer. This includes commands that have been marked as +being specially designed for the current major mode (and enabled +minor modes), as well as commands bound in the active local key +maps." + (declare (interactive-only command-execute)) + (interactive + (let* ((execute-extended-command--last-typed nil) + (keymaps + ;; The major mode's keymap and any active minor modes. + (cons + (current-local-map) + (mapcar + #'cdr + (seq-filter + (lambda (elem) + (symbol-value (car elem))) + minor-mode-map-alist)))) + (read-extended-command-predicate + (lambda (symbol buffer) + (or (command-completion-using-modes-p symbol buffer) + (where-is-internal symbol keymaps))))) + (list current-prefix-arg + (read-extended-command) + execute-extended-command--last-typed))) + (with-suppressed-warnings ((interactive-only execute-extended-command)) + (execute-extended-command prefixarg command-name typed))) + (defun command-execute (cmd &optional record-flag keys special) ;; BEWARE: Called directly from the C code. "Execute CMD as an editor command. diff --git a/lisp/subr.el b/lisp/subr.el index f9bb1bb3ad..cf70b249cf 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1305,6 +1305,7 @@ in a cleaner way with command remapping, like this: (define-key map "l" #'downcase-word) (define-key map "c" #'capitalize-word) (define-key map "x" #'execute-extended-command) + (define-key map "X" #'execute-extended-command-for-buffer) map) "Default keymap for ESC (meta) commands. The normal global definition of the character ESC indirects to this keymap.") commit 12578d6aca2cc7182afdd070aa31c7aff6a3add8 Author: Lars Ingebrigtsen Date: Sat Feb 20 14:29:41 2021 +0100 Change how (declare (modes store the data * lisp/emacs-lisp/byte-run.el (byte-run--set-modes): Change from being a predicate to storing the modes. This allows using the modes for positive command discovery, too. * src/data.c (Fcommand_modes): Look at the `command-modes' symbol property, too. diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index 76e7f01ace..afe94bb035 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el @@ -154,9 +154,7 @@ The return value of this function is not used." (defalias 'byte-run--set-modes #'(lambda (f _args &rest val) (list 'function-put (list 'quote f) - ''completion-predicate - `(lambda (_ b) - (command-completion-with-modes-p ',val b))))) + ''command-modes (list 'quote val)))) ;; Add any new entries to info node `(elisp)Declare Form'. (defvar defun-declarations-alist diff --git a/src/data.c b/src/data.c index ace859d2d0..9af9131b12 100644 --- a/src/data.c +++ b/src/data.c @@ -957,9 +957,17 @@ The value, if non-nil, is a list of mode name symbols. */) if (NILP (fun)) return Qnil; + /* Use a `command-modes' property if present, analogous to the + function-documentation property. */ fun = command; while (SYMBOLP (fun)) - fun = Fsymbol_function (fun); + { + Lisp_Object modes = Fget (fun, Qcommand_modes); + if (!NILP (modes)) + return modes; + else + fun = Fsymbol_function (fun); + } if (COMPILEDP (fun)) { commit 825aed11d267f7879ca8915eb2b0d154e0beb2d4 Author: Lars Ingebrigtsen Date: Sat Feb 20 13:44:19 2021 +0100 Add the `always' function * doc/lispref/functions.texi (Calling Functions): Document it. * lisp/subr.el (always): New function. * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Mark it as side effect free. diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index 1e3da8e3a5..2a9b57f19f 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi @@ -861,6 +861,10 @@ This function returns @var{argument} and has no side effects. @defun ignore &rest arguments This function ignores any @var{arguments} and returns @code{nil}. +@end defun + +@defun always &rest arguments +This function ignores any @var{arguments} and returns @code{t}. @end defun Some functions are user-visible @dfn{commands}, which can be called diff --git a/etc/NEWS b/etc/NEWS index ee8a68a259..c0c292aebc 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2305,6 +2305,10 @@ back in Emacs 23.1. The affected functions are: 'make-obsolete', * Lisp Changes in Emacs 28.1 ++++ +** New function 'always'. +This is identical to 'ignore', but returns t instead. + +++ ** New forms to declare how completion should happen has been added. '(declare (completion PREDICATE))' can be used as a general predicate diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index e0feb95a46..9f0ba232a4 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -1348,7 +1348,7 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") window-total-height window-total-width window-use-time window-vscroll window-width zerop)) (side-effect-and-error-free-fns - '(arrayp atom + '(always arrayp atom bignump bobp bolp bool-vector-p buffer-end buffer-list buffer-size buffer-string bufferp car-safe case-table-p cdr-safe char-or-string-p characterp diff --git a/lisp/subr.el b/lisp/subr.el index 490aec93f1..f9bb1bb3ad 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -373,10 +373,17 @@ PREFIX is a string, and defaults to \"g\"." (defun ignore (&rest _arguments) "Do nothing and return nil. -This function accepts any number of ARGUMENTS, but ignores them." +This function accepts any number of ARGUMENTS, but ignores them. +Also see `always'." (interactive) nil) +(defun always (&rest _arguments) + "Do nothing and return t. +This function accepts any number of ARGUMENTS, but ignores them. +Also see `ignore'." + t) + ;; Signal a compile-error if the first arg is missing. (defun error (&rest args) "Signal an error, making a message by passing ARGS to `format-message'. commit 43703a06b9ea31b86c46bef7cb488ea885569ddc Author: F. Jason Park Date: Fri Feb 5 19:41:04 2021 -0800 Use raw bytes for SOCKS 4 IP addresses * lisp/net/socks.el: (socks--open-network-stream, socks-send-command): * test/lisp/net/socks-tests.el: (socks-tests-v4-basic): (Bug#46342). diff --git a/lisp/net/socks.el b/lisp/net/socks.el index 96fafc826b..1da1d31d67 100644 --- a/lisp/net/socks.el +++ b/lisp/net/socks.el @@ -390,6 +390,8 @@ proc))) (defun socks-send-command (proc command atype address port) + "Send COMMAND to SOCKS service PROC for proxying ADDRESS and PORT. +When ATYPE indicates an IP, param ADDRESS must be given as raw bytes." (let ((addr (cond ((or (= atype socks-address-type-v4) (= atype socks-address-type-v6)) @@ -528,7 +530,7 @@ (setq host (socks-nslookup-host host)) (if (not (listp host)) (error "Could not get IP address for: %s" host)) - (setq host (apply #'format "%c%c%c%c" host)) + (setq host (apply #'unibyte-string host)) socks-address-type-v4) (t socks-address-type-name)))) diff --git a/test/lisp/net/socks-tests.el b/test/lisp/net/socks-tests.el index 340a42d79c..9a2dcba9da 100644 --- a/test/lisp/net/socks-tests.el +++ b/test/lisp/net/socks-tests.el @@ -185,6 +185,26 @@ Vectors must match verbatim. Strings are considered regex patterns.") (kill-buffer buf) (ignore url-gateway-method))) +;; Unlike curl, socks.el includes the ID field (but otherwise matches): +;; $ curl --proxy socks4://127.0.0.1:1080 example.com + +(ert-deftest socks-tests-v4-basic () + "Show correct preparation of SOCKS4 connect command (Bug#46342)." + (let ((socks-server '("server" "127.0.0.1" 10079 4)) + (url-user-agent "Test/4-basic") + (socks-tests-canned-server-patterns + `(([4 1 0 80 93 184 216 34 ?f ?o ?o 0] . [0 90 0 0 0 0 0 0]) + ,socks-tests--hello-world-http-request-pattern)) + socks-nslookup-program) + (ert-info ("Make HTTP request over SOCKS4") + (cl-letf (((symbol-function 'socks-nslookup-host) + (lambda (host) + (should (equal host "example.com")) + (list 93 184 216 34))) + ((symbol-function 'user-full-name) + (lambda () "foo"))) + (socks-tests-perform-hello-world-http-request))))) + ;; Replace first pattern below with ([5 3 0 1 2] . [5 2]) to validate ;; against curl 7.71 with the following options: ;; $ curl --verbose -U foo:bar --proxy socks5h://127.0.0.1:10080 example.com commit acf71609200e56ef28f31be0df33ea3905eb2188 Author: F. Jason Park Date: Fri Feb 5 05:24:55 2021 -0800 Add more auth-related tests for socks.el * test/lisp/net/socks-tests.el (auth-registration-and-suite-offer) (filter-response-parsing-v4, filter-response-parsing-v5): Assert auth-method selection wrangling and socks-filter parsing. (v5-auth-user-pass, v5-auth-user-pass-blank, v5-auth-none): Show prep and execution of the SOCKS connect command and proxying of an HTTP request; simplify fake server. (Bug#46342) diff --git a/test/lisp/net/socks-tests.el b/test/lisp/net/socks-tests.el index b378ed2964..340a42d79c 100644 --- a/test/lisp/net/socks-tests.el +++ b/test/lisp/net/socks-tests.el @@ -21,68 +21,151 @@ ;;; Code: +(require 'ert) (require 'socks) (require 'url-http) -(defvar socks-tests-canned-server-port nil) +(ert-deftest socks-tests-auth-registration-and-suite-offer () + (ert-info ("Default favors user/pass auth") + (should (equal socks-authentication-methods + '((2 "Username/Password" . socks-username/password-auth) + (0 "No authentication" . identity)))) + (should (equal "\2\0\2" (socks-build-auth-list)))) ; length [offer ...] + (let (socks-authentication-methods) + (ert-info ("Empty selection/no methods offered") + (should (equal "\0" (socks-build-auth-list)))) + (ert-info ("Simulate library defaults") + (socks-register-authentication-method 0 "No authentication" + 'identity) + (should (equal socks-authentication-methods + '((0 "No authentication" . identity)))) + (should (equal "\1\0" (socks-build-auth-list))) + (socks-register-authentication-method 2 "Username/Password" + 'socks-username/password-auth) + (should (equal socks-authentication-methods + '((2 "Username/Password" . socks-username/password-auth) + (0 "No authentication" . identity)))) + (should (equal "\2\0\2" (socks-build-auth-list)))) + (ert-info ("Removal") + (socks-unregister-authentication-method 2) + (should (equal socks-authentication-methods + '((0 "No authentication" . identity)))) + (should (equal "\1\0" (socks-build-auth-list))) + (socks-unregister-authentication-method 0) + (should-not socks-authentication-methods) + (should (equal "\0" (socks-build-auth-list)))))) -(defun socks-tests-canned-server-create (verbatim patterns) - "Create a fake SOCKS server and return the process. +(ert-deftest socks-tests-filter-response-parsing-v4 () + "Ensure new chunks added on right (Bug#45162)." + (let* ((buf (generate-new-buffer "*test-socks-filter*")) + (proc (start-process "test-socks-filter" buf "sleep" "1"))) + (process-put proc 'socks t) + (process-put proc 'socks-state socks-state-waiting) + (process-put proc 'socks-server-protocol 4) + (ert-info ("Receive initial incomplete segment") + (socks-filter proc (concat [0 90 0 0 93 184 216])) + ;; From example.com: OK status ^ ^ msg start + (ert-info ("State still set to waiting") + (should (eq (process-get proc 'socks-state) socks-state-waiting))) + (ert-info ("Response field is nil because processing incomplete") + (should-not (process-get proc 'socks-response))) + (ert-info ("Scratch field holds stashed partial payload") + (should (string= (concat [0 90 0 0 93 184 216]) + (process-get proc 'socks-scratch))))) + (ert-info ("Last part arrives") + (socks-filter proc "\42") ; ?\" 34 + (ert-info ("State transitions to complete (length check passes)") + (should (eq (process-get proc 'socks-state) socks-state-connected))) + (ert-info ("Scratch and response fields hold stash w. last chunk") + (should (string= (concat [0 90 0 0 93 184 216 34]) + (process-get proc 'socks-response))) + (should (string= (process-get proc 'socks-response) + (process-get proc 'socks-scratch))))) + (delete-process proc) + (kill-buffer buf))) -`VERBATIM' and `PATTERNS' are dotted alists containing responses. -Requests are tried in order. On failure, an error is raised." - (let* ((buf (generate-new-buffer "*canned-socks-server*")) +(ert-deftest socks-tests-filter-response-parsing-v5 () + "Ensure new chunks added on right (Bug#45162)." + (let* ((buf (generate-new-buffer "*test-socks-filter*")) + (proc (start-process "test-socks-filter" buf "sleep" "1"))) + (process-put proc 'socks t) + (process-put proc 'socks-state socks-state-waiting) + (process-put proc 'socks-server-protocol 5) + (ert-info ("Receive initial incomplete segment") + ;; From fedora.org: 2605:bc80:3010:600:dead:beef:cafe:fed9 + ;; 5004 ~~> Version Status (OK) NOOP Addr-Type (4 -> IPv6) + (socks-filter proc "\5\0\0\4\x26\x05\xbc\x80\x30\x10\x00\x60") + (ert-info ("State still waiting and response emtpy") + (should (eq (process-get proc 'socks-state) socks-state-waiting)) + (should-not (process-get proc 'socks-response))) + (ert-info ("Scratch field holds partial payload of pending msg") + (should (string= "\5\0\0\4\x26\x05\xbc\x80\x30\x10\x00\x60" + (process-get proc 'socks-scratch))))) + (ert-info ("Middle chunk arrives") + (socks-filter proc "\xde\xad\xbe\xef\xca\xfe\xfe\xd9") + (ert-info ("State and response fields still untouched") + (should (eq (process-get proc 'socks-state) socks-state-waiting)) + (should-not (process-get proc 'socks-response))) + (ert-info ("Scratch contains new arrival appended (on RHS)") + (should (string= (concat "\5\0\0\4" + "\x26\x05\xbc\x80\x30\x10\x00\x60" + "\xde\xad\xbe\xef\xca\xfe\xfe\xd9") + (process-get proc 'socks-scratch))))) + (ert-info ("Final part arrives (port number)") + (socks-filter proc "\0\0") + (ert-info ("State transitions to complete") + (should (eq (process-get proc 'socks-state) socks-state-connected))) + (ert-info ("Scratch and response fields show last chunk appended") + (should (string= (concat "\5\0\0\4" + "\x26\x05\xbc\x80\x30\x10\x00\x60" + "\xde\xad\xbe\xef\xca\xfe\xfe\xd9" + "\0\0") + (process-get proc 'socks-scratch))) + (should (string= (process-get proc 'socks-response) + (process-get proc 'socks-scratch))))) + (delete-process proc) + (kill-buffer buf))) + +(defvar socks-tests-canned-server-patterns nil + "Alist containing request/response cons pairs to be tried in order. +Vectors must match verbatim. Strings are considered regex patterns.") + +(defun socks-tests-canned-server-create () + "Create and return a fake SOCKS server." + (let* ((port (nth 2 socks-server)) + (name (format "socks-server:%d" port)) + (pats socks-tests-canned-server-patterns) (filt (lambda (proc line) - (let ((resp (or (assoc-default line verbatim - (lambda (k s) ; s is line - (string= (concat k) s))) - (assoc-default line patterns - (lambda (p s) - (string-match-p p s)))))) - (unless resp + (pcase-let ((`(,pat . ,resp) (pop pats))) + (unless (or (and (vectorp pat) (equal pat (vconcat line))) + (string-match-p pat line)) (error "Unknown request: %s" line)) (let ((print-escape-control-characters t)) - (princ (format "<- %s\n" (prin1-to-string line)) buf) - (princ (format "-> %s\n" (prin1-to-string resp)) buf)) + (message "[%s] <- %s" name (prin1-to-string line)) + (message "[%s] -> %s" name (prin1-to-string resp))) (process-send-string proc (concat resp))))) - (srv (make-network-process :server 1 - :buffer buf - :filter filt - :name "server" - :family 'ipv4 - :host 'local - :service socks-tests-canned-server-port))) - (set-process-query-on-exit-flag srv nil) - (princ (format "[%s] Listening on localhost:10080\n" srv) buf) - srv)) - -;; Add ([5 3 0 1 2] . [5 2]) to the `verbatim' list below to validate -;; against curl 7.71 with the following options: -;; $ curl --verbose -U foo:bar --proxy socks5h://127.0.0.1:10080 example.com -;; -;; If later implementing version 4a, try these: -;; [4 1 0 80 0 0 0 1 0 ?e ?x ?a ?m ?p ?l ?e ?. ?c ?o ?m 0] . [0 90 0 0 0 0 0 0] -;; $ curl --verbose --proxy socks4a://127.0.0.1:10080 example.com + (serv (make-network-process :server 1 + :buffer (get-buffer-create name) + :filter filt + :name name + :family 'ipv4 + :host 'local + :coding 'binary + :service port))) + (set-process-query-on-exit-flag serv nil) + serv)) -(ert-deftest socks-tests-auth-filter-url-http () - "Verify correct handling of SOCKS5 user/pass authentication." - (let* ((socks-server '("server" "127.0.0.1" 10080 5)) - (socks-username "foo") - (socks-password "bar") - (url-gateway-method 'socks) +(defvar socks-tests--hello-world-http-request-pattern + (cons "^GET /" (concat "HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 13\r\n\r\n" + "Hello World!\n"))) + +(defun socks-tests-perform-hello-world-http-request () + "Start canned server, validate hello-world response, and finalize." + (let* ((url-gateway-method 'socks) (url (url-generic-parse-url "http://example.com")) - (verbatim '(([5 2 0 2] . [5 2]) - ([1 3 ?f ?o ?o 3 ?b ?a ?r] . [1 0]) - ([5 1 0 3 11 ?e ?x ?a ?m ?p ?l ?e ?. ?c ?o ?m 0 80] - . [5 0 0 1 0 0 0 0 0 0]))) - (patterns - `(("^GET /" . ,(concat "HTTP/1.1 200 OK\r\n" - "Content-Type: text/plain; charset=UTF-8\r\n" - "Content-Length: 13\r\n\r\n" - "Hello World!\n")))) - (socks-tests-canned-server-port 10080) - (server (socks-tests-canned-server-create verbatim patterns)) - (tries 10) + (server (socks-tests-canned-server-create)) ;; done ;; @@ -90,14 +173,91 @@ Requests are tried in order. On failure, an error is raised." (goto-char (point-min)) (should (search-forward "Hello World" nil t)) (setq done t))) - (buf (url-http url cb '(nil)))) - (ert-info ("Connect to HTTP endpoint over SOCKS5 with USER/PASS method") - (while (and (not done) (< 0 (cl-decf tries))) ; cl-lib via url-http - (sleep-for 0.1))) + (buf (url-http url cb '(nil))) + (proc (get-buffer-process buf)) + (attempts 10)) + (while (and (not done) (< 0 (cl-decf attempts))) + (sleep-for 0.1)) (should done) (delete-process server) + (delete-process proc) ; otherwise seems client proc is sometimes reused (kill-buffer (process-buffer server)) (kill-buffer buf) (ignore url-gateway-method))) +;; Replace first pattern below with ([5 3 0 1 2] . [5 2]) to validate +;; against curl 7.71 with the following options: +;; $ curl --verbose -U foo:bar --proxy socks5h://127.0.0.1:10080 example.com + +(ert-deftest socks-tests-v5-auth-user-pass () + "Verify correct handling of SOCKS5 user/pass authentication." + (should (assq 2 socks-authentication-methods)) + (let ((socks-server '("server" "127.0.0.1" 10080 5)) + (socks-username "foo") + (socks-password "bar") + (url-user-agent "Test/auth-user-pass") + (socks-tests-canned-server-patterns + `(([5 2 0 2] . [5 2]) + ([1 3 ?f ?o ?o 3 ?b ?a ?r] . [1 0]) + ([5 1 0 3 11 ?e ?x ?a ?m ?p ?l ?e ?. ?c ?o ?m 0 80] + . [5 0 0 1 0 0 0 0 0 0]) + ,socks-tests--hello-world-http-request-pattern))) + (ert-info ("Make HTTP request over SOCKS5 with USER/PASS auth method") + (socks-tests-perform-hello-world-http-request)))) + +;; Services (like Tor) may be configured without auth but for some +;; reason still prefer the user/pass method over none when offered both. +;; Given this library's defaults, the scenario below is possible. +;; +;; FYI: RFC 1929 doesn't say that a username or password is required +;; but notes that the length of both fields should be at least one. +;; However, both socks.el and curl send zero-length fields (though +;; curl drops the user part too when the password is empty). +;; +;; From Tor's docs /socks-extensions.txt, 1.1 Extent of support: +;; > We allow username/password fields of this message to be empty ... +;; line 41 in blob 5fd1f828f3e9d014f7b65fa3bd1d33c39e4129e2 +;; https://gitweb.torproject.org/torspec.git/tree/socks-extensions.txt +;; +;; To verify against curl 7.71, swap out the first two pattern pairs +;; with ([5 3 0 1 2] . [5 2]) and ([1 0 0] . [1 0]), then run: +;; $ curl verbose -U "foo:" --proxy socks5h://127.0.0.1:10081 example.com + +(ert-deftest socks-tests-v5-auth-user-pass-blank () + "Verify correct SOCKS5 user/pass authentication with empty pass." + (should (assq 2 socks-authentication-methods)) + (let ((socks-server '("server" "127.0.0.1" 10081 5)) + (socks-username "foo") ; defaults to (user-login-name) + (socks-password "") ; simulate user hitting enter when prompted + (url-user-agent "Test/auth-user-pass-blank") + (socks-tests-canned-server-patterns + `(([5 2 0 2] . [5 2]) + ([1 3 ?f ?o ?o 0] . [1 0]) + ([5 1 0 3 11 ?e ?x ?a ?m ?p ?l ?e ?. ?c ?o ?m 0 80] + . [5 0 0 1 0 0 0 0 0 0]) + ,socks-tests--hello-world-http-request-pattern))) + (ert-info ("Make HTTP request over SOCKS5 with USER/PASS auth method") + (socks-tests-perform-hello-world-http-request)))) + +;; Swap out ([5 2 0 1] . [5 0]) with the first pattern below to validate +;; against curl 7.71 with the following options: +;; $ curl --verbose --proxy socks5h://127.0.0.1:10082 example.com + +(ert-deftest socks-tests-v5-auth-none () + "Verify correct handling of SOCKS5 when auth method 0 requested." + (let ((socks-server '("server" "127.0.0.1" 10082 5)) + (socks-authentication-methods (append socks-authentication-methods + nil)) + (url-user-agent "Test/auth-none") + (socks-tests-canned-server-patterns + `(([5 1 0] . [5 0]) + ([5 1 0 3 11 ?e ?x ?a ?m ?p ?l ?e ?. ?c ?o ?m 0 80] + . [5 0 0 1 0 0 0 0 0 0]) + ,socks-tests--hello-world-http-request-pattern))) + (socks-unregister-authentication-method 2) + (should-not (assq 2 socks-authentication-methods)) + (ert-info ("Make HTTP request over SOCKS5 with no auth method") + (socks-tests-perform-hello-world-http-request))) + (should (assq 2 socks-authentication-methods))) + ;;; socks-tests.el ends here commit d184895a42b37718cded839b95252e7bb165bcfd Author: Stefan Kangas Date: Sat Feb 20 07:34:52 2021 +0100 Convert re-builder menu to easy-menu-define * lisp/emacs-lisp/re-builder.el (reb-mode-map): Move menu definition from here... (reb-mode-menu): ...to here, and rewrite using easy-menu-define. diff --git a/lisp/emacs-lisp/re-builder.el b/lisp/emacs-lisp/re-builder.el index ce8d98df80..7f404c8296 100644 --- a/lisp/emacs-lisp/re-builder.el +++ b/lisp/emacs-lisp/re-builder.el @@ -217,8 +217,7 @@ Except for Lisp syntax this is the same as `reb-regexp'.") ;; Define the local "\C-c" keymap (defvar reb-mode-map - (let ((map (make-sparse-keymap)) - (menu-map (make-sparse-keymap))) + (let ((map (make-sparse-keymap))) (define-key map "\C-c\C-c" 'reb-toggle-case) (define-key map "\C-c\C-q" 'reb-quit) (define-key map "\C-c\C-w" 'reb-copy) @@ -228,43 +227,37 @@ Except for Lisp syntax this is the same as `reb-regexp'.") (define-key map "\C-c\C-e" 'reb-enter-subexp-mode) (define-key map "\C-c\C-b" 'reb-change-target-buffer) (define-key map "\C-c\C-u" 'reb-force-update) - (define-key map [menu-bar reb-mode] (cons "Re-Builder" menu-map)) - (define-key menu-map [rq] - '(menu-item "Quit" reb-quit - :help "Quit the RE Builder mode")) - (define-key menu-map [div1] '(menu-item "--")) - (define-key menu-map [rt] - '(menu-item "Case sensitive" reb-toggle-case - :button (:toggle . (with-current-buffer - reb-target-buffer - (null case-fold-search))) - :help "Toggle case sensitivity of searches for RE Builder target buffer")) - (define-key menu-map [rb] - '(menu-item "Change target buffer..." reb-change-target-buffer - :help "Change the target buffer and display it in the target window")) - (define-key menu-map [rs] - '(menu-item "Change syntax..." reb-change-syntax - :help "Change the syntax used by the RE Builder")) - (define-key menu-map [div2] '(menu-item "--")) - (define-key menu-map [re] - '(menu-item "Enter subexpression mode" reb-enter-subexp-mode - :help "Enter the subexpression mode in the RE Builder")) - (define-key menu-map [ru] - '(menu-item "Force update" reb-force-update - :help "Force an update in the RE Builder target window without a match limit")) - (define-key menu-map [rn] - '(menu-item "Go to next match" reb-next-match - :help "Go to next match in the RE Builder target window")) - (define-key menu-map [rp] - '(menu-item "Go to previous match" reb-prev-match - :help "Go to previous match in the RE Builder target window")) - (define-key menu-map [div3] '(menu-item "--")) - (define-key menu-map [rc] - '(menu-item "Copy current RE" reb-copy - :help "Copy current RE into the kill ring for later insertion")) map) "Keymap used by the RE Builder.") +(easy-menu-define reb-mode-menu reb-mode-map + "Menu for the RE Builder." + '("Re-Builder" + ["Copy current RE" reb-copy + :help "Copy current RE into the kill ring for later insertion"] + "---" + ["Go to previous match" reb-prev-match + :help "Go to previous match in the RE Builder target window"] + ["Go to next match" reb-next-match + :help "Go to next match in the RE Builder target window"] + ["Force update" reb-force-update + :help "Force an update in the RE Builder target window without a match limit"] + ["Enter subexpression mode" reb-enter-subexp-mode + :help "Enter the subexpression mode in the RE Builder"] + "---" + ["Change syntax..." reb-change-syntax + :help "Change the syntax used by the RE Builder"] + ["Change target buffer..." reb-change-target-buffer + :help "Change the target buffer and display it in the target window"] + ["Case sensitive" reb-toggle-case + :button (:toggle . (with-current-buffer + reb-target-buffer + (null case-fold-search))) + :help "Toggle case sensitivity of searches for RE Builder target buffer"] + "---" + ["Quit" reb-quit + :help "Quit the RE Builder mode"])) + (define-derived-mode reb-mode nil "RE Builder" "Major mode for interactively building Regular Expressions." (setq-local blink-matching-paren nil) @@ -368,7 +361,6 @@ matching parts of the target buffer will be highlighted." (defun reb-change-target-buffer (buf) "Change the target buffer and display it in the target window." (interactive "bSet target buffer to: ") - (let ((buffer (get-buffer buf))) (if (not buffer) (error "No such buffer") @@ -381,7 +373,6 @@ matching parts of the target buffer will be highlighted." (defun reb-force-update () "Force an update in the RE Builder target window without a match limit." (interactive) - (let ((reb-auto-match-limit nil)) (reb-update-overlays (if reb-subexp-mode reb-subexp-displayed nil)))) @@ -389,7 +380,6 @@ matching parts of the target buffer will be highlighted." (defun reb-quit () "Quit the RE Builder mode." (interactive) - (setq reb-subexp-mode nil reb-subexp-displayed nil) (reb-delete-overlays) @@ -399,7 +389,6 @@ matching parts of the target buffer will be highlighted." (defun reb-next-match () "Go to next match in the RE Builder target window." (interactive) - (reb-assert-buffer-in-window) (with-selected-window reb-target-window (if (not (re-search-forward reb-regexp (point-max) t)) @@ -411,7 +400,6 @@ matching parts of the target buffer will be highlighted." (defun reb-prev-match () "Go to previous match in the RE Builder target window." (interactive) - (reb-assert-buffer-in-window) (with-selected-window reb-target-window (let ((p (point))) @@ -426,7 +414,6 @@ matching parts of the target buffer will be highlighted." (defun reb-toggle-case () "Toggle case sensitivity of searches for RE Builder target buffer." (interactive) - (with-current-buffer reb-target-buffer (setq case-fold-search (not case-fold-search))) (reb-update-modestring) @@ -435,7 +422,6 @@ matching parts of the target buffer will be highlighted." (defun reb-copy () "Copy current RE into the kill ring for later insertion." (interactive) - (reb-update-regexp) (let ((re (with-output-to-string (print (reb-target-binding reb-regexp))))) @@ -503,7 +489,6 @@ Optional argument SYNTAX must be specified if called non-interactively." (defun reb-do-update (&optional subexp) "Update matches in the RE Builder target window. If SUBEXP is non-nil mark only the corresponding sub-expressions." - (reb-assert-buffer-in-window) (reb-update-regexp) (reb-update-overlays subexp)) @@ -541,7 +526,6 @@ optional fourth argument FORCE is non-nil." (defun reb-assert-buffer-in-window () "Assert that `reb-target-buffer' is displayed in `reb-target-window'." - (if (not (eq reb-target-buffer (window-buffer reb-target-window))) (set-window-buffer reb-target-window reb-target-buffer))) @@ -560,7 +544,6 @@ optional fourth argument FORCE is non-nil." (defun reb-display-subexp (&optional subexp) "Highlight only subexpression SUBEXP in the RE Builder." (interactive) - (setq reb-subexp-displayed (or subexp (string-to-number (format "%c" last-command-event)))) (reb-update-modestring) @@ -568,7 +551,6 @@ optional fourth argument FORCE is non-nil." (defun reb-kill-buffer () "When the RE Builder buffer is killed make sure no overlays stay around." - (when (reb-mode-buffer-p) (reb-delete-overlays))) @@ -600,7 +582,6 @@ optional fourth argument FORCE is non-nil." (defun reb-insert-regexp () "Insert current RE." - (let ((re (or (reb-target-binding reb-regexp) (reb-empty-regexp)))) (cond ((eq reb-re-syntax 'read) @@ -636,7 +617,6 @@ Return t if the (cooked) expression changed." ;; And now the real core of the whole thing (defun reb-count-subexps (re) "Return number of sub-expressions in the regexp RE." - (let ((i 0) (beg 0)) (while (string-match "\\\\(" re beg) (setq i (1+ i) commit 7b12747e2f2136bc76bfbeb3648131281ec14961 Author: Stefan Kangas Date: Sat Feb 20 06:59:02 2021 +0100 Convert finder menu to easy-menu-define * lisp/finder.el (finder-mode-map): Move menu definition from here... (finder-mode-menu): ...to here, and rewrite using easy-menu-define. diff --git a/lisp/finder.el b/lisp/finder.el index 15c3fcbac7..2c3869b508 100644 --- a/lisp/finder.el +++ b/lisp/finder.el @@ -90,24 +90,21 @@ Each element has the form (KEYWORD . DESCRIPTION).") (define-key map "p" 'previous-line) (define-key map "q" 'finder-exit) (define-key map "d" 'finder-list-keywords) - - (define-key map [menu-bar finder-mode] - (cons "Finder" menu-map)) - (define-key menu-map [finder-exit] - '(menu-item "Quit" finder-exit - :help "Exit Finder mode")) - (define-key menu-map [finder-summary] - '(menu-item "Summary" finder-summary - :help "Summary item on current line in a finder buffer")) - (define-key menu-map [finder-list-keywords] - '(menu-item "List keywords" finder-list-keywords - :help "Display descriptions of the keywords in the Finder buffer")) - (define-key menu-map [finder-select] - '(menu-item "Select" finder-select - :help "Select item on current line in a finder buffer")) map) "Keymap used in `finder-mode'.") +(easy-menu-define finder-mode-menu finder-mode-map + "Menu for `finder-mode'." + '("Finder" + ["Select" finder-select + :help "Select item on current line in a finder buffer"] + ["List keywords" finder-list-keywords + :help "Display descriptions of the keywords in the Finder buffer"] + ["Summary" finder-summary + :help "Summary item on current line in a finder buffer"] + ["Quit" finder-exit + :help "Exit Finder mode"])) + (defvar finder-mode-syntax-table (let ((st (make-syntax-table emacs-lisp-mode-syntax-table))) (modify-syntax-entry ?\; ". " st) commit c85c8e7d42ae2a5fc95fa7b14257389d8383b34d Author: Stefan Kangas Date: Sat Feb 20 05:55:33 2021 +0100 Add toolbar for help-mode * lisp/help-mode.el (help-mode): Add toolbar. (help-mode-tool-bar-map): New variable. (help-mode-menu): Disable forward/backward items when stack is empty. (help-bookmark-make-record, help-bookmark-jump): Minor doc fixes. diff --git a/lisp/help-mode.el b/lisp/help-mode.el index 79710a1807..30a1ce053c 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -54,14 +54,30 @@ ["Show Help for Symbol" help-follow-symbol :help "Show the docs for the symbol at point"] ["Previous Topic" help-go-back - :help "Go back to previous topic in this help buffer"] + :help "Go back to previous topic in this help buffer" + :active help-xref-stack] ["Next Topic" help-go-forward - :help "Go back to next topic in this help buffer"] + :help "Go back to next topic in this help buffer" + :active help-xref-forward-stack] ["Move to Previous Button" backward-button :help "Move to the Previous Button in the help buffer"] ["Move to Next Button" forward-button :help "Move to the Next Button in the help buffer"])) +(defvar help-mode-tool-bar-map + (let ((map (make-sparse-keymap))) + (tool-bar-local-item "close" 'quit-window 'quit map + :label "Quit help." + :vert-only t) + (define-key-after map [separator-1] menu-bar-separator) + (tool-bar-local-item "search" 'isearch-forward 'search map + :label "Search" :vert-only t) + (tool-bar-local-item-from-menu 'help-go-back "left-arrow" map help-mode-map + :rtl "right-arrow" :vert-only t) + (tool-bar-local-item-from-menu 'help-go-forward "right-arrow" map help-mode-map + :rtl "left-arrow" :vert-only t) + map)) + (defvar-local help-xref-stack nil "A stack of ways by which to return to help buffers after following xrefs. Used by `help-follow' and `help-xref-go-back'. @@ -317,6 +333,8 @@ Commands: \\{help-mode-map}" (setq-local revert-buffer-function #'help-mode-revert-buffer) + (setq-local tool-bar-map + help-mode-tool-bar-map) (setq-local bookmark-make-record-function #'help-bookmark-make-record)) @@ -778,8 +796,8 @@ help buffer by other means." (&optional no-file no-context posn)) (defun help-bookmark-make-record () - "Create and return a help-mode bookmark record. -Implements `bookmark-make-record-function' for help-mode buffers." + "Create and return a `help-mode' bookmark record. +Implements `bookmark-make-record-function' for `help-mode' buffers." (unless (car help-xref-stack-item) (error "Cannot create bookmark - help command not known")) `(,@(bookmark-make-record-default 'NO-FILE 'NO-CONTEXT) @@ -792,7 +810,7 @@ Implements `bookmark-make-record-function' for help-mode buffers." ;;;###autoload (defun help-bookmark-jump (bookmark) - "Jump to help-mode bookmark BOOKMARK. + "Jump to `help-mode' bookmark BOOKMARK. Handler function for record returned by `help-bookmark-make-record'. BOOKMARK is a bookmark name or a bookmark record." (let ((help-fn (bookmark-prop-get bookmark 'help-fn)) commit b612f1a41f3f0282da6bbe1f7864d93ec9ac8007 Author: Stefan Kangas Date: Sat Feb 20 04:21:35 2021 +0100 * lisp/woman.el: Doc fix; remove redundant setup info. diff --git a/lisp/woman.el b/lisp/woman.el index 9a03d30bb7..98f1a47d24 100644 --- a/lisp/woman.el +++ b/lisp/woman.el @@ -69,13 +69,7 @@ ;; Recommended use ;; =============== -;; Put this in your .emacs: -;; (autoload 'woman "woman" -;; "Decode and browse a UN*X man page." t) -;; (autoload 'woman-find-file "woman" -;; "Find, decode and browse a specific UN*X man-page file." t) - -;; Then either (1 -- *RECOMMENDED*): If the `MANPATH' environment +;; Either (1 -- *RECOMMENDED*): If the `MANPATH' environment ;; variable is set then WoMan will use it; otherwise you may need to ;; reset the Lisp variable `woman-manpath', and you may also want to ;; set the Lisp variable `woman-path'. Please see the online @@ -139,14 +133,8 @@ ;; ============================== ;; WoMan supports the GNU Emacs customization facility, and puts -;; a customization group called `WoMan' in the `Help' group under the -;; top-level `Emacs' group. In order to be able to customize WoMan -;; without first loading it, add the following sexp to your .emacs: - -;; (defgroup woman nil -;; "Browse UNIX manual pages `wo (without) man'." -;; :tag "WoMan" :group 'help :load "woman") - +;; a customization group called `woman' in the `help' group under the +;; top-level `emacs' group. ;; WoMan currently runs two hooks: `woman-pre-format-hook' immediately ;; before formatting a buffer and `woman-post-format-hook' immediately commit 5f539581a461ebdfec107bc2648a399bac888c49 Author: Thomas Fitzsimmons Date: Fri Feb 19 17:32:59 2021 -0500 * lisp/url/url-http.el (url-http): Fix docstring typo. diff --git a/lisp/url/url-http.el b/lisp/url/url-http.el index 8cebd4e79f..e3c178630a 100644 --- a/lisp/url/url-http.el +++ b/lisp/url/url-http.el @@ -1292,7 +1292,7 @@ passing it an updated value of CBARGS as arguments. The first element in CBARGS should be a plist describing what has happened so far during the request, as described in the docstring of `url-retrieve' (if in doubt, specify nil). The current buffer -then CALLBACK is executed is the retrieval buffer. +when CALLBACK is executed is the retrieval buffer. Optional arg RETRY-BUFFER, if non-nil, specifies the buffer of a previous `url-http' call, which is being re-attempted. commit 7366859fe0e185155cbe426903c6081ec1723be1 Author: Thomas Fitzsimmons Date: Fri Feb 19 17:11:16 2021 -0500 ntlm-tests: Remove missing dependency warnings * test/lisp/net/ntlm-tests.el: Remove warnings about dependencies not being present. diff --git a/test/lisp/net/ntlm-tests.el b/test/lisp/net/ntlm-tests.el index c31ab83226..2420b3b48a 100644 --- a/test/lisp/net/ntlm-tests.el +++ b/test/lisp/net/ntlm-tests.el @@ -403,15 +403,6 @@ ARGUMENTS are passed to it." (ntlm-tests--ensure-ws-parse-ntlm-support)) "Non-nil if GNU ELPA test dependencies were loaded.") -(when (not ntlm-tests--dependencies-present) - (warn "Cannot find one or more GNU ELPA packages") - (when (not (featurep 'url-http-ntlm)) - (warn "Need url-http-ntlm/url-http-ntlm.el")) - (when (not (featurep 'web-server)) - (warn "Need web-server/web-server.el")) - (warn "Skipping NTLM authentication tests") - (warn "See GNU_ELPA_DIRECTORY in test/README")) - (ert-deftest ntlm-authentication () "Check ntlm.el's implementation of NTLM authentication over HTTP." (skip-unless ntlm-tests--dependencies-present) commit ade9c22c0497f50e492a8fe8c0356c0c28e313b3 Author: Thomas Fitzsimmons Date: Fri Feb 19 17:07:52 2021 -0500 ntlm-tests: Skip tests if dependencies are too old * test/lisp/net/ntlm-tests.el (ntlm-tests--dependencies-present): Add version and functionality checks. Co-authored-by: Michael Albinus diff --git a/test/lisp/net/ntlm-tests.el b/test/lisp/net/ntlm-tests.el index 0ed430afe6..c31ab83226 100644 --- a/test/lisp/net/ntlm-tests.el +++ b/test/lisp/net/ntlm-tests.el @@ -382,8 +382,25 @@ ARGUMENTS are passed to it." (concat "HTTP/1.1 200 OK\n\nAuthenticated." (unibyte-string 13) "\n") "Expected result of successful NTLM authentication.") +(require 'find-func) +(defun ntlm-tests--ensure-ws-parse-ntlm-support () + "Ensure NTLM special-case in `ws-parse'." + (let* ((hit (find-function-search-for-symbol + 'ws-parse nil (locate-file "web-server.el" load-path))) + (buffer (car hit)) + (position (cdr hit))) + (with-current-buffer buffer + (goto-char position) + (search-forward-regexp + ":NTLM" (save-excursion (forward-sexp) (point)) t)))) + +(require 'lisp-mnt) (defvar ntlm-tests--dependencies-present - (and (featurep 'url-http-ntlm) (featurep 'web-server)) + (and (featurep 'url-http-ntlm) + (version<= "2.0.4" + (lm-version (locate-file "url-http-ntlm.el" load-path))) + (featurep 'web-server) + (ntlm-tests--ensure-ws-parse-ntlm-support)) "Non-nil if GNU ELPA test dependencies were loaded.") (when (not ntlm-tests--dependencies-present) commit 283f98353fe3549ac8f66a3ab8fba85d93c81a88 Author: Alan Third Date: Fri Feb 19 19:25:39 2021 +0000 Fix frame contents scaling bug on macOS (bug#46155) Discussion in bug#46406. * src/nsterm.m ([EmacsView focusOnDrawingBuffer:]): Set the scale factor for the backing layer. diff --git a/src/nsterm.m b/src/nsterm.m index b0cf5952fd..6551694abe 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -8377,6 +8377,11 @@ - (void)focusOnDrawingBuffer surface = [[EmacsSurface alloc] initWithSize:s ColorSpace:[[[self window] colorSpace] CGColorSpace]]; + + /* Since we're using NSViewLayerContentsRedrawOnSetNeedsDisplay + the layer's scale factor is not set automatically, so do it + now. */ + [[self layer] setContentsScale:[[self window] backingScaleFactor]]; } CGContextRef context = [surface getContext]; commit b6eccad06c89eea878c1464571255fe8ce5c6d86 Author: Stefan Monnier Date: Fri Feb 19 12:51:36 2021 -0500 * lisp/emacs-lisp/bytecomp.el: Don't warn for repeated _ args (byte-compile-check-lambda-list): Skip warnings of repeated arg for those that are declared as unused anyway. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 9d80afd774..1b0906b50b 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2859,7 +2859,9 @@ If FORM is a lambda or a macro, byte-compile it as a function." ((eq arg '&optional) (when (memq '&optional (cdr list)) (error "Duplicate &optional"))) - ((memq arg vars) + ((and (memq arg vars) + ;; Allow repetitions for unused args. + (not (string-match "\\`_" (symbol-name arg)))) (byte-compile-warn "repeated variable %s in lambda-list" arg)) (t (push arg vars)))) commit 9b7eed33f94a65c4a9d1353aa052114415fc6381 Author: Stefan Monnier Date: Fri Feb 19 12:08:00 2021 -0500 * test/lisp/emacs-lisp/edebug-tests.el: Adjust to new `edebug-eval-defun`. (edebug-tests-trivial-backquote): Adjust to the way `eval-defun` outputs its result. (edebug-tests-cl-macrolet): Adjust to the fact that now macro expansion takes place during the `eval-defun` even when Edebugging. diff --git a/test/lisp/emacs-lisp/edebug-tests.el b/test/lisp/emacs-lisp/edebug-tests.el index daac43372a..dcb261c2eb 100644 --- a/test/lisp/emacs-lisp/edebug-tests.el +++ b/test/lisp/emacs-lisp/edebug-tests.el @@ -219,16 +219,16 @@ index." (with-current-buffer (find-file-noselect edebug-tests-temp-file) (setq saved-local-map overriding-local-map) (setq overriding-local-map edebug-tests-keymap) - (add-hook 'post-command-hook 'edebug-tests-post-command)) + (add-hook 'post-command-hook #'edebug-tests-post-command)) (advice-add 'exit-recursive-edit - :around 'edebug-tests-preserve-keyboard-macro-state) + :around #'edebug-tests-preserve-keyboard-macro-state) (unwind-protect (kmacro-call-macro nil nil nil kbdmac) (advice-remove 'exit-recursive-edit - 'edebug-tests-preserve-keyboard-macro-state) + #'edebug-tests-preserve-keyboard-macro-state) (with-current-buffer (find-file-noselect edebug-tests-temp-file) (setq overriding-local-map saved-local-map) - (remove-hook 'post-command-hook 'edebug-tests-post-command))))) + (remove-hook 'post-command-hook #'edebug-tests-post-command))))) (defun edebug-tests-preserve-keyboard-macro-state (orig &rest args) "Call ORIG with ARGS preserving the value of `executing-kbd-macro'. @@ -857,12 +857,14 @@ test and possibly others should be updated." (ert-deftest edebug-tests-trivial-backquote () "Edebug can instrument a trivial backquote expression (Bug#23651)." (edebug-tests-with-normal-env - (read-only-mode -1) - (delete-region (point-min) (point-max)) - (insert "`1") - (read-only-mode) + (let ((inhibit-read-only t)) + (delete-region (point-min) (point-max)) + (insert "`1")) (edebug-eval-defun nil) - (should (string-match-p (regexp-quote "1 (#o1, #x1, ?\\C-a)") + ;; `eval-defun' outputs its message to the echo area in a rather + ;; funny way, so the "1" and the " (#o1, #x1, ?\C-a)" end up placed + ;; there in separate pieces (via `print' rather than via `message'). + (should (string-match-p (regexp-quote " (#o1, #x1, ?\\C-a)") edebug-tests-messages)) (setq edebug-tests-messages "") @@ -912,13 +914,17 @@ test and possibly others should be updated." (ert-deftest edebug-tests-cl-macrolet () "Edebug can instrument `cl-macrolet' expressions. (Bug#29919)" (edebug-tests-with-normal-env - (edebug-tests-setup-@ "use-cl-macrolet" '(10) t) + (edebug-tests-locate-def "use-cl-macrolet") (edebug-tests-run-kbd-macro - "@ SPC SPC" + "C-u C-M-x SPC" (edebug-tests-should-be-at "use-cl-macrolet" "func") - (edebug-tests-should-match-result-in-messages "+") - "g" - (should (equal edebug-tests-@-result "The result of applying + to (1 x) is 11"))))) + (edebug-tests-should-match-result-in-messages "+")) + (let ((edebug-initial-mode 'Go-nonstop)) + (edebug-tests-setup-@ "use-cl-macrolet" '(10) t)) + (edebug-tests-run-kbd-macro + "@ SPC g" + (should (equal edebug-tests-@-result "The result of applying + to (1 x) is 11")) + ))) (ert-deftest edebug-tests-backtrace-goto-source () "Edebug can jump to instrumented source from its *Edebug-Backtrace* buffer." diff --git a/test/src/keyboard-tests.el b/test/src/keyboard-tests.el index 607d2eafd4..41c8cdd15f 100644 --- a/test/src/keyboard-tests.el +++ b/test/src/keyboard-tests.el @@ -23,14 +23,15 @@ (ert-deftest keyboard-unread-command-events () "Test `unread-command-events'." - (should (equal (progn (push ?\C-a unread-command-events) - (read-event nil nil 1)) - ?\C-a)) - (should (equal (progn (run-with-timer - 1 nil - (lambda () (push '(t . ?\C-b) unread-command-events))) - (read-event nil nil 2)) - ?\C-b))) + (let ((unread-command-events nil)) + (should (equal (progn (push ?\C-a unread-command-events) + (read-event nil nil 1)) + ?\C-a)) + (should (equal (progn (run-with-timer + 1 nil + (lambda () (push '(t . ?\C-b) unread-command-events))) + (read-event nil nil 2)) + ?\C-b)))) (ert-deftest keyboard-lossage-size () "Test `lossage-size'." @@ -46,6 +47,28 @@ (should-error (lossage-size (1- min-value))) (should (= lossage-orig (lossage-size lossage-orig))))) +;; FIXME: This test doesn't currently work :-( +;; (ert-deftest keyboard-tests--echo-keystrokes-bug15332 () +;; (let ((msgs '()) +;; (unread-command-events nil) +;; (redisplay--interactive t) +;; (echo-keystrokes 2)) +;; (setq unread-command-events '(?\C-u)) +;; (let* ((timer1 +;; (run-with-timer 3 1 +;; (lambda () +;; (setq unread-command-events '(?5))))) +;; (timer2 +;; (run-with-timer 2.5 1 +;; (lambda () +;; (push (current-message) msgs))))) +;; (run-with-timer 5 nil +;; (lambda () +;; (cancel-timer timer1) +;; (cancel-timer timer2) +;; (throw 'exit msgs))) +;; (recursive-edit) +;; (should (equal msgs '("C-u 55-" "C-u 5-" "C-u-")))))) (provide 'keyboard-tests) ;;; keyboard-tests.el ends here commit 1d50050af7f6cde7283d29cd79526bf1cd4a73ae Merge: 51d056b141 8e8b46ef81 Author: Glenn Morris Date: Fri Feb 19 08:36:56 2021 -0800 Merge from origin/emacs-27 8e8b46ef81 (origin/emacs-27) More accurate documentation of the "r" i... dcb2015a5b Mention the GNU Kind Communications Guidelines in the FAQ 9882e63eea ; * CONTRIBUTE: Another wording change regarding tiny chan... 850f18ef23 Allow newlines in password prompts again in comint c977370dd7 Avoid point movement when visiting image files da64a257a4 ; * CONTRIBUTE: Yet another clarification of significant c... d03f2a6ee9 Avoid assertion violation in callproc.c dcc00bbb19 ; * CONTRIBUTE: Clarify the "15-lines" rule a bit more. commit 51d056b14136c3d479ccf949dafa0f3602e7ee2f Merge: 07b22b6b5d 120149cf6a Author: Glenn Morris Date: Fri Feb 19 08:36:56 2021 -0800 ; Merge from origin/emacs-27 The following commit was skipped: 120149cf6a Clarify "changes" in CONTRIBUTE commit 07b22b6b5d196b292f3cb03749b09092b2197cf9 Merge: 6830199984 4712c75ab8 Author: Glenn Morris Date: Fri Feb 19 08:36:55 2021 -0800 Merge from origin/emacs-27 4712c75ab8 Clarify when activate-mark-hook is run abedf3a865 Fix language-environment and font selection on MS-Windows 8b8708eadd Fix example in Sequence Functions node in the manual commit 6830199984b9964286fda8e4c904ce84aa68e514 Author: Ulf Jasper Date: Fri Feb 19 17:07:36 2021 +0100 Enable newsticker--group-shift-feed-(up|down) to move groups as well Fix broken newsticker--group-shift-group-(up-down). * lisp/net/newst-treeview.el (newsticker-treeview-jump): Change prompt string. (newsticker--group-shift): Move the group when a group is currently selected. Fix error when explicitly shifting a group. (Fixes first issue in Bug#41376.) diff --git a/lisp/net/newst-treeview.el b/lisp/net/newst-treeview.el index cf55f66e78..a2d4d89ee5 100644 --- a/lisp/net/newst-treeview.el +++ b/lisp/net/newst-treeview.el @@ -1626,7 +1626,7 @@ Return t if a new feed was activated, nil otherwise." (interactive (list (let ((completion-ignore-case t)) (completing-read - "Jump to feed: " + "Jump to feed/group: " (append '("new" "obsolete" "immortal" "all") (mapcar #'car (append newsticker-url-list newsticker-url-list-defaults))) @@ -1852,28 +1852,34 @@ of the shift. If MOVE-GROUP is nil the currently selected feed `newsticker--treeview-current-feed' is shifted, if it is t then the current feed's parent group is shifted.." (let* ((cur-feed newsticker--treeview-current-feed) - (thing (if move-group - (newsticker--group-find-parent-group cur-feed) + (thing (if (and move-group + (not (newsticker--group-get-group cur-feed))) + (car (newsticker--group-find-parent-group cur-feed)) cur-feed)) (parent-group (newsticker--group-find-parent-group - (if move-group (car thing) thing)))) + ;;(if move-group (car thing) thing) + thing))) (unless parent-group (error "Group not found!")) (let* ((siblings (cdr parent-group)) - (pos (cl-position thing siblings :test 'equal)) + (pos (cl-position thing siblings :test + (lambda (o1 o2) + (equal (if (listp o1) (car o1) o1) + (if (listp o2) (car o2) o2))))) (tpos (+ pos delta )) (new-pos (max 0 (min (length siblings) tpos))) (beg (cl-subseq siblings 0 (min pos new-pos))) (end (cl-subseq siblings (+ 1 (max pos new-pos)))) (p (elt siblings new-pos))) (when (not (= pos new-pos)) - (setcdr parent-group - (cl-concatenate 'list - beg - (if (> delta 0) - (list p thing) - (list thing p)) - end)) + (let ((th (or (newsticker--group-get-group thing) thing))) + (setcdr parent-group + (cl-concatenate 'list + beg + (if (> delta 0) + (list p th) + (list th p)) + end))) (newsticker--treeview-tree-update) (newsticker-treeview-update) (newsticker-treeview-jump cur-feed))))) commit 8e8b46ef818a5f94a9697dce1c49c6869d61deed Author: Eli Zaretskii Date: Fri Feb 19 15:16:31 2021 +0200 More accurate documentation of the "r" interactive spec * doc/lispref/commands.texi (Interactive Codes): Describe the effect of 'mark-even-if-inactive'. diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 5385c03790..7569ca6e69 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -488,7 +488,10 @@ I/O. Point and the mark, as two numeric arguments, smallest first. This is the only code letter that specifies two successive arguments rather than one. This will signal an error if the mark is not set in the buffer -which is current when the command is invoked. No I/O. +which is current when the command is invoked. If Transient Mark mode +is turned on (@pxref{The Mark}) --- as it is by default --- and user +option @code{mark-even-if-inactive} is @code{nil}, Emacs will signal +an error even if the mark @emph{is} set, but is inactive. No I/O. @item s Arbitrary text, read in the minibuffer and returned as a string commit d4f6927d48043d01929a93da53a64b1e4296f994 Author: Mattias Engdegård Date: Fri Feb 19 13:44:25 2021 +0100 Fix regexp mistakes * lisp/progmodes/cperl-mode.el (cperl--package-regexp): Avoid double repetition; cperl--ws-or-comment-regexp is already repeated with 1+. * test/lisp/textmodes/dns-mode-tests.el (dns-mode-tests-dns-mode-soa-increment-serial): Escape literal '$'. * test/lisp/emacs-lisp/rx-tests.el (rx-regexp): Modify test to not trigger a linting warning while retaining its testing power. diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index d01bd3a48e..db142c0dc3 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -1305,7 +1305,7 @@ is a legal variable name).") (group (regexp ,cperl--normal-identifier-regexp)) (opt (sequence - (1+ (regexp ,cperl--ws-or-comment-regexp)) + (regexp ,cperl--ws-or-comment-regexp) (group (regexp ,cperl--version-regexp)))))) "A regular expression for package NAME VERSION in Perl. Contains two groups for the package name and version.") diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el index 388c5e86b4..12bf4f7978 100644 --- a/test/lisp/emacs-lisp/rx-tests.el +++ b/test/lisp/emacs-lisp/rx-tests.el @@ -388,11 +388,11 @@ (ert-deftest rx-regexp () (should (equal (rx (regexp "abc") (regex "[de]")) "\\(?:abc\\)[de]")) + (should (equal (rx "a" (regexp "$")) + "a\\(?:$\\)")) (let ((x "a*")) (should (equal (rx (regexp x) "b") "\\(?:a*\\)b")) - (should (equal (rx "a" (regexp "*")) - "a\\(?:*\\)")) (should (equal (rx "" (regexp x) (eval "")) "a*")))) diff --git a/test/lisp/textmodes/dns-mode-tests.el b/test/lisp/textmodes/dns-mode-tests.el index 92b6cc9177..8bc48732c6 100644 --- a/test/lisp/textmodes/dns-mode-tests.el +++ b/test/lisp/textmodes/dns-mode-tests.el @@ -37,7 +37,7 @@ (dns-mode-soa-increment-serial) ;; Number is updated from 2015080302 to the current date ;; (actually, just ensure the year part is later than 2020). - (should (string-match "$TTL 86400 + (should (string-match "\\$TTL 86400 @ IN SOA ns.icann.org. noc.dns.icann.org. ( 20[2-9][0-9]+ ;Serial 7200 ;Refresh commit dcb2015a5b644dafd61580c791f1f6625f5858e4 Author: Stefan Kangas Date: Fri Feb 19 10:21:14 2021 +0100 Mention the GNU Kind Communications Guidelines in the FAQ * doc/misc/efaq.texi (Guidelines for newsgroup postings): Mention the GNU Kind Communications Guidelines. diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi index fdfde96a99..c0536e0e3a 100644 --- a/doc/misc/efaq.texi +++ b/doc/misc/efaq.texi @@ -388,6 +388,11 @@ posting a followup that recommends such software. @uref{news:gnu.emacs.bug} is a place where bug reports appear, but avoid posting bug reports to this newsgroup directly (@pxref{Reporting bugs}). +Finally, we recommend reading the +@url{https://www.gnu.org/philosophy/kind-communication.html, GNU Kind +Communications Guidelines} before posting to any GNU lists or +newsgroups. + @node Newsgroup archives @section Where can I get old postings to @uref{news:gnu.emacs.help} and other GNU groups? @cindex Archived postings from @code{gnu.emacs.help} commit ea2f5f3fdac0b360833586ac855248094baf328c Merge: a9b49dc311 9b944f48c9 Author: Michael Albinus Date: Fri Feb 19 10:03:32 2021 +0100 Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs commit a9b49dc31159283c962da61a259254b512e63ace Author: Michael Albinus Date: Fri Feb 19 10:03:20 2021 +0100 ; Fix indentation in test/README diff --git a/test/README b/test/README index 877f77ab94..1e0e43a8ac 100644 --- a/test/README +++ b/test/README @@ -106,7 +106,7 @@ tramp-tests.el). Per default, a mock-up connection method is used to test a real remote connection, set $REMOTE_TEMPORARY_FILE_DIRECTORY to a suitable value in order to overwrite the default value: - env REMOTE_TEMPORARY_FILE_DIRECTORY=/ssh:host:/tmp make ... + env REMOTE_TEMPORARY_FILE_DIRECTORY=/ssh:host:/tmp make ... Some optional tests require packages from GNU ELPA. By default ../../elpa will be checked for these packages. If GNU ELPA is checked commit 9b944f48c9ce65bad50e7c6a957200c0f2d4f1a8 Author: Stefan Kangas Date: Fri Feb 19 08:38:29 2021 +0100 * lisp/calculator.el: Minor doc fix. Remove redundant :group args. diff --git a/lisp/calculator.el b/lisp/calculator.el index b4c00753e9..00883989b2 100644 --- a/lisp/calculator.el +++ b/lisp/calculator.el @@ -20,23 +20,18 @@ ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs. If not, see . -;;;===================================================================== ;;; Commentary: -;; + ;; A calculator for Emacs. ;; Why should you reach for your mouse to get xcalc (calc.exe, gcalc or ;; whatever), when you have Emacs running already? ;; -;; If this is not part of your Emacs distribution, then simply bind -;; `calculator' to a key and make it an autoloaded function, e.g.: -;; (autoload 'calculator "calculator" -;; "Run the Emacs calculator." t) +;; You can bind this to a key by adding this to your Init file: +;; ;; (global-set-key [(control return)] 'calculator) ;; ;; Written by Eli Barzilay, eli@barzilay.org -;; -;;;===================================================================== ;;; Customization: (defgroup calculator nil @@ -50,19 +45,16 @@ "Run `calculator' electrically, in the echo area. Electric mode saves some place but changes the way you interact with the calculator." - :type 'boolean - :group 'calculator) + :type 'boolean) (defcustom calculator-use-menu t "Make `calculator' create a menu. Note that this requires easymenu. Must be set before loading." - :type 'boolean - :group 'calculator) + :type 'boolean) (defcustom calculator-bind-escape nil "If non-nil, set escape to exit the calculator." - :type 'boolean - :group 'calculator) + :type 'boolean) (defcustom calculator-unary-style 'postfix "Value is either `prefix' or `postfix'. @@ -75,44 +67,38 @@ This determines the default behavior of unary operators." It should contain a \"%s\" somewhere that will indicate the i/o radixes; this will be a two-character string as described in the documentation for `calculator-mode'." - :type 'string - :group 'calculator) + :type 'string) (defcustom calculator-number-digits 3 "The calculator's number of digits used for standard display. Used by the `calculator-standard-display' function - it will use the format string \"%.NC\" where this number is N and C is a character given at runtime." - :type 'integer - :group 'calculator) + :type 'integer) (defcustom calculator-radix-grouping-mode t "Use digit grouping in radix output mode. If this is set, chunks of `calculator-radix-grouping-digits' characters will be separated by `calculator-radix-grouping-separator' when in radix output mode is active (determined by `calculator-output-radix')." - :type 'boolean - :group 'calculator) + :type 'boolean) (defcustom calculator-radix-grouping-digits 4 "The number of digits used for grouping display in radix modes. See `calculator-radix-grouping-mode'." - :type 'integer - :group 'calculator) + :type 'integer) (defcustom calculator-radix-grouping-separator "'" "The separator used in radix grouping display. See `calculator-radix-grouping-mode'." - :type 'string - :group 'calculator) + :type 'string) (defcustom calculator-remove-zeros t "Non-nil value means delete all redundant zero decimal digits. If this value is not t and not nil, redundant zeros are removed except for one. Used by the `calculator-remove-zeros' function." - :type '(choice (const t) (const leave-decimal) (const nil)) - :group 'calculator) + :type '(choice (const t) (const leave-decimal) (const nil))) (defcustom calculator-displayer '(std ?n) "A displayer specification for numerical values. @@ -135,8 +121,7 @@ a character and G is an optional boolean, in this case the arguments." :type '(choice (function) (string) (sexp) (list (const std) character) - (list (const std) character boolean)) - :group 'calculator) + (list (const std) character boolean))) (defcustom calculator-displayers '(((std ?n) "Standard display, decimal point or scientific") @@ -152,15 +137,13 @@ specification is the same as the values that can be stored in `calculator-displayer'. `calculator-rotate-displayer' rotates this list." - :type 'sexp - :group 'calculator) + :type 'sexp) (defcustom calculator-paste-decimals t "If non-nil, convert pasted integers so they have a decimal point. This makes it possible to paste big integers since they will be read as floats, otherwise the Emacs reader will fail on them." - :type 'boolean - :group 'calculator) + :type 'boolean) (make-obsolete-variable 'calculator-paste-decimals "it is no longer used." "26.1") @@ -169,14 +152,12 @@ floats, otherwise the Emacs reader will fail on them." `calculator-displayer', to format a string before copying it with `calculator-copy'. If nil, then `calculator-displayer's normal value is used." - :type 'boolean - :group 'calculator) + :type 'boolean) (defcustom calculator-2s-complement nil "If non-nil, show negative numbers in 2s complement in radix modes. Otherwise show as a negative number." - :type 'boolean - :group 'calculator) + :type 'boolean) (defcustom calculator-mode-hook nil "List of hook functions for `calculator-mode' to run. @@ -184,8 +165,7 @@ Note: if `calculator-electric-mode' is on, then this hook will get activated in the minibuffer -- in that case it should not do much more than local key settings and other effects that will change things outside the scope of calculator related code." - :type 'hook - :group 'calculator) + :type 'hook) (defcustom calculator-user-registers nil "An association list of user-defined register bindings. @@ -200,8 +180,7 @@ before you load calculator." (when (boundp 'calculator-registers) (setq calculator-registers (append val calculator-registers))) - (setq calculator-user-registers val)) - :group 'calculator) + (setq calculator-user-registers val))) (defcustom calculator-user-operators nil "A list of additional operators. @@ -234,8 +213,7 @@ Examples: Note that this will be either postfix or prefix, according to `calculator-unary-style'." - :type '(repeat (list string symbol sexp integer integer)) - :group 'calculator) + :type '(repeat (list string symbol sexp integer integer))) ;;;===================================================================== ;;; Code: commit 87669400aff6ecdf670de6368168c5833848d56f Author: Stefan Kangas Date: Fri Feb 19 08:30:04 2021 +0100 ; * lisp/plstore.el: Fix formatting. diff --git a/lisp/plstore.el b/lisp/plstore.el index 46533664d5..4ca5886bf1 100644 --- a/lisp/plstore.el +++ b/lisp/plstore.el @@ -1,4 +1,5 @@ ;;; plstore.el --- secure plist store -*- lexical-binding: t -*- + ;; Copyright (C) 2011-2021 Free Software Foundation, Inc. ;; Author: Daiki Ueno @@ -19,7 +20,7 @@ ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs. If not, see . -;;; Commentary +;;; Commentary: ;; Plist based data store providing search and partial encryption. ;; commit 3c7b839e1a2bd8c896892c61f75a9016f52e787b Author: Michael Albinus Date: Fri Feb 19 09:21:55 2021 +0100 Fix Tramp bug#46625 * test/lisp/net/tramp-tests.el (tramp-test33-environment-variables): Adapt test. (Bug#46625) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 9a83fa6676..016b4d3c8f 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -5102,8 +5102,10 @@ INPUT, if non-nil, is a string sent to the process." (string-match-p (regexp-quote envvar) ;; We must remove PS1, the output is truncated otherwise. + ;; We must suppress "_=VAR...". (funcall - this-shell-command-to-string "printenv | grep -v PS1"))))))))) + this-shell-command-to-string + "printenv | grep -v PS1 | grep -v _="))))))))) (tramp--test--deftest-direct-async-process tramp-test33-environment-variables "Check that remote processes set / unset environment variables properly. commit 73a6ab0a1b5c0f9620b439e13998a08f8214a334 Author: Stefan Kangas Date: Fri Feb 19 06:51:49 2021 +0100 Do interactive mode tagging for snake.el diff --git a/lisp/play/snake.el b/lisp/play/snake.el index bed7cea6ee..29effa2346 100644 --- a/lisp/play/snake.el +++ b/lisp/play/snake.el @@ -336,38 +336,38 @@ Argument SNAKE-BUFFER is the name of the buffer." (defun snake-move-left () "Make the snake move left." - (interactive) + (interactive nil snake-mode) (when (zerop (snake-final-x-velocity)) (push '(-1 0) snake-velocity-queue))) (defun snake-move-right () "Make the snake move right." - (interactive) + (interactive nil snake-mode) (when (zerop (snake-final-x-velocity)) (push '(1 0) snake-velocity-queue))) (defun snake-move-up () "Make the snake move up." - (interactive) + (interactive nil snake-mode) (when (zerop (snake-final-y-velocity)) (push '(0 -1) snake-velocity-queue))) (defun snake-move-down () "Make the snake move down." - (interactive) + (interactive nil snake-mode) (when (zerop (snake-final-y-velocity)) (push '(0 1) snake-velocity-queue))) (defun snake-end-game () "Terminate the current game." - (interactive) + (interactive nil snake-mode) (gamegrid-kill-timer) (use-local-map snake-null-map) (gamegrid-add-score snake-score-file snake-score)) (defun snake-start-game () "Start a new game of Snake." - (interactive) + (interactive nil snake-mode) (snake-reset-game) (snake-set-dot) (use-local-map snake-mode-map) @@ -375,7 +375,7 @@ Argument SNAKE-BUFFER is the name of the buffer." (defun snake-pause-game () "Pause (or resume) the current game." - (interactive) + (interactive nil snake-mode) (setq snake-paused (not snake-paused)) (message (and snake-paused "Game paused (press p to resume)"))) @@ -386,6 +386,7 @@ Argument SNAKE-BUFFER is the name of the buffer." (define-derived-mode snake-mode special-mode "Snake" "A mode for playing Snake." + :interactive nil (add-hook 'kill-buffer-hook 'gamegrid-kill-timer nil t) commit 928b643a28919e927af3aba8f8b420e098eb45c4 Author: Stefan Kangas Date: Fri Feb 19 06:32:04 2021 +0100 Do interactive mode tagging for tetris.el diff --git a/lisp/play/tetris.el b/lisp/play/tetris.el index 05e4ffe011..f43aa47326 100644 --- a/lisp/play/tetris.el +++ b/lisp/play/tetris.el @@ -506,7 +506,7 @@ Drops the shape one square, testing for collision." (defun tetris-move-bottom () "Drop the shape to the bottom of the playing area." - (interactive) + (interactive nil tetris-mode) (unless tetris-paused (let ((hit nil)) (tetris-erase-shape) @@ -519,7 +519,7 @@ Drops the shape one square, testing for collision." (defun tetris-move-left () "Move the shape one square to the left." - (interactive) + (interactive nil tetris-mode) (unless tetris-paused (tetris-erase-shape) (setq tetris-pos-x (1- tetris-pos-x)) @@ -529,7 +529,7 @@ Drops the shape one square, testing for collision." (defun tetris-move-right () "Move the shape one square to the right." - (interactive) + (interactive nil tetris-mode) (unless tetris-paused (tetris-erase-shape) (setq tetris-pos-x (1+ tetris-pos-x)) @@ -539,7 +539,7 @@ Drops the shape one square, testing for collision." (defun tetris-move-down () "Move the shape one square to the bottom." - (interactive) + (interactive nil tetris-mode) (unless tetris-paused (tetris-erase-shape) (setq tetris-pos-y (1+ tetris-pos-y)) @@ -549,7 +549,7 @@ Drops the shape one square, testing for collision." (defun tetris-rotate-prev () "Rotate the shape clockwise." - (interactive) + (interactive nil tetris-mode) (unless tetris-paused (tetris-erase-shape) (setq tetris-rot (% (+ 1 tetris-rot) @@ -561,7 +561,7 @@ Drops the shape one square, testing for collision." (defun tetris-rotate-next () "Rotate the shape anticlockwise." - (interactive) + (interactive nil tetris-mode) (unless tetris-paused (tetris-erase-shape) (setq tetris-rot (% (+ 3 tetris-rot) @@ -573,14 +573,14 @@ Drops the shape one square, testing for collision." (defun tetris-end-game () "Terminate the current game." - (interactive) + (interactive nil tetris-mode) (gamegrid-kill-timer) (use-local-map tetris-null-map) (gamegrid-add-score tetris-score-file tetris-score)) (defun tetris-start-game () "Start a new game of Tetris." - (interactive) + (interactive nil tetris-mode) (tetris-reset-game) (use-local-map tetris-mode-map) (let ((period (or (tetris-get-tick-period) @@ -589,7 +589,7 @@ Drops the shape one square, testing for collision." (defun tetris-pause-game () "Pause (or resume) the current game." - (interactive) + (interactive nil tetris-mode) (setq tetris-paused (not tetris-paused)) (message (and tetris-paused "Game paused (press p to resume)"))) @@ -600,6 +600,7 @@ Drops the shape one square, testing for collision." (define-derived-mode tetris-mode nil "Tetris" "A mode for playing Tetris." + :interactive nil (add-hook 'kill-buffer-hook 'gamegrid-kill-timer nil t) commit 388a87432b5e95544d6d74252ea531e64d6495a5 Author: Stefan Kangas Date: Fri Feb 19 06:29:00 2021 +0100 Do interactive mode tagging for man.el diff --git a/lisp/man.el b/lisp/man.el index 1fded38e72..70b8aa8eb2 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -1024,7 +1024,7 @@ to auto-complete your input based on the installed manual pages." ;;;###autoload (defun man-follow (man-args) "Get a Un*x manual page of the item under point and put it in a buffer." - (interactive (list (Man-default-man-entry))) + (interactive (list (Man-default-man-entry)) Man-mode) (if (or (not man-args) (string= man-args "")) (error "No item under point") @@ -1143,7 +1143,7 @@ Return the buffer in which the manpage will appear." (defun Man-update-manpage () "Reformat current manpage by calling the man command again synchronously." - (interactive) + (interactive nil Man-mode) (when (eq Man-arguments nil) ;;this shouldn't happen unless it is not in a Man buffer." (error "Man-arguments not initialized")) @@ -1239,7 +1239,7 @@ See the variable `Man-notify-method' for the different notification behaviors." (defun Man-fontify-manpage () "Convert overstriking and underlining to the correct fonts. Same for the ANSI bold and normal escape sequences." - (interactive) + (interactive nil Man-mode) (goto-char (point-min)) ;; Fontify ANSI escapes. (let ((ansi-color-apply-face-function #'ansi-color-apply-text-property-face) @@ -1355,7 +1355,7 @@ default type, `Man-xref-man-page' is used for the buttons." Normally skip any jobs that should have been done by the sed script, but when called interactively, do those jobs even if the sed script would have done them." - (interactive "p") + (interactive "p" Man-mode) (if (or interactive (not Man-sed-script)) (progn (goto-char (point-min)) @@ -1723,7 +1723,7 @@ The following key bindings are currently in effect in the buffer: (defun Man-next-section (n) "Move point to Nth next section (default 1)." - (interactive "p") + (interactive "p" Man-mode) (let ((case-fold-search nil) (start (point))) (if (looking-at Man-heading-regexp) @@ -1739,7 +1739,7 @@ The following key bindings are currently in effect in the buffer: (defun Man-previous-section (n) "Move point to Nth previous section (default 1)." - (interactive "p") + (interactive "p" Man-mode) (let ((case-fold-search nil)) (if (looking-at Man-heading-regexp) (forward-line -1)) @@ -1756,8 +1756,7 @@ Returns t if section is found, nil otherwise." (if (re-search-forward (concat "^" section) (point-max) t) (progn (beginning-of-line) t) (goto-char curpos) - nil) - )) + nil))) (defvar Man--last-section nil) @@ -1771,7 +1770,8 @@ Returns t if section is found, nil otherwise." (prompt (concat "Go to section (default " default "): ")) (chosen (completing-read prompt Man--sections nil nil nil nil default))) - (list chosen))) + (list chosen)) + Man-mode) (setq Man--last-section section) (unless (Man-find-section section) (error "Section %s not found" section))) @@ -1780,7 +1780,7 @@ Returns t if section is found, nil otherwise." (defun Man-goto-see-also-section () "Move point to the \"SEE ALSO\" section. Actually the section moved to is described by `Man-see-also-regexp'." - (interactive) + (interactive nil Man-mode) (if (not (Man-find-section Man-see-also-regexp)) (error "%s" (concat "No " Man-see-also-regexp " section found in the current manpage")))) @@ -1834,7 +1834,8 @@ Specify which REFERENCE to use; default is based on word at point." (prompt (concat "Refer to (default " default "): ")) (chosen (completing-read prompt Man--refpages nil nil nil nil defaults))) - chosen)))) + chosen))) + Man-mode) (if (not Man--refpages) (error "Can't find any references in the current manpage") (setq Man--last-refpage reference) @@ -1843,7 +1844,7 @@ Specify which REFERENCE to use; default is based on word at point." (defun Man-kill () "Kill the buffer containing the manpage." - (interactive) + (interactive nil Man-mode) (quit-window t)) (defun Man-goto-page (page &optional noerror) @@ -1854,7 +1855,8 @@ Specify which REFERENCE to use; default is based on word at point." (if (= (length Man-page-list) 1) (error "You're looking at the only manpage in the buffer") (list (read-minibuffer (format "Go to manpage [1-%d]: " - (length Man-page-list))))))) + (length Man-page-list)))))) + Man-mode) (if (and (not Man-page-list) (not noerror)) (error "Not a man page buffer")) (when Man-page-list @@ -1876,7 +1878,7 @@ Specify which REFERENCE to use; default is based on word at point." (defun Man-next-manpage () "Find the next manpage entry in the buffer." - (interactive) + (interactive nil Man-mode) (if (= (length Man-page-list) 1) (error "This is the only manpage in the buffer")) (if (< Man-current-page (length Man-page-list)) @@ -1887,7 +1889,7 @@ Specify which REFERENCE to use; default is based on word at point." (defun Man-previous-manpage () "Find the previous manpage entry in the buffer." - (interactive) + (interactive nil Man-mode) (if (= (length Man-page-list) 1) (error "This is the only manpage in the buffer")) (if (> Man-current-page 1) commit 7467dc4f181f2bf9adc3335afab9fb7ee909a60d Author: Stefan Kangas Date: Fri Feb 19 02:27:56 2021 +0100 Do interactive mode tagging for package.el diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 90b7b88d58..092befa1f2 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -2802,6 +2802,7 @@ either a full name or nil, and EMAIL is a valid email address." Letters do not insert themselves; instead, they are commands. \\ \\{package-menu-mode-map}" + :interactive nil (setq mode-line-process '((package--downloads-in-progress ":Loading") (package-menu--transaction-status package-menu--transaction-status))) @@ -2924,7 +2925,7 @@ Installed obsolete packages are always displayed.") Also hide packages whose name matches a regexp in user option `package-hidden-regexps' (a list). To add regexps to this list, use `package-menu-hide-package'." - (interactive) + (interactive nil package-menu-mode) (package--ensure-package-menu-mode) (setq package-menu--hide-packages (not package-menu--hide-packages)) @@ -3261,7 +3262,7 @@ To unhide a package, type Type \\[package-menu-toggle-hiding] to toggle package hiding." (declare (interactive-only "change `package-hidden-regexps' instead.")) - (interactive) + (interactive nil package-menu-mode) (package--ensure-package-menu-mode) (let* ((name (when (derived-mode-p 'package-menu-mode) (concat "\\`" (regexp-quote (symbol-name (package-desc-name @@ -3285,7 +3286,7 @@ Type \\[package-menu-toggle-hiding] to toggle package hiding." (defun package-menu-describe-package (&optional button) "Describe the current package. If optional arg BUTTON is non-nil, describe its associated package." - (interactive) + (interactive nil package-menu-mode) (let ((pkg-desc (if button (button-get button 'package-desc) (tabulated-list-get-id)))) (if pkg-desc @@ -3295,7 +3296,7 @@ If optional arg BUTTON is non-nil, describe its associated package." ;; fixme numeric argument (defun package-menu-mark-delete (&optional _num) "Mark a package for deletion and move to the next line." - (interactive "p") + (interactive "p" package-menu-mode) (package--ensure-package-menu-mode) (if (member (package-menu-get-status) '("installed" "dependency" "obsolete" "unsigned")) @@ -3304,7 +3305,7 @@ If optional arg BUTTON is non-nil, describe its associated package." (defun package-menu-mark-install (&optional _num) "Mark a package for installation and move to the next line." - (interactive "p") + (interactive "p" package-menu-mode) (package--ensure-package-menu-mode) (if (member (package-menu-get-status) '("available" "avail-obso" "new" "dependency")) (tabulated-list-put-tag "I" t) @@ -3312,20 +3313,20 @@ If optional arg BUTTON is non-nil, describe its associated package." (defun package-menu-mark-unmark (&optional _num) "Clear any marks on a package and move to the next line." - (interactive "p") + (interactive "p" package-menu-mode) (package--ensure-package-menu-mode) (tabulated-list-put-tag " " t)) (defun package-menu-backup-unmark () "Back up one line and clear any marks on that package." - (interactive) + (interactive nil package-menu-mode) (package--ensure-package-menu-mode) (forward-line -1) (tabulated-list-put-tag " ")) (defun package-menu-mark-obsolete-for-deletion () "Mark all obsolete packages for deletion." - (interactive) + (interactive nil package-menu-mode) (package--ensure-package-menu-mode) (save-excursion (goto-char (point-min)) @@ -3356,7 +3357,7 @@ If optional arg BUTTON is non-nil, describe its associated package." (defun package-menu-quick-help () "Show short key binding help for `package-menu-mode'. The full list of keys can be viewed with \\[describe-mode]." - (interactive) + (interactive nil package-menu-mode) (package--ensure-package-menu-mode) (message (mapconcat #'package--prettify-quick-help-key package--quick-help-keys "\n"))) @@ -3452,7 +3453,7 @@ call will upgrade the package. If there's an async refresh operation in progress, the flags will be placed as part of `package-menu--post-refresh' instead of immediately." - (interactive) + (interactive nil package-menu-mode) (package--ensure-package-menu-mode) (if (not package--downloads-in-progress) (package-menu--mark-upgrades-1) @@ -3546,7 +3547,7 @@ packages list, respectively." Packages marked for installation are downloaded and installed; packages marked for deletion are removed. Optional argument NOQUERY non-nil means do not ask the user to confirm." - (interactive) + (interactive nil package-menu-mode) (package--ensure-package-menu-mode) (let (install-list delete-list cmd pkg-desc) (save-excursion @@ -3791,7 +3792,8 @@ strings. If ARCHIVE is nil or the empty string, show all packages." (interactive (list (completing-read-multiple "Filter by archive (comma separated): " - (mapcar #'car package-archives)))) + (mapcar #'car package-archives))) + package-menu-mode) (package--ensure-package-menu-mode) (let ((re (if (listp archive) (regexp-opt archive) @@ -3812,7 +3814,8 @@ DESCRIPTION. When called interactively, prompt for DESCRIPTION. If DESCRIPTION is nil or the empty string, show all packages." - (interactive (list (read-regexp "Filter by description (regexp)"))) + (interactive (list (read-regexp "Filter by description (regexp)")) + package-menu-mode) (package--ensure-package-menu-mode) (if (or (not description) (string-empty-p description)) (package-menu--generate t t) @@ -3833,10 +3836,11 @@ strings. If KEYWORD is nil or the empty string, show all packages." (interactive (list (completing-read-multiple "Keywords (comma separated): " - (package-all-keywords)))) + (package-all-keywords))) + package-menu-mode) + (package--ensure-package-menu-mode) (when (stringp keyword) (setq keyword (list keyword))) - (package--ensure-package-menu-mode) (if (not keyword) (package-menu--generate t t) (package-menu--filter-by (lambda (pkg-desc) @@ -3855,7 +3859,8 @@ When called interactively, prompt for NAME-OR-DESCRIPTION. If NAME-OR-DESCRIPTION is nil or the empty string, show all packages." - (interactive (list (read-regexp "Filter by name or description (regexp)"))) + (interactive (list (read-regexp "Filter by name or description (regexp)")) + package-menu-mode) (package--ensure-package-menu-mode) (if (or (not name-or-description) (string-empty-p name-or-description)) (package-menu--generate t t) @@ -3874,7 +3879,8 @@ Display only packages with name that matches regexp NAME. When called interactively, prompt for NAME. If NAME is nil or the empty string, show all packages." - (interactive (list (read-regexp "Filter by name (regexp)"))) + (interactive (list (read-regexp "Filter by name (regexp)")) + package-menu-mode) (package--ensure-package-menu-mode) (if (or (not name) (string-empty-p name)) (package-menu--generate t t) @@ -3904,7 +3910,8 @@ packages." "incompat" "installed" "new" - "unsigned")))) + "unsigned"))) + package-menu-mode) (package--ensure-package-menu-mode) (if (or (not status) (string-empty-p status)) (package-menu--generate t t) @@ -3939,7 +3946,9 @@ If VERSION is nil or the empty string, show all packages." ('< "< less than") ('> "> greater than")) "): ")) - choice)))) + choice))) + package-menu-mode) + (package--ensure-package-menu-mode) (unless (equal predicate 'quit) (if (or (not version) (string-empty-p version)) (package-menu--generate t t) @@ -3957,7 +3966,7 @@ If VERSION is nil or the empty string, show all packages." (defun package-menu-filter-marked () "Filter \"*Packages*\" buffer by non-empty upgrade mark. Unlike other filters, this leaves the marks intact." - (interactive) + (interactive nil package-menu-mode) (package--ensure-package-menu-mode) (widen) (let (found-entries mark pkg-id entry marks) @@ -3985,7 +3994,7 @@ Unlike other filters, this leaves the marks intact." (defun package-menu-filter-upgradable () "Filter \"*Packages*\" buffer to show only upgradable packages." - (interactive) + (interactive nil package-menu-mode) (let ((pkgs (mapcar #'car (package-menu--find-upgrades)))) (package-menu--filter-by (lambda (pkg) @@ -3994,7 +4003,7 @@ Unlike other filters, this leaves the marks intact." (defun package-menu-clear-filter () "Clear any filter currently applied to the \"*Packages*\" buffer." - (interactive) + (interactive nil package-menu-mode) (package--ensure-package-menu-mode) (package-menu--generate t t)) commit 32e790f2514154c72927c414f43c3e277b1344ac Author: Thomas Fitzsimmons Date: Thu Feb 18 18:05:38 2021 -0500 Implement NTLM server for ntlm.el testing * test/Makefile.in (GNU_ELPA_DIRECTORY, elpa_dependencies, elpa_els, elpa_opts): New variables. (EMACSOPT, ert_opts): Add elpa_opts. * test/README: Document GNU_ELPA_DIRECTORY make variable. * test/lisp/net/ntlm-tests.el: Fix checkdoc-reported issues. (ntlm-tests-message, ntlm-server-build-type-2, ntlm-server-hash) (ntlm-server-check-authorization, ntlm-server-do-token) (ntlm-server-filter, ntlm-server-handler, ntlm-server-start) (ntlm-server-stop, ntlm-tests--url-retrieve-internal-around) (ntlm-tests--authenticate) (ntlm-tests--start-server-authenticate-stop-server): New functions. (ntlm-tests--username-oem, ntlm-tests--username-unicode) (ntlm-tests--client-supports-unicode, ntlm-tests--challenge) (ntlm-tests--result-buffer, ntlm-tests--successful-result): New variables. (ntlm-authentication) (ntlm-authentication-old-compatibility-level): New tests. * test/lisp/net/ntlm-resources/authinfo: New file. (Bug#43566) diff --git a/test/Makefile.in b/test/Makefile.in index f907602a62..ff228d1261 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -71,6 +71,15 @@ am__v_at_0 = @ am__v_at_1 = +# Load any GNU ELPA dependencies that are present, for optional tests. +GNU_ELPA_DIRECTORY ?= $(srcdir)/../../elpa +# Keep elpa_dependencies dependency-ordered. +elpa_dependencies = \ + url-http-ntlm/url-http-ntlm.el \ + web-server/web-server.el +elpa_els = $(addprefix $(GNU_ELPA_DIRECTORY)/packages/,$(elpa_dependencies)) +elpa_opts = $(foreach el,$(elpa_els),$(and $(wildcard $(el)),-L $(dir $(el)) -l $(el))) + # We never change directory before running Emacs, so a relative file # name is fine, and makes life easier. If we need to change # directory, we can use emacs --chdir. @@ -81,7 +90,7 @@ EMACS_EXTRAOPT= # Command line flags for Emacs. # Apparently MSYS bash would convert "-L :" to "-L ;" anyway, # but we might as well be explicit. -EMACSOPT = --no-init-file --no-site-file --no-site-lisp -L "$(SEPCHAR)$(srcdir)" $(EMACS_EXTRAOPT) +EMACSOPT = --no-init-file --no-site-file --no-site-lisp -L "$(SEPCHAR)$(srcdir)" $(elpa_opts) $(EMACS_EXTRAOPT) # Prevent any settings in the user environment causing problems. unexport EMACSDATA EMACSDOC EMACSPATH GREP_OPTIONS @@ -105,7 +114,7 @@ export TEST_LOAD_EL ?= \ $(if $(findstring $(MAKECMDGOALS), all check check-maybe),no,yes) # Additional settings for ert. -ert_opts = +ert_opts += $(elpa_opts) # Maximum length of lines in ert backtraces; nil for no limit. # (if empty, use the default ert-batch-backtrace-right-margin). diff --git a/test/README b/test/README index 5f3c10adbe..877f77ab94 100644 --- a/test/README +++ b/test/README @@ -108,6 +108,11 @@ to a suitable value in order to overwrite the default value: env REMOTE_TEMPORARY_FILE_DIRECTORY=/ssh:host:/tmp make ... +Some optional tests require packages from GNU ELPA. By default +../../elpa will be checked for these packages. If GNU ELPA is checked +out somewhere else, use + + make GNU_ELPA_DIRECTORY=/path/to/elpa ... There are also continuous integration tests on (see diff --git a/test/lisp/net/ntlm-resources/authinfo b/test/lisp/net/ntlm-resources/authinfo new file mode 100644 index 0000000000..698391e931 --- /dev/null +++ b/test/lisp/net/ntlm-resources/authinfo @@ -0,0 +1 @@ +machine localhost port http user ntlm password ntlm diff --git a/test/lisp/net/ntlm-tests.el b/test/lisp/net/ntlm-tests.el index 6408ac1334..0ed430afe6 100644 --- a/test/lisp/net/ntlm-tests.el +++ b/test/lisp/net/ntlm-tests.el @@ -17,11 +17,26 @@ ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs. If not, see . +;;; Commentary: + +;; Run this with `NTLM_TESTS_VERBOSE=1' to get verbose debugging. + +;;; Code: + (require 'ert) +(require 'ert-x) (require 'ntlm) +(defsubst ntlm-tests-message (format-string &rest arguments) + "Print a message conditional on an environment variable being set. +FORMAT-STRING and ARGUMENTS are passed to the message function." + (when (getenv "NTLM_TESTS_VERBOSE") + (apply #'message (concat "ntlm-tests: " format-string) arguments))) + + ;; This is the Lisp bignum implementation of `ntlm--time-to-timestamp', ;; for reference. + (defun ntlm-tests--time-to-timestamp (time) "Convert TIME to an NTLMv2 timestamp. Return a unibyte string representing the number of tenths of a @@ -49,4 +64,349 @@ signed integer. TIME must be on the form (HIGH LOW USEC PSEC)." (should (equal (ntlm--time-to-timestamp time) (ntlm-tests--time-to-timestamp time))))) +(defvar ntlm-tests--username-oem "ntlm" + "The username for NTLM authentication tests, in OEM string encoding.") +(defvar ntlm-tests--username-unicode + (ntlm-ascii2unicode ntlm-tests--username-oem + (length ntlm-tests--username-oem)) + "The username for NTLM authentication tests, in Unicode string encoding.") + +(defvar ntlm-tests--password "ntlm" + "The password used for NTLM authentication tests.") + +(defvar ntlm-tests--client-supports-unicode nil + "Non-nil if client supports Unicode strings. +If client only supports OEM strings, nil.") + +(defvar ntlm-tests--challenge nil "The global random challenge.") + +(defun ntlm-server-build-type-2 () + "Return an NTLM Type 2 message as a string. +This string will be returned from the NTLM server to the NTLM client." + (let ((target (if ntlm-tests--client-supports-unicode + (ntlm-ascii2unicode "DOMAIN" (length "DOMAIN")) + "DOMAIN")) + (target-information ntlm-tests--password) + ;; Flag byte 1 flags. + (_negotiate-unicode 1) + (negotiate-oem 2) + (request-target 4) + ;; Flag byte 2 flags. + (negotiate-ntlm 2) + (_negotiate-local-call 4) + (_negotiate-always-sign 8) + ;; Flag byte 3 flags. + (_target-type-domain 1) + (_target-type-server 2) + (target-type-share 4) + (_negotiate-ntlm2-key 8) + (negotiate-target-information 128) + ;; Flag byte 4 flags, unused. + (_negotiate-128 32) + (_negotiate-56 128)) + (concat + ;; Signature. + "NTLMSSP" (unibyte-string 0) + ;; Type 2. + (unibyte-string 2 0 0 0) + ;; Target length + (unibyte-string (length target) 0) + ;; Target allocated space. + (unibyte-string (length target) 0) + ;; Target offset. + (unibyte-string 48 0 0 0) + ;; Flags. + ;; Flag byte 1. + ;; Tell the client that this test server only supports OEM + ;; strings. This test server will handle Unicode strings + ;; anyway though. + (unibyte-string (logior negotiate-oem request-target)) + ;; Flag byte 2. + (unibyte-string negotiate-ntlm) + ;; Flag byte 3. + (unibyte-string (logior negotiate-target-information target-type-share)) + ;; Flag byte 4. Not sure what 2 means here. + (unibyte-string 2) + ;; Challenge. Set this to (unibyte-string 1 2 3 4 5 6 7 8) + ;; instead of (ntlm-generate-nonce) to hold constant for + ;; debugging. + (setq ntlm-tests--challenge (ntlm-generate-nonce)) + ;; Context. + (make-string 8 0) + (unibyte-string (length target-information) 0) + (unibyte-string (length target-information) 0) + (unibyte-string 54 0 0 0) + target + target-information))) + +(defun ntlm-server-hash (challenge blob username password) + "Hash CHALLENGE, BLOB, USERNAME and PASSWORD for a Type 3 check." + (hmac-md5 (concat challenge blob) + (hmac-md5 (concat + (upcase + ;; This calculation always uses + ;; Unicode username, even when the + ;; server only supports OEM strings. + (ntlm-ascii2unicode username (length username))) "") + (cadr (ntlm-get-password-hashes password))))) + +(defun ntlm-server-check-authorization (authorization-string) + "Return t if AUTHORIZATION-STRING correctly authenticates the user." + (let* ((binary (base64-decode-string + (caddr (split-string authorization-string " ")))) + (_lm-response-length (md4-unpack-int16 (substring binary 12 14))) + (_lm-response-offset + (cdr (md4-unpack-int32 (substring binary 16 20)))) + (ntlm-response-length (md4-unpack-int16 (substring binary 20 22))) + (ntlm-response-offset + (cdr (md4-unpack-int32 (substring binary 24 28)))) + (ntlm-hash + (substring binary ntlm-response-offset (+ ntlm-response-offset 16))) + (username-length (md4-unpack-int16 (substring binary 36 38))) + (username-offset (cdr (md4-unpack-int32 (substring binary 40 44)))) + (username (substring binary username-offset + (+ username-offset username-length)))) + (if (equal ntlm-response-length 24) + (let* ((expected + (ntlm-smb-owf-encrypt + (cadr (ntlm-get-password-hashes ntlm-tests--password)) + ntlm-tests--challenge)) + (received (substring binary ntlm-response-offset + (+ ntlm-response-offset + ntlm-response-length)))) + (ntlm-tests-message "Got NTLMv1 response:") + (ntlm-tests-message "Expected hash: ===%S===" expected) + (ntlm-tests-message "Got hash: ===%S===" received) + (ntlm-tests-message "Expected username: ===%S===" + ntlm-tests--username-oem) + (ntlm-tests-message "Got username: ===%S===" username) + (and (or (equal username ntlm-tests--username-oem) + (equal username ntlm-tests--username-unicode)) + (equal expected received))) + (let* ((ntlm-response-blob + (substring binary (+ ntlm-response-offset 16) + (+ (+ ntlm-response-offset 16) + (- ntlm-response-length 16)))) + (_ntlm-timestamp (substring ntlm-response-blob 8 16)) + (_ntlm-nonce (substring ntlm-response-blob 16 24)) + (_target-length (md4-unpack-int16 (substring binary 28 30))) + (_target-offset + (cdr (md4-unpack-int32 (substring binary 32 36)))) + (_workstation-length (md4-unpack-int16 (substring binary 44 46))) + (_workstation-offset + (cdr (md4-unpack-int32 (substring binary 48 52))))) + (cond + ;; This test server claims to only support OEM strings, + ;; but also checks Unicode strings. + ((or (equal username ntlm-tests--username-oem) + (equal username ntlm-tests--username-unicode)) + (let* ((password ntlm-tests--password) + (ntlm-hash-from-type-3 (ntlm-server-hash + ntlm-tests--challenge + ntlm-response-blob + ;; Always -oem since + ;; `ntlm-server-hash' + ;; always converts it to + ;; Unicode. + ntlm-tests--username-oem + password))) + (ntlm-tests-message "Got NTLMv2 response:") + (ntlm-tests-message "Expected hash: ==%S==" ntlm-hash) + (ntlm-tests-message "Got hash: ==%S==" ntlm-hash-from-type-3) + (ntlm-tests-message "Expected username: ===%S===" + ntlm-tests--username-oem) + (ntlm-tests-message " or username: ===%S===" + ntlm-tests--username-unicode) + (ntlm-tests-message "Got username: ===%S===" username) + (equal ntlm-hash ntlm-hash-from-type-3))) + (t + nil)))))) + +(require 'eieio) +(require 'cl-lib) + +;; Silence some byte-compiler warnings that occur when +;; web-server/web-server.el is not found. +(declare-function ws-send nil) +(declare-function ws-parse-request nil) +(declare-function ws-start nil) +(declare-function ws-stop-all nil) + +(require 'web-server nil t) +(require 'url-http-ntlm nil t) + +(defun ntlm-server-do-token (request _process) + "Process an NTLM client's REQUEST. +PROCESS is unused." + (with-slots (process headers) request + (let* ((header-alist (cdr headers)) + (authorization-header (assoc ':AUTHORIZATION header-alist)) + (authorization-string (cdr authorization-header))) + (if (and (stringp authorization-string) + (string-match "NTLM " authorization-string)) + (let* ((challenge (substring authorization-string (match-end 0))) + (binary (base64-decode-string challenge)) + (type (aref binary 8)) + ;; Flag byte 1 flags. + (negotiate-unicode 1) + (negotiate-oem 2) + (flags-byte-1 (aref binary 12)) + (client-supports-unicode + (not (zerop (logand flags-byte-1 negotiate-unicode)))) + (client-supports-oem + (not (zerop (logand flags-byte-1 negotiate-oem)))) + (connection-header (assoc ':CONNECTION header-alist)) + (_keep-alive + (when connection-header (cdr connection-header))) + (response + (cl-case type + (1 + ;; Return Type 2 message. + (when (and (not client-supports-unicode) + (not client-supports-oem)) + (warn (concat + "Weird client supports neither Unicode" + " nor OEM strings, using OEM."))) + (setq ntlm-tests--client-supports-unicode + client-supports-unicode) + (concat + "HTTP/1.1 401 Unauthorized\r\n" + "WWW-Authenticate: NTLM " + (base64-encode-string + (ntlm-server-build-type-2) t) "\r\n" + "WWW-Authenticate: Negotiate\r\n" + "WWW-Authenticate: Basic realm=\"domain\"\r\n" + "Content-Length: 0\r\n\r\n")) + (3 + (if (ntlm-server-check-authorization + authorization-string) + "HTTP/1.1 200 OK\r\n\r\nAuthenticated.\r\n" + (progn + (if process + (set-process-filter process nil) + (error "Type 3 message found first?")) + (concat "HTTP/1.1 401 Unauthorized\r\n\r\n" + "Access Denied.\r\n"))))))) + (if response + (ws-send process response) + (when process + (set-process-filter process nil))) + (when (equal type 3) + (set-process-filter process nil) + (process-send-eof process))) + (progn + ;; Did not get NTLM anything. + (set-process-filter process nil) + (process-send-eof process) + (concat "HTTP/1.1 401 Unauthorized\r\n\r\n" + "Access Denied.\r\n")))))) + +(defun ntlm-server-filter (process string) + "Read from PROCESS a STRING and treat it as a request from an NTLM client." + (let ((request (make-instance 'ws-request + :process process :pending string))) + (if (ws-parse-request request) + (ntlm-server-do-token request process) + (error "Failed to parse request")))) + +(defun ntlm-server-handler (request) + "Handle an HTTP REQUEST." + (with-slots (process headers) request + (let* ((header-alist (cdr headers)) + (authorization-header (assoc ':AUTHORIZATION header-alist)) + (connection-header (assoc ':CONNECTION header-alist)) + (keep-alive (when connection-header (cdr connection-header))) + (response (concat + "HTTP/1.1 401 Unauthorized\r\n" + "WWW-Authenticate: Negotiate\r\n" + "WWW-Authenticate: NTLM\r\n" + "WWW-Authenticate: Basic realm=\"domain\"\r\n" + "Content-Length: 0\r\n\r\n"))) + (if (null authorization-header) + ;; Tell client to use NTLM. Firefox will create a new + ;; connection. + (progn + (process-send-string process response) + (process-send-eof process)) + (progn + (ntlm-server-do-token request nil) + (set-process-filter process #'ntlm-server-filter) + (if (equal (upcase keep-alive) "KEEP-ALIVE") + :keep-alive + (error "NTLM server expects keep-alive connection header"))))))) + +(defun ntlm-server-start () + "Start an NTLM server on port 8080 for testing." + (ws-start 'ntlm-server-handler 8080)) + +(defun ntlm-server-stop () + "Stop the NTLM server." + (ws-stop-all)) + +(defvar ntlm-tests--result-buffer nil "Final NTLM result buffer.") + +(require 'url) + +(defun ntlm-tests--url-retrieve-internal-around (original &rest arguments) + "Save the result buffer from a `url-retrieve-internal' to a global variable. +ORIGINAL is the original `url-retrieve-internal' function and +ARGUMENTS are passed to it." + (setq ntlm-tests--result-buffer (apply original arguments))) + +(defun ntlm-tests--authenticate () + "Authenticate using credentials from the authinfo resource file." + (setq ntlm-tests--result-buffer nil) + (let ((auth-sources (list (ert-resource-file "authinfo"))) + (auth-source-do-cache nil) + (auth-source-debug (when (getenv "NTLM_TESTS_VERBOSE") 'trivia))) + (ntlm-tests-message "Using auth-sources: %S" auth-sources) + (url-retrieve-synchronously "http://localhost:8080")) + (sleep-for 0.1) + (ntlm-tests-message "Results are in: %S" ntlm-tests--result-buffer) + (with-current-buffer ntlm-tests--result-buffer + (buffer-string))) + +(defun ntlm-tests--start-server-authenticate-stop-server () + "Start an NTLM server, authenticate against it, then stop the server." + (advice-add #'url-retrieve-internal + :around #'ntlm-tests--url-retrieve-internal-around) + (ntlm-server-stop) + (ntlm-server-start) + (let ((result (ntlm-tests--authenticate))) + (advice-remove #'url-retrieve-internal + #'ntlm-tests--url-retrieve-internal-around) + (ntlm-server-stop) + result)) + +(defvar ntlm-tests--successful-result + (concat "HTTP/1.1 200 OK\n\nAuthenticated." (unibyte-string 13) "\n") + "Expected result of successful NTLM authentication.") + +(defvar ntlm-tests--dependencies-present + (and (featurep 'url-http-ntlm) (featurep 'web-server)) + "Non-nil if GNU ELPA test dependencies were loaded.") + +(when (not ntlm-tests--dependencies-present) + (warn "Cannot find one or more GNU ELPA packages") + (when (not (featurep 'url-http-ntlm)) + (warn "Need url-http-ntlm/url-http-ntlm.el")) + (when (not (featurep 'web-server)) + (warn "Need web-server/web-server.el")) + (warn "Skipping NTLM authentication tests") + (warn "See GNU_ELPA_DIRECTORY in test/README")) + +(ert-deftest ntlm-authentication () + "Check ntlm.el's implementation of NTLM authentication over HTTP." + (skip-unless ntlm-tests--dependencies-present) + (should (equal (ntlm-tests--start-server-authenticate-stop-server) + ntlm-tests--successful-result))) + +(ert-deftest ntlm-authentication-old-compatibility-level () + (skip-unless ntlm-tests--dependencies-present) + (setq ntlm-compatibility-level 0) + (should (equal (ntlm-tests--start-server-authenticate-stop-server) + ntlm-tests--successful-result))) + (provide 'ntlm-tests) + +;;; ntlm-tests.el ends here commit 5977de581cbffb18f1cacb266928329dc807cb22 Author: Stefan Monnier Date: Thu Feb 18 11:15:13 2021 -0500 * lisp/emacs-lisp/bindat.el: Tweak example in comment Suggested by Kim Storm . diff --git a/lisp/emacs-lisp/bindat.el b/lisp/emacs-lisp/bindat.el index 1f5022c274..b1b2144e3d 100644 --- a/lisp/emacs-lisp/bindat.el +++ b/lisp/emacs-lisp/bindat.el @@ -41,23 +41,23 @@ ;; Consider the following C structures: ;; ;; struct header { -;; unsigned long dest_ip; -;; unsigned long src_ip; -;; unsigned short dest_port; -;; unsigned short src_port; +;; uint32_t dest_ip; +;; uint32_t src_ip; +;; uint16_t dest_port; +;; uint16_t src_port; ;; }; ;; ;; struct data { -;; unsigned char type; -;; unsigned char opcode; -;; unsigned long length; /* In little endian order */ +;; uint8_t type; +;; uint8_t opcode; +;; uint32_t length; /* In little endian order */ ;; unsigned char id[8]; /* nul-terminated string */ ;; unsigned char data[/* (length + 3) & ~3 */]; ;; }; ;; ;; struct packet { ;; struct header header; -;; unsigned char items; +;; uint8_t items; ;; unsigned char filler[3]; ;; struct data item[/* items */]; ;; }; @@ -75,7 +75,7 @@ ;; (bindat-spec ;; (type u8) ;; (opcode u8) -;; (length u16r) ;; little endian order +;; (length u32r) ;; little endian order ;; (id strz 8) ;; (data vec (length)) ;; (align 4))) commit de15ca7d0065c5f77c88a90f4f14569886be3617 Author: Mattias Engdegård Date: Thu Feb 18 16:41:36 2021 +0100 Fix typos * doc/lispref/display.texi (Size of Displayed Text): * doc/lispref/windows.texi (Buffer Display Action Functions): * etc/NEWS: * etc/ORG-NEWS (Org-Attach has been refactored and extended): * lisp/battery.el (display-battery-mode, battery--upower-subsribe): * lisp/calendar/parse-time.el: * lisp/dired-x.el: * lisp/emacs-lisp/chart.el (chart-sequece, chart-bar-quickie): * lisp/emacs-lisp/eldoc.el (eldoc-echo-area-use-multiline-p) (eldoc-documentation-strategy): * lisp/emacs-lisp/pcase.el (pcase--split-pred, pcase--u1): * lisp/gnus/gnus-search.el (gnus-search-expandable-keys) (gnus-search-parse-query, gnus-search-query-return-string) (gnus-search-imap, gnus-search-imap-search-command) (gnus-search-transform-expression): * lisp/gnus/nnselect.el: * lisp/isearch.el (isearch-lazy-count-format): * lisp/mh-e/mh-show.el (mh-show-msg): * lisp/net/dictionary-connection.el (dictionary-connection-open): * lisp/net/dictionary.el (dictionary-default-popup-strategy) (dictionary, dictionary-split-string, dictionary-do-select-dictionary) (dictionary-display-dictionarys, dictionary-search) (dictionary-tooltip-mode): * lisp/net/eudcb-macos-contacts.el (eudc-macos-contacts-set-server): * lisp/net/mailcap.el (mailcap-mime-data): * lisp/net/tramp-smb.el (tramp-smb-maybe-open-connection): * lisp/nxml/nxml-mode.el (nxml-mode): * lisp/progmodes/cc-engine.el: * lisp/progmodes/cperl-mode.el (cperl-mode) (cperl-fontify-syntaxically): * lisp/progmodes/flymake.el (flymake-diagnostic-functions): * lisp/progmodes/verilog-mode.el (verilog--supressed-warnings) (verilog-preprocess): * lisp/simple.el (self-insert-uses-region-functions): * lisp/textmodes/bibtex.el (bibtex-copy-summary-as-kill): * lisp/textmodes/texnfo-upd.el (texinfo-insert-master-menu-list): * src/dispnew.c: * src/font.c (Ffont_get): * src/indent.c (compute_motion): * src/process.c (init_process_emacs): * src/w32fns.c (deliver_wm_chars): * test/lisp/jsonrpc-tests.el (deferred-action-complex-tests): Fix typos in documentation, comments, and internal identifiers. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 93e935ccf8..131ad2d9c8 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -1997,7 +1997,7 @@ the beginning of the result if a multi-column character in If @var{ellipsis} is non-@code{nil}, it should be a string which will replace the end of @var{string} when it is truncated. In this case, -more charcaters will be removed from @var{string} to free enough space +more characters will be removed from @var{string} to free enough space for @var{ellipsis} to fit within @var{width} columns. However, if the display width of @var{string} is less than the display width of @var{ellipsis}, @var{ellipsis} will not be appended to the result. If diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index f305d1a8ee..c32d711f12 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@ -2557,7 +2557,7 @@ frame visible and, unless @var{alist} contains an This function tries to display @var{buffer} by finding a window that is displaying a buffer in a given mode. -If @var{alist} contains a @code{mode} entry, its value specifes a +If @var{alist} contains a @code{mode} entry, its value specifies a major mode (a symbol) or a list of major modes. If @var{alist} contains no @code{mode} entry, the current major mode of @var{buffer} is used instead. A window is a candidate if it displays a buffer diff --git a/etc/NEWS b/etc/NEWS index 7665d4740f..ee8a68a259 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1015,7 +1015,7 @@ separate buffer, or a tooltip. *** New user option 'eldoc-documentation-strategy'. The built-in choices available for this user option let users compose the results of 'eldoc-documentation-functions' in various ways, even -if some of those functions are sychronous and some asynchchronous. +if some of those functions are synchronous and some asynchronous. The user option replaces 'eldoc-documentation-function', which is now obsolete. diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 2cae8b92ac..2b9cbf37c4 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -747,7 +747,7 @@ removed. For those who hate breaking changes, even though the changes are made to clean things up; fear not. ATTACH_DIR will still continue to work. It's just not documented any longer. When you get the chance, run the -code above to clean things up anyways! +code above to clean things up anyway! **** New hooks Two hooks are added to org-attach: diff --git a/lisp/battery.el b/lisp/battery.el index 77ad73d15d..59f6987ad1 100644 --- a/lisp/battery.el +++ b/lisp/battery.el @@ -246,7 +246,7 @@ seconds." (add-to-list 'global-mode-string 'battery-mode-line-string t) (and (eq battery-status-function #'battery-upower) battery-upower-subscribe - (battery--upower-subsribe)) + (battery--upower-subscribe)) (setq battery-update-timer (run-at-time nil battery-update-interval #'battery-update-handler)) (battery-update)) @@ -634,7 +634,7 @@ Intended as a UPower PropertiesChanged signal handler." (mapc #'dbus-unregister-object battery--upower-signals) (setq battery--upower-signals ())) -(defun battery--upower-subsribe () +(defun battery--upower-subscribe () "Subscribe to UPower device change signals." (push (dbus-register-signal :system battery-upower-service battery-upower-path diff --git a/lisp/calendar/parse-time.el b/lisp/calendar/parse-time.el index ba7418faf7..aa3236cf25 100644 --- a/lisp/calendar/parse-time.el +++ b/lisp/calendar/parse-time.el @@ -29,7 +29,7 @@ ;; `parse-time-string' parses a time in a string and returns a list of ;; values, just like `decode-time', where unspecified elements in the -;; string are returned as nil (except unspecfied DST is returned as -1). +;; string are returned as nil (except unspecified DST is returned as -1). ;; `encode-time' may be applied on these values to obtain an internal ;; time value. diff --git a/lisp/dired-x.el b/lisp/dired-x.el index 5a52eccbbe..1199de183f 100644 --- a/lisp/dired-x.el +++ b/lisp/dired-x.el @@ -447,7 +447,7 @@ If it is `no-dir', omitting is much faster, but you can only match against the non-directory part of the file name. Set it to nil if you need to match the entire file name.") -;; \017=^O for Omit - other packages can chose other control characters. +;; \017=^O for Omit - other packages can choose other control characters. (defvar dired-omit-marker-char ?\017 "Temporary marker used by Dired-Omit. Should never be used as marker by the user or other packages.") diff --git a/lisp/emacs-lisp/chart.el b/lisp/emacs-lisp/chart.el index 7d760ffc57..40c17b916f 100644 --- a/lisp/emacs-lisp/chart.el +++ b/lisp/emacs-lisp/chart.el @@ -187,7 +187,7 @@ Make sure the width/height is correct." ) "Class used to display an axis which represents different named items.") -(defclass chart-sequece () +(defclass chart-sequence () ((data :initarg :data :initform nil) (name :initarg :name @@ -583,12 +583,12 @@ SORT-PRED if desired." )) (iv (eq dir 'vertical))) (chart-add-sequence nc - (make-instance 'chart-sequece + (make-instance 'chart-sequence :data namelst :name nametitle) (if iv 'x-axis 'y-axis)) (chart-add-sequence nc - (make-instance 'chart-sequece + (make-instance 'chart-sequence :data numlst :name numtitle) (if iv 'y-axis 'x-axis)) diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el index c95540ea3c..a02406a7b7 100644 --- a/lisp/emacs-lisp/eldoc.el +++ b/lisp/emacs-lisp/eldoc.el @@ -100,7 +100,7 @@ If the value is a positive number, it is used to calculate a number of logical lines of documentation that ElDoc is allowed to put in the echo area. If a positive integer, the number is used directly, while a float specifies the number of lines as a -proporting of the echo area frame's height. +proportion of the echo area frame's height. If value is the symbol `truncate-sym-name-if-fit' t, the part of the doc string that represents a symbol's name may be truncated @@ -692,7 +692,7 @@ following values are allowed: - `eldoc-documentation-compose-eagerly': calls all functions in the special hook and display as many of the resulting doc - strings as possible, as soon as possibl. Preserving the + strings as possible, as soon as possible. Preserving the relative order of doc strings; - `eldoc-documentation-enthusiast': calls all functions in the diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index d3928fa505..c7288b7fa2 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -642,7 +642,7 @@ MATCH is the pattern that needs to be matched, of the form: (defun pcase--split-pred (vars upat pat) "Indicate the overlap or mutual-exclusion between UPAT and PAT. -More specifically retuns a pair (A . B) where A indicates whether PAT +More specifically returns a pair (A . B) where A indicates whether PAT can match when UPAT has matched, and B does the same for the case where UPAT failed to match. A and B can be one of: @@ -784,7 +784,7 @@ Otherwise, it defers to REST which is a list of branches of the form \(ELSE-MATCH ELSE-CODE . ELSE-VARS)." ;; Depending on the order in which we choose to check each of the MATCHES, ;; the resulting tree may be smaller or bigger. So in general, we'd want - ;; to be careful to chose the "optimal" order. But predicate + ;; to be careful to choose the "optimal" order. But predicate ;; patterns make this harder because they create dependencies ;; between matches. So we don't bother trying to reorder anything. (cond diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el index d7b1c06114..339bff9d67 100644 --- a/lisp/gnus/gnus-search.el +++ b/lisp/gnus/gnus-search.el @@ -365,7 +365,7 @@ This variable can also be set per-server." "A list of strings representing expandable search keys. \"Expandable\" simply means the key can be abbreviated while typing in search queries, ie \"subject\" could be entered as -\"subj\" or even \"su\", though \"s\" is ambigous between +\"subj\" or even \"su\", though \"s\" is ambiguous between \"subject\" and \"since\". Ambiguous abbreviations will raise an error." @@ -402,7 +402,7 @@ The search \"language\" is essentially a series of key:value expressions. Key is most often a mail header, but there are other keys. Value is a string, quoted if it contains spaces. Key and value are separated by a colon, no space. Expressions -are implictly ANDed; the \"or\" keyword can be used to +are implicitly ANDed; the \"or\" keyword can be used to OR. \"not\" will negate the following expression, or keys can be prefixed with a \"-\". The \"near\" operator will work for engines that understand it; other engines will convert it to @@ -448,7 +448,7 @@ auto-completion of contact names and addresses for keys like Date values (any key in `gnus-search-date-keys') can be provided in any format that `parse-time-string' can parse (note that this can produce weird results). Dates with missing bits will be -interpreted as the most recent occurance thereof (ie \"march 03\" +interpreted as the most recent occurence thereof (ie \"march 03\" is the most recent March 3rd). Lastly, relative specifications such as 1d (one day ago) are understood. This also accepts w, m, and y. m is assumed to be 30 days. @@ -646,7 +646,7 @@ gnus-*-mark marks, and return an appropriate string." "Return a string from the current buffer. If DELIMITED is non-nil, assume the next character is a delimiter character, and return everything between point and the next -occurance of the delimiter, including the delimiters themselves. +occurence of the delimiter, including the delimiters themselves. If TRIM is non-nil, do not return the delimiters. Otherwise, return one word." ;; This function cannot handle nested delimiters, as it's not a @@ -789,7 +789,7 @@ the files in ARTLIST by that search key.") (raw-queries-p :initform (symbol-value 'gnus-search-imap-raw-queries-p))) :documentation - "The base IMAP search engine, using an IMAP server's search capabilites. + "The base IMAP search engine, using an IMAP server's search capabilities. This backend may be subclassed to handle particular IMAP servers' quirks.") @@ -1082,7 +1082,7 @@ Responsible for handling and, or, and parenthetical expressions.") (cl-defmethod gnus-search-imap-search-command ((engine gnus-search-imap) (query string)) "Create the IMAP search command for QUERY. -Currenly takes into account support for the LITERAL+ capability. +Currently takes into account support for the LITERAL+ capability. Other capabilities could be tested here." (with-slots (literal-plus) engine (when literal-plus @@ -1672,8 +1672,8 @@ and \"-\" before marks." (cl-defmethod gnus-search-transform-expression ((engine gnus-search-mairix) (expr (head or))) "Handle Mairix \"or\" statement. -Mairix only accepts \"or\" expressions on homogenous keys. We -cast \"or\" expressions on heterogenous keys as \"and\", which +Mairix only accepts \"or\" expressions on homogeneous keys. We +cast \"or\" expressions on heterogeneous keys as \"and\", which isn't quite right, but it's the best we can do. For date keys, only keep one of the terms." (let ((term1 (caadr expr)) diff --git a/lisp/gnus/nnselect.el b/lisp/gnus/nnselect.el index fffa2d2731..1daa8aa673 100644 --- a/lisp/gnus/nnselect.el +++ b/lisp/gnus/nnselect.el @@ -33,7 +33,7 @@ ;; turn be a vector of three elements: a real prefixed group name, an ;; article number in that group, and an integer score. The score is ;; not used by nnselect but may be used by other code to help in -;; sorting. Most functions will just chose a fixed number, such as +;; sorting. Most functions will just choose a fixed number, such as ;; 100, for this score. ;; For example the search function `gnus-search-run-query' applied to diff --git a/lisp/isearch.el b/lisp/isearch.el index c571ea9467..8266c4b7a0 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -3356,7 +3356,7 @@ the word mode." (defun isearch-lazy-count-format (&optional suffix-p) "Format the current match number and the total number of matches. -When SUFFIX-P is non-nil, the returned string is indended for +When SUFFIX-P is non-nil, the returned string is intended for isearch-message-suffix prompt. Otherwise, for isearch-message-prefix." (let ((format-string (if suffix-p lazy-count-suffix-format diff --git a/lisp/mh-e/mh-show.el b/lisp/mh-e/mh-show.el index 9ad843c325..1d25b14732 100644 --- a/lisp/mh-e/mh-show.el +++ b/lisp/mh-e/mh-show.el @@ -136,7 +136,7 @@ displayed." (show-window (get-buffer-window mh-show-buffer)) (display-mime-buttons-flag mh-display-buttons-for-inline-parts-flag)) (if (not (eq (next-window (minibuffer-window)) (selected-window))) - (delete-other-windows)) ; force ourself to the top window + (delete-other-windows)) ; force ourselves to the top window (mh-in-show-buffer (mh-show-buffer) (setq mh-display-buttons-for-inline-parts-flag display-mime-buttons-flag) (if (and show-window diff --git a/lisp/net/dictionary-connection.el b/lisp/net/dictionary-connection.el index 8ad4fe4e63..83125742be 100644 --- a/lisp/net/dictionary-connection.el +++ b/lisp/net/dictionary-connection.el @@ -23,9 +23,9 @@ ;;; Commentary: ;; dictionary-connection allows to handle TCP-based connections in -;; client mode where text-based information are exchanged. There is +;; client mode where text-based information is exchanged. There is ;; special support for handling CR LF (and the usual CR LF . CR LF -;; terminater). +;; terminator). ;;; Code: @@ -68,7 +68,7 @@ (defun dictionary-connection-open (server port) "Open a connection to SERVER at PORT. -A data structure identifing the connection is returned" +A data structure identifying the connection is returned" (let ((process-buffer (generate-new-buffer (format " connection to %s:%s" server diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el index 6f086053b6..c6af4e66e3 100644 --- a/lisp/net/dictionary.el +++ b/lisp/net/dictionary.el @@ -127,9 +127,9 @@ by the choice value: The found word exactly matches the searched word. -- Similiar sounding +- Similar sounding - The found word sounds similiar to the searched word. For this match type + The found word sounds similar to the searched word. For this match type the soundex algorithm defined by Donald E. Knuth is used. It will only works with english words and the algorithm is not very reliable (i.e., the soundex algorithm is quite simple). @@ -148,7 +148,7 @@ by the choice value: dictionary server." :group 'dictionary :type '(choice (const :tag "Exact match" "exact") - (const :tag "Similiar sounding" "soundex") + (const :tag "Similar sounding" "soundex") (const :tag "Levenshtein distance one" "lev") (string :tag "User choice")) :version "28.1") @@ -419,7 +419,7 @@ This is a quick reference to this mode describing the default key bindings: ;;;###autoload (defun dictionary () - "Create a new dictonary buffer and install `dictionary-mode'." + "Create a new dictionary buffer and install `dictionary-mode'." (interactive) (let ((buffer (or (and dictionary-use-single-buffer (get-buffer "*Dictionary*")) @@ -568,7 +568,7 @@ The connection takes the proxy setting in customization group answer))) (defun dictionary-split-string (string) - "Split STRING constiting of space-separated words into elements. + "Split STRING consisting of space-separated words into elements. This function knows about the special meaning of quotes (\")" (let ((list)) (while (and string (> (length string) 0)) @@ -894,7 +894,7 @@ The word is taken from the buffer, the DICTIONARY is given as argument." (unless (dictionary-check-reply reply 110) (error "Unknown server answer: %s" (dictionary-reply reply))) - (dictionary-display-dictionarys)))) + (dictionary-display-dictionaries)))) (defun dictionary-simple-split-string (string &optional pattern) "Return a list of substrings of STRING which are separated by PATTERN. @@ -909,7 +909,7 @@ If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." start (match-end 0))) (nreverse (cons (substring string start) parts)))) -(defun dictionary-display-dictionarys () +(defun dictionary-display-dictionaries () "Handle the display of all dictionaries existing on the server." (dictionary-pre-buffer) (insert "Please select your default dictionary:\n\n") @@ -1171,7 +1171,7 @@ allows editing it." ;; if called by pressing the button (unless word (setq word (read-string "Search word: " nil 'dictionary-word-history))) - ;; just in case non-interactivly called + ;; just in case non-interactively called (unless dictionary (setq dictionary dictionary-default-dictionary)) (dictionary-new-search (cons word dictionary))) @@ -1249,10 +1249,10 @@ allows editing it." ;;; Tooltip support -;; Add a mode indicater named "Dict" +;; Add a mode indicator named "Dict" (defvar dictionary-tooltip-mode nil - "Indicates wheather the dictionary tooltip mode is active.") + "Indicates whether the dictionary tooltip mode is active.") (nconc minor-mode-alist '((dictionary-tooltip-mode " Dict"))) (defcustom dictionary-tooltip-dictionary diff --git a/lisp/net/eudcb-macos-contacts.el b/lisp/net/eudcb-macos-contacts.el index 66a684dfc5..b07016c122 100644 --- a/lisp/net/eudcb-macos-contacts.el +++ b/lisp/net/eudcb-macos-contacts.el @@ -108,7 +108,7 @@ RETURN-ATTRS is a list of attributes to return, defaulting to (defun eudc-macos-contacts-set-server (dummy) "Set the EUDC server to macOS Contacts app. The server in DUMMY is not actually used, since this backend -always and implicitly connetcs to an instance of the Contacts app +always and implicitly connects to an instance of the Contacts app running on the local host." (interactive) (eudc-set-server dummy 'macos-contacts) diff --git a/lisp/net/mailcap.el b/lisp/net/mailcap.el index b95cd0febc..3097c9a671 100644 --- a/lisp/net/mailcap.el +++ b/lisp/net/mailcap.el @@ -332,7 +332,7 @@ whose car is a symbol, it is `eval'uated to yield the validity. If it is a string or list of strings, it represents a shell command to run to return a true or false shell value for the validity. -The last matching entry in this structure takes presedence over +The last matching entry in this structure takes precedence over preceding entries.") (put 'mailcap-mime-data 'risky-local-variable t) diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 4519c34d36..69359553e4 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -1928,7 +1928,7 @@ If ARGUMENT is non-nil, use it as argument for ;; Check whether we still have the same smbclient version. ;; Otherwise, we must delete the connection cache, because - ;; capabilities migh have changed. + ;; capabilities might have changed. (unless (or argument (processp p)) (let ((default-directory (tramp-compat-temporary-file-directory)) (command (concat tramp-smb-program " -V"))) diff --git a/lisp/nxml/nxml-mode.el b/lisp/nxml/nxml-mode.el index 0602943db2..1bc905cee2 100644 --- a/lisp/nxml/nxml-mode.el +++ b/lisp/nxml/nxml-mode.el @@ -546,7 +546,7 @@ Many aspects this mode can be customized using (when (and nxml-default-buffer-file-coding-system (not (local-variable-p 'buffer-file-coding-system))) (setq buffer-file-coding-system nxml-default-buffer-file-coding-system)) - ;; When starting a new file, insert the XML declaraction. + ;; When starting a new file, insert the XML declaration. (when (and nxml-auto-insert-xml-declaration-flag (zerop (buffer-size))) (nxml-insert-xml-declaration))) diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 484624b866..9038c7bd95 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -2665,7 +2665,7 @@ comment at the start of cc-engine.el for more info." ;; One of the above "near" caches is associated with each of these functions. ;; ;; When searching this cache, these functions first seek an exact match, then -;; a "close" match from the assiciated near cache. If neither of these +;; a "close" match from the associated near cache. If neither of these ;; succeed, the nearest preceding entry in the far cache is used. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index 44a7526952..d01bd3a48e 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -1764,12 +1764,12 @@ or as help on variables `cperl-tips', `cperl-problems', (setq-local syntax-propertize-function (lambda (start end) (goto-char start) - ;; Even if cperl-fontify-syntaxically has already gone + ;; Even if cperl-fontify-syntactically has already gone ;; beyond `start', syntax-propertize has just removed ;; syntax-table properties between start and end, so we have ;; to re-apply them. (setq cperl-syntax-done-to start) - (cperl-fontify-syntaxically end)))) + (cperl-fontify-syntactically end)))) (setq cperl-font-lock-multiline t) ; Not localized... (setq-local font-lock-multiline t) (setq-local font-lock-fontify-region-function @@ -8407,7 +8407,7 @@ do extra unwind via `cperl-unwind-to-safe'." (setq end (point))) (font-lock-default-fontify-region beg end loudly)) -(defun cperl-fontify-syntaxically (end) +(defun cperl-fontify-syntactically (end) ;; Some vars for debugging only ;; (message "Syntaxifying...") (let ((dbg (point)) (iend end) (idone cperl-syntax-done-to) diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index b8c8a827ee..d01803282a 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -483,7 +483,7 @@ Currently, Flymake may provide these keyword-value pairs: * `:recent-changes', a list of recent changes since the last time the backend function was called for the buffer. An empty list - indicates that no changes have been reocrded. If it is the + indicates that no changes have been recorded. If it is the first time that this backend function is called for this activation of `flymake-mode', then this argument isn't provided at all (i.e. it's not merely nil). diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el index f934ef7a80..55c04e1332 100644 --- a/lisp/progmodes/verilog-mode.el +++ b/lisp/progmodes/verilog-mode.el @@ -134,7 +134,7 @@ (interactive) (message "Using verilog-mode version %s" verilog-mode-version)) -(defmacro verilog--supressed-warnings (warnings &rest body) +(defmacro verilog--suppressed-warnings (warnings &rest body) (declare (indent 1) (debug t)) (cond ((fboundp 'with-suppressed-warnings) @@ -5550,7 +5550,7 @@ FILENAME to find directory to run in, or defaults to `buffer-file-name'." ;; font-lock-fontify-buffer, but IIUC the problem this is supposed to ;; solve only appears in Emacsen older than font-lock-ensure anyway. (when fontlocked - (verilog--supressed-warnings + (verilog--suppressed-warnings ((interactive-only font-lock-fontify-buffer)) (font-lock-fontify-buffer)))))))) diff --git a/lisp/simple.el b/lisp/simple.el index d6ccdad902..a4da3f58a9 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -549,7 +549,7 @@ It must be called via `run-hook-with-args-until-success' with no arguments. If any function on this hook returns a non-nil value, `delete-selection-mode' will act on that value (see `delete-selection-helper') and will usually delete the region. If all the functions on this hook return -nil, it is an indiction that `self-insert-command' needs the region +nil, it is an indication that `self-insert-command' needs the region untouched by `delete-selection-mode' and will itself do whatever is appropriate with the region. Any function on `post-self-insert-hook' that acts on the region should diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el index a22cd97b30..301f7017e4 100644 --- a/lisp/textmodes/bibtex.el +++ b/lisp/textmodes/bibtex.el @@ -3327,7 +3327,7 @@ Use `bibtex-summary-function' to generate summary." (message "%s %s" key summary)))))) (defun bibtex-copy-summary-as-kill (&optional arg) - "Push summery of current BibTeX entry to kill ring. + "Push summary of current BibTeX entry to kill ring. Use `bibtex-summary-function' to generate summary. If prefix ARG is non-nil push BibTeX entry's URL to kill ring that is generated by calling `bibtex-url'." diff --git a/lisp/textmodes/texnfo-upd.el b/lisp/textmodes/texnfo-upd.el index ea35641a6c..04778ee94d 100644 --- a/lisp/textmodes/texnfo-upd.el +++ b/lisp/textmodes/texnfo-upd.el @@ -1033,7 +1033,7 @@ However, there does not need to be a title field." (save-excursion ;; `master-menu-inserted-p' is a kludge to tell - ;; whether to insert @end detailmenu (see bleow) + ;; whether to insert @end detailmenu (see below) (let (master-menu-inserted-p) ;; Handle top of menu (insert "\n@menu\n") diff --git a/src/dispnew.c b/src/dispnew.c index e603c67136..b3e4587250 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -3328,7 +3328,7 @@ update_frame_with_menu (struct frame *f, int row, int col) } /* Update the mouse position for a frame F. This handles both - updating the display for mouse-face propreties and updating the + updating the display for mouse-face properties and updating the help echo text. Returns the number of events generated. */ diff --git a/src/font.c b/src/font.c index a59ebe216b..7c1d1ff89b 100644 --- a/src/font.c +++ b/src/font.c @@ -4122,7 +4122,7 @@ representing the OpenType features supported by the font by this form: SCRIPT, LANGSYS, and FEATURE are all symbols representing OpenType Layout tags. -In addition to the keys listed abobe, the following keys are reserved +In addition to the keys listed above, the following keys are reserved for the specific meanings as below: The value of :combining-capability is non-nil if the font-backend of diff --git a/src/indent.c b/src/indent.c index 0a6b460f75..6246b544fb 100644 --- a/src/indent.c +++ b/src/indent.c @@ -1315,7 +1315,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, j ^---- next after the point ^--- next char. after the point. ---------- - In case of sigle-column character + In case of single-column character ---------- abcdefgh\\ diff --git a/src/process.c b/src/process.c index 3beb9cf714..b98bc297a3 100644 --- a/src/process.c +++ b/src/process.c @@ -8255,7 +8255,7 @@ init_process_emacs (int sockfd) private SIGCHLD handler, allowing catch_child_signal to copy it into lib_child_handler. - Unfortunatly in glib commit 2e471acf, the behavior changed to + Unfortunately in glib commit 2e471acf, the behavior changed to always install a signal handler when g_child_watch_source_new is called and not just the first time it's called. Glib also now resets signal handlers to SIG_DFL when it no longer has a diff --git a/src/w32fns.c b/src/w32fns.c index 86c3db64e7..9db367bfaf 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -3893,7 +3893,7 @@ deliver_wm_chars (int do_translate, HWND hwnd, UINT msg, UINT wParam, Essentially, we have no information about the "role" of modifiers on this key: which contribute into the produced character (so "are consumed"), and which are - "extra" (must attache to bindable events). + "extra" (must attach to bindable events). The default above would consume ALL modifiers, so the character is reported "as is". However, on many layouts diff --git a/test/lisp/jsonrpc-tests.el b/test/lisp/jsonrpc-tests.el index ea340c370d..92306d1c7e 100644 --- a/test/lisp/jsonrpc-tests.el +++ b/test/lisp/jsonrpc-tests.el @@ -244,7 +244,7 @@ :timeout 1) ;; Wait another 0.5 secs just in case the success handlers of ;; one of these last two requests didn't quite have a chance to - ;; run (Emacs 25.2 apparentely needs this). + ;; run (Emacs 25.2 apparently needs this). (accept-process-output nil 0.5) (should second-deferred-went-through-p) (should (eq 1 n-deferred-1)) commit bae2cfe63cbd11eaf348dfa7fbb2b9f7362fc747 Author: Stefan Monnier Date: Thu Feb 18 10:27:36 2021 -0500 * lisp/emacs-lisp/edebug.el (eval-defun): Simplify (edebug-all-defs, edebug-all-forms): Don't autoload since the problem it was working around has been fixed a while back. (edebug--eval-defun): Rename from `edebug-eval-defun` and simplify by making it an `:around` advice. (edebug-install-read-eval-functions) (edebug-uninstall-read-eval-functions): Adjust accordingly. (edebug-eval-defun): Redefine as an obsolete wrapper. * lisp/progmodes/elisp-mode.el (elisp--eval-defun): Use `load-read-function` so it obeys `edebug-all-(defs|forms)`. (elisp--eval-defun): Fix recent regression introduced with `elisp--eval-defun-result`. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 4599694594..45e76c751f 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -88,7 +88,6 @@ using, but only when you also use Edebug." ;; because the byte compiler binds them; as a result, if edebug ;; is first loaded for a require in a compilation, they will be left unbound. -;;;###autoload (defcustom edebug-all-defs nil "If non-nil, evaluating defining forms instruments for Edebug. This applies to `eval-defun', `eval-region', `eval-buffer', and @@ -101,11 +100,6 @@ variable. You may wish to make it local to each buffer with `emacs-lisp-mode-hook'." :type 'boolean) -;; edebug-all-defs and edebug-all-forms need to be autoloaded -;; because the byte compiler binds them; as a result, if edebug -;; is first loaded for a require in a compilation, they will be left unbound. - -;;;###autoload (defcustom edebug-all-forms nil "Non-nil means evaluation of all forms will instrument for Edebug. This doesn't apply to loading or evaluations in the minibuffer. @@ -457,66 +451,24 @@ the option `edebug-all-forms'." ;; We should somehow arrange to be able to do this ;; without actually replacing the eval-defun command. -(defun edebug-eval-defun (edebug-it) - "Evaluate the top-level form containing point, or after point. - -If the current defun is actually a call to `defvar', then reset the -variable using its initial value expression even if the variable -already has some other value. (Normally `defvar' does not change the -variable's value if it already has a value.) Treat `defcustom' -similarly. Reinitialize the face according to `defface' specification. - -With a prefix argument, instrument the code for Edebug. - -Setting option `edebug-all-defs' to a non-nil value reverses the meaning +(defun edebug--eval-defun (orig-fun edebug-it) + "Setting option `edebug-all-defs' to a non-nil value reverses the meaning of the prefix argument. Code is then instrumented when this function is invoked without a prefix argument. If acting on a `defun' for FUNCTION, and the function was instrumented, `Edebug: FUNCTION' is printed in the minibuffer. If not instrumented, -just FUNCTION is printed. +just FUNCTION is printed." + (let* ((edebug-all-forms (not (eq (not edebug-it) (not edebug-all-defs)))) + (edebug-all-defs edebug-all-forms)) + (funcall orig-fun nil))) -If not acting on a `defun', the result of evaluation is displayed in -the minibuffer." +(defun edebug-eval-defun (edebug-it) + (declare (obsolete "use eval-defun or edebug--eval-defun instead" "28.1")) (interactive "P") - (let* ((edebugging (not (eq (not edebug-it) (not edebug-all-defs)))) - (edebug-result) - (form - (let ((edebug-all-forms edebugging) - (edebug-all-defs (eq edebug-all-defs (not edebug-it)))) - (edebug-read-top-level-form)))) - ;; This should be consistent with `eval-defun-1', but not the - ;; same, since that gets a macroexpanded form. - (cond ((and (eq (car form) 'defvar) - (cdr-safe (cdr-safe form))) - ;; Force variable to be bound. - (makunbound (nth 1 form))) - ((and (eq (car form) 'defcustom) - (default-boundp (nth 1 form))) - ;; Force variable to be bound. - ;; FIXME: Shouldn't this use the :setter or :initializer? - (set-default (nth 1 form) (eval (nth 2 form) lexical-binding))) - ((eq (car form) 'defface) - ;; Reset the face. - (setq face-new-frame-defaults - (assq-delete-all (nth 1 form) face-new-frame-defaults)) - (put (nth 1 form) 'face-defface-spec nil) - (put (nth 1 form) 'face-documentation (nth 3 form)) - ;; See comments in `eval-defun-1' for purpose of code below - (setq form (prog1 `(prog1 ,form - (put ',(nth 1 form) 'saved-face - ',(get (nth 1 form) 'saved-face)) - (put ',(nth 1 form) 'customized-face - ,(nth 2 form))) - (put (nth 1 form) 'saved-face nil))))) - (setq edebug-result (eval (eval-sexp-add-defvars form) lexical-binding)) - (if (not edebugging) - (prog1 - (prin1 edebug-result) - (let ((str (eval-expression-print-format edebug-result))) - (if str (princ str)))) - edebug-result))) - + (if (advice-member-p #'edebug--eval-defun 'eval-defun) + (eval-defun edebug-it) + (edebug--eval-defun #'eval-defun edebug-it))) ;;;###autoload (defalias 'edebug-defun 'edebug-eval-top-level-form) @@ -588,12 +540,12 @@ already is one.)" (defun edebug-install-read-eval-functions () (interactive) (add-function :around load-read-function #'edebug--read) - (advice-add 'eval-defun :override #'edebug-eval-defun)) + (advice-add 'eval-defun :around #'edebug--eval-defun)) (defun edebug-uninstall-read-eval-functions () (interactive) (remove-function load-read-function #'edebug--read) - (advice-remove 'eval-defun #'edebug-eval-defun)) + (advice-remove 'eval-defun #'edebug--eval-defun)) ;;; Edebug internal data diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index c14b18425f..397eb269a7 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -1342,6 +1342,7 @@ if it already has a value.) Return the result of evaluation." ;; FIXME: the print-length/level bindings should only be applied while ;; printing, not while evaluating. + (defvar elisp--eval-defun-result) (let ((debug-on-error eval-expression-debug-on-error) (print-length eval-expression-print-length) (print-level eval-expression-print-level) @@ -1357,19 +1358,22 @@ Return the result of evaluation." (end-of-defun) (beginning-of-defun) (setq beg (point)) - (setq form (read (current-buffer))) + (setq form (funcall load-read-function (current-buffer))) (setq end (point))) ;; Alter the form if necessary. (let ((form (eval-sexp-add-defvars (elisp--eval-defun-1 - (macroexpand - `(setq elisp--eval-defun-result ,form)))))) + (macroexpand form))))) (eval-region beg end standard-output (lambda (_ignore) ;; Skipping to the end of the specified region ;; will make eval-region return. (goto-char end) - form))))) + ;; This `setq' needs to be added *after* passing + ;; form through `elisp--eval-defun-1' since it + ;; would otherwise "hide" forms like `defvar's and + ;; thus defeat their special treatment. + `(setq elisp--eval-defun-result ,form)))))) (let ((str (eval-expression-print-format elisp--eval-defun-result))) (if str (princ str))) elisp--eval-defun-result)) commit 9882e63eeaed54244a6b608685dd748f72ef66a6 Author: Eli Zaretskii Date: Thu Feb 18 16:07:34 2021 +0200 ; * CONTRIBUTE: Another wording change regarding tiny changes. diff --git a/CONTRIBUTE b/CONTRIBUTE index b7d72f9965..fe773510d3 100644 --- a/CONTRIBUTE +++ b/CONTRIBUTE @@ -66,9 +66,9 @@ more reliably, and makes the job of applying the patches easier and less error-prone. It also allows sending patches whose author is someone other than the email sender. -Once the cumulative amount of your submissions exceeds about 10 lines -of non-trivial changes, we will need you to assign to the FSF the -copyright for your contributions. (To see how many lines were +Once the cumulative amount of your submissions exceeds a dozen or so +lines of non-trivial changes, we will need you to assign to the FSF +the copyright for your contributions. (To see how many lines were non-trivially changed, count only added and modified lines in the patched code. Consider an added or changed line non-trivial if it includes at least one identifier, string, or substantial comment.) commit eb9f80e37b42576dd5a86c89e18d44ad2cec4273 Author: Lars Ingebrigtsen Date: Thu Feb 18 12:52:55 2021 +0100 Revert "Do interactive mode tagging for python.el navigation functions." This reverts commit 546f552e7b2439b482c7d28222fb88761a9c876a. This is a "core package", so can't use the new syntax. diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 7506043a19..afb96974b1 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1506,7 +1506,7 @@ point position. Return non-nil if point is moved to (defun python-nav-end-of-defun () "Move point to the end of def or class. Returns nil if point is not in a def or class." - (interactive nil python-mode) + (interactive) (let ((beg-defun-indent) (beg-pos (point))) (when (or (python-info-looking-at-beginning-of-defun) @@ -1577,19 +1577,19 @@ repeat it." "Navigate to closer defun backward ARG times. Unlikely `python-nav-beginning-of-defun' this doesn't care about nested definitions." - (interactive "^p" python-mode) + (interactive "^p") (python-nav--forward-defun (- (or arg 1)))) (defun python-nav-forward-defun (&optional arg) "Navigate to closer defun forward ARG times. Unlikely `python-nav-beginning-of-defun' this doesn't care about nested definitions." - (interactive "^p" python-mode) + (interactive "^p") (python-nav--forward-defun (or arg 1))) (defun python-nav-beginning-of-statement () "Move to start of current statement." - (interactive "^" python-mode) + (interactive "^") (forward-line 0) (let* ((ppss (syntax-ppss)) (context-point @@ -1613,7 +1613,7 @@ nested definitions." Optional argument NOEND is internal and makes the logic to not jump to the end of line when moving forward searching for the end of the statement." - (interactive "^" python-mode) + (interactive "^") (let (string-start bs-pos (last-string-end 0)) (while (and (or noend (goto-char (line-end-position))) (not (eobp)) @@ -1654,7 +1654,7 @@ Overlapping strings detected (start=%d, last-end=%d)") (defun python-nav-backward-statement (&optional arg) "Move backward to previous statement. With ARG, repeat. See `python-nav-forward-statement'." - (interactive "^p" python-mode) + (interactive "^p") (or arg (setq arg 1)) (python-nav-forward-statement (- arg))) @@ -1662,7 +1662,7 @@ With ARG, repeat. See `python-nav-forward-statement'." "Move forward to next statement. With ARG, repeat. With negative argument, move ARG times backward to previous statement." - (interactive "^p" python-mode) + (interactive "^p") (or arg (setq arg 1)) (while (> arg 0) (python-nav-end-of-statement) @@ -1677,7 +1677,7 @@ backward to previous statement." (defun python-nav-beginning-of-block () "Move to start of current block." - (interactive "^" python-mode) + (interactive "^") (let ((starting-pos (point))) (if (progn (python-nav-beginning-of-statement) @@ -1701,7 +1701,7 @@ backward to previous statement." (defun python-nav-end-of-block () "Move to end of current block." - (interactive "^" python-mode) + (interactive "^") (when (python-nav-beginning-of-block) (let ((block-indentation (current-indentation))) (python-nav-end-of-statement) @@ -1717,7 +1717,7 @@ backward to previous statement." (defun python-nav-backward-block (&optional arg) "Move backward to previous block of code. With ARG, repeat. See `python-nav-forward-block'." - (interactive "^p" python-mode) + (interactive "^p") (or arg (setq arg 1)) (python-nav-forward-block (- arg))) @@ -1725,7 +1725,7 @@ With ARG, repeat. See `python-nav-forward-block'." "Move forward to next block of code. With ARG, repeat. With negative argument, move ARG times backward to previous block." - (interactive "^p" python-mode) + (interactive "^p") (or arg (setq arg 1)) (let ((block-start-regexp (python-rx line-start (* whitespace) block-start)) @@ -1878,7 +1878,7 @@ throw errors when at end of sexp, skip it instead. With optional argument SKIP-PARENS-P force sexp motion to ignore parenthesized expressions when looking at them in either direction (forced to t in interactive calls)." - (interactive "^p" python-mode) + (interactive "^p") (or arg (setq arg 1)) ;; Do not follow parens on interactive calls. This hack to detect ;; if the function was called interactively copes with the way @@ -1912,7 +1912,7 @@ throw errors when at end of sexp, skip it instead. With optional argument SKIP-PARENS-P force sexp motion to ignore parenthesized expressions when looking at them in either direction (forced to t in interactive calls)." - (interactive "^p" python-mode) + (interactive "^p") (or arg (setq arg 1)) (python-nav-forward-sexp (- arg) safe skip-parens-p)) @@ -1922,7 +1922,7 @@ With ARG, do it that many times. Negative arg -N means move backward N times. With optional argument SKIP-PARENS-P force sexp motion to ignore parenthesized expressions when looking at them in either direction (forced to t in interactive calls)." - (interactive "^p" python-mode) + (interactive "^p") (python-nav-forward-sexp arg t skip-parens-p)) (defun python-nav-backward-sexp-safe (&optional arg skip-parens-p) @@ -1931,7 +1931,7 @@ With ARG, do it that many times. Negative arg -N means move forward N times. With optional argument SKIP-PARENS-P force sexp motion to ignore parenthesized expressions when looking at them in either direction (forced to t in interactive calls)." - (interactive "^p" python-mode) + (interactive "^p") (python-nav-backward-sexp arg t skip-parens-p)) (defun python-nav--up-list (&optional dir) @@ -1977,7 +1977,7 @@ DIR is always 1 or -1 and comes sanitized from With ARG, do this that many times. A negative argument means move backward but still to a less deep spot. This command assumes point is not in a string or comment." - (interactive "^p" python-mode) + (interactive "^p") (or arg (setq arg 1)) (while (> arg 0) (python-nav--up-list 1) @@ -1991,7 +1991,7 @@ This command assumes point is not in a string or comment." With ARG, do this that many times. A negative argument means move forward but still to a less deep spot. This command assumes point is not in a string or comment." - (interactive "^p" python-mode) + (interactive "^p") (or arg (setq arg 1)) (python-nav-up-list (- arg))) @@ -1999,7 +1999,7 @@ This command assumes point is not in a string or comment." "Move point at the beginning the __main__ block. When \"if __name__ == \\='__main__\\=':\" is found returns its position, else returns nil." - (interactive nil python-mode) + (interactive) (let ((point (point)) (found (catch 'found (goto-char (point-min)) commit 850f18ef23ded4aff38afee89de7980e1c9dd1fd Author: Ryan Prior Date: Thu Feb 18 12:48:28 2021 +0100 Allow newlines in password prompts again in comint * lisp/comint.el (comint-password-prompt-regexp): Match all whitespace (including newline) at the end of the passphrase, not just space and \t (bug#46609). (comint-watch-for-password-prompt): Remove trailing newlines from the prompt (bug#46609). Copyright-paperwork-exempt: yes diff --git a/lisp/comint.el b/lisp/comint.el index f5abd1a5bc..24ef0f239b 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -366,7 +366,7 @@ This variable is buffer-local." "\\(?:" (regexp-opt password-word-equivalents) "\\|Response\\)" "\\(?:\\(?:, try\\)? *again\\| (empty for no passphrase)\\| (again)\\)?" ;; "[[:alpha:]]" used to be "for", which fails to match non-English. - "\\(?: [[:alpha:]]+ .+\\)?[[:blank:]]*[::៖][[:blank:]]*\\'") + "\\(?: [[:alpha:]]+ .+\\)?[[:blank:]]*[::៖][[:space:]]*\\'") "Regexp matching prompts for passwords in the inferior process. This is used by `comint-watch-for-password-prompt'." :version "27.1" @@ -2405,6 +2405,8 @@ This function could be in the list `comint-output-filter-functions'." (string-match comint-password-prompt-regexp string)) (when (string-match "^[ \n\r\t\v\f\b\a]+" string) (setq string (replace-match "" t t string))) + (when (string-match "\n+\\'" string) + (setq string (replace-match "" t t string))) (let ((comint--prompt-recursion-depth (1+ comint--prompt-recursion-depth))) (if (> comint--prompt-recursion-depth 10) (message "Password prompt recursion too deep") commit 546f552e7b2439b482c7d28222fb88761a9c876a Author: Doug Davis Date: Thu Feb 18 12:39:00 2021 +0100 Do interactive mode tagging for python.el navigation functions. * lisp/progmodes/python.el (navigation functions): Add python-mode to `interactive' declarations for mode-specific commands (bug#46610). Copyright-paperwork-exempt: yes diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index afb96974b1..7506043a19 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1506,7 +1506,7 @@ point position. Return non-nil if point is moved to (defun python-nav-end-of-defun () "Move point to the end of def or class. Returns nil if point is not in a def or class." - (interactive) + (interactive nil python-mode) (let ((beg-defun-indent) (beg-pos (point))) (when (or (python-info-looking-at-beginning-of-defun) @@ -1577,19 +1577,19 @@ repeat it." "Navigate to closer defun backward ARG times. Unlikely `python-nav-beginning-of-defun' this doesn't care about nested definitions." - (interactive "^p") + (interactive "^p" python-mode) (python-nav--forward-defun (- (or arg 1)))) (defun python-nav-forward-defun (&optional arg) "Navigate to closer defun forward ARG times. Unlikely `python-nav-beginning-of-defun' this doesn't care about nested definitions." - (interactive "^p") + (interactive "^p" python-mode) (python-nav--forward-defun (or arg 1))) (defun python-nav-beginning-of-statement () "Move to start of current statement." - (interactive "^") + (interactive "^" python-mode) (forward-line 0) (let* ((ppss (syntax-ppss)) (context-point @@ -1613,7 +1613,7 @@ nested definitions." Optional argument NOEND is internal and makes the logic to not jump to the end of line when moving forward searching for the end of the statement." - (interactive "^") + (interactive "^" python-mode) (let (string-start bs-pos (last-string-end 0)) (while (and (or noend (goto-char (line-end-position))) (not (eobp)) @@ -1654,7 +1654,7 @@ Overlapping strings detected (start=%d, last-end=%d)") (defun python-nav-backward-statement (&optional arg) "Move backward to previous statement. With ARG, repeat. See `python-nav-forward-statement'." - (interactive "^p") + (interactive "^p" python-mode) (or arg (setq arg 1)) (python-nav-forward-statement (- arg))) @@ -1662,7 +1662,7 @@ With ARG, repeat. See `python-nav-forward-statement'." "Move forward to next statement. With ARG, repeat. With negative argument, move ARG times backward to previous statement." - (interactive "^p") + (interactive "^p" python-mode) (or arg (setq arg 1)) (while (> arg 0) (python-nav-end-of-statement) @@ -1677,7 +1677,7 @@ backward to previous statement." (defun python-nav-beginning-of-block () "Move to start of current block." - (interactive "^") + (interactive "^" python-mode) (let ((starting-pos (point))) (if (progn (python-nav-beginning-of-statement) @@ -1701,7 +1701,7 @@ backward to previous statement." (defun python-nav-end-of-block () "Move to end of current block." - (interactive "^") + (interactive "^" python-mode) (when (python-nav-beginning-of-block) (let ((block-indentation (current-indentation))) (python-nav-end-of-statement) @@ -1717,7 +1717,7 @@ backward to previous statement." (defun python-nav-backward-block (&optional arg) "Move backward to previous block of code. With ARG, repeat. See `python-nav-forward-block'." - (interactive "^p") + (interactive "^p" python-mode) (or arg (setq arg 1)) (python-nav-forward-block (- arg))) @@ -1725,7 +1725,7 @@ With ARG, repeat. See `python-nav-forward-block'." "Move forward to next block of code. With ARG, repeat. With negative argument, move ARG times backward to previous block." - (interactive "^p") + (interactive "^p" python-mode) (or arg (setq arg 1)) (let ((block-start-regexp (python-rx line-start (* whitespace) block-start)) @@ -1878,7 +1878,7 @@ throw errors when at end of sexp, skip it instead. With optional argument SKIP-PARENS-P force sexp motion to ignore parenthesized expressions when looking at them in either direction (forced to t in interactive calls)." - (interactive "^p") + (interactive "^p" python-mode) (or arg (setq arg 1)) ;; Do not follow parens on interactive calls. This hack to detect ;; if the function was called interactively copes with the way @@ -1912,7 +1912,7 @@ throw errors when at end of sexp, skip it instead. With optional argument SKIP-PARENS-P force sexp motion to ignore parenthesized expressions when looking at them in either direction (forced to t in interactive calls)." - (interactive "^p") + (interactive "^p" python-mode) (or arg (setq arg 1)) (python-nav-forward-sexp (- arg) safe skip-parens-p)) @@ -1922,7 +1922,7 @@ With ARG, do it that many times. Negative arg -N means move backward N times. With optional argument SKIP-PARENS-P force sexp motion to ignore parenthesized expressions when looking at them in either direction (forced to t in interactive calls)." - (interactive "^p") + (interactive "^p" python-mode) (python-nav-forward-sexp arg t skip-parens-p)) (defun python-nav-backward-sexp-safe (&optional arg skip-parens-p) @@ -1931,7 +1931,7 @@ With ARG, do it that many times. Negative arg -N means move forward N times. With optional argument SKIP-PARENS-P force sexp motion to ignore parenthesized expressions when looking at them in either direction (forced to t in interactive calls)." - (interactive "^p") + (interactive "^p" python-mode) (python-nav-backward-sexp arg t skip-parens-p)) (defun python-nav--up-list (&optional dir) @@ -1977,7 +1977,7 @@ DIR is always 1 or -1 and comes sanitized from With ARG, do this that many times. A negative argument means move backward but still to a less deep spot. This command assumes point is not in a string or comment." - (interactive "^p") + (interactive "^p" python-mode) (or arg (setq arg 1)) (while (> arg 0) (python-nav--up-list 1) @@ -1991,7 +1991,7 @@ This command assumes point is not in a string or comment." With ARG, do this that many times. A negative argument means move forward but still to a less deep spot. This command assumes point is not in a string or comment." - (interactive "^p") + (interactive "^p" python-mode) (or arg (setq arg 1)) (python-nav-up-list (- arg))) @@ -1999,7 +1999,7 @@ This command assumes point is not in a string or comment." "Move point at the beginning the __main__ block. When \"if __name__ == \\='__main__\\=':\" is found returns its position, else returns nil." - (interactive) + (interactive nil python-mode) (let ((point (point)) (found (catch 'found (goto-char (point-min)) commit 892db042a0d85caeea9a4969073e13f525eb9f60 Author: Mattias Engdegård Date: Thu Feb 18 11:11:11 2021 +0100 Fix rx `regexp` form with deprecated syntax The argument of the rx `regexp` form is assumed to evaluate to a valid regexp, but certain kinds of deprecated but still accepted usage were not handled correctly, such as unescaped literal (special) characters: (rx "a" (regexp "*")) => "a*" which is wrong. Handle these cases; there is no extra trouble. * lisp/emacs-lisp/rx.el (rx--translate-regexp): Force bracketing of single special characters. * test/lisp/emacs-lisp/rx-tests.el (rx-regexp): Add test case. diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index b29b870061..58584f300c 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -890,7 +890,7 @@ Return (REGEXP . PRECEDENCE)." (* (or (seq "[:" (+ (any "a-z")) ":]") (not (any "]")))) "]") - anything + (not (any "*+?^$[\\")) (seq "\\" (or anything (seq (any "sScC_") anything) diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el index 63d7c7b91e..388c5e86b4 100644 --- a/test/lisp/emacs-lisp/rx-tests.el +++ b/test/lisp/emacs-lisp/rx-tests.el @@ -391,6 +391,8 @@ (let ((x "a*")) (should (equal (rx (regexp x) "b") "\\(?:a*\\)b")) + (should (equal (rx "a" (regexp "*")) + "a\\(?:*\\)")) (should (equal (rx "" (regexp x) (eval "")) "a*")))) commit 8358637936c455d906675932db4cbf90c35b6c53 Author: Dmitry Gutov Date: Thu Feb 18 05:06:33 2021 +0200 Move 'project-try-ede' to the back of 'project-find-functions' * lisp/cedet/ede.el (project-find-functions): Move 'project-try-ede' further back, so that 'project-try-vc' has priority (bug46202). diff --git a/lisp/cedet/ede.el b/lisp/cedet/ede.el index e3cc9062ed..369a9f7e71 100644 --- a/lisp/cedet/ede.el +++ b/lisp/cedet/ede.el @@ -1518,7 +1518,7 @@ It does not apply the value to buffers." ;;; FIXME: Could someone look into implementing `project-ignores' for ;;; EDE and/or a faster `project-files'? -(add-hook 'project-find-functions #'project-try-ede) +(add-hook 'project-find-functions #'project-try-ede 50) (provide 'ede) commit 3fe2fb5794715b075fc1dd6d5d84bf10eae24c73 Author: Dmitry Gutov Date: Thu Feb 18 01:41:03 2021 +0200 Present C source files as absolute file names too when possible * lisp/progmodes/elisp-mode.el (xref-location-group): Present C source files as absolute file names too when possible (bug#46514). diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 312153052d..c14b18425f 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -904,7 +904,13 @@ non-nil result supersedes the xrefs produced by (point-marker))))))) (cl-defmethod xref-location-group ((l xref-elisp-location)) - (xref-elisp-location-file l)) + (let ((file (xref-elisp-location-file l))) + (defvar find-function-C-source-directory) + (if (and find-function-C-source-directory + (string-match-p "\\`src/" file)) + (concat find-function-C-source-directory + (substring file 3)) + file))) (defun elisp-load-path-roots () (if (boundp 'package-user-dir) commit a10574c579cf072ace1db0f80a462a737ade45cb Author: Basil L. Contovounesios Date: Wed Feb 17 23:08:24 2021 +0000 ; Fix another recent typo in simple.el. diff --git a/lisp/simple.el b/lisp/simple.el index b0a0896b68..d6ccdad902 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1924,13 +1924,13 @@ to get different commands to edit and resubmit." (defcustom read-extended-command-predicate nil "Predicate to use to determine which commands to include when completing. If it's nil, include all the commands. -If it's a functoion, it will be called with two parameters: the +If it's a function, it will be called with two parameters: the symbol of the command and a buffer. The predicate should return non-nil if the command should be present when doing `M-x TAB' in that buffer." :version "28.1" :group 'completion - :type `(choice (const :tag "Don't exclude any commands" nil) + :type '(choice (const :tag "Don't exclude any commands" nil) (const :tag "Exclude commands irrelevant to current buffer's mode" command-completion-default-include-p) (function :tag "Other function"))) commit a68a5fe03a8b11d00ca9a1de2a86caa3d97d4d35 Author: Basil L. Contovounesios Date: Wed Feb 17 22:49:15 2021 +0000 Fix recent Command Modes changes in Elisp manual * doc/lispref/commands.texi (Command Modes): Fix typos and grammar. Cross-reference the 'declare' form node. diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index e171c3e168..1ad2df9591 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -603,10 +603,11 @@ mode that has editable text, and commands that display information Many other commands, however, are specifically tied to a mode, and make no sense outside of that context. For instance, @code{M-x -dired-diff} will just signal an error used outside of a dired buffer. +dired-diff} will just signal an error if used outside of a Dired +buffer. Emacs therefore has a mechanism for specifying what mode (or modes) a -command ``belong'' to: +command ``belongs'' to: @lisp (defun dired-diff (...) @@ -634,8 +635,8 @@ commands (if they aren't bound to any keys). If using this extended @code{interactive} form isn't convenient (because the code is supposed to work in older versions of Emacs that -doesn't support the extended @code{interactive} form), the following -can be used instead: +don't support the extended @code{interactive} form), the following +equivalent declaration (@pxref{Declare Form}) can be used instead: @lisp (declare (modes dired-mode)) @@ -657,10 +658,10 @@ call @code{kill-buffer}. This command will ``work'' from any mode, but it is highly unlikely that anybody would actually want to use the command outside the context of this special mode. -Many modes have a set of different commands that start that start the -mode in different ways, (e.g., @code{eww-open-in-new-buffer} and +Many modes have a set of different commands that start the mode in +different ways (e.g., @code{eww-open-in-new-buffer} and @code{eww-open-file}). Commands like that should never be tagged as -mode-specific, as then can be issued by the user from pretty much any +mode-specific, as they can be issued by the user from pretty much any context. @node Generic Commands commit 6d0089cabcc8c960cbc24e60481a916275a6833d Author: Basil L. Contovounesios Date: Wed Feb 17 22:48:18 2021 +0000 ; Fix typo in last change to simple.el. diff --git a/lisp/simple.el b/lisp/simple.el index 363a0f26d5..b0a0896b68 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1280,7 +1280,7 @@ that uses or sets the mark." (defcustom goto-line-history-local nil "If this option is nil, `goto-line-history' is shared between all buffers. -if it is non-nil, each buffer has its own value of this history list. +If it is non-nil, each buffer has its own value of this history list. Note that on changing from non-nil to nil, the former contents of `goto-line-history' for each buffer are discarded on use of commit 79940d038f27c46507377a91fcf07fe94b80111a Author: Matt Armstrong Date: Wed Feb 17 23:33:21 2021 +0100 doc/lispref/commands.texi (Command Modes): Fix typo. * doc/lispref/commands.texi (Command Modes): Fix typo. diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 85376cc459..e171c3e168 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -597,8 +597,8 @@ Put them into three windows, selecting the last one." @subsection Specifying Modes For Commands Many commands in Emacs are general, and not tied to any specific mode. -For instance, @kbd{M-x kill-region} can be used pretty in pretty much -any mode that has editable text, and commands that display information +For instance, @kbd{M-x kill-region} can be used in pretty much any +mode that has editable text, and commands that display information (like @kbd{M-x list-buffers}) can be used in pretty much any context. Many other commands, however, are specifically tied to a mode, and commit fbc9c59b9eb02d49f426341ee32334784d224ce4 Author: Alan Mackenzie Date: Wed Feb 17 21:15:51 2021 +0000 Make goto-line-history buffer local only when so customized * lisp/simple.el (goto-line-history-local): New customizable option. (goto-line-history): Define this simply with defvar, not defvar-local. (goto-line-read-args): Handle goto-line-history-local, and changes to it. * doc/emacs/basic.texi (Moving Point): Add a paragraph about goto-line-history-local. * etc/NEWS: Add an item under "Editing Changes in Emacs 28.1". diff --git a/doc/emacs/basic.texi b/doc/emacs/basic.texi index 8bf52d5dd3..4a34fd36c5 100644 --- a/doc/emacs/basic.texi +++ b/doc/emacs/basic.texi @@ -331,6 +331,11 @@ a plain prefix argument. Alternatively, you can use the command @code{goto-line-relative} to move point to the line relative to the accessible portion of the narrowed buffer. +@code{goto-line} has its own history list (@pxref{Minibuffer +History}). You can have either a single list shared between all +buffers (the default) or a separate list for each buffer, by +customizing the user option @code{goto-line-history-local}. + @item M-g @key{TAB} @kindex M-g TAB @findex move-to-column diff --git a/etc/NEWS b/etc/NEWS index b96bcd9ecc..7665d4740f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -345,6 +345,11 @@ trying to be non-destructive. This command opens a new buffer called "*Memory Report*" and gives a summary of where Emacs is using memory currently. ++++ +** The history list for the 'goto-line' command is now a single list +for all buffers by default. You can configure a separate list for +each buffer by customizing the user option 'goto-line-history-local'. + ** Outline +++ diff --git a/lisp/simple.el b/lisp/simple.el index e54cbed7a7..363a0f26d5 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1278,7 +1278,19 @@ that uses or sets the mark." ;; Counting lines, one way or another. -(defvar-local goto-line-history nil +(defcustom goto-line-history-local nil + "If this option is nil, `goto-line-history' is shared between all buffers. +if it is non-nil, each buffer has its own value of this history list. + +Note that on changing from non-nil to nil, the former contents of +`goto-line-history' for each buffer are discarded on use of +`goto-line' in that buffer." + :group 'editing + :type 'boolean + :safe #'booleanp + :version "28.1") + +(defvar goto-line-history nil "History of values entered with `goto-line'.") (defun goto-line-read-args (&optional relative) @@ -1296,6 +1308,11 @@ that uses or sets the mark." (if buffer (concat " in " (buffer-name buffer)) ""))) + ;; Has the buffer locality of `goto-line-history' changed? + (cond ((and goto-line-history-local (not (local-variable-p 'goto-line-history))) + (make-local-variable 'goto-line-history)) + ((and (not goto-line-history-local) (local-variable-p 'goto-line-history)) + (kill-local-variable 'goto-line-history))) ;; Read the argument, offering that number (if any) as default. (list (read-number (format "Goto%s line%s: " (if (buffer-narrowed-p) commit 6735bb3d22dc64f3fe42e4a7f439ea9d62f75b5a Author: Lars Ingebrigtsen Date: Wed Feb 17 20:59:44 2021 +0100 Adjust the edebug spec for `interactive' * lisp/emacs-lisp/edebug.el: Adjust the edebug spec for `interactive' for the new syntax. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 7fae4d21d5..4599694594 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -2136,7 +2136,8 @@ SPEC is the symbol name prefix for `gensym'." ;; more convenient to define their Edebug spec here. (defun ( &define name lambda-list lambda-doc [&optional ("declare" def-declarations)] - [&optional ("interactive" &optional &or stringp def-form)] + [&optional ("interactive" &optional [&or stringp def-form] + &rest symbolp)] def-body)) (defmacro ( &define name lambda-list lambda-doc @@ -2192,7 +2193,8 @@ SPEC is the symbol name prefix for `gensym'." '(&optional [&or stringp (&define ":documentation" def-form)])) -(def-edebug-elem-spec 'interactive '(&optional &or stringp def-form)) +(def-edebug-elem-spec 'interactive '(&optional [&or stringp def-form] + &rest symbolp)) ;; A function-form is for an argument that may be a function or a form. ;; This specially recognizes anonymous functions quoted with quote. commit a5293c8dd389f7bb873dc0a5556eb74d66b0d332 Author: Lars Ingebrigtsen Date: Wed Feb 17 20:14:22 2021 +0100 Make unused `Buffer-menu-sort' alias obsolete * lisp/buff-menu.el (Buffer-menu-sort): Make unused alias obsolete. * test/lisp/progmodes/elisp-mode-tests.el (find-defs-defalias-defun-el): Adjust test to use an alias that's not obsolete. diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el index 4022615a3b..6df935fef8 100644 --- a/lisp/buff-menu.el +++ b/lisp/buff-menu.el @@ -338,7 +338,8 @@ negative ARG, display other buffers as well." "Showing all non-internal buffers.")) (revert-buffer)) -(defalias 'Buffer-menu-sort 'tabulated-list-sort) +(define-obsolete-function-alias 'Buffer-menu-sort 'tabulated-list-sort + "28.1") (defun Buffer-menu-buffer (&optional error-if-non-existent-p) diff --git a/test/lisp/progmodes/elisp-mode-tests.el b/test/lisp/progmodes/elisp-mode-tests.el index badcad670c..f47d54e59c 100644 --- a/test/lisp/progmodes/elisp-mode-tests.el +++ b/test/lisp/progmodes/elisp-mode-tests.el @@ -398,18 +398,21 @@ to (xref-elisp-test-descr-to-target xref)." "(cl-defstruct (xref-elisp-location") )) +(require 'em-xtra) +(require 'find-dired) (xref-elisp-deftest find-defs-defalias-defun-el - (elisp--xref-find-definitions 'Buffer-menu-sort) + (elisp--xref-find-definitions 'eshell/ff) (list - (xref-make "(defalias Buffer-menu-sort)" + (xref-make "(defalias eshell/ff)" (xref-make-elisp-location - 'Buffer-menu-sort 'defalias - (expand-file-name "../../../lisp/buff-menu.elc" emacs-test-dir))) - (xref-make "(defun tabulated-list-sort)" + 'eshell/ff 'defalias + (expand-file-name "../../../lisp/eshell/em-xtra.elc" + emacs-test-dir))) + (xref-make "(defun find-name-dired)" (xref-make-elisp-location - 'tabulated-list-sort nil - (expand-file-name "../../../lisp/emacs-lisp/tabulated-list.el" emacs-test-dir))) - )) + 'find-name-dired nil + (expand-file-name "../../../lisp/find-dired.el" + emacs-test-dir))))) ;; FIXME: defconst commit da78d31c6ea61581242ad54ac5ca935faf48fd7a Author: Lars Ingebrigtsen Date: Wed Feb 17 19:54:09 2021 +0100 Mark up commands in buff-menu.el for modes diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el index bb39e1f579..4022615a3b 100644 --- a/lisp/buff-menu.el +++ b/lisp/buff-menu.el @@ -268,6 +268,7 @@ In Buffer Menu mode, the following commands are defined: \\[revert-buffer] Update the list of buffers. \\[Buffer-menu-toggle-files-only] Toggle whether the menu displays only file buffers. \\[Buffer-menu-bury] Bury the buffer listed on this line." + :interactive nil (setq-local buffer-stale-function (lambda (&optional _noconfirm) 'fast)) (add-hook 'tabulated-list-revert-hook 'list-buffers--refresh nil t)) @@ -328,7 +329,7 @@ ARG, show only buffers that are visiting files." "Toggle whether the current buffer-menu displays only file buffers. With a positive ARG, display only file buffers. With zero or negative ARG, display other buffers as well." - (interactive "P") + (interactive "P" Buffer-menu-mode) (setq Buffer-menu-files-only (cond ((not arg) (not Buffer-menu-files-only)) ((> (prefix-numeric-value arg) 0) t))) @@ -373,14 +374,14 @@ is nil or omitted, and signal an error otherwise." (defun Buffer-menu-mark () "Mark the Buffer menu entry at point for later display. It will be displayed by the \\\\[Buffer-menu-select] command." - (interactive) + (interactive nil Buffer-menu-mode) (tabulated-list-set-col 0 (char-to-string Buffer-menu-marker-char) t) (forward-line)) (defun Buffer-menu-unmark (&optional backup) "Cancel all requested operations on buffer on this line and move down. Optional prefix arg means move up." - (interactive "P") + (interactive "P" Buffer-menu-mode) (Buffer-menu--unmark) (forward-line (if backup -1 1))) @@ -388,7 +389,7 @@ Optional prefix arg means move up." "Cancel a requested operation on all buffers. MARK is the character to flag the operation on the buffers. When called interactively prompt for MARK; RET remove all marks." - (interactive "cRemove marks (RET means all):") + (interactive "cRemove marks (RET means all):" Buffer-menu-mode) (save-excursion (goto-char (point-min)) (when (tabulated-list-header-overlay-p) @@ -403,12 +404,12 @@ When called interactively prompt for MARK; RET remove all marks." (defun Buffer-menu-unmark-all () "Cancel all requested operations on buffers." - (interactive) + (interactive nil Buffer-menu-mode) (Buffer-menu-unmark-all-buffers ?\r)) (defun Buffer-menu-backup-unmark () "Move up and cancel all requested operations on buffer on line above." - (interactive) + (interactive nil Buffer-menu-mode) (forward-line -1) (Buffer-menu--unmark)) @@ -427,7 +428,7 @@ will delete it. If prefix argument ARG is non-nil, it specifies the number of buffers to delete; a negative ARG means to delete backwards." - (interactive "p") + (interactive "p" Buffer-menu-mode) (if (or (null arg) (= arg 0)) (setq arg 1)) (while (> arg 0) @@ -446,14 +447,14 @@ buffers to delete; a negative ARG means to delete backwards." A subsequent \\`\\[Buffer-menu-execute]' command will delete the marked buffer. Prefix ARG means move that many lines." - (interactive "p") + (interactive "p" Buffer-menu-mode) (Buffer-menu-delete (- (or arg 1)))) (defun Buffer-menu-save () "Mark the buffer on this Buffer Menu line for saving. A subsequent \\`\\[Buffer-menu-execute]' command will save it." - (interactive) + (interactive nil Buffer-menu-mode) (when (Buffer-menu-buffer) (tabulated-list-set-col 2 "S" t) (forward-line 1))) @@ -462,7 +463,7 @@ will save it." "Mark the buffer on this line as unmodified (no changes to save). If ARG is non-nil (interactively, with a prefix argument), mark it as modified." - (interactive "P") + (interactive "P" Buffer-menu-mode) (with-current-buffer (Buffer-menu-buffer t) (set-buffer-modified-p arg)) (tabulated-list-set-col 2 (if arg "*" " ") t)) @@ -471,7 +472,7 @@ it as modified." "Save and/or delete marked buffers in the Buffer Menu. Buffers marked with \\`\\[Buffer-menu-save]' are saved. Buffers marked with \\`\\[Buffer-menu-delete]' are deleted." - (interactive) + (interactive nil Buffer-menu-mode) (save-excursion (Buffer-menu-beginning) (while (not (eobp)) @@ -502,7 +503,7 @@ You can mark buffers with the \\`\\[Buffer-menu-mark]' com This command deletes and replaces all the previously existing windows in the selected frame, and will remove any marks." - (interactive) + (interactive nil Buffer-menu-mode) (let* ((this-buffer (Buffer-menu-buffer t)) (menu-buffer (current-buffer)) (others (delq this-buffer (Buffer-menu-marked-buffers t))) @@ -533,23 +534,23 @@ If UNMARK is non-nil, unmark them." (defun Buffer-menu-isearch-buffers () "Search for a string through all marked buffers using Isearch." - (interactive) + (interactive nil Buffer-menu-mode) (multi-isearch-buffers (Buffer-menu-marked-buffers))) (defun Buffer-menu-isearch-buffers-regexp () "Search for a regexp through all marked buffers using Isearch." - (interactive) + (interactive nil Buffer-menu-mode) (multi-isearch-buffers-regexp (Buffer-menu-marked-buffers))) (defun Buffer-menu-multi-occur (regexp &optional nlines) "Show all lines in marked buffers containing a match for a regexp." - (interactive (occur-read-primary-args)) + (interactive (occur-read-primary-args) Buffer-menu-mode) (multi-occur (Buffer-menu-marked-buffers) regexp nlines)) (defun Buffer-menu-visit-tags-table () "Visit the tags table in the buffer on this line. See `visit-tags-table'." - (interactive) + (interactive nil Buffer-menu-mode) (let ((file (buffer-file-name (Buffer-menu-buffer t)))) (if file (visit-tags-table file) @@ -557,30 +558,30 @@ If UNMARK is non-nil, unmark them." (defun Buffer-menu-1-window () "Select this line's buffer, alone, in full frame." - (interactive) + (interactive nil Buffer-menu-mode) (switch-to-buffer (Buffer-menu-buffer t)) (bury-buffer (other-buffer)) (delete-other-windows)) (defun Buffer-menu-this-window () "Select this line's buffer in this window." - (interactive) + (interactive nil Buffer-menu-mode) (switch-to-buffer (Buffer-menu-buffer t))) (defun Buffer-menu-other-window () "Select this line's buffer in other window, leaving buffer menu visible." - (interactive) + (interactive nil Buffer-menu-mode) (switch-to-buffer-other-window (Buffer-menu-buffer t))) (defun Buffer-menu-switch-other-window () "Make the other window select this line's buffer. The current window remains selected." - (interactive) + (interactive nil Buffer-menu-mode) (display-buffer (Buffer-menu-buffer t) t)) (defun Buffer-menu-2-window () "Select this line's buffer, with previous buffer in second window." - (interactive) + (interactive nil Buffer-menu-mode) (let ((buff (Buffer-menu-buffer t)) (menu (current-buffer))) (delete-other-windows) @@ -591,7 +592,7 @@ The current window remains selected." (defun Buffer-menu-toggle-read-only () "Toggle read-only status of buffer on this line. This behaves like invoking \\[read-only-mode] in that buffer." - (interactive) + (interactive nil Buffer-menu-mode) (let ((read-only (with-current-buffer (Buffer-menu-buffer t) (read-only-mode 'toggle) @@ -600,7 +601,7 @@ This behaves like invoking \\[read-only-mode] in that buffer." (defun Buffer-menu-bury () "Bury the buffer listed on this line." - (interactive) + (interactive nil Buffer-menu-mode) (let ((buffer (tabulated-list-get-id))) (cond ((null buffer)) ((buffer-live-p buffer) @@ -616,12 +617,12 @@ This behaves like invoking \\[read-only-mode] in that buffer." (defun Buffer-menu-view () "View this line's buffer in View mode." - (interactive) + (interactive nil Buffer-menu-mode) (view-buffer (Buffer-menu-buffer t))) (defun Buffer-menu-view-other-window () "View this line's buffer in View mode in another window." - (interactive) + (interactive nil Buffer-menu-mode) (view-buffer-other-window (Buffer-menu-buffer t))) ;;; Functions for populating the Buffer Menu. @@ -646,7 +647,7 @@ means list those buffers and no others." (defun Buffer-menu-mouse-select (event) "Select the buffer whose line you click on." - (interactive "e") + (interactive "e" Buffer-menu-mode) (select-window (posn-window (event-end event))) (let ((buffer (tabulated-list-get-id (posn-point (event-end event))))) (when (buffer-live-p buffer) commit a37b6d2cb45cc28953ff708a07ddcc7e34c40d72 Author: Glenn Morris Date: Wed Feb 17 11:08:27 2021 -0800 ; * admin/CPP-DEFINES: Remove unused defines. diff --git a/admin/CPP-DEFINES b/admin/CPP-DEFINES index cb69b2c36c..68c12438f5 100644 --- a/admin/CPP-DEFINES +++ b/admin/CPP-DEFINES @@ -81,7 +81,6 @@ anymore, so they can be removed. AMPERSAND_FULL_NAME BROKEN_DATAGRAM_SOCKETS -BROKEN_FIONREAD BROKEN_GET_CURRENT_DIR_NAME BROKEN_PTY_READ_AFTER_EAGAIN DEFAULT_SOUND_DEVICE @@ -94,16 +93,12 @@ EMACS_CONFIG_OPTIONS EMACS_INT EMACS_UINT GC_MARK_SECONDARY_STACK -GC_MARK_STACK GC_SETJMP_WORKS GNU_MALLOC -HAVE_AIX_SMT_EXP -HAVE_ALARM HAVE_ALLOCA HAVE_ALLOCA_H HAVE_ALSA HAVE_BDFFONT -HAVE_BOXES HAVE_CFMAKERAW HAVE_CFSETSPEED HAVE_CLOCK_GETTIME @@ -117,7 +112,6 @@ HAVE_DBUS_VALIDATE_INTERFACE HAVE_DBUS_VALIDATE_MEMBER HAVE_DBUS_VALIDATE_PATH HAVE_DBUS_WATCH_GET_UNIX_FD -HAVE_DECL_GETENV HAVE_DECL_LOCALTIME_R HAVE_DECL_STRMODE HAVE_DECL_STRTOIMAX @@ -126,8 +120,6 @@ HAVE_DECL_STRTOULL HAVE_DECL_STRTOUMAX HAVE_DECL_TZNAME HAVE_DIALOGS -HAVE_DIFFTIME -HAVE_DUP2 HAVE_ENDGRENT HAVE_ENDPWENT HAVE_ENVIRON_DECL @@ -141,11 +133,9 @@ HAVE_FUTIMES HAVE_FUTIMESAT HAVE_GAI_STRERROR HAVE_GCONF -HAVE_GETDELIM HAVE_GETGRENT HAVE_GETHOSTNAME HAVE_GETIFADDRS -HAVE_GETLINE HAVE_GETLOADAVG HAVE_GETOPT_H HAVE_GETOPT_LONG_ONLY @@ -164,18 +154,8 @@ HAVE_GPM HAVE_GRANTPT HAVE_GSETTINGS HAVE_GTK3 -HAVE_GTK_ADJUSTMENT_GET_PAGE_SIZE -HAVE_GTK_DIALOG_GET_ACTION_AREA HAVE_GTK_FILE_SELECTION_NEW -HAVE_GTK_MAIN -HAVE_GTK_MULTIDISPLAY -HAVE_GTK_ORIENTABLE_SET_ORIENTATION -HAVE_GTK_WIDGET_GET_MAPPED -HAVE_GTK_WIDGET_GET_SENSITIVE -HAVE_GTK_WIDGET_GET_WINDOW -HAVE_GTK_WIDGET_SET_HAS_WINDOW HAVE_GTK_WINDOW_SET_HAS_RESIZE_GRIP -HAVE_G_TYPE_INIT HAVE_IFADDRS_H HAVE_IMAGEMAGICK HAVE_INTTYPES_H @@ -193,10 +173,8 @@ HAVE_LIBLOCKFILE HAVE_LIBMAIL HAVE_LIBOTF HAVE_LIBPERFSTAT -HAVE_LIBPNG_PNG_H HAVE_LIBSELINUX HAVE_LIBXML2 -HAVE_LIBXMU HAVE_LOCALTIME_R HAVE_LOCAL_SOCKETS HAVE_LRAND48 @@ -209,24 +187,18 @@ HAVE_MAGICKEXPORTIMAGEPIXELS HAVE_MAGICKMERGEIMAGELAYERS HAVE_MAILLOCK_H HAVE_MALLOC_MALLOC_H -HAVE_MATHERR HAVE_MBSTATE_T -HAVE_MEMCMP -HAVE_MEMMOVE HAVE_MEMORY_H HAVE_MEMSET -HAVE_MENUS HAVE_MKSTEMP HAVE_MMAP HAVE_MULTILINGUAL_MENU -HAVE_NANOTIME HAVE_NET_IF_DL_H HAVE_NET_IF_H HAVE_NLIST_H HAVE_OTF_GET_VARIATION_GLYPHS HAVE_PERSONALITY_ADDR_NO_RANDOMIZE HAVE_PNG -HAVE_PNG_H HAVE_POSIX_MEMALIGN HAVE_PROCFS HAVE_PSELECT @@ -263,15 +235,12 @@ HAVE_SOUNDCARD_H HAVE_STDINT_H HAVE_STDIO_EXT_H HAVE_STDLIB_H -HAVE_STLIB_H_1 HAVE_STRINGS_H HAVE_STRING_H -HAVE_STRNCASECMP HAVE_STRSIGNAL HAVE_STRTOIMAX HAVE_STRTOLL HAVE_STRTOULL -HAVE_STRTOUMAX HAVE_STRUCT_ERA_ENTRY HAVE_STRUCT_IFREQ_IFR_ADDR HAVE_STRUCT_IFREQ_IFR_ADDR_SA_LEN @@ -287,9 +256,7 @@ HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC -HAVE_STRUCT_TIMEZONE HAVE_STRUCT_TM_TM_ZONE -HAVE_STRUCT_UTIMBUF HAVE_ST_DM_MODE HAVE_SYMLINK HAVE_SYNC @@ -303,26 +270,20 @@ HAVE_SYS_SOCKET_H HAVE_SYS_SOUNDCARD_H HAVE_SYS_STAT_H HAVE_SYS_SYSTEMINFO_H -HAVE_SYS_TIMEB_H HAVE_SYS_TIME_H HAVE_SYS_TYPES_H HAVE_SYS_UN_H HAVE_SYS_UTSNAME_H HAVE_SYS_VLIMIT_H HAVE_SYS_WAIT_H -HAVE_TCATTR HAVE_TERM_H HAVE_TIFF -HAVE_TIMEVAL HAVE_TM_GMTOFF HAVE_TM_ZONE HAVE_TOUCHLOCK HAVE_TZNAME -HAVE_TZSET HAVE_UTIL_H HAVE_UTIMENSAT -HAVE_UTIMES -HAVE_UTIME_H HAVE_UTMP_H HAVE_VFORK HAVE_VFORK_H @@ -342,14 +303,10 @@ HAVE_XRMSETDATABASE HAVE_XSCREENNUMBEROFSCREEN HAVE_XSCREENRESOURCESTRING HAVE_X_I18N -HAVE_X_MENU HAVE_X_SM HAVE_X_WINDOWS -HAVE__BOOL -HAVE__FTIME HAVE___BUILTIN_UNWIND_INIT HAVE___EXECUTABLE_START -HAVE___FPENDING INTERNAL_TERMINAL IS_ANY_SEP IS_DIRECTORY_SEP @@ -359,7 +316,6 @@ MAIL_USE_POP MAIL_USE_SYSTEM_LOCK MAXPATHLEN NLIST_STRUCT -NO_EDITRES NSIG NSIG_MINIMUM NULL_DEVICE commit 9afdf3abe32f5c61aa755faf0c068774d70ab791 Author: Lars Ingebrigtsen Date: Wed Feb 17 19:25:08 2021 +0100 Explicate on how to tag commands with modes * doc/lispref/commands.texi (Command Modes): New node. (Using Interactive): Move the `modes' text to the new node. diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index de04d89b8e..85376cc459 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -144,6 +144,7 @@ commands by adding the @code{interactive} form to them. * Interactive Codes:: The standard letter-codes for reading arguments in various ways. * Interactive Examples:: Examples of how to read interactive arguments. +* Command Modes:: Specifying that commands are for a specific mode. * Generic Commands:: Select among command alternatives. @end menu @@ -178,21 +179,8 @@ occurs within the body, the form simply returns @code{nil} without even evaluating its argument. The @var{modes} list allows specifying which modes the command is -meant to be used in. This affects, for instance, completion in -@kbd{M-x} (commands won't be offered as completions if they don't -match (using @code{derived-mode-p}) the current major mode, or if the -mode is a minor mode, whether it's switched on in the current buffer). -This will also make @kbd{C-h m} list these commands (if they aren't -bound to any keys). - -For instance: - -@lisp -(interactive "p" dired-mode) -@end lisp - -This will mark the command as applicable for modes derived from -@code{dired-mode} only. +meant to be used in. See @ref{Command Modes} for more details about +the effect of specifying @var{modes}, and when to use it. By convention, you should put the @code{interactive} form in the function body, as the first top-level form. If there is an @@ -605,6 +593,76 @@ Put them into three windows, selecting the last one." @end group @end example +@node Command Modes +@subsection Specifying Modes For Commands + +Many commands in Emacs are general, and not tied to any specific mode. +For instance, @kbd{M-x kill-region} can be used pretty in pretty much +any mode that has editable text, and commands that display information +(like @kbd{M-x list-buffers}) can be used in pretty much any context. + +Many other commands, however, are specifically tied to a mode, and +make no sense outside of that context. For instance, @code{M-x +dired-diff} will just signal an error used outside of a dired buffer. + +Emacs therefore has a mechanism for specifying what mode (or modes) a +command ``belong'' to: + +@lisp +(defun dired-diff (...) + ... + (interactive "p" dired-mode) + ...) +@end lisp + +This will mark the command as applicable to @code{dired-mode} only (or +any modes that are derived from @code{dired-mode}). Any number of +modes can be added to the @code{interactive} form. + +@vindex read-extended-command-predicate +Specifying modes may affect completion in @kbd{M-x}, depending on the +value of @code{read-extended-command-predicate}. + +For instance, when using the +@code{command-completion-default-include-p} predicate, @kbd{M-x} won't +list commands that have been marked as being applicable to a specific +mode (unless you are in a buffer that uses that mode, of course). +This goes for both major and minor modes. + +Marking commands this way will also make @kbd{C-h m} list these +commands (if they aren't bound to any keys). + +If using this extended @code{interactive} form isn't convenient +(because the code is supposed to work in older versions of Emacs that +doesn't support the extended @code{interactive} form), the following +can be used instead: + +@lisp +(declare (modes dired-mode)) +@end lisp + +Which commands to tag with modes is to some degree a matter of taste, +but commands that clearly do not work outside of the mode should be +tagged. This includes commands that will signal an error if called +from somewhere else, but also commands that are destructive when +called from an unexpected mode. (This usually includes most of the +commands that are written for special (i.e., non-editing) modes.) + +Some commands may be harmless, and ``work'' when called from other +modes, but should still be tagged with a mode if they don't actually +make much sense to use elsewhere. For instance, many special modes +have commands to exit the buffer bound to @kbd{q}, and may not do +anything but issue a message like "Goodbye from this mode" and then +call @code{kill-buffer}. This command will ``work'' from any mode, +but it is highly unlikely that anybody would actually want to use the +command outside the context of this special mode. + +Many modes have a set of different commands that start that start the +mode in different ways, (e.g., @code{eww-open-in-new-buffer} and +@code{eww-open-file}). Commands like that should never be tagged as +mode-specific, as then can be issued by the user from pretty much any +context. + @node Generic Commands @subsection Select among Command Alternatives @cindex generic commands commit 12409c9064c386a496dcbdca76b790108f6c1cad Author: Juri Linkov Date: Wed Feb 17 20:04:42 2021 +0200 New transient mode 'repeat-mode' to allow shorter key sequences (bug#46515) * doc/emacs/basic.texi (Repeating): Document repeat-mode. * lisp/repeat.el (repeat-exit-key): New defcustom. (repeat-mode): New global minor mode. (repeat-post-hook): New function. * lisp/bindings.el (undo-repeat-map): New variable. (undo): Put 'repeat-map' property with 'undo-repeat-map'. (next-error-repeat-map): New variable. (next-error, previous-error): Put 'repeat-map' property with 'next-error-repeat-map'. * lisp/window.el (other-window-repeat-map): New variable. (other-window): Put 'repeat-map' property with 'other-window-repeat-map'. (resize-window-repeat-map): New variable. (enlarge-window, enlarge-window-horizontally) (shrink-window-horizontally, shrink-window): Put 'repeat-map' property with 'resize-window-repeat-map'. diff --git a/doc/emacs/basic.texi b/doc/emacs/basic.texi index 444b28f24b..8bf52d5dd3 100644 --- a/doc/emacs/basic.texi +++ b/doc/emacs/basic.texi @@ -880,3 +880,14 @@ characters. You can repeat that command (including its argument) three additional times, to delete a total of 80 characters, by typing @kbd{C-x z z z}. The first @kbd{C-x z} repeats the command once, and each subsequent @kbd{z} repeats it once again. + +@findex repeat-mode + Also you can activate @code{repeat-mode} that temporarily enables +a transient mode with short keys after a limited number of commands. +Currently supported shorter key sequences are @kbd{C-x u u} instead of +@kbd{C-x u C-x u} to undo many changes, @kbd{C-x o o} instead of +@kbd{C-x o C-x o} to switch several windows, @kbd{C-x @{ @{ @} @} ^ ^ +v v} to resize the selected window interactively, @kbd{M-g n n p p} to +navigate @code{next-error} matches. Any other key exits transient mode +and then is executed normally. The user option @code{repeat-exit-key} +defines an additional key to exit this transient mode. diff --git a/etc/NEWS b/etc/NEWS index 5c7acfdefa..b96bcd9ecc 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2068,6 +2068,17 @@ the behavior introduced in Octave 3.8 of using a backslash as a line continuation marker within double-quoted strings, and an ellipsis everywhere else. +** Repeat + ++++ +*** New transient mode 'repeat-mode' to allow shorter key sequences. +You can type 'C-x u u' instead of 'C-x u C-x u' to undo many changes, +'C-x o o' instead of 'C-x o C-x o' to switch several windows, +'C-x { { } } ^ ^ v v' to resize the selected window interactively, +'M-g n n p p' to navigate next-error matches. Any other key exits +transient mode and then is executed normally. 'repeat-exit-key' +defines an additional key to exit mode like 'isearch-exit' (RET). + * New Modes and Packages in Emacs 28.1 diff --git a/lisp/bindings.el b/lisp/bindings.el index 2f4bab11cf..7111ae6612 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -950,6 +950,12 @@ if `inhibit-field-text-motion' is non-nil." ;; Richard said that we should not use C-x and I have ;; no idea whereas to bind it. Any suggestion welcome. -stef ;; (define-key ctl-x-map "U" 'undo-only) +(defvar undo-repeat-map + (let ((map (make-sparse-keymap))) + (define-key map "u" 'undo) + map) + "Keymap to repeat undo key sequences `C-x u u'. Used in `repeat-mode'.") +(put 'undo 'repeat-map 'undo-repeat-map) (define-key esc-map "!" 'shell-command) (define-key esc-map "|" 'shell-command-on-region) @@ -1036,6 +1042,17 @@ if `inhibit-field-text-motion' is non-nil." (define-key ctl-x-map "`" 'next-error) +(defvar next-error-repeat-map + (let ((map (make-sparse-keymap))) + (define-key map "n" 'next-error) + (define-key map "\M-n" 'next-error) + (define-key map "p" 'previous-error) + (define-key map "\M-p" 'previous-error) + map) + "Keymap to repeat next-error key sequences. Used in `repeat-mode'.") +(put 'next-error 'repeat-map 'next-error-repeat-map) +(put 'previous-error 'repeat-map 'next-error-repeat-map) + (defvar goto-map (make-sparse-keymap) "Keymap for navigation commands.") (define-key esc-map "g" goto-map) diff --git a/lisp/repeat.el b/lisp/repeat.el index 795577c93f..84a613da0c 100644 --- a/lisp/repeat.el +++ b/lisp/repeat.el @@ -329,6 +329,77 @@ recently executed command not bound to an input event\"." ;;;;; ************************* EMACS CONTROL ************************* ;;;;; + +;; And now for something completely different. + +;;; repeat-mode + +(defcustom repeat-exit-key nil + "Key that stops the modal repeating of keys in sequence. +For example, you can set it to like `isearch-exit'." + :type '(choice (const :tag "No special key to exit repeating sequence" nil) + (key-sequence :tag "Key that exits repeating sequence")) + :group 'convenience + :version "28.1") + +;;;###autoload +(define-minor-mode repeat-mode + "Toggle Repeat mode. +When Repeat mode is enabled, and the command symbol has the property named +`repeat-map', this map is activated temporarily for the next command." + :global t :group 'convenience + (if (not repeat-mode) + (remove-hook 'post-command-hook 'repeat-post-hook) + (add-hook 'post-command-hook 'repeat-post-hook) + (let* ((keymaps nil) + (commands (all-completions + "" obarray (lambda (s) + (and (commandp s) + (get s 'repeat-map) + (push (get s 'repeat-map) keymaps)))))) + (message "Repeat mode is enabled for %d commands and %d keymaps" + (length commands) + (length (delete-dups keymaps)))))) + +(defun repeat-post-hook () + "Function run after commands to set transient keymap for repeatable keys." + (when repeat-mode + (let ((repeat-map (and (symbolp this-command) + (get this-command 'repeat-map)))) + (when repeat-map + (when (boundp repeat-map) + (setq repeat-map (symbol-value repeat-map))) + (let ((map (copy-keymap repeat-map)) + keys mess) + (map-keymap (lambda (key _) (push key keys)) map) + + ;; Exit when the last char is not among repeatable keys, + ;; so e.g. `C-x u u' repeats undo, whereas `C-/ u' doesn't. + (when (or (memq last-command-event keys) + (memq this-original-command '(universal-argument + universal-argument-more + digit-argument + negative-argument))) + ;; Messaging + (setq mess (format-message + "Repeat with %s%s" + (mapconcat (lambda (key) + (key-description (vector key))) + keys ", ") + (if repeat-exit-key + (format ", or exit with %s" + (key-description repeat-exit-key)) + ""))) + (if (current-message) + (message "%s [%s]" (current-message) mess) + (message mess)) + + ;; Adding an exit key + (when repeat-exit-key + (define-key map repeat-exit-key 'ignore)) + + (set-transient-map map))))))) + (provide 'repeat) ;;; repeat.el ends here diff --git a/lisp/window.el b/lisp/window.el index 2d0a73b426..cfd9876ed0 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -10252,6 +10252,28 @@ displaying that processes's buffer." (define-key ctl-x-4-map "1" 'same-window-prefix) (define-key ctl-x-4-map "4" 'other-window-prefix) +(defvar other-window-repeat-map + (let ((map (make-sparse-keymap))) + (define-key map "o" 'other-window) + map) + "Keymap to repeat other-window key sequences. Used in `repeat-mode'.") +(put 'other-window 'repeat-map 'other-window-repeat-map) + +(defvar resize-window-repeat-map + (let ((map (make-sparse-keymap))) + ;; Standard keys: + (define-key map "^" 'enlarge-window) + (define-key map "}" 'enlarge-window-horizontally) + (define-key map "{" 'shrink-window-horizontally) + ;; Additional keys: + (define-key map "v" 'shrink-window) + map) + "Keymap to repeat window resizing commands. Used in `repeat-mode'.") +(put 'enlarge-window 'repeat-map 'resize-window-repeat-map) +(put 'enlarge-window-horizontally 'repeat-map 'resize-window-repeat-map) +(put 'shrink-window-horizontally 'repeat-map 'resize-window-repeat-map) +(put 'shrink-window 'repeat-map 'resize-window-repeat-map) + (provide 'window) ;;; window.el ends here commit 734396aa04cd57173f1a604397244ed84f3f56a8 Author: Juri Linkov Date: Wed Feb 17 19:56:45 2021 +0200 New command 'tab-duplicate' like in web browsers diff --git a/etc/NEWS b/etc/NEWS index 3bef7399fa..5c7acfdefa 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -471,6 +471,9 @@ value of 'tab-bar-show'. It can be used to enable/disable the tab bar individually on each frame independently from the value of 'tab-bar-mode' and 'tab-bar-show'. +--- +*** New command 'tab-duplicate'. + --- *** New user option 'tab-bar-tab-name-format-function'. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index f0210e1a42..dba79fbd81 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -897,6 +897,14 @@ If ARG is zero, create a new tab in place of the current tab." (tab-bar-new-tab-to (1+ to-index))) (tab-bar-new-tab-to))) +(defun tab-bar-duplicate-tab (&optional arg) + "Duplicate the current tab to ARG positions to the right. +If a negative ARG, duplicate the tab to ARG positions to the left. +If ARG is zero, duplicate the tab in place of the current tab." + (interactive "P") + (let ((tab-bar-new-tab-choice nil)) + (tab-bar-new-tab arg))) + (defvar tab-bar-closed-tabs nil "A list of closed tabs to be able to undo their closing.") @@ -1243,6 +1251,7 @@ and can restore them." (defalias 'tab-new 'tab-bar-new-tab) (defalias 'tab-new-to 'tab-bar-new-tab-to) +(defalias 'tab-duplicate 'tab-bar-duplicate-tab) (defalias 'tab-close 'tab-bar-close-tab) (defalias 'tab-close-other 'tab-bar-close-other-tabs) (defalias 'tab-undo 'tab-bar-undo-close-tab) commit e5f50f32f76bab2607d77f0dc51cf81ec0c1e232 Author: Michael Albinus Date: Wed Feb 17 18:04:35 2021 +0100 Further Tramp code cleanup * doc/misc/tramp.texi (Predefined connection information): Mention "about-args". * lisp/net/tramp-cmds.el (tramp-version): Adapt docstring. * lisp/net/tramp.el (tramp-handle-expand-file-name): * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-expand-file-name): * lisp/net/tramp-sh.el (tramp-sh-handle-expand-file-name) * lisp/net/tramp-smb.el (tramp-smb-handle-expand-file-name): * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-expand-file-name): Handle local "/..". * lisp/net/tramp-rclone.el (tramp-methods) : Adapt `tramp-mount-args'. (tramp-rclone-flush-directory-cache): Remove. (tramp-rclone-do-copy-or-rename-file) (tramp-rclone-handle-delete-directory) (tramp-rclone-handle-delete-file) (tramp-rclone-handle-make-directory): Don't use that function. (tramp-rclone-maybe-open-connection): Fix use of `tramp-mount-args'. * lisp/net/trampver.el (tramp-inside-emacs): New defun. * lisp/net/tramp.el (tramp-handle-make-process): * lisp/net/tramp-sh.el (tramp-sh-handle-make-process) (tramp-sh-handle-process-file, tramp-open-shell): Use it. (tramp-get-env-with-u-option): Remove. * test/lisp/net/tramp-tests.el (tramp-test05-expand-file-name-top): New test. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index c2e9fe66df..6d60215734 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -2083,10 +2083,12 @@ there is no effect of this property. @item @t{"mount-args"}@* @t{"copyto-args"}@* -@t{"moveto-args"} +@t{"moveto-args"}@* +@t{"about-args"} These properties keep optional flags to the different @option{rclone} -operations. Their default value is @code{nil}. +operations. See their default values in @code{tramp-methods} if you +want to change their values. @end itemize diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el index 097f25ea85..f0bbe31cea 100644 --- a/lisp/net/tramp-cmds.el +++ b/lisp/net/tramp-cmds.el @@ -465,7 +465,7 @@ For details, see `tramp-rename-files'." ;;;###tramp-autoload (defun tramp-version (arg) - "Print version number of tramp.el in minibuffer or current buffer." + "Print version number of tramp.el in echo area or current buffer." (interactive "P") (if arg (insert tramp-version) (message tramp-version))) diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index e946d73e66..9d4e04ca68 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -1172,6 +1172,9 @@ file names." ;; There might be a double slash. Remove this. (while (string-match "//" localname) (setq localname (replace-match "/" t t localname))) + ;; Do not keep "/..". + (when (string-match-p "^/\\.\\.?$" localname) + (setq localname "/")) ;; No tilde characters in file name, do normal ;; `expand-file-name' (this does "/./" and "/../"). (tramp-make-tramp-file-name diff --git a/lisp/net/tramp-rclone.el b/lisp/net/tramp-rclone.el index 96f7d9a89b..a7f4c9be82 100644 --- a/lisp/net/tramp-rclone.el +++ b/lisp/net/tramp-rclone.el @@ -53,7 +53,12 @@ (tramp--with-startup (add-to-list 'tramp-methods `(,tramp-rclone-method - (tramp-mount-args nil) + ;; Be careful changing "--dir-cache-time", this could + ;; delay visibility of files. Since we use Tramp's + ;; internal cache for file attributes, there shouldn't + ;; be serious performance penalties when set to 0. + (tramp-mount-args + ("--no-unicode-normalization" "--dir-cache-time" "0s")) (tramp-copyto-args nil) (tramp-moveto-args nil) (tramp-about-args ("--full")))) @@ -247,24 +252,13 @@ file names." "Error %s `%s' `%s'" msg-operation filename newname))) (when (and t1 (eq op 'rename)) - (with-parsed-tramp-file-name filename v1 - (tramp-flush-file-properties v1 v1-localname) - (when (tramp-rclone-file-name-p filename) - (tramp-rclone-flush-directory-cache v1) - ;; The mount point's directory cache might need time - ;; to flush. - (while (file-exists-p filename) - (tramp-flush-file-properties v1 v1-localname))))) + (while (file-exists-p filename) + (with-parsed-tramp-file-name filename v1 + (tramp-flush-file-properties v1 v1-localname)))) (when t2 (with-parsed-tramp-file-name newname v2 - (tramp-flush-file-properties v2 v2-localname) - (when (tramp-rclone-file-name-p newname) - (tramp-rclone-flush-directory-cache v2) - ;; The mount point's directory cache might need time - ;; to flush. - (while (not (file-exists-p newname)) - (tramp-flush-file-properties v2 v2-localname)))))))))) + (tramp-flush-file-properties v2 v2-localname)))))))) (defun tramp-rclone-handle-copy-file (filename newname &optional ok-if-already-exists keep-date @@ -288,13 +282,11 @@ file names." "Like `delete-directory' for Tramp files." (with-parsed-tramp-file-name (expand-file-name directory) nil (tramp-flush-directory-properties v localname) - (tramp-rclone-flush-directory-cache v) (delete-directory (tramp-rclone-local-file-name directory) recursive trash))) (defun tramp-rclone-handle-delete-file (filename &optional trash) "Like `delete-file' for Tramp files." (with-parsed-tramp-file-name (expand-file-name filename) nil - (tramp-rclone-flush-directory-cache v) (delete-file (tramp-rclone-local-file-name filename) trash) (tramp-flush-file-properties v localname))) @@ -420,8 +412,7 @@ file names." ;; whole file cache. (tramp-flush-file-properties v localname) (tramp-flush-directory-properties - v (if parents "/" (file-name-directory localname))) - (tramp-rclone-flush-directory-cache v))) + v (if parents "/" (file-name-directory localname))))) (defun tramp-rclone-handle-rename-file (filename newname &optional ok-if-already-exists) @@ -467,39 +458,6 @@ file names." mount) (match-string 1 mount))))))) -(defun tramp-rclone-flush-directory-cache (vec) - "Flush directory cache of VEC mount." - (let ((rclone-pid - ;; Identify rclone process. - (when (tramp-get-connection-process vec) - (with-tramp-connection-property - (tramp-get-connection-process vec) "rclone-pid" - (catch 'pid - (dolist - (pid - ;; Until Emacs 25, `process-attributes' could - ;; crash Emacs for some processes. So we use - ;; "pidof", which might not work everywhere. - (if (<= emacs-major-version 25) - (let ((default-directory - (tramp-compat-temporary-file-directory))) - (mapcar - #'string-to-number - (split-string - (shell-command-to-string "pidof rclone")))) - (list-system-processes))) - (and (string-match-p - (regexp-quote - (format "rclone mount %s:" (tramp-file-name-host vec))) - (or (cdr (assoc 'args (process-attributes pid))) "")) - (throw 'pid pid)))))))) - ;; Send a SIGHUP in order to flush directory cache. - (when rclone-pid - (tramp-message - vec 6 "Send SIGHUP %d: %s" - rclone-pid (cdr (assoc 'args (process-attributes rclone-pid)))) - (signal-process rclone-pid 'SIGHUP)))) - (defun tramp-rclone-local-file-name (filename) "Return local mount name of FILENAME." (setq filename (tramp-compat-file-name-unquote (expand-file-name filename))) @@ -572,7 +530,7 @@ connection if a previous connection has died for some reason." `("mount" ,(concat host ":/") ,(tramp-rclone-mount-point vec) ;; This could be nil. - ,(tramp-get-method-parameter vec 'tramp-mount-args)))) + ,@(tramp-get-method-parameter vec 'tramp-mount-args)))) (while (not (file-exists-p (tramp-make-tramp-file-name vec 'noloc))) (tramp-cleanup-connection vec 'keep-debug 'keep-password)) @@ -607,9 +565,4 @@ The command is the list of strings ARGS." (provide 'tramp-rclone) -;;; TODO: - -;; * If possible, get rid of "rclone mount". Maybe it is more -;; performant then. - ;;; tramp-rclone.el ends here diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index bcdc014dab..5730199407 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -2818,6 +2818,9 @@ the result will be a local, non-Tramp, file name." ;; expands to "/". Remove this. (while (string-match "//" localname) (setq localname (replace-match "/" t t localname))) + ;; Do not keep "/..". + (when (string-match-p "^/\\.\\.?$" localname) + (setq localname "/")) ;; No tilde characters in file name, do normal ;; `expand-file-name' (this does "/./" and "/../"). ;; `default-directory' is bound, because on Windows there would @@ -2927,16 +2930,11 @@ alternative implementation will be used." elt (default-toplevel-value 'process-environment)) (if (string-match-p "=" elt) (setq env (append env `(,elt))) - (if (tramp-get-env-with-u-option v) - (setq env (append `("-u" ,elt) env)) - (setq uenv (cons elt uenv))))))) + (setq uenv (cons elt uenv)))))) + (env (setenv-internal + env "INSIDE_EMACS" (tramp-inside-emacs) 'keep)) (command (when (stringp program) - (setenv-internal - env "INSIDE_EMACS" - (concat (or (getenv "INSIDE_EMACS") emacs-version) - ",tramp:" tramp-version) - 'keep) (format "cd %s && %s exec %s %s env %s %s" (tramp-shell-quote-argument localname) (if uenv @@ -3147,14 +3145,8 @@ alternative implementation will be used." (or (member elt (default-toplevel-value 'process-environment)) (if (string-match-p "=" elt) (setq env (append env `(,elt))) - (if (tramp-get-env-with-u-option v) - (setq env (append `("-u" ,elt) env)) - (setq uenv (cons elt uenv)))))) - (setenv-internal - env "INSIDE_EMACS" - (concat (or (getenv "INSIDE_EMACS") emacs-version) - ",tramp:" tramp-version) - 'keep) + (setq uenv (cons elt uenv))))) + (setenv-internal env "INSIDE_EMACS" (tramp-inside-emacs) 'keep) (when env (setq command (format @@ -4307,10 +4299,9 @@ file exists and nonzero exit status otherwise." (tramp-send-command vec (format (concat - "exec env TERM='%s' INSIDE_EMACS='%s,tramp:%s' " + "exec env TERM='%s' INSIDE_EMACS='%s' " "ENV=%s %s PROMPT_COMMAND='' PS1=%s PS2='' PS3='' %s %s -i") - tramp-terminal-type - (or (getenv "INSIDE_EMACS") emacs-version) tramp-version + tramp-terminal-type (tramp-inside-emacs) (or (getenv-internal "ENV" tramp-remote-process-environment) "") (if (stringp tramp-histfile-override) (format "HISTFILE=%s" @@ -5945,16 +5936,6 @@ This command is returned only if `delete-by-moving-to-trash' is non-nil." (tramp-file-local-name tmpfile) (tramp-file-local-name tmpfile))) (delete-file tmpfile))))) -(defun tramp-get-env-with-u-option (vec) - "Check, whether the remote `env' command supports the -u option." - (with-tramp-connection-property vec "env-u-option" - (tramp-message vec 5 "Checking, whether `env -u' works") - ;; Option "-u" is a GNU extension. - (tramp-send-command-and-check - vec (format "env FOO=foo env -u FOO 2>%s | grep -qv FOO" - (tramp-get-remote-null-device vec)) - t))) - ;; Some predefined connection properties. (defun tramp-get-inline-compress (vec prop size) "Return the compress command related to PROP. diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 26ec910ecc..4519c34d36 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -743,6 +743,9 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." ;; Make the file name absolute. (unless (tramp-run-real-handler #'file-name-absolute-p (list localname)) (setq localname (concat "/" localname))) + ;; Do not keep "/..". + (when (string-match-p "^/\\.\\.?$" localname) + (setq localname "/")) ;; No tilde characters in file name, do normal ;; `expand-file-name' (this does "/./" and "/../"). (tramp-make-tramp-file-name diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el index 0a60b79182..e181365162 100644 --- a/lisp/net/tramp-sudoedit.el +++ b/lisp/net/tramp-sudoedit.el @@ -364,6 +364,9 @@ the result will be a local, non-Tramp, file name." (when (string-equal uname "~") (setq uname (concat uname user))) (setq localname (concat uname fname)))) + ;; Do not keep "/..". + (when (string-match-p "^/\\.\\.?$" localname) + (setq localname "/")) ;; Do normal `expand-file-name' (this does "~user/", "/./" and "/../"). (tramp-make-tramp-file-name v (expand-file-name localname)))) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index e33075ec6f..e99e43938f 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -3163,6 +3163,9 @@ User is always nil." (with-parsed-tramp-file-name name nil (unless (tramp-run-real-handler #'file-name-absolute-p (list localname)) (setq localname (concat "/" localname))) + ;; Do not keep "/..". + (when (string-match-p "^/\\.\\.?$" localname) + (setq localname "/")) ;; Do normal `expand-file-name' (this does "/./" and "/../"). ;; `default-directory' is bound, because on Windows there would ;; be problems with UNC shares or Cygwin mounts. @@ -3811,10 +3814,7 @@ It does not support `:stderr'." elt (default-toplevel-value 'process-environment)))) (setq env (cons elt env))))) (env (setenv-internal - env "INSIDE_EMACS" - (concat (or (getenv "INSIDE_EMACS") emacs-version) - ",tramp:" tramp-version) - 'keep)) + env "INSIDE_EMACS" (tramp-inside-emacs) 'keep)) (env (mapcar #'tramp-shell-quote-argument (delq nil env))) ;; Quote command. (command (mapconcat #'tramp-shell-quote-argument command " ")) diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el index ced3e93fc0..abd92219b2 100644 --- a/lisp/net/trampver.el +++ b/lisp/net/trampver.el @@ -80,6 +80,11 @@ (replace-regexp-in-string "\n" "" (emacs-version)))))) (unless (string-equal "ok" x) (error "%s" x))) +(defun tramp-inside-emacs () + "Version string provided by INSIDE_EMACS enmvironment variable." + (concat (or (getenv "INSIDE_EMACS") emacs-version) + ",tramp:" tramp-version)) + ;; Tramp versions integrated into Emacs. If a user option declares a ;; `:package-version' which doesn't belong to an integrated Tramp ;; version, it must be added here as well (see `tramp-syntax', for diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index f4883923f6..9a83fa6676 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -2182,6 +2182,16 @@ is greater than 10. (expand-file-name ".." "./")) (concat (file-remote-p tramp-test-temporary-file-directory) "/")))) +(ert-deftest tramp-test05-expand-file-name-top () + "Check `expand-file-name'." + (skip-unless (tramp--test-enabled)) + (skip-unless (not (tramp--test-ange-ftp-p))) + + (let ((dir (concat (file-remote-p tramp-test-temporary-file-directory) "/"))) + (dolist (local '("." "..")) + (should (string-equal (expand-file-name local dir) dir)) + (should (string-equal (expand-file-name (concat dir local)) dir))))) + (ert-deftest tramp-test06-directory-file-name () "Check `directory-file-name'. This checks also `file-name-as-directory', `file-name-directory', @@ -6730,8 +6740,8 @@ Since it unloads Tramp, it shall be the last test to run." If INTERACTIVE is non-nil, the tests are run interactively." (interactive "p") (funcall - (if interactive - #'ert-run-tests-interactively #'ert-run-tests-batch) "^tramp")) + (if interactive #'ert-run-tests-interactively #'ert-run-tests-batch) + "^tramp")) ;; TODO: commit 199294206a3afb32674b93a2e2fab03d0f92c900 Author: Eli Zaretskii Date: Wed Feb 17 18:59:01 2021 +0200 ; Fix last m-x.texi change. diff --git a/doc/emacs/m-x.texi b/doc/emacs/m-x.texi index b8770982c5..c51f10a47a 100644 --- a/doc/emacs/m-x.texi +++ b/doc/emacs/m-x.texi @@ -55,7 +55,7 @@ Emacs release.) relevant to, and generally cannot work with, the current buffer's major mode (@pxref{Major Modes}) and minor modes (@pxref{Minor Modes}). By default, no commands are excluded, but you can customize -the option @var{read-extended-command-predicate} to exclude those +the option @code{read-extended-command-predicate} to exclude those irrelevant commands from completion results. To cancel the @kbd{M-x} and not run a command, type @kbd{C-g} instead commit 0c30b939e7463d3d6d4021952e066ac6970e5081 Author: Eli Zaretskii Date: Wed Feb 17 18:57:42 2021 +0200 ; Fix last change in commands.texi. diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index cd30fb19ee..de04d89b8e 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -775,6 +775,7 @@ part of the prompt. @end example @vindex read-extended-command-predicate +@findex command-completion-default-include-p This command heeds the @code{read-extended-command-predicate} variable, which can filter out commands that are not applicable to the current major mode (or enabled minor modes). By default, the value of commit 927b88571cebb4f64aca360fbfa5d15a1f922ad6 Author: Eli Zaretskii Date: Wed Feb 17 18:53:54 2021 +0200 Disable filtering of commands in M-x completion This makes the default behavior like it was before: M-x completion doesn't filter out any commands. To have commands filtered based on their relevance to the current buffer's modes, customize the option 'read-extended-command-predicate' to call 'command-completion-default-include-p'. * doc/lispref/commands.texi (Interactive Call): * doc/emacs/m-x.texi (M-x): Update the description of 'read-extended-command-predicate' and improve wording. * etc/NEWS: Update the entry about 'read-extended-command-predicate'. * lisp/simple.el (read-extended-command-predicate): Change default value to nil. Update doc string. Add :group. (read-extended-command): Handle nil as meaning to apply no-filtering. diff --git a/doc/emacs/m-x.texi b/doc/emacs/m-x.texi index 689125e7b4..b8770982c5 100644 --- a/doc/emacs/m-x.texi +++ b/doc/emacs/m-x.texi @@ -46,9 +46,17 @@ from running the command by name. @cindex obsolete command When @kbd{M-x} completes on commands, it ignores the commands that are declared @dfn{obsolete}; for these, you will have to type their -full name. Obsolete commands are those for which newer, better +full name. (Obsolete commands are those for which newer, better alternatives exist, and which are slated for removal in some future -Emacs release. +Emacs release.) + +@vindex read-extended-command-predicate + In addition, @kbd{M-x} completion can exclude commands that are not +relevant to, and generally cannot work with, the current buffer's +major mode (@pxref{Major Modes}) and minor modes (@pxref{Minor +Modes}). By default, no commands are excluded, but you can customize +the option @var{read-extended-command-predicate} to exclude those +irrelevant commands from completion results. To cancel the @kbd{M-x} and not run a command, type @kbd{C-g} instead of entering the command name. This takes you back to command level. @@ -94,8 +102,3 @@ the command is followed by arguments. @kbd{M-x} works by running the command @code{execute-extended-command}, which is responsible for reading the name of another command and invoking it. - -@vindex read-extended-command-predicate - This command heeds the @code{read-extended-command-predicate} -variable, which will (by default) filter out commands that are not -applicable to the current major mode (or enabled minor modes). diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index b3bcdf35c9..cd30fb19ee 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -776,12 +776,16 @@ part of the prompt. @vindex read-extended-command-predicate This command heeds the @code{read-extended-command-predicate} -variable, which will (by default) filter out commands that are not -applicable to the current major mode (or enabled minor modes). -@code{read-extended-command-predicate} will be called with two -parameters: The symbol that is to be included or not, and the current -buffer. If should return non-@code{nil} if the command is to be -included when completing. +variable, which can filter out commands that are not applicable to the +current major mode (or enabled minor modes). By default, the value of +this variable is @code{nil}, and no commands are filtered out. +However, customizing it to invoke the function +@code{command-completion-default-include-p} will perform +mode-dependent filtering. @code{read-extended-command-predicate} can +be any predicate function; it will be called with two parameters: the +command's symbol and the current buffer. If should return +non-@code{nil} if the command is to be included when completing in +that buffer. @end deffn @node Distinguish Interactive diff --git a/etc/NEWS b/etc/NEWS index b38865dd27..3bef7399fa 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -253,9 +253,11 @@ commands. The new keystrokes are 'C-x x g' ('revert-buffer'), +++ ** New user option 'read-extended-command-predicate'. -This option controls how 'M-x TAB' performs completions. The default -predicate excludes commands that are not applicable to the current -major and minor modes, and also respects the command's completion +This option controls how 'M-x' performs completion of commands when +you type TAB. By default, any command that matches what you have +typed is considered a completion candidate, but you can customize this +option to exclude commands that are not applicable to the current +buffer's major and minor modes, and respect the command's completion predicate (if any). --- diff --git a/lisp/simple.el b/lisp/simple.el index 248d044b19..e54cbed7a7 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1904,17 +1904,18 @@ to get different commands to edit and resubmit." (defvar extended-command-history nil) (defvar execute-extended-command--last-typed nil) -(defcustom read-extended-command-predicate - #'command-completion-default-include-p +(defcustom read-extended-command-predicate nil "Predicate to use to determine which commands to include when completing. -The predicate function is called with two parameters: The -symbol (i.e., command) in question that should be included or -not, and the current buffer. The predicate should return non-nil -if the command should be present when doing `M-x TAB'." +If it's nil, include all the commands. +If it's a functoion, it will be called with two parameters: the +symbol of the command and a buffer. The predicate should return +non-nil if the command should be present when doing `M-x TAB' +in that buffer." :version "28.1" - :type `(choice (const :tag "Exclude commands not relevant to the current mode" + :group 'completion + :type `(choice (const :tag "Don't exclude any commands" nil) + (const :tag "Exclude commands irrelevant to current buffer's mode" command-completion-default-include-p) - (const :tag "All commands" ,(lambda (_s _b) t)) (function :tag "Other function"))) (defun read-extended-command () @@ -1971,7 +1972,9 @@ This function uses the `read-extended-command-predicate' user option." (complete-with-action action obarray string pred))) (lambda (sym) (and (commandp sym) - (funcall read-extended-command-predicate sym buffer))) + (or (null read-extended-command-predicate) + (and (functionp read-extended-command-predicate) + (funcall read-extended-command-predicate sym buffer))))) t nil 'extended-command-history)))) (defun command-completion-default-include-p (symbol buffer) commit 0324ec17375028bd1b26a6d695535450d5a5a9c5 Author: Lars Ingebrigtsen Date: Wed Feb 17 17:12:27 2021 +0100 Fix recently introduced bug in `byte-compile-lambda' * lisp/emacs-lisp/bytecomp.el (byte-compile-lambda): Fix recently introduced error when compiling non-lexical commands (bug#46589). diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 5c6b9c2e39..9d80afd774 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2951,7 +2951,9 @@ for symbols generated by the byte compiler itself." ;; Skip (interactive) if it is in front (the most usual location). (if (eq int (car body)) (setq body (cdr body))) - (cond ((consp (cdr int)) + (cond ((consp (cdr int)) ; There is an `interactive' spec. + ;; Check that the bit after the `interactive' spec is + ;; just a list of symbols (i.e., modes). (unless (seq-every-p #'symbolp (cdr (cdr int))) (byte-compile-warn "malformed interactive specc: %s" (prin1-to-string int))) @@ -2966,16 +2968,14 @@ for symbols generated by the byte compiler itself." (while (consp (cdr form)) (setq form (cdr form))) (setq form (car form))) - (setq int - (if (and (eq (car-safe form) 'list) - ;; For code using lexical-binding, form is not - ;; valid lisp, but rather an intermediate form - ;; which may include "calls" to - ;; internal-make-closure (Bug#29988). - (not lexical-binding)) - `(interactive ,form) - `(interactive ,newform))))) - ((cdr int) + (when (or (not (eq (car-safe form) 'list)) + ;; For code using lexical-binding, form is not + ;; valid lisp, but rather an intermediate form + ;; which may include "calls" to + ;; internal-make-closure (Bug#29988). + lexical-binding) + (setq int `(interactive ,newform))))) + ((cdr int) ; Invalid (interactive . something). (byte-compile-warn "malformed interactive spec: %s" (prin1-to-string int))))) ;; Process the body. commit cccd701ac952f81da8444576a72d92b37ddf42d2 Author: Basil L. Contovounesios Date: Wed Feb 17 13:27:56 2021 +0000 ; Finish recent rename of completion-* predicates. diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 739b56b88c..0e89999b75 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -434,7 +434,7 @@ Value is a pair of positions (START . END) if there is a non-nil (defun shr-show-alt-text () "Show the ALT text of the image under point." - (declare (completion (lambda (_ b) (completion-button-p 'shr b)))) + (declare (completion (lambda (_ b) (command-completion-button-p 'shr b)))) (interactive) (let ((text (get-text-property (point) 'shr-alt))) (if (not text) commit 06f8407ee67b7b19302ff94e3d142c581ba1e25f Author: Lars Ingebrigtsen Date: Wed Feb 17 12:15:07 2021 +0100 Clarify 'read-extended-command-predicate' in NEWS diff --git a/etc/NEWS b/etc/NEWS index 943ad6ac59..b38865dd27 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -254,7 +254,9 @@ commands. The new keystrokes are 'C-x x g' ('revert-buffer'), +++ ** New user option 'read-extended-command-predicate'. This option controls how 'M-x TAB' performs completions. The default -predicate excludes modes for which the command is not applicable. +predicate excludes commands that are not applicable to the current +major and minor modes, and also respects the command's completion +predicate (if any). --- ** 'eval-expression' now no longer signals an error on incomplete expressions. commit b3e34643c41399239f4846c28221b678804e370b Author: Lars Ingebrigtsen Date: Wed Feb 17 12:01:27 2021 +0100 Change name for the completion-* predicates * lisp/simple.el (command-completion-default-include-p) (command-completion-with-modes-p, command-completion-button-p): Rename from completion-*. (read-extended-command-predicate): Adjust default predicate. * lisp/emacs-lisp/byte-run.el (byte-run--set-modes): Adjust predicate name. diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index 8a22388f1d..76e7f01ace 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el @@ -154,8 +154,9 @@ The return value of this function is not used." (defalias 'byte-run--set-modes #'(lambda (f _args &rest val) (list 'function-put (list 'quote f) - ''completion-predicate `(lambda (_ b) - (completion-with-modes-p ',val b))))) + ''completion-predicate + `(lambda (_ b) + (command-completion-with-modes-p ',val b))))) ;; Add any new entries to info node `(elisp)Declare Form'. (defvar defun-declarations-alist diff --git a/lisp/simple.el b/lisp/simple.el index 215f4399f4..248d044b19 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1904,7 +1904,8 @@ to get different commands to edit and resubmit." (defvar extended-command-history nil) (defvar execute-extended-command--last-typed nil) -(defcustom read-extended-command-predicate #'completion-default-include-p +(defcustom read-extended-command-predicate + #'command-completion-default-include-p "Predicate to use to determine which commands to include when completing. The predicate function is called with two parameters: The symbol (i.e., command) in question that should be included or @@ -1912,7 +1913,7 @@ not, and the current buffer. The predicate should return non-nil if the command should be present when doing `M-x TAB'." :version "28.1" :type `(choice (const :tag "Exclude commands not relevant to the current mode" - completion-default-include-p) + command-completion-default-include-p) (const :tag "All commands" ,(lambda (_s _b) t)) (function :tag "Other function"))) @@ -1973,7 +1974,7 @@ This function uses the `read-extended-command-predicate' user option." (funcall read-extended-command-predicate sym buffer))) t nil 'extended-command-history)))) -(defun completion-default-include-p (symbol buffer) +(defun command-completion-default-include-p (symbol buffer) "Say whether SYMBOL should be offered as a completion. If there's a `completion-predicate' for SYMBOL, the result from calling that predicate is called. If there isn't one, this @@ -2002,7 +2003,7 @@ BUFFER." #'eq) (seq-intersection modes global-minor-modes #'eq)))))) -(defun completion-with-modes-p (modes buffer) +(defun command-completion-with-modes-p (modes buffer) "Say whether MODES are in action in BUFFER. This is the case if either the major mode is derived from one of MODES, or (if one of MODES is a minor mode), if it is switched on in BUFFER." @@ -2015,7 +2016,7 @@ or (if one of MODES is a minor mode), if it is switched on in BUFFER." #'eq) (seq-intersection modes global-minor-modes #'eq))) -(defun completion-button-p (category buffer) +(defun command-completion-button-p (category buffer) "Return non-nil if there's a button of CATEGORY at point in BUFFER." (with-current-buffer buffer (and (get-text-property (point) 'button) commit 26fcd8289057805f506a24c6ae7277c653463208 Author: Glenn Morris Date: Tue Feb 16 21:25:18 2021 -0800 * configure.ac: Replace obsolete AC_CHECK_HEADER usage. (Bug#46578) diff --git a/configure.ac b/configure.ac index 9a294bc796..11a06a39be 100644 --- a/configure.ac +++ b/configure.ac @@ -1767,7 +1767,8 @@ fi dnl On Solaris 8 there's a compilation warning for term.h because dnl it doesn't define 'bool'. -AC_CHECK_HEADERS(term.h, , , -) +AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[#include ]],[[]])], + AC_DEFINE(HAVE_TERM_H, 1, [Define to 1 if you have the header file.])) AC_HEADER_SYS_WAIT AC_CHECK_HEADERS_ONCE(sys/socket.h) commit 5f078928bbe85c11d5240d178b3801cd2e23198e Author: Glenn Morris Date: Tue Feb 16 20:54:46 2021 -0800 * configure.ac: Replace obsolete AC_TRY_LINK with AC_LINK_IFELSE. diff --git a/configure.ac b/configure.ac index 5fd0e76b82..9a294bc796 100644 --- a/configure.ac +++ b/configure.ac @@ -4715,10 +4715,10 @@ if test "$USE_X_TOOLKIT" != "none"; then else OTHERLIBS="-lXt -$LIBXMU" fi - AC_TRY_LINK( - [#include - #include ], - [_XEditResCheckMessages (0, 0, 0, 0);], + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[#include + #include ]], + [[_XEditResCheckMessages (0, 0, 0, 0);]])], [AC_DEFINE([X_TOOLKIT_EDITRES], 1, [Define to 1 if we should use XEditRes.])]) LIBS=$OLDLIBS commit 45e964755bafec934b34f5c7c65e861fbe4c8aa6 Author: Glenn Morris Date: Tue Feb 16 20:34:26 2021 -0800 Remove TIME_WITH_SYS_TIME, unused for a long time * configure.ac (AC_HEADER_TIME): Remove. (Bug#46578) diff --git a/admin/CPP-DEFINES b/admin/CPP-DEFINES index a40b430272..cb69b2c36c 100644 --- a/admin/CPP-DEFINES +++ b/admin/CPP-DEFINES @@ -378,7 +378,6 @@ SYSTEM_MALLOC TAB3 TABDLY TERM -TIME_WITH_SYS_TIME TIOCSIGSEND TM_IN_SYS_TIME UNIX98_PTYS diff --git a/configure.ac b/configure.ac index 12cf36303b..5fd0e76b82 100644 --- a/configure.ac +++ b/configure.ac @@ -1768,7 +1768,6 @@ fi dnl On Solaris 8 there's a compilation warning for term.h because dnl it doesn't define 'bool'. AC_CHECK_HEADERS(term.h, , , -) -AC_HEADER_TIME AC_HEADER_SYS_WAIT AC_CHECK_HEADERS_ONCE(sys/socket.h) commit 7b2448ae6eaf4ae5f81f1a1b1b9f1b14735e90d6 Author: Harald Jörg Date: Wed Feb 17 00:54:38 2021 +0100 cperl-mode: Improve detection of index entries for imenu * lisp/progmodes/cperl-mode.el (cperl-imenu-addback): Customization variable deleted. This variable has been declared obsolete in 1998. (cperl--basic-identifier-regexp) and many other variables: defining regular expressions for basic Perl constructs. (cperl-imenu--create-perl-index): This function has been completely rewritten, keeping only some parts of the output formatting. It now recognizes a lot more package and subroutine declarations which came since Perl 5.14: Packages with a version and/or a block attached, lexical subroutines, declarations with a newline between the keyword "package" and the package name, and several more. This version also correctly separates subroutine names from attributes, does no longer support "unnamed" packages (which don't exist in Perl), and doesn't fall for false positives like stuff that looks like a declaration in a multiline string. (cperl-tags-hier-init): Eliminate call to `cperl-imenu-addback` (which actually was commented out in 1997) * test/lisp/progmodes/cperl-mode-tests.el (cperl-test--validate-regexp) and six other new tests for the new regular expressions and the index creation. * test/lisp/progmodes/cperl-mode-resources/grammar.pl: New file showcasing different syntax variations for package and sub declarations (bug#46574). diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index 0dffe279c3..44a7526952 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -440,12 +440,6 @@ after reload." :type 'boolean :group 'cperl-speed) -(defcustom cperl-imenu-addback nil - "Not-nil means add backreferences to generated `imenu's. -May require patched `imenu' and `imenu-go'. Obsolete." - :type 'boolean - :group 'cperl-help-system) - (defcustom cperl-max-help-size 66 "Non-nil means shrink-wrapping of info-buffer allowed up to these percents." :type '(choice integer (const nil)) @@ -1216,6 +1210,153 @@ versions of Emacs." The expansion is entirely correct because it uses the C preprocessor." t) + +;;; Perl Grammar Components +;; +;; The following regular expressions are building blocks for a +;; minimalistic Perl grammar, to be used instead of individual (and +;; not always consistent) literal regular expressions. + +(defconst cperl--basic-identifier-regexp + (rx (sequence (or alpha "_") (* (or word "_")))) + "A regular expression for the name of a \"basic\" Perl variable. +Neither namespace separators nor sigils are included. As is, +this regular expression applies to labels,subroutine calls where +the ampersand sigil is not required, and names of subroutine +attributes.") + +(defconst cperl--label-regexp + (rx-to-string + `(sequence + symbol-start + (regexp ,cperl--basic-identifier-regexp) + (0+ space) + ":")) + "A regular expression for a Perl label. +By convention, labels are uppercase alphabetics, but this isn't +enforced.") + +(defconst cperl--normal-identifier-regexp + (rx-to-string + `(or + (sequence + (1+ (sequence + (opt (regexp ,cperl--basic-identifier-regexp)) + "::")) + (opt (regexp ,cperl--basic-identifier-regexp))) + (regexp ,cperl--basic-identifier-regexp))) + "A regular expression for a Perl variable name with optional namespace. +Examples are `foo`, `Some::Module::VERSION`, and `::` (yes, that +is a legal variable name).") + +(defconst cperl--special-identifier-regexp + (rx-to-string + `(or + (1+ digit) ; $0, $1, $2, ... + (sequence "^" (any "A-Z" "]^_?\\")) ; $^V + (sequence "{" (0+ space) ; ${^MATCH} + "^" (any "A-Z" "]^_?\\") + (0+ (any "A-Z" "_" digit)) + (0+ space) "}") + (in "!\"$%&'()+,-./:;<=>?@\\]^_`|~"))) ; $., $|, $", ... but not $^ or ${ + "The list of Perl \"punctuation\" variables, as listed in perlvar.") + +(defconst cperl--ws-regexp + (rx-to-string + '(or space "\n")) + "Regular expression for a single whitespace in Perl.") + +(defconst cperl--eol-comment-regexp + (rx-to-string + '(sequence "#" (0+ (not (in "\n"))) "\n")) + "Regular expression for a single end-of-line comment in Perl") + +(defconst cperl--ws-or-comment-regexp + (rx-to-string + `(1+ + (or + (regexp ,cperl--ws-regexp) + (regexp ,cperl--eol-comment-regexp)))) + "Regular expression for a sequence of whitespace and comments in Perl.") + +(defconst cperl--ows-regexp + (rx-to-string + `(opt (regexp ,cperl--ws-or-comment-regexp))) + "Regular expression for optional whitespaces or comments in Perl") + +(defconst cperl--version-regexp + (rx-to-string + `(or + (sequence (opt "v") + (>= 2 (sequence (1+ digit) ".")) + (1+ digit) + (opt (sequence "_" (1+ word)))) + (sequence (1+ digit) + (opt (sequence "." (1+ digit))) + (opt (sequence "_" (1+ word)))))) + "A sequence for recommended version number schemes in Perl.") + +(defconst cperl--package-regexp + (rx-to-string + `(sequence + "package" ; FIXME: the "class" and "role" keywords need to be + ; recognized soon...ish. + (regexp ,cperl--ws-or-comment-regexp) + (group (regexp ,cperl--normal-identifier-regexp)) + (opt + (sequence + (1+ (regexp ,cperl--ws-or-comment-regexp)) + (group (regexp ,cperl--version-regexp)))))) + "A regular expression for package NAME VERSION in Perl. +Contains two groups for the package name and version.") + +(defconst cperl--package-for-imenu-regexp + (rx-to-string + `(sequence + (regexp ,cperl--package-regexp) + (regexp ,cperl--ows-regexp) + (group (or ";" "{")))) + "A regular expression to collect package names for `imenu`. +Catches \"package NAME;\", \"package NAME VERSION;\", \"package +NAME BLOCK\" and \"package NAME VERSION BLOCK.\" Contains three +groups: Two from `cperl--package-regexp` for the package name and +version, and a third to detect \"package BLOCK\" syntax.") + +(defconst cperl--sub-name-regexp + (rx-to-string + `(sequence + (optional (sequence (group (or "my" "state" "our")) + (regexp ,cperl--ws-or-comment-regexp))) + "sub" ; FIXME: the "method" and maybe "fun" keywords need to be + ; recognized soon...ish. + (regexp ,cperl--ws-or-comment-regexp) + (group (regexp ,cperl--normal-identifier-regexp)))) + "A regular expression to detect a subroutine start. +Contains two groups: One for to distinguish lexical from +\"normal\" subroutines and one for the subroutine name.") + +(defconst cperl--pod-heading-regexp + (rx-to-string + `(sequence + line-start "=head" + (group (in "1-4")) + (1+ (in " \t")) + (group (1+ (not (in "\n")))) + line-end)) ; that line-end seems to be redundant? + "A regular expression to detect a POD heading. +Contains two groups: One for the heading level, and one for the +heading text.") + +(defconst cperl--imenu-entries-regexp + (rx-to-string + `(or + (regexp ,cperl--package-for-imenu-regexp) ; 1..3 + (regexp ,cperl--sub-name-regexp) ; 4..5 + (regexp ,cperl--pod-heading-regexp))) ; 6..7 + "A regular expression to collect stuff that goes into the `imenu` index. +Covers packages, subroutines, and POD headings.") + + ;; These two must be unwound, otherwise take exponential time (defconst cperl-maybe-white-and-comment-rex "[ \t\n]*\\(#[^\n]*\n[ \t\n]*\\)*" "Regular expression to match optional whitespace with interspersed comments. @@ -1227,8 +1368,7 @@ Should contain exactly one group.") Should contain exactly one group.") -;; Is incorporated in `cperl-imenu--function-name-regexp-perl' -;; `cperl-outline-regexp', `defun-prompt-regexp'. +;; Is incorporated in `cperl-outline-regexp', `defun-prompt-regexp'. ;; Details of groups in this may be used in several functions; see comments ;; near mentioned above variable(s)... ;; sub($$):lvalue{} sub:lvalue{} Both allowed... @@ -5147,117 +5287,80 @@ indentation and initial hashes. Behaves usually outside of comment." ;; Previous space could have gone: (or (memq (preceding-char) '(?\s ?\t)) (insert " ")))))) -(defun cperl-imenu-addback (lst &optional isback name) - ;; We suppose that the lst is a DAG, unless the first element only - ;; loops back, and ISBACK is set. Thus this function cannot be - ;; applied twice without ISBACK set. - (cond ((not cperl-imenu-addback) lst) - (t - (or name - (setq name "+++BACK+++")) - (mapc (lambda (elt) - (if (and (listp elt) (listp (cdr elt))) - (progn - ;; In the other order it goes up - ;; one level only ;-( - (setcdr elt (cons (cons name lst) - (cdr elt))) - (cperl-imenu-addback (cdr elt) t name)))) - (if isback (cdr lst) lst)) - lst))) - -(defun cperl-imenu--create-perl-index (&optional regexp) - (require 'imenu) ; May be called from TAGS creator - (let ((index-alist '()) (index-pack-alist '()) (index-pod-alist '()) +(defun cperl-imenu--create-perl-index () + "Implement `imenu-create-index-function` for CPerl mode. +This function relies on syntaxification to exclude lines which +look like declarations but actually are part of a string, a +comment, or POD." + (interactive) ; We'll remove that at some point + (goto-char (point-min)) + (cperl-update-syntaxification (point-max)) + (let ((case-fold-search nil) + (index-alist '()) + (index-package-alist '()) + (index-pod-alist '()) + (index-sub-alist '()) (index-unsorted-alist '()) - (index-meth-alist '()) meth - packages ends-ranges p marker is-proto - is-pack index index1 name (end-range 0) package) - (goto-char (point-min)) - (cperl-update-syntaxification (point-max)) - ;; Search for the function - (progn ;;save-match-data - (while (re-search-forward - (or regexp cperl-imenu--function-name-regexp-perl) - nil t) - ;; 2=package-group, 5=package-name 8=sub-name + (package-stack '()) ; for package NAME BLOCK + (current-package "(main)") + (current-package-end (point-max))) ; end of package scope + ;; collect index entries + (while (re-search-forward cperl--imenu-entries-regexp nil t) + ;; First, check whether we have left the scope of previously + ;; recorded packages, and if so, eliminate them from the stack. + (while (< current-package-end (point)) + (setq current-package (pop package-stack)) + (setq current-package-end (pop package-stack))) + (let ((state (syntax-ppss)) + name marker) ; for the "current" entry (cond - ((and ; Skip some noise if building tags - (match-beginning 5) ; package name - ;;(eq (char-after (match-beginning 2)) ?p) ; package - (not (save-match-data - (looking-at "[ \t\n]*;")))) ; Plain text word 'package' - nil) - ((and - (or (match-beginning 2) - (match-beginning 8)) ; package or sub - ;; Skip if quoted (will not skip multi-line ''-strings :-(): - (null (get-text-property (match-beginning 1) 'syntax-table)) - (null (get-text-property (match-beginning 1) 'syntax-type)) - (null (get-text-property (match-beginning 1) 'in-pod))) - (setq is-pack (match-beginning 2)) - ;; (if (looking-at "([^()]*)[ \t\n\f]*") - ;; (goto-char (match-end 0))) ; Messes what follows - (setq meth nil - p (point)) - (while (and ends-ranges (>= p (car ends-ranges))) - ;; delete obsolete entries - (setq ends-ranges (cdr ends-ranges) packages (cdr packages))) - (setq package (or (car packages) "") - end-range (or (car ends-ranges) 0)) - (if is-pack ; doing "package" - (progn - (if (match-beginning 5) ; named package - (setq name (buffer-substring (match-beginning 5) - (match-end 5)) - name (progn - (set-text-properties 0 (length name) nil name) - name) - package (concat name "::") - name (concat "package " name)) - ;; Support nameless packages - (setq name "package;" package "")) - (setq end-range - (save-excursion - (parse-partial-sexp (point) (point-max) -1) (point)) - ends-ranges (cons end-range ends-ranges) - packages (cons package packages))) - (setq is-proto - (or (eq (following-char) ?\;) - (eq 0 (get-text-property (point) 'attrib-group))))) - ;; Skip this function name if it is a prototype declaration. - (if (and is-proto (not is-pack)) nil - (or is-pack - (setq name - (buffer-substring (match-beginning 8) (match-end 8))) - (set-text-properties 0 (length name) nil name)) - (setq marker (make-marker)) - (set-marker marker (match-end (if is-pack 2 8))) - (cond (is-pack nil) - ((string-match "[:']" name) - (setq meth t)) - ((> p end-range) nil) - (t - (setq name (concat package name) meth t))) - (setq index (cons name marker)) - (if is-pack - (push index index-pack-alist) - (push index index-alist)) - (if meth (push index index-meth-alist)) - (push index index-unsorted-alist))) - ((match-beginning 16) ; POD section - (setq name (buffer-substring (match-beginning 17) (match-end 17)) - marker (make-marker)) - (set-marker marker (match-beginning 17)) - (set-text-properties 0 (length name) nil name) - (setq name (concat (make-string - (* 3 (- (char-after (match-beginning 16)) ?1)) - ?\ ) - name) - index (cons name marker)) - (setq index1 (cons (concat "=" name) (cdr index))) - (push index index-pod-alist) - (push index1 index-unsorted-alist))))) + ((nth 3 state) nil) ; matched in a string, so skip + ((match-string 1) ; found a package name! + (unless (nth 4 state) ; skip if in a comment + (setq name (match-string-no-properties 1) + marker (copy-marker (match-end 1))) + (if (string= (match-string 3) ";") + (setq current-package name) ; package NAME; + ;; No semicolon, therefore we have: package NAME BLOCK. + ;; Stash the current package, because we need to restore + ;; it after the end of BLOCK. + (push current-package-end package-stack) + (push current-package package-stack) + ;; record the current name and its scope + (setq current-package name) + (setq current-package-end (save-excursion + (goto-char (match-beginning 3)) + (forward-sexp) + (point))) + (push (cons name marker) index-package-alist) + (push (cons (concat "package " name) marker) index-unsorted-alist)))) + ((match-string 5) ; found a sub name! + (unless (nth 4 state) ; skip if in a comment + (setq name (match-string-no-properties 5) + marker (copy-marker (match-end 5))) + ;; Qualify the sub name with the package if it doesn't + ;; already have one, and if it isn't lexically scoped. + ;; "my" and "state" subs are lexically scoped, but "our" + ;; are just lexical aliases to package subs. + (if (and (null (string-match "::" name)) + (or (null (match-string 4)) + (string-equal (match-string 4) "our"))) + (setq name (concat current-package "::" name))) + (let ((index (cons name marker))) + (push index index-alist) + (push index index-sub-alist) + (push index index-unsorted-alist)))) + ((match-string 6) ; found a POD heading! + (when (get-text-property (match-beginning 6) 'in-pod) + (setq name (concat (make-string + (* 3 (- (char-after (match-beginning 6)) ?1)) + ?\ ) + (match-string-no-properties 7)) + marker (copy-marker (match-beginning 7))) + (push (cons name marker) index-pod-alist) + (push (cons (concat "=" name) marker) index-unsorted-alist))) + (t (error "Unidentified match: %s" (match-string 0)))))) + ;; Now format the collected stuff (setq index-alist (if (default-value 'imenu-sort-function) (sort index-alist (default-value 'imenu-sort-function)) @@ -5266,14 +5369,14 @@ indentation and initial hashes. Behaves usually outside of comment." (push (cons "+POD headers+..." (nreverse index-pod-alist)) index-alist)) - (and (or index-pack-alist index-meth-alist) - (let ((lst index-pack-alist) hier-list pack elt group name) - ;; Remove "package ", reverse and uniquify. + (and (or index-package-alist index-sub-alist) + (let ((lst index-package-alist) hier-list pack elt group name) + ;; reverse and uniquify. (while lst - (setq elt (car lst) lst (cdr lst) name (substring (car elt) 8)) + (setq elt (car lst) lst (cdr lst) name (car elt)) (if (assoc name hier-list) nil (setq hier-list (cons (cons name (cdr elt)) hier-list)))) - (setq lst index-meth-alist) + (setq lst index-sub-alist) (while lst (setq elt (car lst) lst (cdr lst)) (cond ((string-match "\\(::\\|'\\)[_a-zA-Z0-9]+$" (car elt)) @@ -5301,17 +5404,18 @@ indentation and initial hashes. Behaves usually outside of comment." (push (cons "+Hierarchy+..." hier-list) index-alist))) - (and index-pack-alist + (and index-package-alist (push (cons "+Packages+..." - (nreverse index-pack-alist)) + (nreverse index-package-alist)) index-alist)) - (and (or index-pack-alist index-pod-alist + (and (or index-package-alist index-pod-alist (default-value 'imenu-sort-function)) index-unsorted-alist (push (cons "+Unsorted List+..." (nreverse index-unsorted-alist)) index-alist)) - (cperl-imenu-addback index-alist))) + ;; Finally, return the whole collection + index-alist)) ;; Suggested by Mark A. Hershberger @@ -6631,9 +6735,7 @@ One may build such TAGS files from CPerl mode menu." (cperl-tags-treeify to 1) (setcar (nthcdr 2 cperl-hierarchy) (cperl-menu-to-keymap (cons '("+++UPDATE+++" . -999) (cdr to)))) - (message "Updating list of classes: done, requesting display...") - ;;(cperl-imenu-addback (nth 2 cperl-hierarchy)) - )) + (message "Updating list of classes: done, requesting display..."))) (or (nth 2 cperl-hierarchy) (error "No items found")) (setq update diff --git a/test/lisp/progmodes/cperl-mode-resources/grammar.pl b/test/lisp/progmodes/cperl-mode-resources/grammar.pl new file mode 100644 index 0000000000..c05fd7efc2 --- /dev/null +++ b/test/lisp/progmodes/cperl-mode-resources/grammar.pl @@ -0,0 +1,158 @@ +use 5.024; +use strict; +use warnings; + +sub outside { + say "Line @{[__LINE__]}: package '@{[__PACKAGE__]}'"; +} + +package Package; + +=head1 NAME + +grammar - A Test resource for regular expressions + +=head1 SYNOPSIS + +A Perl file showing a variety of declarations + +=head1 DESCRIPTION + +This file offers several syntactical constructs for packages, +subroutines, and POD to test the imenu capabilities of CPerl mode. + +Perl offers syntactical variations for package and subroutine +declarations. Packages may, or may not, have a version and may, or +may not, have a block of code attached to them. Subroutines can have +old-style prototypes, attributes, and signatures which are still +experimental but widely accepted. + +Various Extensions and future Perl versions will probably add new +keywords for "class" and "method", both with syntactical extras of +their own. + +This test file tries to keep up with them. + +=head2 Details + +The code is supposed to identify and exclude false positives, +e.g. declarations in a string or in POD, as well as POD in a string. +These should not go into the imenu index. + +=cut + +our $VERSION = 3.1415; +say "Line @{[__LINE__]}: package '@{[__PACKAGE__]}', version $VERSION"; + +sub in_package { + # Special test for POD: A line which looks like POD, but actually + # is part of a multiline string. In the case shown here, the + # semicolon is not part of the string, but POD headings go to the + # end of the line. The code needs to distinguish between a POD + # heading "This Is Not A Pod/;" and a multiline string. + my $not_a_pod = q/Another false positive: + +=head1 This Is Not A Pod/; + +} + +sub Shoved::elsewhere { + say "Line @{[__LINE__]}: package '@{[__PACKAGE__]}', sub Shoved::elsewhere"; +} + +sub prototyped ($$) { + ...; +} + +package Versioned::Package 0.07; +say "Line @{[__LINE__]}: package '@{[__PACKAGE__]}', version $VERSION"; + +sub versioned { + # This sub is in package Versioned::Package + say "sub 'versioned' in package '", __PACKAGE__, "'"; +} + +versioned(); + +my $false_positives = <<'EOH'; +The following declarations are not supposed to be recorded for imenu. +They are in a HERE-doc, which is a generic comment in CPerl mode. + +package Don::T::Report::This; +sub this_is_no_sub { + my $self = shuffle; +} + +And this is not a POD heading: + +=head1 Not a POD heading, just a string. + +EOH + +package Block { + our $VERSION = 2.7182; + say "Line @{[__LINE__]}: package '@{[__PACKAGE__]}', version $VERSION"; + + sub attr:lvalue { + say "sub 'attr' in package '", __PACKAGE__, "'"; + } + + attr(); + + package Block::Inner { + # This hopefully doesn't happen too often. + say "Line @{[__LINE__]}: package '@{[__PACKAGE__]}', version $VERSION"; + } + + # Now check that we're back to package "Block" + say "Line @{[__LINE__]}: package '@{[__PACKAGE__]}', version $VERSION"; +} + +sub outer { + # This is in package Versioned::Package + say "Line @{[__LINE__]}: package '@{[__PACKAGE__]}', version $VERSION"; +} + +outer(); + +package Versioned::Block 42 { + say "Line @{[__LINE__]}: package '@{[__PACKAGE__]}', version $VERSION"; + + my sub lexical { + say "sub 'lexical' in package '", __PACKAGE__, "'"; + } + + lexical(); + + use experimental 'signatures'; + sub signatured :prototype($@) ($self,@rest) + { + ...; + } +} + +# After all is said and done, we're back in package Versioned::Package. +say "We're in package '", __PACKAGE__, "' now."; +say "Now try to call a subroutine which went out of scope:"; +eval { lexical() }; +say $@ if $@; + +# Now back to Package. This must not appear separately in the +# hierarchy list. +package Package; + +our sub in_package_again { + say "Line @{[__LINE__]}: package '@{[__PACKAGE__]}', version $VERSION"; +} + + +package :: { + # This is just a weird, but legal, package name. + say "Line @{[__LINE__]}: package '@{[__PACKAGE__]}', version $VERSION"; + + in_package_again(); # weird, but calls the sub from above +} + +Shoved::elsewhere(); + +1; diff --git a/test/lisp/progmodes/cperl-mode-tests.el b/test/lisp/progmodes/cperl-mode-tests.el index 943c454445..61e4ece49b 100644 --- a/test/lisp/progmodes/cperl-mode-tests.el +++ b/test/lisp/progmodes/cperl-mode-tests.el @@ -166,6 +166,101 @@ point in the distant past, and is still broken in perl-mode. " (if (match-beginning 3) 0 perl-indent-level))))))) +;;; Grammar based tests: unit tests + +(defun cperl-test--validate-regexp (regexp valid &optional invalid) + "Runs tests for elements of VALID and INVALID lists against REGEXP. +Tests with elements from VALID must match, tests with elements +from INVALID must not match. The match string must be equal to +the whole string." + (funcall cperl-test-mode) + (dolist (string valid) + (should (string-match regexp string)) + (should (string= (match-string 0 string) string))) + (when invalid + (dolist (string invalid) + (should-not + (and (string-match regexp string) + (string= (match-string 0 string) string)))))) + +(ert-deftest cperl-test-ws-regexp () + "Tests capture of very simple regular expressions (yawn)." + (let ((valid + '(" " "\t" "\n")) + (invalid + '("a" " " ""))) + (cperl-test--validate-regexp cperl--ws-regexp + valid invalid))) + +(ert-deftest cperl-test-ws-or-comment-regexp () + "Tests sequences of whitespace and comment lines." + (let ((valid + `(" " "\t#\n" "\n# \n" + ,(concat "# comment\n" "# comment\n" "\n" "#comment\n"))) + (invalid + '("=head1 NAME\n" ))) + (cperl-test--validate-regexp cperl--ws-or-comment-regexp + valid invalid))) + +(ert-deftest cperl-test-version-regexp () + "Tests the regexp for recommended syntax of versions in Perl." + (let ((valid + '("1" "1.1" "1.1_1" "5.032001" + "v120.100.103")) + (invalid + '("alpha" "0." ".123" "1E2" + "v1.1" ; a "v" version string needs at least 3 components + ;; bad examples from "Version numbers should be boring" + ;; by xdg AKA David A. Golden + "1.20alpha" "2.34beta2" "2.00R3"))) + (cperl-test--validate-regexp cperl--version-regexp + valid invalid))) + +(ert-deftest cperl-test-package-regexp () + "Tests the regular expression of Perl package names with versions. +Also includes valid cases with whitespace in strange places." + (let ((valid + '("package Foo" + "package Foo::Bar" + "package Foo::Bar v1.2.3" + "package Foo::Bar::Baz 1.1" + "package \nFoo::Bar\n 1.00")) + (invalid + '("package Foo;" ; semicolon must not be included + "package Foo 1.1 {" ; nor the opening brace + "packageFoo" ; not a package declaration + "package Foo1.1" ; invalid package name + "class O3D::Sphere"))) ; class not yet supported + (cperl-test--validate-regexp cperl--package-regexp + valid invalid))) + +;;; Function test: Building an index for imenu + +(ert-deftest cperl-test-imenu-index () + "Test index creation for imenu. +This test relies on the specific layout of the index alist as +created by CPerl mode, so skip it for Perl mode." + (skip-unless (eq cperl-test-mode #'cperl-mode)) + (with-temp-buffer + (insert-file (ert-resource-file "grammar.pl")) + (cperl-mode) + (let ((index (cperl-imenu--create-perl-index)) + current-list) + (setq current-list (assoc-string "+Unsorted List+..." index)) + (should current-list) + (let ((expected '("(main)::outside" + "Package::in_package" + "Shoved::elsewhere" + "Package::prototyped" + "Versioned::Package::versioned" + "Block::attr" + "Versioned::Package::outer" + "lexical" + "Versioned::Block::signatured" + "Package::in_package_again"))) + (dolist (sub expected) + (should (assoc-string sub index))))))) + ;;; Tests for issues reported in the Bug Tracker (defun cperl-test--run-bug-10483 () commit 64ef8ff74d3f111d2d71a22c2326fa4c974182ba Author: Lars Ingebrigtsen Date: Wed Feb 17 00:43:52 2021 +0100 Don't move point in `exif-parse-buffer' * lisp/image/exif.el (exif-parse-buffer): Don't move point (bug#46552). diff --git a/lisp/image/exif.el b/lisp/image/exif.el index 2dc9419b81..c2cf234640 100644 --- a/lisp/image/exif.el +++ b/lisp/image/exif.el @@ -118,8 +118,9 @@ If the data is invalid, an `exif-error' is signaled." dest)) (when-let ((app1 (cdr (assq #xffe1 (exif--parse-jpeg))))) (exif--parse-exif-chunk app1)))) - (when-let ((app1 (cdr (assq #xffe1 (exif--parse-jpeg))))) - (exif--parse-exif-chunk app1))))) + (save-excursion + (when-let ((app1 (cdr (assq #xffe1 (exif--parse-jpeg))))) + (exif--parse-exif-chunk app1)))))) (defun exif-orientation (exif) "Return the orientation (in degrees) in EXIF. commit b39ac4c85a80bc2ee07c3e2f5d5b93c493062ecf Author: Lars Ingebrigtsen Date: Tue Feb 16 23:32:04 2021 +0100 Fix edebug spec for minibuffer-with-setup-hook * lisp/files.el (minibuffer-with-setup-hook): Instrument the :append form for edebug (bug#46531). diff --git a/lisp/files.el b/lisp/files.el index 9ff8f31e37..68e883513c 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -1639,7 +1639,7 @@ called additional times). This macro actually adds an auxiliary function that calls FUN, rather than FUN itself, to `minibuffer-setup-hook'." - (declare (indent 1) (debug t)) + (declare (indent 1) (debug ([&or (":append" form) [&or symbolp form]] body))) (let ((hook (make-symbol "setup-hook")) (funsym (make-symbol "fun")) (append nil)) commit cead0ea38e3e15a544f7374b2e831623bda37f1d Author: Lars Ingebrigtsen Date: Tue Feb 16 23:06:46 2021 +0100 Clarify Gnus Agent expiry quirks * doc/misc/gnus.texi (Agent Expiry): Mention that the last article won't be expired (bug#46533). diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi index 5a79cbc08f..fef066db8f 100644 --- a/doc/misc/gnus.texi +++ b/doc/misc/gnus.texi @@ -19357,6 +19357,9 @@ and dormant. If @code{nil} (which is the default), only read articles are eligible for expiry, and unread, ticked and dormant articles will be kept indefinitely. +The last (i.e., newest) article in a group will normally not be +expired (due to internal book-keeping reasons). + If you find that some articles eligible for expiry are never expired, perhaps some Gnus Agent files are corrupted. There's are special commands, @code{gnus-agent-regenerate} and commit bdb0774faf250798d043a93e8a7295df924c4c3b Author: Glenn Morris Date: Tue Feb 16 12:11:55 2021 -0800 thumbs.el: avoid creating thumbs directory on loading library * lisp/thumbs.el (thumbs-cleanup-thumbsdir): Don't create the thumbs directory if it does not exist. diff --git a/lisp/thumbs.el b/lisp/thumbs.el index 465d097b61..957940bfe0 100644 --- a/lisp/thumbs.el +++ b/lisp/thumbs.el @@ -199,23 +199,24 @@ Create the thumbnails directory if it does not exist." If the total size of all files in `thumbs-thumbsdir' is bigger than `thumbs-thumbsdir-max-size', files are deleted until the max size is reached." - (let* ((files-list - (sort - (mapcar - (lambda (f) - (let ((fattribs-list (file-attributes f))) - `(,(file-attribute-access-time fattribs-list) - ,(file-attribute-size fattribs-list) - ,f))) - (directory-files (thumbs-thumbsdir) t (image-file-name-regexp))) - (lambda (l1 l2) (time-less-p (car l1) (car l2))))) - (dirsize (apply '+ (mapcar (lambda (x) (cadr x)) files-list)))) - (while (> dirsize thumbs-thumbsdir-max-size) - (progn - (message "Deleting file %s" (cadr (cdar files-list)))) - (delete-file (cadr (cdar files-list))) - (setq dirsize (- dirsize (car (cdar files-list)))) - (setq files-list (cdr files-list))))) + (when (file-directory-p thumbs-thumbsdir) + (let* ((files-list + (sort + (mapcar + (lambda (f) + (let ((fattribs-list (file-attributes f))) + `(,(file-attribute-access-time fattribs-list) + ,(file-attribute-size fattribs-list) + ,f))) + (directory-files (thumbs-thumbsdir) t (image-file-name-regexp))) + (lambda (l1 l2) (time-less-p (car l1) (car l2))))) + (dirsize (apply '+ (mapcar (lambda (x) (cadr x)) files-list)))) + (while (> dirsize thumbs-thumbsdir-max-size) + (progn + (message "Deleting file %s" (cadr (cdar files-list)))) + (delete-file (cadr (cdar files-list))) + (setq dirsize (- dirsize (car (cdar files-list)))) + (setq files-list (cdr files-list)))))) ;; Check the thumbnail directory size and clean it if necessary. (when thumbs-thumbsdir-auto-clean commit b2fe1bbd06b6654427d9ff07124be02a21e54c3b Author: Glenn Morris Date: Tue Feb 16 12:03:39 2021 -0800 * admin/cus-test.el (cus-test-load-libs): Quieten loading. diff --git a/admin/cus-test.el b/admin/cus-test.el index 7938359119..afd5f4ceae 100644 --- a/admin/cus-test.el +++ b/admin/cus-test.el @@ -320,7 +320,8 @@ If it is \"all\", load all Lisp files." (lambda (file) (condition-case alpha (unless (member file cus-test-libs-noloads) - (load (file-name-sans-extension (expand-file-name file lispdir))) + (load (file-name-sans-extension (expand-file-name file lispdir)) + nil t) (push file cus-test-libs-loaded)) (error (push (cons file alpha) cus-test-libs-errors) commit f2bf357308dc35e311f1b77e03f4c68b071f5acc Author: Glenn Morris Date: Tue Feb 16 12:01:25 2021 -0800 * admin/cus-test.el (cus-test-get-lisp-files): Ignore loaddefs files. diff --git a/admin/cus-test.el b/admin/cus-test.el index 995586f9c7..7938359119 100644 --- a/admin/cus-test.el +++ b/admin/cus-test.el @@ -349,6 +349,8 @@ Optional argument ALL non-nil means list all (non-obsolete) Lisp files." (mapcar (lambda (e) (substring e 2)) (apply #'process-lines find-program "." "-name" "obsolete" "-prune" "-o" + "-name" "ldefs-boot.el" "-prune" "-o" + "-name" "*loaddefs.el" "-prune" "-o" "-name" "[^.]*.el" ; ignore .dir-locals.el (if all '("-print") commit 12b80948fd2fc599b9ea4cc6497c007205b3e57e Author: Bastian Beranek Date: Tue Feb 16 11:35:35 2021 +0100 * lisp/tab-bar.el: Fix behavior of toggle-frame-tab-bar (bug #46299) (toggle-frame-tab-bar): Add frame parameter to protect tab bar state. (tab-bar--update-tab-bar-lines): Check parameter. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 4e47ae2c10..f0210e1a42 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -161,7 +161,8 @@ update." (t frames)))) ;; Loop over all frames and update default-frame-alist (dolist (frame frame-lst) - (set-frame-parameter frame 'tab-bar-lines (tab-bar--tab-bar-lines-for-frame frame)))) + (unless (frame-parameter frame 'tab-bar-lines-keep-state) + (set-frame-parameter frame 'tab-bar-lines (tab-bar--tab-bar-lines-for-frame frame))))) (when (eq frames t) (setq default-frame-alist (cons (cons 'tab-bar-lines (if (and tab-bar-mode (eq tab-bar-show t)) 1 0)) @@ -233,7 +234,9 @@ new frame when the global `tab-bar-mode' is enabled, by using (add-hook 'after-make-frame-functions 'toggle-frame-tab-bar)" (interactive) (set-frame-parameter frame 'tab-bar-lines - (if (> (frame-parameter frame 'tab-bar-lines) 0) 0 1))) + (if (> (frame-parameter frame 'tab-bar-lines) 0) 0 1)) + (set-frame-parameter frame 'tab-bar-lines-keep-state + (not (frame-parameter frame 'tab-bar-lines-keep-state)))) (defvar tab-bar-map (make-sparse-keymap) "Keymap for the tab bar. commit 1abf3ae854dbf8405e81680225517bbfac648964 Author: Basil L. Contovounesios Date: Sun Feb 14 16:58:06 2021 +0000 Pacify unused function warning in xfns.c with GTK2 * src/xfns.c (x_get_net_workarea, x_get_monitor_for_frame) (x_make_monitor_attribute_list, x_get_monitor_attributes_fallback): [HAVE_XINERAMA] (x_get_monitor_attributes_xinerama) [HAVE_XRANDR] (x_get_monitor_attributes_xrandr) (x_get_monitor_attributes): Fix #ifdefs around definitions to avoid unused function warnings regardless of GTK use (bug#46509). [HAVE_XRANDR] (x_get_monitor_attributes_xrandr): Undefine RANDR13_LIBRARY after it's been used. diff --git a/src/xfns.c b/src/xfns.c index 481ee0e225..d90644819b 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -4599,7 +4599,7 @@ On MS Windows, this just returns nil. */) return Qnil; } -#if !defined USE_GTK || !defined HAVE_GTK3 +#if !(defined USE_GTK && defined HAVE_GTK3) /* Store the geometry of the workarea on display DPYINFO into *RECT. Return false if and only if the workarea information cannot be @@ -4662,6 +4662,9 @@ x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle *rect) return result; } +#endif /* !(USE_GTK && HAVE_GTK3) */ + +#ifndef USE_GTK /* Return monitor number where F is "most" or closest to. */ static int @@ -4877,6 +4880,8 @@ x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo) pxid = XRRGetOutputPrimary (dpy, dpyinfo->root_window); #endif +#undef RANDR13_LIBRARY + for (i = 0; i < n_monitors; ++i) { XRROutputInfo *info = XRRGetOutputInfo (dpy, resources, commit 76220fc3fc8b109d53676c1771fa1f05f3706ac7 Author: Lars Ingebrigtsen Date: Tue Feb 16 17:42:24 2021 +0100 Revert "Fix problem of point movement in image-mode" This reverts commit 7c7377288a125ef47f2b422cf131f044a3b418e1. This is fixed differently in Emacs 27. diff --git a/lisp/image-mode.el b/lisp/image-mode.el index 28b75c8113..ec0a559c8d 100644 --- a/lisp/image-mode.el +++ b/lisp/image-mode.el @@ -611,7 +611,6 @@ Key bindings: (major-mode-suspend) (setq major-mode 'image-mode) (setq image-transform-resize image-auto-resize) - (setq-local disable-point-adjustment t) ;; Bail out early if we have no image data. (if (zerop (buffer-size)) @@ -932,7 +931,6 @@ If the current buffer is displaying an image file as an image, call `image-mode-as-text' to switch to text or hex display. Otherwise, display the image by calling `image-mode'." (interactive) - (goto-char (point-min)) (if (image-get-display-property) (image-mode-as-text) (if (eq major-mode 'hexl-mode) commit 7c7377288a125ef47f2b422cf131f044a3b418e1 Author: Lars Ingebrigtsen Date: Tue Feb 16 17:39:03 2021 +0100 Fix problem of point movement in image-mode * lisp/image-mode.el (image-mode): Switch disable-point-adjustment on, otherwise `C-c C-c' will move point around oddly. (image-toggle-display): Ensure that point is on the image (bug#46552). diff --git a/lisp/image-mode.el b/lisp/image-mode.el index ec0a559c8d..28b75c8113 100644 --- a/lisp/image-mode.el +++ b/lisp/image-mode.el @@ -611,6 +611,7 @@ Key bindings: (major-mode-suspend) (setq major-mode 'image-mode) (setq image-transform-resize image-auto-resize) + (setq-local disable-point-adjustment t) ;; Bail out early if we have no image data. (if (zerop (buffer-size)) @@ -931,6 +932,7 @@ If the current buffer is displaying an image file as an image, call `image-mode-as-text' to switch to text or hex display. Otherwise, display the image by calling `image-mode'." (interactive) + (goto-char (point-min)) (if (image-get-display-property) (image-mode-as-text) (if (eq major-mode 'hexl-mode) commit c977370dd734be12ffbaf0da2f3db529d6175b62 Author: Eli Zaretskii Date: Tue Feb 16 18:20:06 2021 +0200 Avoid point movement when visiting image files * lisp/image-mode.el (image-toggle-display-image): Preserve point around the call to exif-parse-buffer, to prevent it from moving into the image data. (Bug#46552) diff --git a/lisp/image-mode.el b/lisp/image-mode.el index aee91ee8b2..24be008f3f 100644 --- a/lisp/image-mode.el +++ b/lisp/image-mode.el @@ -829,7 +829,9 @@ was inserted." (setq image-transform-rotation (or (exif-orientation (ignore-error exif-error - (exif-parse-buffer))) + ;; exif-parse-buffer can move point, so preserve it. + (save-excursion + (exif-parse-buffer)))) 0.0))) ;; Swap width and height when changing orientation ;; between portrait and landscape. commit fff138eb3d88e6933a0456a49d38f2850e048f53 Author: Lars Ingebrigtsen Date: Tue Feb 16 14:21:52 2021 +0100 Do interactive mode tagging for info.el diff --git a/lisp/info.el b/lisp/info.el index 7f169f4b55..e7324efa2f 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -1972,7 +1972,8 @@ If DIRECTION is `backward', search in the reverse direction." (format-prompt "Regexp search%s" (car Info-search-history) (if case-fold-search "" " case-sensitively")) - nil 'Info-search-history))) + nil 'Info-search-history)) + Info-mode) (when (equal regexp "") (setq regexp (car Info-search-history))) (when regexp @@ -2080,13 +2081,13 @@ If DIRECTION is `backward', search in the reverse direction." (defun Info-search-case-sensitively () "Search for a regexp case-sensitively." - (interactive) + (interactive nil Info-mode) (let ((case-fold-search nil)) (call-interactively 'Info-search))) (defun Info-search-next () "Search for next regexp from a previous `Info-search' command." - (interactive) + (interactive nil Info-mode) (let ((case-fold-search Info-search-case-fold)) (if Info-search-history (Info-search (car Info-search-history)) @@ -2098,7 +2099,8 @@ If DIRECTION is `backward', search in the reverse direction." (format-prompt "Regexp search%s backward" (car Info-search-history) (if case-fold-search "" " case-sensitively")) - nil 'Info-search-history))) + nil 'Info-search-history)) + Info-mode) (Info-search regexp bound noerror count 'backward)) (defun Info-isearch-search () @@ -2235,7 +2237,7 @@ End of submatch 0, 1, and 3 are the same, so you can safely concat." (defun Info-next () "Go to the \"next\" node, staying on the same hierarchical level. This command doesn't descend into sub-nodes, like \\\\[Info-forward-node] does." - (interactive) + (interactive nil Info-mode) ;; In case another window is currently selected (save-window-excursion (or (derived-mode-p 'Info-mode) (switch-to-buffer "*info*")) @@ -2244,7 +2246,7 @@ This command doesn't descend into sub-nodes, like \\\\[Info-forwa (defun Info-prev () "Go to the \"previous\" node, staying on the same hierarchical level. This command doesn't go up to the parent node, like \\\\[Info-backward-node] does." - (interactive) + (interactive nil Info-mode) ;; In case another window is currently selected (save-window-excursion (or (derived-mode-p 'Info-mode) (switch-to-buffer "*info*")) @@ -2253,7 +2255,7 @@ This command doesn't go up to the parent node, like \\\\[Info-bac (defun Info-up (&optional same-file) "Go to the superior node of this node. If SAME-FILE is non-nil, do not move to a different Info file." - (interactive) + (interactive nil Info-mode) ;; In case another window is currently selected (save-window-excursion (or (derived-mode-p 'Info-mode) (switch-to-buffer "*info*")) @@ -2284,7 +2286,7 @@ If SAME-FILE is non-nil, do not move to a different Info file." (defun Info-history-back () "Go back in the history to the last node visited." - (interactive) + (interactive nil Info-mode) (or Info-history (user-error "This is the first Info node you looked at")) (let ((history-forward @@ -2304,7 +2306,7 @@ If SAME-FILE is non-nil, do not move to a different Info file." (defun Info-history-forward () "Go forward in the history of visited nodes." - (interactive) + (interactive nil Info-mode) (or Info-history-forward (user-error "This is the last Info node you looked at")) (let ((history-forward (cdr Info-history-forward)) @@ -2378,7 +2380,7 @@ If SAME-FILE is non-nil, do not move to a different Info file." (defun Info-history () "Go to a node with a menu of visited nodes." - (interactive) + (interactive nil Info-mode) (Info-find-node "*History*" "Top") (Info-next-reference) (Info-next-reference)) @@ -2415,7 +2417,7 @@ If SAME-FILE is non-nil, do not move to a different Info file." (defun Info-toc () "Go to a node with table of contents of the current Info file. Table of contents is created from the tree structure of menus." - (interactive) + (interactive nil Info-mode) (Info-find-node Info-current-file "*TOC*") (let ((prev-node (nth 1 (car Info-history))) p) (goto-char (point-min)) @@ -2587,7 +2589,8 @@ new buffer." (list (if (equal input "") default input) current-prefix-arg)) - (user-error "No cross-references in this node")))) + (user-error "No cross-references in this node"))) + Info-mode) (unless footnotename (error "No reference was specified")) @@ -2789,7 +2792,8 @@ new buffer." (completing-read (format-prompt "Menu item" default) #'Info-complete-menu-item nil t nil nil default)))) - (list item current-prefix-arg)))) + (list item current-prefix-arg))) + Info-mode) ;; there is a problem here in that if several menu items have the same ;; name you can only go to the node of the first with this command. (Info-goto-node (Info-extract-menu-item menu-item) @@ -2833,19 +2837,19 @@ new buffer." (defun Info-nth-menu-item () "Go to the node of the Nth menu item. N is the digit argument used to invoke this command." - (interactive) + (interactive nil Info-mode) (Info-goto-node (Info-extract-menu-counting (- (aref (this-command-keys) (1- (length (this-command-keys)))) ?0)))) (defun Info-top-node () "Go to the Top node of this file." - (interactive) + (interactive nil Info-mode) (Info-goto-node "Top")) (defun Info-final-node () "Go to the final node in this file." - (interactive) + (interactive nil Info-mode) (Info-goto-node "Top") (let ((Info-history nil) (case-fold-search t)) @@ -2869,7 +2873,7 @@ to the parent node. When called from Lisp, NOT-DOWN non-nil means don't descend into sub-nodes, NOT-UP non-nil means don't go to parent nodes, and NO-ERROR non-nil means don't signal a user-error if there's no node to go to." - (interactive) + (interactive nil Info-mode) (goto-char (point-min)) (forward-line 1) (let ((case-fold-search t)) @@ -2906,7 +2910,7 @@ don't signal a user-error if there's no node to go to." "Go backward one node, considering all nodes as forming one sequence. If the current node has a \"previous\" node, go to it, descending into its last sub-node, if any; otherwise go \"up\" to the parent node." - (interactive) + (interactive nil Info-mode) (let ((prevnode (Info-extract-pointer "prev[ious]*" t)) (upnode (Info-extract-pointer "up" t)) (case-fold-search t)) @@ -2935,7 +2939,7 @@ last sub-node, if any; otherwise go \"up\" to the parent node." (defun Info-next-menu-item () "Go to the node of the next menu item." - (interactive) + (interactive nil Info-mode) ;; Bind this in case the user sets it to nil. (let* ((case-fold-search t) (node @@ -2949,7 +2953,7 @@ last sub-node, if any; otherwise go \"up\" to the parent node." (defun Info-last-menu-item () "Go to the node of the previous menu item." - (interactive) + (interactive nil Info-mode) (save-excursion (forward-line 1) ;; Bind this in case the user sets it to nil. @@ -2968,7 +2972,7 @@ last sub-node, if any; otherwise go \"up\" to the parent node." (defun Info-next-preorder () "Go to the next subnode or the next node, or go up a level." - (interactive) + (interactive nil Info-mode) (cond ((Info-no-error (Info-next-menu-item))) ((Info-no-error (Info-next))) ((Info-no-error (Info-up t)) @@ -2987,7 +2991,7 @@ last sub-node, if any; otherwise go \"up\" to the parent node." (defun Info-last-preorder () "Go to the last node, popping up a level if there is none." - (interactive) + (interactive nil Info-mode) (cond ((and Info-scroll-prefer-subnodes (Info-no-error (Info-last-menu-item) @@ -3039,7 +3043,7 @@ the menu of a node, it moves to subnode indicated by the following menu item. (That case won't normally result from this command, but can happen in other ways.)" - (interactive) + (interactive nil Info-mode) (if (or (< (window-start) (point-min)) (> (window-start) (point-max))) (set-window-start (selected-window) (point))) @@ -3061,7 +3065,7 @@ in other ways.)" (defun Info-mouse-scroll-up (e) "Scroll one screenful forward in Info, using the mouse. See `Info-scroll-up'." - (interactive "e") + (interactive "e" Info-mode) (save-selected-window (if (eventp e) (select-window (posn-window (event-start e)))) @@ -3073,7 +3077,7 @@ If point is within the menu of a node, and `Info-scroll-prefer-subnodes' is non-nil, this goes to its last subnode. When you scroll past the beginning of a node, that goes to the previous node or back up to the parent node." - (interactive) + (interactive nil Info-mode) (if (or (< (window-start) (point-min)) (> (window-start) (point-max))) (set-window-start (selected-window) (point))) @@ -3093,7 +3097,7 @@ parent node." (defun Info-mouse-scroll-down (e) "Scroll one screenful backward in Info, using the mouse. See `Info-scroll-down'." - (interactive "e") + (interactive "e" Info-mode) (save-selected-window (if (eventp e) (select-window (posn-window (event-start e)))) @@ -3139,7 +3143,7 @@ Return the new position of point, or nil." "Move cursor to the next cross-reference or menu item in the node. If COUNT is non-nil (interactively with a prefix arg), jump over COUNT cross-references." - (interactive "i\np") + (interactive "i\np" Info-mode) (unless count (setq count 1)) (if (< count 0) @@ -3167,7 +3171,7 @@ COUNT cross-references." "Move cursor to the previous cross-reference or menu item in the node. If COUNT is non-nil (interactively with a prefix arg), jump over COUNT cross-references." - (interactive "i\np") + (interactive "i\np" Info-mode) (unless count (setq count 1)) (if (< count 0) @@ -3365,7 +3369,7 @@ Give an empty topic name to go to the Index node itself." (defun Info-index-next (num) "Go to the next matching index item from the last \\\\[Info-index] command." - (interactive "p") + (interactive "p" Info-mode) (or Info-index-alternatives (user-error "No previous `i' command")) (while (< num 0) @@ -3487,7 +3491,8 @@ search results." (with-current-buffer Info-complete-menu-buffer (Info-goto-index) (completing-read "Index topic: " #'Info-complete-menu-item)) - (kill-buffer Info-complete-menu-buffer))))) + (kill-buffer Info-complete-menu-buffer)))) + Info-mode) (if (equal topic "") (Info-find-node Info-current-file "*Index*") (unless (assoc (cons Info-current-file topic) Info-virtual-index-nodes) @@ -3793,7 +3798,7 @@ with a list of packages that contain all specified keywords." (defun Info-undefined () "Make command be undefined in Info." - (interactive) + (interactive nil Info-mode) (ding)) (defun Info-help () @@ -3870,7 +3875,7 @@ ERRORSTRING optional fourth argument, controls action on no match: "\\Follow a node reference near point. Like \\[Info-menu], \\[Info-follow-reference], \\[Info-next], \\[Info-prev] or \\[Info-up] command, depending on where you click. At end of the node's text, moves to the next node, or up if none." - (interactive "e") + (interactive "e" Info-mode) (mouse-set-point click) (and (not (Info-follow-nearest-node)) (save-excursion (forward-line 1) (eobp)) @@ -3884,7 +3889,7 @@ if point is in a menu item description, follow that menu item. If FORK is non-nil (interactively with a prefix arg), show the node in a new Info buffer. If FORK is a string, it is the name to use for the new buffer." - (interactive "P") + (interactive "P" Info-mode) (or (Info-try-follow-nearest-node fork) (when (save-excursion (search-backward "\n* menu:" nil t)) @@ -3954,7 +3959,7 @@ If FORK is non-nil, it is passed to `Info-goto-node'." (defun Info-mouse-follow-link (click) "Follow a link where you click." - (interactive "@e") + (interactive "@e" Info-mode) (let* ((position (event-start click)) (posn-string (and position (posn-string position))) (link-args (if posn-string @@ -4158,12 +4163,12 @@ If FORK is non-nil, it is passed to `Info-goto-node'." (defun Info-history-back-menu (e) "Pop up the menu with a list of previously visited Info nodes." - (interactive "e") + (interactive "e" Info-mode) (Info-history-menu e "Back in history" Info-history 'Info-history-back)) (defun Info-history-forward-menu (e) "Pop up the menu with a list of Info nodes visited with ‘Info-history-back’." - (interactive "e") + (interactive "e" Info-mode) (Info-history-menu e "Forward in history" Info-history-forward 'Info-history-forward)) (defvar Info-menu-last-node nil) @@ -4237,7 +4242,7 @@ If FORK is non-nil, it is passed to `Info-goto-node'." "Put the name of the current Info node into the kill ring. The name of the Info file is prepended to the node name in parentheses. With a zero prefix arg, put the name inside a function call to `info'." - (interactive "P") + (interactive "P" Info-mode) (unless Info-current-node (user-error "No current Info node")) (let ((node (if (stringp Info-current-file) commit b79055e960dfe9419214930594eddd9ae7b9ece7 Author: Lars Ingebrigtsen Date: Tue Feb 16 14:00:55 2021 +0100 Don't resize images in image-mode if we have a rotation * lisp/image-mode.el (image-fit-to-window): Don't resize of we have a manually rotated imaged (and explain the resizing logic a bit). diff --git a/lisp/image-mode.el b/lisp/image-mode.el index 9ed295e2aa..ec0a559c8d 100644 --- a/lisp/image-mode.el +++ b/lisp/image-mode.el @@ -985,7 +985,13 @@ Otherwise, display the image by calling `image-mode'." (edges (window-inside-pixel-edges window)) (window-width (- (nth 2 edges) (nth 0 edges))) (window-height (- (nth 3 edges) (nth 1 edges)))) + ;; If the size has been changed manually (with `+'/`-'), + ;; then :max-width/:max-height is nil. In that case, do + ;; no automatic resizing. (when (and image-width image-height + ;; Don't do resizing if we have a manual + ;; rotation (from the `r' command), either. + (not (plist-get (cdr spec) :rotation)) (or (not (= image-width window-width)) (not (= image-height window-height)))) (unless image-fit-to-window-lock commit 5b10ca8f4f70cbdc51970b8b756d11f1dbf6e2f6 Author: Konstantin Kharlamov Date: Tue Feb 16 12:49:30 2021 +0100 make smerge-vc-next-conflict wrap around * lisp/vc/smerge-mode.el: (smerge-vc-next-conflict): While searching for conflict markers, wrap search around if current file is the last one with conflicts (bug#46538). diff --git a/lisp/vc/smerge-mode.el b/lisp/vc/smerge-mode.el index c66a4fb2d6..782c799273 100644 --- a/lisp/vc/smerge-mode.el +++ b/lisp/vc/smerge-mode.el @@ -1468,12 +1468,12 @@ found, uses VC to try and find the next file with conflict." (if (and (buffer-modified-p) buffer-file-name) (save-buffer)) (vc-find-conflicted-file) - (if (eq buffer (current-buffer)) - ;; Do nothing: presumably `vc-find-conflicted-file' already - ;; emitted a message explaining there aren't any more conflicts. - nil - (goto-char (point-min)) - (smerge-next))))))) + (when (eq buffer (current-buffer)) + ;; Try to find a conflict marker in current file above the point. + (let ((prev-pos (point))) + (goto-char (point-min)) + (unless (ignore-errors (not (smerge-next))) + (goto-char prev-pos))))))))) (provide 'smerge-mode) commit 03adc69af708e53d18f4efecbcaaee02f055ef56 Author: Stefan Kangas Date: Tue Feb 16 10:05:03 2021 +0100 Do `interactive' mode tagging in gomoku.el * lisp/play/gomoku.el: Do `interactive' mode tagging. diff --git a/lisp/play/gomoku.el b/lisp/play/gomoku.el index 61b67aeb70..0a45885b87 100644 --- a/lisp/play/gomoku.el +++ b/lisp/play/gomoku.el @@ -781,7 +781,7 @@ Use \\[describe-mode] for more info." (defun gomoku-emacs-plays () "Compute Emacs next move and play it." - (interactive) + (interactive nil gomoku-mode) (gomoku-switch-to-window) (cond (gomoku-emacs-is-computing @@ -814,7 +814,7 @@ Use \\[describe-mode] for more info." ;; pixels, event's (X . Y) is a character's top-left corner. (defun gomoku-click (click) "Position at the square where you click." - (interactive "e") + (interactive "e" gomoku-mode) (and (windowp (posn-window (setq click (event-end click)))) (numberp (posn-point click)) (select-window (posn-window click)) @@ -843,7 +843,7 @@ Use \\[describe-mode] for more info." (defun gomoku-mouse-play (click) "Play at the square where you click." - (interactive "e") + (interactive "e" gomoku-mode) (if (gomoku-click click) (gomoku-human-plays))) @@ -851,7 +851,7 @@ Use \\[describe-mode] for more info." "Signal to the Gomoku program that you have played. You must have put the cursor on the square where you want to play. If the game is finished, this command requests for another game." - (interactive) + (interactive nil gomoku-mode) (gomoku-switch-to-window) (cond (gomoku-emacs-is-computing @@ -879,7 +879,7 @@ If the game is finished, this command requests for another game." (defun gomoku-human-takes-back () "Signal to the Gomoku program that you wish to take back your last move." - (interactive) + (interactive nil gomoku-mode) (gomoku-switch-to-window) (cond (gomoku-emacs-is-computing @@ -903,7 +903,7 @@ If the game is finished, this command requests for another game." (defun gomoku-human-resigns () "Signal to the Gomoku program that you may want to resign." - (interactive) + (interactive nil gomoku-mode) (gomoku-switch-to-window) (cond (gomoku-emacs-is-computing @@ -1161,20 +1161,20 @@ If the game is finished, this command requests for another game." ;; the screen. (defun gomoku-move-right () "Move point right one column on the Gomoku board." - (interactive) + (interactive nil gomoku-mode) (when (< (gomoku-point-x) gomoku-board-width) (forward-char gomoku-square-width))) (defun gomoku-move-left () "Move point left one column on the Gomoku board." - (interactive) + (interactive nil gomoku-mode) (when (> (gomoku-point-x) 1) (backward-char gomoku-square-width))) ;; previous-line and next-line don't work right with intangible newlines (defun gomoku-move-down () "Move point down one row on the Gomoku board." - (interactive) + (interactive nil gomoku-mode) (when (< (gomoku-point-y) gomoku-board-height) (let ((column (current-column))) (forward-line gomoku-square-height) @@ -1182,7 +1182,7 @@ If the game is finished, this command requests for another game." (defun gomoku-move-up () "Move point up one row on the Gomoku board." - (interactive) + (interactive nil gomoku-mode) (when (> (gomoku-point-y) 1) (let ((column (current-column))) (forward-line (- gomoku-square-height)) @@ -1190,36 +1190,36 @@ If the game is finished, this command requests for another game." (defun gomoku-move-ne () "Move point North East on the Gomoku board." - (interactive) + (interactive nil gomoku-mode) (gomoku-move-up) (gomoku-move-right)) (defun gomoku-move-se () "Move point South East on the Gomoku board." - (interactive) + (interactive nil gomoku-mode) (gomoku-move-down) (gomoku-move-right)) (defun gomoku-move-nw () "Move point North West on the Gomoku board." - (interactive) + (interactive nil gomoku-mode) (gomoku-move-up) (gomoku-move-left)) (defun gomoku-move-sw () "Move point South West on the Gomoku board." - (interactive) + (interactive nil gomoku-mode) (gomoku-move-down) (gomoku-move-left)) (defun gomoku-beginning-of-line () "Move point to first square on the Gomoku board row." - (interactive) + (interactive nil gomoku-mode) (move-to-column gomoku-x-offset)) (defun gomoku-end-of-line () "Move point to last square on the Gomoku board row." - (interactive) + (interactive nil gomoku-mode) (move-to-column (+ gomoku-x-offset (* gomoku-square-width (1- gomoku-board-width))))) commit 9f843572d2feb4c75bd4f1d2a86edc7595591dc9 Author: Stefan Kangas Date: Tue Feb 16 09:56:17 2021 +0100 * lisp/play/gomoku.el: Minor doc fixes; formatting. diff --git a/lisp/play/gomoku.el b/lisp/play/gomoku.el index 8db40d7f94..61b67aeb70 100644 --- a/lisp/play/gomoku.el +++ b/lisp/play/gomoku.el @@ -28,39 +28,36 @@ ;; RULES: ;; ;; Gomoku is a game played between two players on a rectangular board. Each -;; player, in turn, marks a free square of its choice. The winner is the first +;; player, in turn, marks a free square of its choice. The winner is the first ;; one to mark five contiguous squares in any direction (horizontally, ;; vertically or diagonally). ;; ;; I have been told that, in "The TRUE Gomoku", some restrictions are made ;; about the squares where one may play, or else there is a known forced win -;; for the first player. This program has no such restriction, but it does not +;; for the first player. This program has no such restriction, but it does not ;; know about the forced win, nor do I. -;; See http://renju.se/rif/r1rulhis.htm for more information. - +;; See https://renju.se/rif/r1rulhis.htm for more information. ;; There are two main places where you may want to customize the program: key -;; bindings and board display. These features are commented in the code. Go +;; bindings and board display. These features are commented in the code. Go ;; and see. - ;; HOW TO USE: ;; -;; The command "M-x gomoku" displays a -;; board, the size of which depends on the size of the current window. The -;; size of the board is easily modified by giving numeric arguments to the -;; gomoku command and/or by customizing the displaying parameters. +;; The command `M-x gomoku' displays a board, the size of which depends on the +;; size of the current window. The size of the board is easily modified by +;; giving numeric arguments to the gomoku command and/or by customizing the +;; displaying parameters. ;; -;; Emacs plays when it is its turn. When it is your turn, just put the cursor +;; Emacs plays when it is its turn. When it is your turn, just put the cursor ;; on the square where you want to play and hit RET, or X, or whatever key you -;; bind to the command gomoku-human-plays. When it is your turn, Emacs is +;; bind to the command `gomoku-human-plays'. When it is your turn, Emacs is ;; idle: you may switch buffers, read your mail, ... Just come back to the ;; *Gomoku* buffer and resume play. - ;; ALGORITHM: ;; -;; The algorithm is briefly described in section "THE SCORE TABLE". Some +;; The algorithm is briefly described in section "THE SCORE TABLE". Some ;; parameters may be modified if you want to change the style exhibited by the ;; program. @@ -86,13 +83,15 @@ One useful value to include is `turn-on-font-lock' to highlight the pieces." "Name of the Gomoku buffer.") ;; You may change these values if you have a small screen or if the squares -;; look rectangular, but spacings SHOULD be at least 2 (MUST BE at least 1). +;; look rectangular. (defconst gomoku-square-width 4 - "Horizontal spacing between squares on the Gomoku board.") + "Horizontal spacing between squares on the Gomoku board. +SHOULD be at least 2 (MUST BE at least 1).") (defconst gomoku-square-height 2 - "Vertical spacing between squares on the Gomoku board.") + "Vertical spacing between squares on the Gomoku board. +SHOULD be at least 2 (MUST BE at least 1).") (defconst gomoku-x-offset 3 "Number of columns between the Gomoku board and the side of the window.") @@ -270,13 +269,13 @@ Other useful commands:\n ;; internested 5-tuples of contiguous squares (called qtuples). ;; ;; The aim of the program is to fill one qtuple with its O's while preventing -;; you from filling another one with your X's. To that effect, it computes a -;; score for every qtuple, with better qtuples having better scores. Of +;; you from filling another one with your X's. To that effect, it computes a +;; score for every qtuple, with better qtuples having better scores. Of ;; course, the score of a qtuple (taken in isolation) is just determined by -;; its contents as a set, i.e. not considering the order of its elements. The +;; its contents as a set, i.e. not considering the order of its elements. The ;; highest score is given to the "OOOO" qtuples because playing in such a -;; qtuple is winning the game. Just after this comes the "XXXX" qtuple because -;; not playing in it is just losing the game, and so on. Note that a +;; qtuple is winning the game. Just after this comes the "XXXX" qtuple because +;; not playing in it is just losing the game, and so on. Note that a ;; "polluted" qtuple, i.e. one containing at least one X and at least one O, ;; has score zero because there is no more any point in playing in it, from ;; both an attacking and a defending point of view. @@ -284,11 +283,11 @@ Other useful commands:\n ;; Given the score of every qtuple, the score of a given free square on the ;; board is just the sum of the scores of all the qtuples to which it belongs, ;; because playing in that square is playing in all its containing qtuples at -;; once. And it is that function which takes into account the internesting of +;; once. And it is that function which takes into account the internesting of ;; the qtuples. ;; ;; This algorithm is rather simple but anyway it gives a not so dumb level of -;; play. It easily extends to "n-dimensional Gomoku", where a win should not +;; play. It easily extends to "n-dimensional Gomoku", where a win should not ;; be obtained with as few as 5 contiguous marks: 6 or 7 (depending on n !) ;; should be preferred. @@ -323,8 +322,8 @@ Other useful commands:\n ;; because "a" mainly belongs to six "XX" qtuples (the others are less ;; important) while "b" belongs to one "XXX" and one "XX" qtuples. Other ;; conditions are required to obtain sensible moves, but the previous example -;; should illustrate the point. If you manage to improve on these values, -;; please send me a note. Thanks. +;; should illustrate the point. If you manage to improve on these values, +;; please send me a note. Thanks. ;; As we chose values 0, 1 and 6 to denote empty, X and O squares, the @@ -343,9 +342,9 @@ Other useful commands:\n ;; If you do not modify drastically the previous constants, the only way for a ;; square to have a score higher than gomoku-OOOOscore is to belong to a "OOOO" -;; qtuple, thus to be a winning move. Similarly, the only way for a square to +;; qtuple, thus to be a winning move. Similarly, the only way for a square to ;; have a score between gomoku-XXXXscore and gomoku-OOOOscore is to belong to a "XXXX" -;; qtuple. We may use these considerations to detect when a given move is +;; qtuple. We may use these considerations to detect when a given move is ;; winning or losing. (defconst gomoku-winning-threshold gomoku-OOOOscore @@ -357,8 +356,8 @@ Other useful commands:\n (defun gomoku-strongest-square () "Compute index of free square with highest score, or nil if none." - ;; We just have to loop other all squares. However there are two problems: - ;; 1/ The SCORE-TABLE only gives correct scores to free squares. To speed + ;; We just have to loop other all squares. However there are two problems: + ;; 1/ The SCORE-TABLE only gives correct scores to free squares. To speed ;; up future searches, we set the score of padding or occupied squares ;; to -1 whenever we meet them. ;; 2/ We want to choose randomly between equally good moves. @@ -378,7 +377,7 @@ Other useful commands:\n best-square square score-max score) (aset gomoku-score-table square -1))) ; no: kill it ! - ;; If score is equally good, choose randomly. But first check freedom: + ;; If score is equally good, choose randomly. But first check freedom: ((not (zerop (aref gomoku-board square))) (aset gomoku-score-table square -1)) ((zerop (random (setq count (1+ count)))) @@ -392,11 +391,11 @@ Other useful commands:\n ;;; ;; At initialization the board is empty so that every qtuple amounts for -;; gomoku-nil-score. Therefore, the score of any square is gomoku-nil-score times the number -;; of qtuples that pass through it. This number is 3 in a corner and 20 if you -;; are sufficiently far from the sides. As computing the number is time +;; gomoku-nil-score. Therefore, the score of any square is gomoku-nil-score times the number +;; of qtuples that pass through it. This number is 3 in a corner and 20 if you +;; are sufficiently far from the sides. As computing the number is time ;; consuming, we initialize every square with 20*gomoku-nil-score and then only -;; consider squares at less than 5 squares from one side. We speed this up by +;; consider squares at less than 5 squares from one side. We speed this up by ;; taking symmetry into account. ;; Also, as it is likely that successive games will be played on a board with ;; same size, it is a good idea to save the initial SCORE-TABLE configuration. @@ -451,7 +450,7 @@ Other useful commands:\n "Return the number of qtuples containing square I,J." ;; This function is complicated because we have to deal ;; with ugly cases like 3 by 6 boards, but it works. - ;; If you have a simpler (and correct) solution, send it to me. Thanks ! + ;; If you have a simpler (and correct) solution, send it to me. Thanks ! (let ((left (min 4 (1- i))) (right (min 4 (- gomoku-board-width i))) (up (min 4 (1- j))) @@ -477,9 +476,9 @@ Other useful commands:\n ;;; ;; We do not provide functions for computing the SCORE-TABLE given the -;; contents of the BOARD. This would involve heavy nested loops, with time -;; proportional to the size of the board. It is better to update the -;; SCORE-TABLE after each move. Updating needs not modify more than 36 +;; contents of the BOARD. This would involve heavy nested loops, with time +;; proportional to the size of the board. It is better to update the +;; SCORE-TABLE after each move. Updating needs not modify more than 36 ;; squares: it is done in constant time. (defun gomoku-update-score-table (square dval) commit 62cda6acd61f6de2698674391a26ce0a8672fc93 Author: Stefan Monnier Date: Mon Feb 15 23:54:45 2021 -0500 * lisp/emacs-lisp/bindat.el: Add 64bit int support (bindat--unpack-u64, bindat--unpack-u64r, bindat--pack-u64) (bindat--pack-u64r): New functions. (bindat--unpack-item, bindat--pack-item): Use them. (bindat--fixed-length-alist): Add new types. diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 661e56d276..bb4c57a619 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -3404,10 +3404,15 @@ Unsigned integer in network byte order, with length 3. @itemx long Unsigned integer in network byte order, with length 4. +@item u64 +Unsigned integer in network byte order, with length 8. + @item u16r @itemx u24r @itemx u32r -Unsigned integer in little endian order, with length 2, 3 and 4, respectively. +@itemx u64r +Unsigned integer in little endian order, with length 2, 3, 4, and +8, respectively. @item str @var{len} String of length @var{len}. @@ -3545,7 +3550,7 @@ array, and @var{struct} to an alist representing unpacked field data. @defun bindat-unpack spec raw &optional idx @c FIXME? Again, no multibyte? This function unpacks data from the unibyte string or byte -array var{raw} +array @var{raw} according to @var{spec}. Normally, this starts unpacking at the beginning of the byte array, but if @var{idx} is non-@code{nil}, it specifies a zero-based starting position to use instead. @@ -3586,7 +3591,7 @@ the data in the alist @var{struct}. It normally creates and fills a new byte array starting at the beginning. However, if @var{raw} is non-@code{nil}, it specifies a pre-allocated unibyte string or vector to pack into. If @var{idx} is non-@code{nil}, it specifies the starting -offset for packing into var{raw}. +offset for packing into @var{raw}. When pre-allocating, you should make sure @code{(length @var{raw})} meets or exceeds the total length to avoid an out-of-range error. diff --git a/etc/NEWS b/etc/NEWS index 3ac9bb21bd..943ad6ac59 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -357,8 +357,11 @@ the buffer cycles the whole buffer between "only top-level headings", It used to be enabled when Emacs is started in GUI mode but not when started in text mode. The cursor still only actually blinks in GUI frames. +** Bindat +++ -** Bindat has a new 'bindat-spec' macro to define specs, with Edebug support +*** New types 'u64' and 'u64r' ++++ +*** New macro 'bindat-spec' to define specs, with Edebug support ** pcase +++ diff --git a/lisp/emacs-lisp/bindat.el b/lisp/emacs-lisp/bindat.el index eafcdc7760..1f5022c274 100644 --- a/lisp/emacs-lisp/bindat.el +++ b/lisp/emacs-lisp/bindat.el @@ -146,7 +146,8 @@ ;; | u16 | word | short -- length 2, network byte order ;; | u24 -- 3-byte value ;; | u32 | dword | long -- length 4, network byte order -;; | u16r | u24r | u32r -- little endian byte order. +;; | u64 -- length 8, network byte order +;; | u16r | u24r | u32r | u64r - little endian byte order. ;; | str LEN -- LEN byte string ;; | strz LEN -- LEN byte (zero-terminated) string ;; | vec LEN [TYPE] -- vector of LEN items of TYPE (default: u8) @@ -214,6 +215,9 @@ (defun bindat--unpack-u32 () (logior (ash (bindat--unpack-u16) 16) (bindat--unpack-u16))) +(defun bindat--unpack-u64 () + (logior (ash (bindat--unpack-u32) 32) (bindat--unpack-u32))) + (defun bindat--unpack-u16r () (logior (bindat--unpack-u8) (ash (bindat--unpack-u8) 8))) @@ -223,6 +227,9 @@ (defun bindat--unpack-u32r () (logior (bindat--unpack-u16r) (ash (bindat--unpack-u16r) 16))) +(defun bindat--unpack-u64r () + (logior (bindat--unpack-u32r) (ash (bindat--unpack-u32r) 32))) + (defun bindat--unpack-item (type len &optional vectype) (if (eq type 'ip) (setq type 'vec len 4)) @@ -231,16 +238,14 @@ (bindat--unpack-u8)) ((or 'u16 'word 'short) (bindat--unpack-u16)) - ('u24 - (bindat--unpack-u24)) + ('u24 (bindat--unpack-u24)) ((or 'u32 'dword 'long) (bindat--unpack-u32)) - ('u16r - (bindat--unpack-u16r)) - ('u24r - (bindat--unpack-u24r)) - ('u32r - (bindat--unpack-u32r)) + ('u64 (bindat--unpack-u64)) + ('u16r (bindat--unpack-u16r)) + ('u24r (bindat--unpack-u24r)) + ('u32r (bindat--unpack-u32r)) + ('u64r (bindat--unpack-u64r)) ('bits (let ((bits nil) (bnum (1- (* 8 len))) j m) (while (>= bnum 0) @@ -374,6 +379,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (u16 . 2) (u16r . 2) (word . 2) (short . 2) (u24 . 3) (u24r . 3) (u32 . 4) (u32r . 4) (dword . 4) (long . 4) + (u64 . 8) (u64r . 8) (ip . 4))) (defun bindat--length-group (struct spec) @@ -471,6 +477,10 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (bindat--pack-u16 (ash v -16)) (bindat--pack-u16 v)) +(defun bindat--pack-u64 (v) + (bindat--pack-u32 (ash v -32)) + (bindat--pack-u32 v)) + (defun bindat--pack-u16r (v) (aset bindat-raw (1+ bindat-idx) (logand (ash v -8) 255)) (aset bindat-raw bindat-idx (logand v 255)) @@ -484,6 +494,10 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (bindat--pack-u16r v) (bindat--pack-u16r (ash v -16))) +(defun bindat--pack-u64r (v) + (bindat--pack-u32r v) + (bindat--pack-u32r (ash v -32))) + (defun bindat--pack-item (v type len &optional vectype) (if (eq type 'ip) (setq type 'vec len 4)) @@ -498,12 +512,11 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (bindat--pack-u24 v)) ((or 'u32 'dword 'long) (bindat--pack-u32 v)) - ('u16r - (bindat--pack-u16r v)) - ('u24r - (bindat--pack-u24r v)) - ('u32r - (bindat--pack-u32r v)) + ('u64 (bindat--pack-u64 v)) + ('u16r (bindat--pack-u16r v)) + ('u24r (bindat--pack-u24r v)) + ('u32r (bindat--pack-u32r v)) + ('u64r (bindat--pack-u64r v)) ('bits (let ((bnum (1- (* 8 len))) j m) (while (>= bnum 0) @@ -518,11 +531,9 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." j (ash j -1)))) (bindat--pack-u8 m)))) ((or 'str 'strz) - (let ((l (length v))) - (if (> l len) (setq l len)) - (dotimes (i l) - (aset bindat-raw (+ bindat-idx i) (aref v i))) - (setq bindat-idx (+ bindat-idx len)))) + (dotimes (i (min len (length v))) + (aset bindat-raw (+ bindat-idx i) (aref v i))) + (setq bindat-idx (+ bindat-idx len))) ('vec (let ((l (length v)) (vlen 1)) (if (consp vectype) commit 9b8cf1a38d100d4b860a52ae0349413a37a211db Author: Stefan Kangas Date: Tue Feb 16 05:26:24 2021 +0100 Fix admin/check-doc-strings for new DEFUN format * admin/check-doc-strings: Various fixes, including for the new DEFUN format. The script still produces a ton of false positives, however. diff --git a/admin/check-doc-strings b/admin/check-doc-strings index 63856d3287..135090b34c 100755 --- a/admin/check-doc-strings +++ b/admin/check-doc-strings @@ -59,7 +59,7 @@ sub Check_texi_function { $arglist_parm{$parm} = 1; } - foreach my $parm ($docstring =~ /\@var{([^{}]+)}/g) { + foreach my $parm ($docstring =~ /\@var\{([^{}]+)\}/g) { $docstring_parm{$parm} = 1; } @@ -111,7 +111,9 @@ sub Check_function { # $arglist_parm{$parm} = 1; #} foreach my $parm (@parms) { - next if $parm eq '&optional' || $parm eq '&rest'; + next if $parm eq '&optional' + || $parm eq '&rest' + || $parm eq 'Lisp-Object'; $arglist_parm{$parm} = 1; } my $doc_tmp = $docstring; @@ -150,6 +152,22 @@ sub Check_function { next if $parm eq 'primary'; next if $parm eq 'secondary'; next if $parm eq 'clipboard'; + next if $parm eq 'bbdb'; + next if $parm eq 'dos'; + next if $parm eq 'erc'; + next if $parm eq 'exif'; + next if $parm eq 'ldap'; + next if $parm eq 'ime'; + next if $parm eq 'rfc'; + next if $parm eq 'ms-dos'; + next if $parm eq 'url'; + next if $parm eq 'w32'; + next if $parm eq 'todo'; # org-mode + next if $parm eq 'done'; # org-mode + next if $parm eq 'waiting'; #org-mode + next if $parm eq 'ordered'; #org-mode + next if $parm eq 'deadline'; #org-mode + next if $parm eq 'scheduled'; #org-mode next if length $parm < 3; if (! exists $arglist_parm{$parm}) { print "bogus parm: $function: $parm\n"; @@ -228,20 +246,43 @@ open (FIND, "find src -name '*.c' -print |") or die; while (my $file = ) { my @matches = ((FileContents $file) =~ - /\bDEFUN\s*\(\s*\"((?:[^\\\"]|\\.)+)\"\s*,\s*\S+\s*,\s*(\S+)\s*,\s*(\S+)\s*,\s*((?:0|\"(?:(?:[^\\\"]|\\.)*)\"))\s*,\s*\/\*(.*?)\*\/\s*\(([^()]*)\)\)/sgo); + /\b + DEFUN\s*\(\s* + ## $function + \"((?:[^\\\"]|\\.)+)\"\s*, + \s*\S+\s*, \s*\S+\s*, + ## $minargs + \s*(\S+)\s*, + ## $maxargs + \s*(\S+)\s*, + ## $interactive + \s*((?:0|\"(?:(?:[^\\\"]|\\.)*)\"))\s*, + ## $docstring + \s*doc:\s*\/\*\s*(.*?)\s*\*\/ + # attributes -- skip + (?:\s*attributes:\s* + (?:noreturn|const) + \s*)? + \s*\) + ### $parms + \s*\( + ([^()]*) + \) + /sgox); while (@matches) { my ($function, $minargs, $maxargs, $interactive, $docstring, $parms) = splice (@matches, 0, 6); $docstring =~ s/^\n+//s; $docstring =~ s/\n+$//s; $parms =~ s/,/ /g; - my @parms = split (' ',$parms); + my @parms = $parms eq 'void' ? () : split (' ', $parms); for (@parms) { tr/_/-/; s/-$//; } if ($parms !~ /Lisp_Object/) { if ($minargs < @parms) { - if ($maxargs =~ /^\d+$/) { - die unless $maxargs eq @parms; - splice (@parms, $minargs, 0, '&optional'); - } + if ($maxargs =~ /^\d+$/) { + die "$function: $maxargs" + unless $maxargs eq @parms; + splice (@parms, $minargs, 0, '&optional'); + } } } my $funtype = ($interactive =~ /\"/ ? 'Command' : 'Function'); commit a0b35e2f80df98a3789286af8f68e85fddf368db Author: Stefan Monnier Date: Mon Feb 15 23:22:09 2021 -0500 * lisp/emacs-lisp/bindat.el: Clarify when field labels are optional The fixes the doc and the Edebug spec, as well as a subtle issue in the code where a field whose name is (eval 'fill) was mistakenly considered as an anonymous field of type `fill`. (bindat--unpack-item, bindat--unpack-group, bindat--length-group) (bindat--pack-item, bindat--pack-group): Use dotimes, dolist, and pcase. (bindat--item-aux): New edebug elem. (bindat-item): Use it to fix the handling of optional fields. (bindat-format-vector): Use `mapconcat`. diff --git a/lisp/emacs-lisp/bindat.el b/lisp/emacs-lisp/bindat.el index 0bb4b87070..eafcdc7760 100644 --- a/lisp/emacs-lisp/bindat.el +++ b/lisp/emacs-lisp/bindat.el @@ -129,13 +129,13 @@ ;; SPEC ::= ( ITEM... ) -;; ITEM ::= ( [FIELD] TYPE ) +;; ITEM ::= ( FIELD TYPE ) ;; | ( [FIELD] eval FORM ) -- eval FORM for side-effect only ;; | ( [FIELD] fill LEN ) -- skip LEN bytes ;; | ( [FIELD] align LEN ) -- skip to next multiple of LEN bytes ;; | ( [FIELD] struct SPEC_NAME ) ;; | ( [FIELD] union TAG_VAL (TAG SPEC)... [(t SPEC)] ) -;; | ( [FIELD] repeat COUNT ITEM... ) +;; | ( FIELD repeat ARG ITEM... ) ;; -- In (eval EXPR), the value of the last field is available in ;; the dynamically bound variable `last' and all the previous @@ -151,7 +151,7 @@ ;; | strz LEN -- LEN byte (zero-terminated) string ;; | vec LEN [TYPE] -- vector of LEN items of TYPE (default: u8) ;; | ip -- 4 byte vector -;; | bits LEN -- List with bits set in LEN bytes. +;; | bits LEN -- bit vector using LEN bytes. ;; ;; -- Example: `bits 2' will unpack 0x28 0x1c to (2 3 4 11 13) ;; and 0x1c 0x28 to (3 5 10 11 12). @@ -226,22 +226,22 @@ (defun bindat--unpack-item (type len &optional vectype) (if (eq type 'ip) (setq type 'vec len 4)) - (cond - ((memq type '(u8 byte)) + (pcase type + ((or 'u8 'byte) (bindat--unpack-u8)) - ((memq type '(u16 word short)) + ((or 'u16 'word 'short) (bindat--unpack-u16)) - ((eq type 'u24) + ('u24 (bindat--unpack-u24)) - ((memq type '(u32 dword long)) + ((or 'u32 'dword 'long) (bindat--unpack-u32)) - ((eq type 'u16r) + ('u16r (bindat--unpack-u16r)) - ((eq type 'u24r) + ('u24r (bindat--unpack-u24r)) - ((eq type 'u32r) + ('u32r (bindat--unpack-u32r)) - ((eq type 'bits) + ('bits (let ((bits nil) (bnum (1- (* 8 len))) j m) (while (>= bnum 0) (if (= (setq m (bindat--unpack-u8)) 0) @@ -253,12 +253,12 @@ (setq bnum (1- bnum) j (ash j -1))))) bits)) - ((eq type 'str) + ('str (let ((s (substring bindat-raw bindat-idx (+ bindat-idx len)))) (setq bindat-idx (+ bindat-idx len)) (if (stringp s) s (apply #'unibyte-string s)))) - ((eq type 'strz) + ('strz (let ((i 0) s) (while (and (< i len) (/= (aref bindat-raw (+ bindat-idx i)) 0)) (setq i (1+ i))) @@ -266,34 +266,29 @@ (setq bindat-idx (+ bindat-idx len)) (if (stringp s) s (apply #'unibyte-string s)))) - ((eq type 'vec) - (let ((v (make-vector len 0)) (i 0) (vlen 1)) + ('vec + (let ((v (make-vector len 0)) (vlen 1)) (if (consp vectype) (setq vlen (nth 1 vectype) vectype (nth 2 vectype)) (setq type (or vectype 'u8) vectype nil)) - (while (< i len) - (aset v i (bindat--unpack-item type vlen vectype)) - (setq i (1+ i))) + (dotimes (i len) + (aset v i (bindat--unpack-item type vlen vectype))) v)) - (t nil))) + (_ nil))) (defun bindat--unpack-group (spec) (with-suppressed-warnings ((lexical struct last)) (defvar struct) (defvar last)) (let (struct last) - (while spec - (let* ((item (car spec)) - (field (car item)) + (dolist (item spec) + (let* ((field (car item)) (type (nth 1 item)) (len (nth 2 item)) (vectype (and (eq type 'vec) (nth 3 item))) (tail 3) data) - (setq spec (cdr spec)) - (if (and (consp field) (eq (car field) 'eval)) - (setq field (eval (car (cdr field)) t))) (if (and type (consp type) (eq (car type) 'eval)) (setq type (eval (car (cdr type)) t))) (if (and len (consp len) (eq (car len) 'eval)) @@ -303,29 +298,29 @@ len type type field field nil)) + (if (and (consp field) (eq (car field) 'eval)) + (setq field (eval (car (cdr field)) t))) (if (and (consp len) (not (eq type 'eval))) (setq len (apply #'bindat-get-field struct len))) (if (not len) (setq len 1)) - (cond - ((eq type 'eval) + (pcase type + ('eval (if field (setq data (eval len t)) (eval len t))) - ((eq type 'fill) + ('fill (setq bindat-idx (+ bindat-idx len))) - ((eq type 'align) + ('align (while (/= (% bindat-idx len) 0) (setq bindat-idx (1+ bindat-idx)))) - ((eq type 'struct) + ('struct (setq data (bindat--unpack-group (eval len t)))) - ((eq type 'repeat) - (let ((index 0) (count len)) - (while (< index count) - (push (bindat--unpack-group (nthcdr tail item)) data) - (setq index (1+ index))) - (setq data (nreverse data)))) - ((eq type 'union) + ('repeat + (dotimes (_ len) + (push (bindat--unpack-group (nthcdr tail item)) data)) + (setq data (nreverse data))) + ('union (with-suppressed-warnings ((lexical tag)) (defvar tag)) (let ((tag len) (cases (nthcdr tail item)) case cc) @@ -337,7 +332,8 @@ (and (consp cc) (eval cc t))) (setq data (bindat--unpack-group (cdr case)) cases nil))))) - (t + ((pred integerp) (debug t)) + (_ (setq data (bindat--unpack-item type len vectype) last data))) (if data @@ -384,16 +380,12 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (with-suppressed-warnings ((lexical struct last)) (defvar struct) (defvar last)) (let ((struct struct) last) - (while spec - (let* ((item (car spec)) - (field (car item)) + (dolist (item spec) + (let* ((field (car item)) (type (nth 1 item)) (len (nth 2 item)) (vectype (and (eq type 'vec) (nth 3 item))) (tail 3)) - (setq spec (cdr spec)) - (if (and (consp field) (eq (car field) 'eval)) - (setq field (eval (car (cdr field)) t))) (if (and type (consp type) (eq (car type) 'eval)) (setq type (eval (car (cdr type)) t))) (if (and len (consp len) (eq (car len) 'eval)) @@ -403,6 +395,8 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." len type type field field nil)) + (if (and (consp field) (eq (car field) 'eval)) + (setq field (eval (car (cdr field)) t))) (if (and (consp len) (not (eq type 'eval))) (setq len (apply #'bindat-get-field struct len))) (if (not len) @@ -413,27 +407,25 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." type (nth 2 vectype)) (setq type (or vectype 'u8) vectype nil))) - (cond - ((eq type 'eval) + (pcase type + ('eval (if field (setq struct (cons (cons field (eval len t)) struct)) (eval len t))) - ((eq type 'fill) + ('fill (setq bindat-idx (+ bindat-idx len))) - ((eq type 'align) + ('align (while (/= (% bindat-idx len) 0) (setq bindat-idx (1+ bindat-idx)))) - ((eq type 'struct) + ('struct (bindat--length-group (if field (bindat-get-field struct field) struct) (eval len t))) - ((eq type 'repeat) - (let ((index 0) (count len)) - (while (< index count) - (bindat--length-group - (nth index (bindat-get-field struct field)) - (nthcdr tail item)) - (setq index (1+ index))))) - ((eq type 'union) + ('repeat + (dotimes (index len) + (bindat--length-group + (nth index (bindat-get-field struct field)) + (nthcdr tail item)))) + ('union (with-suppressed-warnings ((lexical tag)) (defvar tag)) (let ((tag len) (cases (nthcdr tail item)) case cc) @@ -446,7 +438,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (progn (bindat--length-group struct (cdr case)) (setq cases nil)))))) - (t + (_ (if (setq type (assq type bindat--fixed-length-alist)) (setq len (* len (cdr type)))) (if field @@ -495,24 +487,24 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (defun bindat--pack-item (v type len &optional vectype) (if (eq type 'ip) (setq type 'vec len 4)) - (cond - ((null v) + (pcase type + ((guard (null v)) (setq bindat-idx (+ bindat-idx len))) - ((memq type '(u8 byte)) + ((or 'u8 'byte) (bindat--pack-u8 v)) - ((memq type '(u16 word short)) + ((or 'u16 'word 'short) (bindat--pack-u16 v)) - ((eq type 'u24) + ('u24 (bindat--pack-u24 v)) - ((memq type '(u32 dword long)) + ((or 'u32 'dword 'long) (bindat--pack-u32 v)) - ((eq type 'u16r) + ('u16r (bindat--pack-u16r v)) - ((eq type 'u24r) + ('u24r (bindat--pack-u24r v)) - ((eq type 'u32r) + ('u32r (bindat--pack-u32r v)) - ((eq type 'bits) + ('bits (let ((bnum (1- (* 8 len))) j m) (while (>= bnum 0) (setq m 0) @@ -525,41 +517,35 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (setq bnum (1- bnum) j (ash j -1)))) (bindat--pack-u8 m)))) - ((memq type '(str strz)) - (let ((l (length v)) (i 0)) + ((or 'str 'strz) + (let ((l (length v))) (if (> l len) (setq l len)) - (while (< i l) - (aset bindat-raw (+ bindat-idx i) (aref v i)) - (setq i (1+ i))) + (dotimes (i l) + (aset bindat-raw (+ bindat-idx i) (aref v i))) (setq bindat-idx (+ bindat-idx len)))) - ((eq type 'vec) - (let ((l (length v)) (i 0) (vlen 1)) + ('vec + (let ((l (length v)) (vlen 1)) (if (consp vectype) (setq vlen (nth 1 vectype) vectype (nth 2 vectype)) (setq type (or vectype 'u8) vectype nil)) (if (> l len) (setq l len)) - (while (< i l) - (bindat--pack-item (aref v i) type vlen vectype) - (setq i (1+ i))))) - (t + (dotimes (i l) + (bindat--pack-item (aref v i) type vlen vectype)))) + (_ (setq bindat-idx (+ bindat-idx len))))) (defun bindat--pack-group (struct spec) (with-suppressed-warnings ((lexical struct last)) (defvar struct) (defvar last)) (let ((struct struct) last) - (while spec - (let* ((item (car spec)) - (field (car item)) + (dolist (item spec) + (let* ((field (car item)) (type (nth 1 item)) (len (nth 2 item)) (vectype (and (eq type 'vec) (nth 3 item))) (tail 3)) - (setq spec (cdr spec)) - (if (and (consp field) (eq (car field) 'eval)) - (setq field (eval (car (cdr field)) t))) (if (and type (consp type) (eq (car type) 'eval)) (setq type (eval (car (cdr type)) t))) (if (and len (consp len) (eq (car len) 'eval)) @@ -569,31 +555,31 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." len type type field field nil)) + (if (and (consp field) (eq (car field) 'eval)) + (setq field (eval (car (cdr field)) t))) (if (and (consp len) (not (eq type 'eval))) (setq len (apply #'bindat-get-field struct len))) (if (not len) (setq len 1)) - (cond - ((eq type 'eval) + (pcase type + ('eval (if field (setq struct (cons (cons field (eval len t)) struct)) (eval len t))) - ((eq type 'fill) + ('fill (setq bindat-idx (+ bindat-idx len))) - ((eq type 'align) + ('align (while (/= (% bindat-idx len) 0) (setq bindat-idx (1+ bindat-idx)))) - ((eq type 'struct) + ('struct (bindat--pack-group (if field (bindat-get-field struct field) struct) (eval len t))) - ((eq type 'repeat) - (let ((index 0) (count len)) - (while (< index count) - (bindat--pack-group - (nth index (bindat-get-field struct field)) - (nthcdr tail item)) - (setq index (1+ index))))) - ((eq type 'union) + ('repeat + (dotimes (index len) + (bindat--pack-group + (nth index (bindat-get-field struct field)) + (nthcdr tail item)))) + ('union (with-suppressed-warnings ((lexical tag)) (defvar tag)) (let ((tag len) (cases (nthcdr tail item)) case cc) @@ -606,7 +592,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (progn (bindat--pack-group struct (cdr case)) (setq cases nil)))))) - (t + (_ (setq last (bindat-get-field struct field)) (bindat--pack-item last type len vectype) )))))) @@ -629,15 +615,21 @@ Optional fourth arg IDX is the starting offset into RAW." (def-edebug-elem-spec 'bindat-spec '(&rest bindat-item)) + +(def-edebug-elem-spec 'bindat--item-aux + ;; Field types which can come without a field label. + '(&or ["eval" form] + ["fill" bindat-len] + ["align" bindat-len] + ["struct" form] ;A reference to another bindat-spec. + ["union" bindat-tag-val &rest (bindat-tag bindat-spec)])) + (def-edebug-elem-spec 'bindat-item - '(([&optional bindat-field] - &or ["eval" form] - ["fill" bindat-len] - ["align" bindat-len] - ["struct" form] ;A reference to another bindat-spec. - ["union" bindat-tag-val &rest (bindat-tag bindat-spec)] - ["repeat" integerp bindat-spec] - bindat-type))) + '((&or bindat--item-aux ;Without label.. + [bindat-field ;..or with label + &or bindat--item-aux + ["repeat" bindat-arg bindat-spec] + bindat-type]))) (def-edebug-elem-spec 'bindat-type '(&or ("eval" form) @@ -672,13 +664,8 @@ Optional fourth arg IDX is the starting offset into RAW." Result is a string with each element of VECT formatted using FMT and separated by the string SEP. If optional fourth arg LEN is given, use only that many elements from VECT." - (unless len - (setq len (length vect))) - (let ((i len) (fmt2 (concat sep fmt)) (s nil)) - (while (> i 0) - (setq i (1- i) - s (cons (format (if (= i 0) fmt fmt2) (aref vect i)) s))) - (apply #'concat s))) + (when len (setq vect (substring vect 0 len))) + (mapconcat (lambda (x) (format fmt x)) vect sep)) (defun bindat-vector-to-dec (vect &optional sep) "Format vector VECT in decimal format separated by dots. commit 83d9fbe3bb8ffdf9e4719842e2510a8dbde86f78 Author: Stefan Monnier Date: Mon Feb 15 21:25:15 2021 -0500 * lisp/emacs-lisp/bindat.el (bindat-spec): New macro. It's basically an alias for `quote`, but it offers the advantage of providing Edebug support and opens the possibility of compiling the bindat spec to ELisp code. * doc/lispref/processes.texi (Bindat Spec): Document `bindat-spec`. (Bindat Functions): Tweak a few things to adjust to the state of the code. * test/lisp/emacs-lisp/bindat-tests.el: Use it. * test/lisp/emacs-lisp/edebug-tests.el (edebug-tests--read): New function. (edebug-tests--&rest-behavior): New test. diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 8346165606..661e56d276 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -3368,6 +3368,11 @@ processed, and how to pack or unpack it. We normally keep bindat specs in variables whose names end in @samp{-bindat-spec}; that kind of name is automatically recognized as risky. +@defmac bindat-spec &rest specs +Creates a Bindat spec object according to the data layout +specification @var{specs}. +@end defmac + @cindex endianness @cindex big endian @cindex little endian @@ -3398,7 +3403,6 @@ Unsigned integer in network byte order, with length 3. @itemx dword @itemx long Unsigned integer in network byte order, with length 4. -Note: These values may be limited by Emacs's integer implementation limits. @item u16r @itemx u24r @@ -3534,16 +3538,16 @@ repetition has completed. @node Bindat Functions @subsection Functions to Unpack and Pack Bytes - In the following documentation, @var{spec} refers to a data layout -specification, @code{bindat-raw} to a byte array, and @var{struct} to an -alist representing unpacked field data. + In the following documentation, @var{spec} refers to a Bindat spec +object as returned from @code{bindat-spec}, @code{raw} to a byte +array, and @var{struct} to an alist representing unpacked field data. -@defun bindat-unpack spec bindat-raw &optional bindat-idx +@defun bindat-unpack spec raw &optional idx @c FIXME? Again, no multibyte? This function unpacks data from the unibyte string or byte -array @code{bindat-raw} +array var{raw} according to @var{spec}. Normally, this starts unpacking at the -beginning of the byte array, but if @var{bindat-idx} is non-@code{nil}, it +beginning of the byte array, but if @var{idx} is non-@code{nil}, it specifies a zero-based starting position to use instead. The value is an alist or nested alist in which each element describes @@ -3576,15 +3580,15 @@ This function returns the total length of the data in @var{struct}, according to @var{spec}. @end defun -@defun bindat-pack spec struct &optional bindat-raw bindat-idx +@defun bindat-pack spec struct &optional raw idx This function returns a byte array packed according to @var{spec} from the data in the alist @var{struct}. It normally creates and fills a -new byte array starting at the beginning. However, if @var{bindat-raw} +new byte array starting at the beginning. However, if @var{raw} is non-@code{nil}, it specifies a pre-allocated unibyte string or vector to -pack into. If @var{bindat-idx} is non-@code{nil}, it specifies the starting -offset for packing into @code{bindat-raw}. +pack into. If @var{idx} is non-@code{nil}, it specifies the starting +offset for packing into var{raw}. -When pre-allocating, you should make sure @code{(length @var{bindat-raw})} +When pre-allocating, you should make sure @code{(length @var{raw})} meets or exceeds the total length to avoid an out-of-range error. @end defun diff --git a/etc/NEWS b/etc/NEWS index 7f32f7bf6a..3ac9bb21bd 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -357,6 +357,8 @@ the buffer cycles the whole buffer between "only top-level headings", It used to be enabled when Emacs is started in GUI mode but not when started in text mode. The cursor still only actually blinks in GUI frames. ++++ +** Bindat has a new 'bindat-spec' macro to define specs, with Edebug support ** pcase +++ diff --git a/lisp/emacs-lisp/bindat.el b/lisp/emacs-lisp/bindat.el index bf01347ae0..0bb4b87070 100644 --- a/lisp/emacs-lisp/bindat.el +++ b/lisp/emacs-lisp/bindat.el @@ -65,13 +65,15 @@ ;; The corresponding Lisp bindat specification looks like this: ;; ;; (setq header-bindat-spec -;; '((dest-ip ip) +;; (bindat-spec +;; (dest-ip ip) ;; (src-ip ip) ;; (dest-port u16) ;; (src-port u16))) ;; ;; (setq data-bindat-spec -;; '((type u8) +;; (bindat-spec +;; (type u8) ;; (opcode u8) ;; (length u16r) ;; little endian order ;; (id strz 8) @@ -79,7 +81,8 @@ ;; (align 4))) ;; ;; (setq packet-bindat-spec -;; '((header struct header-bindat-spec) +;; (bindat-spec +;; (header struct header-bindat-spec) ;; (items u8) ;; (fill 3) ;; (item repeat (items) @@ -179,7 +182,7 @@ ;; is interpreted by evalling TAG_VAL and then comparing that to ;; each TAG using equal; if a match is found, the corresponding SPEC ;; is used. -;; If TAG is a form (eval EXPR), EXPR is evalled with `tag' bound to the +;; If TAG is a form (eval EXPR), EXPR is eval'ed with `tag' bound to the ;; value of TAG_VAL; the corresponding SPEC is used if the result is non-nil. ;; Finally, if TAG is t, the corresponding SPEC is used unconditionally. ;; @@ -368,8 +371,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (setq field (cdr field))) struct) - -;; Calculate bindat-raw length of structured data +;;;; Calculate bindat-raw length of structured data (defvar bindat--fixed-length-alist '((u8 . 1) (byte . 1) @@ -452,13 +454,13 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (setq bindat-idx (+ bindat-idx len)))))))) (defun bindat-length (spec struct) - "Calculate bindat-raw length for STRUCT according to bindat SPEC." + "Calculate `bindat-raw' length for STRUCT according to bindat SPEC." (let ((bindat-idx 0)) (bindat--length-group struct spec) bindat-idx)) -;; Pack structured data into bindat-raw +;;;; Pack structured data into bindat-raw (defun bindat--pack-u8 (v) (aset bindat-raw bindat-idx (logand v 255)) @@ -623,8 +625,47 @@ Optional fourth arg IDX is the starting offset into RAW." (bindat--pack-group struct spec) (if raw nil bindat-raw))) +;;;; Debugging support + +(def-edebug-elem-spec 'bindat-spec '(&rest bindat-item)) + +(def-edebug-elem-spec 'bindat-item + '(([&optional bindat-field] + &or ["eval" form] + ["fill" bindat-len] + ["align" bindat-len] + ["struct" form] ;A reference to another bindat-spec. + ["union" bindat-tag-val &rest (bindat-tag bindat-spec)] + ["repeat" integerp bindat-spec] + bindat-type))) + +(def-edebug-elem-spec 'bindat-type + '(&or ("eval" form) + ["str" bindat-len] + ["strz" bindat-len] + ["vec" bindat-len &optional bindat-type] + ["bits" bindat-len] + symbolp)) + +(def-edebug-elem-spec 'bindat-field + '(&or ("eval" form) symbolp)) + +(def-edebug-elem-spec 'bindat-len '(&or [] "nil" bindat-arg)) + +(def-edebug-elem-spec 'bindat-tag-val '(bindat-arg)) + +(def-edebug-elem-spec 'bindat-tag '(&or ("eval" form) atom)) + +(def-edebug-elem-spec 'bindat-arg + '(&or ("eval" form) integerp (&rest symbolp integerp))) + +(defmacro bindat-spec (&rest fields) + "Build the bindat spec described by FIELDS." + (declare (indent 0) (debug (bindat-spec))) + ;; FIXME: We should really "compile" this to a triplet of functions! + `',fields) -;; Misc. format conversions +;;;; Misc. format conversions (defun bindat-format-vector (vect fmt sep &optional len) "Format vector VECT using element format FMT and separator SEP. diff --git a/test/lisp/emacs-lisp/bindat-tests.el b/test/lisp/emacs-lisp/bindat-tests.el index a9a881987c..72883fc2ec 100644 --- a/test/lisp/emacs-lisp/bindat-tests.el +++ b/test/lisp/emacs-lisp/bindat-tests.el @@ -24,13 +24,15 @@ (require 'cl-lib) (defvar header-bindat-spec - '((dest-ip ip) + (bindat-spec + (dest-ip ip) (src-ip ip) (dest-port u16) (src-port u16))) (defvar data-bindat-spec - '((type u8) + (bindat-spec + (type u8) (opcode u8) (length u16r) ;; little endian order (id strz 8) @@ -38,7 +40,8 @@ (align 4))) (defvar packet-bindat-spec - '((header struct header-bindat-spec) + (bindat-spec + (header struct header-bindat-spec) (items u8) (fill 3) (item repeat (items) diff --git a/test/lisp/emacs-lisp/edebug-tests.el b/test/lisp/emacs-lisp/edebug-tests.el index d81376e45e..daac43372a 100644 --- a/test/lisp/emacs-lisp/edebug-tests.el +++ b/test/lisp/emacs-lisp/edebug-tests.el @@ -970,6 +970,23 @@ primary ones (Bug#42671)." (eval '(setf (edebug-test-code-use-gv-expander (cons 'a 'b)) 3) t)) "(func")))) +(defun edebug-tests--read (form spec) + (with-temp-buffer + (print form (current-buffer)) + (goto-char (point-min)) + (cl-letf ((edebug-all-forms t) + ((get (car form) 'edebug-form-spec) spec)) + (edebug--read nil (current-buffer))))) + +(ert-deftest edebug-tests--&rest-behavior () + ;; `&rest' is documented to allow the last "repetition" to be aborted early. + (should (edebug-tests--read '(dummy x 1 y 2 z) + '(&rest symbolp integerp))) + ;; `&rest' should notice here that the "symbolp integerp" sequence + ;; is not respected. + (should-error (edebug-tests--read '(dummy x 1 2 y) + '(&rest symbolp integerp)))) + (ert-deftest edebug-tests-cl-flet () "Check that Edebug can instrument `cl-flet' forms without name clashes (Bug#41853)." commit 2106b12fa751094d1b754b50e6dcad2a19e8f02a Author: Basil L. Contovounesios Date: Mon Feb 15 21:50:38 2021 +0000 ; Fix last change in simple.el. diff --git a/lisp/simple.el b/lisp/simple.el index 8a9f46cef6..215f4399f4 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1906,14 +1906,14 @@ to get different commands to edit and resubmit." (defcustom read-extended-command-predicate #'completion-default-include-p "Predicate to use to determine which commands to include when completing. -The predicate function is called with two parameter: The +The predicate function is called with two parameters: The symbol (i.e., command) in question that should be included or not, and the current buffer. The predicate should return non-nil if the command should be present when doing `M-x TAB'." :version "28.1" - :type '(choice (const :tag "Exclude commands not relevant to the current mode" - #'completion-default-include-p) - (const :tag "All commands" (lambda (_ _) t)) + :type `(choice (const :tag "Exclude commands not relevant to the current mode" + completion-default-include-p) + (const :tag "All commands" ,(lambda (_s _b) t)) (function :tag "Other function"))) (defun read-extended-command () commit d41a4ad4ae6f25c3cbc90aaaa33781821bb655c5 Author: Stefan Monnier Date: Mon Feb 15 12:07:52 2021 -0500 * lisp/emacs-lisp/macroexp.el (macroexp--expand-all): Warn on empty let bodies diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index 13ff5ef2ed..0934e43e66 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -299,7 +299,12 @@ Assumes the caller has bound `macroexpand-all-environment'." (`(,(and fun (or 'let 'let*)) . ,(or `(,bindings . ,body) dontcare)) (macroexp--cons fun (macroexp--cons (macroexp--all-clauses bindings 1) - (macroexp--all-forms body) + (if (null body) + (macroexp-unprogn + (macroexp--warn-and-return + (format "Empty %s body" fun) + nil t)) + (macroexp--all-forms body)) (cdr form)) form)) (`(,(and fun `(lambda . ,_)) . ,args) commit 899619ff6a73cc75880327ad74ec29f072328d79 Author: Ulf Jasper Date: Mon Feb 15 17:27:45 2021 +0100 Display yearly ical events from first year on. Fix Bug#23100. Convert yearly rrule starting in year x into diary-anniversary entry for year x-1 when importing an icalendar. Correspondingly convert diary-anniversary for year x into yearly rrule starting in year x+1. * test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-american: * test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-european: * test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-iso: * test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-american: * test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-european: * test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-iso: * test/lisp/calendar/icalendar-tests.el (icalendar-convert-anniversary-to-ical): Match new diary-anniversary/yearly-rrule behaviour. * lisp/calendar/icalendar.el (icalendar--datestring-to-isodate): Add year-shift option. (icalendar--convert-anniversary-to-ical): Shift the year as diary-anniversary is not displayed in the initial year. (icalendar--convert-recurring-to-diary): Shift the year as diary-anniversary is not displayed in the initial year. (Bug#23100) diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el index 1d7de4a0c5..dafdd418d0 100644 --- a/lisp/calendar/icalendar.el +++ b/lisp/calendar/icalendar.el @@ -889,12 +889,14 @@ If DAY-SHIFT is non-nil, the result is shifted by DAY-SHIFT days." (format "%04d%02d%02d" (nth 2 mdy) (nth 0 mdy) (nth 1 mdy)))) -(defun icalendar--datestring-to-isodate (datestring &optional day-shift) +(defun icalendar--datestring-to-isodate (datestring &optional day-shift year-shift) "Convert diary-style DATESTRING to iso-style date. If DAY-SHIFT is non-nil, the result is shifted by DAY-SHIFT days --- DAY-SHIFT must be either nil or an integer. This function -tries to figure the date style from DATESTRING itself. If that -is not possible it uses the current calendar date style." +-- DAY-SHIFT must be either nil or an integer. If YEAR-SHIFT is +non-nil, the result is shifted by YEAR-SHIFT years -- YEAR-SHIFT +must be either nil or an integer. This function tries to figure +the date style from DATESTRING itself. If that is not possible +it uses the current calendar date style." (let ((day -1) month year) (save-match-data (cond ( ;; iso-style numeric date @@ -904,7 +906,7 @@ is not possible it uses the current calendar date style." "0?\\([1-9][0-9]?\\)") datestring) (setq year (read (substring datestring (match-beginning 1) - (match-end 1)))) + (match-end 1)))) (setq month (read (substring datestring (match-beginning 2) (match-end 2)))) (setq day (read (substring datestring (match-beginning 3) @@ -967,6 +969,9 @@ is not possible it uses the current calendar date style." (match-end 3))))) (t nil))) + (when year-shift + (setq year (+ year year-shift))) + (if (> day 0) (let ((mdy (calendar-gregorian-from-absolute (+ (calendar-absolute-from-gregorian (list month day @@ -1916,9 +1921,9 @@ entries. ENTRY-MAIN is the first line of the diary entry." (let* ((datetime (substring entry-main (match-beginning 1) (match-end 1))) (startisostring (icalendar--datestring-to-isodate - datetime)) + datetime nil 1)) (endisostring (icalendar--datestring-to-isodate - datetime 1)) + datetime 1 1)) (starttimestring (icalendar--diarytime-to-isotime (if (match-beginning 3) (substring entry-main @@ -2402,8 +2407,11 @@ END-T is the event's end time in diary format." (if end-t "-" "") (or end-t "")))) (setq result (format - "%%%%(and (diary-anniversary %s)) %s%s%s" - dtstart-conv + "%%%%(diary-anniversary %s) %s%s%s" + (let* ((year (nth 5 dtstart-dec)) + (dtstart-1y-dec (copy-sequence dtstart-dec))) + (setf (nth 5 dtstart-1y-dec) (1- year)) + (icalendar--datetime-to-diary-date dtstart-1y-dec)) (or start-t "") (if end-t "-" "") (or end-t ""))))) ;; monthly diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-american index 7b86b554dd..2f7026a0bd 100644 --- a/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-american +++ b/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-american @@ -1 +1 @@ -&%%(and (diary-anniversary 8 15 2004)) Maria Himmelfahrt +&%%(diary-anniversary 8 15 2003) Maria Himmelfahrt diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-european index 3b82ec09fd..fa652dbb92 100644 --- a/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-european +++ b/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-european @@ -1 +1 @@ -&%%(and (diary-anniversary 15 8 2004)) Maria Himmelfahrt +&%%(diary-anniversary 15 8 2003) Maria Himmelfahrt diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-iso index 7fc99478d4..803dd36de0 100644 --- a/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-iso +++ b/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-iso @@ -1 +1 @@ -&%%(and (diary-anniversary 2004 8 15)) Maria Himmelfahrt +&%%(diary-anniversary 2003 8 15) Maria Himmelfahrt diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-american index a54780b969..bc485d8a6c 100644 --- a/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-american +++ b/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-american @@ -1 +1 @@ -&%%(and (diary-anniversary 9 19 2003)) 09:00-11:30 rrule yearly +&%%(diary-anniversary 9 19 2002) 09:00-11:30 rrule yearly diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-european index a4bd81d6f2..42509d42bc 100644 --- a/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-european +++ b/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-european @@ -1 +1 @@ -&%%(and (diary-anniversary 19 9 2003)) 09:00-11:30 rrule yearly +&%%(diary-anniversary 19 9 2002) 09:00-11:30 rrule yearly diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-iso index 65a7abe034..72fe6e12cb 100644 --- a/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-iso +++ b/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-iso @@ -1 +1 @@ -&%%(and (diary-anniversary 2003 9 19)) 09:00-11:30 rrule yearly +&%%(diary-anniversary 2002 9 19) 09:00-11:30 rrule yearly diff --git a/test/lisp/calendar/icalendar-tests.el b/test/lisp/calendar/icalendar-tests.el index 7993a1fd80..61d3c11f6d 100644 --- a/test/lisp/calendar/icalendar-tests.el +++ b/test/lisp/calendar/icalendar-tests.el @@ -87,7 +87,7 @@ (let* ((calendar-date-style 'iso) result) (setq result (icalendar--convert-anniversary-to-ical - "" "%%(diary-anniversary 1964 6 30) g")) + "" "%%(diary-anniversary 1963 6 30) g")) (should (consp result)) (should (string= (concat "\nDTSTART;VALUE=DATE:19640630" @@ -353,7 +353,7 @@ END:VTIMEZONE (let ((calendar-date-style 'iso)) ;; numeric iso (should (string= "20080511" - (icalendar--datestring-to-isodate "2008 05 11"))) + (icalendar--datestring-to-isodate "2008 05 11"))) (should (string= "20080531" (icalendar--datestring-to-isodate "2008 05 31"))) (should (string= "20080602" @@ -384,7 +384,19 @@ END:VTIMEZONE (should (string= "20081105" (icalendar--datestring-to-isodate "05 Nov 2008"))) (should (string= "20081105" - (icalendar--datestring-to-isodate "2008 Nov 05"))))) + (icalendar--datestring-to-isodate "2008 Nov 05"))) + + ;; non-numeric with day-shift and year-shift + (setq calendar-date-style nil) ;not necessary for conversion + (should (string= "20210212" + (icalendar--datestring-to-isodate "2021 Feb 11" 1))) + (should (string= "20210131" + (icalendar--datestring-to-isodate "2021 Feb 11" -11))) + (should (string= "20200211" + (icalendar--datestring-to-isodate "2021 Feb 11" nil -1))) + (should (string= "21010211" + (icalendar--datestring-to-isodate "2021 Feb 11" nil 80))) + )) (ert-deftest icalendar--first-weekday-of-year () "Test method for `icalendar-first-weekday-of-year'." @@ -569,10 +581,10 @@ END:VEVENT ;; testcase: dtstart is mandatory (should (null (icalendar--convert-tz-offset - '((TZOFFSETFROM nil "+0100") - (TZOFFSETTO nil "+0200") - (RRULE nil "FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU")) - t))) + '((TZOFFSETFROM nil "+0100") + (TZOFFSETTO nil "+0200") + (RRULE nil "FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU")) + t))) ;; FIXME: rrule and rdate are NOT mandatory! Must fix code ;; before activating these testcases @@ -830,18 +842,18 @@ SUMMARY:yearly no time "Perform export test." ;; anniversaries (icalendar-tests--test-export - "%%(diary-anniversary 1989 10 3) anniversary no time" - "%%(diary-anniversary 3 10 1989) anniversary no time" - "%%(diary-anniversary 10 3 1989) anniversary no time" + "%%(diary-anniversary 1988 10 3) anniversary no time" + "%%(diary-anniversary 3 10 1988) anniversary no time" + "%%(diary-anniversary 10 3 1988) anniversary no time" "DTSTART;VALUE=DATE:19891003 DTEND;VALUE=DATE:19891004 RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=10;BYMONTHDAY=03 SUMMARY:anniversary no time ") (icalendar-tests--test-export - "%%(diary-anniversary 1989 10 3) 19:00-20:00 anniversary with time" - "%%(diary-anniversary 3 10 1989) 19:00-20:00 anniversary with time" - "%%(diary-anniversary 10 3 1989) 19:00-20:00 anniversary with time" + "%%(diary-anniversary 1988 10 3) 19:00-20:00 anniversary with time" + "%%(diary-anniversary 3 10 1988) 19:00-20:00 anniversary with time" + "%%(diary-anniversary 10 3 1988) 19:00-20:00 anniversary with time" "DTSTART;VALUE=DATE-TIME:19891003T190000 DTEND;VALUE=DATE-TIME:19891004T200000 RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=10;BYMONTHDAY=03 @@ -891,12 +903,12 @@ SUMMARY:no alarm " nil) - ;; 10 minutes in advance, audio - (icalendar-tests--test-export - "2014 Nov 17 19:30 audio alarm" - "17 Nov 2014 19:30 audio alarm" - "Nov 17 2014 19:30 audio alarm" - "DTSTART;VALUE=DATE-TIME:20141117T193000 + ;; 10 minutes in advance, audio + (icalendar-tests--test-export + "2014 Nov 17 19:30 audio alarm" + "17 Nov 2014 19:30 audio alarm" + "Nov 17 2014 19:30 audio alarm" + "DTSTART;VALUE=DATE-TIME:20141117T193000 DTEND;VALUE=DATE-TIME:20141117T203000 SUMMARY:audio alarm BEGIN:VALARM @@ -904,14 +916,14 @@ ACTION:AUDIO TRIGGER:-PT10M END:VALARM " - '(10 ((audio)))) + '(10 ((audio)))) - ;; 20 minutes in advance, display - (icalendar-tests--test-export - "2014 Nov 17 19:30 display alarm" - "17 Nov 2014 19:30 display alarm" - "Nov 17 2014 19:30 display alarm" - "DTSTART;VALUE=DATE-TIME:20141117T193000 + ;; 20 minutes in advance, display + (icalendar-tests--test-export + "2014 Nov 17 19:30 display alarm" + "17 Nov 2014 19:30 display alarm" + "Nov 17 2014 19:30 display alarm" + "DTSTART;VALUE=DATE-TIME:20141117T193000 DTEND;VALUE=DATE-TIME:20141117T203000 SUMMARY:display alarm BEGIN:VALARM @@ -920,14 +932,14 @@ TRIGGER:-PT20M DESCRIPTION:display alarm END:VALARM " - '(20 ((display)))) + '(20 ((display)))) - ;; 66 minutes in advance, email - (icalendar-tests--test-export - "2014 Nov 17 19:30 email alarm" - "17 Nov 2014 19:30 email alarm" - "Nov 17 2014 19:30 email alarm" - "DTSTART;VALUE=DATE-TIME:20141117T193000 + ;; 66 minutes in advance, email + (icalendar-tests--test-export + "2014 Nov 17 19:30 email alarm" + "17 Nov 2014 19:30 email alarm" + "Nov 17 2014 19:30 email alarm" + "DTSTART;VALUE=DATE-TIME:20141117T193000 DTEND;VALUE=DATE-TIME:20141117T203000 SUMMARY:email alarm BEGIN:VALARM @@ -939,14 +951,14 @@ ATTENDEE:MAILTO:att.one@email.com ATTENDEE:MAILTO:att.two@email.com END:VALARM " - '(66 ((email ("att.one@email.com" "att.two@email.com"))))) + '(66 ((email ("att.one@email.com" "att.two@email.com"))))) - ;; 2 minutes in advance, all alarms - (icalendar-tests--test-export - "2014 Nov 17 19:30 all alarms" - "17 Nov 2014 19:30 all alarms" - "Nov 17 2014 19:30 all alarms" - "DTSTART;VALUE=DATE-TIME:20141117T193000 + ;; 2 minutes in advance, all alarms + (icalendar-tests--test-export + "2014 Nov 17 19:30 all alarms" + "17 Nov 2014 19:30 all alarms" + "Nov 17 2014 19:30 all alarms" + "DTSTART;VALUE=DATE-TIME:20141117T193000 DTEND;VALUE=DATE-TIME:20141117T203000 SUMMARY:all alarms BEGIN:VALARM @@ -967,7 +979,7 @@ TRIGGER:-PT2M DESCRIPTION:all alarms END:VALARM " - '(2 ((email ("att.one@email.com" "att.two@email.com")) (audio) (display))))) + '(2 ((email ("att.one@email.com" "att.two@email.com")) (audio) (display))))) ;; ====================================================================== ;; Import tests @@ -1247,7 +1259,7 @@ Argument INPUT icalendar event string." (find-file temp-ics) (goto-char (point-min)) ;;(when (re-search-forward "\nUID:.*\n" nil t) - ;;(replace-match "\n")) + ;;(replace-match "\n")) (let ((cycled (buffer-substring-no-properties (point-min) (point-max)))) (should (string= org-input cycled))))) ;; clean up @@ -1276,8 +1288,8 @@ DESCRIPTION:beschreibung! LOCATION:nowhere ORGANIZER:ulf ") - (icalendar-tests--test-cycle - "UID:4711 + (icalendar-tests--test-cycle + "UID:4711 DTSTART;VALUE=DATE:19190909 DTEND;VALUE=DATE:19190910 RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=09;BYMONTHDAY=09 @@ -1377,7 +1389,7 @@ SUMMARY:ff") " >>> anniversaries: -%%(diary-anniversary 3 28 1991) aa birthday (%d years old)" +%%(diary-anniversary 3 28 1990) aa birthday (%d years old)" "DTSTART;VALUE=DATE:19910328 DTEND;VALUE=DATE:19910329 RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=03;BYMONTHDAY=28 @@ -1387,7 +1399,7 @@ SUMMARY:aa birthday (%d years old) (icalendar-tests--test-export nil nil - "%%(diary-anniversary 5 17 1957) bb birthday (%d years old)" + "%%(diary-anniversary 5 17 1956) bb birthday (%d years old)" "DTSTART;VALUE=DATE:19570517 DTEND;VALUE=DATE:19570518 RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=05;BYMONTHDAY=17 @@ -1396,7 +1408,7 @@ SUMMARY:bb birthday (%d years old)") (icalendar-tests--test-export nil nil - "%%(diary-anniversary 6 8 1997) cc birthday (%d years old)" + "%%(diary-anniversary 6 8 1996) cc birthday (%d years old)" "DTSTART;VALUE=DATE:19970608 DTEND;VALUE=DATE:19970609 RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=06;BYMONTHDAY=08 @@ -1405,7 +1417,7 @@ SUMMARY:cc birthday (%d years old)") (icalendar-tests--test-export nil nil - "%%(diary-anniversary 7 22 1983) dd (%d years ago...!)" + "%%(diary-anniversary 7 22 1982) dd (%d years ago...!)" "DTSTART;VALUE=DATE:19830722 DTEND;VALUE=DATE:19830723 RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=07;BYMONTHDAY=22 @@ -1414,7 +1426,7 @@ SUMMARY:dd (%d years ago...!)") (icalendar-tests--test-export nil nil - "%%(diary-anniversary 8 1 1988) ee birthday (%d years old)" + "%%(diary-anniversary 8 1 1987) ee birthday (%d years old)" "DTSTART;VALUE=DATE:19880801 DTEND;VALUE=DATE:19880802 RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=08;BYMONTHDAY=01 @@ -1423,7 +1435,7 @@ SUMMARY:ee birthday (%d years old)") (icalendar-tests--test-export nil nil - "%%(diary-anniversary 9 21 1957) ff birthday (%d years old)" + "%%(diary-anniversary 9 21 1956) ff birthday (%d years old)" "DTSTART;VALUE=DATE:19570921 DTEND;VALUE=DATE:19570922 RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=09;BYMONTHDAY=21 commit 211731b3a94bf1380e4fb08d9f6ed65e9ed98b22 Author: Stefan Monnier Date: Mon Feb 15 10:57:26 2021 -0500 * lisp/calc/calc-sel.el (calc-replace-sub-formula): Fix typo Reported by Sébastien Miquel diff --git a/lisp/calc/calc-sel.el b/lisp/calc/calc-sel.el index 2b317ac369..18fd483baf 100644 --- a/lisp/calc/calc-sel.el +++ b/lisp/calc/calc-sel.el @@ -486,8 +486,8 @@ (defun calc-replace-sub-formula (expr rsf-old rsf-new) (let ((calc-rsf-old rsf-old) - (calc-rsf-new (calc-encase-atoms rsf-new)))) - (calc-replace-sub-formula-rec expr)) + (calc-rsf-new (calc-encase-atoms rsf-new))) + (calc-replace-sub-formula-rec expr))) (defun calc-replace-sub-formula-rec (expr) (cond ((eq expr calc-rsf-old) calc-rsf-new) commit fc4927fc3a27e995337612dde8614f0309616dde Author: Stefan Monnier Date: Mon Feb 15 10:50:07 2021 -0500 * lisp/emacs-lisp/bindat.el: Expose the `struct` variable (bug#46534) (bindat--unpack-group, bindat--length-group, bindat--pack-group): Mark it as dynamically scoped. diff --git a/lisp/emacs-lisp/bindat.el b/lisp/emacs-lisp/bindat.el index 0d9ba57d66..bf01347ae0 100644 --- a/lisp/emacs-lisp/bindat.el +++ b/lisp/emacs-lisp/bindat.el @@ -26,7 +26,7 @@ ;; Packing and unpacking of (binary) data structures. ;; ;; The data formats used in binary files and network protocols are -;; often structed data which can be described by a C-style structure +;; often structured data which can be described by a C-style structure ;; such as the one shown below. Using the bindat package, decoding ;; and encoding binary data formats like these is made simple using a ;; structure specification which closely resembles the C style @@ -135,7 +135,8 @@ ;; | ( [FIELD] repeat COUNT ITEM... ) ;; -- In (eval EXPR), the value of the last field is available in -;; the dynamically bound variable `last'. +;; the dynamically bound variable `last' and all the previous +;; ones in the variable `struct'. ;; TYPE ::= ( eval EXPR ) -- interpret result as TYPE ;; | u8 | byte -- length 1 @@ -191,7 +192,7 @@ ;;; Code: ;; Helper functions for structure unpacking. -;; Relies on dynamic binding of BINDAT-RAW and BINDAT-IDX +;; Relies on dynamic binding of `bindat-raw' and `bindat-idx'. (defvar bindat-raw) (defvar bindat-idx) @@ -276,8 +277,8 @@ (t nil))) (defun bindat--unpack-group (spec) - (with-suppressed-warnings ((lexical last)) - (defvar last)) + (with-suppressed-warnings ((lexical struct last)) + (defvar struct) (defvar last)) (let (struct last) (while spec (let* ((item (car spec)) @@ -378,9 +379,9 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (ip . 4))) (defun bindat--length-group (struct spec) - (with-suppressed-warnings ((lexical last)) - (defvar last)) - (let (last) + (with-suppressed-warnings ((lexical struct last)) + (defvar struct) (defvar last)) + (let ((struct struct) last) (while spec (let* ((item (car spec)) (field (car item)) @@ -544,9 +545,9 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (setq bindat-idx (+ bindat-idx len))))) (defun bindat--pack-group (struct spec) - (with-suppressed-warnings ((lexical last)) - (defvar last)) - (let (last) + (with-suppressed-warnings ((lexical struct last)) + (defvar struct) (defvar last)) + (let ((struct struct) last) (while spec (let* ((item (car spec)) (field (car item)) commit 6ea920c88d7705e7b09571819d3948efd2e53109 Author: Lars Ingebrigtsen Date: Mon Feb 15 14:43:53 2021 +0100 Allow overriding declared predicates, too * lisp/simple.el (completion-default-include-p): Rename and move the checking for an explicit predicate down here... (read-extended-command): ... from here. (read-extended-command-predicate): Adjust default value. diff --git a/lisp/simple.el b/lisp/simple.el index aafbb3e1f8..8a9f46cef6 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1904,15 +1904,15 @@ to get different commands to edit and resubmit." (defvar extended-command-history nil) (defvar execute-extended-command--last-typed nil) -(defcustom read-extended-command-predicate #'completion-in-mode-p +(defcustom read-extended-command-predicate #'completion-default-include-p "Predicate to use to determine which commands to include when completing. The predicate function is called with two parameter: The symbol (i.e., command) in question that should be included or not, and the current buffer. The predicate should return non-nil if the command should be present when doing `M-x TAB'." :version "28.1" - :type '(choice (const :tag "Exclude commands not relevant to this mode" - #'completion-in-mode-p) + :type '(choice (const :tag "Exclude commands not relevant to the current mode" + #'completion-default-include-p) (const :tag "All commands" (lambda (_ _) t)) (function :tag "Other function"))) @@ -1970,35 +1970,37 @@ This function uses the `read-extended-command-predicate' user option." (complete-with-action action obarray string pred))) (lambda (sym) (and (commandp sym) - ;;; FIXME: This should also be possible to disable by - ;;; the user, but I'm not quite sure what the right - ;;; design for that would look like. - (if (get sym 'completion-predicate) - (funcall (get sym 'completion-predicate) sym buffer) - (funcall read-extended-command-predicate sym buffer)))) + (funcall read-extended-command-predicate sym buffer))) t nil 'extended-command-history)))) -(defun completion-in-mode-p (symbol buffer) +(defun completion-default-include-p (symbol buffer) "Say whether SYMBOL should be offered as a completion. -This is true if the command is applicable to the major mode in -BUFFER, or any of the active minor modes in BUFFER." - (let ((modes (command-modes symbol))) - (or (null modes) - ;; Common case: Just a single mode. - (if (null (cdr modes)) - (or (provided-mode-derived-p - (buffer-local-value 'major-mode buffer) (car modes)) - (memq (car modes) - (buffer-local-value 'local-minor-modes buffer)) - (memq (car modes) global-minor-modes)) - ;; Uncommon case: Multiple modes. - (apply #'provided-mode-derived-p - (buffer-local-value 'major-mode buffer) - modes) - (seq-intersection modes - (buffer-local-value 'local-minor-modes buffer) - #'eq) - (seq-intersection modes global-minor-modes #'eq))))) +If there's a `completion-predicate' for SYMBOL, the result from +calling that predicate is called. If there isn't one, this +predicate is true if the command SYMBOL is applicable to the +major mode in BUFFER, or any of the active minor modes in +BUFFER." + (if (get symbol 'completion-predicate) + ;; An explicit completion predicate takes precedence. + (funcall (get symbol 'completion-predicate) symbol buffer) + ;; Check the modes. + (let ((modes (command-modes symbol))) + (or (null modes) + ;; Common case: Just a single mode. + (if (null (cdr modes)) + (or (provided-mode-derived-p + (buffer-local-value 'major-mode buffer) (car modes)) + (memq (car modes) + (buffer-local-value 'local-minor-modes buffer)) + (memq (car modes) global-minor-modes)) + ;; Uncommon case: Multiple modes. + (apply #'provided-mode-derived-p + (buffer-local-value 'major-mode buffer) + modes) + (seq-intersection modes + (buffer-local-value 'local-minor-modes buffer) + #'eq) + (seq-intersection modes global-minor-modes #'eq)))))) (defun completion-with-modes-p (modes buffer) "Say whether MODES are in action in BUFFER. commit 398811b7f67e2a27d31541e5200707911a3377ce Author: Lars Ingebrigtsen Date: Mon Feb 15 13:43:27 2021 +0100 Do `interactive' mode tagging in the remaining lisp/gnus files diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 5a5dbcebc1..ee98099e08 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -2334,7 +2334,8 @@ Leading \"Re: \" is not stripped by this function. Use the function "Ask for NEW-SUBJECT header, append (was: )." (interactive (list - (read-from-minibuffer "New subject: "))) + (read-from-minibuffer "New subject: ")) + message-mode) (cond ((and (not (or (null new-subject) ; new subject not empty (zerop (string-width new-subject)) (string-match "^[ \t]*$" new-subject)))) @@ -2364,7 +2365,7 @@ Leading \"Re: \" is not stripped by this function. Use the function "Mark some region in the current article with enclosing tags. See `message-mark-insert-begin' and `message-mark-insert-end'. If VERBATIM, use slrn style verbatim marks (\"#v+\" and \"#v-\")." - (interactive "r\nP") + (interactive "r\nP" message-mode) (save-excursion ;; add to the end of the region first, otherwise end would be invalid (goto-char end) @@ -2376,7 +2377,7 @@ If VERBATIM, use slrn style verbatim marks (\"#v+\" and \"#v-\")." "Insert FILE at point, marking it with enclosing tags. See `message-mark-insert-begin' and `message-mark-insert-end'. If VERBATIM, use slrn style verbatim marks (\"#v+\" and \"#v-\")." - (interactive "fFile to insert: \nP") + (interactive "fFile to insert: \nP" message-mode) ;; reverse insertion to get correct result. (let ((p (point))) (insert (if verbatim "#v-\n" message-mark-insert-end)) @@ -2390,7 +2391,7 @@ If VERBATIM, use slrn style verbatim marks (\"#v+\" and \"#v-\")." The note can be customized using `message-archive-note'. When called with a prefix argument, ask for a text to insert. If you don't want the note in the body, set `message-archive-note' to nil." - (interactive) + (interactive nil message-mode) (if current-prefix-arg (setq message-archive-note (read-from-minibuffer "Reason for No-Archive: " @@ -2416,7 +2417,8 @@ With prefix-argument just set Follow-Up, don't cross-post." gnus-newsrc-alist) nil nil '("poster" . 0) (if (boundp 'gnus-group-history) - 'gnus-group-history))))) + 'gnus-group-history)))) + message-mode) (message-remove-header "Follow[Uu]p-[Tt]o" t) (message-goto-newsgroups) (beginning-of-line) @@ -2493,7 +2495,8 @@ With prefix-argument just set Follow-Up, don't cross-post." gnus-newsrc-alist) nil nil '("poster" . 0) (if (boundp 'gnus-group-history) - 'gnus-group-history))))) + 'gnus-group-history)))) + message-mode) (when (fboundp 'gnus-group-real-name) (setq target-group (gnus-group-real-name target-group))) (cond ((not (or (null target-group) ; new subject not empty @@ -2528,7 +2531,7 @@ With prefix-argument just set Follow-Up, don't cross-post." (defun message-reduce-to-to-cc () "Replace contents of To: header with contents of Cc: or Bcc: header." - (interactive) + (interactive nil message-mode) (let ((cc-content (save-restriction (message-narrow-to-headers) (message-fetch-field "cc"))) @@ -2694,7 +2697,7 @@ Point is left at the beginning of the narrowed-to region." (defun message-sort-headers () "Sort headers of the current message according to `message-header-format-alist'." - (interactive) + (interactive nil message-mode) (save-excursion (save-restriction (let ((max (1+ (length message-header-format-alist))) @@ -2715,7 +2718,7 @@ Point is left at the beginning of the narrowed-to region." (defun message-kill-address () "Kill the address under point." - (interactive) + (interactive nil message-mode) (let ((start (point))) (message-skip-to-next-address) (kill-region start (if (bolp) (1- (point)) (point))))) @@ -3208,79 +3211,79 @@ Like `text-mode', but with these additional commands: (defun message-goto-to () "Move point to the To header." - (interactive) + (interactive nil message-mode) (push-mark) (message-position-on-field "To")) (defun message-goto-from () "Move point to the From header." - (interactive) + (interactive nil message-mode) (push-mark) (message-position-on-field "From")) (defun message-goto-subject () "Move point to the Subject header." - (interactive) + (interactive nil message-mode) (push-mark) (message-position-on-field "Subject")) (defun message-goto-cc () "Move point to the Cc header." - (interactive) + (interactive nil message-mode) (push-mark) (message-position-on-field "Cc" "To")) (defun message-goto-bcc () "Move point to the Bcc header." - (interactive) + (interactive nil message-mode) (push-mark) (message-position-on-field "Bcc" "Cc" "To")) (defun message-goto-fcc () "Move point to the Fcc header." - (interactive) + (interactive nil message-mode) (push-mark) (message-position-on-field "Fcc" "To" "Newsgroups")) (defun message-goto-reply-to () "Move point to the Reply-To header." - (interactive) + (interactive nil message-mode) (push-mark) (message-position-on-field "Reply-To" "Subject")) (defun message-goto-newsgroups () "Move point to the Newsgroups header." - (interactive) + (interactive nil message-mode) (push-mark) (message-position-on-field "Newsgroups")) (defun message-goto-distribution () "Move point to the Distribution header." - (interactive) + (interactive nil message-mode) (push-mark) (message-position-on-field "Distribution")) (defun message-goto-followup-to () "Move point to the Followup-To header." - (interactive) + (interactive nil message-mode) (push-mark) (message-position-on-field "Followup-To" "Newsgroups")) (defun message-goto-mail-followup-to () "Move point to the Mail-Followup-To header." - (interactive) + (interactive nil message-mode) (push-mark) (message-position-on-field "Mail-Followup-To" "To")) (defun message-goto-keywords () "Move point to the Keywords header." - (interactive) + (interactive nil message-mode) (push-mark) (message-position-on-field "Keywords" "Subject")) (defun message-goto-summary () "Move point to the Summary header." - (interactive) + (interactive nil message-mode) (push-mark) (message-position-on-field "Summary" "Subject")) @@ -3288,7 +3291,7 @@ Like `text-mode', but with these additional commands: (defun message-goto-body (&optional interactive) "Move point to the beginning of the message body. Returns point." - (interactive "p") + (interactive "p" message-mode) (when interactive (when (looking-at "[ \t]*\n") (expand-abbrev)) @@ -3315,7 +3318,7 @@ Returns point." (defun message-goto-eoh (&optional interactive) "Move point to the end of the headers." - (interactive "p") + (interactive "p" message-mode) (message-goto-body interactive) (forward-line -1)) @@ -3323,7 +3326,7 @@ Returns point." "Move point to the beginning of the message signature. If there is no signature in the article, go to the end and return nil." - (interactive) + (interactive nil message-mode) (push-mark) (goto-char (point-min)) (if (re-search-forward message-signature-separator nil t) @@ -3342,7 +3345,7 @@ in the current mail buffer, and appends the current `user-mail-address'. If the optional argument INCLUDE-CC is non-nil, the addresses in the Cc: header are also put into the MFT." - (interactive "P") + (interactive "P" message-mode) (let* (cc tos) (save-restriction (message-narrow-to-headers) @@ -3360,7 +3363,7 @@ Cc: header are also put into the MFT." "Insert a To header that points to the author of the article being replied to. If the original author requested not to be sent mail, don't insert unless the prefix FORCE is given." - (interactive "P") + (interactive "P" message-mode) (let* ((mct (message-fetch-reply-field "mail-copies-to")) (dont (and mct (or (equal (downcase mct) "never") (equal (downcase mct) "nobody")))) @@ -3379,7 +3382,7 @@ prefix FORCE is given." (defun message-insert-wide-reply () "Insert To and Cc headers as if you were doing a wide reply." - (interactive) + (interactive nil message-mode) (let ((headers (message-with-reply-buffer (message-get-reply-headers t)))) (message-carefully-insert-headers headers))) @@ -3424,7 +3427,7 @@ or in the synonym headers, defined by `message-header-synonyms'." (defun message-widen-reply () "Widen the reply to include maximum recipients." - (interactive) + (interactive nil message-mode) (let ((follow-to (and (buffer-live-p message-reply-buffer) (with-current-buffer message-reply-buffer @@ -3440,7 +3443,7 @@ or in the synonym headers, defined by `message-header-synonyms'." (defun message-insert-newsgroups () "Insert the Newsgroups header from the article being replied to." - (interactive) + (interactive nil message-mode) (let ((old-newsgroups (mail-fetch-field "newsgroups")) (new-newsgroups (message-fetch-reply-field "newsgroups")) (first t) @@ -3475,13 +3478,13 @@ or in the synonym headers, defined by `message-header-synonyms'." (defun message-widen-and-recenter () "Widen the buffer and go to the start." - (interactive) + (interactive nil message-mode) (widen) (goto-char (point-min))) (defun message-delete-not-region (beg end) "Delete everything in the body of the current message outside of the region." - (interactive "r") + (interactive "r" message-mode) (let (citeprefix) (save-excursion (goto-char beg) @@ -3508,7 +3511,7 @@ or in the synonym headers, defined by `message-header-synonyms'." "Kill all text up to the signature. If a numeric argument or prefix arg is given, leave that number of lines before the signature intact." - (interactive "P") + (interactive "P" message-mode) (save-excursion (save-restriction (let ((point (point))) @@ -3526,7 +3529,7 @@ of lines before the signature intact." (defun message-newline-and-reformat (&optional arg not-break) "Insert four newlines, and then reformat if inside quoted text. Prefix arg means justify as well." - (interactive (list (if current-prefix-arg 'full))) + (interactive (list (if current-prefix-arg 'full)) message-mode) (unless (message-in-body-p) (error "This command only works in the body of the message")) (let (quoted point beg end leading-space bolp fill-paragraph-function) @@ -3617,7 +3620,7 @@ Prefix arg means justify as well." "Message specific function to fill a paragraph. This function is used as the value of `fill-paragraph-function' in Message buffers and is not meant to be called directly." - (interactive (list (if current-prefix-arg 'full))) + (interactive (list (if current-prefix-arg 'full)) message-mode) (if (message-point-in-header-p) (message-fill-field) (message-newline-and-reformat arg t)) @@ -3648,7 +3651,7 @@ more information. If FORCE is 0 (or when called interactively), the global values of the signature variables will be consulted if the local ones are null." - (interactive (list 0)) + (interactive (list 0) message-mode) (let ((message-signature message-signature) (message-signature-file message-signature-file)) ;; If called interactively and there's no signature to insert, @@ -3707,7 +3710,7 @@ are null." (defun message-insert-importance-high () "Insert header to mark message as important." - (interactive) + (interactive nil message-mode) (save-excursion (save-restriction (message-narrow-to-headers) @@ -3717,7 +3720,7 @@ are null." (defun message-insert-importance-low () "Insert header to mark message as unimportant." - (interactive) + (interactive nil message-mode) (save-excursion (save-restriction (message-narrow-to-headers) @@ -3729,7 +3732,7 @@ are null." "Insert a \"Importance: high\" header, or cycle through the header values. The three allowed values according to RFC 1327 are `high', `normal' and `low'." - (interactive) + (interactive nil message-mode) (save-excursion (let ((new "high") cur) @@ -3749,7 +3752,7 @@ and `low'." (defun message-insert-disposition-notification-to () "Request a disposition notification (return receipt) to this message. Note that this should not be used in newsgroups." - (interactive) + (interactive nil message-mode) (save-excursion (save-restriction (message-narrow-to-headers) @@ -3764,7 +3767,7 @@ Note that this should not be used in newsgroups." "Elide the text in the region. An ellipsis (from `message-elide-ellipsis') will be inserted where the text was killed." - (interactive "r") + (interactive "r" message-mode) (let ((lines (count-lines b e)) (chars (- e b))) (kill-region b e) @@ -3781,7 +3784,8 @@ text was killed." (min (point) (or (mark t) (point))) (max (point) (or (mark t) (point))) (when current-prefix-arg - (prefix-numeric-value current-prefix-arg)))) + (prefix-numeric-value current-prefix-arg))) + message-mode) (setq n (if (numberp n) (mod n 26) 13)) ;canonize N (unless (or (zerop n) ; no action needed for a rot of 0 @@ -3815,7 +3819,8 @@ With prefix arg, specifies the number of places to rotate each letter forward. Mail and USENET news headers are not rotated unless WIDE is non-nil." (interactive (if current-prefix-arg (list (prefix-numeric-value current-prefix-arg)) - (list nil))) + (list nil)) + message-mode) (save-excursion (save-restriction (when (and (not wide) (message-goto-body)) @@ -3835,7 +3840,7 @@ Mail and USENET news headers are not rotated unless WIDE is non-nil." "Rename the *message* buffer to \"*message* RECIPIENT\". If the function is run with a prefix, it will ask for a new buffer name, rather than giving an automatic name." - (interactive "Pbuffer name: ") + (interactive "Pbuffer name: " message-mode) (save-excursion (save-restriction (goto-char (point-min)) @@ -3858,7 +3863,7 @@ name, rather than giving an automatic name." (defun message-fill-yanked-message (&optional justifyp) "Fill the paragraphs of a message yanked into this one. Numeric argument means justify as well." - (interactive "P") + (interactive "P" message-mode) (save-excursion (goto-char (point-min)) (search-forward (concat "\n" mail-header-separator "\n") nil t) @@ -3923,7 +3928,7 @@ If REMOVE is non-nil, remove newlines, too. To use this automatically, you may add this function to `gnus-message-setup-hook'." - (interactive "P") + (interactive "P" message-mode) (let ((citexp (concat "^\\(" (concat message-yank-cited-prefix "\\|") message-yank-prefix @@ -3988,7 +3993,7 @@ This function uses `message-cite-function' to do the actual citing. Just \\[universal-argument] as argument means don't indent, insert no prefix, and don't delete any headers." - (interactive "P") + (interactive "P" message-mode) ;; eval the let forms contained in message-cite-style (let ((bindings (if (symbolp message-cite-style) (symbol-value message-cite-style) @@ -3999,7 +4004,7 @@ prefix, and don't delete any headers." (defun message-yank-buffer (buffer) "Insert BUFFER into the current buffer and quote it." - (interactive "bYank buffer: ") + (interactive "bYank buffer: " message-mode) (let ((message-reply-buffer (get-buffer buffer))) (save-window-excursion (message-yank-original)))) @@ -4226,7 +4231,7 @@ This function strips off the signature from the original message." "Send message like `message-send', then, if no errors, exit from mail buffer. The usage of ARG is defined by the instance that called Message. It should typically alter the sending method in some way or other." - (interactive "P") + (interactive "P" message-mode) (let ((buf (current-buffer)) (position (point-marker)) (actions message-exit-actions)) @@ -4246,7 +4251,7 @@ It should typically alter the sending method in some way or other." (defun message-dont-send () "Don't send the message you have been editing. Instead, just auto-save the buffer and then bury it." - (interactive) + (interactive nil message-mode) (set-buffer-modified-p t) (save-buffer) (let ((actions message-postpone-actions)) @@ -4255,7 +4260,7 @@ Instead, just auto-save the buffer and then bury it." (defun message-kill-buffer () "Kill the current buffer." - (interactive) + (interactive nil message-mode) (when (or (not (buffer-modified-p)) (not message-kill-buffer-query) (yes-or-no-p "Message modified; kill anyway? ")) @@ -4304,7 +4309,7 @@ Otherwise any failure is reported in a message back to the user from the mailer. The usage of ARG is defined by the instance that called Message. It should typically alter the sending method in some way or other." - (interactive "P") + (interactive "P" message-mode) ;; Make it possible to undo the coming changes. (undo-boundary) (let ((inhibit-read-only t)) @@ -4572,7 +4577,7 @@ An address might be bogus if there's a matching entry in "Warn before composing or sending a mail to an invalid address. This function could be useful in `message-setup-hook'." - (interactive) + (interactive nil message-mode) (save-restriction (message-narrow-to-headers) (dolist (hdr '("To" "Cc" "Bcc")) @@ -5744,7 +5749,7 @@ If NOW, use that time instead." (defun message-insert-expires (days) "Insert the Expires header. Expiry in DAYS days." - (interactive "NExpire article in how many days? ") + (interactive "NExpire article in how many days? " message-mode) (save-excursion (message-position-on-field "Expires" "X-Draft-From") (insert (message-make-expires-date days)))) @@ -6047,7 +6052,7 @@ give as trustworthy answer as possible." (defun message-to-list-only () "Send a message to the list only. Remove all addresses but the list address from To and Cc headers." - (interactive) + (interactive nil message-mode) (let ((listaddr (message-make-mail-followup-to t))) (when listaddr (save-excursion @@ -6133,7 +6138,7 @@ subscribed address (and not the additional To and Cc header contents)." (defun message-idna-to-ascii-rhs () "Possibly IDNA encode non-ASCII domain names in From:, To: and Cc: headers. See `message-idna-encode'." - (interactive) + (interactive nil message-mode) (when message-use-idna (save-excursion (save-restriction @@ -6351,7 +6356,7 @@ Headers already prepared in the buffer are not modified." (defun message-split-line () "Split current line, moving portion beyond point vertically down. If the current line has `message-yank-prefix', insert it on the new line." - (interactive "*") + (interactive "*" message-mode) (split-line message-yank-prefix)) (defun message-insert-header (header value) @@ -6549,7 +6554,7 @@ When called without a prefix argument, header value spanning multiple lines is treated as a single line. Otherwise, even if N is 1, when point is on a continuation header line, it will be moved to the beginning " - (interactive "^p") + (interactive "^p" message-mode) (cond ;; Go to beginning of header or beginning of line. ((and message-beginning-of-line (message-point-in-header-p)) @@ -6874,7 +6879,7 @@ are not included." (defun message-insert-headers () "Generate the headers for the article." - (interactive) + (interactive nil message-mode) (save-excursion (save-restriction (message-narrow-to-headers) @@ -8214,7 +8219,7 @@ If nil, the function bound in `text-mode-map' or `global-map' is executed." Execute function specified by `message-tab-body-function' when not in those headers. If that variable is nil, indent with the regular text mode tabbing command." - (interactive) + (interactive nil message-mode) (cond ((let ((completion-fail-discreetly t)) (completion-at-point)) @@ -8591,7 +8596,7 @@ From headers in the original article." (defun message-display-abbrev (&optional choose) "Display the next possible abbrev for the text before point." - (interactive (list t)) + (interactive (list t) message-mode) (when (message--in-tocc-p) (let* ((end (point)) (start (save-excursion @@ -8678,7 +8683,7 @@ Unless FORCE, prompt before sending. The messages are separated by `message-form-letter-separator'. Header and body are separated by `mail-header-separator'." - (interactive "P") + (interactive "P" message-mode) (let ((sent 0) (skipped 0) start end text buff @@ -8746,7 +8751,7 @@ Used in `message-simplify-recipients'." (make-obsolete 'message-simplify-recipients nil "27.1") (defun message-simplify-recipients () - (interactive) + (interactive nil message-mode) (dolist (hdr '("Cc" "To")) (message-replace-header hdr @@ -8769,7 +8774,8 @@ Used in `message-simplify-recipients'." (defun message-make-html-message-with-image-files (files) "Make a message containing the current dired-marked image files." - (interactive (list (dired-get-marked-files nil current-prefix-arg))) + (interactive (list (dired-get-marked-files nil current-prefix-arg)) + dired-mode) (message-mail) (message-goto-body) (insert "<#part type=text/html>\n\n") @@ -8780,7 +8786,7 @@ Used in `message-simplify-recipients'." (defun message-toggle-image-thumbnails () "For any included image files, insert a thumbnail of that image." - (interactive) + (interactive nil message-mode) (let ((displayed nil)) (save-excursion (goto-char (point-min)) @@ -8816,7 +8822,7 @@ starting the screenshotting process. The `message-screenshot-command' variable says what command is used to take the screenshot." - (interactive "p") + (interactive "p" message-mode) (unless (executable-find (car message-screenshot-command)) (error "Can't find %s to take the screenshot" (car message-screenshot-command))) diff --git a/lisp/gnus/mml-sec.el b/lisp/gnus/mml-sec.el index d41c9dd0d9..a32eed4419 100644 --- a/lisp/gnus/mml-sec.el +++ b/lisp/gnus/mml-sec.el @@ -250,7 +250,7 @@ You can also customize or set `mml-signencrypt-style-alist' instead." "Add MML tags to sign this MML part. Use METHOD if given. Else use `mml-secure-method' or `mml-default-sign-method'." - (interactive) + (interactive nil mml-mode) (mml-secure-part (or method mml-secure-method mml-default-sign-method) 'sign)) @@ -259,43 +259,43 @@ Use METHOD if given. Else use `mml-secure-method' or "Add MML tags to encrypt this MML part. Use METHOD if given. Else use `mml-secure-method' or `mml-default-sign-method'." - (interactive) + (interactive nil mml-mode) (mml-secure-part (or method mml-secure-method mml-default-sign-method))) (defun mml-secure-sign-pgp () "Add MML tags to PGP sign this MML part." - (interactive) + (interactive nil mml-mode) (mml-secure-part "pgp" 'sign)) (defun mml-secure-sign-pgpauto () "Add MML tags to PGP-auto sign this MML part." - (interactive) + (interactive nil mml-mode) (mml-secure-part "pgpauto" 'sign)) (defun mml-secure-sign-pgpmime () "Add MML tags to PGP/MIME sign this MML part." - (interactive) + (interactive nil mml-mode) (mml-secure-part "pgpmime" 'sign)) (defun mml-secure-sign-smime () "Add MML tags to S/MIME sign this MML part." - (interactive) + (interactive nil mml-mode) (mml-secure-part "smime" 'sign)) (defun mml-secure-encrypt-pgp () "Add MML tags to PGP encrypt this MML part." - (interactive) + (interactive nil mml-mode) (mml-secure-part "pgp")) (defun mml-secure-encrypt-pgpmime () "Add MML tags to PGP/MIME encrypt this MML part." - (interactive) + (interactive nil mml-mode) (mml-secure-part "pgpmime")) (defun mml-secure-encrypt-smime () "Add MML tags to S/MIME encrypt this MML part." - (interactive) + (interactive nil mml-mode) (mml-secure-part "smime")) (defun mml-secure-is-encrypted-p (&optional tag-present) @@ -358,7 +358,7 @@ either an error is raised or not." (defun mml-unsecure-message () "Remove security related MML tags from message." - (interactive) + (interactive nil mml-mode) (save-excursion (goto-char (point-max)) (when (re-search-backward "^<#secure.*>\n" nil t) @@ -369,7 +369,7 @@ either an error is raised or not." "Add MML tags to sign the entire message. Use METHOD if given. Else use `mml-secure-method' or `mml-default-sign-method'." - (interactive) + (interactive nil mml-mode) (mml-secure-message (or method mml-secure-method mml-default-sign-method) 'sign)) @@ -378,7 +378,7 @@ Use METHOD if given. Else use `mml-secure-method' or "Add MML tag to sign and encrypt the entire message. Use METHOD if given. Else use `mml-secure-method' or `mml-default-sign-method'." - (interactive) + (interactive nil mml-mode) (mml-secure-message (or method mml-secure-method mml-default-sign-method) 'signencrypt)) @@ -387,53 +387,53 @@ Use METHOD if given. Else use `mml-secure-method' or "Add MML tag to encrypt the entire message. Use METHOD if given. Else use `mml-secure-method' or `mml-default-sign-method'." - (interactive) + (interactive nil mml-mode) (mml-secure-message (or method mml-secure-method mml-default-sign-method) 'encrypt)) (defun mml-secure-message-sign-smime () "Add MML tag to encrypt/sign the entire message." - (interactive) + (interactive nil mml-mode) (mml-secure-message "smime" 'sign)) (defun mml-secure-message-sign-pgp () "Add MML tag to encrypt/sign the entire message." - (interactive) + (interactive nil mml-mode) (mml-secure-message "pgp" 'sign)) (defun mml-secure-message-sign-pgpmime () "Add MML tag to encrypt/sign the entire message." - (interactive) + (interactive nil mml-mode) (mml-secure-message "pgpmime" 'sign)) (defun mml-secure-message-sign-pgpauto () "Add MML tag to encrypt/sign the entire message." - (interactive) + (interactive nil mml-mode) (mml-secure-message "pgpauto" 'sign)) (defun mml-secure-message-encrypt-smime (&optional dontsign) "Add MML tag to encrypt and sign the entire message. If called with a prefix argument, only encrypt (do NOT sign)." - (interactive "P") + (interactive "P" mml-mode) (mml-secure-message "smime" (if dontsign 'encrypt 'signencrypt))) (defun mml-secure-message-encrypt-pgp (&optional dontsign) "Add MML tag to encrypt and sign the entire message. If called with a prefix argument, only encrypt (do NOT sign)." - (interactive "P") + (interactive "P" mml-mode) (mml-secure-message "pgp" (if dontsign 'encrypt 'signencrypt))) (defun mml-secure-message-encrypt-pgpmime (&optional dontsign) "Add MML tag to encrypt and sign the entire message. If called with a prefix argument, only encrypt (do NOT sign)." - (interactive "P") + (interactive "P" mml-mode) (mml-secure-message "pgpmime" (if dontsign 'encrypt 'signencrypt))) (defun mml-secure-message-encrypt-pgpauto (&optional dontsign) "Add MML tag to encrypt and sign the entire message. If called with a prefix argument, only encrypt (do NOT sign)." - (interactive "P") + (interactive "P" mml-mode) (mml-secure-message "pgpauto" (if dontsign 'encrypt 'signencrypt))) ;;; Common functionality for mml1991.el, mml2015.el, mml-smime.el diff --git a/lisp/gnus/mml.el b/lisp/gnus/mml.el index f77e5c6434..dcc9ea51dd 100644 --- a/lisp/gnus/mml.el +++ b/lisp/gnus/mml.el @@ -1339,7 +1339,7 @@ If not set, `default-directory' will be used." (defun mml-quote-region (beg end) "Quote the MML tags in the region." - (interactive "r") + (interactive "r" mml-mode) (save-excursion (save-restriction ;; Temporarily narrow the region to defend from changes diff --git a/lisp/gnus/nnagent.el b/lisp/gnus/nnagent.el index 76a7e21567..56ca2e14b6 100644 --- a/lisp/gnus/nnagent.el +++ b/lisp/gnus/nnagent.el @@ -1,3 +1,4 @@ + ;;; nnagent.el --- offline backend for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/score-mode.el b/lisp/gnus/score-mode.el index d3ed3600ad..5140861890 100644 --- a/lisp/gnus/score-mode.el +++ b/lisp/gnus/score-mode.el @@ -83,12 +83,12 @@ This mode is an extended emacs-lisp mode. (defun gnus-score-edit-insert-date () "Insert date in numerical format." - (interactive) + (interactive nil gnus-score-mode) (princ (time-to-days nil) (current-buffer))) (defun gnus-score-pretty-print () "Format the current score file." - (interactive) + (interactive nil gnus-score-mode) (goto-char (point-min)) (let ((form (read (current-buffer)))) (erase-buffer) @@ -98,7 +98,7 @@ This mode is an extended emacs-lisp mode. (defun gnus-score-edit-exit () "Stop editing the score file." - (interactive) + (interactive nil gnus-score-mode) (unless (file-exists-p (file-name-directory (buffer-file-name))) (make-directory (file-name-directory (buffer-file-name)) t)) (let ((coding-system-for-write score-mode-coding-system)) diff --git a/lisp/gnus/smiley.el b/lisp/gnus/smiley.el index 3ee59479cf..32283af52b 100644 --- a/lisp/gnus/smiley.el +++ b/lisp/gnus/smiley.el @@ -242,7 +242,7 @@ interactively. If there's no argument, do it at the current buffer." (defun smiley-toggle-buffer (&optional arg) "Toggle displaying smiley faces in article buffer. With arg, turn displaying on if and only if arg is positive." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (gnus-with-article-buffer (if (if (numberp arg) (> arg 0) diff --git a/lisp/gnus/smime.el b/lisp/gnus/smime.el index 8900be5e4f..2446577c6a 100644 --- a/lisp/gnus/smime.el +++ b/lisp/gnus/smime.el @@ -672,7 +672,7 @@ The following commands are available: (defun smime-exit () "Quit the S/MIME buffer." - (interactive) + (interactive nil smime-mode) (kill-buffer (current-buffer))) ;; Other functions diff --git a/lisp/gnus/spam-report.el b/lisp/gnus/spam-report.el index d87a6c2af0..7d93f8a555 100644 --- a/lisp/gnus/spam-report.el +++ b/lisp/gnus/spam-report.el @@ -120,7 +120,8 @@ submitted at once. Internal variable.") (defun spam-report-gmane-ham (&rest articles) "Report ARTICLES as ham (unregister) through Gmane." - (interactive (gnus-summary-work-articles current-prefix-arg)) + (interactive (gnus-summary-work-articles current-prefix-arg) + gnus-summary-mode) (let ((count 0)) (dolist (article articles) (setq count (1+ count)) @@ -130,7 +131,8 @@ submitted at once. Internal variable.") (defun spam-report-gmane-spam (&rest articles) "Report ARTICLES as spam through Gmane." - (interactive (gnus-summary-work-articles current-prefix-arg)) + (interactive (gnus-summary-work-articles current-prefix-arg) + gnus-summary-mode) (let ((count 0)) (dolist (article articles) (setq count (1+ count)) diff --git a/lisp/gnus/spam-stat.el b/lisp/gnus/spam-stat.el index 70753cad9c..3e804ecb4b 100644 --- a/lisp/gnus/spam-stat.el +++ b/lisp/gnus/spam-stat.el @@ -575,7 +575,6 @@ check the variable `spam-stat-score-data'." (defun spam-stat-count () "Return size of `spam-stat'." - (interactive) (hash-table-count spam-stat)) (defun spam-stat-test-directory (dir &optional verbose) diff --git a/lisp/gnus/spam.el b/lisp/gnus/spam.el index f7288c98f6..d00f0a60b6 100644 --- a/lisp/gnus/spam.el +++ b/lisp/gnus/spam.el @@ -1604,7 +1604,6 @@ parameters. A string as a parameter will set the `spam-split-group' to that string. See the Info node `(gnus)Fancy Mail Splitting' for more details." - (interactive) (setq spam-split-last-successful-check nil) (unless spam-split-disabled (let ((spam-split-group-choice spam-split-group)) @@ -1654,7 +1653,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (defun spam-find-spam () "Detect spam in the current newsgroup using `spam-split'." - (interactive) + (interactive nil gnus-summary-mode) (let* ((group gnus-newsgroup-name) (autodetect (gnus-parameter-spam-autodetect group)) @@ -2434,7 +2433,7 @@ With a non-nil REMOVE, remove the ADDRESSES." ;; return something sensible if the score can't be determined (defun spam-bogofilter-score (&optional recheck) "Get the Bogofilter spamicity score." - (interactive "P") + (interactive "P" gnus-summary-mode) (save-window-excursion (gnus-summary-show-article t) (set-buffer gnus-article-buffer) @@ -2606,7 +2605,7 @@ With a non-nil REMOVE, remove the ADDRESSES." ;; return something sensible if the score can't be determined (defun spam-spamassassin-score (&optional recheck) "Get the SpamAssassin score." - (interactive "P") + (interactive "P" gnus-summary-mode) (save-window-excursion (gnus-summary-show-article t) (set-buffer gnus-article-buffer) @@ -2673,7 +2672,7 @@ With a non-nil REMOVE, remove the ADDRESSES." ;; return something sensible if the score can't be determined (defun spam-bsfilter-score (&optional recheck) "Get the Bsfilter spamicity score." - (interactive "P") + (interactive "P" gnus-summary-mode) (save-window-excursion (gnus-summary-show-article t) (set-buffer gnus-article-buffer) @@ -2759,7 +2758,7 @@ With a non-nil REMOVE, remove the ADDRESSES." ;; return something sensible if the score can't be determined (defun spam-crm114-score () "Get the CRM114 Mailfilter pR." - (interactive) + (interactive nil gnus-summary-mode) (save-window-excursion (gnus-summary-show-article t) (set-buffer gnus-article-buffer) commit b535c8ba8735409b43ec9b1ce99a966cfa1383b1 Author: Lars Ingebrigtsen Date: Mon Feb 15 13:08:15 2021 +0100 Add a new variable `global-minor-modes' * doc/lispref/modes.texi (Minor Modes): Document it. * lisp/simple.el (global-minor-modes): New variable. (completion-in-mode-p): Use it. (completion-with-modes-p): Use it. * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Support it. diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 192ffb6a0a..e1299b52d4 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -1466,6 +1466,11 @@ This buffer-local variable lists the currently enabled minor modes in the current buffer, and is a list of symbols. @end defvar +@defvar global-minor-modes +This variable lists the currently enabled global minor modes, and is a +list of symbols. +@end defvar + @defvar minor-mode-list The value of this variable is a list of all minor mode commands. @end defvar diff --git a/etc/NEWS b/etc/NEWS index eeaed3b5cf..7f32f7bf6a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2297,7 +2297,13 @@ that is not compatible with byte code in previous Emacs versions. +++ ** New buffer-local variable 'local-minor-modes'. This permanently buffer-local variable holds a list of currently -enabled minor modes in the current buffer (as a list of symbols). +enabled non-global minor modes in the current buffer (as a list of +symbols). + ++++ +** New variable 'global-minor-modes'. +This variable holds a list of currently enabled global minor modes (as +a list of symbols). +++ ** 'define-minor-mode' now takes an :interactive argument. diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index c48ec505ce..4a9e58083b 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -330,11 +330,14 @@ or call the function `%s'.")))) nil) (t t))) - (unless ,globalp - ;; Keep `local-minor-modes' up to date. - (setq local-minor-modes (delq ',modefun local-minor-modes)) - (when ,getter - (push ',modefun local-minor-modes))) + ;; Keep minor modes list up to date. + ,@(if globalp + `((setq global-minor-modes (delq ',modefun global-minor-modes)) + (when ,getter + (push ',modefun global-minor-modes))) + `((setq local-minor-modes (delq ',modefun local-minor-modes)) + (when ,getter + (push ',modefun local-minor-modes)))) ,@body ;; The on/off hooks are here for backward compatibility only. (run-hooks ',hook (if ,getter ',hook-on ',hook-off)) diff --git a/lisp/simple.el b/lisp/simple.el index cb7496d37c..aafbb3e1f8 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -138,6 +138,10 @@ messages are highlighted; this helps to see what messages were visited." nil "Overlay highlighting the current error message in the `next-error' buffer.") +(defvar global-minor-modes nil + "A list of the currently enabled global minor modes. +This is a list of symbols.") + (defcustom next-error-hook nil "List of hook functions run by `next-error' after visiting source file." :type 'hook @@ -1985,14 +1989,16 @@ BUFFER, or any of the active minor modes in BUFFER." (or (provided-mode-derived-p (buffer-local-value 'major-mode buffer) (car modes)) (memq (car modes) - (buffer-local-value 'local-minor-modes buffer))) + (buffer-local-value 'local-minor-modes buffer)) + (memq (car modes) global-minor-modes)) ;; Uncommon case: Multiple modes. (apply #'provided-mode-derived-p (buffer-local-value 'major-mode buffer) modes) (seq-intersection modes (buffer-local-value 'local-minor-modes buffer) - #'eq))))) + #'eq) + (seq-intersection modes global-minor-modes #'eq))))) (defun completion-with-modes-p (modes buffer) "Say whether MODES are in action in BUFFER. @@ -2004,7 +2010,8 @@ or (if one of MODES is a minor mode), if it is switched on in BUFFER." ;; It's a minor mode. (seq-intersection modes (buffer-local-value 'local-minor-modes buffer) - #'eq))) + #'eq) + (seq-intersection modes global-minor-modes #'eq))) (defun completion-button-p (category buffer) "Return non-nil if there's a button of CATEGORY at point in BUFFER." commit 0bd846c17474b161b11fbe21545609cd545b1798 Author: Lars Ingebrigtsen Date: Mon Feb 15 12:44:57 2021 +0100 Rename minor-modes to local-minor-modes * doc/lispref/modes.texi (Minor Modes): Update documentation. * lisp/simple.el (completion-with-modes-p): Change usage. * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Change usage. * src/buffer.c: Rename from minor_modes to local_minor_modes throughout. (syms_of_buffer): Rename minor-modes to local-minor-modes. * src/buffer.h (struct buffer): Rename minor_modes_. * src/pdumper.c (dump_buffer): Update hash and usage. diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index b06cb58506..192ffb6a0a 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -1461,7 +1461,7 @@ used only with Diff mode. other minor modes in effect. It should be possible to activate and deactivate minor modes in any order. -@defvar minor-modes +@defvar local-minor-modes This buffer-local variable lists the currently enabled minor modes in the current buffer, and is a list of symbols. @end defvar diff --git a/etc/NEWS b/etc/NEWS index 1adfb8c5bb..eeaed3b5cf 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2295,7 +2295,7 @@ minor mode activated. Note that using this form will create byte code that is not compatible with byte code in previous Emacs versions. +++ -** New buffer-local variable 'minor-modes'. +** New buffer-local variable 'local-minor-modes'. This permanently buffer-local variable holds a list of currently enabled minor modes in the current buffer (as a list of symbols). diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 5ba0d2187f..c48ec505ce 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -331,10 +331,10 @@ or call the function `%s'.")))) (t t))) (unless ,globalp - ;; Keep `minor-modes' up to date. - (setq minor-modes (delq ',modefun minor-modes)) + ;; Keep `local-minor-modes' up to date. + (setq local-minor-modes (delq ',modefun local-minor-modes)) (when ,getter - (push ',modefun minor-modes))) + (push ',modefun local-minor-modes))) ,@body ;; The on/off hooks are here for backward compatibility only. (run-hooks ',hook (if ,getter ',hook-on ',hook-off)) diff --git a/lisp/simple.el b/lisp/simple.el index 8d27cf8d62..cb7496d37c 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1984,13 +1984,14 @@ BUFFER, or any of the active minor modes in BUFFER." (if (null (cdr modes)) (or (provided-mode-derived-p (buffer-local-value 'major-mode buffer) (car modes)) - (memq (car modes) (buffer-local-value 'minor-modes buffer))) + (memq (car modes) + (buffer-local-value 'local-minor-modes buffer))) ;; Uncommon case: Multiple modes. (apply #'provided-mode-derived-p (buffer-local-value 'major-mode buffer) modes) (seq-intersection modes - (buffer-local-value 'minor-modes buffer) + (buffer-local-value 'local-minor-modes buffer) #'eq))))) (defun completion-with-modes-p (modes buffer) @@ -2002,7 +2003,7 @@ or (if one of MODES is a minor mode), if it is switched on in BUFFER." modes) ;; It's a minor mode. (seq-intersection modes - (buffer-local-value 'minor-modes buffer) + (buffer-local-value 'local-minor-modes buffer) #'eq))) (defun completion-button-p (category buffer) diff --git a/src/buffer.c b/src/buffer.c index 487599dbbe..5bd9b37702 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -292,9 +292,9 @@ bset_major_mode (struct buffer *b, Lisp_Object val) b->major_mode_ = val; } static void -bset_minor_modes (struct buffer *b, Lisp_Object val) +bset_local_minor_modes (struct buffer *b, Lisp_Object val) { - b->minor_modes_ = val; + b->local_minor_modes_ = val; } static void bset_mark (struct buffer *b, Lisp_Object val) @@ -898,7 +898,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */) bset_file_truename (b, Qnil); bset_display_count (b, make_fixnum (0)); bset_backed_up (b, Qnil); - bset_minor_modes (b, Qnil); + bset_local_minor_modes (b, Qnil); bset_auto_save_file_name (b, Qnil); set_buffer_internal_1 (b); Fset (intern ("buffer-save-without-query"), Qnil); @@ -973,7 +973,7 @@ reset_buffer (register struct buffer *b) b->clip_changed = 0; b->prevent_redisplay_optimizations_p = 1; bset_backed_up (b, Qnil); - bset_minor_modes (b, Qnil); + bset_local_minor_modes (b, Qnil); BUF_AUTOSAVE_MODIFF (b) = 0; b->auto_save_failure_time = 0; bset_auto_save_file_name (b, Qnil); @@ -5158,7 +5158,7 @@ init_buffer_once (void) bset_auto_save_file_name (&buffer_local_flags, make_fixnum (-1)); bset_read_only (&buffer_local_flags, make_fixnum (-1)); bset_major_mode (&buffer_local_flags, make_fixnum (-1)); - bset_minor_modes (&buffer_local_flags, make_fixnum (-1)); + bset_local_minor_modes (&buffer_local_flags, make_fixnum (-1)); bset_mode_name (&buffer_local_flags, make_fixnum (-1)); bset_undo_list (&buffer_local_flags, make_fixnum (-1)); bset_mark_active (&buffer_local_flags, make_fixnum (-1)); @@ -5625,7 +5625,8 @@ The default value (normally `fundamental-mode') affects new buffers. A value of nil means to use the current buffer's major mode, provided it is not marked as "special". */); - DEFVAR_PER_BUFFER ("minor-modes", &BVAR (current_buffer, minor_modes), + DEFVAR_PER_BUFFER ("local-minor-modes", + &BVAR (current_buffer, local_minor_modes), Qnil, doc: /* Minor modes currently active in the current buffer. This is a list of symbols, or nil if there are no minor modes active. */); diff --git a/src/buffer.h b/src/buffer.h index 0668d16608..24e9c3fcbc 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -339,7 +339,7 @@ struct buffer Lisp_Object major_mode_; /* Symbol listing all currently enabled minor modes. */ - Lisp_Object minor_modes_; + Lisp_Object local_minor_modes_; /* Pretty name of major mode (e.g., "Lisp"). */ Lisp_Object mode_name_; diff --git a/src/pdumper.c b/src/pdumper.c index b68f992c33..337742fda4 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2692,7 +2692,7 @@ dump_hash_table (struct dump_context *ctx, static dump_off dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer) { -#if CHECK_STRUCTS && !defined HASH_buffer_732A01EB61 +#if CHECK_STRUCTS && !defined HASH_buffer_F8FE65D42F # error "buffer changed. See CHECK_STRUCTS comment in config.h." #endif struct buffer munged_buffer = *in_buffer; @@ -2703,7 +2703,7 @@ dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer) buffer->window_count = 0; else eassert (buffer->window_count == -1); - buffer->minor_modes_ = Qnil; + buffer->local_minor_modes_ = Qnil; buffer->last_selected_window_ = Qnil; buffer->display_count_ = make_fixnum (0); buffer->clip_changed = 0; commit 54e577fbc1fb2e1189388ac290fe70d0f87b6c76 Author: Stefan Monnier Date: Sun Feb 14 23:56:42 2021 -0500 * lisp/emacs-lisp/edebug.el (edebug-&optional, edebug-&rest): Remove vars According to my tests, `edebug-&optional` never has any effect. And `edebug-&rest` can be replaced with a closure. (edebug-&rest-wrapper): Remove function. (edebug--match-&-spec-op): Use a closure to remember the `specs`. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index efca7305fe..7fae4d21d5 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -1091,8 +1091,6 @@ circular objects. Let `read' read everything else." ;; This data is shared by all embedded definitions. (defvar edebug-top-window-data) -(defvar edebug-&optional) -(defvar edebug-&rest) (defvar edebug-gate nil) ;; whether no-match forces an error. (defvar edebug-def-name nil) ; name of definition, used by interactive-form @@ -1143,8 +1141,6 @@ purpose by adding an entry to this alist, and setting edebug-top-window-data edebug-def-name;; make sure it is locally nil ;; I don't like these here!! - edebug-&optional - edebug-&rest edebug-gate edebug-best-error edebug-error-point @@ -1512,6 +1508,9 @@ contains a circular object." ((consp form) ;; The first offset for a list form is for the list form itself. (if (eq 'quote (car form)) + ;; This makes sure we don't instrument 'foo + ;; which would cause the debugger to single-step + ;; the trivial evaluation of a constant. form (let* ((head (car form)) (spec (and (symbolp head) (edebug-get-spec head))) @@ -1584,10 +1583,7 @@ contains a circular object." ;; The after offset will be left in the cursor after processing the form. (let ((head (edebug-top-element-required cursor "Expected elements")) ;; Prevent backtracking whenever instrumenting. - (edebug-gate t) - ;; A list form is never optional because it matches anything. - (edebug-&optional nil) - (edebug-&rest nil)) + (edebug-gate t)) ;; Skip the first offset. (edebug-set-cursor cursor (edebug-cursor-expressions cursor) (cdr (edebug-cursor-offsets cursor))) @@ -1632,7 +1628,7 @@ contains a circular object." (setq edebug-error-point (or edebug-error-point (edebug-before-offset cursor)) edebug-best-error (or edebug-best-error args)) - (if (and edebug-gate (not edebug-&optional)) + (if edebug-gate (progn (if edebug-error-point (goto-char edebug-error-point)) @@ -1643,9 +1639,7 @@ contains a circular object." (defun edebug-match (cursor specs) ;; Top level spec matching function. ;; Used also at each lower level of specs. - (let (edebug-&optional - edebug-&rest - edebug-best-error + (let (edebug-best-error edebug-error-point (edebug-gate edebug-gate) ;; locally bound to limit effect ) @@ -1782,11 +1776,10 @@ contains a circular object." (cl-defmethod edebug--match-&-spec-op ((_ (eql &optional)) cursor specs) ;; Keep matching until one spec fails. - (edebug-&optional-wrapper cursor specs 'edebug-&optional-wrapper)) + (edebug-&optional-wrapper cursor specs #'edebug-&optional-wrapper)) (defun edebug-&optional-wrapper (cursor specs remainder-handler) (let (result - (edebug-&optional specs) (edebug-gate nil) (this-form (edebug-cursor-expressions cursor)) (this-offset (edebug-cursor-offsets cursor))) @@ -1801,21 +1794,21 @@ contains a circular object." nil))) -(defun edebug-&rest-wrapper (cursor specs remainder-handler) - (if (null specs) (setq specs edebug-&rest)) - ;; Reuse the &optional handler with this as the remainder handler. - (edebug-&optional-wrapper cursor specs remainder-handler)) - (cl-defgeneric edebug--match-&-spec-op (op cursor specs) "Handle &foo spec operators. &foo spec operators operate on all the subsequent SPECS.") (cl-defmethod edebug--match-&-spec-op ((_ (eql &rest)) cursor specs) ;; Repeatedly use specs until failure. - (let ((edebug-&rest specs) ;; remember these - edebug-best-error + (let (edebug-best-error edebug-error-point) - (edebug-&rest-wrapper cursor specs 'edebug-&rest-wrapper))) + ;; Reuse the &optional handler with this as the remainder handler. + (edebug-&optional-wrapper + cursor specs + (lambda (c s rh) + ;; `s' is the remaining spec to match. + ;; When it's nil, start over matching `specs'. + (edebug-&optional-wrapper c (or s specs) rh))))) (cl-defmethod edebug--match-&-spec-op ((_ (eql &or)) cursor specs) @@ -1961,19 +1954,15 @@ a sequence of elements." (defun edebug-match-sublist (cursor specs) ;; Match a sublist of specs. - (let (edebug-&optional - ;;edebug-best-error - ;;edebug-error-point - ) - (prog1 - ;; match with edebug-match-specs so edebug-best-error is not bound. - (edebug-match-specs cursor specs 'edebug-match-specs) - (if (not (edebug-empty-cursor cursor)) - (if edebug-best-error - (apply #'edebug-no-match cursor edebug-best-error) - ;; A failed &rest or &optional spec may leave some args. - (edebug-no-match cursor "Failed matching" specs) - ))))) + (prog1 + ;; match with edebug-match-specs so edebug-best-error is not bound. + (edebug-match-specs cursor specs 'edebug-match-specs) + (if (not (edebug-empty-cursor cursor)) + (if edebug-best-error + (apply #'edebug-no-match cursor edebug-best-error) + ;; A failed &rest or &optional spec may leave some args. + (edebug-no-match cursor "Failed matching" specs) + )))) (defun edebug-match-string (cursor spec) commit 623e534e49ad0a360d1291b917ce97515742a3e9 Author: Stefan Monnier Date: Sun Feb 14 22:56:08 2021 -0500 * lisp/emacs-lisp/byte-run.el (compiler-macro): Make it Edebuggable * lisp/emacs-lisp/gv.el (gc-expander, gv-setter): Reuse the spec of `compiler-macro`. diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index 48a7fe8061..8a22388f1d 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el @@ -113,6 +113,9 @@ The return value of this function is not used." (list 'function-put (list 'quote f) ''side-effect-free (list 'quote val)))) +(put 'compiler-macro 'edebug-declaration-spec + '(&or symbolp ("lambda" &define lambda-list lambda-doc def-body))) + (defalias 'byte-run--set-compiler-macro #'(lambda (f args compiler-function) (if (not (eq (car-safe compiler-function) 'lambda)) diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el index 3200b1c349..cbbed06d7c 100644 --- a/lisp/emacs-lisp/gv.el +++ b/lisp/emacs-lisp/gv.el @@ -188,7 +188,9 @@ arguments as NAME. DO is a function as defined in `gv-get'." defun-declarations-alist)) ;;;###autoload -(let ((spec '(&or symbolp ("lambda" &define lambda-list def-body)))) +(let ((spec (get 'compiler-macro 'edebug-declaration-spec))) + ;; It so happens that it's the same spec for gv-* as for compiler-macros. + ;; '(&or symbolp ("lambda" &define lambda-list lambda-doc def-body)) (put 'gv-expander 'edebug-declaration-spec spec) (put 'gv-setter 'edebug-declaration-spec spec)) commit 2594162b23f64dc394e8fe4035ea651ed54661ac Author: Lars Ingebrigtsen Date: Mon Feb 15 04:42:32 2021 +0100 Make the button completion predicate be more useful * lisp/simple.el (completion-button-p): Rework from `completion-at-point-p'. * lisp/net/shr.el (shr-show-alt-text): It should be possible to complete to commands that aren't bound to a key. diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 2596a34838..739b56b88c 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -434,7 +434,7 @@ Value is a pair of positions (START . END) if there is a non-nil (defun shr-show-alt-text () "Show the ALT text of the image under point." - (declare (completion 'completion-at-point-p)) + (declare (completion (lambda (_ b) (completion-button-p 'shr b)))) (interactive) (let ((text (get-text-property (point) 'shr-alt))) (if (not text) diff --git a/lisp/simple.el b/lisp/simple.el index ed0e753ee0..8d27cf8d62 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -2005,11 +2005,11 @@ or (if one of MODES is a minor mode), if it is switched on in BUFFER." (buffer-local-value 'minor-modes buffer) #'eq))) -(defun completion-at-point-p (symbol buffer) - "Return non-nil if SYMBOL is in a local map at point in BUFFER." +(defun completion-button-p (category buffer) + "Return non-nil if there's a button of CATEGORY at point in BUFFER." (with-current-buffer buffer - (when-let ((map (get-text-property (point) 'keymap))) - (where-is-internal symbol map)))) + (and (get-text-property (point) 'button) + (eq (get-text-property (point) 'category) category)))) (defun read-extended-command--affixation (command-names) (with-selected-window (or (minibuffer-selected-window) (selected-window)) commit df99b17e4fe7f6ee0c09ac990117ffea6ee3b695 Author: Lars Ingebrigtsen Date: Mon Feb 15 04:22:29 2021 +0100 Speed up completion-in-mode-p in the common case * lisp/simple.el (completion-in-mode-p): Make predicate more efficient in the common one-mode case. diff --git a/lisp/simple.el b/lisp/simple.el index 44a9c4dc98..ed0e753ee0 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1978,15 +1978,20 @@ This function uses the `read-extended-command-predicate' user option." "Say whether SYMBOL should be offered as a completion. This is true if the command is applicable to the major mode in BUFFER, or any of the active minor modes in BUFFER." - (or (null (command-modes symbol)) - ;; It's derived from a major mode. - (apply #'provided-mode-derived-p - (buffer-local-value 'major-mode buffer) - (command-modes symbol)) - ;; It's a minor mode. - (seq-intersection (command-modes symbol) - (buffer-local-value 'minor-modes buffer) - #'eq))) + (let ((modes (command-modes symbol))) + (or (null modes) + ;; Common case: Just a single mode. + (if (null (cdr modes)) + (or (provided-mode-derived-p + (buffer-local-value 'major-mode buffer) (car modes)) + (memq (car modes) (buffer-local-value 'minor-modes buffer))) + ;; Uncommon case: Multiple modes. + (apply #'provided-mode-derived-p + (buffer-local-value 'major-mode buffer) + modes) + (seq-intersection modes + (buffer-local-value 'minor-modes buffer) + #'eq))))) (defun completion-with-modes-p (modes buffer) "Say whether MODES are in action in BUFFER. commit a81dc34babc76e1fd09a23c9b59cad0ef612a95f Author: Lars Ingebrigtsen Date: Mon Feb 15 03:44:15 2021 +0100 Fix two syntax errors in Specification List * doc/lispref/edebug.texi (Specification List): Add a couple of missing @s. diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi index 3868f675ea..8942f55aff 100644 --- a/doc/lispref/edebug.texi +++ b/doc/lispref/edebug.texi @@ -1367,7 +1367,7 @@ Lets a function control the parsing of the remaining code. It takes the form @code{&interpose @var{spec} @var{fun} @var{args...}} and means that Edebug will first match @var{spec} against the code and then call @var{fun} with the code that matched @code{spec}, a parsing -function var{pf}, and finally @var{args...}. The parsing +function @var{pf}, and finally @var{args...}. The parsing function expects a single argument indicating the specification list to use to parse the remaining code. It should be called exactly once and returns the instrumented code that @var{fun} is expected to return. @@ -1375,7 +1375,7 @@ For example @code{(&interpose symbolp pcase--match-pat-args)} matches sexps whose first element is a symbol and then lets @code{pcase--match-pat-args} lookup the specs associated with that head symbol according to @code{pcase--match-pat-args} and -pass them to the var{pf} it received as argument. +pass them to the @var{pf} it received as argument. @item @var{other-symbol} @cindex indirect specifications commit b939f7ad359807e846831a9854e0d94260d9f084 Author: Stefan Monnier Date: Sun Feb 14 21:13:35 2021 -0500 * Edebug: Generalize `&lookup`, use it for `cl-macrolet` and `cl-generic` This allows the use of (declare (debug ...)) in the lexical macros defined with `cl-macrolet`. It also fixes the names used by Edebug for the methods of `cl-generic` so it doesn't need to use gensym and so they don't include the formal arg names any more. * lisp/emacs-lisp/edebug.el (edebug--match-&-spec-op): Rename from `edebug--handle-&-spec-op`. (edebug--match-&-spec-op <&interpose>): Rename from `&lookup` and generalize so it can let-bind dynamic variables around the rest of the parse. (edebug-lexical-macro-ctx): Rename from `edebug--cl-macrolet-defs` and make it into an alist. (edebug-list-form-args): Use the specs from `edebug-lexical-macro-ctx` when available. (edebug--current-cl-macrolet-defs): Delete var. (edebug-match-cl-macrolet-expr, edebug-match-cl-macrolet-name) (edebug-match-cl-macrolet-body): Delete functions. (def-declarations): Use new `&interpose`. (edebug--match-declare-arg): Rename from `edebug--get-declare-spec` and adjust to new calling convention. * lisp/subr.el (def-edebug-elem-spec): Fix docstring. (eval-after-load): Use `declare`. * lisp/emacs-lisp/cl-generic.el: Fix Edebug names so we don't need gensym any more and we only include the specializers but not the formal arg names. (cl--generic-edebug-name): New var. (cl--generic-edebug-remember-name, cl--generic-edebug-make-name): New funs. (cl-defgeneric, cl-defmethod): Use them. * lisp/emacs-lisp/cl-macs.el: Add support for `debug` declarations in `cl-macrolet`. (cl-declarations-or-string): Fix use of `lambda-doc` and allow use of `declare`. (edebug-lexical-macro-ctx): Declare var. (cl--edebug-macrolet-interposer): New function. (cl-macrolet): Use it to pass the right `lexical-macro-ctx` to the body. * lisp/emacs-lisp/pcase.el (pcase-PAT): Use new `&interpose`. (pcase--edebug-match-pat-args): Rename from `pcase--get-edebug-spec` and adjust to new calling convention. * test/lisp/emacs-lisp/cl-generic-tests.el (cl-defgeneric/edebug/method): Adjust to the new names. * test/lisp/emacs-lisp/edebug-tests.el (edebug-cl-defmethod-qualifier) (edebug-tests-cl-flet): Adjust to the new names. * doc/lispref/edebug.texi (Specification List): Document &interpose. diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi index 46f5cb9026..3868f675ea 100644 --- a/doc/lispref/edebug.texi +++ b/doc/lispref/edebug.texi @@ -1362,16 +1362,20 @@ is primarily used to generate more specific syntax error messages. See edebug-spec; it aborts the instrumentation, displaying the message in the minibuffer. -@item &lookup -Selects a specification based on the code being instrumented. -It takes the form @code{&lookup @var{spec} @var{fun} @var{args...}} +@item &interpose +Lets a function control the parsing of the remaining code. +It takes the form @code{&interpose @var{spec} @var{fun} @var{args...}} and means that Edebug will first match @var{spec} against the code and -then match the rest against the specification returned by calling -@var{fun} with the concatenation of @var{args...} and the code that -matched @code{spec}. For example @code{(&lookup symbolp -pcase--get-edebug-spec)} matches sexps whose first element is -a symbol and whose subsequent elements must obey the spec associated -with that head symbol according to @code{pcase--get-edebug-spec}. +then call @var{fun} with the code that matched @code{spec}, a parsing +function var{pf}, and finally @var{args...}. The parsing +function expects a single argument indicating the specification list +to use to parse the remaining code. It should be called exactly once +and returns the instrumented code that @var{fun} is expected to return. +For example @code{(&interpose symbolp pcase--match-pat-args)} matches +sexps whose first element is a symbol and then lets +@code{pcase--match-pat-args} lookup the specs associated +with that head symbol according to @code{pcase--match-pat-args} and +pass them to the var{pf} it received as argument. @item @var{other-symbol} @cindex indirect specifications diff --git a/etc/NEWS b/etc/NEWS index 33434d598a..1adfb8c5bb 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -959,7 +959,10 @@ declared obsolete. *** Edebug specification lists can use some new keywords: +++ -**** '&lookup SPEC FUN ARGS...' lets FUN compute the specs to use +**** '&interpose SPEC FUN ARGS..' lets FUN control parsing after SPEC. +More specifically, FUN is called with 'HEAD PF ARGS..' where +PF is a parsing function that expects a single argument (the specs to +use) and HEAD is the code that matched SPEC. +++ **** '&error MSG' unconditionally aborts the current edebug instrumentation. diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index 229608395e..279b9d137c 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el @@ -189,6 +189,32 @@ SPECIALIZERS-FUNCTION takes as first argument a tag value TAG (setf (cl--generic name) (setq generic (cl--generic-make name)))) generic)) +(defvar cl--generic-edebug-name nil) + +(defun cl--generic-edebug-remember-name (name pf &rest specs) + ;; Remember the name in `cl-defgeneric' so we can use it when building + ;; the names of its `:methods'. + (let ((cl--generic-edebug-name (car name))) + (funcall pf specs))) + +(defun cl--generic-edebug-make-name (in:method _oldname &rest quals-and-args) + ;; The name to use in Edebug for a method: use the generic + ;; function's name plus all its qualifiers and finish with + ;; its specializers. + (pcase-let* + ((basename (if in:method cl--generic-edebug-name (pop quals-and-args))) + (args (car (last quals-and-args))) + (`(,spec-args . ,_) (cl--generic-split-args args)) + (specializers (mapcar (lambda (spec-arg) + (if (eq '&context (car-safe (car spec-arg))) + spec-arg (cdr spec-arg))) + spec-args))) + (format "%s %s" + (mapconcat (lambda (sexp) (format "%s" sexp)) + (cons basename (butlast quals-and-args)) + " ") + specializers))) + ;;;###autoload (defmacro cl-defgeneric (name args &rest options-and-methods) "Create a generic function NAME. @@ -206,31 +232,22 @@ DEFAULT-BODY, if present, is used as the body of a default method. \(fn NAME ARGS [DOC-STRING] [OPTIONS-AND-METHODS...] &rest DEFAULT-BODY)" (declare (indent 2) (doc-string 3) (debug - (&define [&name sexp] ;Allow (setf ...) additionally to symbols. - listp lambda-doc - [&rest [&or - ("declare" &rest sexp) - (":argument-precedence-order" &rest sexp) - (&define ":method" - ;; FIXME: The `gensym' - ;; construct works around - ;; Bug#42672. We'd rather want - ;; names like those generated by - ;; `cl-defmethod', but that - ;; requires larger changes to - ;; Edebug. - [&name "cl-generic-:method@" []] - [&name [] gensym] ;Make it unique! - [&name - [[&rest cl-generic--method-qualifier-p] - ;; FIXME: We don't actually want the - ;; argument's names to be considered - ;; part of the name of the defined - ;; function. - listp]] ;Formal args - lambda-doc - def-body)]] - def-body))) + (&define + &interpose + [&name sexp] ;Allow (setf ...) additionally to symbols. + cl--generic-edebug-remember-name + listp lambda-doc + [&rest [&or + ("declare" &rest sexp) + (":argument-precedence-order" &rest sexp) + (&define ":method" + [&name + [[&rest cl-generic--method-qualifier-p] + listp] ;Formal args + cl--generic-edebug-make-name in:method] + lambda-doc + def-body)]] + def-body))) (let* ((doc (if (stringp (car-safe options-and-methods)) (pop options-and-methods))) (declarations nil) @@ -451,12 +468,9 @@ The set of acceptable TYPEs (also called \"specializers\") is defined (debug (&define ; this means we are defining something [&name [sexp ;Allow (setf ...) additionally to symbols. - ;; Multiple qualifiers are allowed. - [&rest cl-generic--method-qualifier-p] - ;; FIXME: We don't actually want the argument's names - ;; to be considered part of the name of the - ;; defined function. - listp]] ; arguments + [&rest cl-generic--method-qualifier-p] ;qualifiers + listp] ; arguments + cl--generic-edebug-make-name nil] lambda-doc ; documentation string def-body))) ; part to be debugged (let ((qualifiers nil)) diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index e2faf6df53..b9a8a3f112 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -190,7 +190,7 @@ The name is made by appending a number to PREFIX, default \"T\"." '(&rest ("cl-declare" &rest sexp))) (def-edebug-elem-spec 'cl-declarations-or-string - '(&or lambda-doc cl-declarations)) + '(lambda-doc &or ("declare" def-declarations) cl-declarations)) (def-edebug-elem-spec 'cl-lambda-list '(([&rest cl-lambda-arg] @@ -2193,6 +2193,20 @@ details. (macroexp-progn body) newenv))))) +(defvar edebug-lexical-macro-ctx) + +(defun cl--edebug-macrolet-interposer (bindings pf &rest specs) + ;; (cl-assert (null (cdr bindings))) + (setq bindings (car bindings)) + (let ((edebug-lexical-macro-ctx + (nconc (mapcar (lambda (binding) + (cons (car binding) + (when (eq 'declare (car-safe (nth 2 binding))) + (nth 1 (assq 'debug (cdr (nth 2 binding))))))) + bindings) + edebug-lexical-macro-ctx))) + (funcall pf specs))) + ;; The following ought to have a better definition for use with newer ;; byte compilers. ;;;###autoload @@ -2202,7 +2216,13 @@ This is like `cl-flet', but for macros instead of functions. \(fn ((NAME ARGLIST BODY...) ...) FORM...)" (declare (indent 1) - (debug (cl-macrolet-expr))) + (debug (&interpose (&rest (&define [&name symbolp "@cl-macrolet@"] + [&name [] gensym] ;Make it unique! + cl-macro-list + cl-declarations-or-string + def-body)) + cl--edebug-macrolet-interposer + cl-declarations body))) (if (cdr bindings) `(cl-macrolet (,(car bindings)) (cl-macrolet ,(cdr bindings) ,@body)) (if (null bindings) (macroexp-progn body) diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 8fadeba6c9..efca7305fe 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -1188,6 +1188,9 @@ purpose by adding an entry to this alist, and setting ;;;(message "all defs: %s all forms: %s" edebug-all-defs edebug-all-forms) (let ((result (cond + ;; IIUC, `&define' is treated specially here so as to avoid + ;; entering Edebug during the actual function's definition: + ;; we only want to enter Edebug later when the thing is called. (defining-form-p (if (or edebug-all-defs edebug-all-forms) ;; If it is a defining form and we are edebugging defs, @@ -1238,7 +1241,9 @@ purpose by adding an entry to this alist, and setting (defvar edebug-inside-func) ;; whether code is inside function context. ;; Currently def-form sets this to nil; def-body sets it to t. -(defvar edebug--cl-macrolet-defs) ;; Fully defined below. + +(defvar edebug-lexical-macro-ctx nil + "Alist mapping lexically scoped macro names to their debug spec.") (defun edebug-make-enter-wrapper (forms) ;; Generate the enter wrapper for some forms of a definition. @@ -1549,13 +1554,10 @@ contains a circular object." (defsubst edebug-list-form-args (head cursor) ;; Process the arguments of a list form given that head of form is a symbol. ;; Helper for edebug-list-form - (let ((spec (edebug-get-spec head))) + (let* ((lex-spec (assq head edebug-lexical-macro-ctx)) + (spec (if lex-spec (cdr lex-spec) + (edebug-get-spec head)))) (cond - ;; Treat cl-macrolet bindings like macros with no spec. - ((member head edebug--cl-macrolet-defs) - (if edebug-eval-macro-args - (edebug-forms cursor) - (edebug-sexps cursor))) (spec (cond ((consp spec) @@ -1569,7 +1571,7 @@ contains a circular object." ; but leave it in for compatibility. )) ;; No edebug-form-spec provided. - ((macrop head) + ((or lex-spec (macrop head)) (if edebug-eval-macro-args (edebug-forms cursor) (edebug-sexps cursor))) @@ -1689,7 +1691,7 @@ contains a circular object." (first-char (and (symbolp spec) (aref (symbol-name spec) 0))) (match (cond ((eq ?& first-char);; "&" symbols take all following specs. - (edebug--handle-&-spec-op spec cursor (cdr specs))) + (edebug--match-&-spec-op spec cursor (cdr specs))) ((eq ?: first-char);; ":" symbols take one following spec. (setq rest (cdr (cdr specs))) (edebug--handle-:-spec-op spec cursor (car (cdr specs)))) @@ -1731,9 +1733,6 @@ contains a circular object." (def-form . edebug-match-def-form) ;; Less frequently used: ;; (function . edebug-match-function) - (cl-macrolet-expr . edebug-match-cl-macrolet-expr) - (cl-macrolet-name . edebug-match-cl-macrolet-name) - (cl-macrolet-body . edebug-match-cl-macrolet-body) (place . edebug-match-place) (gate . edebug-match-gate) ;; (nil . edebug-match-nil) not this one - special case it. @@ -1781,7 +1780,7 @@ contains a circular object." (defsubst edebug-match-body (cursor) (edebug-forms cursor)) -(cl-defmethod edebug--handle-&-spec-op ((_ (eql &optional)) cursor specs) +(cl-defmethod edebug--match-&-spec-op ((_ (eql &optional)) cursor specs) ;; Keep matching until one spec fails. (edebug-&optional-wrapper cursor specs 'edebug-&optional-wrapper)) @@ -1807,11 +1806,11 @@ contains a circular object." ;; Reuse the &optional handler with this as the remainder handler. (edebug-&optional-wrapper cursor specs remainder-handler)) -(cl-defgeneric edebug--handle-&-spec-op (op cursor specs) +(cl-defgeneric edebug--match-&-spec-op (op cursor specs) "Handle &foo spec operators. &foo spec operators operate on all the subsequent SPECS.") -(cl-defmethod edebug--handle-&-spec-op ((_ (eql &rest)) cursor specs) +(cl-defmethod edebug--match-&-spec-op ((_ (eql &rest)) cursor specs) ;; Repeatedly use specs until failure. (let ((edebug-&rest specs) ;; remember these edebug-best-error @@ -1819,7 +1818,7 @@ contains a circular object." (edebug-&rest-wrapper cursor specs 'edebug-&rest-wrapper))) -(cl-defmethod edebug--handle-&-spec-op ((_ (eql &or)) cursor specs) +(cl-defmethod edebug--match-&-spec-op ((_ (eql &or)) cursor specs) ;; Keep matching until one spec succeeds, and return its results. ;; If none match, fail. ;; This needs to be optimized since most specs spend time here. @@ -1843,40 +1842,48 @@ contains a circular object." (apply #'edebug-no-match cursor "Expected one of" original-specs)) )) -(cl-defmethod edebug--handle-&-spec-op ((_ (eql &lookup)) cursor specs) - "Compute the specs for `&lookup SPEC FUN ARGS...'. +(cl-defmethod edebug--match-&-spec-op ((_ (eql &interpose)) cursor specs) + "Compute the specs for `&interpose SPEC FUN ARGS...'. Extracts the head of the data by matching it against SPEC, -and then matches the rest against the output of (FUN ARGS... HEAD)." +and then matches the rest by calling (FUN HEAD PF ARGS...) +where PF is the parsing function which FUN can call exactly once, +passing it the specs that it needs to match. +Note that HEAD will always be a list, since specs are defined to match +a sequence of elements." (pcase-let* ((`(,spec ,fun . ,args) specs) (exps (edebug-cursor-expressions cursor)) (instrumented-head (edebug-match-one-spec cursor spec)) (consumed (- (length exps) (length (edebug-cursor-expressions cursor)))) - (newspecs (apply fun (append args (seq-subseq exps 0 consumed))))) + (head (seq-subseq exps 0 consumed))) (cl-assert (eq (edebug-cursor-expressions cursor) (nthcdr consumed exps))) - ;; FIXME: What'd be the difference if we used `edebug-match-sublist', - ;; which is what `edebug-list-form-args' uses for the similar purpose - ;; when matching "normal" forms? - (append instrumented-head (edebug-match cursor newspecs)))) - -(cl-defmethod edebug--handle-&-spec-op ((_ (eql ¬)) cursor specs) + (apply fun `(,head + ,(lambda (newspecs) + ;; FIXME: What'd be the difference if we used + ;; `edebug-match-sublist', which is what + ;; `edebug-list-form-args' uses for the similar purpose + ;; when matching "normal" forms? + (append instrumented-head (edebug-match cursor newspecs))) + ,@args)))) + +(cl-defmethod edebug--match-&-spec-op ((_ (eql ¬)) cursor specs) ;; If any specs match, then fail (if (null (catch 'no-match (let ((edebug-gate nil)) (save-excursion - (edebug--handle-&-spec-op '&or cursor specs))) + (edebug--match-&-spec-op '&or cursor specs))) nil)) ;; This means something matched, so it is a no match. (edebug-no-match cursor "Unexpected")) ;; This means nothing matched, so it is OK. nil) ;; So, return nothing -(cl-defmethod edebug--handle-&-spec-op ((_ (eql &key)) cursor specs) +(cl-defmethod edebug--match-&-spec-op ((_ (eql &key)) cursor specs) ;; Following specs must look like ( ) ... ;; where is the name of a keyword, and spec is its spec. ;; This really doesn't save much over the expanded form and takes time. - (edebug--handle-&-spec-op + (edebug--match-&-spec-op '&rest cursor (cons '&or @@ -1885,7 +1892,7 @@ and then matches the rest against the output of (FUN ARGS... HEAD)." (car (cdr pair)))) specs)))) -(cl-defmethod edebug--handle-&-spec-op ((_ (eql &error)) cursor specs) +(cl-defmethod edebug--match-&-spec-op ((_ (eql &error)) cursor specs) ;; Signal an error, using the following string in the spec as argument. (let ((error-string (car specs)) (edebug-error-point (edebug-before-offset cursor))) @@ -1989,7 +1996,7 @@ and then matches the rest against the output of (FUN ARGS... HEAD)." (defun edebug-match-function (_cursor) (error "Use function-form instead of function in edebug spec")) -(cl-defmethod edebug--handle-&-spec-op ((_ (eql &define)) cursor specs) +(cl-defmethod edebug--match-&-spec-op ((_ (eql &define)) cursor specs) ;; Match a defining form. ;; Normally, &define is interpreted specially other places. ;; This should only be called inside of a spec list to match the remainder @@ -2003,7 +2010,7 @@ and then matches the rest against the output of (FUN ARGS... HEAD)." offsets) specs)) -(cl-defmethod edebug--handle-&-spec-op ((_ (eql &name)) cursor specs) +(cl-defmethod edebug--match-&-spec-op ((_ (eql &name)) cursor specs) "Compute the name for `&name SPEC FUN` spec operator. The full syntax of that operator is: @@ -2083,43 +2090,6 @@ SPEC is the symbol name prefix for `gensym'." suffix))) nil) -(defvar edebug--cl-macrolet-defs nil - "List of symbols found within the bindings of enclosing `cl-macrolet' forms.") -(defvar edebug--current-cl-macrolet-defs nil - "List of symbols found within the bindings of the current `cl-macrolet' form.") - -(defun edebug-match-cl-macrolet-expr (cursor) - "Match a `cl-macrolet' form at CURSOR." - (let (edebug--current-cl-macrolet-defs) - (edebug-match cursor - '((&rest (&define cl-macrolet-name cl-macro-list - cl-declarations-or-string - def-body)) - cl-declarations cl-macrolet-body)))) - -(defun edebug-match-cl-macrolet-name (cursor) - "Match the name in a `cl-macrolet' binding at CURSOR. -Collect the names in `edebug--cl-macrolet-defs' where they -will be checked by `edebug-list-form-args' and treated as -macros without a spec." - (let ((name (edebug-top-element-required cursor "Expected name"))) - (when (not (symbolp name)) - (edebug-no-match cursor "Bad name:" name)) - ;; Change edebug-def-name to avoid conflicts with - ;; names at global scope. - (setq edebug-def-name (gensym "edebug-anon")) - (edebug-move-cursor cursor) - (push name edebug--current-cl-macrolet-defs) - (list name))) - -(defun edebug-match-cl-macrolet-body (cursor) - "Match the body of a `cl-macrolet' expression at CURSOR. -Put the definitions collected in `edebug--current-cl-macrolet-defs' -into `edebug--cl-macrolet-defs' which is checked in `edebug-list-form-args'." - (let ((edebug--cl-macrolet-defs (nconc edebug--current-cl-macrolet-defs - edebug--cl-macrolet-defs))) - (edebug-match-body cursor))) - (defun edebug-match-arg (cursor) ;; set the def-args bound in edebug-defining-form (let ((edebug-arg (edebug-top-element-required cursor "Expected arg"))) @@ -2210,11 +2180,11 @@ into `edebug--cl-macrolet-defs' which is checked in `edebug-list-form-args'." )) (put name 'edebug-form-spec spec)) -(defun edebug--get-declare-spec (head) - (get head 'edebug-declaration-spec)) +(defun edebug--match-declare-arg (head pf) + (funcall pf (get (car head) 'edebug-declaration-spec))) (def-edebug-elem-spec 'def-declarations - '(&rest &or (&lookup symbolp edebug--get-declare-spec) sexp)) + '(&rest &or (&interpose symbolp edebug--match-declare-arg) sexp)) (def-edebug-elem-spec 'lambda-list '(([&rest arg] diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 5d428ac846..d3928fa505 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -63,7 +63,7 @@ (defvar pcase--dontwarn-upats '(pcase--dontcare)) (def-edebug-elem-spec 'pcase-PAT - '(&or (&lookup symbolp pcase--get-edebug-spec) sexp)) + '(&or (&interpose symbolp pcase--edebug-match-pat-args) sexp)) (def-edebug-elem-spec 'pcase-FUN '(&or lambda-expr @@ -73,7 +73,9 @@ ;; Only called from edebug. (declare-function edebug-get-spec "edebug" (symbol)) -(defun pcase--get-edebug-spec (head) +(defun pcase--edebug-match-pat-args (head pf) + ;; (cl-assert (null (cdr head))) + (setq head (car head)) (or (alist-get head '((quote sexp) (or &rest pcase-PAT) (and &rest pcase-PAT) @@ -81,7 +83,7 @@ (pred &or ("not" pcase-FUN) pcase-FUN) (app pcase-FUN pcase-PAT))) (let ((me (pcase--get-macroexpander head))) - (and me (symbolp me) (edebug-get-spec me))))) + (funcall pf (and me (symbolp me) (edebug-get-spec me)))))) (defun pcase--get-macroexpander (s) "Return the macroexpander for pcase pattern head S, or nil" diff --git a/lisp/subr.el b/lisp/subr.el index d215bd29a9..490aec93f1 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -64,8 +64,8 @@ For more information, see Info node `(elisp)Declaring Functions'." ;;;; Basic Lisp macros. -(defalias 'not 'null) -(defalias 'sxhash 'sxhash-equal) +(defalias 'not #'null) +(defalias 'sxhash #'sxhash-equal) (defmacro noreturn (form) "Evaluate FORM, expecting it not to return. @@ -93,10 +93,7 @@ Info node `(elisp)Specification List' for details." (defun def-edebug-elem-spec (name spec) "Define a new Edebug spec element NAME as shorthand for SPEC. -The SPEC has to be a list or a symbol. -The elements of the list describe the argument types; see -Info node `(elisp)Specification List' for details. -If SPEC is a symbol it should name another pre-existing Edebug element." +The SPEC has to be a list." (declare (indent 1)) (when (string-match "\\`[&:]" (symbol-name name)) ;; & and : have special meaning in spec element names. @@ -788,7 +785,7 @@ If TEST is omitted or nil, `equal' is used." (let (found (tail alist) value) (while (and tail (not found)) (let ((elt (car tail))) - (when (funcall (or test 'equal) (if (consp elt) (car elt) elt) key) + (when (funcall (or test #'equal) (if (consp elt) (car elt) elt) key) (setq found t value (if (consp elt) (cdr elt) default)))) (setq tail (cdr tail))) value)) @@ -938,14 +935,14 @@ For an approximate inverse of this, see `key-description'." "Make MAP override all normally self-inserting keys to be undefined. Normally, as an exception, digits and minus-sign are set to make prefix args, but optional second arg NODIGITS non-nil treats them like other chars." - (define-key map [remap self-insert-command] 'undefined) + (define-key map [remap self-insert-command] #'undefined) (or nodigits (let (loop) - (define-key map "-" 'negative-argument) + (define-key map "-" #'negative-argument) ;; Make plain numbers do numeric args. (setq loop ?0) (while (<= loop ?9) - (define-key map (char-to-string loop) 'digit-argument) + (define-key map (char-to-string loop) #'digit-argument) (setq loop (1+ loop)))))) (defun make-composed-keymap (maps &optional parent) @@ -982,8 +979,8 @@ a menu, so this function is not useful for non-menu keymaps." (setq key (if (<= (length key) 1) (aref key 0) (setq keymap (lookup-key keymap - (apply 'vector - (butlast (mapcar 'identity key))))) + (apply #'vector + (butlast (mapcar #'identity key))))) (aref key (1- (length key))))) (let ((tail keymap) done inserted) (while (and (not done) tail) @@ -1111,7 +1108,7 @@ Subkeymaps may be modified but are not canonicalized." (push (cons key item) bindings))) map))) ;; Create the new map. - (setq map (funcall (if ranges 'make-keymap 'make-sparse-keymap) prompt)) + (setq map (funcall (if ranges #'make-keymap #'make-sparse-keymap) prompt)) (dolist (binding ranges) ;; Treat char-ranges specially. FIXME: need to merge as well. (define-key map (vector (car binding)) (cdr binding))) @@ -1750,29 +1747,29 @@ be a list of the form returned by `event-start' and `event-end'." ;;;; Alternate names for functions - these are not being phased out. -(defalias 'send-string 'process-send-string) -(defalias 'send-region 'process-send-region) -(defalias 'string= 'string-equal) -(defalias 'string< 'string-lessp) -(defalias 'string> 'string-greaterp) -(defalias 'move-marker 'set-marker) -(defalias 'rplaca 'setcar) -(defalias 'rplacd 'setcdr) -(defalias 'beep 'ding) ;preserve lingual purity -(defalias 'indent-to-column 'indent-to) -(defalias 'backward-delete-char 'delete-backward-char) +(defalias 'send-string #'process-send-string) +(defalias 'send-region #'process-send-region) +(defalias 'string= #'string-equal) +(defalias 'string< #'string-lessp) +(defalias 'string> #'string-greaterp) +(defalias 'move-marker #'set-marker) +(defalias 'rplaca #'setcar) +(defalias 'rplacd #'setcdr) +(defalias 'beep #'ding) ;preserve lingual purity +(defalias 'indent-to-column #'indent-to) +(defalias 'backward-delete-char #'delete-backward-char) (defalias 'search-forward-regexp (symbol-function 're-search-forward)) (defalias 'search-backward-regexp (symbol-function 're-search-backward)) -(defalias 'int-to-string 'number-to-string) -(defalias 'store-match-data 'set-match-data) -(defalias 'chmod 'set-file-modes) -(defalias 'mkdir 'make-directory) +(defalias 'int-to-string #'number-to-string) +(defalias 'store-match-data #'set-match-data) +(defalias 'chmod #'set-file-modes) +(defalias 'mkdir #'make-directory) ;; These are the XEmacs names: -(defalias 'point-at-eol 'line-end-position) -(defalias 'point-at-bol 'line-beginning-position) +(defalias 'point-at-eol #'line-end-position) +(defalias 'point-at-bol #'line-beginning-position) (define-obsolete-function-alias 'user-original-login-name - 'user-login-name "28.1") + #'user-login-name "28.1") ;;;; Hook manipulation functions. @@ -1886,7 +1883,7 @@ one will be removed." (if local "Buffer-local" "Global")) fn-alist nil t) - fn-alist nil nil 'string=))) + fn-alist nil nil #'string=))) (list hook function local))) (or (boundp hook) (set hook nil)) (or (default-boundp hook) (set-default hook nil)) @@ -2098,9 +2095,9 @@ can do the job." (if (cond ((null compare-fn) (member element (symbol-value list-var))) - ((eq compare-fn 'eq) + ((eq compare-fn #'eq) (memq element (symbol-value list-var))) - ((eq compare-fn 'eql) + ((eq compare-fn #'eql) (memql element (symbol-value list-var))) (t (let ((lst (symbol-value list-var))) @@ -2532,7 +2529,7 @@ program before the output is collected. If STATUS-HANDLER is NIL, an error is signalled if the program returns with a non-zero exit status." (with-temp-buffer - (let ((status (apply 'call-process program nil (current-buffer) nil args))) + (let ((status (apply #'call-process program nil (current-buffer) nil args))) (if status-handler (funcall status-handler status) (unless (eq status 0) @@ -2578,7 +2575,7 @@ process." (format "Buffer %S has a running process; kill it? " (buffer-name (current-buffer))))))) -(add-hook 'kill-buffer-query-functions 'process-kill-buffer-query-function) +(add-hook 'kill-buffer-query-functions #'process-kill-buffer-query-function) ;; process plist management @@ -2766,7 +2763,7 @@ by doing (clear-string STRING)." (use-local-map read-passwd-map) (setq-local inhibit-modification-hooks nil) ;bug#15501. (setq-local show-paren-mode nil) ;bug#16091. - (add-hook 'post-command-hook 'read-password--hide-password nil t)) + (add-hook 'post-command-hook #'read-password--hide-password nil t)) (unwind-protect (let ((enable-recursive-minibuffers t) (read-hide-char (or read-hide-char ?*))) @@ -2776,8 +2773,8 @@ by doing (clear-string STRING)." ;; Not sure why but it seems that there might be cases where the ;; minibuffer is not always properly reset later on, so undo ;; whatever we've done here (bug#11392). - (remove-hook 'after-change-functions 'read-password--hide-password - 'local) + (remove-hook 'after-change-functions + #'read-password--hide-password 'local) (kill-local-variable 'post-self-insert-hook) ;; And of course, don't keep the sensitive data around. (erase-buffer)))))))) @@ -2807,7 +2804,7 @@ This function is used by the `interactive' code letter `n'." prompt nil nil nil (or hist 'read-number-history) (when default (if (consp default) - (mapcar 'number-to-string (delq nil default)) + (mapcar #'number-to-string (delq nil default)) (number-to-string default)))))) (condition-case nil (setq n (cond @@ -2961,13 +2958,13 @@ If there is a natural number at point, use it as default." (let ((map (make-sparse-keymap))) (set-keymap-parent map minibuffer-local-map) - (define-key map [remap self-insert-command] 'read-char-from-minibuffer-insert-char) + (define-key map [remap self-insert-command] #'read-char-from-minibuffer-insert-char) - (define-key map [remap recenter-top-bottom] 'minibuffer-recenter-top-bottom) - (define-key map [remap scroll-up-command] 'minibuffer-scroll-up-command) - (define-key map [remap scroll-down-command] 'minibuffer-scroll-down-command) - (define-key map [remap scroll-other-window] 'minibuffer-scroll-other-window) - (define-key map [remap scroll-other-window-down] 'minibuffer-scroll-other-window-down) + (define-key map [remap recenter-top-bottom] #'minibuffer-recenter-top-bottom) + (define-key map [remap scroll-up-command] #'minibuffer-scroll-up-command) + (define-key map [remap scroll-down-command] #'minibuffer-scroll-down-command) + (define-key map [remap scroll-other-window] #'minibuffer-scroll-other-window) + (define-key map [remap scroll-other-window-down] #'minibuffer-scroll-other-window-down) map) "Keymap for the `read-char-from-minibuffer' function.") @@ -3030,9 +3027,9 @@ There is no need to explicitly add `help-char' to CHARS; (help-form-show))))) (dolist (char chars) (define-key map (vector char) - 'read-char-from-minibuffer-insert-char)) + #'read-char-from-minibuffer-insert-char)) (define-key map [remap self-insert-command] - 'read-char-from-minibuffer-insert-other) + #'read-char-from-minibuffer-insert-other) (puthash (list help-form (cons help-char chars)) map read-char-from-minibuffer-map-hash) map)) @@ -3065,26 +3062,26 @@ There is no need to explicitly add `help-char' to CHARS; (set-keymap-parent map minibuffer-local-map) (dolist (symbol '(act act-and-show act-and-exit automatic)) - (define-key map (vector 'remap symbol) 'y-or-n-p-insert-y)) + (define-key map (vector 'remap symbol) #'y-or-n-p-insert-y)) - (define-key map [remap skip] 'y-or-n-p-insert-n) + (define-key map [remap skip] #'y-or-n-p-insert-n) (dolist (symbol '(backup undo undo-all edit edit-replacement delete-and-edit ignore self-insert-command)) - (define-key map (vector 'remap symbol) 'y-or-n-p-insert-other)) + (define-key map (vector 'remap symbol) #'y-or-n-p-insert-other)) - (define-key map [remap recenter] 'minibuffer-recenter-top-bottom) - (define-key map [remap scroll-up] 'minibuffer-scroll-up-command) - (define-key map [remap scroll-down] 'minibuffer-scroll-down-command) - (define-key map [remap scroll-other-window] 'minibuffer-scroll-other-window) - (define-key map [remap scroll-other-window-down] 'minibuffer-scroll-other-window-down) + (define-key map [remap recenter] #'minibuffer-recenter-top-bottom) + (define-key map [remap scroll-up] #'minibuffer-scroll-up-command) + (define-key map [remap scroll-down] #'minibuffer-scroll-down-command) + (define-key map [remap scroll-other-window] #'minibuffer-scroll-other-window) + (define-key map [remap scroll-other-window-down] #'minibuffer-scroll-other-window-down) - (define-key map [escape] 'abort-recursive-edit) + (define-key map [escape] #'abort-recursive-edit) (dolist (symbol '(quit exit exit-prefix)) - (define-key map (vector 'remap symbol) 'abort-recursive-edit)) + (define-key map (vector 'remap symbol) #'abort-recursive-edit)) ;; FIXME: try catch-all instead of explicit bindings: - ;; (define-key map [remap t] 'y-or-n-p-insert-other) + ;; (define-key map [remap t] #'y-or-n-p-insert-other) map) "Keymap that defines additional bindings for `y-or-n-p' answers.") @@ -3381,7 +3378,7 @@ This finishes the change group by reverting all of its changes." ;; For compatibility. (define-obsolete-function-alias 'redraw-modeline - 'force-mode-line-update "24.3") + #'force-mode-line-update "24.3") (defun momentary-string-display (string pos &optional exit-char message) "Momentarily display STRING in the buffer at POS. @@ -3525,7 +3522,7 @@ When in a major mode that does not provide its own symbol at point exactly." (let ((tag (funcall (or find-tag-default-function (get major-mode 'find-tag-default-function) - 'find-tag-default)))) + #'find-tag-default)))) (if tag (regexp-quote tag)))) (defun find-tag-default-as-symbol-regexp () @@ -3539,8 +3536,8 @@ symbol at point exactly." (if (and tag-regexp (eq (or find-tag-default-function (get major-mode 'find-tag-default-function) - 'find-tag-default) - 'find-tag-default)) + #'find-tag-default) + #'find-tag-default)) (format "\\_<%s\\_>" tag-regexp) tag-regexp))) @@ -3874,7 +3871,7 @@ discouraged." (call-process shell-file-name infile buffer display shell-command-switch - (mapconcat 'identity (cons command args) " "))) + (mapconcat #'identity (cons command args) " "))) (defun process-file-shell-command (command &optional infile buffer display &rest args) @@ -3886,7 +3883,7 @@ Similar to `call-process-shell-command', but calls `process-file'." (with-connection-local-variables (process-file shell-file-name infile buffer display shell-command-switch - (mapconcat 'identity (cons command args) " ")))) + (mapconcat #'identity (cons command args) " ")))) (defun call-shell-region (start end command &optional delete buffer) "Send text from START to END as input to an inferior shell running COMMAND. @@ -4905,8 +4902,8 @@ FILE, a string, is described in the function `eval-after-load'." "" ;; Note: regexp-opt can't be used here, since we need to call ;; this before Emacs has been fully started. 2006-05-21 - (concat "\\(" (mapconcat 'regexp-quote load-suffixes "\\|") "\\)?")) - "\\(" (mapconcat 'regexp-quote jka-compr-load-suffixes "\\|") + (concat "\\(" (mapconcat #'regexp-quote load-suffixes "\\|") "\\)?")) + "\\(" (mapconcat #'regexp-quote jka-compr-load-suffixes "\\|") "\\)?\\'")) (defun load-history-filename-element (file-regexp) @@ -4922,7 +4919,6 @@ Return nil if there isn't one." load-elt (and loads (car loads))))) load-elt)) -(put 'eval-after-load 'lisp-indent-function 1) (defun eval-after-load (file form) "Arrange that if FILE is loaded, FORM will be run immediately afterwards. If FILE is already loaded, evaluate FORM right now. @@ -4957,7 +4953,8 @@ like `font-lock'. This function makes or adds to an entry on `after-load-alist'. See also `with-eval-after-load'." - (declare (compiler-macro + (declare (indent 1) + (compiler-macro (lambda (whole) (if (eq 'quote (car-safe form)) ;; Quote with lambda so the compiler can look inside. @@ -5064,7 +5061,7 @@ This function is called directly from the C code." "Display delayed warnings from `delayed-warnings-list'. Used from `delayed-warnings-hook' (which see)." (dolist (warning (nreverse delayed-warnings-list)) - (apply 'display-warning warning)) + (apply #'display-warning warning)) (setq delayed-warnings-list nil)) (defun collapse-delayed-warnings () @@ -5397,7 +5394,7 @@ The properties used on SYMBOL are `composefunc', `sendfunc', `abortfunc', and `hookvar'." (put symbol 'composefunc composefunc) (put symbol 'sendfunc sendfunc) - (put symbol 'abortfunc (or abortfunc 'kill-buffer)) + (put symbol 'abortfunc (or abortfunc #'kill-buffer)) (put symbol 'hookvar (or hookvar 'mail-send-hook))) @@ -5562,7 +5559,7 @@ To test whether a function can be called interactively, use (set symbol tail))))) (define-obsolete-function-alias - 'set-temporary-overlay-map 'set-transient-map "24.4") + 'set-temporary-overlay-map #'set-transient-map "24.4") (defun set-transient-map (map &optional keep-pred on-exit) "Set MAP as a temporary keymap taking precedence over other keymaps. @@ -6190,7 +6187,7 @@ returned list are in the same order as in TREE. ;; Technically, `flatten-list' is a misnomer, but we provide it here ;; for discoverability: -(defalias 'flatten-list 'flatten-tree) +(defalias 'flatten-list #'flatten-tree) ;; The initial anchoring is for better performance in searching matches. (defconst regexp-unmatchable "\\`a\\`" diff --git a/test/lisp/emacs-lisp/cl-generic-tests.el b/test/lisp/emacs-lisp/cl-generic-tests.el index 4a01623cb8..9312fb44a1 100644 --- a/test/lisp/emacs-lisp/cl-generic-tests.el +++ b/test/lisp/emacs-lisp/cl-generic-tests.el @@ -269,9 +269,7 @@ Edebug symbols (Bug#42672)." (when (memq name instrumented-names) (error "Duplicate definition of `%s'" name)) (push name instrumented-names) - (edebug-new-definition name))) - ;; Make generated symbols reproducible. - (gensym-counter 10000)) + (edebug-new-definition name)))) (eval-buffer) (should (equal (reverse instrumented-names) @@ -280,11 +278,11 @@ Edebug symbols (Bug#42672)." ;; FIXME: We'd rather have names such as ;; `cl-defgeneric/edebug/method/1 ((_ number))', but ;; that requires further changes to Edebug. - (list (intern "cl-generic-:method@10000 ((_ number))") - (intern "cl-generic-:method@10001 ((_ string))") - (intern "cl-generic-:method@10002 :around ((_ number))") + (list (intern "cl-defgeneric/edebug/method/1 (number)") + (intern "cl-defgeneric/edebug/method/1 (string)") + (intern "cl-defgeneric/edebug/method/1 :around (number)") 'cl-defgeneric/edebug/method/1 - (intern "cl-generic-:method@10003 ((_ number))") + (intern "cl-defgeneric/edebug/method/2 (number)") 'cl-defgeneric/edebug/method/2)))))) (provide 'cl-generic-tests) diff --git a/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el b/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el index 835d3781d0..9257f167d6 100644 --- a/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el +++ b/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el @@ -62,12 +62,12 @@ (defun edebug-test-code-format-vector-node (node) !start!(concat "[" - (apply 'concat (mapcar 'edebug-test-code-format-node node))!apply! + (apply #'concat (mapcar #'edebug-test-code-format-node node))!apply! "]")) (defun edebug-test-code-format-list-node (node) !start!(concat "{" - (apply 'concat (mapcar 'edebug-test-code-format-node node))!apply! + (apply #'concat (mapcar #'edebug-test-code-format-node node))!apply! "}")) (defun edebug-test-code-format-node (node) diff --git a/test/lisp/emacs-lisp/edebug-tests.el b/test/lisp/emacs-lisp/edebug-tests.el index dfe2cb3206..d81376e45e 100644 --- a/test/lisp/emacs-lisp/edebug-tests.el +++ b/test/lisp/emacs-lisp/edebug-tests.el @@ -951,8 +951,8 @@ primary ones (Bug#42671)." (should (equal defined-symbols - (list (intern "edebug-cl-defmethod-qualifier :around ((_ number))") - (intern "edebug-cl-defmethod-qualifier ((_ number))"))))))) + (list (intern "edebug-cl-defmethod-qualifier :around (number)") + (intern "edebug-cl-defmethod-qualifier (number)"))))))) (ert-deftest edebug-tests--conflicting-internal-names () "Check conflicts between form's head symbols and Edebug spec elements." @@ -992,23 +992,19 @@ clashes (Bug#41853)." ;; Make generated symbols reproducible. (gensym-counter 10000)) (eval-buffer) - (should (equal (reverse instrumented-names) + ;; Use `format' so as to throw away differences due to + ;; interned/uninterned symbols. + (should (equal (format "%s" (reverse instrumented-names)) ;; The outer definitions come after the inner ;; ones because their body ends later. - ;; FIXME: There are twice as many inner - ;; definitions as expected due to Bug#41988. - ;; Once that bug is fixed, remove the duplicates. ;; FIXME: We'd rather have names such as ;; `edebug-tests-cl-flet-1@inner@cl-flet@10000', ;; but that requires further changes to Edebug. - '(inner@cl-flet@10000 - inner@cl-flet@10001 - inner@cl-flet@10002 - inner@cl-flet@10003 - edebug-tests-cl-flet-1 - inner@cl-flet@10004 - inner@cl-flet@10005 - edebug-tests-cl-flet-2)))))) + (format "%s" '(inner@cl-flet@10000 + inner@cl-flet@10001 + edebug-tests-cl-flet-1 + inner@cl-flet@10002 + edebug-tests-cl-flet-2))))))) (ert-deftest edebug-tests-duplicate-symbol-backtrack () "Check that Edebug doesn't create duplicate symbols when commit f5b172fb6e41e9bf75acd1fd94325a13d75987bf Author: Stefan Kangas Date: Mon Feb 15 00:43:15 2021 +0100 Avoid asking repeatedly about reloading bookmarks file * lisp/bookmark.el (bookmark-maybe-load-default-file): Reload watched bookmarks file only if its mtime has changed since the last query. This avoids asking repeatedly about reloading the bookmarks file if the user has already said "no" to a previous query. (bookmark--watch-file-already-queried-p): New function. (bookmark--watch-already-asked-mtime): New variable. diff --git a/lisp/bookmark.el b/lisp/bookmark.el index 5cdde258e0..98797a0de2 100644 --- a/lisp/bookmark.el +++ b/lisp/bookmark.el @@ -1040,6 +1040,14 @@ it to the name of the bookmark currently being set, advancing (car dired-directory))) (t (error "Buffer not visiting a file or directory"))))) +(defvar bookmark--watch-already-asked-mtime nil + "Mtime for which we already queried about reloading.") + +(defun bookmark--watch-file-already-queried-p (new-mtime) + ;; Don't ask repeatedly if user already said "no" to reloading a + ;; file with this mtime: + (prog1 (equal new-mtime bookmark--watch-already-asked-mtime) + (setq bookmark--watch-already-asked-mtime new-mtime))) (defun bookmark-maybe-load-default-file () "If bookmarks have not been loaded from the default place, load them." @@ -1048,13 +1056,15 @@ it to the name of the bookmark currently being set, advancing (file-readable-p bookmark-default-file) (bookmark-load bookmark-default-file t t))) ((and bookmark-watch-bookmark-file - (not (equal (nth 5 (file-attributes - (car bookmark-bookmarks-timestamp))) - (cdr bookmark-bookmarks-timestamp))) - (or (eq 'silent bookmark-watch-bookmark-file) - (yes-or-no-p - (format "Bookmarks %s changed on disk. Reload? " - (car bookmark-bookmarks-timestamp))))) + (let ((new-mtime (nth 5 (file-attributes + (car bookmark-bookmarks-timestamp)))) + (old-mtime (cdr bookmark-bookmarks-timestamp))) + (and (not (equal new-mtime old-mtime)) + (not (bookmark--watch-file-already-queried-p new-mtime)) + (or (eq 'silent bookmark-watch-bookmark-file) + (yes-or-no-p + (format "Bookmarks %s changed on disk. Reload? " + (car bookmark-bookmarks-timestamp))))))) (bookmark-load (car bookmark-bookmarks-timestamp) t t)))) (defun bookmark-maybe-sort-alist () commit 875ba6f7e79d6d9416e8661213fed362dc182e3f Author: Stefan Kangas Date: Sun Feb 14 21:37:23 2021 +0100 Mark up bookmark.el for correct modes * lisp/bookmark.el: Mark up all commands with applicable modes. diff --git a/lisp/bookmark.el b/lisp/bookmark.el index dcf8ff0d0a..5cdde258e0 100644 --- a/lisp/bookmark.el +++ b/lisp/bookmark.el @@ -953,7 +953,7 @@ When you have finished composing, type \\[bookmark-send-edited-annotation]. (defun bookmark-send-edited-annotation () "Use buffer contents as annotation for a bookmark. Lines beginning with `#' are ignored." - (interactive) + (interactive nil bookmark-edit-annotation-mode) (if (not (derived-mode-p 'bookmark-edit-annotation-mode)) (error "Not in bookmark-edit-annotation-mode")) (goto-char (point-min)) @@ -1827,7 +1827,7 @@ This is used for `tabulated-list-format' in `bookmark-bmenu-mode'." (defun bookmark-bmenu-toggle-filenames (&optional show) "Toggle whether filenames are shown in the bookmark list. Optional argument SHOW means show them unconditionally." - (interactive) + (interactive nil bookmark-bmenu-mode) (cond (show (setq bookmark-bmenu-toggle-filenames t)) @@ -1912,14 +1912,14 @@ If the annotation does not exist, do nothing." (defun bookmark-bmenu-mark () "Mark bookmark on this line to be displayed by \\\\[bookmark-bmenu-select]." - (interactive) + (interactive nil bookmark-bmenu-mode) (bookmark-bmenu-ensure-position) (tabulated-list-put-tag ">" t)) (defun bookmark-bmenu-mark-all () "Mark all listed bookmarks to be displayed by \\\\[bookmark-bmenu-select]." - (interactive) + (interactive nil bookmark-bmenu-mode) (save-excursion (goto-char (point-min)) (bookmark-bmenu-ensure-position) @@ -1930,7 +1930,7 @@ If the annotation does not exist, do nothing." (defun bookmark-bmenu-select () "Select this line's bookmark; also display bookmarks marked with `>'. You can mark bookmarks with the \\\\[bookmark-bmenu-mark] or \\\\[bookmark-bmenu-mark-all] commands." - (interactive) + (interactive nil bookmark-bmenu-mode) (let ((bmrk (bookmark-bmenu-bookmark)) (menu (current-buffer)) (others ()) @@ -1975,7 +1975,7 @@ You can mark bookmarks with the \\\\[bookmark-bmenu-mar (defun bookmark-bmenu-save () "Save the current list into a bookmark file. With a prefix arg, prompts for a file to save them in." - (interactive) + (interactive nil bookmark-bmenu-mode) (save-excursion (save-window-excursion (call-interactively 'bookmark-save) @@ -1984,7 +1984,7 @@ With a prefix arg, prompts for a file to save them in." (defun bookmark-bmenu-load () "Load the bookmark file and rebuild the bookmark menu-buffer." - (interactive) + (interactive nil bookmark-bmenu-mode) (bookmark-bmenu-ensure-position) (save-excursion (save-window-excursion @@ -1994,7 +1994,7 @@ With a prefix arg, prompts for a file to save them in." (defun bookmark-bmenu-1-window () "Select this line's bookmark, alone, in full frame." - (interactive) + (interactive nil bookmark-bmenu-mode) (bookmark-jump (bookmark-bmenu-bookmark)) (bury-buffer (other-buffer)) (delete-other-windows)) @@ -2002,7 +2002,7 @@ With a prefix arg, prompts for a file to save them in." (defun bookmark-bmenu-2-window () "Select this line's bookmark, with previous buffer in second window." - (interactive) + (interactive nil bookmark-bmenu-mode) (let ((bmrk (bookmark-bmenu-bookmark)) (menu (current-buffer)) (pop-up-windows t)) @@ -2014,20 +2014,20 @@ With a prefix arg, prompts for a file to save them in." (defun bookmark-bmenu-this-window () "Select this line's bookmark in this window." - (interactive) + (interactive nil bookmark-bmenu-mode) (bookmark-jump (bookmark-bmenu-bookmark))) (defun bookmark-bmenu-other-window () "Select this line's bookmark in other window, leaving bookmark menu visible." - (interactive) + (interactive nil bookmark-bmenu-mode) (let ((bookmark (bookmark-bmenu-bookmark))) (bookmark--jump-via bookmark 'switch-to-buffer-other-window))) (defun bookmark-bmenu-other-frame () "Select this line's bookmark in other frame." - (interactive) + (interactive nil bookmark-bmenu-mode) (let ((bookmark (bookmark-bmenu-bookmark)) (pop-up-frames t)) (bookmark-jump-other-window bookmark))) @@ -2035,7 +2035,7 @@ With a prefix arg, prompts for a file to save them in." (defun bookmark-bmenu-switch-other-window () "Make the other window select this line's bookmark. The current window remains selected." - (interactive) + (interactive nil bookmark-bmenu-mode) (let ((bookmark (bookmark-bmenu-bookmark)) (fun (lambda (b) (display-buffer b t)))) (bookmark--jump-via bookmark fun))) @@ -2044,7 +2044,7 @@ The current window remains selected." "Jump to bookmark at mouse EVENT position in other window. Move point in menu buffer to the position of EVENT and leave bookmark menu visible." - (interactive "e") + (interactive "e" bookmark-bmenu-mode) (with-current-buffer (window-buffer (posn-window (event-end event))) (save-excursion (goto-char (posn-point (event-end event))) @@ -2053,20 +2053,20 @@ bookmark menu visible." (defun bookmark-bmenu-show-annotation () "Show the annotation for the current bookmark in another window." - (interactive) + (interactive nil bookmark-bmenu-mode) (let ((bookmark (bookmark-bmenu-bookmark))) (bookmark-show-annotation bookmark))) (defun bookmark-bmenu-show-all-annotations () "Show the annotation for all bookmarks in another window." - (interactive) + (interactive nil bookmark-bmenu-mode) (bookmark-show-all-annotations)) (defun bookmark-bmenu-edit-annotation () "Edit the annotation for the current bookmark in another window." - (interactive) + (interactive nil bookmark-bmenu-mode) (let ((bookmark (bookmark-bmenu-bookmark))) (bookmark-edit-annotation bookmark t))) @@ -2074,7 +2074,7 @@ bookmark menu visible." (defun bookmark-bmenu-unmark (&optional backup) "Cancel all requested operations on bookmark on this line and move down. Optional BACKUP means move up." - (interactive "P") + (interactive "P" bookmark-bmenu-mode) ;; any flags to reset according to circumstances? How about a ;; flag indicating whether this bookmark is being visited? ;; well, we don't have this now, so maybe later. @@ -2085,7 +2085,7 @@ Optional BACKUP means move up." (defun bookmark-bmenu-backup-unmark () "Move up and cancel all requested operations on bookmark on line above." - (interactive) + (interactive nil bookmark-bmenu-mode) (forward-line -1) (bookmark-bmenu-ensure-position) (bookmark-bmenu-unmark) @@ -2095,7 +2095,7 @@ Optional BACKUP means move up." (defun bookmark-bmenu-unmark-all () "Cancel all requested operations on all listed bookmarks." - (interactive) + (interactive nil bookmark-bmenu-mode) (save-excursion (goto-char (point-min)) (bookmark-bmenu-ensure-position) @@ -2106,7 +2106,7 @@ Optional BACKUP means move up." (defun bookmark-bmenu-delete () "Mark bookmark on this line to be deleted. To carry out the deletions that you've marked, use \\\\[bookmark-bmenu-execute-deletions]." - (interactive) + (interactive nil bookmark-bmenu-mode) (bookmark-bmenu-ensure-position) (tabulated-list-put-tag "D" t)) @@ -2114,7 +2114,7 @@ To carry out the deletions that you've marked, use \\\\ (defun bookmark-bmenu-delete-backwards () "Mark bookmark on this line to be deleted, then move up one line. To carry out the deletions that you've marked, use \\\\[bookmark-bmenu-execute-deletions]." - (interactive) + (interactive nil bookmark-bmenu-mode) (bookmark-bmenu-delete) (forward-line -2)) @@ -2123,7 +2123,7 @@ To carry out the deletions that you've marked, use \\\\ "Mark all listed bookmarks as to be deleted. To remove all deletion marks, use \\\\[bookmark-bmenu-unmark-all]. To carry out the deletions that you've marked, use \\\\[bookmark-bmenu-execute-deletions]." - (interactive) + (interactive nil bookmark-bmenu-mode) (save-excursion (goto-char (point-min)) (bookmark-bmenu-ensure-position) @@ -2133,7 +2133,7 @@ To carry out the deletions that you've marked, use \\\\ (defun bookmark-bmenu-execute-deletions () "Delete bookmarks flagged `D'." - (interactive) + (interactive nil bookmark-bmenu-mode) (let ((reporter (make-progress-reporter "Deleting bookmarks...")) (o-point (point)) (o-str (save-excursion @@ -2160,7 +2160,7 @@ To carry out the deletions that you've marked, use \\\\ (defun bookmark-bmenu-rename () "Rename bookmark on current line. Prompts for a new name." - (interactive) + (interactive nil bookmark-bmenu-mode) (let ((bmrk (bookmark-bmenu-bookmark)) (thispoint (point))) (bookmark-rename bmrk) @@ -2169,14 +2169,14 @@ To carry out the deletions that you've marked, use \\\\ (defun bookmark-bmenu-locate () "Display location of this bookmark. Displays in the minibuffer." - (interactive) + (interactive nil bookmark-bmenu-mode) (let ((bmrk (bookmark-bmenu-bookmark))) (message "%s" (bookmark-location bmrk)))) (defun bookmark-bmenu-relocate () "Change the absolute file name of the bookmark on the current line. Prompt with completion for the new path." - (interactive) + (interactive nil bookmark-bmenu-mode) (let ((bmrk (bookmark-bmenu-bookmark)) (thispoint (point))) (bookmark-relocate bmrk) @@ -2196,7 +2196,7 @@ Prompt with completion for the new path." ;;;###autoload (defun bookmark-bmenu-search () "Incremental search of bookmarks, hiding the non-matches as we go." - (interactive) + (interactive nil bookmark-bmenu-mode) (let ((bmk (bookmark-bmenu-bookmark)) (timer nil)) (unwind-protect commit 58b9e84a3188837b9a4d45ecccc20bb9f259e278 Author: Lars Ingebrigtsen Date: Sun Feb 14 22:57:19 2021 +0100 Add a comment to `read-extended-command' * lisp/simple.el (read-extended-command): Add a comment. diff --git a/lisp/simple.el b/lisp/simple.el index a547417d7e..44a9c4dc98 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1966,6 +1966,9 @@ This function uses the `read-extended-command-predicate' user option." (complete-with-action action obarray string pred))) (lambda (sym) (and (commandp sym) + ;;; FIXME: This should also be possible to disable by + ;;; the user, but I'm not quite sure what the right + ;;; design for that would look like. (if (get sym 'completion-predicate) (funcall (get sym 'completion-predicate) sym buffer) (funcall read-extended-command-predicate sym buffer)))) commit 1c229d939b09b6725824ace1c510739a1910ac87 Author: Eli Zaretskii Date: Sun Feb 14 22:11:05 2021 +0200 * src/xdisp.c (move_it_to): Fix last change. (Bug#46316) diff --git a/src/xdisp.c b/src/xdisp.c index a195682421..f86d3527b3 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10051,7 +10051,8 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos if ((op & MOVE_TO_POS) != 0 && (IT_CHARPOS (*it) > to_charpos || (IT_CHARPOS (*it) == to_charpos - && to_charpos == ZV))) + && to_charpos == ZV + && FETCH_BYTE (ZV_BYTE - 1) != '\n'))) { reached = 9; goto out; commit f02c93ae7a4f627f5bc37a8cf0cd70cffc4b7bb7 Author: Lars Ingebrigtsen Date: Sun Feb 14 20:34:03 2021 +0100 Add a possible completion predicate for buttons * lisp/simple.el (completion-at-point-p): New predicate. * lisp/net/shr.el (shr-show-alt-text): Mark up as a button. diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 9c3740fccc..2596a34838 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -434,6 +434,7 @@ Value is a pair of positions (START . END) if there is a non-nil (defun shr-show-alt-text () "Show the ALT text of the image under point." + (declare (completion 'completion-at-point-p)) (interactive) (let ((text (get-text-property (point) 'shr-alt))) (if (not text) diff --git a/lisp/simple.el b/lisp/simple.el index 02d3b7df5f..a547417d7e 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1997,6 +1997,12 @@ or (if one of MODES is a minor mode), if it is switched on in BUFFER." (buffer-local-value 'minor-modes buffer) #'eq))) +(defun completion-at-point-p (symbol buffer) + "Return non-nil if SYMBOL is in a local map at point in BUFFER." + (with-current-buffer buffer + (when-let ((map (get-text-property (point) 'keymap))) + (where-is-internal symbol map)))) + (defun read-extended-command--affixation (command-names) (with-selected-window (or (minibuffer-selected-window) (selected-window)) (mapcar commit 02869b6c67d90ba5e75d37e9a83de9c831898fbc Author: Lars Ingebrigtsen Date: Sun Feb 14 20:24:23 2021 +0100 Make completion-with-modes-p work with minor modes, too * lisp/simple.el (completion-with-modes-p): Work with minor modes, too. diff --git a/lisp/simple.el b/lisp/simple.el index 015fa9e4d5..02d3b7df5f 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1974,7 +1974,7 @@ This function uses the `read-extended-command-predicate' user option." (defun completion-in-mode-p (symbol buffer) "Say whether SYMBOL should be offered as a completion. This is true if the command is applicable to the major mode in -BUFFER." +BUFFER, or any of the active minor modes in BUFFER." (or (null (command-modes symbol)) ;; It's derived from a major mode. (apply #'provided-mode-derived-p @@ -1986,9 +1986,16 @@ BUFFER." #'eq))) (defun completion-with-modes-p (modes buffer) - (apply #'provided-mode-derived-p - (buffer-local-value 'major-mode buffer) - modes)) + "Say whether MODES are in action in BUFFER. +This is the case if either the major mode is derived from one of MODES, +or (if one of MODES is a minor mode), if it is switched on in BUFFER." + (or (apply #'provided-mode-derived-p + (buffer-local-value 'major-mode buffer) + modes) + ;; It's a minor mode. + (seq-intersection modes + (buffer-local-value 'minor-modes buffer) + #'eq))) (defun read-extended-command--affixation (command-names) (with-selected-window (or (minibuffer-selected-window) (selected-window)) commit 27eaf37241221a5a37f3d628ac247ac0a039cdb5 Author: Bastian Beranek Date: Mon Feb 8 18:12:33 2021 +0100 Fix showing and hiding of tab-bar on new frames (bug#46299) * lisp/tab-bar.el (tab-bar--update-tab-bar-lines) (tab-bar--tab-bar-lines-for-frame): New functions to update value of tab-bar-lines in frames. (tab-bar-mode, tab-bar-new-tab-to, tab-bar-close-tab) (tab-bar-close-other-tab, tab-bar-show :set): Use new function. (tab-bar-select-tab-modifiers :set): Work around visual glitch. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 6720d82b47..4e47ae2c10 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -89,8 +89,9 @@ Possible modifier keys are `control', `meta', `shift', `hyper', `super' and :set (lambda (sym val) (set-default sym val) ;; Reenable the tab-bar with new keybindings - (tab-bar-mode -1) - (tab-bar-mode 1)) + (when tab-bar-mode + (tab-bar-mode -1) + (tab-bar-mode 1))) :group 'tab-bar :version "27.1") @@ -134,21 +135,47 @@ Possible modifier keys are `control', `meta', `shift', `hyper', `super' and :ascent center)) tab-bar-close-button))) +(defun tab-bar--tab-bar-lines-for-frame (frame) + "Determine and return the value of `tab-bar-lines' for FRAME. +Return 0 if `tab-bar-mode' is not enabled. Otherwise return +either 1 or 0 depending on the value of the customizable variable +`tab-bar-show', which see." + (cond + ((not tab-bar-mode) 0) + ((not tab-bar-show) 0) + ((eq tab-bar-show t) 1) + ((natnump tab-bar-show) + (if (> (length (funcall tab-bar-tabs-function frame)) tab-bar-show) 1 0)))) + +(defun tab-bar--update-tab-bar-lines (&optional frames) + "Update the `tab-bar-lines' parameter in frames. +Update the tab-bar-lines frame parameter. If the optional +parameter FRAMES is omitted, update only the currently selected +frame. If it is `t', update all frames as well as the default +for new frames. Otherwise FRAMES should be a list of frames to +update." + (let ((frame-lst (cond ((null frames) + (list (selected-frame))) + ((eq frames t) + (frame-list)) + (t frames)))) + ;; Loop over all frames and update default-frame-alist + (dolist (frame frame-lst) + (set-frame-parameter frame 'tab-bar-lines (tab-bar--tab-bar-lines-for-frame frame)))) + (when (eq frames t) + (setq default-frame-alist + (cons (cons 'tab-bar-lines (if (and tab-bar-mode (eq tab-bar-show t)) 1 0)) + (assq-delete-all 'tab-bar-lines default-frame-alist))))) + (define-minor-mode tab-bar-mode "Toggle the tab bar in all graphical frames (Tab Bar mode)." :global t ;; It's defined in C/cus-start, this stops the d-m-m macro defining it again. :variable tab-bar-mode - (let ((val (if tab-bar-mode 1 0))) - (dolist (frame (frame-list)) - (set-frame-parameter frame 'tab-bar-lines val)) - ;; If the user has given `default-frame-alist' a `tab-bar-lines' - ;; parameter, replace it. - (if (assq 'tab-bar-lines default-frame-alist) - (setq default-frame-alist - (cons (cons 'tab-bar-lines val) - (assq-delete-all 'tab-bar-lines - default-frame-alist))))) + + ;; Recalculate tab-bar-lines for all frames + (tab-bar--update-tab-bar-lines t) + (when tab-bar-mode (tab-bar--load-buttons)) (if tab-bar-mode @@ -250,17 +277,9 @@ you can use the command `toggle-frame-tab-bar'." :initialize 'custom-initialize-default :set (lambda (sym val) (set-default sym val) - ;; Preload button images - (tab-bar-mode 1) - ;; Then handle each frame individually - (dolist (frame (frame-list)) - (set-frame-parameter - frame 'tab-bar-lines - (if (or (eq val t) - (and (natnump val) - (> (length (funcall tab-bar-tabs-function frame)) - val))) - 1 0)))) + (if val + (tab-bar-mode 1) + (tab-bar--update-tab-bar-lines t))) :group 'tab-bar :version "27.1") @@ -852,16 +871,12 @@ After the tab is created, the hooks in (run-hook-with-args 'tab-bar-tab-post-open-functions (nth to-index tabs))) - (cond - ((eq tab-bar-show t) - (tab-bar-mode 1)) - ((and (natnump tab-bar-show) - (> (length (funcall tab-bar-tabs-function)) tab-bar-show) - (zerop (frame-parameter nil 'tab-bar-lines))) - (progn - (tab-bar--load-buttons) - (tab-bar--define-keys) - (set-frame-parameter nil 'tab-bar-lines 1)))) + (when tab-bar-show + (if (not tab-bar-mode) + ;; Switch on tab-bar-mode, since a tab was created + ;; Note: This also updates tab-bar-lines + (tab-bar-mode 1) + (tab-bar--update-tab-bar-lines))) (force-mode-line-update) (unless tab-bar-mode @@ -996,11 +1011,8 @@ for the last tab on a frame is determined by tab-bar-closed-tabs) (set-frame-parameter nil 'tabs (delq close-tab tabs))) - (when (and (not (zerop (frame-parameter nil 'tab-bar-lines))) - (natnump tab-bar-show) - (<= (length (funcall tab-bar-tabs-function)) - tab-bar-show)) - (set-frame-parameter nil 'tab-bar-lines 0)) + ;; Recalculate tab-bar-lines and update frames + (tab-bar--update-tab-bar-lines) (force-mode-line-update) (unless tab-bar-mode @@ -1036,11 +1048,8 @@ for the last tab on a frame is determined by (run-hook-with-args 'tab-bar-tab-pre-close-functions (nth index tabs) nil))) (set-frame-parameter nil 'tabs (list (nth current-index tabs))) - (when (and (not (zerop (frame-parameter nil 'tab-bar-lines))) - (natnump tab-bar-show) - (<= (length (funcall tab-bar-tabs-function)) - tab-bar-show)) - (set-frame-parameter nil 'tab-bar-lines 0)) + ;; Recalculate tab-bar-lines and update frames + (tab-bar--update-tab-bar-lines) (force-mode-line-update) (unless tab-bar-mode commit d6bfa30860358c54b689e2e82d8c8d59b424ac45 Author: Lars Ingebrigtsen Date: Sun Feb 14 18:14:36 2021 +0100 Do command markup in blackbox.el diff --git a/lisp/play/blackbox.el b/lisp/play/blackbox.el index 61b0878b1c..13bcdcc859 100644 --- a/lisp/play/blackbox.el +++ b/lisp/play/blackbox.el @@ -274,45 +274,45 @@ a reflection." )) (defun bb-right (count) - (interactive "p") + (interactive "p" blackbox-mode) (while (and (> count 0) (< bb-x 8)) (forward-char 2) (setq bb-x (1+ bb-x)) (setq count (1- count)))) (defun bb-left (count) - (interactive "p") + (interactive "p" blackbox-mode) (while (and (> count 0) (> bb-x -1)) (backward-char 2) (setq bb-x (1- bb-x)) (setq count (1- count)))) (defun bb-up (count) - (interactive "p") + (interactive "p" blackbox-mode) (while (and (> count 0) (> bb-y -1)) (with-no-warnings (previous-line)) (setq bb-y (1- bb-y)) (setq count (1- count)))) (defun bb-down (count) - (interactive "p") + (interactive "p" blackbox-mode) (while (and (> count 0) (< bb-y 8)) (with-no-warnings (next-line)) (setq bb-y (1+ bb-y)) (setq count (1- count)))) (defun bb-eol () - (interactive) + (interactive nil blackbox-mode) (setq bb-x 8) (bb-goto (cons bb-x bb-y))) (defun bb-bol () - (interactive) + (interactive nil blackbox-mode) (setq bb-x -1) (bb-goto (cons bb-x bb-y))) (defun bb-romp () - (interactive) + (interactive nil blackbox-mode) (cond ((and (or (= bb-x -1) (= bb-x 8)) @@ -379,7 +379,7 @@ a reflection." (defun bb-done () "Finish the game and report score." - (interactive) + (interactive nil blackbox-mode) (let (bogus-balls) (cond ((not (= (length bb-balls-placed) (length bb-board))) commit c3396917725a537e9060f2144b6907ab870b22dd Author: Lars Ingebrigtsen Date: Sun Feb 14 18:01:06 2021 +0100 Fix byte-run--set-modes call signature * lisp/emacs-lisp/byte-run.el (byte-run--set-modes): We take a list of modes, not a single one (and fix the quoting). diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index 30fcbf2b9c..48a7fe8061 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el @@ -149,10 +149,10 @@ The return value of this function is not used." ''completion-predicate val))) (defalias 'byte-run--set-modes - #'(lambda (f _args val) + #'(lambda (f _args &rest val) (list 'function-put (list 'quote f) ''completion-predicate `(lambda (_ b) - (completion-with-modes-p ,val b))))) + (completion-with-modes-p ',val b))))) ;; Add any new entries to info node `(elisp)Declare Form'. (defvar defun-declarations-alist commit aa3a48510b9f3397af6afdcde899ec85c6cb27fe Author: Lars Ingebrigtsen Date: Sun Feb 14 16:57:05 2021 +0100 Fix missing ' in NEWS diff --git a/etc/NEWS b/etc/NEWS index c58587f12b..33434d598a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2088,7 +2088,7 @@ first). ** The 'M-o M-s' and 'M-o M-S' global bindings have been removed. Use 'M-x center-line' and 'M-x center-paragraph' instead. -** The 'M-o M-o global binding have been removed. +** The 'M-o M-o' global binding have been removed. Use 'M-x font-lock-fontify-block' instead. ** In 'f90-mode', the backslash character ('\') no longer escapes. commit 0334ac671c228bc967cff6a37c335f04491dd0e7 Author: Lars Ingebrigtsen Date: Sun Feb 14 16:55:37 2021 +0100 Also mention `M-o M-o' removal * lisp/loadup.el (facemenu-keymap-restore): Also restore `M-o M-o'. diff --git a/etc/NEWS b/etc/NEWS index 22c320bfa3..c58587f12b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2083,11 +2083,14 @@ first). * Incompatible Editing Changes in Emacs 28.1 -** The 'M-o' ('facemanu-keymap') global binding has been removed. +** The 'M-o' ('facemenu-keymap') global binding has been removed. ** The 'M-o M-s' and 'M-o M-S' global bindings have been removed. Use 'M-x center-line' and 'M-x center-paragraph' instead. +** The 'M-o M-o global binding have been removed. +Use 'M-x font-lock-fontify-block' instead. + ** In 'f90-mode', the backslash character ('\') no longer escapes. For about a decade, the backslash character has no longer had a special escape syntax in Fortran F90. To get the old behaviour back, diff --git a/lisp/loadup.el b/lisp/loadup.el index c91c00a107..d60aa2ead2 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -496,7 +496,8 @@ lost after dumping"))) (define-key global-map [C-down-mouse-2] 'facemenu-menu) (define-key global-map "\M-o" 'facemenu-keymap) (define-key facemenu-keymap "\eS" 'center-paragraph) - (define-key facemenu-keymap "\es" 'center-line)) + (define-key facemenu-keymap "\es" 'center-line) + (define-key facemenu-keymap "\M-o" 'font-lock-fontify-block)) (if dump-mode commit 2f00a3435a05bbcedbf8851baeefd33463bc525b Author: Lars Ingebrigtsen Date: Sun Feb 14 16:51:14 2021 +0100 Don't update `minor-modes' in global modes * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): There's no point in setting the buffer-local `minor-modes' in global modes. diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 7e5e2a9b8a..5ba0d2187f 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -330,10 +330,11 @@ or call the function `%s'.")))) nil) (t t))) - ;; Keep `minor-modes' up to date. - (setq minor-modes (delq ',modefun minor-modes)) - (when ,getter - (push ',modefun minor-modes)) + (unless ,globalp + ;; Keep `minor-modes' up to date. + (setq minor-modes (delq ',modefun minor-modes)) + (when ,getter + (push ',modefun minor-modes))) ,@body ;; The on/off hooks are here for backward compatibility only. (run-hooks ',hook (if ,getter ',hook-on ',hook-off)) commit 1baadbe060f392253bb4a54ddbdd3870f1d08459 Author: Lars Ingebrigtsen Date: Sun Feb 14 16:18:39 2021 +0100 Mark up 5x5 for interactive mode diff --git a/lisp/play/5x5.el b/lisp/play/5x5.el index 891a5f6cba..3630c199bc 100644 --- a/lisp/play/5x5.el +++ b/lisp/play/5x5.el @@ -179,6 +179,7 @@ GRID is the grid of positions to click.") (define-derived-mode 5x5-mode special-mode "5x5" "A mode for playing `5x5'." + :interactive nil (setq buffer-read-only t truncate-lines t) (buffer-disable-undo)) @@ -221,7 +222,7 @@ Quit current game \\[5x5-quit-game]" (defun 5x5-new-game () "Start a new game of `5x5'." - (interactive) + (interactive nil 5x5-mode) (when (if (called-interactively-p 'interactive) (5x5-y-or-n-p "Start a new game? ") t) (setq 5x5-x-pos (/ 5x5-grid-size 2) @@ -234,7 +235,7 @@ Quit current game \\[5x5-quit-game]" (defun 5x5-quit-game () "Quit the current game of `5x5'." - (interactive) + (interactive nil 5x5-mode) (kill-buffer 5x5-buffer-name)) (defun 5x5-make-new-grid () @@ -782,7 +783,7 @@ Solutions are sorted from least to greatest Hamming weight." Argument N is ignored." ;; For the time being n is ignored, the idea was to use some numeric ;; argument to show a limited amount of positions. - (interactive "P") + (interactive "P" 5x5-mode) (5x5-log-init) (let ((solutions (5x5-solver 5x5-grid))) (setq 5x5-solver-output @@ -805,7 +806,7 @@ list. The list of solution is ordered by number of strokes, so rotating left just after calling `5x5-solve-suggest' will show the solution with second least number of strokes, while rotating right will show the solution with greatest number of strokes." - (interactive "P") + (interactive "P" 5x5-mode) (let ((len (length 5x5-solver-output))) (when (>= len 3) (setq n (if (integerp n) n 1) @@ -839,7 +840,7 @@ right will show the solution with greatest number of strokes." If N is not supplied, rotate by 1. Similar to function `5x5-solve-rotate-left' except that rotation is right instead of lest." - (interactive "P") + (interactive "P" 5x5-mode) (setq n (if (integerp n) (- n) -1)) @@ -851,7 +852,7 @@ lest." (defun 5x5-flip-current () "Make a move on the current cursor location." - (interactive) + (interactive nil 5x5-mode) (setq 5x5-grid (5x5-make-move 5x5-grid 5x5-y-pos 5x5-x-pos)) (5x5-made-move) (unless 5x5-cracking @@ -863,61 +864,61 @@ lest." (defun 5x5-up () "Move up." - (interactive) + (interactive nil 5x5-mode) (unless (zerop 5x5-y-pos) (cl-decf 5x5-y-pos) (5x5-position-cursor))) (defun 5x5-down () "Move down." - (interactive) + (interactive nil 5x5-mode) (unless (= 5x5-y-pos (1- 5x5-grid-size)) (cl-incf 5x5-y-pos) (5x5-position-cursor))) (defun 5x5-left () "Move left." - (interactive) + (interactive nil 5x5-mode) (unless (zerop 5x5-x-pos) (cl-decf 5x5-x-pos) (5x5-position-cursor))) (defun 5x5-right () "Move right." - (interactive) + (interactive nil 5x5-mode) (unless (= 5x5-x-pos (1- 5x5-grid-size)) (cl-incf 5x5-x-pos) (5x5-position-cursor))) (defun 5x5-bol () "Move to beginning of line." - (interactive) + (interactive nil 5x5-mode) (setq 5x5-x-pos 0) (5x5-position-cursor)) (defun 5x5-eol () "Move to end of line." - (interactive) + (interactive nil 5x5-mode) (setq 5x5-x-pos (1- 5x5-grid-size)) (5x5-position-cursor)) (defun 5x5-first () "Move to the first cell." - (interactive) + (interactive nil 5x5-mode) (setq 5x5-x-pos 0 5x5-y-pos 0) (5x5-position-cursor)) (defun 5x5-last () "Move to the last cell." - (interactive) + (interactive nil 5x5-mode) (setq 5x5-x-pos (1- 5x5-grid-size) 5x5-y-pos (1- 5x5-grid-size)) (5x5-position-cursor)) (defun 5x5-randomize () "Randomize the grid." - (interactive) + (interactive nil 5x5-mode) (when (5x5-y-or-n-p "Start a new game with a random grid? ") (setq 5x5-x-pos (/ 5x5-grid-size 2) 5x5-y-pos (/ 5x5-grid-size 2) commit 9b4a2dde788cae9bb0284027de493f6f207ad56f Author: Robert Pluim Date: Sun Feb 14 15:05:58 2021 +0100 ; * doc/lispref/modes.texi: typo fix diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 7b8ab4cb4d..b06cb58506 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -1463,7 +1463,7 @@ deactivate minor modes in any order. @defvar minor-modes This buffer-local variable lists the currently enabled minor modes in -the current buffer, and is a list if symbols. +the current buffer, and is a list of symbols. @end defvar @defvar minor-mode-list commit 4be98d5575d3c61a941907cd7aaf525409d25caa Author: Lars Ingebrigtsen Date: Sun Feb 14 14:43:24 2021 +0100 Fix problem with the newly introduces `minor-modes' variable * lisp/help-fns.el (describe-mode): Apparently buffer-local variables take precedence over lexically bound variables? diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 0e2c68292c..ceb6bc0901 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -1743,7 +1743,7 @@ documentation for the major and minor modes of that buffer." ;; don't switch buffers before calling `help-buffer'. (with-help-window (help-buffer) (with-current-buffer buffer - (let (minor-modes) + (let (minors) ;; Older packages do not register in minor-mode-list but only in ;; minor-mode-alist. (dolist (x minor-mode-alist) @@ -1766,19 +1766,19 @@ documentation for the major and minor modes of that buffer." fmode))) (push (list fmode pretty-minor-mode (format-mode-line (assq mode minor-mode-alist))) - minor-modes))))) + minors))))) ;; Narrowing is not a minor mode, but its indicator is part of ;; mode-line-modes. (when (buffer-narrowed-p) - (push '(narrow-to-region "Narrow" " Narrow") minor-modes)) - (setq minor-modes - (sort minor-modes + (push '(narrow-to-region "Narrow" " Narrow") minors)) + (setq minors + (sort minors (lambda (a b) (string-lessp (cadr a) (cadr b))))) - (when minor-modes + (when minors (princ "Enabled minor modes:\n") (make-local-variable 'help-button-cache) (with-current-buffer standard-output - (dolist (mode minor-modes) + (dolist (mode minors) (let ((mode-function (nth 0 mode)) (pretty-minor-mode (nth 1 mode)) (indicator (nth 2 mode))) commit c0221990c46a89b6ecbc8c831225785405aa82b7 Author: Lars Ingebrigtsen Date: Sun Feb 14 14:14:48 2021 +0100 Do `interactive' mode markup in all Gnus files diff --git a/lisp/gnus/deuglify.el b/lisp/gnus/deuglify.el index 08beef7db9..e6c4630a67 100644 --- a/lisp/gnus/deuglify.el +++ b/lisp/gnus/deuglify.el @@ -310,7 +310,7 @@ You can control what lines will be unwrapped by frobbing `gnus-outlook-deuglify-unwrap-min' and `gnus-outlook-deuglify-unwrap-max', indicating the minimum and maximum length of an unwrapped citation line. If NODISPLAY is non-nil, don't redisplay the article buffer." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (let ((case-fold-search nil) (inhibit-read-only t) (cite-marks gnus-outlook-deuglify-cite-marks) @@ -430,7 +430,7 @@ NODISPLAY is non-nil, don't redisplay the article buffer." (defun gnus-article-outlook-repair-attribution (&optional nodisplay) "Repair a broken attribution line. If NODISPLAY is non-nil, don't redisplay the article buffer." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (let ((attrib-start (or (gnus-outlook-repair-attribution-other) @@ -442,7 +442,7 @@ If NODISPLAY is non-nil, don't redisplay the article buffer." (defun gnus-article-outlook-rearrange-citation (&optional nodisplay) "Repair broken citations. If NODISPLAY is non-nil, don't redisplay the article buffer." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (let ((attrib-start (gnus-article-outlook-repair-attribution 'nodisplay))) ;; rearrange citations if an attribution line has been recognized (if attrib-start @@ -455,7 +455,7 @@ If NODISPLAY is non-nil, don't redisplay the article buffer." Treat \"smartquotes\", unwrap lines, repair attribution and rearrange citation. If NODISPLAY is non-nil, don't redisplay the article buffer." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) ;; apply treatment of dumb quotes (gnus-article-treat-smartquotes) ;; repair wrapped cited lines @@ -467,7 +467,7 @@ article buffer." ;;;###autoload (defun gnus-article-outlook-deuglify-article () "Deuglify broken Outlook (Express) articles and redisplay." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-outlook-deuglify-article nil)) (provide 'deuglify) diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index c9afa3ac94..435ccab740 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -1823,7 +1823,7 @@ Initialized from `text-mode-syntax-table'.") (defun article-hide-headers (&optional _arg _delete) "Hide unwanted headers and possibly sort them as well." - (interactive) + (interactive nil gnus-article-mode) ;; This function might be inhibited. (unless gnus-inhibit-hiding (let ((inhibit-read-only t) @@ -1891,7 +1891,7 @@ Initialized from `text-mode-syntax-table'.") "Toggle hiding of headers that aren't very interesting. If given a negative prefix, always show; if given a positive prefix, always hide." - (interactive (gnus-article-hidden-arg)) + (interactive (gnus-article-hidden-arg) gnus-article-mode) (when (and (not (gnus-article-check-hidden-text 'boring-headers arg)) (not gnus-show-all-headers)) (save-excursion @@ -2050,7 +2050,7 @@ always hide." (defun article-normalize-headers () "Make all header lines 40 characters long." - (interactive) + (interactive nil gnus-article-mode) (let ((inhibit-read-only t) column) (save-excursion @@ -2086,7 +2086,7 @@ iso-8859-1 character map in an attempt to provide more quoting characters. If you see something like \\222 or \\264 where you're expecting some kind of apostrophe or quotation mark, then try this wash." - (interactive) + (interactive nil gnus-article-mode) (article-translate-strings gnus-article-smartquotes-map)) (define-obsolete-function-alias 'article-treat-dumbquotes #'article-treat-smartquotes "27.1") @@ -2095,7 +2095,7 @@ try this wash." (defun article-treat-non-ascii () "Translate many Unicode characters into their ASCII equivalents." - (interactive) + (interactive nil gnus-article-mode) (require 'org-entities) (let ((table (make-char-table nil))) (dolist (elem org-entities) @@ -2138,7 +2138,7 @@ MAP is an alist where the elements are on the form (\"from\" \"to\")." (defun article-treat-overstrike () "Translate overstrikes into bold text." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (when (article-goto-body) (let ((inhibit-read-only t)) @@ -2166,7 +2166,7 @@ MAP is an alist where the elements are on the form (\"from\" \"to\")." (defun article-treat-ansi-sequences () "Translate ANSI SGR control sequences into overlays or extents." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (when (article-goto-body) (require 'ansi-color) @@ -2178,7 +2178,7 @@ MAP is an alist where the elements are on the form (\"from\" \"to\")." "Unfold folded message headers. Only the headers that fit into the current window width will be unfolded." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-with-article-headers (let (length) (while (not (eobp)) @@ -2204,7 +2204,7 @@ unfolded." (defun gnus-article-treat-fold-headers () "Fold message headers." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-with-article-headers (while (not (eobp)) (save-restriction @@ -2214,7 +2214,7 @@ unfolded." (defun gnus-treat-smiley () "Toggle display of textual emoticons (\"smileys\") as small graphical icons." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-with-article-buffer (if (memq 'smiley gnus-article-wash-types) (gnus-delete-images 'smiley) @@ -2227,7 +2227,7 @@ unfolded." (defun gnus-article-remove-images () "Remove all images from the article buffer." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-with-article-buffer (save-restriction (widen) @@ -2239,7 +2239,7 @@ unfolded." (defun gnus-article-show-images () "Show any images that are in the HTML-rendered article buffer. This only works if the article in question is HTML." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-with-article-buffer (save-restriction (widen) @@ -2255,7 +2255,7 @@ This only works if the article in question is HTML." (defun gnus-article-treat-fold-newsgroups () "Fold the Newsgroups and Followup-To message headers." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-with-article-headers (while (gnus-article-goto-header "newsgroups\\|followup-to") (save-restriction @@ -2279,7 +2279,7 @@ predicate. See Info node `(gnus)Customizing Articles'." If ARG is non-nil and not a number, toggle `gnus-article-truncate-lines' too. If ARG is a number, truncate long lines if and only if arg is positive." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (cond ((and (numberp arg) (> arg 0)) (setq gnus-article-truncate-lines t)) @@ -2298,7 +2298,7 @@ long lines if and only if arg is positive." (defun gnus-article-treat-body-boundary () "Place a boundary line at the end of the headers." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (when (and gnus-body-boundary-delimiter (> (length gnus-body-boundary-delimiter) 0)) (gnus-with-article-headers @@ -2317,7 +2317,7 @@ long lines if and only if arg is positive." "Fill lines that are wider than the window width or `fill-column'. If WIDTH (interactively, the numeric prefix), use that as the fill width." - (interactive "P") + (interactive "P" gnus-article-mode) (save-excursion (let* ((inhibit-read-only t) (window-width (window-width (get-buffer-window (current-buffer)))) @@ -2341,7 +2341,7 @@ fill width." (defun article-capitalize-sentences () "Capitalize the first word in each sentence." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (let ((inhibit-read-only t) (paragraph-start "^[\n\^L]")) @@ -2352,7 +2352,7 @@ fill width." (defun article-remove-cr () "Remove trailing CRs and then translate remaining CRs into LFs." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (let ((inhibit-read-only t)) (goto-char (point-min)) @@ -2364,7 +2364,7 @@ fill width." (defun article-remove-trailing-blank-lines () "Remove all trailing blank lines from the article." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (let ((inhibit-read-only t)) (goto-char (point-max)) @@ -2383,7 +2383,7 @@ fill width." (defun article-display-face (&optional force) "Display any Face headers in the header." - (interactive (list 'force)) + (interactive (list 'force) gnus-article-mode gnus-summary-mode) (let ((wash-face-p buffer-read-only)) (gnus-with-article-headers ;; When displaying parts, this function can be called several times on @@ -2431,7 +2431,7 @@ fill width." (defun article-display-x-face (&optional force) "Look for an X-Face header and display it if present." - (interactive (list 'force)) + (interactive (list 'force) gnus-article-mode gnus-summary-mode) (let ((wash-face-p buffer-read-only)) ;; When type `W f' (gnus-with-article-headers ;; Delete the old process, if any. @@ -2493,7 +2493,7 @@ fill width." (defun article-decode-mime-words () "Decode all MIME-encoded words in the article." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-with-article-buffer (let ((inhibit-point-motion-hooks t) (mail-parse-charset gnus-newsgroup-charset) @@ -2505,7 +2505,7 @@ fill width." (defun article-decode-charset (&optional prompt) "Decode charset-encoded text in the article. If PROMPT (the prefix), prompt for a coding system to use." - (interactive "P") + (interactive "P" gnus-article-mode) (let ((inhibit-point-motion-hooks t) (case-fold-search t) (inhibit-read-only t) (mail-parse-charset gnus-newsgroup-charset) @@ -2627,7 +2627,7 @@ Mail-Reply-To: and Mail-Followup-To:." If FORCE, decode the article whether it is marked as quoted-printable or not. If READ-CHARSET, ask for a coding system." - (interactive (list 'force current-prefix-arg)) + (interactive (list 'force current-prefix-arg) gnus-article-mode) (save-excursion (let ((inhibit-read-only t) type charset) (if (gnus-buffer-live-p gnus-original-article-buffer) @@ -2655,7 +2655,7 @@ If READ-CHARSET, ask for a coding system." "Translate a base64 article. If FORCE, decode the article whether it is marked as base64 not. If READ-CHARSET, ask for a coding system." - (interactive (list 'force current-prefix-arg)) + (interactive (list 'force current-prefix-arg) gnus-article-mode) (save-excursion (let ((inhibit-read-only t) type charset) (if (gnus-buffer-live-p gnus-original-article-buffer) @@ -2687,7 +2687,7 @@ If READ-CHARSET, ask for a coding system." (defun article-decode-HZ () "Translate a HZ-encoded article." - (interactive) + (interactive nil gnus-article-mode) (require 'rfc1843) (save-excursion (let ((inhibit-read-only t)) @@ -2695,7 +2695,7 @@ If READ-CHARSET, ask for a coding system." (defun article-unsplit-urls () "Remove the newlines that some other mailers insert into URLs." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (let ((inhibit-read-only t)) (goto-char (point-min)) @@ -2707,7 +2707,7 @@ If READ-CHARSET, ask for a coding system." (defun article-wash-html () "Format an HTML article." - (interactive) + (interactive nil gnus-article-mode) (let ((handles nil) (inhibit-read-only t)) (when (gnus-buffer-live-p gnus-original-article-buffer) @@ -3041,7 +3041,7 @@ This command creates temporary files to pass HTML contents including images if any to the browser, and deletes them when exiting the group \(if you want)." ;; Cf. `mm-w3m-safe-url-regexp' - (interactive "P") + (interactive "P" gnus-article-mode) (if arg (gnus-summary-show-article) (let ((gnus-visible-headers @@ -3078,7 +3078,7 @@ images if any to the browser, and deletes them when exiting the group (defun article-hide-list-identifiers () "Remove list identifiers from the Subject header. The `gnus-list-identifiers' variable specifies what to do." - (interactive) + (interactive nil gnus-article-mode) (let ((inhibit-point-motion-hooks t) (regexp (gnus-group-get-list-identifiers gnus-newsgroup-name)) (inhibit-read-only t)) @@ -3100,7 +3100,7 @@ The `gnus-list-identifiers' variable specifies what to do." "Toggle hiding of any PEM headers and signatures in the current article. If given a negative prefix, always show; if given a positive prefix, always hide." - (interactive (gnus-article-hidden-arg)) + (interactive (gnus-article-hidden-arg) gnus-article-mode) (unless (gnus-article-check-hidden-text 'pem arg) (save-excursion (let ((inhibit-read-only t) end) @@ -3126,7 +3126,7 @@ always hide." (defun article-strip-banner () "Strip the banners specified by the `banner' group parameter and by `gnus-article-address-banner-alist'." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (save-restriction (let ((inhibit-point-motion-hooks t)) @@ -3175,7 +3175,7 @@ always hide." (defun article-babel () "Translate article using an online translation service." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (require 'babel) (gnus-with-article-buffer (when (article-goto-body) @@ -3192,7 +3192,7 @@ always hide." "Hide the signature in the current article. If given a negative prefix, always show; if given a positive prefix, always hide." - (interactive (gnus-article-hidden-arg)) + (interactive (gnus-article-hidden-arg) gnus-article-mode) (unless (gnus-article-check-hidden-text 'signature arg) (save-excursion (save-restriction @@ -3204,7 +3204,7 @@ always hide." (defun article-strip-headers-in-body () "Strip offensive headers from bodies." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (article-goto-body) (let ((case-fold-search t)) @@ -3213,7 +3213,7 @@ always hide." (defun article-strip-leading-blank-lines () "Remove all blank lines from the beginning of the article." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (let ((inhibit-point-motion-hooks t) (inhibit-read-only t)) @@ -3255,7 +3255,7 @@ Point is left at the beginning of the narrowed-to region." (defun article-strip-multiple-blank-lines () "Replace consecutive blank lines with one empty line." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (let ((inhibit-point-motion-hooks t) (inhibit-read-only t)) @@ -3274,7 +3274,7 @@ Point is left at the beginning of the narrowed-to region." (defun article-strip-leading-space () "Remove all white space from the beginning of the lines in the article." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (let ((inhibit-point-motion-hooks t) (inhibit-read-only t)) @@ -3284,7 +3284,7 @@ Point is left at the beginning of the narrowed-to region." (defun article-strip-trailing-space () "Remove all white space from the end of the lines in the article." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (let ((inhibit-point-motion-hooks t) (inhibit-read-only t)) @@ -3294,14 +3294,14 @@ Point is left at the beginning of the narrowed-to region." (defun article-strip-blank-lines () "Strip leading, trailing and multiple blank lines." - (interactive) + (interactive nil gnus-article-mode) (article-strip-leading-blank-lines) (article-remove-trailing-blank-lines) (article-strip-multiple-blank-lines)) (defun article-strip-all-blank-lines () "Strip all blank lines." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (let ((inhibit-point-motion-hooks t) (inhibit-read-only t)) @@ -3433,7 +3433,7 @@ lines forward." "Convert DATE date to TYPE in the current article. The default type is `ut'. See `gnus-article-date-headers' for possible values." - (interactive (list 'ut t)) + (interactive (list 'ut t) gnus-article-mode) (let* ((case-fold-search t) (inhibit-read-only t) (inhibit-point-motion-hooks t) @@ -3677,29 +3677,29 @@ possible values." (defun article-date-local (&optional highlight) "Convert the current article date to the local timezone." - (interactive (list t)) + (interactive (list t) gnus-article-mode) (article-date-ut 'local highlight)) (defun article-date-english (&optional highlight) "Convert the current article date to something that is proper English." - (interactive (list t)) + (interactive (list t) gnus-article-mode) (article-date-ut 'english highlight)) (defun article-date-original (&optional highlight) "Convert the current article date to what it was originally. This is only useful if you have used some other date conversion function and want to see what the date was before converting." - (interactive (list t)) + (interactive (list t) gnus-article-mode) (article-date-ut 'original highlight)) (defun article-date-lapsed (&optional highlight) "Convert the current article date to time lapsed since it was sent." - (interactive (list t)) + (interactive (list t) gnus-article-mode) (article-date-ut 'lapsed highlight)) (defun article-date-combined-lapsed (&optional highlight) "Convert the current article date to time lapsed since it was sent." - (interactive (list t)) + (interactive (list t) gnus-article-mode) (article-date-ut 'combined-lapsed highlight)) (defun article-update-date-lapsed () @@ -3748,7 +3748,7 @@ function and want to see what the date was before converting." "Start a timer to update the Date headers in the article buffers. The numerical prefix says how frequently (in seconds) the function is to run." - (interactive "p") + (interactive "p" gnus-article-mode) (unless n (setq n 1)) (gnus-stop-date-timer) @@ -3757,7 +3757,7 @@ is to run." (defun gnus-stop-date-timer () "Stop the Date timer." - (interactive) + (interactive nil gnus-article-mode) (when article-lapsed-timer (cancel-timer article-lapsed-timer) (setq article-lapsed-timer nil))) @@ -3765,12 +3765,12 @@ is to run." (defun article-date-user (&optional highlight) "Convert the current article date to the user-defined format. This format is defined by the `gnus-article-time-format' variable." - (interactive (list t)) + (interactive (list t) gnus-article-mode) (article-date-ut 'user-defined highlight)) (defun article-date-iso8601 (&optional highlight) "Convert the current article date to ISO8601." - (interactive (list t)) + (interactive (list t) gnus-article-mode) (article-date-ut 'iso8601 highlight)) (defmacro gnus-article-save-original-date (&rest forms) @@ -3803,7 +3803,7 @@ This format is defined by the `gnus-article-time-format' variable." (defun article-remove-leading-whitespace () "Remove excessive whitespace from all headers." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (save-restriction (let ((inhibit-read-only t)) @@ -3814,7 +3814,7 @@ This format is defined by the `gnus-article-time-format' variable." (defun article-emphasize (&optional arg) "Emphasize text according to `gnus-emphasis-alist'." - (interactive (gnus-article-hidden-arg)) + (interactive (gnus-article-hidden-arg) gnus-article-mode) (unless (gnus-article-check-hidden-text 'emphasis arg) (save-excursion (let ((alist (or @@ -4247,7 +4247,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is (defun article-verify-x-pgp-sig () "Verify X-PGP-Sig." ;; - (interactive) + (interactive nil gnus-article-mode) (if (gnus-buffer-live-p gnus-original-article-buffer) (let ((sig (with-current-buffer gnus-original-article-buffer (gnus-fetch-field "X-PGP-Sig"))) @@ -4321,7 +4321,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is (defun article-verify-cancel-lock () "Verify Cancel-Lock header." - (interactive) + (interactive nil gnus-article-mode) (if (gnus-buffer-live-p gnus-original-article-buffer) (canlock-verify gnus-original-article-buffer))) @@ -4330,7 +4330,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is `(defun ,(intern (format "gnus-%s" func)) (&optional interactive &rest args) ,(format "Run `%s' in the article buffer." func) - (interactive (list t)) + (interactive (list t) gnus-article-mode gnus-summary-mode) (with-current-buffer gnus-article-buffer (if interactive (call-interactively #',func) @@ -4752,7 +4752,7 @@ If ALL-HEADERS is non-nil, no headers are hidden." (defun gnus-sticky-article (arg) "Make the current article sticky. If a prefix ARG is given, ask for a name for this sticky article buffer." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (gnus-summary-show-thread) (gnus-summary-select-article nil nil 'pseudo) (let (new-art-buf-name) @@ -4796,7 +4796,7 @@ If a prefix ARG is given, ask for a name for this sticky article buffer." "Kill the given sticky article BUFFER. If none is given, assume the current buffer and kill it if it has `gnus-sticky-article-mode'." - (interactive) + (interactive nil gnus-article-mode) (unless buffer (setq buffer (current-buffer))) (with-current-buffer buffer @@ -4806,7 +4806,7 @@ If none is given, assume the current buffer and kill it if it has (defun gnus-kill-sticky-article-buffers (arg) "Kill all sticky article buffers. If a prefix ARG is given, ask for confirmation." - (interactive "P") + (interactive "P" gnus-article-mode) (dolist (buf (gnus-buffers)) (with-current-buffer buf (and (derived-mode-p 'gnus-sticky-article-mode) @@ -4948,7 +4948,7 @@ General format specifiers can also be used. See Info node (defun gnus-mime-view-all-parts (&optional handles) "View all the MIME parts." - (interactive) + (interactive nil gnus-article-mode) (with-current-buffer gnus-article-buffer (let ((handles (or handles gnus-article-mime-handles)) (mail-parse-charset gnus-newsgroup-charset) @@ -4965,7 +4965,7 @@ General format specifiers can also be used. See Info node (defun gnus-article-jump-to-part (n) "Jump to MIME part N." - (interactive "P") + (interactive "P" gnus-article-mode) (let ((parts (with-current-buffer gnus-article-buffer (length gnus-article-mime-handle-alist)))) (when (zerop parts) @@ -5061,11 +5061,11 @@ and `gnus-mime-delete-part', and not provided at run-time normally." (defun gnus-mime-replace-part (file) "Replace MIME part under point with an external body." ;; Useful if file has already been saved to disk - (interactive - (list - (read-file-name "Replace MIME part with file: " - (or mm-default-directory default-directory) - nil t))) + (interactive (list + (read-file-name "Replace MIME part with file: " + (or mm-default-directory default-directory) + nil t)) + gnus-article-mode) (unless (file-regular-p (file-truename file)) (error "Can't replace part with %s, which isn't a regular file" file)) @@ -5074,7 +5074,7 @@ and `gnus-mime-delete-part', and not provided at run-time normally." (defun gnus-mime-save-part-and-strip (&optional file event) "Save the MIME part under point then replace it with an external body. If FILE is given, use it for the external part." - (interactive (list nil last-nonmenu-event)) + (interactive (list nil last-nonmenu-event) gnus-article-mode) (save-excursion (mouse-set-point event) (gnus-article-check-buffer) @@ -5116,7 +5116,7 @@ The current article has a complicated MIME structure, giving up...")) (defun gnus-mime-delete-part (&optional event) "Delete the MIME part under point. Replace it with some information about the removed part." - (interactive (list last-nonmenu-event)) + (interactive (list last-nonmenu-event) gnus-article-mode) (mouse-set-point event) (gnus-article-check-buffer) (when (gnus-group-read-only-p) @@ -5165,7 +5165,7 @@ Deleting parts may malfunction or destroy the article; continue? ")) (defun gnus-mime-save-part (&optional event) "Save the MIME part under point." - (interactive (list last-nonmenu-event)) + (interactive (list last-nonmenu-event) gnus-article-mode) (mouse-set-point event) (gnus-article-check-buffer) (let ((data (get-text-property (point) 'gnus-data))) @@ -5175,7 +5175,7 @@ Deleting parts may malfunction or destroy the article; continue? ")) (defun gnus-mime-pipe-part (&optional cmd event) "Pipe the MIME part under point to a process. Use CMD as the process." - (interactive (list nil last-nonmenu-event)) + (interactive (list nil last-nonmenu-event) gnus-article-mode) (mouse-set-point event) (gnus-article-check-buffer) (let ((data (get-text-property (point) 'gnus-data))) @@ -5184,7 +5184,7 @@ Use CMD as the process." (defun gnus-mime-view-part (&optional event) "Interactively choose a viewing method for the MIME part under point." - (interactive (list last-nonmenu-event)) + (interactive (list last-nonmenu-event) gnus-article-mode) (save-excursion (mouse-set-point event) (gnus-article-check-buffer) @@ -5214,7 +5214,7 @@ Use CMD as the process." "Choose a MIME media type, and view the part as such. If non-nil, PRED is a predicate to use during completion to limit the available media-types." - (interactive (list nil nil last-nonmenu-event)) + (interactive (list nil nil last-nonmenu-event) gnus-article-mode) (save-excursion (if event (mouse-set-point event)) (unless mime-type @@ -5253,7 +5253,8 @@ available media-types." "Put the MIME part under point into a new buffer. If `auto-compression-mode' is enabled, compressed files like .gz and .bz2 are decompressed." - (interactive (list nil current-prefix-arg last-nonmenu-event)) + (interactive (list nil current-prefix-arg last-nonmenu-event) + gnus-article-mode) (mouse-set-point event) (gnus-article-check-buffer) (unless handle @@ -5309,7 +5310,8 @@ are decompressed." (defun gnus-mime-print-part (&optional handle filename event) "Print the MIME part under point." (interactive - (list nil (ps-print-preprint current-prefix-arg) last-nonmenu-event)) + (list nil (ps-print-preprint current-prefix-arg) last-nonmenu-event) + gnus-article-mode) (save-excursion (mouse-set-point event) (gnus-article-check-buffer) @@ -5337,7 +5339,8 @@ are decompressed." (defun gnus-mime-inline-part (&optional handle arg event) "Insert the MIME part under point into the current buffer. Compressed files like .gz and .bz2 are decompressed." - (interactive (list nil current-prefix-arg last-nonmenu-event)) + (interactive (list nil current-prefix-arg last-nonmenu-event) + gnus-article-mode) (if event (mouse-set-point event)) (gnus-article-check-buffer) (let* ((inhibit-read-only t) @@ -5435,7 +5438,8 @@ CHARSET may either be a string or a symbol." (defun gnus-mime-view-part-as-charset (&optional handle arg event) "Insert the MIME part under point into the current buffer using the specified charset." - (interactive (list nil current-prefix-arg last-nonmenu-event)) + (interactive (list nil current-prefix-arg last-nonmenu-event) + gnus-article-mode) (save-excursion (mouse-set-point event) (gnus-article-check-buffer) @@ -5475,7 +5479,7 @@ specified charset." (defun gnus-mime-view-part-externally (&optional handle event) "View the MIME part under point with an external viewer." - (interactive (list nil last-nonmenu-event)) + (interactive (list nil last-nonmenu-event) gnus-article-mode) (save-excursion (mouse-set-point event) (gnus-article-check-buffer) @@ -5497,7 +5501,7 @@ specified charset." (defun gnus-mime-view-part-internally (&optional handle event) "View the MIME part under point with an internal viewer. If no internal viewer is available, use an external viewer." - (interactive (list nil last-nonmenu-event)) + (interactive (list nil last-nonmenu-event) gnus-article-mode) (save-excursion (mouse-set-point event) (gnus-article-check-buffer) @@ -5518,7 +5522,9 @@ If no internal viewer is available, use an external viewer." (defun gnus-mime-action-on-part (&optional action) "Do something with the MIME attachment at (point)." (interactive - (list (gnus-completing-read "Action" (mapcar #'car gnus-mime-action-alist) t))) + (list (gnus-completing-read + "Action" (mapcar #'car gnus-mime-action-alist) t)) + gnus-article-mode) (gnus-article-check-buffer) (let ((action-pair (assoc action gnus-mime-action-alist))) (if action-pair @@ -5611,62 +5617,62 @@ If INTERACTIVE, call FUNCTION interactively." (defun gnus-article-pipe-part (n) "Pipe MIME part N, which is the numerical prefix." - (interactive "P") + (interactive "P" gnus-article-mode) (gnus-article-part-wrapper n 'mm-pipe-part)) (defun gnus-article-save-part (n) "Save MIME part N, which is the numerical prefix." - (interactive "P") + (interactive "P" gnus-article-mode) (gnus-article-part-wrapper n 'mm-save-part)) (defun gnus-article-interactively-view-part (n) "View MIME part N interactively, which is the numerical prefix." - (interactive "P") + (interactive "P" gnus-article-mode) (gnus-article-part-wrapper n 'mm-interactively-view-part)) (defun gnus-article-copy-part (n) "Copy MIME part N, which is the numerical prefix." - (interactive "P") + (interactive "P" gnus-article-mode) (gnus-article-part-wrapper n 'gnus-mime-copy-part)) (defun gnus-article-view-part-as-charset (n) "View MIME part N using a specified charset. N is the numerical prefix." - (interactive "P") + (interactive "P" gnus-article-mode) (gnus-article-part-wrapper n 'gnus-mime-view-part-as-charset)) (defun gnus-article-view-part-externally (n) "View MIME part N externally, which is the numerical prefix." - (interactive "P") + (interactive "P" gnus-article-mode) (gnus-article-part-wrapper n 'gnus-mime-view-part-externally)) (defun gnus-article-inline-part (n) "Inline MIME part N, which is the numerical prefix." - (interactive "P") + (interactive "P" gnus-article-mode) (gnus-article-part-wrapper n 'gnus-mime-inline-part)) (defun gnus-article-save-part-and-strip (n) "Save MIME part N and replace it with an external body. N is the numerical prefix." - (interactive "P") + (interactive "P" gnus-article-mode) (gnus-article-part-wrapper n 'gnus-mime-save-part-and-strip t)) (defun gnus-article-replace-part (n) "Replace MIME part N with an external body. N is the numerical prefix." - (interactive "P") + (interactive "P" gnus-article-mode) (gnus-article-part-wrapper n 'gnus-mime-replace-part t t)) (defun gnus-article-delete-part (n) "Delete MIME part N and add some information about the removed part. N is the numerical prefix." - (interactive "P") + (interactive "P" gnus-article-mode) (gnus-article-part-wrapper n 'gnus-mime-delete-part t)) (defun gnus-article-view-part-as-type (n) "Choose a MIME media type, and view part N as such. N is the numerical prefix." - (interactive "P") + (interactive "P" gnus-article-mode) (gnus-article-part-wrapper n 'gnus-mime-view-part-as-type t)) (defun gnus-article-mime-match-handle-first (condition) @@ -5693,7 +5699,7 @@ N is the numerical prefix." "View MIME part N, which is the numerical prefix. If the part is already shown, hide the part. If N is nil, view all parts." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (with-current-buffer gnus-article-buffer (or (numberp n) (setq n (gnus-article-mime-match-handle-first gnus-article-mime-match-handle-function))) @@ -6383,7 +6389,7 @@ Provided for backwards compatibility." This function toggles the display when called interactively. Note that buttons to be added to the header are only the ones that aren't inlined in the body. Use `gnus-header-face-alist' to highlight buttons." - (interactive (list t)) + (interactive (list t) gnus-article-mode gnus-summary-mode) (gnus-with-article-buffer (let ((case-fold-search t) buttons st) (save-excursion @@ -6488,7 +6494,7 @@ the coding cookie." (defun gnus-narrow-to-page (&optional arg) "Narrow the article buffer to a page. If given a numerical ARG, move forward ARG pages." - (interactive "P") + (interactive "P" gnus-article-mode) (setq arg (if arg (prefix-numeric-value arg) 0)) (with-current-buffer gnus-article-buffer (widen) @@ -6541,7 +6547,7 @@ If given a numerical ARG, move forward ARG pages." (defun gnus-article-goto-next-page () "Show the next page of the article." - (interactive) + (interactive nil gnus-article-mode) (when (gnus-article-next-page) (goto-char (point-min)) (gnus-article-read-summary-keys nil ?n))) @@ -6549,7 +6555,7 @@ If given a numerical ARG, move forward ARG pages." (defun gnus-article-goto-prev-page () "Show the previous page of the article." - (interactive) + (interactive nil gnus-article-mode) (if (save-restriction (widen) (bobp)) ;; Real beginning-of-buffer? (gnus-article-read-summary-keys nil ?p) (gnus-article-prev-page nil))) @@ -6572,7 +6578,7 @@ If given a numerical ARG, move forward ARG pages." "Show the next page of the current article. If end of article, return non-nil. Otherwise return nil. Argument LINES specifies lines to be scrolled up." - (interactive "p") + (interactive "p" gnus-article-mode) (move-to-window-line (- -1 scroll-margin)) (if (and (not (and gnus-article-over-scroll (> (count-lines (window-start) (point-max)) @@ -6628,7 +6634,7 @@ specifies." (defun gnus-article-prev-page (&optional lines) "Show previous page of current article. Argument LINES specifies lines to be scrolled down." - (interactive "p") + (interactive "p" gnus-article-mode) (move-to-window-line 0) (if (and gnus-page-broken (bobp) @@ -6669,7 +6675,7 @@ not have a face in `gnus-article-boring-faces'." (defun gnus-article-refer-article () "Read article specified by message-id around point." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (re-search-backward "[ \t]\\|^" (point-at-bol) t) (re-search-forward "\\[gnus-article-goto-next-page]:Next page \\[gnus-article-goto-prev-page]:Prev page \\[gnus-article-show-summary]:Show summary \\[gnus-info-find-node]:Run Info \\[gnus-article-describe-briefly]:This help"))) (defun gnus-article-check-buffer () @@ -6703,7 +6709,7 @@ not have a face in `gnus-article-boring-faces'." (defun gnus-article-read-summary-keys (&optional _arg key not-restore-window) "Read a summary buffer key sequence and execute it from the article buffer." - (interactive "P") + (interactive "P" gnus-article-mode) (gnus-article-check-buffer) (let ((nosaves '("q" "Q" "r" "m" "a" "f" "WDD" "WDW" @@ -6814,7 +6820,7 @@ not have a face in `gnus-article-boring-faces'." (ding)))))))) (defun gnus-article-read-summary-send-keys () - (interactive) + (interactive nil gnus-article-mode) (let ((unread-command-events (list ?S))) (gnus-article-read-summary-keys))) @@ -6822,7 +6828,8 @@ not have a face in `gnus-article-boring-faces'." "Display documentation of the function invoked by KEY. KEY is a string or a vector." (interactive (list (let ((cursor-in-echo-area t)) - (read-key-sequence "Describe key: ")))) + (read-key-sequence "Describe key: "))) + gnus-article-mode) (gnus-article-check-buffer) (if (memq (key-binding key t) '(gnus-article-read-summary-keys gnus-article-read-summary-send-keys)) @@ -6844,7 +6851,8 @@ KEY is a string or a vector." KEY is a string or a vector." (interactive (list (let ((cursor-in-echo-area t)) (read-key-sequence "Describe key: ")) - current-prefix-arg)) + current-prefix-arg) + gnus-article-mode) (gnus-article-check-buffer) (if (memq (key-binding key t) '(gnus-article-read-summary-keys gnus-article-read-summary-send-keys)) @@ -6871,7 +6879,7 @@ KEY is a string or a vector." "Show a list of all defined keys, and their definitions. The optional argument PREFIX, if non-nil, should be a key sequence; then we display only bindings that start with that prefix." - (interactive) + (interactive nil gnus-article-mode) (gnus-article-check-buffer) (let ((keymap (copy-keymap gnus-article-mode-map)) (map (copy-keymap gnus-article-send-map)) @@ -6930,7 +6938,7 @@ then we display only bindings that start with that prefix." "Start composing a reply mail to the current message. The text in the region will be yanked. If the region isn't active, the entire article will be yanked." - (interactive) + (interactive nil gnus-article-mode) (let ((article (cdr gnus-article-current)) contents) (if (not (and transient-mark-mode mark-active)) @@ -6948,14 +6956,14 @@ the entire article will be yanked." "Start composing a wide reply mail to the current message. The text in the region will be yanked. If the region isn't active, the entire article will be yanked." - (interactive) + (interactive nil gnus-article-mode) (gnus-article-reply-with-original t)) (defun gnus-article-followup-with-original () "Compose a followup to the current article. The text in the region will be yanked. If the region isn't active, the entire article will be yanked." - (interactive) + (interactive nil gnus-article-mode) (let ((article (cdr gnus-article-current)) contents) (if (not (and transient-mark-mode mark-active)) @@ -6974,7 +6982,8 @@ the entire article will be yanked." This means that signatures, cited text and (some) headers will be hidden. If given a prefix, show the hidden text instead." - (interactive (append (gnus-article-hidden-arg) (list 'force))) + (interactive (append (gnus-article-hidden-arg) (list 'force)) + gnus-article-mode gnus-summary-mode) (gnus-with-article-buffer (article-hide-headers arg) (article-hide-list-identifiers) @@ -7269,7 +7278,7 @@ This is an extended text-mode. This will have permanent effect only in mail groups. If FORCE is non-nil, allow editing of articles even in read-only groups." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (when (and (not force) (gnus-group-read-only-p)) (error "The current newsgroup does not support article editing")) @@ -7302,7 +7311,7 @@ groups." (defun gnus-article-edit-done (&optional arg) "Update the article edits and exit." - (interactive "P") + (interactive "P" gnus-article-mode) (let ((func gnus-article-edit-done-function) (buf (current-buffer)) (start (window-start)) @@ -7336,7 +7345,7 @@ groups." (defun gnus-article-edit-exit () "Exit the article editing without updating." - (interactive) + (interactive nil gnus-article-mode) (when (or (not (buffer-modified-p)) (yes-or-no-p "Article modified; kill anyway? ")) (let ((curbuf (current-buffer)) @@ -7357,7 +7366,7 @@ groups." (defun gnus-article-edit-full-stops () "Interactively repair spacing at end of sentences." - (interactive) + (interactive nil gnus-article-mode) (save-excursion (goto-char (point-min)) (search-forward-regexp "^$" nil t) @@ -7875,7 +7884,7 @@ HEADER is a regexp to match a header. For a fuller explanation, see "Check text under the mouse pointer for a callback function. If the text under the mouse pointer has a `gnus-callback' property, call it with the value of the `gnus-data' text property." - (interactive "e") + (interactive "e" gnus-article-mode) (set-buffer (window-buffer (posn-window (event-start event)))) (let* ((pos (posn-point (event-start event))) (data (get-text-property pos 'gnus-data)) @@ -7888,7 +7897,7 @@ call it with the value of the `gnus-data' text property." "Check text at point for a callback function. If the text at point has a `gnus-callback' property, call it with the value of the `gnus-data' text property." - (interactive (list last-nonmenu-event)) + (interactive (list last-nonmenu-event) gnus-article-mode) (save-excursion (when event (mouse-set-point event)) @@ -7902,7 +7911,7 @@ This function calls `gnus-article-highlight-headers', `gnus-article-highlight-citation', `gnus-article-highlight-signature', and `gnus-article-add-buttons' to do the highlighting. See the documentation for those functions." - (interactive (list 'force)) + (interactive (list 'force) gnus-article-mode) (gnus-article-highlight-headers) (gnus-article-highlight-citation force) (gnus-article-highlight-signature) @@ -7914,14 +7923,14 @@ do the highlighting. See the documentation for those functions." This function calls `gnus-article-highlight-headers', `gnus-article-highlight-signature', and `gnus-article-add-buttons' to do the highlighting. See the documentation for those functions." - (interactive (list 'force)) + (interactive (list 'force) gnus-article-mode) (gnus-article-highlight-headers) (gnus-article-highlight-signature) (gnus-article-add-buttons)) (defun gnus-article-highlight-headers () "Highlight article headers as specified by `gnus-header-face-alist'." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-with-article-headers (let (regexp header-face field-face from hpoints fpoints) (dolist (entry gnus-header-face-alist) @@ -7955,7 +7964,7 @@ do the highlighting. See the documentation for those functions." "Highlight the signature in an article. It does this by highlighting everything after `gnus-signature-separator' using the face `gnus-signature'." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-with-article-buffer (let ((inhibit-point-motion-hooks t)) (save-restriction @@ -7978,7 +7987,7 @@ It does this by highlighting everything after "Find external references in the article and make buttons of them. \"External references\" are things like Message-IDs and URLs, as specified by `gnus-button-alist'." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-with-article-buffer (let ((inhibit-point-motion-hooks t) (case-fold-search t) @@ -8072,7 +8081,7 @@ url is put as the `gnus-button-url' overlay property on the button." ;; Add buttons to the head of an article. (defun gnus-article-add-buttons-to-head () "Add buttons to the head of the article." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-with-article-headers (let (beg end) (dolist (entry gnus-header-button-alist) @@ -8120,7 +8129,7 @@ url is put as the `gnus-button-url' overlay property on the button." (defun gnus-article-copy-string () "Copy the string in the button to the kill ring." - (interactive) + (interactive nil gnus-article-mode) (gnus-article-check-buffer) (let ((data (get-text-property (point) 'gnus-string))) (when data @@ -8236,7 +8245,7 @@ url is put as the `gnus-button-url' overlay property on the button." (defun gnus-button-patch (library line) "Visit an Emacs Lisp library LIBRARY on line LINE." - (interactive) + (interactive nil gnus-article-mode) (let ((file (locate-library (file-name-nondirectory library)))) (unless file (error "Couldn't find library %s" library)) @@ -8428,7 +8437,7 @@ url is put as the `gnus-button-url' overlay property on the button." (defun gnus-button-next-page (&optional _args _more-args) "Go to the next page." - (interactive) + (interactive nil gnus-article-mode) (let ((win (selected-window))) (select-window (gnus-get-buffer-window gnus-article-buffer t)) (gnus-article-next-page) @@ -8436,7 +8445,7 @@ url is put as the `gnus-button-url' overlay property on the button." (defun gnus-button-prev-page (&optional _args _more-args) "Go to the prev page." - (interactive) + (interactive nil gnus-article-mode) (let ((win (selected-window))) (select-window (gnus-get-buffer-window gnus-article-buffer t)) (gnus-article-prev-page) @@ -8460,7 +8469,7 @@ url is put as the `gnus-button-url' overlay property on the button." (defun gnus-article-button-next-page (_arg) "Go to the next page." - (interactive "P") + (interactive "P" gnus-article-mode) (let ((win (selected-window))) (select-window (gnus-get-buffer-window gnus-article-buffer t)) (gnus-article-next-page) @@ -8468,7 +8477,7 @@ url is put as the `gnus-button-url' overlay property on the button." (defun gnus-article-button-prev-page (_arg) "Go to the prev page." - (interactive "P") + (interactive "P" gnus-article-mode) (let ((win (selected-window))) (select-window (gnus-get-buffer-window gnus-article-buffer t)) (gnus-article-prev-page) @@ -8602,9 +8611,10 @@ For example: (list (or gnus-article-encrypt-protocol (gnus-completing-read "Encrypt protocol" - (mapcar #'car gnus-article-encrypt-protocol-alist) - t)) - current-prefix-arg)) + (mapcar #'car gnus-article-encrypt-protocol-alist) + t)) + current-prefix-arg) + gnus-article-mode) ;; User might hit `K E' instead of `K e', so prompt once. (when (and gnus-article-encrypt-protocol gnus-novice-user) @@ -8728,7 +8738,7 @@ For example: (defun gnus-mime-security-button-menu (event prefix) "Construct a context-sensitive menu of security commands." - (interactive "e\nP") + (interactive "e\nP" gnus-article-mode) (save-window-excursion (let ((pos (event-start event))) (select-window (posn-window pos)) @@ -8885,12 +8895,12 @@ For example: (defun gnus-mime-security-save-part () "Save the security part under point." - (interactive) + (interactive nil gnus-article-mode) (gnus-mime-security-run-function 'mm-save-part)) (defun gnus-mime-security-pipe-part () "Pipe the security part under point to a process." - (interactive) + (interactive nil gnus-article-mode) (gnus-mime-security-run-function 'mm-pipe-part)) (provide 'gnus-art) diff --git a/lisp/gnus/gnus-bookmark.el b/lisp/gnus/gnus-bookmark.el index bc41d5b149..8c2a928ab9 100644 --- a/lisp/gnus/gnus-bookmark.el +++ b/lisp/gnus/gnus-bookmark.el @@ -168,7 +168,7 @@ So the cdr of each bookmark is an alist too.") ;;;###autoload (defun gnus-bookmark-set () "Set a bookmark for this article." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-bookmark-maybe-load-default-file) (if (or (not (derived-mode-p 'gnus-summary-mode)) (not gnus-article-current)) @@ -483,7 +483,7 @@ Gnus bookmarks names preceded by a \"*\" have annotations. (defun gnus-bookmark-bmenu-toggle-infos (&optional show) "Toggle whether details are shown in the Gnus bookmark list. Optional argument SHOW means show them unconditionally." - (interactive) + (interactive nil gnus-bookmark-bmenu-mode) (cond (show (setq gnus-bookmark-bmenu-toggle-infos nil) @@ -649,14 +649,14 @@ reposition and try again, else return nil." (defun gnus-bookmark-bmenu-show-details () "Show the annotation for the current bookmark in another window." - (interactive) + (interactive nil gnus-bookmark-bmenu-mode) (let ((bookmark (gnus-bookmark-bmenu-bookmark))) (if (gnus-bookmark-bmenu-check-position) (gnus-bookmark-show-details bookmark)))) (defun gnus-bookmark-bmenu-mark () "Mark bookmark on this line to be displayed by \\\\[gnus-bookmark-bmenu-select]." - (interactive) + (interactive nil gnus-bookmark-bmenu-mode) (beginning-of-line) (if (gnus-bookmark-bmenu-check-position) (let ((inhibit-read-only t)) @@ -668,7 +668,7 @@ reposition and try again, else return nil." (defun gnus-bookmark-bmenu-unmark (&optional backup) "Cancel all requested operations on bookmark on this line and move down. Optional BACKUP means move up." - (interactive "P") + (interactive "P" gnus-bookmark-bmenu-mode) (beginning-of-line) (if (gnus-bookmark-bmenu-check-position) (progn @@ -683,7 +683,7 @@ Optional BACKUP means move up." (defun gnus-bookmark-bmenu-backup-unmark () "Move up and cancel all requested operations on bookmark on line above." - (interactive) + (interactive nil gnus-bookmark-bmenu-mode) (forward-line -1) (if (gnus-bookmark-bmenu-check-position) (progn @@ -695,7 +695,7 @@ Optional BACKUP means move up." "Mark Gnus bookmark on this line to be deleted. To carry out the deletions that you've marked, use \\\\[gnus-bookmark-bmenu-execute-deletions]." - (interactive) + (interactive nil gnus-bookmark-bmenu-mode) (beginning-of-line) (if (gnus-bookmark-bmenu-check-position) (let ((inhibit-read-only t)) @@ -708,7 +708,7 @@ To carry out the deletions that you've marked, use "Mark bookmark on this line to be deleted, then move up one line. To carry out the deletions that you've marked, use \\\\[gnus-bookmark-bmenu-execute-deletions]." - (interactive) + (interactive nil gnus-bookmark-bmenu-mode) (gnus-bookmark-bmenu-delete) (forward-line -2) (if (gnus-bookmark-bmenu-check-position) @@ -720,7 +720,7 @@ To carry out the deletions that you've marked, use You can mark bookmarks with the \\\\[gnus-bookmark-bmenu-mark] command." - (interactive) + (interactive nil gnus-bookmark-bmenu-mode) (if (gnus-bookmark-bmenu-check-position) (let ((bmrk (gnus-bookmark-bmenu-bookmark)) (menu (current-buffer))) @@ -730,13 +730,13 @@ command." (bury-buffer menu)))) (defun gnus-bookmark-bmenu-select-by-mouse (event) - (interactive "e") + (interactive "e" gnus-bookmark-bmenu-mode) (mouse-set-point event) (gnus-bookmark-bmenu-select)) (defun gnus-bookmark-bmenu-load () "Load the Gnus bookmark file and rebuild the bookmark menu-buffer." - (interactive) + (interactive nil gnus-bookmark-bmenu-mode) (if (gnus-bookmark-bmenu-check-position) (save-excursion (save-window-excursion @@ -745,7 +745,7 @@ command." (defun gnus-bookmark-bmenu-execute-deletions () "Delete Gnus bookmarks marked with \\\\[Buffer-menu-delete] commands." - (interactive) + (interactive nil gnus-bookmark-bmenu-mode) (message "Deleting Gnus bookmarks...") (let ((hide-em gnus-bookmark-bmenu-toggle-infos) (o-point (point)) diff --git a/lisp/gnus/gnus-cache.el b/lisp/gnus/gnus-cache.el index 5ed731947b..34dba54c11 100644 --- a/lisp/gnus/gnus-cache.el +++ b/lisp/gnus/gnus-cache.el @@ -342,7 +342,7 @@ it's not cached." "Enter the next N articles into the cache. If not given a prefix, use the process marked articles instead. Returns the list of articles entered." - (interactive "P") + (interactive "P" gnus-summary-mode) (let (out) (dolist (article (gnus-summary-work-articles n)) (gnus-summary-remove-process-mark article) @@ -363,7 +363,7 @@ Returns the list of articles entered." "Remove the next N articles from the cache. If not given a prefix, use the process marked articles instead. Returns the list of articles removed." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-cache-change-buffer gnus-newsgroup-name) (let (out) (dolist (article (gnus-summary-work-articles n)) @@ -388,7 +388,7 @@ Returns the list of articles removed." (defun gnus-summary-insert-cached-articles () "Insert all the articles cached for this group into the current buffer." - (interactive) + (interactive nil gnus-summary-mode) (let ((gnus-verbose (max 6 gnus-verbose))) (cond ((not gnus-newsgroup-cached) @@ -401,7 +401,7 @@ Returns the list of articles removed." (defun gnus-summary-limit-include-cached () "Limit the summary buffer to articles that are cached." - (interactive) + (interactive nil gnus-summary-mode) (let ((gnus-verbose (max 6 gnus-verbose))) (if gnus-newsgroup-cached (progn diff --git a/lisp/gnus/gnus-cite.el b/lisp/gnus/gnus-cite.el index 96f1a7de5e..1f564f192b 100644 --- a/lisp/gnus/gnus-cite.el +++ b/lisp/gnus/gnus-cite.el @@ -335,7 +335,7 @@ lines matches `message-cite-prefix-regexp' with the same prefix. Lines matching `gnus-cite-attribution-suffix' and perhaps `gnus-cite-attribution-prefix' are considered attribution lines." - (interactive (list 'force)) + (interactive (list 'force) gnus-article-mode gnus-summary-mode) (with-current-buffer (if same-buffer (current-buffer) gnus-article-buffer) (gnus-cite-parse-maybe force) (let ((buffer-read-only nil) @@ -459,7 +459,7 @@ frame width. Sections that are heuristically interpreted as not being text (i.e., computer code and the like) will not be folded." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (with-current-buffer gnus-article-buffer (let ((buffer-read-only nil) (inhibit-point-motion-hooks t) @@ -529,7 +529,8 @@ text (i.e., computer code and the like) will not be folded." See the documentation for `gnus-article-highlight-citation'. If given a negative prefix, always show; if given a positive prefix, always hide." - (interactive (append (gnus-article-hidden-arg) (list 'force))) + (interactive (append (gnus-article-hidden-arg) (list 'force)) + gnus-article-mode gnus-summary-mode) (gnus-set-format 'cited-opened-text-button t) (gnus-set-format 'cited-closed-text-button t) (with-current-buffer gnus-article-buffer @@ -661,7 +662,8 @@ percent and at least `gnus-cite-hide-absolute' lines of the body is cited text with attributions. When called interactively, these two variables are ignored. See also the documentation for `gnus-article-highlight-citation'." - (interactive (append (gnus-article-hidden-arg) '(force))) + (interactive (append (gnus-article-hidden-arg) '(force)) + gnus-article-mode gnus-summary-mode) (with-current-buffer gnus-article-buffer (gnus-delete-wash-type 'cite) (unless (gnus-article-check-hidden-text 'cite arg) @@ -689,7 +691,7 @@ See also the documentation for `gnus-article-highlight-citation'." (defun gnus-article-hide-citation-in-followups () "Hide cited text in non-root articles." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (with-current-buffer gnus-article-buffer (let ((article (cdr gnus-article-current))) (unless (with-current-buffer gnus-summary-buffer diff --git a/lisp/gnus/gnus-cus.el b/lisp/gnus/gnus-cus.el index d8f48b19f8..0852f8e126 100644 --- a/lisp/gnus/gnus-cus.el +++ b/lisp/gnus/gnus-cus.el @@ -337,7 +337,8 @@ category.")) (defun gnus-group-customize (group &optional topic) "Edit the group or topic on the current line." - (interactive (list (gnus-group-group-name) (gnus-group-topic-name))) + (interactive (list (gnus-group-group-name) (gnus-group-topic-name)) + gnus-group-mode) (let (info (types (mapcar (lambda (entry) `(cons :format "%v%h\n" @@ -485,7 +486,7 @@ form, but who cares?" (defun gnus-group-customize-done (&rest _ignore) "Apply changes and bury the buffer." - (interactive) + (interactive nil gnus-custom-mode) (let ((params (widget-value gnus-custom-params))) (if gnus-custom-topic (gnus-topic-set-parameters gnus-custom-topic params) @@ -829,7 +830,7 @@ eh?"))) "Customize score file FILE. When called interactively, FILE defaults to the current score file. This can be changed using the `\\[gnus-score-change-score-file]' command." - (interactive (list gnus-current-score-file)) + (interactive (list gnus-current-score-file) gnus-summary-mode) (unless file (error "No score file for %s" gnus-newsgroup-name)) (let ((scores (gnus-score-load file)) @@ -1000,7 +1001,7 @@ articles in the thread. (defun gnus-agent-customize-category (category) "Edit the CATEGORY." - (interactive (list (gnus-category-name))) + (interactive (list (gnus-category-name)) gnus-custom-mode) (let ((info (assq category gnus-category-alist)) (defaults (list nil '(agent-predicate . false) (cons 'agent-enable-expiration diff --git a/lisp/gnus/gnus-delay.el b/lisp/gnus/gnus-delay.el index 0cee01b942..944fd9795a 100644 --- a/lisp/gnus/gnus-delay.el +++ b/lisp/gnus/gnus-delay.el @@ -76,10 +76,10 @@ DELAY is a string, giving the length of the time. Possible values are: The value of `message-draft-headers' determines which headers are generated when the article is delayed. Remaining headers are generated when the article is sent." - (interactive - (list (read-string - "Target date (YYYY-MM-DD), time (hh:mm), or length of delay (units in [mhdwMY]): " - gnus-delay-default-delay))) + (interactive (list (read-string + "Target date (YYYY-MM-DD), time (hh:mm), or length of delay (units in [mhdwMY]): " + gnus-delay-default-delay)) + message-mode) ;; Allow spell checking etc. (run-hooks 'message-send-hook) (let (num unit year month day hour minute deadline) ;; days diff --git a/lisp/gnus/gnus-diary.el b/lisp/gnus/gnus-diary.el index 52705640bf..64eb639f61 100644 --- a/lisp/gnus/gnus-diary.el +++ b/lisp/gnus/gnus-diary.el @@ -214,7 +214,7 @@ There are currently two built-in format functions: (defun gnus-summary-sort-by-schedule (&optional reverse) "Sort nndiary summary buffers by schedule of appointments. Optional prefix (or REVERSE argument) means sort in reverse order." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-sort 'schedule reverse)) (defvar gnus-summary-misc-menu) ;; Avoid byte compiler warning. @@ -322,7 +322,7 @@ This function checks that all NNDiary required headers are present and valid, and prompts for values / correction otherwise. If ARG (or prefix) is non-nil, force prompting for all fields." - (interactive "P") + (interactive "P" gnus-summary-mode) (save-excursion (mapcar (lambda (head) diff --git a/lisp/gnus/gnus-dired.el b/lisp/gnus/gnus-dired.el index ca2d57de7d..af0b782202 100644 --- a/lisp/gnus/gnus-dired.el +++ b/lisp/gnus/gnus-dired.el @@ -124,7 +124,8 @@ filenames." (mapcar ;; don't attach directories (lambda (f) (if (file-directory-p f) nil f)) - (nreverse (dired-map-over-marks (dired-get-filename) nil)))))) + (nreverse (dired-map-over-marks (dired-get-filename) nil))))) + dired-mode) (let ((destination nil) (files-str nil) (bufs nil)) @@ -178,7 +179,8 @@ filenames." If ARG is non-nil, open it in a new buffer." (interactive (list (file-name-sans-versions (dired-get-filename) t) - current-prefix-arg)) + current-prefix-arg) + dired-mode) (mailcap-parse-mailcaps) (if (file-exists-p file-name) (let (mime-type method) @@ -216,7 +218,8 @@ that name. If PRINT-TO is a number, prompt the user for the name of the file to save in." (interactive (list (file-name-sans-versions (dired-get-filename) t) - (ps-print-preprint current-prefix-arg))) + (ps-print-preprint current-prefix-arg)) + dired-mode) (mailcap-parse-mailcaps) (cond ((file-directory-p file-name) diff --git a/lisp/gnus/gnus-draft.el b/lisp/gnus/gnus-draft.el index f68e9d6b74..9a0f21359f 100644 --- a/lisp/gnus/gnus-draft.el +++ b/lisp/gnus/gnus-draft.el @@ -71,7 +71,7 @@ (defun gnus-draft-toggle-sending (article) "Toggle whether to send an article or not." - (interactive (list (gnus-summary-article-number))) + (interactive (list (gnus-summary-article-number)) gnus-summary-mode) (if (gnus-draft-article-sendable-p article) (progn (push article gnus-newsgroup-unsendable) @@ -83,7 +83,7 @@ (defun gnus-draft-edit-message () "Enter a mail/post buffer to edit and send the draft." - (interactive) + (interactive nil gnus-summary-mode) (let ((article (gnus-summary-article-number)) (group gnus-newsgroup-name)) (gnus-draft-check-draft-articles (list article)) @@ -109,7 +109,7 @@ (defun gnus-draft-send-message (&optional n) "Send the current draft(s). Obeys the standard process/prefix convention." - (interactive "P") + (interactive "P" gnus-summary-mode) (let* ((articles (gnus-summary-work-articles n)) (total (length articles)) article) diff --git a/lisp/gnus/gnus-eform.el b/lisp/gnus/gnus-eform.el index 265edf4d61..3fd8bf51de 100644 --- a/lisp/gnus/gnus-eform.el +++ b/lisp/gnus/gnus-eform.el @@ -104,7 +104,7 @@ The optional LAYOUT overrides the `edit-form' window layout." (defun gnus-edit-form-done () "Update changes and kill the current buffer." - (interactive) + (interactive nil gnus-edit-form-mode) (goto-char (point-min)) (let ((form (condition-case nil (read (current-buffer)) @@ -115,7 +115,7 @@ The optional LAYOUT overrides the `edit-form' window layout." (defun gnus-edit-form-exit () "Kill the current buffer." - (interactive) + (interactive nil gnus-edit-form-mode) (let ((winconf gnus-prev-winconf)) (kill-buffer (current-buffer)) (set-window-configuration winconf))) diff --git a/lisp/gnus/gnus-fun.el b/lisp/gnus/gnus-fun.el index f69c2ed12c..c2e72aba93 100644 --- a/lisp/gnus/gnus-fun.el +++ b/lisp/gnus/gnus-fun.el @@ -132,11 +132,12 @@ For instance, to insert an X-Face use `gnus-random-x-face' as FUN Files matching `gnus-x-face-omit-files' are not considered." (interactive) - (gnus--random-face-with-type gnus-x-face-directory "\\.pbm$" gnus-x-face-omit-files - (lambda (file) - (gnus-shell-command-to-string - (format gnus-convert-pbm-to-x-face-command - (shell-quote-argument file)))))) + (gnus--random-face-with-type + gnus-x-face-directory "\\.pbm$" gnus-x-face-omit-files + (lambda (file) + (gnus-shell-command-to-string + (format gnus-convert-pbm-to-x-face-command + (shell-quote-argument file)))))) ;;;###autoload (defun gnus-insert-random-x-face-header () @@ -231,8 +232,8 @@ FILE should be a PNG file that's 48x48 and smaller than or equal to Files matching `gnus-face-omit-files' are not considered." (interactive) (gnus--random-face-with-type gnus-face-directory "\\.png$" - gnus-face-omit-files - 'gnus-convert-png-to-face)) + gnus-face-omit-files + 'gnus-convert-png-to-face)) ;;;###autoload (defun gnus-insert-random-face-header () @@ -277,7 +278,6 @@ colors of the displayed X-Faces." (defun gnus-grab-cam-x-face () "Grab a picture off the camera and make it into an X-Face." - (interactive) (shell-command "xawtv-remote snap ppm") (let ((file nil)) (while (null (setq file (directory-files "/tftpboot/sparky/tmp" @@ -289,13 +289,11 @@ colors of the displayed X-Faces." (format "pnmcut -left 110 -top 30 -width 144 -height 144 '%s' | ppmnorm 2>%s | pnmscale -width 48 | ppmtopgm | pgmtopbm -threshold -value 0.92 | pbmtoxbm | compface" file null-device) (current-buffer)) - ;;(sleep-for 3) (delete-file file) (buffer-string)))) (defun gnus-grab-cam-face () "Grab a picture off the camera and make it into an X-Face." - (interactive) (shell-command "xawtv-remote snap ppm") (let ((file nil) (tempfile (make-temp-file "gnus-face-" nil ".ppm")) @@ -312,7 +310,6 @@ colors of the displayed X-Faces." (gnus-fun-ppm-change-string)))) (setq result (gnus-face-from-file tempfile))) (delete-file file) - ;;(delete-file tempfile) ; FIXME why are we not deleting it?! result)) (defun gnus-fun-ppm-change-string () diff --git a/lisp/gnus/gnus-gravatar.el b/lisp/gnus/gnus-gravatar.el index 9ea9e10031..be57774fe9 100644 --- a/lisp/gnus/gnus-gravatar.el +++ b/lisp/gnus/gnus-gravatar.el @@ -125,7 +125,7 @@ callback for `gravatar-retrieve'." (defun gnus-treat-from-gravatar (&optional force) "Display gravatar in the From header. If gravatar is already displayed, remove it." - (interactive "p") + (interactive "p" gnus-article-mode gnus-summary-mode) (gnus-with-article-buffer (if (memq 'from-gravatar gnus-article-wash-types) (gnus-delete-images 'from-gravatar) @@ -135,7 +135,7 @@ If gravatar is already displayed, remove it." (defun gnus-treat-mail-gravatar (&optional force) "Display gravatars in the Cc and To headers. If gravatars are already displayed, remove them." - (interactive "p") + (interactive "p" gnus-article-mode gnus-summary-mode) (gnus-with-article-buffer (if (memq 'mail-gravatar gnus-article-wash-types) (gnus-delete-images 'mail-gravatar) diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index e8b62a4133..909391b6b0 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el @@ -1160,7 +1160,7 @@ The following commands are available: (defun gnus-mouse-pick-group (e) "Enter the group under the mouse pointer." - (interactive "e") + (interactive "e" gnus-group-mode) (mouse-set-point e) (gnus-group-read-group nil)) @@ -1241,7 +1241,8 @@ Also see the `gnus-group-use-permanent-levels' variable." (or (gnus-group-default-level nil t) (gnus-group-default-list-level) - gnus-level-subscribed)))) + gnus-level-subscribed))) + gnus-group-mode) (unless level (setq level (car gnus-group-list-mode) unread (cdr gnus-group-list-mode))) @@ -1292,7 +1293,7 @@ Also see the `gnus-group-use-permanent-levels' variable." (defun gnus-group-list-level (level &optional all) "List groups on LEVEL. If ALL (the prefix), also list groups that have no unread articles." - (interactive "nList groups on level: \nP") + (interactive "nList groups on level: \nP" gnus-group-mode) (gnus-group-list-groups level all level)) (defun gnus-group-prepare-logic (group test) @@ -1866,7 +1867,7 @@ If FIRST-TOO, the current line is also eligible as a target." (defun gnus-group-mark-group (n &optional unmark no-advance) "Mark the current group." - (interactive "p") + (interactive "p" gnus-group-mode) (let ((buffer-read-only nil) group) (while (and (> n 0) @@ -1891,13 +1892,13 @@ If FIRST-TOO, the current line is also eligible as a target." (defun gnus-group-unmark-group (n) "Remove the mark from the current group." - (interactive "p") + (interactive "p" gnus-group-mode) (gnus-group-mark-group n 'unmark) (gnus-group-position-point)) (defun gnus-group-unmark-all-groups () "Unmark all groups." - (interactive) + (interactive nil gnus-group-mode) (save-excursion (mapc #'gnus-group-remove-mark gnus-group-marked)) (gnus-group-position-point)) @@ -1905,7 +1906,7 @@ If FIRST-TOO, the current line is also eligible as a target." (defun gnus-group-mark-region (unmark beg end) "Mark all groups between point and mark. If UNMARK, remove the mark instead." - (interactive "P\nr") + (interactive "P\nr" gnus-group-mode) (let ((num (count-lines beg end))) (save-excursion (goto-char beg) @@ -1914,12 +1915,12 @@ If UNMARK, remove the mark instead." (defun gnus-group-mark-buffer (&optional unmark) "Mark all groups in the buffer. If UNMARK, remove the mark instead." - (interactive "P") + (interactive "P" gnus-group-mode) (gnus-group-mark-region unmark (point-min) (point-max))) (defun gnus-group-mark-regexp (regexp) "Mark all groups that match some regexp." - (interactive "sMark (regexp): ") + (interactive "sMark (regexp): " gnus-group-mode) (let ((alist (cdr gnus-newsrc-alist)) group) (save-excursion @@ -2028,7 +2029,7 @@ number of the earliest articles in the group. If the optional argument NO-ARTICLE is non-nil, no article will be auto-selected upon group entry. If GROUP is non-nil, fetch that group." - (interactive "P") + (interactive "P" gnus-group-mode) (let ((no-display (eq all 0)) (group (or group (gnus-group-group-name))) number active marked entry) @@ -2062,7 +2063,7 @@ If ALL is a positive number, fetch this number of the latest articles in the group. If ALL is a negative number, fetch this number of the earliest articles in the group." - (interactive "P") + (interactive "P" gnus-group-mode) (when (and (eobp) (not (gnus-group-group-name))) (forward-line -1)) (gnus-group-read-group all t)) @@ -2081,7 +2082,7 @@ buffer. If GROUP is nil, use current group. This might be useful if you want to toggle threading before entering the group." - (interactive "P") + (interactive "P" gnus-group-mode) (require 'gnus-score) (let (gnus-visual gnus-score-find-score-files-function @@ -2092,7 +2093,7 @@ before entering the group." (defun gnus-group-visible-select-group (&optional all) "Select the current group without hiding any articles." - (interactive "P") + (interactive "P" gnus-group-mode) (let ((gnus-inhibit-limiting t)) (gnus-group-read-group all t))) @@ -2101,7 +2102,7 @@ before entering the group." You will actually be entered into a group that's a copy of the current group; no changes you make while in this group will be permanent." - (interactive) + (interactive nil gnus-group-mode) (require 'gnus-score) (let* (gnus-visual gnus-score-find-score-files-function gnus-apply-kill-hook @@ -2333,7 +2334,8 @@ specified by `gnus-gmane-group-download-format'." (list (gnus-group-completing-read "Gmane group") (read-number "Start article number: ") - (read-number "How many articles: "))) + (read-number "How many articles: ")) + gnus-group-mode) (unless range (setq range 500)) (when (< range 1) (error "Invalid range: %s" range)) @@ -2367,8 +2369,7 @@ Valid input formats include: ;; - The URLs should be added to `gnus-button-alist'. Probably we should ;; prompt the user to decide: "View via `browse-url' or in Gnus? " ;; (`gnus-read-ephemeral-gmane-group-url') - (interactive - (list (gnus-group-completing-read "Gmane URL"))) + (interactive (list (gnus-group-completing-read "Gmane URL")) gnus-group-mode) (let (group start range) (cond ;; URLs providing `group', `start' and `range': @@ -2543,7 +2544,8 @@ If PROMPT (the prefix) is a number, use the prompt specified in (or (and (stringp gnus-group-jump-to-group-prompt) gnus-group-jump-to-group-prompt) (let ((p (cdr (assq 0 gnus-group-jump-to-group-prompt)))) - (and (stringp p) p))))))) + (and (stringp p) p)))))) + gnus-group-mode) (when (equal group "") (error "Empty group name")) @@ -2612,7 +2614,7 @@ Return nil if GROUP is not found." If N is negative, search backward instead. Returns the difference between N and the number of skips actually done." - (interactive "p") + (interactive "p" gnus-group-mode) (gnus-group-next-unread-group n t nil silent)) (defun gnus-group-next-unread-group (n &optional all level silent) @@ -2624,7 +2626,7 @@ such group can be found, the next group with a level higher than LEVEL. Returns the difference between N and the number of skips actually made." - (interactive "p") + (interactive "p" gnus-group-mode) (let ((backward (< n 0)) (n (abs n))) (while (and (> n 0) @@ -2641,14 +2643,14 @@ made." "Go to previous N'th newsgroup. Returns the difference between N and the number of skips actually done." - (interactive "p") + (interactive "p" gnus-group-mode) (gnus-group-next-unread-group (- n) t)) (defun gnus-group-prev-unread-group (n) "Go to previous N'th unread newsgroup. Returns the difference between N and the number of skips actually done." - (interactive "p") + (interactive "p" gnus-group-mode) (gnus-group-next-unread-group (- n))) (defun gnus-group-next-unread-group-same-level (n) @@ -2656,7 +2658,7 @@ done." If N is negative, search backward instead. Returns the difference between N and the number of skips actually done." - (interactive "p") + (interactive "p" gnus-group-mode) (gnus-group-next-unread-group n t (gnus-group-group-level)) (gnus-group-position-point)) @@ -2664,14 +2666,14 @@ done." "Go to next N'th unread newsgroup on the same level. Returns the difference between N and the number of skips actually done." - (interactive "p") + (interactive "p" gnus-group-mode) (gnus-group-next-unread-group (- n) t (gnus-group-group-level)) (gnus-group-position-point)) (defun gnus-group-best-unread-group (&optional exclude-group) "Go to the group with the highest level. If EXCLUDE-GROUP, do not go to that group." - (interactive) + (interactive nil gnus-group-mode) (goto-char (point-min)) (let ((best 100000) unread best-point) @@ -2711,7 +2713,7 @@ If EXCLUDE-GROUP, do not go to that group." (defun gnus-group-first-unread-group () "Go to the first group with unread articles." - (interactive) + (interactive nil gnus-group-mode) (prog1 (let ((opoint (point)) unread) @@ -2727,13 +2729,13 @@ If EXCLUDE-GROUP, do not go to that group." (defun gnus-group-enter-server-mode () "Jump to the server buffer." - (interactive) + (interactive nil gnus-group-mode) (gnus-enter-server-buffer)) (defun gnus-group-make-group-simple (&optional group) "Add a new newsgroup. The user will be prompted for GROUP." - (interactive (list (gnus-group-completing-read))) + (interactive (list (gnus-group-completing-read)) gnus-group-mode) (gnus-group-make-group (gnus-group-real-name group) (gnus-group-server group) nil nil)) @@ -2749,7 +2751,8 @@ server." (interactive (list (gnus-read-group "Group name: ") - (gnus-read-method "Select method for new group (use tab for completion)"))) + (gnus-read-method "Select method for new group (use tab for completion)")) + gnus-group-mode) (when (stringp method) (setq method (or (gnus-server-to-method method) method))) @@ -2794,7 +2797,7 @@ server." (defun gnus-group-delete-groups (&optional arg) "Delete the current group. Only meaningful with editable groups." - (interactive "P") + (interactive "P" gnus-group-mode) (let ((n (length (gnus-group-process-prefix arg)))) (when (gnus-yes-or-no-p (if (= n 1) @@ -2809,8 +2812,8 @@ server." If OLDP (the prefix), only delete articles that are \"old\", according to the expiry settings. Note that this will delete old not-expirable articles, too." - (interactive (list (gnus-group-group-name) - current-prefix-arg)) + (interactive (list (gnus-group-group-name) current-prefix-arg) + gnus-group-mode) (let ((articles (gnus-uncompress-range (gnus-active group)))) (when (gnus-yes-or-no-p (format "Do you really want to delete these %d articles forever? " @@ -2829,9 +2832,8 @@ doing the deletion. Note that you also have to specify FORCE if you want the group to be removed from the server, even when it's empty." - (interactive - (list (gnus-group-group-name) - current-prefix-arg)) + (interactive (list (gnus-group-group-name) current-prefix-arg) + gnus-group-mode) (unless group (error "No group to delete")) (unless (gnus-check-backend-function 'request-delete-group group) @@ -2865,7 +2867,8 @@ and NEW-NAME will be prompted for." "Rename group to: " (gnus-group-real-name group)) method (gnus-info-method (gnus-get-info group))) - (list group (gnus-group-prefixed-name new-name method)))) + (list group (gnus-group-prefixed-name new-name method))) + gnus-group-mode) (unless (gnus-check-backend-function 'request-rename-group group) (error "This back end does not support renaming groups")) @@ -2911,7 +2914,7 @@ and NEW-NAME will be prompted for." (defun gnus-group-edit-group (group &optional part) "Edit the group on the current line." - (interactive (list (gnus-group-group-name))) + (interactive (list (gnus-group-group-name)) gnus-group-mode) (let ((part (or part 'info)) info) (unless group @@ -2950,12 +2953,12 @@ and NEW-NAME will be prompted for." (defun gnus-group-edit-group-method (group) "Edit the select method of GROUP." - (interactive (list (gnus-group-group-name))) + (interactive (list (gnus-group-group-name)) gnus-group-mode) (gnus-group-edit-group group 'method)) (defun gnus-group-edit-group-parameters (group) "Edit the group parameters of GROUP." - (interactive (list (gnus-group-group-name))) + (interactive (list (gnus-group-group-name)) gnus-group-mode) (gnus-group-edit-group group 'params)) (defun gnus-group-edit-group-done (part group form) @@ -2993,14 +2996,16 @@ and NEW-NAME will be prompted for." (defun gnus-group-make-useful-group (group method) "Create one of the groups described in `gnus-useful-groups'." (interactive - (let ((entry (assoc (gnus-completing-read "Create group" - (mapcar #'car gnus-useful-groups) - t) + (let ((entry (assoc (gnus-completing-read + "Create group" + (mapcar #'car gnus-useful-groups) + t) gnus-useful-groups))) (list (cadr entry) - ;; Don't use `caddr' here since macros within the `interactive' - ;; form won't be expanded. - (car (cddr entry))))) + ;; Don't use `caddr' here since macros within the + ;; `interactive' form won't be expanded. + (car (cddr entry)))) + gnus-group-mode) (setq method (copy-tree method)) (let (entry) (while (setq entry (memq (assq 'eval method) method)) @@ -3014,7 +3019,7 @@ group already exists: - if not given, and error is signaled, - if t, stay silent, - if anything else, just print a message." - (interactive) + (interactive nil gnus-group-mode) (let ((name (gnus-group-prefixed-name "gnus-help" '(nndoc "gnus-help"))) (file (nnheader-find-etc-directory "gnus-tut.txt" t))) (if (gnus-group-entry name) @@ -3040,9 +3045,9 @@ group already exists: "Create a group that uses a single file as the source. If called with a prefix argument, ask for the file type." - (interactive - (list (read-file-name "File name: ") - (and current-prefix-arg 'ask))) + (interactive (list (read-file-name "File name: ") + (and current-prefix-arg 'ask)) + gnus-group-mode) (when (eq type 'ask) (let ((err "") char found) @@ -3077,7 +3082,7 @@ If called with a prefix argument, ask for the file type." (defun gnus-group-make-web-group (&optional solid) "Create an ephemeral nnweb group. If SOLID (the prefix), create a solid group." - (interactive "P") + (interactive "P" gnus-group-mode) (require 'nnweb) (let* ((group (if solid (gnus-read-group "Group name: ") @@ -3117,7 +3122,7 @@ If SOLID (the prefix), create a solid group." (defun gnus-group-make-rss-group (&optional url) "Given a URL, discover if there is an RSS feed. If there is, use Gnus to create an nnrss group" - (interactive) + (interactive nil gnus-group-mode) (require 'nnrss) (if (not url) (setq url (read-from-minibuffer "URL to Search for RSS: "))) @@ -3158,8 +3163,8 @@ If there is, use Gnus to create an nnrss group" The user will be prompted for a directory. The contents of this directory will be used as a newsgroup. The directory should contain mail messages or news articles in files that have numeric names." - (interactive - (list (read-directory-name "Create group from directory: "))) + (interactive (list (read-directory-name "Create group from directory: ")) + gnus-group-mode) (unless (file-exists-p dir) (error "No such directory")) (unless (file-directory-p dir) @@ -3192,7 +3197,7 @@ prefix arg NO-PARSE means that Gnus should not parse the search query before passing it to the underlying search engine. A non-nil SPECS arg must be an alist with `search-query-spec' and `search-group-spec' keys, and skips all prompting." - (interactive "P") + (interactive "P" gnus-group-mode) (let ((name (gnus-read-group "Group name: "))) (with-current-buffer gnus-group-buffer (let* ((group-spec @@ -3246,7 +3251,7 @@ prefix arg NO-PARSE means that Gnus should not parse the search query before passing it to the underlying search engine. A non-nil SPECS arg must be an alist with `search-query-spec' and `search-group-spec' keys, and skips all prompting." - (interactive "P") + (interactive "P" gnus-group-mode) (let* ((group-spec (or (cdr (assq 'search-group-spec specs)) (cdr (assq 'nnir-group-spec specs)) @@ -3286,10 +3291,10 @@ non-nil SPECS arg must be an alist with `search-query-spec' and (defun gnus-group-add-to-virtual (n vgroup) "Add the current group to a virtual group." - (interactive - (list current-prefix-arg - (gnus-group-completing-read "Add to virtual group" - nil t "nnvirtual:"))) + (interactive (list current-prefix-arg + (gnus-group-completing-read "Add to virtual group" + nil t "nnvirtual:")) + gnus-group-mode) (unless (eq (car (gnus-find-method-for-group vgroup)) 'nnvirtual) (error "%s is not an nnvirtual group" vgroup)) (gnus-close-group vgroup) @@ -3307,7 +3312,7 @@ non-nil SPECS arg must be an alist with `search-query-spec' and (defun gnus-group-make-empty-virtual (group) "Create a new, fresh, empty virtual group." - (interactive "sCreate new, empty virtual group: ") + (interactive "sCreate new, empty virtual group: " gnus-group-mode) (let* ((method (list 'nnvirtual "^$")) (pgroup (gnus-group-prefixed-name group method))) ;; Check whether it exists already. @@ -3321,7 +3326,7 @@ non-nil SPECS arg must be an alist with `search-query-spec' and (defun gnus-group-enter-directory (dir) "Enter an ephemeral nneething group." - (interactive "DDirectory to read: ") + (interactive "DDirectory to read: " gnus-group-mode) (let* ((method (list 'nneething dir '(nneething-read-only t))) (leaf (gnus-group-prefixed-name (file-name-nondirectory (directory-file-name dir)) @@ -3336,7 +3341,7 @@ non-nil SPECS arg must be an alist with `search-query-spec' and (defun gnus-group-expunge-group (group) "Expunge deleted articles in current nnimap GROUP." - (interactive (list (gnus-group-group-name))) + (interactive (list (gnus-group-group-name)) gnus-group-mode) (let ((method (gnus-find-method-for-group group))) (if (not (gnus-check-backend-function 'request-expunge-group (car method))) @@ -3348,7 +3353,7 @@ non-nil SPECS arg must be an alist with `search-query-spec' and (defun gnus-group-nnimap-edit-acl (group) "Edit the Access Control List of current nnimap GROUP." - (interactive (list (gnus-group-group-name))) + (interactive (list (gnus-group-group-name)) gnus-group-mode) (let ((mailbox (gnus-group-real-name group)) method acl) (unless group (error "No group on current line")) @@ -3395,7 +3400,8 @@ Editing the access control list for `%s'. When used interactively, the sorting function used will be determined by the `gnus-group-sort-function' variable. If REVERSE (the prefix), reverse the sorting order." - (interactive (list gnus-group-sort-function current-prefix-arg)) + (interactive (list gnus-group-sort-function current-prefix-arg) + gnus-group-mode) (funcall gnus-group-sort-alist-function (gnus-make-sort-function func) reverse) (gnus-group-unmark-all-groups) @@ -3428,56 +3434,57 @@ value is disregarded." (defun gnus-group-sort-groups-by-alphabet (&optional reverse) "Sort the group buffer alphabetically by group name. If REVERSE, sort in reverse order." - (interactive "P") + (interactive "P" gnus-group-mode) (gnus-group-sort-groups 'gnus-group-sort-by-alphabet reverse)) (defun gnus-group-sort-groups-by-real-name (&optional reverse) "Sort the group buffer alphabetically by real (unprefixed) group name. If REVERSE, sort in reverse order." - (interactive "P") + (interactive "P" gnus-group-mode) (gnus-group-sort-groups 'gnus-group-sort-by-real-name reverse)) (defun gnus-group-sort-groups-by-unread (&optional reverse) "Sort the group buffer by number of unread articles. If REVERSE, sort in reverse order." - (interactive "P") + (interactive "P" gnus-group-mode) (gnus-group-sort-groups 'gnus-group-sort-by-unread reverse)) (defun gnus-group-sort-groups-by-level (&optional reverse) "Sort the group buffer by group level. If REVERSE, sort in reverse order." - (interactive "P") + (interactive "P" gnus-group-mode) (gnus-group-sort-groups 'gnus-group-sort-by-level reverse)) (defun gnus-group-sort-groups-by-score (&optional reverse) "Sort the group buffer by group score. If REVERSE, sort in reverse order." - (interactive "P") + (interactive "P" gnus-group-mode) (gnus-group-sort-groups 'gnus-group-sort-by-score reverse)) (defun gnus-group-sort-groups-by-rank (&optional reverse) "Sort the group buffer by group rank. If REVERSE, sort in reverse order." - (interactive "P") + (interactive "P" gnus-group-mode) (gnus-group-sort-groups 'gnus-group-sort-by-rank reverse)) (defun gnus-group-sort-groups-by-method (&optional reverse) "Sort the group buffer alphabetically by back end name. If REVERSE, sort in reverse order." - (interactive "P") + (interactive "P" gnus-group-mode) (gnus-group-sort-groups 'gnus-group-sort-by-method reverse)) (defun gnus-group-sort-groups-by-server (&optional reverse) "Sort the group buffer alphabetically by server name. If REVERSE, sort in reverse order." - (interactive "P") + (interactive "P" gnus-group-mode) (gnus-group-sort-groups 'gnus-group-sort-by-server reverse)) ;;; Selected group sorting. (defun gnus-group-sort-selected-groups (n func &optional reverse) "Sort the process/prefixed groups." - (interactive (list current-prefix-arg gnus-group-sort-function)) + (interactive (list current-prefix-arg gnus-group-sort-function) + gnus-group-mode) (let ((groups (gnus-group-process-prefix n))) (funcall gnus-group-sort-selected-function groups (gnus-make-sort-function func) reverse) @@ -3509,49 +3516,49 @@ If REVERSE is non-nil, reverse the sorting." "Sort the group buffer alphabetically by group name. Obeys the process/prefix convention. If REVERSE (the symbolic prefix), sort in reverse order." - (interactive (gnus-interactive "P\ny")) + (interactive (gnus-interactive "P\ny") gnus-group-mode) (gnus-group-sort-selected-groups n 'gnus-group-sort-by-alphabet reverse)) (defun gnus-group-sort-selected-groups-by-real-name (&optional n reverse) "Sort the group buffer alphabetically by real group name. Obeys the process/prefix convention. If REVERSE (the symbolic prefix), sort in reverse order." - (interactive (gnus-interactive "P\ny")) + (interactive (gnus-interactive "P\ny") gnus-group-mode) (gnus-group-sort-selected-groups n 'gnus-group-sort-by-real-name reverse)) (defun gnus-group-sort-selected-groups-by-unread (&optional n reverse) "Sort the group buffer by number of unread articles. Obeys the process/prefix convention. If REVERSE (the symbolic prefix), sort in reverse order." - (interactive (gnus-interactive "P\ny")) + (interactive (gnus-interactive "P\ny") gnus-group-mode) (gnus-group-sort-selected-groups n 'gnus-group-sort-by-unread reverse)) (defun gnus-group-sort-selected-groups-by-level (&optional n reverse) "Sort the group buffer by group level. Obeys the process/prefix convention. If REVERSE (the symbolic prefix), sort in reverse order." - (interactive (gnus-interactive "P\ny")) + (interactive (gnus-interactive "P\ny") gnus-group-mode) (gnus-group-sort-selected-groups n 'gnus-group-sort-by-level reverse)) (defun gnus-group-sort-selected-groups-by-score (&optional n reverse) "Sort the group buffer by group score. Obeys the process/prefix convention. If REVERSE (the symbolic prefix), sort in reverse order." - (interactive (gnus-interactive "P\ny")) + (interactive (gnus-interactive "P\ny") gnus-group-mode) (gnus-group-sort-selected-groups n 'gnus-group-sort-by-score reverse)) (defun gnus-group-sort-selected-groups-by-rank (&optional n reverse) "Sort the group buffer by group rank. Obeys the process/prefix convention. If REVERSE (the symbolic prefix), sort in reverse order." - (interactive (gnus-interactive "P\ny")) + (interactive (gnus-interactive "P\ny") gnus-group-mode) (gnus-group-sort-selected-groups n 'gnus-group-sort-by-rank reverse)) (defun gnus-group-sort-selected-groups-by-method (&optional n reverse) "Sort the group buffer alphabetically by back end name. Obeys the process/prefix convention. If REVERSE (the symbolic prefix), sort in reverse order." - (interactive (gnus-interactive "P\ny")) + (interactive (gnus-interactive "P\ny") gnus-group-mode) (gnus-group-sort-selected-groups n 'gnus-group-sort-by-method reverse)) ;;; Sorting predicates. @@ -3609,7 +3616,7 @@ sort in reverse order." (defun gnus-group-clear-data (&optional arg) "Clear all marks and read ranges from the current group. Obeys the process/prefix convention." - (interactive "P") + (interactive "P" gnus-group-mode) (when (gnus-y-or-n-p "Really clear data? ") (gnus-group-iterate arg (lambda (group) @@ -3621,7 +3628,7 @@ Obeys the process/prefix convention." (defun gnus-group-clear-data-on-native-groups () "Clear all marks and read ranges from all native groups." - (interactive) + (interactive nil gnus-group-mode) (when (gnus-yes-or-no-p "Really clear all data from almost all groups? ") (let ((alist (cdr gnus-newsrc-alist)) info) @@ -3665,7 +3672,7 @@ caught up. If ALL is non-nil, marked articles will also be marked as read. Cross references (Xref: header) of articles are ignored. The number of newsgroups that this function was unable to catch up is returned." - (interactive "P") + (interactive "P" gnus-group-mode) (let ((groups (gnus-group-process-prefix n)) (ret 0) group) @@ -3704,7 +3711,7 @@ up is returned." (defun gnus-group-catchup-current-all (&optional n) "Mark all articles in current newsgroup as read. Cross references (Xref: header) of articles are ignored." - (interactive "P") + (interactive "P" gnus-group-mode) (gnus-group-catchup-current n 'all)) (declare-function gnus-sequence-of-unread-articles "gnus-sum" (group)) @@ -3751,7 +3758,7 @@ or nil if no action could be taken." (defun gnus-group-expire-articles (&optional n) "Expire all expirable articles in the current newsgroup. Uses the process/prefix convention." - (interactive "P") + (interactive "P" gnus-group-mode) (let ((groups (gnus-group-process-prefix n)) group) (unless groups @@ -3797,7 +3804,7 @@ Uses the process/prefix convention." (defun gnus-group-expire-all-groups () "Expire all expirable articles in all newsgroups." - (interactive) + (interactive nil gnus-group-mode) (save-excursion (gnus-message 5 "Expiring...") (let ((gnus-group-marked (mapcar (lambda (info) (gnus-info-group info)) @@ -3821,7 +3828,8 @@ Uses the process/prefix convention." (if (string-match "^\\s-*$" s) (int-to-string (or (gnus-group-group-level) gnus-level-default-subscribed)) - s)))))) + s))))) + gnus-group-mode) (unless (and (>= level 1) (<= level gnus-level-killed)) (error "Invalid level: %d" level)) (dolist (group (gnus-group-process-prefix n)) @@ -3837,18 +3845,18 @@ Uses the process/prefix convention." (defun gnus-group-unsubscribe (&optional n) "Unsubscribe the current group." - (interactive "P") + (interactive "P" gnus-group-mode) (gnus-group-unsubscribe-current-group n 'unsubscribe)) (defun gnus-group-subscribe (&optional n) "Subscribe the current group." - (interactive "P") + (interactive "P" gnus-group-mode) (gnus-group-unsubscribe-current-group n 'subscribe)) (defun gnus-group-unsubscribe-current-group (&optional n do-sub) "Toggle subscription of the current group. If given numerical prefix, toggle the N next groups." - (interactive "P") + (interactive "P" gnus-group-mode) (dolist (group (gnus-group-process-prefix n)) (gnus-group-remove-mark group) (gnus-group-unsubscribe-group @@ -3871,7 +3879,8 @@ If given numerical prefix, toggle the N next groups." Killed newsgroups are subscribed. If SILENT, don't try to update the group line." (interactive (list (gnus-group-completing-read - nil nil (gnus-read-active-file-p)))) + nil nil (gnus-read-active-file-p))) + gnus-group-mode) (let ((newsrc (gnus-group-entry group))) (cond ((string-match "\\`[ \t]*\\'" group) @@ -3905,7 +3914,7 @@ group line." "Move the current newsgroup up N places. If given a negative prefix, move down instead. The difference between N and the number of steps taken is returned." - (interactive "p") + (interactive "p" gnus-group-mode) (unless (gnus-group-group-name) (error "No group on current line")) (gnus-group-kill-group 1) @@ -3917,7 +3926,8 @@ N and the number of steps taken is returned." (defun gnus-group-kill-all-zombies (&optional dummy) "Kill all zombie newsgroups. The optional DUMMY should always be nil." - (interactive (list (not (gnus-yes-or-no-p "Really kill all zombies? ")))) + (interactive (list (not (gnus-yes-or-no-p "Really kill all zombies? "))) + gnus-group-mode) (unless dummy (setq gnus-killed-list (nconc gnus-zombie-list gnus-killed-list)) (setq gnus-zombie-list nil) @@ -3927,7 +3937,7 @@ The optional DUMMY should always be nil." (defun gnus-group-kill-region (begin end) "Kill newsgroups in current region (excluding current point). The killed newsgroups can be yanked by using \\[gnus-group-yank-group]." - (interactive "r") + (interactive "r" gnus-group-mode) (let ((lines ;; Count lines. (save-excursion @@ -3949,7 +3959,7 @@ However, only groups that were alive can be yanked; already killed groups or zombie groups can't be yanked. The return value is the name of the group that was killed, or a list of groups killed." - (interactive "P") + (interactive "P" gnus-group-mode) (let ((buffer-read-only nil) (groups (gnus-group-process-prefix n)) group entry level out) @@ -4009,7 +4019,7 @@ of groups killed." The numeric ARG specifies how many newsgroups are to be yanked. The name of the newsgroup yanked is returned, or (if several groups are yanked) a list of yanked groups is returned." - (interactive "p") + (interactive "p" gnus-group-mode) (setq arg (or arg 1)) (let (info group prev out) (while (>= (cl-decf arg) 0) @@ -4034,7 +4044,7 @@ yanked) a list of yanked groups is returned." (defun gnus-group-kill-level (level) "Kill all groups that is on a certain LEVEL." - (interactive "nKill all groups on level: ") + (interactive "nKill all groups on level: " gnus-group-mode) (cond ((= level gnus-level-zombie) (setq gnus-killed-list @@ -4065,7 +4075,7 @@ yanked) a list of yanked groups is returned." "List all newsgroups with level ARG or lower. Default is `gnus-level-unsubscribed', which lists all subscribed and most unsubscribed groups." - (interactive "P") + (interactive "P" gnus-group-mode) (gnus-group-list-groups (or arg gnus-level-unsubscribed) t)) ;; Redefine this to list ALL killed groups if prefix arg used. @@ -4074,7 +4084,7 @@ unsubscribed groups." "List all killed newsgroups in the group buffer. If ARG is non-nil, list ALL killed groups known to Gnus. This may entail asking the server for the groups." - (interactive "P") + (interactive "P" gnus-group-mode) ;; Find all possible killed newsgroups if arg. (when arg (gnus-get-killed-groups)) @@ -4088,7 +4098,7 @@ entail asking the server for the groups." (defun gnus-group-list-zombies () "List all zombie newsgroups in the group buffer." - (interactive) + (interactive nil gnus-group-mode) (if (not gnus-zombie-list) (gnus-message 6 "No zombie groups") (let (gnus-group-list-mode) @@ -4099,7 +4109,7 @@ entail asking the server for the groups." (defun gnus-group-list-active () "List all groups that are available from the server(s)." - (interactive) + (interactive nil gnus-group-mode) ;; First we make sure that we have really read the active file. (unless (gnus-read-active-file-p) (let ((gnus-read-active-file t) @@ -4121,7 +4131,7 @@ entail asking the server for the groups." (defun gnus-activate-all-groups (level) "Activate absolutely all groups." - (interactive (list gnus-level-unsubscribed)) + (interactive (list gnus-level-unsubscribed) gnus-group-mode) (let ((gnus-activate-level level) (gnus-activate-foreign-newsgroups level)) (gnus-group-get-new-news))) @@ -4133,7 +4143,7 @@ re-scanning. If ARG is non-nil and not a number, this will force \"hard\" re-reading of the active files from all servers. If ONE-LEVEL is not nil, then re-scan only the specified level, otherwise all levels below ARG will be scanned too." - (interactive "P") + (interactive "P" gnus-group-mode) (require 'nnmail) (let ((gnus-inhibit-demon t) ;; Binding this variable will inhibit multiple fetchings @@ -4163,7 +4173,7 @@ otherwise all levels below ARG will be scanned too." The difference between N and the number of newsgroup checked is returned. If N is negative, this group and the N-1 previous groups will be checked. If DONT-SCAN is non-nil, scan non-activated groups as well." - (interactive "P") + (interactive "P" gnus-group-mode) (let* ((groups (gnus-group-process-prefix n)) (ret (if (numberp n) (- n (length groups)) 0)) (beg (unless n @@ -4208,7 +4218,8 @@ If DONT-SCAN is non-nil, scan non-activated groups as well." (defun gnus-group-describe-group (force &optional group) "Display a description of the current newsgroup." - (interactive (list current-prefix-arg (gnus-group-group-name))) + (interactive (list current-prefix-arg (gnus-group-group-name)) + gnus-group-mode) (let* ((method (gnus-find-method-for-group group)) (mname (gnus-group-prefixed-name "" method)) desc) @@ -4230,7 +4241,7 @@ If DONT-SCAN is non-nil, scan non-activated groups as well." ;; Suggested by Per Abrahamsen . (defun gnus-group-describe-all-groups (&optional force) "Pop up a buffer with descriptions of all newsgroups." - (interactive "P") + (interactive "P" gnus-group-mode) (when force (setq gnus-description-hashtb nil)) (when (not (or gnus-description-hashtb @@ -4255,7 +4266,7 @@ If DONT-SCAN is non-nil, scan non-activated groups as well." ;; Suggested by Daniel Quinlan . (defun gnus-group-apropos (regexp &optional search-description) "List all newsgroups that have names that match a regexp." - (interactive "sGnus apropos (regexp): ") + (interactive "sGnus apropos (regexp): " gnus-group-mode) (let ((prev "") (obuf (current-buffer)) groups des) @@ -4294,7 +4305,7 @@ If DONT-SCAN is non-nil, scan non-activated groups as well." (defun gnus-group-description-apropos (regexp) "List all newsgroups that have names or descriptions that match REGEXP." - (interactive "sGnus description apropos (regexp): ") + (interactive "sGnus description apropos (regexp): " gnus-group-mode) (when (not (or gnus-description-hashtb (gnus-read-all-descriptions-files))) (error "Couldn't request descriptions file")) @@ -4309,7 +4320,7 @@ If ALL, also list groups with no unread articles. If LOWEST, don't list groups with level lower than LOWEST. This command may read the active file." - (interactive "P\nsList newsgroups matching: ") + (interactive "P\nsList newsgroups matching: " gnus-group-mode) ;; First make sure active file has been read. (when (and level (> (prefix-numeric-value level) gnus-level-killed)) @@ -4324,7 +4335,7 @@ This command may read the active file." If the prefix LEVEL is non-nil, it should be a number that says which level to cut off listing groups. If LOWEST, don't list groups with level lower than LOWEST." - (interactive "P\nsList newsgroups matching: ") + (interactive "P\nsList newsgroups matching: " gnus-group-mode) (when level (setq level (prefix-numeric-value level))) (gnus-group-list-matching (or level gnus-level-killed) regexp t lowest)) @@ -4333,12 +4344,12 @@ If LOWEST, don't list groups with level lower than LOWEST." (defun gnus-group-save-newsrc (&optional force) "Save the Gnus startup files. If FORCE, force saving whether it is necessary or not." - (interactive "P") + (interactive "P" gnus-group-mode) (gnus-save-newsrc-file force)) (defun gnus-group-restart (&optional _arg) "Force Gnus to read the .newsrc file." - (interactive) + (interactive nil gnus-group-mode) (when (gnus-yes-or-no-p (format "Are you sure you want to restart Gnus? ")) (gnus-save-newsrc-file) @@ -4347,7 +4358,7 @@ If FORCE, force saving whether it is necessary or not." (defun gnus-group-read-init-file () "Read the Gnus elisp init file." - (interactive) + (interactive nil gnus-group-mode) (gnus-read-init-file) (gnus-message 5 "Read %s" gnus-init-file)) @@ -4355,7 +4366,7 @@ If FORCE, force saving whether it is necessary or not." "Check bogus newsgroups. If given a prefix, don't ask for confirmation before removing a bogus group." - (interactive "P") + (interactive "P" gnus-group-mode) (gnus-check-bogus-newsgroups (and (not silent) (not gnus-expert-user))) (gnus-group-list-groups)) @@ -4366,7 +4377,7 @@ With 1 C-u, use the `ask-server' method to query the server for new groups. With 2 C-u's, use most complete method possible to query the server for new groups, and subscribe the new groups as zombies." - (interactive "p") + (interactive "p" gnus-group-mode) (let ((new-groups (gnus-find-new-newsgroups (or arg 1))) current-group) (gnus-group-list-groups) @@ -4379,7 +4390,7 @@ for new groups, and subscribe the new groups as zombies." (defun gnus-group-edit-global-kill (&optional article group) "Edit the global kill file. If GROUP, edit that local kill file instead." - (interactive "P") + (interactive "P" gnus-group-mode) (setq gnus-current-kill-article article) (gnus-kill-file-edit-file group) (gnus-message 6 "Editing a %s kill file (Type %s to exit)" @@ -4388,12 +4399,12 @@ If GROUP, edit that local kill file instead." (defun gnus-group-edit-local-kill (article group) "Edit a local kill file." - (interactive (list nil (gnus-group-group-name))) + (interactive (list nil (gnus-group-group-name)) gnus-group-mode) (gnus-group-edit-global-kill article group)) (defun gnus-group-force-update () "Update `.newsrc' file." - (interactive) + (interactive nil gnus-group-mode) (gnus-save-newsrc-file)) (defvar gnus-backlog-articles) @@ -4402,7 +4413,7 @@ If GROUP, edit that local kill file instead." "Suspend the current Gnus session. In fact, cleanup buffers except for group mode buffer. The hook `gnus-suspend-gnus-hook' is called before actually suspending." - (interactive) + (interactive nil gnus-group-mode) (gnus-run-hooks 'gnus-suspend-gnus-hook) (gnus-offer-save-summaries) ;; Kill Gnus buffers except for group mode buffer. @@ -4425,14 +4436,14 @@ The hook `gnus-suspend-gnus-hook' is called before actually suspending." (defun gnus-group-clear-dribble () "Clear all information from the dribble buffer." - (interactive) + (interactive nil gnus-group-mode) (gnus-dribble-clear) (gnus-message 7 "Cleared dribble buffer")) (defun gnus-group-exit () "Quit reading news after updating .newsrc.eld and .newsrc. The hook `gnus-exit-gnus-hook' is called before actually exiting." - (interactive) + (interactive nil gnus-group-mode) (when (or noninteractive ;For gnus-batch-kill (not gnus-interactive-exit) ;Without confirmation @@ -4466,7 +4477,7 @@ The hook `gnus-exit-gnus-hook' is called before actually exiting." (defun gnus-group-quit () "Quit reading news without updating .newsrc.eld or .newsrc. The hook `gnus-exit-gnus-hook' is called before actually exiting." - (interactive) + (interactive nil gnus-group-mode) (when (or noninteractive ;For gnus-batch-kill (zerop (buffer-size)) (not (gnus-server-opened gnus-select-method)) @@ -4491,7 +4502,7 @@ The hook `gnus-exit-gnus-hook' is called before actually exiting." (defun gnus-group-describe-briefly () "Give a one line description of the group mode commands." - (interactive) + (interactive nil gnus-group-mode) (gnus-message 7 "%s" (substitute-command-keys "\\\\[gnus-group-read-group]:Select \\[gnus-group-next-unread-group]:Forward \\[gnus-group-prev-unread-group]:Backward \\[gnus-group-exit]:Exit \\[gnus-info-find-node]:Run Info \\[gnus-group-describe-briefly]:This help"))) (defun gnus-group-browse-foreign-server (method) @@ -4504,7 +4515,7 @@ and the second element is the address." (list (let ((how (gnus-completing-read "Which back end" (mapcar #'car (append gnus-valid-select-methods - gnus-server-alist)) + gnus-server-alist)) t (cons "nntp" 0) 'gnus-method-history))) ;; We either got a back end name or a virtual server name. ;; If the first, we also need an address. @@ -4520,7 +4531,8 @@ and the second element is the address." gnus-secondary-servers (cdr gnus-select-method)))) ;; We got a server name. - how)))) + how))) + gnus-group-mode) (gnus-browse-foreign-server method)) (defun gnus-group-set-info (info &optional method-only-group part) @@ -4678,7 +4690,7 @@ level to cut off listing groups. If LOWEST, don't list groups with level lower than LOWEST. This command may read the active file." - (interactive "P") + (interactive "P" gnus-group-mode) (when level (setq level (prefix-numeric-value level))) (when (or (not level) (>= level gnus-level-zombie)) @@ -4709,7 +4721,7 @@ level to cut off listing groups. If LOWEST, don't list groups with level lower than LOWEST. This command may read the active file." - (interactive "P") + (interactive "P" gnus-group-mode) (when level (setq level (prefix-numeric-value level))) (when (or (not level) (>= level gnus-level-zombie)) @@ -4731,7 +4743,7 @@ level to cut off listing groups. If LOWEST, don't list groups with level lower than LOWEST. This command may read the active file." - (interactive "P") + (interactive "P" gnus-group-mode) (when level (setq level (prefix-numeric-value level))) (when (or (not level) (>= level gnus-level-zombie)) @@ -4759,7 +4771,7 @@ This command may read the active file." (defun gnus-group-list-plus (&optional _args) "List groups plus the current selection." - (interactive) + (interactive nil gnus-group-mode) (let ((gnus-group-listed-groups (gnus-group-listed-groups)) (gnus-group-list-mode gnus-group-list-mode) ;; Save it. func) @@ -4775,7 +4787,7 @@ This command may read the active file." (defun gnus-group-list-flush (&optional args) "Flush groups from the current selection." - (interactive "P") + (interactive "P" gnus-group-mode) (let ((gnus-group-list-option 'flush)) (gnus-group-list-plus args))) @@ -4786,7 +4798,7 @@ with this command. If you've first limited to groups with dormant articles with `A ?', you can then further limit with `A / c', which will then limit to groups with cached articles, giving you the groups that have both dormant articles and cached articles." - (interactive "P") + (interactive "P" gnus-group-mode) (let ((gnus-group-list-option 'limit)) (gnus-group-list-plus args))) @@ -4839,7 +4851,7 @@ operation is only meaningful for back ends using one file per article \(e.g. nnml). Note: currently only implemented in nnml." - (interactive (list (gnus-group-group-name))) + (interactive (list (gnus-group-group-name)) gnus-group-mode) (unless group (error "No group to compact")) (unless (gnus-check-backend-function 'request-compact-group group) diff --git a/lisp/gnus/gnus-icalendar.el b/lisp/gnus/gnus-icalendar.el index 9811e8b440..1b2743c148 100644 --- a/lisp/gnus/gnus-icalendar.el +++ b/lisp/gnus/gnus-icalendar.el @@ -970,7 +970,7 @@ These will be used to retrieve the RSVP information from ical events." (defun gnus-icalendar-save-event () "Save the Calendar event in the text/calendar part under point." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-article-check-buffer) (let ((data (get-text-property (point) 'gnus-data))) (when data @@ -978,28 +978,28 @@ These will be used to retrieve the RSVP information from ical events." (defun gnus-icalendar-reply-accept () "Accept invitation in the current article." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (with-current-buffer gnus-article-buffer (gnus-icalendar-reply (list gnus-icalendar-handle 'accepted gnus-icalendar-event)) (setq-local gnus-icalendar-reply-status 'accepted))) (defun gnus-icalendar-reply-tentative () "Send tentative response to invitation in the current article." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (with-current-buffer gnus-article-buffer (gnus-icalendar-reply (list gnus-icalendar-handle 'tentative gnus-icalendar-event)) (setq-local gnus-icalendar-reply-status 'tentative))) (defun gnus-icalendar-reply-decline () "Decline invitation in the current article." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (with-current-buffer gnus-article-buffer (gnus-icalendar-reply (list gnus-icalendar-handle 'declined gnus-icalendar-event)) (setq-local gnus-icalendar-reply-status 'declined))) (defun gnus-icalendar-event-export () "Export calendar event to `org-mode', or update existing agenda entry." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (with-current-buffer gnus-article-buffer (gnus-icalendar-sync-event-to-org gnus-icalendar-event)) ;; refresh article buffer in case the reply had been sent before initial org @@ -1009,14 +1009,14 @@ These will be used to retrieve the RSVP information from ical events." (defun gnus-icalendar-event-show () "Display `org-mode' agenda entry related to the calendar event." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-icalendar--show-org-event (with-current-buffer gnus-article-buffer gnus-icalendar-event))) (defun gnus-icalendar-event-check-agenda () "Display `org-mode' agenda for days between event start and end dates." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-icalendar-show-org-agenda (with-current-buffer gnus-article-buffer gnus-icalendar-event))) diff --git a/lisp/gnus/gnus-int.el b/lisp/gnus/gnus-int.el index 64928623e6..01053797b3 100644 --- a/lisp/gnus/gnus-int.el +++ b/lisp/gnus/gnus-int.el @@ -662,7 +662,7 @@ This is the string that Gnus uses to identify the group." "Look up the current article in the group where it originated. This command only makes sense for groups shows articles gathered from other groups -- for instance, search results and the like." - (interactive) + (interactive nil gnus-summary-mode) (let ((gnus-command-method (gnus-find-method-for-group gnus-newsgroup-name))) (or diff --git a/lisp/gnus/gnus-mh.el b/lisp/gnus/gnus-mh.el index fc8d9be8d6..df076c1175 100644 --- a/lisp/gnus/gnus-mh.el +++ b/lisp/gnus/gnus-mh.el @@ -53,7 +53,7 @@ If N is a positive number, save the N next articles. If N is a negative number, save the N previous articles. If N is nil and any articles have been marked with the process mark, save those articles instead." - (interactive "P") + (interactive "P" gnus-summary-mode) (require 'gnus-art) (let ((gnus-default-article-saver 'gnus-summary-save-in-folder)) (gnus-summary-save-article arg))) diff --git a/lisp/gnus/gnus-msg.el b/lisp/gnus/gnus-msg.el index 61b76381a0..d7851f2629 100644 --- a/lisp/gnus/gnus-msg.el +++ b/lisp/gnus/gnus-msg.el @@ -653,7 +653,7 @@ network. The corresponding back end must have a `request-post' method." If ARG, post to group under point. If ARG is 1, prompt for group name. Depending on the selected group, the message might be either a mail or a news." - (interactive "P") + (interactive "P" gnus-group-mode) ;; Bind this variable here to make message mode hooks work ok. (let ((gnus-newsgroup-name (if arg @@ -672,7 +672,7 @@ a news." Use the posting of the current group by default. If ARG, don't do that. If ARG is 1, prompt for group name to find the posting style." - (interactive "P") + (interactive "P" gnus-summary-mode) (let* (;;(group gnus-newsgroup-name) ;; make sure last viewed article doesn't affect posting styles: (gnus-article-copy) @@ -695,7 +695,7 @@ If ARG, don't do that. If ARG is 1, prompt for group name to post to. This function prepares a news even when using mail groups. This is useful for posting messages to mail groups without actually sending them over the network. The corresponding back end must have a `request-post' method." - (interactive "P") + (interactive "P" gnus-summary-mode) (let* (;;(group gnus-newsgroup-name) ;; make sure last viewed article doesn't affect posting styles: (gnus-article-copy) @@ -722,7 +722,7 @@ network. The corresponding back end must have a `request-post' method." If ARG, don't do that. If ARG is 1, prompt for a group name to post to. Depending on the selected group, the message might be either a mail or a news." - (interactive "P") + (interactive "P" gnus-summary-mode) ;; Bind this variable here to make message mode hooks work ok. (let ((gnus-newsgroup-name (if arg @@ -742,9 +742,9 @@ If prefix argument YANK is non-nil, the original article is yanked automatically. YANK is a list of elements, where the car of each element is the article number, and the cdr is the string to be yanked." - (interactive - (list (and current-prefix-arg - (gnus-summary-work-articles 1)))) + (interactive (list (and current-prefix-arg + (gnus-summary-work-articles 1))) + gnus-summary-mode) (when yank (gnus-summary-goto-subject (if (listp (car yank)) @@ -764,19 +764,19 @@ article number, and the cdr is the string to be yanked." "Compose a followup to an article and include the original article. The text in the region will be yanked. If the region isn't active, the entire article will be yanked." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-followup (gnus-summary-work-articles n) force-news)) (defun gnus-summary-followup-to-mail (&optional arg) "Followup to the current mail message via news." - (interactive - (list (and current-prefix-arg - (gnus-summary-work-articles 1)))) + (interactive (list (and current-prefix-arg + (gnus-summary-work-articles 1))) + gnus-summary-mode) (gnus-summary-followup arg t)) (defun gnus-summary-followup-to-mail-with-original (&optional arg) "Followup to the current mail message via news." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-followup (gnus-summary-work-articles arg) t)) (defun gnus-inews-yank-articles (articles) @@ -811,7 +811,7 @@ active, the entire article will be yanked." Uses the process-prefix convention. If given the symbolic prefix `a', cancel using the standard posting method; if not post using the current select method." - (interactive (gnus-interactive "P\ny")) + (interactive (gnus-interactive "P\ny") gnus-summary-mode) (let ((message-post-method (let ((gn gnus-newsgroup-name)) (lambda (_arg) (gnus-post-method (eq symp 'a) gn)))) @@ -841,7 +841,7 @@ post using the current select method." "Compose an article that will supersede a previous article. This is done simply by taking the old article and adding a Supersedes header line with the old Message-ID." - (interactive) + (interactive nil gnus-summary-mode) (let ((article (gnus-summary-article-number)) (mail-parse-charset gnus-newsgroup-charset)) (gnus-setup-message 'reply-yank @@ -1080,7 +1080,6 @@ If SILENT, don't prompt the user." (defun gnus-extended-version () "Stringified Gnus version and Emacs version. See the variable `gnus-user-agent'." - (interactive) (if (stringp gnus-user-agent) gnus-user-agent ;; `gnus-user-agent' is a list: @@ -1109,9 +1108,9 @@ If prefix argument YANK is non-nil, the original article is yanked automatically. If WIDE, make a wide reply. If VERY-WIDE, make a very wide reply." - (interactive - (list (and current-prefix-arg - (gnus-summary-work-articles 1)))) + (interactive (list (and current-prefix-arg + (gnus-summary-work-articles 1))) + gnus-summary-mode) ;; Allow user to require confirmation before replying by mail to the ;; author of a news article (or mail message). (when (or (not (or (gnus-news-group-p gnus-newsgroup-name) @@ -1179,14 +1178,14 @@ If VERY-WIDE, make a very wide reply." (defun gnus-summary-reply-with-original (n &optional wide) "Start composing a reply mail to the current message. The original article will be yanked." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-reply (gnus-summary-work-articles n) wide)) (defun gnus-summary-reply-to-list-with-original (n &optional wide) "Start composing a reply mail to the current message. The reply goes only to the mailing list. The original article will be yanked." - (interactive "P") + (interactive "P" gnus-summary-mode) (let ((message-reply-to-function (lambda nil `((To . ,(gnus-mailing-list-followup-to)))))) @@ -1198,32 +1197,32 @@ If prefix argument YANK is non-nil, the original article is yanked automatically. If WIDE, make a wide reply. If VERY-WIDE, make a very wide reply." - (interactive - (list (and current-prefix-arg - (gnus-summary-work-articles 1)))) + (interactive (list (and current-prefix-arg + (gnus-summary-work-articles 1))) + gnus-summary-mode) (let ((gnus-msg-force-broken-reply-to t)) (gnus-summary-reply yank wide very-wide))) (defun gnus-summary-reply-broken-reply-to-with-original (n &optional wide) "Like `gnus-summary-reply-with-original' except removing reply-to field. The original article will be yanked." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-reply-broken-reply-to (gnus-summary-work-articles n) wide)) (defun gnus-summary-wide-reply (&optional yank) "Start composing a wide reply mail to the current message. If prefix argument YANK is non-nil, the original article is yanked automatically." - (interactive - (list (and current-prefix-arg - (gnus-summary-work-articles 1)))) + (interactive (list (and current-prefix-arg + (gnus-summary-work-articles 1))) + gnus-summary-mode) (gnus-summary-reply yank t)) (defun gnus-summary-wide-reply-with-original (n) "Start composing a wide reply mail to the current message. The original article(s) will be yanked. Uses the process/prefix convention." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-reply-with-original n t)) (defun gnus-summary-very-wide-reply (&optional yank) @@ -1236,9 +1235,9 @@ messages as the To/Cc headers. If prefix argument YANK is non-nil, the original article(s) will be yanked automatically." - (interactive - (list (and current-prefix-arg - (gnus-summary-work-articles 1)))) + (interactive (list (and current-prefix-arg + (gnus-summary-work-articles 1))) + gnus-summary-mode) (gnus-summary-reply yank t (gnus-summary-work-articles yank))) (defun gnus-summary-very-wide-reply-with-original (n) @@ -1250,7 +1249,7 @@ The reply will include all From/Cc headers from the original messages as the To/Cc headers. The original article(s) will be yanked." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-reply (gnus-summary-work-articles n) t (gnus-summary-work-articles n))) @@ -1266,7 +1265,7 @@ otherwise, use flipped `message-forward-as-mime'. If POST, post instead of mail. For the \"inline\" alternatives, also see the variable `message-forward-ignored-headers'." - (interactive "P") + (interactive "P" gnus-summary-mode) (if (cdr (gnus-summary-work-articles nil)) ;; Process marks are given. (gnus-uu-digest-mail-forward nil post) @@ -1355,7 +1354,8 @@ the message before resending." ;; initial-contents. (with-current-buffer gnus-original-article-buffer (nnmail-fetch-field "to")))) - current-prefix-arg)) + current-prefix-arg) + gnus-summary-mode) (let ((message-header-setup-hook (copy-sequence message-header-setup-hook)) (message-sent-hook (copy-sequence message-sent-hook)) ;; Honor posting-style for `name' and `address' in Resent-From header. @@ -1408,7 +1408,7 @@ the message before resending." A new buffer will be created to allow the user to modify body and contents of the message, and then, everything will happen as when composing a new message." - (interactive) + (interactive nil gnus-summary-mode) (let ((mail-parse-charset gnus-newsgroup-charset)) (gnus-setup-message 'reply-yank (gnus-summary-select-article t) @@ -1436,12 +1436,12 @@ composing a new message." (defun gnus-summary-post-forward (&optional arg) "Forward the current article to a newsgroup. See `gnus-summary-mail-forward' for ARG." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-mail-forward arg t)) (defun gnus-summary-mail-crosspost-complaint (n) "Send a complaint about crossposting to the current article(s)." - (interactive "P") + (interactive "P" gnus-summary-mode) (dolist (article (gnus-summary-work-articles n)) (set-buffer gnus-summary-buffer) (gnus-summary-goto-subject article) @@ -1509,9 +1509,9 @@ Already submitted bugs can be found in the Emacs bug tracker: (defun gnus-summary-yank-message (buffer n) "Yank the current article into a composed message." - (interactive - (list (gnus-completing-read "Buffer" (message-buffers) t) - current-prefix-arg)) + (interactive (list (gnus-completing-read "Buffer" (message-buffers) t) + current-prefix-arg) + gnus-summary-mode) (gnus-summary-iterate n (let ((gnus-inhibit-treatment t)) (gnus-summary-select-article)) @@ -1528,7 +1528,7 @@ contains some mail you have written which has been bounced back to you. If FETCH, try to fetch the article that this is a reply to, if indeed this is a reply." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-select-article t) (let (summary-buffer parent) (if fetch @@ -1571,7 +1571,6 @@ this is a reply." ;; Do Gcc handling, which copied the message over to some group. (defun gnus-inews-do-gcc (&optional gcc) - (interactive) (save-excursion (save-restriction (message-narrow-to-headers) @@ -1964,7 +1963,7 @@ created. This command uses the process/prefix convention, so if you process-mark several articles, they will all be attached." - (interactive "P") + (interactive "P" gnus-summary-mode) (let ((buffers (message-buffers)) destination) ;; Set up the destination mail composition buffer. diff --git a/lisp/gnus/gnus-picon.el b/lisp/gnus/gnus-picon.el index 7927b88c3d..fd4d3b8a76 100644 --- a/lisp/gnus/gnus-picon.el +++ b/lisp/gnus/gnus-picon.el @@ -244,7 +244,7 @@ replacement is added." (gnus-picon-insert-glyph (pop spec) category)))))))))) (defun gnus-picon-transform-newsgroups (header) - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-with-article-headers (gnus-article-goto-header header) (mail-header-narrow-to-field) @@ -283,7 +283,7 @@ replacement is added." (defun gnus-treat-from-picon () "Display picons in the From header. If picons are already displayed, remove them." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (let ((wash-picon-p buffer-read-only)) (gnus-with-article-buffer (if (and wash-picon-p (memq 'from-picon gnus-article-wash-types)) @@ -294,7 +294,7 @@ If picons are already displayed, remove them." (defun gnus-treat-mail-picon () "Display picons in the Cc and To headers. If picons are already displayed, remove them." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (let ((wash-picon-p buffer-read-only)) (gnus-with-article-buffer (if (and wash-picon-p (memq 'mail-picon gnus-article-wash-types)) @@ -306,7 +306,7 @@ If picons are already displayed, remove them." (defun gnus-treat-newsgroups-picon () "Display picons in the Newsgroups and Followup-To headers. If picons are already displayed, remove them." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (let ((wash-picon-p buffer-read-only)) (gnus-with-article-buffer (if (and wash-picon-p (memq 'newsgroups-picon gnus-article-wash-types)) diff --git a/lisp/gnus/gnus-registry.el b/lisp/gnus/gnus-registry.el index 147550d8cf..9a22256113 100644 --- a/lisp/gnus/gnus-registry.el +++ b/lisp/gnus/gnus-registry.el @@ -813,7 +813,7 @@ Consults `gnus-registry-ignored-groups' and (defun gnus-registry-wash-for-keywords (&optional force) "Get the keywords of the current article. Overrides existing keywords with FORCE set non-nil." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (let ((id (gnus-registry-fetch-message-id-fast gnus-current-article)) word words) (if (or (not (gnus-registry-get-id-key id 'keyword)) @@ -1039,13 +1039,15 @@ Uses `gnus-registry-marks' to find what shortcuts to install." (defun gnus-registry-set-article-mark (&rest articles) "Apply a mark to process-marked ARTICLES." - (interactive (gnus-summary-work-articles current-prefix-arg)) + (interactive (gnus-summary-work-articles current-prefix-arg) + gnus-article-mode gnus-summary-mode) (gnus-registry-set-article-mark-internal (gnus-registry-read-mark) articles nil t)) (defun gnus-registry-remove-article-mark (&rest articles) "Remove a mark from process-marked ARTICLES." - (interactive (gnus-summary-work-articles current-prefix-arg)) + (interactive (gnus-summary-work-articles current-prefix-arg) + gnus-article-mode gnus-summary-mode) (gnus-registry-set-article-mark-internal (gnus-registry-read-mark) articles t t)) @@ -1069,7 +1071,8 @@ Uses `gnus-registry-marks' to find what shortcuts to install." "Get the Gnus registry marks for ARTICLES and show them if interactive. Uses process/prefix conventions. For multiple articles, only the last one's marks are returned." - (interactive (gnus-summary-work-articles 1)) + (interactive (gnus-summary-work-articles 1) + gnus-article-mode gnus-summary-mode) (let* ((article (last articles)) (id (gnus-registry-fetch-message-id-fast article)) (marks (when id (gnus-registry-get-id-key id 'mark)))) diff --git a/lisp/gnus/gnus-salt.el b/lisp/gnus/gnus-salt.el index e222d24b69..5b746a8efa 100644 --- a/lisp/gnus/gnus-salt.el +++ b/lisp/gnus/gnus-salt.el @@ -137,6 +137,8 @@ It accepts the same format specs that `gnus-summary-line-format' does." "Start reading the picked articles. If given a prefix, mark all unpicked articles as read." (interactive "P") + (declare (completion (lambda (s b) + (completion-minor-mode-active-p s b 'gnus-pick-mode)))) (if gnus-newsgroup-processable (progn (gnus-summary-limit-to-articles nil) @@ -462,7 +464,7 @@ Two predefined functions are available: (defun gnus-tree-read-summary-keys (&optional arg) "Read a summary buffer key sequence and execute it." - (interactive "P") + (interactive "P" gnus-tree-mode) (unless gnus-tree-inhibit (let ((buf (current-buffer)) (gnus-tree-inhibit t) @@ -477,7 +479,7 @@ Two predefined functions are available: (defun gnus-tree-show-summary () "Reconfigure windows to show summary buffer." - (interactive) + (interactive nil gnus-tree-mode) (if (not (gnus-buffer-live-p gnus-summary-buffer)) (error "There is no summary buffer for this tree buffer") (gnus-configure-windows 'article) @@ -485,7 +487,7 @@ Two predefined functions are available: (defun gnus-tree-select-article (article) "Select the article under point, if any." - (interactive (list (gnus-tree-article-number))) + (interactive (list (gnus-tree-article-number)) gnus-tree-mode) (let ((buf (current-buffer))) (when article (with-current-buffer gnus-summary-buffer @@ -494,7 +496,7 @@ Two predefined functions are available: (defun gnus-tree-pick-article (e) "Select the article under the mouse pointer." - (interactive "e") + (interactive "e" gnus-tree-mode) (mouse-set-point e) (gnus-tree-select-article (gnus-tree-article-number))) diff --git a/lisp/gnus/gnus-score.el b/lisp/gnus/gnus-score.el index ade0897a16..ce64dcef04 100644 --- a/lisp/gnus/gnus-score.el +++ b/lisp/gnus/gnus-score.el @@ -528,7 +528,8 @@ permanence, and the string to be used. The numerical prefix will be used as SCORE. A symbolic prefix of `a' (the SYMP parameter) says to use the `all.SCORE' file for the command instead of the current score file." - (interactive (gnus-interactive "P\ny")) + (interactive (gnus-interactive "P\ny") + gnus-article-mode gnus-summary-mode) (gnus-summary-increase-score (- (gnus-score-delta-default score)) symp)) (defun gnus-score-kill-help-buffer () @@ -544,7 +545,8 @@ permanence, and the string to be used. The numerical prefix will be used as SCORE. A symbolic prefix of `a' (the SYMP parameter) says to use the `all.SCORE' file for the command instead of the current score file." - (interactive (gnus-interactive "P\ny")) + (interactive (gnus-interactive "P\ny") + gnus-article-mode gnus-summary-mode) (let* ((nscore (gnus-score-delta-default score)) (prefix (if (< nscore 0) ?L ?I)) (increase (> nscore 0)) @@ -931,15 +933,16 @@ TYPE is the score type. SCORE is the score to add. EXTRA is the possible non-standard header." (interactive (list (gnus-completing-read "Header" - (mapcar + (mapcar #'car (seq-filter (lambda (x) (fboundp (nth 2 x))) gnus-header-index)) - t) + t) (read-string "Match: ") (if (y-or-n-p "Use regexp match? ") 'r 's) - (string-to-number (read-string "Score: ")))) + (string-to-number (read-string "Score: "))) + gnus-article-mode gnus-summary-mode) (save-excursion (unless (and (stringp match) (> (length match) 0)) (error "No match")) @@ -974,7 +977,8 @@ EXTRA is the possible non-standard header." "Automatically mark articles with score below SCORE as read." (interactive (list (or (and current-prefix-arg (prefix-numeric-value current-prefix-arg)) - (string-to-number (read-string "Mark below: "))))) + (string-to-number (read-string "Mark below: ")))) + gnus-article-mode gnus-summary-mode) (setq score (or score gnus-summary-default-score 0)) (gnus-score-set 'mark (list score)) (gnus-score-set 'touched '(t)) @@ -1008,14 +1012,15 @@ EXTRA is the possible non-standard header." "Automatically expunge articles with score below SCORE." (interactive (list (or (and current-prefix-arg (prefix-numeric-value current-prefix-arg)) - (string-to-number (read-string "Set expunge below: "))))) + (string-to-number (read-string "Set expunge below: ")))) + gnus-article-mode gnus-summary-mode) (setq score (or score gnus-summary-default-score 0)) (gnus-score-set 'expunge (list score)) (gnus-score-set 'touched '(t))) (defun gnus-score-followup-article (&optional score) "Add SCORE to all followups to the article in the current buffer." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (setq score (gnus-score-delta-default score)) (when (gnus-buffer-live-p gnus-summary-buffer) (save-excursion @@ -1030,7 +1035,7 @@ EXTRA is the possible non-standard header." (defun gnus-score-followup-thread (&optional score) "Add SCORE to all later articles in the thread the current buffer is part of." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (setq score (gnus-score-delta-default score)) (when (gnus-buffer-live-p gnus-summary-buffer) (save-excursion @@ -1064,13 +1069,13 @@ EXTRA is the possible non-standard header." (defun gnus-summary-raise-score (n) "Raise the score of the current article by N." - (interactive "p") + (interactive "p" gnus-article-mode gnus-summary-mode) (gnus-summary-set-score (+ (gnus-summary-article-score) (or n gnus-score-interactive-default-score )))) (defun gnus-summary-set-score (n) "Set the score of the current article to N." - (interactive "p") + (interactive "p" gnus-article-mode gnus-summary-mode) (save-excursion (gnus-summary-show-thread) (let ((buffer-read-only nil)) @@ -1089,7 +1094,7 @@ EXTRA is the possible non-standard header." (defun gnus-summary-current-score (arg) "Return the score of the current article. With prefix ARG, return the total score of the current (sub)thread." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (message "%s" (if arg (gnus-thread-total-score (gnus-id-to-thread @@ -1099,14 +1104,16 @@ EXTRA is the possible non-standard header." (defun gnus-score-change-score-file (file) "Change current score alist." (interactive - (list (read-file-name "Change to score file: " gnus-kill-files-directory))) + (list (read-file-name "Change to score file: " gnus-kill-files-directory)) + gnus-article-mode gnus-summary-mode) (gnus-score-load-file file) (gnus-set-mode-line 'summary)) (defvar gnus-score-edit-exit-function) (defun gnus-score-edit-current-scores (file) "Edit the current score alist." - (interactive (list gnus-current-score-file)) + (interactive (list gnus-current-score-file) + gnus-article-mode gnus-summary-mode) (if (not gnus-current-score-file) (error "No current score file") (let ((winconf (current-window-configuration))) @@ -2496,7 +2503,7 @@ score in `gnus-newsgroup-scored' by SCORE." (defun gnus-score-find-trace () "Find all score rules that applies to the current article." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (let ((old-scored gnus-newsgroup-scored)) (let ((gnus-newsgroup-headers (list (gnus-summary-article-header))) @@ -2611,7 +2618,7 @@ the score file and its full name, including the directory.") (defun gnus-summary-rescore () "Redo the entire scoring process in the current summary." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-score-save) (setq gnus-score-cache nil) (setq gnus-newsgroup-scored nil) @@ -2642,7 +2649,7 @@ the score file and its full name, including the directory.") (defun gnus-summary-raise-same-subject-and-select (score) "Raise articles which has the same subject with SCORE and select the next." - (interactive "p") + (interactive "p" gnus-article-mode gnus-summary-mode) (let ((subject (gnus-summary-article-subject))) (gnus-summary-raise-score score) (while (gnus-summary-find-subject subject) @@ -2651,7 +2658,7 @@ the score file and its full name, including the directory.") (defun gnus-summary-raise-same-subject (score) "Raise articles which has the same subject with SCORE." - (interactive "p") + (interactive "p" gnus-article-mode gnus-summary-mode) (let ((subject (gnus-summary-article-subject))) (gnus-summary-raise-score score) (while (gnus-summary-find-subject subject) @@ -2664,7 +2671,7 @@ the score file and its full name, including the directory.") (defun gnus-summary-raise-thread (&optional score) "Raise the score of the articles in the current thread with SCORE." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (setq score (gnus-score-delta-default score)) (let (e) (save-excursion @@ -2683,17 +2690,17 @@ the score file and its full name, including the directory.") (defun gnus-summary-lower-same-subject-and-select (score) "Raise articles which has the same subject with SCORE and select the next." - (interactive "p") + (interactive "p" gnus-article-mode gnus-summary-mode) (gnus-summary-raise-same-subject-and-select (- score))) (defun gnus-summary-lower-same-subject (score) "Raise articles which has the same subject with SCORE." - (interactive "p") + (interactive "p" gnus-article-mode gnus-summary-mode) (gnus-summary-raise-same-subject (- score))) (defun gnus-summary-lower-thread (&optional score) "Lower score of articles in the current thread with SCORE." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (gnus-summary-raise-thread (- (gnus-score-delta-default score)))) ;;; Finding score files. diff --git a/lisp/gnus/gnus-sieve.el b/lisp/gnus/gnus-sieve.el index 5dcd079fb4..eeedf7ff35 100644 --- a/lisp/gnus/gnus-sieve.el +++ b/lisp/gnus/gnus-sieve.el @@ -113,7 +113,7 @@ Return nil if no rule could be guessed." ;;;###autoload (defun gnus-sieve-article-add-rule () - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-summary-select-article nil 'force) (with-current-buffer gnus-original-article-buffer (let ((rule (gnus-sieve-guess-rule-for-article)) diff --git a/lisp/gnus/gnus-srvr.el b/lisp/gnus/gnus-srvr.el index a305e343f6..f66f8427ea 100644 --- a/lisp/gnus/gnus-srvr.el +++ b/lisp/gnus/gnus-srvr.el @@ -409,7 +409,7 @@ The following commands are available: (defun gnus-server-kill-server (server) "Kill the server on the current line." - (interactive (list (gnus-server-server-name))) + (interactive (list (gnus-server-server-name)) gnus-server-mode) (unless (gnus-server-goto-server server) (if server (error "No such server: %s" server) (error "No server on the current line"))) @@ -438,7 +438,7 @@ The following commands are available: (defun gnus-server-yank-server () "Yank the previously killed server." - (interactive) + (interactive nil gnus-server-mode) (unless gnus-server-killed-servers (error "No killed servers to be yanked")) (let ((alist gnus-server-alist) @@ -460,14 +460,14 @@ The following commands are available: (defun gnus-server-exit () "Return to the group buffer." - (interactive) + (interactive nil gnus-server-mode) (gnus-run-hooks 'gnus-server-exit-hook) (gnus-kill-buffer (current-buffer)) (gnus-configure-windows 'group t)) (defun gnus-server-list-servers () "List all available servers." - (interactive) + (interactive nil gnus-server-mode) (let ((cur (gnus-server-server-name))) (gnus-server-prepare) (if cur (gnus-server-goto-server cur) @@ -489,7 +489,7 @@ The following commands are available: (defun gnus-server-open-server (server) "Force an open of SERVER." - (interactive (list (gnus-server-server-name))) + (interactive (list (gnus-server-server-name)) gnus-server-mode) (let ((method (gnus-server-to-method server))) (unless method (error "No such server: %s" server)) @@ -501,13 +501,13 @@ The following commands are available: (defun gnus-server-open-all-servers () "Open all servers." - (interactive) + (interactive nil gnus-server-mode) (dolist (server gnus-inserted-opened-servers) (gnus-server-open-server (car server)))) (defun gnus-server-close-server (server) "Close SERVER." - (interactive (list (gnus-server-server-name))) + (interactive (list (gnus-server-server-name)) gnus-server-mode) (let ((method (gnus-server-to-method server))) (unless method (error "No such server: %s" server)) @@ -519,7 +519,7 @@ The following commands are available: (defun gnus-server-offline-server (server) "Set SERVER to offline." - (interactive (list (gnus-server-server-name))) + (interactive (list (gnus-server-server-name)) gnus-server-mode) (let ((method (gnus-server-to-method server))) (unless method (error "No such server: %s" server)) @@ -531,7 +531,7 @@ The following commands are available: (defun gnus-server-close-all-servers () "Close all servers." - (interactive) + (interactive nil gnus-server-mode) (dolist (server gnus-inserted-opened-servers) (gnus-server-close-server (car server))) (dolist (server gnus-server-alist) @@ -539,7 +539,7 @@ The following commands are available: (defun gnus-server-deny-server (server) "Make sure SERVER will never be attempted opened." - (interactive (list (gnus-server-server-name))) + (interactive (list (gnus-server-server-name)) gnus-server-mode) (let ((method (gnus-server-to-method server))) (unless method (error "No such server: %s" server)) @@ -550,7 +550,7 @@ The following commands are available: (defun gnus-server-remove-denials () "Make all denied servers into closed servers." - (interactive) + (interactive nil gnus-server-mode) (dolist (server gnus-opened-servers) (when (eq (nth 1 server) 'denied) (setcar (nthcdr 1 server) 'closed))) @@ -558,11 +558,11 @@ The following commands are available: (defun gnus-server-copy-server (from to) "Copy a server definition to a new name." - (interactive - (list - (or (gnus-server-server-name) - (error "No server on the current line")) - (read-string "Copy to: "))) + (interactive (list + (or (gnus-server-server-name) + (error "No server on the current line")) + (read-string "Copy to: ")) + gnus-server-mode) (unless from (error "No server on current line")) (unless (and to (not (string= to ""))) @@ -583,7 +583,8 @@ The following commands are available: (list (intern (gnus-completing-read "Server method" (mapcar #'car gnus-valid-select-methods) t)) - (read-string "Server name: "))) + (read-string "Server name: ")) + gnus-server-mode) (when (assq where gnus-server-alist) (error "Server with that name already defined")) (push (list where how where) gnus-server-killed-servers) @@ -593,7 +594,8 @@ The following commands are available: "Jump to a server line." (interactive (list (gnus-completing-read "Goto server" - (mapcar #'car gnus-server-alist) t))) + (mapcar #'car gnus-server-alist) t)) + gnus-server-mode) (let ((to (text-property-any (point-min) (point-max) 'gnus-server (intern server)))) (when to @@ -602,7 +604,7 @@ The following commands are available: (defun gnus-server-edit-server (server) "Edit the server on the current line." - (interactive (list (gnus-server-server-name))) + (interactive (list (gnus-server-server-name)) gnus-server-mode) (unless server (error "No server on current line")) (unless (assoc server gnus-server-alist) @@ -620,7 +622,7 @@ The following commands are available: (defun gnus-server-show-server (server) "Show the definition of the server on the current line." - (interactive (list (gnus-server-server-name))) + (interactive (list (gnus-server-server-name)) gnus-server-mode) (unless server (error "No server on current line")) (let ((info (gnus-server-to-method server))) @@ -632,7 +634,7 @@ The following commands are available: (defun gnus-server-scan-server (server) "Request a scan from the current server." - (interactive (list (gnus-server-server-name))) + (interactive (list (gnus-server-server-name)) gnus-server-mode) (let ((method (gnus-server-to-method server))) (if (not (gnus-get-function method 'request-scan)) (error "Server %s can't scan" (car method)) @@ -897,7 +899,7 @@ buffer. (defun gnus-browse-read-group (&optional no-article number) "Enter the group at the current line. If NUMBER, fetch this number of articles." - (interactive "P") + (interactive "P" gnus-browse-mode) (let* ((full-name (gnus-browse-group-name)) (group (if (gnus-native-method-p (gnus-find-method-for-group full-name)) @@ -916,26 +918,26 @@ If NUMBER, fetch this number of articles." (defun gnus-browse-select-group (&optional number) "Select the current group. If NUMBER, fetch this number of articles." - (interactive "P") + (interactive "P" gnus-browse-mode) (gnus-browse-read-group 'no number)) (defun gnus-browse-next-group (n) "Go to the next group." - (interactive "p") + (interactive "p" gnus-browse-mode) (prog1 (forward-line n) (gnus-group-position-point))) (defun gnus-browse-prev-group (n) "Go to the next group." - (interactive "p") + (interactive "p" gnus-browse-mode) (gnus-browse-next-group (- n))) (defun gnus-browse-unsubscribe-current-group (arg) "(Un)subscribe to the next ARG groups. The variable `gnus-browse-subscribe-newsgroup-method' determines how new groups will be entered into the group buffer." - (interactive "p") + (interactive "p" gnus-browse-mode) (when (eobp) (error "No group at current line")) (let ((ward (if (< arg 0) -1 1)) @@ -961,7 +963,7 @@ how new groups will be entered into the group buffer." (defun gnus-browse-describe-group (group) "Describe the current group." - (interactive (list (gnus-browse-group-name))) + (interactive (list (gnus-browse-group-name)) gnus-browse-mode) (gnus-group-describe-group nil group)) (defun gnus-browse-delete-group (group force) @@ -970,8 +972,8 @@ If FORCE (the prefix) is non-nil, all the articles in the group will be deleted. This is \"deleted\" as in \"removed forever from the face of the Earth\". There is no undo. The user will be prompted before doing the deletion." - (interactive (list (gnus-browse-group-name) - current-prefix-arg)) + (interactive (list (gnus-browse-group-name) current-prefix-arg) + gnus-browse-mode) (gnus-group-delete-group group force)) (defun gnus-browse-unsubscribe-group () @@ -1020,7 +1022,7 @@ doing the deletion." (defun gnus-browse-exit () "Quit browsing and return to the group buffer." - (interactive) + (interactive nil gnus-browse-mode) (when (derived-mode-p 'gnus-browse-mode) (gnus-kill-buffer (current-buffer))) ;; Insert the newly subscribed groups in the group buffer. @@ -1032,7 +1034,7 @@ doing the deletion." (defun gnus-browse-describe-briefly () "Give a one line description of the group mode commands." - (interactive) + (interactive nil gnus-browse-mode) (gnus-message 6 "%s" (substitute-command-keys "\\\\[gnus-group-next-group]:Forward \\[gnus-group-prev-group]:Backward \\[gnus-browse-exit]:Exit \\[gnus-info-find-node]:Run Info \\[gnus-browse-describe-briefly]:This help"))) @@ -1089,7 +1091,7 @@ Requesting compaction of %s... (this may take a long time)" (defun gnus-server-toggle-cloud-server () "Toggle whether the server under point is replicated in the Emacs Cloud." - (interactive) + (interactive nil gnus-server-mode) (let ((server (gnus-server-server-name))) (unless server (error "No server on the current line")) @@ -1110,7 +1112,7 @@ Requesting compaction of %s... (this may take a long time)" (defun gnus-server-set-cloud-method-server () "Set the server under point to host the Emacs Cloud." - (interactive) + (interactive nil gnus-server-mode) (let ((server (gnus-server-server-name))) (unless server (error "No server on the current line")) diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el index 1554635a3f..a3112bdd9f 100644 --- a/lisp/gnus/gnus-start.el +++ b/lisp/gnus/gnus-start.el @@ -1070,7 +1070,7 @@ With 1 C-u, use the `ask-server' method to query the server for new groups. With 2 C-u's, use most complete method possible to query the server for new groups, and subscribe the new groups as zombies." - (interactive "p") + (interactive "p" gnus-group-mode) (let* ((gnus-subscribe-newsgroup-method gnus-subscribe-newsgroup-method) (check (cond @@ -1405,7 +1405,7 @@ newsgroup." (defun gnus-check-duplicate-killed-groups () "Remove duplicates from the list of killed groups." - (interactive) + (interactive nil gnus-group-mode) (let ((killed gnus-killed-list)) (while killed (gnus-message 9 "%d" (length killed)) diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index 456e7b0f8c..4065cf0834 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -73,18 +73,10 @@ (eval-when-compile (require 'subr-x)) -(autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t) +(autoload 'gnus-summary-limit-include-cached "gnus-cache" nil + '(gnus-summary-mode)) (autoload 'gnus-cache-write-active "gnus-cache") -(autoload 'gnus-mailing-list-insinuate "gnus-ml" nil t) -(autoload 'turn-on-gnus-mailing-list-mode "gnus-ml" nil t) (autoload 'gnus-pick-line-number "gnus-salt" nil t) -(autoload 'mm-uu-dissect "mm-uu") -(autoload 'gnus-article-outlook-deuglify-article "deuglify" - "Deuglify broken Outlook (Express) articles and redisplay." - t) -(autoload 'gnus-article-outlook-unwrap-lines "deuglify" nil t) -(autoload 'gnus-article-outlook-repair-attribution "deuglify" nil t) -(autoload 'gnus-article-outlook-rearrange-citation "deuglify" nil t) (autoload 'nnselect-article-rsv "nnselect" nil nil) (autoload 'nnselect-article-group "nnselect" nil nil) (autoload 'gnus-nnselect-group-p "nnselect" nil nil) @@ -2525,6 +2517,7 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs)))) (let ((gnus-summary-show-article-charset-alist `((1 . ,cs)))) (gnus-summary-show-article 1)))) + (put command 'completion-predicate 'ignore) `[,(symbol-name cs) ,command t])) (sort (coding-system-list) #'string<))))) ("Washing" @@ -3149,6 +3142,7 @@ buffer; read the Info manual for more information (`\\[gnus-info-find-node]'). The following commands are available: \\{gnus-summary-mode-map}" + :interactive nil (let ((gnus-summary-local-variables gnus-newsgroup-variables)) (gnus-summary-make-local-variables)) (gnus-summary-make-local-variables) @@ -3479,7 +3473,7 @@ marks of articles." ;; Various summary mode internalish functions. (defun gnus-mouse-pick-article (e) - (interactive "e") + (interactive "e" gnus-summary-mode) (mouse-set-point e) (gnus-summary-next-page nil t)) @@ -4219,7 +4213,7 @@ If SELECT-ARTICLES, only select those articles from GROUP." (defun gnus-summary-prepare () "Generate the summary buffer." - (interactive) + (interactive nil gnus-summary-mode) (let ((inhibit-read-only t)) (erase-buffer) (setq gnus-newsgroup-data nil @@ -4268,7 +4262,7 @@ If SELECT-ARTICLES, only select those articles from GROUP." (defun gnus-summary-simplify-subject-query () "Query where the respool algorithm would put this article." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-select-article) (message "%s" (gnus-general-simplify-subject (gnus-summary-article-subject)))) @@ -6671,19 +6665,19 @@ executed with point over the summary line of the articles." (defun gnus-summary-save-process-mark () "Push the current set of process marked articles on the stack." - (interactive) + (interactive nil gnus-summary-mode) (push (copy-sequence gnus-newsgroup-processable) gnus-newsgroup-process-stack)) (defun gnus-summary-kill-process-mark () "Push the current set of process marked articles on the stack and unmark." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-save-process-mark) (gnus-summary-unmark-all-processable)) (defun gnus-summary-yank-process-mark () "Pop the last process mark state off the stack and restore it." - (interactive) + (interactive nil gnus-summary-mode) (unless gnus-newsgroup-process-stack (error "Empty mark stack")) (gnus-summary-process-mark-set (pop gnus-newsgroup-process-stack))) @@ -6818,7 +6812,7 @@ articles with that subject. If BACKWARD, search backward instead." (defun gnus-recenter (&optional n) "Center point in window and redisplay frame. Also do horizontal recentering." - (interactive "P") + (interactive "P" gnus-summary-mode) (when (and gnus-auto-center-summary (not (eq gnus-auto-center-summary 'vertical))) (gnus-horizontal-recenter)) @@ -6852,7 +6846,7 @@ If `gnus-auto-center-summary' is nil, or the article buffer isn't displayed, no centering will be performed." ;; Suggested by earle@mahendo.JPL.NASA.GOV (Greg Earle). ;; Recenter only when requested. Suggested by popovich@park.cs.columbia.edu. - (interactive) + (interactive nil gnus-summary-mode) ;; The user has to want it. (when gnus-auto-center-summary (let* ((top (cond ((< (window-height) 4) 0) @@ -7029,7 +7023,7 @@ displayed, no centering will be performed." "Reconfigure windows to show the article buffer. If `gnus-widen-article-window' is set, show only the article buffer." - (interactive) + (interactive nil gnus-summary-mode) (if (not (gnus-buffer-live-p gnus-article-buffer)) (error "There is no article buffer for this summary buffer") (or (get-buffer-window gnus-article-buffer) @@ -7052,7 +7046,7 @@ buffer." (defun gnus-summary-universal-argument (arg) "Perform any operation on all articles that are process/prefixed." - (interactive "P") + (interactive "P" gnus-summary-mode) (let ((articles (gnus-summary-work-articles arg)) func article) (if (eq @@ -7073,7 +7067,7 @@ buffer." (gnus-summary-position-point)) (define-obsolete-function-alias - 'gnus-summary-toggle-truncation #'toggle-truncate-lines "26.1") + 'gnus-summary-toggle-truncation #'toggle-truncate-lines "26.1") (defun gnus-summary-find-for-reselect () "Return the number of an article to stay on across a reselect. @@ -7095,7 +7089,7 @@ insertion from another group. If there's no such then return a dummy 0." (defun gnus-summary-reselect-current-group (&optional all rescan) "Exit and then reselect the current newsgroup. The prefix argument ALL means to select all articles." - (interactive "P") + (interactive "P" gnus-summary-mode) (when (gnus-ephemeral-group-p gnus-newsgroup-name) (error "Ephemeral groups can't be reselected")) (let ((current-subject (gnus-summary-find-for-reselect)) @@ -7113,7 +7107,7 @@ The prefix argument ALL means to select all articles." (defun gnus-summary-rescan-group (&optional all) "Exit the newsgroup, ask for new articles, and select the newsgroup." - (interactive "P") + (interactive "P" gnus-summary-mode) (let ((config gnus-current-window-configuration)) (gnus-summary-reselect-current-group all t) (gnus-configure-windows config) @@ -7168,7 +7162,7 @@ The prefix argument ALL means to select all articles." (defun gnus-summary-make-group-from-search () "Make a persistent group from the current ephemeral search group." - (interactive) + (interactive nil gnus-summary-mode) (if (not (gnus-nnselect-group-p gnus-newsgroup-name)) (gnus-message 3 "%s is not a search group" gnus-newsgroup-name) (let ((name (gnus-read-group "Group name: "))) @@ -7185,7 +7179,7 @@ The prefix argument ALL means to select all articles." "Save the current number of read/marked articles in the dribble buffer. The dribble buffer will then be saved. If FORCE (the prefix), also save the .newsrc file(s)." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-update-info t) (if force (gnus-save-newsrc-file) @@ -7197,7 +7191,7 @@ If FORCE (the prefix), also save the .newsrc file(s)." (defun gnus-summary-exit (&optional temporary leave-hidden) "Exit reading current newsgroup, and then return to group selection mode. `gnus-exit-group-hook' is called with no arguments if that value is non-nil." - (interactive) + (interactive nil gnus-summary-mode) (gnus-set-global-variables) (when (gnus-buffer-live-p gnus-article-buffer) (with-current-buffer gnus-article-buffer @@ -7303,7 +7297,7 @@ If FORCE (the prefix), also save the .newsrc file(s)." (defalias 'gnus-summary-quit 'gnus-summary-exit-no-update) (defun gnus-summary-exit-no-update (&optional no-questions) "Quit reading current newsgroup without updating read article info." - (interactive) + (interactive nil gnus-summary-mode) (let* ((group gnus-newsgroup-name) (gnus-group-is-exiting-p t) (gnus-group-is-exiting-without-update-p t) @@ -7457,7 +7451,7 @@ The state which existed when entering the ephemeral is reset." (defun gnus-summary-wake-up-the-dead (&rest _) "Wake up the dead summary buffer." - (interactive) + (interactive nil gnus-summary-mode) (gnus-dead-summary-mode -1) (let ((name (buffer-name))) (when (string-match "Dead " name) @@ -7470,12 +7464,12 @@ The state which existed when entering the ephemeral is reset." ;; Suggested by Per Abrahamsen . (defun gnus-summary-describe-group (&optional force) "Describe the current newsgroup." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-group-describe-group force gnus-newsgroup-name)) (defun gnus-summary-describe-briefly () "Describe summary mode commands briefly." - (interactive) + (interactive nil gnus-summary-mode) (gnus-message 6 "%s" (substitute-command-keys "\\\\[gnus-summary-next-page]:Select \\[gnus-summary-next-unread-article]:Forward \\[gnus-summary-prev-unread-article]:Backward \\[gnus-summary-exit]:Exit \\[gnus-info-find-node]:Run Info \\[gnus-summary-describe-briefly]:This help"))) ;; Walking around group mode buffer from summary mode. @@ -7485,7 +7479,7 @@ The state which existed when entering the ephemeral is reset." If prefix argument NO-ARTICLE is non-nil, no article is selected initially. If TARGET-GROUP, go to this group. If BACKWARD, go to previous group instead." - (interactive "P") + (interactive "P" gnus-summary-mode) ;; Stop pre-fetching. (gnus-async-halt-prefetch) (let ((current-group gnus-newsgroup-name) @@ -7531,7 +7525,7 @@ previous group instead." (defun gnus-summary-prev-group (&optional no-article) "Exit current newsgroup and then select previous unread newsgroup. If prefix argument NO-ARTICLE is non-nil, no article is selected initially." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-next-group no-article nil t)) ;; Walking around summary lines. @@ -7542,7 +7536,7 @@ If UNREAD is non-nil, the article should be unread. If UNDOWNLOADED is non-nil, the article should be undownloaded. If UNSEEN is non-nil, the article should be unseen as well as unread. Returns the article selected or nil if there are no matching articles." - (interactive "P") + (interactive "P" gnus-summary-mode) (cond ;; Empty summary. ((null gnus-newsgroup-data) @@ -7594,7 +7588,7 @@ If N is negative, go to the previous N'th subject line. If UNREAD is non-nil, only unread articles are selected. The difference between N and the actual number of steps taken is returned." - (interactive "p") + (interactive "p" gnus-summary-mode) (let ((backward (< n 0)) (n (abs n))) (while (and (> n 0) @@ -7613,18 +7607,18 @@ returned." (defun gnus-summary-next-unread-subject (n) "Go to next N'th unread summary line." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-next-subject n t)) (defun gnus-summary-prev-subject (n &optional unread) "Go to previous N'th summary line. If optional argument UNREAD is non-nil, only unread article is selected." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-next-subject (- n) unread)) (defun gnus-summary-prev-unread-subject (n) "Go to previous N'th unread summary line." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-next-subject (- n) t)) (defun gnus-summary-goto-subjects (articles) @@ -7638,7 +7632,7 @@ If optional argument UNREAD is non-nil, only unread article is selected." (defun gnus-summary-goto-subject (article &optional force silent) "Go to the subject line of ARTICLE. If FORCE, also allow jumping to articles not currently shown." - (interactive "nArticle number: ") + (interactive "nArticle number: " gnus-summary-mode) (unless (numberp article) (error "Article %s is not a number" article)) (let ((b (point)) @@ -7668,7 +7662,7 @@ If FORCE, also allow jumping to articles not currently shown." (defun gnus-summary-expand-window (&optional arg) "Make the summary buffer take up the entire Emacs frame. Given a prefix, will force an `article' buffer configuration." - (interactive "P") + (interactive "P" gnus-summary-mode) (if arg (gnus-configure-windows 'article 'force) (gnus-configure-windows 'summary 'force))) @@ -7751,7 +7745,7 @@ be displayed." (defun gnus-summary-force-verify-and-decrypt () "Display buttons for signed/encrypted parts and verify/decrypt them." - (interactive) + (interactive nil gnus-summary-mode) (let ((mm-verify-option 'known) (mm-decrypt-option 'known) (gnus-article-emulate-mime t) @@ -7765,7 +7759,7 @@ be displayed." If UNREAD, only unread articles are selected. If SUBJECT, only articles with SUBJECT are selected. If BACKWARD, the previous article is selected instead of the next." - (interactive "P") + (interactive "P" gnus-summary-mode) ;; Make sure we are in the summary buffer. (unless (derived-mode-p 'gnus-summary-mode) (set-buffer gnus-summary-buffer)) @@ -7877,7 +7871,7 @@ If BACKWARD, the previous article is selected instead of the next." (defun gnus-summary-next-unread-article () "Select unread article after current one." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-next-article (or (not (eq gnus-summary-goto-unread 'never)) (gnus-summary-last-article-p (gnus-summary-article-number))) @@ -7887,12 +7881,12 @@ If BACKWARD, the previous article is selected instead of the next." (defun gnus-summary-prev-article (&optional unread subject) "Select the article before the current one. If UNREAD is non-nil, only unread articles are selected." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-next-article unread subject t)) (defun gnus-summary-prev-unread-article () "Select unread article before current one." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-prev-article (or (not (eq gnus-summary-goto-unread 'never)) (gnus-summary-first-article-p (gnus-summary-article-number))) @@ -7913,7 +7907,7 @@ article. If STOP is non-nil, just stop when reaching the end of the message. Also see the variable `gnus-article-skip-boring'." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-set-global-variables) (let ((article (gnus-summary-article-number)) (article-window (get-buffer-window gnus-article-buffer t)) @@ -7958,7 +7952,7 @@ Also see the variable `gnus-article-skip-boring'." Argument LINES specifies lines to be scrolled down. If MOVE, move to the previous unread article if point is at the beginning of the buffer." - (interactive "P") + (interactive "P" gnus-summary-mode) (let ((article (gnus-summary-article-number)) (article-window (get-buffer-window gnus-article-buffer t)) endp) @@ -7988,14 +7982,14 @@ the beginning of the buffer." "Show previous page of selected article. Argument LINES specifies lines to be scrolled down. If at the beginning of the article, go to the next article." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-prev-page lines t)) (defun gnus-summary-scroll-up (lines) "Scroll up (or down) one line current article. Argument LINES specifies lines to be scrolled up (or down if negative). If no article is selected, then the current article will be selected first." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-configure-windows 'article) (gnus-summary-show-thread) (when (eq (gnus-summary-select-article nil nil 'pseudo) 'old) @@ -8012,33 +8006,33 @@ If no article is selected, then the current article will be selected first." "Scroll down (or up) one line current article. Argument LINES specifies lines to be scrolled down (or up if negative). If no article is selected, then the current article will be selected first." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-scroll-up (- lines))) (defun gnus-summary-next-same-subject () "Select next article which has the same subject as current one." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-next-article nil (gnus-summary-article-subject))) (defun gnus-summary-prev-same-subject () "Select previous article which has the same subject as current one." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-prev-article nil (gnus-summary-article-subject))) (defun gnus-summary-next-unread-same-subject () "Select next unread article which has the same subject as current one." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-next-article t (gnus-summary-article-subject))) (defun gnus-summary-prev-unread-same-subject () "Select previous unread article which has the same subject as current one." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-prev-article t (gnus-summary-article-subject))) (defun gnus-summary-first-unread-article () "Select the first unread article. Return nil if there are no unread articles." - (interactive) + (interactive nil gnus-summary-mode) (prog1 (when (gnus-summary-first-subject t) (gnus-summary-show-thread) @@ -8049,7 +8043,7 @@ Return nil if there are no unread articles." (defun gnus-summary-first-unread-subject () "Place the point on the subject line of the first unread article. Return nil if there are no unread articles." - (interactive) + (interactive nil gnus-summary-mode) (prog1 (when (gnus-summary-first-subject t) (gnus-summary-show-thread) @@ -8058,7 +8052,7 @@ Return nil if there are no unread articles." (defun gnus-summary-next-unseen-article (&optional backward) "Select the next unseen article." - (interactive) + (interactive nil gnus-summary-mode) (let* ((article (gnus-summary-article-number)) (articles (gnus-data-find-list article (gnus-data-list backward)))) (when (or (not gnus-summary-check-current) @@ -8079,13 +8073,13 @@ Return nil if there are no unread articles." (defun gnus-summary-prev-unseen-article () "Select the previous unseen article." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-next-unseen-article t)) (defun gnus-summary-first-unseen-subject () "Place the point on the subject line of the first unseen article. Return nil if there are no unseen articles." - (interactive) + (interactive nil gnus-summary-mode) (prog1 (when (gnus-summary-first-subject nil nil t) (gnus-summary-show-thread) @@ -8096,7 +8090,7 @@ Return nil if there are no unseen articles." "Place the point on the subject line of the first unseen and unread article. If all article have been seen, on the subject line of the first unread article." - (interactive) + (interactive nil gnus-summary-mode) (prog1 (unless (when (gnus-summary-first-subject nil nil t) (gnus-summary-show-thread) @@ -8109,7 +8103,7 @@ article." (defun gnus-summary-first-article () "Select the first article. Return nil if there are no articles." - (interactive) + (interactive nil gnus-summary-mode) (prog1 (when (gnus-summary-first-subject) (gnus-summary-show-thread) @@ -8121,7 +8115,7 @@ Return nil if there are no articles." "Select the unread article with the highest score. If given a prefix argument, select the next unread article that has a score higher than the default score." - (interactive "P") + (interactive "P" gnus-summary-mode) (let ((article (if arg (gnus-summary-better-unread-subject) (gnus-summary-best-unread-subject)))) @@ -8131,7 +8125,7 @@ score higher than the default score." (defun gnus-summary-best-unread-subject () "Select the unread subject with the highest score." - (interactive) + (interactive nil gnus-summary-mode) (let ((best -1000000) (data gnus-newsgroup-data) article score) @@ -8150,7 +8144,7 @@ score higher than the default score." (defun gnus-summary-better-unread-subject () "Select the first unread subject that has a score over the default score." - (interactive) + (interactive nil gnus-summary-mode) (let ((data gnus-newsgroup-data) article) (while (and (setq article (gnus-data-number (car data))) @@ -8176,11 +8170,10 @@ If FORCE, go to the article even if it isn't displayed. If FORCE is a number, it is the line the article is to be displayed on." (interactive (list - (gnus-completing-read - "Article number or Message-ID" - (mapcar #'int-to-string gnus-newsgroup-limit)) - current-prefix-arg - t)) + (gnus-completing-read "Article number or Message-ID" + (mapcar #'int-to-string gnus-newsgroup-limit)) + current-prefix-arg t) + gnus-summary-mode) (prog1 (if (and (stringp article) (string-match "@\\|%40" article)) @@ -8194,7 +8187,7 @@ is a number, it is the line the article is to be displayed on." (defun gnus-summary-goto-last-article () "Go to the previously read article." - (interactive) + (interactive nil gnus-summary-mode) (prog1 (when gnus-last-article (gnus-summary-goto-article gnus-last-article nil t)) @@ -8203,7 +8196,7 @@ is a number, it is the line the article is to be displayed on." (defun gnus-summary-pop-article (number) "Pop one article off the history and go to the previous. NUMBER articles will be popped off." - (interactive "p") + (interactive "p" gnus-summary-mode) (let (to) (setq gnus-newsgroup-history (cdr (setq to (nthcdr number gnus-newsgroup-history)))) @@ -8217,7 +8210,7 @@ NUMBER articles will be popped off." (defun gnus-summary-limit-to-articles (n) "Limit the summary buffer to the next N articles. If not given a prefix, use the process marked articles instead." - (interactive "P") + (interactive "P" gnus-summary-mode) (prog1 (let ((articles (gnus-summary-work-articles n))) (setq gnus-newsgroup-processable nil) @@ -8227,7 +8220,7 @@ If not given a prefix, use the process marked articles instead." (defun gnus-summary-pop-limit (&optional total) "Restore the previous limit. If given a prefix, remove all limits." - (interactive "P") + (interactive "P" gnus-summary-mode) (when total (setq gnus-newsgroup-limits (list (mapcar #'mail-header-number gnus-newsgroup-headers)))) @@ -8241,10 +8234,11 @@ If given a prefix, remove all limits." "Limit the summary buffer to articles that have subjects that match a regexp. If NOT-MATCHING, excluding articles that have subjects that match a regexp." (interactive - (list (read-string (if current-prefix-arg - "Exclude subject (regexp): " - "Limit to subject (regexp): ")) - nil current-prefix-arg)) + (list + (read-string + (if current-prefix-arg "Exclude subject (regexp): " "Limit to subject (regexp): ")) + nil current-prefix-arg) + gnus-summary-mode) (unless header (setq header "subject")) (when (not (equal "" subject)) @@ -8261,18 +8255,25 @@ If NOT-MATCHING, excluding articles that have subjects that match a regexp." "Limit the summary buffer to articles that have authors that match a regexp. If NOT-MATCHING, excluding articles that have authors that match a regexp." (interactive - (list (let* ((header (gnus-summary-article-header)) - (default (and header (car (mail-header-parse-address - (mail-header-from header)))))) - (read-string (concat (if current-prefix-arg - "Exclude author (regexp" - "Limit to author (regexp") - (if default - (concat ", default \"" default "\"): ") - "): ")) - nil nil - default)) - current-prefix-arg)) + (list + (let* + ((header + (gnus-summary-article-header)) + (default + (and header + (car + (mail-header-parse-address + (mail-header-from header)))))) + (read-string + (concat + (if current-prefix-arg + "Exclude author (regexp" "Limit to author (regexp") + (if default + (concat ", default \"" default "\"): ") + "): ")) + nil nil default)) + current-prefix-arg) + gnus-summary-mode) (gnus-summary-limit-to-subject from "from" not-matching)) (defun gnus-summary-limit-to-recipient (recipient &optional not-matching) @@ -8284,9 +8285,12 @@ To and Cc headers are checked. You need to include them in `nnmail-extra-headers'." ;; Unlike `rmail-summary-by-recipients', doesn't include From. (interactive - (list (read-string (format "%s recipient (regexp): " - (if current-prefix-arg "Exclude" "Limit to"))) - current-prefix-arg)) + (list + (read-string + (format "%s recipient (regexp): " + (if current-prefix-arg "Exclude" "Limit to"))) + current-prefix-arg) + gnus-summary-mode) (when (not (equal "" recipient)) (prog1 (let* ((to (if (memq 'To nnmail-extra-headers) @@ -8326,9 +8330,12 @@ If NOT-MATCHING, exclude ADDRESS. To, Cc and From headers are checked. You need to include `To' and `Cc' in `nnmail-extra-headers'." (interactive - (list (read-string (format "%s address (regexp): " - (if current-prefix-arg "Exclude" "Limit to"))) - current-prefix-arg)) + (list + (read-string + (format "%s address (regexp): " + (if current-prefix-arg "Exclude" "Limit to"))) + current-prefix-arg) + gnus-summary-mode) (when (not (equal "" address)) (prog1 (let* ((to (if (memq 'To nnmail-extra-headers) @@ -8415,7 +8422,8 @@ articles that are younger than AGE days." (setq days (* days -1)))) (message "Please enter a number.") (sleep-for 1))) - (list days younger))) + (list days younger)) + gnus-summary-mode) (prog1 (let ((data gnus-newsgroup-data) (cutoff (days-to-time age)) @@ -8439,17 +8447,18 @@ articles that are younger than AGE days." (let ((header (intern (gnus-completing-read - (if current-prefix-arg - "Exclude extra header" - "Limit extra header") + (if current-prefix-arg "Exclude extra header" "Limit extra header") (mapcar #'symbol-name gnus-extra-headers) t nil nil - (symbol-name (car gnus-extra-headers)))))) + (symbol-name + (car gnus-extra-headers)))))) (list header - (read-string (format "%s header %s (regexp): " - (if current-prefix-arg "Exclude" "Limit to") - header)) - current-prefix-arg))) + (read-string + (format "%s header %s (regexp): " + (if current-prefix-arg "Exclude" "Limit to") + header)) + current-prefix-arg)) + gnus-summary-mode) (when (not (equal "" regexp)) (prog1 (let ((articles (gnus-summary-find-matching @@ -8462,7 +8471,7 @@ articles that are younger than AGE days." (defun gnus-summary-limit-to-display-predicate () "Limit the summary buffer to the predicated in the `display' group parameter." - (interactive) + (interactive nil gnus-summary-mode) (unless gnus-newsgroup-display (error "There is no `display' group parameter")) (let (articles) @@ -8475,7 +8484,7 @@ articles that are younger than AGE days." (defun gnus-summary-limit-to-unread (&optional all) "Limit the summary buffer to articles that are not marked as read. If ALL is non-nil, limit strictly to unread articles." - (interactive "P") + (interactive "P" gnus-summary-mode) (if all (gnus-summary-limit-to-marks (char-to-string gnus-unread-mark)) (gnus-summary-limit-to-marks @@ -8491,7 +8500,7 @@ If ALL is non-nil, limit strictly to unread articles." (defun gnus-summary-limit-to-headers (match &optional reverse) "Limit the summary buffer to articles that have headers that match MATCH. If REVERSE (the prefix), limit to articles that don't match." - (interactive "sMatch headers (regexp): \nP") + (interactive "sMatch headers (regexp): \nP" gnus-summary-mode) (gnus-summary-limit-to-bodies match reverse t)) (declare-function article-goto-body "gnus-art" ()) @@ -8499,7 +8508,7 @@ If REVERSE (the prefix), limit to articles that don't match." (defun gnus-summary-limit-to-bodies (match &optional reverse headersp) "Limit the summary buffer to articles that have bodies that match MATCH. If REVERSE (the prefix), limit to articles that don't match." - (interactive "sMatch body (regexp): \nP") + (interactive "sMatch body (regexp): \nP" gnus-summary-mode) (let ((articles nil) (gnus-select-article-hook nil) ;Disable hook. (gnus-article-prepare-hook nil) @@ -8532,7 +8541,7 @@ If REVERSE (the prefix), limit to articles that don't match." (defun gnus-summary-limit-to-singletons (&optional threadsp) "Limit the summary buffer to articles that aren't part on any thread. If THREADSP (the prefix), limit to articles that are in threads." - (interactive "P") + (interactive "P" gnus-summary-mode) (let ((articles nil) thread-articles threads) @@ -8556,7 +8565,7 @@ If THREADSP (the prefix), limit to articles that are in threads." (defun gnus-summary-limit-to-replied (&optional unreplied) "Limit the summary buffer to replied articles. If UNREPLIED (the prefix), limit to unreplied articles." - (interactive "P") + (interactive "P" gnus-summary-mode) (if unreplied (gnus-summary-limit (gnus-set-difference gnus-newsgroup-articles @@ -8569,7 +8578,7 @@ If UNREPLIED (the prefix), limit to unreplied articles." If REVERSE, limit the summary buffer to articles that are marked with MARKS. MARKS can either be a string of marks or a list of marks. Returns how many articles were removed." - (interactive "sMarks: ") + (interactive "sMarks: " gnus-summary-mode) (gnus-summary-limit-to-marks marks t)) (defun gnus-summary-limit-to-marks (marks &optional reverse) @@ -8578,7 +8587,7 @@ If REVERSE (the prefix), limit the summary buffer to articles that are not marked with MARKS. MARKS can either be a string of marks or a list of marks. Returns how many articles were removed." - (interactive "sMarks: \nP") + (interactive "sMarks: \nP" gnus-summary-mode) (prog1 (let ((data gnus-newsgroup-data) (marks (if (listp marks) marks @@ -8597,10 +8606,13 @@ Returns how many articles were removed." With a prefix argument, limit to articles with score at or below SCORE." - (interactive (list (string-to-number - (read-string - (format "Limit to articles with score of at %s: " - (if current-prefix-arg "most" "least")))))) + (interactive + (list + (string-to-number + (read-string + (format "Limit to articles with score of at %s: " + (if current-prefix-arg "most" "least"))))) + gnus-summary-mode) (let ((data gnus-newsgroup-data) (compare (if (or below current-prefix-arg) #'<= #'>=)) articles) @@ -8616,7 +8628,7 @@ SCORE." (defun gnus-summary-limit-to-unseen () "Limit to unseen articles." - (interactive) + (interactive nil gnus-summary-mode) (prog1 (gnus-summary-limit gnus-newsgroup-unseen) (gnus-summary-position-point))) @@ -8626,8 +8638,12 @@ SCORE." When called interactively, ID is the Message-ID of the current article. If thread-only is non-nil limit the summary buffer to these articles." - (interactive (list (mail-header-id (gnus-summary-article-header)) - current-prefix-arg)) + (interactive + (list + (mail-header-id + (gnus-summary-article-header)) + current-prefix-arg) + gnus-summary-mode) (let ((articles (gnus-articles-in-thread (gnus-id-to-thread (gnus-root-id id)))) ;;we REALLY want the whole thread---this prevents cut-threads @@ -8653,8 +8669,11 @@ these articles." (defun gnus-summary-limit-include-matching-articles (header regexp) "Display all the hidden articles that have HEADERs that match REGEXP." - (interactive (list (read-string "Match on header: ") - (read-string "Regexp: "))) + (interactive + (list + (read-string "Match on header: ") + (read-string "Regexp: ")) + gnus-summary-mode) (let ((articles (gnus-find-matching-articles header regexp))) (prog1 (gnus-summary-limit (nconc articles gnus-newsgroup-limit)) @@ -8662,7 +8681,7 @@ these articles." (defun gnus-summary-insert-dormant-articles () "Insert all the dormant articles for this group into the current buffer." - (interactive) + (interactive nil gnus-summary-mode) (let ((gnus-verbose (max 6 gnus-verbose))) (if (not gnus-newsgroup-dormant) (gnus-message 3 "No dormant articles for this group") @@ -8670,7 +8689,7 @@ these articles." (defun gnus-summary-insert-ticked-articles () "Insert ticked articles for this group into the current buffer." - (interactive) + (interactive nil gnus-summary-mode) (let ((gnus-verbose (max 6 gnus-verbose))) (if (not gnus-newsgroup-marked) (gnus-message 3 "No ticked articles for this group") @@ -8680,7 +8699,7 @@ these articles." "Display all the hidden articles that are marked as dormant. Note that this command only works on a subset of the articles currently fetched for this group." - (interactive) + (interactive nil gnus-summary-mode) (unless gnus-newsgroup-dormant (error "There are no dormant articles in this group")) (prog1 @@ -8703,14 +8722,14 @@ fetched for this group." (defun gnus-summary-limit-exclude-dormant () "Hide all dormant articles." - (interactive) + (interactive nil gnus-summary-mode) (prog1 (gnus-summary-limit-to-marks (list gnus-dormant-mark) 'reverse) (gnus-summary-position-point))) (defun gnus-summary-limit-exclude-childless-dormant () "Hide all dormant articles that have no children." - (interactive) + (interactive nil gnus-summary-mode) (let ((data (gnus-data-list t)) articles d children) ;; Find all articles that are either not dormant or have @@ -8735,7 +8754,7 @@ fetched for this group." (defun gnus-summary-limit-mark-excluded-as-read (&optional all) "Mark all unread excluded articles as read. If ALL, mark even excluded ticked and dormants as read." - (interactive "P") + (interactive "P" gnus-summary-mode) (setq gnus-newsgroup-limit (sort gnus-newsgroup-limit #'<)) (let ((articles (gnus-sorted-ndifference (sort @@ -8974,7 +8993,7 @@ fetch-old-headers verbiage, and so on." "Refer parent article N times. If N is negative, go to ancestor -N instead. The difference between N and the number of articles fetched is returned." - (interactive "p") + (interactive "p" gnus-summary-mode) (let ((skip 1) error header ref) (when (not (natnump n)) @@ -9016,7 +9035,7 @@ The difference between N and the number of articles fetched is returned." (defun gnus-summary-refer-references () "Fetch all articles mentioned in the References header. Return the number of articles fetched." - (interactive) + (interactive nil gnus-summary-mode) (let ((ref (mail-header-references (gnus-summary-article-header))) (current (gnus-summary-article-number)) (n 0)) @@ -9059,7 +9078,7 @@ has the reverse meaning. If no backend-specific `request-thread' function is available fetch LIMIT (the numerical prefix) old headers. If LIMIT is non-numeric or nil fetch the number specified by the `gnus-refer-thread-limit' variable." - (interactive "P") + (interactive "P" gnus-summary-mode) (let* ((header (gnus-summary-article-header)) (id (mail-header-id header)) (gnus-inhibit-demon t) @@ -9114,7 +9133,7 @@ specified by the `gnus-refer-thread-limit' variable." (defun gnus-summary-open-group-with-article (message-id) "Open a group containing the article with the given MESSAGE-ID." - (interactive "sMessage-ID: ") + (interactive "sMessage-ID: " gnus-summary-mode) (require 'nndoc) (with-temp-buffer ;; Prepare a dummy article @@ -9149,7 +9168,7 @@ specified by the `gnus-refer-thread-limit' variable." (defun gnus-summary-refer-article (message-id) "Fetch an article specified by MESSAGE-ID." - (interactive "sMessage-ID: ") + (interactive "sMessage-ID: " gnus-summary-mode) (when (and (stringp message-id) (not (zerop (length message-id)))) (setq message-id (replace-regexp-in-string " " "" message-id)) @@ -9222,12 +9241,12 @@ specified by the `gnus-refer-thread-limit' variable." (defun gnus-summary-edit-parameters () "Edit the group parameters of the current group." - (interactive) + (interactive nil gnus-summary-mode) (gnus-group-edit-group gnus-newsgroup-name 'params)) (defun gnus-summary-customize-parameters () "Customize the group parameters of the current group." - (interactive) + (interactive nil gnus-summary-mode) (gnus-group-customize gnus-newsgroup-name)) (defun gnus-summary-enter-digest-group (&optional force) @@ -9237,7 +9256,7 @@ what the document format is. To control what happens when you exit the group, see the `gnus-auto-select-on-ephemeral-exit' variable." - (interactive "P") + (interactive "P" gnus-summary-mode) (let ((conf gnus-current-window-configuration)) (save-window-excursion (save-excursion @@ -9322,7 +9341,7 @@ To control what happens when you exit the group, see the This will allow you to read digests and other similar documents as newsgroups. Obeys the standard process/prefix convention." - (interactive "P") + (interactive "P" gnus-summary-mode) (let* ((ogroup gnus-newsgroup-name) (params (append (gnus-info-params (gnus-get-info ogroup)) (list (cons 'to-group ogroup)))) @@ -9371,7 +9390,7 @@ Obeys the standard process/prefix convention." (defun gnus-summary-button-forward (arg) "Move point to the next field or button in the article. With optional ARG, move across that many fields." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-select-article) (gnus-configure-windows 'article) (let ((win (or (gnus-get-buffer-window gnus-article-buffer t) @@ -9385,7 +9404,7 @@ With optional ARG, move across that many fields." (defun gnus-summary-button-backward (arg) "Move point to the previous field or button in the article. With optional ARG, move across that many fields." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-select-article) (gnus-configure-windows 'article) (let ((win (or (gnus-get-buffer-window gnus-article-buffer t) @@ -9442,7 +9461,7 @@ If only one link is found, browse that directly, otherwise use completion to select a link. The first link marked in the article text with `gnus-collect-urls-primary-text' is the default." - (interactive "P") + (interactive "P" gnus-summary-mode) (let (urls target) (gnus-summary-select-article) (gnus-with-article-buffer @@ -9467,7 +9486,7 @@ default." (defun gnus-summary-isearch-article (&optional regexp-p) "Do incremental search forward on the current article. If REGEXP-P (the prefix) is non-nil, do regexp isearch." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-select-article) (gnus-configure-windows 'article) (gnus-eval-in-buffer-window gnus-article-buffer @@ -9477,14 +9496,14 @@ If REGEXP-P (the prefix) is non-nil, do regexp isearch." (defun gnus-summary-repeat-search-article-forward () "Repeat the previous search forwards." - (interactive) + (interactive nil gnus-summary-mode) (unless gnus-last-search-regexp (error "No previous search")) (gnus-summary-search-article-forward gnus-last-search-regexp)) (defun gnus-summary-repeat-search-article-backward () "Repeat the previous search backwards." - (interactive) + (interactive nil gnus-summary-mode) (unless gnus-last-search-regexp (error "No previous search")) (gnus-summary-search-article-forward gnus-last-search-regexp t)) @@ -9493,13 +9512,15 @@ If REGEXP-P (the prefix) is non-nil, do regexp isearch." "Search for an article containing REGEXP forward. If BACKWARD, search backward instead." (interactive - (list (read-string - (format "Search article %s (regexp%s): " - (if current-prefix-arg "backward" "forward") - (if gnus-last-search-regexp - (concat ", default " gnus-last-search-regexp) - ""))) - current-prefix-arg)) + (list + (read-string + (format "Search article %s (regexp%s): " + (if current-prefix-arg "backward" "forward") + (if gnus-last-search-regexp + (concat ", default " gnus-last-search-regexp) + ""))) + current-prefix-arg) + gnus-summary-mode) (if (string-equal regexp "") (setq regexp (or gnus-last-search-regexp "")) (setq gnus-last-search-regexp regexp) @@ -9514,11 +9535,13 @@ If BACKWARD, search backward instead." (defun gnus-summary-search-article-backward (regexp) "Search for an article containing REGEXP backward." (interactive - (list (read-string - (format "Search article backward (regexp%s): " - (if gnus-last-search-regexp - (concat ", default " gnus-last-search-regexp) - ""))))) + (list + (read-string + (format "Search article backward (regexp%s): " + (if gnus-last-search-regexp + (concat ", default " gnus-last-search-regexp) + "")))) + gnus-summary-mode) (gnus-summary-search-article-forward regexp 'backward)) (defun gnus-summary-search-article (regexp &optional backward) @@ -9653,18 +9676,20 @@ that not match REGEXP on HEADER." If HEADER is an empty string (or nil), the match is done on the entire article. If BACKWARD (the prefix) is non-nil, search backward instead." (interactive - (list (let ((completion-ignore-case t)) - (gnus-completing-read - "Header name" - (mapcar #'symbol-name - (append - '(Number Subject From Lines Date - Message-ID Xref References Body) - gnus-extra-headers)) - 'require-match)) - (read-string "Regexp: ") - (read-key-sequence "Command: ") - current-prefix-arg)) + (list + (let ((completion-ignore-case t)) + (gnus-completing-read + "Header name" + (mapcar #'symbol-name + (append + '(Number Subject From Lines Date Message-ID + Xref References Body) + gnus-extra-headers)) + 'require-match)) + (read-string "Regexp: ") + (read-key-sequence "Command: ") + current-prefix-arg) + gnus-summary-mode) (when (equal header "Body") (setq header "")) ;; Hidden thread subtrees must be searched as well. @@ -9688,7 +9713,7 @@ article. If BACKWARD (the prefix) is non-nil, search backward instead." (defun gnus-summary-beginning-of-article () "Scroll the article back to the beginning." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-select-article) (gnus-configure-windows 'article) (gnus-eval-in-buffer-window gnus-article-buffer @@ -9699,7 +9724,7 @@ article. If BACKWARD (the prefix) is non-nil, search backward instead." (defun gnus-summary-end-of-article () "Scroll to the end of the article." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-select-article) (gnus-configure-windows 'article) (gnus-eval-in-buffer-window gnus-article-buffer @@ -9732,7 +9757,9 @@ If the optional first argument FILENAME is nil, send the image to the printer. If FILENAME is a string, save the PostScript image in a file with that name. If FILENAME is a number, prompt the user for the name of the file to save in." - (interactive (list (ps-print-preprint current-prefix-arg))) + (interactive + (list (ps-print-preprint current-prefix-arg)) + gnus-summary-mode) (dolist (article (gnus-summary-work-articles n)) (gnus-summary-select-article nil nil 'pseudo article) (gnus-eval-in-buffer-window gnus-article-buffer @@ -9772,7 +9799,7 @@ to save in." "Show a complete version of the current article. This is only useful if you're looking at a partial version of the article currently." - (interactive) + (interactive nil gnus-summary-mode) (let ((gnus-keep-backlog nil) (gnus-use-cache nil) (gnus-agent nil) @@ -9799,7 +9826,7 @@ If ARG (the prefix) is non-nil and not a number, show the article, but without running any of the article treatment functions article. Normally, the keystroke is `C-u g'. When using `C-u C-u g', show the raw article." - (interactive "P") + (interactive "P" gnus-summary-mode) (cond ((numberp arg) (gnus-summary-show-article t) @@ -9875,14 +9902,14 @@ C-u g', show the raw article." (defun gnus-summary-show-raw-article () "Show the raw article without any article massaging functions being run." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-show-article t)) (defun gnus-summary-verbose-headers (&optional arg) "Toggle permanent full header display. If ARG is a positive number, turn header display on. If ARG is a negative number, turn header display off." - (interactive "P") + (interactive "P" gnus-summary-mode) (setq gnus-show-all-headers (cond ((or (not (numberp arg)) (zerop arg)) @@ -9901,7 +9928,7 @@ If ARG is a negative number, turn header display off." "Show the headers if they are hidden, or hide them if they are shown. If ARG is a positive number, show the entire header. If ARG is a negative number, hide the unwanted header lines." - (interactive "P") + (interactive "P" gnus-summary-mode) (let ((window (and (gnus-buffer-live-p gnus-article-buffer) (get-buffer-window gnus-article-buffer t)))) (with-current-buffer gnus-article-buffer @@ -9947,14 +9974,14 @@ If ARG is a negative number, hide the unwanted header lines." (defun gnus-summary-show-all-headers () "Make all header lines visible." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-toggle-header 1)) (defun gnus-summary-caesar-message (&optional arg) "Caesar rotate the current article by 13. With a non-numerical prefix, also rotate headers. A numerical prefix specifies how many places to rotate each letter forward." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-select-article) (let ((mail-header-separator "")) (gnus-eval-in-buffer-window gnus-article-buffer @@ -9977,7 +10004,7 @@ invalid IDNA string (`xn--bar' is invalid). You must have GNU Libidn (URL `https://www.gnu.org/software/libidn/') installed for this command to work." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-select-article) (let ((mail-header-separator "")) (gnus-eval-in-buffer-window gnus-article-buffer @@ -9991,7 +10018,7 @@ installed for this command to work." (defun gnus-summary-morse-message (&optional _arg) "Morse decode the current article." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-select-article) (let ((mail-header-separator "")) (gnus-eval-in-buffer-window gnus-article-buffer @@ -10012,7 +10039,7 @@ installed for this command to work." (defun gnus-summary-stop-page-breaking () "Stop page breaking in the current article." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-select-article) (gnus-eval-in-buffer-window gnus-article-buffer (widen) @@ -10042,7 +10069,7 @@ newsgroup that you want to move to have to support the `request-move' and `request-accept' functions. ACTION can be either `move' (the default), `crosspost' or `copy'." - (interactive "P") + (interactive "P" gnus-summary-mode) (unless action (setq action 'move)) ;; Check whether the source group supports the required functions. @@ -10348,13 +10375,13 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." (defun gnus-summary-copy-article (&optional n to-newsgroup select-method) "Copy the current article to some other group. Arguments have the same meanings as in `gnus-summary-move-article'." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-move-article n to-newsgroup select-method 'copy)) (defun gnus-summary-crosspost-article (&optional n) "Crosspost the current article to some other group. Arguments have the same meanings as in `gnus-summary-move-article'." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-move-article n nil nil 'crosspost)) (defcustom gnus-summary-respool-default-method nil @@ -10398,7 +10425,8 @@ latter case, they will be copied into the relevant groups." (t (let ((ms-alist (mapcar (lambda (m) (cons (cadr m) m)) ms))) (cdr (assoc (gnus-completing-read "Server name" ms-alist t) - ms-alist)))))))) + ms-alist))))))) + gnus-summary-mode) (unless method (error "No method given for respooling")) (if (assoc (symbol-name @@ -10409,7 +10437,7 @@ latter case, they will be copied into the relevant groups." (defun gnus-summary-import-article (file &optional edit) "Import an arbitrary file into a mail newsgroup." - (interactive "fImport file: \nP") + (interactive "fImport file: \nP" gnus-summary-mode) (let ((group gnus-newsgroup-name) atts lines group-art) (unless (gnus-check-backend-function 'request-accept-article group) @@ -10453,7 +10481,7 @@ latter case, they will be copied into the relevant groups." (defun gnus-summary-create-article () "Create an article in a mail newsgroup." - (interactive) + (interactive nil gnus-summary-mode) (let ((group gnus-newsgroup-name) (now (current-time)) group-art) @@ -10477,7 +10505,7 @@ latter case, they will be copied into the relevant groups." (defun gnus-summary-article-posted-p () "Say whether the current (mail) article is available from news as well. This will be the case if the article has both been mailed and posted." - (interactive) + (interactive nil gnus-summary-mode) (let ((id (mail-header-references (gnus-summary-article-header))) (gnus-override-method (car (gnus-refer-article-methods)))) (if (gnus-request-head id "") @@ -10489,7 +10517,7 @@ This will be the case if the article has both been mailed and posted." (defun gnus-summary-expire-articles (&optional now) "Expire all articles that are marked as expirable in the current group." - (interactive) + (interactive nil gnus-summary-mode) (when (and (not gnus-group-is-exiting-without-update-p) (gnus-check-backend-function 'request-expire-articles gnus-newsgroup-name)) @@ -10558,7 +10586,7 @@ This will be the case if the article has both been mailed and posted." "Expunge all expirable articles in the current group. This means that *all* articles that are marked as expirable will be deleted forever, right now." - (interactive) + (interactive nil gnus-summary-mode) (or gnus-expert-user (gnus-yes-or-no-p "Are you really, really sure you want to delete all expirable messages? ") @@ -10578,7 +10606,7 @@ delete these instead. If `gnus-novice-user' is non-nil you will be asked for confirmation before the articles are deleted." - (interactive "P") + (interactive "P" gnus-summary-mode) (unless (gnus-check-backend-function 'request-expire-articles gnus-newsgroup-name) (error "The current newsgroup does not support article deletion")) @@ -10628,7 +10656,7 @@ If ARG is 2, edit the raw articles even in read-only groups. If ARG is 3, edit the articles with the current handles. Otherwise, allow editing of articles even in read-only groups." - (interactive "P") + (interactive "P" gnus-summary-mode) (let (force raw current-handles) (cond ((null arg)) @@ -10708,7 +10736,7 @@ groups." (defun gnus-summary-edit-article-done (&optional references read-only buffer no-highlight) "Make edits to the current article permanent." - (interactive) + (interactive nil gnus-summary-mode) (save-excursion ;; The buffer restriction contains the entire article if it exists. (when (article-goto-body) @@ -10796,7 +10824,8 @@ groups." (list (progn (message "%s" (concat (this-command-keys) "- ")) - (read-char)))) + (read-char))) + gnus-summary-mode) (message "") (gnus-summary-edit-article) (execute-kbd-macro (concat (this-command-keys) key)) @@ -10809,7 +10838,7 @@ groups." (defun gnus-summary-respool-query (&optional silent trace) "Query where the respool algorithm would put this article." - (interactive) + (interactive nil gnus-summary-mode) (let (gnus-mark-article-hook) (gnus-summary-select-article) (with-current-buffer gnus-original-article-buffer @@ -10839,7 +10868,7 @@ groups." (defun gnus-summary-respool-trace () "Trace where the respool algorithm would put this article. Display a buffer showing all fancy splitting patterns which matched." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-respool-query nil t)) ;; Summary marking commands. @@ -10848,7 +10877,7 @@ Display a buffer showing all fancy splitting patterns which matched." "Mark articles which has the same subject as read, and then select the next. If UNMARK is positive, remove any kind of mark. If UNMARK is negative, tick articles." - (interactive "P") + (interactive "P" gnus-summary-mode) (when unmark (setq unmark (prefix-numeric-value unmark))) (let ((count @@ -10866,7 +10895,7 @@ If UNMARK is negative, tick articles." "Mark articles which has the same subject as read. If UNMARK is positive, remove any kind of mark. If UNMARK is negative, tick articles." - (interactive "P") + (interactive "P" gnus-summary-mode) (when unmark (setq unmark (prefix-numeric-value unmark))) (let ((count @@ -10916,7 +10945,7 @@ If optional argument UNMARK is negative, mark articles as unread instead." If N is negative, mark backward instead. If UNMARK is non-nil, remove the process mark instead. The difference between N and the actual number of articles marked is returned." - (interactive "P") + (interactive "P" gnus-summary-mode) (if (and (null n) (and transient-mark-mode mark-active)) (gnus-uu-mark-region (region-beginning) (region-end) unmark) (setq n (prefix-numeric-value n)) @@ -10940,12 +10969,12 @@ number of articles marked is returned." "Remove the process mark from the next N articles. If N is negative, unmark backward instead. The difference between N and the actual number of articles unmarked is returned." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-mark-as-processable n t)) (defun gnus-summary-unmark-all-processable () "Remove the process mark from all articles." - (interactive) + (interactive nil gnus-summary-mode) (save-excursion (while gnus-newsgroup-processable (gnus-summary-remove-process-mark (car gnus-newsgroup-processable)))) @@ -10969,20 +10998,21 @@ the actual number of articles unmarked is returned." "Mark N articles forward as expirable. If N is negative, mark backward instead. The difference between N and the actual number of articles marked is returned." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-mark-forward n gnus-expirable-mark)) (defun gnus-summary-mark-as-spam (n) "Mark N articles forward as spam. If N is negative, mark backward instead. The difference between N and the actual number of articles marked is returned." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-mark-forward n gnus-spam-mark)) (defun gnus-summary-mark-article-as-replied (article) "Mark ARTICLE as replied to and update the summary line. ARTICLE can also be a list of articles." - (interactive (list (gnus-summary-article-number))) + (interactive (list (gnus-summary-article-number)) + gnus-summary-mode) (let ((articles (if (listp article) article (list article)))) (dolist (article articles) (unless (numberp article) @@ -11004,7 +11034,8 @@ ARTICLE can also be a list of articles." (defun gnus-summary-set-bookmark (article) "Set a bookmark in current article." - (interactive (list (gnus-summary-article-number))) + (interactive (list (gnus-summary-article-number)) + gnus-summary-mode) (when (or (not (get-buffer gnus-article-buffer)) (not gnus-current-article) (not gnus-article-current) @@ -11028,7 +11059,8 @@ ARTICLE can also be a list of articles." (defun gnus-summary-remove-bookmark (article) "Remove the bookmark from the current article." - (interactive (list (gnus-summary-article-number))) + (interactive (list (gnus-summary-article-number)) + gnus-summary-mode) ;; Remove old bookmark, if one exists. (if (not (assq article gnus-newsgroup-bookmarks)) (gnus-message 6 "No bookmark in current article.") @@ -11040,7 +11072,7 @@ ARTICLE can also be a list of articles." "Mark N articles forward as dormant. If N is negative, mark backward instead. The difference between N and the actual number of articles marked is returned." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-mark-forward n gnus-dormant-mark)) (defun gnus-summary-set-process-mark (article) @@ -11075,7 +11107,7 @@ If N is negative, mark backwards instead. Mark with MARK, ?r by default. The difference between N and the actual number of articles marked is returned. If NO-EXPIRE, auto-expiry will be inhibited." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-show-thread) (let ((backward (< n 0)) (gnus-summary-goto-unread @@ -11339,20 +11371,20 @@ If NO-EXPIRE, auto-expiry will be inhibited." "Tick N articles forwards. If N is negative, tick backwards instead. The difference between N and the number of articles ticked is returned." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-mark-forward n gnus-ticked-mark)) (defun gnus-summary-tick-article-backward (n) "Tick N articles backwards. The difference between N and the number of articles ticked is returned." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-mark-forward (- n) gnus-ticked-mark)) (defun gnus-summary-tick-article (&optional article clear-mark) "Mark current article as unread. Optional 1st argument ARTICLE specifies article number to be marked as unread. Optional 2nd argument CLEAR-MARK remove any kinds of mark." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-mark-article article (if clear-mark gnus-unread-mark gnus-ticked-mark))) @@ -11361,14 +11393,14 @@ Optional 2nd argument CLEAR-MARK remove any kinds of mark." If N is negative, mark backwards instead. The difference between N and the actual number of articles marked is returned." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-mark-forward n gnus-del-mark gnus-inhibit-user-auto-expire)) (defun gnus-summary-mark-as-read-backward (n) "Mark the N articles as read backwards. The difference between N and the actual number of articles marked is returned." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-mark-forward (- n) gnus-del-mark gnus-inhibit-user-auto-expire)) @@ -11382,13 +11414,13 @@ MARK specifies a string to be inserted at the beginning of the line." "Clear marks from N articles forward. If N is negative, clear backward instead. The difference between N and the number of marks cleared is returned." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-mark-forward n gnus-unread-mark)) (defun gnus-summary-clear-mark-backward (n) "Clear marks from N articles backward. The difference between N and the number of marks cleared is returned." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-mark-forward (- n) gnus-unread-mark)) (defun gnus-summary-mark-unread-as-read () @@ -11421,7 +11453,7 @@ The difference between N and the number of marks cleared is returned." "Mark all unread articles between point and mark as read. If given a prefix, mark all articles between point and mark as read, even ticked and dormant ones." - (interactive "r\nP") + (interactive "r\nP" gnus-summary-mode) (save-excursion (let (article) (goto-char point) @@ -11438,7 +11470,7 @@ even ticked and dormant ones." (defun gnus-summary-mark-below (score mark) "Mark articles with score less than SCORE with MARK." - (interactive "P\ncMark: ") + (interactive "P\ncMark: " gnus-summary-mode) (setq score (if score (prefix-numeric-value score) (or gnus-summary-default-score 0))) @@ -11452,22 +11484,22 @@ even ticked and dormant ones." (defun gnus-summary-kill-below (&optional score) "Mark articles with score below SCORE as read." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-mark-below score gnus-killed-mark)) (defun gnus-summary-clear-above (&optional score) "Clear all marks from articles with score above SCORE." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-mark-above score gnus-unread-mark)) (defun gnus-summary-tick-above (&optional score) "Tick all articles with score above SCORE." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-mark-above score gnus-ticked-mark)) (defun gnus-summary-mark-above (score mark) "Mark articles with score over SCORE with MARK." - (interactive "P\ncMark: ") + (interactive "P\ncMark: " gnus-summary-mode) (setq score (if score (prefix-numeric-value score) (or gnus-summary-default-score 0))) @@ -11483,7 +11515,7 @@ even ticked and dormant ones." (defalias 'gnus-summary-show-all-expunged 'gnus-summary-limit-include-expunged) (defun gnus-summary-limit-include-expunged (&optional no-error) "Display all the hidden articles that were expunged for low scores." - (interactive) + (interactive nil gnus-summary-mode) (let ((inhibit-read-only t)) (let ((scored gnus-newsgroup-scored) headers h) @@ -11520,7 +11552,7 @@ Note that this function will only catch up the unread article in the current summary buffer limitation. The number of articles marked as read is returned." - (interactive "P") + (interactive "P" gnus-summary-mode) (prog1 (save-excursion (when (or quietly @@ -11569,7 +11601,7 @@ The number of articles marked as read is returned." (defun gnus-summary-catchup-to-here (&optional all) "Mark all unticked articles before the current one as read. If ALL is non-nil, also mark ticked and dormant articles as read." - (interactive "P") + (interactive "P" gnus-summary-mode) (save-excursion (gnus-save-hidden-threads (let ((beg (point))) @@ -11581,7 +11613,7 @@ If ALL is non-nil, also mark ticked and dormant articles as read." (defun gnus-summary-catchup-from-here (&optional all) "Mark all unticked articles after (and including) the current one as read. If ALL is non-nil, also mark ticked and dormant articles as read." - (interactive "P") + (interactive "P" gnus-summary-mode) (save-excursion (gnus-save-hidden-threads (let ((beg (point))) @@ -11594,14 +11626,14 @@ If ALL is non-nil, also mark ticked and dormant articles as read." "Mark all articles in this newsgroup as read. This command is dangerous. Normally, you want \\[gnus-summary-catchup] instead, which marks only unread articles as read." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-catchup t quietly)) (defun gnus-summary-catchup-and-exit (&optional all quietly) "Mark all unread articles in this group as read, then exit. If prefix argument ALL is non-nil, all articles are marked as read. If QUIETLY is non-nil, no questions will be asked." - (interactive "P") + (interactive "P" gnus-summary-mode) (when (gnus-summary-catchup all quietly nil 'fast) ;; Select next newsgroup or exit. (if (and (not (gnus-group-quit-config gnus-newsgroup-name)) @@ -11613,14 +11645,14 @@ If QUIETLY is non-nil, no questions will be asked." "Mark all articles in this newsgroup as read, and then exit. This command is dangerous. Normally, you want \\[gnus-summary-catchup-and-exit] instead, which marks only unread articles as read." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-catchup-and-exit t quietly)) (defun gnus-summary-catchup-and-goto-next-group (&optional all) "Mark all articles in this group as read and select the next group. If given a prefix, mark all articles, unread as well as ticked, as read." - (interactive "P") + (interactive "P" gnus-summary-mode) (save-excursion (gnus-summary-catchup all)) (gnus-summary-next-group)) @@ -11629,7 +11661,7 @@ read." "Mark all articles in this group as read and select the previous group. If given a prefix, mark all articles, unread as well as ticked, as read." - (interactive "P") + (interactive "P" gnus-summary-mode) (save-excursion (gnus-summary-catchup all)) (gnus-summary-next-group nil nil t)) @@ -11705,7 +11737,7 @@ with that article." (defun gnus-summary-rethread-current () "Rethread the thread the current article is part of." - (interactive) + (interactive nil gnus-summary-mode) (let* ((gnus-show-threads t) (article (gnus-summary-article-number)) (id (mail-header-id (gnus-summary-article-header))) @@ -11720,7 +11752,7 @@ with that article." Note that the re-threading will only work if `gnus-thread-ignore-subject' is non-nil or the Subject: of both articles are the same." - (interactive) + (interactive nil gnus-summary-mode) (unless (not (gnus-group-read-only-p)) (error "The current newsgroup does not support article editing")) (unless (<= (length gnus-newsgroup-processable) 1) @@ -11739,9 +11771,10 @@ is non-nil or the Subject: of both articles are the same." "Make PARENT the parent of CHILDREN. When called interactively, PARENT is the current article and CHILDREN are the process-marked articles." - (interactive - (list (gnus-summary-article-number) - (gnus-summary-work-articles nil))) + (interactive (list + (gnus-summary-article-number) + (gnus-summary-work-articles nil)) + gnus-summary-mode) (dolist (child children) (save-window-excursion (let ((gnus-article-buffer " *reparent*")) @@ -11774,7 +11807,7 @@ are the process-marked articles." (defun gnus-summary-toggle-threads (&optional arg) "Toggle showing conversation threads. If ARG is positive number, turn showing conversation threads on." - (interactive "P") + (interactive "P" gnus-summary-mode) (let ((current (or (gnus-summary-article-number) gnus-newsgroup-end))) (setq gnus-show-threads (if (null arg) (not gnus-show-threads) @@ -11786,7 +11819,7 @@ If ARG is positive number, turn showing conversation threads on." (defun gnus-summary-show-all-threads () "Show all threads." - (interactive) + (interactive nil gnus-summary-mode) (remove-overlays (point-min) (point-max) 'invisible 'gnus-sum) (gnus-summary-position-point)) @@ -11796,7 +11829,7 @@ If ARG is positive number, turn showing conversation threads on." (defun gnus-summary-show-thread () "Show thread subtrees. Returns nil if no thread was there to be shown." - (interactive) + (interactive nil gnus-summary-mode) (let* ((orig (point)) (end (point-at-eol)) (end (or (gnus-summary--inv end) (gnus-summary--inv (1- end)))) @@ -11837,7 +11870,7 @@ Returns nil if no thread was there to be shown." "Hide all thread subtrees. If PREDICATE is supplied, threads that satisfy this predicate will not be hidden." - (interactive) + (interactive nil gnus-summary-mode) (save-excursion (goto-char (point-min)) (let ((end nil) @@ -11856,7 +11889,7 @@ will not be hidden." (defun gnus-summary-hide-thread () "Hide thread subtrees. Returns nil if no threads were there to be hidden." - (interactive) + (interactive nil gnus-summary-mode) (beginning-of-line) (let ((start (point)) (starteol (line-end-position)) @@ -11908,7 +11941,7 @@ Returns the difference between N and the number of skips actually done. If SILENT, don't output messages." - (interactive "p") + (interactive "p" gnus-summary-mode) (let ((backward (< n 0)) (n (abs n))) (while (and (> n 0) @@ -11924,7 +11957,7 @@ If SILENT, don't output messages." "Go to the same level previous N'th thread. Returns the difference between N and the number of skips actually done." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-next-thread (- n))) (defun gnus-summary-go-down-thread () @@ -11944,7 +11977,7 @@ done." If N is negative, go up instead. Returns the difference between N and how many steps down that were taken." - (interactive "p") + (interactive "p" gnus-summary-mode) (let ((up (< n 0)) (n (abs n))) (while (and (> n 0) @@ -11961,18 +11994,18 @@ taken." If N is negative, go down instead. Returns the difference between N and how many steps down that were taken." - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-down-thread (- n))) (defun gnus-summary-top-thread () "Go to the top of the thread." - (interactive) + (interactive nil gnus-summary-mode) (while (gnus-summary-go-up-thread)) (gnus-summary-article-number)) (defun gnus-summary-expire-thread () "Mark articles under current thread as expired." - (interactive) + (interactive nil gnus-summary-mode) (gnus-summary-kill-thread 0)) (defun gnus-summary-kill-thread (&optional unmark) @@ -11980,7 +12013,7 @@ taken." If the prefix argument is positive, remove any kinds of marks. If the prefix argument is zero, mark thread as expired. If the prefix argument is negative, tick articles instead." - (interactive "P") + (interactive "P" gnus-summary-mode) (when unmark (setq unmark (prefix-numeric-value unmark))) (let ((articles (gnus-summary-articles-in-thread)) @@ -12015,82 +12048,82 @@ If the prefix argument is negative, tick articles instead." (defun gnus-summary-sort-by-number (&optional reverse) "Sort the summary buffer by article number. Argument REVERSE means reverse order." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-sort 'number reverse)) (defun gnus-summary-sort-by-most-recent-number (&optional reverse) "Sort the summary buffer by most recent article number. Argument REVERSE means reverse order." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-sort 'most-recent-number reverse)) (defun gnus-summary-sort-by-random (&optional reverse) "Randomize the order in the summary buffer. Argument REVERSE means to randomize in reverse order." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-sort 'random reverse)) (defun gnus-summary-sort-by-author (&optional reverse) "Sort the summary buffer by author name alphabetically. If `case-fold-search' is non-nil, case of letters is ignored. Argument REVERSE means reverse order." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-sort 'author reverse)) (defun gnus-summary-sort-by-recipient (&optional reverse) "Sort the summary buffer by recipient name alphabetically. If `case-fold-search' is non-nil, case of letters is ignored. Argument REVERSE means reverse order." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-sort 'recipient reverse)) (defun gnus-summary-sort-by-subject (&optional reverse) "Sort the summary buffer by subject alphabetically. `Re:'s are ignored. If `case-fold-search' is non-nil, case of letters is ignored. Argument REVERSE means reverse order." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-sort 'subject reverse)) (defun gnus-summary-sort-by-date (&optional reverse) "Sort the summary buffer by date. Argument REVERSE means reverse order." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-sort 'date reverse)) (defun gnus-summary-sort-by-most-recent-date (&optional reverse) "Sort the summary buffer by most recent date. Argument REVERSE means reverse order." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-sort 'most-recent-date reverse)) (defun gnus-summary-sort-by-score (&optional reverse) "Sort the summary buffer by score. Argument REVERSE means reverse order." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-sort 'score reverse)) (defun gnus-summary-sort-by-lines (&optional reverse) "Sort the summary buffer by the number of lines. Argument REVERSE means reverse order." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-sort 'lines reverse)) (defun gnus-summary-sort-by-chars (&optional reverse) "Sort the summary buffer by article length. Argument REVERSE means reverse order." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-sort 'chars reverse)) (defun gnus-summary-sort-by-marks (&optional reverse) "Sort the summary buffer by article marks. Argument REVERSE means reverse order." - (interactive "P") + (interactive "P" gnus-summary-mode) (gnus-summary-sort 'marks reverse)) (defun gnus-summary-sort-by-original (&optional _reverse) "Sort the summary buffer using the default sorting method. Argument REVERSE means reverse order." - (interactive) + (interactive nil gnus-summary-mode) (let* ((inhibit-read-only t) (gnus-summary-prepare-hook nil)) ;; We do the sorting by regenerating the threads. @@ -12139,7 +12172,7 @@ will not be marked as saved. The `gnus-prompt-before-saving' variable says how prompting is performed." - (interactive "P") + (interactive "P" gnus-summary-mode) (require 'gnus-art) (let* ((articles (gnus-summary-work-articles n)) (save-buffer (save-excursion @@ -12208,7 +12241,7 @@ is neither omitted nor the symbol `r', force including all headers regardless of the `:headers' property. If it is the symbol `r', articles that are not decoded and include all headers will be piped no matter what the properties `:decode' and `:headers' are." - (interactive (gnus-interactive "P\ny")) + (interactive (gnus-interactive "P\ny") gnus-summary-mode) (require 'gnus-art) (let* ((articles (gnus-summary-work-articles n)) (result-buffer shell-command-buffer-name) @@ -12260,7 +12293,7 @@ If N is a positive number, save the N next articles. If N is a negative number, save the N previous articles. If N is nil and any articles have been marked with the process mark, save those articles instead." - (interactive "P") + (interactive "P" gnus-summary-mode) (require 'gnus-art) (let ((gnus-default-article-saver 'gnus-summary-save-in-mail)) (gnus-summary-save-article arg))) @@ -12271,7 +12304,7 @@ If N is a positive number, save the N next articles. If N is a negative number, save the N previous articles. If N is nil and any articles have been marked with the process mark, save those articles instead." - (interactive "P") + (interactive "P" gnus-summary-mode) (require 'gnus-art) (let ((gnus-default-article-saver 'gnus-summary-save-in-rmail)) (gnus-summary-save-article arg))) @@ -12282,7 +12315,7 @@ If N is a positive number, save the N next articles. If N is a negative number, save the N previous articles. If N is nil and any articles have been marked with the process mark, save those articles instead." - (interactive "P") + (interactive "P" gnus-summary-mode) (require 'gnus-art) (let ((gnus-default-article-saver 'gnus-summary-save-in-file)) (gnus-summary-save-article arg))) @@ -12293,7 +12326,7 @@ If N is a positive number, save the N next articles. If N is a negative number, save the N previous articles. If N is nil and any articles have been marked with the process mark, save those articles instead." - (interactive "P") + (interactive "P" gnus-summary-mode) (require 'gnus-art) (let ((gnus-default-article-saver 'gnus-summary-write-to-file)) (gnus-summary-save-article arg))) @@ -12304,7 +12337,7 @@ If N is a positive number, save the N next articles. If N is a negative number, save the N previous articles. If N is nil and any articles have been marked with the process mark, save those articles instead." - (interactive "P") + (interactive "P" gnus-summary-mode) (require 'gnus-art) (let ((gnus-default-article-saver 'gnus-summary-save-body-in-file)) (gnus-summary-save-article arg))) @@ -12315,7 +12348,7 @@ If N is a positive number, save the N next articles. If N is a negative number, save the N previous articles. If N is nil and any articles have been marked with the process mark, save those articles instead." - (interactive "P") + (interactive "P" gnus-summary-mode) (require 'gnus-art) (let ((gnus-default-article-saver 'gnus-summary-write-body-to-file)) (gnus-summary-save-article arg))) @@ -12326,14 +12359,14 @@ If N is a positive number, save the N next articles. If N is a negative number, save the N previous articles. If N is nil and any articles have been marked with the process mark, save those articles instead." - (interactive "P") + (interactive "P" gnus-summary-mode) (require 'gnus-art) (let ((gnus-default-article-saver 'gnus-summary-pipe-to-muttprint)) (gnus-summary-save-article arg t))) (defun gnus-summary-pipe-message (program) "Pipe the current article through PROGRAM." - (interactive "sProgram: ") + (interactive "sProgram: " gnus-summary-mode) (gnus-summary-select-article) (let ((mail-header-separator "")) (gnus-eval-in-buffer-window gnus-article-buffer @@ -12451,7 +12484,8 @@ If REVERSE, save parts that do not match TYPE." (read-directory-name "Save to directory: " gnus-summary-save-parts-last-directory nil t)) - current-prefix-arg)) + current-prefix-arg) + gnus-summary-mode) (gnus-summary-iterate n (let ((gnus-display-mime-function nil) gnus-article-prepare-hook @@ -12590,12 +12624,12 @@ If REVERSE, save parts that do not match TYPE." (defun gnus-summary-edit-global-kill (article) "Edit the \"global\" kill file." - (interactive (list (gnus-summary-article-number))) + (interactive (list (gnus-summary-article-number)) gnus-summary-mode) (gnus-group-edit-global-kill article)) (defun gnus-summary-edit-local-kill () "Edit a local kill file applied to the current newsgroup." - (interactive) + (interactive nil gnus-summary-mode) (setq gnus-current-headers (gnus-summary-article-header)) (gnus-group-edit-local-kill (gnus-summary-article-number) gnus-newsgroup-name)) @@ -12893,7 +12927,7 @@ UNREAD is a sorted list." "Display the current article buffer fully MIME-buttonized. If SHOW-ALL-PARTS (the prefix) is non-nil, all multipart/* parts are treated as multipart/mixed." - (interactive "P") + (interactive "P" gnus-summary-mode) (require 'gnus-art) (let ((gnus-unbuttonized-mime-types nil) (gnus-mime-display-multipart-as-mixed show-all-parts)) @@ -12901,7 +12935,7 @@ treated as multipart/mixed." (defun gnus-summary-repair-multipart (article) "Add a Content-Type header to a multipart article without one." - (interactive (list (gnus-summary-article-number))) + (interactive (list (gnus-summary-article-number)) gnus-summary-mode) (gnus-with-article article (message-narrow-to-head) (message-remove-header "Mime-Version") @@ -12921,7 +12955,7 @@ treated as multipart/mixed." (defun gnus-summary-toggle-display-buttonized () "Toggle the buttonizing of the article buffer." - (interactive) + (interactive nil gnus-summary-mode) (require 'gnus-art) (if (setq gnus-inhibit-mime-unbuttonizing (not gnus-inhibit-mime-unbuttonizing)) @@ -12976,7 +13010,7 @@ If N is negative, move in reverse order. The difference between N and the actual number of articles marked is returned." name (cadr lway)) - (interactive "p") + (interactive "p" gnus-summary-mode) (gnus-summary-generic-mark n ,mark ',(nth 2 lway) ,(nth 3 lway)))) (defun gnus-summary-generic-mark (n mark move unread) @@ -13059,7 +13093,7 @@ returned." "Insert all old articles in this group. If ALL is non-nil, already read articles become readable. If ALL is a number, fetch this number of articles." - (interactive "P") + (interactive "P" gnus-summary-mode) (prog1 (let ((old (sort (mapcar #'gnus-data-number gnus-newsgroup-data) #'<)) older len) @@ -13133,7 +13167,7 @@ If ALL is a number, fetch this number of articles." (defun gnus-summary-insert-new-articles () "Insert all new articles in this group." - (interactive) + (interactive nil gnus-summary-mode) (let ((old (sort (mapcar #'gnus-data-number gnus-newsgroup-data) #'<)) (old-high gnus-newsgroup-highest) (nnmail-fetched-sources (list t)) diff --git a/lisp/gnus/gnus-topic.el b/lisp/gnus/gnus-topic.el index 3253b7853d..b3d17bc03f 100644 --- a/lisp/gnus/gnus-topic.el +++ b/lisp/gnus/gnus-topic.el @@ -146,7 +146,8 @@ See Info node `(gnus)Formatting Variables'." (defun gnus-topic-jump-to-topic (topic) "Go to TOPIC." (interactive - (list (gnus-completing-read "Go to topic" (gnus-topic-list) t))) + (list (gnus-completing-read "Go to topic" (gnus-topic-list) t)) + gnus-topic-mode) (let ((inhibit-read-only t)) (dolist (topic (gnus-current-topics topic)) (unless (gnus-topic-goto-topic topic) @@ -235,12 +236,12 @@ If RECURSIVE is t, return groups in its subtopics too." (defun gnus-topic-goto-previous-topic (n) "Go to the N'th previous topic." - (interactive "p") + (interactive "p" gnus-topic-mode) (gnus-topic-goto-next-topic (- n))) (defun gnus-topic-goto-next-topic (n) "Go to the N'th next topic." - (interactive "p") + (interactive "p" gnus-topic-mode) (let ((backward (< n 0)) (n (abs n)) (topic (gnus-current-topic))) @@ -661,7 +662,7 @@ articles in the topic and its subtopics." (defun gnus-topic-update-topics-containing-group (group) "Update all topics that have GROUP as a member." - (when (and (eq major-mode 'gnus-group-mode) + (when (and (eq major-mode 'gnus-topic-mode) gnus-topic-mode) (save-excursion (let ((alist gnus-topic-alist)) @@ -677,7 +678,7 @@ articles in the topic and its subtopics." (defun gnus-topic-update-topic () "Update all parent topics to the current group." - (when (and (eq major-mode 'gnus-group-mode) + (when (and (eq major-mode 'gnus-topic-mode) gnus-topic-mode) (let ((group (gnus-group-group-name)) (m (point-marker)) @@ -1122,7 +1123,9 @@ articles in the topic and its subtopics." (define-minor-mode gnus-topic-mode "Minor mode for topicsifying Gnus group buffers." - :lighter " Topic" :keymap gnus-topic-mode-map + :lighter " Topic" + :keymap gnus-topic-mode-map + :interactive (gnus-group-mode) (if (not (derived-mode-p 'gnus-group-mode)) (setq gnus-topic-mode nil) ;; Infest Gnus with topics. @@ -1172,7 +1175,7 @@ articles in the group. If ALL is a negative number, fetch this number of the earliest articles in the group. If performed over a topic line, toggle folding the topic." - (interactive "P") + (interactive "P" gnus-topic-mode) (when (and (eobp) (not (gnus-group-group-name))) (forward-line -1)) (if (gnus-group-topic-p) @@ -1184,13 +1187,13 @@ If performed over a topic line, toggle folding the topic." (defun gnus-mouse-pick-topic (e) "Select the group or topic under the mouse pointer." - (interactive "e") + (interactive "e" gnus-topic-mode) (mouse-set-point e) (gnus-topic-read-group nil)) (defun gnus-topic-expire-articles (topic) "Expire articles in this topic or group." - (interactive (list (gnus-group-topic-name))) + (interactive (list (gnus-group-topic-name)) gnus-topic-mode) (if (not topic) (call-interactively 'gnus-group-expire-articles) (save-excursion @@ -1205,7 +1208,7 @@ If performed over a topic line, toggle folding the topic." (defun gnus-topic-catchup-articles (topic) "Catchup this topic or group. Also see `gnus-group-catchup'." - (interactive (list (gnus-group-topic-name))) + (interactive (list (gnus-group-topic-name)) gnus-topic-mode) (if (not topic) (call-interactively 'gnus-group-catchup-current) (save-excursion @@ -1232,7 +1235,7 @@ be auto-selected upon group entry. If GROUP is non-nil, fetch that group. If performed over a topic line, toggle folding the topic." - (interactive "P") + (interactive "P" gnus-topic-mode) (when (and (eobp) (not (gnus-group-group-name))) (forward-line -1)) (if (gnus-group-topic-p) @@ -1247,7 +1250,8 @@ When used interactively, PARENT will be the topic under point." (interactive (list (read-string "New topic: ") - (gnus-current-topic))) + (gnus-current-topic)) + gnus-topic-mode) ;; Check whether this topic already exists. (when (gnus-topic-find-topology topic) (error "Topic already exists")) @@ -1284,7 +1288,8 @@ If COPYP, copy the groups instead." (interactive (list current-prefix-arg (gnus-completing-read "Move to topic" (mapcar #'car gnus-topic-alist) t - nil 'gnus-topic-history))) + nil 'gnus-topic-history)) + gnus-topic-mode) (let ((use-marked (and (not n) (not (and transient-mark-mode mark-active)) gnus-group-marked t)) (groups (gnus-group-process-prefix n)) @@ -1309,7 +1314,7 @@ If COPYP, copy the groups instead." (defun gnus-topic-remove-group (&optional n) "Remove the current group from the topic." - (interactive "P") + (interactive "P" gnus-topic-mode) (let ((use-marked (and (not n) (not (and transient-mark-mode mark-active)) gnus-group-marked t)) (groups (gnus-group-process-prefix n))) @@ -1331,12 +1336,13 @@ If COPYP, copy the groups instead." (interactive (list current-prefix-arg (gnus-completing-read - "Copy to topic" (mapcar #'car gnus-topic-alist) t))) + "Copy to topic" (mapcar #'car gnus-topic-alist) t)) + gnus-topic-mode) (gnus-topic-move-group n topic t)) (defun gnus-topic-kill-group (&optional n discard) "Kill the next N groups." - (interactive "P") + (interactive "P" gnus-topic-mode) (if (gnus-group-topic-p) (let ((topic (gnus-group-topic-name))) (push (cons @@ -1356,7 +1362,7 @@ If COPYP, copy the groups instead." (defun gnus-topic-yank-group (&optional arg) "Yank the last topic." - (interactive "p") + (interactive "p" gnus-topic-mode) (if gnus-topic-killed-topics (let* ((previous (or (gnus-group-topic-name) @@ -1405,7 +1411,7 @@ If COPYP, copy the groups instead." (defun gnus-topic-hide-topic (&optional permanent) "Hide the current topic. If PERMANENT, make it stay hidden in subsequent sessions as well." - (interactive "P") + (interactive "P" gnus-topic-mode) (when (gnus-current-topic) (gnus-topic-goto-topic (gnus-current-topic)) (if permanent @@ -1418,7 +1424,7 @@ If PERMANENT, make it stay hidden in subsequent sessions as well." (defun gnus-topic-show-topic (&optional permanent) "Show the hidden topic. If PERMANENT, make it stay shown in subsequent sessions as well." - (interactive "P") + (interactive "P" gnus-topic-mode) (when (gnus-group-topic-p) (if (not permanent) (gnus-topic-remove-topic t nil) @@ -1433,9 +1439,11 @@ If PERMANENT, make it stay shown in subsequent sessions as well." (defun gnus-topic-mark-topic (topic &optional unmark non-recursive) "Mark all groups in the TOPIC with the process mark. If NON-RECURSIVE (which is the prefix) is t, don't mark its subtopics." - (interactive (list (gnus-group-topic-name) - nil - (and current-prefix-arg t))) + (interactive + (list (gnus-group-topic-name) + nil + (and current-prefix-arg t)) + gnus-topic-mode) (if (not topic) (call-interactively 'gnus-group-mark-group) (save-excursion @@ -1450,14 +1458,15 @@ If NON-RECURSIVE (which is the prefix) is t, don't mark its subtopics." If NON-RECURSIVE (which is the prefix) is t, don't unmark its subtopics." (interactive (list (gnus-group-topic-name) nil - (and current-prefix-arg t))) + (and current-prefix-arg t)) + gnus-topic-mode) (if (not topic) (call-interactively 'gnus-group-unmark-group) (gnus-topic-mark-topic topic t non-recursive))) (defun gnus-topic-get-new-news-this-topic (&optional n) "Check for new news in the current topic." - (interactive "P") + (interactive "P" gnus-topic-mode) (if (not (gnus-group-topic-p)) (gnus-group-get-new-news-this-group n) (let* ((topic (gnus-group-topic-name)) @@ -1475,7 +1484,8 @@ If NON-RECURSIVE (which is the prefix) is t, don't unmark its subtopics." (list (setq topic (gnus-completing-read "Move to topic" (mapcar #'car gnus-topic-alist) t)) - (read-string (format "Move to %s (regexp): " topic)))))) + (read-string (format "Move to %s (regexp): " topic))))) + gnus-topic-mode) (gnus-group-mark-regexp regexp) (gnus-topic-move-group nil topic copyp)) @@ -1486,12 +1496,13 @@ If NON-RECURSIVE (which is the prefix) is t, don't unmark its subtopics." (mapcar #'car gnus-topic-alist) t))) (nreverse (list topic - (read-string (format "Copy to %s (regexp): " topic)))))) + (read-string (format "Copy to %s (regexp): " topic))))) + gnus-topic-mode) (gnus-topic-move-matching regexp topic t)) (defun gnus-topic-delete (topic) "Delete a topic." - (interactive (list (gnus-group-topic-name))) + (interactive (list (gnus-group-topic-name)) gnus-topic-mode) (unless topic (error "No topic to be deleted")) (let ((entry (assoc topic gnus-topic-alist)) @@ -1512,7 +1523,8 @@ If NON-RECURSIVE (which is the prefix) is t, don't unmark its subtopics." (interactive (let ((topic (gnus-current-topic))) (list topic - (read-string (format "Rename %s to: " topic) topic)))) + (read-string (format "Rename %s to: " topic) topic))) + gnus-topic-mode) ;; Check whether the new name exists. (when (gnus-topic-find-topology new-name) (error "Topic `%s' already exists" new-name)) @@ -1535,7 +1547,7 @@ If NON-RECURSIVE (which is the prefix) is t, don't unmark its subtopics." (defun gnus-topic-indent (&optional unindent) "Indent a topic -- make it a sub-topic of the previous topic. If UNINDENT, remove an indentation." - (interactive "P") + (interactive "P" gnus-topic-mode) (if unindent (gnus-topic-unindent) (let* ((topic (gnus-current-topic)) @@ -1555,7 +1567,7 @@ If UNINDENT, remove an indentation." (defun gnus-topic-unindent () "Unindent a topic." - (interactive) + (interactive nil gnus-topic-mode) (let* ((topic (gnus-current-topic)) (parent (gnus-topic-parent-topic topic)) (grandparent (gnus-topic-parent-topic parent))) @@ -1574,7 +1586,7 @@ If UNINDENT, remove an indentation." (defun gnus-topic-list-active (&optional force) "List all groups that Gnus knows about in a topicsified fashion. If FORCE, always re-read the active file." - (interactive "P") + (interactive "P" gnus-topic-mode) (when force (gnus-get-killed-groups)) (gnus-topic-grok-active force) @@ -1585,7 +1597,7 @@ If FORCE, always re-read the active file." (defun gnus-topic-toggle-display-empty-topics () "Show/hide topics that have no unread articles." - (interactive) + (interactive nil gnus-topic-mode) (setq gnus-topic-display-empty-topics (not gnus-topic-display-empty-topics)) (gnus-group-list-groups) @@ -1598,7 +1610,7 @@ If FORCE, always re-read the active file." (defun gnus-topic-edit-parameters (group) "Edit the group parameters of GROUP. If performed on a topic, edit the topic parameters instead." - (interactive (list (gnus-group-group-name))) + (interactive (list (gnus-group-group-name)) gnus-topic-mode) (if group (gnus-group-edit-group-parameters group) (if (not (gnus-group-topic-p)) @@ -1642,7 +1654,8 @@ If performed on a topic, edit the topic parameters instead." (defun gnus-topic-sort-groups (func &optional reverse) "Sort the current topic according to FUNC. If REVERSE, reverse the sorting order." - (interactive (list gnus-group-sort-function current-prefix-arg)) + (interactive (list gnus-group-sort-function current-prefix-arg) + gnus-topic-mode) (let ((topic (assoc (gnus-current-topic) gnus-topic-alist))) (gnus-topic-sort-topic topic (gnus-make-sort-function func) reverse) @@ -1651,43 +1664,43 @@ If REVERSE, reverse the sorting order." (defun gnus-topic-sort-groups-by-alphabet (&optional reverse) "Sort the current topic alphabetically by group name. If REVERSE, sort in reverse order." - (interactive "P") + (interactive "P" gnus-topic-mode) (gnus-topic-sort-groups 'gnus-group-sort-by-alphabet reverse)) (defun gnus-topic-sort-groups-by-unread (&optional reverse) "Sort the current topic by number of unread articles. If REVERSE, sort in reverse order." - (interactive "P") + (interactive "P" gnus-topic-mode) (gnus-topic-sort-groups 'gnus-group-sort-by-unread reverse)) (defun gnus-topic-sort-groups-by-level (&optional reverse) "Sort the current topic by group level. If REVERSE, sort in reverse order." - (interactive "P") + (interactive "P" gnus-topic-mode) (gnus-topic-sort-groups 'gnus-group-sort-by-level reverse)) (defun gnus-topic-sort-groups-by-score (&optional reverse) "Sort the current topic by group score. If REVERSE, sort in reverse order." - (interactive "P") + (interactive "P" gnus-topic-mode) (gnus-topic-sort-groups 'gnus-group-sort-by-score reverse)) (defun gnus-topic-sort-groups-by-rank (&optional reverse) "Sort the current topic by group rank. If REVERSE, sort in reverse order." - (interactive "P") + (interactive "P" gnus-topic-mode) (gnus-topic-sort-groups 'gnus-group-sort-by-rank reverse)) (defun gnus-topic-sort-groups-by-method (&optional reverse) "Sort the current topic alphabetically by backend name. If REVERSE, sort in reverse order." - (interactive "P") + (interactive "P" gnus-topic-mode) (gnus-topic-sort-groups 'gnus-group-sort-by-method reverse)) (defun gnus-topic-sort-groups-by-server (&optional reverse) "Sort the current topic alphabetically by server name. If REVERSE, sort in reverse order." - (interactive "P") + (interactive "P" gnus-topic-mode) (gnus-topic-sort-groups 'gnus-group-sort-by-server reverse)) (defun gnus-topic-sort-topics-1 (top reverse) @@ -1708,7 +1721,8 @@ If REVERSE, reverse the sorting order." (list (gnus-completing-read "Sort topics in" (mapcar #'car gnus-topic-alist) t (gnus-current-topic)) - current-prefix-arg)) + current-prefix-arg) + gnus-topic-mode) (let ((topic-topology (or (and topic (cdr (gnus-topic-find-topology topic))) gnus-topic-topology))) (gnus-topic-sort-topics-1 topic-topology reverse) @@ -1721,7 +1735,8 @@ If REVERSE, reverse the sorting order." (interactive (list (gnus-group-topic-name) - (gnus-completing-read "Move to topic" (mapcar #'car gnus-topic-alist) t))) + (gnus-completing-read "Move to topic" (mapcar #'car gnus-topic-alist) t)) + gnus-topic-mode) (unless (and current to) (error "Can't find topic")) (let ((current-top (cdr (gnus-topic-find-topology current))) diff --git a/lisp/gnus/gnus-uu.el b/lisp/gnus/gnus-uu.el index 32a8785154..bd9a1a33ec 100644 --- a/lisp/gnus/gnus-uu.el +++ b/lisp/gnus/gnus-uu.el @@ -355,7 +355,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (defun gnus-uu-decode-uu (&optional n) "Uudecodes the current article." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (gnus-uu-decode-with-method #'gnus-uu-uustrip-article n)) (defun gnus-uu-decode-uu-and-save (n dir) @@ -364,13 +364,14 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (list current-prefix-arg (file-name-as-directory (read-directory-name "Uudecode and save in dir: " - gnus-uu-default-dir - gnus-uu-default-dir t)))) + gnus-uu-default-dir + gnus-uu-default-dir t))) + gnus-article-mode gnus-summary-mode) (gnus-uu-decode-with-method #'gnus-uu-uustrip-article n dir nil nil t)) (defun gnus-uu-decode-unshar (&optional n) "Unshars the current article." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (gnus-uu-decode-with-method #'gnus-uu-unshar-article n nil nil 'scan t)) (defun gnus-uu-decode-unshar-and-save (n dir) @@ -379,8 +380,9 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (list current-prefix-arg (file-name-as-directory (read-directory-name "Unshar and save in dir: " - gnus-uu-default-dir - gnus-uu-default-dir t)))) + gnus-uu-default-dir + gnus-uu-default-dir t))) + gnus-article-mode gnus-summary-mode) (gnus-uu-decode-with-method #'gnus-uu-unshar-article n dir nil 'scan t)) (defun gnus-uu-decode-save (n file) @@ -391,7 +393,8 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (read-directory-name "Save articles in dir: " gnus-uu-default-dir gnus-uu-default-dir) (read-file-name - "Save article in file: " gnus-uu-default-dir gnus-uu-default-dir)))) + "Save article in file: " gnus-uu-default-dir gnus-uu-default-dir))) + gnus-article-mode gnus-summary-mode) (setq gnus-uu-saved-article-name file) (gnus-uu-decode-with-method #'gnus-uu-save-article n nil t)) @@ -401,8 +404,9 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (list current-prefix-arg (file-name-as-directory (read-directory-name "Unbinhex and save in dir: " - gnus-uu-default-dir - gnus-uu-default-dir)))) + gnus-uu-default-dir + gnus-uu-default-dir))) + gnus-article-mode gnus-summary-mode) (gnus-uu-initialize) (setq gnus-uu-binhex-article-name (make-temp-file (expand-file-name "binhex" gnus-uu-work-dir))) @@ -414,14 +418,15 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (list current-prefix-arg (file-name-as-directory (read-directory-name "yEnc decode and save in dir: " - gnus-uu-default-dir - gnus-uu-default-dir)))) + gnus-uu-default-dir + gnus-uu-default-dir))) + gnus-article-mode gnus-summary-mode) (setq gnus-uu-yenc-article-name nil) (gnus-uu-decode-with-method #'gnus-uu-yenc-article n dir nil t)) (defun gnus-uu-decode-uu-view (&optional n) "Uudecodes and views the current article." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) (gnus-uu-decode-uu n))) @@ -431,13 +436,14 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (list current-prefix-arg (read-file-name "Uudecode, view and save in dir: " gnus-uu-default-dir - gnus-uu-default-dir t))) + gnus-uu-default-dir t)) + gnus-article-mode gnus-summary-mode) (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) (gnus-uu-decode-uu-and-save n dir))) (defun gnus-uu-decode-unshar-view (&optional n) "Unshars and views the current article." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) (gnus-uu-decode-unshar n))) @@ -447,7 +453,8 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (list current-prefix-arg (read-file-name "Unshar, view and save in dir: " gnus-uu-default-dir - gnus-uu-default-dir t))) + gnus-uu-default-dir t)) + gnus-article-mode gnus-summary-mode) (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) (gnus-uu-decode-unshar-and-save n dir))) @@ -459,7 +466,8 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (read-directory-name "Save articles in dir: " gnus-uu-default-dir gnus-uu-default-dir) (read-file-name "Save articles in file: " - gnus-uu-default-dir gnus-uu-default-dir)))) + gnus-uu-default-dir gnus-uu-default-dir))) + gnus-article-mode gnus-summary-mode) (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) (gnus-uu-decode-save n file))) @@ -468,7 +476,8 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (interactive (list current-prefix-arg (read-file-name "Unbinhex, view and save in dir: " - gnus-uu-default-dir gnus-uu-default-dir))) + gnus-uu-default-dir gnus-uu-default-dir)) + gnus-article-mode gnus-summary-mode) (gnus-uu-initialize) (setq gnus-uu-binhex-article-name (make-temp-file (expand-file-name "binhex" gnus-uu-work-dir))) @@ -480,7 +489,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (defun gnus-uu-digest-mail-forward (&optional n post) "Digests and forwards all articles in this series." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (gnus-uu-initialize) (let ((gnus-uu-save-in-digest t) (file (make-temp-file (nnheader-concat gnus-uu-work-dir "forward"))) @@ -546,7 +555,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (defun gnus-uu-digest-post-forward (&optional n) "Digest and forward to a newsgroup." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (gnus-uu-digest-mail-forward n t)) ;; Process marking. @@ -576,7 +585,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." "Set the process mark on articles whose subjects match REGEXP. When called interactively, prompt for REGEXP. Optional UNMARK non-nil means unmark instead of mark." - (interactive "sMark (regexp): \nP") + (interactive "sMark (regexp): \nP" gnus-article-mode gnus-summary-mode) (save-excursion (let* ((articles (gnus-uu-find-articles-matching regexp)) (new-marked (gnus-new-processable unmark articles))) @@ -590,12 +599,12 @@ Optional UNMARK non-nil means unmark instead of mark." (defun gnus-uu-unmark-by-regexp (regexp) "Remove the process mark from articles whose subjects match REGEXP. When called interactively, prompt for REGEXP." - (interactive "sUnmark (regexp): ") + (interactive "sUnmark (regexp): " gnus-article-mode gnus-summary-mode) (gnus-uu-mark-by-regexp regexp t)) (defun gnus-uu-mark-series (&optional silent) "Mark the current series with the process mark." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (let* ((articles (gnus-uu-find-articles-matching)) (l (length articles))) (while articles @@ -608,7 +617,7 @@ When called interactively, prompt for REGEXP." (defun gnus-uu-mark-region (beg end &optional unmark) "Set the process mark on all articles between point and mark." - (interactive "r") + (interactive "r" gnus-article-mode gnus-summary-mode) (save-excursion (goto-char beg) (while (< (point) end) @@ -620,22 +629,22 @@ When called interactively, prompt for REGEXP." (defun gnus-uu-unmark-region (beg end) "Remove the process mark from all articles between point and mark." - (interactive "r") + (interactive "r" gnus-article-mode gnus-summary-mode) (gnus-uu-mark-region beg end t)) (defun gnus-uu-mark-buffer () "Set the process mark on all articles in the buffer." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-uu-mark-region (point-min) (point-max))) (defun gnus-uu-unmark-buffer () "Remove the process mark on all articles in the buffer." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-uu-mark-region (point-min) (point-max) t)) (defun gnus-uu-mark-thread () "Marks all articles downwards in this thread." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (gnus-save-hidden-threads (let ((level (gnus-summary-thread-level))) (while (and (gnus-summary-set-process-mark (gnus-summary-article-number)) @@ -646,7 +655,7 @@ When called interactively, prompt for REGEXP." (defun gnus-uu-unmark-thread () "Unmarks all articles downwards in this thread." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (let ((level (gnus-summary-thread-level))) (while (and (gnus-summary-remove-process-mark (gnus-summary-article-number)) @@ -656,7 +665,7 @@ When called interactively, prompt for REGEXP." (defun gnus-uu-invert-processable () "Invert the list of process-marked articles." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (let ((data gnus-newsgroup-data) number) (save-excursion @@ -669,7 +678,7 @@ When called interactively, prompt for REGEXP." (defun gnus-uu-mark-over (&optional score) "Mark all articles with a score over SCORE (the prefix)." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (let ((score (or score gnus-summary-default-score 0)) (data gnus-newsgroup-data)) (save-excursion @@ -684,7 +693,7 @@ When called interactively, prompt for REGEXP." (defun gnus-uu-mark-sparse () "Mark all series that have some articles marked." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (let ((marked (nreverse gnus-newsgroup-processable)) subject articles total headers) (unless marked @@ -708,7 +717,7 @@ When called interactively, prompt for REGEXP." (defun gnus-uu-mark-all () "Mark all articles in \"series\" order." - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (setq gnus-newsgroup-processable nil) (save-excursion (let ((data gnus-newsgroup-data) @@ -728,33 +737,33 @@ When called interactively, prompt for REGEXP." (defun gnus-uu-decode-postscript (&optional n) "Gets PostScript of the current article." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (gnus-uu-decode-with-method #'gnus-uu-decode-postscript-article n)) (defun gnus-uu-decode-postscript-view (&optional n) "Gets and views the current article." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) (gnus-uu-decode-postscript n))) (defun gnus-uu-decode-postscript-and-save (n dir) "Extracts PostScript and saves the current article." - (interactive - (list current-prefix-arg - (file-name-as-directory - (read-directory-name "Save in dir: " - gnus-uu-default-dir - gnus-uu-default-dir t)))) + (interactive (list current-prefix-arg + (file-name-as-directory + (read-directory-name "Save in dir: " + gnus-uu-default-dir + gnus-uu-default-dir t))) + gnus-article-mode gnus-summary-mode) (gnus-uu-decode-with-method #'gnus-uu-decode-postscript-article n dir nil nil t)) (defun gnus-uu-decode-postscript-and-save-view (n dir) "Decodes, views and saves the resulting file." - (interactive - (list current-prefix-arg - (read-file-name "Where do you want to save the file(s)? " - gnus-uu-default-dir - gnus-uu-default-dir t))) + (interactive (list current-prefix-arg + (read-file-name "Where do you want to save the file(s)? " + gnus-uu-default-dir + gnus-uu-default-dir t)) + gnus-article-mode gnus-summary-mode) (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) (gnus-uu-decode-postscript-and-save n dir))) diff --git a/lisp/gnus/gnus-vm.el b/lisp/gnus/gnus-vm.el index b7e6b2a889..ec3601109e 100644 --- a/lisp/gnus/gnus-vm.el +++ b/lisp/gnus/gnus-vm.el @@ -72,7 +72,7 @@ If N is a positive number, save the N next articles. If N is a negative number, save the N previous articles. If N is nil and any articles have been marked with the process mark, save those articles instead." - (interactive "P") + (interactive "P" gnus-article-mode gnus-summary-mode) (require 'gnus-art) (let ((gnus-default-article-saver 'gnus-summary-save-in-vm)) (gnus-summary-save-article arg))) @@ -80,7 +80,7 @@ save those articles instead." (declare-function vm-save-message "ext:vm-save" (folder &optional count)) (defun gnus-summary-save-in-vm (&optional folder) - (interactive) + (interactive nil gnus-article-mode gnus-summary-mode) (require 'vm) (setq folder (gnus-read-save-file-name diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index 7b94c64ae7..0334b81f0b 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el @@ -2513,7 +2513,7 @@ are always t.") '(("info" :interactive t Info-goto-node) ("qp" quoted-printable-decode-region quoted-printable-decode-string) ("ps-print" ps-print-preprint) - ("message" :interactive t + ("message" :interactive (message-mode) message-send-and-exit message-yank-original) ("babel" babel-as-string) ("nnmail" nnmail-split-fancy nnmail-article-group) @@ -2530,7 +2530,7 @@ are always t.") ("score-mode" :interactive t gnus-score-mode) ("gnus-mh" gnus-summary-save-article-folder gnus-Folder-save-name gnus-folder-save-name) - ("gnus-mh" :interactive t gnus-summary-save-in-folder) + ("gnus-mh" :interactive (gnus-summary-mode) gnus-summary-save-in-folder) ("gnus-demon" gnus-demon-add-scanmail gnus-demon-add-rescan gnus-demon-add-scan-timestamps gnus-demon-add-disconnection gnus-demon-add-handler @@ -2545,7 +2545,7 @@ are always t.") ("gnus-srvr" gnus-enter-server-buffer gnus-server-set-info gnus-server-server-name) ("gnus-srvr" gnus-browse-foreign-server) - ("gnus-cite" :interactive t + ("gnus-cite" :interactive (gnus-article-mode gnus-summary-mode) gnus-article-highlight-citation gnus-article-hide-citation-maybe gnus-article-hide-citation gnus-article-fill-cited-article gnus-article-hide-citation-in-followups @@ -2561,29 +2561,34 @@ are always t.") gnus-cache-enter-remove-article gnus-cached-article-p gnus-cache-open gnus-cache-close gnus-cache-update-article gnus-cache-articles-in-group) - ("gnus-cache" :interactive t gnus-jog-cache gnus-cache-enter-article + ("gnus-cache" :interactive (gnus-summary-mode) + gnus-summary-insert-cached-articles gnus-cache-enter-article gnus-cache-remove-article gnus-summary-insert-cached-articles) + ("gnus-cache" :interactive t gnus-jog-cache) ("gnus-score" :interactive t + gnus-score-flush-cache gnus-score-close) + ("gnus-score" :interactive (gnus-summary-mode) gnus-summary-increase-score gnus-summary-set-score gnus-summary-raise-thread gnus-summary-raise-same-subject gnus-summary-raise-score gnus-summary-raise-same-subject-and-select gnus-summary-lower-thread gnus-summary-lower-same-subject gnus-summary-lower-score gnus-summary-lower-same-subject-and-select gnus-summary-current-score gnus-score-delta-default - gnus-score-flush-cache gnus-score-close gnus-possibly-score-headers gnus-score-followup-article gnus-score-followup-thread) ("gnus-score" (gnus-summary-score-map keymap) gnus-score-save gnus-score-headers gnus-current-score-file-nondirectory gnus-score-adaptive gnus-score-find-trace gnus-score-file-name) - ("gnus-cus" :interactive t gnus-group-customize gnus-score-customize) - ("gnus-topic" :interactive t gnus-topic-mode) + ("gnus-cus" :interactive (gnus-group-mode) gnus-group-customize) + ("gnus-cus" :interactive (gnus-summary-mode) gnus-score-customize) + ("gnus-topic" :interactive (gnus-group-mode) gnus-topic-mode) ("gnus-topic" gnus-topic-remove-group gnus-topic-set-parameters gnus-subscribe-topics) - ("gnus-salt" :interactive t gnus-pick-mode gnus-binary-mode) + ("gnus-salt" :interactive (gnus-summary-mode) + gnus-pick-mode gnus-binary-mode) ("gnus-uu" (gnus-uu-extract-map keymap) (gnus-uu-mark-map keymap)) - ("gnus-uu" :interactive t + ("gnus-uu" :interactive (gnus-article-mode gnus-summary-mode) gnus-uu-digest-mail-forward gnus-uu-digest-post-forward gnus-uu-mark-series gnus-uu-mark-region gnus-uu-mark-buffer gnus-uu-mark-by-regexp gnus-uu-mark-all @@ -2598,12 +2603,13 @@ are always t.") ("gnus-uu" gnus-uu-delete-work-dir gnus-uu-unmark-thread) ("gnus-msg" (gnus-summary-send-map keymap) gnus-article-mail gnus-copy-article-buffer gnus-extended-version) - ("gnus-msg" :interactive t - gnus-group-post-news gnus-group-mail gnus-group-news + ("gnus-msg" :interactive (gnus-group-mode) + gnus-group-post-news gnus-group-mail gnus-group-news) + ("gnus-msg" :interactive (gnus-summary-mode) gnus-summary-post-news gnus-summary-news-other-window gnus-summary-followup gnus-summary-followup-with-original gnus-summary-cancel-article gnus-summary-supersede-article - gnus-post-news gnus-summary-reply gnus-summary-reply-with-original + gnus-summary-reply gnus-summary-reply-with-original gnus-summary-mail-forward gnus-summary-mail-other-window gnus-summary-resend-message gnus-summary-resend-bounced-mail gnus-summary-wide-reply gnus-summary-followup-to-mail @@ -2611,7 +2617,9 @@ are always t.") gnus-summary-wide-reply-with-original gnus-summary-post-forward gnus-summary-wide-reply-with-original gnus-summary-post-forward) - ("gnus-picon" :interactive t gnus-treat-from-picon) + ("gnus-msg" gnus-post-news) + ("gnus-picon" :interactive (gnus-article-mode gnus-summary-mode) + gnus-treat-from-picon) ("smiley" :interactive t smiley-region) ("gnus-win" gnus-configure-windows gnus-add-configuration) ("gnus-sum" gnus-summary-insert-line gnus-summary-read-group @@ -2634,7 +2642,7 @@ are always t.") gnus-request-article-this-buffer gnus-article-mode gnus-article-setup-buffer gnus-narrow-to-page gnus-article-delete-invisible-text gnus-treat-article) - ("gnus-art" :interactive t + ("gnus-art" :interactive (gnus-summary-mode gnus-article-mode) gnus-article-hide-headers gnus-article-hide-boring-headers gnus-article-treat-overstrike gnus-article-remove-cr gnus-article-remove-trailing-blank-lines @@ -2646,7 +2654,6 @@ are always t.") gnus-article-hide-pem gnus-article-hide-signature gnus-article-strip-leading-blank-lines gnus-article-date-local gnus-article-date-original gnus-article-date-lapsed - ;;gnus-article-show-all-headers gnus-article-edit-mode gnus-article-edit-article gnus-article-edit-done gnus-article-decode-encoded-words gnus-start-date-timer gnus-stop-date-timer @@ -2671,12 +2678,13 @@ are always t.") gnus-agent-store-article gnus-agent-group-covered-p) ("gnus-agent" :interactive t gnus-unplugged gnus-agentize gnus-agent-batch) - ("gnus-vm" :interactive t gnus-summary-save-in-vm + ("gnus-vm" :interactive (gnus-summary-mode) gnus-summary-save-in-vm gnus-summary-save-article-vm) ("compface" uncompface) - ("gnus-draft" :interactive t gnus-draft-mode gnus-group-send-queue) + ("gnus-draft" :interactive (gnus-summary-mode) gnus-draft-mode) + ("gnus-draft" :interactive t gnus-group-send-queue) ("gnus-mlspl" gnus-group-split gnus-group-split-fancy) - ("gnus-mlspl" :interactive t gnus-group-split-setup + ("gnus-mlspl" :interactive (gnus-group-mode) gnus-group-split-setup gnus-group-split-update) ("gnus-delay" gnus-delay-initialize)))) commit 869cdcf4e7a787534d275ca6fc0a792ab642c764 Author: Lars Ingebrigtsen Date: Sun Feb 14 14:13:38 2021 +0100 Really fix the syntax problem in define-minor-mode * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Fix interactive extension in previous change. diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 01fb58e863..7e5e2a9b8a 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -314,10 +314,10 @@ or call the function `%s'.")))) ;; repeat-command still does the toggling correctly. (if (consp interactive) `(interactive - ,interactive (list (if current-prefix-arg (prefix-numeric-value current-prefix-arg) - 'toggle))) + 'toggle)) + ,@interactive) '(interactive (list (if current-prefix-arg (prefix-numeric-value current-prefix-arg) 'toggle))))) commit 07e6b29b12c961808fcf4d8f804946056118efc5 Author: Lars Ingebrigtsen Date: Sun Feb 14 14:12:08 2021 +0100 Fix previous define-minor-mode change * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Fix interactive extension in previous change. diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 08ac818694..01fb58e863 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -313,10 +313,11 @@ or call the function `%s'.")))) ;; Use `toggle' rather than (if ,mode 0 1) so that using ;; repeat-command still does the toggling correctly. (if (consp interactive) - `(command ,interactive - (list (if current-prefix-arg - (prefix-numeric-value current-prefix-arg) - 'toggle))) + `(interactive + ,interactive + (list (if current-prefix-arg + (prefix-numeric-value current-prefix-arg) + 'toggle))) '(interactive (list (if current-prefix-arg (prefix-numeric-value current-prefix-arg) 'toggle))))) commit ffca27267822f019a0b0dc86101ef54234839e05 Author: Lars Ingebrigtsen Date: Sun Feb 14 14:08:56 2021 +0100 Mark up eww.el for correct modes * lisp/net/eww.el: Mark up all commands with applicable modes. diff --git a/lisp/net/eww.el b/lisp/net/eww.el index e39a4c33b2..c94fa03a07 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -855,7 +855,7 @@ Currently this means either text/html or application/xhtml+xml." (defun eww-view-source () "View the HTML source code of the current page." - (interactive) + (interactive nil eww-mode) (let ((buf (get-buffer-create "*eww-source*")) (source (plist-get eww-data :source))) (with-current-buffer buf @@ -881,7 +881,7 @@ Currently this means either text/html or application/xhtml+xml." (defun eww-toggle-paragraph-direction () "Cycle the paragraph direction between left-to-right, right-to-left and auto." - (interactive) + (interactive nil eww-mode) (setq bidi-paragraph-direction (cond ((eq bidi-paragraph-direction 'left-to-right) nil) @@ -899,7 +899,7 @@ Currently this means either text/html or application/xhtml+xml." This command uses heuristics to find the parts of the web page that contains the main textual portion, leaving out navigation menus and the like." - (interactive) + (interactive nil eww-mode) (let* ((old-data eww-data) (dom (with-temp-buffer (insert (plist-get old-data :source)) @@ -1038,6 +1038,7 @@ the like." ;;;###autoload (define-derived-mode eww-mode special-mode "eww" "Mode for browsing the web." + :interactive nil (setq-local eww-data (list :title "")) (setq-local browse-url-browser-function #'eww-browse-url) (add-hook 'after-change-functions #'eww-process-text-input nil t) @@ -1090,7 +1091,7 @@ instead of `browse-url-new-window-flag'." (defun eww-back-url () "Go to the previously displayed page." - (interactive) + (interactive nil eww-mode) (when (>= eww-history-position (length eww-history)) (user-error "No previous page")) (eww-save-history) @@ -1099,7 +1100,7 @@ instead of `browse-url-new-window-flag'." (defun eww-forward-url () "Go to the next displayed page." - (interactive) + (interactive nil eww-mode) (when (zerop eww-history-position) (user-error "No next page")) (eww-save-history) @@ -1123,7 +1124,7 @@ instead of `browse-url-new-window-flag'." "Go to the page marked `next'. A page is marked `next' if rel=\"next\" appears in a or tag." - (interactive) + (interactive nil eww-mode) (if (plist-get eww-data :next) (eww-browse-url (shr-expand-url (plist-get eww-data :next) (plist-get eww-data :url))) @@ -1133,7 +1134,7 @@ or tag." "Go to the page marked `previous'. A page is marked `previous' if rel=\"previous\" appears in a or tag." - (interactive) + (interactive nil eww-mode) (if (plist-get eww-data :previous) (eww-browse-url (shr-expand-url (plist-get eww-data :previous) (plist-get eww-data :url))) @@ -1143,7 +1144,7 @@ or tag." "Go to the page marked `up'. A page is marked `up' if rel=\"up\" appears in a or tag." - (interactive) + (interactive nil eww-mode) (if (plist-get eww-data :up) (eww-browse-url (shr-expand-url (plist-get eww-data :up) (plist-get eww-data :url))) @@ -1153,7 +1154,7 @@ or tag." "Go to the page marked `top'. A page is marked `top' if rel=\"start\", rel=\"home\", or rel=\"contents\" appears in a or tag." - (interactive) + (interactive nil eww-mode) (let ((best-url (or (plist-get eww-data :start) (plist-get eww-data :contents) (plist-get eww-data :home)))) @@ -1166,7 +1167,7 @@ appears in a or tag." If LOCAL is non-nil (interactively, the command was invoked with a prefix argument), don't reload the page from the network, but just re-display the HTML already fetched." - (interactive "P") + (interactive "P" eww-mode) (let ((url (plist-get eww-data :url))) (if local (if (null (plist-get eww-data :dom)) @@ -1232,12 +1233,12 @@ just re-display the HTML already fetched." (defun eww-beginning-of-text () "Move to the start of the input field." - (interactive) + (interactive nil eww-mode) (goto-char (eww-beginning-of-field))) (defun eww-end-of-text () "Move to the end of the text in the input field." - (interactive) + (interactive nil eww-mode) (goto-char (eww-end-of-field)) (let ((start (eww-beginning-of-field))) (while (and (equal (following-char) ? ) @@ -1329,7 +1330,7 @@ just re-display the HTML already fetched." (defun eww-select-file () "Change the value of the upload file menu under point." - (interactive) + (interactive nil eww-mode) (let* ((input (get-text-property (point) 'eww-form))) (let ((filename (let ((insert-default-directory t)) @@ -1537,7 +1538,9 @@ See URL `https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input'.") (defun eww-change-select (event) "Change the value of the select drop-down menu under point." - (interactive (list last-nonmenu-event)) + (interactive + (list last-nonmenu-event) + eww-mode) (mouse-set-point event) (let ((input (get-text-property (point) 'eww-form))) (popup-menu @@ -1572,7 +1575,7 @@ See URL `https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input'.") (defun eww-toggle-checkbox () "Toggle the value of the checkbox under point." - (interactive) + (interactive nil eww-mode) (let* ((input (get-text-property (point) 'eww-form)) (type (plist-get input :type))) (if (equal type "checkbox") @@ -1642,7 +1645,7 @@ See URL `https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input'.") (defun eww-submit () "Submit the current form." - (interactive) + (interactive nil eww-mode) (let* ((this-input (get-text-property (point) 'eww-form)) (form (plist-get this-input :eww-form)) values next-submit) @@ -1729,7 +1732,7 @@ See URL `https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input'.") "Browse the current URL with an external browser. The browser to used is specified by the `browse-url-secondary-browser-function' variable." - (interactive) + (interactive nil eww-mode) (funcall browse-url-secondary-browser-function (or url (plist-get eww-data :url)))) @@ -1739,7 +1742,9 @@ If EXTERNAL is single prefix, browse the URL using `browse-url-secondary-browser-function'. If EXTERNAL is double prefix, browse in new buffer." - (interactive (list current-prefix-arg last-nonmenu-event)) + (interactive + (list current-prefix-arg last-nonmenu-event) + eww-mode) (mouse-set-point mouse-event) (let ((url (get-text-property (point) 'shr-url))) (cond @@ -1773,14 +1778,14 @@ Differences in #targets are ignored." (defun eww-copy-page-url () "Copy the URL of the current page into the kill ring." - (interactive) + (interactive nil eww-mode) (message "%s" (plist-get eww-data :url)) (kill-new (plist-get eww-data :url))) (defun eww-download () "Download URL to `eww-download-directory'. Use link at point if there is one, else the current page's URL." - (interactive) + (interactive nil eww-mode) (let ((dir (if (stringp eww-download-directory) eww-download-directory (funcall eww-download-directory)))) @@ -1848,14 +1853,14 @@ Use link at point if there is one, else the current page's URL." (defun eww-set-character-encoding (charset) "Set character encoding to CHARSET. If CHARSET is nil then use UTF-8." - (interactive "zUse character set (default utf-8): ") + (interactive "zUse character set (default utf-8): " eww-mode) (if (null charset) (eww-reload nil 'utf-8) (eww-reload nil charset))) (defun eww-switch-to-buffer () "Prompt for an EWW buffer to display in the selected window." - (interactive) + (interactive nil eww-mode) (let ((completion-extra-properties '(:annotation-function (lambda (buf) (with-current-buffer buf @@ -1873,7 +1878,7 @@ If CHARSET is nil then use UTF-8." (defun eww-toggle-fonts () "Toggle whether to use monospaced or font-enabled layouts." - (interactive) + (interactive nil eww-mode) (setq shr-use-fonts (not shr-use-fonts)) (eww-reload) (message "Proportional fonts are now %s" @@ -1881,7 +1886,7 @@ If CHARSET is nil then use UTF-8." (defun eww-toggle-colors () "Toggle whether to use HTML-specified colors or not." - (interactive) + (interactive nil eww-mode) (message "Colors are now %s" (if (setq shr-use-colors (not shr-use-colors)) "on" @@ -1894,7 +1899,7 @@ If CHARSET is nil then use UTF-8." (defun eww-add-bookmark () "Bookmark the current page." - (interactive) + (interactive nil eww-mode) (eww-read-bookmarks) (dolist (bookmark eww-bookmarks) (when (equal (plist-get eww-data :url) (plist-get bookmark :url)) @@ -1958,7 +1963,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." (defun eww-bookmark-kill () "Kill the current bookmark." - (interactive) + (interactive nil eww-bookmark-mode) (let* ((start (line-beginning-position)) (bookmark (get-text-property start 'eww-bookmark)) (inhibit-read-only t)) @@ -1972,7 +1977,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." (defun eww-bookmark-yank () "Yank a previously killed bookmark to the current line." - (interactive) + (interactive nil eww-bookmark-mode) (unless eww-bookmark-kill-ring (user-error "No previously killed bookmark")) (beginning-of-line) @@ -1990,7 +1995,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." (defun eww-bookmark-browse () "Browse the bookmark under point in eww." - (interactive) + (interactive nil eww-bookmark-mode) (let ((bookmark (get-text-property (line-beginning-position) 'eww-bookmark))) (unless bookmark (user-error "No bookmark on the current line")) @@ -1999,7 +2004,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." (defun eww-next-bookmark () "Go to the next bookmark in the list." - (interactive) + (interactive nil eww-bookmark-mode) (let ((first nil) bookmark) (unless (get-buffer "*eww bookmarks*") @@ -2018,7 +2023,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." (defun eww-previous-bookmark () "Go to the previous bookmark in the list." - (interactive) + (interactive nil eww-bookmark-mode) (let ((first nil) bookmark) (unless (get-buffer "*eww bookmarks*") @@ -2061,6 +2066,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." "Mode for listing bookmarks. \\{eww-bookmark-mode-map}" + :interactive nil (buffer-disable-undo) (setq truncate-lines t)) @@ -2109,7 +2115,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." (defun eww-history-browse () "Browse the history under point in eww." - (interactive) + (interactive nil eww-history-mode) (let ((history (get-text-property (line-beginning-position) 'eww-history))) (unless history (error "No history on the current line")) @@ -2137,6 +2143,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." "Mode for listing eww-histories. \\{eww-history-mode-map}" + :interactive nil (buffer-disable-undo) (setq truncate-lines t)) @@ -2191,7 +2198,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." (defun eww-buffer-select () "Switch to eww buffer." - (interactive) + (interactive nil eww-buffers-mode) (let ((buffer (get-text-property (line-beginning-position) 'eww-buffer))) (unless buffer @@ -2211,7 +2218,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." (defun eww-buffer-show-next () "Move to next eww buffer in the list and display it." - (interactive) + (interactive nil eww-buffers-mode) (forward-line) (when (eobp) (goto-char (point-min))) @@ -2219,7 +2226,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." (defun eww-buffer-show-previous () "Move to previous eww buffer in the list and display it." - (interactive) + (interactive nil eww-buffers-mode) (beginning-of-line) (when (bobp) (goto-char (point-max))) @@ -2228,7 +2235,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." (defun eww-buffer-kill () "Kill buffer from eww list." - (interactive) + (interactive nil eww-buffers-mode) (let* ((start (line-beginning-position)) (buffer (get-text-property start 'eww-buffer)) (inhibit-read-only t)) @@ -2262,6 +2269,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." "Mode for listing buffers. \\{eww-buffers-mode-map}" + :interactive nil (buffer-disable-undo) (setq truncate-lines t)) commit 98e3ee27472d071c353743dcfc0eaef7c2f21059 Author: Lars Ingebrigtsen Date: Sun Feb 14 14:07:48 2021 +0100 Make `C-h m' list unbound commands applicable for the mode * lisp/help-fns.el (help-fns--list-local-commands): New function. (describe-mode): Use it. diff --git a/lisp/help-fns.el b/lisp/help-fns.el index b03a440412..0e2c68292c 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -1827,9 +1827,30 @@ documentation for the major and minor modes of that buffer." nil t) (help-xref-button 1 'help-function-def mode file-name))))) (princ ":\n") - (princ (help-split-fundoc (documentation major-mode) nil 'doc))))) + (princ (help-split-fundoc (documentation major-mode) nil 'doc)) + (princ (help-fns--list-local-commands))))) ;; For the sake of IELM and maybe others nil) + +(defun help-fns--list-local-commands () + (let ((functions nil)) + (mapatoms + (lambda (sym) + (when (and (commandp sym) + ;; Ignore aliases. + (not (symbolp (symbol-function sym))) + ;; Ignore everything bound. + (not (where-is-internal sym)) + (apply #'derived-mode-p (command-modes sym))) + (push sym functions)))) + (with-temp-buffer + (when functions + (setq functions (sort functions #'string<)) + (insert "\n\nOther commands for this mode, not bound to any keys:\n\n") + (dolist (function functions) + (insert (format "`%s'\n" function)))) + (buffer-string)))) + ;; Widgets. commit 40f7804ecb299a7f7c3accd19d27e2898d3b8374 Author: Lars Ingebrigtsen Date: Sun Feb 14 14:06:16 2021 +0100 Allow define-minor-mode to take an :interactive keyword * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Allow specifying the :interactive state and the modes. diff --git a/etc/NEWS b/etc/NEWS index 9c3396d33a..22c320bfa3 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2294,7 +2294,13 @@ This permanently buffer-local variable holds a list of currently enabled minor modes in the current buffer (as a list of symbols). +++ -** 'defined-derived-mode' now takes an :interactive argument. +** 'define-minor-mode' now takes an :interactive argument. +This can be used for specifying which modes this minor mode is meant +for, or to make the new minor mode non-interactive. The default value +is t. + ++++ +** 'define-derived-mode' now takes an :interactive argument. This can be used to control whether the defined mode is a command or not, and is useful when defining commands that aren't meant to be used by users directly. diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index bfffbe4bf2..08ac818694 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -172,6 +172,10 @@ BODY contains code to execute each time the mode is enabled or disabled. :lighter SPEC Same as the LIGHTER argument. :keymap MAP Same as the KEYMAP argument. :require SYM Same as in `defcustom'. +:interactive VAL Whether this mode should be a command or not. The default + is to make it one; use nil to avoid that. If VAL is a list, + it's interpreted as a list of major modes this minor mode + is useful in. :variable PLACE The location to use instead of the variable MODE to store the state of the mode. This can be simply a different named variable, or a generalized variable. @@ -226,6 +230,7 @@ For example, you could write (hook (intern (concat mode-name "-hook"))) (hook-on (intern (concat mode-name "-on-hook"))) (hook-off (intern (concat mode-name "-off-hook"))) + (interactive t) keyw keymap-sym tmp) ;; Check keys. @@ -245,6 +250,7 @@ For example, you could write (:type (setq type (list :type (pop body)))) (:require (setq require (pop body))) (:keymap (setq keymap (pop body))) + (:interactive (setq interactive (pop body))) (:variable (setq variable (pop body)) (if (not (and (setq tmp (cdr-safe variable)) (or (symbolp tmp) @@ -303,11 +309,17 @@ or call the function `%s'.")))) ;; The actual function. (defun ,modefun (&optional arg ,@extra-args) ,(easy-mmode--mode-docstring doc pretty-name keymap-sym) - ;; Use `toggle' rather than (if ,mode 0 1) so that using - ;; repeat-command still does the toggling correctly. - (interactive (list (if current-prefix-arg - (prefix-numeric-value current-prefix-arg) - 'toggle))) + ,(when interactive + ;; Use `toggle' rather than (if ,mode 0 1) so that using + ;; repeat-command still does the toggling correctly. + (if (consp interactive) + `(command ,interactive + (list (if current-prefix-arg + (prefix-numeric-value current-prefix-arg) + 'toggle))) + '(interactive (list (if current-prefix-arg + (prefix-numeric-value current-prefix-arg) + 'toggle))))) (let ((,last-message (current-message))) (,@setter (cond ((eq arg 'toggle) commit a4c8b6e7c6ccc0608fb555a1b063d3072e13e50a Author: Lars Ingebrigtsen Date: Sun Feb 14 14:00:51 2021 +0100 Fix dumping of buffers after minor_modes was added * src/pdumper.c (dump_buffer): Set minor_modes to nil before dumping. diff --git a/src/pdumper.c b/src/pdumper.c index c1388ebbb3..b68f992c33 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2692,7 +2692,7 @@ dump_hash_table (struct dump_context *ctx, static dump_off dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer) { -#if CHECK_STRUCTS && !defined HASH_buffer_99D642C1CB +#if CHECK_STRUCTS && !defined HASH_buffer_732A01EB61 # error "buffer changed. See CHECK_STRUCTS comment in config.h." #endif struct buffer munged_buffer = *in_buffer; @@ -2703,6 +2703,7 @@ dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer) buffer->window_count = 0; else eassert (buffer->window_count == -1); + buffer->minor_modes_ = Qnil; buffer->last_selected_window_ = Qnil; buffer->display_count_ = make_fixnum (0); buffer->clip_changed = 0; commit 8cdb61679e169a68829a3122d4eda7139199f7ee Author: Lars Ingebrigtsen Date: Sun Feb 14 13:57:59 2021 +0100 Revert the bit about command_modes in previous patch set * src/data.c (Fcommand_modes): Remove the subr bit -- it's not necessary since it can just use a predicate. * src/lisp.h (GCALIGNED_STRUCT): Remove command_modes. * src/lread.c (defsubr): Remove command_modes. diff --git a/src/data.c b/src/data.c index 7bddc039f6..ace859d2d0 100644 --- a/src/data.c +++ b/src/data.c @@ -961,12 +961,7 @@ The value, if non-nil, is a list of mode name symbols. */) while (SYMBOLP (fun)) fun = Fsymbol_function (fun); - if (SUBRP (fun)) - { - if (!NILP (XSUBR (fun)->command_modes)) - return XSUBR (fun)->command_modes; - } - else if (COMPILEDP (fun)) + if (COMPILEDP (fun)) { Lisp_Object form = AREF (fun, COMPILED_INTERACTIVE); if (VECTORP (form)) diff --git a/src/lisp.h b/src/lisp.h index 697dd89363..b95f389b89 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2060,7 +2060,6 @@ struct Lisp_Subr const char *symbol_name; const char *intspec; EMACS_INT doc; - Lisp_Object command_modes; } GCALIGNED_STRUCT; union Aligned_Lisp_Subr { diff --git a/src/lread.c b/src/lread.c index 8b8ba93c60..dea1b232ff 100644 --- a/src/lread.c +++ b/src/lread.c @@ -4467,7 +4467,6 @@ defsubr (union Aligned_Lisp_Subr *aname) XSETPVECTYPE (sname, PVEC_SUBR); XSETSUBR (tem, sname); set_symbol_function (sym, tem); - sname->command_modes = Qnil; } #ifdef NOTDEF /* Use fset in subr.el now! */ commit c1ef7adeb649aa99a10c4bd3b6ce988b309da3cc Author: Lars Ingebrigtsen Date: Sun Feb 14 13:56:53 2021 +0100 Add 'read-extended-command-predicate' * doc/emacs/m-x.texi (M-x): Document it. * doc/lispref/commands.texi (Interactive Call): Document it further. * lisp/simple.el (read-extended-command-predicate): New user option. (read-extended-command-predicate): Use it. (completion-in-mode-p): New function (the default predicate). diff --git a/doc/emacs/m-x.texi b/doc/emacs/m-x.texi index 865220fb21..689125e7b4 100644 --- a/doc/emacs/m-x.texi +++ b/doc/emacs/m-x.texi @@ -94,3 +94,8 @@ the command is followed by arguments. @kbd{M-x} works by running the command @code{execute-extended-command}, which is responsible for reading the name of another command and invoking it. + +@vindex read-extended-command-predicate + This command heeds the @code{read-extended-command-predicate} +variable, which will (by default) filter out commands that are not +applicable to the current major mode (or enabled minor modes). diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index d60745a825..b3bcdf35c9 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -773,6 +773,15 @@ part of the prompt. @result{} t @end group @end example + +@vindex read-extended-command-predicate +This command heeds the @code{read-extended-command-predicate} +variable, which will (by default) filter out commands that are not +applicable to the current major mode (or enabled minor modes). +@code{read-extended-command-predicate} will be called with two +parameters: The symbol that is to be included or not, and the current +buffer. If should return non-@code{nil} if the command is to be +included when completing. @end deffn @node Distinguish Interactive diff --git a/etc/NEWS b/etc/NEWS index 3b6467bf45..9c3396d33a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -251,6 +251,11 @@ commands. The new keystrokes are 'C-x x g' ('revert-buffer'), * Editing Changes in Emacs 28.1 ++++ +** New user option 'read-extended-command-predicate'. +This option controls how 'M-x TAB' performs completions. The default +predicate excludes modes for which the command is not applicable. + --- ** 'eval-expression' now no longer signals an error on incomplete expressions. Previously, typing 'M-: ( RET' would result in Emacs saying "End of diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 31c15fea90..55ce6d9426 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -455,6 +455,7 @@ negative integer or 0, nil is returned." (setq sequence (seq-drop sequence n))) (nreverse result)))) +;;;###autoload (cl-defgeneric seq-intersection (sequence1 sequence2 &optional testfn) "Return a list of the elements that appear in both SEQUENCE1 and SEQUENCE2. Equality is defined by TESTFN if non-nil or by `equal' if nil." diff --git a/lisp/simple.el b/lisp/simple.el index 9057355a7a..015fa9e4d5 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1900,55 +1900,90 @@ to get different commands to edit and resubmit." (defvar extended-command-history nil) (defvar execute-extended-command--last-typed nil) +(defcustom read-extended-command-predicate #'completion-in-mode-p + "Predicate to use to determine which commands to include when completing. +The predicate function is called with two parameter: The +symbol (i.e., command) in question that should be included or +not, and the current buffer. The predicate should return non-nil +if the command should be present when doing `M-x TAB'." + :version "28.1" + :type '(choice (const :tag "Exclude commands not relevant to this mode" + #'completion-in-mode-p) + (const :tag "All commands" (lambda (_ _) t)) + (function :tag "Other function"))) + (defun read-extended-command () - "Read command name to invoke in `execute-extended-command'." - (minibuffer-with-setup-hook - (lambda () - (add-hook 'post-self-insert-hook - (lambda () - (setq execute-extended-command--last-typed - (minibuffer-contents))) - nil 'local) - (setq-local minibuffer-default-add-function - (lambda () - ;; Get a command name at point in the original buffer - ;; to propose it after M-n. - (let ((def (with-current-buffer - (window-buffer (minibuffer-selected-window)) - (and (commandp (function-called-at-point)) - (format "%S" (function-called-at-point))))) - (all (sort (minibuffer-default-add-completions) - #'string<))) - (if def - (cons def (delete def all)) - all))))) - ;; Read a string, completing from and restricting to the set of - ;; all defined commands. Don't provide any initial input. - ;; Save the command read on the extended-command history list. - (completing-read - (concat (cond - ((eq current-prefix-arg '-) "- ") - ((and (consp current-prefix-arg) - (eq (car current-prefix-arg) 4)) "C-u ") - ((and (consp current-prefix-arg) - (integerp (car current-prefix-arg))) - (format "%d " (car current-prefix-arg))) - ((integerp current-prefix-arg) - (format "%d " current-prefix-arg))) - ;; This isn't strictly correct if `execute-extended-command' - ;; is bound to anything else (e.g. [menu]). - ;; It could use (key-description (this-single-command-keys)), - ;; but actually a prompt other than "M-x" would be confusing, - ;; because "M-x" is a well-known prompt to read a command - ;; and it serves as a shorthand for "Extended command: ". - "M-x ") - (lambda (string pred action) - (if (and suggest-key-bindings (eq action 'metadata)) - '(metadata - (affixation-function . read-extended-command--affixation) - (category . command)) - (complete-with-action action obarray string pred))) - #'commandp t nil 'extended-command-history))) + "Read command name to invoke in `execute-extended-command'. +This function uses the `read-extended-command-predicate' user option." + (let ((buffer (current-buffer))) + (minibuffer-with-setup-hook + (lambda () + (add-hook 'post-self-insert-hook + (lambda () + (setq execute-extended-command--last-typed + (minibuffer-contents))) + nil 'local) + (setq-local minibuffer-default-add-function + (lambda () + ;; Get a command name at point in the original buffer + ;; to propose it after M-n. + (let ((def + (with-current-buffer + (window-buffer (minibuffer-selected-window)) + (and (commandp (function-called-at-point)) + (format + "%S" (function-called-at-point))))) + (all (sort (minibuffer-default-add-completions) + #'string<))) + (if def + (cons def (delete def all)) + all))))) + ;; Read a string, completing from and restricting to the set of + ;; all defined commands. Don't provide any initial input. + ;; Save the command read on the extended-command history list. + (completing-read + (concat (cond + ((eq current-prefix-arg '-) "- ") + ((and (consp current-prefix-arg) + (eq (car current-prefix-arg) 4)) "C-u ") + ((and (consp current-prefix-arg) + (integerp (car current-prefix-arg))) + (format "%d " (car current-prefix-arg))) + ((integerp current-prefix-arg) + (format "%d " current-prefix-arg))) + ;; This isn't strictly correct if `execute-extended-command' + ;; is bound to anything else (e.g. [menu]). + ;; It could use (key-description (this-single-command-keys)), + ;; but actually a prompt other than "M-x" would be confusing, + ;; because "M-x" is a well-known prompt to read a command + ;; and it serves as a shorthand for "Extended command: ". + "M-x ") + (lambda (string pred action) + (if (and suggest-key-bindings (eq action 'metadata)) + '(metadata + (affixation-function . read-extended-command--affixation) + (category . command)) + (complete-with-action action obarray string pred))) + (lambda (sym) + (and (commandp sym) + (if (get sym 'completion-predicate) + (funcall (get sym 'completion-predicate) sym buffer) + (funcall read-extended-command-predicate sym buffer)))) + t nil 'extended-command-history)))) + +(defun completion-in-mode-p (symbol buffer) + "Say whether SYMBOL should be offered as a completion. +This is true if the command is applicable to the major mode in +BUFFER." + (or (null (command-modes symbol)) + ;; It's derived from a major mode. + (apply #'provided-mode-derived-p + (buffer-local-value 'major-mode buffer) + (command-modes symbol)) + ;; It's a minor mode. + (seq-intersection (command-modes symbol) + (buffer-local-value 'minor-modes buffer) + #'eq))) (defun completion-with-modes-p (modes buffer) (apply #'provided-mode-derived-p commit 2bfcd93e83d264e6b801e43bfd1a78e345b8221d Author: Lars Ingebrigtsen Date: Sun Feb 14 13:31:10 2021 +0100 Mark easy-menu-do-define menus as "not interesting" * lisp/emacs-lisp/easymenu.el (easy-menu-do-define): Mark menu keymaps as "not interesting" when doing completion. diff --git a/lisp/emacs-lisp/easymenu.el b/lisp/emacs-lisp/easymenu.el index 5303da3746..39b3193b2f 100644 --- a/lisp/emacs-lisp/easymenu.el +++ b/lisp/emacs-lisp/easymenu.el @@ -183,7 +183,10 @@ This is expected to be bound to a mouse event." :filter) 'identity) (symbol-function symbol))) - symbol))))) + symbol)))) + ;; These symbols are commands, but not interesting for users + ;; to `M-x TAB'. + (put symbol 'completion-predicate 'ignore)) (dolist (map (if (keymapp maps) (list maps) maps)) (define-key map (vector 'menu-bar (easy-menu-intern (car menu))) commit 9291e7316f98ab0858b323f72047ffd5a23d9ac9 Author: Lars Ingebrigtsen Date: Sun Feb 14 13:29:35 2021 +0100 Add new 'declare' forms for command completion predicates * doc/lispref/functions.texi (Declare Form): Document the new `completion' and `modes' declarations. * lisp/simple.el (completion-with-modes-p): New helper functions. * lisp/emacs-lisp/byte-run.el (byte-run--set-completion) (byte-run--set-modes): (defun-declarations-alist): New declarations for `completion' and `modes'. diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index 414035f684..1e3da8e3a5 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi @@ -2309,6 +2309,16 @@ form @code{(lambda (@var{arg}) @var{body})} in which case that function will additionally have access to the macro (or function)'s arguments and it will be passed to @code{gv-define-setter}. +@item (completion @var{completion-predicate}) +Declare @var{completion-predicate} as a function to determine whether +to include the symbol in the list of functions when asking for +completions in @kbd{M-x}. @var{completion-predicate} is called with +two parameters: The first parameter is the symbol, and the second is +the current buffer. + +@item (modes @var{modes}) +Specify that this command is meant to be applicable for @var{modes} +only. @end table @end defmac diff --git a/etc/NEWS b/etc/NEWS index d8f0bc6072..3b6467bf45 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2266,6 +2266,15 @@ back in Emacs 23.1. The affected functions are: 'make-obsolete', * Lisp Changes in Emacs 28.1 ++++ +** New forms to declare how completion should happen has been added. +'(declare (completion PREDICATE))' can be used as a general predicate +to say whether the command should be present when completing with +'M-x TAB'. '(declare (modes MODE...))' can be used as a short-hand +way of saying that the command should be present when completing from +buffers in major modes derived from MODE..., or, if it's a minor mode, +whether that minor mode is enabled in the current buffer. + +++ ** The 'interactive' syntax has been extended to allow listing applicable modes. Forms like '(interactive "p" dired-mode)' can be used to annotate the diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index 88f362d24f..30fcbf2b9c 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el @@ -143,6 +143,17 @@ The return value of this function is not used." (list 'function-put (list 'quote f) ''lisp-indent-function (list 'quote val)))) +(defalias 'byte-run--set-completion + #'(lambda (f _args val) + (list 'function-put (list 'quote f) + ''completion-predicate val))) + +(defalias 'byte-run--set-modes + #'(lambda (f _args val) + (list 'function-put (list 'quote f) + ''completion-predicate `(lambda (_ b) + (completion-with-modes-p ,val b))))) + ;; Add any new entries to info node `(elisp)Declare Form'. (defvar defun-declarations-alist (list @@ -159,7 +170,9 @@ This may shift errors from run-time to compile-time.") If `error-free', drop calls even if `byte-compile-delete-errors' is nil.") (list 'compiler-macro #'byte-run--set-compiler-macro) (list 'doc-string #'byte-run--set-doc-string) - (list 'indent #'byte-run--set-indent)) + (list 'indent #'byte-run--set-indent) + (list 'completion #'byte-run--set-completion) + (list 'modes #'byte-run--set-modes)) "List associating function properties to their macro expansion. Each element of the list takes the form (PROP FUN) where FUN is a function. For each (PROP . VALUES) in a function's declaration, diff --git a/lisp/simple.el b/lisp/simple.el index 0c5bcb6672..9057355a7a 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1950,6 +1950,11 @@ to get different commands to edit and resubmit." (complete-with-action action obarray string pred))) #'commandp t nil 'extended-command-history))) +(defun completion-with-modes-p (modes buffer) + (apply #'provided-mode-derived-p + (buffer-local-value 'major-mode buffer) + modes)) + (defun read-extended-command--affixation (command-names) (with-selected-window (or (minibuffer-selected-window) (selected-window)) (mapcar commit 58e0c8ee86e2c36245f1c5a1483f1c73600b4914 Author: Lars Ingebrigtsen Date: Sun Feb 14 13:21:24 2021 +0100 Extend the syntax of `interactive' to list applicable modes * doc/lispref/commands.texi (Using Interactive): Document the extended `interactive' form. * doc/lispref/loading.texi (Autoload): Document list-of-modes form. * lisp/emacs-lisp/autoload.el (make-autoload): Pick the list of modes from `interactive' out of the functions. * lisp/emacs-lisp/bytecomp.el (byte-compile-lambda): Allow for the extended `interactive' form. * src/callint.c (Finteractive): Document the extended form. * src/data.c (Finteractive_form): Return the interactive form in the old format (even when there's an extended `interactive') to avoid having other parts of Emacs be aware of this. (Fcommand_modes): New defun. * src/emacs-module.c (GCALIGNED_STRUCT): Allow for modules to return command modes. * src/lisp.h: New function module_function_command_modes. diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 3a2c7d019e..d60745a825 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -156,7 +156,7 @@ commands by adding the @code{interactive} form to them. makes a Lisp function an interactively-callable command, and how to examine a command's @code{interactive} form. -@defspec interactive arg-descriptor +@defspec interactive &optional arg-descriptor &rest modes This special form declares that a function is a command, and that it may therefore be called interactively (via @kbd{M-x} or by entering a key sequence bound to it). The argument @var{arg-descriptor} declares @@ -177,6 +177,23 @@ forms are executed; at this time, if the @code{interactive} form occurs within the body, the form simply returns @code{nil} without even evaluating its argument. +The @var{modes} list allows specifying which modes the command is +meant to be used in. This affects, for instance, completion in +@kbd{M-x} (commands won't be offered as completions if they don't +match (using @code{derived-mode-p}) the current major mode, or if the +mode is a minor mode, whether it's switched on in the current buffer). +This will also make @kbd{C-h m} list these commands (if they aren't +bound to any keys). + +For instance: + +@lisp +(interactive "p" dired-mode) +@end lisp + +This will mark the command as applicable for modes derived from +@code{dired-mode} only. + By convention, you should put the @code{interactive} form in the function body, as the first top-level form. If there is an @code{interactive} form in both the @code{interactive-form} symbol diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi index 33f3733194..8c6aeb0472 100644 --- a/doc/lispref/loading.texi +++ b/doc/lispref/loading.texi @@ -510,6 +510,9 @@ specification is not given here; it's not needed unless the user actually calls @var{function}, and when that happens, it's time to load the real definition. +If @var{interactive} is a list, it is interpreted as a list of modes +this command is applicable for. + You can autoload macros and keymaps as well as ordinary functions. Specify @var{type} as @code{macro} if @var{function} is really a macro. Specify @var{type} as @code{keymap} if @var{function} is really a diff --git a/etc/NEWS b/etc/NEWS index 08e1e94d83..d8f0bc6072 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2266,6 +2266,14 @@ back in Emacs 23.1. The affected functions are: 'make-obsolete', * Lisp Changes in Emacs 28.1 ++++ +** The 'interactive' syntax has been extended to allow listing applicable modes. +Forms like '(interactive "p" dired-mode)' can be used to annotate the +commands as being applicable for modes derived from 'dired-mode', +or if the mode is a minor mode, that the current buffer has that +minor mode activated. Note that using this form will create byte code +that is not compatible with byte code in previous Emacs versions. + +++ ** New buffer-local variable 'minor-modes'. This permanently buffer-local variable holds a list of currently diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el index ec7492dd4b..ae17039645 100644 --- a/lisp/emacs-lisp/autoload.el +++ b/lisp/emacs-lisp/autoload.el @@ -141,9 +141,12 @@ expression, in which case we want to handle forms differently." ((stringp (car-safe rest)) (car rest)))) ;; Look for an interactive spec. (interactive (pcase body - ((or `((interactive . ,_) . ,_) - `(,_ (interactive . ,_) . ,_)) - t)))) + ((or `((interactive . ,iargs) . ,_) + `(,_ (interactive . ,iargs) . ,_)) + ;; List of modes or just t. + (if (nthcdr 1 iargs) + (list 'quote (nthcdr 1 iargs)) + t))))) ;; Add the usage form at the end where describe-function-1 ;; can recover it. (when (consp args) (setq doc (help-add-fundoc-usage doc args))) @@ -207,7 +210,11 @@ expression, in which case we want to handle forms differently." easy-mmode-define-minor-mode define-minor-mode)) t) - (eq (car-safe (car body)) 'interactive)) + (and (eq (car-safe (car body)) 'interactive) + ;; List of modes or just t. + (or (if (nthcdr 1 (car body)) + (list 'quote (nthcdr 1 (car body))) + t)))) ,(if macrop ''macro nil)))) ;; For defclass forms, use `eieio-defclass-autoload'. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 89068a14f0..5c6b9c2e39 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2939,7 +2939,8 @@ for symbols generated by the byte compiler itself." ;; unless it is the last element of the body. (if (cdr body) (setq body (cdr body)))))) - (int (assq 'interactive body))) + (int (assq 'interactive body)) + command-modes) (when lexical-binding (dolist (var arglistvars) (when (assq var byte-compile--known-dynamic-vars) @@ -2951,9 +2952,10 @@ for symbols generated by the byte compiler itself." (if (eq int (car body)) (setq body (cdr body))) (cond ((consp (cdr int)) - (if (cdr (cdr int)) - (byte-compile-warn "malformed interactive spec: %s" - (prin1-to-string int))) + (unless (seq-every-p #'symbolp (cdr (cdr int))) + (byte-compile-warn "malformed interactive specc: %s" + (prin1-to-string int))) + (setq command-modes (cdr (cdr int))) ;; If the interactive spec is a call to `list', don't ;; compile it, because `call-interactively' looks at the ;; args of `list'. Actually, compile it to get warnings, @@ -2964,14 +2966,15 @@ for symbols generated by the byte compiler itself." (while (consp (cdr form)) (setq form (cdr form))) (setq form (car form))) - (if (and (eq (car-safe form) 'list) - ;; For code using lexical-binding, form is not - ;; valid lisp, but rather an intermediate form - ;; which may include "calls" to - ;; internal-make-closure (Bug#29988). - (not lexical-binding)) - nil - (setq int `(interactive ,newform))))) + (setq int + (if (and (eq (car-safe form) 'list) + ;; For code using lexical-binding, form is not + ;; valid lisp, but rather an intermediate form + ;; which may include "calls" to + ;; internal-make-closure (Bug#29988). + (not lexical-binding)) + `(interactive ,form) + `(interactive ,newform))))) ((cdr int) (byte-compile-warn "malformed interactive spec: %s" (prin1-to-string int))))) @@ -3002,9 +3005,16 @@ for symbols generated by the byte compiler itself." (list (help-add-fundoc-usage doc arglist))) ((or doc int) (list doc))) - ;; optionally, the interactive spec. - (if int - (list (nth 1 int)))))))) + ;; optionally, the interactive spec (and the modes the + ;; command applies to). + (cond + ;; We have some command modes, so use the vector form. + (command-modes + (list (vector (nth 1 int) command-modes))) + ;; No command modes, use the simple form with just the + ;; interactive spec. + (int + (list (nth 1 int))))))))) (defvar byte-compile-reserved-constants 0) diff --git a/src/callint.c b/src/callint.c index d3f49bc35d..1862463784 100644 --- a/src/callint.c +++ b/src/callint.c @@ -104,7 +104,14 @@ If the string begins with `^' and `shift-select-mode' is non-nil, Emacs first calls the function `handle-shift-selection'. You may use `@', `*', and `^' together. They are processed in the order that they appear, before reading any arguments. -usage: (interactive &optional ARG-DESCRIPTOR) */ + +If MODES is present, it should be a list of mode names (symbols) that +this command is applicable for. The main effect of this is that +`M-x TAB' (by default) won't list this command if the current buffer's +mode doesn't match the list. That is, if either the major mode isn't +derived from them, or (when it's a minor mode) the mode isn't in effect. + +usage: (interactive &optional ARG-DESCRIPTOR &rest MODES) */ attributes: const) (Lisp_Object args) { diff --git a/src/data.c b/src/data.c index 38cde0ff8b..7bddc039f6 100644 --- a/src/data.c +++ b/src/data.c @@ -904,7 +904,17 @@ Value, if non-nil, is a list (interactive SPEC). */) else if (COMPILEDP (fun)) { if (PVSIZE (fun) > COMPILED_INTERACTIVE) - return list2 (Qinteractive, AREF (fun, COMPILED_INTERACTIVE)); + { + Lisp_Object form = AREF (fun, COMPILED_INTERACTIVE); + if (VECTORP (form)) + /* The vector form is the new form, where the first + element is the interactive spec, and the second is the + command modes. */ + return list2 (Qinteractive, AREF (form, 0)); + else + /* Old form -- just the interactive spec. */ + return list2 (Qinteractive, form); + } } #ifdef HAVE_MODULES else if (MODULE_FUNCTIONP (fun)) @@ -920,10 +930,80 @@ Value, if non-nil, is a list (interactive SPEC). */) else if (CONSP (fun)) { Lisp_Object funcar = XCAR (fun); - if (EQ (funcar, Qclosure)) - return Fassq (Qinteractive, Fcdr (Fcdr (XCDR (fun)))); - else if (EQ (funcar, Qlambda)) - return Fassq (Qinteractive, Fcdr (XCDR (fun))); + if (EQ (funcar, Qclosure) + || EQ (funcar, Qlambda)) + { + Lisp_Object form = Fcdr (XCDR (fun)); + if (EQ (funcar, Qclosure)) + form = Fcdr (form); + Lisp_Object spec = Fassq (Qinteractive, form); + if (NILP (Fcdr (Fcdr (spec)))) + return spec; + else + return list2 (Qinteractive, Fcar (Fcdr (spec))); + } + } + return Qnil; +} + +DEFUN ("command-modes", Fcommand_modes, Scommand_modes, 1, 1, 0, + doc: /* Return the modes COMMAND is defined for. +If COMMAND is not a command, the return value is nil. +The value, if non-nil, is a list of mode name symbols. */) + (Lisp_Object command) +{ + Lisp_Object fun = indirect_function (command); /* Check cycles. */ + + if (NILP (fun)) + return Qnil; + + fun = command; + while (SYMBOLP (fun)) + fun = Fsymbol_function (fun); + + if (SUBRP (fun)) + { + if (!NILP (XSUBR (fun)->command_modes)) + return XSUBR (fun)->command_modes; + } + else if (COMPILEDP (fun)) + { + Lisp_Object form = AREF (fun, COMPILED_INTERACTIVE); + if (VECTORP (form)) + /* New form -- the second element is the command modes. */ + return AREF (form, 1); + else + /* Old .elc file -- no command modes. */ + return Qnil; + } +#ifdef HAVE_MODULES + else if (MODULE_FUNCTIONP (fun)) + { + Lisp_Object form + = module_function_command_modes (XMODULE_FUNCTION (fun)); + if (! NILP (form)) + return form; + } +#endif + else if (AUTOLOADP (fun)) + { + Lisp_Object modes = Fnth (make_int (3), fun); + if (CONSP (modes)) + return modes; + else + return Qnil; + } + else if (CONSP (fun)) + { + Lisp_Object funcar = XCAR (fun); + if (EQ (funcar, Qclosure) + || EQ (funcar, Qlambda)) + { + Lisp_Object form = Fcdr (XCDR (fun)); + if (EQ (funcar, Qclosure)) + form = Fcdr (form); + return Fcdr (Fcdr (Fassq (Qinteractive, form))); + } } return Qnil; } @@ -3908,6 +3988,7 @@ syms_of_data (void) defsubr (&Sindirect_variable); defsubr (&Sinteractive_form); + defsubr (&Scommand_modes); defsubr (&Seq); defsubr (&Snull); defsubr (&Stype_of); @@ -4030,6 +4111,7 @@ This variable cannot be set; trying to do so will signal an error. */); DEFSYM (Qunlet, "unlet"); DEFSYM (Qset, "set"); DEFSYM (Qset_default, "set-default"); + DEFSYM (Qcommand_modes, "command-modes"); defsubr (&Sadd_variable_watcher); defsubr (&Sremove_variable_watcher); defsubr (&Sget_variable_watchers); diff --git a/src/emacs-module.c b/src/emacs-module.c index 894dffcf21..f8fb54c072 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -549,7 +549,7 @@ struct Lisp_Module_Function union vectorlike_header header; /* Fields traced by GC; these must come first. */ - Lisp_Object documentation, interactive_form; + Lisp_Object documentation, interactive_form, command_modes; /* Fields ignored by GC. */ ptrdiff_t min_arity, max_arity; @@ -646,6 +646,12 @@ module_function_interactive_form (const struct Lisp_Module_Function *fun) return fun->interactive_form; } +Lisp_Object +module_function_command_modes (const struct Lisp_Module_Function *fun) +{ + return fun->command_modes; +} + static emacs_value module_funcall (emacs_env *env, emacs_value func, ptrdiff_t nargs, emacs_value *args) diff --git a/src/eval.c b/src/eval.c index 91fc4e6837..542d7f686e 100644 --- a/src/eval.c +++ b/src/eval.c @@ -2080,14 +2080,21 @@ then strings and vectors are not accepted. */) DEFUN ("autoload", Fautoload, Sautoload, 2, 5, 0, doc: /* Define FUNCTION to autoload from FILE. FUNCTION is a symbol; FILE is a file name string to pass to `load'. + Third arg DOCSTRING is documentation for the function. -Fourth arg INTERACTIVE if non-nil says function can be called interactively. + +Fourth arg INTERACTIVE if non-nil says function can be called +interactively. If INTERACTIVE is a list, it is interpreted as a list +of modes the function is applicable for. + Fifth arg TYPE indicates the type of the object: nil or omitted says FUNCTION is a function, `keymap' says FUNCTION is really a keymap, and `macro' or t says FUNCTION is really a macro. + Third through fifth args give info about the real definition. They default to nil. + If FUNCTION is already defined other than as an autoload, this does nothing and returns nil. */) (Lisp_Object function, Lisp_Object file, Lisp_Object docstring, Lisp_Object interactive, Lisp_Object type) diff --git a/src/lisp.h b/src/lisp.h index 0847324d1f..697dd89363 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2060,6 +2060,7 @@ struct Lisp_Subr const char *symbol_name; const char *intspec; EMACS_INT doc; + Lisp_Object command_modes; } GCALIGNED_STRUCT; union Aligned_Lisp_Subr { @@ -4221,6 +4222,8 @@ extern Lisp_Object module_function_documentation (struct Lisp_Module_Function const *); extern Lisp_Object module_function_interactive_form (const struct Lisp_Module_Function *); +extern Lisp_Object module_function_command_modes + (const struct Lisp_Module_Function *); extern module_funcptr module_function_address (struct Lisp_Module_Function const *); extern void *module_function_data (const struct Lisp_Module_Function *); diff --git a/src/lread.c b/src/lread.c index dea1b232ff..8b8ba93c60 100644 --- a/src/lread.c +++ b/src/lread.c @@ -4467,6 +4467,7 @@ defsubr (union Aligned_Lisp_Subr *aname) XSETPVECTYPE (sname, PVEC_SUBR); XSETSUBR (tem, sname); set_symbol_function (sym, tem); + sname->command_modes = Qnil; } #ifdef NOTDEF /* Use fset in subr.el now! */ commit 8d517daf770e8c6bd05e040b3bd3402626dbd9ef Author: Lars Ingebrigtsen Date: Sun Feb 14 12:52:00 2021 +0100 Fix how `shell-mode' avoids being called interactively * lisp/shell.el (shell-mode): Make noninteractive instead of erroring out after being called. diff --git a/lisp/shell.el b/lisp/shell.el index 9238ad1e8a..53f5d0b6f1 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -556,8 +556,7 @@ Variables `comint-output-filter-functions', a hook, and `comint-scroll-to-bottom-on-input' and `comint-scroll-to-bottom-on-output' control whether input and output cause the window to scroll to the end of the buffer." - (when (called-interactively-p 'any) - (error "Can't be called interactively; did you mean `shell-script-mode' instead?")) + :interactive nil (setq comint-prompt-regexp shell-prompt-pattern) (shell-completion-vars) (setq-local paragraph-separate "\\'") commit 43ecde85786ccbf4c07d535f08fd74c82a0af31b Author: Lars Ingebrigtsen Date: Sun Feb 14 12:50:19 2021 +0100 Introduce an :interactive keyword for `defined-derived-mode' * doc/lispref/modes.texi (Derived Modes): Document it. * lisp/emacs-lisp/derived.el (define-derived-mode): Introduce a new :interactive keyword. diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 3a4828c8fa..7b8ab4cb4d 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -861,6 +861,13 @@ abbrev table as @var{parent}, or @code{fundamental-mode-abbrev-table} if @var{parent} is @code{nil}. (Again, a @code{nil} value is @emph{not} equivalent to not specifying this keyword.) +@item :interactive +Modes are interactive commands by default. If you specify a +@code{nil} value, the mode defined here won't be interactive. This is +useful for modes that are never meant to be activated by users +manually, but are only supposed to be used in some specially-formatted +buffer. + @item :group If this is specified, the value should be the customization group for this mode. (Not all major modes have one.) The command diff --git a/etc/NEWS b/etc/NEWS index 7e224b411f..08e1e94d83 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2271,6 +2271,12 @@ back in Emacs 23.1. The affected functions are: 'make-obsolete', This permanently buffer-local variable holds a list of currently enabled minor modes in the current buffer (as a list of symbols). ++++ +** 'defined-derived-mode' now takes an :interactive argument. +This can be used to control whether the defined mode is a command +or not, and is useful when defining commands that aren't meant to be +used by users directly. + ** The 'values' variable is now obsolete. --- diff --git a/lisp/emacs-lisp/derived.el b/lisp/emacs-lisp/derived.el index 54528b2fb9..43d6dfd3c8 100644 --- a/lisp/emacs-lisp/derived.el +++ b/lisp/emacs-lisp/derived.el @@ -141,6 +141,9 @@ KEYWORD-ARGS: :after-hook FORM A single lisp form which is evaluated after the mode hooks have been run. It should not be quoted. + :interactive BOOLEAN + Whether the derived mode should be `interactive' or not. + The default is t. BODY: forms to execute just before running the hooks for the new mode. Do not use `interactive' here. @@ -194,6 +197,7 @@ See Info node `(elisp)Derived Modes' for more details. (declare-syntax t) (hook (derived-mode-hook-name child)) (group nil) + (interactive t) (after-hook nil)) ;; Process the keyword args. @@ -203,6 +207,7 @@ See Info node `(elisp)Derived Modes' for more details. (:abbrev-table (setq abbrev (pop body)) (setq declare-abbrev nil)) (:syntax-table (setq syntax (pop body)) (setq declare-syntax nil)) (:after-hook (setq after-hook (pop body))) + (:interactive (setq interactive (pop body))) (_ (pop body)))) (setq docstring (derived-mode-make-docstring @@ -246,7 +251,7 @@ No problems result if this variable is not bound. (defun ,child () ,docstring - (interactive) + ,(and interactive '(interactive)) ; Run the parent. (delay-mode-hooks commit 7f62faf20607394f9c6dfa0f1696cb68291f9fb7 Author: Stefan Kangas Date: Sun Feb 14 12:54:36 2021 +0100 Remove redundant :group args from textmodes/*.el * lisp/textmodes/enriched.el: * lisp/textmodes/ispell.el: * lisp/textmodes/makeinfo.el: * lisp/textmodes/paragraphs.el: * lisp/textmodes/picture.el: * lisp/textmodes/refbib.el: * lisp/textmodes/refer.el: * lisp/textmodes/remember.el: * lisp/textmodes/texinfo.el: * lisp/textmodes/tildify.el: * lisp/textmodes/two-column.el: Remove redundant :group args. diff --git a/lisp/textmodes/enriched.el b/lisp/textmodes/enriched.el index fe92d60306..c44b69cdb7 100644 --- a/lisp/textmodes/enriched.el +++ b/lisp/textmodes/enriched.el @@ -50,8 +50,7 @@ (defcustom enriched-verbose t "If non-nil, give status messages when reading and writing files." - :type 'boolean - :group 'enriched) + :type 'boolean) ;;; ;;; Set up faces & display table @@ -65,14 +64,12 @@ "Face used for text that must be shown in fixed width. Currently, Emacs can only display fixed-width fonts, but this may change. This face is used for text specifically marked as fixed-width, for example -in text/enriched files." - :group 'enriched) +in text/enriched files.") (defface excerpt '((t (:slant italic))) "Face used for text that is an excerpt from another document. -This is used in Enriched mode for text explicitly marked as an excerpt." - :group 'enriched) +This is used in Enriched mode for text explicitly marked as an excerpt.") (defconst enriched-display-table (or (copy-sequence standard-display-table) (make-display-table))) @@ -146,8 +143,7 @@ Any property that is neither on this list nor dealt with by If you set variables in this hook, you should arrange for them to be restored to their old values if you leave Enriched mode. One way to do this is to add them and their old values to `enriched-old-bindings'." - :type 'hook - :group 'enriched) + :type 'hook) (defcustom enriched-allow-eval-in-display-props nil "If non-nil allow to evaluate arbitrary forms in display properties. @@ -162,8 +158,7 @@ Note, however, that applying unsafe display properties could execute malicious Lisp code, if that code came from an external source." :risky t :type 'boolean - :version "26.1" - :group 'enriched) + :version "26.1") (defvar-local enriched-old-bindings nil "Store old variable values that we change when entering mode. diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index ea46270508..cee578fc4b 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -131,8 +131,7 @@ (defcustom ispell-highlight-p 'block "Highlight spelling errors when non-nil. When set to `block', assumes a block cursor with TTY displays." - :type '(choice (const block) (const :tag "off" nil) (const :tag "on" t)) - :group 'ispell) + :type '(choice (const block) (const :tag "off" nil) (const :tag "on" t))) (defcustom ispell-lazy-highlight (boundp 'lazy-highlight-cleanup) "Controls the lazy-highlighting of spelling errors. @@ -141,7 +140,6 @@ error is highlighted lazily using isearch lazy highlighting (see `lazy-highlight-initial-delay' and `lazy-highlight-interval')." :type 'boolean :group 'lazy-highlight - :group 'ispell :version "22.1") (defcustom ispell-highlight-face (if ispell-lazy-highlight 'isearch 'highlight) @@ -149,16 +147,14 @@ error is highlighted lazily using isearch lazy highlighting (see This variable can be set by the user to whatever face they desire. It's most convenient if the cursor color and highlight color are slightly different." - :type 'face - :group 'ispell) + :type 'face) (defcustom ispell-check-comments t "Spelling of comments checked when non-nil. When set to `exclusive', ONLY comments are checked. (For code comments). Warning! Not checking comments, when a comment start is embedded in strings, may produce undesired results." - :type '(choice (const exclusive) (const :tag "off" nil) (const :tag "on" t)) - :group 'ispell) + :type '(choice (const exclusive) (const :tag "off" nil) (const :tag "on" t))) ;;;###autoload (put 'ispell-check-comments 'safe-local-variable (lambda (a) (memq a '(nil t exclusive)))) @@ -166,8 +162,7 @@ may produce undesired results." (defcustom ispell-query-replace-choices nil "Corrections made throughout region when non-nil. Uses `query-replace' (\\[query-replace]) for corrections." - :type 'boolean - :group 'ispell) + :type 'boolean) (defcustom ispell-skip-tib nil "Does not spell check `tib' bibliography references when non-nil. @@ -177,8 +172,7 @@ Skips any text between strings matching regular expressions TeX users beware: Any text between [. and .] will be skipped -- even if that's your whole buffer -- unless you set `ispell-skip-tib' to nil. That includes the [.5mm] type of number..." - :type 'boolean - :group 'ispell) + :type 'boolean) (defvar ispell-tib-ref-beginning "[[<]\\." "Regexp matching the beginning of a Tib reference.") @@ -189,14 +183,12 @@ That includes the [.5mm] type of number..." (defcustom ispell-keep-choices-win t "If non-nil, keep the `*Choices*' window for the entire spelling session. This minimizes redisplay thrashing." - :type 'boolean - :group 'ispell) + :type 'boolean) (defcustom ispell-choices-win-default-height 2 "The default size of the `*Choices*' window, including the mode line. Must be greater than 1." - :type 'integer - :group 'ispell) + :type 'integer) (defcustom ispell-program-name (or (executable-find "aspell") @@ -211,8 +203,7 @@ Must be greater than 1." :set (lambda (symbol value) (set-default symbol value) (if (featurep 'ispell) - (ispell-set-spellchecker-params))) - :group 'ispell) + (ispell-set-spellchecker-params)))) (defcustom ispell-alternate-dictionary (cond ((file-readable-p "/usr/dict/web2") "/usr/dict/web2") @@ -224,14 +215,12 @@ Must be greater than 1." "/usr/share/lib/dict/words") ((file-readable-p "/sys/dict") "/sys/dict")) "Alternate plain word-list dictionary for spelling help." - :type '(choice file (const :tag "None" nil)) - :group 'ispell) + :type '(choice file (const :tag "None" nil))) (defcustom ispell-complete-word-dict nil "Plain word-list dictionary used for word completion if different from `ispell-alternate-dictionary'." - :type '(choice file (const :tag "None" nil)) - :group 'ispell) + :type '(choice file (const :tag "None" nil))) (defcustom ispell-message-dictionary-alist nil "List used by `ispell-message' to select a new dictionary. @@ -241,29 +230,25 @@ DICTIONARY if `ispell-local-dictionary' is not buffer-local. E.g. you may use the following value: ((\"^Newsgroups:[ \\t]*de\\\\.\" . \"deutsch8\") (\"^To:[^\\n,]+\\\\.de[ \\t\\n,>]\" . \"deutsch8\"))" - :type '(repeat (cons regexp string)) - :group 'ispell) + :type '(repeat (cons regexp string))) (defcustom ispell-message-fcc-skip 50000 "Query before saving Fcc message copy if attachment larger than this value. Always stores Fcc copy of message when nil." - :type '(choice integer (const :tag "off" nil)) - :group 'ispell) + :type '(choice integer (const :tag "off" nil))) (defcustom ispell-grep-command "grep" "Name of the grep command for search processes." - :type 'string - :group 'ispell) + :type 'string) (defcustom ispell-grep-options "-Ei" "String of options to use when running the program in `ispell-grep-command'. Should probably be \"-Ei\"." - :type 'string - :group 'ispell) + :type 'string) (defcustom ispell-look-command (cond ((file-exists-p "/bin/look") "/bin/look") @@ -272,36 +257,30 @@ Should probably be \"-Ei\"." (t "look")) "Name of the look command for search processes. This must be an absolute file name." - :type 'file - :group 'ispell) + :type 'file) (defcustom ispell-look-p (file-exists-p ispell-look-command) "Non-nil means use `look' rather than `grep'. Default is based on whether `look' seems to be available." - :type 'boolean - :group 'ispell) + :type 'boolean) (defcustom ispell-have-new-look nil "Non-nil means use the `-r' option (regexp) when running `look'." - :type 'boolean - :group 'ispell) + :type 'boolean) (defcustom ispell-look-options (if ispell-have-new-look "-dfr" "-df") "String of command options for `ispell-look-command'." - :type 'string - :group 'ispell) + :type 'string) (defcustom ispell-use-ptys-p nil "When non-nil, Emacs uses ptys to communicate with Ispell. When nil, Emacs uses pipes." - :type 'boolean - :group 'ispell) + :type 'boolean) (defcustom ispell-following-word nil "Non-nil means `ispell-word' checks the word around or after point. Otherwise `ispell-word' checks the preceding word." - :type 'boolean - :group 'ispell) + :type 'boolean) (defcustom ispell-help-in-bufferp nil "Non-nil means display interactive keymap help in a buffer. @@ -312,21 +291,18 @@ The following values are supported: for a couple of seconds. electric Pop up a new buffer and display a long help message there. User can browse and then exit the help mode." - :type '(choice (const electric) (const :tag "off" nil) (const :tag "on" t)) - :group 'ispell) + :type '(choice (const electric) (const :tag "off" nil) (const :tag "on" t))) (defcustom ispell-quietly nil "Non-nil means suppress messages in `ispell-word'." - :type 'boolean - :group 'ispell) + :type 'boolean) (defvaralias 'ispell-format-word 'ispell-format-word-function) (defcustom ispell-format-word-function (function upcase) "Formatting function for displaying word being spell checked. The function must take one string argument and return a string." - :type 'function - :group 'ispell) + :type 'function) ;; FIXME framepop.el last updated c 2003 (?), ;; use posframe. @@ -335,21 +311,18 @@ The function must take one string argument and return a string." You can set this variable to dynamically use framepop if you are in a window system by evaluating the following on startup to set this variable: (and (display-graphic-p) (require \\='framepop nil t))" - :type 'boolean - :group 'ispell) + :type 'boolean) ;;;###autoload (defcustom ispell-personal-dictionary nil "File name of your personal spelling dictionary, or nil. If nil, the default personal dictionary for your spelling checker is used." :type '(choice file - (const :tag "default" nil)) - :group 'ispell) + (const :tag "default" nil))) (defcustom ispell-silently-savep nil "When non-nil, save personal dictionary without asking for confirmation." - :type 'boolean - :group 'ispell) + :type 'boolean) (defvar-local ispell-local-dictionary-overridden nil "Non-nil means the user has explicitly set this buffer's Ispell dictionary.") @@ -366,8 +339,7 @@ calling \\[ispell-change-dictionary] with that value. This variable is automatically set when defined in the file with either `ispell-dictionary-keyword' or the Local Variable syntax." :type '(choice string - (const :tag "default" nil)) - :group 'ispell) + (const :tag "default" nil))) ;;;###autoload (put 'ispell-local-dictionary 'safe-local-variable 'string-or-null-p) @@ -376,16 +348,14 @@ is automatically set when defined in the file with either (defcustom ispell-dictionary nil "Default dictionary to use if `ispell-local-dictionary' is nil." :type '(choice string - (const :tag "default" nil)) - :group 'ispell) + (const :tag "default" nil))) (defcustom ispell-extra-args nil "If non-nil, a list of extra switches to pass to the Ispell program. For example, (\"-W\" \"3\") to cause it to accept all 1-3 character words as correct. See also `ispell-dictionary-alist', which may be used for language-specific arguments." - :type '(repeat string) - :group 'ispell) + :type '(repeat string)) @@ -400,8 +370,7 @@ such as \"&\". See `ispell-html-skip-alists' for more details. This variable affects spell-checking of HTML, XML, and SGML files." :type '(choice (const :tag "always" t) (const :tag "never" nil) - (const :tag "use-mode-name" use-mode-name)) - :group 'ispell) + (const :tag "use-mode-name" use-mode-name))) (make-variable-buffer-local 'ispell-skip-html) @@ -427,8 +396,7 @@ re-start Emacs." (const "~nroff") (const "~list") (const "~latin1") (const "~latin3") (const :tag "default" nil)) - (coding-system :tag "Coding System"))) - :group 'ispell) + (coding-system :tag "Coding System")))) (defvar ispell-dictionary-base-alist diff --git a/lisp/textmodes/makeinfo.el b/lisp/textmodes/makeinfo.el index e48649bae3..f63894b815 100644 --- a/lisp/textmodes/makeinfo.el +++ b/lisp/textmodes/makeinfo.el @@ -59,16 +59,14 @@ (defcustom makeinfo-run-command "makeinfo" "Command used to run `makeinfo' subjob. The name of the file is appended to this string, separated by a space." - :type 'string - :group 'makeinfo) + :type 'string) (defcustom makeinfo-options "--fill-column=70" "String containing options for running `makeinfo'. Do not include `--footnote-style' or `--paragraph-indent'; the proper way to specify those is with the Texinfo commands `@footnotestyle' and `@paragraphindent'." - :type 'string - :group 'makeinfo) + :type 'string) (require 'texinfo) diff --git a/lisp/textmodes/paragraphs.el b/lisp/textmodes/paragraphs.el index 96edfd6de3..472c406961 100644 --- a/lisp/textmodes/paragraphs.el +++ b/lisp/textmodes/paragraphs.el @@ -96,7 +96,6 @@ lines that start paragraphs from lines that separate them. If the variable `use-hard-newlines' is non-nil, then only lines following a hard newline are considered to match." - :group 'paragraphs :type 'regexp) (put 'paragraph-start 'safe-local-variable 'stringp) @@ -114,7 +113,6 @@ This is matched against the text at the left margin, which is not necessarily the beginning of the line, so it should not use \"^\" as an anchor. This ensures that the paragraph functions will work equally within a region of text indented by a margin setting." - :group 'paragraphs :type 'regexp) (put 'paragraph-separate 'safe-local-variable 'stringp) @@ -149,7 +147,6 @@ regexp describing the end of a sentence, when the value of the variable This value is used by the function `sentence-end' to construct the regexp describing the end of a sentence, when the value of the variable `sentence-end' is nil. See Info node `(elisp)Standard Regexps'." - :group 'paragraphs :type 'string) (put 'sentence-end-without-space 'safe-local-variable 'stringp) @@ -161,13 +158,11 @@ All paragraph boundaries also end sentences, regardless. The value nil means to use the default value defined by the function `sentence-end'. You should always use this function to obtain the value of this variable." - :group 'paragraphs :type '(choice regexp (const :tag "Use default value" nil))) (put 'sentence-end 'safe-local-variable 'string-or-null-p) (defcustom sentence-end-base "[.?!…‽][]\"'”’)}»›]*" "Regexp matching the basic end of a sentence, not including following space." - :group 'paragraphs :type 'regexp :version "25.1") (put 'sentence-end-base 'safe-local-variable 'stringp) @@ -197,14 +192,12 @@ in between. See Info node `(elisp)Standard Regexps'." (defcustom page-delimiter "^\014" "Regexp describing line-beginnings that separate pages." - :group 'paragraphs :type 'regexp) (put 'page-delimiter 'safe-local-variable 'stringp) (defcustom paragraph-ignore-fill-prefix nil "Non-nil means the paragraph commands are not affected by `fill-prefix'. This is desirable in modes where blank lines are the paragraph delimiters." - :group 'paragraphs :type 'boolean) (put 'paragraph-ignore-fill-prefix 'safe-local-variable 'booleanp) diff --git a/lisp/textmodes/picture.el b/lisp/textmodes/picture.el index 3cb1043545..1368af01ba 100644 --- a/lisp/textmodes/picture.el +++ b/lisp/textmodes/picture.el @@ -37,28 +37,22 @@ (defcustom picture-rectangle-ctl ?+ "Character `picture-draw-rectangle' uses for top left corners." - :type 'character - :group 'picture) + :type 'character) (defcustom picture-rectangle-ctr ?+ "Character `picture-draw-rectangle' uses for top right corners." - :type 'character - :group 'picture) + :type 'character) (defcustom picture-rectangle-cbr ?+ "Character `picture-draw-rectangle' uses for bottom right corners." - :type 'character - :group 'picture) + :type 'character) (defcustom picture-rectangle-cbl ?+ "Character `picture-draw-rectangle' uses for bottom left corners." - :type 'character - :group 'picture) + :type 'character) (defcustom picture-rectangle-v ?| "Character `picture-draw-rectangle' uses for vertical lines." - :type 'character - :group 'picture) + :type 'character) (defcustom picture-rectangle-h ?- "Character `picture-draw-rectangle' uses for horizontal lines." - :type 'character - :group 'picture) + :type 'character) ;; Picture Movement Commands @@ -409,8 +403,7 @@ character `\\' in the set it must be preceded by itself: \"\\\\\". The command \\[picture-tab-search] is defined to move beneath (or to) a character belonging to this set independent of the tab stops list." - :type 'string - :group 'picture) + :type 'string) (defun picture-set-tab-stops (&optional arg) "Set value of `tab-stop-list' according to context of this line. @@ -682,8 +675,7 @@ Leaves the region surrounding the rectangle." (defcustom picture-mode-hook nil "If non-nil, its value is called on entry to Picture mode. Picture mode is invoked by the command \\[picture-mode]." - :type 'hook - :group 'picture) + :type 'hook) (defvar picture-mode-old-local-map) (defvar picture-mode-old-mode-name) diff --git a/lisp/textmodes/refbib.el b/lisp/textmodes/refbib.el index bff57128c5..2f3e0243ef 100644 --- a/lisp/textmodes/refbib.el +++ b/lisp/textmodes/refbib.el @@ -65,8 +65,7 @@ (defcustom r2b-trace-on nil "Non-nil means trace conversion." - :type 'boolean - :group 'refbib) + :type 'boolean) (defcustom r2b-journal-abbrevs '( @@ -83,8 +82,7 @@ letter, even if it really doesn't. \(\"Ijcai81\" \"ijcai7\")) would expand Aij to the text string \"Artificial Intelligence\", but would replace Ijcai81 with the BibTeX macro \"ijcai7\"." - :type '(repeat (list string string)) - :group 'refbib) + :type '(repeat (list string string))) (defcustom r2b-booktitle-abbrevs '( @@ -101,8 +99,7 @@ should be listed as beginning with a capital letter, even if it doesn't. \(\"Ijcai81\" \"ijcai7\")) would expand Aij to the text string \"Artificial Intelligence\", but would replace Ijcai81 with the BibTeX macro \"ijcai7\"." - :type '(repeat (list string string)) - :group 'refbib) + :type '(repeat (list string string))) (defcustom r2b-proceedings-list '() @@ -119,8 +116,7 @@ a conference, and its expansion is the BibTeX macro \"ijcai7\". Then expansion were \"Proceedings of the Seventh International Conference on Artificial Intelligence\", then you would NOT need to include Ijcai81 in `r2b-proceedings-list' (although it wouldn't cause an error)." - :type '(repeat (list string string)) - :group 'refbib) + :type '(repeat (list string string))) (defvar r2b-additional-stop-words "Some\\|What" @@ -129,8 +125,7 @@ This is in addition to the `r2b-capitalize-title-stop-words'.") (defcustom r2b-delimit-with-quote t "If true, then use \" to delimit fields, otherwise use braces." - :type 'boolean - :group 'refbib) + :type 'boolean) ;********************************************************** ; Utility Functions @@ -205,13 +200,11 @@ This is in addition to the `r2b-capitalize-title-stop-words'.") (defcustom r2b-out-buf-name "*Out*" "Name of buffer for output from refer-to-bibtex." - :type 'string - :group 'refbib) + :type 'string) (defcustom r2b-log-name "*Log*" "Name of buffer for logs errors from refer-to-bibtex." - :type 'string - :group 'refbib) + :type 'string) (defvar r2b-in-buf nil) (defvar r2b-out-buf nil) diff --git a/lisp/textmodes/refer.el b/lisp/textmodes/refer.el index ae1f778168..c2bf90f37b 100644 --- a/lisp/textmodes/refer.el +++ b/lisp/textmodes/refer.el @@ -91,8 +91,7 @@ the default search path. Since Refer does not know that default path, it cannot search it. Include that path explicitly in your BIBINPUTS environment if you really want it searched (which is not likely to happen anyway)." - :type '(choice (repeat directory) (const bibinputs) (const texinputs)) - :group 'refer) + :type '(choice (repeat directory) (const bibinputs) (const texinputs))) (defcustom refer-bib-files 'dir "List of \\.bib files to search for references, @@ -110,16 +109,14 @@ If `refer-bib-files' is nil, auto or dir, it is setq'd to the appropriate list of files when it is first used if `refer-cache-bib-files' is t. If `refer-cache-bib-files' is nil, the list of \\.bib files to use is re-read each time it is needed." - :type '(choice (repeat file) (const nil) (const auto) (const dir)) - :group 'refer) + :type '(choice (repeat file) (const nil) (const auto) (const dir))) (defcustom refer-cache-bib-files t "Variable determining whether the value of `refer-bib-files' should be cached. If t, initialize the value of refer-bib-files the first time it is used. If nil, re-read the list of \\.bib files depending on the value of `refer-bib-files' each time it is needed." - :type 'boolean - :group 'refer) + :type 'boolean) (defcustom refer-bib-files-regexp "\\\\bibliography" "Regexp matching a bibliography file declaration. @@ -131,8 +128,7 @@ command is expected to specify a file name, or a list of comma-separated file names, within curly braces. If a specified file doesn't exist and has no extension, a \\.bib extension is automatically tried." - :type 'regexp - :group 'refer) + :type 'regexp) (make-variable-buffer-local 'refer-bib-files) (make-variable-buffer-local 'refer-cache-bib-files) diff --git a/lisp/textmodes/remember.el b/lisp/textmodes/remember.el index 820ee38d10..6a72ebb332 100644 --- a/lisp/textmodes/remember.el +++ b/lisp/textmodes/remember.el @@ -193,24 +193,20 @@ (defcustom remember-mode-hook nil "Functions run upon entering `remember-mode'." :type 'hook - :options '(flyspell-mode turn-on-auto-fill org-remember-apply-template) - :group 'remember) + :options '(flyspell-mode turn-on-auto-fill org-remember-apply-template)) (defcustom remember-in-new-frame nil "Non-nil means use a separate frame for capturing remember data." - :type 'boolean - :group 'remember) + :type 'boolean) (defcustom remember-register ?R "The register in which the window configuration is stored." - :type 'character - :group 'remember) + :type 'character) (defcustom remember-filter-functions nil "Functions run to filter remember data. All functions are run in the remember buffer." - :type 'hook - :group 'remember) + :type 'hook) (defcustom remember-handler-functions '(remember-append-to-file) "Functions run to process remember data. @@ -223,13 +219,11 @@ recorded somewhere by that function." remember-append-to-file remember-store-in-files remember-diary-extract-entries - org-remember-handler) - :group 'remember) + org-remember-handler)) (defcustom remember-all-handler-functions nil "If non-nil every function in `remember-handler-functions' is called." - :type 'boolean - :group 'remember) + :type 'boolean) ;; See below for more user variables. @@ -240,16 +234,14 @@ recorded somewhere by that function." (defcustom remember-save-after-remembering t "Non-nil means automatically save after remembering." - :type 'boolean - :group 'remember) + :type 'boolean) ;;; User Functions: (defcustom remember-annotation-functions '(buffer-file-name) "Hook that returns an annotation to be inserted into the remember buffer." :type 'hook - :options '(org-remember-annotation buffer-file-name) - :group 'remember) + :options '(org-remember-annotation buffer-file-name)) (defvar remember-annotation nil "Current annotation.") @@ -258,13 +250,11 @@ recorded somewhere by that function." (defcustom remember-before-remember-hook nil "Functions run before switching to the *Remember* buffer." - :type 'hook - :group 'remember) + :type 'hook) (defcustom remember-run-all-annotation-functions-flag nil "Non-nil means use all annotations returned by `remember-annotation-functions'." - :type 'boolean - :group 'remember) + :type 'boolean) ;;;###autoload (defun remember (&optional initial) @@ -337,13 +327,11 @@ With a prefix or a visible region, use the region as INITIAL." (defcustom remember-mailbox "~/Mail/remember" "The file in which to store remember data as mail." - :type 'file - :group 'remember) + :type 'file) (defcustom remember-default-priority "medium" "The default priority for remembered mail messages." - :type 'string - :group 'remember) + :type 'string) (defun remember-store-in-mailbox () "Store remember data as if it were incoming mail. @@ -396,19 +384,16 @@ exists) might be changed." (with-current-buffer buf (set-visited-file-name (expand-file-name remember-data-file)))))) - :initialize 'custom-initialize-default - :group 'remember) + :initialize 'custom-initialize-default) (defcustom remember-leader-text "** " "The text used to begin each remember item." - :type 'string - :group 'remember) + :type 'string) (defcustom remember-time-format "%a %b %d %H:%M:%S %Y" "The format for time stamp, passed to `format-time-string'. The default emulates `current-time-string' for backward compatibility." :type 'string - :group 'remember :version "27.1") (defcustom remember-text-format-function nil @@ -416,7 +401,6 @@ The default emulates `current-time-string' for backward compatibility." The function receives the remembered text as argument and should return the text to be remembered." :type '(choice (const nil) function) - :group 'remember :version "28.1") (defun remember-append-to-file () @@ -465,16 +449,14 @@ If you want to remember a region, supply a universal prefix to "The directory in which to store remember data as files. Used by `remember-store-in-files'." :type 'directory - :version "24.4" - :group 'remember) + :version "24.4") (defcustom remember-directory-file-name-format "%Y-%m-%d_%T-%z" "Format string for the file name in which to store unprocessed data. This is passed to `format-time-string'. Used by `remember-store-in-files'." :type 'string - :version "24.4" - :group 'remember) + :version "24.4") (defun remember-store-in-files () "Store remember data in a file in `remember-data-directory'. @@ -511,8 +493,7 @@ Most useful for remembering things from other applications." (defcustom remember-diary-file nil "File for extracted diary entries. If this is nil, then `diary-file' will be used instead." - :type '(choice (const :tag "diary-file" nil) file) - :group 'remember) + :type '(choice (const :tag "diary-file" nil) file)) (defvar calendar-date-style) ; calendar.el diff --git a/lisp/textmodes/texinfo.el b/lisp/textmodes/texinfo.el index 7799cdb552..278cd0cd84 100644 --- a/lisp/textmodes/texinfo.el +++ b/lisp/textmodes/texinfo.el @@ -54,20 +54,17 @@ ;;;###autoload (defcustom texinfo-open-quote (purecopy "``") "String inserted by typing \\[texinfo-insert-quote] to open a quotation." - :type 'string - :group 'texinfo) + :type 'string) ;;;###autoload (defcustom texinfo-close-quote (purecopy "''") "String inserted by typing \\[texinfo-insert-quote] to close a quotation." - :type 'string - :group 'texinfo) + :type 'string) (defcustom texinfo-mode-hook nil "Normal hook run when entering Texinfo mode." :type 'hook - :options '(turn-on-auto-fill flyspell-mode) - :group 'texinfo) + :options '(turn-on-auto-fill flyspell-mode)) ;;; Autoloads: @@ -349,8 +346,7 @@ Subexpression 1 is what goes into the corresponding `@end' statement.") (defface texinfo-heading '((t (:inherit font-lock-function-name-face))) - "Face used for section headings in `texinfo-mode'." - :group 'texinfo) + "Face used for section headings in `texinfo-mode'.") (defvar texinfo-font-lock-keywords `(;; All but the first had an OVERRIDE of t. @@ -962,32 +958,27 @@ to jump to the corresponding spot in the Texinfo source file." (defcustom texinfo-texi2dvi-command "texi2dvi" "Command used by `texinfo-tex-buffer' to run TeX and texindex on a buffer." - :type 'string - :group 'texinfo) + :type 'string) (defcustom texinfo-texi2dvi-options "" "Command line options for `texinfo-texi2dvi-command'." :type 'string - :group 'texinfo :version "28.1") (defcustom texinfo-tex-command "tex" "Command used by `texinfo-tex-region' to run TeX on a region." - :type 'string - :group 'texinfo) + :type 'string) (defcustom texinfo-texindex-command "texindex" "Command used by `texinfo-texindex' to sort unsorted index files." - :type 'string - :group 'texinfo) + :type 'string) (defcustom texinfo-delete-from-print-queue-command "lprm" "Command string used to delete a job from the line printer queue. Command is used by \\[texinfo-delete-from-print-queue] based on number provided by a previous \\[tex-show-print-queue] command." - :type 'string - :group 'texinfo) + :type 'string) (defvar texinfo-tex-trailer "@bye" "String appended after a region sent to TeX by `texinfo-tex-region'.") diff --git a/lisp/textmodes/tildify.el b/lisp/textmodes/tildify.el index 33a976aa7b..1d90562ae2 100644 --- a/lisp/textmodes/tildify.el +++ b/lisp/textmodes/tildify.el @@ -66,7 +66,6 @@ non-capturing groups can be used for grouping prior to the part of the regexp matching the white space). The pattern is matched case-sensitive regardless of the value of `case-fold-search' setting." :version "25.1" - :group 'tildify :type 'regexp :safe t) @@ -90,7 +89,6 @@ by the hard space character. The form (MAJOR-MODE . SYMBOL) defines alias item for MAJOR-MODE. For this mode, the item for the mode SYMBOL is looked up in the alist instead." - :group 'tildify :type '(repeat (cons :tag "Entry for major mode" (choice (const :tag "Default" t) (symbol :tag "Major mode")) @@ -110,7 +108,6 @@ might be used for other modes if compatible encoding is used. If nil, current major mode has no way to represent a hard space." :version "25.1" - :group 'tildify :type '(choice (const :tag "Space character (no hard-space representation)" " ") (const :tag "No-break space (U+00A0)" "\u00A0") @@ -133,7 +130,6 @@ STRING defines the hard space, which is inserted at places defined by The form (MAJOR-MODE . SYMBOL) defines alias item for MAJOR-MODE. For this mode, the item for the mode SYMBOL is looked up in the alist instead." - :group 'tildify :type '(repeat (cons :tag "Entry for major mode" (choice (const :tag "Default" t) (symbol :tag "Major mode")) @@ -164,7 +160,6 @@ or better still: See `tildify-foreach-ignore-environments' function for other ways to use the variable." :version "25.1" - :group 'tildify :type 'function) (defcustom tildify-ignored-environments-alist () @@ -183,7 +178,6 @@ MAJOR-MODE defines major mode, for which the item applies. It can be either: See `tildify-foreach-ignore-environments' function for description of BEG-REGEX and END-REGEX." - :group 'tildify :type '(repeat (cons :tag "Entry for major mode" (choice (const :tag "Default" t) @@ -416,19 +410,16 @@ If the pattern matches `looking-back', a hard space needs to be inserted instead of a space at point. The regexp is always case sensitive, regardless of the current `case-fold-search' setting." :version "25.1" - :group 'tildify :type 'regexp) (defcustom tildify-space-predicates '(tildify-space-region-predicate) "A list of predicate functions for `tildify-space' function." :version "25.1" - :group 'tildify :type '(repeat function)) (defcustom tildify-double-space-undos t "Weather `tildify-space' should undo hard space when space is typed again." :version "25.1" - :group 'tildify :type 'boolean) ;;;###autoload diff --git a/lisp/textmodes/two-column.el b/lisp/textmodes/two-column.el index d072ab16c3..9c0ed8fbd5 100644 --- a/lisp/textmodes/two-column.el +++ b/lisp/textmodes/two-column.el @@ -133,26 +133,22 @@ '("-%*- %15b --" (-3 . "%p") "--%[(" mode-name minor-mode-alist "%n" mode-line-process ")%]%-") "Value of `mode-line-format' for a buffer in two-column minor mode." - :type 'sexp - :group 'two-column) + :type 'sexp) (defcustom 2C-other-buffer-hook 'text-mode "Hook run in new buffer when it is associated with current one." - :type 'function - :group 'two-column) + :type 'function) (defcustom 2C-separator "" "A string inserted between the two columns when merging. This gets set locally by \\[2C-split]." - :type 'string - :group 'two-column) + :type 'string) (put '2C-separator 'permanent-local t) (defcustom 2C-window-width 40 "The width of the first column. (Must be at least `window-min-width'.) This value is local for every buffer that sets it." - :type 'integer - :group 'two-column) + :type 'integer) (make-variable-buffer-local '2C-window-width) (put '2C-window-width 'permanent-local t) @@ -160,13 +156,11 @@ This value is local for every buffer that sets it." "Base for calculating `fill-column' for a buffer in two-column minor mode. The value of `fill-column' becomes `2C-window-width' for this buffer minus this value." - :type 'integer - :group 'two-column) + :type 'integer) (defcustom 2C-autoscroll t "If non-nil, Emacs attempts to keep the two column's buffers aligned." - :type 'boolean - :group 'two-column) + :type 'boolean) (defvar 2C-mode-map commit 760910f4917ad8ff5e1cd1bf0bfec443b02f0e44 Author: Lars Ingebrigtsen Date: Sun Feb 14 12:37:44 2021 +0100 Add a new buffer-local variable `minor-modes' * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Keep `minor-modes' updated. * src/buffer.c (bset_minor_modes, Fmake_indirect_buffer) (reset_buffer, init_buffer_once): Initialise `minor-modes'. (syms_of_buffer): Add `minor-modes' as a new permanently-local variable. * src/buffer.h (struct buffer): Add minor_modes_. diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 3c64e97b3b..3a4828c8fa 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -1454,6 +1454,11 @@ used only with Diff mode. other minor modes in effect. It should be possible to activate and deactivate minor modes in any order. +@defvar minor-modes +This buffer-local variable lists the currently enabled minor modes in +the current buffer, and is a list if symbols. +@end defvar + @defvar minor-mode-list The value of this variable is a list of all minor mode commands. @end defvar diff --git a/etc/NEWS b/etc/NEWS index d865aa7c74..7e224b411f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2266,6 +2266,11 @@ back in Emacs 23.1. The affected functions are: 'make-obsolete', * Lisp Changes in Emacs 28.1 ++++ +** New buffer-local variable 'minor-modes'. +This permanently buffer-local variable holds a list of currently +enabled minor modes in the current buffer (as a list of symbols). + ** The 'values' variable is now obsolete. --- diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 2916ae4ade..bfffbe4bf2 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -317,6 +317,10 @@ or call the function `%s'.")))) nil) (t t))) + ;; Keep `minor-modes' up to date. + (setq minor-modes (delq ',modefun minor-modes)) + (when ,getter + (push ',modefun minor-modes)) ,@body ;; The on/off hooks are here for backward compatibility only. (run-hooks ',hook (if ,getter ',hook-on ',hook-off)) diff --git a/src/buffer.c b/src/buffer.c index 80c799e719..487599dbbe 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -292,6 +292,11 @@ bset_major_mode (struct buffer *b, Lisp_Object val) b->major_mode_ = val; } static void +bset_minor_modes (struct buffer *b, Lisp_Object val) +{ + b->minor_modes_ = val; +} +static void bset_mark (struct buffer *b, Lisp_Object val) { b->mark_ = val; @@ -893,6 +898,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */) bset_file_truename (b, Qnil); bset_display_count (b, make_fixnum (0)); bset_backed_up (b, Qnil); + bset_minor_modes (b, Qnil); bset_auto_save_file_name (b, Qnil); set_buffer_internal_1 (b); Fset (intern ("buffer-save-without-query"), Qnil); @@ -967,6 +973,7 @@ reset_buffer (register struct buffer *b) b->clip_changed = 0; b->prevent_redisplay_optimizations_p = 1; bset_backed_up (b, Qnil); + bset_minor_modes (b, Qnil); BUF_AUTOSAVE_MODIFF (b) = 0; b->auto_save_failure_time = 0; bset_auto_save_file_name (b, Qnil); @@ -5151,6 +5158,7 @@ init_buffer_once (void) bset_auto_save_file_name (&buffer_local_flags, make_fixnum (-1)); bset_read_only (&buffer_local_flags, make_fixnum (-1)); bset_major_mode (&buffer_local_flags, make_fixnum (-1)); + bset_minor_modes (&buffer_local_flags, make_fixnum (-1)); bset_mode_name (&buffer_local_flags, make_fixnum (-1)); bset_undo_list (&buffer_local_flags, make_fixnum (-1)); bset_mark_active (&buffer_local_flags, make_fixnum (-1)); @@ -5617,6 +5625,11 @@ The default value (normally `fundamental-mode') affects new buffers. A value of nil means to use the current buffer's major mode, provided it is not marked as "special". */); + DEFVAR_PER_BUFFER ("minor-modes", &BVAR (current_buffer, minor_modes), + Qnil, + doc: /* Minor modes currently active in the current buffer. +This is a list of symbols, or nil if there are no minor modes active. */); + DEFVAR_PER_BUFFER ("mode-name", &BVAR (current_buffer, mode_name), Qnil, doc: /* Pretty name of current buffer's major mode. diff --git a/src/buffer.h b/src/buffer.h index 790291f118..0668d16608 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -338,6 +338,9 @@ struct buffer /* Symbol naming major mode (e.g., lisp-mode). */ Lisp_Object major_mode_; + /* Symbol listing all currently enabled minor modes. */ + Lisp_Object minor_modes_; + /* Pretty name of major mode (e.g., "Lisp"). */ Lisp_Object mode_name_; commit 103039b06c2c9a917fc796d2a4afda8433e37473 Author: Stefan Monnier Date: Sat Feb 13 19:24:33 2021 -0500 * lisp/emacs-lisp/edebug.el (edebug-make-enter-wrapper): Reinstate. Removed by accident. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 76fb19023a..8fadeba6c9 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -1240,6 +1240,33 @@ purpose by adding an entry to this alist, and setting (defvar edebug--cl-macrolet-defs) ;; Fully defined below. +(defun edebug-make-enter-wrapper (forms) + ;; Generate the enter wrapper for some forms of a definition. + ;; This is not to be used for the body of other forms, e.g. `while', + ;; since it wraps the list of forms with a call to `edebug-enter'. + ;; Uses the dynamically bound vars edebug-def-name and edebug-def-args. + ;; Do this after parsing since that may find a name. + (when (string-match-p (rx bos "edebug-anon" (+ digit) eos) + (symbol-name edebug-old-def-name)) + ;; FIXME: Due to Bug#42701, we reset an anonymous name so that + ;; backtracking doesn't generate duplicate definitions. It would + ;; be better to not define wrappers in the case of a non-matching + ;; specification branch to begin with. + (setq edebug-old-def-name nil)) + (setq edebug-def-name + (or edebug-def-name edebug-old-def-name (gensym "edebug-anon"))) + `(edebug-enter + (quote ,edebug-def-name) + ,(if edebug-inside-func + `(list + ;; Doesn't work with more than one def-body!! + ;; But the list will just be reversed. + ,@(nreverse edebug-def-args)) + 'nil) + (function (lambda () ,@forms)) + )) + + (defvar edebug-form-begin-marker) ; the mark for def being instrumented (defvar edebug-offset-index) ; the next available offset index. commit 2d9ff601ab5fc7187f0466f22c6c5e9451bce04f Author: Stefan Monnier Date: Sat Feb 13 19:22:17 2021 -0500 * lisp/emacs-lisp/edebug.el: Fix `called-interactively-p` And get rid of the old special-case handling of `interactive-p`, which is now redundant. (edebug--called-interactively-skip): Fix lexical-binding case, and adjust to some formerly missed call patterns. (edebug-def-interactive, edebug-interactive-p): Remove vars. (edebug-interactive-p-name, edebug-wrap-def-body) (edebug-make-enter-wrapper): Remove functions. (edebug-list-form): Don't special-case `interactive-p`. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 1cc95f7ac8..76fb19023a 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -1235,54 +1235,11 @@ purpose by adding an entry to this alist, and setting (funcall edebug-after-instrumentation-function result)))) (defvar edebug-def-args) ; args of defining form. -(defvar edebug-def-interactive) ; is it an emacs interactive function? (defvar edebug-inside-func) ;; whether code is inside function context. ;; Currently def-form sets this to nil; def-body sets it to t. (defvar edebug--cl-macrolet-defs) ;; Fully defined below. -(defun edebug-interactive-p-name () - ;; Return a unique symbol for the variable used to store the - ;; status of interactive-p for this function. - (intern (format "edebug-%s-interactive-p" edebug-def-name))) - - -(defun edebug-wrap-def-body (forms) - "Wrap the FORMS of a definition body." - (if edebug-def-interactive - `(let ((,(edebug-interactive-p-name) - (called-interactively-p 'interactive))) - ,(edebug-make-enter-wrapper forms)) - (edebug-make-enter-wrapper forms))) - - -(defun edebug-make-enter-wrapper (forms) - ;; Generate the enter wrapper for some forms of a definition. - ;; This is not to be used for the body of other forms, e.g. `while', - ;; since it wraps the list of forms with a call to `edebug-enter'. - ;; Uses the dynamically bound vars edebug-def-name and edebug-def-args. - ;; Do this after parsing since that may find a name. - (when (string-match-p (rx bos "edebug-anon" (+ digit) eos) - (symbol-name edebug-old-def-name)) - ;; FIXME: Due to Bug#42701, we reset an anonymous name so that - ;; backtracking doesn't generate duplicate definitions. It would - ;; be better to not define wrappers in the case of a non-matching - ;; specification branch to begin with. - (setq edebug-old-def-name nil)) - (setq edebug-def-name - (or edebug-def-name edebug-old-def-name (gensym "edebug-anon"))) - `(edebug-enter - (quote ,edebug-def-name) - ,(if edebug-inside-func - `(list - ;; Doesn't work with more than one def-body!! - ;; But the list will just be reversed. - ,@(nreverse edebug-def-args)) - 'nil) - (function (lambda () ,@forms)) - )) - - (defvar edebug-form-begin-marker) ; the mark for def being instrumented (defvar edebug-offset-index) ; the next available offset index. @@ -1404,7 +1361,6 @@ contains a circular object." (edebug-old-def-name (edebug--form-data-name form-data-entry)) edebug-def-name edebug-def-args - edebug-def-interactive edebug-inside-func;; whether wrapped code executes inside a function. ) @@ -1610,11 +1566,6 @@ contains a circular object." ((symbolp head) (cond ((null head) nil) ; () is valid. - ((eq head 'interactive-p) - ;; Special case: replace (interactive-p) with variable - (setq edebug-def-interactive 'check-it) - (edebug-move-cursor cursor) - (edebug-interactive-p-name)) (t (cons head (edebug-list-form-args head (edebug-move-cursor cursor)))))) @@ -2170,7 +2121,7 @@ into `edebug--cl-macrolet-defs' which is checked in `edebug-list-form-args'." ;; This happens to handle bug#20281, tho maybe a better fix would be to ;; improve the `defun' spec. (when forms - (list (edebug-wrap-def-body forms))))) + (list (edebug-make-enter-wrapper forms))))) ;;;; Edebug Form Specs @@ -2922,7 +2873,6 @@ See `edebug-behavior-alist' for implementations.") (defvar edebug-outside-match-data) ; match data outside of edebug (defvar edebug-backtrace-buffer) ; each recursive edit gets its own (defvar edebug-inside-windows) -(defvar edebug-interactive-p) (defvar edebug-mode-map) ; will be defined fully later. @@ -2938,7 +2888,6 @@ See `edebug-behavior-alist' for implementations.") ;;(edebug-number-of-recursions (1+ edebug-number-of-recursions)) (edebug-recursion-depth (recursion-depth)) edebug-entered ; bind locally to nil - (edebug-interactive-p nil) ; again non-interactive edebug-backtrace-buffer ; each recursive edit gets its own ;; The window configuration may be saved and restored ;; during a recursive-edit @@ -4588,13 +4537,18 @@ With prefix argument, make it a temporary breakpoint." (add-hook 'called-interactively-p-functions #'edebug--called-interactively-skip) (defun edebug--called-interactively-skip (i frame1 frame2) - (when (and (eq (car-safe (nth 1 frame1)) 'lambda) - (eq (nth 1 (nth 1 frame1)) '()) - (eq (nth 1 frame2) 'edebug-enter)) + (when (and (memq (car-safe (nth 1 frame1)) '(lambda closure)) + ;; Lambda value with no arguments. + (null (nth (if (eq (car-safe (nth 1 frame1)) 'lambda) 1 2) + (nth 1 frame1))) + (memq (nth 1 frame2) '(edebug-enter edebug-default-enter))) ;; `edebug-enter' calls itself on its first invocation. - (if (eq (nth 1 (backtrace-frame i 'called-interactively-p)) - 'edebug-enter) - 2 1))) + (let ((s 1)) + (while (memq (nth 1 (backtrace-frame i 'called-interactively-p)) + '(edebug-enter edebug-default-enter)) + (cl-incf s) + (cl-incf i)) + s))) ;; Finally, hook edebug into the rest of Emacs. ;; There are probably some other things that could go here. commit 39a401ddae154b94e4c0e9c8ced1b27d9dc56daa Author: Stefan Monnier Date: Sat Feb 13 17:50:31 2021 -0500 * lisp/emacs-lisp/edebug.el (edebug-match-lambda-expr): Delete function (lambda-expr): Define with `def-edebug-elem-spec` instead. (edebug--handle-&-spec-op): Remove left over code. (interactive): Re-add mistakenly removed spec elem. * doc/lispref/edebug.texi (Specification List): Remove `function-form`. diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi index 2412e844b7..46f5cb9026 100644 --- a/doc/lispref/edebug.texi +++ b/doc/lispref/edebug.texi @@ -1290,14 +1290,6 @@ Short for @code{&rest form}. See @code{&rest} below. If your macro wraps its body of code with @code{lambda} before it is evaluated, use @code{def-body} instead. See @code{def-body} below. -@item function-form -A function form: either a quoted function symbol, a quoted lambda -expression, or a form (that should evaluate to a function symbol or -lambda expression). This is useful when an argument that's a lambda -expression might be quoted with @code{quote} rather than -@code{function}, since it instruments the body of the lambda expression -either way. - @item lambda-expr A lambda expression with no quoting. @@ -1452,7 +1444,7 @@ match @var{spec} against the code and then call @var{fun} with the concatenation of the current name, @var{args...}, @var{prestring}, the code that matched @code{spec}, and @var{poststring}. If @var{fun} is absent, it defaults to a function that concatenates the arguments -(with an @code{@} between the previous name and the new). +(with an @code{@@} between the previous name and the new). @item name The argument, a symbol, is the name of the defining form. diff --git a/etc/NEWS b/etc/NEWS index de26c0172b..d865aa7c74 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -940,7 +940,9 @@ To customize obsolete user options, use 'customize-option' or **** 'get-edebug-spec' is obsolete, replaced by 'edebug-get-spec'. +++ -**** The Edebug spec operator ':name NAME' is obsolete. +**** The spec operator ':name NAME' is obsolete, use '&name' instead. ++++ +**** The spec element 'function-form' is obsolete, use 'form' instead. +++ *** New function 'def-edebug-elem-spec' to define Edebug spec elements. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 867161e028..1cc95f7ac8 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -1753,7 +1753,6 @@ contains a circular object." (def-form . edebug-match-def-form) ;; Less frequently used: ;; (function . edebug-match-function) - (lambda-expr . edebug-match-lambda-expr) (cl-macrolet-expr . edebug-match-cl-macrolet-expr) (cl-macrolet-name . edebug-match-cl-macrolet-name) (cl-macrolet-body . edebug-match-cl-macrolet-body) @@ -1873,7 +1872,7 @@ and then matches the rest against the output of (FUN ARGS... HEAD)." (pcase-let* ((`(,spec ,fun . ,args) specs) (exps (edebug-cursor-expressions cursor)) - (instrumented-head (edebug-match-one-spec cursor (or spec 'sexp))) + (instrumented-head (edebug-match-one-spec cursor spec)) (consumed (- (length exps) (length (edebug-cursor-expressions cursor)))) (newspecs (apply fun (append args (seq-subseq exps 0 consumed))))) @@ -2026,32 +2025,6 @@ and then matches the rest against the output of (FUN ARGS... HEAD)." offsets) specs)) -(defun edebug-match-lambda-expr (cursor) - ;; The expression must be a function. - ;; This will match any list form that begins with a symbol - ;; that has an edebug-form-spec beginning with &define. In - ;; practice, only lambda expressions should be used. - ;; I could add a &lambda specification to avoid confusion. - (let* ((sexp (edebug-top-element-required - cursor "Expected lambda expression")) - (offset (edebug-top-offset cursor)) - (head (and (consp sexp) (car sexp))) - (spec (and (symbolp head) (edebug-get-spec head))) - (edebug-inside-func nil)) - ;; Find out if this is a defining form from first symbol. - (if (and (consp spec) (eq '&define (car spec))) - (prog1 - (list - (edebug-defining-form - (edebug-new-cursor sexp offset) - (car offset);; before the sexp - (edebug-after-offset cursor) - (cons (symbol-name head) (cdr spec)))) - (edebug-move-cursor cursor)) - (edebug-no-match cursor "Expected lambda expression") - ))) - - (cl-defmethod edebug--handle-&-spec-op ((_ (eql &name)) cursor specs) "Compute the name for `&name SPEC FUN` spec operator. @@ -2271,12 +2244,19 @@ into `edebug--cl-macrolet-defs' which is checked in `edebug-list-form-args'." &optional ["&rest" arg] ))) +(def-edebug-elem-spec 'lambda-expr + '(("lambda" &define lambda-list lambda-doc + [&optional ("interactive" interactive)] + def-body))) + (def-edebug-elem-spec 'arglist '(lambda-list)) ;; deprecated - use lambda-list. (def-edebug-elem-spec 'lambda-doc '(&optional [&or stringp (&define ":documentation" def-form)])) +(def-edebug-elem-spec 'interactive '(&optional &or stringp def-form)) + ;; A function-form is for an argument that may be a function or a form. ;; This specially recognizes anonymous functions quoted with quote. (def-edebug-elem-spec 'function-form ;Deprecated, use `form'! commit 68bd6f3ea9c05637501139c46f1f4304482db95f Author: Alan Third Date: Sun Jan 31 20:19:53 2021 +0000 Fix flicker when resizing NS frame programmatically (bug#46155) ; Incidentally fixes bug#21326. * src/nsterm.m ([EmacsView viewWillDraw]): New function. ([EmacsView viewDidResize:]): We now have to mark the frame for display on resize. ([EmacsView initFrameFromEmacs:]): Retain frame contents on resize. ([EmacsView updateLayer]): Don't update the layer if the frame is still garbaged. diff --git a/src/nsterm.m b/src/nsterm.m index ca240eb55f..b0cf5952fd 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -7350,6 +7350,8 @@ - (void)viewDidResize:(NSNotification *)notification [surface release]; surface = nil; + + [self setNeedsDisplay:YES]; } #endif @@ -7521,6 +7523,16 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f [self initWithFrame: r]; [self setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; +#ifdef NS_DRAW_TO_BUFFER + /* These settings mean AppKit will retain the contents of the frame + on resize. Unfortunately it also means the frame will not be + automatically marked for display, but we can do that ourselves in + viewDidResize. */ + [self setLayerContentsRedrawPolicy: + NSViewLayerContentsRedrawOnSetNeedsDisplay]; + [self setLayerContentsPlacement:NSViewLayerContentsPlacementTopLeft]; +#endif + FRAME_NS_VIEW (f) = self; emacsframe = f; #ifdef NS_IMPL_COCOA @@ -8463,6 +8475,34 @@ - (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect } +#ifdef NS_IMPL_COCOA +/* If the frame has been garbaged but the toolkit wants to draw, for + example when resizing the frame, we end up with a blank screen. + Sometimes this results in an unpleasant flicker, so try to + redisplay before drawing. */ +- (void)viewWillDraw +{ + if (FRAME_GARBAGED_P (emacsframe) + && !redisplaying_p) + { + /* If there is IO going on when redisplay is run here Emacs + crashes. I think it's because this code will always be run + within the run loop and for whatever reason processing input + is dangerous. This technique was stolen wholesale from + nsmenu.m and seems to work. */ + bool owfi = waiting_for_input; + waiting_for_input = 0; + block_input (); + + redisplay (); + + unblock_input (); + waiting_for_input = owfi; + } +} +#endif + + #ifdef NS_DRAW_TO_BUFFER - (BOOL)wantsUpdateLayer { @@ -8480,6 +8520,13 @@ - (void)updateLayer { NSTRACE ("[EmacsView updateLayer]"); + /* We run redisplay on frames that are garbaged, but marked for + display, before updateLayer is called so if the frame is still + garbaged that means the last redisplay must have refused to + update the frame. */ + if (FRAME_GARBAGED_P (emacsframe)) + return; + /* This can fail to update the screen if the same surface is provided twice in a row, even if its contents have changed. There's a private method, -[CALayer setContentsChanged], that we commit 0474a0d7d4478e967c7bbee93ab3606f0b215e66 Author: Alan Third Date: Wed Feb 10 22:12:16 2021 +0000 Remove aliasing on SVG images under scaled NS frames * src/image.c (FRAME_SCALE_FACTOR): New #define for getting frame scale factor. (image_set_transform): (svg_load_image): Use FRAME_SCALE_FACTOR. * src/nsterm.m (ns_frame_scale_factor): Get the scale factor for an NS frame. diff --git a/src/image.c b/src/image.c index a124cf91ba..8137dbea8d 100644 --- a/src/image.c +++ b/src/image.c @@ -135,6 +135,12 @@ typedef struct ns_bitmap_record Bitmap_Record; # define COLOR_TABLE_SUPPORT 1 #endif +#if defined HAVE_NS +# define FRAME_SCALE_FACTOR(f) ns_frame_scale_factor (f) +#else +# define FRAME_SCALE_FACTOR(f) 1; +#endif + static void image_disable_image (struct frame *, struct image *); static void image_edge_detection (struct frame *, struct image *, Lisp_Object, Lisp_Object); @@ -2207,8 +2213,8 @@ image_set_transform (struct frame *f, struct image *img) /* SVGs are pre-scaled to the correct size. */ if (EQ (image_spec_value (img->spec, QCtype, NULL), Qsvg)) { - width = img->width; - height = img->height; + width = img->width / FRAME_SCALE_FACTOR (f); + height = img->height / FRAME_SCALE_FACTOR (f); } else #endif @@ -10008,6 +10014,9 @@ svg_load_image (struct frame *f, struct image *img, char *contents, compute_image_size (viewbox_width, viewbox_height, img->spec, &width, &height); + width *= FRAME_SCALE_FACTOR (f); + height *= FRAME_SCALE_FACTOR (f); + if (! check_image_size (f, width, height)) { image_size_error (); diff --git a/src/nsterm.h b/src/nsterm.h index eae1d0725e..017c2394ef 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -1252,6 +1252,7 @@ struct input_event; extern void ns_init_events (struct input_event *); extern void ns_finish_events (void); +extern double ns_frame_scale_factor (struct frame *); #ifdef NS_IMPL_GNUSTEP extern char gnustep_base_version[]; /* version tracking */ diff --git a/src/nsterm.m b/src/nsterm.m index 1b2328628e..ca240eb55f 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -857,6 +857,17 @@ Free a pool and temporary objects it refers to (callable from C) } +double +ns_frame_scale_factor (struct frame *f) +{ +#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED > 1060 + return [[FRAME_NS_VIEW (f) window] backingScaleFactor]; +#else + return [[FRAME_NS_VIEW (f) window] userSpaceScaleFactor]; +#endif +} + + /* ========================================================================== Focus (clipping) and screen update commit 2007afd21b5f6c72a7a9c15fd7c4785331f2700f Author: Stefan Monnier Date: Sat Feb 13 16:21:53 2021 -0500 * lisp/emacs-lisp/edebug.el (edebug--handle-&-spec-op <&name>): New method (edebug--concat-name): New function. (edebug-match-name, edebug-match-cl-generic-method-qualifier) (edebug-match-cl-generic-method-args): Delete functions. * doc/lispref/edebug.texi (Specification List): Document it. * lisp/emacs-lisp/cl-generic.el (cl-defgeneric): Use `&name`. (cl-generic--method-qualifier-p): New predicate. (cl-defmethod): Use it and `&name`. * lisp/emacs-lisp/cl-macs.el (cl-defun, cl-iter-defun, cl-flet): * lisp/emacs-lisp/eieio-compat.el (defmethod): * lisp/emacs-lisp/gv.el (gv-define-setter): * lisp/emacs-lisp/ert.el (ert-deftest): Use `&name`. * lisp/erc/erc-backend.el (define-erc-response-handler): Use `declare` and `&name`. diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi index 99d55c7ab9..2412e844b7 100644 --- a/doc/lispref/edebug.texi +++ b/doc/lispref/edebug.texi @@ -1444,29 +1444,23 @@ Here is a list of additional specifications that may appear only after @code{&define}. See the @code{defun} example. @table @code +@item &name +Extracts the name of the current defining form from the code. +It takes the form @code{&name [@var{prestring}] @var{spec} +[@var{poststring}] @var{fun} @var{args...}} and means that Edebug will +match @var{spec} against the code and then call @var{fun} with the +concatenation of the current name, @var{args...}, @var{prestring}, +the code that matched @code{spec}, and @var{poststring}. If @var{fun} +is absent, it defaults to a function that concatenates the arguments +(with an @code{@} between the previous name and the new). + @item name The argument, a symbol, is the name of the defining form. +Shorthand for @code{[&name symbolp]}. A defining form is not required to have a name field; and it may have multiple name fields. -@item :name -This construct does not actually match an argument. The element -following @code{:name} should be a symbol; it is used as an additional -name component for the definition. You can use this to add a unique, -static component to the name of the definition. It may be used more -than once. - -@item :unique -This construct is like @code{:name}, but generates unique names. It -does not match an argument. The element following @code{:unique} -should be a string; it is used as the prefix for an additional name -component for the definition. You can use this to add a unique, -dynamic component to the name of the definition. This is useful for -macros that can define the same symbol multiple times in different -scopes, such as @code{cl-flet}; @ref{Function Bindings,,,cl}. It may -be used more than once. - @item arg The argument, a symbol, is the name of an argument of the defining form. However, lambda-list keywords (symbols starting with @samp{&}) diff --git a/etc/NEWS b/etc/NEWS index aead8c6f78..de26c0172b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -936,7 +936,11 @@ To customize obsolete user options, use 'customize-option' or ** Edebug --- -*** 'get-edebug-spec' is obsolete, replaced by 'edebug-get-spec'. +*** Obsoletions +**** 'get-edebug-spec' is obsolete, replaced by 'edebug-get-spec'. + ++++ +**** The Edebug spec operator ':name NAME' is obsolete. +++ *** New function 'def-edebug-elem-spec' to define Edebug spec elements. @@ -954,8 +958,7 @@ declared obsolete. **** '&error MSG' unconditionally aborts the current edebug instrumentation. +++ -**** ':unique STRING' appends STRING to the Edebug name of the current -definition to (hopefully) make it more unique. +**** '&name SPEC FUN' extracts the current name from the code matching SPEC. ** ElDoc diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index 8e36dbe4a3..229608395e 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el @@ -206,22 +206,29 @@ DEFAULT-BODY, if present, is used as the body of a default method. \(fn NAME ARGS [DOC-STRING] [OPTIONS-AND-METHODS...] &rest DEFAULT-BODY)" (declare (indent 2) (doc-string 3) (debug - (&define [&or name ("setf" name :name setf)] listp - lambda-doc + (&define [&name sexp] ;Allow (setf ...) additionally to symbols. + listp lambda-doc [&rest [&or ("declare" &rest sexp) (":argument-precedence-order" &rest sexp) (&define ":method" - ;; FIXME: The `:unique' + ;; FIXME: The `gensym' ;; construct works around ;; Bug#42672. We'd rather want ;; names like those generated by ;; `cl-defmethod', but that ;; requires larger changes to ;; Edebug. - :unique "cl-generic-:method@" - [&rest cl-generic-method-qualifier] - cl-generic-method-args lambda-doc + [&name "cl-generic-:method@" []] + [&name [] gensym] ;Make it unique! + [&name + [[&rest cl-generic--method-qualifier-p] + ;; FIXME: We don't actually want the + ;; argument's names to be considered + ;; part of the name of the defined + ;; function. + listp]] ;Formal args + lambda-doc def-body)]] def-body))) (let* ((doc (if (stringp (car-safe options-and-methods)) @@ -398,6 +405,9 @@ the specializer used will be the one returned by BODY." (let ((combined-doc (buffer-string))) (if ud (help-add-fundoc-usage combined-doc (car ud)) combined-doc))))) +(defun cl-generic--method-qualifier-p (x) + (not (listp x))) + ;;;###autoload (defmacro cl-defmethod (name args &rest body) "Define a new method for generic function NAME. @@ -440,15 +450,17 @@ The set of acceptable TYPEs (also called \"specializers\") is defined (declare (doc-string 3) (indent defun) (debug (&define ; this means we are defining something - [&or name ("setf" name :name setf)] - ;; ^^ This is the methods symbol - [ &rest cl-generic-method-qualifier ] - ;; Multiple qualifiers are allowed. - cl-generic-method-args ; arguments + [&name [sexp ;Allow (setf ...) additionally to symbols. + ;; Multiple qualifiers are allowed. + [&rest cl-generic--method-qualifier-p] + ;; FIXME: We don't actually want the argument's names + ;; to be considered part of the name of the + ;; defined function. + listp]] ; arguments lambda-doc ; documentation string def-body))) ; part to be debugged (let ((qualifiers nil)) - (while (not (listp args)) + (while (cl-generic--method-qualifier-p args) (push args qualifiers) (setq args (pop body))) (when (eq 'setf (car-safe name)) diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 5967e0d084..e2faf6df53 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -358,7 +358,7 @@ more details. \(fn NAME ARGLIST [DOCSTRING] BODY...)" (declare (debug ;; Same as defun but use cl-lambda-list. - (&define [&or name ("setf" :name setf name)] + (&define [&name sexp] ;Allow (setf ...) additionally to symbols. cl-lambda-list cl-declarations-or-string [&optional ("interactive" interactive)] @@ -376,7 +376,7 @@ and BODY is implicitly surrounded by (cl-block NAME ...). \(fn NAME ARGLIST [DOCSTRING] BODY...)" (declare (debug ;; Same as iter-defun but use cl-lambda-list. - (&define [&or name ("setf" :name setf name)] + (&define [&name sexp] ;Allow (setf ...) additionally to symbols. cl-lambda-list cl-declarations-or-string [&optional ("interactive" interactive)] @@ -2016,8 +2016,9 @@ info node `(cl) Function Bindings' for details. \(fn ((FUNC ARGLIST BODY...) ...) FORM...)" (declare (indent 1) - (debug ((&rest [&or (&define name :unique "cl-flet@" form) - (&define name :unique "cl-flet@" + (debug ((&rest [&or (symbolp form) + (&define [&name symbolp "@cl-flet@"] + [&name [] gensym] ;Make it unique! cl-lambda-list cl-declarations-or-string [&optional ("interactive" interactive)] diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index cbf2d171a9..867161e028 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -1748,16 +1748,12 @@ contains a circular object." (dolist (pair '((form . edebug-match-form) (sexp . edebug-match-sexp) (body . edebug-match-body) - (name . edebug-match-name) (arg . edebug-match-arg) (def-body . edebug-match-def-body) (def-form . edebug-match-def-form) ;; Less frequently used: ;; (function . edebug-match-function) (lambda-expr . edebug-match-lambda-expr) - (cl-generic-method-qualifier - . edebug-match-cl-generic-method-qualifier) - (cl-generic-method-args . edebug-match-cl-generic-method-args) (cl-macrolet-expr . edebug-match-cl-macrolet-expr) (cl-macrolet-name . edebug-match-cl-macrolet-name) (cl-macrolet-body . edebug-match-cl-macrolet-body) @@ -2056,19 +2052,61 @@ and then matches the rest against the output of (FUN ARGS... HEAD)." ))) -(defun edebug-match-name (cursor) - ;; Set the edebug-def-name bound in edebug-defining-form. - (let ((name (edebug-top-element-required cursor "Expected name"))) - ;; Maybe strings and numbers could be used. - (if (not (symbolp name)) - (edebug-no-match cursor "Symbol expected for name of definition")) - (setq edebug-def-name - (if edebug-def-name - ;; Construct a new name by appending to previous name. - (intern (format "%s@%s" edebug-def-name name)) - name)) - (edebug-move-cursor cursor) - (list name))) +(cl-defmethod edebug--handle-&-spec-op ((_ (eql &name)) cursor specs) + "Compute the name for `&name SPEC FUN` spec operator. + +The full syntax of that operator is: + &name [PRESTRING] SPEC [POSTSTRING] FUN ARGS... + +Extracts the head of the data by matching it against SPEC, +and then get the new name to use by calling + (FUN ARGS... OLDNAME [PRESTRING] HEAD [POSTSTRING]) +FUN should return either a string or a symbol. +FUN can be missing in which case it defaults to concatenating +the new name to the end of the old with an \"@\" char between the two. +PRESTRING and POSTSTRING are optional strings that get prepended +or appended to the actual name." + (pcase-let* + ((`(,spec ,fun . ,args) specs) + (prestrings (when (stringp spec) + (prog1 (list spec) (setq spec fun fun (pop args))))) + (poststrings (when (stringp fun) + (prog1 (list fun) (setq fun (pop args))))) + (exps (edebug-cursor-expressions cursor)) + (instrumented (edebug-match-one-spec cursor spec)) + (consumed (- (length exps) + (length (edebug-cursor-expressions cursor)))) + (newname (apply (or fun #'edebug--concat-name) + `(,@args ,edebug-def-name + ,@prestrings + ,@(seq-subseq exps 0 consumed) + ,@poststrings)))) + (cl-assert (eq (edebug-cursor-expressions cursor) (nthcdr consumed exps))) + (setq edebug-def-name (if (stringp newname) (intern newname) newname)) + instrumented)) + +(defun edebug--concat-name (oldname &rest newnames) + (let ((newname (if (null (cdr newnames)) + (car newnames) + ;; Put spaces between each name, but not for the + ;; leading and trailing strings, if any. + (let (beg mid end) + (dolist (name newnames) + (if (stringp name) + (push name (if mid end beg)) + (when end (setq mid (nconc end mid) end nil)) + (push name mid))) + (apply #'concat `(,@(nreverse beg) + ,(mapconcat (lambda (x) (format "%s" x)) + (nreverse mid) " ") + ,@(nreverse end))))))) + (if (null oldname) + (if (or (stringp newname) (symbolp newname)) + newname + (format "%s" newname)) + (format "%s@%s" edebug-def-name newname)))) + +(def-edebug-elem-spec 'name '(&name symbolp)) (cl-defgeneric edebug--handle-:-spec-op (op cursor spec) "Handle :foo spec operators. @@ -2094,26 +2132,6 @@ SPEC is the symbol name prefix for `gensym'." suffix))) nil) -(defun edebug-match-cl-generic-method-qualifier (cursor) - "Match a QUALIFIER for `cl-defmethod' at CURSOR." - (let ((args (edebug-top-element-required cursor "Expected qualifier"))) - ;; Like in CLOS spec, we support any non-list values. - (unless (atom args) (edebug-no-match cursor "Atom expected")) - ;; Append the arguments to `edebug-def-name' (Bug#42671). - (setq edebug-def-name (intern (format "%s %s" edebug-def-name args))) - (edebug-move-cursor cursor) - (list args))) - -(defun edebug-match-cl-generic-method-args (cursor) - (let ((args (edebug-top-element-required cursor "Expected arguments"))) - (if (not (consp args)) - (edebug-no-match cursor "List expected")) - ;; Append the arguments to edebug-def-name. - (setq edebug-def-name - (intern (format "%s %s" edebug-def-name args))) - (edebug-move-cursor cursor) - (list args))) - (defvar edebug--cl-macrolet-defs nil "List of symbols found within the bindings of enclosing `cl-macrolet' forms.") (defvar edebug--current-cl-macrolet-defs nil diff --git a/lisp/emacs-lisp/eieio-compat.el b/lisp/emacs-lisp/eieio-compat.el index db97d4ca4e..6d84839c34 100644 --- a/lisp/emacs-lisp/eieio-compat.el +++ b/lisp/emacs-lisp/eieio-compat.el @@ -105,7 +105,7 @@ Summary: (declare (doc-string 3) (obsolete cl-defmethod "25.1") (debug (&define ; this means we are defining something - [&or name ("setf" name :name setf)] + [&name sexp] ;Allow (setf ...) additionally to symbols. ;; ^^ This is the methods symbol [ &optional symbolp ] ; this is key :before etc cl-generic-method-args ; arguments diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index fdbf95319f..e08fa7ac7b 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -196,8 +196,8 @@ it has to be wrapped in `(eval (quote ...))'. \(fn NAME () [DOCSTRING] [:expected-result RESULT-TYPE] \ [:tags \\='(TAG...)] BODY...)" - (declare (debug (&define :name test - name sexp [&optional stringp] + (declare (debug (&define [&name "test@" symbolp] + sexp [&optional stringp] [&rest keywordp sexp] def-body)) (doc-string 3) (indent 2)) diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el index edacdf7f0c..3200b1c349 100644 --- a/lisp/emacs-lisp/gv.el +++ b/lisp/emacs-lisp/gv.el @@ -229,7 +229,8 @@ The first arg in ARGLIST (the one that receives VAL) receives an expression which can do arbitrary things, whereas the other arguments are all guaranteed to be pure and copyable. Example use: (gv-define-setter aref (v a i) \\=`(aset ,a ,i ,v))" - (declare (indent 2) (debug (&define name :name gv-setter sexp def-body))) + (declare (indent 2) + (debug (&define [&name symbolp "@gv-setter"] sexp def-body))) `(gv-define-expander ,name (lambda (do &rest args) (declare-function diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index 6f1193cbb2..73c2b56b02 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -1079,14 +1079,12 @@ Finds hooks by looking in the `erc-server-responses' hash table." (erc-display-message parsed 'notice proc line))) -(put 'define-erc-response-handler 'edebug-form-spec - '(&define :name erc-response-handler - (name &rest name) - &optional sexp sexp def-body)) - (cl-defmacro define-erc-response-handler ((name &rest aliases) - &optional extra-fn-doc extra-var-doc - &rest fn-body) + &optional extra-fn-doc extra-var-doc + &rest fn-body) + (declare (debug (&define [&name "erc-response-handler@" + (symbolp &rest symbolp)] + &optional sexp sexp def-body))) "Define an ERC handler hook/function pair. NAME is the response name as sent by the server (see the IRC RFC for meanings). commit e81cf63be15f907fbe9de6b6c9eb1a021d4e2fe2 Author: Philipp Stephani Date: Sat Feb 13 19:35:26 2021 +0100 * etc/NEWS: Document new JSON behavior. diff --git a/etc/NEWS b/etc/NEWS index 464b955ee7..aead8c6f78 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2557,6 +2557,12 @@ locales. They are also available as aliases 'ebcdic-cp-*' (e.g., 'cp278' for 'ibm278'). There are also new charsets 'ibm2xx' to support these coding-systems. +** The JSON functions 'json-serialize', 'json-insert', +'json-parse-string', and 'json-parse-buffer' now implement some of the +semantics of RFC 8259 instead of the earlier RFC 4627. In particular, +these functions now accept top-level JSON values that are neither +arrays nor objects. + * Changes in Emacs 28.1 on Non-Free Operating Systems commit 6b0de9f8300022d41f3acd63ef6d9a913e983215 Author: Augusto Stoffel Date: Fri Feb 12 19:29:54 2021 +0100 Small correction to `isearch-lazy-highlight-buffer-update' The value of point is now read after a potential change of buffer. * lisp/isearch.el (isearch-lazy-highlight-buffer-update): Move call to `point' after `select-window'. Copyright-paperwork-exempt: yes diff --git a/lisp/isearch.el b/lisp/isearch.el index b58ca8a6f7..c571ea9467 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -4127,13 +4127,13 @@ Attempt to do the search exactly the way the pending Isearch would." "Update highlighting of other matches in the full buffer." (let ((max lazy-highlight-buffer-max-at-a-time) (looping t) - nomore window-start window-end - (opoint (point))) + nomore opoint window-start window-end) (with-local-quit (save-selected-window (if (and (window-live-p isearch-lazy-highlight-window) (not (memq (selected-window) isearch-lazy-highlight-window-group))) (select-window isearch-lazy-highlight-window)) + (setq opoint (point)) (setq window-start (window-group-start)) (setq window-end (window-group-end)) (save-excursion commit f65402f851c91523ca44450c609bee07d37b9036 Author: Stefan Monnier Date: Sat Feb 13 10:41:45 2021 -0500 (backtrace-goto-source-functions): Make it a normal abnormal hook * lisp/emacs-lisp/backtrace.el (backtrace-goto-source-functions): Don't mark it as buffer-local any more. (backtrace-goto-source): Use `run-hook-with-args-until-success`. * lisp/emacs-lisp/edebug.el (edebug-pop-to-backtrace): Clarify that the hook is only intended to be modified buffer-locally. diff --git a/lisp/emacs-lisp/backtrace.el b/lisp/emacs-lisp/backtrace.el index 3e1c329265..ea70baa953 100644 --- a/lisp/emacs-lisp/backtrace.el +++ b/lisp/emacs-lisp/backtrace.el @@ -190,7 +190,7 @@ This is commonly used to recompute `backtrace-frames'.") (defvar-local backtrace-print-function #'cl-prin1 "Function used to print values in the current Backtrace buffer.") -(defvar-local backtrace-goto-source-functions nil +(defvar backtrace-goto-source-functions nil "Abnormal hook used to jump to the source code for the current frame. Each hook function is called with no argument, and should return non-nil if it is able to switch to the buffer containing the @@ -638,10 +638,8 @@ content of the sexp." (source-available (plist-get (backtrace-frame-flags frame) :source-available))) (unless (and source-available - (catch 'done - (dolist (func backtrace-goto-source-functions) - (when (funcall func) - (throw 'done t))))) + (run-hook-with-args-until-success + 'backtrace-goto-source-functions)) (user-error "Source code location not known")))) (defun backtrace-help-follow-symbol (&optional pos) diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 394f47090c..cbf2d171a9 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -4247,7 +4247,8 @@ This should be a list of `edebug---frame' objects.") (pop-to-buffer edebug-backtrace-buffer) (unless (derived-mode-p 'backtrace-mode) (backtrace-mode) - (add-hook 'backtrace-goto-source-functions #'edebug--backtrace-goto-source)) + (add-hook 'backtrace-goto-source-functions + #'edebug--backtrace-goto-source nil t)) (setq edebug-instrumented-backtrace-frames (backtrace-get-frames 'edebug-debugger :constructor #'edebug--make-frame) commit 56c42bd28d9be400e37e122b7abebcd980ea0e8b Author: Eli Zaretskii Date: Sat Feb 13 17:27:02 2021 +0200 Fix I-search at EOB when long lines are truncated * src/xdisp.c (move_it_to): Fix logic when TO_CHARPOS is at the end of an hscrolled line which ends at EOB. (Bug#46316) diff --git a/src/xdisp.c b/src/xdisp.c index 125d3ed7f0..a195682421 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10049,7 +10049,9 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos it->continuation_lines_width = 0; reseat_at_next_visible_line_start (it, false); if ((op & MOVE_TO_POS) != 0 - && IT_CHARPOS (*it) > to_charpos) + && (IT_CHARPOS (*it) > to_charpos + || (IT_CHARPOS (*it) == to_charpos + && to_charpos == ZV))) { reached = 9; goto out; commit c535fe647c02ccde424340dc8ceae75922443ca5 Author: Eli Zaretskii Date: Sat Feb 13 16:10:53 2021 +0200 ; * src/json.c (Fjson_parse_string): Fix the doc string. diff --git a/src/json.c b/src/json.c index 3562e175cf..3f1d27ad7f 100644 --- a/src/json.c +++ b/src/json.c @@ -928,14 +928,14 @@ json_to_lisp (json_t *json, const struct json_configuration *conf) DEFUN ("json-parse-string", Fjson_parse_string, Sjson_parse_string, 1, MANY, NULL, - doc: /* Parse the JSON STRING into a Lisp object. This is -essentially the reverse operation of `json-serialize', which see. The -returned object will be the JSON null value, the JSON false value, t, -a number, a string, a vector, a list, a hashtable, an alist, or a -plist. Its elements will be further objects of these types. If there -are duplicate keys in an object, all but the last one are ignored. If -STRING doesn't contain a valid JSON object, this function signals an -error of type `json-parse-error'. + doc: /* Parse the JSON STRING into a Lisp object. +This is essentially the reverse operation of `json-serialize', which +see. The returned object will be the JSON null value, the JSON false +value, t, a number, a string, a vector, a list, a hashtable, an alist, +or a plist. Its elements will be further objects of these types. If +there are duplicate keys in an object, all but the last one are +ignored. If STRING doesn't contain a valid JSON object, this function +signals an error of type `json-parse-error'. The arguments ARGS are a list of keyword/argument pairs: commit 1680a1c0945cb0aa7e0e16867a9dacb8316cbf33 Author: Philipp Stephani Date: Sat Feb 13 14:35:30 2021 +0100 Pass 'struct json_configuration' as const where possible. The JSON serialization and parsing functions don't need to modify these structures. * src/json.c (lisp_to_json_nonscalar_1, lisp_to_json_nonscalar) (lisp_to_json, json_to_lisp): Mark configuration object parameter as const. diff --git a/src/json.c b/src/json.c index e0e49ae308..3562e175cf 100644 --- a/src/json.c +++ b/src/json.c @@ -327,13 +327,14 @@ struct json_configuration { Lisp_Object false_object; }; -static json_t *lisp_to_json (Lisp_Object, struct json_configuration *conf); +static json_t *lisp_to_json (Lisp_Object, + const struct json_configuration *conf); /* Convert a Lisp object to a nonscalar JSON object (array or object). */ static json_t * lisp_to_json_nonscalar_1 (Lisp_Object lisp, - struct json_configuration *conf) + const struct json_configuration *conf) { json_t *json; ptrdiff_t count; @@ -454,7 +455,7 @@ lisp_to_json_nonscalar_1 (Lisp_Object lisp, static json_t * lisp_to_json_nonscalar (Lisp_Object lisp, - struct json_configuration *conf) + const struct json_configuration *conf) { if (++lisp_eval_depth > max_lisp_eval_depth) xsignal0 (Qjson_object_too_deep); @@ -468,7 +469,7 @@ lisp_to_json_nonscalar (Lisp_Object lisp, JSON object. */ static json_t * -lisp_to_json (Lisp_Object lisp, struct json_configuration *conf) +lisp_to_json (Lisp_Object lisp, const struct json_configuration *conf) { if (EQ (lisp, conf->null_object)) return json_check (json_null ()); @@ -788,7 +789,7 @@ usage: (json-insert OBJECT &rest ARGS) */) /* Convert a JSON object to a Lisp object. */ static Lisp_Object ARG_NONNULL ((1)) -json_to_lisp (json_t *json, struct json_configuration *conf) +json_to_lisp (json_t *json, const struct json_configuration *conf) { switch (json_typeof (json)) { commit 625de7e403abb24c2d6ae417622fa8c7d6f55530 Author: Philipp Stephani Date: Sat Feb 13 14:25:42 2021 +0100 Allow any JSON value at the top level (Bug#42994). Newer standards like RFC 8259, which obsoletes the earlier RFC 4627, now allow any top-level value unconditionally, so Emacs should too. * src/json.c (Fjson_serialize, Fjson_insert): Pass JSON_ENCODE_ANY to allow serialization of any JSON value. Call 'lisp_to_json' instead of 'lisp_to_json_toplevel'. Remove obsolete comments (neither JSON_DECODE_ANY nor JSON_ALLOW_NUL are allowed here). Reword documentation strings. (Fjson_parse_string, Fjson_parse_buffer): Pass JSON_DECODE_ANY to allow deserialization of any JSON value. Reword documentation strings. (lisp_to_json_nonscalar, lisp_to_json_nonscalar_1): Rename from "toplevel" to avoid confusion. (lisp_to_json): Adapt caller. * test/src/json-tests.el (json-serialize/roundtrip-scalars): New unit test. * doc/lispref/text.texi (Parsing JSON): Update documentation. diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index b367346524..e47e851b10 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -5288,10 +5288,9 @@ object parsed. Signaled when encountering invalid JSON syntax. @end table - Only top-level values (arrays and objects) can be serialized to -JSON@. The subobjects within these top-level values can be of any -type. Likewise, the parsing functions will only return vectors, -hashtables, alists, and plists. + Top-level values and the subobjects within these top-level values +can be serialized to JSON@. Likewise, the parsing functions will +return any of the possible types described above. @defun json-serialize object &rest args This function returns a new Lisp string which contains the JSON diff --git a/src/json.c b/src/json.c index 2901a20811..e0e49ae308 100644 --- a/src/json.c +++ b/src/json.c @@ -329,11 +329,11 @@ struct json_configuration { static json_t *lisp_to_json (Lisp_Object, struct json_configuration *conf); -/* Convert a Lisp object to a toplevel JSON object (array or object). */ +/* Convert a Lisp object to a nonscalar JSON object (array or object). */ static json_t * -lisp_to_json_toplevel_1 (Lisp_Object lisp, - struct json_configuration *conf) +lisp_to_json_nonscalar_1 (Lisp_Object lisp, + struct json_configuration *conf) { json_t *json; ptrdiff_t count; @@ -448,16 +448,17 @@ lisp_to_json_toplevel_1 (Lisp_Object lisp, return json; } -/* Convert LISP to a toplevel JSON object (array or object). Signal +/* Convert LISP to a nonscalar JSON object (array or object). Signal an error of type `wrong-type-argument' if LISP is not a vector, hashtable, alist, or plist. */ static json_t * -lisp_to_json_toplevel (Lisp_Object lisp, struct json_configuration *conf) +lisp_to_json_nonscalar (Lisp_Object lisp, + struct json_configuration *conf) { if (++lisp_eval_depth > max_lisp_eval_depth) xsignal0 (Qjson_object_too_deep); - json_t *json = lisp_to_json_toplevel_1 (lisp, conf); + json_t *json = lisp_to_json_nonscalar_1 (lisp, conf); --lisp_eval_depth; return json; } @@ -499,7 +500,7 @@ lisp_to_json (Lisp_Object lisp, struct json_configuration *conf) } /* LISP now must be a vector, hashtable, alist, or plist. */ - return lisp_to_json_toplevel (lisp, conf); + return lisp_to_json_nonscalar (lisp, conf); } static void @@ -557,15 +558,15 @@ DEFUN ("json-serialize", Fjson_serialize, Sjson_serialize, 1, MANY, NULL, doc: /* Return the JSON representation of OBJECT as a string. -OBJECT must be a vector, hashtable, alist, or plist and its elements -can recursively contain the Lisp equivalents to the JSON null and -false values, t, numbers, strings, or other vectors hashtables, alists -or plists. t will be converted to the JSON true value. Vectors will -be converted to JSON arrays, whereas hashtables, alists and plists are -converted to JSON objects. Hashtable keys must be strings without -embedded null characters and must be unique within each object. Alist -and plist keys must be symbols; if a key is duplicate, the first -instance is used. +OBJECT must be t, a number, string, vector, hashtable, alist, plist, +or the Lisp equivalents to the JSON null and false values, and its +elements must recursively consist of the same kinds of values. t will +be converted to the JSON true value. Vectors will be converted to +JSON arrays, whereas hashtables, alists and plists are converted to +JSON objects. Hashtable keys must be strings without embedded null +characters and must be unique within each object. Alist and plist +keys must be symbols; if a key is duplicate, the first instance is +used. The Lisp equivalents to the JSON null and false values are configurable in the arguments ARGS, a list of keyword/argument pairs: @@ -603,12 +604,10 @@ usage: (json-serialize OBJECT &rest ARGS) */) {json_object_hashtable, json_array_array, QCnull, QCfalse}; json_parse_args (nargs - 1, args + 1, &conf, false); - json_t *json = lisp_to_json_toplevel (args[0], &conf); + json_t *json = lisp_to_json (args[0], &conf); record_unwind_protect_ptr (json_release_object, json); - /* If desired, we might want to add the following flags: - JSON_DECODE_ANY, JSON_ALLOW_NUL. */ - char *string = json_dumps (json, JSON_COMPACT); + char *string = json_dumps (json, JSON_COMPACT | JSON_ENCODE_ANY); if (string == NULL) json_out_of_memory (); record_unwind_protect_ptr (json_free, string); @@ -723,12 +722,10 @@ usage: (json-insert OBJECT &rest ARGS) */) move_gap_both (PT, PT_BYTE); struct json_insert_data data; data.inserted_bytes = 0; - /* If desired, we might want to add the following flags: - JSON_DECODE_ANY, JSON_ALLOW_NUL. */ - int status - /* Could have used json_dumpb, but that became available only in - Jansson 2.10, whereas we want to support 2.7 and upward. */ - = json_dump_callback (json, json_insert_callback, &data, JSON_COMPACT); + /* Could have used json_dumpb, but that became available only in + Jansson 2.10, whereas we want to support 2.7 and upward. */ + int status = json_dump_callback (json, json_insert_callback, &data, + JSON_COMPACT | JSON_ENCODE_ANY); if (status == -1) { if (CONSP (data.error)) @@ -930,14 +927,14 @@ json_to_lisp (json_t *json, struct json_configuration *conf) DEFUN ("json-parse-string", Fjson_parse_string, Sjson_parse_string, 1, MANY, NULL, - doc: /* Parse the JSON STRING into a Lisp object. -This is essentially the reverse operation of `json-serialize', which -see. The returned object will be a vector, list, hashtable, alist, or -plist. Its elements will be the JSON null value, the JSON false -value, t, numbers, strings, or further vectors, hashtables, alists, or -plists. If there are duplicate keys in an object, all but the last -one are ignored. If STRING doesn't contain a valid JSON object, this -function signals an error of type `json-parse-error'. + doc: /* Parse the JSON STRING into a Lisp object. This is +essentially the reverse operation of `json-serialize', which see. The +returned object will be the JSON null value, the JSON false value, t, +a number, a string, a vector, a list, a hashtable, an alist, or a +plist. Its elements will be further objects of these types. If there +are duplicate keys in an object, all but the last one are ignored. If +STRING doesn't contain a valid JSON object, this function signals an +error of type `json-parse-error'. The arguments ARGS are a list of keyword/argument pairs: @@ -982,7 +979,8 @@ usage: (json-parse-string STRING &rest ARGS) */) json_parse_args (nargs - 1, args + 1, &conf, true); json_error_t error; - json_t *object = json_loads (SSDATA (encoded), 0, &error); + json_t *object + = json_loads (SSDATA (encoded), JSON_DECODE_ANY, &error); if (object == NULL) json_parse_error (&error); @@ -1078,8 +1076,10 @@ usage: (json-parse-buffer &rest args) */) ptrdiff_t point = PT_BYTE; struct json_read_buffer_data data = {.point = point}; json_error_t error; - json_t *object = json_load_callback (json_read_buffer_callback, &data, - JSON_DISABLE_EOF_CHECK, &error); + json_t *object + = json_load_callback (json_read_buffer_callback, &data, + JSON_DECODE_ANY | JSON_DISABLE_EOF_CHECK, + &error); if (object == NULL) json_parse_error (&error); diff --git a/test/src/json-tests.el b/test/src/json-tests.el index 4be11b8c81..908945fcb0 100644 --- a/test/src/json-tests.el +++ b/test/src/json-tests.el @@ -51,6 +51,34 @@ (should (equal (json-parse-buffer) lisp)) (should (eobp))))) +(ert-deftest json-serialize/roundtrip-scalars () + "Check that Bug#42994 is fixed." + (skip-unless (fboundp 'json-serialize)) + (dolist (case '((:null "null") + (:false "false") + (t "true") + (0 "0") + (123 "123") + (-456 "-456") + (3.75 "3.75") + ;; The noncharacter U+FFFF should be passed through, + ;; cf. https://www.unicode.org/faq/private_use.html#noncharacters. + ("abc\uFFFFαβγ𝔸𝐁𝖢\"\\" + "\"abc\uFFFFαβγ𝔸𝐁𝖢\\\"\\\\\""))) + (cl-destructuring-bind (lisp json) case + (ert-info ((format "%S ↔ %S" lisp json)) + (should (equal (json-serialize lisp) json)) + (with-temp-buffer + (json-insert lisp) + (should (equal (buffer-string) json)) + (should (eobp))) + (should (equal (json-parse-string json) lisp)) + (with-temp-buffer + (insert json) + (goto-char 1) + (should (equal (json-parse-buffer) lisp)) + (should (eobp))))))) + (ert-deftest json-serialize/object () (skip-unless (fboundp 'json-serialize)) (let ((table (make-hash-table :test #'equal))) commit 856502d80d0a3ccfe8c80b65290fdb00e8813391 Author: Basil L. Contovounesios Date: Sat Feb 13 12:47:59 2021 +0000 Remove stale comments from gnus-msg.el * lisp/gnus/gnus-msg.el (gnus-group-mail, gnus-group-news) (gnus-summary-mail-other-window, gnus-summary-news-other-window): Remove stale comments about let-binding gnus-newsgroup-name, as they should have been addressed (bug#37871#38). diff --git a/lisp/gnus/gnus-msg.el b/lisp/gnus/gnus-msg.el index 45e665be8c..61b76381a0 100644 --- a/lisp/gnus/gnus-msg.el +++ b/lisp/gnus/gnus-msg.el @@ -609,8 +609,6 @@ instead." If ARG, use the group under the point to find a posting style. If ARG is 1, prompt for a group name to find the posting style." (interactive "P") - ;; We can't `let' gnus-newsgroup-name here, since that leads - ;; to local variables leaking. (let* (;;(group gnus-newsgroup-name) ;; make sure last viewed article doesn't affect posting styles: (gnus-article-copy) @@ -634,8 +632,6 @@ This function prepares a news even when using mail groups. This is useful for posting messages to mail groups without actually sending them over the network. The corresponding back end must have a `request-post' method." (interactive "P") - ;; We can't `let' gnus-newsgroup-name here, since that leads - ;; to local variables leaking. (let* (;;(group gnus-newsgroup-name) ;; make sure last viewed article doesn't affect posting styles: (gnus-article-copy) @@ -677,8 +673,6 @@ Use the posting of the current group by default. If ARG, don't do that. If ARG is 1, prompt for group name to find the posting style." (interactive "P") - ;; We can't `let' gnus-newsgroup-name here, since that leads - ;; to local variables leaking. (let* (;;(group gnus-newsgroup-name) ;; make sure last viewed article doesn't affect posting styles: (gnus-article-copy) @@ -702,8 +696,6 @@ This function prepares a news even when using mail groups. This is useful for posting messages to mail groups without actually sending them over the network. The corresponding back end must have a `request-post' method." (interactive "P") - ;; We can't `let' gnus-newsgroup-name here, since that leads - ;; to local variables leaking. (let* (;;(group gnus-newsgroup-name) ;; make sure last viewed article doesn't affect posting styles: (gnus-article-copy) commit 1a6c7c10951ce6dadfdab36ad6ff6f679526828f Author: Eli Zaretskii Date: Sat Feb 13 14:57:25 2021 +0200 Fix vertical cursor motion among many images * src/xdisp.c (move_it_in_display_line_to): Consider it MOVE_POS_MATCH_OR_ZV if we are just after an image, stretch, or display string, and the position matches exactly. This is needed when one image follows another at TO_CHARPOS. (Bug#46464) diff --git a/src/xdisp.c b/src/xdisp.c index fb8eaf4b96..125d3ed7f0 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -9227,10 +9227,10 @@ move_it_in_display_line_to (struct it *it, || prev_method == GET_FROM_STRING) /* Passed TO_CHARPOS from left to right. */ && ((prev_pos < to_charpos - && IT_CHARPOS (*it) > to_charpos) + && IT_CHARPOS (*it) >= to_charpos) /* Passed TO_CHARPOS from right to left. */ || (prev_pos > to_charpos - && IT_CHARPOS (*it) < to_charpos))))) + && IT_CHARPOS (*it) <= to_charpos))))) { if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0) { commit aefdde96367ba38dbff8fa1761f44d5534fccaba Author: Lars Ingebrigtsen Date: Sat Feb 13 12:46:34 2021 +0100 add-minor-mode doc string clarification * lisp/subr.el (add-minor-mode): Clarify that this function isn't only about XEmacs compat stuff. diff --git a/lisp/subr.el b/lisp/subr.el index 70ee281fe6..d215bd29a9 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2318,7 +2318,8 @@ tho trying to avoid AVOIDED-MODES." (defun add-minor-mode (toggle name &optional keymap after toggle-fun) "Register a new minor mode. -This is an XEmacs-compatibility function. Use `define-minor-mode' instead. +This function shouldn't be used directly -- use `define-minor-mode' +instead (which will then call this function). TOGGLE is a symbol that is the name of a buffer-local variable that is toggled on or off to say whether the minor mode is active or not. commit 06639a4ab27887804539f3dc9b805756e6020660 Author: Stefan Kangas Date: Sat Feb 13 07:22:44 2021 +0100 Delete 20 year old comment in executable.el * lisp/progmodes/executable.el (executable-insert): Delete 20 year old comment. diff --git a/lisp/progmodes/executable.el b/lisp/progmodes/executable.el index b1cd3303c5..85e9b4bb88 100644 --- a/lisp/progmodes/executable.el +++ b/lisp/progmodes/executable.el @@ -54,20 +54,14 @@ "Base functionality for executable interpreter scripts." :group 'processes) -;; This used to default to `other', but that doesn't seem to have any -;; significance. fx 2000-02-11. -(defcustom executable-insert t ; 'other +(defcustom executable-insert t "Non-nil means offer to add a magic number to a file. This takes effect when you switch to certain major modes, including Shell-script mode (`sh-mode'). When you type \\[executable-set-magic], it always offers to add or update the magic number." -;;; :type '(choice (const :tag "off" nil) -;;; (const :tag "on" t) -;;; symbol) :type 'boolean) - (defcustom executable-query 'function "If non-nil, ask user before changing an existing magic number. When this is `function', only ask when called non-interactively." commit b4b9ecdfe366c64a7b95c4fd295b583c3f3c7aa9 Author: Stefan Kangas Date: Sat Feb 13 05:18:55 2021 +0100 Remove redundant :group args in progmodes/*.el * lisp/progmodes/bug-reference.el: * lisp/progmodes/cfengine.el: * lisp/progmodes/cmacexp.el: * lisp/progmodes/cpp.el: * lisp/progmodes/cwarn.el: * lisp/progmodes/dcl-mode.el: * lisp/progmodes/executable.el: * lisp/progmodes/flymake.el: * lisp/progmodes/gud.el: * lisp/progmodes/hideshow.el: * lisp/progmodes/icon.el: * lisp/progmodes/inf-lisp.el: * lisp/progmodes/js.el: * lisp/progmodes/ld-script.el: * lisp/progmodes/make-mode.el: * lisp/progmodes/modula2.el: * lisp/progmodes/pascal.el: * lisp/progmodes/perl-mode.el: * lisp/progmodes/prog-mode.el: * lisp/progmodes/simula.el: * lisp/progmodes/xscheme.el: Remove redundant :group args. diff --git a/lisp/progmodes/bug-reference.el b/lisp/progmodes/bug-reference.el index a759394abe..4d4becf780 100644 --- a/lisp/progmodes/bug-reference.el +++ b/lisp/progmodes/bug-reference.el @@ -73,8 +73,7 @@ so that it is considered safe, see `enable-local-variables'.") "Regular expression matching bug references. The second subexpression should match the bug reference (usually a number)." :type 'regexp - :version "24.3" ; previously defconst - :group 'bug-reference) + :version "24.3") ; previously defconst ;;;###autoload (put 'bug-reference-bug-regexp 'safe-local-variable 'stringp) diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el index f516664f7f..bef99f2484 100644 --- a/lisp/progmodes/cfengine.el +++ b/lisp/progmodes/cfengine.el @@ -69,7 +69,6 @@ (defcustom cfengine-indent 2 "Size of a CFEngine indentation step in columns." - :group 'cfengine :type 'integer) (defcustom cfengine-cf-promises @@ -86,7 +85,6 @@ Used for syntax discovery and checking. Set to nil to disable the `compile-command' override. In that case, the ElDoc support will use a fallback syntax definition." :version "24.4" - :group 'cfengine :type '(choice file (const nil))) (defcustom cfengine-parameters-indent '(promise pname 2) @@ -145,7 +143,6 @@ bundle agent rcfiles } " :version "24.4" - :group 'cfengine :type '(list (choice (const :tag "Anchor at beginning of promise" promise) (const :tag "Anchor at beginning of line" bol)) @@ -799,7 +796,6 @@ bundle agent rcfiles (defcustom cfengine-mode-abbrevs nil "Abbrevs for CFEngine2 mode." - :group 'cfengine :type '(repeat (list (string :tag "Name") (string :tag "Expansion") (choice :tag "Hook" (const nil) function)))) diff --git a/lisp/progmodes/cmacexp.el b/lisp/progmodes/cmacexp.el index 1a45b1cb83..820867ab41 100644 --- a/lisp/progmodes/cmacexp.el +++ b/lisp/progmodes/cmacexp.el @@ -99,13 +99,11 @@ (defcustom c-macro-shrink-window-flag nil "Non-nil means shrink the *Macroexpansion* window to fit its contents." - :type 'boolean - :group 'c-macro) + :type 'boolean) (defcustom c-macro-prompt-flag nil "Non-nil makes `c-macro-expand' prompt for preprocessor arguments." - :type 'boolean - :group 'c-macro) + :type 'boolean) (defcustom c-macro-preprocessor (cond ;; Solaris has it in an unusual place. @@ -129,13 +127,11 @@ If you change this, be sure to preserve the `-C' (don't strip comments) option, or to set an equivalent one." - :type 'string - :group 'c-macro) + :type 'string) (defcustom c-macro-cppflags "" "Preprocessor flags used by `c-macro-expand'." - :type 'string - :group 'c-macro) + :type 'string) (defconst c-macro-buffer-name "*Macroexpansion*") diff --git a/lisp/progmodes/cpp.el b/lisp/progmodes/cpp.el index b2c2e8dab5..6602a79b2a 100644 --- a/lisp/progmodes/cpp.el +++ b/lisp/progmodes/cpp.el @@ -53,8 +53,7 @@ (defcustom cpp-config-file (convert-standard-filename ".cpp.el") "File name to save cpp configuration." - :type 'file - :group 'cpp) + :type 'file) (define-widget 'cpp-face 'lazy "Either a face or the special symbol `invisible'." @@ -62,13 +61,11 @@ (defcustom cpp-known-face 'invisible "Face used for known cpp symbols." - :type 'cpp-face - :group 'cpp) + :type 'cpp-face) (defcustom cpp-unknown-face 'highlight "Face used for unknown cpp symbols." - :type 'cpp-face - :group 'cpp) + :type 'cpp-face) (defcustom cpp-face-type 'light "Indicate what background face type you prefer. @@ -76,18 +73,15 @@ Can be either light or dark for color screens, mono for monochrome screens, and none if you don't use a window system and don't have a color-capable display." :options '(light dark mono nil) - :type 'symbol - :group 'cpp) + :type 'symbol) (defcustom cpp-known-writable t "Non-nil means you are allowed to modify the known conditionals." - :type 'boolean - :group 'cpp) + :type 'boolean) (defcustom cpp-unknown-writable t "Non-nil means you are allowed to modify the unknown conditionals." - :type 'boolean - :group 'cpp) + :type 'boolean) (defcustom cpp-edit-list nil "Alist of cpp macros and information about how they should be displayed. @@ -101,15 +95,13 @@ Each entry is a list with the following elements: (cpp-face :tag "False") (choice (const :tag "True branch writable" t) (const :tag "False branch writable" nil) - (const :tag "Both branches writable" both)))) - :group 'cpp) + (const :tag "Both branches writable" both))))) (defcustom cpp-message-min-time-interval 1.0 "Minimum time interval in seconds for `cpp-progress-message' messages. If nil, `cpp-progress-message' prints no progress messages." :type '(choice (const :tag "Disable progress messages" nil) float) - :group 'cpp :version "26.1") (defvar-local cpp-overlay-list nil @@ -153,36 +145,31 @@ or a cons cell (background-color . COLOR)." :value-type (choice face (const invisible) (cons (const background-color) - (string :tag "Color")))) - :group 'cpp) + (string :tag "Color"))))) (defcustom cpp-face-light-name-list '("light gray" "light blue" "light cyan" "light yellow" "light pink" "pale green" "beige" "orange" "magenta" "violet" "medium purple" "turquoise") "Background colors useful with dark foreground colors." - :type '(repeat string) - :group 'cpp) + :type '(repeat string)) (defcustom cpp-face-dark-name-list '("dim gray" "blue" "cyan" "yellow" "red" "dark green" "brown" "dark orange" "dark khaki" "dark violet" "purple" "dark turquoise") "Background colors useful with light foreground colors." - :type '(repeat string) - :group 'cpp) + :type '(repeat string)) (defcustom cpp-face-light-list nil "Alist of names and faces to be used for light backgrounds." :type '(repeat (cons string (choice face - (cons (const background-color) string)))) - :group 'cpp) + (cons (const background-color) string))))) (defcustom cpp-face-dark-list nil "Alist of names and faces to be used for dark backgrounds." :type '(repeat (cons string (choice face - (cons (const background-color) string)))) - :group 'cpp) + (cons (const background-color) string))))) (defcustom cpp-face-mono-list '(("bold" . bold) @@ -190,15 +177,13 @@ or a cons cell (background-color . COLOR)." ("italic" . italic) ("underline" . underline)) "Alist of names and faces to be used for monochrome screens." - :type '(repeat (cons string face)) - :group 'cpp) + :type '(repeat (cons string face))) (defcustom cpp-face-none-list '(("default" . default) ("invisible" . invisible)) "Alist of names and faces available even if you don't use a window system." - :type '(repeat (cons string cpp-face)) - :group 'cpp) + :type '(repeat (cons string cpp-face))) (defvar cpp-face-all-list (append cpp-face-light-list diff --git a/lisp/progmodes/cwarn.el b/lisp/progmodes/cwarn.el index 042030da39..63b344bea1 100644 --- a/lisp/progmodes/cwarn.el +++ b/lisp/progmodes/cwarn.el @@ -128,8 +128,7 @@ on one of three forms: See variable `cwarn-font-lock-feature-keywords-alist' for available features." - :type '(repeat sexp) - :group 'cwarn) + :type '(repeat sexp)) (defcustom cwarn-font-lock-feature-keywords-alist '((assign . cwarn-font-lock-assignment-keywords) @@ -142,15 +141,13 @@ keyword list." :type '(alist :key-type (choice (const assign) (const semicolon) (const reference)) - :value-type (sexp :tag "Value")) - :group 'cwarn) + :value-type (sexp :tag "Value"))) (defcustom cwarn-verbose t "When nil, CWarn mode will not generate any messages. Currently, messages are generated when the mode is activated and deactivated." - :group 'cwarn :type 'boolean) (defcustom cwarn-mode-text " CWarn" @@ -158,13 +155,11 @@ deactivated." \(When the string is not empty, make sure that it has a leading space.)" :tag "CWarn mode text" ; To separate it from `global-...' - :group 'cwarn :type 'string) (defcustom cwarn-load-hook nil "Functions to run when CWarn mode is first loaded." :tag "Load Hook" - :group 'cwarn :type 'hook) (make-obsolete-variable 'cwarn-load-hook "use `with-eval-after-load' instead." "28.1") diff --git a/lisp/progmodes/dcl-mode.el b/lisp/progmodes/dcl-mode.el index 8943d8b6d0..4a8a20a296 100644 --- a/lisp/progmodes/dcl-mode.el +++ b/lisp/progmodes/dcl-mode.el @@ -97,8 +97,7 @@ dcl-block-begin-regexp and dcl-block-end-regexp. The meaning of this variable may be changed if dcl-calc-command-indent-function is set to a function." - :type 'integer - :group 'dcl) + :type 'integer) (defcustom dcl-continuation-offset 6 @@ -107,8 +106,7 @@ A continuation line is a line that follows a line ending with `-'. The meaning of this variable may be changed if dcl-calc-cont-indent-function is set to a function." - :type 'integer - :group 'dcl) + :type 'integer) (defcustom dcl-margin-offset 8 @@ -117,37 +115,32 @@ The first command line in a file or after a SUBROUTINE statement is indented this much. Other command lines are indented the same number of columns as the preceding command line. A command line is a line that starts with `$'." - :type 'integer - :group 'dcl) + :type 'integer) (defcustom dcl-margin-label-offset 2 "Number of columns to indent a margin label in DCL. A margin label is a label that doesn't begin or end a block, i.e. it doesn't match dcl-block-begin-regexp or dcl-block-end-regexp." - :type 'integer - :group 'dcl) + :type 'integer) (defcustom dcl-comment-line-regexp "^\\$!" "Regexp describing the start of a comment line in DCL. Comment lines are not indented." - :type 'regexp - :group 'dcl) + :type 'regexp) (defcustom dcl-block-begin-regexp "loop[0-9]*:" "Regexp describing a command that begins an indented block in DCL. Set to nil to only indent at THEN-ELSE-ENDIF." - :type 'regexp - :group 'dcl) + :type 'regexp) (defcustom dcl-block-end-regexp "endloop[0-9]*:" "Regexp describing a command that ends an indented block in DCL. Set to nil to only indent at THEN-ELSE-ENDIF." - :type 'regexp - :group 'dcl) + :type 'regexp) (defcustom dcl-calc-command-indent-function nil @@ -178,8 +171,7 @@ CUR-INDENT + EXTRA-INDENT. This package includes two functions suitable for this: dcl-calc-command-indent-multiple dcl-calc-command-indent-hang" - :type '(choice (const nil) function) - :group 'dcl) + :type '(choice (const nil) function)) (defcustom dcl-calc-cont-indent-function 'dcl-calc-cont-indent-relative @@ -196,8 +188,7 @@ CUR-INDENT + EXTRA-INDENT. This package includes one function suitable for this: dcl-calc-cont-indent-relative" - :type 'function - :group 'dcl) + :type 'function) (defcustom dcl-tab-always-indent t @@ -206,50 +197,41 @@ If t, pressing TAB always indents the current line. If nil, pressing TAB indents the current line if point is at the left margin. Data lines (i.e. lines not part of a command line or continuation line) are never indented." - :type 'boolean - :group 'dcl) + :type 'boolean) (defcustom dcl-electric-characters t "Non-nil means reindent immediately when a label, ELSE or ENDIF is inserted." - :type 'boolean - :group 'dcl) + :type 'boolean) (defcustom dcl-tempo-comma ", " "Text to insert when a comma is needed in a template, in DCL mode." - :type 'string - :group 'dcl) + :type 'string) (defcustom dcl-tempo-left-paren "(" "Text to insert when a left parenthesis is needed in a template in DCL." - :type 'string - :group 'dcl) + :type 'string) (defcustom dcl-tempo-right-paren ")" "Text to insert when a right parenthesis is needed in a template in DCL." - :type 'string - :group 'dcl) + :type 'string) ; I couldn't decide what looked best, so I'll let you decide... ; Remember, you can also customize this with imenu-submenu-name-format. (defcustom dcl-imenu-label-labels "Labels" "Imenu menu title for sub-listing with label names." - :type 'string - :group 'dcl) + :type 'string) (defcustom dcl-imenu-label-goto "GOTO" "Imenu menu title for sub-listing with GOTO statements." - :type 'string - :group 'dcl) + :type 'string) (defcustom dcl-imenu-label-gosub "GOSUB" "Imenu menu title for sub-listing with GOSUB statements." - :type 'string - :group 'dcl) + :type 'string) (defcustom dcl-imenu-label-call "CALL" "Imenu menu title for sub-listing with CALL statements." - :type 'string - :group 'dcl) + :type 'string) (defcustom dcl-imenu-generic-expression `((nil "^\\$[ \t]*\\([A-Za-z0-9_$]+\\):[ \t]+SUBROUTINE\\b" 1) @@ -263,14 +245,12 @@ never indented." The default includes SUBROUTINE labels in the main listing and sub-listings for other labels, CALL, GOTO and GOSUB statements. See `imenu-generic-expression' for details." - :type '(repeat (sexp :tag "Imenu Expression")) - :group 'dcl) + :type '(repeat (sexp :tag "Imenu Expression"))) (defcustom dcl-mode-hook nil "Hook called by `dcl-mode'." - :type 'hook - :group 'dcl) + :type 'hook) ;;; *** Global variables **************************************************** @@ -354,16 +334,14 @@ See `imenu-generic-expression' for details." "Regular expression describing white space in a DCL command line. White space is any number of continued lines with only space,tab,endcomment followed by space or tab." - :type 'regexp - :group 'dcl) + :type 'regexp) (defcustom dcl-label-r "[a-zA-Z0-9_$]*:\\([ \t!]\\|$\\)" "Regular expression describing a label. A label is a name followed by a colon followed by white-space or end-of-line." - :type 'regexp - :group 'dcl) + :type 'regexp) (defcustom dcl-cmd-r @@ -373,8 +351,7 @@ A line starting with $, optionally followed by continuation lines, followed by the end of the command line. A continuation line is any characters followed by `-', optionally followed by a comment, followed by a newline." - :type 'regexp - :group 'dcl) + :type 'regexp) (defcustom dcl-command-regexp @@ -384,8 +361,7 @@ A line starting with $, optionally followed by continuation lines, followed by the end of the command line. A continuation line is any characters followed by `-', optionally followed by a comment, followed by a newline." - :type 'regexp - :group 'dcl) + :type 'regexp) (defcustom dcl-electric-reindent-regexps @@ -397,8 +373,7 @@ is defined as dcl-electric-character. E.g.: if this list contains `endif', the key `f' is defined as dcl-electric-character and you have just typed the `f' in `endif', the line will be reindented." - :type '(repeat regexp) - :group 'dcl) + :type '(repeat regexp)) (defvar dcl-option-alist diff --git a/lisp/progmodes/executable.el b/lisp/progmodes/executable.el index fa5724a380..b1cd3303c5 100644 --- a/lisp/progmodes/executable.el +++ b/lisp/progmodes/executable.el @@ -65,8 +65,7 @@ update the magic number." ;;; :type '(choice (const :tag "off" nil) ;;; (const :tag "on" t) ;;; symbol) - :type 'boolean - :group 'executable) + :type 'boolean) (defcustom executable-query 'function @@ -74,21 +73,18 @@ update the magic number." When this is `function', only ask when called non-interactively." :type '(choice (const :tag "Don't Ask" nil) (const :tag "Ask when non-interactive" function) - (other :tag "Ask" t)) - :group 'executable) + (other :tag "Ask" t))) (defcustom executable-magicless-file-regexp "/[Mm]akefile$\\|/\\.\\(z?profile\\|bash_profile\\|z?login\\|bash_login\\|z?logout\\|bash_logout\\|.+shrc\\|esrc\\|rcrc\\|[kz]shenv\\)$" "On files with this kind of name no magic is inserted or changed." - :type 'regexp - :group 'executable) + :type 'regexp) (defcustom executable-prefix "#!" "Interpreter magic number prefix inserted when there was no magic number. Use of `executable-prefix-env' is preferable to this option." :version "26.1" ; deprecated - :type 'string - :group 'executable) + :type 'string) (defcustom executable-prefix-env nil "If non-nil, use \"/usr/bin/env\" in interpreter magic number. @@ -96,8 +92,7 @@ If this variable is non-nil, the interpreter magic number inserted by `executable-set-magic' will be \"#!/usr/bin/env INTERPRETER\", otherwise it will be \"#!/path/to/INTERPRETER\"." :version "26.1" - :type 'boolean - :group 'executable) + :type 'boolean) (defcustom executable-chmod 73 "After saving, if the file is not executable, set this mode. @@ -105,8 +100,7 @@ This mode passed to `set-file-modes' is taken absolutely when negative, or relative to the files existing modes. Do nothing if this is nil. Typical values are 73 (+x) or -493 (rwxr-xr-x)." :type '(choice integer - (const nil)) - :group 'executable) + (const nil))) (defvar executable-command nil) @@ -114,8 +108,7 @@ Typical values are 73 (+x) or -493 (rwxr-xr-x)." (defcustom executable-self-display "tail" "Command you use with argument `-n+2' to make text files self-display. Note that the like of `more' doesn't work too well under Emacs \\[shell]." - :type 'string - :group 'executable) + :type 'string) (make-obsolete-variable 'executable-self-display nil "25.1" 'set) diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index 5d96c62b41..b8c8a827ee 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -1198,7 +1198,6 @@ default) no filter is applied." '(" " flymake-mode-line-title flymake-mode-line-exception flymake-mode-line-counters) "Mode line construct for customizing Flymake information." - :group 'flymake :type '(repeat (choice string symbol))) (defcustom flymake-mode-line-counter-format @@ -1210,7 +1209,6 @@ default) no filter is applied." This is a suitable place for placing the `flymake-error-counter', `flymake-warning-counter' and `flymake-note-counter' constructs. Separating each of these with space is not necessary." - :group 'flymake :type '(repeat (choice string symbol))) (defvar flymake-mode-line-title '(:eval (flymake--mode-line-title)) diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el index eb114acdab..b105cbaa0e 100644 --- a/lisp/progmodes/gud.el +++ b/lisp/progmodes/gud.el @@ -64,8 +64,7 @@ pdb (Python), and jdb." (defcustom gud-key-prefix "\C-x\C-a" "Prefix of all GUD commands valid in C buffers." - :type 'key-sequence - :group 'gud) + :type 'key-sequence) (global-set-key (vconcat gud-key-prefix "\C-l") 'gud-refresh) ;; (define-key ctl-x-map " " 'gud-break); backward compatibility hack @@ -1074,8 +1073,7 @@ The file names should be absolute, or relative to the directory containing the executable being debugged." :type '(choice (const :tag "Current Directory" nil) (repeat :value ("") - directory)) - :group 'gud) + directory))) (defun gud-dbx-massage-args (_file args) (nconc (let ((directories gud-dbx-directories) @@ -1380,8 +1378,7 @@ The file names should be absolute, or relative to the directory containing the executable being debugged." :type '(choice (const :tag "Current Directory" nil) (repeat :value ("") - directory)) - :group 'gud) + directory))) (defun gud-xdb-massage-args (_file args) (nconc (let ((directories gud-xdb-directories) @@ -1563,8 +1560,7 @@ into one that invokes an Emacs-enabled debugging session. (defcustom gud-perldb-command-name "perl -d" "Default command to execute a Perl script under debugger." - :type 'string - :group 'gud) + :type 'string) ;;;###autoload (defun perldb (command-line) @@ -1677,8 +1673,7 @@ and source-file directory for your debugger." (if (executable-find "pdb") "pdb" "python -m pdb") "Command that executes the Python debugger." :version "27.1" - :type 'string - :group 'gud) + :type 'string) ;;;###autoload (defun pdb (command-line) @@ -1759,8 +1754,7 @@ directory and source-file directory for your debugger." "File name for executing the Guile debugger. This should be an executable on your path, or an absolute file name." :version "25.1" - :type 'string - :group 'gud) + :type 'string) ;;;###autoload (defun guiler (command-line) @@ -1883,8 +1877,7 @@ and source-file directory for your debugger." (defcustom gud-jdb-command-name "jdb" "Command that executes the Java debugger." - :type 'string - :group 'gud) + :type 'string) (defcustom gud-jdb-use-classpath t "If non-nil, search for Java source files in classpath directories. @@ -1899,8 +1892,7 @@ and parsing all Java files for class information. Set to nil to use `gud-jdb-directories' to scan java sources for class information on jdb startup (original method)." - :type 'boolean - :group 'gud) + :type 'boolean) (defvar gud-jdb-classpath nil "Java/jdb classpath directories list. @@ -2584,7 +2576,6 @@ Commands: (defcustom gud-chdir-before-run t "Non-nil if GUD should `cd' to the debugged executable." - :group 'gud :type 'boolean) ;; Perform initializations common to all debuggers. @@ -3419,7 +3410,6 @@ Treats actions as defuns." python-mode) "List of modes for which to enable GUD tooltips." :type '(repeat (symbol :tag "Major mode")) - :group 'gud :group 'tooltip) (defcustom gud-tooltip-display @@ -3431,13 +3421,11 @@ Forms in the list are combined with AND. The default is to display only tooltips in the buffer containing the overlay arrow." :type 'sexp :risky t - :group 'gud :group 'tooltip) (defcustom gud-tooltip-echo-area nil "Use the echo area instead of frames for GUD tooltips." :type 'boolean - :group 'gud :group 'tooltip) (make-obsolete-variable 'gud-tooltip-echo-area diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el index 73d09e0059..81ba0d8695 100644 --- a/lisp/progmodes/hideshow.el +++ b/lisp/progmodes/hideshow.el @@ -232,13 +232,11 @@ (defcustom hs-hide-comments-when-hiding-all t "Hide the comments too when you do an `hs-hide-all'." - :type 'boolean - :group 'hideshow) + :type 'boolean) (defcustom hs-minor-mode-hook nil "Hook called when hideshow minor mode is activated or deactivated." :type 'hook - :group 'hideshow :version "21.1") (defcustom hs-isearch-open 'code @@ -254,8 +252,7 @@ This has effect only if `search-invisible' is set to `open'." :type '(choice (const :tag "open only code blocks" code) (const :tag "open only comment blocks" comment) (const :tag "open both code and comment blocks" t) - (const :tag "don't open any of them" nil)) - :group 'hideshow) + (const :tag "don't open any of them" nil))) ;;;###autoload (defvar hs-special-modes-alist diff --git a/lisp/progmodes/icon.el b/lisp/progmodes/icon.el index 933cb333df..a36f020439 100644 --- a/lisp/progmodes/icon.el +++ b/lisp/progmodes/icon.el @@ -86,42 +86,35 @@ (defcustom icon-indent-level 4 "Indentation of Icon statements with respect to containing block." - :type 'integer - :group 'icon) + :type 'integer) (defcustom icon-brace-imaginary-offset 0 "Imagined indentation of an Icon open brace that actually follows a statement." - :type 'integer - :group 'icon) + :type 'integer) (defcustom icon-brace-offset 0 "Extra indentation for braces, compared with other text in same context." - :type 'integer - :group 'icon) + :type 'integer) (defcustom icon-continued-statement-offset 4 "Extra indent for Icon lines not starting new statements." - :type 'integer - :group 'icon) + :type 'integer) (defcustom icon-continued-brace-offset 0 "Extra indent for Icon substatements that start with open-braces. This is in addition to `icon-continued-statement-offset'." - :type 'integer - :group 'icon) + :type 'integer) (defcustom icon-auto-newline nil "Non-nil means automatically newline before and after braces Icon code. This applies when braces are inserted." - :type 'boolean - :group 'icon) + :type 'boolean) (defcustom icon-tab-always-indent t "Non-nil means TAB in Icon mode should always reindent the current line. It will then reindent, regardless of where in the line point is when the TAB command is used." - :type 'boolean - :group 'icon) + :type 'boolean) (defvar icon-imenu-generic-expression '((nil "^[ \t]*procedure[ \t]+\\(\\sw+\\)[ \t]*(" 1)) diff --git a/lisp/progmodes/inf-lisp.el b/lisp/progmodes/inf-lisp.el index ac23059624..146ed4dca4 100644 --- a/lisp/progmodes/inf-lisp.el +++ b/lisp/progmodes/inf-lisp.el @@ -76,8 +76,7 @@ Input matching this regexp is not saved on the input history in Inferior Lisp mode. Default is whitespace followed by 0 or 1 single-letter colon-keyword \(as in :a, :c, etc.)" - :type 'regexp - :group 'inferior-lisp) + :type 'regexp) (defvar inferior-lisp-mode-map (let ((map (copy-keymap comint-mode-map))) @@ -155,8 +154,7 @@ mode. Default is whitespace followed by 0 or 1 single-letter colon-keyword (defcustom inferior-lisp-program "lisp" "Program name for invoking an inferior Lisp in Inferior Lisp mode." - :type 'string - :group 'inferior-lisp) + :type 'string) (defcustom inferior-lisp-load-command "(load \"%s\")\n" "Format-string for building a Lisp expression to load a file. @@ -166,8 +164,7 @@ to load that file. The default works acceptably on most Lisps. The string \"(progn (load \\\"%s\\\" :verbose nil :print t) (values))\\n\" produces cosmetically superior output for this application, but it works only in Common Lisp." - :type 'string - :group 'inferior-lisp) + :type 'string) (defcustom inferior-lisp-prompt "^[^> \n]*>+:? *" "Regexp to recognize prompts in the Inferior Lisp mode. @@ -182,8 +179,7 @@ More precise choices: Lucid Common Lisp: \"^\\\\(>\\\\|\\\\(->\\\\)+\\\\) *\" franz: \"^\\\\(->\\\\|<[0-9]*>:\\\\) *\" kcl: \"^>+ *\"" - :type 'regexp - :group 'inferior-lisp) + :type 'regexp) (defvar inferior-lisp-buffer nil "*The current inferior-lisp process buffer. @@ -487,8 +483,7 @@ describing the last `lisp-load-file' or `lisp-compile-file' command.") If it's loaded into a buffer that is in one of these major modes, it's considered a Lisp source file by `lisp-load-file' and `lisp-compile-file'. Used by these commands to determine defaults." - :type '(repeat symbol) - :group 'inferior-lisp) + :type '(repeat symbol)) (defun lisp-load-file (file-name) "Load a Lisp file into the inferior Lisp process." diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index cdf6536fc7..21bda08680 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -427,22 +427,19 @@ Match group 1 is the name of the macro.") (defcustom js-indent-level 4 "Number of spaces for each indentation step in `js-mode'." :type 'integer - :safe 'integerp - :group 'js) + :safe 'integerp) (defcustom js-expr-indent-offset 0 "Number of additional spaces for indenting continued expressions. The value must be no less than minus `js-indent-level'." :type 'integer - :safe 'integerp - :group 'js) + :safe 'integerp) (defcustom js-paren-indent-offset 0 "Number of additional spaces for indenting expressions in parentheses. The value must be no less than minus `js-indent-level'." :type 'integer :safe 'integerp - :group 'js :version "24.1") (defcustom js-square-indent-offset 0 @@ -450,7 +447,6 @@ The value must be no less than minus `js-indent-level'." The value must be no less than minus `js-indent-level'." :type 'integer :safe 'integerp - :group 'js :version "24.1") (defcustom js-curly-indent-offset 0 @@ -458,7 +454,6 @@ The value must be no less than minus `js-indent-level'." The value must be no less than minus `js-indent-level'." :type 'integer :safe 'integerp - :group 'js :version "24.1") (defcustom js-switch-indent-offset 0 @@ -466,26 +461,22 @@ The value must be no less than minus `js-indent-level'." The value must not be negative." :type 'integer :safe 'integerp - :group 'js :version "24.4") (defcustom js-flat-functions nil "Treat nested functions as top-level functions in `js-mode'. This applies to function movement, marking, and so on." - :type 'boolean - :group 'js) + :type 'boolean) (defcustom js-indent-align-list-continuation t "Align continuation of non-empty ([{ lines in `js-mode'." :version "26.1" :type 'boolean - :safe 'booleanp - :group 'js) + :safe 'booleanp) (defcustom js-comment-lineup-func #'c-lineup-C-comments "Lineup function for `cc-mode-style', for C comments in `js-mode'." - :type 'function - :group 'js) + :type 'function) (defcustom js-enabled-frameworks js--available-frameworks "Frameworks recognized by `js-mode'. @@ -493,30 +484,26 @@ To improve performance, you may turn off some frameworks you seldom use, either globally or on a per-buffer basis." :type (cons 'set (mapcar (lambda (x) (list 'const x)) - js--available-frameworks)) - :group 'js) + js--available-frameworks))) (defcustom js-js-switch-tabs (and (memq system-type '(darwin)) t) "Whether `js-mode' should display tabs while selecting them. This is useful only if the windowing system has a good mechanism for preventing Firefox from stealing the keyboard focus." - :type 'boolean - :group 'js) + :type 'boolean) (defcustom js-js-tmpdir "~/.emacs.d/js/js" "Temporary directory used by `js-mode' to communicate with Mozilla. This directory must be readable and writable by both Mozilla and Emacs." - :type 'directory - :group 'js) + :type 'directory) (defcustom js-js-timeout 5 "Reply timeout for executing commands in Mozilla via `js-mode'. The value is given in seconds. Increase this value if you are getting timeout messages." - :type 'integer - :group 'js) + :type 'integer) (defcustom js-indent-first-init nil "Non-nil means specially indent the first variable declaration's initializer. @@ -557,8 +544,7 @@ don't indent the first one's initializer; otherwise, indent it. bar = 2;" :version "25.1" :type '(choice (const nil) (const t) (const dynamic)) - :safe 'symbolp - :group 'js) + :safe 'symbolp) (defcustom js-chain-indent nil "Use \"chained\" indentation. @@ -571,8 +557,7 @@ then the \".\"s will be lined up: " :version "26.1" :type 'boolean - :safe 'booleanp - :group 'js) + :safe 'booleanp) (defcustom js-jsx-detect-syntax t "When non-nil, automatically detect whether JavaScript uses JSX. @@ -581,8 +566,7 @@ t. The detection strategy can be customized by adding elements to `js-jsx-regexps', which see." :version "27.1" :type 'boolean - :safe 'booleanp - :group 'js) + :safe 'booleanp) (defcustom js-jsx-syntax nil "When non-nil, parse JavaScript with consideration for JSX syntax. @@ -600,8 +584,7 @@ When `js-mode' is already enabled, you should call It is set to be buffer-local (and t) when in `js-jsx-mode'." :version "27.1" :type 'boolean - :safe 'booleanp - :group 'js) + :safe 'booleanp) (defcustom js-jsx-align->-with-< t "When non-nil, “>” will be indented to the opening “<” in JSX. @@ -625,8 +608,7 @@ When this is disabled, JSX indentation looks like this: />" :version "27.1" :type 'boolean - :safe 'booleanp - :group 'js) + :safe 'booleanp) (defcustom js-jsx-indent-level nil "When non-nil, indent JSX by this value, instead of like JS. @@ -655,8 +637,7 @@ indentation looks like this (different): :version "27.1" :type '(choice integer (const :tag "Not Set" nil)) - :safe (lambda (x) (or (null x) (integerp x))) - :group 'js) + :safe (lambda (x) (or (null x) (integerp x)))) ;; This is how indentation behaved out-of-the-box until Emacs 27. JSX ;; indentation was controlled with `sgml-basic-offset', which defaults ;; to 2, whereas `js-indent-level' defaults to 4. Users who had the @@ -685,8 +666,7 @@ indentation looks like this: This variable is like `sgml-attribute-offset'." :version "27.1" :type 'integer - :safe 'integerp - :group 'js) + :safe 'integerp) ;;; KeyMap diff --git a/lisp/progmodes/ld-script.el b/lisp/progmodes/ld-script.el index c4ea8e158d..485e64e249 100644 --- a/lisp/progmodes/ld-script.el +++ b/lisp/progmodes/ld-script.el @@ -35,8 +35,7 @@ (defvar ld-script-location-counter-face 'ld-script-location-counter) (defface ld-script-location-counter '((t :weight bold :inherit font-lock-builtin-face)) - "Face for location counter in GNU ld script." - :group 'ld-script) + "Face for location counter in GNU ld script.") ;; Syntax rules (defvar ld-script-mode-syntax-table diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el index e382d6edcd..3d1e7d634a 100644 --- a/lisp/progmodes/make-mode.el +++ b/lisp/progmodes/make-mode.el @@ -101,14 +101,12 @@ (defface makefile-space '((((class color)) (:background "hotpink")) (t (:reverse-video t))) - "Face to use for highlighting leading spaces in Font-Lock mode." - :group 'makefile) + "Face to use for highlighting leading spaces in Font-Lock mode.") (defface makefile-targets ;; This needs to go along both with foreground and background colors (i.e. shell) '((t (:inherit font-lock-function-name-face))) "Face to use for additionally highlighting rule targets in Font-Lock mode." - :group 'makefile :version "22.1") (defface makefile-shell @@ -116,7 +114,6 @@ ;;'((((class color) (min-colors 88) (background light)) (:background "seashell1")) ;; (((class color) (min-colors 88) (background dark)) (:background "seashell4"))) "Face to use for additionally highlighting Shell commands in Font-Lock mode." - :group 'makefile :version "22.1") (defface makefile-makepp-perl @@ -124,19 +121,16 @@ (((class color) (background dark)) (:background "DarkBlue")) (t (:reverse-video t))) "Face to use for additionally highlighting Perl code in Font-Lock mode." - :group 'makefile :version "22.1") (defcustom makefile-browser-buffer-name "*Macros and Targets*" "Name of the macro- and target browser buffer." - :type 'string - :group 'makefile) + :type 'string) (defcustom makefile-target-colon ":" "String to append to all target names inserted by `makefile-insert-target'. \":\" or \"::\" are common values." - :type 'string - :group 'makefile) + :type 'string) (defcustom makefile-macro-assign " = " "String to append to all macro names inserted by `makefile-insert-macro'. @@ -144,70 +138,58 @@ The normal value should be \" = \", since this is what standard make expects. However, newer makes such as dmake allow a larger variety of different macro assignments, so you might prefer to use \" += \" or \" := \" ." - :type 'string - :group 'makefile) + :type 'string) (defcustom makefile-electric-keys nil "If non-nil, Makefile mode should install electric keybindings. Default is nil." - :type 'boolean - :group 'makefile) + :type 'boolean) (defcustom makefile-use-curly-braces-for-macros-p nil "Controls the style of generated macro references. Non-nil means macro references should use curly braces, like `${this}'. nil means use parentheses, like `$(this)'." - :type 'boolean - :group 'makefile) + :type 'boolean) (defcustom makefile-tab-after-target-colon t "If non-nil, insert a TAB after a target colon. Otherwise, a space is inserted. The default is t." - :type 'boolean - :group 'makefile) + :type 'boolean) (defcustom makefile-browser-leftmost-column 10 "Number of blanks to the left of the browser selection mark." - :type 'integer - :group 'makefile) + :type 'integer) (defcustom makefile-browser-cursor-column 10 "Column the cursor goes to when it moves up or down in the Makefile browser." - :type 'integer - :group 'makefile) + :type 'integer) (defcustom makefile-backslash-column 48 "Column in which `makefile-backslash-region' inserts backslashes." - :type 'integer - :group 'makefile) + :type 'integer) (defcustom makefile-backslash-align t "If non-nil, `makefile-backslash-region' will align backslashes." - :type 'boolean - :group 'makefile) + :type 'boolean) (defcustom makefile-browser-selected-mark "+ " "String used to mark selected entries in the Makefile browser." - :type 'string - :group 'makefile) + :type 'string) (defcustom makefile-browser-unselected-mark " " "String used to mark unselected entries in the Makefile browser." - :type 'string - :group 'makefile) + :type 'string) (defcustom makefile-browser-auto-advance-after-selection-p t "If non-nil, cursor will move after item is selected in Makefile browser." - :type 'boolean - :group 'makefile) + :type 'boolean) (defcustom makefile-pickup-everything-picks-up-filenames-p nil "If non-nil, `makefile-pickup-everything' picks up filenames as targets. This means it calls `makefile-pickup-filenames-as-targets'. Otherwise filenames are omitted." - :type 'boolean - :group 'makefile) + :type 'boolean) (defcustom makefile-cleanup-continuations nil "If non-nil, automatically clean up continuation lines when saving. @@ -215,13 +197,11 @@ A line is cleaned up by removing all whitespace following a trailing backslash. This is done silently. IMPORTANT: Please note that enabling this option causes Makefile mode to MODIFY A FILE WITHOUT YOUR CONFIRMATION when \"it seems necessary\"." - :type 'boolean - :group 'makefile) + :type 'boolean) (defcustom makefile-mode-hook nil "Normal hook run by `makefile-mode'." - :type 'hook - :group 'makefile) + :type 'hook) (defvar makefile-browser-hook '()) @@ -240,8 +220,7 @@ to MODIFY A FILE WITHOUT YOUR CONFIRMATION when \"it seems necessary\"." "List of special targets. You will be offered to complete on one of those in the minibuffer whenever you enter a \".\" at the beginning of a line in `makefile-mode'." - :type '(repeat string) - :group 'makefile) + :type '(repeat string)) (put 'makefile-special-targets-list 'risky-local-variable t) (defcustom makefile-runtime-macros-list @@ -250,8 +229,7 @@ you enter a \".\" at the beginning of a line in `makefile-mode'." If you insert a macro reference using `makefile-insert-macro-ref', the name of the macro is checked against this list. If it can be found its name will not be enclosed in { } or ( )." - :type '(repeat (list string)) - :group 'makefile) + :type '(repeat (list string))) ;; Note that the first big subexpression is used by font lock. Note ;; that if you change this regexp you might have to fix the imenu @@ -563,8 +541,7 @@ not be enclosed in { } or ( )." (defcustom makefile-brave-make "make" "How to invoke make, for `makefile-query-targets'. This should identify a `make' command that can handle the `-q' option." - :type 'string - :group 'makefile) + :type 'string) (defvaralias 'makefile-query-one-target-method 'makefile-query-one-target-method-function) @@ -584,13 +561,11 @@ The function must satisfy this calling convention: * It must return the integer value 0 (zero) if the given target should be considered up-to-date in the context of the given makefile, any nonzero integer value otherwise." - :type 'function - :group 'makefile) + :type 'function) (defcustom makefile-up-to-date-buffer-name "*Makefile Up-to-date overview*" "Name of the Up-to-date overview buffer." - :type 'string - :group 'makefile) + :type 'string) ;;; --- end of up-to-date-overview configuration ------------------ diff --git a/lisp/progmodes/modula2.el b/lisp/progmodes/modula2.el index a77a4e2b21..536d3be005 100644 --- a/lisp/progmodes/modula2.el +++ b/lisp/progmodes/modula2.el @@ -51,23 +51,19 @@ (defcustom m2-compile-command "m2c" "Command to compile Modula-2 programs." - :type 'string - :group 'modula2) + :type 'string) (defcustom m2-link-command "m2l" "Command to link Modula-2 programs." - :type 'string - :group 'modula2) + :type 'string) (defcustom m2-link-name nil "Name of the Modula-2 executable." - :type '(choice (const nil) string) - :group 'modula2) + :type '(choice (const nil) string)) (defcustom m2-end-comment-column 75 "Column for aligning the end of a comment, in Modula-2." - :type 'integer - :group 'modula2) + :type 'integer) ;;; Added by TEP (defvar m2-mode-map @@ -105,8 +101,7 @@ (defcustom m2-indent 5 "This variable gives the indentation in Modula-2 mode." - :type 'integer - :group 'modula2) + :type 'integer) (put 'm2-indent 'safe-local-variable (lambda (v) (or (null v) (integerp v)))) diff --git a/lisp/progmodes/pascal.el b/lisp/progmodes/pascal.el index 59f90d7293..e6e6e40aa1 100644 --- a/lisp/progmodes/pascal.el +++ b/lisp/progmodes/pascal.el @@ -199,38 +199,32 @@ (defcustom pascal-indent-level 3 "Indentation of Pascal statements with respect to containing block." - :type 'integer - :group 'pascal) + :type 'integer) (defcustom pascal-case-indent 2 "Indentation for case statements." - :type 'integer - :group 'pascal) + :type 'integer) (defcustom pascal-auto-newline nil "Non-nil means automatically insert newlines in certain cases. These include after semicolons and after the punctuation mark after an `end'." - :type 'boolean - :group 'pascal) + :type 'boolean) (defcustom pascal-indent-nested-functions t "Non-nil means nested functions are indented." - :type 'boolean - :group 'pascal) + :type 'boolean) (defcustom pascal-tab-always-indent t "Non-nil means TAB in Pascal mode should always reindent the current line. If this is nil, TAB inserts a tab if it is at the end of the line and follows non-whitespace text." - :type 'boolean - :group 'pascal) + :type 'boolean) (defcustom pascal-auto-endcomments t "Non-nil means automatically insert comments after certain `end's. Specifically, this is done after the ends of case statements and functions. The name of the function or case is included between the braces." - :type 'boolean - :group 'pascal) + :type 'boolean) (defcustom pascal-auto-lineup '(all) "List of contexts where auto lineup of :'s or ='s should be done. @@ -243,8 +237,7 @@ will do all lineups." (const :tag "Everything" all) (const :tag "Parameter lists" paramlist) (const :tag "Declarations" declaration) - (const :tag "Case statements" case)) - :group 'pascal) + (const :tag "Case statements" case))) (defvar pascal-toggle-completions nil "If non-nil, `pascal-complete-word' tries all possible completions. @@ -260,8 +253,7 @@ completions.") These include integer, real, char, etc. The types defined within the Pascal program are handled in another way, and should not be added to this list." - :type '(repeat (string :tag "Keyword")) - :group 'pascal) + :type '(repeat (string :tag "Keyword"))) (defcustom pascal-start-keywords '("begin" "end" "function" "procedure" "repeat" "until" "while" @@ -270,8 +262,7 @@ are handled in another way, and should not be added to this list." These are keywords such as begin, repeat, until, readln. The procedures and variables defined within the Pascal program are handled in another way, and should not be added to this list." - :type '(repeat (string :tag "Keyword")) - :group 'pascal) + :type '(repeat (string :tag "Keyword"))) (defcustom pascal-separator-keywords '("downto" "else" "mod" "div" "then") @@ -279,8 +270,7 @@ are handled in another way, and should not be added to this list." These are keywords such as downto, else, mod, then. Variables and function names defined within the Pascal program are handled in another way, and should not be added to this list." - :type '(repeat (string :tag "Keyword")) - :group 'pascal) + :type '(repeat (string :tag "Keyword"))) ;;; diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el index 0120e4a7cd..c7fa5ab84b 100644 --- a/lisp/progmodes/perl-mode.el +++ b/lisp/progmodes/perl-mode.el @@ -98,8 +98,7 @@ (defface perl-non-scalar-variable '((t :inherit font-lock-variable-name-face :underline t)) "Face used for non-scalar variables." - :version "28.1" - :group 'perl) + :version "28.1") (defvar perl-mode-abbrev-table nil "Abbrev table in use in perl-mode buffers.") @@ -640,7 +639,6 @@ This is a non empty list of strings, the checker tool possibly followed by required arguments. Once launched it will receive the Perl source to be checked as its standard input." :version "26.1" - :group 'perl :type '(repeat string)) (defvar-local perl--flymake-proc nil) diff --git a/lisp/progmodes/prog-mode.el b/lisp/progmodes/prog-mode.el index d88d350558..19de7545bf 100644 --- a/lisp/progmodes/prog-mode.el +++ b/lisp/progmodes/prog-mode.el @@ -41,8 +41,7 @@ :type 'hook :options '(flyspell-prog-mode abbrev-mode flymake-mode display-line-numbers-mode - prettify-symbols-mode) - :group 'prog-mode) + prettify-symbols-mode)) (defvar prog-mode-map (let ((map (make-sparse-keymap))) @@ -166,8 +165,7 @@ on the symbol." :version "25.1" :type '(choice (const :tag "Never unprettify" nil) (const :tag "Unprettify when point is inside" t) - (const :tag "Unprettify when point is inside or at right edge" right-edge)) - :group 'prog-mode) + (const :tag "Unprettify when point is inside or at right edge" right-edge))) (defun prettify-symbols--post-command-hook () (cl-labels ((get-prop-as-list diff --git a/lisp/progmodes/simula.el b/lisp/progmodes/simula.el index a863e7eb4b..fab600f83f 100644 --- a/lisp/progmodes/simula.el +++ b/lisp/progmodes/simula.el @@ -51,16 +51,14 @@ the run of whitespace at the beginning of the line.") "Non-nil means TAB in SIMULA mode should always reindent the current line. Otherwise TAB indents only when point is within the run of whitespace at the beginning of the line." - :type 'boolean - :group 'simula) + :type 'boolean) (defconst simula-indent-level-default 3 "Indentation of SIMULA statements with respect to containing block.") (defcustom simula-indent-level simula-indent-level-default "Indentation of SIMULA statements with respect to containing block." - :type 'integer - :group 'simula) + :type 'integer) (defconst simula-substatement-offset-default 3 @@ -68,8 +66,7 @@ the run of whitespace at the beginning of the line." (defcustom simula-substatement-offset simula-substatement-offset-default "Extra indentation after DO, THEN, ELSE, WHEN and OTHERWISE." - :type 'integer - :group 'simula) + :type 'integer) (defconst simula-continued-statement-offset-default 3 "Extra indentation for lines not starting a statement or substatement. @@ -83,16 +80,14 @@ the previous line of the statement.") If value is a list, each line in a multipleline continued statement will have the car of the list extra indentation with respect to the previous line of the statement." - :type 'integer - :group 'simula) + :type 'integer) (defconst simula-label-offset-default -4711 "Offset of SIMULA label lines relative to usual indentation.") (defcustom simula-label-offset simula-label-offset-default "Offset of SIMULA label lines relative to usual indentation." - :type 'integer - :group 'simula) + :type 'integer) (defconst simula-if-indent-default '(0 . 0) "Extra indentation of THEN and ELSE with respect to the starting IF. @@ -103,8 +98,7 @@ extra ELSE indentation. IF after ELSE is indented as the starting IF.") "Extra indentation of THEN and ELSE with respect to the starting IF. Value is a cons cell, the car is extra THEN indentation and the cdr extra ELSE indentation. IF after ELSE is indented as the starting IF." - :type '(cons integer integer) - :group 'simula) + :type '(cons integer integer)) (defconst simula-inspect-indent-default '(0 . 0) "Extra indentation of WHEN and OTHERWISE with respect to the INSPECT. @@ -115,16 +109,14 @@ and the cdr extra OTHERWISE indentation.") "Extra indentation of WHEN and OTHERWISE with respect to the INSPECT. Value is a cons cell, the car is extra WHEN indentation and the cdr extra OTHERWISE indentation." - :type '(cons integer integer) - :group 'simula) + :type '(cons integer integer)) (defconst simula-electric-indent-default nil "Non-nil means `simula-indent-line' function may reindent previous line.") (defcustom simula-electric-indent simula-electric-indent-default "Non-nil means `simula-indent-line' function may reindent previous line." - :type 'boolean - :group 'simula) + :type 'boolean) (defconst simula-abbrev-keyword-default 'upcase "Specify how to convert case for SIMULA keywords. @@ -135,8 +127,7 @@ Value is one of the symbols `upcase', `downcase', `capitalize', "Specify how to convert case for SIMULA keywords. Value is one of the symbols `upcase', `downcase', `capitalize', \(as in) `abbrev-table' or nil if they should not be changed." - :type '(choice (const upcase) (const downcase) (const capitalize)(const nil)) - :group 'simula) + :type '(choice (const upcase) (const downcase) (const capitalize)(const nil))) (defconst simula-abbrev-stdproc-default 'abbrev-table "Specify how to convert case for standard SIMULA procedure and class names. @@ -148,16 +139,14 @@ Value is one of the symbols `upcase', `downcase', `capitalize', Value is one of the symbols `upcase', `downcase', `capitalize', \(as in) `abbrev-table', or nil if they should not be changed." :type '(choice (const upcase) (const downcase) (const capitalize) - (const abbrev-table) (const nil)) - :group 'simula) + (const abbrev-table) (const nil))) (defcustom simula-abbrev-file nil "File with extra abbrev definitions for use in SIMULA mode. These are used together with the standard abbrev definitions for SIMULA. Please note that the standard definitions are required for SIMULA mode to function correctly." - :type '(choice file (const nil)) - :group 'simula) + :type '(choice file (const nil))) (defvar simula-mode-syntax-table nil "Syntax table in SIMULA mode buffers.") diff --git a/lisp/progmodes/xscheme.el b/lisp/progmodes/xscheme.el index e85e3cfdbb..613863dd61 100644 --- a/lisp/progmodes/xscheme.el +++ b/lisp/progmodes/xscheme.el @@ -104,20 +104,17 @@ reading-string reading prompt string") (defcustom scheme-band-name nil "Band loaded by the `run-scheme' command." - :type '(choice (const nil) string) - :group 'xscheme) + :type '(choice (const nil) string)) (defcustom scheme-program-arguments nil "Arguments passed to the Scheme program by the `run-scheme' command." - :type '(choice (const nil) string) - :group 'xscheme) + :type '(choice (const nil) string)) (defcustom xscheme-allow-pipelined-evaluation t "If non-nil, an expression may be transmitted while another is evaluating. Otherwise, attempting to evaluate an expression before the previous expression has finished evaluating will signal an error." - :type 'boolean - :group 'xscheme) + :type 'boolean) (defcustom xscheme-startup-message "This is the Scheme process buffer. @@ -128,19 +125,16 @@ Type \\[describe-mode] for more information. " "String to insert into Scheme process buffer first time it is started. Is processed with `substitute-command-keys' first." - :type 'string - :group 'xscheme) + :type 'string) (defcustom xscheme-signal-death-message nil "If non-nil, causes a message to be generated when the Scheme process dies." - :type 'boolean - :group 'xscheme) + :type 'boolean) (defcustom xscheme-start-hook nil "If non-nil, a procedure to call when the Scheme process is started. When called, the current buffer will be the Scheme process-buffer." :type 'hook - :group 'xscheme :version "20.3") (defun xscheme-evaluation-commands (keymap) commit ca0842347e5437bcaeeded4a7fd55e0e48ed4bad Author: Stefan Monnier Date: Fri Feb 12 22:53:38 2021 -0500 Edebug: Make it possible to debug `gv-expander`s in `declare` Arrange for declarations to be able to specify their own specs via the `edebug-declaration-spec` property. * lisp/emacs-lisp/edebug.el: (edebug--get-declare-spec): New function. (def-declarations): New spec element. (defun, defmacro): Use it in their spec. * lisp/emacs-lisp/gv.el (gv-expander, gv-setter): Set `edebug-declaration-spec`. * test/lisp/emacs-lisp/edebug-tests.el (edebug-tests-gv-expander): New test. * test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el (edebug-test-code-use-gv-expander): New test case. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 47b45614e7..394f47090c 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -2207,14 +2207,12 @@ into `edebug--cl-macrolet-defs' which is checked in `edebug-list-form-args'." ;; `defun' and `defmacro' are not special forms (any more), but it's ;; more convenient to define their Edebug spec here. (defun ( &define name lambda-list lambda-doc - [&optional ("declare" &rest sexp)] + [&optional ("declare" def-declarations)] [&optional ("interactive" &optional &or stringp def-form)] def-body)) - ;; FIXME: Improve `declare' so we can Edebug gv-expander and - ;; gv-setter declarations. (defmacro ( &define name lambda-list lambda-doc - [&optional ("declare" &rest sexp)] + [&optional ("declare" def-declarations)] def-body)) ;; function expects a symbol or a lambda or macro expression @@ -2243,6 +2241,12 @@ into `edebug--cl-macrolet-defs' which is checked in `edebug-list-form-args'." )) (put name 'edebug-form-spec spec)) +(defun edebug--get-declare-spec (head) + (get head 'edebug-declaration-spec)) + +(def-edebug-elem-spec 'def-declarations + '(&rest &or (&lookup symbolp edebug--get-declare-spec) sexp)) + (def-edebug-elem-spec 'lambda-list '(([&rest arg] [&optional ["&optional" arg &rest arg]] diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el index c160aa1fd3..edacdf7f0c 100644 --- a/lisp/emacs-lisp/gv.el +++ b/lisp/emacs-lisp/gv.el @@ -187,6 +187,11 @@ arguments as NAME. DO is a function as defined in `gv-get'." (push (list 'gv-setter #'gv--setter-defun-declaration) defun-declarations-alist)) +;;;###autoload +(let ((spec '(&or symbolp ("lambda" &define lambda-list def-body)))) + (put 'gv-expander 'edebug-declaration-spec spec) + (put 'gv-setter 'edebug-declaration-spec spec)) + ;; (defmacro gv-define-expand (name expander) ;; "Use EXPANDER to handle NAME as a generalized var. ;; NAME is a symbol: the name of a function, macro, or special form. diff --git a/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el b/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el index d77df3c3c5..835d3781d0 100644 --- a/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el +++ b/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el @@ -147,5 +147,11 @@ ;; of the same name. (message "Hi %s" (gate 7)))) +(defun edebug-test-code-use-gv-expander (x) + (declare (gv-expander + (lambda (do) + (funcall do `(car ,x) (lambda (v) `(setcar ,x ,v)))))) + (car x)) + (provide 'edebug-test-code) ;;; edebug-test-code.el ends here diff --git a/test/lisp/emacs-lisp/edebug-tests.el b/test/lisp/emacs-lisp/edebug-tests.el index c11bfcf001..dfe2cb3206 100644 --- a/test/lisp/emacs-lisp/edebug-tests.el +++ b/test/lisp/emacs-lisp/edebug-tests.el @@ -959,6 +959,17 @@ primary ones (Bug#42671)." (edebug-tests-with-normal-env (edebug-tests-setup-@ "cl-flet1" '(10) t))) +(ert-deftest edebug-tests-gv-expander () + "Edebug can instrument `gv-expander' expressions." + (edebug-tests-with-normal-env + (edebug-tests-setup-@ "use-gv-expander" nil t) + (should (equal + (catch 'text + (run-at-time 0 nil + (lambda () (throw 'text (buffer-substring (point) (+ (point) 5))))) + (eval '(setf (edebug-test-code-use-gv-expander (cons 'a 'b)) 3) t)) + "(func")))) + (ert-deftest edebug-tests-cl-flet () "Check that Edebug can instrument `cl-flet' forms without name clashes (Bug#41853)." commit 626911b704b3f144e9b8dbd187c394ed90e8411c Author: Stefan Kangas Date: Sat Feb 13 00:21:36 2021 +0100 Comment out mysterious code from cperl-mode.el * lisp/progmodes/cperl-mode.el: Comment out mysterious code referring to some unknown variable 'edit-var-mode-alist'. No one seems to know what it is used for, so comment it out and see if anyone complains before Emacs 28.1 or 28.2. diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index 167b2c6f33..0dffe279c3 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -975,9 +975,12 @@ versions of Emacs." "Abbrev table in use in CPerl mode buffers." :parents (list cperl-mode-electric-keywords-abbrev-table)) -(when (boundp 'edit-var-mode-alist) - ;; FIXME: What package uses this? - (add-to-list 'edit-var-mode-alist '(perl-mode (regexp . "^cperl-")))) +;; ;; TODO: Commented out as we don't know what it is used for. If +;; ;; there are no bug reports about this for Emacs 28.1, this +;; ;; can probably be removed. (Code search online reveals nothing.) +;; (when (boundp 'edit-var-mode-alist) +;; ;; FIXME: What package uses this? +;; (add-to-list 'edit-var-mode-alist '(perl-mode (regexp . "^cperl-")))) (defvar cperl-mode-map (let ((map (make-sparse-keymap))) commit 24a98755ab7dd6b0805da02d040c9eb3bf5feac9 Author: Stefan Kangas Date: Sat Feb 13 00:10:38 2021 +0100 Remove outdated documentation from cperl-mode.el * lisp/progmodes/cperl-mode.el (cperl-tips, cperl-problems) (cperl-praise, cperl-speed, cperl-mode): Doc fixes; remove references to very old versions of Emacs and other "Emaxen". (cperl-problems-old-emaxen): Make obsolete and remove information on Emacs 20.3 and older. diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index 97d0e36464..167b2c6f33 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -659,8 +659,8 @@ Run Perl/Tools/Insert-spaces-if-needed to fix your lazy typing. Switch auto-help on/off with Perl/Tools/Auto-help. -Though with contemporary Emaxen CPerl mode should maintain the correct -parsing of Perl even when editing, sometimes it may be lost. Fix this by +Though CPerl mode should maintain the correct parsing of Perl even when +editing, sometimes it may be lost. Fix this by \\[normal-mode] @@ -676,63 +676,20 @@ micro-docs on what I know about CPerl problems.") "Description of problems in CPerl mode. `fill-paragraph' on a comment may leave the point behind the paragraph. It also triggers a bug in some versions of Emacs (CPerl tries -to detect it and bulk out). - -See documentation of a variable `cperl-problems-old-emaxen' for the -problems which disappear if you upgrade Emacs to a reasonably new -version (20.3 for Emacs).") +to detect it and bulk out).") (defvar cperl-problems-old-emaxen 'please-ignore-this-line - "Description of problems in CPerl mode specific for older Emacs versions. - -Emacs had a _very_ restricted syntax parsing engine until version -20.1. Most problems below are corrected starting from this version of -Emacs, and all of them should be fixed in version 20.3. (Or apply -patches to Emacs 19.33/34 - see tips.) - -Note that even with newer Emacsen in some very rare cases the details -of interaction of `font-lock' and syntaxification may be not cleaned -up yet. You may get slightly different colors basing on the order of -fontification and syntaxification. Say, the initial faces is correct, -but editing the buffer breaks this. - -Even with older Emacsen CPerl mode tries to corrects some Emacs -misunderstandings, however, for efficiency reasons the degree of -correction is different for different operations. The partially -corrected problems are: POD sections, here-documents, regexps. The -operations are: highlighting, indentation, electric keywords, electric -braces. - -This may be confusing, since the regexp s#//#/#; may be highlighted -as a comment, but it will be recognized as a regexp by the indentation -code. Or the opposite case, when a POD section is highlighted, but -may break the indentation of the following code (though indentation -should work if the balance of delimiters is not broken by POD). - -The main trick (to make $ a \"backslash\") makes constructions like -${aaa} look like unbalanced braces. The only trick I can think of is -to insert it as $ {aaa} (valid in perl5, not in perl4). - -Similar problems arise in regexps, when /(\\s|$)/ should be rewritten -as /($|\\s)/. Note that such a transposition is not always possible. - -The solution is to upgrade your Emacs or patch an older one. Note -that Emacs 20.2 has some bugs related to `syntax-table' text -properties. Patches are available on the main CPerl download site, -and on CPAN. - -If these bugs cannot be fixed on your machine (say, you have an inferior -environment and cannot recompile), you may still disable all the fancy stuff -via `cperl-use-syntax-table-text-property'.") + "This used to contain a description of problems in CPerl mode +specific for very old Emacs versions. This is no longer relevant +and has been removed.") +(make-obsolete-variable 'cperl-problems-old-emaxen nil "28.1") (defvar cperl-praise 'please-ignore-this-line "Advantages of CPerl mode. 0) It uses the newest `syntax-table' property ;-); -1) It does 99% of Perl syntax correct (as opposed to 80-90% in Perl -mode - but the latter number may have improved too in last years) even -with old Emaxen which do not support `syntax-table' property. +1) It does 99% of Perl syntax correct. When using `syntax-table' property for syntax assist hints, it should handle 99.995% of lines correct - or somesuch. It automatically @@ -813,8 +770,7 @@ the settings present before the switch. 9) When doing indentation of control constructs, may correct line-breaks/spacing between elements of the construct. -10) Uses a linear-time algorithm for indentation of regions (on Emaxen with -capable syntax engines). +10) Uses a linear-time algorithm for indentation of regions. 11) Syntax-highlight, indentation, sexp-recognition inside regular expressions. ") @@ -838,8 +794,8 @@ syntax-parsing routines, and marks them up so that either A1) CPerl may work around these deficiencies (for big chunks, mostly PODs and HERE-documents), or - A2) On capable Emaxen CPerl will use improved syntax-handling - which reads mark-up hints directly. + A2) CPerl will use improved syntax-handling which reads mark-up + hints directly. The scan in case A2 is much more comprehensive, thus may be slower. @@ -1514,8 +1470,7 @@ span the needed amount of lines. Variables `cperl-pod-here-scan', `cperl-pod-here-fontify', `cperl-pod-face', `cperl-pod-head-face' control processing of POD and -here-docs sections. With capable Emaxen results of scan are used -for indentation too, otherwise they are used for highlighting only. +here-docs sections. Results of scan are used for indentation too. Variables controlling indentation style: `cperl-tab-always-indent' commit d1be48fdedabb451d5c6cf315fd5f09a632e771f Author: Stefan Monnier Date: Fri Feb 12 19:28:25 2021 -0500 Edebug: Overload `edebug-form-spec` even less The `edebug-form-spec` symbol property was used both to map forms's head symbol to the corresponding spec, and to map spec element names to their expansion. This lead to name conflicts which break instrumentation of examples such as (cl-flet ((gate (x) x)) (gate 4)) because of the Edebug spec element `gate`. So introduce a new symbol property `edebug-elem-spec`. * lisp/subr.el (def-edebug-elem-spec): New function. * lisp/emacs-lisp/edebug.el (edebug--get-elem-spec): New function. (edebug-match-symbol): Use it. (Core Edebug elems): Put them on `edebug-elem-spec` instead of `edebug-form-spec`. (ELisp special forms): Set their `edebug-form-spec` via dolist. (Other non-core Edebug elems): Use `def-edebug-elem-spec`. (edebug-\`): Use `declare`. * lisp/emacs-lisp/pcase.el (pcase-PAT, pcase-FUN, pcase-QPAT): * lisp/skeleton.el (skeleton-edebug-spec): * lisp/emacs-lisp/cl-macs.el: Use `def-edebug-elem-spec`. * test/lisp/emacs-lisp/edebug-tests.el (edebug-tests--conflicting-internal-names): New test. * test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el (edebug-test-code-cl-flet1): New test case. * doc/lispref/edebug.texi (Specification List): Add `def-edebug-elem-spec`. (Specification Examples): Use it. * doc/lispref/loading.texi (Hooks for Loading): Avoid the use of `def-edebug-spec` in example (better use `debug` declaration). diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi index 693d0e0630..99d55c7ab9 100644 --- a/doc/lispref/edebug.texi +++ b/doc/lispref/edebug.texi @@ -1203,7 +1203,7 @@ define Edebug specifications for special forms implemented in C. @defmac def-edebug-spec macro specification Specify which expressions of a call to macro @var{macro} are forms to be -evaluated. @var{specification} should be the edebug specification. +evaluated. @var{specification} should be the Edebug specification. Neither argument is evaluated. The @var{macro} argument can actually be any symbol, not just a macro @@ -1389,8 +1389,13 @@ indirect specification. If the symbol has an Edebug specification, this @dfn{indirect specification} should be either a list specification that is used in place of the symbol, or a function that is called to process the -arguments. The specification may be defined with @code{def-edebug-spec} -just as for macros. See the @code{defun} example. +arguments. The specification may be defined with +@code{def-edebug-elem-spec}: + +@defun def-edebug-elem-spec element specification +Define the @var{specification} to use in place of the symbol @var{element}. +@var{specification} has to be a list. +@end defun Otherwise, the symbol should be a predicate. The predicate is called with the argument, and if the predicate returns @code{nil}, the @@ -1568,14 +1573,14 @@ specification for @code{defmacro} is very similar to that for [&optional ("interactive" interactive)] def-body)) -(def-edebug-spec lambda-list - (([&rest arg] - [&optional ["&optional" arg &rest arg]] - &optional ["&rest" arg] - ))) +(def-edebug-elem-spec 'lambda-list + '(([&rest arg] + [&optional ["&optional" arg &rest arg]] + &optional ["&rest" arg] + ))) -(def-edebug-spec interactive - (&optional &or stringp def-form)) ; @r{Notice: @code{def-form}} +(def-edebug-elem-spec 'interactive + '(&optional &or stringp def-form)) ; @r{Notice: @code{def-form}} @end smallexample The specification for backquote below illustrates how to match @@ -1588,11 +1593,11 @@ could fail.) @smallexample (def-edebug-spec \` (backquote-form)) ; @r{Alias just for clarity.} -(def-edebug-spec backquote-form - (&or ([&or "," ",@@"] &or ("quote" backquote-form) form) - (backquote-form . [&or nil backquote-form]) - (vector &rest backquote-form) - sexp)) +(def-edebug-elem-spec 'backquote-form + '(&or ([&or "," ",@@"] &or ("quote" backquote-form) form) + (backquote-form . [&or nil backquote-form]) + (vector &rest backquote-form) + sexp)) @end smallexample @@ -1635,10 +1640,10 @@ option. @xref{Instrumenting}. @defopt edebug-eval-macro-args When this is non-@code{nil}, all macro arguments will be instrumented -in the generated code. For any macro, an @code{edebug-form-spec} +in the generated code. For any macro, the @code{debug} declaration overrides this option. So to specify exceptions for macros that have -some arguments evaluated and some not, use @code{def-edebug-spec} to -specify an @code{edebug-form-spec}. +some arguments evaluated and some not, use the @code{debug} declaration +specify an Edebug form specification. @end defopt @defopt edebug-save-windows diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi index 22f0dde593..33f3733194 100644 --- a/doc/lispref/loading.texi +++ b/doc/lispref/loading.texi @@ -1125,7 +1125,7 @@ You don't need to give a directory or extension in the file name @var{library}. Normally, you just give a bare file name, like this: @example -(with-eval-after-load "edebug" (def-edebug-spec c-point t)) +(with-eval-after-load "js" (define-key js-mode-map "\C-c\C-c" 'js-eval)) @end example To restrict which files can trigger the evaluation, include a diff --git a/etc/NEWS b/etc/NEWS index fe626fec7e..464b955ee7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -938,6 +938,13 @@ To customize obsolete user options, use 'customize-option' or --- *** 'get-edebug-spec' is obsolete, replaced by 'edebug-get-spec'. ++++ +*** New function 'def-edebug-elem-spec' to define Edebug spec elements. +These used to be defined with 'def-edebug-spec' thus conflating the +two name spaces, which lead to name collisions. +The use of 'def-edebug-spec' to define Edebug spec elements is +declared obsolete. + *** Edebug specification lists can use some new keywords: +++ diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index c312afe55b..5967e0d084 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -186,14 +186,14 @@ The name is made by appending a number to PREFIX, default \"T\"." ;;; Program structure. -(def-edebug-spec cl-declarations - (&rest ("cl-declare" &rest sexp))) +(def-edebug-elem-spec 'cl-declarations + '(&rest ("cl-declare" &rest sexp))) -(def-edebug-spec cl-declarations-or-string - (&or lambda-doc cl-declarations)) +(def-edebug-elem-spec 'cl-declarations-or-string + '(&or lambda-doc cl-declarations)) -(def-edebug-spec cl-lambda-list - (([&rest cl-lambda-arg] +(def-edebug-elem-spec 'cl-lambda-list + '(([&rest cl-lambda-arg] [&optional ["&optional" cl-&optional-arg &rest cl-&optional-arg]] [&optional ["&rest" cl-lambda-arg]] [&optional ["&key" [cl-&key-arg &rest cl-&key-arg] @@ -202,27 +202,27 @@ The name is made by appending a number to PREFIX, default \"T\"." &or (cl-lambda-arg &optional def-form) arg]] . [&or arg nil]))) -(def-edebug-spec cl-&optional-arg - (&or (cl-lambda-arg &optional def-form arg) arg)) +(def-edebug-elem-spec 'cl-&optional-arg + '(&or (cl-lambda-arg &optional def-form arg) arg)) -(def-edebug-spec cl-&key-arg - (&or ([&or (symbolp cl-lambda-arg) arg] &optional def-form arg) arg)) +(def-edebug-elem-spec 'cl-&key-arg + '(&or ([&or (symbolp cl-lambda-arg) arg] &optional def-form arg) arg)) -(def-edebug-spec cl-lambda-arg - (&or arg cl-lambda-list1)) +(def-edebug-elem-spec 'cl-lambda-arg + '(&or arg cl-lambda-list1)) -(def-edebug-spec cl-lambda-list1 - (([&optional ["&whole" arg]] ;; only allowed at lower levels - [&rest cl-lambda-arg] - [&optional ["&optional" cl-&optional-arg &rest cl-&optional-arg]] - [&optional ["&rest" cl-lambda-arg]] - [&optional ["&key" cl-&key-arg &rest cl-&key-arg - &optional "&allow-other-keys"]] - [&optional ["&aux" &rest - &or (cl-lambda-arg &optional def-form) arg]] - . [&or arg nil]))) +(def-edebug-elem-spec 'cl-lambda-list1 + '(([&optional ["&whole" arg]] ;; only allowed at lower levels + [&rest cl-lambda-arg] + [&optional ["&optional" cl-&optional-arg &rest cl-&optional-arg]] + [&optional ["&rest" cl-lambda-arg]] + [&optional ["&key" cl-&key-arg &rest cl-&key-arg + &optional "&allow-other-keys"]] + [&optional ["&aux" &rest + &or (cl-lambda-arg &optional def-form) arg]] + . [&or arg nil]))) -(def-edebug-spec cl-type-spec sexp) +(def-edebug-elem-spec 'cl-type-spec '(sexp)) (defconst cl--lambda-list-keywords '(&optional &rest &key &allow-other-keys &aux &whole &body &environment)) @@ -390,39 +390,39 @@ and BODY is implicitly surrounded by (cl-block NAME ...). ;; Note that &environment is only allowed as first or last items in the ;; top level list. -(def-edebug-spec cl-macro-list - (([&optional "&environment" arg] - [&rest cl-macro-arg] - [&optional ["&optional" &rest - &or (cl-macro-arg &optional def-form cl-macro-arg) arg]] - [&optional [[&or "&rest" "&body"] cl-macro-arg]] - [&optional ["&key" [&rest - [&or ([&or (symbolp cl-macro-arg) arg] - &optional def-form cl-macro-arg) - arg]] - &optional "&allow-other-keys"]] - [&optional ["&aux" &rest - &or (cl-macro-arg &optional def-form) arg]] - [&optional "&environment" arg] - ))) - -(def-edebug-spec cl-macro-arg - (&or arg cl-macro-list1)) - -(def-edebug-spec cl-macro-list1 - (([&optional "&whole" arg] ;; only allowed at lower levels - [&rest cl-macro-arg] - [&optional ["&optional" &rest - &or (cl-macro-arg &optional def-form cl-macro-arg) arg]] - [&optional [[&or "&rest" "&body"] cl-macro-arg]] - [&optional ["&key" [&rest - [&or ([&or (symbolp cl-macro-arg) arg] - &optional def-form cl-macro-arg) - arg]] - &optional "&allow-other-keys"]] - [&optional ["&aux" &rest - &or (cl-macro-arg &optional def-form) arg]] - . [&or arg nil]))) +(def-edebug-elem-spec 'cl-macro-list + '(([&optional "&environment" arg] + [&rest cl-macro-arg] + [&optional ["&optional" &rest + &or (cl-macro-arg &optional def-form cl-macro-arg) arg]] + [&optional [[&or "&rest" "&body"] cl-macro-arg]] + [&optional ["&key" [&rest + [&or ([&or (symbolp cl-macro-arg) arg] + &optional def-form cl-macro-arg) + arg]] + &optional "&allow-other-keys"]] + [&optional ["&aux" &rest + &or (cl-macro-arg &optional def-form) arg]] + [&optional "&environment" arg] + ))) + +(def-edebug-elem-spec 'cl-macro-arg + '(&or arg cl-macro-list1)) + +(def-edebug-elem-spec 'cl-macro-list1 + '(([&optional "&whole" arg] ;; only allowed at lower levels + [&rest cl-macro-arg] + [&optional ["&optional" &rest + &or (cl-macro-arg &optional def-form cl-macro-arg) arg]] + [&optional [[&or "&rest" "&body"] cl-macro-arg]] + [&optional ["&key" [&rest + [&or ([&or (symbolp cl-macro-arg) arg] + &optional def-form cl-macro-arg) + arg]] + &optional "&allow-other-keys"]] + [&optional ["&aux" &rest + &or (cl-macro-arg &optional def-form) arg]] + . [&or arg nil]))) ;;;###autoload (defmacro cl-defmacro (name args &rest body) @@ -452,19 +452,19 @@ more details. (indent 2)) `(defmacro ,name ,@(cl--transform-lambda (cons args body) name))) -(def-edebug-spec cl-lambda-expr - (&define ("lambda" cl-lambda-list - cl-declarations-or-string - [&optional ("interactive" interactive)] - def-body))) +(def-edebug-elem-spec 'cl-lambda-expr + '(&define ("lambda" cl-lambda-list + cl-declarations-or-string + [&optional ("interactive" interactive)] + def-body))) ;; Redefine function-form to also match cl-function -(def-edebug-spec function-form +(def-edebug-elem-spec 'function-form ;; form at the end could also handle "function", ;; but recognize it specially to avoid wrapping function forms. - (&or ([&or "quote" "function"] &or symbolp lambda-expr) - ("cl-function" cl-function) - form)) + '(&or ([&or "quote" "function"] &or symbolp lambda-expr) + ("cl-function" cl-function) + form)) ;;;###autoload (defmacro cl-function (func) @@ -1051,20 +1051,20 @@ For more details, see Info node `(cl)Loop Facility'. ;; [&rest loop-clause] ;; )) -;; (def-edebug-spec loop-with -;; ("with" loop-var +;; (def-edebug-elem-spec 'loop-with +;; '("with" loop-var ;; loop-type-spec ;; [&optional ["=" form]] ;; &rest ["and" loop-var ;; loop-type-spec ;; [&optional ["=" form]]])) -;; (def-edebug-spec loop-for-as -;; ([&or "for" "as"] loop-for-as-subclause +;; (def-edebug-elem-spec 'loop-for-as +;; '([&or "for" "as"] loop-for-as-subclause ;; &rest ["and" loop-for-as-subclause])) -;; (def-edebug-spec loop-for-as-subclause -;; (loop-var +;; (def-edebug-elem-spec 'loop-for-as-subclause +;; '(loop-var ;; loop-type-spec ;; &or ;; [[&or "in" "on" "in-ref" "across-ref"] @@ -1124,19 +1124,19 @@ For more details, see Info node `(cl)Loop Facility'. ;; [&optional ["by" form]] ;; ])) -;; (def-edebug-spec loop-initial-final -;; (&or ["initially" +;; (def-edebug-elem-spec 'loop-initial-final +;; '(&or ["initially" ;; ;; [&optional &or "do" "doing"] ;; CLtL2 doesn't allow this. ;; &rest loop-non-atomic-expr] ;; ["finally" &or ;; [[&optional &or "do" "doing"] &rest loop-non-atomic-expr] ;; ["return" form]])) -;; (def-edebug-spec loop-and-clause -;; (loop-clause &rest ["and" loop-clause])) +;; (def-edebug-elem-spec 'loop-and-clause +;; '(loop-clause &rest ["and" loop-clause])) -;; (def-edebug-spec loop-clause -;; (&or +;; (def-edebug-elem-spec 'loop-clause +;; '(&or ;; [[&or "while" "until" "always" "never" "thereis"] form] ;; [[&or "collect" "collecting" @@ -1163,10 +1163,10 @@ For more details, see Info node `(cl)Loop Facility'. ;; loop-initial-final ;; )) -;; (def-edebug-spec loop-non-atomic-expr -;; ([¬ atom] form)) +;; (def-edebug-elem-spec 'loop-non-atomic-expr +;; '([¬ atom] form)) -;; (def-edebug-spec loop-var +;; (def-edebug-elem-spec 'loop-var ;; ;; The symbolp must be last alternative to recognize e.g. (a b . c) ;; ;; loop-var => ;; ;; (loop-var . [&or nil loop-var]) @@ -1175,13 +1175,13 @@ For more details, see Info node `(cl)Loop Facility'. ;; ;; (symbolp . (symbolp . [&or nil loop-var])) ;; ;; (symbolp . (symbolp . loop-var)) ;; ;; (symbolp . (symbolp . symbolp)) == (symbolp symbolp . symbolp) -;; (&or (loop-var . [&or nil loop-var]) [gate symbolp])) +;; '(&or (loop-var . [&or nil loop-var]) [gate symbolp])) -;; (def-edebug-spec loop-type-spec -;; (&optional ["of-type" loop-d-type-spec])) +;; (def-edebug-elem-spec 'loop-type-spec +;; '(&optional ["of-type" loop-d-type-spec])) -;; (def-edebug-spec loop-d-type-spec -;; (&or (loop-d-type-spec . [&or nil loop-d-type-spec]) cl-type-spec)) +;; (def-edebug-elem-spec 'loop-d-type-spec +;; '(&or (loop-d-type-spec . [&or nil loop-d-type-spec]) cl-type-spec)) (defun cl--parse-loop-clause () ; uses loop-* (let ((word (pop cl--loop-args)) diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 782299454e..47b45614e7 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -261,6 +261,14 @@ The argument is usually a symbol, but it doesn't have to be." (define-obsolete-function-alias 'get-edebug-spec #'edebug-get-spec "28.1") +(defun edebug--get-elem-spec (elem) + "Return the specs of the Edebug element ELEM, if any. +ELEM has to be a symbol." + (or (get elem 'edebug-elem-spec) + ;; For backward compatibility, we also allow the use of + ;; a form's name as a shorthand to refer to its spec. + (edebug-get-spec elem))) + ;;;###autoload (defun edebug-basic-spec (spec) "Return t if SPEC uses only extant spec symbols. @@ -1757,16 +1765,11 @@ contains a circular object." (gate . edebug-match-gate) ;; (nil . edebug-match-nil) not this one - special case it. )) - ;; FIXME: We abuse `edebug-form-spec' here. It's normally used to store the - ;; specs for a given sexp's head, but here we use it to keep the - ;; function implementing of a given "core spec". - (put (car pair) 'edebug-form-spec (cdr pair))) + (put (car pair) 'edebug-elem-spec (cdr pair))) (defun edebug-match-symbol (cursor symbol) ;; Match a symbol spec. - ;; FIXME: We abuse `edebug-get-spec' here, passing it a *spec* rather than - ;; the head element of a source sexp. - (let* ((spec (edebug-get-spec symbol))) + (let* ((spec (edebug--get-elem-spec symbol))) (cond (spec (if (consp spec) @@ -2184,112 +2187,114 @@ into `edebug--cl-macrolet-defs' which is checked in `edebug-list-form-args'." ;;;* Emacs special forms and some functions. -;; quote expects only one argument, although it allows any number. -(def-edebug-spec quote sexp) - -;; The standard defining forms. -(def-edebug-spec defconst defvar) -(def-edebug-spec defvar (symbolp &optional form stringp)) - -(def-edebug-spec defun - (&define name lambda-list lambda-doc - [&optional ("declare" &rest sexp)] - [&optional ("interactive" interactive)] - def-body)) -(def-edebug-spec defmacro - ;; FIXME: Improve `declare' so we can Edebug gv-expander and - ;; gv-setter declarations. - (&define name lambda-list lambda-doc - [&optional ("declare" &rest sexp)] def-body)) - -(def-edebug-spec arglist lambda-list) ;; deprecated - use lambda-list. +(pcase-dolist + (`(,name ,spec) + + '((quote (sexp)) ;quote expects only one arg, tho it allows any number. + + ;; The standard defining forms. + (defvar (symbolp &optional form stringp)) + (defconst defvar) + + ;; Contrary to macros, special forms default to assuming that all args + ;; are normal forms, so we don't need to do anything about those + ;; special forms: + ;;(save-current-buffer t) + ;;(save-excursion t) + ;;... + ;;(progn t) + + ;; `defun' and `defmacro' are not special forms (any more), but it's + ;; more convenient to define their Edebug spec here. + (defun ( &define name lambda-list lambda-doc + [&optional ("declare" &rest sexp)] + [&optional ("interactive" &optional &or stringp def-form)] + def-body)) + + ;; FIXME: Improve `declare' so we can Edebug gv-expander and + ;; gv-setter declarations. + (defmacro ( &define name lambda-list lambda-doc + [&optional ("declare" &rest sexp)] + def-body)) + + ;; function expects a symbol or a lambda or macro expression + ;; A macro is allowed by Emacs. + (function (&or symbolp lambda-expr)) + + ;; FIXME? The manual uses this form (maybe that's just + ;; for illustration purposes?): + ;; (let ((&rest &or symbolp (gate symbolp &optional form)) body)) + (let ((&rest &or (symbolp &optional form) symbolp) body)) + (let* let) + + (setq (&rest symbolp form)) + (cond (&rest (&rest form))) + + (condition-case ( symbolp form + &rest ([&or symbolp (&rest symbolp)] body))) + + (\` (backquote-form)) + + ;; Assume immediate quote in unquotes mean backquote at next + ;; higher level. + (\, (&or ("quote" edebug-\`) def-form)) + (\,@ (&define ;; so (,@ form) is never wrapped. + &or ("quote" edebug-\`) def-form)) + )) + (put name 'edebug-form-spec spec)) -(def-edebug-spec lambda-list - (([&rest arg] - [&optional ["&optional" arg &rest arg]] - &optional ["&rest" arg] - ))) +(def-edebug-elem-spec 'lambda-list + '(([&rest arg] + [&optional ["&optional" arg &rest arg]] + &optional ["&rest" arg] + ))) -(def-edebug-spec lambda-doc - (&optional [&or stringp - (&define ":documentation" def-form)])) +(def-edebug-elem-spec 'arglist '(lambda-list)) ;; deprecated - use lambda-list. -(def-edebug-spec interactive - (&optional &or stringp def-form)) +(def-edebug-elem-spec 'lambda-doc + '(&optional [&or stringp + (&define ":documentation" def-form)])) ;; A function-form is for an argument that may be a function or a form. ;; This specially recognizes anonymous functions quoted with quote. -(def-edebug-spec function-form +(def-edebug-elem-spec 'function-form ;Deprecated, use `form'! ;; form at the end could also handle "function", ;; but recognize it specially to avoid wrapping function forms. - (&or ([&or "quote" "function"] &or symbolp lambda-expr) form)) - -;; function expects a symbol or a lambda or macro expression -;; A macro is allowed by Emacs. -(def-edebug-spec function (&or symbolp lambda-expr)) - -;; A macro expression is a lambda expression with "macro" prepended. -(def-edebug-spec macro (&define "lambda" lambda-list def-body)) - -;; (def-edebug-spec anonymous-form ((&or ["lambda" lambda] ["macro" macro]))) - -;; Standard functions that take function-forms arguments. - -;; FIXME? The manual uses this form (maybe that's just for illustration?): -;; (def-edebug-spec let -;; ((&rest &or symbolp (gate symbolp &optional form)) -;; body)) -(def-edebug-spec let - ((&rest &or (symbolp &optional form) symbolp) - body)) - -(def-edebug-spec let* let) - -(def-edebug-spec setq (&rest symbolp form)) - -(def-edebug-spec cond (&rest (&rest form))) - -(def-edebug-spec condition-case - (symbolp - form - &rest ([&or symbolp (&rest symbolp)] body))) - - -(def-edebug-spec \` (backquote-form)) + '(&or ([&or "quote" "function"] &or symbolp lambda-expr) form)) ;; Supports quotes inside backquotes, ;; but only at the top level inside unquotes. -(def-edebug-spec backquote-form - (&or - ;; Disallow instrumentation of , and ,@ inside a nested backquote, since - ;; these are likely to be forms generated by a macro being debugged. - ("`" nested-backquote-form) - ([&or "," ",@"] &or ("quote" backquote-form) form) - ;; The simple version: - ;; (backquote-form &rest backquote-form) - ;; doesn't handle (a . ,b). The straightforward fix: - ;; (backquote-form . [&or nil backquote-form]) - ;; uses up too much stack space. - ;; Note that `(foo . ,@bar) is not valid, so we don't need to handle it. - (backquote-form [&rest [¬ ","] backquote-form] - . [&or nil backquote-form]) - ;; If you use dotted forms in backquotes, replace the previous line - ;; with the following. This takes quite a bit more stack space, however. - ;; (backquote-form . [&or nil backquote-form]) - (vector &rest backquote-form) - sexp)) - -(def-edebug-spec nested-backquote-form - (&or - ("`" &error "Triply nested backquotes (without commas \"between\" them) \ +(def-edebug-elem-spec 'backquote-form + '(&or + ;; Disallow instrumentation of , and ,@ inside a nested backquote, since + ;; these are likely to be forms generated by a macro being debugged. + ("`" nested-backquote-form) + ([&or "," ",@"] &or ("quote" backquote-form) form) + ;; The simple version: + ;; (backquote-form &rest backquote-form) + ;; doesn't handle (a . ,b). The straightforward fix: + ;; (backquote-form . [&or nil backquote-form]) + ;; uses up too much stack space. + ;; Note that `(foo . ,@bar) is not valid, so we don't need to handle it. + (backquote-form [&rest [¬ ","] backquote-form] + . [&or nil backquote-form]) + ;; If you use dotted forms in backquotes, replace the previous line + ;; with the following. This takes quite a bit more stack space, however. + ;; (backquote-form . [&or nil backquote-form]) + (vector &rest backquote-form) + sexp)) + +(def-edebug-elem-spec 'nested-backquote-form + '(&or + ("`" &error "Triply nested backquotes (without commas \"between\" them) \ are too difficult to instrument") - ;; Allow instrumentation of any , or ,@ contained within the (\, ...) or - ;; (\,@ ...) matched on the next line. - ([&or "," ",@"] backquote-form) - (nested-backquote-form [&rest [¬ "," ",@"] nested-backquote-form] - . [&or nil nested-backquote-form]) - (vector &rest nested-backquote-form) - sexp)) + ;; Allow instrumentation of any , or ,@ contained within the (\, ...) or + ;; (\,@ ...) matched on the next line. + ([&or "," ",@"] backquote-form) + (nested-backquote-form [&rest [¬ "," ",@"] nested-backquote-form] + . [&or nil nested-backquote-form]) + (vector &rest nested-backquote-form) + sexp)) ;; Special version of backquote that instruments backquoted forms ;; destined to be evaluated, usually as the result of a @@ -2304,20 +2309,9 @@ are too difficult to instrument") ;; ,@ might have some problems. -(defalias 'edebug-\` '\`) ;; same macro as regular backquote. -(def-edebug-spec edebug-\` (def-form)) - -;; Assume immediate quote in unquotes mean backquote at next higher level. -(def-edebug-spec \, (&or ("quote" edebug-\`) def-form)) -(def-edebug-spec \,@ (&define ;; so (,@ form) is never wrapped. - &or ("quote" edebug-\`) def-form)) - -;; New byte compiler. - -(def-edebug-spec save-selected-window t) -(def-edebug-spec save-current-buffer t) - -;; Anything else? +(defmacro edebug-\` (exp) + (declare (debug (def-form))) + (list '\` exp)) ;;; The debugger itself diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index d6c96c1ec8..5d428ac846 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -62,15 +62,14 @@ (defvar pcase--dontwarn-upats '(pcase--dontcare)) -(def-edebug-spec pcase-PAT - (&or (&lookup symbolp pcase--get-edebug-spec) - sexp)) +(def-edebug-elem-spec 'pcase-PAT + '(&or (&lookup symbolp pcase--get-edebug-spec) sexp)) -(def-edebug-spec pcase-FUN - (&or lambda-expr - ;; Punt on macros/special forms. - (functionp &rest form) - sexp)) +(def-edebug-elem-spec 'pcase-FUN + '(&or lambda-expr + ;; Punt on macros/special forms. + (functionp &rest form) + sexp)) ;; Only called from edebug. (declare-function edebug-get-spec "edebug" (symbol)) @@ -925,13 +924,13 @@ Otherwise, it defers to REST which is a list of branches of the form (t (error "Unknown pattern `%S'" upat))))) (t (error "Incorrect MATCH %S" (car matches))))) -(def-edebug-spec pcase-QPAT +(def-edebug-elem-spec 'pcase-QPAT ;; Cf. edebug spec for `backquote-form' in edebug.el. - (&or ("," pcase-PAT) - (pcase-QPAT [&rest [¬ ","] pcase-QPAT] - . [&or nil pcase-QPAT]) - (vector &rest pcase-QPAT) - sexp)) + '(&or ("," pcase-PAT) + (pcase-QPAT [&rest [¬ ","] pcase-QPAT] + . [&or nil pcase-QPAT]) + (vector &rest pcase-QPAT) + sexp)) (pcase-defmacro \` (qpat) "Backquote-style pcase patterns: \\=`QPAT diff --git a/lisp/skeleton.el b/lisp/skeleton.el index 48491e43ca..8a50fbef64 100644 --- a/lisp/skeleton.el +++ b/lisp/skeleton.el @@ -104,10 +104,10 @@ are integer buffer positions in the reverse order of the insertion order.") (defvar skeleton-point) (defvar skeleton-regions) -(def-edebug-spec skeleton-edebug-spec - ([&or null stringp (stringp &rest stringp) [[¬ atom] sexp]] - &rest &or "n" "_" "-" ">" "@" "&" "!" "|" "resume:" - ("quote" def-form) skeleton-edebug-spec def-form)) +(def-edebug-elem-spec 'skeleton-edebug-spec + '([&or null stringp (stringp &rest stringp) [[¬ atom] sexp]] + &rest &or "n" "_" "-" ">" "@" "&" "!" "|" "resume:" + ("quote" def-form) skeleton-edebug-spec def-form)) ;;;###autoload (defmacro define-skeleton (command documentation &rest skeleton) "Define a user-configurable COMMAND that enters a statement skeleton. diff --git a/lisp/subr.el b/lisp/subr.el index 454ea54b6a..70ee281fe6 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -82,7 +82,7 @@ Testcover will raise an error." form) (defmacro def-edebug-spec (symbol spec) - "Set the `edebug-form-spec' property of SYMBOL according to SPEC. + "Set the Edebug SPEC to use for sexps which have SYMBOL as head. Both SYMBOL and SPEC are unevaluated. The SPEC can be: 0 (instrument no arguments); t (instrument all arguments); a symbol (naming a function with an Edebug specification); or a list. @@ -91,6 +91,21 @@ Info node `(elisp)Specification List' for details." (declare (indent 1)) `(put (quote ,symbol) 'edebug-form-spec (quote ,spec))) +(defun def-edebug-elem-spec (name spec) + "Define a new Edebug spec element NAME as shorthand for SPEC. +The SPEC has to be a list or a symbol. +The elements of the list describe the argument types; see +Info node `(elisp)Specification List' for details. +If SPEC is a symbol it should name another pre-existing Edebug element." + (declare (indent 1)) + (when (string-match "\\`[&:]" (symbol-name name)) + ;; & and : have special meaning in spec element names. + (error "Edebug spec name cannot start with '&' or ':'")) + (unless (consp spec) + (error "Edebug spec has to be a list: %S" spec)) + (put name 'edebug-elem-spec spec)) + + (defmacro lambda (&rest cdr) "Return an anonymous function. Under dynamic binding, a call of the form (lambda ARGS DOCSTRING diff --git a/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el b/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el index f8ca39c8c6..d77df3c3c5 100644 --- a/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el +++ b/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el @@ -137,5 +137,15 @@ ,(cons func args)))) (wrap + 1 x))) +(defun edebug-test-code-cl-flet1 () + (cl-flet + ;; This `&rest' sexp head should not collide with + ;; the Edebug spec elem of the same name. + ((f (&rest x) x) + (gate (x) (+ x 5))) + ;; This call to `gate' shouldn't collide with the Edebug spec elem + ;; of the same name. + (message "Hi %s" (gate 7)))) + (provide 'edebug-test-code) ;;; edebug-test-code.el ends here diff --git a/test/lisp/emacs-lisp/edebug-tests.el b/test/lisp/emacs-lisp/edebug-tests.el index 6a6080df3c..c11bfcf001 100644 --- a/test/lisp/emacs-lisp/edebug-tests.el +++ b/test/lisp/emacs-lisp/edebug-tests.el @@ -954,6 +954,11 @@ primary ones (Bug#42671)." (list (intern "edebug-cl-defmethod-qualifier :around ((_ number))") (intern "edebug-cl-defmethod-qualifier ((_ number))"))))))) +(ert-deftest edebug-tests--conflicting-internal-names () + "Check conflicts between form's head symbols and Edebug spec elements." + (edebug-tests-with-normal-env + (edebug-tests-setup-@ "cl-flet1" '(10) t))) + (ert-deftest edebug-tests-cl-flet () "Check that Edebug can instrument `cl-flet' forms without name clashes (Bug#41853)." commit bdd8d5b6a45bb66e230473fe221f8c1832bebb6c Author: Stefan Kangas Date: Fri Feb 12 19:07:12 2021 +0100 Remove XEmacs and Emacs 21 compat code from cperl-mode * lisp/progmodes/cperl-mode.el (cperl-mode): Remove XEmacs and Emacs 21 compat code. (cperl-compilation-error-regexp-list): New variable. (cperl-compilation-error-regexp-alist): Make obsolete. diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index 90ccdbf00a..97d0e36464 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -1396,13 +1396,15 @@ the last)." (defvar cperl-font-lock-multiline nil) (defvar cperl-font-locking nil) -;; NB as it stands the code in cperl-mode assumes this only has one -;; element. Since XEmacs 19 support has been dropped, this could all be simplified. -(defvar cperl-compilation-error-regexp-alist +(defvar cperl-compilation-error-regexp-list ;; This look like a paranoiac regexp: could anybody find a better one? (which WORKS). - '(("^[^\n]* \\(file\\|at\\) \\([^ \t\n]+\\) [^\n]*line \\([0-9]+\\)[\\., \n]" - 2 3)) - "Alist that specifies how to match errors in perl output.") + '("^[^\n]* \\(file\\|at\\) \\([^ \t\n]+\\) [^\n]*line \\([0-9]+\\)[\\., \n]" + 2 3) + "List that specifies how to match errors in Perl output.") + +(defvar cperl-compilation-error-regexp-alist) +(make-obsolete-variable 'cperl-compilation-error-regexp-alist + 'cperl-compilation-error-regexp-list "28.1") (defvar compilation-error-regexp-alist) @@ -1639,19 +1641,18 @@ or as help on variables `cperl-tips', `cperl-problems', (setq-local imenu-sort-function nil) (setq-local vc-rcs-header cperl-vc-rcs-header) (setq-local vc-sccs-header cperl-vc-sccs-header) - (cond ((boundp 'compilation-error-regexp-alist-alist);; xemacs 20.x - (setq-local compilation-error-regexp-alist-alist - (cons (cons 'cperl (car cperl-compilation-error-regexp-alist)) - compilation-error-regexp-alist-alist)) - (if (fboundp 'compilation-build-compilation-error-regexp-alist) - (let ((f 'compilation-build-compilation-error-regexp-alist)) - (funcall f)) - (make-local-variable 'compilation-error-regexp-alist) - (push 'cperl compilation-error-regexp-alist))) - ((boundp 'compilation-error-regexp-alist);; xemacs 19.x - (setq-local compilation-error-regexp-alist - (append cperl-compilation-error-regexp-alist - compilation-error-regexp-alist)))) + (when (boundp 'compilation-error-regexp-alist-alist) + ;; The let here is just a compatibility kludge for the obsolete + ;; variable `cperl-compilation-error-regexp-alist'. It can be removed + ;; when that variable is removed. + (let ((regexp (if (boundp 'cperl-compilation-error-regexp-alist) + (car cperl-compilation-error-regexp-alist) + cperl-compilation-error-regexp-list))) + (setq-local compilation-error-regexp-alist-alist + (cons (cons 'cperl regexp) + compilation-error-regexp-alist-alist))) + (make-local-variable 'compilation-error-regexp-alist) + (push 'cperl compilation-error-regexp-alist)) (setq-local font-lock-defaults '((cperl-load-font-lock-keywords cperl-load-font-lock-keywords-1 commit c3163069a1e0a9aba16ae110ec75ace948e2ce0c Author: Basil L. Contovounesios Date: Fri Feb 12 21:26:08 2021 +0000 Fix ElDoc setup for eval-expression * lisp/emacs-lisp/eldoc.el (eldoc--eval-expression-setup): Don't set global value of eldoc-documentation-strategy (bug#44886). diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el index 90e075b110..c95540ea3c 100644 --- a/lisp/emacs-lisp/eldoc.el +++ b/lisp/emacs-lisp/eldoc.el @@ -248,7 +248,8 @@ expression point is on." :lighter eldoc-minor-mode-string #'elisp-eldoc-var-docstring nil t) (add-hook 'eldoc-documentation-functions #'elisp-eldoc-funcall nil t) - (setq eldoc-documentation-strategy 'eldoc-documentation-default))) + (setq-local eldoc-documentation-strategy + 'eldoc-documentation-default))) (eldoc-mode +1)) ;;;###autoload commit f8dbefbaa59bb17dd4a2dfa4d9ff560c46785792 Author: Stefan Monnier Date: Fri Feb 12 16:08:01 2021 -0500 Use `declare` instead of `def-edebug-spec` in most places * lisp/speedbar.el: Use lexical-binding. (speedbar-with-writable): Use `declare`. * lisp/subr.el (def-edebug-spec): Use `declare`. * lisp/cedet/ede/base.el: Use lexical-binding. (ede-with-projectfile): Use `declare`. (recentf-exclude): Declare var. * lisp/cedet/ede/pmake.el: Use lexical-binding. (ede-pmake-insert-variable-shared, ede-pmake-insert-variable-once): Use `declare`. * lisp/cedet/ede/proj-comp.el: Use lexical-binding. (ede-compiler-begin-unique, ede-compiler-only-once) (ede-linker-begin-unique, ede-linker-only-once): Use `declare`. * lisp/cedet/semantic/ctxt.el: Use lexical-binding. (semantic-with-buffer-narrowed-to-context) (semantic-with-buffer-narrowed-to-command): Use `declare`. (semantic--progress-reporter): Declare var. (semantic-ctxt-end-of-symbol-default): Remove unused var `fieldsep`. * lisp/cedet/semantic/lex-spp.el: Use lexical-binding. (define-lex-spp-macro-declaration-analyzer) (define-lex-spp-include-analyzer, semantic-lex-with-macro-used) (define-lex-spp-macro-undeclaration-analyzer): Use `declare`. (semantic-lex-spp-symbol-remove): Rename arg to avoid colliding with dynamic variable `obarray`. (semantic-lex-spp-symbol-pop): Remove unused var `oldvalue`. (semantic-lex-spp-lex-text-string): Remove unused var `analyzer`. * lisp/cedet/semantic/lex.el (define-lex) (semantic-lex-unterminated-syntax-protection, define-lex-analyzer) (define-lex-regex-analyzer, define-lex-block-analyzer) (semantic-lex-catch-errors): Use `declare`. * lisp/cedet/semantic/tag.el: Use lexical-binding. (semantic-with-buffer-narrowed-to-current-tag) (semantic-with-buffer-narrowed-to-tag): Use `declare`. * lisp/cedet/semantic/wisent.el: Use lexical-binding. (define-wisent-lexer): Use `declare`. * lisp/emacs-lisp/cl-lib.el (cl-pushnew): The arg to :test can be any form not just function form. * lisp/org/ob-comint.el (org-babel-comint-in-buffer) (org-babel-comint-with-output): Use `declare`. * lisp/org/ob-core.el (org-babel-map-src-blocks): Use `declare`. (org-babel-result-cond): Simplify edebug spec. * lisp/org/org-clock.el (org-with-clock-position, org-with-clock): * lisp/org/org-agenda.el (org-agenda-with-point-at-orig-entry): * lisp/org/ob-tangle.el (org-babel-with-temp-filebuffer): Use `declare`. * lisp/textmodes/rst.el (push): Remove redundant edebug spec. * lisp/vc/pcvs-parse.el: Use lexical-binding. (cvs-parse-buffer): Rename arg to avoid dynbound conflict. (cvs-or): Use `declare`. diff --git a/lisp/cedet/ede/base.el b/lisp/cedet/ede/base.el index 810d6ef3bd..3fcc023e0c 100644 --- a/lisp/cedet/ede/base.el +++ b/lisp/cedet/ede/base.el @@ -1,4 +1,4 @@ -;;; ede/base.el --- Baseclasses for EDE. +;;; ede/base.el --- Baseclasses for EDE -*- lexical-binding: t; -*- ;; Copyright (C) 2010-2021 Free Software Foundation, Inc. @@ -288,7 +288,7 @@ All specific project types must derive from this project." ;; (defmacro ede-with-projectfile (obj &rest forms) "For the project in which OBJ resides, execute FORMS." - (declare (indent 1)) + (declare (indent 1) (debug t)) (unless (symbolp obj) (message "Beware! ede-with-projectfile's first arg is copied: %S" obj)) `(let* ((pf (if (obj-of-class-p ,obj 'ede-target) @@ -317,13 +317,15 @@ If set to nil, then the cache is not saved." (defvar ede-project-cache-files nil "List of project files EDE has seen before.") +(defvar recentf-exclude) + (defun ede-save-cache () "Save a cache of EDE objects that Emacs has seen before." (interactive) (when ede-project-placeholder-cache-file (let ((p ede-projects) (c ede-project-cache-files) - (recentf-exclude '( (lambda (f) t) )) + (recentf-exclude `( ,(lambda (_) t) )) ) (condition-case nil (progn @@ -461,7 +463,7 @@ Not all buffers need headers, so return nil if no applicable." (ede-buffer-header-file ede-object (current-buffer)) nil)) -(cl-defmethod ede-buffer-header-file ((this ede-project) buffer) +(cl-defmethod ede-buffer-header-file ((_this ede-project) _buffer) "Return nil, projects don't have header files." nil) @@ -487,12 +489,12 @@ Some projects may have multiple documentation files, so return a list." (ede-buffer-documentation-files ede-object (current-buffer)) nil)) -(cl-defmethod ede-buffer-documentation-files ((this ede-project) buffer) +(cl-defmethod ede-buffer-documentation-files ((this ede-project) _buffer) "Return all documentation in project THIS based on BUFFER." ;; Find the info node. (ede-documentation this)) -(cl-defmethod ede-buffer-documentation-files ((this ede-target) buffer) +(cl-defmethod ede-buffer-documentation-files ((_this ede-target) buffer) "Check for some documentation files for THIS. Also do a quick check to see if there is a Documentation tag in this BUFFER." (with-current-buffer buffer @@ -518,7 +520,7 @@ files in the project." proj (cdr proj))) found)) -(cl-defmethod ede-documentation ((this ede-target)) +(cl-defmethod ede-documentation ((_this ede-target)) "Return a list of files that provide documentation. Documentation is not for object THIS, but is provided by THIS for other files in the project." @@ -529,7 +531,7 @@ files in the project." (ede-html-documentation (ede-toplevel)) ) -(cl-defmethod ede-html-documentation ((this ede-project)) +(cl-defmethod ede-html-documentation ((_this ede-project)) "Return a list of HTML files provided by project THIS." ) @@ -636,18 +638,7 @@ PROJECT-FILE-NAME is a name of project file (short name, like `pom.xml', etc." (oset this directory (file-name-directory (oref this file)))) ) - - -;;; Hooks & Autoloads -;; -;; These let us watch various activities, and respond appropriately. - -;; (add-hook 'edebug-setup-hook -;; (lambda () -;; (def-edebug-spec ede-with-projectfile -;; (form def-body)))) - (provide 'ede/base) ;; Local variables: diff --git a/lisp/cedet/ede/pmake.el b/lisp/cedet/ede/pmake.el index 4c948df410..e1fe85659f 100644 --- a/lisp/cedet/ede/pmake.el +++ b/lisp/cedet/ede/pmake.el @@ -1,4 +1,4 @@ -;;; ede-pmake.el --- EDE Generic Project Makefile code generator. +;;; ede-pmake.el --- EDE Generic Project Makefile code generator -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2005, 2007-2021 Free Software Foundation, Inc. @@ -241,6 +241,7 @@ MFILENAME is the makefile to generate." (defmacro ede-pmake-insert-variable-shared (varname &rest body) "Add VARNAME into the current Makefile. Execute BODY in a location where a value can be placed." + (declare (debug t) (indent 1)) `(let ((addcr t) (v ,varname)) (if (save-excursion (goto-char (point-max)) @@ -258,11 +259,11 @@ Execute BODY in a location where a value can be placed." ,@body (if addcr (insert "\n")) (goto-char (point-max)))) -(put 'ede-pmake-insert-variable-shared 'lisp-indent-function 1) (defmacro ede-pmake-insert-variable-once (varname &rest body) "Add VARNAME into the current Makefile if it doesn't exist. Execute BODY in a location where a value can be placed." + (declare (debug t) (indent 1)) `(let ((addcr t) (v ,varname)) (unless (save-excursion @@ -271,7 +272,6 @@ Execute BODY in a location where a value can be placed." ,@body (when addcr (insert "\n")) (goto-char (point-max))))) -(put 'ede-pmake-insert-variable-once 'lisp-indent-function 1) ;;; SOURCE VARIABLE NAME CONSTRUCTION @@ -289,7 +289,7 @@ Change . to _ in the variable name." ;;; DEPENDENCY FILE GENERATOR LISTS ;; -(cl-defmethod ede-proj-makefile-dependency-files ((this ede-proj-target)) +(cl-defmethod ede-proj-makefile-dependency-files ((_this ede-proj-target)) "Return a list of source files to convert to dependencies. Argument THIS is the target to get sources from." nil) @@ -302,7 +302,7 @@ Argument THIS is the target to get sources from." Use CONFIGURATION as the current configuration to query." (cdr (assoc configuration (oref this configuration-variables)))) -(cl-defmethod ede-proj-makefile-insert-variables-new ((this ede-proj-project)) +(cl-defmethod ede-proj-makefile-insert-variables-new ((_this ede-proj-project)) "Insert variables needed by target THIS. NOTE: Not yet in use! This is part of an SRecode conversion of @@ -420,7 +420,7 @@ Use CONFIGURATION as the current configuration to query." (cdr (assoc configuration (oref this configuration-variables)))) (cl-defmethod ede-proj-makefile-insert-variables ((this ede-proj-target-makefile) - &optional moresource) + &optional _moresource) "Insert variables needed by target THIS. Optional argument MORESOURCE is a list of additional sources to add to the sources variable." @@ -449,12 +449,12 @@ sources variable." (ede-proj-makefile-insert-variables linker))))) (cl-defmethod ede-proj-makefile-insert-automake-pre-variables - ((this ede-proj-target)) + ((_this ede-proj-target)) "Insert variables needed by target THIS in Makefile.am before SOURCES." nil) (cl-defmethod ede-proj-makefile-insert-automake-post-variables - ((this ede-proj-target)) + ((_this ede-proj-target)) "Insert variables needed by target THIS in Makefile.am after SOURCES." nil) @@ -511,7 +511,7 @@ Argument THIS is the project that should insert stuff." (mapc 'ede-proj-makefile-insert-dist-dependencies (oref this targets)) ) -(cl-defmethod ede-proj-makefile-insert-dist-dependencies ((this ede-proj-target)) +(cl-defmethod ede-proj-makefile-insert-dist-dependencies ((_this ede-proj-target)) "Insert any symbols that the DIST rule should depend on. Argument THIS is the target that should insert stuff." nil) @@ -530,7 +530,7 @@ Argument THIS is the target that should insert stuff." (insert " " (ede-subproject-relative-path sproj)) )))) -(cl-defmethod ede-proj-makefile-automake-insert-extradist ((this ede-proj-project)) +(cl-defmethod ede-proj-makefile-automake-insert-extradist ((_this ede-proj-project)) "Insert the EXTRADIST variable entries needed for Automake and EDE." (proj-comp-insert-variable-once "EXTRA_DIST" (insert "Project.ede"))) @@ -602,7 +602,7 @@ Argument THIS is the target that should insert stuff." "\t@false\n\n" "\n\n# End of Makefile\n"))) -(cl-defmethod ede-proj-makefile-insert-rules ((this ede-proj-target)) +(cl-defmethod ede-proj-makefile-insert-rules ((_this ede-proj-target)) "Insert rules needed by THIS target." nil) diff --git a/lisp/cedet/ede/proj-comp.el b/lisp/cedet/ede/proj-comp.el index 26aa66873a..ba52784a7a 100644 --- a/lisp/cedet/ede/proj-comp.el +++ b/lisp/cedet/ede/proj-comp.el @@ -1,4 +1,4 @@ -;;; ede/proj-comp.el --- EDE Generic Project compiler/rule driver +;;; ede/proj-comp.el --- EDE Generic Project compiler/rule driver -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2001, 2004-2005, 2007, 2009-2021 Free Software ;; Foundation, Inc. @@ -172,12 +172,12 @@ Adds this rule to a .PHONY list.")) This is used when creating a Makefile to prevent duplicate variables and rules from being created.") -(cl-defmethod initialize-instance :after ((this ede-compiler) &rest fields) +(cl-defmethod initialize-instance :after ((this ede-compiler) &rest _fields) "Make sure that all ede compiler objects are cached in `ede-compiler-list'." (add-to-list 'ede-compiler-list this)) -(cl-defmethod initialize-instance :after ((this ede-linker) &rest fields) +(cl-defmethod initialize-instance :after ((this ede-linker) &rest _fields) "Make sure that all ede compiler objects are cached in `ede-linker-list'." (add-to-list 'ede-linker-list this)) @@ -185,11 +185,13 @@ rules from being created.") (defmacro ede-compiler-begin-unique (&rest body) "Execute BODY, making sure that `ede-current-build-list' is maintained. This will prevent rules from creating duplicate variables or rules." + (declare (indent 0) (debug t)) `(let ((ede-current-build-list nil)) ,@body)) (defmacro ede-compiler-only-once (object &rest body) "Using OBJECT, execute BODY only once per Makefile generation." + (declare (indent 1) (debug t)) `(if (not (member ,object ede-current-build-list)) (progn (add-to-list 'ede-current-build-list ,object) @@ -198,25 +200,18 @@ This will prevent rules from creating duplicate variables or rules." (defmacro ede-linker-begin-unique (&rest body) "Execute BODY, making sure that `ede-current-build-list' is maintained. This will prevent rules from creating duplicate variables or rules." + (declare (indent 0) (debug t)) `(let ((ede-current-build-list nil)) ,@body)) (defmacro ede-linker-only-once (object &rest body) "Using OBJECT, execute BODY only once per Makefile generation." + (declare (indent 1) (debug t)) `(if (not (member ,object ede-current-build-list)) (progn (add-to-list 'ede-current-build-list ,object) ,@body))) -(add-hook 'edebug-setup-hook - (lambda () - (def-edebug-spec ede-compiler-begin-unique def-body) - (def-edebug-spec ede-compiler-only-once (form def-body)) - (def-edebug-spec ede-linker-begin-unique def-body) - (def-edebug-spec ede-linker-only-once (form def-body)) - (def-edebug-spec ede-pmake-insert-variable-shared (form def-body)) - )) - ;;; Queries (defun ede-proj-find-compiler (compilers sourcetype) "Return a compiler from the list COMPILERS that will compile SOURCETYPE." @@ -246,7 +241,7 @@ This will prevent rules from creating duplicate variables or rules." ) (oref this autoconf))) -(cl-defmethod ede-proj-flush-autoconf ((this ede-compilation-program)) +(cl-defmethod ede-proj-flush-autoconf ((_this ede-compilation-program)) "Flush the configure file (current buffer) to accommodate THIS." nil) @@ -281,8 +276,8 @@ If this compiler creates code that can be linked together, then the object files created by the compiler are considered intermediate." (oref this uselinker)) -(cl-defmethod ede-compiler-intermediate-object-variable ((this ede-compiler) - targetname) +(cl-defmethod ede-compiler-intermediate-object-variable ((_this ede-compiler) + targetname) "Return a string based on THIS representing a make object variable. TARGETNAME is the name of the target that these objects belong to." (concat targetname "_OBJ")) @@ -343,16 +338,6 @@ compiler it decides to use after inserting in the rule." commands)) (insert "\n"))) -;;; Some details about our new macro -;; -(add-hook 'edebug-setup-hook - (lambda () - (def-edebug-spec ede-compiler-begin-unique def-body))) -(put 'ede-compiler-begin-unique 'lisp-indent-function 0) -(put 'ede-compiler-only-once 'lisp-indent-function 1) -(put 'ede-linker-begin-unique 'lisp-indent-function 0) -(put 'ede-linker-only-once 'lisp-indent-function 1) - (provide 'ede/proj-comp) ;;; ede/proj-comp.el ends here diff --git a/lisp/cedet/semantic/ctxt.el b/lisp/cedet/semantic/ctxt.el index 8d5b5dcdbd..17ffaeff5e 100644 --- a/lisp/cedet/semantic/ctxt.el +++ b/lisp/cedet/semantic/ctxt.el @@ -1,4 +1,4 @@ -;;; semantic/ctxt.el --- Context calculations for Semantic tools. +;;; semantic/ctxt.el --- Context calculations for Semantic tools -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. @@ -137,18 +137,16 @@ Return non-nil if there is no upper context." (defmacro semantic-with-buffer-narrowed-to-context (&rest body) "Execute BODY with the buffer narrowed to the current context." + (declare (indent 0) (debug t)) `(save-restriction (semantic-narrow-to-context) ,@body)) -(put 'semantic-with-buffer-narrowed-to-context 'lisp-indent-function 0) -(add-hook 'edebug-setup-hook - (lambda () - (def-edebug-spec semantic-with-buffer-narrowed-to-context - (def-body)))) ;;; Local Variables ;; -;; + +(defvar semantic--progress-reporter) + (define-overloadable-function semantic-get-local-variables (&optional point) "Get the local variables based on POINT's context. Local variables are returned in Semantic tag format. @@ -345,14 +343,10 @@ beginning and end of a command." (defmacro semantic-with-buffer-narrowed-to-command (&rest body) "Execute BODY with the buffer narrowed to the current command." + (declare (indent 0) (debug t)) `(save-restriction (semantic-narrow-to-command) ,@body)) -(put 'semantic-with-buffer-narrowed-to-command 'lisp-indent-function 0) -(add-hook 'edebug-setup-hook - (lambda () - (def-edebug-spec semantic-with-buffer-narrowed-to-command - (def-body)))) (define-overloadable-function semantic-ctxt-end-of-symbol (&optional point) "Move point to the end of the current symbol under POINT. @@ -374,7 +368,7 @@ work on C like languages." ;; NOTE: The [ \n] expression below should used \\s-, but that ;; doesn't work in C since \n means end-of-comment, and isn't ;; really whitespace. - (fieldsep (concat "[ \t\n\r]*\\(" fieldsep1 "\\)[ \t\n\r]*\\(\\w\\|\\s_\\)")) + ;;(fieldsep (concat "[ \t\n\r]*\\(" fieldsep1 "\\)[ \t\n\r]*\\(\\w\\|\\s_\\)")) (case-fold-search semantic-case-fold) (continuesearch t) (end nil) @@ -655,7 +649,7 @@ POINT defaults to the value of point in current buffer. You should override this function in multiple mode buffers to determine which major mode apply at point.") -(defun semantic-ctxt-current-mode-default (&optional point) +(defun semantic-ctxt-current-mode-default (&optional _point) "Return the major mode active at POINT. POINT defaults to the value of point in current buffer. This default implementation returns the current major mode." @@ -671,7 +665,7 @@ The return value can be a mixed list of either strings (names of types that are in scope) or actual tags (type declared locally that may or may not have a name.)") -(defun semantic-ctxt-scoped-types-default (&optional point) +(defun semantic-ctxt-scoped-types-default (&optional _point) "Return a list of scoped types by name for the current context at POINT. This is very different for various languages, and does nothing unless overridden." diff --git a/lisp/cedet/semantic/lex-spp.el b/lisp/cedet/semantic/lex-spp.el index 408011c628..5675b9f3e3 100644 --- a/lisp/cedet/semantic/lex-spp.el +++ b/lisp/cedet/semantic/lex-spp.el @@ -1,4 +1,4 @@ -;;; semantic/lex-spp.el --- Semantic Lexical Pre-processor +;;; semantic/lex-spp.el --- Semantic Lexical Pre-processor -*- lexical-binding: t; -*- ;; Copyright (C) 2006-2021 Free Software Foundation, Inc. @@ -106,22 +106,12 @@ added and removed from this symbol table.") Pushes NAME into the macro stack. The above stack is checked by `semantic-lex-spp-symbol' to not return true for any symbol currently being expanded." + (declare (indent 1) (debug (symbolp def-body))) `(unwind-protect (progn (push ,name semantic-lex-spp-expanded-macro-stack) ,@body) (pop semantic-lex-spp-expanded-macro-stack))) -(put 'semantic-lex-with-macro-used 'lisp-indent-function 1) - -(add-hook - 'edebug-setup-hook - #'(lambda () - - (def-edebug-spec semantic-lex-with-macro-used - (symbolp def-body) - ) - - )) ;;; MACRO TABLE UTILS ;; @@ -190,7 +180,7 @@ Disable debugging by entering nothing." (setq semantic-lex-spp-debug-symbol nil) (setq semantic-lex-spp-debug-symbol sym))) -(defmacro semantic-lex-spp-validate-value (name value) +(defmacro semantic-lex-spp-validate-value (_name _value) "Validate the NAME and VALUE of a macro before it is set." ; `(progn ; (when (not (semantic-lex-spp-value-valid-p ,value)) @@ -212,12 +202,11 @@ the dynamic map." (semantic-lex-spp-dynamic-map))) value)) -(defsubst semantic-lex-spp-symbol-remove (name &optional obarray) +(defsubst semantic-lex-spp-symbol-remove (name &optional map) "Remove the spp symbol with NAME. -If optional OBARRAY is non-nil, then use that obarray instead of +If optional obarray MAP is non-nil, then use that obarray instead of the dynamic map." - (unintern name (or obarray - (semantic-lex-spp-dynamic-map)))) + (unintern name (or map (semantic-lex-spp-dynamic-map)))) (defun semantic-lex-spp-symbol-push (name value) "Push macro NAME with VALUE into the map. @@ -246,7 +235,7 @@ Reverse with `semantic-lex-spp-symbol-pop'." (stack (semantic-lex-spp-dynamic-map-stack)) (mapsym (intern name map)) (stacksym (intern name stack)) - (oldvalue nil) + ;; (oldvalue nil) ) (if (or (not (boundp stacksym) ) (= (length (symbol-value stacksym)) 0)) @@ -324,7 +313,7 @@ For use with semanticdb restoration of state." ;; Default obarray for below is the dynamic map. (semantic-lex-spp-symbol-set (car e) (cdr e)))) -(defun semantic-lex-spp-reset-hook (start end) +(defun semantic-lex-spp-reset-hook (start _end) "Reset anything needed by SPP for parsing. In this case, reset the dynamic macro symbol table if START is (point-min). @@ -354,7 +343,7 @@ Return non-nil if it matches" (string-match regex value)) )) -(defun semantic-lex-spp-simple-macro-to-macro-stream (val beg end argvalues) +(defun semantic-lex-spp-simple-macro-to-macro-stream (val beg end _argvalues) "Convert lexical macro contents VAL into a macro expansion stream. These are for simple macro expansions that a user may have typed in directly. As such, we need to analyze the input text, to figure out what kind of real @@ -819,7 +808,7 @@ ARGVALUES are values for any arg list, or nil." ;; An analyzer that will push tokens from a macro in place ;; of the macro symbol. ;; -(defun semantic-lex-spp-analyzer-do-replace (sym val beg end) +(defun semantic-lex-spp-analyzer-do-replace (_sym val beg end) "Do the lexical replacement for SYM with VAL. Argument BEG and END specify the bounds of SYM in the buffer." (if (not val) @@ -1045,7 +1034,7 @@ and variable state from the current buffer." (fresh-toks nil) (toks nil) (origbuff (current-buffer)) - (analyzer semantic-lex-analyzer) + ;; (analyzer semantic-lex-analyzer) (important-vars '(semantic-lex-spp-macro-symbol-obarray semantic-lex-spp-project-macro-symbol-obarray semantic-lex-spp-dynamic-macro-symbol-obarray @@ -1176,6 +1165,7 @@ of type `spp-macro-def' is to be created. VALFORM are forms that return the value to be saved for this macro, or nil. When implementing a macro, you can use `semantic-lex-spp-stream-for-macro' to convert text into a lexical stream for storage in the macro." + (declare (debug (&define name stringp stringp form def-body))) (let ((start (make-symbol "start")) (end (make-symbol "end")) (val (make-symbol "val")) @@ -1209,6 +1199,7 @@ REGEXP is a regular expression for the analyzer to match. See `define-lex-regex-analyzer' for more on regexp. TOKIDX is an index into REGEXP for which a new lexical token of type `spp-macro-undef' is to be created." + (declare (debug (&define name stringp stringp form))) (let ((start (make-symbol "start")) (end (make-symbol "end"))) `(define-lex-regex-analyzer ,name @@ -1244,7 +1235,7 @@ Note: Not implemented yet." :group 'semantic :type 'boolean) -(defun semantic-lex-spp-merge-header (name) +(defun semantic-lex-spp-merge-header (_name) "Extract and merge any macros from the header with NAME. Finds the header file belonging to NAME, gets the macros from that file, and then merge the macros with our current @@ -1269,6 +1260,7 @@ type of include. The return value should be of the form: (NAME . TYPE) where NAME is the name of the include, and TYPE is the type of the include, where a valid symbol is `system', or nil." + (declare (debug (&define name stringp stringp form def-body))) (let ((start (make-symbol "start")) (end (make-symbol "end")) (val (make-symbol "val")) @@ -1369,23 +1361,6 @@ If BUFFER is not provided, use the current buffer." (princ "\n") )))) -;;; EDEBUG Handlers -;; -(add-hook - 'edebug-setup-hook - #'(lambda () - - (def-edebug-spec define-lex-spp-macro-declaration-analyzer - (&define name stringp stringp form def-body) - ) - - (def-edebug-spec define-lex-spp-macro-undeclaration-analyzer - (&define name stringp stringp form) - ) - - (def-edebug-spec define-lex-spp-include-analyzer - (&define name stringp stringp form def-body)))) - (provide 'semantic/lex-spp) ;; Local variables: diff --git a/lisp/cedet/semantic/lex.el b/lisp/cedet/semantic/lex.el index ae70d5c730..b3399aa2e6 100644 --- a/lisp/cedet/semantic/lex.el +++ b/lisp/cedet/semantic/lex.el @@ -760,6 +760,7 @@ If two analyzers can match the same text, it is important to order the analyzers so that the one you want to match first occurs first. For example, it is good to put a number analyzer in front of a symbol analyzer which might mistake a number for a symbol." + (declare (debug (&define name stringp (&rest symbolp)))) `(defun ,name (start end &optional depth length) ,(concat doc "\nSee `semantic-lex' for more information.") ;; Make sure the state of block parsing starts over. @@ -1064,14 +1065,13 @@ the desired syntax, and a position returned. If `debug-on-error' is set, errors are not caught, so that you can debug them. Avoid using a large FORMS since it is duplicated." + (declare (indent 1) (debug t)) `(if (and debug-on-error semantic-lex-debug-analyzers) (progn ,@forms) (condition-case nil (progn ,@forms) (error (semantic-lex-unterminated-syntax-detected ,syntax))))) -(put 'semantic-lex-unterminated-syntax-protection - 'lisp-indent-function 1) (defmacro define-lex-analyzer (name doc condition &rest forms) "Create a single lexical analyzer NAME with DOC. @@ -1096,6 +1096,7 @@ Proper action in FORMS is to move the value of `semantic-lex-end-point' to after the location of the analyzed entry, and to add any discovered tokens at the beginning of `semantic-lex-token-stream'. This can be done by using `semantic-lex-push-token'." + (declare (debug (&define name stringp form def-body))) `(eval-and-compile (defvar ,name nil ,doc) (defun ,name nil) @@ -1122,6 +1123,7 @@ This can be done by using `semantic-lex-push-token'." "Create a lexical analyzer with NAME and DOC that will match REGEXP. FORMS are evaluated upon a successful match. See `define-lex-analyzer' for more about analyzers." + (declare (debug (&define name stringp form def-body))) `(define-lex-analyzer ,name ,doc (looking-at ,regexp) @@ -1139,6 +1141,8 @@ expression. FORMS are evaluated upon a successful match BEFORE the new token is created. It is valid to ignore FORMS. See `define-lex-analyzer' for more about analyzers." + (declare (debug + (&define name stringp form symbolp [ &optional form ] def-body))) `(define-lex-analyzer ,name ,doc (looking-at ,regexp) @@ -1163,6 +1167,7 @@ where BLOCK-SYM is the symbol returned in a block token. OPEN-DELIM and CLOSE-DELIM are respectively the open and close delimiters identifying a block. OPEN-SYM and CLOSE-SYM are respectively the symbols returned in open and close tokens." + (declare (debug (&define name stringp form (&rest form)))) (let ((specs (cons spec1 specs)) spec open olist clist) (while specs @@ -1684,6 +1689,7 @@ the error will be caught here without the buffer's cache being thrown out of date. If there is an error, the syntax that failed is returned. If there is no error, then the last value of FORMS is returned." + (declare (indent 1) (debug (symbolp def-body))) (let ((ret (make-symbol "ret")) (syntax (make-symbol "syntax")) (start (make-symbol "start")) @@ -1707,35 +1713,7 @@ If there is no error, then the last value of FORMS is returned." ;;(message "Buffer not currently parsable (%S)." ,ret) (semantic-parse-tree-unparseable)) ,ret))) -(put 'semantic-lex-catch-errors 'lisp-indent-function 1) - -;;; Interfacing with edebug -;; -(add-hook - 'edebug-setup-hook - #'(lambda () - - (def-edebug-spec define-lex - (&define name stringp (&rest symbolp)) - ) - (def-edebug-spec define-lex-analyzer - (&define name stringp form def-body) - ) - (def-edebug-spec define-lex-regex-analyzer - (&define name stringp form def-body) - ) - (def-edebug-spec define-lex-simple-regex-analyzer - (&define name stringp form symbolp [ &optional form ] def-body) - ) - (def-edebug-spec define-lex-block-analyzer - (&define name stringp form (&rest form)) - ) - (def-edebug-spec semantic-lex-catch-errors - (symbolp def-body) - ) - - )) ;;; Compatibility with Semantic 1.x lexical analysis diff --git a/lisp/cedet/semantic/tag.el b/lisp/cedet/semantic/tag.el index 85defe4f2c..3d7bce8657 100644 --- a/lisp/cedet/semantic/tag.el +++ b/lisp/cedet/semantic/tag.el @@ -1,4 +1,4 @@ -;;; semantic/tag.el --- tag creation and access +;;; semantic/tag.el --- Tag creation and access -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2005, 2007-2021 Free Software Foundation, Inc. @@ -1038,25 +1038,17 @@ See `semantic-tag-bounds'." (defmacro semantic-with-buffer-narrowed-to-current-tag (&rest body) "Execute BODY with the buffer narrowed to the current tag." + (declare (indent 0) (debug t)) `(save-restriction (semantic-narrow-to-tag (semantic-current-tag)) ,@body)) -(put 'semantic-with-buffer-narrowed-to-current-tag 'lisp-indent-function 0) -(add-hook 'edebug-setup-hook - (lambda () - (def-edebug-spec semantic-with-buffer-narrowed-to-current-tag - (def-body)))) (defmacro semantic-with-buffer-narrowed-to-tag (tag &rest body) "Narrow to TAG, and execute BODY." + (declare (indent 1) (debug t)) `(save-restriction (semantic-narrow-to-tag ,tag) ,@body)) -(put 'semantic-with-buffer-narrowed-to-tag 'lisp-indent-function 1) -(add-hook 'edebug-setup-hook - (lambda () - (def-edebug-spec semantic-with-buffer-narrowed-to-tag - (def-body)))) ;;; Tag Hooks ;; diff --git a/lisp/cedet/semantic/wisent.el b/lisp/cedet/semantic/wisent.el index d5b73244a0..ecd9683135 100644 --- a/lisp/cedet/semantic/wisent.el +++ b/lisp/cedet/semantic/wisent.el @@ -1,4 +1,4 @@ -;;; semantic/wisent.el --- Wisent - Semantic gateway +;;; semantic/wisent.el --- Wisent - Semantic gateway -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2007, 2009-2021 Free Software Foundation, Inc. @@ -69,6 +69,7 @@ Returned tokens must have the form: (TOKSYM VALUE START . END) where VALUE is the buffer substring between START and END positions." + (declare (debug (&define name stringp def-body))) `(defun ,name () ,doc (cond @@ -319,18 +320,6 @@ the standard function `semantic-parse-region'." (point-max)))))) ;; Return parse tree (nreverse ptree))) - -;;; Interfacing with edebug -;; -(add-hook - 'edebug-setup-hook - #'(lambda () - - (def-edebug-spec define-wisent-lexer - (&define name stringp def-body) - ) - - )) (provide 'semantic/wisent) diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el index 3bf3fd21de..f06452ea17 100644 --- a/lisp/emacs-lisp/cl-lib.el +++ b/lisp/emacs-lisp/cl-lib.el @@ -140,7 +140,7 @@ to an element already in the list stored in PLACE. \n(fn X PLACE [KEYWORD VALUE]...)" (declare (debug (form place &rest - &or [[&or ":test" ":test-not" ":key"] function-form] + &or [[&or ":test" ":test-not" ":key"] form] [keywordp form]))) (if (symbolp place) (if (null keys) diff --git a/lisp/eshell/esh-var.el b/lisp/eshell/esh-var.el index a09c47ce7c..9fccc6b1c9 100644 --- a/lisp/eshell/esh-var.el +++ b/lisp/eshell/esh-var.el @@ -355,7 +355,7 @@ This function is explicit for adding to `eshell-parse-argument-hook'." (defun pcomplete/eshell-mode/setq () "Completion function for Eshell's `setq'." (while (and (pcomplete-here (all-completions pcomplete-stub - obarray 'boundp)) + obarray #'boundp)) (pcomplete-here)))) ;; FIXME the real "env" command does more than this, it runs a program diff --git a/lisp/org/ob-comint.el b/lisp/org/ob-comint.el index 18d4f3c938..b14849df69 100644 --- a/lisp/org/ob-comint.el +++ b/lisp/org/ob-comint.el @@ -44,7 +44,7 @@ BUFFER is checked with `org-babel-comint-buffer-livep'. BODY is executed inside the protection of `save-excursion' and `save-match-data'." - (declare (indent 1)) + (declare (indent 1) (debug t)) `(progn (unless (org-babel-comint-buffer-livep ,buffer) (error "Buffer %s does not exist or has no process" ,buffer)) @@ -53,7 +53,6 @@ executed inside the protection of `save-excursion' and (save-excursion (let ((comint-input-filter (lambda (_input) nil))) ,@body)))))) -(def-edebug-spec org-babel-comint-in-buffer (form body)) (defmacro org-babel-comint-with-output (meta &rest body) "Evaluate BODY in BUFFER and return process output. @@ -67,7 +66,7 @@ elements are optional. This macro ensures that the filter is removed in case of an error or user `keyboard-quit' during execution of body." - (declare (indent 1)) + (declare (indent 1) (debug (sexp body))) (let ((buffer (nth 0 meta)) (eoe-indicator (nth 1 meta)) (remove-echo (nth 2 meta)) @@ -112,7 +111,6 @@ or user `keyboard-quit' during execution of body." string-buffer)) (setq string-buffer (substring string-buffer (match-end 0)))) (split-string string-buffer comint-prompt-regexp))))) -(def-edebug-spec org-babel-comint-with-output (sexp body)) (defun org-babel-comint-input-command (buffer cmd) "Pass CMD to BUFFER. diff --git a/lisp/org/ob-core.el b/lisp/org/ob-core.el index 1343410792..b1fd694371 100644 --- a/lisp/org/ob-core.el +++ b/lisp/org/ob-core.el @@ -1100,7 +1100,7 @@ end-header-args -- point at the end of the header-args body ------------- string holding the body of the code block beg-body --------- point at the beginning of the body end-body --------- point at the end of the body" - (declare (indent 1)) + (declare (indent 1) (debug t)) (let ((tempvar (make-symbol "file"))) `(let* ((case-fold-search t) (,tempvar ,file) @@ -1139,7 +1139,6 @@ end-body --------- point at the end of the body" (goto-char end-block))))) (unless visited-p (kill-buffer to-be-removed)) (goto-char point)))) -(def-edebug-spec org-babel-map-src-blocks (form body)) ;;;###autoload (defmacro org-babel-map-inline-src-blocks (file &rest body) @@ -1354,7 +1353,7 @@ the `org-mode-hook'." (goto-char (match-beginning 0)) (org-babel-hide-hash) (goto-char (match-end 0)))))) -(add-hook 'org-mode-hook 'org-babel-hide-all-hashes) +(add-hook 'org-mode-hook #'org-babel-hide-all-hashes) (defun org-babel-hash-at-point (&optional point) "Return the value of the hash at POINT. @@ -1372,7 +1371,7 @@ This can be called with `\\[org-ctrl-c-ctrl-c]'." Add `org-babel-hide-result' as an invisibility spec for hiding portions of results lines." (add-to-invisibility-spec '(org-babel-hide-result . t))) -(add-hook 'org-mode-hook 'org-babel-result-hide-spec) +(add-hook 'org-mode-hook #'org-babel-result-hide-spec) (defvar org-babel-hide-result-overlays nil "Overlays hiding results.") @@ -1443,11 +1442,11 @@ portions of results lines." (push ov org-babel-hide-result-overlays))))) ;; org-tab-after-check-for-cycling-hook -(add-hook 'org-tab-first-hook 'org-babel-hide-result-toggle-maybe) +(add-hook 'org-tab-first-hook #'org-babel-hide-result-toggle-maybe) ;; Remove overlays when changing major mode (add-hook 'org-mode-hook (lambda () (add-hook 'change-major-mode-hook - 'org-babel-show-result-all 'append 'local))) + #'org-babel-show-result-all 'append 'local))) (defun org-babel-params-from-properties (&optional lang no-eval) "Retrieve source block parameters specified as properties. @@ -3075,8 +3074,7 @@ Emacs shutdown.")) (defmacro org-babel-result-cond (result-params scalar-form &rest table-forms) "Call the code to parse raw string results according to RESULT-PARAMS." - (declare (indent 1) - (debug (form form &rest form))) + (declare (indent 1) (debug t)) (org-with-gensyms (params) `(let ((,params ,result-params)) (unless (member "none" ,params) @@ -3093,7 +3091,6 @@ Emacs shutdown.")) (not (member "table" ,params)))) ,scalar-form ,@table-forms))))) -(def-edebug-spec org-babel-result-cond (form form body)) (defun org-babel-temp-file (prefix &optional suffix) "Create a temporary file in the `org-babel-temporary-directory'. @@ -3136,7 +3133,7 @@ of `org-babel-temporary-directory'." org-babel-temporary-directory "[directory not defined]")))))) -(add-hook 'kill-emacs-hook 'org-babel-remove-temporary-directory) +(add-hook 'kill-emacs-hook #'org-babel-remove-temporary-directory) (defun org-babel-one-header-arg-safe-p (pair safe-list) "Determine if the PAIR is a safe babel header arg according to SAFE-LIST. diff --git a/lisp/org/ob-tangle.el b/lisp/org/ob-tangle.el index 3c3943c8fa..aa0373ab88 100644 --- a/lisp/org/ob-tangle.el +++ b/lisp/org/ob-tangle.el @@ -150,7 +150,7 @@ represented in the file." "Open FILE into a temporary buffer execute BODY there like `progn', then kill the FILE buffer returning the result of evaluating BODY." - (declare (indent 1)) + (declare (indent 1) (debug t)) (let ((temp-path (make-symbol "temp-path")) (temp-result (make-symbol "temp-result")) (temp-file (make-symbol "temp-file")) @@ -164,7 +164,6 @@ evaluating BODY." (setf ,temp-result (progn ,@body))) (unless ,visited-p (kill-buffer ,temp-file)) ,temp-result))) -(def-edebug-spec org-babel-with-temp-filebuffer (form body)) ;;;###autoload (defun org-babel-tangle-file (file &optional target-file lang-re) diff --git a/lisp/org/org-agenda.el b/lisp/org/org-agenda.el index 99e5464c2b..b9799d2abe 100644 --- a/lisp/org/org-agenda.el +++ b/lisp/org/org-agenda.el @@ -2090,6 +2090,7 @@ Note that functions in this alist don't need to be quoted." If STRING is non-nil, the text property will be fetched from position 0 in that string. If STRING is nil, it will be fetched from the beginning of the current line." + (declare (debug t)) (org-with-gensyms (marker) `(let ((,marker (get-text-property (if ,string 0 (point-at-bol)) 'org-hd-marker ,string))) @@ -2097,7 +2098,6 @@ of the current line." (save-excursion (goto-char ,marker) ,@body))))) -(def-edebug-spec org-agenda-with-point-at-orig-entry (form body)) (defun org-add-agenda-custom-command (entry) "Replace or add a command in `org-agenda-custom-commands'. diff --git a/lisp/org/org-clock.el b/lisp/org/org-clock.el index 2073b33380..2844b0e511 100644 --- a/lisp/org/org-clock.el +++ b/lisp/org/org-clock.el @@ -911,17 +911,17 @@ If CLOCK-SOUND is non-nil, it overrides `org-clock-sound'." (defmacro org-with-clock-position (clock &rest forms) "Evaluate FORMS with CLOCK as the current active clock." + (declare (indent 1) (debug t)) `(with-current-buffer (marker-buffer (car ,clock)) (org-with-wide-buffer (goto-char (car ,clock)) (beginning-of-line) ,@forms))) -(def-edebug-spec org-with-clock-position (form body)) -(put 'org-with-clock-position 'lisp-indent-function 1) (defmacro org-with-clock (clock &rest forms) "Evaluate FORMS with CLOCK as the current active clock. This macro also protects the current active clock from being altered." + (declare (indent 1) (debug t)) `(org-with-clock-position ,clock (let ((org-clock-start-time (cdr ,clock)) (org-clock-total-time) @@ -932,8 +932,6 @@ This macro also protects the current active clock from being altered." (org-back-to-heading t) (point-marker)))) ,@forms))) -(def-edebug-spec org-with-clock (form body)) -(put 'org-with-clock 'lisp-indent-function 1) (defsubst org-clock-clock-in (clock &optional resume start-time) "Clock in to the clock located by CLOCK. diff --git a/lisp/org/org-pcomplete.el b/lisp/org/org-pcomplete.el index 29d9d58482..d8a4937b95 100644 --- a/lisp/org/org-pcomplete.el +++ b/lisp/org/org-pcomplete.el @@ -239,11 +239,11 @@ When completing for #+STARTUP, for example, this function returns (require 'ox) (pcomplete-here (and org-export-exclude-tags - (list (mapconcat 'identity org-export-exclude-tags " "))))) + (list (mapconcat #'identity org-export-exclude-tags " "))))) (defun pcomplete/org-mode/file-option/filetags () "Complete arguments for the #+FILETAGS file option." - (pcomplete-here (and org-file-tags (mapconcat 'identity org-file-tags " ")))) + (pcomplete-here (and org-file-tags (mapconcat #'identity org-file-tags " ")))) (defun pcomplete/org-mode/file-option/language () "Complete arguments for the #+LANGUAGE file option." @@ -264,13 +264,13 @@ When completing for #+STARTUP, for example, this function returns (require 'ox) (pcomplete-here (and org-export-select-tags - (list (mapconcat 'identity org-export-select-tags " "))))) + (list (mapconcat #'identity org-export-select-tags " "))))) (defun pcomplete/org-mode/file-option/startup () "Complete arguments for the #+STARTUP file option." (while (pcomplete-here (let ((opts (pcomplete-uniquify-list - (mapcar 'car org-startup-options)))) + (mapcar #'car org-startup-options)))) ;; Some options are mutually exclusive, and shouldn't be completed ;; against if certain other options have already been seen. (dolist (arg pcomplete-args) @@ -340,7 +340,8 @@ When completing for #+STARTUP, for example, this function returns "Complete against TeX-style HTML entity names." (require 'org-entities) (while (pcomplete-here - (pcomplete-uniquify-list (remove nil (mapcar 'car-safe org-entities))) + (pcomplete-uniquify-list + (remove nil (mapcar #'car-safe org-entities))) (substring pcomplete-stub 1)))) (defun pcomplete/org-mode/todo () diff --git a/lisp/pcmpl-gnu.el b/lisp/pcmpl-gnu.el index dd964e3638..6c68645eb2 100644 --- a/lisp/pcmpl-gnu.el +++ b/lisp/pcmpl-gnu.el @@ -106,7 +106,7 @@ (while (pcomplete-here (completion-table-in-turn (pcmpl-gnu-make-rule-names) (pcomplete-entries)) - nil 'identity)))) + nil #'identity)))) (defun pcmpl-gnu-makefile-names () "Return a list of possible makefile names." @@ -336,7 +336,7 @@ Return the new list." (pcomplete-match-string 1 0))))) (unless saw-option (pcomplete-here - (mapcar 'char-to-string + (mapcar #'char-to-string (string-to-list "01234567ABCFGIKLMNOPRSTUVWXZbcdfghiklmoprstuvwxz"))) (if (pcomplete-match "[xt]" 'first 1) @@ -355,7 +355,7 @@ Return the new list." (pcmpl-gnu-with-file-buffer file (mapcar #'tar-header-name tar-parse-info))))) (pcomplete-entries)) - nil 'identity)))) + nil #'identity)))) ;;;###autoload @@ -391,7 +391,7 @@ Return the new list." (string= prec "-execdir")) (while (pcomplete-here* (funcall pcomplete-command-completion-function) (pcomplete-arg 'last) t)))) - (while (pcomplete-here (pcomplete-dirs) nil 'identity)))) + (while (pcomplete-here (pcomplete-dirs) nil #'identity)))) ;;;###autoload (defalias 'pcomplete/gdb 'pcomplete/xargs) diff --git a/lisp/pcmpl-linux.el b/lisp/pcmpl-linux.el index 2f42dbd4fa..263d646dc6 100644 --- a/lisp/pcmpl-linux.el +++ b/lisp/pcmpl-linux.el @@ -50,20 +50,20 @@ (while (pcomplete-here (if (file-directory-p "/proc") (directory-files "/proc" nil "\\`[0-9]+\\'")) - nil 'identity))) + nil #'identity))) ;;;###autoload (defun pcomplete/umount () "Completion for GNU/Linux `umount'." (pcomplete-opt "hVafrnvt(pcmpl-linux-fs-types)") (while (pcomplete-here (pcmpl-linux-mounted-directories) - nil 'identity))) + nil #'identity))) ;;;###autoload (defun pcomplete/mount () "Completion for GNU/Linux `mount'." (pcomplete-opt "hVanfFrsvwt(pcmpl-linux-fs-types)o?L?U?") - (while (pcomplete-here (pcomplete-entries) nil 'identity))) + (while (pcomplete-here (pcomplete-entries) nil #'identity))) (defconst pcmpl-linux-fs-modules-path-format "/lib/modules/%s/kernel/fs/") diff --git a/lisp/pcmpl-unix.el b/lisp/pcmpl-unix.el index 70273b94a1..c1aaf829dc 100644 --- a/lisp/pcmpl-unix.el +++ b/lisp/pcmpl-unix.el @@ -77,7 +77,7 @@ being via `pcmpl-ssh-known-hosts-file'." (let ((pcomplete-help "(fileutils)rm invocation")) (pcomplete-opt "dfirRv") (while (pcomplete-here (pcomplete-all-entries) nil - 'expand-file-name)))) + #'expand-file-name)))) ;;;###autoload (defun pcomplete/xargs () diff --git a/lisp/pcmpl-x.el b/lisp/pcmpl-x.el index 61d8866679..084f0e66bc 100644 --- a/lisp/pcmpl-x.el +++ b/lisp/pcmpl-x.el @@ -301,7 +301,8 @@ long options." "nst" "ntd" "nto" "nvf" "obi" "obs" "ofp" "osh" "ovf" "par" "pch" "pck" "pia" "pin" "pow" "prc" "pre" "pro" "rch" "ret" "rng" "rpt" "rvl" "sig" "spa" "stl" "stu" "stv" "sus" "tai" - "tes" "thr" "ucp" "use" "voi" "zdi") (match-string 2 cur))) + "tes" "thr" "ucp" "use" "voi" "zdi") + (match-string 2 cur))) ((string-match "\\`-[LIn]\\([^;]+;\\)*\\([^;]*\\)\\'" cur) (pcomplete-here (pcomplete-dirs) (match-string 2 cur))) ((string-match "\\`-[Ee]\\(.*\\)\\'" cur) diff --git a/lisp/shell.el b/lisp/shell.el index 3212824165..9238ad1e8a 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -463,7 +463,7 @@ Shell buffers. It implements `shell-completion-execonly' for (if (pcomplete-match "/") (pcomplete-here (pcomplete-entries nil (if shell-completion-execonly - 'file-executable-p))) + #'file-executable-p))) (pcomplete-here (nth 2 (shell--command-completion-data))))) diff --git a/lisp/speedbar.el b/lisp/speedbar.el index e43978f413..d64c72184e 100644 --- a/lisp/speedbar.el +++ b/lisp/speedbar.el @@ -1,4 +1,4 @@ -;;; speedbar --- quick access to files and tags in a frame +;;; speedbar --- quick access to files and tags in a frame -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. @@ -1640,7 +1640,7 @@ variable `speedbar-obj-alist'." (defmacro speedbar-with-writable (&rest forms) "Allow the buffer to be writable and evaluate FORMS." - (declare (indent 0)) + (declare (indent 0) (debug t)) `(let ((inhibit-read-only t)) ,@forms)) @@ -4001,11 +4001,6 @@ TEXT is the buffer's name, TOKEN and INDENT are unused." "Speedbar face for separator labels in a display." :group 'speedbar-faces) -;; some edebug hooks -(add-hook 'edebug-setup-hook - (lambda () - (def-edebug-spec speedbar-with-writable def-body))) - ;; Fix a font lock problem for some versions of Emacs (and (boundp 'font-lock-global-modes) font-lock-global-modes diff --git a/lisp/subr.el b/lisp/subr.el index eb28728760..454ea54b6a 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -88,6 +88,7 @@ Both SYMBOL and SPEC are unevaluated. The SPEC can be: a symbol (naming a function with an Edebug specification); or a list. The elements of the list describe the argument types; see Info node `(elisp)Specification List' for details." + (declare (indent 1)) `(put (quote ,symbol) 'edebug-form-spec (quote ,spec))) (defmacro lambda (&rest cdr) diff --git a/lisp/textmodes/rst.el b/lisp/textmodes/rst.el index 2b31e7ed61..c51285d3de 100644 --- a/lisp/textmodes/rst.el +++ b/lisp/textmodes/rst.el @@ -105,10 +105,6 @@ ;; Common Lisp stuff (require 'cl-lib) -;; Correct wrong declaration. -(def-edebug-spec push - (&or [form symbolp] [form gv-place])) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Support for `testcover' diff --git a/lisp/vc/pcvs-parse.el b/lisp/vc/pcvs-parse.el index 43816501bd..a95ea0d99d 100644 --- a/lisp/vc/pcvs-parse.el +++ b/lisp/vc/pcvs-parse.el @@ -1,4 +1,4 @@ -;;; pcvs-parse.el --- the CVS output parser +;;; pcvs-parse.el --- the CVS output parser -*- lexical-binding: t; -*- ;; Copyright (C) 1991-2021 Free Software Foundation, Inc. @@ -73,12 +73,12 @@ by `$'." '("status" "add" "commit" "update" "remove" "checkout" "ci") "List of CVS commands whose output is understood by the parser.") -(defun cvs-parse-buffer (parse-spec dont-change-disc &optional subdir) +(defun cvs-parse-buffer (parse-spec dcd &optional subdir) "Parse current buffer according to PARSE-SPEC. PARSE-SPEC is a function of no argument advancing the point and returning either a fileinfo or t (if the matched text should be ignored) or nil if it didn't match anything. -DONT-CHANGE-DISC just indicates whether the command was changing the disc +DCD just indicates whether the command was changing the disc or not (useful to tell the difference between `cvs-examine' and `cvs-update' output. The path names should be interpreted as relative to SUBDIR (defaults @@ -86,6 +86,7 @@ The path names should be interpreted as relative to SUBDIR (defaults Return a list of collected entries, or t if an error occurred." (goto-char (point-min)) (let ((fileinfos ()) + (dont-change-disc dcd) (cvs-current-dir "") (case-fold-search nil) (cvs-current-subdir (or subdir ""))) @@ -134,12 +135,12 @@ Match RE and if successful, execute MATCHES." (defmacro cvs-or (&rest alts) "Try each one of the ALTS alternatives until one matches." + (declare (debug t)) `(let ((-cvs-parse-point (point))) ,(cons 'or (mapcar (lambda (es) `(or ,es (ignore (goto-char -cvs-parse-point)))) alts)))) -(def-edebug-spec cvs-or t) ;; This is how parser tables should be executed (defun cvs-parse-run-table (parse-spec) @@ -190,9 +191,9 @@ The remaining KEYS are passed directly to `cvs-create-fileinfo'." file (cvs-parse-msg) :subtype subtype keys)))) ;;;; CVS Process Parser Tables: -;;;; -;;;; The table for status and update could actually be merged since they -;;;; don't conflict. But they don't overlap much either. +;; +;; The table for status and update could actually be merged since they +;; don't conflict. But they don't overlap much either. (defun cvs-parse-table () "Table of message objects for `cvs-parse-process'." commit 9518926220943d5c405e03d7352343341e07ba83 Author: Mattias Engdegård Date: Fri Feb 12 19:43:41 2021 +0100 Simplify expression in byte-code decompiler * lisp/emacs-lisp/byte-opt.el (byte-decompile-bytecode-1): Replace roundabout expression with what it essentially does. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index c383e0285b..e0feb95a46 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -1562,10 +1562,7 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") ;; so we create a copy of it, and replace the addresses with ;; TAGs. (let ((orig-table last-constant)) - (cl-loop for e across constvec - when (eq e last-constant) - do (setq last-constant (copy-hash-table e)) - and return nil) + (setq last-constant (copy-hash-table last-constant)) ;; Replace all addresses with TAGs. (maphash #'(lambda (value offset) (let ((match (assq offset tags))) commit 5a11e9185c0416df8fa3a15bb0d60b6ba6827869 Author: Mattias Engdegård Date: Fri Feb 12 19:41:07 2021 +0100 byte-opt.el: More concise expression * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Refactor `setq` clause. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index fec3407782..c383e0285b 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -593,16 +593,15 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") (lexvar (assq var byte-optimize--lexvars)) (value (byte-optimize-form expr nil))) (when lexvar - ;; If it's bound outside conditional, invalidate. - (if (assq var byte-optimize--vars-outside-condition) - ;; We are in conditional code and the variable was - ;; bound outside: cancel substitutions. - (setcdr (cdr lexvar) nil) - ;; Set a new value (if substitutable). - (setcdr (cdr lexvar) - (and (byte-optimize--substitutable-p value) - (list value)))) - (setcar (cdr lexvar) t)) ; Mark variable to be kept. + ;; Set a new value or inhibit further substitution. + (setcdr (cdr lexvar) + (and + ;; Inhibit if bound outside conditional code. + (not (assq var byte-optimize--vars-outside-condition)) + ;; The new value must be substitutable. + (byte-optimize--substitutable-p value) + (list value))) + (setcar (cdr lexvar) t)) ; Mark variable to be kept. (push var var-expr-list) (push value var-expr-list)) (setq args (cddr args))) commit ea29908c1870417eba98f27525a6f2f571d65396 Author: Mattias Engdegård Date: Thu Feb 11 17:34:17 2021 +0100 Avoid traversing dead `if` branches in bytecode optimiser There is no point in traversing conditional branches that are statically known never to be executed. This saves some optimisation effort, but more importantly prevents variable assignments and references in those branches from blocking effective constant propagation. Also attempt to traverse as much as possible in an unconditional context, which enables constant-propagation through (linear) assignments. * lisp/emacs-lisp/byte-opt.el (byte-optimize-form): Rewrite the (tail) recursion into an explicit loop. Normalise a return value of (quote nil) to nil, for easier subsequent optimisations. * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Don't traverse dead `if` branches. Use unconditional traversion context when possible. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 8851f0ef32..fec3407782 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -458,16 +458,22 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") (cons fn (byte-optimize-body exps for-effect))) (`(if ,test ,then . ,else) + ;; FIXME: We are conservative here: any variable changed in the + ;; THEN branch will be barred from substitution in the ELSE + ;; branch, despite the branches being mutually exclusive. + ;; The test is always executed. (let* ((test-opt (byte-optimize-form test nil)) - ;; The THEN and ELSE branches are executed conditionally. - ;; - ;; FIXME: We are conservative here: any variable changed in the - ;; THEN branch will be barred from substitution in the ELSE - ;; branch, despite the branches being mutually exclusive. - (byte-optimize--vars-outside-condition byte-optimize--lexvars) - (then-opt (byte-optimize-form then for-effect)) - (else-opt (byte-optimize-body else for-effect))) + (const (macroexp-const-p test-opt)) + ;; The branches are traversed unconditionally when possible. + (byte-optimize--vars-outside-condition + (if const + byte-optimize--vars-outside-condition + byte-optimize--lexvars)) + ;; Avoid traversing dead branches. + (then-opt (and test-opt (byte-optimize-form then for-effect))) + (else-opt (and (not (and test-opt const)) + (byte-optimize-body else for-effect)))) `(if ,test-opt ,then-opt . ,else-opt))) (`(,(or 'and 'or) . ,exps) ; Remember, and/or are control structures. @@ -638,30 +644,24 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") (defun byte-optimize-form (form &optional for-effect) "The source-level pass of the optimizer." - ;; - ;; First, optimize all sub-forms of this one. - (setq form (byte-optimize-form-code-walker form for-effect)) - ;; - ;; after optimizing all subforms, optimize this form until it doesn't - ;; optimize any further. This means that some forms will be passed through - ;; the optimizer many times, but that's necessary to make the for-effect - ;; processing do as much as possible. - ;; - (let (opt new) - (if (and (consp form) - (symbolp (car form)) - (or ;; (and for-effect - ;; ;; We don't have any of these yet, but we might. - ;; (setq opt (get (car form) - ;; 'byte-for-effect-optimizer))) - (setq opt (function-get (car form) 'byte-optimizer))) - (not (eq form (setq new (funcall opt form))))) - (progn -;; (if (equal form new) (error "bogus optimizer -- %s" opt)) - (byte-compile-log " %s\t==>\t%s" form new) - (setq new (byte-optimize-form new for-effect)) - new) - form))) + (while + (progn + ;; First, optimize all sub-forms of this one. + (setq form (byte-optimize-form-code-walker form for-effect)) + + ;; If a form-specific optimiser is available, run it and start over + ;; until a fixpoint has been reached. + (and (consp form) + (symbolp (car form)) + (let ((opt (function-get (car form) 'byte-optimizer))) + (and opt + (let ((old form) + (new (funcall opt form))) + (byte-compile-log " %s\t==>\t%s" old new) + (setq form new) + (not (eq new old)))))))) + ;; Normalise (quote nil) to nil, for a single representation of constant nil. + (and (not (equal form '(quote nil))) form)) (defun byte-optimize-let-form (head form for-effect) ;; Recursively enter the optimizer for the bindings and body commit c4459a10a6962d90adc4cdfada36175aaed99dfc Author: Mattias Engdegård Date: Thu Feb 11 20:41:02 2021 +0100 Don't inline tramp-debug-message * lisp/net/tramp.el (tramp-debug-message): Change defsubst into defun. Until now the byte-compiler hasn't been clever enough to inline this function but this is about to change; the code expansion is unnecessary and makes compiler improvements more difficult to gauge. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 690dd99ae5..e33075ec6f 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1750,7 +1750,7 @@ The outline level is equal to the verbosity of the Tramp message." (tramp-compat-string-replace "/" " " (tramp-debug-buffer-name vec)) (tramp-compat-temporary-file-directory))) -(defsubst tramp-debug-message (vec fmt-string &rest arguments) +(defun tramp-debug-message (vec fmt-string &rest arguments) "Append message to debug buffer of VEC. Message is formatted with FMT-STRING as control string and the remaining ARGUMENTS to actually emit the message (if applicable)." commit b24ae269b28673fabf4458f0c3d4afbf5c93a164 Author: Basil L. Contovounesios Date: Fri Feb 12 18:21:45 2021 +0000 ; Fix typo in last change to m4-mode.el. diff --git a/lisp/progmodes/m4-mode.el b/lisp/progmodes/m4-mode.el index 431d86bddd..7dfaed4428 100644 --- a/lisp/progmodes/m4-mode.el +++ b/lisp/progmodes/m4-mode.el @@ -78,7 +78,7 @@ If m4 is not in your PATH, set this to an absolute file name." "stack_foreach_sep" "stack_foreach_sep_lifo" "substr" "syscmd" "sysval" "traceoff" "traceon" "translit" "undefine" "undivert" "unix" "upcase" "windows") - "List of valid m4 macros. for M4 mode")) + "List of valid m4 macros for M4 mode.")) (defvar m4-font-lock-keywords (eval-when-compile commit 733dfe244b44de957b0d91b7726f3e053be7000a Author: Stefan Kangas Date: Fri Feb 12 18:38:58 2021 +0100 ; Fix recent regexp-opt conversion in cperl-mode * lisp/progmodes/cperl-mode.el (cperl-init-faces): Add missing identifiers found by static analysis of recent change. Thanks to Mattias Engdegård . diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index b1a49b25a3..90ccdbf00a 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -5435,7 +5435,7 @@ indentation and initial hashes. Behaves usually outside of comment." (concat "\\(^\\|[^$@%&\\]\\)\\<\\(" (regexp-opt - '("CORE" "__FILE__" "__LINE__" "__SUB__" + '("CORE" "__FILE__" "__LINE__" "__SUB__" "__PACKAGE__" "abs" "accept" "alarm" "and" "atan2" "bind" "binmode" "bless" "caller" "chdir" "chmod" "chown" "chr" "chroot" "close" @@ -5483,7 +5483,7 @@ indentation and initial hashes. Behaves usually outside of comment." "evalbytes" "exists" "finally" "for" "foreach" "format" "given" "goto" "grep" "if" "keys" "last" "local" "m" "map" "my" "next" "no" "our" "package" "pop" "pos" "print" "printf" "prototype" - "push" "q" "qq" "qw" "qx" "redo" "return" "s" "say" "scalar" + "push" "q" "qq" "qr" "qw" "qx" "redo" "return" "s" "say" "scalar" "shift" "sort" "splice" "split" "state" "study" "sub" "tie" "tied" "tr" "try" "undef" "unless" "unshift" "untie" "until" "use" "when" "while" "y")) commit fffe88bf623802c64518eae84cf6f3fcd16ac420 Author: Stefan Kangas Date: Fri Feb 12 05:39:44 2021 +0100 Use regexp-opt for font lock defaults in meta-mode.el * lisp/progmodes/meta-mode.el: Remove redundant :group args. (meta-font-lock-keywords): Use regexp-opt. diff --git a/lisp/progmodes/meta-mode.el b/lisp/progmodes/meta-mode.el index 9da968c831..46b0949c13 100644 --- a/lisp/progmodes/meta-mode.el +++ b/lisp/progmodes/meta-mode.el @@ -109,44 +109,31 @@ "\\(def\\|let\\|mode_def\\|vardef\\)") (macro-keywords-2 "\\(primarydef\\|secondarydef\\|tertiarydef\\)") -;(make-regexp -; '("expr" "suffix" "text" "primary" "secondary" "tertiary") t) (args-keywords - (concat "\\(expr\\|primary\\|s\\(econdary\\|uffix\\)\\|" - "te\\(rtiary\\|xt\\)\\)")) -;(make-regexp -; '("boolean" "color" "numeric" "pair" "path" "pen" "picture" -; "string" "transform" "newinternal") t) + (eval-when-compile + (regexp-opt + '("expr" "suffix" "text" "primary" "secondary" "tertiary") + t))) (type-keywords - (concat "\\(boolean\\|color\\|n\\(ewinternal\\|umeric\\)\\|" - "p\\(a\\(ir\\|th\\)\\|en\\|icture\\)\\|string\\|" - "transform\\)")) -;(make-regexp -; '("for" "forever" "forsuffixes" "endfor" -; "step" "until" "upto" "downto" "thru" "within" -; "iff" "if" "elseif" "else" "fi" "exitif" "exitunless" -; "let" "def" "vardef" "enddef" "mode_def" -; "true" "false" "known" "unknown" "and" "or" "not" -; "save" "interim" "inner" "outer" "relax" -; "begingroup" "endgroup" "expandafter" "scantokens" -; "generate" "input" "endinput" "end" "bye" -; "message" "errmessage" "errhelp" "special" "numspecial" -; "readstring" "readfrom" "write") t) + (eval-when-compile + (regexp-opt + '("boolean" "color" "numeric" "pair" "path" "pen" "picture" + "string" "transform" "newinternal") + t))) (syntactic-keywords - (concat "\\(and\\|b\\(egingroup\\|ye\\)\\|" - "d\\(ef\\|ownto\\)\\|e\\(lse\\(\\|if\\)" - "\\|nd\\(\\|def\\|for\\|group\\|input\\)" - "\\|rr\\(help\\|message\\)" - "\\|x\\(it\\(if\\|unless\\)\\|pandafter\\)\\)\\|" - "f\\(alse\\|i\\|or\\(\\|ever\\|suffixes\\)\\)\\|" - "generate\\|i\\(ff?\\|n\\(ner\\|put\\|terim\\)\\)\\|" - "known\\|let\\|m\\(essage\\|ode_def\\)\\|" - "n\\(ot\\|umspecial\\)\\|o\\(r\\|uter\\)\\|" - "re\\(ad\\(from\\|string\\)\\|lax\\)\\|" - "s\\(ave\\|cantokens\\|pecial\\|tep\\)\\|" - "t\\(hru\\|rue\\)\\|" - "u\\(n\\(known\\|til\\)\\|pto\\)\\|" - "vardef\\|w\\(ithin\\|rite\\)\\)")) + (eval-when-compile + (regexp-opt + '("for" "forever" "forsuffixes" "endfor" + "step" "until" "upto" "downto" "thru" "within" + "iff" "if" "elseif" "else" "fi" "exitif" "exitunless" + "let" "def" "vardef" "enddef" "mode_def" + "true" "false" "known" "unknown" "and" "or" "not" + "save" "interim" "inner" "outer" "relax" + "begingroup" "endgroup" "expandafter" "scantokens" + "generate" "input" "endinput" "end" "bye" + "message" "errmessage" "errhelp" "special" "numspecial" + "readstring" "readfrom" "write") + t))) ) (list ;; embedded TeX code in btex ... etex @@ -463,25 +450,21 @@ If the list was changed, sort the list and remove duplicates first." (defcustom meta-indent-level 2 "Indentation of begin-end blocks in Metafont or MetaPost mode." - :type 'integer - :group 'meta-font) + :type 'integer) (defcustom meta-left-comment-regexp "%%+" "Regexp matching comments that should be placed on the left margin." - :type 'regexp - :group 'meta-font) + :type 'regexp) (defcustom meta-right-comment-regexp nil "Regexp matching comments that should be placed on the right margin." :type '(choice regexp - (const :tag "None" nil)) - :group 'meta-font) + (const :tag "None" nil))) (defcustom meta-ignore-comment-regexp "%[^%]" "Regexp matching comments whose indentation should not be touched." - :type 'regexp - :group 'meta-font) + :type 'regexp) (defcustom meta-begin-environment-regexp @@ -489,22 +472,19 @@ If the list was changed, sort the list and remove duplicates first." "def\\|for\\(\\|ever\\|suffixes\\)\\|if\\|mode_def\\|" "primarydef\\|secondarydef\\|tertiarydef\\|vardef\\)") "Regexp matching the beginning of environments to be indented." - :type 'regexp - :group 'meta-font) + :type 'regexp) (defcustom meta-end-environment-regexp (concat "\\(end\\(char\\|def\\|f\\(ig\\|or\\)\\|gr\\(aph\\|oup\\)\\)" "\\|fi\\)") "Regexp matching the end of environments to be indented." - :type 'regexp - :group 'meta-font) + :type 'regexp) (defcustom meta-within-environment-regexp ; (concat "\\(e\\(lse\\(\\|if\\)\\|xit\\(if\\|unless\\)\\)\\)") (concat "\\(else\\(\\|if\\)\\)") "Regexp matching keywords within environments not to be indented." - :type 'regexp - :group 'meta-font) + :type 'regexp) (defun meta-comment-indent () @@ -689,14 +669,12 @@ If the list was changed, sort the list and remove duplicates first." (concat "\\(begin\\(char\\|fig\\|logochar\\)\\|def\\|mode_def\\|" "primarydef\\|secondarydef\\|tertiarydef\\|vardef\\)") "Regexp matching beginning of defuns in Metafont or MetaPost mode." - :type 'regexp - :group 'meta-font) + :type 'regexp) (defcustom meta-end-defun-regexp (concat "\\(end\\(char\\|def\\|fig\\)\\)") "Regexp matching the end of defuns in Metafont or MetaPost mode." - :type 'regexp - :group 'meta-font) + :type 'regexp) (defun meta-beginning-of-defun (&optional arg) @@ -893,24 +871,21 @@ The environment marked is the one that contains point or follows point." (defcustom meta-mode-load-hook nil "Hook evaluated when first loading Metafont or MetaPost mode." - :type 'hook - :group 'meta-font) + :type 'hook) (make-obsolete-variable 'meta-mode-load-hook "use `with-eval-after-load' instead." "28.1") (defcustom meta-common-mode-hook nil "Hook evaluated by both `metafont-mode' and `metapost-mode'." - :type 'hook - :group 'meta-font) + :type 'hook) (defcustom metafont-mode-hook nil "Hook evaluated by `metafont-mode' after `meta-common-mode-hook'." - :type 'hook - :group 'meta-font) + :type 'hook) + (defcustom metapost-mode-hook nil "Hook evaluated by `metapost-mode' after `meta-common-mode-hook'." - :type 'hook - :group 'meta-font) + :type 'hook) commit a799f6d9d859163f8c66b1b349206141b318a9eb Author: Stefan Kangas Date: Fri Feb 12 05:30:32 2021 +0100 Minor cleanups in scheme.el * lisp/progmodes/scheme.el: Remove redundant :group args. (dsssl-font-lock-keywords): Use regexp-opt. diff --git a/lisp/progmodes/scheme.el b/lisp/progmodes/scheme.el index f610efbfca..a899de7e59 100644 --- a/lisp/progmodes/scheme.el +++ b/lisp/progmodes/scheme.el @@ -215,8 +215,7 @@ Blank lines separate paragraphs. Semicolons start comments. (defcustom scheme-mit-dialect t "If non-nil, scheme mode is specialized for MIT Scheme. Set this to nil if you normally use another dialect." - :type 'boolean - :group 'scheme) + :type 'boolean) (defcustom dsssl-sgml-declaration " @@ -226,26 +225,22 @@ If it is defined as a string this will be inserted into an empty buffer which is in `dsssl-mode'. It is typically James Clark's style-sheet doctype, as required for Jade." :type '(choice (string :tag "Specified string") - (const :tag "None" :value nil)) - :group 'scheme) + (const :tag "None" :value nil))) (defcustom scheme-mode-hook nil "Normal hook run when entering `scheme-mode'. See `run-hooks'." - :type 'hook - :group 'scheme) + :type 'hook) (defcustom dsssl-mode-hook nil "Normal hook run when entering `dsssl-mode'. See `run-hooks'." - :type 'hook - :group 'scheme) + :type 'hook) ;; This is shared by cmuscheme and xscheme. (defcustom scheme-program-name "scheme" "Program invoked by the `run-scheme' command." - :type 'string - :group 'scheme) + :type 'string) (defvar dsssl-imenu-generic-expression ;; Perhaps this should also look for the style-sheet DTD tags. I'm @@ -429,12 +424,10 @@ that variable's value is a string." '(1 font-lock-keyword-face) '(4 font-lock-function-name-face)) (cons - (concat "(\\(" - ;; (make-regexp '("case" "cond" "else" "if" "lambda" - ;; "let" "let*" "letrec" "and" "or" "map" "with-mode")) - "and\\|c\\(ase\\|ond\\)\\|else\\|if\\|" - "l\\(ambda\\|et\\(\\|\\*\\|rec\\)\\)\\|map\\|or\\|with-mode" - "\\)\\>") + (concat "(" (regexp-opt + '("case" "cond" "else" "if" "lambda" + "let" "let*" "letrec" "and" "or" "map" "with-mode") + 'words)) 1) ;; DSSSL syntax '("(\\(element\\|mode\\|declare-\\w+\\)\\>[ \t]*\\(\\sw+\\)" commit 506b8d725a4591747a97e806c140d9e72863c1d0 Author: Stefan Kangas Date: Fri Feb 12 05:15:01 2021 +0100 Add font locking for many missing macros in m4-mode * lisp/progmodes/m4-mode.el (m4--macro-list): New variable. (m4-font-lock-keywords): Use regexp-opt and add many missing macros sourced from the M4 manual. diff --git a/lisp/progmodes/m4-mode.el b/lisp/progmodes/m4-mode.el index 99f4be3872..431d86bddd 100644 --- a/lisp/progmodes/m4-mode.el +++ b/lisp/progmodes/m4-mode.el @@ -60,12 +60,34 @@ If m4 is not in your PATH, set this to an absolute file name." ;;or ;;(defconst m4-program-options '("--prefix-builtins")) +;; Needed at compile-time for `m4-font-lock-keywords' below. +(eval-and-compile + (defconst m4--macro-list + ;; From (info "(m4) Macro index") + '("__file__" "__gnu__" "__line__" "__os2__" "__program__" "__unix__" + "__windows__" "argn" "array" "array_set" "builtin" "capitalize" + "changecom" "changequote" "changeword" "cleardivert" "cond" "copy" + "curry" "debugfile" "debugmode" "decr" "define" "define_blind" + "defn" "divert" "divnum" "dnl" "downcase" "dquote" "dquote_elt" + "dumpdef" "errprint" "esyscmd" "eval" "example" "exch" + "fatal_error" "file" "foreach" "foreachq" "forloop" "format" "gnu" + "ifdef" "ifelse" "include" "incr" "index" "indir" "join" "joinall" + "len" "line" "m4exit" "m4wrap" "maketemp" "mkstemp" "nargs" "os2" + "patsubst" "popdef" "pushdef" "quote" "regexp" "rename" "reverse" + "shift" "sinclude" "stack_foreach" "stack_foreach_lifo" + "stack_foreach_sep" "stack_foreach_sep_lifo" "substr" "syscmd" + "sysval" "traceoff" "traceon" "translit" "undefine" "undivert" + "unix" "upcase" "windows") + "List of valid m4 macros. for M4 mode")) + (defvar m4-font-lock-keywords - '(("\\(\\_<\\(m4_\\)?dnl\\_>\\).*$" (0 font-lock-comment-face t)) - ("\\$[*#@0-9]" . font-lock-variable-name-face) - ("\\$@" . font-lock-variable-name-face) - ("\\$\\*" . font-lock-variable-name-face) - ("\\_<\\(m4_\\)?\\(builtin\\|change\\(com\\|quote\\|word\\)\\|d\\(e\\(bug\\(file\\|mode\\)\\|cr\\|f\\(ine\\|n\\)\\)\\|iv\\(ert\\|num\\)\\|nl\\|umpdef\\)\\|e\\(rrprint\\|syscmd\\|val\\)\\|f\\(ile\\|ormat\\)\\|gnu\\|i\\(f\\(def\\|else\\)\\|n\\(c\\(lude\\|r\\)\\|d\\(ex\\|ir\\)\\)\\)\\|l\\(en\\|ine\\)\\|m\\(4\\(exit\\|wrap\\)\\|aketemp\\)\\|p\\(atsubst\\|opdef\\|ushdef\\)\\|regexp\\|s\\(hift\\|include\\|ubstr\\|ys\\(cmd\\|val\\)\\)\\|tra\\(ceo\\(ff\\|n\\)\\|nslit\\)\\|un\\(d\\(efine\\|ivert\\)\\|ix\\)\\)\\_>" . font-lock-keyword-face)) + (eval-when-compile + `(("\\(\\_<\\(m4_\\)?dnl\\_>\\).*$" (0 font-lock-comment-face t)) + ("\\$[*#@0-9]" . font-lock-variable-name-face) + ("\\$@" . font-lock-variable-name-face) + ("\\$\\*" . font-lock-variable-name-face) + (,(concat "\\_<\\(m4_\\)?" (regexp-opt m4--macro-list) "\\_>") + . font-lock-keyword-face))) "Default `font-lock-keywords' for M4 mode.") (defcustom m4-mode-hook nil @@ -155,22 +177,4 @@ If m4 is not in your PATH, set this to an absolute file name." ;;stuff to play with for debugging ;(char-to-string (char-syntax ?`)) -;;;how I generate the nasty looking regexps at the top -;;;(make-regexp '("builtin" "changecom" "changequote" "changeword" "debugfile" -;;; "debugmode" "decr" "define" "defn" "divert" "divnum" "dnl" -;;; "dumpdef" "errprint" "esyscmd" "eval" "file" "format" "gnu" -;;; "ifdef" "ifelse" "include" "incr" "index" "indir" "len" "line" -;;; "m4exit" "m4wrap" "maketemp" "patsubst" "popdef" "pushdef" "regexp" -;;; "shift" "sinclude" "substr" "syscmd" "sysval" "traceoff" "traceon" -;;; "translit" "undefine" "undivert" "unix")) -;;;(make-regexp '("m4_builtin" "m4_changecom" "m4_changequote" "m4_changeword" -;;; "m4_debugfile" "m4_debugmode" "m4_decr" "m4_define" "m4_defn" -;;; "m4_divert" "m4_divnum" "m4_dnl" "m4_dumpdef" "m4_errprint" -;;; "m4_esyscmd" "m4_eval" "m4_file" "m4_format" "m4_ifdef" "m4_ifelse" -;;; "m4_include" "m4_incr" "m4_index" "m4_indir" "m4_len" "m4_line" -;;; "m4_m4exit" "m4_m4wrap" "m4_maketemp" "m4_patsubst" "m4_popdef" -;;; "m4_pushdef" "m4_regexp" "m4_shift" "m4_sinclude" "m4_substr" -;;; "m4_syscmd" "m4_sysval" "m4_traceoff" "m4_traceon" "m4_translit" -;;; "m4_m4_undefine" "m4_undivert")) - ;;; m4-mode.el ends here commit c7b35ea3060b90ed68a933eed29e85dd2d567e3e Author: Stefan Monnier Date: Fri Feb 12 12:17:40 2021 -0500 * lisp/emacs-lisp/edebug.el (edebug--handle-&-spec-op) <&lookup>: New method * doc/lispref/edebug.texi (Specification List): Document it. * lisp/emacs-lisp/pcase.el (pcase-PAT): Use it. (pcase-MACRO): Remove Edebug element. (pcase--get-edebug-spec): New function. (pcase--edebug-match-macro): Remove function. diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi index 569545d83f..693d0e0630 100644 --- a/doc/lispref/edebug.texi +++ b/doc/lispref/edebug.texi @@ -1370,6 +1370,17 @@ is primarily used to generate more specific syntax error messages. See edebug-spec; it aborts the instrumentation, displaying the message in the minibuffer. +@item &lookup +Selects a specification based on the code being instrumented. +It takes the form @code{&lookup @var{spec} @var{fun} @var{args...}} +and means that Edebug will first match @var{spec} against the code and +then match the rest against the specification returned by calling +@var{fun} with the concatenation of @var{args...} and the code that +matched @code{spec}. For example @code{(&lookup symbolp +pcase--get-edebug-spec)} matches sexps whose first element is +a symbol and whose subsequent elements must obey the spec associated +with that head symbol according to @code{pcase--get-edebug-spec}. + @item @var{other-symbol} @cindex indirect specifications Any other symbol in a specification list may be a predicate or an diff --git a/etc/NEWS b/etc/NEWS index 228b773cb2..fe626fec7e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -938,14 +938,17 @@ To customize obsolete user options, use 'customize-option' or --- *** 'get-edebug-spec' is obsolete, replaced by 'edebug-get-spec'. +*** Edebug specification lists can use some new keywords: + ++++ +**** '&lookup SPEC FUN ARGS...' lets FUN compute the specs to use + +++ -*** Edebug specification lists can use the new keyword '&error', which -unconditionally aborts the current edebug instrumentation with the -supplied error message. +**** '&error MSG' unconditionally aborts the current edebug instrumentation. -*** Edebug specification lists can use the new keyword ':unique', -which appends a unique suffix to the Edebug name of the current -definition. ++++ +**** ':unique STRING' appends STRING to the Edebug name of the current +definition to (hopefully) make it more unique. ** ElDoc diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 04a4829c5e..782299454e 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -55,6 +55,7 @@ (require 'backtrace) (require 'macroexp) (require 'cl-lib) +(require 'seq) (eval-when-compile (require 'pcase)) ;;; Options @@ -1866,6 +1867,22 @@ contains a circular object." (apply #'edebug-no-match cursor "Expected one of" original-specs)) )) +(cl-defmethod edebug--handle-&-spec-op ((_ (eql &lookup)) cursor specs) + "Compute the specs for `&lookup SPEC FUN ARGS...'. +Extracts the head of the data by matching it against SPEC, +and then matches the rest against the output of (FUN ARGS... HEAD)." + (pcase-let* + ((`(,spec ,fun . ,args) specs) + (exps (edebug-cursor-expressions cursor)) + (instrumented-head (edebug-match-one-spec cursor (or spec 'sexp))) + (consumed (- (length exps) + (length (edebug-cursor-expressions cursor)))) + (newspecs (apply fun (append args (seq-subseq exps 0 consumed))))) + (cl-assert (eq (edebug-cursor-expressions cursor) (nthcdr consumed exps))) + ;; FIXME: What'd be the difference if we used `edebug-match-sublist', + ;; which is what `edebug-list-form-args' uses for the similar purpose + ;; when matching "normal" forms? + (append instrumented-head (edebug-match cursor newspecs)))) (cl-defmethod edebug--handle-&-spec-op ((_ (eql ¬)) cursor specs) ;; If any specs match, then fail diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 7a88bdf8de..d6c96c1ec8 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -62,45 +62,32 @@ (defvar pcase--dontwarn-upats '(pcase--dontcare)) -(def-edebug-spec - pcase-PAT - (&or symbolp - ("or" &rest pcase-PAT) - ("and" &rest pcase-PAT) - ("guard" form) - ("pred" pcase-FUN) - ("app" pcase-FUN pcase-PAT) - pcase-MACRO +(def-edebug-spec pcase-PAT + (&or (&lookup symbolp pcase--get-edebug-spec) sexp)) -(def-edebug-spec - pcase-FUN +(def-edebug-spec pcase-FUN (&or lambda-expr ;; Punt on macros/special forms. (functionp &rest form) sexp)) -;; See bug#24717 -(put 'pcase-MACRO 'edebug-form-spec #'pcase--edebug-match-macro) - ;; Only called from edebug. (declare-function edebug-get-spec "edebug" (symbol)) -(declare-function edebug-match "edebug" (cursor specs)) +(defun pcase--get-edebug-spec (head) + (or (alist-get head '((quote sexp) + (or &rest pcase-PAT) + (and &rest pcase-PAT) + (guard form) + (pred &or ("not" pcase-FUN) pcase-FUN) + (app pcase-FUN pcase-PAT))) + (let ((me (pcase--get-macroexpander head))) + (and me (symbolp me) (edebug-get-spec me))))) (defun pcase--get-macroexpander (s) "Return the macroexpander for pcase pattern head S, or nil" (get s 'pcase-macroexpander)) -(defun pcase--edebug-match-macro (cursor) - (let (specs) - (mapatoms - (lambda (s) - (let ((m (pcase--get-macroexpander s))) - (when (and m (edebug-get-spec m)) - (push (cons (symbol-name s) (edebug-get-spec m)) - specs))))) - (edebug-match cursor (cons '&or specs)))) - ;;;###autoload (defmacro pcase (exp &rest cases) ;; FIXME: Add some "global pattern" to wrap every case? @@ -938,8 +925,7 @@ Otherwise, it defers to REST which is a list of branches of the form (t (error "Unknown pattern `%S'" upat))))) (t (error "Incorrect MATCH %S" (car matches))))) -(def-edebug-spec - pcase-QPAT +(def-edebug-spec pcase-QPAT ;; Cf. edebug spec for `backquote-form' in edebug.el. (&or ("," pcase-PAT) (pcase-QPAT [&rest [¬ ","] pcase-QPAT] commit 6ae731e04f261b9139fbe3573822a381dc3577d3 Author: Stefan Monnier Date: Fri Feb 12 11:37:49 2021 -0500 * lisp/emacs-lisp/cl-macs.el (cl-flet): Fix edebug spec diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index c2bf02ccec..c312afe55b 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -2016,7 +2016,7 @@ info node `(cl) Function Bindings' for details. \(fn ((FUNC ARGLIST BODY...) ...) FORM...)" (declare (indent 1) - (debug ((&rest [&or (&define name :unique "cl-flet@" function-form) + (debug ((&rest [&or (&define name :unique "cl-flet@" form) (&define name :unique "cl-flet@" cl-lambda-list cl-declarations-or-string commit 1d2487b1fc5f0648deb80507be8c713d4482fd8d Author: Stefan Monnier Date: Fri Feb 12 11:12:49 2021 -0500 * lisp/emacs-lisp/edebug.el: Misc cleanups. Move all definitions under the `edebug-` prefix. (edebug-get-spec): Rename from `get-edebug-spec`. (edebug-move-cursor): Use `cl-callf`. (edebug-spec-p): Remove unused function. (def-edebug-spec, edebug-spec-list, edebug-spec): Remove unused specs (nothing in there gets instrumented anyway). (edebug-tracing): Use `declare`. (edebug-cancel-on-entry): Rename from `cancel-edebug-on-entry`. (edebug-global-prefix): Rename from `global-edebug-prefix`. (edebug-global-map): Rename from `global-edebug-map`. * lisp/emacs-lisp/pcase.el (pcase-PAT): Remove `let`. (let): Use `declare` instead. (pcase--edebug-match-macro): Use new name `edebug-get-spec`. diff --git a/etc/NEWS b/etc/NEWS index 9a9c75f0f8..228b773cb2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -935,6 +935,9 @@ To customize obsolete user options, use 'customize-option' or ** Edebug +--- +*** 'get-edebug-spec' is obsolete, replaced by 'edebug-get-spec'. + +++ *** Edebug specification lists can use the new keyword '&error', which unconditionally aborts the current edebug instrumentation with the diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 0733dcec27..04a4829c5e 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -244,19 +244,22 @@ If the result is non-nil, then break. Errors are ignored." ;;; Form spec utilities. -(defun get-edebug-spec (symbol) +(defun edebug-get-spec (symbol) + "Return the Edebug spec of a given Lisp expression's head SYMBOL. +The argument is usually a symbol, but it doesn't have to be." ;; Get the spec of symbol resolving all indirection. (let ((spec nil) (indirect symbol)) (while - (progn - (and (symbolp indirect) - (setq indirect - (function-get indirect 'edebug-form-spec 'macro)))) + (and (symbolp indirect) + (setq indirect + (function-get indirect 'edebug-form-spec 'macro))) ;; (edebug-trace "indirection: %s" edebug-form-spec) (setq spec indirect)) spec)) +(define-obsolete-function-alias 'get-edebug-spec #'edebug-get-spec "28.1") + ;;;###autoload (defun edebug-basic-spec (spec) "Return t if SPEC uses only extant spec symbols. @@ -961,6 +964,18 @@ circular objects. Let `read' read everything else." ;;; Cursors for traversal of list and vector elements with offsets. +;; Edebug's instrumentation is based on parsing the sexps, which come with +;; auxiliary position information. Instead of keeping the position +;; information together with the sexps, it is kept in a "parallel +;; tree" of offsets. +;; +;; An "edebug cursor" is a pair of a *list of sexps* (called the +;; "expressions") together with a matching list of offsets. +;; When we're parsing the content of a list, the +;; `edebug-cursor-expressions' is simply the list but when parsing +;; a vector, the `edebug-cursor-expressions' is a list formed of the +;; elements of the vector. + (defvar edebug-dotted-spec nil "Set to t when matching after the dot in a dotted spec list.") @@ -1015,8 +1030,8 @@ circular objects. Let `read' read everything else." ;; The following test should always fail. (if (edebug-empty-cursor cursor) (edebug-no-match cursor "Not enough arguments.")) - (setcar cursor (cdr (car cursor))) - (setcdr cursor (cdr (cdr cursor))) + (cl-callf cdr (car cursor)) + (cl-callf cdr (cdr cursor)) cursor) @@ -1153,7 +1168,7 @@ purpose by adding an entry to this alist, and setting (eq 'symbol (progn (forward-char 1) (edebug-next-token-class)))) ;; Find out if this is a defining form from first symbol (setq def-kind (read (current-buffer)) - spec (and (symbolp def-kind) (get-edebug-spec def-kind)) + spec (and (symbolp def-kind) (edebug-get-spec def-kind)) defining-form-p (and (listp spec) (eq '&define (car spec))) ;; This is incorrect in general!! But OK most of the time. @@ -1502,7 +1517,7 @@ contains a circular object." (if (eq 'quote (car form)) form (let* ((head (car form)) - (spec (and (symbolp head) (get-edebug-spec head))) + (spec (and (symbolp head) (edebug-get-spec head))) (new-cursor (edebug-new-cursor form offset))) ;; Find out if this is a defining form from first symbol. ;; An indirect spec would not work here, yet. @@ -1542,7 +1557,7 @@ contains a circular object." (defsubst edebug-list-form-args (head cursor) ;; Process the arguments of a list form given that head of form is a symbol. ;; Helper for edebug-list-form - (let ((spec (get-edebug-spec head))) + (let ((spec (edebug-get-spec head))) (cond ;; Treat cl-macrolet bindings like macros with no spec. ((member head edebug--cl-macrolet-defs) @@ -1645,7 +1660,7 @@ contains a circular object." edebug-error-point (edebug-gate edebug-gate) ;; locally bound to limit effect ) - (edebug-match-specs cursor specs 'edebug-match-specs))) + (edebug-match-specs cursor specs #'edebug-match-specs))) (defun edebug-match-one-spec (cursor spec) @@ -1741,11 +1756,16 @@ contains a circular object." (gate . edebug-match-gate) ;; (nil . edebug-match-nil) not this one - special case it. )) + ;; FIXME: We abuse `edebug-form-spec' here. It's normally used to store the + ;; specs for a given sexp's head, but here we use it to keep the + ;; function implementing of a given "core spec". (put (car pair) 'edebug-form-spec (cdr pair))) (defun edebug-match-symbol (cursor symbol) ;; Match a symbol spec. - (let* ((spec (get-edebug-spec symbol))) + ;; FIXME: We abuse `edebug-get-spec' here, passing it a *spec* rather than + ;; the head element of a source sexp. + (let* ((spec (edebug-get-spec symbol))) (cond (spec (if (consp spec) @@ -2000,7 +2020,7 @@ contains a circular object." cursor "Expected lambda expression")) (offset (edebug-top-offset cursor)) (head (and (consp sexp) (car sexp))) - (spec (and (symbolp head) (get-edebug-spec head))) + (spec (and (symbolp head) (edebug-get-spec head))) (edebug-inside-func nil)) ;; Find out if this is a defining form from first symbol. (if (and (consp spec) (eq '&define (car spec))) @@ -2145,37 +2165,6 @@ into `edebug--cl-macrolet-defs' which is checked in `edebug-list-form-args'." ;;;; Edebug Form Specs ;;; ========================================================== -;;;;* Spec for def-edebug-spec -;;; Out of date. - -(defun edebug-spec-p (object) - "Return non-nil if OBJECT is a symbol with an edebug-form-spec property." - (and (symbolp object) - (get object 'edebug-form-spec))) - -(def-edebug-spec def-edebug-spec - ;; Top level is different from lower levels. - (&define :name edebug-spec name - &or "nil" edebug-spec-p "t" "0" (&rest edebug-spec))) - -(def-edebug-spec edebug-spec-list - ;; A list must have something in it, or it is nil, a symbolp - ((edebug-spec . [&or nil edebug-spec]))) - -(def-edebug-spec edebug-spec - (&or - edebug-spec-list - (vector &rest edebug-spec) ; matches a vector - ("vector" &rest edebug-spec) ; matches a vector spec - ("quote" symbolp) - stringp - [edebug-lambda-list-keywordp &rest edebug-spec] - [keywordp gate edebug-spec] - edebug-spec-p ;; Including all the special ones e.g. form. - symbolp;; a predicate - )) - - ;;;* Emacs special forms and some functions. ;; quote expects only one argument, although it allows any number. @@ -2485,11 +2474,10 @@ STATUS should be a list returned by `edebug-var-status'." (edebug-print-trace-after (format "%s result: %s" function edebug-result))))) -(def-edebug-spec edebug-tracing (form body)) - (defmacro edebug-tracing (msg &rest body) "Print MSG in *edebug-trace* before and after evaluating BODY. The result of BODY is also printed." + (declare (debug (form body))) `(let ((edebug-stack-depth (1+ edebug-stack-depth)) edebug-result) (edebug-print-trace-before ,msg) @@ -3601,7 +3589,10 @@ canceled the first time the function is entered." ;; Could store this in the edebug data instead. (put function 'edebug-on-entry (if flag 'temp t))) -(defalias 'edebug-cancel-edebug-on-entry #'cancel-edebug-on-entry) +(define-obsolete-function-alias 'edebug-cancel-edebug-on-entry + #'edebug-cancel-on-entry "28.1") +(define-obsolete-function-alias 'cancel-edebug-on-entry + #'edebug-cancel-on-entry "28.1") (defun edebug--edebug-on-entry-functions () (let ((functions nil)) @@ -3613,7 +3604,7 @@ canceled the first time the function is entered." obarray) functions)) -(defun cancel-edebug-on-entry (function) +(defun edebug-cancel-on-entry (function) "Cause Edebug to not stop when FUNCTION is called. The removes the effect of `edebug-on-entry'. If FUNCTION is is nil, remove `edebug-on-entry' on all functions." @@ -3937,10 +3928,14 @@ be installed in `emacs-lisp-mode-map'.") ;; Autoloading these global bindings doesn't make sense because ;; they cannot be used anyway unless Edebug is already loaded and active. -(defvar global-edebug-prefix "\^XX" +(define-obsolete-variable-alias 'global-edebug-prefix + 'edebug-global-prefix "28.1") +(defvar edebug-global-prefix "\^XX" "Prefix key for global edebug commands, available from any buffer.") -(defvar global-edebug-map +(define-obsolete-variable-alias 'global-edebug-map + 'edebug-global-map "28.1") +(defvar edebug-global-map (let ((map (make-sparse-keymap))) (define-key map " " 'edebug-step-mode) @@ -3973,9 +3968,9 @@ be installed in `emacs-lisp-mode-map'.") map) "Global map of edebug commands, available from any buffer.") -(when global-edebug-prefix - (global-unset-key global-edebug-prefix) - (global-set-key global-edebug-prefix global-edebug-map)) +(when edebug-global-prefix + (global-unset-key edebug-global-prefix) + (global-set-key edebug-global-prefix edebug-global-map)) (defun edebug-help () diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index ec746fa474..7a88bdf8de 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -27,19 +27,10 @@ ;; Todo: -;; - (pcase e (`(,x . ,x) foo)) signals an "x unused" warning if `foo' doesn't -;; use x, because x is bound separately for the equality constraint -;; (as well as any pred/guard) and for the body, so uses at one place don't -;; count for the other. -;; - provide ways to extend the set of primitives, with some kind of -;; define-pcase-matcher. We could easily make it so that (guard BOOLEXP) -;; could be defined this way, as a shorthand for (pred (lambda (_) BOOLEXP)). -;; But better would be if we could define new ways to match by having the -;; extension provide its own `pcase--split-' thingy. -;; - along these lines, provide patterns to match CL structs. +;; - Allow to provide new `pcase--split-' thingy. ;; - provide something like (setq VAR) so a var can be set rather than ;; let-bound. -;; - provide a way to fallthrough to subsequent cases +;; - provide a way to continue matching to subsequent cases ;; (e.g. Like Racket's (=> ID). ;; - try and be more clever to reduce the size of the decision tree, and ;; to reduce the number of leaves that need to be turned into functions: @@ -77,7 +68,6 @@ ("or" &rest pcase-PAT) ("and" &rest pcase-PAT) ("guard" form) - ("let" pcase-PAT form) ("pred" pcase-FUN) ("app" pcase-FUN pcase-PAT) pcase-MACRO @@ -91,10 +81,10 @@ sexp)) ;; See bug#24717 -(put 'pcase-MACRO 'edebug-form-spec 'pcase--edebug-match-macro) +(put 'pcase-MACRO 'edebug-form-spec #'pcase--edebug-match-macro) ;; Only called from edebug. -(declare-function get-edebug-spec "edebug" (symbol)) +(declare-function edebug-get-spec "edebug" (symbol)) (declare-function edebug-match "edebug" (cursor specs)) (defun pcase--get-macroexpander (s) @@ -106,13 +96,15 @@ (mapatoms (lambda (s) (let ((m (pcase--get-macroexpander s))) - (when (and m (get-edebug-spec m)) - (push (cons (symbol-name s) (get-edebug-spec m)) + (when (and m (edebug-get-spec m)) + (push (cons (symbol-name s) (edebug-get-spec m)) specs))))) (edebug-match cursor (cons '&or specs)))) ;;;###autoload (defmacro pcase (exp &rest cases) + ;; FIXME: Add some "global pattern" to wrap every case? + ;; Could be used to wrap all cases in a ` "Evaluate EXP to get EXPVAL; try passing control to one of CASES. CASES is a list of elements of the form (PATTERN CODE...). For the first CASE whose PATTERN \"matches\" EXPVAL, @@ -1002,7 +994,13 @@ The predicate is the logical-AND of: (pcase-defmacro let (pat expr) "Matches if EXPR matches PAT." + (declare (debug (pcase-PAT form))) `(app (lambda (_) ,expr) ,pat)) +;; (pcase-defmacro guard (expr) +;; "Matches if EXPR is non-nil." +;; (declare (debug (form))) +;; `(pred (lambda (_) ,expr))) + (provide 'pcase) ;;; pcase.el ends here commit db237850abc240e2c3e765e9cc7e15ee5681dcaf Author: Robert Pluim Date: Fri Feb 12 11:43:02 2021 +0100 Remove Motif support * configure.ac: Remove support for configuring --with-x-toolkit=motif * etc/NEWS: Mention removal of Motif support. diff --git a/configure.ac b/configure.ac index 08f3c0cd85..12cf36303b 100644 --- a/configure.ac +++ b/configure.ac @@ -409,19 +409,18 @@ dnl This should be the last --with option, because --with-x is dnl added later on when we find the file name of X, and it's best to dnl keep them together visually. AC_ARG_WITH([x-toolkit],[AS_HELP_STRING([--with-x-toolkit=KIT], - [use an X toolkit (KIT one of: yes or gtk, gtk2, gtk3, lucid or athena, motif, no)])], + [use an X toolkit (KIT one of: yes or gtk, gtk2, gtk3, lucid or athena, no)])], [ case "${withval}" in y | ye | yes ) val=gtk ;; n | no ) val=no ;; l | lu | luc | luci | lucid ) val=lucid ;; a | at | ath | athe | athen | athena ) val=athena ;; - m | mo | mot | moti | motif ) val=motif ;; g | gt | gtk ) val=gtk ;; gtk2 ) val=gtk2 ;; gtk3 ) val=gtk3 ;; * ) AC_MSG_ERROR(['--with-x-toolkit=$withval' is invalid; -this option's value should be 'yes', 'no', 'lucid', 'athena', 'motif', 'gtk', +this option's value should be 'yes', 'no', 'lucid', 'athena', 'gtk', 'gtk2' or 'gtk3'. 'yes' and 'gtk' are synonyms. 'athena' and 'lucid' are synonyms.]) ;; @@ -460,7 +459,7 @@ OPTION_DEFAULT_ON([harfbuzz],[don't use HarfBuzz for text shaping]) OPTION_DEFAULT_ON([libotf],[don't use libotf for OpenType font support]) OPTION_DEFAULT_ON([m17n-flt],[don't use m17n-flt for text shaping]) -OPTION_DEFAULT_ON([toolkit-scroll-bars],[don't use Motif/Xaw3d/GTK toolkit scroll bars]) +OPTION_DEFAULT_ON([toolkit-scroll-bars],[don't use Xaw3d/GTK toolkit scroll bars]) OPTION_DEFAULT_ON([xaw3d],[don't use Xaw3d]) OPTION_DEFAULT_ON([xim],[at runtime, default X11 XIM to off]) OPTION_DEFAULT_ON([xdbe],[don't use X11 double buffering support]) @@ -2252,7 +2251,7 @@ if test "$window_system" = none && test "X$with_x" != "Xno"; then then AC_MSG_ERROR([You seem to be running X, but no X development libraries were found. You should install the relevant development files for X -and for the toolkit you want, such as Gtk+ or Motif. Also make +and for the toolkit you want, such as Gtk+. Also make sure you have development files for image handling, i.e. tiff, gif, jpeg, png and xpm. If you are sure you want Emacs compiled without X window support, pass diff --git a/etc/NEWS b/etc/NEWS index 2f15f078a7..9a9c75f0f8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -24,6 +24,9 @@ applies, and please also update docstrings as needed. * Installation Changes in Emacs 28.1 +-- +** Support for building with Motif has been removed. + ** Cairo graphics library is now used by default if found. '--with-cairo' is now the default, if the appropriate development files are found by 'configure'. Note that building with Cairo means using commit 6a2cdc67fa7607d5f77aee053a62773533cd5e7b Author: Lars Ingebrigtsen Date: Fri Feb 12 14:19:50 2021 +0100 Allow minor modes to specify major modes they're useful in diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index ce7727b87e..3c64e97b3b 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -1730,6 +1730,11 @@ and @var{set} is a function of one argument (a state) that sets it. @item :after-hook @var{after-hook} This defines a single Lisp form which is evaluated after the mode hooks have run. It should not be quoted. + +@item :interactive @var{value} +Minor modes are interactive commands by default. If @var{value} is +@code{nil}, this is inhibited. If @var{value} is a list of symbols, +it's used to say which major modes this minor mode is useful in. @end table Any other keyword arguments are passed directly to the commit da64a257a482e95a3a314da97260ea08635a83e0 Author: Eli Zaretskii Date: Fri Feb 12 09:25:13 2021 +0200 ; * CONTRIBUTE: Yet another clarification of significant changes. diff --git a/CONTRIBUTE b/CONTRIBUTE index 9f0d9e7e16..b7d72f9965 100644 --- a/CONTRIBUTE +++ b/CONTRIBUTE @@ -66,12 +66,15 @@ more reliably, and makes the job of applying the patches easier and less error-prone. It also allows sending patches whose author is someone other than the email sender. -Once the cumulative amount of your submissions exceeds about 15 lines -of non-trivial code you added or changed (not counting deleted lines), -we will need you to assign to the FSF the copyright for your -contributions. Ask on emacs-devel@gnu.org, and we will send you the -necessary form together with the instructions to fill and email it, in -order to start this legal paperwork. +Once the cumulative amount of your submissions exceeds about 10 lines +of non-trivial changes, we will need you to assign to the FSF the +copyright for your contributions. (To see how many lines were +non-trivially changed, count only added and modified lines in the +patched code. Consider an added or changed line non-trivial if it +includes at least one identifier, string, or substantial comment.) +Ask on emacs-devel@gnu.org, and we will send you the necessary form +together with the instructions to fill and email it, in order to start +this legal paperwork. ** Issue tracker (a.k.a. "bug tracker") commit 3a4b65177f0c26f342e657636ce62e8c16cbb14b Author: Stefan Monnier Date: Thu Feb 11 19:06:30 2021 -0500 * lisp/emacs-lisp/gv.el (gv-place): Simplify diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el index 29f8230e6b..c160aa1fd3 100644 --- a/lisp/emacs-lisp/gv.el +++ b/lisp/emacs-lisp/gv.el @@ -307,7 +307,7 @@ The return value is the last VAL in the list. ;; Autoload this `put' since a user might use C-u C-M-x on an expression ;; containing a non-trivial `push' even before gv.el was loaded. ;;;###autoload -(put 'gv-place 'edebug-form-spec 'edebug-match-form) +(put 'gv-place 'edebug-form-spec '(form)) ;So-called "indirect spec". ;; CL did the equivalent of: ;;(gv-define-macroexpand edebug-after (lambda (before index place) place)) commit c55f4055dd28452996d828ee1a65b29c1ddce4c8 Author: Stefan Monnier Date: Thu Feb 11 19:00:53 2021 -0500 * lisp/cedet/semantic/symref/: Use lexical-binding * lisp/cedet/semantic/symref/cscope.el: * lisp/cedet/semantic/symref/filter.el: * lisp/cedet/semantic/symref/global.el: * lisp/cedet/semantic/symref/grep.el: * lisp/cedet/semantic/symref/idutils.el: * lisp/cedet/semantic/symref/list.el: Use lexical-binding. diff --git a/lisp/cedet/semantic/symref/cscope.el b/lisp/cedet/semantic/symref/cscope.el index 3686e51946..e63b7a7e91 100644 --- a/lisp/cedet/semantic/symref/cscope.el +++ b/lisp/cedet/semantic/symref/cscope.el @@ -1,6 +1,6 @@ -;;; semantic/symref/cscope.el --- Semantic-symref support via cscope. +;;; semantic/symref/cscope.el --- Semantic-symref support via cscope -*- lexical-binding: t; -*- -;;; Copyright (C) 2009-2021 Free Software Foundation, Inc. +;; Copyright (C) 2009-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam diff --git a/lisp/cedet/semantic/symref/filter.el b/lisp/cedet/semantic/symref/filter.el index a40ce13f3d..7ef3cd90d6 100644 --- a/lisp/cedet/semantic/symref/filter.el +++ b/lisp/cedet/semantic/symref/filter.el @@ -1,4 +1,4 @@ -;;; semantic/symref/filter.el --- Filter symbol reference hits for accuracy. +;;; semantic/symref/filter.el --- Filter symbol reference hits for accuracy -*- lexical-binding: t; -*- ;; Copyright (C) 2009-2021 Free Software Foundation, Inc. @@ -48,7 +48,7 @@ "Determine if the tag TARGET is used at POSITION in the current buffer. Return non-nil for a match." (semantic-analyze-current-symbol - (lambda (start end prefix) + (lambda (_start _end prefix) (let ((tag (car (nreverse prefix)))) (and (semantic-tag-p tag) (semantic-equivalent-tag-p target tag)))) @@ -97,7 +97,7 @@ tag that contains point, and return that." (Lcount 0)) (when (semantic-tag-p target) (semantic-symref-hits-in-region - target (lambda (start end prefix) (setq Lcount (1+ Lcount))) + target (lambda (_start _end _prefix) (setq Lcount (1+ Lcount))) (semantic-tag-start tag) (semantic-tag-end tag)) (when (called-interactively-p 'interactive) @@ -106,6 +106,8 @@ tag that contains point, and return that." (semantic-elapsed-time start nil))) Lcount))) +(defvar srecode-field-archive) + (defun semantic-symref-rename-local-variable () "Fancy way to rename the local variable under point. Depends on the SRecode Field editing API." @@ -140,7 +142,7 @@ Depends on the SRecode Field editing API." (region nil) ) (semantic-symref-hits-in-region - target (lambda (start end prefix) + target (lambda (start end _prefix) ;; For every valid hit, create one field. (srecode-field "LOCAL" :name "LOCAL" :start start :end end)) (semantic-tag-start tag) (semantic-tag-end tag)) diff --git a/lisp/cedet/semantic/symref/global.el b/lisp/cedet/semantic/symref/global.el index 7f63e4ddbc..23e40349a6 100644 --- a/lisp/cedet/semantic/symref/global.el +++ b/lisp/cedet/semantic/symref/global.el @@ -1,4 +1,4 @@ -;;; semantic/symref/global.el --- Use GNU Global for symbol references +;;; semantic/symref/global.el --- Use GNU Global for symbol references -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/semantic/symref/grep.el b/lisp/cedet/semantic/symref/grep.el index 9f0ac38ec7..46027f1f91 100644 --- a/lisp/cedet/semantic/symref/grep.el +++ b/lisp/cedet/semantic/symref/grep.el @@ -1,4 +1,4 @@ -;;; semantic/symref/grep.el --- Symref implementation using find/grep +;;; semantic/symref/grep.el --- Symref implementation using find/grep -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/semantic/symref/idutils.el b/lisp/cedet/semantic/symref/idutils.el index 4a41355dd6..3e3e3b0a94 100644 --- a/lisp/cedet/semantic/symref/idutils.el +++ b/lisp/cedet/semantic/symref/idutils.el @@ -1,6 +1,6 @@ -;;; semantic/symref/idutils.el --- Symref implementation for idutils +;;; semantic/symref/idutils.el --- Symref implementation for idutils -*- lexical-binding: t; -*- -;;; Copyright (C) 2009-2021 Free Software Foundation, Inc. +;; Copyright (C) 2009-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam diff --git a/lisp/cedet/semantic/symref/list.el b/lisp/cedet/semantic/symref/list.el index 7d3a5ddc2d..50d2e2b1c3 100644 --- a/lisp/cedet/semantic/symref/list.el +++ b/lisp/cedet/semantic/symref/list.el @@ -1,4 +1,4 @@ -;;; semantic/symref/list.el --- Symref Output List UI. +;;; semantic/symref/list.el --- Symref Output List UI -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. commit 9451ea0a05612ec95a01c8c0b28d851176ed8b43 Author: Stefan Monnier Date: Thu Feb 11 18:54:12 2021 -0500 * lisp/cedet/semantic/decorate/: Use lexical-binding in all files * lisp/cedet/semantic/decorate/include.el (semantic-decoration-fileless-include-describe): Remove unused var `mm`. * lisp/cedet/semantic/decorate/mode.el: Use lexical-binding. diff --git a/lisp/cedet/semantic/decorate/include.el b/lisp/cedet/semantic/decorate/include.el index ee7fad1fc5..851a2c46a9 100644 --- a/lisp/cedet/semantic/decorate/include.el +++ b/lisp/cedet/semantic/decorate/include.el @@ -1,4 +1,4 @@ -;;; semantic/decorate/include.el --- Decoration modes for include statements +;;; semantic/decorate/include.el --- Decoration modes for include statements -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -535,7 +535,7 @@ Argument EVENT is the mouse clicked event." (interactive) (let* ((tag (semantic-current-tag)) (table (semanticdb-find-table-for-include tag (current-buffer))) - (mm major-mode)) + ) ;; (mm major-mode) (with-output-to-temp-buffer (help-buffer) ; "*Help*" (help-setup-xref (list #'semantic-decoration-fileless-include-describe) (called-interactively-p 'interactive)) @@ -793,7 +793,7 @@ any decorated referring includes.") (let ((table (oref obj table))) ;; This is a hack. Add in something better? (semanticdb-notify-references - table (lambda (tab me) + table (lambda (tab _me) (semantic-decoration-unparsed-include-refrence-reset tab) )) )) @@ -805,7 +805,7 @@ any decorated referring includes.") (semantic-reset cache))) (cl-defmethod semanticdb-synchronize ((cache semantic-decoration-unparsed-include-cache) - new-tags) + _new-tags) "Synchronize a CACHE with some NEW-TAGS." (semantic-reset cache)) diff --git a/lisp/cedet/semantic/decorate/mode.el b/lisp/cedet/semantic/decorate/mode.el index 884b066d77..89cc9304d4 100644 --- a/lisp/cedet/semantic/decorate/mode.el +++ b/lisp/cedet/semantic/decorate/mode.el @@ -1,4 +1,4 @@ -;;; semantic/decorate/mode.el --- Minor mode for decorating tags +;;; semantic/decorate/mode.el --- Minor mode for decorating tags -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2005, 2007-2021 Free Software Foundation, Inc. @@ -358,12 +358,12 @@ Return non-nil if the decoration style is enabled." :selected `(semantic-decoration-style-enabled-p ,(car style)) )) -(defun semantic-build-decoration-mode-menu (&rest ignore) +(defun semantic-build-decoration-mode-menu (&rest _ignore) "Create a menu listing all the known decorations for toggling. IGNORE any input arguments." (or semantic-decoration-menu-cache (setq semantic-decoration-menu-cache - (mapcar 'semantic-decoration-build-style-menu + (mapcar #'semantic-decoration-build-style-menu (reverse semantic-decoration-styles)) ))) commit 203e61ff837128b397eb313a5bb1b703f0eae0ec Author: Alan Mackenzie Date: Thu Feb 11 21:37:45 2021 +0000 Make recursive minibuffers and recursive edits work together * lisp/minibuffer.el (exit-minibuffer): When in a minibuffer, throw an error should the command loop nesting level be wrong. * src/lisp.h (minibuffer_quit_level): declare as an extern. (command_loop_level): Move definition from src/window.h * src/window.h (command_loop_level): move definition to src/lisp.h. * src/eval.c (minibuffer_quit_level): Move this variable to file level from being a static inside internal_catch. (internal_catch): Simplify the logic. * src/minibuf.c (Vcommand_loop_level_list): New variable. (move_minibuffer_onto_frame): Set the major mode of *Minibuf-0*. (Fminibuffer_innermost_command_loop_p): New primitive. (Fabort_minibuffers): Check the command loop level before throwing t to 'exit, and set minibuffer_quit_level too. (read_minibuf): New variable calling_window. Before stacking up minibuffers on the current mini-window, check that the mini-window is not the current one. Do not call choose_minibuf_frame from read_minibuf's unwinding process. Bind calling_frame and calling_window over the recursive edit. Set the new minibuffer's major mode directly. Remove the switching away from the minibuffer after the recursive edit. (get_minibuffer): Record the command loop level in new variable Vcommand_loop_level_list. No longer set the major mode of a returned minibuffer. (minibuf_c_loop_level): New function. (read_minibuf_unwind): New variables calling_frame, calling_window are unbound from the binding stack. Remove old variable `window', which could not be set reliably to the expired mini-window. The expired minibuffer is determined as the nth in the list, rather than the contents of the current or previous mini-window. Switch the current window away from the mini-window here (moved from read_minibuf). diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index a899a943d4..aacb8ab00b 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -2116,18 +2116,19 @@ variables.") (defun exit-minibuffer () "Terminate this minibuffer argument." (interactive) - (when (or - (innermost-minibuffer-p) - (not (minibufferp))) + (when (minibufferp) + (when (not (minibuffer-innermost-command-loop-p)) + (error "%s" "Not in most nested command loop")) + (when (not (innermost-minibuffer-p)) + (error "%s" "Not in most nested minibuffer"))) ;; If the command that uses this has made modifications in the minibuffer, ;; we don't want them to cause deactivation of the mark in the original ;; buffer. ;; A better solution would be to make deactivate-mark buffer-local ;; (or to turn it into a list of buffers, ...), but in the mean time, ;; this should do the trick in most cases. - (setq deactivate-mark nil) - (throw 'exit nil)) - (error "%s" "Not in most nested minibuffer")) + (setq deactivate-mark nil) + (throw 'exit nil)) (defun self-insert-and-exit () "Terminate minibuffer input." diff --git a/src/eval.c b/src/eval.c index 3aff3b56d5..91fc4e6837 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1165,21 +1165,23 @@ usage: (catch TAG BODY...) */) FUNC should return a Lisp_Object. This is how catches are done from within C code. */ +/* MINIBUFFER_QUIT_LEVEL is to handle quitting from nested minibuffers by + throwing t to tag `exit'. + 0 means there is no (throw 'exit t) in progress, or it wasn't from + a minibuffer which isn't the most nested; + N > 0 means the `throw' was done from the minibuffer at level N which + wasn't the most nested. */ +EMACS_INT minibuffer_quit_level = 0; + Lisp_Object internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) { - /* MINIBUFFER_QUIT_LEVEL is to handle quitting from nested minibuffers by - throwing t to tag `exit'. - Value -1 means there is no (throw 'exit t) in progress; - 0 means the `throw' wasn't done from an active minibuffer; - N > 0 means the `throw' was done from the minibuffer at level N. */ - static EMACS_INT minibuffer_quit_level = -1; /* This structure is made part of the chain `catchlist'. */ struct handler *c = push_handler (tag, CATCHER); if (EQ (tag, Qexit)) - minibuffer_quit_level = -1; + minibuffer_quit_level = 0; /* Call FUNC. */ if (! sys_setjmp (c->jmp)) @@ -1194,22 +1196,16 @@ internal_catch (Lisp_Object tag, Lisp_Object val = handlerlist->val; clobbered_eassert (handlerlist == c); handlerlist = handlerlist->next; - if (EQ (tag, Qexit) && EQ (val, Qt)) + if (EQ (tag, Qexit) && EQ (val, Qt) && minibuffer_quit_level > 0) /* If we've thrown t to tag `exit' from within a minibuffer, we exit all minibuffers more deeply nested than the current one. */ { - EMACS_INT mini_depth = this_minibuffer_depth (Qnil); - if (mini_depth && mini_depth != minibuffer_quit_level) - { - if (minibuffer_quit_level == -1) - minibuffer_quit_level = mini_depth; - if (minibuffer_quit_level - && (minibuf_level > minibuffer_quit_level)) - Fthrow (Qexit, Qt); - } + if (minibuf_level > minibuffer_quit_level + && !NILP (Fminibuffer_innermost_command_loop_p (Qnil))) + Fthrow (Qexit, Qt); else - minibuffer_quit_level = -1; + minibuffer_quit_level = 0; } return val; } diff --git a/src/lisp.h b/src/lisp.h index 409a1e7060..0847324d1f 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4091,6 +4091,7 @@ intern_c_string (const char *str) } /* Defined in eval.c. */ +extern EMACS_INT minibuffer_quit_level; extern Lisp_Object Vautoload_queue; extern Lisp_Object Vrun_hooks; extern Lisp_Object Vsignaling_function; @@ -4369,6 +4370,7 @@ extern void syms_of_casetab (void); /* Defined in keyboard.c. */ +extern EMACS_INT command_loop_level; extern Lisp_Object echo_message_buffer; extern struct kboard *echo_kboard; extern void cancel_echoing (void); diff --git a/src/minibuf.c b/src/minibuf.c index 949c3d989d..4b1f4b1ff7 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -41,6 +41,7 @@ along with GNU Emacs. If not, see . */ minibuffer recursions are encountered. */ Lisp_Object Vminibuffer_list; +Lisp_Object Vcommand_loop_level_list; /* Data to remember during recursive minibuffer invocations. */ @@ -64,6 +65,8 @@ static Lisp_Object minibuf_prompt; static ptrdiff_t minibuf_prompt_width; static Lisp_Object nth_minibuffer (EMACS_INT depth); +static EMACS_INT minibuf_c_loop_level (EMACS_INT depth); +static void set_minibuffer_mode (Lisp_Object buf, EMACS_INT depth); /* Return TRUE when a frame switch causes a minibuffer on the old @@ -181,7 +184,12 @@ void move_minibuffer_onto_frame (void) set_window_buffer (sf->minibuffer_window, nth_minibuffer (i), 0, 0); minibuf_window = sf->minibuffer_window; if (of != sf) - set_window_buffer (of->minibuffer_window, get_minibuffer (0), 0, 0); + { + Lisp_Object temp = get_minibuffer (0); + + set_window_buffer (of->minibuffer_window, temp, 0, 0); + set_minibuffer_mode (temp, 0); + } } } @@ -389,6 +397,21 @@ No argument or nil as argument means use the current buffer as BUFFER. */) : Qnil; } +DEFUN ("minibuffer-innermost-command-loop-p", Fminibuffer_innermost_command_loop_p, + Sminibuffer_innermost_command_loop_p, 0, 1, 0, + doc: /* Return t if BUFFER is a minibuffer at the current command loop level. +No argument or nil as argument means use the current buffer as BUFFER. */) + (Lisp_Object buffer) +{ + EMACS_INT depth; + if (NILP (buffer)) + buffer = Fcurrent_buffer (); + depth = this_minibuffer_depth (buffer); + return depth && minibuf_c_loop_level (depth) == command_loop_level + ? Qt + : Qnil; +} + /* Return the nesting depth of the active minibuffer BUFFER, or 0 if BUFFER isn't such a thing. If BUFFER is nil, this means use the current buffer. */ @@ -420,12 +443,17 @@ confirm the aborting of the current minibuffer and all contained ones. */) if (!minibuf_depth) error ("Not in a minibuffer"); + if (NILP (Fminibuffer_innermost_command_loop_p (Qnil))) + error ("Not in most nested command loop"); if (minibuf_depth < minibuf_level) { array[0] = fmt; array[1] = make_fixnum (minibuf_level - minibuf_depth + 1); if (!NILP (Fyes_or_no_p (Fformat (2, array)))) - Fthrow (Qexit, Qt); + { + minibuffer_quit_level = minibuf_depth; + Fthrow (Qexit, Qt); + } } else Fthrow (Qexit, Qt); @@ -508,6 +536,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, ptrdiff_t count = SPECPDL_INDEX (); Lisp_Object mini_frame, ambient_dir, minibuffer, input_method; Lisp_Object calling_frame = selected_frame; + Lisp_Object calling_window = selected_window; Lisp_Object enable_multibyte; EMACS_INT pos = 0; /* String to add to the history. */ @@ -598,7 +627,8 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, if (minibuf_level > 1 && minibuf_moves_frame_when_opened () - && !minibuf_follows_frame ()) + && (!minibuf_follows_frame () + || (!EQ (mini_frame, selected_frame)))) { EMACS_INT i; @@ -607,8 +637,6 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, set_window_buffer (minibuf_window, nth_minibuffer (i), 0, 0); } - record_unwind_protect_void (choose_minibuf_frame); - record_unwind_protect (restore_window_configuration, Fcons (Qt, Fcurrent_window_configuration (Qnil))); @@ -640,7 +668,9 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, minibuf_save_list = Fcons (Voverriding_local_map, Fcons (minibuf_window, - minibuf_save_list)); + Fcons (calling_frame, + Fcons (calling_window, + minibuf_save_list)))); minibuf_save_list = Fcons (minibuf_prompt, Fcons (make_fixnum (minibuf_prompt_width), @@ -694,6 +724,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, /* Switch to the minibuffer. */ minibuffer = get_minibuffer (minibuf_level); + set_minibuffer_mode (minibuffer, minibuf_level); Fset_buffer (minibuffer); /* Defeat (setq-default truncate-lines t), since truncated lines do @@ -738,6 +769,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, where there is an active minibuffer. Set them to point to ` *Minibuf-0*', which is always empty. */ empty_minibuf = get_minibuffer (0); + set_minibuffer_mode (empty_minibuf, 0); FOR_EACH_FRAME (dummy, frame) { @@ -837,20 +869,6 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, recursive_edit_1 (); - /* We've exited the recursive edit without an error, so switch the - current window away from the expired minibuffer window. */ - { - Lisp_Object prev = Fprevious_window (minibuf_window, Qnil, Qnil); - /* PREV can be on a different frame when we have a minibuffer only - frame, the other frame's minibuffer window is MINIBUF_WINDOW, - and its "focus window" is also MINIBUF_WINDOW. */ - while (!EQ (prev, minibuf_window) - && !EQ (selected_frame, WINDOW_FRAME (XWINDOW (prev)))) - prev = Fprevious_window (prev, Qnil, Qnil); - if (!EQ (prev, minibuf_window)) - Fset_frame_selected_window (selected_frame, prev, Qnil); - } - /* If cursor is on the minibuffer line, show the user we have exited by putting it in column 0. */ if (XWINDOW (minibuf_window)->cursor.vpos >= 0 @@ -959,11 +977,16 @@ Lisp_Object get_minibuffer (EMACS_INT depth) { Lisp_Object tail = Fnthcdr (make_fixnum (depth), Vminibuffer_list); + Lisp_Object cll_tail = Fnthcdr (make_fixnum (depth), + Vcommand_loop_level_list); if (NILP (tail)) { tail = list1 (Qnil); Vminibuffer_list = nconc2 (Vminibuffer_list, tail); + cll_tail = list1 (Qnil); + Vcommand_loop_level_list = nconc2 (Vcommand_loop_level_list, cll_tail); } + XSETCAR (cll_tail, make_fixnum (depth ? command_loop_level : 0)); Lisp_Object buf = Fcar (tail); if (NILP (buf) || !BUFFER_LIVE_P (XBUFFER (buf))) { @@ -973,7 +996,6 @@ get_minibuffer (EMACS_INT depth) buf = Fget_buffer_create (lname, Qnil); /* Do this before set_minibuffer_mode. */ XSETCAR (tail, buf); - set_minibuffer_mode (buf, depth); /* Although the buffer's name starts with a space, undo should be enabled in it. */ Fbuffer_enable_undo (buf); @@ -985,12 +1007,19 @@ get_minibuffer (EMACS_INT depth) while the buffer doesn't know about them any more. */ delete_all_overlays (XBUFFER (buf)); reset_buffer (XBUFFER (buf)); - set_minibuffer_mode (buf, depth); } return buf; } +static EMACS_INT minibuf_c_loop_level (EMACS_INT depth) +{ + Lisp_Object cll = Fnth (make_fixnum (depth), Vcommand_loop_level_list); + if (FIXNUMP (cll)) + return XFIXNUM (cll); + return 0; +} + static void run_exit_minibuf_hook (void) { @@ -1004,17 +1033,16 @@ static void read_minibuf_unwind (void) { Lisp_Object old_deactivate_mark; - Lisp_Object window; + Lisp_Object calling_frame; + Lisp_Object calling_window; Lisp_Object future_mini_window; - /* If this was a recursive minibuffer, - tie the minibuffer window back to the outer level minibuffer buffer. */ - minibuf_level--; - - window = minibuf_window; /* To keep things predictable, in case it matters, let's be in the - minibuffer when we reset the relevant variables. */ - Fset_buffer (XWINDOW (window)->contents); + minibuffer when we reset the relevant variables. Don't depend on + `minibuf_window' here. This could by now be the mini-window of any + frame. */ + Fset_buffer (nth_minibuffer (minibuf_level)); + minibuf_level--; /* Restore prompt, etc, from outer minibuffer level. */ Lisp_Object key_vec = Fcar (minibuf_save_list); @@ -1042,6 +1070,10 @@ read_minibuf_unwind (void) #endif future_mini_window = Fcar (minibuf_save_list); minibuf_save_list = Fcdr (minibuf_save_list); + calling_frame = Fcar (minibuf_save_list); + minibuf_save_list = Fcdr (minibuf_save_list); + calling_window = Fcar (minibuf_save_list); + minibuf_save_list = Fcdr (minibuf_save_list); /* Erase the minibuffer we were using at this level. */ { @@ -1059,7 +1091,7 @@ read_minibuf_unwind (void) mini-window back to its normal size. */ if (minibuf_level == 0 || !EQ (selected_frame, WINDOW_FRAME (XWINDOW (future_mini_window)))) - resize_mini_window (XWINDOW (window), 0); + resize_mini_window (XWINDOW (minibuf_window), 0); /* Deal with frames that should be removed when exiting the minibuffer. */ @@ -1090,6 +1122,24 @@ read_minibuf_unwind (void) to make sure we don't leave around bindings and stuff which only made sense during the read_minibuf invocation. */ call0 (intern ("minibuffer-inactive-mode")); + + /* We've exited the recursive edit, so switch the current windows + away from the expired minibuffer window, both in the current + minibuffer's frame and the original calling frame. */ + choose_minibuf_frame (); + if (!EQ (WINDOW_FRAME (XWINDOW (minibuf_window)), calling_frame)) + { + Lisp_Object prev = Fprevious_window (minibuf_window, Qnil, Qnil); + /* PREV can be on a different frame when we have a minibuffer only + frame, the other frame's minibuffer window is MINIBUF_WINDOW, + and its "focus window" is also MINIBUF_WINDOW. */ + if (!EQ (prev, minibuf_window) + && EQ (WINDOW_FRAME (XWINDOW (prev)), + WINDOW_FRAME (XWINDOW (minibuf_window)))) + Fset_frame_selected_window (selected_frame, prev, Qnil); + } + else + Fset_frame_selected_window (calling_frame, calling_window, Qnil); } @@ -2137,6 +2187,7 @@ void init_minibuf_once (void) { staticpro (&Vminibuffer_list); + staticpro (&Vcommand_loop_level_list); pdumper_do_now_and_after_load (init_minibuf_once_for_pdumper); } @@ -2150,6 +2201,7 @@ init_minibuf_once_for_pdumper (void) restore from a dump file. pdumper doesn't try to preserve frames, windows, and so on, so reset everything related here. */ Vminibuffer_list = Qnil; + Vcommand_loop_level_list = Qnil; minibuf_level = 0; minibuf_prompt = Qnil; minibuf_save_list = Qnil; @@ -2380,6 +2432,7 @@ instead. */); defsubr (&Sminibufferp); defsubr (&Sinnermost_minibuffer_p); + defsubr (&Sminibuffer_innermost_command_loop_p); defsubr (&Sabort_minibuffers); defsubr (&Sminibuffer_prompt_end); defsubr (&Sminibuffer_contents); diff --git a/src/window.h b/src/window.h index 79eb44e7a3..b6f88e8f55 100644 --- a/src/window.h +++ b/src/window.h @@ -1120,10 +1120,6 @@ void set_window_buffer (Lisp_Object window, Lisp_Object buffer, extern Lisp_Object echo_area_window; -/* Depth in recursive edits. */ - -extern EMACS_INT command_loop_level; - /* Non-zero if we should redraw the mode lines on the next redisplay. Usually set to a unique small integer so we can track the main causes of full redisplays in `redisplay--mode-lines-cause'. */ commit 4f63b4bfc6c16abeaf9d8a9e9de76cc42d772567 Author: Stefan Kangas Date: Thu Feb 11 21:30:23 2021 +0100 Use lexical-binding in erc-sound.el * lisp/erc/erc-sound.el: Use lexical-binding. Remove redundant :group args. diff --git a/lisp/erc/erc-sound.el b/lisp/erc/erc-sound.el index edde9737ff..fff1639a9d 100644 --- a/lisp/erc/erc-sound.el +++ b/lisp/erc/erc-sound.el @@ -1,4 +1,4 @@ -;;; erc-sound.el --- CTCP SOUND support for ERC +;;; erc-sound.el --- CTCP SOUND support for ERC -*- lexical-binding: t -*- ;; Copyright (C) 2002-2003, 2006-2021 Free Software Foundation, Inc. @@ -66,18 +66,15 @@ and play sound files as requested." (defcustom erc-play-sound t "Play sounds when you receive CTCP SOUND requests." - :group 'erc-sound :type 'boolean) (defcustom erc-sound-path nil "List of directories that contain sound samples to play on SOUND events." - :group 'erc-sound :type '(repeat directory)) (defcustom erc-default-sound nil "Play this sound if the requested file was not found. If this is set to nil or the file doesn't exist a beep will sound." - :group 'erc-sound :type '(choice (const nil) file)) @@ -108,7 +105,7 @@ LINE is the text entered, including the command." t)) (t nil))) -(defun erc-ctcp-query-SOUND (proc nick login host to msg) +(defun erc-ctcp-query-SOUND (_proc nick login host _to msg) "Display a CTCP SOUND message and play sound if `erc-play-sound' is non-nil." (when (string-match "^SOUND\\s-+\\(\\S-+\\)\\(\\(\\s-+.*\\)\\|\\(\\s-*\\)\\)$" msg) (let ((sound (match-string 1 msg)) commit 0bcec1e4ae0028d6f0f4c04ab2717f6fdadb79c1 Author: Stefan Kangas Date: Thu Feb 11 21:08:17 2021 +0100 Drop XEmacs and SXEmacs support from EDE * lisp/cedet/ede/emacs.el (ede-emacs-version): Drop XEmacs and SXEmacs support from EDE. diff --git a/lisp/cedet/ede/emacs.el b/lisp/cedet/ede/emacs.el index 332f09bc5b..00496ace16 100644 --- a/lisp/cedet/ede/emacs.el +++ b/lisp/cedet/ede/emacs.el @@ -54,31 +54,6 @@ Return a tuple of ( EMACSNAME . VERSION )." (erase-buffer) (setq default-directory (file-name-as-directory dir)) (cond - ;; Maybe XEmacs? - ((file-exists-p "version.sh") - (setq emacs "XEmacs") - (insert-file-contents "version.sh") - (goto-char (point-min)) - (re-search-forward "emacs_major_version=\\([0-9]+\\) -emacs_minor_version=\\([0-9]+\\) -emacs_beta_version=\\([0-9]+\\)") - (setq ver (concat (match-string 1) "." - (match-string 2) "." - (match-string 3))) - ) - ((file-exists-p "sxemacs.pc.in") - (setq emacs "SXEmacs") - (insert-file-contents "sxemacs_version.m4") - (goto-char (point-min)) - (re-search-forward "m4_define(\\[SXEM4CS_MAJOR_VERSION\\], \\[\\([0-9]+\\)\\]) -m4_define(\\[SXEM4CS_MINOR_VERSION\\], \\[\\([0-9]+\\)\\]) -m4_define(\\[SXEM4CS_BETA_VERSION\\], \\[\\([0-9]+\\)\\])") - (setq ver (concat (match-string 1) "." - (match-string 2) "." - (match-string 3))) - ) - ;; Insert other Emacs here... - ;; Vaguely recent version of GNU Emacs? ((or (file-exists-p configure_ac) (file-exists-p (setq configure_ac "configure.in"))) commit f29c7d61d7e143458a7452e4b1c439c85dbe3bc9 Author: Stefan Kangas Date: Thu Feb 11 20:59:41 2021 +0100 Use lexical-binding in various ede files * lisp/cedet/ede/dired.el: * lisp/cedet/ede/emacs.el: * lisp/cedet/ede/make.el: * lisp/cedet/ede/proj-archive.el: * lisp/cedet/ede/proj-aux.el: * lisp/cedet/ede/proj-misc.el: * lisp/cedet/ede/proj-scheme.el: * lisp/cedet/ede/srecode.el: * lisp/cedet/ede/system.el: Use lexical-binding. diff --git a/lisp/cedet/ede/dired.el b/lisp/cedet/ede/dired.el index c85d4ee792..7eb42ed9de 100644 --- a/lisp/cedet/ede/dired.el +++ b/lisp/cedet/ede/dired.el @@ -1,4 +1,4 @@ -;;; ede/dired.el --- EDE extensions to dired. +;;; ede/dired.el --- EDE extensions to dired. -*- lexical-binding: t -*- ;; Copyright (C) 1998-2000, 2003, 2009-2021 Free Software Foundation, ;; Inc. diff --git a/lisp/cedet/ede/emacs.el b/lisp/cedet/ede/emacs.el index 1eb4c6395a..332f09bc5b 100644 --- a/lisp/cedet/ede/emacs.el +++ b/lisp/cedet/ede/emacs.el @@ -1,4 +1,4 @@ -;;; ede/emacs.el --- Special project for Emacs +;;; ede/emacs.el --- Special project for Emacs -*- lexical-binding: t -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/ede/make.el b/lisp/cedet/ede/make.el index 863d715e4f..4f86558c62 100644 --- a/lisp/cedet/ede/make.el +++ b/lisp/cedet/ede/make.el @@ -1,4 +1,4 @@ -;;; ede/make.el --- General information about "make" +;;; ede/make.el --- General information about "make" -*- lexical-binding: t -*- ;;; Copyright (C) 2009-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/ede/proj-archive.el b/lisp/cedet/ede/proj-archive.el index 038f994e4f..9da6374d09 100644 --- a/lisp/cedet/ede/proj-archive.el +++ b/lisp/cedet/ede/proj-archive.el @@ -1,4 +1,4 @@ -;;; ede/proj-archive.el --- EDE Generic Project archive support +;;; ede/proj-archive.el --- EDE Generic Project archive support -*- lexical-binding: t -*- ;; Copyright (C) 1998-2001, 2009-2021 Free Software Foundation, Inc. @@ -45,7 +45,7 @@ "Linker object for creating an archive.") (cl-defmethod ede-proj-makefile-insert-source-variables :before - ((this ede-proj-target-makefile-archive) &optional moresource) + ((this ede-proj-target-makefile-archive) &optional _moresource) "Insert bin_PROGRAMS variables needed by target THIS. We aren't actually inserting SOURCE details, but this is used by the Makefile.am generator, so use it to add this important bin program." diff --git a/lisp/cedet/ede/proj-aux.el b/lisp/cedet/ede/proj-aux.el index f5bcebdd4c..73259558a6 100644 --- a/lisp/cedet/ede/proj-aux.el +++ b/lisp/cedet/ede/proj-aux.el @@ -1,4 +1,4 @@ -;;; ede/proj-aux.el --- EDE Generic Project auxiliary file support +;;; ede/proj-aux.el --- EDE Generic Project auxiliary file support -*- lexical-binding: t -*- ;; Copyright (C) 1998-2000, 2007, 2009-2021 Free Software Foundation, ;; Inc. diff --git a/lisp/cedet/ede/proj-misc.el b/lisp/cedet/ede/proj-misc.el index 70132aff6c..068e998d1a 100644 --- a/lisp/cedet/ede/proj-misc.el +++ b/lisp/cedet/ede/proj-misc.el @@ -1,4 +1,4 @@ -;;; ede-proj-misc.el --- EDE Generic Project Emacs Lisp support +;;; ede-proj-misc.el --- EDE Generic Project Emacs Lisp support -*- lexical-binding: t -*- ;; Copyright (C) 1998-2001, 2008-2021 Free Software Foundation, Inc. diff --git a/lisp/cedet/ede/proj-scheme.el b/lisp/cedet/ede/proj-scheme.el index 51844af536..b0e287895f 100644 --- a/lisp/cedet/ede/proj-scheme.el +++ b/lisp/cedet/ede/proj-scheme.el @@ -1,4 +1,4 @@ -;;; ede/proj-scheme.el --- EDE Generic Project scheme (guile) support +;;; ede/proj-scheme.el --- EDE Generic Project scheme (guile) support -*- lexical-binding: t -*- ;; Copyright (C) 1998-2000, 2009-2021 Free Software Foundation, Inc. @@ -40,7 +40,7 @@ ) "This target consists of scheme files.") -(cl-defmethod ede-proj-tweak-autoconf ((this ede-proj-target-scheme)) +(cl-defmethod ede-proj-tweak-autoconf ((_this ede-proj-target-scheme)) "Tweak the configure file (current buffer) to accommodate THIS." (autoconf-insert-new-macro "AM_INIT_GUILE_MODULE")) diff --git a/lisp/cedet/ede/srecode.el b/lisp/cedet/ede/srecode.el index 5dd0a7ec61..dd009bfb31 100644 --- a/lisp/cedet/ede/srecode.el +++ b/lisp/cedet/ede/srecode.el @@ -1,4 +1,4 @@ -;;; ede/srecode.el --- EDE utilities on top of SRecoder +;;; ede/srecode.el --- EDE utilities on top of SRecoder -*- lexical-binding: t -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -86,7 +86,6 @@ Note: Just like `srecode-insert', but templates found in `ede' app." (car (cdr dictionary-entries))) (setq dictionary-entries (cdr (cdr dictionary-entries)))) - )) (provide 'ede/srecode) diff --git a/lisp/cedet/ede/system.el b/lisp/cedet/ede/system.el index d83d6d1cc6..8ef38f0d33 100644 --- a/lisp/cedet/ede/system.el +++ b/lisp/cedet/ede/system.el @@ -1,4 +1,4 @@ -;;; ede-system.el --- EDE working with the system (VC, FTP, ETC) +;;; ede-system.el --- EDE working with the system (VC, FTP, ETC) -*- lexical-binding: t -*- ;; Copyright (C) 2001-2003, 2009-2021 Free Software Foundation, Inc. commit a24be5ef7e29fd3626f355abf3a8be3b19188d13 Author: Stefan Kangas Date: Thu Feb 11 20:21:16 2021 +0100 Use lexical-binding in wid-browse.el * lisp/wid-browse.el: Use lexical-binding. (widget-browse-mode): Use define-derived-mode. (widget-browse-mode-hook): Remove redundant :group arg. (widget-browse-action, widget-browse-value-create): Doc fixes. diff --git a/lisp/wid-browse.el b/lisp/wid-browse.el index 0864e1b313..124cb04486 100644 --- a/lisp/wid-browse.el +++ b/lisp/wid-browse.el @@ -56,11 +56,10 @@ ["Browse At" widget-browse-at t])) (defcustom widget-browse-mode-hook nil - "Hook called when entering widget-browse-mode." - :type 'hook - :group 'widget-browse) + "Hook run after entering `widget-browse-mode'." + :type 'hook) -(defun widget-browse-mode () +(define-derived-mode widget-browse-mode special-mode "Widget Browse" "Major mode for widget browser buffers. The following commands are available: @@ -68,15 +67,7 @@ The following commands are available: \\[widget-forward] Move to next button or editable field. \\[widget-backward] Move to previous button or editable field. \\[widget-button-click] Activate button under the mouse pointer. -\\[widget-button-press] Activate button under point. - -Entry to this mode calls the value of `widget-browse-mode-hook' -if that value is non-nil." - (kill-all-local-variables) - (setq major-mode 'widget-browse-mode - mode-name "Widget") - (use-local-map widget-browse-mode-map) - (run-mode-hooks 'widget-browse-mode-hook)) +\\[widget-button-press] Activate button under point.") (put 'widget-browse-mode 'mode-class 'special) @@ -190,11 +181,11 @@ The :value of the widget should be the widget to be browsed." :action 'widget-browse-action) (defun widget-browse-action (widget &optional _event) - ;; Create widget browser for WIDGET's :value. + "Create widget browser for :value of WIDGET." (widget-browse (widget-get widget :value))) (defun widget-browse-value-create (widget) - ;; Insert type name. + "Insert type name for WIDGET." (let ((value (widget-get widget :value))) (cond ((symbolp value) (insert (symbol-name value))) @@ -273,8 +264,6 @@ VALUE is assumed to be a list of widgets." "Minor mode for traversing widgets." :lighter " Widget") -;;; The End: - (provide 'wid-browse) ;;; wid-browse.el ends here commit c99460cbf6ac9345059f87f4620700bde7f32b67 Author: Stefan Kangas Date: Thu Feb 11 20:10:31 2021 +0100 * lisp/ps-samp.el: Use lexical-binding. diff --git a/lisp/ps-samp.el b/lisp/ps-samp.el index fdff0f182d..22a29b8b4b 100644 --- a/lisp/ps-samp.el +++ b/lisp/ps-samp.el @@ -1,4 +1,4 @@ -;;; ps-samp.el --- ps-print sample setup code +;;; ps-samp.el --- ps-print sample setup code -*- lexical-binding: t -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. commit c553fdc80c45c3cb3a609f85c3573d0fbc95c1a5 Author: Stefan Kangas Date: Thu Feb 11 19:18:38 2021 +0100 Fix two Emacs version references in misc manuals * doc/misc/forms.texi: Fix reference to Emacs version. * doc/misc/remember.texi: Fix version reference to indicate Emacs version instead of version of remember. The corresponding version variable and header have been marked obsolete. diff --git a/doc/misc/forms.texi b/doc/misc/forms.texi index 3d7ac96cc2..15fcd97c5b 100644 --- a/doc/misc/forms.texi +++ b/doc/misc/forms.texi @@ -6,6 +6,7 @@ @setfilename ../../info/forms.info @settitle Forms Mode User's Manual @include docstyle.texi +@include emacsver.texi @syncodeindex vr cp @syncodeindex fn cp @syncodeindex ky cp @@ -47,7 +48,7 @@ modify this GNU manual.'' @sp 4 @center Forms-Mode version 2 @sp 1 -@center for GNU Emacs 22.1 +@center for GNU Emacs @value{EMACSVER} @sp 1 @center April 2007 @sp 5 diff --git a/doc/misc/remember.texi b/doc/misc/remember.texi index 80065be0a1..91e67a8798 100644 --- a/doc/misc/remember.texi +++ b/doc/misc/remember.texi @@ -3,11 +3,12 @@ @setfilename ../../info/remember.info @settitle Remember Manual @include docstyle.texi +@include emacsver.texi @syncodeindex fn cp @c %**end of header @copying -This manual is for Remember Mode, version 2.0 +This manual is for Remember Mode, as distributed with Emacs @value{EMACSVER}. Copyright @copyright{} 2001, 2004--2005, 2007--2021 Free Software Foundation, Inc. commit b3362f7b705d004f53792406f4fdac78e8370fc7 Author: Stefan Kangas Date: Thu Feb 11 15:40:45 2021 +0100 ; Fix lexical-binding conversion of semantic/bovine/gcc.el * lisp/cedet/semantic/bovine/gcc.el (semantic-gcc-get-include-paths): Fix sorting and comparison after previous lexical-binding conversion. diff --git a/lisp/cedet/semantic/bovine/gcc.el b/lisp/cedet/semantic/bovine/gcc.el index 9cd9cdcb84..c2121e5d58 100644 --- a/lisp/cedet/semantic/bovine/gcc.el +++ b/lisp/cedet/semantic/bovine/gcc.el @@ -89,8 +89,9 @@ to give to the program." (let ((path (substring line 1))) (when (and (file-accessible-directory-p path) (file-name-absolute-p path)) - (cl-pushnew (expand-file-name path) inc-path)))))))) - inc-path)) + (cl-pushnew (expand-file-name path) inc-path + :test #'equal)))))))) + (nreverse inc-path))) (defun semantic-cpp-defs (str) commit 21ec45c10727403421c41c8c67a752458790afbb Author: Basil L. Contovounesios Date: Wed Feb 10 01:30:08 2021 +0000 Fix Octave double-quoted string line continuations * lisp/progmodes/octave.el (octave-string-continuation-marker): New defconst after octave-continuation-string. (octave-continuation-string): Mention it in docstring. (octave-maybe-insert-continuation-string): Mark unused function as obsolete. (octave-help-function): Simplify action. (octave--indent-new-comment-line): Insert octave-string-continuation-marker instead of octave-continuation-string within double-quoted strings (bug#46420). (octave-indent-new-comment-line): * etc/NEWS: Describe new behavior. diff --git a/doc/misc/octave-mode.texi b/doc/misc/octave-mode.texi index 1adc268969..e330606015 100644 --- a/doc/misc/octave-mode.texi +++ b/doc/misc/octave-mode.texi @@ -83,9 +83,12 @@ addition to the standard Emacs commands. @kindex C-M-j @findex octave-indent-new-comment-line @vindex octave-continuation-string +@vindex octave-string-continuation-marker Break Octave line at point, continuing comment if within one. Insert @code{octave-continuation-string} before breaking the line unless -inside a list. Signal an error if within a single-quoted string. +inside a list. If within a double-quoted string, insert +@code{octave-string-continuation-marker} instead. Signal an error if +within a single-quoted string. @item C-c ; @kindex C-c ; diff --git a/etc/NEWS b/etc/NEWS index 67fc49f181..2f15f078a7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2018,6 +2018,15 @@ could have saved enough typing by using an abbrev, a hint will be displayed in the echo area, mentioning the abbrev that could have been used instead. +** Octave Mode + ++++ +*** Line continuations in double-quoted strings now use a backslash. +Typing 'C-M-j' (bound to 'octave-indent-new-comment-line') now follows +the behavior introduced in Octave 3.8 of using a backslash as a line +continuation marker within double-quoted strings, and an ellipsis +everywhere else. + * New Modes and Packages in Emacs 28.1 diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el index ddcc6f5450..a8a86478d8 100644 --- a/lisp/progmodes/octave.el +++ b/lisp/progmodes/octave.el @@ -215,9 +215,15 @@ newline or semicolon after an else or end keyword." (concat "[^#%\n]*\\(" octave-continuation-marker-regexp "\\)\\s-*\\(\\s<.*\\)?$")) -;; Char \ is considered a bad decision for continuing a line. (defconst octave-continuation-string "..." - "Character string used for Octave continuation lines.") + "Character string used for Octave continuation lines. +Joins current line with following line, except within +double-quoted strings, where `octave-string-continuation-marker' +is used instead.") + +(defconst octave-string-continuation-marker "\\" + "Line continuation marker for double-quoted Octave strings. +Non-string statements use `octave-continuation-string'.") (defvar octave-mode-imenu-generic-expression (list @@ -1032,11 +1038,11 @@ directory and makes this the current buffer's default directory." (looking-at regexp))) (defun octave-maybe-insert-continuation-string () - (if (or (octave-in-comment-p) - (save-excursion - (beginning-of-line) - (looking-at octave-continuation-regexp))) - nil + (declare (obsolete nil "28.1")) + (unless (or (octave-in-comment-p) + (save-excursion + (beginning-of-line) + (looking-at octave-continuation-regexp))) (delete-horizontal-space) (insert (concat " " octave-continuation-string)))) @@ -1218,23 +1224,22 @@ q: Don't fix\n" func file)) (defun octave-indent-new-comment-line (&optional soft) "Break Octave line at point, continuing comment if within one. Insert `octave-continuation-string' before breaking the line -unless inside a list. Signal an error if within a single-quoted -string." +unless inside a list. If within a double-quoted string, insert +`octave-string-continuation-marker' instead. Signal an error if +within a single-quoted string." (interactive) (funcall comment-line-break-function soft)) (defun octave--indent-new-comment-line (orig &rest args) - (cond - ((octave-in-comment-p) nil) - ((eq (octave-in-string-p) ?') - (error "Cannot split a single-quoted string")) - ((eq (octave-in-string-p) ?\") - (insert octave-continuation-string)) - (t - (delete-horizontal-space) - (unless (and (cadr (syntax-ppss)) - (eq (char-after (cadr (syntax-ppss))) ?\()) - (insert " " octave-continuation-string)))) + (pcase (syntax-ppss) + ((app ppss-string-terminator ?\') + (user-error "Cannot split a single-quoted string")) + ((app ppss-string-terminator ?\") + (insert octave-string-continuation-marker)) + ((pred (not ppss-comment-depth)) + (delete-horizontal-space) + (unless (octave-smie--in-parens-p) + (insert " " octave-continuation-string)))) (apply orig args) (indent-according-to-mode)) @@ -1663,9 +1668,7 @@ code line." (define-button-type 'octave-help-function 'follow-link t - 'action (lambda (b) - (octave-help - (buffer-substring (button-start b) (button-end b))))) + 'action (lambda (b) (octave-help (button-label b)))) (defvar octave-help-mode-map (let ((map (make-sparse-keymap))) commit 0e2b123a4ef600f5b337972a7bb61c1fc4b7d0cd Author: Andrii Kolomoiets Date: Thu Feb 11 10:09:41 2021 +0100 Use frame monitor in frame_float * src/frame.c (frame_float): Use frame monitor attributes instead of attributes of the main monitor (bug#46406). diff --git a/src/frame.c b/src/frame.c index 635fc94560..a62347c1fb 100644 --- a/src/frame.c +++ b/src/frame.c @@ -3890,7 +3890,7 @@ frame_float (struct frame *f, Lisp_Object val, enum frame_float_type what, Lisp_Object frame; XSETFRAME (frame, f); - monitor_attributes = Fcar (call1 (Qdisplay_monitor_attributes_list, frame)); + monitor_attributes = call1 (Qframe_monitor_attributes, frame); if (NILP (monitor_attributes)) { /* No monitor attributes available. */ @@ -5890,7 +5890,7 @@ syms_of_frame (void) DEFSYM (Qframep, "framep"); DEFSYM (Qframe_live_p, "frame-live-p"); DEFSYM (Qframe_windows_min_size, "frame-windows-min-size"); - DEFSYM (Qdisplay_monitor_attributes_list, "display-monitor-attributes-list"); + DEFSYM (Qframe_monitor_attributes, "frame-monitor-attributes"); DEFSYM (Qwindow__pixel_to_total, "window--pixel-to-total"); DEFSYM (Qexplicit_name, "explicit-name"); DEFSYM (Qheight, "height"); commit aaa80f408cbfe9419c2bc140f358604cf0b1a7c7 Author: Stefan Kangas Date: Wed Feb 10 20:58:16 2021 +0100 Avoid having erc in irrelevant finder categories * lisp/erc/erc-backend.el: * lisp/erc/erc-button.el: * lisp/erc/erc-dcc.el: * lisp/erc/erc-identd.el: * lisp/erc/erc-join.el: * lisp/erc/erc-lang.el: * lisp/erc/erc-log.el: * lisp/erc/erc-match.el: * lisp/erc/erc-menu.el: * lisp/erc/erc-pcomplete.el: * lisp/erc/erc-replace.el: * lisp/erc/erc-spelling.el: * lisp/erc/erc-stamp.el: * lisp/erc/erc-track.el: * lisp/erc/erc-xdcc.el: Remove irrelevant entries in Keywords header. diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index 4cabd42f53..6f1193cbb2 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -6,7 +6,7 @@ ;; Author: Lawrence Mitchell ;; Maintainer: Amin Bandali ;; Created: 2004-05-7 -;; Keywords: IRC chat client internet +;; Keywords: comm, IRC, chat, client, internet ;; This file is part of GNU Emacs. diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el index 71ff40877a..0a81da3897 100644 --- a/lisp/erc/erc-button.el +++ b/lisp/erc/erc-button.el @@ -4,7 +4,7 @@ ;; Author: Mario Lang ;; Maintainer: Amin Bandali -;; Keywords: irc, button, url, regexp +;; Keywords: comm, irc, button, url, regexp ;; URL: https://www.emacswiki.org/emacs/ErcButton ;; This file is part of GNU Emacs. diff --git a/lisp/erc/erc-dcc.el b/lisp/erc/erc-dcc.el index 9dedd3cda8..e72d8fbe3d 100644 --- a/lisp/erc/erc-dcc.el +++ b/lisp/erc/erc-dcc.el @@ -7,7 +7,7 @@ ;; Noah Friedman ;; Per Persson ;; Maintainer: Amin Bandali -;; Keywords: comm, processes +;; Keywords: comm ;; Created: 1994-01-23 ;; This file is part of GNU Emacs. diff --git a/lisp/erc/erc-identd.el b/lisp/erc/erc-identd.el index 5f1aab1784..1f68272ebb 100644 --- a/lisp/erc/erc-identd.el +++ b/lisp/erc/erc-identd.el @@ -4,7 +4,7 @@ ;; Author: John Wiegley ;; Maintainer: Amin Bandali -;; Keywords: comm, processes +;; Keywords: comm ;; This file is part of GNU Emacs. diff --git a/lisp/erc/erc-join.el b/lisp/erc/erc-join.el index e6e5070783..1707e714cc 100644 --- a/lisp/erc/erc-join.el +++ b/lisp/erc/erc-join.el @@ -4,7 +4,7 @@ ;; Author: Alex Schroeder ;; Maintainer: Amin Bandali -;; Keywords: irc +;; Keywords: comm, irc ;; URL: https://www.emacswiki.org/emacs/ErcAutoJoin ;; This file is part of GNU Emacs. diff --git a/lisp/erc/erc-lang.el b/lisp/erc/erc-lang.el index b86a8d0be2..4163e5a08d 100644 --- a/lisp/erc/erc-lang.el +++ b/lisp/erc/erc-lang.el @@ -6,7 +6,7 @@ ;; Maintainer: Amin Bandali ;; Old-Version: 1.0.0 ;; URL: https://www.emacswiki.org/emacs/ErcLang -;; Keywords: comm languages processes +;; Keywords: comm ;; This file is part of GNU Emacs. diff --git a/lisp/erc/erc-log.el b/lisp/erc/erc-log.el index 4540ec6808..22fd3d2713 100644 --- a/lisp/erc/erc-log.el +++ b/lisp/erc/erc-log.el @@ -5,7 +5,7 @@ ;; Author: Lawrence Mitchell ;; Maintainer: Amin Bandali ;; URL: https://www.emacswiki.org/emacs/ErcLogging -;; Keywords: IRC, chat, client, Internet, logging +;; Keywords: comm, IRC, chat, client, Internet, logging ;; Created 2003-04-26 ;; Logging code taken from erc.el and modified to use markers. diff --git a/lisp/erc/erc-match.el b/lisp/erc/erc-match.el index 153742a670..eede15c11a 100644 --- a/lisp/erc/erc-match.el +++ b/lisp/erc/erc-match.el @@ -4,7 +4,7 @@ ;; Author: Andreas Fuchs ;; Maintainer: Amin Bandali -;; Keywords: comm, faces +;; Keywords: comm ;; URL: https://www.emacswiki.org/emacs/ErcMatch ;; This file is part of GNU Emacs. diff --git a/lisp/erc/erc-menu.el b/lisp/erc/erc-menu.el index 4c092c834b..3995a0564a 100644 --- a/lisp/erc/erc-menu.el +++ b/lisp/erc/erc-menu.el @@ -4,7 +4,7 @@ ;; Author: Mario Lang ;; Maintainer: Amin Bandali -;; Keywords: comm, processes, menu +;; Keywords: comm, menu ;; This file is part of GNU Emacs. diff --git a/lisp/erc/erc-pcomplete.el b/lisp/erc/erc-pcomplete.el index ddaf78774a..e9ebf0a07a 100644 --- a/lisp/erc/erc-pcomplete.el +++ b/lisp/erc/erc-pcomplete.el @@ -4,7 +4,7 @@ ;; Author: Sacha Chua ;; Maintainer: Amin Bandali -;; Keywords: comm, convenience +;; Keywords: comm ;; URL: https://www.emacswiki.org/emacs/ErcCompletion ;; This file is part of GNU Emacs. diff --git a/lisp/erc/erc-replace.el b/lisp/erc/erc-replace.el index 91fafbb630..c67d751403 100644 --- a/lisp/erc/erc-replace.el +++ b/lisp/erc/erc-replace.el @@ -6,7 +6,7 @@ ;; Author: Andreas Fuchs ;; Maintainer: Amin Bandali ;; URL: https://www.emacswiki.org/emacs/ErcReplace -;; Keywords: IRC, client, Internet +;; Keywords: comm, IRC, client, Internet ;; This file is part of GNU Emacs. diff --git a/lisp/erc/erc-spelling.el b/lisp/erc/erc-spelling.el index 44a3e35881..c18ac5b3ec 100644 --- a/lisp/erc/erc-spelling.el +++ b/lisp/erc/erc-spelling.el @@ -4,7 +4,7 @@ ;; Author: Jorgen Schaefer ;; Maintainer: Amin Bandali -;; Keywords: irc +;; Keywords: comm, irc ;; URL: https://www.emacswiki.org/emacs/ErcSpelling ;; This file is part of GNU Emacs. diff --git a/lisp/erc/erc-stamp.el b/lisp/erc/erc-stamp.el index 2c42a18081..da91364e9c 100644 --- a/lisp/erc/erc-stamp.el +++ b/lisp/erc/erc-stamp.el @@ -4,7 +4,7 @@ ;; Author: Mario Lang ;; Maintainer: Amin Bandali -;; Keywords: comm, processes, timestamp +;; Keywords: comm, timestamp ;; URL: https://www.emacswiki.org/emacs/ErcStamp ;; This file is part of GNU Emacs. diff --git a/lisp/erc/erc-track.el b/lisp/erc/erc-track.el index d6ad847c5b..56f66563ad 100644 --- a/lisp/erc/erc-track.el +++ b/lisp/erc/erc-track.el @@ -4,7 +4,7 @@ ;; Author: Mario Lang ;; Maintainer: Amin Bandali -;; Keywords: comm, faces +;; Keywords: comm ;; URL: https://www.emacswiki.org/emacs/ErcChannelTracking ;; This file is part of GNU Emacs. diff --git a/lisp/erc/erc-xdcc.el b/lisp/erc/erc-xdcc.el index 6808f24911..db8383ba20 100644 --- a/lisp/erc/erc-xdcc.el +++ b/lisp/erc/erc-xdcc.el @@ -4,7 +4,7 @@ ;; Author: Mario Lang ;; Maintainer: Amin Bandali -;; Keywords: comm, processes +;; Keywords: comm ;; This file is part of GNU Emacs. commit ad3e5da95359a15b1f615574ae0b39bade6efd67 Author: Stefan Kangas Date: Wed Feb 10 20:54:48 2021 +0100 * lisp/progmodes/cperl-mode.el (cperl-init-faces): Use regexp-opt. diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index a70e8e36c0..b1a49b25a3 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -5415,120 +5415,79 @@ indentation and initial hashes. Behaves usually outside of comment." (cons (concat "\\(^\\|[^$@%&\\]\\)\\<\\(" - ;; FIXME: Use regexp-opt. - (mapconcat - #'identity + (regexp-opt (append cperl-sub-keywords '("if" "until" "while" "elsif" "else" - "given" "when" "default" "break" - "unless" "for" - "try" "catch" "finally" - "foreach" "continue" "exit" "die" "last" "goto" "next" - "redo" "return" "local" "exec" - "do" "dump" - "use" "our" - "require" "package" "eval" "evalbytes" "my" "state" - "BEGIN" "END" "CHECK" "INIT" "UNITCHECK")) - "\\|") ; Flow control + "given" "when" "default" "break" + "unless" "for" + "try" "catch" "finally" + "foreach" "continue" "exit" "die" "last" "goto" "next" + "redo" "return" "local" "exec" + "do" "dump" + "use" "our" + "require" "package" "eval" "evalbytes" "my" "state" + "BEGIN" "END" "CHECK" "INIT" "UNITCHECK"))) ; Flow control "\\)\\>") 2) ; was "\\)[ \n\t;():,|&]" ; In what follows we use `type' style ; for overwritable builtins (list (concat "\\(^\\|[^$@%&\\]\\)\\<\\(" - ;; FIXME: Use regexp-opt. - ;; "CORE" "__FILE__" "__LINE__" "__SUB__" "abs" "accept" "alarm" - ;; "and" "atan2" "bind" "binmode" "bless" "caller" - ;; "chdir" "chmod" "chown" "chr" "chroot" "close" - ;; "closedir" "cmp" "connect" "continue" "cos" "crypt" - ;; "dbmclose" "dbmopen" "die" "dump" "endgrent" - ;; "endhostent" "endnetent" "endprotoent" "endpwent" - ;; "endservent" "eof" "eq" "exec" "exit" "exp" "fc" "fcntl" - ;; "fileno" "flock" "fork" "formline" "ge" "getc" - ;; "getgrent" "getgrgid" "getgrnam" "gethostbyaddr" - ;; "gethostbyname" "gethostent" "getlogin" - ;; "getnetbyaddr" "getnetbyname" "getnetent" - ;; "getpeername" "getpgrp" "getppid" "getpriority" - ;; "getprotobyname" "getprotobynumber" "getprotoent" - ;; "getpwent" "getpwnam" "getpwuid" "getservbyname" - ;; "getservbyport" "getservent" "getsockname" - ;; "getsockopt" "glob" "gmtime" "gt" "hex" "index" "int" - ;; "ioctl" "join" "kill" "lc" "lcfirst" "le" "length" - ;; "link" "listen" "localtime" "lock" "log" "lstat" "lt" - ;; "mkdir" "msgctl" "msgget" "msgrcv" "msgsnd" "ne" - ;; "not" "oct" "open" "opendir" "or" "ord" "pack" "pipe" - ;; "quotemeta" "rand" "read" "readdir" "readline" - ;; "readlink" "readpipe" "recv" "ref" "rename" "require" - ;; "reset" "reverse" "rewinddir" "rindex" "rmdir" "seek" - ;; "seekdir" "select" "semctl" "semget" "semop" "send" - ;; "setgrent" "sethostent" "setnetent" "setpgrp" - ;; "setpriority" "setprotoent" "setpwent" "setservent" - ;; "setsockopt" "shmctl" "shmget" "shmread" "shmwrite" - ;; "shutdown" "sin" "sleep" "socket" "socketpair" - ;; "sprintf" "sqrt" "srand" "stat" "substr" "symlink" - ;; "syscall" "sysopen" "sysread" "sysseek" "system" "syswrite" "tell" - ;; "telldir" "time" "times" "truncate" "uc" "ucfirst" - ;; "umask" "unlink" "unpack" "utime" "values" "vec" - ;; "wait" "waitpid" "wantarray" "warn" "write" "x" "xor" - "a\\(bs\\|ccept\\|tan2\\|larm\\|nd\\)\\|" - "b\\(in\\(d\\|mode\\)\\|less\\)\\|" - "c\\(h\\(r\\(\\|oot\\)\\|dir\\|mod\\|own\\)\\|aller\\|rypt\\|" - "lose\\(\\|dir\\)\\|mp\\|o\\(s\\|n\\(tinue\\|nect\\)\\)\\)\\|" - "CORE\\|d\\(ie\\|bm\\(close\\|open\\)\\|ump\\)\\|" - "e\\(x\\(p\\|it\\|ec\\)\\|q\\|nd\\(p\\(rotoent\\|went\\)\\|" - "hostent\\|servent\\|netent\\|grent\\)\\|of\\)\\|" - "f\\(ileno\\|c\\(ntl\\)?\\|lock\\|or\\(k\\|mline\\)\\)\\|" - "g\\(t\\|lob\\|mtime\\|e\\(\\|t\\(p\\(pid\\|r\\(iority\\|" - "oto\\(byn\\(ame\\|umber\\)\\|ent\\)\\)\\|eername\\|w" - "\\(uid\\|ent\\|nam\\)\\|grp\\)\\|host\\(by\\(addr\\|name\\)\\|" - "ent\\)\\|s\\(erv\\(by\\(port\\|name\\)\\|ent\\)\\|" - "ock\\(name\\|opt\\)\\)\\|c\\|login\\|net\\(by\\(addr\\|name\\)\\|" - "ent\\)\\|gr\\(ent\\|nam\\|gid\\)\\)\\)\\)\\|" - "hex\\|i\\(n\\(t\\|dex\\)\\|octl\\)\\|join\\|kill\\|" - "l\\(i\\(sten\\|nk\\)\\|stat\\|c\\(\\|first\\)\\|t\\|e" - "\\(\\|ngth\\)\\|o\\(c\\(altime\\|k\\)\\|g\\)\\)\\|m\\(sg\\(rcv\\|snd\\|" - "ctl\\|get\\)\\|kdir\\)\\|n\\(e\\|ot\\)\\|o\\(pen\\(\\|dir\\)\\|" - "r\\(\\|d\\)\\|ct\\)\\|p\\(ipe\\|ack\\)\\|quotemeta\\|" - "r\\(index\\|and\\|mdir\\|e\\(quire\\|ad\\(pipe\\|\\|lin" - "\\(k\\|e\\)\\|dir\\)\\|set\\|cv\\|verse\\|f\\|winddir\\|name" - "\\)\\)\\|s\\(printf\\|qrt\\|rand\\|tat\\|ubstr\\|e\\(t\\(p\\(r" - "\\(iority\\|otoent\\)\\|went\\|grp\\)\\|hostent\\|s\\(ervent\\|" - "ockopt\\)\\|netent\\|grent\\)\\|ek\\(\\|dir\\)\\|lect\\|" - "m\\(ctl\\|op\\|get\\)\\|nd\\)\\|h\\(utdown\\|m\\(read\\|ctl\\|" - "write\\|get\\)\\)\\|y\\(s\\(read\\|call\\|open\\|tem\\|write\\|seek\\)\\|" - "mlink\\)\\|in\\|leep\\|ocket\\(pair\\|\\)\\)\\|t\\(runcate\\|" - "ell\\(\\|dir\\)\\|ime\\(\\|s\\)\\)\\|u\\(c\\(\\|first\\)\\|" - "time\\|mask\\|n\\(pack\\|link\\)\\)\\|v\\(alues\\|ec\\)\\|" - "w\\(a\\(rn\\|it\\(pid\\|\\)\\|ntarray\\)\\|rite\\)\\|" - "x\\(\\|or\\)\\|__\\(FILE\\|LINE\\|PACKAGE\\|SUB\\)__" - "\\)\\>") 2 'font-lock-type-face) + (regexp-opt + '("CORE" "__FILE__" "__LINE__" "__SUB__" + "abs" "accept" "alarm" "and" "atan2" + "bind" "binmode" "bless" "caller" + "chdir" "chmod" "chown" "chr" "chroot" "close" + "closedir" "cmp" "connect" "continue" "cos" "crypt" + "dbmclose" "dbmopen" "die" "dump" "endgrent" + "endhostent" "endnetent" "endprotoent" "endpwent" + "endservent" "eof" "eq" "exec" "exit" "exp" "fc" "fcntl" + "fileno" "flock" "fork" "formline" "ge" "getc" + "getgrent" "getgrgid" "getgrnam" "gethostbyaddr" + "gethostbyname" "gethostent" "getlogin" + "getnetbyaddr" "getnetbyname" "getnetent" + "getpeername" "getpgrp" "getppid" "getpriority" + "getprotobyname" "getprotobynumber" "getprotoent" + "getpwent" "getpwnam" "getpwuid" "getservbyname" + "getservbyport" "getservent" "getsockname" + "getsockopt" "glob" "gmtime" "gt" "hex" "index" "int" + "ioctl" "join" "kill" "lc" "lcfirst" "le" "length" + "link" "listen" "localtime" "lock" "log" "lstat" "lt" + "mkdir" "msgctl" "msgget" "msgrcv" "msgsnd" "ne" + "not" "oct" "open" "opendir" "or" "ord" "pack" "pipe" + "quotemeta" "rand" "read" "readdir" "readline" + "readlink" "readpipe" "recv" "ref" "rename" "require" + "reset" "reverse" "rewinddir" "rindex" "rmdir" "seek" + "seekdir" "select" "semctl" "semget" "semop" "send" + "setgrent" "sethostent" "setnetent" "setpgrp" + "setpriority" "setprotoent" "setpwent" "setservent" + "setsockopt" "shmctl" "shmget" "shmread" "shmwrite" + "shutdown" "sin" "sleep" "socket" "socketpair" + "sprintf" "sqrt" "srand" "stat" "substr" "symlink" + "syscall" "sysopen" "sysread" "sysseek" "system" "syswrite" "tell" + "telldir" "time" "times" "truncate" "uc" "ucfirst" + "umask" "unlink" "unpack" "utime" "values" "vec" + "wait" "waitpid" "wantarray" "warn" "write" "x" "xor")) + "\\)\\>") + 2 'font-lock-type-face) ;; In what follows we use `other' style ;; for nonoverwritable builtins - ;; Somehow 's', 'm' are not auto-generated??? (list (concat "\\(^\\|[^$@%&\\]\\)\\<\\(" - ;; "AUTOLOAD" "BEGIN" "CHECK" "DESTROY" "END" "INIT" "UNITCHECK" "__END__" "chomp" - ;; "break" "chop" "default" "defined" "delete" "do" "each" "else" "elsif" - ;; "eval" "evalbytes" "exists" "for" "foreach" "format" "given" "goto" - ;; "grep" "if" "keys" "last" "local" "map" "my" "next" - ;; "no" "our" "package" "pop" "pos" "print" "printf" "prototype" "push" - ;; "q" "qq" "qw" "qx" "redo" "return" "say" "scalar" "shift" - ;; "sort" "splice" "split" "state" "study" "sub" "tie" "tr" - ;; "undef" "unless" "unshift" "untie" "until" "use" - ;; "when" "while" "y" - "AUTOLOAD\\|BEGIN\\|\\(UNIT\\)?CHECK\\|break\\|c\\(atch\\|ho\\(p\\|mp\\)\\)\\|d\\(e\\(f\\(inally\\|ault\\|ined\\)\\|lete\\)\\|" - "o\\)\\|DESTROY\\|e\\(ach\\|val\\(bytes\\)?\\|xists\\|ls\\(e\\|if\\)\\)\\|" - "END\\|for\\(\\|each\\|mat\\)\\|g\\(iven\\|rep\\|oto\\)\\|INIT\\|if\\|keys\\|" - "l\\(ast\\|ocal\\)\\|m\\(ap\\|y\\)\\|n\\(ext\\|o\\)\\|our\\|" - "p\\(ackage\\|rototype\\|rint\\(\\|f\\)\\|ush\\|o\\(p\\|s\\)\\)\\|" - "q\\(\\|q\\|w\\|x\\|r\\)\\|re\\(turn\\|do\\)\\|s\\(ay\\|pli\\(ce\\|t\\)\\|" - "calar\\|t\\(ate\\|udy\\)\\|ub\\|hift\\|ort\\)\\|t\\(ry?\\|ied?\\)\\|" - "u\\(se\\|n\\(shift\\|ti\\(l\\|e\\)\\|def\\|less\\)\\)\\|" - "wh\\(en\\|ile\\)\\|y\\|__\\(END\\|DATA\\)__" ;__DATA__ added manually - "\\|[sm]" ; Added manually - "\\)\\>") + (regexp-opt + '("AUTOLOAD" "BEGIN" "CHECK" "DESTROY" "END" "INIT" "UNITCHECK" + "__END__" "__DATA__" "break" "catch" "chomp" "chop" "default" + "defined" "delete" "do" "each" "else" "elsif" "eval" + "evalbytes" "exists" "finally" "for" "foreach" "format" "given" + "goto" "grep" "if" "keys" "last" "local" "m" "map" "my" "next" + "no" "our" "package" "pop" "pos" "print" "printf" "prototype" + "push" "q" "qq" "qw" "qx" "redo" "return" "s" "say" "scalar" + "shift" "sort" "splice" "split" "state" "study" "sub" "tie" + "tied" "tr" "try" "undef" "unless" "unshift" "untie" "until" + "use" "when" "while" "y")) + "\\)\\>") 2 ''cperl-nonoverridable-face) ; unbound as var, so: doubly quoted ;; (mapconcat #'identity ;; '("#endif" "#else" "#ifdef" "#ifndef" "#if" commit 1be27e3bf36f5e984429f645bdce1bcb8e82c54c Author: Stefan Monnier Date: Wed Feb 10 17:47:18 2021 -0500 * lisp/play/decipher.el: Use lexical-binding (decipher-mode-syntax-table): Move initialization into declaration. (decipher-mode, decipher-stats-mode): Use `define-derived-mode`. (decipher-stats-buffer): Use `buffer-local-value`. diff --git a/lisp/play/decipher.el b/lisp/play/decipher.el index 524ca81f30..9b2626b19d 100644 --- a/lisp/play/decipher.el +++ b/lisp/play/decipher.el @@ -1,4 +1,4 @@ -;;; decipher.el --- cryptanalyze monoalphabetic substitution ciphers +;;; decipher.el --- cryptanalyze monoalphabetic substitution ciphers -*- lexical-binding: t; -*- ;; ;; Copyright (C) 1995-1996, 2001-2021 Free Software Foundation, Inc. ;; @@ -71,7 +71,7 @@ ;; Emacs commands. ;; ;; Decipher supports Font Lock mode. To use it, you can also add -;; (add-hook 'decipher-mode-hook 'turn-on-font-lock) +;; (add-hook 'decipher-mode-hook #'turn-on-font-lock) ;; See the variable `decipher-font-lock-keywords' if you want to customize ;; the faces used. I'd like to thank Simon Marshall for his help in making ;; Decipher work well with Font Lock. @@ -84,6 +84,8 @@ ;; 1. The consonant-line shortcut ;; 2. More functions for analyzing ciphertext +;;; Code: + ;;;=================================================================== ;;; Variables: ;;;=================================================================== @@ -139,20 +141,20 @@ the tail of the list." (defvar decipher-mode-map (let ((map (make-keymap))) (suppress-keymap map) - (define-key map "A" 'decipher-show-alphabet) - (define-key map "C" 'decipher-complete-alphabet) - (define-key map "D" 'decipher-digram-list) - (define-key map "F" 'decipher-frequency-count) - (define-key map "M" 'decipher-make-checkpoint) - (define-key map "N" 'decipher-adjacency-list) - (define-key map "R" 'decipher-restore-checkpoint) - (define-key map "U" 'decipher-undo) - (define-key map " " 'decipher-keypress) - (define-key map [remap undo] 'decipher-undo) - (define-key map [remap advertised-undo] 'decipher-undo) + (define-key map "A" #'decipher-show-alphabet) + (define-key map "C" #'decipher-complete-alphabet) + (define-key map "D" #'decipher-digram-list) + (define-key map "F" #'decipher-frequency-count) + (define-key map "M" #'decipher-make-checkpoint) + (define-key map "N" #'decipher-adjacency-list) + (define-key map "R" #'decipher-restore-checkpoint) + (define-key map "U" #'decipher-undo) + (define-key map " " #'decipher-keypress) + (define-key map [remap undo] #'decipher-undo) + (define-key map [remap advertised-undo] #'decipher-undo) (let ((key ?a)) (while (<= key ?z) - (define-key map (vector key) 'decipher-keypress) + (define-key map (vector key) #'decipher-keypress) (cl-incf key))) map) "Keymap for Decipher mode.") @@ -161,24 +163,21 @@ the tail of the list." (defvar decipher-stats-mode-map (let ((map (make-keymap))) (suppress-keymap map) - (define-key map "D" 'decipher-digram-list) - (define-key map "F" 'decipher-frequency-count) - (define-key map "N" 'decipher-adjacency-list) + (define-key map "D" #'decipher-digram-list) + (define-key map "F" #'decipher-frequency-count) + (define-key map "N" #'decipher-adjacency-list) map) -"Keymap for Decipher-Stats mode.") + "Keymap for Decipher-Stats mode.") -(defvar decipher-mode-syntax-table nil - "Decipher mode syntax table") - -(if decipher-mode-syntax-table - () +(defvar decipher-mode-syntax-table (let ((table (make-syntax-table)) (c ?0)) (while (<= c ?9) (modify-syntax-entry c "_" table) ;Digits are not part of words (cl-incf c)) - (setq decipher-mode-syntax-table table))) + table) + "Decipher mode syntax table") (defvar-local decipher-alphabet nil) ;; This is an alist containing entries (PLAIN-CHAR . CIPHER-CHAR), @@ -214,7 +213,6 @@ list of such cons cells.") (defvar decipher--freqs) ;;;=================================================================== -;;; Code: ;;;=================================================================== ;; Main entry points: ;;-------------------------------------------------------------------- @@ -256,7 +254,7 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ -*-decipher-*-\n)\n\n") (decipher-mode)) ;;;###autoload -(defun decipher-mode () +(define-derived-mode decipher-mode nil "Decipher" "Major mode for decrypting monoalphabetic substitution ciphers. Lower-case letters enter plaintext. Upper-case letters are commands. @@ -272,16 +270,10 @@ The most useful commands are: Show adjacency list for current letter (lists letters appearing next to it) \\[decipher-make-checkpoint] Save the current cipher alphabet (checkpoint) \\[decipher-restore-checkpoint] Restore a saved cipher alphabet (checkpoint)" - (interactive) - (kill-all-local-variables) (setq buffer-undo-list t ;Disable undo - indent-tabs-mode nil ;Do not use tab characters - major-mode 'decipher-mode - mode-name "Decipher") + indent-tabs-mode nil) ;Do not use tab characters (if decipher-force-uppercase (setq case-fold-search nil)) ;Case is significant when searching - (use-local-map decipher-mode-map) - (set-syntax-table decipher-mode-syntax-table) (unless (= (point-min) (point-max)) (decipher-read-alphabet)) (setq-local font-lock-defaults @@ -291,7 +283,6 @@ The most useful commands are: (lambda () (setq buffer-read-only nil buffer-undo-list nil)) nil t) - (run-mode-hooks 'decipher-mode-hook) (setq buffer-read-only t)) (put 'decipher-mode 'mode-class 'special) @@ -314,10 +305,10 @@ The most useful commands are: ((= ?> first-char) nil) ((= ?\( first-char) - (setq decipher-function 'decipher-alphabet-keypress) + (setq decipher-function #'decipher-alphabet-keypress) t) ((= ?\) first-char) - (setq decipher-function 'decipher-alphabet-keypress) + (setq decipher-function #'decipher-alphabet-keypress) nil) (t (error "Bad location"))))) @@ -456,7 +447,7 @@ The most useful commands are: (decipher-insert plain-char) (setq case-fold-search t ;Case is not significant cipher-string (downcase cipher-string)) - (let ((font-lock-fontify-region-function 'ignore)) + (let ((font-lock-fontify-region-function #'ignore)) ;; insert-and-inherit will pick the right face automatically (while (search-forward-regexp "^:" nil t) (setq bound (point-at-eol)) @@ -868,12 +859,12 @@ Creates the statistics buffer if it doesn't exist." (aset decipher--after i (make-vector 27 0)))) (if decipher-ignore-spaces (progn - (decipher-loop-no-breaks 'decipher--analyze) + (decipher-loop-no-breaks #'decipher--analyze) ;; The first character of ciphertext was marked as following a space: (let ((i 26)) (while (>= (cl-decf i) 0) (aset (aref decipher--after i) 26 0)))) - (decipher-loop-with-breaks 'decipher--analyze)) + (decipher-loop-with-breaks #'decipher--analyze)) (message "Processing results...") (setcdr (last decipher--digram-list 2) nil) ;Delete the phony "* " digram ;; Sort the digram list by frequency and alphabetical order: @@ -954,18 +945,12 @@ Creates the statistics buffer if it doesn't exist." ;; Statistics Buffer: ;;==================================================================== -(defun decipher-stats-mode () +(define-derived-mode decipher-stats-mode nil "Decipher-Stats" "Major mode for displaying ciphertext statistics." - (interactive) - (kill-all-local-variables) (setq buffer-read-only t buffer-undo-list t ;Disable undo case-fold-search nil ;Case is significant when searching - indent-tabs-mode nil ;Do not use tab characters - major-mode 'decipher-stats-mode - mode-name "Decipher-Stats") - (use-local-map decipher-stats-mode-map) - (run-mode-hooks 'decipher-stats-mode-hook)) + indent-tabs-mode nil)) ;Do not use tab characters (put 'decipher-stats-mode 'mode-class 'special) ;;-------------------------------------------------------------------- @@ -1001,9 +986,8 @@ if it can't, it signals an error." (let ((stats-name (concat "*" (buffer-name) "*"))) (setq decipher-stats-buffer (if (eq 'decipher-stats-mode - (cdr-safe (assoc 'major-mode - (buffer-local-variables - (get-buffer stats-name))))) + (buffer-local-value 'major-mode + (get-buffer stats-name))) ;; We just lost track of the statistics buffer: (get-buffer stats-name) (generate-new-buffer stats-name)))) commit 1b4435e6ea6e7699e43f6079b111b42879fc7c47 Author: Stefan Monnier Date: Wed Feb 10 17:37:25 2021 -0500 * lisp/leim/quail: Use lexical-binding * lisp/leim/quail/hangul.el: * lisp/leim/quail/indian.el: * lisp/leim/quail/ipa.el: * lisp/leim/quail/japanese.el: * lisp/leim/quail/lao.el: * lisp/leim/quail/latin-ltx.el: * lisp/leim/quail/lrt.el: * lisp/leim/quail/sisheng.el: * lisp/leim/quail/thai.el: * lisp/leim/quail/tibetan.el: Use lexical-binding. * lisp/leim/quail/uni-input.el (ucs-input-method): Remove unused var `str`. diff --git a/lisp/leim/quail/hangul.el b/lisp/leim/quail/hangul.el index ca1aae77be..c03e86b33c 100644 --- a/lisp/leim/quail/hangul.el +++ b/lisp/leim/quail/hangul.el @@ -1,4 +1,4 @@ -;;; hangul.el --- Korean Hangul input method +;;; hangul.el --- Korean Hangul input method -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -88,9 +88,9 @@ (defvar hangul-im-keymap (let ((map (make-sparse-keymap))) - (define-key map "\d" 'hangul-delete-backward-char) - (define-key map [f9] 'hangul-to-hanja-conversion) - (define-key map [Hangul_Hanja] 'hangul-to-hanja-conversion) + (define-key map "\d" #'hangul-delete-backward-char) + (define-key map [f9] #'hangul-to-hanja-conversion) + (define-key map [Hangul_Hanja] #'hangul-to-hanja-conversion) map) "Keymap for Hangul method. It is used by all Hangul input methods.") @@ -337,7 +337,7 @@ Other parts are the same as a `hangul3-input-method-cho'." char))))) (aset hangul-queue 5 char))) (hangul-insert-character hangul-queue) - (if (zerop (apply '+ (append hangul-queue nil))) + (if (zerop (apply #'+ (append hangul-queue nil))) (hangul-insert-character (setq hangul-queue (vector 0 0 0 0 char 0))) (hangul-insert-character hangul-queue (setq hangul-queue (vector 0 0 0 0 char 0)))))) @@ -349,7 +349,7 @@ Other parts are the same as a `hangul3-input-method-cho'." (while (and (> i 0) (zerop (aref hangul-queue i))) (setq i (1- i))) (aset hangul-queue i 0)) - (if (notzerop (apply '+ (append hangul-queue nil))) + (if (notzerop (apply #'+ (append hangul-queue nil))) (hangul-insert-character hangul-queue) (delete-char -1))) @@ -514,16 +514,16 @@ When a Korean input method is off, convert the following hangul character." (defvar-local hangul-input-method-help-text nil) ;;;###autoload -(defun hangul-input-method-activate (input-method func help-text &rest args) +(defun hangul-input-method-activate (_input-method func help-text &rest _args) "Activate Hangul input method INPUT-METHOD. FUNC is a function to handle input key. HELP-TEXT is a text set in `hangul-input-method-help-text'." - (setq deactivate-current-input-method-function 'hangul-input-method-deactivate - describe-current-input-method-function 'hangul-input-method-help + (setq deactivate-current-input-method-function #'hangul-input-method-deactivate + describe-current-input-method-function #'hangul-input-method-help hangul-input-method-help-text help-text) (quail-delete-overlays) (if (eq (selected-window) (minibuffer-window)) - (add-hook 'minibuffer-exit-hook 'quail-exit-from-minibuffer)) + (add-hook 'minibuffer-exit-hook #'quail-exit-from-minibuffer)) (setq-local input-method-function func)) (defun hangul-input-method-deactivate () @@ -538,7 +538,7 @@ HELP-TEXT is a text set in `hangul-input-method-help-text'." (define-obsolete-function-alias 'hangul-input-method-inactivate - 'hangul-input-method-deactivate "24.3") + #'hangul-input-method-deactivate "24.3") (defun hangul-input-method-help () "Describe the current Hangul input method." diff --git a/lisp/leim/quail/ipa.el b/lisp/leim/quail/ipa.el index d9f58885f2..e805c6ad3b 100644 --- a/lisp/leim/quail/ipa.el +++ b/lisp/leim/quail/ipa.el @@ -1,4 +1,4 @@ -;;; ipa.el --- Quail package for inputting IPA characters -*-coding: utf-8;-*- +;;; ipa.el --- Quail package for inputting IPA characters -*- lexical-binding: t; -*- ;; Copyright (C) 2009-2021 Free Software Foundation, Inc. ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, @@ -276,7 +276,7 @@ string." (cl-assert (vectorp quail-keymap) t) (setq quail-keymap (append quail-keymap nil)))) (list - (apply 'vector + (apply #'vector (mapcar #'(lambda (entry) (cl-assert (char-or-string-p entry) t) @@ -502,9 +502,9 @@ of the mapping.") ;; diacritic. To avoid this, handle the input specially with the function ;; ipa-x-sampa-underscore-implosive. -(dolist (implosive-x-sampa (mapcar 'car ipa-x-sampa-implosive-submap)) +(dolist (implosive-x-sampa (mapcar #'car ipa-x-sampa-implosive-submap)) (setq implosive-x-sampa (car (split-string implosive-x-sampa "_"))) (quail-defrule (format "%s_" implosive-x-sampa) - 'ipa-x-sampa-underscore-implosive)) + #'ipa-x-sampa-underscore-implosive)) ;;; ipa.el ends here diff --git a/lisp/leim/quail/japanese.el b/lisp/leim/quail/japanese.el index a4ea550c26..6a2bcdc9ed 100644 --- a/lisp/leim/quail/japanese.el +++ b/lisp/leim/quail/japanese.el @@ -1,4 +1,4 @@ -;;; japanese.el --- Quail package for inputting Japanese +;;; japanese.el --- Quail package for inputting Japanese -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, @@ -412,7 +412,7 @@ C-h kkc-help List these key bindings. " nil t t nil nil nil nil nil - 'quail-japanese-update-translation + #'quail-japanese-update-translation '(("K" . quail-japanese-toggle-kana) (" " . quail-japanese-kanji-kkc) ("\C-m" . quail-no-conversion) @@ -491,7 +491,7 @@ qh: shift to the input method `japanese', qq: toggle between this input method and the input method `japanese-ascii'. " nil t t nil nil nil nil nil - 'quail-japanese-hankaku-update-translation) + #'quail-japanese-hankaku-update-translation) (dolist (elt quail-japanese-transliteration-rules) (quail-defrule (car elt) @@ -517,7 +517,7 @@ qq: toggle between this input method and the input method `japanese-ascii'. nil "Japanese hiragana input method by Roman transliteration." nil t t nil nil nil nil nil - 'quail-japanese-update-translation) + #'quail-japanese-update-translation) ;; Use the same map as that of `japanese'. (setcar (cdr (cdr quail-current-package)) @@ -538,7 +538,7 @@ qq: toggle between this input method and the input method `japanese-ascii'. nil "Japanese katakana input method by Roman transliteration." nil t t nil nil nil nil nil - 'quail-japanese-katakana-update-translation) + #'quail-japanese-katakana-update-translation) (dolist (elt quail-japanese-transliteration-rules) (quail-defrule (car elt) diff --git a/lisp/leim/quail/lao.el b/lisp/leim/quail/lao.el index af3b589262..a932460a20 100644 --- a/lisp/leim/quail/lao.el +++ b/lisp/leim/quail/lao.el @@ -1,4 +1,4 @@ -;;; lao.el --- Quail package for inputting Lao characters -*-coding: utf-8;-*- +;;; lao.el --- Quail package for inputting Lao characters -*- lexical-binding: t; -*- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, ;; 2006, 2007, 2008, 2009, 2010, 2011 @@ -195,7 +195,7 @@ you need to re-load it to properly re-initialize related alists.") (quail-define-package "lao" "Lao" "ລ" t "Lao input method simulating Lao keyboard layout based on Thai TIS620" - nil t t t t nil nil nil 'quail-lao-update-translation nil t) + nil t t t t nil nil nil #'quail-lao-update-translation nil t) (quail-install-map (quail-map-from-table diff --git a/lisp/leim/quail/latin-ltx.el b/lisp/leim/quail/latin-ltx.el index fd78253c4f..8b1e520361 100644 --- a/lisp/leim/quail/latin-ltx.el +++ b/lisp/leim/quail/latin-ltx.el @@ -1,4 +1,4 @@ -;;; latin-ltx.el --- Quail package for TeX-style input -*-coding: utf-8;-*- +;;; latin-ltx.el --- Quail package for TeX-style input -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, diff --git a/lisp/leim/quail/lrt.el b/lisp/leim/quail/lrt.el index e05bc1e6cb..68eaeb58ec 100644 --- a/lisp/leim/quail/lrt.el +++ b/lisp/leim/quail/lrt.el @@ -1,4 +1,4 @@ -;;; lrt.el --- Quail package for inputting Lao characters by LRT method -*-coding: utf-8;-*- +;;; lrt.el --- Quail package for inputting Lao characters by LRT method -*- lexical-binding: t; -*- ;; Copyright (C) 1998, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, @@ -60,7 +60,7 @@ `\\' (backslash) + `$' => ຯ LAO ELLIPSIS " nil 'forget-last-selection 'deterministic 'kbd-translate 'show-layout - nil nil nil 'quail-lrt-update-translation nil t) + nil nil nil #'quail-lrt-update-translation nil t) ;; LRT (Lao Roman Transcription) input method accepts the following ;; key sequence: diff --git a/lisp/leim/quail/sisheng.el b/lisp/leim/quail/sisheng.el index 8e7a500276..aa35bb0574 100644 --- a/lisp/leim/quail/sisheng.el +++ b/lisp/leim/quail/sisheng.el @@ -1,4 +1,4 @@ -;;; sisheng.el --- sisheng input method for Chinese pinyin transliteration +;;; sisheng.el --- sisheng input method for Chinese pinyin transliteration -*- lexical-binding: t; -*- ;; Copyright (C) 2004-2021 Free Software Foundation, Inc. diff --git a/lisp/leim/quail/thai.el b/lisp/leim/quail/thai.el index 7cf11daf9d..07ba657f9b 100644 --- a/lisp/leim/quail/thai.el +++ b/lisp/leim/quail/thai.el @@ -1,4 +1,4 @@ -;;; thai.el --- Quail package for inputting Thai characters -*-coding: utf-8;-*- +;;; thai.el --- Quail package for inputting Thai characters -*- lexical-binding: t; -*- ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, ;; 2005, 2006, 2007, 2008, 2009, 2010, 2011 diff --git a/lisp/leim/quail/tibetan.el b/lisp/leim/quail/tibetan.el index a54763d56f..33cc6f5965 100644 --- a/lisp/leim/quail/tibetan.el +++ b/lisp/leim/quail/tibetan.el @@ -1,4 +1,4 @@ -;;; tibetan.el --- Quail package for inputting Tibetan characters -*-coding: utf-8-emacs;-*- +;;; tibetan.el --- Quail package for inputting Tibetan characters -*-coding: utf-8-emacs; lexical-binding: t; -*- ;; Copyright (C) 1997, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, @@ -158,7 +158,7 @@ Tsheg is assigned to SPC. Space is assigned to period `.'. " nil nil nil nil nil nil nil nil - 'quail-tibetan-update-translation) + #'quail-tibetan-update-translation) ;; Here we build up a Quail map for a Tibetan sequence the whole of ;; which can be one composition. @@ -371,7 +371,7 @@ (setq trans-list (cons trans trans-list) i last) (setq trans-list nil i len)))) - (apply 'concat (nreverse trans-list)))) + (apply #'concat (nreverse trans-list)))) (defvar quail-tibkey-characters nil) @@ -440,7 +440,7 @@ I hope I'll complete in a future revision. " nil nil nil nil nil nil nil nil - 'quail-tibkey-update-translation) + #'quail-tibkey-update-translation) (quail-install-map (quail-map-from-table diff --git a/lisp/leim/quail/uni-input.el b/lisp/leim/quail/uni-input.el index c7cf6abe2a..bfe4ce6f12 100644 --- a/lisp/leim/quail/uni-input.el +++ b/lisp/leim/quail/uni-input.el @@ -1,4 +1,4 @@ -;;; uni-input.el --- Hex Unicode input method +;;; uni-input.el --- Hex Unicode input method -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 @@ -57,11 +57,12 @@ (echo-keystrokes 0) (help-char nil) (events (list key)) - (str " ")) + ;; (str " ") + ) (unwind-protect (catch 'non-digit (progn - (dotimes (i 4) + (dotimes (_ 4) (let ((seq (read-key-sequence nil)) key) (if (and (stringp seq) @@ -76,7 +77,7 @@ (throw 'non-digit (append (reverse events) (listify-key-sequence seq)))))) (quail-delete-region) - (let ((n (string-to-number (apply 'string + (let ((n (string-to-number (apply #'string (cdr (nreverse events))) 16))) (if (characterp n) @@ -100,12 +101,12 @@ While this input method is active, the variable (quail-delete-overlays) (setq describe-current-input-method-function nil)) (kill-local-variable 'input-method-function)) - (setq deactivate-current-input-method-function 'ucs-input-deactivate) - (setq describe-current-input-method-function 'ucs-input-help) + (setq deactivate-current-input-method-function #'ucs-input-deactivate) + (setq describe-current-input-method-function #'ucs-input-help) (quail-delete-overlays) (if (eq (selected-window) (minibuffer-window)) - (add-hook 'minibuffer-exit-hook 'quail-exit-from-minibuffer)) - (setq-local input-method-function 'ucs-input-method))) + (add-hook 'minibuffer-exit-hook #'quail-exit-from-minibuffer)) + (setq-local input-method-function #'ucs-input-method))) (defun ucs-input-deactivate () "Deactivate UCS input method." @@ -114,7 +115,7 @@ While this input method is active, the variable (define-obsolete-function-alias 'ucs-input-inactivate - 'ucs-input-deactivate "24.3") + #'ucs-input-deactivate "24.3") (defun ucs-input-help () (interactive) commit 8d33cc53a2d0ce893afad77703ba361593896084 Author: Stefan Monnier Date: Wed Feb 10 17:35:31 2021 -0500 * lisp/leim/quail: Use lexical-binding * lisp/leim/quail/hangul.el: * lisp/leim/quail/indian.el: * lisp/leim/quail/ipa.el: * lisp/leim/quail/japanese.el: * lisp/leim/quail/lao.el: * lisp/leim/quail/latin-ltx.el: * lisp/leim/quail/lrt.el: * lisp/leim/quail/sisheng.el: * lisp/leim/quail/thai.el: * lisp/leim/quail/tibetan.el: Use lexical-binding. * lisp/leim/quail/uni-input.el (ucs-input-method): Remove unused var `str`. diff --git a/lisp/leim/quail/indian.el b/lisp/leim/quail/indian.el index 6f5054e3f6..2e36508273 100644 --- a/lisp/leim/quail/indian.el +++ b/lisp/leim/quail/indian.el @@ -1,4 +1,4 @@ -;;; indian.el --- Quail packages for inputting Indian +;;; indian.el --- Quail packages for inputting Indian -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. @@ -39,7 +39,7 @@ (defun quail-define-indian-trans-package (hashtbls pkgname lang title doc) - (funcall 'quail-define-package pkgname lang title t doc + (quail-define-package pkgname lang title t doc nil nil nil nil nil nil t nil) (maphash (lambda (key val) @@ -200,7 +200,7 @@ (setq clm 6) (dolist (v vowels) - (apply 'insert (propertize "\t" 'display (list 'space :align-to clm)) + (apply #'insert (propertize "\t" 'display (list 'space :align-to clm)) (if (nth 1 c) (list (nth 1 c) (nth 2 v)) (list ""))) (setq clm (+ clm 6)))) (insert "\n") @@ -309,7 +309,7 @@ Full key sequences are listed below:") (defun quail-define-inscript-package (char-tables key-tables pkgname lang title docstring) - (funcall 'quail-define-package pkgname lang title nil docstring + (quail-define-package pkgname lang title nil docstring nil nil nil t nil nil nil nil) (let (char-table key-table char key) (while (and char-tables key-tables) @@ -627,7 +627,7 @@ Full key sequences are listed below:") (quail-define-package "malayalam-mozhi" "Malayalam" "MlmMI" t "Malayalam transliteration by Mozhi method." nil nil t nil nil nil t nil - 'indian-mlm-mozhi-update-translation) + #'indian-mlm-mozhi-update-translation) (maphash (lambda (key val) @@ -636,9 +636,9 @@ Full key sequences are listed below:") (vector val)))) (cdr indian-mlm-mozhi-hash)) -(defun indian-mlm-mozhi-underscore (key len) (throw 'quail-tag nil)) +(defun indian-mlm-mozhi-underscore (_key _len) (throw 'quail-tag nil)) -(quail-defrule "_" 'indian-mlm-mozhi-underscore) +(quail-defrule "_" #'indian-mlm-mozhi-underscore) (quail-defrule "|" ?‌) (quail-defrule "||" ?​) commit 5a598fa41491132758810649ddbb565d44142f76 Author: Stefan Monnier Date: Wed Feb 10 16:39:53 2021 -0500 * lisp/subr.el (combine-change-calls-1): Don't presume integer args This avoids problems where the `after-change-functions` end up called with the new length rather than the old length. diff --git a/lisp/subr.el b/lisp/subr.el index 6573090ebe..eb28728760 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4330,6 +4330,8 @@ the specified region. It must not change Additionally, the buffer modifications of BODY are recorded on the buffer's undo list as a single (apply ...) entry containing the function `undo--wrap-and-run-primitive-undo'." + (if (markerp beg) (setq beg (marker-position beg))) + (if (markerp end) (setq end (marker-position end))) (let ((old-bul buffer-undo-list) (end-marker (copy-marker end t)) result) commit 29c47ac19a393d2544562fe8932bc4e1b6ddd7c9 Author: Stefan Monnier Date: Wed Feb 10 16:06:24 2021 -0500 * lisp/emacs-lisp/macroexp.el (macroexp--fgrep): Break cycles * test/lisp/emacs-lisp/macroexp-tests.el: New file. diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index 042061c44f..13ff5ef2ed 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -572,20 +572,35 @@ test of free variables in the following ways: - For the same reason it may cause the result to fail to include bindings which will be used if SEXP is not yet fully macro-expanded and the use of the binding will only be revealed by macro expansion." - (let ((res '())) - (while (and (consp sexp) bindings) - (dolist (binding (macroexp--fgrep bindings (pop sexp))) - (push binding res) - (setq bindings (remove binding bindings)))) - (if (or (vectorp sexp) (byte-code-function-p sexp)) - ;; With backquote, code can appear within vectors as well. - ;; This wouldn't be needed if we `macroexpand-all' before - ;; calling macroexp--fgrep, OTOH. - (macroexp--fgrep bindings (mapcar #'identity sexp)) - (let ((tmp (assq sexp bindings))) - (if tmp - (cons tmp res) - res))))) + (let ((res '()) + ;; Cyclic code should not happen, but code can contain cyclic data :-( + (seen (make-hash-table :test #'eq)) + (sexpss (list (list sexp)))) + ;; Use a nested while loop to reduce the amount of heap allocations for + ;; pushes to `sexpss' and the `gethash' overhead. + (while (and sexpss bindings) + (let ((sexps (pop sexpss))) + (unless (gethash sexps seen) + (puthash sexps t seen) ;; Using `setf' here causes bootstrap problems. + (if (vectorp sexps) (setq sexps (mapcar #'identity sexps))) + (let ((tortoise sexps) (skip t)) + (while sexps + (let ((sexp (if (consp sexps) (pop sexps) + (prog1 sexps (setq sexps nil))))) + (if skip + (setq skip nil) + (setq tortoise (cdr tortoise)) + (if (eq tortoise sexps) + (setq sexps nil) ;; Found a cycle: we're done! + (setq skip t))) + (cond + ((or (consp sexp) (vectorp sexp)) (push sexp sexpss)) + (t + (let ((tmp (assq sexp bindings))) + (when tmp + (push tmp res) + (setq bindings (remove tmp bindings)))))))))))) + res)) ;;; Load-time macro-expansion. diff --git a/test/lisp/emacs-lisp/macroexp-tests.el b/test/lisp/emacs-lisp/macroexp-tests.el new file mode 100644 index 0000000000..1124e3b8d9 --- /dev/null +++ b/test/lisp/emacs-lisp/macroexp-tests.el @@ -0,0 +1,36 @@ +;;; macroexp-tests.el --- Tests for macroexp.el -*- lexical-binding: t; -*- + +;; Copyright (C) 2021 Stefan Monnier + +;; Author: Stefan Monnier +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; + +;;; Code: + +(ert-deftest macroexp--tests-fgrep () + (should (equal (macroexp--fgrep '((x) (y)) '([x] z ((u)))) + '((x)))) + (should (equal (macroexp--fgrep '((x) (y)) '#2=([y] ((y #2#)))) + '((y)))) + (should (equal (macroexp--fgrep '((x) (y)) '#2=([r] ((a x)) a b c d . #2#)) + '((x))))) + +(provide 'macroexp-tests) +;;; macroexp-tests.el ends here commit 6bfdfeed36fab4680c8db90c22da8f6611694186 Author: Juri Linkov Date: Wed Feb 10 21:37:47 2021 +0200 Fix ediff even/odd faces to increase their contrast and readability * lisp/vc/ediff-init.el (ediff-even-diff-A, ediff-even-diff-B) (ediff-even-diff-C, ediff-even-diff-Ancestor, ediff-odd-diff-A) (ediff-odd-diff-B, ediff-odd-diff-C): Add :distant-foreground "Black" for light background. For dark background add :distant-foreground "White", and use darker shades of grey for background colors (bug#46396). diff --git a/lisp/vc/ediff-init.el b/lisp/vc/ediff-init.el index 6e658163b9..3f33e6aae2 100644 --- a/lisp/vc/ediff-init.el +++ b/lisp/vc/ediff-init.el @@ -980,8 +980,10 @@ this variable represents.") (defface ediff-even-diff-A `((((type pc)) (:foreground "green3" :background "light grey" :extend t)) - (((class color) (min-colors 88)) - (:background "light grey" :extend t)) + (((class color) (min-colors 88) (background light)) + (:distant-foreground "Black" :background "light grey" :extend t)) + (((class color) (min-colors 88) (background dark)) + (:distant-foreground "White" :background "dark grey" :extend t)) (((class color) (min-colors 16)) (:foreground "Black" :background "light grey" :extend t)) (((class color)) @@ -999,8 +1001,10 @@ widget to customize the actual face object `ediff-even-diff-A' this variable represents.") (defface ediff-even-diff-B - `((((class color) (min-colors 88)) - (:background "Grey" :extend t)) + `((((class color) (min-colors 88) (background light)) + (:distant-foreground "Black" :background "Grey" :extend t)) + (((class color) (min-colors 88) (background dark)) + (:distant-foreground "White" :background "dim grey" :extend t)) (((class color) (min-colors 16)) (:foreground "White" :background "Grey" :extend t)) (((class color)) @@ -1019,8 +1023,10 @@ this variable represents.") (defface ediff-even-diff-C `((((type pc)) (:foreground "yellow3" :background "light grey" :extend t)) - (((class color) (min-colors 88)) - (:background "light grey" :extend t)) + (((class color) (min-colors 88) (background light)) + (:distant-foreground "Black" :background "light grey" :extend t)) + (((class color) (min-colors 88) (background dark)) + (:distant-foreground "White" :background "dark grey" :extend t)) (((class color) (min-colors 16)) (:foreground "Black" :background "light grey" :extend t)) (((class color)) @@ -1040,8 +1046,10 @@ this variable represents.") (defface ediff-even-diff-Ancestor `((((type pc)) (:foreground "cyan3" :background "light grey" :extend t)) - (((class color) (min-colors 88)) - (:background "Grey" :extend t)) + (((class color) (min-colors 88) (background light)) + (:distant-foreground "Black" :background "Grey" :extend t)) + (((class color) (min-colors 88) (background dark)) + (:distant-foreground "White" :background "dim grey" :extend t)) (((class color) (min-colors 16)) (:foreground "White" :background "Grey" :extend t)) (((class color)) @@ -1068,8 +1076,10 @@ this variable represents.") (defface ediff-odd-diff-A '((((type pc)) (:foreground "green3" :background "gray40" :extend t)) - (((class color) (min-colors 88)) - (:background "Grey" :extend t)) + (((class color) (min-colors 88) (background light)) + (:distant-foreground "Black" :background "Grey" :extend t)) + (((class color) (min-colors 88) (background dark)) + (:distant-foreground "White" :background "dim grey" :extend t)) (((class color) (min-colors 16)) (:foreground "White" :background "Grey" :extend t)) (((class color)) @@ -1088,8 +1098,10 @@ this variable represents.") (defface ediff-odd-diff-B '((((type pc)) (:foreground "White" :background "gray40" :extend t)) - (((class color) (min-colors 88)) - (:background "light grey" :extend t)) + (((class color) (min-colors 88) (background light)) + (:distant-foreground "Black" :background "light grey" :extend t)) + (((class color) (min-colors 88) (background dark)) + (:distant-foreground "White" :background "dark grey" :extend t)) (((class color) (min-colors 16)) (:foreground "Black" :background "light grey" :extend t)) (((class color)) @@ -1108,8 +1120,10 @@ this variable represents.") (defface ediff-odd-diff-C '((((type pc)) (:foreground "yellow3" :background "gray40" :extend t)) - (((class color) (min-colors 88)) - (:background "Grey" :extend t)) + (((class color) (min-colors 88) (background light)) + (:distant-foreground "Black" :background "Grey" :extend t)) + (((class color) (min-colors 88) (background dark)) + (:distant-foreground "White" :background "dim grey" :extend t)) (((class color) (min-colors 16)) (:foreground "White" :background "Grey" :extend t)) (((class color)) commit 81e55fa6c37d51845b50ae22a935185cd441e99b Author: Lars Ingebrigtsen Date: Wed Feb 10 20:37:10 2021 +0100 Fix build problem with previous facemenu change * lisp/facemenu.el (facemenu-add-face-function): Move to avoid a warning. (list-colors-display): Autoload. diff --git a/lisp/facemenu.el b/lisp/facemenu.el index dc5f8f46ab..6290b02add 100644 --- a/lisp/facemenu.el +++ b/lisp/facemenu.el @@ -85,10 +85,6 @@ ;;; Code: -;; Global bindings: -(define-key global-map [C-down-mouse-2] 'facemenu-menu) -(define-key global-map "\M-o" 'facemenu-keymap) - (defgroup facemenu nil "Create a face menu for interactively adding fonts to text." :group 'faces diff --git a/lisp/loadup.el b/lisp/loadup.el index 3ee8bed184..c91c00a107 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -253,6 +253,7 @@ (load "startup") (load "term/tty-colors") (load "font-core") +(load "facemenu") (load "emacs-lisp/syntax") (load "font-lock") (load "jit-lock") @@ -491,7 +492,9 @@ lost after dumping"))) (defun facemenu-keymap-restore () "Restore the facemenu keymap." - (require 'facemenu) + ;; Global bindings: + (define-key global-map [C-down-mouse-2] 'facemenu-menu) + (define-key global-map "\M-o" 'facemenu-keymap) (define-key facemenu-keymap "\eS" 'center-paragraph) (define-key facemenu-keymap "\es" 'center-line)) commit 4467073c50d2c7fbbb30530d1a0a25f8272ff56f Author: Paul Eggert Date: Wed Feb 10 10:55:42 2021 -0800 Simplify and speed up after-find-file Use newer primitives like file-accessible-directory-p to simplify and speed up longstanding code in after-find-file. * lisp/files.el (after-find-file): Prefer file-exists-p + file-symlink-p to file-attributes + file-symlink-p + file-chase-links + file-exists-p. Prefer file-accessible-directory-p to directory-file-name + file-attributes. Prefer file-directory-p to file-name-directory + file-exists-p. diff --git a/lisp/files.el b/lisp/files.el index dada69c145..9ff8f31e37 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -2530,13 +2530,11 @@ unless NOMODES is non-nil." (msg (cond ((not warn) nil) - ((and error (file-attributes buffer-file-name)) + ((and error (file-exists-p buffer-file-name)) (setq buffer-read-only t) - (if (and (file-symlink-p buffer-file-name) - (not (file-exists-p - (file-chase-links buffer-file-name)))) - "Symbolic link that points to nonexistent file" - "File exists, but cannot be read")) + "File exists, but cannot be read") + ((and error (file-symlink-p buffer-file-name)) + "Symbolic link that points to nonexistent file") ((not buffer-read-only) (if (and warn ;; No need to warn if buffer is auto-saved @@ -2553,13 +2551,12 @@ unless NOMODES is non-nil." ((not error) (setq not-serious t) "Note: file is write protected") - ((file-attributes (directory-file-name default-directory)) + ((file-accessible-directory-p default-directory) "File not found and directory write-protected") - ((file-exists-p (file-name-directory buffer-file-name)) - (setq buffer-read-only nil)) (t (setq buffer-read-only nil) - "Use M-x make-directory RET RET to create the directory and its parents")))) + (unless (file-directory-p default-directory) + "Use M-x make-directory RET RET to create the directory and its parents"))))) (when msg (message "%s" msg) (or not-serious (sit-for 1 t)))) commit 4459dcc07865f6ae1f21f624fcb09cf8fdaecdb5 Author: Paul Eggert Date: Wed Feb 10 10:50:44 2021 -0800 Fix file lock issue (Bug#46397) * src/filelock.c (current_lock_owner): Also treat ENOTDIR as meaning the lock file does not exist. diff --git a/src/filelock.c b/src/filelock.c index 35baa0c666..373fc00a42 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -532,7 +532,7 @@ current_lock_owner (lock_info_type *owner, char *lfname) /* If nonexistent lock file, all is well; otherwise, got strange error. */ lfinfolen = read_lock_data (lfname, owner->user); if (lfinfolen < 0) - return errno == ENOENT ? 0 : errno; + return errno == ENOENT || errno == ENOTDIR ? 0 : errno; if (MAX_LFINFO < lfinfolen) return ENAMETOOLONG; owner->user[lfinfolen] = 0; commit 21e475ea0c0d04ae7634f377ed64fe179388b133 Author: Lars Ingebrigtsen Date: Wed Feb 10 19:38:10 2021 +0100 Remove the 'M-o' ('facemap-keymap') binding experimentally * doc/lispref/maps.texi (Standard Keymaps): * doc/lispref/keymaps.texi (Prefix Keys): Remove mentions. * etc/facemenu-removal.txt: New temporary file. * lisp/loadup.el: Don't load facemenu.el. (removed-facemenu-command): New command. (facemenu-keymap-restore): New function. * lisp/textmodes/text-mode.el (center-paragraph): Remove binding. (center-line): Remove binding. diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi index 55d179b875..6a227e3a79 100644 --- a/doc/lispref/keymaps.texi +++ b/doc/lispref/keymaps.texi @@ -573,12 +573,6 @@ key. @code{search-map} is the global keymap used for the @kbd{M-s} prefix key. -@item -@cindex @kbd{M-o} -@vindex facemenu-keymap -@code{facemenu-keymap} is the global keymap used for the @kbd{M-o} -prefix key. - @item The other Emacs prefix keys are @kbd{C-x @@}, @kbd{C-x a i}, @kbd{C-x @key{ESC}} and @kbd{@key{ESC} @key{ESC}}. They use keymaps that have diff --git a/doc/lispref/maps.texi b/doc/lispref/maps.texi index aea0242408..59c6e6f57a 100644 --- a/doc/lispref/maps.texi +++ b/doc/lispref/maps.texi @@ -53,9 +53,6 @@ A sparse keymap for subcommands of the prefix @kbd{C-x r}.@* @item esc-map A full keymap for @key{ESC} (or @key{Meta}) commands. -@item facemenu-keymap -A sparse keymap used for the @kbd{M-o} prefix key. - @item function-key-map The parent keymap of all @code{local-function-key-map} (q.v.@:) instances. diff --git a/etc/NEWS b/etc/NEWS index 3cbf2a0fe7..67fc49f181 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2048,6 +2048,11 @@ first). * Incompatible Editing Changes in Emacs 28.1 +** The 'M-o' ('facemanu-keymap') global binding has been removed. + +** The 'M-o M-s' and 'M-o M-S' global bindings have been removed. +Use 'M-x center-line' and 'M-x center-paragraph' instead. + ** In 'f90-mode', the backslash character ('\') no longer escapes. For about a decade, the backslash character has no longer had a special escape syntax in Fortran F90. To get the old behaviour back, diff --git a/etc/facemenu-removal.txt b/etc/facemenu-removal.txt new file mode 100644 index 0000000000..9a969df0e4 --- /dev/null +++ b/etc/facemenu-removal.txt @@ -0,0 +1,20 @@ +`facemenu-keymap' (normally bound to `M-o') has been disabled. +============================================================== + +We've disabled the normal `M-o' keymap for a month (until March the +10th, 2021) in the development version of Emacs to see whether anybody +uses this feature. + +If the removal of this key binding doesn't annoy too many people, the +plan is to then leave the it unbound, for usage by third-party +packages and users. + +If you wish to restore the binding during the trial period, you can +put the following in your .emacs file: + +(facemenu-keymap-restore) + +After the trial period is over, the function will be removed. + +If you wish to protest the removal of the `M-o' key binding, please +send your thoughts to the emacs-devel@gnu.org mailing list. diff --git a/lisp/loadup.el b/lisp/loadup.el index 9cee6a2fd8..3ee8bed184 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -253,9 +253,6 @@ (load "startup") (load "term/tty-colors") (load "font-core") -;; facemenu must be loaded before font-lock, because `facemenu-keymap' -;; needs to be defined when font-lock is loaded. -(load "facemenu") (load "emacs-lisp/syntax") (load "font-lock") (load "jit-lock") @@ -477,6 +474,28 @@ lost after dumping"))) ;; Make sure we will attempt bidi reordering henceforth. (setq redisplay--inhibit-bidi nil) + +;; Experimental feature removal. +(define-key global-map "\M-o" #'removed-facemenu-command) + +(defun removed-facemenu-command () + "Transition command during test period for facemenu removal." + (interactive) + (switch-to-buffer "*Facemenu Removal*") + (let ((inhibit-read-only t)) + (erase-buffer) + (insert-file-contents + (expand-file-name "facemenu-removal.txt" data-directory))) + (goto-char (point-min)) + (special-mode)) + +(defun facemenu-keymap-restore () + "Restore the facemenu keymap." + (require 'facemenu) + (define-key facemenu-keymap "\eS" 'center-paragraph) + (define-key facemenu-keymap "\es" 'center-line)) + + (if dump-mode (let ((output (cond ((equal dump-mode "pdump") "emacs.pdmp") ((equal dump-mode "dump") "emacs") diff --git a/lisp/textmodes/text-mode.el b/lisp/textmodes/text-mode.el index 1432ab6a30..ab9f7b9c7c 100644 --- a/lisp/textmodes/text-mode.el +++ b/lisp/textmodes/text-mode.el @@ -169,8 +169,6 @@ both existing buffers and buffers that you subsequently create." (if enable-mode "enabled" "disabled")))) -(define-key facemenu-keymap "\eS" 'center-paragraph) - (defun center-paragraph () "Center each nonblank line in the paragraph at or after point. See `center-line' for more info." @@ -198,8 +196,6 @@ See `center-line' for more info." (center-line)) (forward-line 1))))) -(define-key facemenu-keymap "\es" 'center-line) - (defun center-line (&optional nlines) "Center the line point is on, within the width specified by `fill-column'. This means adjusting the indentation so that it equals commit 2e5d400ca6d7619cb4c0bcbd8abf5828127c77bf Author: Stefan Monnier Date: Wed Feb 10 13:12:09 2021 -0500 * lisp/emacs-lisp/edebug.el: Tweak last change Use generic functions i.s.o `edebug--spec-op-function`. : No need to register the &foo and :foo handler any more. (edebug--handle-&-spec-op, edebug--handle-:-spec-op): New generic functions. (edebug-match-specs): Use them. (edebug--get-spec-op): Remove function. (edebug-match-&optional, edebug-match-&rest, edebug-match-&or) (edebug-match-¬, edebug-match-&key, edebug-match-&error) (edebug-match-&define): Turn functions into methods of `edebug--handle-&-spec-op`. (edebug-match-:name, edebug-match-:unique): Turn functions into methods of `edebug--handle-:-spec-op`. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 176f61402a..0733dcec27 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -1687,10 +1687,10 @@ contains a circular object." (first-char (and (symbolp spec) (aref (symbol-name spec) 0))) (match (cond ((eq ?& first-char);; "&" symbols take all following specs. - (funcall (edebug--get-spec-op spec) cursor (cdr specs))) + (edebug--handle-&-spec-op spec cursor (cdr specs))) ((eq ?: first-char);; ":" symbols take one following spec. (setq rest (cdr (cdr specs))) - (funcall (edebug--get-spec-op spec) cursor (car (cdr specs)))) + (edebug--handle-:-spec-op spec cursor (car (cdr specs)))) (t;; Any other normal spec. (setq rest (cdr specs)) (edebug-match-one-spec cursor spec))))) @@ -1743,30 +1743,6 @@ contains a circular object." )) (put (car pair) 'edebug-form-spec (cdr pair))) -;; Spec operators are things like `&or' and `&define': they are not -;; themselves specs matching sexps but rather ways to combine specs. -;; Contrary to spec matchers (which take 1 arg), they take 2 arguments. -;; Their name can either start with `&' or `:' and they are called -;; differently depending on this difference (The ones whose name -;; starts with `:' only handle&receive the subsequent element, -;; whereas the ones whose name starts with `&' handle&receive -;; everything that follows). -(dolist (pair '((&optional . edebug-match-&optional) - (&rest . edebug-match-&rest) - (&or . edebug-match-&or) - (&define . edebug-match-&define) - (¬ . edebug-match-¬) - (&key . edebug-match-&key) - (&error . edebug-match-&error) - (:name . edebug-match-:name) - (:unique . edebug-match-:unique) - )) - (put (car pair) 'edebug--spec-op-function (cdr pair))) - -(defun edebug--get-spec-op (name) - "Return the function that handles the spec operator NAME." - (get name 'edebug--spec-op-function)) - (defun edebug-match-symbol (cursor symbol) ;; Match a symbol spec. (let* ((spec (get-edebug-spec symbol))) @@ -1808,7 +1784,7 @@ contains a circular object." (defsubst edebug-match-body (cursor) (edebug-forms cursor)) -(defun edebug-match-&optional (cursor specs) +(cl-defmethod edebug--handle-&-spec-op ((_ (eql &optional)) cursor specs) ;; Keep matching until one spec fails. (edebug-&optional-wrapper cursor specs 'edebug-&optional-wrapper)) @@ -1834,7 +1810,11 @@ contains a circular object." ;; Reuse the &optional handler with this as the remainder handler. (edebug-&optional-wrapper cursor specs remainder-handler)) -(defun edebug-match-&rest (cursor specs) +(cl-defgeneric edebug--handle-&-spec-op (op cursor specs) + "Handle &foo spec operators. +&foo spec operators operate on all the subsequent SPECS.") + +(cl-defmethod edebug--handle-&-spec-op ((_ (eql &rest)) cursor specs) ;; Repeatedly use specs until failure. (let ((edebug-&rest specs) ;; remember these edebug-best-error @@ -1842,7 +1822,7 @@ contains a circular object." (edebug-&rest-wrapper cursor specs 'edebug-&rest-wrapper))) -(defun edebug-match-&or (cursor specs) +(cl-defmethod edebug--handle-&-spec-op ((_ (eql &or)) cursor specs) ;; Keep matching until one spec succeeds, and return its results. ;; If none match, fail. ;; This needs to be optimized since most specs spend time here. @@ -1867,23 +1847,24 @@ contains a circular object." )) -(defun edebug-match-¬ (cursor specs) +(cl-defmethod edebug--handle-&-spec-op ((_ (eql ¬)) cursor specs) ;; If any specs match, then fail (if (null (catch 'no-match (let ((edebug-gate nil)) (save-excursion - (edebug-match-&or cursor specs))) + (edebug--handle-&-spec-op '&or cursor specs))) nil)) ;; This means something matched, so it is a no match. (edebug-no-match cursor "Unexpected")) ;; This means nothing matched, so it is OK. nil) ;; So, return nothing -(defun edebug-match-&key (cursor specs) +(cl-defmethod edebug--handle-&-spec-op ((_ (eql &key)) cursor specs) ;; Following specs must look like ( ) ... ;; where is the name of a keyword, and spec is its spec. ;; This really doesn't save much over the expanded form and takes time. - (edebug-match-&rest + (edebug--handle-&-spec-op + '&rest cursor (cons '&or (mapcar (lambda (pair) @@ -1891,7 +1872,7 @@ contains a circular object." (car (cdr pair)))) specs)))) -(defun edebug-match-&error (cursor specs) +(cl-defmethod edebug--handle-&-spec-op ((_ (eql &error)) cursor specs) ;; Signal an error, using the following string in the spec as argument. (let ((error-string (car specs)) (edebug-error-point (edebug-before-offset cursor))) @@ -1995,7 +1976,7 @@ contains a circular object." (defun edebug-match-function (_cursor) (error "Use function-form instead of function in edebug spec")) -(defun edebug-match-&define (cursor specs) +(cl-defmethod edebug--handle-&-spec-op ((_ (eql &define)) cursor specs) ;; Match a defining form. ;; Normally, &define is interpreted specially other places. ;; This should only be called inside of a spec list to match the remainder @@ -2049,7 +2030,11 @@ contains a circular object." (edebug-move-cursor cursor) (list name))) -(defun edebug-match-:name (_cursor spec) +(cl-defgeneric edebug--handle-:-spec-op (op cursor spec) + "Handle :foo spec operators. +:foo spec operators operate on just the one subsequent SPEC element.") + +(cl-defmethod edebug--handle-:-spec-op ((_ (eql :name)) _cursor spec) ;; Set the edebug-def-name to the spec. (setq edebug-def-name (if edebug-def-name @@ -2058,7 +2043,7 @@ contains a circular object." spec)) nil) -(defun edebug-match-:unique (_cursor spec) +(cl-defmethod edebug--handle-:-spec-op ((_ (eql :unique)) _cursor spec) "Match a `:unique PREFIX' specifier. SPEC is the symbol name prefix for `gensym'." (let ((suffix (gensym spec))) commit d03f2a6ee942882c5bc78226b4730dac6f1d0916 Author: Eli Zaretskii Date: Wed Feb 10 20:04:26 2021 +0200 Avoid assertion violation in callproc.c * src/callproc.c (call_process): Avoid assertion violation when DESTINATION is a cons cell '(:file . "FOO")'. (Bug#46426) diff --git a/src/callproc.c b/src/callproc.c index 5b1d8bfb76..3eac38d375 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -394,7 +394,11 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, /* If the buffer is (still) a list, it might be a (:file "file") spec. */ if (CONSP (buffer) && EQ (XCAR (buffer), QCfile)) { - output_file = Fexpand_file_name (XCAR (XCDR (buffer)), + Lisp_Object ofile = XCDR (buffer); + if (CONSP (ofile)) + ofile = XCAR (ofile); + CHECK_STRING (ofile); + output_file = Fexpand_file_name (ofile, BVAR (current_buffer, directory)); CHECK_STRING (output_file); buffer = Qnil; commit dcfb8f6b617f285a51e4aac23e37b0e81ae37698 Author: Stefan Kangas Date: Wed Feb 10 18:42:52 2021 +0100 Use lexical-binding in dns-mode.el * lisp/textmodes/dns-mode.el: Use lexical-binding. Remove redundant :group args. * test/lisp/textmodes/dns-mode-tests.el (dns-mode-tests-dns-mode-soa-increment-serial): New test. diff --git a/lisp/textmodes/dns-mode.el b/lisp/textmodes/dns-mode.el index 23a622992a..f1a7517192 100644 --- a/lisp/textmodes/dns-mode.el +++ b/lisp/textmodes/dns-mode.el @@ -1,4 +1,4 @@ -;;; dns-mode.el --- a mode for viewing/editing Domain Name System master files +;;; dns-mode.el --- a mode for viewing/editing Domain Name System master files -*- lexical-binding: t -*- ;; Copyright (C) 2000-2001, 2004-2021 Free Software Foundation, Inc. @@ -70,23 +70,19 @@ (defface dns-mode-control-entity '((t :inherit font-lock-keyword-face)) "Face used for DNS control entities, e.g. $ORIGIN." - :version "26.1" - :group 'dns-mode) + :version "26.1") (defface dns-mode-bad-control-entity '((t :inherit font-lock-warning-face)) "Face used for non-standard DNS control entities, e.g. $FOO." - :version "26.1" - :group 'dns-mode) + :version "26.1") (defface dns-mode-type '((t :inherit font-lock-type-face)) "Face used for DNS types, e.g., SOA." - :version "26.1" - :group 'dns-mode) + :version "26.1") (defface dns-mode-class '((t :inherit font-lock-constant-face)) "Face used for DNS classes, e.g., IN." - :version "26.1" - :group 'dns-mode) + :version "26.1") (defvar dns-mode-control-entity-face ''dns-mode-control-entity "Name of face used for control entities, e.g. $ORIGIN.") @@ -121,8 +117,7 @@ (,(regexp-opt dns-mode-types) 0 ,dns-mode-type-face)) "Font lock keywords used to highlight text in DNS master file mode." :version "26.1" - :type 'sexp - :group 'dns-mode) + :type 'sexp) (defcustom dns-mode-soa-auto-increment-serial t "Whether to increment the SOA serial number automatically. @@ -134,8 +129,7 @@ manually with \\[dns-mode-soa-increment-serial]." :type '(choice (const :tag "Always" t) (const :tag "Ask" ask) (const :tag "Never" nil)) - :safe 'symbolp - :group 'dns-mode) + :safe 'symbolp) ;; Syntax table. diff --git a/test/lisp/textmodes/dns-mode-tests.el b/test/lisp/textmodes/dns-mode-tests.el index 694d683d54..92b6cc9177 100644 --- a/test/lisp/textmodes/dns-mode-tests.el +++ b/test/lisp/textmodes/dns-mode-tests.el @@ -25,6 +25,27 @@ (require 'ert) (require 'dns-mode) +(ert-deftest dns-mode-tests-dns-mode-soa-increment-serial () + (with-temp-buffer + (insert "$TTL 86400 +@ IN SOA ns.icann.org. noc.dns.icann.org. ( + 2015080302 ;Serial + 7200 ;Refresh + 3600 ;Retry + 1209600 ;Expire + 3600 ;Negative response caching TTL\n)") + (dns-mode-soa-increment-serial) + ;; Number is updated from 2015080302 to the current date + ;; (actually, just ensure the year part is later than 2020). + (should (string-match "$TTL 86400 +@ IN SOA ns.icann.org. noc.dns.icann.org. ( + 20[2-9][0-9]+ ;Serial + 7200 ;Refresh + 3600 ;Retry + 1209600 ;Expire + 3600 ;Negative response caching TTL\n)" + (buffer-string))))) + ;;; IPv6 reverse zones (ert-deftest dns-mode-ipv6-conversion () (let ((address "2001:db8::42")) commit 8147bf5812ea6f7fa281df4a2628efb85e3476b5 Author: Stefan Kangas Date: Wed Feb 10 17:31:17 2021 +0100 Use lexical-binding in mail-utils.el and add tests * lisp/mail/mail-utils.el: Use lexical-binding. * test/lisp/mail/mail-utils-tests.el: New file. diff --git a/lisp/mail/mail-utils.el b/lisp/mail/mail-utils.el index ad2dee59c7..83125a0d20 100644 --- a/lisp/mail/mail-utils.el +++ b/lisp/mail/mail-utils.el @@ -1,4 +1,4 @@ -;;; mail-utils.el --- utility functions used both by rmail and rnews +;;; mail-utils.el --- utility functions used both by rmail and rnews -*- lexical-binding: t -*- ;; Copyright (C) 1985, 2001-2021 Free Software Foundation, Inc. @@ -46,6 +46,7 @@ also the To field, unless this would leave an empty To field." :type '(choice regexp (const :tag "Your Name" nil)) :group 'mail) +(defvar epa-inhibit) ;; Returns t if file FILE is an Rmail file. ;;;###autoload (defun mail-file-babyl-p (file) @@ -58,6 +59,7 @@ also the To field, unless this would leave an empty To field." (defun mail-string-delete (string start end) "Return a string containing all of STRING except the part from START (inclusive) to END (exclusive)." + ;; FIXME: This is not used anywhere. Make obsolete? (if (null end) (substring string 0 start) (concat (substring string 0 start) (substring string end nil)))) diff --git a/test/lisp/mail/mail-utils-tests.el b/test/lisp/mail/mail-utils-tests.el new file mode 100644 index 0000000000..5b54f2440c --- /dev/null +++ b/test/lisp/mail/mail-utils-tests.el @@ -0,0 +1,104 @@ +;;; mail-utils-tests.el --- tests for mail-utils.el -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Stefan Kangas + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'sasl) +(require 'mail-utils) + +(ert-deftest mail-utils-tests-mail-quote-printable () + (should (equal (mail-quote-printable "abc") "abc")) + (should (equal (mail-quote-printable "åäö") "=E5=E4=F6")) + (should (equal (mail-quote-printable "åäö" t) "=?ISO-8859-1?Q?=E5=E4=F6?="))) + +(ert-deftest mail-utils-tests-mail-quote-printable-region () + (with-temp-buffer + (insert "?=\"\"") + (mail-quote-printable-region (point-min) (point-max)) + (should (equal (buffer-string) "=3F=3D=22=22"))) + (with-temp-buffer + (insert "x") + (mail-quote-printable-region (point-min) (point-max) t) + (should (equal (buffer-string) "=?=?ISO-8859-1?Q?x")))) + +(ert-deftest mail-utils-tests-mail-unquote-printable () + (should (equal (mail-unquote-printable "=E5=E4=F6") "åäö")) + (should (equal (mail-unquote-printable "=?ISO-8859-1?Q?=E5=E4=F6?=" t) "åäö"))) + +(ert-deftest mail-utils-tests-mail-unquote-printable-region () + (with-temp-buffer + (insert "=E5=E4=F6") + (mail-unquote-printable-region (point-min) (point-max)) + (should (equal (buffer-string) "åäö"))) + (with-temp-buffer + (insert "=?ISO-8859-1?Q?=E5=E4=F6?=") + (mail-unquote-printable-region (point-min) (point-max) t) + (should (equal (buffer-string) "åäö")))) + +(ert-deftest mail-utils-tests-mail-strip-quoted-names () + (should (equal (mail-strip-quoted-names + "\"foo\" , bar@example.org") + "foo@example.org, bar@example.org"))) + +(ert-deftest mail-utils-tests-mail-dont-reply-to () + (let ((mail-dont-reply-to-names "foo@example.org")) + (should (equal (mail-dont-reply-to "foo@example.org, bar@example.org") + "bar@example.org")))) + + +(ert-deftest mail-utils-tests-mail-fetch-field () + (with-temp-buffer + (insert "Foo: bar\nBaz: zut") + (should (equal (mail-fetch-field "Foo") "bar")))) + +(ert-deftest mail-utils-tests-mail-parse-comma-list () + (with-temp-buffer + (insert "foo@example.org,bar@example.org,baz@example.org") + (goto-char (point-min)) + (should (equal (mail-parse-comma-list) + '("baz@example.org" "bar@example.org" "foo@example.org"))))) + +(ert-deftest mail-utils-tests-mail-comma-list-regexp () + (should (equal (mail-comma-list-regexp + "foo@example.org,bar@example.org,baz@example.org") + "foo@example.org\\|bar@example.org\\|baz@example.org"))) + +(ert-deftest mail-utils-tests-mail-rfc822-time-zone () + (should (stringp (mail-rfc822-time-zone (current-time))))) + +(ert-deftest mail-utils-test-mail-rfc822-date/contains-year () + (should (string-match (rx " 20" digit digit " ") + (mail-rfc822-date)))) + +(ert-deftest mail-utils-test-mail-mbox-from () + (with-temp-buffer + (insert "Subject: Hello +From: jrh@example.org +To: emacs-devel@gnu.org +Date: Sun, 07 Feb 2021 22:46:37 -0500") + (should (equal (mail-mbox-from) + "From jrh@example.org Sun Feb 7 22:46:37 2021\n")))) + +(provide 'mail-utils-tests) +;;; mail-utils-tests.el ends here commit d6eddf2c079280e5ceea8c5251613ba801f3e54d Author: Stefan Monnier Date: Wed Feb 10 12:36:36 2021 -0500 * list/emacs-lisp/edebug.el: Don't overload `edebug-form-spec` The `edebug-form-spec` symbol property was used to store two different things: the handlers for spec elements like `body` and the handlers for spec operators like `&or`. But these two sets use different calling conventions, so they're fundamentally incompatible. So, move the handlers to spec operators to the new property `edebug--spec-op-function`. This unbreaks Edebugging of: (cl-flet ((f (&rest x) x)) 3) * lisp/emacs-lisp/edebug.el : Split the alist of built in spec elements into normal spec element and spec ops. (edebug--get-spec-op): New function. (edebug-match-specs): Use it. (edebug-match-:name): Rename from `edebug-match-colon-name`. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 41768f2670..176f61402a 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -1687,10 +1687,10 @@ contains a circular object." (first-char (and (symbolp spec) (aref (symbol-name spec) 0))) (match (cond ((eq ?& first-char);; "&" symbols take all following specs. - (funcall (get-edebug-spec spec) cursor (cdr specs))) + (funcall (edebug--get-spec-op spec) cursor (cdr specs))) ((eq ?: first-char);; ":" symbols take one following spec. (setq rest (cdr (cdr specs))) - (funcall (get-edebug-spec spec) cursor (car (cdr specs)))) + (funcall (edebug--get-spec-op spec) cursor (car (cdr specs)))) (t;; Any other normal spec. (setq rest (cdr specs)) (edebug-match-one-spec cursor spec))))) @@ -1721,16 +1721,10 @@ contains a circular object." ;; user may want to define macros or functions with the same names. ;; We could use an internal obarray for these primitive specs. -(dolist (pair '((&optional . edebug-match-&optional) - (&rest . edebug-match-&rest) - (&or . edebug-match-&or) - (form . edebug-match-form) +(dolist (pair '((form . edebug-match-form) (sexp . edebug-match-sexp) (body . edebug-match-body) - (&define . edebug-match-&define) (name . edebug-match-name) - (:name . edebug-match-colon-name) - (:unique . edebug-match-:unique) (arg . edebug-match-arg) (def-body . edebug-match-def-body) (def-form . edebug-match-def-form) @@ -1743,15 +1737,36 @@ contains a circular object." (cl-macrolet-expr . edebug-match-cl-macrolet-expr) (cl-macrolet-name . edebug-match-cl-macrolet-name) (cl-macrolet-body . edebug-match-cl-macrolet-body) - (¬ . edebug-match-¬) - (&key . edebug-match-&key) - (&error . edebug-match-&error) (place . edebug-match-place) (gate . edebug-match-gate) ;; (nil . edebug-match-nil) not this one - special case it. )) (put (car pair) 'edebug-form-spec (cdr pair))) +;; Spec operators are things like `&or' and `&define': they are not +;; themselves specs matching sexps but rather ways to combine specs. +;; Contrary to spec matchers (which take 1 arg), they take 2 arguments. +;; Their name can either start with `&' or `:' and they are called +;; differently depending on this difference (The ones whose name +;; starts with `:' only handle&receive the subsequent element, +;; whereas the ones whose name starts with `&' handle&receive +;; everything that follows). +(dolist (pair '((&optional . edebug-match-&optional) + (&rest . edebug-match-&rest) + (&or . edebug-match-&or) + (&define . edebug-match-&define) + (¬ . edebug-match-¬) + (&key . edebug-match-&key) + (&error . edebug-match-&error) + (:name . edebug-match-:name) + (:unique . edebug-match-:unique) + )) + (put (car pair) 'edebug--spec-op-function (cdr pair))) + +(defun edebug--get-spec-op (name) + "Return the function that handles the spec operator NAME." + (get name 'edebug--spec-op-function)) + (defun edebug-match-symbol (cursor symbol) ;; Match a symbol spec. (let* ((spec (get-edebug-spec symbol))) @@ -2034,7 +2049,7 @@ contains a circular object." (edebug-move-cursor cursor) (list name))) -(defun edebug-match-colon-name (_cursor spec) +(defun edebug-match-:name (_cursor spec) ;; Set the edebug-def-name to the spec. (setq edebug-def-name (if edebug-def-name commit 9b0d76e93b1e72425f8ee67de5eea74520beb5dd Author: Eli Zaretskii Date: Wed Feb 10 18:10:17 2021 +0200 Bump FACE_CACHE_BUCKETS_SIZE to 1009 * src/xfaces.c (FACE_CACHE_BUCKETS_SIZE): Make it 1009, a prime number, per the comment. Reported by Win Treese . diff --git a/src/xfaces.c b/src/xfaces.c index 12087138e5..4b020001c3 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -289,7 +289,7 @@ along with GNU Emacs. If not, see . */ /* Size of hash table of realized faces in face caches (should be a prime number). */ -#define FACE_CACHE_BUCKETS_SIZE 1001 +#define FACE_CACHE_BUCKETS_SIZE 1009 char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg"; commit f3ae26cb2ae581a84bbaa15a47e9917a799a5682 Author: Mattias Engdegård Date: Wed Feb 10 14:26:49 2021 +0100 Fix local defvar scoping error (bug#46387) This bug was introduced by the lexical variable constant propagation mechanism. It was discovered by Michael Heerdegen. * lisp/emacs-lisp/byte-opt.el (byte-optimize-let-form) (byte-optimize-body): Let the effects of a local defvar declaration be scoped by let and let*, not any arbitrary Lisp expression body (such as progn). * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--get-vars) (bytecomp-local-defvar): New test. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 4fa2c75a88..8851f0ef32 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -698,7 +698,8 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") (append new-lexvars byte-optimize--lexvars)) ;; Walk the body expressions, which may mutate some of the records, ;; and generate new bindings that exclude unused variables. - (let* ((opt-body (byte-optimize-body (cdr form) for-effect)) + (let* ((byte-optimize--dynamic-vars byte-optimize--dynamic-vars) + (opt-body (byte-optimize-body (cdr form) for-effect)) (bindings nil)) (dolist (var let-vars) ;; VAR is (NAME EXPR [KEEP [VALUE]]) @@ -730,7 +731,6 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") ;; all-for-effect is true. returns a new list of forms. (let ((rest forms) (result nil) - (byte-optimize--dynamic-vars byte-optimize--dynamic-vars) fe new) (while rest (setq fe (or all-for-effect (cdr rest))) diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el index bc623d3efc..0b70c11b29 100644 --- a/test/lisp/emacs-lisp/bytecomp-tests.el +++ b/test/lisp/emacs-lisp/bytecomp-tests.el @@ -1168,6 +1168,37 @@ mountpoint (Bug#44631)." (with-demoted-errors "Error cleaning up directory: %s" (delete-directory directory :recursive))))) +(defun bytecomp-tests--get-vars () + (list (ignore-errors (symbol-value 'bytecomp-tests--var1)) + (ignore-errors (symbol-value 'bytecomp-tests--var2)))) + +(ert-deftest bytecomp-local-defvar () + "Check that local `defvar' declarations work correctly, both +interpreted and compiled." + (let ((lexical-binding t)) + (let ((fun '(lambda () + (defvar bytecomp-tests--var1) + (let ((bytecomp-tests--var1 'a) ; dynamic + (bytecomp-tests--var2 'b)) ; still lexical + (ignore bytecomp-tests--var2) ; avoid warning + (bytecomp-tests--get-vars))))) + (should (listp fun)) ; Guard against overzealous refactoring! + (should (equal (funcall (eval fun t)) '(a nil))) + (should (equal (funcall (byte-compile fun)) '(a nil))) + ) + + ;; `progn' does not constitute a lexical scope for `defvar' (bug#46387). + (let ((fun '(lambda () + (progn + (defvar bytecomp-tests--var1) + (defvar bytecomp-tests--var2)) + (let ((bytecomp-tests--var1 'c) + (bytecomp-tests--var2 'd)) + (bytecomp-tests--get-vars))))) + (should (listp fun)) + (should (equal (funcall (eval fun t)) '(c d))) + (should (equal (funcall (byte-compile fun)) '(c d)))))) + ;; Local Variables: ;; no-byte-compile: t ;; End: commit d9af4167019c4ed4f8605965cdf3e3ff7b72244f Author: Stefan Kangas Date: Wed Feb 10 14:10:10 2021 +0100 Minor cleanup in imenu.el * lisp/imenu.el: Doc fix; these examples have been removed. Remove redundant :group args. diff --git a/lisp/imenu.el b/lisp/imenu.el index 72d1c40e9a..7fc57c1052 100644 --- a/lisp/imenu.el +++ b/lisp/imenu.el @@ -36,14 +36,6 @@ ;; A mode-specific function is called to generate the index. It is ;; then presented to the user, who can choose from this index. -;; -;; The package comes with a set of example functions for how to -;; utilize this package. - -;; There are *examples* for index gathering functions/regular -;; expressions for C/C++ and Lisp/Emacs Lisp but it is easy to -;; customize for other modes. A function for jumping to the chosen -;; index position is also supplied. ;;; History: ;; Thanks go to @@ -81,25 +73,20 @@ Setting this to nil makes Imenu work a little faster but editing the buffer will make the generated index positions wrong. This might not yet be honored by all index-building functions." - :type 'boolean - :group 'imenu) - + :type 'boolean) (defcustom imenu-max-item-length 60 "If a number, truncate Imenu entries to that length." :type '(choice integer - (const :tag "Unlimited")) - :group 'imenu) + (const :tag "Unlimited"))) (defcustom imenu-auto-rescan nil "Non-nil means Imenu should always rescan the buffers." - :type 'boolean - :group 'imenu) + :type 'boolean) (defcustom imenu-auto-rescan-maxout 600000 "Imenu auto-rescan is disabled in buffers larger than this size (in bytes)." :type 'integer - :group 'imenu :version "26.2") (defcustom imenu-use-popup-menu 'on-mouse @@ -109,13 +96,11 @@ If t, always use a popup menu, If `on-mouse' use a popup menu when `imenu' was invoked with the mouse." :type '(choice (const :tag "On Mouse" on-mouse) (const :tag "Never" nil) - (other :tag "Always" t)) - :group 'imenu) + (other :tag "Always" t))) (defcustom imenu-eager-completion-buffer t "If non-nil, eagerly popup the completion buffer." :type 'boolean - :group 'imenu :version "22.1") (defcustom imenu-after-jump-hook nil @@ -123,8 +108,7 @@ If `on-mouse' use a popup menu when `imenu' was invoked with the mouse." Useful things to use here include `reposition-window', `recenter', and \(lambda () (recenter 0)) to show at top of screen." - :type 'hook - :group 'imenu) + :type 'hook) ;;;###autoload (defcustom imenu-sort-function nil @@ -143,27 +127,23 @@ element should come before the second. The arguments are cons cells; \(NAME . POSITION). Look at `imenu--sort-by-name' for an example." :type '(choice (const :tag "No sorting" nil) (const :tag "Sort by name" imenu--sort-by-name) - (function :tag "Another function")) - :group 'imenu) + (function :tag "Another function"))) (defcustom imenu-max-items 25 "Maximum number of elements in a mouse menu for Imenu." - :type 'integer - :group 'imenu) + :type 'integer) (defcustom imenu-space-replacement "." "The replacement string for spaces in index names. Used when presenting the index in a completion buffer to make the names work as tokens." - :type '(choice string (const nil)) - :group 'imenu) + :type '(choice string (const nil))) (defcustom imenu-level-separator ":" "The separator between index names of different levels. Used for making mouse-menu titles and for flattening nested indexes with name concatenation." - :type 'string - :group 'imenu) + :type 'string) (defcustom imenu-generic-skip-comments-and-strings t "When non-nil, ignore text inside comments and strings. @@ -171,7 +151,6 @@ Only affects `imenu-default-create-index-function' (and any alternative implementation of `imenu-create-index-function' that uses `imenu--generic-function')." :type 'boolean - :group 'imenu :version "24.4") ;;;###autoload commit 553613e7ca5ff5d6120212360e166f7e45ef62d6 Author: Stefan Kangas Date: Wed Feb 10 14:08:01 2021 +0100 Use lexical-binding in snmp-mode.el * lisp/net/snmp-mode.el: Use lexical-binding. Remove redundant :group args. Doc fix; remove outdated information. (snmp-mode, snmpv2-mode): Add FIXME to use define-derived-mode. diff --git a/lisp/net/snmp-mode.el b/lisp/net/snmp-mode.el index 2fbe744401..ae878ef3a5 100644 --- a/lisp/net/snmp-mode.el +++ b/lisp/net/snmp-mode.el @@ -1,4 +1,4 @@ -;;; snmp-mode.el --- SNMP & SNMPv2 MIB major mode +;;; snmp-mode.el --- SNMP & SNMPv2 MIB major mode -*- lexical-binding: t -*- ;; Copyright (C) 1995, 1998, 2001-2021 Free Software Foundation, Inc. @@ -69,16 +69,6 @@ ;; Once the template is done, you can use C-cC-f and C-cC-b to move back ;; and forth between the Tempo sequence points to fill in the rest of ;; the information. -;; -;; Font Lock -;; ------------ -;; -;; If you want font-lock in your MIB buffers, add this: -;; -;; (add-hook 'snmp-common-mode-hook 'turn-on-font-lock) -;; -;; Enabling global-font-lock-mode is also sufficient. -;; ;;; Code: @@ -101,42 +91,35 @@ (defcustom snmp-special-indent t "If non-nil, use a simple heuristic to try to guess the right indentation. If nil, then no special indentation is attempted." - :type 'boolean - :group 'snmp) + :type 'boolean) (defcustom snmp-indent-level 4 "Indentation level for SNMP MIBs." - :type 'integer - :group 'snmp) + :type 'integer) (defcustom snmp-tab-always-indent nil "Non-nil means TAB should always reindent the current line. A value of nil means reindent if point is within the initial line indentation; otherwise insert a TAB." - :type 'boolean - :group 'snmp) + :type 'boolean) (defcustom snmp-completion-ignore-case t "Non-nil means that case differences are ignored during completion. A value of nil means that case is significant. This is used during Tempo template completion." - :type 'boolean - :group 'snmp) + :type 'boolean) (defcustom snmp-common-mode-hook nil "Hook(s) evaluated when a buffer enters either SNMP or SNMPv2 mode." - :type 'hook - :group 'snmp) + :type 'hook) (defcustom snmp-mode-hook nil "Hook(s) evaluated when a buffer enters SNMP mode." - :type 'hook - :group 'snmp) + :type 'hook) (defcustom snmpv2-mode-hook nil "Hook(s) evaluated when a buffer enters SNMPv2 mode." - :type 'hook - :group 'snmp) + :type 'hook) (defvar snmp-tempo-tags nil "Tempo tags for SNMP mode.") @@ -291,7 +274,7 @@ This is used during Tempo template completion." ;; Set up the stuff that's common between snmp-mode and snmpv2-mode ;; -(defun snmp-common-mode (name mode abbrev font-keywords imenu-index tempo-tags) +(defun snmp-common-mode (name mode abbrev font-keywords imenu-index mode-tempo-tags) (kill-all-local-variables) ;; Become the current major mode @@ -326,7 +309,7 @@ This is used during Tempo template completion." (setq-local imenu-create-index-function imenu-index) ;; Tempo - (tempo-use-tag-list tempo-tags) + (tempo-use-tag-list mode-tempo-tags) (setq-local tempo-match-finder "\\b\\(.+\\)\\=") (setq-local tempo-interactive t) @@ -338,6 +321,7 @@ This is used during Tempo template completion." ;; ;;;###autoload (defun snmp-mode () + ;; FIXME: Use define-derived-mode. "Major mode for editing SNMP MIBs. Expression and list commands understand all C brackets. Tab indents for C code. @@ -370,6 +354,7 @@ Turning on snmp-mode runs the hooks in `snmp-common-mode-hook', then ;;;###autoload (defun snmpv2-mode () + ;; FIXME: Use define-derived-mode. "Major mode for editing SNMPv2 MIBs. Expression and list commands understand all C brackets. Tab indents for C code. commit 70d562b43e0db4e76fbf51f30ec2f51290f525d1 Author: Stefan Kangas Date: Wed Feb 10 13:59:09 2021 +0100 Declare empty macro imenu-progress-menu obsolete * lisp/imenu.el: Remove commented out code. (imenu-progress-message): Declare macro obsolete. * lisp/erc/erc-imenu.el (erc-create-imenu-index): * lisp/net/snmp-mode.el (snmp-mode-imenu-create-index): * lisp/progmodes/antlr-mode.el (antlr-imenu-create-index-function): Don't use or mention above obsolete macro. diff --git a/lisp/erc/erc-imenu.el b/lisp/erc/erc-imenu.el index 1a2d8e2755..ecdfc2a04b 100644 --- a/lisp/erc/erc-imenu.el +++ b/lisp/erc/erc-imenu.el @@ -73,13 +73,11 @@ Don't rely on this function, read it first!" (topic-change-alist '()) prev-pos) (goto-char (point-max)) - (imenu-progress-message prev-pos 0) (while (if (bolp) (> (forward-line -1) -1) (progn (forward-line 0) t)) - (imenu-progress-message prev-pos nil t) (save-match-data (when (looking-at (concat (regexp-quote erc-notice-prefix) "\\(.+\\)$")) diff --git a/lisp/imenu.el b/lisp/imenu.el index 2a557e0453..72d1c40e9a 100644 --- a/lisp/imenu.el +++ b/lisp/imenu.el @@ -151,18 +151,6 @@ element should come before the second. The arguments are cons cells; :type 'integer :group 'imenu) -;; No longer used. KFS 2004-10-27 -;; (defcustom imenu-scanning-message "Scanning buffer for index (%3d%%)" -;; "Progress message during the index scanning of the buffer. -;; If non-nil, user gets a message during the scanning of the buffer. -;; -;; Relevant only if the mode-specific function that creates the buffer -;; index use `imenu-progress-message', and not useful if that is fast, in -;; which case you might as well set this to nil." -;; :type '(choice string -;; (const :tag "None" nil)) -;; :group 'imenu) - (defcustom imenu-space-replacement "." "The replacement string for spaces in index names. Used when presenting the index in a completion buffer to make the @@ -280,26 +268,11 @@ The function in this variable is called when selecting a normal index-item.") (not (functionp (cadr item))))) (defmacro imenu-progress-message (_prevpos &optional _relpos _reverse) - "Macro to display a progress message. -RELPOS is the relative position to display. -If RELPOS is nil, then the relative position in the buffer -is calculated. -PREVPOS is the variable in which we store the last position displayed." - + "This macro is obsolete and does nothing." + (declare (obsolete nil "28.1")) ;; Made obsolete/empty, as computers are now faster than the eye, and ;; it had problems updating the messages correctly, and could shadow ;; more important messages/prompts in the minibuffer. KFS 2004-10-27. - -;; `(and -;; imenu-scanning-message -;; (let ((pos ,(if relpos -;; relpos -;; `(imenu--relative-position ,reverse)))) -;; (if ,(if relpos t -;; `(> pos (+ 5 ,prevpos))) -;; (progn -;; (message imenu-scanning-message pos) -;; (setq ,prevpos pos))))) ) diff --git a/lisp/net/snmp-mode.el b/lisp/net/snmp-mode.el index 983e6d92ee..2fbe744401 100644 --- a/lisp/net/snmp-mode.el +++ b/lisp/net/snmp-mode.el @@ -474,13 +474,11 @@ lines for the purposes of this function." (index-table-alist '()) (index-trap-alist '()) (case-fold-search nil) ; keywords must be uppercase - prev-pos token end) + token end) (goto-char (point-min)) - (imenu-progress-message prev-pos 0) ;; Search for a useful MIB item (that's not in a comment) (save-match-data (while (re-search-forward snmp-clause-regexp nil t) - (imenu-progress-message prev-pos) (setq end (match-end 0) token (cons (match-string 1) @@ -498,7 +496,6 @@ lines for the purposes of this function." (push token index-tc-alist))) (goto-char end))) ;; Create the menu - (imenu-progress-message prev-pos 100) (setq index-alist (nreverse index-alist)) (and index-tc-alist (push (cons "Textual Conventions" (nreverse index-tc-alist)) diff --git a/lisp/progmodes/antlr-mode.el b/lisp/progmodes/antlr-mode.el index e5b9ac0a53..d92c8c35b1 100644 --- a/lisp/progmodes/antlr-mode.el +++ b/lisp/progmodes/antlr-mode.el @@ -1246,9 +1246,8 @@ IF TOKENREFS-ONLY is non-nil, just return alist with tokenref names." (let ((items nil) (classes nil) (continue t)) - ;; Using `imenu-progress-message' would require imenu for compilation, but - ;; nobody is missing these messages. The generic imenu function searches - ;; backward, which is slower and more likely not to work during editing. + ;; The generic imenu function searches backward, which is slower + ;; and more likely not to work during editing. (antlr-with-syntax-table antlr-action-syntax-table (antlr-invalidate-context-cache) (goto-char (point-min)) commit d0826e592ae40d05217e69f28bbf2d1dfe4b9085 Author: Protesilaos Stavrou Date: Wed Feb 10 06:03:33 2021 +0200 Update NEWS entry for vc-dir faces * NEWS: Remove reference to specific backend, as it now applies to all of them. Update name of 'vc-dir-status-ignored'. This follows from the discussion in bug#46358. diff --git a/etc/NEWS b/etc/NEWS index bd209de18e..3cbf2a0fe7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -602,10 +602,11 @@ This is used when expanding commit messages from 'vc-print-root-log' and similar commands. --- -*** New faces for 'vc-dir' buffers and their Git VC backend. +*** New faces for 'vc-dir' buffers. Those are: 'vc-dir-header', 'vc-dir-header-value', 'vc-dir-directory', 'vc-dir-file', 'vc-dir-mark-indicator', 'vc-dir-status-warning', -'vc-dir-status-edited', 'vc-dir-status-up-to-date', 'vc-dir-ignored'. +'vc-dir-status-edited', 'vc-dir-status-up-to-date', +'vc-dir-status-ignored'. --- *** The responsible VC backend is now the most specific one. commit 30f3b9f8472acc53ca5948797a342cafd4ea9cd8 Author: Stefan Kangas Date: Wed Feb 10 13:21:34 2021 +0100 * lisp/cedet/semantic/bovine/gcc.el: Use lexical-binding. diff --git a/lisp/cedet/semantic/bovine/gcc.el b/lisp/cedet/semantic/bovine/gcc.el index 1cfe5a3bac..9cd9cdcb84 100644 --- a/lisp/cedet/semantic/bovine/gcc.el +++ b/lisp/cedet/semantic/bovine/gcc.el @@ -1,4 +1,4 @@ -;;; semantic/bovine/gcc.el --- gcc querying special code for the C parser +;;; semantic/bovine/gcc.el --- gcc querying special code for the C parser -*- lexical-binding: t -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -25,6 +25,7 @@ ;; GCC, and set up the preprocessor and include paths. (require 'semantic/dep) +(require 'cl-lib) (defvar semantic-lex-c-preprocessor-symbol-file) (defvar semantic-lex-c-preprocessor-symbol-map) @@ -88,9 +89,7 @@ to give to the program." (let ((path (substring line 1))) (when (and (file-accessible-directory-p path) (file-name-absolute-p path)) - (add-to-list 'inc-path - (expand-file-name path) - t)))))))) + (cl-pushnew (expand-file-name path) inc-path)))))))) inc-path)) @@ -101,7 +100,7 @@ to give to the program." (dolist (L lines) (let ((dat (split-string L))) (when (= (length dat) 3) - (add-to-list 'lst (cons (nth 1 dat) (nth 2 dat)))))) + (push (cons (nth 1 dat) (nth 2 dat)) lst)))) lst)) (defun semantic-gcc-fields (str) @@ -142,6 +141,8 @@ This is an alist, and should include keys of: `--prefix' - where GCC was installed. It should also include other symbols GCC was compiled with.") +(defvar c++-include-path) + ;;;###autoload (defun semantic-gcc-setup () "Setup Semantic C/C++ parsing based on GCC output." commit 4786353b2abc756d3fd6bda016859b40ba9aca8a Author: Stefan Kangas Date: Wed Feb 10 12:44:07 2021 +0100 Move cedet test resource files to follow our conventions * test/lisp/cedet/semantic-utest-ia.el (ert, ert-x): Require. (cedet-utest-directory, semantic-utest-test-directory): Remove variables. (semantic-utest-ia-doublens.cpp, semantic-utest-ia-subclass.cpp) (semantic-utest-ia-typedefs.cpp, semantic-utest-ia-struct.cpp) (semantic-utest-ia-templates.cpp, semantic-utest-ia-using.cpp) (semantic-utest-ia-nsp.cpp, semantic-utest-ia-localvars.cpp) (semantic-utest-ia-namespace.cpp) (semantic-utest-ia-sppcomplete.c, semantic-utest-ia-varnames.c) (semantic-utest-ia-javacomp.java) (semantic-utest-ia-varnames.java, semantic-utest-ia-wisent.wy) (semantic-utest-ia-texi, semantic-utest-ia-make) (semantic-utest-ia-srecoder): Use 'ert-resource-file'. Don't check if file exists; we can assume that it does. * test/manual/cedet/tests/testjavacomp.java: * test/manual/cedet/tests/testlocalvars.cpp: * test/manual/cedet/tests/testnsp.cpp: * test/manual/cedet/tests/testsppcomplete.c: * test/manual/cedet/tests/teststruct.cpp: * test/manual/cedet/tests/testsubclass.cpp: * test/manual/cedet/tests/testsubclass.hh: * test/manual/cedet/tests/testtemplates.cpp: * test/manual/cedet/tests/testtypedefs.cpp: * test/manual/cedet/tests/testusing.cpp: * test/manual/cedet/tests/testusing.hh: * test/manual/cedet/tests/testvarnames.c: * test/manual/cedet/tests/testvarnames.java: * test/manual/cedet/tests/testwisent.wy: Move from here... * test/lisp/cedet/semantic-utest-ia-resources/testjavacomp.java: * test/lisp/cedet/semantic-utest-ia-resources/testlocalvars.cpp: * test/lisp/cedet/semantic-utest-ia-resources/testnsp.cpp: * test/lisp/cedet/semantic-utest-ia-resources/testsppcomplete.c: * test/lisp/cedet/semantic-utest-ia-resources/teststruct.cpp: * test/lisp/cedet/semantic-utest-ia-resources/testsubclass.cpp: * test/lisp/cedet/semantic-utest-ia-resources/testsubclass.hh: * test/lisp/cedet/semantic-utest-ia-resources/testtemplates.cpp: * test/lisp/cedet/semantic-utest-ia-resources/testtypedefs.cpp: * test/lisp/cedet/semantic-utest-ia-resources/testusing.cpp: * test/lisp/cedet/semantic-utest-ia-resources/testusing.hh: * test/lisp/cedet/semantic-utest-ia-resources/testvarnames.c: * test/lisp/cedet/semantic-utest-ia-resources/testvarnames.java: * test/lisp/cedet/semantic-utest-ia-resources/testwisent.wy: ...to here. diff --git a/test/manual/cedet/tests/test.mk b/test/lisp/cedet/semantic-utest-ia-resources/test.mk similarity index 100% rename from test/manual/cedet/tests/test.mk rename to test/lisp/cedet/semantic-utest-ia-resources/test.mk diff --git a/test/manual/cedet/tests/test.srt b/test/lisp/cedet/semantic-utest-ia-resources/test.srt similarity index 100% rename from test/manual/cedet/tests/test.srt rename to test/lisp/cedet/semantic-utest-ia-resources/test.srt diff --git a/test/manual/cedet/tests/test.texi b/test/lisp/cedet/semantic-utest-ia-resources/test.texi similarity index 100% rename from test/manual/cedet/tests/test.texi rename to test/lisp/cedet/semantic-utest-ia-resources/test.texi diff --git a/test/manual/cedet/tests/testdoublens.cpp b/test/lisp/cedet/semantic-utest-ia-resources/testdoublens.cpp similarity index 100% rename from test/manual/cedet/tests/testdoublens.cpp rename to test/lisp/cedet/semantic-utest-ia-resources/testdoublens.cpp diff --git a/test/manual/cedet/tests/testdoublens.hpp b/test/lisp/cedet/semantic-utest-ia-resources/testdoublens.hpp similarity index 100% rename from test/manual/cedet/tests/testdoublens.hpp rename to test/lisp/cedet/semantic-utest-ia-resources/testdoublens.hpp diff --git a/test/manual/cedet/tests/testfriends.cpp b/test/lisp/cedet/semantic-utest-ia-resources/testfriends.cpp similarity index 99% rename from test/manual/cedet/tests/testfriends.cpp rename to test/lisp/cedet/semantic-utest-ia-resources/testfriends.cpp index 20425f93af..f84ed5a219 100644 --- a/test/manual/cedet/tests/testfriends.cpp +++ b/test/lisp/cedet/semantic-utest-ia-resources/testfriends.cpp @@ -35,4 +35,3 @@ int B::testB() { int B::testAB() { // %1% ( ( "testfriends.cpp" ) ( "B" "B::testAB" ) ) } - diff --git a/test/manual/cedet/tests/testjavacomp.java b/test/lisp/cedet/semantic-utest-ia-resources/testjavacomp.java similarity index 100% rename from test/manual/cedet/tests/testjavacomp.java rename to test/lisp/cedet/semantic-utest-ia-resources/testjavacomp.java diff --git a/test/manual/cedet/tests/testlocalvars.cpp b/test/lisp/cedet/semantic-utest-ia-resources/testlocalvars.cpp similarity index 100% rename from test/manual/cedet/tests/testlocalvars.cpp rename to test/lisp/cedet/semantic-utest-ia-resources/testlocalvars.cpp diff --git a/test/manual/cedet/tests/testnsp.cpp b/test/lisp/cedet/semantic-utest-ia-resources/testnsp.cpp similarity index 100% rename from test/manual/cedet/tests/testnsp.cpp rename to test/lisp/cedet/semantic-utest-ia-resources/testnsp.cpp diff --git a/test/manual/cedet/tests/testsppcomplete.c b/test/lisp/cedet/semantic-utest-ia-resources/testsppcomplete.c similarity index 100% rename from test/manual/cedet/tests/testsppcomplete.c rename to test/lisp/cedet/semantic-utest-ia-resources/testsppcomplete.c diff --git a/test/manual/cedet/tests/teststruct.cpp b/test/lisp/cedet/semantic-utest-ia-resources/teststruct.cpp similarity index 100% rename from test/manual/cedet/tests/teststruct.cpp rename to test/lisp/cedet/semantic-utest-ia-resources/teststruct.cpp diff --git a/test/manual/cedet/tests/testsubclass.cpp b/test/lisp/cedet/semantic-utest-ia-resources/testsubclass.cpp similarity index 100% rename from test/manual/cedet/tests/testsubclass.cpp rename to test/lisp/cedet/semantic-utest-ia-resources/testsubclass.cpp diff --git a/test/manual/cedet/tests/testsubclass.hh b/test/lisp/cedet/semantic-utest-ia-resources/testsubclass.hh similarity index 100% rename from test/manual/cedet/tests/testsubclass.hh rename to test/lisp/cedet/semantic-utest-ia-resources/testsubclass.hh diff --git a/test/manual/cedet/tests/testtemplates.cpp b/test/lisp/cedet/semantic-utest-ia-resources/testtemplates.cpp similarity index 100% rename from test/manual/cedet/tests/testtemplates.cpp rename to test/lisp/cedet/semantic-utest-ia-resources/testtemplates.cpp diff --git a/test/manual/cedet/tests/testtypedefs.cpp b/test/lisp/cedet/semantic-utest-ia-resources/testtypedefs.cpp similarity index 100% rename from test/manual/cedet/tests/testtypedefs.cpp rename to test/lisp/cedet/semantic-utest-ia-resources/testtypedefs.cpp diff --git a/test/manual/cedet/tests/testusing.cpp b/test/lisp/cedet/semantic-utest-ia-resources/testusing.cpp similarity index 100% rename from test/manual/cedet/tests/testusing.cpp rename to test/lisp/cedet/semantic-utest-ia-resources/testusing.cpp diff --git a/test/manual/cedet/tests/testusing.hh b/test/lisp/cedet/semantic-utest-ia-resources/testusing.hh similarity index 100% rename from test/manual/cedet/tests/testusing.hh rename to test/lisp/cedet/semantic-utest-ia-resources/testusing.hh diff --git a/test/manual/cedet/tests/testvarnames.c b/test/lisp/cedet/semantic-utest-ia-resources/testvarnames.c similarity index 100% rename from test/manual/cedet/tests/testvarnames.c rename to test/lisp/cedet/semantic-utest-ia-resources/testvarnames.c diff --git a/test/manual/cedet/tests/testvarnames.java b/test/lisp/cedet/semantic-utest-ia-resources/testvarnames.java similarity index 100% rename from test/manual/cedet/tests/testvarnames.java rename to test/lisp/cedet/semantic-utest-ia-resources/testvarnames.java diff --git a/test/manual/cedet/tests/testwisent.wy b/test/lisp/cedet/semantic-utest-ia-resources/testwisent.wy similarity index 100% rename from test/manual/cedet/tests/testwisent.wy rename to test/lisp/cedet/semantic-utest-ia-resources/testwisent.wy diff --git a/test/lisp/cedet/semantic-utest-ia.el b/test/lisp/cedet/semantic-utest-ia.el index 7210f66b0a..122c431d47 100644 --- a/test/lisp/cedet/semantic-utest-ia.el +++ b/test/lisp/cedet/semantic-utest-ia.el @@ -30,121 +30,94 @@ ;; (Replace // with contents of comment-start for the language being tested.) ;;; Code: +(require 'ert) +(require 'ert-x) (require 'semantic) (require 'semantic/analyze) (require 'semantic/analyze/refs) (require 'semantic/symref) (require 'semantic/symref/filter) -(defvar cedet-utest-directory - (let* ((C (file-name-directory (locate-library "cedet"))) - (D (expand-file-name "../../test/manual/cedet/" C))) - D) - "Location of test files for this test suite.") - -(defvar semantic-utest-test-directory (expand-file-name "tests" cedet-utest-directory) - "Location of test files.") - (ert-deftest semantic-utest-ia-doublens.cpp () - (let ((tst (expand-file-name "testdoublens.cpp" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "testdoublens.cpp"))) (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-subclass.cpp () - (let ((tst (expand-file-name "testsubclass.cpp" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "testsubclass.cpp"))) (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-typedefs.cpp () - (let ((tst (expand-file-name "testtypedefs.cpp" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "testtypedefs.cpp"))) (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-struct.cpp () - (let ((tst (expand-file-name "teststruct.cpp" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "teststruct.cpp"))) (should-not (semantic-ia-utest tst)))) ;;(ert-deftest semantic-utest-ia-union.cpp () -;; (let ((tst (expand-file-name "testunion.cpp" semantic-utest-test-directory))) -;; (should (file-exists-p tst)) +;; (let ((tst (ert-resource-file "testunion.cpp"))) ;; (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-templates.cpp () - (let ((tst (expand-file-name "testtemplates.cpp" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "testtemplates.cpp"))) (should-not (semantic-ia-utest tst)))) ;;(ert-deftest semantic-utest-ia-friends.cpp () -;; (let ((tst (expand-file-name "testfriends.cpp" semantic-utest-test-directory))) -;; (should (file-exists-p tst)) +;; (let ((tst (ert-resource-file "testfriends.cpp"))) ;; (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-using.cpp () - (let ((tst (expand-file-name "testusing.cpp" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "testusing.cpp"))) (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-nsp.cpp () (skip-unless (executable-find "g++")) - (let ((tst (expand-file-name "testnsp.cpp" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "testnsp.cpp"))) (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-localvars.cpp () - (let ((tst (expand-file-name "testlocalvars.cpp" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "testlocalvars.cpp"))) (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-namespace.cpp () (skip-unless (executable-find "g++")) - (let ((tst (expand-file-name "testnsp.cpp" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "testnsp.cpp"))) (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-sppcomplete.c () - (let ((tst (expand-file-name "testsppcomplete.c" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "testsppcomplete.c"))) (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-varnames.c () - (let ((tst (expand-file-name "testvarnames.c" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "testvarnames.c"))) (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-javacomp.java () - (let ((tst (expand-file-name "testjavacomp.java" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "testjavacomp.java"))) (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-varnames.java () - (let ((tst (expand-file-name "testvarnames.java" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "testvarnames.java"))) (should-not (semantic-ia-utest tst)))) ;;(ert-deftest semantic-utest-ia-f90.f90 () -;; (let ((tst (expand-file-name "testf90.f90" semantic-utest-test-directory))) -;; (should (file-exists-p tst)) +;; (let ((tst (ert-resource-file "testf90.f90"))) ;; (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-wisent.wy () - (let ((tst (expand-file-name "testwisent.wy" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "testwisent.wy"))) (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-texi () - (let ((tst (expand-file-name "test.texi" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "test.texi"))) (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-make () - (let ((tst (expand-file-name "test.mk" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "test.mk"))) (should-not (semantic-ia-utest tst)))) (ert-deftest semantic-utest-ia-srecoder () - (let ((tst (expand-file-name "test.srt" semantic-utest-test-directory))) - (should (file-exists-p tst)) + (let ((tst (ert-resource-file "test.srt"))) (should-not (semantic-ia-utest tst)))) ;;; Core testing utility commit 62ee5999a725b0561c625277e3756657de9e4360 Author: Stefan Kangas Date: Wed Feb 10 12:20:32 2021 +0100 Convert tests for srecode/fields.el to ert * test/manual/cedet/srecode-tests.el: Move from here... * test/lisp/cedet/srecode/fields-tests.el: ...to here. (srecode-field-utest-impl): Convert test to ert. Silence byte-compiler. * test/manual/cedet/cedet-utests.el (cedet-utest-libs): Don't list the above moved file. diff --git a/test/manual/cedet/srecode-tests.el b/test/lisp/cedet/srecode/fields-tests.el similarity index 88% rename from test/manual/cedet/srecode-tests.el rename to test/lisp/cedet/srecode/fields-tests.el index 18ca07343d..5f634a5e4c 100644 --- a/test/manual/cedet/srecode-tests.el +++ b/test/lisp/cedet/srecode/fields-tests.el @@ -1,4 +1,4 @@ -;;; srecode-tests.el --- Some tests for CEDET's srecode -*- lexical-binding: t -*- +;;; srecode/fields-tests.el --- Tests for srecode/fields.el -*- lexical-binding: t -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -21,13 +21,15 @@ ;;; Commentary: -;; Extracted from srecode-fields.el and srecode-document.el in the -;; CEDET distribution. +;; Extracted from srecode-fields.el in the CEDET distribution. + +;; Converted to ert from test/manual/cedet/srecode-tests.el ;;; Code: ;;; From srecode-fields: +(require 'ert) (require 'srecode/fields) (defvar srecode-field-utest-text @@ -36,13 +38,10 @@ It is filled with some text." "Text for tests.") -(defun srecode-field-utest () - "Test the srecode field manager." - (interactive) - (srecode-field-utest-impl)) - -(defun srecode-field-utest-impl () +;; FIXME: This test fails even before conversion to ert. +(ert-deftest srecode-field-utest-impl () "Implementation of the SRecode field utest." + :tags '(:unstable) (save-excursion (find-file "/tmp/srecode-field-test.txt") @@ -131,15 +130,15 @@ It is filled with some text." ;; Various sizes (mapc (lambda (T) - (if (string= (object-name-string T) "Test4") + (if (string= (eieio-object-name-string T) "Test4") (progn (when (not (srecode-empty-region-p T)) (error "Field %s is not empty" - (object-name T))) + (eieio-object-name T))) ) (when (not (= (srecode-region-size T) 5)) (error "Calculated size of %s was not 5" - (object-name T))))) + (eieio-object-name T))))) fields) ;; Make sure things stay up after a 'command'. @@ -151,21 +150,21 @@ It is filled with some text." (when (not (eq (srecode-overlaid-at-point 'srecode-field) (nth 0 fields))) (error "Region Test: Field %s not under point" - (object-name (nth 0 fields)))) + (eieio-object-name (nth 0 fields)))) (srecode-field-next) (when (not (eq (srecode-overlaid-at-point 'srecode-field) (nth 1 fields))) (error "Region Test: Field %s not under point" - (object-name (nth 1 fields)))) + (eieio-object-name (nth 1 fields)))) (srecode-field-prev) (when (not (eq (srecode-overlaid-at-point 'srecode-field) (nth 0 fields))) (error "Region Test: Field %s not under point" - (object-name (nth 0 fields)))) + (eieio-object-name (nth 0 fields)))) ;; Move cursor out of the region and have everything cleaned up. (goto-char 42) @@ -176,7 +175,7 @@ It is filled with some text." (mapc (lambda (T) (when (slot-boundp T 'overlay) (error "Overlay did not clear off of field %s" - (object-name T)))) + (eieio-object-name T)))) fields) ;; End of LET @@ -187,8 +186,7 @@ It is filled with some text." (f1 (srecode-field "Test1" :name "TEST" :start 6 :end 8)) (f2 (srecode-field "Test2" :name "TEST" :start 28 :end 30)) (f3 (srecode-field "Test3" :name "NOTTEST" :start 35 :end 40)) - (reg (srecode-template-inserted-region "REG" :start 4 :end 40)) - ) + (reg (srecode-template-inserted-region "REG" :start 4 :end 40))) (srecode-overlaid-activate reg) (when (not (string= (srecode-overlaid-text f1) @@ -233,12 +231,8 @@ It is filled with some text." (error "Linkage Test: tail-insert string on dissimilar fields is now the same")) ;; Cleanup - (srecode-delete reg) - ) - - (set-buffer-modified-p nil) + (srecode-delete reg)) - (message " All field tests passed.") - )) + (set-buffer-modified-p nil))) -;;; srecode-tests.el ends here +;;; srecode/fields-tests.el ends here diff --git a/test/manual/cedet/cedet-utests.el b/test/manual/cedet/cedet-utests.el index 94e5071352..e421054102 100644 --- a/test/manual/cedet/cedet-utests.el +++ b/test/manual/cedet/cedet-utests.el @@ -35,7 +35,6 @@ (defvar cedet-utest-libs '("ede-tests" "semantic-tests" - "srecode-tests" ) "List of test srcs that need to be loaded.") @@ -106,7 +105,7 @@ ;; ;; TODO - fix the fields test - ;;("srecode: fields" . srecode-field-utest) + ;;("srecode: fields" . srecode-field-utest) ; moved to automated suite ;;("srecode: templates" . srecode-utest-template-output) ("srecode: show maps" . srecode-get-maps) ;;("srecode: getset" . srecode-utest-getset-output) commit def546679fd93a4a1d049d9d3021166bf66a0e26 Author: Stefan Kangas Date: Wed Feb 10 06:40:13 2021 +0100 ; * test/lisp/cedet/semantic/format-tests.el: Minor cleanup. diff --git a/test/lisp/cedet/semantic/format-tests.el b/test/lisp/cedet/semantic/format-tests.el index a9eb4489d5..e82c97b4c4 100644 --- a/test/lisp/cedet/semantic/format-tests.el +++ b/test/lisp/cedet/semantic/format-tests.el @@ -20,7 +20,7 @@ ;; along with GNU Emacs. If not, see . ;;; Commentary: -;; + ;; Unit tests for the formatting feature. ;; ;; Using test code from the tests source directory, parse the source @@ -40,71 +40,55 @@ ) "List of files to run unit tests in.") -(defvar semantic-fmt-utest-error-log-list nil - "Log errors during testing in this variable.") - (ert-deftest semantic-fmt-utest () - "Visit all file entries, and run formatting test. -Files to visit are in `semantic-fmt-utest-file-list'." + "Visit all file entries, and run formatting test. " (save-current-buffer (semantic-mode 1) - (let ((fl semantic-fmt-utest-file-list)) - (dolist (fname fl) + (dolist (fname semantic-fmt-utest-file-list) + (let ((fb (find-buffer-visiting fname)) + (b (semantic-find-file-noselect fname)) + (tags nil)) (save-current-buffer - (let ((fb (find-buffer-visiting fname)) - (b (semantic-find-file-noselect fname)) - (tags nil)) - - (save-current-buffer - (set-buffer b) - (should (semantic-active-p)) - ;;(error "Cannot open %s for format tests" fname)) - - ;; This will force a reparse, removing any chance of semanticdb cache - ;; using stale data. - (semantic-clear-toplevel-cache) - ;; Force the reparse - (setq tags (semantic-fetch-tags)) - - (save-excursion - (while tags - (let* ((T (car tags)) - (start (semantic-tag-end T)) - (end (if (cdr tags) - (semantic-tag-start (car (cdr tags))) - (point-max))) - (TESTS nil) - ) - (goto-char start) - ;; Scan the space between tags for all test condition matches. - (while (re-search-forward "## \\([a-z-]+\\) \"\\([^\n\"]+\\)\"$" end t) - (push (cons (match-string 1) (match-string 2)) TESTS)) - (setq TESTS (nreverse TESTS)) - - (dolist (TST TESTS) - (let* ( ;; For each test, convert CAR into a semantic-format-tag* fcn - (sym (intern (concat "semantic-format-tag-" (car TST)))) - ;; Convert the desired result from a string syntax to a string. - (desired (cdr TST)) - ;; What does the fmt function do? - (actual (funcall sym T)) - ) - (when (not (string= desired actual)) - (should-not (list "Desired" desired - "Actual" actual - "Formatter" (car TST)))) - ))) - (setq tags (cdr tags))) - - )) - - ;; If it wasn't already in memory, whack it. - (when (and b (not fb)) - (kill-buffer b))) - )) - - ))) - + (set-buffer b) + (should (semantic-active-p)) + ;;(error "Cannot open %s for format tests" fname)) + + ;; This will force a reparse, removing any chance of semanticdb cache + ;; using stale data. + (semantic-clear-toplevel-cache) + ;; Force the reparse + (setq tags (semantic-fetch-tags)) + + (save-excursion + (while tags + (let* ((T (car tags)) + (start (semantic-tag-end T)) + (end (if (cdr tags) + (semantic-tag-start (car (cdr tags))) + (point-max))) + (TESTS nil)) + (goto-char start) + ;; Scan the space between tags for all test condition matches. + (while (re-search-forward "## \\([a-z-]+\\) \"\\([^\n\"]+\\)\"$" end t) + (push (cons (match-string 1) (match-string 2)) TESTS)) + (setq TESTS (nreverse TESTS)) + + (dolist (TST TESTS) + (let* ( ;; For each test, convert CAR into a semantic-format-tag* fcn + (sym (intern (concat "semantic-format-tag-" (car TST)))) + ;; Convert the desired result from a string syntax to a string. + (desired (cdr TST)) + ;; What does the fmt function do? + (actual (funcall sym T))) + (when (not (string= desired actual)) + (should-not (list "Desired" desired + "Actual" actual + "Formatter" (car TST))))))) + (setq tags (cdr tags))))) + + ;; If it wasn't already in memory, whack it. + (when (and b (not fb)) + (kill-buffer b)))))) (provide 'format-tests) commit c735ec94545d1ca726d6cdcfdf4b0847e55330d9 Author: Stefan Kangas Date: Wed Feb 10 04:48:43 2021 +0100 Make texinfmt-version variable obsolete * lisp/textmodes/texinfmt.el (texinfmt-version): Make variable and command obsolete in favour of 'emacs-version'. (texinfo-format-region, texinfo-format-buffer-1): Use 'emacs-version' instead of above obsolete variable. diff --git a/lisp/textmodes/texinfmt.el b/lisp/textmodes/texinfmt.el index ed0a367d01..fe052e3241 100644 --- a/lisp/textmodes/texinfmt.el +++ b/lisp/textmodes/texinfmt.el @@ -28,10 +28,12 @@ ;;; Emacs lisp functions to convert Texinfo files to Info files. (defvar texinfmt-version "2.42 of 7 Jul 2006") +(make-obsolete-variable 'texinfmt-version 'emacs-version "28.1") (defun texinfmt-version (&optional here) "Show the version of texinfmt.el in the minibuffer. If optional argument HERE is non-nil, insert info at point." + (declare (obsolete emacs-version "28.1")) (interactive "P") (let ((version-string (format-message "Version of `texinfmt.el': %s" texinfmt-version))) @@ -345,8 +347,8 @@ converted to Info is stored in a temporary buffer." (file-name-nondirectory (buffer-file-name input-buffer)))) (format-message "buffer `%s'" (buffer-name input-buffer))) - (format-message "\nusing `texinfmt.el' version ") - texinfmt-version + (format-message "\nusing `texinfmt.el' on Emacs version ") + emacs-version ".\n\n") ;; Now convert for real. @@ -489,8 +491,8 @@ if large. You can use `Info-split' to do this manually." (file-name-nondirectory (buffer-file-name input-buffer)))) (format-message "buffer `%s'" (buffer-name input-buffer))) - (format-message "\nusing `texinfmt.el' version ") - texinfmt-version + (format-message "\nusing `texinfmt.el' on Emacs version ") + emacs-version ".\n\n") ;; Return data for indices. (list outfile commit f0f548095358c8969847e7dc2ac4ba7bd8bb80b7 Author: Stefan Kangas Date: Wed Feb 10 04:42:37 2021 +0100 Use lexical-binding in bib-mode.el * lisp/textmodes/bib-mode.el: Use lexical-binding. Remove redundant :group args. diff --git a/lisp/textmodes/bib-mode.el b/lisp/textmodes/bib-mode.el index 1e22287d32..ec21987bbf 100644 --- a/lisp/textmodes/bib-mode.el +++ b/lisp/textmodes/bib-mode.el @@ -1,4 +1,4 @@ -;;; bib-mode.el --- major mode for editing bib files +;;; bib-mode.el --- major mode for editing bib files -*- lexical-binding: t -*- ;; Copyright (C) 1989, 2001-2021 Free Software Foundation, Inc. @@ -39,13 +39,11 @@ (defcustom bib-file "~/my-bibliography.bib" "Default name of file used by `addbib'." - :type 'file - :group 'bib) + :type 'file) (defcustom unread-bib-file "~/to-be-read.bib" "Default name of file used by `unread-bib' in Bib mode." - :type 'file - :group 'bib) + :type 'file) (defvar bib-mode-map (let ((map (make-sparse-keymap))) @@ -138,8 +136,7 @@ with the cdr.") (defcustom bib-auto-capitalize t "True to automatically capitalize appropriate fields in Bib mode." - :type 'boolean - :group 'bib) + :type 'boolean) (defconst bib-capitalized-fields "%[AETCBIJR]") commit c07459fd10a9352b32d4de6e9145a419772bd70b Author: Stefan Kangas Date: Wed Feb 10 04:14:48 2021 +0100 Move semantic/format.el tests to follow our conventions * test/lisp/cedet/semantic-utest-fmt.el: Move from here... * test/lisp/cedet/semantic/format-tests.el: ...to here. (ert, ert-x): Require. (semantic-fmt-utest-file-list): Use ert-resource-file. * test/manual/cedet/tests/test-fmt.cpp: * test/manual/cedet/tests/test-fmt.el: Move from here... * test/lisp/cedet/semantic/format-resources/test-fmt.cpp: * test/lisp/cedet/semantic/format-resources/test-fmt.el: ...to here. diff --git a/test/manual/cedet/tests/test-fmt.cpp b/test/lisp/cedet/semantic/format-resources/test-fmt.cpp similarity index 100% rename from test/manual/cedet/tests/test-fmt.cpp rename to test/lisp/cedet/semantic/format-resources/test-fmt.cpp diff --git a/test/manual/cedet/tests/test-fmt.el b/test/lisp/cedet/semantic/format-resources/test-fmt.el similarity index 95% rename from test/manual/cedet/tests/test-fmt.el rename to test/lisp/cedet/semantic/format-resources/test-fmt.el index 122571323b..941aaae859 100644 --- a/test/manual/cedet/tests/test-fmt.el +++ b/test/lisp/cedet/semantic/format-resources/test-fmt.el @@ -1,4 +1,4 @@ -;;; test-fmt.el --- test semantic tag formatting +;;; test-fmt.el --- test semantic tag formatting -*- lexical-binding: t -*- ;;; Copyright (C) 2012, 2019-2021 Free Software Foundation, Inc. diff --git a/test/lisp/cedet/semantic-utest-fmt.el b/test/lisp/cedet/semantic/format-tests.el similarity index 79% rename from test/lisp/cedet/semantic-utest-fmt.el rename to test/lisp/cedet/semantic/format-tests.el index d6e5ce7a0f..a9eb4489d5 100644 --- a/test/lisp/cedet/semantic-utest-fmt.el +++ b/test/lisp/cedet/semantic/format-tests.el @@ -1,4 +1,4 @@ -;;; cedet/semantic-utest-fmt.el --- Parsing / Formatting tests -*- lexical-binding:t -*- +;;; semantic/format-tests.el --- Parsing / Formatting tests -*- lexical-binding:t -*- ;;; Copyright (C) 2003-2004, 2007-2021 Free Software Foundation, Inc. @@ -28,19 +28,14 @@ ;; make sure that the semantic-tag-format-* functions in question ;; created the desired output. -(require 'semantic) -(require 'semantic/format) - ;;; Code: -(defvar cedet-utest-directory - (let* ((C (file-name-directory (locate-library "cedet"))) - (D (expand-file-name "../../test/manual/cedet/" C))) - D) - "Location of test files for this test suite.") +(require 'ert) +(require 'ert-x) +(require 'semantic/format) (defvar semantic-fmt-utest-file-list - '("tests/test-fmt.cpp" + (list (ert-resource-file "test-fmt.cpp") ;; "tests/test-fmt.el" - add this when elisp is support by dflt in Emacs ) "List of files to run unit tests in.") @@ -53,21 +48,10 @@ Files to visit are in `semantic-fmt-utest-file-list'." (save-current-buffer (semantic-mode 1) - (let ((fl semantic-fmt-utest-file-list) - (fname nil) - ) - - (dolist (FILE fl) - - (save-current-buffer - (setq fname (expand-file-name FILE cedet-utest-directory)) - - ;; Make sure we have the files we think we have. - (should (file-exists-p fname)) - ;; (error "Cannot find unit test file: %s" fname)) - - ;; Run the tests. - (let ((fb (find-buffer-visiting fname)) + (let ((fl semantic-fmt-utest-file-list)) + (dolist (fname fl) + (save-current-buffer + (let ((fb (find-buffer-visiting fname)) (b (semantic-find-file-noselect fname)) (tags nil)) @@ -122,6 +106,6 @@ Files to visit are in `semantic-fmt-utest-file-list'." ))) -(provide 'cedet/semantic/fmt-utest) +(provide 'format-tests) -;;; semantic-fmt-utest.el ends here +;;; format-tests.el ends here commit 18ad1388d00e40a031bead1d0b5a0ae429dcc8ad Author: Stefan Kangas Date: Wed Feb 10 03:06:27 2021 +0100 Use lexical-binding in some test files * test/manual/cedet/ede-tests.el: * test/manual/cedet/srecode-tests.el: * test/manual/cedet/tests/test.el: Use lexical-binding. * test/manual/etags/el-src/TAGTEST.EL: Add lexical-binding cookie. * test/manual/etags/ETAGS.good_1: Update expected result for the above change. diff --git a/test/manual/cedet/ede-tests.el b/test/manual/cedet/ede-tests.el index eb3132398a..2af50860c6 100644 --- a/test/manual/cedet/ede-tests.el +++ b/test/manual/cedet/ede-tests.el @@ -1,4 +1,4 @@ -;;; ede-tests.el --- Some tests for the Emacs Development Environment +;;; ede-tests.el --- Some tests for the Emacs Development Environment -*- lexical-binding: t -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -42,8 +42,7 @@ The search is done with the current EDE root." (ede-toplevel))))) (data-debug-new-buffer "*EDE Locate ADEBUG*") (ede-locate-file-in-project loc file) - (data-debug-insert-object-slots loc "]")) - ) + (data-debug-insert-object-slots loc "]"))) (defun ede-locate-test-global (file) "Test EDE Locate on FILE using GNU Global type. @@ -55,8 +54,7 @@ The search is done with the current EDE root." (ede-toplevel))))) (data-debug-new-buffer "*EDE Locate ADEBUG*") (ede-locate-file-in-project loc file) - (data-debug-insert-object-slots loc "]")) - ) + (data-debug-insert-object-slots loc "]"))) (defun ede-locate-test-idutils (file) "Test EDE Locate on FILE using ID Utils type. @@ -68,8 +66,7 @@ The search is done with the current EDE root." (ede-toplevel))))) (data-debug-new-buffer "*EDE Locate ADEBUG*") (ede-locate-file-in-project loc file) - (data-debug-insert-object-slots loc "]")) - ) + (data-debug-insert-object-slots loc "]"))) (defun ede-locate-test-cscope (file) "Test EDE Locate on FILE using CScope type. @@ -81,7 +78,6 @@ The search is done with the current EDE root." (ede-toplevel))))) (data-debug-new-buffer "*EDE Locate ADEBUG*") (ede-locate-file-in-project loc file) - (data-debug-insert-object-slots loc "]")) - ) + (data-debug-insert-object-slots loc "]"))) ;;; ede-test.el ends here diff --git a/test/manual/cedet/srecode-tests.el b/test/manual/cedet/srecode-tests.el index 483074078b..18ca07343d 100644 --- a/test/manual/cedet/srecode-tests.el +++ b/test/manual/cedet/srecode-tests.el @@ -1,4 +1,4 @@ -;;; srecode-tests.el --- Some tests for CEDET's srecode +;;; srecode-tests.el --- Some tests for CEDET's srecode -*- lexical-binding: t -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. diff --git a/test/manual/cedet/tests/test.el b/test/manual/cedet/tests/test.el index 3bc945d89f..a54c253be6 100644 --- a/test/manual/cedet/tests/test.el +++ b/test/manual/cedet/tests/test.el @@ -1,4 +1,4 @@ -;;; test.el --- Unit test file for Semantic Emacs Lisp support. +;;; test.el --- Unit test file for Semantic Emacs Lisp support. -*- lexical-binding: t -*- ;; Copyright (C) 2005-2021 Free Software Foundation, Inc. diff --git a/test/manual/etags/ETAGS.good_1 b/test/manual/etags/ETAGS.good_1 index 3de15514e7..e6b060f335 100644 --- a/test/manual/etags/ETAGS.good_1 +++ b/test/manual/etags/ETAGS.good_1 @@ -2143,11 +2143,11 @@ main(37,571 class D 41,622 D(43,659 -el-src/TAGTEST.EL,179 -(foo::defmumble bletch 1,0 -(defun foo==bar foo==bar2,33 -(defalias 'pending-delete-mode pending-delete-mode6,149 -(defalias (quote explicitly-quoted-pending-delete-mode)9,222 +el-src/TAGTEST.EL,181 +(foo::defmumble bletch 3,33 +(defun foo==bar foo==bar4,66 +(defalias 'pending-delete-mode pending-delete-mode8,182 +(defalias (quote explicitly-quoted-pending-delete-mode)11,255 el-src/emacs/lisp/progmodes/etags.el,5069 (defvar tags-file-name 34,1035 diff --git a/test/manual/etags/el-src/TAGTEST.EL b/test/manual/etags/el-src/TAGTEST.EL index 89a6791377..3e6599a4a4 100644 --- a/test/manual/etags/el-src/TAGTEST.EL +++ b/test/manual/etags/el-src/TAGTEST.EL @@ -1,3 +1,5 @@ +;;; -*- lexical-binding: t -*- + (foo::defmumble bletch beuarghh) (defun foo==bar () (message "hi")) ; Bug#5624 ;;; Ctags test file for lisp mode. commit 45934e51e427712b96ff3b58a940d9327d15468d Author: Stefan Kangas Date: Wed Feb 10 03:02:03 2021 +0100 Change default semantic-lex-analyzer to semantic-lex * lisp/cedet/semantic/lex.el (semantic-lex-analyzer): Change default to semantic-lex, since semantic-flex was obsolete and has been removed. diff --git a/lisp/cedet/semantic/lex.el b/lisp/cedet/semantic/lex.el index 4cafc7d4fe..ae70d5c730 100644 --- a/lisp/cedet/semantic/lex.el +++ b/lisp/cedet/semantic/lex.el @@ -469,11 +469,9 @@ PROPERTY set." ;;; Lexical Analyzer framework settings ;; -;; FIXME change to non-obsolete default. -(defvar-local semantic-lex-analyzer 'semantic-flex +(defvar-local semantic-lex-analyzer 'semantic-lex "The lexical analyzer used for a given buffer. -See `semantic-lex' for documentation. -For compatibility with Semantic 1.x it defaults to `semantic-flex'.") +See `semantic-lex' for documentation.") (defvar semantic-lex-tokens '( commit 843ca067dbee2555b91f3b08f7acc8a70915f383 Author: Stefan Kangas Date: Wed Feb 10 02:07:55 2021 +0100 Convert many manual cedet tests to ert * test/manual/cedet/cedet-utests.el (cedet-files-utest): Move test from here... * test/lisp/cedet/cedet-files-tests.el: ...to this new file. * test/manual/cedet/srecode-tests.el (srecode-document-function-comment-extract-test): Move test from here... * test/lisp/cedet/srecode/document-tests.el: ...to this new file. * test/manual/cedet/cedet-utests.el (inversion-unit-test): Move test from here... * test/lisp/cedet/inversion-tests.el: ...to this new file. * test/manual/cedet/semantic-tests.el (semantic-gcc-test-output-parser): Move test from here... * test/lisp/cedet/semantic/bovine/gcc-tests.el: ...to this new file. * test/manual/cedet/semantic-tests.el (semantic-test-data-cache): Move test from here... * test/lisp/cedet/semantic/fw-tests.el: ...to this new file. diff --git a/test/lisp/cedet/cedet-files-tests.el b/test/lisp/cedet/cedet-files-tests.el new file mode 100644 index 0000000000..5502d42431 --- /dev/null +++ b/test/lisp/cedet/cedet-files-tests.el @@ -0,0 +1,54 @@ +;;; cedet-files-tests.el --- Tests for cedet-files.el -*- lexical-binding:t -*- + +;; Copyright (C) 2008-2021 Free Software Foundation, Inc. + +;; Author: Eric M. Ludlam + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; Moved here from test/manual/cedet/cedet-utests.el + +;;; Code: + +(require 'ert) +(require 'cedet-files) + +(defvar cedet-files-utest-list + '( + ( "/home/me/src/myproj/src/foo.c" . "!home!me!src!myproj!src!foo.c" ) + ( "c:/work/myproj/foo.el" . "!drive_c!work!myproj!foo.el" ) + ( "//windows/proj/foo.java" . "!!windows!proj!foo.java" ) + ( "/home/me/proj!bang/foo.c" . "!home!me!proj!!bang!foo.c" ) + ) + "List of different file names to test. +Each entry is a cons cell of ( FNAME . CONVERTED ) +where FNAME is some file name, and CONVERTED is what it should be +converted into.") + +(ert-deftest cedet-files-utest () + "Test out some file name conversions." + (interactive) + (dolist (FT cedet-files-utest-list) + (let ((dir->file (cedet-directory-name-to-file-name (car FT) t)) + (file->dir (cedet-file-name-to-directory-name (cdr FT) t))) + (should (string= (cdr FT) dir->file)) + (should (string= file->dir (car FT)))))) + +(provide 'cedet-files-tests) + +;;; cedet-files-tests.el ends here diff --git a/test/lisp/cedet/inversion-tests.el b/test/lisp/cedet/inversion-tests.el new file mode 100644 index 0000000000..c8b45d67ea --- /dev/null +++ b/test/lisp/cedet/inversion-tests.el @@ -0,0 +1,81 @@ +;;; inversion-tests.el --- Tests for inversion.el -*- lexical-binding:t -*- + +;; Copyright (C) 2008-2021 Free Software Foundation, Inc. + +;; Author: Eric M. Ludlam + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; Moved here from test/manual/cedet/cedet-utests.el + +;;; Code: + +(require 'inversion) +(require 'ert) + +(ert-deftest inversion-unit-test () + "Test inversion to make sure it can identify different version strings." + (interactive) + (let ((c1 (inversion-package-version 'inversion)) + (c1i (inversion-package-incompatibility-version 'inversion)) + (c2 (inversion-decode-version "1.3alpha2")) + (c3 (inversion-decode-version "1.3beta4")) + (c4 (inversion-decode-version "1.3 beta5")) + (c5 (inversion-decode-version "1.3.4")) + (c6 (inversion-decode-version "2.3alpha")) + (c7 (inversion-decode-version "1.3")) + (c8 (inversion-decode-version "1.3pre1")) + (c9 (inversion-decode-version "2.4 (patch 2)")) + (c10 (inversion-decode-version "2.4 (patch 3)")) + (c11 (inversion-decode-version "2.4.2.1")) + (c12 (inversion-decode-version "2.4.2.2"))) + (should (inversion-= c1 c1)) + (should (inversion-< c1i c1)) + (should (inversion-< c2 c3)) + (should (inversion-< c3 c4)) + (should (inversion-< c4 c5)) + (should (inversion-< c5 c6)) + (should (inversion-< c2 c4)) + (should (inversion-< c2 c5)) + (should (inversion-< c2 c6)) + (should (inversion-< c3 c5)) + (should (inversion-< c3 c6)) + (should (inversion-< c7 c6)) + (should (inversion-< c4 c7)) + (should (inversion-< c2 c7)) + (should (inversion-< c8 c6)) + (should (inversion-< c8 c7)) + (should (inversion-< c4 c8)) + (should (inversion-< c2 c8)) + (should (inversion-< c9 c10)) + (should (inversion-< c10 c11)) + (should (inversion-< c11 c12)) + ;; Negatives + (should-not (inversion-< c3 c2)) + (should-not (inversion-< c4 c3)) + (should-not (inversion-< c5 c4)) + (should-not (inversion-< c6 c5)) + (should-not (inversion-< c7 c2)) + (should-not (inversion-< c7 c8)) + (should-not (inversion-< c12 c11)) + ;; Test the tester on inversion + (should-not (inversion-test 'inversion inversion-version)) + (should (stringp (inversion-test 'inversion "0.0.0"))) + (should (stringp (inversion-test 'inversion "1000.0"))))) + +;;; inversion-tests.el ends here diff --git a/test/lisp/cedet/semantic/bovine/gcc-tests.el b/test/lisp/cedet/semantic/bovine/gcc-tests.el new file mode 100644 index 0000000000..e1a18c6c64 --- /dev/null +++ b/test/lisp/cedet/semantic/bovine/gcc-tests.el @@ -0,0 +1,129 @@ +;;; gcc-tests.el --- Tests for semantic/bovine/gcc.el -*- lexical-binding:t -*- + +;;; Copyright (C) 2003-2004, 2007-2021 Free Software Foundation, Inc. + +;; Author: Eric M. Ludlam + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; Moved here from test/manual/cedet/semantic-tests.el + +;;; Code: + +(require 'ert) +(require 'semantic/bovine/gcc) + +;;; From bovine-gcc: + +;; Example output of "gcc -v" +(defvar semantic-gcc-test-strings + '(;; My old box: + "Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs +Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux +Thread model: posix +gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)" + ;; Alex Ott: + "Using built-in specs. +Target: i486-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.3.1-9ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu +Thread model: posix +gcc version 4.3.1 (Ubuntu 4.3.1-9ubuntu1)" + ;; My debian box: + "Using built-in specs. +Target: x86_64-unknown-linux-gnu +Configured with: ../../../sources/gcc/configure --prefix=/usr/local/glibc-2.3.6/x86_64/apps/gcc-4.2.3 --with-gmp=/usr/local/gcc/gmp --with-mpfr=/usr/local/gcc/mpfr --enable-languages=c,c++,fortran --with-as=/usr/local/glibc-2.3.6/x86_64/apps/gcc-4.2.3/bin/as --with-ld=/usr/local/glibc-2.3.6/x86_64/apps/gcc-4.2.3/bin/ld --disable-multilib +Thread model: posix +gcc version 4.2.3" + ;; My mac: + "Using built-in specs. +Target: i686-apple-darwin8 +Configured with: /private/var/tmp/gcc/gcc-5341.obj~1/src/configure --disable-checking -enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.0/ --with-gxx-include-dir=/include/c++/4.0.0 --with-slibdir=/usr/lib --build=powerpc-apple-darwin8 --with-arch=pentium-m --with-tune=prescott --program-prefix= --host=i686-apple-darwin8 --target=i686-apple-darwin8 +Thread model: posix +gcc version 4.0.1 (Apple Computer, Inc. build 5341)" + ;; Ubuntu Intrepid + "Using built-in specs. +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.3.2-1ubuntu12' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 4.3.2 (Ubuntu 4.3.2-1ubuntu12)" + ;; Red Hat EL4 + "Reading specs from /usr/lib/gcc/x86_64-redhat-linux/3.4.6/specs +Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=x86_64-redhat-linux +Thread model: posix +gcc version 3.4.6 20060404 (Red Hat 3.4.6-10)" + ;; Red Hat EL5 + "Using built-in specs. +Target: x86_64-redhat-linux +Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux +Thread model: posix +gcc version 4.1.2 20080704 (Red Hat 4.1.2-44)" + ;; David Engster's german gcc on ubuntu 4.3 + "Es werden eingebaute Spezifikationen verwendet. +Ziel: i486-linux-gnu +Konfiguriert mit: ../src/configure -v --with-pkgversion='Ubuntu 4.3.2-1ubuntu12' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu +Thread-Modell: posix +gcc-Version 4.3.2 (Ubuntu 4.3.2-1ubuntu12)" + ;; Damien Deville bsd + "Using built-in specs. +Target: i386-undermydesk-freebsd +Configured with: FreeBSD/i386 system compiler +Thread model: posix +gcc version 4.2.1 20070719 [FreeBSD]" + ) + "A bunch of sample gcc -v outputs from different machines.") + +(defvar semantic-gcc-test-strings-fail + '(;; A really old solaris box I found + "Reading specs from /usr/local/gcc-2.95.2/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/specs +gcc version 2.95.2 19991024 (release)" + ) + "A bunch of sample gcc -v outputs that fail to provide the info we want.") + +(defun semantic-gcc-test-output-parser () + "Test the output parser against some collected strings." + (dolist (S semantic-gcc-test-strings) + (let* ((fields (semantic-gcc-fields S)) + (v (cdr (assoc 'version fields))) + (h (or (cdr (assoc 'target fields)) + (cdr (assoc '--target fields)) + (cdr (assoc '--host fields)))) + (p (cdr (assoc '--prefix fields)))) + ;; No longer test for prefixes. + (when (not (and v h)) + (let ((strs (split-string S "\n"))) + (error "Test failed on %S\nV H P:\n%S %S %S" (car strs) v h p))))) + (dolist (S semantic-gcc-test-strings-fail) + (let* ((fields (semantic-gcc-fields S)) + (v (cdr (assoc 'version fields))) + (h (or (cdr (assoc '--host fields)) + (cdr (assoc 'target fields)))) + (p (cdr (assoc '--prefix fields))) + ) + (when (and v h p) + (error "Negative test failed on %S" S))))) + +(ert-deftest semantic-gcc-test-output-parser () + (semantic-gcc-test-output-parser)) + +(ert-deftest semantic-gcc-test-output-parser-this-machine () + "Test the output parser against the machine currently running Emacs." + (skip-unless (executable-find "gcc")) + (let ((semantic-gcc-test-strings (list (semantic-gcc-query "gcc" "-v")))) + (semantic-gcc-test-output-parser))) + +;;; gcc-tests.el ends here diff --git a/test/lisp/cedet/semantic/fw-tests.el b/test/lisp/cedet/semantic/fw-tests.el new file mode 100644 index 0000000000..62d665dbb6 --- /dev/null +++ b/test/lisp/cedet/semantic/fw-tests.el @@ -0,0 +1,45 @@ +;;; fw-tests.el --- Tests for semantic/fw.el -*- lexical-binding:t -*- + +;;; Copyright (C) 2003-2004, 2007-2021 Free Software Foundation, Inc. + +;; Author: Eric M. Ludlam + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; Moved here from test/manual/cedet/semantic-tests.el + +;;; Code: + +(require 'ert) +(require 'semantic/fw) + +;;; From semantic-fw: + +(ert-deftest semantic-test-data-cache () + "Test the data cache." + (let ((data '(a b c))) + (with-current-buffer (get-buffer-create " *semantic-test-data-cache*") + (erase-buffer) + (insert "The Moose is Loose") + (goto-char (point-min)) + (semantic-cache-data-to-buffer (current-buffer) (point) (+ (point) 5) + data 'moose 'exit-cache-zone) + ;; retrieve cached data + (should (equal (semantic-get-cache-data 'moose) data))))) + +;;; gw-tests.el ends here diff --git a/test/lisp/cedet/srecode/document-tests.el b/test/lisp/cedet/srecode/document-tests.el new file mode 100644 index 0000000000..0bc6e10d7a --- /dev/null +++ b/test/lisp/cedet/srecode/document-tests.el @@ -0,0 +1,80 @@ +;;; document-tests.el --- Tests for srecode/document.el -*- lexical-binding:t -*- + +;; Copyright (C) 2008-2021 Free Software Foundation, Inc. + +;; Author: Eric M. Ludlam + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; Extracted from srecode-document.el in the CEDET distribution. + +;; Converted to ert from test/manual/cedet/srecode-tests.el + +;;; Code: + +(require 'ert) +(require 'srecode/document) + +;; FIXME: This test fails even before conversion to ert. +(ert-deftest srecode-document-function-comment-extract-test () + "Test old comment extraction. +Dump out the extracted dictionary." + :tags '(:unstable) + (interactive) + + (srecode-load-tables-for-mode major-mode) + (srecode-load-tables-for-mode major-mode 'document) + + (should (srecode-table)) + ;; (error "No template table found for mode %s" major-mode) + + (let* ((temp (srecode-template-get-table (srecode-table) + "function-comment" + "declaration" + 'document)) + (fcn-in (semantic-current-tag))) + + (should temp) + ;; (error "No templates for function comments") + + ;; Try to figure out the tag we want to use. + (should fcn-in) + (should (semantic-tag-of-class-p fcn-in 'function)) + ;; (error "No tag of class 'function to insert comment for") + + (let ((lextok (semantic-documentation-comment-preceding-tag fcn-in 'lex))) + + (should lextok) + ;; (error "No comment to attempt an extraction") + + (let ((s (semantic-lex-token-start lextok)) + (e (semantic-lex-token-end lextok)) + (extract nil)) + + (pulse-momentary-highlight-region s e) + + ;; Extract text from the existing comment. + (setq extract (srecode-extract temp s e)) + + (with-output-to-temp-buffer "*SRECODE DUMP*" + (princ "EXTRACTED DICTIONARY FOR ") + (princ (semantic-tag-name fcn-in)) + (princ "\n--------------------------------------------\n") + (srecode-dump extract)))))) + +;;; document-tests.el ends here diff --git a/test/manual/cedet/cedet-utests.el b/test/manual/cedet/cedet-utests.el index 7805fce2d1..94e5071352 100644 --- a/test/manual/cedet/cedet-utests.el +++ b/test/manual/cedet/cedet-utests.el @@ -26,7 +26,6 @@ ;; into one command. (require 'cedet) -(require 'inversion) (defvar cedet-utest-directory (let* ((C (file-name-directory (locate-library "cedet"))) @@ -48,7 +47,7 @@ ;; ;; Test inversion - ("inversion" . inversion-unit-test) + ;; ("inversion" . inversion-unit-test) ; moved to automated suite ;; EZ Image dumping. ("ezimage associations" . ezimage-image-association-dump) @@ -60,7 +59,7 @@ ("pulse interactive test" . (lambda () (pulse-test t))) ;; Files - ("cedet file conversion" . cedet-files-utest) + ;; ("cedet file conversion" . cedet-files-utest) ; moved to automated suite ;; ;; EIEIO @@ -100,7 +99,7 @@ (message " ** Skipping test in noninteractive mode.") (semantic-test-throw-on-input)))) - ;;("semantic: gcc: output parse test" . semantic-gcc-test-output-parser) + ;;("semantic: gcc: output parse test" . semantic-gcc-test-output-parser) ; moved to automated suite ;; ;; SRECODE @@ -376,7 +375,7 @@ Optional argument PRECR indicates to prefix the done msg w/ a newline." (cedet-utest-add-log-item-start testname) )) -(defun cedet-utest-log(format &rest args) +(defun cedet-utest-log (format &rest args) "Log the text string FORMAT. The rest of the ARGS are used to fill in FORMAT with `format'." (if noninteractive @@ -392,99 +391,6 @@ The rest of the ARGS are used to fill in FORMAT with `format'." (cedet-utest-show-log-end) ) -;;; Inversion tests - -(defun inversion-unit-test () - "Test inversion to make sure it can identify different version strings." - (interactive) - (let ((c1 (inversion-package-version 'inversion)) - (c1i (inversion-package-incompatibility-version 'inversion)) - (c2 (inversion-decode-version "1.3alpha2")) - (c3 (inversion-decode-version "1.3beta4")) - (c4 (inversion-decode-version "1.3 beta5")) - (c5 (inversion-decode-version "1.3.4")) - (c6 (inversion-decode-version "2.3alpha")) - (c7 (inversion-decode-version "1.3")) - (c8 (inversion-decode-version "1.3pre1")) - (c9 (inversion-decode-version "2.4 (patch 2)")) - (c10 (inversion-decode-version "2.4 (patch 3)")) - (c11 (inversion-decode-version "2.4.2.1")) - (c12 (inversion-decode-version "2.4.2.2")) - ) - (if (not (and - (inversion-= c1 c1) - (inversion-< c1i c1) - (inversion-< c2 c3) - (inversion-< c3 c4) - (inversion-< c4 c5) - (inversion-< c5 c6) - (inversion-< c2 c4) - (inversion-< c2 c5) - (inversion-< c2 c6) - (inversion-< c3 c5) - (inversion-< c3 c6) - (inversion-< c7 c6) - (inversion-< c4 c7) - (inversion-< c2 c7) - (inversion-< c8 c6) - (inversion-< c8 c7) - (inversion-< c4 c8) - (inversion-< c2 c8) - (inversion-< c9 c10) - (inversion-< c10 c11) - (inversion-< c11 c12) - ;; Negatives - (not (inversion-< c3 c2)) - (not (inversion-< c4 c3)) - (not (inversion-< c5 c4)) - (not (inversion-< c6 c5)) - (not (inversion-< c7 c2)) - (not (inversion-< c7 c8)) - (not (inversion-< c12 c11)) - ;; Test the tester on inversion - (not (inversion-test 'inversion inversion-version)) - ;; Test that we throw an error - (inversion-test 'inversion "0.0.0") - (inversion-test 'inversion "1000.0") - )) - (error "Inversion tests failed") - (message "Inversion tests passed.")))) - -;;; cedet-files unit test - -(defvar cedet-files-utest-list - '( - ( "/home/me/src/myproj/src/foo.c" . "!home!me!src!myproj!src!foo.c" ) - ( "c:/work/myproj/foo.el" . "!drive_c!work!myproj!foo.el" ) - ( "//windows/proj/foo.java" . "!!windows!proj!foo.java" ) - ( "/home/me/proj!bang/foo.c" . "!home!me!proj!!bang!foo.c" ) - ) - "List of different file names to test. -Each entry is a cons cell of ( FNAME . CONVERTED ) -where FNAME is some file name, and CONVERTED is what it should be -converted into.") - -(defun cedet-files-utest () - "Test out some file name conversions." - (interactive) - (let ((idx 0)) - (dolist (FT cedet-files-utest-list) - - (setq idx (+ idx 1)) - - (let ((dir->file (cedet-directory-name-to-file-name (car FT) t)) - (file->dir (cedet-file-name-to-directory-name (cdr FT) t)) - ) - - (unless (string= (cdr FT) dir->file) - (error "Failed: %d. Found: %S Wanted: %S" - idx dir->file (cdr FT)) - ) - - (unless (string= file->dir (car FT)) - (error "Failed: %d. Found: %S Wanted: %S" - idx file->dir (car FT))))))) - ;;; pulse test (defun pulse-test (&optional no-error) diff --git a/test/manual/cedet/semantic-tests.el b/test/manual/cedet/semantic-tests.el index 716bcc7abe..3d72fa2965 100644 --- a/test/manual/cedet/semantic-tests.el +++ b/test/manual/cedet/semantic-tests.el @@ -138,21 +138,6 @@ Optional argument ARG specifies not to use color." (require 'semantic/fw) -(defun semantic-test-data-cache () - "Test the data cache." - (interactive) - (let ((data '(a b c))) - (save-excursion - (set-buffer (get-buffer-create " *semantic-test-data-cache*")) - (erase-buffer) - (insert "The Moose is Loose") - (goto-char (point-min)) - (semantic-cache-data-to-buffer (current-buffer) (point) (+ (point) 5) - data 'moose 'exit-cache-zone) - (if (equal (semantic-get-cache-data 'moose) data) - (message "Successfully retrieved cached data.") - (error "Failed to retrieve cached data"))))) - (defun semantic-test-throw-on-input () "Test that throw on input will work." (interactive) @@ -281,110 +266,3 @@ tag that contains point, and return that." Lcount (semantic-tag-name target) (semantic-elapsed-time start nil))) Lcount))) - -;;; From bovine-gcc: - -(require 'semantic/bovine/gcc) - -;; Example output of "gcc -v" -(defvar semantic-gcc-test-strings - '(;; My old box: - "Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs -Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux -Thread model: posix -gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)" - ;; Alex Ott: - "Using built-in specs. -Target: i486-linux-gnu -Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.3.1-9ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu -Thread model: posix -gcc version 4.3.1 (Ubuntu 4.3.1-9ubuntu1)" - ;; My debian box: - "Using built-in specs. -Target: x86_64-unknown-linux-gnu -Configured with: ../../../sources/gcc/configure --prefix=/usr/local/glibc-2.3.6/x86_64/apps/gcc-4.2.3 --with-gmp=/usr/local/gcc/gmp --with-mpfr=/usr/local/gcc/mpfr --enable-languages=c,c++,fortran --with-as=/usr/local/glibc-2.3.6/x86_64/apps/gcc-4.2.3/bin/as --with-ld=/usr/local/glibc-2.3.6/x86_64/apps/gcc-4.2.3/bin/ld --disable-multilib -Thread model: posix -gcc version 4.2.3" - ;; My mac: - "Using built-in specs. -Target: i686-apple-darwin8 -Configured with: /private/var/tmp/gcc/gcc-5341.obj~1/src/configure --disable-checking -enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.0/ --with-gxx-include-dir=/include/c++/4.0.0 --with-slibdir=/usr/lib --build=powerpc-apple-darwin8 --with-arch=pentium-m --with-tune=prescott --program-prefix= --host=i686-apple-darwin8 --target=i686-apple-darwin8 -Thread model: posix -gcc version 4.0.1 (Apple Computer, Inc. build 5341)" - ;; Ubuntu Intrepid - "Using built-in specs. -Target: x86_64-linux-gnu -Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.3.2-1ubuntu12' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu -Thread model: posix -gcc version 4.3.2 (Ubuntu 4.3.2-1ubuntu12)" - ;; Red Hat EL4 - "Reading specs from /usr/lib/gcc/x86_64-redhat-linux/3.4.6/specs -Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=x86_64-redhat-linux -Thread model: posix -gcc version 3.4.6 20060404 (Red Hat 3.4.6-10)" - ;; Red Hat EL5 - "Using built-in specs. -Target: x86_64-redhat-linux -Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux -Thread model: posix -gcc version 4.1.2 20080704 (Red Hat 4.1.2-44)" - ;; David Engster's german gcc on ubuntu 4.3 - "Es werden eingebaute Spezifikationen verwendet. -Ziel: i486-linux-gnu -Konfiguriert mit: ../src/configure -v --with-pkgversion='Ubuntu 4.3.2-1ubuntu12' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu -Thread-Modell: posix -gcc-Version 4.3.2 (Ubuntu 4.3.2-1ubuntu12)" - ;; Damien Deville bsd - "Using built-in specs. -Target: i386-undermydesk-freebsd -Configured with: FreeBSD/i386 system compiler -Thread model: posix -gcc version 4.2.1 20070719 [FreeBSD]" - ) - "A bunch of sample gcc -v outputs from different machines.") - -(defvar semantic-gcc-test-strings-fail - '(;; A really old solaris box I found - "Reading specs from /usr/local/gcc-2.95.2/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/specs -gcc version 2.95.2 19991024 (release)" - ) - "A bunch of sample gcc -v outputs that fail to provide the info we want.") - -(defun semantic-gcc-test-output-parser () - "Test the output parser against some collected strings." - (interactive) - (let ((fail nil)) - (dolist (S semantic-gcc-test-strings) - (let* ((fields (semantic-gcc-fields S)) - (v (cdr (assoc 'version fields))) - (h (or (cdr (assoc 'target fields)) - (cdr (assoc '--target fields)) - (cdr (assoc '--host fields)))) - (p (cdr (assoc '--prefix fields))) - ) - ;; No longer test for prefixes. - (when (not (and v h)) - (let ((strs (split-string S "\n"))) - (message "Test failed on %S\nV H P:\n%S %S %S" (car strs) v h p)) - (setq fail t)) - )) - (dolist (S semantic-gcc-test-strings-fail) - (let* ((fields (semantic-gcc-fields S)) - (v (cdr (assoc 'version fields))) - (h (or (cdr (assoc '--host fields)) - (cdr (assoc 'target fields)))) - (p (cdr (assoc '--prefix fields))) - ) - (when (and v h p) - (message "Negative test failed on %S" S) - (setq fail t)) - )) - (if (not fail) (message "Tests passed.")) - )) - -(defun semantic-gcc-test-output-parser-this-machine () - "Test the output parser against the machine currently running Emacs." - (interactive) - (let ((semantic-gcc-test-strings (list (semantic-gcc-query "gcc" "-v")))) - (semantic-gcc-test-output-parser)) - ) diff --git a/test/manual/cedet/srecode-tests.el b/test/manual/cedet/srecode-tests.el index ebc3261f81..483074078b 100644 --- a/test/manual/cedet/srecode-tests.el +++ b/test/manual/cedet/srecode-tests.el @@ -241,54 +241,4 @@ It is filled with some text." (message " All field tests passed.") )) -;;; From srecode-document: - -(require 'srecode/document) - -(defun srecode-document-function-comment-extract-test () - "Test old comment extraction. -Dump out the extracted dictionary." - (interactive) - - (srecode-load-tables-for-mode major-mode) - (srecode-load-tables-for-mode major-mode 'document) - - (if (not (srecode-table)) - (error "No template table found for mode %s" major-mode)) - - (let* ((temp (srecode-template-get-table (srecode-table) - "function-comment" - "declaration" - 'document)) - (fcn-in (semantic-current-tag))) - - (if (not temp) - (error "No templates for function comments")) - - ;; Try to figure out the tag we want to use. - (when (or (not fcn-in) - (not (semantic-tag-of-class-p fcn-in 'function))) - (error "No tag of class 'function to insert comment for")) - - (let ((lextok (semantic-documentation-comment-preceding-tag fcn-in 'lex)) - ) - - (when (not lextok) - (error "No comment to attempt an extraction")) - - (let ((s (semantic-lex-token-start lextok)) - (e (semantic-lex-token-end lextok)) - (extract nil)) - - (pulse-momentary-highlight-region s e) - - ;; Extract text from the existing comment. - (setq extract (srecode-extract temp s e)) - - (with-output-to-temp-buffer "*SRECODE DUMP*" - (princ "EXTRACTED DICTIONARY FOR ") - (princ (semantic-tag-name fcn-in)) - (princ "\n--------------------------------------------\n") - (srecode-dump extract)))))) - ;;; srecode-tests.el ends here commit a0451be18b2581f5288e1123ee7bbd2aabccbe52 Author: Stefan Kangas Date: Wed Feb 10 01:23:41 2021 +0100 Use lexical-binding in almost all of play/*.el * lisp/play/5x5.el: Use lexical-binding. (5x5-draw-grid-end, 5x5-draw-grid, 5x5-solver) (5x5-solve-suggest): Silence byte-compiler. * lisp/play/cookie1.el: Use lexical-binding. (cookie-shuffle-vector, cookie-apropos): Silence byte-compiler. * lisp/play/zone.el: Use lexical-binding. (zone): Convert lambda to proper lexical closure. (zone-replace-char, zone-fill-out-screen): Silence byte-compiler. * lisp/play/blackbox.el: * lisp/play/doctor.el: * lisp/play/gametree.el: * lisp/play/hanoi.el: Use lexical-binding. * test/lisp/play/cookie1-resources/cookies: * test/lisp/play/cookie1-tests.el: New files. diff --git a/lisp/play/5x5.el b/lisp/play/5x5.el index 05e61dfe40..891a5f6cba 100644 --- a/lisp/play/5x5.el +++ b/lisp/play/5x5.el @@ -1,4 +1,4 @@ -;;; 5x5.el --- simple little puzzle game +;;; 5x5.el --- simple little puzzle game -*- lexical-binding: t -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. @@ -289,7 +289,7 @@ Quit current game \\[5x5-quit-game]" (defun 5x5-draw-grid-end () "Draw the top/bottom of the grid." (insert "+") - (dotimes (x 5x5-grid-size) + (dotimes (_ 5x5-grid-size) (insert "-" (make-string 5x5-x-scale ?-))) (insert "-+ ")) @@ -297,11 +297,11 @@ Quit current game \\[5x5-quit-game]" "Draw the grids GRIDS into the current buffer." (let ((inhibit-read-only t) grid-org) (erase-buffer) - (dolist (grid grids) (5x5-draw-grid-end)) + (dolist (_ grids) (5x5-draw-grid-end)) (insert "\n") (setq grid-org (point)) (dotimes (y 5x5-grid-size) - (dotimes (lines 5x5-y-scale) + (dotimes (_lines 5x5-y-scale) (dolist (grid grids) (dotimes (x 5x5-grid-size) (insert (if (zerop x) "| " " ") @@ -331,7 +331,7 @@ Quit current game \\[5x5-quit-game]" (forward-char (1+ 5x5-x-scale)))) (forward-line 5x5-y-scale)))) (setq 5x5-solver-output nil))) - (dolist (grid grids) (5x5-draw-grid-end)) + (dolist (_grid grids) (5x5-draw-grid-end)) (insert "\n") (insert (format "On: %d Moves: %d" (5x5-grid-value (car grids)) 5x5-moves)))) @@ -475,11 +475,11 @@ position." "Convert a grid matrix GRID-MATRIX in Calc format to a grid in 5x5 format. See function `5x5-grid-to-vec'." (apply - 'vector + #'vector (mapcar (lambda (x) (apply - 'vector + #'vector (mapcar (lambda (y) (/= (cadr y) 0)) (cdr x)))) @@ -503,7 +503,9 @@ position." Log a matrix VALUE of (mod B 2) forms, only B is output and Scilab matrix notation is used. VALUE is returned so that it is easy to log a value with minimal rewrite of code." - (when (buffer-live-p 5x5-log-buffer) + (when (buffer-live-p 5x5-log-buffer) + (defvar calc-matrix-brackets) + (defvar calc-vector-commas) (let* ((unpacked-value (math-map-vec (lambda (row) (math-map-vec 'cadr row)) @@ -515,7 +517,7 @@ easy to log a value with minimal rewrite of code." (insert name ?= value-to-log ?\n)))) value)) (defsubst 5x5-log-init ()) - (defsubst 5x5-log (name value) value))) + (defsubst 5x5-log (_name value) value))) (declare-function math-map-vec "calc-vec" (f a)) (declare-function math-sub "calc" (a b)) @@ -533,6 +535,10 @@ easy to log a value with minimal rewrite of code." (declare-function calcFunc-mcol "calc-vec" (mat n)) (declare-function calcFunc-vconcat "calc-vec" (a b)) (declare-function calcFunc-index "calc-vec" (n &optional start incr)) +(defvar calc-word-size) +(defvar calc-leading-zeros) +(defvar calc-number-radix) +(defvar calc-command-flags) (defun 5x5-solver (grid) "Return a list of solutions for GRID. @@ -671,16 +677,16 @@ Solutions are sorted from least to greatest Hamming weight." (5x5-log "cb" (math-mul inv-base-change targetv))); CB - (row-1 (math-make-intv 3 1 transferm-kernel-size)) ; 1..2 + ;; (row-1 (math-make-intv 3 1 transferm-kernel-size)) ; 1..2 (row-2 (math-make-intv 1 transferm-kernel-size grid-size-squared)); 3..25 (col-1 (math-make-intv 3 1 (- grid-size-squared transferm-kernel-size))); 1..23 - (col-2 (math-make-intv 1 (- grid-size-squared - transferm-kernel-size) - grid-size-squared)); 24..25 - (ctransferm-1-: (calcFunc-mrow ctransferm row-1)) - (ctransferm-1-1 (calcFunc-mcol ctransferm-1-: col-1)) + ;; (col-2 (math-make-intv 1 (- grid-size-squared + ;; transferm-kernel-size) + ;; grid-size-squared)) ; 24..25 + ;; (ctransferm-1-: (calcFunc-mrow ctransferm row-1)) + ;; (ctransferm-1-1 (calcFunc-mcol ctransferm-1-: col-1)) ;; By construction ctransferm-:-2 = 0, so ctransferm-1-2 = 0 ;; and ctransferm-2-2 = 0. @@ -696,8 +702,8 @@ Solutions are sorted from least to greatest Hamming weight." ;; ;;(ctransferm-2-2 (calcFunc-mcol ctransferm-2-: col-2)) - (ctarget-1 (calcFunc-mrow ctarget row-1)) - (ctarget-2 (calcFunc-mrow ctarget row-2)) + ;; (ctarget-1 (calcFunc-mrow ctarget row-1)) + (ctarget-2 (calcFunc-mrow ctarget row-2)) ;; ctarget-1(2x1) = ctransferm-1-1(2x23) *cx-1(23x1) ;; + ctransferm-1-2(2x2) *cx-2(2x1); @@ -770,7 +776,7 @@ Solutions are sorted from least to greatest Hamming weight." (message "5x5 Solution computation done.") solution-list))) -(defun 5x5-solve-suggest (&optional n) +(defun 5x5-solve-suggest (&optional _n) "Suggest to the user where to click. Argument N is ignored." diff --git a/lisp/play/blackbox.el b/lisp/play/blackbox.el index e3854b55a1..61b0878b1c 100644 --- a/lisp/play/blackbox.el +++ b/lisp/play/blackbox.el @@ -1,4 +1,4 @@ -;;; blackbox.el --- blackbox game in Emacs Lisp +;;; blackbox.el --- blackbox game in Emacs Lisp -*- lexical-binding: t -*- ;; Copyright (C) 1985-1987, 1992, 2001-2021 Free Software Foundation, ;; Inc. diff --git a/lisp/play/cookie1.el b/lisp/play/cookie1.el index 5255d81e5b..be35daf4da 100644 --- a/lisp/play/cookie1.el +++ b/lisp/play/cookie1.el @@ -1,4 +1,4 @@ -;;; cookie1.el --- retrieve random phrases from fortune cookie files +;;; cookie1.el --- retrieve random phrases from fortune cookie files -*- lexical-binding: t -*- ;; Copyright (C) 1993, 2001-2021 Free Software Foundation, Inc. @@ -177,11 +177,12 @@ Argument REQUIRE-MATCH non-nil forces a matching cookie." "Randomly permute the elements of VECTOR (all permutations equally likely)." (let ((len (length vector)) j temp) - (dotimes (i len vector) + (dotimes (i len) (setq j (+ i (random (- len i))) temp (aref vector i)) (aset vector i (aref vector j)) - (aset vector j temp)))) + (aset vector j temp)) + vector)) (define-obsolete-function-alias 'shuffle-vector 'cookie-shuffle-vector "24.4") @@ -204,9 +205,10 @@ If called interactively, or if DISPLAY is non-nil, display a list of matches." (cookie-table-symbol (intern phrase-file cookie-cache)) (string-table (symbol-value cookie-table-symbol)) (matches nil)) - (and (dotimes (i (length string-table) matches) - (and (string-match-p regexp (aref string-table i)) - (setq matches (cons (aref string-table i) matches)))) + (dotimes (i (length string-table)) + (and (string-match-p regexp (aref string-table i)) + (setq matches (cons (aref string-table i) matches)))) + (and matches (setq matches (sort matches 'string-lessp))) (and display (if matches diff --git a/lisp/play/doctor.el b/lisp/play/doctor.el index 028f04c325..46fd852b4c 100644 --- a/lisp/play/doctor.el +++ b/lisp/play/doctor.el @@ -1,4 +1,4 @@ -;;; doctor.el --- psychological help for frustrated users +;;; doctor.el --- psychological help for frustrated users -*- lexical-binding: t -*- ;; Copyright (C) 1985, 1987, 1994, 1996, 2000-2021 Free Software ;; Foundation, Inc. diff --git a/lisp/play/gametree.el b/lisp/play/gametree.el index 1c2c24ad75..c6aef027e5 100644 --- a/lisp/play/gametree.el +++ b/lisp/play/gametree.el @@ -1,4 +1,4 @@ -;;; gametree.el --- manage game analysis trees in Emacs +;;; gametree.el --- manage game analysis trees in Emacs -*- lexical-binding: t -*- ;; Copyright (C) 1997, 1999, 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/play/hanoi.el b/lisp/play/hanoi.el index f6e5fcd367..ac28fba10a 100644 --- a/lisp/play/hanoi.el +++ b/lisp/play/hanoi.el @@ -1,4 +1,4 @@ -;;; hanoi.el --- towers of hanoi in Emacs +;;; hanoi.el --- towers of hanoi in Emacs -*- lexical-binding: t -*- ;; Author: Damon Anton Permezel ;; Maintainer: emacs-devel@gnu.org diff --git a/lisp/play/zone.el b/lisp/play/zone.el index 70b6a01a01..19e4e399ff 100644 --- a/lisp/play/zone.el +++ b/lisp/play/zone.el @@ -1,4 +1,4 @@ -;;; zone.el --- idle display hacks +;;; zone.el --- idle display hacks -*- lexical-binding: t -*- ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. @@ -128,14 +128,17 @@ If the element is a function or a list of a function and a number, (let ((pgm (elt zone-programs (random (length zone-programs)))) (ct (and f (frame-parameter f 'cursor-type))) (show-trailing-whitespace nil) - (restore (list '(kill-buffer outbuf)))) + restore) (when ct - (modify-frame-parameters f '((cursor-type . (bar . 0)))) - (setq restore (cons '(modify-frame-parameters - f (list (cons 'cursor-type ct))) - restore))) + (modify-frame-parameters f '((cursor-type . (bar . 0))))) ;; Make `restore' a self-disabling one-shot thunk. - (setq restore `(lambda () ,@restore (setq restore nil))) + (setq restore + (lambda () + (when ct + (modify-frame-parameters + f (list (cons 'cursor-type ct)))) + (kill-buffer outbuf) + (setq restore nil))) (condition-case nil (progn (message "Zoning... (%s)" pgm) @@ -419,7 +422,7 @@ If the element is a function or a list of a function and a number, (defsubst zone-replace-char (count del-count char-as-string new-value) (delete-char (or del-count (- count))) (aset char-as-string 0 new-value) - (dotimes (i count) (insert char-as-string))) + (dotimes (_ count) (insert char-as-string))) (defsubst zone-park/sit-for (pos seconds) (let ((p (point))) @@ -460,7 +463,7 @@ If the element is a function or a list of a function and a number, (let ((nl (- height (count-lines (point-min) (point))))) (when (> nl 0) (setq line (concat line "\n")) - (dotimes (i nl) + (dotimes (_ nl) (insert line)))) (goto-char start) (recenter 0) diff --git a/test/lisp/play/cookie1-resources/cookies b/test/lisp/play/cookie1-resources/cookies new file mode 100644 index 0000000000..7bf569fa7d --- /dev/null +++ b/test/lisp/play/cookie1-resources/cookies @@ -0,0 +1,8 @@ +This fortune intentionally left blank. +% +This fortune intentionally not included. +% +This fortune intentionally says nothing. +% +This fortune is false. +% diff --git a/test/lisp/play/cookie1-tests.el b/test/lisp/play/cookie1-tests.el new file mode 100644 index 0000000000..d63ecb972a --- /dev/null +++ b/test/lisp/play/cookie1-tests.el @@ -0,0 +1,40 @@ +;;; fortune-tests.el --- Tests for fortune.el -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'ert-x) +(require 'cookie1) + +(ert-deftest cookie1-tests-cookie () + (let ((fortune-file (ert-resource-file "cookies"))) + (should (string-match "\\`This fortune" + (cookie fortune-file))))) + +(ert-deftest cookie1-testss-cookie-apropos () + (let ((fortune-file (ert-resource-file "cookies"))) + (should (string-match "\\`This fortune" + (car (cookie-apropos "false" fortune-file)))) + (should (= (length (cookie-apropos "false" fortune-file)) 1)))) + +(provide 'fortune-tests) +;;; fortune-tests.el ends here commit ff16c897eadab9bebc58bd0ca0fb5c8e1c237a15 Author: Protesilaos Stavrou Date: Tue Feb 9 06:49:05 2021 +0200 Refine use of vc-dir faces; apply to all backends * lisp/vc/vc-dir.el (vc-default-dir-printer): Add check for the "ignored" status and make 'vc-dir-status-edited' the default face. Also extend condition for more states that qualify as "warnings". (vc-dir-ignored, vc-dir-status-ignored): Rename face for consistency. * lisp/vc/vc-git.el (vc-git-dir-printer): Use the 'vc-dir-status-edited' as the default for the Git backend. And reference the renamed face. Also stop treating the empty stash differently from other header values. * lisp/vc/vc-bzr.el (vc-bzr-dir-extra-headers): Implement new faces. * lisp/vc/vc-cvs.el (vc-cvs-dir-extra-headers): Same. * lisp/vc/vc-hg.el (vc-hg-dir-extra-headers): Same. * lisp/vc/vc-svn.el (vc-svn-dir-extra-headers): Same. This follows from the discussion in bug#46358. diff --git a/lisp/vc/vc-bzr.el b/lisp/vc/vc-bzr.el index c495afb6ec..d1385ea778 100644 --- a/lisp/vc/vc-bzr.el +++ b/lisp/vc/vc-bzr.el @@ -1076,49 +1076,49 @@ stream. Standard error output is discarded." (when (string-match ".+checkout of branch: \\(.+\\)$" str) (match-string 1 str))))) (concat - (propertize "Parent branch : " 'face 'font-lock-type-face) + (propertize "Parent branch : " 'face 'vc-dir-header) (propertize (if (string-match "parent branch: \\(.+\\)$" str) (match-string 1 str) "None") - 'face 'font-lock-variable-name-face) + 'face 'vc-dir-header-value) "\n" (when light-checkout (concat - (propertize "Light checkout root: " 'face 'font-lock-type-face) - (propertize light-checkout 'face 'font-lock-variable-name-face) + (propertize "Light checkout root: " 'face 'vc-dir-header) + (propertize light-checkout 'face 'vc-dir-header-value) "\n")) (when light-checkout-branch (concat - (propertize "Checkout of branch : " 'face 'font-lock-type-face) - (propertize light-checkout-branch 'face 'font-lock-variable-name-face) + (propertize "Checkout of branch : " 'face 'vc-dir-header) + (propertize light-checkout-branch 'face 'vc-dir-header-value) "\n")) (when pending-merge (concat - (propertize "Warning : " 'face 'font-lock-warning-face + (propertize "Warning : " 'face 'vc-dir-status-warning 'help-echo pending-merge-help-echo) (propertize "Pending merges, commit recommended before any other action" 'help-echo pending-merge-help-echo - 'face 'font-lock-warning-face) + 'face 'vc-dir-status-warning) "\n")) (if shelve (concat - (propertize "Shelves :\n" 'face 'font-lock-type-face + (propertize "Shelves :\n" 'face 'vc-dir-header 'help-echo shelve-help-echo) (mapconcat (lambda (x) (propertize x - 'face 'font-lock-variable-name-face + 'face 'vc-dir-header-value 'mouse-face 'highlight 'help-echo "mouse-3: Show shelve menu\nA: Apply and keep shelf\nP: Apply and remove shelf (pop)\nS: Snapshot to a shelf\nC-k: Delete shelf" 'keymap vc-bzr-shelve-map)) shelve "\n")) (concat - (propertize "Shelves : " 'face 'font-lock-type-face + (propertize "Shelves : " 'face 'vc-dir-header 'help-echo shelve-help-echo) (propertize "No shelved changes" 'help-echo shelve-help-echo - 'face 'font-lock-variable-name-face)))))) + 'face 'vc-dir-header-value)))))) ;; Follows vc-bzr-command, which uses vc-do-command from vc-dispatcher. (declare-function vc-resynch-buffer "vc-dispatcher" diff --git a/lisp/vc/vc-cvs.el b/lisp/vc/vc-cvs.el index a595cc9778..0adb5328bc 100644 --- a/lisp/vc/vc-cvs.el +++ b/lisp/vc/vc-cvs.el @@ -1047,29 +1047,29 @@ Query all files in DIR if files is nil." (file-error nil)))) (concat (cond (repo - (concat (propertize "Repository : " 'face 'font-lock-type-face) - (propertize repo 'face 'font-lock-variable-name-face))) + (concat (propertize "Repository : " 'face 'vc-dir-header) + (propertize repo 'face 'vc-dir-header-value))) (t "")) (cond (module - (concat (propertize "Module : " 'face 'font-lock-type-face) - (propertize module 'face 'font-lock-variable-name-face))) + (concat (propertize "Module : " 'face 'vc-dir-header) + (propertize module 'face 'vc-dir-header-value))) (t "")) (if (file-readable-p "CVS/Tag") (let ((tag (vc-cvs-file-to-string "CVS/Tag"))) (cond ((string-match "\\`T" tag) - (concat (propertize "Tag : " 'face 'font-lock-type-face) + (concat (propertize "Tag : " 'face 'vc-dir-header) (propertize (substring tag 1) - 'face 'font-lock-variable-name-face))) + 'face 'vc-dir-header-value))) ((string-match "\\`D" tag) - (concat (propertize "Date : " 'face 'font-lock-type-face) + (concat (propertize "Date : " 'face 'vc-dir-header) (propertize (substring tag 1) - 'face 'font-lock-variable-name-face))) + 'face 'vc-dir-header-value))) (t "")))) ;; In CVS, branch is a per-file property, not a per-directory property. ;; We can't really do this here without making dangerous assumptions. - ;;(propertize "Branch: " 'face 'font-lock-type-face) + ;;(propertize "Branch: " 'face 'vc-dir-header) ;;(propertize "ADD CODE TO PRINT THE BRANCH NAME\n" ;; 'face 'font-lock-warning-face) ))) diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index 14c81578b7..a416474e16 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -86,7 +86,7 @@ See `run-hooks'." "Face for up-to-date status in VC-dir buffers." :group 'vc) -(defface vc-dir-ignored '((t :inherit shadow)) +(defface vc-dir-status-ignored '((t :inherit shadow)) "Face for ignored or empty values in VC-dir buffers." :group 'vc) @@ -1454,10 +1454,12 @@ These are the commands available for use in the file status buffer: " " (propertize (format "%-20s" state) - 'face (cond ((eq state 'up-to-date) 'vc-dir-status-up-to-date) - ((memq state '(missing conflict)) 'vc-dir-status-warning) - ((eq state 'edited) 'font-lock-constant-face) - (t 'vc-dir-header-value)) + 'face (cond + ((eq state 'up-to-date) 'vc-dir-status-up-to-date) + ((memq state '(missing conflict needs-update unlocked-changes)) + 'vc-dir-status-warning) + ((eq state 'ignored) 'vc-dir-status-ignored) + (t 'vc-dir-status-edited)) 'mouse-face 'highlight 'keymap vc-dir-status-mouse-map) " " diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index e7306386fe..25ae26d746 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -479,7 +479,8 @@ or an empty string if none." (propertize (format "%-12s" state) 'face (cond ((eq state 'up-to-date) 'vc-dir-status-up-to-date) - ((eq state '(missing conflict)) 'vc-dir-status-warning) + ((memq state '(missing conflict)) 'vc-dir-status-warning) + ((eq state 'ignored) 'vc-dir-status-ignored) (t 'vc-dir-status-edited)) 'mouse-face 'highlight 'keymap vc-dir-status-mouse-map) @@ -835,7 +836,7 @@ or an empty string if none." (propertize "Nothing stashed" 'help-echo vc-git-stash-shared-help 'keymap vc-git-stash-shared-map - 'face 'vc-dir-ignored)))))) + 'face 'vc-dir-header-value)))))) (defun vc-git-branches () "Return the existing branches, as a list of strings. diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index 1d163a64ab..adb0fce875 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -1403,8 +1403,8 @@ This runs the command \"hg summary\"." (cons (capitalize (match-string 1)) (match-string 2)) (cons "" (buffer-substring (point) (line-end-position)))))) (concat - (propertize (format "%-11s: " (car entry)) 'face 'font-lock-type-face) - (propertize (cdr entry) 'face 'font-lock-variable-name-face))) + (propertize (format "%-11s: " (car entry)) 'face 'vc-dir-header) + (propertize (cdr entry) 'face 'vc-dir-header-value))) result) (forward-line)) (nreverse result)) diff --git a/lisp/vc/vc-svn.el b/lisp/vc/vc-svn.el index da5471107d..22becc91cd 100644 --- a/lisp/vc/vc-svn.el +++ b/lisp/vc/vc-svn.el @@ -239,8 +239,8 @@ RESULT is a list of conses (FILE . STATE) for directory DIR." (concat (cond (repo (concat - (propertize "Repository : " 'face 'font-lock-type-face) - (propertize repo 'face 'font-lock-variable-name-face))) + (propertize "Repository : " 'face 'vc-dir-header) + (propertize repo 'face 'vc-dir-header-value))) (t ""))))) (defun vc-svn-working-revision (file) commit bff9bd0d3acff0fa0a50e21bdeca024e71fa518b Author: Basil L. Contovounesios Date: Tue Feb 9 19:04:58 2021 +0000 ; Fix warning in last change to semantic/idle.el. diff --git a/lisp/cedet/semantic/idle.el b/lisp/cedet/semantic/idle.el index 29cc8187e1..5af4607abb 100644 --- a/lisp/cedet/semantic/idle.el +++ b/lisp/cedet/semantic/idle.el @@ -898,7 +898,7 @@ Call `semantic-symref-hits-in-region' to identify local references." (when (semantic-tag-p target) (require 'semantic/symref/filter) (semantic-symref-hits-in-region - target (lambda (start end prefix) + target (lambda (start end _prefix) (when (/= start (car Hbounds)) (pulse-momentary-highlight-region start end semantic-idle-symbol-highlight-face)) commit e4328d4b3eea1849b5f081a6d3d2a27f633362d6 Author: Basil L. Contovounesios Date: Tue Feb 9 18:59:24 2021 +0000 Tiny simplification to read-char-by-name * lisp/international/mule-cmds.el (mule--ucs-names-sort-by-code): Sort with car-less-than-car instead of slower lambda. (mule--ucs-names-affixation): Just stick character into a list to avoid trip through format and char-to-string. (read-char-by-name): Quote function symbols as such. diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index 5f66328e94..e4bdf50f52 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -3078,15 +3078,14 @@ on encoding." (setq ucs-names names)))) (defun mule--ucs-names-sort-by-code (names) - (let* ((codes-and-names - (mapcar (lambda (name) (cons (gethash name ucs-names) name)) names)) - (sorted (sort codes-and-names (lambda (a b) (< (car a) (car b)))))) - (mapcar #'cdr sorted))) + (let ((codes-and-names + (mapcar (lambda (name) (cons (gethash name ucs-names) name)) names))) + (mapcar #'cdr (sort codes-and-names #'car-less-than-car)))) (defun mule--ucs-names-affixation (names) (mapcar (lambda (name) (let ((char (gethash name ucs-names))) - (list name (concat (if char (format "%c" char) " ") "\t") ""))) + (list name (concat (if char (list char) " ") "\t") ""))) names)) (defun mule--ucs-names-group (names) @@ -3189,11 +3188,11 @@ as names, not numbers." `(metadata (display-sort-function . ,(when (eq read-char-by-name-sort 'code) - 'mule--ucs-names-sort-by-code)) + #'mule--ucs-names-sort-by-code)) (affixation-function . ,(if read-char-by-name-group - 'mule--ucs-names-group - 'mule--ucs-names-affixation)) + #'mule--ucs-names-group + #'mule--ucs-names-affixation)) (category . unicode-name)) (complete-with-action action (ucs-names) string pred))))) (char commit 817a49748f0cd7f746ce1895d7c31c086289a91e Author: Eli Zaretskii Date: Tue Feb 9 20:57:29 2021 +0200 Fix syntax category of some characters * lisp/international/characters.el (modify-syntax-entry): Fix syntax of numerical subscripts and superscripts. (Bug#46240) diff --git a/lisp/international/characters.el b/lisp/international/characters.el index 9bce419b48..c643f66cbb 100644 --- a/lisp/international/characters.el +++ b/lisp/international/characters.el @@ -265,7 +265,7 @@ with L, LRE, or LRO Unicode bidi character type.") (map-charset-chars #'modify-syntax-entry 'korean-ksc5601 "_" #x2121 #x227E) (map-charset-chars #'modify-syntax-entry 'korean-ksc5601 "_" #x2621 #x277E) (map-charset-chars #'modify-syntax-entry 'korean-ksc5601 "_" #x2830 #x287E) -(map-charset-chars #'modify-syntax-entry 'korean-ksc5601 "_" #x2930 #x297E) +(map-charset-chars #'modify-syntax-entry 'korean-ksc5601 "_" #x2930 #x2975) (map-charset-chars #'modify-category-entry 'korean-ksc5601 ?A #x2330 #x2339) (map-charset-chars #'modify-category-entry 'korean-ksc5601 ?A #x2341 #x235A) (map-charset-chars #'modify-category-entry 'korean-ksc5601 ?A #x2361 #x237A) commit 552d2b9083c2dac210fd8f565b2d46897ae9d4ed Author: Juri Linkov Date: Tue Feb 9 20:29:54 2021 +0200 * lisp/net/dictionary.el: Dictionary improvements (bug#45262) * lisp/net/dictionary.el (dictionary-link-dictionary): New defcustom. (dictionary-mark-reference): Use dictionary-link-dictionary. (dictionary-post-buffer-hook): New defcustom. (dictionary-post-buffer): Run dictionary-post-buffer-hook. (dictionary-mode-map): Bind 'S-SPC' to scroll-down-command. (dictionary-search-default): Use possibly multi-word data at point. diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el index ccc24cbf30..6f086053b6 100644 --- a/lisp/net/dictionary.el +++ b/lisp/net/dictionary.el @@ -160,6 +160,18 @@ by the choice value: :type 'boolean :version "28.1") +(defcustom dictionary-link-dictionary + "*" + "The dictionary which is used in links. +* means to create links that search all dictionaries, +nil means to create links that search only in the same dictionary +where the current word was found." + :group 'dictionary + :type '(choice (const :tag "Link to all dictionaries" "*") + (const :tag "Link only to the same dictionary" nil) + (string :tag "User choice")) + :version "28.1") + (defcustom dictionary-mode-hook nil "Hook run in dictionary mode buffers." @@ -167,6 +179,13 @@ by the choice value: :type 'hook :version "28.1") +(defcustom dictionary-post-buffer-hook + nil + "Hook run at the end of every update of the dictionary buffer." + :group 'dictionary + :type 'hook + :version "28.1") + (defcustom dictionary-use-http-proxy nil "Connects via a HTTP proxy using the CONNECT command when not nil." @@ -323,8 +342,9 @@ is utf-8" (define-key map "l" 'dictionary-previous) (define-key map "n" 'forward-button) (define-key map "p" 'backward-button) - (define-key map " " 'scroll-up) - (define-key map (read-kbd-macro "M-SPC") 'scroll-down) + (define-key map " " 'scroll-up-command) + (define-key map [?\S-\ ] 'scroll-down-command) + (define-key map (read-kbd-macro "M-SPC") 'scroll-down-command) map) "Keymap for the dictionary mode.") @@ -772,7 +792,8 @@ of matching words." (goto-char dictionary-marker) (set-buffer-modified-p nil) - (setq buffer-read-only t)) + (setq buffer-read-only t) + (run-hooks 'dictionary-post-buffer-hook)) (defun dictionary-display-search-result (reply) "Start displaying the result in REPLY." @@ -842,6 +863,8 @@ The word is taken from the buffer, the DICTIONARY is given as argument." (setq word (replace-match " " t t word))) (while (string-match "[*\"]" word) (setq word (replace-match "" t t word))) + (when dictionary-link-dictionary + (setq dictionary dictionary-link-dictionary)) (unless (equal word displayed-word) (make-button start end :type 'dictionary-link @@ -1117,9 +1140,11 @@ If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." ;; - if region is active returns its contents ;; - otherwise return the word near the point (defun dictionary-search-default () - (if (use-region-p) - (buffer-substring-no-properties (region-beginning) (region-end)) - (current-word t))) + (cond + ((use-region-p) + (buffer-substring-no-properties (region-beginning) (region-end))) + ((car (get-char-property (point) 'data))) + (t (current-word t)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; User callable commands commit 80c9871428aca6927b3723d1808497e8cb78e17b Author: Stefan Monnier Date: Tue Feb 9 13:27:08 2021 -0500 Use lexical-binding in a few more scattered files * lisp/registry.el: Use lexical-binding. (registry-reindex): Remove unused var `values`. * lisp/cedet/pulse.el: Use lexical-binding. * lisp/cedet/semantic/idle.el: Use lexical-binding. (semantic-idle-core-handler): Remove unused var `safe`. (ede-auto-add-method): Declare var. (define-semantic-idle-service): Use `declare`. Remove unused var `setup`. (pulse-flag): Declare var. * lisp/net/ldap.el: Use lexical-binding. (ldap-search-internal): Remove unused var `proc`. * lisp/net/mairix.el: Use lexical-binding. Remove redundant `:group` args. (mairix-widget-create-query): Remove unnused var `allwidgets`. diff --git a/lisp/cedet/pulse.el b/lisp/cedet/pulse.el index aef4fc8905..3257feb1fe 100644 --- a/lisp/cedet/pulse.el +++ b/lisp/cedet/pulse.el @@ -1,6 +1,6 @@ -;;; pulse.el --- Pulsing Overlays +;;; pulse.el --- Pulsing Overlays -*- lexical-binding: t; -*- -;;; Copyright (C) 2007-2021 Free Software Foundation, Inc. +;; Copyright (C) 2007-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Version: 1.0 diff --git a/lisp/cedet/semantic/idle.el b/lisp/cedet/semantic/idle.el index 9f1bcfa691..29cc8187e1 100644 --- a/lisp/cedet/semantic/idle.el +++ b/lisp/cedet/semantic/idle.el @@ -1,4 +1,4 @@ -;;; idle.el --- Schedule parsing tasks in idle time +;;; idle.el --- Schedule parsing tasks in idle time -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2006, 2008-2021 Free Software Foundation, Inc. @@ -222,18 +222,18 @@ And also manages services that depend on tag values." (and (buffer-file-name b) b)) (buffer-list))))) - safe ;; This safe is not used, but could be. + ;; safe ;; This safe is not used, but could be. others mode) (when (semantic-idle-scheduler-enabled-p) (save-excursion ;; First, reparse the current buffer. - (setq mode major-mode - safe (semantic-safe "Idle Parse Error: %S" - ;(error "Goofy error 1") - (semantic-idle-scheduler-refresh-tags) - ) - ) + (setq mode major-mode) + ;; (setq safe + (semantic-safe "Idle Parse Error: %S" + ;(error "Goofy error 1") + (semantic-idle-scheduler-refresh-tags)) + ;; Now loop over other buffers with same major mode, trying to ;; update them as well. Stop on keypress. (dolist (b buffers) @@ -430,6 +430,8 @@ datasets." (message "Long Work Idle Timer...%s" exit-type))) ) +(defvar ede-auto-add-method) + (defun semantic-idle-scheduler-work-parse-neighboring-files () "Parse all the files in similar directories to buffers being edited." ;; Let's tell EDE to ignore all the files we're about to load @@ -564,11 +566,12 @@ DOC will be a documentation string describing FORMS. FORMS will be called during idle time after the current buffer's semantic tag information has been updated. This routine creates the following functions and variables:" + (declare (indent 1) (debug (&define name stringp def-body))) (let ((global (intern (concat "global-" (symbol-name name) "-mode"))) (mode (intern (concat (symbol-name name) "-mode"))) (hook (intern (concat (symbol-name name) "-mode-hook"))) (map (intern (concat (symbol-name name) "-mode-map"))) - (setup (intern (concat (symbol-name name) "-mode-setup"))) + ;; (setup (intern (concat (symbol-name name) "-mode-setup"))) (func (intern (concat (symbol-name name) "-idle-function")))) `(progn @@ -618,11 +621,6 @@ turned on in every Semantic-supported buffer.") ,(concat "Perform idle activity for the minor mode `" (symbol-name mode) "'.") ,@forms)))) -(put 'define-semantic-idle-service 'lisp-indent-function 1) -(add-hook 'edebug-setup-hook - (lambda () - (def-edebug-spec define-semantic-idle-service - (&define name stringp def-body)))) ;;; SUMMARY MODE ;; @@ -821,6 +819,8 @@ turned on in every Semantic-supported buffer." (make-obsolete-variable 'semantic-idle-symbol-highlight-face "customize the face `semantic-idle-symbol-highlight' instead" "24.4" 'set) +(defvar pulse-flag) + (defun semantic-idle-symbol-maybe-highlight (tag) "Perhaps add highlighting to the symbol represented by TAG. TAG was found as the symbol under point. If it happens to be @@ -1231,7 +1231,7 @@ shortened at the beginning." ) (defun semantic-idle-breadcrumbs--format-linear - (tag-list &optional max-length) + (tag-list &optional _max-length) "Format TAG-LIST as a linear list, starting with the outermost tag. MAX-LENGTH is not used." (require 'semantic/analyze/fcn) diff --git a/lisp/net/ldap.el b/lisp/net/ldap.el index 0476835ebd..7997bf3c90 100644 --- a/lisp/net/ldap.el +++ b/lisp/net/ldap.el @@ -1,4 +1,4 @@ -;;; ldap.el --- client interface to LDAP for Emacs +;;; ldap.el --- client interface to LDAP for Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2021 Free Software Foundation, Inc. @@ -418,12 +418,12 @@ RFC2798 Section 9.1.1") (encode-coding-string str ldap-coding-system)) (defun ldap-decode-address (str) - (mapconcat 'ldap-decode-string + (mapconcat #'ldap-decode-string (split-string str "\\$") "\n")) (defun ldap-encode-address (str) - (mapconcat 'ldap-encode-string + (mapconcat #'ldap-encode-string (split-string str "\n") "$")) @@ -601,7 +601,7 @@ an alist of attribute/value pairs." (sizelimit (plist-get search-plist 'sizelimit)) (withdn (plist-get search-plist 'withdn)) (numres 0) - arglist dn name value record result proc) + arglist dn name value record result) (if (or (null filter) (equal "" filter)) (error "No search filter")) @@ -671,7 +671,7 @@ an alist of attribute/value pairs." " bind distinguished name (binddn)")) (error "Failed ldapsearch invocation: %s \"%s\"" ldap-ldapsearch-prog - (mapconcat 'identity proc-args "\" \"")))))) + (mapconcat #'identity proc-args "\" \"")))))) (apply #'call-process ldap-ldapsearch-prog ;; Ignore stderr, which can corrupt results nil (list buf nil) nil diff --git a/lisp/net/mairix.el b/lisp/net/mairix.el index 08edb44275..024d118f2d 100644 --- a/lisp/net/mairix.el +++ b/lisp/net/mairix.el @@ -1,4 +1,4 @@ -;;; mairix.el --- Mairix interface for Emacs +;;; mairix.el --- Mairix interface for Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -83,55 +83,46 @@ (defcustom mairix-file-path "~/" "Path where output files produced by Mairix should be stored." - :type 'directory - :group 'mairix) + :type 'directory) (defcustom mairix-search-file "mairixsearch.mbox" "Name of the default file for storing the searches. Note that this will be prefixed by `mairix-file-path'." - :type 'string - :group 'mairix) + :type 'string) (defcustom mairix-command "mairix" "Command for calling mairix. You can add further options here if you want to, but better use `mairix-update-options' instead." - :type 'string - :group 'mairix) + :type 'string) (defcustom mairix-output-buffer "*mairix output*" "Name of the buffer for the output of the mairix binary." - :type 'string - :group 'mairix) + :type 'string) (defcustom mairix-customize-query-buffer "*mairix query*" "Name of the buffer for customizing a search query." - :type 'string - :group 'mairix) + :type 'string) (defcustom mairix-saved-searches-buffer "*mairix searches*" "Name of the buffer for displaying saved searches." - :type 'string - :group 'mairix) + :type 'string) (defcustom mairix-update-options '("-F" "-Q") "Options when calling mairix for updating the database. The default is \"-F\" and \"-Q\" for making updates faster. You should call mairix without these options from time to time (e.g. via cron job)." - :type '(repeat string) - :group 'mairix) + :type '(repeat string)) (defcustom mairix-search-options '("-Q") "Options when calling mairix for searching. The default is \"-Q\" for making searching faster." - :type '(repeat string) - :group 'mairix) + :type '(repeat string)) (defcustom mairix-synchronous-update nil "Defines if Emacs should wait for the mairix database update." - :type 'boolean - :group 'mairix) + :type 'boolean) (defcustom mairix-saved-searches nil "Saved mairix searches. @@ -144,8 +135,7 @@ threads (nil or t). Note that the file will be prefixed by (choice :tag "File" (const :tag "default") file) - (boolean :tag "Threads"))) - :group 'mairix) + (boolean :tag "Threads")))) (defcustom mairix-mail-program 'rmail "Mail program used to display search results. @@ -153,8 +143,7 @@ Currently RMail, Gnus (mbox), and VM are supported. If you use Gnus with maildir, use nnmairix.el instead." :type '(choice (const :tag "RMail" rmail) (const :tag "Gnus mbox" gnus) - (const :tag "VM" vm)) - :group 'mairix) + (const :tag "VM" vm))) (defcustom mairix-display-functions '((rmail mairix-rmail-display) @@ -166,8 +155,7 @@ This is an alist where each entry consists of a symbol from displaying the search results. The function will be called with the mailbox file produced by mairix as the single argument." :type '(repeat (list (symbol :tag "Mail program") - (function))) - :group 'mairix) + (function)))) (defcustom mairix-get-mail-header-functions '((rmail mairix-rmail-fetch-field) @@ -184,15 +172,13 @@ won't work." :type '(repeat (list (symbol :tag "Mail program") (choice :tag "Header function" (const :tag "none") - function))) - :group 'mairix) + function)))) (defcustom mairix-widget-select-window-function (lambda () (select-window (get-largest-window))) "Function for selecting the window for customizing the mairix query. The default chooses the largest window in the current frame." - :type 'function - :group 'mairix) + :type 'function) ;; Other variables @@ -466,18 +452,18 @@ MVALUES may contain values from current article." ;; generate Buttons (widget-create 'push-button :notify - (lambda (&rest ignore) + (lambda (&rest _) (mairix-widget-send-query mairix-widgets)) "Send Query") (widget-insert " ") (widget-create 'push-button :notify - (lambda (&rest ignore) + (lambda (&rest _) (mairix-widget-save-search mairix-widgets)) "Save search") (widget-insert " ") (widget-create 'push-button - :notify (lambda (&rest ignore) + :notify (lambda (&rest _) (kill-buffer mairix-customize-query-buffer)) "Cancel") (use-local-map widget-keymap) @@ -502,7 +488,7 @@ Mairix will be called asynchronously unless (cdr commandsplit) mairix-update-options)) (setq args (append args mairix-update-options))) - (apply 'call-process args)) + (apply #'call-process args)) (progn (message "Updating mairix database...") (setq args (append (list "mairixupdate" (get-buffer-create mairix-output-buffer) @@ -511,8 +497,8 @@ Mairix will be called asynchronously unless (setq args (append args (cdr commandsplit) mairix-update-options)) (setq args (append args mairix-update-options))) (set-process-sentinel - (apply 'start-process args) - 'mairix-sentinel-mairix-update-finished))))) + (apply #'start-process args) + #'mairix-sentinel-mairix-update-finished))))) ;;;; Helper functions @@ -557,7 +543,7 @@ whole threads. Function returns t if messages were found." mairix-file-path)) file)) (setq rval - (apply 'call-process + (apply #'call-process (append args (list "-o" file) query))) (if (zerop rval) (with-current-buffer mairix-output-buffer @@ -582,7 +568,7 @@ whole threads. Function returns t if messages were found." (setq header (replace-match "," t t header))) header)) -(defun mairix-sentinel-mairix-update-finished (proc status) +(defun mairix-sentinel-mairix-update-finished (_proc status) "Sentinel for mairix update process PROC with STATUS." (if (equal status "finished\n") (message "Updating mairix database... done") @@ -642,51 +628,50 @@ See %s for details" mairix-output-buffer))) (when (not (zerop (length flag))) (push (concat "F:" flag) query))) ;; return query string - (mapconcat 'identity query " "))) + (mapconcat #'identity query " "))) (defun mairix-widget-create-query (&optional values) "Create widgets for creating mairix queries. Fill in VALUES if based on an article." - (let (allwidgets) - (when (get-buffer mairix-customize-query-buffer) - (kill-buffer mairix-customize-query-buffer)) - (switch-to-buffer mairix-customize-query-buffer) - (kill-all-local-variables) - (erase-buffer) - (widget-insert - "Specify your query for Mairix using check boxes for activating fields.\n\n") - (widget-insert - (concat "Use ~word to match messages " - (propertize "not" 'face 'italic) - " containing the word)\n" - " substring= to match words containing the substring\n" - " substring=N to match words containing the substring, allowing\n" - " up to N errors(missing/extra/different letters)\n" - " ^substring= to match the substring at the beginning of a word.\n")) - (widget-insert - (format-message - "Whitespace will be converted to `,' (i.e. AND). Use `/' for OR.\n\n")) - (setq mairix-widgets (mairix-widget-build-editable-fields values)) - (when (member 'flags mairix-widget-other) - (widget-insert "\nFlags:\n Seen: ") - (mairix-widget-add "seen" - 'menu-choice - :value "ignore" - '(item "yes") '(item "no") '(item "ignore")) - (widget-insert " Replied: ") - (mairix-widget-add "replied" - 'menu-choice - :value "ignore" - '(item "yes") '(item "no") '(item "ignore")) - (widget-insert " Ticked: ") - (mairix-widget-add "flagged" - 'menu-choice - :value "ignore" - '(item "yes") '(item "no") '(item "ignore"))) - (when (member 'threads mairix-widget-other) - (widget-insert "\n") - (mairix-widget-add "Threads" 'checkbox nil)) - (widget-insert " Show full threads\n\n"))) + (when (get-buffer mairix-customize-query-buffer) + (kill-buffer mairix-customize-query-buffer)) + (switch-to-buffer mairix-customize-query-buffer) + (kill-all-local-variables) + (erase-buffer) + (widget-insert + "Specify your query for Mairix using check boxes for activating fields.\n\n") + (widget-insert + (concat "Use ~word to match messages " + (propertize "not" 'face 'italic) + " containing the word)\n" + " substring= to match words containing the substring\n" + " substring=N to match words containing the substring, allowing\n" + " up to N errors(missing/extra/different letters)\n" + " ^substring= to match the substring at the beginning of a word.\n")) + (widget-insert + (format-message + "Whitespace will be converted to `,' (i.e. AND). Use `/' for OR.\n\n")) + (setq mairix-widgets (mairix-widget-build-editable-fields values)) + (when (member 'flags mairix-widget-other) + (widget-insert "\nFlags:\n Seen: ") + (mairix-widget-add "seen" + 'menu-choice + :value "ignore" + '(item "yes") '(item "no") '(item "ignore")) + (widget-insert " Replied: ") + (mairix-widget-add "replied" + 'menu-choice + :value "ignore" + '(item "yes") '(item "no") '(item "ignore")) + (widget-insert " Ticked: ") + (mairix-widget-add "flagged" + 'menu-choice + :value "ignore" + '(item "yes") '(item "no") '(item "ignore"))) + (when (member 'threads mairix-widget-other) + (widget-insert "\n") + (mairix-widget-add "Threads" 'checkbox nil)) + (widget-insert " Show full threads\n\n")) (defun mairix-widget-build-editable-fields (values) "Build editable field widgets in `nnmairix-widget-fields-list'. @@ -703,7 +688,7 @@ VALUES may contain values for editable fields from current article." (concat "c" field) (widget-create 'checkbox :tag field - :notify (lambda (widget &rest ignore) + :notify (lambda (widget &rest _ignore) (mairix-widget-toggle-activate widget)) nil))) (list @@ -727,7 +712,7 @@ VALUES may contain values for editable fields from current article." "Add a widget NAME with optional ARGS." (push (list name - (apply 'widget-create args)) + (apply #'widget-create args)) mairix-widgets)) (defun mairix-widget-toggle-activate (widget) diff --git a/lisp/registry.el b/lisp/registry.el index a5c30f20ef..258f7fc904 100644 --- a/lisp/registry.el +++ b/lisp/registry.el @@ -1,4 +1,4 @@ -;;; registry.el --- Track and remember data items by various fields +;;; registry.el --- Track and remember data items by various fields -*- lexical-binding: t; -*- ;; Copyright (C) 2011-2021 Free Software Foundation, Inc. @@ -128,7 +128,7 @@ :type hash-table :documentation "The data hash table."))) -(cl-defmethod initialize-instance :before ((this registry-db) slots) +(cl-defmethod initialize-instance :before ((_this registry-db) slots) "Check whether a registry object needs to be upgraded." ;; Hardcoded upgrade routines. Version 0.1 to 0.2 requires the ;; :max-soft slot to disappear, and the :max-hard slot to be renamed @@ -212,7 +212,7 @@ When SET is not nil, set it for VAL (use t for an empty list)." (:regex (string-match (car vals) (mapconcat - 'prin1-to-string + #'prin1-to-string (cdr-safe (assoc key entry)) "\0")))) vals (cdr-safe vals))) @@ -247,7 +247,7 @@ Updates the secondary ('tracked') indices as well. With assert non-nil, errors out if the key does not exist already." (let* ((data (oref db data)) (keys (or keys - (apply 'registry-search db spec))) + (apply #'registry-search db spec))) (tracked (oref db tracked))) (dolist (key keys) @@ -308,19 +308,18 @@ Errors out if the key exists already." (let ((count 0) (expected (* (length (oref db tracked)) (registry-size db)))) (dolist (tr (oref db tracked)) - (let (values) - (maphash - (lambda (key v) - (cl-incf count) - (when (and (< 0 expected) - (= 0 (mod count 1000))) - (message "reindexing: %d of %d (%.2f%%)" - count expected (/ (* 100.0 count) expected))) - (dolist (val (cdr-safe (assq tr v))) - (let ((value-keys (registry-lookup-secondary-value db tr val))) - (push key value-keys) - (registry-lookup-secondary-value db tr val value-keys)))) - (oref db data)))))) + (maphash + (lambda (key v) + (cl-incf count) + (when (and (< 0 expected) + (= 0 (mod count 1000))) + (message "reindexing: %d of %d (%.2f%%)" + count expected (/ (* 100.0 count) expected))) + (dolist (val (cdr-safe (assq tr v))) + (let ((value-keys (registry-lookup-secondary-value db tr val))) + (push key value-keys) + (registry-lookup-secondary-value db tr val value-keys)))) + (oref db data))))) (cl-defmethod registry-prune ((db registry-db) &optional sortfunc) "Prune the registry-db object DB. commit 7020fce353b3e836c03703683e447a9ddf209b6a Author: Juri Linkov Date: Tue Feb 9 20:12:36 2021 +0200 New options read-char-by-name-sort and read-char-by-name-group (bug#46240) * lisp/international/mule-cmds.el (mule--ucs-names-sort-by-code) (mule--ucs-names-group): New functions. (read-char-by-name-sort, read-char-by-name-group): New defcustoms. (read-char-by-name): Use them. diff --git a/etc/NEWS b/etc/NEWS index 5325e87ccf..bd209de18e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -871,6 +871,14 @@ iso-transl RET', it supports the same key sequences as 'C-x 8', so e.g. like 'C-x 8 [' inserts a left single quotation mark, 'C-x \ [' does the same. +--- +*** New user options 'read-char-by-name-sort' and 'read-char-by-name-group'. +'read-char-by-name-sort' defines the sorting order of characters for +completion of 'C-x 8 RET TAB' and can be customized to sort them +by codepoints instead of character names by default. The 't' value of +'read-char-by-name-group' groups the characters for completion of +'C-x 8 RET TAB' by Unicode blocks. + --- *** Improved language transliteration in Malayalam input methods. Added a new Mozhi scheme. The inapplicable ITRANS scheme is now diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index 5dc3de4422..5f66328e94 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -3077,12 +3077,48 @@ on encoding." (puthash "BELL (BEL)" ?\a names) (setq ucs-names names)))) +(defun mule--ucs-names-sort-by-code (names) + (let* ((codes-and-names + (mapcar (lambda (name) (cons (gethash name ucs-names) name)) names)) + (sorted (sort codes-and-names (lambda (a b) (< (car a) (car b)))))) + (mapcar #'cdr sorted))) + (defun mule--ucs-names-affixation (names) (mapcar (lambda (name) (let ((char (gethash name ucs-names))) (list name (concat (if char (format "%c" char) " ") "\t") ""))) names)) +(defun mule--ucs-names-group (names) + (let* ((codes-and-names + (mapcar (lambda (name) (cons (gethash name ucs-names) name)) names)) + (grouped + (seq-group-by + (lambda (code-name) + (let ((script (aref char-script-table (car code-name)))) + (if script (symbol-name script) "ungrouped"))) + codes-and-names)) + names-with-header header) + (dolist (group (sort grouped (lambda (a b) (string< (car a) (car b))))) + (setq header t) + (dolist (code-name (cdr group)) + (push (list + (cdr code-name) + (concat + (if header + (progn + (setq header nil) + (concat "\n" (propertize + (format "* %s\n" (car group)) + 'face 'header-line))) + "") + ;; prefix + (if (car code-name) (format "%c" (car code-name)) " ") "\t") + ;; suffix + "") + names-with-header))) + (nreverse names-with-header))) + (defun char-from-name (string &optional ignore-case) "Return a character as a number from its Unicode name STRING. If optional IGNORE-CASE is non-nil, ignore case in STRING. @@ -3104,6 +3140,23 @@ Return nil if STRING does not name a character." ignore-case)) code))))))) +(defcustom read-char-by-name-sort nil + "How to sort characters for `read-char-by-name' completion. +Defines the sorting order either by character names or their codepoints." + :type '(choice + (const :tag "Sort by character names" nil) + (const :tag "Sort by character codepoints" code)) + :group 'mule + :version "28.1") + +(defcustom read-char-by-name-group nil + "How to group characters for `read-char-by-name' completion. +When t, split characters to sections of Unicode blocks +sorted alphabetically." + :type 'boolean + :group 'mule + :version "28.1") + (defun read-char-by-name (prompt) "Read a character by its Unicode name or hex number string. Display PROMPT and read a string that represents a character by its @@ -3117,6 +3170,9 @@ preceded by an asterisk `*' and use completion, it will show all the characters whose names include that substring, not necessarily at the beginning of the name. +The options `read-char-by-name-sort' and `read-char-by-name-group' +define the sorting order of completion characters and how to group them. + Accept a name like \"CIRCULATION FUNCTION\", a hexadecimal number like \"2A10\", or a number in hash notation (e.g., \"#x2a10\" for hex, \"10r10768\" for decimal, or \"#o25020\" for @@ -3130,8 +3186,14 @@ as names, not numbers." prompt (lambda (string pred action) (if (eq action 'metadata) - '(metadata - (affixation-function . mule--ucs-names-affixation) + `(metadata + (display-sort-function + . ,(when (eq read-char-by-name-sort 'code) + 'mule--ucs-names-sort-by-code)) + (affixation-function + . ,(if read-char-by-name-group + 'mule--ucs-names-group + 'mule--ucs-names-affixation)) (category . unicode-name)) (complete-with-action action (ucs-names) string pred))))) (char commit 5a77517e7dbe823554e9670564758c69cbd1796a Author: Stefan Monnier Date: Tue Feb 9 12:52:04 2021 -0500 * lisp/cedet/{semantic/scope.el,ede/project-am.el}: Use lexical-scoping * lisp/cedet/ede/project-am.el: Remove redundant `:group` args. (recentf-exclude): Declare variable. (project-am--with-makefile-current): New function extracted from `project-am-with-makefile-current`. Use `with-current-buffer` and `unwind-protect`. (project-am-with-makefile-current): Use `declare` and `project-am--with-makefile-current`. (project-am-with-config-current): Use `declare` and `with-temp-buffer`. (project-am-extract-shell-variable): Turn it into a `defun`; the use of `defmacro` appears to have been a plain mistake. diff --git a/lisp/cedet/ede/project-am.el b/lisp/cedet/ede/project-am.el index 061d1b540b..d676c5749c 100644 --- a/lisp/cedet/ede/project-am.el +++ b/lisp/cedet/ede/project-am.el @@ -1,4 +1,4 @@ -;;; project-am.el --- A project management scheme based on automake files. +;;; project-am.el --- A project management scheme based on automake files. -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2000, 2003, 2005, 2007-2021 Free Software ;; Foundation, Inc. @@ -54,17 +54,14 @@ (defcustom project-am-compile-project-command nil "Default command used to compile a project." - :group 'project-am :type '(choice (const nil) string)) (defcustom project-am-compile-target-command (concat ede-make-command " -k %s") "Default command used to compile a project." - :group 'project-am :type 'string) (defcustom project-am-debug-target-function 'gdb "Default Emacs command used to debug a target." - :group 'project-am :type 'function) ; make this be a list some day (defconst project-am-type-alist @@ -240,8 +237,8 @@ OT is the object target. DIR is the directory to start in." (if (= (point-min) (point)) (re-search-forward (ede-target-name obj)))) -(cl-defmethod project-new-target ((proj project-am-makefile) - &optional name type) +(cl-defmethod project-new-target ((_proj project-am-makefile) + &optional name type) "Create a new target named NAME. Argument TYPE is the type of target to insert. This is a string matching something in `project-am-type-alist' or type class symbol. @@ -300,7 +297,7 @@ buffer being in order to provide a smart default target type." ;; This should be handled at the EDE level, calling a method of the ;; top most project. ;; -(cl-defmethod project-compile-project ((obj project-am-target) &optional command) +(cl-defmethod project-compile-project ((_obj project-am-target) &optional command) "Compile the entire current project. Argument COMMAND is the command to use when compiling." (require 'compile) @@ -324,7 +321,7 @@ Argument COMMAND is the command to use when compiling." (let* ((default-directory (project-am-find-topmost-level default-directory))) (compile command))) -(cl-defmethod project-compile-project ((obj project-am-makefile) +(cl-defmethod project-compile-project ((_obj project-am-makefile) &optional command) "Compile the entire current project. Argument COMMAND is the command to use when compiling." @@ -349,7 +346,7 @@ Argument COMMAND is the command to use when compiling." (let* ((default-directory (project-am-find-topmost-level default-directory))) (compile command))) -(cl-defmethod project-compile-target ((obj project-am-target) &optional command) +(cl-defmethod project-compile-target ((_obj project-am-target) &optional command) "Compile the current target. Argument COMMAND is the command to use for compiling the target." (require 'compile) @@ -423,7 +420,7 @@ Argument COMMAND is the command to use for compiling the target." ;;; Project loading and saving ;; -(defun project-am-load (directory &optional rootproj) +(defun project-am-load (directory &optional _rootproj) "Read an automakefile DIRECTORY into our data structure. If a given set of projects has already been loaded, then do nothing but return the project for the directory given. @@ -442,34 +439,28 @@ Optional ROOTPROJ is the root EDE project." (file-name-directory (directory-file-name newdir)))) (expand-file-name dir))) +(defvar recentf-exclude) + (defmacro project-am-with-makefile-current (dir &rest forms) "Set the Makefile.am in DIR to be the current buffer. -Run FORMS while the makefile is current. -Kill the makefile if it was not loaded before the load." - `(let* ((fn (expand-file-name "Makefile.am" ,dir)) - (fb nil) - (kb (get-file-buffer fn))) - (if (not (file-exists-p fn)) - nil - (save-excursion - (if kb (setq fb kb) - ;; We need to find-file this thing, but don't use - ;; any semantic features. - (let ((semantic-init-hook nil) - (recentf-exclude '( (lambda (f) t) )) - ) - (setq fb (find-file-noselect fn))) - ) - (set-buffer fb) - (prog1 ,@forms - (if (not kb) (kill-buffer (current-buffer)))))))) -(put 'project-am-with-makefile-current 'lisp-indent-function 1) - -(add-hook 'edebug-setup-hook - (lambda () - (def-edebug-spec project-am-with-makefile-current - (form def-body)))) - +Run FORMS while the makefile is current." + (declare (indent 1) (debug (form def-body))) + `(project-am--with-makefile-current ,dir (lambda () ,@forms))) + +(defun project-am--with-makefile-current (dir fun) + (let* ((fn (expand-file-name "Makefile.am" dir)) + (kb (get-file-buffer fn))) + (if (not (file-exists-p fn)) + nil + (with-current-buffer + (or kb + ;; We need to find-file this thing, but don't use + ;; any semantic features. + (let ((semantic-init-hook nil) + (recentf-exclude `(,(lambda (_f) t)))) + (find-file-noselect fn))) + (unwind-protect (funcall fun) + (if (not kb) (kill-buffer (current-buffer)))))))) (defun project-am-load-makefile (path &optional suggestedname) "Convert PATH into a project Makefile, and return its project object. @@ -480,6 +471,7 @@ This is used when subprojects are made in named subdirectories." (if (and ede-object (project-am-makefile-p ede-object)) ede-object (let* ((pi (project-am-package-info path)) + (fn buffer-file-name) (sfn (when suggestedname (project-am-last-dir suggestedname))) (pn (or sfn (nth 0 pi) (project-am-last-dir fn))) @@ -734,19 +726,19 @@ Strip out duplicates, and recurse on variables." "Return the default macro to `edit' for this object type." (concat (subst-char-in-string ?- ?_ (oref this name)) "_SOURCES")) -(cl-defmethod project-am-macro ((this project-am-header-noinst)) +(cl-defmethod project-am-macro ((_this project-am-header-noinst)) "Return the default macro to `edit' for this object." "noinst_HEADERS") -(cl-defmethod project-am-macro ((this project-am-header-inst)) +(cl-defmethod project-am-macro ((_this project-am-header-inst)) "Return the default macro to `edit' for this object." "include_HEADERS") -(cl-defmethod project-am-macro ((this project-am-header-pkg)) +(cl-defmethod project-am-macro ((_this project-am-header-pkg)) "Return the default macro to `edit' for this object." "pkginclude_HEADERS") -(cl-defmethod project-am-macro ((this project-am-header-chk)) +(cl-defmethod project-am-macro ((_this project-am-header-chk)) "Return the default macro to `edit' for this object." "check_HEADERS") @@ -758,7 +750,7 @@ Strip out duplicates, and recurse on variables." "Return the default macro to `edit' for this object type." (oref this name)) -(cl-defmethod project-am-macro ((this project-am-lisp)) +(cl-defmethod project-am-macro ((_this project-am-lisp)) "Return the default macro to `edit' for this object." "lisp_LISP") @@ -785,13 +777,11 @@ nil means that this buffer belongs to no-one." "Return t if object THIS lays claim to the file in BUFFER." (let ((efn (expand-file-name (buffer-file-name buffer)))) (or (string= (oref this file) efn) - (string-match "/configure\\.ac$" efn) - (string-match "/configure\\.in$" efn) - (string-match "/configure$" efn) + (string-match "/configure\\(?:\\.ac\\|\\.in\\)?\\'" efn) ;; Search output files. (let ((ans nil)) (dolist (f (oref this configureoutputfiles)) - (when (string-match (concat (regexp-quote f) "$") efn) + (when (string-match (concat (regexp-quote f) "\\'") efn) (setq ans t))) ans) ))) @@ -822,7 +812,7 @@ nil means that this buffer belongs to no-one." "Return the sub project in AMPF specified by SUBDIR." (object-assoc (expand-file-name subdir) 'file (oref ampf subproj))) -(cl-defmethod project-compile-target-command ((this project-am-target)) +(cl-defmethod project-compile-target-command ((_this project-am-target)) "Default target to use when compiling a given target." ;; This is a pretty good default for most. "") @@ -861,7 +851,7 @@ Argument FILE is the file to extract the end directory name from." (t 'project-am-program))) -(cl-defmethod ede-buffer-header-file((this project-am-objectcode) buffer) +(cl-defmethod ede-buffer-header-file((this project-am-objectcode) _buffer) "There are no default header files." (or (cl-call-next-method) (let ((s (oref this source)) @@ -910,22 +900,13 @@ files in the project." "Set the Configure FILE in the top most directory above DIR as current. Run FORMS in the configure file. Kill the Configure buffer if it was not already in a buffer." - `(save-excursion - (let ((fb (generate-new-buffer ,file))) - (set-buffer fb) - (erase-buffer) - (insert-file-contents ,file) - (prog1 ,@forms - (kill-buffer fb))))) - -(put 'project-am-with-config-current 'lisp-indent-function 1) - -(add-hook 'edebug-setup-hook - (lambda () - (def-edebug-spec project-am-with-config-current - (form def-body)))) - -(defmacro project-am-extract-shell-variable (var) + (declare (indent 1) (debug t)) + `(with-temp-buffer + (erase-buffer) + (insert-file-contents ,file) + ,@forms)) + +(defun project-am-extract-shell-variable (var) "Extract the value of the shell variable VAR from a shell script." (save-excursion (goto-char (point-min)) @@ -997,12 +978,12 @@ Calculates the info with `project-am-extract-package-info'." (project-am-extract-package-info dir))) ;; for simple per project include path extension -(cl-defmethod ede-system-include-path ((this project-am-makefile)) +(cl-defmethod ede-system-include-path ((_this project-am-makefile)) "Return `project-am-localvars-include-path', usually local variable per file or in .dir-locals.el or similar." (bound-and-true-p project-am-localvars-include-path)) -(cl-defmethod ede-system-include-path ((this project-am-target)) +(cl-defmethod ede-system-include-path ((_this project-am-target)) "Return `project-am-localvars-include-path', usually local variable per file or in .dir-locals.el or similar." (bound-and-true-p project-am-localvars-include-path)) diff --git a/lisp/cedet/semantic/scope.el b/lisp/cedet/semantic/scope.el index 31576d29bc..6bd04b2e34 100644 --- a/lisp/cedet/semantic/scope.el +++ b/lisp/cedet/semantic/scope.el @@ -1,4 +1,4 @@ -;;; semantic/scope.el --- Analyzer Scope Calculations +;;; semantic/scope.el --- Analyzer Scope Calculations -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. @@ -115,7 +115,7 @@ Saves scoping information between runs of the analyzer.") ) (cl-defmethod semanticdb-synchronize ((cache semantic-scope-cache) - new-tags) + _new-tags) "Synchronize a CACHE with some NEW-TAGS." (semantic-reset cache)) @@ -262,7 +262,7 @@ are from nesting data types." (semantic-go-to-tag pparent) (setq stack (semantic-find-tag-by-overlay (point))) ;; Step one, find the merged version of stack in the typecache. - (let* ((stacknames (reverse (mapcar 'semantic-tag-name stack))) + (let* ((stacknames (reverse (mapcar #'semantic-tag-name stack))) (tc nil) ) ;; @todo - can we use the typecache ability to @@ -317,7 +317,7 @@ are from nesting data types." ;; returnlist is empty. (while snlist (setq fullsearchname - (append (mapcar 'semantic-tag-name returnlist) + (append (mapcar #'semantic-tag-name returnlist) (list (car snlist)))) ;; Next one (setq ptag (semanticdb-typecache-find fullsearchname)) @@ -325,8 +325,8 @@ are from nesting data types." (when (or (not ptag) (not (semantic-tag-of-class-p ptag 'type))) (let ((rawscope - (apply 'append - (mapcar 'semantic-tag-type-members + (apply #'append + (mapcar #'semantic-tag-type-members (cons (car returnlist) scopetypes) ))) ) @@ -541,7 +541,7 @@ tag is not something you can complete from within TYPE." (setq leftover (cons S leftover))))) (nreverse leftover))) -(defun semantic-analyze-scoped-type-parts (type &optional scope noinherit protection) +(defun semantic-analyze-scoped-type-parts (type &optional scope noinherit _protection) "Return all parts of TYPE, a tag representing a TYPE declaration. SCOPE is the scope object. NOINHERIT turns off searching of inherited tags. commit 6fd8548b1620aadd2c9e4efddd899b87d023913b Author: Stefan Monnier Date: Tue Feb 9 12:10:07 2021 -0500 * lisp/emacs-lisp/byte-opt.el (byte-optimize--pcase): New macro (byte-optimize-form-code-walker): Use it. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index e67077639c..4fa2c75a88 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -348,6 +348,40 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") (symbolp (cadr expr))) (keywordp expr))) +(defmacro byte-optimize--pcase (exp &rest cases) + ;; When we do + ;; + ;; (pcase EXP + ;; (`(if ,exp ,then ,else) (DO-TEST)) + ;; (`(plus ,e2 ,e2) (DO-ADD)) + ;; (`(times ,e2 ,e2) (DO-MULT)) + ;; ...) + ;; + ;; we usually don't want to fall back to the default case if + ;; the value of EXP is of a form like `(if E1 E2)' or `(plus E1)' + ;; or `(times E1 E2 E3)', instead we either want to signal an error + ;; that EXP has an unexpected shape, or we want to carry on as if + ;; it had the right shape (ignore the extra data and pretend the missing + ;; data is nil) because it should simply never happen. + ;; + ;; The macro below implements the second option by rewriting patterns + ;; like `(if ,exp ,then ,else)' + ;; to `(if . (or `(,exp ,then ,else) pcase--dontcare))'. + ;; + ;; The resulting macroexpansion is also significantly cleaner/smaller/faster. + (declare (indent 1) (debug (form &rest (pcase-PAT body)))) + `(pcase ,exp + . ,(mapcar (lambda (case) + `(,(pcase (car case) + ((and `(,'\` (,_ . (,'\, ,_))) pat) pat) + (`(,'\` (,head . ,tail)) + (list '\` + (cons head + (list '\, `(or ,(list '\` tail) pcase--dontcare))))) + (pat pat)) + . ,(cdr case))) + cases))) + (defun byte-optimize-form-code-walker (form for-effect) ;; ;; For normal function calls, We can just mapcar the optimizer the cdr. But @@ -360,7 +394,7 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") ;; have no place in an optimizer: the corresponding tests should be ;; performed in `macroexpand-all', or in `cconv', or in `bytecomp'. (let ((fn (car-safe form))) - (pcase form + (byte-optimize--pcase form ((pred (not consp)) (cond ((and for-effect @@ -370,7 +404,7 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") nil) ((symbolp form) (let ((lexvar (assq form byte-optimize--lexvars))) - (if (cddr lexvar) ; Value available? + (if (cddr lexvar) ; Value available? (if (assq form byte-optimize--vars-outside-loop) ;; Cannot substitute; mark for retention to avoid the ;; variable being eliminated. @@ -390,27 +424,27 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") (not for-effect) form)) (`(,(or 'let 'let*) . ,rest) - (cons fn (byte-optimize-let-form fn rest for-effect))) + (cons fn (byte-optimize-let-form fn rest for-effect))) (`(cond . ,clauses) ;; The condition in the first clause is always executed, but ;; right now we treat all of them as conditional for simplicity. (let ((byte-optimize--vars-outside-condition byte-optimize--lexvars)) (cons fn (mapcar (lambda (clause) - (if (consp clause) - (cons - (byte-optimize-form (car clause) nil) - (byte-optimize-body (cdr clause) for-effect)) - (byte-compile-warn "malformed cond form: `%s'" - (prin1-to-string clause)) - clause)) - clauses)))) + (if (consp clause) + (cons + (byte-optimize-form (car clause) nil) + (byte-optimize-body (cdr clause) for-effect)) + (byte-compile-warn "malformed cond form: `%s'" + (prin1-to-string clause)) + clause)) + clauses)))) (`(progn . ,exps) ;; As an extra added bonus, this simplifies (progn ) --> . (if (cdr exps) (macroexp-progn (byte-optimize-body exps for-effect)) (byte-optimize-form (car exps) for-effect))) - (`(prog1 . ,(or `(,exp . ,exps) pcase--dontcare)) + (`(prog1 ,exp . ,exps) (if exps `(prog1 ,(byte-optimize-form exp for-effect) . ,(byte-optimize-body exps t)) @@ -435,8 +469,6 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") (then-opt (byte-optimize-form then for-effect)) (else-opt (byte-optimize-body else for-effect))) `(if ,test-opt ,then-opt . ,else-opt))) - (`(if . ,_) - (byte-compile-warn "too few arguments for `if'")) (`(,(or 'and 'or) . ,exps) ; Remember, and/or are control structures. ;; FIXME: We have to traverse the expressions in left-to-right @@ -474,8 +506,6 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") (body (byte-optimize-body exps t))) `(while ,condition . ,body))) - (`(while . ,_) - (byte-compile-warn "too few arguments for `while'")) (`(interactive . ,_) (byte-compile-warn "misplaced interactive spec: `%s'" @@ -487,9 +517,9 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") ;; all the subexpressions and compiling them separately. form) - (`(condition-case . ,(or `(,var ,exp . ,clauses) pcase--dontcare)) + (`(condition-case ,var ,exp . ,clauses) (let ((byte-optimize--vars-outside-condition byte-optimize--lexvars)) - `(condition-case ,var ;Not evaluated. + `(condition-case ,var ;Not evaluated. ,(byte-optimize-form exp for-effect) ,@(mapcar (lambda (clause) `(,(car clause) @@ -513,7 +543,7 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") `(unwind-protect ,bodyform . ,(byte-optimize-body exps t)))))) - (`(catch . ,(or `(,tag . ,exps) pcase--dontcare)) + (`(catch ,tag . ,exps) (let ((byte-optimize--vars-outside-condition byte-optimize--lexvars)) `(catch ,(byte-optimize-form tag nil) . ,(byte-optimize-body exps for-effect)))) @@ -566,7 +596,7 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") (setcdr (cdr lexvar) (and (byte-optimize--substitutable-p value) (list value)))) - (setcar (cdr lexvar) t)) ; Mark variable to be kept. + (setcar (cdr lexvar) t)) ; Mark variable to be kept. (push var var-expr-list) (push value var-expr-list)) (setq args (cddr args))) commit 04fb1664a8ee3c20ed8a231ce5c9bb05a145f8e0 Author: Stefan Monnier Date: Tue Feb 9 12:02:25 2021 -0500 * lisp/emacs-lisp/macroexp.el: Break cycle with bytecomp/byte-opt The recent change in macroexp triggered a cyclic dependency error during eager macroexpansion when neither `bytecomp` nor `byte-opt` had been byte-compiled yet. This fixes it by moving the offending function to macroexp.el. * lisp/emacs-lisp/macroexp.el (macroexp--unfold-lambda): Move from byte-opt.el and rename. (macroexp--expand-all): Use it. * lisp/emacs-lisp/byte-opt.el (byte-compile-unfold-lambda): Move to macroexp.el. (byte-compile-inline-expand, byte-optimize-form-code-walker): * lisp/emacs-lisp/bytecomp.el (byte-compile-form): Use `macroexp--unfold-lambda` instead. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index abbe2a2e63..e67077639c 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -289,7 +289,7 @@ (byte-compile-preprocess (byte-compile--reify-function fn)))))) (if (eq (car-safe newfn) 'function) - (byte-compile-unfold-lambda `(,(cadr newfn) ,@(cdr form))) + (macroexp--unfold-lambda `(,(cadr newfn) ,@(cdr form))) ;; This can happen because of macroexp-warn-and-return &co. (byte-compile-warn "Inlining closure %S failed" name) @@ -297,74 +297,6 @@ (_ ;; Give up on inlining. form)))) - -;; ((lambda ...) ...) -(defun byte-compile-unfold-lambda (form &optional name) - ;; In lexical-binding mode, let and functions don't bind vars in the same way - ;; (let obey special-variable-p, but functions don't). But luckily, this - ;; doesn't matter here, because function's behavior is underspecified so it - ;; can safely be turned into a `let', even though the reverse is not true. - (or name (setq name "anonymous lambda")) - (let* ((lambda (car form)) - (values (cdr form)) - (arglist (nth 1 lambda)) - (body (cdr (cdr lambda))) - optionalp restp - bindings) - (if (and (stringp (car body)) (cdr body)) - (setq body (cdr body))) - (if (and (consp (car body)) (eq 'interactive (car (car body)))) - (setq body (cdr body))) - ;; FIXME: The checks below do not belong in an optimization phase. - (while arglist - (cond ((eq (car arglist) '&optional) - ;; ok, I'll let this slide because funcall_lambda() does... - ;; (if optionalp (error "multiple &optional keywords in %s" name)) - (if restp (error "&optional found after &rest in %s" name)) - (if (null (cdr arglist)) - (error "nothing after &optional in %s" name)) - (setq optionalp t)) - ((eq (car arglist) '&rest) - ;; ...but it is by no stretch of the imagination a reasonable - ;; thing that funcall_lambda() allows (&rest x y) and - ;; (&rest x &optional y) in arglists. - (if (null (cdr arglist)) - (error "nothing after &rest in %s" name)) - (if (cdr (cdr arglist)) - (error "multiple vars after &rest in %s" name)) - (setq restp t)) - (restp - (setq bindings (cons (list (car arglist) - (and values (cons 'list values))) - bindings) - values nil)) - ((and (not optionalp) (null values)) - (byte-compile-warn "attempt to open-code `%s' with too few arguments" name) - (setq arglist nil values 'too-few)) - (t - (setq bindings (cons (list (car arglist) (car values)) - bindings) - values (cdr values)))) - (setq arglist (cdr arglist))) - (if values - (progn - (or (eq values 'too-few) - (byte-compile-warn - "attempt to open-code `%s' with too many arguments" name)) - form) - - ;; The following leads to infinite recursion when loading a - ;; file containing `(defsubst f () (f))', and then trying to - ;; byte-compile that file. - ;(setq body (mapcar 'byte-optimize-form body))) - - (let ((newform - (if bindings - (cons 'let (cons (nreverse bindings) body)) - (cons 'progn body)))) - (byte-compile-log " %s\t==>\t%s" form newform) - newform)))) - ;;; implementing source-level optimizers @@ -604,7 +536,7 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") form) (`((lambda . ,_) . ,_) - (let ((newform (byte-compile-unfold-lambda form))) + (let ((newform (macroexp--unfold-lambda form))) (if (eq newform form) ;; Some error occurred, avoid infinite recursion. form diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 9429d6a0d5..89068a14f0 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -195,7 +195,6 @@ otherwise adds \".elc\"." (autoload 'byte-optimize-form "byte-opt") ;; This is the entry point to the lapcode optimizer pass2. (autoload 'byte-optimize-lapcode "byte-opt") -(autoload 'byte-compile-unfold-lambda "byte-opt") ;; This is the entry point to the decompiler, which is used by the ;; disassembler. The disassembler just requires 'byte-compile, but @@ -3277,7 +3276,7 @@ for symbols generated by the byte compiler itself." ((and (eq (car-safe (car form)) 'lambda) ;; if the form comes out the same way it went in, that's ;; because it was malformed, and we couldn't unfold it. - (not (eq form (setq form (byte-compile-unfold-lambda form))))) + (not (eq form (setq form (macroexp--unfold-lambda form))))) (byte-compile-form form byte-compile--for-effect) (setq byte-compile--for-effect nil)) ((byte-compile-normal-call form))) diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index e842222b7c..042061c44f 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -200,6 +200,69 @@ and also to avoid outputting the warning during normal execution." new-form)) new-form))) +(defun macroexp--unfold-lambda (form &optional name) + ;; In lexical-binding mode, let and functions don't bind vars in the same way + ;; (let obey special-variable-p, but functions don't). But luckily, this + ;; doesn't matter here, because function's behavior is underspecified so it + ;; can safely be turned into a `let', even though the reverse is not true. + (or name (setq name "anonymous lambda")) + (let* ((lambda (car form)) + (values (cdr form)) + (arglist (nth 1 lambda)) + (body (cdr (cdr lambda))) + optionalp restp + bindings) + (if (and (stringp (car body)) (cdr body)) + (setq body (cdr body))) + (if (and (consp (car body)) (eq 'interactive (car (car body)))) + (setq body (cdr body))) + ;; FIXME: The checks below do not belong in an optimization phase. + (while arglist + (cond ((eq (car arglist) '&optional) + ;; ok, I'll let this slide because funcall_lambda() does... + ;; (if optionalp (error "multiple &optional keywords in %s" name)) + (if restp (error "&optional found after &rest in %s" name)) + (if (null (cdr arglist)) + (error "nothing after &optional in %s" name)) + (setq optionalp t)) + ((eq (car arglist) '&rest) + ;; ...but it is by no stretch of the imagination a reasonable + ;; thing that funcall_lambda() allows (&rest x y) and + ;; (&rest x &optional y) in arglists. + (if (null (cdr arglist)) + (error "nothing after &rest in %s" name)) + (if (cdr (cdr arglist)) + (error "multiple vars after &rest in %s" name)) + (setq restp t)) + (restp + (setq bindings (cons (list (car arglist) + (and values (cons 'list values))) + bindings) + values nil)) + ((and (not optionalp) (null values)) + (setq arglist nil values 'too-few)) + (t + (setq bindings (cons (list (car arglist) (car values)) + bindings) + values (cdr values)))) + (setq arglist (cdr arglist))) + (if values + (macroexp--warn-and-return + (format (if (eq values 'too-few) + "attempt to open-code `%s' with too few arguments" + "attempt to open-code `%s' with too many arguments") + name) + form) + + ;; The following leads to infinite recursion when loading a + ;; file containing `(defsubst f () (f))', and then trying to + ;; byte-compile that file. + ;;(setq body (mapcar 'byte-optimize-form body))) + + (if bindings + `(let ,(nreverse bindings) . ,body) + (macroexp-progn body))))) + (defun macroexp--expand-all (form) "Expand all macros in FORM. This is an internal version of `macroexpand-all'. @@ -245,12 +308,8 @@ Assumes the caller has bound `macroexpand-all-environment'." ;; i.e. rewrite it to (let () ). We'd do it in the optimizer ;; anyway, but doing it here (i.e. earlier) can sometimes avoid the ;; creation of a closure, thus resulting in much better code. - (let ((newform (if (not (fboundp 'byte-compile-unfold-lambda)) - 'macroexp--not-unfolded - ;; Don't unfold if byte-opt is not yet loaded. - (byte-compile-unfold-lambda form)))) - (if (or (eq newform 'macroexp--not-unfolded) - (eq newform form)) + (let ((newform (macroexp--unfold-lambda form))) + (if (eq newform form) ;; Unfolding failed for some reason, avoid infinite recursion. (macroexp--cons (macroexp--all-forms fun 2) (macroexp--all-forms args) commit 3c53d28ae19232ae817565453342edf8124c053a Author: Stefan Kangas Date: Tue Feb 9 16:57:27 2021 +0100 Remove some dead, commented out code from lisp-mode.el * lisp/emacs-lisp/lisp-mode.el (lisp-data-mode-syntax-table): Remove code commented out since 2005. diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index f5ce107185..54089c4bc6 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -62,9 +62,6 @@ (modify-syntax-entry ?\t " " table) (modify-syntax-entry ?\f " " table) (modify-syntax-entry ?\n "> " table) - ;; This is probably obsolete since nowadays such features use overlays. - ;; ;; Give CR the same syntax as newline, for selective-display. - ;; (modify-syntax-entry ?\^m "> " table) (modify-syntax-entry ?\; "< " table) (modify-syntax-entry ?` "' " table) (modify-syntax-entry ?' "' " table) commit 0161c9df6edc02db6bd8871b00df522dd0699157 Author: Stefan Kangas Date: Tue Feb 9 15:58:37 2021 +0100 Load all generic-x.el modes unconditionally * lisp/generic-x.el: Load all modes unconditionally. (generic-default-modes, generic-mswindows-modes) (generic-unix-modes, generic-other-modes) (generic-extras-enable-list): Make obsolete. Ref: https://lists.gnu.org/r/emacs-devel/2021-01/msg01403.html diff --git a/etc/NEWS b/etc/NEWS index 7f02f6106d..5325e87ccf 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2113,6 +2113,11 @@ parameter. 'previous-system-time-locale' have been removed, as they were created by mistake and were not useful to Lisp code. +--- +** Loading 'generic-x' unconditionally loads all modes. +The user option `generic-extras-enable-list' is now obsolete, and +setting it has no effect. + --- ** The 'load-dangerous-libraries' variable is now obsolete. It was used to allow loading Lisp libraries compiled by XEmacs, a diff --git a/lisp/generic-x.el b/lisp/generic-x.el index 4c6e118900..0f4e1ae4a6 100644 --- a/lisp/generic-x.el +++ b/lisp/generic-x.el @@ -23,7 +23,7 @@ ;; along with GNU Emacs. If not, see . ;;; Commentary: -;; + ;; This file contains a collection of generic modes. ;; ;; INSTALLATION: @@ -32,17 +32,6 @@ ;; ;; (require 'generic-x) ;; -;; You can decide which modes to load by setting the variable -;; `generic-extras-enable-list'. Its default value is platform- -;; specific. The recommended way to set this variable is through -;; customize: -;; -;; M-x customize-option RET generic-extras-enable-list RET -;; -;; This lets you select generic modes from the list of available -;; modes. If you manually set `generic-extras-enable-list' in your -;; .emacs, do it BEFORE loading generic-x with (require 'generic-x). -;; ;; You can also send in new modes; if the file types are reasonably ;; common, we would like to install them. ;; @@ -184,88 +173,7 @@ This hook will be installed if the variable ;; Other Generic modes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; If you add a generic mode to this file, put it in one of these four -;; lists as well. - -(defconst generic-default-modes - '(apache-conf-generic-mode - apache-log-generic-mode - hosts-generic-mode - java-manifest-generic-mode - java-properties-generic-mode - javascript-generic-mode - show-tabs-generic-mode - vrml-generic-mode) - "List of generic modes that are defined by default.") - -(defconst generic-mswindows-modes - '(bat-generic-mode - inf-generic-mode - ini-generic-mode - rc-generic-mode - reg-generic-mode - rul-generic-mode) - "List of generic modes that are defined by default on MS-Windows.") - -(defconst generic-unix-modes - '(alias-generic-mode - ansible-inventory-generic-mode - etc-fstab-generic-mode - etc-modules-conf-generic-mode - etc-passwd-generic-mode - etc-services-generic-mode - etc-sudoers-generic-mode - fvwm-generic-mode - inetd-conf-generic-mode - mailagent-rules-generic-mode - mailrc-generic-mode - named-boot-generic-mode - named-database-generic-mode - prototype-generic-mode - resolve-conf-generic-mode - samba-generic-mode - x-resource-generic-mode - xmodmap-generic-mode) - "List of generic modes that are defined by default on Unix.") - -(defconst generic-other-modes - '(astap-generic-mode - ibis-generic-mode - pkginfo-generic-mode - spice-generic-mode) - "List of generic modes that are not defined by default.") - -(defcustom generic-extras-enable-list - (append generic-default-modes - (if (memq system-type '(windows-nt ms-dos)) - generic-mswindows-modes - generic-unix-modes) - nil) - "List of generic modes to define. -Each entry in the list should be a symbol. If you set this variable -directly, without using customize, you must reload generic-x to put -your changes into effect." - :type (let (list) - (dolist (mode - (sort (append generic-default-modes - generic-mswindows-modes - generic-unix-modes - generic-other-modes - nil) - (lambda (a b) - (string< (symbol-name b) - (symbol-name a)))) - (cons 'set list)) - (push `(const ,mode) list))) - :set (lambda (s v) - (set-default s v) - (unless load-in-progress - (load "generic-x"))) - :version "22.1") - ;;; Apache -(when (memq 'apache-conf-generic-mode generic-extras-enable-list) - (define-generic-mode apache-conf-generic-mode '(?#) nil @@ -278,9 +186,7 @@ your changes into effect." '((nil "^\\([-A-Za-z0-9_]+\\)" 1) ("*Directories*" "^\\s-*]+\\)>" 1) ("*Locations*" "^\\s-*]+\\)>" 1))))) - "Generic mode for Apache or HTTPD configuration files.")) - -(when (memq 'apache-log-generic-mode generic-extras-enable-list) + "Generic mode for Apache or HTTPD configuration files.") (define-generic-mode apache-log-generic-mode nil @@ -291,11 +197,9 @@ your changes into effect." (2 font-lock-variable-name-face))) '("access_log\\'") nil - "Generic mode for Apache log files.")) + "Generic mode for Apache log files.") ;;; Samba -(when (memq 'samba-generic-mode generic-extras-enable-list) - (define-generic-mode samba-generic-mode '(?\; ?#) nil @@ -305,13 +209,11 @@ your changes into effect." (2 font-lock-type-face))) '("smb\\.conf\\'") '(generic-bracket-support) - "Generic mode for Samba configuration files.")) + "Generic mode for Samba configuration files.") ;;; Fvwm ;; This is pretty basic. Also, modes for other window managers could ;; be defined as well. -(when (memq 'fvwm-generic-mode generic-extras-enable-list) - (define-generic-mode fvwm-generic-mode '(?#) '("AddToMenu" @@ -330,33 +232,28 @@ your changes into effect." nil '("\\.fvwmrc\\'" "\\.fvwm2rc\\'") nil - "Generic mode for FVWM configuration files.")) + "Generic mode for FVWM configuration files.") ;;; X Resource ;; I'm pretty sure I've seen an actual mode to do this, but I don't ;; think it's standard with Emacs -(when (memq 'x-resource-generic-mode generic-extras-enable-list) - (define-generic-mode x-resource-generic-mode '(?!) nil '(("^\\([^:\n]+:\\)" 1 font-lock-variable-name-face)) '("\\.Xdefaults\\'" "\\.Xresources\\'" "\\.Xenvironment\\'" "\\.ad\\'") nil - "Generic mode for X Resource configuration files.")) + "Generic mode for X Resource configuration files.") -(if (memq 'xmodmap-generic-mode generic-extras-enable-list) (define-generic-mode xmodmap-generic-mode '(?!) '("add" "clear" "keycode" "keysym" "remove" "pointer") nil '("[xX]modmap\\(rc\\)?\\'") nil - "Simple mode for xmodmap files.")) + "Simple mode for xmodmap files.") ;;; Hosts -(when (memq 'hosts-generic-mode generic-extras-enable-list) - (define-generic-mode hosts-generic-mode '(?#) '("localhost") @@ -364,27 +261,20 @@ your changes into effect." ("\\<\\([0-9A-Fa-f:]+\\)\\>" 1 font-lock-constant-face)) '("[hH][oO][sS][tT][sS]\\'") nil - "Generic mode for HOSTS files.")) + "Generic mode for HOSTS files.") ;;; Windows INF files -;; If i-g-m-f-f-h is defined, then so is i-g-m. -(declare-function ini-generic-mode "generic-x") - -(when (memq 'inf-generic-mode generic-extras-enable-list) - (define-generic-mode inf-generic-mode '(?\;) nil '(("^\\(\\[.*\\]\\)" 1 font-lock-constant-face)) '("\\.[iI][nN][fF]\\'") '(generic-bracket-support) - "Generic mode for MS-Windows INF files.")) + "Generic mode for MS-Windows INF files.") ;;; Windows INI files ;; Should define escape character as well! -(when (memq 'ini-generic-mode generic-extras-enable-list) - (define-generic-mode ini-generic-mode '(?\;) nil @@ -411,13 +301,9 @@ like an INI file. You can add this hook to `find-file-hook'." (goto-char (point-min)) (and (looking-at "^\\s-*\\[.*\\]") (ini-generic-mode))))) -(define-obsolete-function-alias 'generic-mode-ini-file-find-file-hook - 'ini-generic-mode-find-file-hook "28.1")) ;;; Windows REG files ;;; Unfortunately, Windows 95 and Windows NT have different REG file syntax! -(when (memq 'reg-generic-mode generic-extras-enable-list) - (define-generic-mode reg-generic-mode '(?\;) '("key" "classes_root" "REGEDIT" "REGEDIT4") @@ -428,19 +314,11 @@ like an INI file. You can add this hook to `find-file-hook'." (lambda () (setq imenu-generic-expression '((nil "^\\s-*\\(.*\\)\\s-*=" 1))))) - "Generic mode for MS-Windows Registry files.")) - -(declare-function w32-shell-name "w32-fns" ()) - -;;; DOS/Windows BAT files -(when (memq 'bat-generic-mode generic-extras-enable-list) - (define-obsolete-function-alias 'bat-generic-mode 'bat-mode "24.4")) + "Generic mode for MS-Windows Registry files.") ;;; Mailagent ;; Mailagent is a Unix mail filtering program. Anyone wanna do a ;; generic mode for procmail? -(when (memq 'mailagent-rules-generic-mode generic-extras-enable-list) - (define-generic-mode mailagent-rules-generic-mode '(?#) '("SAVE" "DELETE" "PIPE" "ANNOTATE" "REJECT") @@ -451,11 +329,9 @@ like an INI file. You can add this hook to `find-file-hook'." (lambda () (setq imenu-generic-expression '((nil "\\s-/\\([^/]+\\)/[i, \t\n]" 1))))) - "Generic mode for Mailagent rules files.")) + "Generic mode for Mailagent rules files.") ;; Solaris/Sys V prototype files -(when (memq 'prototype-generic-mode generic-extras-enable-list) - (define-generic-mode prototype-generic-mode '(?#) nil @@ -474,11 +350,9 @@ like an INI file. You can add this hook to `find-file-hook'." (2 font-lock-variable-name-face))) '("prototype\\'") nil - "Generic mode for Sys V prototype files.")) + "Generic mode for Sys V prototype files.") ;; Solaris/Sys V pkginfo files -(when (memq 'pkginfo-generic-mode generic-extras-enable-list) - (define-generic-mode pkginfo-generic-mode '(?#) nil @@ -487,17 +361,9 @@ like an INI file. You can add this hook to `find-file-hook'." (2 font-lock-variable-name-face))) '("pkginfo\\'") nil - "Generic mode for Sys V pkginfo files.")) - -;; Javascript mode -;; Obsolete; defer to js-mode from js.el. -(when (memq 'javascript-generic-mode generic-extras-enable-list) - (define-obsolete-function-alias 'javascript-generic-mode 'js-mode "24.3") - (define-obsolete-variable-alias 'javascript-generic-mode-hook 'js-mode-hook "24.3")) + "Generic mode for Sys V pkginfo files.") ;; VRML files -(when (memq 'vrml-generic-mode generic-extras-enable-list) - (define-generic-mode vrml-generic-mode '(?#) '("DEF" @@ -545,11 +411,9 @@ like an INI file. You can add this hook to `find-file-hook'." ("*Definitions*" "DEF\\s-+\\([-A-Za-z0-9_]+\\)\\s-+\\([A-Za-z0-9]+\\)\\s-*{" 1))))) - "Generic Mode for VRML files.")) + "Generic Mode for VRML files.") ;; Java Manifests -(when (memq 'java-manifest-generic-mode generic-extras-enable-list) - (define-generic-mode java-manifest-generic-mode '(?#) '("Name" @@ -566,11 +430,9 @@ like an INI file. You can add this hook to `find-file-hook'." (2 font-lock-constant-face))) '("[mM][aA][nN][iI][fF][eE][sS][tT]\\.[mM][fF]\\'") nil - "Generic mode for Java Manifest files.")) + "Generic mode for Java Manifest files.") ;; Java properties files -(when (memq 'java-properties-generic-mode generic-extras-enable-list) - (define-generic-mode java-properties-generic-mode '(?! ?#) nil @@ -596,11 +458,9 @@ like an INI file. You can add this hook to `find-file-hook'." (lambda () (setq imenu-generic-expression '((nil "^\\([^#! \t\n\r=:]+\\)" 1))))) - "Generic mode for Java properties files.")) + "Generic mode for Java properties files.") ;; C shell alias definitions -(when (memq 'alias-generic-mode generic-extras-enable-list) - (define-generic-mode alias-generic-mode '(?#) '("alias" "unalias") @@ -613,11 +473,9 @@ like an INI file. You can add this hook to `find-file-hook'." (lambda () (setq imenu-generic-expression '((nil "^\\(alias\\|unalias\\)\\s-+\\([-a-zA-Z0-9_]+\\)" 2))))) - "Generic mode for C Shell alias files.")) + "Generic mode for C Shell alias files.") ;; Ansible inventory files -(when (memq 'ansible-inventory-generic-mode generic-extras-enable-list) - (define-generic-mode ansible-inventory-generic-mode '(?#) nil @@ -636,12 +494,10 @@ like an INI file. You can add this hook to `find-file-hook'." (setq imenu-generic-expression '((nil "^\\s-*\\[\\(.*\\)\\]" 1) ("*Variables*" "\\s-+\\([^ =\n\r]+\\)=" 1))))) - "Generic mode for Ansible inventory files.")) + "Generic mode for Ansible inventory files.") ;;; Windows RC files ;; Contributed by ACorreir@pervasive-sw.com (Alfred Correira) -(when (memq 'rc-generic-mode generic-extras-enable-list) - (define-generic-mode rc-generic-mode ;; '(?\/) '("//") @@ -721,15 +577,13 @@ like an INI file. You can add this hook to `find-file-hook'." '("^#[ \t]*\\(\\sw+\\)\\>[ \t]*\\(\\sw+\\)?" (1 font-lock-constant-face) (2 font-lock-variable-name-face nil t)))) - '("\\.[rR][cC]\\'") - nil - "Generic mode for MS-Windows Resource files.")) + '("\\.[rR][cC]\\'") + nil + "Generic mode for MS-Windows Resource files.") ;; InstallShield RUL files ;; Contributed by Alfred.Correira@Pervasive.Com ;; Bugfixes by "Rolf Sandau" -(when (memq 'rul-generic-mode generic-extras-enable-list) - (eval-when-compile ;;; build the regexp strings using regexp-opt @@ -1372,11 +1226,9 @@ like an INI file. You can add this hook to `find-file-hook'." > "begin" \n > _ \n resume: - > "end;")) + > "end;") ;; Additions by ACorreir@pervasive-sw.com (Alfred Correira) -(when (memq 'mailrc-generic-mode generic-extras-enable-list) - (define-generic-mode mailrc-generic-mode '(?#) '("alias" @@ -1398,11 +1250,9 @@ like an INI file. You can add this hook to `find-file-hook'." (2 font-lock-variable-name-face))) '("\\.mailrc\\'") nil - "Mode for mailrc files.")) + "Mode for mailrc files.") ;; Inetd.conf -(when (memq 'inetd-conf-generic-mode generic-extras-enable-list) - (define-generic-mode inetd-conf-generic-mode '(?#) '("stream" @@ -1417,11 +1267,9 @@ like an INI file. You can add this hook to `find-file-hook'." (list (lambda () (setq imenu-generic-expression - '((nil "^\\([-A-Za-z0-9_]+\\)" 1))))))) + '((nil "^\\([-A-Za-z0-9_]+\\)" 1)))))) ;; Services -(when (memq 'etc-services-generic-mode generic-extras-enable-list) - (define-generic-mode etc-services-generic-mode '(?#) '("tcp" @@ -1434,11 +1282,9 @@ like an INI file. You can add this hook to `find-file-hook'." (list (lambda () (setq imenu-generic-expression - '((nil "^\\([-A-Za-z0-9_]+\\)" 1))))))) + '((nil "^\\([-A-Za-z0-9_]+\\)" 1)))))) ;; Password and Group files -(when (memq 'etc-passwd-generic-mode generic-extras-enable-list) - (define-generic-mode etc-passwd-generic-mode nil ;; No comment characters '("root") ;; Only one keyword @@ -1476,11 +1322,9 @@ like an INI file. You can add this hook to `find-file-hook'." (list (lambda () (setq imenu-generic-expression - '((nil "^\\([-A-Za-z0-9_]+\\):" 1))))))) + '((nil "^\\([-A-Za-z0-9_]+\\):" 1)))))) ;; Fstab -(when (memq 'etc-fstab-generic-mode generic-extras-enable-list) - (define-generic-mode etc-fstab-generic-mode '(?#) '("adfs" @@ -1592,11 +1436,9 @@ like an INI file. You can add this hook to `find-file-hook'." (list (lambda () (setq imenu-generic-expression - '((nil "^\\([^# \t]+\\)\\s-+" 1))))))) + '((nil "^\\([^# \t]+\\)\\s-+" 1)))))) ;; /etc/sudoers -(when (memq 'etc-sudoers-generic-mode generic-extras-enable-list) - (define-generic-mode etc-sudoers-generic-mode '(?#) '("User_Alias" "Runas_Alias" "Host_Alias" "Cmnd_Alias" @@ -1607,11 +1449,9 @@ like an INI file. You can add this hook to `find-file-hook'." ("\\<\\(%[A-Za-z0-9_]+\\)\\>" 1 font-lock-variable-name-face)) '("/etc/sudoers\\'") nil - "Generic mode for sudoers configuration files.")) + "Generic mode for sudoers configuration files.") ;; From Jacques Duthen -(when (memq 'show-tabs-generic-mode generic-extras-enable-list) - (eval-when-compile (defconst show-tabs-generic-mode-font-lock-defaults-1 @@ -1649,14 +1489,12 @@ like an INI file. You can add this hook to `find-file-hook'." nil ;; no auto-mode-alist ;; '(show-tabs-generic-mode-hook-fun) nil - "Generic mode to show tabs and trailing spaces.")) + "Generic mode to show tabs and trailing spaces.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; DNS modes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(when (memq 'named-boot-generic-mode generic-extras-enable-list) - (define-generic-mode named-boot-generic-mode ;; List of comment characters '(?\;) @@ -1672,9 +1510,7 @@ like an INI file. You can add this hook to `find-file-hook'." ;; List of additional automode-alist expressions '("/etc/named\\.boot\\'") ;; List of set up functions to call - nil)) - -(when (memq 'named-database-generic-mode generic-extras-enable-list) + nil) (define-generic-mode named-database-generic-mode ;; List of comment characters @@ -1695,9 +1531,7 @@ like an INI file. You can add this hook to `find-file-hook'." (defun named-database-print-serial () "Print a serial number based on the current date." (interactive) - (insert (format-time-string named-database-time-string)))) - -(when (memq 'resolve-conf-generic-mode generic-extras-enable-list) + (insert (format-time-string named-database-time-string))) (define-generic-mode resolve-conf-generic-mode ;; List of comment characters @@ -1709,14 +1543,12 @@ like an INI file. You can add this hook to `find-file-hook'." ;; List of additional auto-mode-alist expressions '("/etc/resolve?\\.conf\\'") ;; List of set up functions to call - nil)) + nil) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Modes for spice and common electrical engineering circuit netlist formats ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(when (memq 'spice-generic-mode generic-extras-enable-list) - (define-generic-mode spice-generic-mode nil '("and" @@ -1752,9 +1584,7 @@ like an INI file. You can add this hook to `find-file-hook'." ;; Make keywords case-insensitive (lambda () (setq font-lock-defaults '(generic-font-lock-keywords nil t)))) - "Generic mode for SPICE circuit netlist files.")) - -(when (memq 'ibis-generic-mode generic-extras-enable-list) + "Generic mode for SPICE circuit netlist files.") (define-generic-mode ibis-generic-mode '(?|) @@ -1763,9 +1593,7 @@ like an INI file. You can add this hook to `find-file-hook'." ("\\(\\(_\\|\\w\\)+\\)\\s-*=" 1 font-lock-variable-name-face)) '("\\.[iI][bB][sS]\\'") '(generic-bracket-support) - "Generic mode for IBIS circuit netlist files.")) - -(when (memq 'astap-generic-mode generic-extras-enable-list) + "Generic mode for IBIS circuit netlist files.") (define-generic-mode astap-generic-mode nil @@ -1799,9 +1627,7 @@ like an INI file. You can add this hook to `find-file-hook'." ;; Make keywords case-insensitive (lambda () (setq font-lock-defaults '(generic-font-lock-keywords nil t)))) - "Generic mode for ASTAP circuit netlist files.")) - -(when (memq 'etc-modules-conf-generic-mode generic-extras-enable-list) + "Generic mode for ASTAP circuit netlist files.") (define-generic-mode etc-modules-conf-generic-mode ;; List of comment characters @@ -1843,7 +1669,98 @@ like an INI file. You can add this hook to `find-file-hook'." ;; List of additional automode-alist expressions '("/etc/modules\\.conf" "/etc/conf\\.modules") ;; List of set up functions to call - nil)) + nil) + +;; Obsolete + +(define-obsolete-function-alias 'javascript-generic-mode #'js-mode "24.3") +(define-obsolete-variable-alias 'javascript-generic-mode-hook 'js-mode-hook "24.3") + +(define-obsolete-function-alias 'bat-generic-mode #'bat-mode "24.4") + +(define-obsolete-function-alias 'generic-mode-ini-file-find-file-hook + #'ini-generic-mode-find-file-hook "28.1") + +(defconst generic-default-modes + '(apache-conf-generic-mode + apache-log-generic-mode + hosts-generic-mode + java-manifest-generic-mode + java-properties-generic-mode + javascript-generic-mode + show-tabs-generic-mode + vrml-generic-mode) + "List of generic modes that are defined by default.") +(make-obsolete-variable 'generic-default-modes "no longer used." "28.1") + +(defconst generic-mswindows-modes + '(bat-generic-mode + inf-generic-mode + ini-generic-mode + rc-generic-mode + reg-generic-mode + rul-generic-mode) + "List of generic modes that are defined by default on MS-Windows.") +(make-obsolete-variable 'generic-mswindows-modes "no longer used." "28.1") + +(defconst generic-unix-modes + '(alias-generic-mode + ansible-inventory-generic-mode + etc-fstab-generic-mode + etc-modules-conf-generic-mode + etc-passwd-generic-mode + etc-services-generic-mode + etc-sudoers-generic-mode + fvwm-generic-mode + inetd-conf-generic-mode + mailagent-rules-generic-mode + mailrc-generic-mode + named-boot-generic-mode + named-database-generic-mode + prototype-generic-mode + resolve-conf-generic-mode + samba-generic-mode + x-resource-generic-mode + xmodmap-generic-mode) + "List of generic modes that are defined by default on Unix.") +(make-obsolete-variable 'generic-unix-modes "no longer used." "28.1") + +(defconst generic-other-modes + '(astap-generic-mode + ibis-generic-mode + pkginfo-generic-mode + spice-generic-mode) + "List of generic modes that are not defined by default.") +(make-obsolete-variable 'generic-other-modes "no longer used." "28.1") + +(defcustom generic-extras-enable-list + (append generic-default-modes + (if (memq system-type '(windows-nt ms-dos)) + generic-mswindows-modes + generic-unix-modes) + nil) + "List of generic modes to define. +Each entry in the list should be a symbol. If you set this variable +directly, without using customize, you must reload generic-x to put +your changes into effect." + :type (let (list) + (dolist (mode + (sort (append generic-default-modes + generic-mswindows-modes + generic-unix-modes + generic-other-modes + nil) + (lambda (a b) + (string< (symbol-name b) + (symbol-name a)))) + (cons 'set list)) + (push `(const ,mode) list))) + :set (lambda (s v) + (set-default s v) + (unless load-in-progress + (load "generic-x"))) + :version "22.1") +(make-obsolete-variable 'generic-extras-enable-list "no longer used." "28.1") (provide 'generic-x) commit 627a02467508140d213a68c9eed6cb78a5e94860 Author: Lars Ingebrigtsen Date: Tue Feb 9 16:28:30 2021 +0100 Note that the `values' variable is now obsolete * src/lread.c (syms_of_lread): Note that it's obsolete in the doc string (because we can't mark it as obsolete "properly" yet, because that leads to compilation warnings when somebody (let (values) ... values). diff --git a/etc/NEWS b/etc/NEWS index ec574543d1..7f02f6106d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2217,6 +2217,8 @@ back in Emacs 23.1. The affected functions are: 'make-obsolete', * Lisp Changes in Emacs 28.1 +** The 'values' variable is now obsolete. + --- ** New variable 'indent-line-ignored-functions'. This allows modes to cycle through a set of indentation functions diff --git a/src/lread.c b/src/lread.c index 010194c34e..dea1b232ff 100644 --- a/src/lread.c +++ b/src/lread.c @@ -4833,7 +4833,8 @@ to find all the symbols in an obarray, use `mapatoms'. */); DEFVAR_LISP ("values", Vvalues, doc: /* List of values of all expressions which were read, evaluated and printed. -Order is reverse chronological. */); +Order is reverse chronological. +This variable is obsolete as of Emacs 28.1 and should not be used. */); XSYMBOL (intern ("values"))->u.s.declared_special = false; DEFVAR_LISP ("standard-input", Vstandard_input, commit 8e3ace4297512d9f1a2825d332b7e70c6ae3ea15 Author: Basil L. Contovounesios Date: Tue Feb 9 13:00:56 2021 +0000 ; Fix recent change in eval-last-sexp diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 0325d4ea75..312153052d 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -1268,7 +1268,7 @@ If `eval-expression-debug-on-error' is non-nil, which is the default, this command arranges for all errors to enter the debugger." (interactive "P") (if (null eval-expression-debug-on-error) - (values--store-values + (values--store-value (elisp--eval-last-sexp eval-last-sexp-arg-internal)) (let ((value (let ((debug-on-error elisp--eval-last-sexp-fake-value)) commit 1c326dfc1ce79bcbcfe9d7ad904e2184d4a691c4 Author: Basil L. Contovounesios Date: Tue Feb 9 12:50:36 2021 +0000 ; Finish customize-changed-options obsoletion diff --git a/etc/NEWS b/etc/NEWS index 52e9ab0b1d..ec574543d1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -916,7 +916,7 @@ To revert to the previous behavior, *** Most customize commands now hide obsolete user options. Obsolete user options are no longer shown in the listings produced by the commands 'customize', 'customize-group', 'customize-apropos' and -'customize-changed-options'. +'customize-changed'. To customize obsolete user options, use 'customize-option' or 'customize-saved'. diff --git a/test/lisp/cus-edit-tests.el b/test/lisp/cus-edit-tests.el index 95f62e0d7e..97b3349000 100644 --- a/test/lisp/cus-edit-tests.el +++ b/test/lisp/cus-edit-tests.el @@ -53,9 +53,9 @@ (customize-apropos "cus-edit-tests") (should-not (search-forward cus-edit-tests--obsolete-option-tag nil t)))) -(ert-deftest cus-edit-tests-customize-changed-options/hide-obsolete () +(ert-deftest cus-edit-tests-customize-changed/hide-obsolete () (with-cus-edit-test "*Customize Changed Options*" - (customize-changed-options "917.2") ; some future version + (customize-changed "917.2") ;; Some future version. (should-not (search-forward cus-edit-tests--obsolete-option-tag nil t)))) (ert-deftest cus-edit-tests-customize-group/hide-obsolete () commit 69d3a6c90f9bafdc4742097d1828ed7204aa12e0 Author: Alan Mackenzie Date: Tue Feb 9 09:41:13 2021 +0000 Allow exit-minibuffer to be called from Lisp code. Fixes bug #46373 * lisp/minibuffer.el (exit-minibuffer): Throw the error "Not in most nested minibuffer" only when the current buffer is a minibuffer (thus the command came directly from a key binding). * doc/lispref/minibuf.texi (Minibuffer Commands): Change the documentation accordingly. diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index 185d355ba7..b60775d457 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -2393,7 +2393,7 @@ minibuffer. @deffn Command exit-minibuffer This command exits the active minibuffer. It is normally bound to keys in minibuffer local keymaps. The command throws an error if the -current buffer is not the active minibuffer. +current buffer is a minibuffer, but not the active minibuffer. @end deffn @deffn Command self-insert-and-exit diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 03cc70c0d4..a899a943d4 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -2116,13 +2116,15 @@ variables.") (defun exit-minibuffer () "Terminate this minibuffer argument." (interactive) + (when (or + (innermost-minibuffer-p) + (not (minibufferp))) ;; If the command that uses this has made modifications in the minibuffer, ;; we don't want them to cause deactivation of the mark in the original ;; buffer. ;; A better solution would be to make deactivate-mark buffer-local ;; (or to turn it into a list of buffers, ...), but in the mean time, ;; this should do the trick in most cases. - (when (innermost-minibuffer-p) (setq deactivate-mark nil) (throw 'exit nil)) (error "%s" "Not in most nested minibuffer")) commit 5131e3accccc7bb3d59ab03cbb990eb3261ee9da Author: Lars Ingebrigtsen Date: Tue Feb 9 09:20:11 2021 +0100 Make pcomplete-ignore-case obsolete * lisp/pcomplete.el (pcomplete-completions-at-point) (pcomplete-stub, pcomplete--entries, pcomplete-insert-entry): * lisp/eshell/em-cmpl.el (eshell-cmpl-initialize): * lisp/eshell/em-cmpl.el (eshell-cmpl-ignore-case): * lisp/erc/erc-pcomplete.el (pcomplete-erc-setup): Use `completion-ignore-case' instead (bug#23117). * lisp/pcomplete.el (pcomplete-ignore-case): Make obsolete. diff --git a/etc/NEWS b/etc/NEWS index 513004885c..52e9ab0b1d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2056,6 +2056,8 @@ directory instead of the default directory. * Incompatible Lisp Changes in Emacs 28.1 +** 'pcomplete-ignore-case' is now an obsolete alias of 'completion-ignore-case'. + ** 'completions-annotations' face is not used when the caller puts own face. This affects the suffix specified by completion 'annotation-function'. diff --git a/lisp/erc/erc-pcomplete.el b/lisp/erc/erc-pcomplete.el index ab4c7c580c..ddaf78774a 100644 --- a/lisp/erc/erc-pcomplete.el +++ b/lisp/erc/erc-pcomplete.el @@ -89,7 +89,7 @@ for use on `completion-at-point-function'." (defun pcomplete-erc-setup () "Setup `erc-mode' to use pcomplete." - (setq-local pcomplete-ignore-case t) + (setq-local completion-ignore-case t) (setq-local pcomplete-use-paring nil) (setq-local pcomplete-parse-arguments-function #'pcomplete-erc-parse-arguments) diff --git a/lisp/eshell/em-cmpl.el b/lisp/eshell/em-cmpl.el index 638c0ac230..cbfe0b8154 100644 --- a/lisp/eshell/em-cmpl.el +++ b/lisp/eshell/em-cmpl.el @@ -150,8 +150,8 @@ to writing a completion function." :type (get 'pcomplete-dir-ignore 'custom-type)) (defcustom eshell-cmpl-ignore-case (eshell-under-windows-p) - (eshell-cmpl--custom-variable-docstring 'pcomplete-ignore-case) - :type (get 'pcomplete-ignore-case 'custom-type)) + (eshell-cmpl--custom-variable-docstring 'completion-ignore-case) + :type (get 'completion-ignore-case 'custom-type)) (defcustom eshell-cmpl-autolist nil (eshell-cmpl--custom-variable-docstring 'pcomplete-autolist) @@ -259,7 +259,7 @@ to writing a completion function." eshell-cmpl-file-ignore) (setq-local pcomplete-dir-ignore eshell-cmpl-dir-ignore) - (setq-local pcomplete-ignore-case + (setq-local completion-ignore-case eshell-cmpl-ignore-case) (setq-local pcomplete-autolist eshell-cmpl-autolist) diff --git a/lisp/pcomplete.el b/lisp/pcomplete.el index 7effb27af7..b648ecf098 100644 --- a/lisp/pcomplete.el +++ b/lisp/pcomplete.el @@ -135,11 +135,8 @@ "A regexp of names to be disregarded during directory completion." :type '(choice regexp (const :tag "None" nil))) -(defcustom pcomplete-ignore-case (memq system-type '(ms-dos windows-nt cygwin)) - ;; FIXME: the doc mentions file-name completion, but the code - ;; seems to apply it to all completions. - "If non-nil, ignore case when doing filename completion." - :type 'boolean) +(define-obsolete-variable-alias 'pcomplete-ignore-case 'completion-ignore-case + "28.1") (defcustom pcomplete-autolist nil "If non-nil, automatically list possibilities on partial completion. @@ -472,7 +469,7 @@ Same as `pcomplete' but using the standard completion UI." (not (member (funcall norm-func (directory-file-name f)) seen))))))) - (when pcomplete-ignore-case + (when completion-ignore-case (setq table (completion-table-case-fold table))) (list beg (point) table :predicate pred @@ -865,7 +862,7 @@ this is `comint-dynamic-complete-functions'." (sort comps pcomplete-compare-entry-function))) ,@(cdr (completion-file-name-table s p a))) (let ((completion-ignored-extensions nil) - (completion-ignore-case pcomplete-ignore-case)) + (completion-ignore-case completion-ignore-case)) (completion-table-with-predicate #'comint-completion-file-name-table pred 'strict s p a)))))) @@ -1116,7 +1113,7 @@ Typing SPC flushes the help buffer." "Insert a completion entry at point. Returns non-nil if a space was appended at the end." (let ((here (point))) - (if (not pcomplete-ignore-case) + (if (not completion-ignore-case) (insert-and-inherit (if raw-p (substring entry (length stub)) (comint-quote-filename @@ -1194,7 +1191,7 @@ Returns `partial' if completed as far as possible with the matches. Returns `listed' if a completion listing was shown. See also `pcomplete-filename'." - (let* ((completion-ignore-case pcomplete-ignore-case) + (let* ((completion-ignore-case completion-ignore-case) (completions (all-completions stub candidates)) (entry (try-completion stub candidates)) result) commit 9c1e89a32c65244a992a8a1ff73fd606f94a8a15 Author: Matt Armstrong Date: Tue Feb 9 09:10:45 2021 +0100 Preserve leading whitespace in `lm-commentary'. * lisp/emacs-lisp/lisp-mnt.el (lm-commentary): Preserve leading whitespace (bug#46364). diff --git a/lisp/emacs-lisp/lisp-mnt.el b/lisp/emacs-lisp/lisp-mnt.el index adb9cb2372..6d9c8c3279 100644 --- a/lisp/emacs-lisp/lisp-mnt.el +++ b/lisp/emacs-lisp/lisp-mnt.el @@ -495,7 +495,7 @@ absent, return nil." (concat "^;;;[[:blank:]]*\\(" lm-commentary-header "\\):[[:blank:]\n]*") - "^;;[[:blank:]]*" ; double semicolon prefix + "^;;[[:blank:]]?" ; double semicolon prefix "[[:blank:]\n]*\\'") ; trailing new-lines "" (buffer-substring-no-properties start (lm-commentary-end)))))))) commit 0cc35e14319d6b113049f5389629dc693541a14c Author: Lars Ingebrigtsen Date: Tue Feb 9 09:04:47 2021 +0100 Move all usages of `values' to `values--store-value' * lisp/simple.el (eval-expression): * lisp/progmodes/elisp-mode.el (eval-last-sexp): * lisp/emacs-lisp/pp.el (pp-eval-expression): * lisp/emacs-lisp/edebug.el (edebug-eval-expression): * lisp/emacs-lisp/pp.el (pp-eval-expression): * lisp/emacs-lisp/edebug.el (edebug-eval-expression): * lisp/cedet/data-debug.el (data-debug-eval-expression): Use it instead of pushing to `values' directly (bug#22066). * lisp/subr.el (values--store-value): New function. diff --git a/lisp/cedet/data-debug.el b/lisp/cedet/data-debug.el index a062a5a585..f0fa91b3b1 100644 --- a/lisp/cedet/data-debug.el +++ b/lisp/cedet/data-debug.el @@ -1045,30 +1045,30 @@ If the result is a list or vector, then use the data debugger to display it." (list (let ((minibuffer-completing-symbol t)) (read-from-minibuffer "Eval: " nil read-expression-map t - 'read-expression-history)) - )) - - (if (null eval-expression-debug-on-error) - (setq values (cons (eval expr) values)) - (let ((old-value (make-symbol "t")) new-value) - ;; Bind debug-on-error to something unique so that we can - ;; detect when evalled code changes it. - (let ((debug-on-error old-value)) - (setq values (cons (eval expr) values)) - (setq new-value debug-on-error)) - ;; If evalled code has changed the value of debug-on-error, - ;; propagate that change to the global binding. - (unless (eq old-value new-value) - (setq debug-on-error new-value)))) - - (if (or (consp (car values)) (vectorp (car values))) - (let ((v (car values))) - (data-debug-show-stuff v "Expression")) - ;; Old style - (prog1 - (prin1 (car values) t) - (let ((str (eval-expression-print-format (car values)))) - (if str (princ str t)))))) + 'read-expression-history)))) + + (let (result) + (if (null eval-expression-debug-on-error) + (setq result (values--store-value (eval expr))) + (let ((old-value (make-symbol "t")) new-value) + ;; Bind debug-on-error to something unique so that we can + ;; detect when evalled code changes it. + (let ((debug-on-error old-value)) + (setq result (values--store-value (eval expr))) + (setq new-value debug-on-error)) + ;; If evalled code has changed the value of debug-on-error, + ;; propagate that change to the global binding. + (unless (eq old-value new-value) + (setq debug-on-error new-value)))) + + (if (or (consp result) (vectorp result)) + (let ((v result)) + (data-debug-show-stuff v "Expression")) + ;; Old style + (prog1 + (prin1 result t) + (let ((str (eval-expression-print-format result))) + (if str (princ str t))))))) (provide 'data-debug) diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 5d595851b9..41768f2670 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -3801,9 +3801,10 @@ Print result in minibuffer." (interactive (list (read--expression "Eval: "))) (princ (edebug-outside-excursion - (setq values (cons (edebug-eval expr) values)) - (concat (edebug-safe-prin1-to-string (car values)) - (eval-expression-print-format (car values)))))) + (let ((result (edebug-eval expr))) + (values--store-value result) + (concat (edebug-safe-prin1-to-string result) + (eval-expression-print-format result)))))) (defun edebug-eval-last-sexp (&optional no-truncate) "Evaluate sexp before point in the outside environment. diff --git a/lisp/emacs-lisp/pp.el b/lisp/emacs-lisp/pp.el index ef4c960328..2fd4724aef 100644 --- a/lisp/emacs-lisp/pp.el +++ b/lisp/emacs-lisp/pp.el @@ -127,8 +127,9 @@ Also add the value to the front of the list in the variable `values'." (interactive (list (read--expression "Eval: "))) (message "Evaluating...") - (push (eval expression lexical-binding) values) - (pp-display-expression (car values) "*Pp Eval Output*")) + (let ((result (eval expression lexical-binding))) + (values--store-value result) + (pp-display-expression result "*Pp Eval Output*"))) ;;;###autoload (defun pp-macroexpand-expression (expression) diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 9a36206bfd..0325d4ea75 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -1268,9 +1268,8 @@ If `eval-expression-debug-on-error' is non-nil, which is the default, this command arranges for all errors to enter the debugger." (interactive "P") (if (null eval-expression-debug-on-error) - (let ((value (elisp--eval-last-sexp eval-last-sexp-arg-internal))) - (push value values) - value) + (values--store-values + (elisp--eval-last-sexp eval-last-sexp-arg-internal)) (let ((value (let ((debug-on-error elisp--eval-last-sexp-fake-value)) (cons (elisp--eval-last-sexp eval-last-sexp-arg-internal) diff --git a/lisp/simple.el b/lisp/simple.el index 568debaa61..0c5bcb6672 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1809,31 +1809,34 @@ this command arranges for all errors to enter the debugger." (cons (read--expression "Eval: ") (eval-expression-get-print-arguments current-prefix-arg))) - (if (null eval-expression-debug-on-error) - (push (eval (let ((lexical-binding t)) (macroexpand-all exp)) t) - values) - (let ((old-value (make-symbol "t")) new-value) - ;; Bind debug-on-error to something unique so that we can - ;; detect when evalled code changes it. - (let ((debug-on-error old-value)) - (push (eval (let ((lexical-binding t)) (macroexpand-all exp)) t) - values) - (setq new-value debug-on-error)) - ;; If evalled code has changed the value of debug-on-error, - ;; propagate that change to the global binding. - (unless (eq old-value new-value) - (setq debug-on-error new-value)))) - - (let ((print-length (unless no-truncate eval-expression-print-length)) - (print-level (unless no-truncate eval-expression-print-level)) - (eval-expression-print-maximum-character char-print-limit) - (deactivate-mark)) - (let ((out (if insert-value (current-buffer) t))) - (prog1 - (prin1 (car values) out) - (let ((str (and char-print-limit - (eval-expression-print-format (car values))))) - (when str (princ str out))))))) + (let (result) + (if (null eval-expression-debug-on-error) + (setq result + (values--store-value + (eval (let ((lexical-binding t)) (macroexpand-all exp)) t))) + (let ((old-value (make-symbol "t")) new-value) + ;; Bind debug-on-error to something unique so that we can + ;; detect when evalled code changes it. + (let ((debug-on-error old-value)) + (setq result + (values--store-value + (eval (let ((lexical-binding t)) (macroexpand-all exp)) t))) + (setq new-value debug-on-error)) + ;; If evalled code has changed the value of debug-on-error, + ;; propagate that change to the global binding. + (unless (eq old-value new-value) + (setq debug-on-error new-value)))) + + (let ((print-length (unless no-truncate eval-expression-print-length)) + (print-level (unless no-truncate eval-expression-print-level)) + (eval-expression-print-maximum-character char-print-limit) + (deactivate-mark)) + (let ((out (if insert-value (current-buffer) t))) + (prog1 + (prin1 result out) + (let ((str (and char-print-limit + (eval-expression-print-format result)))) + (when str (princ str out)))))))) (defun edit-and-eval-command (prompt command) "Prompting with PROMPT, let user edit COMMAND and eval result. diff --git a/lisp/subr.el b/lisp/subr.el index f0de6d5ac9..6573090ebe 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1655,6 +1655,12 @@ The return value has the form (WIDTH . HEIGHT). POSITION should be a list of the form returned by `event-start' and `event-end'." (nth 9 position)) +(defun values--store-value (value) + "Store VALUE in the obsolete `values' variable." + (with-suppressed-warnings ((obsolete values)) + (push value values)) + value) + ;;;; Obsolescent names for functions. @@ -1721,6 +1727,10 @@ be a list of the form returned by `event-start' and `event-end'." (make-obsolete-variable 'load-dangerous-libraries "no longer used." "27.1") +;; We can't actually make `values' obsolete, because that will result +;; in warnings when using `values' in let-bindings. +;;(make-obsolete-variable 'values "no longer used" "28.1") + ;;;; Alternate names for functions - these are not being phased out. commit 900ed3ad84c2144ca6bd86f3f7bd20f1c9347eb1 Author: Lars Ingebrigtsen Date: Tue Feb 9 08:32:40 2021 +0100 Don't use `values' in elisp--eval-defun * lisp/progmodes/elisp-mode.el (elisp--eval-defun): Don't use `values', since it's being deprecated (bug#22066). diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index a096866316..9a36206bfd 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -1339,7 +1339,8 @@ Return the result of evaluation." ;; printing, not while evaluating. (let ((debug-on-error eval-expression-debug-on-error) (print-length eval-expression-print-length) - (print-level eval-expression-print-level)) + (print-level eval-expression-print-level) + elisp--eval-defun-result) (save-excursion ;; Arrange for eval-region to "read" the (possibly) altered form. ;; eval-region handles recording which file defines a function or @@ -1355,17 +1356,18 @@ Return the result of evaluation." (setq end (point))) ;; Alter the form if necessary. (let ((form (eval-sexp-add-defvars - (elisp--eval-defun-1 (macroexpand form))))) + (elisp--eval-defun-1 + (macroexpand + `(setq elisp--eval-defun-result ,form)))))) (eval-region beg end standard-output (lambda (_ignore) ;; Skipping to the end of the specified region ;; will make eval-region return. (goto-char end) - form)))))) - (let ((str (eval-expression-print-format (car values)))) - (if str (princ str))) - ;; The result of evaluation has been put onto VALUES. So return it. - (car values)) + form))))) + (let ((str (eval-expression-print-format elisp--eval-defun-result))) + (if str (princ str))) + elisp--eval-defun-result)) (defun eval-defun (edebug-it) "Evaluate the top-level form containing point, or after point. commit fe449d8e081be9f09f29e5009bca0e152be85192 Author: Lars Ingebrigtsen Date: Tue Feb 9 08:20:08 2021 +0100 Finish customize-changed-options/customize-changed fix up * doc/emacs/custom.texi (Specific Customization): Fix customize-changed/customize-changed-options documentation. * lisp/cus-dep.el (custom-make-dependencies): Adjust doc string (bug#23085). * lisp/menu-bar.el (menu-bar-custom-menu): Adjust menu options. diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi index ccf5f1932f..22900c5739 100644 --- a/doc/emacs/custom.texi +++ b/doc/emacs/custom.texi @@ -519,12 +519,9 @@ Set up a customization buffer for all the settings and groups that match @var{regexp}. @item M-x customize-changed @key{RET} @var{version} @key{RET} -Set up a customization buffer with all the settings and groups -whose meaning has changed since Emacs version @var{version}. - -@item M-x customize-changed-options @key{RET} @var{version} @key{RET} -Set up a customization buffer with all the options whose meaning or -default values have changed since Emacs version @var{version}. +Set up a customization buffer with all the user options, faces and +groups whose meaning has changed since (or been added after) Emacs +version @var{version}. @item M-x customize-saved Set up a customization buffer containing all settings that you diff --git a/lisp/cus-dep.el b/lisp/cus-dep.el index a52d08266c..f0b108b77d 100644 --- a/lisp/cus-dep.el +++ b/lisp/cus-dep.el @@ -178,7 +178,7 @@ Usage: emacs -batch -l ./cus-dep.el -f custom-make-dependencies DIRS" (insert "\ ;; The remainder of this file is for handling :version. -;; We provide a minimum of information so that `customize-changed-options' +;; We provide a minimum of information so that `customize-changed' ;; can do its job. ;; For groups we set `custom-version', `group-documentation' and @@ -239,7 +239,7 @@ Usage: emacs -batch -l ./cus-dep.el -f custom-make-dependencies DIRS" This is an alist whose members have as car a version string, and as elements the files that have variables or faces that contain that version. These files should be loaded before showing the customization -buffer that `customize-changed-options' generates.\")\n\n")) +buffer that `customize-changed' generates.\")\n\n")) (save-buffer) (byte-compile-info (format "Generating %s...done" generated-custom-dependencies-file) t)) diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el index cd1ae964eb..dde6e8997b 100644 --- a/lisp/cus-edit.el +++ b/lisp/cus-edit.el @@ -1206,7 +1206,7 @@ Show the buffer in another window, but don't select it." (message "`%s' is an alias for `%s'" symbol basevar)))) (defvar customize-changed-options-previous-release "26.3" - "Version for `customize-changed-options' to refer back to by default.") + "Version for `customize-changed' to refer back to by default.") ;; Packages will update this variable, so make it available. ;;;###autoload diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index 2fdfcc8b58..133df65cbc 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -636,9 +636,9 @@ Do the same for the keys of the same name." :help "Customize value of specific option")) (bindings--define-key menu [separator-2] menu-bar-separator) - (bindings--define-key menu [customize-changed-options] - '(menu-item "New Options..." customize-changed-options - :help "Options added or changed in recent Emacs versions")) + (bindings--define-key menu [customize-changed] + '(menu-item "New Options..." customize-changed + :help "Options and faces added or changed in recent Emacs versions")) (bindings--define-key menu [customize-saved] '(menu-item "Saved Options" customize-saved :help "Customize previously saved options")) commit f3fd9591cfca5450b4bc74274340f24068f96fc7 Author: Lars Ingebrigtsen Date: Tue Feb 9 08:12:10 2021 +0100 Fix count-lines problem in non-ASCII buffers * src/fns.c (Fline_number_at_pos): Get the correct start position in non-ASCII buffers (bug#22763). diff --git a/src/fns.c b/src/fns.c index 02743c62a5..c16f9c6399 100644 --- a/src/fns.c +++ b/src/fns.c @@ -5769,7 +5769,7 @@ visible part of the buffer. If ABSOLUTE is non-nil, count the lines from the absolute start of the buffer. */) (register Lisp_Object position, Lisp_Object absolute) { - ptrdiff_t pos, start = BEGV; + ptrdiff_t pos, start = BEGV_BYTE; if (MARKERP (position)) pos = marker_position (position); diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el index b4007a6c3f..f2ddc2e3fb 100644 --- a/test/lisp/simple-tests.el +++ b/test/lisp/simple-tests.el @@ -67,6 +67,11 @@ (insert (propertize "\nbar\nbaz\nzut" 'invisible t)) (should (= (count-lines (point-min) (point-max) t) 2)))) +(ert-deftest simple-text-count-lines-non-ascii () + (with-temp-buffer + (insert "あ\nい\nう\nえ\nお\n") + (should (= (count-lines (point) (point)) 0)))) + ;;; `transpose-sexps' (defmacro simple-test--transpositions (&rest body) commit 69943ae70ce0aec075bd26ad0100c174b34bad7f Author: Stefan Monnier Date: Mon Feb 8 19:08:14 2021 -0500 * lisp/gnus/gnus-topic.el: Fix a backward incompatibility (gnus-topic-insert-topic-line): Make the vars used in `gnus-topic-line-format-spec` dynamically scoped since it seems that they're sometimes accessed from functions called by `gnus-topic-line-format-spec` :-( * lisp/gnus/gnus-util.el (gnus--\,@): Move macro to here... * lisp/gnus/gnus-art.el (gnus--\,@): .. from here. * lisp/gnus/gnus.el (gnus-method-to-server): Apply DeMorgan. diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index 7ded9e40e9..c9afa3ac94 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -4325,10 +4325,6 @@ If variable `gnus-use-long-file-name' is non-nil, it is (if (gnus-buffer-live-p gnus-original-article-buffer) (canlock-verify gnus-original-article-buffer))) -(defmacro gnus--\,@ (exp) - (declare (debug t)) - `(progn ,@(eval exp t))) - (gnus--\,@ (mapcar (lambda (func) `(defun ,(intern (format "gnus-%s" func)) diff --git a/lisp/gnus/gnus-topic.el b/lisp/gnus/gnus-topic.el index e7d1cf8616..3253b7853d 100644 --- a/lisp/gnus/gnus-topic.el +++ b/lisp/gnus/gnus-topic.el @@ -627,7 +627,14 @@ articles in the topic and its subtopics." (defun gnus-topic-insert-topic-line (name visiblep shownp level entries &optional unread) + (gnus--\,@ + (let ((vars '(indentation visible name level number-of-groups + total-number-of-articles entries))) + `((with-suppressed-warnings ((lexical ,@vars)) + ,@(mapcar (lambda (s) `(defvar ,s)) vars))))) (let* ((visible (if visiblep "" "...")) + (level level) + (name name) (indentation (make-string (* gnus-topic-indent-level level) ? )) (total-number-of-articles unread) (number-of-groups (length entries)) @@ -640,14 +647,7 @@ articles in the topic and its subtopics." (add-text-properties (point) (prog1 (1+ (point)) - (eval gnus-topic-line-format-spec - `((indentation . ,indentation) - (visible . ,visible) - (name . ,name) - (level . ,level) - (number-of-groups . ,number-of-groups) - (total-number-of-articles . ,total-number-of-articles) - (entries . ,entries)))) + (eval gnus-topic-line-format-spec t)) (list 'gnus-topic name 'gnus-topic-level level 'gnus-topic-unread unread diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el index 3c7c948c2b..f80243cfed 100644 --- a/lisp/gnus/gnus-util.el +++ b/lisp/gnus/gnus-util.el @@ -1068,6 +1068,11 @@ ARG is passed to the first function." ;;; Various +(defmacro gnus--\,@ (exp) + "Splice EXP's value (a list of Lisp forms) into the code." + (declare (debug t)) + `(progn ,@(eval exp t))) + (defvar gnus-group-buffer) ; Compiler directive (defun gnus-alive-p () "Say whether Gnus is running or not." diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index 98664ac2b4..7b94c64ae7 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el @@ -3212,9 +3212,9 @@ that that variable is buffer-local to the summary buffers." (format "%s" (car method)) (format "%s:%s" (car method) (cadr method)))) (name-method (cons name method))) - (when (and (not no-enter-cache) - (not (member name-method gnus-server-method-cache)) - (not (assoc (car name-method) gnus-server-method-cache))) + (unless (or no-enter-cache + (member name-method gnus-server-method-cache) + (assoc (car name-method) gnus-server-method-cache)) (push name-method gnus-server-method-cache)) name))) commit 1b0e6a16d3ae32576a642898c39695a3affd2fd7 Author: Eric Abrahamsen Date: Mon Feb 8 12:27:04 2021 -0800 Run Gnus group names through regexp-quote when matching results * lisp/gnus/gnus-search.el (gnus-search-indexed-parse-output): Be more careful about making sure group names will match search results correctly. diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el index 4538370584..d7b1c06114 100644 --- a/lisp/gnus/gnus-search.el +++ b/lisp/gnus/gnus-search.el @@ -1348,12 +1348,14 @@ Returns a list of [group article score] vectors." (let ((prefix (slot-value engine 'remove-prefix)) (group-regexp (when groups (mapconcat - (lambda (x) - (replace-regexp-in-string - ;; Accept any of [.\/] as path separators. - "[.\\/]" "[.\\\\/]" - (gnus-group-real-name x))) - groups "\\|"))) + (lambda (group-name) + (mapconcat #'regexp-quote + (split-string + (gnus-group-real-name group-name) + "[.\\/]") + "[.\\\\/]")) + groups + "\\|"))) artlist vectors article group) (goto-char (point-min)) (while (not (eobp)) commit 9a698da7dea51a59aa9ddfb71887ac6b865883dc Author: Eli Zaretskii Date: Mon Feb 8 18:19:31 2021 +0200 ; * etc/NEWS: Call out a recent change in Enriched mode. diff --git a/etc/NEWS b/etc/NEWS index 40fe215600..513004885c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1620,6 +1620,13 @@ that makes it a valid button. *** New variable 'thing-at-point-provider-alist'. This allows mode-specific alterations to how 'thing-at-point' works. +** Enriched mode + +--- +*** 'C-a' is by default no longer bound to 'beginning-of-line-text'. +This is so 'C-a' works as in other modes, and in particular holding +Shift while typing 'C-a', i.e. 'C-S-a', will now highlight the text. + ** Miscellaneous +++ commit dcc00bbb1989b27c49442422e7fbaf8c3f6415cb Author: Eli Zaretskii Date: Mon Feb 8 18:09:21 2021 +0200 ; * CONTRIBUTE: Clarify the "15-lines" rule a bit more. diff --git a/CONTRIBUTE b/CONTRIBUTE index 125c183229..9f0d9e7e16 100644 --- a/CONTRIBUTE +++ b/CONTRIBUTE @@ -67,10 +67,11 @@ error-prone. It also allows sending patches whose author is someone other than the email sender. Once the cumulative amount of your submissions exceeds about 15 lines -of non-trivial code, we will need you to assign to the FSF the -copyright for your contributions. Ask on emacs-devel@gnu.org, and we -will send you the necessary form together with the instructions to -fill and email it, in order to start this legal paperwork. +of non-trivial code you added or changed (not counting deleted lines), +we will need you to assign to the FSF the copyright for your +contributions. Ask on emacs-devel@gnu.org, and we will send you the +necessary form together with the instructions to fill and email it, in +order to start this legal paperwork. ** Issue tracker (a.k.a. "bug tracker") commit 120149cf6a82dd20dfade3b2c09996f7be562441 Author: Lars Ingebrigtsen Date: Mon Feb 8 07:30:18 2021 +0100 Clarify "changes" in CONTRIBUTE * CONTRIBUTE: Clarify that "changes" doesn't include removing code (bug#44834). (cherry picked from commit 33c9556c9db9b8c62dcd80dd3cc665e669ea66d4) diff --git a/CONTRIBUTE b/CONTRIBUTE index 4e42c7aafc..125c183229 100644 --- a/CONTRIBUTE +++ b/CONTRIBUTE @@ -67,7 +67,7 @@ error-prone. It also allows sending patches whose author is someone other than the email sender. Once the cumulative amount of your submissions exceeds about 15 lines -of non-trivial changes, we will need you to assign to the FSF the +of non-trivial code, we will need you to assign to the FSF the copyright for your contributions. Ask on emacs-devel@gnu.org, and we will send you the necessary form together with the instructions to fill and email it, in order to start this legal paperwork. commit 6b351b2d7608def23cc4bbd76ba8dc300708e953 Author: Eli Zaretskii Date: Mon Feb 8 18:04:00 2021 +0200 Fix scrolling past tall images * src/xdisp.c (try_window): Don't try checking the margins if the window is vscrolled, as that could cause unnecessary recentering when tall images are displayed. (Bug#46320) diff --git a/src/xdisp.c b/src/xdisp.c index 1815f98678..fb8eaf4b96 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -19452,8 +19452,11 @@ try_window (Lisp_Object window, struct text_pos pos, int flags) 'start_display' again. */ ptrdiff_t it_charpos = IT_CHARPOS (it); - /* Don't let the cursor end in the scroll margins. */ + /* Don't let the cursor end in the scroll margins. However, when + the window is vscrolled, we leave it to vscroll to handle the + margins, see window_scroll_pixel_based. */ if ((flags & TRY_WINDOW_CHECK_MARGINS) + && w->vscroll == 0 && !MINI_WINDOW_P (w)) { int top_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS); @@ -19462,7 +19465,7 @@ try_window (Lisp_Object window, struct text_pos pos, int flags) top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w); start_display (&it, w, pos); - if ((w->cursor.y >= 0 /* not vscrolled */ + if ((w->cursor.y >= 0 && w->cursor.y < top_scroll_margin && CHARPOS (pos) > BEGV) /* rms: considering make_cursor_line_fully_visible_p here commit cfb91b5bca51dadce661d51cd6bd3df94a2d5761 Author: Stefan Monnier Date: Mon Feb 8 09:18:41 2021 -0500 * lisp/indent.el (beginning-of-line-text): Mark it as a movement command So that combining it with `shift` selects the text, as usual, in case you have it bound for example to `C-a` in a mode like `enriched-mode`. diff --git a/lisp/indent.el b/lisp/indent.el index 5cbf0acaa2..285b8e2038 100644 --- a/lisp/indent.el +++ b/lisp/indent.el @@ -525,7 +525,7 @@ From the beginning of the line, moves past the left-margin indentation, the fill-prefix, and any indentation used for centering or right-justifying the line, but does not move past any whitespace that was explicitly inserted \(such as a tab used to indent the first line of a paragraph)." - (interactive "p") + (interactive "^p") (beginning-of-line n) (skip-chars-forward " \t") ;; Skip over fill-prefix. commit ce35760b19315b634e62e2c64988018189dcdbdc Author: Stefan Kangas Date: Mon Feb 8 09:03:27 2021 +0100 ; Minor license statement fixes diff --git a/admin/gitmerge.el b/admin/gitmerge.el index b92ecc7c78..851212c7bb 100644 --- a/admin/gitmerge.el +++ b/admin/gitmerge.el @@ -7,6 +7,8 @@ ;; Keywords: maint +;; This file is part of GNU Emacs. + ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or diff --git a/etc/themes/modus-operandi-theme.el b/etc/themes/modus-operandi-theme.el index c7a0f72c10..346000a093 100644 --- a/etc/themes/modus-operandi-theme.el +++ b/etc/themes/modus-operandi-theme.el @@ -10,18 +10,18 @@ ;; This file is part of GNU Emacs. -;; This program is free software; you can redistribute it and/or +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, + +;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. -;; + ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see . +;; along with GNU Emacs. If not, see . ;;; Commentary: ;; diff --git a/etc/themes/modus-vivendi-theme.el b/etc/themes/modus-vivendi-theme.el index 6e71e8d8e3..73f07d644b 100644 --- a/etc/themes/modus-vivendi-theme.el +++ b/etc/themes/modus-vivendi-theme.el @@ -10,18 +10,18 @@ ;; This file is part of GNU Emacs. -;; This program is free software; you can redistribute it and/or +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, + +;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. -;; + ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see . +;; along with GNU Emacs. If not, see . ;;; Commentary: ;; diff --git a/lisp/cedet/ede/proj-archive.el b/lisp/cedet/ede/proj-archive.el index 2b1e50dcea..038f994e4f 100644 --- a/lisp/cedet/ede/proj-archive.el +++ b/lisp/cedet/ede/proj-archive.el @@ -5,6 +5,8 @@ ;; Author: Eric M. Ludlam ;; Keywords: project, make +;; This file is part of GNU Emacs. + ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or diff --git a/lisp/emacs-lisp/tcover-ses.el b/lisp/emacs-lisp/tcover-ses.el index fb9cd8f47d..12b0dcfff9 100644 --- a/lisp/emacs-lisp/tcover-ses.el +++ b/lisp/emacs-lisp/tcover-ses.el @@ -6,6 +6,8 @@ ;; Keywords: spreadsheet lisp utility ;; Package: testcover +;; This file is part of GNU Emacs. + ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el index 21602f825c..4538370584 100644 --- a/lisp/gnus/gnus-search.el +++ b/lisp/gnus/gnus-search.el @@ -4,18 +4,20 @@ ;; Author: Eric Abrahamsen -;; This program is free software; you can redistribute it and/or modify +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, +;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see . +;; along with GNU Emacs. If not, see . ;;; Commentary: diff --git a/lisp/jsonrpc.el b/lisp/jsonrpc.el index 7f5aa8295f..f1fb6c1dda 100644 --- a/lisp/jsonrpc.el +++ b/lisp/jsonrpc.el @@ -10,18 +10,20 @@ ;; This is a GNU ELPA :core package. Avoid functionality that is not ;; compatible with the version of Emacs recorded above. -;; This program is free software; you can redistribute it and/or modify +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, +;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see . +;; along with GNU Emacs. If not, see . ;;; Commentary: diff --git a/lisp/org/ol-w3m.el b/lisp/org/ol-w3m.el index f1f3afd764..ebb11ce3d5 100644 --- a/lisp/org/ol-w3m.el +++ b/lisp/org/ol-w3m.el @@ -7,13 +7,13 @@ ;; Homepage: https://orgmode.org ;; ;; This file is part of GNU Emacs. -;; -;; This program is free software: you can redistribute it and/or modify + +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, +;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. diff --git a/lisp/org/org-refile.el b/lisp/org/org-refile.el index 1e0c339f7b..8b42f817c1 100644 --- a/lisp/org/org-refile.el +++ b/lisp/org/org-refile.el @@ -7,18 +7,18 @@ ;; ;; This file is part of GNU Emacs. -;; This program is free software; you can redistribute it and/or modify +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, +;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see . +;; along with GNU Emacs. If not, see . ;;; Commentary: diff --git a/test/lisp/dom-tests.el b/test/lisp/dom-tests.el index dbe3a15dac..0a0d783b82 100644 --- a/test/lisp/dom-tests.el +++ b/test/lisp/dom-tests.el @@ -5,6 +5,8 @@ ;; Author: Simen Heggestøyl ;; Keywords: +;; This file is part of GNU Emacs. + ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or diff --git a/test/lisp/emacs-lisp/cl-extra-tests.el b/test/lisp/emacs-lisp/cl-extra-tests.el index f3c308725a..91f0a1e201 100644 --- a/test/lisp/emacs-lisp/cl-extra-tests.el +++ b/test/lisp/emacs-lisp/cl-extra-tests.el @@ -4,18 +4,18 @@ ;; This file is part of GNU Emacs. -;; This program is free software: you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation, either version 3 of the -;; License, or (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. -;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see `https://www.gnu.org/licenses/'. +;; along with GNU Emacs. If not, see . ;;; Code: diff --git a/test/lisp/emacs-lisp/cl-lib-tests.el b/test/lisp/emacs-lisp/cl-lib-tests.el index 065ca4fa65..a5ec62b9c4 100644 --- a/test/lisp/emacs-lisp/cl-lib-tests.el +++ b/test/lisp/emacs-lisp/cl-lib-tests.el @@ -4,18 +4,18 @@ ;; This file is part of GNU Emacs. -;; This program is free software: you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation, either version 3 of the -;; License, or (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. -;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see `https://www.gnu.org/licenses/'. +;; along with GNU Emacs. If not, see . ;;; Commentary: diff --git a/test/lisp/emacs-lisp/cl-macs-tests.el b/test/lisp/emacs-lisp/cl-macs-tests.el index bcd63f73a3..2e5f3020b4 100644 --- a/test/lisp/emacs-lisp/cl-macs-tests.el +++ b/test/lisp/emacs-lisp/cl-macs-tests.el @@ -4,18 +4,18 @@ ;; This file is part of GNU Emacs. -;; This program is free software: you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation, either version 3 of the -;; License, or (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. -;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see `https://www.gnu.org/licenses/'. +;; along with GNU Emacs. If not, see . ;;; Commentary: diff --git a/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el b/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el index a3010f9e35..f8ca39c8c6 100644 --- a/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el +++ b/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el @@ -6,18 +6,18 @@ ;; This file is part of GNU Emacs. -;; This program is free software: you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation, either version 3 of the -;; License, or (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. -;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see . +;; along with GNU Emacs. If not, see . ;;; Commentary: diff --git a/test/lisp/emacs-lisp/edebug-tests.el b/test/lisp/emacs-lisp/edebug-tests.el index d60a6cb3d5..6a6080df3c 100644 --- a/test/lisp/emacs-lisp/edebug-tests.el +++ b/test/lisp/emacs-lisp/edebug-tests.el @@ -6,18 +6,18 @@ ;; This file is part of GNU Emacs. -;; This program is free software: you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation, either version 3 of the -;; License, or (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. -;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see . +;; along with GNU Emacs. If not, see . ;;; Commentary: diff --git a/test/lisp/emacs-lisp/ert-tests.el b/test/lisp/emacs-lisp/ert-tests.el index 40cb432708..bdacb0832b 100644 --- a/test/lisp/emacs-lisp/ert-tests.el +++ b/test/lisp/emacs-lisp/ert-tests.el @@ -6,18 +6,18 @@ ;; This file is part of GNU Emacs. -;; This program is free software: you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation, either version 3 of the -;; License, or (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. -;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see `https://www.gnu.org/licenses/'. +;; along with GNU Emacs. If not, see . ;;; Commentary: diff --git a/test/lisp/emacs-lisp/ert-x-tests.el b/test/lisp/emacs-lisp/ert-x-tests.el index f46fa63e4c..9f40a18d34 100644 --- a/test/lisp/emacs-lisp/ert-x-tests.el +++ b/test/lisp/emacs-lisp/ert-x-tests.el @@ -7,18 +7,18 @@ ;; This file is part of GNU Emacs. -;; This program is free software: you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation, either version 3 of the -;; License, or (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. -;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see `https://www.gnu.org/licenses/'. +;; along with GNU Emacs. If not, see . ;;; Commentary: diff --git a/test/lisp/emacs-lisp/lisp-mode-tests.el b/test/lisp/emacs-lisp/lisp-mode-tests.el index 85db3a00c8..e2cecdf6b0 100644 --- a/test/lisp/emacs-lisp/lisp-mode-tests.el +++ b/test/lisp/emacs-lisp/lisp-mode-tests.el @@ -2,6 +2,8 @@ ;; Copyright (C) 2017-2021 Free Software Foundation, Inc. +;; This file is part of GNU Emacs. + ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or diff --git a/test/lisp/emacs-lisp/lisp-tests.el b/test/lisp/emacs-lisp/lisp-tests.el index fd07011137..78ecf3ff03 100644 --- a/test/lisp/emacs-lisp/lisp-tests.el +++ b/test/lisp/emacs-lisp/lisp-tests.el @@ -8,6 +8,8 @@ ;; Author: Marcin Borkowski ;; Keywords: internal +;; This file is part of GNU Emacs. + ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or diff --git a/test/lisp/emacs-lisp/testcover-resources/testcases.el b/test/lisp/emacs-lisp/testcover-resources/testcases.el index 5dbf2272b1..7ced257c6f 100644 --- a/test/lisp/emacs-lisp/testcover-resources/testcases.el +++ b/test/lisp/emacs-lisp/testcover-resources/testcases.el @@ -6,18 +6,18 @@ ;; This file is part of GNU Emacs. -;; This program is free software: you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation, either version 3 of the -;; License, or (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. -;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see `https://www.gnu.org/licenses/'. +;; along with GNU Emacs. If not, see . ;;; Commentary: diff --git a/test/lisp/emacs-lisp/testcover-tests.el b/test/lisp/emacs-lisp/testcover-tests.el index 9f0312d85f..7854e33e77 100644 --- a/test/lisp/emacs-lisp/testcover-tests.el +++ b/test/lisp/emacs-lisp/testcover-tests.el @@ -6,18 +6,18 @@ ;; This file is part of GNU Emacs. -;; This program is free software: you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation, either version 3 of the -;; License, or (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. -;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see `https://www.gnu.org/licenses/'. +;; along with GNU Emacs. If not, see . ;;; Commentary: diff --git a/test/lisp/gnus/gnus-search-tests.el b/test/lisp/gnus/gnus-search-tests.el index 63469f8d51..e30ed9a80a 100644 --- a/test/lisp/gnus/gnus-search-tests.el +++ b/test/lisp/gnus/gnus-search-tests.el @@ -5,18 +5,20 @@ ;; Author: Eric Abrahamsen ;; Keywords: -;; This program is free software; you can redistribute it and/or modify +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, +;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see . +;; along with GNU Emacs. If not, see . ;;; Commentary: diff --git a/test/lisp/gnus/gnus-util-tests.el b/test/lisp/gnus/gnus-util-tests.el index 7f64b96303..959be7987d 100644 --- a/test/lisp/gnus/gnus-util-tests.el +++ b/test/lisp/gnus/gnus-util-tests.el @@ -3,12 +3,12 @@ ;; Author: Jens Lechtenbörger -;; This file is not part of GNU Emacs. +;; This file is part of GNU Emacs. -;; GNU Emacs is free software; you can redistribute it and/or modify +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test/lisp/gnus/mm-decode-tests.el b/test/lisp/gnus/mm-decode-tests.el index 7d059cb3f8..586097aaf3 100644 --- a/test/lisp/gnus/mm-decode-tests.el +++ b/test/lisp/gnus/mm-decode-tests.el @@ -4,10 +4,10 @@ ;; This file is part of GNU Emacs. -;; GNU Emacs is free software; you can redistribute it and/or modify +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test/lisp/gnus/mml-sec-tests.el b/test/lisp/gnus/mml-sec-tests.el index b743187030..a7ed7d3975 100644 --- a/test/lisp/gnus/mml-sec-tests.el +++ b/test/lisp/gnus/mml-sec-tests.el @@ -1,14 +1,15 @@ ;;; mml-sec-tests.el --- Tests mml-sec.el, see README-mml-secure.txt. -*- lexical-binding:t -*- + ;; Copyright (C) 2015, 2020-2021 Free Software Foundation, Inc. ;; Author: Jens Lechtenbörger -;; This file is not part of GNU Emacs. +;; This file is part of GNU Emacs. -;; GNU Emacs is free software; you can redistribute it and/or modify +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/test/lisp/net/sasl-scram-rfc-tests.el b/test/lisp/net/sasl-scram-rfc-tests.el index 3e9879a49d..dfd4cf0e7a 100644 --- a/test/lisp/net/sasl-scram-rfc-tests.el +++ b/test/lisp/net/sasl-scram-rfc-tests.el @@ -4,6 +4,8 @@ ;; Author: Magnus Henoch +;; This file is part of GNU Emacs. + ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or diff --git a/test/lisp/nxml/nxml-mode-tests.el b/test/lisp/nxml/nxml-mode-tests.el index 4baab1f760..7824691333 100644 --- a/test/lisp/nxml/nxml-mode-tests.el +++ b/test/lisp/nxml/nxml-mode-tests.el @@ -2,6 +2,8 @@ ;; Copyright (C) 2019-2021 Free Software Foundation, Inc. +;; This file is part of GNU Emacs. + ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or diff --git a/test/lisp/nxml/xsd-regexp-tests.el b/test/lisp/nxml/xsd-regexp-tests.el index 4dbc899924..2194602dbe 100644 --- a/test/lisp/nxml/xsd-regexp-tests.el +++ b/test/lisp/nxml/xsd-regexp-tests.el @@ -2,6 +2,8 @@ ;; Copyright (C) 2019-2021 Free Software Foundation, Inc. +;; This file is part of GNU Emacs. + ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or diff --git a/test/lisp/obsolete/cl-tests.el b/test/lisp/obsolete/cl-tests.el index 4a5f4f872b..0e02e1ca1b 100644 --- a/test/lisp/obsolete/cl-tests.el +++ b/test/lisp/obsolete/cl-tests.el @@ -4,18 +4,18 @@ ;; This file is part of GNU Emacs. -;; This program is free software: you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation, either version 3 of the -;; License, or (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. -;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see `https://www.gnu.org/licenses/'. +;; along with GNU Emacs. If not, see . ;;; Commentary: diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el index 928fb15f10..9f6593a177 100644 --- a/test/src/fns-tests.el +++ b/test/src/fns-tests.el @@ -4,18 +4,18 @@ ;; This file is part of GNU Emacs. -;; This program is free software: you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation, either version 3 of the -;; License, or (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. -;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see `https://www.gnu.org/licenses/'. +;; along with GNU Emacs. If not, see . ;;; Commentary: diff --git a/test/src/indent-tests.el b/test/src/indent-tests.el index 10f1202949..6a3f1a5c95 100644 --- a/test/src/indent-tests.el +++ b/test/src/indent-tests.el @@ -4,18 +4,18 @@ ;; This file is part of GNU Emacs. -;; This program is free software: you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation, either version 3 of the -;; License, or (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. -;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see `https://www.gnu.org/licenses/'. +;; along with GNU Emacs. If not, see . ;;; Commentary: commit 1a1193c8643d198d5260a4f929cfc1007ed0b39a Author: Stefan Kangas Date: Mon Feb 8 08:23:19 2021 +0100 * lisp/avoid.el: Doc fixes. diff --git a/lisp/avoid.el b/lisp/avoid.el index b53584ba9c..3b3848e20d 100644 --- a/lisp/avoid.el +++ b/lisp/avoid.el @@ -25,8 +25,10 @@ ;; For those who are annoyed by the mouse pointer obscuring text, ;; this mode moves the mouse pointer - either just a little out of ;; the way, or all the way to the corner of the frame. -;; To use, load or evaluate this file and type M-x mouse-avoidance-mode . -;; To set up permanently, put the following in your .emacs: +;; +;; To use, type `M-x mouse-avoidance-mode'. +;; +;; To set up permanently, put this in your .emacs: ;; ;; (if (display-mouse-p) (mouse-avoidance-mode 'animate)) ;; @@ -47,11 +49,6 @@ ;; ;; For completely random pointer shape, replace the setq above with: ;; (setq x-pointer-shape (mouse-avoidance-random-shape)) -;; -;; Bugs / Warnings / To-Do: -;; -;; - Using this code does slow Emacs down. "banish" mode shouldn't -;; be too bad, and on my workstation even "animate" is reasonable. ;; Credits: ;; This code was helped by all those who contributed suggestions, @@ -76,7 +73,7 @@ "Activate Mouse Avoidance mode. See function `mouse-avoidance-mode' for possible values. Setting this variable directly does not take effect; -use either \\[customize] or the function `mouse-avoidance-mode'." +use either \\[customize] or \\[mouse-avoidance-mode]." :set (lambda (_symbol value) ;; 'none below prevents toggling when value is nil. (mouse-avoidance-mode (or value 'none))) @@ -261,9 +258,9 @@ If you want the mouse banished to a different corner set (t 0)))) (defun mouse-avoidance-nudge-mouse () - ;; Push the mouse a little way away, possibly animating the move. - ;; For these modes, state keeps track of the total offset that we've - ;; accumulated, and tries to keep it close to zero. + "Push the mouse a little way away, possibly animating the move. +For these modes, state keeps track of the total offset that we've +accumulated, and tries to keep it close to zero." (let* ((cur (mouse-position)) (cur-pos (cdr cur)) (pos (window-edges)) @@ -375,7 +372,7 @@ redefine this function to suit your own tastes." (setq mouse-avoidance-state nil)))))) (defun mouse-avoidance-fancy () - ;; Used for the "fancy" modes, ie jump et al. + ;; Used for the "fancy" modes, i.e. jump et al. (if (and (not mouse-avoidance-animating-pointer) (not (mouse-avoidance-ignore-p)) (mouse-avoidance-too-close-p (mouse-position))) commit 4428c27c1ae7d5fe5233e8d7b001a8cd2fcdc56f Author: Lars Ingebrigtsen Date: Mon Feb 8 08:15:45 2021 +0100 Record the value of `C-x C-e' in `values' * lisp/progmodes/elisp-mode.el (eval-last-sexp): Record the value in `values' (bug#22066) since we're messaging it. diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 9348a7f0d2..a096866316 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -1268,7 +1268,9 @@ If `eval-expression-debug-on-error' is non-nil, which is the default, this command arranges for all errors to enter the debugger." (interactive "P") (if (null eval-expression-debug-on-error) - (elisp--eval-last-sexp eval-last-sexp-arg-internal) + (let ((value (elisp--eval-last-sexp eval-last-sexp-arg-internal))) + (push value values) + value) (let ((value (let ((debug-on-error elisp--eval-last-sexp-fake-value)) (cons (elisp--eval-last-sexp eval-last-sexp-arg-internal) commit 9fdc753e1450d1b2eb610ef4fc55460d63688799 Author: Protesilaos Stavrou Date: Mon Feb 8 07:54:54 2021 +0100 Add vc-dir faces; also apply them to vc-git * etc/NEWS: Document the new faces. * lisp/vc/vc-dir.el (vc-dir-header, vc-dir-header-value) (vc-dir-directory, vc-dir-file, vc-dir-mark-indicator) (vc-dir-status-warning, vc-dir-status-edited, vc-dir-status-up-to-date) (vc-dir-ignored): Add new faces. * lisp/vc/vc-git.el (vc-git-permissions-as-string, vc-git-dir-printer) (vc-git-dir-extra-headers): Apply new faces (bug#46358). diff --git a/etc/NEWS b/etc/NEWS index 05a8beb740..40fe215600 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -601,6 +601,12 @@ their 'default-directory' under VC. This is used when expanding commit messages from 'vc-print-root-log' and similar commands. +--- +*** New faces for 'vc-dir' buffers and their Git VC backend. +Those are: 'vc-dir-header', 'vc-dir-header-value', 'vc-dir-directory', +'vc-dir-file', 'vc-dir-mark-indicator', 'vc-dir-status-warning', +'vc-dir-status-edited', 'vc-dir-status-up-to-date', 'vc-dir-ignored'. + --- *** The responsible VC backend is now the most specific one. 'vc-responsible-backend' loops over the backends in diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index 9d0808c043..14c81578b7 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -54,6 +54,42 @@ See `run-hooks'." :type 'hook :group 'vc) +(defface vc-dir-header '((t :inherit font-lock-type-face)) + "Face for headers in VC-dir buffers." + :group 'vc) + +(defface vc-dir-header-value '((t :inherit font-lock-variable-name-face)) + "Face for header values in VC-dir buffers." + :group 'vc) + +(defface vc-dir-directory '((t :inherit font-lock-comment-delimiter-face)) + "Face for directories in VC-dir buffers." + :group 'vc) + +(defface vc-dir-file '((t :inherit font-lock-function-name-face)) + "Face for files in VC-dir buffers." + :group 'vc) + +(defface vc-dir-mark-indicator '((t :inherit font-lock-type-face)) + "Face for mark indicators in VC-dir buffers." + :group 'vc) + +(defface vc-dir-status-warning '((t :inherit font-lock-warning-face)) + "Face for warning status in VC-dir buffers." + :group 'vc) + +(defface vc-dir-status-edited '((t :inherit font-lock-variable-name-face)) + "Face for edited status in VC-dir buffers." + :group 'vc) + +(defface vc-dir-status-up-to-date '((t :inherit font-lock-builtin-face)) + "Face for up-to-date status in VC-dir buffers." + :group 'vc) + +(defface vc-dir-ignored '((t :inherit shadow)) + "Face for ignored or empty values in VC-dir buffers." + :group 'vc) + ;; Used to store information for the files displayed in the directory buffer. ;; Each item displayed corresponds to one of these defstructs. (cl-defstruct (vc-dir-fileinfo @@ -1126,11 +1162,11 @@ It calls the `dir-extra-headers' backend method to display backend specific headers." (concat ;; First layout the common headers. - (propertize "VC backend : " 'face 'font-lock-type-face) - (propertize (format "%s\n" backend) 'face 'font-lock-variable-name-face) - (propertize "Working dir: " 'face 'font-lock-type-face) + (propertize "VC backend : " 'face 'vc-dir-header) + (propertize (format "%s\n" backend) 'face 'vc-dir-header-value) + (propertize "Working dir: " 'face 'vc-dir-header) (propertize (format "%s\n" (abbreviate-file-name dir)) - 'face 'font-lock-variable-name-face) + 'face 'vc-dir-header-value) ;; Then the backend specific ones. (vc-call-backend backend 'dir-extra-headers dir) "\n")) @@ -1386,9 +1422,9 @@ These are the commands available for use in the file status buffer: ;; backend specific headers. ;; XXX: change this to return nil before the release. (concat - (propertize "Extra : " 'face 'font-lock-type-face) + (propertize "Extra : " 'face 'vc-dir-header) (propertize "Please add backend specific headers here. It's easy!" - 'face 'font-lock-warning-face))) + 'face 'vc-dir-status-warning))) (defvar vc-dir-status-mouse-map (let ((map (make-sparse-keymap))) @@ -1414,21 +1450,21 @@ These are the commands available for use in the file status buffer: (insert (propertize (format "%c" (if (vc-dir-fileinfo->marked fileentry) ?* ? )) - 'face 'font-lock-type-face) + 'face 'vc-dir-mark-indicator) " " (propertize (format "%-20s" state) - 'face (cond ((eq state 'up-to-date) 'font-lock-builtin-face) - ((memq state '(missing conflict)) 'font-lock-warning-face) + 'face (cond ((eq state 'up-to-date) 'vc-dir-status-up-to-date) + ((memq state '(missing conflict)) 'vc-dir-status-warning) ((eq state 'edited) 'font-lock-constant-face) - (t 'font-lock-variable-name-face)) + (t 'vc-dir-header-value)) 'mouse-face 'highlight 'keymap vc-dir-status-mouse-map) " " (propertize (format "%s" filename) 'face - (if isdir 'font-lock-comment-delimiter-face 'font-lock-function-name-face) + (if isdir 'vc-dir-directory 'vc-dir-file) 'help-echo (if isdir "Directory\nVC operations can be applied to it\nmouse-3: Pop-up menu" diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index d00c2c2133..e7306386fe 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -462,7 +462,7 @@ or an empty string if none." (eq 0 (logand ?\111 (logxor old-perm new-perm)))) " " (if (eq 0 (logand ?\111 old-perm)) "+x" "-x")) - 'face 'font-lock-type-face)) + 'face 'vc-dir-header)) (defun vc-git-dir-printer (info) "Pretty-printer for the vc-dir-fileinfo structure." @@ -474,20 +474,20 @@ or an empty string if none." (insert " " (propertize (format "%c" (if (vc-dir-fileinfo->marked info) ?* ? )) - 'face 'font-lock-type-face) + 'face 'vc-dir-mark-indicator) " " (propertize (format "%-12s" state) - 'face (cond ((eq state 'up-to-date) 'font-lock-builtin-face) - ((eq state '(missing conflict)) 'font-lock-warning-face) - (t 'font-lock-variable-name-face)) + 'face (cond ((eq state 'up-to-date) 'vc-dir-status-up-to-date) + ((eq state '(missing conflict)) 'vc-dir-status-warning) + (t 'vc-dir-status-edited)) 'mouse-face 'highlight 'keymap vc-dir-status-mouse-map) " " (vc-git-permissions-as-string old-perm new-perm) " " (propertize (vc-git-escape-file-name (vc-dir-fileinfo->name info)) - 'face (if isdir 'font-lock-comment-delimiter-face - 'font-lock-function-name-face) + 'face (if isdir 'vc-dir-directory + 'vc-dir-file) 'help-echo (if isdir "Directory\nVC operations can be applied to it\nmouse-3: Pop-up menu" @@ -784,7 +784,7 @@ or an empty string if none." (mapconcat (lambda (x) (propertize x - 'face 'font-lock-variable-name-face + 'face 'vc-dir-header-value 'mouse-face 'highlight 'vc-git-hideable all-hideable 'help-echo vc-git-stash-list-help @@ -800,7 +800,7 @@ or an empty string if none." (mapconcat (lambda (x) (propertize x - 'face 'font-lock-variable-name-face + 'face 'vc-dir-header-value 'mouse-face 'highlight 'invisible t 'vc-git-hideable t @@ -810,33 +810,32 @@ or an empty string if none." (propertize "\n" 'invisible t 'vc-git-hideable t)))))))) - ;; FIXME: maybe use a different face when nothing is stashed. (concat - (propertize "Branch : " 'face 'font-lock-type-face) + (propertize "Branch : " 'face 'vc-dir-header) (propertize branch - 'face 'font-lock-variable-name-face) + 'face 'vc-dir-header-value) (when remote-url (concat "\n" - (propertize "Remote : " 'face 'font-lock-type-face) + (propertize "Remote : " 'face 'vc-dir-header) (propertize remote-url - 'face 'font-lock-variable-name-face))) + 'face 'vc-dir-header-value))) ;; For now just a heading, key bindings can be added later for various bisect actions (when (file-exists-p (expand-file-name ".git/BISECT_START" (vc-git-root dir))) - (propertize "\nBisect : in progress" 'face 'font-lock-warning-face)) + (propertize "\nBisect : in progress" 'face 'vc-dir-status-warning)) (when (file-exists-p (expand-file-name ".git/rebase-apply" (vc-git-root dir))) - (propertize "\nRebase : in progress" 'face 'font-lock-warning-face)) + (propertize "\nRebase : in progress" 'face 'vc-dir-status-warning)) (if stash-list (concat - (propertize "\nStash : " 'face 'font-lock-type-face) + (propertize "\nStash : " 'face 'vc-dir-header) stash-button stash-string) (concat - (propertize "\nStash : " 'face 'font-lock-type-face) + (propertize "\nStash : " 'face 'vc-dir-header) (propertize "Nothing stashed" 'help-echo vc-git-stash-shared-help 'keymap vc-git-stash-shared-map - 'face 'font-lock-variable-name-face)))))) + 'face 'vc-dir-ignored)))))) (defun vc-git-branches () "Return the existing branches, as a list of strings. commit 657641fb83b927a8da18bccfcf843b0a3b720755 Author: Sean Whitton Date: Mon Feb 8 07:52:16 2021 +0100 Bind clone-buffer to C-x x n * lisp/bindings.el (ctl-x-x-map): Bind clone-buffer. * etc/NEWS: Document the change (bug#46369). diff --git a/etc/NEWS b/etc/NEWS index b3d53bf73c..05a8beb740 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -241,8 +241,9 @@ search buffer due to too many matches being highlighted. ** A new keymap for buffer actions has been added. The 'C-x x' keymap now holds keystrokes for various buffer-oriented commands. The new keystrokes are 'C-x x g' ('revert-buffer'), -'C-x x r' ('rename-buffer'), 'C-x x u' ('rename-uniquely'), -'C-x x i' ('insert-buffer') and 'C-x x t' ('toggle-truncate-lines'). +'C-x x r' ('rename-buffer'), 'C-x x u' ('rename-uniquely'), 'C-x x n' +('clone-buffer'), 'C-x x i' ('insert-buffer') and 'C-x x t' +('toggle-truncate-lines'). * Editing Changes in Emacs 28.1 diff --git a/lisp/bindings.el b/lisp/bindings.el index 9462468b1b..2f4bab11cf 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -1418,6 +1418,7 @@ if `inhibit-field-text-motion' is non-nil." (define-key map "g" #'revert-buffer) (define-key map "r" #'rename-buffer) (define-key map "u" #'rename-uniquely) + (define-key map "n" #'clone-buffer) (define-key map "i" #'insert-buffer) (define-key map "t" #'toggle-truncate-lines) map) commit 798bd1273c5ba85427952e6eee22c8eeda58e85e Author: Anticrisis Date: Mon Feb 8 07:33:49 2021 +0100 Fix tcl-mode indentation of namespaced code * lisp/progmodes/tcl.el (tcl-calculate-indent): Fix indentation when using namespaces (bug#44834). (tcl-beginning-of-defun-function): Remove. This partially reverts cd5bb4bf3dbad8941d25823f398b595b8f0edbb9. Copyright-paperwork-exempt: yes diff --git a/lisp/progmodes/tcl.el b/lisp/progmodes/tcl.el index 0a0118a5eb..82e1343e05 100644 --- a/lisp/progmodes/tcl.el +++ b/lisp/progmodes/tcl.el @@ -651,7 +651,6 @@ already exist." (setq-local add-log-current-defun-function #'tcl-add-log-defun) - (setq-local beginning-of-defun-function #'tcl-beginning-of-defun-function) (setq-local end-of-defun-function #'tcl-end-of-defun-function)) @@ -849,14 +848,12 @@ Returns nil if line starts inside a string, t if in a comment." state containing-sexp found-next-line) - (cond - (parse-start + + (if parse-start (goto-char parse-start)) - ((not (beginning-of-defun)) - ;; If we're not in a function, don't use - ;; `tcl-beginning-of-defun-function'. - (let ((beginning-of-defun-function nil)) - (beginning-of-defun)))) + + (beginning-of-defun) + (while (< (point) indent-point) (setq parse-start (point)) (setq state (parse-partial-sexp (point) indent-point 0)) @@ -1035,22 +1032,6 @@ Returns nil if line starts inside a string, t if in a comment." ;; Interfaces to other packages. ;; -(defun tcl-beginning-of-defun-function (&optional arg) - "`beginning-of-defun-function' for Tcl mode." - (when (or (not arg) (= arg 0)) - (setq arg 1)) - (let* ((search-fn (if (> arg 0) - ;; Positive arg means to search backward. - #'re-search-backward - #'re-search-forward)) - (arg (abs arg)) - (result t)) - (while (and (> arg 0) result) - (unless (funcall search-fn tcl-proc-regexp nil t) - (setq result nil)) - (setq arg (1- arg))) - result)) - (defun tcl-end-of-defun-function () "`end-of-defun-function' for Tcl mode." ;; Because we let users redefine tcl-proc-list, we don't really know diff --git a/test/lisp/progmodes/tcl-tests.el b/test/lisp/progmodes/tcl-tests.el index cf1ed2896e..e55eb6d901 100644 --- a/test/lisp/progmodes/tcl-tests.el +++ b/test/lisp/progmodes/tcl-tests.el @@ -74,7 +74,6 @@ ;; From bug#44834 (ert-deftest tcl-mode-namespace-indent-2 () - :expected-result :failed (with-temp-buffer (tcl-mode) (let ((text "namespace eval Foo {\n proc foo {} {}\n\n proc bar {}{}}\n")) commit 33c9556c9db9b8c62dcd80dd3cc665e669ea66d4 Author: Lars Ingebrigtsen Date: Mon Feb 8 07:30:18 2021 +0100 Clarify "changes" in CONTRIBUTE * CONTRIBUTE: Clarify that "changes" doesn't include removing code (bug#44834). diff --git a/CONTRIBUTE b/CONTRIBUTE index cb09391c32..9b2af9ccf1 100644 --- a/CONTRIBUTE +++ b/CONTRIBUTE @@ -67,7 +67,7 @@ error-prone. It also allows sending patches whose author is someone other than the email sender. Once the cumulative amount of your submissions exceeds about 15 lines -of non-trivial changes, we will need you to assign to the FSF the +of non-trivial code, we will need you to assign to the FSF the copyright for your contributions. Ask on emacs-devel@gnu.org, and we will send you the necessary form together with the instructions to fill and email it, in order to start this legal paperwork. commit f2814b2018f731a9b299422191591e5b1e857827 Author: Lars Ingebrigtsen Date: Mon Feb 8 07:22:02 2021 +0100 Make `C-a' in enriched-mode behave more line in other modes * lisp/textmodes/enriched.el (enriched-mode-map): Don't rebind beginning-or-line, because it makes `C-S-a' not mark the region, and it doesn't allow actually moving to the beginning of the line if the line starts with characters in `adaptive-fill-regexp' (bug#22554). diff --git a/lisp/textmodes/enriched.el b/lisp/textmodes/enriched.el index bac209cdef..fe92d60306 100644 --- a/lisp/textmodes/enriched.el +++ b/lisp/textmodes/enriched.el @@ -186,7 +186,6 @@ The value is a list of \(VAR VALUE VAR VALUE...).") (defvar enriched-mode-map (let ((map (make-sparse-keymap))) - (define-key map [remap move-beginning-of-line] 'beginning-of-line-text) (define-key map "\C-m" 'reindent-then-newline-and-indent) (define-key map [remap newline-and-indent] 'reindent-then-newline-and-indent) commit efb10ffdb75ba61353b3451797e0214ac2f03171 Author: Lars Ingebrigtsen Date: Mon Feb 8 07:11:52 2021 +0100 Fix noninteractive gnus-article-press-button * lisp/gnus/gnus-art.el (gnus-article-press-button): Make the `b' summary mode command work again. diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index 70ededf1ba..7ded9e40e9 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -7894,7 +7894,8 @@ If the text at point has a `gnus-callback' property, call it with the value of the `gnus-data' text property." (interactive (list last-nonmenu-event)) (save-excursion - (mouse-set-point event) + (when event + (mouse-set-point event)) (let ((fun (get-text-property (point) 'gnus-callback))) (when fun (funcall fun (get-text-property (point) 'gnus-data)))))) commit 7d4d577ed14fb2519ea2eaecb11c8ecff658f147 Author: Stefan Kangas Date: Mon Feb 8 00:25:16 2021 +0100 Prefer setq-local in a few more places * lisp/calc/calc-embed.el (calc-embedded-make-info): * lisp/calc/calcalg2.el (calcFunc-integ): * lisp/comint.el (comint-mode): * lisp/epa.el (epa--list-keys, epa--show-key): * lisp/epg.el (epg--start): * lisp/vc/ediff-util.el (ediff-activate-mark): Prefer setq-local. diff --git a/lisp/calc/calc-embed.el b/lisp/calc/calc-embed.el index cfb3fda106..7455140477 100644 --- a/lisp/calc/calc-embed.el +++ b/lisp/calc/calc-embed.el @@ -854,31 +854,21 @@ The command \\[yank] can retrieve it from there." (newmode (cl-assoc-if #'derived-mode-p calc-embedded-open-close-mode-alist))) (when newann - (make-local-variable 'calc-embedded-announce-formula) - (setq calc-embedded-announce-formula (cdr newann))) + (setq-local calc-embedded-announce-formula (cdr newann))) (when newform - (make-local-variable 'calc-embedded-open-formula) - (make-local-variable 'calc-embedded-close-formula) - (setq calc-embedded-open-formula (nth 0 (cdr newform))) - (setq calc-embedded-close-formula (nth 1 (cdr newform)))) + (setq-local calc-embedded-open-formula (nth 0 (cdr newform))) + (setq-local calc-embedded-close-formula (nth 1 (cdr newform)))) (when newword - (make-local-variable 'calc-embedded-word-regexp) - (setq calc-embedded-word-regexp (nth 1 newword))) + (setq-local calc-embedded-word-regexp (nth 1 newword))) (when newplain - (make-local-variable 'calc-embedded-open-plain) - (make-local-variable 'calc-embedded-close-plain) - (setq calc-embedded-open-plain (nth 0 (cdr newplain))) - (setq calc-embedded-close-plain (nth 1 (cdr newplain)))) + (setq-local calc-embedded-open-plain (nth 0 (cdr newplain))) + (setq-local calc-embedded-close-plain (nth 1 (cdr newplain)))) (when newnewform - (make-local-variable 'calc-embedded-open-new-formula) - (make-local-variable 'calc-embedded-close-new-formula) - (setq calc-embedded-open-new-formula (nth 0 (cdr newnewform))) - (setq calc-embedded-close-new-formula (nth 1 (cdr newnewform)))) + (setq-local calc-embedded-open-new-formula (nth 0 (cdr newnewform))) + (setq-local calc-embedded-close-new-formula (nth 1 (cdr newnewform)))) (when newmode - (make-local-variable 'calc-embedded-open-mode) - (make-local-variable 'calc-embedded-close-mode) - (setq calc-embedded-open-mode (nth 0 (cdr newmode))) - (setq calc-embedded-close-mode (nth 1 (cdr newmode))))))) + (setq-local calc-embedded-open-mode (nth 0 (cdr newmode))) + (setq-local calc-embedded-close-mode (nth 1 (cdr newmode))))))) (while (and (cdr found) (> point (aref (car (cdr found)) 3))) (setq found (cdr found))) diff --git a/lisp/calc/calcalg2.el b/lisp/calc/calcalg2.el index fc6eb74e9f..94b99aa29d 100644 --- a/lisp/calc/calcalg2.el +++ b/lisp/calc/calcalg2.el @@ -1545,9 +1545,7 @@ (set-buffer trace-buffer) (goto-char (point-max)) (or (assq 'scroll-stop (buffer-local-variables)) - (progn - (make-local-variable 'scroll-step) - (setq scroll-step 3))) + (setq-local scroll-step 3)) (insert "\n\n\n") (set-buffer calcbuf) (math-try-integral sexpr)) diff --git a/lisp/comint.el b/lisp/comint.el index a9633d08ba..57df6bfb19 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -700,8 +700,7 @@ Entry to this mode runs the hooks on `comint-mode-hook'." ;; https://lists.gnu.org/r/emacs-devel/2007-08/msg00827.html ;; ;; This makes it really work to keep point at the bottom. - ;; (make-local-variable 'scroll-conservatively) - ;; (setq scroll-conservatively 10000) + ;; (setq-local scroll-conservatively 10000) (add-hook 'pre-command-hook 'comint-preinput-scroll-to-bottom t t) (make-local-variable 'comint-ptyp) (make-local-variable 'comint-process-echoes) diff --git a/lisp/epa.el b/lisp/epa.el index 197cd92f97..572c947e4b 100644 --- a/lisp/epa.el +++ b/lisp/epa.el @@ -379,8 +379,7 @@ DOC is documentation text to insert at the start." (goto-char point)) (epa--insert-keys (epg-list-keys context name secret))) - (make-local-variable 'epa-list-keys-arguments) - (setq epa-list-keys-arguments (list name secret)) + (setq-local epa-list-keys-arguments (list name secret)) (goto-char (point-min)) (pop-to-buffer (current-buffer))) @@ -500,8 +499,7 @@ If SECRET is non-nil, list secret keys instead of public keys." (format "*Key*%s" (epg-sub-key-id primary-sub-key))))) (set-buffer (cdr entry)) (epa-key-mode) - (make-local-variable 'epa-key) - (setq epa-key key) + (setq-local epa-key key) (erase-buffer) (setq pointer (epg-key-user-id-list key)) (while pointer diff --git a/lisp/epg.el b/lisp/epg.el index 36794d09a7..36515ef4e5 100644 --- a/lisp/epg.el +++ b/lisp/epg.el @@ -641,22 +641,14 @@ callback data (if any)." (with-current-buffer buffer (if (fboundp 'set-buffer-multibyte) (set-buffer-multibyte nil)) - (make-local-variable 'epg-last-status) - (setq epg-last-status nil) - (make-local-variable 'epg-read-point) - (setq epg-read-point (point-min)) - (make-local-variable 'epg-process-filter-running) - (setq epg-process-filter-running nil) - (make-local-variable 'epg-pending-status-list) - (setq epg-pending-status-list nil) - (make-local-variable 'epg-key-id) - (setq epg-key-id nil) - (make-local-variable 'epg-context) - (setq epg-context context) - (make-local-variable 'epg-agent-file) - (setq epg-agent-file agent-file) - (make-local-variable 'epg-agent-mtime) - (setq epg-agent-mtime agent-mtime)) + (setq-local epg-last-status nil) + (setq-local epg-read-point (point-min)) + (setq-local epg-process-filter-running nil) + (setq-local epg-pending-status-list nil) + (setq-local epg-key-id nil) + (setq-local epg-context context) + (setq-local epg-agent-file agent-file) + (setq-local epg-agent-mtime agent-mtime)) (setq error-process (make-pipe-process :name "epg-error" :buffer (generate-new-buffer " *epg-error*") diff --git a/lisp/vc/ediff-util.el b/lisp/vc/ediff-util.el index f955ba8283..9909dcd542 100644 --- a/lisp/vc/ediff-util.el +++ b/lisp/vc/ediff-util.el @@ -3998,8 +3998,8 @@ Mail anyway? (y or n) ") (define-obsolete-function-alias 'ediff-deactivate-mark #'deactivate-mark "27.1") (defun ediff-activate-mark () - (make-local-variable 'transient-mark-mode) - (setq mark-active 'ediff-util transient-mark-mode t)) + (setq mark-active 'ediff-util) + (setq-local transient-mark-mode t)) (define-obsolete-function-alias 'ediff-nuke-selective-display #'ignore "27.1") commit 651aefa31246a786891e2e743800dbf753223928 Author: Stefan Kangas Date: Mon Feb 8 00:24:11 2021 +0100 Add tests for count-lines * test/lisp/simple-tests.el (simple-test-count-lines) (simple-test-count-lines/ignore-invisible-lines): Add tests. diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el index 7b022811a5..b4007a6c3f 100644 --- a/test/lisp/simple-tests.el +++ b/test/lisp/simple-tests.el @@ -47,6 +47,26 @@ (dotimes (_i 10) (insert (propertize "test " 'field (cons nil nil)))) (should (= (count-words (point-min) (point-max)) 10)))) + +;;; `count-lines' + +(ert-deftest simple-test-count-lines () + (with-temp-buffer + (should (= (count-lines (point-min) (point-max)) 0)) + (insert "foo") + (should (= (count-lines (point-min) (point-max)) 1)) + (insert "\nbar\nbaz\n") + (should (= (count-lines (point-min) (point-max)) 3)) + (insert "r\n") + (should (= (count-lines (point-min) (point-max)) 4)))) + +(ert-deftest simple-test-count-lines/ignore-invisible-lines () + (with-temp-buffer + (insert "foo\nbar") + (should (= (count-lines (point-min) (point-max) t) 2)) + (insert (propertize "\nbar\nbaz\nzut" 'invisible t)) + (should (= (count-lines (point-min) (point-max) t) 2)))) + ;;; `transpose-sexps' (defmacro simple-test--transpositions (&rest body) commit fa735ebc0cd4fbb96ae05b494f7728f5707a8536 Author: Eric Abrahamsen Date: Sun Feb 7 13:46:50 2021 -0800 Fix namazu search result parsing in gnus-search * lisp/gnus/gnus-search.el (gnus-search-indexed-extract): This method is documented to leave point at the end of the extracted search result. The namazu implementation wasn't doing that. diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el index 0783d34733..21602f825c 100644 --- a/lisp/gnus/gnus-search.el +++ b/lisp/gnus/gnus-search.el @@ -1514,6 +1514,7 @@ Namazu provides a little more information, for instance a score." (when (re-search-forward "^\\([0-9,]+\\.\\).*\\((score: \\([0-9]+\\)\\))\n\\([^ ]+\\)" nil t) + (forward-line 1) (list (match-string 4) (match-string 3)))) commit 4712c75ab853ee77587dbc1910cc7c0401e02aa0 Author: Lars Ingebrigtsen Date: Sun Feb 7 22:01:34 2021 +0100 Clarify when activate-mark-hook is run * doc/lispref/markers.texi (The Mark): * lisp/simple.el (activate-mark-hook): Clarify when the hook is run (bug#23444). diff --git a/doc/lispref/markers.texi b/doc/lispref/markers.texi index cdd0938b45..93f98190fa 100644 --- a/doc/lispref/markers.texi +++ b/doc/lispref/markers.texi @@ -607,8 +607,8 @@ the function @code{use-region-p} for that (@pxref{The Region}). @defvarx deactivate-mark-hook These normal hooks are run, respectively, when the mark becomes active and when it becomes inactive. The hook @code{activate-mark-hook} is -also run at the end of the command loop if the mark is active and it -is possible that the region may have changed. +also run when the region is reactivated, for instance after using a +command that switches back to a buffer that has an active mark. @ignore This piece of command_loop_1, run unless deactivating the mark: if (current_buffer != prev_buffer || MODIFF != prev_modiff) diff --git a/lisp/simple.el b/lisp/simple.el index 10cde4e4b8..28738a262d 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -5536,8 +5536,9 @@ START and END specify the portion of the current buffer to be copied." (defvar activate-mark-hook nil "Hook run when the mark becomes active. -It is also run at the end of a command, if the mark is active and -it is possible that the region may have changed.") +It is also run when the region is reactivated, for instance after +using a command that switches back to a buffer that has an active +mark.") (defvar deactivate-mark-hook nil "Hook run when the mark becomes inactive.") commit 5a1222196b5a9c3b8afe5c24cd16649a796fa11a Author: Michael Albinus Date: Sun Feb 7 19:38:49 2021 +0100 ; Rearrange changed entry in etc/NEWS diff --git a/etc/NEWS b/etc/NEWS index f65e3cf672..b3d53bf73c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -85,12 +85,12 @@ useful on systems such as FreeBSD which ships only with "etc/termcap". * Changes in Emacs 28.1 +** The new NonGNU ELPA archive is enabled by default alongside GNU ELPA. + +++ ** New command 'recenter-other-window', bound to 'S-M-C-l'. Like 'recenter-top-bottom' acting in the other window. -** The new NonGNU ELPA archive is enabled by default alongside GNU ELPA - ** Minibuffer scrolling is now conservative by default. This is controlled by the new variable 'scroll-minibuffer-conservatively'. commit 7c5938ad7d8884d03471e2395937e11611faadb9 Author: Lars Ingebrigtsen Date: Sun Feb 7 17:29:57 2021 +0100 Use `line-number-at-pos' in `count-lines' * lisp/simple.el (count-lines): Use `line-number-at-pos', which should be faster. diff --git a/lisp/simple.el b/lisp/simple.el index 60c13166e7..568debaa61 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1453,9 +1453,9 @@ included in the count." (save-excursion (save-restriction (narrow-to-region start end) - (goto-char (point-min)) (cond ((and (not ignore-invisible-lines) (eq selective-display t)) + (goto-char (point-min)) (save-match-data (let ((done 0)) (while (re-search-forward "\n\\|\r[^\n]" nil t 40) @@ -1468,6 +1468,7 @@ included in the count." (1+ done) done)))) (ignore-invisible-lines + (goto-char (point-min)) (save-match-data (- (buffer-size) (forward-line (buffer-size)) @@ -1482,7 +1483,11 @@ included in the count." (assq prop buffer-invisibility-spec))) (setq invisible-count (1+ invisible-count)))) invisible-count)))) - (t (- (buffer-size) (forward-line (buffer-size)))))))) + (t + (goto-char (point-max)) + (if (bolp) + (1- (line-number-at-pos)) + (line-number-at-pos))))))) (defcustom what-cursor-show-names nil "Whether to show character names in `what-cursor-position'." commit abedf3a8653829f5170ff72b2fc7adad0e6f80d4 Author: Eli Zaretskii Date: Sun Feb 7 17:52:30 2021 +0200 Fix language-environment and font selection on MS-Windows These changes improve setting the language-environment and font selection when MS-Windows returns useless "ZZZ" as the "language name", which then disrupts all the setup of the locale-dependent stuff, and in particular font selection. * lisp/w32-fns.el (w32-charset-info-alist): Add an element for "iso8859-5", in case LANG is set to something unusable, like "ZZZ". This allows fonts capable of displaying Cyrillic characters to be used even when language preferences are screwed. * src/w32.c (init_environment): If GetLocaleInfo returns "ZZZ" as the "language name" for LOCALE_USER_DEFAULT, try again with locale ID based on what GetUserDefaultUILanguage returns. (Bug#39286) diff --git a/lisp/w32-fns.el b/lisp/w32-fns.el index eb12dcd896..687afc828d 100644 --- a/lisp/w32-fns.el +++ b/lisp/w32-fns.el @@ -252,6 +252,7 @@ bit output with no translation." (w32-add-charset-info "iso8859-2" 'w32-charset-easteurope 28592) (w32-add-charset-info "iso8859-3" 'w32-charset-turkish 28593) (w32-add-charset-info "iso8859-4" 'w32-charset-baltic 28594) + (w32-add-charset-info "iso8859-5" 'w32-charset-russian 28595) (w32-add-charset-info "iso8859-6" 'w32-charset-arabic 28596) (w32-add-charset-info "iso8859-7" 'w32-charset-greek 28597) (w32-add-charset-info "iso8859-8" 'w32-charset-hebrew 1255) diff --git a/src/w32.c b/src/w32.c index e6dffe2e63..d4f3192442 100644 --- a/src/w32.c +++ b/src/w32.c @@ -346,6 +346,7 @@ static BOOL g_b_init_get_adapters_addresses; static BOOL g_b_init_reg_open_key_ex_w; static BOOL g_b_init_reg_query_value_ex_w; static BOOL g_b_init_expand_environment_strings_w; +static BOOL g_b_init_get_user_default_ui_language; BOOL g_b_init_compare_string_w; BOOL g_b_init_debug_break_process; @@ -533,6 +534,7 @@ DWORD multiByteToWideCharFlags; typedef LONG (WINAPI *RegOpenKeyExW_Proc) (HKEY,LPCWSTR,DWORD,REGSAM,PHKEY); typedef LONG (WINAPI *RegQueryValueExW_Proc) (HKEY,LPCWSTR,LPDWORD,LPDWORD,LPBYTE,LPDWORD); typedef DWORD (WINAPI *ExpandEnvironmentStringsW_Proc) (LPCWSTR,LPWSTR,DWORD); +typedef LANGID (WINAPI *GetUserDefaultUILanguage_Proc) (void); /* ** A utility function ** */ static BOOL @@ -1489,6 +1491,28 @@ expand_environment_strings_w (LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize) return s_pfn_Expand_Environment_Strings_w (lpSrc, lpDst, nSize); } +static LANGID WINAPI +get_user_default_ui_language (void) +{ + static GetUserDefaultUILanguage_Proc s_pfn_GetUserDefaultUILanguage = NULL; + HMODULE hm_kernel32 = NULL; + + if (is_windows_9x () == TRUE) + return 0; + + if (g_b_init_get_user_default_ui_language == 0) + { + g_b_init_get_user_default_ui_language = 1; + hm_kernel32 = LoadLibrary ("Kernel32.dll"); + if (hm_kernel32) + s_pfn_GetUserDefaultUILanguage = (GetUserDefaultUILanguage_Proc) + get_proc_addr (hm_kernel32, "GetUserDefaultUILanguage"); + } + if (s_pfn_GetUserDefaultUILanguage == NULL) + return 0; + return s_pfn_GetUserDefaultUILanguage (); +} + /* Return 1 if P is a valid pointer to an object of size SIZE. Return @@ -2927,6 +2951,32 @@ init_environment (char ** argv) LOCALE_SABBREVLANGNAME | LOCALE_USE_CP_ACP, locale_name, sizeof (locale_name))) { + /* Microsoft are migrating away of locale IDs, replacing them + with locale names, such as "en-US", and are therefore + deprecating the APIs which use LCID etc. As part of that + deprecation, they don't bother inventing LCID and LANGID + codes for new locales and language/culture combinations; + instead, those get LCID of 0xC000 and LANGID of 0x2000, for + which the LCID/LANGID oriented APIs return "ZZZ" as the + "language name". Such "language name" is useless for our + purposes. So we instead use the default UI language, in the + hope of getting something usable. */ + if (strcmp (locale_name, "ZZZ") == 0) + { + LANGID lang_id = get_user_default_ui_language (); + + if (lang_id != 0) + { + /* Disregard the sorting order differences between cultures. */ + LCID def_lcid = MAKELCID (lang_id, SORT_DEFAULT); + char locale_name_def[32]; + + if (GetLocaleInfo (def_lcid, + LOCALE_SABBREVLANGNAME | LOCALE_USE_CP_ACP, + locale_name_def, sizeof (locale_name_def))) + strcpy (locale_name, locale_name_def); + } + } for (i = 0; i < N_ENV_VARS; i++) { if (strcmp (env_vars[i].name, "LANG") == 0) @@ -10451,6 +10501,7 @@ globals_of_w32 (void) g_b_init_expand_environment_strings_w = 0; g_b_init_compare_string_w = 0; g_b_init_debug_break_process = 0; + g_b_init_get_user_default_ui_language = 0; num_of_processors = 0; /* The following sets a handler for shutdown notifications for console apps. This actually applies to Emacs in both console and commit 9380a7ed906e667df4fc5b9d9c8e487fafa7c654 Author: Tino Calancha Date: Sun Feb 7 16:51:07 2021 +0100 Add command to recenter errors from Occur/Grep buffers To scroll up/down the current displayed occurrence/error without abandon the Occur/Grep buffer. Add also a command 'recenter-other-window' to recenter the other window from any kind of buffer. * lisp/window.el (recenter-other-window): New command. Bind recenter-other-window to S-M-C-l (Bug#46119). * lisp/simple.el (recenter-current-error): New command. * lisp/progmodes/grep.el (grep-mode-map): Delete bidings for n and p. * lisp/progmodes/compile.el (compilation-minor-mode-map): Move here the n and p bindings. Bind `recenter-current-error' to l. * lisp/replace.el (occur-mode-map): Same. * doc/emacs/windows.texi (Other Window): * doc/emacs/display.texi (Recentering): Document recenter-other-window. * etc/NEWS (Changes in Specialized Modes and Packages in Emacs 28.1): Announce the changes. diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi index 2781328cb7..58d08b43c0 100644 --- a/doc/emacs/display.texi +++ b/doc/emacs/display.texi @@ -173,6 +173,10 @@ line; on subsequent consecutive invocations, make the current line the top line, the bottom line, and so on in cyclic order. Possibly redisplay the screen too (@code{recenter-top-bottom}). +@item C-M-S-l +Scroll the other window; this is equivalent to @kbd{C-l} acting on the +other window. + @item M-x recenter Scroll the selected window so the current line is the center-most text line. Possibly redisplay the screen too. diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi index e851f1b1b5..c66deb7748 100644 --- a/doc/emacs/windows.texi +++ b/doc/emacs/windows.texi @@ -161,6 +161,8 @@ Select another window (@code{other-window}). Scroll the next window upward (@code{scroll-other-window}). @item C-M-S-v Scroll the next window downward (@code{scroll-other-window-down}). +@item C-M-S-l +Recenter the next window (@code{recenter-other-window}). @item mouse-1 @kbd{mouse-1}, in the text area of a window, selects the window and moves point to the position clicked. Clicking in the mode line @@ -194,6 +196,8 @@ rebind a command.) @findex scroll-other-window @kindex C-M-S-v @findex scroll-other-window-down +@kindex C-M-S-l +@findex recenter-other-window The usual scrolling commands (@pxref{Display}) apply to the selected window only, but there are also commands to scroll the next window. @kbd{C-M-v} (@code{scroll-other-window}) scrolls the window that @@ -203,7 +207,9 @@ take positive and negative arguments. (In the minibuffer, @kbd{C-M-v} scrolls the help window associated with the minibuffer, if any, rather than the next window in the standard cyclic order; @pxref{Minibuffer Edit}.) @kbd{C-M-S-v} (@code{scroll-other-window-down}) scrolls the -next window downward in a similar way. +next window downward in a similar way. Likewise, @kbd{C-M-S-l} +(@code{recenter-other-window}) behaves like @kbd{C-l} +(@code{recenter-top-bottom}) in the next window. @vindex mouse-autoselect-window If you set @code{mouse-autoselect-window} to a non-@code{nil} value, diff --git a/etc/NEWS b/etc/NEWS index 0faed3e5aa..f65e3cf672 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -85,7 +85,11 @@ useful on systems such as FreeBSD which ships only with "etc/termcap". * Changes in Emacs 28.1 -** The new NonGNU ELPA archive is enabled by default alongside GNU ELPA. ++++ +** New command 'recenter-other-window', bound to 'S-M-C-l'. +Like 'recenter-top-bottom' acting in the other window. + +** The new NonGNU ELPA archive is enabled by default alongside GNU ELPA ** Minibuffer scrolling is now conservative by default. This is controlled by the new variable 'scroll-minibuffer-conservatively'. @@ -469,9 +473,14 @@ applied when the option 'tab-line-tab-face-functions' is so-configured. That option may also be used to customize tab-line faces in other ways. -** New bindings in occur-mode, 'next-error-no-select' bound to 'n' and +** Occur mode + +*** New bindings in occur-mode, 'next-error-no-select' bound to 'n' and 'previous-error-no-select' bound to 'p'. +*** The new command 'recenter-current-error', bound to 'l' in Occur or +compilation buffers, recenters the current displayed occurrence/error. + ** EIEIO +++ diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index 614ed7d835..48b5ee9973 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -2069,6 +2069,10 @@ Returns the compilation buffer created." (define-key map "\M-p" 'compilation-previous-error) (define-key map "\M-{" 'compilation-previous-file) (define-key map "\M-}" 'compilation-next-file) + (define-key map "n" 'next-error-no-select) + (define-key map "p" 'previous-error-no-select) + (define-key map "l" 'recenter-current-error) + (define-key map "g" 'recompile) ; revert ;; Set up the menu-bar (define-key map [menu-bar compilation] diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el index 1a8435fde3..d6ee8bb423 100644 --- a/lisp/progmodes/grep.el +++ b/lisp/progmodes/grep.el @@ -275,8 +275,6 @@ See `compilation-error-screen-columns'." (define-key map "\C-c\C-f" 'next-error-follow-minor-mode) (define-key map "\r" 'compile-goto-error) ;; ? - (define-key map "n" 'next-error-no-select) - (define-key map "p" 'previous-error-no-select) (define-key map "{" 'compilation-previous-file) (define-key map "}" 'compilation-next-file) (define-key map "\t" 'compilation-next-error) diff --git a/lisp/replace.el b/lisp/replace.el index d320542d62..eb7a439b54 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -1161,6 +1161,7 @@ a previously found match." (define-key map "\C-o" 'occur-mode-display-occurrence) (define-key map "n" 'next-error-no-select) (define-key map "p" 'previous-error-no-select) + (define-key map "l" 'recenter-current-error) (define-key map "\M-n" 'occur-next) (define-key map "\M-p" 'occur-prev) (define-key map "r" 'occur-rename-buffer) diff --git a/lisp/simple.el b/lisp/simple.el index 73e3fb9f84..60c13166e7 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -492,6 +492,16 @@ buffer causes automatic display of the corresponding source code location." (overlay-put ol 'window (get-buffer-window)) (setf next-error--message-highlight-overlay ol))))) +(defun recenter-current-error (&optional arg) + "Recenter the current displayed error in the `next-error' buffer." + (interactive "P") + (save-selected-window + (let ((next-error-highlight next-error-highlight-no-select) + (display-buffer-overriding-action + '(nil (inhibit-same-window . t)))) + (next-error 0) + (set-buffer (window-buffer)) + (recenter-top-bottom arg)))) ;;; diff --git a/lisp/window.el b/lisp/window.el index 92ed6ee092..2d0a73b426 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -9768,6 +9768,19 @@ With plain \\[universal-argument], move current line to window center." (define-key global-map [?\C-l] 'recenter-top-bottom) +(defun recenter-other-window (&optional arg) + "Call `recenter-top-bottom' in the other window. + +A prefix argument is handled like `recenter': + With numeric prefix ARG, move current line to window-line ARG. + With plain `C-u', move current line to window center." + (interactive "P") + (with-selected-window (other-window-for-scrolling) + (recenter-top-bottom arg) + (pulse-momentary-highlight-one-line (point)))) + +(define-key global-map [?\S-\M-\C-l] 'recenter-other-window) + (defun move-to-window-line-top-bottom (&optional arg) "Position point relative to window. commit 5461808c40ea5baeade203c0a4cc8200855eb00c Author: Lars Ingebrigtsen Date: Sun Feb 7 16:42:25 2021 +0100 Allow Fline_number_at_pos being called with a marker * src/fns.c (Fline_number_at_pos): Also allow being called with a marker (since the Lisp function allowed that). diff --git a/src/fns.c b/src/fns.c index d27f63222c..02743c62a5 100644 --- a/src/fns.c +++ b/src/fns.c @@ -5771,7 +5771,9 @@ from the absolute start of the buffer. */) { ptrdiff_t pos, start = BEGV; - if (NILP (position)) + if (MARKERP (position)) + pos = marker_position (position); + else if (NILP (position)) pos = PT; else { commit 56e76f0eb00d92b49ddd5757d0a68d09dc522d39 Author: Lars Ingebrigtsen Date: Sun Feb 7 16:28:30 2021 +0100 Move line-number-at-pos to C * doc/lispref/positions.texi (Text Lines): Revert previous change. * lisp/simple.el (line-number-at-pos): Remove definition. * lisp/simple.el (count-lines): Revert back to using `forward-line', because there seems to be a disagreement on how lines should be counted in a region... * src/fns.c (Fline_number_at_pos): Rename from Fline_number_at_position and adjust parameter list. diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index 9adce21bae..dc0c7442d8 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi @@ -437,18 +437,16 @@ prints a message reporting the number of lines, words, and characters in the buffer, or in the region if the region is active. @end deffn -@defun line-number-at-position pos -This function returns the line number in the current buffer -corresponding to the buffer position @var{pos}. If narrowing is in -effect, this is the line number in the visible part of the buffer. -@end defun - @defun line-number-at-pos &optional pos absolute @cindex line number -This function is like @code{line-number-at-position}, but if @var{pos} -is @code{nil} or omitted, the current buffer position is used. In -addition, if @var{absolute} is non-@code{nil}, ignore any narrowing -and return the absolute line number. +This function returns the line number in the current buffer +corresponding to the buffer position @var{pos}. If @var{pos} is +@code{nil} or omitted, the current buffer position is used. If +@var{absolute} is @code{nil}, the default, counting starts at +@code{(point-min)}, so the value refers to the contents of the +accessible portion of the (potentially narrowed) buffer. If +@var{absolute} is non-@code{nil}, ignore any narrowing and return +the absolute line number. @end defun @ignore diff --git a/etc/NEWS b/etc/NEWS index 93a60bf14c..0faed3e5aa 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2192,10 +2192,6 @@ back in Emacs 23.1. The affected functions are: 'make-obsolete', * Lisp Changes in Emacs 28.1 -+++ -** New function 'line-number-at-position'. -This returns the line number in the visible portion of the buffer. - --- ** New variable 'indent-line-ignored-functions'. This allows modes to cycle through a set of indentation functions diff --git a/lisp/simple.el b/lisp/simple.el index eab2ac2569..73e3fb9f84 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1472,22 +1472,7 @@ included in the count." (assq prop buffer-invisibility-spec))) (setq invisible-count (1+ invisible-count)))) invisible-count)))) - (t (1- (line-number-at-position (point-max)))))))) - -(defun line-number-at-pos (&optional pos absolute) - "Return buffer line number at position POS. -If POS is nil, use current buffer location. - -If ABSOLUTE is nil, the default, counting starts -at (point-min), so the value refers to the contents of the -accessible portion of the (potentially narrowed) buffer. If -ABSOLUTE is non-nil, ignore any narrowing and return the -absolute line number." - (if absolute - (save-restriction - (widen) - (line-number-at-position (or pos (point)))) - (line-number-at-position (or pos (point))))) + (t (- (buffer-size) (forward-line (buffer-size)))))))) (defcustom what-cursor-show-names nil "Whether to show character names in `what-cursor-position'." diff --git a/src/fns.c b/src/fns.c index 479a5975ce..d27f63222c 100644 --- a/src/fns.c +++ b/src/fns.c @@ -5759,21 +5759,34 @@ in OBJECT. */) return CDR (collector); } -DEFUN ("line-number-at-position", Fline_number_at_position, - Sline_number_at_position, 1, 1, 0, +DEFUN ("line-number-at-pos", Fline_number_at_pos, + Sline_number_at_pos, 0, 2, 0, doc: /* Return the line number at POSITION. +If POSITION is nil, use the current buffer location. + If the buffer is narrowed, the position returned is the position in the -visible part of the buffer. */) - (register Lisp_Object position) +visible part of the buffer. If ABSOLUTE is non-nil, count the lines +from the absolute start of the buffer. */) + (register Lisp_Object position, Lisp_Object absolute) { - CHECK_FIXNUM (position); - ptrdiff_t pos = XFIXNUM (position); + ptrdiff_t pos, start = BEGV; + + if (NILP (position)) + pos = PT; + else + { + CHECK_FIXNUM (position); + pos = XFIXNUM (position); + } + + if (!NILP (absolute)) + start = BEG_BYTE; /* Check that POSITION is n the visible range of the buffer. */ if (pos < BEGV || pos > ZV) - args_out_of_range (make_int (BEGV), make_int (ZV)); + args_out_of_range (make_int (start), make_int (ZV)); - return make_int (count_lines (BEGV_BYTE, CHAR_TO_BYTE (pos)) + 1); + return make_int (count_lines (start, CHAR_TO_BYTE (pos)) + 1); } @@ -5817,7 +5830,7 @@ syms_of_fns (void) defsubr (&Sdefine_hash_table_test); defsubr (&Sstring_search); defsubr (&Sobject_intervals); - defsubr (&Sline_number_at_position); + defsubr (&Sline_number_at_pos); /* Crypto and hashing stuff. */ DEFSYM (Qiv_auto, "iv-auto"); diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el index 3a43142106..928fb15f10 100644 --- a/test/src/fns-tests.el +++ b/test/src/fns-tests.el @@ -1102,7 +1102,7 @@ (ert-deftest test-line-number-at-position () (with-temp-buffer (insert (make-string 10 ?\n)) - (should (= (line-number-at-position (point)) 11)) - (should-error (line-number-at-position nil)) - (should-error (line-number-at-position -1)) - (should-error (line-number-at-position 100)))) + (should (= (line-number-at-pos (point)) 11)) + (should (= (line-number-at-pos nil) 11)) + (should-error (line-number-at-pos -1)) + (should-error (line-number-at-pos 100)))) commit 5a4d50dfb136080fa2353461ee888d552da44a29 Author: Stefan Kangas Date: Sun Feb 7 16:06:06 2021 +0100 Minor doc fixes in dictionary-connection.el * lisp/net/dictionary-connection.el: (dictionary-connection-p, dictionary-connection-read-to-point): Minor doc fixes to adhere to our conventions. diff --git a/lisp/net/dictionary-connection.el b/lisp/net/dictionary-connection.el index 2404a36171..8ad4fe4e63 100644 --- a/lisp/net/dictionary-connection.el +++ b/lisp/net/dictionary-connection.el @@ -23,14 +23,14 @@ ;;; Commentary: ;; dictionary-connection allows to handle TCP-based connections in -;; client mode where text-based information are exchanged. There is +;; client mode where text-based information are exchanged. There is ;; special support for handling CR LF (and the usual CR LF . CR LF ;; terminater). ;;; Code: (defsubst dictionary-connection-p (connection) - "Returns non-nil if CONNECTION is a connection object." + "Return non-nil if CONNECTION is a connection object." (get connection 'connection)) (defsubst dictionary-connection-read-point (connection) @@ -149,8 +149,7 @@ nil: argument is no connection object (defun dictionary-connection-read-to-point (connection) "Read from CONNECTION until an end of entry is encountered. -End of entry is a decimal point found on a line by itself. -" +End of entry is a decimal point found on a line by itself." (dictionary-connection-read connection "\015?\012[.]\015?\012")) (provide 'dictionary-connection) commit e027842f4fb57afbcd117409be12de916b0a1878 Author: Stefan Kangas Date: Sun Feb 7 16:02:30 2021 +0100 Fix copyright and license statement in dictionary*.el * lisp/net/dictionary-connection.el: * lisp/net/dictionary.el: Add copyright statement and fix license statement. diff --git a/lisp/net/dictionary-connection.el b/lisp/net/dictionary-connection.el index d88c0b48f9..2404a36171 100644 --- a/lisp/net/dictionary-connection.el +++ b/lisp/net/dictionary-connection.el @@ -1,22 +1,24 @@ ;;; dictionary-connection.el --- TCP-based client connection for dictionary -*- lexical-binding:t -*- +;; Copyright (C) 2021 Free Software Foundation, Inc. + ;; Author: Torsten Hilbrich ;; Keywords: network -;; This file is free software; you can redistribute it and/or modify +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. -;; This file is distributed in the hope that it will be useful, +;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;; along with GNU Emacs. If not, see . ;;; Commentary: diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el index 7af8cdc59b..ccc24cbf30 100644 --- a/lisp/net/dictionary.el +++ b/lisp/net/dictionary.el @@ -1,22 +1,24 @@ ;;; dictionary.el --- Client for rfc2229 dictionary servers -*- lexical-binding:t -*- +;; Copyright (C) 2021 Free Software Foundation, Inc. + ;; Author: Torsten Hilbrich ;; Keywords: interface, dictionary -;; This file is free software; you can redistribute it and/or modify +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. -;; This file is distributed in the hope that it will be useful, +;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;; along with GNU Emacs. If not, see . ;;; Commentary: commit 094a109b8eefbabbc99dba925ebec9887c101a91 Author: Lars Ingebrigtsen Date: Sun Feb 7 16:02:56 2021 +0100 Add a new function 'line-number-at-position' * doc/lispref/positions.texi (Text Lines): Document it. * lisp/simple.el (count-lines): Use it. (line-number-at-pos): Ditto. * src/fns.c (Fline_number_at_position): New function (bug#22763). diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index dc0c7442d8..9adce21bae 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi @@ -437,16 +437,18 @@ prints a message reporting the number of lines, words, and characters in the buffer, or in the region if the region is active. @end deffn +@defun line-number-at-position pos +This function returns the line number in the current buffer +corresponding to the buffer position @var{pos}. If narrowing is in +effect, this is the line number in the visible part of the buffer. +@end defun + @defun line-number-at-pos &optional pos absolute @cindex line number -This function returns the line number in the current buffer -corresponding to the buffer position @var{pos}. If @var{pos} is -@code{nil} or omitted, the current buffer position is used. If -@var{absolute} is @code{nil}, the default, counting starts at -@code{(point-min)}, so the value refers to the contents of the -accessible portion of the (potentially narrowed) buffer. If -@var{absolute} is non-@code{nil}, ignore any narrowing and return -the absolute line number. +This function is like @code{line-number-at-position}, but if @var{pos} +is @code{nil} or omitted, the current buffer position is used. In +addition, if @var{absolute} is non-@code{nil}, ignore any narrowing +and return the absolute line number. @end defun @ignore diff --git a/etc/NEWS b/etc/NEWS index 0faed3e5aa..93a60bf14c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2192,6 +2192,10 @@ back in Emacs 23.1. The affected functions are: 'make-obsolete', * Lisp Changes in Emacs 28.1 ++++ +** New function 'line-number-at-position'. +This returns the line number in the visible portion of the buffer. + --- ** New variable 'indent-line-ignored-functions'. This allows modes to cycle through a set of indentation functions diff --git a/lisp/simple.el b/lisp/simple.el index e4a363a9a5..eab2ac2569 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1472,7 +1472,7 @@ included in the count." (assq prop buffer-invisibility-spec))) (setq invisible-count (1+ invisible-count)))) invisible-count)))) - (t (- (buffer-size) (forward-line (buffer-size)))))))) + (t (1- (line-number-at-position (point-max)))))))) (defun line-number-at-pos (&optional pos absolute) "Return buffer line number at position POS. @@ -1483,16 +1483,11 @@ at (point-min), so the value refers to the contents of the accessible portion of the (potentially narrowed) buffer. If ABSOLUTE is non-nil, ignore any narrowing and return the absolute line number." - (save-restriction - (when absolute - (widen)) - (let ((opoint (or pos (point))) start) - (save-excursion - (goto-char (point-min)) - (setq start (point)) - (goto-char opoint) - (forward-line 0) - (1+ (count-lines start (point))))))) + (if absolute + (save-restriction + (widen) + (line-number-at-position (or pos (point)))) + (line-number-at-position (or pos (point))))) (defcustom what-cursor-show-names nil "Whether to show character names in `what-cursor-position'." diff --git a/src/fns.c b/src/fns.c index bd4afa0c4e..479a5975ce 100644 --- a/src/fns.c +++ b/src/fns.c @@ -5758,6 +5758,23 @@ in OBJECT. */) traverse_intervals (intervals, 0, collect_interval, collector); return CDR (collector); } + +DEFUN ("line-number-at-position", Fline_number_at_position, + Sline_number_at_position, 1, 1, 0, + doc: /* Return the line number at POSITION. +If the buffer is narrowed, the position returned is the position in the +visible part of the buffer. */) + (register Lisp_Object position) +{ + CHECK_FIXNUM (position); + ptrdiff_t pos = XFIXNUM (position); + + /* Check that POSITION is n the visible range of the buffer. */ + if (pos < BEGV || pos > ZV) + args_out_of_range (make_int (BEGV), make_int (ZV)); + + return make_int (count_lines (BEGV_BYTE, CHAR_TO_BYTE (pos)) + 1); +} void @@ -5800,6 +5817,7 @@ syms_of_fns (void) defsubr (&Sdefine_hash_table_test); defsubr (&Sstring_search); defsubr (&Sobject_intervals); + defsubr (&Sline_number_at_position); /* Crypto and hashing stuff. */ DEFSYM (Qiv_auto, "iv-auto"); diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el index e0aed2a71b..3a43142106 100644 --- a/test/src/fns-tests.el +++ b/test/src/fns-tests.el @@ -1098,3 +1098,11 @@ (goto-char (point-max)) (insert "fóo") (should (approx-equal (buffer-line-statistics) '(1002 50 49.9))))) + +(ert-deftest test-line-number-at-position () + (with-temp-buffer + (insert (make-string 10 ?\n)) + (should (= (line-number-at-position (point)) 11)) + (should-error (line-number-at-position nil)) + (should-error (line-number-at-position -1)) + (should-error (line-number-at-position 100)))) commit 4e8d36fdaadade020f0bcadc70d617d8b07b739c Author: Stefan Kangas Date: Sun Feb 7 15:53:46 2021 +0100 Various doc fixes in dictionary.el * lisp/net/dictionary.el (dictionary-set-server-var) (dictionary-server, dictionary-port) (dictionary-default-dictionary) (dictionary-default-popup-strategy, dictionary-proxy-server) (dictionary-proxy-port, dictionary-description-open-delimiter) (dictionary-description-close-delimiter) (dictionary-window-configuration, dictionary-selected-window) (dictionary-position-stack, dictionary-data-stack) (dictionary-positions, dictionary-current-data) (dictionary-connection, dictionary-instances) (dictionary-color-support, dictionary-word-history) (dictionary-mode, dictionary, dictionary-check-connection) (dictionary-mode-p, dictionary-send-command) (dictionary-read-reply-and-split, dictionary-check-reply) (dictionary-check-initial-reply, dictionary-store-state) (dictionary-store-positions, dictionary-new-search) (dictionary-new-search-internal, dictionary-do-search) (dictionary-display-search-result) (dictionary-display-word-definition) (dictionary-special-dictionary, dictionary-set-strategy) (dictionary-tooltip-dictionary, dictionary-switch-tooltip-mode) (dictionary-tooltip-mode, global-dictionary-tooltip-mode): Doc fixes to adhere to our conventions. diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el index f8733429e9..7af8cdc59b 100644 --- a/lisp/net/dictionary.el +++ b/lisp/net/dictionary.el @@ -46,7 +46,7 @@ (defun dictionary-set-server-var (name value) "Customize helper for setting variable NAME to VALUE. The helper is used by customize to check for an active connection -when setting a variable. The user has then the choice to close +when setting a variable. The user has then the choice to close the existing connection." (if (and (boundp 'dictionary-connection) dictionary-connection @@ -73,8 +73,7 @@ You can specify here: - Automatic: First try localhost, then dict.org after confirmation - localhost: Only use localhost - dict.org: Only use dict.org -- User-defined: You can specify your own server here -" +- User-defined: You can specify your own server here" :group 'dictionary :set 'dictionary-set-server-var :type '(choice (const :tag "Automatic" nil) @@ -86,7 +85,7 @@ You can specify here: (defcustom dictionary-port 2628 "The port of the dictionary server. - This port is propably always 2628 so there should be no need to modify it." +This port is propably always 2628 so there should be no need to modify it." :group 'dictionary :set 'dictionary-set-server-var :type 'number @@ -102,8 +101,8 @@ You can specify here: (defcustom dictionary-default-dictionary "*" "The dictionary which is used for searching definitions and matching. - * and ! have a special meaning, * search all dictionaries, ! search until - one dictionary yields matches." +* and ! have a special meaning, * search all dictionaries, ! search until +one dictionary yields matches." :group 'dictionary :type 'string :version "28.1") @@ -144,8 +143,7 @@ by the choice value: - User choice Here you can enter any matching algorithm supported by your - dictionary server. -" + dictionary server." :group 'dictionary :type '(choice (const :tag "Exact match" "exact") (const :tag "Similiar sounding" "soundex") @@ -177,7 +175,7 @@ by the choice value: (defcustom dictionary-proxy-server "proxy" - "The name of the HTTP proxy to use when dictionary-use-http-proxy is set." + "The name of the HTTP proxy to use when `dictionary-use-http-proxy' is set." :group 'dictionary-proxy :set 'dictionary-set-server-var :type 'string @@ -185,7 +183,7 @@ by the choice value: (defcustom dictionary-proxy-port 3128 - "The port of the proxy server, used only when dictionary-use-http-proxy is set." + "The port of the proxy server, used only when `dictionary-use-http-proxy' is set." :group 'dictionary-proxy :set 'dictionary-set-server-var :type 'number @@ -200,14 +198,14 @@ by the choice value: (defcustom dictionary-description-open-delimiter "" - "The delimiter to display in front of the dictionaries description" + "The delimiter to display in front of the dictionaries description." :group 'dictionary :type 'string :version "28.1") (defcustom dictionary-description-close-delimiter "" - "The delimiter to display after of the dictionaries description" + "The delimiter to display after of the dictionaries description." :group 'dictionary :type 'string :version "28.1") @@ -283,27 +281,27 @@ is utf-8" (defvar dictionary-window-configuration nil - "The window configuration to be restored upon closing the buffer") + "The window configuration to be restored upon closing the buffer.") (defvar dictionary-selected-window nil - "The currently selected window") + "The currently selected window.") (defvar dictionary-position-stack nil - "The history buffer for point and window position") + "The history buffer for point and window position.") (defvar dictionary-data-stack nil - "The history buffer for functions and arguments") + "The history buffer for functions and arguments.") (defvar dictionary-positions nil - "The current positions") + "The current positions.") (defvar dictionary-current-data nil - "The item that will be placed on stack next time") + "The item that will be placed on stack next time.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Global variables @@ -330,11 +328,11 @@ is utf-8" (defvar dictionary-connection nil - "The current network connection") + "The current network connection.") (defvar dictionary-instances 0 - "The number of open dictionary buffers") + "The number of open dictionary buffers.") (defvar dictionary-marker nil @@ -344,11 +342,11 @@ is utf-8" (condition-case nil (x-display-color-p) (error nil)) - "Determines if the Emacs has support to display color") + "Determines if the Emacs has support to display color.") (defvar dictionary-word-history '() - "History list of searched word") + "History list of searched word.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Basic function providing startup actions @@ -356,25 +354,25 @@ is utf-8" ;;;###autoload (defun dictionary-mode () + ;; FIXME: Use define-derived-mode. "Mode for searching a dictionary. This is a mode for searching a dictionary server implementing the protocol defined in RFC 2229. This is a quick reference to this mode describing the default key bindings: +\\ +* \\[dictionary-close] close the dictionary buffer +* \\[dictionary-help] display this help information +* \\[dictionary-search] ask for a new word to search +* \\[dictionary-lookup-definition] search the word at point +* \\[forward-button] or TAB place point to the next link +* \\[backward-button] or S-TAB place point to the prev link -* q close the dictionary buffer -* h display this help information -* s ask for a new word to search -* d search the word at point -* n or Tab place point to the next link -* p or S-Tab place point to the prev link +* \\[dictionary-match-words] ask for a pattern and list all matching words. +* \\[dictionary-select-dictionary] select the default dictionary +* \\[dictionary-select-strategy] select the default search strategy -* m ask for a pattern and list all matching words. -* D select the default dictionary -* M select the default search strategy - -* Return or Button2 visit that link -" +* RET or visit that link" (unless (eq major-mode 'dictionary-mode) (cl-incf dictionary-instances)) @@ -399,7 +397,7 @@ This is a quick reference to this mode describing the default key bindings: ;;;###autoload (defun dictionary () - "Create a new dictonary buffer and install dictionary-mode." + "Create a new dictonary buffer and install `dictionary-mode'." (interactive) (let ((buffer (or (and dictionary-use-single-buffer (get-buffer "*Dictionary*")) @@ -498,13 +496,13 @@ The connection takes the proxy setting in customization group (dictionary-open-server server) (error (if (y-or-n-p - (format "Failed to open server %s, continue with dict.org?" + (format "Failed to open server %s, continue with dict.org? " server)) (dictionary-open-server "dict.org") (error "Failed automatic server selection, please customize dictionary-server")))))))) (defun dictionary-mode-p () - "Return non-nil if current buffer has dictionary-mode." + "Return non-nil if current buffer has `dictionary-mode'." (eq major-mode 'dictionary-mode)) (defun dictionary-ensure-buffer () @@ -535,7 +533,7 @@ The connection takes the proxy setting in customization group ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun dictionary-send-command (string) - "Send the command `string' to the network connection." + "Send the command STRING to the network connection." (dictionary-check-connection) ;;;; ##### (dictionary-connection-send-crlf dictionary-connection string)) @@ -566,7 +564,7 @@ This function knows about the special meaning of quotes (\")" (nreverse list))) (defun dictionary-read-reply-and-split () - "Reads the reply, splits it into words and returns it." + "Read the reply, split it into words and return it." (let ((answer (make-symbol "reply-data")) (reply (dictionary-read-reply))) (let ((reply-list (dictionary-split-string reply))) @@ -589,7 +587,7 @@ The answer is delimited by a decimal point (.) on a line by itself." answer)) (defun dictionary-check-reply (reply code) - "Extract the reply code from REPLY and checks against CODE." + "Extract the reply code from REPLY and check against CODE." (let ((number (dictionary-reply-code reply))) (and (numberp number) (= number code)))) @@ -623,7 +621,7 @@ The answer is delimited by a decimal point (.) on a line by itself." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun dictionary-check-initial-reply () - "Reads the first reply from server and checks it." + "Read the first reply from server and check it." (let ((reply (dictionary-read-reply-and-split))) (unless (dictionary-check-reply reply 220) (dictionary-connection-close dictionary-connection) @@ -631,9 +629,9 @@ The answer is delimited by a decimal point (.) on a line by itself." ;; Store the current state (defun dictionary-store-state (function data) - "Stores the current state of operation for later restore. -The current state consist of a tuple of FUNCTION and DATA. This -is basically an implementation of a history to return to a + "Store the current state of operation for later restore. +The current state consist of a tuple of FUNCTION and DATA. +This is basically an implementation of a history to return to a previous state." (if dictionary-current-data (progn @@ -645,7 +643,7 @@ previous state." (cons function data))) (defun dictionary-store-positions () - "Stores the current positions for later restore." + "Store the current positions for later restore." (setq dictionary-positions (cons (point) (window-start)))) @@ -664,7 +662,7 @@ previous state." ;; The normal search (defun dictionary-new-search (args &optional all) - "Saves the current state and starts a new search based on ARGS. + "Save the current state and start a new search based on ARGS. The parameter ARGS is a cons cell where car is the word to search and cdr is the dictionary where to search the word in." (interactive) @@ -680,15 +678,14 @@ and cdr is the dictionary where to search the word in." (list word dictionary 'dictionary-display-search-result)))) (defun dictionary-new-search-internal (word dictionary function) - "Starts a new search for WORD in DICTIONARY after preparing the buffer. -FUNCTION is the callback which is called for each search result. -" + "Start a new search for WORD in DICTIONARY after preparing the buffer. +FUNCTION is the callback which is called for each search result." (dictionary-pre-buffer) (dictionary-do-search word dictionary function)) (defun dictionary-do-search (word dictionary function &optional nomatching) - "Searches WORD in DICTIONARY and calls FUNCTION for each result. -The parameter NOMATCHING controls whether to suppress the display + "Search for WORD in DICTIONARY and call FUNCTION for each result. +Optional argument NOMATCHING controls whether to suppress the display of matching words." (message "Searching for %s in %s" word dictionary) @@ -712,7 +709,7 @@ of matching words." 'dictionary-display-only-match-result) (dictionary-post-buffer))) (if (dictionary-check-reply reply 550) - (error "Dictionary \"%s\" is unknown, please select an existing one." + (error "Dictionary \"%s\" is unknown, please select an existing one" dictionary) (unless (dictionary-check-reply reply 150) (error "Unknown server answer: %s" (dictionary-reply reply))) @@ -776,7 +773,7 @@ of matching words." (setq buffer-read-only t)) (defun dictionary-display-search-result (reply) - "This function starts displaying the result in REPLY." + "Start displaying the result in REPLY." (let ((number (nth 1 (dictionary-reply-list reply)))) (insert number (if (equal number "1") @@ -810,8 +807,7 @@ The DICTIONARY is only used for decoding the bytes to display the DESCRIPTION." (defun dictionary-display-word-definition (reply word dictionary) "Insert the definition in REPLY for the current WORD from DICTIONARY. It will replace links which are found in the REPLY and replace -them with buttons to perform a a new search. -" +them with buttons to perform a a new search." (let ((start (point))) (insert (dictionary-decode-charset reply dictionary)) (insert "\n\n") @@ -931,7 +927,7 @@ If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." (message "Dictionary %s has been selected" dictionary)))) (defun dictionary-special-dictionary (name) - "Checks whether the special * or ! dictionary are seen in NAME." + "Check whether the special * or ! dictionary are seen in NAME." (or (equal name "*") (equal name "!"))) @@ -1011,7 +1007,7 @@ If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." (insert "\n"))))) (defun dictionary-set-strategy (strategy &rest ignored) - "Select this STRATEGY as new default" + "Select this STRATEGY as new default." (setq dictionary-default-strategy strategy) (dictionary-restore-state) (message "Strategy %s has been selected" strategy)) @@ -1234,7 +1230,7 @@ allows editing it." (defcustom dictionary-tooltip-dictionary nil - "This dictionary to lookup words for tooltips" + "This dictionary to lookup words for tooltips." :group 'dictionary :type '(choice (const :tag "None" nil) string) :version "28.1") @@ -1296,8 +1292,7 @@ It is normally internally called with 1 to enable support for the tooltip mode. The hook function will check the value of the variable dictionary-tooltip-mode to decide if some action must be taken. When disabling the tooltip mode the value of this variable -will be set to nil. -" +will be set to nil." (interactive) (tooltip-mode on) (if on @@ -1309,10 +1304,8 @@ will be set to nil. "Display tooltips for the current word. This function can be used to enable or disable the tooltip mode -for the current buffer (based on ARG). If global-tooltip-mode is -active it will overwrite that mode for the current buffer. -" - +for the current buffer (based on ARG). If global-tooltip-mode is +active it will overwrite that mode for the current buffer." (interactive "P") (require 'tooltip) (let ((on (if arg @@ -1335,8 +1328,7 @@ Internally it provides a default for the dictionary-tooltip-mode. It can be overwritten for each buffer using dictionary-tooltip-mode. Note: (global-dictionary-tooltip-mode 0) will not disable the mode -any buffer where (dictionary-tooltip-mode 1) has been called. -" +any buffer where (dictionary-tooltip-mode 1) has been called." (interactive "P") (require 'tooltip) (let ((on (if arg (> (prefix-numeric-value arg) 0) commit 5ffc55d1e98d04b035c3d8d88d678b74af7a1fd7 Author: Lars Ingebrigtsen Date: Sun Feb 7 15:12:15 2021 +0100 Revert "Fix inferior octave single-quote font lock" This reverts commit 9e68413c7f0a7f71e1cee923ace7282d14c2e686. This patch led to bug#46327: x = [2 2]' disp(x) Which meant that the transpose operator was interpreted as the start of a string. diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el index cb44b72fb4..ddcc6f5450 100644 --- a/lisp/progmodes/octave.el +++ b/lisp/progmodes/octave.el @@ -165,7 +165,7 @@ parenthetical grouping.") (modify-syntax-entry ?| "." table) (modify-syntax-entry ?! "." table) (modify-syntax-entry ?\\ "." table) - (modify-syntax-entry ?\' "\"" table) + (modify-syntax-entry ?\' "." table) (modify-syntax-entry ?\` "." table) (modify-syntax-entry ?. "." table) (modify-syntax-entry ?\" "\"" table) commit 5beddcd325e8ec16a6f284ef0524fb796fe07d5e Author: Lars Ingebrigtsen Date: Sun Feb 7 15:07:21 2021 +0100 Reverse customize-changed and customize-changed-options aliasing * lisp/cus-edit.el (customize-changed): Rename from customize-changed-options (bug#23085), since the old name doesn't reflect what it does: It's not just about user options, but also faces and the like. (customize-changed-options): Make into an obsolete alias. diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el index e52df4e6a2..cd1ae964eb 100644 --- a/lisp/cus-edit.el +++ b/lisp/cus-edit.el @@ -1242,10 +1242,11 @@ the user might see the value in an error message, a good choice is the official name of the package, such as MH-E or Gnus.") ;;;###autoload -(defalias 'customize-changed 'customize-changed-options) +(define-obsolete-function-alias 'customize-changed-options + #'customize-changed "28.1") ;;;###autoload -(defun customize-changed-options (&optional since-version) +(defun customize-changed (&optional since-version) "Customize all settings whose meanings have changed in Emacs itself. This includes new user options and faces, and new customization groups, as well as older options and faces whose meanings or commit a1a31ecb4027a831eb81728bf66fbd44a28d2840 Author: Lars Ingebrigtsen Date: Sun Feb 7 14:47:09 2021 +0100 Clarify that #s(hash-table ...) doesn't always create a new hash table * doc/lispref/hash.texi (Creating Hash): Note that the printed representation doesn't necessarily create a new table (bug#23417). * doc/lispref/lists.texi (Rearrangement): Link to Self-Evaluating Forms to further expand upon immutability. diff --git a/doc/lispref/hash.texi b/doc/lispref/hash.texi index 8781fad30c..12c6a65907 100644 --- a/doc/lispref/hash.texi +++ b/doc/lispref/hash.texi @@ -150,11 +150,11 @@ multiplied by an approximation to this value. The default for @end table @end defun -You can also create a new hash table using the printed representation +You can also create a hash table using the printed representation for hash tables. The Lisp reader can read this printed representation, provided each element in the specified hash table has a valid read syntax (@pxref{Printed Representation}). For instance, -the following specifies a new hash table containing the keys +the following specifies a hash table containing the keys @code{key1} and @code{key2} (both symbols) associated with @code{val1} (a symbol) and @code{300} (a number) respectively. @@ -162,6 +162,11 @@ the following specifies a new hash table containing the keys #s(hash-table size 30 data (key1 val1 key2 300)) @end example +Note, however, that when using this in Emacs Lisp code, it's +undefined whether this creates a new hash table or not. If you want +to create a new hash table, you should always use +@code{make-hash-table} (@pxref{Self-Evaluating Forms}). + @noindent The printed representation for a hash table consists of @samp{#s} followed by a list beginning with @samp{hash-table}. The rest of the diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi index c54496f616..2805b1f5fd 100644 --- a/doc/lispref/lists.texi +++ b/doc/lispref/lists.texi @@ -1168,13 +1168,14 @@ x @end group @end example -However, the other arguments (all but the last) should be mutable lists. - -A common pitfall is to use a constant list as a non-last -argument to @code{nconc}. If you do this, the resulting behavior -is undefined. It is possible that your program will change -each time you run it! Here is what might happen (though this -is not guaranteed to happen): +However, the other arguments (all but the last) should be mutable +lists. + +A common pitfall is to use a constant list as a non-last argument to +@code{nconc}. If you do this, the resulting behavior is undefined +(@pxref{Self-Evaluating Forms}). It is possible that your program +will change each time you run it! Here is what might happen (though +this is not guaranteed to happen): @smallexample @group commit e0c9399454838444e0cc8c6c1fc1d307d9e9752b Author: Lars Ingebrigtsen Date: Sun Feb 7 13:53:44 2021 +0100 Add more commands to the new `C-x x' keymap * doc/emacs/killing.texi (Accumulating Text): * doc/emacs/display.texi (Line Truncation): * doc/emacs/buffers.texi (Misc Buffer): Document it. * lisp/bindings.el (ctl-x-x-map): Add new bindings for rename-buffer, rename-uniquely, insert-buffer and toggle-truncate-lines. diff --git a/doc/emacs/buffers.texi b/doc/emacs/buffers.texi index 9cdfa493ed..3a166e404a 100644 --- a/doc/emacs/buffers.texi +++ b/doc/emacs/buffers.texi @@ -232,9 +232,9 @@ unless they visit files: such buffers are used internally by Emacs. @table @kbd @item C-x C-q Toggle read-only status of buffer (@code{read-only-mode}). -@item M-x rename-buffer @key{RET} @var{buffer} @key{RET} +@item C-x x r @key{RET} @var{buffer} @key{RET} Change the name of the current buffer. -@item M-x rename-uniquely +@item C-x x u Rename the current buffer by adding @samp{<@var{number}>} to the end. @item M-x view-buffer @key{RET} @var{buffer} @key{RET} Scroll through buffer @var{buffer}. @xref{View Mode}. @@ -263,28 +263,28 @@ non-@code{nil} value, making the buffer read-only with @kbd{C-x C-q} also enables View mode in the buffer (@pxref{View Mode}). @findex rename-buffer - @kbd{M-x rename-buffer} changes the name of the current buffer. You -specify the new name as a minibuffer argument; there is no default. -If you specify a name that is in use for some other buffer, an error -happens and no renaming is done. + @kbd{C-x x r} (@code{rename-buffer} changes the name of the current +buffer. You specify the new name as a minibuffer argument; there is +no default. If you specify a name that is in use for some other +buffer, an error happens and no renaming is done. @findex rename-uniquely - @kbd{M-x rename-uniquely} renames the current buffer to a similar -name with a numeric suffix added to make it both different and unique. -This command does not need an argument. It is useful for creating -multiple shell buffers: if you rename the @file{*shell*} buffer, then -do @kbd{M-x shell} again, it makes a new shell buffer named -@file{*shell*}; meanwhile, the old shell buffer continues to exist -under its new name. This method is also good for mail buffers, + @kbd{C-x x u} (@code{rename-uniquely}) renames the current buffer to +a similar name with a numeric suffix added to make it both different +and unique. This command does not need an argument. It is useful for +creating multiple shell buffers: if you rename the @file{*shell*} +buffer, then do @kbd{M-x shell} again, it makes a new shell buffer +named @file{*shell*}; meanwhile, the old shell buffer continues to +exist under its new name. This method is also good for mail buffers, compilation buffers, and most Emacs features that create special buffers with particular names. (With some of these features, such as @kbd{M-x compile}, @kbd{M-x grep}, you need to switch to some other buffer before using the command again, otherwise it will reuse the current buffer despite the name change.) - The commands @kbd{M-x append-to-buffer} and @kbd{M-x insert-buffer} -can also be used to copy text from one buffer to another. -@xref{Accumulating Text}. + The commands @kbd{M-x append-to-buffer} and @kbd{C-x x i} +(@code{insert-buffer}) can also be used to copy text from one buffer +to another. @xref{Accumulating Text}. @node Kill Buffer @section Killing Buffers diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi index f4b1854142..2781328cb7 100644 --- a/doc/emacs/display.texi +++ b/doc/emacs/display.texi @@ -1755,13 +1755,13 @@ and/or leftmost columns. @findex toggle-truncate-lines Horizontal scrolling automatically causes line truncation (@pxref{Horizontal Scrolling}). You can explicitly enable line -truncation for a particular buffer with the command @kbd{M-x -toggle-truncate-lines}. This works by locally changing the variable -@code{truncate-lines}. If that variable is non-@code{nil}, long lines -are truncated; if it is @code{nil}, they are continued onto multiple -screen lines. Setting the variable @code{truncate-lines} in any way -makes it local to the current buffer; until that time, the default -value, which is normally @code{nil}, is in effect. +truncation for a particular buffer with the command @kbd{C-x x t} +(@code{toggle-truncate-lines}). This works by locally changing the +variable @code{truncate-lines}. If that variable is non-@code{nil}, +long lines are truncated; if it is @code{nil}, they are continued onto +multiple screen lines. Setting the variable @code{truncate-lines} in +any way makes it local to the current buffer; until that time, the +default value, which is normally @code{nil}, is in effect. If a split window becomes too narrow, Emacs may automatically enable line truncation. @xref{Split Window}, for the variable diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi index 9bc786dc47..8434040bce 100644 --- a/doc/emacs/killing.texi +++ b/doc/emacs/killing.texi @@ -703,13 +703,13 @@ copy-to-buffer} is similar, except that any existing text in the other buffer is deleted, so the buffer is left containing just the text newly copied into it. - The command @kbd{M-x insert-buffer} can be used to retrieve the -accumulated text from another buffer. This prompts for the name of a -buffer, and inserts a copy of all the text in that buffer into the -current buffer at point, leaving point at the beginning of the -inserted text. It also adds the position of the end of the inserted -text to the mark ring, without activating the mark. @xref{Buffers}, -for background information on buffers. + The command @kbd{C-x x i} (@code{insert-buffer}) can be used to +retrieve the accumulated text from another buffer. This prompts for +the name of a buffer, and inserts a copy of all the text in that +buffer into the current buffer at point, leaving point at the +beginning of the inserted text. It also adds the position of the end +of the inserted text to the mark ring, without activating the mark. +@xref{Buffers}, for background information on buffers. Instead of accumulating text in a buffer, you can append text directly into a file with @kbd{M-x append-to-file}. This prompts for diff --git a/etc/NEWS b/etc/NEWS index b80c649074..0faed3e5aa 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -234,7 +234,11 @@ still applies for shorter search strings, which avoids flicker in the search buffer due to too many matches being highlighted. +++ -** 'revert-buffer' is now bound to 'C-x x g' globally. +** A new keymap for buffer actions has been added. +The 'C-x x' keymap now holds keystrokes for various buffer-oriented +commands. The new keystrokes are 'C-x x g' ('revert-buffer'), +'C-x x r' ('rename-buffer'), 'C-x x u' ('rename-uniquely'), +'C-x x i' ('insert-buffer') and 'C-x x t' ('toggle-truncate-lines'). * Editing Changes in Emacs 28.1 diff --git a/lisp/bindings.el b/lisp/bindings.el index 35adfa8172..9462468b1b 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -1416,6 +1416,10 @@ if `inhibit-field-text-motion' is non-nil." (defvar ctl-x-x-map (let ((map (make-sparse-keymap))) (define-key map "g" #'revert-buffer) + (define-key map "r" #'rename-buffer) + (define-key map "u" #'rename-uniquely) + (define-key map "i" #'insert-buffer) + (define-key map "t" #'toggle-truncate-lines) map) "Keymap for subcommands of C-x x.") (define-key ctl-x-map "x" ctl-x-x-map) commit a6a5d6a27a86396ab96662fa158cdcc854bd777b Author: Sean Whitton Date: Sun Feb 7 13:30:33 2021 +0100 Move 'revert-buffer' global binding to 'C-x g g' * lisp/bindings.el: Define ctl-x-g-map and bind 'revert-buffer' to 'C-x x g' globally. * doc/emacs/files.texi: Replace 'C-x g' with 'C-x x g'. * etc/NEWS: Document the change (bug#46300). diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index 12ceac800e..6b3bc430d9 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -927,7 +927,7 @@ Manual}). For customizations, see the Custom group @code{time-stamp}. If you have made extensive changes to a file-visiting buffer and then change your mind, you can @dfn{revert} the changes and go back to -the saved version of the file. To do this, type @kbd{C-x g}. Since +the saved version of the file. To do this, type @kbd{C-x x g}. Since reverting unintentionally could lose a lot of work, Emacs asks for confirmation first. diff --git a/etc/NEWS b/etc/NEWS index fb77688470..b80c649074 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -234,7 +234,7 @@ still applies for shorter search strings, which avoids flicker in the search buffer due to too many matches being highlighted. +++ -** 'revert-buffer' is now bound to 'C-x g' globally. +** 'revert-buffer' is now bound to 'C-x x g' globally. * Editing Changes in Emacs 28.1 diff --git a/lisp/bindings.el b/lisp/bindings.el index 9ea188d1a0..35adfa8172 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -1413,7 +1413,12 @@ if `inhibit-field-text-motion' is non-nil." (define-key ctl-x-map "z" 'repeat) -(define-key ctl-x-map "g" #'revert-buffer) +(defvar ctl-x-x-map + (let ((map (make-sparse-keymap))) + (define-key map "g" #'revert-buffer) + map) + "Keymap for subcommands of C-x x.") +(define-key ctl-x-map "x" ctl-x-x-map) (define-key esc-map "\C-l" 'reposition-window) commit 8b8708eadd94fcdad4c426a20370ff4ab13df258 Author: Petteri Hintsanen Date: Sun Feb 7 13:10:19 2021 +0100 Fix example in Sequence Functions node in the manual * doc/lispref/sequences.texi (Sequence Functions): Fix the result from the example. diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index bdf0b95d81..b48d456918 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -594,7 +594,7 @@ returned value is a list. (seq-map-indexed (lambda (elt idx) (list idx elt)) '(a b c)) -@result{} ((0 a) (b 1) (c 2)) +@result{} ((0 a) (1 b) (2 c)) @end group @end example @end defun commit 7e48430a43bbf7a2bbe347540dc346d0129df2ec Author: Mattias Engdegård Date: Sun Feb 7 12:24:40 2021 +0100 ; * lisp/emacs-lisp/byte-opt.el: improved comment diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 32f66ebebb..abbe2a2e63 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -440,7 +440,7 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") (let ((lexvar (assq form byte-optimize--lexvars))) (if (cddr lexvar) ; Value available? (if (assq form byte-optimize--vars-outside-loop) - ;; Cannot substitute; mark as changed to avoid the + ;; Cannot substitute; mark for retention to avoid the ;; variable being eliminated. (progn (setcar (cdr lexvar) t) commit 765ffeb54569c1679b9f08b50c6a88fe50c525c8 Author: Mattias Engdegård Date: Sun Feb 7 10:35:36 2021 +0100 ; Improved commentary in the variable constprop mechanism * lisp/emacs-lisp/byte-opt.el (byte-optimize--lexvars) (byte-optimize--vars-outside-condition) (byte-optimize-form-code-walker, byte-optimize-let-form): Clarify various aspects in the variable constant-propagation code, as kindly pointed out by Stefan Monnier. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 017cad900d..32f66ebebb 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -378,16 +378,17 @@ very chatty, but can be useful for debugging.") (defvar byte-optimize--lexvars nil "Lexical variables in scope, in reverse order of declaration. -Each element is on the form (NAME CHANGED [VALUE]), where: +Each element is on the form (NAME KEEP [VALUE]), where: NAME is the variable name, - CHANGED is a boolean indicating whether it's been changed (with setq), + KEEP is a boolean indicating whether the binding must be retained, VALUE, if present, is a substitutable expression. Earlier variables shadow later ones with the same name.") (defvar byte-optimize--vars-outside-condition nil "Alist of variables lexically bound outside conditionally executed code. -Variables here are sensitive to mutation inside the condition, since such -changes may not be effective for all code paths. +Variables here are sensitive to mutation inside the conditional code, +since their contents in sequentially later code depends on the path taken +and may no longer be statically known. Same format as `byte-optimize--lexvars', with shared structure and contents.") (defvar byte-optimize--vars-outside-loop nil @@ -507,7 +508,9 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") (`(,(or 'and 'or) . ,exps) ; Remember, and/or are control structures. ;; FIXME: We have to traverse the expressions in left-to-right - ;; order, but doing so we miss some optimisation opportunities: + ;; order (because that is the order of evaluation and variable + ;; mutations must be found prior to their use), but doing so we miss + ;; some optimisation opportunities: ;; consider (and A B) in a for-effect context, where B => nil. ;; Then A could be optimised in a for-effect context too. (let ((tail exps) @@ -592,7 +595,7 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") ;; Needed as long as we run byte-optimize-form after cconv. (`(internal-make-closure . ,_) - ;; Look up free vars and mark them as changed, so that they + ;; Look up free vars and mark them to be kept, so that they ;; won't be optimised away. (dolist (var (caddr form)) (let ((lexvar (assq var byte-optimize--lexvars))) @@ -627,10 +630,11 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") ;; We are in conditional code and the variable was ;; bound outside: cancel substitutions. (setcdr (cdr lexvar) nil) + ;; Set a new value (if substitutable). (setcdr (cdr lexvar) (and (byte-optimize--substitutable-p value) (list value)))) - (setcar (cdr lexvar) t)) ; Mark variable as changed. + (setcar (cdr lexvar) t)) ; Mark variable to be kept. (push var var-expr-list) (push value var-expr-list)) (setq args (cddr args))) @@ -735,8 +739,9 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") (let* ((opt-body (byte-optimize-body (cdr form) for-effect)) (bindings nil)) (dolist (var let-vars) - ;; VAR is (NAME EXPR [CHANGED [VALUE]]) + ;; VAR is (NAME EXPR [KEEP [VALUE]]) (if (and (nthcdr 3 var) (not (nth 2 var))) + ;; Value present and not marked to be kept: eliminate. (when byte-optimize-warn-eliminated-variable (byte-compile-warn "eliminating local variable %S" (car var))) (push (list (nth 0 var) (nth 1 var)) bindings))) commit 06e1e5eeacf67b11490431c3d36700a73cf49d88 Author: Dmitry Gutov Date: Sat Feb 6 22:59:00 2021 +0200 Revert "Fix the previous change" This reverts commit fc37dc298f27025823fad2d944e11cc7ee6a058d. That change was only needed in the release branch. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 4c9b70ce04..abe563bec0 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -725,7 +725,7 @@ requires quoting, e.g. `\\[quoted-insert]'." (require 'xref) (require 'grep) (let* ((pr (project-current t)) - (default-directory (car (project-roots pr))) + (default-directory (project-root pr)) (files (if (not current-prefix-arg) (project-files pr) @@ -757,7 +757,7 @@ pattern to search for." (interactive (list (project--read-regexp))) (require 'xref) (let* ((pr (project-current t)) - (default-directory (car (project-roots pr))) + (default-directory (project-root pr)) (files (project-files pr (cons (project-root pr) commit 4dc3231c91c339e602f59dcfee372017b92e4318 Author: Mattias Engdegård Date: Thu Feb 4 14:32:21 2021 +0100 Fix spurious warnings from unwise condition order in inlined code These are both conditions having the form (and A B) where A is side-effect-free and B may be known to be nil at compile time. The compiler will then warn about A being useless and thrown away. The fix is to test B first. * lisp/gnus/gnus.el (gnus-method-to-server): Test `(not no-enter-cache)` first. (gnus-server-get-method): Test `group` first. diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index 84e53da297..98664ac2b4 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el @@ -3212,8 +3212,8 @@ that that variable is buffer-local to the summary buffers." (format "%s" (car method)) (format "%s:%s" (car method) (cadr method)))) (name-method (cons name method))) - (when (and (not (member name-method gnus-server-method-cache)) - (not no-enter-cache) + (when (and (not no-enter-cache) + (not (member name-method gnus-server-method-cache)) (not (assoc (car name-method) gnus-server-method-cache))) (push name-method gnus-server-method-cache)) name))) @@ -3273,8 +3273,7 @@ that that variable is buffer-local to the summary buffers." (gnus-server-to-method method)) ((equal method gnus-select-method) gnus-select-method) - ((and (stringp (car method)) - group) + ((and group (stringp (car method))) (gnus-server-extend-method group method)) ((and method (not group) commit 83983b6b7a115474572973b62eb5e42251713e63 Author: Mattias Engdegård Date: Sat Feb 6 18:34:45 2021 +0100 Constprop of lexical variables Lexical variables bound to a constant value (symbol, number or string) are substituted at their point of use and the variable then eliminated if possible. Example: (let ((x (+ 2 3))) (f x)) => (f 5) This reduces code size, eliminates stack operations, and enables further optimisations. The implementation is conservative, and is strongly curtailed by the presence of variable mutation, conditions and loops. * lisp/emacs-lisp/byte-opt.el (byte-optimize-enable-variable-constprop) (byte-optimize-warn-eliminated-variable): New constants. (byte-optimize--lexvars, byte-optimize--vars-outside-condition) (byte-optimize--vars-outside-loop, byte-optimize--dynamic-vars): New dynamic variables. (byte-optimize--substitutable-p, byte-optimize-let-form): New functions. (byte-optimize-form-code-walker): Adapt clauses for variable constprop, and add clauses for 'setq' and 'defvar'. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-test-var) (bytecomp-test-get-var, bytecomp-test-identity) (byte-opt-testsuite-arith-data): Add test cases. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 66a117fccc..017cad900d 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -368,6 +368,53 @@ ;;; implementing source-level optimizers +(defconst byte-optimize-enable-variable-constprop t + "If non-nil, enable constant propagation through local variables.") + +(defconst byte-optimize-warn-eliminated-variable nil + "Whether to warn when a variable is optimised away entirely. +This does usually not indicate a problem and makes the compiler +very chatty, but can be useful for debugging.") + +(defvar byte-optimize--lexvars nil + "Lexical variables in scope, in reverse order of declaration. +Each element is on the form (NAME CHANGED [VALUE]), where: + NAME is the variable name, + CHANGED is a boolean indicating whether it's been changed (with setq), + VALUE, if present, is a substitutable expression. +Earlier variables shadow later ones with the same name.") + +(defvar byte-optimize--vars-outside-condition nil + "Alist of variables lexically bound outside conditionally executed code. +Variables here are sensitive to mutation inside the condition, since such +changes may not be effective for all code paths. +Same format as `byte-optimize--lexvars', with shared structure and contents.") + +(defvar byte-optimize--vars-outside-loop nil + "Alist of variables lexically bound outside the innermost `while' loop. +Variables here are sensitive to mutation inside the loop, since this can +occur an indeterminate number of times and thus have effect on code +sequentially preceding the mutation itself. +Same format as `byte-optimize--lexvars', with shared structure and contents.") + +(defvar byte-optimize--dynamic-vars nil + "List of variables declared as dynamic during optimisation.") + +(defun byte-optimize--substitutable-p (expr) + "Whether EXPR is a constant that can be propagated." + ;; Only consider numbers, symbols and strings to be values for substitution + ;; purposes. Numbers and symbols are immutable, and mutating string + ;; literals (or results from constant-evaluated string-returning functions) + ;; can be considered undefined. + ;; (What about other quoted values, like conses?) + (or (booleanp expr) + (numberp expr) + (stringp expr) + (and (consp expr) + (eq (car expr) 'quote) + (symbolp (cadr expr))) + (keywordp expr))) + (defun byte-optimize-form-code-walker (form for-effect) ;; ;; For normal function calls, We can just mapcar the optimizer the cdr. But @@ -382,11 +429,24 @@ (let ((fn (car-safe form))) (pcase form ((pred (not consp)) - (if (not (and for-effect - (or byte-compile-delete-errors - (not (symbolp form)) - (eq form t)))) - form)) + (cond + ((and for-effect + (or byte-compile-delete-errors + (not (symbolp form)) + (eq form t))) + nil) + ((symbolp form) + (let ((lexvar (assq form byte-optimize--lexvars))) + (if (cddr lexvar) ; Value available? + (if (assq form byte-optimize--vars-outside-loop) + ;; Cannot substitute; mark as changed to avoid the + ;; variable being eliminated. + (progn + (setcar (cdr lexvar) t) + form) + (caddr lexvar)) ; variable value to use + form))) + (t form))) (`(quote . ,v) (if (cdr v) (byte-compile-warn "malformed quote form: `%s'" @@ -396,33 +456,22 @@ (and (car v) (not for-effect) form)) - (`(,(or 'let 'let*) . ,(or `(,bindings . ,exps) pcase--dontcare)) - ;; Recursively enter the optimizer for the bindings and body - ;; of a let or let*. This for depth-firstness: forms that - ;; are more deeply nested are optimized first. - (cons fn - (cons - (mapcar (lambda (binding) - (if (symbolp binding) - binding - (if (cdr (cdr binding)) - (byte-compile-warn "malformed let binding: `%s'" - (prin1-to-string binding))) - (list (car binding) - (byte-optimize-form (nth 1 binding) nil)))) - bindings) - (byte-optimize-body exps for-effect)))) + (`(,(or 'let 'let*) . ,rest) + (cons fn (byte-optimize-let-form fn rest for-effect))) (`(cond . ,clauses) - (cons fn - (mapcar (lambda (clause) - (if (consp clause) - (cons - (byte-optimize-form (car clause) nil) - (byte-optimize-body (cdr clause) for-effect)) - (byte-compile-warn "malformed cond form: `%s'" - (prin1-to-string clause)) - clause)) - clauses))) + ;; The condition in the first clause is always executed, but + ;; right now we treat all of them as conditional for simplicity. + (let ((byte-optimize--vars-outside-condition byte-optimize--lexvars)) + (cons fn + (mapcar (lambda (clause) + (if (consp clause) + (cons + (byte-optimize-form (car clause) nil) + (byte-optimize-body (cdr clause) for-effect)) + (byte-compile-warn "malformed cond form: `%s'" + (prin1-to-string clause)) + clause)) + clauses)))) (`(progn . ,exps) ;; As an extra added bonus, this simplifies (progn ) --> . (if (cdr exps) @@ -442,35 +491,54 @@ (cons fn (byte-optimize-body exps for-effect))) (`(if ,test ,then . ,else) - `(if ,(byte-optimize-form test nil) - ,(byte-optimize-form then for-effect) - . ,(byte-optimize-body else for-effect))) + ;; The test is always executed. + (let* ((test-opt (byte-optimize-form test nil)) + ;; The THEN and ELSE branches are executed conditionally. + ;; + ;; FIXME: We are conservative here: any variable changed in the + ;; THEN branch will be barred from substitution in the ELSE + ;; branch, despite the branches being mutually exclusive. + (byte-optimize--vars-outside-condition byte-optimize--lexvars) + (then-opt (byte-optimize-form then for-effect)) + (else-opt (byte-optimize-body else for-effect))) + `(if ,test-opt ,then-opt . ,else-opt))) (`(if . ,_) (byte-compile-warn "too few arguments for `if'")) (`(,(or 'and 'or) . ,exps) ; Remember, and/or are control structures. - ;; Take forms off the back until we can't any more. - ;; In the future it could conceivably be a problem that the - ;; subexpressions of these forms are optimized in the reverse - ;; order, but it's ok for now. - (if for-effect - (let ((backwards (reverse exps))) - (while (and backwards - (null (setcar backwards - (byte-optimize-form (car backwards) - for-effect)))) - (setq backwards (cdr backwards))) - (if (and exps (null backwards)) - (byte-compile-log - " all subforms of %s called for effect; deleted" form)) - (and backwards - (cons fn (nreverse (mapcar #'byte-optimize-form - backwards))))) - (cons fn (mapcar #'byte-optimize-form exps)))) + ;; FIXME: We have to traverse the expressions in left-to-right + ;; order, but doing so we miss some optimisation opportunities: + ;; consider (and A B) in a for-effect context, where B => nil. + ;; Then A could be optimised in a for-effect context too. + (let ((tail exps) + (args nil)) + (when tail + ;; The first argument is always unconditional. + (push (byte-optimize-form + (car tail) (and for-effect (null (cdr tail)))) + args) + (setq tail (cdr tail)) + ;; Remaining arguments are conditional. + (let ((byte-optimize--vars-outside-condition byte-optimize--lexvars)) + (while tail + (push (byte-optimize-form + (car tail) (and for-effect (null (cdr tail)))) + args) + (setq tail (cdr tail))))) + (cons fn (nreverse args)))) (`(while ,exp . ,exps) - `(while ,(byte-optimize-form exp nil) - . ,(byte-optimize-body exps t))) + ;; FIXME: We conservatively prevent the substitution of any variable + ;; bound outside the loop in case it is mutated later in the loop, + ;; but this misses many opportunities: variables not mutated in the + ;; loop at all, and variables affecting the initial condition (which + ;; is always executed unconditionally). + (let* ((byte-optimize--vars-outside-condition byte-optimize--lexvars) + (byte-optimize--vars-outside-loop byte-optimize--lexvars) + (condition (byte-optimize-form exp nil)) + (body (byte-optimize-body exps t))) + `(while ,condition . ,body))) + (`(while . ,_) (byte-compile-warn "too few arguments for `while'")) @@ -485,24 +553,35 @@ form) (`(condition-case . ,(or `(,var ,exp . ,clauses) pcase--dontcare)) - `(condition-case ,var ;Not evaluated. - ,(byte-optimize-form exp for-effect) - ,@(mapcar (lambda (clause) - `(,(car clause) - ,@(byte-optimize-body (cdr clause) for-effect))) - clauses))) - - (`(unwind-protect . ,(or `(,exp . ,exps) pcase--dontcare)) - ;; The "protected" part of an unwind-protect is compiled (and thus - ;; optimized) as a top-level form, so don't do it here. But the - ;; non-protected part has the same for-effect status as the - ;; unwind-protect itself. (The protected part is always for effect, + (let ((byte-optimize--vars-outside-condition byte-optimize--lexvars)) + `(condition-case ,var ;Not evaluated. + ,(byte-optimize-form exp for-effect) + ,@(mapcar (lambda (clause) + `(,(car clause) + ,@(byte-optimize-body (cdr clause) for-effect))) + clauses)))) + + (`(unwind-protect ,exp . ,exps) + ;; The unwinding part of an unwind-protect is compiled (and thus + ;; optimized) as a top-level form, but run the optimizer for it here + ;; anyway for lexical variable usage and substitution. But the + ;; protected part has the same for-effect status as the + ;; unwind-protect itself. (The unwinding part is always for effect, ;; but that isn't handled properly yet.) - `(unwind-protect ,(byte-optimize-form exp for-effect) . ,exps)) + (let* ((byte-optimize--vars-outside-condition byte-optimize--lexvars) + (bodyform (byte-optimize-form exp for-effect))) + (pcase exps + (`(:fun-body ,f) + `(unwind-protect ,bodyform + :fun-body ,(byte-optimize-form f nil))) + (_ + `(unwind-protect ,bodyform + . ,(byte-optimize-body exps t)))))) (`(catch . ,(or `(,tag . ,exps) pcase--dontcare)) - `(catch ,(byte-optimize-form tag nil) - . ,(byte-optimize-body exps for-effect))) + (let ((byte-optimize--vars-outside-condition byte-optimize--lexvars)) + `(catch ,(byte-optimize-form tag nil) + . ,(byte-optimize-body exps for-effect)))) (`(ignore . ,exps) ;; Don't treat the args to `ignore' as being @@ -512,7 +591,14 @@ `(prog1 nil . ,(mapcar #'byte-optimize-form exps))) ;; Needed as long as we run byte-optimize-form after cconv. - (`(internal-make-closure . ,_) form) + (`(internal-make-closure . ,_) + ;; Look up free vars and mark them as changed, so that they + ;; won't be optimised away. + (dolist (var (caddr form)) + (let ((lexvar (assq var byte-optimize--lexvars))) + (when lexvar + (setcar (cdr lexvar) t)))) + form) (`((lambda . ,_) . ,_) (let ((newform (byte-compile-unfold-lambda form))) @@ -525,6 +611,35 @@ ;; is a *value* and shouldn't appear in the car. (`((closure . ,_) . ,_) form) + (`(setq . ,args) + (let ((var-expr-list nil)) + (while args + (unless (and (consp args) + (symbolp (car args)) (consp (cdr args))) + (byte-compile-warn "malformed setq form: %S" form)) + (let* ((var (car args)) + (expr (cadr args)) + (lexvar (assq var byte-optimize--lexvars)) + (value (byte-optimize-form expr nil))) + (when lexvar + ;; If it's bound outside conditional, invalidate. + (if (assq var byte-optimize--vars-outside-condition) + ;; We are in conditional code and the variable was + ;; bound outside: cancel substitutions. + (setcdr (cdr lexvar) nil) + (setcdr (cdr lexvar) + (and (byte-optimize--substitutable-p value) + (list value)))) + (setcar (cdr lexvar) t)) ; Mark variable as changed. + (push var var-expr-list) + (push value var-expr-list)) + (setq args (cddr args))) + (cons fn (nreverse var-expr-list)))) + + (`(defvar ,(and (pred symbolp) name) . ,_) + (push name byte-optimize--dynamic-vars) + form) + (`(,(pred byte-code-function-p) . ,exps) (cons fn (mapcar #'byte-optimize-form exps))) @@ -582,6 +697,64 @@ new) form))) +(defun byte-optimize-let-form (head form for-effect) + ;; Recursively enter the optimizer for the bindings and body + ;; of a let or let*. This for depth-firstness: forms that + ;; are more deeply nested are optimized first. + (if (and lexical-binding byte-optimize-enable-variable-constprop) + (let* ((byte-optimize--lexvars byte-optimize--lexvars) + (new-lexvars nil) + (let-vars nil)) + (dolist (binding (car form)) + (let (name expr) + (cond ((consp binding) + (setq name (car binding)) + (unless (symbolp name) + (byte-compile-warn "let-bind nonvariable: `%S'" name)) + (setq expr (byte-optimize-form (cadr binding) nil))) + ((symbolp binding) + (setq name binding)) + (t (byte-compile-warn "malformed let binding: `%S'" binding))) + (let* ( + (value (and (byte-optimize--substitutable-p expr) + (list expr))) + (lexical (not (or (and (symbolp name) + (special-variable-p name)) + (memq name byte-compile-bound-variables) + (memq name byte-optimize--dynamic-vars)))) + (lexinfo (and lexical (cons name (cons nil value))))) + (push (cons name (cons expr (cdr lexinfo))) let-vars) + (when lexinfo + (push lexinfo (if (eq head 'let*) + byte-optimize--lexvars + new-lexvars)))))) + (setq byte-optimize--lexvars + (append new-lexvars byte-optimize--lexvars)) + ;; Walk the body expressions, which may mutate some of the records, + ;; and generate new bindings that exclude unused variables. + (let* ((opt-body (byte-optimize-body (cdr form) for-effect)) + (bindings nil)) + (dolist (var let-vars) + ;; VAR is (NAME EXPR [CHANGED [VALUE]]) + (if (and (nthcdr 3 var) (not (nth 2 var))) + (when byte-optimize-warn-eliminated-variable + (byte-compile-warn "eliminating local variable %S" (car var))) + (push (list (nth 0 var) (nth 1 var)) bindings))) + (cons bindings opt-body))) + + ;; With dynamic binding, no substitutions are in effect. + (let ((byte-optimize--lexvars nil)) + (cons + (mapcar (lambda (binding) + (if (symbolp binding) + binding + (when (or (atom binding) (cddr binding)) + (byte-compile-warn "malformed let binding: `%S'" binding)) + (list (car binding) + (byte-optimize-form (nth 1 binding) nil)))) + (car form)) + (byte-optimize-body (cdr form) for-effect))))) + (defun byte-optimize-body (forms all-for-effect) ;; Optimize the cdr of a progn or implicit progn; all forms is a list of @@ -590,6 +763,7 @@ ;; all-for-effect is true. returns a new list of forms. (let ((rest forms) (result nil) + (byte-optimize--dynamic-vars byte-optimize--dynamic-vars) fe new) (while rest (setq fe (or all-for-effect (cdr rest))) diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el index 980b402ca2..bc623d3efc 100644 --- a/test/lisp/emacs-lisp/bytecomp-tests.el +++ b/test/lisp/emacs-lisp/bytecomp-tests.el @@ -32,6 +32,15 @@ (require 'bytecomp) ;;; Code: +(defvar bytecomp-test-var nil) + +(defun bytecomp-test-get-var () + bytecomp-test-var) + +(defun bytecomp-test-identity (x) + "Identity, but hidden from some optimisations." + x) + (defconst byte-opt-testsuite-arith-data '( ;; some functional tests @@ -371,7 +380,57 @@ (assoc 'b '((a 1) (b 2) (c 3))) (assoc "b" '(("a" 1) ("b" 2) ("c" 3))) (let ((x '((a 1) (b 2) (c 3)))) (assoc 'c x)) - (assoc 'a '((a 1) (b 2) (c 3)) (lambda (u v) (not (equal u v))))) + (assoc 'a '((a 1) (b 2) (c 3)) (lambda (u v) (not (equal u v)))) + + ;; Constprop test cases + (let ((a 'alpha) (b (concat "be" "ta")) (c nil) (d t) (e :gamma) + (f '(delta epsilon))) + (list a b c d e f)) + + (let ((x 1) (y (+ 3 4))) + (list + (let (q (y x) (z y)) + (if q x (list x y z))))) + + (let* ((x 3) (y (* x 2)) (x (1+ y))) + x) + + (let ((x 1) (bytecomp-test-var 2) (y 3)) + (list x bytecomp-test-var (bytecomp-get-test-var) y)) + + (progn + (defvar d) + (let ((x 'a) (y 'b)) (list x y))) + + (let ((x 2)) + (list x (setq x 13) (setq x (* x 2)) x)) + + (let ((x 'a) (y 'b)) + (setq y x + x (cons 'c y) + y x) + (list x y)) + + (let ((x 3)) + (let ((y x) z) + (setq x 5) + (setq y (+ y 8)) + (setq z (if (bytecomp-test-identity t) + (progn + (setq x (+ x 1)) + (list x y)) + (setq x (+ x 2)) + (list x y))) + (list x y z))) + + (let ((i 1) (s 0) (x 13)) + (while (< i 5) + (setq s (+ s i)) + (setq i (1+ i))) + (list s x i)) + + (let ((x 2)) + (list (or (bytecomp-identity 'a) (setq x 3)) x))) "List of expression for test. Each element will be executed by interpreter and with bytecompiled code, and their results compared.") commit f95266ee68ab85f7a237b473f98b36413b542553 Author: Eli Zaretskii Date: Sat Feb 6 20:50:57 2021 +0200 ; Fix byte-compilation warning * test/src/process-tests.el (process-sentinel-interrupt-event): Fix byte compilation warning. diff --git a/test/src/process-tests.el b/test/src/process-tests.el index b2e0ec19de..e62bcb3f7c 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -893,7 +893,7 @@ Return nil if FILENAME doesn't exist." ;; Capture any incoming events. (set-process-sentinel proc - (lambda (proc event) + (lambda (_prc event) (push event events))) ;; Wait for the process to start. (sleep-for 2) commit a3b182954ccf10a0c21568bd91f7725db575690e Author: Eli Zaretskii Date: Sat Feb 6 20:20:31 2021 +0200 ; Fix last change diff --git a/test/src/process-tests.el b/test/src/process-tests.el index 950d0814c2..b2e0ec19de 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -881,8 +881,7 @@ Return nil if FILENAME doesn't exist." ;; Bug#46284 (ert-deftest process-sentinel-interrupt-event () - "Test that interrupting a process on MS-Windows sends the - \"interrupt\" event to the process sentinel." + "Test that interrupting a process on Windows sends \"interrupt\" to sentinel." (skip-unless (eq system-type 'windows-nt)) (with-temp-buffer (let* ((proc-buf (current-buffer)) commit d640ec27183c9424daaf2d5dcb683ed1ff39d036 Author: Ioannis Kappas Date: Wed Feb 3 22:50:54 2021 +0000 New test for src/process.c on MS-Windows * test/src/process-tests.el (process-sentinel-interrupt-event): New test. (Bug#46284) Copyright-paperwork-exempt: yes diff --git a/test/src/process-tests.el b/test/src/process-tests.el index a3fba8d328..950d0814c2 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -879,5 +879,34 @@ Return nil if FILENAME doesn't exist." (file-regular-p filename) filename))) +;; Bug#46284 +(ert-deftest process-sentinel-interrupt-event () + "Test that interrupting a process on MS-Windows sends the + \"interrupt\" event to the process sentinel." + (skip-unless (eq system-type 'windows-nt)) + (with-temp-buffer + (let* ((proc-buf (current-buffer)) + ;; Start a new emacs process to wait idly until interrupted. + (cmd "emacs -batch --eval=\"(sit-for 50000)\"") + (proc (start-file-process-shell-command + "test/process-sentinel-signal-event" proc-buf cmd)) + (events '())) + + ;; Capture any incoming events. + (set-process-sentinel proc + (lambda (proc event) + (push event events))) + ;; Wait for the process to start. + (sleep-for 2) + (should (equal 'run (process-status proc))) + ;; Interrupt the sub-process and wait for it to die. + (interrupt-process proc) + (sleep-for 2) + ;; Should have received SIGINT... + (should (equal 'signal (process-status proc))) + (should (equal 2 (process-exit-status proc))) + ;; ...and the change description should be "interrupt". + (should (equal '("interrupt\n") events))))) + (provide 'process-tests) ;;; process-tests.el ends here commit b76864ef5513a9c1f7fe1138266dfab47f6fe350 Author: Eric Abrahamsen Date: Sat Feb 6 09:29:53 2021 -0800 Fix TEXT check in gnus-search IMAP search * lisp/gnus/gnus-search.el (gnus-search-run-search): It's a string, not a buffer! diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el index f3e08519c3..0783d34733 100644 --- a/lisp/gnus/gnus-search.el +++ b/lisp/gnus/gnus-search.el @@ -1040,7 +1040,7 @@ Responsible for handling and, or, and parenthetical expressions.") ;; A bit of backward-compatibility slash convenience: if the ;; query string doesn't start with any known IMAP search ;; keyword, assume it is a "TEXT" search. - (unless (or (looking-at "(") + (unless (or (eql ?\( (aref q-string 0)) (and (string-match "\\`[^[:blank:]]+" q-string) (memql (intern-soft (downcase (match-string 0 q-string))) commit 29e9cf291eb35a77ad782e56effddf2fa00ee96c Author: Martin Rudalics Date: Sat Feb 6 18:22:29 2021 +0100 Permit zero value for 'child-frame-border-width' parameter (Bug#46184) * doc/lispref/frames.texi (Layout Parameters): Update entry on 'child-frame-border-width' parameter. * src/frame.c (make_frame): Init child_frame_border_width to -1. (Fframe_child_frame_border_width): Return internal border width if child frame border width parameter is nil. (gui_report_frame_params): Report nil as child frame border width parameter if the frame value is negative. * src/frame.h (FRAME_INTERNAL_BORDER_WIDTH): Return value of child frame border width only if it is not negative. * src/xfns.c (Fx_create_frame): Default child frame border to -1 when recording it in its frame slot via gui_default_parameter. * src/nsfns.m (ns_set_child_frame_border_width): Handle nil ARG. (Fx_create_frame): Default child frame border width parameter to nil. * src/w32fns.c (w32_set_child_frame_border_width): Handle nil ARG. (Fx_create_frame): Default child frame border width parameter to nil. * src/xfns.c (x_set_child_frame_border_width): Handle nil ARG. (Fx_create_frame): Default child frame border width parameter to nil. diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index a15511dc9f..f4316b753d 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -1802,6 +1802,8 @@ Geometry}). @item child-frame-border-width The width in pixels of the frame's internal border (@pxref{Frame Geometry}) if the given frame is a child frame (@pxref{Child Frames}). +If this is @code{nil}, the value specified by the +@code{internal-border-width} parameter is used instead. @vindex vertical-scroll-bars@r{, a frame parameter} @item vertical-scroll-bars diff --git a/src/frame.c b/src/frame.c index a2167ce1e4..635fc94560 100644 --- a/src/frame.c +++ b/src/frame.c @@ -898,6 +898,7 @@ make_frame (bool mini_p) f->no_accept_focus = false; f->z_group = z_group_none; f->tooltip = false; + f->child_frame_border_width = -1; f->last_tab_bar_item = -1; #ifndef HAVE_EXT_TOOL_BAR f->last_tool_bar_item = -1; @@ -3544,10 +3545,17 @@ DEFUN ("frame-fringe-width", Ffringe_width, Sfringe_width, 0, 1, 0, } DEFUN ("frame-child-frame-border-width", Fframe_child_frame_border_width, Sframe_child_frame_border_width, 0, 1, 0, - doc: /* Return width of FRAME's child-frame border in pixels. */) + doc: /* Return width of FRAME's child-frame border in pixels. + If FRAME's 'child-frame-border-width' parameter is nil, return FRAME's + internal border width instead. */) (Lisp_Object frame) { - return make_fixnum (FRAME_CHILD_FRAME_BORDER_WIDTH (decode_any_frame (frame))); + int width = FRAME_CHILD_FRAME_BORDER_WIDTH (decode_any_frame (frame)); + + if (width < 0) + return make_fixnum (FRAME_INTERNAL_BORDER_WIDTH (decode_any_frame (frame))); + else + return make_fixnum (FRAME_CHILD_FRAME_BORDER_WIDTH (decode_any_frame (frame))); } DEFUN ("frame-internal-border-width", Fframe_internal_border_width, Sframe_internal_border_width, 0, 1, 0, @@ -4311,7 +4319,9 @@ gui_report_frame_params (struct frame *f, Lisp_Object *alistptr) store_in_alist (alistptr, Qborder_width, make_fixnum (f->border_width)); store_in_alist (alistptr, Qchild_frame_border_width, - make_fixnum (FRAME_CHILD_FRAME_BORDER_WIDTH (f))); + FRAME_CHILD_FRAME_BORDER_WIDTH (f) >= 0 + ? make_fixnum (FRAME_CHILD_FRAME_BORDER_WIDTH (f)) + : Qnil); store_in_alist (alistptr, Qinternal_border_width, make_fixnum (FRAME_INTERNAL_BORDER_WIDTH (f))); store_in_alist (alistptr, Qright_divider_width, diff --git a/src/frame.h b/src/frame.h index 21148fe94c..9ddcb4c681 100644 --- a/src/frame.h +++ b/src/frame.h @@ -1449,11 +1449,11 @@ INLINE int FRAME_INTERNAL_BORDER_WIDTH (struct frame *f) { #ifdef HAVE_WINDOW_SYSTEM - return FRAME_PARENT_FRAME(f) - ? (f->child_frame_border_width - ? FRAME_CHILD_FRAME_BORDER_WIDTH(f) - : frame_dimension (f->internal_border_width)) - : frame_dimension (f->internal_border_width); + return (FRAME_PARENT_FRAME(f) + ? (FRAME_CHILD_FRAME_BORDER_WIDTH(f) >= 0 + ? FRAME_CHILD_FRAME_BORDER_WIDTH(f) + : frame_dimension (f->internal_border_width)) + : frame_dimension (f->internal_border_width)); #else return frame_dimension (f->internal_border_width); #endif diff --git a/src/nsfns.m b/src/nsfns.m index c7857eac73..5c4cc915e7 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -690,17 +690,24 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side. static void ns_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { - int old_width = FRAME_CHILD_FRAME_BORDER_WIDTH (f); - int new_width = check_int_nonnegative (arg); + int border; - if (new_width == old_width) - return; - f->child_frame_border_width = new_width; + if (NILP (arg)) + border = -1; + else if (RANGED_FIXNUMP (0, arg, INT_MAX)) + border = XFIXNAT (arg); + else + signal_error ("Invalid child frame border width", arg); - if (FRAME_NATIVE_WINDOW (f) != 0) - adjust_frame_size (f, -1, -1, 3, 0, Qchild_frame_border_width); + if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f)) + { + f->child_frame_border_width = border; - SET_FRAME_GARBAGED (f); + if (FRAME_NATIVE_WINDOW (f) != 0) + adjust_frame_size (f, -1, -1, 3, 0, Qchild_frame_border_width); + + SET_FRAME_GARBAGED (f); + } } static void @@ -1213,7 +1220,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side. gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (2), "internalBorderWidth", "InternalBorderWidth", RES_TYPE_NUMBER); - gui_default_parameter (f, parms, Qchild_frame_border_width, make_fixnum (2), + gui_default_parameter (f, parms, Qchild_frame_border_width, Qnil, "childFrameBorderWidth", "childFrameBorderWidth", RES_TYPE_NUMBER); gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0), diff --git a/src/w32fns.c b/src/w32fns.c index 5704f1d3c3..86c3db64e7 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -1561,8 +1561,14 @@ w32_clear_under_internal_border (struct frame *f) static void w32_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { - int argval = check_integer_range (arg, INT_MIN, INT_MAX); - int border = max (argval, 0); + int border; + + if (NILP (arg)) + border = -1; + else if (RANGED_FIXNUMP (0, arg, INT_MAX)) + border = XFIXNAT (arg); + else + signal_error ("Invalid child frame border width", arg); if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f)) { @@ -5896,37 +5902,33 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, Lisp_Object value; value = gui_display_get_arg (dpyinfo, parameters, Qinternal_border_width, - "internalBorder", "InternalBorder", + "internalBorder", "internalBorder", RES_TYPE_NUMBER); if (! EQ (value, Qunbound)) parameters = Fcons (Fcons (Qinternal_border_width, value), parameters); } + gui_default_parameter (f, parameters, Qinternal_border_width, make_fixnum (0), + "internalBorderWidth", "internalBorderWidth", + RES_TYPE_NUMBER); + /* Same for child frames. */ if (NILP (Fassq (Qchild_frame_border_width, parameters))) { Lisp_Object value; value = gui_display_get_arg (dpyinfo, parameters, Qchild_frame_border_width, - "childFrameBorderWidth", "childFrameBorderWidth", + "childFrameBorder", "childFrameBorder", RES_TYPE_NUMBER); - if (! EQ (value, Qunbound)) + if (!EQ (value, Qunbound)) parameters = Fcons (Fcons (Qchild_frame_border_width, value), parameters); - } - gui_default_parameter (f, parameters, Qchild_frame_border_width, -#ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */ - make_fixnum (0), -#else - make_fixnum (1), -#endif + gui_default_parameter (f, parameters, Qchild_frame_border_width, Qnil, "childFrameBorderWidth", "childFrameBorderWidth", RES_TYPE_NUMBER); - gui_default_parameter (f, parameters, Qinternal_border_width, make_fixnum (0), - "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER); gui_default_parameter (f, parameters, Qright_divider_width, make_fixnum (0), NULL, NULL, RES_TYPE_NUMBER); gui_default_parameter (f, parameters, Qbottom_divider_width, make_fixnum (0), diff --git a/src/xfns.c b/src/xfns.c index cac41ee485..481ee0e225 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -1803,7 +1803,14 @@ x_change_tool_bar_height (struct frame *f, int height) static void x_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { - int border = check_int_nonnegative (arg); + int border; + + if (NILP (arg)) + border = -1; + else if (RANGED_FIXNUMP (0, arg, INT_MAX)) + border = XFIXNAT (arg); + else + signal_error ("Invalid child frame border width", arg); if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f)) { @@ -3920,36 +3927,31 @@ This function is an internal primitive--use `make-frame' instead. */) parms); } + gui_default_parameter (f, parms, Qinternal_border_width, +#ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */ + make_fixnum (0), +#else + make_fixnum (1), +#endif + "internalBorderWidth", "internalBorderWidth", + RES_TYPE_NUMBER); + /* Same for child frames. */ if (NILP (Fassq (Qchild_frame_border_width, parms))) { Lisp_Object value; value = gui_display_get_arg (dpyinfo, parms, Qchild_frame_border_width, - "childFrameBorderWidth", "childFrameBorderWidth", + "childFrameBorder", "childFrameBorder", RES_TYPE_NUMBER); if (! EQ (value, Qunbound)) parms = Fcons (Fcons (Qchild_frame_border_width, value), parms); - } - gui_default_parameter (f, parms, Qchild_frame_border_width, -#ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */ - make_fixnum (0), -#else - make_fixnum (1), -#endif + gui_default_parameter (f, parms, Qchild_frame_border_width, Qnil, "childFrameBorderWidth", "childFrameBorderWidth", RES_TYPE_NUMBER); - gui_default_parameter (f, parms, Qinternal_border_width, -#ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */ - make_fixnum (0), -#else - make_fixnum (1), -#endif - "internalBorderWidth", "internalBorderWidth", - RES_TYPE_NUMBER); gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0), NULL, NULL, RES_TYPE_NUMBER); gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0), commit c0d504eb7e0922be9f9ec6d9b7f1a27c5fc31b33 Merge: fdc56b5d56 8ad48a0bdd Author: Glenn Morris Date: Sat Feb 6 08:10:38 2021 -0800 Merge from origin/emacs-27 8ad48a0bdd (origin/emacs-27) Improve doc string of 'text-scale-adjust' 7a25ff767d Clarify the indent-rigidly doc string 6c5ddf0e0b Fix two small tab bar issues c71e08eba9 Fix last change in syntax.texi # Conflicts: # lisp/indent.el commit fdc56b5d567b2e5aac017582a75b34351d53b867 Merge: 3c0f86312e 43bf7f1b06 Author: Glenn Morris Date: Sat Feb 6 08:05:30 2021 -0800 ; Merge from origin/emacs-27 The following commit was skipped: 43bf7f1b06 Correct the lispref manual about flushing ppss info commit 3c0f86312eda9a9afb91a3c3979fcc2b779eeb7b Merge: 7a960251b3 8c27af3ff4 Author: Glenn Morris Date: Sat Feb 6 08:05:29 2021 -0800 Merge from origin/emacs-27 8c27af3ff4 Clarify how transient indentation modes are exited in the ... fc37dc298f Fix the previous change commit 7a960251b3f836254aee83977dffca2540e091db Merge: c4a6f81ca4 b99848c72c Author: Glenn Morris Date: Sat Feb 6 08:05:29 2021 -0800 ; Merge from origin/emacs-27 The following commits were skipped: b99848c72c Bind default-directory to the project root 19534f988c Make sure default-directory relates to the originating buffer d1455027e0 Initialize signal descriptions after pdumping 256356a36f Clarify the "Sentinels" node in the lispref manual 89f1634afc Fix problem with non-ASCII characters in nnmaildir commit c4a6f81ca4405a91ba04797ec5aced98c3c6decf Author: Lars Ingebrigtsen Date: Sat Feb 6 15:04:52 2021 +0100 Fix previous change in testcover.el * lisp/emacs-lisp/testcover.el (testcover-analyze-coverage-edebug-after): The wrapper macro is called `1value', not `testcover-1value'. diff --git a/lisp/emacs-lisp/testcover.el b/lisp/emacs-lisp/testcover.el index 50f2b51637..75b27d08e5 100644 --- a/lisp/emacs-lisp/testcover.el +++ b/lisp/emacs-lisp/testcover.el @@ -516,7 +516,7 @@ form to be treated accordingly." (aset testcover-vector before-id 'edebug-ok-coverage)) (setq val (testcover-analyze-coverage-wrapped-form wrapped-form)) - (when (or (eq wrapper 'testcover-1value) val) + (when (or (eq wrapper '1value) val) ;; The form is 1-valued or potentially 1-valued. (aset testcover-vector after-id (or val 'testcover-1value))) @@ -529,7 +529,7 @@ form to be treated accordingly." (aset testcover-vector after-id 'testcover-1value) (setq val 'testcover-1value)) - ((eq (car-safe wrapped-form) 'testcover-1value) + ((eq (car-safe wrapped-form) '1value) ;; This function is always supposed to return the same value. (setq val 'testcover-1value) (aset testcover-vector after-id 'testcover-1value))) @@ -586,9 +586,9 @@ FORM is treated as if it will be evaluated." ;; depending on the symbol. (let ((temp-form (cons func args))) (testcover-analyze-coverage-wrapped-form temp-form))) - (`(,(and func (or 'testcover-1value 'noreturn)) ,inner-form) + (`(,(and func (or '1value 'noreturn)) ,inner-form) ;; 1value and noreturn change how the edebug-after they wrap is handled. - (let ((val (if (eq func 'testcover-1value) 'testcover-1value 'maybe))) + (let ((val (if (eq func '1value) '1value 'maybe))) (pcase inner-form (`(edebug-after ,(and before-form (or `(edebug-before ,before-id) before-id)) commit 1e0632e772f43ba7fd2aca180ee041bf3571d43f Merge: f534d3fdac 5903db0c20 Author: Eli Zaretskii Date: Sat Feb 6 15:11:29 2021 +0200 Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs commit f534d3fdacb3d6114a0ebdc8df2723265339db5d Author: Eli Zaretskii Date: Sat Feb 6 15:09:32 2021 +0200 Support file names with whitespace in Nroff mode * lisp/textmodes/nroff-mode.el (nroff-view): Quote argument of 'Man-getpage-in-background' to support file names with special characters. (Bug#46051) diff --git a/lisp/textmodes/nroff-mode.el b/lisp/textmodes/nroff-mode.el index fe70e925b0..e7d852be3c 100644 --- a/lisp/textmodes/nroff-mode.el +++ b/lisp/textmodes/nroff-mode.el @@ -316,7 +316,7 @@ otherwise off." (save-buffer)) (if viewbuf (kill-buffer viewbuf)) - (Man-getpage-in-background file))) + (Man-getpage-in-background (shell-quote-argument file)))) (provide 'nroff-mode) commit 5903db0c2049c588f6b15717a8f9bd4c6a6f46a4 Author: Lars Ingebrigtsen Date: Sat Feb 6 13:54:33 2021 +0100 Tweak provided-mode-derived-p doc string * lisp/subr.el (provided-mode-derived-p): Remove detail about "or their aliases", since that seems self-evident (bug#46331) (and derived-mode-p works the same, and doesn't have the bit in question). diff --git a/lisp/subr.el b/lisp/subr.el index c1624aa9c0..f0de6d5ac9 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2228,7 +2228,7 @@ Affects only hooks run in the current buffer." ;; PUBLIC: find if the current mode derives from another. (defun provided-mode-derived-p (mode &rest modes) - "Non-nil if MODE is derived from one of MODES or their aliases. + "Non-nil if MODE is derived from one of MODES. Uses the `derived-mode-parent' property of the symbol to trace backwards. If you just want to check `major-mode', use `derived-mode-p'." ;; If MODE is an alias, then look up the real mode function first. commit 8ad48a0bdd0806fe3bfbabf00c845381d9107cb0 Author: Eli Zaretskii Date: Sat Feb 6 14:31:51 2021 +0200 Improve doc string of 'text-scale-adjust' * lisp/face-remap.el (text-scale-adjust): Clarify that "default face height" refers to the 'default' face. (Bug#25168) diff --git a/lisp/face-remap.el b/lisp/face-remap.el index 49b01d02a3..6c3f4082fd 100644 --- a/lisp/face-remap.el +++ b/lisp/face-remap.el @@ -325,9 +325,9 @@ INC may be passed as a numeric prefix argument. The actual adjustment made depends on the final component of the key-binding used to invoke the command, with all modifiers removed: - +, = Increase the default face height by one step - - Decrease the default face height by one step - 0 Reset the default face height to the global default + +, = Increase the height of the default face by one step + - Decrease the height of the default face by one step + 0 Reset the height of the default face to the global default After adjusting, continue to read input events and further adjust the face height as long as the input event read commit 0100e33f83eaf1e6698c168c4118cf84a1792496 Author: Lars Ingebrigtsen Date: Sat Feb 6 13:26:25 2021 +0100 Warn in message.el when sending encryptable mail * lisp/gnus/message.el (message-send): Query if it looks like encryption was intended, but is not going to happen. * lisp/gnus/mml-sec.el (mml-secure-is-encrypted-p): Allow saying whether there's any <#secure tags present (bug#24411). diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 6668784f93..5a5dbcebc1 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -4315,6 +4315,10 @@ It should typically alter the sending method in some way or other." (when message-confirm-send (or (y-or-n-p "Send message? ") (keyboard-quit))) + (when (and (not (mml-secure-is-encrypted-p)) + (mml-secure-is-encrypted-p 'anywhere) + (not (yes-or-no-p "This message has a <#secure tag, but is not going to be encrypted. Send anyway?"))) + (error "Aborting sending")) (message message-sending-message) (let ((alist message-send-method-alist) (success t) diff --git a/lisp/gnus/mml-sec.el b/lisp/gnus/mml-sec.el index 8d01d15ca0..d41c9dd0d9 100644 --- a/lisp/gnus/mml-sec.el +++ b/lisp/gnus/mml-sec.el @@ -298,14 +298,17 @@ Use METHOD if given. Else use `mml-secure-method' or (interactive) (mml-secure-part "smime")) -(defun mml-secure-is-encrypted-p () - "Check whether secure encrypt tag is present." +(defun mml-secure-is-encrypted-p (&optional tag-present) + "Whether the current buffer contains a mail message that should be encrypted. +If TAG-PRESENT, say whether the <#secure tag is present anywhere +in the buffer." (save-excursion (goto-char (point-min)) - (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "\n" - "<#secure[^>]+encrypt") - nil t))) + (message-goto-body) + (if tag-present + (re-search-forward "<#secure[^>]+encrypt" nil t) + (skip-chars-forward "[ \t\n") + (looking-at "<#secure[^>]+encrypt")))) (defun mml-secure-bcc-is-safe () "Check whether usage of Bcc is safe (or absent). commit cf0869d22bc62ae255bf5f824a02c92878c5c6cc Author: Lars Ingebrigtsen Date: Sat Feb 6 12:28:46 2021 +0100 Rename the `1value' symbol in testcover.el * lisp/emacs-lisp/testcover.el: Rename the symbol `1value' throughout the file to `testcover-1value' to allow using the variable in code that's to be tested (bug#25471). diff --git a/lisp/emacs-lisp/testcover.el b/lisp/emacs-lisp/testcover.el index 312e38769c..50f2b51637 100644 --- a/lisp/emacs-lisp/testcover.el +++ b/lisp/emacs-lisp/testcover.el @@ -258,10 +258,10 @@ vector. Return VALUE." (aset testcover-vector after-index (testcover--copy-object value))) ((eq 'maybe old-result) (aset testcover-vector after-index 'edebug-ok-coverage)) - ((eq '1value old-result) + ((eq 'testcover-1value old-result) (aset testcover-vector after-index (cons old-result (testcover--copy-object value)))) - ((and (eq (car-safe old-result) '1value) + ((and (eq (car-safe old-result) 'testcover-1value) (not (condition-case () (equal (cdr old-result) value) (circular-list t)))) @@ -358,11 +358,11 @@ eliminated by adding more test cases." data (aref coverage len)) (when (and (not (eq data 'edebug-ok-coverage)) (not (memq (car-safe data) - '(1value maybe noreturn))) + '(testcover-1value maybe noreturn))) (setq j (+ def-mark (aref points len)))) (setq ov (make-overlay (1- j) j)) (overlay-put ov 'face - (if (memq data '(edebug-unknown maybe 1value)) + (if (memq data '(edebug-unknown maybe testcover-1value)) 'testcover-nohits 'testcover-1value)))) (set-buffer-modified-p changed)))) @@ -450,12 +450,12 @@ or return multiple values." (`(defconst ,sym . ,args) (push sym testcover-module-constants) (testcover-analyze-coverage-progn args) - '1value) + 'testcover-1value) (`(defun ,name ,_ . ,doc-and-body) (let ((val (testcover-analyze-coverage-progn doc-and-body))) (cl-case val - ((1value) (push name testcover-module-1value-functions)) + ((testcover-1value) (push name testcover-module-1value-functions)) ((maybe) (push name testcover-module-potentially-1value-functions))) nil)) @@ -466,13 +466,13 @@ or return multiple values." ;; To avoid infinite recursion, don't examine quoted objects. ;; This will cause the coverage marks on an instrumented quoted ;; form to look odd. See bug#25316. - '1value) + 'testcover-1value) (`(\` ,bq-form) (testcover-analyze-coverage-backquote-form bq-form)) ((or 't 'nil (pred keywordp)) - '1value) + 'testcover-1value) ((pred vectorp) (testcover-analyze-coverage-compose (append form nil) @@ -482,7 +482,7 @@ or return multiple values." nil) ((pred atom) - '1value) + 'testcover-1value) (_ ;; Whatever we have here, it's not wrapped, so treat it as a list of forms. @@ -494,7 +494,7 @@ Analyze all the forms in FORMS and return 1value, maybe or nil depending on the analysis of the last one. Find the coverage vectors referenced by `edebug-enter' forms nested within FORMS and update them with the results of the analysis." - (let ((result '1value)) + (let ((result 'testcover-1value)) (while (consp forms) (setq result (testcover-analyze-coverage (pop forms)))) result)) @@ -516,9 +516,9 @@ form to be treated accordingly." (aset testcover-vector before-id 'edebug-ok-coverage)) (setq val (testcover-analyze-coverage-wrapped-form wrapped-form)) - (when (or (eq wrapper '1value) val) + (when (or (eq wrapper 'testcover-1value) val) ;; The form is 1-valued or potentially 1-valued. - (aset testcover-vector after-id (or val '1value))) + (aset testcover-vector after-id (or val 'testcover-1value))) (cond ((or (eq wrapper 'noreturn) @@ -526,13 +526,13 @@ form to be treated accordingly." ;; This function won't return, so indicate to testcover-before that ;; it should record coverage. (aset testcover-vector before-id (cons 'noreturn after-id)) - (aset testcover-vector after-id '1value) - (setq val '1value)) + (aset testcover-vector after-id 'testcover-1value) + (setq val 'testcover-1value)) - ((eq (car-safe wrapped-form) '1value) + ((eq (car-safe wrapped-form) 'testcover-1value) ;; This function is always supposed to return the same value. - (setq val '1value) - (aset testcover-vector after-id '1value))) + (setq val 'testcover-1value) + (aset testcover-vector after-id 'testcover-1value))) val)) (defun testcover-analyze-coverage-wrapped-form (form) @@ -540,26 +540,26 @@ form to be treated accordingly." FORM is treated as if it will be evaluated." (pcase form ((pred keywordp) - '1value) + 'testcover-1value) ((pred symbolp) (when (or (memq form testcover-constants) (memq form testcover-module-constants)) - '1value)) + 'testcover-1value)) ((pred atom) - '1value) + 'testcover-1value) (`(\` ,bq-form) (testcover-analyze-coverage-backquote-form bq-form)) (`(defconst ,sym ,val . ,_) (push sym testcover-module-constants) (testcover-analyze-coverage val) - '1value) + 'testcover-1value) (`(,(or 'dotimes 'dolist) (,_ ,expr . ,result) . ,body) ;; These always return RESULT if provided. (testcover-analyze-coverage expr) (testcover-analyze-coverage-progn body) (let ((val (testcover-analyze-coverage-progn result))) ;; If the third value is not present, the loop always returns nil. - (if result val '1value))) + (if result val 'testcover-1value))) (`(,(or 'let 'let*) ,bindings . ,body) (testcover-analyze-coverage-progn bindings) (testcover-analyze-coverage-progn body)) @@ -586,9 +586,9 @@ FORM is treated as if it will be evaluated." ;; depending on the symbol. (let ((temp-form (cons func args))) (testcover-analyze-coverage-wrapped-form temp-form))) - (`(,(and func (or '1value 'noreturn)) ,inner-form) + (`(,(and func (or 'testcover-1value 'noreturn)) ,inner-form) ;; 1value and noreturn change how the edebug-after they wrap is handled. - (let ((val (if (eq func '1value) '1value 'maybe))) + (let ((val (if (eq func 'testcover-1value) 'testcover-1value 'maybe))) (pcase inner-form (`(edebug-after ,(and before-form (or `(edebug-before ,before-id) before-id)) @@ -604,12 +604,12 @@ FORM is treated as if it will be evaluated." (defun testcover-analyze-coverage-wrapped-application (func args) "Analyze the application of FUNC to ARGS for code coverage." (cond - ((eq func 'quote) '1value) + ((eq func 'quote) 'testcover-1value) ((or (memq func testcover-1value-functions) (memq func testcover-module-1value-functions)) ;; The function should always return the same value. (testcover-analyze-coverage-progn args) - '1value) + 'testcover-1value) ((or (memq func testcover-potentially-1value-functions) (memq func testcover-module-potentially-1value-functions)) ;; The function might always return the same value. @@ -635,14 +635,14 @@ If either argument is nil, return nil, otherwise if either argument is maybe, return maybe. Return 1value only if both arguments are 1value." (cl-case val - (1value result) + (testcover-1value result) (maybe (and result 'maybe)) (nil nil))) (defun testcover-analyze-coverage-compose (forms func) "Analyze a list of FORMS for code coverage using FUNC. The list is 1valued if all of its constituent elements are also 1valued." - (let ((result '1value)) + (let ((result 'testcover-1value)) (while (consp forms) (setq result (testcover-coverage-combine result (funcall func (car forms)))) (setq forms (cdr forms))) @@ -652,7 +652,7 @@ The list is 1valued if all of its constituent elements are also 1valued." (defun testcover-analyze-coverage-backquote (bq-list) "Analyze BQ-LIST, the body of a backquoted list, for code coverage." - (let ((result '1value)) + (let ((result 'testcover-1value)) (while (consp bq-list) (let ((form (car bq-list)) val) @@ -670,7 +670,7 @@ The list is 1valued if all of its constituent elements are also 1valued." "Analyze a single FORM from a backquoted list for code coverage." (cond ((vectorp form) (testcover-analyze-coverage-backquote (append form nil))) - ((atom form) '1value) + ((atom form) 'testcover-1value) ((memq (car form) (list '\, '\,@)) (testcover-analyze-coverage (cadr form))) (t (testcover-analyze-coverage-backquote form)))) commit 2476abc1f24f1b2385648cfb08cd9f178422497d Author: Lars Ingebrigtsen Date: Sat Feb 6 12:03:43 2021 +0100 Allow provided-mode-derived-p to work on aliases * lisp/subr.el (provided-mode-derived-p): Allow this to work on modes that are aliases of other modes (bug#46331). For instance: (provided-mode-derived-p 'javascript-mode 'prog-mode) diff --git a/lisp/subr.el b/lisp/subr.el index 6e52bd20df..c1624aa9c0 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2231,6 +2231,10 @@ Affects only hooks run in the current buffer." "Non-nil if MODE is derived from one of MODES or their aliases. Uses the `derived-mode-parent' property of the symbol to trace backwards. If you just want to check `major-mode', use `derived-mode-p'." + ;; If MODE is an alias, then look up the real mode function first. + (when-let ((alias (symbol-function mode))) + (when (symbolp alias) + (setq mode alias))) (while (and (not (memq mode modes)) commit 23a7da9148c84dbcc228dda37c9bcebfc2a004d2 Author: Michael Albinus Date: Sat Feb 6 11:50:55 2021 +0100 Modernize use of prompts in auth-source.el * lisp/auth-source.el (auth-source-search): Adapt docstring (auth-source-format-prompt): Remove trailing ": ". (auth-source-netrc-create, auth-source-secrets-create) (auth-source-plstore-create): Adapt prompts. Use `format-prompt'. Do not ask interactively if `auth-source-save-behavior' is nil. diff --git a/lisp/auth-source.el b/lisp/auth-source.el index 2494040457..14cae8a52c 100644 --- a/lisp/auth-source.el +++ b/lisp/auth-source.el @@ -581,14 +581,15 @@ default value. If the user, host, or port are missing, the alist `auth-source-creation-prompts' will be used to look up the prompts IN THAT ORDER (so the `user' prompt will be queried first, then `host', then `port', and finally `secret'). Each prompt string -can use %u, %h, and %p to show the user, host, and port. +can use %u, %h, and %p to show the user, host, and port. The prompt +is formatted with `format-prompt', a trailing \": \" is removed. Here's an example: \(let ((auth-source-creation-defaults \\='((user . \"defaultUser\") (A . \"default A\"))) (auth-source-creation-prompts - \\='((secret . \"Enter IMAP password for %h:%p: \")))) + \\='((secret . \"Enter IMAP password for %h:%p\")))) (auth-source-search :host \\='(\"nonesuch\" \"twosuch\") :type \\='netrc :max 1 :P \"pppp\" :Q \"qqqq\" :create \\='(A B Q))) @@ -860,7 +861,9 @@ while \(:host t) would find all host entries." secret))) (defun auth-source-format-prompt (prompt alist) - "Format PROMPT using %x (for any character x) specifiers in ALIST." + "Format PROMPT using %x (for any character x) specifiers in ALIST. +Remove trailing \": \"." + (setq prompt (replace-regexp-in-string ":\\s-*$" "" prompt)) (dolist (cell alist) (let ((c (nth 0 cell)) (v (nth 1 cell))) @@ -1344,11 +1347,11 @@ See `auth-source-search' for details on SPEC." "[any port]")))) (prompt (or (auth-source--aget auth-source-creation-prompts r) (cl-case r - (secret "%p password for %u@%h: ") - (user "%p user name for %h: ") - (host "%p host name for user %u: ") - (port "%p port for %u@%h: ")) - (format "Enter %s (%%u@%%h:%%p): " r))) + (secret "%p password for %u@%h") + (user "%p user name for %h") + (host "%p host name for user %u") + (port "%p port for %u@%h")) + (format "Enter %s (%%u@%%h:%%p)" r))) (prompt (auth-source-format-prompt prompt `((?u ,(auth-source--aget printable-defaults 'user)) @@ -1378,7 +1381,9 @@ See `auth-source-search' for details on SPEC." (setq check nil))) ret)) (t 'never))) - (plain (or (eval default) (read-passwd prompt)))) + (plain + (or (eval default) + (read-passwd (format-prompt prompt nil))))) ;; ask if we don't know what to do (in which case ;; auth-source-netrc-use-gpg-tokens must be a list) (unless gpg-encrypt @@ -1390,12 +1395,9 @@ See `auth-source-search' for details on SPEC." (if (eq gpg-encrypt 'gpg) (auth-source-epa-make-gpg-token plain file) plain)) - (if (stringp default) - (read-string (if (string-match ": *\\'" prompt) - (concat (substring prompt 0 (match-beginning 0)) - " (default " default "): ") - (concat prompt "(default " default ") ")) - nil nil default) + (if (and (stringp default) auth-source-save-behavior) + (read-string + (format-prompt prompt default) nil nil default) (eval default))))) (when data @@ -1745,12 +1747,12 @@ authentication tokens: "[any label]")))) (prompt (or (auth-source--aget auth-source-creation-prompts r) (cl-case r - (secret "%p password for %u@%h: ") - (user "%p user name for %h: ") - (host "%p host name for user %u: ") - (port "%p port for %u@%h: ") - (label "Enter label for %u@%h: ")) - (format "Enter %s (%%u@%%h:%%p): " r))) + (secret "%p password for %u@%h") + (user "%p user name for %h") + (host "%p host name for user %u") + (port "%p port for %u@%h") + (label "Enter label for %u@%h")) + (format "Enter %s (%%u@%%h:%%p)" r))) (prompt (auth-source-format-prompt prompt `((?u ,(auth-source--aget printable-defaults 'user)) @@ -1760,13 +1762,11 @@ authentication tokens: ;; Store the data, prompting for the password if needed. (setq data (or data (if (eq r 'secret) - (or (eval default) (read-passwd prompt)) - (if (stringp default) - (read-string (if (string-match ": *\\'" prompt) - (concat (substring prompt 0 (match-beginning 0)) - " (default " default "): ") - (concat prompt "(default " default ") ")) - nil nil default) + (or (eval default) + (read-passwd (format-prompt prompt nil))) + (if (and (stringp default) auth-source-save-behavior) + (read-string + (format-prompt prompt default) nil nil default) (eval default))))) (when data @@ -2190,11 +2190,11 @@ entries for git.gnus.org: "[any port]")))) (prompt (or (auth-source--aget auth-source-creation-prompts r) (cl-case r - (secret "%p password for %u@%h: ") - (user "%p user name for %h: ") - (host "%p host name for user %u: ") - (port "%p port for %u@%h: ")) - (format "Enter %s (%%u@%%h:%%p): " r))) + (secret "%p password for %u@%h") + (user "%p user name for %h") + (host "%p host name for user %u") + (port "%p port for %u@%h")) + (format "Enter %s (%%u@%%h:%%p)" r))) (prompt (auth-source-format-prompt prompt `((?u ,(auth-source--aget printable-defaults 'user)) @@ -2204,14 +2204,11 @@ entries for git.gnus.org: ;; Store the data, prompting for the password if needed. (setq data (or data (if (eq r 'secret) - (or (eval default) (read-passwd prompt)) - (if (stringp default) + (or (eval default) + (read-passwd (format-prompt prompt nil))) + (if (and (stringp default) auth-source-save-behavior) (read-string - (if (string-match ": *\\'" prompt) - (concat (substring prompt 0 (match-beginning 0)) - " (default " default "): ") - (concat prompt "(default " default ") ")) - nil nil default) + (format-prompt prompt default) nil nil default) (eval default))))) (when data commit 7a25ff767df7a323898a59531a1c518b1bc28699 Author: Lars Ingebrigtsen Date: Sat Feb 6 11:46:58 2021 +0100 Clarify the indent-rigidly doc string * lisp/indent.el (indent-rigidly): Clarify exiting the transient mode (bug#46296). diff --git a/lisp/indent.el b/lisp/indent.el index ea71e88b8b..ed67e1c16f 100644 --- a/lisp/indent.el +++ b/lisp/indent.el @@ -212,7 +212,8 @@ It is activated by calling `indent-rigidly' interactively.") If called interactively with no prefix argument, activate a transient mode in which the indentation can be adjusted interactively by typing \\\\[indent-rigidly-left], \\[indent-rigidly-right], \\[indent-rigidly-left-to-tab-stop], or \\[indent-rigidly-right-to-tab-stop]. -Typing any other key deactivates the transient mode. +Typing any other key deactivates the transient mode, and this key is then +acted upon as normally. If called from a program, or interactively with prefix ARG, indent all lines starting in the region forward by ARG columns. commit 293264623235fdcf672eec3f8e88e4ec7e1182e4 Author: Lars Ingebrigtsen Date: Sat Feb 6 11:40:00 2021 +0100 Fix problem when ~/.mailcap had several entries for a MIME type * lisp/net/mailcap.el (mailcap-mime-info): Use all the matching entries from ~/.mailcap, not just the first (bug#46318). diff --git a/lisp/net/mailcap.el b/lisp/net/mailcap.el index 455673b5e9..b95cd0febc 100644 --- a/lisp/net/mailcap.el +++ b/lisp/net/mailcap.el @@ -842,11 +842,11 @@ If NO-DECODE is non-nil, don't decode STRING." ;; ~/.mailcap file, then we filter out the system entries ;; and see whether we have anything left. (when mailcap-prefer-mailcap-viewers - (when-let ((user-entry - (seq-find (lambda (elem) - (eq (cdr (assq 'source elem)) 'user)) - passed))) - (setq passed (list user-entry)))) + (when-let ((user-entries + (seq-filter (lambda (elem) + (eq (cdr (assq 'source elem)) 'user)) + passed))) + (setq passed user-entries))) (setq viewer (car passed)))) (when (and (stringp (cdr (assq 'viewer viewer))) passed) commit f853f2d42829326ef3606411e751b921e8ffed24 Author: Lars Ingebrigtsen Date: Sat Feb 6 11:31:08 2021 +0100 Avoid a compilation warning in iter-do * lisp/emacs-lisp/generator.el (iter-do): Avoid a compilation warning on using variables marked for not using (bug#31641). Eg. (iter-do (_ i)) diff --git a/lisp/emacs-lisp/generator.el b/lisp/emacs-lisp/generator.el index 9eb6d95964..e45260c32a 100644 --- a/lisp/emacs-lisp/generator.el +++ b/lisp/emacs-lisp/generator.el @@ -725,17 +725,20 @@ Return the value with which ITERATOR finished iteration." (condition-symbol (cps--gensym "iter-do-condition")) (it-symbol (cps--gensym "iter-do-iterator")) (result-symbol (cps--gensym "iter-do-result"))) - `(let (,var - ,result-symbol + `(let (,result-symbol (,done-symbol nil) (,it-symbol ,iterator)) - (while (not ,done-symbol) - (condition-case ,condition-symbol - (setf ,var (iter-next ,it-symbol)) - (iter-end-of-sequence - (setf ,result-symbol (cdr ,condition-symbol)) - (setf ,done-symbol t))) - (unless ,done-symbol ,@body)) + (while + (let ((,var + (condition-case ,condition-symbol + (iter-next ,it-symbol) + (iter-end-of-sequence + (setf ,result-symbol (cdr ,condition-symbol)) + (setf ,done-symbol t))))) + (unless ,done-symbol + ,@body + ;; Loop until done-symbol is set. + t))) ,result-symbol))) (defvar cl--loop-args) commit b84b8dff709fd80ee124565222f333f53351ab4a Author: Eli Zaretskii Date: Sat Feb 6 11:54:08 2021 +0200 Fix copying text properties in 'format' * src/editfns.c (styled_format): Fix accounting for text properties that come from the format string. (Bug#46317) * test/src/editfns-tests.el (format-properties): Add new tests for bug#46317. diff --git a/src/editfns.c b/src/editfns.c index e3285494c1..991f79abac 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -3134,6 +3134,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) char *format_start = SSDATA (args[0]); bool multibyte_format = STRING_MULTIBYTE (args[0]); ptrdiff_t formatlen = SBYTES (args[0]); + bool fmt_props = string_intervals (args[0]); /* Upper bound on number of format specs. Each uses at least 2 chars. */ ptrdiff_t nspec_bound = SCHARS (args[0]) >> 1; @@ -3406,13 +3407,20 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) convbytes += padding; if (convbytes <= buf + bufsize - p) { + /* If the format spec has properties, we should account + for the padding on the left in the info[] array. */ + if (fmt_props) + spec->start = nchars; if (! minus_flag) { memset (p, ' ', padding); p += padding; nchars += padding; } - spec->start = nchars; + /* If the properties will come from the argument, we + don't extend them to the left due to padding. */ + if (!fmt_props) + spec->start = nchars; if (p > buf && multibyte diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el index 64f9137865..dcec971c12 100644 --- a/test/src/editfns-tests.el +++ b/test/src/editfns-tests.el @@ -106,7 +106,27 @@ #("foobar" 3 6 (face error)))) (should (ert-equal-including-properties (format (concat "%s " (propertize "%s" 'face 'error)) "foo" "bar") - #("foo bar" 4 7 (face error))))) + #("foo bar" 4 7 (face error)))) + ;; Bug #46317 + (let ((s (propertize "X" 'prop "val"))) + (should (ert-equal-including-properties + (format (concat "%3s/" s) 12) + #(" 12/X" 4 5 (prop "val")))) + (should (ert-equal-including-properties + (format (concat "%3S/" s) 12) + #(" 12/X" 4 5 (prop "val")))) + (should (ert-equal-including-properties + (format (concat "%3d/" s) 12) + #(" 12/X" 4 5 (prop "val")))) + (should (ert-equal-including-properties + (format (concat "%-3s/" s) 12) + #("12 /X" 4 5 (prop "val")))) + (should (ert-equal-including-properties + (format (concat "%-3S/" s) 12) + #("12 /X" 4 5 (prop "val")))) + (should (ert-equal-including-properties + (format (concat "%-3d/" s) 12) + #("12 /X" 4 5 (prop "val")))))) ;; Tests for bug#5131. (defun transpose-test-reverse-word (start end) commit 6c5ddf0e0bc4e3e3ed819835f00419b7289d33c7 Author: Martin Rudalics Date: Sat Feb 6 09:28:40 2021 +0100 Fix two small tab bar issues * lisp/cus-start.el (frame-inhibit-implied-resize): Update version tag. * lisp/frame.el (frame-inner-height): Do not count in tab bar. diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 4b7c386306..b7f0d7e2a8 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -336,7 +336,7 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of (const :tag "Never" nil) (const :tag "Always" t) (repeat (symbol :tag "Parameter"))) - "25.1") + "27.1") (iconify-child-frame frames (choice (const :tag "Do nothing" nil) diff --git a/lisp/frame.el b/lisp/frame.el index 7f1b8af919..15e46c9e21 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -1344,6 +1344,7 @@ FRAME defaults to the selected frame." FRAME defaults to the selected frame." (setq frame (window-normalize-frame frame)) (- (frame-native-height frame) + (tab-bar-height frame t) (* 2 (frame-internal-border-width frame)))) (defun frame-outer-width (&optional frame) commit 431b098a206d27a2dff6a88312c28c36926f90e9 Author: Stefan Monnier Date: Fri Feb 5 15:07:47 2021 -0500 * lisp/emacs-lisp/pcase.el (let): Reimplement as a pcase macro (pcase--macroexpand, pcase--u1): Remove handling of `let` from `pcase`s core. diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index cf129c453e..ec746fa474 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -135,7 +135,6 @@ PATTERN matches. PATTERN can take one of the forms: (pred (not FUN)) matches if FUN called on EXPVAL returns nil. (app FUN PAT) matches if FUN called on EXPVAL matches PAT. (guard BOOLEXP) matches if BOOLEXP evaluates to non-nil. - (let PAT EXPR) matches if EXPR matches PAT. (and PAT...) matches if all the patterns match. (or PAT...) matches if any of the patterns matches. @@ -145,7 +144,7 @@ FUN in `pred' and `app' can take one of the forms: (F ARG1 .. ARGn) call F with ARG1..ARGn and EXPVAL as n+1'th argument -FUN, BOOLEXP, EXPR, and subsequent PAT can refer to variables +FUN, BOOLEXP, and subsequent PAT can refer to variables bound earlier in the pattern by a SYMBOL pattern. Additional patterns can be defined using `pcase-defmacro'. @@ -426,7 +425,6 @@ of the elements of LIST is performed as if by `pcase-let'. (if (pcase--self-quoting-p pat) `',pat pat)) ((memq head '(pred guard quote)) pat) ((memq head '(or and)) `(,head ,@(mapcar #'pcase--macroexpand (cdr pat)))) - ((eq head 'let) `(let ,(pcase--macroexpand (cadr pat)) ,@(cddr pat))) ((eq head 'app) `(app ,(nth 1 pat) ,(pcase--macroexpand (nth 2 pat)))) (t (let* ((expander (pcase--get-macroexpander head)) @@ -888,18 +886,9 @@ Otherwise, it defers to REST which is a list of branches of the form (if (not (assq upat vars)) (pcase--u1 matches code (cons (cons upat sym) vars) rest) ;; Non-linear pattern. Turn it into an `eq' test. - (pcase--u1 (cons `(match ,sym . (pred (eq ,(cdr (assq upat vars))))) + (pcase--u1 (cons `(match ,sym . (pred (eql ,(cdr (assq upat vars))))) matches) code vars rest))) - ((eq (car-safe upat) 'let) - ;; A upat of the form (let VAR EXP). - ;; (pcase--u1 matches code - ;; (cons (cons (nth 1 upat) (nth 2 upat)) vars) rest) - (macroexp-let2 - macroexp-copyable-p sym - (pcase--eval (nth 2 upat) vars) - (pcase--u1 (cons (pcase--match sym (nth 1 upat)) matches) - code vars rest))) ((eq (car-safe upat) 'app) ;; A upat of the form (app FUN PAT) (pcase--mark-used sym) @@ -1011,5 +1000,9 @@ The predicate is the logical-AND of: ;; compounded values that are not `consp' (t (error "Unknown QPAT: %S" qpat)))) +(pcase-defmacro let (pat expr) + "Matches if EXPR matches PAT." + `(app (lambda (_) ,expr) ,pat)) + (provide 'pcase) ;;; pcase.el ends here commit a6f23c226e601d6682f057056fe4c7a069a9f69a Author: Eli Zaretskii Date: Fri Feb 5 22:04:15 2021 +0200 ; * src/xdisp.c (Fwindow_text_pixel_size): Fix comment. diff --git a/src/xdisp.c b/src/xdisp.c index 764735769b..1815f98678 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10780,8 +10780,8 @@ include the height of both, if present, in the return value. */) if (it.current_y > start_y) start_x = 0; - /* Subtract height of header-line which was counted automatically by - start_display. */ + /* Subtract height of header-line and tab-line which was counted + automatically by start_display. */ y = it.current_y + it.max_ascent + it.max_descent - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w); /* Don't return more than Y-LIMIT. */ commit 0484879d3b0f81222bacbc3c9655d1cfcdb5d321 Author: Eli Zaretskii Date: Fri Feb 5 16:27:51 2021 +0200 Fix 'C-d' on the first line in Rmail summary buffer * lisp/mail/rmailsum.el (rmail-summary-delete-forward): Fix deleting backward past the beginning of the summary buffer. (Bug#46325) diff --git a/lisp/mail/rmailsum.el b/lisp/mail/rmailsum.el index 7f99ecdcf2..f53e6e768f 100644 --- a/lisp/mail/rmailsum.el +++ b/lisp/mail/rmailsum.el @@ -930,10 +930,11 @@ a negative argument means to delete and move backward." (unless (numberp count) (setq count 1)) (let (del-msg (backward (< count 0))) - (while (and (/= count 0) - ;; Don't waste time if we are at the beginning - ;; and trying to go backward. - (not (and backward (bobp)))) + (while (/= count 0) + ;; Don't waste time counting down without doing anything if we + ;; are at the beginning and trying to go backward. + (if (and backward (bobp)) + (setq count -1)) (rmail-summary-goto-msg) (with-current-buffer rmail-buffer (setq del-msg rmail-current-message) commit d5b1deb62e7fe56ccd88348e885a589ff8098106 Author: Michael Albinus Date: Fri Feb 5 14:32:41 2021 +0100 Add command 'dbus-monitor' * doc/misc/dbus.texi: (Monitoring Messages): Document 'dbus-monitor'. * etc/NEWS: Mention 'dbus-monitor' but 'dbus-register-monitor'. Fix typos and other oddities. * lisp/net/dbus.el (dbus-monitor): New command. * test/lisp/net/dbus-tests.el (dbus--test-register-service): Extend test. diff --git a/doc/misc/dbus.texi b/doc/misc/dbus.texi index e8e99db76b..6463687793 100644 --- a/doc/misc/dbus.texi +++ b/doc/misc/dbus.texi @@ -2151,6 +2151,11 @@ And this form restricts the monitoring on D-Bus errors: @end lisp @end defun +@deffn Command dbus-monitor &optional bus +This command invokes @code{dbus-register-monitor} interactively, and +switches to the monitor buffer. +@end deffn + @node Index @unnumbered Index diff --git a/etc/NEWS b/etc/NEWS index 61efdc7b61..fb77688470 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -85,7 +85,7 @@ useful on systems such as FreeBSD which ships only with "etc/termcap". * Changes in Emacs 28.1 -** The new NonGNU ELPA archive is enabled by default alongside GNU ELPA +** The new NonGNU ELPA archive is enabled by default alongside GNU ELPA. ** Minibuffer scrolling is now conservative by default. This is controlled by the new variable 'scroll-minibuffer-conservatively'. @@ -221,10 +221,10 @@ It is not enabled by default. +++ ** Modifiers now go outside angle brackets in pretty-printed key bindings. -For example, with Control and Meta modifiers is now shown as -C-M- instead of . Either variant can be used as -input; functions such as 'kbd' and 'read-kbd-macro' accept both styles -as equivalent (they have done so for a long time). +For example, 'RET' with Control and Meta modifiers is now shown as +'C-M-' instead of ''. Either variant can be used +as input; functions such as 'kbd' and 'read-kbd-macro' accept both +styles as equivalent (they have done so for a long time). +++ ** New user option 'lazy-highlight-no-delay-length'. @@ -257,7 +257,7 @@ forms, but this command has now been changed to work more like When 'M-y' is typed not after a yank command, it activates the minibuffer where you can browse previous kills using the minibuffer history or completion. In Isearch, you can bind 'C-s M-y' to the command -`isearch-yank-pop' that uses the minibuffer with completion on +'isearch-yank-pop' that uses the minibuffer with completion on previous kills to read a string and append it to the search string. --- @@ -341,9 +341,10 @@ It used to be enabled when Emacs is started in GUI mode but not when started in text mode. The cursor still only actually blinks in GUI frames. ** pcase + +++ -*** The `pred` pattern can now take the form (pred (not FUN)). -This is like (pred (lambda (x) (not (FUN x)))) but results +*** The 'pred' pattern can now take the form '(pred (not FUN))'. +This is like '(pred (lambda (x) (not (FUN x))))' but results in better code. +++ @@ -403,7 +404,7 @@ disabled entirely. ** Windows +++ -*** New 'display-buffer' function 'display-buffer-use-least-recent-window' +*** New 'display-buffer' function 'display-buffer-use-least-recent-window'. This is like 'display-buffer-use-some-window', but won't reuse the current window, and when called repeatedly will try not to reuse a previously selected window. @@ -736,7 +737,7 @@ not. --- *** Respect 'message-forward-ignored-headers' more. -Previously, this variable would not be consulted if +Previously, this user option would not be consulted if 'message-forward-show-mml' was nil and forwarding as MIME. +++ @@ -857,7 +858,7 @@ deprecated. Errors in the Inscript method were corrected. --- *** New input method 'cham'. -There's also a Cham greeting in 'etc/HELLO'. +There's also a Cham greeting in "etc/HELLO". ** Ispell @@ -1395,13 +1396,13 @@ have been renamed to have "proper" public names and documented 'xref-show-definitions-buffer-at-bottom'). *** New command 'xref-quit-and-pop-marker-stack' and a binding for it -in Xref buffers ('M-,'). This combination is easy to press +in "*xref*" buffers ('M-,'). This combination is easy to press semi-accidentally if the user wants to go back in the middle of choosing the exact definition to go to, and this should do TRT. --- -*** New value 'project-relative' for 'xref-file-name-display' -If chosen, file names in *xref* buffers will be displayed relative +*** New value 'project-relative' for 'xref-file-name-display'. +If chosen, file names in "*xref*" buffers will be displayed relative to the 'project-root' of the current project, when available. ** json.el @@ -1424,9 +1425,9 @@ https://www.w3.org/TR/xml/#charsets). Now it rejects such strings. --- *** erc-services.el now supports NickServ passwords from auth-source. -The 'erc-use-auth-source-for-nickserv-password' variable enables querying -auth-source for NickServ passwords. To enable this, add the following -to your init file: +The 'erc-use-auth-source-for-nickserv-password' user option enables +querying auth-source for NickServ passwords. To enable this, add the +following to your init file: (setq erc-prompt-for-nickserv-password nil erc-use-auth-source-for-nickserv-password t) @@ -1591,18 +1592,18 @@ that makes it a valid button. 'string-clean-whitespace', 'string-fill', 'string-limit', 'string-lines', 'string-pad' and 'string-chop-newline'. -*** New macro `named-let` that provides Scheme's "named let" looping construct +*** New macro 'named-let' that provides Scheme's "named let" looping construct. ** thingatpt +++ *** New variable 'thing-at-point-provider-alist'. -This allows mode-specific alterations to how `thing-at-point' works. +This allows mode-specific alterations to how 'thing-at-point' works. ** Miscellaneous +++ -*** New command `C-x C-k Q' to force redisplay in keyboard macros. +*** New command 'C-x C-k Q' to force redisplay in keyboard macros. --- *** New user option 'remember-diary-regexp'. @@ -1616,8 +1617,8 @@ This function returns some statistics about the line lengths in a buffer. +++ *** New variable 'inhibit-interaction' to make user prompts signal an error. If this is bound to something non-nil, functions like -`read-from-minibuffer', `read-char' (and related) will signal an -`inhibited-interaction' error. +'read-from-minibuffer', 'read-char' (and related) will signal an +'inhibited-interaction' error. --- *** 'process-attributes' now works under OpenBSD, too. @@ -1888,14 +1889,12 @@ Otherwise, it will use 'xwidget-webkit-last-session'. +++ *** New user options to customize Flymake's mode-line. - -The new customization variable 'flymake-mode-line-format' is a mix of -strings and symbols like 'flymake-mode-line-title' , -'flymake-mode-line-exception' and 'flymake-mode-line-counters'. The -new customization variable 'flymake-mode-line-counter-format' is a mix -of strings and symbols like 'flymake-mode-line-error-counter', -'flymake-mode-line-warning-counter' and -'flymake-mode-line-note-counter'. +The new user option 'flymake-mode-line-format' is a mix of strings and +symbols like 'flymake-mode-line-title', 'flymake-mode-line-exception' +and 'flymake-mode-line-counters'. The new user option +'flymake-mode-line-counter-format' is a mix of strings and symbols +like 'flymake-mode-line-error-counter', +'flymake-mode-line-warning-counter' and 'flymake-mode-line-note-counter'. ** Flyspell mode @@ -1954,7 +1953,7 @@ type symbols. Both functions propagate D-Bus errors. messages, contain the error name of that message now. +++ -*** D-Bus messages can be monitored with new function 'dbus-register-monitor'. +*** D-Bus messages can be monitored with the new command 'dbus-monitor'. +++ *** D-Bus events have changed their internal structure. @@ -2178,13 +2177,13 @@ ledit.el, lmenu.el, lucid.el and old-whitespace.el. 'vcursor-toggle-vcursor-map', 'w32-focus-frame', 'w32-select-font', 'wisent-lex-make-token-table'. -** The 'when' argument of `make-obsolete` and related functions is mandatory. -The use of those functions without a 'when' argument was marked -obsolete back in Emacs-23.1. The affected functions are: -make-obsolete, define-obsolete-function-alias, make-obsolete-variable, -define-obsolete-variable-alias. +** The WHEN argument of 'make-obsolete' and related functions is mandatory. +The use of those functions without a WHEN argument was marked obsolete +back in Emacs 23.1. The affected functions are: 'make-obsolete', +'define-obsolete-function-alias', 'make-obsolete-variable', +'define-obsolete-variable-alias'. -** The variable 'keyboard-type' is obsolete and not dynamically scoped any more +** The variable 'keyboard-type' is obsolete and not dynamically scoped any more. * Lisp Changes in Emacs 28.1 diff --git a/lisp/net/dbus.el b/lisp/net/dbus.el index 195ddc6bba..a9de35c814 100644 --- a/lisp/net/dbus.el +++ b/lisp/net/dbus.el @@ -2171,6 +2171,23 @@ has been handled by this function." (when eobp (goto-char (point-max)))))) +;;;###autoload +(defun dbus-monitor (&optional bus) + "Invoke `dbus-register-monitor' interactively, and switch to the buffer. +BUS is either a Lisp keyword, `:system' or `:session', or a +string denoting the bus address. The value nil defaults to `:session'." + (interactive + (list + (let ((input + (completing-read + (format-prompt "Enter bus symbol or name" :session) + '(:system :session) nil nil nil nil :session))) + (if (and (stringp input) + (string-match-p "^\\(:session\\|:system\\)$" input)) + (intern input) input)))) + (dbus-register-monitor (or bus :session)) + (switch-to-buffer (get-buffer-create "*D-Bus Monitor*"))) + (defun dbus-handle-bus-disconnect () "React to a bus disconnection. BUS is the bus that disconnected. This routine unregisters all diff --git a/test/lisp/net/dbus-tests.el b/test/lisp/net/dbus-tests.el index 34a2af188f..53c786ada4 100644 --- a/test/lisp/net/dbus-tests.el +++ b/test/lisp/net/dbus-tests.el @@ -465,6 +465,14 @@ (should (eq (dbus-unregister-service bus dbus--test-service) :non-existent)) (should-not (member dbus--test-service (dbus-list-known-names bus))) + ;; A service name is a string, constructed of at least two words + ;; separated by ".". + (should + (equal + (butlast + (should-error (dbus-register-service bus "s"))) + `(dbus-error ,dbus-error-invalid-args))) + ;; `dbus-service-dbus' is reserved for the BUS itself. (should (equal commit a14811fc96d63157acbf398034ef7f1b5fd14d5d Author: Lars Ingebrigtsen Date: Fri Feb 5 13:36:01 2021 +0100 Don't hard-code ignored functions in `indent-according-to-mode' * lisp/indent.el (indent-line-ignored-functions): New variable (bug#26945). (indent-according-to-mode): Use it. diff --git a/etc/NEWS b/etc/NEWS index dddc150af1..61efdc7b61 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2189,6 +2189,11 @@ define-obsolete-variable-alias. * Lisp Changes in Emacs 28.1 +--- +** New variable 'indent-line-ignored-functions'. +This allows modes to cycle through a set of indentation functions +appropriate for those modes. + ** New function 'garbage-collect-maybe' to trigger GC early. --- diff --git a/lisp/indent.el b/lisp/indent.el index 5c5270b07c..4a5550786d 100644 --- a/lisp/indent.el +++ b/lisp/indent.el @@ -83,22 +83,23 @@ This variable has no effect unless `tab-always-indent' is `complete'." (const :tag "Unless at a word, parenthesis, or punctuation." 'word-or-paren-or-punct)) :version "27.1") +(defvar indent-line-ignored-functions '(indent-relative + indent-relative-maybe + indent-relative-first-indent-point) + "Values that are ignored by `indent-according-to-mode'.") (defun indent-according-to-mode () "Indent line in proper way for current major mode. Normally, this is done by calling the function specified by the variable `indent-line-function'. However, if the value of that -variable is `indent-relative' or `indent-relative-first-indent-point', +variable is present in the `indent-line-ignored-functions' variable, handle it specially (since those functions are used for tabbing); in that case, indent by aligning to the previous non-blank line." (interactive) (save-restriction (widen) (syntax-propertize (line-end-position)) - (if (memq indent-line-function - '(indent-relative - indent-relative-maybe - indent-relative-first-indent-point)) + (if (memq indent-line-function indent-line-ignored-functions) ;; These functions are used for tabbing, but can't be used for ;; indenting. Replace with something ad-hoc. (let ((column (save-excursion commit 07ead60a822580b1dd3d8b3a5f6730d486b57cb3 Author: Eli Zaretskii Date: Fri Feb 5 14:27:46 2021 +0200 ; * src/xdisp.c (Fwindow_text_pixel_size): Another minor fix. diff --git a/src/xdisp.c b/src/xdisp.c index 4db981aa65..764735769b 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10777,7 +10777,7 @@ include the height of both, if present, in the return value. */) /* If text spans more than one screen line, we don't need to adjust the x-span for start_x, since the second and subsequent lines will begin at zero X coordinate. */ - if (it.current_y > 0) + if (it.current_y > start_y) start_x = 0; /* Subtract height of header-line which was counted automatically by commit 764db69dd06b794074561e3830fdf02e67698445 Author: Eli Zaretskii Date: Fri Feb 5 14:24:01 2021 +0200 Fix last change in 'window-text-pixel-size' * src/xdisp.c (Fwindow_text_pixel_size): Fix last change: preserve the original Y coordinate after start_display, instead of zeroing it out. Reported by martin rudalics . diff --git a/src/xdisp.c b/src/xdisp.c index 426c874cdb..4db981aa65 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10706,6 +10706,7 @@ include the height of both, if present, in the return value. */) itdata = bidi_shelve_cache (); start_display (&it, w, startp); + int start_y = it.current_y; /* It makes no sense to measure dimensions of region of text that crosses the point where bidi reordering changes scan direction. By using unidirectional movement here we at least support the use @@ -10726,7 +10727,7 @@ include the height of both, if present, in the return value. */) int start_x = it.current_x; int move_op = MOVE_TO_POS | MOVE_TO_Y; int to_x = -1; - it.current_y = 0; + it.current_y = start_y; /* If FROM is on a newline, pretend that we start at the beginning of the next line, because the newline takes no place on display. */ if (FETCH_BYTE (start) == '\n') commit f00afb9bb8b5356690e2a785d14aa89995c96f50 Author: Lars Ingebrigtsen Date: Fri Feb 5 13:08:50 2021 +0100 Fontize more automatic variables in makefile-gmake-mode * lisp/progmodes/make-mode.el (makefile-gmake-font-lock-keywords): Fontize the $ in more automatic variables (bug#27842). diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el index a0e09f51ce..e382d6edcd 100644 --- a/lisp/progmodes/make-mode.el +++ b/lisp/progmodes/make-mode.el @@ -435,6 +435,9 @@ not be enclosed in { } or ( )." '("[^$]\\(\\$[({][@%*][DF][})]\\)" 1 'makefile-targets append) + ;; Automatic variables. + '("[^$]\\(\\$[@%*?+^|]\\)" 1 'makefile-targets append) + ;; $(function ...) ${function ...} '("[^$]\\$[({]\\([-a-zA-Z0-9_.]+\\s \\)" 1 font-lock-function-name-face prepend) commit c71e08eba94fc821616ab8d48847ff7130974d61 Author: Eli Zaretskii Date: Fri Feb 5 13:06:07 2021 +0200 Fix last change in syntax.texi * doc/lispref/syntax.texi (Syntax Properties): Fix wording in last change. (Bug#46274) diff --git a/doc/lispref/syntax.texi b/doc/lispref/syntax.texi index 58f07c9644..9adffcc18d 100644 --- a/doc/lispref/syntax.texi +++ b/doc/lispref/syntax.texi @@ -573,10 +573,11 @@ and by Font Lock mode during syntactic fontification (@pxref{Syntactic Font Lock}). It is called with two arguments, @var{start} and @var{end}, which are the starting and ending positions of the text on which it should act. It is allowed to call @code{syntax-ppss} on any -position before @var{end}, but if it calls @code{syntax-ppss} on some -position and later modifies the buffer on some earlier position, -then it is its responsibility to call @code{syntax-ppss-flush-cache} -to flush the now obsolete info from the cache. +position before @var{end}, but if a Lisp program calls +@code{syntax-ppss} on some position and later modifies the buffer at +some earlier position, then it is that program's responsibility to +call @code{syntax-ppss-flush-cache} to flush the now obsolete info +from the cache. @strong{Caution:} When this variable is non-@code{nil}, Emacs removes @code{syntax-table} text properties arbitrarily and relies on commit 43bf7f1b06f5ca21a3af166e803b632934e6674d Author: Lars Ingebrigtsen Date: Fri Feb 5 09:36:58 2021 +0100 Correct the lispref manual about flushing ppss info * doc/lispref/syntax.texi (Syntax Properties): Correct the information about flushing the state by copying the text from the doc string (bug#46274). (cherry picked from commit ff701ce2b261acce1dfcd1fe137268d87d5eab35) diff --git a/doc/lispref/syntax.texi b/doc/lispref/syntax.texi index b4bd48771f..58f07c9644 100644 --- a/doc/lispref/syntax.texi +++ b/doc/lispref/syntax.texi @@ -573,10 +573,10 @@ and by Font Lock mode during syntactic fontification (@pxref{Syntactic Font Lock}). It is called with two arguments, @var{start} and @var{end}, which are the starting and ending positions of the text on which it should act. It is allowed to call @code{syntax-ppss} on any -position before @var{end}. However, it should not call -@code{syntax-ppss-flush-cache}; so, it is not allowed to call -@code{syntax-ppss} on some position and later modify the buffer at an -earlier position. +position before @var{end}, but if it calls @code{syntax-ppss} on some +position and later modifies the buffer on some earlier position, +then it is its responsibility to call @code{syntax-ppss-flush-cache} +to flush the now obsolete info from the cache. @strong{Caution:} When this variable is non-@code{nil}, Emacs removes @code{syntax-table} text properties arbitrarily and relies on commit 8c27af3ff465fe78c635a8acd1debc9c63bfa7f3 Author: Lars Ingebrigtsen Date: Fri Feb 5 11:00:07 2021 +0100 Clarify how transient indentation modes are exited in the manual * doc/emacs/indent.texi (Indentation Commands): Clarify that the other keys don't just exit the transient mode, but are also handled as normally (bug#46296). diff --git a/doc/emacs/indent.texi b/doc/emacs/indent.texi index ceb911bef9..cca9432fa4 100644 --- a/doc/emacs/indent.texi +++ b/doc/emacs/indent.texi @@ -136,8 +136,8 @@ this transient mode is active, typing @kbd{@key{LEFT}} or @kbd{@key{RIGHT}} indents leftward and rightward, respectively, by one space. You can also type @kbd{S-@key{LEFT}} or @kbd{S-@key{RIGHT}} to indent leftward or rightward to the next tab stop (@pxref{Tab Stops}). -Typing any other key disables the transient mode, and resumes normal -editing. +Typing any other key disables the transient mode, and this key is then +acted upon as normally. If called with a prefix argument @var{n}, this command indents the lines forward by @var{n} spaces (without enabling the transient mode). commit 9730575f3a2599be0a4f9c3d1ef5321bf1294e93 Author: Lars Ingebrigtsen Date: Fri Feb 5 10:13:23 2021 +0100 Protect against killed buffers in term-emulate-terminal * lisp/term.el (term-emulate-terminal): Ensure that the buffer is still alive before selecting it (bug#46323). This avoids an error when saying `C-x k' in an ansi-term buffer. diff --git a/lisp/term.el b/lisp/term.el index 971f270397..6beb17fb66 100644 --- a/lisp/term.el +++ b/lisp/term.el @@ -2812,333 +2812,334 @@ See `term-prompt-regexp'." "[\032\e]") (defun term-emulate-terminal (proc str) - (with-current-buffer (process-buffer proc) - (let* ((i 0) funny - decoded-substring - save-point save-marker win - (inhibit-read-only t) - (buffer-undo-list t) - (selected (selected-window)) - last-win - (str-length (length str))) - (save-selected-window - - (when (marker-buffer term-pending-delete-marker) - ;; Delete text following term-pending-delete-marker. - (delete-region term-pending-delete-marker (process-mark proc)) - (set-marker term-pending-delete-marker nil)) - - (when (/= (point) (process-mark proc)) - (setq save-point (point-marker))) - - (setf term-vertical-motion - (if (eq (window-buffer) (current-buffer)) - 'vertical-motion - 'term-buffer-vertical-motion)) - (setq save-marker (copy-marker (process-mark proc))) - (goto-char (process-mark proc)) - - (save-restriction - ;; If the buffer is in line mode, and there is a partial - ;; input line, save the line (by narrowing to leave it - ;; outside the restriction ) until we're done with output. - (when (and (> (point-max) (process-mark proc)) - (term-in-line-mode)) - (narrow-to-region (point-min) (process-mark proc))) - - (when term-log-buffer - (princ str term-log-buffer)) - (when term-terminal-undecoded-bytes - (setq str (concat term-terminal-undecoded-bytes str)) - (setq str-length (length str)) - (setq term-terminal-undecoded-bytes nil)) - - (while (< i str-length) - (setq funny (string-match term-control-seq-regexp str i)) - (let ((ctl-params (and funny (match-string 1 str))) - (ctl-params-end (and funny (match-end 1))) - (ctl-end (if funny (match-end 0) - (setq funny (string-match term-control-seq-prefix-regexp str i)) - (if funny - (setq term-terminal-undecoded-bytes - (substring str funny)) - (setq funny str-length)) - ;; The control sequence ends somewhere - ;; past the end of this string. - (1+ str-length)))) - (when (> funny i) - (when term-do-line-wrapping - (term-down 1 t) - (term-move-to-column 0) - (setq term-do-line-wrapping nil)) - ;; Handle non-control data. Decode the string before - ;; counting characters, to avoid garbling of certain - ;; multibyte characters (bug#1006). - (setq decoded-substring - (decode-coding-string - (substring str i funny) - locale-coding-system t)) - ;; Check for multibyte characters that ends - ;; before end of string, and save it for - ;; next time. - (when (= funny str-length) - (let ((partial 0) - (count (length decoded-substring))) - (while (and (< partial count) - (eq (char-charset (aref decoded-substring - (- count 1 partial))) - 'eight-bit)) - (cl-incf partial)) - (when (> count partial 0) - (setq term-terminal-undecoded-bytes - (substring decoded-substring (- partial))) - (setq decoded-substring - (substring decoded-substring 0 (- partial))) - (cl-decf str-length partial) - (cl-decf funny partial)))) - - ;; Insert a string, check how many columns - ;; we moved, then delete that many columns - ;; following point if not eob nor insert-mode. - (let ((old-column (term-horizontal-column)) - (old-point (point)) - columns) - (unless term-suppress-hard-newline - (while (> (+ (length decoded-substring) old-column) - term-width) - (insert (substring decoded-substring 0 - (- term-width old-column))) - ;; Since we've enough text to fill the whole line, - ;; delete previous text regardless of - ;; `term-insert-mode's value. - (delete-region (point) (line-end-position)) - (term-down 1 t) - (term-move-columns (- (term-current-column))) - (add-text-properties (1- (point)) (point) - '(term-line-wrap t rear-nonsticky t)) - (setq decoded-substring - (substring decoded-substring (- term-width old-column))) - (setq old-column 0))) - (insert decoded-substring) - (setq term-current-column (current-column) - columns (- term-current-column old-column)) - (when (not (or (eobp) term-insert-mode)) - (let ((pos (point))) - (term-move-columns columns) - (delete-region pos (point)) - (setq term-current-column nil))) - ;; In insert mode if the current line - ;; has become too long it needs to be - ;; chopped off. - (when term-insert-mode - (let ((pos (point))) - (end-of-line) - (when (> (current-column) term-width) - (delete-region (- (point) (- (current-column) term-width)) - (point))) - (goto-char pos))) - - (put-text-property old-point (point) - 'font-lock-face term-current-face)) - ;; If the last char was written in last column, - ;; back up one column, but remember we did so. - ;; Thus we emulate xterm/vt100-style line-wrapping. - (when (eq (term-current-column) term-width) - (term-move-columns -1) - ;; We check after ctrl sequence handling if point - ;; was moved (and leave line-wrapping state if so). - (setq term-do-line-wrapping (point))) - (setq term-current-column nil) - (setq i funny)) - (pcase-exhaustive (and (<= ctl-end str-length) (aref str i)) - (?\t ;; TAB (terminfo: ht) - ;; The line cannot exceed term-width. TAB at - ;; the end of a line should not cause wrapping. - (let ((col (term-current-column))) - (term-move-to-column - (min (1- term-width) - (+ col 8 (- (mod col 8))))))) - (?\r ;; (terminfo: cr) - (term-vertical-motion 0) - (setq term-current-column term-start-line-column)) - (?\n ;; (terminfo: cud1, ind) - (unless (and term-kill-echo-list - (term-check-kill-echo-list)) - (term-down 1 t))) - (?\b ;; (terminfo: cub1) - (term-move-columns -1)) - (?\C-g ;; (terminfo: bel) - (beep t)) - (?\032 ; Emacs specific control sequence. - (funcall term-command-function - (decode-coding-string - (substring str (1+ i) - (- ctl-end - (if (eq (aref str (- ctl-end 2)) ?\r) - 2 1))) - locale-coding-system t))) - (?\e - (pcase (aref str (1+ i)) - (?\[ - ;; We only handle control sequences with a single - ;; "Final" byte (see [ECMA-48] section 5.4). - (when (eq ctl-params-end (1- ctl-end)) - (term-handle-ansi-escape - proc - (mapcar ;; We don't distinguish empty params - ;; from 0 (according to [ECMA-48] we - ;; should, but all commands we support - ;; default to 0 values anyway). - #'string-to-number - (split-string ctl-params ";")) - (aref str (1- ctl-end))))) - (?D ;; Scroll forward (apparently not documented in - ;; [ECMA-48], [ctlseqs] mentions it as C1 - ;; character "Index" though). - (term-handle-deferred-scroll) - (term-down 1 t)) - (?M ;; Scroll reversed (terminfo: ri, ECMA-48 - ;; "Reverse Linefeed"). - (if (or (< (term-current-row) term-scroll-start) - (>= (1- (term-current-row)) - term-scroll-start)) - ;; Scrolling up will not move outside - ;; the scroll region. - (term-down -1) - ;; Scrolling the scroll region is needed. - (term-down -1 t))) - (?7 ;; Save cursor (terminfo: sc, not in [ECMA-48], - ;; [ctlseqs] has it as "DECSC"). - (term-handle-deferred-scroll) - (setq term-saved-cursor - (list (term-current-row) - (term-horizontal-column) - term-ansi-current-bg-color - term-ansi-current-bold - term-ansi-current-color - term-ansi-current-invisible - term-ansi-current-reverse - term-ansi-current-underline - term-current-face))) - (?8 ;; Restore cursor (terminfo: rc, [ctlseqs] - ;; "DECRC"). - (when term-saved-cursor - (term-goto (nth 0 term-saved-cursor) - (nth 1 term-saved-cursor)) - (setq term-ansi-current-bg-color - (nth 2 term-saved-cursor) - term-ansi-current-bold - (nth 3 term-saved-cursor) - term-ansi-current-color - (nth 4 term-saved-cursor) - term-ansi-current-invisible - (nth 5 term-saved-cursor) - term-ansi-current-reverse - (nth 6 term-saved-cursor) - term-ansi-current-underline - (nth 7 term-saved-cursor) - term-current-face - (nth 8 term-saved-cursor)))) - (?c ;; \Ec - Reset (terminfo: rs1, [ctlseqs] "RIS"). - ;; This is used by the "clear" program. - (term-reset-terminal)) - (?A ;; An \eAnSiT sequence (Emacs specific). - (term-handle-ansi-terminal-messages - (substring str i ctl-end))))) - ;; Ignore NUL, Shift Out, Shift In. - ((or ?\0 #xE #xF 'nil) nil)) - ;; Leave line-wrapping state if point was moved. - (unless (eq term-do-line-wrapping (point)) - (setq term-do-line-wrapping nil)) - (if (term-handling-pager) - (progn - ;; Finish stuff to get ready to handle PAGER. - (if (> (% (current-column) term-width) 0) + (when (buffer-live-p (process-buffer proc)) + (with-current-buffer (process-buffer proc) + (let* ((i 0) funny + decoded-substring + save-point save-marker win + (inhibit-read-only t) + (buffer-undo-list t) + (selected (selected-window)) + last-win + (str-length (length str))) + (save-selected-window + + (when (marker-buffer term-pending-delete-marker) + ;; Delete text following term-pending-delete-marker. + (delete-region term-pending-delete-marker (process-mark proc)) + (set-marker term-pending-delete-marker nil)) + + (when (/= (point) (process-mark proc)) + (setq save-point (point-marker))) + + (setf term-vertical-motion + (if (eq (window-buffer) (current-buffer)) + 'vertical-motion + 'term-buffer-vertical-motion)) + (setq save-marker (copy-marker (process-mark proc))) + (goto-char (process-mark proc)) + + (save-restriction + ;; If the buffer is in line mode, and there is a partial + ;; input line, save the line (by narrowing to leave it + ;; outside the restriction ) until we're done with output. + (when (and (> (point-max) (process-mark proc)) + (term-in-line-mode)) + (narrow-to-region (point-min) (process-mark proc))) + + (when term-log-buffer + (princ str term-log-buffer)) + (when term-terminal-undecoded-bytes + (setq str (concat term-terminal-undecoded-bytes str)) + (setq str-length (length str)) + (setq term-terminal-undecoded-bytes nil)) + + (while (< i str-length) + (setq funny (string-match term-control-seq-regexp str i)) + (let ((ctl-params (and funny (match-string 1 str))) + (ctl-params-end (and funny (match-end 1))) + (ctl-end (if funny (match-end 0) + (setq funny (string-match term-control-seq-prefix-regexp str i)) + (if funny + (setq term-terminal-undecoded-bytes + (substring str funny)) + (setq funny str-length)) + ;; The control sequence ends somewhere + ;; past the end of this string. + (1+ str-length)))) + (when (> funny i) + (when term-do-line-wrapping + (term-down 1 t) + (term-move-to-column 0) + (setq term-do-line-wrapping nil)) + ;; Handle non-control data. Decode the string before + ;; counting characters, to avoid garbling of certain + ;; multibyte characters (bug#1006). + (setq decoded-substring + (decode-coding-string + (substring str i funny) + locale-coding-system t)) + ;; Check for multibyte characters that ends + ;; before end of string, and save it for + ;; next time. + (when (= funny str-length) + (let ((partial 0) + (count (length decoded-substring))) + (while (and (< partial count) + (eq (char-charset (aref decoded-substring + (- count 1 partial))) + 'eight-bit)) + (cl-incf partial)) + (when (> count partial 0) (setq term-terminal-undecoded-bytes - (substring str i)) - ;; We're at column 0. Goto end of buffer; to compensate, - ;; prepend a ?\r for later. This looks more consistent. - (if (zerop i) + (substring decoded-substring (- partial))) + (setq decoded-substring + (substring decoded-substring 0 (- partial))) + (cl-decf str-length partial) + (cl-decf funny partial)))) + + ;; Insert a string, check how many columns + ;; we moved, then delete that many columns + ;; following point if not eob nor insert-mode. + (let ((old-column (term-horizontal-column)) + (old-point (point)) + columns) + (unless term-suppress-hard-newline + (while (> (+ (length decoded-substring) old-column) + term-width) + (insert (substring decoded-substring 0 + (- term-width old-column))) + ;; Since we've enough text to fill the whole line, + ;; delete previous text regardless of + ;; `term-insert-mode's value. + (delete-region (point) (line-end-position)) + (term-down 1 t) + (term-move-columns (- (term-current-column))) + (add-text-properties (1- (point)) (point) + '(term-line-wrap t rear-nonsticky t)) + (setq decoded-substring + (substring decoded-substring (- term-width old-column))) + (setq old-column 0))) + (insert decoded-substring) + (setq term-current-column (current-column) + columns (- term-current-column old-column)) + (when (not (or (eobp) term-insert-mode)) + (let ((pos (point))) + (term-move-columns columns) + (delete-region pos (point)) + (setq term-current-column nil))) + ;; In insert mode if the current line + ;; has become too long it needs to be + ;; chopped off. + (when term-insert-mode + (let ((pos (point))) + (end-of-line) + (when (> (current-column) term-width) + (delete-region (- (point) (- (current-column) term-width)) + (point))) + (goto-char pos))) + + (put-text-property old-point (point) + 'font-lock-face term-current-face)) + ;; If the last char was written in last column, + ;; back up one column, but remember we did so. + ;; Thus we emulate xterm/vt100-style line-wrapping. + (when (eq (term-current-column) term-width) + (term-move-columns -1) + ;; We check after ctrl sequence handling if point + ;; was moved (and leave line-wrapping state if so). + (setq term-do-line-wrapping (point))) + (setq term-current-column nil) + (setq i funny)) + (pcase-exhaustive (and (<= ctl-end str-length) (aref str i)) + (?\t ;; TAB (terminfo: ht) + ;; The line cannot exceed term-width. TAB at + ;; the end of a line should not cause wrapping. + (let ((col (term-current-column))) + (term-move-to-column + (min (1- term-width) + (+ col 8 (- (mod col 8))))))) + (?\r ;; (terminfo: cr) + (term-vertical-motion 0) + (setq term-current-column term-start-line-column)) + (?\n ;; (terminfo: cud1, ind) + (unless (and term-kill-echo-list + (term-check-kill-echo-list)) + (term-down 1 t))) + (?\b ;; (terminfo: cub1) + (term-move-columns -1)) + (?\C-g ;; (terminfo: bel) + (beep t)) + (?\032 ; Emacs specific control sequence. + (funcall term-command-function + (decode-coding-string + (substring str (1+ i) + (- ctl-end + (if (eq (aref str (- ctl-end 2)) ?\r) + 2 1))) + locale-coding-system t))) + (?\e + (pcase (aref str (1+ i)) + (?\[ + ;; We only handle control sequences with a single + ;; "Final" byte (see [ECMA-48] section 5.4). + (when (eq ctl-params-end (1- ctl-end)) + (term-handle-ansi-escape + proc + (mapcar ;; We don't distinguish empty params + ;; from 0 (according to [ECMA-48] we + ;; should, but all commands we support + ;; default to 0 values anyway). + #'string-to-number + (split-string ctl-params ";")) + (aref str (1- ctl-end))))) + (?D ;; Scroll forward (apparently not documented in + ;; [ECMA-48], [ctlseqs] mentions it as C1 + ;; character "Index" though). + (term-handle-deferred-scroll) + (term-down 1 t)) + (?M ;; Scroll reversed (terminfo: ri, ECMA-48 + ;; "Reverse Linefeed"). + (if (or (< (term-current-row) term-scroll-start) + (>= (1- (term-current-row)) + term-scroll-start)) + ;; Scrolling up will not move outside + ;; the scroll region. + (term-down -1) + ;; Scrolling the scroll region is needed. + (term-down -1 t))) + (?7 ;; Save cursor (terminfo: sc, not in [ECMA-48], + ;; [ctlseqs] has it as "DECSC"). + (term-handle-deferred-scroll) + (setq term-saved-cursor + (list (term-current-row) + (term-horizontal-column) + term-ansi-current-bg-color + term-ansi-current-bold + term-ansi-current-color + term-ansi-current-invisible + term-ansi-current-reverse + term-ansi-current-underline + term-current-face))) + (?8 ;; Restore cursor (terminfo: rc, [ctlseqs] + ;; "DECRC"). + (when term-saved-cursor + (term-goto (nth 0 term-saved-cursor) + (nth 1 term-saved-cursor)) + (setq term-ansi-current-bg-color + (nth 2 term-saved-cursor) + term-ansi-current-bold + (nth 3 term-saved-cursor) + term-ansi-current-color + (nth 4 term-saved-cursor) + term-ansi-current-invisible + (nth 5 term-saved-cursor) + term-ansi-current-reverse + (nth 6 term-saved-cursor) + term-ansi-current-underline + (nth 7 term-saved-cursor) + term-current-face + (nth 8 term-saved-cursor)))) + (?c ;; \Ec - Reset (terminfo: rs1, [ctlseqs] "RIS"). + ;; This is used by the "clear" program. + (term-reset-terminal)) + (?A ;; An \eAnSiT sequence (Emacs specific). + (term-handle-ansi-terminal-messages + (substring str i ctl-end))))) + ;; Ignore NUL, Shift Out, Shift In. + ((or ?\0 #xE #xF 'nil) nil)) + ;; Leave line-wrapping state if point was moved. + (unless (eq term-do-line-wrapping (point)) + (setq term-do-line-wrapping nil)) + (if (term-handling-pager) + (progn + ;; Finish stuff to get ready to handle PAGER. + (if (> (% (current-column) term-width) 0) (setq term-terminal-undecoded-bytes - (concat "\r" (substring str i))) - (setq term-terminal-undecoded-bytes (substring str (1- i))) - (aset term-terminal-undecoded-bytes 0 ?\r)) - (goto-char (point-max))) - ;; FIXME: Use (add-function :override (process-filter proc) - (setq-local term-pager-old-filter (process-filter proc)) - ;; FIXME: Where is `term-pager-filter' set to a function?! - (set-process-filter proc term-pager-filter) - (setq i str-length)) - (setq i ctl-end))))) - - (when (>= (term-current-row) term-height) - (term-handle-deferred-scroll)) - - (set-marker (process-mark proc) (point)) - (when (stringp decoded-substring) - (term-watch-for-password-prompt decoded-substring)) - (when save-point - (goto-char save-point) - (set-marker save-point nil)) - - ;; Check for a pending filename-and-line number to display. - ;; We do this before scrolling, because we might create a new window. - (when (and term-pending-frame - (eq (window-buffer selected) (current-buffer))) - (term-display-line (car term-pending-frame) - (cdr term-pending-frame)) - (setq term-pending-frame nil)) - - ;; Scroll each window displaying the buffer but (by default) - ;; only if the point matches the process-mark we started with. - (setq win selected) - ;; Avoid infinite loop in strange case where minibuffer window - ;; is selected but not active. - (while (window-minibuffer-p win) - (setq win (next-window win nil t))) - (setq last-win win) - (while (progn - (setq win (next-window win nil t)) - (when (eq (window-buffer win) (process-buffer proc)) - (let ((scroll term-scroll-to-bottom-on-output)) - (select-window win) - (when (or (= (point) save-marker) - (eq scroll t) (eq scroll 'all) - ;; Maybe user wants point to jump to the end. - (and (eq selected win) - (or (eq scroll 'this) (not save-point))) - (and (eq scroll 'others) - (not (eq selected win)))) - (when term-scroll-snap-to-bottom - (goto-char term-home-marker) - (recenter 0)) - (goto-char (process-mark proc)) - (if (not (pos-visible-in-window-p (point) win)) - (recenter -1))) - ;; Optionally scroll so that the text - ;; ends at the bottom of the window. - (when (and term-scroll-show-maximum-output - (>= (point) (process-mark proc)) - (or term-scroll-snap-to-bottom - (not (pos-visible-in-window-p - (point-max) win)))) - (save-excursion - (goto-char (point-max)) - (recenter -1))))) - (not (eq win last-win)))) - - ;; Stolen from comint.el and adapted -mm - (when (> term-buffer-maximum-size 0) - (save-excursion - (goto-char (process-mark (get-buffer-process (current-buffer)))) - (forward-line (- term-buffer-maximum-size)) - (beginning-of-line) - (delete-region (point-min) (point)))) - (set-marker save-marker nil))) - ;; This might be expensive, but we need it to handle something - ;; like `sleep 5 | less -c' in more-or-less real time. - (when (get-buffer-window (current-buffer)) - (redisplay)))) + (substring str i)) + ;; We're at column 0. Goto end of buffer; to compensate, + ;; prepend a ?\r for later. This looks more consistent. + (if (zerop i) + (setq term-terminal-undecoded-bytes + (concat "\r" (substring str i))) + (setq term-terminal-undecoded-bytes (substring str (1- i))) + (aset term-terminal-undecoded-bytes 0 ?\r)) + (goto-char (point-max))) + ;; FIXME: Use (add-function :override (process-filter proc) + (setq-local term-pager-old-filter (process-filter proc)) + ;; FIXME: Where is `term-pager-filter' set to a function?! + (set-process-filter proc term-pager-filter) + (setq i str-length)) + (setq i ctl-end))))) + + (when (>= (term-current-row) term-height) + (term-handle-deferred-scroll)) + + (set-marker (process-mark proc) (point)) + (when (stringp decoded-substring) + (term-watch-for-password-prompt decoded-substring)) + (when save-point + (goto-char save-point) + (set-marker save-point nil)) + + ;; Check for a pending filename-and-line number to display. + ;; We do this before scrolling, because we might create a new window. + (when (and term-pending-frame + (eq (window-buffer selected) (current-buffer))) + (term-display-line (car term-pending-frame) + (cdr term-pending-frame)) + (setq term-pending-frame nil)) + + ;; Scroll each window displaying the buffer but (by default) + ;; only if the point matches the process-mark we started with. + (setq win selected) + ;; Avoid infinite loop in strange case where minibuffer window + ;; is selected but not active. + (while (window-minibuffer-p win) + (setq win (next-window win nil t))) + (setq last-win win) + (while (progn + (setq win (next-window win nil t)) + (when (eq (window-buffer win) (process-buffer proc)) + (let ((scroll term-scroll-to-bottom-on-output)) + (select-window win) + (when (or (= (point) save-marker) + (eq scroll t) (eq scroll 'all) + ;; Maybe user wants point to jump to the end. + (and (eq selected win) + (or (eq scroll 'this) (not save-point))) + (and (eq scroll 'others) + (not (eq selected win)))) + (when term-scroll-snap-to-bottom + (goto-char term-home-marker) + (recenter 0)) + (goto-char (process-mark proc)) + (if (not (pos-visible-in-window-p (point) win)) + (recenter -1))) + ;; Optionally scroll so that the text + ;; ends at the bottom of the window. + (when (and term-scroll-show-maximum-output + (>= (point) (process-mark proc)) + (or term-scroll-snap-to-bottom + (not (pos-visible-in-window-p + (point-max) win)))) + (save-excursion + (goto-char (point-max)) + (recenter -1))))) + (not (eq win last-win)))) + + ;; Stolen from comint.el and adapted -mm + (when (> term-buffer-maximum-size 0) + (save-excursion + (goto-char (process-mark (get-buffer-process (current-buffer)))) + (forward-line (- term-buffer-maximum-size)) + (beginning-of-line) + (delete-region (point-min) (point)))) + (set-marker save-marker nil))) + ;; This might be expensive, but we need it to handle something + ;; like `sleep 5 | less -c' in more-or-less real time. + (when (get-buffer-window (current-buffer)) + (redisplay))))) (defvar-local term-goto-process-mark t "Whether to reset point to the current process mark after this command. commit 7016db933cd529c3cbc157b126dc17df8f2ff165 Author: Sean Whitton Date: Fri Feb 5 10:06:22 2021 +0100 Fix repeating complex commands * lisp/repeat.el (repeat): Fix repeating complex commands (bug#46290). This makes `M-: date RET C-x z' work again (like in Emacs 21, apparently). diff --git a/lisp/repeat.el b/lisp/repeat.el index d488889348..795577c93f 100644 --- a/lisp/repeat.el +++ b/lisp/repeat.el @@ -239,9 +239,7 @@ recently executed command not bound to an input event\"." (car (memq last-command-event (listify-key-sequence repeat-on-final-keystroke)))))) - (if (memq last-repeatable-command '(exit-minibuffer - minibuffer-complete-and-exit - self-insert-and-exit)) + (if (eq last-repeatable-command (caar command-history)) (let ((repeat-command (car command-history))) (repeat-message "Repeating %S" repeat-command) (eval repeat-command)) commit f06acf752a27b0ab34eae5e2342579863ede3b2f Author: Lars Ingebrigtsen Date: Fri Feb 5 09:45:49 2021 +0100 Make octave-send-region deactivate the region * lisp/progmodes/octave.el (octave-send-region): Deactivate mark after sending the region (bug#32282), since this is how these commands usually work. diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el index c37bb1c711..cb44b72fb4 100644 --- a/lisp/progmodes/octave.el +++ b/lisp/progmodes/octave.el @@ -1516,7 +1516,8 @@ current buffer file unless called with a prefix arg \\[universal-argument]." ;; https://lists.gnu.org/r/emacs-devel/2013-10/msg00095.html (compilation-forget-errors) (insert-before-markers string "\n") - (comint-send-string proc (concat string "\n")))) + (comint-send-string proc (concat string "\n"))) + (deactivate-mark)) (if octave-send-show-buffer (display-buffer inferior-octave-buffer))) commit ff701ce2b261acce1dfcd1fe137268d87d5eab35 Author: Lars Ingebrigtsen Date: Fri Feb 5 09:36:58 2021 +0100 Correct the lispref manual about flushing ppss info * doc/lispref/syntax.texi (Syntax Properties): Correct the information about flushing the state by copying the text from the doc string (bug#46274). diff --git a/doc/lispref/syntax.texi b/doc/lispref/syntax.texi index d27053a179..4a316a1bdd 100644 --- a/doc/lispref/syntax.texi +++ b/doc/lispref/syntax.texi @@ -573,10 +573,10 @@ and by Font Lock mode during syntactic fontification (@pxref{Syntactic Font Lock}). It is called with two arguments, @var{start} and @var{end}, which are the starting and ending positions of the text on which it should act. It is allowed to call @code{syntax-ppss} on any -position before @var{end}. However, it should not call -@code{syntax-ppss-flush-cache}; so, it is not allowed to call -@code{syntax-ppss} on some position and later modify the buffer at an -earlier position. +position before @var{end}, but if it calls @code{syntax-ppss} on some +position and later modifies the buffer on some earlier position, +then it is its responsibility to call @code{syntax-ppss-flush-cache} +to flush the now obsolete info from the cache. @strong{Caution:} When this variable is non-@code{nil}, Emacs removes @code{syntax-table} text properties arbitrarily and relies on commit 6bd9dbf9593799913bed2d32eb736f1f27007303 Author: Stefan Kangas Date: Fri Feb 5 02:39:49 2021 +0100 * lisp/emacs-lisp/checkdoc.el: Doc fix; don't mention built-ins. diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index 9722792a5a..75aefdc7ba 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -147,13 +147,6 @@ ;; ;; See the above section "Checking Parameters" for details about ;; parameter checking. -;; -;; Dependencies: -;; -;; This file requires lisp-mnt (Lisp maintenance routines) for the -;; comment checkers. -;; -;; Requires custom for Emacs v20. ;;; TO DO: ;; Hook into the byte compiler on a defun/defvar level to generate commit de701470b2c62ab47723f8b10cec0ee7f7ed724d Author: Stefan Kangas Date: Fri Feb 5 02:27:57 2021 +0100 Remove some unnecessary references to Emacs 18 * lisp/progmodes/cmacexp.el: * lisp/progmodes/f90.el: * lisp/shell.el: Doc fix; don't mention Emacs 18. diff --git a/lisp/progmodes/cmacexp.el b/lisp/progmodes/cmacexp.el index d3a33bdf87..1a45b1cb83 100644 --- a/lisp/progmodes/cmacexp.el +++ b/lisp/progmodes/cmacexp.el @@ -72,15 +72,6 @@ ;; Please report bugs, suggestions, complaints and so on to ;; bug-gnu-emacs@gnu.org and pot@gnu.org (Francesco Potortì). -;; IMPROVEMENTS OVER emacs 18.xx cmacexp.el ========================== - -;; - A lot of user and programmer visible changes. See above. -;; - #line directives are inserted, so __LINE__ and __FILE__ are -;; correctly expanded. Works even with START inside a string, a -;; comment or a region #ifdef'd away by cpp. cpp is invoked with -C, -;; making comments visible in the expansion. -;; - All work is done in core memory, no need for temporary files. - ;; ACKNOWLEDGMENTS =================================================== ;; A lot of thanks to Don Maszle who did a great work of testing, bug diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el index 90678c8cb1..5c0b7880e8 100644 --- a/lisp/progmodes/f90.el +++ b/lisp/progmodes/f90.el @@ -117,11 +117,10 @@ ;; correctly, but I imagine them to be rare. ;; 3) Regexps for hilit19 are no longer supported. ;; 4) For FIXED FORMAT code, use fortran mode. -;; 5) This mode does not work under emacs-18.x. -;; 6) Preprocessor directives, i.e., lines starting with # are left-justified +;; 5) Preprocessor directives, i.e., lines starting with # are left-justified ;; and are untouched by all case-changing commands. There is, at present, no ;; mechanism for treating multi-line directives (continued by \ ). -;; 7) f77 do-loops do 10 i=.. ; ; 10 continue are not correctly indented. +;; 6) f77 do-loops do 10 i=.. ; ; 10 continue are not correctly indented. ;; You are urged to use f90-do loops (with labels if you wish). ;; List of user commands diff --git a/lisp/shell.el b/lisp/shell.el index 0f866158fe..3212824165 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -26,9 +26,7 @@ ;;; Commentary: ;; This file defines a shell-in-a-buffer package (shell mode) built on -;; top of comint mode. This is actually cmushell with things renamed -;; to replace its counterpart in Emacs 18. cmushell is more -;; featureful, robust, and uniform than the Emacs 18 version. +;; top of comint mode. ;; Since this mode is built on top of the general command-interpreter-in- ;; a-buffer mode (comint mode), it shares a common base functionality, @@ -785,8 +783,7 @@ Make the shell buffer the current buffer, and return it. ;; that tracks cd, pushd, and popd commands issued to the shell, and ;; changes the current directory of the shell buffer accordingly. ;; -;; This is basically a fragile hack, although it's more accurate than -;; the version in Emacs 18's shell.el. It has the following failings: +;; This is basically a fragile hack. It has the following failings: ;; 1. It doesn't know about the cdpath shell variable. ;; 2. It cannot infallibly deal with command sequences, though it does well ;; with these and with ignoring commands forked in another shell with ()s. commit 620470f0b7bd648d75b39924b23e54b759d6cbd9 Author: Stefan Kangas Date: Fri Feb 5 02:21:50 2021 +0100 Remove Emacs 19 compat code from dcl-mode.el * lisp/progmodes/dcl-mode.el: Doc fix. (dcl-mode-map, dcl-mode): Remove compat code for Emacs 19. diff --git a/lisp/progmodes/dcl-mode.el b/lisp/progmodes/dcl-mode.el index 3815b17650..8943d8b6d0 100644 --- a/lisp/progmodes/dcl-mode.el +++ b/lisp/progmodes/dcl-mode.el @@ -30,21 +30,14 @@ ;; Type `C-h m' when you are editing a .COM file to get more ;; information about this mode. ;; -;; To use templates you will need a version of tempo.el that is at -;; least later than the buggy 1.1.1, which was included with my versions of -;; Emacs. I used version 1.2.4. -;; The latest tempo.el distribution can be fetched from -;; ftp.lysator.liu.se in the directory /pub/emacs. +;; Support for templates is based on the built-in tempo.el. ;; I recommend setting (setq tempo-interactive t). This will make ;; tempo prompt you for values to put in the blank spots in the templates. ;; -;; There is limited support for imenu. The limitation is that you need -;; a version of imenu.el that uses imenu-generic-expression. I found -;; the version I use in Emacs 19.30. (It was *so* much easier to hook -;; into that version than the one in 19.27...) +;; There is limited support for imenu. ;; ;; Any feedback will be welcomed. If you write functions for -;; dcl-calc-command-indent-function or dcl-calc-cont-indent-function, +;; `dcl-calc-command-indent-function' or `dcl-calc-cont-indent-function', ;; please send them to the maintainer. ;; ;; @@ -349,13 +342,10 @@ See `imenu-generic-expression' for details." '("End of statement" . dcl-forward-command)) (define-key map [menu-bar dcl dcl-backward-command] '("Beginning of statement" . dcl-backward-command)) - ;; imenu is only supported for versions with imenu-generic-expression - (if (boundp 'imenu-generic-expression) - (progn - (define-key map [menu-bar dcl dcl-separator-movement] - '("--")) - (define-key map [menu-bar dcl imenu] - '("Buffer index menu" . imenu)))) + (define-key map [menu-bar dcl dcl-separator-movement] + '("--")) + (define-key map [menu-bar dcl imenu] + '("Buffer index menu" . imenu)) map) "Keymap used in DCL-mode buffers.") @@ -463,8 +453,7 @@ Preloaded with all known option names from dcl-option-alist") ;The default includes SUBROUTINE labels in the main listing and ;sub-listings for other labels, CALL, GOTO and GOSUB statements. -;See `imenu-generic-expression' in a recent (e.g. Emacs 19.30) imenu.el -;for details.") +;See `imenu-generic-expression' for details.") ;;; *** Mode initialization ************************************************* @@ -600,9 +589,8 @@ There is some minimal font-lock support (see vars ;; and something inappropriate might be interpreted as a comment. (setq-local comment-start-skip "\\$[ \t]*![ \t]*") - (if (boundp 'imenu-generic-expression) - (progn (setq imenu-generic-expression dcl-imenu-generic-expression) - (setq imenu-case-fold-search t))) + (setq imenu-generic-expression dcl-imenu-generic-expression) + (setq imenu-case-fold-search t) (setq imenu-create-index-function 'dcl-imenu-create-index-function) (make-local-variable 'dcl-comment-line-regexp) commit 574f71b739cf07aed1f2c8ba7e17cd12ae482c7c Author: Stefan Kangas Date: Fri Feb 5 01:33:25 2021 +0100 Remove Emacs 20 compat code for header-line-format * lisp/cedet/semantic/util-modes.el (semantic-stickyfunc-mode): * lisp/erc/erc.el (erc-update-mode-line-buffer): * lisp/ibuffer.el (ibuffer-use-header-line): Remove Emacs 20 compat code; header-line-format is always defined starting with Emacs 21. diff --git a/lisp/cedet/semantic/util-modes.el b/lisp/cedet/semantic/util-modes.el index f8d6bb759b..0de66d29e3 100644 --- a/lisp/cedet/semantic/util-modes.el +++ b/lisp/cedet/semantic/util-modes.el @@ -691,10 +691,6 @@ non-nil if the minor mode is enabled." ;; Disable minor mode if semantic stuff not available (setq semantic-stickyfunc-mode nil) (error "Buffer %s was not set up for parsing" (buffer-name))) - (unless (boundp 'header-line-format) - ;; Disable if there are no header lines to use. - (setq semantic-stickyfunc-mode nil) - (error "Sticky Function mode requires Emacs")) ;; Enable the mode ;; Save previous buffer local value of header line format. (when (and (local-variable-p 'header-line-format (current-buffer)) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 37e4cc39d5..dd7f50fb38 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -6464,32 +6464,31 @@ if `erc-away' is non-nil." (setq mode-line-buffer-identification (list (format-spec erc-mode-line-format spec))) (setq mode-line-process (list process-status)) - (when (boundp 'header-line-format) - (let ((header (if erc-header-line-format - (format-spec erc-header-line-format spec) - nil))) - (cond (erc-header-line-uses-tabbar-p - (setq-local tabbar--local-hlf header-line-format) - (kill-local-variable 'header-line-format)) - ((null header) - (setq header-line-format nil)) - (erc-header-line-uses-help-echo-p - (let ((help-echo (with-temp-buffer - (insert header) - (fill-region (point-min) (point-max)) - (buffer-string)))) - (setq header-line-format - (replace-regexp-in-string - "%" - "%%" - (if face - (propertize header 'help-echo help-echo - 'face face) - (propertize header 'help-echo help-echo)))))) - (t (setq header-line-format - (if face - (propertize header 'face face) - header))))))) + (let ((header (if erc-header-line-format + (format-spec erc-header-line-format spec) + nil))) + (cond (erc-header-line-uses-tabbar-p + (setq-local tabbar--local-hlf header-line-format) + (kill-local-variable 'header-line-format)) + ((null header) + (setq header-line-format nil)) + (erc-header-line-uses-help-echo-p + (let ((help-echo (with-temp-buffer + (insert header) + (fill-region (point-min) (point-max)) + (buffer-string)))) + (setq header-line-format + (replace-regexp-in-string + "%" + "%%" + (if face + (propertize header 'help-echo help-echo + 'face face) + (propertize header 'help-echo help-echo)))))) + (t (setq header-line-format + (if face + (propertize header 'face face) + header)))))) (force-mode-line-update))) (defun erc-update-mode-line (&optional buffer) diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el index c0a6d16c6f..6dc1c7ebc2 100644 --- a/lisp/ibuffer.el +++ b/lisp/ibuffer.el @@ -303,7 +303,7 @@ This variable takes precedence over filtering, and even in completion lists of the `ibuffer-jump-to-buffer' command." :type 'boolean) -(defcustom ibuffer-use-header-line (boundp 'header-line-format) +(defcustom ibuffer-use-header-line t "If non-nil, display a header line containing current filters." :type 'boolean) commit 1a35d2e67375f0ffe0a749a2488e13f9d96cd994 Author: Stefan Kangas Date: Fri Feb 5 01:29:20 2021 +0100 * lisp/color.el: Remove Emacs 23.2 compat code. diff --git a/lisp/color.el b/lisp/color.el index 258acbe405..fec36eecc3 100644 --- a/lisp/color.el +++ b/lisp/color.el @@ -33,11 +33,6 @@ ;;; Code: -;; Emacs < 23.3 -(eval-and-compile - (unless (boundp 'float-pi) - (defconst float-pi (* 4 (atan 1)) "The value of Pi (3.1415926...)."))) - ;;;###autoload (defun color-name-to-rgb (color &optional frame) "Convert COLOR string to a list of normalized RGB components. commit ce1a4cd54c87626f5c1cba9832f0885325c792fb Author: Stefan Kangas Date: Fri Feb 5 01:27:14 2021 +0100 * lisp/textmodes/rst.el (rst-directive): Remove XEmacs compat code. diff --git a/lisp/textmodes/rst.el b/lisp/textmodes/rst.el index 18341716e3..2b31e7ed61 100644 --- a/lisp/textmodes/rst.el +++ b/lisp/textmodes/rst.el @@ -3627,10 +3627,7 @@ Region is from BEG to END. With WITH-EMPTY prefix empty lines too." "customize the face `rst-definition' instead." "24.1") -;; XEmacs compatibility (?). -(defface rst-directive (if (boundp 'font-lock-builtin-face) - '((t :inherit font-lock-builtin-face)) - '((t :inherit font-lock-preprocessor-face))) +(defface rst-directive '((t :inherit font-lock-builtin-face)) "Face used for directives and roles." :version "24.1" :group 'rst-faces) commit bbe88cd82e4bbfd76df06223614ab74d1022c119 Author: Stefan Kangas Date: Fri Feb 5 01:14:17 2021 +0100 Assume font-lock-mode variable is not void * lisp/align.el (align-rules-list): * lisp/cedet/semantic/idle.el (semantic-idle-summary-useful-context-p): * lisp/org/org-table.el (org-table-edit-field): * lisp/org/org.el (org-restart-font-lock): * lisp/progmodes/antlr-mode.el (antlr-language-option-extra): * lisp/progmodes/idlwave.el (idlwave-choose): * lisp/progmodes/sql.el (sql-product-font-lock): * lisp/progmodes/verilog-mode.el (verilog-save-font-no-change-functions, verilog-preprocess): * lisp/vc/cvs-status.el: * lisp/vc/smerge-mode.el (smerge-mode): * lisp/woman.el (woman-decode-buffer): Assume font-lock-mode variable is not void; it is preloaded. diff --git a/lisp/align.el b/lisp/align.el index 4d78393115..1a1d3dd7ec 100644 --- a/lisp/align.el +++ b/lisp/align.el @@ -424,7 +424,7 @@ The possible settings for `align-region-separate' are: (backward-word 1) (looking-at "\\(goto\\|return\\|new\\|delete\\|throw\\)")) - (if (and (boundp 'font-lock-mode) font-lock-mode) + (if font-lock-mode (eq (get-text-property (point) 'face) 'font-lock-comment-face) (eq (caar (c-guess-basic-syntax)) 'c))))))) diff --git a/lisp/cedet/semantic/idle.el b/lisp/cedet/semantic/idle.el index 73954f0266..9f1bcfa691 100644 --- a/lisp/cedet/semantic/idle.el +++ b/lisp/cedet/semantic/idle.el @@ -716,8 +716,7 @@ specific to a major mode. For example, in jde mode: (defun semantic-idle-summary-useful-context-p () "Non-nil if we should show a summary based on context." - (if (and (boundp 'font-lock-mode) - font-lock-mode + (if (and font-lock-mode (memq (get-text-property (point) 'face) semantic-idle-summary-out-of-context-faces)) ;; The best I can think of at the moment is to disable diff --git a/lisp/org/org-table.el b/lisp/org/org-table.el index ef4672e1b9..1248efabc1 100644 --- a/lisp/org/org-table.el +++ b/lisp/org/org-table.el @@ -2008,7 +2008,7 @@ toggle `org-table-follow-field-mode'." (let ((b (save-excursion (skip-chars-backward "^|") (point))) (e (save-excursion (skip-chars-forward "^|\r\n") (point)))) (remove-text-properties b e '(invisible t intangible t)) - (if (and (boundp 'font-lock-mode) font-lock-mode) + (if font-lock-mode (font-lock-fontify-block)))) (t (let ((pos (point-marker)) diff --git a/lisp/org/org.el b/lisp/org/org.el index 2d21a44fb4..e6a5cca939 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -5520,7 +5520,7 @@ highlighting was done, nil otherwise." (defun org-restart-font-lock () "Restart `font-lock-mode', to force refontification." - (when (and (boundp 'font-lock-mode) font-lock-mode) + (when font-lock-mode (font-lock-mode -1) (font-lock-mode 1))) diff --git a/lisp/progmodes/antlr-mode.el b/lisp/progmodes/antlr-mode.el index 527cb03cfb..e5b9ac0a53 100644 --- a/lisp/progmodes/antlr-mode.el +++ b/lisp/progmodes/antlr-mode.el @@ -2047,7 +2047,7 @@ Called in PHASE `after-insertion', see `antlr-options-alists'." (let ((new-language (antlr-language-option t))) (or (null new-language) (eq new-language antlr-language) - (let ((font-lock (and (boundp 'font-lock-mode) font-lock-mode))) + (let ((font-lock font-lock-mode)) (if font-lock (font-lock-mode 0)) (antlr-mode) (and font-lock (null font-lock-mode) (font-lock-mode 1))))))) diff --git a/lisp/progmodes/idlwave.el b/lisp/progmodes/idlwave.el index c11892492d..e8e55ae96d 100644 --- a/lisp/progmodes/idlwave.el +++ b/lisp/progmodes/idlwave.el @@ -6876,7 +6876,6 @@ sort the list before displaying." (let ((completion-ignore-case t)) ; install correct value (apply function args)) (if (and (derived-mode-p 'idlwave-shell-mode) - (boundp 'font-lock-mode) (not font-lock-mode)) ;; For the shell, remove the fontification of the word before point (let ((beg (save-excursion diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el index 4d027f3df5..f1f4d61324 100644 --- a/lisp/progmodes/sql.el +++ b/lisp/progmodes/sql.el @@ -2829,9 +2829,7 @@ configured." ;; Force font lock to reinitialize if it is already on ;; Otherwise, we can wait until it can be started. - (when (and (fboundp 'font-lock-mode) - (boundp 'font-lock-mode) - font-lock-mode) + (when font-lock-mode (font-lock-mode-internal nil) (font-lock-mode-internal t)) diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el index e5c2c80753..f934ef7a80 100644 --- a/lisp/progmodes/verilog-mode.el +++ b/lisp/progmodes/verilog-mode.el @@ -3442,7 +3442,7 @@ For insignificant changes, see instead `verilog-save-buffer-state'." (verilog-run-hooks 'verilog-before-save-font-hook) (let* ((verilog-save-font-mod-hooked (- (point-max) (point-min))) ;; Significant speed savings with no font-lock properties - (fontlocked (when (and (boundp 'font-lock-mode) font-lock-mode) + (fontlocked (when font-lock-mode (font-lock-mode 0) t))) (run-hook-with-args 'before-change-functions (point-min) (point-max)) @@ -5535,7 +5535,7 @@ FILENAME to find directory to run in, or defaults to `buffer-file-name'." default nil nil 'verilog-preprocess-history default))))) (unless command (setq command (verilog-expand-command verilog-preprocessor))) - (let* ((fontlocked (and (boundp 'font-lock-mode) font-lock-mode)) + (let* ((fontlocked font-lock-mode) (dir (file-name-directory (or filename buffer-file-name))) (cmd (concat "cd " dir "; " command))) (with-output-to-temp-buffer "*Verilog-Preprocessed*" diff --git a/lisp/vc/cvs-status.el b/lisp/vc/cvs-status.el index ff3a2944a1..26fb6206c8 100644 --- a/lisp/vc/cvs-status.el +++ b/lisp/vc/cvs-status.el @@ -356,9 +356,8 @@ the list is a three-string list TAG, KIND, REV." (defvar font-lock-mode) ;; (defun cvs-refontify (beg end) -;; (when (and (boundp 'font-lock-mode) -;; font-lock-mode -;; (fboundp 'font-lock-fontify-region)) +;; (when (and font-lock-mode +;; (fboundp 'font-lock-fontify-region)) ;; (font-lock-fontify-region (1- beg) (1+ end)))) (defun cvs-status-trees () diff --git a/lisp/vc/smerge-mode.el b/lisp/vc/smerge-mode.el index f50b2540c5..c66a4fb2d6 100644 --- a/lisp/vc/smerge-mode.el +++ b/lisp/vc/smerge-mode.el @@ -1410,7 +1410,7 @@ with a \\[universal-argument] prefix, makes up a 3-way conflict." \\{smerge-mode-map}" :group 'smerge :lighter " SMerge" - (when (and (boundp 'font-lock-mode) font-lock-mode) + (when font-lock-mode (save-excursion (if smerge-mode (font-lock-add-keywords nil smerge-font-lock-keywords 'append) diff --git a/lisp/woman.el b/lisp/woman.el index 1d3c8d1690..9a03d30bb7 100644 --- a/lisp/woman.el +++ b/lisp/woman.el @@ -2114,7 +2114,7 @@ No external programs are used." (interactive) ; mainly for testing (WoMan-log-begin) (run-hooks 'woman-pre-format-hook) - (and (boundp 'font-lock-mode) font-lock-mode (font-lock-mode -1)) + (and font-lock-mode (font-lock-mode -1)) ;; (fundamental-mode) (let ((start-time (current-time)) time) commit fc37dc298f27025823fad2d944e11cc7ee6a058d Author: Dmitry Gutov Date: Fri Feb 5 01:17:09 2021 +0200 Fix the previous change * lisp/progmodes/project.el (project-find-regexp): Fix the previous change (project-root is not defined in this version). (project-or-external-find-regexp): Same. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 2b35ea412f..ca0755cf8c 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -441,7 +441,7 @@ requires quoting, e.g. `\\[quoted-insert]'." (require 'xref) (require 'grep) (let* ((pr (project-current t)) - (default-directory (project-root pr)) + (default-directory (car (project-roots pr))) (files (if (not current-prefix-arg) (project-files pr (project-roots pr)) @@ -474,7 +474,7 @@ pattern to search for." (interactive (list (project--read-regexp))) (require 'xref) (let* ((pr (project-current t)) - (default-directory (project-root pr)) + (default-directory (car (project-roots pr))) (files (project-files pr (append (project-roots pr) commit b99848c72cb2570cfcab98443be9156b66dee830 Author: Dmitry Gutov Date: Thu Feb 4 03:38:27 2021 +0200 Bind default-directory to the project root * lisp/progmodes/project.el (project-find-regexp): Bind default-directory to the project root, to save this value in the resulting buffer (esp. if the project selector was used, (https://lists.gnu.org/archive/html/emacs-devel/2021-02/msg00140.html). (project-or-external-find-regexp): Same. (cherry picked from commit c07ebfcbe084e8219d8c2588f23f77ba4ef39087) diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 1caf8bed7d..2b35ea412f 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -441,6 +441,7 @@ requires quoting, e.g. `\\[quoted-insert]'." (require 'xref) (require 'grep) (let* ((pr (project-current t)) + (default-directory (project-root pr)) (files (if (not current-prefix-arg) (project-files pr (project-roots pr)) @@ -473,6 +474,7 @@ pattern to search for." (interactive (list (project--read-regexp))) (require 'xref) (let* ((pr (project-current t)) + (default-directory (project-root pr)) (files (project-files pr (append (project-roots pr) commit 19534f988c0f29199dfd51d627392bccf7426253 Author: Dmitry Gutov Date: Sat Jan 9 02:08:59 2021 +0200 Make sure default-directory relates to the originating buffer * lisp/progmodes/xref.el (xref--show-xref-buffer): Pick up default-directory value from the caller (https://lists.gnu.org/archive/html/emacs-devel/2021-01/msg00551.html). (xref-show-definitions-buffer-at-bottom): Same. (cherry picked from commit 6e73e07a6f5cbdd1c5ae6e0f3fbd0f8f56813f1a) diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 4c53c09d7b..309f48a817 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -852,8 +852,10 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (or (assoc-default 'fetched-xrefs alist) (funcall fetcher))) - (xref-alist (xref--analyze xrefs))) + (xref-alist (xref--analyze xrefs)) + (dd default-directory)) (with-current-buffer (get-buffer-create xref-buffer-name) + (setq default-directory dd) (xref--xref-buffer-mode) (xref--show-common-initialize xref-alist fetcher alist) (pop-to-buffer (current-buffer)) @@ -903,13 +905,15 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." When there is more than one definition, split the selected window and show the list in a small window at the bottom. And use a local keymap that binds `RET' to `xref-quit-and-goto-xref'." - (let ((xrefs (funcall fetcher))) + (let ((xrefs (funcall fetcher)) + (dd default-directory)) (cond ((not (cdr xrefs)) (xref-pop-to-location (car xrefs) (assoc-default 'display-action alist))) (t (with-current-buffer (get-buffer-create xref-buffer-name) + (setq default-directory dd) (xref--transient-buffer-mode) (xref--show-common-initialize (xref--analyze xrefs) fetcher alist) (pop-to-buffer (current-buffer) commit a92167674f6f2bbe4e97c40b483995d08ab15b85 Author: Harald Jörg Date: Thu Feb 4 20:52:20 2021 +0100 cperl-mode: eliminate dead code * lisp/progmodes/cperl-mode.el (cperl-update-syntaxification): Eliminate check for `syntax-propertize-rules` (always true) and eliminate unused first parameter. (cperl-mode): Eliminate obsolete `font-lock-syntactic-keywords`, Eliminate check for `syntax-propertize-rules` (always true). (cperl-fontify-syntaxically): Eliminate call to no-longer-existing function `edebug-backtrace` (bug#46302). diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index d401513646..a70e8e36c0 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -1157,25 +1157,25 @@ versions of Emacs." (get-text-property (point-min) 'in-pod) (< (progn (and cperl-syntaxify-for-menu - (cperl-update-syntaxification (point-max) (point-max))) + (cperl-update-syntaxification (point-max))) (next-single-property-change (point-min) 'in-pod nil (point-max))) (point-max)))] ["Ispell HERE-DOCs" cperl-here-doc-spell (< (progn (and cperl-syntaxify-for-menu - (cperl-update-syntaxification (point-max) (point-max))) + (cperl-update-syntaxification (point-max))) (next-single-property-change (point-min) 'here-doc-group nil (point-max))) (point-max))] ["Narrow to this HERE-DOC" cperl-narrow-to-here-doc (eq 'here-doc (progn (and cperl-syntaxify-for-menu - (cperl-update-syntaxification (point) (point))) + (cperl-update-syntaxification (point))) (get-text-property (point) 'syntax-type)))] ["Select this HERE-DOC or POD section" cperl-select-this-pod-or-here-doc (memq (progn (and cperl-syntaxify-for-menu - (cperl-update-syntaxification (point) (point))) + (cperl-update-syntaxification (point))) (get-text-property (point) 'syntax-type)) '(here-doc pod))] "----" @@ -1659,36 +1659,18 @@ or as help on variables `cperl-tips', `cperl-problems', nil nil ((?_ . "w")))) ;; Reset syntaxification cache. (setq-local cperl-syntax-state nil) - (if cperl-use-syntax-table-text-property - (if (eval-when-compile (fboundp 'syntax-propertize-rules)) - (progn - ;; Reset syntaxification cache. - (setq-local cperl-syntax-done-to nil) - (setq-local syntax-propertize-function - (lambda (start end) - (goto-char start) - ;; Even if cperl-fontify-syntaxically has already gone - ;; beyond `start', syntax-propertize has just removed - ;; syntax-table properties between start and end, so we have - ;; to re-apply them. - (setq cperl-syntax-done-to start) - (cperl-fontify-syntaxically end)))) - ;; Do not introduce variable if not needed, we check it! - (setq-local parse-sexp-lookup-properties t) - ;; Our: just a plug for wrong font-lock - (setq-local font-lock-unfontify-region-function - ;; not present with old Emacs - #'cperl-font-lock-unfontify-region-function) - ;; Reset syntaxification cache. - (setq-local cperl-syntax-done-to nil) - (setq-local font-lock-syntactic-keywords - (if cperl-syntaxify-by-font-lock - '((cperl-fontify-syntaxically)) - ;; unless font-lock-syntactic-keywords, font-lock (pre-22.1) - ;; used to ignore syntax-table text-properties. (t) is a hack - ;; to make font-lock think that font-lock-syntactic-keywords - ;; are defined. - '(t))))) + (when cperl-use-syntax-table-text-property + ;; Reset syntaxification cache. + (setq-local cperl-syntax-done-to nil) + (setq-local syntax-propertize-function + (lambda (start end) + (goto-char start) + ;; Even if cperl-fontify-syntaxically has already gone + ;; beyond `start', syntax-propertize has just removed + ;; syntax-table properties between start and end, so we have + ;; to re-apply them. + (setq cperl-syntax-done-to start) + (cperl-fontify-syntaxically end)))) (setq cperl-font-lock-multiline t) ; Not localized... (setq-local font-lock-multiline t) (setq-local font-lock-fontify-region-function @@ -2405,7 +2387,7 @@ means indent rigidly all the lines of the expression starting after point so that this line becomes properly indented. The relative indentation among the lines of the expression are preserved." (interactive "P") - (cperl-update-syntaxification (point) (point)) + (cperl-update-syntaxification (point)) (if whole-exp ;; If arg, always indent this line as Perl ;; and shift remaining lines of expression the same amount. @@ -2533,7 +2515,7 @@ Will not look before LIM." (defun cperl-sniff-for-indent (&optional parse-data) ; was parse-start ;; the sniffer logic to understand what the current line MEANS. - (cperl-update-syntaxification (point) (point)) + (cperl-update-syntaxification (point)) (let ((res (get-text-property (point) 'syntax-type))) (save-excursion (cond @@ -3025,7 +3007,7 @@ Returns true if comment is found. In POD will not move the point." ;; then looks for literal # or end-of-line. (let (state stop-in cpoint (lim (point-at-eol)) pr e) (or cperl-font-locking - (cperl-update-syntaxification lim lim)) + (cperl-update-syntaxification lim)) (beginning-of-line) (if (setq pr (get-text-property (point) 'syntax-type)) (setq e (next-single-property-change (point) 'syntax-type nil (point-max)))) @@ -4640,7 +4622,7 @@ CHARS is a string that contains good characters to have before us (however, `}' is treated \"smartly\" if it is not in the list)." (let ((lim (or lim (point-min))) stop p) - (cperl-update-syntaxification (point) (point)) + (cperl-update-syntaxification (point)) (save-excursion (while (and (not stop) (> (point) lim)) (skip-chars-backward " \t\n\f" lim) @@ -5027,7 +5009,7 @@ inclusive. If `cperl-indent-region-fix-constructs', will improve spacing on conditional/loop constructs." (interactive "r") - (cperl-update-syntaxification end end) + (cperl-update-syntaxification end) (save-excursion (let (cperl-update-start cperl-update-end (h-a-c after-change-functions)) (let ((indent-info (list nil nil nil) ; Cannot use '(), since will modify @@ -5233,7 +5215,7 @@ indentation and initial hashes. Behaves usually outside of comment." packages ends-ranges p marker is-proto is-pack index index1 name (end-range 0) package) (goto-char (point-min)) - (cperl-update-syntaxification (point-max) (point-max)) + (cperl-update-syntaxification (point-max)) ;; Search for the function (progn ;;save-match-data (while (re-search-forward @@ -8209,7 +8191,7 @@ function returns nil." (or prop (setq prop 'in-pod)) (or s (setq s (point-min))) (or end (setq end (point-max))) - (cperl-update-syntaxification end end) + (cperl-update-syntaxification end) (save-excursion (goto-char (setq pos s)) (while (and cont (< pos end)) @@ -8225,7 +8207,7 @@ function returns nil." Return nil if the point is not in a HERE document region. If POD is non-nil, will return a POD section if point is in a POD section." (or pos (setq pos (point))) - (cperl-update-syntaxification pos pos) + (cperl-update-syntaxification pos) (if (or (eq 'here-doc (get-text-property pos 'syntax-type)) (and pod (eq 'pod (get-text-property pos 'syntax-type)))) @@ -8295,7 +8277,7 @@ start with default arguments, then refine the slowdown regions." (forward-line step) (setq l (+ l step)) (setq c (1+ c)) - (cperl-update-syntaxification (point) (point)) + (cperl-update-syntaxification (point)) (setq delta (- (- tt (setq tt (funcall timems)))) tot (+ tot delta)) (message "to %s:%6s,%7s" l delta tot)) tot)) @@ -8405,19 +8387,12 @@ do extra unwind via `cperl-unwind-to-safe'." (setq end (point))) (font-lock-default-fontify-region beg end loudly)) -(defvar cperl-d-l nil) -(defvar edebug-backtrace-buffer) ;FIXME: Why? (defun cperl-fontify-syntaxically (end) ;; Some vars for debugging only ;; (message "Syntaxifying...") (let ((dbg (point)) (iend end) (idone cperl-syntax-done-to) (istate (car cperl-syntax-state)) - start from-start edebug-backtrace-buffer) - (if (eq cperl-syntaxify-by-font-lock 'backtrace) - (progn - (require 'edebug) - (let ((f 'edebug-backtrace)) - (funcall f)))) ; Avoid compile-time warning + start from-start) (or cperl-syntax-done-to (setq cperl-syntax-done-to (point-min) from-start t)) @@ -8473,16 +8448,9 @@ do extra unwind via `cperl-unwind-to-safe'." (if cperl-syntax-done-to (setq cperl-syntax-done-to (min cperl-syntax-done-to beg)))) -(defun cperl-update-syntaxification (from to) - (cond - ((not cperl-use-syntax-table-text-property) nil) - ((fboundp 'syntax-propertize) (syntax-propertize to)) - ((and cperl-syntaxify-by-font-lock - (or (null cperl-syntax-done-to) - (< cperl-syntax-done-to to))) - (save-excursion - (goto-char from) - (cperl-fontify-syntaxically to))))) +(defun cperl-update-syntaxification (to) + (when cperl-use-syntax-table-text-property + (syntax-propertize to))) (defvar cperl-version (let ((v "Revision: 6.2")) commit d1455027e0b04b67e903f5ef658a3fd65ca4da48 Author: Eli Zaretskii Date: Thu Feb 4 20:21:18 2021 +0200 Initialize signal descriptions after pdumping * src/sysdep.c (init_signals) [!HAVE_DECL_SYS_SIGLIST]: Reinit sys_siglist also after pdumping. (Bug#46284) diff --git a/src/sysdep.c b/src/sysdep.c index f94ce4d492..d100a5cb50 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1980,7 +1980,8 @@ init_signals (void) #endif #if !HAVE_DECL_SYS_SIGLIST && !defined _sys_siglist - if (! initialized) + if (! initialized + || dumped_with_pdumper_p ()) { sys_siglist[SIGABRT] = "Aborted"; # ifdef SIGAIO commit a2d7f3f171386f39a55f73988f94b1f4c94d8a6b Author: Eli Zaretskii Date: Thu Feb 4 19:35:07 2021 +0200 Avoid overwriting minibuffer prompt by keystrokes echo * src/lread.c (Fread_char, Fread_event, Fread_char_exclusive): Call cancel_echoing to make sure the prompt is not obscured by keystrokes echo. (Bug#46243) diff --git a/src/lread.c b/src/lread.c index b33a312299..010194c34e 100644 --- a/src/lread.c +++ b/src/lread.c @@ -804,7 +804,10 @@ If `inhibit-interaction' is non-nil, this function will signal an barf_if_interaction_inhibited (); if (! NILP (prompt)) - message_with_string ("%s", prompt, 0); + { + cancel_echoing (); + message_with_string ("%s", prompt, 0); + } val = read_filtered_event (1, 1, 1, ! NILP (inherit_input_method), seconds); return (NILP (val) ? Qnil @@ -839,7 +842,10 @@ If `inhibit-interaction' is non-nil, this function will signal an barf_if_interaction_inhibited (); if (! NILP (prompt)) - message_with_string ("%s", prompt, 0); + { + cancel_echoing (); + message_with_string ("%s", prompt, 0); + } return read_filtered_event (0, 0, 0, ! NILP (inherit_input_method), seconds); } @@ -875,7 +881,10 @@ If `inhibit-interaction' is non-nil, this function will signal an barf_if_interaction_inhibited (); if (! NILP (prompt)) - message_with_string ("%s", prompt, 0); + { + cancel_echoing (); + message_with_string ("%s", prompt, 0); + } val = read_filtered_event (1, 1, 0, ! NILP (inherit_input_method), seconds); commit 3bf21f52b653a71801d371fcac0fcc862a95ec32 Author: Lars Ingebrigtsen Date: Thu Feb 4 18:24:28 2021 +0100 Deactivate region in `C-c C-r' in python-mode * lisp/progmodes/python.el (python-shell-send-region): Deactivate mark after executing (bug#28789). This is how this command worked in Emacs 24, apparently. diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index d6c0a4d1db..afb96974b1 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -3273,7 +3273,8 @@ process running; defaults to t when called interactively." ;; lines have been removed/added. (with-current-buffer (process-buffer process) (compilation-forget-errors)) - (python-shell-send-string string process))) + (python-shell-send-string string process) + (deactivate-mark))) (defun python-shell-send-statement (&optional send-main msg) "Send the statement at point to inferior Python process. commit a304b22bc9f1396cd6958b0a6fc6092437e36d96 Merge: 914cb7a1d6 9bf367e184 Author: Eli Zaretskii Date: Thu Feb 4 18:02:27 2021 +0200 Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs commit 914cb7a1d666a87994e0492635f262396a839d4c Author: Eli Zaretskii Date: Thu Feb 4 18:00:29 2021 +0200 Fix 'window-text-pixel-size' for short spans of text * src/xdisp.c (Fwindow_text_pixel_size): Support the use case where FROM and TO belong to the same screen line. Reported by Yuan Fu . diff --git a/src/xdisp.c b/src/xdisp.c index eb3f221df8..426c874cdb 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10714,8 +10714,23 @@ include the height of both, if present, in the return value. */) same directionality. */ it.bidi_p = false; + /* Start at the beginning of the line containing FROM. Otherwise + IT.current_x will be incorrectly set to zero at some arbitrary + non-zero X coordinate. */ + reseat_at_previous_visible_line_start (&it); + it.current_x = it.hpos = 0; + if (IT_CHARPOS (it) != start) + move_it_to (&it, start, -1, -1, -1, MOVE_TO_POS); + + /* Now move to TO. */ + int start_x = it.current_x; int move_op = MOVE_TO_POS | MOVE_TO_Y; int to_x = -1; + it.current_y = 0; + /* If FROM is on a newline, pretend that we start at the beginning + of the next line, because the newline takes no place on display. */ + if (FETCH_BYTE (start) == '\n') + it.current_x = 0; if (!NILP (x_limit)) { it.last_visible_x = max_x; @@ -10758,6 +10773,12 @@ include the height of both, if present, in the return value. */) x = max_x; } + /* If text spans more than one screen line, we don't need to adjust + the x-span for start_x, since the second and subsequent lines + will begin at zero X coordinate. */ + if (it.current_y > 0) + start_x = 0; + /* Subtract height of header-line which was counted automatically by start_display. */ y = it.current_y + it.max_ascent + it.max_descent @@ -10786,7 +10807,7 @@ include the height of both, if present, in the return value. */) if (old_b) set_buffer_internal (old_b); - return Fcons (make_fixnum (x), make_fixnum (y)); + return Fcons (make_fixnum (x - start_x), make_fixnum (y)); } /*********************************************************************** commit 256356a36fa15c17968febfb3fa49ac33872a11e Author: Lars Ingebrigtsen Date: Thu Feb 4 12:02:53 2021 +0100 Clarify the "Sentinels" node in the lispref manual * doc/lispref/processes.texi (Sentinels): Mention "run" and that the strings can be anything (bug#30461). (cherry picked from commit 859a4cb6b22f75a3456e29d08fcfe9b8940fbe8b) diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 42f436501f..063b5f5134 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -1969,7 +1969,8 @@ describing the type of event. default sentinel function, which inserts a message in the process's buffer with the process name and the string describing the event. - The string describing the event looks like one of the following: + The string describing the event looks like one of the following (but +this is not an exhaustive list of event strings): @itemize @bullet @item @@ -1999,6 +2000,9 @@ core. @item @code{"open\n"}. +@item +@code{"run\n"}. + @item @code{"connection broken by remote peer\n"}. @end itemize commit 9bf367e18486b8f89ff1e0a4c4f4b5b4da4d9a75 Author: Lars Ingebrigtsen Date: Thu Feb 4 16:12:41 2021 +0100 Improve filling of Emacs Lisp doc strings * lisp/emacs-lisp/lisp-mode.el (lisp-fill-paragraph): When filling a Lisp string, try to avoid filling bits that follow it (bug#28937). diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 5dda3a8f8e..f5ce107185 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -1373,7 +1373,24 @@ and initial semicolons." (derived-mode-p 'emacs-lisp-mode)) emacs-lisp-docstring-fill-column fill-column))) - (fill-paragraph justify)) + (save-restriction + (save-excursion + (let ((ppss (syntax-ppss))) + ;; If we're in a string, then narrow (roughly) to that + ;; string before filling. This avoids filling Lisp + ;; statements that follow the string. + (when (ppss-string-terminator ppss) + (goto-char (ppss-comment-or-string-start ppss)) + (beginning-of-line) + ;; The string may be unterminated -- in that case, don't + ;; narrow. + (when (ignore-errors + (progn + (forward-sexp 1) + t)) + (narrow-to-region (ppss-comment-or-string-start ppss) + (point)))) + (fill-paragraph justify))))) ;; Never return nil. t)) commit e1d54bb638dfb017acb778a45092f97bb0d3427c Author: Lars Ingebrigtsen Date: Thu Feb 4 15:22:40 2021 +0100 Allow a :variable keyword in define-globalized-minor-mode * doc/lispref/modes.texi (Defining Minor Modes): Document it. * lisp/emacs-lisp/easy-mmode.el (define-globalized-minor-mode): Allow specifying a :variable to be used if the underlying mode has a divergent variable to store the state (bug#29081). diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index abc1254641..ce7727b87e 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -1826,6 +1826,11 @@ starts, for example by providing a @code{:require} keyword. Use @code{:group @var{group}} in @var{keyword-args} to specify the custom group for the mode variable of the global minor mode. +By default, the buffer-local minor mode variable that says whether the +mode is switched on or off is the same as the name of the mode itself. +Use @code{:variable @var{variable}} if that's not the case--some minor +modes use a different variable to store this state information. + Generally speaking, when you define a globalized minor mode, you should also define a non-globalized version, so that people can use (or disable) it in individual buffers. This also allows them to disable a diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 54c0cf08b7..2916ae4ade 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -418,6 +418,7 @@ on if the hook has explicitly disabled it. (pretty-global-name (easy-mmode-pretty-mode-name global-mode)) (group nil) (extra-keywords nil) + (MODE-variable mode) (MODE-buffers (intern (concat global-mode-name "-buffers"))) (MODE-enable-in-buffers (intern (concat global-mode-name "-enable-in-buffers"))) @@ -439,6 +440,7 @@ on if the hook has explicitly disabled it. (pcase keyw (:group (setq group (nconc group (list :group (pop body))))) (:global (pop body)) + (:variable (setq MODE-variable (pop body))) (:predicate (setq predicate (list (pop body))) (setq turn-on-function @@ -541,7 +543,7 @@ list." (with-current-buffer buf (unless ,MODE-set-explicitly (unless (eq ,MODE-major-mode major-mode) - (if ,mode + (if ,MODE-variable (progn (,mode -1) (funcall ,turn-on-function)) commit bd795dd659d6f67077f1870bbb775df15ce6001b Author: Lars Ingebrigtsen Date: Thu Feb 4 14:36:58 2021 +0100 Fix previous ibuffer patch * lisp/ibuffer.el (ibuffer-last-sorting-mode): Restore variable removed by mistake in previous change. diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el index c91a70b3a1..c0a6d16c6f 100644 --- a/lisp/ibuffer.el +++ b/lisp/ibuffer.el @@ -219,6 +219,7 @@ view of the buffers." (const :tag "File name" :value filename/process) (const :tag "Major mode" :value major-mode))) (defvar ibuffer-sorting-mode nil) +(defvar ibuffer-last-sorting-mode nil) (defcustom ibuffer-default-sorting-reversep nil "If non-nil, reverse the default sorting order." commit d3cb07d784a4c4029f0a50ba003ebf4b93dd59c3 Author: Lars Ingebrigtsen Date: Thu Feb 4 12:59:16 2021 +0100 Make the recency sorting stable when we have inverted sorting * lisp/ibuffer.el (recency): Remove. (recency): New macro function so that sorting by recency is stable when inverted sorting is switched on (bug#30129). diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el index 84c53b16ac..c91a70b3a1 100644 --- a/lisp/ibuffer.el +++ b/lisp/ibuffer.el @@ -219,7 +219,6 @@ view of the buffers." (const :tag "File name" :value filename/process) (const :tag "Major mode" :value major-mode))) (defvar ibuffer-sorting-mode nil) -(defvar ibuffer-last-sorting-mode nil) (defcustom ibuffer-default-sorting-reversep nil "If non-nil, reverse the default sorting order." @@ -2129,16 +2128,13 @@ the value of point at the beginning of the line for that buffer." (and ibuffer-buf (not (eq ibuffer-buf buf)))))) -;; This function is a special case; it's not defined by -;; `define-ibuffer-sorter'. -(defun ibuffer-do-sort-by-recency () - "Sort the buffers by last view time." - (interactive) - (setq ibuffer-sorting-mode 'recency) - (when (eq ibuffer-last-sorting-mode 'recency) - (setq ibuffer-sorting-reversep (not ibuffer-sorting-reversep))) - (ibuffer-update nil t) - (setq ibuffer-last-sorting-mode 'recency)) +(define-ibuffer-sorter recency + "Sort the buffers by how recently they've been used." + (:description "recency") + (time-less-p (with-current-buffer (car b) + (or buffer-display-time 0)) + (with-current-buffer (car a) + (or buffer-display-time 0)))) (defun ibuffer-update-format () (when (null ibuffer-current-format) commit 3b27f2e46494cbcb5a2c81bd68617ecdf3bc4ad9 Author: Lars Ingebrigtsen Date: Thu Feb 4 12:32:08 2021 +0100 Revert "Tweak how ibuffer-invert-sorting updates the buffer" This reverts commit b8b3263eab688b97530a7bf7d565b084df56ea08. This doesn't fix other instances of ibuffer-redisplay diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el index d3d2b324c1..44574abd46 100644 --- a/lisp/ibuf-ext.el +++ b/lisp/ibuf-ext.el @@ -1446,7 +1446,7 @@ Default sorting modes are: (if ibuffer-sorting-reversep "reversed" "normal")) - (ibuffer-update nil t)) + (ibuffer-redisplay t)) ;;;###autoload (autoload 'ibuffer-do-sort-by-major-mode "ibuf-ext") (define-ibuffer-sorter major-mode commit b8b3263eab688b97530a7bf7d565b084df56ea08 Author: Lars Ingebrigtsen Date: Thu Feb 4 12:26:00 2021 +0100 Tweak how ibuffer-invert-sorting updates the buffer * lisp/ibuf-ext.el (ibuffer-invert-sorting): Enable calling this function repeatedly with more predictable results (bug#30129). diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el index 44574abd46..d3d2b324c1 100644 --- a/lisp/ibuf-ext.el +++ b/lisp/ibuf-ext.el @@ -1446,7 +1446,7 @@ Default sorting modes are: (if ibuffer-sorting-reversep "reversed" "normal")) - (ibuffer-redisplay t)) + (ibuffer-update nil t)) ;;;###autoload (autoload 'ibuffer-do-sort-by-major-mode "ibuf-ext") (define-ibuffer-sorter major-mode commit b12d22f6afd75d7556e301304c0529936828cf2b Author: Lars Ingebrigtsen Date: Thu Feb 4 12:08:46 2021 +0100 Don't ask the user to make a bug report on missing arglists * lisp/help-fns.el (help-fns--signature): Don't ask the user to make a bug report (bug#30223) because the symbol may very well be one that the user has defined themselves. (help-fns-function-description-header): Ditto. diff --git a/lisp/help-fns.el b/lisp/help-fns.el index da90519246..b03a440412 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -533,7 +533,7 @@ suitable file is found, return nil." (format "\nMacro: %s" (help--docstring-quote (format-kbd-macro real-def)))) - (t "[Missing arglist. Please make a bug report.]"))) + (t "[Missing arglist.]"))) ;; Insert "`X", not "(\` X)", when documenting `X. (use1 (replace-regexp-in-string "\\`(\\\\=\\\\\\\\=` \\([^\n ]*\\))\\'" @@ -839,7 +839,7 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)." (t ""))) (if (and aliased (not (fboundp real-def))) - (princ ",\nwhich is not defined. Please make a bug report.") + (princ ",\nwhich is not defined.") (with-current-buffer standard-output (save-excursion (save-match-data commit 859a4cb6b22f75a3456e29d08fcfe9b8940fbe8b Author: Lars Ingebrigtsen Date: Thu Feb 4 12:02:53 2021 +0100 Clarify the "Sentinels" node in the lispref manual * doc/lispref/processes.texi (Sentinels): Mention "run" and that the strings can be anything (bug#30461). diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 6dedaa31f2..8346165606 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -2017,7 +2017,8 @@ describing the type of event. default sentinel function, which inserts a message in the process's buffer with the process name and the string describing the event. - The string describing the event looks like one of the following: + The string describing the event looks like one of the following (but +this is not an exhaustive list of event strings): @itemize @bullet @item @@ -2047,6 +2048,9 @@ core. @item @code{"open\n"}. +@item +@code{"run\n"}. + @item @code{"connection broken by remote peer\n"}. @end itemize commit 828b3d93eca4215baac4bab74156eeb3fa02955e Author: Lars Ingebrigtsen Date: Thu Feb 4 11:55:44 2021 +0100 Allow eshell to have an "erasedups"-like history * lisp/eshell/em-hist.el (eshell-add-input-to-history): Use the new value (bug#30466). (eshell-hist-ignoredups): Allow "erasedups"-like value. diff --git a/etc/NEWS b/etc/NEWS index 7cdb9d9430..dddc150af1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -958,6 +958,9 @@ command line under point (and any following output). ** Eshell +--- +*** 'eshell-hist-ignoredups' can now also be used to mimic "erasedups" in bash. + --- *** Environment variable 'INSIDE_EMACS' is now copied to subprocesses. Its value equals the result of evaluating '(format "%s,eshell" emacs-version)'. diff --git a/lisp/eshell/em-hist.el b/lisp/eshell/em-hist.el index 0d09ef4a12..b7b1778ebb 100644 --- a/lisp/eshell/em-hist.el +++ b/lisp/eshell/em-hist.el @@ -99,8 +99,12 @@ If it is nil, Eshell will use the value of HISTFILE." (defcustom eshell-hist-ignoredups nil "If non-nil, don't add input matching the last on the input ring. -This mirrors the optional behavior of bash." - :type 'boolean) +The value `erase' mirrors the \"erasedups\" value of HISTCONTROL +in bash, and any other non-nil value mirrors the \"ignoredups\" +value." + :type '(choice (const :tag "Don't ignore anything" nil) + (const :tag "Ignore consecutive duplicates" t) + (const :tag "Only keep last duplicate" 'erase))) (defcustom eshell-save-history-on-exit t "Determine if history should be automatically saved. @@ -371,12 +375,22 @@ unless a different file is specified on the command line.") Input is entered into the input history ring, if the value of variable `eshell-input-filter' returns non-nil when called on the input." - (if (and (funcall eshell-input-filter input) - (or (null eshell-hist-ignoredups) - (not (ring-p eshell-history-ring)) - (ring-empty-p eshell-history-ring) - (not (string-equal (eshell-get-history 0) input)))) - (eshell-put-history input)) + (when (and (funcall eshell-input-filter input) + (if (eq eshell-hist-ignoredups 'erase) + ;; Remove any old occurrences of the input, and put + ;; the new one at the end. + (progn + (ring-remove eshell-history-ring + (ring-member eshell-history-ring input)) + t) + ;; Always add... + (or (null eshell-hist-ignoredups) + ;; ... or add if it's not already present at the + ;; end. + (not (ring-p eshell-history-ring)) + (ring-empty-p eshell-history-ring) + (not (string-equal (eshell-get-history 0) input))))) + (eshell-put-history input)) (setq eshell-save-history-index eshell-history-index) (setq eshell-history-index nil)) commit 2f3df36be8bd57dc3bf002e26e9e761c5b2cf878 Author: Robert Pluim Date: Thu Feb 4 11:24:13 2021 +0100 Update description of 'tramp-crypt-remove-directory' * doc/misc/tramp.texi (Keeping files encrypted): Correct name of function to use to indicate files should no longer be encrypted, and update its description. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index efe839574d..c2e9fe66df 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -2792,9 +2792,10 @@ visiting a file will show its encrypted contents. However, it is highly discouraged to mix encrypted and not encrypted files in the same directory. -@deffn Command tramp-crypt-add-directory name -If a remote directory shall not include encrypted files anymore, it -must be indicated by this command. +@deffn Command tramp-crypt-remove-directory name +This command should be used to indicate that files in @code{name} +should no longer be encrypted. Existing encrypted files and +subdirectories will remain encrypted. @end deffn commit 517e123f90175f9c8fb94348c46d7d6d3236d57a Author: Lars Ingebrigtsen Date: Thu Feb 4 11:23:21 2021 +0100 Be stricter when going back to the previous node in Info-find-node-2 * lisp/info.el (Info-find-node-2): When going back to the previous node, be strict (bug#31137) since we have the exact node name. diff --git a/lisp/info.el b/lisp/info.el index dec93928b3..7f169f4b55 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -1260,9 +1260,9 @@ is non-nil)." (if Info-history (let ((hist (car Info-history))) (setq Info-history (cdr Info-history)) - (Info-find-node (nth 0 hist) (nth 1 hist) t) + (Info-find-node (nth 0 hist) (nth 1 hist) t t) (goto-char (nth 2 hist))) - (Info-find-node Info-current-file "Top" t))))) + (Info-find-node Info-current-file "Top" t t))))) ;; Cache the contents of the (virtual) dir file, once we have merged ;; it for the first time, so we can save time subsequently. commit 5666955379e8ca82d072c1aba60a2c58ff3f855a Author: Juri Linkov Date: Thu Feb 4 11:17:54 2021 +0200 * lisp/replace.el (occur-rename-buffer): Check for overlay (bug#46268). (occur-1): Don't use occur--garbage-collect-revert-args when reverting the Occur buffer with same bufs. diff --git a/lisp/replace.el b/lisp/replace.el index f13d27aff8..d320542d62 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -1545,7 +1545,10 @@ You can add this to `occur-hook' if you always want a separate (with-current-buffer (if (eq major-mode 'occur-mode) (current-buffer) (get-buffer "*Occur*")) (rename-buffer (concat "*Occur: " - (mapconcat #'buffer-name + (mapconcat (lambda (boo) + (buffer-name (if (overlayp boo) + (overlay-buffer boo) + boo))) (car (cddr occur-revert-arguments)) "/") "*") (or unique-p (not interactive-p))))) @@ -1779,7 +1782,8 @@ See also `multi-occur'." 42) (window-width)) "" (occur-regexp-descr regexp)))) - (occur--garbage-collect-revert-args) + (unless (eq bufs (nth 2 occur-revert-arguments)) + (occur--garbage-collect-revert-args)) (setq occur-revert-arguments (list regexp nlines bufs)) (if (= count 0) (kill-buffer occur-buf) commit a8958640c4d8b17d6bc093d94741565276fa9e5f Author: Lars Ingebrigtsen Date: Thu Feb 4 09:25:28 2021 +0100 Fix epg filtering out keys that contain revoked IDs * lisp/epg.el (epg--filter-revoked-keys): Only filter out the revoked user ids, not the entire key that contains revoked user ids (bug#46138). diff --git a/lisp/epg.el b/lisp/epg.el index b1f37cbbdc..36794d09a7 100644 --- a/lisp/epg.el +++ b/lisp/epg.el @@ -332,7 +332,6 @@ callback data (if any)." (cl-defstruct (epg-key (:constructor nil) (:constructor epg-make-key (owner-trust)) - (:copier nil) (:predicate nil)) (owner-trust nil :read-only t) sub-key-list user-id-list) @@ -1383,11 +1382,22 @@ NAME is either a string or a list of strings." keys)) (defun epg--filter-revoked-keys (keys) - (seq-remove (lambda (key) - (seq-find (lambda (user) - (eq (epg-user-id-validity user) 'revoked)) - (epg-key-user-id-list key))) - keys)) + (mapcar + (lambda (key) + ;; We have something revoked, so copy the key and remove the + ;; revoked bits. + (if (seq-find (lambda (user) + (eq (epg-user-id-validity user) 'revoked)) + (epg-key-user-id-list key)) + (let ((copy (copy-epg-key key))) + (setf (epg-key-user-id-list copy) + (seq-remove (lambda (user) + (eq (epg-user-id-validity user) 'revoked)) + (epg-key-user-id-list copy))) + copy) + ;; Nothing to delete; return the key. + key)) + keys)) (defun epg--args-from-sig-notations (notations) (apply #'nconc commit 89f1634afcca318def07151424a21b81c70acd76 Author: Alexandre Duret-Lutz Date: Mon Jan 11 15:27:54 2021 +0100 Fix problem with non-ASCII characters in nnmaildir * lisp/gnus/nnmaildir.el (nnmaildir-request-article): Enable multipart 8bit-content-transfer-encoded files to be displayed correctly by reading as `raw-text' instead of having Emacs (incorrectly) decode the files (bug#44307). Copyright-paperwork-exempt: yes diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el index 9cf766ee46..5461c4c960 100644 --- a/lisp/gnus/nnmaildir.el +++ b/lisp/gnus/nnmaildir.el @@ -1351,7 +1351,8 @@ This variable is set by `nnmaildir-request-article'.") (throw 'return nil)) (with-current-buffer (or to-buffer nntp-server-buffer) (erase-buffer) - (nnheader-insert-file-contents nnmaildir-article-file-name)) + (let ((coding-system-for-read mm-text-coding-system)) + (mm-insert-file-contents nnmaildir-article-file-name))) (cons gname num-msgid)))) (defun nnmaildir-request-post (&optional _server) commit e4cafc5430615cf282038e26650719654834418c Author: Stefan Kangas Date: Thu Feb 4 08:16:33 2021 +0100 Don't set removed variable facemenu-unlisted-faces * lisp/vc/ediff-init.el (ediff-hide-face): Redefine as obsolete function alias for 'ignore'; the variable 'facemenu-unlisted-faces' was removed in Emacs 22. Remove all calls. * lisp/mh-e/mh-e.el: Add comment saying that the variable 'facemenu-unlisted-faces' is removed. diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el index 9185c2a064..2eb7fbaa20 100644 --- a/lisp/mh-e/mh-e.el +++ b/lisp/mh-e/mh-e.el @@ -3412,6 +3412,7 @@ sequence." ;;; Faces (:group 'mh-faces + group where faces described) (if (boundp 'facemenu-unlisted-faces) + ;; This variable was removed in Emacs 22.1. (add-to-list 'facemenu-unlisted-faces "^mh-")) ;; To add a new face: diff --git a/lisp/vc/ediff-init.el b/lisp/vc/ediff-init.el index c20d03c83d..6e658163b9 100644 --- a/lisp/vc/ediff-init.el +++ b/lisp/vc/ediff-init.el @@ -797,13 +797,6 @@ to temp files in buffer jobs and when Ediff needs to find fine differences." (message "Pixmap not found for %S: %s" (face-name face) pixmap) (sit-for 1))))) -(defun ediff-hide-face (face) - (if (and (ediff-has-face-support-p) - (boundp 'add-to-list) - (boundp 'facemenu-unlisted-faces)) - (add-to-list 'facemenu-unlisted-faces face))) - - (defface ediff-current-diff-A '((((class color) (min-colors 88) (background light)) @@ -824,7 +817,6 @@ to temp files in buffer jobs and when Ediff needs to find fine differences." DO NOT CHANGE this variable. Instead, use the customization widget to customize the actual face object `ediff-current-diff-A' this variable represents.") -(ediff-hide-face ediff-current-diff-face-A) (defface ediff-current-diff-B '((((class color) (min-colors 88) (background light)) @@ -846,7 +838,6 @@ this variable represents.") this variable. Instead, use the customization widget to customize the actual face `ediff-current-diff-B' this variable represents.") -(ediff-hide-face ediff-current-diff-face-B) (defface ediff-current-diff-C '((((class color) (min-colors 88) (background light)) @@ -867,7 +858,6 @@ this variable represents.") DO NOT CHANGE this variable. Instead, use the customization widget to customize the actual face object `ediff-current-diff-C' this variable represents.") -(ediff-hide-face ediff-current-diff-face-C) (defface ediff-current-diff-Ancestor '((((class color) (min-colors 88) (background light)) @@ -890,7 +880,6 @@ this variable represents.") DO NOT CHANGE this variable. Instead, use the customization widget to customize the actual face object `ediff-current-diff-Ancestor' this variable represents.") -(ediff-hide-face ediff-current-diff-face-Ancestor) (defface ediff-fine-diff-A '((((class color) (min-colors 88) (background light)) @@ -911,7 +900,6 @@ this variable represents.") DO NOT CHANGE this variable. Instead, use the customization widget to customize the actual face object `ediff-fine-diff-A' this variable represents.") -(ediff-hide-face ediff-fine-diff-face-A) (defface ediff-fine-diff-B '((((class color) (min-colors 88) (background light)) @@ -932,7 +920,6 @@ this variable represents.") DO NOT CHANGE this variable. Instead, use the customization widget to customize the actual face object `ediff-fine-diff-B' this variable represents.") -(ediff-hide-face ediff-fine-diff-face-B) (defface ediff-fine-diff-C '((((class color) (min-colors 88) (background light)) @@ -956,7 +943,6 @@ this variable represents.") DO NOT CHANGE this variable. Instead, use the customization widget to customize the actual face object `ediff-fine-diff-C' this variable represents.") -(ediff-hide-face ediff-fine-diff-face-C) (defface ediff-fine-diff-Ancestor '((((class color) (min-colors 88) (background light)) @@ -981,7 +967,6 @@ ancestor buffer." DO NOT CHANGE this variable. Instead, use the customization widget to customize the actual face object `ediff-fine-diff-Ancestor' this variable represents.") -(ediff-hide-face ediff-fine-diff-face-Ancestor) ;; Some installs don't have stipple or Stipple. So, try them in turn. (defvar stipple-pixmap @@ -1012,7 +997,6 @@ this variable represents.") DO NOT CHANGE this variable. Instead, use the customization widget to customize the actual face object `ediff-even-diff-A' this variable represents.") -(ediff-hide-face ediff-even-diff-face-A) (defface ediff-even-diff-B `((((class color) (min-colors 88)) @@ -1031,7 +1015,6 @@ this variable represents.") DO NOT CHANGE this variable. Instead, use the customization widget to customize the actual face object `ediff-even-diff-B' this variable represents.") -(ediff-hide-face ediff-even-diff-face-B) (defface ediff-even-diff-C `((((type pc)) @@ -1053,7 +1036,6 @@ this variable represents.") DO NOT CHANGE this variable. Instead, use the customization widget to customize the actual face object `ediff-even-diff-C' this variable represents.") -(ediff-hide-face ediff-even-diff-face-C) (defface ediff-even-diff-Ancestor `((((type pc)) @@ -1075,7 +1057,6 @@ this variable represents.") DO NOT CHANGE this variable. Instead, use the customization widget to customize the actual face object `ediff-even-diff-Ancestor' this variable represents.") -(ediff-hide-face ediff-even-diff-face-Ancestor) ;; Association between buffer types and even-diff-face symbols (defconst ediff-even-diff-face-alist @@ -1103,8 +1084,6 @@ this variable represents.") DO NOT CHANGE this variable. Instead, use the customization widget to customize the actual face object `ediff-odd-diff-A' this variable represents.") -(ediff-hide-face ediff-odd-diff-face-A) - (defface ediff-odd-diff-B '((((type pc)) @@ -1125,7 +1104,6 @@ this variable represents.") DO NOT CHANGE this variable. Instead, use the customization widget to customize the actual face object `ediff-odd-diff-B' this variable represents.") -(ediff-hide-face ediff-odd-diff-face-B) (defface ediff-odd-diff-C '((((type pc)) @@ -1146,7 +1124,6 @@ this variable represents.") DO NOT CHANGE this variable. Instead, use the customization widget to customize the actual face object `ediff-odd-diff-C' this variable represents.") -(ediff-hide-face ediff-odd-diff-face-C) (defface ediff-odd-diff-Ancestor '((((class color) (min-colors 88)) @@ -1165,7 +1142,6 @@ this variable represents.") DO NOT CHANGE this variable. Instead, use the customization widget to customize the actual face object `ediff-odd-diff-Ancestor' this variable represents.") -(ediff-hide-face ediff-odd-diff-face-Ancestor) ;; Association between buffer types and odd-diff-face symbols (defconst ediff-odd-diff-face-alist @@ -1571,6 +1547,8 @@ This default should work without changes." (ediff-file-attributes filename 5)) +;;; Obsolete + (defun ediff-convert-standard-filename (fname) (declare (obsolete convert-standard-filename "28.1")) (convert-standard-filename fname)) @@ -1578,5 +1556,7 @@ This default should work without changes." (define-obsolete-function-alias 'ediff-with-syntax-table #'with-syntax-table "27.1") +(define-obsolete-function-alias 'ediff-hide-face #'ignore "28.1") + (provide 'ediff-init) ;;; ediff-init.el ends here commit b01ee9a1142377b1c984998f7af8b3c7fc142859 Author: Stefan Kangas Date: Thu Feb 4 08:12:22 2021 +0100 * lisp/man.el (Man-notify-method): Remove Emacs 19.28 compat code. diff --git a/lisp/man.el b/lisp/man.el index eb383a8439..1fded38e72 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -97,8 +97,6 @@ :group 'external :group 'help) -(defvar Man-notify) - (defcustom Man-filter-list nil "Manpage cleaning filter command phrases. This variable contains a list of the following form: @@ -149,8 +147,7 @@ the manpage buffer." (ansi-color-make-color-map)) "The value used here for `ansi-color-map'.") -;; Use the value of the obsolete user option Man-notify, if set. -(defcustom Man-notify-method (if (boundp 'Man-notify) Man-notify 'friendly) +(defcustom Man-notify-method 'friendly "Selects the behavior when manpage is ready. This variable may have one of the following values, where (sf) means that the frames are switched, so the manpage is displayed in the frame commit 7febfe1c2bad173a9d89a667738be081e74e639f Author: Stefan Kangas Date: Thu Feb 4 05:02:42 2021 +0100 Use require instead of boundp+load-library in double.el * lisp/double.el (isearch): Use require instead of boundp+load-library. diff --git a/lisp/double.el b/lisp/double.el index d099fd0642..7bc8d92e60 100644 --- a/lisp/double.el +++ b/lisp/double.el @@ -95,8 +95,7 @@ but not `C-u X' or `ESC X' since the X is not the prefix key." (global-set-key [ignore] 'ignore) -(or (boundp 'isearch-mode-map) - (load-library "isearch")) +(require 'isearch) (define-key isearch-mode-map [ignore] (lambda () (interactive) (isearch-update))) commit 0d8e15757ed610bbe1833b7540006bbf7363c776 Author: Stefan Kangas Date: Thu Feb 4 04:53:02 2021 +0100 Remove some unnecessary references to Emacs 19 * lisp/emacs-lisp/elp.el: * lisp/mouse-copy.el: * lisp/mouse-drag.el: * lisp/progmodes/simula.el (simula-mode-map): * lisp/term.el (term-matching-input-from-input-string): * lisp/vcursor.el: Doc fix; don't mention Emacs 19. diff --git a/lisp/emacs-lisp/elp.el b/lisp/emacs-lisp/elp.el index f551c0c36c..cc2927caf4 100644 --- a/lisp/emacs-lisp/elp.el +++ b/lisp/emacs-lisp/elp.el @@ -110,8 +110,7 @@ ;; Boy Jim's profiler.el. Both were written for Emacs 18 and both were ;; pretty good first shots at profiling, but I found that they didn't ;; provide the functionality or interface that I wanted, so I wrote -;; this. I've tested elp in XEmacs 19 and Emacs 19. There's no point -;; in even trying to make this work with Emacs 18. +;; this. ;; Unlike previous profilers, elp uses Emacs 19's built-in function ;; current-time to return interval times. This obviates the need for diff --git a/lisp/mouse-copy.el b/lisp/mouse-copy.el index e48722ef94..8155c9dff3 100644 --- a/lisp/mouse-copy.el +++ b/lisp/mouse-copy.el @@ -55,9 +55,6 @@ ;; is similar to mouse-drag-throw, but ;; doesn't pass clicks through. ;; -;; These functions have been tested in emacs version 19.30, -;; and this package has run in the past on 19.25-19.29. -;; ;; Originally mouse-copy was part of a larger package. ;; As of 11 July 96 the scrolling functions were split out ;; in preparation for incorporation into (the future) emacs-19.32. diff --git a/lisp/mouse-drag.el b/lisp/mouse-drag.el index 907ef06159..b2960a4ccd 100644 --- a/lisp/mouse-drag.el +++ b/lisp/mouse-drag.el @@ -70,9 +70,6 @@ ;; is similar to mouse-drag-throw, but ;; doesn't pass clicks through. ;; -;; These functions have been tested in emacs version 19.30, -;; and this package has run in the past on 19.25-19.29. -;; ;; Originally mouse-drag was part of a larger package. ;; As of 11 July 96 the scrolling functions were split out ;; in preparation for incorporation into (the future) emacs-19.32. diff --git a/lisp/progmodes/simula.el b/lisp/progmodes/simula.el index 7806a6b46c..a863e7eb4b 100644 --- a/lisp/progmodes/simula.el +++ b/lisp/progmodes/simula.el @@ -281,7 +281,7 @@ for SIMULA mode to function correctly." (define-key map ":" 'simula-electric-label) (define-key map "\e\C-q" 'simula-indent-exp) (define-key map "\t" 'simula-indent-command) - ;; Emacs 19 defines menus in the mode map + (define-key map [menu-bar simula] (cons "SIMULA" (make-sparse-keymap "SIMULA"))) (define-key map [menu-bar simula indent-exp] diff --git a/lisp/term.el b/lisp/term.el index 8a560e85d5..971f270397 100644 --- a/lisp/term.el +++ b/lisp/term.el @@ -683,8 +683,7 @@ Buffer local variable.") "Index of last matched history element.") (defvar term-matching-input-from-input-string "" "Input previously used to match input history.") -; This argument to set-process-filter disables reading from the process, -; assuming this is Emacs 19.20 or newer. +; This argument to set-process-filter disables reading from the process. (defvar term-pager-filter t) (put 'term-input-ring 'permanent-local t) diff --git a/lisp/vcursor.el b/lisp/vcursor.el index e699df4842..595a25381a 100644 --- a/lisp/vcursor.el +++ b/lisp/vcursor.el @@ -38,7 +38,7 @@ ;; or t), which means that copying from the vcursor will be turned ;; off after any operation not involving the vcursor, but the ;; vcursor itself will be left alone. -;; - works on dumb terminals with Emacs 19.29 and later +;; - works on dumb terminals ;; - new keymap vcursor-map for binding to a prefix key ;; - vcursor-compare-windows substantially improved ;; - vcursor-execute-{key,command} much better about using the @@ -50,11 +50,7 @@ ;; ============ ;; ;; Virtual cursor commands. I got this idea from the old BBC micro. -;; You need Emacs 19 or 20 and a window system for the best effects. -;; For character terminals, at least Emacs 19.29 is required -;; (special behavior for the overlay property -;; "before-string" must be implemented). Search for "dumb terminals" -;; for more information. +;; You need a window system for the best effects. ;; ;; This is much easier to use than the instructions are to read. ;; First, you need to let vcursor define some keys: setting commit fd9516238a4930bc09b26cc37ae61a2bda95dca2 Author: Stefan Kangas Date: Thu Feb 4 04:30:03 2021 +0100 Remove XEmacs compat code from edebug.el * lisp/emacs-lisp/edebug.el (edebug-window-live-p, edebug-mark): Make obsolete. Update callers. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 84191af88c..5d595851b9 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -341,7 +341,7 @@ Return the result of the last expression in BODY." ;; FIXME: We should probably just be using `pop-to-buffer'. (setq window (cond - ((and (edebug-window-live-p window) + ((and (window-live-p window) (eq (window-buffer window) buffer)) window) ((eq (window-buffer) buffer) @@ -392,7 +392,7 @@ Return the result of the last expression in BODY." ;; Get either a full window configuration or some window information. (if (listp which-windows) (mapcar (lambda (window) - (if (edebug-window-live-p window) + (if (window-live-p window) (list window (window-buffer window) (window-point window) @@ -407,7 +407,7 @@ Return the result of the last expression in BODY." (mapcar (lambda (one-window-info) (if one-window-info (apply (lambda (window buffer point start hscroll) - (if (edebug-window-live-p window) + (if (window-live-p window) (progn (set-window-buffer window buffer) (set-window-point window point) @@ -2688,7 +2688,7 @@ See `edebug-behavior-alist' for implementations.") (edebug-outside-window (selected-window)) (edebug-outside-buffer (current-buffer)) (edebug-outside-point (point)) - (edebug-outside-mark (edebug-mark)) + (edebug-outside-mark (mark t)) edebug-outside-windows ; Window or screen configuration. edebug-buffer-points @@ -2857,7 +2857,7 @@ See `edebug-behavior-alist' for implementations.") ;; Unrestore edebug-buffer's window-start, if displayed. (let ((window (car edebug-window-data))) - (if (and (edebug-window-live-p window) + (if (and (window-live-p window) (eq (window-buffer) edebug-buffer)) (progn (set-window-start window (cdr edebug-window-data) @@ -2876,7 +2876,7 @@ See `edebug-behavior-alist' for implementations.") ;; Since we may be in a save-excursion, in case of quit, ;; reselect the outside window only. ;; Only needed if we are not recovering windows?? - (if (edebug-window-live-p edebug-outside-window) + (if (window-live-p edebug-outside-window) (select-window edebug-outside-window)) ) ; if edebug-save-windows @@ -4540,11 +4540,6 @@ It is removed when you hit any char." ;;; Emacs version specific code -(defalias 'edebug-window-live-p 'window-live-p) - -(defun edebug-mark () - (mark t)) - (defun edebug-set-conditional-breakpoint (arg condition) "Set a conditional breakpoint at nearest sexp. The condition is evaluated in the outside context. @@ -4660,7 +4655,15 @@ instrumentation for, defaulting to all functions." (message "Removed edebug instrumentation from %s" (mapconcat #'symbol-name functions ", "))) + +;;; Obsolete. + +(defun edebug-mark () + (declare (obsolete mark "28.1")) + (mark t)) + (define-obsolete-function-alias 'edebug-mark-marker #'mark-marker "28.1") +(define-obsolete-function-alias 'edebug-window-live-p #'window-live-p "28.1") (provide 'edebug) ;;; edebug.el ends here commit c07ebfcbe084e8219d8c2588f23f77ba4ef39087 Author: Dmitry Gutov Date: Thu Feb 4 03:38:27 2021 +0200 Bind default-directory to the project root * lisp/progmodes/project.el (project-find-regexp): Bind default-directory to the project root, to save this value in the resulting buffer (esp. if the project selector was used, (https://lists.gnu.org/archive/html/emacs-devel/2021-02/msg00140.html). (project-or-external-find-regexp): Same. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index fc5e30111e..abe563bec0 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -725,6 +725,7 @@ requires quoting, e.g. `\\[quoted-insert]'." (require 'xref) (require 'grep) (let* ((pr (project-current t)) + (default-directory (project-root pr)) (files (if (not current-prefix-arg) (project-files pr) @@ -756,6 +757,7 @@ pattern to search for." (interactive (list (project--read-regexp))) (require 'xref) (let* ((pr (project-current t)) + (default-directory (project-root pr)) (files (project-files pr (cons (project-root pr) commit b81516c7fb558c9b4bc44e6e69f6729a5f2f9894 Author: Michael Albinus Date: Wed Feb 3 18:48:09 2021 +0100 Tramp code cleanup * lisp/net/tramp.el (tramp-signal-hook-function) (tramp-handle-access-file, tramp-handle-copy-directory) (tramp-handle-directory-files, tramp-handle-file-local-copy) (tramp-handle-insert-file-contents, tramp-handle-load): * lisp/net/tramp-adb.el (tramp-adb-handle-directory-files-and-attributes) (tramp-adb-handle-make-directory) (tramp-adb-handle-file-local-copy, tramp-adb-handle-copy-file) (tramp-adb-handle-rename-file): * lisp/net/tramp-crypt.el (tramp-crypt-do-copy-or-rename-file) (tramp-crypt-handle-directory-files) (tramp-crypt-handle-make-directory): * lisp/net/tramp-gvfs.el (tramp-gvfs-dbus-event-error) (tramp-gvfs-do-copy-or-rename-file) (tramp-gvfs-handle-make-directory): * lisp/net/tramp-rclone.el (tramp-rclone-do-copy-or-rename-file) (tramp-rclone-handle-directory-files): * lisp/net/tramp-sh.el (tramp-sh-handle-make-symbolic-link) (tramp-sh-handle-directory-files-and-attributes) (tramp-sh-handle-file-name-all-completions) (tramp-sh-handle-copy-directory, tramp-do-copy-or-rename-file) (tramp-sh-handle-make-directory) (tramp-sh-handle-file-local-copy) (tramp-sh-inotifywait-process-filter): * lisp/net/tramp-smb.el (tramp-smb-handle-copy-directory) (tramp-smb-handle-copy-file, tramp-smb-handle-directory-files) (tramp-smb-handle-file-local-copy) (tramp-smb-handle-make-directory, tramp-smb-handle-rename-file): * lisp/net/tramp-sudoedit.el (tramp-sudoedit-do-copy-or-rename-file): Unify error report. * lisp/net/tramp-adb.el (tramp-adb-file-name-handler): Sync args with other `tramp-*-file-name-handler'. * lisp/net/tramp-compat.el (tramp-error): Declare. (tramp-compat-file-missing): New defsubst. * lisp/net/tramp-gvfs.el (tramp-gvfs-do-copy-or-rename-file): Handle volatile files. (tramp-gvfs-set-attribute): New defun. (tramp-gvfs-handle-set-file-modes) (tramp-gvfs-handle-set-file-times) (tramp-gvfs-handle-set-file-uid-gid): Use it. * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file): Use `msg-operation'. * lisp/net/tramp-smb.el (tramp-smb-handle-insert-directory): Remove superfluous `format: (tramp-smb-maybe-open-connection): Simplify loop. * lisp/net/tramp.el (tramp-handle-file-truename): Drop volume letter from symlinked files. * test/lisp/net/tramp-tests.el (tramp--test-gdrive-p): New defun. (tramp--test-nextcloud-p): Remove. (tramp-test40-special-characters-with-ls): Do not skip on MS Windows. (tramp-test41-utf8): Skip if needed. diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index 73dffe1d64..6ec4d1fed3 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -197,13 +197,13 @@ It is used for TCP/IP devices." tramp-adb-method))) ;;;###tramp-autoload -(defun tramp-adb-file-name-handler (operation &rest arguments) +(defun tramp-adb-file-name-handler (operation &rest args) "Invoke the ADB handler for OPERATION. First arg specifies the OPERATION, second arg is a list of -ARGUMENTS to pass to the OPERATION." +arguments to pass to the OPERATION." (if-let ((fn (assoc operation tramp-adb-file-name-handler-alist))) - (save-match-data (apply (cdr fn) arguments)) - (tramp-run-real-handler operation arguments))) + (save-match-data (apply (cdr fn) args)) + (tramp-run-real-handler operation args))) ;;;###tramp-autoload (tramp--with-startup @@ -305,9 +305,7 @@ ARGUMENTS to pass to the OPERATION." (directory &optional full match nosort id-format count) "Like `directory-files-and-attributes' for Tramp files." (unless (file-exists-p directory) - (tramp-error - (tramp-dissect-file-name directory) tramp-file-missing - "No such file or directory" directory)) + (tramp-compat-file-missing (tramp-dissect-file-name directory) directory)) (when (file-directory-p directory) (with-parsed-tramp-file-name (expand-file-name directory) nil (copy-tree @@ -435,7 +433,7 @@ Emacs dired can't find files." (setq dir (expand-file-name dir)) (with-parsed-tramp-file-name dir nil (when (and (null parents) (file-exists-p dir)) - (tramp-error v 'file-already-exists "Directory already exists %s" dir)) + (tramp-error v 'file-already-exists dir)) (when parents (let ((par (expand-file-name ".." dir))) (unless (file-directory-p par) @@ -498,9 +496,7 @@ Emacs dired can't find files." "Like `file-local-copy' for Tramp files." (with-parsed-tramp-file-name filename nil (unless (file-exists-p (file-truename filename)) - (tramp-error - v tramp-file-missing - "Cannot make local copy of non-existing file `%s'" filename)) + (tramp-compat-file-missing v filename)) (let ((tmpfile (tramp-compat-make-temp-file filename))) (with-tramp-progress-reporter v 3 (format "Fetching %s to tmp file %s" filename tmpfile) @@ -642,9 +638,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (jka-compr-inhibit t)) (with-parsed-tramp-file-name (if t1 filename newname) nil (unless (file-exists-p filename) - (tramp-error - v tramp-file-missing - "Copying file" "No such file or directory" filename)) + (tramp-compat-file-missing v filename)) (when (and (not ok-if-already-exists) (file-exists-p newname)) (tramp-error v 'file-already-exists newname)) (when (and (file-directory-p newname) @@ -726,9 +720,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (jka-compr-inhibit t)) (with-parsed-tramp-file-name (if t1 filename newname) nil (unless (file-exists-p filename) - (tramp-error - v tramp-file-missing - "Renaming file" "No such file or directory" filename)) + (tramp-compat-file-missing v filename)) (when (and (not ok-if-already-exists) (file-exists-p newname)) (tramp-error v 'file-already-exists newname)) (when (and (file-directory-p newname) diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el index 87e5378e80..27461e6917 100644 --- a/lisp/net/tramp-compat.el +++ b/lisp/net/tramp-compat.el @@ -41,6 +41,7 @@ (require 'shell) (require 'subr-x) +(declare-function tramp-error "tramp") ;; `temporary-file-directory' as function is introduced with Emacs 26.1. (declare-function tramp-handle-temporary-file-directory "tramp") (declare-function tramp-tramp-file-p "tramp") @@ -178,6 +179,12 @@ This is a string of ten letters or dashes as in ls -l." (if (get 'file-missing 'error-conditions) 'file-missing 'file-error) "The error symbol for the `file-missing' error.") +(defsubst tramp-compat-file-missing (vec file) + "Emit the `file-missing' error." + (if (get 'file-missing 'error-conditions) + (tramp-error vec tramp-file-missing file) + (tramp-error vec tramp-file-missing "No such file or directory: %s" file))) + ;; `file-local-name', `file-name-quoted-p', `file-name-quote' and ;; `file-name-unquote' are introduced in Emacs 26.1. (defalias 'tramp-compat-file-local-name diff --git a/lisp/net/tramp-crypt.el b/lisp/net/tramp-crypt.el index dfe54623db..f8de7085e2 100644 --- a/lisp/net/tramp-crypt.el +++ b/lisp/net/tramp-crypt.el @@ -249,7 +249,7 @@ arguments to pass to the OPERATION." ;;;###tramp-autoload (defun tramp-crypt-file-name-handler (operation &rest args) "Invoke the crypted remote file related OPERATION. -First arg specifies the OPERATION, second arg ARGS is a list of +First arg specifies the OPERATION, second arg is a list of arguments to pass to the OPERATION." (if-let ((filename (apply #'tramp-crypt-file-name-for-operation operation args)) @@ -568,9 +568,7 @@ absolute file names." (with-parsed-tramp-file-name (if t1 filename newname) nil (unless (file-exists-p filename) - (tramp-error - v tramp-file-missing - "%s file" msg-operation "No such file or directory" filename)) + (tramp-compat-file-missing v filename)) (when (and (not ok-if-already-exists) (file-exists-p newname)) (tramp-error v 'file-already-exists newname)) (when (and (file-directory-p newname) @@ -672,9 +670,7 @@ absolute file names." (directory &optional full match nosort count) "Like `directory-files' for Tramp files." (unless (file-exists-p directory) - (tramp-error - (tramp-dissect-file-name directory) tramp-file-missing - "No such file or directory" directory)) + (tramp-compat-file-missing (tramp-dissect-file-name directory) directory)) (when (file-directory-p directory) (setq directory (file-name-as-directory (expand-file-name directory))) (let* (tramp-crypt-enabled @@ -781,7 +777,7 @@ WILDCARD is not supported." "Like `make-directory' for Tramp files." (with-parsed-tramp-file-name (expand-file-name dir) nil (when (and (null parents) (file-exists-p dir)) - (tramp-error v 'file-already-exists "Directory already exists %s" dir)) + (tramp-error v 'file-already-exists dir)) (let (tramp-crypt-enabled) (make-directory (tramp-crypt-encrypt-file-name dir) parents)) ;; When PARENTS is non-nil, DIR could be a chain of non-existent diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index f882636a8f..e946d73e66 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -841,8 +841,8 @@ Operations not mentioned here will be handled by the default Emacs primitives.") ;;;###tramp-autoload (defun tramp-gvfs-file-name-handler (operation &rest args) "Invoke the GVFS related OPERATION and ARGS. -First arg specifies the OPERATION, second arg is a list of arguments to -pass to the OPERATION." +First arg specifies the OPERATION, second arg is a list of +arguments to pass to the OPERATION." (unless tramp-gvfs-enabled (tramp-user-error nil "Package `tramp-gvfs' not supported")) (if-let ((fn (assoc operation tramp-gvfs-file-name-handler-alist))) @@ -945,7 +945,7 @@ is no information where to trace the message.") "Called when a D-Bus error message arrives, see `dbus-event-error-functions'." (when tramp-gvfs-dbus-event-vector (tramp-message tramp-gvfs-dbus-event-vector 6 "%S" event) - (tramp-error tramp-gvfs-dbus-event-vector 'file-error "%s" (cadr err)))) + (tramp-error tramp-gvfs-dbus-event-vector 'file-error (cadr err)))) (add-hook 'dbus-event-error-functions #'tramp-gvfs-dbus-event-error) (add-hook 'tramp-gvfs-unload-hook @@ -985,83 +985,97 @@ file names." (let ((t1 (tramp-tramp-file-p filename)) (t2 (tramp-tramp-file-p newname)) (equal-remote (tramp-equal-remote filename newname)) + (volatile + (and (eq op 'rename) (tramp-gvfs-file-name-p filename) + (equal + (cdr + (assoc + "standard::is-volatile" + (tramp-gvfs-get-file-attributes filename))) + "TRUE"))) ;; "gvfs-rename" is not trustworthy. (gvfs-operation (if (eq op 'copy) "gvfs-copy" "gvfs-move")) (msg-operation (if (eq op 'copy) "Copying" "Renaming"))) (with-parsed-tramp-file-name (if t1 filename newname) nil (unless (file-exists-p filename) - (tramp-error - v tramp-file-missing - "%s file" msg-operation "No such file or directory" filename)) + (tramp-compat-file-missing v filename)) (when (and (not ok-if-already-exists) (file-exists-p newname)) (tramp-error v 'file-already-exists newname)) (when (and (file-directory-p newname) (not (directory-name-p newname))) (tramp-error v 'file-error "File is a directory %s" newname)) - (if (or (and equal-remote - (tramp-get-connection-property v "direct-copy-failed" nil)) - (and t1 (not (tramp-gvfs-file-name-p filename))) - (and t2 (not (tramp-gvfs-file-name-p newname)))) - - ;; We cannot copy or rename directly. - (let ((tmpfile (tramp-compat-make-temp-file filename))) - (if (eq op 'copy) - (copy-file - filename tmpfile t keep-date preserve-uid-gid - preserve-extended-attributes) - (rename-file filename tmpfile t)) - (rename-file tmpfile newname ok-if-already-exists)) - - ;; Direct action. - (with-tramp-progress-reporter - v 0 (format "%s %s to %s" msg-operation filename newname) - (unless - (and (apply - #'tramp-gvfs-send-command v gvfs-operation - (append - (and (eq op 'copy) (or keep-date preserve-uid-gid) - '("--preserve")) - (list - (tramp-gvfs-url-file-name filename) - (tramp-gvfs-url-file-name newname)))) - ;; Some backends do not return a proper error - ;; code in case of direct copy/move. Apply sanity checks. - (or (not equal-remote) - (tramp-gvfs-send-command - v "gvfs-info" (tramp-gvfs-url-file-name newname)) - (eq op 'copy) - (not (tramp-gvfs-send-command - v "gvfs-info" - (tramp-gvfs-url-file-name filename))))) - - (if (or (not equal-remote) - (and equal-remote - (tramp-get-connection-property - v "direct-copy-failed" nil))) - ;; Propagate the error. - (with-current-buffer (tramp-get-connection-buffer v) - (goto-char (point-min)) - (tramp-error-with-buffer - nil v 'file-error - "%s failed, see buffer `%s' for details." - msg-operation (buffer-name))) - - ;; Some WebDAV server, like the one from QNAP, do not - ;; support direct copy/move. Try a fallback. - (tramp-set-connection-property v "direct-copy-failed" t) - (tramp-gvfs-do-copy-or-rename-file - op filename newname ok-if-already-exists keep-date - preserve-uid-gid preserve-extended-attributes)))) - - (when (and t1 (eq op 'rename)) - (with-parsed-tramp-file-name filename nil - (tramp-flush-file-properties v localname))) - - (when t2 - (with-parsed-tramp-file-name newname nil - (tramp-flush-file-properties v localname)))))))) + (cond + ;; We cannot rename volatile files, as used by Google-drive. + ((and (not equal-remote) volatile) + (prog1 (copy-file + filename newname ok-if-already-exists keep-date + preserve-uid-gid preserve-extended-attributes) + (delete-file filename))) + + ;; We cannot copy or rename directly. + ((or (and equal-remote + (tramp-get-connection-property v "direct-copy-failed" nil)) + (and t1 (not (tramp-gvfs-file-name-p filename))) + (and t2 (not (tramp-gvfs-file-name-p newname)))) + (let ((tmpfile (tramp-compat-make-temp-file filename))) + (if (eq op 'copy) + (copy-file + filename tmpfile t keep-date preserve-uid-gid + preserve-extended-attributes) + (rename-file filename tmpfile t)) + (rename-file tmpfile newname ok-if-already-exists))) + + ;; Direct action. + (t (with-tramp-progress-reporter + v 0 (format "%s %s to %s" msg-operation filename newname) + (unless + (and (apply + #'tramp-gvfs-send-command v gvfs-operation + (append + (and (eq op 'copy) (or keep-date preserve-uid-gid) + '("--preserve")) + (list + (tramp-gvfs-url-file-name filename) + (tramp-gvfs-url-file-name newname)))) + ;; Some backends do not return a proper error + ;; code in case of direct copy/move. Apply + ;; sanity checks. + (or (not equal-remote) + (tramp-gvfs-send-command + v "gvfs-info" (tramp-gvfs-url-file-name newname)) + (eq op 'copy) + (not (tramp-gvfs-send-command + v "gvfs-info" + (tramp-gvfs-url-file-name filename))))) + + (if (or (not equal-remote) + (and equal-remote + (tramp-get-connection-property + v "direct-copy-failed" nil))) + ;; Propagate the error. + (with-current-buffer (tramp-get-connection-buffer v) + (goto-char (point-min)) + (tramp-error-with-buffer + nil v 'file-error + "%s failed, see buffer `%s' for details." + msg-operation (buffer-name))) + + ;; Some WebDAV server, like the one from QNAP, do + ;; not support direct copy/move. Try a fallback. + (tramp-set-connection-property v "direct-copy-failed" t) + (tramp-gvfs-do-copy-or-rename-file + op filename newname ok-if-already-exists keep-date + preserve-uid-gid preserve-extended-attributes)))) + + (when (and t1 (eq op 'rename)) + (with-parsed-tramp-file-name filename nil + (tramp-flush-file-properties v localname))) + + (when t2 + (with-parsed-tramp-file-name newname nil + (tramp-flush-file-properties v localname))))))))) (defun tramp-gvfs-handle-copy-file (filename newname &optional ok-if-already-exists keep-date @@ -1545,7 +1559,7 @@ If FILE-SYSTEM is non-nil, return file system attributes." (setq dir (directory-file-name (expand-file-name dir))) (with-parsed-tramp-file-name dir nil (when (and (null parents) (file-exists-p dir)) - (tramp-error v 'file-already-exists "Directory already exists %s" dir)) + (tramp-error v 'file-already-exists dir)) (tramp-flush-directory-properties v localname) (save-match-data (let ((ldir (file-name-directory dir))) @@ -1575,20 +1589,31 @@ If FILE-SYSTEM is non-nil, return file system attributes." (tramp-run-real-handler #'rename-file (list filename newname ok-if-already-exists)))) +(defun tramp-gvfs-set-attribute (vec &rest args) + "Call \"gio set ...\" if possible." + (let ((key (concat "gvfs-set-attribute-" (nth 3 args)))) + (when (tramp-get-connection-property vec key t) + (or (apply #'tramp-gvfs-send-command vec "gvfs-set-attribute" args) + (with-current-buffer (tramp-get-connection-buffer vec) + (goto-char (point-min)) + (when (looking-at-p "gio: Operation not supported") + (tramp-set-connection-property vec key nil))) + nil)))) + (defun tramp-gvfs-handle-set-file-modes (filename mode &optional flag) "Like `set-file-modes' for Tramp files." (with-parsed-tramp-file-name filename nil (tramp-flush-file-properties v localname) - (tramp-gvfs-send-command - v "gvfs-set-attribute" (if (eq flag 'nofollow) "-nt" "-t") "uint32" + (tramp-gvfs-set-attribute + v (if (eq flag 'nofollow) "-nt" "-t") "uint32" (tramp-gvfs-url-file-name filename) "unix::mode" (number-to-string mode)))) (defun tramp-gvfs-handle-set-file-times (filename &optional time flag) "Like `set-file-times' for Tramp files." (with-parsed-tramp-file-name filename nil (tramp-flush-file-properties v localname) - (tramp-gvfs-send-command - v "gvfs-set-attribute" (if (eq flag 'nofollow) "-nt" "-t") "uint64" + (tramp-gvfs-set-attribute + v (if (eq flag 'nofollow) "-nt" "-t") "uint64" (tramp-gvfs-url-file-name filename) "time::modified" (format-time-string "%s" (if (or (null time) @@ -1622,12 +1647,12 @@ ID-FORMAT valid values are `string' and `integer'." (with-parsed-tramp-file-name filename nil (tramp-flush-file-properties v localname) (when (natnump uid) - (tramp-gvfs-send-command - v "gvfs-set-attribute" "-t" "uint32" + (tramp-gvfs-set-attribute + v "-t" "uint32" (tramp-gvfs-url-file-name filename) "unix::uid" (number-to-string uid))) (when (natnump gid) - (tramp-gvfs-send-command - v "gvfs-set-attribute" "-t" "uint32" + (tramp-gvfs-set-attribute + v "-t" "uint32" (tramp-gvfs-url-file-name filename) "unix::gid" (number-to-string gid))))) diff --git a/lisp/net/tramp-rclone.el b/lisp/net/tramp-rclone.el index 8638bb477f..96f7d9a89b 100644 --- a/lisp/net/tramp-rclone.el +++ b/lisp/net/tramp-rclone.el @@ -157,8 +157,8 @@ Operations not mentioned here will be handled by the default Emacs primitives.") ;;;###tramp-autoload (defun tramp-rclone-file-name-handler (operation &rest args) "Invoke the rclone handler for OPERATION and ARGS. -First arg specifies the OPERATION, second arg is a list of arguments to -pass to the OPERATION." +First arg specifies the OPERATION, second arg is a list of +arguments to pass to the OPERATION." (if-let ((fn (assoc operation tramp-rclone-file-name-handler-alist))) (save-match-data (apply (cdr fn) args)) (tramp-run-real-handler operation args))) @@ -215,9 +215,7 @@ file names." (with-parsed-tramp-file-name (if t1 filename newname) nil (unless (file-exists-p filename) - (tramp-error - v tramp-file-missing - "%s file" msg-operation "No such file or directory" filename)) + (tramp-compat-file-missing v filename)) (when (and (not ok-if-already-exists) (file-exists-p newname)) (tramp-error v 'file-already-exists newname)) (when (and (file-directory-p newname) @@ -304,9 +302,7 @@ file names." (directory &optional full match nosort count) "Like `directory-files' for Tramp files." (unless (file-exists-p directory) - (tramp-error - (tramp-dissect-file-name directory) tramp-file-missing - "No such file or directory" directory)) + (tramp-compat-file-missing (tramp-dissect-file-name directory) directory)) (when (file-directory-p directory) (setq directory (file-name-as-directory (expand-file-name directory))) (with-parsed-tramp-file-name directory nil diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 2274efdf8b..bcdc014dab 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -1094,7 +1094,8 @@ component is used as the target of the symlink." (unless ln (tramp-error v 'file-error - "Making a symbolic link. ln(1) does not exist on the remote host.")) + (concat "Making a symbolic link. " + "ln(1) does not exist on the remote host."))) ;; Do the 'confirm if exists' thing. (when (file-exists-p linkname) @@ -1724,9 +1725,8 @@ ID-FORMAT valid values are `string' and `integer'." "Like `directory-files-and-attributes' for Tramp files." (unless id-format (setq id-format 'integer)) (unless (file-exists-p directory) - (tramp-error - (tramp-dissect-file-name directory) tramp-file-missing - "No such file or directory" directory)) + (tramp-compat-file-missing + (tramp-dissect-file-name directory) directory)) (when (file-directory-p directory) (setq directory (expand-file-name directory)) (let* ((temp @@ -1877,8 +1877,9 @@ ID-FORMAT valid values are `string' and `integer'." ;; side. (unless (looking-at-p "^ok$") (tramp-error - v 'file-error "\ -tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'" + v 'file-error + (concat "tramp-sh-handle-file-name-all-completions: " + "internal error accessing `%s': `%s'") (tramp-shell-quote-argument localname) (buffer-string)))) (while (zerop (forward-line -1)) @@ -1944,9 +1945,7 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'" (t2 (tramp-tramp-file-p newname))) (with-parsed-tramp-file-name (if t1 dirname newname) nil (unless (file-exists-p dirname) - (tramp-error - v tramp-file-missing - "Copying directory" "No such file or directory" dirname)) + (tramp-compat-file-missing v dirname)) (if (and (not copy-contents) (tramp-get-method-parameter v 'tramp-copy-recursive) ;; When DIRNAME and NEWNAME are remote, they must have @@ -2032,12 +2031,12 @@ file names." (length (tramp-compat-file-attribute-size (file-attributes (file-truename filename)))) (attributes (and preserve-extended-attributes - (apply #'file-extended-attributes (list filename))))) + (apply #'file-extended-attributes (list filename)))) + (msg-operation (if (eq op 'copy) "Copying" "Renaming"))) (with-parsed-tramp-file-name (if t1 filename newname) nil (unless (file-exists-p filename) - (tramp-error - v tramp-file-missing "No such file or directory" filename)) + (tramp-compat-file-missing v filename)) (when (and (not ok-if-already-exists) (file-exists-p newname)) (tramp-error v 'file-already-exists newname)) (when (and (file-directory-p newname) @@ -2045,9 +2044,7 @@ file names." (tramp-error v 'file-error "File is a directory %s" newname)) (with-tramp-progress-reporter - v 0 (format "%s %s to %s" - (if (eq op 'copy) "Copying" "Renaming") - filename newname) + v 0 (format "%s %s to %s" msg-operation filename newname) (cond ;; Both are Tramp files. @@ -2536,7 +2533,7 @@ The method used must be an out-of-band method." (setq dir (expand-file-name dir)) (with-parsed-tramp-file-name dir nil (when (and (null parents) (file-exists-p dir)) - (tramp-error v 'file-already-exists "Directory already exists %s" dir)) + (tramp-error v 'file-already-exists dir)) ;; When PARENTS is non-nil, DIR could be a chain of non-existent ;; directories a/b/c/... Instead of checking, we simply flush the ;; whole cache. @@ -3278,9 +3275,7 @@ alternative implementation will be used." "Like `file-local-copy' for Tramp files." (with-parsed-tramp-file-name filename nil (unless (file-exists-p (file-truename filename)) - (tramp-error - v tramp-file-missing - "Cannot make local copy of non-existing file `%s'" filename)) + (tramp-compat-file-missing v filename)) (let* ((size (tramp-compat-file-attribute-size (file-attributes (file-truename filename)))) @@ -3969,7 +3964,7 @@ Fall back to normal file name handler if no Tramp handler exists." "[[:blank:]]+\\([^[:blank:]]+\\)" "\\([[:blank:]]+\\([^\n\r]+\\)\\)?") line) - (tramp-error proc 'file-notify-error "%s" line)) + (tramp-error proc 'file-notify-error line)) (let ((object (list diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index c5a74a5c65..26ec910ecc 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -342,8 +342,8 @@ This can be used to disable echo etc." ;;;###tramp-autoload (defun tramp-smb-file-name-handler (operation &rest args) "Invoke the SMB related OPERATION and ARGS. -First arg specifies the OPERATION, second arg is a list of arguments to -pass to the OPERATION." +First arg specifies the OPERATION, second arg is a list of +arguments to pass to the OPERATION." (if-let ((fn (assoc operation tramp-smb-file-name-handler-alist))) (save-match-data (apply (cdr fn) args)) (tramp-run-real-handler operation args))) @@ -430,9 +430,7 @@ pass to the OPERATION." (with-tramp-progress-reporter v 0 (format "Copying %s to %s" dirname newname) (unless (file-exists-p dirname) - (tramp-error - v tramp-file-missing - "Copying directory" "No such file or directory" dirname)) + (tramp-compat-file-missing v dirname)) (when (and (file-directory-p newname) (not (directory-name-p newname))) (tramp-error v 'file-already-exists newname)) @@ -588,11 +586,10 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (copy-directory filename newname keep-date 'parents 'copy-contents) (unless (file-exists-p filename) - (tramp-error + (tramp-compat-file-missing (tramp-dissect-file-name (if (tramp-tramp-file-p filename) filename newname)) - tramp-file-missing - "Copying file" "No such file or directory" filename)) + filename)) (if-let ((tmpfile (file-local-copy filename))) ;; Remote filename. @@ -693,9 +690,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (directory &optional full match nosort count) "Like `directory-files' for Tramp files." (unless (file-exists-p directory) - (tramp-error - (tramp-dissect-file-name directory) tramp-file-missing - "No such file or directory" directory)) + (tramp-compat-file-missing (tramp-dissect-file-name directory) directory)) (let ((result (mapcar #'directory-file-name (file-name-all-completions "" directory)))) ;; Discriminate with regexp. @@ -962,9 +957,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." "Like `file-local-copy' for Tramp files." (with-parsed-tramp-file-name (file-truename filename) nil (unless (file-exists-p (file-truename filename)) - (tramp-error - v tramp-file-missing - "Cannot make local copy of non-existing file `%s'" filename)) + (tramp-compat-file-missing v filename)) (let ((tmpfile (tramp-compat-make-temp-file filename))) (with-tramp-progress-reporter v 3 (format "Fetching %s to tmp file %s" filename tmpfile) @@ -1153,12 +1146,10 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." ;; of `default-directory'. (let ((start (point))) (insert - (format - "%s" - (file-relative-name - (expand-file-name - (nth 0 x) (file-name-directory filename)) - (when full-directory-p (file-name-directory filename))))) + (file-relative-name + (expand-file-name + (nth 0 x) (file-name-directory filename)) + (when full-directory-p (file-name-directory filename)))) (put-text-property start (point) 'dired-filename t)) ;; Insert symlink. @@ -1177,7 +1168,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (setq dir (expand-file-name dir default-directory))) (with-parsed-tramp-file-name dir nil (when (and (null parents) (file-exists-p dir)) - (tramp-error v 'file-already-exists "Directory already exists %s" dir)) + (tramp-error v 'file-already-exists dir)) (let* ((ldir (file-name-directory dir))) ;; Make missing directory parts. (when (and parents @@ -1386,9 +1377,7 @@ component is used as the target of the symlink." (with-parsed-tramp-file-name (if (tramp-tramp-file-p filename) filename newname) nil (unless (file-exists-p filename) - (tramp-error - v tramp-file-missing - "Renaming file" "No such file or directory" filename)) + (tramp-compat-file-missing v filename)) (when (and (not ok-if-already-exists) (file-exists-p newname)) (tramp-error v 'file-already-exists newname)) (when (and (file-directory-p newname) @@ -2010,10 +1999,8 @@ If ARGUMENT is non-nil, use it as argument for (when port (setq args (append args (list "-p" port)))) (when tramp-smb-conf (setq args (append args (list "-s" tramp-smb-conf)))) - (while options - (setq args - (append args `("--option" ,(format "%s" (car options)))) - options (cdr options))) + (dolist (option options) + (setq args (append args (list "--option" option)))) (when argument (setq args (append args (list argument)))) diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el index 5bb1546d08..0a60b79182 100644 --- a/lisp/net/tramp-sudoedit.el +++ b/lisp/net/tramp-sudoedit.el @@ -153,8 +153,8 @@ See `tramp-actions-before-shell' for more info.") ;;;###tramp-autoload (defun tramp-sudoedit-file-name-handler (operation &rest args) "Invoke the SUDOEDIT handler for OPERATION and ARGS. -First arg specifies the OPERATION, second arg is a list of arguments to -pass to the OPERATION." +First arg specifies the OPERATION, second arg is a list of +arguments to pass to the OPERATION." (if-let ((fn (assoc operation tramp-sudoedit-file-name-handler-alist))) (save-match-data (apply (cdr fn) args)) (tramp-run-real-handler operation args))) @@ -243,9 +243,7 @@ absolute file names." (with-parsed-tramp-file-name (if t1 filename newname) nil (unless (file-exists-p filename) - (tramp-error - v tramp-file-missing - "%s file" msg-operation "No such file or directory" filename)) + (tramp-compat-file-missing v filename)) (when (and (not ok-if-already-exists) (file-exists-p newname)) (tramp-error v 'file-already-exists newname)) (when (and (file-directory-p newname) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 7b34a74882..690dd99ae5 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -2001,7 +2001,7 @@ the resulting error message." (unless (eq error-symbol 'void-variable) (tramp-error (car tramp-current-connection) error-symbol - "%s" (mapconcat (lambda (x) (format "%s" x)) data " ")))) + (mapconcat (lambda (x) (format "%s" x)) data " ")))) (put #'tramp-signal-hook-function 'tramp-suppress-trace t) @@ -3058,9 +3058,9 @@ User is always nil." (defun tramp-handle-access-file (filename string) "Like `access-file' for Tramp files." (unless (file-readable-p (file-truename filename)) - (tramp-error - (tramp-dissect-file-name filename) tramp-file-missing - "%s: No such file or directory %s" string filename))) + (tramp-compat-file-missing + (tramp-dissect-file-name filename) + (format "%s: %s" string filename)))) (defun tramp-handle-add-name-to-file (filename newname &optional ok-if-already-exists) @@ -3094,9 +3094,7 @@ User is always nil." ;; `copy-directory' creates NEWNAME before running this check. So ;; we do it ourselves. (unless (file-exists-p directory) - (tramp-error - (tramp-dissect-file-name directory) tramp-file-missing - "No such file or directory" directory)) + (tramp-compat-file-missing (tramp-dissect-file-name directory) directory)) ;; We must do it file-wise. (tramp-run-real-handler 'copy-directory @@ -3117,9 +3115,7 @@ User is always nil." (defun tramp-handle-directory-files (directory &optional full match nosort count) "Like `directory-files' for Tramp files." (unless (file-exists-p directory) - (tramp-error - (tramp-dissect-file-name directory) tramp-file-missing - "No such file or directory" directory)) + (tramp-compat-file-missing (tramp-dissect-file-name directory) directory)) (when (file-directory-p directory) (setq directory (file-name-as-directory (expand-file-name directory))) (let ((temp (nreverse (file-name-all-completions "" directory))) @@ -3216,9 +3212,7 @@ User is always nil." "Like `file-local-copy' for Tramp files." (with-parsed-tramp-file-name filename nil (unless (file-exists-p filename) - (tramp-error - v tramp-file-missing - "Cannot make local copy of non-existing file `%s'" filename)) + (tramp-compat-file-missing v filename)) (let ((tmpfile (tramp-compat-make-temp-file filename))) (copy-file filename tmpfile 'ok-if-already-exists 'keep-time) tmpfile))) @@ -3428,8 +3422,10 @@ User is always nil." (if (stringp symlink-target) (if (file-remote-p symlink-target) (tramp-compat-file-name-quote symlink-target 'top) - (expand-file-name - symlink-target (file-name-directory v2-localname))) + (tramp-drop-volume-letter + (expand-file-name + symlink-target + (file-name-directory v2-localname)))) v2-localname) 'nohop))) (when (>= numchase numchase-limit) @@ -3511,9 +3507,7 @@ User is always nil." (with-parsed-tramp-file-name filename nil (unwind-protect (if (not (file-exists-p filename)) - (tramp-error - v tramp-file-missing - "File `%s' not found on remote host" filename) + (tramp-compat-file-missing v filename) (with-tramp-progress-reporter v 3 (format-message "Inserting `%s'" filename) @@ -3636,8 +3630,7 @@ User is always nil." v 'file-error "File `%s' does not include a `.el' or `.elc' suffix" file))) (unless (or noerror (file-exists-p file)) - (tramp-error - v tramp-file-missing "Cannot load nonexistent file `%s'" file)) + (tramp-compat-file-missing v file)) (if (not (file-exists-p file)) nil (let ((signal-hook-function (unless noerror signal-hook-function)) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 19a40fdf06..f4883923f6 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -5739,6 +5739,11 @@ This does not support globbing characters in file names (yet)." (string-match-p "ftp$" (file-remote-p tramp-test-temporary-file-directory 'method))) +(defun tramp--test-gdrive-p () + "Check, whether the gdrive method is used." + (string-equal + "gdrive" (file-remote-p tramp-test-temporary-file-directory 'method))) + (defun tramp--test-gvfs-p (&optional method) "Check, whether the remote host runs a GVFS based method. This requires restrictions of file name syntax. @@ -5769,11 +5774,6 @@ This does not support external Emacs calls." (string-equal "mock" (file-remote-p tramp-test-temporary-file-directory 'method))) -(defun tramp--test-nextcloud-p () - "Check, whether the nextcloud method is used." - (string-equal - "nextcloud" (file-remote-p tramp-test-temporary-file-directory 'method))) - (defun tramp--test-rclone-p () "Check, whether the remote host is offered by rclone. This requires restrictions of file name syntax." @@ -6144,7 +6144,6 @@ Use the `ls' command." (skip-unless (tramp--test-enabled)) (skip-unless (tramp--test-sh-p)) (skip-unless (not (tramp--test-rsync-p))) - (skip-unless (not (tramp--test-windows-nt-and-batch-p))) (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) @@ -6214,6 +6213,7 @@ Use the `ls' command." (skip-unless (not (tramp--test-windows-nt-and-batch-p))) (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) (skip-unless (not (tramp--test-ksh-p))) + (skip-unless (not (tramp--test-gdrive-p))) (skip-unless (not (tramp--test-crypt-p))) (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) @@ -6747,8 +6747,6 @@ If INTERACTIVE is non-nil, the tests are run interactively." ;; * Work on skipped tests. Make a comment, when it is impossible. ;; * Revisit expensive tests, once problems in `tramp-error' are solved. ;; * Fix `tramp-test06-directory-file-name' for `ftp'. -;; * Investigate, why `tramp-test11-copy-file' and `tramp-test12-rename-file' -;; do not work properly for `nextcloud'. ;; * Implement `tramp-test31-interrupt-process' for `adb' and for ;; direct async processes. ;; * Fix `tramp-test44-threads'. commit bd5b4b35bc85b19f152e89e3945071ffc48c454d Merge: 1ef8d5e0da 7355209f53 Author: Glenn Morris Date: Wed Feb 3 08:11:08 2021 -0800 Merge from origin/emacs-27 7355209f53 (origin/emacs-27) * lisp/window.el (recenter-top-bottom): ... dc78f8a4ea (emacs-27) url-http.el: Special-case NTLM authentication 85b0137858 * lisp/isearch.el (isearch-lazy-highlight): Fix defcustom ... cbeda21083 Sync latest SKK-JISYO.L commit 1ef8d5e0da1060f38bbcc9d840a4bb256a18ed99 Merge: 7e86357b42 0bc4b003d7 Author: Glenn Morris Date: Wed Feb 3 08:11:08 2021 -0800 ; Merge from origin/emacs-27 The following commit was skipped: 0bc4b003d7 ; emacs-26 → emacs-27 commit 7e86357b423b8b0e197203f874e390e6c7cad6ee Merge: 0d1e96ac95 9c75434173 Author: Glenn Morris Date: Wed Feb 3 08:11:08 2021 -0800 Merge from origin/emacs-27 9c75434173 Fix build failure on macOS 10.7 (bug#46036) ca44ea18ef Improve documentation of auto-resize-tool/tab-bars commit 0d1e96ac951dddb36defd788f1a4c5e7bd4d82a3 Merge: 17f2be08f8 9e45c29224 Author: Glenn Morris Date: Wed Feb 3 08:11:08 2021 -0800 ; Merge from origin/emacs-27 The following commit was skipped: 9e45c29224 (xref-revert-buffer): Also 'erase-buffer' when handling a ... commit 17f2be08f8fe2375cfa56d17d3a5482b3f6d6d58 Merge: b099f1d774 74a71c41e0 Author: Glenn Morris Date: Wed Feb 3 08:11:08 2021 -0800 Merge from origin/emacs-27 74a71c41e0 (tag: emacs-27.1.91) Update files for 27.1.91 pretest # Conflicts: # ChangeLog.3 # etc/AUTHORS # lisp/ldefs-boot.el commit b099f1d774a37c09cf4b990e2acd68cbcb070269 Merge: ca55e4d898 86a2207d92 Author: Glenn Morris Date: Wed Feb 3 08:11:04 2021 -0800 ; Merge from origin/emacs-27 The following commit was skipped: 86a2207d92 Bump Emacs version to 27.1.91 commit ca55e4d89831cf25137e7d9df4110df16aab1800 Author: Lars Ingebrigtsen Date: Wed Feb 3 14:36:17 2021 +0100 Make backslash characters no longer escape in `f90-mode' * lisp/progmodes/f90.el (f90-backslash-not-special): Make obsolete (bug#32766). (f90-mode-syntax-table): Make the backslash be a normal (non-escape) character, which is the default since about 2007 (and F2K): https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34203 diff --git a/etc/NEWS b/etc/NEWS index a376df62e3..7cdb9d9430 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2010,6 +2010,13 @@ first). * Incompatible Editing Changes in Emacs 28.1 +** In 'f90-mode', the backslash character ('\') no longer escapes. +For about a decade, the backslash character has no longer had a +special escape syntax in Fortran F90. To get the old behaviour back, +say something like: + + (modify-syntax-entry ?\\ "\\" f90-mode-syntax-table) + ** In 'nroff-mode', 'center-line' is now bound to 'M-o M-s'. The original key binding was 'M-s', which interfered with I-search, since the latter uses 'M-s' as a prefix key of the search prefix map. diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el index 92b165bc64..90678c8cb1 100644 --- a/lisp/progmodes/f90.el +++ b/lisp/progmodes/f90.el @@ -718,10 +718,7 @@ Can be overridden by the value of `font-lock-maximum-decoration'.") (modify-syntax-entry ?* "." table) (modify-syntax-entry ?/ "." table) (modify-syntax-entry ?% "." table) ; bug#8820 - ;; I think that the f95 standard leaves the behavior of \ - ;; unspecified, but that f2k will require it to be non-special. - ;; Use `f90-backslash-not-special' to change. - (modify-syntax-entry ?\\ "\\" table) ; escape chars + (modify-syntax-entry ?\\ "." table) table) "Syntax table used in F90 mode.") @@ -2395,9 +2392,11 @@ CHANGE-WORD should be one of `upcase-word', `downcase-word', `capitalize-word'." (defun f90-backslash-not-special (&optional all) "Make the backslash character (\\) be non-special in the current buffer. +This is the default in `f90-mode'. + With optional argument ALL, change the default for all present -and future F90 buffers. F90 mode normally treats backslash as an -escape character." +and future F90 buffers." + (declare (obsolete nil "28.1")) (or (derived-mode-p 'f90-mode) (user-error "This function should only be used in F90 buffers")) (when (equal (char-syntax ?\\ ) ?\\ ) commit 20e48b6fd6cade60e468140a66127d326abfb8ff Author: Wilson Snyder Date: Tue Feb 2 23:22:44 2021 -0500 Update lisp/progmodes/verilog-mode.el * lisp/progmodes/verilog-mode.el: Cleanup compile-time warning suppression. Use underscore for unused arguments and other style cleanups. Use '# for function references. By Stefan Monnier. (verilog-auto-reset, verilog-sig-tieoff): Fix AUTORESET '0 (#1714). Reported by Paul Adams. (verilog-simplify-range-expression): Fix AUTOWIRE simplifying X/Y where there is a remainder (#1712). Reported by Joachim Lechner. (verilog-read-sub-decls-expr): Fix multiplication in multidimensional AUTOINST output (#1698). Reported by alanamckee. (verilog-at-constraint-p, verilog-at-streaming-op-p, verilog-streaming-op-re): Add streaming operator support (#1692) (#1516), (verilog-auto-assign-modport, verilog-auto-inout-modport): Support adding prefix to AUTOASSIGNMODPORT and AUTOINOUTMODPORT (#1690). (verilog-signals-matching-dir-re): Fix error when matching regexp with 2D packed memory. Reported by Chris DeMarco. (verilog-declaration-core-re): Allow parameter declaration statements to align like any other declaration (#1683). Suggested by Vinam Arora. (verilog-auto-inout, verilog-auto-inout-in) (verilog-auto-inout-module, verilog-auto-input, verilog-auto-inst) (verilog-auto-inst-param, verilog-auto-output-every) (verilog-signals-matching-regexp) (verilog-signals-not-matching-regexp): When "?!" is at the front of a signal-matching regexp, invert it. (verilog-declaration-varname-matcher) (verilog-highlight-max-lookahead, verilog-mode) (verilog-single-declaration-end) (verilog-font-lock-keywords-1): Improve syntax highlighting in declaration statements, and support multi-line declarations, #1681. Reported by Vinam Arora. diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el index 8dddcf0eef..e5c2c80753 100644 --- a/lisp/progmodes/verilog-mode.el +++ b/lisp/progmodes/verilog-mode.el @@ -9,7 +9,7 @@ ;; Keywords: languages ;; The "Version" is the date followed by the decimal rendition of the Git ;; commit hex. -;; Version: 2020.06.27.014326051 +;; Version: 2021.02.02.263931197 ;; Yoni Rabkin contacted the maintainer of this ;; file on 19/3/2008, and the maintainer agreed that when a bug is @@ -124,7 +124,7 @@ ;; ;; This variable will always hold the version number of the mode -(defconst verilog-mode-version "2020-06-27-0da9923-vpo-GNU" +(defconst verilog-mode-version "2021-02-02-fbb453d-vpo-GNU" "Version of this Verilog mode.") (defconst verilog-mode-release-emacs t "If non-nil, this version of Verilog mode was released with Emacs itself.") @@ -134,6 +134,16 @@ (interactive) (message "Using verilog-mode version %s" verilog-mode-version)) +(defmacro verilog--supressed-warnings (warnings &rest body) + (declare (indent 1) (debug t)) + (cond + ((fboundp 'with-suppressed-warnings) + `(with-suppressed-warnings ,warnings ,@body)) + ((fboundp 'with-no-warnings) + `(with-no-warnings ,@body)) + (t + `(progn ,@body)))) + ;; Insure we have certain packages, and deal with it if we don't ;; Be sure to note which Emacs flavor and version added each feature. (eval-when-compile @@ -220,7 +230,7 @@ STRING should be given if the last search was by `string-match' on STRING." ) (if (fboundp 'defface) nil ; great! - (defmacro defface (var values doc &rest _args) + (defmacro defface (var _values _doc &rest _args) `(make-face ,var)) ) @@ -339,7 +349,7 @@ wherever possible, since it is slow." ((fboundp 'quit-window) (defalias 'verilog-quit-window 'quit-window)) (t - (defun verilog-quit-window (kill-ignored window) + (defun verilog-quit-window (_kill-ignored window) "Quit WINDOW and bury its buffer. KILL-IGNORED is ignored." (delete-window window))))) @@ -407,7 +417,7 @@ wherever possible, since it is slow." "Filter `define-abbrev-table' TABLENAME DEFINITIONS Provides DOCSTRING PROPS in newer Emacs (23.1)." (condition-case nil - (apply 'define-abbrev-table tablename definitions docstring props) + (apply #'define-abbrev-table tablename definitions docstring props) (error (define-abbrev-table tablename definitions)))) @@ -572,7 +582,7 @@ entry \"Fontify Buffer\"). XEmacs: turn off and on font locking." :type 'boolean :group 'verilog-mode-indent) ;; Note we don't use :safe, as that would break on Emacsen before 22.0. -(put 'verilog-highlight-translate-off 'safe-local-variable 'verilog-booleanp) +(put 'verilog-highlight-translate-off 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-lineup 'declarations "Type of statements to lineup across multiple lines. @@ -611,7 +621,7 @@ are lineup only when \\[verilog-pretty-declarations] is typed." "Indentation of Verilog statements with respect to containing block." :group 'verilog-mode-indent :type 'integer) -(put 'verilog-indent-level 'safe-local-variable 'integerp) +(put 'verilog-indent-level 'safe-local-variable #'integerp) (defcustom verilog-indent-level-module 3 "Indentation of Module level Verilog statements (eg always, initial). @@ -619,14 +629,14 @@ Set to 0 to get initial and always statements lined up on the left side of your screen." :group 'verilog-mode-indent :type 'integer) -(put 'verilog-indent-level-module 'safe-local-variable 'integerp) +(put 'verilog-indent-level-module 'safe-local-variable #'integerp) (defcustom verilog-indent-level-declaration 3 "Indentation of declarations with respect to containing block. Set to 0 to get them list right under containing block." :group 'verilog-mode-indent :type 'integer) -(put 'verilog-indent-level-declaration 'safe-local-variable 'integerp) +(put 'verilog-indent-level-declaration 'safe-local-variable #'integerp) (defcustom verilog-indent-declaration-macros nil "How to treat macro expansions in a declaration. @@ -640,7 +650,7 @@ If non-nil, treat as: output c;" :group 'verilog-mode-indent :type 'boolean) -(put 'verilog-indent-declaration-macros 'safe-local-variable 'verilog-booleanp) +(put 'verilog-indent-declaration-macros 'safe-local-variable #'verilog-booleanp) (defcustom verilog-indent-lists t "How to treat indenting items in a list. @@ -653,72 +663,72 @@ If nil, treat as: reset ) begin" :group 'verilog-mode-indent :type 'boolean) -(put 'verilog-indent-lists 'safe-local-variable 'verilog-booleanp) +(put 'verilog-indent-lists 'safe-local-variable #'verilog-booleanp) (defcustom verilog-indent-level-behavioral 3 "Absolute indentation of first begin in a task or function block. Set to 0 to get such code to start at the left side of the screen." :group 'verilog-mode-indent :type 'integer) -(put 'verilog-indent-level-behavioral 'safe-local-variable 'integerp) +(put 'verilog-indent-level-behavioral 'safe-local-variable #'integerp) (defcustom verilog-indent-level-directive 1 "Indentation to add to each level of \\=`ifdef declarations. Set to 0 to have all directives start at the left side of the screen." :group 'verilog-mode-indent :type 'integer) -(put 'verilog-indent-level-directive 'safe-local-variable 'integerp) +(put 'verilog-indent-level-directive 'safe-local-variable #'integerp) (defcustom verilog-cexp-indent 2 "Indentation of Verilog statements split across lines." :group 'verilog-mode-indent :type 'integer) -(put 'verilog-cexp-indent 'safe-local-variable 'integerp) +(put 'verilog-cexp-indent 'safe-local-variable #'integerp) (defcustom verilog-case-indent 2 "Indentation for case statements." :group 'verilog-mode-indent :type 'integer) -(put 'verilog-case-indent 'safe-local-variable 'integerp) +(put 'verilog-case-indent 'safe-local-variable #'integerp) (defcustom verilog-auto-newline t "Non-nil means automatically newline after semicolons." :group 'verilog-mode-indent :type 'boolean) -(put 'verilog-auto-newline 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-newline 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-indent-on-newline t "Non-nil means automatically indent line after newline." :group 'verilog-mode-indent :type 'boolean) -(put 'verilog-auto-indent-on-newline 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-indent-on-newline 'safe-local-variable #'verilog-booleanp) (defcustom verilog-tab-always-indent t "Non-nil means TAB should always re-indent the current line. A nil value means TAB will only reindent when at the beginning of the line." :group 'verilog-mode-indent :type 'boolean) -(put 'verilog-tab-always-indent 'safe-local-variable 'verilog-booleanp) +(put 'verilog-tab-always-indent 'safe-local-variable #'verilog-booleanp) (defcustom verilog-tab-to-comment nil "Non-nil means TAB moves to the right hand column in preparation for a comment." :group 'verilog-mode-actions :type 'boolean) -(put 'verilog-tab-to-comment 'safe-local-variable 'verilog-booleanp) +(put 'verilog-tab-to-comment 'safe-local-variable #'verilog-booleanp) (defcustom verilog-indent-begin-after-if t "Non-nil means indent begin statements following if, else, while, etc. Otherwise, line them up." :group 'verilog-mode-indent :type 'boolean) -(put 'verilog-indent-begin-after-if 'safe-local-variable 'verilog-booleanp) +(put 'verilog-indent-begin-after-if 'safe-local-variable #'verilog-booleanp) (defcustom verilog-align-ifelse nil "Non-nil means align `else' under matching `if'. Otherwise else is lined up with first character on line holding matching if." :group 'verilog-mode-indent :type 'boolean) -(put 'verilog-align-ifelse 'safe-local-variable 'verilog-booleanp) +(put 'verilog-align-ifelse 'safe-local-variable #'verilog-booleanp) (defcustom verilog-minimum-comment-distance 10 "Minimum distance (in lines) between begin and end required before a comment. @@ -726,7 +736,7 @@ Setting this variable to zero results in every end acquiring a comment; the default avoids too many redundant comments in tight quarters." :group 'verilog-mode-indent :type 'integer) -(put 'verilog-minimum-comment-distance 'safe-local-variable 'integerp) +(put 'verilog-minimum-comment-distance 'safe-local-variable #'integerp) (defcustom verilog-highlight-p1800-keywords nil "Obsolete. @@ -734,7 +744,7 @@ Was non-nil means highlight SystemVerilog IEEE-1800 differently. All code is now highlighted as if SystemVerilog IEEE-1800." :group 'verilog-mode-indent :type 'boolean) -(put 'verilog-highlight-p1800-keywords 'safe-local-variable 'verilog-booleanp) +(put 'verilog-highlight-p1800-keywords 'safe-local-variable #'verilog-booleanp) (make-obsolete-variable 'verilog-highlight-p1800-keywords nil "27.1") (defcustom verilog-highlight-grouping-keywords nil @@ -745,7 +755,7 @@ Some find that special highlighting on these grouping constructs allow the structure of the code to be understood at a glance." :group 'verilog-mode-indent :type 'boolean) -(put 'verilog-highlight-grouping-keywords 'safe-local-variable 'verilog-booleanp) +(put 'verilog-highlight-grouping-keywords 'safe-local-variable #'verilog-booleanp) (defcustom verilog-highlight-modules nil "Non-nil means highlight module statements for `verilog-load-file-at-point'. @@ -754,7 +764,7 @@ module definition. If false, this is not supported. Setting this is experimental, and may lead to bad performance." :group 'verilog-mode-indent :type 'boolean) -(put 'verilog-highlight-modules 'safe-local-variable 'verilog-booleanp) +(put 'verilog-highlight-modules 'safe-local-variable #'verilog-booleanp) (defcustom verilog-highlight-includes t "Non-nil means highlight module statements for `verilog-load-file-at-point'. @@ -762,7 +772,17 @@ When true, mousing over include file names will allow jumping to the file referenced. If false, this is not supported." :group 'verilog-mode-indent :type 'boolean) -(put 'verilog-highlight-includes 'safe-local-variable 'verilog-booleanp) +(put 'verilog-highlight-includes 'safe-local-variable #'verilog-booleanp) + +(defcustom verilog-highlight-max-lookahead 10000 + "Maximum size of declaration statement that undergoes highlighting. +Highlighting is performed only on the first `verilog-highlight-max-lookahead' +characters in a declaration statement. +Setting this variable to zero would remove this limit. Note that removing +the limit can greatly slow down highlighting for very large files." + :group 'verilog-mode-indent + :type 'integer) +(put 'verilog-highlight-max-lookahead 'safe-local-variable #'integerp) (defcustom verilog-auto-declare-nettype nil "Non-nil specifies the data type to use with `verilog-auto-input' etc. @@ -772,14 +792,14 @@ mode is experimental." :version "24.1" ; rev670 :group 'verilog-mode-actions :type 'boolean) -(put 'verilog-auto-declare-nettype 'safe-local-variable 'stringp) +(put 'verilog-auto-declare-nettype 'safe-local-variable #'stringp) (defcustom verilog-auto-wire-comment t "Non-nil indicates to insert to/from comments with `verilog-auto-wire' etc." :version "25.1" :group 'verilog-mode-actions :type 'boolean) -(put 'verilog-auto-wire-comment 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-wire-comment 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-wire-type nil "Non-nil specifies the data type to use with `verilog-auto-wire' etc. @@ -790,21 +810,21 @@ containing SystemVerilog cells." :version "24.1" ; rev673 :group 'verilog-mode-actions :type '(choice (const nil) string)) -(put 'verilog-auto-wire-type 'safe-local-variable 'stringp) +(put 'verilog-auto-wire-type 'safe-local-variable #'stringp) (defcustom verilog-auto-endcomments t "Non-nil means insert a comment /* ... */ after `end's. The name of the function or case will be set between the braces." :group 'verilog-mode-actions :type 'boolean) -(put 'verilog-auto-endcomments 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-endcomments 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-delete-trailing-whitespace nil "Non-nil means to `delete-trailing-whitespace' in `verilog-auto'." :version "24.1" ; rev703 :group 'verilog-mode-actions :type 'boolean) -(put 'verilog-auto-delete-trailing-whitespace 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-delete-trailing-whitespace 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-ignore-concat nil "Non-nil means ignore signals in {...} concatenations for AUTOWIRE etc. @@ -812,7 +832,7 @@ This will exclude signals referenced as pin connections in {...} or (...) from AUTOWIRE, AUTOOUTPUT and friends." :group 'verilog-mode-actions :type 'boolean) -(put 'verilog-auto-ignore-concat 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-ignore-concat 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-read-includes nil "Non-nil means to automatically read includes before AUTOs. @@ -822,7 +842,7 @@ but can result in very slow reading times if there are many or large include files." :group 'verilog-mode-actions :type 'boolean) -(put 'verilog-auto-read-includes 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-read-includes 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-save-policy nil "Non-nil indicates action to take when saving a Verilog buffer with AUTOs. @@ -843,7 +863,7 @@ They will be expanded in the same way as if there was an AUTOINST in the instantiation. See also `verilog-auto-star' and `verilog-auto-star-save'." :group 'verilog-mode-actions :type 'boolean) -(put 'verilog-auto-star-expand 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-star-expand 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-star-save nil "Non-nil means save to disk SystemVerilog .* instance expansions. @@ -854,7 +874,7 @@ Instead of setting this, you may want to use /*AUTOINST*/, which will always be saved." :group 'verilog-mode-actions :type 'boolean) -(put 'verilog-auto-star-save 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-star-save 'safe-local-variable #'verilog-booleanp) (defvar verilog-auto-update-tick nil "Modification tick at which autos were last performed.") @@ -862,7 +882,7 @@ always be saved." (defvar verilog-auto-last-file-locals nil "Text from file-local-variables during last evaluation.") -(defvar verilog-diff-function 'verilog-diff-report +(defvar verilog-diff-function #'verilog-diff-report "Function to run when `verilog-diff-auto' detects differences. Function takes three arguments, the original buffer, the difference buffer, and the point in original buffer with the @@ -917,7 +937,7 @@ See `compilation-error-regexp-alist' for the formatting. For Emacs 22+.") ;; Emacs form is '((v-tool "re" 1 2) ...) ;; XEmacs form is '(verilog ("re" 1 2) ...) ;; So we can just map from Emacs to XEmacs - (cons 'verilog (mapcar 'cdr verilog-error-regexp-emacs-alist)) + (cons 'verilog (mapcar #'cdr verilog-error-regexp-emacs-alist)) "List of regexps for Verilog compilers. See `compilation-error-regexp-alist-alist' for the formatting. For XEmacs.") @@ -997,7 +1017,7 @@ have problems, use \\[find-alternate-file] RET to have these take effect. See also the variables mentioned above." :group 'verilog-mode-auto :type '(repeat string)) -(put 'verilog-library-flags 'safe-local-variable 'listp) +(put 'verilog-library-flags 'safe-local-variable #'listp) (defcustom verilog-library-directories '(".") "List of directories when looking for files for /*AUTOINST*/. @@ -1020,7 +1040,7 @@ See also `verilog-library-flags', `verilog-library-files' and `verilog-library-extensions'." :group 'verilog-mode-auto :type '(repeat file)) -(put 'verilog-library-directories 'safe-local-variable 'listp) +(put 'verilog-library-directories 'safe-local-variable #'listp) (defcustom verilog-library-files '() "List of files to search for modules. @@ -1042,14 +1062,14 @@ have problems, use \\[find-alternate-file] RET to have these take effect. See also `verilog-library-flags', `verilog-library-directories'." :group 'verilog-mode-auto :type '(repeat directory)) -(put 'verilog-library-files 'safe-local-variable 'listp) +(put 'verilog-library-files 'safe-local-variable #'listp) (defcustom verilog-library-extensions '(".v" ".va" ".sv") "List of extensions to use when looking for files for /*AUTOINST*/. See also `verilog-library-flags', `verilog-library-directories'." :type '(repeat string) :group 'verilog-mode-auto) -(put 'verilog-library-extensions 'safe-local-variable 'listp) +(put 'verilog-library-extensions 'safe-local-variable #'listp) (defcustom verilog-active-low-regexp nil "If true, treat signals matching this regexp as active low. @@ -1057,7 +1077,7 @@ This is used for AUTORESET and AUTOTIEOFF. For proper behavior, you will probably also need `verilog-auto-reset-widths' set." :group 'verilog-mode-auto :type '(choice (const nil) regexp)) -(put 'verilog-active-low-regexp 'safe-local-variable 'stringp) +(put 'verilog-active-low-regexp 'safe-local-variable #'stringp) (defcustom verilog-auto-sense-include-inputs nil "Non-nil means AUTOSENSE should include all inputs. @@ -1065,7 +1085,7 @@ If nil, only inputs that are NOT output signals in the same block are included." :group 'verilog-mode-auto :type 'boolean) -(put 'verilog-auto-sense-include-inputs 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-sense-include-inputs 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-sense-defines-constant nil "Non-nil means AUTOSENSE should assume all defines represent constants. @@ -1074,7 +1094,7 @@ maintain compatibility with other sites, this should be set at the bottom of each Verilog file that requires it, rather than being set globally." :group 'verilog-mode-auto :type 'boolean) -(put 'verilog-auto-sense-defines-constant 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-sense-defines-constant 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-simplify-expressions t "Non-nil means AUTOs will simplify expressions when calculating bit ranges. @@ -1086,7 +1106,7 @@ file that requires it, rather than being set globally." :version "27.1" :group 'verilog-mode-auto :type 'boolean) -(put 'verilog-auto-simplify-expressions 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-simplify-expressions 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-reset-blocking-in-non t "Non-nil means AUTORESET will reset blocking statements. @@ -1101,7 +1121,7 @@ those temporaries reset. See example in `verilog-auto-reset'." :version "24.1" ; rev718 :type 'boolean :group 'verilog-mode-auto) -(put 'verilog-auto-reset-blocking-in-non 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-reset-blocking-in-non 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-reset-widths t "True means AUTORESET should determine the width of signals. @@ -1124,7 +1144,7 @@ SystemVerilog designs." "Text used for delays in delayed assignments. Add a trailing space if set." :group 'verilog-mode-auto :type 'string) -(put 'verilog-assignment-delay 'safe-local-variable 'stringp) +(put 'verilog-assignment-delay 'safe-local-variable #'stringp) (defcustom verilog-auto-arg-format 'packed "Formatting to use for AUTOARG signal names. @@ -1150,7 +1170,7 @@ it's bad practice to rely on order based instantiations anyhow. See also `verilog-auto-inst-sort'." :group 'verilog-mode-auto :type 'boolean) -(put 'verilog-auto-arg-sort 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-arg-sort 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-inst-dot-name nil "Non-nil means when creating ports with AUTOINST, use .name syntax. @@ -1160,7 +1180,7 @@ simulators. Setting `verilog-auto-inst-vector' to nil may also be desirable to increase how often .name will be used." :group 'verilog-mode-auto :type 'boolean) -(put 'verilog-auto-inst-dot-name 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-inst-dot-name 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-inst-param-value nil "Non-nil means AUTOINST will replace parameters with the parameter value. @@ -1227,7 +1247,7 @@ This second expansion of parameter types can be overridden with `verilog-auto-inst-param-value-type'." :group 'verilog-mode-auto :type 'boolean) -(put 'verilog-auto-inst-param-value 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-inst-param-value 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-inst-param-value-type t "Non-nil means expand parameter type in instantiations. @@ -1237,7 +1257,7 @@ See `verilog-auto-inst-param-value'." :version "25.1" :group 'verilog-mode-auto :type 'boolean) -(put 'verilog-auto-inst-param-value-type 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-inst-param-value-type 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-inst-sort nil "Non-nil means AUTOINST signals will be sorted, not in declaration order. @@ -1250,7 +1270,7 @@ See also `verilog-auto-arg-sort'." :version "24.1" ; rev688 :group 'verilog-mode-auto :type 'boolean) -(put 'verilog-auto-inst-sort 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-inst-sort 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-inst-vector t "True means when creating default ports with AUTOINST, use bus subscripts. @@ -1292,48 +1312,48 @@ to a net with the same name as the port." :version "28.0" :group 'verilog-mode-auto :type 'boolean) -(put 'verilog-auto-inst-template-required 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-inst-template-required 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-inst-column 40 "Indent-to column number for net name part of AUTOINST created pin." :group 'verilog-mode-indent :type 'integer) -(put 'verilog-auto-inst-column 'safe-local-variable 'integerp) +(put 'verilog-auto-inst-column 'safe-local-variable #'integerp) (defcustom verilog-auto-inst-interfaced-ports nil "Non-nil means include interfaced ports in AUTOINST expansions." :version "24.3" ; rev773, default change rev815 :group 'verilog-mode-auto :type 'boolean) -(put 'verilog-auto-inst-interfaced-ports 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-inst-interfaced-ports 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-input-ignore-regexp nil "If non-nil, when creating AUTOINPUT, ignore signals matching this regexp. See the \\[verilog-faq] for examples on using this." :group 'verilog-mode-auto :type '(choice (const nil) regexp)) -(put 'verilog-auto-input-ignore-regexp 'safe-local-variable 'stringp) +(put 'verilog-auto-input-ignore-regexp 'safe-local-variable #'stringp) (defcustom verilog-auto-reg-input-assigned-ignore-regexp nil "If non-nil, when creating AUTOINPUTREG, ignore signals matching this regexp." :version "27.1" :group 'verilog-mode-auto :type '(choice (const nil) regexp)) -(put 'verilog-auto-reg-input-assigned-ignore-regexp 'safe-local-variable 'stringp) +(put 'verilog-auto-reg-input-assigned-ignore-regexp 'safe-local-variable #'stringp) (defcustom verilog-auto-inout-ignore-regexp nil "If non-nil, when creating AUTOINOUT, ignore signals matching this regexp. See the \\[verilog-faq] for examples on using this." :group 'verilog-mode-auto :type '(choice (const nil) regexp)) -(put 'verilog-auto-inout-ignore-regexp 'safe-local-variable 'stringp) +(put 'verilog-auto-inout-ignore-regexp 'safe-local-variable #'stringp) (defcustom verilog-auto-output-ignore-regexp nil "If non-nil, when creating AUTOOUTPUT, ignore signals matching this regexp. See the \\[verilog-faq] for examples on using this." :group 'verilog-mode-auto :type '(choice (const nil) regexp)) -(put 'verilog-auto-output-ignore-regexp 'safe-local-variable 'stringp) +(put 'verilog-auto-output-ignore-regexp 'safe-local-variable #'stringp) (defcustom verilog-auto-template-warn-unused nil "Non-nil means report warning if an AUTO_TEMPLATE line is not used. @@ -1341,7 +1361,7 @@ This feature is not supported before Emacs 21.1 or XEmacs 21.4." :version "24.3" ; rev787 :group 'verilog-mode-auto :type 'boolean) -(put 'verilog-auto-template-warn-unused 'safe-local-variable 'verilog-booleanp) +(put 'verilog-auto-template-warn-unused 'safe-local-variable #'verilog-booleanp) (defcustom verilog-auto-tieoff-declaration "wire" "Data type used for the declaration for AUTOTIEOFF. @@ -1350,21 +1370,21 @@ assignment, else the data type for variable creation." :version "24.1" ; rev713 :group 'verilog-mode-auto :type 'string) -(put 'verilog-auto-tieoff-declaration 'safe-local-variable 'stringp) +(put 'verilog-auto-tieoff-declaration 'safe-local-variable #'stringp) (defcustom verilog-auto-tieoff-ignore-regexp nil "If non-nil, when creating AUTOTIEOFF, ignore signals matching this regexp. See the \\[verilog-faq] for examples on using this." :group 'verilog-mode-auto :type '(choice (const nil) regexp)) -(put 'verilog-auto-tieoff-ignore-regexp 'safe-local-variable 'stringp) +(put 'verilog-auto-tieoff-ignore-regexp 'safe-local-variable #'stringp) (defcustom verilog-auto-unused-ignore-regexp nil "If non-nil, when creating AUTOUNUSED, ignore signals matching this regexp. See the \\[verilog-faq] for examples on using this." :group 'verilog-mode-auto :type '(choice (const nil) regexp)) -(put 'verilog-auto-unused-ignore-regexp 'safe-local-variable 'stringp) +(put 'verilog-auto-unused-ignore-regexp 'safe-local-variable #'stringp) (defcustom verilog-case-fold t "Non-nil means `verilog-mode' regexps should ignore case. @@ -1372,7 +1392,7 @@ This variable is t for backward compatibility; nil is suggested." :version "24.4" :group 'verilog-mode :type 'boolean) -(put 'verilog-case-fold 'safe-local-variable 'verilog-booleanp) +(put 'verilog-case-fold 'safe-local-variable #'verilog-booleanp) (defcustom verilog-typedef-regexp nil "If non-nil, regular expression that matches Verilog-2001 typedef names. @@ -1380,9 +1400,9 @@ For example, \"_t$\" matches typedefs named with _t, as in the C language. See also `verilog-case-fold'." :group 'verilog-mode-auto :type '(choice (const nil) regexp)) -(put 'verilog-typedef-regexp 'safe-local-variable 'stringp) +(put 'verilog-typedef-regexp 'safe-local-variable #'stringp) -(defcustom verilog-mode-hook 'verilog-set-compile-command +(defcustom verilog-mode-hook (list #'verilog-set-compile-command) "Hook run after Verilog mode is loaded." :type 'hook :group 'verilog-mode) @@ -2035,17 +2055,25 @@ be substituted." (set (make-local-variable 'verilog-compile-command-post-mod) compile-command)))) -(if (featurep 'xemacs) +(when (featurep 'xemacs) + (defvar compilation-error-regexp-systems-alist) + (if (not (and (= emacs-major-version 21) (<= emacs-minor-version 4))) + ;; XEmacs 21.5 and newer match GNU, see bug1700 + (defun verilog-error-regexp-add-xemacs () + (interactive) + (verilog-error-regexp-add-xemacs)) + ;; XEmacs 21.4 and older ;; Following code only gets called from compilation-mode-hook on XEmacs to add error handling. (defun verilog-error-regexp-add-xemacs () - "Teach XEmacs about verilog errors. + "Teach XEmacs about Verilog errors. Called by `compilation-mode-hook'. This allows \\[next-error] to find the errors." (interactive) (if (boundp 'compilation-error-regexp-systems-alist) (if (and (not (equal compilation-error-regexp-systems-list 'all)) - (not (member compilation-error-regexp-systems-list 'verilog))) + ;; eval required due to bug1700, XEmacs otherwise errors on compile + (not (eval "(member compilation-error-regexp-systems-list 'verilog)"))) (push 'verilog compilation-error-regexp-systems-list))) (if (boundp 'compilation-error-regexp-alist-alist) (if (not (assoc 'verilog compilation-error-regexp-alist-alist)) @@ -2060,7 +2088,7 @@ find the errors." ;; Need to re-run compilation-error-regexp builder (if (fboundp 'compilation-build-compilation-error-regexp-alist) (compilation-build-compilation-error-regexp-alist)) - )) + ))) ;; Following code only gets called from compilation-mode-hook on Emacs to add error handling. (defun verilog-error-regexp-add-emacs () @@ -2076,8 +2104,10 @@ find the errors." (push item compilation-error-regexp-alist-alist)) verilog-error-regexp-emacs-alist)))) -(if (featurep 'xemacs) (add-hook 'compilation-mode-hook 'verilog-error-regexp-add-xemacs)) -(if (featurep 'emacs) (add-hook 'compilation-mode-hook 'verilog-error-regexp-add-emacs)) +(add-hook 'compilation-mode-hook + (if (featurep 'xemacs) + #'verilog-error-regexp-add-xemacs + #'verilog-error-regexp-add-emacs)) (defconst verilog-compiler-directives (eval-when-compile @@ -2285,7 +2315,8 @@ find the errors." "`ovm_update_sequence_lib_and_item" "`ovm_warning" "`static_dut_error" - "`static_message") nil ))) + "`static_message") + nil ))) (defconst verilog-uvm-statement-re (eval-when-compile @@ -2424,7 +2455,8 @@ find the errors." "`uvm_update_sequence_lib" ; Deprecated in 1.1 "`uvm_update_sequence_lib_and_item" ; Deprecated in 1.1 "`uvm_warning" - "`uvm_warning_context") nil ))) + "`uvm_warning_context") + nil ))) ;; @@ -2566,10 +2598,10 @@ find the errors." "\\(property\\)\\|" ; 16 "\\(connectmodule\\)\\|" ; 17 "\\)\\>\\)")) + (defconst verilog-end-block-re (eval-when-compile (verilog-regexp-words - '("end" ; closes begin "endcase" ; closes any of case, casex casez or randcase "join" "join_any" "join_none" ; closes fork @@ -2606,7 +2638,6 @@ find the errors." "`vmm_xactor_member_end" )))) - (defconst verilog-endcomment-reason-re ;; Parenthesis indicate type of keyword found (concat @@ -2775,6 +2806,8 @@ find the errors." "shortreal" "real" "realtime" ;; net_type "supply0" "supply1" "tri" "triand" "trior" "trireg" "tri0" "tri1" "uwire" "wire" "wand" "wor" + ;; parameters + "localparam" "parameter" "var" ;; misc "string" "event" "chandle" "virtual" "enum" "genvar" "struct" "union" @@ -3310,13 +3343,20 @@ See also `verilog-font-lock-extra-types'.") '("\\\\s-+\\(\\sw+\\)" 1 'font-lock-constant-face append) ;; Fontify variable names in declarations - (list ;; Implemented as an anchored-matcher - (concat verilog-declaration-re - " *\\(" verilog-range-re "\\)?") - (list ;; anchored-highlighter - (concat "\\_<\\(" verilog-symbol-re "\\)" - " *\\(" verilog-range-re "\\)?*") - nil nil '(1 font-lock-variable-name-face)))))) + (list + verilog-declaration-re + (list + ;; Anchored matcher (lookup Search-Based Fontification) + 'verilog-declaration-varname-matcher + ;; Pre-form for this anchored matcher: + ;; First, avoid declaration keywords written in comments, + ;; which can also trigger this anchor. + '(if (not (verilog-in-comment-p)) + (verilog-single-declaration-end verilog-highlight-max-lookahead) + (point)) ;; => current declaration statement is of 0 length + nil ;; Post-form: nothing to be done + '(0 font-lock-variable-name-face t t))) + ))) (setq verilog-font-lock-keywords-2 @@ -3564,6 +3604,87 @@ inserted using a single call to `verilog-insert'." (defun verilog-declaration-end () (search-forward ";")) +(defun verilog-single-declaration-end (limit) + "Returns pos where current (single) declaration statement ends. +Also, this function moves POINT forward to the start of a variable name +(skipping the range-part and whitespace). +Function expected to be called with POINT just after a declaration keyword. +LIMIT sets the max POINT for searching and moving to. No such limit if LIMIT +is 0. + +Meaning of *single* declaration: + Eg. In a module's port-list - + module test(input clk, rst, x, output [1:0] y); + Here 'input clk, rst, x' is 1 *single* declaration statement, +and 'output [1:0] y' is the other single declaration. In the 1st single +declaration, POINT is moved to start of 'clk'. And in the 2nd declaration, +POINT is moved to 'y'." + + + (let (maxpoint old-point) + ;; maxpoint = min(curr-point + limit, buffer-size) + (setq maxpoint (if (eq limit 0) + (point-max) ;; no bounds if search-bound is zero + (+ (point) limit))) + (if (> maxpoint (buffer-size)) (setq maxpoint (buffer-size))) + + ;; Skip comment - range - comment + (verilog-forward-ws&directives maxpoint) + (when (eq (char-after) ?\[) + (re-search-forward verilog-range-re maxpoint t)) + (verilog-forward-ws&directives maxpoint) + + ;; Move forward until a delimiter is reached which marks end of current + ;; single declaration. Return point at found delimiter + (save-excursion + (while (and (< (point) maxpoint) + (not (eq old-point (point))) + (not (eq (char-after) ?\; )) + (not (eq (char-after) ?\) )) + (not (looking-at verilog-declaration-re))) + (setq old-point (point)) + (ignore-errors + (forward-sexp) + (verilog-forward-ws&directives maxpoint) + (when (eq (char-after) ?,) + (forward-char) + (verilog-forward-ws&directives maxpoint)))) + (point)))) + +(defun verilog-declaration-varname-matcher (limit) + "Match first variable name b/w POINT & LIMIT, move POINT to next variable. +Expected to be called within a declaration statement, with POINT already beyond +the declaration keyword and range ([a:b]) +This function moves POINT to the next variable within the same declaration (if +it exists). +LIMIT is expected to be the pos at which current single-declaration ends, +obtained using `verilog-single-declaration-end'." + + (let (found-var old-point) + + ;; Remove starting whitespace + (verilog-forward-ws&directives limit) + + (when (< (point) limit) ;; no matching if this is violated + + ;; Find the variable name (match-data is set here) + (setq found-var (re-search-forward verilog-symbol-re limit t)) + + ;; Walk to this variable's delimiter + (save-match-data + (verilog-forward-ws&directives limit) + (setq old-point nil) + (while (and (< (point) limit) + (not (member (char-after) '(?, ?\) ?\;))) + (not (eq old-point (point)))) + (setq old-point (point)) + (verilog-forward-ws&directives limit) + (forward-sexp) + (verilog-forward-ws&directives limit)) + ;; Only a comma or semicolon expected at this point + (skip-syntax-forward ".")) + found-var))) + (defun verilog-point-text (&optional pointnum) "Return text describing where POINTNUM or current point is (for errors). Use filename, if current buffer being edited shorten to just buffer name." @@ -3934,13 +4055,13 @@ Key bindings specific to `verilog-mode-map' are: \\{verilog-mode-map}" :abbrev-table verilog-mode-abbrev-table (set (make-local-variable 'beginning-of-defun-function) - 'verilog-beg-of-defun) + #'verilog-beg-of-defun) (set (make-local-variable 'end-of-defun-function) - 'verilog-end-of-defun) + #'verilog-end-of-defun) (set-syntax-table verilog-mode-syntax-table) (set (make-local-variable 'indent-line-function) #'verilog-indent-line-relative) - (set (make-local-variable 'comment-indent-function) 'verilog-comment-indent) + (set (make-local-variable 'comment-indent-function) #'verilog-comment-indent) (set (make-local-variable 'parse-sexp-ignore-comments) nil) (set (make-local-variable 'comment-start) "// ") (set (make-local-variable 'comment-end) "") @@ -3951,7 +4072,7 @@ Key bindings specific to `verilog-mode-map' are: (setq verilog-tool 'verilog-linter) (verilog-set-compile-command) (when (boundp 'hack-local-variables-hook) ; Also modify any file-local-variables - (add-hook 'hack-local-variables-hook 'verilog-modify-compile-command t)) + (add-hook 'hack-local-variables-hook #'verilog-modify-compile-command t)) ;; Setting up menus (when (featurep 'xemacs) @@ -3973,6 +4094,10 @@ Key bindings specific to `verilog-mode-map' are: ;; verilog-beg-of-defun. nil 'verilog-beg-of-defun))) + + ;; Stuff for multiline font-lock + (set (make-local-variable 'font-lock-multiline) t) + ;;------------------------------------------------------------ ;; now hook in 'verilog-highlight-include-files (eldo-mode.el&spice-mode.el) ;; all buffer local: @@ -3981,9 +4106,9 @@ Key bindings specific to `verilog-mode-map' are: (make-local-hook 'font-lock-mode-hook) (make-local-hook 'font-lock-after-fontify-buffer-hook); doesn't exist in Emacs (make-local-hook 'after-change-functions)) - (add-hook 'font-lock-mode-hook 'verilog-highlight-buffer t t) - (add-hook 'font-lock-after-fontify-buffer-hook 'verilog-highlight-buffer t t) ; not in Emacs - (add-hook 'after-change-functions 'verilog-highlight-region t t)) + (add-hook 'font-lock-mode-hook #'verilog-highlight-buffer t t) + (add-hook 'font-lock-after-fontify-buffer-hook #'verilog-highlight-buffer t t) ; not in Emacs + (add-hook 'after-change-functions #'verilog-highlight-region t t)) ;; Tell imenu how to handle Verilog. (set (make-local-variable 'imenu-generic-expression) @@ -4005,7 +4130,7 @@ Key bindings specific to `verilog-mode-map' are: ;; Stuff for autos (add-hook (if (boundp 'write-contents-hooks) 'write-contents-hooks 'write-contents-functions) ; Emacs >= 22.1 - 'verilog-auto-save-check nil 'local) + #'verilog-auto-save-check nil 'local) ;; verilog-mode-hook call added by define-derived-mode ) @@ -5424,22 +5549,23 @@ FILENAME to find directory to run in, or defaults to `buffer-file-name'." ;; We should use font-lock-ensure in preference to ;; font-lock-fontify-buffer, but IIUC the problem this is supposed to ;; solve only appears in Emacsen older than font-lock-ensure anyway. - ;; So avoid bytecomp's interactive-only by going through intern. - (when fontlocked (funcall (intern "font-lock-fontify-buffer")))))))) + (when fontlocked + (verilog--supressed-warnings + ((interactive-only font-lock-fontify-buffer)) + (font-lock-fontify-buffer)))))))) ;;; Batch: ;; (defun verilog-warn (string &rest args) "Print a warning with `format' using STRING and optional ARGS." - (apply 'message (concat "%%Warning: " string) args)) + (apply #'message (concat "%%Warning: " string) args)) (defun verilog-warn-error (string &rest args) "Call `error' using STRING and optional ARGS. If `verilog-warn-fatal' is non-nil, call `verilog-warn' instead." - (if verilog-warn-fatal - (apply 'error string args) - (apply 'verilog-warn string args))) + (apply (if verilog-warn-fatal #'error #'verilog-warn) + string args)) (defmacro verilog-batch-error-wrapper (&rest body) "Execute BODY and add error prefix to any errors found. @@ -6452,6 +6578,7 @@ Return >0 for nested struct." (let ((p (point))) (and (equal (char-after) ?\{) + (not (verilog-at-streaming-op-p)) (ignore-errors (forward-list)) (progn (backward-char 1) (verilog-backward-ws&directives) @@ -6489,6 +6616,18 @@ Return >0 for nested struct." ;; not nil)) +(defconst verilog-streaming-op-re + ;; Regexp to detect Streaming Operator expressions + (concat + "{" "\\s-*" + "\\(<<\\|>>\\)" ".*" + "{" ".*" "}" "\\s-*" "}" + )) + +(defun verilog-at-streaming-op-p () + "If at the { of a streaming operator, return t." + (looking-at verilog-streaming-op-re)) + (defun verilog-at-struct-p () "If at the { of a struct, return true, not moving point." (save-excursion @@ -7961,6 +8100,8 @@ See also `verilog-sk-header' for an alternative format." ;; Unfortunately we use 'assoc' on this, so can't be a vector (defsubst verilog-sig-new (name bits comment mem enum signed type multidim modport) (list name bits comment mem enum signed type multidim modport)) +(defsubst verilog-sig-new-renamed (name old-sig) + (cons name (cdr old-sig))) (defsubst verilog-sig-name (sig) (car sig)) (defsubst verilog-sig-bits (sig) ; First element of packed array (pre signal-name) @@ -8315,7 +8456,7 @@ Tieoff value uses `verilog-active-low-regexp' and (t (let* ((width (verilog-sig-width sig))) (cond ((not width) - "`0/*NOWIDTH*/") + "'0/*NOWIDTH*/") ((string-match "^[0-9]+$" width) (concat width (if (verilog-sig-signed sig) "'sh0" "'h0"))) (t @@ -8497,9 +8638,25 @@ Optional NUM-PARAM and MAX-PARAM check for a specific number of parameters." (error "%s: Expected <= %d parameters" (verilog-point-text) max-param)) (nreverse olist))) +;; Prevent compile warnings; these are let's, not globals. +(defvar sigs-in) +(defvar sigs-inout) +(defvar sigs-intf) +(defvar sigs-intfd) +(defvar sigs-out) +(defvar sigs-out-d) +(defvar sigs-out-i) +(defvar sigs-out-unk) +(defvar sigs-temp) +;; These are known to be from other packages and may not be defined +(defvar diff-command) +;; There are known to be from newer versions of Emacs +(defvar create-lockfiles) +(defvar which-func-modes) + (defun verilog-read-decls () "Compute signal declaration information for the current module at point. -Return an array of [outputs inouts inputs wire reg assign const]." +Return an array of [outputs inouts inputs wire reg assign const gparam intf]." (let ((end-mod-point (or (verilog-get-end-of-defun) (point-max))) (functask 0) (paren 0) (sig-paren 0) (v2kargs-ok t) in-modport in-clocking in-ign-to-semi ptype ign-prop @@ -8777,25 +8934,6 @@ Return an array of [outputs inouts inputs wire reg assign const]." (defvar verilog-read-sub-decls-gate-ios nil "For `verilog-read-sub-decls', gate IO pins remaining, nil if non-primitive.") -(eval-when-compile - ;; Prevent compile warnings; these are let's, not globals - ;; Do not remove the eval-when-compile - ;; - we want an error when we are debugging this code if they are refed. - (defvar sigs-in) - (defvar sigs-inout) - (defvar sigs-intf) - (defvar sigs-intfd) - (defvar sigs-out) - (defvar sigs-out-d) - (defvar sigs-out-i) - (defvar sigs-out-unk) - (defvar sigs-temp) - ;; These are known to be from other packages and may not be defined - (defvar diff-command) - ;; There are known to be from newer versions of Emacs - (defvar create-lockfiles) - (defvar which-func-modes)) - (defun verilog-read-sub-decls-type (par-values portdata) "For `verilog-read-sub-decls-line', decode a signal type." (let* ((type (verilog-sig-type portdata)) @@ -8894,7 +9032,8 @@ Return an array of [outputs inouts inputs wire reg assign const]." "For `verilog-read-sub-decls-line', parse a subexpression and add signals." ;;(message "vrsde: `%s'" expr) ;; Replace special /*[....]*/ comments inserted by verilog-auto-inst-port - (setq expr (verilog-string-replace-matches "/\\*\\(\\.?\\[[^*]+\\]\\)\\*/" "\\1" nil nil expr)) + (setq expr (verilog-string-replace-matches + "/\\*\\(\\.?\\[\\([^*]+\\|[*][^/]\\)+\\]\\)\\*/" "\\1" nil nil expr)) ;; Remove front operators (setq expr (verilog-string-replace-matches "^\\s-*[---+~!|&]+\\s-*" "" nil nil expr)) ;; @@ -9809,10 +9948,10 @@ Use DEFAULT-DIR to anchor paths if non-nil." "Convert `verilog-library-flags' into standard library variables." ;; If the flags are local, then all the outputs should be local also (when (local-variable-p 'verilog-library-flags (current-buffer)) - (mapc 'make-local-variable '(verilog-library-extensions - verilog-library-directories - verilog-library-files - verilog-library-flags))) + (mapc #'make-local-variable '(verilog-library-extensions + verilog-library-directories + verilog-library-files + verilog-library-flags))) ;; Allow user to customize (verilog-run-hooks 'verilog-before-getopt-flags-hook) ;; Process arguments @@ -10017,7 +10156,7 @@ Or, just the existing dirnames themselves if there are no wildcards." (setq dirnames (reverse dirnames)) ; not nreverse (let ((dirlist nil) pattern dirfile dirfiles dirname root filename rest basefile) - (setq dirnames (mapcar 'substitute-in-file-name dirnames)) + (setq dirnames (mapcar #'substitute-in-file-name dirnames)) (while dirnames (setq dirname (car dirnames) dirnames (cdr dirnames)) @@ -10210,7 +10349,7 @@ Return modi if successful, else print message unless IGNORE-ERROR is true." (if (not (equal module realname)) (concat " (Expanded macro to " realname ")") "") - (mapconcat 'concat orig-filenames "\n\t"))) + (mapconcat #'concat orig-filenames "\n\t"))) (when (eval-when-compile (fboundp 'make-hash-table)) (unless verilog-modi-lookup-cache (setq verilog-modi-lookup-cache @@ -10348,42 +10487,47 @@ those clocking block's signals." (defun verilog-signals-matching-enum (in-list enum) "Return all signals in IN-LIST matching the given ENUM." (let (out-list) - (while in-list - (if (equal (verilog-sig-enum (car in-list)) enum) - (setq out-list (cons (car in-list) out-list))) - (setq in-list (cdr in-list))) + (dolist (sig in-list) + (if (equal (verilog-sig-enum sig) enum) + (push sig out-list))) ;; New scheme ;; Namespace intentionally short for AUTOs and compatibility - (let* ((enumvar (intern (concat "venum-" enum))) - (enumlist (and (boundp enumvar) (eval enumvar)))) - (while enumlist - (add-to-list 'out-list (list (car enumlist))) - (setq enumlist (cdr enumlist)))) + (let* ((enumvar (intern (concat "venum-" enum)))) + (dolist (en (and (boundp enumvar) (eval enumvar))) + (let ((sig (list en))) + (unless (member sig out-list) + (push sig out-list))))) (nreverse out-list))) (defun verilog-signals-matching-regexp (in-list regexp) - "Return all signals in IN-LIST matching the given REGEXP, if non-nil." + "Return all signals in IN-LIST matching the given REGEXP, if non-nil. +Allow regexp inversion if REGEXP begins with ?!." (if (or (not regexp) (equal regexp "")) in-list - (let ((case-fold-search verilog-case-fold) - out-list) - (while in-list - (if (string-match regexp (verilog-sig-name (car in-list))) - (setq out-list (cons (car in-list) out-list))) - (setq in-list (cdr in-list))) - (nreverse out-list)))) + (if (string-match "^\\?!" regexp) + (verilog-signals-not-matching-regexp in-list (substring regexp 2)) + (let ((case-fold-search verilog-case-fold) + out-list) + (while in-list + (if (string-match regexp (verilog-sig-name (car in-list))) + (setq out-list (cons (car in-list) out-list))) + (setq in-list (cdr in-list))) + (nreverse out-list))))) (defun verilog-signals-not-matching-regexp (in-list regexp) - "Return all signals in IN-LIST not matching the given REGEXP, if non-nil." + "Return all signals in IN-LIST not matching the given REGEXP, if non-nil. +Allow regexp inversion if REGEXP begins with ?!." (if (or (not regexp) (equal regexp "")) in-list - (let ((case-fold-search verilog-case-fold) - out-list) - (while in-list - (if (not (string-match regexp (verilog-sig-name (car in-list)))) - (setq out-list (cons (car in-list) out-list))) - (setq in-list (cdr in-list))) - (nreverse out-list)))) + (if (string-match "^\\?!" regexp) + (verilog-signals-matching-regexp in-list (substring regexp 2)) + (let ((case-fold-search verilog-case-fold) + out-list) + (while in-list + (if (not (string-match regexp (verilog-sig-name (car in-list)))) + (setq out-list (cons (car in-list) out-list))) + (setq in-list (cdr in-list))) + (nreverse out-list))))) (defun verilog-signals-matching-dir-re (in-list decl-type regexp) "Return all signals in IN-LIST matching the given DECL-TYPE and REGEXP, @@ -10396,7 +10540,7 @@ if non-nil." (setq to-match (concat decl-type " " (verilog-sig-signed (car in-list)) - " " (verilog-sig-multidim (car in-list)) + " " (verilog-sig-multidim-string (car in-list)) (verilog-sig-bits (car in-list)))) (if (string-match regexp to-match) (setq out-list (cons (car in-list) out-list))) @@ -10410,6 +10554,20 @@ if non-nil." (verilog-sig-type-set sig nil)) sig) in-list)) +(defun verilog-signals-add-prefix (in-list prefix) + "Return all signals in IN-LIST with PREFIX added." + (if (or (not prefix) (equal prefix "")) + in-list + (let (out-list) + (while in-list + (setq out-list (cons (verilog-sig-new-renamed + (concat prefix (verilog-sig-name (car in-list))) + (car in-list)) + out-list)) + (setq in-list (cdr in-list))) + (nreverse out-list)))) +;(verilog-signals-add-prefix (list (list "foo" "...") (list "bar" "...")) "p_") + ;; Combined (defun verilog-decls-get-signals (decls) "Return all declared signals in DECLS, excluding `assign' statements." @@ -10450,7 +10608,7 @@ if non-nil." ;; (defun verilog-auto-re-search-do (search-for func) - "Search for given auto text regexp SEARCH-FOR, and perform FUNC where it occurs." + "Given start brace BRA, and end brace KET, expand one line into many lines." (goto-char (point-min)) (while (verilog-re-search-forward-quick search-for nil t) (funcall func))) @@ -10540,9 +10698,7 @@ When MODI is non-null, also add to modi-cache, for tracking." (verilog-insert "// " (verilog-sig-comment sig) "\n")) (setq sigs (cdr sigs))))) -(eval-when-compile - (if (not (boundp 'indent-pt)) - (defvar indent-pt nil "Local used by `verilog-insert-indent'."))) +(defvar indent-pt) ;; Local used by `verilog-insert-indent'. (defun verilog-insert-indent (&rest stuff) "Indent to position stored in local `indent-pt' variable, then insert STUFF. @@ -10649,11 +10805,15 @@ This repairs those mis-inserted by an AUTOARG." (match-string 3 out)) nil nil out))) ;; For precedence do *,/ before +,-,>>,<< - (while (string-match - (concat "\\([[({:*/<>+-]\\)" - "\\([0-9]+\\)\\s *\\([*/]\\)\\s *\\([0-9]+\\)" - "\\([])}:*/<>+-]\\)") - out) + (while (and + (string-match + (concat "\\([[({:*/<>+-]\\)" + "\\([0-9]+\\)\\s *\\([*/]\\)\\s *\\([0-9]+\\)" + "\\([])}:*/<>+-]\\)") + out) + (not (and (equal (match-string 3 out) "/") + (not (equal 0 (% (string-to-number (match-string 2 out)) + (string-to-number (match-string 4 out)))))))) (setq out (replace-match (concat (match-string 1 out) (if (equal (match-string 3 out) "/") @@ -10725,6 +10885,7 @@ This repairs those mis-inserted by an AUTOARG." ;;(verilog-simplify-range-expression "[(TEST[1])-1:0]") ;;(verilog-simplify-range-expression "[1<<2:8>>2]") ; [4:2] ;;(verilog-simplify-range-expression "[2*4/(4-2) +2+4 <<4 >>2]") +;;(verilog-simplify-range-expression "[WIDTH*2/8-1:0]") (defun verilog-clog2 (value) "Compute $clog2 - ceiling log2 of VALUE." @@ -11336,6 +11497,8 @@ making verification modules that connect to UVM interfaces. The optional fourth parameter is a regular expression, and only signals matching the regular expression will be included. + The optional fifth parameter is a prefix to add to the signals. + Limitations: Interface names must be resolvable to filenames. See `verilog-auto-inst'. @@ -11349,11 +11512,12 @@ Limitations: See the example in `verilog-auto-inout-modport'." (save-excursion - (let* ((params (verilog-read-auto-params 3 4)) + (let* ((params (verilog-read-auto-params 3 5)) (submod (nth 0 params)) (modport-re (nth 1 params)) (inst-name (nth 2 params)) (regexp (nth 3 params)) + (prefix (nth 4 params)) direction-re submodi) ; direction argument not supported until requested ;; Lookup position, etc of co-module ;; Note this may raise an error @@ -11387,15 +11551,18 @@ See the example in `verilog-auto-inout-modport'." ;; Don't sort them so an upper AUTOINST will match the main module (let ((sigs sig-list-o)) (while sigs - (verilog-insert-indent "assign " (verilog-sig-name (car sigs)) - " = " inst-name - "." (verilog-sig-name (car sigs)) ";\n") + (verilog-insert-indent "assign " + (concat prefix (verilog-sig-name (car sigs))) + " = " inst-name + "." (verilog-sig-name (car sigs)) ";\n") (setq sigs (cdr sigs)))) (let ((sigs sig-list-i)) (while sigs - (verilog-insert-indent "assign " inst-name - "." (verilog-sig-name (car sigs)) - " = " (verilog-sig-name (car sigs)) ";\n") + (verilog-insert-indent "assign " inst-name + "." (verilog-sig-name (car sigs)) + " = " + (concat prefix (verilog-sig-name (car sigs))) + ";\n") (setq sigs (cdr sigs)))) (verilog-insert-indent "// End of automatics\n"))))))) @@ -11611,7 +11778,9 @@ declaration with ones automatically derived from the module or interface header of the instantiated item. You may also provide an optional regular expression, in which -case only I/O matching the regular expression will be included. +case only I/O matching the regular expression will be included, +or excluded if the regexp begins with ?! (question-mark +exclamation-mark). If `verilog-auto-star-expand' is set, also expand SystemVerilog .* ports, and delete them before saving unless `verilog-auto-star-save' is set. @@ -12047,7 +12216,8 @@ automatically derived from the module header of the instantiated netlist. You may also provide an optional regular expression, in which case only parameters matching the regular expression will be -included. +included, or excluded if the regexp begins with ?! (question-mark +exclamation-mark). See \\[verilog-auto-inst] for limitations, and templates to customize the output. @@ -12466,9 +12636,11 @@ Typing \\[verilog-auto] will make this into: wire o = tempb; endmodule -You may also provide an optional regular expression, in which case only -signals matching the regular expression will be included. For example the -same expansion will result from only extracting outputs starting with ov: +You may also provide an optional regular expression, in which +case only signals matching the regular expression will be +included,or excluded if the regexp begins with ?! (question-mark +exclamation-mark). For example the same expansion will result +from only extracting outputs starting with ov: /*AUTOOUTPUTEVERY(\"^ov\")*/" (save-excursion @@ -12544,9 +12716,12 @@ Typing \\[verilog-auto] will make this into: .i (i)); endmodule -You may also provide an optional regular expression, in which case only -signals matching the regular expression will be included. For example the -same expansion will result from only extracting inputs starting with i: +You may also provide an optional regular expression, in which +case only signals matching the regular expression will be +included. or excluded if the regexp begins with +?! (question-mark exclamation-mark). For example the same +expansion will result from only extracting inputs starting with +i: /*AUTOINPUT(\"^i\")*/" (save-excursion @@ -12628,9 +12803,11 @@ Typing \\[verilog-auto] will make this into: .io (io)); endmodule -You may also provide an optional regular expression, in which case only -signals matching the regular expression will be included. For example the -same expansion will result from only extracting inouts starting with i: +You may also provide an optional regular expression, in which +case only signals matching the regular expression will be +included, or excluded if the regexp begins with ?! (question-mark +exclamation-mark). For example the same expansion will result +from only extracting inouts starting with i: /*AUTOINOUT(\"^i\")*/" (save-excursion @@ -12711,9 +12888,11 @@ Typing \\[verilog-auto] will make this into: // End of automatics endmodule -You may also provide an optional regular expression, in which case only -signals matching the regular expression will be included. For example the -same expansion will result from only extracting signals starting with i: +You may also provide an optional regular expression, in which +case only signals matching the regular expression will be +included, or excluded if the regexp begins with ?! (question-mark +exclamation-mark). For example the same expansion will result +from only extracting signals starting with i: /*AUTOINOUTMODULE(\"ExampMain\",\"^i\")*/ @@ -12919,9 +13098,11 @@ Typing \\[verilog-auto] will make this into: // End of automatics endmodule -You may also provide an optional regular expression, in which case only -signals matching the regular expression will be included. For example the -same expansion will result from only extracting signals starting with i: +You may also provide an optional regular expression, in which +case only signals matching the regular expression will be +included, or excluded if the regexp begins with ?! (question-mark +exclamation-mark). For example the same expansion will result +from only extracting signals starting with i: /*AUTOINOUTIN(\"ExampMain\",\"^i\")*/" (verilog-auto-inout-module nil t)) @@ -13009,6 +13190,8 @@ for making verification modules that connect to UVM interfaces. The optional third parameter is a regular expression, and only signals matching the regular expression will be included. + The optional fourth parameter is a prefix to add to the signals. + Limitations: If placed inside the parenthesis of a module declaration, it creates Verilog 2001 style, else uses Verilog 1995 style. @@ -13032,10 +13215,16 @@ An example: modport mp(clocking mon_clkblk); endinterface + module ExampMain ( input clk, /*AUTOINOUTMODPORT(\"ExampIf\", \"mp\")*/ ); + + ExampleIf i; + + /*AUTOASSIGNMODPORT(\"ExampIf\", \"mp\", \"i\")*/ + endmodule Typing \\[verilog-auto] will make this into: @@ -13048,16 +13237,26 @@ Typing \\[verilog-auto] will make this into: input [7:0] req_dat // End of automatics ); + + ExampleIf i; + + /*AUTOASSIGNMODPORT(\"ExampIf\", \"mp\", \"i\")*/ + // Beginning of automatic assignments from modport + assign i.req_dat = req_dat; + assign i.req_val = req_val; + // End of automatics + endmodule If the modport is part of a UVM monitor/driver class, this creates a wrapper module that may be used to instantiate the driver/monitor using AUTOINST in the testbench." (save-excursion - (let* ((params (verilog-read-auto-params 2 3)) + (let* ((params (verilog-read-auto-params 2 4)) (submod (nth 0 params)) (modport-re (nth 1 params)) (regexp (nth 2 params)) + (prefix (nth 3 params)) direction-re submodi) ; direction argument not supported until requested ;; Lookup position, etc of co-module ;; Note this may raise an error @@ -13072,33 +13271,42 @@ driver/monitor using AUTOINST in the testbench." (verilog-decls-get-vars submoddecls) (verilog-signals-not-in (verilog-decls-get-inputs submodportdecls) - (append (verilog-decls-get-ports submoddecls) - (verilog-decls-get-ports moddecls))))) + (verilog-decls-get-ports submoddecls)))) (sig-list-o (verilog-signals-in ; Decls doesn't have data types, must resolve (verilog-decls-get-vars submoddecls) (verilog-signals-not-in (verilog-decls-get-outputs submodportdecls) - (append (verilog-decls-get-ports submoddecls) - (verilog-decls-get-ports moddecls))))) + (verilog-decls-get-ports submoddecls)))) (sig-list-io (verilog-signals-in ; Decls doesn't have data types, must resolve (verilog-decls-get-vars submoddecls) (verilog-signals-not-in (verilog-decls-get-inouts submodportdecls) - (append (verilog-decls-get-ports submoddecls) - (verilog-decls-get-ports moddecls)))))) + (verilog-decls-get-ports submoddecls))))) (forward-line 1) (setq sig-list-i (verilog-signals-edit-wire-reg - (verilog-signals-matching-dir-re - (verilog-signals-matching-regexp sig-list-i regexp) - "input" direction-re)) + (verilog-signals-not-in + (verilog-signals-add-prefix + (verilog-signals-matching-dir-re + (verilog-signals-matching-regexp sig-list-i regexp) + "input" direction-re) + prefix) + (verilog-decls-get-ports moddecls))) sig-list-o (verilog-signals-edit-wire-reg - (verilog-signals-matching-dir-re - (verilog-signals-matching-regexp sig-list-o regexp) - "output" direction-re)) + (verilog-signals-not-in + (verilog-signals-add-prefix + (verilog-signals-matching-dir-re + (verilog-signals-matching-regexp sig-list-o regexp) + "output" direction-re) + prefix) + (verilog-decls-get-ports moddecls))) sig-list-io (verilog-signals-edit-wire-reg - (verilog-signals-matching-dir-re - (verilog-signals-matching-regexp sig-list-io regexp) - "inout" direction-re))) + (verilog-signals-not-in + (verilog-signals-add-prefix + (verilog-signals-matching-dir-re + (verilog-signals-matching-regexp sig-list-io regexp) + "inout" direction-re) + prefix) + (verilog-decls-get-ports moddecls)))) (when v2k (verilog-repair-open-comma)) (when (or sig-list-i sig-list-o sig-list-io) (verilog-insert-indent "// Beginning of automatic in/out/inouts (from modport)\n") @@ -13335,7 +13543,7 @@ them to a one. AUTORESET may try to reset arrays or structures that cannot be reset by a simple assignment, resulting in compile errors. This is a feature to be taken as a hint that you need to reset these -signals manually (or put them into a \"\\=`ifdef NEVER signal<=\\=`0; +signals manually (or put them into a \"\\=`ifdef NEVER signal<=\\='0; \\=`endif\" so Verilog-Mode ignores them.) An example: @@ -13559,7 +13767,7 @@ defines the regular expression will be undefed." (t (setq defs (delete (match-string-no-properties 2) defs)))))) ;; Insert - (setq defs (sort defs 'string<)) + (setq defs (sort defs #'string<)) (when defs (verilog-forward-or-insert-line) (verilog-insert-indent "// Beginning of automatic undefs\n") commit 9a67da98a25f545ff68540e01a06bc62605ee147 Author: Alan Mackenzie Date: Tue Feb 2 20:34:42 2021 +0000 CC Mode: Prevent "const" inside an identifier being recognized as the keyword This fixes bug #45560. * lisp/progmodes/cc-engine.el (c-forward-declarator) (c-forward-decl-or-cast-1): Amend certain regexp match numbers on account of the change below. Surround some looking-at calls with save-match-data. * lisp/progmodes/cc-langs.el (c-type-decl-prefix-keywords-key): New lang const. (c-type-decl-prefix-key): Reformulate to match operators and keywords separately, using the new lang const (above). diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 3fce7dbafa..484624b866 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -9021,14 +9021,15 @@ point unchanged and return nil." (c-forward-noise-clause)) ((and (looking-at c-type-decl-prefix-key) (if (and (c-major-mode-is 'c++-mode) - (match-beginning 3)) + (match-beginning 4)) ; Was 3 - 2021-01-01 ;; If the third submatch matches in C++ then ;; we're looking at an identifier that's a ;; prefix only if it specifies a member pointer. (progn (setq id-start (point)) (c-forward-name) - (if (looking-at "\\(::\\)") + (if (save-match-data + (looking-at "\\(::\\)")) ;; We only check for a trailing "::" and ;; let the "*" that should follow be ;; matched in the next round. @@ -9038,13 +9039,15 @@ point unchanged and return nil." (setq got-identifier t) nil)) t)) - (if (looking-at c-type-decl-operator-prefix-key) + (if (save-match-data + (looking-at c-type-decl-operator-prefix-key)) (setq decorated t)) (if (eq (char-after) ?\() (progn (setq paren-depth (1+ paren-depth)) (forward-char)) - (goto-char (match-end 1))) + (goto-char (or (match-end 1) + (match-end 2)))) (c-forward-syntactic-ws) t))) @@ -9721,14 +9724,15 @@ This function might do hidden buffer changes." (setq after-paren-pos (point)))) (while (and (looking-at c-type-decl-prefix-key) (if (and (c-major-mode-is 'c++-mode) - (match-beginning 3)) - ;; If the third submatch matches in C++ then + (match-beginning 4)) + ;; If the fourth submatch matches in C++ then ;; we're looking at an identifier that's a ;; prefix only if it specifies a member pointer. (when (progn (setq pos (point)) (setq got-identifier (c-forward-name))) (setq name-start pos) - (if (looking-at "\\(::\\)") + (if (save-match-data + (looking-at "\\(::\\)")) ;; We only check for a trailing "::" and ;; let the "*" that should follow be ;; matched in the next round. @@ -9749,7 +9753,8 @@ This function might do hidden buffer changes." (when (save-match-data (looking-at c-type-decl-operator-prefix-key)) (setq got-function-name-prefix t)) - (goto-char (match-end 1))) + (goto-char (or (match-end 1) + (match-end 2)))) (c-forward-syntactic-ws))) (setq got-parens (> paren-depth 0)) diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index f4dcbcda96..07479389c6 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -3433,41 +3433,47 @@ possible for good performance." t (c-make-bare-char-alt (c-lang-const c-block-prefix-disallowed-chars) t)) (c-lang-defvar c-block-prefix-charset (c-lang-const c-block-prefix-charset)) -(c-lang-defconst c-type-decl-prefix-key - "Regexp matching any declarator operator that might precede the -identifier in a declaration, e.g. the \"*\" in \"char *argv\". This -regexp should match \"(\" if parentheses are valid in declarators. -The end of the first submatch is taken as the end of the operator. -Identifier syntax is in effect when this is matched (see -`c-identifier-syntax-table')." +(c-lang-defconst c-type-decl-prefix-keywords-key + ;; Regexp matching any keyword operator that might precede the identifier in + ;; a declaration, e.g. "const" or nil. It doesn't test there is no "_" + ;; following the keyword. t (if (or (c-lang-const c-type-modifier-kwds) (c-lang-const c-modifier-kwds)) - (concat + (concat (regexp-opt (c--delete-duplicates (append (c-lang-const c-type-modifier-kwds) (c-lang-const c-modifier-kwds)) :test 'string-equal) t) - "\\>") - ;; Default to a regexp that never matches. - regexp-unmatchable) + "\\>"))) + +(c-lang-defconst c-type-decl-prefix-key + "Regexp matching any declarator operator that might precede the +identifier in a declaration, e.g. the \"*\" in \"char *argv\". This +regexp should match \"(\" if parentheses are valid in declarators. +The operator found is either the first submatch (if it is not a +keyword) or the second submatch (if it is)." + t (if (c-lang-const c-type-decl-prefix-keywords-key) + (concat "\\(\\`a\\`\\)\\|" ; 1 - will never match. + (c-lang-const c-type-decl-prefix-keywords-key) ; 2 + "\\([^_]\\|$\\)") ; 3 + "\\`a\\`") ;; Default to a regexp that never matches. ;; Check that there's no "=" afterwards to avoid matching tokens ;; like "*=". - (c objc) (concat "\\(" + (c objc) (concat "\\(" ; 1 "[*(]" - "\\|" - (c-lang-const c-type-decl-prefix-key) - "\\)" - "\\([^=]\\|$\\)") - c++ (concat "\\(" + "\\)\\|" + (c-lang-const c-type-decl-prefix-keywords-key) ; 2 + "\\([^=_]\\|$\\)") ; 3 + c++ (concat "\\(" ; 1 "&&" "\\|" "\\.\\.\\." "\\|" "[*(&~]" + "\\)\\|\\(" ; 2 + (c-lang-const c-type-decl-prefix-keywords-key) ; 3 "\\|" - (c-lang-const c-type-decl-prefix-key) - "\\|" - (concat "\\(" ; 3 + (concat "\\(" ; 4 ;; If this matches there's special treatment in ;; `c-font-lock-declarators' and ;; `c-font-lock-declarations' that check for a @@ -3475,8 +3481,9 @@ Identifier syntax is in effect when this is matched (see (c-lang-const c-identifier-start) "\\)") "\\)" - "\\([^=]\\|$\\)") + "\\([^=_]\\|$\\)") ; 5 pike "\\(\\*\\)\\([^=]\\|$\\)") + (c-lang-defvar c-type-decl-prefix-key (c-lang-const c-type-decl-prefix-key) 'dont-doc) commit 04ab3904eddc01af918fb85b8712cd5d45238468 Author: Stefan Monnier Date: Tue Feb 2 14:39:28 2021 -0500 * lisp/gnus/gnus-art.el: Fix misuse of `standard-value`. * lisp/custom.el (custom--standard-value): New function. * lisp/gnus/gnus-art.el: (gnus-article-browse-html-parts) (gnus-article-browse-html-article): * lisp/dired-aux.el (dired-do-find-regexp-and-replace): * lisp/emacs-lisp/package-x.el (package-upload-buffer-internal): * lisp/startup.el (command-line): Use it. diff --git a/lisp/custom.el b/lisp/custom.el index 5e354c4c59..833810718b 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -350,7 +350,7 @@ for more information." ;; if you need to recompile all the Lisp files using interpreted code. `(custom-declare-variable ',symbol - ,(if lexical-binding ;FIXME: This is not reliable, but is all we have. + ,(if lexical-binding ;; The STANDARD arg should be an expression that evaluates to ;; the standard value. The use of `eval' for it is spread ;; over many different places and hence difficult to @@ -627,6 +627,10 @@ property, or (ii) an alias for another customizable variable." (or (get variable 'standard-value) (get variable 'custom-autoload)))) +(defun custom--standard-value (variable) + "Return the standard value of VARIABLE." + (eval (car (get variable 'standard-value)) t)) + (define-obsolete-function-alias 'user-variable-p 'custom-variable-p "24.3") (defun custom-note-var-changed (variable) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index ec864d54d6..a94bdf5b42 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -3148,7 +3148,7 @@ REGEXP should use constructs supported by your local `grep' command." (with-current-buffer (let ((xref-show-xrefs-function ;; Some future-proofing (bug#44905). - (eval (car (get 'xref-show-xrefs-function 'standard-value))))) + (custom--standard-value 'xref-show-xrefs-function))) (dired-do-find-regexp from)) (xref-query-replace-in-results from to))) diff --git a/lisp/emacs-lisp/package-x.el b/lisp/emacs-lisp/package-x.el index b723643ffb..2e327d16de 100644 --- a/lisp/emacs-lisp/package-x.el +++ b/lisp/emacs-lisp/package-x.el @@ -182,8 +182,7 @@ if it exists." ;; Check if `package-archive-upload-base' is valid. (when (or (not (stringp package-archive-upload-base)) (equal package-archive-upload-base - (car-safe - (get 'package-archive-upload-base 'standard-value)))) + (custom--standard-value 'package-archive-upload-base))) (setq package-archive-upload-base (read-directory-name "Base directory for package archive: "))) diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index 39b182f2cd..70ededf1ba 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -3010,8 +3010,7 @@ message header will be added to the bodies of the \"text/html\" parts." (when header (article-decode-encoded-words) (let ((gnus-visible-headers - (or (get 'gnus-visible-headers 'standard-value) - gnus-visible-headers))) + (custom--standard-value 'gnus-visible-headers))) (article-hide-headers)) (goto-char (point-min)) (search-forward "\n\n" nil 'move) @@ -3045,8 +3044,8 @@ images if any to the browser, and deletes them when exiting the group (interactive "P") (if arg (gnus-summary-show-article) - (let ((gnus-visible-headers (or (get 'gnus-visible-headers 'standard-value) - gnus-visible-headers)) + (let ((gnus-visible-headers + (custom--standard-value 'gnus-visible-headers)) (gnus-mime-display-attachment-buttons-in-header nil) ;; As we insert a
, there's no need for the body boundary. (gnus-treat-body-boundary nil)) diff --git a/lisp/startup.el b/lisp/startup.el index 60e1a200bb..b173d61973 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -1386,7 +1386,7 @@ please check its value") (equal user-mail-address (let (mail-host-address) (ignore-errors - (eval (car (get 'user-mail-address 'standard-value)))))) + (custom--standard-value 'user-mail-address)))) (custom-reevaluate-setting 'user-mail-address)) ;; If parameter have been changed in the init file which influence commit c2b3a1d41457a4edbf86673c2680541039b85d59 Author: Stefan Monnier Date: Tue Feb 2 14:12:17 2021 -0500 * lisp/gnus/gnus-group.el: Fix a regression due to lexical scoping (gnus-group-highlight): Improve docstring. (gnus-group-update-eval-form): Add `group` and `method` to the vars provided to `eval`. diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index 3661b6376d..e8b62a4133 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el @@ -367,13 +367,16 @@ requires an understanding of Lisp expressions. Hopefully this will change in a future release. For now, you can use the following variables in the Lisp expression: -group: The name of the group. -unread: The number of unread articles in the group. -method: The select method used. -mailp: Whether it's a mail group or not. -level: The level of the group. -score: The score of the group. -ticked: The number of ticked articles." +`group': The name of the group. +`unread': The number of unread articles in the group. +`method': The select method used. +`total': The total number of articles in the group. +`mailp': Whether it's a mail group or not. +`level': The level of the group. +`score': The score of the group. +`ticked': The number of ticked articles. +`group-age': Time in seconds since the group was last read + (see info node `(gnus)Group Timestamp')." :group 'gnus-group-visual :type '(repeat (cons (sexp :tag "Form") face))) (put 'gnus-group-highlight 'risky-local-variable t) @@ -401,16 +404,8 @@ file. It is also possible to change and add form fields, but currently that requires an understanding of Lisp expressions. Hopefully this will -change in a future release. For now, you can use the following -variables in the Lisp expression: - -group: The name of the group. -unread: The number of unread articles in the group. -method: The select method used. -mailp: Whether it's a mail group or not. -level: The level of the group. -score: The score of the group. -ticked: The number of ticked articles." +change in a future release. For now, you can use the same +variables in the Lisp expression as in `gnus-group-highlight'." :group 'gnus-group-icons :type '(repeat (cons (sexp :tag "Form") file))) (put 'gnus-group-icon-list 'risky-local-variable t) @@ -1624,7 +1619,9 @@ Some value are bound so the form can use them." (marked (gnus-info-marks info)) (env (list + (cons 'group group) (cons 'unread (if (numberp (car entry)) (car entry) 0)) + (cons 'method method) (cons 'total (if active (1+ (- (cdr active) (car active))) 0)) (cons 'mailp (apply #'append commit 7355209f53e1c7f383a1df8b5e294ec9f43ab82e Author: Eli Zaretskii Date: Tue Feb 2 18:25:31 2021 +0200 * lisp/window.el (recenter-top-bottom): Clarify doc string. diff --git a/lisp/window.el b/lisp/window.el index f388f86372..95db01bca4 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -9545,13 +9545,16 @@ cycling order is middle -> top -> bottom." :group 'windows) (defun recenter-top-bottom (&optional arg) - "Move current buffer line to the specified window line. -With no prefix argument, successive calls place point according -to the cycling order defined by `recenter-positions'. - -A prefix argument is handled like `recenter': - With numeric prefix ARG, move current line to window-line ARG. - With plain `C-u', move current line to window center." + "Scroll the window so that current line is in the middle of the window. +Successive invocations scroll the window in a cyclical order to put +the current line at certain places within the window, as determined by +`recenter-positions'. By default, the second invocation puts the +current line at the top-most window line, the third invocation puts it +on the bottom-most window line, and then the order is reused in a +cyclical manner. + +With numeric prefix ARG, move current line ARG lines below the window top. +With plain \\[universal-argument], move current line to window center." (interactive "P") (cond (arg (recenter arg t)) ; Always respect ARG. commit 97ef20e250126bbf2206f92864f87c85f1d3b6ec Author: Lars Ingebrigtsen Date: Tue Feb 2 16:11:13 2021 +0100 Handle errors in `comint-strip-ctrl-m' in some cases * lisp/comint.el (comint-strip-ctrl-m): Don't signal errors when used noninteractively (bug#33115). diff --git a/lisp/comint.el b/lisp/comint.el index 432307934a..a9633d08ba 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -2253,15 +2253,23 @@ This function could be on `comint-output-filter-functions' or bound to a key." "Strip trailing `^M' characters from the current output group. This function could be on `comint-output-filter-functions' or bound to a key." (interactive) - (let ((pmark (process-mark (get-buffer-process (current-buffer))))) - (save-excursion - (condition-case nil - (goto-char - (if (called-interactively-p 'interactive) - comint-last-input-end comint-last-output-start)) - (error nil)) - (while (re-search-forward "\r+$" pmark t) - (replace-match "" t t))))) + (let ((process (get-buffer-process (current-buffer)))) + (if (not process) + ;; This function may be used in + ;; `comint-output-filter-functions', and in that case, if + ;; there's no process, then we should do nothing. If + ;; interactive, report an error. + (when (called-interactively-p 'interactive) + (error "No process in the current buffer")) + (let ((pmark (process-mark process))) + (save-excursion + (condition-case nil + (goto-char + (if (called-interactively-p 'interactive) + comint-last-input-end comint-last-output-start)) + (error nil)) + (while (re-search-forward "\r+$" pmark t) + (replace-match "" t t))))))) (define-obsolete-function-alias 'shell-strip-ctrl-m #'comint-strip-ctrl-m "27.1") (defun comint-show-maximum-output () commit 5f612d8a1fd7336541a69f0d37bc69d5618f98d1 Author: Stefan Monnier Date: Tue Feb 2 10:08:44 2021 -0500 * lisp/emacs-lisp/lisp-mode.el (lisp-mode): Also set `comment-end-skip` diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 398cb76ac7..5dda3a8f8e 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -775,6 +775,7 @@ or to switch back to an existing one." (setq-local find-tag-default-function 'lisp-find-tag-default) (setq-local comment-start-skip "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *") + (setq-local comment-end-skip "[ \t]*\\(\\s>\\||#\\)") (setq-local font-lock-comment-end-skip "|#") (setq imenu-case-fold-search t)) commit a2de694d8aa144ba1261a3c9a488d76f7cfa6728 Author: chuntaro Date: Tue Feb 2 10:18:28 2021 +0100 Fix |# fontification in lisp-mode * lisp/emacs-lisp/lisp-mode.el (lisp-mode): Give the |# the correct (font-lock-comment-delimited-face) face (bug#39820). Copyright-paperwork-exempt: yes diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index c96d849d44..398cb76ac7 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -775,6 +775,7 @@ or to switch back to an existing one." (setq-local find-tag-default-function 'lisp-find-tag-default) (setq-local comment-start-skip "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *") + (setq-local font-lock-comment-end-skip "|#") (setq imenu-case-fold-search t)) (defun lisp-find-tag-default () commit a35b796c991232146a504f375112c2a6353b84a4 Author: Lars Ingebrigtsen Date: Tue Feb 2 10:10:39 2021 +0100 Have `dired-mode' refer to Customize instead of listing some variables * lisp/dired.el (dired-mode): Punt to Customize instead of listing some of the dired variables (bug#46239). diff --git a/lisp/dired.el b/lisp/dired.el index fe6ac1e259..553fb64da0 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -2332,19 +2332,9 @@ to relist the file at point or the marked files or a subdirectory, or type \\[dired-build-subdir-alist] to parse the buffer again for the directory tree. -Customization variables (rename this buffer and type \\[describe-variable] on each line -for more info): - - `dired-listing-switches' - `dired-trivial-filenames' - `dired-marker-char' - `dired-del-marker' - `dired-keep-marker-rename' - `dired-keep-marker-copy' - `dired-keep-marker-hardlink' - `dired-keep-marker-symlink' - -Hooks (use \\[describe-variable] to see their documentation): +See the `dired' customization group for a list of user options. + +This mode runs the following hooks: `dired-before-readin-hook' `dired-after-readin-hook' commit e0fc879c0c2185bb5858dc64eabf19ee267beac3 Author: Stefan Kangas Date: Tue Feb 2 09:55:40 2021 +0100 Prefer defvar-local in remaining libraries * lisp/align.el (align-mode-rules-list) (align-mode-exclude-rules-list): * lisp/bookmark.el (bookmark-current-bookmark) (bookmark-annotation-name) (bookmark--annotation-from-bookmark-list): * lisp/calc/calc-embed.el (calc-embedded-all-active) (calc-embedded-some-active): * lisp/comint.el (comint-password-function): * lisp/completion.el (completion-syntax-table): * lisp/dframe.el (dframe-track-mouse-function) (dframe-help-echo-function, dframe-mouse-click-function) (dframe-mouse-position-function, dframe-timer) (dframe-attached-frame, dframe-controlled): * lisp/ehelp.el (electric-help-orig-major-mode): * lisp/eshell/esh-util.el (eshell-path-env): * lisp/expand.el (expand-pos, expand-index, expand-point): * lisp/face-remap.el (text-scale-mode-remapping) (text-scale-mode-lighter, text-scale-mode-amount) (text-scale-remap-header-line, buffer-face-mode-remapping): * lisp/ffap.el (ffap-menu-alist): * lisp/files-x.el (connection-local-variables-alist): * lisp/foldout.el (foldout-fold-list, foldout-mode-line-string): * lisp/follow.el (follow-start-end-invalid): * lisp/forms.el (forms--mode-setup): * lisp/gnus/message.el (message-cross-post-old-target) (message-options): * lisp/help-mode.el (help-xref-stack, help-xref-forward-stack) (help-xref-stack-item, help-xref-stack-forward-item): * lisp/hexl.el (hexl-mode--old-var-vals, hexl-ascii-overlay): * lisp/hilit-chg.el (hilit-chg-string): * lisp/ido.el (ido-eoinput): * lisp/imenu.el (imenu-generic-expression) (imenu-create-index-function, imenu-default-goto-function) (imenu-prev-index-position-function) (imenu-extract-index-name-function, imenu-name-lookup-function) (imenu-syntax-alist, imenu-case-fold-search): * lisp/jka-compr.el (jka-compr-really-do-compress): * lisp/language/ethio-util.el (ethio-prefer-ascii-space): * lisp/leim/quail/hangul.el (hangul-input-method-help-text): * lisp/leim/quail/japanese.el (quail-japanese-package-saved): * lisp/linum.el (linum-overlays, linum-available): * lisp/man.el (Man-original-frame, Man-arguments, Man--sections) (Man--refpages, Man-page-list, Man-current-page) (Man-page-mode-string): * lisp/pcomplete.el (pcomplete-current-completions) (pcomplete-last-completion-length) (pcomplete-last-completion-stub, pcomplete-last-completion-raw) (pcomplete-last-window-config, pcomplete-window-restore-timer): * lisp/reveal.el (reveal-open-spots, reveal-last-tick): * lisp/ruler-mode.el (ruler-mode): * lisp/scroll-lock.el (scroll-lock-preserve-screen-pos-save): * lisp/server.el (server-buffer-clients, server-existing-buffer): * lisp/tab-line.el (tab-line-exclude): * lisp/tar-mode.el (tar-data-buffer, tar-data-swapped): * lisp/thumbs.el (thumbs-current-tmp-filename) (thumbs-current-image-filename, thumbs-extra-images) (thumbs-image-num, thumbs-buffer, thumbs-marked-list): * lisp/tutorial.el (tutorial--point-before-chkeys) (tutorial--point-after-chkeys, tutorial--lang): * lisp/url/url-vars.el (url-current-object) (url-current-mime-headers, url-current-lastloc): * lisp/view.el (view-mode, view-old-buffer-read-only) (view-old-Helper-return-blurb, view-page-size) (view-half-page-size, view-last-regexp, view-return-to-alist) (view-exit-action, view-overlay): * lisp/wid-edit.el (widget-global-map, widget-field-new) (widget-field-list, widget-field-last, widget-field-was): * lisp/woman.el (woman-imenu-done): Prefer defvar-local. diff --git a/lisp/align.el b/lisp/align.el index 1318b735c0..4d78393115 100644 --- a/lisp/align.el +++ b/lisp/align.el @@ -775,18 +775,14 @@ See the documentation for `align-rules-list' for more info." ;;; Internal Variables: -(defvar align-mode-rules-list nil +(defvar-local align-mode-rules-list nil "Alignment rules specific to the current major mode. See the variable `align-rules-list' for more details.") -(make-variable-buffer-local 'align-mode-rules-list) - -(defvar align-mode-exclude-rules-list nil +(defvar-local align-mode-exclude-rules-list nil "Alignment exclusion rules specific to the current major mode. See the variable `align-exclude-rules-list' for more details.") -(make-variable-buffer-local 'align-mode-exclude-rules-list) - (defvar align-highlight-overlays nil "The current overlays highlighting the text matched by a rule.") diff --git a/lisp/bookmark.el b/lisp/bookmark.el index c857c9ba7f..dcf8ff0d0a 100644 --- a/lisp/bookmark.el +++ b/lisp/bookmark.el @@ -271,13 +271,11 @@ defaults to `bookmark-default-file' and MODTIME is its modification time.") (defvar bookmark-file-coding-system nil "The coding-system of the last loaded or saved bookmark file.") -(defvar bookmark-current-bookmark nil +(defvar-local bookmark-current-bookmark nil "Name of bookmark most recently used in the current file. It is buffer local, used to make moving a bookmark forward through a file easier.") -(make-variable-buffer-local 'bookmark-current-bookmark) - (defvar bookmark-alist-modification-count 0 "Number of modifications to bookmark list since it was last saved.") @@ -903,13 +901,11 @@ Does not affect the kill ring." (when (and newline-too (= (following-char) ?\n)) (delete-char 1)))) -(defvar bookmark-annotation-name nil +(defvar-local bookmark-annotation-name nil "Name of bookmark under edit in `bookmark-edit-annotation-mode'.") -(make-variable-buffer-local 'bookmark-annotation-name) -(defvar bookmark--annotation-from-bookmark-list nil +(defvar-local bookmark--annotation-from-bookmark-list nil "If non-nil, `bookmark-edit-annotation-mode' should return to bookmark list.") -(make-variable-buffer-local 'bookmark--annotation-from-bookmark-list) (defun bookmark-default-annotation-text (bookmark-name) "Return default annotation text for BOOKMARK-NAME. diff --git a/lisp/calc/calc-embed.el b/lisp/calc/calc-embed.el index fda0b4bbed..cfb3fda106 100644 --- a/lisp/calc/calc-embed.el +++ b/lisp/calc/calc-embed.el @@ -46,10 +46,8 @@ (defvar calc-embedded-modes nil) (defvar calc-embedded-globals nil) (defvar calc-embedded-active nil) -(defvar calc-embedded-all-active nil) -(make-variable-buffer-local 'calc-embedded-all-active) -(defvar calc-embedded-some-active nil) -(make-variable-buffer-local 'calc-embedded-some-active) +(defvar-local calc-embedded-all-active nil) +(defvar-local calc-embedded-some-active nil) ;; The following variables are customizable and defined in calc.el. (defvar calc-embedded-announce-formula) diff --git a/lisp/comint.el b/lisp/comint.el index e52d67d0e5..432307934a 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -2375,12 +2375,11 @@ a buffer local variable." ;; saved -- typically passwords to ftp, telnet, or somesuch. ;; Just enter m-x comint-send-invisible and type in your line. -(defvar comint-password-function nil +(defvar-local comint-password-function nil "Abnormal hook run when prompted for a password. This function gets one argument, a string containing the prompt. It may return a string containing the password, or nil if normal password prompting should occur.") -(make-variable-buffer-local 'comint-password-function) (defun comint-send-invisible (&optional prompt) "Read a string without echoing. diff --git a/lisp/completion.el b/lisp/completion.el index 8810a22d26..da2fb38feb 100644 --- a/lisp/completion.el +++ b/lisp/completion.el @@ -505,9 +505,8 @@ Used to decide whether to save completions.") ;; Old name, non-namespace-clean. (defvaralias 'cmpl-syntax-table 'completion-syntax-table) -(defvar completion-syntax-table completion-standard-syntax-table +(defvar-local completion-syntax-table completion-standard-syntax-table "This variable holds the current completion syntax table.") -(make-variable-buffer-local 'completion-syntax-table) ;;----------------------------------------------- ;; Symbol functions diff --git a/lisp/dframe.el b/lisp/dframe.el index 7ea5b3364e..e61d2ea058 100644 --- a/lisp/dframe.el +++ b/lisp/dframe.el @@ -146,42 +146,35 @@ selected frame and the focus will change to that frame." :group 'dframe :type 'hook) -(defvar dframe-track-mouse-function nil +(defvar-local dframe-track-mouse-function nil "A function to call when the mouse is moved in the given frame. Typically used to display info about the line under the mouse.") -(make-variable-buffer-local 'dframe-track-mouse-function) -(defvar dframe-help-echo-function nil +(defvar-local dframe-help-echo-function nil "A function to call when help-echo is used in newer versions of Emacs. Typically used to display info about the line under the mouse.") -(make-variable-buffer-local 'dframe-help-echo-function) -(defvar dframe-mouse-click-function nil +(defvar-local dframe-mouse-click-function nil "A function to call when the mouse is clicked. Valid clicks are mouse 2, our double mouse 1.") -(make-variable-buffer-local 'dframe-mouse-click-function) -(defvar dframe-mouse-position-function nil +(defvar-local dframe-mouse-position-function nil "A function to call to position the cursor for a mouse click.") -(make-variable-buffer-local 'dframe-mouse-position-function) (defvar dframe-power-click nil "Never set this by hand. Value is t when S-mouse activity occurs.") -(defvar dframe-timer nil +(defvar-local dframe-timer nil "The dframe timer used for updating the buffer.") -(make-variable-buffer-local 'dframe-timer) -(defvar dframe-attached-frame nil +(defvar-local dframe-attached-frame nil "The frame which started a frame mode. This is the frame from which all interesting activities will go for the mode using dframe.") -(make-variable-buffer-local 'dframe-attached-frame) -(defvar dframe-controlled nil +(defvar-local dframe-controlled nil "Is this buffer controlled by a dedicated frame. Local to those buffers, as a function called that created it.") -(make-variable-buffer-local 'dframe-controlled) (defun dframe-update-keymap (map) "Update the keymap MAP for dframe default bindings." diff --git a/lisp/ehelp.el b/lisp/ehelp.el index 996b7db48f..aa809d6f6f 100644 --- a/lisp/ehelp.el +++ b/lisp/ehelp.el @@ -95,8 +95,7 @@ map) "Keymap defining commands available in `electric-help-mode'.") -(defvar electric-help-orig-major-mode nil) -(make-variable-buffer-local 'electric-help-orig-major-mode) +(defvar-local electric-help-orig-major-mode nil) (defun electric-help-mode () "`with-electric-help' temporarily places its buffer in this mode. diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el index 0b5cf193a1..8ef1ac9c34 100644 --- a/lisp/eshell/esh-util.el +++ b/lisp/eshell/esh-util.el @@ -235,11 +235,10 @@ If N or M is nil, it means the end of the list." a (last a))) a)) -(defvar eshell-path-env (getenv "PATH") +(defvar-local eshell-path-env (getenv "PATH") "Content of $PATH. It might be different from \(getenv \"PATH\"), when `default-directory' points to a remote host.") -(make-variable-buffer-local 'eshell-path-env) (defun eshell-get-path () "Return $PATH as a list. diff --git a/lisp/expand.el b/lisp/expand.el index 5c0b5f4281..9df8d9f15a 100644 --- a/lisp/expand.el +++ b/lisp/expand.el @@ -289,17 +289,14 @@ If ARG is omitted, point is placed at the end of the expanded text." (defvar expand-list nil "Temporary variable used by the Expand package.") -(defvar expand-pos nil +(defvar-local expand-pos nil "If non-nil, store a vector with position markers defined by the last expansion.") -(make-variable-buffer-local 'expand-pos) -(defvar expand-index 0 +(defvar-local expand-index 0 "Index of the last marker used in `expand-pos'.") -(make-variable-buffer-local 'expand-index) -(defvar expand-point nil +(defvar-local expand-point nil "End of the expanded region.") -(make-variable-buffer-local 'expand-point) (defun expand-add-abbrev (table abbrev expansion arg) "Add one abbreviation and provide the hook to move to the specified positions." diff --git a/lisp/face-remap.el b/lisp/face-remap.el index c53b20f333..7fbf0c42be 100644 --- a/lisp/face-remap.el +++ b/lisp/face-remap.el @@ -217,21 +217,17 @@ Each positive or negative step scales the default face height by this amount." :type 'number :version "23.1") -;; current remapping cookie for text-scale-mode -(defvar text-scale-mode-remapping nil) -(make-variable-buffer-local 'text-scale-mode-remapping) +(defvar-local text-scale-mode-remapping nil + "Current remapping cookie for text-scale-mode.") -;; Lighter displayed for text-scale-mode in mode-line minor-mode list -(defvar text-scale-mode-lighter "+0") -(make-variable-buffer-local 'text-scale-mode-lighter) +(defvar-local text-scale-mode-lighter "+0" + "Lighter displayed for text-scale-mode in mode-line minor-mode list.") -;; Number of steps that text-scale-mode will increase/decrease text height -(defvar text-scale-mode-amount 0) -(make-variable-buffer-local 'text-scale-mode-amount) +(defvar-local text-scale-mode-amount 0 + "Number of steps that text-scale-mode will increase/decrease text height.") -(defvar text-scale-remap-header-line nil +(defvar-local text-scale-remap-header-line nil "If non-nil, text scaling may change font size of header lines too.") -(make-variable-buffer-local 'text-scale-header-line) (defun face-remap--clear-remappings () (dolist (remapping @@ -413,8 +409,7 @@ plist, etc." :version "23.1") ;; current remapping cookie for buffer-face-mode -(defvar buffer-face-mode-remapping nil) -(make-variable-buffer-local 'buffer-face-mode-remapping) +(defvar-local buffer-face-mode-remapping nil) ;;;###autoload (define-minor-mode buffer-face-mode diff --git a/lisp/ffap.el b/lisp/ffap.el index 1f43bafdb9..6faf8d50b2 100644 --- a/lisp/ffap.el +++ b/lisp/ffap.el @@ -1675,9 +1675,8 @@ For example, try \":/\" for URL (and some FTP) references." :type '(choice (const nil) regexp) :group 'ffap) -(defvar ffap-menu-alist nil +(defvar-local ffap-menu-alist nil "Buffer local cache of menu presented by `ffap-menu'.") -(make-variable-buffer-local 'ffap-menu-alist) (defvar ffap-menu-text-plist (cond diff --git a/lisp/files-x.el b/lisp/files-x.el index 628bf18092..526a128623 100644 --- a/lisp/files-x.el +++ b/lisp/files-x.el @@ -570,13 +570,12 @@ from the MODE alist ignoring the input argument VALUE." (defvar enable-connection-local-variables t "Non-nil means enable use of connection-local variables.") -(defvar connection-local-variables-alist nil +(defvar-local connection-local-variables-alist nil "Alist of connection-local variable settings in the current buffer. Each element in this list has the form (VAR . VALUE), where VAR is a connection-local variable (a symbol) and VALUE is its value. The actual value in the buffer may differ from VALUE, if it is changed by the user.") -(make-variable-buffer-local 'connection-local-variables-alist) (setq ignored-local-variables (cons 'connection-local-variables-alist ignored-local-variables)) diff --git a/lisp/foldout.el b/lisp/foldout.el index 4c479d68e9..2de49d2839 100644 --- a/lisp/foldout.el +++ b/lisp/foldout.el @@ -209,14 +209,12 @@ (require 'outline) -(defvar foldout-fold-list nil +(defvar-local foldout-fold-list nil "List of start and end markers for the folds currently entered. An end marker of nil means the fold ends after (point-max).") -(make-variable-buffer-local 'foldout-fold-list) -(defvar foldout-mode-line-string nil +(defvar-local foldout-mode-line-string nil "Mode line string announcing that we are in an outline fold.") -(make-variable-buffer-local 'foldout-mode-line-string) ;; put our minor mode string immediately following outline-minor-mode's (or (assq 'foldout-mode-line-string minor-mode-alist) diff --git a/lisp/follow.el b/lisp/follow.el index 292dc4a022..069758747c 100644 --- a/lisp/follow.el +++ b/lisp/follow.el @@ -1140,9 +1140,8 @@ Otherwise, return nil." ;; is nil. Start every window directly after the end of the previous ;; window, to make sure long lines are displayed correctly. -(defvar follow-start-end-invalid t +(defvar-local follow-start-end-invalid t "When non-nil, indicates `follow-windows-start-end-cache' is invalid.") -(make-variable-buffer-local 'follow-start-end-invalid) (defun follow-redisplay (&optional windows win preserve-win) "Reposition the WINDOWS around WIN. diff --git a/lisp/forms.el b/lisp/forms.el index 5d7e6dde96..62c4288869 100644 --- a/lisp/forms.el +++ b/lisp/forms.el @@ -418,9 +418,8 @@ Also, initial position is at last record." (defvar forms--parser nil "Forms parser routine.") -(defvar forms--mode-setup nil +(defvar-local forms--mode-setup nil "To keep track of forms-mode being set-up.") -(make-variable-buffer-local 'forms--mode-setup) (defvar forms--dynamic-text nil "Array that holds dynamic texts to insert between fields.") diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index d2a0092fde..6668784f93 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -394,9 +394,8 @@ If nil, don't insert any text in the body." ;; inspired by JoH-followup-to by Jochem Huhman ;; new suggestions by R. Weikusat -(defvar message-cross-post-old-target nil +(defvar-local message-cross-post-old-target nil "Old target for cross-posts or follow-ups.") -(make-variable-buffer-local 'message-cross-post-old-target) (defcustom message-cross-post-default t "When non-nil `message-cross-post-followup-to' will perform a crosspost. @@ -2004,9 +2003,8 @@ You must have the \"hashcash\" binary installed, see `hashcash-path'." (User-Agent)) "Alist used for formatting headers.") -(defvar message-options nil +(defvar-local message-options nil "Some saved answers when sending message.") -(make-variable-buffer-local 'message-options) (defvar message-send-mail-real-function nil "Internal send mail function.") diff --git a/lisp/help-mode.el b/lisp/help-mode.el index 7043f12c9a..79710a1807 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -62,33 +62,29 @@ ["Move to Next Button" forward-button :help "Move to the Next Button in the help buffer"])) -(defvar help-xref-stack nil +(defvar-local help-xref-stack nil "A stack of ways by which to return to help buffers after following xrefs. Used by `help-follow' and `help-xref-go-back'. An element looks like (POSITION FUNCTION ARGS...). To use the element, do (apply FUNCTION ARGS) then goto the point.") (put 'help-xref-stack 'permanent-local t) -(make-variable-buffer-local 'help-xref-stack) -(defvar help-xref-forward-stack nil +(defvar-local help-xref-forward-stack nil "A stack used to navigate help forwards after using the back button. Used by `help-follow' and `help-xref-go-forward'. An element looks like (POSITION FUNCTION ARGS...). To use the element, do (apply FUNCTION ARGS) then goto the point.") (put 'help-xref-forward-stack 'permanent-local t) -(make-variable-buffer-local 'help-xref-forward-stack) -(defvar help-xref-stack-item nil +(defvar-local help-xref-stack-item nil "An item for `help-follow' in this buffer to push onto `help-xref-stack'. The format is (FUNCTION ARGS...).") (put 'help-xref-stack-item 'permanent-local t) -(make-variable-buffer-local 'help-xref-stack-item) -(defvar help-xref-stack-forward-item nil +(defvar-local help-xref-stack-forward-item nil "An item for `help-go-back' to push onto `help-xref-forward-stack'. The format is (FUNCTION ARGS...).") (put 'help-xref-stack-forward-item 'permanent-local t) -(make-variable-buffer-local 'help-xref-stack-forward-item) (setq-default help-xref-stack nil help-xref-stack-item nil) (setq-default help-xref-forward-stack nil help-xref-forward-stack-item nil) diff --git a/lisp/hexl.el b/lisp/hexl.el index 8d3cfe6de4..85c3a53413 100644 --- a/lisp/hexl.el +++ b/lisp/hexl.el @@ -209,12 +209,10 @@ as that will override any bit grouping options set here." (defvar hl-line-face) ;; Variables where the original values are stored to. -(defvar hexl-mode--old-var-vals ()) -(make-variable-buffer-local 'hexl-mode--old-var-vals) +(defvar-local hexl-mode--old-var-vals ()) -(defvar hexl-ascii-overlay nil +(defvar-local hexl-ascii-overlay nil "Overlay used to highlight ASCII element corresponding to current point.") -(make-variable-buffer-local 'hexl-ascii-overlay) (defvar hexl-font-lock-keywords '(("^\\([0-9a-f]+:\\)\\( \\).\\{39\\}\\( \\)\\(.+$\\)" diff --git a/lisp/hilit-chg.el b/lisp/hilit-chg.el index fb33cd92e3..89a1a9108c 100644 --- a/lisp/hilit-chg.el +++ b/lisp/hilit-chg.el @@ -296,9 +296,7 @@ remove it from existing buffers." ;; These are for internal use. (defvar hilit-chg-list nil) -(defvar hilit-chg-string " ??") - -(make-variable-buffer-local 'hilit-chg-string) +(defvar-local hilit-chg-string " ??") diff --git a/lisp/ido.el b/lisp/ido.el index 89b6a62f5a..3ed0d952f3 100644 --- a/lisp/ido.el +++ b/lisp/ido.el @@ -1037,10 +1037,9 @@ Should never be set permanently.") (defvar ido-completion-map nil "Currently active keymap for Ido commands.") -(defvar ido-eoinput 1 +(defvar-local ido-eoinput 1 "Point where minibuffer input ends and completion info begins. Copied from `icomplete-eoinput'.") -(make-variable-buffer-local 'ido-eoinput) (defvar ido-common-match-string nil "Stores the string that is common to all matching files.") diff --git a/lisp/imenu.el b/lisp/imenu.el index b5cd18a689..2a557e0453 100644 --- a/lisp/imenu.el +++ b/lisp/imenu.el @@ -187,7 +187,7 @@ uses `imenu--generic-function')." :version "24.4") ;;;###autoload -(defvar imenu-generic-expression nil +(defvar-local imenu-generic-expression nil "List of definition matchers for creating an Imenu index. Each element of this list should have the form @@ -223,13 +223,10 @@ characters which normally have \"symbol\" syntax are considered to have \"word\" syntax during matching.") ;;;###autoload(put 'imenu-generic-expression 'risky-local-variable t) -;;;###autoload -(make-variable-buffer-local 'imenu-generic-expression) - ;;;; Hooks ;;;###autoload -(defvar imenu-create-index-function 'imenu-default-create-index-function +(defvar-local imenu-create-index-function 'imenu-default-create-index-function "The function to use for creating an index alist of the current buffer. It should be a function that takes no arguments and returns @@ -237,11 +234,9 @@ an index alist of the current buffer. The function is called within a `save-excursion'. See `imenu--index-alist' for the format of the buffer index alist.") -;;;###autoload -(make-variable-buffer-local 'imenu-create-index-function) ;;;###autoload -(defvar imenu-prev-index-position-function 'beginning-of-defun +(defvar-local imenu-prev-index-position-function 'beginning-of-defun "Function for finding the next index position. If `imenu-create-index-function' is set to @@ -251,21 +246,17 @@ file. The function should leave point at the place to be connected to the index and it should return nil when it doesn't find another index.") -;;;###autoload -(make-variable-buffer-local 'imenu-prev-index-position-function) ;;;###autoload -(defvar imenu-extract-index-name-function nil +(defvar-local imenu-extract-index-name-function nil "Function for extracting the index item name, given a position. This function is called after `imenu-prev-index-position-function' finds a position for an index item, with point at that position. It should return the name for that index item.") -;;;###autoload -(make-variable-buffer-local 'imenu-extract-index-name-function) ;;;###autoload -(defvar imenu-name-lookup-function nil +(defvar-local imenu-name-lookup-function nil "Function to compare string with index item. This function will be called with two strings, and should return @@ -275,15 +266,11 @@ If nil, comparison is done with `string='. Set this to some other function for more advanced comparisons, such as \"begins with\" or \"name matches and number of arguments match\".") -;;;###autoload -(make-variable-buffer-local 'imenu-name-lookup-function) ;;;###autoload -(defvar imenu-default-goto-function 'imenu-default-goto-function +(defvar-local imenu-default-goto-function 'imenu-default-goto-function "The default function called when selecting an Imenu item. The function in this variable is called when selecting a normal index-item.") -;;;###autoload -(make-variable-buffer-local 'imenu-default-goto-function) (defun imenu--subalist-p (item) @@ -554,7 +541,8 @@ Non-nil arguments are in recursive calls." (setq alist nil res elt)))) res)) -(defvar imenu-syntax-alist nil +;;;###autoload +(defvar-local imenu-syntax-alist nil "Alist of syntax table modifiers to use while in `imenu--generic-function'. The car of the assocs may be either a character or a string and the @@ -564,8 +552,6 @@ a string, all the characters in the string get the specified syntax. This is typically used to give word syntax to characters which normally have symbol syntax to simplify `imenu-expression' and speed-up matching.") -;;;###autoload -(make-variable-buffer-local 'imenu-syntax-alist) (defun imenu-default-create-index-function () "Default function to create an index alist of the current buffer. @@ -607,14 +593,13 @@ The alternate method, which is the one most often used, is to call ;;; Generic index gathering function. ;;; -(defvar imenu-case-fold-search t +;;;###autoload +(defvar-local imenu-case-fold-search t "Defines whether `imenu--generic-function' should fold case when matching. This variable should be set (only) by initialization code for modes which use `imenu--generic-function'. If it is not set, but `font-lock-defaults' is set, then font-lock's setting is used.") -;;;###autoload -(make-variable-buffer-local 'imenu-case-fold-search) ;; This function can be called with quitting disabled, ;; so it needs to be careful never to loop! diff --git a/lisp/jka-compr.el b/lisp/jka-compr.el index 877f2eb825..8aebcd0ec4 100644 --- a/lisp/jka-compr.el +++ b/lisp/jka-compr.el @@ -101,11 +101,10 @@ NOTE: Not used in MS-DOS and Windows systems." (defvar jka-compr-use-shell (not (memq system-type '(ms-dos windows-nt)))) -(defvar jka-compr-really-do-compress nil +(defvar-local jka-compr-really-do-compress nil "Non-nil in a buffer whose visited file was uncompressed on visiting it. This means compress the data on writing the file, even if the data appears to be compressed already.") -(make-variable-buffer-local 'jka-compr-really-do-compress) (put 'jka-compr-really-do-compress 'permanent-local t) diff --git a/lisp/language/ethio-util.el b/lisp/language/ethio-util.el index 9b5fdf24d2..fa31cd5f9f 100644 --- a/lisp/language/ethio-util.el +++ b/lisp/language/ethio-util.el @@ -972,8 +972,7 @@ Otherwise, [0-9A-F]." ;; Ethiopic word separator vs. ASCII space ;; -(defvar ethio-prefer-ascii-space t) -(make-variable-buffer-local 'ethio-prefer-ascii-space) +(defvar-local ethio-prefer-ascii-space t) (defun ethio-toggle-space nil "Toggle ASCII space and Ethiopic separator for keyboard input." diff --git a/lisp/leim/quail/hangul.el b/lisp/leim/quail/hangul.el index 20762d36f0..ca1aae77be 100644 --- a/lisp/leim/quail/hangul.el +++ b/lisp/leim/quail/hangul.el @@ -511,8 +511,7 @@ When a Korean input method is off, convert the following hangul character." ;; Text shown by describe-input-method. Set to a proper text by ;; hangul-input-method-activate. -(defvar hangul-input-method-help-text nil) -(make-variable-buffer-local 'hangul-input-method-help-text) +(defvar-local hangul-input-method-help-text nil) ;;;###autoload (defun hangul-input-method-activate (input-method func help-text &rest args) diff --git a/lisp/leim/quail/japanese.el b/lisp/leim/quail/japanese.el index d7249d286f..a4ea550c26 100644 --- a/lisp/leim/quail/japanese.el +++ b/lisp/leim/quail/japanese.el @@ -113,8 +113,7 @@ (?h . "japanese") (?q . ("japanese-ascii")))) -(defvar quail-japanese-package-saved nil) -(make-variable-buffer-local 'quail-japanese-package-saved) +(defvar-local quail-japanese-package-saved nil) (put 'quail-japanese-package-saved 'permanent-local t) (defun quail-japanese-switch-package (key idx) diff --git a/lisp/linum.el b/lisp/linum.el index 824f016271..f9761d22c6 100644 --- a/lisp/linum.el +++ b/lisp/linum.el @@ -34,13 +34,11 @@ (defconst linum-version "0.9x") (make-obsolete-variable 'linum-version nil "28.1") -(defvar linum-overlays nil "Overlays used in this buffer.") -(defvar linum-available nil "Overlays available for reuse.") +(defvar-local linum-overlays nil "Overlays used in this buffer.") +(defvar-local linum-available nil "Overlays available for reuse.") (defvar linum-before-numbering-hook nil "Functions run in each buffer before line numbering starts.") -(mapc #'make-variable-buffer-local '(linum-overlays linum-available)) - (defgroup linum nil "Show line numbers in the left margin." :group 'convenience) diff --git a/lisp/man.el b/lisp/man.el index ca50b3a2fa..eb383a8439 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -399,22 +399,15 @@ Otherwise, the value is whatever the function ;; other variables and keymap initializations -(defvar Man-original-frame) -(make-variable-buffer-local 'Man-original-frame) -(defvar Man-arguments) -(make-variable-buffer-local 'Man-arguments) +(defvar-local Man-original-frame nil) +(defvar-local Man-arguments nil) (put 'Man-arguments 'permanent-local t) -(defvar Man--sections nil) -(make-variable-buffer-local 'Man--sections) -(defvar Man--refpages nil) -(make-variable-buffer-local 'Man--refpages) -(defvar Man-page-list nil) -(make-variable-buffer-local 'Man-page-list) -(defvar Man-current-page 0) -(make-variable-buffer-local 'Man-current-page) -(defvar Man-page-mode-string "1 of 1") -(make-variable-buffer-local 'Man-page-mode-string) +(defvar-local Man--sections nil) +(defvar-local Man--refpages nil) +(defvar-local Man-page-list nil) +(defvar-local Man-current-page 0) +(defvar-local Man-page-mode-string "1 of 1") (defconst Man-sysv-sed-script "\ /\b/ { s/_\b//g diff --git a/lisp/pcomplete.el b/lisp/pcomplete.el index 0dd99cec66..7effb27af7 100644 --- a/lisp/pcomplete.el +++ b/lisp/pcomplete.el @@ -330,19 +330,12 @@ modified to be an empty string, or the desired separation string." ;;; Internal Variables: ;; for cycling completion support -(defvar pcomplete-current-completions nil) -(defvar pcomplete-last-completion-length) -(defvar pcomplete-last-completion-stub) -(defvar pcomplete-last-completion-raw) -(defvar pcomplete-last-window-config nil) -(defvar pcomplete-window-restore-timer nil) - -(make-variable-buffer-local 'pcomplete-current-completions) -(make-variable-buffer-local 'pcomplete-last-completion-length) -(make-variable-buffer-local 'pcomplete-last-completion-stub) -(make-variable-buffer-local 'pcomplete-last-completion-raw) -(make-variable-buffer-local 'pcomplete-last-window-config) -(make-variable-buffer-local 'pcomplete-window-restore-timer) +(defvar-local pcomplete-current-completions nil) +(defvar-local pcomplete-last-completion-length nil) +(defvar-local pcomplete-last-completion-stub nil) +(defvar-local pcomplete-last-completion-raw nil) +(defvar-local pcomplete-last-window-config nil) +(defvar-local pcomplete-window-restore-timer nil) ;; used for altering pcomplete's behavior. These global variables ;; should always be nil. diff --git a/lisp/reveal.el b/lisp/reveal.el index c01afd9739..697df45c5c 100644 --- a/lisp/reveal.el +++ b/lisp/reveal.el @@ -67,13 +67,11 @@ revealed text manually." :type 'boolean :version "28.1") -(defvar reveal-open-spots nil +(defvar-local reveal-open-spots nil "List of spots in the buffer which are open. Each element has the form (WINDOW . OVERLAY).") -(make-variable-buffer-local 'reveal-open-spots) -(defvar reveal-last-tick nil) -(make-variable-buffer-local 'reveal-last-tick) +(defvar-local reveal-last-tick nil) ;; Actual code diff --git a/lisp/ruler-mode.el b/lisp/ruler-mode.el index 1e81904419..38283a5c56 100644 --- a/lisp/ruler-mode.el +++ b/lisp/ruler-mode.el @@ -572,10 +572,9 @@ This variable is expected to be made buffer-local by modes.") Call `ruler-mode-ruler-function' to compute the ruler value.") ;;;###autoload -(defvar ruler-mode nil +(defvar-local ruler-mode nil "Non-nil if Ruler mode is enabled. Use the command `ruler-mode' to change this variable.") -(make-variable-buffer-local 'ruler-mode) (defun ruler--save-header-line-format () "Install the header line format for Ruler mode. diff --git a/lisp/scroll-lock.el b/lisp/scroll-lock.el index e8f69b2956..d283b8089c 100644 --- a/lisp/scroll-lock.el +++ b/lisp/scroll-lock.el @@ -40,9 +40,8 @@ map) "Keymap for Scroll Lock mode.") -(defvar scroll-lock-preserve-screen-pos-save scroll-preserve-screen-position +(defvar-local scroll-lock-preserve-screen-pos-save scroll-preserve-screen-position "Used for saving the state of `scroll-preserve-screen-position'.") -(make-variable-buffer-local 'scroll-lock-preserve-screen-pos-save) (defvar scroll-lock-temporary-goal-column 0 "Like `temporary-goal-column' but for scroll-lock-* commands.") diff --git a/lisp/server.el b/lisp/server.el index b82e301d0a..220694f6cb 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -197,9 +197,8 @@ The created frame is selected when the hook is called." "List of current server clients. Each element is a process.") -(defvar server-buffer-clients nil +(defvar-local server-buffer-clients nil "List of client processes requesting editing of current buffer.") -(make-variable-buffer-local 'server-buffer-clients) ;; Changing major modes should not erase this local. (put 'server-buffer-clients 'permanent-local t) @@ -239,11 +238,10 @@ in this way." :type 'boolean :version "21.1") -(defvar server-existing-buffer nil +(defvar-local server-existing-buffer nil "Non-nil means the buffer existed before the server was asked to visit it. This means that the server should not kill the buffer when you say you are done with it in the server.") -(make-variable-buffer-local 'server-existing-buffer) (defvar server--external-socket-initialized nil "When an external socket is passed into Emacs, we need to call diff --git a/lisp/tab-line.el b/lisp/tab-line.el index 9209f2d46e..1bdddc2c83 100644 --- a/lisp/tab-line.el +++ b/lisp/tab-line.el @@ -810,9 +810,7 @@ from the tab line." :version "27.1") ;;;###autoload -(defvar tab-line-exclude nil) -;;;###autoload -(make-variable-buffer-local 'tab-line-exclude) +(defvar-local tab-line-exclude nil) (defun tab-line-mode--turn-on () "Turn on `tab-line-mode'." diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el index cd53d7b6ff..89a71ac2b8 100644 --- a/lisp/tar-mode.el +++ b/lisp/tar-mode.el @@ -149,12 +149,11 @@ This information is useful, but it takes screen space away from file names." ;; So instead, we now keep the two pieces of data in separate buffers, and ;; use the new buffer-swap-text primitive when we need to change which data ;; is associated with "the" buffer. -(defvar tar-data-buffer nil "Buffer that holds the actual raw tar bytes.") -(make-variable-buffer-local 'tar-data-buffer) +(defvar-local tar-data-buffer nil + "Buffer that holds the actual raw tar bytes.") -(defvar tar-data-swapped nil +(defvar-local tar-data-swapped nil "If non-nil, `tar-data-buffer' indeed holds raw tar bytes.") -(make-variable-buffer-local 'tar-data-swapped) (defun tar-data-swapped-p () "Return non-nil if the tar-data is in `tar-data-buffer'." diff --git a/lisp/thumbs.el b/lisp/thumbs.el index 7d6558d8f7..465d097b61 100644 --- a/lisp/thumbs.el +++ b/lisp/thumbs.el @@ -148,36 +148,30 @@ this value can let another user see some of your images." :group 'thumbs) ;; Initialize some variable, for later use. -(defvar thumbs-current-tmp-filename nil +(defvar-local thumbs-current-tmp-filename nil "Temporary filename of current image.") -(make-variable-buffer-local 'thumbs-current-tmp-filename) -(defvar thumbs-current-image-filename nil +(defvar-local thumbs-current-image-filename nil "Filename of current image.") -(make-variable-buffer-local 'thumbs-current-image-filename) -(defvar thumbs-extra-images 1 +(defvar-local thumbs-extra-images 1 "Counter for showing extra images in thumbs buffer.") -(make-variable-buffer-local 'thumbs-extra-images) (put 'thumbs-extra-images 'permanent-local t) (defvar thumbs-current-image-size nil "Size of current image.") -(defvar thumbs-image-num nil +(defvar-local thumbs-image-num nil "Number of current image.") -(make-variable-buffer-local 'thumbs-image-num) -(defvar thumbs-buffer nil +(defvar-local thumbs-buffer nil "Name of buffer containing thumbnails associated with image.") -(make-variable-buffer-local 'thumbs-buffer) (defvar thumbs-current-dir nil "Current directory.") -(defvar thumbs-marked-list nil +(defvar-local thumbs-marked-list nil "List of marked files.") -(make-variable-buffer-local 'thumbs-marked-list) (put 'thumbs-marked-list 'permanent-local t) (defsubst thumbs-temp-dir () diff --git a/lisp/tutorial.el b/lisp/tutorial.el index 6bda1ab0d5..57e5570d53 100644 --- a/lisp/tutorial.el +++ b/lisp/tutorial.el @@ -38,17 +38,14 @@ "Face used to highlight warnings in the tutorial." :group 'help) -(defvar tutorial--point-before-chkeys 0 +(defvar-local tutorial--point-before-chkeys 0 "Point before display of key changes.") -(make-variable-buffer-local 'tutorial--point-before-chkeys) -(defvar tutorial--point-after-chkeys 0 +(defvar-local tutorial--point-after-chkeys 0 "Point after display of key changes.") -(make-variable-buffer-local 'tutorial--point-after-chkeys) -(defvar tutorial--lang nil +(defvar-local tutorial--lang nil "Tutorial language.") -(make-variable-buffer-local 'tutorial--lang) (defvar tutorial--buffer nil "The selected tutorial buffer.") diff --git a/lisp/url/url-vars.el b/lisp/url/url-vars.el index 6493abfa05..8c836f8f64 100644 --- a/lisp/url/url-vars.el +++ b/lisp/url/url-vars.el @@ -55,26 +55,19 @@ :group 'url) -(defvar url-current-object nil +(defvar-local url-current-object nil "A parsed representation of the current URL.") -(defvar url-current-mime-headers nil +(defvar-local url-current-mime-headers nil "A parsed representation of the MIME headers for the current URL.") -(defvar url-current-lastloc nil +(defvar-local url-current-lastloc nil "A parsed representation of the URL to be considered as the last location. Use of this value on outbound connections is subject to `url-privacy-level' and `url-lastloc-privacy-level'. This is never set by the url library, applications are expected to set this variable in buffers representing a displayed location.") -(mapc 'make-variable-buffer-local - '( - url-current-object - url-current-mime-headers - url-current-lastloc - )) - (defcustom url-honor-refresh-requests t "Whether to do automatic page reloads. These are done at the request of the document author or the server via diff --git a/lisp/view.el b/lisp/view.el index 5a2f2fadfc..026c1ece30 100644 --- a/lisp/view.el +++ b/lisp/view.el @@ -96,38 +96,31 @@ interactive command; otherwise the help message is not shown." :version "22.1") ;;;###autoload -(defvar view-mode nil +(defvar-local view-mode nil "Non-nil if View mode is enabled. Don't change this variable directly, you must change it by one of the functions that enable or disable view mode.") -;;;###autoload -(make-variable-buffer-local 'view-mode) (defcustom view-mode-hook nil "Normal hook run when starting to view a buffer or file." :type 'hook :group 'view) -(defvar view-old-buffer-read-only nil) -(make-variable-buffer-local 'view-old-buffer-read-only) +(defvar-local view-old-buffer-read-only nil) -(defvar view-old-Helper-return-blurb) -(make-variable-buffer-local 'view-old-Helper-return-blurb) +(defvar-local view-old-Helper-return-blurb nil) -(defvar view-page-size nil +(defvar-local view-page-size nil "Default number of lines to scroll by View page commands. If nil that means use the window size.") -(make-variable-buffer-local 'view-page-size) -(defvar view-half-page-size nil +(defvar-local view-half-page-size nil "Default number of lines to scroll by View half page commands. If nil that means use half the window size.") -(make-variable-buffer-local 'view-half-page-size) -(defvar view-last-regexp nil) -(make-variable-buffer-local 'view-last-regexp) ; Global is better??? +(defvar-local view-last-regexp nil) ; Global is better??? -(defvar view-return-to-alist nil +(defvar-local view-return-to-alist nil "What to do with used windows and where to go when finished viewing buffer. This is local in each buffer being viewed. It is added to by `view-mode-enter' when starting to view a buffer and @@ -136,18 +129,16 @@ subtracted from by `view-mode-exit' when finished viewing the buffer. See RETURN-TO-ALIST argument of function `view-mode-exit' for the format of `view-return-to-alist'.") (make-obsolete-variable - 'view-return-to-alist "this variable is no more used." "24.1") -(make-variable-buffer-local 'view-return-to-alist) + 'view-return-to-alist "this variable is no longer used." "24.1") (put 'view-return-to-alist 'permanent-local t) -(defvar view-exit-action nil +(defvar-local view-exit-action nil "If non-nil, a function called when finished viewing. The function should take one argument (a buffer). Commands like \\[view-file] and \\[view-file-other-window] may set this to bury or kill the viewed buffer. Observe that the buffer viewed might not appear in any window at the time this function is called.") -(make-variable-buffer-local 'view-exit-action) (defvar view-no-disable-on-exit nil "If non-nil, View mode \"exit\" commands don't actually disable View mode. @@ -155,10 +146,9 @@ Instead, these commands just switch buffers or windows. This is set in certain buffers by specialized features such as help commands that use View mode automatically.") -(defvar view-overlay nil +(defvar-local view-overlay nil "Overlay used to display where a search operation found its match. This is local in each buffer, once it is used.") -(make-variable-buffer-local 'view-overlay) ;; Define keymap inside defvar to make it easier to load changes. ;; Some redundant "less"-like key bindings below have been commented out. diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index 68a0d3d235..de2b5d4a7c 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el @@ -1019,9 +1019,8 @@ button end points." Recommended as a parent keymap for modes using widgets. Note that such modes will need to require wid-edit.") -(defvar widget-global-map global-map +(defvar-local widget-global-map global-map "Keymap used for events a widget does not handle itself.") -(make-variable-buffer-local 'widget-global-map) (defvar widget-field-keymap (let ((map (copy-keymap widget-keymap))) @@ -1326,13 +1325,11 @@ When not inside a field, signal an error." ;;; Setting up the buffer. -(defvar widget-field-new nil +(defvar-local widget-field-new nil "List of all newly created editable fields in the buffer.") -(make-variable-buffer-local 'widget-field-new) -(defvar widget-field-list nil +(defvar-local widget-field-list nil "List of all editable fields in the buffer.") -(make-variable-buffer-local 'widget-field-list) (defun widget-at (&optional pos) "The button or field at POS (default, point)." @@ -1359,13 +1356,11 @@ When not inside a field, signal an error." (widget-clear-undo) (widget-add-change)) -(defvar widget-field-last nil) -;; Last field containing point. -(make-variable-buffer-local 'widget-field-last) +(defvar-local widget-field-last nil + "Last field containing point.") -(defvar widget-field-was nil) -;; The widget data before the change. -(make-variable-buffer-local 'widget-field-was) +(defvar-local widget-field-was nil + "The widget data before the change.") (defun widget-field-at (pos) "Return the widget field at POS, or nil if none." diff --git a/lisp/woman.el b/lisp/woman.el index 0e4c1c10fc..1d3c8d1690 100644 --- a/lisp/woman.el +++ b/lisp/woman.el @@ -1078,9 +1078,8 @@ Set by `.ns' request; reset by any output or `.rs' request") ;; Could end with "\\( +\\|$\\)" instead of " *" "Regexp to match a ?roff request plus trailing white space.") -(defvar woman-imenu-done nil +(defvar-local woman-imenu-done nil "Buffer-local: set to true if function `woman-imenu' has been called.") -(make-variable-buffer-local 'woman-imenu-done) ;; From imenu.el -- needed when reformatting a file in its old buffer. ;; The latest buffer index used to update the menu bar menu. commit cfe8d9e0f74a1256cb75bd467b866f03ac513634 Author: Stefan Kangas Date: Mon Feb 1 16:35:48 2021 +0100 Remove redundant :group args in play/*.el * lisp/play/bubbles.el: * lisp/play/cookie1.el: * lisp/play/decipher.el: * lisp/play/dunnet.el: * lisp/play/gametree.el: * lisp/play/gomoku.el: * lisp/play/hanoi.el: Remove redundant :group args. diff --git a/lisp/play/bubbles.el b/lisp/play/bubbles.el index f317ad51cf..dc93ef9031 100644 --- a/lisp/play/bubbles.el +++ b/lisp/play/bubbles.el @@ -82,6 +82,10 @@ ;; Careful with that axe, Eugene! Order does matter in the custom ;; section below. +(defgroup bubbles nil + "Bubbles, a puzzle game." + :group 'games) + (defcustom bubbles-game-theme 'easy "Overall game theme. @@ -91,8 +95,7 @@ and a shift mode." (const :tag "Medium" medium) (const :tag "Difficult" difficult) (const :tag "Hard" hard) - (const :tag "User defined" user-defined)) - :group 'bubbles) + (const :tag "User defined" user-defined))) (defun bubbles-set-game-easy () "Set game theme to `easy'." @@ -124,10 +127,6 @@ and a shift mode." (setq bubbles-game-theme 'user-defined) (bubbles)) -(defgroup bubbles nil - "Bubbles, a puzzle game." - :group 'games) - (defcustom bubbles-graphics-theme 'circles "Graphics theme. diff --git a/lisp/play/cookie1.el b/lisp/play/cookie1.el index 9cecb706f9..5255d81e5b 100644 --- a/lisp/play/cookie1.el +++ b/lisp/play/cookie1.el @@ -60,7 +60,6 @@ (defcustom cookie-file nil "Default phrase file for cookie functions." :type '(choice (const nil) file) - :group 'cookie :version "24.4") (defconst cookie-delimiter "\n%%\n\\|\n%\n\\|\0" diff --git a/lisp/play/decipher.el b/lisp/play/decipher.el index b870bfb4a1..524ca81f30 100644 --- a/lisp/play/decipher.el +++ b/lisp/play/decipher.el @@ -99,8 +99,7 @@ "Non-nil means to convert ciphertext to uppercase. nil means the case of the ciphertext is preserved. This variable must be set before typing `\\[decipher]'." - :type 'boolean - :group 'decipher) + :type 'boolean) (defcustom decipher-ignore-spaces nil @@ -108,21 +107,18 @@ This variable must be set before typing `\\[decipher]'." You should set this to nil if the cipher message is divided into words, or t if it is not. This variable is buffer-local." - :type 'boolean - :group 'decipher) + :type 'boolean) (make-variable-buffer-local 'decipher-ignore-spaces) (defcustom decipher-undo-limit 5000 "The maximum number of entries in the undo list. When the undo list exceeds this number, 100 entries are deleted from the tail of the list." - :type 'integer - :group 'decipher) + :type 'integer) (defcustom decipher-mode-hook nil "Hook to run upon entry to decipher." - :type 'hook - :group 'decipher) + :type 'hook) ;; End of user modifiable variables ;;-------------------------------------------------------------------- diff --git a/lisp/play/dunnet.el b/lisp/play/dunnet.el index 3916e35f76..c3be029a65 100644 --- a/lisp/play/dunnet.el +++ b/lisp/play/dunnet.el @@ -42,8 +42,7 @@ (locate-user-emacs-file "games/"))) "Name of file to store score information for dunnet." :version "26.1" - :type 'file - :group 'dunnet) + :type 'file) ;;;; ;;;; This section defines the globals that are used in dunnet. diff --git a/lisp/play/gametree.el b/lisp/play/gametree.el index be39e1ebfb..1c2c24ad75 100644 --- a/lisp/play/gametree.el +++ b/lisp/play/gametree.el @@ -97,35 +97,30 @@ numbers of moves by Black (if considered in isolation) by the ellipsis conflicts with the use of ellipsis by Outline mode to denote collapsed subtrees. The author uses \":\" because it agrees nicely with a set of LaTeX macros he uses for typesetting annotated games." - :type 'regexp - :group 'gametree) + :type 'regexp) (defcustom gametree-full-ply-regexp (regexp-quote ".") "Matches ends of numbers of moves by the \"first\" player. For instance, it is an almost universal convention in chess to postfix numbers of moves by White (if considered in isolation) by the dot \".\"." - :type 'regexp - :group 'gametree) + :type 'regexp) (defcustom gametree-half-ply-format "%d:" "Output format for move numbers of moves by the \"second\" player. Has to contain \"%d\" to output the actual number." - :type 'string - :group 'gametree) + :type 'string) (defcustom gametree-full-ply-format "%d." "Output format for move numbers of moves by the \"first\" player. Has to contain \"%d\" to output the actual number." - :type 'string - :group 'gametree) + :type 'string) (defcustom gametree-make-heading-function (lambda (level) (insert (make-string level ?*))) "A function of one numeric argument, LEVEL, to insert a heading at point. You should change this if you change `outline-regexp'." - :type 'function - :group 'gametree) + :type 'function) (defvar gametree-local-layout nil "A list encoding the layout (i.e. the show or hide state) of the file. @@ -137,18 +132,15 @@ the file is visited (subject to the usual restriction via (defcustom gametree-score-opener "{score=" "The string which opens a score tag, and precedes the actual score." - :type 'string - :group 'gametree) + :type 'string) (defcustom gametree-score-manual-flag "!" "String marking the line as manually (as opposed to automatically) scored." - :type 'string - :group 'gametree) + :type 'string) (defcustom gametree-score-closer "}" "The string which closes a score tag, and follows the actual score." - :type 'string - :group 'gametree) + :type 'string) (defcustom gametree-score-regexp (concat "[^\n\^M]*\\(" @@ -166,13 +158,11 @@ line as *manually* (as opposed to automatically) scored, which prevents the program from recursively applying the scoring algorithm on the subtree headed by the marked line, and makes it use the manual score instead." - :type 'regexp - :group 'gametree) + :type 'regexp) (defcustom gametree-default-score 0 "Score to assume for branches lacking score tags." - :type 'integer - :group 'gametree) + :type 'integer) ;;;; Helper functions diff --git a/lisp/play/gomoku.el b/lisp/play/gomoku.el index 1856db8b8b..8db40d7f94 100644 --- a/lisp/play/gomoku.el +++ b/lisp/play/gomoku.el @@ -76,8 +76,7 @@ (defcustom gomoku-mode-hook nil "If non-nil, its value is called on entry to Gomoku mode. One useful value to include is `turn-on-font-lock' to highlight the pieces." - :type 'hook - :group 'gomoku) + :type 'hook) ;;; ;;; CONSTANTS FOR BOARD @@ -168,13 +167,11 @@ One useful value to include is `turn-on-font-lock' to highlight the pieces." (defface gomoku-O '((((class color)) (:foreground "red" :weight bold))) - "Face to use for Emacs's O." - :group 'gomoku) + "Face to use for Emacs's O.") (defface gomoku-X '((((class color)) (:foreground "green" :weight bold))) - "Face to use for your X." - :group 'gomoku) + "Face to use for your X.") (defvar gomoku-font-lock-keywords '(("O" . 'gomoku-O) diff --git a/lisp/play/hanoi.el b/lisp/play/hanoi.el index d762290f0d..f6e5fcd367 100644 --- a/lisp/play/hanoi.el +++ b/lisp/play/hanoi.el @@ -71,33 +71,33 @@ (defcustom hanoi-horizontal-flag nil "If non-nil, hanoi poles are oriented horizontally." - :group 'hanoi :type 'boolean) + :type 'boolean) (defcustom hanoi-move-period 1.0 "Time, in seconds, for each pole-to-pole move of a ring. If nil, move rings as fast as possible while displaying all intermediate positions." - :group 'hanoi :type '(restricted-sexp :match-alternatives (numberp 'nil))) + :type '(restricted-sexp :match-alternatives (numberp 'nil))) (defcustom hanoi-use-faces nil "If nil, all hanoi-*-face variables are ignored." - :group 'hanoi :type 'boolean) + :type 'boolean) (defcustom hanoi-pole-face 'highlight "Face for poles. Ignored if hanoi-use-faces is nil." - :group 'hanoi :type 'face) + :type 'face) (defcustom hanoi-base-face 'highlight "Face for base. Ignored if hanoi-use-faces is nil." - :group 'hanoi :type 'face) + :type 'face) (defcustom hanoi-even-ring-face 'region "Face for even-numbered rings. Ignored if hanoi-use-faces is nil." - :group 'hanoi :type 'face) + :type 'face) (defcustom hanoi-odd-ring-face 'secondary-selection "Face for odd-numbered rings. Ignored if hanoi-use-faces is nil." - :group 'hanoi :type 'face) + :type 'face) ;;; commit 78744f5168f7dd19f742684afd9c588a4a1e688d Author: Stefan Kangas Date: Mon Feb 1 16:03:10 2021 +0100 ; Move obsolete version variables further down * lisp/dframe.el: * lisp/speedbar.el: Move obsolete variables from the top of the file to the bottom, where they don't obscure the license information. diff --git a/lisp/dframe.el b/lisp/dframe.el index 23cb6c5a92..7ea5b3364e 100644 --- a/lisp/dframe.el +++ b/lisp/dframe.el @@ -5,10 +5,6 @@ ;; Author: Eric M. Ludlam ;; Keywords: file, tags, tools -(defvar dframe-version "1.3" - "The current version of the dedicated frame library.") -(make-obsolete-variable 'dframe-version nil "28.1") - ;; This file is part of GNU Emacs. ;; GNU Emacs is free software: you can redistribute it and/or modify @@ -834,6 +830,13 @@ the mode-line." (t (dframe-message "Click on the edge of the mode line to scroll left/right"))))) + +;;; Obsolete + +(defvar dframe-version "1.3" + "The current version of the dedicated frame library.") +(make-obsolete-variable 'dframe-version nil "28.1") + (provide 'dframe) ;;; dframe.el ends here diff --git a/lisp/speedbar.el b/lisp/speedbar.el index 7f751ec347..e43978f413 100644 --- a/lisp/speedbar.el +++ b/lisp/speedbar.el @@ -5,15 +5,6 @@ ;; Author: Eric M. Ludlam ;; Keywords: file, tags, tools -(defvar speedbar-version "1.0" - "The current version of speedbar.") -(make-obsolete-variable 'speedbar-version nil "28.1") -(defvar speedbar-incompatible-version "0.14beta4" - "This version of speedbar is incompatible with this version. -Due to massive API changes (removing the use of the word PATH) -this version is not backward compatible to 0.14 or earlier.") -(make-obsolete-variable 'speedbar-incompatible-version nil "28.1") - ;; This file is part of GNU Emacs. ;; GNU Emacs is free software: you can redistribute it and/or modify @@ -4086,6 +4077,19 @@ See `speedbar-expand-image-button-alist' for details." (insert (car (car ia)) "\t" (format "%s" (cdr (car ia))) "\n")) (setq ia (cdr ia))))))) + +;; Obsolete + +(defvar speedbar-version "1.0" + "The current version of speedbar.") +(make-obsolete-variable 'speedbar-version 'emacs-version "28.1") + +(defvar speedbar-incompatible-version "0.14beta4" + "This version of speedbar is incompatible with this version. +Due to massive API changes (removing the use of the word PATH) +this version is not backward compatible to 0.14 or earlier.") +(make-obsolete-variable 'speedbar-incompatible-version nil "28.1") + (provide 'speedbar) commit 7d15fa008af774789a91d7242055dc87497df66f Author: Sean Whitton Date: Tue Feb 2 09:44:44 2021 +0100 Bind 'revert-buffer' to 'C-x g' globally * lisp/bindings.el: Bind 'revert-buffer' to 'C-x g' globally. * doc/emacs/files.texi: Replace 'M-x revert-buffer' with 'C-x g'. * etc/NEWS: Document the change (bug#46151). diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index ede382c146..12ceac800e 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -927,9 +927,9 @@ Manual}). For customizations, see the Custom group @code{time-stamp}. If you have made extensive changes to a file-visiting buffer and then change your mind, you can @dfn{revert} the changes and go back to -the saved version of the file. To do this, type @kbd{M-x -revert-buffer}. Since reverting unintentionally could lose a lot of -work, Emacs asks for confirmation first. +the saved version of the file. To do this, type @kbd{C-x g}. Since +reverting unintentionally could lose a lot of work, Emacs asks for +confirmation first. The @code{revert-buffer} command tries to position point in such a way that, if the file was edited only slightly, you will be at diff --git a/etc/NEWS b/etc/NEWS index fc3a3dafb8..a376df62e3 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -233,6 +233,9 @@ search string is at least this long. 'lazy-highlight-initial-delay' still applies for shorter search strings, which avoids flicker in the search buffer due to too many matches being highlighted. ++++ +** 'revert-buffer' is now bound to 'C-x g' globally. + * Editing Changes in Emacs 28.1 diff --git a/lisp/bindings.el b/lisp/bindings.el index 43b62f9bbf..9ea188d1a0 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -1413,6 +1413,8 @@ if `inhibit-field-text-motion' is non-nil." (define-key ctl-x-map "z" 'repeat) +(define-key ctl-x-map "g" #'revert-buffer) + (define-key esc-map "\C-l" 'reposition-window) (define-key ctl-x-4-map "a" 'add-change-log-entry-other-window) commit 56804edc835b5b48f3bd6f89763c13d5e3ae3124 Author: Lars Ingebrigtsen Date: Tue Feb 2 09:26:02 2021 +0100 Fix up invalid_syntax error signalling * src/lread.c (invalid_syntax_lisp): Instead of putting the line/column in a string, signal an error containing the numbers as data. This allows for easier post-processing and is how other similar errors (like (forward-sexp 1)) do it. diff --git a/src/lread.c b/src/lread.c index 5d1676b0c9..b33a312299 100644 --- a/src/lread.c +++ b/src/lread.c @@ -545,14 +545,13 @@ invalid_syntax_lisp (Lisp_Object s, Lisp_Object readcharfun) { if (BUFFERP (readcharfun)) { - xsignal1 (Qinvalid_read_syntax, - CALLN (Fformat, build_string ("%s (line %d, column %d)"), - s, - /* We should already be in the readcharfun - buffer when this error is called, so no need - to switch to it first. */ - make_fixnum (count_lines (BEGV_BYTE, PT_BYTE) + 1), - make_fixnum (current_column ()))); + xsignal (Qinvalid_read_syntax, + list3 (s, + /* We should already be in the readcharfun + buffer when this error is called, so no need + to switch to it first. */ + make_fixnum (count_lines (BEGV_BYTE, PT_BYTE) + 1), + make_fixnum (current_column ()))); } else xsignal1 (Qinvalid_read_syntax, s); commit 83efac64779b0cda1a700d2f82d63a1afa1ac6f4 Author: Dmitry Gutov Date: Tue Feb 2 03:47:46 2021 +0200 ruby-syntax-propertize: Fix certain cases following :: * lisp/progmodes/ruby-mode.el (ruby-syntax-propertize): Make sure to backtrack if the "symbols with special characters" rule is aborted because of preceding colon. diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index a8667acb9d..e7f407b636 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -1869,8 +1869,8 @@ It will be properly highlighted even when the call omits parens.") ;; Symbols with special characters. (":\\([-+~]@?\\|[/%&|^`]\\|\\*\\*?\\|<\\(<\\|=>?\\)?\\|>[>=]?\\|===?\\|=~\\|![~=]?\\|\\[\\]=?\\)" (1 (unless (or - (eq (char-before (match-beginning 0)) ?:) - (nth 8 (syntax-ppss (match-beginning 1)))) + (nth 8 (syntax-ppss (match-beginning 1))) + (eq (char-before (match-beginning 0)) ?:)) (goto-char (match-end 0)) (string-to-syntax "_")))) ;; Symbols ending with '=' (bug#42846). diff --git a/test/lisp/progmodes/ruby-mode-resources/ruby.rb b/test/lisp/progmodes/ruby-mode-resources/ruby.rb index 434237cf63..8c698e4fac 100644 --- a/test/lisp/progmodes/ruby-mode-resources/ruby.rb +++ b/test/lisp/progmodes/ruby-mode-resources/ruby.rb @@ -108,7 +108,7 @@ def foo # Multiline regexp. /bars tees # toots - nfoos/ + nfoos::/ def test1(arg) puts "hello" commit e38e7b7bc121b96649518e5e986bba23697abc2d Author: Lars Ingebrigtsen Date: Mon Feb 1 17:04:17 2021 +0100 Make syntax errors say the line/column they appear at * src/lisp.h: Add count_lines prototype. * src/lread.c (invalid_syntax_lisp): New function (bug#36970). (invalid_syntax): Extend function to take a readcharfun parameter. (read_emacs_mule_char, character_name_to_code): Pass in. (read_escape, invalid_radix_integer, read1): Ditto. * src/xdisp.c (count_lines): Add a more succinct shim over display_count_lines. diff --git a/src/lisp.h b/src/lisp.h index f658868544..409a1e7060 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3734,6 +3734,7 @@ extern void message_log_maybe_newline (void); extern void update_echo_area (void); extern void truncate_echo_area (ptrdiff_t); extern void redisplay (void); +extern ptrdiff_t count_lines (ptrdiff_t start_byte, ptrdiff_t end_byte); void set_frame_cursor_types (struct frame *, Lisp_Object); extern void syms_of_xdisp (void); diff --git a/src/lread.c b/src/lread.c index 72b68df663..5d1676b0c9 100644 --- a/src/lread.c +++ b/src/lread.c @@ -537,6 +537,34 @@ readbyte_from_string (int c, Lisp_Object readcharfun) } +/* Signal Qinvalid_read_syntax error. + S is error string of length N (if > 0) */ + +static AVOID +invalid_syntax_lisp (Lisp_Object s, Lisp_Object readcharfun) +{ + if (BUFFERP (readcharfun)) + { + xsignal1 (Qinvalid_read_syntax, + CALLN (Fformat, build_string ("%s (line %d, column %d)"), + s, + /* We should already be in the readcharfun + buffer when this error is called, so no need + to switch to it first. */ + make_fixnum (count_lines (BEGV_BYTE, PT_BYTE) + 1), + make_fixnum (current_column ()))); + } + else + xsignal1 (Qinvalid_read_syntax, s); +} + +static AVOID +invalid_syntax (const char *s, Lisp_Object readcharfun) +{ + invalid_syntax_lisp (build_string (s), readcharfun); +} + + /* Read one non-ASCII character from INFILE. The character is encoded in `emacs-mule' and the first byte is already read in C. */ @@ -594,8 +622,7 @@ read_emacs_mule_char (int c, int (*readbyte) (int, Lisp_Object), Lisp_Object rea } c = DECODE_CHAR (charset, code); if (c < 0) - Fsignal (Qinvalid_read_syntax, - list1 (build_string ("invalid multibyte form"))); + invalid_syntax ("invalid multibyte form", readcharfun); return c; } @@ -2330,16 +2357,6 @@ read_internal_start (Lisp_Object stream, Lisp_Object start, Lisp_Object end) } -/* Signal Qinvalid_read_syntax error. - S is error string of length N (if > 0) */ - -static AVOID -invalid_syntax (const char *s) -{ - xsignal1 (Qinvalid_read_syntax, build_string (s)); -} - - /* Use this for recursive reads, in contexts where internal tokens are not allowed. */ @@ -2353,8 +2370,8 @@ read0 (Lisp_Object readcharfun) if (!c) return val; - xsignal1 (Qinvalid_read_syntax, - Fmake_string (make_fixnum (1), make_fixnum (c), Qnil)); + invalid_syntax_lisp (Fmake_string (make_fixnum (1), make_fixnum (c), Qnil), + readcharfun); } /* Grow a read buffer BUF that contains OFFSET useful bytes of data, @@ -2384,7 +2401,8 @@ grow_read_buffer (char *buf, ptrdiff_t offset, /* Return the scalar value that has the Unicode character name NAME. Raise 'invalid-read-syntax' if there is no such character. */ static int -character_name_to_code (char const *name, ptrdiff_t name_len) +character_name_to_code (char const *name, ptrdiff_t name_len, + Lisp_Object readcharfun) { /* For "U+XXXX", pass the leading '+' to string_to_number to reject monstrosities like "U+-0000". */ @@ -2400,7 +2418,7 @@ character_name_to_code (char const *name, ptrdiff_t name_len) { AUTO_STRING (format, "\\N{%s}"); AUTO_STRING_WITH_LEN (namestr, name, name_len); - xsignal1 (Qinvalid_read_syntax, CALLN (Fformat, format, namestr)); + invalid_syntax_lisp (CALLN (Fformat, format, namestr), readcharfun); } return XFIXNUM (code); @@ -2619,7 +2637,7 @@ read_escape (Lisp_Object readcharfun, bool stringp) { c = READCHAR; if (c != '{') - invalid_syntax ("Expected opening brace after \\N"); + invalid_syntax ("Expected opening brace after \\N", readcharfun); char name[UNICODE_CHARACTER_NAME_LENGTH_BOUND + 1]; bool whitespace = false; ptrdiff_t length = 0; @@ -2634,8 +2652,9 @@ read_escape (Lisp_Object readcharfun, bool stringp) { AUTO_STRING (format, "Invalid character U+%04X in character name"); - xsignal1 (Qinvalid_read_syntax, - CALLN (Fformat, format, make_fixed_natnum (c))); + invalid_syntax_lisp (CALLN (Fformat, format, + make_fixed_natnum (c)), + readcharfun); } /* Treat multiple adjacent whitespace characters as a single space character. This makes it easier to use @@ -2651,15 +2670,15 @@ read_escape (Lisp_Object readcharfun, bool stringp) whitespace = false; name[length++] = c; if (length >= sizeof name) - invalid_syntax ("Character name too long"); + invalid_syntax ("Character name too long", readcharfun); } if (length == 0) - invalid_syntax ("Empty character name"); + invalid_syntax ("Empty character name", readcharfun); name[length] = '\0'; /* character_name_to_code can invoke read1, recursively. This is why read1's buffer is not static. */ - return character_name_to_code (name, length); + return character_name_to_code (name, length, readcharfun); } default: @@ -2697,10 +2716,11 @@ enum { stackbufsize = max (64, + INT_STRLEN_BOUND (EMACS_INT) + 1)) }; static void -invalid_radix_integer (EMACS_INT radix, char stackbuf[VLA_ELEMS (stackbufsize)]) +invalid_radix_integer (EMACS_INT radix, char stackbuf[VLA_ELEMS (stackbufsize)], + Lisp_Object readcharfun) { sprintf (stackbuf, invalid_radix_integer_format, radix); - invalid_syntax (stackbuf); + invalid_syntax (stackbuf, readcharfun); } /* Read an integer in radix RADIX using READCHARFUN to read @@ -2760,7 +2780,7 @@ read_integer (Lisp_Object readcharfun, int radix, UNREAD (c); if (valid != 1) - invalid_radix_integer (radix, stackbuf); + invalid_radix_integer (radix, stackbuf, readcharfun); *p = '\0'; return unbind_to (count, string_to_number (read_buffer, radix, NULL)); @@ -2896,7 +2916,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) return ht; } UNREAD (c); - invalid_syntax ("#"); + invalid_syntax ("#", readcharfun); } if (c == '^') { @@ -2948,9 +2968,9 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) } return tbl; } - invalid_syntax ("#^^"); + invalid_syntax ("#^^", readcharfun); } - invalid_syntax ("#^"); + invalid_syntax ("#^", readcharfun); } if (c == '&') { @@ -2973,7 +2993,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) version. */ && ! (XFIXNAT (length) == (SCHARS (tmp) - 1) * BOOL_VECTOR_BITS_PER_CHAR))) - invalid_syntax ("#&..."); + invalid_syntax ("#&...", readcharfun); val = make_uninit_bool_vector (XFIXNAT (length)); data = bool_vector_uchar_data (val); @@ -2984,7 +3004,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) &= (1 << (XFIXNUM (length) % BOOL_VECTOR_BITS_PER_CHAR)) - 1; return val; } - invalid_syntax ("#&..."); + invalid_syntax ("#&...", readcharfun); } if (c == '[') { @@ -3002,7 +3022,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) && VECTORP (AREF (tmp, COMPILED_CONSTANTS))) || CONSP (AREF (tmp, COMPILED_BYTECODE))) && FIXNATP (AREF (tmp, COMPILED_STACK_DEPTH)))) - invalid_syntax ("Invalid byte-code object"); + invalid_syntax ("Invalid byte-code object", readcharfun); if (STRINGP (AREF (tmp, COMPILED_BYTECODE)) && STRING_MULTIBYTE (AREF (tmp, COMPILED_BYTECODE))) @@ -3044,7 +3064,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) /* Read the string itself. */ tmp = read1 (readcharfun, &ch, 0); if (ch != 0 || !STRINGP (tmp)) - invalid_syntax ("#"); + invalid_syntax ("#", readcharfun); /* Read the intervals and their properties. */ while (1) { @@ -3059,7 +3079,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) if (ch == 0) plist = read1 (readcharfun, &ch, 0); if (ch) - invalid_syntax ("Invalid string property list"); + invalid_syntax ("Invalid string property list", readcharfun); Fset_text_properties (beg, end, plist, tmp); } @@ -3207,7 +3227,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) if (c == 'r' || c == 'R') { if (! (2 <= n && n <= 36)) - invalid_radix_integer (n, stackbuf); + invalid_radix_integer (n, stackbuf, readcharfun); return read_integer (readcharfun, n, stackbuf); } @@ -3301,7 +3321,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) return read_integer (readcharfun, 2, stackbuf); UNREAD (c); - invalid_syntax ("#"); + invalid_syntax ("#", readcharfun); case ';': while ((c = READCHAR) >= 0 && c != '\n'); @@ -3373,7 +3393,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) if (ok) return make_fixnum (c); - invalid_syntax ("?"); + invalid_syntax ("?", readcharfun); } case '"': @@ -3459,7 +3479,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) /* Any modifiers remaining are invalid. */ if (modifiers) - invalid_syntax ("Invalid modifier in string"); + invalid_syntax ("Invalid modifier in string", readcharfun); p += CHAR_STRING (ch, (unsigned char *) p); } else @@ -3999,7 +4019,7 @@ read_list (bool flag, Lisp_Object readcharfun) { if (ch == ']') return val; - invalid_syntax (") or . in a vector"); + invalid_syntax (") or . in a vector", readcharfun); } if (ch == ')') return val; @@ -4079,9 +4099,9 @@ read_list (bool flag, Lisp_Object readcharfun) return val; } - invalid_syntax (". in wrong context"); + invalid_syntax (". in wrong context", readcharfun); } - invalid_syntax ("] in a list"); + invalid_syntax ("] in a list", readcharfun); } tem = list1 (elt); if (!NILP (tail)) diff --git a/src/xdisp.c b/src/xdisp.c index 32b359098a..efca6f641f 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -26969,6 +26969,15 @@ decode_mode_spec (struct window *w, register int c, int field_width, return ""; } +/* Return the number of lines between start_byte and end_byte in the + current buffer. */ + +ptrdiff_t +count_lines (ptrdiff_t start_byte, ptrdiff_t end_byte) +{ + ptrdiff_t ignored; + return display_count_lines (start_byte, end_byte, ZV, &ignored); +} /* Count up to COUNT lines starting from START_BYTE. COUNT negative means count lines back from START_BYTE. But don't go beyond commit 3990716a97f48adc0a77250cdf5a2853f3f7f7e0 Author: Glenn Morris Date: Mon Feb 1 06:28:21 2021 -0800 ; Auto-commit of loaddefs files. diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index c6fa497c21..9924d62774 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -8415,9 +8415,6 @@ strings when pressed twice. See `double-map' for details. (autoload 'dunnet "dunnet" "\ Switch to *dungeon* buffer and start game." t nil) -(autoload 'dun-batch "dunnet" "\ -Start `dunnet' in batch mode." nil nil) - (register-definition-prefixes "dunnet" '("dun" "obj-special")) ;;;*** @@ -12945,7 +12942,7 @@ lines. ;;;### (autoloads nil "flymake" "progmodes/flymake.el" (0 0 0 0)) ;;; Generated autoloads from progmodes/flymake.el -(push (purecopy '(flymake 1 0 9)) package--builtin-versions) +(push (purecopy '(flymake 1 1 1)) package--builtin-versions) (autoload 'flymake-log "flymake" "\ Log, at level LEVEL, the message MSG formatted with ARGS. @@ -15889,7 +15886,7 @@ Produce a texinfo buffer with sorted doc-strings from the DOC file. \(fn FILE)" t nil) -(register-definition-prefixes "help-fns" '("describe-" "help-")) +(register-definition-prefixes "help-fns" '("describe-" "help-" "keymap-name-history")) ;;;*** @@ -16672,9 +16669,7 @@ non-selected window. Hl-Line mode uses the function `hl-line-highlight' on `post-command-hook' in this case. When `hl-line-sticky-flag' is nil, Hl-Line mode highlights the -line about point in the selected window only. In this case, it -uses the function `hl-line-maybe-unhighlight' in -addition to `hl-line-highlight' on `post-command-hook'. +line about point in the selected window only. \(fn &optional ARG)" t nil) @@ -16706,8 +16701,8 @@ If `global-hl-line-sticky-flag' is non-nil, Global Hl-Line mode highlights the line about the current buffer's point in all live windows. -Global-Hl-Line mode uses the functions `global-hl-line-highlight' -and `global-hl-line-maybe-unhighlight' on `post-command-hook'. +Global-Hl-Line mode uses the function `global-hl-line-highlight' +on `post-command-hook'. \(fn &optional ARG)" t nil) @@ -18387,7 +18382,9 @@ the environment variable INFOPATH is set. Although this is a customizable variable, that is mainly for technical reasons. Normally, you should either set INFOPATH or customize -`Info-additional-directory-list', rather than changing this variable." :initialize 'custom-initialize-delay :type '(repeat directory)) +`Info-additional-directory-list', rather than changing this variable." :initialize #'custom-initialize-delay :type '(repeat directory)) + +(custom-autoload 'Info-default-directory-list "info" t) (autoload 'info-other-window "info" "\ Like `info' but show the Info buffer in another window. @@ -19539,7 +19536,7 @@ Create lambda form for macro bound to symbol or key. \(fn MAC &optional COUNTER FORMAT)" nil nil) -(register-definition-prefixes "kmacro" '("kmacro-")) +(register-definition-prefixes "kmacro" '("kdb-macro-redisplay" "kmacro-")) ;;;*** @@ -19548,8 +19545,8 @@ Create lambda form for macro bound to symbol or key. ;;; Generated autoloads from language/korea-util.el (defvar default-korean-keyboard (purecopy (if (string-match "3" (or (getenv "HANGUL_KEYBOARD_TYPE") "")) "3" "")) "\ -The kind of Korean keyboard for Korean input method. -\"\" for 2, \"3\" for 3.") +The kind of Korean keyboard for Korean (Hangul) input method. +\"\" for 2, \"3\" for 3, and \"3f\" for 3f.") (autoload 'setup-korean-environment-internal "korea-util" nil nil nil) @@ -21586,8 +21583,10 @@ Major mode for the mixal asm language. ;;;### (autoloads nil "mm-encode" "gnus/mm-encode.el" (0 0 0 0)) ;;; Generated autoloads from gnus/mm-encode.el -(autoload 'mm-default-file-encoding "mm-encode" "\ -Return a default encoding for FILE. +(define-obsolete-function-alias 'mm-default-file-encoding #'mm-default-file-type "future") + +(autoload 'mm-default-file-type "mm-encode" "\ +Return a default content type for FILE. \(fn FILE)" nil nil) @@ -22746,7 +22745,7 @@ Generate NOV databases in all nnml directories. ;;;### (autoloads nil "nnoo" "gnus/nnoo.el" (0 0 0 0)) ;;; Generated autoloads from gnus/nnoo.el -(register-definition-prefixes "nnoo" '("deffoo" "defvoo" "nnoo-")) +(register-definition-prefixes "nnoo" '("deffoo" "defvoo" "nnoo-" "noo--defalias")) ;;;*** @@ -24246,10 +24245,27 @@ with \"-q\"). Even if the value is nil, you can type \\[package-initialize] to make installed packages available at any time, or you can -call (package-initialize) in your init-file.") +call (package-activate-all) in your init-file.") (custom-autoload 'package-enable-at-startup "package" t) +(defcustom package-user-dir (locate-user-emacs-file "elpa") "\ +Directory containing the user's Emacs Lisp packages. +The directory name should be absolute. +Apart from this directory, Emacs also looks for system-wide +packages in `package-directory-list'." :type 'directory :initialize #'custom-initialize-delay :risky t :version "24.1") + +(custom-autoload 'package-user-dir "package" t) + +(defcustom package-directory-list (let (result) (dolist (f load-path) (and (stringp f) (equal (file-name-nondirectory f) "site-lisp") (push (expand-file-name "elpa" f) result))) (nreverse result)) "\ +List of additional directories containing Emacs Lisp packages. +Each directory name should be absolute. + +These directories contain packages intended for system-wide; in +contrast, `package-user-dir' contains packages for personal use." :type '(repeat directory) :initialize #'custom-initialize-delay :risky t :version "24.1") + +(custom-autoload 'package-directory-list "package" t) + (defvar package--activated nil "\ Non-nil if `package-activate-all' has been run.") @@ -24271,9 +24287,9 @@ that code in the early init-file. \(fn &optional NO-ACTIVATE)" t nil) -(autoload 'package-activate-all "package" "\ +(defun package-activate-all nil "\ Activate all installed packages. -The variable `package-load-list' controls which packages to load." nil nil) +The variable `package-load-list' controls which packages to load." (setq package--activated t) (let* ((elc (concat package-quickstart-file "c")) (qs (if (file-readable-p elc) elc (if (file-readable-p package-quickstart-file) package-quickstart-file)))) (if qs (let ((load-source-file-function nil)) (unless (boundp 'package-activated-list) (setq package-activated-list nil)) (load qs nil 'nomessage)) (require 'package) (package--activate-all)))) (autoload 'package-import-keyring "package" "\ Import keys from FILE. @@ -24370,6 +24386,11 @@ The return value is a string (or nil in case we can't find it)." nil nil) (function-put 'package-get-version 'pure 't) +(defcustom package-quickstart-file (locate-user-emacs-file "package-quickstart.el") "\ +Location of the file used to speed up activation of packages at startup." :type 'file :initialize #'custom-initialize-delay :version "27.1") + +(custom-autoload 'package-quickstart-file "package" t) + (register-definition-prefixes "package" '("bad-signature" "define-package" "describe-package-1" "package-")) ;;;*** @@ -24561,6 +24582,7 @@ PATTERN matches. PATTERN can take one of the forms: If a SYMBOL is used twice in the same pattern the second occurrence becomes an `eq'uality test. (pred FUN) matches if FUN called on EXPVAL returns non-nil. + (pred (not FUN)) matches if FUN called on EXPVAL returns nil. (app FUN PAT) matches if FUN called on EXPVAL matches PAT. (guard BOOLEXP) matches if BOOLEXP evaluates to non-nil. (let PAT EXPR) matches if EXPR matches PAT. @@ -25851,7 +25873,7 @@ Open profile FILENAME. ;;;### (autoloads nil "project" "progmodes/project.el" (0 0 0 0)) ;;; Generated autoloads from progmodes/project.el -(push (purecopy '(project 0 5 3)) package--builtin-versions) +(push (purecopy '(project 0 5 4)) package--builtin-versions) (autoload 'project-current "project" "\ Return the project instance in DIRECTORY, defaulting to `default-directory'. @@ -25956,9 +25978,13 @@ if one already exists." t nil) (autoload 'project-async-shell-command "project" "\ Run `async-shell-command' in the current project's root directory." t nil) +(function-put 'project-async-shell-command 'interactive-only 'async-shell-command) + (autoload 'project-shell-command "project" "\ Run `shell-command' in the current project's root directory." t nil) +(function-put 'project-shell-command 'interactive-only 'shell-command) + (autoload 'project-search "project" "\ Search for REGEXP in all the files of the project. Stops when a match is found. @@ -25976,10 +26002,9 @@ loop using the command \\[fileloop-continue]. \(fn FROM TO)" t nil) (autoload 'project-compile "project" "\ -Run `compile' in the project root. -Arguments the same as in `compile'. +Run `compile' in the project root." t nil) -\(fn COMMAND &optional COMINT)" t nil) +(function-put 'project-compile 'interactive-only 'compile) (autoload 'project-switch-to-buffer "project" "\ Display buffer BUFFER-OR-NAME in the selected window. @@ -26967,6 +26992,13 @@ When Recentf mode is enabled, a \"Open Recent\" submenu is displayed in the \"File\" menu, containing a list of files that were operated on recently, in the most-recently-used order. +By default, only operations like opening a file, writing a buffer +to a file, and killing a buffer is counted as \"operating\" on +the file. If instead you want to prioritize files that appear in +buffers you switch to a lot, you can say something like the following: + + (add-hook 'buffer-list-update-hook 'recentf-track-opened-file) + \(fn &optional ARG)" t nil) (register-definition-prefixes "recentf" '("recentf-")) @@ -27347,7 +27379,7 @@ Remember the contents of the current clipboard. Most useful for remembering things from other applications." t nil) (autoload 'remember-diary-extract-entries "remember" "\ -Extract diary entries from the region." nil nil) +Extract diary entries from the region based on `remember-diary-regexp'." nil nil) (autoload 'remember-notes "remember" "\ Return the notes buffer, creating it if needed, and maybe switch to it. @@ -27637,14 +27669,11 @@ Name of user's primary mail file.") (custom-autoload 'rmail-file-name "rmail" t) -(put 'rmail-spool-directory 'standard-value '((cond ((file-exists-p "/var/mail") "/var/mail/") ((file-exists-p "/var/spool/mail") "/var/spool/mail/") ((memq system-type '(hpux usg-unix-v)) "/usr/mail/") (t "/usr/spool/mail/")))) - -(defvar rmail-spool-directory (purecopy (cond ((file-exists-p "/var/mail") "/var/mail/") ((file-exists-p "/var/spool/mail") "/var/spool/mail/") ((memq system-type '(hpux usg-unix-v)) "/usr/mail/") (t "/usr/spool/mail/"))) "\ +(defcustom rmail-spool-directory (purecopy (cond ((file-exists-p "/var/mail") "/var/mail/") ((file-exists-p "/var/spool/mail") "/var/spool/mail/") ((memq system-type '(hpux usg-unix-v)) "/usr/mail/") (t "/usr/spool/mail/"))) "\ Name of directory used by system mailer for delivering new mail. -Its name should end with a slash.") +Its name should end with a slash." :initialize #'custom-initialize-delay :type 'directory :group 'rmail) (custom-autoload 'rmail-spool-directory "rmail" t) -(custom-initialize-delay 'rmail-spool-directory nil) (autoload 'rmail-movemail-variant-p "rmail" "\ Return t if the current movemail variant is any of VARIANTS. @@ -29076,7 +29105,9 @@ variable `feedmail-deduce-envelope-from'.") (defvar mail-self-blind nil "\ Non-nil means insert Bcc to self in messages to be sent. This is done when the message is initialized, -so you can remove or alter the Bcc field to override the default.") +so you can remove or alter the Bcc field to override the default. +If you are using `message-mode' to compose messages, customize the +variable `message-default-mail-headers' instead.") (custom-autoload 'mail-self-blind "sendmail" t) @@ -29104,14 +29135,18 @@ Line used to separate headers from text in messages being composed.") (defvar mail-archive-file-name nil "\ Name of file to write all outgoing messages in, or nil for none. This is normally an mbox file, but for backwards compatibility may also -be a Babyl file.") +be a Babyl file. +If you are using `message-mode' to compose messages, customize the +variable `message-default-mail-headers' instead.") (custom-autoload 'mail-archive-file-name "sendmail" t) (defvar mail-default-reply-to nil "\ Address to insert as default Reply-To field of outgoing messages. If nil, it will be initialized from the REPLYTO environment variable -when you first send mail.") +when you first send mail. +If you are using `message-mode' to compose messages, customize the +variable `message-default-mail-headers' instead.") (custom-autoload 'mail-default-reply-to "sendmail" t) @@ -29198,7 +29233,9 @@ in `message-auto-save-directory'.") (defvar mail-default-headers nil "\ A string containing header lines, to be inserted in outgoing messages. It can contain newlines, and should end in one. It is inserted -before you edit the message, so you can edit or delete the lines.") +before you edit the message, so you can edit or delete the lines. +If you are using `message-mode' to compose messages, customize the +variable `message-default-mail-headers' instead.") (custom-autoload 'mail-default-headers "sendmail" t) @@ -29887,10 +29924,6 @@ DOM should be a parse tree as generated by (autoload 'sieve-mode "sieve-mode" "\ Major mode for editing Sieve code. -This is much like C mode except for the syntax of comments. Its keymap -inherits from C mode's and it has the same variables for customizing -indentation. It has its own abbrev table and its own syntax table. - Turning on Sieve mode runs `sieve-mode-hook'. \(fn)" t nil) @@ -31532,7 +31565,7 @@ Truncate STRING to LENGTH, replacing initial surplus with \"...\". \(fn STRING LENGTH)" nil nil) -(register-definition-prefixes "subr-x" '("and-let*" "hash-table-" "if-let*" "internal--" "replace-region-contents" "string-" "thread-" "when-let*")) +(register-definition-prefixes "subr-x" '("and-let*" "hash-table-" "if-let*" "internal--" "named-let" "replace-region-contents" "string-" "thread-" "when-let*")) ;;;*** @@ -34174,7 +34207,7 @@ Add archive file name handler to `file-name-handler-alist'." (when tramp-archive ;;;### (autoloads nil "trampver" "net/trampver.el" (0 0 0 0)) ;;; Generated autoloads from net/trampver.el -(push (purecopy '(tramp 2 5 0)) package--builtin-versions) +(push (purecopy '(tramp 2 5 1 -1)) package--builtin-versions) (register-definition-prefixes "trampver" '("tramp-")) @@ -34542,9 +34575,9 @@ The variable `unrmail-mbox-format' controls which mbox format to use. (autoload 'unsafep "unsafep" "\ Return nil if evaluating FORM couldn't possibly do any harm. Otherwise result is a reason why FORM is unsafe. -UNSAFEP-VARS is a list of symbols with local bindings. +VARS is a list of symbols with local bindings like `unsafep-vars'. -\(fn FORM &optional UNSAFEP-VARS)" nil nil) +\(fn FORM &optional VARS)" nil nil) (register-definition-prefixes "unsafep" '("safe-functions" "unsafep-")) @@ -38493,43 +38526,43 @@ Zone out, completely." t nil) ;;;;;; "leim/quail/Punct-b5.el" "leim/quail/Punct.el" "leim/quail/QJ-b5.el" ;;;;;; "leim/quail/QJ.el" "leim/quail/SW.el" "leim/quail/TONEPY.el" ;;;;;; "leim/quail/ZIRANMA.el" "leim/quail/ZOZY.el" "leim/quail/arabic.el" -;;;;;; "leim/quail/compose.el" "leim/quail/croatian.el" "leim/quail/cyril-jis.el" -;;;;;; "leim/quail/cyrillic.el" "leim/quail/czech.el" "leim/quail/georgian.el" -;;;;;; "leim/quail/greek.el" "leim/quail/hanja-jis.el" "leim/quail/hanja.el" -;;;;;; "leim/quail/hanja3.el" "leim/quail/hebrew.el" "leim/quail/ipa-praat.el" -;;;;;; "leim/quail/latin-alt.el" "leim/quail/latin-ltx.el" "leim/quail/latin-post.el" -;;;;;; "leim/quail/latin-pre.el" "leim/quail/persian.el" "leim/quail/programmer-dvorak.el" -;;;;;; "leim/quail/py-punct.el" "leim/quail/pypunct-b5.el" "leim/quail/quick-b5.el" -;;;;;; "leim/quail/quick-cns.el" "leim/quail/rfc1345.el" "leim/quail/sami.el" -;;;;;; "leim/quail/sgml-input.el" "leim/quail/slovak.el" "leim/quail/symbol-ksc.el" -;;;;;; "leim/quail/tamil-dvorak.el" "leim/quail/tsang-b5.el" "leim/quail/tsang-cns.el" -;;;;;; "leim/quail/vntelex.el" "leim/quail/vnvni.el" "leim/quail/welsh.el" -;;;;;; "loadup.el" "mail/blessmail.el" "mail/rmailedit.el" "mail/rmailkwd.el" -;;;;;; "mail/rmailmm.el" "mail/rmailmsc.el" "mail/rmailsort.el" -;;;;;; "mail/rmailsum.el" "mail/undigest.el" "menu-bar.el" "mh-e/mh-gnus.el" -;;;;;; "mh-e/mh-loaddefs.el" "minibuffer.el" "mouse.el" "net/tramp-loaddefs.el" -;;;;;; "newcomment.el" "obarray.el" "org/ob-core.el" "org/ob-lob.el" -;;;;;; "org/ob-matlab.el" "org/ob-tangle.el" "org/ob.el" "org/ol-bbdb.el" -;;;;;; "org/ol-irc.el" "org/ol.el" "org/org-archive.el" "org/org-attach.el" -;;;;;; "org/org-clock.el" "org/org-colview.el" "org/org-compat.el" -;;;;;; "org/org-datetree.el" "org/org-duration.el" "org/org-element.el" -;;;;;; "org/org-feed.el" "org/org-footnote.el" "org/org-goto.el" -;;;;;; "org/org-id.el" "org/org-indent.el" "org/org-install.el" -;;;;;; "org/org-keys.el" "org/org-lint.el" "org/org-list.el" "org/org-macs.el" -;;;;;; "org/org-mobile.el" "org/org-num.el" "org/org-plot.el" "org/org-refile.el" -;;;;;; "org/org-table.el" "org/org-timer.el" "org/ox-ascii.el" "org/ox-beamer.el" -;;;;;; "org/ox-html.el" "org/ox-icalendar.el" "org/ox-latex.el" -;;;;;; "org/ox-md.el" "org/ox-odt.el" "org/ox-org.el" "org/ox-publish.el" -;;;;;; "org/ox-texinfo.el" "org/ox.el" "progmodes/elisp-mode.el" -;;;;;; "progmodes/prog-mode.el" "ps-mule.el" "register.el" "replace.el" -;;;;;; "rfn-eshadow.el" "select.el" "simple.el" "startup.el" "subdirs.el" -;;;;;; "subr.el" "tab-bar.el" "textmodes/fill.el" "textmodes/page.el" -;;;;;; "textmodes/paragraphs.el" "textmodes/reftex-auc.el" "textmodes/reftex-cite.el" -;;;;;; "textmodes/reftex-dcr.el" "textmodes/reftex-global.el" "textmodes/reftex-index.el" -;;;;;; "textmodes/reftex-parse.el" "textmodes/reftex-ref.el" "textmodes/reftex-sel.el" -;;;;;; "textmodes/reftex-toc.el" "textmodes/text-mode.el" "uniquify.el" -;;;;;; "vc/ediff-hook.el" "vc/vc-hooks.el" "version.el" "widget.el" -;;;;;; "window.el") (0 0 0 0)) +;;;;;; "leim/quail/cham.el" "leim/quail/compose.el" "leim/quail/croatian.el" +;;;;;; "leim/quail/cyril-jis.el" "leim/quail/cyrillic.el" "leim/quail/czech.el" +;;;;;; "leim/quail/georgian.el" "leim/quail/greek.el" "leim/quail/hanja-jis.el" +;;;;;; "leim/quail/hanja.el" "leim/quail/hanja3.el" "leim/quail/hebrew.el" +;;;;;; "leim/quail/ipa-praat.el" "leim/quail/latin-alt.el" "leim/quail/latin-ltx.el" +;;;;;; "leim/quail/latin-post.el" "leim/quail/latin-pre.el" "leim/quail/persian.el" +;;;;;; "leim/quail/programmer-dvorak.el" "leim/quail/py-punct.el" +;;;;;; "leim/quail/pypunct-b5.el" "leim/quail/quick-b5.el" "leim/quail/quick-cns.el" +;;;;;; "leim/quail/rfc1345.el" "leim/quail/sami.el" "leim/quail/sgml-input.el" +;;;;;; "leim/quail/slovak.el" "leim/quail/symbol-ksc.el" "leim/quail/tamil-dvorak.el" +;;;;;; "leim/quail/tsang-b5.el" "leim/quail/tsang-cns.el" "leim/quail/vntelex.el" +;;;;;; "leim/quail/vnvni.el" "leim/quail/welsh.el" "loadup.el" "mail/blessmail.el" +;;;;;; "mail/rmailedit.el" "mail/rmailkwd.el" "mail/rmailmm.el" +;;;;;; "mail/rmailmsc.el" "mail/rmailsort.el" "mail/rmailsum.el" +;;;;;; "mail/undigest.el" "menu-bar.el" "mh-e/mh-gnus.el" "mh-e/mh-loaddefs.el" +;;;;;; "minibuffer.el" "mouse.el" "net/tramp-loaddefs.el" "newcomment.el" +;;;;;; "obarray.el" "org/ob-core.el" "org/ob-lob.el" "org/ob-matlab.el" +;;;;;; "org/ob-tangle.el" "org/ob.el" "org/ol-bbdb.el" "org/ol-irc.el" +;;;;;; "org/ol.el" "org/org-archive.el" "org/org-attach.el" "org/org-clock.el" +;;;;;; "org/org-colview.el" "org/org-compat.el" "org/org-datetree.el" +;;;;;; "org/org-duration.el" "org/org-element.el" "org/org-feed.el" +;;;;;; "org/org-footnote.el" "org/org-goto.el" "org/org-id.el" "org/org-indent.el" +;;;;;; "org/org-install.el" "org/org-keys.el" "org/org-lint.el" +;;;;;; "org/org-list.el" "org/org-macs.el" "org/org-mobile.el" "org/org-num.el" +;;;;;; "org/org-plot.el" "org/org-refile.el" "org/org-table.el" +;;;;;; "org/org-timer.el" "org/ox-ascii.el" "org/ox-beamer.el" "org/ox-html.el" +;;;;;; "org/ox-icalendar.el" "org/ox-latex.el" "org/ox-md.el" "org/ox-odt.el" +;;;;;; "org/ox-org.el" "org/ox-publish.el" "org/ox-texinfo.el" "org/ox.el" +;;;;;; "progmodes/elisp-mode.el" "progmodes/prog-mode.el" "ps-mule.el" +;;;;;; "register.el" "replace.el" "rfn-eshadow.el" "select.el" "simple.el" +;;;;;; "startup.el" "subdirs.el" "subr.el" "tab-bar.el" "textmodes/fill.el" +;;;;;; "textmodes/page.el" "textmodes/paragraphs.el" "textmodes/reftex-auc.el" +;;;;;; "textmodes/reftex-cite.el" "textmodes/reftex-dcr.el" "textmodes/reftex-global.el" +;;;;;; "textmodes/reftex-index.el" "textmodes/reftex-parse.el" "textmodes/reftex-ref.el" +;;;;;; "textmodes/reftex-sel.el" "textmodes/reftex-toc.el" "textmodes/text-mode.el" +;;;;;; "uniquify.el" "vc/ediff-hook.el" "vc/vc-hooks.el" "version.el" +;;;;;; "widget.el" "window.el") (0 0 0 0)) ;;;*** commit 3b708f42682cf963e33aed3e8618c1a73c589743 Author: Stefan Kangas Date: Mon Feb 1 06:47:36 2021 +0100 * test/src/minibuf-tests.el (test-inhibit-interaction): Fix test. diff --git a/test/src/minibuf-tests.el b/test/src/minibuf-tests.el index 28119fc999..c55611eb84 100644 --- a/test/src/minibuf-tests.el +++ b/test/src/minibuf-tests.el @@ -412,11 +412,11 @@ (ert-deftest test-inhibit-interaction () (let ((inhibit-interaction t)) - (should-error (read-from-minibuffer "foo: ")) + (should-error (read-from-minibuffer "foo: ") :type 'inhibited-interaction) - (should-error (y-or-n-p "foo: ")) - (should-error (yes-or-no-p "foo: ")) - (should-error (read-blanks-no-input "foo: ")) + (should-error (y-or-n-p "foo: ") :type 'inhibited-interaction) + (should-error (yes-or-no-p "foo: ") :type 'inhibited-interaction) + (should-error (read-no-blanks-input "foo: ") :type 'inhibited-interaction) ;; See that we get the expected error. (should (eq (condition-case nil commit d987ca6f2267f5107a3e543fca4e8eaca983afa6 Author: Stefan Kangas Date: Mon Feb 1 06:12:15 2021 +0100 Remove another variable obsolete since Emacs 23.2 * src/keymap.c (syms_of_keymap, Fdefine_key): * lisp/subr.el (define-key-rebound-commands): Remove variable obsolete since Emacs 23.2. diff --git a/etc/NEWS b/etc/NEWS index 29499639e7..fc3a3dafb8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2108,8 +2108,9 @@ ledit.el, lmenu.el, lucid.el and old-whitespace.el. 'completion-base-size', 'completion-common-substring', 'crm-minibuffer-complete', 'crm-minibuffer-complete-and-exit', 'crm-minibuffer-completion-help', 'custom-mode', 'custom-mode-hook', -'define-mode-overload-implementation', 'detect-coding-with-priority', -'dirtrack-debug', 'dirtrack-debug-toggle', 'dynamic-completion-table', +'define-key-rebound-commands', 'define-mode-overload-implementation', +'detect-coding-with-priority', 'dirtrack-debug', +'dirtrack-debug-toggle', 'dynamic-completion-table', 'easy-menu-precalculate-equivalent-keybindings', 'epa-display-verify-result', 'epg-passphrase-callback-function', 'eshell-report-bug', 'eval-next-after-load', 'exchange-dot-and-mark', diff --git a/lisp/subr.el b/lisp/subr.el index a85f41d7d7..6e52bd20df 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1694,7 +1694,6 @@ be a list of the form returned by `event-start' and `event-end'." ;;;; Obsolescence declarations for variables, and aliases. -(make-obsolete-variable 'define-key-rebound-commands nil "23.2") (make-obsolete-variable 'redisplay-end-trigger-functions 'jit-lock-register "23.1") (make-obsolete-variable 'deferred-action-list 'post-command-hook "24.1") (make-obsolete-variable 'deferred-action-function 'post-command-hook "24.1") diff --git a/src/keymap.c b/src/keymap.c index de9b2b58c5..782931fadf 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -1065,9 +1065,6 @@ binding KEY to DEF is added at the front of KEYMAP. */) if (length == 0) return Qnil; - if (SYMBOLP (def) && !EQ (Vdefine_key_rebound_commands, Qt)) - Vdefine_key_rebound_commands = Fcons (def, Vdefine_key_rebound_commands); - int meta_bit = (VECTORP (key) || (STRINGP (key) && STRING_MULTIBYTE (key)) ? meta_modifier : 0x80); @@ -3132,12 +3129,6 @@ syms_of_keymap (void) pure_cons (build_pure_c_string ("SPC"), build_pure_c_string (" "))); staticpro (&exclude_keys); - DEFVAR_LISP ("define-key-rebound-commands", Vdefine_key_rebound_commands, - doc: /* List of commands given new key bindings recently. -This is used for internal purposes during Emacs startup; -don't alter it yourself. */); - Vdefine_key_rebound_commands = Qt; - DEFVAR_LISP ("minibuffer-local-map", Vminibuffer_local_map, doc: /* Default keymap to use when reading from the minibuffer. */); Vminibuffer_local_map = Fmake_sparse_keymap (Qnil); commit 9785c6d0a5f3fa2042f2fc8f08d3c33289c68688 Author: Stefan Kangas Date: Mon Feb 1 05:46:13 2021 +0100 * lisp/hi-lock.el (hi-lock-mode): Doc fix; don't mention Emacs 21. diff --git a/lisp/hi-lock.el b/lisp/hi-lock.el index e214ab640d..0ad499b4db 100644 --- a/lisp/hi-lock.el +++ b/lisp/hi-lock.el @@ -381,13 +381,7 @@ Hi-lock: end is found. A mode is excluded if it's in the list (warn "%s" "Possible archaic use of (hi-lock-mode). Use (global-hi-lock-mode 1) in .emacs to enable hi-lock for all buffers, -use (hi-lock-mode 1) for individual buffers. For compatibility with Emacs -versions before 22 use the following in your init file: - - (if (functionp 'global-hi-lock-mode) - (global-hi-lock-mode 1) - (hi-lock-mode 1)) -"))) +use (hi-lock-mode 1) for individual buffers."))) (if hi-lock-mode ;; Turned on. (progn commit 1fdd7a0a3aacd9792b9368ad9d750ef253e29165 Author: Stefan Kangas Date: Mon Feb 1 05:34:40 2021 +0100 Make XEmacs compat alias obsolete in allout-widgets.el * lisp/allout-widgets.el (allout-frame-property): Redefine compat alias as obsolete function alias for 'frame-parameter'. (allout-fetch-icon-image): Update caller. diff --git a/lisp/allout-widgets.el b/lisp/allout-widgets.el index 7dcf36851f..f251be8dfb 100644 --- a/lisp/allout-widgets.el +++ b/lisp/allout-widgets.el @@ -2231,7 +2231,7 @@ interactive command." We use a caching strategy, so the caller doesn't need to do so." (let* ((types allout-widgets-icon-types) - (use-dir (if (equal (allout-frame-property nil 'background-mode) + (use-dir (if (equal (frame-parameter nil 'background-mode) 'light) allout-widgets-icons-light-subdir allout-widgets-icons-dark-subdir)) @@ -2262,13 +2262,6 @@ We use a caching strategy, so the caller doesn't need to do so." "Return seconds between START/END time values." (let ((elapsed (time-subtract end start))) (float-time elapsed))) -;;;_ > allout-frame-property (frame property) -(defalias 'allout-frame-property - (cond ((fboundp 'frame-parameter) - 'frame-parameter) - ((fboundp 'frame-property) - 'frame-property) - (t nil))) ;;;_ > allout-find-image (specs) (define-obsolete-function-alias 'allout-find-image #'find-image "28.1") ;;;_ > allout-widgets-copy-list (list) @@ -2295,6 +2288,8 @@ The elements of LIST are not copied, just the list structure itself." (overlays-in start end))))) (length button-overlays))) +(define-obsolete-function-alias 'allout-frame-property #'frame-parameter "28.1") + ;;;_ : provide (provide 'allout-widgets) commit c322728e0d4ecd95237291c6b28c7221ffa8060b Author: Stefan Kangas Date: Mon Feb 1 05:33:02 2021 +0100 Redefine two functions as regular defuns * lisp/dframe.el (dframe-popup-kludge, dframe-mouse-event-p): Redefine as regular defun. diff --git a/lisp/dframe.el b/lisp/dframe.el index 09d2fe4079..23cb6c5a92 100644 --- a/lisp/dframe.el +++ b/lisp/dframe.el @@ -686,28 +686,26 @@ Evaluates all cached timer functions in sequence." (funcall (car l))) (setq l (cdr l))))) -(defalias 'dframe-popup-kludge - (lambda (e) - "Pop up a menu related to the clicked on item. +(defun dframe-popup-kludge (e) + "Pop up a menu related to the clicked on item. Must be bound to event E." - (interactive "e") - (save-excursion - (mouse-set-point e) - ;; This gets the cursor where the user can see it. - (if (not (bolp)) (forward-char -1)) - (sit-for 0) - (popup-menu (mouse-menu-major-mode-map) e)))) + (interactive "e") + (save-excursion + (mouse-set-point e) + ;; This gets the cursor where the user can see it. + (if (not (bolp)) (forward-char -1)) + (sit-for 0) + (popup-menu (mouse-menu-major-mode-map) e))) ;;; Interactive user functions for the mouse ;; -(defalias 'dframe-mouse-event-p - (lambda (event) - "Return t if the event is a mouse related event." - (if (and (listp event) - (member (event-basic-type event) - '(mouse-1 mouse-2 mouse-3))) - t - nil))) +(defun dframe-mouse-event-p (event) + "Return t if the event is a mouse related event." + (if (and (listp event) + (member (event-basic-type event) + '(mouse-1 mouse-2 mouse-3))) + t + nil)) (defun dframe-track-mouse (event) "For motion EVENT, display info about the current line." commit 7de495a7c14f24d494e3391e7655130867c21e27 Author: Stefan Kangas Date: Mon Feb 1 05:32:16 2021 +0100 Make two eshell aliases obsolete * lisp/eshell/esh-util.el (eshell-user-name): Redefine as obsolete function alias for 'user-login-name'. (eshell-copy-tree): Redefine as obsolete function alias for 'copy-tree'. * lisp/eshell/esh-cmd.el (eshell-do-eval): Don't use above obsolete alias. diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index 4d63467899..daca035ea4 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el @@ -1001,7 +1001,7 @@ be finished later after the completion of an asynchronous subprocess." ;; expand any macros directly into the form. This is done so that ;; we can modify any `let' forms to evaluate only once. (if (macrop (car form)) - (let ((exp (eshell-copy-tree (macroexpand form)))) + (let ((exp (copy-tree (macroexpand form)))) (eshell-manipulate (format-message "expanding macro `%s'" (symbol-name (car form))) (setcar form (car exp)) @@ -1009,7 +1009,7 @@ be finished later after the completion of an asynchronous subprocess." (let ((args (cdr form))) (cond ((eq (car form) 'while) - ;; `eshell-copy-tree' is needed here so that the test argument + ;; `copy-tree' is needed here so that the test argument ;; doesn't get modified and thus always yield the same result. (when (car eshell-command-body) (cl-assert (not synchronous-p)) @@ -1017,27 +1017,27 @@ be finished later after the completion of an asynchronous subprocess." (setcar eshell-command-body nil) (setcar eshell-test-body nil)) (unless (car eshell-test-body) - (setcar eshell-test-body (eshell-copy-tree (car args)))) + (setcar eshell-test-body (copy-tree (car args)))) (while (cadr (eshell-do-eval (car eshell-test-body))) (setcar eshell-command-body (if (cddr args) - `(progn ,@(eshell-copy-tree (cdr args))) - (eshell-copy-tree (cadr args)))) + `(progn ,@(copy-tree (cdr args))) + (copy-tree (cadr args)))) (eshell-do-eval (car eshell-command-body) synchronous-p) (setcar eshell-command-body nil) - (setcar eshell-test-body (eshell-copy-tree (car args)))) + (setcar eshell-test-body (copy-tree (car args)))) (setcar eshell-command-body nil)) ((eq (car form) 'if) - ;; `eshell-copy-tree' is needed here so that the test argument + ;; `copy-tree' is needed here so that the test argument ;; doesn't get modified and thus always yield the same result. (if (car eshell-command-body) (progn (cl-assert (not synchronous-p)) (eshell-do-eval (car eshell-command-body))) (unless (car eshell-test-body) - (setcar eshell-test-body (eshell-copy-tree (car args)))) + (setcar eshell-test-body (copy-tree (car args)))) (setcar eshell-command-body - (eshell-copy-tree + (copy-tree (if (cadr (eshell-do-eval (car eshell-test-body))) (cadr args) (car (cddr args))))) diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el index 872e3b5204..0b5cf193a1 100644 --- a/lisp/eshell/esh-util.el +++ b/lisp/eshell/esh-util.el @@ -486,8 +486,6 @@ list." "Return the user id for user NAME." (car (rassoc name (eshell-read-user-names)))) -(defalias 'eshell-user-name 'user-login-name) - (autoload 'pcomplete-read-hosts-file "pcomplete") (autoload 'pcomplete-read-hosts "pcomplete") (autoload 'pcomplete-read-host-names "pcomplete") @@ -644,8 +642,6 @@ gid format. Valid values are `string' and `integer', defaulting to entry) (file-attributes file id-format)))) -(defalias 'eshell-copy-tree 'copy-tree) - (defsubst eshell-processp (proc) "If the `processp' function does not exist, PROC is not a process." (and (fboundp 'processp) (processp proc))) @@ -715,6 +711,9 @@ gid format. Valid values are `string' and `integer', defaulting to ; (or result ; (file-attributes filename)))) +(define-obsolete-function-alias 'eshell-copy-tree #'copy-tree "28.1") +(define-obsolete-function-alias 'eshell-user-name #'user-login-name "28.1") + (provide 'esh-util) ;;; esh-util.el ends here commit f215332c8be43ef0dc838e2a63012aba791818c2 Author: Stefan Kangas Date: Mon Feb 1 01:43:29 2021 +0100 Add cross-references to defvar-local * src/data.c (Fmake_variable_buffer_local): * src/eval.c (Fdefvar): Add cross-references to 'defvar-local'. diff --git a/src/data.c b/src/data.c index 35a6890b9b..38cde0ff8b 100644 --- a/src/data.c +++ b/src/data.c @@ -1819,7 +1819,9 @@ a variable local to the current buffer for one particular use, use while setting up a new major mode, unless they have a `permanent-local' property. -The function `default-value' gets the default value and `set-default' sets it. */) +The function `default-value' gets the default value and `set-default' sets it. + +See also `defvar-local'. */) (register Lisp_Object variable) { struct Lisp_Symbol *sym; diff --git a/src/eval.c b/src/eval.c index 5bf3faebc8..3aff3b56d5 100644 --- a/src/eval.c +++ b/src/eval.c @@ -818,6 +818,8 @@ The optional argument DOCSTRING is a documentation string for the variable. To define a user option, use `defcustom' instead of `defvar'. + +To define a buffer-local variable, use `defvar-local'. usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) (Lisp_Object args) { commit a6be18461471b0889ded6084693664927a041704 Author: Lars Ingebrigtsen Date: Mon Feb 1 10:42:22 2021 +0100 Fix indentation of non-comment HTML with -- in it * lisp/textmodes/sgml-mode.el (sgml-comment-indent-new-line): Only indent as if we're in a comment if syntax-ppss says that we're in a comment (bug#36227). diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el index 3e29f055ec..7051f520b9 100644 --- a/lisp/textmodes/sgml-mode.el +++ b/lisp/textmodes/sgml-mode.el @@ -510,10 +510,12 @@ an optional alist of possible values." (with-no-warnings (defvar v2)) ; free for skeleton (defun sgml-comment-indent-new-line (&optional soft) - (let ((comment-start "-- ") - (comment-start-skip "\\( Date: Sun Jan 31 22:39:45 2021 -0500 * lisp/eshell/em-cmpl.el (eshell--complete-commands-list): Fix last fix Complete `*firef` to `*firefox` rather than to `firefox`. diff --git a/lisp/eshell/em-cmpl.el b/lisp/eshell/em-cmpl.el index e0b3ab1ecf..638c0ac230 100644 --- a/lisp/eshell/em-cmpl.el +++ b/lisp/eshell/em-cmpl.el @@ -91,27 +91,23 @@ variable names, arguments, etc." (defcustom eshell-cmpl-load-hook nil "A list of functions to run when `eshell-cmpl' is loaded." :version "24.1" ; removed eshell-cmpl-initialize - :type 'hook - :group 'eshell-cmpl) + :type 'hook) (defcustom eshell-show-lisp-completions nil "If non-nil, include Lisp functions in the command completion list. If this variable is nil, Lisp completion can still be done in command position by using M-TAB instead of TAB." - :type 'boolean - :group 'eshell-cmpl) + :type 'boolean) (defcustom eshell-show-lisp-alternatives t "If non-nil, and no other completions found, show Lisp functions. Setting this variable means nothing if `eshell-show-lisp-completions' is non-nil." - :type 'boolean - :group 'eshell-cmpl) + :type 'boolean) (defcustom eshell-no-completion-during-jobs t "If non-nil, don't allow completion while a process is running." - :type 'boolean - :group 'eshell-cmpl) + :type 'boolean) (defcustom eshell-command-completions-alist '(("acroread" . "\\.pdf\\'") @@ -136,8 +132,7 @@ is non-nil." "An alist that defines simple argument type correlations. This is provided for common commands, as a simplistic alternative to writing a completion function." - :type '(repeat (cons string regexp)) - :group 'eshell-cmpl) + :type '(repeat (cons string regexp))) (defun eshell-cmpl--custom-variable-docstring (pcomplete-var) "Generate the docstring of a variable derived from a pcomplete-* variable." @@ -148,23 +143,19 @@ to writing a completion function." (defcustom eshell-cmpl-file-ignore "~\\'" (eshell-cmpl--custom-variable-docstring 'pcomplete-file-ignore) - :type (get 'pcomplete-file-ignore 'custom-type) - :group 'eshell-cmpl) + :type (get 'pcomplete-file-ignore 'custom-type)) (defcustom eshell-cmpl-dir-ignore "\\`\\(\\.\\.?\\|CVS\\)/\\'" (eshell-cmpl--custom-variable-docstring 'pcomplete-dir-ignore) - :type (get 'pcomplete-dir-ignore 'custom-type) - :group 'eshell-cmpl) + :type (get 'pcomplete-dir-ignore 'custom-type)) (defcustom eshell-cmpl-ignore-case (eshell-under-windows-p) (eshell-cmpl--custom-variable-docstring 'pcomplete-ignore-case) - :type (get 'pcomplete-ignore-case 'custom-type) - :group 'eshell-cmpl) + :type (get 'pcomplete-ignore-case 'custom-type)) (defcustom eshell-cmpl-autolist nil (eshell-cmpl--custom-variable-docstring 'pcomplete-autolist) - :type (get 'pcomplete-autolist 'custom-type) - :group 'eshell-cmpl) + :type (get 'pcomplete-autolist 'custom-type)) (defcustom eshell-cmpl-suffix-list (list ?/ ?:) (eshell-cmpl--custom-variable-docstring 'pcomplete-suffix-list) @@ -176,51 +167,42 @@ to writing a completion function." (defcustom eshell-cmpl-recexact nil (eshell-cmpl--custom-variable-docstring 'pcomplete-recexact) - :type (get 'pcomplete-recexact 'custom-type) - :group 'eshell-cmpl) + :type (get 'pcomplete-recexact 'custom-type)) -(defcustom eshell-cmpl-man-function 'man +(defcustom eshell-cmpl-man-function #'man (eshell-cmpl--custom-variable-docstring 'pcomplete-man-function) - :type (get 'pcomplete-man-function 'custom-type) - :group 'eshell-cmpl) + :type (get 'pcomplete-man-function 'custom-type)) -(defcustom eshell-cmpl-compare-entry-function 'file-newer-than-file-p +(defcustom eshell-cmpl-compare-entry-function #'file-newer-than-file-p (eshell-cmpl--custom-variable-docstring 'pcomplete-compare-entry-function) - :type (get 'pcomplete-compare-entry-function 'custom-type) - :group 'eshell-cmpl) + :type (get 'pcomplete-compare-entry-function 'custom-type)) (defcustom eshell-cmpl-expand-before-complete nil (eshell-cmpl--custom-variable-docstring 'pcomplete-expand-before-complete) - :type (get 'pcomplete-expand-before-complete 'custom-type) - :group 'eshell-cmpl) + :type (get 'pcomplete-expand-before-complete 'custom-type)) (defcustom eshell-cmpl-cycle-completions t (eshell-cmpl--custom-variable-docstring 'pcomplete-cycle-completions) - :type (get 'pcomplete-cycle-completions 'custom-type) - :group 'eshell-cmpl) + :type (get 'pcomplete-cycle-completions 'custom-type)) (defcustom eshell-cmpl-cycle-cutoff-length 5 (eshell-cmpl--custom-variable-docstring 'pcomplete-cycle-cutoff-length) - :type (get 'pcomplete-cycle-cutoff-length 'custom-type) - :group 'eshell-cmpl) + :type (get 'pcomplete-cycle-cutoff-length 'custom-type)) (defcustom eshell-cmpl-restore-window-delay 1 (eshell-cmpl--custom-variable-docstring 'pcomplete-restore-window-delay) - :type (get 'pcomplete-restore-window-delay 'custom-type) - :group 'eshell-cmpl) + :type (get 'pcomplete-restore-window-delay 'custom-type)) (defcustom eshell-command-completion-function (lambda () (pcomplete-here (eshell--complete-commands-list))) (eshell-cmpl--custom-variable-docstring 'pcomplete-command-completion-function) - :type (get 'pcomplete-command-completion-function 'custom-type) - :group 'eshell-cmpl) + :type (get 'pcomplete-command-completion-function 'custom-type)) (defcustom eshell-cmpl-command-name-function - 'eshell-completion-command-name + #'eshell-completion-command-name (eshell-cmpl--custom-variable-docstring 'pcomplete-command-name-function) - :type (get 'pcomplete-command-name-function 'custom-type) - :group 'eshell-cmpl) + :type (get 'pcomplete-command-name-function 'custom-type)) (defcustom eshell-default-completion-function (lambda () @@ -229,13 +211,11 @@ to writing a completion function." (cdr (assoc (funcall eshell-cmpl-command-name-function) eshell-command-completions-alist)))))) (eshell-cmpl--custom-variable-docstring 'pcomplete-default-completion-function) - :type (get 'pcomplete-default-completion-function 'custom-type) - :group 'eshell-cmpl) + :type (get 'pcomplete-default-completion-function 'custom-type)) (defcustom eshell-cmpl-use-paring t (eshell-cmpl--custom-variable-docstring 'pcomplete-use-paring) - :type (get 'pcomplete-use-paring 'custom-type) - :group 'eshell-cmpl) + :type (get 'pcomplete-use-paring 'custom-type)) ;;; Functions: @@ -274,7 +254,7 @@ to writing a completion function." (setq-local pcomplete-default-completion-function eshell-default-completion-function) (setq-local pcomplete-parse-arguments-function - 'eshell-complete-parse-arguments) + #'eshell-complete-parse-arguments) (setq-local pcomplete-file-ignore eshell-cmpl-file-ignore) (setq-local pcomplete-dir-ignore @@ -407,20 +387,19 @@ to writing a completion function." "Generate list of applicable, visible commands." ;; Building the commands list can take quite a while, especially over Tramp ;; (bug#41423), so do it lazily. - (completion-table-dynamic - (lambda (filename) - (if (file-name-directory filename) - (if eshell-force-execution - (pcomplete-dirs-or-entries nil #'file-readable-p) - (pcomplete-executables)) - (let (glob-name) - (if (and (> (length filename) 0) - (eq (aref filename 0) eshell-explicit-command-char)) - ;; FIXME: Shouldn't we handle this `*' outside of the - ;; `pcomplete-here' in `eshell-command-completion-function'? - (setq filename (substring filename 1) - pcomplete-stub filename - glob-name t)) + (let ((glob-name + ;; When a command is specified using `eshell-explicit-command-char', + ;; that char is not part of the command and hence not part of what + ;; we complete. Adjust `pcomplete-stub' accordingly! + (if (and (> (length pcomplete-stub) 0) + (eq (aref pcomplete-stub 0) eshell-explicit-command-char)) + (setq pcomplete-stub (substring pcomplete-stub 1))))) + (completion-table-dynamic + (lambda (filename) + (if (file-name-directory filename) + (if eshell-force-execution + (pcomplete-dirs-or-entries nil #'file-readable-p) + (pcomplete-executables)) (let* ((paths (eshell-get-path)) (cwd (file-name-as-directory (expand-file-name default-directory))) commit 82c76e3aeb2465d1d1e66eae5db13ba53e38ed84 Author: Stefan Monnier Date: Sun Jan 31 19:27:10 2021 -0500 * lisp/eshell/em-cmpl.el: Try and fix bug#41423 (eshell--complete-commands-list): Rename from `eshell-complete-commands-list`. Return a (dynamic) completion table rather than a list of completions. Use `dolist` and `push`. diff --git a/lisp/eshell/em-cmpl.el b/lisp/eshell/em-cmpl.el index 0200631da6..e0b3ab1ecf 100644 --- a/lisp/eshell/em-cmpl.el +++ b/lisp/eshell/em-cmpl.el @@ -211,7 +211,7 @@ to writing a completion function." (defcustom eshell-command-completion-function (lambda () - (pcomplete-here (eshell-complete-commands-list))) + (pcomplete-here (eshell--complete-commands-list))) (eshell-cmpl--custom-variable-docstring 'pcomplete-command-completion-function) :type (get 'pcomplete-command-completion-function 'custom-type) :group 'eshell-cmpl) @@ -403,64 +403,66 @@ to writing a completion function." args) posns))) -(defun eshell-complete-commands-list () +(defun eshell--complete-commands-list () "Generate list of applicable, visible commands." - (let ((filename (pcomplete-arg)) glob-name) - (if (file-name-directory filename) - (if eshell-force-execution - (pcomplete-dirs-or-entries nil #'file-readable-p) - (pcomplete-executables)) - (if (and (> (length filename) 0) - (eq (aref filename 0) eshell-explicit-command-char)) - (setq filename (substring filename 1) - pcomplete-stub filename - glob-name t)) - (let* ((paths (eshell-get-path)) - (cwd (file-name-as-directory - (expand-file-name default-directory))) - (path "") (comps-in-path ()) - (file "") (filepath "") (completions ())) - ;; Go thru each path in the search path, finding completions. - (while paths - (setq path (file-name-as-directory - (expand-file-name (or (car paths) "."))) - comps-in-path - (and (file-accessible-directory-p path) - (file-name-all-completions filename path))) - ;; Go thru each completion found, to see whether it should - ;; be used. - (while comps-in-path - (setq file (car comps-in-path) - filepath (concat path file)) - (if (and (not (member file completions)) ; - (or (string-equal path cwd) - (not (file-directory-p filepath))) - (if eshell-force-execution - (file-readable-p filepath) - (file-executable-p filepath))) - (setq completions (cons file completions))) - (setq comps-in-path (cdr comps-in-path))) - (setq paths (cdr paths))) - ;; Add aliases which are currently visible, and Lisp functions. - (pcomplete-uniquify-list - (if glob-name - completions - (setq completions - (append (if (fboundp 'eshell-alias-completions) - (eshell-alias-completions filename)) - (eshell-winnow-list - (mapcar - (lambda (name) - (substring name 7)) - (all-completions (concat "eshell/" filename) - obarray #'functionp)) - nil '(eshell-find-alias-function)) - completions)) - (append (and (or eshell-show-lisp-completions - (and eshell-show-lisp-alternatives - (null completions))) - (all-completions filename obarray #'functionp)) - completions))))))) + ;; Building the commands list can take quite a while, especially over Tramp + ;; (bug#41423), so do it lazily. + (completion-table-dynamic + (lambda (filename) + (if (file-name-directory filename) + (if eshell-force-execution + (pcomplete-dirs-or-entries nil #'file-readable-p) + (pcomplete-executables)) + (let (glob-name) + (if (and (> (length filename) 0) + (eq (aref filename 0) eshell-explicit-command-char)) + ;; FIXME: Shouldn't we handle this `*' outside of the + ;; `pcomplete-here' in `eshell-command-completion-function'? + (setq filename (substring filename 1) + pcomplete-stub filename + glob-name t)) + (let* ((paths (eshell-get-path)) + (cwd (file-name-as-directory + (expand-file-name default-directory))) + (filepath "") (completions ())) + ;; Go thru each path in the search path, finding completions. + (dolist (path paths) + (setq path (file-name-as-directory + (expand-file-name (or path ".")))) + ;; Go thru each completion found, to see whether it should + ;; be used. + (dolist (file (and (file-accessible-directory-p path) + (file-name-all-completions filename path))) + (setq filepath (concat path file)) + (if (and (not (member file completions)) ; + (or (string-equal path cwd) + (not (file-directory-p filepath))) + ;; FIXME: Those repeated file tests end up + ;; very costly over Tramp, we should cache the result. + (if eshell-force-execution + (file-readable-p filepath) + (file-executable-p filepath))) + (push file completions)))) + ;; Add aliases which are currently visible, and Lisp functions. + (pcomplete-uniquify-list + (if glob-name + completions + (setq completions + (append (if (fboundp 'eshell-alias-completions) + (eshell-alias-completions filename)) + (eshell-winnow-list + (mapcar + (lambda (name) + (substring name 7)) + (all-completions (concat "eshell/" filename) + obarray #'functionp)) + nil '(eshell-find-alias-function)) + completions)) + (append (and (or eshell-show-lisp-completions + (and eshell-show-lisp-alternatives + (null completions))) + (all-completions filename obarray #'functionp)) + completions))))))))) (define-obsolete-function-alias 'eshell-pcomplete #'completion-at-point "27.1") commit dc78f8a4ead88744c258ae712adb4fbbb65ec539 Author: Thomas Fitzsimmons Date: Sun Jan 31 18:36:52 2021 -0500 url-http.el: Special-case NTLM authentication * lisp/url/url-http.el (url-http-handle-authentication): Do not signal an error on NTLM authorization strings. (Bug#43566) diff --git a/lisp/url/url-http.el b/lisp/url/url-http.el index b4d7d333f3..473da6f84c 100644 --- a/lisp/url/url-http.el +++ b/lisp/url/url-http.el @@ -461,8 +461,10 @@ Return the number of characters removed." ;; headers, then this means that we've already tried sending ;; credentials to the server, and they were wrong, so just give ;; up. - (when (assoc "Authorization" url-http-extra-headers) - (error "Wrong authorization used for %s" url)) + (let ((authorization (assoc "Authorization" url-http-extra-headers))) + (when (and authorization + (not (string-match "^NTLM " (cdr authorization)))) + (error "Wrong authorization used for %s" url))) ;; find strongest supported auth (dolist (this-auth auths) commit 24b9515da0588aca38a1bce5f615e0cdf7891388 Author: Stefan Monnier Date: Sun Jan 31 18:00:39 2021 -0500 * admin/*.el: Use lexical-binding * admin/admin.el: Use lexical-binding. (manual-misc-manuals): Pass a limit to `looking-back`. (reminder-for-release-blocking-bugs): Don't use `_` for a real variable. * admin/authors.el: Use lexical-binding. (authors-disambiguate-file-name): Remove unused var `parent`. * admin/cus-test.el: * admin/find-gc.el: * admin/gitmerge.el: Use lexical-binding. diff --git a/admin/admin.el b/admin/admin.el index fa96b7e5ca..d032c1ceb8 100644 --- a/admin/admin.el +++ b/admin/admin.el @@ -1,4 +1,4 @@ -;;; admin.el --- utilities for Emacs administration +;;; admin.el --- utilities for Emacs administration -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. @@ -254,7 +254,7 @@ ROOT should be the root of an Emacs source tree." (search-forward "INFO_COMMON = ") (let ((start (point))) (end-of-line) - (while (and (looking-back "\\\\") + (while (and (looking-back "\\\\" (- (point) 2)) (zerop (forward-line 1))) (end-of-line)) (append (split-string (replace-regexp-in-string @@ -930,13 +930,19 @@ changes (in a non-trivial way). This function does not check for that." (interactive (list (progn (require 'debbugs-gnu) + (defvar debbugs-gnu-emacs-blocking-reports) + (defvar debbugs-gnu-emacs-current-release) (completing-read "Emacs release: " (mapcar #'identity debbugs-gnu-emacs-blocking-reports) nil t debbugs-gnu-emacs-current-release)))) (require 'debbugs-gnu) + (declare-function debbugs-get-status "debbugs" (&rest bug-numbers)) + (declare-function debbugs-get-attribute "debbugs" (bug-or-message attribute)) (require 'reporter) + (declare-function mail-position-on-field "sendmail" (field &optional soft)) + (declare-function mail-text "sendmail" ()) (when-let ((id (alist-get version debbugs-gnu-emacs-blocking-reports nil nil #'string-equal)) @@ -958,11 +964,11 @@ changes (in a non-trivial way). This function does not check for that." (insert " The following bugs are regarded as release-blocking for Emacs " version ". People are encouraged to work on them with priority.\n\n") - (dolist (_ blockedby-status) - (unless (equal (debbugs-get-attribute _ 'pending) "done") + (dolist (i blockedby-status) + (unless (equal (debbugs-get-attribute i 'pending) "done") (insert (format "bug#%d %s\n" - (debbugs-get-attribute _ 'id) - (debbugs-get-attribute _ 'subject))))) + (debbugs-get-attribute i 'id) + (debbugs-get-attribute i 'subject))))) (insert " If you use the debbugs package from GNU ELPA, you can apply the following form to see all bugs which block a given release: diff --git a/admin/authors.el b/admin/authors.el index 0180ffea25..6c81c7872f 100644 --- a/admin/authors.el +++ b/admin/authors.el @@ -1,4 +1,4 @@ -;;; authors.el --- utility for maintaining Emacs's AUTHORS file +;;; authors.el --- utility for maintaining Emacs's AUTHORS file -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. @@ -1254,7 +1254,7 @@ Additionally, for these logs we apply the `lax' elements of (defun authors-disambiguate-file-name (fullname) "Convert FULLNAME to an unambiguous relative-name." (let ((relname (file-name-nondirectory fullname)) - dir parent) + dir) (if (and (member relname authors-ambiguous-files) ;; Try to identify the top-level directory. ;; FIXME should really use ROOT from M-x authors. @@ -1266,8 +1266,8 @@ Additionally, for these logs we apply the `lax' elements of ;; I think it looks weird to see eg "lisp/simple.el". ;; But for eg Makefile.in, we do want to say "lisp/Makefile.in". (if (and (string-equal "lisp" - (setq parent (file-name-nondirectory - (directory-file-name dir)))) + (file-name-nondirectory + (directory-file-name dir))) ;; TODO better to simply have hard-coded list? ;; Only really Makefile.in where this applies. (not (file-exists-p @@ -1569,9 +1569,9 @@ and changed by AUTHOR." (cons (cons file (cdr (assq :changed actions))) changed-list)))))) (if wrote-list - (setq wrote-list (sort wrote-list 'string-lessp))) + (setq wrote-list (sort wrote-list #'string-lessp))) (if cowrote-list - (setq cowrote-list (sort cowrote-list 'string-lessp))) + (setq cowrote-list (sort cowrote-list #'string-lessp))) (when changed-list (setq changed-list (sort changed-list (lambda (a b) @@ -1579,7 +1579,7 @@ and changed by AUTHOR." (string-lessp (car a) (car b)) (> (cdr a) (cdr b)))))) (setq nchanged (length changed-list)) - (setq changed-list (mapcar 'car changed-list))) + (setq changed-list (mapcar #'car changed-list))) (if (> (- nchanged authors-many-files) 2) (setcdr (nthcdr authors-many-files changed-list) (list (format "and %d other files" (- nchanged authors-many-files))))) @@ -1688,12 +1688,12 @@ list of their contributions.\n") (when authors-invalid-file-names (insert "Unrecognized file entries found:\n\n") (mapc (lambda (f) (if (not (string-match "^[A-Za-z]+$" f)) (insert f "\n"))) - (sort authors-invalid-file-names 'string-lessp))) + (sort authors-invalid-file-names #'string-lessp))) (when authors-ignored-names (insert "\n\nThese authors were ignored:\n\n" (mapconcat - 'identity - (sort authors-ignored-names 'string-lessp) "\n"))) + #'identity + (sort authors-ignored-names #'string-lessp) "\n"))) (goto-char (point-min)) (compilation-mode) (message "Errors were found. See buffer %s" (buffer-name)))) diff --git a/admin/cus-test.el b/admin/cus-test.el index aca7b68aa7..995586f9c7 100644 --- a/admin/cus-test.el +++ b/admin/cus-test.el @@ -1,4 +1,4 @@ -;;; cus-test.el --- tests for custom types and load problems +;;; cus-test.el --- tests for custom types and load problems -*- lexical-binding: t; -*- ;; Copyright (C) 1998, 2000, 2002-2021 Free Software Foundation, Inc. @@ -112,6 +112,7 @@ Names should be as they appear in loaddefs.el.") ;; This avoids a hang of `cus-test-apropos' in 21.2. ;; (add-to-list 'cus-test-skip-list 'sh-alias-alist) +(defvar viper-mode) (or noninteractive ;; Never Viperize. (setq viper-mode nil)) @@ -196,7 +197,7 @@ The detected problematic options are stored in `cus-test-errors'." mismatch) (when (default-boundp symbol) (push (funcall get symbol) values) - (push (eval (car (get symbol 'standard-value))) values)) + (push (eval (car (get symbol 'standard-value)) t) values)) (if (boundp symbol) (push (symbol-value symbol) values)) ;; That does not work. @@ -222,7 +223,7 @@ The detected problematic options are stored in `cus-test-errors'." (get symbol 'standard-value)))) (and (consp c-value) (boundp symbol) - (not (equal (eval (car c-value)) (symbol-value symbol))) + (not (equal (eval (car c-value) t) (symbol-value symbol))) (add-to-list 'cus-test-vars-with-changed-state symbol))) (if mismatch @@ -239,7 +240,7 @@ The detected problematic options are stored in `cus-test-errors'." (defun cus-test-cus-load-groups (&optional cus-load) "Return a list of current custom groups. If CUS-LOAD is non-nil, include groups from cus-load.el." - (append (mapcar 'cdr custom-current-group-alist) + (append (mapcar #'cdr custom-current-group-alist) (if cus-load (with-temp-buffer (insert-file-contents (locate-library "cus-load.el")) @@ -290,7 +291,7 @@ currently defined groups." "Call `custom-load-symbol' on all atoms." (interactive) (if noninteractive (let (noninteractive) (require 'dunnet))) - (mapatoms 'custom-load-symbol) + (mapatoms #'custom-load-symbol) (run-hooks 'cus-test-after-load-libs-hook)) (defmacro cus-test-load-1 (&rest body) @@ -346,7 +347,7 @@ Optional argument ALL non-nil means list all (non-obsolete) Lisp files." (prog1 ;; Hack to remove leading "./". (mapcar (lambda (e) (substring e 2)) - (apply 'process-lines find-program + (apply #'process-lines find-program "." "-name" "obsolete" "-prune" "-o" "-name" "[^.]*.el" ; ignore .dir-locals.el (if all @@ -542,7 +543,7 @@ in the Emacs source directory." (message "No options not loaded by custom-load-symbol found") (message "The following options were not loaded by custom-load-symbol:") (cus-test-message - (sort cus-test-vars-not-cus-loaded 'string<))) + (sort cus-test-vars-not-cus-loaded #'string<))) (dolist (o groups-loaded) (setq groups-not-loaded (delete o groups-not-loaded))) @@ -550,7 +551,7 @@ in the Emacs source directory." (if (not groups-not-loaded) (message "No groups not in cus-load.el found") (message "The following groups are not in cus-load.el:") - (cus-test-message (sort groups-not-loaded 'string<))))) + (cus-test-message (sort groups-not-loaded #'string<))))) (provide 'cus-test) diff --git a/admin/find-gc.el b/admin/find-gc.el index c70a051bfb..1cce54ef14 100644 --- a/admin/find-gc.el +++ b/admin/find-gc.el @@ -1,4 +1,4 @@ -;;; find-gc.el --- detect functions that call the garbage collector +;;; find-gc.el --- detect functions that call the garbage collector -*- lexical-binding: t; -*- ;; Copyright (C) 1992, 2001-2021 Free Software Foundation, Inc. @@ -42,14 +42,14 @@ Each entry has the form (FUNCTION . FUNCTIONS-THAT-CALL-IT).") Each entry has the form (FUNCTION . FUNCTIONS-IT-CALLS).") -;;; Functions on this list are safe, even if they appear to be able -;;; to call the target. +;; Functions on this list are safe, even if they appear to be able +;; to call the target. (defvar find-gc-noreturn-list '(Fsignal Fthrow wrong_type_argument)) -;;; This was originally generated directory-files, but there were -;;; too many files there that were not actually compiled. The -;;; list below was created for a HP-UX 7.0 system. +;; This was originally generated directory-files, but there were +;; too many files there that were not actually compiled. The +;; list below was created for a HP-UX 7.0 system. (defvar find-gc-source-files '("dispnew.c" "scroll.c" "xdisp.c" "window.c" @@ -76,11 +76,11 @@ Also store it in `find-gc-unsafe-list'." (lambda (x y) (string-lessp (car x) (car y)))))) -;;; This does a depth-first search to find all functions that can -;;; ultimately call the function "target". The result is an a-list -;;; in find-gc-unsafe-list; the cars are the unsafe functions, and the cdrs -;;; are (one of) the unsafe functions that these functions directly -;;; call. +;; This does a depth-first search to find all functions that can +;; ultimately call the function "target". The result is an a-list +;; in find-gc-unsafe-list; the cars are the unsafe functions, and the cdrs +;; are (one of) the unsafe functions that these functions directly +;; call. (defun find-unsafe-funcs (target) (setq find-gc-unsafe-list (list (list target))) @@ -134,7 +134,8 @@ Also store it in `find-gc-unsafe-list'." (setcdr entry (cons name (cdr entry))))))))))))) (defun trace-use-tree () - (setq find-gc-subrs-callers (mapcar 'list (mapcar 'car find-gc-subrs-called))) + (setq find-gc-subrs-callers + (mapcar #'list (mapcar #'car find-gc-subrs-called))) (let ((ptr find-gc-subrs-called) p2 found) (while ptr diff --git a/admin/gitmerge.el b/admin/gitmerge.el index 1364bdc67a..b92ecc7c78 100644 --- a/admin/gitmerge.el +++ b/admin/gitmerge.el @@ -1,4 +1,4 @@ -;;; gitmerge.el --- help merge one Emacs branch into another +;;; gitmerge.el --- help merge one Emacs branch into another -*- lexical-binding: t; -*- ;; Copyright (C) 2010-2021 Free Software Foundation, Inc. @@ -390,7 +390,7 @@ is nil, only the single commit BEG is merged." (if end "s were " " was ") "skipped:\n\n") "")) - (apply 'call-process "git" nil t nil "log" "--oneline" + (apply #'call-process "git" nil t nil "log" "--oneline" (if end (list (concat beg "~.." end)) `("-1" ,beg))) (insert "\n") @@ -422,7 +422,7 @@ MISSING must be a list of SHA1 strings." (unless end (setq end beg)) (unless (zerop - (apply 'call-process "git" nil t nil "merge" "--no-ff" + (apply #'call-process "git" nil t nil "merge" "--no-ff" (append (when skip '("-s" "ours")) `("-m" ,commitmessage ,end)))) (gitmerge-write-missing missing from) commit 11abc4aef42ceaea451c264e5a7292e765d4f31b Merge: cb72b8345b d2341eb0fb Author: Stefan Monnier Date: Sun Jan 31 17:38:38 2021 -0500 Merge remote-tracking branch 'origin/scratch/lexical-gnus' into trunk commit d2341eb0fb8139f92955c1462ee7b965befdccee Author: Stefan Monnier Date: Sun Jan 31 17:32:11 2021 -0500 * lisp/gnus/gnus-group.el: Defvar all the `gnus-tmp-*` vars These were collected via sed -n -e 's/.*\(gnus-tmp-[^ ()]*\).*/(defvar \1)/p' \ lisp/gnus/gnus-group.el diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index eec64fd217..3661b6376d 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el @@ -477,23 +477,31 @@ simple manner." (defvar gnus-group-edit-buffer nil) +(defvar gnus-tmp-active) +(defvar gnus-tmp-colon) +(defvar gnus-tmp-comment) (defvar gnus-tmp-group) +(defvar gnus-tmp-group-icon) +(defvar gnus-tmp-header) (defvar gnus-tmp-level) (defvar gnus-tmp-marked) +(defvar gnus-tmp-marked-mark) +(defvar gnus-tmp-method) +(defvar gnus-tmp-moderated) +(defvar gnus-tmp-moderated-string) +(defvar gnus-tmp-newsgroup-description) (defvar gnus-tmp-news-method) -(defvar gnus-tmp-colon) +(defvar gnus-tmp-news-method-string) (defvar gnus-tmp-news-server) -(defvar gnus-tmp-header) +(defvar gnus-tmp-number-of-read) +(defvar gnus-tmp-number-of-unread) +(defvar gnus-tmp-number-total) (defvar gnus-tmp-process-marked) -(defvar gnus-tmp-summary-live) -(defvar gnus-tmp-news-method-string) -(defvar gnus-tmp-group-icon) -(defvar gnus-tmp-moderated-string) -(defvar gnus-tmp-newsgroup-description) -(defvar gnus-tmp-comment) (defvar gnus-tmp-qualified-group) (defvar gnus-tmp-subscribed) -(defvar gnus-tmp-number-of-read) +(defvar gnus-tmp-summary-live) +(defvar gnus-tmp-user-defined) + (defvar gnus-inhibit-demon) (defvar gnus-pick-mode) (defvar gnus-tmp-marked-mark) @@ -1503,7 +1511,7 @@ if it is a string, only list groups matching REGEXP." (gnus-group-get-new-news 0)))) :type 'boolean) -(defun gnus-group-insert-group-line (group level marked number gnus-tmp-method) +(defun gnus-group-insert-group-line (group level marked number method) "Insert a group line in the group buffer." (with-suppressed-warnings ((lexical number)) (defvar number)) ;FIXME: Used in `gnus-group-line-format-alist'. @@ -1512,7 +1520,7 @@ if it is a string, only list groups matching REGEXP." (gnus-tmp-marked marked) (gnus-tmp-group group) (gnus-tmp-method - (gnus-server-get-method gnus-tmp-group gnus-tmp-method)) + (gnus-server-get-method gnus-tmp-group method)) (gnus-tmp-active (gnus-active gnus-tmp-group)) (gnus-tmp-number-total (if gnus-tmp-active commit 85b0137858098013eb8ab66c4e9b256eedb1954d Author: Juri Linkov Date: Sun Jan 31 23:47:31 2021 +0200 * lisp/isearch.el (isearch-lazy-highlight): Fix defcustom type (bug#46208) diff --git a/lisp/isearch.el b/lisp/isearch.el index 8320847893..f99461ac45 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -310,7 +310,8 @@ matching the current search string is highlighted lazily When multiple windows display the current buffer, the highlighting is displayed only on the selected window, unless this variable is set to the symbol `all-windows'." - :type '(choice boolean + :type '(choice (const :tag "Off" nil) + (const :tag "On, and applied to current window" t) (const :tag "On, and applied to all windows" all-windows)) :group 'lazy-highlight :group 'isearch) commit cb72b8345b4c6741650c4cff8844716386acaf23 Author: Stefan Kangas Date: Sun Jan 31 19:57:11 2021 +0100 ; * lisp/double.el: Delete cruft dating back to 1994. diff --git a/lisp/double.el b/lisp/double.el index 8bbbaa5818..d099fd0642 100644 --- a/lisp/double.el +++ b/lisp/double.el @@ -141,12 +141,6 @@ but not `C-u X' or `ESC X' since the X is not the prefix key." ;;; Mode -;; This feature seemed useless and it confused describe-mode, -;; so I deleted it. -;; (defvar double-mode-name "Double") -;; ;; Name of current double mode. -;; (make-variable-buffer-local 'double-mode-name) - ;;;###autoload (define-minor-mode double-mode "Toggle special insertion on double keypresses (Double mode). commit 58473dc6608fcfb1ce66e8f540bd804a70813246 Author: Stefan Kangas Date: Sun Jan 31 19:46:20 2021 +0100 Prefer defvar-local in preloaded files * lisp/abbrev.el: * lisp/bindings.el (mode-line-mule-info, mode-line-modified) (mode-line-remote, mode-line-process) (mode-line-buffer-identification): * lisp/buff-menu.el (Buffer-menu-files-only): * lisp/files.el (buffer-file-number, buffer-file-read-only) (local-write-file-hooks, write-contents-functions) (file-local-variables-alist, dir-local-variables-alist) (save-buffer-coding-system, buffer-save-without-query): * lisp/font-core.el (font-lock-defaults): * lisp/font-lock.el (font-lock-keywords-case-fold-search) (font-lock-syntactically-fontified) (font-lock-extend-after-change-region-function) (font-lock-extend-region-functions, font-lock-major-mode): * lisp/menu-bar.el (list-buffers-directory): * lisp/simple.el (next-error--message-highlight-overlay) (next-error-buffer, next-error-function) (next-error-move-function, goto-line-history) (minibuffer-default-add-done, undo-extra-outer-limit): * lisp/tab-bar.el (tab-switcher-column): * lisp/term/ns-win.el (ns-select-overlay): * lisp/window.el (window-size-fixed, window-area-factor) (window-group-start-function, window-group-end-function) (set-window-group-start-function) (recenter-window-group-function) (pos-visible-in-window-group-p-function) (selected-window-group-function) (move-to-window-group-line-function): Prefer defvar-local. diff --git a/lisp/abbrev.el b/lisp/abbrev.el index 65f7118385..54783db2c3 100644 --- a/lisp/abbrev.el +++ b/lisp/abbrev.el @@ -516,9 +516,8 @@ It is nil if the abbrev has already been unexpanded.") (defvar last-abbrev-location 0 "The location of the start of the last abbrev expanded.") -;; (defvar local-abbrev-table fundamental-mode-abbrev-table +;; (defvar-local local-abbrev-table fundamental-mode-abbrev-table ;; "Local (mode-specific) abbrev table of current buffer.") -;; (make-variable-buffer-local 'local-abbrev-table) (defun clear-abbrev-table (table) "Undefine all abbrevs in abbrev table TABLE, leaving it empty." diff --git a/lisp/bindings.el b/lisp/bindings.el index 187444af66..43b62f9bbf 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -199,7 +199,7 @@ mouse-3: Set coding system" (symbol-name buffer-file-coding-system)) "Buffer coding system: none specified"))) -(defvar mode-line-mule-info +(defvar-local mode-line-mule-info `("" (current-input-method (:propertize ("" current-input-method-title) @@ -225,7 +225,6 @@ mnemonics of the following coding systems: coding system for terminal output (on a text terminal)") ;;;###autoload (put 'mode-line-mule-info 'risky-local-variable t) -(make-variable-buffer-local 'mode-line-mule-info) (defvar mode-line-client `("" @@ -247,7 +246,7 @@ mnemonics of the following coding systems: (format "Buffer is %smodified\nmouse-1: Toggle modification state" (if (buffer-modified-p (window-buffer window)) "" "not "))) -(defvar mode-line-modified +(defvar-local mode-line-modified (list (propertize "%1*" 'help-echo 'mode-line-read-only-help-echo @@ -264,9 +263,8 @@ mnemonics of the following coding systems: "Mode line construct for displaying whether current buffer is modified.") ;;;###autoload (put 'mode-line-modified 'risky-local-variable t) -(make-variable-buffer-local 'mode-line-modified) -(defvar mode-line-remote +(defvar-local mode-line-remote (list (propertize "%1@" 'mouse-face 'mode-line-highlight @@ -283,7 +281,6 @@ mnemonics of the following coding systems: "Mode line construct to indicate a remote buffer.") ;;;###autoload (put 'mode-line-remote 'risky-local-variable t) -(make-variable-buffer-local 'mode-line-remote) ;; MSDOS frames have window-system, but want the Fn identification. (defun mode-line-frame-control () @@ -301,12 +298,11 @@ Value is used for `mode-line-frame-identification', which see." ;;;###autoload (put 'mode-line-frame-identification 'risky-local-variable t) -(defvar mode-line-process nil +(defvar-local mode-line-process nil "Mode line construct for displaying info on process status. Normally nil in most modes, since there is no process to display.") ;;;###autoload (put 'mode-line-process 'risky-local-variable t) -(make-variable-buffer-local 'mode-line-process) (defun bindings--define-key (map key item) "Define KEY in keymap MAP according to ITEM from a menu. @@ -543,7 +539,7 @@ mouse-1: Previous buffer\nmouse-3: Next buffer") 'mouse-face 'mode-line-highlight 'local-map mode-line-buffer-identification-keymap))) -(defvar mode-line-buffer-identification +(defvar-local mode-line-buffer-identification (propertized-buffer-identification "%12b") "Mode line construct for identifying the buffer being displayed. Its default value is (\"%12b\") with some text properties added. @@ -551,7 +547,6 @@ Major modes that edit things other than ordinary files may change this \(e.g. Info, Dired,...)") ;;;###autoload (put 'mode-line-buffer-identification 'risky-local-variable t) -(make-variable-buffer-local 'mode-line-buffer-identification) (defvar mode-line-misc-info '((global-mode-string ("" global-mode-string " "))) diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el index 49f8604f52..bb39e1f579 100644 --- a/lisp/buff-menu.el +++ b/lisp/buff-menu.el @@ -111,11 +111,10 @@ as it is by default." :group 'Buffer-menu :version "22.1") -(defvar Buffer-menu-files-only nil +(defvar-local Buffer-menu-files-only nil "Non-nil if the current Buffer Menu lists only file buffers. This is set by the prefix argument to `buffer-menu' and related commands.") -(make-variable-buffer-local 'Buffer-menu-files-only) (defvar Buffer-menu-mode-map (let ((map (make-sparse-keymap)) diff --git a/lisp/files.el b/lisp/files.el index 77e3a3a834..dada69c145 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -191,20 +191,18 @@ if the file has changed on disk and you have not edited the buffer." :type '(repeat regexp) :group 'find-file) -(defvar buffer-file-number nil +(defvar-local buffer-file-number nil "The device number and file number of the file visited in the current buffer. The value is a list of the form (FILENUM DEVNUM). This pair of numbers uniquely identifies the file. If the buffer is visiting a new file, the value is nil.") -(make-variable-buffer-local 'buffer-file-number) (put 'buffer-file-number 'permanent-local t) (defvar buffer-file-numbers-unique (not (memq system-type '(windows-nt))) "Non-nil means that `buffer-file-number' uniquely identifies files.") -(defvar buffer-file-read-only nil +(defvar-local buffer-file-read-only nil "Non-nil if visited file was read-only when visited.") -(make-variable-buffer-local 'buffer-file-read-only) (defcustom small-temporary-file-directory (if (eq system-type 'ms-dos) (getenv "TMPDIR")) @@ -529,15 +527,14 @@ updates before the buffer is saved, use `before-save-hook'.") (put 'write-file-functions 'permanent-local t) ;; I found some files still using the obsolete form in 2018. -(defvar local-write-file-hooks nil) -(make-variable-buffer-local 'local-write-file-hooks) +(defvar-local local-write-file-hooks nil) (put 'local-write-file-hooks 'permanent-local t) (make-obsolete-variable 'local-write-file-hooks 'write-file-functions "22.1") ;; I found some files still using the obsolete form in 2018. (define-obsolete-variable-alias 'write-contents-hooks 'write-contents-functions "22.1") -(defvar write-contents-functions nil +(defvar-local write-contents-functions nil "List of functions to be called before writing out a buffer to a file. Used only by `save-buffer'. If one of them returns non-nil, the @@ -556,7 +553,6 @@ For hooks that _do_ pertain to the particular visited file, use `write-file-functions' relate to how a buffer is saved to file. To perform various checks or updates before the buffer is saved, use `before-save-hook'.") -(make-variable-buffer-local 'write-contents-functions) (defcustom enable-local-variables t "Control use of local variables in files you visit. @@ -3443,23 +3439,21 @@ asking you for confirmation." (put 'c-set-style 'safe-local-eval-function t) -(defvar file-local-variables-alist nil +(defvar-local file-local-variables-alist nil "Alist of file-local variable settings in the current buffer. Each element in this list has the form (VAR . VALUE), where VAR is a file-local variable (a symbol) and VALUE is the value specified. The actual value in the buffer may differ from VALUE, if it is changed by the major or minor modes, or by the user.") -(make-variable-buffer-local 'file-local-variables-alist) (put 'file-local-variables-alist 'permanent-local t) -(defvar dir-local-variables-alist nil +(defvar-local dir-local-variables-alist nil "Alist of directory-local variable settings in the current buffer. Each element in this list has the form (VAR . VALUE), where VAR is a directory-local variable (a symbol) and VALUE is the value specified in .dir-locals.el. The actual value in the buffer may differ from VALUE, if it is changed by the major or minor modes, or by the user.") -(make-variable-buffer-local 'dir-local-variables-alist) (defvar before-hack-local-variables-hook nil "Normal hook run before setting file-local variables. @@ -5233,7 +5227,7 @@ Used only by `save-buffer'." :type 'hook :group 'files) -(defvar save-buffer-coding-system nil +(defvar-local save-buffer-coding-system nil "If non-nil, use this coding system for saving the buffer. More precisely, use this coding system in place of the value of `buffer-file-coding-system', when saving the buffer. @@ -5241,7 +5235,6 @@ Calling `write-region' for any purpose other than saving the buffer will still use `buffer-file-coding-system'; this variable has no effect in such cases.") -(make-variable-buffer-local 'save-buffer-coding-system) (put 'save-buffer-coding-system 'permanent-local t) (defun basic-save-buffer (&optional called-interactively) @@ -5510,9 +5503,8 @@ Before and after saving the buffer, this function runs "ACTION-ALIST argument used in call to `map-y-or-n-p'.") (put 'save-some-buffers-action-alist 'risky-local-variable t) -(defvar buffer-save-without-query nil +(defvar-local buffer-save-without-query nil "Non-nil means `save-some-buffers' should save this buffer without asking.") -(make-variable-buffer-local 'buffer-save-without-query) (defcustom save-some-buffers-default-predicate nil "Default predicate for `save-some-buffers'. diff --git a/lisp/font-core.el b/lisp/font-core.el index 0f1a3d1c36..4b69542497 100644 --- a/lisp/font-core.el +++ b/lisp/font-core.el @@ -26,7 +26,7 @@ ;; This variable is used by mode packages that support Font Lock mode by ;; defining their own keywords to use for `font-lock-keywords'. (The mode ;; command should make it buffer-local and set it to provide the set up.) -(defvar font-lock-defaults nil +(defvar-local font-lock-defaults nil "Defaults for Font Lock mode specified by the major mode. Defaults should be of the form: @@ -66,7 +66,6 @@ functions, `font-lock-fontify-buffer-function', `font-lock-unfontify-region-function', and `font-lock-inhibit-thing-lock'.") ;;;###autoload (put 'font-lock-defaults 'risky-local-variable t) -(make-variable-buffer-local 'font-lock-defaults) (defvar font-lock-function 'font-lock-default-function "A function which is called when `font-lock-mode' is toggled. diff --git a/lisp/font-lock.el b/lisp/font-lock.el index a9fc69d419..c344a61258 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -515,17 +515,15 @@ This is normally set via `font-lock-add-keywords' and "Non-nil means Font Lock should not fontify comments or strings. This is normally set via `font-lock-defaults'.") -(defvar font-lock-keywords-case-fold-search nil +(defvar-local font-lock-keywords-case-fold-search nil "Non-nil means the patterns in `font-lock-keywords' are case-insensitive. This is set via the function `font-lock-set-defaults', based on the CASE-FOLD argument of `font-lock-defaults'.") -(make-variable-buffer-local 'font-lock-keywords-case-fold-search) -(defvar font-lock-syntactically-fontified 0 +(defvar-local font-lock-syntactically-fontified 0 "Point up to which `font-lock-syntactic-keywords' has been applied. If nil, this is ignored, in which case the syntactic fontification may sometimes be slightly incorrect.") -(make-variable-buffer-local 'font-lock-syntactically-fontified) (defvar font-lock-syntactic-face-function (lambda (state) @@ -1026,7 +1024,7 @@ The value of this variable is used when Font Lock mode is turned on." ;; directives correctly and cleanly. (It is the same problem as fontifying ;; multi-line strings and comments; regexps are not appropriate for the job.) -(defvar font-lock-extend-after-change-region-function nil +(defvar-local font-lock-extend-after-change-region-function nil "A function that determines the region to refontify after a change. This variable is either nil, or is a function that determines the @@ -1040,7 +1038,6 @@ and end buffer positions \(in that order) of the region to refontify, or nil \(which directs the caller to fontify a default region). This function should preserve the match-data. The region it returns may start or end in the middle of a line.") -(make-variable-buffer-local 'font-lock-extend-after-change-region-function) (defun font-lock-fontify-buffer (&optional interactively) "Fontify the current buffer the way the function `font-lock-mode' would." @@ -1159,7 +1156,7 @@ a very meaningful entity to highlight.") (defvar font-lock-beg) (defvar font-lock-end) -(defvar font-lock-extend-region-functions +(defvar-local font-lock-extend-region-functions '(font-lock-extend-region-wholelines ;; This use of font-lock-multiline property is unreliable but is just ;; a handy heuristic: in case you don't have a function that does @@ -1181,7 +1178,6 @@ These functions are run in turn repeatedly until they all return nil. Put first the functions more likely to cause a change and cheaper to compute.") ;; Mark it as a special hook which doesn't use any global setting ;; (i.e. doesn't obey the element t in the buffer-local value). -(make-variable-buffer-local 'font-lock-extend-region-functions) (defun font-lock-extend-region-multiline () "Move fontification boundaries away from any `font-lock-multiline' property." @@ -1888,9 +1884,8 @@ preserve `hi-lock-mode' highlighting patterns." (kill-local-variable 'font-lock-set-defaults) (font-lock-mode 1)) -(defvar font-lock-major-mode nil +(defvar-local font-lock-major-mode nil "Major mode for which the font-lock settings have been setup.") -(make-variable-buffer-local 'font-lock-major-mode) (defun font-lock-set-defaults () "Set fontification defaults appropriately for this mode. diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index 526491f027..2fdfcc8b58 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -2240,9 +2240,8 @@ Buffers menu is regenerated." :type 'boolean :group 'menu) -(defvar list-buffers-directory nil +(defvar-local list-buffers-directory nil "String to display in buffer listings for buffers not visiting a file.") -(make-variable-buffer-local 'list-buffers-directory) (defun menu-bar-select-buffer () (interactive) diff --git a/lisp/simple.el b/lisp/simple.el index 742fc5004d..e4a363a9a5 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -134,10 +134,9 @@ messages are highlighted; this helps to see what messages were visited." :group 'next-error :version "28.1") -(defvar next-error--message-highlight-overlay +(defvar-local next-error--message-highlight-overlay nil "Overlay highlighting the current error message in the `next-error' buffer.") -(make-variable-buffer-local 'next-error--message-highlight-overlay) (defcustom next-error-hook nil "List of hook functions run by `next-error' after visiting source file." @@ -165,15 +164,14 @@ A buffer becomes most recent when its compilation, grep, or similar mode is started, or when it is used with \\[next-error] or \\[compile-goto-error].") -(defvar next-error-buffer nil +(defvar-local next-error-buffer nil "The buffer-local value of the most recent `next-error' buffer.") ;; next-error-buffer is made buffer-local to keep the reference ;; to the parent buffer used to navigate to the current buffer, so the ;; next call of next-buffer will use the same parent buffer to ;; continue navigation from it. -(make-variable-buffer-local 'next-error-buffer) -(defvar next-error-function nil +(defvar-local next-error-function nil "Function to use to find the next error in the current buffer. The function is called with 2 parameters: ARG is an integer specifying by how many errors to move. @@ -182,15 +180,13 @@ of the errors before moving. Major modes providing compile-like functionality should set this variable to indicate to `next-error' that this is a candidate buffer and how to navigate in it.") -(make-variable-buffer-local 'next-error-function) -(defvar next-error-move-function nil +(defvar-local next-error-move-function nil "Function to use to move to an error locus. It takes two arguments, a buffer position in the error buffer and a buffer position in the error locus buffer. The buffer for the error locus should already be current. nil means use goto-char using the second argument position.") -(make-variable-buffer-local 'next-error-move-function) (defsubst next-error-buffer-p (buffer &optional avoid-current @@ -1268,9 +1264,8 @@ that uses or sets the mark." ;; Counting lines, one way or another. -(defvar goto-line-history nil +(defvar-local goto-line-history nil "History of values entered with `goto-line'.") -(make-variable-buffer-local 'goto-line-history) (defun goto-line-read-args (&optional relative) "Read arguments for `goto-line' related commands." @@ -2309,14 +2304,12 @@ once. In special cases, when this function needs to be called more than once, it can set `minibuffer-default-add-done' to nil explicitly, overriding the setting of this variable to t in `goto-history-element'.") -(defvar minibuffer-default-add-done nil +(defvar-local minibuffer-default-add-done nil "When nil, add more elements to the end of the list of default values. The value nil causes `goto-history-element' to add more elements to the list of defaults when it reaches the end of this list. It does this by calling a function defined by `minibuffer-default-add-function'.") -(make-variable-buffer-local 'minibuffer-default-add-done) - (defun minibuffer-default-add-completions () "Return a list of all completions without the default value. This function is used to add all elements of the completion table to @@ -3480,13 +3473,12 @@ excessively long before answering the question." :group 'undo :version "22.1") -(defvar undo-extra-outer-limit nil +(defvar-local undo-extra-outer-limit nil "If non-nil, an extra level of size that's ok in an undo item. We don't ask the user about truncating the undo list until the current item gets bigger than this amount. This variable matters only if `undo-ask-before-discard' is non-nil.") -(make-variable-buffer-local 'undo-extra-outer-limit) ;; When the first undo batch in an undo list is longer than ;; undo-outer-limit, this function gets called to warn the user that diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 7e556550da..6720d82b47 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -1308,8 +1308,7 @@ For more information, see the function `tab-switcher'." (setq buffer-read-only t) (current-buffer)))) -(defvar tab-switcher-column 3) -(make-variable-buffer-local 'tab-switcher-column) +(defvar-local tab-switcher-column 3) (defvar tab-switcher-mode-map (let ((map (make-keymap))) diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el index 94e9d5c582..af1e388c2a 100644 --- a/lisp/term/ns-win.el +++ b/lisp/term/ns-win.el @@ -374,9 +374,8 @@ prompting. If file is a directory perform a `find-file' on it." (find-file f) (push-mark (+ (point) (cadr (insert-file-contents f))))))) -(defvar ns-select-overlay nil +(defvar-local ns-select-overlay nil "Overlay used to highlight areas in files requested by Nextstep apps.") -(make-variable-buffer-local 'ns-select-overlay) (defvar ns-input-line) ; nsterm.m diff --git a/lisp/window.el b/lisp/window.el index d587691420..8905d4a826 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -1500,7 +1500,7 @@ otherwise." (window-pixel-height window) (window-total-height window round)))) -(defvar window-size-fixed nil +(defvar-local window-size-fixed nil "Non-nil in a buffer means windows displaying the buffer are fixed-size. If the value is `height', then only the window's height is fixed. If the value is `width', then only the window's width is fixed. @@ -1509,7 +1509,6 @@ Any other non-nil value fixes both the width and the height. Emacs won't change the size of any window displaying that buffer, unless it has no other choice (like when deleting a neighboring window).") -(make-variable-buffer-local 'window-size-fixed) (defun window--preservable-size (window &optional horizontal) "Return height of WINDOW as `window-preserve-size' would preserve it. @@ -5753,11 +5752,10 @@ nil (i.e. any), `height' or `width'." '((height . width) (width . height)))))))) ;;; A different solution to balance-windows. -(defvar window-area-factor 1 +(defvar-local window-area-factor 1 "Factor by which the window area should be over-estimated. This is used by `balance-windows-area'. Changing this globally has no effect.") -(make-variable-buffer-local 'window-area-factor) (defun balance-windows-area-adjust (window delta horizontal pixelwise) "Wrapper around `window-resize' with error checking. @@ -9580,8 +9578,7 @@ buffers displaying right to left text." ;; status is undone only when explicitly programmed, not when a buffer ;; is reverted or a mode function is called. -(defvar window-group-start-function nil) -(make-variable-buffer-local 'window-group-start-function) +(defvar-local window-group-start-function nil) (put 'window-group-start-function 'permanent-local t) (defun window-group-start (&optional window) "Return position at which display currently starts in the group of @@ -9594,8 +9591,7 @@ This is updated by redisplay or by calling `set-window*-start'." (funcall window-group-start-function window) (window-start window))) -(defvar window-group-end-function nil) -(make-variable-buffer-local 'window-group-end-function) +(defvar-local window-group-end-function nil) (put 'window-group-end-function 'permanent-local t) (defun window-group-end (&optional window update) "Return position at which display currently ends in the group of @@ -9614,8 +9610,7 @@ if it isn't already recorded." (funcall window-group-end-function window update) (window-end window update))) -(defvar set-window-group-start-function nil) -(make-variable-buffer-local 'set-window-group-start-function) +(defvar-local set-window-group-start-function nil) (put 'set-window-group-start-function 'permanent-local t) (defun set-window-group-start (window pos &optional noforce) "Make display in the group of windows containing WINDOW start at @@ -9629,8 +9624,7 @@ overriding motion of point in order to display at this exact start." (funcall set-window-group-start-function window pos noforce) (set-window-start window pos noforce))) -(defvar recenter-window-group-function nil) -(make-variable-buffer-local 'recenter-window-group-function) +(defvar-local recenter-window-group-function nil) (put 'recenter-window-group-function 'permanent-local t) (defun recenter-window-group (&optional arg) "Center point in the group of windows containing the selected window @@ -9656,8 +9650,7 @@ and redisplay normally--don't erase and redraw the frame." (funcall recenter-window-group-function arg) (recenter arg))) -(defvar pos-visible-in-window-group-p-function nil) -(make-variable-buffer-local 'pos-visible-in-window-group-p-function) +(defvar-local pos-visible-in-window-group-p-function nil) (put 'pos-visible-in-window-group-p-function 'permanent-local t) (defun pos-visible-in-window-group-p (&optional pos window partially) "Return non-nil if position POS is currently on the frame in the @@ -9687,8 +9680,7 @@ POS, ROWH is the visible height of that row, and VPOS is the row number (funcall pos-visible-in-window-group-p-function pos window partially) (pos-visible-in-window-p pos window partially))) -(defvar selected-window-group-function nil) -(make-variable-buffer-local 'selected-window-group-function) +(defvar-local selected-window-group-function nil) (put 'selected-window-group-function 'permanent-local t) (defun selected-window-group () "Return the list of windows in the group containing the selected window. @@ -9698,8 +9690,7 @@ result is a list containing only the selected window." (funcall selected-window-group-function) (list (selected-window)))) -(defvar move-to-window-group-line-function nil) -(make-variable-buffer-local 'move-to-window-group-line-function) +(defvar-local move-to-window-group-line-function nil) (put 'move-to-window-group-line-function 'permanent-local t) (defun move-to-window-group-line (arg) "Position point relative to the current group of windows. commit 2c754cf449e97203187556390d2c219a50f7c950 Author: Stefan Kangas Date: Sun Jan 31 19:28:22 2021 +0100 Prefer defvar-local in mail/*.el * lisp/mail/emacsbug.el (report-emacs-bug-send-command) (report-emacs-bug-send-hook): * lisp/mail/reporter.el (reporter-initial-text): * lisp/mail/supercite.el (sc-mail-info, sc-attributions): * lisp/mail/rmail.el (rmail-buffer-swapped, rmail-view-buffer): Prefer defvar-local. diff --git a/lisp/mail/emacsbug.el b/lisp/mail/emacsbug.el index 4e8009db86..815ff4339e 100644 --- a/lisp/mail/emacsbug.el +++ b/lisp/mail/emacsbug.el @@ -58,13 +58,11 @@ (defvar report-emacs-bug-orig-text nil "The automatically-created initial text of the bug report.") -(defvar report-emacs-bug-send-command nil +(defvar-local report-emacs-bug-send-command nil "Name of the command to send the bug report, as a string.") -(make-variable-buffer-local 'report-emacs-bug-send-command) -(defvar report-emacs-bug-send-hook nil +(defvar-local report-emacs-bug-send-hook nil "Hook run before sending the bug report.") -(make-variable-buffer-local 'report-emacs-bug-send-hook) (declare-function x-server-vendor "xfns.c" (&optional terminal)) (declare-function x-server-version "xfns.c" (&optional terminal)) diff --git a/lisp/mail/reporter.el b/lisp/mail/reporter.el index 2e583a470d..4b70582a26 100644 --- a/lisp/mail/reporter.el +++ b/lisp/mail/reporter.el @@ -100,9 +100,8 @@ This is necessary to properly support the printing of buffer-local variables. Current buffer will always be the mail buffer being composed.") -(defvar reporter-initial-text nil +(defvar-local reporter-initial-text nil "The automatically created initial text of a bug report.") -(make-variable-buffer-local 'reporter-initial-text) diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el index 9f95b62d87..8ccf1bffdd 100644 --- a/lisp/mail/rmail.el +++ b/lisp/mail/rmail.el @@ -620,14 +620,12 @@ Element N specifies the summary line for message N+1.") ;; Rmail buffer swapping variables. -(defvar rmail-buffer-swapped nil +(defvar-local rmail-buffer-swapped nil "If non-nil, `rmail-buffer' is swapped with `rmail-view-buffer'.") -(make-variable-buffer-local 'rmail-buffer-swapped) (put 'rmail-buffer-swapped 'permanent-local t) -(defvar rmail-view-buffer nil +(defvar-local rmail-view-buffer nil "Buffer which holds RMAIL message for MIME displaying.") -(make-variable-buffer-local 'rmail-view-buffer) (put 'rmail-view-buffer 'permanent-local t) ;; `Sticky' default variables. diff --git a/lisp/mail/supercite.el b/lisp/mail/supercite.el index 5766c79187..99ac41dd9b 100644 --- a/lisp/mail/supercite.el +++ b/lisp/mail/supercite.el @@ -509,9 +509,9 @@ string." ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;; end user configuration variables -(defvar sc-mail-info nil +(defvar-local sc-mail-info nil "Alist of mail header information gleaned from reply buffer.") -(defvar sc-attributions nil +(defvar-local sc-attributions nil "Alist of attributions for use when citing.") (defvar sc-tmp-nested-regexp nil @@ -521,9 +521,6 @@ string." (defvar sc-tmp-dumb-regexp nil "Temp regexp describing non-nested citation cited with a nesting citer.") -(make-variable-buffer-local 'sc-mail-info) -(make-variable-buffer-local 'sc-attributions) - ;; ====================================================================== ;; supercite keymaps commit 59e8c37d61d313335408f8f23e3025b499200266 Author: Stefan Kangas Date: Sun Jan 31 18:46:17 2021 +0100 Prefer defvar-local in progmodes/*.el This skips libraries that might want compatibility with Emacs 24.2. * lisp/progmodes/compile.el (compilation-auto-jump-to-next) (compilation--previous-directory-cache, compilation--parsed) (compilation-gcpro): * lisp/progmodes/cpp.el (cpp-overlay-list, cpp-edit-buffer) (cpp-parse-symbols, cpp-edit-symbols): * lisp/progmodes/ebnf2ps.el (ebnf-eps-upper-x, ebnf-eps-upper-y) (ebnf-eps-prod-width, ebnf-eps-max-height, ebnf-eps-max-width): * lisp/progmodes/f90.el (f90-cache-position): * lisp/progmodes/gud.el (gud-marker-acc): * lisp/progmodes/js.el (js--quick-match-re) (js--quick-match-re-func, js--cache-end, js--last-parse-pos) (js--state-at-last-parse-pos, js--tmp-location): * lisp/progmodes/octave.el (inferior-octave-directory-tracker-resync): * lisp/progmodes/sh-script.el (sh-header-marker): Prefer defvar-local. diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index 2c1e6ff52e..614ed7d835 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -953,13 +953,11 @@ Faces `compilation-error-face', `compilation-warning-face', :type 'boolean :version "23.1") -(defvar compilation-auto-jump-to-next nil +(defvar-local compilation-auto-jump-to-next nil "If non-nil, automatically jump to the next error encountered.") -(make-variable-buffer-local 'compilation-auto-jump-to-next) -;; (defvar compilation-buffer-modtime nil +;; (defvar-local compilation-buffer-modtime nil ;; "The buffer modification time, for buffers not associated with files.") -;; (make-variable-buffer-local 'compilation-buffer-modtime) (defvar compilation-skip-to-next-location t "If non-nil, skip multiple error messages for the same source location.") @@ -1087,13 +1085,12 @@ from a different message." (:conc-name compilation--message->)) loc type end-loc rule) -(defvar compilation--previous-directory-cache nil +(defvar-local compilation--previous-directory-cache nil "A pair (POS . RES) caching the result of previous directory search. Basically, this pair says that calling (previous-single-property-change POS \\='compilation-directory) returned RES, i.e. there is no change of `compilation-directory' between POS and RES.") -(make-variable-buffer-local 'compilation--previous-directory-cache) (defun compilation--flush-directory-cache (start _end) (cond @@ -1600,8 +1597,7 @@ to `compilation-error-regexp-alist' if RULES is nil." (match-beginning mn) (match-end mn) 'font-lock-face (cadr props))))))))) -(defvar compilation--parsed -1) -(make-variable-buffer-local 'compilation--parsed) +(defvar-local compilation--parsed -1) (defun compilation--ensure-parse (limit) "Make sure the text has been parsed up to LIMIT." @@ -2673,9 +2669,8 @@ This is the value of `next-error-function' in Compilation buffers." (compilation--loc->marker end-loc)) (setf (compilation--loc->visited loc) t))) -(defvar compilation-gcpro nil +(defvar-local compilation-gcpro nil "Internal variable used to keep some values from being GC'd.") -(make-variable-buffer-local 'compilation-gcpro) (defun compilation-fake-loc (marker file &optional line col) "Preassociate MARKER with FILE. diff --git a/lisp/progmodes/cpp.el b/lisp/progmodes/cpp.el index 4ea1674db0..b2c2e8dab5 100644 --- a/lisp/progmodes/cpp.el +++ b/lisp/progmodes/cpp.el @@ -112,9 +112,8 @@ If nil, `cpp-progress-message' prints no progress messages." :group 'cpp :version "26.1") -(defvar cpp-overlay-list nil) -;; List of cpp overlays active in the current buffer. -(make-variable-buffer-local 'cpp-overlay-list) +(defvar-local cpp-overlay-list nil + "List of cpp overlays active in the current buffer.") (defvar cpp-callback-data) (defvar cpp-state-stack) @@ -134,9 +133,8 @@ If nil, `cpp-progress-message' prints no progress messages." (defvar cpp-button-event nil) ;; This will be t in the callback for `cpp-make-button'. -(defvar cpp-edit-buffer nil) -;; Real buffer whose cpp display information we are editing. -(make-variable-buffer-local 'cpp-edit-buffer) +(defvar-local cpp-edit-buffer nil + "Real buffer whose cpp display information we are editing.") (defconst cpp-branch-list ;; Alist of branches. @@ -211,9 +209,8 @@ or a cons cell (background-color . COLOR)." ;;; Parse Buffer: -(defvar cpp-parse-symbols nil +(defvar-local cpp-parse-symbols nil "List of cpp macros used in the local buffer.") -(make-variable-buffer-local 'cpp-parse-symbols) (defconst cpp-parse-regexp ;; Regexp matching all tokens needed to find conditionals. @@ -471,9 +468,8 @@ A prefix arg suppresses display of that buffer." -(defvar cpp-edit-symbols nil) -;; Symbols defined in the edit buffer. -(make-variable-buffer-local 'cpp-edit-symbols) +(defvar-local cpp-edit-symbols nil + "Symbols defined in the edit buffer.") (define-derived-mode cpp-edit-mode fundamental-mode "CPP Edit" "Major mode for editing the criteria for highlighting cpp conditionals. diff --git a/lisp/progmodes/ebnf2ps.el b/lisp/progmodes/ebnf2ps.el index 6f9509d152..b376423c18 100644 --- a/lisp/progmodes/ebnf2ps.el +++ b/lisp/progmodes/ebnf2ps.el @@ -2941,16 +2941,11 @@ See `ebnf-style-database' documentation." (defvar ebnf-eps-executing nil) (defvar ebnf-eps-header-comment nil) (defvar ebnf-eps-footer-comment nil) -(defvar ebnf-eps-upper-x 0.0) -(make-variable-buffer-local 'ebnf-eps-upper-x) -(defvar ebnf-eps-upper-y 0.0) -(make-variable-buffer-local 'ebnf-eps-upper-y) -(defvar ebnf-eps-prod-width 0.0) -(make-variable-buffer-local 'ebnf-eps-prod-width) -(defvar ebnf-eps-max-height 0.0) -(make-variable-buffer-local 'ebnf-eps-max-height) -(defvar ebnf-eps-max-width 0.0) -(make-variable-buffer-local 'ebnf-eps-max-width) +(defvar-local ebnf-eps-upper-x 0.0) +(defvar-local ebnf-eps-upper-y 0.0) +(defvar-local ebnf-eps-prod-width 0.0) +(defvar-local ebnf-eps-max-height 0.0) +(defvar-local ebnf-eps-max-width 0.0) (defvar ebnf-eps-context nil diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el index 2641387986..92b165bc64 100644 --- a/lisp/progmodes/f90.el +++ b/lisp/progmodes/f90.el @@ -926,9 +926,8 @@ then the presence of the token here allows a line-break before or after the other character, where a break would not normally be allowed. This minor issue currently only affects \"(/\" and \"/)\".") -(defvar f90-cache-position nil +(defvar-local f90-cache-position nil "Temporary position used to speed up region operations.") -(make-variable-buffer-local 'f90-cache-position) ;; Hideshow support. diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el index 259da2fd01..eb114acdab 100644 --- a/lisp/progmodes/gud.el +++ b/lisp/progmodes/gud.el @@ -638,8 +638,7 @@ The option \"--fullname\" must be included in this value." ;; receive a chunk of text which looks like it might contain the ;; beginning of a marker, we save it here between calls to the ;; filter. -(defvar gud-marker-acc "") -(make-variable-buffer-local 'gud-marker-acc) +(defvar-local gud-marker-acc "") (defun gud-gdb-marker-filter (string) (setq gud-marker-acc (concat gud-marker-acc string)) diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 33bea59e3b..cdf6536fc7 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -717,26 +717,20 @@ This variable is like `sgml-attribute-offset'." table) "Syntax table for `js-mode'.") -(defvar js--quick-match-re nil +(defvar-local js--quick-match-re nil "Autogenerated regexp used by `js-mode' to match buffer constructs.") -(defvar js--quick-match-re-func nil +(defvar-local js--quick-match-re-func nil "Autogenerated regexp used by `js-mode' to match constructs and functions.") -(make-variable-buffer-local 'js--quick-match-re) -(make-variable-buffer-local 'js--quick-match-re-func) - -(defvar js--cache-end 1 +(defvar-local js--cache-end 1 "Last valid buffer position for the `js-mode' function cache.") -(make-variable-buffer-local 'js--cache-end) -(defvar js--last-parse-pos nil +(defvar-local js--last-parse-pos nil "Latest parse position reached by `js--ensure-cache'.") -(make-variable-buffer-local 'js--last-parse-pos) -(defvar js--state-at-last-parse-pos nil +(defvar-local js--state-at-last-parse-pos nil "Parse state at `js--last-parse-pos'.") -(make-variable-buffer-local 'js--state-at-last-parse-pos) (defun js--maybe-join (prefix separator suffix &rest list) "Helper function for `js--update-quick-match-re'. @@ -1505,8 +1499,7 @@ REGEXPS, but only if FRAMEWORK is in `js-enabled-frameworks'." (when (memq (quote ,framework) js-enabled-frameworks) (re-search-forward ,regexps limit t))))) -(defvar js--tmp-location nil) -(make-variable-buffer-local 'js--tmp-location) +(defvar-local js--tmp-location nil) (defun js--forward-destructuring-spec (&optional func) "Move forward over a JavaScript destructuring spec. diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el index a14a8d75a7..c37bb1c711 100644 --- a/lisp/progmodes/octave.el +++ b/lisp/progmodes/octave.el @@ -964,8 +964,7 @@ output is passed to the filter `inferior-octave-output-digest'." (setq list (cdr list))) (set-process-filter proc filter)))) -(defvar inferior-octave-directory-tracker-resync nil) -(make-variable-buffer-local 'inferior-octave-directory-tracker-resync) +(defvar-local inferior-octave-directory-tracker-resync nil) (defun inferior-octave-directory-tracker (string) "Tracks `cd' commands issued to the inferior Octave process. diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index fd68952767..f588ad99c9 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -541,10 +541,9 @@ sign. See `sh-feature'." :group 'sh-script) -(defvar sh-header-marker nil +(defvar-local sh-header-marker nil "When non-nil is the end of header for prepending by \\[sh-execute-region]. That command is also used for setting this variable.") -(make-variable-buffer-local 'sh-header-marker) (defcustom sh-beginning-of-command "\\([;({`|&]\\|\\`\\|[^\\]\n\\)[ \t]*\\([/~[:alnum:]:]\\)" commit 458faaf4c39936a5e7d187684cbf0fe0b161bb0a Author: Stefan Kangas Date: Sun Jan 31 18:45:47 2021 +0100 Prefer defvar-local in textmodes/*.el This skips libraries that might want compatibility with Emacs 24.2. * lisp/textmodes/artist.el (artist-curr-go) (artist-line-char-set, artist-line-char, artist-fill-char-set) (artist-fill-char, artist-erase-char, artist-default-fill-char) (artist-draw-region-min-y, artist-draw-region-max-y) (artist-borderless-shapes): * lisp/textmodes/css-mode.el (css--at-ids, css--bang-ids) (css--nested-selectors-allowed): * lisp/textmodes/enriched.el (enriched-old-bindings): * lisp/textmodes/flyspell.el (flyspell-generic-check-word-predicate) (flyspell-consider-dash-as-word-delimiter-flag) (flyspell-dash-dictionary, flyspell-dash-local-dictionary) (flyspell-word-cache-start, flyspell-word-cache-end) (flyspell-word-cache-word, flyspell-word-cache-result) (flyspell-changes, flyspell-auto-correct-pos) (flyspell-auto-correct-region, flyspell-auto-correct-ring) (flyspell-auto-correct-word): * lisp/textmodes/ispell.el (ispell-local-dictionary-overridden) (ispell-local-pdict, ispell-buffer-session-localwords): * lisp/textmodes/refill.el (refill-ignorable-overlay) (refill-doit): * lisp/textmodes/sgml-mode.el (html--buffer-classes-cache) (html--buffer-ids-cache): * lisp/textmodes/table.el (table-mode-indicator): * lisp/textmodes/tex-mode.el (tex-send-command-modified-tick): * lisp/textmodes/two-column.el (2C-autoscroll-start, 2C-mode): Prefer defvar-local. diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el index 13b7118d2f..e66adb43e7 100644 --- a/lisp/textmodes/artist.el +++ b/lisp/textmodes/artist.el @@ -411,50 +411,40 @@ be in `artist-spray-chars', or spraying will behave strangely.") (defvar artist-mode-name " Artist" "Name of Artist mode beginning with a space (appears in the mode-line).") -(defvar artist-curr-go 'pen-line +(defvar-local artist-curr-go 'pen-line "Current selected graphics operation.") -(make-variable-buffer-local 'artist-curr-go) -(defvar artist-line-char-set nil +(defvar-local artist-line-char-set nil "Boolean to tell whether user has set some char to use when drawing lines.") -(make-variable-buffer-local 'artist-line-char-set) -(defvar artist-line-char nil +(defvar-local artist-line-char nil "Char to use when drawing lines.") -(make-variable-buffer-local 'artist-line-char) -(defvar artist-fill-char-set nil +(defvar-local artist-fill-char-set nil "Boolean to tell whether user has set some char to use when filling.") -(make-variable-buffer-local 'artist-fill-char-set) -(defvar artist-fill-char nil +(defvar-local artist-fill-char nil "Char to use when filling.") -(make-variable-buffer-local 'artist-fill-char) -(defvar artist-erase-char ?\s +(defvar-local artist-erase-char ?\s "Char to use when erasing.") -(make-variable-buffer-local 'artist-erase-char) -(defvar artist-default-fill-char ?. +(defvar-local artist-default-fill-char ?. "Char to use when a fill-char is required but none is set.") -(make-variable-buffer-local 'artist-default-fill-char) ; This variable is not buffer local (defvar artist-copy-buffer nil "Copy buffer.") -(defvar artist-draw-region-min-y 0 +(defvar-local artist-draw-region-min-y 0 "Line-number for top-most visited line for draw operation.") -(make-variable-buffer-local 'artist-draw-region-min-y) -(defvar artist-draw-region-max-y 0 +(defvar-local artist-draw-region-max-y 0 "Line-number for bottom-most visited line for draw operation.") -(make-variable-buffer-local 'artist-draw-region-max-y) -(defvar artist-borderless-shapes nil +(defvar-local artist-borderless-shapes nil "When non-nil, draw shapes without border. The fill char is used instead, if it is set.") -(make-variable-buffer-local 'artist-borderless-shapes) (defvar artist-prev-next-op-alist nil "Assoc list for looking up next and/or previous draw operation. diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index 9186e52008..622853da45 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -71,9 +71,8 @@ "while") "Additional identifiers that appear in the form @foo in SCSS.") -(defvar css--at-ids css-at-ids +(defvar-local css--at-ids css-at-ids "List of at-rules for the current mode.") -(make-variable-buffer-local 'css--at-ids) (defconst css-bang-ids '("important") @@ -83,9 +82,8 @@ '("default" "global" "optional") "Additional identifiers that appear in the form !foo in SCSS.") -(defvar css--bang-ids css-bang-ids +(defvar-local css--bang-ids css-bang-ids "List of bang-rules for the current mode.") -(make-variable-buffer-local 'css--bang-ids) (defconst css-descriptor-ids '("ascent" "baseline" "bbox" "cap-height" "centerline" "definition-src" @@ -1374,9 +1372,8 @@ the string PROPERTY." "List of HTML tags. Used to provide completion of HTML tags in selectors.") -(defvar css--nested-selectors-allowed nil +(defvar-local css--nested-selectors-allowed nil "Non-nil if nested selectors are allowed in the current mode.") -(make-variable-buffer-local 'css--nested-selectors-allowed) (defvar css-class-list-function #'ignore "Called to provide completions of class names. diff --git a/lisp/textmodes/enriched.el b/lisp/textmodes/enriched.el index 1aac96413e..bac209cdef 100644 --- a/lisp/textmodes/enriched.el +++ b/lisp/textmodes/enriched.el @@ -165,10 +165,9 @@ execute malicious Lisp code, if that code came from an external source." :version "26.1" :group 'enriched) -(defvar enriched-old-bindings nil +(defvar-local enriched-old-bindings nil "Store old variable values that we change when entering mode. The value is a list of \(VAR VALUE VAR VALUE...).") -(make-variable-buffer-local 'enriched-old-bindings) ;; The next variable is buffer local if and only if Enriched mode is ;; enabled. The buffer local value records whether diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el index d850316884..83dba7177a 100644 --- a/lisp/textmodes/flyspell.el +++ b/lisp/textmodes/flyspell.el @@ -304,12 +304,11 @@ If this variable is nil, all regions are treated as small." (define-obsolete-variable-alias 'flyspell-generic-check-word-p 'flyspell-generic-check-word-predicate "25.1") -(defvar flyspell-generic-check-word-predicate nil +(defvar-local flyspell-generic-check-word-predicate nil "Function providing per-mode customization over which words are flyspelled. Returns t to continue checking, nil otherwise. Flyspell mode sets this variable to whatever is the `flyspell-mode-predicate' property of the major mode name.") -(make-variable-buffer-local 'flyspell-generic-check-word-predicate) ;;*--- mail mode -------------------------------------------------------*/ (put 'mail-mode 'flyspell-mode-predicate 'mail-mode-flyspell-verify) @@ -466,13 +465,10 @@ If this is set, also unbind `mouse-2'." :version "28.1") ;; dash character machinery -(defvar flyspell-consider-dash-as-word-delimiter-flag nil +(defvar-local flyspell-consider-dash-as-word-delimiter-flag nil "Non-nil means that the `-' char is considered as a word delimiter.") -(make-variable-buffer-local 'flyspell-consider-dash-as-word-delimiter-flag) -(defvar flyspell-dash-dictionary nil) -(make-variable-buffer-local 'flyspell-dash-dictionary) -(defvar flyspell-dash-local-dictionary nil) -(make-variable-buffer-local 'flyspell-dash-local-dictionary) +(defvar-local flyspell-dash-dictionary nil) +(defvar-local flyspell-dash-local-dictionary nil) ;;*---------------------------------------------------------------------*/ ;;* Highlighting */ @@ -714,14 +710,10 @@ has been used, the current word is not checked." ;;*---------------------------------------------------------------------*/ ;;* flyspell-word-cache ... */ ;;*---------------------------------------------------------------------*/ -(defvar flyspell-word-cache-start nil) -(defvar flyspell-word-cache-end nil) -(defvar flyspell-word-cache-word nil) -(defvar flyspell-word-cache-result '_) -(make-variable-buffer-local 'flyspell-word-cache-start) -(make-variable-buffer-local 'flyspell-word-cache-end) -(make-variable-buffer-local 'flyspell-word-cache-word) -(make-variable-buffer-local 'flyspell-word-cache-result) +(defvar-local flyspell-word-cache-start nil) +(defvar-local flyspell-word-cache-end nil) +(defvar-local flyspell-word-cache-word nil) +(defvar-local flyspell-word-cache-result '_) ;;*---------------------------------------------------------------------*/ ;;* The flyspell pre-hook, store the current position. In the */ @@ -827,8 +819,7 @@ before the current command." ;;* the post command hook, we will check, if the word at this */ ;;* position has to be spell checked. */ ;;*---------------------------------------------------------------------*/ -(defvar flyspell-changes nil) -(make-variable-buffer-local 'flyspell-changes) +(defvar-local flyspell-changes nil) ;;*---------------------------------------------------------------------*/ ;;* flyspell-after-change-function ... */ @@ -1894,14 +1885,10 @@ as returned by `ispell-parse-output'." ;;*---------------------------------------------------------------------*/ ;;* flyspell-auto-correct-cache ... */ ;;*---------------------------------------------------------------------*/ -(defvar flyspell-auto-correct-pos nil) -(defvar flyspell-auto-correct-region nil) -(defvar flyspell-auto-correct-ring nil) -(defvar flyspell-auto-correct-word nil) -(make-variable-buffer-local 'flyspell-auto-correct-pos) -(make-variable-buffer-local 'flyspell-auto-correct-region) -(make-variable-buffer-local 'flyspell-auto-correct-ring) -(make-variable-buffer-local 'flyspell-auto-correct-word) +(defvar-local flyspell-auto-correct-pos nil) +(defvar-local flyspell-auto-correct-region nil) +(defvar-local flyspell-auto-correct-ring nil) +(defvar-local flyspell-auto-correct-word nil) ;;*---------------------------------------------------------------------*/ ;;* flyspell-check-previous-highlighted-word ... */ diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index 8d49a7c54c..ea46270508 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -351,9 +351,8 @@ If nil, the default personal dictionary for your spelling checker is used." :type 'boolean :group 'ispell) -(defvar ispell-local-dictionary-overridden nil +(defvar-local ispell-local-dictionary-overridden nil "Non-nil means the user has explicitly set this buffer's Ispell dictionary.") -(make-variable-buffer-local 'ispell-local-dictionary-overridden) (defcustom ispell-local-dictionary nil "If non-nil, the dictionary to be used for Ispell commands in this buffer. @@ -1748,7 +1747,7 @@ Note - substrings of other matches must come last (e.g. \"<[tT][tT]/\" and \"<[^ \\t\\n>]\").") (put 'ispell-html-skip-alists 'risky-local-variable t) -(defvar ispell-local-pdict ispell-personal-dictionary +(defvar-local ispell-local-pdict ispell-personal-dictionary "A buffer local variable containing the current personal dictionary. If non-nil, the value must be a string, which is a file name. @@ -1758,18 +1757,15 @@ to calling \\[ispell-change-dictionary]. This variable is automatically set when defined in the file with either `ispell-pdict-keyword' or the local variable syntax.") -(make-variable-buffer-local 'ispell-local-pdict) ;;;###autoload(put 'ispell-local-pdict 'safe-local-variable 'stringp) (defvar ispell-buffer-local-name nil "Contains the buffer name if local word definitions were used. Ispell is then restarted because the local words could conflict.") -(defvar ispell-buffer-session-localwords nil +(defvar-local ispell-buffer-session-localwords nil "List of words accepted for session in this buffer.") -(make-variable-buffer-local 'ispell-buffer-session-localwords) - (defvar ispell-parser 'use-mode-name "Indicates whether ispell should parse the current buffer as TeX Code. Special value `use-mode-name' tries to guess using the name of `major-mode'. diff --git a/lisp/textmodes/refill.el b/lisp/textmodes/refill.el index 6edd9aeb7e..8f4f3c5a23 100644 --- a/lisp/textmodes/refill.el +++ b/lisp/textmodes/refill.el @@ -88,10 +88,9 @@ ;;; "Refilling paragraphs on changes." ;;; :group 'fill) -(defvar refill-ignorable-overlay nil +(defvar-local refill-ignorable-overlay nil "Portion of the most recently filled paragraph not needing filling. This is used to optimize refilling.") -(make-variable-buffer-local 'refill-ignorable-overlay) (defun refill-adjust-ignorable-overlay (overlay afterp beg end &optional len) "Adjust OVERLAY to not include the about-to-be-modified region." @@ -149,7 +148,7 @@ This is used to optimize refilling.") "Like `fill-paragraph' but don't delete whitespace at paragraph end." (refill-fill-paragraph-at (point) arg)) -(defvar refill-doit nil +(defvar-local refill-doit nil "Non-nil tells `refill-post-command-function' to do its processing. Set by `refill-after-change-function' in `after-change-functions' and unset by `refill-post-command-function' in `post-command-hook', and @@ -157,7 +156,6 @@ sometimes `refill-pre-command-function' in `pre-command-hook'. This ensures refilling is only done once per command that causes a change, regardless of the number of after-change calls from commands doing complex processing.") -(make-variable-buffer-local 'refill-doit) (defun refill-after-change-function (beg end len) "Function for `after-change-functions' which just sets `refill-doit'." diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el index c50c544cb5..3e29f055ec 100644 --- a/lisp/textmodes/sgml-mode.el +++ b/lisp/textmodes/sgml-mode.el @@ -2290,19 +2290,17 @@ This takes effect when first loading the library.") nil t) (match-string-no-properties 1)))) -(defvar html--buffer-classes-cache nil +(defvar-local html--buffer-classes-cache nil "Cache for `html-current-buffer-classes'. When set, this should be a cons cell where the CAR is the buffer's tick counter (as produced by `buffer-modified-tick'), and the CDR is the list of class names found in the buffer.") -(make-variable-buffer-local 'html--buffer-classes-cache) -(defvar html--buffer-ids-cache nil +(defvar-local html--buffer-ids-cache nil "Cache for `html-current-buffer-ids'. When set, this should be a cons cell where the CAR is the buffer's tick counter (as produced by `buffer-modified-tick'), and the CDR is the list of class names found in the buffer.") -(make-variable-buffer-local 'html--buffer-ids-cache) (declare-function libxml-parse-html-region "xml.c" (start end &optional base-url discard-comments)) diff --git a/lisp/textmodes/table.el b/lisp/textmodes/table.el index 071684d3c4..06785e458b 100644 --- a/lisp/textmodes/table.el +++ b/lisp/textmodes/table.el @@ -859,11 +859,10 @@ cell to cache and cache to cell.") "Non-nil inhibits auto fill paragraph when `table-with-cache-buffer' exits. This is always set to nil at the entry to `table-with-cache-buffer' before executing body forms.") -(defvar table-mode-indicator nil +(defvar-local table-mode-indicator nil "For mode line indicator") ;; This is not a real minor-mode but placed in the minor-mode-alist ;; so that we can show the indicator on the mode line handy. -(make-variable-buffer-local 'table-mode-indicator) (unless (assq table-mode-indicator minor-mode-alist) (push '(table-mode-indicator (table-fixed-width-mode " Fixed-Table" " Table")) minor-mode-alist)) diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el index ce665e6165..d5a79ad0ac 100644 --- a/lisp/textmodes/tex-mode.el +++ b/lisp/textmodes/tex-mode.el @@ -2044,8 +2044,7 @@ In the tex shell buffer this command behaves like `comint-send-input'." (with-current-buffer buffer (setq default-directory directory)))) -(defvar tex-send-command-modified-tick 0) -(make-variable-buffer-local 'tex-send-command-modified-tick) +(defvar-local tex-send-command-modified-tick 0) (defun tex-shell-proc () (or (tex-shell-running) (error "No TeX subprocess"))) diff --git a/lisp/textmodes/two-column.el b/lisp/textmodes/two-column.el index 36aad84c0e..d072ab16c3 100644 --- a/lisp/textmodes/two-column.el +++ b/lisp/textmodes/two-column.el @@ -218,15 +218,13 @@ minus this value." ;; Markers seem to be the only buffer-id not affected by renaming a buffer. ;; This nevertheless loses when a buffer is killed. The variable-name is ;; required by `describe-mode'. -(defvar 2C-mode nil +(defvar-local 2C-mode nil "Marker to the associated buffer, if non-nil.") -(make-variable-buffer-local '2C-mode) (put '2C-mode 'permanent-local t) (setq minor-mode-alist (cons '(2C-mode " 2C") minor-mode-alist)) -(defvar 2C-autoscroll-start nil) -(make-variable-buffer-local '2C-autoscroll-start) +(defvar-local 2C-autoscroll-start nil) ;;;;; base functions ;;;;; commit 834ba2b6197369bb4cd8faa40c1f131594d30c75 Author: Stefan Kangas Date: Sun Jan 31 16:54:54 2021 +0100 Prefer defvar-local in cedet * lisp/cedet/ede.el (ede-object-root-project) (ede-object-project, ede-object): * lisp/cedet/mode-local.el (mode-local-symbol-table): * lisp/cedet/semantic.el (semantic--parse-table) (semantic-symbol->name-assoc-list) (semantic-symbol->name-assoc-list-for-type-parts) (semantic-case-fold, semantic--buffer-cache) (semantic-unmatched-syntax-cache) (semantic-unmatched-syntax-cache-check, semantic-parser-name) (semantic--completion-cache, semantic-parse-tree-state) (semantic-init-mode-hook, semantic-parser-warnings): * lisp/cedet/semantic/bovine.el (semantic-bovinate-nonterminal-check-obarray): * lisp/cedet/semantic/complete.el (semantic-collector-per-buffer-list): * lisp/cedet/semantic/ctxt.el (semantic-command-separation-character) (semantic-function-argument-separation-character): * lisp/cedet/semantic/db-find.el (semanticdb-find-lost-includes) (semanticdb-find-scanned-include-tags): * lisp/cedet/semantic/db.el (semanticdb-new-database-class) (semanticdb-default-find-index-class) (semanticdb-current-database, semanticdb-current-table) (semanticdb-project-system-databases) (semanticdb-out-of-buffer-create-table-fcn): * lisp/cedet/semantic/debug.el (semantic-debug-parser-source) (semantic-debug-parser-class) (semantic-debug-parser-debugger-source): * lisp/cedet/semantic/dep.el (semantic-dependency-include-path) (semantic-dependency-system-include-path): * lisp/cedet/semantic/format.el (semantic-function-argument-separator) (semantic-format-parent-separator): * lisp/cedet/semantic/fw.el (semantic-new-buffer-fcn-was-run): * lisp/cedet/semantic/grammar.el (semantic-grammar-macros) (semantic--grammar-macros-regexp-1) (semantic--grammar-macros-regexp-2): * lisp/cedet/semantic/idle.el (semantic-idle-scheduler-mode): * lisp/cedet/semantic/imenu.el (semantic-imenu-expandable-tag-classes): * lisp/cedet/semantic/lex-spp.el (semantic-lex-spp-macro-symbol-obarray) (semantic-lex-spp-project-macro-symbol-obarray) (semantic-lex-spp-dynamic-macro-symbol-obarray) (semantic-lex-spp-dynamic-macro-symbol-obarray-stack): * lisp/cedet/semantic/lex.el (semantic-flex-keywords-obarray) (semantic-lex-types-obarray, semantic-lex-analyzer) (semantic-lex-syntax-modifications, semantic-lex-syntax-table) (semantic-lex-comment-regex, semantic-lex-number-expression) (semantic-lex-depth, semantic-flex-extensions) (semantic-flex-syntax-modifications, semantic-ignore-comments) (semantic-flex-enable-newlines, semantic-flex-enable-whitespace) (semantic-flex-enable-bol, semantic-number-expression) (semantic-flex-depth): * lisp/cedet/semantic/senator.el (senator-isearch-semantic-mode): * lisp/cedet/semantic/sort.el (semantic-orphaned-member-metaparent-type): * lisp/cedet/semantic/tag.el (semantic-tag-expand-function): * lisp/cedet/semantic/util-modes.el (semantic-show-parser-state-string) (semantic-stickyfunc-sticky-classes) (semantic-highlight-func-ct-overlay): * lisp/cedet/semantic/util.el (semantic-type-relation-separator-character) (semantic-equivalent-major-modes): * lisp/cedet/semantic/wisent.el (wisent-error-function) (wisent-lexer-function): Prefer defvar-local. diff --git a/lisp/cedet/ede.el b/lisp/cedet/ede.el index 14289153e8..e3cc9062ed 100644 --- a/lisp/cedet/ede.el +++ b/lisp/cedet/ede.el @@ -140,22 +140,19 @@ specified by `ede-project-directories'." (defvar ede-projects nil "A list of all active projects currently loaded in Emacs.") -(defvar ede-object-root-project nil +(defvar-local ede-object-root-project nil "The current buffer's current root project. If a file is under a project, this specifies the project that is at the root of a project tree.") -(make-variable-buffer-local 'ede-object-root-project) -(defvar ede-object-project nil +(defvar-local ede-object-project nil "The current buffer's current project at that level. If a file is under a project, this specifies the project that contains the current target.") -(make-variable-buffer-local 'ede-object-project) -(defvar ede-object nil +(defvar-local ede-object nil "The current buffer's target object. This object's class determines how to compile and debug from a buffer.") -(make-variable-buffer-local 'ede-object) (defvar ede-selected-object nil "The currently user-selected project or target. diff --git a/lisp/cedet/mode-local.el b/lisp/cedet/mode-local.el index d1e528c4a0..63e0cef61a 100644 --- a/lisp/cedet/mode-local.el +++ b/lisp/cedet/mode-local.el @@ -170,11 +170,10 @@ definition." ;;; Core bindings API ;; -(defvar mode-local-symbol-table nil +(defvar-local mode-local-symbol-table nil "Buffer local mode bindings. These symbols provide a hook for a `major-mode' to specify specific behaviors. Use the function `mode-local-bind' to define new bindings.") -(make-variable-buffer-local 'mode-local-symbol-table) (defvar mode-local-active-mode nil "Major mode in which bindings are active.") diff --git a/lisp/cedet/semantic.el b/lisp/cedet/semantic.el index c64a9822c6..44bd4b0cd8 100644 --- a/lisp/cedet/semantic.el +++ b/lisp/cedet/semantic.el @@ -77,13 +77,12 @@ introduced." ;;; Variables and Configuration ;; -(defvar semantic--parse-table nil +(defvar-local semantic--parse-table nil "Variable that defines how to parse top level items in a buffer. This variable is for internal use only, and its content depends on the external parser used.") -(make-variable-buffer-local 'semantic--parse-table) -(defvar semantic-symbol->name-assoc-list +(defvar-local semantic-symbol->name-assoc-list '((type . "Types") (variable . "Variables") (function . "Functions") @@ -95,22 +94,19 @@ It is sometimes useful for a language to use a different string in place of the default, even though that language will still return a symbol. For example, Java return's includes, but the string can be replaced with `Imports'.") -(make-variable-buffer-local 'semantic-symbol->name-assoc-list) -(defvar semantic-symbol->name-assoc-list-for-type-parts nil +(defvar-local semantic-symbol->name-assoc-list-for-type-parts nil "Like `semantic-symbol->name-assoc-list' for type parts. Some tags that have children (see `semantic-tag-children-compatibility') will want to define the names of classes of tags differently than at the top level. For example, in C++, a Function may be called a Method. In addition, there may be new types of tags that exist only in classes, such as protection labels.") -(make-variable-buffer-local 'semantic-symbol->name-assoc-list-for-type-parts) -(defvar semantic-case-fold nil +(defvar-local semantic-case-fold nil "Value for `case-fold-search' when parsing.") -(make-variable-buffer-local 'semantic-case-fold) -(defvar semantic--buffer-cache nil +(defvar-local semantic--buffer-cache nil "A cache of the fully parsed buffer. If no significant changes have been made (based on the state) then this is returned instead of re-parsing the buffer. @@ -120,16 +116,13 @@ this is returned instead of re-parsing the buffer. If you need a tag list, use `semantic-fetch-tags'. If you need the cached values for some reason, chances are you can add a hook to `semantic-after-toplevel-cache-change-hook'.") -(make-variable-buffer-local 'semantic--buffer-cache) -(defvar semantic-unmatched-syntax-cache nil +(defvar-local semantic-unmatched-syntax-cache nil "A cached copy of unmatched syntax tokens.") -(make-variable-buffer-local 'semantic-unmatched-syntax-cache) -(defvar semantic-unmatched-syntax-cache-check nil +(defvar-local semantic-unmatched-syntax-cache-check nil "Non-nil if the unmatched syntax cache is out of date. This is tracked with `semantic-change-function'.") -(make-variable-buffer-local 'semantic-unmatched-syntax-cache-check) (defvar semantic-edits-are-safe nil "When non-nil, modifications do not require a reparse. @@ -180,19 +173,16 @@ during a flush when the cache is given a new value of nil.") :group 'semantic :type 'boolean) -(defvar semantic-parser-name "LL" +(defvar-local semantic-parser-name "LL" "Optional name of the parser used to parse input stream.") -(make-variable-buffer-local 'semantic-parser-name) -(defvar semantic--completion-cache nil +(defvar-local semantic--completion-cache nil "Internal variable used by `semantic-complete-symbol'.") -(make-variable-buffer-local 'semantic--completion-cache) ;;; Parse tree state management API ;; -(defvar semantic-parse-tree-state 'needs-rebuild +(defvar-local semantic-parse-tree-state 'needs-rebuild "State of the current parse tree.") -(make-variable-buffer-local 'semantic-parse-tree-state) (defmacro semantic-parse-tree-unparseable () "Indicate that the current buffer is unparseable. @@ -268,9 +258,8 @@ These functions are called by `semantic-new-buffer-fcn', before (defvar semantic-init-hook nil "Hook run when a buffer is initialized with a parsing table.") -(defvar semantic-init-mode-hook nil +(defvar-local semantic-init-mode-hook nil "Hook run when a buffer of a particular mode is initialized.") -(make-variable-buffer-local 'semantic-init-mode-hook) (defvar semantic-init-db-hook nil "Hook run when a buffer is initialized with a parsing table for DBs. @@ -729,9 +718,8 @@ This function returns semantic tags without overlays." ;; ;; Any parser can use this API to provide a list of warnings during a ;; parse which a user may want to investigate. -(defvar semantic-parser-warnings nil +(defvar-local semantic-parser-warnings nil "A list of parser warnings since the last full reparse.") -(make-variable-buffer-local 'semantic-parser-warnings) (defun semantic-clear-parser-warnings () "Clear the current list of parser warnings for this buffer." diff --git a/lisp/cedet/semantic/bovine.el b/lisp/cedet/semantic/bovine.el index 034ecb5ea1..3bc0e4dd61 100644 --- a/lisp/cedet/semantic/bovine.el +++ b/lisp/cedet/semantic/bovine.el @@ -41,10 +41,9 @@ ;;; Variables ;; -(defvar semantic-bovinate-nonterminal-check-obarray nil +(defvar-local semantic-bovinate-nonterminal-check-obarray nil "Obarray of streams already parsed for nonterminal symbols. Use this to detect infinite recursion during a parse.") -(make-variable-buffer-local 'semantic-bovinate-nonterminal-check-obarray) diff --git a/lisp/cedet/semantic/complete.el b/lisp/cedet/semantic/complete.el index 0a80b428e8..c83505818f 100644 --- a/lisp/cedet/semantic/complete.el +++ b/lisp/cedet/semantic/complete.el @@ -867,9 +867,8 @@ Expected return values are: ;; * semantic-collector-try-completion ;; * semantic-collector-all-completions -(defvar semantic-collector-per-buffer-list nil +(defvar-local semantic-collector-per-buffer-list nil "List of collectors active in this buffer.") -(make-variable-buffer-local 'semantic-collector-per-buffer-list) (defvar semantic-collector-list nil "List of global collectors active this session.") diff --git a/lisp/cedet/semantic/ctxt.el b/lisp/cedet/semantic/ctxt.el index 4d2defde35..8d5b5dcdbd 100644 --- a/lisp/cedet/semantic/ctxt.el +++ b/lisp/cedet/semantic/ctxt.el @@ -32,17 +32,15 @@ (require 'semantic) ;;; Code: -(defvar semantic-command-separation-character +(defvar-local semantic-command-separation-character ";" "String which indicates the end of a command. Used for identifying the end of a single command.") -(make-variable-buffer-local 'semantic-command-separation-character) -(defvar semantic-function-argument-separation-character +(defvar-local semantic-function-argument-separation-character "," "String which indicates the end of an argument. Used for identifying arguments to functions.") -(make-variable-buffer-local 'semantic-function-argument-separation-character) ;;; Local Contexts ;; diff --git a/lisp/cedet/semantic/db-find.el b/lisp/cedet/semantic/db-find.el index 14726e503d..db88463bfd 100644 --- a/lisp/cedet/semantic/db-find.el +++ b/lisp/cedet/semantic/db-find.el @@ -426,17 +426,15 @@ Default action as described in `semanticdb-find-translate-path'." ;; searchable item, then instead do the regular thing without caching. (semanticdb-find-translate-path-includes--internal path)))) -(defvar semanticdb-find-lost-includes nil +(defvar-local semanticdb-find-lost-includes nil "Include files that we cannot find associated with this buffer.") -(make-variable-buffer-local 'semanticdb-find-lost-includes) -(defvar semanticdb-find-scanned-include-tags nil +(defvar-local semanticdb-find-scanned-include-tags nil "All include tags scanned, plus action taken on the tag. Each entry is an alist: (ACTION . TAG) where ACTION is one of `scanned', `duplicate', `lost' and TAG is a clone of the include tag that was found.") -(make-variable-buffer-local 'semanticdb-find-scanned-include-tags) (defvar semanticdb-implied-include-tags nil "Include tags implied for all files of a given mode. diff --git a/lisp/cedet/semantic/db.el b/lisp/cedet/semantic/db.el index b9b10917dc..8f9eceea55 100644 --- a/lisp/cedet/semantic/db.el +++ b/lisp/cedet/semantic/db.el @@ -50,27 +50,23 @@ (defvar semanticdb-database-list nil "List of all active databases.") -(defvar semanticdb-new-database-class 'semanticdb-project-database-file +(defvar-local semanticdb-new-database-class 'semanticdb-project-database-file "The default type of database created for new files. This can be changed on a per file basis, so that some directories are saved using one mechanism, and some directories via a different mechanism.") -(make-variable-buffer-local 'semanticdb-new-database-class) -(defvar semanticdb-default-find-index-class 'semanticdb-find-search-index +(defvar-local semanticdb-default-find-index-class 'semanticdb-find-search-index "The default type of search index to use for a `semanticdb-table's. This can be changed to try out new types of search indices.") -(make-variable-buffer-local 'semanticdb-default-find=index-class) ;;;###autoload -(defvar semanticdb-current-database nil +(defvar-local semanticdb-current-database nil "For a given buffer, this is the currently active database.") -(make-variable-buffer-local 'semanticdb-current-database) ;;;###autoload -(defvar semanticdb-current-table nil +(defvar-local semanticdb-current-table nil "For a given buffer, this is the currently active database table.") -(make-variable-buffer-local 'semanticdb-current-table) ;;; ABSTRACT CLASSES ;; @@ -825,13 +821,12 @@ must return a string, (the root directory) or a list of strings (multiple root directories in a more complex system). This variable should be used by project management programs like EDE or JDE.") -(defvar semanticdb-project-system-databases nil +(defvar-local semanticdb-project-system-databases nil "List of databases containing system library information. Mode authors can create their own system databases which know detailed information about the system libraries for querying purposes. Put those into this variable as a buffer-local, or mode-local value.") -(make-variable-buffer-local 'semanticdb-project-system-databases) (defvar semanticdb-search-system-databases t "Non-nil if search routines are to include a system database.") @@ -1016,10 +1011,9 @@ DONTLOAD does not affect the creation of new database objects." ) ))) -(defvar semanticdb-out-of-buffer-create-table-fcn nil +(defvar-local semanticdb-out-of-buffer-create-table-fcn nil "When non-nil, a function for creating a semanticdb table. This should take a filename to be parsed.") -(make-variable-buffer-local 'semanticdb-out-of-buffer-create-table-fcn) (defun semanticdb-create-table-for-file-not-in-buffer (filename) "Create a table for the file FILENAME. diff --git a/lisp/cedet/semantic/debug.el b/lisp/cedet/semantic/debug.el index b3e8f076d0..ce4afbbf26 100644 --- a/lisp/cedet/semantic/debug.el +++ b/lisp/cedet/semantic/debug.el @@ -44,24 +44,18 @@ ;;; Code: ;;;###autoload -(defvar semantic-debug-parser-source nil +(defvar-local semantic-debug-parser-source nil "For any buffer, the file name (no path) of the parser. This would be a parser for a specific language, not the source to one of the parser generators.") -;;;###autoload -(make-variable-buffer-local 'semantic-debug-parser-source) ;;;###autoload -(defvar semantic-debug-parser-class nil +(defvar-local semantic-debug-parser-class nil "Class to create when building a debug parser object.") -;;;###autoload -(make-variable-buffer-local 'semantic-debug-parser-class) ;;;###autoload -(defvar semantic-debug-parser-debugger-source nil +(defvar-local semantic-debug-parser-debugger-source nil "Location of the debug parser class.") -;;;###autoload -(make-variable-buffer-local 'semantic-debug-parser-source) (defvar semantic-debug-enabled nil "Non-nil when debugging a parser.") diff --git a/lisp/cedet/semantic/dep.el b/lisp/cedet/semantic/dep.el index 0fba2a2f09..db8be5ecf4 100644 --- a/lisp/cedet/semantic/dep.el +++ b/lisp/cedet/semantic/dep.el @@ -39,7 +39,7 @@ ;;; Code: -(defvar semantic-dependency-include-path nil +(defvar-local semantic-dependency-include-path nil "Defines the include path used when searching for files. This should be a list of directories to search which is specific to the file being included. @@ -56,9 +56,8 @@ reparsed, the cache will be reset. TODO: use ffap.el to locate such items? NOTE: Obsolete this, or use as special user") -(make-variable-buffer-local 'semantic-dependency-include-path) -(defvar semantic-dependency-system-include-path nil +(defvar-local semantic-dependency-system-include-path nil "Defines the system include path. This should be set with either `defvar-mode-local', or with `semantic-add-system-include'. @@ -71,7 +70,6 @@ When searching for a file associated with a name found in a tag of class include, this path will be inspected for includes of type `system'. Some include tags are agnostic to this setting and will check both the project and system directories.") -(make-variable-buffer-local 'semantic-dependency-system-include-path) (defmacro defcustom-mode-local-semantic-dependency-system-include-path (mode name value &optional docstring) diff --git a/lisp/cedet/semantic/format.el b/lisp/cedet/semantic/format.el index f9c5365a29..8927ccde84 100644 --- a/lisp/cedet/semantic/format.el +++ b/lisp/cedet/semantic/format.el @@ -78,13 +78,11 @@ Images can be used as icons instead of some types of text strings." :group 'semantic :type 'boolean) -(defvar semantic-function-argument-separator "," +(defvar-local semantic-function-argument-separator "," "Text used to separate arguments when creating text from tags.") -(make-variable-buffer-local 'semantic-function-argument-separator) -(defvar semantic-format-parent-separator "::" +(defvar-local semantic-format-parent-separator "::" "Text used to separate names when between namespaces/classes and functions.") -(make-variable-buffer-local 'semantic-format-parent-separator) (defvar semantic-format-face-alist `( (function . font-lock-function-name-face) diff --git a/lisp/cedet/semantic/fw.el b/lisp/cedet/semantic/fw.el index f034ba01a4..91944c44f5 100644 --- a/lisp/cedet/semantic/fw.el +++ b/lisp/cedet/semantic/fw.el @@ -243,9 +243,8 @@ Avoid using a large BODY since it is duplicated." ;;; Misc utilities ;; -(defvar semantic-new-buffer-fcn-was-run nil +(defvar-local semantic-new-buffer-fcn-was-run nil "Non-nil after `semantic-new-buffer-fcn' has been executed.") -(make-variable-buffer-local 'semantic-new-buffer-fcn-was-run) (defsubst semantic-active-p () "Return non-nil if the current buffer was set up for parsing." diff --git a/lisp/cedet/semantic/grammar.el b/lisp/cedet/semantic/grammar.el index 7721a834ea..4551811c23 100644 --- a/lisp/cedet/semantic/grammar.el +++ b/lisp/cedet/semantic/grammar.el @@ -432,9 +432,8 @@ Also load the specified macro libraries." defs))) (nreverse defs))) -(defvar semantic-grammar-macros nil +(defvar-local semantic-grammar-macros nil "List of associations (MACRO-NAME . EXPANDER).") -(make-variable-buffer-local 'semantic-grammar-macros) (defun semantic-grammar-macros () "Build and return the alist of defined macros." @@ -1054,8 +1053,7 @@ See also the variable `semantic-grammar-file-regexp'." ;;;; Macros highlighting ;;;; -(defvar semantic--grammar-macros-regexp-1 nil) -(make-variable-buffer-local 'semantic--grammar-macros-regexp-1) +(defvar-local semantic--grammar-macros-regexp-1 nil) (defun semantic--grammar-macros-regexp-1 () "Return font-lock keyword regexp for pre-installed macro names." @@ -1076,8 +1074,7 @@ See also the variable `semantic-grammar-file-regexp'." "\\<%use-macros\\>[ \t\r\n]+\\(\\sw\\|\\s_\\)+[ \t\r\n]+{" "Regexp that matches a macro declaration statement.") -(defvar semantic--grammar-macros-regexp-2 nil) -(make-variable-buffer-local 'semantic--grammar-macros-regexp-2) +(defvar-local semantic--grammar-macros-regexp-2 nil) (defun semantic--grammar-clear-macros-regexp-2 (&rest _) "Clear the cached regexp that match macros local in this grammar. diff --git a/lisp/cedet/semantic/idle.el b/lisp/cedet/semantic/idle.el index 4898c85b21..73954f0266 100644 --- a/lisp/cedet/semantic/idle.el +++ b/lisp/cedet/semantic/idle.el @@ -135,10 +135,9 @@ it is unlikely the user would be ready to type again right away." :group 'semantic :type 'hook) -(defvar semantic-idle-scheduler-mode nil +(defvar-local semantic-idle-scheduler-mode nil "Non-nil if idle-scheduler minor mode is enabled. Use the command `semantic-idle-scheduler-mode' to change this variable.") -(make-variable-buffer-local 'semantic-idle-scheduler-mode) (defcustom semantic-idle-scheduler-max-buffer-size 0 "Maximum size in bytes of buffers where idle-scheduler is enabled. diff --git a/lisp/cedet/semantic/imenu.el b/lisp/cedet/semantic/imenu.el index 2898f3711a..4c13959ba1 100644 --- a/lisp/cedet/semantic/imenu.el +++ b/lisp/cedet/semantic/imenu.el @@ -136,12 +136,11 @@ other buffer local ones based on the same semanticdb." "Non-nil if `semantic-imenu-rebuild-directory-indexes' is running.") ;;;###autoload -(defvar semantic-imenu-expandable-tag-classes '(type) +(defvar-local semantic-imenu-expandable-tag-classes '(type) "List of expandable tag classes. Tags of those classes will be given submenu with children. By default, a `type' has interesting children. In Texinfo, however, a `section' has interesting children.") -(make-variable-buffer-local 'semantic-imenu-expandable-tag-classes) ;;; Code: (defun semantic-imenu-tag-overlay (tag) diff --git a/lisp/cedet/semantic/lex-spp.el b/lisp/cedet/semantic/lex-spp.el index 8b83c09eb1..408011c628 100644 --- a/lisp/cedet/semantic/lex-spp.el +++ b/lisp/cedet/semantic/lex-spp.el @@ -73,28 +73,24 @@ (declare-function c-end-of-macro "cc-engine") ;;; Code: -(defvar semantic-lex-spp-macro-symbol-obarray nil +(defvar-local semantic-lex-spp-macro-symbol-obarray nil "Table of macro keywords used by the Semantic Preprocessor. These symbols will be used in addition to those in `semantic-lex-spp-dynamic-macro-symbol-obarray'.") -(make-variable-buffer-local 'semantic-lex-spp-macro-symbol-obarray) -(defvar semantic-lex-spp-project-macro-symbol-obarray nil +(defvar-local semantic-lex-spp-project-macro-symbol-obarray nil "Table of macro keywords for this project. These symbols will be used in addition to those in `semantic-lex-spp-dynamic-macro-symbol-obarray'.") -(make-variable-buffer-local 'semantic-lex-spp-project-macro-symbol-obarray) -(defvar semantic-lex-spp-dynamic-macro-symbol-obarray nil +(defvar-local semantic-lex-spp-dynamic-macro-symbol-obarray nil "Table of macro keywords used during lexical analysis. Macros are lexical symbols which are replaced by other lexical tokens during lexical analysis. During analysis symbols can be added and removed from this symbol table.") -(make-variable-buffer-local 'semantic-lex-spp-dynamic-macro-symbol-obarray) -(defvar semantic-lex-spp-dynamic-macro-symbol-obarray-stack nil +(defvar-local semantic-lex-spp-dynamic-macro-symbol-obarray-stack nil "A stack of obarrays for temporarily scoped macro values.") -(make-variable-buffer-local 'semantic-lex-spp-dynamic-macro-symbol-obarray-stack) (defvar semantic-lex-spp-expanded-macro-stack nil "The stack of lexical SPP macros we have expanded.") diff --git a/lisp/cedet/semantic/lex.el b/lisp/cedet/semantic/lex.el index 993c1dc14b..4cafc7d4fe 100644 --- a/lisp/cedet/semantic/lex.el +++ b/lisp/cedet/semantic/lex.el @@ -202,10 +202,9 @@ as a PROPERTY value. FUN receives a symbol as argument." ;; These keywords are keywords defined for using in a grammar with the ;; %keyword declaration, and are not keywords used in Emacs Lisp. -(defvar semantic-flex-keywords-obarray nil +(defvar-local semantic-flex-keywords-obarray nil "Buffer local keyword obarray for the lexical analyzer. These keywords are matched explicitly, and converted into special symbols.") -(make-variable-buffer-local 'semantic-flex-keywords-obarray) (defmacro semantic-lex-keyword-invalid (name) "Signal that NAME is an invalid keyword name." @@ -333,9 +332,8 @@ so that analysis can continue, if possible." ;; with the %type declaration. Types represent different syntaxes. ;; See code for `semantic-lex-preset-default-types' for the classic ;; types of syntax. -(defvar semantic-lex-types-obarray nil +(defvar-local semantic-lex-types-obarray nil "Buffer local types obarray for the lexical analyzer.") -(make-variable-buffer-local 'semantic-lex-types-obarray) (defun semantic-lex-type-invalid (type) "Signal that TYPE is an invalid lexical type name." @@ -472,11 +470,10 @@ PROPERTY set." ;; ;; FIXME change to non-obsolete default. -(defvar semantic-lex-analyzer 'semantic-flex +(defvar-local semantic-lex-analyzer 'semantic-flex "The lexical analyzer used for a given buffer. See `semantic-lex' for documentation. For compatibility with Semantic 1.x it defaults to `semantic-flex'.") -(make-variable-buffer-local 'semantic-lex-analyzer) (defvar semantic-lex-tokens '( @@ -558,7 +555,7 @@ The key to this alist is the symbol representing token type that - whitespace: Characters that match `\\s-+' regexp. This token is produced with `semantic-lex-whitespace'.") -(defvar semantic-lex-syntax-modifications nil +(defvar-local semantic-lex-syntax-modifications nil "Changes to the syntax table for this buffer. These changes are active only while the buffer is being flexed. This is a list where each element has the form: @@ -566,20 +563,17 @@ This is a list where each element has the form: CHAR is the char passed to `modify-syntax-entry', and CLASS is the string also passed to `modify-syntax-entry' to define what syntax class CHAR has.") -(make-variable-buffer-local 'semantic-lex-syntax-modifications) -(defvar semantic-lex-syntax-table nil +(defvar-local semantic-lex-syntax-table nil "Syntax table used by lexical analysis. See also `semantic-lex-syntax-modifications'.") -(make-variable-buffer-local 'semantic-lex-syntax-table) -(defvar semantic-lex-comment-regex nil +(defvar-local semantic-lex-comment-regex nil "Regular expression for identifying comment start during lexical analysis. This may be automatically set when semantic initializes in a mode, but may need to be overridden for some special languages.") -(make-variable-buffer-local 'semantic-lex-comment-regex) -(defvar semantic-lex-number-expression +(defvar-local semantic-lex-number-expression ;; This expression was written by David Ponce for Java, and copied ;; here for C and any other similar language. (eval-when-compile @@ -628,12 +622,10 @@ FLOATING_POINT_LITERAL: | [0-9]+[fFdD]? | [0-9]+?[fFdD] ;") -(make-variable-buffer-local 'semantic-lex-number-expression) -(defvar semantic-lex-depth 0 +(defvar-local semantic-lex-depth 0 "Default lexing depth. This specifies how many lists to create tokens in.") -(make-variable-buffer-local 'semantic-lex-depth) (defvar semantic-lex-unterminated-syntax-end-function (lambda (_syntax _syntax-start lex-end) lex-end) @@ -1768,7 +1760,7 @@ when finding unterminated syntax.") (make-obsolete-variable 'semantic-flex-unterminated-syntax-end-function nil "28.1") -(defvar semantic-flex-extensions nil +(defvar-local semantic-flex-extensions nil "Buffer local extensions to the lexical analyzer. This should contain an alist with a key of a regex and a data element of a function. The function should both move point, and return a lexical @@ -1777,10 +1769,9 @@ token of the form: nil is also a valid return value. TYPE can be any type of symbol, as long as it doesn't occur as a nonterminal in the language definition.") -(make-variable-buffer-local 'semantic-flex-extensions) (make-obsolete-variable 'semantic-flex-extensions nil "28.1") -(defvar semantic-flex-syntax-modifications nil +(defvar-local semantic-flex-syntax-modifications nil "Changes to the syntax table for this buffer. These changes are active only while the buffer is being flexed. This is a list where each element has the form: @@ -1788,47 +1779,40 @@ This is a list where each element has the form: CHAR is the char passed to `modify-syntax-entry', and CLASS is the string also passed to `modify-syntax-entry' to define what syntax class CHAR has.") -(make-variable-buffer-local 'semantic-flex-syntax-modifications) (make-obsolete-variable 'semantic-flex-syntax-modifications nil "28.1") -(defvar semantic-ignore-comments t +(defvar-local semantic-ignore-comments t "Default comment handling. The value t means to strip comments when flexing; nil means to keep comments as part of the token stream.") -(make-variable-buffer-local 'semantic-ignore-comments) (make-obsolete-variable 'semantic-ignore-comments nil "28.1") -(defvar semantic-flex-enable-newlines nil +(defvar-local semantic-flex-enable-newlines nil "When flexing, report newlines as syntactic elements. Useful for languages where the newline is a special case terminator. Only set this on a per mode basis, not globally.") -(make-variable-buffer-local 'semantic-flex-enable-newlines) (make-obsolete-variable 'semantic-flex-enable-newlines nil "28.1") -(defvar semantic-flex-enable-whitespace nil +(defvar-local semantic-flex-enable-whitespace nil "When flexing, report whitespace as syntactic elements. Useful for languages where the syntax is whitespace dependent. Only set this on a per mode basis, not globally.") -(make-variable-buffer-local 'semantic-flex-enable-whitespace) (make-obsolete-variable 'semantic-flex-enable-whitespace nil "28.1") -(defvar semantic-flex-enable-bol nil +(defvar-local semantic-flex-enable-bol nil "When flexing, report beginning of lines as syntactic elements. Useful for languages like python which are indentation sensitive. Only set this on a per mode basis, not globally.") -(make-variable-buffer-local 'semantic-flex-enable-bol) (make-obsolete-variable 'semantic-flex-enable-bol nil "28.1") -(defvar semantic-number-expression semantic-lex-number-expression +(defvar-local semantic-number-expression semantic-lex-number-expression "See variable `semantic-lex-number-expression'.") -(make-variable-buffer-local 'semantic-number-expression) (make-obsolete-variable 'semantic-number-expression 'semantic-lex-number-expression "28.1") -(defvar semantic-flex-depth 0 +(defvar-local semantic-flex-depth 0 "Default flexing depth. This specifies how many lists to create tokens in.") -(make-variable-buffer-local 'semantic-flex-depth) (make-obsolete-variable 'semantic-flex-depth nil "28.1") (provide 'semantic/lex) diff --git a/lisp/cedet/semantic/senator.el b/lisp/cedet/semantic/senator.el index 6768b432f6..f33356a170 100644 --- a/lisp/cedet/semantic/senator.el +++ b/lisp/cedet/semantic/senator.el @@ -601,10 +601,9 @@ Makes C/C++ language like assumptions." ) (t nil))) -(defvar senator-isearch-semantic-mode nil +(defvar-local senator-isearch-semantic-mode nil "Non-nil if isearch does semantic search. This is a buffer local variable.") -(make-variable-buffer-local 'senator-isearch-semantic-mode) (defun senator-beginning-of-defun (&optional arg) "Move backward to the beginning of a defun. diff --git a/lisp/cedet/semantic/sort.el b/lisp/cedet/semantic/sort.el index 154a56a27a..19f46ff7f1 100644 --- a/lisp/cedet/semantic/sort.el +++ b/lisp/cedet/semantic/sort.el @@ -310,11 +310,10 @@ may re-organize the list with side-effects." ;; external members, and bring them together in a cloned copy of the ;; class tag. ;; -(defvar semantic-orphaned-member-metaparent-type "class" +(defvar-local semantic-orphaned-member-metaparent-type "class" "In `semantic-adopt-external-members', the type of 'type for metaparents. A metaparent is a made-up type semantic token used to hold the child list of orphaned members of a named type.") -(make-variable-buffer-local 'semantic-orphaned-member-metaparent-type) (defvar semantic-mark-external-member-function nil "Function called when an externally defined orphan is found. diff --git a/lisp/cedet/semantic/tag.el b/lisp/cedet/semantic/tag.el index d68ffa55d6..85defe4f2c 100644 --- a/lisp/cedet/semantic/tag.el +++ b/lisp/cedet/semantic/tag.el @@ -1194,7 +1194,7 @@ See also the function `semantic--expand-tag'." (setq tag (cdr tag))) (null tag))) -(defvar semantic-tag-expand-function nil +(defvar-local semantic-tag-expand-function nil "Function used to expand a tag. It is passed each tag production, and must return a list of tags derived from it, or nil if it does not need to be expanded. @@ -1207,7 +1207,6 @@ following definition is easily parsed into one tag: This function should take this compound tag and turn it into two tags, one for A, and the other for B.") -(make-variable-buffer-local 'semantic-tag-expand-function) (defun semantic--tag-expand (tag) "Convert TAG from a raw state to a cooked state, and expand it. diff --git a/lisp/cedet/semantic/util-modes.el b/lisp/cedet/semantic/util-modes.el index 45eef10f00..f8d6bb759b 100644 --- a/lisp/cedet/semantic/util-modes.el +++ b/lisp/cedet/semantic/util-modes.el @@ -498,10 +498,9 @@ non-nil if the minor mode is enabled." (semantic-add-minor-mode 'semantic-show-parser-state-mode "") -(defvar semantic-show-parser-state-string nil +(defvar-local semantic-show-parser-state-string nil "String showing the parser state for this buffer. See `semantic-show-parser-state-marker' for details.") -(make-variable-buffer-local 'semantic-show-parser-state-string) (defun semantic-show-parser-state-marker (&rest ignore) "Set `semantic-show-parser-state-string' to indicate parser state. @@ -713,10 +712,9 @@ non-nil if the minor mode is enabled." (setq header-line-format semantic-stickyfunc-old-hlf) (kill-local-variable 'semantic-stickyfunc-old-hlf))))) -(defvar semantic-stickyfunc-sticky-classes +(defvar-local semantic-stickyfunc-sticky-classes '(function type) "List of tag classes which stickyfunc will display in the header line.") -(make-variable-buffer-local 'semantic-stickyfunc-sticky-classes) (defcustom semantic-stickyfunc-show-only-functions-p nil "Non-nil means don't show lines that aren't part of a tag. @@ -886,9 +884,8 @@ Argument EVENT describes the event that caused this function to be called." ) (select-window startwin))) -(defvar semantic-highlight-func-ct-overlay nil +(defvar-local semantic-highlight-func-ct-overlay nil "Overlay used to highlight the tag the cursor is in.") -(make-variable-buffer-local 'semantic-highlight-func-ct-overlay) (defface semantic-highlight-func-current-tag-face '((((class color) (background dark)) diff --git a/lisp/cedet/semantic/util.el b/lisp/cedet/semantic/util.el index 7d33d0e088..8c487e14ed 100644 --- a/lisp/cedet/semantic/util.el +++ b/lisp/cedet/semantic/util.el @@ -39,20 +39,18 @@ ;;; Code: -(defvar semantic-type-relation-separator-character '(".") +(defvar-local semantic-type-relation-separator-character '(".") "Character strings used to separate a parent/child relationship. This list of strings are used for displaying or finding separators in variable field dereferencing. The first character will be used for display. In C, a type field is separated like this: \"type.field\" thus, the character is a \".\". In C, and additional value of \"->\" would be in the list, so that \"type->field\" could be found.") -(make-variable-buffer-local 'semantic-type-relation-separator-character) -(defvar semantic-equivalent-major-modes nil +(defvar-local semantic-equivalent-major-modes nil "List of major modes which are considered equivalent. Equivalent modes share a parser, and a set of override methods. A value of nil means that the current major mode is the only one.") -(make-variable-buffer-local 'semantic-equivalent-major-modes) (declare-function semanticdb-file-stream "semantic/db" (file)) diff --git a/lisp/cedet/semantic/wisent.el b/lisp/cedet/semantic/wisent.el index fb4d0b074a..d5b73244a0 100644 --- a/lisp/cedet/semantic/wisent.el +++ b/lisp/cedet/semantic/wisent.el @@ -93,15 +93,13 @@ it to a form suitable for the Wisent's parser." ;;; Syntax analysis ;; -(defvar wisent-error-function nil +(defvar-local wisent-error-function nil "Function used to report parse error. By default use the function `wisent-message'.") -(make-variable-buffer-local 'wisent-error-function) -(defvar wisent-lexer-function 'wisent-lex +(defvar-local wisent-lexer-function 'wisent-lex "Function used to obtain the next lexical token in input. Should be a lexical analyzer created with `define-wisent-lexer'.") -(make-variable-buffer-local 'wisent-lexer-function) ;; Tag production ;; commit 21d9303c61ce5ecc81fd7ea96aeb94b5b03bee79 Author: Stefan Kangas Date: Sun Jan 31 16:30:55 2021 +0100 Prefer defvar-local in net/*.el * lisp/net/browse-url.el (browse-url-temp-file-name): * lisp/net/rcirc.el (rcirc-ignore-buffer-activity-flag) (rcirc-low-priority-flag, rcirc-parent-buffer) (rcirc-activity-types, rcirc-last-sender): * lisp/net/soap-inspect.el (soap-inspect-previous-items) (soap-inspect-current-item): * lisp/net/telnet.el (telnet-remote-echoes) (telnet-interrupt-string, telnet-count): Prefer defvar-local. diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el index 7b72a71362..58f01d5bf9 100644 --- a/lisp/net/browse-url.el +++ b/lisp/net/browse-url.el @@ -481,8 +481,7 @@ Used by the `browse-url-of-file' command." "Hook run after `browse-url-of-file' has asked a browser to load a file." :type 'hook) -(defvar browse-url-temp-file-name nil) -(make-variable-buffer-local 'browse-url-temp-file-name) +(defvar-local browse-url-temp-file-name nil) (defcustom browse-url-xterm-program "xterm" "The name of the terminal emulator used by `browse-url-text-xterm'. diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el index 22348a1725..58cc8b1be5 100644 --- a/lisp/net/rcirc.el +++ b/lisp/net/rcirc.el @@ -178,13 +178,11 @@ If nil, no maximum is applied." :type '(choice (const :tag "No maximum" nil) (integer :tag "Number of characters"))) -(defvar rcirc-ignore-buffer-activity-flag nil +(defvar-local rcirc-ignore-buffer-activity-flag nil "If non-nil, ignore activity in this buffer.") -(make-variable-buffer-local 'rcirc-ignore-buffer-activity-flag) -(defvar rcirc-low-priority-flag nil +(defvar-local rcirc-low-priority-flag nil "If non-nil, activity in this buffer is considered low priority.") -(make-variable-buffer-local 'rcirc-low-priority-flag) (defcustom rcirc-omit-responses '("JOIN" "PART" "QUIT" "NICK") @@ -1328,8 +1326,7 @@ Create the buffer if it doesn't exist." (rcirc-send-string process (concat command " :" args))))))) -(defvar rcirc-parent-buffer nil) -(make-variable-buffer-local 'rcirc-parent-buffer) +(defvar-local rcirc-parent-buffer nil) (put 'rcirc-parent-buffer 'permanent-local t) (defvar rcirc-window-configuration nil) (defun rcirc-edit-multiline () @@ -1501,10 +1498,8 @@ is found by looking up RESPONSE in `rcirc-response-formats'." ((or (rcirc-get-buffer process target) (rcirc-any-buffer process)))))) -(defvar rcirc-activity-types nil) -(make-variable-buffer-local 'rcirc-activity-types) -(defvar rcirc-last-sender nil) -(make-variable-buffer-local 'rcirc-last-sender) +(defvar-local rcirc-activity-types nil) +(defvar-local rcirc-last-sender nil) (defcustom rcirc-omit-threshold 100 "Lines since last activity from a nick before `rcirc-omit-responses' are omitted." diff --git a/lisp/net/soap-inspect.el b/lisp/net/soap-inspect.el index 604e35c07c..9d4e440719 100644 --- a/lisp/net/soap-inspect.el +++ b/lisp/net/soap-inspect.el @@ -206,17 +206,13 @@ This is a specialization of `soap-sample-value' for ;;; soap-inspect -(defvar soap-inspect-previous-items nil +(defvar-local soap-inspect-previous-items nil "A stack of previously inspected items in the *soap-inspect* buffer. Used to implement the BACK button.") -(defvar soap-inspect-current-item nil +(defvar-local soap-inspect-current-item nil "The current item being inspected in the *soap-inspect* buffer.") -(progn - (make-variable-buffer-local 'soap-inspect-previous-items) - (make-variable-buffer-local 'soap-inspect-current-item)) - (defun soap-inspect (element) "Inspect a SOAP ELEMENT in the *soap-inspect* buffer. The buffer is populated with information about ELEMENT with links diff --git a/lisp/net/telnet.el b/lisp/net/telnet.el index 67f844428a..44f535f01c 100644 --- a/lisp/net/telnet.el +++ b/lisp/net/telnet.el @@ -72,15 +72,12 @@ LOGIN-NAME, which is optional, says what to log in as on that machine.") (defvar telnet-prompt-pattern "^[^#$%>\n]*[#$%>] *") (defvar telnet-replace-c-g nil) -(make-variable-buffer-local - (defvar telnet-remote-echoes t - "True if the telnet process will echo input.")) -(make-variable-buffer-local - (defvar telnet-interrupt-string "\C-c" "String sent by C-c.")) +(defvar-local telnet-remote-echoes t + "True if the telnet process will echo input.") +(defvar-local telnet-interrupt-string "\C-c" "String sent by C-c.") -(defvar telnet-count 0 +(defvar-local telnet-count 0 "Number of output strings from telnet process while looking for password.") -(make-variable-buffer-local 'telnet-count) (defvar telnet-program "telnet" "Program to run to open a telnet connection.") commit a5885d9d633f0a0e2e23d5d9f48d6b70a6301442 Author: Stefan Kangas Date: Sun Jan 31 16:27:26 2021 +0100 Prefer defvar-local in vc/*.el * lisp/vc/ediff-diff.el (ediff-whitespace, ediff-word-1) (ediff-word-2, ediff-word-3, ediff-word-4): * lisp/vc/ediff-init.el (ediff-defvar-local): * lisp/vc/smerge-mode.el (smerge-check-cache): * lisp/vc/vc-bzr.el (vc-bzr-annotation-table): * lisp/vc/vc-dispatcher.el (vc-mode-line-hook): Prefer defvar-local. diff --git a/lisp/vc/ediff-diff.el b/lisp/vc/ediff-diff.el index e90eaa1156..fde9d4338f 100644 --- a/lisp/vc/ediff-diff.el +++ b/lisp/vc/ediff-diff.el @@ -1230,35 +1230,30 @@ are ignored." Used for splitting difference regions into individual words.") ;; \240 is Unicode symbol for nonbreakable whitespace -(defvar ediff-whitespace " \n\t\f\r\240" +(defvar-local ediff-whitespace " \n\t\f\r\240" "Characters constituting white space. These characters are ignored when differing regions are split into words.") -(make-variable-buffer-local 'ediff-whitespace) -(defvar ediff-word-1 "-[:word:]_" +(defvar-local ediff-word-1 "-[:word:]_" "Characters that constitute words of type 1. More precisely, [ediff-word-1] is a regexp that matches type 1 words. See `ediff-forward-word' for more details.") -(make-variable-buffer-local 'ediff-word-1) -(defvar ediff-word-2 "0-9.," +(defvar-local ediff-word-2 "0-9.," "Characters that constitute words of type 2. More precisely, [ediff-word-2] is a regexp that matches type 2 words. See `ediff-forward-word' for more details.") -(make-variable-buffer-local 'ediff-word-2) -(defvar ediff-word-3 "`'?!:;\"{}[]()" +(defvar-local ediff-word-3 "`'?!:;\"{}[]()" "Characters that constitute words of type 3. More precisely, [ediff-word-3] is a regexp that matches type 3 words. See `ediff-forward-word' for more details.") -(make-variable-buffer-local 'ediff-word-3) -(defvar ediff-word-4 +(defvar-local ediff-word-4 (concat "^" ediff-word-1 ediff-word-2 ediff-word-3 ediff-whitespace) "Characters that constitute words of type 4. More precisely, [ediff-word-4] is a regexp that matches type 4 words. See `ediff-forward-word' for more details.") -(make-variable-buffer-local 'ediff-word-4) ;; Split region along word boundaries. Each word will be on its own line. ;; Output to buffer out-buffer. diff --git a/lisp/vc/ediff-init.el b/lisp/vc/ediff-init.el index 0865ac5ce4..c20d03c83d 100644 --- a/lisp/vc/ediff-init.el +++ b/lisp/vc/ediff-init.el @@ -80,13 +80,12 @@ that Ediff doesn't know about.") ;; so that `kill-all-local-variables' (called by major-mode setting ;; commands) won't destroy Ediff control variables. ;; -;; Plagiarized from `emerge-defvar-local' for XEmacs. +;; Plagiarized from `emerge-defvar-local'. (defmacro ediff-defvar-local (var value doc) "Defines VAR as a local variable." (declare (indent defun) (doc-string 3)) `(progn - (defvar ,var ,value ,doc) - (make-variable-buffer-local ',var) + (defvar-local ,var ,value ,doc) (put ',var 'permanent-local t))) diff --git a/lisp/vc/smerge-mode.el b/lisp/vc/smerge-mode.el index 3b09dfe5d2..f50b2540c5 100644 --- a/lisp/vc/smerge-mode.el +++ b/lisp/vc/smerge-mode.el @@ -173,8 +173,7 @@ Used in `smerge-diff-base-upper' and related functions." `((,smerge-command-prefix . ,smerge-basic-map)) "Keymap for `smerge-mode'.") -(defvar smerge-check-cache nil) -(make-variable-buffer-local 'smerge-check-cache) +(defvar-local smerge-check-cache nil) (defun smerge-check (n) (condition-case nil (let ((state (cons (point) (buffer-modified-tick)))) diff --git a/lisp/vc/vc-bzr.el b/lisp/vc/vc-bzr.el index e4eff486f5..c495afb6ec 100644 --- a/lisp/vc/vc-bzr.el +++ b/lisp/vc/vc-bzr.el @@ -860,9 +860,8 @@ If LIMIT is non-nil, show no more than this many entries." (vc-bzr-command "mv" nil 0 new old) (message "Renamed %s => %s" old new)) -(defvar vc-bzr-annotation-table nil +(defvar-local vc-bzr-annotation-table nil "Internal use.") -(make-variable-buffer-local 'vc-bzr-annotation-table) (defun vc-bzr-annotate-command (file buffer &optional revision) "Prepare BUFFER for `vc-annotate' on FILE. diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el index 6b17f2afe7..2573964c42 100644 --- a/lisp/vc/vc-dispatcher.el +++ b/lisp/vc/vc-dispatcher.el @@ -531,8 +531,7 @@ ARG and NO-CONFIRM are passed on to `revert-buffer'." (revert-buffer arg no-confirm t)) (vc-restore-buffer-context context))) -(defvar vc-mode-line-hook nil) -(make-variable-buffer-local 'vc-mode-line-hook) +(defvar-local vc-mode-line-hook nil) (put 'vc-mode-line-hook 'permanent-local t) (defvar view-old-buffer-read-only) commit 2c74924b0194e9947ac4432a2be2d3f6194a4477 Author: Philipp Stephani Date: Sun Jan 31 19:50:28 2021 +0100 * etc/MACHINES: Document that we support AArch64 with macOS. diff --git a/etc/MACHINES b/etc/MACHINES index 9799577737..d8d0b86fb4 100644 --- a/etc/MACHINES +++ b/etc/MACHINES @@ -66,8 +66,9 @@ the list at the end of this file. ** macOS - Mac OS X 10.6 or newer. PowerPC is not supported. - For installation instructions see the file nextstep/INSTALL. + Mac OS X 10.6 or newer. Both AArch64 (Arm) and x86-64 systems are + supported, but PowerPC is not supported. For installation + instructions see the file nextstep/INSTALL. ** Microsoft Windows commit 427d4b3c69f9d2fd8473189564dc1e96b27937ff Author: Alan Mackenzie Date: Sun Jan 31 17:24:23 2021 +0000 Minimise the time Vminibuffer_list is in an inconsistent state (src/minibuf.c) src/minibuf.c (get_minibuffer): Move the XSETCAR which writes the new minibuffer into Vminibuffer_list to immediately after the MB's creation, so that the list is in a consistent state before calling fundamental-mode or minibuffer-inactive-mode. diff --git a/src/minibuf.c b/src/minibuf.c index 0221f388dd..949c3d989d 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -971,12 +971,12 @@ get_minibuffer (EMACS_INT depth) char name[sizeof name_fmt + INT_STRLEN_BOUND (EMACS_INT)]; AUTO_STRING_WITH_LEN (lname, name, sprintf (name, name_fmt, depth)); buf = Fget_buffer_create (lname, Qnil); + /* Do this before set_minibuffer_mode. */ + XSETCAR (tail, buf); set_minibuffer_mode (buf, depth); /* Although the buffer's name starts with a space, undo should be enabled in it. */ Fbuffer_enable_undo (buf); - - XSETCAR (tail, buf); } else { commit 4b2203a07ebca62a012e0509ddd62451cb15a914 Author: Stefan Kangas Date: Sun Jan 31 15:56:53 2021 +0100 Prefer defvar-local in international/*.el * lisp/international/mule-cmds.el (current-input-method) (current-input-method-title, current-transient-input-method) (previous-transient-input-method, input-method-history) (deactivate-current-input-method-function) (describe-current-input-method-function): * lisp/international/mule.el (buffer-file-coding-system-explicit): * lisp/international/quail.el (quail-current-package) (quail-guidance-str, quail-overlay, quail-conv-overlay) (quail-current-key, quail-current-str) (quail-current-translations, quail-current-data): * lisp/international/robin.el (robin-mode) (robin-current-package-name): Prefer defvar-local in international/*.el. diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index 8202c3ee27..5dc3de4422 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -1315,15 +1315,13 @@ Each function is called with one arg, LEIM directory name.") (dolist (function update-leim-list-functions) (apply function dirs))) -(defvar current-input-method nil +(defvar-local current-input-method nil "The current input method for multilingual text. If nil, that means no input method is activated now.") -(make-variable-buffer-local 'current-input-method) (put 'current-input-method 'permanent-local t) -(defvar current-input-method-title nil +(defvar-local current-input-method-title nil "Title string of the current input method shown in mode line.") -(make-variable-buffer-local 'current-input-method-title) (put 'current-input-method-title 'permanent-local t) (define-widget 'mule-input-method-string 'string @@ -1355,45 +1353,40 @@ This is the input method activated by the command :set-after '(current-language-environment) :version "28.1") -(defvar current-transient-input-method nil +(defvar-local current-transient-input-method nil "Current input method temporarily enabled by `activate-transient-input-method'. If nil, that means no transient input method is active now.") -(make-variable-buffer-local 'current-transient-input-method) (put 'current-transient-input-method 'permanent-local t) -(defvar previous-transient-input-method nil +(defvar-local previous-transient-input-method nil "The input method that was active before enabling the transient input method. If nil, that means no previous input method was active.") -(make-variable-buffer-local 'previous-transient-input-method) (put 'previous-transient-input-method 'permanent-local t) (put 'input-method-function 'permanent-local t) -(defvar input-method-history nil +(defvar-local input-method-history nil "History list of input methods read from the minibuffer. Maximum length of the history list is determined by the value of `history-length', which see.") -(make-variable-buffer-local 'input-method-history) (put 'input-method-history 'permanent-local t) (define-obsolete-variable-alias 'inactivate-current-input-method-function 'deactivate-current-input-method-function "24.3") -(defvar deactivate-current-input-method-function nil +(defvar-local deactivate-current-input-method-function nil "Function to call for deactivating the current input method. Every input method should set this to an appropriate value when activated. This function is called with no argument. This function should never change the value of `current-input-method'. It is set to nil by the function `deactivate-input-method'.") -(make-variable-buffer-local 'deactivate-current-input-method-function) (put 'deactivate-current-input-method-function 'permanent-local t) -(defvar describe-current-input-method-function nil +(defvar-local describe-current-input-method-function nil "Function to call for describing the current input method. This function is called with no argument.") -(make-variable-buffer-local 'describe-current-input-method-function) (put 'describe-current-input-method-function 'permanent-local t) (defvar input-method-alist nil diff --git a/lisp/international/mule.el b/lisp/international/mule.el index 6a32cffe9a..52e743e6f3 100644 --- a/lisp/international/mule.el +++ b/lisp/international/mule.el @@ -1191,12 +1191,11 @@ FORM is a form to evaluate to define the coding-system." ;; `last-coding-system-used'. (It used to set it unconditionally, but ;; that seems unnecessary; see Bug#4533.) -(defvar buffer-file-coding-system-explicit nil +(defvar-local buffer-file-coding-system-explicit nil "The file coding system explicitly specified for the current buffer. The value is a cons of coding systems for reading (decoding) and writing (encoding). Internal use only.") -(make-variable-buffer-local 'buffer-file-coding-system-explicit) (put 'buffer-file-coding-system-explicit 'permanent-local t) (defun read-buffer-file-coding-system () diff --git a/lisp/international/quail.el b/lisp/international/quail.el index c66aa6a537..67ea00665f 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el @@ -61,15 +61,14 @@ ;; Buffer local variables -(defvar quail-current-package nil +(defvar-local quail-current-package nil "The current Quail package, which depends on the current input method. See the documentation of `quail-package-alist' for the format.") -(make-variable-buffer-local 'quail-current-package) (put 'quail-current-package 'permanent-local t) ;; Quail uses the following variables to assist users. ;; A string containing available key sequences or translation list. -(defvar quail-guidance-str nil) +(defvar-local quail-guidance-str nil) ;; A buffer to show completion list of the current key sequence. (defvar quail-completion-buf nil) ;; We may display the guidance string in a buffer on a one-line frame. @@ -78,41 +77,34 @@ See the documentation of `quail-package-alist' for the format.") ;; Each buffer in which Quail is activated should use different ;; guidance string. -(make-variable-buffer-local 'quail-guidance-str) (put 'quail-guidance-str 'permanent-local t) -(defvar quail-overlay nil +(defvar-local quail-overlay nil "Overlay which covers the current translation region of Quail.") -(make-variable-buffer-local 'quail-overlay) -(defvar quail-conv-overlay nil +(defvar-local quail-conv-overlay nil "Overlay which covers the text to be converted in Quail mode.") -(make-variable-buffer-local 'quail-conv-overlay) -(defvar quail-current-key nil +(defvar-local quail-current-key nil "Current key for translation in Quail mode.") -(make-variable-buffer-local 'quail-current-key) -(defvar quail-current-str nil +(defvar-local quail-current-str nil "Currently selected translation of the current key.") -(make-variable-buffer-local 'quail-current-str) -(defvar quail-current-translations nil +(defvar-local quail-current-translations nil "Cons of indices and vector of possible translations of the current key. Indices is a list of (CURRENT START END BLOCK BLOCKS), where CURRENT is an index of the current translation, START and END are indices of the start and end of the current block, BLOCK is the current block index, BLOCKS is a number of blocks of translation.") -(make-variable-buffer-local 'quail-current-translations) -(defvar quail-current-data nil +(defvar-local quail-current-data nil "Any Lisp object holding information of current translation status. When a key sequence is mapped to TRANS and TRANS is a cons of actual translation and some Lisp object to be referred for translating the longer key sequence, this variable is set to that Lisp object.") -(make-variable-buffer-local 'quail-current-data) ;; Quail package handlers. diff --git a/lisp/international/robin.el b/lisp/international/robin.el index 55390df315..e4a11801c3 100644 --- a/lisp/international/robin.el +++ b/lisp/international/robin.el @@ -371,14 +371,12 @@ Internal use only." ;;; Interactive use -(defvar robin-mode nil +(defvar-local robin-mode nil "If non-nil, `robin-input-method' is active.") -(make-variable-buffer-local 'robin-mode) -(defvar robin-current-package-name nil +(defvar-local robin-current-package-name nil "String representing the name of the current robin package. A nil value means no package is selected.") -(make-variable-buffer-local 'robin-current-package-name) ;;;###autoload (defun robin-use-package (name) commit 09e99053470ef19d75c4b000d5ebe848288d60dd Author: Stefan Kangas Date: Sun Jan 31 15:00:41 2021 +0100 Prefer defvar-local in nxml/*.el * lisp/nxml/rng-cmpct.el (rng-c-current-token) (rng-c-escape-positions, rng-c-file-name): * lisp/nxml/rng-pttrn.el (rng-current-schema): * lisp/nxml/rng-valid.el (rng-validate-timer) (rng-validate-quick-timer, rng-error-count, rng-message-overlay) (rng-message-overlay-inhibit-point, rng-message-overlay-current) (rng-validate-up-to-date-end, rng-conditional-up-to-date-start) (rng-conditional-up-to-date-end, rng-dtd): Prefer defvar-local. diff --git a/lisp/nxml/rng-cmpct.el b/lisp/nxml/rng-cmpct.el index dcbd7ed1dd..45a69a73f3 100644 --- a/lisp/nxml/rng-cmpct.el +++ b/lisp/nxml/rng-cmpct.el @@ -123,8 +123,7 @@ Return a pattern." (set-buffer-multibyte t) (set-syntax-table rng-c-syntax-table)) -(defvar rng-c-current-token nil) -(make-variable-buffer-local 'rng-c-current-token) +(defvar-local rng-c-current-token nil) (defun rng-c-advance () (cond ((looking-at rng-c-token-re) @@ -334,11 +333,9 @@ OVERRIDE is either nil, require or t." ;;; Parsing -(defvar rng-c-escape-positions nil) -(make-variable-buffer-local 'rng-c-escape-positions) +(defvar-local rng-c-escape-positions nil) -(defvar rng-c-file-name nil) -(make-variable-buffer-local 'rng-c-file-name) +(defvar-local rng-c-file-name nil) (defvar rng-c-file-index nil) diff --git a/lisp/nxml/rng-pttrn.el b/lisp/nxml/rng-pttrn.el index 12ffa57820..034671feeb 100644 --- a/lisp/nxml/rng-pttrn.el +++ b/lisp/nxml/rng-pttrn.el @@ -66,9 +66,8 @@ (defvar rng-schema-change-hook nil "Hook to be run after `rng-current-schema' changes.") -(defvar rng-current-schema nil +(defvar-local rng-current-schema nil "Pattern to be used as schema for the current buffer.") -(make-variable-buffer-local 'rng-current-schema) (defun rng-make-ref (name) (list 'ref nil name)) diff --git a/lisp/nxml/rng-valid.el b/lisp/nxml/rng-valid.el index 6ea893404c..a5eb893c55 100644 --- a/lisp/nxml/rng-valid.el +++ b/lisp/nxml/rng-valid.el @@ -132,36 +132,30 @@ A quick validation validates at most one chunk." ;; Global variables -(defvar rng-validate-timer nil) -(make-variable-buffer-local 'rng-validate-timer) +(defvar-local rng-validate-timer nil) ;; ensure that we can cancel the timer even after a kill-all-local-variables (put 'rng-validate-timer 'permanent-local t) -(defvar rng-validate-quick-timer nil) -(make-variable-buffer-local 'rng-validate-quick-timer) +(defvar-local rng-validate-quick-timer nil) ;; ensure that we can cancel the timer even after a kill-all-local-variables (put 'rng-validate-quick-timer 'permanent-local t) -(defvar rng-error-count nil +(defvar-local rng-error-count nil "Number of errors in the current buffer. Always equal to number of overlays with category `rng-error'.") -(make-variable-buffer-local 'rng-error-count) -(defvar rng-message-overlay nil +(defvar-local rng-message-overlay nil "Overlay in this buffer whose `help-echo' property was last printed. It is nil if none.") -(make-variable-buffer-local 'rng-message-overlay) -(defvar rng-message-overlay-inhibit-point nil +(defvar-local rng-message-overlay-inhibit-point nil "Position at which message from overlay should be inhibited. If point is equal to this and the error overlay around point is `rng-message-overlay', then the `help-echo' property of the error overlay should not be printed with `message'.") -(make-variable-buffer-local 'rng-message-overlay-inhibit-point) -(defvar rng-message-overlay-current nil +(defvar-local rng-message-overlay-current nil "Non-nil if `rng-message-overlay' is still the current message.") -(make-variable-buffer-local 'rng-message-overlay-current) (defvar rng-open-elements nil "Stack of names of open elements represented as a list. @@ -178,11 +172,10 @@ indicating an unresolvable entity or character reference.") (defvar rng-collecting-text nil) -(defvar rng-validate-up-to-date-end nil +(defvar-local rng-validate-up-to-date-end nil "Last position where validation is known to be up to date.") -(make-variable-buffer-local 'rng-validate-up-to-date-end) -(defvar rng-conditional-up-to-date-start nil +(defvar-local rng-conditional-up-to-date-start nil "Marker for the start of the conditionally up-to-date region. It is nil if there is no conditionally up-to-date region. The conditionally up-to-date region must be such that for any cached @@ -191,20 +184,17 @@ if at some point it is determined that S becomes correct for P, then all states with position >= P in the conditionally up to date region must also then be correct and all errors between P and the end of the region must then be correctly marked.") -(make-variable-buffer-local 'rng-conditional-up-to-date-start) -(defvar rng-conditional-up-to-date-end nil +(defvar-local rng-conditional-up-to-date-end nil "Marker for the end of the conditionally up-to-date region. It is nil if there is no conditionally up-to-date region. See the variable `rng-conditional-up-to-date-start'.") -(make-variable-buffer-local 'rng-conditional-up-to-date-end) (defvar rng-parsing-for-state nil "Non-nil means we are currently parsing just to compute the state. Should be dynamically bound.") -(defvar rng-dtd nil) -(make-variable-buffer-local 'rng-dtd) +(defvar-local rng-dtd nil) ;;;###autoload (define-minor-mode rng-validate-mode commit 5f69c222f47dfb339304b57083cb68c1da340271 Author: Stefan Kangas Date: Sun Jan 31 14:55:53 2021 +0100 Prefer defvar-local in emacs-lisp/*.el * lisp/emacs-lisp/chart.el (chart-local-object): * lisp/emacs-lisp/easy-mmode.el (define-minor-mode) (define-globalized-minor-mode): * lisp/emacs-lisp/edebug.el: * lisp/emacs-lisp/generic.el (generic-font-lock-keywords): * lisp/emacs-lisp/re-builder.el (reb-regexp, reb-regexp-src) (reb-overlays): * lisp/emacs-lisp/syntax.el (syntax-propertize-extend-region-functions): Prefer defvar-local. diff --git a/lisp/emacs-lisp/chart.el b/lisp/emacs-lisp/chart.el index 2cd73225ff..7d760ffc57 100644 --- a/lisp/emacs-lisp/chart.el +++ b/lisp/emacs-lisp/chart.el @@ -67,9 +67,8 @@ (define-obsolete-variable-alias 'chart-map 'chart-mode-map "24.1") (defvar chart-mode-map (make-sparse-keymap) "Keymap used in chart mode.") -(defvar chart-local-object nil +(defvar-local chart-local-object nil "Local variable containing the locally displayed chart object.") -(make-variable-buffer-local 'chart-local-object) (defvar chart-face-color-list '("red" "green" "blue" "cyan" "yellow" "purple") diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index f4dbcee4d6..54c0cf08b7 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -278,11 +278,10 @@ For example, you could write ((not globalp) `(progn :autoload-end - (defvar ,mode ,init-value + (defvar-local ,mode ,init-value ,(concat (format "Non-nil if %s is enabled.\n" pretty-name) (internal--format-docstring-line - "Use the command `%s' to change this variable." mode))) - (make-variable-buffer-local ',mode))) + "Use the command `%s' to change this variable." mode))))) (t (let ((base-doc-string (concat "Non-nil if %s is enabled. @@ -453,8 +452,7 @@ on if the hook has explicitly disabled it. (progn (put ',global-mode 'globalized-minor-mode t) :autoload-end - (defvar ,MODE-major-mode nil) - (make-variable-buffer-local ',MODE-major-mode)) + (defvar-local ,MODE-major-mode nil)) ;; The actual global minor-mode (define-minor-mode ,global-mode ,(concat (format "Toggle %s in all buffers.\n" pretty-name) diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 1ded0e7b09..84191af88c 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -2641,12 +2641,11 @@ See `edebug-behavior-alist' for implementations.") ;; window-start now stored with each function. -;;(defvar edebug-window-start nil) +;;(defvar-local edebug-window-start nil) ;; Remember where each buffers' window starts between edebug calls. ;; This is to avoid spurious recentering. ;; Does this still need to be buffer-local?? ;;(setq-default edebug-window-start nil) -;;(make-variable-buffer-local 'edebug-window-start) ;; Dynamically declared unbound vars diff --git a/lisp/emacs-lisp/generic.el b/lisp/emacs-lisp/generic.el index 6db1bbbb22..294aba66c3 100644 --- a/lisp/emacs-lisp/generic.el +++ b/lisp/emacs-lisp/generic.el @@ -96,9 +96,8 @@ ;; Internal Variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defvar generic-font-lock-keywords nil +(defvar-local generic-font-lock-keywords nil "Keywords for `font-lock-defaults' in a generic mode.") -(make-variable-buffer-local 'generic-font-lock-keywords) ;;;###autoload (defvar generic-mode-list nil diff --git a/lisp/emacs-lisp/re-builder.el b/lisp/emacs-lisp/re-builder.el index 23221a2a00..ce8d98df80 100644 --- a/lisp/emacs-lisp/re-builder.el +++ b/lisp/emacs-lisp/re-builder.el @@ -187,14 +187,14 @@ Set it to nil if you don't want limits here." (defvar reb-target-window nil "Window to which the RE is applied to.") -(defvar reb-regexp nil +(defvar-local reb-regexp nil "Last regexp used by RE Builder.") -(defvar reb-regexp-src nil +(defvar-local reb-regexp-src nil "Last regexp used by RE Builder before processing it. Except for Lisp syntax this is the same as `reb-regexp'.") -(defvar reb-overlays nil +(defvar-local reb-overlays nil "List of overlays of the RE Builder.") (defvar reb-window-config nil @@ -212,10 +212,6 @@ Except for Lisp syntax this is the same as `reb-regexp'.") (defvar reb-valid-string "" "String in mode line showing validity of RE.") -(make-variable-buffer-local 'reb-overlays) -(make-variable-buffer-local 'reb-regexp) -(make-variable-buffer-local 'reb-regexp-src) - (defconst reb-buffer "*RE-Builder*" "Buffer to use for the RE Builder.") diff --git a/lisp/emacs-lisp/syntax.el b/lisp/emacs-lisp/syntax.el index 62f213c57f..bee2f9639e 100644 --- a/lisp/emacs-lisp/syntax.el +++ b/lisp/emacs-lisp/syntax.el @@ -75,7 +75,7 @@ properties won't work properly.") (defvar syntax-propertize-chunk-size 500) -(defvar syntax-propertize-extend-region-functions +(defvar-local syntax-propertize-extend-region-functions '(syntax-propertize-wholelines) "Special hook run just before proceeding to propertize a region. This is used to allow major modes to help `syntax-propertize' find safe buffer @@ -89,7 +89,6 @@ These functions are run in turn repeatedly until they all return nil. Put first the functions more likely to cause a change and cheaper to compute.") ;; Mark it as a special hook which doesn't use any global setting ;; (i.e. doesn't obey the element t in the buffer-local value). -(make-variable-buffer-local 'syntax-propertize-extend-region-functions) (cl-defstruct (ppss (:constructor make-ppss) commit 4d635ceffbdfc3f709c09d25d28421e7816ecd8f Author: Stefan Kangas Date: Sun Jan 31 14:35:44 2021 +0100 Prefer defvar-local in allout * lisp/allout.el (allout-just-did-undo, allout-mode) (allout-layout, allout-regexp, allout-bullets-string) (allout-bullets-string-len, allout-depth-specific-regexp) (allout-depth-one-regexp, allout-line-boundary-regexp) (allout-bob-regexp, allout-header-subtraction) (allout-plain-bullets-string-len, allout-mode-prior-settings) (allout-outside-normal-auto-fill-function) (allout-encryption-plaintext-sanitization-regexps) (allout-encryption-ciphertext-rejection-regexps) (allout-explicitly-deactivated, allout-recent-prefix-beginning) (allout-recent-prefix-end, allout-recent-depth) (allout-recent-end-of-subtree, allout-post-goto-bullet) (allout-command-counter, allout-this-command-hid-text): * lisp/allout-widgets.el (allout-widgets-mode) (allout-widgets-tally, allout-widgets-mode-inhibit) (allout-inhibit-body-modification-hook) (allout-widgets-changes-record) (allout-widgets-undo-exposure-record) (allout-escaped-prefix-regexp, allout-item-icon-keymap) (allout-item-body-keymap, allout-cue-span-keymap) (allout-widgets-last-decoration-timing) (allout-container-item-widget): Prefer defvar-local. diff --git a/lisp/allout-widgets.el b/lisp/allout-widgets.el index d31083e427..7dcf36851f 100644 --- a/lisp/allout-widgets.el +++ b/lisp/allout-widgets.el @@ -78,9 +78,8 @@ ;;; during file load, so the involved code must reside above that ;;; definition in the file. ;;;_ = allout-widgets-mode -(defvar allout-widgets-mode nil +(defvar-local allout-widgets-mode nil "Allout mode enhanced with graphical widgets.") -(make-variable-buffer-local 'allout-widgets-mode) ;;;_ : USER CUSTOMIZATION VARIABLES and incidental functions: ;;;_ > defgroup allout-widgets @@ -243,14 +242,13 @@ decreases as obsolete widgets are garbage collected." :version "24.1" :type 'boolean :group 'allout-widgets-developer) -(defvar allout-widgets-tally nil +(defvar-local allout-widgets-tally nil "Hash-table of existing allout widgets, for debugging. Table is maintained only if `allout-widgets-maintain-tally' is non-nil. The table contents will be out of sync if any widgets are created or deleted while this variable is nil.") -(make-variable-buffer-local 'allout-widgets-tally) (defvar allout-widgets-mode-inhibit) ; defined below ;;;_ > allout-widgets-tally-string (defun allout-widgets-tally-string () @@ -295,7 +293,7 @@ to publicize it by making it a customization variable)." (message "%s" msg) msg)) ;;;_ = allout-widgets-mode-inhibit -(defvar allout-widgets-mode-inhibit nil +(defvar-local allout-widgets-mode-inhibit nil "Inhibit `allout-widgets-mode' from activating widgets. This also inhibits automatic adjustment of widgets to track allout outline @@ -310,15 +308,13 @@ buffers where this is set to enable and disable widget enhancements, directly.") ;;;###autoload (put 'allout-widgets-mode-inhibit 'safe-local-variable 'booleanp) -(make-variable-buffer-local 'allout-widgets-mode-inhibit) ;;;_ = allout-inhibit-body-modification-hook -(defvar allout-inhibit-body-modification-hook nil +(defvar-local allout-inhibit-body-modification-hook nil "Override de-escaping of text-prefixes in item bodies during specific changes. This is used by `allout-buffer-modification-handler' to signal such changes to `allout-body-modification-handler', and is always reset by `allout-post-command-business'.") -(make-variable-buffer-local 'allout-inhibit-body-modification-hook) ;;;_ = allout-widgets-icons-cache (defvar allout-widgets-icons-cache nil "Cache allout icon images, as an association list. @@ -358,7 +354,7 @@ See \\[describe-mode] for many more options." The structure includes the guides lines, bullet, and bullet cue.") ;;;_ = allout-widgets-changes-record -(defvar allout-widgets-changes-record nil +(defvar-local allout-widgets-changes-record nil "Record outline changes for processing by post-command hook. Entries on the list are lists whose first element is a symbol indicating @@ -369,14 +365,12 @@ type. For example: The changes are recorded in reverse order, with new values pushed onto the front.") -(make-variable-buffer-local 'allout-widgets-changes-record) ;;;_ = allout-widgets-undo-exposure-record -(defvar allout-widgets-undo-exposure-record nil +(defvar-local allout-widgets-undo-exposure-record nil "Record outline undo traces for processing by post-command hook. The changes are recorded in reverse order, with new values pushed onto the front.") -(make-variable-buffer-local 'allout-widgets-undo-exposure-record) ;;;_ = allout-widgets-last-hook-error (defvar allout-widgets-last-hook-error nil "String holding last error string, for debugging purposes.") @@ -393,13 +387,12 @@ onto the front.") "Maintained true during `allout-widgets-exposure-undo-processor'") ;;;_ , Widget-specific outline text format ;;;_ = allout-escaped-prefix-regexp -(defvar allout-escaped-prefix-regexp "" +(defvar-local allout-escaped-prefix-regexp "" "Regular expression for body text that would look like an item prefix if not altered with an escape sequence.") -(make-variable-buffer-local 'allout-escaped-prefix-regexp) ;;;_ , Widget element formatting ;;;_ = allout-item-icon-keymap -(defvar allout-item-icon-keymap +(defvar-local allout-item-icon-keymap (let ((km (make-sparse-keymap)) (as-parent (if (current-local-map) (make-composed-keymap (current-local-map) @@ -420,9 +413,8 @@ not altered with an escape sequence.") km) "General tree-node key bindings.") -(make-variable-buffer-local 'allout-item-icon-keymap) ;;;_ = allout-item-body-keymap -(defvar allout-item-body-keymap +(defvar-local allout-item-body-keymap (let ((km (make-sparse-keymap)) (as-parent (if (current-local-map) (make-composed-keymap (current-local-map) @@ -432,17 +424,15 @@ not altered with an escape sequence.") (set-keymap-parent km as-parent) km) "General key bindings for the text content of outline items.") -(make-variable-buffer-local 'allout-item-body-keymap) ;;;_ = allout-body-span-category (defvar allout-body-span-category nil "Symbol carrying allout body-text overlay properties.") ;;;_ = allout-cue-span-keymap -(defvar allout-cue-span-keymap +(defvar-local allout-cue-span-keymap (let ((km (make-sparse-keymap))) (set-keymap-parent km allout-item-icon-keymap) km) "Keymap used in the item cue area - the space between the icon and headline.") -(make-variable-buffer-local 'allout-cue-span-keymap) ;;;_ = allout-escapes-category (defvar allout-escapes-category nil "Symbol for category of text property used to hide escapes of prefix-like @@ -477,7 +467,7 @@ including things like: (defvar allout-trailing-category nil "Symbol carrying common properties of an overlay's trailing newline.") ;;;_ , Developer -(defvar allout-widgets-last-decoration-timing nil +(defvar-local allout-widgets-last-decoration-timing nil "Timing details for the last cooperative decoration action. This is maintained when `allout-widgets-time-decoration-activity' is set. @@ -488,7 +478,6 @@ The value is a list containing two elements: When active, the value is revised each time automatic decoration activity happens in the buffer.") -(make-variable-buffer-local 'allout-widgets-last-decoration-timing) ;;;_ . mode hookup ;;;_ > define-minor-mode allout-widgets-mode (arg) ;;;###autoload @@ -693,12 +682,11 @@ outline hot-spot navigation (see `allout-mode')." (allout-get-or-create-item-widget)))))) ;;;_ . settings context ;;;_ = allout-container-item -(defvar allout-container-item-widget nil +(defvar-local allout-container-item-widget nil "A widget for the current outline's overarching container as an item. The item has settings (of the file/connection) and maybe a body, but no icon/bullet.") -(make-variable-buffer-local 'allout-container-item-widget) ;;;_ . Hooks and hook helpers ;;;_ , major command-loop business: ;;;_ > allout-widgets-pre-command-business (&optional recursing) diff --git a/lisp/allout.el b/lisp/allout.el index 39aa29b664..ff0b67556e 100644 --- a/lisp/allout.el +++ b/lisp/allout.el @@ -830,9 +830,8 @@ such topics are encrypted.)" The value of `buffer-saved-size' at the time of decryption is used, for restoring when all encryptions are established.") -(defvar allout-just-did-undo nil +(defvar-local allout-just-did-undo nil "True just after undo commands, until allout-post-command-business.") -(make-variable-buffer-local 'allout-just-did-undo) ;;;_ + Developer ;;;_ = allout-developer group @@ -874,10 +873,10 @@ For details, see `allout-toggle-current-subtree-encryption's docstring." msg)) ;;;_ : Mode activation (defined here because it's referenced early) ;;;_ = allout-mode -(defvar allout-mode nil "Allout outline mode minor-mode flag.") -(make-variable-buffer-local 'allout-mode) +(defvar-local allout-mode nil + "Allout outline mode minor-mode flag.") ;;;_ = allout-layout nil -(defvar allout-layout nil ; LEAVE GLOBAL VALUE NIL -- see docstring. +(defvar-local allout-layout nil ; LEAVE GLOBAL VALUE NIL -- see docstring. "Buffer-specific setting for allout layout. In buffers where this is non-nil (and if `allout-auto-activation' @@ -903,34 +902,30 @@ followed by the equivalent of `(allout-expose-topic 0 : -1 -1 0)'. `allout-default-layout' describes the specification format. `allout-layout' can additionally have the value t, in which case the value of `allout-default-layout' is used.") -(make-variable-buffer-local 'allout-layout) ;;;###autoload (put 'allout-layout 'safe-local-variable (lambda (x) (or (numberp x) (listp x) (memq x '(: * + -))))) ;;;_ : Topic header format ;;;_ = allout-regexp -(defvar allout-regexp "" +(defvar-local allout-regexp "" "Regular expression to match the beginning of a heading line. Any line whose beginning matches this regexp is considered a heading. This var is set according to the user configuration vars by `allout-set-regexp'.") -(make-variable-buffer-local 'allout-regexp) ;;;_ = allout-bullets-string -(defvar allout-bullets-string "" +(defvar-local allout-bullets-string "" "A string dictating the valid set of outline topic bullets. This var should *not* be set by the user -- it is set by `allout-set-regexp', and is produced from the elements of `allout-plain-bullets-string' and `allout-distinctive-bullets-string'.") -(make-variable-buffer-local 'allout-bullets-string) ;;;_ = allout-bullets-string-len -(defvar allout-bullets-string-len 0 +(defvar-local allout-bullets-string-len 0 "Length of current buffers' `allout-plain-bullets-string'.") -(make-variable-buffer-local 'allout-bullets-string-len) ;;;_ = allout-depth-specific-regexp -(defvar allout-depth-specific-regexp "" +(defvar-local allout-depth-specific-regexp "" "Regular expression to match a heading line prefix for a particular depth. This expression is used to search for depth-specific topic @@ -941,34 +936,28 @@ This var is set according to the user configuration vars by `allout-set-regexp'. It is prepared with format strings for two decimal numbers, which should each be one less than the depth of the topic prefix to be matched.") -(make-variable-buffer-local 'allout-depth-specific-regexp) ;;;_ = allout-depth-one-regexp -(defvar allout-depth-one-regexp "" +(defvar-local allout-depth-one-regexp "" "Regular expression to match a heading line prefix for depth one. This var is set according to the user configuration vars by `allout-set-regexp'. It is prepared with format strings for two decimal numbers, which should each be one less than the depth of the topic prefix to be matched.") -(make-variable-buffer-local 'allout-depth-one-regexp) ;;;_ = allout-line-boundary-regexp -(defvar allout-line-boundary-regexp () +(defvar-local allout-line-boundary-regexp () "`allout-regexp' prepended with a newline for the search target. This is properly set by `allout-set-regexp'.") -(make-variable-buffer-local 'allout-line-boundary-regexp) ;;;_ = allout-bob-regexp -(defvar allout-bob-regexp () +(defvar-local allout-bob-regexp () "Like `allout-line-boundary-regexp', for headers at beginning of buffer.") -(make-variable-buffer-local 'allout-bob-regexp) ;;;_ = allout-header-subtraction -(defvar allout-header-subtraction (1- (length allout-header-prefix)) +(defvar-local allout-header-subtraction (1- (length allout-header-prefix)) "Allout-header prefix length to subtract when computing topic depth.") -(make-variable-buffer-local 'allout-header-subtraction) ;;;_ = allout-plain-bullets-string-len -(defvar allout-plain-bullets-string-len (length allout-plain-bullets-string) +(defvar-local allout-plain-bullets-string-len (length allout-plain-bullets-string) "Length of `allout-plain-bullets-string', updated by `allout-set-regexp'.") -(make-variable-buffer-local 'allout-plain-bullets-string-len) ;;;_ = allout-doublecheck-at-and-shallower (defconst allout-doublecheck-at-and-shallower 3 @@ -1279,11 +1268,10 @@ Also refresh various data structures that hinge on the regexp." ["Set New Exposure" allout-expose-topic t]))) ;;;_ : Allout Modal-Variables Utilities ;;;_ = allout-mode-prior-settings -(defvar allout-mode-prior-settings nil +(defvar-local allout-mode-prior-settings nil "Internal `allout-mode' use; settings to be resumed on mode deactivation. See `allout-add-resumptions' and `allout-do-resumptions'.") -(make-variable-buffer-local 'allout-mode-prior-settings) ;;;_ > allout-add-resumptions (&rest pairs) (defun allout-add-resumptions (&rest pairs) "Set name/value PAIRS. @@ -1466,16 +1454,15 @@ that was affected by the undo.." :version "24.3") ;;;_ = allout-outside-normal-auto-fill-function -(defvar allout-outside-normal-auto-fill-function nil +(defvar-local allout-outside-normal-auto-fill-function nil "Value of `normal-auto-fill-function' outside of allout mode. Used by `allout-auto-fill' to do the mandated `normal-auto-fill-function' wrapped within allout's automatic `fill-prefix' setting.") -(make-variable-buffer-local 'allout-outside-normal-auto-fill-function) ;;;_ = prevent redundant activation by desktop mode: (add-to-list 'desktop-minor-mode-handlers '(allout-mode . nil)) ;;;_ = allout-after-save-decrypt -(defvar allout-after-save-decrypt nil +(defvar-local allout-after-save-decrypt nil "Internal variable, is nil or has the value of two points: - the location of a topic to be decrypted after saving is done @@ -1483,9 +1470,8 @@ wrapped within allout's automatic `fill-prefix' setting.") This is used to decrypt the topic that was currently being edited, if it was encrypted automatically as part of a file write or autosave.") -(make-variable-buffer-local 'allout-after-save-decrypt) ;;;_ = allout-encryption-plaintext-sanitization-regexps -(defvar allout-encryption-plaintext-sanitization-regexps nil +(defvar-local allout-encryption-plaintext-sanitization-regexps nil "List of regexps whose matches are removed from plaintext before encryption. This is for the sake of removing artifacts, like escapes, that are added on @@ -1498,9 +1484,8 @@ Each value can be a regexp or a list with a regexp followed by a substitution string. If it's just a regexp, all its matches are removed before the text is encrypted. If it's a regexp and a substitution, the substitution is used against the regexp matches, a la `replace-match'.") -(make-variable-buffer-local 'allout-encryption-plaintext-sanitization-regexps) ;;;_ = allout-encryption-ciphertext-rejection-regexps -(defvar allout-encryption-ciphertext-rejection-regexps nil +(defvar-local allout-encryption-ciphertext-rejection-regexps nil "Variable for regexps matching plaintext to remove before encryption. This is used to detect strings in encryption results that would @@ -1513,13 +1498,11 @@ Encryptions that result in matches will be retried, up to `allout-encryption-ciphertext-rejection-ceiling' times, after which an error is raised.") -(make-variable-buffer-local 'allout-encryption-ciphertext-rejection-regexps) ;;;_ = allout-encryption-ciphertext-rejection-ceiling -(defvar allout-encryption-ciphertext-rejection-ceiling 5 +(defvar-local allout-encryption-ciphertext-rejection-ceiling 5 "Limit on number of times encryption ciphertext is rejected. See `allout-encryption-ciphertext-rejection-regexps' for rejection reasons.") -(make-variable-buffer-local 'allout-encryption-ciphertext-rejection-ceiling) ;;;_ > allout-mode-p () ;; Must define this macro above any uses, or byte compilation will lack ;; proper def, if file isn't loaded -- eg, during emacs build! @@ -1607,10 +1590,9 @@ non-nil in a lasting way.") ;;;_ #2 Mode environment and activation ;;;_ = allout-explicitly-deactivated -(defvar allout-explicitly-deactivated nil +(defvar-local allout-explicitly-deactivated nil "If t, `allout-mode's last deactivation was deliberate. So `allout-post-command-business' should not reactivate it...") -(make-variable-buffer-local 'allout-explicitly-deactivated) ;;;_ > allout-setup-menubar () (defun allout-setup-menubar () "Populate the current buffer's menubar with `allout-mode' stuff." @@ -2119,21 +2101,17 @@ function can also be used as an `isearch-mode-end-hook'." ;; for just-established data. This optimization can provide ;; significant speed improvement, but it must be employed carefully. ;;;_ = allout-recent-prefix-beginning -(defvar allout-recent-prefix-beginning 0 +(defvar-local allout-recent-prefix-beginning 0 "Buffer point of the start of the last topic prefix encountered.") -(make-variable-buffer-local 'allout-recent-prefix-beginning) ;;;_ = allout-recent-prefix-end -(defvar allout-recent-prefix-end 0 +(defvar-local allout-recent-prefix-end 0 "Buffer point of the end of the last topic prefix encountered.") -(make-variable-buffer-local 'allout-recent-prefix-end) ;;;_ = allout-recent-depth -(defvar allout-recent-depth 0 +(defvar-local allout-recent-depth 0 "Depth of the last topic prefix encountered.") -(make-variable-buffer-local 'allout-recent-depth) ;;;_ = allout-recent-end-of-subtree -(defvar allout-recent-end-of-subtree 0 +(defvar-local allout-recent-end-of-subtree 0 "Buffer point last returned by `allout-end-of-current-subtree'.") -(make-variable-buffer-local 'allout-recent-end-of-subtree) ;;;_ > allout-prefix-data () (defsubst allout-prefix-data () "Register allout-prefix state data. @@ -3213,7 +3191,7 @@ Returns resulting position, else nil if none found." ;;;_ - Fundamental ;;;_ = allout-post-goto-bullet -(defvar allout-post-goto-bullet nil +(defvar-local allout-post-goto-bullet nil "Outline internal var, for `allout-pre-command-business' hot-spot operation. When set, tells post-processing to reposition on topic bullet, and @@ -3221,18 +3199,15 @@ then unset it. Set by `allout-pre-command-business' when implementing hot-spot operation, where literal characters typed over a topic bullet are mapped to the command of the corresponding control-key on the `allout-mode-map-value'.") -(make-variable-buffer-local 'allout-post-goto-bullet) ;;;_ = allout-command-counter -(defvar allout-command-counter 0 +(defvar-local allout-command-counter 0 "Counter that monotonically increases in allout-mode buffers. Set by `allout-pre-command-business', to support allout addons in coordinating with allout activity.") -(make-variable-buffer-local 'allout-command-counter) ;;;_ = allout-this-command-hid-text -(defvar allout-this-command-hid-text nil +(defvar-local allout-this-command-hid-text nil "True if the most recent allout-mode command hid any text.") -(make-variable-buffer-local 'allout-this-command-hid-text) ;;;_ > allout-post-command-business () (defun allout-post-command-business () "Outline `post-command-hook' function. commit 035ef9f5aec01d61ea8b7de353cfbe3d2b15f731 Author: Stefan Kangas Date: Sun Jan 31 14:17:16 2021 +0100 Prefer defvar-local in cua * lisp/emulation/cua-base.el (cua-inhibit-cua-keys) (cua--status-string): * lisp/emulation/cua-rect.el (cua--rectangle) (cua--rectangle-overlays): Prefer defvar-local. diff --git a/lisp/emulation/cua-base.el b/lisp/emulation/cua-base.el index 881eff7f80..a64274bc0c 100644 --- a/lisp/emulation/cua-base.el +++ b/lisp/emulation/cua-base.el @@ -634,9 +634,8 @@ a cons (TYPE . COLOR), then both properties are affected." ;;; Low-level Interface -(defvar cua-inhibit-cua-keys nil +(defvar-local cua-inhibit-cua-keys nil "Buffer-local variable that may disable the CUA keymappings.") -(make-variable-buffer-local 'cua-inhibit-cua-keys) ;;; Aux. variables @@ -644,9 +643,8 @@ a cons (TYPE . COLOR), then both properties are affected." ;; checked in post-command hook to see if point was moved (defvar cua--buffer-and-point-before-command nil) -;; status string for mode line indications -(defvar cua--status-string nil) -(make-variable-buffer-local 'cua--status-string) +(defvar-local cua--status-string nil + "Status string for mode line indications.") (defvar cua--debug nil) diff --git a/lisp/emulation/cua-rect.el b/lisp/emulation/cua-rect.el index ea5dad2aa0..be2d7c0fd8 100644 --- a/lisp/emulation/cua-rect.el +++ b/lisp/emulation/cua-rect.el @@ -37,7 +37,7 @@ (require 'rect) -(defvar cua--rectangle nil +(defvar-local cua--rectangle nil "If non-nil, restrict current region to this rectangle. A cua-rectangle definition is a vector used for all actions in `cua-rectangle-mark-mode', of the form: @@ -59,7 +59,6 @@ If VIRT is non-nil, virtual straight edges are enabled. If SELECT is a regexp, only lines starting with that regexp are affected.") -(make-variable-buffer-local 'cua--rectangle) (defvar cua--last-rectangle nil "Most recent rectangle geometry. @@ -85,9 +84,8 @@ See `cua--rectangle'.") ;; "active " "sert on" " straig" " lines ") (defvar cua--last-killed-rectangle nil) -(defvar cua--rectangle-overlays nil +(defvar-local cua--rectangle-overlays nil "List of overlays used to display current rectangle.") -(make-variable-buffer-local 'cua--rectangle-overlays) (put 'cua--rectangle-overlays 'permanent-local t) (defvar cua--overlay-keymap commit d7405e474b43ba5c4238cc27f2aaa61341b828b4 Author: Stefan Kangas Date: Sun Jan 31 14:10:10 2021 +0100 Obsolete viper-deflocalvar for defvar-local * lisp/emulation/viper-init.el (viper-deflocalvar): Make obsolete. Use defvar-local. * lisp/emulation/viper-cmd.el (viper--undo-change-group-handle): * lisp/emulation/viper-init.el (viper-vi-intercept-minor-mode) (viper-vi-basic-minor-mode, viper-vi-local-user-minor-mode) (viper-vi-global-user-minor-mode) (viper-vi-state-modifier-minor-mode) (viper-vi-diehard-minor-mode, viper-vi-kbd-minor-mode) (viper-insert-intercept-minor-mode) (viper-insert-basic-minor-mode) (viper-insert-local-user-minor-mode) (viper-insert-global-user-minor-mode) (viper-insert-state-modifier-minor-mode) (viper-insert-diehard-minor-mode, viper-insert-kbd-minor-mode) (viper-replace-minor-mode, viper-emacs-intercept-minor-mode) (viper-emacs-local-user-minor-mode) (viper-emacs-global-user-minor-mode, viper-emacs-kbd-minor-mode) (viper-emacs-state-modifier-minor-mode) (viper-vi-minibuffer-minor-mode) (viper-insert-minibuffer-minor-mode) (viper-automatic-iso-accents, viper-special-input-method) (viper-intermediate-command, viper-began-as-replace) (viper-replace-overlay, viper-last-posn-in-replace-region) (viper-last-posn-while-in-insert-state) (viper-sitting-in-replace, viper-replace-chars-to-delete) (viper-replace-region-chars-deleted, viper-current-state) (viper-cted, viper-current-indent, viper-preserve-indent) (viper-auto-indent, viper-electric-mode, viper-insert-point) (viper-pre-command-point, viper-com-point) (viper-ex-style-motion, viper-ex-style-editing) (viper-ESC-moves-cursor-back, viper-delete-backwards-in-replace) (viper-related-files-and-buffers-ring) (viper-local-search-start-marker, viper-search-overlay) (viper-last-jump, viper-last-jump-ignore) (viper-minibuffer-current-face, viper-minibuffer-overlay): * lisp/emulation/viper-keym.el (viper-vi-local-user-map) (viper-insert-local-user-map, viper-emacs-local-user-map) (viper--key-maps, viper-need-new-vi-local-map) (viper-need-new-insert-local-map) (viper-need-new-emacs-local-map): * lisp/emulation/viper-mous.el (viper-mouse-click-search-noerror) (viper-mouse-click-search-limit): * lisp/emulation/viper-util.el (viper-non-word-characters) (viper-ALPHA-char-class): * lisp/emulation/viper.el: Use defvar-local instead of now obsolete macro viper-deflocalvar. diff --git a/lisp/emulation/viper-cmd.el b/lisp/emulation/viper-cmd.el index 1e235831d6..f38be90889 100644 --- a/lisp/emulation/viper-cmd.el +++ b/lisp/emulation/viper-cmd.el @@ -1624,7 +1624,7 @@ invokes the command before that, etc." ;; The following two functions are used to set up undo properly. ;; In VI, unlike Emacs, if you open a line, say, and add a bunch of lines, ;; they are undone all at once. -(viper-deflocalvar viper--undo-change-group-handle nil) +(defvar-local viper--undo-change-group-handle nil) (put 'viper--undo-change-group-handle 'permanent-local t) (defun viper-adjust-undo () diff --git a/lisp/emulation/viper-init.el b/lisp/emulation/viper-init.el index cede99bff7..c05cf6a48b 100644 --- a/lisp/emulation/viper-init.el +++ b/lisp/emulation/viper-init.el @@ -91,11 +91,9 @@ In all likelihood, you don't need to bother with this setting." "Define VAR as a buffer-local variable. DEFAULT-VALUE is the default value, and DOCUMENTATION is the docstring. The variable becomes buffer-local whenever set." - (declare (indent defun)) - `(progn - (defvar ,var ,default-value - ,(format "%s\n(buffer local)" documentation)) - (make-variable-buffer-local ',var))) + (declare (indent defun) + (obsolete defvar-local "28.1")) + `(defvar-local ,var ,default-value ,documentation)) ;; (viper-loop COUNT BODY) Execute BODY COUNT times. (defmacro viper-loop (count &rest body) @@ -161,87 +159,87 @@ docstring. The variable becomes buffer-local whenever set." ;;; Viper minor modes ;; Mode for vital things like \e, C-z. -(viper-deflocalvar viper-vi-intercept-minor-mode nil) +(defvar-local viper-vi-intercept-minor-mode nil) -(viper-deflocalvar viper-vi-basic-minor-mode nil +(defvar-local viper-vi-basic-minor-mode nil "Viper's minor mode for Vi bindings.") -(viper-deflocalvar viper-vi-local-user-minor-mode nil +(defvar-local viper-vi-local-user-minor-mode nil "Auxiliary minor mode for user-defined local bindings in Vi state.") -(viper-deflocalvar viper-vi-global-user-minor-mode nil +(defvar-local viper-vi-global-user-minor-mode nil "Auxiliary minor mode for user-defined global bindings in Vi state.") -(viper-deflocalvar viper-vi-state-modifier-minor-mode nil +(defvar-local viper-vi-state-modifier-minor-mode nil "Minor mode used to make major-mode-specific modification to Vi state.") -(viper-deflocalvar viper-vi-diehard-minor-mode nil +(defvar-local viper-vi-diehard-minor-mode nil "This minor mode is in effect when the user wants Viper to be Vi.") -(viper-deflocalvar viper-vi-kbd-minor-mode nil +(defvar-local viper-vi-kbd-minor-mode nil "Minor mode for Ex command macros in Vi state. The corresponding keymap stores key bindings of Vi macros defined with the Ex command :map.") ;; Mode for vital things like \e, C-z. -(viper-deflocalvar viper-insert-intercept-minor-mode nil) +(defvar-local viper-insert-intercept-minor-mode nil) -(viper-deflocalvar viper-insert-basic-minor-mode nil +(defvar-local viper-insert-basic-minor-mode nil "Viper's minor mode for bindings in Insert mode.") -(viper-deflocalvar viper-insert-local-user-minor-mode nil +(defvar-local viper-insert-local-user-minor-mode nil "Auxiliary minor mode for buffer-local user-defined bindings in Insert state. This is a way to overshadow normal Insert mode bindings locally to certain designated buffers.") -(viper-deflocalvar viper-insert-global-user-minor-mode nil +(defvar-local viper-insert-global-user-minor-mode nil "Auxiliary minor mode for global user-defined bindings in Insert state.") -(viper-deflocalvar viper-insert-state-modifier-minor-mode nil +(defvar-local viper-insert-state-modifier-minor-mode nil "Minor mode used to make major-mode-specific modification to Insert state.") -(viper-deflocalvar viper-insert-diehard-minor-mode nil +(defvar-local viper-insert-diehard-minor-mode nil "Minor mode that simulates Vi very closely. Not recommended, except for the novice user.") -(viper-deflocalvar viper-insert-kbd-minor-mode nil +(defvar-local viper-insert-kbd-minor-mode nil "Minor mode for Ex command macros Insert state. The corresponding keymap stores key bindings of Vi macros defined with the Ex command :map!.") -(viper-deflocalvar viper-replace-minor-mode nil +(defvar-local viper-replace-minor-mode nil "Minor mode in effect in replace state (cw, C, and the like commands).") ;; Mode for vital things like \C-z and \C-x) This is set to t, when viper-mode ;; is invoked. So, any new buffer will have C-z defined as switch to Vi, ;; unless we switched states in this buffer -(viper-deflocalvar viper-emacs-intercept-minor-mode nil) +(defvar-local viper-emacs-intercept-minor-mode nil) -(viper-deflocalvar viper-emacs-local-user-minor-mode nil +(defvar-local viper-emacs-local-user-minor-mode nil "Minor mode for local user bindings effective in Emacs state. Users can use it to override Emacs bindings when Viper is in its Emacs state.") -(viper-deflocalvar viper-emacs-global-user-minor-mode nil +(defvar-local viper-emacs-global-user-minor-mode nil "Minor mode for global user bindings in effect in Emacs state. Users can use it to override Emacs bindings when Viper is in its Emacs state.") -(viper-deflocalvar viper-emacs-kbd-minor-mode nil +(defvar-local viper-emacs-kbd-minor-mode nil "Minor mode for Vi style macros in Emacs state. The corresponding keymap stores key bindings of Vi macros defined with `viper-record-kbd-macro' command. There is no Ex-level command to do this interactively.") -(viper-deflocalvar viper-emacs-state-modifier-minor-mode nil +(defvar-local viper-emacs-state-modifier-minor-mode nil "Minor mode used to make major-mode-specific modification to Emacs state. For instance, a Vi purist may want to bind `dd' in Dired mode to a function that deletes a file.") -(viper-deflocalvar viper-vi-minibuffer-minor-mode nil +(defvar-local viper-vi-minibuffer-minor-mode nil "Minor mode that forces Vi-style when the Minibuffer is in Vi state.") -(viper-deflocalvar viper-insert-minibuffer-minor-mode nil +(defvar-local viper-insert-minibuffer-minor-mode nil "Minor mode that forces Vi-style when the Minibuffer is in Insert state.") @@ -284,7 +282,7 @@ Use `\\[viper-set-expert-level]' to change this.") ;; If non-nil, ISO accents will be turned on in insert/replace emacs states and ;; turned off in vi-state. For some users, this behavior may be too ;; primitive. In this case, use insert/emacs/vi state hooks. -(viper-deflocalvar viper-automatic-iso-accents nil "") +(defvar-local viper-automatic-iso-accents nil "") ;; Set iso-accents-mode to ARG. Check if it is bound first (defsubst viper-set-iso-accents-mode (arg) (if (boundp 'iso-accents-mode) @@ -294,7 +292,7 @@ Use `\\[viper-set-expert-level]' to change this.") ;; Don't change this! (defvar viper-mule-hook-flag t) ;; If non-nil, the default intl. input method is turned on. -(viper-deflocalvar viper-special-input-method nil "") +(defvar-local viper-special-input-method nil "") ;; viper hook to run on input-method activation (defun viper-activate-input-method-action () @@ -357,7 +355,7 @@ it better fits your working style." ;; Replace mode and changing text ;; Hack used to pass global states around for short period of time -(viper-deflocalvar viper-intermediate-command nil "") +(defvar-local viper-intermediate-command nil "") ;; This is used to pass the right Vi command key sequence to ;; viper-set-destructive-command whenever (this-command-keys) doesn't give the @@ -367,7 +365,7 @@ it better fits your working style." (defconst viper-this-command-keys nil) ;; Indicates that the current destructive command has started in replace mode. -(viper-deflocalvar viper-began-as-replace nil "") +(defvar-local viper-began-as-replace nil "") (defcustom viper-allow-multiline-replace-regions t "If non-nil, Viper will allow multi-line replace regions. @@ -398,7 +396,7 @@ delete the text being replaced, as in standard Vi." ;; internal var, used to remember the default cursor color of emacs frames (defvar viper-vi-state-cursor-color nil) -(viper-deflocalvar viper-replace-overlay nil "") +(defvar-local viper-replace-overlay nil "") (put 'viper-replace-overlay 'permanent-local t) (defcustom viper-replace-region-end-delimiter "$" @@ -430,24 +428,24 @@ color displays. By default, the delimiters are used only on TTYs." ;; `viper-move-marker-locally' ;; ;; Remember the last position inside the replace region. -(viper-deflocalvar viper-last-posn-in-replace-region nil) +(defvar-local viper-last-posn-in-replace-region nil) ;; Remember the last position while inserting -(viper-deflocalvar viper-last-posn-while-in-insert-state nil) +(defvar-local viper-last-posn-while-in-insert-state nil) (put 'viper-last-posn-in-replace-region 'permanent-local t) (put 'viper-last-posn-while-in-insert-state 'permanent-local t) -(viper-deflocalvar viper-sitting-in-replace nil "") +(defvar-local viper-sitting-in-replace nil "") (put 'viper-sitting-in-replace 'permanent-local t) ;; Remember the number of characters that have to be deleted in replace ;; mode to compensate for the inserted characters. -(viper-deflocalvar viper-replace-chars-to-delete 0 "") +(defvar-local viper-replace-chars-to-delete 0 "") ;; This variable is used internally by the before/after changed functions to ;; determine how many chars were deleted by the change. This can't be ;; determined inside after-change-functions because those get the length of the ;; deleted region, not the number of chars deleted (which are two different ;; things under MULE). -(viper-deflocalvar viper-replace-region-chars-deleted 0 "") +(defvar-local viper-replace-region-chars-deleted 0 "") ;; Insertion ring and command ring (defcustom viper-insertion-ring-size 14 @@ -490,28 +488,28 @@ will make it hard to use Vi-style timeout macros." ;; Modes and related variables ;; Current mode. One of: `emacs-state', `vi-state', `insert-state' -(viper-deflocalvar viper-current-state 'emacs-state) +(defvar-local viper-current-state 'emacs-state) ;; Autoindent in insert ;; Variable that keeps track of whether C-t has been pressed. -(viper-deflocalvar viper-cted nil "") +(defvar-local viper-cted nil "") ;; Preserve the indent value, used by C-d in insert mode. -(viper-deflocalvar viper-current-indent 0) +(defvar-local viper-current-indent 0) ;; Whether to preserve the indent, used by C-d in insert mode. -(viper-deflocalvar viper-preserve-indent nil) +(defvar-local viper-preserve-indent nil) -(viper-deflocalvar viper-auto-indent nil "") +(defvar-local viper-auto-indent nil "") (defcustom viper-auto-indent nil "Enable autoindent, if t. This is a buffer-local variable." :type 'boolean :group 'viper) -(viper-deflocalvar viper-electric-mode t "") +(defvar-local viper-electric-mode t "") (defcustom viper-electric-mode t "If t, electrify Viper. Currently, this only electrifies auto-indentation, making it appropriate to the @@ -541,7 +539,7 @@ to a new place after repeating previous Vi command." ;; Remember insert point as a marker. This is a local marker that must be ;; initialized to nil and moved with `viper-move-marker-locally'. -(viper-deflocalvar viper-insert-point nil) +(defvar-local viper-insert-point nil) (put 'viper-insert-point 'permanent-local t) ;; This remembers the point before dabbrev-expand was called. @@ -562,7 +560,7 @@ to a new place after repeating previous Vi command." ;; problem. However, the same trick can be used if such a command is ;; discovered later. ;; -(viper-deflocalvar viper-pre-command-point nil) +(defvar-local viper-pre-command-point nil) (put 'viper-pre-command-point 'permanent-local t) ; this is probably an overkill ;; This is used for saving inserted text. @@ -573,7 +571,7 @@ to a new place after repeating previous Vi command." ;; Remember com point as a marker. ;; This is a local marker. Should be moved with `viper-move-marker-locally' -(viper-deflocalvar viper-com-point nil) +(defvar-local viper-com-point nil) ;; If non-nil, the value is a list (M-COM VAL COM REG inserted-text cmd-keys) ;; It is used to re-execute last destructive command. @@ -660,14 +658,14 @@ negative number." :type 'boolean :group 'viper) -(viper-deflocalvar viper-ex-style-motion t "") +(defvar-local viper-ex-style-motion t "") (defcustom viper-ex-style-motion t "If t, the commands l,h do not cross lines, etc (Ex-style). If nil, these commands cross line boundaries." :type 'boolean :group 'viper) -(viper-deflocalvar viper-ex-style-editing t "") +(defvar-local viper-ex-style-editing t "") (defcustom viper-ex-style-editing t "If t, Ex-style behavior while editing in Vi command and insert states. `Backspace' and `Delete' don't cross line boundaries in insert. @@ -679,14 +677,14 @@ If nil, the above commands can work across lines." :type 'boolean :group 'viper) -(viper-deflocalvar viper-ESC-moves-cursor-back viper-ex-style-editing "") +(defvar-local viper-ESC-moves-cursor-back viper-ex-style-editing "") (defcustom viper-ESC-moves-cursor-back nil "If t, ESC moves cursor back when changing from insert to vi state. If nil, the cursor stays where it was when ESC was hit." :type 'boolean :group 'viper) -(viper-deflocalvar viper-delete-backwards-in-replace nil "") +(defvar-local viper-delete-backwards-in-replace nil "") (defcustom viper-delete-backwards-in-replace nil "If t, DEL key will delete characters while moving the cursor backwards. If nil, the cursor will move backwards without deleting anything." @@ -704,7 +702,7 @@ If nil, the cursor will move backwards without deleting anything." :tag "Search Wraps Around" :group 'viper-search) -(viper-deflocalvar viper-related-files-and-buffers-ring nil "") +(defvar-local viper-related-files-and-buffers-ring nil "") (defcustom viper-related-files-and-buffers-ring nil "List of file and buffer names to consider related to the current buffer. Related buffers can be cycled through via :R and :P commands." @@ -713,12 +711,12 @@ Related buffers can be cycled through via :R and :P commands." (put 'viper-related-files-and-buffers-ring 'permanent-local t) ;; Used to find out if we are done with searching the current buffer. -(viper-deflocalvar viper-local-search-start-marker nil) +(defvar-local viper-local-search-start-marker nil) ;; As above, but global (defvar viper-search-start-marker (make-marker)) ;; the search overlay -(viper-deflocalvar viper-search-overlay nil) +(defvar-local viper-search-overlay nil) (defvar viper-heading-start @@ -745,9 +743,9 @@ Related buffers can be cycled through via :R and :P commands." ;; inside the lines. ;; Remembers position of the last jump done using ``'. -(viper-deflocalvar viper-last-jump nil) +(defvar-local viper-last-jump nil) ;; Remembers position of the last jump done using `''. -(viper-deflocalvar viper-last-jump-ignore 0) +(defvar-local viper-last-jump-ignore 0) ;; History variables @@ -841,7 +839,7 @@ to customize the actual face object `viper-minibuffer-vi' this variable represents.") ;; the current face to be used in the minibuffer -(viper-deflocalvar +(defvar-local viper-minibuffer-current-face viper-minibuffer-emacs-face "") @@ -877,7 +875,7 @@ Should be set in `viper-custom-file-name'." :group 'viper) ;; overlay used in the minibuffer to indicate which state it is in -(viper-deflocalvar viper-minibuffer-overlay nil) +(defvar-local viper-minibuffer-overlay nil) (put 'viper-minibuffer-overlay 'permanent-local t) ;; Hook, specific to Viper, which is run just *before* exiting the minibuffer. @@ -946,9 +944,4 @@ on a dumb terminal." (provide 'viper-init) - -;; Local Variables: -;; eval: (put 'viper-deflocalvar 'lisp-indent-hook 'defun) -;; End: - ;;; viper-init.el ends here diff --git a/lisp/emulation/viper-keym.el b/lisp/emulation/viper-keym.el index 7209dc664b..1d80c9cd02 100644 --- a/lisp/emulation/viper-keym.el +++ b/lisp/emulation/viper-keym.el @@ -82,7 +82,7 @@ major mode in effect." (defvar viper-insert-intercept-map (make-sparse-keymap)) (defvar viper-emacs-intercept-map (make-sparse-keymap)) -(viper-deflocalvar viper-vi-local-user-map (make-sparse-keymap) +(defvar-local viper-vi-local-user-map (make-sparse-keymap) "Keymap for user-defined local bindings. Useful for changing bindings such as ZZ in certain major modes. For instance, in letter-mode, one may want to bind ZZ to @@ -106,7 +106,7 @@ This map is global, shared by all buffers.") This happens when viper-expert-level is 1 or 2. See viper-set-expert-level.") -(viper-deflocalvar viper-insert-local-user-map (make-sparse-keymap) +(defvar-local viper-insert-local-user-map (make-sparse-keymap) "Auxiliary map for per-buffer user-defined keybindings in Insert state.") (put 'viper-insert-local-user-map 'permanent-local t) @@ -133,7 +133,7 @@ viper-insert-basic-map. Not recommended, except for novice users.") (defvar viper-emacs-kbd-map (make-sparse-keymap) "This keymap keeps Vi-style kbd macros for Emacs mode.") -(viper-deflocalvar viper-emacs-local-user-map (make-sparse-keymap) +(defvar-local viper-emacs-local-user-map (make-sparse-keymap) "Auxiliary map for local user-defined bindings in Emacs state.") (put 'viper-emacs-local-user-map 'permanent-local t) @@ -209,22 +209,22 @@ In insert mode, this key also functions as Meta." (defvar viper-emacs-state-modifier-alist nil) ;; The list of viper keymaps. Set by viper-normalize-minor-mode-map-alist -(viper-deflocalvar viper--key-maps nil) -(viper-deflocalvar viper--intercept-key-maps nil) +(defvar-local viper--key-maps nil) +(defvar-local viper--intercept-key-maps nil) ;; Tells viper-add-local-keys to create a new viper-vi-local-user-map for new ;; buffers. Not a user option. -(viper-deflocalvar viper-need-new-vi-local-map t "") +(defvar-local viper-need-new-vi-local-map t "") (put 'viper-need-new-vi-local-map 'permanent-local t) ;; Tells viper-add-local-keys to create a new viper-insert-local-user-map for ;; new buffers. Not a user option. -(viper-deflocalvar viper-need-new-insert-local-map t "") +(defvar-local viper-need-new-insert-local-map t "") (put 'viper-need-new-insert-local-map 'permanent-local t) ;; Tells viper-add-local-keys to create a new viper-emacs-local-user-map for ;; new buffers. Not a user option. -(viper-deflocalvar viper-need-new-emacs-local-map t "") +(defvar-local viper-need-new-emacs-local-map t "") (put 'viper-need-new-emacs-local-map 'permanent-local t) @@ -654,10 +654,4 @@ form ((key . function) (key . function) ... )." (provide 'viper-keym) - -;; Local Variables: -;; eval: (put 'viper-deflocalvar 'lisp-indent-hook 'defun) -;; End: - - ;;; viper-keym.el ends here diff --git a/lisp/emulation/viper-mous.el b/lisp/emulation/viper-mous.el index eec83dd05b..71e40ee023 100644 --- a/lisp/emulation/viper-mous.el +++ b/lisp/emulation/viper-mous.el @@ -74,10 +74,10 @@ considered related." :group 'viper-mouse) ;; Local variable used to toggle wraparound search on click. -(viper-deflocalvar viper-mouse-click-search-noerror t) +(defvar-local viper-mouse-click-search-noerror t) ;; Local variable used to delimit search after wraparound. -(viper-deflocalvar viper-mouse-click-search-limit nil) +(defvar-local viper-mouse-click-search-limit nil) ;; remembers prefix argument to pass along to commands invoked by second ;; click. @@ -592,11 +592,4 @@ This buffer may be different from the one where the click occurred." :set 'viper-reset-mouse-insert-key :group 'viper-mouse) - - -;; Local Variables: -;; eval: (put 'viper-deflocalvar 'lisp-indent-hook 'defun) -;; End: - - ;;; viper-mous.el ends here diff --git a/lisp/emulation/viper-util.el b/lisp/emulation/viper-util.el index 07a234bab9..1bdb155538 100644 --- a/lisp/emulation/viper-util.el +++ b/lisp/emulation/viper-util.el @@ -1085,10 +1085,10 @@ the `Local variables' section of a file." ;; These are characters that are not to be considered as parts of a word in ;; Viper. ;; Set each time state changes and at loading time -(viper-deflocalvar viper-non-word-characters nil) +(defvar-local viper-non-word-characters nil) ;; must be buffer-local -(viper-deflocalvar viper-ALPHA-char-class "w" +(defvar-local viper-ALPHA-char-class "w" "String of syntax classes characterizing Viper's alphanumeric symbols. In addition, the symbol `_' may be considered alphanumeric if `viper-syntax-preference' is `strict-vi' or `reformed-vi'.") @@ -1375,10 +1375,4 @@ This option is appropriate if you like Emacs-style words." (setq i (1+ i) start (1+ start))) res)))))) - - -;; Local Variables: -;; eval: (put 'viper-deflocalvar 'lisp-indent-hook 'defun) -;; End: - ;;; viper-util.el ends here diff --git a/lisp/emulation/viper.el b/lisp/emulation/viper.el index 6c9428060f..df5a083a08 100644 --- a/lisp/emulation/viper.el +++ b/lisp/emulation/viper.el @@ -1256,9 +1256,4 @@ These two lines must come in the order given.")) (provide 'viper) - -;; Local Variables: -;; eval: (put 'viper-deflocalvar 'lisp-indent-hook 'defun) -;; End: - ;;; viper.el ends here commit 686caed4af6e92ae908f482151fa3da87aeab8ec Author: Alan Mackenzie Date: Sun Jan 31 11:20:50 2021 +0000 Don't attempt to display input method guidance in expired minibuffers This caused infinite waits in circumstances involving setting an input method in a global minor mode. This commit fixes bug #45792. * lisp/international/quail.el (quail-show-guidance): Test the major mode is not minibuffer-inactive-mode before proceding with the function. diff --git a/lisp/international/quail.el b/lisp/international/quail.el index 0901115cff..c66aa6a537 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el @@ -2027,10 +2027,15 @@ minibuffer and the selected frame has no other windows)." (bury-buffer quail-completion-buf) ;; Then, show the guidance. - (when (and (quail-require-guidance-buf) - (not input-method-use-echo-area) - (null unread-command-events) - (null unread-post-input-method-events)) + (when (and + ;; Don't try to display guidance on an expired minibuffer. This + ;; would go into an infinite wait rather than executing the user's + ;; command. Bug #45792. + (not (eq major-mode 'minibuffer-inactive-mode)) + (quail-require-guidance-buf) + (not input-method-use-echo-area) + (null unread-command-events) + (null unread-post-input-method-events)) (if (minibufferp) (if (eq (minibuffer-window) (frame-root-window)) ;; Use another frame. It is sure that we are using some commit 5cf9b915fa3557b4cd9e36ef8068d40b68ee485a Author: Lars Ingebrigtsen Date: Sun Jan 31 08:46:02 2021 +0100 execute-kbd-macro doc string clarification * src/macros.c (Fexecute_kbd_macro): Mention that the buffer is (potentially) changed (bug#37396). diff --git a/src/macros.c b/src/macros.c index c8ce94e63b..60d0766a75 100644 --- a/src/macros.c +++ b/src/macros.c @@ -279,7 +279,10 @@ its function definition is used. COUNT is a repeat count, or nil for once, or 0 for infinite loop. Optional third arg LOOPFUNC may be a function that is called prior to -each iteration of the macro. Iteration stops if LOOPFUNC returns nil. */) +each iteration of the macro. Iteration stops if LOOPFUNC returns nil. + +The buffer shown in the currently selected window will be made the current +buffer before the macro is executed. */) (Lisp_Object macro, Lisp_Object count, Lisp_Object loopfunc) { Lisp_Object final; commit d88e12aa19c42ceda39eacfe223c00d24bf31d3d Author: Lars Ingebrigtsen Date: Sun Jan 31 08:22:12 2021 +0100 Make operating-system-release obsolete * lisp/subr.el (operating-system-release): Make obsolete (bug#39940). There are no in-tree usages any more, and the data doesn't seem all that interesting on its own. diff --git a/lisp/subr.el b/lisp/subr.el index 34129ea38a..a85f41d7d7 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1701,6 +1701,7 @@ be a list of the form returned by `event-start' and `event-end'." (make-obsolete-variable 'redisplay-dont-pause nil "24.5") (make-obsolete 'window-redisplay-end-trigger nil "23.1") (make-obsolete 'set-window-redisplay-end-trigger nil "23.1") +(make-obsolete-variable 'operating-system-release nil "28.1") (make-obsolete 'run-window-configuration-change-hook nil "27.1") commit 21c4a3dfb4d5822ac8d25c54ea5ae160892ab896 Author: Lars Ingebrigtsen Date: Sun Jan 31 08:12:10 2021 +0100 Doc string improvements around `default-korean-keyboard' * lisp/language/korea-util.el (default-korean-keyboard): Mention "Hangul" here for easier discoverability. (toggle-korean-input-method, quail-hangul-switch-symbol-ksc) (quail-hangul-switch-hanja): Mention the variable. diff --git a/lisp/language/korea-util.el b/lisp/language/korea-util.el index c99ff3c3f2..b999eff662 100644 --- a/lisp/language/korea-util.el +++ b/lisp/language/korea-util.el @@ -32,13 +32,15 @@ (purecopy (if (string-match "3" (or (getenv "HANGUL_KEYBOARD_TYPE") "")) "3" "")) - "The kind of Korean keyboard for Korean input method. -\"\" for 2, \"3\" for 3.") + "The kind of Korean keyboard for Korean (Hangul) input method. +\"\" for 2, \"3\" for 3, and \"3f\" for 3f.") ;; functions useful for Korean text input (defun toggle-korean-input-method () - "Turn on or off a Korean text input method for the current buffer." + "Turn on or off a Korean text input method for the current buffer. +The keyboard layout variation used is determined by +`default-korean-keyboard'." (interactive) (if current-input-method (deactivate-input-method) @@ -46,7 +48,9 @@ (concat "korean-hangul" default-korean-keyboard)))) (defun quail-hangul-switch-symbol-ksc (&rest _ignore) - "Switch to/from Korean symbol package." + "Switch to/from Korean symbol package. +The keyboard layout variation used is determined by +`default-korean-keyboard'." (interactive "i") (and current-input-method (if (string-equal current-input-method "korean-symbol") @@ -55,7 +59,9 @@ (activate-input-method "korean-symbol")))) (defun quail-hangul-switch-hanja (&rest _ignore) - "Switch to/from Korean hanja package." + "Switch to/from Korean hanja package. +The keyboard layout variation used is determined by +`default-korean-keyboard'." (interactive "i") (and current-input-method (if (string-match "korean-hanja" current-input-method) commit 867b99d68fcd406243d5d48aef8cb072f229b5d4 Author: Lars Ingebrigtsen Date: Sun Jan 31 07:59:40 2021 +0100 Revert "Improve fontifying of #| ... |# in `lisp-mode'" This reverts commit 1275dc4711af77c9c223063dcd149d782d497463. Setting comment-end isn't the correct thing to do -- it makes M-; insert that string. diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 3918fa01b2..c96d849d44 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -775,7 +775,6 @@ or to switch back to an existing one." (setq-local find-tag-default-function 'lisp-find-tag-default) (setq-local comment-start-skip "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *") - (setq-local comment-end "|#") (setq imenu-case-fold-search t)) (defun lisp-find-tag-default () commit a0b743da19a5020436f9a46453b1817045483c98 Author: Stefan Kangas Date: Sun Jan 31 05:41:51 2021 +0100 ; Fix my previous commit * lisp/play/5x5.el (5x5-solver-output): Prefer defvar-local. * lisp/play/gamegrid.el (gamegrid-display-table): Provide default value. diff --git a/lisp/play/5x5.el b/lisp/play/5x5.el index c89188c023..05e61dfe40 100644 --- a/lisp/play/5x5.el +++ b/lisp/play/5x5.el @@ -141,7 +141,7 @@ map) "Local keymap for the 5x5 game.") -(5x5-defvar-local 5x5-solver-output nil +(defvar-local 5x5-solver-output nil "List that is the output of an arithmetic solver. This list L is such that diff --git a/lisp/play/gamegrid.el b/lisp/play/gamegrid.el index 34787d928e..8b64dfdf9b 100644 --- a/lisp/play/gamegrid.el +++ b/lisp/play/gamegrid.el @@ -50,7 +50,7 @@ (defvar-local gamegrid-display-mode nil) -(defvar-local gamegrid-display-table) +(defvar-local gamegrid-display-table nil) (defvar-local gamegrid-face-table nil) commit 31ec1a7d329cc9374b16c5831d30248c99e93dfb Author: Stefan Kangas Date: Sun Jan 31 05:27:06 2021 +0100 Prefer defvar-local in play/*.el * lisp/play/5x5.el (5x5-grid, 5x5-x-pos, 5x5-y-pos, 5x5-moves, 5x5-cracking): * lisp/play/decipher.el (decipher-alphabet) (decipher-stats-buffer, decipher-undo-list-size) (decipher-undo-list): * lisp/play/gamegrid.el (gamegrid-use-glyphs) (gamegrid-use-color, gamegrid-font, gamegrid-face) (gamegrid-display-options, gamegrid-buffer-width) (gamegrid-buffer-height, gamegrid-blank, gamegrid-timer) (gamegrid-display-mode, gamegrid-display-table) (gamegrid-face-table, gamegrid-buffer-start) (gamegrid-score-file-length): * lisp/play/snake.el (snake-length, snake-velocity-x) (snake-velocity-y, snake-positions, snake-score, snake-paused) (snake-moved-p, snake-velocity-queue): * lisp/play/tetris.el (tetris-shape, tetris-rot) (tetris-next-shape, tetris-n-shapes, tetris-n-rows) (tetris-score, tetris-pos-x, tetris-pos-y, tetris-paused): Prefer defvar-local. * lisp/play/5x5.el (5x5-defvar-local): Make obsolete. diff --git a/lisp/play/5x5.el b/lisp/play/5x5.el index 07ef30c07d..c89188c023 100644 --- a/lisp/play/5x5.el +++ b/lisp/play/5x5.el @@ -84,23 +84,24 @@ (defmacro 5x5-defvar-local (var value doc) "Define VAR to VALUE with documentation DOC and make it buffer local." + (declare (obsolete defvar-local "28.1")) `(progn (defvar ,var ,value ,doc) (make-variable-buffer-local (quote ,var)))) -(5x5-defvar-local 5x5-grid nil +(defvar-local 5x5-grid nil "5x5 grid contents.") -(5x5-defvar-local 5x5-x-pos 2 +(defvar-local 5x5-x-pos 2 "X position of cursor.") -(5x5-defvar-local 5x5-y-pos 2 +(defvar-local 5x5-y-pos 2 "Y position of cursor.") -(5x5-defvar-local 5x5-moves 0 +(defvar-local 5x5-moves 0 "Moves made.") -(5x5-defvar-local 5x5-cracking nil +(defvar-local 5x5-cracking nil "Are we in cracking mode?") (defvar 5x5-buffer-name "*5x5*" diff --git a/lisp/play/decipher.el b/lisp/play/decipher.el index a7a4b89c37..b870bfb4a1 100644 --- a/lisp/play/decipher.el +++ b/lisp/play/decipher.el @@ -184,28 +184,24 @@ the tail of the list." (cl-incf c)) (setq decipher-mode-syntax-table table))) -(defvar decipher-alphabet nil) +(defvar-local decipher-alphabet nil) ;; This is an alist containing entries (PLAIN-CHAR . CIPHER-CHAR), ;; where PLAIN-CHAR runs from ?a to ?z and CIPHER-CHAR is an uppercase ;; letter or space (which means no mapping is known for that letter). ;; This *must* contain entries for all lowercase characters. -(make-variable-buffer-local 'decipher-alphabet) -(defvar decipher-stats-buffer nil +(defvar-local decipher-stats-buffer nil "The buffer which displays statistics for this ciphertext. Do not access this variable directly, use the function `decipher-stats-buffer' instead.") -(make-variable-buffer-local 'decipher-stats-buffer) -(defvar decipher-undo-list-size 0 +(defvar-local decipher-undo-list-size 0 "The number of entries in the undo list.") -(make-variable-buffer-local 'decipher-undo-list-size) -(defvar decipher-undo-list nil +(defvar-local decipher-undo-list nil "The undo list for this buffer. Each element is either a cons cell (PLAIN-CHAR . CIPHER-CHAR) or a list of such cons cells.") -(make-variable-buffer-local 'decipher-undo-list) (defvar decipher-pending-undo-list nil) diff --git a/lisp/play/gamegrid.el b/lisp/play/gamegrid.el index e540ca723d..34787d928e 100644 --- a/lisp/play/gamegrid.el +++ b/lisp/play/gamegrid.el @@ -28,36 +28,35 @@ ;; ;;;;;;;;;;;;; buffer-local variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defvar gamegrid-use-glyphs t +(defvar-local gamegrid-use-glyphs t "Non-nil means use glyphs when available.") -(defvar gamegrid-use-color t +(defvar-local gamegrid-use-color t "Non-nil means use color when available.") -(defvar gamegrid-font "-*-courier-medium-r-*-*-*-140-100-75-*-*-iso8859-*" +(defvar-local gamegrid-font "-*-courier-medium-r-*-*-*-140-100-75-*-*-iso8859-*" "Name of the font used in X mode.") -(defvar gamegrid-face nil +(defvar-local gamegrid-face nil "Indicates the face to use as a default.") -(make-variable-buffer-local 'gamegrid-face) -(defvar gamegrid-display-options nil) +(defvar-local gamegrid-display-options nil) -(defvar gamegrid-buffer-width 0) -(defvar gamegrid-buffer-height 0) -(defvar gamegrid-blank 0) +(defvar-local gamegrid-buffer-width 0) +(defvar-local gamegrid-buffer-height 0) +(defvar-local gamegrid-blank 0) -(defvar gamegrid-timer nil) +(defvar-local gamegrid-timer nil) -(defvar gamegrid-display-mode nil) +(defvar-local gamegrid-display-mode nil) -(defvar gamegrid-display-table) +(defvar-local gamegrid-display-table) -(defvar gamegrid-face-table nil) +(defvar-local gamegrid-face-table nil) -(defvar gamegrid-buffer-start 1) +(defvar-local gamegrid-buffer-start 1) -(defvar gamegrid-score-file-length 50 +(defvar-local gamegrid-score-file-length 50 "Number of high scores to keep.") (defvar gamegrid-user-score-file-directory @@ -66,19 +65,6 @@ If Emacs was built without support for shared game scores, then this directory will be used.") -(make-variable-buffer-local 'gamegrid-use-glyphs) -(make-variable-buffer-local 'gamegrid-use-color) -(make-variable-buffer-local 'gamegrid-font) -(make-variable-buffer-local 'gamegrid-display-options) -(make-variable-buffer-local 'gamegrid-buffer-width) -(make-variable-buffer-local 'gamegrid-buffer-height) -(make-variable-buffer-local 'gamegrid-blank) -(make-variable-buffer-local 'gamegrid-timer) -(make-variable-buffer-local 'gamegrid-display-mode) -(make-variable-buffer-local 'gamegrid-display-table) -(make-variable-buffer-local 'gamegrid-face-table) -(make-variable-buffer-local 'gamegrid-buffer-start) -(make-variable-buffer-local 'gamegrid-score-file-length) ;; ;;;;;;;;;;;;; global variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/lisp/play/snake.el b/lisp/play/snake.el index 5584bf8810..bed7cea6ee 100644 --- a/lisp/play/snake.el +++ b/lisp/play/snake.el @@ -140,14 +140,14 @@ ;; ;;;;;;;;;;;;; variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defvar snake-length 0) -(defvar snake-velocity-x 1) -(defvar snake-velocity-y 0) -(defvar snake-positions nil) -(defvar snake-score 0) -(defvar snake-paused nil) -(defvar snake-moved-p nil) -(defvar snake-velocity-queue nil +(defvar-local snake-length 0) +(defvar-local snake-velocity-x 1) +(defvar-local snake-velocity-y 0) +(defvar-local snake-positions nil) +(defvar-local snake-score 0) +(defvar-local snake-paused nil) +(defvar-local snake-moved-p nil) +(defvar-local snake-velocity-queue nil "This queue stores the velocities requested too quickly by user. They will take effect one at a time at each clock-interval. This is necessary for proper behavior. @@ -158,16 +158,6 @@ we implemented all your keystrokes immediately, the snake would effectively never move up. Thus, we need to move it up for one turn and then start moving it leftwards.") - -(make-variable-buffer-local 'snake-length) -(make-variable-buffer-local 'snake-velocity-x) -(make-variable-buffer-local 'snake-velocity-y) -(make-variable-buffer-local 'snake-positions) -(make-variable-buffer-local 'snake-score) -(make-variable-buffer-local 'snake-paused) -(make-variable-buffer-local 'snake-moved-p) -(make-variable-buffer-local 'snake-velocity-queue) - ;; ;;;;;;;;;;;;; keymaps ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar snake-mode-map diff --git a/lisp/play/tetris.el b/lisp/play/tetris.el index 8205d3f79c..05e4ffe011 100644 --- a/lisp/play/tetris.el +++ b/lisp/play/tetris.el @@ -224,25 +224,15 @@ each one of its four blocks.") ;; ;;;;;;;;;;;;; variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defvar tetris-shape 0) -(defvar tetris-rot 0) -(defvar tetris-next-shape 0) -(defvar tetris-n-shapes 0) -(defvar tetris-n-rows 0) -(defvar tetris-score 0) -(defvar tetris-pos-x 0) -(defvar tetris-pos-y 0) -(defvar tetris-paused nil) - -(make-variable-buffer-local 'tetris-shape) -(make-variable-buffer-local 'tetris-rot) -(make-variable-buffer-local 'tetris-next-shape) -(make-variable-buffer-local 'tetris-n-shapes) -(make-variable-buffer-local 'tetris-n-rows) -(make-variable-buffer-local 'tetris-score) -(make-variable-buffer-local 'tetris-pos-x) -(make-variable-buffer-local 'tetris-pos-y) -(make-variable-buffer-local 'tetris-paused) +(defvar-local tetris-shape 0) +(defvar-local tetris-rot 0) +(defvar-local tetris-next-shape 0) +(defvar-local tetris-n-shapes 0) +(defvar-local tetris-n-rows 0) +(defvar-local tetris-score 0) +(defvar-local tetris-pos-x 0) +(defvar-local tetris-pos-y 0) +(defvar-local tetris-paused nil) ;; ;;;;;;;;;;;;; keymaps ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; commit e226357c3b651b525e82933423f84f497395432f Author: Stefan Kangas Date: Sun Jan 31 03:23:29 2021 +0100 Remove redundant defvar for artist-mode * lisp/textmodes/artist.el (artist-mode): Remove redundant defvar; it is defined by define-minor-mode. diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el index 50c00c9532..13b7118d2f 100644 --- a/lisp/textmodes/artist.el +++ b/lisp/textmodes/artist.el @@ -408,10 +408,6 @@ be in `artist-spray-chars', or spraying will behave strangely.") ;; Internal variables ;; -(defvar artist-mode nil - "Non-nil to enable `artist-mode' and nil to disable.") -(make-variable-buffer-local 'artist-mode) - (defvar artist-mode-name " Artist" "Name of Artist mode beginning with a space (appears in the mode-line).") commit fc66ec33226aeed0b745356363ed952c8ff1f7fd Author: Stefan Kangas Date: Sun Jan 31 03:19:41 2021 +0100 Prefer defvar-local in erc * lisp/erc/erc-backend.el (erc-server-current-nick) (erc-server-process, erc-session-server, erc-session-connector) (erc-session-port, erc-server-announced-name) (erc-server-version, erc-server-parameters) (erc-server-connected, erc-server-reconnect-count) (erc-server-quitting, erc-server-reconnecting) (erc-server-timed-out, erc-server-banned) (erc-server-error-occurred, erc-server-lines-sent) (erc-server-last-peers, erc-server-last-sent-time) (erc-server-last-ping-time, erc-server-last-received-time) (erc-server-lag, erc-server-filter-data, erc-server-duplicates) (erc-server-processing-p, erc-server-flood-last-message) (erc-server-flood-queue, erc-server-flood-timer) (erc-server-ping-handler): * lisp/erc/erc-capab.el (erc-capab-identify-activated) (erc-capab-identify-sent): * lisp/erc/erc-dcc.el (erc-dcc-byte-count, erc-dcc-entry-data) (erc-dcc-file-name): * lisp/erc/erc-ezbounce.el (erc-ezb-session-list): * lisp/erc/erc-join.el (erc--autojoin-timer): * lisp/erc/erc-netsplit.el (erc-netsplit-list): * lisp/erc/erc-networks.el (erc-network): * lisp/erc/erc-notify.el (erc-last-ison, erc-last-ison-time): * lisp/erc/erc-ring.el (erc-input-ring, erc-input-ring-index): * lisp/erc/erc-stamp.el (erc-timestamp-last-inserted) (erc-timestamp-last-inserted-left) (erc-timestamp-last-inserted-right): * lisp/erc/erc.el (erc-session-password, erc-channel-users) (erc-server-users, erc-channel-topic, erc-channel-modes) (erc-insert-marker, erc-input-marker, erc-last-saved-position) (erc-dbuf, erc-active-buffer, erc-default-recipients) (erc-session-user-full-name, erc-channel-user-limit) (erc-channel-key, erc-invitation, erc-channel-list) (erc-bad-nick, erc-logged-in, erc-default-nicks) (erc-nick-change-attempt-count, erc-send-input-line-function) (erc-channel-new-member-names, erc-channel-banlist) (erc-current-message-catalog): Prefer defvar-local. diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index 487dc7692e..4cabd42f53 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -120,38 +120,31 @@ ;;; User data -(defvar erc-server-current-nick nil +(defvar-local erc-server-current-nick nil "Nickname on the current server. Use `erc-current-nick' to access this.") -(make-variable-buffer-local 'erc-server-current-nick) ;;; Server attributes -(defvar erc-server-process nil +(defvar-local erc-server-process nil "The process object of the corresponding server connection.") -(make-variable-buffer-local 'erc-server-process) -(defvar erc-session-server nil +(defvar-local erc-session-server nil "The server name used to connect to for this session.") -(make-variable-buffer-local 'erc-session-server) -(defvar erc-session-connector nil +(defvar-local erc-session-connector nil "The function used to connect to this session (nil for the default).") -(make-variable-buffer-local 'erc-session-connector) -(defvar erc-session-port nil +(defvar-local erc-session-port nil "The port used to connect to.") -(make-variable-buffer-local 'erc-session-port) -(defvar erc-server-announced-name nil +(defvar-local erc-server-announced-name nil "The name the server announced to use.") -(make-variable-buffer-local 'erc-server-announced-name) -(defvar erc-server-version nil +(defvar-local erc-server-version nil "The name and version of the server's ircd.") -(make-variable-buffer-local 'erc-server-version) -(defvar erc-server-parameters nil +(defvar-local erc-server-parameters nil "Alist listing the supported server parameters. This is only set if the server sends 005 messages saying what is @@ -177,86 +170,70 @@ RFC2812 - server supports RFC 2812 features SILENCE=10 - supports the SILENCE command, maximum allowed number of entries TOPICLEN=160 - maximum allowed topic length WALLCHOPS - supports sending messages to all operators in a channel") -(make-variable-buffer-local 'erc-server-parameters) ;;; Server and connection state (defvar erc-server-ping-timer-alist nil "Mapping of server buffers to their specific ping timer.") -(defvar erc-server-connected nil +(defvar-local erc-server-connected nil "Non-nil if the current buffer has been used by ERC to establish an IRC connection. If you wish to determine whether an IRC connection is currently active, use the `erc-server-process-alive' function instead.") -(make-variable-buffer-local 'erc-server-connected) -(defvar erc-server-reconnect-count 0 +(defvar-local erc-server-reconnect-count 0 "Number of times we have failed to reconnect to the current server.") -(make-variable-buffer-local 'erc-server-reconnect-count) -(defvar erc-server-quitting nil +(defvar-local erc-server-quitting nil "Non-nil if the user requests a quit.") -(make-variable-buffer-local 'erc-server-quitting) -(defvar erc-server-reconnecting nil +(defvar-local erc-server-reconnecting nil "Non-nil if the user requests an explicit reconnect, and the current IRC process is still alive.") -(make-variable-buffer-local 'erc-server-reconnecting) -(defvar erc-server-timed-out nil +(defvar-local erc-server-timed-out nil "Non-nil if the IRC server failed to respond to a ping.") -(make-variable-buffer-local 'erc-server-timed-out) -(defvar erc-server-banned nil +(defvar-local erc-server-banned nil "Non-nil if the user is denied access because of a server ban.") -(make-variable-buffer-local 'erc-server-banned) -(defvar erc-server-error-occurred nil +(defvar-local erc-server-error-occurred nil "Non-nil if the user triggers some server error.") -(make-variable-buffer-local 'erc-server-error-occurred) -(defvar erc-server-lines-sent nil +(defvar-local erc-server-lines-sent nil "Line counter.") -(make-variable-buffer-local 'erc-server-lines-sent) -(defvar erc-server-last-peers '(nil . nil) +(defvar-local erc-server-last-peers '(nil . nil) "Last peers used, both sender and receiver. Those are used for /MSG destination shortcuts.") -(make-variable-buffer-local 'erc-server-last-peers) -(defvar erc-server-last-sent-time nil +(defvar-local erc-server-last-sent-time nil "Time the message was sent. This is useful for flood protection.") -(make-variable-buffer-local 'erc-server-last-sent-time) -(defvar erc-server-last-ping-time nil +(defvar-local erc-server-last-ping-time nil "Time the last ping was sent. This is useful for flood protection.") -(make-variable-buffer-local 'erc-server-last-ping-time) -(defvar erc-server-last-received-time nil +(defvar-local erc-server-last-received-time nil "Time the last message was received from the server. This is useful for detecting hung connections.") -(make-variable-buffer-local 'erc-server-last-received-time) -(defvar erc-server-lag nil +(defvar-local erc-server-lag nil "Calculated server lag time in seconds. This variable is only set in a server buffer.") -(make-variable-buffer-local 'erc-server-lag) -(defvar erc-server-filter-data nil +(defvar-local erc-server-filter-data nil "The data that arrived from the server but has not been processed yet.") -(make-variable-buffer-local 'erc-server-filter-data) -(defvar erc-server-duplicates (make-hash-table :test 'equal) +(defvar-local erc-server-duplicates (make-hash-table :test 'equal) "Internal variable used to track duplicate messages.") -(make-variable-buffer-local 'erc-server-duplicates) ;; From Circe -(defvar erc-server-processing-p nil +(defvar-local erc-server-processing-p nil "Non-nil when we're currently processing a message. When ERC receives a private message, it sets up a new buffer for @@ -267,23 +244,19 @@ network exceptions. So, if someone sends you two messages quickly after each other, ispell is started for the first, but might take long enough for the second message to be processed first.") -(make-variable-buffer-local 'erc-server-processing-p) -(defvar erc-server-flood-last-message 0 +(defvar-local erc-server-flood-last-message 0 "When we sent the last message. See `erc-server-flood-margin' for an explanation of the flood protection algorithm.") -(make-variable-buffer-local 'erc-server-flood-last-message) -(defvar erc-server-flood-queue nil +(defvar-local erc-server-flood-queue nil "The queue of messages waiting to be sent to the server. See `erc-server-flood-margin' for an explanation of the flood protection algorithm.") -(make-variable-buffer-local 'erc-server-flood-queue) -(defvar erc-server-flood-timer nil +(defvar-local erc-server-flood-timer nil "The timer to resume sending.") -(make-variable-buffer-local 'erc-server-flood-timer) ;;; IRC protocol and misc options @@ -453,9 +426,8 @@ If this is set to nil, never try to reconnect." :type '(choice (const :tag "Disabled" nil) (integer :tag "Seconds"))) -(defvar erc-server-ping-handler nil +(defvar-local erc-server-ping-handler nil "This variable holds the periodic ping timer.") -(make-variable-buffer-local 'erc-server-ping-handler) ;;;; Helper functions diff --git a/lisp/erc/erc-capab.el b/lisp/erc/erc-capab.el index 06d4fbd9f6..4e4d012545 100644 --- a/lisp/erc/erc-capab.el +++ b/lisp/erc/erc-capab.el @@ -113,13 +113,11 @@ character not found in IRC nicknames to avoid confusion." ;;; Variables: -(defvar erc-capab-identify-activated nil +(defvar-local erc-capab-identify-activated nil "CAPAB IDENTIFY-MSG has been activated.") -(make-variable-buffer-local 'erc-capab-identify-activated) -(defvar erc-capab-identify-sent nil +(defvar-local erc-capab-identify-sent nil "CAPAB IDENTIFY-MSG and IDENTIFY-CTCP messages have been sent.") -(make-variable-buffer-local 'erc-capab-identify-sent) ;;; Functions: diff --git a/lisp/erc/erc-dcc.el b/lisp/erc/erc-dcc.el index 590785e91c..9dedd3cda8 100644 --- a/lisp/erc/erc-dcc.el +++ b/lisp/erc/erc-dcc.el @@ -538,8 +538,7 @@ PROC is the server process." nil '(notice error) 'active 'dcc-get-notfound ?n nick ?f filename)))) -(defvar erc-dcc-byte-count nil) -(make-variable-buffer-local 'erc-dcc-byte-count) +(defvar-local erc-dcc-byte-count nil) (defun erc-dcc-do-LIST-command (proc) "This is the handler for the /dcc list command. @@ -751,9 +750,8 @@ the matching regexp, or nil if none found." 'dcc-malformed ?n nick ?u login ?h host ?q query))))) -(defvar erc-dcc-entry-data nil +(defvar-local erc-dcc-entry-data nil "Holds the `erc-dcc-list' entry for this DCC connection.") -(make-variable-buffer-local 'erc-dcc-entry-data) ;;; SEND handling @@ -905,8 +903,7 @@ other client." :group 'erc-dcc :type 'integer) -(defvar erc-dcc-file-name nil) -(make-variable-buffer-local 'erc-dcc-file-name) +(defvar-local erc-dcc-file-name nil) (defun erc-dcc-get-file (entry file parent-proc) "Set up a transfer from the remote client to the local over a TCP connection. diff --git a/lisp/erc/erc-ezbounce.el b/lisp/erc/erc-ezbounce.el index 62238dd434..8378ff5374 100644 --- a/lisp/erc/erc-ezbounce.el +++ b/lisp/erc/erc-ezbounce.el @@ -61,9 +61,8 @@ The alist's format is as follows: "Alist of actions to take on NOTICEs from EZBounce.") -(defvar erc-ezb-session-list '() +(defvar-local erc-ezb-session-list '() "List of detached EZBounce sessions.") -(make-variable-buffer-local 'erc-ezb-session-list) (defvar erc-ezb-inside-session-listing nil "Indicate whether current notices are expected to be EZB session listings.") diff --git a/lisp/erc/erc-join.el b/lisp/erc/erc-join.el index 947b294969..e6e5070783 100644 --- a/lisp/erc/erc-join.el +++ b/lisp/erc/erc-join.el @@ -105,8 +105,7 @@ servers, presumably in the same domain." :group 'erc-autojoin :type 'boolean) -(defvar erc--autojoin-timer nil) -(make-variable-buffer-local 'erc--autojoin-timer) +(defvar-local erc--autojoin-timer nil) (defun erc-autojoin-channels-delayed (server nick buffer) "Attempt to autojoin channels. diff --git a/lisp/erc/erc-netsplit.el b/lisp/erc/erc-netsplit.el index 9fd3cfe1cc..37fc4cf16c 100644 --- a/lisp/erc/erc-netsplit.el +++ b/lisp/erc/erc-netsplit.el @@ -82,12 +82,11 @@ Args: PROC is the process the netjoin originated from and :group 'erc-hooks :type 'hook) -(defvar erc-netsplit-list nil +(defvar-local erc-netsplit-list nil "This is a list of the form \((\"a.b.c.d e.f.g\" TIMESTAMP FIRST-JOIN \"nick1\" ... \"nickn\") ...) where FIRST-JOIN is t or nil, depending on whether or not the first join from that split has been detected or not.") -(make-variable-buffer-local 'erc-netsplit-list) (defun erc-netsplit-install-message-catalogs () (erc-define-catalog diff --git a/lisp/erc/erc-networks.el b/lisp/erc/erc-networks.el index 9c2bb9dfee..9926255e3a 100644 --- a/lisp/erc/erc-networks.el +++ b/lisp/erc/erc-networks.el @@ -722,9 +722,8 @@ MATCHER is used to find a corresponding network to a server while (regexp) (const :tag "Network has no common server ending" nil))))) -(defvar erc-network nil +(defvar-local erc-network nil "The name of the network you are connected to (a symbol).") -(make-variable-buffer-local 'erc-network) ;; Functions: diff --git a/lisp/erc/erc-notify.el b/lisp/erc/erc-notify.el index 098049edc6..e133e05a7d 100644 --- a/lisp/erc/erc-notify.el +++ b/lisp/erc/erc-notify.el @@ -75,13 +75,11 @@ strings." ;;;; Internal variables -(defvar erc-last-ison nil +(defvar-local erc-last-ison nil "Last ISON information received through `erc-notify-timer'.") -(make-variable-buffer-local 'erc-last-ison) -(defvar erc-last-ison-time 0 +(defvar-local erc-last-ison-time 0 "Last time ISON was sent to the server in `erc-notify-timer'.") -(make-variable-buffer-local 'erc-last-ison-time) ;;;; Setup diff --git a/lisp/erc/erc-ring.el b/lisp/erc/erc-ring.el index 3813eafe00..71a9f8ef3d 100644 --- a/lisp/erc/erc-ring.el +++ b/lisp/erc/erc-ring.el @@ -53,16 +53,14 @@ be recalled using M-p and M-n." (define-key erc-mode-map "\M-p" 'undefined) (define-key erc-mode-map "\M-n" 'undefined))) -(defvar erc-input-ring nil "Input ring for erc.") -(make-variable-buffer-local 'erc-input-ring) +(defvar-local erc-input-ring nil "Input ring for erc.") -(defvar erc-input-ring-index nil +(defvar-local erc-input-ring-index nil "Position in the input ring for erc. If nil, the input line is blank and the user is conceptually after the most recently added item in the ring. If an integer, the input line is non-blank and displays the item from the ring indexed by this variable.") -(make-variable-buffer-local 'erc-input-ring-index) (defun erc-input-ring-setup () "Do the setup required so that we can use comint style input rings. diff --git a/lisp/erc/erc-stamp.el b/lisp/erc/erc-stamp.el index c7dfb0807b..2c42a18081 100644 --- a/lisp/erc/erc-stamp.el +++ b/lisp/erc/erc-stamp.el @@ -191,21 +191,18 @@ or `erc-send-modify-hook'." (list (lambda (_window _before dir) (erc-echo-timestamp dir ct)))))))) -(defvar erc-timestamp-last-inserted nil +(defvar-local erc-timestamp-last-inserted nil "Last timestamp inserted into the buffer.") -(make-variable-buffer-local 'erc-timestamp-last-inserted) -(defvar erc-timestamp-last-inserted-left nil +(defvar-local erc-timestamp-last-inserted-left nil "Last timestamp inserted into the left side of the buffer. This is used when `erc-insert-timestamp-function' is set to `erc-timestamp-left-and-right'") -(make-variable-buffer-local 'erc-timestamp-last-inserted-left) -(defvar erc-timestamp-last-inserted-right nil +(defvar-local erc-timestamp-last-inserted-right nil "Last timestamp inserted into the right side of the buffer. This is used when `erc-insert-timestamp-function' is set to `erc-timestamp-left-and-right'") -(make-variable-buffer-local 'erc-timestamp-last-inserted-right) (defcustom erc-timestamp-only-if-changed-flag t "Insert timestamp only if its value changed since last insertion. diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index bb68173b6d..37e4cc39d5 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -270,9 +270,8 @@ A typical value would be \((\"#emacs\" \"QUIT\" \"JOIN\") :group 'erc-ignore :type 'erc-message-type) -(defvar erc-session-password nil +(defvar-local erc-session-password nil "The password used for the current session.") -(make-variable-buffer-local 'erc-session-password) (defcustom erc-disconnected-hook nil "Run this hook with arguments (NICK IP REASON) when disconnected. @@ -337,18 +336,16 @@ Functions are passed a buffer as the first argument." :type 'hook) -(defvar erc-channel-users nil +(defvar-local erc-channel-users nil "A hash table of members in the current channel, which associates nicknames with cons cells of the form: \(USER . MEMBER-DATA) where USER is a pointer to an erc-server-user struct, and MEMBER-DATA is a pointer to an erc-channel-user struct.") -(make-variable-buffer-local 'erc-channel-users) -(defvar erc-server-users nil +(defvar-local erc-server-users nil "A hash table of users on the current server, which associates nicknames with erc-server-user struct instances.") -(make-variable-buffer-local 'erc-server-users) (defun erc-downcase (string) "Convert STRING to IRC standard conforming downcase." @@ -632,23 +629,19 @@ See also: `erc-get-channel-user-list'." (or (not nicky) (string-lessp nickx nicky)))))))) -(defvar erc-channel-topic nil +(defvar-local erc-channel-topic nil "A topic string for the channel. Should only be used in channel-buffers.") -(make-variable-buffer-local 'erc-channel-topic) -(defvar erc-channel-modes nil +(defvar-local erc-channel-modes nil "List of strings representing channel modes. E.g. (\"i\" \"m\" \"s\" \"b Quake!*@*\") \(not sure the ban list will be here, but why not)") -(make-variable-buffer-local 'erc-channel-modes) -(defvar erc-insert-marker nil +(defvar-local erc-insert-marker nil "The place where insertion of new text in erc buffers should happen.") -(make-variable-buffer-local 'erc-insert-marker) -(defvar erc-input-marker nil +(defvar-local erc-input-marker nil "The marker where input should be inserted.") -(make-variable-buffer-local 'erc-input-marker) (defun erc-string-no-properties (string) "Return a copy of STRING will all text-properties removed." @@ -900,9 +893,8 @@ directory in the list." :group 'erc-scripts :type 'boolean) -(defvar erc-last-saved-position nil +(defvar-local erc-last-saved-position nil "A marker containing the position the current buffer was last saved at.") -(make-variable-buffer-local 'erc-last-saved-position) (defcustom erc-kill-buffer-on-part nil "Kill the channel buffer on PART. @@ -1271,8 +1263,7 @@ See also `erc-show-my-nick'." (defvar erc-debug-log-file (expand-file-name "ERC.debug") "Debug log file name.") -(defvar erc-dbuf nil) -(make-variable-buffer-local 'erc-dbuf) +(defvar-local erc-dbuf nil) (defmacro define-erc-module (name alias doc enable-body disable-body &optional local-p) @@ -1462,11 +1453,10 @@ If BUFFER is nil, the current buffer is used." ;; Last active buffer, to print server messages in the right place -(defvar erc-active-buffer nil +(defvar-local erc-active-buffer nil "The current active buffer, the one where the user typed the last command. Defaults to the server buffer, and should only be set in the server buffer.") -(make-variable-buffer-local 'erc-active-buffer) (defun erc-active-buffer () "Return the value of `erc-active-buffer' for the current server. @@ -1820,52 +1810,41 @@ all channel buffers on all servers." ;; Some local variables -(defvar erc-default-recipients nil +(defvar-local erc-default-recipients nil "List of default recipients of the current buffer.") -(make-variable-buffer-local 'erc-default-recipients) -(defvar erc-session-user-full-name nil +(defvar-local erc-session-user-full-name nil "Full name of the user on the current server.") -(make-variable-buffer-local 'erc-session-user-full-name) -(defvar erc-channel-user-limit nil +(defvar-local erc-channel-user-limit nil "Limit of users per channel.") -(make-variable-buffer-local 'erc-channel-user-limit) -(defvar erc-channel-key nil +(defvar-local erc-channel-key nil "Key needed to join channel.") -(make-variable-buffer-local 'erc-channel-key) -(defvar erc-invitation nil +(defvar-local erc-invitation nil "Last invitation channel.") -(make-variable-buffer-local 'erc-invitation) -(defvar erc-away nil +(defvar-local erc-away nil "Non-nil indicates that we are away. Use `erc-away-time' to access this if you might be in a channel buffer rather than a server buffer.") -(make-variable-buffer-local 'erc-away) -(defvar erc-channel-list nil +(defvar-local erc-channel-list nil "Server channel list.") -(make-variable-buffer-local 'erc-channel-list) -(defvar erc-bad-nick nil +(defvar-local erc-bad-nick nil "Non-nil indicates that we got a `nick in use' error while connecting.") -(make-variable-buffer-local 'erc-bad-nick) -(defvar erc-logged-in nil +(defvar-local erc-logged-in nil "Non-nil indicates that we are logged in.") -(make-variable-buffer-local 'erc-logged-in) -(defvar erc-default-nicks nil +(defvar-local erc-default-nicks nil "The local copy of `erc-nick' - the list of nicks to choose from.") -(make-variable-buffer-local 'erc-default-nicks) -(defvar erc-nick-change-attempt-count 0 +(defvar-local erc-nick-change-attempt-count 0 "Used to keep track of how many times an attempt at changing nick is made.") -(make-variable-buffer-local 'erc-nick-change-attempt-count) (defun erc-migrate-modules (mods) "Migrate old names of ERC modules to new ones." @@ -2764,8 +2743,7 @@ present." (let ((prop-val (erc-get-parsed-vector position))) (and prop-val (member (erc-response.command prop-val) list)))) -(defvar erc-send-input-line-function 'erc-send-input-line) -(make-variable-buffer-local 'erc-send-input-line-function) +(defvar-local erc-send-input-line-function 'erc-send-input-line) (defun erc-send-input-line (target line &optional force) "Send LINE to TARGET. @@ -3181,12 +3159,11 @@ were most recently invited. See also `invitation'." (defalias 'erc-cmd-CHANNEL 'erc-cmd-JOIN) (defalias 'erc-cmd-J 'erc-cmd-JOIN) -(defvar erc-channel-new-member-names nil +(defvar-local erc-channel-new-member-names nil "If non-nil, a names list is currently being received. If non-nil, this variable is a hash-table that associates received nicks with t.") -(make-variable-buffer-local 'erc-channel-new-member-names) (defun erc-cmd-NAMES (&optional channel) "Display the users in CHANNEL. @@ -3833,7 +3810,7 @@ If CHANNEL is not specified, clear the topic for the default channel." ;;; Banlists -(defvar erc-channel-banlist nil +(defvar-local erc-channel-banlist nil "A list of bans seen for the current channel. Each ban is an alist of the form: @@ -3841,7 +3818,6 @@ Each ban is an alist of the form: The property `received-from-server' indicates whether or not the ban list has been requested from the server.") -(make-variable-buffer-local 'erc-channel-banlist) (put 'erc-channel-banlist 'received-from-server nil) (defun erc-cmd-BANLIST () @@ -6783,8 +6759,7 @@ functions." ""))))) -(defvar erc-current-message-catalog 'english) -(make-variable-buffer-local 'erc-current-message-catalog) +(defvar-local erc-current-message-catalog 'english) (defun erc-retrieve-catalog-entry (entry &optional catalog) "Retrieve ENTRY from CATALOG. commit 44eb87cd0a8d7fb529e36b0aca9a3fc92d419822 Author: Stefan Kangas Date: Sun Jan 31 03:09:13 2021 +0100 Remove redundant requires of 'derived' * lisp/net/newst-backend.el (derived): * lisp/net/newst-plainview.el (derived): * lisp/play/gametree.el (derived): * lisp/textmodes/less-css-mode.el (derived): Remove redundant require; 'define-derived-mode' is autoloaded. diff --git a/lisp/net/newst-backend.el b/lisp/net/newst-backend.el index 3b120be61f..ea96012af2 100644 --- a/lisp/net/newst-backend.el +++ b/lisp/net/newst-backend.el @@ -34,7 +34,6 @@ ;; ====================================================================== ;;; Code: -(require 'derived) (require 'xml) (require 'url-parse) (require 'iso8601) diff --git a/lisp/net/newst-plainview.el b/lisp/net/newst-plainview.el index 44d2fd666a..21d47b838f 100644 --- a/lisp/net/newst-plainview.el +++ b/lisp/net/newst-plainview.el @@ -34,7 +34,6 @@ (require 'newst-ticker) (require 'newst-reader) -(require 'derived) (require 'xml) ;; Silence warnings diff --git a/lisp/play/gametree.el b/lisp/play/gametree.el index 1a1d2d7652..be39e1ebfb 100644 --- a/lisp/play/gametree.el +++ b/lisp/play/gametree.el @@ -79,7 +79,6 @@ ;;; Code: -(require 'derived) (require 'outline) ;;;; Configuration variables diff --git a/lisp/textmodes/less-css-mode.el b/lisp/textmodes/less-css-mode.el index 9cacc175ba..24ccb3ce98 100644 --- a/lisp/textmodes/less-css-mode.el +++ b/lisp/textmodes/less-css-mode.el @@ -73,7 +73,6 @@ (require 'compile) (require 'css-mode) -(require 'derived) (eval-when-compile (require 'subr-x)) (defgroup less-css nil commit cbeda210835bee9ff3e7f697c7944a10db8b132c Author: Stefan Kangas Date: Sun Jan 31 03:44:54 2021 +0100 Sync latest SKK-JISYO.L * leim/SKK-DIC/SKK-JISYO.L: Sync to current upstream version. diff --git a/leim/SKK-DIC/SKK-JISYO.L b/leim/SKK-DIC/SKK-JISYO.L index 9098868cae..78d6e08027 100644 --- a/leim/SKK-DIC/SKK-JISYO.L +++ b/leim/SKK-DIC/SKK-JISYO.L @@ -38109,8 +38109,8 @@ sari / sarin // sarod //å/ sars /severe acute respiratory syndrome/žɵƵ۴ɸ/ -sars-cov /severe acute respiratory syndrome coronavirus/SARSʥ륹 -sars-cov-2 /severe acute respiratory syndrome coronavirus 2/2019ʥ륹 +sars-cov /severe acute respiratory syndrome coronavirus/SARSʥ륹/ +sars-cov-2 /severe acute respiratory syndrome coronavirus 2/2019ʥ륹/ sartre /ȥ/ saruman /ޥ/ sasa // commit 0bc4b003d7493844d0f4aedb17cb1277bdf20533 Author: Stefan Kangas Date: Sun Jan 31 03:40:01 2021 +0100 ; emacs-26 → emacs-27 diff --git a/admin/gitmerge.el b/admin/gitmerge.el index b21cb3be33..be946f3468 100644 --- a/admin/gitmerge.el +++ b/admin/gitmerge.el @@ -126,7 +126,7 @@ If nil, the function `gitmerge-default-branch' guesses.") (string-to-number (match-string 1)))) (defun gitmerge-default-branch () - "Default for branch that should be merged; eg \"origin/emacs-26\"." + "Default for branch that should be merged; eg \"origin/emacs-27\"." (or gitmerge-default-branch (format "origin/emacs-%s" (1- (gitmerge-emacs-version))))) diff --git a/admin/make-tarball.txt b/admin/make-tarball.txt index 5125086e88..907afbbf5a 100644 --- a/admin/make-tarball.txt +++ b/admin/make-tarball.txt @@ -5,7 +5,7 @@ Instructions to create pretest or release tarballs. -*- coding: utf-8 -*- Steps to take before starting on the first pretest in any release sequence: -0. The release branch (e.g. emacs-26) should already have been made +0. The release branch (e.g. emacs-27) should already have been made and you should use it for all that follows. Diffs from this branch should be going to the emacs-diffs mailing list. diff --git a/admin/notes/git-workflow b/admin/notes/git-workflow index 28b6f91a25..143520c2c8 100644 --- a/admin/notes/git-workflow +++ b/admin/notes/git-workflow @@ -15,14 +15,14 @@ Initial setup ============= Then we want to clone the repository. We normally want to have both -the current master and the emacs-26 branch. +the current master and the emacs-27 branch. mkdir ~/emacs cd ~/emacs git clone @git.sv.gnu.org:/srv/git/emacs.git master cd master git config push.default current -git worktree add ../emacs-26 emacs-26 +git worktree add ../emacs-27 emacs-27 You now have both branches conveniently accessible, and you can do "git pull" in them once in a while to keep updated. @@ -52,11 +52,11 @@ you commit your change locally and then send a patch file as a bug report as described in ../../CONTRIBUTE. -Backporting to emacs-26 +Backporting to emacs-27 ======================= If you have applied a fix to the master, but then decide that it should -be applied to the emacs-26 branch, too, then +be applied to the emacs-27 branch, too, then cd ~/emacs/master git log @@ -66,7 +66,7 @@ which will look like commit 958b768a6534ae6e77a8547a56fc31b46b63710b -cd ~/emacs/emacs-26 +cd ~/emacs/emacs-27 git cherry-pick -xe 958b768a6534ae6e77a8547a56fc31b46b63710b and add "Backport:" to the commit string. Then @@ -74,17 +74,17 @@ and add "Backport:" to the commit string. Then git push -Merging emacs-26 to the master +Merging emacs-27 to the master ============================== It is recommended to use the file gitmerge.el in the admin directory -for merging 'emacs-26' into 'master'. It will take care of many +for merging 'emacs-27' into 'master'. It will take care of many things which would otherwise have to be done manually, like ignoring commits that should not land in master, fixing up ChangeLogs and automatically dealing with certain types of conflicts. If you really want to, you can do the merge manually, but then you're on your own. If you still choose to do that, make absolutely sure that you *always* -use the 'merge' command to transport commits from 'emacs-26' to +use the 'merge' command to transport commits from 'emacs-27' to 'master'. *Never* use 'cherry-pick'! If you don't know why, then you shouldn't manually do the merge in the first place; just use gitmerge.el instead. @@ -97,11 +97,11 @@ up-to-date by doing a pull. Then start Emacs with emacs -l admin/gitmerge.el -f gitmerge You'll be asked for the branch to merge, which will default to -'origin/emacs-26', which you should accept. Merging a local tracking +'origin/emacs-27', which you should accept. Merging a local tracking branch is discouraged, since it might not be up-to-date, or worse, contain commits from you which are not yet pushed upstream. -You will now see the list of commits from 'emacs-26' which are not yet +You will now see the list of commits from 'emacs-27' which are not yet merged to 'master'. You might also see commits that are already marked for "skipping", which means that they will be merged with a different merge strategy ('ours'), which will effectively ignore the diff --git a/nt/INSTALL.W64 b/nt/INSTALL.W64 index fdda1adf2e..32170bddc5 100644 --- a/nt/INSTALL.W64 +++ b/nt/INSTALL.W64 @@ -95,19 +95,19 @@ Savannah Emacs site, https://savannah.gnu.org/projects/emacs. The Emacs ftp site is located at https://ftp.gnu.org/gnu/emacs/ - download the version you want to build and put the file into a location like C:\emacs\, then uncompress it with tar. This will put the Emacs source into a folder like -C:\emacs\emacs-24.5: +C:\emacs\emacs-27.1: cd /c/emacs - tar xJf emacs-24.5.tar.xz + tar xJf emacs-27.1.tar.xz ** From the Git repository To download the Git repository, do something like the following -- this will -put the Emacs source into C:\emacs\emacs-26: +put the Emacs source into C:\emacs\emacs-27: mkdir /c/emacs cd /c/emacs - git clone git://git.sv.gnu.org/emacs.git emacs-26 + git clone git://git.sv.gnu.org/emacs.git emacs-27 (We recommend using the command shown on Savannah Emacs project page.) @@ -120,7 +120,7 @@ First we need to switch to the MinGW-w64 environment. Exit the MSYS2 BASH console and run mingw64.exe in the C:\msys64 folder, then cd back to your Emacs source directory, e.g.: - cd /c/emacs/emacs-26 + cd /c/emacs/emacs-27 ** Run autogen @@ -137,14 +137,14 @@ that the example given here is just a simple one - for more information on the options available please see the INSTALL file in this directory. The '--prefix' option specifies a location for the resulting binary files, -which 'make install' will use - in this example we set it to C:\emacs\emacs-26. +which 'make install' will use - in this example we set it to C:\emacs\emacs-27. If a prefix is not specified the files will be put in the standard Unix directories located in your C:\msys64 directory, but this is not recommended. Note also that we need to disable D-Bus because Emacs does not yet support them on Windows. - ./configure --prefix=/c/emacs/emacs-26 --without-dbus + ./configure --prefix=/c/emacs/emacs-27 --without-dbus ** Run make commit 0f2d87716a2cb6fae5ea6719763441c448fe7a74 Author: Dmitry Gutov Date: Sun Jan 31 03:08:38 2021 +0200 Recompute mode-lines when marking conflicts resolved * lisp/vc/vc.el (vc-mark-resolved): Recompute the mode lines of the affected files. diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index bc9f11202b..00976a07d4 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -1549,6 +1549,9 @@ After check-out, runs the normal hook `vc-checkout-hook'." (vc-call-backend backend 'mark-resolved files) ;; FIXME: Is this TRTD? Might not be. `((vc-state . edited))) + ;; Recompute mode lines. + (dolist (file files) + (vc-mode-line file backend)) (message (substitute-command-keys "Conflicts have been resolved in %s. \ commit 12189ae415f88984dd26712bdf4e4f9a50e10c8f (refs/remotes/origin/scratch/lexical-gnus-rc) Author: Stefan Monnier Date: Sat Jan 30 18:56:37 2021 -0500 * lisp/gnus: Use closures now that we activated `lexical-binding` * lisp/gnus/nnml.el (nnml-request-accept-article): * lisp/gnus/nnmairix.el (nnmairix-request-marks): * lisp/gnus/nnmail.el (nnmail-get-new-mail-1): * lisp/gnus/mm-view.el (mm-inline-image) (mm-inline-text-html-render-with-w3m, mm-inline-text) (mm-insert-inline, mm-inline-message): * lisp/gnus/mm-partial.el (mm-inline-partial): * lisp/gnus/mm-archive.el (mm-archive-dissect-and-inline): * lisp/gnus/gnus-util.el (gnus-create-info-command): * lisp/gnus/gnus-topic.el (gnus-topic-edit-parameters) (gnus-topic-sort-topics-1): * lisp/gnus/gnus-sum.el (gnus-summary-edit-article): * lisp/gnus/gnus-srvr.el (gnus-server-edit-server): * lisp/gnus/gnus-msg.el (gnus-inews-make-draft) (gnus-inews-add-send-actions, gnus-summary-cancel-article) (gnus-summary-supersede-article, gnus-summary-resend-message) (gnus-configure-posting-styles): * lisp/gnus/gnus-kill.el (gnus-execute): * lisp/gnus/gnus-html.el (gnus-html-wash-images): * lisp/gnus/gnus-group.el (gnus-group-edit-group) (gnus-group-nnimap-edit-acl): * lisp/gnus/gnus-draft.el (gnus-draft-edit-message, gnus-draft-setup): * lisp/gnus/gnus-art.el (gnus-article-edit-part) (gnus-mm-display-part, gnus-article-edit): * lisp/gnus/gnus-agent.el (gnus-category-edit-predicate) (gnus-category-edit-score, gnus-category-edit-groups): Use closures instead of `(lambda ...). * lisp/gnus/nnoo.el (noo--defalias): New function. (nnoo-import-1, nnoo-define-skeleton-1): Use it to avoid `eval`. diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el index 86c471197d..cbe3505cd1 100644 --- a/lisp/gnus/gnus-agent.el +++ b/lisp/gnus/gnus-agent.el @@ -2776,16 +2776,15 @@ The following commands are available: (gnus-edit-form (gnus-agent-cat-predicate info) (format "Editing the select predicate for category %s" category) - `(lambda (predicate) - ;; Avoid run-time execution of setf form - ;; (setf (gnus-agent-cat-predicate (assq ',category gnus-category-alist)) - ;; predicate) - ;; use its expansion instead: - (gnus-agent-cat-set-property (assq ',category gnus-category-alist) - 'agent-predicate predicate) - - (gnus-category-write) - (gnus-category-list))))) + (lambda (predicate) + ;; Avoid run-time execution of setf form + ;; (setf (gnus-agent-cat-predicate (assq ',category gnus-category-alist)) + ;; predicate) + ;; use its expansion instead: + (gnus-agent-cat-set-property (assq category gnus-category-alist) + 'agent-predicate predicate) + (gnus-category-write) + (gnus-category-list))))) (defun gnus-category-edit-score (category) "Edit the score expression for CATEGORY." @@ -2794,16 +2793,15 @@ The following commands are available: (gnus-edit-form (gnus-agent-cat-score-file info) (format "Editing the score expression for category %s" category) - `(lambda (score-file) - ;; Avoid run-time execution of setf form - ;; (setf (gnus-agent-cat-score-file (assq ',category gnus-category-alist)) - ;; score-file) - ;; use its expansion instead: - (gnus-agent-cat-set-property (assq ',category gnus-category-alist) - 'agent-score-file score-file) - - (gnus-category-write) - (gnus-category-list))))) + (lambda (score-file) + ;; Avoid run-time execution of setf form + ;; (setf (gnus-agent-cat-score-file (assq ',category gnus-category-alist)) + ;; score-file) + ;; use its expansion instead: + (gnus-agent-cat-set-property (assq category gnus-category-alist) + 'agent-score-file score-file) + (gnus-category-write) + (gnus-category-list))))) (defun gnus-category-edit-groups (category) "Edit the group list for CATEGORY." @@ -2812,16 +2810,15 @@ The following commands are available: (gnus-edit-form (gnus-agent-cat-groups info) (format "Editing the group list for category %s" category) - `(lambda (groups) - ;; Avoid run-time execution of setf form - ;; (setf (gnus-agent-cat-groups (assq ',category gnus-category-alist)) - ;; groups) - ;; use its expansion instead: - (gnus-agent-set-cat-groups (assq ',category gnus-category-alist) - groups) - - (gnus-category-write) - (gnus-category-list))))) + (lambda (groups) + ;; Avoid run-time execution of setf form + ;; (setf (gnus-agent-cat-groups (assq category gnus-category-alist)) + ;; groups) + ;; use its expansion instead: + (gnus-agent-set-cat-groups (assq category gnus-category-alist) + groups) + (gnus-category-write) + (gnus-category-list))))) (defun gnus-category-kill (category) "Kill the current category." diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index 25ebc30594..39b182f2cd 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -5002,53 +5002,53 @@ General format specifiers can also be used. See Info node "ID of a mime part that should be buttonized. `gnus-mime-save-part-and-strip' and `gnus-mime-delete-part' bind it.") +(defvar message-options-set-recipient) + (eval-when-compile (defsubst gnus-article-edit-part (handles &optional current-id) "Edit an article in order to delete a mime part. This function is exclusively used by `gnus-mime-save-part-and-strip' and `gnus-mime-delete-part', and not provided at run-time normally." - (gnus-article-edit-article - `(lambda () - (buffer-disable-undo) - (let ((mail-parse-charset (or gnus-article-charset - ',gnus-newsgroup-charset)) - (mail-parse-ignored-charsets - (or gnus-article-ignored-charsets - ',gnus-newsgroup-ignored-charsets)) - (mbl mml-buffer-list)) - (setq mml-buffer-list nil) - ;; A new text must be inserted before deleting existing ones - ;; at the end so as not to move existing markers of which - ;; the insertion type is t. - (delete-region - (point-min) - (prog1 - (goto-char (point-max)) - (insert-buffer-substring gnus-original-article-buffer))) - (mime-to-mml ',handles) - (setq gnus-article-mime-handles nil) - (let ((mbl1 mml-buffer-list)) - (setq mml-buffer-list mbl) - (setq-local mml-buffer-list mbl1)) - (add-hook 'kill-buffer-hook 'mml-destroy-buffers t t))) - `(lambda (no-highlight) - (let ((mail-parse-charset (or gnus-article-charset - ',gnus-newsgroup-charset)) - (message-options message-options) - (message-options-set-recipient) - (mail-parse-ignored-charsets - (or gnus-article-ignored-charsets - ',gnus-newsgroup-ignored-charsets))) - (mml-to-mime) - (mml-destroy-buffers) - (remove-hook 'kill-buffer-hook - 'mml-destroy-buffers t) - (kill-local-variable 'mml-buffer-list)) - (gnus-summary-edit-article-done - ,(or (mail-header-references gnus-current-headers) "") - ,(gnus-group-read-only-p) - ,gnus-summary-buffer no-highlight)) - t) + (let ((charset gnus-newsgroup-charset) + (ign-cs gnus-newsgroup-ignored-charsets) + (gch (or (mail-header-references gnus-current-headers) "")) + (ro (gnus-group-read-only-p)) + (buf gnus-summary-buffer)) + (gnus-article-edit-article + (lambda () + (buffer-disable-undo) + (let ((mail-parse-charset (or gnus-article-charset charset)) + (mail-parse-ignored-charsets + (or gnus-article-ignored-charsets ign-cs)) + (mbl mml-buffer-list)) + (setq mml-buffer-list nil) + ;; A new text must be inserted before deleting existing ones + ;; at the end so as not to move existing markers of which + ;; the insertion type is t. + (delete-region + (point-min) + (prog1 + (goto-char (point-max)) + (insert-buffer-substring gnus-original-article-buffer))) + (mime-to-mml handles) + (setq gnus-article-mime-handles nil) + (let ((mbl1 mml-buffer-list)) + (setq mml-buffer-list mbl) + (setq-local mml-buffer-list mbl1)) + (add-hook 'kill-buffer-hook #'mml-destroy-buffers t t))) + (lambda (no-highlight) + (let ((mail-parse-charset (or gnus-article-charset charset)) + (message-options message-options) + (message-options-set-recipient) + (mail-parse-ignored-charsets + (or gnus-article-ignored-charsets ign-cs))) + (mml-to-mime) + (mml-destroy-buffers) + (remove-hook 'kill-buffer-hook + #'mml-destroy-buffers t) + (kill-local-variable 'mml-buffer-list)) + (gnus-summary-edit-article-done gch ro buf no-highlight)) + t)) ;; Force buttonizing this part. (let ((gnus-mime-buttonized-part-id current-id)) (gnus-article-edit-done)) @@ -5768,10 +5768,11 @@ all parts." (mm-handle-media-type handle)) (mm-handle-set-undisplayer handle - `(lambda () - (let ((inhibit-read-only t)) - (delete-region ,(copy-marker (point-min) t) - ,(point-max-marker))))))) + (let ((beg (copy-marker (point-min) t)) + (end (point-max-marker))) + (lambda () + (let ((inhibit-read-only t)) + (delete-region beg end))))))) (part (mm-display-inline handle)))))) (when (markerp point) @@ -7280,12 +7281,13 @@ groups." (gnus-with-article-buffer (article-date-original)) (gnus-article-edit-article - 'ignore - `(lambda (no-highlight) - 'ignore - (gnus-summary-edit-article-done - ,(or (mail-header-references gnus-current-headers) "") - ,(gnus-group-read-only-p) ,gnus-summary-buffer no-highlight)))) + #'ignore + (let ((gch (or (mail-header-references gnus-current-headers) "")) + (ro (gnus-group-read-only-p)) + (buf gnus-summary-buffer)) + (lambda (no-highlight) + 'ignore + (gnus-summary-edit-article-done gch ro buf no-highlight))))) (defun gnus-article-edit-article (start-func exit-func &optional quiet) "Start editing the contents of the current article buffer." diff --git a/lisp/gnus/gnus-draft.el b/lisp/gnus/gnus-draft.el index a4bcae23bd..f68e9d6b74 100644 --- a/lisp/gnus/gnus-draft.el +++ b/lisp/gnus/gnus-draft.el @@ -99,10 +99,11 @@ (let ((gnus-verbose-backends nil)) (gnus-request-expire-articles (list article) group t)) (push - `((lambda () - (when (gnus-buffer-live-p ,gnus-summary-buffer) - (with-current-buffer ,gnus-summary-buffer - (gnus-cache-possibly-remove-article ,article nil nil nil t))))) + (let ((buf gnus-summary-buffer)) + (lambda () + (when (gnus-buffer-live-p buf) + (with-current-buffer buf + (gnus-cache-possibly-remove-article article nil nil nil t))))) message-send-actions))) (defun gnus-draft-send-message (&optional n) @@ -274,8 +275,7 @@ If DONT-POP is nil, display the buffer after setting it up." (gnus-configure-posting-styles) (setq gnus-message-group-art (cons gnus-newsgroup-name (cadr ga))) (setq message-post-method - `(lambda (arg) - (gnus-post-method arg ,(car ga)))) + (lambda (arg) (gnus-post-method arg (car ga)))) (unless (equal (cadr ga) "") (dolist (article (cdr ga)) (message-add-action diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index 6d969609c4..eec64fd217 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el @@ -2930,8 +2930,8 @@ and NEW-NAME will be prompted for." ((eq part 'params) "group parameters") (t "group info")) group) - `(lambda (form) - (gnus-group-edit-group-done ',part ,group form))) + (lambda (form) + (gnus-group-edit-group-done part group form))) (local-set-key "\C-c\C-i" (gnus-create-info-command @@ -3378,9 +3378,9 @@ Editing the access control list for `%s'. implementation-defined hierarchy, RENAME or DELETE mailbox) d - delete messages (STORE \\DELETED flag, perform EXPUNGE) a - administer (perform SETACL)" group) - `(lambda (form) - (nnimap-acl-edit - ,mailbox ',method ',acl form))))) + (lambda (form) + (nnimap-acl-edit + mailbox method acl form))))) ;; Group sorting commands ;; Suggested by Joe Hildebrand . diff --git a/lisp/gnus/gnus-html.el b/lisp/gnus/gnus-html.el index 962d7337ec..be62bfd81f 100644 --- a/lisp/gnus/gnus-html.el +++ b/lisp/gnus/gnus-html.el @@ -177,9 +177,9 @@ fit these criteria." (add-text-properties start end (list 'image-url url - 'image-displayer `(lambda (url start end) - (gnus-html-display-image url start end - ,alt-text)) + 'image-displayer (lambda (url start end) + (gnus-html-display-image url start end + alt-text)) 'help-echo alt-text 'button t 'keymap gnus-html-image-map diff --git a/lisp/gnus/gnus-kill.el b/lisp/gnus/gnus-kill.el index 00a4f11c6c..b0e6cb59d5 100644 --- a/lisp/gnus/gnus-kill.el +++ b/lisp/gnus/gnus-kill.el @@ -606,12 +606,10 @@ marked as read or ticked are ignored." (downcase (symbol-name header))) gnus-extra-headers))) (setq function - `(lambda (h) - (gnus-extra-header - (quote ,(nth (- (length gnus-extra-headers) - (length extras)) - gnus-extra-headers)) - h))))))) + (let ((type (nth (- (length gnus-extra-headers) + (length extras)) + gnus-extra-headers))) + (lambda (h) (gnus-extra-header type h)))))))) ;; Signal error. (t (error "Unknown header field: \"%s\"" field))) diff --git a/lisp/gnus/gnus-msg.el b/lisp/gnus/gnus-msg.el index 1bd62516b1..45e665be8c 100644 --- a/lisp/gnus/gnus-msg.el +++ b/lisp/gnus/gnus-msg.el @@ -389,9 +389,10 @@ only affect the Gcc copy, but not the original message." ;;; Internal functions. (defun gnus-inews-make-draft (articles) - `(lambda () - (gnus-inews-make-draft-meta-information - ,gnus-newsgroup-name ',articles))) + (let ((gn gnus-newsgroup-name)) + (lambda () + (gnus-inews-make-draft-meta-information + gn articles)))) (autoload 'nnselect-article-number "nnselect" nil nil 'macro) (autoload 'nnselect-article-group "nnselect" nil nil 'macro) @@ -578,8 +579,8 @@ instead." (when gnus-agent (add-hook 'message-header-hook #'gnus-agent-possibly-save-gcc nil t)) (setq message-post-method - `(lambda (&optional arg) - (gnus-post-method arg ,gnus-newsgroup-name))) + (let ((gn gnus-newsgroup-name)) + (lambda (&optional arg) (gnus-post-method arg gn)))) (message-add-action `(progn (setq gnus-current-window-configuration ',winconf-name) @@ -820,8 +821,8 @@ prefix `a', cancel using the standard posting method; if not post using the current select method." (interactive (gnus-interactive "P\ny")) (let ((message-post-method - `(lambda (arg) - (gnus-post-method (eq ',symp 'a) ,gnus-newsgroup-name))) + (let ((gn gnus-newsgroup-name)) + (lambda (_arg) (gnus-post-method (eq symp 'a) gn)))) (custom-address user-mail-address)) (dolist (article (gnus-summary-work-articles n)) (when (gnus-summary-select-article t nil nil article) @@ -856,11 +857,12 @@ header line with the old Message-ID." (set-buffer gnus-original-article-buffer) (message-supersede) (push - `((lambda () - (when (gnus-buffer-live-p ,gnus-summary-buffer) - (with-current-buffer ,gnus-summary-buffer - (gnus-cache-possibly-remove-article ,article nil nil nil t) - (gnus-summary-mark-as-read ,article gnus-canceled-mark))))) + (let ((buf gnus-summary-buffer)) + (lambda () + (when (gnus-buffer-live-p buf) + (with-current-buffer buf + (gnus-cache-possibly-remove-article article nil nil nil t) + (gnus-summary-mark-as-read article gnus-canceled-mark))))) message-send-actions) ;; Add Gcc header. (gnus-inews-insert-gcc)))) @@ -1387,11 +1389,12 @@ the message before resending." (add-hook 'message-header-setup-hook #'gnus-summary-resend-message-insert-gcc t) (add-hook 'message-sent-hook - `(lambda () - (let ((rfc2047-encode-encoded-words nil)) - ,(if gnus-agent - '(gnus-agent-possibly-do-gcc) - '(gnus-inews-do-gcc))))) + (let ((agent gnus-agent)) + (lambda () + (let ((rfc2047-encode-encoded-words nil)) + (if agent + (gnus-agent-possibly-do-gcc) + (gnus-inews-do-gcc)))))) (dolist (article (gnus-summary-work-articles n)) (if no-select (with-current-buffer " *nntpd*" @@ -1916,47 +1919,49 @@ this is a reply." ((eq 'eval (car result)) #'ignore) ((eq 'body (car result)) - `(lambda () - (save-excursion - (message-goto-body) - (insert ,(cdr result))))) + (let ((txt (cdr result))) + (lambda () + (save-excursion + (message-goto-body) + (insert txt))))) ((eq 'signature (car result)) (setq-local message-signature nil) (setq-local message-signature-file nil) - (if (not (cdr result)) - #'ignore - `(lambda () - (save-excursion - (let ((message-signature ,(cdr result))) - (when message-signature - (message-insert-signature))))))) + (let ((txt (cdr result))) + (if (not txt) + #'ignore + (lambda () + (save-excursion + (let ((message-signature txt)) + (when message-signature + (message-insert-signature)))))))) (t (let ((header (if (symbolp (car result)) (capitalize (symbol-name (car result))) - (car result)))) - `(lambda () - (save-excursion - (message-remove-header ,header) - (let ((value ,(cdr result))) - (when value - (message-goto-eoh) - (insert ,header ": " value) - (unless (bolp) - (insert "\n"))))))))) + (car result))) + (value (cdr result))) + (lambda () + (save-excursion + (message-remove-header header) + (when value + (message-goto-eoh) + (insert header ": " value) + (unless (bolp) + (insert "\n")))))))) nil 'local)) (when (or name address) (add-hook 'message-setup-hook - `(lambda () - (setq-local user-mail-address - ,(or (cdr address) user-mail-address)) - (let ((user-full-name ,(or (cdr name) (user-full-name))) - (user-mail-address - ,(or (cdr address) user-mail-address))) - (save-excursion - (message-remove-header "From") - (message-goto-eoh) - (insert "From: " (message-make-from) "\n")))) + (let ((name (or (cdr name) (user-full-name))) + (email (or (cdr address) user-mail-address))) + (lambda () + (setq-local user-mail-address email) + (let ((user-full-name name) + (user-mail-address email)) + (save-excursion + (message-remove-header "From") + (message-goto-eoh) + (insert "From: " (message-make-from) "\n"))))) nil 'local))))) (defun gnus-summary-attach-article (n) diff --git a/lisp/gnus/gnus-srvr.el b/lisp/gnus/gnus-srvr.el index 54b5a7d5fa..a305e343f6 100644 --- a/lisp/gnus/gnus-srvr.el +++ b/lisp/gnus/gnus-srvr.el @@ -612,10 +612,10 @@ The following commands are available: (gnus-close-server info) (gnus-edit-form info "Editing the server." - `(lambda (form) - (gnus-server-set-info ,server form) - (gnus-server-list-servers) - (gnus-server-position-point)) + (lambda (form) + (gnus-server-set-info server form) + (gnus-server-list-servers) + (gnus-server-position-point)) 'edit-server))) (defun gnus-server-show-server (server) diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index 39110338c3..456e7b0f8c 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -10676,31 +10676,32 @@ groups." (setq mml-buffer-list mbl) (setq-local mml-buffer-list mbl1)) (add-hook 'kill-buffer-hook #'mml-destroy-buffers t t)))) - `(lambda (no-highlight) - (let ((mail-parse-charset ',gnus-newsgroup-charset) - (message-options message-options) - (message-options-set-recipient) - (mail-parse-ignored-charsets - ',gnus-newsgroup-ignored-charsets) - (rfc2047-header-encoding-alist - ',(let ((charset (gnus-group-name-charset - (gnus-find-method-for-group - gnus-newsgroup-name) - gnus-newsgroup-name))) - (append (list (cons "Newsgroups" charset) - (cons "Followup-To" charset) - (cons "Xref" charset)) - rfc2047-header-encoding-alist)))) - ,(if (not raw) '(progn - (mml-to-mime) - (mml-destroy-buffers) - (remove-hook 'kill-buffer-hook - #'mml-destroy-buffers t) - (kill-local-variable 'mml-buffer-list))) - (gnus-summary-edit-article-done - ,(or (mail-header-references gnus-current-headers) "") - ,(gnus-group-read-only-p) - ,gnus-summary-buffer no-highlight)))))))) + (let ((charset gnus-newsgroup-charset) + (ign-cs gnus-newsgroup-ignored-charsets) + (hea (let ((charset (gnus-group-name-charset + (gnus-find-method-for-group + gnus-newsgroup-name) + gnus-newsgroup-name))) + (append (list (cons "Newsgroups" charset) + (cons "Followup-To" charset) + (cons "Xref" charset)) + rfc2047-header-encoding-alist))) + (gch (or (mail-header-references gnus-current-headers) "")) + (ro (gnus-group-read-only-p)) + (buf gnus-summary-buffer)) + (lambda (no-highlight) + (let ((mail-parse-charset charset) + (message-options message-options) + (message-options-set-recipient) + (mail-parse-ignored-charsets ign-cs) + (rfc2047-header-encoding-alist hea)) + (unless raw + (mml-to-mime) + (mml-destroy-buffers) + (remove-hook 'kill-buffer-hook + #'mml-destroy-buffers t) + (kill-local-variable 'mml-buffer-list)) + (gnus-summary-edit-article-done gch ro buf no-highlight))))))))) (defalias 'gnus-summary-edit-article-postpone 'gnus-article-edit-exit) diff --git a/lisp/gnus/gnus-topic.el b/lisp/gnus/gnus-topic.el index bbcccfee2f..e7d1cf8616 100644 --- a/lisp/gnus/gnus-topic.el +++ b/lisp/gnus/gnus-topic.el @@ -1608,8 +1608,8 @@ If performed on a topic, edit the topic parameters instead." (gnus-topic-parameters topic) (format-message "Editing the topic parameters for `%s'." (or group topic)) - `(lambda (form) - (gnus-topic-set-parameters ,topic form))))))) + (lambda (form) + (gnus-topic-set-parameters topic form))))))) (defun gnus-group-sort-topic (func reverse) "Sort groups in the topics according to FUNC and REVERSE." @@ -1693,9 +1693,8 @@ If REVERSE, sort in reverse order." (defun gnus-topic-sort-topics-1 (top reverse) (if (cdr top) (let ((subtop - (mapcar (gnus-byte-compile - `(lambda (top) - (gnus-topic-sort-topics-1 top ,reverse))) + (mapcar (lambda (top) + (gnus-topic-sort-topics-1 top reverse)) (sort (cdr top) (lambda (t1 t2) (string-lessp (caar t1) (caar t2))))))) diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el index f8d4325386..3c7c948c2b 100644 --- a/lisp/gnus/gnus-util.el +++ b/lisp/gnus/gnus-util.el @@ -1234,14 +1234,17 @@ sure of changing the value of `foo'." (cons (cons key value) (gnus-remassoc key alist)) (gnus-remassoc key alist))) +(defvar gnus-info-buffer) +(declare-function gnus-configure-windows "gnus-win" (setting &optional force)) + (defun gnus-create-info-command (node) "Create a command that will go to info NODE." - `(lambda () - (interactive) - ,(concat "Enter the info system at node " node) - (Info-goto-node ,node) - (setq gnus-info-buffer (current-buffer)) - (gnus-configure-windows 'info))) + (lambda () + (:documentation (format "Enter the info system at node %s." node)) + (interactive) + (info node) + (setq gnus-info-buffer (current-buffer)) + (gnus-configure-windows 'info))) (defun gnus-not-ignore (&rest _args) t) diff --git a/lisp/gnus/mm-archive.el b/lisp/gnus/mm-archive.el index d550045e0a..1ecceeedeb 100644 --- a/lisp/gnus/mm-archive.el +++ b/lisp/gnus/mm-archive.el @@ -100,11 +100,11 @@ (goto-char (point-max)) (mm-handle-set-undisplayer handle - `(lambda () - (let ((inhibit-read-only t) - (end ,(point-marker))) - (remove-images ,start end) - (delete-region ,start end))))))) + (let ((end (point-marker))) + (lambda () + (let ((inhibit-read-only t)) + (remove-images start end) + (delete-region start end)))))))) (provide 'mm-archive) diff --git a/lisp/gnus/mm-partial.el b/lisp/gnus/mm-partial.el index 8f5d45d67d..0c25c8f8bc 100644 --- a/lisp/gnus/mm-partial.el +++ b/lisp/gnus/mm-partial.el @@ -135,9 +135,11 @@ If NO-DISPLAY is nil, display it. Otherwise, do nothing after replacing." (mm-merge-handles gnus-article-mime-handles handles))) (mm-handle-set-undisplayer handle - `(lambda () - (let (buffer-read-only) - (delete-region ,(point-min-marker) ,(point-max-marker)))))))))) + (let ((beg (point-min-marker)) + (end (point-max-marker))) + (lambda () + (let ((inhibit-read-only t)) + (delete-region beg end)))))))))) (provide 'mm-partial) diff --git a/lisp/gnus/mm-view.el b/lisp/gnus/mm-view.el index f4c1cf9a6c..3e36d6724e 100644 --- a/lisp/gnus/mm-view.el +++ b/lisp/gnus/mm-view.el @@ -104,11 +104,10 @@ This is only used if `mm-inline-large-images' is set to (insert "\n") (mm-handle-set-undisplayer handle - `(lambda () - (let ((b ,b) - (inhibit-read-only t)) - (remove-images b b) - (delete-region b (1+ b))))))) + (lambda () + (let ((inhibit-read-only t)) + (remove-images b b) + (delete-region b (1+ b))))))) (defvar mm-w3m-setup nil "Whether gnus-article-mode has been setup to use emacs-w3m.") @@ -202,10 +201,11 @@ This is only used if `mm-inline-large-images' is set to 'keymap w3m-minor-mode-map))) (mm-handle-set-undisplayer handle - `(lambda () - (let ((inhibit-read-only t)) - (delete-region ,(point-min-marker) - ,(point-max-marker))))))))) + (let ((beg (point-min-marker)) + (end (point-max-marker))) + (lambda () + (let ((inhibit-read-only t)) + (delete-region beg end))))))))) (defcustom mm-w3m-standalone-supports-m17n-p 'undecided "T means the w3m command supports the m17n feature." @@ -381,10 +381,11 @@ This is only used if `mm-inline-large-images' is set to handle (if (= (point-min) (point-max)) #'ignore - `(lambda () - (let ((inhibit-read-only t)) - (delete-region ,(copy-marker (point-min) t) - ,(point-max-marker))))))))) + (let ((beg (copy-marker (point-min) t)) + (end (point-max-marker))) + (lambda () + (let ((inhibit-read-only t)) + (delete-region beg end))))))))) (defun mm-insert-inline (handle text) "Insert TEXT inline from HANDLE." @@ -394,10 +395,11 @@ This is only used if `mm-inline-large-images' is set to (insert "\n")) (mm-handle-set-undisplayer handle - `(lambda () - (let ((inhibit-read-only t)) - (delete-region ,(copy-marker b t) - ,(point-marker))))))) + (let ((beg (copy-marker b t)) + (end (point-marker))) + (lambda () + (let ((inhibit-read-only t)) + (delete-region beg end))))))) (defun mm-inline-audio (_handle) (message "Not implemented")) @@ -457,9 +459,11 @@ This is only used if `mm-inline-large-images' is set to (mm-merge-handles gnus-article-mime-handles handles))) (mm-handle-set-undisplayer handle - `(lambda () - (let ((inhibit-read-only t)) - (delete-region ,(point-min-marker) ,(point-max-marker))))))))) + (let ((beg (point-min-marker)) + (end (point-max-marker))) + (lambda () + (let ((inhibit-read-only t)) + (delete-region beg end))))))))) ;; Shut up byte-compiler. (defvar font-lock-mode-hook) diff --git a/lisp/gnus/nnmail.el b/lisp/gnus/nnmail.el index ac56e8f4b9..9826bc6172 100644 --- a/lisp/gnus/nnmail.el +++ b/lisp/gnus/nnmail.el @@ -1783,7 +1783,7 @@ be called once per group or once for all groups." (assq 'directory mail-sources))) (defun nnmail-get-new-mail-1 (method exit-func temp - group _in-group spool-func) + group in-group spool-func) (let* ((sources mail-sources) fetching-sources (i 0) @@ -1812,10 +1812,10 @@ be called once per group or once for all groups." (setq source (append source (list :predicate - (gnus-byte-compile - `(lambda (file) + (let ((str (concat group suffix))) + (lambda (file) (string-equal - ,(concat group suffix) + str (file-name-nondirectory file))))))))) (when nnmail-fetched-sources (if (member source nnmail-fetched-sources) @@ -1836,17 +1836,19 @@ be called once per group or once for all groups." (condition-case cond (mail-source-fetch source - (gnus-byte-compile - `(lambda (file orig-file) + (let ((smsym (intern (format "%s-save-mail" method))) + (ansym (intern (format "%s-active-number" method))) + (src source)) + (lambda (file orig-file) (nnmail-split-incoming - file ',(intern (format "%s-save-mail" method)) - ',spool-func + file smsym + spool-func (or in-group (if (equal file orig-file) nil (nnmail-get-split-group orig-file - ',source))) - ',(intern (format "%s-active-number" method)))))) + src))) + ansym)))) ((error quit) (message "Mail source %s failed: %s" source cond) 0))) diff --git a/lisp/gnus/nnmairix.el b/lisp/gnus/nnmairix.el index a2de5e061e..c6aaf460ec 100644 --- a/lisp/gnus/nnmairix.el +++ b/lisp/gnus/nnmairix.el @@ -701,8 +701,8 @@ Other back ends might or might not work.") (setf (gnus-info-read info) (if docorr (nnmairix-map-range - ;; FIXME: Use lexical-binding. - `(lambda (x) (+ x ,(cadr corr))) + (let ((off (cadr corr))) + (lambda (x) (+ x off))) (gnus-info-read folderinfo)) (gnus-info-read folderinfo))) ;; set other marks @@ -712,8 +712,8 @@ Other back ends might or might not work.") (cons (car cur) (nnmairix-map-range - ;; FIXME: Use lexical-binding. - `(lambda (x) (+ x ,(cadr corr))) + (let ((off (cadr corr))) + (lambda (x) (+ x off))) (list (cadr cur))))) (gnus-info-marks folderinfo)) (gnus-info-marks folderinfo)))) diff --git a/lisp/gnus/nnml.el b/lisp/gnus/nnml.el index 7bd295399c..18acc73aad 100644 --- a/lisp/gnus/nnml.el +++ b/lisp/gnus/nnml.el @@ -411,8 +411,8 @@ non-nil.") (and (nnmail-activate 'nnml) (if (and (not (setq result (nnmail-article-group - `(lambda (group) - (nnml-active-number group ,server))))) + (lambda (group) + (nnml-active-number group server))))) (yes-or-no-p "Moved to `junk' group; delete article? ")) (setq result 'junk) (setq result (car (nnml-save-mail result server t)))) diff --git a/lisp/gnus/nnoo.el b/lisp/gnus/nnoo.el index 2260fd694e..7759951662 100644 --- a/lisp/gnus/nnoo.el +++ b/lisp/gnus/nnoo.el @@ -49,6 +49,9 @@ (defun ,func ,args ,@forms) (nnoo-register-function ',func))) +(defun noo--defalias (fun val) + (prog1 (defalias fun val) (nnoo-register-function fun))) + (defun nnoo-register-function (func) (let ((funcs (nthcdr 3 (assoc (nnoo-backend func) nnoo-definition-alist)))) @@ -90,9 +93,9 @@ (dolist (fun (or (cdr imp) (nnoo-functions (car imp)))) (let ((function (nnoo-symbol backend (nnoo-rest-symbol fun)))) (unless (fboundp function) - ;; FIXME: Use `defalias' and closures to avoid `eval'. - (eval `(deffoo ,function (&rest args) - (,call-function ',backend ',fun args))))))))) + (noo--defalias function + (lambda (&rest args) + (funcall call-function backend fun args))))))))) (defun nnoo-parent-function (backend function args) (let ((pbackend (nnoo-backend function)) @@ -301,11 +304,9 @@ All functions will return nil and report an error." request-list request-post request-list-newsgroups)) (let ((fun (nnoo-symbol backend op))) (unless (fboundp fun) - ;; FIXME: Use `defalias' and closures to avoid `eval'. - (eval `(deffoo ,fun - (&rest _args) - (nnheader-report ',backend ,(format "%s-%s not implemented" - backend op)))))))) + (let ((msg (format "%s-%s not implemented" backend op))) + (noo--defalias fun + (lambda (&rest _args) (nnheader-report backend msg)))))))) (defun nnoo-set (server &rest args) (let ((parents (nnoo-parents (car server))) commit daa4e0120dc32a8c3eeafdf8914a0e29e5c149e9 Author: Stefan Monnier Date: Sat Jan 30 18:44:00 2021 -0500 * lisp/gnus: Use lexical-binding in all the files * lisp/gnus/gnus-group.el (features): Use `dlet`. (gnus-tmp-level, gnus-tmp-marked, gnus-tmp-group): Declare vars. (gnus-group-insert-group-line): Bind dynbound vars via `let` rather than as formal args. Bind `number` as dynbound. (gnus-visual, gnus-score-find-score-files-function) (gnus-home-score-file, gnus-apply-kill-hook) (gnus-summary-expunge-below): Declare vars. (gnus-group-restart, gnus-group-list-plus): Fix `interactive` spec since the arg is unused. * lisp/gnus/mail-source.el (mail-source-bind, mail-source-bind-common): Use `dlet` and suppress the warnings about the non-prefixed dynbound vars. (mail-source-set-1): Remove unused var `auth-info`. (mail-source-call-script): Remove unused var `background`. (mail-source-fetch-pop, mail-source-check-pop): Bind pop3 vars with `dlet`. * lisp/gnus/gnus-int.el (mail-source-plugged, gnus-inhibit-demon): Declare vars. (gnus-server-opened, gnus-status-message) (gnus-open-server, gnus-close-server, gnus-request-list) (gnus-finish-retrieve-group-infos, gnus-retrieve-group-data-early) (gnus-request-list-newsgroups, gnus-request-newgroups) (gnus-request-regenerate, gnus-request-compact, gnus-request-group) (gnus-retrieve-groups, gnus-request-post, gnus-request-expunge-group) (gnus-request-scan, gnus-request-update-info, gnus-request-marks) (gnus-request-accept-article, gnus-request-create-group) (gnus-asynchronous-p, gnus-remove-denial): Bind `gnus-command-method` via `let` rather than as formal args. * lisp/gnus/gnus-topic.el (gnus-topic-insert-topic-line): Pass documented vars to eval for `gnus-topic-line-format-spec`. * lisp/gnus/message.el (message-yank-original): Use `cl-progv` rather than `eval` to bind the vars from `message-cite-style`. * lisp/gnus/mml.el (mml-parse-1): Use `apply` instead of `eval`. (gnus-newsgroup-name, gnus-displaying-mime, gnus-newsgroup-name) (gnus-article-prepare-hook, gnus-newsgroup-charset) (gnus-original-article-buffer, gnus-message-buffer) (message-this-is-news, message-this-is-mail): Declare vars. * lisp/gnus/deuglify.el (gnus-outlook-rearrange-article): Remove unused var `cite-marks`. * lisp/gnus/gnus-art.el (ansi-color-context-region): Declare var. (gnus-mime-display-attachment-buttons-in-header): Move declaration before first use. (gnus-mime-display-alternative): Remove unused var `from`. * lisp/gnus/gnus-bookmark.el (gnus-bookmark-bmenu-list): Remove unused var `start` `end`. * lisp/gnus/gnus-cache.el (gnus-article-decode-hook) (nnml-generate-active-function): Declare var. * lisp/gnus/gnus-cite.el (gnus-message-citation-mode): Remove unused var `keywords`. * lisp/gnus/gnus-cloud.el (gnus-cloud-encode-data): Remove unused var `cipher`. (gnus-cloud-ensure-cloud-group): Remove unused var `method`. * lisp/gnus/gnus-delay.el (gnus-delay-article): Remove unused var `days`. * lisp/gnus/gnus-html.el (gnus-html-wash-images): Remove unused vars `tag`, `string`, and `images`. (gnus-html-wash-tags): Remove unused vars `string` and `images`. * lisp/gnus/gnus-msg.el (gnus-msg-mail): Remove unused var `group-name`. (gnus-group-mail, gnus-group-news, gnus-summary-mail-other-window) (gnus-summary-news-other-window): Remove unused vars `group` and `buffer`. (gnus-configure-posting-styles): Remove unused vars `style` and `attribute`. * lisp/gnus/gnus-picon.el (gnus-picon-find-face): Remove unused vars `database`, `directory`, and `instance`. (gnus-picon-transform-newsgroups): Remove unused var `point`. * lisp/gnus/gnus-range.el (gnus-range-difference): Remove unused var `safe`. * lisp/gnus/gnus-score.el (gnus-score-load-file): Remove unused var `score-fn`. * lisp/gnus/gnus-sum.el (message-options-set-recipient): Declare var. * lisp/gnus/gnus-undo.el (gnus-undo): Fix docstring lie. * lisp/gnus/gnus-util.el (print-string-length) (iswitchb-make-buflist-hook): Declare vars. (gnus-emacs-version): Remove unused var `codename`. (gnus-rename-file): Remove unused vars `old-name` and `new-name`. * lisp/gnus/gnus-uu.el (gnus-uu-yenc-article): Remove unused var `start-char`. (gnus-asynchronous): Declare var. * lisp/gnus/mm-partial.el (gnus-displaying-mime): Declare var. (mm-inline-partial): Remove unused var `buffer`. * lisp/gnus/mm-view.el (w3m-force-redisplay, w3m-safe-url-regexp) (gnus-displaying-mime, gnus-original-article-buffer) (gnus-article-prepare-hook): Declare vars. * lisp/gnus/mml-smime.el (mml-smime-epg-encrypt): Remove unused var `boundary`. (mml-smime-epg-verify): Remove unused vars `plain` and `signature-file`. * lisp/gnus/mml1991.el (pgg-text-mode): Declare var. * lisp/gnus/mml2015.el (pgg-text-mode): Declare var. (mml2015-pgg-decrypt): Remove unused var `result`. (mml2015-epg-key-image-to-string): Remove unused var `error`. (mml2015-epg-decrypt): Remove unused var `result`. (mml2015-epg-verify): Remove unused vars `plain` and `signature-file`. * lisp/gnus/nnbabyl.el (nnml-current-directory): Declare var. * lisp/gnus/nndiary.el (nndiary-files): Move declaration before first use. * lisp/gnus/nnfolder.el (nnfolder-request-accept-article): Remove unused var `buf`. * lisp/gnus/nnmail.el (nnmail-parse-active): Remove unused var `err`. * lisp/gnus/nnmairix.el (nnmairix-request-group): Remove unused var `args`. (nnmairix-request-create-group): Remove unused var `info`. (nnmairix-request-list): Remove unused var `folder`. (nnmairix-request-set-mark): Remove unused var `propto`. (nnmairix-request-set-mark): Remove unused vars `number` and `method`. (nnmairix-close-group): Remove unused var `method`. (nnmairix-create-search-group-from-message): Remove unused var `cq`. (nnmairix-create-server-and-default-group): Remove unused var `create`. (nnmairix-purge-old-groups): Remove unused var `folder`. (nnmairix-remove-tick-mark-original-article, nnmairix-get-valid-servers): Remove unused var `cur`. (nnmairix-replace-group-and-numbers): Remove unused var `header`. (nnmairix-goto-original-article): Remove unused var `rval`. (nnmairix-widget-create-query): Remove unused var `allwidgets`. * lisp/gnus/nnmbox.el (nnml-current-directory): Declare var. * lisp/gnus/nnmh.el (nnmh-toplev): Move declaration before first use. (nnmh-request-list-1): Remove unused var `rdir`. * lisp/gnus/nnml.el (nnml-generate-nov-file): Remove unused var `file`. * lisp/gnus/nnrss.el (nnrss-request-article): Remove unused var `post`. (nnrss-request-article): Remove unused var `fn`. (nnrss-check-group): Remove unused var `rdf-ns`. * lisp/gnus/nnweb.el (nnweb-request-article): Remove unused var `active`. (nnweb-google-parse-1): Remove unused var `Score`. * lisp/gnus/spam-stat.el (spam-stat-error-holder): Remove var. (spam-stat-buffer-words-with-scores): Remove unused var `word`. (spam-stat-score-buffer): Remove unused var `spam-stat-error-holder`. (spam-stat-split-fancy): Use `err` instead of `spam-stat-error-holder`. * lisp/gnus/spam-wash.el (spam-wash): Remove unused var `handle`. * lisp/gnus/spam.el (spam-copy-or-move-routine): Remove unused vars `article` and `mark`. (spam-register-routine): Remove unused var `article`. (spam-log-undo-registration): Remove unused var `found`. (spam-ifile-register-with-ifile): Remove unused var `parameters`. (spam-check-stat): Remove unused vars `category` and `return`. (spam-parse-list): Remove unused var `found`. (spam-filelist-register-routine): Remove unused var `from`. diff --git a/lisp/gnus/canlock.el b/lisp/gnus/canlock.el index 993050109d..dbdbaa83d7 100644 --- a/lisp/gnus/canlock.el +++ b/lisp/gnus/canlock.el @@ -1,4 +1,4 @@ -;;; canlock.el --- functions for Cancel-Lock feature +;;; canlock.el --- functions for Cancel-Lock feature -*- lexical-binding: t; -*- ;; Copyright (C) 1998-1999, 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/deuglify.el b/lisp/gnus/deuglify.el index 3a40b55f56..08beef7db9 100644 --- a/lisp/gnus/deuglify.el +++ b/lisp/gnus/deuglify.el @@ -1,4 +1,4 @@ -;;; deuglify.el --- deuglify broken Outlook (Express) articles +;;; deuglify.el --- deuglify broken Outlook (Express) articles -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. @@ -336,7 +336,8 @@ NODISPLAY is non-nil, don't redisplay the article buffer." "Put text from ATTR-START to the end of buffer at the top of the article buffer." ;; FIXME: 1. (*) text/plain ( ) text/html (let ((inhibit-read-only t) - (cite-marks gnus-outlook-deuglify-cite-marks)) + ;; (cite-marks gnus-outlook-deuglify-cite-marks) + ) (gnus-with-article-buffer (article-goto-body) ;; article does not start with attribution diff --git a/lisp/gnus/gmm-utils.el b/lisp/gnus/gmm-utils.el index 3542587319..bcf8dd014b 100644 --- a/lisp/gnus/gmm-utils.el +++ b/lisp/gnus/gmm-utils.el @@ -1,4 +1,4 @@ -;;; gmm-utils.el --- Utility functions for Gnus, Message and MML +;;; gmm-utils.el --- Utility functions for Gnus, Message and MML -*- lexical-binding: t; -*- ;; Copyright (C) 2006-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el index 9af19bd02c..86c471197d 100644 --- a/lisp/gnus/gnus-agent.el +++ b/lisp/gnus/gnus-agent.el @@ -1,4 +1,4 @@ -;;; gnus-agent.el --- unplugged support for Gnus +;;; gnus-agent.el --- unplugged support for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -820,7 +820,7 @@ be a select method." (condition-case err (while t (let ((bgn (point))) - (eval (read (current-buffer))) + (eval (read (current-buffer)) t) (delete-region bgn (point)))) (end-of-file (delete-file (gnus-agent-lib-file "flags"))) @@ -2666,7 +2666,7 @@ The following commands are available: (point) (prog1 (1+ (point)) ;; Insert the text. - (eval gnus-category-line-format-spec)) + (eval gnus-category-line-format-spec t)) (list 'gnus-category gnus-tmp-name)))) (defun gnus-enter-category-buffer () diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index 4034d362af..25ebc30594 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -1,4 +1,4 @@ -;;; gnus-art.el --- article mode commands for Gnus +;;; gnus-art.el --- article mode commands for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. @@ -1432,7 +1432,7 @@ See Info node `(gnus)Customizing Articles' and Info node (message "\ ** gnus-treat-display-xface is an obsolete variable;\ use gnus-treat-display-x-face instead") - (eval (car (get 'gnus-treat-display-xface 'saved-value)))) + (eval (car (get 'gnus-treat-display-xface 'saved-value)) t)) (t value))))) (put 'gnus-treat-display-x-face 'highlight t) @@ -2162,6 +2162,8 @@ MAP is an alist where the elements are on the form (\"from\" \"to\")." (put-text-property (point) (1+ (point)) 'face 'underline))))))))) +(defvar ansi-color-context-region) + (defun article-treat-ansi-sequences () "Translate ANSI SGR control sequences into overlays or extents." (interactive) @@ -2893,7 +2895,7 @@ message header will be added to the bodies of the \"text/html\" parts." (t "
\n")))) (goto-char (point-min)) (while (re-search-forward "^[\t ]+" nil t) - (dotimes (i (prog1 + (dotimes (_ (prog1 (current-column) (delete-region (match-beginning 0) (match-end 0)))) @@ -3021,6 +3023,8 @@ message header will be added to the bodies of the \"text/html\" parts." (setq showed t))))) showed)) +(defvar gnus-mime-display-attachment-buttons-in-header) + (defun gnus-article-browse-html-article (&optional arg) "View \"text/html\" parts of the current article with a WWW browser. Inline images embedded in a message using the cid scheme, as they are @@ -4712,8 +4716,6 @@ If ALL-HEADERS is non-nil, no headers are hidden." (gnus-run-hooks 'gnus-article-prepare-hook) t)))))) -(defvar gnus-mime-display-attachment-buttons-in-header) - ;;;###autoload (defun gnus-article-prepare-display () "Make the current buffer look like a nice article." @@ -6149,7 +6151,7 @@ If nil, don't show those extra buttons." (let* ((preferred (or preferred (mm-preferred-alternative handles))) (ihandles handles) (point (point)) - handle (inhibit-read-only t) from begend not-pref) + handle (inhibit-read-only t) begend not-pref) ;; from (save-window-excursion (save-restriction (when ibegend @@ -6170,7 +6172,8 @@ If nil, don't show those extra buttons." (not (gnus-unbuttonized-mime-type-p "multipart/alternative"))) (add-text-properties - (setq from (point)) + ;; (setq from + (point);; ) (progn (insert (format "%d. " id)) (point)) @@ -6191,7 +6194,8 @@ If nil, don't show those extra buttons." ;; Do the handles (while (setq handle (pop handles)) (add-text-properties - (setq from (point)) + ;; (setq from + (point) ;; ) (progn (insert (format "(%c) %-18s" (if (equal handle preferred) ?* ? ) @@ -7986,13 +7990,13 @@ specified by `gnus-button-alist'." (article-goto-body) (setq beg (point)) (while (setq entry (pop alist)) - (setq regexp (eval (car entry))) + (setq regexp (eval (car entry) t)) (goto-char beg) (while (re-search-forward regexp nil t) (let ((start (match-beginning (nth 1 entry))) (end (match-end (nth 1 entry))) (from (match-beginning 0))) - (when (and (eval (nth 2 entry)) + (when (and (eval (nth 2 entry) t) (not (gnus-button-in-region-p start end 'gnus-callback))) ;; That optional form returned non-nil, so we add the @@ -8083,14 +8087,14 @@ url is put as the `gnus-button-url' overlay property on the button." (match-beginning 0)) (point-max))) (goto-char beg) - (while (re-search-forward (eval (nth 1 entry)) end t) + (while (re-search-forward (eval (nth 1 entry) t) end t) ;; Each match within a header. (let* ((entry (cdr entry)) (start (match-beginning (nth 1 entry))) (end (match-end (nth 1 entry))) (form (nth 2 entry))) (goto-char (match-end 0)) - (when (eval form) + (when (eval form t) (gnus-article-add-button start end (nth 3 entry) (buffer-substring (match-beginning (nth 4 entry)) @@ -8099,7 +8103,7 @@ url is put as the `gnus-button-url' overlay property on the button." ;;; External functions: -(defun gnus-article-add-button (from to fun &optional data text) +(defun gnus-article-add-button (from to fun &optional data _text) "Create a button between FROM and TO with callback FUN and data DATA." (add-text-properties from to @@ -8312,7 +8316,7 @@ url is put as the `gnus-button-url' overlay property on the button." (setq indx (match-string 1 indx)) (Info-index indx) (when comma - (dotimes (i (with-temp-buffer + (dotimes (_ (with-temp-buffer (insert comma) ;; Note: the XEmacs version of `how-many' takes ;; no optional argument. diff --git a/lisp/gnus/gnus-bcklg.el b/lisp/gnus/gnus-bcklg.el index d6f53e4b38..6c7ad0c474 100644 --- a/lisp/gnus/gnus-bcklg.el +++ b/lisp/gnus/gnus-bcklg.el @@ -1,4 +1,4 @@ -;;; gnus-bcklg.el --- backlog functions for Gnus +;;; gnus-bcklg.el --- backlog functions for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/gnus-bookmark.el b/lisp/gnus/gnus-bookmark.el index c6eb2a1c1d..bc41d5b149 100644 --- a/lisp/gnus/gnus-bookmark.el +++ b/lisp/gnus/gnus-bookmark.el @@ -1,4 +1,4 @@ -;;; gnus-bookmark.el --- Bookmarks in Gnus +;;; gnus-bookmark.el --- Bookmarks in Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 2006-2021 Free Software Foundation, Inc. @@ -350,7 +350,7 @@ deletion, or > if it is flagged for displaying." (switch-to-buffer (gnus-get-buffer-create "*Gnus Bookmark List*")) (set-buffer (gnus-get-buffer-create "*Gnus Bookmark List*"))) (let ((inhibit-read-only t) - alist name start end) + alist name) ;; start end (erase-buffer) (insert "% Gnus Bookmark\n- --------\n") (add-text-properties (point-min) (point) diff --git a/lisp/gnus/gnus-cache.el b/lisp/gnus/gnus-cache.el index b17a11276c..5ed731947b 100644 --- a/lisp/gnus/gnus-cache.el +++ b/lisp/gnus/gnus-cache.el @@ -1,4 +1,4 @@ -;;; gnus-cache.el --- cache interface for Gnus +;;; gnus-cache.el --- cache interface for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -148,6 +148,8 @@ it's not cached." (gnus-kill-buffer buffer) (setq gnus-cache-buffer nil)))) +(defvar gnus-article-decode-hook) + (defun gnus-cache-possibly-enter-article (group article ticked dormant unread &optional force) (when (and (or force (not (eq gnus-use-cache 'passive))) @@ -728,6 +730,8 @@ If LOW, update the lower bound instead." (gnus-cache-write-active t) (gnus-message 5 "Generating the cache active file...done")))) +(defvar nnml-generate-active-function) + ;;;###autoload (defun gnus-cache-generate-nov-databases (dir) "Generate NOV files recursively starting in DIR." diff --git a/lisp/gnus/gnus-cite.el b/lisp/gnus/gnus-cite.el index c63adb36d8..96f1a7de5e 100644 --- a/lisp/gnus/gnus-cite.el +++ b/lisp/gnus/gnus-cite.el @@ -1,4 +1,4 @@ -;;; gnus-cite.el --- parse citations in articles for Gnus +;;; gnus-cite.el --- parse citations in articles for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -524,7 +524,7 @@ text (i.e., computer code and the like) will not be folded." ;; like code? Check for ragged edges on the left. (< (length columns) 3)))) -(defun gnus-article-hide-citation (&optional arg force) +(defun gnus-article-hide-citation (&optional arg _force) "Toggle hiding of all cited text except attribution lines. See the documentation for `gnus-article-highlight-citation'. If given a negative prefix, always show; if given a positive prefix, @@ -594,7 +594,7 @@ always hide." (progn (gnus-article-add-button (point) - (progn (eval gnus-cited-closed-text-button-line-format-spec) + (progn (eval gnus-cited-closed-text-button-line-format-spec t) (point)) 'gnus-article-toggle-cited-text (list (cons beg end) start)) @@ -644,7 +644,8 @@ means show, nil means toggle." (progn (eval (if hidden gnus-cited-opened-text-button-line-format-spec - gnus-cited-closed-text-button-line-format-spec)) + gnus-cited-closed-text-button-line-format-spec) + t) (point)) 'gnus-article-toggle-cited-text args) @@ -697,7 +698,7 @@ See also the documentation for `gnus-article-highlight-citation'." ;;; Internal functions: -(defun gnus-cite-parse-maybe (&optional force no-overlay) +(defun gnus-cite-parse-maybe (&optional _force no-overlay) "Always parse the buffer." (gnus-cite-localize) ;;Reset parser information. @@ -890,25 +891,25 @@ See also the documentation for `gnus-article-highlight-citation'." (regexp-quote tag) ">")))) ;; Find loose supercite citations after attributions. (gnus-cite-match-attributions 'small t - (lambda (prefix tag) + (lambda (_prefix tag) (when tag (concat "\\<" (regexp-quote tag) "\\>")))) ;; Find loose supercite citations anywhere. (gnus-cite-match-attributions 'small nil - (lambda (prefix tag) + (lambda (_prefix tag) (when tag (concat "\\<" (regexp-quote tag) "\\>")))) ;; Find nested citations after attributions. (gnus-cite-match-attributions 'small-if-unique t - (lambda (prefix tag) + (lambda (prefix _tag) (concat "\\`" (regexp-quote prefix) ".+"))) ;; Find nested citations anywhere. (gnus-cite-match-attributions 'small nil - (lambda (prefix tag) + (lambda (prefix _tag) (concat "\\`" (regexp-quote prefix) ".+"))) ;; Remove loose prefixes with too few lines. (let ((alist gnus-cite-loose-prefix-alist) @@ -1137,7 +1138,7 @@ When enabled, it automatically turns on `font-lock-mode'." (when (derived-mode-p 'message-mode) ;; FIXME: Use font-lock-add-keywords! (let ((defaults (car font-lock-defaults)) - default keywords) + default) ;; keywords (while defaults (setq default (if (consp defaults) (pop defaults) diff --git a/lisp/gnus/gnus-cloud.el b/lisp/gnus/gnus-cloud.el index 95ebf7fbe7..3bc94f11e7 100644 --- a/lisp/gnus/gnus-cloud.el +++ b/lisp/gnus/gnus-cloud.el @@ -1,4 +1,4 @@ -;;; gnus-cloud.el --- storing and retrieving data via IMAP +;;; gnus-cloud.el --- storing and retrieving data via IMAP -*- lexical-binding: t; -*- ;; Copyright (C) 2014-2021 Free Software Foundation, Inc. @@ -128,7 +128,7 @@ easy interactive way to set this from the Server buffer." ((eq gnus-cloud-storage-method 'epg) (let ((context (epg-make-context 'OpenPGP)) - cipher) + ) ;; cipher (setf (epg-context-armor context) t) (setf (epg-context-textmode context) t) (let ((data (epg-encrypt-string context @@ -344,15 +344,15 @@ easy interactive way to set this from the Server buffer." (group &optional previous method)) (defun gnus-cloud-ensure-cloud-group () - (let ((method (if (stringp gnus-cloud-method) - (gnus-server-to-method gnus-cloud-method) - gnus-cloud-method))) + ;; (let ((method (if (stringp gnus-cloud-method) + ;; (gnus-server-to-method gnus-cloud-method) + ;; gnus-cloud-method))) (unless (or (gnus-active gnus-cloud-group-name) (gnus-activate-group gnus-cloud-group-name nil nil gnus-cloud-method)) (and (gnus-request-create-group gnus-cloud-group-name gnus-cloud-method) (gnus-activate-group gnus-cloud-group-name nil nil gnus-cloud-method) - (gnus-subscribe-group gnus-cloud-group-name))))) + (gnus-subscribe-group gnus-cloud-group-name)))) ;; ) (defun gnus-cloud-upload-all-data () "Upload all data (newsrc and files) to the Gnus Cloud." diff --git a/lisp/gnus/gnus-cus.el b/lisp/gnus/gnus-cus.el index a36ef0cbec..d8f48b19f8 100644 --- a/lisp/gnus/gnus-cus.el +++ b/lisp/gnus/gnus-cus.el @@ -1,4 +1,4 @@ -;;; gnus-cus.el --- customization commands for Gnus +;;; gnus-cus.el --- customization commands for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1996, 1999-2021 Free Software Foundation, Inc. @@ -483,7 +483,7 @@ form, but who cares?" (buffer-enable-undo) (goto-char (point-min)))) -(defun gnus-group-customize-done (&rest ignore) +(defun gnus-group-customize-done (&rest _ignore) "Apply changes and bury the buffer." (interactive) (let ((params (widget-value gnus-custom-params))) @@ -927,7 +927,7 @@ articles in the thread. (use-local-map widget-keymap) (widget-setup))) -(defun gnus-score-customize-done (&rest ignore) +(defun gnus-score-customize-done (&rest _ignore) "Reset the score alist with the present value." (let ((alist gnus-custom-score-alist) (value (widget-value gnus-custom-scores))) @@ -1027,14 +1027,15 @@ articles in the thread. (widget-create 'push-button :notify - (lambda (&rest ignore) + (lambda (&rest _ignore) (let* ((info (assq gnus-agent-cat-name gnus-category-alist)) (widgets category-fields)) (while widgets (let* ((widget (pop widgets)) (value (condition-case nil (widget-value widget) (error)))) (eval `(setf (,(widget-get widget :accessor) ',info) - ',value))))) + ',value) + t)))) (gnus-category-write) (gnus-kill-buffer (current-buffer)) (when (get-buffer gnus-category-buffer) diff --git a/lisp/gnus/gnus-delay.el b/lisp/gnus/gnus-delay.el index 0699db405c..0cee01b942 100644 --- a/lisp/gnus/gnus-delay.el +++ b/lisp/gnus/gnus-delay.el @@ -1,4 +1,4 @@ -;;; gnus-delay.el --- Delayed posting of articles +;;; gnus-delay.el --- Delayed posting of articles -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. @@ -82,7 +82,7 @@ generated when the article is sent." gnus-delay-default-delay))) ;; Allow spell checking etc. (run-hooks 'message-send-hook) - (let (num unit days year month day hour minute deadline) + (let (num unit year month day hour minute deadline) ;; days (cond ((string-match "\\([0-9][0-9][0-9]?[0-9]?\\)-\\([0-9]+\\)-\\([0-9]+\\)" delay) @@ -167,7 +167,7 @@ generated when the article is sent." (message "Delay header missing for article %d" article))))))) ;;;###autoload -(defun gnus-delay-initialize (&optional no-keymap no-check) +(defun gnus-delay-initialize (&optional _no-keymap no-check) "Initialize the gnus-delay package. This sets up a key binding in `message-mode' to delay a message. This tells Gnus to look for delayed messages after getting new news. diff --git a/lisp/gnus/gnus-demon.el b/lisp/gnus/gnus-demon.el index f85d53f70e..e99247c0ca 100644 --- a/lisp/gnus/gnus-demon.el +++ b/lisp/gnus/gnus-demon.el @@ -1,4 +1,4 @@ -;;; gnus-demon.el --- daemonic Gnus behavior +;;; gnus-demon.el --- daemonic Gnus behavior -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/gnus-diary.el b/lisp/gnus/gnus-diary.el index ff563d6bf3..52705640bf 100644 --- a/lisp/gnus/gnus-diary.el +++ b/lisp/gnus/gnus-diary.el @@ -1,4 +1,4 @@ -;;; gnus-diary.el --- Wrapper around the NNDiary Gnus back end +;;; gnus-diary.el --- Wrapper around the NNDiary Gnus back end -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/gnus-dired.el b/lisp/gnus/gnus-dired.el index e412dd01a2..ca2d57de7d 100644 --- a/lisp/gnus/gnus-dired.el +++ b/lisp/gnus/gnus-dired.el @@ -1,4 +1,4 @@ -;;; gnus-dired.el --- utility functions where gnus and dired meet +;;; gnus-dired.el --- utility functions where gnus and dired meet -*- lexical-binding: t; -*- ;; Copyright (C) 1996-1999, 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/gnus-draft.el b/lisp/gnus/gnus-draft.el index 0752267e21..a4bcae23bd 100644 --- a/lisp/gnus/gnus-draft.el +++ b/lisp/gnus/gnus-draft.el @@ -1,4 +1,4 @@ -;;; gnus-draft.el --- draft message support for Gnus +;;; gnus-draft.el --- draft message support for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/gnus-eform.el b/lisp/gnus/gnus-eform.el index 6d0cea7feb..265edf4d61 100644 --- a/lisp/gnus/gnus-eform.el +++ b/lisp/gnus/gnus-eform.el @@ -1,4 +1,4 @@ -;;; gnus-eform.el --- a mode for editing forms for Gnus +;;; gnus-eform.el --- a mode for editing forms for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/gnus-fun.el b/lisp/gnus/gnus-fun.el index 8ce6990804..f69c2ed12c 100644 --- a/lisp/gnus/gnus-fun.el +++ b/lisp/gnus/gnus-fun.el @@ -1,4 +1,4 @@ -;;; gnus-fun.el --- various frivolous extension functions to Gnus +;;; gnus-fun.el --- various frivolous extension functions to Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index 0444b05450..6d969609c4 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el @@ -1,4 +1,4 @@ -;;; gnus-group.el --- group mode commands for Gnus +;;; gnus-group.el --- group mode commands for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. @@ -39,8 +39,9 @@ (eval-when-compile (require 'mm-url) (require 'subr-x) - (let ((features (cons 'gnus-group features))) - (require 'gnus-sum))) + (with-suppressed-warnings ((lexical features)) + (dlet ((features (cons 'gnus-group features))) + (require 'gnus-sum)))) (defvar gnus-cache-active-hashtb) @@ -476,6 +477,9 @@ simple manner." (defvar gnus-group-edit-buffer nil) +(defvar gnus-tmp-group) +(defvar gnus-tmp-level) +(defvar gnus-tmp-marked) (defvar gnus-tmp-news-method) (defvar gnus-tmp-colon) (defvar gnus-tmp-news-server) @@ -1499,11 +1503,15 @@ if it is a string, only list groups matching REGEXP." (gnus-group-get-new-news 0)))) :type 'boolean) -(defun gnus-group-insert-group-line (gnus-tmp-group gnus-tmp-level - gnus-tmp-marked number - gnus-tmp-method) +(defun gnus-group-insert-group-line (group level marked number gnus-tmp-method) "Insert a group line in the group buffer." - (let* ((gnus-tmp-method + (with-suppressed-warnings ((lexical number)) + (defvar number)) ;FIXME: Used in `gnus-group-line-format-alist'. + (let* ((number number) + (gnus-tmp-level level) + (gnus-tmp-marked marked) + (gnus-tmp-group group) + (gnus-tmp-method (gnus-server-get-method gnus-tmp-group gnus-tmp-method)) (gnus-tmp-active (gnus-active gnus-tmp-group)) (gnus-tmp-number-total @@ -1567,7 +1575,7 @@ if it is a string, only list groups matching REGEXP." (point) (prog1 (1+ (point)) ;; Insert the text. - (eval gnus-group-line-format-spec)) + (eval gnus-group-line-format-spec t)) `(gnus-group ,gnus-tmp-group gnus-unread ,(if (numberp number) (string-to-number gnus-tmp-number-of-unread) @@ -1738,7 +1746,7 @@ already. If INFO-UNCHANGED is non-nil, dribble buffer is not updated." (buffer-modified-p gnus-dribble-buffer) (with-current-buffer gnus-dribble-buffer (not (zerop (buffer-size)))))) - (mode-string (eval gformat))) + (mode-string (eval gformat t))) ;; Say whether the dribble buffer has been modified. (setq mode-line-modified (if modified "**" "--")) @@ -1934,7 +1942,7 @@ Return nil if the group isn't displayed." (gnus-group-mark-group 1 nil t)) (setq gnus-group-marked (cons group (delete group gnus-group-marked))))) -(defun gnus-group-universal-argument (arg &optional groups func) +(defun gnus-group-universal-argument (arg &optional _groups func) "Perform any command on all groups according to the process/prefix convention." (interactive "P") (if (eq (setq func (or func @@ -1945,7 +1953,7 @@ Return nil if the group isn't displayed." 'undefined) (gnus-error 1 "Undefined key") (gnus-group-iterate arg - (lambda (group) + (lambda (_group) (command-execute func)))) (gnus-group-position-point)) @@ -2054,6 +2062,12 @@ articles in the group." (forward-line -1)) (gnus-group-read-group all t)) +(defvar gnus-visual) +(defvar gnus-score-find-score-files-function) +(defvar gnus-home-score-file) +(defvar gnus-apply-kill-hook) +(defvar gnus-summary-expunge-below) + (defun gnus-group-quick-select-group (&optional all group) "Select the GROUP \"quickly\". This means that no highlighting or scoring will be performed. If @@ -2511,7 +2525,7 @@ The arguments have the same meaning as those of (if (stringp id) (setq id (string-to-number id))) (setq-local debbugs-gnu-bug-number id))))) -(defun gnus-group-jump-to-group (group &optional prompt) +(defun gnus-group-jump-to-group (group &optional _prompt) "Jump to newsgroup GROUP. If PROMPT (the prefix) is a number, use the prompt specified in @@ -2985,7 +2999,7 @@ and NEW-NAME will be prompted for." (setq method (copy-tree method)) (let (entry) (while (setq entry (memq (assq 'eval method) method)) - (setcar entry (eval (cadar entry))))) + (setcar entry (eval (cadar entry) t)))) (gnus-group-make-group group method)) (defun gnus-group-make-help-group (&optional noerror) @@ -4317,9 +4331,9 @@ If FORCE, force saving whether it is necessary or not." (interactive "P") (gnus-save-newsrc-file force)) -(defun gnus-group-restart (&optional arg) +(defun gnus-group-restart (&optional _arg) "Force Gnus to read the .newsrc file." - (interactive "P") + (interactive) (when (gnus-yes-or-no-p (format "Are you sure you want to restart Gnus? ")) (gnus-save-newsrc-file) @@ -4738,9 +4752,9 @@ This command may read the active file." (forward-char 1)) groups)) -(defun gnus-group-list-plus (&optional args) +(defun gnus-group-list-plus (&optional _args) "List groups plus the current selection." - (interactive "P") + (interactive) (let ((gnus-group-listed-groups (gnus-group-listed-groups)) (gnus-group-list-mode gnus-group-list-mode) ;; Save it. func) diff --git a/lisp/gnus/gnus-html.el b/lisp/gnus/gnus-html.el index 6a0cc0b47d..962d7337ec 100644 --- a/lisp/gnus/gnus-html.el +++ b/lisp/gnus/gnus-html.el @@ -1,4 +1,4 @@ -;;; gnus-html.el --- Render HTML in a buffer. +;;; gnus-html.el --- Render HTML in a buffer. -*- lexical-binding: t; -*- ;; Copyright (C) 2010-2021 Free Software Foundation, Inc. @@ -151,8 +151,8 @@ fit these criteria." (defun gnus-html-wash-images () "Run through current buffer and replace img tags by images." - (let (tag parameters string start end images - inhibit-images blocked-images) + (let ( parameters start end ;; tag string images + inhibit-images blocked-images) (if (buffer-live-p gnus-summary-buffer) (with-current-buffer gnus-summary-buffer (setq inhibit-images gnus-inhibit-images @@ -229,7 +229,7 @@ fit these criteria." (> width 4))) (gnus-html-display-image url start end alt-text)))))))))) -(defun gnus-html-display-image (url start end &optional alt-text) +(defun gnus-html-display-image (url _start _end &optional alt-text) "Display image at URL on text from START to END. Use ALT-TEXT for the image string." (or alt-text (setq alt-text "*")) @@ -248,7 +248,7 @@ Use ALT-TEXT for the image string." (gnus-html-put-image (gnus-html-get-image-data url) url alt-text)))) (defun gnus-html-wash-tags () - (let (tag parameters string start end images url) + (let (tag parameters start end url) ;; string images (gnus-html-pre-wash) (gnus-html-wash-images) diff --git a/lisp/gnus/gnus-int.el b/lisp/gnus/gnus-int.el index 8bad44687b..64928623e6 100644 --- a/lisp/gnus/gnus-int.el +++ b/lisp/gnus/gnus-int.el @@ -1,4 +1,4 @@ -;;; gnus-int.el --- backend interface functions for Gnus +;;; gnus-int.el --- backend interface functions for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. @@ -76,23 +76,25 @@ server denied." "The current method, for the registry.") -(defun gnus-server-opened (gnus-command-method) - "Check whether a connection to GNUS-COMMAND-METHOD has been opened." - (unless (eq (gnus-server-status gnus-command-method) +(defun gnus-server-opened (command-method) + "Check whether a connection to COMMAND-METHOD has been opened." + (unless (eq (gnus-server-status command-method) 'denied) - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (inline (gnus-get-function gnus-command-method 'server-opened)) - (nth 1 gnus-command-method)))) - -(defun gnus-status-message (gnus-command-method) - "Return the status message from GNUS-COMMAND-METHOD. -If GNUS-COMMAND-METHOD is a string, it is interpreted as a group -name. The method this group uses will be queried." + (let ((gnus-command-method + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method))) + (funcall (inline (gnus-get-function gnus-command-method 'server-opened)) + (nth 1 gnus-command-method))))) + +(defun gnus-status-message (command-method) + "Return the status message from COMMAND-METHOD. +If COMMAND-METHOD is a string, it is interpreted as a group name. +The method this group uses will be queried." (let ((gnus-command-method - (if (stringp gnus-command-method) - (gnus-find-method-for-group gnus-command-method) - gnus-command-method))) + (if (stringp command-method) + (gnus-find-method-for-group command-method) + command-method))) (funcall (gnus-get-function gnus-command-method 'status-message) (nth 1 gnus-command-method)))) @@ -265,13 +267,14 @@ If it is down, start it up (again)." type form)) (setq gnus-backend-trace-elapsed (float-time))))) -(defun gnus-open-server (gnus-command-method) - "Open a connection to GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) +(defun gnus-open-server (command-method) + "Open a connection to COMMAND-METHOD." (gnus-backend-trace :opening gnus-command-method) - (let ((elem (assoc gnus-command-method gnus-opened-servers)) - (server (gnus-method-to-server-name gnus-command-method))) + (let* ((gnus-command-method (if (stringp command-method) + (gnus-server-to-method command-method) + command-method)) + (elem (assoc gnus-command-method gnus-opened-servers)) + (server (gnus-method-to-server-name gnus-command-method))) ;; If this method was previously denied, we just return nil. (if (eq (nth 1 elem) 'denied) (progn @@ -347,23 +350,27 @@ If it is down, start it up (again)." (gnus-backend-trace :opened gnus-command-method) result))))) -(defun gnus-close-server (gnus-command-method) - "Close the connection to GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (prog1 - (funcall (gnus-get-function gnus-command-method 'close-server) - (nth 1 gnus-command-method) - (nthcdr 2 gnus-command-method)) - (when-let ((elem (assoc gnus-command-method gnus-opened-servers))) - (setf (nth 1 elem) 'closed)))) - -(defun gnus-request-list (gnus-command-method) - "Request the active file from GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'request-list) - (nth 1 gnus-command-method))) +(defun gnus-close-server (command-method) + "Close the connection to COMMAND-METHOD." + (let ((gnus-command-method + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method))) + (prog1 + (funcall (gnus-get-function gnus-command-method 'close-server) + (nth 1 gnus-command-method) + (nthcdr 2 gnus-command-method)) + (when-let ((elem (assoc gnus-command-method gnus-opened-servers))) + (setf (nth 1 elem) 'closed))))) + +(defun gnus-request-list (command-method) + "Request the active file from COMMAND-METHOD." + (let ((gnus-command-method + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method))) + (funcall (gnus-get-function gnus-command-method 'request-list) + (nth 1 gnus-command-method)))) (defun gnus-server-get-active (server &optional ignored) "Return the active list for SERVER. @@ -407,47 +414,57 @@ Groups matching the IGNORED regexp are excluded." (forward-line))))) groups)) -(defun gnus-finish-retrieve-group-infos (gnus-command-method infos data) - "Read and update infos from GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) +(defun gnus-finish-retrieve-group-infos (command-method infos data) + "Read and update infos from COMMAND-METHOD." + (let ((gnus-command-method + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method))) (gnus-backend-trace :finishing gnus-command-method) (prog1 (funcall (gnus-get-function gnus-command-method 'finish-retrieve-group-infos) (nth 1 gnus-command-method) infos data) - (gnus-backend-trace :finished gnus-command-method))) - -(defun gnus-retrieve-group-data-early (gnus-command-method infos) - "Start early async retrieval of data from GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'retrieve-group-data-early) - (nth 1 gnus-command-method) - infos)) - -(defun gnus-request-list-newsgroups (gnus-command-method) - "Request the newsgroups file from GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'request-list-newsgroups) - (nth 1 gnus-command-method))) - -(defun gnus-request-newgroups (date gnus-command-method) - "Request all new groups since DATE from GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (let ((func (gnus-get-function gnus-command-method 'request-newgroups t))) - (when func - (funcall func date (nth 1 gnus-command-method))))) - -(defun gnus-request-regenerate (gnus-command-method) - "Request a data generation from GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'request-regenerate) - (nth 1 gnus-command-method))) + (gnus-backend-trace :finished gnus-command-method)))) + +(defun gnus-retrieve-group-data-early (command-method infos) + "Start early async retrieval of data from COMMAND-METHOD." + (let ((gnus-command-method + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method))) + (funcall (gnus-get-function gnus-command-method 'retrieve-group-data-early) + (nth 1 gnus-command-method) + infos))) + +(defun gnus-request-list-newsgroups (command-method) + "Request the newsgroups file from COMMAND-METHOD." + (let ((gnus-command-method + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method))) + (funcall (gnus-get-function gnus-command-method 'request-list-newsgroups) + (nth 1 gnus-command-method)))) + +(defun gnus-request-newgroups (date command-method) + "Request all new groups since DATE from COMMAND-METHOD." + (let ((gnus-command-method + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method))) + (let ((func (gnus-get-function gnus-command-method 'request-newgroups t))) + (when func + (funcall func date (nth 1 gnus-command-method)))))) + +(defun gnus-request-regenerate (command-method) + "Request a data generation from COMMAND-METHOD." + (let ((gnus-command-method + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method))) + (funcall (gnus-get-function gnus-command-method 'request-regenerate) + (nth 1 gnus-command-method)))) (defun gnus-request-compact-group (group) (let* ((method (gnus-find-method-for-group group)) @@ -459,17 +476,19 @@ Groups matching the IGNORED regexp are excluded." (nth 1 gnus-command-method) t))) result)) -(defun gnus-request-compact (gnus-command-method) - "Request groups compaction from GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'request-compact) - (nth 1 gnus-command-method))) +(defun gnus-request-compact (command-method) + "Request groups compaction from COMMAND-METHOD." + (let ((gnus-command-method + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method))) + (funcall (gnus-get-function gnus-command-method 'request-compact) + (nth 1 gnus-command-method)))) -(defun gnus-request-group (group &optional dont-check gnus-command-method info) +(defun gnus-request-group (group &optional dont-check command-method info) "Request GROUP. If DONT-CHECK, no information is required." (let ((gnus-command-method - (or gnus-command-method (inline (gnus-find-method-for-group group))))) + (or command-method (inline (gnus-find-method-for-group group))))) (when (stringp gnus-command-method) (setq gnus-command-method (inline (gnus-server-to-method gnus-command-method)))) @@ -522,12 +541,14 @@ If FETCH-OLD, retrieve all headers (or some subset thereof) in the group." articles (gnus-group-real-name group) (nth 1 gnus-command-method)))) -(defun gnus-retrieve-groups (groups gnus-command-method) - "Request active information on GROUPS from GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'retrieve-groups) - groups (nth 1 gnus-command-method))) +(defun gnus-retrieve-groups (groups command-method) + "Request active information on GROUPS from COMMAND-METHOD." + (let ((gnus-command-method + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method))) + (funcall (gnus-get-function gnus-command-method 'retrieve-groups) + groups (nth 1 gnus-command-method)))) (defun gnus-request-type (group &optional article) "Return the type (`post' or `mail') of GROUP (and ARTICLE)." @@ -715,26 +736,33 @@ from other groups -- for instance, search results and the like." (delete-region (point-min) (1- (point)))))) res)) -(defun gnus-request-post (gnus-command-method) - "Post the current buffer using GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'request-post) - (nth 1 gnus-command-method))) +(defun gnus-request-post (command-method) + "Post the current buffer using COMMAND-METHOD." + (let ((gnus-command-method + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method))) + (funcall (gnus-get-function gnus-command-method 'request-post) + (nth 1 gnus-command-method)))) -(defun gnus-request-expunge-group (group gnus-command-method) +(defun gnus-request-expunge-group (group command-method) "Expunge GROUP, which is removing articles that have been marked as deleted." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'request-expunge-group) - (gnus-group-real-name group) - (nth 1 gnus-command-method))) - -(defun gnus-request-scan (group gnus-command-method) - "Request a SCAN being performed in GROUP from GNUS-COMMAND-METHOD. -If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned." (let ((gnus-command-method - (if group (gnus-find-method-for-group group) gnus-command-method)) + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method))) + (funcall (gnus-get-function gnus-command-method 'request-expunge-group) + (gnus-group-real-name group) + (nth 1 gnus-command-method)))) + +(defvar mail-source-plugged) +(defvar gnus-inhibit-demon) + +(defun gnus-request-scan (group command-method) + "Request a SCAN being performed in GROUP from COMMAND-METHOD. +If GROUP is nil, all groups on COMMAND-METHOD are scanned." + (let ((gnus-command-method + (if group (gnus-find-method-for-group group) command-method)) (gnus-inhibit-demon t) (mail-source-plugged gnus-plugged)) (when (or gnus-plugged @@ -744,36 +772,40 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned." (and group (gnus-group-real-name group)) (nth 1 gnus-command-method))))) -(defun gnus-request-update-info (info gnus-command-method) +(defun gnus-request-update-info (info command-method) (when (gnus-check-backend-function - 'request-update-info (car gnus-command-method)) - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'request-update-info) - (gnus-group-real-name (gnus-info-group info)) info - (nth 1 gnus-command-method)))) - -(defsubst gnus-request-marks (info gnus-command-method) - "Request that GNUS-COMMAND-METHOD update INFO." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (when (gnus-check-backend-function - 'request-marks (car gnus-command-method)) - (let ((group (gnus-info-group info))) - (and (funcall (gnus-get-function gnus-command-method 'request-marks) - (gnus-group-real-name group) - info (nth 1 gnus-command-method)) - ;; If the minimum article number is greater than 1, then all - ;; smaller article numbers are known not to exist; we'll - ;; artificially add those to the 'read range. - (let* ((active (gnus-active group)) - (min (car active))) - (when (> min 1) - (let* ((range (if (= min 2) 1 (cons 1 (1- min)))) - (read (gnus-info-read info)) - (new-read (gnus-range-add read (list range)))) - (setf (gnus-info-read info) new-read))) - info))))) + 'request-update-info (car command-method)) + (let ((gnus-command-method + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method))) + (funcall (gnus-get-function gnus-command-method 'request-update-info) + (gnus-group-real-name (gnus-info-group info)) info + (nth 1 gnus-command-method))))) + +(defsubst gnus-request-marks (info command-method) + "Request that COMMAND-METHOD update INFO." + (let ((gnus-command-method + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method))) + (when (gnus-check-backend-function + 'request-marks (car gnus-command-method)) + (let ((group (gnus-info-group info))) + (and (funcall (gnus-get-function gnus-command-method 'request-marks) + (gnus-group-real-name group) + info (nth 1 gnus-command-method)) + ;; If the minimum article number is greater than 1, then all + ;; smaller article numbers are known not to exist; we'll + ;; artificially add those to the 'read range. + (let* ((active (gnus-active group)) + (min (car active))) + (when (> min 1) + (let* ((range (if (= min 2) 1 (cons 1 (1- min)))) + (read (gnus-info-read info)) + (new-read (gnus-range-add read (list range)))) + (setf (gnus-info-read info) new-read))) + info)))))) (defun gnus-request-expire-articles (articles group &optional force) (let* ((gnus-command-method (gnus-find-method-for-group group)) @@ -794,7 +826,7 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned." (gnus-agent-expire expired-articles group 'force)))) not-deleted)) -(defun gnus-request-move-article (article group server accept-function +(defun gnus-request-move-article (article group _server accept-function &optional last move-is-internal) (let* ((gnus-command-method (gnus-find-method-for-group group)) (result (funcall (gnus-get-function gnus-command-method @@ -807,38 +839,40 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned." (gnus-agent-unfetch-articles group (list article))) result)) -(defun gnus-request-accept-article (group &optional gnus-command-method last +(defun gnus-request-accept-article (group &optional command-method last no-encode) - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (when (and (not gnus-command-method) - (stringp group)) - (setq gnus-command-method (or (gnus-find-method-for-group group) - (gnus-group-name-to-method group)))) - (goto-char (point-max)) - ;; Make sure there's a newline at the end of the article. - (unless (bolp) - (insert "\n")) - (unless no-encode - (let ((message-options message-options)) - (message-options-set-recipient) - (save-restriction - (message-narrow-to-head) - (mail-encode-encoded-word-buffer)) - (message-encode-message-body))) - (let ((gnus-command-method (or gnus-command-method - (gnus-find-method-for-group group))) - (result - (funcall - (gnus-get-function gnus-command-method 'request-accept-article) - (if (stringp group) (gnus-group-real-name group) group) - (cadr gnus-command-method) - last))) - (when (and gnus-agent - (gnus-agent-method-p gnus-command-method) - (cdr result)) - (gnus-agent-regenerate-group group (list (cdr result)))) - result)) + (let ((gnus-command-method + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method))) + (when (and (not gnus-command-method) + (stringp group)) + (setq gnus-command-method (or (gnus-find-method-for-group group) + (gnus-group-name-to-method group)))) + (goto-char (point-max)) + ;; Make sure there's a newline at the end of the article. + (unless (bolp) + (insert "\n")) + (unless no-encode + (let ((message-options message-options)) + (message-options-set-recipient) + (save-restriction + (message-narrow-to-head) + (mail-encode-encoded-word-buffer)) + (message-encode-message-body))) + (let ((gnus-command-method (or gnus-command-method + (gnus-find-method-for-group group))) + (result + (funcall + (gnus-get-function gnus-command-method 'request-accept-article) + (if (stringp group) (gnus-group-real-name group) group) + (cadr gnus-command-method) + last))) + (when (and gnus-agent + (gnus-agent-method-p gnus-command-method) + (cdr result)) + (gnus-agent-regenerate-group group (list (cdr result)))) + result))) (defun gnus-request-replace-article (article group buffer &optional no-encode) (unless no-encode @@ -862,13 +896,14 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned." article (gnus-group-real-name group) (nth 1 gnus-command-method)))) -(defun gnus-request-create-group (group &optional gnus-command-method args) - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (let ((gnus-command-method - (or gnus-command-method (gnus-find-method-for-group group)))) +(defun gnus-request-create-group (group &optional command-method args) + (let* ((gnus-command-method + (or (if (stringp command-method) + (gnus-server-to-method command-method) + command-method) + (gnus-find-method-for-group group)))) (funcall (gnus-get-function gnus-command-method 'request-create-group) - (gnus-group-real-name group) (nth 1 gnus-command-method) args))) + (gnus-group-real-name group) (nth 1 gnus-command-method) args))) (defun gnus-request-delete-group (group &optional force) (let* ((gnus-command-method (gnus-find-method-for-group group)) @@ -902,15 +937,18 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned." "-request-close")))) (funcall func))))) -(defun gnus-asynchronous-p (gnus-command-method) - (let ((func (gnus-get-function gnus-command-method 'asynchronous-p t))) +(defun gnus-asynchronous-p (command-method) + (let ((func (gnus-get-function command-method 'asynchronous-p t))) (when (fboundp func) - (funcall func)))) - -(defun gnus-remove-denial (gnus-command-method) - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (let* ((elem (assoc gnus-command-method gnus-opened-servers)) + (let ((gnus-command-method command-method)) + (funcall func))))) + +(defun gnus-remove-denial (command-method) + (let* ((gnus-command-method + (if (stringp command-method) + (gnus-server-to-method command-method) + command-method)) + (elem (assoc gnus-command-method gnus-opened-servers)) (status (cadr elem))) ;; If this hasn't been opened before, we add it to the list. (when (eq status 'denied) diff --git a/lisp/gnus/gnus-kill.el b/lisp/gnus/gnus-kill.el index 20ea983105..00a4f11c6c 100644 --- a/lisp/gnus/gnus-kill.el +++ b/lisp/gnus/gnus-kill.el @@ -1,4 +1,4 @@ -;;; gnus-kill.el --- kill commands for Gnus +;;; gnus-kill.el --- kill commands for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -275,7 +275,7 @@ If NEWSGROUP is nil, the global kill file is selected." (save-excursion (save-window-excursion (pop-to-buffer gnus-summary-buffer) - (eval (car (read-from-string string))))))) + (eval (car (read-from-string string)) t))))) (defun gnus-kill-file-apply-last-sexp () "Apply sexp before point in current buffer to current newsgroup." @@ -289,7 +289,7 @@ If NEWSGROUP is nil, the global kill file is selected." (save-excursion (save-window-excursion (pop-to-buffer gnus-summary-buffer) - (eval (car (read-from-string string)))))) + (eval (car (read-from-string string)) t)))) (ding) (gnus-message 2 "No newsgroup is selected."))) (defun gnus-kill-file-exit () @@ -403,9 +403,9 @@ Returns the number of articles marked as read." (eq (car form) 'gnus-lower)) (progn (delete-region beg (point)) - (insert (or (eval form) ""))) + (insert (or (eval form t) ""))) (with-current-buffer gnus-summary-buffer - (ignore-errors (eval form))))) + (ignore-errors (eval form t))))) (and (buffer-modified-p) gnus-kill-save-kill-file (save-buffer)) @@ -560,7 +560,7 @@ COMMAND must be a Lisp expression or a string representing a key sequence." ((functionp form) (funcall form)) (t - (eval form))))) + (eval form t))))) ;; Search article body. (let ((gnus-current-article nil) ;Save article pointer. (gnus-last-article nil) @@ -578,7 +578,7 @@ COMMAND must be a Lisp expression or a string representing a key sequence." ((functionp form) (funcall form)) (t - (eval form))))))) + (eval form t))))))) did-kill))) (defun gnus-execute (field regexp form &optional backward unread) diff --git a/lisp/gnus/gnus-logic.el b/lisp/gnus/gnus-logic.el index 105222d679..cdfdc9b731 100644 --- a/lisp/gnus/gnus-logic.el +++ b/lisp/gnus/gnus-logic.el @@ -1,4 +1,4 @@ -;;; gnus-logic.el --- advanced scoring code for Gnus +;;; gnus-logic.el --- advanced scoring code for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/gnus-mh.el b/lisp/gnus/gnus-mh.el index b26b736d05..fc8d9be8d6 100644 --- a/lisp/gnus/gnus-mh.el +++ b/lisp/gnus/gnus-mh.el @@ -1,4 +1,4 @@ -;;; gnus-mh.el --- mh-e interface for Gnus +;;; gnus-mh.el --- mh-e interface for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1994-2021 Free Software Foundation, Inc. @@ -95,7 +95,7 @@ Optional argument FOLDER specifies folder name." (kill-buffer errbuf)))) (setq gnus-newsgroup-last-folder folder))) -(defun gnus-Folder-save-name (newsgroup headers &optional last-folder) +(defun gnus-Folder-save-name (newsgroup _headers &optional last-folder) "Generate folder name from NEWSGROUP, HEADERS, and optional LAST-FOLDER. If variable `gnus-use-long-file-name' is nil, it is +News.group. Otherwise, it is like +news/group." @@ -105,7 +105,7 @@ Otherwise, it is like +news/group." (gnus-capitalize-newsgroup newsgroup) (gnus-newsgroup-directory-form newsgroup))))) -(defun gnus-folder-save-name (newsgroup headers &optional last-folder) +(defun gnus-folder-save-name (newsgroup _headers &optional last-folder) "Generate folder name from NEWSGROUP, HEADERS, and optional LAST-FOLDER. If variable `gnus-use-long-file-name' is nil, it is +news.group. Otherwise, it is like +news/group." diff --git a/lisp/gnus/gnus-ml.el b/lisp/gnus/gnus-ml.el index a47c15525a..3b2b5a07c1 100644 --- a/lisp/gnus/gnus-ml.el +++ b/lisp/gnus/gnus-ml.el @@ -1,4 +1,4 @@ -;;; gnus-ml.el --- Mailing list minor mode for Gnus +;;; gnus-ml.el --- Mailing list minor mode for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/gnus-mlspl.el b/lisp/gnus/gnus-mlspl.el index 77816d22eb..d42f097125 100644 --- a/lisp/gnus/gnus-mlspl.el +++ b/lisp/gnus/gnus-mlspl.el @@ -1,4 +1,4 @@ -;;; gnus-mlspl.el --- a group params-based mail splitting mechanism +;;; gnus-mlspl.el --- a group params-based mail splitting mechanism -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/gnus-msg.el b/lisp/gnus/gnus-msg.el index 49be704785..1bd62516b1 100644 --- a/lisp/gnus/gnus-msg.el +++ b/lisp/gnus/gnus-msg.el @@ -1,4 +1,4 @@ -;;; gnus-msg.el --- mail and post interface for Gnus +;;; gnus-msg.el --- mail and post interface for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -517,7 +517,7 @@ instead." switch-action yank-action send-actions return-action)) (let ((buf (current-buffer)) ;; Don't use posting styles corresponding to any existing group. - (group-name gnus-newsgroup-name) + ;; (group-name gnus-newsgroup-name) mail-buf) (let ((gnus-newsgroup-name "")) (gnus-setup-message @@ -610,10 +610,10 @@ If ARG is 1, prompt for a group name to find the posting style." (interactive "P") ;; We can't `let' gnus-newsgroup-name here, since that leads ;; to local variables leaking. - (let* ((group gnus-newsgroup-name) + (let* (;;(group gnus-newsgroup-name) ;; make sure last viewed article doesn't affect posting styles: (gnus-article-copy) - (buffer (current-buffer)) + ;; (buffer (current-buffer)) (gnus-newsgroup-name (if arg (if (= 1 (prefix-numeric-value arg)) @@ -635,10 +635,10 @@ network. The corresponding back end must have a `request-post' method." (interactive "P") ;; We can't `let' gnus-newsgroup-name here, since that leads ;; to local variables leaking. - (let* ((group gnus-newsgroup-name) + (let* (;;(group gnus-newsgroup-name) ;; make sure last viewed article doesn't affect posting styles: (gnus-article-copy) - (buffer (current-buffer)) + ;; (buffer (current-buffer)) (gnus-newsgroup-name (if arg (if (= 1 (prefix-numeric-value arg)) @@ -678,10 +678,10 @@ posting style." (interactive "P") ;; We can't `let' gnus-newsgroup-name here, since that leads ;; to local variables leaking. - (let* ((group gnus-newsgroup-name) + (let* (;;(group gnus-newsgroup-name) ;; make sure last viewed article doesn't affect posting styles: (gnus-article-copy) - (buffer (current-buffer)) + ;; (buffer (current-buffer)) (gnus-newsgroup-name (if arg (if (= 1 (prefix-numeric-value arg)) @@ -703,10 +703,10 @@ network. The corresponding back end must have a `request-post' method." (interactive "P") ;; We can't `let' gnus-newsgroup-name here, since that leads ;; to local variables leaking. - (let* ((group gnus-newsgroup-name) + (let* (;;(group gnus-newsgroup-name) ;; make sure last viewed article doesn't affect posting styles: (gnus-article-copy) - (buffer (current-buffer)) + ;; (buffer (current-buffer)) (gnus-newsgroup-name (if arg (if (= 1 (prefix-numeric-value arg)) @@ -930,7 +930,7 @@ header line with the old Message-ID." (run-hooks 'gnus-article-decode-hook))))) gnus-article-copy))) -(defun gnus-post-news (post &optional group header article-buffer yank subject +(defun gnus-post-news (post &optional group header article-buffer yank _subject force-news) (when article-buffer (gnus-copy-article-buffer)) @@ -1732,7 +1732,7 @@ this is a reply." ;; Function. (funcall (car var) group)) (t - (eval (car var))))))) + (eval (car var) t)))))) (setq var (cdr var))) result))) name) @@ -1789,7 +1789,7 @@ this is a reply." (with-current-buffer gnus-summary-buffer gnus-posting-styles) gnus-posting-styles)) - style match attribute value v results matched-string + match value v results matched-string ;; style attribute filep name address element) ;; If the group has a posting-style parameter, add it at the end with a ;; regexp matching everything, to be sure it takes precedence over all @@ -1844,7 +1844,7 @@ this is a reply." (setq matched-string header))))))) (t ;; This is a form to be evalled. - (eval match))))) + (eval match t))))) ;; We have a match, so we set the variables. (dolist (attribute style) (setq element (pop attribute) @@ -1875,7 +1875,7 @@ this is a reply." ((boundp value) (symbol-value value)))) ((listp value) - (eval value)))) + (eval value t)))) ;; Translate obsolescent value. (cond ((eq element 'signature-file) diff --git a/lisp/gnus/gnus-notifications.el b/lisp/gnus/gnus-notifications.el index adf23f36c0..a4d198b46e 100644 --- a/lisp/gnus/gnus-notifications.el +++ b/lisp/gnus/gnus-notifications.el @@ -1,4 +1,4 @@ -;; gnus-notifications.el -- Send notification on new message in Gnus +;; gnus-notifications.el -- Send notification on new message in Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/gnus-picon.el b/lisp/gnus/gnus-picon.el index a33316a526..7927b88c3d 100644 --- a/lisp/gnus/gnus-picon.el +++ b/lisp/gnus/gnus-picon.el @@ -1,4 +1,4 @@ -;;; gnus-picon.el --- displaying pretty icons in Gnus +;;; gnus-picon.el --- displaying pretty icons in Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. @@ -112,7 +112,7 @@ List of pairs (KEY . GLYPH) where KEY is either a filename or an URL.") (let* ((address (gnus-picon-split-address address)) (user (pop address)) (faddress address) - database directory result instance base) + result base) ;; database directory instance (catch 'found (dolist (database gnus-picon-databases) (dolist (directory directories) @@ -249,7 +249,7 @@ replacement is added." (gnus-article-goto-header header) (mail-header-narrow-to-field) (let ((groups (message-tokenize-header (mail-fetch-field header))) - spec file point) + spec file) ;; point (dolist (group groups) (unless (setq spec (cdr (assoc group gnus-picon-cache))) (setq spec (nreverse (split-string group "[.]"))) diff --git a/lisp/gnus/gnus-range.el b/lisp/gnus/gnus-range.el index 1e5d2a066f..6cc60cb49b 100644 --- a/lisp/gnus/gnus-range.el +++ b/lisp/gnus/gnus-range.el @@ -1,4 +1,4 @@ -;;; gnus-range.el --- range and sequence functions for Gnus +;;; gnus-range.el --- range and sequence functions for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. @@ -87,7 +87,7 @@ Both ranges must be in ascending order." (setq range2 (gnus-range-normalize range2)) (let* ((new-range (cons nil (copy-sequence range1))) (r new-range) - (safe t)) + ) ;; (safe t) (while (cdr r) (let* ((r1 (cadr r)) (r2 (car range2)) diff --git a/lisp/gnus/gnus-rfc1843.el b/lisp/gnus/gnus-rfc1843.el index dca55af460..5697c87088 100644 --- a/lisp/gnus/gnus-rfc1843.el +++ b/lisp/gnus/gnus-rfc1843.el @@ -1,4 +1,4 @@ -;;; gnus-rfc1843.el --- HZ (rfc1843) decoding interface functions for Gnus +;;; gnus-rfc1843.el --- HZ (rfc1843) decoding interface functions for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/gnus-salt.el b/lisp/gnus/gnus-salt.el index d07d36e544..e222d24b69 100644 --- a/lisp/gnus/gnus-salt.el +++ b/lisp/gnus/gnus-salt.el @@ -1,4 +1,4 @@ -;;; gnus-salt.el --- alternate summary mode interfaces for Gnus +;;; gnus-salt.el --- alternate summary mode interfaces for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1996-1999, 2001-2021 Free Software Foundation, Inc. @@ -609,7 +609,7 @@ Two predefined functions are available: beg end) (add-text-properties (setq beg (point)) - (setq end (progn (eval gnus-tree-line-format-spec) (point))) + (setq end (progn (eval gnus-tree-line-format-spec t) (point))) (list 'gnus-number gnus-tmp-number)) (when (or t (gnus-visual-p 'tree-highlight 'highlight)) (gnus-tree-highlight-node gnus-tmp-number beg end)))) diff --git a/lisp/gnus/gnus-score.el b/lisp/gnus/gnus-score.el index 254f0e548c..ade0897a16 100644 --- a/lisp/gnus/gnus-score.el +++ b/lisp/gnus/gnus-score.el @@ -1,4 +1,4 @@ -;;; gnus-score.el --- scoring code for Gnus +;;; gnus-score.el --- scoring code for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -1235,7 +1235,7 @@ If FORMAT, also format the current score file." (let ((mark (car (gnus-score-get 'mark alist))) (expunge (car (gnus-score-get 'expunge alist))) (mark-and-expunge (car (gnus-score-get 'mark-and-expunge alist))) - (score-fn (car (gnus-score-get 'score-fn alist))) + ;; (score-fn (car (gnus-score-get 'score-fn alist))) (files (gnus-score-get 'files alist)) (exclude-files (gnus-score-get 'exclude-files alist)) (orphan (car (gnus-score-get 'orphan alist))) @@ -1263,7 +1263,7 @@ If FORMAT, also format the current score file." (if adapt-file (cons adapt-file files) files))))) (when (and eval (not global)) - (eval eval)) + (eval eval t)) ;; We then expand any exclude-file directives. (setq gnus-scores-exclude-files (nconc @@ -2698,7 +2698,7 @@ the score file and its full name, including the directory.") ;;; Finding score files. -(defun gnus-score-score-files (group) +(defun gnus-score-score-files (_group) "Return a list of all possible score files." ;; Search and set any global score files. (when gnus-global-score-files diff --git a/lisp/gnus/gnus-sieve.el b/lisp/gnus/gnus-sieve.el index 70b1345ca2..5dcd079fb4 100644 --- a/lisp/gnus/gnus-sieve.el +++ b/lisp/gnus/gnus-sieve.el @@ -1,4 +1,4 @@ -;;; gnus-sieve.el --- Utilities to manage sieve scripts for Gnus +;;; gnus-sieve.el --- Utilities to manage sieve scripts for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/gnus-spec.el b/lisp/gnus/gnus-spec.el index a50d9f3a5f..cb60108ea9 100644 --- a/lisp/gnus/gnus-spec.el +++ b/lisp/gnus/gnus-spec.el @@ -1,4 +1,4 @@ -;;; gnus-spec.el --- format spec functions for Gnus +;;; gnus-spec.el --- format spec functions for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. @@ -628,8 +628,8 @@ or to characters when given a pad value." If PROPS, insert the result." (let ((form (gnus-parse-format format alist props))) (if props - (add-text-properties (point) (progn (eval form) (point)) props) - (eval form)))) + (add-text-properties (point) (progn (eval form t) (point)) props) + (eval form t)))) (defun gnus-set-format (type &optional insertable) (set (intern (format "gnus-%s-line-format-spec" type)) diff --git a/lisp/gnus/gnus-srvr.el b/lisp/gnus/gnus-srvr.el index deeb28885b..54b5a7d5fa 100644 --- a/lisp/gnus/gnus-srvr.el +++ b/lisp/gnus/gnus-srvr.el @@ -1,4 +1,4 @@ -;;; gnus-srvr.el --- virtual server support for Gnus +;;; gnus-srvr.el --- virtual server support for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -297,7 +297,7 @@ The following commands are available: (point) (prog1 (1+ (point)) ;; Insert the text. - (eval gnus-server-line-format-spec)) + (eval gnus-server-line-format-spec t)) (list 'gnus-server (intern gnus-tmp-name) 'gnus-named-server (intern (gnus-method-to-server method t)))))) @@ -626,7 +626,7 @@ The following commands are available: (let ((info (gnus-server-to-method server))) (gnus-edit-form info "Showing the server." - (lambda (form) + (lambda (_form) (gnus-server-position-point)) 'edit-server))) diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index 05e49be093..39110338c3 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -3186,7 +3186,7 @@ The following commands are available: ;; Copy the global value of the variable. (symbol-value (car local)) ;; Use the value from the list. - (eval (cdr local))))) + (eval (cdr local) t)))) (set (make-local-variable (car local)) global)) ;; Simple nil-valued local variable. (set (make-local-variable local) nil)))) @@ -3850,7 +3850,7 @@ buffer that was in action when the last article was fetched." (condition-case () (put-text-property (point) - (progn (eval gnus-summary-line-format-spec) (point)) + (progn (eval gnus-summary-line-format-spec t) (point)) 'gnus-number gnus-tmp-number) (error (gnus-message 5 "Error updating the summary line"))) (when (gnus-visual-p 'summary-highlight 'highlight) @@ -3971,14 +3971,14 @@ Input should look like this: \"Sun, 14 Oct 2001 13:34:39 +0200\"." (my-format "%b %d '%y")) (let* ((difference (time-subtract now messy-date)) (templist gnus-user-date-format-alist) - (top (eval (caar templist)))) + (top (eval (caar templist) t))) (while (if (numberp top) (time-less-p top difference) (not top)) (progn (setq templist (cdr templist)) - (setq top (eval (caar templist))))) + (setq top (eval (caar templist) t)))) (if (stringp (cdr (car templist))) (setq my-format (cdr (car templist))))) - (format-time-string (eval my-format) messy-date)) + (format-time-string (eval my-format t) messy-date)) (error " ? "))) (defun gnus-summary-set-local-parameters (group) @@ -3997,8 +3997,8 @@ Input should look like this: \"Sun, 14 Oct 2001 13:34:39 +0200\"." ;; buffer-local, whereas just parameters like `gcc-self', ;; `timestamp', etc. should not be bound as variables. (if (boundp (car elem)) - (set (make-local-variable (car elem)) (eval (nth 1 elem))) - (eval (nth 1 elem)))))))) + (set (make-local-variable (car elem)) (eval (nth 1 elem) t)) + (eval (nth 1 elem) t))))))) (defun gnus-summary-read-group (group &optional show-all no-article kill-buffer no-display backward @@ -5557,7 +5557,7 @@ or a straight list of headers." (setq gnus-tmp-thread thread) (put-text-property (point) - (progn (eval gnus-summary-line-format-spec) (point)) + (progn (eval gnus-summary-line-format-spec t) (point)) 'gnus-number number) (when gnus-visual-p (forward-line -1) @@ -6265,7 +6265,7 @@ If WHERE is `summary', the summary mode line format will be used." "")) bufname-length max-len gnus-tmp-header) ;; passed as argument to any user-format-funcs - (setq mode-string (eval mformat)) + (setq mode-string (eval mformat t)) (setq bufname-length (if (string-match "%b" mode-string) (- (length (buffer-name @@ -7863,7 +7863,7 @@ If BACKWARD, the previous article is selected instead of the next." (switch-to-buffer gnus-group-buffer) (when group (gnus-group-jump-to-group group)) - (eval (cadr (assq key keystrokes))) + (eval (cadr (assq key keystrokes)) t) (setq group (gnus-group-group-name)) (switch-to-buffer obuf)) (setq ended nil)) @@ -10617,6 +10617,8 @@ confirmation before the articles are deleted." (gnus-set-mode-line 'summary) not-deleted)) +(defvar message-options-set-recipient) + (defun gnus-summary-edit-article (&optional arg) "Edit the current article. This will have permanent effect only in mail groups. @@ -12366,7 +12368,7 @@ save those articles instead." ;; Form. (save-restriction (widen) - (setq result (eval match))))) + (setq result (eval match t))))) (setq split-name (cdr method)) (cond ((stringp result) (push (expand-file-name @@ -12956,7 +12958,7 @@ treated as multipart/mixed." (nomove "" nil nil ,keystroke))) (let ((func (gnus-summary-make-marking-command-1 mark (car lway) lway name))) - (setq func (eval func)) + (setq func (eval func t)) (define-key map (nth 4 lway) func))))) (defun gnus-summary-make-marking-command-1 (mark way lway name) diff --git a/lisp/gnus/gnus-topic.el b/lisp/gnus/gnus-topic.el index c491848527..bbcccfee2f 100644 --- a/lisp/gnus/gnus-topic.el +++ b/lisp/gnus/gnus-topic.el @@ -1,4 +1,4 @@ -;;; gnus-topic.el --- a folding minor mode for Gnus group buffers +;;; gnus-topic.el --- a folding minor mode for Gnus group buffers -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -640,7 +640,14 @@ articles in the topic and its subtopics." (add-text-properties (point) (prog1 (1+ (point)) - (eval gnus-topic-line-format-spec)) + (eval gnus-topic-line-format-spec + `((indentation . ,indentation) + (visible . ,visible) + (name . ,name) + (level . ,level) + (number-of-groups . ,number-of-groups) + (total-number-of-articles . ,total-number-of-articles) + (entries . ,entries)))) (list 'gnus-topic name 'gnus-topic-level level 'gnus-topic-unread unread diff --git a/lisp/gnus/gnus-undo.el b/lisp/gnus/gnus-undo.el index 5d2f85af36..64ed2bbad6 100644 --- a/lisp/gnus/gnus-undo.el +++ b/lisp/gnus/gnus-undo.el @@ -1,4 +1,4 @@ -;;; gnus-undo.el --- minor mode for undoing in Gnus +;;; gnus-undo.el --- minor mode for undoing in Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. @@ -153,10 +153,10 @@ ;; We are not at a boundary... (setq gnus-undo-boundary-inhibit t))) -(defun gnus-undo (n) +(defun gnus-undo (_n) "Undo some previous changes in Gnus buffers. -Repeat this command to undo more changes. -A numeric argument serves as a repeat count." +Repeat this command to undo more changes." + ;; FIXME: A numeric argument should serve as a repeat count. (interactive "p") (unless gnus-undo-mode (error "Undoing is not enabled in this buffer")) diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el index 408293f1a1..f8d4325386 100644 --- a/lisp/gnus/gnus-util.el +++ b/lisp/gnus/gnus-util.el @@ -1,4 +1,4 @@ -;;; gnus-util.el --- utility functions for Gnus +;;; gnus-util.el --- utility functions for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. @@ -681,6 +681,8 @@ yield \"nnimap:yxa\"." (define-key (symbol-value (intern (format "gnus-%s-mode-map" type))) [menu-bar edit] 'undefined)) +(defvar print-string-length) + (defmacro gnus-bind-print-variables (&rest forms) "Bind print-* variables and evaluate FORMS. This macro is used with `prin1', `pp', etc. in order to ensure @@ -1241,7 +1243,7 @@ sure of changing the value of `foo'." (setq gnus-info-buffer (current-buffer)) (gnus-configure-windows 'info))) -(defun gnus-not-ignore (&rest args) +(defun gnus-not-ignore (&rest _args) t) (defvar gnus-directory-sep-char-regexp "/" @@ -1381,6 +1383,7 @@ SPEC is a predicate specifier that contains stuff like `or', `and', (declare-function iswitchb-minibuffer-setup "iswitchb") (defvar iswitchb-temp-buflist) (defvar iswitchb-mode) +(defvar iswitchb-make-buflist-hook) (defun gnus-iswitchb-completing-read (prompt collection &optional require-match initial-input history def) @@ -1500,7 +1503,7 @@ Return nil otherwise." (defvar tool-bar-mode) -(defun gnus-tool-bar-update (&rest ignore) +(defun gnus-tool-bar-update (&rest _ignore) "Update the tool bar." (when (and (boundp 'tool-bar-mode) tool-bar-mode) @@ -1526,7 +1529,7 @@ sequence, this is like `mapcar'. With several, it is like the Common Lisp (if seqs2_n (let* ((seqs (cons seq1 seqs2_n)) (cnt 0) - (heads (mapcar (lambda (seq) + (heads (mapcar (lambda (_seq) (make-symbol (concat "head" (int-to-string (setq cnt (1+ cnt)))))) @@ -1560,7 +1563,7 @@ sequence, this is like `mapcar'. With several, it is like the Common Lisp ((memq 'type lst) (symbol-name system-type)) (t nil))) - codename) + ) ;; codename (cond ((not (memq 'emacs lst)) nil) @@ -1576,9 +1579,9 @@ sequence, this is like `mapcar'. With several, it is like the Common Lisp empty directories from OLD-PATH." (when (file-exists-p old-path) (let* ((old-dir (file-name-directory old-path)) - (old-name (file-name-nondirectory old-path)) + ;; (old-name (file-name-nondirectory old-path)) (new-dir (file-name-directory new-path)) - (new-name (file-name-nondirectory new-path)) + ;; (new-name (file-name-nondirectory new-path)) temp) (gnus-make-directory new-dir) (rename-file old-path new-path t) diff --git a/lisp/gnus/gnus-uu.el b/lisp/gnus/gnus-uu.el index e4aaf92c89..32a8785154 100644 --- a/lisp/gnus/gnus-uu.el +++ b/lisp/gnus/gnus-uu.el @@ -1,4 +1,4 @@ -;;; gnus-uu.el --- extract (uu)encoded files in Gnus +;;; gnus-uu.el --- extract (uu)encoded files in Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1985-1987, 1993-1998, 2000-2021 Free Software ;; Foundation, Inc. @@ -977,7 +977,7 @@ When called interactively, prompt for REGEXP." (defvar gnus-uu-binhex-end-line ":$") -(defun gnus-uu-binhex-article (buffer in-state) +(defun gnus-uu-binhex-article (buffer _in-state) (let (state start-char) (with-current-buffer buffer (widen) @@ -1014,11 +1014,11 @@ When called interactively, prompt for REGEXP." ;; yEnc -(defun gnus-uu-yenc-article (buffer in-state) +(defun gnus-uu-yenc-article (_buffer _in-state) (with-current-buffer gnus-original-article-buffer (widen) (let ((file-name (yenc-extract-filename)) - state start-char) + state) ;; start-char (when (not file-name) (setq state (list 'wrong-type))) @@ -1046,7 +1046,7 @@ When called interactively, prompt for REGEXP." ;; PostScript -(defun gnus-uu-decode-postscript-article (process-buffer in-state) +(defun gnus-uu-decode-postscript-article (process-buffer _in-state) (let ((state (list 'ok)) start-char end-char file-name) (with-current-buffer process-buffer @@ -1278,13 +1278,15 @@ When called interactively, prompt for REGEXP." (when dont-unmark-last-article (setq gnus-uu-has-been-grabbed (list art)))))) +(defvar gnus-asynchronous) + ;; This function takes a list of articles and a function to apply to ;; each article grabbed. ;; ;; This function returns a list of files decoded if the grabbing and ;; the process-function has been successful and nil otherwise. (defun gnus-uu-grab-articles (articles process-function - &optional sloppy limit no-errors) + &optional sloppy limit _no-errors) (require 'gnus-async) (let ((state 'first) (gnus-asynchronous nil) @@ -1452,10 +1454,10 @@ When called interactively, prompt for REGEXP." (setq subject (substring subject (match-end 0))))) (or part ""))) -(defun gnus-uu-uudecode-sentinel (process event) +(defun gnus-uu-uudecode-sentinel (process _event) (delete-process (get-process process))) -(defun gnus-uu-uustrip-article (process-buffer in-state) +(defun gnus-uu-uustrip-article (process-buffer _in-state) ;; Uudecodes a file asynchronously. (with-current-buffer process-buffer (let ((state (list 'wrong-type)) @@ -1576,7 +1578,7 @@ Gnus might fail to display all of it.") ;; This function is used by `gnus-uu-grab-articles' to treat ;; a shared article. -(defun gnus-uu-unshar-article (process-buffer in-state) +(defun gnus-uu-unshar-article (process-buffer _in-state) (let ((state (list 'ok)) start-char) (with-current-buffer process-buffer diff --git a/lisp/gnus/gnus-vm.el b/lisp/gnus/gnus-vm.el index 533b1e2a58..b7e6b2a889 100644 --- a/lisp/gnus/gnus-vm.el +++ b/lisp/gnus/gnus-vm.el @@ -1,4 +1,4 @@ -;;; gnus-vm.el --- vm interface for Gnus +;;; gnus-vm.el --- vm interface for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1994-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/gnus-win.el b/lisp/gnus/gnus-win.el index d8b037ebe4..8ac4e39fa5 100644 --- a/lisp/gnus/gnus-win.el +++ b/lisp/gnus/gnus-win.el @@ -1,4 +1,4 @@ -;;; gnus-win.el --- window configuration functions for Gnus +;;; gnus-win.el --- window configuration functions for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. @@ -246,7 +246,7 @@ See the Gnus manual for an explanation of the syntax used.") ;; return a new SPLIT. (while (and (not (assq (car split) gnus-window-to-buffer)) (symbolp (car split)) (fboundp (car split))) - (setq split (eval split))) + (setq split (eval split t))) (let* ((type (car split)) (subs (cddr split)) (len (if (eq type 'horizontal) (window-width) (window-height))) @@ -323,7 +323,7 @@ See the Gnus manual for an explanation of the syntax used.") (setq sub (append (pop subs) nil)) (while (and (not (assq (car sub) gnus-window-to-buffer)) (symbolp (car sub)) (fboundp (car sub))) - (setq sub (eval sub))) + (setq sub (eval sub t))) (when sub (push sub comp-subs) (setq size (cadar comp-subs)) @@ -471,7 +471,7 @@ should have point." ;; return a new SPLIT. (while (and (not (assq (car split) gnus-window-to-buffer)) (symbolp (car split)) (fboundp (car split))) - (setq split (eval split))) + (setq split (eval split t))) (setq type (elt split 0)) (cond diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index 1eff9a8223..84e53da297 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el @@ -3724,7 +3724,7 @@ just the host name." depth (+ depth 1))) depth)))) ;; Separate foreign select method from group name and collapse. - ;; If method contains a server, collapse to non-domain server name, + ;; If method contains a server, collapse to non-domain server name, ;; otherwise collapse to select method. (let* ((colon (string-match ":" group)) (server (and colon (substring group 0 colon))) diff --git a/lisp/gnus/gssapi.el b/lisp/gnus/gssapi.el index 20562fb9ad..6ff2a4e285 100644 --- a/lisp/gnus/gssapi.el +++ b/lisp/gnus/gssapi.el @@ -1,4 +1,4 @@ -;;; gssapi.el --- GSSAPI/Kerberos 5 interface for Emacs +;;; gssapi.el --- GSSAPI/Kerberos 5 interface for Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 2011-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/legacy-gnus-agent.el b/lisp/gnus/legacy-gnus-agent.el index b47e69ffa4..091e3899c2 100644 --- a/lisp/gnus/legacy-gnus-agent.el +++ b/lisp/gnus/legacy-gnus-agent.el @@ -1,4 +1,4 @@ -;;; gnus-agent.el --- Legacy unplugged support for Gnus +;;; gnus-agent.el --- Legacy unplugged support for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 2004-2021 Free Software Foundation, Inc. @@ -210,7 +210,7 @@ converted to the compressed format." ;; Therefore, hide the default prompt. (gnus-convert-mark-converter-prompt 'gnus-agent-unlist-expire-days t) -(defun gnus-agent-unhook-expire-days (converting-to) +(defun gnus-agent-unhook-expire-days (_converting-to) "Remove every lambda from `gnus-group-prepare-hook' that mention the symbol `gnus-agent-do-once' in their definition. This should NOT be necessary as gnus-agent.el no longer adds them. However, it is diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el index 4f02d86f44..af0a198376 100644 --- a/lisp/gnus/mail-source.el +++ b/lisp/gnus/mail-source.el @@ -1,4 +1,4 @@ -;;; mail-source.el --- functions for fetching mail +;;; mail-source.el --- functions for fetching mail -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. @@ -403,16 +403,19 @@ of the second `let' form. The variables bound and their default values are described by the `mail-source-keyword-map' variable." (declare (indent 1) (debug (sexp body))) - `(let* ,(mail-source-bind-1 (car type-source)) - (mail-source-set-1 ,(cadr type-source)) - ,@body)) - + ;; FIXME: Use lexical vars, i.e. don't initialize the vars inside + ;; `mail-source-set-1' via `set'. + (let ((bindings (mail-source-bind-1 (car type-source)))) + `(with-suppressed-warnings ((lexical ,@(mapcar #'car bindings))) + (dlet ,bindings + (mail-source-set-1 ,(cadr type-source)) + ,@body)))) (defun mail-source-set-1 (source) (let* ((type (pop source)) (defaults (cdr (assq type mail-source-keyword-map))) (search '(:max 1)) - found default value keyword auth-info user-auth pass-auth) + found default value keyword user-auth pass-auth) ;; auth-info ;; append to the search the useful info from the source and the defaults: ;; user, host, and port @@ -494,9 +497,13 @@ the `mail-source-keyword-map' variable." "Return a `let' form that binds all common variables. See `mail-source-bind'." (declare (indent 1) (debug (sexp body))) - `(let ,(mail-source-bind-common-1) - (mail-source-set-common-1 ,source) - ,@body)) + ;; FIXME: AFAICT this is a Rube Goldberg'esque way to bind and initialize the + ;; `plugged` variable. + (let ((bindings (mail-source-bind-common-1))) + `(with-suppressed-warnings ((lexical ,@(mapcar #'car bindings))) + (dlet ,bindings + (mail-source-set-common-1 ,source) + ,@body)))) (defun mail-source-value (value) "Return the value of VALUE." @@ -506,7 +513,7 @@ See `mail-source-bind'." value) ;; Function ((and (listp value) (symbolp (car value)) (fboundp (car value))) - (eval value)) + (eval value t)) ;; Just return the value. (t value))) @@ -721,12 +728,13 @@ Deleting old (> %s day(s)) incoming mail file `%s'." diff bfile) (declare-function gnus-get-buffer-create "gnus" (name)) (defun mail-source-call-script (script) (require 'gnus) - (let ((background nil) + (let (;; (background nil) (stderr (gnus-get-buffer-create " *mail-source-stderr*")) result) (when (string-match "& *$" script) (setq script (substring script 0 (match-beginning 0)) - background 0)) + ;; background 0 + )) (setq result (call-process shell-file-name nil stderr nil shell-command-switch script)) @@ -810,14 +818,14 @@ Deleting old (> %s day(s)) incoming mail file `%s'." diff bfile) ;; The default is to use pop3.el. (t (require 'pop3) - (let ((pop3-password password) - (pop3-maildrop user) - (pop3-mailhost server) - (pop3-port port) - (pop3-authentication-scheme - (if (eq authentication 'apop) 'apop 'pass)) - (pop3-stream-type stream) - (pop3-leave-mail-on-server leave)) + (dlet ((pop3-password password) + (pop3-maildrop user) + (pop3-mailhost server) + (pop3-port port) + (pop3-authentication-scheme + (if (eq authentication 'apop) 'apop 'pass)) + (pop3-stream-type stream) + (pop3-leave-mail-on-server leave)) (if (or debug-on-quit debug-on-error) (save-excursion (pop3-movemail mail-source-crash-box)) (condition-case err @@ -877,12 +885,12 @@ Deleting old (> %s day(s)) incoming mail file `%s'." diff bfile) ;; The default is to use pop3.el. (t (require 'pop3) - (let ((pop3-password password) - (pop3-maildrop user) - (pop3-mailhost server) - (pop3-port port) - (pop3-authentication-scheme - (if (eq authentication 'apop) 'apop 'pass))) + (dlet ((pop3-password password) + (pop3-maildrop user) + (pop3-mailhost server) + (pop3-port port) + (pop3-authentication-scheme + (if (eq authentication 'apop) 'apop 'pass))) (if (or debug-on-quit debug-on-error) (save-excursion (pop3-get-message-count)) (condition-case err diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 3f671193a2..d2a0092fde 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -3675,7 +3675,7 @@ are null." ((functionp message-signature) (funcall message-signature)) ((listp message-signature) - (eval message-signature)) + (eval message-signature t)) (t message-signature))) signature-file) (setq signature @@ -3992,11 +3992,12 @@ Just \\[universal-argument] as argument means don't indent, insert no prefix, and don't delete any headers." (interactive "P") ;; eval the let forms contained in message-cite-style - (eval - `(let ,(if (symbolp message-cite-style) - (symbol-value message-cite-style) - message-cite-style) - (message--yank-original-internal ',arg)))) + (let ((bindings (if (symbolp message-cite-style) + (symbol-value message-cite-style) + message-cite-style))) + (cl-progv (mapcar #'car bindings) + (mapcar (lambda (binding) (eval (cadr binding) t)) bindings) + (message--yank-original-internal arg)))) (defun message-yank-buffer (buffer) "Insert BUFFER into the current buffer and quote it." @@ -4627,7 +4628,7 @@ Valid types are `send', `return', `exit', `kill' and `postpone'." (funcall action)) ;; Something to be evalled. (t - (eval action)))))) + (eval action t)))))) (defun message-send-mail-partially () "Send mail as message/partial." @@ -4943,7 +4944,7 @@ that instead." ;; Insert an extra newline if we need it to work around ;; Sun's bug that swallows newlines. (goto-char (1+ delimline)) - (when (eval message-mailer-swallows-blank-line) + (when (eval message-mailer-swallows-blank-line t) (newline)) (when message-interactive (with-current-buffer errbuf diff --git a/lisp/gnus/mm-archive.el b/lisp/gnus/mm-archive.el index 6173d86327..d550045e0a 100644 --- a/lisp/gnus/mm-archive.el +++ b/lisp/gnus/mm-archive.el @@ -1,4 +1,4 @@ -;;; mm-archive.el --- Functions for parsing archive files as MIME +;;; mm-archive.el --- Functions for parsing archive files as MIME -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/mm-bodies.el b/lisp/gnus/mm-bodies.el index f35ba3a0b9..d6b71f15e5 100644 --- a/lisp/gnus/mm-bodies.el +++ b/lisp/gnus/mm-bodies.el @@ -1,4 +1,4 @@ -;;; mm-bodies.el --- Functions for decoding MIME things +;;; mm-bodies.el --- Functions for decoding MIME things -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/mm-encode.el b/lisp/gnus/mm-encode.el index 31d613146b..84a3b0a8d1 100644 --- a/lisp/gnus/mm-encode.el +++ b/lisp/gnus/mm-encode.el @@ -1,4 +1,4 @@ -;;; mm-encode.el --- Functions for encoding MIME things +;;; mm-encode.el --- Functions for encoding MIME things -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/mm-partial.el b/lisp/gnus/mm-partial.el index 8d4913e6fb..8f5d45d67d 100644 --- a/lisp/gnus/mm-partial.el +++ b/lisp/gnus/mm-partial.el @@ -1,4 +1,4 @@ -;;; mm-partial.el --- showing message/partial +;;; mm-partial.el --- showing message/partial -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. @@ -50,6 +50,8 @@ (push nhandles phandles)))))))) phandles)) +(defvar gnus-displaying-mime) + ;;;###autoload (defun mm-inline-partial (handle &optional no-display) "Show the partial part of HANDLE. @@ -60,7 +62,7 @@ If NO-DISPLAY is nil, display it. Otherwise, do nothing after replacing." phandles (b (point)) (n 1) total phandle nn ntotal - gnus-displaying-mime handles buffer) + gnus-displaying-mime handles) ;; buffer (unless (mm-handle-cache handle) (unless id (error "Can not find message/partial id")) diff --git a/lisp/gnus/mm-url.el b/lisp/gnus/mm-url.el index 01d25ac61e..3d58738d63 100644 --- a/lisp/gnus/mm-url.el +++ b/lisp/gnus/mm-url.el @@ -1,4 +1,4 @@ -;;; mm-url.el --- a wrapper of url functions/commands for Gnus +;;; mm-url.el --- a wrapper of url functions/commands for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/mm-util.el b/lisp/gnus/mm-util.el index be279b6cf1..92e04f9d2e 100644 --- a/lisp/gnus/mm-util.el +++ b/lisp/gnus/mm-util.el @@ -160,7 +160,7 @@ is not available." form (prog2 ;; Avoid errors... - (condition-case nil (eval form) (error nil)) + (condition-case nil (eval form t) (error nil)) ;; (message "Failed to eval `%s'" form)) (mm-coding-system-p cs) (message "Added charset `%s' via `mm-charset-eval-alist'" cs)) diff --git a/lisp/gnus/mm-view.el b/lisp/gnus/mm-view.el index 266f471a3f..f4c1cf9a6c 100644 --- a/lisp/gnus/mm-view.el +++ b/lisp/gnus/mm-view.el @@ -1,4 +1,4 @@ -;;; mm-view.el --- functions for viewing MIME objects +;;; mm-view.el --- functions for viewing MIME objects -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2021 Free Software Foundation, Inc. @@ -137,7 +137,7 @@ This is only used if `mm-inline-large-images' is set to (equal "multipart" (mm-handle-media-supertype elem))) (mm-w3m-cid-retrieve-1 url elem))))) -(defun mm-w3m-cid-retrieve (url &rest args) +(defun mm-w3m-cid-retrieve (url &rest _args) "Insert a content pointed by URL if it has the cid: scheme." (when (string-match "\\`cid:" url) (or (catch 'found-handle @@ -149,6 +149,9 @@ This is only used if `mm-inline-large-images' is set to nil (message "Failed to find \"Content-ID: %s\"" url))))) +(defvar w3m-force-redisplay) +(defvar w3m-safe-url-regexp) + (defun mm-inline-text-html-render-with-w3m (handle) "Render a text/html part using emacs-w3m." (mm-setup-w3m) @@ -396,7 +399,7 @@ This is only used if `mm-inline-large-images' is set to (delete-region ,(copy-marker b t) ,(point-marker))))))) -(defun mm-inline-audio (handle) +(defun mm-inline-audio (_handle) (message "Not implemented")) (defun mm-view-message () @@ -413,6 +416,10 @@ This is only used if `mm-inline-large-images' is set to (fundamental-mode) (goto-char (point-min))) +(defvar gnus-original-article-buffer) +(defvar gnus-article-prepare-hook) +(defvar gnus-displaying-mime) + (defun mm-inline-message (handle) (let ((b (point)) (bolp (bolp)) diff --git a/lisp/gnus/mml-sec.el b/lisp/gnus/mml-sec.el index a050fe04e1..8d01d15ca0 100644 --- a/lisp/gnus/mml-sec.el +++ b/lisp/gnus/mml-sec.el @@ -1,4 +1,4 @@ -;;; mml-sec.el --- A package with security functions for MML documents +;;; mml-sec.el --- A package with security functions for MML documents -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. @@ -622,7 +622,7 @@ Passphrase caching in Emacs is NOT recommended. Use gpg-agent instead." mml-smime-passphrase-cache-expiry) mml-secure-passphrase-cache-expiry)))) -(defun mml-secure-passphrase-callback (context key-id standard) +(defun mml-secure-passphrase-callback (context key-id _standard) "Ask for passphrase in CONTEXT for KEY-ID for STANDARD. The passphrase is read and cached." ;; Based on mml2015-epg-passphrase-callback. @@ -906,7 +906,7 @@ If no one is selected, symmetric encryption will be performed. " (error "No recipient specified"))) recipients)) -(defun mml-secure-epg-encrypt (protocol cont &optional sign) +(defun mml-secure-epg-encrypt (protocol _cont &optional sign) ;; Based on code appearing inside mml2015-epg-encrypt. (let* ((context (epg-make-context protocol)) (config (epg-find-configuration 'OpenPGP)) diff --git a/lisp/gnus/mml-smime.el b/lisp/gnus/mml-smime.el index eabb56b303..5c133e680a 100644 --- a/lisp/gnus/mml-smime.el +++ b/lisp/gnus/mml-smime.el @@ -1,4 +1,4 @@ -;;; mml-smime.el --- S/MIME support for MML +;;; mml-smime.el --- S/MIME support for MML -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. @@ -129,7 +129,7 @@ Whether the passphrase is cached at all is controlled by (if func (funcall func handle ctl)))) -(defun mml-smime-openssl-sign (cont) +(defun mml-smime-openssl-sign (_cont) (when (null smime-keys) (customize-variable 'smime-keys) (error "No S/MIME keys configured, use customize to add your key")) @@ -309,7 +309,7 @@ Whether the passphrase is cached at all is controlled by (buffer-string) "\n"))))) handle) -(defun mml-smime-openssl-verify-test (handle ctl) +(defun mml-smime-openssl-verify-test (_handle _ctl) smime-openssl-program) (defvar epg-user-id-alist) @@ -370,7 +370,7 @@ Content-Disposition: attachment; filename=smime.p7s (defun mml-smime-epg-encrypt (cont) (let* ((inhibit-redisplay t) ;FIXME: Why? - (boundary (mml-compute-boundary cont)) + ;; (boundary (mml-compute-boundary cont)) (cipher (mml-secure-epg-encrypt 'CMS cont))) (delete-region (point-min) (point-max)) (goto-char (point-min)) @@ -388,7 +388,7 @@ Content-Disposition: attachment; filename=smime.p7m (defun mml-smime-epg-verify (handle ctl) (catch 'error (let ((inhibit-redisplay t) - context plain signature-file part signature) + context part signature) ;; plain signature-file (when (or (null (setq part (mm-find-raw-part-by-type ctl (or (mm-handle-multipart-ctl-parameter ctl 'protocol) @@ -407,7 +407,8 @@ Content-Disposition: attachment; filename=smime.p7m (setq part (replace-regexp-in-string "\n" "\r\n" part) context (epg-make-context 'CMS)) (condition-case error - (setq plain (epg-verify-string context (mm-get-part signature) part)) + ;; (setq plain + (epg-verify-string context (mm-get-part signature) part) ;;) (error (mm-sec-error 'gnus-info "Failed") (mm-sec-status 'gnus-details (if (eq (car error) 'quit) @@ -419,7 +420,7 @@ Content-Disposition: attachment; filename=smime.p7m (epg-verify-result-to-string (epg-context-result-for context 'verify))) handle))) -(defun mml-smime-epg-verify-test (handle ctl) +(defun mml-smime-epg-verify-test (_handle _ctl) t) (provide 'mml-smime) diff --git a/lisp/gnus/mml.el b/lisp/gnus/mml.el index 54f8715baf..f77e5c6434 100644 --- a/lisp/gnus/mml.el +++ b/lisp/gnus/mml.el @@ -1,4 +1,4 @@ -;;; mml.el --- A package for parsing and validating MML documents +;;; mml.el --- A package for parsing and validating MML documents -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2021 Free Software Foundation, Inc. @@ -259,18 +259,19 @@ part. This is for the internal use, you should never modify the value.") (list "sign" method "encrypt" method)) (t (error "Unknown secure mode %s" mode)))) - (eval `(mml-insert-tag ,secure-mode - ,@tags - ,(if keyfile "keyfile") - ,keyfile - ,@(apply #'append - (mapcar (lambda (certfile) - (list "certfile" certfile)) - certfiles)) - ,(if recipients "recipients") - ,recipients - ,(if sender "sender") - ,sender)) + (apply #'mml-insert-tag + secure-mode + `(,@tags + ,(if keyfile "keyfile") + ,keyfile + ,@(apply #'append + (mapcar (lambda (certfile) + (list "certfile" certfile)) + certfiles)) + ,(if recipients "recipients") + ,recipients + ,(if sender "sender") + ,sender)) ;; restart the parse (goto-char location))) ((looking-at "<#multipart") @@ -1458,7 +1459,7 @@ will be computed and used." (file-name-nondirectory file))) (goto-char head)))) -(defun mml-dnd-attach-file (uri action) +(defun mml-dnd-attach-file (uri _action) "Attach a drag and drop file. Ask for type, description or disposition according to @@ -1589,6 +1590,16 @@ Should be adopted if code in `message-send-mail' is changed." (declare-function message-generate-headers "message" (headers)) (declare-function message-sort-headers "message" ()) +(defvar gnus-newsgroup-name) +(defvar gnus-displaying-mime) +(defvar gnus-newsgroup-name) +(defvar gnus-article-prepare-hook) +(defvar gnus-newsgroup-charset) +(defvar gnus-original-article-buffer) +(defvar gnus-message-buffer) +(defvar message-this-is-news) +(defvar message-this-is-mail) + (defun mml-preview (&optional raw) "Display current buffer with Gnus, in a new buffer. If RAW, display a raw encoded MIME message. @@ -1708,7 +1719,7 @@ or the `pop-to-buffer' function." cont) (let ((alist mml-tweak-sexp-alist)) (while alist - (if (eval (caar alist)) + (if (eval (caar alist) t) (funcall (cdar alist) cont)) (setq alist (cdr alist))))) cont) diff --git a/lisp/gnus/mml1991.el b/lisp/gnus/mml1991.el index a87e642c07..05f44a1cbd 100644 --- a/lisp/gnus/mml1991.el +++ b/lisp/gnus/mml1991.el @@ -1,4 +1,4 @@ -;;; mml1991.el --- Old PGP message format (RFC 1991) support for MML +;;; mml1991.el --- Old PGP message format (RFC 1991) support for MML -*- lexical-binding: t; -*- ;; Copyright (C) 1998-2021 Free Software Foundation, Inc. @@ -82,7 +82,7 @@ Whether the passphrase is cached at all is controlled by (defvar mml1991-decrypt-function 'mailcrypt-decrypt) (defvar mml1991-verify-function 'mailcrypt-verify) -(defun mml1991-mailcrypt-sign (cont) +(defun mml1991-mailcrypt-sign (_cont) (let ((text (current-buffer)) headers signature (result-buffer (get-buffer-create "*GPG Result*"))) @@ -118,7 +118,7 @@ Whether the passphrase is cached at all is controlled by (declare-function mc-encrypt-generic "ext:mc-toplev" (&optional recipients scheme start end from sign)) -(defun mml1991-mailcrypt-encrypt (cont &optional sign) +(defun mml1991-mailcrypt-encrypt (_cont &optional sign) (let ((text (current-buffer)) (mc-pgp-always-sign (or mc-pgp-always-sign @@ -171,8 +171,9 @@ Whether the passphrase is cached at all is controlled by (defvar pgg-default-user-id) (defvar pgg-errors-buffer) (defvar pgg-output-buffer) +(defvar pgg-text-mode) -(defun mml1991-pgg-sign (cont) +(defun mml1991-pgg-sign (_cont) (let ((pgg-text-mode t) (pgg-default-user-id (or (message-options-get 'mml-sender) pgg-default-user-id)) @@ -209,7 +210,7 @@ Whether the passphrase is cached at all is controlled by (buffer-string))) t)) -(defun mml1991-pgg-encrypt (cont &optional sign) +(defun mml1991-pgg-encrypt (_cont &optional sign) (goto-char (point-min)) (when (re-search-forward "^$" nil t) (let ((cte (save-restriction @@ -257,7 +258,7 @@ Whether the passphrase is cached at all is controlled by (autoload 'epg-configuration "epg-config") (autoload 'epg-expand-group "epg-config") -(defun mml1991-epg-sign (cont) +(defun mml1991-epg-sign (_cont) (let ((inhibit-redisplay t) headers cte) ;; Don't sign headers. diff --git a/lisp/gnus/mml2015.el b/lisp/gnus/mml2015.el index 53454bf16d..1af7d10d05 100644 --- a/lisp/gnus/mml2015.el +++ b/lisp/gnus/mml2015.el @@ -1,4 +1,4 @@ -;;; mml2015.el --- MIME Security with Pretty Good Privacy (PGP) +;;; mml2015.el --- MIME Security with Pretty Good Privacy (PGP) -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. @@ -185,7 +185,7 @@ If set, it overrides the setting of `mml2015-sign-with-sender'." (cadr err) (format "%S" (cdr err)))) -(defun mml2015-mailcrypt-decrypt (handle ctl) +(defun mml2015-mailcrypt-decrypt (handle _ctl) (catch 'error (let (child handles result) (unless (setq child (mm-find-part-by-type @@ -479,6 +479,7 @@ If set, it overrides the setting of `mml2015-sign-with-sender'." (defvar pgg-default-user-id) (defvar pgg-errors-buffer) (defvar pgg-output-buffer) +(defvar pgg-text-mode) (autoload 'pgg-decrypt-region "pgg") (autoload 'pgg-verify-region "pgg") @@ -486,10 +487,10 @@ If set, it overrides the setting of `mml2015-sign-with-sender'." (autoload 'pgg-encrypt-region "pgg") (autoload 'pgg-parse-armor "pgg-parse") -(defun mml2015-pgg-decrypt (handle ctl) +(defun mml2015-pgg-decrypt (handle _ctl) (catch 'error (let ((pgg-errors-buffer mml2015-result-buffer) - child handles result decrypt-status) + child handles decrypt-status) ;; result (unless (setq child (mm-find-part-by-type (cdr handle) "application/octet-stream" nil t)) @@ -751,7 +752,7 @@ If set, it overrides the setting of `mml2015-sign-with-sender'." (let ((key-image (mml2015-epg-key-image key-id))) (if (not key-image) "" - (condition-case error + (condition-case nil (let ((result " ")) (put-text-property 1 2 'display @@ -770,10 +771,10 @@ If set, it overrides the setting of `mml2015-sign-with-sender'." (defun mml2015-epg-verify-result-to-string (verify-result) (mapconcat #'mml2015-epg-signature-to-string verify-result "\n")) -(defun mml2015-epg-decrypt (handle ctl) +(defun mml2015-epg-decrypt (handle _ctl) (catch 'error (let ((inhibit-redisplay t) - context plain child handles result decrypt-status) + context plain child handles) ;; decrypt-status result (unless (setq child (mm-find-part-by-type (cdr handle) "application/octet-stream" nil t)) @@ -851,7 +852,7 @@ If set, it overrides the setting of `mml2015-sign-with-sender'." (defun mml2015-epg-verify (handle ctl) (catch 'error (let ((inhibit-redisplay t) - context plain signature-file part signature) + context part signature) ;; plain signature-file (when (or (null (setq part (mm-find-raw-part-by-type ctl (or (mm-handle-multipart-ctl-parameter ctl 'protocol) @@ -866,7 +867,8 @@ If set, it overrides the setting of `mml2015-sign-with-sender'." signature (mm-get-part signature) context (epg-make-context)) (condition-case error - (setq plain (epg-verify-string context signature part)) + ;; (setq plain + (epg-verify-string context signature part) ;;) (error (mm-sec-error 'gnus-info "Failed") (mm-sec-status 'gnus-details (if (eq (car error) 'quit) @@ -978,7 +980,7 @@ If set, it overrides the setting of `mml2015-sign-with-sender'." handle))) ;;;###autoload -(defun mml2015-decrypt-test (handle ctl) +(defun mml2015-decrypt-test (_handle _ctl) mml2015-use) ;;;###autoload @@ -990,7 +992,7 @@ If set, it overrides the setting of `mml2015-sign-with-sender'." handle))) ;;;###autoload -(defun mml2015-verify-test (handle ctl) +(defun mml2015-verify-test (_handle _ctl) mml2015-use) ;;;###autoload diff --git a/lisp/gnus/nnagent.el b/lisp/gnus/nnagent.el index 1f21eee868..76a7e21567 100644 --- a/lisp/gnus/nnagent.el +++ b/lisp/gnus/nnagent.el @@ -1,4 +1,4 @@ -;;; nnagent.el --- offline backend for Gnus +;;; nnagent.el --- offline backend for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -86,7 +86,7 @@ server dir) t)))) -(deffoo nnagent-retrieve-groups (groups &optional server) +(deffoo nnagent-retrieve-groups (_groups &optional _server) (save-excursion (cond ((file-exists-p (gnus-agent-lib-file "groups")) @@ -106,13 +106,13 @@ (funcall (gnus-get-function gnus-command-method 'request-type) (gnus-group-real-name group) article))))) -(deffoo nnagent-request-newgroups (date server) +(deffoo nnagent-request-newgroups (_date _server) nil) -(deffoo nnagent-request-update-info (group info &optional server) +(deffoo nnagent-request-update-info (_group _info &optional _server) nil) -(deffoo nnagent-request-post (&optional server) +(deffoo nnagent-request-post (&optional _server) (gnus-agent-insert-meta-information 'news gnus-command-method) (gnus-request-accept-article "nndraft:queue" nil t t)) @@ -184,7 +184,7 @@ t) 'nov))) -(deffoo nnagent-request-expire-articles (articles group &optional server force) +(deffoo nnagent-request-expire-articles (articles _group &optional _server _force) articles) (deffoo nnagent-request-group (group &optional server dont-check info) @@ -249,7 +249,7 @@ (nnoo-parent-function 'nnagent 'nnml-request-regenerate (list (nnagent-server server)))) -(deffoo nnagent-retrieve-group-data-early (server infos) +(deffoo nnagent-retrieve-group-data-early (_server _infos) nil) ;; Use nnml functions for just about everything. diff --git a/lisp/gnus/nnbabyl.el b/lisp/gnus/nnbabyl.el index 41f7f62fae..3e6f9e88ee 100644 --- a/lisp/gnus/nnbabyl.el +++ b/lisp/gnus/nnbabyl.el @@ -1,4 +1,4 @@ -;;; nnbabyl.el --- rmail mbox access for Gnus +;;; nnbabyl.el --- rmail mbox access for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -70,7 +70,7 @@ (nnoo-define-basics nnbabyl) -(deffoo nnbabyl-retrieve-headers (articles &optional group server fetch-old) +(deffoo nnbabyl-retrieve-headers (articles &optional group server _fetch-old) (with-current-buffer nntp-server-buffer (erase-buffer) (let ((number (length articles)) @@ -185,7 +185,7 @@ (cons nnbabyl-current-group article) (nnbabyl-article-group-number))))))) -(deffoo nnbabyl-request-group (group &optional server dont-check info) +(deffoo nnbabyl-request-group (group &optional server dont-check _info) (let ((active (cadr (assoc group nnbabyl-group-alist)))) (save-excursion (cond @@ -224,10 +224,10 @@ (insert-buffer-substring in-buf))) (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file)))) -(deffoo nnbabyl-close-group (group &optional server) +(deffoo nnbabyl-close-group (_group &optional _server) t) -(deffoo nnbabyl-request-create-group (group &optional server args) +(deffoo nnbabyl-request-create-group (group &optional _server _args) (nnmail-activate 'nnbabyl) (unless (assoc group nnbabyl-group-alist) (push (list group (cons 1 0)) @@ -235,18 +235,20 @@ (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file)) t) -(deffoo nnbabyl-request-list (&optional server) +(deffoo nnbabyl-request-list (&optional _server) (save-excursion (nnmail-find-file nnbabyl-active-file) (setq nnbabyl-group-alist (nnmail-get-active)) t)) -(deffoo nnbabyl-request-newgroups (date &optional server) +(deffoo nnbabyl-request-newgroups (_date &optional server) (nnbabyl-request-list server)) -(deffoo nnbabyl-request-list-newsgroups (&optional server) +(deffoo nnbabyl-request-list-newsgroups (&optional _server) (nnheader-report 'nnbabyl "nnbabyl: LIST NEWSGROUPS is not implemented.")) +(defvar nnml-current-directory) + (deffoo nnbabyl-request-expire-articles (articles newsgroup &optional server force) (nnbabyl-possibly-change-newsgroup newsgroup server) @@ -293,7 +295,7 @@ (nconc rest articles)))) (deffoo nnbabyl-request-move-article - (article group server accept-form &optional last move-is-internal) + (article group server accept-form &optional last _move-is-internal) (let ((buf (gnus-get-buffer-create " *nnbabyl move*")) result) (and @@ -305,7 +307,7 @@ "^X-Gnus-Newsgroup:" (save-excursion (search-forward "\n\n" nil t) (point)) t) (delete-region (point-at-bol) (progn (forward-line 1) (point)))) - (setq result (eval accept-form)) + (setq result (eval accept-form t)) (kill-buffer (current-buffer)) result) (save-excursion diff --git a/lisp/gnus/nndiary.el b/lisp/gnus/nndiary.el index 60ef6e9b8e..15003fabcd 100644 --- a/lisp/gnus/nndiary.el +++ b/lisp/gnus/nndiary.el @@ -1,4 +1,4 @@ -;;; nndiary.el --- A diary back end for Gnus +;;; nndiary.el --- A diary back end for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. @@ -469,7 +469,7 @@ all. This may very well take some time.") (cons (if group-num (car group-num) group) (string-to-number (file-name-nondirectory path))))))) -(deffoo nndiary-request-group (group &optional server dont-check info) +(deffoo nndiary-request-group (group &optional server dont-check _info) (let ((file-name-coding-system nnmail-pathname-coding-system)) (cond ((not (nndiary-possibly-change-directory group server)) @@ -503,11 +503,11 @@ all. This may very well take some time.") (nndiary-possibly-change-directory group server) (nnmail-get-new-mail 'nndiary 'nndiary-save-nov nndiary-directory group))) -(deffoo nndiary-close-group (group &optional server) +(deffoo nndiary-close-group (_group &optional _server) (setq nndiary-article-file-alist nil) t) -(deffoo nndiary-request-create-group (group &optional server args) +(deffoo nndiary-request-create-group (group &optional server _args) (nndiary-possibly-change-directory nil server) (nnmail-activate 'nndiary) (cond @@ -535,7 +535,7 @@ all. This may very well take some time.") t)) )) -(deffoo nndiary-request-list (&optional server) +(deffoo nndiary-request-list (&optional _server) (save-excursion (let ((nnmail-file-coding-system nnmail-active-file-coding-system) (file-name-coding-system nnmail-pathname-coding-system)) @@ -543,10 +543,10 @@ all. This may very well take some time.") (setq nndiary-group-alist (nnmail-get-active)) t)) -(deffoo nndiary-request-newgroups (date &optional server) +(deffoo nndiary-request-newgroups (_date &optional server) (nndiary-request-list server)) -(deffoo nndiary-request-list-newsgroups (&optional server) +(deffoo nndiary-request-list-newsgroups (&optional _server) (save-excursion (nnmail-find-file nndiary-newsgroups-file))) @@ -590,7 +590,7 @@ all. This may very well take some time.") (nconc rest articles))) (deffoo nndiary-request-move-article - (article group server accept-form &optional last move-is-internal) + (article group server accept-form &optional last _move-is-internal) (let ((buf (gnus-get-buffer-create " *nndiary move*")) result) (nndiary-possibly-change-directory group server) @@ -603,7 +603,7 @@ all. This may very well take some time.") nndiary-article-file-alist) (with-current-buffer buf (insert-buffer-substring nntp-server-buffer) - (setq result (eval accept-form)) + (setq result (eval accept-form t)) (kill-buffer (current-buffer)) result)) (progn @@ -766,7 +766,7 @@ all. This may very well take some time.") ;;; Interface optional functions ============================================ -(deffoo nndiary-request-update-info (group info &optional server) +(deffoo nndiary-request-update-info (group info &optional _server) (nndiary-possibly-change-directory group) (let ((timestamp (gnus-group-parameter-value (gnus-info-params info) 'timestamp t))) @@ -1033,6 +1033,8 @@ all. This may very well take some time.") ;; Save the active file. (nnmail-save-active nndiary-group-alist nndiary-active-file)) +(defvar nndiary-files) ; dynamically bound in nndiary-generate-nov-databases-1 + (defun nndiary-generate-nov-databases-1 (dir &optional seen no-active) "Regenerate the NOV database in DIR." (interactive "DRegenerate NOV in: ") @@ -1062,7 +1064,6 @@ all. This may very well take some time.") (unless no-active (nnmail-save-active nndiary-group-alist nndiary-active-file)))))) -(defvar nndiary-files) ; dynamically bound in nndiary-generate-nov-databases-1 (defun nndiary-generate-active-info (dir) ;; Update the active info for this group. (let* ((group (nnheader-file-to-group diff --git a/lisp/gnus/nndir.el b/lisp/gnus/nndir.el index 46351d0004..bfc2283658 100644 --- a/lisp/gnus/nndir.el +++ b/lisp/gnus/nndir.el @@ -1,4 +1,4 @@ -;;; nndir.el --- single directory newsgroup access for Gnus +;;; nndir.el --- single directory newsgroup access for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/nndoc.el b/lisp/gnus/nndoc.el index dccf6c1ffb..172433ef3b 100644 --- a/lisp/gnus/nndoc.el +++ b/lisp/gnus/nndoc.el @@ -1,4 +1,4 @@ -;;; nndoc.el --- single file access for Gnus +;;; nndoc.el --- single file access for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -225,7 +225,7 @@ from the document.") (nnoo-define-basics nndoc) -(deffoo nndoc-retrieve-headers (articles &optional newsgroup server fetch-old) +(deffoo nndoc-retrieve-headers (articles &optional newsgroup server _fetch-old) (when (nndoc-possibly-change-buffer newsgroup server) (with-current-buffer nntp-server-buffer (erase-buffer) @@ -280,7 +280,7 @@ from the document.") (funcall nndoc-article-transform-function article)) t)))))) -(deffoo nndoc-request-group (group &optional server dont-check info) +(deffoo nndoc-request-group (group &optional server dont-check _info) "Select news GROUP." (let (number) (cond @@ -301,7 +301,7 @@ from the document.") (nndoc-request-group group server)) t) -(deffoo nndoc-request-type (group &optional article) +(deffoo nndoc-request-type (_group &optional article) (cond ((not article) 'unknown) (nndoc-post-type nndoc-post-type) (t 'unknown))) @@ -317,19 +317,19 @@ from the document.") (setq nndoc-dissection-alist nil) t) -(deffoo nndoc-request-list (&optional server) +(deffoo nndoc-request-list (&optional _server) t) -(deffoo nndoc-request-newgroups (date &optional server) +(deffoo nndoc-request-newgroups (_date &optional _server) nil) -(deffoo nndoc-request-list-newsgroups (&optional server) +(deffoo nndoc-request-list-newsgroups (&optional _server) nil) ;;; Internal functions. -(defun nndoc-possibly-change-buffer (group source) +(defun nndoc-possibly-change-buffer (group _source) (let (buf) (cond ;; The current buffer is this group's buffer. @@ -677,7 +677,7 @@ from the document.") (search-forward "\ncommit " nil t) (search-forward "\nAuthor: " nil t))) -(defun nndoc-transform-git-article (article) +(defun nndoc-transform-git-article (_article) (goto-char (point-min)) (when (re-search-forward "^Author: " nil t) (replace-match "From: " t t))) @@ -701,7 +701,7 @@ from the document.") (re-search-forward "^\\\\\\\\\n\\(Paper\\( (\\*cross-listing\\*)\\)?: [a-zA-Z\\.-]+/[0-9]+\\|arXiv:\\)" nil t)) t)) -(defun nndoc-transform-lanl-gov-announce (article) +(defun nndoc-transform-lanl-gov-announce (_article) (let ((case-fold-search nil)) (goto-char (point-max)) (when (re-search-backward "^\\\\\\\\ +( *\\([^ ]*\\) , *\\([^ ]*\\))" nil t) @@ -858,7 +858,7 @@ from the document.") nil) (goto-char point)))) -(deffoo nndoc-request-accept-article (group &optional server last) +(deffoo nndoc-request-accept-article (_group &optional _server _last) nil) ;;; diff --git a/lisp/gnus/nndraft.el b/lisp/gnus/nndraft.el index e636636a17..394b6fcc4f 100644 --- a/lisp/gnus/nndraft.el +++ b/lisp/gnus/nndraft.el @@ -1,4 +1,4 @@ -;;; nndraft.el --- draft article access for Gnus +;;; nndraft.el --- draft article access for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -79,7 +79,7 @@ are generated if and only if they are also in `message-draft-headers'." server nndraft-directory) t))) -(deffoo nndraft-retrieve-headers (articles &optional group server fetch-old) +(deffoo nndraft-retrieve-headers (articles &optional group server _fetch-old) (nndraft-possibly-change-group group) (with-current-buffer nntp-server-buffer (erase-buffer) @@ -108,7 +108,7 @@ are generated if and only if they are also in `message-draft-headers'." (nnheader-fold-continuation-lines) 'headers)))) -(deffoo nndraft-request-article (id &optional group server buffer) +(deffoo nndraft-request-article (id &optional group _server buffer) (nndraft-possibly-change-group group) (when (numberp id) ;; We get the newest file of the auto-saved file and the @@ -145,7 +145,7 @@ are generated if and only if they are also in `message-draft-headers'." ;;(message-remove-header "date") t)) -(deffoo nndraft-request-update-info (group info &optional server) +(deffoo nndraft-request-update-info (group info &optional _server) (nndraft-possibly-change-group group) (setf (gnus-info-read info) (gnus-update-read-articles @@ -210,7 +210,7 @@ are generated if and only if they are also in `message-draft-headers'." 'exit 'postpone 'kill) article)) -(deffoo nndraft-request-group (group &optional server dont-check info) +(deffoo nndraft-request-group (group &optional server dont-check _info) (nndraft-possibly-change-group group) (unless dont-check (let* ((pathname (nnmail-group-pathname group nndraft-directory)) @@ -229,7 +229,7 @@ are generated if and only if they are also in `message-draft-headers'." (list group server dont-check))) (deffoo nndraft-request-move-article (article group server accept-form - &optional last move-is-internal) + &optional _last _move-is-internal) (nndraft-possibly-change-group group) (let ((buf (gnus-get-buffer-create " *nndraft move*")) result) @@ -238,7 +238,7 @@ are generated if and only if they are also in `message-draft-headers'." (with-current-buffer buf (erase-buffer) (insert-buffer-substring nntp-server-buffer) - (setq result (eval accept-form)) + (setq result (eval accept-form t)) (kill-buffer (current-buffer)) result) (null (nndraft-request-expire-articles (list article) group server 'force)) @@ -292,7 +292,7 @@ are generated if and only if they are also in `message-draft-headers'." (nnoo-parent-function 'nndraft 'nnmh-request-replace-article (list article group buffer)))) -(deffoo nndraft-request-create-group (group &optional server args) +(deffoo nndraft-request-create-group (group &optional _server _args) (nndraft-possibly-change-group group) (if (file-exists-p nndraft-current-directory) (if (file-directory-p nndraft-current-directory) diff --git a/lisp/gnus/nneething.el b/lisp/gnus/nneething.el index 014ad3adfb..d881d6ce05 100644 --- a/lisp/gnus/nneething.el +++ b/lisp/gnus/nneething.el @@ -1,4 +1,4 @@ -;;; nneething.el --- arbitrary file access for Gnus +;;; nneething.el --- arbitrary file access for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -77,7 +77,7 @@ included.") (nnoo-define-basics nneething) -(deffoo nneething-retrieve-headers (articles &optional group server fetch-old) +(deffoo nneething-retrieve-headers (articles &optional group _server _fetch-old) (nneething-possibly-change-directory group) (with-current-buffer nntp-server-buffer @@ -114,7 +114,7 @@ included.") (nnheader-fold-continuation-lines) 'headers)))) -(deffoo nneething-request-article (id &optional group server buffer) +(deffoo nneething-request-article (id &optional group _server buffer) (nneething-possibly-change-directory group) (let ((file (unless (stringp id) (nneething-file-name id))) @@ -143,7 +143,7 @@ included.") (insert "\n")) t)))) -(deffoo nneething-request-group (group &optional server dont-check info) +(deffoo nneething-request-group (group &optional server dont-check _info) (nneething-possibly-change-directory group server) (unless dont-check (nneething-create-mapping) @@ -156,16 +156,16 @@ included.") group))) t) -(deffoo nneething-request-list (&optional server dir) +(deffoo nneething-request-list (&optional _server _dir) (nnheader-report 'nneething "LIST is not implemented.")) -(deffoo nneething-request-newgroups (date &optional server) +(deffoo nneething-request-newgroups (_date &optional _server) (nnheader-report 'nneething "NEWSGROUPS is not implemented.")) -(deffoo nneething-request-type (group &optional article) +(deffoo nneething-request-type (_group &optional _article) 'unknown) -(deffoo nneething-close-group (group &optional server) +(deffoo nneething-close-group (_group &optional _server) (setq nneething-current-directory nil) t) diff --git a/lisp/gnus/nnfolder.el b/lisp/gnus/nnfolder.el index 70e15c5713..1dd784d5a5 100644 --- a/lisp/gnus/nnfolder.el +++ b/lisp/gnus/nnfolder.el @@ -1,4 +1,4 @@ -;;; nnfolder.el --- mail folder access for Gnus +;;; nnfolder.el --- mail folder access for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -261,7 +261,7 @@ all. This may very well take some time.") (point) (point-at-eol))) -1)))))))) -(deffoo nnfolder-request-group (group &optional server dont-check info) +(deffoo nnfolder-request-group (group &optional server dont-check _info) (nnfolder-possibly-change-group group server t) (save-excursion (cond ((not (assoc group nnfolder-group-alist)) @@ -314,7 +314,7 @@ all. This may very well take some time.") ;; over the buffer again unless we add new mail to it or modify it in some ;; way. -(deffoo nnfolder-close-group (group &optional server force) +(deffoo nnfolder-close-group (group &optional _server _force) ;; Make sure we _had_ the group open. (when (or (assoc group nnfolder-buffer-alist) (equal group nnfolder-current-group)) @@ -342,7 +342,7 @@ all. This may very well take some time.") nnfolder-current-buffer nil) t) -(deffoo nnfolder-request-create-group (group &optional server args) +(deffoo nnfolder-request-create-group (group &optional server _args) (nnfolder-possibly-change-group nil server) (nnmail-activate 'nnfolder) (cond ((zerop (length group)) @@ -369,7 +369,7 @@ all. This may very well take some time.") (setq nnfolder-group-alist (nnmail-get-active))) t)) -(deffoo nnfolder-request-newgroups (date &optional server) +(deffoo nnfolder-request-newgroups (_date &optional server) (nnfolder-possibly-change-group nil server) (nnfolder-request-list server)) @@ -394,12 +394,13 @@ all. This may very well take some time.") (let ((newnum (string-to-number (match-string 0)))) (if (nnmail-within-headers-p) (push newnum numbers)))) - ;; The article numbers are increasing, so this result is sorted. + ;; The article numbers are increasing, so this result is sorted. (nreverse numbers))))) (autoload 'gnus-request-group "gnus-int") (declare-function gnus-request-create-group "gnus-int" (group &optional gnus-command-method args)) +(defvar nnfolder-current-directory) (deffoo nnfolder-request-expire-articles (articles newsgroup &optional server force) @@ -462,7 +463,7 @@ all. This may very well take some time.") (gnus-sorted-difference articles (nreverse deleted-articles))))) (deffoo nnfolder-request-move-article (article group server accept-form - &optional last move-is-internal) + &optional last _move-is-internal) (save-excursion (let ((buf (gnus-get-buffer-create " *nnfolder move*")) result) @@ -477,7 +478,7 @@ all. This may very well take some time.") (save-excursion (and (search-forward "\n\n" nil t) (point))) t) (gnus-delete-line)) - (setq result (eval accept-form)) + (setq result (eval accept-form t)) (kill-buffer buf) result) (save-excursion @@ -498,7 +499,7 @@ all. This may very well take some time.") (save-excursion (nnfolder-possibly-change-group group server) (nnmail-check-syntax) - (let ((buf (current-buffer)) + (let (;; (buf (current-buffer)) result art-group) (goto-char (point-min)) (when (looking-at "X-From-Line: ") diff --git a/lisp/gnus/nngateway.el b/lisp/gnus/nngateway.el index 15e4876642..c10989aa1e 100644 --- a/lisp/gnus/nngateway.el +++ b/lisp/gnus/nngateway.el @@ -1,4 +1,4 @@ -;;; nngateway.el --- posting news via mail gateways +;;; nngateway.el --- posting news via mail gateways -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/nnheader.el b/lisp/gnus/nnheader.el index ae8506c5c2..708887cb9c 100644 --- a/lisp/gnus/nnheader.el +++ b/lisp/gnus/nnheader.el @@ -1,4 +1,4 @@ -;;; nnheader.el --- header access macros for Gnus and its backends +;;; nnheader.el --- header access macros for Gnus and its backends -*- lexical-binding: t; -*- ;; Copyright (C) 1987-1990, 1993-1998, 2000-2021 Free Software ;; Foundation, Inc. diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el index 4a50f1127b..f4f4ef89a9 100644 --- a/lisp/gnus/nnimap.el +++ b/lisp/gnus/nnimap.el @@ -1,4 +1,4 @@ -;;; nnimap.el --- IMAP interface for Gnus +;;; nnimap.el --- IMAP interface for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 2010-2021 Free Software Foundation, Inc. @@ -1004,7 +1004,7 @@ during splitting, which may be slow." internal-move-group server message-id nnimap-request-articles-find-limit))))) ;; Move the article to a different method. - (when-let* ((result (eval accept-form))) + (when-let* ((result (eval accept-form t))) (nnimap-change-group group server) (nnimap-delete-article article) result)))))) @@ -1165,7 +1165,7 @@ If LIMIT, first try to limit the search to the N last articles." 7 "Article marked for deletion, but not expunged.") nil)))) -(deffoo nnimap-request-scan (&optional group server) +(deffoo nnimap-request-scan (&optional _group server) (when (and (nnimap-change-group nil server) nnimap-inbox nnimap-split-methods) diff --git a/lisp/gnus/nnmail.el b/lisp/gnus/nnmail.el index 251ae657bb..ac56e8f4b9 100644 --- a/lisp/gnus/nnmail.el +++ b/lisp/gnus/nnmail.el @@ -1,4 +1,4 @@ -;;; nnmail.el --- mail support functions for the Gnus mail backends +;;; nnmail.el --- mail support functions for the Gnus mail backends -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -598,7 +598,7 @@ These will be logged to the \"*nnmail split*\" buffer." -(defun nnmail-request-post (&optional server) +(defun nnmail-request-post (&optional _server) (mail-send-and-exit nil)) (defvar nnmail-file-coding-system 'raw-text @@ -664,7 +664,7 @@ nn*-request-list should have been called before calling this function." (let ((buffer (current-buffer)) group-assoc group max min) (while (not (eobp)) - (condition-case err + (condition-case nil (progn (narrow-to-region (point) (point-at-eol)) (setq group (read buffer) @@ -1332,7 +1332,7 @@ Eudora has a broken References line, but an OK In-Reply-To." (declare-function gnus-activate-group "gnus-start" (group &optional scan dont-check method dont-sub-check)) -(defun nnmail-do-request-post (accept-func &optional server) +(defun nnmail-do-request-post (accept-func &optional _server) "Utility function to directly post a message to an nnmail-derived group. Calls ACCEPT-FUNC (which should be `nnchoke-request-accept-article') to actually put the message in the right group." @@ -1397,7 +1397,7 @@ See the documentation for the variable `nnmail-split-fancy' for details." ;; Builtin : operation. ((eq (car split) ':) (nnmail-log-split split) - (nnmail-split-it (save-excursion (eval (cdr split))))) + (nnmail-split-it (save-excursion (eval (cdr split) t)))) ;; Builtin ! operation. ((eq (car split) '!) @@ -1783,7 +1783,7 @@ be called once per group or once for all groups." (assq 'directory mail-sources))) (defun nnmail-get-new-mail-1 (method exit-func temp - group in-group spool-func) + group _in-group spool-func) (let* ((sources mail-sources) fetching-sources (i 0) @@ -1918,7 +1918,7 @@ If TIME is nil, then return the cutoff time for oldness instead." (cdr group-art)) (gnus-group-mark-article-read target (cdr group-art)))))))) -(defun nnmail-fancy-expiry-target (group) +(defun nnmail-fancy-expiry-target (_group) "Return a target expiry group determined by `nnmail-fancy-expiry-targets'." (let* (header (case-fold-search nil) diff --git a/lisp/gnus/nnmairix.el b/lisp/gnus/nnmairix.el index 8b3ab40e22..a2de5e061e 100644 --- a/lisp/gnus/nnmairix.el +++ b/lisp/gnus/nnmairix.el @@ -1,4 +1,4 @@ -;;; nnmairix.el --- Mairix back end for Gnus, the Emacs newsreader +;;; nnmairix.el --- Mairix back end for Gnus, the Emacs newsreader -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. @@ -404,7 +404,7 @@ Other back ends might or might not work.") (setq nnmairix-current-server server) (nnoo-change-server 'nnmairix server definitions)) -(deffoo nnmairix-request-group (group &optional server fast info) +(deffoo nnmairix-request-group (group &optional server fast _info) ;; Call mairix and request group on back end server (when server (nnmairix-open-server server)) (let* ((qualgroup (if server @@ -417,7 +417,7 @@ Other back ends might or might not work.") (backendmethod (gnus-server-to-method (format "%s:%s" (symbol-name nnmairix-backend) nnmairix-backend-server))) - rval mfolder folderpath args) + rval mfolder folderpath) ;; args (cond ((not folder) ;; No folder parameter -> error @@ -497,12 +497,12 @@ Other back ends might or might not work.") nil)))))) -(deffoo nnmairix-request-create-group (group &optional server args) +(deffoo nnmairix-request-create-group (group &optional server _args) (let ((qualgroup (if server (gnus-group-prefixed-name group (list 'nnmairix server)) group)) (exist t) (count 0) - groupname info) + groupname) ;; info (when server (nnmairix-open-server server)) (gnus-group-add-parameter qualgroup '(query . nil)) (gnus-group-add-parameter qualgroup '(threads . nil)) @@ -561,7 +561,7 @@ Other back ends might or might not work.") (deffoo nnmairix-request-list (&optional server) (when server (nnmairix-open-server server)) (if (nnmairix-call-backend "request-list" nnmairix-backend-server) - (let (cpoint cur qualgroup folder) + (let (cpoint cur qualgroup) ;; folder (with-current-buffer nntp-server-buffer (goto-char (point-min)) (setq cpoint (point)) @@ -590,7 +590,7 @@ Other back ends might or might not work.") (nnmairix-open-server server)) (let* ((qualgroup (gnus-group-prefixed-name group (list 'nnmairix nnmairix-current-server))) (propmarks (gnus-group-get-parameter qualgroup 'propmarks)) - (propto (gnus-group-get-parameter qualgroup 'propto t)) + ;; (propto (gnus-group-get-parameter qualgroup 'propto t)) (corr (nnmairix-get-numcorr group server)) (folder (nnmairix-get-backend-folder group server))) (save-excursion @@ -598,7 +598,7 @@ Other back ends might or might not work.") (let ((type (nth 1 cur)) (cmdmarks (nth 2 cur)) (range (gnus-uncompress-range (nth 0 cur))) - mid ogroup number method temp) + mid ogroup temp) ;; number method (when (and corr (not (zerop (cadr corr)))) (setq range (mapcar (lambda (arg) @@ -661,7 +661,7 @@ Other back ends might or might not work.") (nnmairix-open-server server)) (let* ((qualgroup (gnus-group-prefixed-name group (list 'nnmairix nnmairix-current-server))) (propmarks (gnus-group-get-parameter qualgroup 'propmarks)) - method) + ) ;; method (when (and propmarks nnmairix-marks-cache) (when (or (eq nnmairix-propagate-marks-upon-close t) @@ -690,7 +690,7 @@ Other back ends might or might not work.") (corr (nnmairix-get-numcorr group server)) (docorr (and corr (not (zerop (cadr corr))))) (folderinfo `(,group 1 ((1 . 1)))) - readrange marks) + ) ;; readrange marks (when (and propmarks nnmairix-propagate-marks-to-nnmairix-groups) ;; these groups are not subscribed, so we have to ask the back end directly @@ -778,7 +778,7 @@ called interactively, user will be asked for parameters." (interactive) (let ((char-header nnmairix-interactive-query-parameters) (server (nnmairix-backend-to-server gnus-current-select-method)) - query achar header finished group threads cq) + query achar header finished group threads) ;; cq (when (or (not (gnus-buffer-live-p gnus-article-buffer)) (not (gnus-buffer-live-p gnus-summary-buffer))) (error "No article or summary buffer")) @@ -796,7 +796,8 @@ called interactively, user will be asked for parameters." (setq achar nil))) (set-buffer gnus-article-buffer) (setq header nil) - (when (setq cq (nth 1 (assoc achar char-header))) + (when ;; (setq cq + (nth 1 (assoc achar char-header)) ;;) (setq header (nnmairix-replace-illegal-chars (gnus-fetch-field (nth 1 (assoc achar char-header)))))) @@ -827,7 +828,7 @@ All necessary information will be queried from the user." (hidden (and (string-match "^nn\\(imap\\|maildir\\)$" backend) (y-or-n-p "Does the back end server work with maildir++ (i.e. hidden directories)? "))) - create) + ) ;; create (apply (intern (format "%s-%s" backend "open-server")) (list servername)) @@ -1009,7 +1010,7 @@ before deleting a group on the back end. SERVER specifies nnmairix server." (if (nnmairix-open-server (nth 1 server)) (when (nnmairix-call-backend "request-list" nnmairix-backend-server) - (let (cur qualgroup folder) + (let (cur qualgroup) ;; folder (with-current-buffer nntp-server-buffer (goto-char (point-min)) (while (re-search-forward nnmairix-group-regexp (point-max) t) @@ -1172,7 +1173,7 @@ Marks propagation has to be enabled for this to work." (error "Not in a nnmairix group")) (save-excursion (let ((mid (mail-header-message-id (gnus-summary-article-header))) - groups cur) + groups) ;; cur (when mid (setq groups (nnmairix-determine-original-group-from-registry mid)) (unless (or groups @@ -1299,7 +1300,7 @@ If ALL is t, return also the unopened/failed ones." "Return list of valid back end servers for nnmairix groups." (let ((alist gnus-opened-servers) (mairixservers (nnmairix-get-nnmairix-servers t)) - server mserver openedserver occ cur) + server mserver openedserver occ) ;; cur ;; Get list of all nnmairix backends (i.e. backends which are ;; already occupied) (dolist (cur mairixservers) @@ -1393,7 +1394,7 @@ TYPE is either `nov' or `headers'." (let ((buf (gnus-get-buffer-create " *nnmairix buffer*")) (corr (not (zerop numc))) (name (buffer-name nntp-server-buffer)) - header cur xref) + cur xref) ;; header (with-current-buffer buf (erase-buffer) (set-buffer nntp-server-buffer) @@ -1586,7 +1587,7 @@ search in raw mode." (when (not (gnus-buffer-live-p gnus-article-buffer)) (error "No article buffer available")) (let ((server (nth 1 gnus-current-select-method)) - mid rval group allgroups) + mid group allgroups) ;; rval ;; get message id (with-current-buffer gnus-article-buffer (gnus-summary-toggle-header 1) @@ -1817,10 +1818,10 @@ MVALUES may contain values from current article." (widget-create 'push-button :notify (if mvalues - (lambda (&rest ignore) + (lambda (&rest _ignore) (nnmairix-widget-send-query nnmairix-widgets t)) - (lambda (&rest ignore) + (lambda (&rest _ignore) (nnmairix-widget-send-query nnmairix-widgets nil))) "Send Query") @@ -1828,16 +1829,16 @@ MVALUES may contain values from current article." (widget-create 'push-button :notify (if mvalues - (lambda (&rest ignore) + (lambda (&rest _ignore) (nnmairix-widget-create-group nnmairix-widgets t)) - (lambda (&rest ignore) + (lambda (&rest _ignore) (nnmairix-widget-create-group nnmairix-widgets nil))) "Create permanent group") (widget-insert " ") (widget-create 'push-button - :notify (lambda (&rest ignore) + :notify (lambda (&rest _ignore) (kill-buffer nnmairix-customize-query-buffer)) "Cancel") (use-local-map widget-keymap) @@ -1912,7 +1913,7 @@ If WITHVALUES is t, query is based on current article." (defun nnmairix-widget-create-query (&optional values) "Create widgets for creating mairix queries. Fill in VALUES if based on an article." - (let (allwidgets) + ;;(let (allwidgets) (when (get-buffer nnmairix-customize-query-buffer) (kill-buffer nnmairix-customize-query-buffer)) (switch-to-buffer nnmairix-customize-query-buffer) @@ -1943,7 +1944,7 @@ Fill in VALUES if based on an article." (when (member 'threads nnmairix-widget-other) (widget-insert "\n") (nnmairix-widget-add "Threads" 'checkbox nil)) - (widget-insert " Show full threads\n\n"))) + (widget-insert " Show full threads\n\n")) ;; ) (defun nnmairix-widget-build-editable-fields (values) "Build editable field widgets in `nnmairix-widget-fields-list'. @@ -1960,7 +1961,7 @@ VALUES may contain values for editable fields from current article." (concat "c" field) (widget-create 'checkbox :tag field - :notify (lambda (widget &rest ignore) + :notify (lambda (widget &rest _ignore) (nnmairix-widget-toggle-activate widget)) nil))) (list diff --git a/lisp/gnus/nnmbox.el b/lisp/gnus/nnmbox.el index 92c7dde9c8..66c22670b2 100644 --- a/lisp/gnus/nnmbox.el +++ b/lisp/gnus/nnmbox.el @@ -1,4 +1,4 @@ -;;; nnmbox.el --- mail mbox access for Gnus +;;; nnmbox.el --- mail mbox access for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -76,7 +76,7 @@ (nnoo-define-basics nnmbox) -(deffoo nnmbox-retrieve-headers (sequence &optional newsgroup server fetch-old) +(deffoo nnmbox-retrieve-headers (sequence &optional newsgroup server _fetch-old) (with-current-buffer nntp-server-buffer (erase-buffer) (let ((number (length sequence)) @@ -168,7 +168,7 @@ (cons nnmbox-current-group article) (nnmbox-article-group-number nil)))))))) -(deffoo nnmbox-request-group (group &optional server dont-check info) +(deffoo nnmbox-request-group (group &optional server dont-check _info) (nnmbox-possibly-change-newsgroup nil server) (let ((active (cadr (assoc group nnmbox-group-alist)))) (cond @@ -213,10 +213,10 @@ (insert-buffer-substring in-buf))) (nnmbox-save-active nnmbox-group-alist nnmbox-active-file)))) -(deffoo nnmbox-close-group (group &optional server) +(deffoo nnmbox-close-group (_group &optional _server) t) -(deffoo nnmbox-request-create-group (group &optional server args) +(deffoo nnmbox-request-create-group (group &optional _server _args) (nnmail-activate 'nnmbox) (unless (assoc group nnmbox-group-alist) (push (list group (cons 1 0)) @@ -224,7 +224,7 @@ (nnmbox-save-active nnmbox-group-alist nnmbox-active-file)) t) -(deffoo nnmbox-request-list (&optional server) +(deffoo nnmbox-request-list (&optional _server) (save-excursion (let ((nnmail-file-coding-system nnmbox-active-file-coding-system)) @@ -232,12 +232,14 @@ (setq nnmbox-group-alist (nnmail-get-active)) t)) -(deffoo nnmbox-request-newgroups (date &optional server) +(deffoo nnmbox-request-newgroups (_date &optional server) (nnmbox-request-list server)) -(deffoo nnmbox-request-list-newsgroups (&optional server) +(deffoo nnmbox-request-list-newsgroups (&optional _server) (nnheader-report 'nnmbox "LIST NEWSGROUPS is not implemented.")) +(defvar nnml-current-directory) + (deffoo nnmbox-request-expire-articles (articles newsgroup &optional server force) (nnmbox-possibly-change-newsgroup newsgroup server) @@ -278,7 +280,7 @@ (nconc rest articles)))) (deffoo nnmbox-request-move-article - (article group server accept-form &optional last move-is-internal) + (article group server accept-form &optional last _move-is-internal) (let ((buf (gnus-get-buffer-create " *nnmbox move*")) result) (and @@ -291,7 +293,7 @@ "^X-Gnus-Newsgroup:" (save-excursion (search-forward "\n\n" nil t) (point)) t) (gnus-delete-line)) - (setq result (eval accept-form)) + (setq result (eval accept-form t)) (kill-buffer buf) result) (save-excursion diff --git a/lisp/gnus/nnmh.el b/lisp/gnus/nnmh.el index 46abf46ce7..231583fae8 100644 --- a/lisp/gnus/nnmh.el +++ b/lisp/gnus/nnmh.el @@ -1,4 +1,4 @@ -;;; nnmh.el --- mhspool access for Gnus +;;; nnmh.el --- mhspool access for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -72,7 +72,7 @@ as unread by Gnus.") (nnoo-define-basics nnmh) -(deffoo nnmh-retrieve-headers (articles &optional newsgroup server fetch-old) +(deffoo nnmh-retrieve-headers (articles &optional newsgroup server _fetch-old) (with-current-buffer nntp-server-buffer (erase-buffer) (let* ((file nil) @@ -147,7 +147,7 @@ as unread by Gnus.") (save-excursion (nnmail-find-file file)) (string-to-number (file-name-nondirectory file))))) -(deffoo nnmh-request-group (group &optional server dont-check info) +(deffoo nnmh-request-group (group &optional server dont-check _info) (nnheader-init-server-buffer) (nnmh-possibly-change-directory group server) (let ((pathname (nnmail-group-pathname group nnmh-directory)) @@ -188,9 +188,11 @@ as unread by Gnus.") (nnheader-report 'nnmh "Empty group %s" group) (nnheader-insert (format "211 0 1 0 %s\n" group)))))))))) -(deffoo nnmh-request-scan (&optional group server) +(deffoo nnmh-request-scan (&optional group _server) (nnmail-get-new-mail 'nnmh nil nnmh-directory group)) +(defvar nnmh-toplev) + (deffoo nnmh-request-list (&optional server dir) (nnheader-insert "") (nnmh-possibly-change-directory nil server) @@ -201,13 +203,12 @@ as unread by Gnus.") (setq nnmh-group-alist (nnmail-get-active)) t) -(defvar nnmh-toplev) (defun nnmh-request-list-1 (dir) (setq dir (expand-file-name dir)) ;; Recurse down all directories. (let ((files (nnheader-directory-files dir t nil t)) (max 0) - min rdir num subdirectoriesp file) + min num subdirectoriesp file) ;; rdir ;; Recurse down directories. (setq subdirectoriesp ;; link number always 1 on MS Windows :( @@ -252,7 +253,7 @@ as unread by Gnus.") (or min 1)))))) t) -(deffoo nnmh-request-newgroups (date &optional server) +(deffoo nnmh-request-newgroups (_date &optional server) (nnmh-request-list server)) (deffoo nnmh-request-expire-articles (articles newsgroup @@ -291,11 +292,11 @@ as unread by Gnus.") (nnheader-message 5 "") (nconc rest articles))) -(deffoo nnmh-close-group (group &optional server) +(deffoo nnmh-close-group (_group &optional _server) t) -(deffoo nnmh-request-move-article (article group server accept-form - &optional last move-is-internal) +(deffoo nnmh-request-move-article ( article group server accept-form + &optional _last _move-is-internal) (let ((buf (gnus-get-buffer-create " *nnmh move*")) result) (and @@ -304,7 +305,7 @@ as unread by Gnus.") (with-current-buffer buf (erase-buffer) (insert-buffer-substring nntp-server-buffer) - (setq result (eval accept-form)) + (setq result (eval accept-form t)) (kill-buffer (current-buffer)) result) (progn @@ -350,7 +351,7 @@ as unread by Gnus.") nil (if (nnheader-be-verbose 5) nil 'nomesg)) t))) -(deffoo nnmh-request-create-group (group &optional server args) +(deffoo nnmh-request-create-group (group &optional server _args) (nnheader-init-server-buffer) (unless (assoc group nnmh-group-alist) (let (active) diff --git a/lisp/gnus/nnml.el b/lisp/gnus/nnml.el index eaa2004272..7bd295399c 100644 --- a/lisp/gnus/nnml.el +++ b/lisp/gnus/nnml.el @@ -1,4 +1,4 @@ -;;; nnml.el --- mail spool access for Gnus +;;; nnml.el --- mail spool access for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1995-2021 Free Software Foundation, Inc. @@ -111,7 +111,7 @@ non-nil.") (nnoo-define-basics nnml) -(defun nnml-group-pathname (group &optional file server) +(defun nnml-group-pathname (group &optional file _server) "Return an absolute file name of FILE for GROUP on SERVER." (nnmail-group-pathname group nnml-directory file)) @@ -215,7 +215,7 @@ non-nil.") (cons (if group-num (car group-num) group) (string-to-number (file-name-nondirectory path))))))) -(deffoo nnml-request-group (group &optional server dont-check info) +(deffoo nnml-request-group (group &optional server dont-check _info) (let ((file-name-coding-system nnmail-pathname-coding-system)) (cond ((not (nnml-possibly-change-directory group server)) @@ -252,11 +252,11 @@ non-nil.") (t (nnmail-get-new-mail 'nnml 'nnml-save-incremental-nov nnml-directory nil)))) -(deffoo nnml-close-group (group &optional server) +(deffoo nnml-close-group (_group &optional _server) (setq nnml-article-file-alist nil) t) -(deffoo nnml-request-create-group (group &optional server args) +(deffoo nnml-request-create-group (group &optional server _args) (nnml-possibly-change-directory nil server) (nnmail-activate 'nnml) (cond @@ -283,7 +283,7 @@ non-nil.") (nnmail-save-active nnml-group-alist nnml-active-file) t)))) -(deffoo nnml-request-list (&optional server) +(deffoo nnml-request-list (&optional _server) (save-excursion (let ((nnmail-file-coding-system nnmail-active-file-coding-system) (file-name-coding-system nnmail-pathname-coding-system)) @@ -291,10 +291,10 @@ non-nil.") (setq nnml-group-alist (nnmail-get-active)) t)) -(deffoo nnml-request-newgroups (date &optional server) +(deffoo nnml-request-newgroups (_date &optional server) (nnml-request-list server)) -(deffoo nnml-request-list-newsgroups (&optional server) +(deffoo nnml-request-list-newsgroups (&optional _server) (save-excursion (nnmail-find-file nnml-newsgroups-file))) @@ -360,7 +360,7 @@ non-nil.") (nconc rest articles))) (deffoo nnml-request-move-article - (article group server accept-form &optional last move-is-internal) + (article group server accept-form &optional last _move-is-internal) (let ((buf (gnus-get-buffer-create " *nnml move*")) (file-name-coding-system nnmail-pathname-coding-system) result) @@ -374,7 +374,7 @@ non-nil.") nnml-article-file-alist) (with-current-buffer buf (insert-buffer-substring nntp-server-buffer) - (setq result (eval accept-form)) + (setq result (eval accept-form t)) (kill-buffer (current-buffer)) result)) (progn @@ -889,7 +889,7 @@ Unless no-active is non-nil, update the active file too." (let* ((dir (file-name-as-directory dir)) (nov (concat dir nnml-nov-file-name)) (nov-buffer (gnus-get-buffer-create " *nov*")) - chars file headers) + chars headers) ;; file (with-current-buffer nov-buffer ;; Init the nov buffer. (buffer-disable-undo) diff --git a/lisp/gnus/nnnil.el b/lisp/gnus/nnnil.el index 7d400791fa..36a8bc4581 100644 --- a/lisp/gnus/nnnil.el +++ b/lisp/gnus/nnnil.el @@ -1,4 +1,4 @@ -;;; nnnil.el --- empty backend for Gnus +;;; nnnil.el --- empty backend for Gnus -*- lexical-binding: t; -*- ;; This file is in the public domain. @@ -32,31 +32,31 @@ (defvar nnnil-status-string "") -(defun nnnil-retrieve-headers (articles &optional group server fetch-old) +(defun nnnil-retrieve-headers (_articles &optional _group _server _fetch-old) (with-current-buffer nntp-server-buffer (erase-buffer)) 'nov) -(defun nnnil-open-server (server &optional definitions) +(defun nnnil-open-server (_server &optional _definitions) t) -(defun nnnil-close-server (&optional server) +(defun nnnil-close-server (&optional _server) t) (defun nnnil-request-close () t) -(defun nnnil-server-opened (&optional server) +(defun nnnil-server-opened (&optional _server) t) -(defun nnnil-status-message (&optional server) +(defun nnnil-status-message (&optional _server) nnnil-status-string) -(defun nnnil-request-article (article &optional group server to-buffer) +(defun nnnil-request-article (_article &optional _group _server _to-buffer) (setq nnnil-status-string "No such group") nil) -(defun nnnil-request-group (group &optional server fast info) +(defun nnnil-request-group (_group &optional _server _fast _info) (let (deactivate-mark) (with-current-buffer nntp-server-buffer (erase-buffer) @@ -64,15 +64,15 @@ (setq nnnil-status-string "No such group") nil) -(defun nnnil-close-group (group &optional server) +(defun nnnil-close-group (_group &optional _server) t) -(defun nnnil-request-list (&optional server) +(defun nnnil-request-list (&optional _server) (with-current-buffer nntp-server-buffer (erase-buffer)) t) -(defun nnnil-request-post (&optional server) +(defun nnnil-request-post (&optional _server) (setq nnnil-status-string "Read-only server") nil) diff --git a/lisp/gnus/nnoo.el b/lisp/gnus/nnoo.el index 39469d140d..2260fd694e 100644 --- a/lisp/gnus/nnoo.el +++ b/lisp/gnus/nnoo.el @@ -1,4 +1,4 @@ -;;; nnoo.el --- OO Gnus Backends +;;; nnoo.el --- OO Gnus Backends -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. @@ -257,7 +257,7 @@ nnoo-state-alist)) t) -(defun nnoo-status-message (backend server) +(defun nnoo-status-message (backend _server) (nnheader-get-report backend)) (defun nnoo-server-opened (backend server) diff --git a/lisp/gnus/nnregistry.el b/lisp/gnus/nnregistry.el index e78f93d829..15e41e9d42 100644 --- a/lisp/gnus/nnregistry.el +++ b/lisp/gnus/nnregistry.el @@ -1,5 +1,4 @@ -;;; nnregistry.el --- access to articles via Gnus' message-id registry -;;; -*- coding: utf-8 -*- +;;; nnregistry.el --- access to articles via Gnus' message-id registry -*- lexical-binding: t; -*- ;; Copyright (C) 2010-2021 Free Software Foundation, Inc. @@ -36,21 +35,21 @@ (nnoo-declare nnregistry) -(deffoo nnregistry-server-opened (server) +(deffoo nnregistry-server-opened (_server) gnus-registry-enabled) -(deffoo nnregistry-close-server (server &optional defs) +(deffoo nnregistry-close-server (_server &optional _defs) t) -(deffoo nnregistry-status-message (server) +(deffoo nnregistry-status-message (_server) nil) -(deffoo nnregistry-open-server (server &optional defs) +(deffoo nnregistry-open-server (_server &optional _defs) gnus-registry-enabled) (defvar nnregistry-within-nnregistry nil) -(deffoo nnregistry-request-article (id &optional group server buffer) +(deffoo nnregistry-request-article (id &optional _group _server buffer) (and (not nnregistry-within-nnregistry) (let* ((nnregistry-within-nnregistry t) (group (nth 0 (gnus-registry-get-id-key id 'group))) diff --git a/lisp/gnus/nnrss.el b/lisp/gnus/nnrss.el index b62a6412e5..aa7c8e584a 100644 --- a/lisp/gnus/nnrss.el +++ b/lisp/gnus/nnrss.el @@ -1,4 +1,4 @@ -;;; nnrss.el --- interfacing with RSS +;;; nnrss.el --- interfacing with RSS -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. @@ -125,7 +125,7 @@ for decoding when the cdr that the data specify is not available.") (setq group (decode-coding-string group 'utf-8)) group)) -(deffoo nnrss-retrieve-headers (articles &optional group server fetch-old) +(deffoo nnrss-retrieve-headers (articles &optional group server _fetch-old) (setq group (nnrss-decode-group-name group)) (nnrss-possibly-change-group group server) (let (e) @@ -173,7 +173,7 @@ for decoding when the cdr that the data specify is not available.") "\n"))))) 'nov) -(deffoo nnrss-request-group (group &optional server dont-check info) +(deffoo nnrss-request-group (group &optional server dont-check _info) (setq group (nnrss-decode-group-name group)) (nnheader-message 6 "nnrss: Requesting %s..." group) (nnrss-possibly-change-group group server) @@ -188,7 +188,7 @@ for decoding when the cdr that the data specify is not available.") t)) (nnheader-message 6 "nnrss: Requesting %s...done" group))) -(deffoo nnrss-close-group (group &optional server) +(deffoo nnrss-close-group (_group &optional _server) t) (deffoo nnrss-request-article (article &optional group server buffer) @@ -200,7 +200,7 @@ for decoding when the cdr that the data specify is not available.") (nnrss-possibly-change-group group server) (let ((e (assq article nnrss-group-data)) (nntp-server-buffer (or buffer nntp-server-buffer)) - post err) + err) ;; post (when e (with-current-buffer nntp-server-buffer (erase-buffer) @@ -222,7 +222,7 @@ for decoding when the cdr that the data specify is not available.") (cons '("Newsgroups" . utf-8) rfc2047-header-encoding-alist) rfc2047-header-encoding-alist)) - rfc2047-encode-encoded-words body fn) + rfc2047-encode-encoded-words body) ;; fn (when (or text link enclosure comments) (insert "\n") (insert "<#multipart type=alternative>\n" @@ -311,7 +311,7 @@ for decoding when the cdr that the data specify is not available.") ;; we return the article number. (cons nnrss-group (car e)))))) -(deffoo nnrss-open-server (server &optional defs connectionless) +(deffoo nnrss-open-server (server &optional defs _connectionless) (nnrss-read-server-data server) (nnoo-change-server 'nnrss server defs) t) @@ -335,7 +335,7 @@ for decoding when the cdr that the data specify is not available.") (nnrss-save-group-data group server)) not-expirable)) -(deffoo nnrss-request-delete-group (group &optional force server) +(deffoo nnrss-request-delete-group (group &optional _force server) (setq group (nnrss-decode-group-name group)) (nnrss-possibly-change-group group server) (let (elem) @@ -561,7 +561,7 @@ which RSS 2.0 allows." ;;; URL interface -(defun nnrss-no-cache (url) +(defun nnrss-no-cache (_url) "") (defun nnrss-insert (url) @@ -613,7 +613,7 @@ which RSS 2.0 allows." (defun nnrss-check-group (group server) (let (file xml subject url extra changed author date feed-subject - enclosure comments rss-ns rdf-ns content-ns dc-ns + enclosure comments rss-ns content-ns dc-ns ;; rdf-ns hash-index) (if (and nnrss-use-local (file-exists-p (setq file (expand-file-name @@ -637,7 +637,7 @@ which RSS 2.0 allows." (setq changed t)) (setq xml (nnrss-fetch url))) (setq dc-ns (nnrss-get-namespace-prefix xml "http://purl.org/dc/elements/1.1/") - rdf-ns (nnrss-get-namespace-prefix xml "http://www.w3.org/1999/02/22-rdf-syntax-ns#") + ;; rdf-ns (nnrss-get-namespace-prefix xml "http://www.w3.org/1999/02/22-rdf-syntax-ns#") rss-ns (nnrss-get-namespace-prefix xml "http://purl.org/rss/1.0/") content-ns (nnrss-get-namespace-prefix xml "http://purl.org/rss/1.0/modules/content/")) (dolist (item (nreverse (nnrss-find-el (intern (concat rss-ns "item")) xml))) diff --git a/lisp/gnus/nnspool.el b/lisp/gnus/nnspool.el index cb85417856..ce9ab3c53c 100644 --- a/lisp/gnus/nnspool.el +++ b/lisp/gnus/nnspool.el @@ -1,4 +1,4 @@ -;;; nnspool.el --- spool access for GNU Emacs +;;; nnspool.el --- spool access for GNU Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 1988-1990, 1993-1998, 2000-2021 Free Software ;; Foundation, Inc. @@ -126,7 +126,7 @@ there.") (nnoo-define-basics nnspool) -(deffoo nnspool-retrieve-headers (articles &optional group server fetch-old) +(deffoo nnspool-retrieve-headers (articles &optional group _server fetch-old) "Retrieve the headers of ARTICLES." (with-current-buffer nntp-server-buffer (erase-buffer) @@ -203,7 +203,7 @@ there.") server nnspool-spool-directory) t))) -(deffoo nnspool-request-article (id &optional group server buffer) +(deffoo nnspool-request-article (id &optional group _server buffer) "Select article by message ID (or number)." (nnspool-possibly-change-directory group) (let ((nntp-server-buffer (or buffer nntp-server-buffer)) @@ -222,7 +222,7 @@ there.") (cons nnspool-current-group id) ag)))) -(deffoo nnspool-request-body (id &optional group server) +(deffoo nnspool-request-body (id &optional group _server) "Select article body by message ID (or number)." (nnspool-possibly-change-directory group) (let ((res (nnspool-request-article id))) @@ -233,7 +233,7 @@ there.") (delete-region (point-min) (point))) res)))) -(deffoo nnspool-request-head (id &optional group server) +(deffoo nnspool-request-head (id &optional group _server) "Select article head by message ID (or number)." (nnspool-possibly-change-directory group) (let ((res (nnspool-request-article id))) @@ -245,7 +245,7 @@ there.") (nnheader-fold-continuation-lines))) res)) -(deffoo nnspool-request-group (group &optional server dont-check info) +(deffoo nnspool-request-group (group &optional _server dont-check _info) "Select news GROUP." (let ((pathname (nnspool-article-pathname group)) dir) @@ -269,26 +269,26 @@ there.") (nnheader-report 'nnspool "Empty group %s" group) (nnheader-insert "211 0 0 0 %s\n" group)))))) -(deffoo nnspool-request-type (group &optional article) +(deffoo nnspool-request-type (_group &optional _article) 'news) -(deffoo nnspool-close-group (group &optional server) +(deffoo nnspool-close-group (_group &optional _server) t) -(deffoo nnspool-request-list (&optional server) +(deffoo nnspool-request-list (&optional _server) "List active newsgroups." (save-excursion (or (nnspool-find-file nnspool-active-file) (nnheader-report 'nnspool (nnheader-file-error nnspool-active-file))))) -(deffoo nnspool-request-list-newsgroups (&optional server) +(deffoo nnspool-request-list-newsgroups (&optional _server) "List newsgroups (defined in NNTP2)." (save-excursion (or (nnspool-find-file nnspool-newsgroups-file) (nnheader-report 'nnspool (nnheader-file-error nnspool-newsgroups-file))))) -(deffoo nnspool-request-list-distributions (&optional server) +(deffoo nnspool-request-list-distributions (&optional _server) "List distributions (defined in NNTP2)." (save-excursion (or (nnspool-find-file nnspool-distributions-file) @@ -296,7 +296,7 @@ there.") nnspool-distributions-file))))) ;; Suggested by Hallvard B Furuseth . -(deffoo nnspool-request-newgroups (date &optional server) +(deffoo nnspool-request-newgroups (date &optional _server) "List groups created after DATE." (if (nnspool-find-file nnspool-active-times-file) (save-excursion @@ -323,7 +323,7 @@ there.") t) nil)) -(deffoo nnspool-request-post (&optional server) +(deffoo nnspool-request-post (&optional _server) "Post a new news in current buffer." (save-excursion (let* ((process-connection-type nil) ; t bugs out on Solaris @@ -356,7 +356,7 @@ there.") ;;; Internal functions. -(defun nnspool-inews-sentinel (proc status) +(defun nnspool-inews-sentinel (proc _status) (with-current-buffer (process-buffer proc) (goto-char (point-min)) (if (or (zerop (buffer-size)) diff --git a/lisp/gnus/nntp.el b/lisp/gnus/nntp.el index cf89eebbbb..1eb604d675 100644 --- a/lisp/gnus/nntp.el +++ b/lisp/gnus/nntp.el @@ -1330,7 +1330,7 @@ If SEND-IF-FORCE, only send authinfo to the server if the (dolist (entry nntp-server-action-alist) (when (string-match (car entry) nntp-server-type) (if (not (functionp (cadr entry))) - (eval (cadr entry)) + (eval (cadr entry) t) (funcall (cadr entry))))))) (defun nntp-async-wait (process wait-for buffer decode callback) diff --git a/lisp/gnus/nnvirtual.el b/lisp/gnus/nnvirtual.el index 902df868f8..b3b701e412 100644 --- a/lisp/gnus/nnvirtual.el +++ b/lisp/gnus/nnvirtual.el @@ -1,4 +1,4 @@ -;;; nnvirtual.el --- virtual newsgroups access for Gnus +;;; nnvirtual.el --- virtual newsgroups access for Gnus -*- lexical-binding: t; -*- ;; Copyright (C) 1994-2021 Free Software Foundation, Inc. @@ -94,8 +94,8 @@ It is computed from the marks of individual component groups.") (nnoo-define-basics nnvirtual) -(deffoo nnvirtual-retrieve-headers (articles &optional newsgroup - server fetch-old) +(deffoo nnvirtual-retrieve-headers (articles &optional _newsgroup + server _fetch-old) (when (nnvirtual-possibly-change-server server) (with-current-buffer nntp-server-buffer (erase-buffer) @@ -186,7 +186,7 @@ It is computed from the marks of individual component groups.") (defvoo nnvirtual-last-accessed-component-group nil) -(deffoo nnvirtual-request-article (article &optional group server buffer) +(deffoo nnvirtual-request-article (article &optional _group server buffer) (when (nnvirtual-possibly-change-server server) (if (stringp article) ;; This is a fetch by Message-ID. @@ -250,7 +250,7 @@ It is computed from the marks of individual component groups.") t))) -(deffoo nnvirtual-request-group (group &optional server dont-check info) +(deffoo nnvirtual-request-group (group &optional server dont-check _info) (nnvirtual-possibly-change-server server) (setq nnvirtual-component-groups (delete (nnvirtual-current-group) nnvirtual-component-groups)) @@ -269,7 +269,7 @@ It is computed from the marks of individual component groups.") nnvirtual-mapping-len nnvirtual-mapping-len group)))) -(deffoo nnvirtual-request-type (group &optional article) +(deffoo nnvirtual-request-type (_group &optional article) (if (not article) 'unknown (if (numberp article) @@ -279,7 +279,7 @@ It is computed from the marks of individual component groups.") (gnus-request-type nnvirtual-last-accessed-component-group nil)))) -(deffoo nnvirtual-request-update-mark (group article mark) +(deffoo nnvirtual-request-update-mark (_group article mark) (let* ((nart (nnvirtual-map-article article)) (cgroup (car nart))) (when (and nart @@ -291,22 +291,22 @@ It is computed from the marks of individual component groups.") mark) -(deffoo nnvirtual-close-group (group &optional server) +(deffoo nnvirtual-close-group (_group &optional server) (when (and (nnvirtual-possibly-change-server server) (not (gnus-ephemeral-group-p (nnvirtual-current-group)))) (nnvirtual-update-read-and-marked t t)) t) -(deffoo nnvirtual-request-newgroups (date &optional server) +(deffoo nnvirtual-request-newgroups (_date &optional _server) (nnheader-report 'nnvirtual "NEWGROUPS is not supported.")) -(deffoo nnvirtual-request-list-newsgroups (&optional server) +(deffoo nnvirtual-request-list-newsgroups (&optional _server) (nnheader-report 'nnvirtual "LIST NEWSGROUPS is not implemented.")) -(deffoo nnvirtual-request-update-info (group info &optional server) +(deffoo nnvirtual-request-update-info (_group info &optional server) (when (and (nnvirtual-possibly-change-server server) (not nnvirtual-info-installed)) ;; Install the precomputed lists atomically, so the virtual group @@ -321,7 +321,7 @@ It is computed from the marks of individual component groups.") t)) -(deffoo nnvirtual-catchup-group (group &optional server all) +(deffoo nnvirtual-catchup-group (_group &optional server all) (when (and (nnvirtual-possibly-change-server server) (not (gnus-ephemeral-group-p (nnvirtual-current-group)))) ;; copy over existing marks first, in case they set anything @@ -339,12 +339,12 @@ It is computed from the marks of individual component groups.") (gnus-group-catchup-current nil all))))) -(deffoo nnvirtual-find-group-art (group article) +(deffoo nnvirtual-find-group-art (_group article) "Return the real group and article for virtual GROUP and ARTICLE." (nnvirtual-map-article article)) -(deffoo nnvirtual-request-post (&optional server) +(deffoo nnvirtual-request-post (&optional _server) (if (not gnus-message-group-art) (nnheader-report 'nnvirtual "Can't post to an nnvirtual group") (let ((group (car (nnvirtual-find-group-art @@ -353,8 +353,8 @@ It is computed from the marks of individual component groups.") (gnus-request-post (gnus-find-method-for-group group))))) -(deffoo nnvirtual-request-expire-articles (articles group - &optional server force) +(deffoo nnvirtual-request-expire-articles ( _articles _group + &optional server _force) (nnvirtual-possibly-change-server server) (setq nnvirtual-component-groups (delete (nnvirtual-current-group) nnvirtual-component-groups)) diff --git a/lisp/gnus/nnweb.el b/lisp/gnus/nnweb.el index dd71bea72e..f08dc47e31 100644 --- a/lisp/gnus/nnweb.el +++ b/lisp/gnus/nnweb.el @@ -1,4 +1,4 @@ -;;; nnweb.el --- retrieving articles via web search engines +;;; nnweb.el --- retrieving articles via web search engines -*- lexical-binding: t; -*- ;; Copyright (C) 1996-2021 Free Software Foundation, Inc. @@ -96,7 +96,7 @@ Valid types include `google', `dejanews', and `gmane'.") (nnoo-define-basics nnweb) -(deffoo nnweb-retrieve-headers (articles &optional group server fetch-old) +(deffoo nnweb-retrieve-headers (articles &optional group server _fetch-old) (nnweb-possibly-change-server group server) (with-current-buffer nntp-server-buffer (erase-buffer) @@ -117,7 +117,7 @@ Valid types include `google', `dejanews', and `gmane'.") (nnweb-write-active) (nnweb-write-overview group))) -(deffoo nnweb-request-group (group &optional server dont-check info) +(deffoo nnweb-request-group (group &optional server dont-check _info) (nnweb-possibly-change-server group server) (unless (or nnweb-ephemeral-p dont-check @@ -156,7 +156,7 @@ Valid types include `google', `dejanews', and `gmane'.") (let ((fetch (nnweb-definition 'id)) (art (when (string-match "^<\\(.*\\)>$" article) (match-string 1 article))) - active) + ) ;; active (when (and fetch art) (setq url (format fetch (mm-url-form-encode-xwfu art))) @@ -184,19 +184,19 @@ Valid types include `google', `dejanews', and `gmane'.") (nnmail-generate-active (list (assoc server nnweb-group-alist))) t)) -(deffoo nnweb-request-update-info (group info &optional server)) +(deffoo nnweb-request-update-info (_group _info &optional _server)) (deffoo nnweb-asynchronous-p () nil) -(deffoo nnweb-request-create-group (group &optional server args) +(deffoo nnweb-request-create-group (group &optional server _args) (nnweb-possibly-change-server nil server) (nnweb-request-delete-group group) (push `(,group ,(cons 1 0)) nnweb-group-alist) (nnweb-write-active) t) -(deffoo nnweb-request-delete-group (group &optional force server) +(deffoo nnweb-request-delete-group (group &optional _force server) (nnweb-possibly-change-server group server) (gnus-alist-pull group nnweb-group-alist t) (nnweb-write-active) @@ -317,7 +317,7 @@ Valid types include `google', `dejanews', and `gmane'.") (let ((i 0) (case-fold-search t) (active (cadr (assoc nnweb-group nnweb-group-alist))) - Subject Score Date Newsgroups From + Subject Date Newsgroups From map url mid) (unless active (push (list nnweb-group (setq active (cons 1 0))) diff --git a/lisp/gnus/score-mode.el b/lisp/gnus/score-mode.el index b8726c03c3..d3ed3600ad 100644 --- a/lisp/gnus/score-mode.el +++ b/lisp/gnus/score-mode.el @@ -1,4 +1,4 @@ -;;; score-mode.el --- mode for editing Gnus score files +;;; score-mode.el --- mode for editing Gnus score files -*- lexical-binding: t; -*- ;; Copyright (C) 1996, 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/smiley.el b/lisp/gnus/smiley.el index 9884bcc075..3ee59479cf 100644 --- a/lisp/gnus/smiley.el +++ b/lisp/gnus/smiley.el @@ -1,4 +1,4 @@ -;;; smiley.el --- displaying smiley faces +;;; smiley.el --- displaying smiley faces -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/spam-report.el b/lisp/gnus/spam-report.el index 11d653d537..d87a6c2af0 100644 --- a/lisp/gnus/spam-report.el +++ b/lisp/gnus/spam-report.el @@ -1,4 +1,4 @@ -;;; spam-report.el --- Reporting spam +;;; spam-report.el --- Reporting spam -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. diff --git a/lisp/gnus/spam-stat.el b/lisp/gnus/spam-stat.el index 1980bd1d74..70753cad9c 100644 --- a/lisp/gnus/spam-stat.el +++ b/lisp/gnus/spam-stat.el @@ -1,4 +1,4 @@ -;;; spam-stat.el --- detecting spam based on statistics +;;; spam-stat.el --- detecting spam based on statistics -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. @@ -251,9 +251,6 @@ Use `spam-stat-ngood', `spam-stat-nbad', `spam-stat-good', (defvar spam-stat-nbad 0 "The number of bad mails in the dictionary.") -(defvar spam-stat-error-holder nil - "A holder for condition-case errors while scoring buffers.") - (defsubst spam-stat-good (entry) "Return the number of times this word belongs to good mails." (aref entry 0)) @@ -477,8 +474,8 @@ The default score for unknown words is stored in These are the words whose spam-stat differs the most from 0.5. The list returned contains elements of the form \(WORD SCORE DIFF), where DIFF is the difference between SCORE and 0.5." - (let (result word score) - (maphash (lambda (word ignore) + (let (result score) ;; word + (maphash (lambda (word _ignore) (setq score (spam-stat-score-word word) result (cons (list word score (abs (- score 0.5))) result))) @@ -498,8 +495,7 @@ Add user supplied modifications if supplied." (/ prod (+ prod (apply #'* (mapcar #'(lambda (x) (- 1 x)) probs))))) (score1s - (condition-case - spam-stat-error-holder + (condition-case nil (spam-stat-score-buffer-user score0) (error nil))) (ans @@ -522,7 +518,7 @@ Add user supplied modifications if supplied." Use this function on `nnmail-split-fancy'. If you are interested in the raw data used for the last run of `spam-stat-score-buffer', check the variable `spam-stat-score-data'." - (condition-case spam-stat-error-holder + (condition-case err (progn (set-buffer spam-stat-buffer) (goto-char (point-min)) @@ -532,7 +528,7 @@ check the variable `spam-stat-score-data'." (push entry nnmail-split-trace)) spam-stat-score-data)) spam-stat-split-fancy-spam-group)) - (error (message "Error in spam-stat-split-fancy: %S" spam-stat-error-holder) + (error (message "Error in spam-stat-split-fancy: %S" err) nil))) ;; Testing diff --git a/lisp/gnus/spam-wash.el b/lisp/gnus/spam-wash.el index 1c755fb464..bb2a1b97ad 100644 --- a/lisp/gnus/spam-wash.el +++ b/lisp/gnus/spam-wash.el @@ -1,4 +1,4 @@ -;;; spam-wash.el --- wash spam before analysis +;;; spam-wash.el --- wash spam before analysis -*- lexical-binding: t; -*- ;; Copyright (C) 2004, 2007-2021 Free Software Foundation, Inc. @@ -43,7 +43,7 @@ (handles (or (mm-dissect-buffer nil gnus-article-loose-mime) (and gnus-article-emulate-mime (mm-uu-dissect)))) - handle) + ) ;; handle (when gnus-article-mime-handles (mm-destroy-parts gnus-article-mime-handles) (setq gnus-article-mime-handle-alist nil)) diff --git a/lisp/gnus/spam.el b/lisp/gnus/spam.el index 00dcd00cea..f7288c98f6 100644 --- a/lisp/gnus/spam.el +++ b/lisp/gnus/spam.el @@ -1,4 +1,4 @@ -;;; spam.el --- Identifying spam +;;; spam.el --- Identifying spam -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. @@ -1387,7 +1387,7 @@ In the case of mover backends, checks the setting of (gnus-check-backend-function 'request-move-article gnus-newsgroup-name)) (respool-method (gnus-find-method-for-group gnus-newsgroup-name)) - article mark deletep respool valid-move-destinations) + deletep respool valid-move-destinations) ;; article mark (when (member 'respool groups) (setq respool t) ; boolean for later @@ -1807,7 +1807,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (log-function (if unregister 'spam-log-undo-registration 'spam-log-processing-to-registry)) - article articles) + articles) ;; article (when run-function ;; make list of articles, using specific-articles if given @@ -1910,7 +1910,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." ;; undo a ham- or spam-processor registration (the group is not used) (defun spam-log-undo-registration (id type classification backend - &optional group) + &optional _group) (when (and spam-log-to-registry (spam-log-unregistration-needed-p id type classification backend)) (if (and (stringp id) @@ -1918,7 +1918,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (spam-classification-valid-p classification) (spam-backend-valid-p backend)) (let ((cell-list (gnus-registry-get-id-key id type)) - new-cell-list found) + new-cell-list) ;; found (dolist (cell cell-list) (unless (and (eq classification (nth 0 cell)) (eq backend (nth 1 cell))) @@ -2050,7 +2050,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (declare-function bbdb-create-internal "bbdb-com" (&rest spec)) ;; when the BBDB changes, we want to clear out our cache -(defun spam-clear-cache-BBDB (&rest immaterial) +(defun spam-clear-cache-BBDB (&rest _immaterial) (spam-clear-cache 'spam-use-BBDB)) (when (featurep 'bbdb-com) @@ -2150,7 +2150,7 @@ Uses `gnus-newsgroup-name' if category is nil (for ham registration)." (let ((category (or category gnus-newsgroup-name)) (add-or-delete-option (if unregister "-d" "-i")) (db (spam-get-ifile-database-parameter)) - parameters) + ) ;; parameters (with-temp-buffer (dolist (article articles) (let ((article-string (spam-get-article-as-string article))) @@ -2184,7 +2184,7 @@ Uses `gnus-newsgroup-name' if category is nil (for ham registration)." "Check the spam-stat backend for the classification of this message." (let ((spam-stat-split-fancy-spam-group spam-split-group) ; override (spam-stat-buffer (buffer-name)) ; stat the current buffer - category return) + ) ;; category return (spam-stat-split-fancy))) (defun spam-stat-register-spam-routine (articles &optional unregister) @@ -2335,7 +2335,7 @@ With a non-nil REMOVE, remove the ADDRESSES." (defun spam-from-listed-p (type) (let ((from (message-fetch-field "from")) - found) + ) ;; found (spam-filelist-check-cache type from))) (defun spam-filelist-register-routine (articles blacklist &optional unregister) @@ -2345,7 +2345,7 @@ With a non-nil REMOVE, remove the ADDRESSES." (if blacklist 'spam-enter-blacklist 'spam-enter-whitelist)) (remove-function (if blacklist 'spam-enter-whitelist 'spam-enter-blacklist)) - from addresses unregister-list article-unregister-list) + addresses unregister-list article-unregister-list) ;; from (dolist (article articles) (let ((from (spam-fetch-field-from-fast article)) (id (spam-fetch-field-message-id-fast article)) @@ -2562,13 +2562,13 @@ With a non-nil REMOVE, remove the ADDRESSES." (defun spam-spamoracle-learn-ham (articles &optional unregister) (spam-spamoracle-learn articles nil unregister)) -(defun spam-spamoracle-unlearn-ham (articles &optional unregister) +(defun spam-spamoracle-unlearn-ham (articles &optional _unregister) (spam-spamoracle-learn-ham articles t)) (defun spam-spamoracle-learn-spam (articles &optional unregister) (spam-spamoracle-learn articles t unregister)) -(defun spam-spamoracle-unlearn-spam (articles &optional unregister) +(defun spam-spamoracle-unlearn-spam (articles &optional _unregister) (spam-spamoracle-learn-spam articles t)) ;;}}} commit 9be4f41b4254c029fc328b10ecef4e71cd2ca024 Author: Stefan Monnier Date: Sat Jan 30 16:45:25 2021 -0500 * lisp/gnus: Misc simplifications found during conversion to lexical * lisp/gnus/nnoo.el (noo-import-1, nnoo-define-skeleton-1): Use `dolist`. (noo-map-functions, nnoo-define-basics): Directly emit the code rather than going through an intermediate function; this also avoids the use of `eval`. (noo-map-functions-1, nnoo-define-basics-1): Delete functions, folded into their corresponding macro. * lisp/gnus/gmm-utils.el (gmm-tool-bar-from-list): Demote `eval` to `symbol-value`. * lisp/gnus/gnus-art.el (gnus-button-handle-describe-key): Avoid `eval` since `kbd` is a function nowadays. (gnus-treat-part-number): Rename from `part-number`. (gnus-treat-total-parts): Rename from `total-parts`. (gnus-treat-article, gnus-treat-predicate): Adjust accordingly. * lisp/gnus/gnus-cache.el (gnus-agent-load-alist): Use `declare-function`. * lisp/gnus/gnus-group.el (gnus-cache-active-hashtb): Use `defvar`. (gnus-group-iterate): Make it a normal function since lexical scoping avoids the risk of name capture anyway. (gnus-group-delete-articles): Actually use the `oldp` arg. * lisp/gnus/gnus-html.el (gnus-html-wash-images): Fix debug message so it's emitted after the `url` var it prints is actually initialized. And avoid `setq` while we're at it. * lisp/gnus/gnus-msg.el (gnus-group-mail, gnus-group-news) (gnus-summary-mail-other-window, gnus-summary-news-other-window): Merge `let`s using `let*`. * lisp/gnus/gnus-spec.el (gnus-update-format-specifications): Tighten the scope of `buffer`, and tighten a regexp. (gnus-parse-simple-format): Reduce code duplication. * lisp/gnus/gnus-start.el (gnus-child-mode): Don't `defvar` it since we never use that variable and accordingly don't define it as a minor mode. * lisp/gnus/gnus-util.el (gnus-byte-compile): Simplify so it obeys `gnus-use-byte-compile` not just on the first call. (iswitchb-minibuffer-setup): Declare. * lisp/gnus/mail-source.el (mail-source-bind-1) (mail-source-bind-common-1): Use `mapcar`. (mail-source-set-common-1): Use `dolist`. (display-time-event-handler): Declare. * lisp/gnus/mml-smime.el (mml-smime-epg-verify): Reduce code duplication. * lisp/gnus/mml.el (mml-parse-1): Reduce code duplication. * lisp/gnus/mml2015.el (mml2015-epg-verify): Reduce code duplication. * lisp/gnus/nnmail.el (nnmail-get-split-group): Tighten regexp. (nnmail-split-it): Reduce code duplication. * lisp/gnus/nnweb.el (nnweb-request-article): Avoid `setq`. * lisp/gnus/spam.el (BBDB): Use the `noerror` arg of `require`, and define all the functions for BBDB regardless if the require succeeded. (spam-exists-in-BBDB-p): Don't inline, not worth it. diff --git a/lisp/gnus/gmm-utils.el b/lisp/gnus/gmm-utils.el index c64bfea7ca..3542587319 100644 --- a/lisp/gnus/gmm-utils.el +++ b/lisp/gnus/gmm-utils.el @@ -231,7 +231,7 @@ DEFAULT-MAP specifies the default key map for ICON-LIST." props))) t)) (if (symbolp icon-list) - (eval icon-list) + (symbol-value icon-list) icon-list)) map)) diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el index cb679b849f..9af19bd02c 100644 --- a/lisp/gnus/gnus-agent.el +++ b/lisp/gnus/gnus-agent.el @@ -735,7 +735,7 @@ be a select method." (interactive "P") (unless gnus-plugged (error "Groups can't be fetched when Gnus is unplugged")) - (gnus-group-iterate n 'gnus-agent-fetch-group)) + (gnus-group-iterate n #'gnus-agent-fetch-group)) (defun gnus-agent-fetch-group (&optional group) "Put all new articles in GROUP into the Agent." diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index 7e5439a217..4034d362af 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -7617,7 +7617,7 @@ Calls `describe-variable' or `describe-function'." "Call `describe-key' when pushing the corresponding URL button." (let* ((key-string (replace-regexp-in-string gnus-button-handle-describe-prefix "" url)) - (keys (ignore-errors (eval `(kbd ,key-string))))) + (keys (ignore-errors (kbd key-string)))) (if keys (describe-key keys) (gnus-message 3 "Invalid key sequence in button: %s" key-string)))) @@ -8516,8 +8516,8 @@ For example: (defvar gnus-inhibit-article-treatments nil) ;; Dynamic variables. -(defvar part-number) ;FIXME: Lacks a "gnus-" prefix. -(defvar total-parts) ;FIXME: Lacks a "gnus-" prefix. +(defvar gnus-treat-part-number) +(defvar gnus-treat-total-parts) (defvar gnus-treat-type) (defvar gnus-treat-condition) (defvar gnus-treat-length) @@ -8525,8 +8525,8 @@ For example: (defun gnus-treat-article (condition &optional part-num total type) (let ((gnus-treat-condition condition) - (part-number part-num) - (total-parts total) + (gnus-treat-part-number part-num) + (gnus-treat-total-parts total) (gnus-treat-type type) (gnus-treat-length (- (point-max) (point-min))) (alist gnus-treatment-function-alist) @@ -8586,9 +8586,9 @@ For example: ((eq val 'head) nil) ((eq val 'first) - (eq part-number 1)) + (eq gnus-treat-part-number 1)) ((eq val 'last) - (eq part-number total-parts)) + (eq gnus-treat-part-number gnus-treat-total-parts)) ((numberp val) (< gnus-treat-length val)) (t diff --git a/lisp/gnus/gnus-cache.el b/lisp/gnus/gnus-cache.el index bea3d3bf03..b17a11276c 100644 --- a/lisp/gnus/gnus-cache.el +++ b/lisp/gnus/gnus-cache.el @@ -29,9 +29,7 @@ (require 'gnus) (require 'gnus-sum) -(eval-when-compile - (unless (fboundp 'gnus-agent-load-alist) - (defun gnus-agent-load-alist (group)))) +(declare-function gnus-agent-load-alist "gnus-agent" (group)) (defcustom gnus-cache-active-file (expand-file-name "active" gnus-cache-directory) @@ -55,7 +53,7 @@ If you only want to cache your nntp groups, you could set this variable to \"^nntp\". -If a group matches both gnus-cacheable-groups and gnus-uncacheable-groups +If a group matches both `gnus-cacheable-groups' and `gnus-uncacheable-groups' it's not cached." :group 'gnus-cache :type '(choice (const :tag "off" nil) diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index a165752881..0444b05450 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el @@ -40,9 +40,9 @@ (require 'mm-url) (require 'subr-x) (let ((features (cons 'gnus-group features))) - (require 'gnus-sum)) - (unless (boundp 'gnus-cache-active-hashtb) - (defvar gnus-cache-active-hashtb nil))) + (require 'gnus-sum))) + +(defvar gnus-cache-active-hashtb) (defvar tool-bar-mode) @@ -505,7 +505,8 @@ simple manner." (+ number (gnus-range-length (cdr (assq 'dormant gnus-tmp-marked))) (gnus-range-length (cdr (assq 'tick gnus-tmp-marked)))))) - (t number)) ?s) + (t number)) + ?s) (?R gnus-tmp-number-of-read ?s) (?U (if (gnus-active gnus-tmp-group) (gnus-number-of-unseen-articles-in-group gnus-tmp-group) @@ -516,7 +517,8 @@ simple manner." (?I (gnus-range-length (cdr (assq 'dormant gnus-tmp-marked))) ?d) (?T (gnus-range-length (cdr (assq 'tick gnus-tmp-marked))) ?d) (?i (+ (gnus-range-length (cdr (assq 'dormant gnus-tmp-marked))) - (gnus-range-length (cdr (assq 'tick gnus-tmp-marked)))) ?d) + (gnus-range-length (cdr (assq 'tick gnus-tmp-marked)))) + ?d) (?g gnus-tmp-group ?s) (?G gnus-tmp-qualified-group ?s) (?c (gnus-short-group-name gnus-tmp-group) @@ -1541,7 +1543,8 @@ if it is a string, only list groups matching REGEXP." (gnus-tmp-news-method-string (if gnus-tmp-method (format "(%s:%s)" (car gnus-tmp-method) - (cadr gnus-tmp-method)) "")) + (cadr gnus-tmp-method)) + "")) (gnus-tmp-marked-mark (if (and (numberp number) (zerop number) @@ -1985,31 +1988,18 @@ Take into consideration N (the prefix) and the list of marked groups." (let ((group (gnus-group-group-name))) (and group (list group)))))) -;;; !!!Surely gnus-group-iterate should be a macro instead? I can't -;;; imagine why I went through these contortions... -(eval-and-compile - (let ((function (make-symbol "gnus-group-iterate-function")) - (window (make-symbol "gnus-group-iterate-window")) - (groups (make-symbol "gnus-group-iterate-groups")) - (group (make-symbol "gnus-group-iterate-group"))) - (eval - `(defun gnus-group-iterate (arg ,function) - "Iterate FUNCTION over all process/prefixed groups. +(defun gnus-group-iterate (arg function) + "Iterate FUNCTION over all process/prefixed groups. FUNCTION will be called with the group name as the parameter and with point over the group in question." - (let ((,groups (gnus-group-process-prefix arg)) - (,window (selected-window)) - ,group) - (while ,groups - (setq ,group (car ,groups) - ,groups (cdr ,groups)) - (select-window ,window) - (gnus-group-remove-mark ,group) - (save-selected-window - (save-excursion - (funcall ,function ,group))))))))) - -(put 'gnus-group-iterate 'lisp-indent-function 1) + (declare (indent 1)) + (let ((window (selected-window))) + (dolist (group (gnus-group-process-prefix arg)) + (select-window window) + (gnus-group-remove-mark group) + (save-selected-window + (save-excursion + (funcall function group)))))) ;; Selecting groups. @@ -2807,7 +2797,7 @@ not-expirable articles, too." (format "Do you really want to delete these %d articles forever? " (length articles))) (gnus-request-expire-articles articles group - (if current-prefix-arg + (if oldp nil 'force))))) diff --git a/lisp/gnus/gnus-html.el b/lisp/gnus/gnus-html.el index 855d085c3a..6a0cc0b47d 100644 --- a/lisp/gnus/gnus-html.el +++ b/lisp/gnus/gnus-html.el @@ -151,7 +151,7 @@ fit these criteria." (defun gnus-html-wash-images () "Run through current buffer and replace img tags by images." - (let (tag parameters string start end images url alt-text + (let (tag parameters string start end images inhibit-images blocked-images) (if (buffer-live-p gnus-summary-buffer) (with-current-buffer gnus-summary-buffer @@ -169,65 +169,65 @@ fit these criteria." (delete-region (match-beginning 0) (match-end 0))) (setq end (point)) (when (string-match "src=\"\\([^\"]+\\)" parameters) - (gnus-message 8 "gnus-html-wash-tags: fetching image URL %s" url) - (setq url (gnus-html-encode-url (match-string 1 parameters)) - alt-text (when (string-match "\\(alt\\|title\\)=\"\\([^\"]+\\)" - parameters) - (xml-substitute-special (match-string 2 parameters)))) - (add-text-properties - start end - (list 'image-url url - 'image-displayer `(lambda (url start end) - (gnus-html-display-image url start end - ,alt-text)) - 'help-echo alt-text - 'button t - 'keymap gnus-html-image-map - 'gnus-image (list url start end alt-text))) - (if (string-match "\\`cid:" url) - ;; URLs with cid: have their content stashed in other - ;; parts of the MIME structure, so just insert them - ;; immediately. - (let* ((handle (mm-get-content-id (substring url (match-end 0)))) - (image (when (and handle - (not inhibit-images)) - (gnus-create-image - (mm-with-part handle (buffer-string)) - nil t)))) - (if image - (gnus-add-image - 'cid - (gnus-put-image - (gnus-rescale-image - image (gnus-html-maximum-image-size)) - (gnus-string-or (prog1 - (buffer-substring start end) - (delete-region start end)) - "*") - 'cid)) + (let ((url (gnus-html-encode-url (match-string 1 parameters))) + (alt-text (when (string-match "\\(alt\\|title\\)=\"\\([^\"]+\\)" + parameters) + (xml-substitute-special (match-string 2 parameters))))) + (gnus-message 8 "gnus-html-wash-tags: fetching image URL %s" url) + (add-text-properties + start end + (list 'image-url url + 'image-displayer `(lambda (url start end) + (gnus-html-display-image url start end + ,alt-text)) + 'help-echo alt-text + 'button t + 'keymap gnus-html-image-map + 'gnus-image (list url start end alt-text))) + (if (string-match "\\`cid:" url) + ;; URLs with cid: have their content stashed in other + ;; parts of the MIME structure, so just insert them + ;; immediately. + (let* ((handle (mm-get-content-id (substring url (match-end 0)))) + (image (when (and handle + (not inhibit-images)) + (gnus-create-image + (mm-with-part handle (buffer-string)) + nil t)))) + (if image + (gnus-add-image + 'cid + (gnus-put-image + (gnus-rescale-image + image (gnus-html-maximum-image-size)) + (gnus-string-or (prog1 + (buffer-substring start end) + (delete-region start end)) + "*") + 'cid)) + (make-text-button start end + 'help-echo url + 'keymap gnus-html-image-map))) + ;; Normal, external URL. + (if (or inhibit-images + (gnus-html-image-url-blocked-p url blocked-images)) (make-text-button start end 'help-echo url - 'keymap gnus-html-image-map))) - ;; Normal, external URL. - (if (or inhibit-images - (gnus-html-image-url-blocked-p url blocked-images)) - (make-text-button start end - 'help-echo url - 'keymap gnus-html-image-map) - ;; Non-blocked url - (let ((width - (when (string-match "width=\"?\\([0-9]+\\)" parameters) - (string-to-number (match-string 1 parameters)))) - (height - (when (string-match "height=\"?\\([0-9]+\\)" parameters) - (string-to-number (match-string 1 parameters))))) - ;; Don't fetch images that are really small. They're - ;; probably tracking pictures. - (when (and (or (null height) - (> height 4)) - (or (null width) - (> width 4))) - (gnus-html-display-image url start end alt-text))))))))) + 'keymap gnus-html-image-map) + ;; Non-blocked url + (let ((width + (when (string-match "width=\"?\\([0-9]+\\)" parameters) + (string-to-number (match-string 1 parameters)))) + (height + (when (string-match "height=\"?\\([0-9]+\\)" parameters) + (string-to-number (match-string 1 parameters))))) + ;; Don't fetch images that are really small. They're + ;; probably tracking pictures. + (when (and (or (null height) + (> height 4)) + (or (null width) + (> width 4))) + (gnus-html-display-image url start end alt-text)))))))))) (defun gnus-html-display-image (url start end &optional alt-text) "Display image at URL on text from START to END. diff --git a/lisp/gnus/gnus-msg.el b/lisp/gnus/gnus-msg.el index 9ca82f881a..49be704785 100644 --- a/lisp/gnus/gnus-msg.el +++ b/lisp/gnus/gnus-msg.el @@ -610,19 +610,19 @@ If ARG is 1, prompt for a group name to find the posting style." (interactive "P") ;; We can't `let' gnus-newsgroup-name here, since that leads ;; to local variables leaking. - (let ((group gnus-newsgroup-name) - ;; make sure last viewed article doesn't affect posting styles: - (gnus-article-copy) - (buffer (current-buffer))) - (let ((gnus-newsgroup-name - (if arg - (if (= 1 (prefix-numeric-value arg)) - (gnus-group-completing-read - "Use posting style of group" - nil (gnus-read-active-file-p)) - (gnus-group-group-name)) - ""))) - (gnus-setup-message 'message (message-mail))))) + (let* ((group gnus-newsgroup-name) + ;; make sure last viewed article doesn't affect posting styles: + (gnus-article-copy) + (buffer (current-buffer)) + (gnus-newsgroup-name + (if arg + (if (= 1 (prefix-numeric-value arg)) + (gnus-group-completing-read + "Use posting style of group" + nil (gnus-read-active-file-p)) + (gnus-group-group-name)) + ""))) + (gnus-setup-message 'message (message-mail)))) (defun gnus-group-news (&optional arg) "Start composing a news. @@ -635,21 +635,21 @@ network. The corresponding back end must have a `request-post' method." (interactive "P") ;; We can't `let' gnus-newsgroup-name here, since that leads ;; to local variables leaking. - (let ((group gnus-newsgroup-name) - ;; make sure last viewed article doesn't affect posting styles: - (gnus-article-copy) - (buffer (current-buffer))) - (let ((gnus-newsgroup-name - (if arg - (if (= 1 (prefix-numeric-value arg)) - (gnus-group-completing-read "Use group" - nil - (gnus-read-active-file-p)) - (gnus-group-group-name)) - ""))) - (gnus-setup-message - 'message - (message-news (gnus-group-real-name gnus-newsgroup-name)))))) + (let* ((group gnus-newsgroup-name) + ;; make sure last viewed article doesn't affect posting styles: + (gnus-article-copy) + (buffer (current-buffer)) + (gnus-newsgroup-name + (if arg + (if (= 1 (prefix-numeric-value arg)) + (gnus-group-completing-read "Use group" + nil + (gnus-read-active-file-p)) + (gnus-group-group-name)) + ""))) + (gnus-setup-message + 'message + (message-news (gnus-group-real-name gnus-newsgroup-name))))) (defun gnus-group-post-news (&optional arg) "Start composing a message (a news by default). @@ -678,19 +678,19 @@ posting style." (interactive "P") ;; We can't `let' gnus-newsgroup-name here, since that leads ;; to local variables leaking. - (let ((group gnus-newsgroup-name) - ;; make sure last viewed article doesn't affect posting styles: - (gnus-article-copy) - (buffer (current-buffer))) - (let ((gnus-newsgroup-name - (if arg - (if (= 1 (prefix-numeric-value arg)) - (gnus-group-completing-read "Use group" - nil - (gnus-read-active-file-p)) - "") - gnus-newsgroup-name))) - (gnus-setup-message 'message (message-mail))))) + (let* ((group gnus-newsgroup-name) + ;; make sure last viewed article doesn't affect posting styles: + (gnus-article-copy) + (buffer (current-buffer)) + (gnus-newsgroup-name + (if arg + (if (= 1 (prefix-numeric-value arg)) + (gnus-group-completing-read "Use group" + nil + (gnus-read-active-file-p)) + "") + gnus-newsgroup-name))) + (gnus-setup-message 'message (message-mail)))) (defun gnus-summary-news-other-window (&optional arg) "Start composing a news in another window. @@ -703,26 +703,26 @@ network. The corresponding back end must have a `request-post' method." (interactive "P") ;; We can't `let' gnus-newsgroup-name here, since that leads ;; to local variables leaking. - (let ((group gnus-newsgroup-name) - ;; make sure last viewed article doesn't affect posting styles: - (gnus-article-copy) - (buffer (current-buffer))) - (let ((gnus-newsgroup-name - (if arg - (if (= 1 (prefix-numeric-value arg)) - (gnus-group-completing-read "Use group" - nil - (gnus-read-active-file-p)) - "") - gnus-newsgroup-name))) - (gnus-setup-message - 'message - (progn - (message-news (gnus-group-real-name gnus-newsgroup-name)) - (setq-local gnus-discouraged-post-methods - (remove - (car (gnus-find-method-for-group gnus-newsgroup-name)) - gnus-discouraged-post-methods))))))) + (let* ((group gnus-newsgroup-name) + ;; make sure last viewed article doesn't affect posting styles: + (gnus-article-copy) + (buffer (current-buffer)) + (gnus-newsgroup-name + (if arg + (if (= 1 (prefix-numeric-value arg)) + (gnus-group-completing-read "Use group" + nil + (gnus-read-active-file-p)) + "") + gnus-newsgroup-name))) + (gnus-setup-message + 'message + (progn + (message-news (gnus-group-real-name gnus-newsgroup-name)) + (setq-local gnus-discouraged-post-methods + (remove + (car (gnus-find-method-for-group gnus-newsgroup-name)) + gnus-discouraged-post-methods)))))) (defun gnus-summary-post-news (&optional arg) "Start composing a message. Post to the current group by default. diff --git a/lisp/gnus/gnus-spec.el b/lisp/gnus/gnus-spec.el index 0dfa9f99d3..a50d9f3a5f 100644 --- a/lisp/gnus/gnus-spec.el +++ b/lisp/gnus/gnus-spec.el @@ -151,9 +151,9 @@ Return a list of updated types." (when (and (boundp buffer) (setq val (symbol-value buffer)) (gnus-buffer-live-p val)) - (set-buffer val)) - (setq new-format (symbol-value - (intern (format "gnus-%s-line-format" type))))) + (set-buffer val))) + (setq new-format (symbol-value + (intern (format "gnus-%s-line-format" type)))) (setq entry (cdr (assq type gnus-format-specs))) (if (and (car entry) (equal (car entry) new-format)) @@ -170,7 +170,7 @@ Return a list of updated types." new-format (symbol-value (intern (format "gnus-%s-line-format-alist" type))) - (not (string-match "mode$" (symbol-name type)))))) + (not (string-match "mode\\'" (symbol-name type)))))) ;; Enter the new format spec into the list. (if entry (progn @@ -526,13 +526,13 @@ or to characters when given a pad value." (if (eq spec ?%) ;; "%%" just results in a "%". (insert "%") - (cond - ;; Do tilde forms. - ((eq spec ?@) - (setq elem (list tilde-form ?s))) - ;; Treat user defined format specifiers specially. - (user-defined - (setq elem + (setq elem + (cond + ;; Do tilde forms. + ((eq spec ?@) + (list tilde-form ?s)) + ;; Treat user defined format specifiers specially. + (user-defined (list (list (intern (format (if (stringp user-defined) @@ -540,14 +540,14 @@ or to characters when given a pad value." "gnus-user-format-function-%c") user-defined)) 'gnus-tmp-header) - ?s))) - ;; Find the specification from `spec-alist'. - ((setq elem (cdr (assq (or extended-spec spec) spec-alist)))) - ;; We used to use "%l" for displaying the grouplens score. - ((eq spec ?l) - (setq elem '("" ?s))) - (t - (setq elem '("*" ?s)))) + ?s)) + ;; Find the specification from `spec-alist'. + ((cdr (assq (or extended-spec spec) spec-alist))) + ;; We used to use "%l" for displaying the grouplens score. + ((eq spec ?l) + '("" ?s)) + (t + '("*" ?s)))) (setq elem-type (cadr elem)) ;; Insert the new format elements. (when pad-width diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el index a3159595c4..1554635a3f 100644 --- a/lisp/gnus/gnus-start.el +++ b/lisp/gnus/gnus-start.el @@ -2337,7 +2337,7 @@ If FORCE is non-nil, the .newsrc file is read." gnus-newsrc-file-version gnus-version))))))) (defun gnus-convert-mark-converter-prompt (converter no-prompt) - "Indicate whether CONVERTER requires gnus-convert-old-newsrc to + "Indicate whether CONVERTER requires `gnus-convert-old-newsrc' to display the conversion prompt. NO-PROMPT may be nil (prompt), t (no prompt), or any form that can be called as a function. The form should return either t or nil." @@ -2989,13 +2989,12 @@ SPECIFIC-VARIABLES, or those in `gnus-variable-list'." ;;; Child functions. ;;; -(defvar gnus-child-mode nil) +;; (defvar gnus-child-mode nil) (defun gnus-child-mode () "Minor mode for child Gnusae." - ;; FIXME: gnus-child-mode appears to never be set (i.e. it'll always be nil): - ;; Remove, or fix and use define-minor-mode. - (add-minor-mode 'gnus-child-mode " Child" (make-sparse-keymap)) + ;; FIXME: gnus-child-mode appears to never be set (i.e. it'll always be nil). + ;; (add-minor-mode 'gnus-child-mode " Child" (make-sparse-keymap)) (gnus-run-hooks 'gnus-child-mode-hook)) (define-obsolete-function-alias 'gnus-slave-mode #'gnus-child-mode "28.1") diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el index b8451028d1..408293f1a1 100644 --- a/lisp/gnus/gnus-util.el +++ b/lisp/gnus/gnus-util.el @@ -1203,9 +1203,7 @@ ARG is passed to the first function." (string-equal (downcase x) (downcase y))))) (defcustom gnus-use-byte-compile t - "If non-nil, byte-compile crucial run-time code. -Setting it to nil has no effect after the first time `gnus-byte-compile' -is run." + "If non-nil, byte-compile crucial run-time code." :type 'boolean :version "22.1" :group 'gnus-various) @@ -1213,13 +1211,8 @@ is run." (defun gnus-byte-compile (form) "Byte-compile FORM if `gnus-use-byte-compile' is non-nil." (if gnus-use-byte-compile - (progn - (require 'bytecomp) - (defalias 'gnus-byte-compile - (lambda (form) - (let ((byte-compile-warnings '(unresolved callargs redefine))) - (byte-compile form)))) - (gnus-byte-compile form)) + (let ((byte-compile-warnings '(unresolved callargs redefine))) + (byte-compile form)) form)) (defun gnus-remassoc (key alist) @@ -1385,6 +1378,7 @@ SPEC is a predicate specifier that contains stuff like `or', `and', (declare-function iswitchb-read-buffer "iswitchb" (prompt &optional default require-match _predicate start matches-set)) +(declare-function iswitchb-minibuffer-setup "iswitchb") (defvar iswitchb-temp-buflist) (defvar iswitchb-mode) @@ -1449,7 +1443,8 @@ CHOICE is a list of the choice char and help message at IDX." prompt (concat (mapconcat (lambda (s) (char-to-string (car s))) - choice ", ") ", ?")) + choice ", ") + ", ?")) (setq tchar (read-char)) (when (not (assq tchar choice)) (setq tchar nil) diff --git a/lisp/gnus/gnus-uu.el b/lisp/gnus/gnus-uu.el index 2bc1f864de..e4aaf92c89 100644 --- a/lisp/gnus/gnus-uu.el +++ b/lisp/gnus/gnus-uu.el @@ -1949,6 +1949,7 @@ The user will be asked for a file name." (gnus-uu-choose-action file-name gnus-uu-ext-to-mime-list) file-name)) (insert (format "Content-Transfer-Encoding: %s\n\n" encoding)) + ;; FIXME: Shouldn't we set-buffer before saving the restriction? --Stef (save-restriction (set-buffer gnus-message-buffer) (goto-char (point-min)) diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el index 212657aec2..4f02d86f44 100644 --- a/lisp/gnus/mail-source.el +++ b/lisp/gnus/mail-source.el @@ -380,13 +380,10 @@ All keywords that can be used must be listed here.")) ;; suitable for usage in a `let' form (eval-and-compile (defun mail-source-bind-1 (type) - (let* ((defaults (cdr (assq type mail-source-keyword-map))) - default bind) - (while (setq default (pop defaults)) - (push (list (mail-source-strip-keyword (car default)) - nil) - bind)) - bind))) + (mapcar (lambda (default) + (list (mail-source-strip-keyword (car default)) + nil)) + (cdr (assq type mail-source-keyword-map))))) (defmacro mail-source-bind (type-source &rest body) "Return a `let' form that binds all variables in source TYPE. @@ -476,20 +473,16 @@ the `mail-source-keyword-map' variable." (eval-and-compile (defun mail-source-bind-common-1 () - (let* ((defaults mail-source-common-keyword-map) - default bind) - (while (setq default (pop defaults)) - (push (list (mail-source-strip-keyword (car default)) - nil) - bind)) - bind))) + (mapcar (lambda (default) + (list (mail-source-strip-keyword (car default)) + nil)) + mail-source-common-keyword-map))) (defun mail-source-set-common-1 (source) (let* ((type (pop source)) - (defaults mail-source-common-keyword-map) (defaults-1 (cdr (assq type mail-source-keyword-map))) - default value keyword) - (while (setq default (pop defaults)) + value keyword) + (dolist (default mail-source-common-keyword-map) (set (mail-source-strip-keyword (setq keyword (car default))) (if (setq value (plist-get source keyword)) (mail-source-value value) @@ -919,7 +912,7 @@ authentication. To do that, you need to set the `message-send-mail-function' variable as `message-smtpmail-send-it' and put the following line in your ~/.gnus.el file: -\(add-hook \\='message-send-mail-hook \\='mail-source-touch-pop) +\(add-hook \\='message-send-mail-hook #\\='mail-source-touch-pop) See the Gnus manual for details." (let ((sources (if mail-source-primary-source @@ -963,6 +956,8 @@ See the Gnus manual for details." ;; (element 0 of the vector is nil if the timer is active). (aset mail-source-report-new-mail-idle-timer 0 nil))) +(declare-function display-time-event-handler "time" ()) + (defun mail-source-report-new-mail (arg) "Toggle whether to report when new mail is available. This only works when `display-time' is enabled." @@ -1075,7 +1070,8 @@ This only works when `display-time' is enabled." (if (and (imap-open server port stream authentication buf) (imap-authenticate user (or (cdr (assoc from mail-source-password-cache)) - password) buf)) + password) + buf)) (let ((mailbox-list (if (listp mailbox) mailbox (list mailbox)))) (dolist (mailbox mailbox-list) (when (imap-mailbox-select mailbox nil buf) diff --git a/lisp/gnus/mm-partial.el b/lisp/gnus/mm-partial.el index 165c19139c..8d4913e6fb 100644 --- a/lisp/gnus/mm-partial.el +++ b/lisp/gnus/mm-partial.el @@ -39,7 +39,8 @@ gnus-newsgroup-name) (when (search-forward id nil t) (let ((nhandles (mm-dissect-buffer - nil gnus-article-loose-mime)) nid) + nil gnus-article-loose-mime)) + nid) (if (consp (car nhandles)) (mm-destroy-parts nhandles) (setq nid (cdr (assq 'id @@ -90,7 +91,7 @@ If NO-DISPLAY is nil, display it. Otherwise, do nothing after replacing." (if ntotal (if total (unless (eq total ntotal) - (error "The numbers of total are different")) + (error "The numbers of total are different")) (setq total ntotal))) (unless (< nn n) (unless (eq nn n) diff --git a/lisp/gnus/mm-util.el b/lisp/gnus/mm-util.el index 329b9e8884..be279b6cf1 100644 --- a/lisp/gnus/mm-util.el +++ b/lisp/gnus/mm-util.el @@ -144,9 +144,9 @@ is not available." ;; on there being some coding system matching each `mime-charset' ;; property defined, as there should be.) ((and (mm-coding-system-p charset) -;;; Doing this would potentially weed out incorrect charsets. -;;; charset -;;; (eq charset (coding-system-get charset 'mime-charset)) + ;; Doing this would potentially weed out incorrect charsets. + ;; charset + ;; (eq charset (coding-system-get charset 'mime-charset)) ) charset) ;; Use coding system Emacs knows. diff --git a/lisp/gnus/mml-smime.el b/lisp/gnus/mml-smime.el index e97e3e9a06..eabb56b303 100644 --- a/lisp/gnus/mml-smime.el +++ b/lisp/gnus/mml-smime.el @@ -369,7 +369,7 @@ Content-Disposition: attachment; filename=smime.p7s (goto-char (point-max))))) (defun mml-smime-epg-encrypt (cont) - (let* ((inhibit-redisplay t) + (let* ((inhibit-redisplay t) ;FIXME: Why? (boundary (mml-compute-boundary cont)) (cipher (mml-secure-epg-encrypt 'CMS cont))) (delete-region (point-min) (point-max)) @@ -410,9 +410,9 @@ Content-Disposition: attachment; filename=smime.p7m (setq plain (epg-verify-string context (mm-get-part signature) part)) (error (mm-sec-error 'gnus-info "Failed") - (if (eq (car error) 'quit) - (mm-sec-status 'gnus-details "Quit.") - (mm-sec-status 'gnus-details (format "%S" error))) + (mm-sec-status 'gnus-details (if (eq (car error) 'quit) + "Quit." + (format "%S" error))) (throw 'error handle))) (mm-sec-status 'gnus-info diff --git a/lisp/gnus/mml.el b/lisp/gnus/mml.el index acde958c05..54f8715baf 100644 --- a/lisp/gnus/mml.el +++ b/lisp/gnus/mml.el @@ -241,22 +241,24 @@ part. This is for the internal use, you should never modify the value.") (method (cdr (assq 'method taginfo))) tags) (save-excursion - (if (re-search-forward - "<#/?\\(multipart\\|part\\|external\\|mml\\)." nil t) - (setq secure-mode "multipart") - (setq secure-mode "part"))) + (setq secure-mode + (if (re-search-forward + "<#/?\\(multipart\\|part\\|external\\|mml\\)." + nil t) + "multipart" + "part"))) (save-excursion (goto-char location) (re-search-forward "<#secure[^\n]*>\n")) (delete-region (match-beginning 0) (match-end 0)) - (cond ((string= mode "sign") - (setq tags (list "sign" method))) - ((string= mode "encrypt") - (setq tags (list "encrypt" method))) - ((string= mode "signencrypt") - (setq tags (list "sign" method "encrypt" method))) - (t - (error "Unknown secure mode %s" mode))) + (setq tags (cond ((string= mode "sign") + (list "sign" method)) + ((string= mode "encrypt") + (list "encrypt" method)) + ((string= mode "signencrypt") + (list "sign" method "encrypt" method)) + (t + (error "Unknown secure mode %s" mode)))) (eval `(mml-insert-tag ,secure-mode ,@tags ,(if keyfile "keyfile") @@ -1598,7 +1600,8 @@ or the `pop-to-buffer' function." (interactive "P") (setq mml-preview-buffer (generate-new-buffer (concat (if raw "*Raw MIME preview of " - "*MIME preview of ") (buffer-name)))) + "*MIME preview of ") + (buffer-name)))) (require 'gnus-msg) ; for gnus-setup-posting-charset (save-excursion (let* ((buf (current-buffer)) @@ -1655,7 +1658,8 @@ or the `pop-to-buffer' function." (use-local-map nil) (add-hook 'kill-buffer-hook (lambda () - (mm-destroy-parts gnus-article-mime-handles)) nil t) + (mm-destroy-parts gnus-article-mime-handles)) + nil t) (setq buffer-read-only t) (local-set-key "q" (lambda () (interactive) (kill-buffer nil))) (local-set-key "=" (lambda () (interactive) (delete-other-windows))) diff --git a/lisp/gnus/mml2015.el b/lisp/gnus/mml2015.el index 8eda59372f..53454bf16d 100644 --- a/lisp/gnus/mml2015.el +++ b/lisp/gnus/mml2015.el @@ -869,9 +869,9 @@ If set, it overrides the setting of `mml2015-sign-with-sender'." (setq plain (epg-verify-string context signature part)) (error (mm-sec-error 'gnus-info "Failed") - (if (eq (car error) 'quit) - (mm-sec-status 'gnus-details "Quit.") - (mm-sec-status 'gnus-details (mml2015-format-error error))) + (mm-sec-status 'gnus-details (if (eq (car error) 'quit) + "Quit." + (mml2015-format-error error))) (throw 'error handle))) (mm-sec-status 'gnus-info (mml2015-epg-verify-result-to-string diff --git a/lisp/gnus/nnbabyl.el b/lisp/gnus/nnbabyl.el index 5149acc0e7..41f7f62fae 100644 --- a/lisp/gnus/nnbabyl.el +++ b/lisp/gnus/nnbabyl.el @@ -263,7 +263,8 @@ (nnmail-expired-article-p newsgroup (buffer-substring - (point) (progn (end-of-line) (point))) force)) + (point) (progn (end-of-line) (point))) + force)) (progn (unless (eq nnmail-expiry-target 'delete) (with-temp-buffer diff --git a/lisp/gnus/nnmail.el b/lisp/gnus/nnmail.el index 59d61379f1..251ae657bb 100644 --- a/lisp/gnus/nnmail.el +++ b/lisp/gnus/nnmail.el @@ -712,7 +712,7 @@ If SOURCE is a directory spec, try to return the group name component." (if (eq (car source) 'directory) (let ((file (file-name-nondirectory file))) (mail-source-bind (directory source) - (if (string-match (concat (regexp-quote suffix) "$") file) + (if (string-match (concat (regexp-quote suffix) "\\'") file) (substring file 0 (match-beginning 0)) nil))) nil)) @@ -1339,7 +1339,8 @@ to actually put the message in the right group." (let ((success t)) (dolist (mbx (message-unquote-tokens (message-tokenize-header - (message-fetch-field "Newsgroups") ", ")) success) + (message-fetch-field "Newsgroups") ", ")) + success) (let ((to-newsgroup (gnus-group-prefixed-name mbx gnus-command-method))) (or (gnus-active to-newsgroup) (gnus-activate-group to-newsgroup) @@ -1433,11 +1434,11 @@ See the documentation for the variable `nnmail-split-fancy' for details." ;; we do not exclude foo.list just because ;; the header is: ``To: x-foo, foo'' (goto-char end) - (if (and (re-search-backward (cadr split-rest) - after-header-name t) - (> (match-end 0) start-of-value)) - (setq split-rest nil) - (setq split-rest (cddr split-rest)))) + (setq split-rest + (unless (and (re-search-backward (cadr split-rest) + after-header-name t) + (> (match-end 0) start-of-value)) + (cddr split-rest)))) (when split-rest (goto-char end) ;; Someone might want to do a \N sub on this match, so diff --git a/lisp/gnus/nnmairix.el b/lisp/gnus/nnmairix.el index 5e8ad4fa9a..8b3ab40e22 100644 --- a/lisp/gnus/nnmairix.el +++ b/lisp/gnus/nnmairix.el @@ -676,9 +676,9 @@ Other back ends might or might not work.") (autoload 'nnimap-request-update-info-internal "nnimap") (deffoo nnmairix-request-marks (group info &optional server) -;; propagate info from underlying IMAP folder to nnmairix group -;; This is currently experimental and must be explicitly activated -;; with nnmairix-propagate-marks-to-nnmairix-group + ;; propagate info from underlying IMAP folder to nnmairix group + ;; This is currently experimental and must be explicitly activated + ;; with nnmairix-propagate-marks-to-nnmairix-group (when server (nnmairix-open-server server)) (let* ((qualgroup (gnus-group-prefixed-name diff --git a/lisp/gnus/nnoo.el b/lisp/gnus/nnoo.el index cd0a5e6de9..39469d140d 100644 --- a/lisp/gnus/nnoo.el +++ b/lisp/gnus/nnoo.el @@ -85,20 +85,14 @@ (defun nnoo-import-1 (backend imports) (let ((call-function - (if (symbolp (car imports)) (pop imports) 'nnoo-parent-function)) - imp functions function) - (while (setq imp (pop imports)) - (setq functions - (or (cdr imp) - (nnoo-functions (car imp)))) - (while functions - (unless (fboundp - (setq function - (nnoo-symbol backend - (nnoo-rest-symbol (car functions))))) - (eval `(deffoo ,function (&rest args) - (,call-function ',backend ',(car functions) args)))) - (pop functions))))) + (if (symbolp (car imports)) (pop imports) #'nnoo-parent-function))) + (dolist (imp imports) + (dolist (fun (or (cdr imp) (nnoo-functions (car imp)))) + (let ((function (nnoo-symbol backend (nnoo-rest-symbol fun)))) + (unless (fboundp function) + ;; FIXME: Use `defalias' and closures to avoid `eval'. + (eval `(deffoo ,function (&rest args) + (,call-function ',backend ',fun args))))))))) (defun nnoo-parent-function (backend function args) (let ((pbackend (nnoo-backend function)) @@ -131,22 +125,21 @@ (defmacro nnoo-map-functions (backend &rest maps) (declare (indent 1)) - `(nnoo-map-functions-1 ',backend ',maps)) - -(defun nnoo-map-functions-1 (backend maps) - (let (m margs i) - (while (setq m (pop maps)) - (setq i 0 - margs nil) - (while (< i (length (cdr m))) - (if (numberp (nth i (cdr m))) - (push `(nth ,i args) margs) - (push (nth i (cdr m)) margs)) - (cl-incf i)) - (eval `(deffoo ,(nnoo-symbol backend (nnoo-rest-symbol (car m))) + `(progn + ,@(mapcar + (lambda (m) + (let ((margs nil)) + (dotimes (i (length (cdr m))) + (push (if (numberp (nth i (cdr m))) + `(nth ,i args) + (nth i (cdr m))) + margs)) + `(deffoo ,(nnoo-symbol backend (nnoo-rest-symbol (car m))) (&rest args) + (ignore args) ;; Not always used! (nnoo-parent-function ',backend ',(car m) - ,(cons 'list (nreverse margs)))))))) + ,(cons 'list (nreverse margs)))))) + maps))) (defun nnoo-backend (symbol) (string-match "^[^-]+-" (symbol-name symbol)) @@ -273,19 +266,27 @@ (defmacro nnoo-define-basics (backend) "Define `close-server', `server-opened' and `status-message'." - `(eval-and-compile - (nnoo-define-basics-1 ',backend))) - -(defun nnoo-define-basics-1 (backend) - (dolist (function '(server-opened status-message)) - (eval `(deffoo ,(nnoo-symbol backend function) (&optional server) - (,(nnoo-symbol 'nnoo function) ',backend server)))) - (dolist (function '(close-server)) - (eval `(deffoo ,(nnoo-symbol backend function) (&optional server defs) - (,(nnoo-symbol 'nnoo function) ',backend server)))) - (eval `(deffoo ,(nnoo-symbol backend 'open-server) - (server &optional defs) - (nnoo-change-server ',backend server defs)))) + (let ((form + ;; We wrap the definitions in `when t' here so that a subsequent + ;; "real" definition of one those doesn't trigger a "defined multiple + ;; times" warning. + `(when t + ,@(mapcar (lambda (fun) + `(deffoo ,(nnoo-symbol backend fun) (&optional server) + (,(nnoo-symbol 'nnoo fun) ',backend server))) + '(server-opened status-message)) + (deffoo ,(nnoo-symbol backend 'close-server) (&optional server _defs) + (,(nnoo-symbol 'nnoo 'close-server) ',backend server)) + (deffoo ,(nnoo-symbol backend 'open-server) (server &optional defs) + (nnoo-change-server ',backend server defs))))) + ;; Wrapping with `when' has the downside that the compiler now doesn't + ;; "know" that these functions are defined, so to avoid "not known to be + ;; defined" warnings we eagerly define them during the compilation. + ;; This is fairly nasty since it will override previous "real" definitions + ;; (e.g. when compiling this in an Emacs instance that's running Gnus), but + ;; that's also what the previous code did, so it sucks but is not worse. + (eval form t) + form)) (defmacro nnoo-define-skeleton (backend) "Define all required backend functions for BACKEND. @@ -294,17 +295,17 @@ All functions will return nil and report an error." (nnoo-define-skeleton-1 ',backend))) (defun nnoo-define-skeleton-1 (backend) - (let ((functions '(retrieve-headers - request-close request-article - request-group close-group - request-list request-post request-list-newsgroups)) - function fun) - (while (setq function (pop functions)) - (when (not (fboundp (setq fun (nnoo-symbol backend function)))) + (dolist (op '(retrieve-headers + request-close request-article + request-group close-group + request-list request-post request-list-newsgroups)) + (let ((fun (nnoo-symbol backend op))) + (unless (fboundp fun) + ;; FIXME: Use `defalias' and closures to avoid `eval'. (eval `(deffoo ,fun - (&rest args) - (nnheader-report ',backend ,(format "%s-%s not implemented" - backend function)))))))) + (&rest _args) + (nnheader-report ',backend ,(format "%s-%s not implemented" + backend op)))))))) (defun nnoo-set (server &rest args) (let ((parents (nnoo-parents (car server))) diff --git a/lisp/gnus/nnweb.el b/lisp/gnus/nnweb.el index 2a94825471..dd71bea72e 100644 --- a/lisp/gnus/nnweb.el +++ b/lisp/gnus/nnweb.el @@ -154,17 +154,17 @@ Valid types include `google', `dejanews', and `gmane'.") (and (stringp article) (nnweb-definition 'id t) (let ((fetch (nnweb-definition 'id)) - art active) - (when (string-match "^<\\(.*\\)>$" article) - (setq art (match-string 1 article))) + (art (when (string-match "^<\\(.*\\)>$" article) + (match-string 1 article))) + active) (when (and fetch art) (setq url (format fetch (mm-url-form-encode-xwfu art))) (mm-url-insert url) (if (nnweb-definition 'reference t) (setq article - (funcall (nnweb-definition - 'reference) article))))))) + (funcall (nnweb-definition 'reference) + article))))))) (unless nnheader-callback-function (funcall (nnweb-definition 'article))) (nnheader-report 'nnweb "Fetched article %s" article) diff --git a/lisp/gnus/spam.el b/lisp/gnus/spam.el index 3f4fd3614e..00dcd00cea 100644 --- a/lisp/gnus/spam.el +++ b/lisp/gnus/spam.el @@ -321,8 +321,8 @@ Default to t if one of the spam-use-* variables is set." :type 'string :group 'spam) -;;; TODO: deprecate this variable, it's confusing since it's a list of strings, -;;; not regular expressions +;; TODO: deprecate this variable, it's confusing since it's a list of strings, +;; not regular expressions (defcustom spam-junk-mailgroups (cons spam-split-group '("mail.junk" "poste.pourriel")) @@ -1836,7 +1836,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." ;; return the number of articles processed (length articles)))) -;;; log a ham- or spam-processor invocation to the registry +;; log a ham- or spam-processor invocation to the registry (defun spam-log-processing-to-registry (id type classification backend group) (when spam-log-to-registry (if (and (stringp id) @@ -1855,7 +1855,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." "%s call with bad ID, type, classification, spam-backend, or group" "spam-log-processing-to-registry"))))) -;;; check if a ham- or spam-processor registration has been done +;; check if a ham- or spam-processor registration has been done (defun spam-log-registered-p (id type) (when spam-log-to-registry (if (and (stringp id) @@ -1868,8 +1868,8 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." "spam-log-registered-p")) nil)))) -;;; check what a ham- or spam-processor registration says -;;; returns nil if conflicting registrations are found +;; check what a ham- or spam-processor registration says +;; returns nil if conflicting registrations are found (defun spam-log-registration-type (id type) (let ((count 0) decision) @@ -1885,7 +1885,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." decision))) -;;; check if a ham- or spam-processor registration needs to be undone +;; check if a ham- or spam-processor registration needs to be undone (defun spam-log-unregistration-needed-p (id type classification backend) (when spam-log-to-registry (if (and (stringp id) @@ -1908,7 +1908,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." nil)))) -;;; undo a ham- or spam-processor registration (the group is not used) +;; undo a ham- or spam-processor registration (the group is not used) (defun spam-log-undo-registration (id type classification backend &optional group) (when (and spam-log-to-registry @@ -2034,94 +2034,83 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." ;;{{{ BBDB -;;; original idea for spam-check-BBDB from Alexander Kotelnikov -;;; +;; original idea for spam-check-BBDB from Alexander Kotelnikov +;; ;; all this is done inside a condition-case to trap errors ;; Autoloaded in message, which we require. (declare-function gnus-extract-address-components "gnus-util" (from)) -(eval-and-compile - (condition-case nil - (progn - (require 'bbdb) - (require 'bbdb-com)) - (file-error - ;; `bbdb-records' should not be bound as an autoload function - ;; before loading bbdb because of `bbdb-hashtable-size'. - (defalias 'bbdb-buffer 'ignore) - (defalias 'bbdb-create-internal 'ignore) - (defalias 'bbdb-records 'ignore) - (defalias 'spam-BBDB-register-routine 'ignore) - (defalias 'spam-enter-ham-BBDB 'ignore) - (defalias 'spam-exists-in-BBDB-p 'ignore) - (defalias 'bbdb-gethash 'ignore) - nil))) - -(eval-and-compile - (when (featurep 'bbdb-com) - ;; when the BBDB changes, we want to clear out our cache - (defun spam-clear-cache-BBDB (&rest immaterial) - (spam-clear-cache 'spam-use-BBDB)) - - (add-hook 'bbdb-change-hook 'spam-clear-cache-BBDB) - - (defun spam-enter-ham-BBDB (addresses &optional remove) - "Enter an address into the BBDB; implies ham (non-spam) sender" - (dolist (from addresses) - (when (stringp from) - (let* ((parsed-address (gnus-extract-address-components from)) - (name (or (nth 0 parsed-address) "Ham Sender")) - (remove-function (if remove - 'bbdb-delete-record-internal - 'ignore)) - (net-address (nth 1 parsed-address)) - (record (and net-address - (spam-exists-in-BBDB-p net-address)))) - (when net-address - (gnus-message 6 "%s address %s %s BBDB" - (if remove "Deleting" "Adding") - from - (if remove "from" "to")) - (if record - (funcall remove-function record) - (bbdb-create-internal name nil net-address nil nil - "ham sender added by spam.el"))))))) - - (defun spam-BBDB-register-routine (articles &optional unregister) - (let (addresses) - (dolist (article articles) - (when (stringp (spam-fetch-field-from-fast article)) - (push (spam-fetch-field-from-fast article) addresses))) - ;; now do the register/unregister action - (spam-enter-ham-BBDB addresses unregister))) - - (defun spam-BBDB-unregister-routine (articles) - (spam-BBDB-register-routine articles t)) - - (defsubst spam-exists-in-BBDB-p (net) - (when (and (stringp net) (not (zerop (length net)))) - (bbdb-records) - (bbdb-gethash (downcase net)))) - - (defun spam-check-BBDB () - "Mail from people in the BBDB is classified as ham or non-spam" - (let ((net (message-fetch-field "from"))) - (when net - (setq net (nth 1 (gnus-extract-address-components net))) - (if (spam-exists-in-BBDB-p net) - t - (if spam-use-BBDB-exclusive - spam-split-group - nil))))))) +(require 'bbdb nil 'noerror) +(require 'bbdb-com nil 'noerror) + +(declare-function bbdb-records "bbdb" ()) +(declare-function bbdb-gethash "bbdb" (key &optional predicate)) +(declare-function bbdb-create-internal "bbdb-com" (&rest spec)) + +;; when the BBDB changes, we want to clear out our cache +(defun spam-clear-cache-BBDB (&rest immaterial) + (spam-clear-cache 'spam-use-BBDB)) + +(when (featurep 'bbdb-com) + (add-hook 'bbdb-change-hook #'spam-clear-cache-BBDB)) + +(defun spam-enter-ham-BBDB (addresses &optional remove) + "Enter an address into the BBDB; implies ham (non-spam) sender" + (dolist (from addresses) + (when (stringp from) + (let* ((parsed-address (gnus-extract-address-components from)) + (name (or (nth 0 parsed-address) "Ham Sender")) + (remove-function (if remove + 'bbdb-delete-record-internal + 'ignore)) + (net-address (nth 1 parsed-address)) + (record (and net-address + (spam-exists-in-BBDB-p net-address)))) + (when net-address + (gnus-message 6 "%s address %s %s BBDB" + (if remove "Deleting" "Adding") + from + (if remove "from" "to")) + (if record + (funcall remove-function record) + (bbdb-create-internal name nil net-address nil nil + "ham sender added by spam.el"))))))) + +(defun spam-BBDB-register-routine (articles &optional unregister) + (let (addresses) + (dolist (article articles) + (when (stringp (spam-fetch-field-from-fast article)) + (push (spam-fetch-field-from-fast article) addresses))) + ;; now do the register/unregister action + (spam-enter-ham-BBDB addresses unregister))) + +(defun spam-BBDB-unregister-routine (articles) + (spam-BBDB-register-routine articles t)) + +(defun spam-exists-in-BBDB-p (net) + (when (and (stringp net) (not (zerop (length net)))) + (bbdb-records) + (bbdb-gethash (downcase net)))) + +(defun spam-check-BBDB () + "Mail from people in the BBDB is classified as ham or non-spam" + (let ((net (message-fetch-field "from"))) + (when net + (setq net (nth 1 (gnus-extract-address-components net))) + (if (spam-exists-in-BBDB-p net) + t + (if spam-use-BBDB-exclusive + spam-split-group + nil))))) ;;}}} ;;{{{ ifile -;;; check the ifile backend; return nil if the mail was NOT classified -;;; as spam +;; check the ifile backend; return nil if the mail was NOT classified +;; as spam (defun spam-get-ifile-database-parameter () @@ -2240,7 +2229,7 @@ Uses `gnus-newsgroup-name' if category is nil (for ham registration)." (let ((kill-whole-line t)) (kill-line))) -;;; address can be a list, too +;; address can be a list, too (defun spam-enter-whitelist (address &optional remove) "Enter ADDRESS (list or single) into the whitelist. With a non-nil REMOVE, remove them." @@ -2249,7 +2238,7 @@ With a non-nil REMOVE, remove them." (setq spam-whitelist-cache nil) (spam-clear-cache 'spam-use-whitelist)) -;;; address can be a list, too +;; address can be a list, too (defun spam-enter-blacklist (address &optional remove) "Enter ADDRESS (list or single) into the blacklist. With a non-nil REMOVE, remove them." @@ -2310,8 +2299,8 @@ With a non-nil REMOVE, remove the ADDRESSES." (cl-return))) found))) -;;; returns t if the sender is in the whitelist, nil or -;;; spam-split-group otherwise +;; returns t if the sender is in the whitelist, nil or +;; spam-split-group otherwise (defun spam-check-whitelist () ;; FIXME! Should it detect when file timestamps change? (unless spam-whitelist-cache commit 9c7543417306752683faacd1436f9748a6f4f616 Author: Alan Third Date: Sat Jan 30 10:53:12 2021 +0000 Fix build failure on macOS 10.7 (bug#46036) * src/nsfns.m (ns_set_represented_filename): Define the NSNumber in a more compatible manner. diff --git a/src/nsfns.m b/src/nsfns.m index 5a9ad18a12..5f22366939 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -493,7 +493,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side. #if defined (NS_IMPL_COCOA) && defined (MAC_OS_X_VERSION_10_7) /* Work around for Mach port leaks on macOS 10.15 (bug#38618). */ NSURL *fileURL = [NSURL fileURLWithPath:fstr isDirectory:NO]; - NSNumber *isUbiquitousItem = @YES; + NSNumber *isUbiquitousItem = [NSNumber numberWithBool:YES]; [fileURL getResourceValue:(id *)&isUbiquitousItem forKey:NSURLIsUbiquitousItemKey error:nil]; commit 636ef445af03a564ad431648cda34d78d0cb807c Author: Alan Mackenzie Date: Sat Jan 30 21:16:35 2021 +0000 With minibuffer-follows-selected-frame `hybrid', preserve recursive Mbuffers ...when enable-recursive-minibuffers is non-nil, and several minibuffers are activated from different frames. Also set the major mode of a reused active minibuffer to `fundamental-mode' - up till now it's been minibuffer-inactive-mode. * src/minibuf.c (read_minibuf): with the indicated settings of variables, "stack up" all containing minibuffers on the mini-window of the current frame. Delete another, now superfluous such stacking up. (set_minibuffer_mode): New function. (get_minibuffer): Call the above new function (twice), in place of inline code, ensuring active minibuffers are never left in minibuffer-inactive-mode. diff --git a/src/minibuf.c b/src/minibuf.c index 5df1045373..0221f388dd 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -594,6 +594,18 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, record_unwind_protect (restore_buffer, Fcurrent_buffer ()); choose_minibuf_frame (); + mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window)); + + if (minibuf_level > 1 + && minibuf_moves_frame_when_opened () + && !minibuf_follows_frame ()) + { + EMACS_INT i; + + /* Stack up the existing minibuffers on the current mini-window */ + for (i = 1; i < minibuf_level; i++) + set_window_buffer (minibuf_window, nth_minibuffer (i), 0, 0); + } record_unwind_protect_void (choose_minibuf_frame); @@ -602,7 +614,6 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, /* If the minibuffer window is on a different frame, save that frame's configuration too. */ - mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window)); if (!EQ (mini_frame, selected_frame)) record_unwind_protect (restore_window_configuration, Fcons (/* Arrange for the frame later to be @@ -745,17 +756,6 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, } } - if (minibuf_moves_frame_when_opened ()) - { - EMACS_INT i; - - /* Stack up all the (recursively) open minibuffers on the selected - mini_window. */ - for (i = 1; i < minibuf_level; i++) - set_window_buffer (XFRAME (mini_frame)->minibuffer_window, - nth_minibuffer (i), 0, 0); - } - /* Display this minibuffer in the proper window. */ /* Use set_window_buffer instead of Fset_window_buffer (see discussion of bug#11984, bug#12025, bug#12026). */ @@ -926,6 +926,31 @@ nth_minibuffer (EMACS_INT depth) return XCAR (tail); } +/* Set the major mode of the minibuffer BUF, depending on DEPTH, the + minibuffer depth. */ + +static void +set_minibuffer_mode (Lisp_Object buf, EMACS_INT depth) +{ + ptrdiff_t count = SPECPDL_INDEX (); + + record_unwind_current_buffer (); + Fset_buffer (buf); + if (depth > 0) + { + if (!NILP (Ffboundp (intern ("fundamental-mode")))) + call0 (intern ("fundamental-mode")); + } + else + { + if (!NILP (Ffboundp (intern ("minibuffer-inactive-mode")))) + call0 (intern ("minibuffer-inactive-mode")); + else + Fkill_all_local_variables (); + } + buf = unbind_to (count, buf); +} + /* Return a buffer to be used as the minibuffer at depth `depth'. depth = 0 is the lowest allowed argument, and that is the value used for nonrecursive minibuffer invocations. */ @@ -946,7 +971,7 @@ get_minibuffer (EMACS_INT depth) char name[sizeof name_fmt + INT_STRLEN_BOUND (EMACS_INT)]; AUTO_STRING_WITH_LEN (lname, name, sprintf (name, name_fmt, depth)); buf = Fget_buffer_create (lname, Qnil); - + set_minibuffer_mode (buf, depth); /* Although the buffer's name starts with a space, undo should be enabled in it. */ Fbuffer_enable_undo (buf); @@ -955,19 +980,12 @@ get_minibuffer (EMACS_INT depth) } else { - ptrdiff_t count = SPECPDL_INDEX (); /* We have to empty both overlay lists. Otherwise we end up with overlays that think they belong to this buffer while the buffer doesn't know about them any more. */ delete_all_overlays (XBUFFER (buf)); reset_buffer (XBUFFER (buf)); - record_unwind_current_buffer (); - Fset_buffer (buf); - if (!NILP (Ffboundp (intern ("minibuffer-inactive-mode")))) - call0 (intern ("minibuffer-inactive-mode")); - else - Fkill_all_local_variables (); - buf = unbind_to (count, buf); + set_minibuffer_mode (buf, depth); } return buf; commit acf4ec23d966b6bc92c61b557148afc88f20f99e Author: Stefan Monnier Date: Sat Jan 30 14:27:40 2021 -0500 * lisp/gnus: Remove redundant `:group` args * lisp/gnus/spam-stat.el: * lisp/gnus/spam-report.el: * lisp/gnus/smime.el: * lisp/gnus/nnrss.el: * lisp/gnus/nnmairix.el: * lisp/gnus/nnimap.el: * lisp/gnus/nndiary.el: * lisp/gnus/mm-url.el: * lisp/gnus/mail-source.el: * lisp/gnus/gnus-win.el: * lisp/gnus/gnus-topic.el: * lisp/gnus/gnus-sieve.el: * lisp/gnus/gnus-search.el: * lisp/gnus/gnus-registry.el: * lisp/gnus/gnus-notifications.el: * lisp/gnus/gnus-gravatar.el: * lisp/gnus/gnus-eform.el: * lisp/gnus/gnus-dup.el: * lisp/gnus/gnus-diary.el: * lisp/gnus/gnus-demon.el: * lisp/gnus/gnus-delay.el: * lisp/gnus/gnus-cloud.el: * lisp/gnus/gnus-cite.el: * lisp/gnus/gnus-bookmark.el: * lisp/gnus/gmm-utils.el: * lisp/gnus/deuglify.el: * lisp/gnus/canlock.el: Remove redundant `:group` arguments diff --git a/lisp/gnus/canlock.el b/lisp/gnus/canlock.el index e203ebc0a9..993050109d 100644 --- a/lisp/gnus/canlock.el +++ b/lisp/gnus/canlock.el @@ -52,20 +52,17 @@ (defcustom canlock-password nil "Password to use when signing a Cancel-Lock or a Cancel-Key header." :type '(radio (const :format "Not specified " nil) - (string :tag "Password")) - :group 'canlock) + (string :tag "Password"))) (defcustom canlock-password-for-verify canlock-password "Password to use when verifying a Cancel-Lock or a Cancel-Key header." :type '(radio (const :format "Not specified " nil) - (string :tag "Password")) - :group 'canlock) + (string :tag "Password"))) (defcustom canlock-force-insert-header nil "If non-nil, insert a Cancel-Lock or a Cancel-Key header even if the buffer does not look like a news message." - :type 'boolean - :group 'canlock) + :type 'boolean) (defun canlock-sha1 (message) "Make a SHA-1 digest of MESSAGE as a unibyte string of length 20 bytes." diff --git a/lisp/gnus/deuglify.el b/lisp/gnus/deuglify.el index 4f9ac26ed8..3a40b55f56 100644 --- a/lisp/gnus/deuglify.el +++ b/lisp/gnus/deuglify.el @@ -234,20 +234,17 @@ (defcustom gnus-outlook-deuglify-unwrap-min 45 "Minimum length of the cited line above the (possibly) wrapped line." :version "22.1" - :type 'integer - :group 'gnus-outlook-deuglify) + :type 'integer) (defcustom gnus-outlook-deuglify-unwrap-max 95 "Maximum length of the cited line after unwrapping." :version "22.1" - :type 'integer - :group 'gnus-outlook-deuglify) + :type 'integer) (defcustom gnus-outlook-deuglify-cite-marks ">|#%" "Characters that indicate cited lines." :version "22.1" - :type 'string - :group 'gnus-outlook-deuglify) + :type 'string) (defcustom gnus-outlook-deuglify-unwrap-stop-chars nil ;; ".?!" or nil "Characters that, when at end of cited line, inhibit unwrapping. @@ -255,44 +252,38 @@ When one of these characters is the last one on the cited line above the possibly wrapped line, it disallows unwrapping." :version "22.1" :type '(radio (const :format "None " nil) - (string :value ".?!")) - :group 'gnus-outlook-deuglify) + (string :value ".?!"))) (defcustom gnus-outlook-deuglify-no-wrap-chars "`" "Characters that, when at beginning of line, inhibit unwrapping. When one of these characters is the first one in the possibly wrapped line, it disallows unwrapping." :version "22.1" - :type 'string - :group 'gnus-outlook-deuglify) + :type 'string) (defcustom gnus-outlook-deuglify-attrib-cut-regexp "\\(On \\|Am \\)?\\(Mon\\|Tue\\|Wed\\|Thu\\|Fri\\|Sat\\|Sun\\),[^,]+, " "Regexp matching beginning of attribution line that should be cut off." :version "22.1" - :type 'regexp - :group 'gnus-outlook-deuglify) + :type 'regexp) (defcustom gnus-outlook-deuglify-attrib-verb-regexp "wrote\\|writes\\|says\\|schrieb\\|schreibt\\|meinte\\|skrev\\|a écrit\\|schreef\\|escribió" "Regular expression matching the verb used in an attribution line." :version "22.1" - :type 'regexp - :group 'gnus-outlook-deuglify) + :type 'regexp) (defcustom gnus-outlook-deuglify-attrib-end-regexp ": *\\|\\.\\.\\." "Regular expression matching the end of an attribution line." :version "22.1" - :type 'regexp - :group 'gnus-outlook-deuglify) + :type 'regexp) (defcustom gnus-outlook-display-hook nil "A hook called after a deuglified article has been prepared. It is run after `gnus-article-prepare-hook'." :version "22.1" - :type 'hook - :group 'gnus-outlook-deuglify) + :type 'hook) ;; Functions diff --git a/lisp/gnus/gmm-utils.el b/lisp/gnus/gmm-utils.el index 5e27a2f93a..c64bfea7ca 100644 --- a/lisp/gnus/gmm-utils.el +++ b/lisp/gnus/gmm-utils.el @@ -42,8 +42,7 @@ The higher the number, the more messages will flash to say what it did. At zero, it will be totally mute; at five, it will display most important messages; and at ten, it will keep on jabbering all the time." - :type 'integer - :group 'gmm) + :type 'integer) ;;;###autoload (defun gmm-regexp-concat (regexp) @@ -175,8 +174,7 @@ ARGS are passed to `message'." 'retro) "Preferred tool bar style." :type '(choice (const :tag "GNOME style" gnome) - (const :tag "Retro look" retro)) - :group 'gmm) + (const :tag "Retro look" retro))) (defvar tool-bar-map) diff --git a/lisp/gnus/gnus-bookmark.el b/lisp/gnus/gnus-bookmark.el index d1af64d6d6..c6eb2a1c1d 100644 --- a/lisp/gnus/gnus-bookmark.el +++ b/lisp/gnus/gnus-bookmark.el @@ -78,22 +78,19 @@ ((file-exists-p "~/.gnus.bmk") "~/.gnus.bmk") (t (nnheader-concat gnus-directory "bookmarks.el"))) "The default Gnus bookmarks file." - :type 'string - :group 'gnus-bookmark) + :type 'string) (defcustom gnus-bookmark-file-coding-system (if (mm-coding-system-p 'iso-2022-7bit) 'iso-2022-7bit) "Coding system used for writing Gnus bookmark files." - :type '(symbol :tag "Coding system") - :group 'gnus-bookmark) + :type '(symbol :tag "Coding system")) (defcustom gnus-bookmark-sort-flag t "Non-nil means Gnus bookmarks are sorted by bookmark names. Otherwise they will be displayed in LIFO order (that is, most recently set ones come first, oldest ones come last)." - :type 'boolean - :group 'gnus-bookmark) + :type 'boolean) (defcustom gnus-bookmark-bmenu-toggle-infos t "Non-nil means show details when listing Gnus bookmarks. @@ -102,19 +99,16 @@ This may result in truncated bookmark names. To disable this, put the following in your `.emacs' file: \(setq gnus-bookmark-bmenu-toggle-infos nil)" - :type 'boolean - :group 'gnus-bookmark) + :type 'boolean) (defcustom gnus-bookmark-bmenu-file-column 30 "Column at which to display details in a buffer listing Gnus bookmarks. You can toggle whether details are shown with \\\\[gnus-bookmark-bmenu-toggle-infos]." - :type 'integer - :group 'gnus-bookmark) + :type 'integer) (defcustom gnus-bookmark-use-annotations nil "If non-nil, ask for an annotation when setting a bookmark." - :type 'boolean - :group 'gnus-bookmark) + :type 'boolean) (defcustom gnus-bookmark-bookmark-inline-details '(author) "Details to be shown with `gnus-bookmark-bmenu-toggle-infos'. @@ -125,8 +119,7 @@ The default value is \(subject)." (const :tag "Subject" subject) (const :tag "Date" date) (const :tag "Group" group) - (const :tag "Message-id" message-id))) - :group 'gnus-bookmark) + (const :tag "Message-id" message-id)))) (defcustom gnus-bookmark-bookmark-details '(author subject date group annotation) @@ -139,14 +132,12 @@ The default value is \(author subject date group annotation)." (const :tag "Date" date) (const :tag "Group" group) (const :tag "Message-id" message-id) - (const :tag "Annotation" annotation))) - :group 'gnus-bookmark) + (const :tag "Annotation" annotation)))) (defface gnus-bookmark-menu-heading '((t (:inherit font-lock-type-face))) "Face used to highlight the heading in Gnus bookmark menu buffers." - :version "23.1" ;; No Gnus - :group 'gnus-bookmark) + :version "23.1") ;; No Gnus (defconst gnus-bookmark-end-of-version-stamp-marker "-*- End Of Bookmark File Format Version Stamp -*-\n" diff --git a/lisp/gnus/gnus-cite.el b/lisp/gnus/gnus-cite.el index a6d1101e01..c63adb36d8 100644 --- a/lisp/gnus/gnus-cite.el +++ b/lisp/gnus/gnus-cite.el @@ -38,19 +38,16 @@ (defcustom gnus-cited-opened-text-button-line-format "%(%{[-]%}%)\n" "Format of opened cited text buttons." - :group 'gnus-cite :type 'string) (defcustom gnus-cited-closed-text-button-line-format "%(%{[+]%}%)\n" "Format of closed cited text buttons." - :group 'gnus-cite :type 'string) (defcustom gnus-cited-lines-visible nil "The number of lines of hidden cited text to remain visible. Or a pair (cons) of numbers which are the number of lines at the top and bottom of the text, respectively, to remain visible." - :group 'gnus-cite :type '(choice (const :tag "none" nil) integer (cons :tag "Top and Bottom" integer integer))) @@ -58,13 +55,11 @@ and bottom of the text, respectively, to remain visible." (defcustom gnus-cite-parse-max-size 25000 "Maximum article size (in bytes) where parsing citations is allowed. Set it to nil to parse all articles." - :group 'gnus-cite :type '(choice (const :tag "all" nil) integer)) (defcustom gnus-cite-max-prefix 20 "Maximum possible length for a citation prefix." - :group 'gnus-cite :type 'integer) (defcustom gnus-supercite-regexp @@ -72,18 +67,15 @@ Set it to nil to parse all articles." ">>>>> +\"\\([^\"\n]+\\)\" +==") "Regexp matching normal Supercite attribution lines. The first grouping must match prefixes added by other packages." - :group 'gnus-cite :type 'regexp) (defcustom gnus-supercite-secondary-regexp "^.*\"\\([^\"\n]+\\)\" +==" "Regexp matching mangled Supercite attribution lines. The first regexp group should match the Supercite attribution." - :group 'gnus-cite :type 'regexp) (defcustom gnus-cite-minimum-match-count 2 "Minimum number of identical prefixes before we believe it's a citation." - :group 'gnus-cite :type 'integer) ;; Some Microsoft products put in a citation that extends to the @@ -106,21 +98,18 @@ The first regexp group should match the Supercite attribution." (defcustom gnus-cite-attribution-prefix "In article\\|in <\\|On \\(Mon\\|Tue\\|Wed\\|Thu\\|Fri\\|Sat\\|Sun\\),\\|----- ?Original Message ?-----" "Regexp matching the beginning of an attribution line." - :group 'gnus-cite :type 'regexp) (defcustom gnus-cite-attribution-suffix "\\(\\(wrote\\|writes\\|said\\|says\\|>\\)\\(:\\|\\.\\.\\.\\)\\|----- ?Original Message ?-----\\)[ \t]*$" "Regexp matching the end of an attribution line. The text matching the first grouping will be used as a button." - :group 'gnus-cite :type 'regexp) (defcustom gnus-cite-unsightly-citation-regexp "^-----Original Message-----\nFrom: \\(.+\n\\)+\n" "Regexp matching Microsoft-type rest-of-message citations." :version "22.1" - :group 'gnus-cite :type 'regexp) (defcustom gnus-cite-ignore-quoted-from t @@ -128,18 +117,15 @@ The text matching the first grouping will be used as a button." Those lines may have been quoted by MTAs in order not to mix up with the envelope From line." :version "22.1" - :group 'gnus-cite :type 'boolean) (defface gnus-cite-attribution '((t (:italic t))) - "Face used for attribution lines." - :group 'gnus-cite) + "Face used for attribution lines.") (defcustom gnus-cite-attribution-face 'gnus-cite-attribution "Face used for attribution lines. It is merged with the face for the cited text belonging to the attribution." :version "22.1" - :group 'gnus-cite :type 'face) (defface gnus-cite-1 '((((class color) @@ -150,8 +136,7 @@ It is merged with the face for the cited text belonging to the attribution." (:foreground "MidnightBlue")) (t (:italic t))) - "Citation face." - :group 'gnus-cite) + "Citation face.") (defface gnus-cite-2 '((((class color) (background dark)) @@ -161,8 +146,7 @@ It is merged with the face for the cited text belonging to the attribution." (:foreground "firebrick")) (t (:italic t))) - "Citation face." - :group 'gnus-cite) + "Citation face.") (defface gnus-cite-3 '((((class color) (background dark)) @@ -172,8 +156,7 @@ It is merged with the face for the cited text belonging to the attribution." (:foreground "dark green")) (t (:italic t))) - "Citation face." - :group 'gnus-cite) + "Citation face.") (defface gnus-cite-4 '((((class color) (background dark)) @@ -183,8 +166,7 @@ It is merged with the face for the cited text belonging to the attribution." (:foreground "OrangeRed")) (t (:italic t))) - "Citation face." - :group 'gnus-cite) + "Citation face.") (defface gnus-cite-5 '((((class color) (background dark)) @@ -194,8 +176,7 @@ It is merged with the face for the cited text belonging to the attribution." (:foreground "dark khaki")) (t (:italic t))) - "Citation face." - :group 'gnus-cite) + "Citation face.") (defface gnus-cite-6 '((((class color) (background dark)) @@ -205,8 +186,7 @@ It is merged with the face for the cited text belonging to the attribution." (:foreground "dark violet")) (t (:italic t))) - "Citation face." - :group 'gnus-cite) + "Citation face.") (defface gnus-cite-7 '((((class color) (background dark)) @@ -216,8 +196,7 @@ It is merged with the face for the cited text belonging to the attribution." (:foreground "SteelBlue4")) (t (:italic t))) - "Citation face." - :group 'gnus-cite) + "Citation face.") (defface gnus-cite-8 '((((class color) (background dark)) @@ -227,8 +206,7 @@ It is merged with the face for the cited text belonging to the attribution." (:foreground "magenta")) (t (:italic t))) - "Citation face." - :group 'gnus-cite) + "Citation face.") (defface gnus-cite-9 '((((class color) (background dark)) @@ -238,8 +216,7 @@ It is merged with the face for the cited text belonging to the attribution." (:foreground "violet")) (t (:italic t))) - "Citation face." - :group 'gnus-cite) + "Citation face.") (defface gnus-cite-10 '((((class color) (background dark)) @@ -249,8 +226,7 @@ It is merged with the face for the cited text belonging to the attribution." (:foreground "medium purple")) (t (:italic t))) - "Citation face." - :group 'gnus-cite) + "Citation face.") (defface gnus-cite-11 '((((class color) (background dark)) @@ -260,8 +236,7 @@ It is merged with the face for the cited text belonging to the attribution." (:foreground "turquoise")) (t (:italic t))) - "Citation face." - :group 'gnus-cite) + "Citation face.") (defcustom gnus-cite-face-list '(gnus-cite-1 gnus-cite-2 gnus-cite-3 gnus-cite-4 gnus-cite-5 gnus-cite-6 @@ -271,7 +246,6 @@ It is merged with the face for the cited text belonging to the attribution." When there are citations from multiple articles in the same message, Gnus will try to give each citation from each article its own face. This should make it easier to see who wrote what." - :group 'gnus-cite :type '(repeat face) :set (lambda (symbol value) (prog1 @@ -290,17 +264,14 @@ This should make it easier to see who wrote what." (defcustom gnus-cite-hide-percentage 50 "Only hide excess citation if above this percentage of the body." - :group 'gnus-cite :type 'number) (defcustom gnus-cite-hide-absolute 10 "Only hide excess citation if above this number of lines in the body." - :group 'gnus-cite :type 'integer) (defcustom gnus-cite-blank-line-after-header t "If non-nil, put a blank line between the citation header and the button." - :group 'gnus-cite :type 'boolean) ;; This has to go here because its default value depends on diff --git a/lisp/gnus/gnus-cloud.el b/lisp/gnus/gnus-cloud.el index f7c71f43ce..95ebf7fbe7 100644 --- a/lisp/gnus/gnus-cloud.el +++ b/lisp/gnus/gnus-cloud.el @@ -52,14 +52,12 @@ Each element may be either a string or a property list. The latter should have a :directory element whose value is a string, and a :match element whose value is a regular expression to match against the basename of files in said directory." - :group 'gnus-cloud :type '(repeat (choice (string :tag "File") (plist :tag "Property list")))) (defcustom gnus-cloud-storage-method (if (featurep 'epg) 'epg 'base64-gzip) "Storage method for cloud data, defaults to EPG if that's available." :version "26.1" - :group 'gnus-cloud :type '(radio (const :tag "No encoding" nil) (const :tag "Base64" base64) (const :tag "Base64+gzip" base64-gzip) @@ -68,7 +66,6 @@ against the basename of files in said directory." (defcustom gnus-cloud-interactive t "Whether Gnus Cloud changes should be confirmed." :version "26.1" - :group 'gnus-cloud :type 'boolean) (defvar gnus-cloud-group-name "Emacs-Cloud") @@ -81,7 +78,6 @@ against the basename of files in said directory." "The IMAP select method used to store the cloud data. See also `gnus-server-set-cloud-method-server' for an easy interactive way to set this from the Server buffer." - :group 'gnus-cloud :type '(radio (const :tag "Not set" nil) (string :tag "A Gnus server name as a string"))) diff --git a/lisp/gnus/gnus-delay.el b/lisp/gnus/gnus-delay.el index 74147f2092..0699db405c 100644 --- a/lisp/gnus/gnus-delay.el +++ b/lisp/gnus/gnus-delay.el @@ -44,24 +44,20 @@ (defcustom gnus-delay-group "delayed" "Group name for storing delayed articles." - :type 'string - :group 'gnus-delay) + :type 'string) (defcustom gnus-delay-header "X-Gnus-Delayed" "Header name for storing info about delayed articles." - :type 'string - :group 'gnus-delay) + :type 'string) (defcustom gnus-delay-default-delay "3d" "Default length of delay." - :type 'string - :group 'gnus-delay) + :type 'string) (defcustom gnus-delay-default-hour 8 "If deadline is given as date, then assume this time of day." :version "22.1" - :type 'integer - :group 'gnus-delay) + :type 'integer) ;;;###autoload (defun gnus-delay-article (delay) diff --git a/lisp/gnus/gnus-demon.el b/lisp/gnus/gnus-demon.el index 219f15e222..f85d53f70e 100644 --- a/lisp/gnus/gnus-demon.el +++ b/lisp/gnus/gnus-demon.el @@ -52,7 +52,6 @@ this number of `gnus-demon-timestep's. If IDLE is nil, don't care about idleness. If IDLE is a number and TIME is nil, then call once each time Emacs has been idle for IDLE `gnus-demon-timestep's." - :group 'gnus-demon :type '(repeat (list function (choice :tag "Time" (const :tag "never" nil) @@ -65,7 +64,6 @@ Emacs has been idle for IDLE `gnus-demon-timestep's." (defcustom gnus-demon-timestep 60 "Number of seconds in each demon timestep." - :group 'gnus-demon :type 'integer) ;;; Internal variables. diff --git a/lisp/gnus/gnus-diary.el b/lisp/gnus/gnus-diary.el index 561a15b809..ff563d6bf3 100644 --- a/lisp/gnus/gnus-diary.el +++ b/lisp/gnus/gnus-diary.el @@ -57,8 +57,7 @@ (defcustom gnus-diary-time-format "%a, %b %e %y, %H:%M" "Time format to display appointments in nndiary summary buffers. Please refer to `format-time-string' for information on possible values." - :type 'string - :group 'gnus-diary) + :type 'string) (defcustom gnus-diary-delay-format-function 'gnus-diary-delay-format-english "Function called to format a diary delay string. @@ -73,8 +72,7 @@ There are currently two built-in format functions: `gnus-diary-delay-format-french'" :type '(choice (const :tag "english" gnus-diary-delay-format-english) (const :tag "french" gnus-diary-delay-format-french) - (symbol :tag "other")) - :group 'gnus-diary) + (symbol :tag "other"))) (defconst gnus-diary-version nndiary-version "Current Diary back end version.") diff --git a/lisp/gnus/gnus-dup.el b/lisp/gnus/gnus-dup.el index f7d61bb35f..e4f3da9457 100644 --- a/lisp/gnus/gnus-dup.el +++ b/lisp/gnus/gnus-dup.el @@ -40,17 +40,14 @@ "If non-nil, save the duplicate list when shutting down Gnus. If nil, duplicate suppression will only work on duplicates seen in the same session." - :group 'gnus-duplicate :type 'boolean) (defcustom gnus-duplicate-list-length 10000 "The maximum number of duplicate Message-IDs to keep track of." - :group 'gnus-duplicate :type 'integer) (defcustom gnus-duplicate-file (nnheader-concat gnus-directory "suppression") "The name of the file to store the duplicate suppression list." - :group 'gnus-duplicate :type 'file) ;;; Internal variables diff --git a/lisp/gnus/gnus-eform.el b/lisp/gnus/gnus-eform.el index feee7326cd..6d0cea7feb 100644 --- a/lisp/gnus/gnus-eform.el +++ b/lisp/gnus/gnus-eform.el @@ -37,12 +37,10 @@ (defcustom gnus-edit-form-mode-hook nil "Hook run in `gnus-edit-form-mode' buffers." - :group 'gnus-edit-form :type 'hook) (defcustom gnus-edit-form-menu-hook nil "Hook run when creating menus in `gnus-edit-form-mode' buffers." - :group 'gnus-edit-form :type 'hook) ;;; Internal variables diff --git a/lisp/gnus/gnus-gravatar.el b/lisp/gnus/gnus-gravatar.el index a7ca733e75..9ea9e10031 100644 --- a/lisp/gnus/gnus-gravatar.el +++ b/lisp/gnus/gnus-gravatar.el @@ -38,21 +38,18 @@ If nil, default to `gravatar-size'." :type '(choice (const :tag "Default" nil) (integer :tag "Pixels")) - :version "24.1" - :group 'gnus-gravatar) + :version "24.1") (defcustom gnus-gravatar-properties '(:ascent center :relief 1) "List of image properties applied to Gravatar images." :type 'plist - :version "24.1" - :group 'gnus-gravatar) + :version "24.1") (defcustom gnus-gravatar-too-ugly gnus-article-x-face-too-ugly "Regexp matching posters whose avatar shouldn't be shown automatically. If nil, show all avatars." :type '(choice regexp (const :tag "Allow all" nil)) - :version "24.1" - :group 'gnus-gravatar) + :version "24.1") (defun gnus-gravatar-transform-address (header category &optional force) (gnus-with-article-headers diff --git a/lisp/gnus/gnus-notifications.el b/lisp/gnus/gnus-notifications.el index 39ef51b2b8..adf23f36c0 100644 --- a/lisp/gnus/gnus-notifications.el +++ b/lisp/gnus/gnus-notifications.el @@ -47,26 +47,22 @@ (defcustom gnus-notifications-use-google-contacts t "Use Google Contacts to retrieve photo." - :type 'boolean - :group 'gnus-notifications) + :type 'boolean) (defcustom gnus-notifications-use-gravatar t "Use Gravatar to retrieve photo." - :type 'boolean - :group 'gnus-notifications) + :type 'boolean) (defcustom gnus-notifications-minimum-level 1 "Minimum group level the message should have to be notified. Any message in a group that has a greater value than this will not get notifications." - :type 'integer - :group 'gnus-notifications) + :type 'integer) (defcustom gnus-notifications-timeout nil "Timeout used for notifications sent via `notifications-notify'." :type '(choice (const :tag "Server default" nil) - (integer :tag "Milliseconds")) - :group 'gnus-notifications) + (integer :tag "Milliseconds"))) (defvar gnus-notifications-sent nil "Notifications already sent.") diff --git a/lisp/gnus/gnus-registry.el b/lisp/gnus/gnus-registry.el index 7fdf668313..147550d8cf 100644 --- a/lisp/gnus/gnus-registry.el +++ b/lisp/gnus/gnus-registry.el @@ -131,7 +131,6 @@ display.") (defcustom gnus-registry-default-mark 'To-Do "The default mark. Should be a valid key for `gnus-registry-marks'." - :group 'gnus-registry :type 'symbol) (defcustom gnus-registry-unfollowed-addresses @@ -141,7 +140,6 @@ The addresses are matched, they don't have to be fully qualified. In the messages, these addresses can be the sender or the recipients." :version "24.1" - :group 'gnus-registry :type '(repeat regexp)) (defcustom gnus-registry-unfollowed-groups @@ -153,12 +151,10 @@ message into a group that matches one of these, regardless of references.' nnmairix groups are specifically excluded because they are ephemeral." - :group 'gnus-registry :type '(repeat regexp)) (defcustom gnus-registry-install 'ask "Whether the registry should be installed." - :group 'gnus-registry :type '(choice (const :tag "Never Install" nil) (const :tag "Always Install" t) (const :tag "Ask Me" ask))) @@ -181,7 +177,6 @@ nnmairix groups are specifically excluded because they are ephemeral." "Whether the registry should track extra data about a message. The subject, recipients (To: and Cc:), and Sender (From:) headers are tracked this way by default." - :group 'gnus-registry :type '(set :tag "Tracking choices" (const :tag "Track by subject (Subject: header)" subject) @@ -205,7 +200,6 @@ This is the slowest strategy but also the most accurate one. When `first', the first element of G wins. This is fast and should be OK if your senders and subjects don't \"bleed\" across groups." - :group 'gnus-registry :type '(choice :tag "Splitting strategy" (const :tag "Only use single choices, discard multiple matches" nil) @@ -214,7 +208,6 @@ groups." (defcustom gnus-registry-minimum-subject-length 5 "The minimum length of a subject before it's considered trackable." - :group 'gnus-registry :type 'integer) (defcustom gnus-registry-extra-entries-precious '(mark) @@ -225,20 +218,18 @@ considered precious. Before you save the Gnus registry, it's pruned. Any entries with keys in this list will not be pruned. All other entries go to the Bit Bucket." - :group 'gnus-registry :type '(repeat symbol)) (defcustom gnus-registry-cache-file + ;; FIXME: Use `locate-user-emacs-file'! (nnheader-concat (or gnus-dribble-directory gnus-home-directory "~/") ".gnus.registry.eieio") "File where the Gnus registry will be stored." - :group 'gnus-registry :type 'file) (defcustom gnus-registry-max-entries nil "Maximum number of entries in the registry, nil for unlimited." - :group 'gnus-registry :type '(radio (const :format "Unlimited " nil) (integer :format "Maximum number: %v"))) @@ -253,7 +244,6 @@ cut the registry back to \(- 50000 \(* 50000 0.1)) -> 45000 entries. The pruning process is constrained by the presence of \"precious\" entries." :version "25.1" - :group 'gnus-registry :type 'float) (defcustom gnus-registry-default-sort-function @@ -262,7 +252,6 @@ entries. The pruning process is constrained by the presence of Entries that sort to the front of the list are pruned first. This can slow pruning down. Set to nil to perform no sorting." :version "25.1" - :group 'gnus-registry :type '(choice (const :tag "No sorting" nil) function)) (defun gnus-registry-sort-by-creation-time (l r) diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el index 636a0d7637..f3e08519c3 100644 --- a/lisp/gnus/gnus-search.el +++ b/lisp/gnus/gnus-search.el @@ -123,8 +123,7 @@ If this option is set to nil, search queries will be passed directly to the search engines without being parsed or transformed." :version "28.1" - :type 'boolean - :group 'gnus-search) + :type 'boolean) (define-obsolete-variable-alias 'nnir-ignored-newsgroups 'gnus-search-ignored-newsgroups "28.1") @@ -133,8 +132,7 @@ transformed." "A regexp to match newsgroups in the active file that should be skipped when searching." :version "24.1" - :type 'regexp - :group 'gnus-search) + :type 'regexp) (make-obsolete-variable 'nnir-imap-default-search-key @@ -146,14 +144,12 @@ transformed." (expand-file-name "~/Mail/swish++.conf") "Location of Swish++ configuration file. This variable can also be set per-server." - :type 'file - :group 'gnus-search) + :type 'file) (defcustom gnus-search-swish++-program "search" "Name of swish++ search executable. This variable can also be set per-server." - :type 'string - :group 'gnus-search) + :type 'string) (defcustom gnus-search-swish++-switches '() "A list of strings, to be given as additional arguments to swish++. @@ -163,8 +159,7 @@ Instead, use this: (setq gnus-search-swish++-switches \\='(\"-i\" \"-w\")) This variable can also be set per-server." - :type '(repeat string) - :group 'gnus-search) + :type '(repeat string)) (defcustom gnus-search-swish++-remove-prefix (concat (getenv "HOME") "/Mail/") "The prefix to remove from each file name returned by swish++ @@ -172,30 +167,26 @@ in order to get a group name (albeit with / instead of .). This is a regular expression. This variable can also be set per-server." - :type 'regexp - :group 'gnus-search) + :type 'regexp) (defcustom gnus-search-swish++-raw-queries-p nil "If t, all Swish++ engines will only accept raw search query strings." :type 'boolean - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-swish-e-config-file (expand-file-name "~/Mail/swish-e.conf") "Configuration file for swish-e. This variable can also be set per-server." :type 'file - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-swish-e-program "search" "Name of swish-e search executable. This variable can also be set per-server." :type 'string - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-swish-e-switches '() "A list of strings, to be given as additional arguments to swish-e. @@ -206,8 +197,7 @@ Instead, use this: This variable can also be set per-server." :type '(repeat string) - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-swish-e-remove-prefix (concat (getenv "HOME") "/Mail/") "The prefix to remove from each file name returned by swish-e @@ -216,22 +206,19 @@ regular expression. This variable can also be set per-server." :type 'regexp - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-swish-e-index-files '() "A list of index files to use with this Swish-e instance. This variable can also be set per-server." :type '(repeat file) - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-swish-e-raw-queries-p nil "If t, all Swish-e engines will only accept raw search query strings." :type 'boolean - :version "28.1" - :group 'gnus-search) + :version "28.1") ;; Namazu engine, see @@ -239,15 +226,13 @@ This variable can also be set per-server." "Name of Namazu search executable. This variable can also be set per-server." :type 'string - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-namazu-index-directory (expand-file-name "~/Mail/namazu/") "Index directory for Namazu. This variable can also be set per-server." :type 'directory - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-namazu-switches '() "A list of strings, to be given as additional arguments to namazu. @@ -261,8 +246,7 @@ Instead, use this: This variable can also be set per-server." :type '(repeat string) - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-namazu-remove-prefix (concat (getenv "HOME") "/Mail/") "The prefix to remove from each file name returned by Namazu @@ -277,30 +261,26 @@ arrive at the correct group name, \"mail.misc\". This variable can also be set per-server." :type 'directory - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-namazu-raw-queries-p nil "If t, all Namazu engines will only accept raw search query strings." :type 'boolean - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-notmuch-program "notmuch" "Name of notmuch search executable. This variable can also be set per-server." :type '(string) - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-notmuch-config-file (expand-file-name "~/.notmuch-config") "Configuration file for notmuch. This variable can also be set per-server." :type 'file - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-notmuch-switches '() "A list of strings, to be given as additional arguments to notmuch. @@ -311,8 +291,7 @@ Instead, use this: This variable can also be set per-server." :type '(repeat string) - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-notmuch-remove-prefix (concat (getenv "HOME") "/Mail/") "The prefix to remove from each file name returned by notmuch @@ -321,37 +300,32 @@ regular expression. This variable can also be set per-server." :type 'regexp - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-notmuch-raw-queries-p nil "If t, all Notmuch engines will only accept raw search query strings." :type 'boolean - :version "28.1" - :group 'gnus-search) + :version "28.1") (defcustom gnus-search-imap-raw-queries-p nil "If t, all IMAP engines will only accept raw search query strings." :version "28.1" - :type 'boolean - :group 'gnus-search) + :type 'boolean) (defcustom gnus-search-mairix-program "mairix" "Name of mairix search executable. This variable can also be set per-server." :version "28.1" - :type 'string - :group 'gnus-search) + :type 'string) (defcustom gnus-search-mairix-config-file (expand-file-name "~/.mairixrc") "Configuration file for mairix. This variable can also be set per-server." :version "28.1" - :type 'file - :group 'gnus-search) + :type 'file) (defcustom gnus-search-mairix-switches '() "A list of strings, to be given as additional arguments to mairix. @@ -362,8 +336,7 @@ Instead, use this: This variable can also be set per-server." :version "28.1" - :type '(repeat string) - :group 'gnus-search) + :type '(repeat string)) (defcustom gnus-search-mairix-remove-prefix (concat (getenv "HOME") "/Mail/") "The prefix to remove from each file name returned by mairix @@ -372,15 +345,13 @@ regular expression. This variable can also be set per-server." :version "28.1" - :type 'regexp - :group 'gnus-search) + :type 'regexp) (defcustom gnus-search-mairix-raw-queries-p nil "If t, all Mairix engines will only accept raw search query strings." :version "28.1" - :type 'boolean - :group 'gnus-search) + :type 'boolean) ;; Options for search language parsing. @@ -396,7 +367,6 @@ typing in search queries, ie \"subject\" could be entered as \"subject\" and \"since\". Ambiguous abbreviations will raise an error." - :group 'gnus-search :version "28.1" :type '(repeat string)) @@ -405,7 +375,6 @@ Ambiguous abbreviations will raise an error." "A list of keywords whose value should be parsed as a date. See the docstring of `gnus-search-parse-query' for information on date parsing." - :group 'gnus-search :version "26.1" :type '(repeat string)) @@ -414,7 +383,6 @@ date parsing." Each list element should be a table or collection suitable to be returned by `completion-at-point-functions'. That usually means a list of strings, a hash table, or an alist." - :group 'gnus-search :version "28.1" :type '(repeat sexp)) @@ -939,7 +907,6 @@ quirks.") (defcustom gnus-search-default-engines '((nnimap . gnus-search-imap)) "Alist of default search engines keyed by server method." :version "26.1" - :group 'gnus-search :type `(repeat (cons (choice (const nnimap) (const nntp) (const nnspool) (const nneething) (const nndir) (const nnmbox) (const nnml) (const nnmh) (const nndraft) diff --git a/lisp/gnus/gnus-sieve.el b/lisp/gnus/gnus-sieve.el index 7046f5949c..70b1345ca2 100644 --- a/lisp/gnus/gnus-sieve.el +++ b/lisp/gnus/gnus-sieve.el @@ -40,30 +40,25 @@ (defcustom gnus-sieve-file "~/.sieve" "Path to your Sieve script." - :type 'file - :group 'gnus-sieve) + :type 'file) (defcustom gnus-sieve-region-start "\n## Begin Gnus Sieve Script\n" "Line indicating the start of the autogenerated region in your Sieve script." - :type 'string - :group 'gnus-sieve) + :type 'string) (defcustom gnus-sieve-region-end "\n## End Gnus Sieve Script\n" "Line indicating the end of the autogenerated region in your Sieve script." - :type 'string - :group 'gnus-sieve) + :type 'string) (defcustom gnus-sieve-select-method nil "Which select method we generate the Sieve script for. For example: \"nnimap:mailbox\"" ;; FIXME? gnus-select-method? - :type '(choice (const nil) string) - :group 'gnus-sieve) + :type '(choice (const nil) string)) (defcustom gnus-sieve-crosspost t "Whether the generated Sieve script should do crossposting." - :type 'boolean - :group 'gnus-sieve) + :type 'boolean) (defcustom gnus-sieve-update-shell-command "echo put %f | sieveshell %s" "Shell command to execute after updating your Sieve script. The following @@ -71,8 +66,7 @@ formatting characters are recognized: %f Script's file name (gnus-sieve-file) %s Server name (from gnus-sieve-select-method)" - :type 'string - :group 'gnus-sieve) + :type 'string) ;;;###autoload (defun gnus-sieve-update () diff --git a/lisp/gnus/gnus-topic.el b/lisp/gnus/gnus-topic.el index 402de05210..c491848527 100644 --- a/lisp/gnus/gnus-topic.el +++ b/lisp/gnus/gnus-topic.el @@ -43,8 +43,7 @@ (defcustom gnus-topic-mode-hook nil "Hook run in topic mode buffers." - :type 'hook - :group 'gnus-topic) + :type 'hook) (defcustom gnus-topic-line-format "%i[ %(%{%n%}%) -- %A ]%v\n" "Format of topic lines. @@ -61,18 +60,15 @@ with some simple extensions. General format specifiers can also be used. See Info node `(gnus)Formatting Variables'." :link '(custom-manual "(gnus)Formatting Variables") - :type 'string - :group 'gnus-topic) + :type 'string) (defcustom gnus-topic-indent-level 2 "How much each subtopic should be indented." - :type 'integer - :group 'gnus-topic) + :type 'integer) (defcustom gnus-topic-display-empty-topics t "If non-nil, display the topic lines even of topics that have no unread articles." - :type 'boolean - :group 'gnus-topic) + :type 'boolean) ;; Internal variables. diff --git a/lisp/gnus/gnus-win.el b/lisp/gnus/gnus-win.el index 3fb8e469d0..d8b037ebe4 100644 --- a/lisp/gnus/gnus-win.el +++ b/lisp/gnus/gnus-win.el @@ -36,7 +36,6 @@ (defcustom gnus-use-full-window t "If non-nil, use the entire Emacs screen." - :group 'gnus-windows :type 'boolean) (defcustom gnus-use-atomic-windows nil @@ -46,17 +45,14 @@ (defcustom gnus-window-min-width 2 "Minimum width of Gnus buffers." - :group 'gnus-windows :type 'integer) (defcustom gnus-window-min-height 1 "Minimum height of Gnus buffers." - :group 'gnus-windows :type 'integer) (defcustom gnus-always-force-window-configuration nil "If non-nil, always force the Gnus window configurations." - :group 'gnus-windows :type 'boolean) (defcustom gnus-use-frames-on-any-display nil @@ -64,7 +60,6 @@ When nil, only frames on the same display as the selected frame will be used to display Gnus windows." :version "22.1" - :group 'gnus-windows :type 'boolean) (defvar gnus-buffer-configuration @@ -202,7 +197,6 @@ See the Gnus manual for an explanation of the syntax used.") (defcustom gnus-configure-windows-hook nil "A hook called when configuring windows." :version "22.1" - :group 'gnus-windows :type 'hook) ;;; Internal variables. diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el index 2427977ca8..212657aec2 100644 --- a/lisp/gnus/mail-source.el +++ b/lisp/gnus/mail-source.el @@ -56,7 +56,6 @@ "Where the mail backends will look for incoming mail. This variable is a list of mail source specifiers. See Info node `(gnus)Mail Source Specifiers'." - :group 'mail-source :version "24.4" :link '(custom-manual "(gnus)Mail Source Specifiers") :type `(choice @@ -230,33 +229,27 @@ Leave mails for this many days" :value 14))))) If nil, the user will be prompted when an error occurs. If non-nil, the error will be ignored." :version "22.1" - :group 'mail-source :type 'boolean) (defcustom mail-source-primary-source nil "Primary source for incoming mail. If non-nil, this maildrop will be checked periodically for new mail." - :group 'mail-source :type 'sexp) (defcustom mail-source-flash t "If non-nil, flash periodically when mail is available." - :group 'mail-source :type 'boolean) (defcustom mail-source-crash-box "~/.emacs-mail-crash-box" "File where mail will be stored while processing it." - :group 'mail-source :type 'file) (defcustom mail-source-directory message-directory "Directory where incoming mail source files (if any) will be stored." - :group 'mail-source :type 'directory) (defcustom mail-source-default-file-modes 384 "Set the mode bits of all new mail files to this integer." - :group 'mail-source :type 'integer) (defcustom mail-source-delete-incoming @@ -270,7 +263,6 @@ Removing of old files happens in `mail-source-callback', i.e. no old incoming files will be deleted unless you receive new mail. You may also set this variable to nil and call `mail-source-delete-old-incoming' interactively." - :group 'mail-source :version "22.2" ;; No Gnus / Gnus 5.10.10 (default changed) :type '(choice (const :tag "immediately" t) (const :tag "never" nil) @@ -281,28 +273,23 @@ You may also set this variable to nil and call This variable only applies when `mail-source-delete-incoming' is a positive number." :version "22.2" ;; No Gnus / Gnus 5.10.10 (default changed) - :group 'mail-source :type 'boolean) (defcustom mail-source-incoming-file-prefix "Incoming" "Prefix for file name for storing incoming mail." - :group 'mail-source :type 'string) (defcustom mail-source-report-new-mail-interval 5 "Interval in minutes between checks for new mail." - :group 'mail-source :type 'number) (defcustom mail-source-idle-time-delay 5 "Number of idle seconds to wait before checking for new mail." - :group 'mail-source :type 'number) (defcustom mail-source-movemail-program "movemail" "If non-nil, name of program for fetching new mail." :version "26.2" - :group 'mail-source :type '(choice (const nil) string)) ;;; Internal variables. diff --git a/lisp/gnus/mm-url.el b/lisp/gnus/mm-url.el index 73106a2932..01d25ac61e 100644 --- a/lisp/gnus/mm-url.el +++ b/lisp/gnus/mm-url.el @@ -44,8 +44,7 @@ (defcustom mm-url-use-external nil "If non-nil, use external grab program `mm-url-program'." :version "22.1" - :type 'boolean - :group 'mm-url) + :type 'boolean) (defvar mm-url-predefined-programs '((wget "wget" "--user-agent=mm-url" "-q" "-O" "-") @@ -68,14 +67,12 @@ Likely values are `wget', `w3m', `lynx' and `curl'." (symbol :tag "w3m" w3m) (symbol :tag "lynx" lynx) (symbol :tag "curl" curl) - (string :tag "other")) - :group 'mm-url) + (string :tag "other"))) (defcustom mm-url-arguments nil "The arguments for `mm-url-program'." :version "22.1" - :type '(repeat string) - :group 'mm-url) + :type '(repeat string)) ;;; Internal variables diff --git a/lisp/gnus/nndiary.el b/lisp/gnus/nndiary.el index c1ac3cc5e8..60ef6e9b8e 100644 --- a/lisp/gnus/nndiary.el +++ b/lisp/gnus/nndiary.el @@ -149,7 +149,6 @@ In order to make this clear, here are some examples: - (360 . minute): for an appointment at 18:30 and 15 seconds, this would pop up the appointment message at 12:30." - :group 'nndiary :type '(repeat (cons :format "%v\n" (integer :format "%v") (choice :format "%[%v(s)%] before...\n" @@ -163,8 +162,7 @@ In order to make this clear, here are some examples: (defcustom nndiary-week-starts-on-monday nil "Whether a week starts on monday (otherwise, sunday)." - :type 'boolean - :group 'nndiary) + :type 'boolean) (define-obsolete-variable-alias 'nndiary-request-create-group-hooks @@ -172,7 +170,6 @@ In order to make this clear, here are some examples: (defcustom nndiary-request-create-group-functions nil "Hook run after `nndiary-request-create-group' is executed. The hook functions will be called with the full group name as argument." - :group 'nndiary :type 'hook) (define-obsolete-variable-alias 'nndiary-request-update-info-hooks @@ -180,7 +177,6 @@ The hook functions will be called with the full group name as argument." (defcustom nndiary-request-update-info-functions nil "Hook run after `nndiary-request-update-info' is executed. The hook functions will be called with the full group name as argument." - :group 'nndiary :type 'hook) (define-obsolete-variable-alias 'nndiary-request-accept-article-hooks @@ -189,12 +185,10 @@ The hook functions will be called with the full group name as argument." "Hook run before accepting an article. Executed near the beginning of `nndiary-request-accept-article'. The hook functions will be called with the article in the current buffer." - :group 'nndiary :type 'hook) (defcustom nndiary-check-directory-twice t "If t, check directories twice to avoid NFS failures." - :group 'nndiary :type 'boolean) diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el index 121513117b..4a50f1127b 100644 --- a/lisp/gnus/nnimap.el +++ b/lisp/gnus/nnimap.el @@ -143,8 +143,7 @@ textual parts.") (defcustom nnimap-request-articles-find-limit nil "Limit the number of articles to look for after moving an article." :type '(choice (const nil) integer) - :version "24.4" - :group 'nnimap) + :version "24.4") (define-obsolete-variable-alias 'nnimap-split-download-body-default 'nnimap-split-download-body diff --git a/lisp/gnus/nnmairix.el b/lisp/gnus/nnmairix.el index 2bf5015543..5e8ad4fa9a 100644 --- a/lisp/gnus/nnmairix.el +++ b/lisp/gnus/nnmairix.el @@ -219,20 +219,17 @@ server will be this prefix plus a random number. You can delete unused nnmairix groups on the back end using `nnmairix-purge-old-groups'." :version "23.1" - :type 'string - :group 'nnmairix) + :type 'string) (defcustom nnmairix-mairix-output-buffer "*mairix output*" "Buffer used for mairix output." :version "23.1" - :type 'string - :group 'nnmairix) + :type 'string) (defcustom nnmairix-customize-query-buffer "*mairix query*" "Name of the buffer for customizing Mairix queries." :version "23.1" - :type 'string - :group 'nnmairix) + :type 'string) (defcustom nnmairix-mairix-update-options '("-F" "-Q") "Options when calling mairix for updating the database. @@ -240,21 +237,18 @@ The default is \"-F\" and \"-Q\" for making updates faster. You should call mairix without these options from time to time (e.g. via cron job)." :version "23.1" - :type '(repeat string) - :group 'nnmairix) + :type '(repeat string)) (defcustom nnmairix-mairix-search-options '("-Q") "Options when calling mairix for searching. The default is \"-Q\" for making searching faster." :version "23.1" - :type '(repeat string) - :group 'nnmairix) + :type '(repeat string)) (defcustom nnmairix-mairix-synchronous-update nil "Set this to t if you want Emacs to wait for mairix updating the database." :version "23.1" - :type 'boolean - :group 'nnmairix) + :type 'boolean) (defcustom nnmairix-rename-files-for-nnml t "Rename nnml mail files so that they are consecutively numbered. @@ -263,8 +257,7 @@ article numbers which will produce wrong article counts by Gnus. This option controls whether nnmairix should rename the files consecutively." :version "23.1" - :type 'boolean - :group 'nnmairix) + :type 'boolean) (defcustom nnmairix-widget-fields-list '(("from" "f" "From") ("to" "t" "To") ("cc" "c" "Cc") @@ -288,16 +281,14 @@ nil for disabling this)." (const :tag "Subject" "subject") (const :tag "Message ID" "Message-ID")) (string :tag "Command") - (string :tag "Description"))) - :group 'nnmairix) + (string :tag "Description")))) (defcustom nnmairix-widget-select-window-function (lambda () (select-window (get-largest-window))) "Function for selecting the window for customizing the mairix query. The default chooses the largest window in the current frame." :version "23.1" - :type 'function - :group 'nnmairix) + :type 'function) (defcustom nnmairix-propagate-marks-upon-close t "Flag if marks should be propagated upon closing a group. @@ -308,8 +299,7 @@ call `nnmairix-propagate-marks'." :version "23.1" :type '(choice (const :tag "always" t) (const :tag "ask" ask) - (const :tag "never" nil)) - :group 'nnmairix) + (const :tag "never" nil))) (defcustom nnmairix-propagate-marks-to-nnmairix-groups nil "Flag if marks from original articles should be seen in nnmairix groups. @@ -319,8 +309,7 @@ e.g. an IMAP server (which stores the marks in the maildir file name). You may safely set this to t for testing - the worst that can happen are wrong marks in nnmairix groups." :version "23.1" - :type 'boolean - :group 'nnmairix) + :type 'boolean) (defcustom nnmairix-only-use-registry nil "Use only the registry for determining original group(s). @@ -330,16 +319,14 @@ propagating marks). If set to nil, it will also try to determine the group from an additional mairix search which might be slow when propagating lots of marks." :version "23.1" - :type 'boolean - :group 'nnmairix) + :type 'boolean) (defcustom nnmairix-allowfast-default nil "Whether fast entering should be the default for nnmairix groups. You may set this to t to make entering the group faster, but note that this might lead to problems, especially when used with marks propagation." :version "23.1" - :type 'boolean - :group 'nnmairix) + :type 'boolean) ;; ==== Other variables diff --git a/lisp/gnus/nnrss.el b/lisp/gnus/nnrss.el index a340c9e2b8..b62a6412e5 100644 --- a/lisp/gnus/nnrss.el +++ b/lisp/gnus/nnrss.el @@ -100,7 +100,6 @@ Note that you have to regenerate all the nnrss groups if you change the value. Moreover, you should be patient even if you are made to read the same articles twice, that arises for the difference of the versions of xml.el." - :group 'nnrss :type 'coding-system) (defvar nnrss-compatible-encoding-alist diff --git a/lisp/gnus/smime.el b/lisp/gnus/smime.el index 147c51d89a..8900be5e4f 100644 --- a/lisp/gnus/smime.el +++ b/lisp/gnus/smime.el @@ -135,8 +135,7 @@ certificates to be sent with every message to each address." :type '(repeat (list (string :tag "Mail address") (file :tag "File name") (repeat :tag "Additional certificate files" - (file :tag "File name")))) - :group 'smime) + (file :tag "File name"))))) (defcustom smime-CA-directory nil "Directory containing certificates for CAs you trust. @@ -148,16 +147,14 @@ $ ln -s ca.pem \\=`openssl x509 -noout -hash -in ca.pem\\=`.0 where `ca.pem' is the file containing a PEM encoded X.509 CA certificate." :type '(choice (const :tag "none" nil) - directory) - :group 'smime) + directory)) (defcustom smime-CA-file nil "Files containing certificates for CAs you trust. File should contain certificates in PEM format." :version "22.1" :type '(choice (const :tag "none" nil) - file) - :group 'smime) + file)) (defcustom smime-certificate-directory "~/Mail/certs/" "Directory containing other people's certificates. @@ -166,8 +163,7 @@ and the files themselves should be in PEM format." ;The S/MIME library provide simple functionality for fetching ;certificates into this directory, so there is no need to populate it ;manually. - :type 'directory - :group 'smime) + :type 'directory) (defcustom smime-openssl-program (and (condition-case () @@ -176,8 +172,7 @@ and the files themselves should be in PEM format." "openssl") "Name of OpenSSL binary or nil if none." :type '(choice string - (const :tag "none" nil)) - :group 'smime) + (const :tag "none" nil))) ;; OpenSSL option to select the encryption cipher @@ -191,8 +186,7 @@ and the files themselves should be in PEM format." (const :tag "AES 128 bits" "-aes128") (const :tag "RC2 40 bits" "-rc2-40") (const :tag "RC2 64 bits" "-rc2-64") - (const :tag "RC2 128 bits" "-rc2-128")) - :group 'smime) + (const :tag "RC2 128 bits" "-rc2-128"))) (defcustom smime-crl-check nil "Check revocation status of signers certificate using CRLs. @@ -212,24 +206,21 @@ certificate with .r0 as file name extension. At least OpenSSL version 0.9.7 is required for this to work." :type '(choice (const :tag "No check" nil) (const :tag "Check certificate" "-crl_check") - (const :tag "Check certificate chain" "-crl_check_all")) - :group 'smime) + (const :tag "Check certificate chain" "-crl_check_all"))) (defcustom smime-dns-server nil "DNS server to query certificates from. If nil, use system defaults." :version "22.1" :type '(choice (const :tag "System defaults") - string) - :group 'smime) + string)) (defcustom smime-ldap-host-list nil "A list of LDAP hosts with S/MIME user certificates. If needed search base, binddn, passwd, etc. for the LDAP host must be set in `ldap-host-parameters-alist'." :type '(repeat (string :tag "Host name")) - :version "23.1" ;; No Gnus - :group 'smime) + :version "23.1") ;; No Gnus (defvar smime-details-buffer "*OpenSSL output*") diff --git a/lisp/gnus/spam-report.el b/lisp/gnus/spam-report.el index e2125563f2..11d653d537 100644 --- a/lisp/gnus/spam-report.el +++ b/lisp/gnus/spam-report.el @@ -43,8 +43,7 @@ If you are using spam.el, consider setting gnus-spam-process-newsgroups or the gnus-group-spam-exit-processor-report-gmane group/topic parameter instead." :type '(radio (const nil) - (regexp :value "^nntp\\+.*:gmane\\.")) - :group 'spam-report) + (regexp :value "^nntp\\+.*:gmane\\."))) (defcustom spam-report-gmane-use-article-number t "Whether the article number (faster!) or the header should be used. @@ -52,8 +51,7 @@ instead." You must set this to nil if you don't read Gmane groups directly from news.gmane.org, e.g. when using local newsserver such as leafnode." - :type 'boolean - :group 'spam-report) + :type 'boolean) (defcustom spam-report-url-ping-function 'spam-report-url-ping-plain @@ -66,23 +64,20 @@ The function must accept the arguments `host' and `report'." spam-report-url-ping-mm-url) (const :tag "Store request URLs in `spam-report-requests-file'" spam-report-url-to-file) - (function :tag "User defined function" nil)) - :group 'spam-report) + (function :tag "User defined function" nil))) (defcustom spam-report-requests-file (nnheader-concat gnus-directory "spam/" "spam-report-requests.url") ;; Is there a convention for the extension of such a file? ;; Should we use `spam-directory'? "File where spam report request are stored." - :type 'file - :group 'spam-report) + :type 'file) (defcustom spam-report-resend-to nil "Email address that spam articles are resent to when reporting. If not set, the user will be prompted to enter a value which will be saved for future use." - :type '(choice (const :tag "Prompt" nil) string) - :group 'spam-report) + :type '(choice (const :tag "Prompt" nil) string)) (defvar spam-report-url-ping-temp-agent-function nil "Internal variable for `spam-report-agentize' and `spam-report-deagentize'. @@ -232,8 +227,7 @@ the function specified by `spam-report-url-ping-function'." This is initialized based on `user-mail-address'." :type '(choice string (const :tag "Don't expose address" nil)) - :version "23.1" ;; No Gnus - :group 'spam-report) + :version "23.1") ;; No Gnus (defvar spam-report-user-agent (if spam-report-user-mail-address diff --git a/lisp/gnus/spam-stat.el b/lisp/gnus/spam-stat.el index 89c2deb36f..1980bd1d74 100644 --- a/lisp/gnus/spam-stat.el +++ b/lisp/gnus/spam-stat.el @@ -135,42 +135,35 @@ whether a buffer contains spam or not." (defcustom spam-stat-file "~/.spam-stat.el" "File used to save and load the dictionary. See `spam-stat-to-hash-table' for the format of the file." - :type 'file - :group 'spam-stat) + :type 'file) (defcustom spam-stat-unknown-word-score 0.2 "The score to use for unknown words. Also used for words that don't appear often enough." - :type 'number - :group 'spam-stat) + :type 'number) (defcustom spam-stat-max-word-length 15 "Only words shorter than this will be considered." - :type 'integer - :group 'spam-stat) + :type 'integer) (defcustom spam-stat-max-buffer-length 10240 "Only the beginning of buffers will be analyzed. This variable says how many characters this will be." - :type 'integer - :group 'spam-stat) + :type 'integer) (defcustom spam-stat-split-fancy-spam-group "mail.spam" "Name of the group where spam should be stored. If `spam-stat-split-fancy' is used in fancy splitting rules. Has no effect when spam-stat is invoked through spam.el." - :type 'string - :group 'spam-stat) + :type 'string) (defcustom spam-stat-split-fancy-spam-threshold 0.9 "Spam score threshold in spam-stat-split-fancy." - :type 'number - :group 'spam-stat) + :type 'number) (defcustom spam-stat-washing-hook nil "Hook applied to each message before analysis." - :type 'hook - :group 'spam-stat) + :type 'hook) (defcustom spam-stat-score-buffer-user-functions nil "List of additional scoring functions. @@ -187,8 +180,7 @@ Also be careful when defining such functions. If they take a long time, they will slow down your mail splitting. Thus, if the buffer is large, don't forget to use smaller regions, by wrapping your work in, say, `with-spam-stat-max-buffer-size'." - :type '(repeat sexp) - :group 'spam-stat) + :type '(repeat sexp)) (defcustom spam-stat-process-directory-age 90 "Max. age of files to be processed in directory, in days. @@ -197,8 +189,7 @@ When using `spam-stat-process-spam-directory' or been touched in this many days will be considered. Without this filter, re-training spam-stat with several thousand messages will start to take a very long time." - :type 'number - :group 'spam-stat) + :type 'number) (defvar spam-stat-last-saved-at nil "Time stamp of last change of spam-stat-file on this run") commit f0ca9ad5dcbcf7ab9789087a1f053427e30b3fe4 Author: Stefan Monnier Date: Sat Jan 30 14:15:19 2021 -0500 * lisp/gnus: Demote some macros and defsubsts, plus a fix * lisp/gnus/gnus-sum.el (gnus-summary-thread-level) (gnus-summary-article-mark): Turn macros into `defsubst`. * lisp/gnus/mail-source.el (mail-source-bind-common): Actually use its arg. * lisp/gnus/nntp.el (nntp-copy-to-buffer): Turn macro into a `defsubst`. (nntp-wait-for, nntp-retrieve-data, nntp-send-command): Don't inline those, it's not worth it. diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index b0f9ed4c6f..05e49be093 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -3339,18 +3339,18 @@ article number." ,(or number (inline-quote (gnus-summary-article-number))))))) -(defmacro gnus-summary-thread-level (&optional number) +(defsubst gnus-summary-thread-level (&optional number) "Return the level of thread that starts with article NUMBER." - `(if (and (eq gnus-summary-make-false-root 'dummy) - (get-text-property (point) 'gnus-intangible)) - 0 - (gnus-data-level (gnus-data-find - ,(or number '(gnus-summary-article-number)))))) + (if (and (eq gnus-summary-make-false-root 'dummy) + (get-text-property (point) 'gnus-intangible)) + 0 + (gnus-data-level (gnus-data-find + (or number (gnus-summary-article-number)))))) -(defmacro gnus-summary-article-mark (&optional number) +(defsubst gnus-summary-article-mark (&optional number) "Return the mark of article NUMBER." - `(gnus-data-mark (gnus-data-find - ,(or number '(gnus-summary-article-number))))) + (gnus-data-mark (gnus-data-find + (or number (gnus-summary-article-number))))) (defmacro gnus-summary-article-pos (&optional number) "Return the position of the line of article NUMBER." diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el index c954f65793..2427977ca8 100644 --- a/lisp/gnus/mail-source.el +++ b/lisp/gnus/mail-source.el @@ -515,7 +515,7 @@ the `mail-source-keyword-map' variable." See `mail-source-bind'." (declare (indent 1) (debug (sexp body))) `(let ,(mail-source-bind-common-1) - (mail-source-set-common-1 source) + (mail-source-set-common-1 ,source) ,@body)) (defun mail-source-value (value) diff --git a/lisp/gnus/nntp.el b/lisp/gnus/nntp.el index c2bb960f94..cf89eebbbb 100644 --- a/lisp/gnus/nntp.el +++ b/lisp/gnus/nntp.el @@ -335,16 +335,16 @@ retried once before actually displaying the error report." (apply #'error args))) -(defmacro nntp-copy-to-buffer (buffer start end) +(defsubst nntp-copy-to-buffer (buffer start end) "Copy string from unibyte current buffer to multibyte buffer." - `(let ((string (buffer-substring ,start ,end))) - (with-current-buffer ,buffer + (let ((string (buffer-substring start end))) + (with-current-buffer buffer (erase-buffer) (insert string) (goto-char (point-min)) nil))) -(defsubst nntp-wait-for (process wait-for buffer &optional decode discard) +(defun nntp-wait-for (process wait-for buffer &optional decode discard) "Wait for WAIT-FOR to arrive from PROCESS." (with-current-buffer (process-buffer process) @@ -436,7 +436,7 @@ retried once before actually displaying the error report." (when process (process-buffer process)))) -(defsubst nntp-retrieve-data (command address _port buffer +(defun nntp-retrieve-data (command address _port buffer &optional wait-for callback decode) "Use COMMAND to retrieve data into BUFFER from PORT on ADDRESS." (let ((process (or (nntp-find-connection buffer) @@ -469,7 +469,7 @@ retried once before actually displaying the error report." nil))) (nnheader-report 'nntp "Couldn't open connection to %s" address)))) -(defsubst nntp-send-command (wait-for &rest strings) +(defun nntp-send-command (wait-for &rest strings) "Send STRINGS to server and wait until WAIT-FOR returns." (when (not (or nnheader-callback-function nntp-inhibit-output)) commit 8403b9a36862f3e781cfd9c556a7e981d9ee5417 Author: Stefan Monnier Date: Sat Jan 30 14:12:10 2021 -0500 * lisp/gnus: Use `with-current-buffer` at a few more places * lisp/gnus/nnmbox.el (nnmbox-request-scan, nnmbox-read-mbox): * lisp/gnus/nnmairix.el (nnmairix-create-search-group): * lisp/gnus/nnfolder.el (nnfolder-existing-articles): * lisp/gnus/nndraft.el (nndraft-auto-save-file-name): * lisp/gnus/nndoc.el (nndoc-request-article): * lisp/gnus/nnbabyl.el (nnbabyl-read-mbox): * lisp/gnus/gnus-score.el (gnus-score-body): * lisp/gnus/gnus-start.el (gnus-dribble-enter) (gnus-dribble-eval-file, gnus-ask-server-for-new-groups) (gnus-read-newsrc-file, gnus-read-descriptions-file): * lisp/gnus/gnus-spec.el (gnus-update-format-specifications): * lisp/gnus/gnus-draft.el (gnus-draft-edit-message): * lisp/gnus/gnus-art.el (gnus-request-article-this-buffer) (gnus-article-edit-exit): Use `with-current-buffer`. diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index 7ae4e5836a..7e5439a217 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -7151,13 +7151,11 @@ If given a prefix, show the hidden text instead." (when (and do-update-line (or (numberp article) (stringp article))) - (let ((buf (current-buffer))) - (set-buffer gnus-summary-buffer) + (with-current-buffer gnus-summary-buffer (gnus-summary-update-article do-update-line sparse-header) (gnus-summary-goto-subject do-update-line nil t) (set-window-point (gnus-get-buffer-window (current-buffer) t) - (point)) - (set-buffer buf)))))) + (point))))))) (defun gnus-block-private-groups (group) "Allows images in newsgroups to be shown, blocks images in all @@ -7351,8 +7349,7 @@ groups." (gnus-article-mode) (set-window-configuration winconf) ;; Tippy-toe some to make sure that point remains where it was. - (save-current-buffer - (set-buffer curbuf) + (with-current-buffer curbuf (set-window-start (get-buffer-window (current-buffer)) window-start) (goto-char p)))) (gnus-summary-show-article))) diff --git a/lisp/gnus/gnus-draft.el b/lisp/gnus/gnus-draft.el index 3b380f30c6..0752267e21 100644 --- a/lisp/gnus/gnus-draft.el +++ b/lisp/gnus/gnus-draft.el @@ -101,8 +101,7 @@ (push `((lambda () (when (gnus-buffer-live-p ,gnus-summary-buffer) - (save-excursion - (set-buffer ,gnus-summary-buffer) + (with-current-buffer ,gnus-summary-buffer (gnus-cache-possibly-remove-article ,article nil nil nil t))))) message-send-actions))) diff --git a/lisp/gnus/gnus-score.el b/lisp/gnus/gnus-score.el index c6e08cee73..254f0e548c 100644 --- a/lisp/gnus/gnus-score.el +++ b/lisp/gnus/gnus-score.el @@ -1818,45 +1818,44 @@ score in `gnus-newsgroup-scored' by SCORE." handles)))) (defun gnus-score-body (scores header now expire &optional trace) - (if gnus-agent-fetching - nil - (save-excursion - (setq gnus-scores-articles - (sort gnus-scores-articles - (lambda (a1 a2) - (< (mail-header-number (car a1)) - (mail-header-number (car a2)))))) - (set-buffer nntp-server-buffer) - (save-restriction - (let* ((buffer-read-only nil) - (articles gnus-scores-articles) - (all-scores scores) - (request-func (cond ((string= "head" header) - 'gnus-request-head) - ((string= "body" header) - 'gnus-request-body) - (t 'gnus-request-article))) - entries alist ofunc article last) - (when articles - (setq last (mail-header-number (caar (last articles)))) - ;; Not all backends support partial fetching. In that case, - ;; we just fetch the entire article. - ;; When scoring by body, we need to peek at the headers to detect - ;; the content encoding - (unless (or (gnus-check-backend-function - (and (string-match "^gnus-" (symbol-name request-func)) - (intern (substring (symbol-name request-func) - (match-end 0)))) - gnus-newsgroup-name) - (string= "body" header)) - (setq ofunc request-func) - (setq request-func 'gnus-request-article)) - (while articles - (setq article (mail-header-number (caar articles))) - (gnus-message 7 "Scoring article %s of %s..." article last) - (widen) - (let (handles) - (when (funcall request-func article gnus-newsgroup-name) + (if gnus-agent-fetching + nil + (setq gnus-scores-articles + (sort gnus-scores-articles + (lambda (a1 a2) + (< (mail-header-number (car a1)) + (mail-header-number (car a2)))))) + (with-current-buffer nntp-server-buffer + (save-restriction + (let* ((buffer-read-only nil) + (articles gnus-scores-articles) + (all-scores scores) + (request-func (cond ((string= "head" header) + 'gnus-request-head) + ((string= "body" header) + 'gnus-request-body) + (t 'gnus-request-article))) + entries alist ofunc article last) + (when articles + (setq last (mail-header-number (caar (last articles)))) + ;; Not all backends support partial fetching. In that case, + ;; we just fetch the entire article. + ;; When scoring by body, we need to peek at the headers to detect + ;; the content encoding + (unless (or (gnus-check-backend-function + (and (string-match "^gnus-" (symbol-name request-func)) + (intern (substring (symbol-name request-func) + (match-end 0)))) + gnus-newsgroup-name) + (string= "body" header)) + (setq ofunc request-func) + (setq request-func 'gnus-request-article)) + (while articles + (setq article (mail-header-number (caar articles))) + (gnus-message 7 "Scoring article %s of %s..." article last) + (widen) + (let (handles) + (when (funcall request-func article gnus-newsgroup-name) (when (string= "body" header) (setq handles (gnus-score-decode-text-parts))) (goto-char (point-min)) @@ -1921,8 +1920,8 @@ score in `gnus-newsgroup-scored' by SCORE." (setq rest entries)))) (setq entries rest)))) (when handles (mm-destroy-parts handles)))) - (setq articles (cdr articles))))))) - nil)) + (setq articles (cdr articles))))))) + nil)) (defun gnus-score-thread (scores header now expire &optional trace) (gnus-score-followup scores header now expire trace t)) diff --git a/lisp/gnus/gnus-spec.el b/lisp/gnus/gnus-spec.el index a522855139..0dfa9f99d3 100644 --- a/lisp/gnus/gnus-spec.el +++ b/lisp/gnus/gnus-spec.el @@ -146,7 +146,7 @@ Return a list of updated types." (while (setq type (pop types)) ;; Jump to the proper buffer to find out the value of the ;; variable, if possible. (It may be buffer-local.) - (save-excursion + (save-current-buffer (let ((buffer (intern (format "gnus-%s-buffer" type)))) (when (and (boundp buffer) (setq val (symbol-value buffer)) diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el index cd43876413..a3159595c4 100644 --- a/lisp/gnus/gnus-start.el +++ b/lisp/gnus/gnus-start.el @@ -843,8 +843,7 @@ prompt the user for the name of an NNTP server to use." If REGEXP is given, lines that match it will be deleted." (when (and (not gnus-dribble-ignore) (buffer-live-p gnus-dribble-buffer)) - (let ((obuf (current-buffer))) - (set-buffer gnus-dribble-buffer) + (with-current-buffer gnus-dribble-buffer (when regexp (goto-char (point-min)) (let (end) @@ -859,8 +858,7 @@ If REGEXP is given, lines that match it will be deleted." (insert (replace-regexp-in-string "\n" "\\\\n" string) "\n") (bury-buffer gnus-dribble-buffer) (with-current-buffer gnus-group-buffer - (gnus-group-set-mode-line)) - (set-buffer obuf)))) + (gnus-group-set-mode-line))))) (defun gnus-dribble-touch () "Touch the dribble buffer." @@ -916,9 +914,8 @@ If REGEXP is given, lines that match it will be deleted." (defun gnus-dribble-eval-file () (when gnus-dribble-eval-file (setq gnus-dribble-eval-file nil) - (save-excursion - (let ((gnus-dribble-ignore t)) - (set-buffer gnus-dribble-buffer) + (let ((gnus-dribble-ignore t)) + (with-current-buffer gnus-dribble-buffer (eval-buffer (current-buffer)))))) (defun gnus-dribble-delete-file () @@ -1187,10 +1184,9 @@ for new groups, and subscribe the new groups as zombies." gnus-override-subscribe-method method) (when (and (gnus-check-server method) (gnus-request-newgroups date method)) - (save-excursion - (setq got-new t - hashtb (gnus-make-hashtable 100)) - (set-buffer nntp-server-buffer) + (setq got-new t + hashtb (gnus-make-hashtable 100)) + (with-current-buffer nntp-server-buffer ;; Enter all the new groups into a hashtable. (gnus-active-to-gnus-format method hashtb 'ignore)) ;; Now all new groups from `method' are in `hashtb'. @@ -2250,9 +2246,8 @@ If FORCE is non-nil, the .newsrc file is read." ;; can find there for changing the data already read - ;; i. e., reading the .newsrc file will not trash the data ;; already read (except for read articles). - (save-excursion - (gnus-message 5 "Reading %s..." newsrc-file) - (set-buffer (nnheader-find-file-noselect newsrc-file)) + (gnus-message 5 "Reading %s..." newsrc-file) + (with-current-buffer (nnheader-find-file-noselect newsrc-file) (buffer-disable-undo) (gnus-newsrc-to-gnus-format) (kill-buffer (current-buffer)) @@ -3102,50 +3097,49 @@ SPECIFIC-VARIABLES, or those in `gnus-variable-list'." (gnus-message 1 "Couldn't read newsgroups descriptions") nil) (t - (save-excursion - ;; FIXME: Shouldn't save-restriction be done after set-buffer? - (save-restriction - (set-buffer nntp-server-buffer) - (goto-char (point-min)) - (when (or (search-forward "\n.\n" nil t) - (goto-char (point-max))) - (beginning-of-line) - (narrow-to-region (point-min) (point))) - ;; If these are groups from a foreign select method, we insert the - ;; group prefix in front of the group names. - (and method (not (inline - (gnus-server-equal - (gnus-server-get-method nil method) - (gnus-server-get-method - nil gnus-select-method)))) - (let ((prefix (gnus-group-prefixed-name "" method))) - (goto-char (point-min)) - (while (and (not (eobp)) - (progn (insert prefix) - (zerop (forward-line 1))))))) - (goto-char (point-min)) - (while (not (eobp)) - (setq group - (condition-case () - (read nntp-server-buffer) - (error nil))) - (skip-chars-forward " \t") - (when group - (setq group (if (numberp group) - (number-to-string group) - (symbol-name group))) - (let* ((str (buffer-substring - (point) (progn (end-of-line) (point)))) - (charset - (or (gnus-group-name-charset method group) - (gnus-parameter-charset group) - gnus-default-charset))) - ;; Fixme: Don't decode in unibyte mode. - ;; Double fixme: We're not in unibyte mode, are we? - (when (and str charset) - (setq str (decode-coding-string str charset))) - (puthash group str gnus-description-hashtb))) - (forward-line 1)))) + (with-current-buffer nntp-server-buffer + (save-excursion ;;FIXME: Not sure if it's needed! + (save-restriction + (goto-char (point-min)) + (when (or (search-forward "\n.\n" nil t) + (goto-char (point-max))) + (beginning-of-line) + (narrow-to-region (point-min) (point))) + ;; If these are groups from a foreign select method, we insert the + ;; group prefix in front of the group names. + (and method (not (inline + (gnus-server-equal + (gnus-server-get-method nil method) + (gnus-server-get-method + nil gnus-select-method)))) + (let ((prefix (gnus-group-prefixed-name "" method))) + (goto-char (point-min)) + (while (and (not (eobp)) + (progn (insert prefix) + (zerop (forward-line 1))))))) + (goto-char (point-min)) + (while (not (eobp)) + (setq group + (condition-case () + (read nntp-server-buffer) + (error nil))) + (skip-chars-forward " \t") + (when group + (setq group (if (numberp group) + (number-to-string group) + (symbol-name group))) + (let* ((str (buffer-substring + (point) (progn (end-of-line) (point)))) + (charset + (or (gnus-group-name-charset method group) + (gnus-parameter-charset group) + gnus-default-charset))) + ;; Fixme: Don't decode in unibyte mode. + ;; Double fixme: We're not in unibyte mode, are we? + (when (and str charset) + (setq str (decode-coding-string str charset))) + (puthash group str gnus-description-hashtb))) + (forward-line 1))))) (gnus-message 5 "Reading descriptions file...done") t)))) diff --git a/lisp/gnus/nnbabyl.el b/lisp/gnus/nnbabyl.el index 130f56ad92..5149acc0e7 100644 --- a/lisp/gnus/nnbabyl.el +++ b/lisp/gnus/nnbabyl.el @@ -554,13 +554,12 @@ (with-current-buffer nnbabyl-mbox-buffer (= (buffer-size) (nnheader-file-size nnbabyl-mbox-file)))) ;; This buffer has changed since we read it last. Possibly. - (save-excursion - (let ((delim (concat "^" nnbabyl-mail-delimiter)) - (alist nnbabyl-group-alist) - start end number) - (set-buffer (setq nnbabyl-mbox-buffer - (nnheader-find-file-noselect - nnbabyl-mbox-file nil t))) + (let ((delim (concat "^" nnbabyl-mail-delimiter)) + (alist nnbabyl-group-alist) + start end number) + (with-current-buffer (setq nnbabyl-mbox-buffer + (nnheader-find-file-noselect + nnbabyl-mbox-file nil t)) ;; Save previous buffer mode. (setq nnbabyl-previous-buffer-mode (cons (cons (point-min) (point-max)) diff --git a/lisp/gnus/nndoc.el b/lisp/gnus/nndoc.el index c68e201271..dccf6c1ffb 100644 --- a/lisp/gnus/nndoc.el +++ b/lisp/gnus/nndoc.el @@ -256,11 +256,10 @@ from the document.") (deffoo nndoc-request-article (article &optional newsgroup server buffer) (nndoc-possibly-change-buffer newsgroup server) - (save-excursion - (let ((buffer (or buffer nntp-server-buffer)) - (entry (cdr (assq article nndoc-dissection-alist))) - beg) - (set-buffer buffer) + (let ((buffer (or buffer nntp-server-buffer)) + (entry (cdr (assq article nndoc-dissection-alist))) + beg) + (with-current-buffer buffer (erase-buffer) (when entry (cond diff --git a/lisp/gnus/nndraft.el b/lisp/gnus/nndraft.el index 9e70bb6214..e636636a17 100644 --- a/lisp/gnus/nndraft.el +++ b/lisp/gnus/nndraft.el @@ -322,12 +322,10 @@ are generated if and only if they are also in `message-draft-headers'." args)) (defun nndraft-auto-save-file-name (file) - (save-excursion + (with-current-buffer (gnus-get-buffer-create " *draft tmp*") + (setq buffer-file-name file) (prog1 - (progn - (set-buffer (gnus-get-buffer-create " *draft tmp*")) - (setq buffer-file-name file) - (make-auto-save-file-name)) + (make-auto-save-file-name) (kill-buffer (current-buffer))))) (defun nndraft-articles () diff --git a/lisp/gnus/nnfolder.el b/lisp/gnus/nnfolder.el index 405ab2f92f..70e15c5713 100644 --- a/lisp/gnus/nnfolder.el +++ b/lisp/gnus/nnfolder.el @@ -383,9 +383,8 @@ all. This may very well take some time.") ;; current folder. (defun nnfolder-existing-articles () - (save-excursion - (when nnfolder-current-buffer - (set-buffer nnfolder-current-buffer) + (when nnfolder-current-buffer + (with-current-buffer nnfolder-current-buffer (goto-char (point-min)) (let ((marker (concat "\n" nnfolder-article-marker)) (number "[0-9]+") diff --git a/lisp/gnus/nnmairix.el b/lisp/gnus/nnmairix.el index 54d6c5276e..2bf5015543 100644 --- a/lisp/gnus/nnmairix.el +++ b/lisp/gnus/nnmairix.el @@ -757,10 +757,9 @@ called interactively, user will be asked for parameters." (when (not (listp query)) (setq query (list query))) (when (and server group query) - (save-excursion - (let ((groupname (gnus-group-prefixed-name group server)) - info) - (set-buffer gnus-group-buffer) + (let ((groupname (gnus-group-prefixed-name group server)) + ) ;; info + (with-current-buffer gnus-group-buffer (gnus-group-make-group group server) (gnus-group-set-parameter groupname 'query query) (gnus-group-set-parameter groupname 'threads threads) diff --git a/lisp/gnus/nnmbox.el b/lisp/gnus/nnmbox.el index a4863c3e1f..92c7dde9c8 100644 --- a/lisp/gnus/nnmbox.el +++ b/lisp/gnus/nnmbox.el @@ -207,9 +207,8 @@ (file-name-directory nnmbox-mbox-file) group (lambda () - (save-excursion - (let ((in-buf (current-buffer))) - (set-buffer nnmbox-mbox-buffer) + (let ((in-buf (current-buffer))) + (with-current-buffer nnmbox-mbox-buffer (goto-char (point-max)) (insert-buffer-substring in-buf))) (nnmbox-save-active nnmbox-group-alist nnmbox-active-file)))) @@ -622,16 +621,15 @@ (with-current-buffer nnmbox-mbox-buffer (= (buffer-size) (nnheader-file-size nnmbox-mbox-file)))) () - (save-excursion - (let ((delim (concat "^" message-unix-mail-delimiter)) - (alist nnmbox-group-alist) - (nnmbox-group-building-active-articles t) - start end end-header number) - (set-buffer (setq nnmbox-mbox-buffer - (let ((nnheader-file-coding-system - nnmbox-file-coding-system)) - (nnheader-find-file-noselect - nnmbox-mbox-file t t)))) + (let ((delim (concat "^" message-unix-mail-delimiter)) + (alist nnmbox-group-alist) + (nnmbox-group-building-active-articles t) + start end end-header number) + (with-current-buffer (setq nnmbox-mbox-buffer + (let ((nnheader-file-coding-system + nnmbox-file-coding-system)) + (nnheader-find-file-noselect + nnmbox-mbox-file t t))) (mm-enable-multibyte) (buffer-disable-undo) (gnus-add-buffer) commit 419a33eb1dd37fe529e756e04253ff1c9ad2eeb1 Author: Eli Zaretskii Date: Sat Jan 30 21:13:53 2021 +0200 Fix NS build broken by a recent change * src/nsmenu.m (set_frame_menubar, Fns_reset_menu): Adapt to recent changes in set_frame_menubar. (Bug#45759) diff --git a/src/nsmenu.m b/src/nsmenu.m index f8219d2702..24aa5a0ac1 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -405,7 +405,7 @@ frame's menus have changed, and the *step representation should be updated from Lisp. */ void -set_frame_menubar (struct frame *f, bool first_time, bool deep_p) +set_frame_menubar (struct frame *f, bool deep_p) { ns_update_menubar (f, deep_p); } @@ -1795,7 +1795,7 @@ - (Lisp_Object)runDialogAt: (NSPoint)p doc: /* Cause the NS menu to be re-calculated. */) (void) { - set_frame_menubar (SELECTED_FRAME (), 1, 0); + set_frame_menubar (SELECTED_FRAME (), 0); return Qnil; } commit b32d4bf682c41e30c46d154093eb3b00dab6b0a5 Author: Juri Linkov Date: Sat Jan 30 21:12:37 2021 +0200 Allow the caller to specify own face on suffix in annotation-function * lisp/minibuffer.el (completion--insert-strings): Don't add 'completions-annotations' face when the caller specified own face in annotation-function. Remove no-op code for 'unless prefix' branch. (completion-metadata, completion-extra-properties): Update docs of affixation-function. Suggested by Clemens (bug#45780) * test/lisp/minibuffer-tests.el: Rename package name from completion-tests.el to minibuffer-tests.el. Add new test completion--insert-strings-faces. * doc/lispref/minibuf.texi (Completion Variables) (Programmed Completion): Update descriptions of annotation-function and affixation-function. diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index 0ce17ed571..185d355ba7 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -1799,15 +1799,19 @@ pairs. The following properties are supported: The value should be a function to add annotations in the completions buffer. This function must accept one argument, a completion, and should either return @code{nil} or a string to be displayed next to -the completion. +the completion. Unless this function puts own face on the annotation +suffix string, the @code{completions-annotations} face is added by +default to that string. @item :affixation-function The value should be a function to add prefixes and suffixes to completions. This function must accept one argument, a list of completions, and should return such a list of completions where each element contains a list of three elements: a completion, -a prefix string, and a suffix string. This function takes priority -over @code{:annotation-function}. +a prefix string, and a suffix string. When this function +returns a list of two elements, it is interpreted as a list +of a completion and a suffix string like in @code{:annotation-function}. +This function takes priority over @code{:annotation-function}. @item :exit-function The value should be a function to run after performing completion. @@ -1907,6 +1911,9 @@ The value should be a function for @dfn{annotating} completions. The function should take one argument, @var{string}, which is a possible completion. It should return a string, which is displayed after the completion @var{string} in the @file{*Completions*} buffer. +Unless this function puts own face on the annotation suffix string, +the @code{completions-annotations} face is added by default to +that string. @item affixation-function The value should be a function for adding prefixes and suffixes to @@ -1915,8 +1922,10 @@ completions. The function should take one argument, return such a list of @var{completions} where each element contains a list of three elements: a completion, a prefix which is displayed before the completion string in the @file{*Completions*} buffer, and -a suffix displayed after the completion string. This function -takes priority over @code{annotation-function}. +a suffix displayed after the completion string. When this function +returns a list of two elements, it is interpreted as a list of +a completion and a suffix string like in @code{annotation-function}. +This function takes priority over @code{annotation-function}. @item display-sort-function The value should be a function for sorting completions. The function diff --git a/etc/NEWS b/etc/NEWS index 483375e8a2..29499639e7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2017,6 +2017,9 @@ directory instead of the default directory. * Incompatible Lisp Changes in Emacs 28.1 +** 'completions-annotations' face is not used when the caller puts own face. +This affects the suffix specified by completion 'annotation-function'. + ** 'set-process-buffer' now updates the process mark. The mark will be set to point to the end of the new buffer. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 315f2d369a..03cc70c0d4 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -122,7 +122,8 @@ This metadata is an alist. Currently understood keys are: returns a string to append to STRING. - `affixation-function': function to prepend/append a prefix/suffix to entries. Takes one argument (COMPLETIONS) and should return a list - of completions with a list of three elements: completion, its prefix + of completions with a list of either two elements: completion + and suffix, or three elements: completion, its prefix and suffix. This function takes priority over `annotation-function' when both are provided, so only this function is used. - `display-sort-function': function to sort entries in *Completions*. @@ -1785,22 +1786,17 @@ It also eliminates runs of equal strings." (when prefix (let ((beg (point)) (end (progn (insert prefix) (point)))) - (put-text-property beg end 'mouse-face nil) - ;; When both prefix and suffix are added - ;; by the caller via affixation-function, - ;; then allow the caller to decide - ;; what faces to put on prefix and suffix. - (unless prefix - (font-lock-prepend-text-property - beg end 'face 'completions-annotations)))) + (put-text-property beg end 'mouse-face nil))) (put-text-property (point) (progn (insert (car str)) (point)) 'mouse-face 'highlight) (let ((beg (point)) (end (progn (insert suffix) (point)))) (put-text-property beg end 'mouse-face nil) ;; Put the predefined face only when suffix - ;; is added via annotation-function. - (unless prefix + ;; is added via annotation-function without prefix, + ;; and when the caller doesn't use own face. + (unless (or prefix (text-property-not-all + 0 (length suffix) 'face nil suffix)) (font-lock-prepend-text-property beg end 'face 'completions-annotations))))) (cond @@ -1927,6 +1923,7 @@ These include: `:affixation-function': Function to prepend/append a prefix/suffix to completions. The function must accept one argument, a list of completions, and return a list where each element is a list of + either two elements: a completion, and a suffix, or three elements: a completion, a prefix and a suffix. This function takes priority over `:annotation-function' when both are provided, so only this function is used. diff --git a/test/lisp/minibuffer-tests.el b/test/lisp/minibuffer-tests.el index 3ebca14a28..7349b191ca 100644 --- a/test/lisp/minibuffer-tests.el +++ b/test/lisp/minibuffer-tests.el @@ -1,4 +1,4 @@ -;;; completion-tests.el --- Tests for completion functions -*- lexical-binding: t; -*- +;;; minibuffer-tests.el --- Tests for completion functions -*- lexical-binding: t; -*- ;; Copyright (C) 2013-2021 Free Software Foundation, Inc. @@ -107,5 +107,23 @@ nil (length input)) (cons output (length output))))))) -(provide 'completion-tests) -;;; completion-tests.el ends here +(ert-deftest completion--insert-strings-faces () + (with-temp-buffer + (completion--insert-strings + '(("completion1" "suffix1"))) + (should (equal (get-text-property 12 'face) '(completions-annotations)))) + (with-temp-buffer + (completion--insert-strings + '(("completion1" #("suffix1" 0 7 (face shadow))))) + (should (equal (get-text-property 12 'face) 'shadow))) + (with-temp-buffer + (completion--insert-strings + '(("completion1" "prefix1" "suffix1"))) + (should (equal (get-text-property 19 'face) nil))) + (with-temp-buffer + (completion--insert-strings + '(("completion1" "prefix1" #("suffix1" 0 7 (face shadow))))) + (should (equal (get-text-property 19 'face) 'shadow)))) + +(provide 'minibuffer-tests) +;;; minibuffer-tests.el ends here commit 42f45e52aacf513abf3dafe1773bf64f04cf5299 Author: Basil L. Contovounesios Date: Sat Jan 30 19:09:46 2021 +0000 ; Improve defcustom :type in last change. diff --git a/lisp/isearch.el b/lisp/isearch.el index a6978a4c16..82d64c5766 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -362,7 +362,7 @@ This setting only has effect when the search string is less than "For search strings at least this long, lazy highlight starts immediately. For shorter search strings, `lazy-highlight-initial-delay' applies." - :type 'number + :type 'integer :group 'lazy-highlight :version "28.1") commit ece7425c22633196ae164cb6aa0e6d77fabe9f81 Author: Augusto Stoffel Date: Wed Jan 27 16:09:38 2021 +0100 Reduce flicker in Isearch mode Lazy highlighting now happens immediately when the search string is at least as long as the value of the new custom variable `lazy-highlight-no-delay-length`. Also avoid updating the lazy count in the echo area too often. * isearch.el (lazy-highlight-no-delay-length): New defcustom. * isearch.el (lazy-lazy-count-format): Avoid a momentarily incorrect count when reversing search direction. * isearch.el (isearch-lazy-highlight-new-loop): Avoid a call to `isearch-message` that is quickly succeed by a second echo area update, thus causing flicker. * isearch.el (isearch-lazy-highlight-new-loop): Start lazy highlight immediately if appropriate. * etc/NEWS: Announce the change. * doc/emacs/search.texi: Document `lazy-highlight-no-delay-length'. Copyright-paperwork-exempt: yes diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi index 637867b811..f3c42bcea7 100644 --- a/doc/emacs/search.texi +++ b/doc/emacs/search.texi @@ -2027,6 +2027,13 @@ highlighting: @item lazy-highlight-initial-delay @vindex lazy-highlight-initial-delay Time in seconds to wait before highlighting visible matches. +Applies only if the search string is less than +@code{lazy-highlight-no-delay-length} characters long. + +@item lazy-highlight-no-delay-length +@vindex lazy-highlight-no-delay-length +For search strings at least as long as the value of this variable, +lazy highlighting of matches starts immediately. @item lazy-highlight-interval @vindex lazy-highlight-interval diff --git a/etc/NEWS b/etc/NEWS index 7b4b7fea5a..483375e8a2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -226,6 +226,13 @@ C-M- instead of . Either variant can be used as input; functions such as 'kbd' and 'read-kbd-macro' accept both styles as equivalent (they have done so for a long time). ++++ +** New user option 'lazy-highlight-no-delay-length'. +Lazy highlighting of matches in Isearch now starts immediately if the +search string is at least this long. 'lazy-highlight-initial-delay' +still applies for shorter search strings, which avoids flicker in the +search buffer due to too many matches being highlighted. + * Editing Changes in Emacs 28.1 diff --git a/lisp/isearch.el b/lisp/isearch.el index a1e3fe2c3f..a6978a4c16 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -352,10 +352,20 @@ If this is nil, extra highlighting can be \"manually\" removed with :group 'lazy-highlight) (defcustom lazy-highlight-initial-delay 0.25 - "Seconds to wait before beginning to lazily highlight all matches." + "Seconds to wait before beginning to lazily highlight all matches. +This setting only has effect when the search string is less than +`lazy-highlight-no-delay-length' characters long." :type 'number :group 'lazy-highlight) +(defcustom lazy-highlight-no-delay-length 3 + "For search strings at least this long, lazy highlight starts immediately. +For shorter search strings, `lazy-highlight-initial-delay' +applies." + :type 'number + :group 'lazy-highlight + :version "28.1") + (defcustom lazy-highlight-interval 0 ; 0.0625 "Seconds between lazily highlighting successive matches." :type 'number @@ -3356,7 +3366,7 @@ isearch-message-suffix prompt. Otherwise, for isearch-message-prefix." (not isearch-error) (not isearch-suspended)) (format format-string - (if isearch-forward + (if isearch-lazy-highlight-forward isearch-lazy-count-current (if (eq isearch-lazy-count-current 0) 0 @@ -3916,7 +3926,8 @@ by other Emacs features." (clrhash isearch-lazy-count-hash) (setq isearch-lazy-count-current nil isearch-lazy-count-total nil) - (isearch-message))) + ;; Delay updating the message if possible, to avoid flicker + (when (string-equal isearch-string "") (isearch-message)))) (setq isearch-lazy-highlight-window-start-changed nil) (setq isearch-lazy-highlight-window-end-changed nil) (setq isearch-lazy-highlight-error isearch-error) @@ -3961,7 +3972,11 @@ by other Emacs features." (point-min)))) (unless (equal isearch-string "") (setq isearch-lazy-highlight-timer - (run-with-idle-timer lazy-highlight-initial-delay nil + (run-with-idle-timer (if (>= (length isearch-string) + lazy-highlight-no-delay-length) + 0 + lazy-highlight-initial-delay) + nil 'isearch-lazy-highlight-start)))) ;; Update the current match number only in isearch-mode and ;; unless isearch-mode is used specially with isearch-message-function commit 8b3eb67be31730fd0eefc482a5d2d3f85449f881 Author: Stefan Monnier Date: Sat Jan 30 00:45:22 2021 -0500 * lisp/gnus/gnus-msg.el: Remove empty `unwind-protect`s (gnus-msg-mail, gnus-group-mail) (gnus-group-news, gnus-summary-mail-other-window) (gnus-summary-news-other-window): Remove empty `unwind-protect`. diff --git a/lisp/gnus/gnus-msg.el b/lisp/gnus/gnus-msg.el index 278b1d9d73..9ca82f881a 100644 --- a/lisp/gnus/gnus-msg.el +++ b/lisp/gnus/gnus-msg.el @@ -519,12 +519,11 @@ instead." ;; Don't use posting styles corresponding to any existing group. (group-name gnus-newsgroup-name) mail-buf) - (unwind-protect - (progn - (let ((gnus-newsgroup-name "")) - (gnus-setup-message 'message - (message-mail to subject other-headers continue - nil yank-action send-actions return-action))))) + (let ((gnus-newsgroup-name "")) + (gnus-setup-message + 'message + (message-mail to subject other-headers continue + nil yank-action send-actions return-action))) (when switch-action (setq mail-buf (current-buffer)) (switch-to-buffer buf) @@ -615,17 +614,15 @@ If ARG is 1, prompt for a group name to find the posting style." ;; make sure last viewed article doesn't affect posting styles: (gnus-article-copy) (buffer (current-buffer))) - (unwind-protect - (progn - (let ((gnus-newsgroup-name - (if arg - (if (= 1 (prefix-numeric-value arg)) - (gnus-group-completing-read - "Use posting style of group" - nil (gnus-read-active-file-p)) - (gnus-group-group-name)) - ""))) - (gnus-setup-message 'message (message-mail))))))) + (let ((gnus-newsgroup-name + (if arg + (if (= 1 (prefix-numeric-value arg)) + (gnus-group-completing-read + "Use posting style of group" + nil (gnus-read-active-file-p)) + (gnus-group-group-name)) + ""))) + (gnus-setup-message 'message (message-mail))))) (defun gnus-group-news (&optional arg) "Start composing a news. @@ -642,18 +639,17 @@ network. The corresponding back end must have a `request-post' method." ;; make sure last viewed article doesn't affect posting styles: (gnus-article-copy) (buffer (current-buffer))) - (unwind-protect - (progn - (let ((gnus-newsgroup-name - (if arg - (if (= 1 (prefix-numeric-value arg)) - (gnus-group-completing-read "Use group" - nil - (gnus-read-active-file-p)) - (gnus-group-group-name)) - ""))) - (gnus-setup-message 'message - (message-news (gnus-group-real-name gnus-newsgroup-name)))))))) + (let ((gnus-newsgroup-name + (if arg + (if (= 1 (prefix-numeric-value arg)) + (gnus-group-completing-read "Use group" + nil + (gnus-read-active-file-p)) + (gnus-group-group-name)) + ""))) + (gnus-setup-message + 'message + (message-news (gnus-group-real-name gnus-newsgroup-name)))))) (defun gnus-group-post-news (&optional arg) "Start composing a message (a news by default). @@ -686,17 +682,15 @@ posting style." ;; make sure last viewed article doesn't affect posting styles: (gnus-article-copy) (buffer (current-buffer))) - (unwind-protect - (progn - (let ((gnus-newsgroup-name - (if arg - (if (= 1 (prefix-numeric-value arg)) - (gnus-group-completing-read "Use group" - nil - (gnus-read-active-file-p)) - "") - gnus-newsgroup-name))) - (gnus-setup-message 'message (message-mail))))))) + (let ((gnus-newsgroup-name + (if arg + (if (= 1 (prefix-numeric-value arg)) + (gnus-group-completing-read "Use group" + nil + (gnus-read-active-file-p)) + "") + gnus-newsgroup-name))) + (gnus-setup-message 'message (message-mail))))) (defun gnus-summary-news-other-window (&optional arg) "Start composing a news in another window. @@ -713,23 +707,22 @@ network. The corresponding back end must have a `request-post' method." ;; make sure last viewed article doesn't affect posting styles: (gnus-article-copy) (buffer (current-buffer))) - (unwind-protect - (progn - (let ((gnus-newsgroup-name - (if arg - (if (= 1 (prefix-numeric-value arg)) - (gnus-group-completing-read "Use group" - nil - (gnus-read-active-file-p)) - "") - gnus-newsgroup-name))) - (gnus-setup-message 'message - (progn - (message-news (gnus-group-real-name gnus-newsgroup-name)) - (setq-local gnus-discouraged-post-methods - (remove - (car (gnus-find-method-for-group gnus-newsgroup-name)) - gnus-discouraged-post-methods))))))))) + (let ((gnus-newsgroup-name + (if arg + (if (= 1 (prefix-numeric-value arg)) + (gnus-group-completing-read "Use group" + nil + (gnus-read-active-file-p)) + "") + gnus-newsgroup-name))) + (gnus-setup-message + 'message + (progn + (message-news (gnus-group-real-name gnus-newsgroup-name)) + (setq-local gnus-discouraged-post-methods + (remove + (car (gnus-find-method-for-group gnus-newsgroup-name)) + gnus-discouraged-post-methods))))))) (defun gnus-summary-post-news (&optional arg) "Start composing a message. Post to the current group by default. commit 9e96fca53dbd9f52b69341dbb5d9849fd2b5a16c Author: Stefan Monnier Date: Sat Jan 30 00:40:21 2021 -0500 * lisp/gnus/mm-encode.el (mm-default-file-type): New name Rename from misleading `mm-default-file-encoding`. (mm-default-file-encoding): Redefine as obsolete alias. * lisp/mail/sendmail.el (mail-add-attachment): * lisp/mh-e/mh-mime.el (mh-minibuffer-read-type): * lisp/gnus/gnus-art.el (gnus-mime-view-part-as-type-internal): * lisp/gnus/gnus-dired.el (gnus-dired-attach): * lisp/gnus/mml.el (mml-generate-mime-1, mml-minibuffer-read-type) (mml-attach-file): Use the new name. diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index ca24e6f251..7ae4e5836a 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -5206,7 +5206,7 @@ Use CMD as the process." (mail-content-type-get (mm-handle-type handle) 'name) ;; Content-Disposition: attachment; filename=... (cdr (assq 'filename (cdr (mm-handle-disposition handle)))))) - (def-type (and name (mm-default-file-encoding name)))) + (def-type (and name (mm-default-file-type name)))) (or (and def-type (cons def-type 0)) (and handle (equal (mm-handle-media-supertype handle) "text") diff --git a/lisp/gnus/gnus-dired.el b/lisp/gnus/gnus-dired.el index e78163afe2..e412dd01a2 100644 --- a/lisp/gnus/gnus-dired.el +++ b/lisp/gnus/gnus-dired.el @@ -40,7 +40,6 @@ (require 'dired) (autoload 'mml-attach-file "mml") -(autoload 'mm-default-file-encoding "mm-decode");; Shift this to `mailcap.el'? (autoload 'mailcap-extension-to-mime "mailcap") (autoload 'mailcap-mime-info "mailcap") @@ -166,8 +165,9 @@ filenames." (goto-char (point-max)) ;attach at end of buffer (while files-to-attach (mml-attach-file (car files-to-attach) - (or (mm-default-file-encoding (car files-to-attach)) - "application/octet-stream") nil) + (or (mm-default-file-type (car files-to-attach)) + "application/octet-stream") + nil) (setq files-to-attach (cdr files-to-attach))) (message "Attached file(s) %s" files-str)))) diff --git a/lisp/gnus/mm-encode.el b/lisp/gnus/mm-encode.el index 8bd3e0b3d2..31d613146b 100644 --- a/lisp/gnus/mm-encode.el +++ b/lisp/gnus/mm-encode.el @@ -98,9 +98,12 @@ This variable should never be set directly, but bound before a call to boundary)) ;;;###autoload -(defun mm-default-file-encoding (file) - "Return a default encoding for FILE." - (if (not (string-match "\\.[^.]+$" file)) +(define-obsolete-function-alias 'mm-default-file-encoding + #'mm-default-file-type "future") ;Old bad name. +;;;###autoload +(defun mm-default-file-type (file) + "Return a default content type for FILE." + (if (not (string-match "\\.[^.]+\\'" file)) "application/octet-stream" (mailcap-extension-to-mime (match-string 0 file)))) diff --git a/lisp/gnus/mml.el b/lisp/gnus/mml.el index 752dede8d0..acde958c05 100644 --- a/lisp/gnus/mml.el +++ b/lisp/gnus/mml.el @@ -617,7 +617,7 @@ type detected." (filename (cdr (assq 'filename cont))) (type (or (cdr (assq 'type cont)) (if filename - (or (mm-default-file-encoding filename) + (or (mm-default-file-type filename) "application/octet-stream") "text/plain"))) (charset (cdr (assq 'charset cont))) @@ -775,7 +775,7 @@ type detected." (insert "Content-Type: " (or (cdr (assq 'type cont)) (if name - (or (mm-default-file-encoding name) + (or (mm-default-file-type name) "application/octet-stream") "text/plain")) "\n") @@ -1304,7 +1304,7 @@ If not set, `default-directory' will be used." (require 'mailcap) (mailcap-parse-mimetypes) (let* ((default (or default - (mm-default-file-encoding name) + (mm-default-file-type name) ;; Perhaps here we should check what the file ;; looks like, and offer text/plain if it looks ;; like text/plain. @@ -1426,7 +1426,7 @@ will be computed and used." (interactive (let* ((file (mml-minibuffer-read-file "Attach file: ")) (type (if current-prefix-arg - (or (mm-default-file-encoding file) + (or (mm-default-file-type file) "application/octet-stream") (mml-minibuffer-read-type file))) (description (if current-prefix-arg diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el index d2601c35e8..cd07166756 100644 --- a/lisp/mail/sendmail.el +++ b/lisp/mail/sendmail.el @@ -1800,14 +1800,14 @@ If the current line has `mail-yank-prefix', insert it on the new line." (declare-function mml-attach-file "mml" (file &optional type description disposition)) -(declare-function mm-default-file-encoding "mm-encode" (file)) (defun mail-add-attachment (file) "Add FILE as a MIME attachment to the end of the mail message being composed." (interactive "fAttach file: ") (mml-attach-file file - (or (mm-default-file-encoding file) - "application/octet-stream") nil) + (or (mm-default-file-type file) + "application/octet-stream") + nil) (setq mail-encode-mml t)) diff --git a/lisp/mh-e/mh-mime.el b/lisp/mh-e/mh-mime.el index 7bdf743fc4..70df9e6b0f 100644 --- a/lisp/mh-e/mh-mime.el +++ b/lisp/mh-e/mh-mime.el @@ -1725,14 +1725,14 @@ a type (see `mailcap-mime-types'). Optional argument DEFAULT is returned if a type isn't entered." (mailcap-parse-mimetypes) (let* ((default (or default - (mm-default-file-encoding filename) + (mm-default-file-type filename) "application/octet-stream")) (probed-type (mh-file-mime-type filename)) (type (or (and (not (equal probed-type "application/octet-stream")) probed-type) (completing-read (format "Content type (default %s): " default) - (mapcar 'list (mailcap-mime-types)))))) + (mapcar #'list (mailcap-mime-types)))))) (if (not (equal type "")) type default))) commit d6f8bce6d4595bc1af53772fa0f302e16adcbf23 Author: Stefan Monnier Date: Sat Jan 30 00:35:24 2021 -0500 * lisp/gnus: Quote functions with #' To get better warnings, try and use #' to quote function names. * lisp/gnus/canlock.el: * lisp/gnus/deuglify.el: * lisp/gnus/gmm-utils.el: * lisp/gnus/gnus-agent.el: * lisp/gnus/gnus-art.el: * lisp/gnus/gnus-bookmark.el: * lisp/gnus/gnus-cache.el: * lisp/gnus/gnus-cite.el: * lisp/gnus/gnus-cus.el: * lisp/gnus/gnus-delay.el: * lisp/gnus/gnus-diary.el: * lisp/gnus/gnus-dired.el: * lisp/gnus/gnus-draft.el: * lisp/gnus/gnus-fun.el: * lisp/gnus/gnus-group.el: * lisp/gnus/gnus-html.el: * lisp/gnus/gnus-int.el: * lisp/gnus/gnus-kill.el: * lisp/gnus/gnus-mlspl.el: * lisp/gnus/gnus-msg.el: * lisp/gnus/gnus-notifications.el: * lisp/gnus/gnus-picon.el: * lisp/gnus/gnus-registry.el: * lisp/gnus/gnus-rfc1843.el: * lisp/gnus/gnus-salt.el: * lisp/gnus/gnus-score.el: * lisp/gnus/gnus-search.el: * lisp/gnus/gnus-sieve.el: * lisp/gnus/gnus-srvr.el: * lisp/gnus/gnus-start.el: * lisp/gnus/gnus-topic.el: * lisp/gnus/gnus-undo.el: * lisp/gnus/gnus-util.el: * lisp/gnus/gnus-uu.el: * lisp/gnus/gnus.el: * lisp/gnus/mail-source.el: * lisp/gnus/message.el: * lisp/gnus/mm-archive.el: * lisp/gnus/mm-decode.el: * lisp/gnus/mm-url.el: * lisp/gnus/mm-util.el: * lisp/gnus/mm-view.el: * lisp/gnus/mml-sec.el: * lisp/gnus/mml-smime.el: * lisp/gnus/mml.el: * lisp/gnus/nnagent.el: * lisp/gnus/nndiary.el: * lisp/gnus/nndoc.el: * lisp/gnus/nndraft.el: * lisp/gnus/nnfolder.el: * lisp/gnus/nnheader.el: * lisp/gnus/nnmail.el: * lisp/gnus/nnmaildir.el: * lisp/gnus/nnmairix.el: * lisp/gnus/nnmh.el: * lisp/gnus/nnml.el: * lisp/gnus/nnrss.el: * lisp/gnus/nnselect.el: * lisp/gnus/nnspool.el: * lisp/gnus/nnvirtual.el: * lisp/gnus/nnweb.el: * lisp/gnus/smiley.el: * lisp/gnus/smime.el: * lisp/gnus/spam-report.el: * lisp/gnus/spam-stat.el: * lisp/gnus/spam-wash.el: * lisp/gnus/spam.el: diff --git a/lisp/gnus/canlock.el b/lisp/gnus/canlock.el index 6c8c1a5927..e203ebc0a9 100644 --- a/lisp/gnus/canlock.el +++ b/lisp/gnus/canlock.el @@ -30,7 +30,7 @@ ;; Key) header in a news article by using a hook which will be evaluated ;; just before sending an article as follows: ;; -;; (add-hook '*e**a*e-header-hook 'canlock-insert-header t) +;; (add-hook '*e**a*e-header-hook #'canlock-insert-header t) ;; ;; Verifying Cancel-Lock is mainly a function of news servers, however, ;; you can verify your own article using the command `canlock-verify' in diff --git a/lisp/gnus/deuglify.el b/lisp/gnus/deuglify.el index b77dcdd462..4f9ac26ed8 100644 --- a/lisp/gnus/deuglify.el +++ b/lisp/gnus/deuglify.el @@ -155,15 +155,15 @@ ;; To automatically invoke deuglification on every article you read, ;; put something like that in your .gnus: ;; -;; (add-hook 'gnus-article-decode-hook 'gnus-article-outlook-unwrap-lines) +;; (add-hook 'gnus-article-decode-hook #'gnus-article-outlook-unwrap-lines) ;; ;; or _one_ of the following lines: ;; ;; ;; repair broken attribution lines -;; (add-hook 'gnus-article-decode-hook 'gnus-article-outlook-repair-attribution) +;; (add-hook 'gnus-article-decode-hook #'gnus-article-outlook-repair-attribution) ;; ;; ;; repair broken attribution lines and citations -;; (add-hook 'gnus-article-decode-hook 'gnus-article-outlook-rearrange-citation) +;; (add-hook 'gnus-article-decode-hook #'gnus-article-outlook-rearrange-citation) ;; ;; Note that there always may be some false positives, so I suggest ;; using the manual invocation. After deuglification you may want to diff --git a/lisp/gnus/gmm-utils.el b/lisp/gnus/gmm-utils.el index ab97c593d9..5e27a2f93a 100644 --- a/lisp/gnus/gmm-utils.el +++ b/lisp/gnus/gmm-utils.el @@ -69,18 +69,18 @@ Guideline for numbers: 7 - not very important messages on stuff 9 - messages inside loops." (if (<= level gmm-verbose) - (apply 'message args) + (apply #'message args) ;; We have to do this format thingy here even if the result isn't ;; shown - the return value has to be the same as the return value ;; from `message'. - (apply 'format args))) + (apply #'format args))) ;;;###autoload (defun gmm-error (level &rest args) "Beep an error if LEVEL is equal to or less than `gmm-verbose'. ARGS are passed to `message'." (when (<= (floor level) gmm-verbose) - (apply 'message args) + (apply #'message args) (ding) (let (duration) (when (and (floatp level) @@ -215,18 +215,18 @@ DEFAULT-MAP specifies the default key map for ICON-LIST." ;; The dummy `gmm-ignore', see `gmm-tool-bar-item' ;; widget. Suppress tooltip by adding `:enable nil'. (if (fboundp 'tool-bar-local-item) - (apply 'tool-bar-local-item icon nil nil + (apply #'tool-bar-local-item icon nil nil map :enable nil props) ;; (tool-bar-local-item ICON DEF KEY MAP &rest PROPS) ;; (tool-bar-add-item ICON DEF KEY &rest PROPS) - (apply 'tool-bar-add-item icon nil nil :enable nil props))) + (apply #'tool-bar-add-item icon nil nil :enable nil props))) ((equal fmap t) ;; Not a menu command - (apply 'tool-bar-local-item + (apply #'tool-bar-local-item icon command (intern icon) ;; reuse icon or fmap here? map props)) (t ;; A menu command - (apply 'tool-bar-local-item-from-menu + (apply #'tool-bar-local-item-from-menu ;; (apply 'tool-bar-local-item icon def key ;; tool-bar-map props) command icon map (symbol-value fmap) diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el index 46a4af8214..cb679b849f 100644 --- a/lisp/gnus/gnus-agent.el +++ b/lisp/gnus/gnus-agent.el @@ -248,9 +248,9 @@ Actually a hash table holding subjects mapped to t.") (gnus-agent-read-servers) (gnus-category-read) (gnus-agent-create-buffer) - (add-hook 'gnus-group-mode-hook 'gnus-agent-mode) - (add-hook 'gnus-summary-mode-hook 'gnus-agent-mode) - (add-hook 'gnus-server-mode-hook 'gnus-agent-mode)) + (add-hook 'gnus-group-mode-hook #'gnus-agent-mode) + (add-hook 'gnus-summary-mode-hook #'gnus-agent-mode) + (add-hook 'gnus-server-mode-hook #'gnus-agent-mode)) (defun gnus-agent-create-buffer () (if (gnus-buffer-live-p gnus-agent-overview-buffer) @@ -701,7 +701,7 @@ be a select method." (message-narrow-to-headers) (let* ((gcc (mail-fetch-field "gcc" nil t)) (methods (and gcc - (mapcar 'gnus-inews-group-method + (mapcar #'gnus-inews-group-method (message-unquote-tokens (message-tokenize-header gcc " ,"))))) @@ -1057,7 +1057,8 @@ article's mark is toggled." (let* ((alist (gnus-agent-load-alist gnus-newsgroup-name)) (headers (sort (mapcar (lambda (h) (mail-header-number h)) - gnus-newsgroup-headers) '<)) + gnus-newsgroup-headers) + #'<)) (cached (and gnus-use-cache gnus-newsgroup-cached)) (undownloaded (list nil)) (tail-undownloaded undownloaded) @@ -1128,7 +1129,7 @@ downloadable." (when gnus-newsgroup-processable (setq gnus-newsgroup-downloadable (let* ((dl gnus-newsgroup-downloadable) - (processable (sort (copy-tree gnus-newsgroup-processable) '<)) + (processable (sort (copy-tree gnus-newsgroup-processable) #'<)) (gnus-newsgroup-downloadable processable)) (gnus-agent-summary-fetch-group) @@ -1820,7 +1821,7 @@ article numbers will be returned." (dolist (arts (gnus-info-marks (gnus-get-info group))) (unless (memq (car arts) '(seen recent killed cache)) (setq articles (gnus-range-add articles (cdr arts))))) - (setq articles (sort (gnus-uncompress-sequence articles) '<))) + (setq articles (sort (gnus-uncompress-sequence articles) #'<))) ;; At this point, I have the list of articles to consider for ;; fetching. This is the list that I'll return to my caller. Some @@ -2066,7 +2067,7 @@ doesn't exist, to valid the overview buffer." alist (cdr alist)) (while sequence (push (cons (pop sequence) state) uncomp))) - (setq alist (sort uncomp 'car-less-than-car))) + (setq alist (sort uncomp #'car-less-than-car))) (setq changed-version (not (= 2 gnus-agent-article-alist-save-format))))) (when changed-version (let ((gnus-agent-article-alist alist)) @@ -2408,13 +2409,13 @@ modified) original contents, they are first saved to their own file." (setq marked-articles (nconc (gnus-uncompress-range arts) marked-articles)) )))) - (setq marked-articles (sort marked-articles '<)) + (setq marked-articles (sort marked-articles #'<)) ;; Fetch any new articles from the server (setq articles (gnus-agent-fetch-headers group)) ;; Merge new articles with marked - (setq articles (sort (append marked-articles articles) '<)) + (setq articles (sort (append marked-articles articles) #'<)) (when articles ;; Parse them and see which articles we want to fetch. @@ -3127,7 +3128,7 @@ FORCE is equivalent to setting the expiration predicates to true." (gnus-uncompress-range (cons (caar alist) (caar (last alist)))) - (sort articles '<))))) + (sort articles #'<))))) (marked ;; More articles that are excluded from the ;; expiration process (cond (gnus-agent-expire-all @@ -3859,7 +3860,7 @@ If REREAD is not nil, downloaded articles are marked as unread." (string-to-number name))) (directory-files dir nil "\\`[0-9]+\\'" t))) - '>) + #'>) (progn (gnus-make-directory dir) nil))) nov-arts alist header @@ -4163,7 +4164,7 @@ modified." (path (gnus-agent-group-pathname group)) (entry (gethash path gnus-agent-total-fetched-hashtb))) (if entry - (apply '+ entry) + (apply #'+ entry) (let ((gnus-agent-inhibit-update-total-fetched-for (not no-inhibit))) (+ (gnus-agent-update-view-total-fetched-for group nil method path) diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index 6a66dc6542..ca24e6f251 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -1623,7 +1623,7 @@ It is a string, such as \"PGP\". If nil, ask user." :group 'gnus-article :type 'boolean) -(defcustom gnus-blocked-images 'gnus-block-private-groups +(defcustom gnus-blocked-images #'gnus-block-private-groups "Images that have URLs matching this regexp will be blocked. Note that the main reason external images are included in HTML emails (these days) is to allow tracking whether you've read the @@ -2987,7 +2987,7 @@ message header will be added to the bodies of the \"text/html\" parts." (when tmp-file (add-to-list 'gnus-article-browse-html-temp-list tmp-file)) (add-hook 'gnus-summary-prepare-exit-hook - 'gnus-article-browse-delete-temp-files) + #'gnus-article-browse-delete-temp-files) (add-hook 'gnus-exit-gnus-hook (lambda () (gnus-article-browse-delete-temp-files t))) diff --git a/lisp/gnus/gnus-bookmark.el b/lisp/gnus/gnus-bookmark.el index 57859d806c..d1af64d6d6 100644 --- a/lisp/gnus/gnus-bookmark.el +++ b/lisp/gnus/gnus-bookmark.el @@ -279,7 +279,7 @@ So the cdr of each bookmark is an alist too.") (gnus-bookmark-maybe-load-default-file) (let* ((bookmark (or bmk-name (gnus-completing-read "Jump to bookmarked article" - (mapcar 'car gnus-bookmark-alist)))) + (mapcar #'car gnus-bookmark-alist)))) (bmk-record (cadr (assoc bookmark gnus-bookmark-alist))) (group (cdr (assoc 'group bmk-record))) (message-id (cdr (assoc 'message-id bmk-record)))) diff --git a/lisp/gnus/gnus-cache.el b/lisp/gnus/gnus-cache.el index 36657e4621..bea3d3bf03 100644 --- a/lisp/gnus/gnus-cache.el +++ b/lisp/gnus/gnus-cache.el @@ -518,7 +518,7 @@ Returns the list of articles removed." (setq articles (sort (mapcar (lambda (name) (string-to-number name)) (directory-files dir nil "\\`[0-9]+\\'" t)) - '<)) + #'<)) ;; Update the cache active file, just to synch more. (if articles (progn @@ -714,7 +714,7 @@ If LOW, update the lower bound instead." (push (string-to-number (file-name-nondirectory (pop files))) nums) (push (pop files) alphs))) ;; If we have nums, then this is probably a valid group. - (when (setq nums (sort nums '<)) + (when (setq nums (sort nums #'<)) (puthash group (cons (car nums) (car (last nums))) gnus-cache-active-hashtb)) @@ -884,7 +884,7 @@ supported." (setq gnus-cache-total-fetched-hashtb (gnus-make-hashtable 1000))) (let* ((entry (gethash group gnus-cache-total-fetched-hashtb))) (if entry - (apply '+ entry) + (apply #'+ entry) (let ((gnus-cache-inhibit-update-total-fetched-for (not no-inhibit))) (+ (gnus-cache-update-overview-total-fetched-for group nil) diff --git a/lisp/gnus/gnus-cite.el b/lisp/gnus/gnus-cite.el index d02e898e23..a6d1101e01 100644 --- a/lisp/gnus/gnus-cite.el +++ b/lisp/gnus/gnus-cite.el @@ -445,7 +445,7 @@ Lines matching `gnus-cite-attribution-suffix' and perhaps (gnus-article-search-signature) (push (cons (point-marker) "") marks) ;; Sort the marks. - (setq marks (sort marks 'car-less-than-car)) + (setq marks (sort marks #'car-less-than-car)) (let ((omarks marks)) (setq marks nil) (while (cdr omarks) @@ -999,7 +999,7 @@ See also the documentation for `gnus-article-highlight-citation'." cites (cdr cites) candidate (car cite) numbers (cdr cite) - first (apply 'min numbers) + first (apply #'min numbers) compare (if size (length candidate) first)) (and (> first limit) regexp @@ -1125,7 +1125,7 @@ See also the documentation for `gnus-article-highlight-citation'." "Search for a cited line and set match data accordingly. Returns nil if there is no such line before LIMIT, t otherwise." (when (re-search-forward gnus-message-cite-prefix-regexp limit t) - (let ((cdepth (min (length (apply 'concat + (let ((cdepth (min (length (apply #'concat (split-string (match-string-no-properties 0) "[\t [:alnum:]]+"))) diff --git a/lisp/gnus/gnus-cus.el b/lisp/gnus/gnus-cus.el index dc14943a06..a36ef0cbec 100644 --- a/lisp/gnus/gnus-cus.el +++ b/lisp/gnus/gnus-cus.el @@ -417,7 +417,7 @@ category.")) (setq tmp (cdr tmp)))) (setq gnus-custom-params - (apply 'widget-create 'group + (apply #'widget-create 'group :value values (delq nil (list `(set :inline t diff --git a/lisp/gnus/gnus-delay.el b/lisp/gnus/gnus-delay.el index 477ad88a9c..74147f2092 100644 --- a/lisp/gnus/gnus-delay.el +++ b/lisp/gnus/gnus-delay.el @@ -179,7 +179,7 @@ This tells Gnus to look for delayed messages after getting new news. The optional arg NO-KEYMAP is ignored. Checking delayed messages is skipped if optional arg NO-CHECK is non-nil." (unless no-check - (add-hook 'gnus-get-new-news-hook 'gnus-delay-send-queue))) + (add-hook 'gnus-get-new-news-hook #'gnus-delay-send-queue))) (provide 'gnus-delay) diff --git a/lisp/gnus/gnus-diary.el b/lisp/gnus/gnus-diary.el index 78f1e53ff7..561a15b809 100644 --- a/lisp/gnus/gnus-diary.el +++ b/lisp/gnus/gnus-diary.el @@ -276,13 +276,13 @@ Optional prefix (or REVERSE argument) means sort in reverse order." (gnus-diary-update-group-parameters group))) (add-hook 'nndiary-request-create-group-functions - 'gnus-diary-update-group-parameters) + #'gnus-diary-update-group-parameters) ;; Now that we have `gnus-subscribe-newsgroup-functions', this is not needed ;; anymore. Maybe I should remove this completely. (add-hook 'nndiary-request-update-info-functions - 'gnus-diary-update-group-parameters) + #'gnus-diary-update-group-parameters) (add-hook 'gnus-subscribe-newsgroup-functions - 'gnus-diary-maybe-update-group-parameters) + #'gnus-diary-maybe-update-group-parameters) ;; Diary Message Checking =================================================== @@ -360,7 +360,7 @@ If ARG (or prefix) is non-nil, force prompting for all fields." header ": "))) (setq value (if (listp (nth 1 head)) - (gnus-completing-read prompt (cons "*" (mapcar 'car (nth 1 head))) + (gnus-completing-read prompt (cons "*" (mapcar #'car (nth 1 head))) t value 'gnus-diary-header-value-history) (read-string prompt value diff --git a/lisp/gnus/gnus-dired.el b/lisp/gnus/gnus-dired.el index 6f231c4fbb..e78163afe2 100644 --- a/lisp/gnus/gnus-dired.el +++ b/lisp/gnus/gnus-dired.el @@ -29,7 +29,7 @@ ;; following in your ~/.gnus: ;; (require 'gnus-dired) ;, isn't needed due to autoload cookies -;; (add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode) +;; (add-hook 'dired-mode-hook #'turn-on-gnus-dired-mode) ;; Note that if you visit dired buffers before your ~/.gnus file has ;; been read, those dired buffers won't have the keybindings in diff --git a/lisp/gnus/gnus-draft.el b/lisp/gnus/gnus-draft.el index 5f7ed38629..3b380f30c6 100644 --- a/lisp/gnus/gnus-draft.el +++ b/lisp/gnus/gnus-draft.el @@ -65,7 +65,7 @@ ;; Set up the menu. (when (gnus-visual-p 'draft-menu 'menu) (gnus-draft-make-menu-bar)) - (add-hook 'gnus-summary-prepare-exit-hook 'gnus-draft-clear-marks t t)))) + (add-hook 'gnus-summary-prepare-exit-hook #'gnus-draft-clear-marks t t)))) ;;; Commands diff --git a/lisp/gnus/gnus-fun.el b/lisp/gnus/gnus-fun.el index 615f4a55bc..8ce6990804 100644 --- a/lisp/gnus/gnus-fun.el +++ b/lisp/gnus/gnus-fun.el @@ -268,9 +268,9 @@ colors of the displayed X-Faces." 'xface (gnus-put-image (if (gnus-image-type-available-p 'xface) - (apply 'gnus-create-image (concat "X-Face: " data) 'xface t + (apply #'gnus-create-image (concat "X-Face: " data) 'xface t (cdr (assq 'xface gnus-face-properties-alist))) - (apply 'gnus-create-image pbm 'pbm t + (apply #'gnus-create-image pbm 'pbm t (cdr (assq 'pbm gnus-face-properties-alist)))) nil 'xface)) (gnus-add-wash-type 'xface)))))) @@ -325,7 +325,7 @@ colors of the displayed X-Faces." (dotimes (i 255) (push (format format i i i i i i) values)) - (mapconcat 'identity values " "))) + (mapconcat #'identity values " "))) (defun gnus-funcall-no-warning (function &rest args) (when (fboundp function) diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index ff792c5706..a165752881 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el @@ -1361,7 +1361,7 @@ if it is a string, only list groups matching REGEXP." (and (>= level gnus-level-zombie) (<= lowest gnus-level-zombie))) (gnus-group-prepare-flat-list-dead - (setq gnus-zombie-list (sort gnus-zombie-list 'string<)) + (setq gnus-zombie-list (sort gnus-zombie-list #'string<)) gnus-level-zombie ?Z regexp)) (when not-in-list @@ -1372,7 +1372,7 @@ if it is a string, only list groups matching REGEXP." (gnus-group-prepare-flat-list-dead (cl-union not-in-list - (setq gnus-killed-list (sort gnus-killed-list 'string<)) + (setq gnus-killed-list (sort gnus-killed-list #'string<)) :test 'equal) gnus-level-killed ?K regexp)) @@ -1608,7 +1608,7 @@ Some value are bound so the form can use them." (cons 'unread (if (numberp (car entry)) (car entry) 0)) (cons 'total (if active (1+ (- (cdr active) (car active))) 0)) (cons 'mailp (apply - 'append + #'append (mapcar (lambda (x) (memq x (assoc @@ -1883,7 +1883,7 @@ If FIRST-TOO, the current line is also eligible as a target." "Unmark all groups." (interactive) (save-excursion - (mapc 'gnus-group-remove-mark gnus-group-marked)) + (mapc #'gnus-group-remove-mark gnus-group-marked)) (gnus-group-position-point)) (defun gnus-group-mark-region (unmark beg end) @@ -2985,7 +2985,7 @@ and NEW-NAME will be prompted for." "Create one of the groups described in `gnus-useful-groups'." (interactive (let ((entry (assoc (gnus-completing-read "Create group" - (mapcar 'car gnus-useful-groups) + (mapcar #'car gnus-useful-groups) t) gnus-useful-groups))) (list (cadr entry) @@ -3118,7 +3118,7 @@ If there is, use Gnus to create an nnrss group" (read-from-minibuffer "Title: " (gnus-newsgroup-savable-name (mapconcat - 'identity + #'identity (split-string (or (cdr (assoc 'title feedinfo)) @@ -3126,7 +3126,7 @@ If there is, use Gnus to create an nnrss group" " "))))) (desc (read-from-minibuffer "Description: " (mapconcat - 'identity + #'identity (split-string (or (cdr (assoc 'description feedinfo)) @@ -4268,7 +4268,7 @@ If DONT-SCAN is non-nil, scan non-activated groups as well." (pop-to-buffer "*Gnus Help*") (buffer-disable-undo) (erase-buffer) - (setq groups (sort groups 'string<)) + (setq groups (sort groups #'string<)) (while groups ;; Groups may be entered twice into the list of groups. (when (not (string= (car groups) prev)) @@ -4494,7 +4494,7 @@ and the second element is the address." (interactive (list (let ((how (gnus-completing-read "Which back end" - (mapcar 'car (append gnus-valid-select-methods + (mapcar #'car (append gnus-valid-select-methods gnus-server-alist)) t (cons "nntp" 0) 'gnus-method-history))) ;; We either got a back end name or a virtual server name. @@ -4616,7 +4616,9 @@ and the second element is the address." (setcdr m (gnus-compress-sequence articles t))) (setcdr m (gnus-compress-sequence (sort (nconc (gnus-uncompress-range (cdr m)) - (copy-sequence articles)) '<) t)))))) + (copy-sequence articles)) + #'<) + t)))))) (declare-function gnus-summary-add-mark "gnus-sum" (article type)) @@ -4684,7 +4686,7 @@ This command may read the active file." ;; Cache active file might use "." ;; instead of ":". (gethash - (mapconcat 'identity + (mapconcat #'identity (split-string group ":") ".") gnus-cache-active-hashtb)))) @@ -4808,7 +4810,7 @@ you the groups that have both dormant articles and cached articles." (push n gnus-newsgroup-unselected)) (setq n (1+ n))) (setq gnus-newsgroup-unselected - (sort gnus-newsgroup-unselected '<))))) + (sort gnus-newsgroup-unselected #'<))))) (gnus-activate-group group) (gnus-group-make-articles-read group (list article)) (when (and (gnus-group-auto-expirable-p group) diff --git a/lisp/gnus/gnus-html.el b/lisp/gnus/gnus-html.el index bb1ee5a806..855d085c3a 100644 --- a/lisp/gnus/gnus-html.el +++ b/lisp/gnus/gnus-html.el @@ -329,10 +329,10 @@ Use ALT-TEXT for the image string." (replace-match "" t t)) (mm-url-decode-entities))) -(defun gnus-html-insert-image (&rest args) +(defun gnus-html-insert-image (&rest _args) "Fetch and insert the image under point." (interactive) - (apply 'gnus-html-display-image (get-text-property (point) 'gnus-image))) + (apply #'gnus-html-display-image (get-text-property (point) 'gnus-image))) (defun gnus-html-show-alt-text () "Show the ALT text of the image under point." diff --git a/lisp/gnus/gnus-int.el b/lisp/gnus/gnus-int.el index 9c68773e19..8bad44687b 100644 --- a/lisp/gnus/gnus-int.el +++ b/lisp/gnus/gnus-int.el @@ -628,7 +628,7 @@ the group's summary. article-number) ;; Clean up the new summary and propagate the error (error (when group-is-new (gnus-summary-exit)) - (apply 'signal err))))) + (apply #'signal err))))) (defun gnus-simplify-group-name (group) "Return the simplest representation of the name of GROUP. diff --git a/lisp/gnus/gnus-kill.el b/lisp/gnus/gnus-kill.el index 7e592026cd..20ea983105 100644 --- a/lisp/gnus/gnus-kill.el +++ b/lisp/gnus/gnus-kill.el @@ -641,7 +641,7 @@ Usage: emacs -batch -l ~/.emacs -l gnus -f gnus-batch-score" (let* ((gnus-newsrc-options-n (gnus-newsrc-parse-options (concat "options -n " - (mapconcat 'identity command-line-args-left " ")))) + (mapconcat #'identity command-line-args-left " ")))) (gnus-expert-user t) (mail-sources nil) (gnus-use-dribble-file nil) diff --git a/lisp/gnus/gnus-mlspl.el b/lisp/gnus/gnus-mlspl.el index ed8d15a2fe..77816d22eb 100644 --- a/lisp/gnus/gnus-mlspl.el +++ b/lisp/gnus/gnus-mlspl.el @@ -196,13 +196,13 @@ Calling (gnus-group-split-fancy nil nil \"mail.others\") returns: (concat "\\(" (mapconcat - 'identity + #'identity (append (and to-address (list (regexp-quote to-address))) (and to-list (list (regexp-quote to-list))) (and extra-aliases (if (listp extra-aliases) - (mapcar 'regexp-quote extra-aliases) + (mapcar #'regexp-quote extra-aliases) (list extra-aliases))) (and split-regexp (list split-regexp))) "\\|") diff --git a/lisp/gnus/gnus-msg.el b/lisp/gnus/gnus-msg.el index 836cc959c5..278b1d9d73 100644 --- a/lisp/gnus/gnus-msg.el +++ b/lisp/gnus/gnus-msg.el @@ -566,13 +566,18 @@ instead." (symbol-value (car elem)))) (throw 'found (cons (cadr elem) (caddr elem))))))))) +(declare-function gnus-agent-possibly-do-gcc "gnus-agent" ()) +(declare-function gnus-cache-possibly-remove-article "gnus-cache" + (article ticked dormant unread &optional force)) + (defun gnus-inews-add-send-actions (winconf buffer article &optional config yanked winconf-name) - (add-hook 'message-sent-hook (if gnus-agent 'gnus-agent-possibly-do-gcc - 'gnus-inews-do-gcc) nil t) + (add-hook 'message-sent-hook (if gnus-agent #'gnus-agent-possibly-do-gcc + #'gnus-inews-do-gcc) + nil t) (when gnus-agent - (add-hook 'message-header-hook 'gnus-agent-possibly-save-gcc nil t)) + (add-hook 'message-header-hook #'gnus-agent-possibly-save-gcc nil t)) (setq message-post-method `(lambda (&optional arg) (gnus-post-method arg ,gnus-newsgroup-name))) @@ -1038,8 +1043,8 @@ If SILENT, don't prompt the user." gnus-post-method (list gnus-post-method))) gnus-secondary-select-methods - (mapcar 'cdr gnus-server-alist) - (mapcar 'car gnus-opened-servers) + (mapcar #'cdr gnus-server-alist) + (mapcar #'car gnus-opened-servers) (list gnus-select-method) (list group-method))) method-alist post-methods method) @@ -1067,7 +1072,7 @@ If SILENT, don't prompt the user." ;; Just use the last value. gnus-last-posting-server (gnus-completing-read - "Posting method" (mapcar 'car method-alist) t + "Posting method" (mapcar #'car method-alist) t (cons (or gnus-last-posting-server "") 0)))) method-alist)))) ;; Override normal method. @@ -1341,13 +1346,13 @@ For the \"inline\" alternatives, also see the variable self)) "\n")) ((null self) - (insert "Gcc: " (mapconcat 'identity gcc ", ") "\n")) + (insert "Gcc: " (mapconcat #'identity gcc ", ") "\n")) ((eq self 'no-gcc-self) (when (setq gcc (delete gnus-newsgroup-name (delete (concat "\"" gnus-newsgroup-name "\"") gcc))) - (insert "Gcc: " (mapconcat 'identity gcc ", ") "\n"))))))) + (insert "Gcc: " (mapconcat #'identity gcc ", ") "\n"))))))) (defun gnus-summary-resend-message (address n &optional no-select) "Resend the current article to ADDRESS. @@ -1387,7 +1392,7 @@ the message before resending." (setq user-mail-address tem)))) ;; `gnus-summary-resend-message-insert-gcc' must run last. (add-hook 'message-header-setup-hook - 'gnus-summary-resend-message-insert-gcc t) + #'gnus-summary-resend-message-insert-gcc t) (add-hook 'message-sent-hook `(lambda () (let ((rfc2047-encode-encoded-words nil)) @@ -1916,7 +1921,7 @@ this is a reply." (add-hook 'message-setup-hook (cond ((eq 'eval (car result)) - 'ignore) + #'ignore) ((eq 'body (car result)) `(lambda () (save-excursion @@ -1926,7 +1931,7 @@ this is a reply." (setq-local message-signature nil) (setq-local message-signature-file nil) (if (not (cdr result)) - 'ignore + #'ignore `(lambda () (save-excursion (let ((message-signature ,(cdr result))) diff --git a/lisp/gnus/gnus-notifications.el b/lisp/gnus/gnus-notifications.el index e772dd8e62..39ef51b2b8 100644 --- a/lisp/gnus/gnus-notifications.el +++ b/lisp/gnus/gnus-notifications.el @@ -24,7 +24,7 @@ ;; This implements notifications using `notifications-notify' on new ;; messages received. -;; Use (add-hook 'gnus-after-getting-new-news-hook 'gnus-notifications) +;; Use (add-hook 'gnus-after-getting-new-news-hook #'gnus-notifications) ;; to get notifications just after getting the new news. ;;; Code: diff --git a/lisp/gnus/gnus-picon.el b/lisp/gnus/gnus-picon.el index 92def9a72d..a33316a526 100644 --- a/lisp/gnus/gnus-picon.el +++ b/lisp/gnus/gnus-picon.el @@ -120,7 +120,7 @@ List of pairs (KEY . GLYPH) where KEY is either a filename or an URL.") base (expand-file-name directory database)) (while address (when (setq result (gnus-picon-find-image - (concat base "/" (mapconcat 'downcase + (concat base "/" (mapconcat #'downcase (reverse address) "/") "/" (downcase user) "/"))) @@ -158,7 +158,7 @@ replacement is added." (defun gnus-picon-create-glyph (file) (or (cdr (assoc file gnus-picon-glyph-alist)) - (cdar (push (cons file (apply 'gnus-create-image + (cdar (push (cons file (apply #'gnus-create-image file nil nil gnus-picon-properties)) gnus-picon-glyph-alist)))) @@ -190,7 +190,7 @@ replacement is added." (gnus-picon-find-face (concat "unknown@" (mapconcat - 'identity (cdr spec) ".")) + #'identity (cdr spec) ".")) gnus-picon-user-directories))) (setcar spec (cons (gnus-picon-create-glyph file) (car spec)))) @@ -201,7 +201,7 @@ replacement is added." (when (setq file (gnus-picon-find-face (concat "unknown@" (mapconcat - 'identity (nthcdr (1+ i) spec) ".")) + #'identity (nthcdr (1+ i) spec) ".")) gnus-picon-domain-directories t)) (setcar (nthcdr (1+ i) spec) (cons (gnus-picon-create-glyph file) @@ -214,10 +214,11 @@ replacement is added." (cl-case gnus-picon-style (right (when (= (length addresses) 1) - (setq len (apply '+ (mapcar (lambda (x) - (condition-case nil - (car (image-size (car x))) - (error 0))) spec))) + (setq len (apply #'+ (mapcar (lambda (x) + (condition-case nil + (car (image-size (car x))) + (error 0))) + spec))) (when (> len 0) (goto-char (point-at-eol)) (insert (propertize @@ -256,7 +257,7 @@ replacement is added." (when (setq file (gnus-picon-find-face (concat "unknown@" (mapconcat - 'identity (nthcdr i spec) ".")) + #'identity (nthcdr i spec) ".")) gnus-picon-news-directories t)) (setcar (nthcdr i spec) (cons (gnus-picon-create-glyph file) diff --git a/lisp/gnus/gnus-registry.el b/lisp/gnus/gnus-registry.el index 068066e38c..7fdf668313 100644 --- a/lisp/gnus/gnus-registry.el +++ b/lisp/gnus/gnus-registry.el @@ -891,7 +891,7 @@ Addresses without a name will say \"noname\"." (defun gnus-registry-sort-addresses (&rest addresses) "Return a normalized and sorted list of ADDRESSES." - (sort (mapcan #'gnus-registry-extract-addresses addresses) 'string-lessp)) + (sort (mapcan #'gnus-registry-extract-addresses addresses) #'string-lessp)) (defun gnus-registry-simplify-subject (subject) (if (stringp subject) diff --git a/lisp/gnus/gnus-rfc1843.el b/lisp/gnus/gnus-rfc1843.el index 107e96350b..dca55af460 100644 --- a/lisp/gnus/gnus-rfc1843.el +++ b/lisp/gnus/gnus-rfc1843.el @@ -56,11 +56,11 @@ (defun rfc1843-gnus-setup () "Setup HZ decoding for Gnus." - (add-hook 'gnus-article-decode-hook 'rfc1843-decode-article-body t) + (add-hook 'gnus-article-decode-hook #'rfc1843-decode-article-body t) (setq gnus-decode-encoded-word-function - 'gnus-multi-decode-encoded-word-string + #'gnus-multi-decode-encoded-word-string gnus-decode-header-function - 'gnus-multi-decode-header + #'gnus-multi-decode-header gnus-decode-encoded-word-methods (nconc gnus-decode-encoded-word-methods (list diff --git a/lisp/gnus/gnus-salt.el b/lisp/gnus/gnus-salt.el index abaa844f58..d07d36e544 100644 --- a/lisp/gnus/gnus-salt.el +++ b/lisp/gnus/gnus-salt.el @@ -103,7 +103,7 @@ It accepts the same format specs that `gnus-summary-line-format' does." ((not (derived-mode-p 'gnus-summary-mode)) (setq gnus-pick-mode nil)) ((not gnus-pick-mode) ;; FIXME: a buffer-local minor mode removing globally from a hook?? - (remove-hook 'gnus-message-setup-hook 'gnus-pick-setup-message)) + (remove-hook 'gnus-message-setup-hook #'gnus-pick-setup-message)) (t ;; Make sure that we don't select any articles upon group entry. (setq-local gnus-auto-select-first nil) @@ -113,7 +113,7 @@ It accepts the same format specs that `gnus-summary-line-format' does." (gnus-update-format-specifications nil 'summary) (gnus-update-summary-mark-positions) ;; FIXME: a buffer-local minor mode adding globally to a hook?? - (add-hook 'gnus-message-setup-hook 'gnus-pick-setup-message) + (add-hook 'gnus-message-setup-hook #'gnus-pick-setup-message) (setq-local gnus-summary-goto-unread 'never) ;; Set up the menu. (when (gnus-visual-p 'pick-menu 'menu) diff --git a/lisp/gnus/gnus-score.el b/lisp/gnus/gnus-score.el index e74c498087..c6e08cee73 100644 --- a/lisp/gnus/gnus-score.el +++ b/lisp/gnus/gnus-score.el @@ -683,7 +683,7 @@ current score file." (and gnus-extra-headers (equal (nth 1 entry) "extra") (intern ; need symbol - (let ((collection (mapcar 'symbol-name gnus-extra-headers))) + (let ((collection (mapcar #'symbol-name gnus-extra-headers))) (gnus-completing-read "Score extra header" ; prompt collection ; completion list @@ -932,7 +932,7 @@ SCORE is the score to add. EXTRA is the possible non-standard header." (interactive (list (gnus-completing-read "Header" (mapcar - 'car + #'car (seq-filter (lambda (x) (fboundp (nth 2 x))) gnus-header-index)) @@ -1258,8 +1258,8 @@ If FORMAT, also format the current score file." ;; We do not respect eval and files atoms from global score ;; files. (when (and files (not global)) - (setq lists (apply 'append lists - (mapcar 'gnus-score-load-file + (setq lists (apply #'append lists + (mapcar #'gnus-score-load-file (if adapt-file (cons adapt-file files) files))))) (when (and eval (not global)) @@ -1268,7 +1268,7 @@ If FORMAT, also format the current score file." (setq gnus-scores-exclude-files (nconc (apply - 'nconc + #'nconc (mapcar (lambda (sfile) (list @@ -1554,10 +1554,10 @@ If FORMAT, also format the current score file." (setq entry (pop entries) header (nth 0 entry) gnus-score-index (nth 1 (assoc header gnus-header-index))) - (when (< 0 (apply 'max (mapcar - (lambda (score) - (length (gnus-score-get header score))) - scores))) + (when (< 0 (apply #'max (mapcar + (lambda (score) + (length (gnus-score-get header score))) + scores))) (when (if (and gnus-inhibit-slow-scoring (or (eq gnus-inhibit-slow-scoring t) (and (stringp gnus-inhibit-slow-scoring) @@ -1574,9 +1574,9 @@ If FORMAT, also format the current score file." ;; Run score-fn (if (eq header 'score-fn) (setq new (gnus-score-func scores trace)) - ;; Call the scoring function for this type of "header". - (setq new (funcall (nth 2 entry) scores header - now expire trace)))) + ;; Call the scoring function for this type of "header". + (setq new (funcall (nth 2 entry) scores header + now expire trace)))) (push new news)))) (when (gnus-buffer-live-p gnus-summary-buffer) @@ -1948,7 +1948,7 @@ score in `gnus-newsgroup-scored' by SCORE." gnus-newsgroup-name gnus-adaptive-file-suffix)))) (setq gnus-scores-articles (sort gnus-scores-articles - 'gnus-score-string<) + #'gnus-score-string<) articles gnus-scores-articles) (erase-buffer) @@ -2077,7 +2077,7 @@ score in `gnus-newsgroup-scored' by SCORE." ;; We cannot string-sort the extra headers list. *sigh* (if (= gnus-score-index 9) gnus-scores-articles - (sort gnus-scores-articles 'gnus-score-string<)) + (sort gnus-scores-articles #'gnus-score-string<)) articles gnus-scores-articles) (erase-buffer) @@ -2550,11 +2550,11 @@ score in `gnus-newsgroup-scored' by SCORE." (abbreviate-file-name file)))) (insert (format "\nTotal score: %d" - (apply '+ (mapcar - (lambda (s) - (or (caddr s) - gnus-score-interactive-default-score)) - trace)))) + (apply #'+ (mapcar + (lambda (s) + (or (caddr s) + gnus-score-interactive-default-score)) + trace)))) (insert "\n\nQuick help: @@ -2872,7 +2872,7 @@ This includes the score file for the group and all its parents." (mapcar (lambda (group) (gnus-score-file-name group gnus-adaptive-file-suffix)) (setq all (nreverse all))) - (mapcar 'gnus-score-file-name all))) + (mapcar #'gnus-score-file-name all))) (if (equal prefix "") all (mapcar @@ -2912,7 +2912,7 @@ Destroys the current buffer." (lambda (file) (cons (inline (gnus-score-file-rank file)) file)) files))) - (mapcar 'cdr (sort alist 'car-less-than-car))))) + (mapcar #'cdr (sort alist #'car-less-than-car))))) (defun gnus-score-find-alist (group) "Return list of score files for GROUP. diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el index 44780609af..636a0d7637 100644 --- a/lisp/gnus/gnus-search.el +++ b/lisp/gnus/gnus-search.el @@ -1859,7 +1859,7 @@ Assume \"size\" key is equal to \"larger\"." "No directory found in definition of server %s" server)))) (apply - 'vconcat + #'vconcat (mapcar (lambda (x) (let ((group x) artlist) @@ -1894,7 +1894,7 @@ Assume \"size\" key is equal to \"larger\"." "Cannot locate directory for group"))) (save-excursion (apply - 'call-process "find" nil t + #'call-process "find" nil t "find" group "-maxdepth" "1" "-type" "f" "-name" "[0-9]*" "-exec" (slot-value engine 'grep-program) @@ -1907,7 +1907,8 @@ Assume \"size\" key is equal to \"larger\"." (let* ((path (split-string (buffer-substring (point) - (line-end-position)) "/" t)) + (line-end-position)) + "/" t)) (art (string-to-number (car (last path))))) (while (string= "." (car path)) (setq path (cdr path))) diff --git a/lisp/gnus/gnus-sieve.el b/lisp/gnus/gnus-sieve.el index 3b79d57864..7046f5949c 100644 --- a/lisp/gnus/gnus-sieve.el +++ b/lisp/gnus/gnus-sieve.el @@ -140,7 +140,7 @@ For example: \(gnus-sieve-string-list \\='(\"to\" \"cc\")) => \"[\\\"to\\\", \\\"cc\\\"]\" " - (concat "[\"" (mapconcat 'identity list "\", \"") "\"]")) + (concat "[\"" (mapconcat #'identity list "\", \"") "\"]")) (defun gnus-sieve-test-list (list) "Convert an elisp test list to a Sieve test list. @@ -148,7 +148,7 @@ For example: For example: \(gnus-sieve-test-list \\='((address \"sender\" \"boss@company.com\") (size :over 4K))) => \"(address \\\"sender\\\" \\\"boss@company.com\\\", size :over 4K)\"" - (concat "(" (mapconcat 'gnus-sieve-test list ", ") ")")) + (concat "(" (mapconcat #'gnus-sieve-test list ", ") ")")) ;; FIXME: do proper quoting (defun gnus-sieve-test-token (token) @@ -189,7 +189,7 @@ For example: (size :over 100K)))) => \"anyof (header :contains [\\\"to\\\", \\\"cc\\\"] \\\"my@address.com\\\", size :over 100K)\"" - (mapconcat 'gnus-sieve-test-token test " ")) + (mapconcat #'gnus-sieve-test-token test " ")) (defun gnus-sieve-script (&optional method crosspost) "Generate a Sieve script based on groups with select method METHOD @@ -228,7 +228,7 @@ This is returned as a string." "\tstop;\n") "}") script))))) - (mapconcat 'identity script "\n"))) + (mapconcat #'identity script "\n"))) (provide 'gnus-sieve) diff --git a/lisp/gnus/gnus-srvr.el b/lisp/gnus/gnus-srvr.el index 34e5ceb3f6..deeb28885b 100644 --- a/lisp/gnus/gnus-srvr.el +++ b/lisp/gnus/gnus-srvr.el @@ -581,7 +581,7 @@ The following commands are available: (defun gnus-server-add-server (how where) (interactive (list (intern (gnus-completing-read "Server method" - (mapcar 'car gnus-valid-select-methods) + (mapcar #'car gnus-valid-select-methods) t)) (read-string "Server name: "))) (when (assq where gnus-server-alist) @@ -592,7 +592,8 @@ The following commands are available: (defun gnus-server-goto-server (server) "Jump to a server line." (interactive - (list (gnus-completing-read "Goto server" (mapcar 'car gnus-server-alist) t))) + (list (gnus-completing-read "Goto server" + (mapcar #'car gnus-server-alist) t))) (let ((to (text-property-any (point-min) (point-max) 'gnus-server (intern server)))) (when to diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el index cf37a1ccdf..cd43876413 100644 --- a/lisp/gnus/gnus-start.el +++ b/lisp/gnus/gnus-start.el @@ -259,7 +259,7 @@ not match this regexp will be removed before saving the list." regexp)) (defcustom gnus-ignored-newsgroups - (mapconcat 'identity + (mapconcat #'identity '("^to\\." ; not "real" groups "^[0-9. \t]+\\( \\|$\\)" ; all digits in name "^[\"][\"#'()]" ; bogus characters @@ -518,7 +518,7 @@ Can be used to turn version control on or off." ;; For subscribing new newsgroup (defun gnus-subscribe-hierarchical-interactive (groups) - (let ((groups (sort groups 'string<)) + (let ((groups (sort groups #'string<)) prefixes prefix start ans group starts) (while groups (setq prefixes (list "^")) @@ -3162,7 +3162,7 @@ SPECIFIC-VARIABLES, or those in `gnus-variable-list'." "Declare back end NAME with ABILITIES as a Gnus back end." (setq gnus-valid-select-methods (nconc gnus-valid-select-methods - (list (apply 'list name abilities)))) + (list (apply #'list name abilities)))) (gnus-redefine-select-method-widget)) (defun gnus-set-default-directory () diff --git a/lisp/gnus/gnus-topic.el b/lisp/gnus/gnus-topic.el index 8a77c532d2..402de05210 100644 --- a/lisp/gnus/gnus-topic.el +++ b/lisp/gnus/gnus-topic.el @@ -335,7 +335,7 @@ If RECURSIVE is t, return groups in its subtopics too." (setq topology gnus-topic-topology gnus-tmp-topics nil)) (push (caar topology) gnus-tmp-topics) - (mapc 'gnus-topic-list (cdr topology)) + (mapc #'gnus-topic-list (cdr topology)) gnus-tmp-topics) ;;; Topic parameter jazz @@ -386,7 +386,7 @@ inheritance." ;; We probably have lots of nil elements here, so we remove them. ;; Probably faster than doing this "properly". (delq nil (cons group-params-list - (mapcar 'gnus-topic-parameters + (mapcar #'gnus-topic-parameters (gnus-current-topics topic))))) param out params) ;; Now we have all the parameters, so we go through them @@ -445,7 +445,7 @@ If LOWEST is non-nil, list all newsgroups of level LOWEST or higher." (and (>= level gnus-level-zombie) (<= lowest gnus-level-zombie))) (gnus-group-prepare-flat-list-dead - (setq gnus-zombie-list (sort gnus-zombie-list 'string<)) + (setq gnus-zombie-list (sort gnus-zombie-list #'string<)) gnus-level-zombie ?Z regexp)) @@ -453,7 +453,7 @@ If LOWEST is non-nil, list all newsgroups of level LOWEST or higher." (and (>= level gnus-level-killed) (<= lowest gnus-level-killed))) (gnus-group-prepare-flat-list-dead - (setq gnus-killed-list (sort gnus-killed-list 'string<)) + (setq gnus-killed-list (sort gnus-killed-list #'string<)) gnus-level-killed ?K regexp) (when not-in-list (unless gnus-killed-hashtb @@ -841,7 +841,7 @@ articles in the topic and its subtopics." (pop topics))) ;; Go through all living groups and make sure that ;; they belong to some topic. - (let* ((tgroups (apply 'append (mapcar 'cdr gnus-topic-alist))) + (let* ((tgroups (apply #'append (mapcar #'cdr gnus-topic-alist))) (entry (last (assoc (caar gnus-topic-topology) gnus-topic-alist))) (groups (cdr gnus-group-list))) (dolist (group groups) @@ -1128,21 +1128,21 @@ articles in the topic and its subtopics." (when (gnus-visual-p 'topic-menu 'menu) (gnus-topic-make-menu-bar)) (gnus-set-format 'topic t) - (add-hook 'gnus-group-catchup-group-hook 'gnus-topic-update-topic) + (add-hook 'gnus-group-catchup-group-hook #'gnus-topic-update-topic) (setq-local gnus-group-prepare-function - 'gnus-group-prepare-topics) + #'gnus-group-prepare-topics) (setq-local gnus-group-get-parameter-function - 'gnus-group-topic-parameters) + #'gnus-group-topic-parameters) (setq-local gnus-group-goto-next-group-function - 'gnus-topic-goto-next-group) + #'gnus-topic-goto-next-group) (setq-local gnus-group-indentation-function - 'gnus-topic-group-indentation) + #'gnus-topic-group-indentation) (setq-local gnus-group-update-group-function - 'gnus-topic-update-topics-containing-group) - (setq-local gnus-group-sort-alist-function 'gnus-group-sort-topic) - (setq gnus-group-change-level-function 'gnus-topic-change-level) - (setq gnus-goto-missing-group-function 'gnus-topic-goto-missing-group) - (add-hook 'gnus-check-bogus-groups-hook 'gnus-topic-clean-alist + #'gnus-topic-update-topics-containing-group) + (setq-local gnus-group-sort-alist-function #'gnus-group-sort-topic) + (setq gnus-group-change-level-function #'gnus-topic-change-level) + (setq gnus-goto-missing-group-function #'gnus-topic-goto-missing-group) + (add-hook 'gnus-check-bogus-groups-hook #'gnus-topic-clean-alist nil 'local) (setq gnus-topology-checked-p nil) ;; We check the topology. @@ -1150,11 +1150,11 @@ articles in the topic and its subtopics." (gnus-topic-check-topology))) ;; Remove topic infestation. (unless gnus-topic-mode - (remove-hook 'gnus-summary-exit-hook 'gnus-topic-update-topic) + (remove-hook 'gnus-summary-exit-hook #'gnus-topic-update-topic) (setq gnus-group-change-level-function nil) - (remove-hook 'gnus-check-bogus-groups-hook 'gnus-topic-clean-alist) - (setq gnus-group-prepare-function 'gnus-group-prepare-flat) - (setq gnus-group-sort-alist-function 'gnus-group-sort-flat)) + (remove-hook 'gnus-check-bogus-groups-hook #'gnus-topic-clean-alist) + (setq gnus-group-prepare-function #'gnus-group-prepare-flat) + (setq gnus-group-sort-alist-function #'gnus-group-sort-flat)) (when (called-interactively-p 'any) (gnus-group-list-groups)))) @@ -1213,7 +1213,7 @@ Also see `gnus-group-catchup'." (inhibit-read-only t) (gnus-group-marked groups)) (gnus-group-catchup-current) - (mapcar 'gnus-topic-update-topics-containing-group groups))))) + (mapcar #'gnus-topic-update-topics-containing-group groups))))) (defun gnus-topic-read-group (&optional all no-article group) "Read news in this newsgroup. @@ -1280,7 +1280,7 @@ When used interactively, PARENT will be the topic under point." If COPYP, copy the groups instead." (interactive (list current-prefix-arg - (gnus-completing-read "Move to topic" (mapcar 'car gnus-topic-alist) t + (gnus-completing-read "Move to topic" (mapcar #'car gnus-topic-alist) t nil 'gnus-topic-history))) (let ((use-marked (and (not n) (not (and transient-mark-mode mark-active)) gnus-group-marked t)) @@ -1328,7 +1328,7 @@ If COPYP, copy the groups instead." (interactive (list current-prefix-arg (gnus-completing-read - "Copy to topic" (mapcar 'car gnus-topic-alist) t))) + "Copy to topic" (mapcar #'car gnus-topic-alist) t))) (gnus-topic-move-group n topic t)) (defun gnus-topic-kill-group (&optional n discard) @@ -1422,7 +1422,7 @@ If PERMANENT, make it stay shown in subsequent sessions as well." (let ((topic (gnus-topic-find-topology (gnus-completing-read "Show topic" - (mapcar 'car gnus-topic-alist) t)))) + (mapcar #'car gnus-topic-alist) t)))) (setcar (cddr (cadr topic)) nil) (setcar (cdr (cadr topic)) 'visible) (gnus-group-list-groups))))) @@ -1471,7 +1471,7 @@ If NON-RECURSIVE (which is the prefix) is t, don't unmark its subtopics." (nreverse (list (setq topic (gnus-completing-read "Move to topic" - (mapcar 'car gnus-topic-alist) t)) + (mapcar #'car gnus-topic-alist) t)) (read-string (format "Move to %s (regexp): " topic)))))) (gnus-group-mark-regexp regexp) (gnus-topic-move-group nil topic copyp)) @@ -1704,7 +1704,7 @@ If REVERSE, sort in reverse order." If REVERSE, reverse the sorting order." (interactive (list (gnus-completing-read "Sort topics in" - (mapcar 'car gnus-topic-alist) t + (mapcar #'car gnus-topic-alist) t (gnus-current-topic)) current-prefix-arg)) (let ((topic-topology (or (and topic (cdr (gnus-topic-find-topology topic))) @@ -1719,7 +1719,7 @@ If REVERSE, reverse the sorting order." (interactive (list (gnus-group-topic-name) - (gnus-completing-read "Move to topic" (mapcar 'car gnus-topic-alist) t))) + (gnus-completing-read "Move to topic" (mapcar #'car gnus-topic-alist) t))) (unless (and current to) (error "Can't find topic")) (let ((current-top (cdr (gnus-topic-find-topology current))) diff --git a/lisp/gnus/gnus-undo.el b/lisp/gnus/gnus-undo.el index 5e72effa6c..5d2f85af36 100644 --- a/lisp/gnus/gnus-undo.el +++ b/lisp/gnus/gnus-undo.el @@ -103,7 +103,7 @@ ;; Set up the menu. (when (gnus-visual-p 'undo-menu 'menu) (gnus-undo-make-menu-bar)) - (add-hook 'post-command-hook 'gnus-undo-boundary nil t))) + (add-hook 'post-command-hook #'gnus-undo-boundary nil t))) ;;; Interface functions. @@ -161,15 +161,15 @@ A numeric argument serves as a repeat count." (unless gnus-undo-mode (error "Undoing is not enabled in this buffer")) (message "%s" last-command) - (when (or (not (eq last-command 'gnus-undo)) - (not gnus-undo-last)) + (unless (and (eq last-command 'gnus-undo) + gnus-undo-last) (setq gnus-undo-last gnus-undo-actions)) (let ((action (pop gnus-undo-last))) (unless action (error "Nothing further to undo")) (setq gnus-undo-actions (delq action gnus-undo-actions)) (setq gnus-undo-boundary t) - (mapc 'funcall action))) + (mapc #'funcall action))) (provide 'gnus-undo) diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el index 82c8731b47..b8451028d1 100644 --- a/lisp/gnus/gnus-util.el +++ b/lisp/gnus/gnus-util.el @@ -445,7 +445,7 @@ displayed in the echo area." `(let (str time) (cond ((eq gnus-add-timestamp-to-message 'log) (setq str (let (message-log-max) - (apply 'message ,format-string ,args))) + (apply #'message ,format-string ,args))) (when (and message-log-max (> message-log-max 0) (/= (length str) 0)) @@ -471,7 +471,7 @@ displayed in the echo area." (message "%s" (concat ,timestamp str)) str)) (t - (apply 'message ,format-string ,args))))))) + (apply #'message ,format-string ,args))))))) (defvar gnus-action-message-log nil) @@ -491,8 +491,8 @@ inside loops." (if (<= level gnus-verbose) (let ((message (if gnus-add-timestamp-to-message - (apply 'gnus-message-with-timestamp args) - (apply 'message args)))) + (apply #'gnus-message-with-timestamp args) + (apply #'message args)))) (when (and (consp gnus-action-message-log) (<= level 3)) (push message gnus-action-message-log)) @@ -513,7 +513,7 @@ inside loops." "Beep an error if LEVEL is equal to or less than `gnus-verbose'. ARGS are passed to `message'." (when (<= (floor level) gnus-verbose) - (apply 'message args) + (apply #'message args) (ding) (let (duration) (when (and (floatp level) @@ -1053,16 +1053,16 @@ ARG is passed to the first function." (defun gnus-run-hooks (&rest funcs) "Does the same as `run-hooks', but saves the current buffer." (save-current-buffer - (apply 'run-hooks funcs))) + (apply #'run-hooks funcs))) (defun gnus-run-hook-with-args (hook &rest args) "Does the same as `run-hook-with-args', but saves the current buffer." (save-current-buffer - (apply 'run-hook-with-args hook args))) + (apply #'run-hook-with-args hook args))) (defun gnus-run-mode-hooks (&rest funcs) "Run `run-mode-hooks', saving the current buffer." - (save-current-buffer (apply 'run-mode-hooks funcs))) + (save-current-buffer (apply #'run-mode-hooks funcs))) ;;; Various @@ -1355,7 +1355,7 @@ SPEC is a predicate specifier that contains stuff like `or', `and', `(,spec elem)) ((listp spec) (if (memq (car spec) '(or and not)) - `(,(car spec) ,@(mapcar 'gnus-make-predicate-1 (cdr spec))) + `(,(car spec) ,@(mapcar #'gnus-make-predicate-1 (cdr spec))) (error "Invalid predicate specifier: %s" spec))))) (defun gnus-completing-read (prompt collection &optional require-match @@ -1684,7 +1684,7 @@ lists of strings." (setq props (plist-put props :foreground (face-foreground face))) (setq props (plist-put props :background (face-background face)))) (ignore-errors - (apply 'create-image file type data-p props)))) + (apply #'create-image file type data-p props)))) (defun gnus-put-image (glyph &optional string category) (let ((point (point))) diff --git a/lisp/gnus/gnus-uu.el b/lisp/gnus/gnus-uu.el index db0ffc6d0d..2bc1f864de 100644 --- a/lisp/gnus/gnus-uu.el +++ b/lisp/gnus/gnus-uu.el @@ -356,7 +356,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (defun gnus-uu-decode-uu (&optional n) "Uudecodes the current article." (interactive "P") - (gnus-uu-decode-with-method 'gnus-uu-uustrip-article n)) + (gnus-uu-decode-with-method #'gnus-uu-uustrip-article n)) (defun gnus-uu-decode-uu-and-save (n dir) "Decodes and saves the resulting file." @@ -366,12 +366,12 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (read-directory-name "Uudecode and save in dir: " gnus-uu-default-dir gnus-uu-default-dir t)))) - (gnus-uu-decode-with-method 'gnus-uu-uustrip-article n dir nil nil t)) + (gnus-uu-decode-with-method #'gnus-uu-uustrip-article n dir nil nil t)) (defun gnus-uu-decode-unshar (&optional n) "Unshars the current article." (interactive "P") - (gnus-uu-decode-with-method 'gnus-uu-unshar-article n nil nil 'scan t)) + (gnus-uu-decode-with-method #'gnus-uu-unshar-article n nil nil 'scan t)) (defun gnus-uu-decode-unshar-and-save (n dir) "Unshars and saves the current article." @@ -381,7 +381,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (read-directory-name "Unshar and save in dir: " gnus-uu-default-dir gnus-uu-default-dir t)))) - (gnus-uu-decode-with-method 'gnus-uu-unshar-article n dir nil 'scan t)) + (gnus-uu-decode-with-method #'gnus-uu-unshar-article n dir nil 'scan t)) (defun gnus-uu-decode-save (n file) "Saves the current article." @@ -393,7 +393,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (read-file-name "Save article in file: " gnus-uu-default-dir gnus-uu-default-dir)))) (setq gnus-uu-saved-article-name file) - (gnus-uu-decode-with-method 'gnus-uu-save-article n nil t)) + (gnus-uu-decode-with-method #'gnus-uu-save-article n nil t)) (defun gnus-uu-decode-binhex (n dir) "Unbinhexes the current article." @@ -406,7 +406,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (gnus-uu-initialize) (setq gnus-uu-binhex-article-name (make-temp-file (expand-file-name "binhex" gnus-uu-work-dir))) - (gnus-uu-decode-with-method 'gnus-uu-binhex-article n dir)) + (gnus-uu-decode-with-method #'gnus-uu-binhex-article n dir)) (defun gnus-uu-decode-yenc (n dir) "Decode the yEnc-encoded current article." @@ -417,7 +417,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." gnus-uu-default-dir gnus-uu-default-dir)))) (setq gnus-uu-yenc-article-name nil) - (gnus-uu-decode-with-method 'gnus-uu-yenc-article n dir nil t)) + (gnus-uu-decode-with-method #'gnus-uu-yenc-article n dir nil t)) (defun gnus-uu-decode-uu-view (&optional n) "Uudecodes and views the current article." @@ -729,7 +729,7 @@ When called interactively, prompt for REGEXP." (defun gnus-uu-decode-postscript (&optional n) "Gets PostScript of the current article." (interactive "P") - (gnus-uu-decode-with-method 'gnus-uu-decode-postscript-article n)) + (gnus-uu-decode-with-method #'gnus-uu-decode-postscript-article n)) (defun gnus-uu-decode-postscript-view (&optional n) "Gets and views the current article." @@ -745,7 +745,7 @@ When called interactively, prompt for REGEXP." (read-directory-name "Save in dir: " gnus-uu-default-dir gnus-uu-default-dir t)))) - (gnus-uu-decode-with-method 'gnus-uu-decode-postscript-article + (gnus-uu-decode-with-method #'gnus-uu-decode-postscript-article n dir nil nil t)) (defun gnus-uu-decode-postscript-and-save-view (n dir) @@ -1196,11 +1196,11 @@ When called interactively, prompt for REGEXP." ;; Expand numbers, sort, and return the list of article ;; numbers. - (mapcar 'cdr + (mapcar #'cdr (sort (gnus-uu-expand-numbers list-of-subjects (not do-not-translate)) - 'gnus-uu-string<)))))) + #'gnus-uu-string<)))))) (defun gnus-uu-expand-numbers (string-list &optional translate) ;; Takes a list of strings and "expands" all numbers in all the @@ -1830,8 +1830,8 @@ Gnus might fail to display all of it.") ;; Initializing -(add-hook 'gnus-summary-prepare-exit-hook 'gnus-uu-clean-up) -(add-hook 'gnus-summary-prepare-exit-hook 'gnus-uu-delete-work-dir) +(add-hook 'gnus-summary-prepare-exit-hook #'gnus-uu-clean-up) +(add-hook 'gnus-summary-prepare-exit-hook #'gnus-uu-delete-work-dir) diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index 3b172db211..1eff9a8223 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el @@ -3501,7 +3501,7 @@ You should probably use `gnus-find-method-for-group' instead." (while (setq info (pop alist)) (when (gnus-server-equal (gnus-info-method info) server) (push (gnus-info-group info) groups))) - (sort groups 'string<))) + (sort groups #'string<))) (defun gnus-group-foreign-p (group) "Say whether a group is foreign or not." diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el index 91671016a8..c954f65793 100644 --- a/lisp/gnus/mail-source.el +++ b/lisp/gnus/mail-source.el @@ -462,21 +462,23 @@ the `mail-source-keyword-map' variable." (cond ((and (eq keyword :user) - (setq user-auth (plist-get - ;; cache the search result in `found' - (or found - (setq found (nth 0 (apply 'auth-source-search - search)))) - :user))) + (setq user-auth + (plist-get + ;; cache the search result in `found' + (or found + (setq found (nth 0 (apply #'auth-source-search + search)))) + :user))) user-auth) ((and (eq keyword :password) - (setq pass-auth (plist-get - ;; cache the search result in `found' - (or found - (setq found (nth 0 (apply 'auth-source-search - search)))) - :secret))) + (setq pass-auth + (plist-get + ;; cache the search result in `found' + (or found + (setq found (nth 0 (apply #'auth-source-search + search)))) + :secret))) ;; maybe set the password to the return of the :secret function (if (functionp pass-auth) (setq pass-auth (funcall pass-auth)) @@ -685,7 +687,7 @@ Deleting old (> %s day(s)) incoming mail file `%s'." diff bfile) ;; find "our" movemail in exec-directory. ;; Bug#31737 (apply - 'call-process + #'call-process (append (list mail-source-movemail-program @@ -1002,11 +1004,11 @@ This only works when `display-time' is enabled." #'mail-source-start-idle-timer)) ;; When you get new mail, clear "Mail" from the mode line. (add-hook 'nnmail-post-get-new-mail-hook - 'display-time-event-handler) + #'display-time-event-handler) (message "Mail check enabled")) (setq display-time-mail-function nil) (remove-hook 'nnmail-post-get-new-mail-hook - 'display-time-event-handler) + #'display-time-event-handler) (message "Mail check disabled")))) (defun mail-source-fetch-maildir (source callback) diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 1409a4384a..3f671193a2 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -2195,10 +2195,11 @@ see `message-narrow-to-headers-or-head'." (require 'gnus-sum) ; for gnus-list-identifiers (let ((regexp (if (stringp gnus-list-identifiers) gnus-list-identifiers - (mapconcat 'identity gnus-list-identifiers " *\\|")))) + (mapconcat #'identity gnus-list-identifiers " *\\|")))) (if (and (not (equal regexp "")) (string-match (concat "\\(\\(\\(Re: +\\)?\\(" regexp - " *\\)\\)+\\(Re: +\\)?\\)") subject)) + " *\\)\\)+\\(Re: +\\)?\\)") + subject)) (concat (substring subject 0 (match-beginning 1)) (or (match-string 3 subject) (match-string 5 subject)) @@ -3173,7 +3174,7 @@ Like `text-mode', but with these additional commands: (defun message-setup-fill-variables () "Setup message fill variables." - (setq-local fill-paragraph-function 'message-fill-paragraph) + (setq-local fill-paragraph-function #'message-fill-paragraph) (make-local-variable 'adaptive-fill-first-line-regexp) (let ((quote-prefix-regexp ;; User should change message-cite-prefix-regexp if @@ -3197,7 +3198,7 @@ Like `text-mode', but with these additional commands: (concat quote-prefix-regexp "\\|" adaptive-fill-first-line-regexp))) (setq-local auto-fill-inhibit-regexp nil) - (setq-local normal-auto-fill-function 'message-do-auto-fill)) + (setq-local normal-auto-fill-function #'message-do-auto-fill)) @@ -4064,7 +4065,7 @@ This function uses `mail-citation-hook' if that is non-nil." ;; Insert a blank line if it is peeled off. (insert "\n")))) (goto-char start) - (mapc 'funcall functions) + (mapc #'funcall functions) (when message-citation-line-function (unless (bolp) (insert "\n")) @@ -4555,7 +4556,7 @@ An address might be bogus if there's a matching entry in (and message-bogus-addresses (let ((re (if (listp message-bogus-addresses) - (mapconcat 'identity + (mapconcat #'identity message-bogus-addresses "\\|") message-bogus-addresses))) @@ -4950,7 +4951,7 @@ that instead." (let* ((default-directory "/") (coding-system-for-write message-send-coding-system) (cpr (apply - 'call-process-region + #'call-process-region (append (list (point-min) (point-max) sendmail-program nil errbuf nil "-oi") @@ -5002,7 +5003,7 @@ to find out how to use this." (pcase (let ((coding-system-for-write message-send-coding-system)) (apply - 'call-process-region (point-min) (point-max) + #'call-process-region (point-min) (point-max) message-qmail-inject-program nil nil nil ;; qmail-inject's default behavior is to look for addresses on the ;; command line; if there're none, it scans the headers. @@ -5394,7 +5395,7 @@ Otherwise, generate and save a value for `canlock-password' first." "Really use %s possibly unknown group%s: %s? " (if (= (length errors) 1) "this" "these") (if (= (length errors) 1) "" "s") - (mapconcat 'identity errors ", ")))) + (mapconcat #'identity errors ", ")))) ;; There were no errors. ((not errors) t) @@ -6061,7 +6062,7 @@ subscribed address (and not the additional To and Cc header contents)." (cc (message-fetch-field "cc")) (msg-recipients (concat to (and to cc ", ") cc)) (recipients - (mapcar 'mail-strip-quoted-names + (mapcar #'mail-strip-quoted-names (message-tokenize-header msg-recipients))) (file-regexps (if message-subscribed-address-file @@ -6078,11 +6079,11 @@ subscribed address (and not the additional To and Cc header contents)." (if re (setq re (concat re "\\|" item)) (setq re (concat "\\`\\(" item)))) (and re (list (concat re "\\)\\'")))))))) - (mft-regexps (apply 'append message-subscribed-regexps - (mapcar 'regexp-quote + (mft-regexps (apply #'append message-subscribed-regexps + (mapcar #'regexp-quote message-subscribed-addresses) file-regexps - (mapcar 'funcall + (mapcar #'funcall message-subscribed-address-functions)))) (save-match-data (let ((list @@ -6103,7 +6104,7 @@ subscribed address (and not the additional To and Cc header contents)." (dolist (rhs (delete-dups (mapcar (lambda (rhs) (or (cadr (split-string rhs "@")) "")) - (mapcar 'downcase + (mapcar #'downcase (mapcar (lambda (elem) (or (cadr elem) @@ -6569,7 +6570,7 @@ moved to the beginning " (if to (concat " to " (or (car (mail-extract-address-components to)) - to) "") + to)) "") (if (and group (not (string= group ""))) (concat " on " group) "") "*"))) @@ -6583,7 +6584,7 @@ moved to the beginning " (if to (concat " to " (or (car (mail-extract-address-components to)) - to) "") + to)) "") (if (and group (not (string= group ""))) (concat " on " group) "") "*"))) @@ -6612,7 +6613,7 @@ moved to the beginning " (cons (string-to-number (or (match-string 1 b) "1")) b))) (buffer-list))) - 'car-less-than-car))) + #'car-less-than-car))) new))))) (defun message-pop-to-buffer (name &optional switch-function) @@ -6968,8 +6969,8 @@ The function is called with one parameter, a cons cell ..." (message-fetch-field "original-to"))) cc (message-fetch-field "cc") extra (when message-extra-wide-headers - (mapconcat 'identity - (mapcar 'message-fetch-field + (mapconcat #'identity + (mapcar #'message-fetch-field message-extra-wide-headers) ", ")) mct (message-fetch-field "mail-copies-to") @@ -7053,7 +7054,7 @@ want to get rid of this query permanently."))) (setq recipients (cond ((functionp message-dont-reply-to-names) (mapconcat - 'identity + #'identity (delq nil (mapcar (lambda (mail) (unless (funcall message-dont-reply-to-names @@ -7087,7 +7088,7 @@ want to get rid of this query permanently."))) ;; Remove hierarchical lists that are contained within each other, ;; if message-hierarchical-addresses is defined. (when message-hierarchical-addresses - (let ((plain-addrs (mapcar 'car recipients)) + (let ((plain-addrs (mapcar #'car recipients)) subaddrs recip) (while plain-addrs (setq subaddrs (assoc (car plain-addrs) @@ -8366,7 +8367,7 @@ The following arguments may contain lists of values." (with-output-to-temp-buffer " *MESSAGE information message*" (with-current-buffer " *MESSAGE information message*" (fundamental-mode) - (mapc 'princ text) + (mapc #'princ text) (goto-char (point-min)))) (funcall ask question)) (funcall ask question))) diff --git a/lisp/gnus/mm-archive.el b/lisp/gnus/mm-archive.el index 635e7f4ee8..6173d86327 100644 --- a/lisp/gnus/mm-archive.el +++ b/lisp/gnus/mm-archive.el @@ -54,10 +54,10 @@ (write-region (point-min) (point-max) file nil 'silent) (setq decoder (copy-sequence decoder)) (setcar (member "%f" decoder) file) - (apply 'call-process (car decoder) nil nil nil + (apply #'call-process (car decoder) nil nil nil (append (cdr decoder) (list dir))) (delete-file file)) - (apply 'call-process-region (point-min) (point-max) (car decoder) + (apply #'call-process-region (point-min) (point-max) (car decoder) nil (gnus-get-buffer-create "*tnef*") nil (append (cdr decoder) (list dir))))) `("multipart/mixed" diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el index a62e954af3..02cd6af0c9 100644 --- a/lisp/gnus/mm-decode.el +++ b/lisp/gnus/mm-decode.el @@ -40,8 +40,8 @@ (defvar gnus-current-window-configuration) -(add-hook 'gnus-exit-gnus-hook 'mm-destroy-postponed-undisplay-list) -(add-hook 'gnus-exit-gnus-hook 'mm-temp-files-delete) +(add-hook 'gnus-exit-gnus-hook #'mm-destroy-postponed-undisplay-list) +(add-hook 'gnus-exit-gnus-hook #'mm-temp-files-delete) (defgroup mime-display () "Display of MIME in mail and news articles." @@ -603,7 +603,7 @@ files left at the next time." (if fails ;; Schedule the deletion of the files left at the next time. (with-file-modes #o600 - (write-region (concat (mapconcat 'identity (nreverse fails) "\n") + (write-region (concat (mapconcat #'identity (nreverse fails) "\n") "\n") nil cache-file nil 'silent)) (when (file-exists-p cache-file) @@ -1081,7 +1081,8 @@ external if displayed external." (string= total "\"%s\"")) (setq uses-stdin nil) (push (shell-quote-argument - (gnus-map-function mm-path-name-rewrite-functions file)) out)) + (gnus-map-function mm-path-name-rewrite-functions file)) + out)) ((string= total "%t") (push (shell-quote-argument (car type-list)) out)) (t @@ -1092,7 +1093,7 @@ external if displayed external." (push (shell-quote-argument (gnus-map-function mm-path-name-rewrite-functions file)) out)) - (mapconcat 'identity (nreverse out) ""))) + (mapconcat #'identity (nreverse out) ""))) (defun mm-remove-parts (handles) "Remove the displayed MIME parts represented by HANDLES." diff --git a/lisp/gnus/mm-url.el b/lisp/gnus/mm-url.el index 412a474412..73106a2932 100644 --- a/lisp/gnus/mm-url.el +++ b/lisp/gnus/mm-url.el @@ -299,7 +299,7 @@ If `mm-url-use-external' is non-nil, use `mm-url-program'." args (append (cdr item) (list url)))) (setq program mm-url-program args (append mm-url-arguments (list url)))) - (unless (eq 0 (apply 'call-process program nil t nil args)) + (unless (eq 0 (apply #'call-process program nil t nil args)) (error "Couldn't fetch %s" url)))) (defvar mm-url-timeout 30 diff --git a/lisp/gnus/mm-util.el b/lisp/gnus/mm-util.el index db42bfa4b1..329b9e8884 100644 --- a/lisp/gnus/mm-util.el +++ b/lisp/gnus/mm-util.el @@ -380,7 +380,7 @@ like \"€\" to the euro sign, mainly in html messages." "Return the MIME charset corresponding to the given Mule CHARSET." (let ((css (sort (sort-coding-systems (find-coding-systems-for-charsets (list charset))) - 'mm-sort-coding-systems-predicate)) + #'mm-sort-coding-systems-predicate)) cs mime) (while (and (not mime) css) @@ -501,7 +501,7 @@ charset, and a longer list means no appropriate charset." (let ((systems (find-coding-systems-region b e))) (when mm-coding-system-priorities (setq systems - (sort systems 'mm-sort-coding-systems-predicate))) + (sort systems #'mm-sort-coding-systems-predicate))) (setq systems (delq 'compound-text systems)) (unless (equal systems '(undecided)) (while systems @@ -751,7 +751,7 @@ decompressed data. The buffer's multibyteness must be turned off." (insert-buffer-substring cur) (condition-case err (progn - (unless (memq (apply 'call-process-region + (unless (memq (apply #'call-process-region (point-min) (point-max) prog t (list t err-file) nil args) jka-compr-acceptable-retval-list) diff --git a/lisp/gnus/mm-view.el b/lisp/gnus/mm-view.el index 0683703a4e..266f471a3f 100644 --- a/lisp/gnus/mm-view.el +++ b/lisp/gnus/mm-view.el @@ -274,13 +274,13 @@ This is only used if `mm-inline-large-images' is set to (write-region (point-min) (point-max) file nil 'silent)) (delete-region (point-min) (point-max)) (unwind-protect - (apply 'call-process cmd nil t nil (mapcar 'eval args)) + (apply #'call-process cmd nil t nil (mapcar (lambda (e) (eval e t)) args)) (delete-file file)) (and post-func (funcall post-func)))) (defun mm-inline-wash-with-stdin (post-func cmd &rest args) (let ((coding-system-for-write 'binary)) - (apply 'call-process-region (point-min) (point-max) + (apply #'call-process-region (point-min) (point-max) cmd t t nil args)) (and post-func (funcall post-func))) @@ -290,7 +290,7 @@ This is only used if `mm-inline-large-images' is set to handle (mm-with-unibyte-buffer (insert source) - (apply 'mm-inline-wash-with-file post-func cmd args) + (apply #'mm-inline-wash-with-file post-func cmd args) (buffer-string))))) (defun mm-inline-render-with-stdin (handle post-func cmd &rest args) @@ -299,7 +299,7 @@ This is only used if `mm-inline-large-images' is set to handle (mm-with-unibyte-buffer (insert source) - (apply 'mm-inline-wash-with-stdin post-func cmd args) + (apply #'mm-inline-wash-with-stdin post-func cmd args) (buffer-string))))) (defun mm-inline-render-with-function (handle func &rest args) @@ -317,7 +317,7 @@ This is only used if `mm-inline-large-images' is set to (defun mm-inline-text-html (handle) (if (stringp (car handle)) - (mapcar 'mm-inline-text-html (cdr handle)) + (mapcar #'mm-inline-text-html (cdr handle)) (let* ((func mm-text-html-renderer) (entry (assq func mm-text-html-renderer-alist)) (inhibit-read-only t)) diff --git a/lisp/gnus/mml-sec.el b/lisp/gnus/mml-sec.el index c117a3866a..a050fe04e1 100644 --- a/lisp/gnus/mml-sec.el +++ b/lisp/gnus/mml-sec.el @@ -236,7 +236,7 @@ You can also customize or set `mml-signencrypt-style-alist' instead." (re-search-forward (concat "^" (regexp-quote mail-header-separator) "\n") nil t)) (goto-char (match-end 0)) - (apply 'mml-insert-tag 'part (cons (if sign 'sign 'encrypt) + (apply #'mml-insert-tag 'part (cons (if sign 'sign 'encrypt) (cons method tags)))) (t (error "The message is corrupted. No mail header separator")))))) @@ -346,8 +346,8 @@ either an error is raised or not." (concat "^" (regexp-quote mail-header-separator) "\n") nil t) (goto-char (setq insert-loc (match-end 0))) (unless (looking-at "<#secure") - (apply 'mml-insert-tag - 'secure 'method method 'mode mode tags))) + (apply #'mml-insert-tag + 'secure 'method method 'mode mode tags))) (t (error "The message is corrupted. No mail header separator")))) (when (eql insert-loc (point)) @@ -558,7 +558,7 @@ Return keys." (cl-assert keys) (let* ((usage-prefs (mml-secure-cust-usage-lookup context usage)) (curr-fprs (cdr (assoc name (cdr usage-prefs)))) - (key-fprs (mapcar 'mml-secure-fingerprint keys)) + (key-fprs (mapcar #'mml-secure-fingerprint keys)) (new-fprs (cl-union curr-fprs key-fprs :test 'equal))) (if curr-fprs (setcdr (assoc name (cdr usage-prefs)) new-fprs) @@ -795,7 +795,7 @@ When `mml-secure-fail-when-key-problem' is t, fail with an error in case of outdated or multiple keys." (let* ((nname (mml-secure-normalize-cust-name name)) (fprs (mml-secure-cust-fpr-lookup context usage nname)) - (usable-fprs (mapcar 'mml-secure-fingerprint keys))) + (usable-fprs (mapcar #'mml-secure-fingerprint keys))) (if fprs (if (gnus-subsetp fprs usable-fprs) (mml-secure-filter-keys keys fprs) diff --git a/lisp/gnus/mml-smime.el b/lisp/gnus/mml-smime.el index 5baeaffa53..e97e3e9a06 100644 --- a/lisp/gnus/mml-smime.el +++ b/lisp/gnus/mml-smime.el @@ -179,7 +179,7 @@ Whether the passphrase is cached at all is controlled by (and from (smime-get-key-by-email from))) (smime-get-key-by-email (gnus-completing-read "Sign this part with what signature" - (mapcar 'car smime-keys) nil nil nil + (mapcar #'car smime-keys) nil nil nil (and (listp (car-safe smime-keys)) (caar smime-keys)))))))) @@ -287,7 +287,7 @@ Whether the passphrase is cached at all is controlled by (point-min) (point)) addresses))) (delete-region (point-min) (point))) - (setq addresses (mapcar 'downcase addresses)))) + (setq addresses (mapcar #'downcase addresses)))) (if (not (member (downcase (or (mm-handle-multipart-from ctl) "")) addresses)) (mm-sec-error 'gnus-info "Sender address forged") @@ -299,7 +299,7 @@ Whether the passphrase is cached at all is controlled by (concat "Sender claimed to be: " (mm-handle-multipart-from ctl) "\n" (if addresses (concat "Addresses in certificate: " - (mapconcat 'identity addresses ", ")) + (mapconcat #'identity addresses ", ")) "No addresses found in certificate. (Requires OpenSSL 0.9.6 or later.)") "\n" "\n" "OpenSSL output:\n" diff --git a/lisp/gnus/mml.el b/lisp/gnus/mml.el index 424215de94..752dede8d0 100644 --- a/lisp/gnus/mml.el +++ b/lisp/gnus/mml.el @@ -206,8 +206,8 @@ part. This is for the internal use, you should never modify the value.") (defun mml-destroy-buffers () (let (kill-buffer-hook) - (mapc 'kill-buffer mml-buffer-list) - (setq mml-buffer-list nil))) + (mapc #'kill-buffer (prog1 mml-buffer-list + (setq mml-buffer-list nil))))) (defun mml-parse () "Parse the current buffer as an MML document." @@ -499,7 +499,7 @@ type detected." content-type) (setcdr (assq 'type (cdr (car cont))) content-type)) (when (fboundp 'libxml-parse-html-region) - (setq cont (mapcar 'mml-expand-all-html-into-multipart-related cont))) + (setq cont (mapcar #'mml-expand-all-html-into-multipart-related cont))) (prog1 (with-temp-buffer (set-buffer-multibyte nil) @@ -862,7 +862,7 @@ type detected." (cl-incf mml-multipart-number))) (throw 'not-unique nil)))) ((eq (car cont) 'multipart) - (mapc 'mml-compute-boundary-1 (cddr cont)))) + (mapc #'mml-compute-boundary-1 (cddr cont)))) t) (defun mml-make-boundary (number) @@ -1077,7 +1077,7 @@ If HANDLES is non-nil, use it instead reparsing the buffer." (goto-char (point-max)) (insert "<#/mml>\n")) ((stringp (car handle)) - (mapc 'mml-insert-mime (cdr handle)) + (mapc #'mml-insert-mime (cdr handle)) (insert "<#/multipart>\n")) (textp (let ((charset (mail-content-type-get diff --git a/lisp/gnus/nnagent.el b/lisp/gnus/nnagent.el index f2acea4fa6..1f21eee868 100644 --- a/lisp/gnus/nnagent.el +++ b/lisp/gnus/nnagent.el @@ -138,13 +138,13 @@ group action server))) nil) -(deffoo nnagent-retrieve-headers (articles &optional group server fetch-old) +(deffoo nnagent-retrieve-headers (articles &optional group _server fetch-old) (let ((file (gnus-agent-article-name ".overview" group)) arts n first) (save-excursion (gnus-agent-load-alist group) (setq arts (gnus-sorted-difference - articles (mapcar 'car gnus-agent-article-alist))) + articles (mapcar #'car gnus-agent-article-alist))) ;; Assume that articles with smaller numbers than the first one ;; Agent knows are gone. (setq first (caar gnus-agent-article-alist)) diff --git a/lisp/gnus/nndiary.el b/lisp/gnus/nndiary.el index b3e83e494d..c1ac3cc5e8 100644 --- a/lisp/gnus/nndiary.el +++ b/lisp/gnus/nndiary.el @@ -532,8 +532,8 @@ all. This may very well take some time.") (nndiary-possibly-change-directory group server) (let ((articles (nnheader-directory-articles nndiary-current-directory))) (when articles - (setcar active (apply 'min articles)) - (setcdr active (apply 'max articles)))) + (setcar active (apply #'min articles)) + (setcdr active (apply #'max articles)))) (nnmail-save-active nndiary-group-alist nndiary-active-file) (run-hook-with-args 'nndiary-request-create-group-functions (gnus-group-prefixed-name group @@ -589,7 +589,7 @@ all. This may very well take some time.") (let ((active (nth 1 (assoc group nndiary-group-alist)))) (when active (setcar active (or (and active-articles - (apply 'min active-articles)) + (apply #'min active-articles)) (1+ (cdr active))))) (nnmail-save-active nndiary-group-alist nndiary-active-file)) (nndiary-save-nov) @@ -960,7 +960,7 @@ all. This may very well take some time.") (setq nndiary-article-file-alist (sort (nnheader-article-to-file-alist nndiary-current-directory) - 'car-less-than-car))) + #'car-less-than-car))) (setq active (if nndiary-article-file-alist (cons (caar nndiary-article-file-alist) @@ -1055,7 +1055,7 @@ all. This may very well take some time.") (nndiary-generate-nov-databases-1 dir seen)))) ;; Do this directory. (let ((nndiary-files (sort (nnheader-article-to-file-alist dir) - 'car-less-than-car))) + #'car-less-than-car))) (if (not nndiary-files) (let* ((group (nnheader-file-to-group (directory-file-name dir) nndiary-directory)) @@ -1245,7 +1245,7 @@ all. This may very well take some time.") (defun nndiary-unflatten (spec) ;; opposite of flatten: build ranges if possible - (setq spec (sort spec '<)) + (setq spec (sort spec #'<)) (let (min max res) (while (setq min (pop spec)) (setq max min) @@ -1300,7 +1300,7 @@ all. This may very well take some time.") (apply #'encode-time 0 0 0 1 1 (nthcdr 5 date-elts)) (* (car reminder) 400861056)))) res)) - (sort res 'time-less-p))) + (sort res #'time-less-p))) (defun nndiary-last-occurrence (sched) ;; Returns the last occurrence of schedule SCHED as an Emacs time struct, or @@ -1318,8 +1318,8 @@ all. This may very well take some time.") ;; bored in finding a good algorithm for doing that ;-) ;; ### FIXME: remove identical entries. (let ((dom-list (nth 2 sched)) - (month-list (sort (nndiary-flatten (nth 3 sched) 1 12) '>)) - (year-list (sort (nndiary-flatten (nth 4 sched) 1971) '>)) + (month-list (sort (nndiary-flatten (nth 3 sched) 1 12) #'>)) + (year-list (sort (nndiary-flatten (nth 4 sched) 1971) #'>)) (dow-list (nth 5 sched))) ;; Special case: an asterisk in one of the days specifications means ;; that only the other should be taken into account. If both are @@ -1370,7 +1370,7 @@ all. This may very well take some time.") (setq day (+ 7 day)))) ;; Finally, if we have some days, they are valid (when days - (sort days '>) + (sort days #'>) (throw 'found (encode-time 0 minute hour (car days) month year time-zone))) @@ -1396,12 +1396,12 @@ all. This may very well take some time.") (this-day (decoded-time-day today)) (this-month (decoded-time-month today)) (this-year (decoded-time-year today)) - (minute-list (sort (nndiary-flatten (nth 0 sched) 0 59) '<)) - (hour-list (sort (nndiary-flatten (nth 1 sched) 0 23) '<)) + (minute-list (sort (nndiary-flatten (nth 0 sched) 0 59) #'<)) + (hour-list (sort (nndiary-flatten (nth 1 sched) 0 23) #'<)) (dom-list (nth 2 sched)) - (month-list (sort (nndiary-flatten (nth 3 sched) 1 12) '<)) + (month-list (sort (nndiary-flatten (nth 3 sched) 1 12) #'<)) (years (if (nth 4 sched) - (sort (nndiary-flatten (nth 4 sched) 1971) '<) + (sort (nndiary-flatten (nth 4 sched) 1971) #'<) t)) (dow-list (nth 5 sched)) (year (1- this-year)) @@ -1474,7 +1474,7 @@ all. This may very well take some time.") ;; Aaaaaaall right. Now we have a valid list of DAYS for ;; this month and this year. (when days - (setq days (sort days '<)) + (setq days (sort days #'<)) ;; Remove past days for this year and this month. (and (= year this-year) (= month this-month) diff --git a/lisp/gnus/nndoc.el b/lisp/gnus/nndoc.el index a3a6645485..c68e201271 100644 --- a/lisp/gnus/nndoc.el +++ b/lisp/gnus/nndoc.el @@ -427,9 +427,9 @@ from the document.") (setq result nil)))) (unless (or result results) (error "Document is not of any recognized type")) - (if result - (car entry) - (cadar (last (sort results 'car-less-than-car)))))) + (car (if result + entry + (cdar (last (sort results #'car-less-than-car))))))) ;;; ;;; Built-in type predicates and functions diff --git a/lisp/gnus/nndraft.el b/lisp/gnus/nndraft.el index 1f87beda5f..9e70bb6214 100644 --- a/lisp/gnus/nndraft.el +++ b/lisp/gnus/nndraft.el @@ -204,8 +204,8 @@ are generated if and only if they are also in `message-draft-headers'." (setq buffer-file-name (expand-file-name file) buffer-auto-save-file-name (make-auto-save-file-name)) (clear-visited-file-modtime) - (add-hook 'write-contents-functions 'nndraft-generate-headers nil t) - (add-hook 'after-save-hook 'nndraft-update-unread-articles nil t) + (add-hook 'write-contents-functions #'nndraft-generate-headers nil t) + (add-hook 'after-save-hook #'nndraft-update-unread-articles nil t) (message-add-action '(nndraft-update-unread-articles) 'exit 'postpone 'kill) article)) @@ -316,7 +316,7 @@ are generated if and only if they are also in `message-draft-headers'." (nnheader-concat nndraft-directory group)))) (defun nndraft-article-filename (article &rest args) - (apply 'concat + (apply #'concat (file-name-as-directory nndraft-current-directory) (int-to-string article) args)) @@ -334,9 +334,9 @@ are generated if and only if they are also in `message-draft-headers'." "Return the list of messages in the group." (gnus-make-directory nndraft-current-directory) (sort - (mapcar 'string-to-number + (mapcar #'string-to-number (directory-files nndraft-current-directory nil "\\`[0-9]+\\'" t)) - '<)) + #'<)) (nnoo-import nndraft (nnmh diff --git a/lisp/gnus/nnfolder.el b/lisp/gnus/nnfolder.el index 9a0219c143..405ab2f92f 100644 --- a/lisp/gnus/nnfolder.el +++ b/lisp/gnus/nnfolder.el @@ -145,7 +145,7 @@ all. This may very well take some time.") 'nov (setq articles (gnus-sorted-intersection ;; Is ARTICLES sorted? - (sort articles '<) + (sort articles #'<) (nnfolder-existing-articles))) (while (setq article (pop articles)) (set-buffer nnfolder-current-buffer) diff --git a/lisp/gnus/nnheader.el b/lisp/gnus/nnheader.el index a381720f24..ae8506c5c2 100644 --- a/lisp/gnus/nnheader.el +++ b/lisp/gnus/nnheader.el @@ -468,7 +468,7 @@ leaving the original buffer untouched." (defun nnheader-write-overview-file (file headers) "Write HEADERS to FILE." (with-temp-file file - (mapcar 'nnheader-insert-nov headers))) + (mapcar #'nnheader-insert-nov headers))) (defun nnheader-insert-header (header) (insert @@ -723,15 +723,15 @@ an alarming frequency on NFS mounted file systems. If it is nil, (defun nnheader-directory-files-safe (&rest args) "Execute `directory-files' twice and returns the longer result." - (let ((first (apply 'directory-files args)) - (second (apply 'directory-files args))) + (let ((first (apply #'directory-files args)) + (second (apply #'directory-files args))) (if (> (length first) (length second)) first second))) (defun nnheader-directory-articles (dir) "Return a list of all article files in directory DIR." - (mapcar 'nnheader-file-to-number + (mapcar #'nnheader-file-to-number (if nnheader-directory-files-is-safe (directory-files dir nil nnheader-numerical-short-files t) @@ -783,7 +783,7 @@ The first string in ARGS can be a format string." (set (intern (format "%s-status-string" backend)) (if (< (length args) 2) (car args) - (apply 'format args))) + (apply #'format args))) nil) (defun nnheader-get-report-string (backend) @@ -804,8 +804,8 @@ without formatting." (with-current-buffer nntp-server-buffer (erase-buffer) (if (string-match "%" format) - (insert (apply 'format format args)) - (apply 'insert format args)) + (insert (apply #'format format args)) + (apply #'insert format args)) t)) (defsubst nnheader-replace-chars-in-string (string from to) @@ -841,12 +841,13 @@ without formatting." (defun nnheader-message (level &rest args) "Message if the Gnus backends are talkative." - (if (or (not (numberp gnus-verbose-backends)) - (<= level gnus-verbose-backends)) - (if gnus-add-timestamp-to-message - (apply 'gnus-message-with-timestamp args) - (apply 'message args)) - (apply 'format args))) + (apply (cond + ((and (numberp gnus-verbose-backends) + (> level gnus-verbose-backends)) + #'format) + (gnus-add-timestamp-to-message #'gnus-message-with-timestamp) + (t #'message)) + args)) (defun nnheader-be-verbose (level) "Return whether the backends should be verbose on LEVEL." @@ -877,7 +878,7 @@ without formatting." (defun nnheader-concat (dir &rest files) "Concat DIR as directory to FILES." - (apply 'concat (file-name-as-directory dir) files)) + (apply #'concat (file-name-as-directory dir) files)) (defun nnheader-ms-strip-cr () "Strip ^M from the end of all lines." @@ -915,7 +916,7 @@ first. Otherwise, find the newest one, though it may take a time." (setq path (cdr path)))) (if (or first (not (cdr results))) (car results) - (car (sort results 'file-newer-than-file-p))))) + (car (sort results #'file-newer-than-file-p))))) (defvar ange-ftp-path-format) (defvar efs-path-regexp) @@ -961,15 +962,15 @@ find-file-hook, etc. "Open a file with some variables bound. See `find-file-noselect' for the arguments." (cl-letf* ((format-alist nil) - (auto-mode-alist (mm-auto-mode-alist)) - ((default-value 'major-mode) 'fundamental-mode) - (enable-local-variables nil) - (after-insert-file-functions nil) - (enable-local-eval nil) - (coding-system-for-read nnheader-file-coding-system) - (version-control 'never) - (find-file-hook nil)) - (apply 'find-file-noselect args))) + (auto-mode-alist (mm-auto-mode-alist)) + ((default-value 'major-mode) 'fundamental-mode) + (enable-local-variables nil) + (after-insert-file-functions nil) + (enable-local-eval nil) + (coding-system-for-read nnheader-file-coding-system) + (version-control 'never) + (find-file-hook nil)) + (apply #'find-file-noselect args))) (defun nnheader-directory-regular-files (dir) "Return a list of all regular files in DIR." @@ -983,7 +984,7 @@ See `find-file-noselect' for the arguments." (defun nnheader-directory-files (&rest args) "Same as `directory-files', but prune \".\" and \"..\"." - (let ((files (apply 'directory-files args)) + (let ((files (apply #'directory-files args)) out) (while files (unless (member (file-name-nondirectory (car files)) '("." "..")) @@ -1065,7 +1066,7 @@ See `find-file-noselect' for the arguments." (let ((now (current-time))) (when (time-less-p 1 (time-subtract now nnheader-last-message-time)) (setq nnheader-last-message-time now) - (apply 'nnheader-message args)))) + (apply #'nnheader-message args)))) (make-obsolete-variable 'nnheader-load-hook "use `with-eval-after-load' instead." "28.1") diff --git a/lisp/gnus/nnmail.el b/lisp/gnus/nnmail.el index d043ae1b42..59d61379f1 100644 --- a/lisp/gnus/nnmail.el +++ b/lisp/gnus/nnmail.el @@ -1281,7 +1281,7 @@ Return the number of characters in the body." "Remove list identifiers from Subject headers." (let ((regexp (if (consp nnmail-list-identifiers) - (mapconcat 'identity nnmail-list-identifiers " *\\|") + (mapconcat #'identity nnmail-list-identifiers " *\\|") nnmail-list-identifiers))) (when regexp (goto-char (point-min)) @@ -1321,8 +1321,8 @@ Eudora has a broken References line, but an OK In-Reply-To." (when (re-search-forward "^\\(In-Reply-To:[^\n]+\\)\n[ \t]+" nil t) (replace-match "\\1" t)))) -(defalias 'nnmail-fix-eudora-headers 'nnmail-ignore-broken-references) -(make-obsolete 'nnmail-fix-eudora-headers 'nnmail-ignore-broken-references "Emacs 23.1") +(defalias 'nnmail-fix-eudora-headers #'nnmail-ignore-broken-references) +(make-obsolete 'nnmail-fix-eudora-headers #'nnmail-ignore-broken-references "Emacs 23.1") (custom-add-option 'nnmail-prepare-incoming-header-hook 'nnmail-ignore-broken-references) @@ -1528,7 +1528,7 @@ See the documentation for the variable `nnmail-split-fancy' for details." expanded)))) (setq pos (1+ pos))) (if did-expand - (apply 'concat (nreverse expanded)) + (apply #'concat (nreverse expanded)) newtext))) ;; Activate a backend only if it isn't already activated. @@ -1623,7 +1623,7 @@ See the documentation for the variable `nnmail-split-fancy' for details." (gnus-methods-equal-p gnus-command-method (nnmail-cache-primary-mail-backend))) (let ((regexp (if (consp nnmail-cache-ignore-groups) - (mapconcat 'identity nnmail-cache-ignore-groups + (mapconcat #'identity nnmail-cache-ignore-groups "\\|") nnmail-cache-ignore-groups))) (unless (and regexp (string-match regexp grp)) @@ -1766,7 +1766,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (defvar nnmail-fetched-sources nil) (defun nnmail-get-value (&rest args) - (let ((sym (intern (apply 'format args)))) + (let ((sym (intern (apply #'format args)))) (when (boundp sym) (symbol-value sym)))) diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el index 4179a2cc63..46691e3494 100644 --- a/lisp/gnus/nnmaildir.el +++ b/lisp/gnus/nnmaildir.el @@ -101,7 +101,7 @@ SUFFIX should start with \":2,\"." (new-flags (concat (gnus-delete-duplicates ;; maildir flags must be sorted - (sort (cons flag flags-as-list) '<))))) + (sort (cons flag flags-as-list) #'<))))) (concat ":2," new-flags))) (defun nnmaildir--remove-flag (flag suffix) @@ -292,7 +292,7 @@ This variable is set by `nnmaildir-request-article'.") (write-region "" nil file nil 'no-message)) (defun nnmaildir--delete-dir-files (dir ls) (when (file-attributes dir) - (mapc 'delete-file (funcall ls dir 'full "\\`[^.]" 'nosort)) + (mapc #'delete-file (funcall ls dir 'full "\\`[^.]" 'nosort)) (delete-directory dir))) (defun nnmaildir--group-maxnum (server group) @@ -855,8 +855,8 @@ This variable is set by `nnmaildir-request-article'.") file)) files) files (delq nil files) - files (mapcar 'nnmaildir--parse-filename files) - files (sort files 'nnmaildir--sort-files)) + files (mapcar #'nnmaildir--parse-filename files) + files (sort files #'nnmaildir--sort-files)) (dolist (file files) (setq file (if (consp file) file (aref file 3)) x (make-nnmaildir--art :prefix (car file) :suffix (cdr file))) @@ -998,7 +998,7 @@ This variable is set by `nnmaildir-request-article'.") always-marks (nnmaildir--param pgname 'always-marks) never-marks (nnmaildir--param pgname 'never-marks) existing (nnmaildir--grp-nlist group) - existing (mapcar 'car existing) + existing (mapcar #'car existing) existing (nreverse existing) existing (gnus-compress-sequence existing 'always-list) missing (list (cons 1 (nnmaildir--group-maxnum @@ -1013,8 +1013,8 @@ This variable is set by `nnmaildir-request-article'.") ;; get mark names from mark dirs and from flag ;; mappings (append - (mapcar 'cdr nnmaildir-flag-mark-mapping) - (mapcar 'intern (funcall ls dir nil "\\`[^.]" 'nosort)))) + (mapcar #'cdr nnmaildir-flag-mark-mapping) + (mapcar #'intern (funcall ls dir nil "\\`[^.]" 'nosort)))) new-mmth (make-hash-table :size (length all-marks)) old-mmth (nnmaildir--grp-mmth group)) (dolist (mark all-marks) @@ -1070,7 +1070,7 @@ This variable is set by `nnmaildir-request-article'.") (let ((article (nnmaildir--flist-art flist prefix))) (when article (push (nnmaildir--art-num article) article-list)))))) - (setq ranges (gnus-add-to-range ranges (sort article-list '<))))) + (setq ranges (gnus-add-to-range ranges (sort article-list #'<))))) (if (eq mark 'read) (setq read ranges) (if ranges (setq marks (cons (cons mark ranges) marks))))) (setf (gnus-info-read info) (gnus-range-add read missing)) @@ -1695,8 +1695,8 @@ This variable is set by `nnmaildir-request-article'.") ;; get mark names from mark dirs and from flag ;; mappings (append - (mapcar 'cdr nnmaildir-flag-mark-mapping) - (mapcar 'intern all-marks)))) + (mapcar #'cdr nnmaildir-flag-mark-mapping) + (mapcar #'intern all-marks)))) (dolist (action actions) (setq ranges (car action) todo-marks (caddr action)) diff --git a/lisp/gnus/nnmairix.el b/lisp/gnus/nnmairix.el index c061031b40..54d6c5276e 100644 --- a/lisp/gnus/nnmairix.el +++ b/lisp/gnus/nnmairix.el @@ -193,8 +193,8 @@ (define-key gnus-summary-mode-map (kbd "G G u") 'nnmairix-remove-tick-mark-original-article)) -(add-hook 'gnus-group-mode-hook 'nnmairix-group-mode-hook) -(add-hook 'gnus-summary-mode-hook 'nnmairix-summary-mode-hook) +(add-hook 'gnus-group-mode-hook #'nnmairix-group-mode-hook) +(add-hook 'gnus-summary-mode-hook #'nnmairix-summary-mode-hook) ;; ;;;###autoload ;; (defun nnmairix-initialize (&optional force) @@ -202,8 +202,8 @@ ;; (if (not (or (file-readable-p "~/.mairixrc") ;; force)) ;; (message "No file `~/.mairixrc', skipping nnmairix setup") -;; (add-hook 'gnus-group-mode-hook 'nnmairix-group-mode-hook) -;; (add-hook 'gnus-summary-mode-hook 'nnmairix-summary-mode-hook))) +;; (add-hook 'gnus-group-mode-hook #'nnmairix-group-mode-hook) +;; (add-hook 'gnus-summary-mode-hook #'nnmairix-summary-mode-hook))) ;; Customizable stuff @@ -783,7 +783,7 @@ called interactively, user will be asked for parameters." (setq finished (not (y-or-n-p "Add another search query? ")) achar nil)) (nnmairix-search - (mapconcat 'identity query " ") + (mapconcat #'identity query " ") (car (nnmairix-get-server)) (y-or-n-p "Include whole threads? ")))) @@ -824,7 +824,7 @@ called interactively, user will be asked for parameters." (setq group (read-string "Group name: ")) (set-buffer gnus-summary-buffer) (message "Creating group %s on server %s with query %s." group - (gnus-method-to-server server) (mapconcat 'identity query " ")) + (gnus-method-to-server server) (mapconcat #'identity query " ")) (nnmairix-create-search-group server group query threads))) (defun nnmairix-create-server-and-default-group () @@ -866,7 +866,7 @@ All necessary information will be queried from the user." (if (eq (car method) 'nnmairix) (progn (when (listp oldquery) - (setq oldquery (mapconcat 'identity oldquery " "))) + (setq oldquery (mapconcat #'identity oldquery " "))) (setq query (or query (read-string "New query: " oldquery))) (when (stringp query) @@ -1068,7 +1068,7 @@ with `nnmairix-mairix-update-options'." (if (> (length commandsplit) 1) (setq args (append args (cdr commandsplit) nnmairix-mairix-update-options)) (setq args (append args nnmairix-mairix-update-options))) - (apply 'call-process args) + (apply #'call-process args) (nnheader-message 7 "Updating mairix database for %s... done" cur)) (progn (setq args (append (list cur (get-buffer nnmairix-mairix-output-buffer) @@ -1076,7 +1076,7 @@ with `nnmairix-mairix-update-options'." (if (> (length commandsplit) 1) (setq args (append args (cdr commandsplit) nnmairix-mairix-update-options)) (setq args (append args nnmairix-mairix-update-options))) - (set-process-sentinel (apply 'start-process args) + (set-process-sentinel (apply #'start-process args) 'nnmairix-sentinel-mairix-update-finished)))))) (defun nnmairix-group-delete-recreate-this-group () @@ -1260,7 +1260,7 @@ If THREADS is non-nil, enable full threads." (setq args (append args '("-c")))) (when threads (setq args (append args '("-t")))) - (apply 'call-process + (apply #'call-process (append args (list "-o" folder) searchquery))))) (defun nnmairix-call-mairix-binary-raw (command query) @@ -1272,7 +1272,7 @@ If THREADS is non-nil, enable full threads." (when (> (length command) 1) (setq args (append args (cdr command)))) (setq args (append args '("-r"))) - (apply 'call-process + (apply #'call-process (append args query))))) (defun nnmairix-get-server () @@ -1382,9 +1382,9 @@ This should correct problems of wrong article counts when using nnmairix with nnml backends." (let* ((files (sort - (mapcar 'string-to-number + (mapcar #'string-to-number (directory-files path nil "[0-9]+" t)) - '<)) + #'<)) (lastplusone (car files)) (path (file-name-as-directory path))) (dolist (cur files) @@ -1774,7 +1774,7 @@ If VERSION is a string: must be contained in mairix version output." (let* ((commandsplit (split-string nnmairix-mairix-command)) (args (append (list (car commandsplit)) '(nil t nil) (cdr commandsplit) '("-V")))) - (apply 'call-process args) + (apply #'call-process args) (goto-char (point-min)) (re-search-forward "mairix.*") (match-string 0)))) @@ -1920,7 +1920,7 @@ If WITHVALUES is t, query is based on current article." (when (not (zerop (length flag))) (push (concat "F:" flag) query))) ;; return query string - (mapconcat 'identity query " "))) + (mapconcat #'identity query " "))) (defun nnmairix-widget-create-query (&optional values) @@ -1997,7 +1997,7 @@ VALUES may contain values for editable fields from current article." "Add a widget NAME with optional ARGS." (push (list name - (apply 'widget-create args)) + (apply #'widget-create args)) nnmairix-widgets)) (defun nnmairix-widget-toggle-activate (widget) diff --git a/lisp/gnus/nnmh.el b/lisp/gnus/nnmh.el index 82ed091982..46abf46ce7 100644 --- a/lisp/gnus/nnmh.el +++ b/lisp/gnus/nnmh.el @@ -171,9 +171,9 @@ as unread by Gnus.") (nnheader-re-read-dir pathname) (setq dir (sort - (mapcar 'string-to-number + (mapcar #'string-to-number (directory-files pathname nil "\\`[0-9]+\\'" t)) - '<)) + #'<)) (cond (dir (setq nnmh-group-alist @@ -358,12 +358,12 @@ as unread by Gnus.") nnmh-group-alist) (nnmh-possibly-create-directory group) (nnmh-possibly-change-directory group server) - (let ((articles (mapcar 'string-to-number + (let ((articles (mapcar #'string-to-number (directory-files nnmh-current-directory nil "\\`[0-9]+\\'")))) (when articles - (setcar active (apply 'min articles)) - (setcdr active (apply 'max articles)))))) + (setcar active (apply #'min articles)) + (setcdr active (apply #'max articles)))))) t) (deffoo nnmh-request-delete-group (group &optional force server) @@ -484,9 +484,9 @@ as unread by Gnus.") (gnus-make-directory dir)) ;; Find the highest number in the group. (let ((files (sort - (mapcar 'string-to-number + (mapcar #'string-to-number (directory-files dir nil "\\`[0-9]+\\'")) - '>))) + #'>))) (when files (setcdr active (car files))))) (setcdr active (1+ (cdr active))) @@ -507,10 +507,10 @@ as unread by Gnus.") ;; articles in this folder. The articles that are "new" will be ;; marked as unread by Gnus. (let* ((dir nnmh-current-directory) - (files (sort (mapcar 'string-to-number + (files (sort (mapcar #'string-to-number (directory-files nnmh-current-directory nil "\\`[0-9]+\\'" t)) - '<)) + #'<)) (nnmh-file (concat dir ".nnmh-articles")) new articles) ;; Load the .nnmh-articles file. @@ -557,7 +557,7 @@ as unread by Gnus.") (when new (gnus-make-articles-unread (gnus-group-prefixed-name group (list 'nnmh "")) - (setq new (sort new '<)))) + (setq new (sort new #'<)))) ;; Sort the article list with highest numbers first. (setq articles (sort articles (lambda (art1 art2) (> (car art1) (car art2))))) diff --git a/lisp/gnus/nnml.el b/lisp/gnus/nnml.el index 3cdfc74970..eaa2004272 100644 --- a/lisp/gnus/nnml.el +++ b/lisp/gnus/nnml.el @@ -278,8 +278,8 @@ non-nil.") (let* ((file-name-coding-system nnmail-pathname-coding-system) (articles (nnml-directory-articles nnml-current-directory))) (when articles - (setcar active (apply 'min articles)) - (setcdr active (apply 'max articles)))) + (setcar active (apply #'min articles)) + (setcdr active (apply #'max articles)))) (nnmail-save-active nnml-group-alist nnml-active-file) t)))) @@ -307,7 +307,7 @@ non-nil.") article rest mod-time number target) (nnmail-activate 'nnml) - (setq active-articles (sort active-articles '<)) + (setq active-articles (sort active-articles #'<)) ;; Articles not listed in active-articles are already gone, ;; so don't try to expire them. (setq articles (gnus-sorted-intersection articles active-articles)) @@ -353,7 +353,7 @@ non-nil.") (let ((active (nth 1 (assoc-string group nnml-group-alist)))) (when active (setcar active (or (and active-articles - (apply 'min active-articles)) + (apply #'min active-articles)) (1+ (cdr active))))) (nnmail-save-active nnml-group-alist nnml-active-file)) (nnml-save-nov) @@ -705,7 +705,7 @@ article number. This function is called narrowed to an article." (setq nnml-article-file-alist (sort (nnml-current-group-article-to-file-alist) - 'car-less-than-car))) + #'car-less-than-car))) (setq active (if nnml-article-file-alist (cons (caar nnml-article-file-alist) @@ -856,7 +856,7 @@ Unless no-active is non-nil, update the active file too." (nnml-generate-nov-databases-directory dir seen))) ;; Do this directory. (let ((nnml-files (sort (nnheader-article-to-file-alist dir) - 'car-less-than-car))) + #'car-less-than-car))) (if (not nnml-files) (let* ((group (nnheader-file-to-group (directory-file-name dir) nnml-directory)) @@ -1010,7 +1010,7 @@ Use the nov database for the current group if available." (unless nnml-article-file-alist (setq nnml-article-file-alist (sort (nnml-current-group-article-to-file-alist) - 'car-less-than-car))) + #'car-less-than-car))) (if (not nnml-article-file-alist) ;; The group is empty: do nothing but return t t diff --git a/lisp/gnus/nnrss.el b/lisp/gnus/nnrss.el index f9e0a08a06..a340c9e2b8 100644 --- a/lisp/gnus/nnrss.el +++ b/lisp/gnus/nnrss.el @@ -798,7 +798,7 @@ It is useful when `(setq nnrss-use-local t)'." (defun nnrss-node-just-text (node) (if (and node (listp node)) - (mapconcat 'nnrss-node-just-text (cddr node) " ") + (mapconcat #'nnrss-node-just-text (cddr node) " ") node)) (defun nnrss-find-el (tag data &optional found-list) diff --git a/lisp/gnus/nnselect.el b/lisp/gnus/nnselect.el index ba0e60a267..fffa2d2731 100644 --- a/lisp/gnus/nnselect.el +++ b/lisp/gnus/nnselect.el @@ -81,12 +81,12 @@ "Compress ARTLIST." (let (selection) (pcase-dolist (`(,artgroup . ,arts) - (nnselect-categorize artlist 'nnselect-artitem-group)) + (nnselect-categorize artlist #'nnselect-artitem-group)) (let (list) (pcase-dolist (`(,rsv . ,articles) (nnselect-categorize - arts 'nnselect-artitem-rsv 'nnselect-artitem-number)) - (push (cons rsv (gnus-compress-sequence (sort articles '<))) + arts #'nnselect-artitem-rsv #'nnselect-artitem-number)) + (push (cons rsv (gnus-compress-sequence (sort articles #'<))) list)) (push (cons artgroup list) selection))) selection)) @@ -200,25 +200,27 @@ as `(keyfunc member)' and the corresponding element is just (define-inline ids-by-group (articles) (inline-quote - (nnselect-categorize ,articles 'nnselect-article-group - 'nnselect-article-id))) + (nnselect-categorize ,articles #'nnselect-article-group + #'nnselect-article-id))) (define-inline numbers-by-group (articles &optional type) (inline-quote (cond ((eq ,type 'range) (nnselect-categorize (gnus-uncompress-range ,articles) - 'nnselect-article-group 'nnselect-article-number)) + #'nnselect-article-group #'nnselect-article-number)) ((eq ,type 'tuple) (nnselect-categorize ,articles #'(lambda (elem) (nnselect-article-group (car elem))) #'(lambda (elem) (cons (nnselect-article-number - (car elem)) (cdr elem))))) + (car elem)) + (cdr elem))))) (t (nnselect-categorize ,articles - 'nnselect-article-group 'nnselect-article-number))))) + #'nnselect-article-group + #'nnselect-article-number))))) (defmacro nnselect-add-prefix (group) "Ensures that the GROUP has an nnselect prefix." @@ -319,7 +321,7 @@ If this variable is nil, or if the provided function returns nil, headers) (with-current-buffer nntp-server-buffer (pcase-dolist (`(,artgroup . ,artids) gartids) - (let ((artlist (sort (mapcar 'cdr artids) '<)) + (let ((artlist (sort (mapcar #'cdr artids) #'<)) (gnus-override-method (gnus-find-method-for-group artgroup)) (fetch-old (or @@ -385,7 +387,8 @@ If this variable is nil, or if the provided function returns nil, (list (gnus-method-to-server (gnus-find-method-for-group - (nnselect-article-group x)))) servers :test 'equal))) + (nnselect-article-group x)))) + servers :test 'equal))) (gnus-articles-in-thread thread))))) (setq servers (list (list server)))) (setq artlist @@ -455,7 +458,7 @@ If this variable is nil, or if the provided function returns nil, (if force (let (not-expired) (pcase-dolist (`(,artgroup . ,artids) (ids-by-group articles)) - (let ((artlist (sort (mapcar 'cdr artids) '<))) + (let ((artlist (sort (mapcar #'cdr artids) #'<))) (unless (gnus-check-backend-function 'request-expire-articles artgroup) (error "Group %s does not support article expiration" artgroup)) @@ -467,7 +470,7 @@ If this variable is nil, or if the provided function returns nil, (gnus-request-expire-articles artlist artgroup force))) not-expired))) - (sort (delq nil not-expired) '<)) + (sort (delq nil not-expired) #'<)) articles)) @@ -518,11 +521,11 @@ If this variable is nil, or if the provided function returns nil, (mapcar (lambda (artgroup) (list (car artgroup) - (gnus-compress-sequence (sort (cdr artgroup) '<)) + (gnus-compress-sequence (sort (cdr artgroup) #'<)) action marks)) (numbers-by-group range 'range)))) actions) - 'car 'cdr))) + #'car #'cdr))) (deffoo nnselect-request-update-info (group info &optional _server) (let* ((group (nnselect-add-prefix group)) @@ -651,8 +654,9 @@ If this variable is nil, or if the provided function returns nil, new-nnselect-artlist) (setq headers (gnus-fetch-headers - (append (sort old-arts '<) - (number-sequence first last)) nil t)) + (append (sort old-arts #'<) + (number-sequence first last)) + nil t)) (gnus-group-set-parameter group 'nnselect-artlist @@ -942,7 +946,7 @@ article came from is also searched." (gnus-remove-from-range old-unread (cdr (assoc artgroup select-reads))) - (sort (cdr (assoc artgroup select-unreads)) '<)))) + (sort (cdr (assoc artgroup select-unreads)) #'<)))) (gnus-get-unread-articles-in-group group-info (gnus-active artgroup) t) (gnus-group-update-group artgroup t t))))))) diff --git a/lisp/gnus/nnspool.el b/lisp/gnus/nnspool.el index 9de59d8631..cb85417856 100644 --- a/lisp/gnus/nnspool.el +++ b/lisp/gnus/nnspool.el @@ -261,7 +261,7 @@ there.") ;; Yes, completely empty spool directories *are* possible. ;; Fix by Sudish Joseph (when (setq dir (directory-files pathname nil "\\`[0-9]+\\'" t)) - (setq dir (sort (mapcar 'string-to-number dir) '<))) + (setq dir (sort (mapcar #'string-to-number dir) #'<))) (if dir (nnheader-insert "211 %d %d %d %s\n" (length dir) (car dir) @@ -331,7 +331,7 @@ there.") (buf (current-buffer)) (proc (condition-case err - (apply 'start-process "*nnspool inews*" inews-buffer + (apply #'start-process "*nnspool inews*" inews-buffer nnspool-inews-program nnspool-inews-switches) (error (nnheader-report 'nnspool "inews error: %S" err))))) @@ -409,7 +409,7 @@ there.") (<= last (car arts))) (pop arts)) ;; The articles in `arts' are missing from the buffer. - (mapc 'nnspool-insert-nov-head arts) + (mapc #'nnspool-insert-nov-head arts) t)))))))))) (defun nnspool-insert-nov-head (article) diff --git a/lisp/gnus/nnvirtual.el b/lisp/gnus/nnvirtual.el index 1e2feda636..902df868f8 100644 --- a/lisp/gnus/nnvirtual.el +++ b/lisp/gnus/nnvirtual.el @@ -367,7 +367,7 @@ It is computed from the marks of individual component groups.") group article)) (gnus-uncompress-range (gnus-group-expire-articles-1 group)))))) - (sort (delq nil unexpired) '<))) + (sort (delq nil unexpired) #'<))) ;;; Internal functions. @@ -378,7 +378,7 @@ It is computed from the marks of individual component groups.") (let* ((dependencies (make-hash-table :test #'equal)) (headers (gnus-get-newsgroup-headers dependencies))) (erase-buffer) - (mapc 'nnheader-insert-nov headers)))) + (mapc #'nnheader-insert-nov headers)))) (defun nnvirtual-update-xref-header (group article prefix sysname) @@ -502,7 +502,7 @@ If UPDATE-P is not nil, call gnus-group-update-group on the components." "Merge many sorted lists of numbers." (if (null (cdr lists)) (car lists) - (sort (apply 'nconc lists) '<))) + (sort (apply #'nconc lists) #'<))) ;; We map between virtual articles and real articles in a manner @@ -648,7 +648,7 @@ numbers has no corresponding component article, then it is left out of the result." (when (numberp (cdr-safe articles)) (setq articles (list articles))) - (let ((carticles (mapcar 'list nnvirtual-component-groups)) + (let ((carticles (mapcar #'list nnvirtual-component-groups)) a i j article entry) (while (setq a (pop articles)) (if (atom a) @@ -750,7 +750,7 @@ based on the marks on the component groups." ;; Now that the mapping tables are generated, we can convert ;; and combine the separate component unreads and marks lists ;; into single lists of virtual article numbers. - (setq unreads (apply 'nnvirtual-merge-sorted-lists + (setq unreads (apply #'nnvirtual-merge-sorted-lists (mapcar (lambda (x) (nnvirtual-reverse-map-sequence (car x) (cdr x))) @@ -760,7 +760,7 @@ based on the marks on the component groups." (cons (cdr type) (gnus-compress-sequence (apply - 'nnvirtual-merge-sorted-lists + #'nnvirtual-merge-sorted-lists (mapcar (lambda (x) (nnvirtual-reverse-map-sequence (car x) diff --git a/lisp/gnus/nnweb.el b/lisp/gnus/nnweb.el index b8fb4a8373..2a94825471 100644 --- a/lisp/gnus/nnweb.el +++ b/lisp/gnus/nnweb.el @@ -411,7 +411,7 @@ Valid types include `google', `dejanews', and `gmane'.") ;; Return the articles in the right order. (nnheader-message 7 "Searching google...done") (setq nnweb-articles - (sort nnweb-articles 'car-less-than-car)))))) + (sort nnweb-articles #'car-less-than-car)))))) (defun nnweb-google-search (search) (mm-url-insert @@ -481,7 +481,7 @@ Valid types include `google', `dejanews', and `gmane'.") (forward-line 1))) (nnheader-message 7 "Searching Gmane...done") (setq nnweb-articles - (sort (nconc nnweb-articles map) 'car-less-than-car))))) + (sort (nconc nnweb-articles map) #'car-less-than-car))))) (defun nnweb-gmane-wash-article () (let ((case-fold-search t)) @@ -534,7 +534,7 @@ Valid types include `google', `dejanews', and `gmane'.") (nth 1 parse) " ")) (insert ">\n") - (mapc 'nnweb-insert-html (nth 2 parse)) + (mapc #'nnweb-insert-html (nth 2 parse)) (insert "\n"))) (defun nnweb-parse-find (type parse &optional maxdepth) diff --git a/lisp/gnus/smiley.el b/lisp/gnus/smiley.el index d9e04f3b40..9884bcc075 100644 --- a/lisp/gnus/smiley.el +++ b/lisp/gnus/smiley.el @@ -71,9 +71,8 @@ (set-default symbol value) (setq smiley-data-directory (smiley-directory)) (smiley-update-cache)) - :initialize 'custom-initialize-default - :version "23.1" ;; No Gnus - :group 'smiley) + :initialize #'custom-initialize-default + :version "23.1") ;; No Gnus ;; For compatibility, honor the variable `smiley-data-directory' if the user ;; has set it. @@ -94,9 +93,8 @@ is nil, use `smiley-style'." :set (lambda (symbol value) (set-default symbol value) (smiley-update-cache)) - :initialize 'custom-initialize-default - :type 'directory - :group 'smiley) + :initialize #'custom-initialize-default + :type 'directory) (defcustom smiley-emoji-regexp-alist '(("\\(;-)\\)\\W" 1 "😉") @@ -124,8 +122,7 @@ regexp to replace with EMOJI." :set (lambda (symbol value) (set-default symbol value) (smiley-update-cache)) - :initialize 'custom-initialize-default - :group 'smiley) + :initialize #'custom-initialize-default) ;; The XEmacs version has a baroque, if not rococo, set of these. (defcustom smiley-regexp-alist @@ -154,8 +151,7 @@ regexp to replace with IMAGE. IMAGE is the name of an image file in :set (lambda (symbol value) (set-default symbol value) (smiley-update-cache)) - :initialize 'custom-initialize-default - :group 'smiley) + :initialize #'custom-initialize-default) (defcustom gnus-smiley-file-types (let ((types (list "pbm"))) @@ -166,8 +162,7 @@ regexp to replace with IMAGE. IMAGE is the name of an image file in types) "List of suffixes on smiley file names to try." :version "24.1" - :type '(repeat string) - :group 'smiley) + :type '(repeat string)) (defvar smiley-cached-regexp-alist nil) diff --git a/lisp/gnus/smime.el b/lisp/gnus/smime.el index ae5d171d87..147c51d89a 100644 --- a/lisp/gnus/smime.el +++ b/lisp/gnus/smime.el @@ -282,7 +282,7 @@ key and certificate itself." (setenv "GNUS_SMIME_PASSPHRASE" passphrase)) (prog1 (when (prog1 - (apply 'smime-call-openssl-region b e (list buffer tmpfile) + (apply #'smime-call-openssl-region b e (list buffer tmpfile) "smime" "-sign" "-signer" (expand-file-name keyfile) (append (smime-make-certfiles certfiles) @@ -314,9 +314,9 @@ is expected to contain of a PEM encoded certificate." (tmpfile (make-temp-file "smime"))) (prog1 (when (prog1 - (apply 'smime-call-openssl-region b e (list buffer tmpfile) + (apply #'smime-call-openssl-region b e (list buffer tmpfile) "smime" "-encrypt" smime-encrypt-cipher - (mapcar 'expand-file-name certfiles)) + (mapcar #'expand-file-name certfiles)) (with-current-buffer smime-details-buffer (insert-file-contents tmpfile) (delete-file tmpfile))) @@ -384,7 +384,7 @@ Any details (stdout and stderr) are left in the buffer specified by (with-temp-buffer (let ((result-buffer (current-buffer))) (with-current-buffer input-buffer - (if (apply 'smime-call-openssl-region b e (list result-buffer + (if (apply #'smime-call-openssl-region b e (list result-buffer smime-details-buffer) "smime" "-verify" "-out" "-" CAs) (with-current-buffer result-buffer @@ -397,7 +397,7 @@ Returns non-nil on success. Any details (stdout and stderr) are left in the buffer specified by `smime-details-buffer'." (smime-new-details-buffer) - (if (apply 'smime-call-openssl-region b e (list smime-details-buffer t) + (if (apply #'smime-call-openssl-region b e (list smime-details-buffer t) "smime" "-verify" "-noverify" "-out" `(,null-device)) t (insert-buffer-substring smime-details-buffer) @@ -416,7 +416,7 @@ in the buffer specified by `smime-details-buffer'." (if passphrase (setenv "GNUS_SMIME_PASSPHRASE" passphrase)) (if (prog1 - (apply 'smime-call-openssl-region b e + (apply #'smime-call-openssl-region b e (list buffer tmpfile) "smime" "-decrypt" "-recip" (expand-file-name keyfile) (if passphrase diff --git a/lisp/gnus/spam-report.el b/lisp/gnus/spam-report.el index 8c148ce9d9..e2125563f2 100644 --- a/lisp/gnus/spam-report.el +++ b/lisp/gnus/spam-report.el @@ -345,8 +345,8 @@ Spam reports will be queued with \\[spam-report-url-to-file] when the Agent is unplugged, and will be submitted in a batch when the Agent is plugged." (interactive) - (add-hook 'gnus-agent-plugged-hook 'spam-report-plug-agent) - (add-hook 'gnus-agent-unplugged-hook 'spam-report-unplug-agent)) + (add-hook 'gnus-agent-plugged-hook #'spam-report-plug-agent) + (add-hook 'gnus-agent-unplugged-hook #'spam-report-unplug-agent)) ;;;###autoload (defun spam-report-deagentize () @@ -354,8 +354,8 @@ Agent is plugged." Spam reports will be queued with the method used when \\[spam-report-agentize] was run." (interactive) - (remove-hook 'gnus-agent-plugged-hook 'spam-report-plug-agent) - (remove-hook 'gnus-agent-unplugged-hook 'spam-report-unplug-agent)) + (remove-hook 'gnus-agent-plugged-hook #'spam-report-plug-agent) + (remove-hook 'gnus-agent-unplugged-hook #'spam-report-unplug-agent)) (defun spam-report-plug-agent () "Adjust spam report settings for plugged state. diff --git a/lisp/gnus/spam-stat.el b/lisp/gnus/spam-stat.el index 3662ade266..89c2deb36f 100644 --- a/lisp/gnus/spam-stat.el +++ b/lisp/gnus/spam-stat.el @@ -501,7 +501,7 @@ where DIFF is the difference between SCORE and 0.5." Add user supplied modifications if supplied." (interactive) ; helps in debugging. (setq spam-stat-score-data (spam-stat-buffer-words-with-scores)) - (let* ((probs (mapcar 'cadr spam-stat-score-data)) + (let* ((probs (mapcar #'cadr spam-stat-score-data)) (prod (apply #'* probs)) (score0 (/ prod (+ prod (apply #'* (mapcar #'(lambda (x) (- 1 x)) @@ -652,19 +652,19 @@ COUNT defaults to 5" "Install the spam-stat function hooks." (interactive) (add-hook 'nnmail-prepare-incoming-message-hook - 'spam-stat-store-current-buffer) + #'spam-stat-store-current-buffer) (add-hook 'gnus-select-article-hook - 'spam-stat-store-gnus-article-buffer)) + #'spam-stat-store-gnus-article-buffer)) (defun spam-stat-unload-hook () "Uninstall the spam-stat function hooks." (interactive) (remove-hook 'nnmail-prepare-incoming-message-hook - 'spam-stat-store-current-buffer) + #'spam-stat-store-current-buffer) (remove-hook 'gnus-select-article-hook - 'spam-stat-store-gnus-article-buffer)) + #'spam-stat-store-gnus-article-buffer)) -(add-hook 'spam-stat-unload-hook 'spam-stat-unload-hook) +(add-hook 'spam-stat-unload-hook #'spam-stat-unload-hook) (provide 'spam-stat) diff --git a/lisp/gnus/spam-wash.el b/lisp/gnus/spam-wash.el index 1d00a39060..1c755fb464 100644 --- a/lisp/gnus/spam-wash.el +++ b/lisp/gnus/spam-wash.el @@ -57,7 +57,7 @@ (defun spam-treat-parts (handle) (if (stringp (car handle)) - (mapcar 'spam-treat-parts (cdr handle)) + (mapcar #'spam-treat-parts (cdr handle)) (if (bufferp (car handle)) (save-restriction (narrow-to-region (point) (point)) @@ -65,7 +65,7 @@ (string-match "text" (car (mm-handle-type handle)))) (mm-insert-part handle)) (goto-char (point-max))) - (mapcar 'spam-treat-parts handle)))) + (mapcar #'spam-treat-parts handle)))) (provide 'spam-wash) diff --git a/lisp/gnus/spam.el b/lisp/gnus/spam.el index 22810332b6..3f4fd3614e 100644 --- a/lisp/gnus/spam.el +++ b/lisp/gnus/spam.el @@ -705,7 +705,7 @@ finds ham or spam.") "Clear the `spam-caches' entry for a check." (remhash symbol spam-caches)) -(define-obsolete-function-alias 'spam-xor 'xor "27.1") +(define-obsolete-function-alias 'spam-xor #'xor "27.1") (defun spam-set-difference (list1 list2) "Return a set difference of LIST1 and LIST2. @@ -727,7 +727,7 @@ When either list is nil, the other is returned." (let* ((marks (spam-group-ham-marks group spam)) (marks (if (symbolp mark) marks - (mapcar 'symbol-value marks)))) + (mapcar #'symbol-value marks)))) (memq mark marks)))) (defun spam-group-spam-mark-p (group mark) @@ -1014,28 +1014,28 @@ backends)." ;;{{{ backend installations (spam-install-checkonly-backend 'spam-use-blackholes - 'spam-check-blackholes) + #'spam-check-blackholes) (spam-install-checkonly-backend 'spam-use-hashcash - 'spam-check-hashcash) + #'spam-check-hashcash) (spam-install-checkonly-backend 'spam-use-spamassassin-headers - 'spam-check-spamassassin-headers) + #'spam-check-spamassassin-headers) (spam-install-checkonly-backend 'spam-use-bogofilter-headers - 'spam-check-bogofilter-headers) + #'spam-check-bogofilter-headers) (spam-install-checkonly-backend 'spam-use-bsfilter-headers - 'spam-check-bsfilter-headers) + #'spam-check-bsfilter-headers) (spam-install-checkonly-backend 'spam-use-gmane-xref - 'spam-check-gmane-xref) + #'spam-check-gmane-xref) (spam-install-checkonly-backend 'spam-use-regex-headers - 'spam-check-regex-headers) + #'spam-check-regex-headers) (spam-install-statistical-checkonly-backend 'spam-use-regex-body - 'spam-check-regex-body) + #'spam-check-regex-body) ;; TODO: NOTE: spam-use-ham-copy is now obsolete, use (ham spam-use-copy) (spam-install-mover-backend 'spam-use-move @@ -1045,94 +1045,94 @@ backends)." nil) (spam-install-nocheck-backend 'spam-use-copy - 'spam-copy-ham-routine - 'spam-copy-spam-routine + #'spam-copy-ham-routine + #'spam-copy-spam-routine nil nil) (spam-install-nocheck-backend 'spam-use-gmane - 'spam-report-gmane-unregister-routine - 'spam-report-gmane-register-routine - 'spam-report-gmane-register-routine - 'spam-report-gmane-unregister-routine) + #'spam-report-gmane-unregister-routine + #'spam-report-gmane-register-routine + #'spam-report-gmane-register-routine + #'spam-report-gmane-unregister-routine) (spam-install-nocheck-backend 'spam-use-resend - 'spam-report-resend-register-ham-routine - 'spam-report-resend-register-routine + #'spam-report-resend-register-ham-routine + #'spam-report-resend-register-routine nil nil) (spam-install-backend 'spam-use-BBDB - 'spam-check-BBDB - 'spam-BBDB-register-routine + #'spam-check-BBDB + #'spam-BBDB-register-routine nil - 'spam-BBDB-unregister-routine + #'spam-BBDB-unregister-routine nil) (spam-install-backend-alias 'spam-use-BBDB 'spam-use-BBDB-exclusive) (spam-install-backend 'spam-use-blacklist - 'spam-check-blacklist + #'spam-check-blacklist nil - 'spam-blacklist-register-routine + #'spam-blacklist-register-routine nil - 'spam-blacklist-unregister-routine) + #'spam-blacklist-unregister-routine) (spam-install-backend 'spam-use-whitelist - 'spam-check-whitelist - 'spam-whitelist-register-routine + #'spam-check-whitelist + #'spam-whitelist-register-routine nil - 'spam-whitelist-unregister-routine + #'spam-whitelist-unregister-routine nil) (spam-install-statistical-backend 'spam-use-ifile - 'spam-check-ifile - 'spam-ifile-register-ham-routine - 'spam-ifile-register-spam-routine - 'spam-ifile-unregister-ham-routine - 'spam-ifile-unregister-spam-routine) + #'spam-check-ifile + #'spam-ifile-register-ham-routine + #'spam-ifile-register-spam-routine + #'spam-ifile-unregister-ham-routine + #'spam-ifile-unregister-spam-routine) (spam-install-statistical-backend 'spam-use-spamoracle - 'spam-check-spamoracle - 'spam-spamoracle-learn-ham - 'spam-spamoracle-learn-spam - 'spam-spamoracle-unlearn-ham - 'spam-spamoracle-unlearn-spam) + #'spam-check-spamoracle + #'spam-spamoracle-learn-ham + #'spam-spamoracle-learn-spam + #'spam-spamoracle-unlearn-ham + #'spam-spamoracle-unlearn-spam) (spam-install-statistical-backend 'spam-use-stat - 'spam-check-stat - 'spam-stat-register-ham-routine - 'spam-stat-register-spam-routine - 'spam-stat-unregister-ham-routine - 'spam-stat-unregister-spam-routine) + #'spam-check-stat + #'spam-stat-register-ham-routine + #'spam-stat-register-spam-routine + #'spam-stat-unregister-ham-routine + #'spam-stat-unregister-spam-routine) (spam-install-statistical-backend 'spam-use-spamassassin - 'spam-check-spamassassin - 'spam-spamassassin-register-ham-routine - 'spam-spamassassin-register-spam-routine - 'spam-spamassassin-unregister-ham-routine - 'spam-spamassassin-unregister-spam-routine) + #'spam-check-spamassassin + #'spam-spamassassin-register-ham-routine + #'spam-spamassassin-register-spam-routine + #'spam-spamassassin-unregister-ham-routine + #'spam-spamassassin-unregister-spam-routine) (spam-install-statistical-backend 'spam-use-bogofilter - 'spam-check-bogofilter - 'spam-bogofilter-register-ham-routine - 'spam-bogofilter-register-spam-routine - 'spam-bogofilter-unregister-ham-routine - 'spam-bogofilter-unregister-spam-routine) + #'spam-check-bogofilter + #'spam-bogofilter-register-ham-routine + #'spam-bogofilter-register-spam-routine + #'spam-bogofilter-unregister-ham-routine + #'spam-bogofilter-unregister-spam-routine) (spam-install-statistical-backend 'spam-use-bsfilter - 'spam-check-bsfilter - 'spam-bsfilter-register-ham-routine - 'spam-bsfilter-register-spam-routine - 'spam-bsfilter-unregister-ham-routine - 'spam-bsfilter-unregister-spam-routine) + #'spam-check-bsfilter + #'spam-bsfilter-register-ham-routine + #'spam-bsfilter-register-spam-routine + #'spam-bsfilter-unregister-ham-routine + #'spam-bsfilter-unregister-spam-routine) (spam-install-statistical-backend 'spam-use-crm114 - 'spam-check-crm114 - 'spam-crm114-register-ham-routine - 'spam-crm114-register-spam-routine - 'spam-crm114-unregister-ham-routine - 'spam-crm114-unregister-spam-routine) + #'spam-check-crm114 + #'spam-crm114-register-ham-routine + #'spam-crm114-register-spam-routine + #'spam-crm114-unregister-ham-routine + #'spam-crm114-unregister-spam-routine) ;;}}} ;;{{{ scoring and summary formatting @@ -1709,7 +1709,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (if (or (null first-method) (equal first-method 'default)) (spam-split) - (apply 'spam-split methods)))))) + (apply #'spam-split methods)))))) (if (equal split-return 'spam) (gnus-summary-mark-article article gnus-spam-mark)) @@ -1981,7 +1981,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." (defun spam-reverse-ip-string (ip) (when (stringp ip) - (mapconcat 'identity + (mapconcat #'identity (nreverse (split-string ip "\\.")) "."))) @@ -2139,7 +2139,7 @@ See `spam-ifile-database'." (let ((temp-buffer-name (buffer-name)) (db-param (spam-get-ifile-database-parameter))) (with-current-buffer article-buffer-name - (apply 'call-process-region + (apply #'call-process-region (point-min) (point-max) spam-ifile-program nil temp-buffer-name nil "-c" (if db-param `(,db-param "-q") '("-q")))) @@ -2167,7 +2167,7 @@ Uses `gnus-newsgroup-name' if category is nil (for ham registration)." (let ((article-string (spam-get-article-as-string article))) (when (stringp article-string) (insert article-string)))) - (apply 'call-process-region + (apply #'call-process-region (point-min) (point-max) spam-ifile-program nil nil nil add-or-delete-option category @@ -2406,11 +2406,11 @@ With a non-nil REMOVE, remove the ADDRESSES." ;;{{{ Spam-report glue (gmane and resend reporting) (defun spam-report-gmane-register-routine (articles) (when articles - (apply 'spam-report-gmane-spam articles))) + (apply #'spam-report-gmane-spam articles))) (defun spam-report-gmane-unregister-routine (articles) (when articles - (apply 'spam-report-gmane-ham articles))) + (apply #'spam-report-gmane-ham articles))) (defun spam-report-resend-register-ham-routine (articles) (spam-report-resend-register-routine articles t)) @@ -2474,7 +2474,7 @@ With a non-nil REMOVE, remove the ADDRESSES." (with-temp-buffer (let ((temp-buffer-name (buffer-name))) (with-current-buffer article-buffer-name - (apply 'call-process-region + (apply #'call-process-region (point-min) (point-max) spam-bogofilter-program nil temp-buffer-name nil @@ -2502,7 +2502,7 @@ With a non-nil REMOVE, remove the ADDRESSES." (with-temp-buffer (insert article-string) - (apply 'call-process-region + (apply #'call-process-region (point-min) (point-max) spam-bogofilter-program nil nil nil switch @@ -2532,7 +2532,7 @@ With a non-nil REMOVE, remove the ADDRESSES." (let ((temp-buffer-name (buffer-name))) (with-current-buffer article-buffer-name (let ((status - (apply 'call-process-region + (apply #'call-process-region (point-min) (point-max) spam-spamoracle-binary nil temp-buffer-name nil @@ -2559,7 +2559,7 @@ With a non-nil REMOVE, remove the ADDRESSES." "-spam" "-good")) (status - (apply 'call-process-region + (apply #'call-process-region (point-min) (point-max) spam-spamoracle-binary nil temp-buffer-name nil @@ -2607,7 +2607,7 @@ With a non-nil REMOVE, remove the ADDRESSES." (with-temp-buffer (let ((temp-buffer-name (buffer-name))) (with-current-buffer article-buffer-name - (apply 'call-process-region + (apply #'call-process-region (point-min) (point-max) spam-assassin-program nil temp-buffer-name nil spam-spamassassin-arguments)) ;; check the return now (we're back in the temp buffer) @@ -2648,7 +2648,7 @@ With a non-nil REMOVE, remove the ADDRESSES." (insert article-string) (insert "\n")))) ;; call sa-learn on all messages at the same time - (apply 'call-process-region + (apply #'call-process-region (point-min) (point-max) spam-sa-learn-program nil nil nil "--mbox" @@ -2703,7 +2703,7 @@ With a non-nil REMOVE, remove the ADDRESSES." (with-temp-buffer (let ((temp-buffer-name (buffer-name))) (with-current-buffer article-buffer-name - (apply 'call-process-region + (apply #'call-process-region (point-min) (point-max) spam-bsfilter-program nil temp-buffer-name nil @@ -2731,7 +2731,7 @@ With a non-nil REMOVE, remove the ADDRESSES." (when (stringp article-string) (with-temp-buffer (insert article-string) - (apply 'call-process-region + (apply #'call-process-region (point-min) (point-max) spam-bsfilter-program nil nil nil switch @@ -2788,7 +2788,7 @@ With a non-nil REMOVE, remove the ADDRESSES." (with-temp-buffer (let ((temp-buffer-name (buffer-name))) (with-current-buffer article-buffer-name - (apply 'call-process-region + (apply #'call-process-region (point-min) (point-max) spam-crm114-program nil temp-buffer-name nil @@ -2814,7 +2814,7 @@ With a non-nil REMOVE, remove the ADDRESSES." (with-temp-buffer (insert article-string) - (apply 'call-process-region + (apply #'call-process-region (point-min) (point-max) spam-crm114-program nil nil nil @@ -2859,13 +2859,13 @@ installed through `spam-necessary-extra-headers'." (push '((eq mark gnus-spam-mark) . spam) gnus-summary-highlight) ;; Add hooks for loading and saving the spam stats - (add-hook 'gnus-save-newsrc-hook 'spam-maybe-spam-stat-save) - (add-hook 'gnus-get-top-new-news-hook 'spam-maybe-spam-stat-load) - (add-hook 'gnus-startup-hook 'spam-maybe-spam-stat-load) - (add-hook 'gnus-summary-prepare-exit-hook 'spam-summary-prepare-exit) - (add-hook 'gnus-summary-prepare-hook 'spam-summary-prepare) - (add-hook 'gnus-get-new-news-hook 'spam-setup-widening) - (add-hook 'gnus-summary-prepared-hook 'spam-find-spam) + (add-hook 'gnus-save-newsrc-hook #'spam-maybe-spam-stat-save) + (add-hook 'gnus-get-top-new-news-hook #'spam-maybe-spam-stat-load) + (add-hook 'gnus-startup-hook #'spam-maybe-spam-stat-load) + (add-hook 'gnus-summary-prepare-exit-hook #'spam-summary-prepare-exit) + (add-hook 'gnus-summary-prepare-hook #'spam-summary-prepare) + (add-hook 'gnus-get-new-news-hook #'spam-setup-widening) + (add-hook 'gnus-summary-prepared-hook #'spam-find-spam) ;; Don't install things more than once. (setq spam-install-hooks nil))) @@ -2873,15 +2873,15 @@ installed through `spam-necessary-extra-headers'." "Uninstall the spam.el hooks." (interactive) (spam-teardown-widening) - (remove-hook 'gnus-save-newsrc-hook 'spam-maybe-spam-stat-save) - (remove-hook 'gnus-get-top-new-news-hook 'spam-maybe-spam-stat-load) - (remove-hook 'gnus-startup-hook 'spam-maybe-spam-stat-load) - (remove-hook 'gnus-summary-prepare-exit-hook 'spam-summary-prepare-exit) - (remove-hook 'gnus-summary-prepare-hook 'spam-summary-prepare) - (remove-hook 'gnus-get-new-news-hook 'spam-setup-widening) - (remove-hook 'gnus-summary-prepare-hook 'spam-find-spam)) - -(add-hook 'spam-unload-hook 'spam-unload-hook) + (remove-hook 'gnus-save-newsrc-hook #'spam-maybe-spam-stat-save) + (remove-hook 'gnus-get-top-new-news-hook #'spam-maybe-spam-stat-load) + (remove-hook 'gnus-startup-hook #'spam-maybe-spam-stat-load) + (remove-hook 'gnus-summary-prepare-exit-hook #'spam-summary-prepare-exit) + (remove-hook 'gnus-summary-prepare-hook #'spam-summary-prepare) + (remove-hook 'gnus-get-new-news-hook #'spam-setup-widening) + (remove-hook 'gnus-summary-prepare-hook #'spam-find-spam)) + +(add-hook 'spam-unload-hook #'spam-unload-hook) ;;}}} commit e1e9e4eefa41bacb6b412e57a569440a0847e4fa Author: Stefan Monnier Date: Fri Jan 29 23:58:58 2021 -0500 * lisp/gnus/gnus-art.el: Add `event` args and operate at its position. (gnus-mime-save-part-and-strip) (gnus-mime-delete-part, gnus-mime-save-part, gnus-mime-pipe-part) (gnus-mime-view-part, gnus-mime-view-part-as-type) (gnus-mime-copy-part, gnus-mime-print-part, gnus-mime-inline-part) (gnus-mime-view-part-as-charset, gnus-mime-view-part-externally) (gnus-mime-view-part-internally, gnus-article-press-button): Add `event` arg and operate at its position. diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index 588e75384a..6a66dc6542 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -2707,7 +2707,7 @@ If READ-CHARSET, ask for a coding system." "Format an HTML article." (interactive) (let ((handles nil) - (buffer-read-only nil)) + (inhibit-read-only t)) (when (gnus-buffer-live-p gnus-original-article-buffer) (with-current-buffer gnus-original-article-buffer (setq handles (mm-dissect-buffer t t)))) @@ -5074,50 +5074,53 @@ and `gnus-mime-delete-part', and not provided at run-time normally." file)) (gnus-mime-save-part-and-strip file)) -(defun gnus-mime-save-part-and-strip (&optional file) +(defun gnus-mime-save-part-and-strip (&optional file event) "Save the MIME part under point then replace it with an external body. If FILE is given, use it for the external part." - (interactive) - (gnus-article-check-buffer) - (when (gnus-group-read-only-p) - (error "The current group does not support deleting of parts")) - (when (mm-complicated-handles gnus-article-mime-handles) - (error "\ + (interactive (list nil last-nonmenu-event)) + (save-excursion + (mouse-set-point event) + (gnus-article-check-buffer) + (when (gnus-group-read-only-p) + (error "The current group does not support deleting of parts")) + (when (mm-complicated-handles gnus-article-mime-handles) + (error "\ The current article has a complicated MIME structure, giving up...")) - (let* ((data (get-text-property (point) 'gnus-data)) - (id (get-text-property (point) 'gnus-part)) - (handles gnus-article-mime-handles)) - (unless file - (setq file - (and data (mm-save-part data "Delete MIME part and save to: ")))) - (when file - (with-current-buffer (mm-handle-buffer data) - (erase-buffer) - (insert "Content-Type: " (mm-handle-media-type data)) - (mml-insert-parameter-string (cdr (mm-handle-type data)) - '(charset)) - ;; Add a filename for the sake of saving the part again. - (mml-insert-parameter - (mail-header-encode-parameter "name" (file-name-nondirectory file))) - (insert "\n") - (insert "Content-ID: " (message-make-message-id) "\n") - (insert "Content-Transfer-Encoding: binary\n") - (insert "\n")) - (setcdr data - (cdr (mm-make-handle nil - `("message/external-body" - (access-type . "LOCAL-FILE") - (name . ,file))))) - ;; (set-buffer gnus-summary-buffer) - (gnus-article-edit-part handles id)))) + (let* ((data (get-text-property (point) 'gnus-data)) + (id (get-text-property (point) 'gnus-part)) + (handles gnus-article-mime-handles)) + (unless file + (setq file + (and data (mm-save-part data "Delete MIME part and save to: ")))) + (when file + (with-current-buffer (mm-handle-buffer data) + (erase-buffer) + (insert "Content-Type: " (mm-handle-media-type data)) + (mml-insert-parameter-string (cdr (mm-handle-type data)) + '(charset)) + ;; Add a filename for the sake of saving the part again. + (mml-insert-parameter + (mail-header-encode-parameter "name" (file-name-nondirectory file))) + (insert "\n") + (insert "Content-ID: " (message-make-message-id) "\n") + (insert "Content-Transfer-Encoding: binary\n") + (insert "\n")) + (setcdr data + (cdr (mm-make-handle nil + `("message/external-body" + (access-type . "LOCAL-FILE") + (name . ,file))))) + ;; (set-buffer gnus-summary-buffer) + (gnus-article-edit-part handles id))))) ;; A function like `gnus-summary-save-parts' (`X m', ` ') but with stripping would be nice. -(defun gnus-mime-delete-part () +(defun gnus-mime-delete-part (&optional event) "Delete the MIME part under point. Replace it with some information about the removed part." - (interactive) + (interactive (list last-nonmenu-event)) + (mouse-set-point event) (gnus-article-check-buffer) (when (gnus-group-read-only-p) (error "The current group does not support deleting of parts")) @@ -5163,33 +5166,37 @@ Deleting parts may malfunction or destroy the article; continue? ")) ;; (set-buffer gnus-summary-buffer) (gnus-article-edit-part handles id)))) -(defun gnus-mime-save-part () +(defun gnus-mime-save-part (&optional event) "Save the MIME part under point." - (interactive) + (interactive (list last-nonmenu-event)) + (mouse-set-point event) (gnus-article-check-buffer) (let ((data (get-text-property (point) 'gnus-data))) (when data (mm-save-part data)))) -(defun gnus-mime-pipe-part (&optional cmd) +(defun gnus-mime-pipe-part (&optional cmd event) "Pipe the MIME part under point to a process. Use CMD as the process." - (interactive) + (interactive (list nil last-nonmenu-event)) + (mouse-set-point event) (gnus-article-check-buffer) (let ((data (get-text-property (point) 'gnus-data))) (when data (mm-pipe-part data cmd)))) -(defun gnus-mime-view-part () +(defun gnus-mime-view-part (&optional event) "Interactively choose a viewing method for the MIME part under point." - (interactive) - (gnus-article-check-buffer) - (let ((data (get-text-property (point) 'gnus-data))) - (when data - (setq gnus-article-mime-handles - (mm-merge-handles - gnus-article-mime-handles (setq data (copy-sequence data)))) - (mm-interactively-view-part data)))) + (interactive (list last-nonmenu-event)) + (save-excursion + (mouse-set-point event) + (gnus-article-check-buffer) + (let ((data (get-text-property (point) 'gnus-data))) + (when data + (setq gnus-article-mime-handles + (mm-merge-handles + gnus-article-mime-handles (setq data (copy-sequence data)))) + (mm-interactively-view-part data))))) (defun gnus-mime-view-part-as-type-internal () (gnus-article-check-buffer) @@ -5206,48 +5213,51 @@ Use CMD as the process." '("text/plain" . 0)) '("application/octet-stream" . 0)))) -(defun gnus-mime-view-part-as-type (&optional mime-type pred) +(defun gnus-mime-view-part-as-type (&optional mime-type pred event) "Choose a MIME media type, and view the part as such. If non-nil, PRED is a predicate to use during completion to limit the available media-types." - (interactive) - (unless mime-type - (setq mime-type - (let ((default (gnus-mime-view-part-as-type-internal))) - (gnus-completing-read - "View as MIME type" - (if pred - (seq-filter pred (mailcap-mime-types)) - (mailcap-mime-types)) - nil nil nil - (car default))))) - (gnus-article-check-buffer) - (let ((handle (get-text-property (point) 'gnus-data))) - (when handle - (when (equal (mm-handle-media-type handle) "message/external-body") - (unless (mm-handle-cache handle) - (mm-extern-cache-contents handle)) - (setq handle (mm-handle-cache handle))) - (setq handle - (mm-make-handle (mm-handle-buffer handle) - (cons mime-type (cdr (mm-handle-type handle))) - (mm-handle-encoding handle) - (mm-handle-undisplayer handle) - (mm-handle-disposition handle) - (mm-handle-description handle) - nil - (mm-handle-id handle))) - (setq gnus-article-mime-handles - (mm-merge-handles gnus-article-mime-handles handle)) - (when (mm-handle-displayed-p handle) - (mm-remove-part handle)) - (gnus-mm-display-part handle)))) - -(defun gnus-mime-copy-part (&optional handle arg) + (interactive (list nil nil last-nonmenu-event)) + (save-excursion + (if event (mouse-set-point event)) + (unless mime-type + (setq mime-type + (let ((default (gnus-mime-view-part-as-type-internal))) + (gnus-completing-read + "View as MIME type" + (if pred + (seq-filter pred (mailcap-mime-types)) + (mailcap-mime-types)) + nil nil nil + (car default))))) + (gnus-article-check-buffer) + (let ((handle (get-text-property (point) 'gnus-data))) + (when handle + (when (equal (mm-handle-media-type handle) "message/external-body") + (unless (mm-handle-cache handle) + (mm-extern-cache-contents handle)) + (setq handle (mm-handle-cache handle))) + (setq handle + (mm-make-handle (mm-handle-buffer handle) + (cons mime-type (cdr (mm-handle-type handle))) + (mm-handle-encoding handle) + (mm-handle-undisplayer handle) + (mm-handle-disposition handle) + (mm-handle-description handle) + nil + (mm-handle-id handle))) + (setq gnus-article-mime-handles + (mm-merge-handles gnus-article-mime-handles handle)) + (when (mm-handle-displayed-p handle) + (mm-remove-part handle)) + (gnus-mm-display-part handle))))) + +(defun gnus-mime-copy-part (&optional handle arg event) "Put the MIME part under point into a new buffer. If `auto-compression-mode' is enabled, compressed files like .gz and .bz2 are decompressed." - (interactive (list nil current-prefix-arg)) + (interactive (list nil current-prefix-arg last-nonmenu-event)) + (mouse-set-point event) (gnus-article-check-buffer) (unless handle (setq handle (get-text-property (point) 'gnus-data))) @@ -5299,15 +5309,18 @@ are decompressed." (setq buffer-file-name nil)) (goto-char (point-min))))) -(defun gnus-mime-print-part (&optional handle filename) +(defun gnus-mime-print-part (&optional handle filename event) "Print the MIME part under point." - (interactive (list nil (ps-print-preprint current-prefix-arg))) - (gnus-article-check-buffer) - (let* ((handle (or handle (get-text-property (point) 'gnus-data))) - (contents (and handle (mm-get-part handle))) - (file (make-temp-file (expand-file-name "mm." mm-tmp-directory))) - (printer (mailcap-mime-info (mm-handle-media-type handle) "print"))) - (when contents + (interactive + (list nil (ps-print-preprint current-prefix-arg) last-nonmenu-event)) + (save-excursion + (mouse-set-point event) + (gnus-article-check-buffer) + (let* ((handle (or handle (get-text-property (point) 'gnus-data))) + (contents (and handle (mm-get-part handle))) + (file (make-temp-file (expand-file-name "mm." mm-tmp-directory))) + (printer (mailcap-mime-info (mm-handle-media-type handle) "print"))) + (when contents (if printer (unwind-protect (progn @@ -5322,12 +5335,13 @@ are decompressed." (with-temp-buffer (insert contents) (gnus-print-buffer)) - (ps-despool filename))))) + (ps-despool filename)))))) -(defun gnus-mime-inline-part (&optional handle arg) +(defun gnus-mime-inline-part (&optional handle arg event) "Insert the MIME part under point into the current buffer. Compressed files like .gz and .bz2 are decompressed." - (interactive (list nil current-prefix-arg)) + (interactive (list nil current-prefix-arg last-nonmenu-event)) + (if event (mouse-set-point event)) (gnus-article-check-buffer) (let* ((inhibit-read-only t) (b (point)) @@ -5421,82 +5435,88 @@ CHARSET may either be a string or a symbol." (setcdr param charset) (setcdr type (cons (cons 'charset charset) (cdr type))))))) -(defun gnus-mime-view-part-as-charset (&optional handle arg) +(defun gnus-mime-view-part-as-charset (&optional handle arg event) "Insert the MIME part under point into the current buffer using the specified charset." - (interactive (list nil current-prefix-arg)) - (gnus-article-check-buffer) - (let ((handle (or handle (get-text-property (point) 'gnus-data))) - (fun (get-text-property (point) 'gnus-callback)) - (gnus-newsgroup-ignored-charsets 'gnus-all) - charset form preferred parts) - (when handle - (when (prog1 - (and fun - (setq charset - (or (cdr (assq - arg - gnus-summary-show-article-charset-alist)) - (read-coding-system "Charset: ")))) - (if (mm-handle-undisplayer handle) - (mm-remove-part handle))) - (gnus-mime-set-charset-parameters handle charset) - (when (and (consp (setq form (cdr-safe fun))) - (setq form (ignore-errors - (assq 'gnus-mime-display-alternative form))) - (setq preferred (caddr form)) - (progn - (when (eq (car preferred) 'quote) - (setq preferred (cadr preferred))) - (not (equal preferred - (get-text-property (point) 'gnus-data)))) - (setq parts (get-text-property (point) 'gnus-part)) - (setq parts (cdr (assq parts - gnus-article-mime-handle-alist))) - (equal (mm-handle-media-type parts) "multipart/alternative") - (setq parts (reverse (cdr parts)))) - (setcar (cddr form) - (list 'quote (or (cadr (member preferred parts)) - (car parts))))) - (funcall fun handle))))) - -(defun gnus-mime-view-part-externally (&optional handle) - "View the MIME part under point with an external viewer." - (interactive) - (gnus-article-check-buffer) - (let* ((handle (or handle (get-text-property (point) 'gnus-data))) - (mm-inlined-types nil) - (mail-parse-charset gnus-newsgroup-charset) - (mail-parse-ignored-charsets - (with-current-buffer gnus-summary-buffer - gnus-newsgroup-ignored-charsets)) - (type (mm-handle-media-type handle)) - (method (mailcap-mime-info type)) - (mm-enable-external t)) - (if (not (stringp method)) - (gnus-mime-view-part-as-type - nil (lambda (type) (stringp (mailcap-mime-info type)))) + (interactive (list nil current-prefix-arg last-nonmenu-event)) + (save-excursion + (mouse-set-point event) + (gnus-article-check-buffer) + (let ((handle (or handle (get-text-property (point) 'gnus-data))) + (fun (get-text-property (point) 'gnus-callback)) + (gnus-newsgroup-ignored-charsets 'gnus-all) + charset form preferred parts) (when handle - (mm-display-part handle nil t))))) - -(defun gnus-mime-view-part-internally (&optional handle) + (when (prog1 + (and fun + (setq charset + (or (cdr (assq + arg + gnus-summary-show-article-charset-alist)) + (read-coding-system "Charset: ")))) + (if (mm-handle-undisplayer handle) + (mm-remove-part handle))) + (gnus-mime-set-charset-parameters handle charset) + (when (and (consp (setq form (cdr-safe fun))) + (setq form (ignore-errors + (assq 'gnus-mime-display-alternative form))) + (setq preferred (caddr form)) + (progn + (when (eq (car preferred) 'quote) + (setq preferred (cadr preferred))) + (not (equal preferred + (get-text-property (point) 'gnus-data)))) + (setq parts (get-text-property (point) 'gnus-part)) + (setq parts (cdr (assq parts + gnus-article-mime-handle-alist))) + (equal (mm-handle-media-type parts) "multipart/alternative") + (setq parts (reverse (cdr parts)))) + (setcar (cddr form) + (list 'quote (or (cadr (member preferred parts)) + (car parts))))) + (funcall fun handle)))))) + +(defun gnus-mime-view-part-externally (&optional handle event) + "View the MIME part under point with an external viewer." + (interactive (list nil last-nonmenu-event)) + (save-excursion + (mouse-set-point event) + (gnus-article-check-buffer) + (let* ((handle (or handle (get-text-property (point) 'gnus-data))) + (mm-inlined-types nil) + (mail-parse-charset gnus-newsgroup-charset) + (mail-parse-ignored-charsets + (with-current-buffer gnus-summary-buffer + gnus-newsgroup-ignored-charsets)) + (type (mm-handle-media-type handle)) + (method (mailcap-mime-info type)) + (mm-enable-external t)) + (if (not (stringp method)) + (gnus-mime-view-part-as-type + nil (lambda (type) (stringp (mailcap-mime-info type)))) + (when handle + (mm-display-part handle nil t)))))) + +(defun gnus-mime-view-part-internally (&optional handle event) "View the MIME part under point with an internal viewer. If no internal viewer is available, use an external viewer." - (interactive) - (gnus-article-check-buffer) - (let* ((handle (or handle (get-text-property (point) 'gnus-data))) - (mm-inlined-types '(".*")) - (mm-inline-large-images t) - (mail-parse-charset gnus-newsgroup-charset) - (mail-parse-ignored-charsets - (with-current-buffer gnus-summary-buffer - gnus-newsgroup-ignored-charsets)) - (inhibit-read-only t)) - (if (not (mm-inlinable-p handle)) - (gnus-mime-view-part-as-type - nil (lambda (type) (mm-inlinable-p handle type))) - (when handle - (gnus-bind-mm-vars (mm-display-part handle nil t)))))) + (interactive (list nil last-nonmenu-event)) + (save-excursion + (mouse-set-point event) + (gnus-article-check-buffer) + (let* ((handle (or handle (get-text-property (point) 'gnus-data))) + (mm-inlined-types '(".*")) + (mm-inline-large-images t) + (mail-parse-charset gnus-newsgroup-charset) + (mail-parse-ignored-charsets + (with-current-buffer gnus-summary-buffer + gnus-newsgroup-ignored-charsets)) + (inhibit-read-only t)) + (if (not (mm-inlinable-p handle)) + (gnus-mime-view-part-as-type + nil (lambda (type) (mm-inlinable-p handle type))) + (when handle + (gnus-bind-mm-vars (mm-display-part handle nil t))))))) (defun gnus-mime-action-on-part (&optional action) "Do something with the MIME attachment at (point)." @@ -7866,15 +7886,16 @@ call it with the value of the `gnus-data' text property." (when fun (funcall fun data)))) -(defun gnus-article-press-button () +(defun gnus-article-press-button (&optional event) "Check text at point for a callback function. If the text at point has a `gnus-callback' property, call it with the value of the `gnus-data' text property." - (interactive) - (let ((data (get-text-property (point) 'gnus-data)) - (fun (get-text-property (point) 'gnus-callback))) - (when fun - (funcall fun data)))) + (interactive (list last-nonmenu-event)) + (save-excursion + (mouse-set-point event) + (let ((fun (get-text-property (point) 'gnus-callback))) + (when fun + (funcall fun (get-text-property (point) 'gnus-data)))))) (defun gnus-article-highlight (&optional force) "Highlight current article. commit 5577d441e518a36509af4302edd3ac957da14b3b Author: Stefan Monnier Date: Fri Jan 29 23:40:48 2021 -0500 * lisp/gnus: Use `declare`. * lisp/gnus/nnoo.el (defvoo, deffoo, nnoo-declare, nnoo-import) (nnoo-map-functions): * lisp/gnus/nnmaildir.el (nnmaildir--with-nntp-buffer) (nnmaildir--with-work-buffer, nnmaildir--with-nov-buffer) (nnmaildir--with-move-buffer, nnmaildir--condcase): * lisp/gnus/mm-decode.el (mm-with-part): * lisp/gnus/gnus-msg.el (gnus-setup-message): * lisp/gnus/gnus-agent.el (gnus-agent-with-fetch, gnus-agent-while-plugged): * lisp/gnus/mail-source.el (mail-source-set-1, mail-source-value): Use `declare`. * lisp/gnus/gnus-util.el (gnus-define-keys): Use `declare`, and also don't quote `keymap` if it's a variable name. (gnus-define-keys-1): Reject the case where `keymap` is a variable name. (gnus-eval-in-buffer-window, gnus-define-keys-safe) (gnus-define-keymap, gnus-atomic-progn, gnus-with-output-to-file) (gnus-parse-without-error): Use `declare`. (gnus-atomic-progn-assign, gnus-atomic-setq): Delete macros. * lisp/gnus/gnus-undo.el (gnus-undo-register): Drop indent and edebug spec since they're not really appropriate for a function. * lisp/gnus/gnus-art.el (gnus--\,@): New macro. Use it at top-level to construct the `gnus-article-FOO` => `article-FOO` wrapper functions. (gnus-with-article-headers, gnus-with-article-buffer): Use `declare`. diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el index 56640ea830..46a4af8214 100644 --- a/lisp/gnus/gnus-agent.el +++ b/lisp/gnus/gnus-agent.el @@ -422,15 +422,13 @@ manipulated as follows: (defmacro gnus-agent-with-fetch (&rest forms) "Do FORMS safely." + (declare (indent 0) (debug t)) `(unwind-protect (let ((gnus-agent-fetching t)) (gnus-agent-start-fetch) ,@forms) (gnus-agent-stop-fetch))) -(put 'gnus-agent-with-fetch 'lisp-indent-function 0) -(put 'gnus-agent-with-fetch 'edebug-form-spec '(body)) - (defmacro gnus-agent-append-to-list (tail value) `(setq ,tail (setcdr ,tail (cons ,value nil)))) @@ -573,14 +571,12 @@ manipulated as follows: (set-buffer-modified-p t)) (defmacro gnus-agent-while-plugged (&rest body) + (declare (indent 0) (debug t)) `(let ((original-gnus-plugged gnus-plugged)) - (unwind-protect - (progn (gnus-agent-toggle-plugged t) - ,@body) - (gnus-agent-toggle-plugged original-gnus-plugged)))) - -(put 'gnus-agent-while-plugged 'lisp-indent-function 0) -(put 'gnus-agent-while-plugged 'edebug-form-spec '(body)) + (unwind-protect + (progn (gnus-agent-toggle-plugged t) + ,@body) + (gnus-agent-toggle-plugged original-gnus-plugged)))) (defun gnus-agent-close-connections () "Close all methods covered by the Gnus agent." diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index 4ade36f4b9..588e75384a 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -1738,6 +1738,7 @@ Initialized from `text-mode-syntax-table'.") ;;; Macros for dealing with the article buffer. (defmacro gnus-with-article-headers (&rest forms) + (declare (indent 0) (debug t)) `(with-current-buffer gnus-article-buffer (save-restriction (let ((inhibit-read-only t) @@ -1746,18 +1747,13 @@ Initialized from `text-mode-syntax-table'.") (article-narrow-to-head) ,@forms)))) -(put 'gnus-with-article-headers 'lisp-indent-function 0) -(put 'gnus-with-article-headers 'edebug-form-spec '(body)) - (defmacro gnus-with-article-buffer (&rest forms) + (declare (indent 0) (debug t)) `(when (buffer-live-p (get-buffer gnus-article-buffer)) (with-current-buffer gnus-article-buffer (let ((inhibit-read-only t)) ,@forms)))) -(put 'gnus-with-article-buffer 'lisp-indent-function 0) -(put 'gnus-with-article-buffer 'edebug-form-spec '(body)) - (defun gnus-article-goto-header (header) "Go to HEADER, which is a regular expression." (re-search-forward (concat "^\\(" header "\\):") nil t)) @@ -4326,74 +4322,69 @@ If variable `gnus-use-long-file-name' is non-nil, it is (if (gnus-buffer-live-p gnus-original-article-buffer) (canlock-verify gnus-original-article-buffer))) -(eval-and-compile - (mapc - (lambda (func) - (let (afunc gfunc) - (if (consp func) - (setq afunc (car func) - gfunc (cdr func)) - (setq afunc func - gfunc (intern (format "gnus-%s" func)))) - (defalias gfunc - (when (fboundp afunc) - `(lambda (&optional interactive &rest args) - ,(documentation afunc t) - (interactive (list t)) - (with-current-buffer gnus-article-buffer - (if interactive - (call-interactively ',afunc) - (apply #',afunc args)))))))) - '(article-hide-headers - article-verify-x-pgp-sig - article-verify-cancel-lock - article-hide-boring-headers - article-treat-overstrike - article-treat-ansi-sequences - article-fill-long-lines - article-capitalize-sentences - article-remove-cr - article-remove-leading-whitespace - article-display-x-face - article-display-face - article-de-quoted-unreadable - article-de-base64-unreadable - article-decode-HZ - article-wash-html - article-unsplit-urls - article-hide-list-identifiers - article-strip-banner - article-babel - article-hide-pem - article-hide-signature - article-strip-headers-in-body - article-remove-trailing-blank-lines - article-strip-leading-blank-lines - article-strip-multiple-blank-lines - article-strip-leading-space - article-strip-trailing-space - article-strip-blank-lines - article-strip-all-blank-lines - article-date-local - article-date-english - article-date-iso8601 - article-date-original - article-treat-date - article-date-ut - article-decode-mime-words - article-decode-charset - article-decode-encoded-words - article-date-user - article-date-lapsed - article-date-combined-lapsed - article-emphasize - article-treat-smartquotes - ;; Obsolete alias. - article-treat-dumbquotes - article-treat-non-ascii - article-normalize-headers))) +(defmacro gnus--\,@ (exp) + (declare (debug t)) + `(progn ,@(eval exp t))) + +(gnus--\,@ + (mapcar (lambda (func) + `(defun ,(intern (format "gnus-%s" func)) + (&optional interactive &rest args) + ,(format "Run `%s' in the article buffer." func) + (interactive (list t)) + (with-current-buffer gnus-article-buffer + (if interactive + (call-interactively #',func) + (apply #',func args))))) + '(article-hide-headers + article-verify-x-pgp-sig + article-verify-cancel-lock + article-hide-boring-headers + article-treat-overstrike + article-treat-ansi-sequences + article-fill-long-lines + article-capitalize-sentences + article-remove-cr + article-remove-leading-whitespace + article-display-x-face + article-display-face + article-de-quoted-unreadable + article-de-base64-unreadable + article-decode-HZ + article-wash-html + article-unsplit-urls + article-hide-list-identifiers + article-strip-banner + article-babel + article-hide-pem + article-hide-signature + article-strip-headers-in-body + article-remove-trailing-blank-lines + article-strip-leading-blank-lines + article-strip-multiple-blank-lines + article-strip-leading-space + article-strip-trailing-space + article-strip-blank-lines + article-strip-all-blank-lines + article-date-local + article-date-english + article-date-iso8601 + article-date-original + article-treat-date + article-date-ut + article-decode-mime-words + article-decode-charset + article-decode-encoded-words + article-date-user + article-date-lapsed + article-date-combined-lapsed + article-emphasize + article-treat-smartquotes + ;;article-treat-dumbquotes ;; Obsolete alias. + article-treat-non-ascii + article-normalize-headers))) (define-obsolete-function-alias 'gnus-article-treat-dumbquotes - 'gnus-article-treat-smartquotes "27.1") + #'gnus-article-treat-smartquotes "27.1") ;;; ;;; Gnus article mode diff --git a/lisp/gnus/gnus-msg.el b/lisp/gnus/gnus-msg.el index 419b5ead56..836cc959c5 100644 --- a/lisp/gnus/gnus-msg.el +++ b/lisp/gnus/gnus-msg.el @@ -399,6 +399,7 @@ only affect the Gcc copy, but not the original message." (defvar gnus-article-reply nil) (defmacro gnus-setup-message (config &rest forms) + (declare (indent 1) (debug t)) (let ((winconf (make-symbol "gnus-setup-message-winconf")) (winconf-name (make-symbol "gnus-setup-message-winconf-name")) (buffer (make-symbol "gnus-setup-message-buffer")) @@ -473,8 +474,8 @@ only affect the Gcc copy, but not the original message." (let ((mbl1 mml-buffer-list)) (setq mml-buffer-list mbl) ;; Global value (setq-local mml-buffer-list mbl1) ;; Local value - (add-hook 'change-major-mode-hook 'mml-destroy-buffers nil t) - (add-hook 'kill-buffer-hook 'mml-destroy-buffers t t)) + (add-hook 'change-major-mode-hook #'mml-destroy-buffers nil t) + (add-hook 'kill-buffer-hook #'mml-destroy-buffers t t)) (mml-destroy-buffers) (setq mml-buffer-list mbl))) (message-hide-headers) @@ -596,9 +597,6 @@ instead." `(gnus-summary-mark-article-as-replied ',to-be-marked))))) 'send))) -(put 'gnus-setup-message 'lisp-indent-function 1) -(put 'gnus-setup-message 'edebug-form-spec '(form body)) - ;;; Post news commands of Gnus group mode and summary mode (defun gnus-group-mail (&optional arg) diff --git a/lisp/gnus/gnus-undo.el b/lisp/gnus/gnus-undo.el index b1c1fb832f..5e72effa6c 100644 --- a/lisp/gnus/gnus-undo.el +++ b/lisp/gnus/gnus-undo.el @@ -52,8 +52,7 @@ (defcustom gnus-undo-limit 2000 "The number of undoable actions recorded." - :type 'integer - :group 'gnus-undo) + :type 'integer) (defcustom gnus-undo-mode nil ;; FIXME: This is a buffer-local minor mode which requires running @@ -61,13 +60,11 @@ ;; doesn't seem very useful: setting it to non-nil via Customize ;; probably won't do the right thing. "Minor mode for undoing in Gnus buffers." - :type 'boolean - :group 'gnus-undo) + :type 'boolean) (defcustom gnus-undo-mode-hook nil "Hook called in all `gnus-undo-mode' buffers." - :type 'hook - :group 'gnus-undo) + :type 'hook) ;;; Internal variables. @@ -130,15 +127,10 @@ gnus-undo-boundary t)) (defun gnus-undo-register (form) - "Register FORMS as something to be performed to undo a change. -FORMS may use backtick quote syntax." + "Register FORMS as something to be performed to undo a change." (when gnus-undo-mode (gnus-undo-register-1 - `(lambda () - ,form)))) - -(put 'gnus-undo-register 'lisp-indent-function 0) -(put 'gnus-undo-register 'edebug-form-spec '(body)) + `(lambda () ,form)))) (defun gnus-undo-register-1 (function) "Register FUNCTION as something to be performed to undo a change." diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el index de3c854ca5..82c8731b47 100644 --- a/lisp/gnus/gnus-util.el +++ b/lisp/gnus/gnus-util.el @@ -87,6 +87,7 @@ This is a compatibility function for different Emacsen." (defmacro gnus-eval-in-buffer-window (buffer &rest forms) "Pop to BUFFER, evaluate FORMS, and then return to the original window." + (declare (indent 1) (debug t)) (let ((tempvar (make-symbol "GnusStartBufferWindow")) (w (make-symbol "w")) (buf (make-symbol "buf"))) @@ -103,9 +104,6 @@ This is a compatibility function for different Emacsen." ,@forms) (select-window ,tempvar))))) -(put 'gnus-eval-in-buffer-window 'lisp-indent-function 1) -(put 'gnus-eval-in-buffer-window 'edebug-form-spec '(form body)) - (defsubst gnus-goto-char (point) (and point (goto-char point))) @@ -302,31 +300,28 @@ Symbols are also allowed; their print names are used instead." (defmacro gnus-local-set-keys (&rest plist) "Set the keys in PLIST in the current keymap." + (declare (indent 1)) `(gnus-define-keys-1 (current-local-map) ',plist)) (defmacro gnus-define-keys (keymap &rest plist) "Define all keys in PLIST in KEYMAP." - `(gnus-define-keys-1 (quote ,keymap) (quote ,plist))) + (declare (indent 1)) + `(gnus-define-keys-1 ,(if (symbolp keymap) keymap `',keymap) (quote ,plist))) (defmacro gnus-define-keys-safe (keymap &rest plist) "Define all keys in PLIST in KEYMAP without overwriting previous definitions." + (declare (indent 1)) `(gnus-define-keys-1 (quote ,keymap) (quote ,plist) t)) -(put 'gnus-define-keys 'lisp-indent-function 1) -(put 'gnus-define-keys-safe 'lisp-indent-function 1) -(put 'gnus-local-set-keys 'lisp-indent-function 1) - (defmacro gnus-define-keymap (keymap &rest plist) "Define all keys in PLIST in KEYMAP." + (declare (indent 1)) `(gnus-define-keys-1 ,keymap (quote ,plist))) -(put 'gnus-define-keymap 'lisp-indent-function 1) - (defun gnus-define-keys-1 (keymap plist &optional safe) (when (null keymap) (error "Can't set keys in a null keymap")) - (cond ((symbolp keymap) - (setq keymap (symbol-value keymap))) + (cond ((symbolp keymap) (error "First arg should be a keymap object")) ((keymapp keymap)) ((listp keymap) (set (car keymap) nil) @@ -856,64 +851,10 @@ the user are disabled, it is recommended that only the most minimal operations are performed by FORMS. If you wish to assign many complicated values atomically, compute the results into temporary variables and then do only the assignment atomically." + (declare (indent 0) (debug t)) `(let ((inhibit-quit gnus-atomic-be-safe)) ,@forms)) -(put 'gnus-atomic-progn 'lisp-indent-function 0) - -(defmacro gnus-atomic-progn-assign (protect &rest forms) - "Evaluate FORMS, but ensure that the variables listed in PROTECT -are not changed if anything in FORMS signals an error or otherwise -non-locally exits. The variables listed in PROTECT are updated atomically. -It is safe to use gnus-atomic-progn-assign with long computations. - -Note that if any of the symbols in PROTECT were unbound, they will be -set to nil on a successful assignment. In case of an error or other -non-local exit, it will still be unbound." - (let* ((temp-sym-map (mapcar (lambda (x) (list (make-symbol - (concat (symbol-name x) - "-tmp")) - x)) - protect)) - (sym-temp-map (mapcar (lambda (x) (list (cadr x) (car x))) - temp-sym-map)) - (temp-sym-let (mapcar (lambda (x) (list (car x) - `(and (boundp ',(cadr x)) - ,(cadr x)))) - temp-sym-map)) - (sym-temp-let sym-temp-map) - (temp-sym-assign (apply 'append temp-sym-map)) - (sym-temp-assign (apply 'append sym-temp-map)) - (result (make-symbol "result-tmp"))) - `(let (,@temp-sym-let - ,result) - (let ,sym-temp-let - (setq ,result (progn ,@forms)) - (setq ,@temp-sym-assign)) - (let ((inhibit-quit gnus-atomic-be-safe)) - (setq ,@sym-temp-assign)) - ,result))) - -(put 'gnus-atomic-progn-assign 'lisp-indent-function 1) -;(put 'gnus-atomic-progn-assign 'edebug-form-spec '(sexp body)) - -(defmacro gnus-atomic-setq (&rest pairs) - "Similar to setq, except that the real symbols are only assigned when -there are no errors. And when the real symbols are assigned, they are -done so atomically. If other variables might be changed via side-effect, -see gnus-atomic-progn-assign. It is safe to use gnus-atomic-setq -with potentially long computations." - (let ((tpairs pairs) - syms) - (while tpairs - (push (car tpairs) syms) - (setq tpairs (cddr tpairs))) - `(gnus-atomic-progn-assign ,syms - (setq ,@pairs)))) - -;(put 'gnus-atomic-setq 'edebug-form-spec '(body)) - - ;;; Functions for saving to babyl/mail files. (require 'rmail) @@ -1197,6 +1138,7 @@ ARG is passed to the first function." ;; Fixme: Why not use `with-output-to-temp-buffer'? (defmacro gnus-with-output-to-file (file &rest body) + (declare (indent 1) (debug t)) (let ((buffer (make-symbol "output-buffer")) (size (make-symbol "output-buffer-size")) (leng (make-symbol "output-buffer-length")) @@ -1219,9 +1161,6 @@ ARG is passed to the first function." (write-region (substring ,buffer 0 ,leng) nil ,file ,append 'no-msg)))))) -(put 'gnus-with-output-to-file 'lisp-indent-function 1) -(put 'gnus-with-output-to-file 'edebug-form-spec '(form body)) - (defun gnus-add-text-properties-when (property value start end properties &optional object) "Like `add-text-properties', only applied on where PROPERTY is VALUE." @@ -1358,7 +1297,7 @@ REJECT-NEWLINES is nil, remove them; otherwise raise an error. If LINE-LENGTH is set and the string (or any line in the string if REJECT-NEWLINES is nil) is longer than that number, raise an error. Common line length for input characters are 76 plus CRLF -(RFC 2045 MIME), 64 plus CRLF (RFC 1421 PEM), and 1000 including +\(RFC 2045 MIME), 64 plus CRLF (RFC 1421 PEM), and 1000 including CRLF (RFC 5321 SMTP). If NOCHECK, don't check anything, but just repad." @@ -1468,16 +1407,14 @@ SPEC is a predicate specifier that contains stuff like `or', `and', (unwind-protect (progn (or iswitchb-mode - (add-hook 'minibuffer-setup-hook 'iswitchb-minibuffer-setup)) + (add-hook 'minibuffer-setup-hook #'iswitchb-minibuffer-setup)) (iswitchb-read-buffer prompt def require-match)) (or iswitchb-mode - (remove-hook 'minibuffer-setup-hook 'iswitchb-minibuffer-setup))))) - -(put 'gnus-parse-without-error 'lisp-indent-function 0) -(put 'gnus-parse-without-error 'edebug-form-spec '(body)) + (remove-hook 'minibuffer-setup-hook #'iswitchb-minibuffer-setup))))) (defmacro gnus-parse-without-error (&rest body) "Allow continuing onto the next line even if an error occurs." + (declare (indent 0) (debug t)) `(while (not (eobp)) (condition-case () (progn diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el index 52470196f6..91671016a8 100644 --- a/lisp/gnus/mail-source.el +++ b/lisp/gnus/mail-source.el @@ -418,12 +418,11 @@ of the second `let' form. The variables bound and their default values are described by the `mail-source-keyword-map' variable." + (declare (indent 1) (debug (sexp body))) `(let* ,(mail-source-bind-1 (car type-source)) (mail-source-set-1 ,(cadr type-source)) ,@body)) -(put 'mail-source-bind 'lisp-indent-function 1) -(put 'mail-source-bind 'edebug-form-spec '(sexp body)) (defun mail-source-set-1 (source) (let* ((type (pop source)) @@ -512,13 +511,11 @@ the `mail-source-keyword-map' variable." (defmacro mail-source-bind-common (source &rest body) "Return a `let' form that binds all common variables. See `mail-source-bind'." + (declare (indent 1) (debug (sexp body))) `(let ,(mail-source-bind-common-1) (mail-source-set-common-1 source) ,@body)) -(put 'mail-source-bind-common 'lisp-indent-function 1) -(put 'mail-source-bind-common 'edebug-form-spec '(sexp body)) - (defun mail-source-value (value) "Return the value of VALUE." (cond diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el index 61946aa581..a62e954af3 100644 --- a/lisp/gnus/mm-decode.el +++ b/lisp/gnus/mm-decode.el @@ -1255,6 +1255,7 @@ in HANDLE." (defmacro mm-with-part (handle &rest forms) "Run FORMS in the temp buffer containing the contents of HANDLE." + (declare (indent 1) (debug t)) ;; The handle-buffer's content is a sequence of bytes, not a sequence of ;; chars, so the buffer should be unibyte. It may happen that the ;; handle-buffer is multibyte for some reason, in which case now is a good @@ -1270,8 +1271,6 @@ in HANDLE." (mm-handle-encoding handle) (mm-handle-media-type handle)) ,@forms)))) -(put 'mm-with-part 'lisp-indent-function 1) -(put 'mm-with-part 'edebug-form-spec '(body)) (defun mm-get-part (handle &optional no-cache) "Return the contents of HANDLE as a string. diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el index 2a4c74db5e..4179a2cc63 100644 --- a/lisp/gnus/nnmaildir.el +++ b/lisp/gnus/nnmaildir.el @@ -48,16 +48,6 @@ ;;; Code: -;; eval this before editing -[(progn - (put 'nnmaildir--with-nntp-buffer 'lisp-indent-function 0) - (put 'nnmaildir--with-work-buffer 'lisp-indent-function 0) - (put 'nnmaildir--with-nov-buffer 'lisp-indent-function 0) - (put 'nnmaildir--with-move-buffer 'lisp-indent-function 0) - (put 'nnmaildir--condcase 'lisp-indent-function 2) - ) -] - (require 'nnheader) (require 'gnus) (require 'gnus-util) @@ -264,19 +254,19 @@ This variable is set by `nnmaildir-request-article'.") (eval param t)) (defmacro nnmaildir--with-nntp-buffer (&rest body) - (declare (debug (body))) + (declare (indent 0) (debug t)) `(with-current-buffer nntp-server-buffer ,@body)) (defmacro nnmaildir--with-work-buffer (&rest body) - (declare (debug (body))) + (declare (indent 0) (debug t)) `(with-current-buffer (gnus-get-buffer-create " *nnmaildir work*") ,@body)) (defmacro nnmaildir--with-nov-buffer (&rest body) - (declare (debug (body))) + (declare (indent 0) (debug t)) `(with-current-buffer (gnus-get-buffer-create " *nnmaildir nov*") ,@body)) (defmacro nnmaildir--with-move-buffer (&rest body) - (declare (debug (body))) + (declare (indent 0) (debug t)) `(with-current-buffer (gnus-get-buffer-create " *nnmaildir move*") ,@body)) @@ -358,7 +348,7 @@ This variable is set by `nnmaildir-request-article'.") string) (defmacro nnmaildir--condcase (errsym body &rest handler) - (declare (debug (sexp form body))) + (declare (indent 2) (debug (sexp form body))) `(condition-case ,errsym (let ((system-messages-locale "C")) ,body) (error . ,handler))) diff --git a/lisp/gnus/nnoo.el b/lisp/gnus/nnoo.el index 9bb86d65ab..cd0a5e6de9 100644 --- a/lisp/gnus/nnoo.el +++ b/lisp/gnus/nnoo.el @@ -33,21 +33,21 @@ (defmacro defvoo (var init &optional doc &rest map) "The same as `defvar', only takes list of variables to MAP to." + (declare (indent 2) + (debug (var init &optional doc &rest map))) `(prog1 ,(if doc `(defvar ,var ,init ,(concat doc "\n\nThis is a Gnus server variable. See Info node `(gnus)Select Methods'.")) `(defvar ,var ,init)) (nnoo-define ',var ',map))) -(put 'defvoo 'lisp-indent-function 2) -(put 'defvoo 'edebug-form-spec '(var init &optional doc &rest map)) (defmacro deffoo (func args &rest forms) "The same as `defun', only register FUNC." + (declare (indent 2) + (debug (&define name lambda-list def-body))) `(prog1 (defun ,func ,args ,@forms) (nnoo-register-function ',func))) -(put 'deffoo 'lisp-indent-function 2) -(put 'deffoo 'edebug-form-spec '(&define name lambda-list def-body)) (defun nnoo-register-function (func) (let ((funcs (nthcdr 3 (assoc (nnoo-backend func) @@ -57,18 +57,18 @@ (setcar funcs (cons func (car funcs))))) (defmacro nnoo-declare (backend &rest parents) + (declare (indent 1)) `(eval-and-compile (if (assq ',backend nnoo-definition-alist) (setcar (cdr (assq ',backend nnoo-definition-alist)) - (mapcar 'list ',parents)) + (mapcar #'list ',parents)) (push (list ',backend - (mapcar 'list ',parents) + (mapcar #'list ',parents) nil nil) nnoo-definition-alist)) (unless (assq ',backend nnoo-state-alist) (push (list ',backend "*internal-non-initialized-backend*") nnoo-state-alist)))) -(put 'nnoo-declare 'lisp-indent-function 1) (defun nnoo-parents (backend) (nth 1 (assoc backend nnoo-definition-alist))) @@ -80,8 +80,8 @@ (nth 3 (assoc backend nnoo-definition-alist))) (defmacro nnoo-import (backend &rest imports) + (declare (indent 1)) `(nnoo-import-1 ',backend ',imports)) -(put 'nnoo-import 'lisp-indent-function 1) (defun nnoo-import-1 (backend imports) (let ((call-function @@ -130,8 +130,8 @@ (setq vars (cdr vars))))))) (defmacro nnoo-map-functions (backend &rest maps) + (declare (indent 1)) `(nnoo-map-functions-1 ',backend ',maps)) -(put 'nnoo-map-functions 'lisp-indent-function 1) (defun nnoo-map-functions-1 (backend maps) (let (m margs i) commit 3555657585bb2c1809fa6abff7f565a8c7f226eb Author: Stefan Kangas Date: Sat Jan 30 15:59:13 2021 +0100 Remove unused argument from set_frame_menubar (Bug#45759) * src/w32menu.c (set_frame_menubar): * src/xmenu.c (set_frame_menubar): Remove unused argument. All callers updated. diff --git a/src/frame.h b/src/frame.h index 9b0852c7b9..21148fe94c 100644 --- a/src/frame.h +++ b/src/frame.h @@ -1707,7 +1707,7 @@ extern Lisp_Object gui_display_get_resource (Display_Info *, Lisp_Object component, Lisp_Object subclass); -extern void set_frame_menubar (struct frame *f, bool first_time, bool deep_p); +extern void set_frame_menubar (struct frame *f, bool deep_p); extern void frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y); extern void free_frame_menubar (struct frame *); extern bool frame_ancestor_p (struct frame *af, struct frame *df); diff --git a/src/w32fns.c b/src/w32fns.c index e93a0b85d9..5704f1d3c3 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -1637,7 +1637,7 @@ w32_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) if (!old) /* Make menu bar when there was none. Emacs 25 waited until the next redisplay for this to take effect. */ - set_frame_menubar (f, false, true); + set_frame_menubar (f, true); else { /* Remove menu bar. */ diff --git a/src/w32menu.c b/src/w32menu.c index 8bf0c46203..3bf7666394 100644 --- a/src/w32menu.c +++ b/src/w32menu.c @@ -155,7 +155,7 @@ w32_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents) void w32_activate_menubar (struct frame *f) { - set_frame_menubar (f, false, true); + set_frame_menubar (f, true); /* Lock out further menubar changes while active. */ f->output_data.w32->menubar_active = 1; @@ -258,12 +258,10 @@ menubar_selection_callback (struct frame *f, void * client_data) } -/* Set the contents of the menubar widgets of frame F. - The argument FIRST_TIME is currently ignored; - it is set the first time this is called, from initialize_frame_menubar. */ +/* Set the contents of the menubar widgets of frame F. */ void -set_frame_menubar (struct frame *f, bool first_time, bool deep_p) +set_frame_menubar (struct frame *f, bool deep_p) { HMENU menubar_widget = f->output_data.w32->menubar_widget; Lisp_Object items; @@ -511,7 +509,7 @@ initialize_frame_menubar (struct frame *f) /* This function is called before the first chance to redisplay the frame. It has to be, so the frame will have the right size. */ fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f))); - set_frame_menubar (f, true, true); + set_frame_menubar (f, true); } /* Get rid of the menu bar of frame F, and free its storage. diff --git a/src/xdisp.c b/src/xdisp.c index 11b9e1becf..32b359098a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -12876,7 +12876,7 @@ update_menu_bar (struct frame *f, bool save_match_data, bool hooks_run) the selected frame should be allowed to set it. */ if (f == SELECTED_FRAME ()) #endif - set_frame_menubar (f, false, false); + set_frame_menubar (f, false); } else /* On a terminal screen, the menu bar is an ordinary screen diff --git a/src/xmenu.c b/src/xmenu.c index ea3813a64e..a83fffbf1c 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -289,7 +289,7 @@ DEFUN ("x-menu-bar-open-internal", Fx_menu_bar_open_internal, Sx_menu_bar_open_i block_input (); if (FRAME_EXTERNAL_MENU_BAR (f)) - set_frame_menubar (f, false, true); + set_frame_menubar (f, true); menubar = FRAME_X_OUTPUT (f)->menubar_widget; if (menubar) @@ -368,7 +368,7 @@ If FRAME is nil or not given, use the selected frame. */) f = decode_window_system_frame (frame); if (FRAME_EXTERNAL_MENU_BAR (f)) - set_frame_menubar (f, false, true); + set_frame_menubar (f, true); menubar = FRAME_X_OUTPUT (f)->menubar_widget; if (menubar) @@ -433,7 +433,7 @@ x_activate_menubar (struct frame *f) return; #endif - set_frame_menubar (f, false, true); + set_frame_menubar (f, true); block_input (); popup_activated_flag = 1; #ifdef USE_GTK @@ -677,12 +677,10 @@ apply_systemfont_to_menu (struct frame *f, Widget w) #endif -/* Set the contents of the menubar widgets of frame F. - The argument FIRST_TIME is currently ignored; - it is set the first time this is called, from initialize_frame_menubar. */ +/* Set the contents of the menubar widgets of frame F. */ void -set_frame_menubar (struct frame *f, bool first_time, bool deep_p) +set_frame_menubar (struct frame *f, bool deep_p) { xt_or_gtk_widget menubar_widget, old_widget; #ifdef USE_X_TOOLKIT @@ -1029,7 +1027,7 @@ initialize_frame_menubar (struct frame *f) /* This function is called before the first chance to redisplay the frame. It has to be, so the frame will have the right size. */ fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f))); - set_frame_menubar (f, true, true); + set_frame_menubar (f, true); } commit ca44ea18ef2738b4f2e8c72058a12dc82ba13c65 Author: Eli Zaretskii Date: Sat Jan 30 16:15:00 2021 +0200 Improve documentation of auto-resize-tool/tab-bars * src/xdisp.c (syms_of_xdisp) : Doc fix. (Bug#46178) diff --git a/src/xdisp.c b/src/xdisp.c index cac3195170..77c9af747c 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -34742,7 +34742,8 @@ of your window manager. */); This dynamically changes the tab-bar's height to the minimum height that is needed to make all tab-bar items visible. If value is `grow-only', the tab-bar's height is only increased -automatically; to decrease the tab-bar height, use \\[recenter]. */); +automatically; to decrease the tab-bar height, use \\[recenter], +after setting `recenter-redisplay' to the value of t. */); Vauto_resize_tab_bars = Qt; DEFVAR_BOOL ("auto-raise-tab-bar-buttons", auto_raise_tab_bar_buttons_p, @@ -34754,7 +34755,8 @@ automatically; to decrease the tab-bar height, use \\[recenter]. */); This dynamically changes the tool-bar's height to the minimum height that is needed to make all tool-bar items visible. If value is `grow-only', the tool-bar's height is only increased -automatically; to decrease the tool-bar height, use \\[recenter]. */); +automatically; to decrease the tool-bar height, use \\[recenter], +after setting `recenter-redisplay' to the value of t. */); Vauto_resize_tool_bars = Qt; DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p, commit 96f20120c97a0a329fff81a0cc3747082a8a2c55 Author: Dmitry Gutov Date: Sat Jan 30 15:42:19 2021 +0200 Also highlight 'conflict' with the warning face * lisp/vc/vc-git.el (vc-git-dir-printer): Also highlight 'conflict' with the warning face, like vc-default-dir-printer does already. diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index 94fac3a83b..d00c2c2133 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -479,8 +479,8 @@ or an empty string if none." (propertize (format "%-12s" state) 'face (cond ((eq state 'up-to-date) 'font-lock-builtin-face) - ((eq state 'missing) 'font-lock-warning-face) - (t 'font-lock-variable-name-face)) + ((eq state '(missing conflict)) 'font-lock-warning-face) + (t 'font-lock-variable-name-face)) 'mouse-face 'highlight 'keymap vc-dir-status-mouse-map) " " (vc-git-permissions-as-string old-perm new-perm) commit f7b9b9a85e40555a23ee56d75338a3c4e378e4f5 Author: Basil L. Contovounesios Date: Sat Jan 30 13:26:29 2021 +0000 ; Use American spelling in etc/NEWS. diff --git a/etc/NEWS b/etc/NEWS index 11fca4fecb..7b4b7fea5a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -505,7 +505,7 @@ time zones will use a form like "+0100" instead of "CET". ** Dired --- -*** Behaviour change on 'dired-clean-confirm-killing-deleted-buffers'. +*** Behavior change on 'dired-clean-confirm-killing-deleted-buffers'. Previously, if 'dired-clean-up-buffers-too' was non-nil, and 'dired-clean-confirm-killing-deleted-buffers' was nil, the buffers wouldn't be killed. This combination will now kill the buffers. commit ed2f2cc5577d5d9b61db7a5b61e93e79d678be41 Author: Lars Ingebrigtsen Date: Sat Jan 30 11:10:26 2021 +0100 auth-source-search doc string fix * lisp/auth-source.el (auth-source-search): Fix example (bug#36286). diff --git a/lisp/auth-source.el b/lisp/auth-source.el index ad3b690dfa..2494040457 100644 --- a/lisp/auth-source.el +++ b/lisp/auth-source.el @@ -588,7 +588,7 @@ Here's an example: \(let ((auth-source-creation-defaults \\='((user . \"defaultUser\") (A . \"default A\"))) (auth-source-creation-prompts - \\='((password . \"Enter IMAP password for %h:%p: \")))) + \\='((secret . \"Enter IMAP password for %h:%p: \")))) (auth-source-search :host \\='(\"nonesuch\" \"twosuch\") :type \\='netrc :max 1 :P \"pppp\" :Q \"qqqq\" :create \\='(A B Q))) commit 0e2e1caa0bc87c5972ca1bbe6893a56d4db1df0a Author: Jared Finder Date: Mon Dec 7 22:44:32 2020 -0800 * lisp/tab-line.el (tab-line-new-tab): Use tty menus when supported. diff --git a/lisp/tab-line.el b/lisp/tab-line.el index 2726947a4c..9209f2d46e 100644 --- a/lisp/tab-line.el +++ b/lisp/tab-line.el @@ -651,7 +651,9 @@ corresponding to the switched buffer." (if (functionp tab-line-new-tab-choice) (funcall tab-line-new-tab-choice) (let ((tab-line-tabs-buffer-groups mouse-buffer-menu-mode-groups)) - (if (and (listp mouse-event) window-system) ; (display-popup-menus-p) + (if (and (listp mouse-event) + (display-popup-menus-p) + (not tty-menu-open-use-tmm)) (mouse-buffer-menu mouse-event) ; like (buffer-menu-open) ;; tty menu doesn't support mouse clicks, so use tmm (tmm-prompt (mouse-buffer-menu-keymap)))))) commit bb652f68fd4e996d58f731a0dba1be18fd4e03d7 Author: Eli Zaretskii Date: Sat Jan 30 11:26:07 2021 +0200 New Rmail option 'rmail-show-message-set-modified' * lisp/mail/rmail.el (rmail-show-message-set-modified): New option. (rmail-show-message-1): If 'rmail-show-message-set-modified' is non-nil, don't reset the buffer's modified state. (Bug#45941) * etc/NEWS: Announce the new option. diff --git a/etc/NEWS b/etc/NEWS index a6fd51b8a2..11fca4fecb 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1138,6 +1138,11 @@ bindings, will be aborted, and Emacs will not ask you whether to enlarge 'max-specpdl-size' to complete the rendering. The default is t, which preserves the original behavior. +--- +*** New user option 'rmail-show-message-set-modified'. +If set non-nil, showing an unseen message will set the Rmail buffer's +modified flag. + ** Apropos *** New commands 'apropos-next-symbol' and 'apropos-previous-symbol'. diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el index 29460cc20f..9f95b62d87 100644 --- a/lisp/mail/rmail.el +++ b/lisp/mail/rmail.el @@ -2723,6 +2723,12 @@ See also `unrmail-mbox-format'." :version "24.4" :group 'rmail-files) +(defcustom rmail-show-message-set-modified nil + "If non-nil, displaying an unseen message marks the Rmail buffer as modified." + :type 'boolean + :group 'rmail + :version "28.1") + (defun rmail-show-message-1 (&optional msg) "Show message MSG (default: current message) using `rmail-view-buffer'. Return text to display in the minibuffer if MSG is out of @@ -2750,6 +2756,8 @@ The current mail message becomes the message displayed." ;; Mark the message as seen, but preserve buffer modified flag. (let ((modiff (buffer-modified-p))) (rmail-set-attribute rmail-unseen-attr-index nil) + (and rmail-show-message-set-modified + (setq modiff t)) (unless modiff (restore-buffer-modified-p modiff))) ;; bracket the message in the mail commit 32dc433dbb83a5c38650769dc064c082bf79ee8c Author: Lars Ingebrigtsen Date: Sat Jan 30 08:59:48 2021 +0100 Fix vc-hg-rename-file on file names like ~/foo/bar * lisp/vc/vc-hg.el (vc-hg-rename-file): Use absolute file names, because hg doesn't like getting file names like "~/foo/bar" (bug#36932). diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index c4b82ab11e..1d163a64ab 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -1166,7 +1166,8 @@ hg binary." ;; Modeled after the similar function in vc-bzr.el (defun vc-hg-rename-file (old new) "Rename file from OLD to NEW using `hg mv'." - (vc-hg-command nil 0 new "mv" old)) + (vc-hg-command nil 0 (expand-file-name new) "mv" + (expand-file-name old))) (defun vc-hg-register (files &optional _comment) "Register FILES under hg. COMMENT is ignored." commit cc2d3a62c2a1f5be7907eda55d3c678e1149eb7b Author: Jeff Spencer Date: Sat Jan 30 08:12:57 2021 +0100 Fix interaction between two dired cleanup variables * lisp/dired.el (dired-clean-up-after-deletion): Kill the buffers if you have `dired-clean-up-buffers-too' set and `dired-clean-confirm-killing-deleted-buffers' nil (bug#38037). Copyright-paperwork-exempt: yes diff --git a/etc/NEWS b/etc/NEWS index 8e233f8f19..a6fd51b8a2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -504,6 +504,12 @@ time zones will use a form like "+0100" instead of "CET". ** Dired +--- +*** Behaviour change on 'dired-clean-confirm-killing-deleted-buffers'. +Previously, if 'dired-clean-up-buffers-too' was non-nil, and +'dired-clean-confirm-killing-deleted-buffers' was nil, the buffers +wouldn't be killed. This combination will now kill the buffers. + +++ *** New user option 'dired-switches-in-mode-line'. This user option controls how 'ls' switches are displayed in the mode diff --git a/lisp/dired.el b/lisp/dired.el index 3f11936331..fe6ac1e259 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -3532,18 +3532,21 @@ confirmation. To disable the confirmation, see (when (and (featurep 'dired-x) dired-clean-up-buffers-too) (let ((buf (get-file-buffer fn))) (and buf - (and dired-clean-confirm-killing-deleted-buffers - (funcall #'y-or-n-p - (format "Kill buffer of %s, too? " - (file-name-nondirectory fn)))) + (or (and dired-clean-confirm-killing-deleted-buffers + (funcall #'y-or-n-p + (format "Kill buffer of %s, too? " + (file-name-nondirectory fn)))) + (not dired-clean-confirm-killing-deleted-buffers)) (kill-buffer buf))) (let ((buf-list (dired-buffers-for-dir (expand-file-name fn)))) (and buf-list - (and dired-clean-confirm-killing-deleted-buffers - (y-or-n-p (format (ngettext "Kill Dired buffer of %s, too? " - "Kill Dired buffers of %s, too? " - (length buf-list)) - (file-name-nondirectory fn)))) + (or (and dired-clean-confirm-killing-deleted-buffers + (y-or-n-p (format + (ngettext "Kill Dired buffer of %s, too? " + "Kill Dired buffers of %s, too? " + (length buf-list)) + (file-name-nondirectory fn)))) + (not dired-clean-confirm-killing-deleted-buffers)) (dolist (buf buf-list) (kill-buffer buf)))))) commit 0fa2a715d4c38cdea06737b5b9142db29dc3ebc9 Author: Lars Ingebrigtsen Date: Sat Jan 30 07:59:30 2021 +0100 Improve :foreground description in the manual * doc/lispref/frames.texi (Font and Color Parameters): Make the description less confusing (bug#38710). diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 9b4716b93d..a15511dc9f 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -2411,7 +2411,7 @@ attribute of the @code{default} face. @vindex foreground-color@r{, a frame parameter} @item foreground-color -The color to use for the image of a character. It is equivalent to +The color to use for characters. It is equivalent to the @code{:foreground} attribute of the @code{default} face. @vindex background-color@r{, a frame parameter} commit 5644ac41c42fde4a4434131e45110aa1e909e0b2 Author: Mauro Aranda Date: Sat Jan 30 07:47:34 2021 +0100 Add source to sgml-empty-tags * lisp/textmodes/sgml-mode.el (html-mode): Add "source" as an empty tag to fix indentation when this element is present (bug#46181). diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el index 8465e82b02..c50c544cb5 100644 --- a/lisp/textmodes/sgml-mode.el +++ b/lisp/textmodes/sgml-mode.el @@ -2402,9 +2402,9 @@ To work around that, do: (setq-local sgml-empty-tags ;; From HTML-4.01's loose.dtd, parsed with - ;; `sgml-parse-dtd', plus manual addition of "wbr". + ;; `sgml-parse-dtd', plus manual additions of "source" and "wbr". '("area" "base" "basefont" "br" "col" "frame" "hr" "img" "input" - "isindex" "link" "meta" "param" "wbr")) + "isindex" "link" "meta" "source" "param" "wbr")) (setq-local sgml-unclosed-tags ;; From HTML-4.01's loose.dtd, parsed with `sgml-parse-dtd'. '("body" "colgroup" "dd" "dt" "head" "html" "li" "option" commit 90ce2b80342299ef4c6c2f6b08cca55e20ffa06b Author: Lars Ingebrigtsen Date: Fri Jan 29 08:34:43 2021 +0100 rmail-summary-mark-deleted optional argument fix * lisp/mail/rmailsum.el (rmail-summary-mark-deleted): Argument N is optional, so don't assume that it's a number (bug#39076). diff --git a/lisp/mail/rmailsum.el b/lisp/mail/rmailsum.el index d29115a957..7f99ecdcf2 100644 --- a/lisp/mail/rmailsum.el +++ b/lisp/mail/rmailsum.el @@ -974,8 +974,9 @@ a negative argument means to delete and move forward." (delete-char 1) (insert "D")) ;; Discard cached new summary line. - (with-current-buffer rmail-buffer - (aset rmail-summary-vector (1- n) nil)))) + (when n + (with-current-buffer rmail-buffer + (aset rmail-summary-vector (1- n) nil))))) (beginning-of-line)) (defun rmail-summary-update-line (n) commit bbad7904e20ba0366a3397a45fb89de0275bbf28 Author: Dmitry Gutov Date: Sat Jan 30 03:56:27 2021 +0200 vc-dir-mode-map: Remove the mouse-2 binding * lisp/vc/vc-dir.el (vc-dir-mode-map): Remove the mouse-2 binding (bug#13692). (vc-dir-mode): Update the docstring accordingly. (vc-dir-status-mouse-map): New variable. (vc-default-dir-printer): Use it on the state buttons. * lisp/vc/vc-git.el (vc-git-dir-printer): Same. diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index bbb73240be..9d0808c043 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -300,7 +300,6 @@ See `run-hooks'." (define-key map "\C-o" 'vc-dir-display-file) (define-key map "\C-c\C-c" 'vc-dir-kill-dir-status-process) (define-key map [down-mouse-3] 'vc-dir-menu) - (define-key map [mouse-2] 'vc-dir-toggle-mark) (define-key map [follow-link] 'mouse-face) (define-key map "x" 'vc-dir-hide-up-to-date) (define-key map [?\C-k] 'vc-dir-kill-line) @@ -1085,7 +1084,6 @@ U - if the cursor is on a file: unmark all the files with the same state as the current file - if the cursor is on a directory: unmark all child files - with a prefix argument: unmark all files -mouse-2 - toggles the mark state VC commands VC commands in the `C-x v' prefix can be used. @@ -1392,6 +1390,12 @@ These are the commands available for use in the file status buffer: (propertize "Please add backend specific headers here. It's easy!" 'face 'font-lock-warning-face))) +(defvar vc-dir-status-mouse-map + (let ((map (make-sparse-keymap))) + (define-key map [mouse-2] 'vc-dir-toggle-mark) + map) + "Local keymap for toggling mark.") + (defvar vc-dir-filename-mouse-map (let ((map (make-sparse-keymap))) (define-key map [mouse-2] 'vc-dir-find-file-other-window) @@ -1418,7 +1422,8 @@ These are the commands available for use in the file status buffer: ((memq state '(missing conflict)) 'font-lock-warning-face) ((eq state 'edited) 'font-lock-constant-face) (t 'font-lock-variable-name-face)) - 'mouse-face 'highlight) + 'mouse-face 'highlight + 'keymap vc-dir-status-mouse-map) " " (propertize (format "%s" filename) diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index a9ee28e3aa..94fac3a83b 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -481,7 +481,8 @@ or an empty string if none." 'face (cond ((eq state 'up-to-date) 'font-lock-builtin-face) ((eq state 'missing) 'font-lock-warning-face) (t 'font-lock-variable-name-face)) - 'mouse-face 'highlight) + 'mouse-face 'highlight + 'keymap vc-dir-status-mouse-map) " " (vc-git-permissions-as-string old-perm new-perm) " " (propertize (vc-git-escape-file-name (vc-dir-fileinfo->name info)) commit f3f6e84ca6f16c243cd1242ca51c333972a4bb9a Author: Stefan Kangas Date: Sat Jan 30 00:32:20 2021 +0100 Use lexical-binding in mpuz.el * lisp/play/mpuz.el: Use lexical-binding. Remove redundant :group args. (mpuz-switch-to-window): Minor cleanup. diff --git a/lisp/play/mpuz.el b/lisp/play/mpuz.el index 7fff604aea..838bddfb66 100644 --- a/lisp/play/mpuz.el +++ b/lisp/play/mpuz.el @@ -1,4 +1,4 @@ -;;; mpuz.el --- multiplication puzzle for GNU Emacs +;;; mpuz.el --- multiplication puzzle for GNU Emacs -*- lexical-binding: t -*- ;; Copyright (C) 1990, 2001-2021 Free Software Foundation, Inc. @@ -40,49 +40,41 @@ The value t means never ding, and `error' means only ding on wrong input." :type '(choice (const :tag "No" nil) (const :tag "Yes" t) - (const :tag "If correct" error)) - :group 'mpuz) + (const :tag "If correct" error))) (defcustom mpuz-solve-when-trivial t "Solve any row that can be trivially calculated from what you've found." - :type 'boolean - :group 'mpuz) + :type 'boolean) (defcustom mpuz-allow-double-multiplicator nil "Allow 2nd factors like 33 or 77." - :type 'boolean - :group 'mpuz) + :type 'boolean) (defface mpuz-unsolved '((default :weight bold) (((class color)) :foreground "red1")) - "Face for letters to be solved." - :group 'mpuz) + "Face for letters to be solved.") (defface mpuz-solved '((default :weight bold) (((class color)) :foreground "green1")) - "Face for solved digits." - :group 'mpuz) + "Face for solved digits.") (defface mpuz-trivial '((default :weight bold) (((class color)) :foreground "blue")) - "Face for trivial digits solved for you." - :group 'mpuz) + "Face for trivial digits solved for you.") (defface mpuz-text '((t :inherit variable-pitch)) - "Face for text on right." - :group 'mpuz) + "Face for text on right.") ;; Mpuz mode and keymaps ;;---------------------- (defcustom mpuz-mode-hook nil "Hook to run upon entry to mpuz." - :type 'hook - :group 'mpuz) + :type 'hook) (defvar mpuz-mode-map (let ((map (make-sparse-keymap))) @@ -341,8 +333,8 @@ You may abort a game by typing \\\\[mpuz-offer-abort]." (defun mpuz-switch-to-window () "Find or create the Mult-Puzzle buffer, and display it." - (let ((buf (mpuz-get-buffer))) - (or buf (setq buf (mpuz-create-buffer))) + (let ((buf (or (mpuz-get-buffer) + (mpuz-create-buffer)))) (switch-to-buffer buf) (setq buffer-read-only t) (mpuz-mode))) commit 1a4bb1e2f28ec20aff23bab335ba949a0f2b75a1 Author: Stefan Kangas Date: Sat Jan 30 00:10:10 2021 +0100 Use lexical-binding in handwrite.el * lisp/play/handwrite.el: Use lexical-binding. Remove redundant :group args. Minor cleanups. (handwrite): Minor cleanups. (handwrite-set-pagenumber-off, handwrite-set-pagenumber-on): Make comments into docstrings. diff --git a/lisp/play/handwrite.el b/lisp/play/handwrite.el index 7ad3de6fb6..98da26c2e6 100644 --- a/lisp/play/handwrite.el +++ b/lisp/play/handwrite.el @@ -1,8 +1,9 @@ -;;; handwrite.el --- turns your emacs buffer into a handwritten document +;;; handwrite.el --- turns your emacs buffer into a handwritten document -*- lexical-binding: t -*- ;; Copyright (C) 1996, 2001-2021 Free Software Foundation, Inc. ;; Author: Danny Roozendaal (was: ) +;; Maintainer: emacs-devel@gnu.org ;; Created: October 21 1996 ;; Keywords: wp, print, postscript, cursive writing @@ -22,11 +23,11 @@ ;; along with GNU Emacs. If not, see . ;;; Commentary: + +;; The function `handwrite' creates PostScript output containing a +;; handwritten version of the current buffer. ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; The function handwrite creates PostScript output containing a -;; handwritten version of the current buffer.. -;; Other functions that may be useful are +;; Other functions that may be useful are: ;; ;; handwrite-10pt: sets the font size to 10 and finds corresponding ;; values for the line spacing and the number of lines @@ -54,8 +55,6 @@ ;; unknown characters. ;; ;; Thanks to anyone who emailed me suggestions! -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;; Code: @@ -64,7 +63,6 @@ (defvar ps-lpr-command) (defvar ps-lpr-switches) - ;; Variables (defgroup handwrite nil @@ -98,44 +96,43 @@ (defcustom handwrite-numlines 60 "The number of lines on a page of the PostScript output from `handwrite'." - :type 'integer - :group 'handwrite) + :type 'integer) + (defcustom handwrite-fontsize 11 "The size of the font for the PostScript output from `handwrite'." - :type 'integer - :group 'handwrite) + :type 'integer) + (defcustom handwrite-linespace 12 "The spacing for the PostScript output from `handwrite'." - :type 'integer - :group 'handwrite) + :type 'integer) + (defcustom handwrite-xstart 30 "X-axis translation in the PostScript output from `handwrite'." - :type 'integer - :group 'handwrite) + :type 'integer) + (defcustom handwrite-ystart 810 "Y-axis translation in the PostScript output from `handwrite'." - :type 'integer - :group 'handwrite) + :type 'integer) + (defcustom handwrite-pagenumbering nil "If non-nil, number each page of the PostScript output from `handwrite'." - :type 'boolean - :group 'handwrite) + :type 'boolean) + (defcustom handwrite-10pt-numlines 65 "The number of lines on a page for the function `handwrite-10pt'." - :type 'integer - :group 'handwrite) + :type 'integer) + (defcustom handwrite-11pt-numlines 60 "The number of lines on a page for the function `handwrite-11pt'." - :type 'integer - :group 'handwrite) + :type 'integer) + (defcustom handwrite-12pt-numlines 55 "The number of lines on a page for the function `handwrite-12pt'." - :type 'integer - :group 'handwrite) + :type 'integer) + (defcustom handwrite-13pt-numlines 50 "The number of lines on a page for the function `handwrite-13pt'." - :type 'integer - :group 'handwrite) + :type 'integer) ;; Interactive functions @@ -150,17 +147,17 @@ Variables: `handwrite-linespace' (default 12) `handwrite-numlines' (default 60) `handwrite-pagenumbering' (default nil)" (interactive) + (setq handwrite-psindex (1+ handwrite-psindex)) (let - (;(pmin) ; thanks, Havard - (cur-buf (current-buffer)) + ((cur-buf (current-buffer)) (tpoint (point)) (ps-ypos 63) (lcount 0) (ipage 1) - (nlan next-line-add-newlines) ;remember the old value + (next-line-add-newlines t) (buf-name (buffer-name) ) (textp) - (ps-buf-name) ;name of the PostScript buffer + (ps-buf-name (format "*handwritten%d.ps*" handwrite-psindex)) (trans-table '(("ÿ" . "264") ("á" . "207") ("à" . "210") ("â" . "211") ("ä" . "212") ("ã" . "213") ("å" . "214") ("é" . "216") @@ -175,10 +172,6 @@ Variables: `handwrite-linespace' (default 12) ; on inserted backslashes line) (goto-char (point-min)) ;start at beginning - (setq handwrite-psindex (1+ handwrite-psindex)) - (setq ps-buf-name - (format "*handwritten%d.ps*" handwrite-psindex)) - (setq next-line-add-newlines t) (switch-to-buffer ps-buf-name) (handwrite-insert-header buf-name) (insert "%%Creator: GNU Emacs's handwrite version " emacs-version "\n") @@ -258,9 +251,7 @@ Variables: `handwrite-linespace' (default 12) (message "") (bury-buffer ()) (switch-to-buffer cur-buf) - (goto-char tpoint) - (setq next-line-add-newlines nlan) - )) + (goto-char tpoint))) (defun handwrite-set-pagenumber () @@ -280,7 +271,6 @@ values for `handwrite-linespace' and `handwrite-numlines'." (setq handwrite-numlines handwrite-10pt-numlines) (message "Handwrite output size set to 10 points")) - (defun handwrite-11pt () "Specify 11-point output for `handwrite'. This sets `handwrite-fontsize' to 11 and finds correct @@ -1238,28 +1228,16 @@ end /Joepie Hwfdict definefont %%EndFont Joepie\n\n")) -;;Sets page numbering off (defun handwrite-set-pagenumber-off () + "Set page numbering off." (setq handwrite-pagenumbering nil) (message "page numbering off")) -;;Sets page numbering on (defun handwrite-set-pagenumber-on () + "Set page numbering on." (setq handwrite-pagenumbering t) (message "page numbering on" )) - -;; Key bindings - -;; I'd rather not fill up the menu bar menus with -;; lots of random miscellaneous features. -- rms. -;;;(define-key-after -;;; (lookup-key global-map [menu-bar edit]) -;;; [handwrite] -;;; '("Write by hand" . menu-bar-handwrite-map) -;;; 'spell) - (provide 'handwrite) - ;;; handwrite.el ends here commit 295de50329a584c588c44a8485f576a33d12044c Author: Stefan Monnier Date: Fri Jan 29 16:49:12 2021 -0500 * test/lisp/electric-tests.el: Fix switch to lexical-binding. (define-electric-pair-test): Don't presume that function values are self-evaluating. diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el index 05a6989664..62a42b7fe4 100644 --- a/test/lisp/electric-tests.el +++ b/test/lisp/electric-tests.el @@ -135,9 +135,11 @@ The buffer's contents should %s: (length fixture) fixture (if fixture-fn (format "\nNow call this:\n\n%s" - (pp-to-string fixture-fn)) "") + (pp-to-string fixture-fn)) + "") (if bindings (format "\nEnsure the following bindings:\n\n%s" - (pp-to-string bindings)) "") + (pp-to-string bindings)) + "") char (if (string= fixture expected-string) "stay" "become") (replace-regexp-in-string "\n" "\\\\n" expected-string) @@ -163,8 +165,11 @@ The buffer's contents should %s: (test-in-comments t) (test-in-strings t) (test-in-code t) - (fixture-fn #'(lambda () - (electric-pair-mode 1)))) + ;; The semantics of CL's defmacro "default values" is subtle: + ;; contrary to the actual arguments, these are evaluated (and + ;; are expected to return the "default form"). + ;; `fixture-fn' contains a form whose evaluation returns a function. + (fixture-fn '#'electric-pair-mode)) `(progn ,@(cl-loop for mode in (eval modes) ;FIXME: avoid `eval' commit 7415c66d8b3e2476aeea64c70ef376c12a39f175 Author: Mattias Engdegård Date: Fri Jan 29 21:15:33 2021 +0100 ; * src/process.c (child_signal_read): Don't report EAGAIN as error diff --git a/src/process.c b/src/process.c index 1df4ed9ce0..3beb9cf714 100644 --- a/src/process.c +++ b/src/process.c @@ -7217,7 +7217,7 @@ child_signal_read (int fd, void *data) eassert (0 <= fd); eassert (fd == child_signal_read_fd); char dummy; - if (emacs_read (fd, &dummy, 1) < 0) + if (emacs_read (fd, &dummy, 1) < 0 && errno != EAGAIN) emacs_perror ("reading from child signal FD"); } #endif /* !WINDOWSNT */ commit 47147db9b0f40c77657aff625048bbef5d32fb05 Author: Stefan Kangas Date: Fri Jan 29 21:06:02 2021 +0100 ; Silence byte-compiler * lisp/net/sasl-ntlm.el (sasl-ntlm-request): * lisp/net/sasl.el (sasl-plain-response, sasl-login-response-1) (sasl-login-response-2, sasl-anonymous-response): Fix warnings introduced by my previous commit. diff --git a/lisp/net/sasl-ntlm.el b/lisp/net/sasl-ntlm.el index 1ceb6d179c..dfb7e71330 100644 --- a/lisp/net/sasl-ntlm.el +++ b/lisp/net/sasl-ntlm.el @@ -40,7 +40,7 @@ "A list of functions to be called in sequence for the NTLM authentication steps. They are called by `sasl-next-step'.") -(defun sasl-ntlm-request (client step) +(defun sasl-ntlm-request (client _step) "SASL step function to generate a NTLM authentication request to the server. Called from `sasl-next-step'. CLIENT is a vector [mechanism user service server sasl-client-properties] diff --git a/lisp/net/sasl.el b/lisp/net/sasl.el index aa4681f11c..b7f814f723 100644 --- a/lisp/net/sasl.el +++ b/lisp/net/sasl.el @@ -203,7 +203,7 @@ It contain at least 64 bits of entropy." (defconst sasl-plain-steps '(sasl-plain-response)) -(defun sasl-plain-response (client step) +(defun sasl-plain-response (client _step) (let ((passphrase (sasl-read-passphrase (format "PLAIN passphrase for %s: " (sasl-client-name client)))) @@ -229,12 +229,12 @@ It contain at least 64 bits of entropy." sasl-login-response-1 sasl-login-response-2)) -(defun sasl-login-response-1 (client step) +(defun sasl-login-response-1 (client _step) ;;; (unless (string-match "^Username:" (sasl-step-data step)) ;;; (sasl-error (format "Unexpected response: %s" (sasl-step-data step)))) (sasl-client-name client)) -(defun sasl-login-response-2 (client step) +(defun sasl-login-response-2 (client _step) ;;; (unless (string-match "^Password:" (sasl-step-data step)) ;;; (sasl-error (format "Unexpected response: %s" (sasl-step-data step)))) (sasl-read-passphrase @@ -250,7 +250,7 @@ It contain at least 64 bits of entropy." '(ignore ;no initial response sasl-anonymous-response)) -(defun sasl-anonymous-response (client step) +(defun sasl-anonymous-response (client _step) (or (sasl-client-property client 'trace) (sasl-client-name client))) commit c7a86cb7ecb79cd07c66ce6a5af5fac32fc2fca4 Author: Stefan Kangas Date: Fri Jan 29 20:11:38 2021 +0100 Use lexical-binding in sasl.el and add tests * lisp/net/sasl.el: * lisp/net/sasl-digest.el: * lisp/net/sasl-cram.el: * lisp/net/sasl-ntlm.el: Use lexical-binding. * test/lisp/net/sasl-tests.el: * test/lisp/net/sasl-cram-tests.el: New files. diff --git a/lisp/net/sasl-cram.el b/lisp/net/sasl-cram.el index bc2612d945..4022a35b39 100644 --- a/lisp/net/sasl-cram.el +++ b/lisp/net/sasl-cram.el @@ -1,4 +1,4 @@ -;;; sasl-cram.el --- CRAM-MD5 module for the SASL client framework +;;; sasl-cram.el --- CRAM-MD5 module for the SASL client framework -*- lexical-binding: t -*- ;; Copyright (C) 2000, 2007-2021 Free Software Foundation, Inc. diff --git a/lisp/net/sasl-digest.el b/lisp/net/sasl-digest.el index efc8f82890..5afc195d4b 100644 --- a/lisp/net/sasl-digest.el +++ b/lisp/net/sasl-digest.el @@ -1,4 +1,4 @@ -;;; sasl-digest.el --- DIGEST-MD5 module for the SASL client framework +;;; sasl-digest.el --- DIGEST-MD5 module for the SASL client framework -*- lexical-binding: t -*- ;; Copyright (C) 2000, 2007-2021 Free Software Foundation, Inc. diff --git a/lisp/net/sasl-ntlm.el b/lisp/net/sasl-ntlm.el index 6658226561..1ceb6d179c 100644 --- a/lisp/net/sasl-ntlm.el +++ b/lisp/net/sasl-ntlm.el @@ -1,4 +1,4 @@ -;;; sasl-ntlm.el --- NTLM (NT Lan Manager) module for the SASL client framework +;;; sasl-ntlm.el --- NTLM (NT Lan Manager) module for the SASL client framework -*- lexical-binding: t -*- ;; Copyright (C) 2000, 2007-2021 Free Software Foundation, Inc. diff --git a/lisp/net/sasl.el b/lisp/net/sasl.el index d2e08f7e3e..aa4681f11c 100644 --- a/lisp/net/sasl.el +++ b/lisp/net/sasl.el @@ -1,4 +1,4 @@ -;;; sasl.el --- SASL client framework +;;; sasl.el --- SASL client framework -*- lexical-binding: t -*- ;; Copyright (C) 2000, 2007-2021 Free Software Foundation, Inc. diff --git a/test/lisp/net/sasl-cram-tests.el b/test/lisp/net/sasl-cram-tests.el new file mode 100644 index 0000000000..e0230ddee6 --- /dev/null +++ b/test/lisp/net/sasl-cram-tests.el @@ -0,0 +1,46 @@ +;;; sasl-cram-tests.el --- tests for sasl-cram.el -*- lexical-binding: t; -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Stefan Kangas + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; Test case from RFC 2195. + +;;; Code: + +(require 'ert) +(require 'sasl) +(require 'sasl-cram) + +(ert-deftest sasl-cram-md5-response-test () + ;; The following strings are taken from section 2 of RFC 2195. + (let ((client + (sasl-make-client (sasl-find-mechanism '("CRAM-MD5")) + "user" + "imap" + "localhost")) + (data (base64-decode-string "PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UucmVzdG9uLm1jaS5uZXQ+")) + (sasl-read-passphrase + (lambda (_prompt) (copy-sequence "tanstaaftanstaaf")))) + (should (equal (sasl-cram-md5-response client (vector nil data)) + "user b913a602c7eda7a495b4e6e7334d3890")))) + +(provide 'sasl-cram-tests) +;;; sasl-cram-tests.el ends here diff --git a/test/lisp/net/sasl-tests.el b/test/lisp/net/sasl-tests.el new file mode 100644 index 0000000000..dab40754c0 --- /dev/null +++ b/test/lisp/net/sasl-tests.el @@ -0,0 +1,59 @@ +;;; sasl-tests.el --- tests for sasl.el -*- lexical-binding: t; -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Stefan Kangas + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'sasl) + +(ert-deftest sasl-test-make-client () + (let ((client (sasl-make-client 'foo 'bar 'baz 'zut))) + (should (eq (sasl-client-mechanism client) 'foo)) + (should (eq (sasl-client-name client) 'bar)) + (should (eq (sasl-client-service client) 'baz)) + (should (eq (sasl-client-server client) 'zut)))) + +(ert-deftest sasl-test-client-set-properties () + (let ((client (sasl-make-client 'foo 'bar 'baz 'zut))) + (sasl-client-set-property client 'foo 'bar) + (should (eq (sasl-client-property client 'foo) 'bar)))) + +(ert-deftest sasl-test-step-data () + (let ((step [nil nil])) + (sasl-step-set-data step "foo") + (should (equal (sasl-step-data step) "foo")))) + +(ert-deftest sasl-test-unique-id () + (should (stringp (sasl-unique-id))) + (should-not (equal (sasl-unique-id) (sasl-unique-id)))) + +(ert-deftest sasl-test-find-mechanism () + (should (sasl-find-mechanism '("ANONYMOUS"))) + (should-not (sasl-find-mechanism '("nonexistent mechanism")))) + +(ert-deftest sasl-test-mechanism-name () + (let ((mechanism (sasl-find-mechanism '("ANONYMOUS")))) + (should (equal (sasl-mechanism-name mechanism) "ANONYMOUS")))) + +(provide 'sasl-tests) +;;; sasl-tests.el ends here commit 9e45c29224c8e8837cfb2ba7706af8ceffdc93bd Author: Dmitry Gutov Date: Fri Jan 29 15:53:28 2021 +0200 (xref-revert-buffer): Also 'erase-buffer' when handling a user-error * lisp/progmodes/xref.el (xref-revert-buffer): Also 'erase-buffer' when handling a user-error (bug#46042). (cherry picked from commit e86b30d6fd04070b86560774ec82392dbe24ca1e) diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 0b25110b79..4c53c09d7b 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -881,6 +881,7 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (erase-buffer) (xref--insert-xrefs alist)) (user-error + (erase-buffer) (insert (propertize (error-message-string err) commit e86b30d6fd04070b86560774ec82392dbe24ca1e Author: Dmitry Gutov Date: Fri Jan 29 15:53:28 2021 +0200 (xref-revert-buffer): Also 'erase-buffer' when handling a user-error * lisp/progmodes/xref.el (xref-revert-buffer): Also 'erase-buffer' when handling a user-error (bug#46042). diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 07a65d4ed9..18fdd963fb 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -972,6 +972,7 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (erase-buffer) (xref--insert-xrefs alist)) (user-error + (erase-buffer) (insert (propertize (error-message-string err) commit 74a71c41e03f28a6380a0537babfdd6c1edb929a (tag: refs/tags/emacs-27.1.91) Author: Eli Zaretskii Date: Fri Jan 29 07:45:45 2021 -0500 Update files for 27.1.91 pretest * ChangeLog.3: * etc/AUTHORS * lisp/ldefs-boot.el: Update. diff --git a/ChangeLog.3 b/ChangeLog.3 index 10c2e2d489..1c0745e9d7 100644 --- a/ChangeLog.3 +++ b/ChangeLog.3 @@ -1,3 +1,331 @@ +2021-01-29 Eli Zaretskii + + Bump Emacs version to 27.1.91 + + * README: + * configure.ac: + * nt/README.W32: + * msdos/sed2v2.inp: Bump Emacs version to 27.1.91. + +2021-01-27 Eli Zaretskii + + Improve documentation of 'read-regexp' and friends + + * doc/emacs/glossary.texi (Glossary): Add "Tag" to the Glossary. + * doc/emacs/maintaining.texi (Xref): Mention that identifiers are + also known as "tags". + + * lisp/replace.el (read-regexp, read-regexp-suggestions): Improve + wording of doc strings. (Bug#46088) (Bug#46089) + + (cherry picked from commit 49eb03d6c8a181fd46adbbcf1f0a976d0a9efa87) + +2021-01-27 Lars Ingebrigtsen + + read-regexp-suggestions doc string improvement + + * lisp/replace.el (read-regexp-suggestions): Add a link to the + manual to explain what a tag is (bug#46089). + + (cherry picked from commit f9cc2d48246fe8370e9286866e6115ba8e2acf44) + +2021-01-27 Lars Ingebrigtsen + + Try to improve the read-regexp doc string + + * lisp/replace.el (read-regexp): Attempt to clarify the semantics + (bug#46088). + + (cherry picked from commit eded2a7ad7d456a417354a2797c18e9a578414d7) + +2021-01-23 Dmitry Gutov + + Erase the buffer only after fetching the new contents + + * lisp/progmodes/xref.el (xref-revert-buffer): + Erase the buffer only after fetching the new contents (bug#46042). + + (cherry picked from commit 5821dee0949b2913c07970d6e4b8bb8e8a35f036) + +2021-01-23 Eli Zaretskii + + Fix last change + + * doc/lispref/text.texi (Undo): Add a cross-reference to the + description of 'undo-amalgamate-change-group'. + (Atomic Changes): Expand and improve the description of + 'undo-amalgamate-change-group'. (Bug#42303) + +2021-01-23 Lars Ingebrigtsen + + Mention undo-amalgamate-change-group in the lispref manual + + * doc/lispref/text.texi (Atomic Changes): Mention + undo-amalgamate-change-group (bug#42303). + + (cherry picked from commit ba25a82855a2c03c25fec83f3056c166b692e94f) + +2021-01-22 Eli Zaretskii + + Avoid sending systemd shutdown notifications if non-daemon + + * src/emacs.c (Fkill_emacs): Send the shutdown notification only + in daemon mode. (Bug#46022) + +2021-01-22 Eli Zaretskii + + * src/cmds.c (Fforward_line): Doc fix. (Bug#46027) + +2021-01-22 Eli Zaretskii + + Improve documentation of sendmail.el defcustom's + + * lisp/mail/sendmail.el (mail-archive-file-name) + (mail-default-reply-to, mail-self-blind, mail-default-headers): + Say in the doc string that 'message-default-mail-headers' shall be + customized when using 'message-mode' for email composition. + (Bug#46029) + +2021-01-20 Stefan Monnier + + Don't let `maybe_quit` prevent resetting `consing_until_gc` (bug#43389) + + * src/alloc.c (garbage_collect): Postpone `unblock_input` a bit. + * src/window.c (window_parameter): Avoid `maybe_quit`. + + cherry picked from commit 420661af07448857f0a17e15dc27bceeb6aff541 + +2021-01-13 Juri Linkov + + Remove one of recently added warnings abound binding keys in Isearch maps + + * lisp/isearch.el (minibuffer-local-isearch-map): Remove comments + which warn against wantonly rebinding unbound keys from + irrelevant keymap. + https://lists.gnu.org/archive/html/emacs-devel/2021-01/msg00259.html + +2021-01-10 Martin Rudalics + + Fix assertion failure in window_box_height (Bug#45737) + + * lisp/window.el (window-sizable): Don't try to grow a mini window + when the root window's minimum height is already larger than its + actual height (Bug#45737). + +2021-01-09 Eli Zaretskii + + Fix cl-concatenate inlining + + * lisp/emacs-lisp/seq.el (seq-concatenate): Auto-load it. Do not + merge to master. (Bug#45610) + +2021-01-09 Tak Kunihiro + + Fix infloop in 'pixel-scroll-mode' + + * lisp/pixel-scroll.el (pixel-scroll-up, pixel-scroll-down): Avoid + inflooping when 'vertical-motion' doesn't move. (Bug#45628) + +2021-01-08 Eli Zaretskii + + Fix inhibiting the default.el loading in user init file + + * lisp/startup.el (startup--load-user-init-file): Test the value + of 'inhibit-default-init', not just the LOAD-DEFAULTS argument, + because loading the user's init file could have set the value of + the former. + (command-line): Call 'startup--load-user-init-file' with last arg + t: there's no longer any need to test the value of + 'inhibit-default-init' here, as it will be tested by the called + function. (Bug#45708) + +2021-01-07 Lars Ingebrigtsen + + Fix problem with 8bit content-transfer-encoding in nndoc mbox files + + * lisp/gnus/nndoc.el (nndoc-possibly-change-buffer): If we're + reading an mbox file, it may contain messages that use + content-transfer-encoding 8bit, which means that we have to treat + the file as a sequence of byte (bug#42951). This avoids + double-decoding -- once by Emacs when inserting the mbox into the + buffer, and once by Gnus when displaying the articles. + +2021-01-05 Michael Albinus + + * doc/misc/tramp.texi (Quick Start Guide): Fix thinko. + +2021-01-05 Robert Pluim + + Tell people how to remove fontconfig customizations + +2021-01-04 Simen Heggestøyl + + Remove extraneous closing paren + + * doc/lispref/modes.texi (SMIE Indentation Example): Remove extraneous + closing paren. + +2021-01-04 Mauro Aranda + + Update two user option names in the Widget manual + + * doc/misc/widget.texi (Basic Types): The user options + widget-glyph-directory and widget-glyph-enable were renamed long ago + to widget-image-directory and widget-image-enable, but the manual + kept calling them by their old names. Update the names. + +2021-01-03 Paul Eggert + + Mention -lcurses problem on AIX + + * etc/PROBLEMS: Describe problem with Emacs 27 and -lcurses. + Do not merge to master. + +2021-01-03 Paul Eggert + + Revert previous patch which was installed into wrong branch. + +2021-01-03 Paul Eggert + + Fix broken build on AIX 7.2 + + Without this fix, the build on AIX 7.2 with xlc fails in the ‘CCLD + temacs’ step with the diagnostic ‘ld: 0711-317 ERROR: Undefined + symbol: BC’. This is because -lcurses does not define BC etc. + * configure.ac: When building terminfo.o, define + TERMINFO_DEFINES_BC if the library defines BC etc. + * src/terminfo.c (UP, BC, PC): Define depending on + TERMINFO_DEFINES_BC, not on TERMINFO. + +2021-01-02 Eli Zaretskii + + Fix last change + + * doc/lispref/strings.texi (Creating Strings): Improve wording of + last change. (Bug#45516) + +2021-01-02 Lars Ingebrigtsen + + Add a reference between the Strings node and Search/Replace + + * doc/lispref/strings.texi (Creating Strings): Mention + string-replace/replace-regexp-in-string (bug#45516). + + (cherry picked from commit b9359d4183a1a6923122d3aa12b922ab89693354) + +2021-01-01 Eli Zaretskii + + Add warning comments abound binding keys in Isearch maps + + * lisp/isearch.el (isearch-mode-map) + (minibuffer-local-isearch-map): Add comments which warn against + wantonly rebinding unbound keys. + +2021-01-01 Alan Third + + Fix crash in ns_mouse_position (bug#45541) + + * src/nsterm.m (ns_mouse_position): Explicitly initialize f to NULL. + +2021-01-01 Paul Eggert + + Fix copyright years by hand + + These are dates that admin/update-copyright did not update. + +2021-01-01 Paul Eggert + + Update copyright year to 2021 + + Run "TZ=UTC0 admin/update-copyright $(git ls-files)". + +2020-12-31 Eli Zaretskii + + Improve documentation of 'network-lookup-address-info' + + * src/process.c (Fnetwork_lookup_address_info): + * doc/lispref/processes.texi (Misc Network): Document the error + message emitted by 'network-lookup-address-info' when it fails. + +2020-12-28 Amin Bandali + + Display messages sent using ERC's /say + + * lisp/erc/erc.el (erc-cmd-SAY): Call `erc-display-msg' to display the + user's message in the buffer, just like other [non-command] messages. + + https://lists.gnu.org/r/help-gnu-emacs/2020-12/msg00066.html + +2020-12-26 Eli Zaretskii + + Fix Rmail summary display when From: header is malformed + + * lisp/mail/rmailsum.el (rmail-header-summary): Remove newlines + from the "From:" value, to avoid producing corrupted summary + display. + +2020-12-25 Eli Zaretskii + + Add more details to the "word processor" section + + * etc/TODO (Emacs as word processor): Add more details based on + recent discussions. + +2020-12-23 Philipp Stephani + + * src/Makefile.in (DO_CODESIGN): Fix expected architecture name. + +2020-12-23 Itai Seggev (tiny change) + + Codesign the executable on recene MacOS systems + + * src/Makefile.in (temacs$(EXEEXT)): Codesign the executable on + recent (ARM) MacOS systems (bug#43878). Without this, building + Emacs fails. + +2020-12-23 Lars Ingebrigtsen + + Support build of Emacs on ARM Macos machines + + * configure.ac: Add support for aarch64-* on Macos (i.e., 64-bit + ARM) (bug#43369). + +2020-12-22 Bastien Guerry + + Update to Org 9.4.4 + +2020-12-21 Stefan Kangas + + * lisp/so-long.el: Decrease use of passive voice. + + Suggested by Richard Stallman . + +2020-12-21 Stefan Kangas + + * doc/misc/efaq.texi (New in Emacs 27): Add section. + + * doc/misc/efaq.texi (Latest version of Emacs): Bump version. + +2020-12-19 Eli Zaretskii + + * lisp/face-remap.el (face-remap-set-base): Doc fix. (Bug#45264) + +2020-12-19 Vasilij Schneidermann + + Correct argument order in comment + + * etc/ETAGS.EBNF (position): Correct comment. + +2020-12-18 Eli Zaretskii + + Update files for the 27.1.90 pretest + + * README: + * configure.ac: + * nt/README.W32: + * msdos/sed2v2.inp: Bump Emacs version to 27.1.90. + * lisp/ldefs-boot.el: Update from loaddefs.el + 2020-12-18 Eli Zaretskii * README: @@ -144118,7 +144446,7 @@ This file records repository revisions from commit 9d56a21e6a696ad19ac65c4b405aeca44785884a (exclusive) to -commit 48b9c47805fc304441017f6ee4c114212cdb0496 (inclusive). +commit 86a2207d9244f7cbef9f91e697ad5fc0ce49ec97 (inclusive). See ChangeLog.2 for earlier changes. ;; Local Variables: diff --git a/etc/AUTHORS b/etc/AUTHORS index 9694841557..b06b401231 100644 --- a/etc/AUTHORS +++ b/etc/AUTHORS @@ -1454,9 +1454,9 @@ Eli Zaretskii: wrote [bidirectional display in xdisp.c] chartab-tests.el coding-tests.el doc-tests.el etags-tests.el rxvt.el tty-colors.el and changed xdisp.c msdos.c w32.c display.texi w32fns.c simple.el - files.el fileio.c keyboard.c w32term.c emacs.c w32proc.c text.texi - dispnew.c files.texi frames.texi lisp.h dispextern.h window.c term.c - process.c and 1192 other files + files.el fileio.c keyboard.c emacs.c w32term.c text.texi w32proc.c + dispnew.c files.texi frames.texi lisp.h dispextern.h window.c process.c + term.c and 1193 other files Emanuele Giaquinta: changed configure.ac rxvt.el charset.c etags.c fontset.c frame.el gnus-faq.texi loadup.el lread.c sh-script.el @@ -2109,6 +2109,8 @@ Ismail S: changed org-capture.el Istvan Marko: changed gnus-agent.el xfns.c +Itai Seggev: changed src/Makefile.in + Itai Zukerman: changed mm-decode.el Ivan Andrus: changed editfns.c epg.el ffap.el find-file.el ibuf-ext.el @@ -3075,7 +3077,7 @@ and co-wrote gnus-kill.el gnus-mh.el gnus-msg.el gnus-score.el rfc2047.el svg.el time-date.el and changed gnus.texi process.c subr.el simple.el files.el gnutls.c gnus-ems.el smtpmail.el display.texi url-http.el auth-source.el - gnus-cite.el pop3.el dired.el edebug.el gnus-xmas.el text.texi image.el + gnus-cite.el pop3.el dired.el edebug.el text.texi gnus-xmas.el image.el image.c gnutls.el nnrss.el and 658 other files Lars Rasmusson: changed ebrowse.c @@ -3493,10 +3495,10 @@ Matt Swift: changed dired.el editfns.c lisp-mode.el mm-decode.el outline.el progmodes/compile.el rx.el simple.el startup.el Mauro Aranda: changed wid-edit.el cus-edit.el gnus.texi octave.el pong.el - autorevert.el cc-mode.texi control.texi custom-tests.el custom.el - dbus.texi dired-x.texi elisp-mode.el epa.el esh-mode.el + widget.texi autorevert.el cc-mode.texi control.texi custom-tests.el + custom.el dbus.texi dired-x.texi elisp-mode.el epa.el esh-mode.el eshell/eshell.el eudc.texi files.texi functions.texi gnus-faq.texi - info.el and 15 other files + and 15 other files Maxime Edouard Robert Froumentin: changed gnus-art.el mml.el @@ -4745,7 +4747,7 @@ and changed css-mode.el css-mode.css json-tests.el json.el sgml-mode.el scss-mode.scss page.el ring.el rot13.el scheme.el sql.el asm-mode.el autoinsert.el color.el files.el js.el less-css-mode.el less-css-mode.less maintaining.texi makesum.el midnight.el - and 5 other files + and 6 other files Simona Arizanova: changed help.el @@ -4808,7 +4810,7 @@ and changed bookmark.el package.el efaq.texi package.texi ibuffer.el mwheel.el cperl-mode.el fns.c gud.el simple.el subr.el tips.texi autoinsert.el comint-tests.el control.texi cus-edit.el delim-col.el dired-aux.el dired-x.el em-term.el emacs-lisp-intro.texi - and 157 other files + and 158 other files Stefan Merten: co-wrote rst.el @@ -5337,7 +5339,7 @@ Valery Alexeev: changed cyril-util.el cyrillic.el Van L: changed subr.el -Vasilij Schneidermann: changed cus-start.el eww.el cc-mode.el +Vasilij Schneidermann: changed cus-start.el eww.el ETAGS.EBNF cc-mode.el debugging.texi display.texi edebug.el emacs-lisp/debug.el eval.c ielm.el os.texi profiler.el redisplay-testsuite.el shr.el snake.el term.el tetris.el xdisp.c xterm.c diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index 7d4c7b84bf..f0dc2680d3 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -29364,7 +29364,9 @@ variable `feedmail-deduce-envelope-from'.") (defvar mail-self-blind nil "\ Non-nil means insert Bcc to self in messages to be sent. This is done when the message is initialized, -so you can remove or alter the Bcc field to override the default.") +so you can remove or alter the Bcc field to override the default. +If you are using `message-mode' to compose messages, customize the +variable `message-default-mail-headers' instead.") (custom-autoload 'mail-self-blind "sendmail" t) @@ -29392,14 +29394,18 @@ Line used to separate headers from text in messages being composed.") (defvar mail-archive-file-name nil "\ Name of file to write all outgoing messages in, or nil for none. This is normally an mbox file, but for backwards compatibility may also -be a Babyl file.") +be a Babyl file. +If you are using `message-mode' to compose messages, customize the +variable `message-default-mail-headers' instead.") (custom-autoload 'mail-archive-file-name "sendmail" t) (defvar mail-default-reply-to nil "\ Address to insert as default Reply-To field of outgoing messages. If nil, it will be initialized from the REPLYTO environment variable -when you first send mail.") +when you first send mail. +If you are using `message-mode' to compose messages, customize the +variable `message-default-mail-headers' instead.") (custom-autoload 'mail-default-reply-to "sendmail" t) @@ -29486,7 +29492,9 @@ in `message-auto-save-directory'.") (defvar mail-default-headers nil "\ A string containing header lines, to be inserted in outgoing messages. It can contain newlines, and should end in one. It is inserted -before you edit the message, so you can edit or delete the lines.") +before you edit the message, so you can edit or delete the lines. +If you are using `message-mode' to compose messages, customize the +variable `message-default-mail-headers' instead.") (custom-autoload 'mail-default-headers "sendmail" t) @@ -29633,6 +29641,13 @@ sorted. FUNCTION must be a function of one argument. \(fn FUNCTION PRED SEQUENCE)" nil nil) +(autoload 'seq-concatenate "seq" "\ +Concatenate SEQUENCES into a single sequence of type TYPE. +TYPE must be one of following symbols: vector, string or list. + + +\(fn TYPE SEQUENCE...)" nil nil) + (autoload 'seq-filter "seq" "\ Return a list of all the elements for which (PRED element) is non-nil in SEQUENCE. @@ -38637,10 +38652,19 @@ Zone out, completely." t nil) ;;;;;; "eshell/em-unix.el" "eshell/em-xtra.el" "facemenu.el" "faces.el" ;;;;;; "files.el" "font-core.el" "font-lock.el" "format.el" "frame.el" ;;;;;; "help.el" "hfy-cmap.el" "ibuf-ext.el" "indent.el" "international/characters.el" -;;;;;; "international/charscript.el" "international/cp51932.el" -;;;;;; "international/eucjp-ms.el" "international/mule-cmds.el" -;;;;;; "international/mule-conf.el" "international/mule.el" "isearch.el" -;;;;;; "jit-lock.el" "jka-cmpr-hook.el" "language/burmese.el" "language/cham.el" +;;;;;; "international/charprop.el" "international/charscript.el" +;;;;;; "international/cp51932.el" "international/eucjp-ms.el" "international/mule-cmds.el" +;;;;;; "international/mule-conf.el" "international/mule.el" "international/uni-bidi.el" +;;;;;; "international/uni-brackets.el" "international/uni-category.el" +;;;;;; "international/uni-combining.el" "international/uni-comment.el" +;;;;;; "international/uni-decimal.el" "international/uni-decomposition.el" +;;;;;; "international/uni-digit.el" "international/uni-lowercase.el" +;;;;;; "international/uni-mirrored.el" "international/uni-name.el" +;;;;;; "international/uni-numeric.el" "international/uni-old-name.el" +;;;;;; "international/uni-special-lowercase.el" "international/uni-special-titlecase.el" +;;;;;; "international/uni-special-uppercase.el" "international/uni-titlecase.el" +;;;;;; "international/uni-uppercase.el" "isearch.el" "jit-lock.el" +;;;;;; "jka-cmpr-hook.el" "language/burmese.el" "language/cham.el" ;;;;;; "language/chinese.el" "language/cyrillic.el" "language/czech.el" ;;;;;; "language/english.el" "language/ethiopic.el" "language/european.el" ;;;;;; "language/georgian.el" "language/greek.el" "language/hebrew.el" commit 86a2207d9244f7cbef9f91e697ad5fc0ce49ec97 Author: Eli Zaretskii Date: Fri Jan 29 07:02:59 2021 -0500 Bump Emacs version to 27.1.91 * README: * configure.ac: * nt/README.W32: * msdos/sed2v2.inp: Bump Emacs version to 27.1.91. diff --git a/README b/README index 7c4c75cf0a..653d3665b7 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ Copyright (C) 2001-2021 Free Software Foundation, Inc. See the end of the file for license conditions. -This directory tree holds version 27.1.90 of GNU Emacs, the extensible, +This directory tree holds version 27.1.91 of GNU Emacs, the extensible, customizable, self-documenting real-time display editor. The file INSTALL in this directory says how to build and install GNU diff --git a/configure.ac b/configure.ac index 48e96529ff..3e4e0641ac 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ dnl along with GNU Emacs. If not, see . AC_PREREQ(2.65) dnl Note this is parsed by (at least) make-dist and lisp/cedet/ede/emacs.el. -AC_INIT(GNU Emacs, 27.1.90, bug-gnu-emacs@gnu.org, , https://www.gnu.org/software/emacs/) +AC_INIT(GNU Emacs, 27.1.91, bug-gnu-emacs@gnu.org, , https://www.gnu.org/software/emacs/) dnl Set emacs_config_options to the options of 'configure', quoted for the shell, dnl and then quoted again for a C string. Separate options with spaces. diff --git a/msdos/sed2v2.inp b/msdos/sed2v2.inp index 80cf7eb253..04ecee1706 100644 --- a/msdos/sed2v2.inp +++ b/msdos/sed2v2.inp @@ -66,7 +66,7 @@ /^#undef PACKAGE_NAME/s/^.*$/#define PACKAGE_NAME ""/ /^#undef PACKAGE_STRING/s/^.*$/#define PACKAGE_STRING ""/ /^#undef PACKAGE_TARNAME/s/^.*$/#define PACKAGE_TARNAME ""/ -/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "27.1.90"/ +/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "27.1.91"/ /^#undef SYSTEM_TYPE/s/^.*$/#define SYSTEM_TYPE "ms-dos"/ /^#undef HAVE_DECL_GETENV/s/^.*$/#define HAVE_DECL_GETENV 1/ /^#undef SYS_SIGLIST_DECLARED/s/^.*$/#define SYS_SIGLIST_DECLARED 1/ diff --git a/nt/README.W32 b/nt/README.W32 index b168bc2dbc..a93d780055 100644 --- a/nt/README.W32 +++ b/nt/README.W32 @@ -1,7 +1,7 @@ Copyright (C) 2001-2021 Free Software Foundation, Inc. See the end of the file for license conditions. - Emacs version 27.1.90 for MS-Windows + Emacs version 27.1.91 for MS-Windows This README file describes how to set up and run a precompiled distribution of the latest version of GNU Emacs for MS-Windows. You commit 75eb2d0e850352bef1afe052315de63817b2070b Author: Eli Zaretskii Date: Fri Jan 29 13:52:31 2021 +0200 Support 'operating-system-release' on MS-Windows * src/w32fns.c (w32_version_string) [WINDOWSNT]: New function. * src/w32common.h (w32_version_string) [WINDOWSNT]: Add prototype. * src/editfns.c (init_editfns) [WINDOWSNT]: Produce a non-nil string with the OS version. diff --git a/src/editfns.c b/src/editfns.c index 3c2a858b46..e3285494c1 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -52,6 +52,9 @@ along with GNU Emacs. If not, see . */ #include "window.h" #include "blockinput.h" +#ifdef WINDOWSNT +# include "w32common.h" +#endif static void update_buffer_properties (ptrdiff_t, ptrdiff_t); static Lisp_Object styled_format (ptrdiff_t, Lisp_Object *, bool); @@ -121,12 +124,14 @@ init_editfns (void) else if (NILP (Vuser_full_name)) Vuser_full_name = build_string ("unknown"); -#ifdef HAVE_SYS_UTSNAME_H +#if defined HAVE_SYS_UTSNAME_H { struct utsname uts; uname (&uts); Voperating_system_release = build_string (uts.release); } +#elif defined WINDOWSNT + Voperating_system_release = build_string (w32_version_string ()); #else Voperating_system_release = Qnil; #endif diff --git a/src/w32common.h b/src/w32common.h index 94bb457e59..714a2386a6 100644 --- a/src/w32common.h +++ b/src/w32common.h @@ -50,6 +50,11 @@ extern int os_subtype; /* Cache system info, e.g., the NT page size. */ extern void cache_system_info (void); +#ifdef WINDOWSNT +/* Return a static buffer with the MS-Windows version string. */ +extern char * w32_version_string (void); +#endif + typedef void (* VOIDFNPTR) (void); /* Load a function address from a DLL. Cast the result via VOIDFNPTR diff --git a/src/w32fns.c b/src/w32fns.c index 7519c752b6..e93a0b85d9 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -9480,6 +9480,18 @@ cache_system_info (void) w32_num_mouse_buttons = GetSystemMetrics (SM_CMOUSEBUTTONS); } +#ifdef WINDOWSNT +char * +w32_version_string (void) +{ + /* NNN.NNN.NNNNNNNNNN */ + static char version_string[3 + 1 + 3 + 1 + 10 + 1]; + _snprintf (version_string, sizeof version_string, "%d.%d.%d", + w32_major_version, w32_minor_version, w32_build_number); + return version_string; +} +#endif + #ifdef EMACSDEBUG void _DebPrint (const char *fmt, ...) commit 83591e1aec86530e0d293df3078760838f37679a Author: Michael Albinus Date: Fri Jan 29 12:25:36 2021 +0100 * test/lisp/net/tramp-tests.el (tramp--test-special-characters): Adapt test for docker. diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 6467c7ee21..19a40fdf06 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -6037,13 +6037,13 @@ This requires restrictions of file name syntax." (let ((files (list (cond ((or (tramp--test-ange-ftp-p) + (tramp--test-docker-p) (tramp--test-gvfs-p) (tramp--test-rclone-p) (tramp--test-sudoedit-p) (tramp--test-windows-nt-or-smb-p)) "foo bar baz") ((or (tramp--test-adb-p) - (tramp--test-docker-p) (eq system-type 'cygwin)) " foo bar baz ") ((tramp--test-sh-no-ls--dired-p) commit 840b1c66b4a686763c9288de8efb7ec48ccf06da Author: Juri Linkov Date: Fri Jan 29 10:55:16 2021 +0200 Use save-mark-and-excursion in query-replace-read-args (bug#45617) diff --git a/lisp/replace.el b/lisp/replace.el index cbf24bedef..f13d27aff8 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -343,14 +343,15 @@ Prompt with PROMPT. REGEXP-FLAG non-nil means the response should a regexp." (defun query-replace-read-args (prompt regexp-flag &optional noerror) (unless noerror (barf-if-buffer-read-only)) - (let* ((from (query-replace-read-from prompt regexp-flag)) - (to (if (consp from) (prog1 (cdr from) (setq from (car from))) - (query-replace-read-to from prompt regexp-flag)))) - (list from to - (or (and current-prefix-arg (not (eq current-prefix-arg '-))) - (and (plist-member (text-properties-at 0 from) 'isearch-regexp-function) - (get-text-property 0 'isearch-regexp-function from))) - (and current-prefix-arg (eq current-prefix-arg '-))))) + (save-mark-and-excursion + (let* ((from (query-replace-read-from prompt regexp-flag)) + (to (if (consp from) (prog1 (cdr from) (setq from (car from))) + (query-replace-read-to from prompt regexp-flag)))) + (list from to + (or (and current-prefix-arg (not (eq current-prefix-arg '-))) + (and (plist-member (text-properties-at 0 from) 'isearch-regexp-function) + (get-text-property 0 'isearch-regexp-function from))) + (and current-prefix-arg (eq current-prefix-arg '-)))))) (defun query-replace (from-string to-string &optional delimited start end backward region-noncontiguous-p) "Replace some occurrences of FROM-STRING with TO-STRING. commit 4ce5646d592c8d998d066d56108e6dd92372e22b Author: Michael Albinus Date: Fri Jan 29 09:44:31 2021 +0100 Fix Bug#45518 in compile.el * lisp/progmodes/compile.el (compilation-get-file-structure): Avoid call of `file-truename' for remote files. (Bug#45518) diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index 94e4f3c6fa..2c1e6ff52e 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -3041,7 +3041,12 @@ TRUE-DIRNAME is the `file-truename' of DIRNAME, if given." ;; Get the specified directory from FILE. (spec-directory (if (cdr file) - (file-truename (concat comint-file-name-prefix (cdr file)))))) + ;; This function is active in `compilation-filter'. + ;; There could be problems to call `file-truename' + ;; for remote compilation processes. + (if (file-remote-p default-directory) + (concat comint-file-name-prefix (cdr file)) + (file-truename (concat comint-file-name-prefix (cdr file))))))) ;; Check for a comint-file-name-prefix and prepend it if appropriate. ;; (This is very useful for compilation-minor-mode in an rlogin-mode commit ae2e2b6acdf9c052b726c45507945ff0a824db91 Author: Eli Zaretskii Date: Fri Jan 29 09:45:13 2021 +0200 Improve doc string of 'operating-system-release' * src/editfns.c (syms_of_editfns) : Doc fix. (Bug#39940) diff --git a/src/editfns.c b/src/editfns.c index 3b2876f01e..3c2a858b46 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -4479,7 +4479,9 @@ functions if all the text being accessed has this property. */); doc: /* The user's name, based upon the real uid only. */); DEFVAR_LISP ("operating-system-release", Voperating_system_release, - doc: /* The operating system kernel version Emacs is running on. */); + doc: /* The kernel version of the operating system on which Emacs is running. +The value is a string. It can also be nil if Emacs doesn't +know how to get the kernel version on the underlying OS. */); DEFVAR_BOOL ("binary-as-unsigned", binary_as_unsigned, commit 19afd6de25eb836014301009620091be6f0012b0 Author: Sean Whitton Date: Fri Jan 29 08:18:52 2021 +0100 Fix previous commit regarding revert-buffer-function * simple.el (shell-command, shell-command-on-region): Set revert-buffer-function buffer-locally, not globally. Also, avoid an unnecessary call to (current-buffer) by taking advantage of the closure (bug#46151). diff --git a/lisp/simple.el b/lisp/simple.el index 64ee042135..742fc5004d 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -3991,9 +3991,9 @@ impose the use of a shell (with its need to quote arguments)." (start-process-shell-command "Shell" buffer command))) (setq mode-line-process '(":%s")) (shell-mode) - (setq revert-buffer-function - (lambda (&rest _) - (async-shell-command command (current-buffer)))) + (setq-local revert-buffer-function + (lambda (&rest _) + (async-shell-command command buffer))) (set-process-sentinel proc #'shell-command-sentinel) ;; Use the comint filter for proper handling of ;; carriage motion (see comint-inhibit-carriage-motion). @@ -4260,9 +4260,9 @@ characters." buffer)))) ;; Report the output. (with-current-buffer buffer - (setq revert-buffer-function - (lambda (&rest _) - (shell-command command))) + (setq-local revert-buffer-function + (lambda (&rest _) + (shell-command command))) (setq mode-line-process (cond ((null exit-status) " - Error") commit 4e27a260e5886ee9f51877c4e66306e411c195e1 Author: Lars Ingebrigtsen Date: Fri Jan 29 08:16:04 2021 +0100 Describe pointer shapes in the manual * doc/lispref/frames.texi (Pointer Shape): Describe what the typical pointer shapes are (and add `nhdrag') (bug#39246). diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 19c80fad53..9b4716b93d 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -3761,10 +3761,31 @@ for instance using the window manager, then this produces a quit and You can specify the mouse pointer style for particular text or images using the @code{pointer} text property, and for images with the @code{:pointer} and @code{:map} image properties. The values you can -use in these properties are @code{text} (or @code{nil}), @code{arrow}, -@code{hand}, @code{vdrag}, @code{hdrag}, @code{modeline}, and -@code{hourglass}. @code{text} stands for the usual mouse pointer -style used over text. +use in these properties are in the table below. The actual shapes +may vary between systems; the descriptions are examples. + +@table @code +@item text +@itemx nil +The usual mouse pointer style used over text (an ``I''-like shape). + +@item arrow +@itemx vdrag +@itemx modeline +An arrow that points north-west. + +@item hand +A hand that points upwards. + +@item hdrag +A right-left arrow. + +@item nhdrag +An up-down arrow. + +@item hourglass +A rotating ring. +@end table Over void parts of the window (parts that do not correspond to any of the buffer contents), the mouse pointer usually uses the commit d4e9d191aeba9076db06857a90649f6fcddc7f3b Author: Marco Wahl Date: Fri Jan 29 08:01:12 2021 +0100 Add a command for redisplay during keyboard macros * doc/emacs/kmacro.texi (Basic Keyboard Macro): Document it (bug#39252). * lisp/kmacro.el (kdb-macro-redisplay): New function. (kmacro-keymap): Bind it. diff --git a/doc/emacs/kmacro.texi b/doc/emacs/kmacro.texi index adb2ab8d56..e713c6ef8c 100644 --- a/doc/emacs/kmacro.texi +++ b/doc/emacs/kmacro.texi @@ -179,6 +179,14 @@ itself counts as the first repetition, since it is executed as you define it, so @kbd{C-u 4 C-x )} executes the macro immediately 3 additional times. +@findex kdb-macro-redisplay +@kindex C-x C-k Q + While executing a long-running keyboard macro, it can sometimes be +useful to trigger a redisplay (to show how far we've gotten). The +@kbd{C-x C-k Q} can be used for this. As a not very useful example, +@kbd{C-x ( M-f C-x C-k Q C-x )} will create a macro that will +redisplay once per iteration when saying @kbd{C-u 42 C-x e}. + @node Keyboard Macro Ring @section The Keyboard Macro Ring diff --git a/etc/NEWS b/etc/NEWS index f12c94d649..8e233f8f19 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1577,6 +1577,9 @@ This allows mode-specific alterations to how `thing-at-point' works. ** Miscellaneous ++++ +*** New command `C-x C-k Q' to force redisplay in keyboard macros. + --- *** New user option 'remember-diary-regexp'. diff --git a/lisp/kmacro.el b/lisp/kmacro.el index bb8dacf4f4..303f38a59b 100644 --- a/lisp/kmacro.el +++ b/lisp/kmacro.el @@ -172,6 +172,7 @@ macro to be executed before appending to it." (define-key map "\C-k" 'kmacro-end-or-call-macro-repeat) (define-key map "r" 'apply-macro-to-region-lines) (define-key map "q" 'kbd-macro-query) ;; Like C-x q + (define-key map "Q" 'kdb-macro-redisplay) ;; macro ring (define-key map "\C-n" 'kmacro-cycle-ring-next) @@ -1298,6 +1299,16 @@ To customize possible responses, change the \"bindings\" in (kmacro-push-ring) (setq last-kbd-macro kmacro-step-edit-new-macro)))) +(defun kdb-macro-redisplay () + "Force redisplay during kbd macro execution." + (interactive) + (or executing-kbd-macro + defining-kbd-macro + (user-error "Not defining or executing kbd macro")) + (when executing-kbd-macro + (let ((executing-kbd-macro nil)) + (redisplay)))) + (provide 'kmacro) ;;; kmacro.el ends here commit 1275dc4711af77c9c223063dcd149d782d497463 Author: Lars Ingebrigtsen Date: Fri Jan 29 07:40:06 2021 +0100 Improve fontifying of #| ... |# in `lisp-mode' * lisp/emacs-lisp/lisp-mode.el (lisp-mode): Fontify the end delimiter in #| ... |# correctly (bug#39820). diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index c96d849d44..3918fa01b2 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -775,6 +775,7 @@ or to switch back to an existing one." (setq-local find-tag-default-function 'lisp-find-tag-default) (setq-local comment-start-skip "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *") + (setq-local comment-end "|#") (setq imenu-case-fold-search t)) (defun lisp-find-tag-default () commit 3f92d0093246c6f17f04f97282f95c81a398ea30 Author: Lars Ingebrigtsen Date: Fri Jan 29 07:22:14 2021 +0100 operating-system-release doc string improvement * src/editfns.c (syms_of_editfns): Be more precise about what `operating-system-release' is (bug#39940). diff --git a/src/editfns.c b/src/editfns.c index 6f04c99891..3b2876f01e 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -4479,7 +4479,7 @@ functions if all the text being accessed has this property. */); doc: /* The user's name, based upon the real uid only. */); DEFVAR_LISP ("operating-system-release", Voperating_system_release, - doc: /* The release of the operating system Emacs is running on. */); + doc: /* The operating system kernel version Emacs is running on. */); DEFVAR_BOOL ("binary-as-unsigned", binary_as_unsigned, commit 9fb859010fa624f4b63ad4a1a8ba22a0f64f16f2 Author: Lars Ingebrigtsen Date: Fri Jan 29 07:15:35 2021 +0100 flymake-diagnostic-beg/end doc string and error reporting improvement * lisp/progmodes/flymake.el (flymake-diagnostic-beg): (flymake-diagnostic-end): Improve doc string and error reporting (bug#39971). diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index 460af718aa..5d96c62b41 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -352,12 +352,20 @@ diagnostics at BEG." (flymake--diag-accessor flymake-diagnostic-data flymake--diag-data backend) (defun flymake-diagnostic-beg (diag) - "Get Flymake diagnostic DIAG's start position." - (overlay-start (flymake--diag-overlay diag))) + "Get Flymake diagnostic DIAG's start position. +This position only be queried after DIAG has been reported to Flymake." + (let ((overlay (flymake--diag-overlay diag))) + (unless overlay + (error "DIAG %s not reported to Flymake yet" diag)) + (overlay-start overlay))) (defun flymake-diagnostic-end (diag) - "Get Flymake diagnostic DIAG's end position." - (overlay-end (flymake--diag-overlay diag))) + "Get Flymake diagnostic DIAG's end position. +This position only be queried after DIAG has been reported to Flymake." + (let ((overlay (flymake--diag-overlay diag))) + (unless overlay + (error "DIAG %s not reported to Flymake yet" diag)) + (overlay-end overlay))) (cl-defun flymake--overlays (&key beg end filter compare key) "Get flymake-related overlays. commit 0b80935d37f4a089ee7e925e246622dcd4b1addb Author: Lars Ingebrigtsen Date: Fri Jan 29 07:04:43 2021 +0100 Fix position in empty buffers in checkdoc-file-comments-engine * lisp/emacs-lisp/checkdoc.el (checkdoc-file-comments-engine): Don't give invalid positions on empty buffers (bug#39987). diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index 76638ec13b..9722792a5a 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -2362,7 +2362,9 @@ Code:, and others referenced in the style guide." (checkdoc-create-error (format "The footer should be: (provide '%s)\\n;;; %s%s ends here" fn fn fe) - (1- (point-max)) (point-max))))) + ;; The buffer may be empty. + (max (point-min) (1- (point-max))) + (point-max))))) err)) ;; The below checks will not return errors if the user says NO commit 5f650422e4a4c44ffc5ee0be4ec969765a307c7b Author: Sean Whitton Date: Fri Jan 29 06:50:38 2021 +0100 Set revert-buffer-function in shell command output buffers * simple.el (shell-command, shell-command-on-region): Set revert-buffer-function in shell command output buffers (bug#46151). diff --git a/lisp/simple.el b/lisp/simple.el index e82b138b0d..64ee042135 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -3991,6 +3991,9 @@ impose the use of a shell (with its need to quote arguments)." (start-process-shell-command "Shell" buffer command))) (setq mode-line-process '(":%s")) (shell-mode) + (setq revert-buffer-function + (lambda (&rest _) + (async-shell-command command (current-buffer)))) (set-process-sentinel proc #'shell-command-sentinel) ;; Use the comint filter for proper handling of ;; carriage motion (see comint-inhibit-carriage-motion). @@ -4257,6 +4260,9 @@ characters." buffer)))) ;; Report the output. (with-current-buffer buffer + (setq revert-buffer-function + (lambda (&rest _) + (shell-command command))) (setq mode-line-process (cond ((null exit-status) " - Error") commit de51d94721efb90b153d70dc15691c16d0fbb46a Author: Lars Ingebrigtsen Date: Fri Jan 29 06:46:14 2021 +0100 Mention using buffer-list-update-hook in recentf-mode * lisp/recentf.el (recentf-mode): Mention using `buffer-list-update-hook' (bug#46153). diff --git a/lisp/recentf.el b/lisp/recentf.el index a28a3977a7..d39a523289 100644 --- a/lisp/recentf.el +++ b/lisp/recentf.el @@ -1352,7 +1352,14 @@ That is, remove duplicates, non-kept, and excluded files." When Recentf mode is enabled, a \"Open Recent\" submenu is displayed in the \"File\" menu, containing a list of files that -were operated on recently, in the most-recently-used order." +were operated on recently, in the most-recently-used order. + +By default, only operations like opening a file, writing a buffer +to a file, and killing a buffer is counted as \"operating\" on +the file. If instead you want to prioritize files that appear in +buffers you switch to a lot, you can say something like the following: + + (add-hook 'buffer-list-update-hook 'recentf-track-opened-file)" :global t :group 'recentf :keymap recentf-mode-map commit e52f2ec968a73a3f29939cf62d67a5ffe811ee09 Author: Stefan Kangas Date: Fri Jan 29 04:43:57 2021 +0100 Remove Emacs 21 compat code from sasl.el * lisp/net/sasl.el (sasl-read-passphrase): Remove compat code; 'read-passwd' is preloaded since Emacs 22. diff --git a/lisp/net/sasl.el b/lisp/net/sasl.el index 7f0431afb6..d2e08f7e3e 100644 --- a/lisp/net/sasl.el +++ b/lisp/net/sasl.el @@ -161,15 +161,8 @@ the current challenge. At the first time STEP should be set to nil." (if function (vector function (funcall function client step))))) -(defvar sasl-read-passphrase nil) +(defvar sasl-read-passphrase 'read-passwd) (defun sasl-read-passphrase (prompt) - (if (not sasl-read-passphrase) - (if (functionp 'read-passwd) - (setq sasl-read-passphrase 'read-passwd) - (if (load "passwd" t) - (setq sasl-read-passphrase 'read-passwd) - (autoload 'ange-ftp-read-passwd "ange-ftp") - (setq sasl-read-passphrase 'ange-ftp-read-passwd)))) (funcall sasl-read-passphrase prompt)) (defun sasl-unique-id () commit a27512e21c710ab39a0b811701a952db482204c1 Author: Stefan Kangas Date: Fri Jan 29 02:55:34 2021 +0100 * lisp/flow-ctrl.el: Use lexical-binding. * lisp/flow-ctrl.el (enable-flow-control): Minor cleanup. diff --git a/lisp/flow-ctrl.el b/lisp/flow-ctrl.el index 656edf2eb0..adb52d7253 100644 --- a/lisp/flow-ctrl.el +++ b/lisp/flow-ctrl.el @@ -1,4 +1,4 @@ -;;; flow-ctrl.el --- help for lusers on cu(1) or ttys with wired-in ^S/^Q flow control +;;; flow-ctrl.el --- help for lusers on cu(1) or ttys with wired-in ^S/^Q flow control -*- lexical-binding: t -*- ;; Copyright (C) 1990-1991, 1994, 2001-2021 Free Software Foundation, ;; Inc. @@ -64,12 +64,11 @@ With arg, enable flow control mode if arg is positive, otherwise disable." (progn ;; Turn flow control off, and stop exchanging chars. (set-input-mode t nil (nth 2 (current-input-mode))) - (if keyboard-translate-table - (progn - (aset keyboard-translate-table flow-control-c-s-replacement nil) - (aset keyboard-translate-table ?\^s nil) - (aset keyboard-translate-table flow-control-c-q-replacement nil) - (aset keyboard-translate-table ?\^q nil)))) + (when keyboard-translate-table + (aset keyboard-translate-table flow-control-c-s-replacement nil) + (aset keyboard-translate-table ?\^s nil) + (aset keyboard-translate-table flow-control-c-q-replacement nil) + (aset keyboard-translate-table ?\^q nil))) ;; Turn flow control on. ;; Tell emacs to pass C-s and C-q to OS. (set-input-mode nil t (nth 2 (current-input-mode))) commit bab133e6d0bff03e5ddd7f43eca169f4843d5860 Author: Stefan Kangas Date: Fri Jan 29 02:47:38 2021 +0100 Use lexical-binding in find-cmd.el and add tests * lisp/find-cmd.el: Use lexical-binding. * test/lisp/find-cmd-tests.el: New file. diff --git a/lisp/find-cmd.el b/lisp/find-cmd.el index 5866b30855..bb2e97d866 100644 --- a/lisp/find-cmd.el +++ b/lisp/find-cmd.el @@ -1,4 +1,4 @@ -;;; find-cmd.el --- Build a valid find(1) command with sexps +;;; find-cmd.el --- Build a valid find(1) command with sexps -*- lexical-binding: t -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. @@ -28,7 +28,7 @@ ;; (find-cmd '(prune (name ".svn" ".git" ".CVS")) ;; '(and (or (name "*.pl" "*.pm" "*.t") ;; (mtime "+1")) -;; (fstype "nfs" "ufs")))) +;; (fstype "nfs" "ufs"))) ;; will become (un-wrapped): diff --git a/test/lisp/find-cmd-tests.el b/test/lisp/find-cmd-tests.el new file mode 100644 index 0000000000..b8e0f27398 --- /dev/null +++ b/test/lisp/find-cmd-tests.el @@ -0,0 +1,45 @@ +;;; find-cmd-tests.el --- tests for find-cmd.el. -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Code: + +(require 'ert) +(require 'find-cmd) + +(ert-deftest find-cmd-test-find-cmd () + (should + (string-match + (rx "find " (+ any) + " \\( \\( -name .svn -or -name .git -or -name .CVS \\)" + " -prune -or -true \\)" + " \\( \\( \\(" " -name \\*.pl -or -name \\*.pm -or -name \\*.t \\)" + " -or -mtime \\+1 \\) -and \\( -fstype nfs -or -fstype ufs \\) \\) ") + (find-cmd '(prune (name ".svn" ".git" ".CVS")) + '(and (or (name "*.pl" "*.pm" "*.t") + (mtime "+1")) + (fstype "nfs" "ufs")))))) + +(ert-deftest find-cmd-test-find-cmd/error-unknown-atom () + (should-error (find-cmd '(unknown 123)))) + +(ert-deftest find-cmd-test-find-cmd/error-wrong-argnum () + (should-error (find-cmd '(name)))) + +(provide 'find-cmd-tests) +;;; find-cmd-tests.el ends here commit 3ddea271cc9542e29829629991a4073ab3cf5db9 Author: Lars Ingebrigtsen Date: Fri Jan 29 05:52:51 2021 +0100 Slight gravatar.el code clean up * lisp/image/gravatar.el (gravatar--service-libravatar): Clean the code up slightly. diff --git a/lisp/image/gravatar.el b/lisp/image/gravatar.el index b1e2a314ce..f6f056a2ba 100644 --- a/lisp/image/gravatar.el +++ b/lisp/image/gravatar.el @@ -167,13 +167,12 @@ to track whether you're reading a specific mail." ;; ignore). (and (eq (dns-get 'type answers) 'SRV) answers))) - (priorities (and (mapcar (lambda (r) - (dns-get 'priority r)) - data))) - (max-priority (if priorities - (apply #'max priorities) - 0)) - (sum 0) top) + (priorities (mapcar (lambda (r) + (dns-get 'priority r)) + data)) + (max-priority (apply #'max 0 priorities)) + (sum 0) + top) ;; Attempt to find all records with the same maximal ;; priority, and calculate the sum of their weights. (dolist (ent data) commit 887b03386fd5925ef5d74404ee6cc18e2257cff6 Merge: 991c8946b6 cb97581870 Author: Stefan Monnier Date: Thu Jan 28 18:10:29 2021 -0500 Merge branch 'master' of git+ssh://git.sv.gnu.org/srv/git/emacs into trunk commit cb97581870cb1e3c211e4cead5f14f6cb67e4c8f Author: Stefan Kangas Date: Thu Jan 28 22:06:35 2021 +0100 Use lexical-binding in nroff-mode.el * lisp/textmodes/nroff-mode.el: Use lexical-binding. Remove redundant :group args. diff --git a/lisp/textmodes/nroff-mode.el b/lisp/textmodes/nroff-mode.el index 896578513c..fe70e925b0 100644 --- a/lisp/textmodes/nroff-mode.el +++ b/lisp/textmodes/nroff-mode.el @@ -1,4 +1,4 @@ -;;; nroff-mode.el --- GNU Emacs major mode for editing nroff source +;;; nroff-mode.el --- GNU Emacs major mode for editing nroff source -*- lexical-binding: t -*- ;; Copyright (C) 1985-1986, 1994-1995, 1997, 2001-2021 Free Software ;; Foundation, Inc. @@ -43,7 +43,6 @@ (defcustom nroff-electric-mode nil "Non-nil means automatically closing requests when you insert an open." - :group 'nroff :type 'boolean) (defvar nroff-mode-map @@ -111,7 +110,7 @@ ;; arguments in common cases, like \f. (concat "\\\\" ; backslash "\\(" ; followed by various possibilities - (mapconcat 'identity + (mapconcat #'identity '("[f*n]*\\[.+?]" ; some groff extensions "(.." ; two chars after ( "[^(\"#]" ; single char escape @@ -119,13 +118,11 @@ "\\)") ) "Font-lock highlighting control in `nroff-mode'." - :group 'nroff :type '(repeat regexp)) (defcustom nroff-mode-hook nil "Hook run by function `nroff-mode'." - :type 'hook - :group 'nroff) + :type 'hook) ;;;###autoload (define-derived-mode nroff-mode text-mode "Nroff" commit a50fe43337eef4b287784527f33cceab4f9ab30c Author: Stefan Kangas Date: Thu Jan 28 21:45:26 2021 +0100 * lisp/progmodes/bat-mode.el: Use lexical-binding. diff --git a/lisp/progmodes/bat-mode.el b/lisp/progmodes/bat-mode.el index 44295c3f67..7ba8a69775 100644 --- a/lisp/progmodes/bat-mode.el +++ b/lisp/progmodes/bat-mode.el @@ -1,4 +1,4 @@ -;;; bat-mode.el --- Major mode for editing DOS/Windows scripts +;;; bat-mode.el --- Major mode for editing DOS/Windows scripts -*- lexical-binding: t -*- ;; Copyright (C) 2003, 2008-2021 Free Software Foundation, Inc. commit ae7fe263b28cc87f5d8c8770b7d321ff436a12bb Author: Stefan Kangas Date: Thu Jan 28 21:55:31 2021 +0100 ; Fix my previous commit * lisp/generic-x.el (generic-mode-ini-file-find-file-hook): Fix my previous commit; for some reason 'function' produces a warning here while 'quote' does not. diff --git a/lisp/generic-x.el b/lisp/generic-x.el index be8d41bde0..4c6e118900 100644 --- a/lisp/generic-x.el +++ b/lisp/generic-x.el @@ -412,7 +412,7 @@ like an INI file. You can add this hook to `find-file-hook'." (and (looking-at "^\\s-*\\[.*\\]") (ini-generic-mode))))) (define-obsolete-function-alias 'generic-mode-ini-file-find-file-hook - #'ini-generic-mode-find-file-hook "28.1")) + 'ini-generic-mode-find-file-hook "28.1")) ;;; Windows REG files ;;; Unfortunately, Windows 95 and Windows NT have different REG file syntax! commit 554ec932ba37e0191df33959abaec9e1bfdaa891 Author: Stefan Kangas Date: Thu Jan 28 21:35:34 2021 +0100 Use lexical-binding in generic-x.el * lisp/generic-x.el: Use lexical-binding. Remove redundant :groups. (generic-rul-mode-setup-function): Prefer setq-local. diff --git a/lisp/generic-x.el b/lisp/generic-x.el index 0063cb73b3..be8d41bde0 100644 --- a/lisp/generic-x.el +++ b/lisp/generic-x.el @@ -1,4 +1,4 @@ -;;; generic-x.el --- A collection of generic modes +;;; generic-x.el --- A collection of generic modes -*- lexical-binding: t -*- ;; Copyright (C) 1997-1998, 2001-2021 Free Software Foundation, Inc. @@ -121,14 +121,12 @@ "If non-nil, add a hook to enter `default-generic-mode' automatically. This is done if the first few lines of a file in fundamental mode start with a hash comment character." - :group 'generic-x :type 'boolean) (defcustom generic-lines-to-scan 3 "Number of lines that `generic-mode-find-file-hook' looks at. Relevant when deciding whether to enter Default-Generic mode automatically. This variable should be set to a small positive number." - :group 'generic-x :type 'integer) (defcustom generic-find-file-regexp "^#" @@ -137,7 +135,6 @@ Files in fundamental mode whose first few lines contain a match for this regexp, should be put into Default-Generic mode instead. The number of lines tested for the matches is specified by the value of the variable `generic-lines-to-scan', which see." - :group 'generic-x :type 'regexp) (defcustom generic-ignore-files-regexp "[Tt][Aa][Gg][Ss]\\'" @@ -146,7 +143,6 @@ Files whose names match this regular expression should not be put into Default-Generic mode, even if they have lines which match the regexp in `generic-find-file-regexp'. If the value is nil, `generic-mode-find-file-hook' does not check the file names." - :group 'generic-x :type '(choice (const :tag "Don't check file names" nil) regexp)) ;; This generic mode is always defined @@ -249,7 +245,6 @@ This hook will be installed if the variable Each entry in the list should be a symbol. If you set this variable directly, without using customize, you must reload generic-x to put your changes into effect." - :group 'generic-x :type (let (list) (dolist (mode (sort (append generic-default-modes @@ -1298,19 +1293,16 @@ like an INI file. You can add this hook to `find-file-hook'." ;; here manually instead (defun generic-rul-mode-setup-function () - (make-local-variable 'parse-sexp-ignore-comments) - (make-local-variable 'comment-start) (make-local-variable 'comment-start-skip) - (make-local-variable 'comment-end) (setq imenu-generic-expression - '((nil "^function\\s-+\\([A-Za-z0-9_]+\\)" 1)) - parse-sexp-ignore-comments t - comment-end "*/" - comment-start "/*" -;;; comment-end "" -;;; comment-start "//" -;;; comment-start-skip "" - ) + '((nil "^function\\s-+\\([A-Za-z0-9_]+\\)" 1))) + (setq-local parse-sexp-ignore-comments t + comment-end "*/" + comment-start "/*" +;;; comment-end "" +;;; comment-start "//" +;;; comment-start-skip "" + ) ;; (set-syntax-table rul-generic-mode-syntax-table) (setq-local font-lock-syntax-table rul-generic-mode-syntax-table)) @@ -1460,7 +1452,7 @@ like an INI file. You can add this hook to `find-file-hook'." ":" ;; Password, UID and GID (mapconcat - 'identity + #'identity (make-list 3 "\\([^:]+\\)") ":") ":" @@ -1640,8 +1632,7 @@ like an INI file. You can add this hook to `find-file-hook'." (((class color) (min-colors 88)) (:background "red1")) (((class color)) (:background "red")) (t (:weight bold))) - "Font Lock mode face used to highlight TABs." - :group 'generic-x) + "Font Lock mode face used to highlight TABs.") (defface show-tabs-space '((((class grayscale) (background light)) (:background "DimGray" :weight bold)) @@ -1649,8 +1640,7 @@ like an INI file. You can add this hook to `find-file-hook'." (((class color) (min-colors 88)) (:background "yellow1")) (((class color)) (:background "yellow")) (t (:weight bold))) - "Font Lock mode face used to highlight spaces." - :group 'generic-x) + "Font Lock mode face used to highlight spaces.") (define-generic-mode show-tabs-generic-mode nil ;; no comment char commit 11c504c9d2742cd7b19a2ed188b6545c9e86d206 Author: Stefan Kangas Date: Thu Jan 28 21:28:03 2021 +0100 Define compat alias obsolete * lisp/generic-x.el (generic-mode-ini-file-find-file-hook): Define compat alias introduced after rename in 22.1 obsolete. diff --git a/lisp/generic-x.el b/lisp/generic-x.el index bd03f287fc..0063cb73b3 100644 --- a/lisp/generic-x.el +++ b/lisp/generic-x.el @@ -416,7 +416,8 @@ like an INI file. You can add this hook to `find-file-hook'." (goto-char (point-min)) (and (looking-at "^\\s-*\\[.*\\]") (ini-generic-mode))))) -(defalias 'generic-mode-ini-file-find-file-hook 'ini-generic-mode-find-file-hook)) +(define-obsolete-function-alias 'generic-mode-ini-file-find-file-hook + #'ini-generic-mode-find-file-hook "28.1")) ;;; Windows REG files ;;; Unfortunately, Windows 95 and Windows NT have different REG file syntax! commit 991c8946b6e9c87403dc2691100566cb98577de1 Author: Stefan Monnier Date: Thu Jan 28 14:42:21 2021 -0500 Use lexical-binding in all of `lisp/emacs-lisp` * lisp/emacs-lisp/bindat.el: Use lexical-binding. (bindat--unpack-group, bindat--length-group, bindat--pack-group): Declare `last` and `tag` as dyn-scoped. (bindat-unpack, bindat-pack): Bind `bindat-raw` and `bindat-idx` via `let` rather than via the formal arglist. * lisp/emacs-lisp/package-x.el: * lisp/emacs-lisp/generic.el: * lisp/emacs-lisp/eieio-opt.el: * lisp/emacs-lisp/derived.el: * lisp/emacs-lisp/crm.el: Use lexical-binding. * lisp/emacs-lisp/helper.el: Use lexical-binding. (Helper-help-map): Move initialization into declaration. * lisp/emacs-lisp/regi.el: Use lexical-binding. (regi-interpret): Remove unused var `tstart`. Declare `curframe`, `curentry` and `curline` as dyn-scoped. * lisp/emacs-lisp/shadow.el: Use lexical-binding. (load-path-shadows-find): Remove unused var `file`. Tighten a regexp, use `push`. * lisp/emacs-lisp/tcover-ses.el: Use lexical-binding. Require `ses`. Remove correspondingly redundant declarations. (ses--curcell-overlay): Declare. (ses-exercise): Use `dlet` and use a properly-prefixed var name. Fix name of `curcell-overlay` variable. * lisp/emacs-lisp/unsafep.el: Use lexical-binding. (unsafep): Bind `unsafep-vars` via `let` rather than via the formal arglist. diff --git a/admin/notes/unicode b/admin/notes/unicode index d69d5418e2..bcede9c6ed 100644 --- a/admin/notes/unicode +++ b/admin/notes/unicode @@ -267,6 +267,7 @@ nontrivial changes to the build process. lisp/language/tibetan.el lisp/leim/quail/ethiopic.el lisp/leim/quail/tibetan.el + lisp/international/titdic-cnv.el * binary files diff --git a/lisp/emacs-lisp/bindat.el b/lisp/emacs-lisp/bindat.el index 5f432b80bc..0d9ba57d66 100644 --- a/lisp/emacs-lisp/bindat.el +++ b/lisp/emacs-lisp/bindat.el @@ -1,4 +1,4 @@ -;;; bindat.el --- binary data structure packing and unpacking. +;;; bindat.el --- binary data structure packing and unpacking. -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. @@ -198,7 +198,7 @@ (defun bindat--unpack-u8 () (prog1 - (aref bindat-raw bindat-idx) + (aref bindat-raw bindat-idx) (setq bindat-idx (1+ bindat-idx)))) (defun bindat--unpack-u16 () @@ -276,6 +276,8 @@ (t nil))) (defun bindat--unpack-group (spec) + (with-suppressed-warnings ((lexical last)) + (defvar last)) (let (struct last) (while spec (let* ((item (car spec)) @@ -287,11 +289,11 @@ data) (setq spec (cdr spec)) (if (and (consp field) (eq (car field) 'eval)) - (setq field (eval (car (cdr field))))) + (setq field (eval (car (cdr field)) t))) (if (and type (consp type) (eq (car type) 'eval)) - (setq type (eval (car (cdr type))))) + (setq type (eval (car (cdr type)) t))) (if (and len (consp len) (eq (car len) 'eval)) - (setq len (eval (car (cdr len))))) + (setq len (eval (car (cdr len)) t))) (if (memq field '(eval fill align struct union)) (setq tail 2 len type @@ -304,48 +306,51 @@ (cond ((eq type 'eval) (if field - (setq data (eval len)) - (eval len))) + (setq data (eval len t)) + (eval len t))) ((eq type 'fill) (setq bindat-idx (+ bindat-idx len))) ((eq type 'align) (while (/= (% bindat-idx len) 0) (setq bindat-idx (1+ bindat-idx)))) ((eq type 'struct) - (setq data (bindat--unpack-group (eval len)))) + (setq data (bindat--unpack-group (eval len t)))) ((eq type 'repeat) (let ((index 0) (count len)) (while (< index count) - (setq data (cons (bindat--unpack-group (nthcdr tail item)) data)) + (push (bindat--unpack-group (nthcdr tail item)) data) (setq index (1+ index))) (setq data (nreverse data)))) ((eq type 'union) + (with-suppressed-warnings ((lexical tag)) + (defvar tag)) (let ((tag len) (cases (nthcdr tail item)) case cc) (while cases (setq case (car cases) cases (cdr cases) cc (car case)) (if (or (equal cc tag) (equal cc t) - (and (consp cc) (eval cc))) + (and (consp cc) (eval cc t))) (setq data (bindat--unpack-group (cdr case)) cases nil))))) (t (setq data (bindat--unpack-item type len vectype) last data))) (if data - (if field - (setq struct (cons (cons field data) struct)) - (setq struct (append data struct)))))) + (setq struct (if field + (cons (cons field data) struct) + (append data struct)))))) struct)) -(defun bindat-unpack (spec bindat-raw &optional bindat-idx) - "Return structured data according to SPEC for binary data in BINDAT-RAW. -BINDAT-RAW is a unibyte string or vector. -Optional third arg BINDAT-IDX specifies the starting offset in BINDAT-RAW." - (when (multibyte-string-p bindat-raw) +(defun bindat-unpack (spec raw &optional idx) + "Return structured data according to SPEC for binary data in RAW. +RAW is a unibyte string or vector. +Optional third arg IDX specifies the starting offset in RAW." + (when (multibyte-string-p raw) (error "String is multibyte")) - (unless bindat-idx (setq bindat-idx 0)) - (bindat--unpack-group spec)) + (let ((bindat-idx (or idx 0)) + (bindat-raw raw)) + (bindat--unpack-group spec))) (defun bindat-get-field (struct &rest field) "In structured data STRUCT, return value of field named FIELD. @@ -373,6 +378,8 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (ip . 4))) (defun bindat--length-group (struct spec) + (with-suppressed-warnings ((lexical last)) + (defvar last)) (let (last) (while spec (let* ((item (car spec)) @@ -383,32 +390,31 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (tail 3)) (setq spec (cdr spec)) (if (and (consp field) (eq (car field) 'eval)) - (setq field (eval (car (cdr field))))) + (setq field (eval (car (cdr field)) t))) (if (and type (consp type) (eq (car type) 'eval)) - (setq type (eval (car (cdr type))))) + (setq type (eval (car (cdr type)) t))) (if (and len (consp len) (eq (car len) 'eval)) - (setq len (eval (car (cdr len))))) + (setq len (eval (car (cdr len)) t))) (if (memq field '(eval fill align struct union)) (setq tail 2 len type type field field nil)) (if (and (consp len) (not (eq type 'eval))) - (setq len (apply 'bindat-get-field struct len))) + (setq len (apply #'bindat-get-field struct len))) (if (not len) (setq len 1)) (while (eq type 'vec) - (let ((vlen 1)) - (if (consp vectype) - (setq len (* len (nth 1 vectype)) - type (nth 2 vectype)) - (setq type (or vectype 'u8) - vectype nil)))) + (if (consp vectype) + (setq len (* len (nth 1 vectype)) + type (nth 2 vectype)) + (setq type (or vectype 'u8) + vectype nil))) (cond ((eq type 'eval) (if field - (setq struct (cons (cons field (eval len)) struct)) - (eval len))) + (setq struct (cons (cons field (eval len t)) struct)) + (eval len t))) ((eq type 'fill) (setq bindat-idx (+ bindat-idx len))) ((eq type 'align) @@ -416,7 +422,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (setq bindat-idx (1+ bindat-idx)))) ((eq type 'struct) (bindat--length-group - (if field (bindat-get-field struct field) struct) (eval len))) + (if field (bindat-get-field struct field) struct) (eval len t))) ((eq type 'repeat) (let ((index 0) (count len)) (while (< index count) @@ -425,13 +431,15 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (nthcdr tail item)) (setq index (1+ index))))) ((eq type 'union) + (with-suppressed-warnings ((lexical tag)) + (defvar tag)) (let ((tag len) (cases (nthcdr tail item)) case cc) (while cases (setq case (car cases) cases (cdr cases) cc (car case)) (if (or (equal cc tag) (equal cc t) - (and (consp cc) (eval cc))) + (and (consp cc) (eval cc t))) (progn (bindat--length-group struct (cdr case)) (setq cases nil)))))) @@ -536,6 +544,8 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (setq bindat-idx (+ bindat-idx len))))) (defun bindat--pack-group (struct spec) + (with-suppressed-warnings ((lexical last)) + (defvar last)) (let (last) (while spec (let* ((item (car spec)) @@ -546,11 +556,11 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (tail 3)) (setq spec (cdr spec)) (if (and (consp field) (eq (car field) 'eval)) - (setq field (eval (car (cdr field))))) + (setq field (eval (car (cdr field)) t))) (if (and type (consp type) (eq (car type) 'eval)) - (setq type (eval (car (cdr type))))) + (setq type (eval (car (cdr type)) t))) (if (and len (consp len) (eq (car len) 'eval)) - (setq len (eval (car (cdr len))))) + (setq len (eval (car (cdr len)) t))) (if (memq field '(eval fill align struct union)) (setq tail 2 len type @@ -563,8 +573,8 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (cond ((eq type 'eval) (if field - (setq struct (cons (cons field (eval len)) struct)) - (eval len))) + (setq struct (cons (cons field (eval len t)) struct)) + (eval len t))) ((eq type 'fill) (setq bindat-idx (+ bindat-idx len))) ((eq type 'align) @@ -572,7 +582,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (setq bindat-idx (1+ bindat-idx)))) ((eq type 'struct) (bindat--pack-group - (if field (bindat-get-field struct field) struct) (eval len))) + (if field (bindat-get-field struct field) struct) (eval len t))) ((eq type 'repeat) (let ((index 0) (count len)) (while (< index count) @@ -581,13 +591,15 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (nthcdr tail item)) (setq index (1+ index))))) ((eq type 'union) + (with-suppressed-warnings ((lexical tag)) + (defvar tag)) (let ((tag len) (cases (nthcdr tail item)) case cc) (while cases (setq case (car cases) cases (cdr cases) cc (car case)) (if (or (equal cc tag) (equal cc t) - (and (consp cc) (eval cc))) + (and (consp cc) (eval cc t))) (progn (bindat--pack-group struct (cdr case)) (setq cases nil)))))) @@ -596,19 +608,19 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." (bindat--pack-item last type len vectype) )))))) -(defun bindat-pack (spec struct &optional bindat-raw bindat-idx) +(defun bindat-pack (spec struct &optional raw idx) "Return binary data packed according to SPEC for structured data STRUCT. -Optional third arg BINDAT-RAW is a pre-allocated unibyte string or vector to +Optional third arg RAW is a pre-allocated unibyte string or vector to pack into. -Optional fourth arg BINDAT-IDX is the starting offset into BINDAT-RAW." - (when (multibyte-string-p bindat-raw) +Optional fourth arg IDX is the starting offset into RAW." + (when (multibyte-string-p raw) (error "Pre-allocated string is multibyte")) - (let ((no-return bindat-raw)) - (unless bindat-idx (setq bindat-idx 0)) - (unless bindat-raw - (setq bindat-raw (make-string (+ bindat-idx (bindat-length spec struct)) 0))) + (let* ((bindat-idx (or idx 0)) + (bindat-raw + (or raw + (make-string (+ bindat-idx (bindat-length spec struct)) 0)))) (bindat--pack-group struct spec) - (if no-return nil bindat-raw))) + (if raw nil bindat-raw))) ;; Misc. format conversions diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el index eb3193c821..e106815817 100644 --- a/lisp/emacs-lisp/crm.el +++ b/lisp/emacs-lisp/crm.el @@ -1,4 +1,4 @@ -;;; crm.el --- read multiple strings with completion +;;; crm.el --- read multiple strings with completion -*- lexical-binding: t; -*- ;; Copyright (C) 1985-1986, 1993-2021 Free Software Foundation, Inc. diff --git a/lisp/emacs-lisp/derived.el b/lisp/emacs-lisp/derived.el index 42528429aa..54528b2fb9 100644 --- a/lisp/emacs-lisp/derived.el +++ b/lisp/emacs-lisp/derived.el @@ -1,4 +1,4 @@ -;;; derived.el --- allow inheritance of major modes +;;; derived.el --- allow inheritance of major modes -*- lexical-binding: t; -*- ;; (formerly mode-clone.el) ;; Copyright (C) 1993-1994, 1999, 2001-2021 Free Software Foundation, diff --git a/lisp/emacs-lisp/eieio-opt.el b/lisp/emacs-lisp/eieio-opt.el index edf4d34b64..e65f424cba 100644 --- a/lisp/emacs-lisp/eieio-opt.el +++ b/lisp/emacs-lisp/eieio-opt.el @@ -1,4 +1,4 @@ -;;; eieio-opt.el -- eieio optional functions (debug, printing, speedbar) +;;; eieio-opt.el -- eieio optional functions (debug, printing, speedbar) -*- lexical-binding: t; -*- ;; Copyright (C) 1996, 1998-2003, 2005, 2008-2021 Free Software ;; Foundation, Inc. diff --git a/lisp/emacs-lisp/generic.el b/lisp/emacs-lisp/generic.el index 93f780eac2..6db1bbbb22 100644 --- a/lisp/emacs-lisp/generic.el +++ b/lisp/emacs-lisp/generic.el @@ -1,4 +1,4 @@ -;;; generic.el --- defining simple major modes with comment and font-lock +;;; generic.el --- defining simple major modes with comment and font-lock -*- lexical-binding: t; -*- ;; ;; Copyright (C) 1997, 1999, 2001-2021 Free Software Foundation, Inc. ;; @@ -245,7 +245,6 @@ Some generic modes are defined in `generic-x.el'." "Set up comment functionality for generic mode." (let ((chars nil) (comstyles) - (comstyle "") (comment-start nil)) ;; Go through all the comments. @@ -269,14 +268,16 @@ Some generic modes are defined in `generic-x.el'." ;; Store the relevant info but don't update yet. (push (cons c0 (concat (cdr (assoc c0 chars)) "1")) chars) (push (cons c1 (concat (cdr (assoc c1 chars)) - (concat "2" comstyle))) chars))) + (concat "2" comstyle))) + chars))) (if (= (length end) 1) (modify-syntax-entry (aref end 0) (concat ">" comstyle) st) (let ((c0 (aref end 0)) (c1 (aref end 1))) ;; Store the relevant info but don't update yet. (push (cons c0 (concat (cdr (assoc c0 chars)) - (concat "3" comstyle))) chars) + (concat "3" comstyle))) + chars) (push (cons c1 (concat (cdr (assoc c1 chars)) "4")) chars))))) ;; Process the chars that were part of a 2-char comment marker diff --git a/lisp/emacs-lisp/helper.el b/lisp/emacs-lisp/helper.el index 737f3ec2f3..a5f21a5592 100644 --- a/lisp/emacs-lisp/helper.el +++ b/lisp/emacs-lisp/helper.el @@ -1,4 +1,4 @@ -;;; helper.el --- utility help package supporting help in electric modes +;;; helper.el --- utility help package supporting help in electric modes -*- lexical-binding: t; -*- ;; Copyright (C) 1985, 2001-2021 Free Software Foundation, Inc. @@ -39,20 +39,19 @@ ;; keymap either. -(defvar Helper-help-map nil) -(if Helper-help-map - nil - (setq Helper-help-map (make-keymap)) - ;(fillarray Helper-help-map 'undefined) - (define-key Helper-help-map "m" 'Helper-describe-mode) - (define-key Helper-help-map "b" 'Helper-describe-bindings) - (define-key Helper-help-map "c" 'Helper-describe-key-briefly) - (define-key Helper-help-map "k" 'Helper-describe-key) - ;(define-key Helper-help-map "f" 'Helper-describe-function) - ;(define-key Helper-help-map "v" 'Helper-describe-variable) - (define-key Helper-help-map "?" 'Helper-help-options) - (define-key Helper-help-map (char-to-string help-char) 'Helper-help-options) - (fset 'Helper-help-map Helper-help-map)) +(defvar Helper-help-map + (let ((map (make-sparse-keymap))) + ;(fillarray map 'undefined) + (define-key map "m" 'Helper-describe-mode) + (define-key map "b" 'Helper-describe-bindings) + (define-key map "c" 'Helper-describe-key-briefly) + (define-key map "k" 'Helper-describe-key) + ;(define-key map "f" 'Helper-describe-function) + ;(define-key map "v" 'Helper-describe-variable) + (define-key map "?" 'Helper-help-options) + (define-key map (char-to-string help-char) 'Helper-help-options) + (fset 'Helper-help-map map) + map)) (defun Helper-help-scroller () (let ((blurb (or (and (boundp 'Helper-return-blurb) diff --git a/lisp/emacs-lisp/package-x.el b/lisp/emacs-lisp/package-x.el index 8a0853ce44..b723643ffb 100644 --- a/lisp/emacs-lisp/package-x.el +++ b/lisp/emacs-lisp/package-x.el @@ -1,4 +1,4 @@ -;;; package-x.el --- Package extras +;;; package-x.el --- Package extras -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. diff --git a/lisp/emacs-lisp/regi.el b/lisp/emacs-lisp/regi.el index 38b202fa10..527af1ddf2 100644 --- a/lisp/emacs-lisp/regi.el +++ b/lisp/emacs-lisp/regi.el @@ -1,4 +1,4 @@ -;;; regi.el --- REGular expression Interpreting engine +;;; regi.el --- REGular expression Interpreting engine -*- lexical-binding: t; -*- ;; Copyright (C) 1993, 2001-2021 Free Software Foundation, Inc. @@ -153,7 +153,7 @@ useful information: ;; set up the narrowed region (and start end - (let* ((tstart start) + (let* (;; (tstart start) (start (min start end)) (end (max start end))) (narrow-to-region @@ -206,30 +206,33 @@ useful information: ;; if the line matched, package up the argument list and ;; funcall the FUNC (if match-p - (let* ((curline (buffer-substring - (regi-pos 'bol) - (regi-pos 'eol))) - (curframe current-frame) - (curentry entry) - (result (eval func)) - (step (or (cdr (assq 'step result)) 1)) - ) - ;; changing frame on the fly? - (if (assq 'frame result) - (setq working-frame (cdr (assq 'frame result)))) - - ;; continue processing current frame? - (if (memq 'continue result) - (setq current-frame (cdr current-frame)) - (forward-line step) - (setq current-frame working-frame)) - - ;; abort current frame? - (if (memq 'abort result) - (progn - (setq donep t) - (throw 'regi-throw-top t))) - ) ; end-let + (with-suppressed-warnings + ((lexical curframe curentry curline)) + (defvar curframe) (defvar curentry) (defvar curline) + (let* ((curline (buffer-substring + (regi-pos 'bol) + (regi-pos 'eol))) + (curframe current-frame) + (curentry entry) + (result (eval func)) + (step (or (cdr (assq 'step result)) 1)) + ) + ;; changing frame on the fly? + (if (assq 'frame result) + (setq working-frame (cdr (assq 'frame result)))) + + ;; continue processing current frame? + (if (memq 'continue result) + (setq current-frame (cdr current-frame)) + (forward-line step) + (setq current-frame working-frame)) + + ;; abort current frame? + (if (memq 'abort result) + (progn + (setq donep t) + (throw 'regi-throw-top t))) + )) ; end-let ;; else if no match occurred, then process the next ;; frame-entry on the current line diff --git a/lisp/emacs-lisp/shadow.el b/lisp/emacs-lisp/shadow.el index 168e5e46f3..c1d0594123 100644 --- a/lisp/emacs-lisp/shadow.el +++ b/lisp/emacs-lisp/shadow.el @@ -1,4 +1,4 @@ -;;; shadow.el --- locate Emacs Lisp file shadowings +;;; shadow.el --- locate Emacs Lisp file shadowings -*- lexical-binding: t; -*- ;; Copyright (C) 1995, 2001-2021 Free Software Foundation, Inc. @@ -58,8 +58,7 @@ (defcustom load-path-shadows-compare-text nil "If non-nil, then shadowing files are reported only if their text differs. This is slower, but filters out some innocuous shadowing." - :type 'boolean - :group 'lisp-shadow) + :type 'boolean) (defun load-path-shadows-find (&optional path) "Return a list of Emacs Lisp files that create shadows. @@ -78,8 +77,7 @@ See the documentation for `list-load-path-shadows' for further information." dir-case-insensitive ; `file-name-case-insensitive-p' of dir. curr-files ; This dir's Emacs Lisp files. orig-dir ; Where the file was first seen. - files-seen-this-dir ; Files seen so far in this dir. - file) ; The current file. + files-seen-this-dir) ; Files seen so far in this dir. (dolist (pp (or path load-path)) (setq dir (directory-file-name (file-truename (or pp ".")))) (if (member dir true-names) @@ -109,7 +107,7 @@ See the documentation for `list-load-path-shadows' for further information." (dolist (file curr-files) - (if (string-match "\\.gz$" file) + (if (string-match "\\.gz\\'" file) (setq file (substring file 0 -3))) (setq file (substring file 0 (if (string= (substring file -1) "c") -4 -3))) @@ -125,9 +123,13 @@ See the documentation for `list-load-path-shadows' for further information." ;; XXX.elc (or vice-versa) when they are in the same directory. (setq files-seen-this-dir (cons file files-seen-this-dir)) - (if (setq orig-dir (assoc file files - (when dir-case-insensitive - (lambda (f1 f2) (eq (compare-strings f1 nil nil f2 nil nil t) t))))) + (if (setq orig-dir + (assoc file files + (when dir-case-insensitive + (lambda (f1 f2) + (eq (compare-strings f1 nil nil + f2 nil nil t) + t))))) ;; This file was seen before, we have a shadowing. ;; Report it unless the files are identical. (let ((base1 (concat (cdr orig-dir) "/" (car orig-dir))) @@ -142,7 +144,7 @@ See the documentation for `list-load-path-shadows' for further information." (append shadows (list base1 base2))))) ;; Not seen before, add it to the list of seen files. - (setq files (cons (cons file dir) files))))))) + (push (cons file dir) files)))))) ;; Return the list of shadowings. shadows)) diff --git a/lisp/emacs-lisp/tcover-ses.el b/lisp/emacs-lisp/tcover-ses.el index 7de9d547ce..fb9cd8f47d 100644 --- a/lisp/emacs-lisp/tcover-ses.el +++ b/lisp/emacs-lisp/tcover-ses.el @@ -1,4 +1,4 @@ -;;;; testcover-ses.el -- Example use of `testcover' to test "SES" +;;;; testcover-ses.el -- Example use of `testcover' to test "SES" -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. @@ -19,21 +19,14 @@ ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs. If not, see . -(require 'testcover) +;;; Commentary: -(defvar ses-initial-global-parameters) -(defvar ses-mode-map) +;; FIXME: Convert to ERT and move to `test/'? -(declare-function ses-set-curcell "ses") -(declare-function ses-update-cells "ses") -(declare-function ses-load "ses") -(declare-function ses-vector-delete "ses") -(declare-function ses-create-header-string "ses") -(declare-function ses-read-cell "ses") -(declare-function ses-read-symbol "ses") -(declare-function ses-command-hook "ses") -(declare-function ses-jump "ses") +;;; Code: +(require 'testcover) +(require 'ses) ;;;Here are some macros that exercise SES. Set `pause' to t if you want the ;;;macros to pause after each step. @@ -652,6 +645,7 @@ spreadsheet files with invalid formatting." (testcover-start "ses.el" t)) (require 'unsafep)) ;In case user has safe-functions = t! +(defvar ses--curcell-overlay) ;;;######################################################################### (defun ses-exercise () @@ -674,8 +668,8 @@ spreadsheet files with invalid formatting." (ses-load)) ;;ses-vector-delete is always called from buffer-undo-list with the same ;;symbol as argument. We'll give it a different one here. - (let ((x [1 2 3])) - (ses-vector-delete 'x 0 0)) + (dlet ((tcover-ses--x [1 2 3])) + (ses-vector-delete 'tcover-ses--x 0 0)) ;;ses-create-header-string behaves differently in a non-window environment ;;but we always test under windows. (let ((window-system (not window-system))) @@ -704,7 +698,7 @@ spreadsheet files with invalid formatting." (ses-mode))))) ;;Test error-handling in command hook, outside a macro. ;;This will ring the bell. - (let (curcell-overlay) + (let (ses--curcell-overlay) (ses-command-hook)) ;;Due to use of run-with-timer, ses-command-hook sometimes gets called ;;after we switch to another buffer. @@ -720,4 +714,4 @@ spreadsheet files with invalid formatting." ;;Could do this here: (testcover-end "ses.el") (message "Done")) -;; testcover-ses.el ends here. +;;; testcover-ses.el ends here. diff --git a/lisp/emacs-lisp/unsafep.el b/lisp/emacs-lisp/unsafep.el index f46d9c77ea..d52a6c796d 100644 --- a/lisp/emacs-lisp/unsafep.el +++ b/lisp/emacs-lisp/unsafep.el @@ -1,4 +1,4 @@ -;;;; unsafep.el -- Determine whether a Lisp form is safe to evaluate +;;;; unsafep.el -- Determine whether a Lisp form is safe to evaluate -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. @@ -129,15 +129,16 @@ in the parse.") (put x 'safe-function t)) ;;;###autoload -(defun unsafep (form &optional unsafep-vars) +(defun unsafep (form &optional vars) "Return nil if evaluating FORM couldn't possibly do any harm. Otherwise result is a reason why FORM is unsafe. -UNSAFEP-VARS is a list of symbols with local bindings." +VARS is a list of symbols with local bindings like `unsafep-vars'." (catch 'unsafep (if (or (eq safe-functions t) ;User turned off safety-checking (atom form)) ;Atoms are never unsafe (throw 'unsafep nil)) - (let* ((fun (car form)) + (let* ((unsafep-vars vars) + (fun (car form)) (reason (unsafep-function fun)) arg) (cond commit c8c4d65d6510724acd40527a9af67e21e3cf4d5e Author: Juri Linkov Date: Thu Jan 28 21:27:26 2021 +0200 Use isearch-tmm-menubar when tmm-menubar is called in isearch-mode (bug#43966) * lisp/isearch.el (isearch-menu-bar-commands): Add tmm-menubar to defaults. (isearch-mode-map): Remove remapping of tmm-menubar to isearch-tmm-menubar. * lisp/tmm.el (tmm-menubar): Call isearch-tmm-menubar in isearch-mode. diff --git a/lisp/isearch.el b/lisp/isearch.el index a86678572c..a1e3fe2c3f 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -513,7 +513,7 @@ This is like `describe-bindings', but displays only Isearch keys." (call-interactively command))) (defvar isearch-menu-bar-commands - '(isearch-tmm-menubar menu-bar-open mouse-minor-mode-menu) + '(isearch-tmm-menubar tmm-menubar menu-bar-open mouse-minor-mode-menu) "List of commands that can open a menu during Isearch.") (defvar isearch-menu-bar-yank-map @@ -787,7 +787,6 @@ This is like `describe-bindings', but displays only Isearch keys." (define-key map [menu-bar search-menu] (list 'menu-item "Isearch" isearch-menu-bar-map)) - (define-key map [remap tmm-menubar] 'isearch-tmm-menubar) map) "Keymap for `isearch-mode'.") diff --git a/lisp/tmm.el b/lisp/tmm.el index e49246a5c4..2040f52270 100644 --- a/lisp/tmm.el +++ b/lisp/tmm.el @@ -56,12 +56,14 @@ to invoke `tmm-menubar' instead, customize the variable `tty-menu-open-use-tmm' to a non-nil value." (interactive) (run-hooks 'menu-bar-update-hook) - (let ((menu-bar (menu-bar-keymap)) - (menu-bar-item-cons (and x-position - (menu-bar-item-at-x x-position)))) - (tmm-prompt menu-bar - nil - (and menu-bar-item-cons (car menu-bar-item-cons))))) + (if isearch-mode + (isearch-tmm-menubar) + (let ((menu-bar (menu-bar-keymap)) + (menu-bar-item-cons (and x-position + (menu-bar-item-at-x x-position)))) + (tmm-prompt menu-bar + nil + (and menu-bar-item-cons (car menu-bar-item-cons)))))) ;;;###autoload (defun tmm-menubar-mouse (event) commit 50c7de093a4e699fb86b05b8fdd6b6a47a886106 Author: Stefan Kangas Date: Thu Jan 28 19:21:41 2021 +0100 * lisp/wdired.el: Minor doc fixes. diff --git a/lisp/wdired.el b/lisp/wdired.el index 037eb31245..a096abd106 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -27,26 +27,26 @@ ;; wdired.el (the "w" is for writable) provides an alternative way of ;; renaming files. ;; -;; Have you ever wished to use C-x r t (string-rectangle), M-% +;; Have you ever wanted to use C-x r t (string-rectangle), M-% ;; (query-replace), M-c (capitalize-word), etc... to change the name of -;; the files in a "dired" buffer? Now you can do this. All the power -;; of Emacs commands are available to renaming files! +;; the files in a "dired" buffer? Now you can do this. All the power +;; of Emacs commands are available when renaming files! ;; ;; This package provides a function that makes the filenames of a ;; dired buffer editable, by changing the buffer mode (which inhibits -;; all of the commands of dired mode). Here you can edit the names of +;; all of the commands of dired mode). Here you can edit the names of ;; one or more files and directories, and when you press C-c C-c, the ;; renaming takes effect and you are back to dired mode. ;; -;; Another things you can do with WDired: +;; Other things you can do with WDired: ;; -;; - To move files to another directory (by typing their path, +;; - Move files to another directory (by typing their path, ;; absolute or relative, as a part of the new filename). ;; -;; - To change the target of symbolic links. +;; - Change the target of symbolic links. ;; -;; - To change the permission bits of the filenames (in systems with a -;; working unix-alike `dired-chmod-program'). See and customize the +;; - Change the permission bits of the filenames (in systems with a +;; working unix-alike `dired-chmod-program'). See and customize the ;; variable `wdired-allow-to-change-permissions'. To change a single ;; char (toggling between its two more usual values) you can press ;; the space bar over it or left-click the mouse. To set any char to @@ -56,7 +56,7 @@ ;; the change would affect to their targets, and this would not be ;; WYSIWYG :-). ;; -;; - To mark files for deletion, by deleting their whole filename. +;; - Mark files for deletion, by deleting their whole filename. ;;; Usage: commit a8caa66906b157c9c2b4c4dc1c447b6a9e747c5e Author: Stefan Kangas Date: Thu Jan 28 19:06:18 2021 +0100 Avoid recommending Google * doc/misc/org.texi (Link Abbreviations): * lisp/net/webjump.el (webjump-sample-sites): * lisp/org/ol.el (org-link-shell-confirm-function) (org-link-elisp-confirm-function): * lisp/org/org.el (org-highlight-links): * lisp/wdired.el: Avoid recommending Google. squash! Avoid recommending Google diff --git a/doc/misc/org.texi b/doc/misc/org.texi index 5eeb098cc7..8902d62887 100644 --- a/doc/misc/org.texi +++ b/doc/misc/org.texi @@ -4071,7 +4071,7 @@ the link. Such a function will be called with the tag as the only argument. With the above setting, you could link to a specific bug with -@samp{[[bugzilla:129]]}, search the web for @samp{OrgMode} with @samp{[[google:OrgMode]]}, +@samp{[[bugzilla:129]]}, search the web for @samp{OrgMode} with @samp{[[duckduckgo:OrgMode]]}, show the map location of the Free Software Foundation @samp{[[gmap:51 Franklin Street, Boston]]} or of Carsten office @samp{[[omap:Science Park 904, Amsterdam, The Netherlands]]} and find out what the Org author is doing @@ -4082,8 +4082,8 @@ can define them in the file with @cindex @samp{LINK}, keyword @example -#+LINK: bugzilla http://10.1.2.9/bugzilla/show_bug.cgi?id= -#+LINK: google http://www.google.com/search?q=%s +#+LINK: bugzilla http://10.1.2.9/bugzilla/show_bug.cgi?id= +#+LINK: duckduckgo https://duckduckgo.com/?q=%s @end example In-buffer completion (see @ref{Completion}) can be used after @samp{[} to diff --git a/lisp/net/webjump.el b/lisp/net/webjump.el index e5941ae652..1fa625c324 100644 --- a/lisp/net/webjump.el +++ b/lisp/net/webjump.el @@ -96,9 +96,6 @@ ("DuckDuckGo" . [simple-query "duckduckgo.com" "duckduckgo.com/?q=" ""]) - ("Google" . - [simple-query "www.google.com" - "www.google.com/search?q=" ""]) ("Google Groups" . [simple-query "groups.google.com" "groups.google.com/groups?q=" ""]) diff --git a/lisp/org/ol.el b/lisp/org/ol.el index d1db1683bb..994e30f4f4 100644 --- a/lisp/org/ol.el +++ b/lisp/org/ol.el @@ -376,9 +376,9 @@ changes to the current buffer." Shell links can be dangerous: just think about a link - [[shell:rm -rf ~/*][Google Search]] + [[shell:rm -rf ~/*][Web Search]] -This link would show up in your Org document as \"Google Search\", +This link would show up in your Org document as \"Web Search\", but really it would remove your entire home directory. Therefore we advise against setting this variable to nil. Just change it to `y-or-n-p' if you want to confirm with a @@ -401,9 +401,9 @@ single keystroke rather than having to type \"yes\"." "Non-nil means ask for confirmation before executing Emacs Lisp links. Elisp links can be dangerous: just think about a link - [[elisp:(shell-command \"rm -rf ~/*\")][Google Search]] + [[elisp:(shell-command \"rm -rf ~/*\")][Web Search]] -This link would show up in your Org document as \"Google Search\", +This link would show up in your Org document as \"Web Search\", but really it would remove your entire home directory. Therefore we advise against setting this variable to nil. Just change it to `y-or-n-p' if you want to confirm with a diff --git a/lisp/org/org.el b/lisp/org/org.el index 43aa0a178a..2d21a44fb4 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -1846,7 +1846,7 @@ link types. The types are: bracket The recommended [[link][description]] or [[link]] links with hiding. angle Links in angular brackets that may contain whitespace like . -plain Plain links in normal text, no whitespace, like http://google.com. +plain Plain links in normal text, no whitespace, like https://gnu.org. radio Text that is matched by a radio target, see manual for details. tag Tag settings in a headline (link to tag search). date Time stamps (link to calendar). diff --git a/lisp/wdired.el b/lisp/wdired.el index f4a0b6d9a9..037eb31245 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -68,8 +68,8 @@ ;;; Change Log: -;; Google is your friend (previous versions with complete changelogs -;; were posted to gnu.emacs.sources) +;; Previous versions with complete changelogs were posted to +;; gnu.emacs.sources. ;;; Code: commit aca93f67239e82f7c63444525e00337db8f168fe Author: Stefan Kangas Date: Thu Jan 28 18:49:29 2021 +0100 * lisp/leim/quail/viqr.el: Use lexical-binding. diff --git a/lisp/leim/quail/viqr.el b/lisp/leim/quail/viqr.el index b7591b15e0..d127ff247c 100644 --- a/lisp/leim/quail/viqr.el +++ b/lisp/leim/quail/viqr.el @@ -1,4 +1,4 @@ -;;; viqr.el --- Quail packages for inputting Vietnamese with VIQR system -*-coding: utf-8;-*- +;;; viqr.el --- Quail packages for inputting Vietnamese with VIQR system -*-coding: utf-8; lexical-binding: t -*- ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, ;; 2006, 2007, 2008, 2009, 2010, 2011 commit f782f1a8e07c7ef689e9f3a763259a030883c5c6 Author: Stefan Kangas Date: Thu Jan 28 18:49:17 2021 +0100 * lisp/leim/quail/compose.el: Use lexical-binding. diff --git a/lisp/leim/quail/compose.el b/lisp/leim/quail/compose.el index f7ac83aec5..264a9b479b 100644 --- a/lisp/leim/quail/compose.el +++ b/lisp/leim/quail/compose.el @@ -1,4 +1,4 @@ -;;; compose.el --- Quail package for Multi_key character composition -*-coding: utf-8;-*- +;;; compose.el --- Quail package for Multi_key character composition -*-coding: utf-8; lexical-binding: t -*- ;; Copyright (C) 2020-2021 Free Software Foundation, Inc. commit c407b54cf37ae56f65a75f5238f86898be7d8159 Author: Stefan Kangas Date: Thu Jan 28 18:35:45 2021 +0100 * lisp/ezimage.el: Use lexical-binding. diff --git a/lisp/ezimage.el b/lisp/ezimage.el index 9c1d859910..13f5c039a7 100644 --- a/lisp/ezimage.el +++ b/lisp/ezimage.el @@ -1,4 +1,4 @@ -;;; ezimage --- Generalized Image management +;;; ezimage.el --- Generalized Image management -*- lexical-binding: t -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. commit 592a230832257e915aa3ed798a1f0210df639031 Author: Stefan Monnier Date: Thu Jan 28 12:27:09 2021 -0500 * src/fns.c (hash_string): Fix bug#46111 Use `memcpy` instead of an unaligned memory access. On x86 at least, GCC turns this `memcpy` into a single `mov`, so it's about as fast. diff --git a/src/fns.c b/src/fns.c index 7ab2e8f1a0..bd4afa0c4e 100644 --- a/src/fns.c +++ b/src/fns.c @@ -4599,33 +4599,29 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p) EMACS_UINT hash_string (char const *ptr, ptrdiff_t len) { - EMACS_UINT const *p = (EMACS_UINT const *) ptr; - EMACS_UINT const *end = (EMACS_UINT const *) (ptr + len); + char const *p = ptr; + char const *end = ptr + len; EMACS_UINT hash = len; /* At most 8 steps. We could reuse SXHASH_MAX_LEN, of course, * but dividing by 8 is cheaper. */ - ptrdiff_t step = 1 + ((end - p) >> 3); + ptrdiff_t step = sizeof hash + ((end - p) >> 3); - /* Beware: `end` might be unaligned, so `p < end` is not always the same - * as `p <= end - 1`. */ - while (p <= end - 1) + while (p + sizeof hash <= end) { - EMACS_UINT c = *p; + EMACS_UINT c; + /* We presume that the compiler will replace this `memcpy` with + a single load/move instruction when applicable. */ + memcpy (&c, p, sizeof hash); p += step; hash = sxhash_combine (hash, c); } - if (p < end) - { /* A few last bytes remain (smaller than an EMACS_UINT). */ - /* FIXME: We could do this without a loop, but it'd require - endian-dependent code :-( */ - char const *p1 = (char const *)p; - char const *end1 = (char const *)end; - do - { - unsigned char c = *p1++; - hash = sxhash_combine (hash, c); - } - while (p1 < end1); + /* A few last bytes may remain (smaller than an EMACS_UINT). */ + /* FIXME: We could do this without a loop, but it'd require + endian-dependent code :-( */ + while (p < end) + { + unsigned char c = *p++; + hash = sxhash_combine (hash, c); } return hash; commit b04f1c0cec5bc722fd5823861044f212206c3d3b Author: Stefan Kangas Date: Thu Jan 28 18:16:49 2021 +0100 Add cross-reference to with-eval-after-load * lisp/subr.el (eval-after-load): Doc fix; add cross-reference to 'with-eval-after-load'. diff --git a/lisp/subr.el b/lisp/subr.el index afa73c72ea..34129ea38a 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4921,7 +4921,9 @@ file, FORM is evaluated immediately after the provide statement. Usually FILE is just a library name like \"font-lock\" or a feature name like `font-lock'. -This function makes or adds to an entry on `after-load-alist'." +This function makes or adds to an entry on `after-load-alist'. + +See also `with-eval-after-load'." (declare (compiler-macro (lambda (whole) (if (eq 'quote (car-safe form)) commit 4cded88b0ebb005f67447cd07da016eb0b7ef4a4 Author: Stefan Kangas Date: Thu Jan 28 17:05:06 2021 +0100 * lisp/generic-x.el (hosts-generic-mode): Support IPv6 addresses. diff --git a/lisp/generic-x.el b/lisp/generic-x.el index 60cf8468a4..bd03f287fc 100644 --- a/lisp/generic-x.el +++ b/lisp/generic-x.el @@ -365,7 +365,8 @@ your changes into effect." (define-generic-mode hosts-generic-mode '(?#) '("localhost") - '(("\\([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+\\)" 1 font-lock-constant-face)) + '(("\\([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+\\)" 1 font-lock-constant-face) + ("\\<\\([0-9A-Fa-f:]+\\)\\>" 1 font-lock-constant-face)) '("[hH][oO][sS][tT][sS]\\'") nil "Generic mode for HOSTS files.")) commit 80d964ec8b64a1c604c99aa51ecdbd813d739a90 Author: Stefan Kangas Date: Thu Jan 28 15:08:51 2021 +0100 Add missing file systems to etc-fstab-generic-mode * lisp/generic-x.el (etc-fstab-generic-mode): Add entries for missing file systems. diff --git a/lisp/generic-x.el b/lisp/generic-x.el index f3ea22a4a3..60cf8468a4 100644 --- a/lisp/generic-x.el +++ b/lisp/generic-x.el @@ -1490,41 +1490,104 @@ like an INI file. You can add this hook to `find-file-hook'." (define-generic-mode etc-fstab-generic-mode '(?#) '("adfs" + "ados" "affs" + "anon_inodefs" + "atfs" + "audiofs" "autofs" + "bdev" + "befs" + "bfs" + "binfmt_misc" + "btrfs" + "cd9660" + "cfs" + "cgroup" + "cifs" "coda" "coherent" + "configfs" + "cpuset" "cramfs" + "devfs" "devpts" + "devtmpfs" + "e2compr" "efs" "ext2" + "ext2fs" "ext3" "ext4" + "fdesc" + "ffs" + "filecore" + "fuse" + "fuseblk" + "fusectl" "hfs" "hpfs" + "hugetlbfs" "iso9660" + "jffs" + "jffs2" "jfs" + "kernfs" + "lfs" + "linprocfs" + "mfs" "minix" + "mqueue" "msdos" "ncpfs" "nfs" + "nfsd" + "nilfs2" + "none" "ntfs" + "null" + "nwfs" + "overlay" + "ovlfs" + "pipefs" + "portal" "proc" + "procfs" + "pstore" + "ptyfs" "qnx4" + "ramfs" "reiserfs" "romfs" + "securityfs" + "shm" "smbfs" - "cifs" - "usbdevfs" - "sysv" + "sockfs" + "squashfs" + "sshfs" + "std" + "subfs" "sysfs" + "sysv" + "tcfs" "tmpfs" "udf" "ufs" + "umap" "umsdos" + "union" + "usbdevfs" + "usbfs" + "userfs" "vfat" + "vs3fs" + "vxfs" + "wrapfs" + "wvfs" + "xenfs" "xenix" "xfs" + "zisofs" "swap" "auto" "ignore") commit 6c601689a40079dd6c253f15a690a3c0cf6918df Author: Stefan Kangas Date: Sun Jan 24 00:53:38 2021 +0100 ; * lisp/dired-aux.el (dired-compress-files-alist): Minor doc fix. diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index c765e4be45..ec864d54d6 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -1179,7 +1179,7 @@ archive to which you want to compress, and CMD is the corresponding command. Within CMD, %i denotes the input file(s), and %o denotes the -output file. %i path(s) are relative, while %o is absolute.") +output file. %i path(s) are relative, while %o is absolute.") ;;;###autoload (defun dired-do-compress-to () commit 91f9d6788e83e619b2df5a30ca4ab9f4be0a11b0 Author: Stefan Monnier Date: Thu Jan 28 12:13:29 2021 -0500 * test/Makefile.in (emacs): Use the C locale This fixes spurious test failures in my environment for `diff-mode-test-font-lock-syntax-one-line` (where my `diff` otherwise returns "No newline at end of file" in French) and for various tests in `emacs-module-tests` because errors signal "Abandon" instead of "Abort". diff --git a/test/Makefile.in b/test/Makefile.in index c5e86df376..f907602a62 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -122,8 +122,9 @@ MODULES_EMACSOPT := endif # The actual Emacs command run in the targets below. -# Prevent any setting of EMACSLOADPATH in user environment causing problems. -emacs = EMACSLOADPATH= \ +# Prevent any setting of EMACSLOADPATH in user environment causing problems, +# and prevent locals to influence the text of the errors we expect to receive. +emacs = LANG=C EMACSLOADPATH= \ EMACS_TEST_DIRECTORY=$(abspath $(srcdir)) \ $(GDB) "$(EMACS)" $(MODULES_EMACSOPT) $(EMACSOPT) commit ac102bb966f7944babbd8594684550905eecca0a Author: Michael Albinus Date: Thu Jan 28 15:09:29 2021 +0100 * lisp/net/ange-ftp.el (ange-ftp-ls): Handle several "--dired" switches. diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el index 9559b12513..fa13dd57d1 100644 --- a/lisp/net/ange-ftp.el +++ b/lisp/net/ange-ftp.el @@ -2547,7 +2547,7 @@ can parse the output from a DIR listing for a host of type TYPE.") FILE is the full name of the remote file, LSARGS is any args to pass to the `ls' command, and PARSE specifies that the output should be parsed and stored away in the internal cache." - (when (string-match "^--dired\\s-+" lsargs) + (while (string-match "^--dired\\s-+" lsargs) (setq lsargs (replace-match "" nil t lsargs))) ;; If parse is t, we assume that file is a directory. i.e. we only parse ;; full directory listings. commit a8c4f8041cc64e3dafc0e435bab8043d7165ffff Author: Michael Albinus Date: Thu Jan 28 15:09:18 2021 +0100 Simplify auto-revert buffer list by watch descriptor (Bug#44639) * lisp/autorevert.el (auto-revert--buffer-by-watch-descriptor): Rename from `auto-revert--buffers-by-watch-descriptor'. Make it an assoc list. (auto-revert-notify-rm-watch, auto-revert-notify-add-watch) (auto-revert-notify-handler): Adapt accordingly. Based on a patch provided by Spencer Baugh . (Bug#44639) diff --git a/lisp/autorevert.el b/lisp/autorevert.el index 1b2d68939a..57258f9c83 100644 --- a/lisp/autorevert.el +++ b/lisp/autorevert.el @@ -355,10 +355,9 @@ the list of old buffers.") (add-hook 'after-set-visited-file-name-hook #'auto-revert-set-visited-file-name) -(defvar auto-revert--buffers-by-watch-descriptor - (make-hash-table :test 'equal) - "A hash table mapping notification descriptors to lists of buffers. -The buffers use that descriptor for auto-revert notifications. +(defvar auto-revert--buffer-by-watch-descriptor nil + "An association list mapping notification descriptors to buffers. +The buffer uses that descriptor for auto-revert notifications. The key is equal to `auto-revert-notify-watch-descriptor' in each buffer.") @@ -630,16 +629,12 @@ will use an up-to-date value of `auto-revert-interval'." (defun auto-revert-notify-rm-watch () "Disable file notification for current buffer's associated file." - (let ((desc auto-revert-notify-watch-descriptor) - (table auto-revert--buffers-by-watch-descriptor)) - (when desc - (let ((buffers (delq (current-buffer) (gethash desc table)))) - (if buffers - (puthash desc buffers table) - (remhash desc table))) - (ignore-errors - (file-notify-rm-watch desc)) - (remove-hook 'kill-buffer-hook #'auto-revert-notify-rm-watch t))) + (when-let ((desc auto-revert-notify-watch-descriptor)) + (setq auto-revert--buffer-by-watch-descriptor + (assoc-delete-all desc auto-revert--buffer-by-watch-descriptor)) + (ignore-errors + (file-notify-rm-watch desc)) + (remove-hook 'kill-buffer-hook #'auto-revert-notify-rm-watch t)) (setq auto-revert-notify-watch-descriptor nil auto-revert-notify-modified-p nil)) @@ -660,13 +655,10 @@ will use an up-to-date value of `auto-revert-interval'." (if buffer-file-name '(change attribute-change) '(change)) 'auto-revert-notify-handler)))) (when auto-revert-notify-watch-descriptor - (setq auto-revert-notify-modified-p t) - (puthash - auto-revert-notify-watch-descriptor - (cons (current-buffer) - (gethash auto-revert-notify-watch-descriptor - auto-revert--buffers-by-watch-descriptor)) - auto-revert--buffers-by-watch-descriptor) + (setq auto-revert-notify-modified-p t + auto-revert--buffer-by-watch-descriptor + (cons (cons auto-revert-notify-watch-descriptor (current-buffer)) + auto-revert--buffer-by-watch-descriptor)) (add-hook 'kill-buffer-hook #'auto-revert-notify-rm-watch nil t)))) ;; If we have file notifications, we want to update the auto-revert buffers @@ -696,8 +688,8 @@ system.") (action (nth 1 event)) (file (nth 2 event)) (file1 (nth 3 event)) ;; Target of `renamed'. - (buffers (gethash descriptor - auto-revert--buffers-by-watch-descriptor))) + (buffer (alist-get descriptor auto-revert--buffer-by-watch-descriptor + nil nil #'equal))) ;; Check, that event is meant for us. (cl-assert descriptor) ;; Since we watch a directory, a file name must be returned. @@ -706,9 +698,9 @@ system.") (when auto-revert-debug (message "auto-revert-notify-handler %S" event)) - (if (eq action 'stopped) - ;; File notification has stopped. Continue with polling. - (cl-dolist (buffer buffers) + (when (buffer-live-p buffer) + (if (eq action 'stopped) + ;; File notification has stopped. Continue with polling. (with-current-buffer buffer (when (or ;; A buffer associated with a file. @@ -721,38 +713,35 @@ system.") (auto-revert-notify-rm-watch) ;; Restart the timer if it wasn't running. (unless auto-revert-timer - (auto-revert-set-timer))))) - - ;; Loop over all buffers, in order to find the intended one. - (cl-dolist (buffer buffers) - (when (buffer-live-p buffer) - (with-current-buffer buffer - (when (or - ;; A buffer associated with a file. - (and (stringp buffer-file-name) - (or - (and (memq - action '(attribute-changed changed created)) - (string-equal - (file-name-nondirectory file) - (file-name-nondirectory buffer-file-name))) - (and (eq action 'renamed) - (string-equal - (file-name-nondirectory file1) - (file-name-nondirectory buffer-file-name))))) - ;; A buffer w/o a file, like dired. - (and (null buffer-file-name) - (memq action '(created renamed deleted)))) - ;; Mark buffer modified. - (setq auto-revert-notify-modified-p t) - - ;; Revert the buffer now if we're not locked out. - (unless auto-revert--lockout-timer - (auto-revert-handler) - (setq auto-revert--lockout-timer - (run-with-timer - auto-revert--lockout-interval nil - #'auto-revert--end-lockout buffer))))))))))) + (auto-revert-set-timer)))) + + (with-current-buffer buffer + (when (or + ;; A buffer associated with a file. + (and (stringp buffer-file-name) + (or + (and (memq + action '(attribute-changed changed created)) + (string-equal + (file-name-nondirectory file) + (file-name-nondirectory buffer-file-name))) + (and (eq action 'renamed) + (string-equal + (file-name-nondirectory file1) + (file-name-nondirectory buffer-file-name))))) + ;; A buffer w/o a file, like dired. + (and (null buffer-file-name) + (memq action '(created renamed deleted)))) + ;; Mark buffer modified. + (setq auto-revert-notify-modified-p t) + + ;; Revert the buffer now if we're not locked out. + (unless auto-revert--lockout-timer + (auto-revert-handler) + (setq auto-revert--lockout-timer + (run-with-timer + auto-revert--lockout-interval nil + #'auto-revert--end-lockout buffer)))))))))) (defun auto-revert--end-lockout (buffer) "End the lockout period after a notification. commit 62233c9824047e989cb72c8e2d05e4b4444fe0be Author: Stefan Monnier Date: Thu Jan 28 08:43:01 2021 -0500 Use lexical-binding in lisp/{term,nxml,language} * test/lisp/electric-tests.el: * lisp/term/w32console.el: * lisp/nxml/rng-util.el: * leim/leim-ext.el: Use lexical-binding. * lisp/international/titdic-cnv.el (tit-process-header) (miscdic-convert): * lisp/international/mule-cmds.el (leim-list-header): * lisp/international/ja-dic-cnv.el (skkdic-convert): Use lexical-binding in the generated file. diff --git a/leim/leim-ext.el b/leim/leim-ext.el index 2378f6fdb4..687379db9f 100644 --- a/leim/leim-ext.el +++ b/leim/leim-ext.el @@ -1,4 +1,4 @@ -;; leim-ext.el -- extra leim configuration -*- coding:utf-8; -*- +;; leim-ext.el -- extra leim configuration -*- lexical-binding: t; -*- ;; Copyright (C) 2004-2021 Free Software Foundation, Inc. ;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 @@ -39,13 +39,13 @@ (eval-after-load "quail/Punct-b5" '(quail-defrule " " ?  nil t)) -(register-input-method "ucs" "UTF-8" 'ucs-input-activate "U+" +(register-input-method "ucs" "UTF-8" #'ucs-input-activate "U+" "Unicode input as hex in the form Uxxxx.") (register-input-method "korean-hangul" "UTF-8" - 'hangul-input-method-activate + #'hangul-input-method-activate "한2" "Hangul 2-Bulsik Input" 'hangul2-input-method @@ -54,7 +54,7 @@ (register-input-method "korean-hangul3f" "UTF-8" - 'hangul-input-method-activate + #'hangul-input-method-activate "한3f" "Hangul 3-Bulsik final Input" 'hangul3-input-method @@ -63,7 +63,7 @@ (register-input-method "korean-hangul390" "UTF-8" - 'hangul-input-method-activate + #'hangul-input-method-activate "한390" "Hangul 3-Bulsik 390 Input" 'hangul390-input-method @@ -72,7 +72,7 @@ (register-input-method "korean-hangul3" "UTF-8" - 'hangul-input-method-activate + #'hangul-input-method-activate "한390" "Hangul 3-Bulsik 390 Input" 'hangul390-input-method diff --git a/lisp/international/ja-dic-cnv.el b/lisp/international/ja-dic-cnv.el index 155c85fb42..3be7849df1 100644 --- a/lisp/international/ja-dic-cnv.el +++ b/lisp/international/ja-dic-cnv.el @@ -342,7 +342,8 @@ The name of generated file is specified by the variable `ja-dic-filename'." (with-current-buffer buf (erase-buffer) (buffer-disable-undo) - (insert ";;; ja-dic.el --- dictionary for Japanese input method\n" + (insert ";;; ja-dic.el --- dictionary for Japanese input method" + " -*- lexical-binding:t -*-\n" ";;\tGenerated by the command `skkdic-convert'\n" ";;\tOriginal SKK dictionary file: " (file-relative-name (expand-file-name filename) dirname) diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index 347e678259..8202c3ee27 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -1279,7 +1279,7 @@ in the format of Lisp expression for registering each input method. Emacs loads this file at startup time.") (defconst leim-list-header (format-message -";;; %s -- list of LEIM (Library of Emacs Input Method) -*-coding: utf-8;-*- +";;; %s --- list of LEIM (Library of Emacs Input Method) -*- lexical-binding:t -*- ;; ;; This file is automatically generated. ;; diff --git a/lisp/international/quail.el b/lisp/international/quail.el index 9698d46153..0901115cff 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el @@ -3013,7 +3013,7 @@ of each directory." ;; At first, clean up the file. (with-current-buffer list-buf - (goto-char 1) + (goto-char (point-min)) ;; Insert the correct header. (if (looking-at (regexp-quote leim-list-header)) diff --git a/lisp/international/titdic-cnv.el b/lisp/international/titdic-cnv.el index ce5c04293a..64d6644376 100644 --- a/lisp/international/titdic-cnv.el +++ b/lisp/international/titdic-cnv.el @@ -269,6 +269,8 @@ SPC, 6, 3, 4, or 7 specifying a tone (SPC:陰平, 6:陽平, 3:上聲, 4:去聲, (tit-moveleft ",<") (tit-keyprompt nil)) + (princ (format ";;; %s -*- lexical-binding:t -*-\n" + (file-name-nondirectory filename))) (princ ";; Quail package `") (princ package) (princ "\n") @@ -1133,6 +1135,8 @@ the generated Quail package is saved." ;; Explicitly set eol format to `unix'. (setq coding-system-for-write 'utf-8-unix) (with-temp-file (expand-file-name quailfile dirname) + (insert (format ";;; %s -*- lexical-binding:t -*-\n" + (file-name-nondirectory quailfile))) (insert (format-message ";; Quail package `%s'\n" name)) (insert (format-message ";; Generated by the command `miscdic-convert'\n")) diff --git a/lisp/nxml/rng-util.el b/lisp/nxml/rng-util.el index 59465c371e..a20e95086c 100644 --- a/lisp/nxml/rng-util.el +++ b/lisp/nxml/rng-util.el @@ -1,4 +1,4 @@ -;;; rng-util.el --- utility functions for RELAX NG library +;;; rng-util.el --- utility functions for RELAX NG library -*- lexical-binding: t; -*- ;; Copyright (C) 2003, 2007-2021 Free Software Foundation, Inc. diff --git a/lisp/term/w32console.el b/lisp/term/w32console.el index 8859f13bd2..4a925cd84c 100644 --- a/lisp/term/w32console.el +++ b/lisp/term/w32console.el @@ -1,4 +1,4 @@ -;;; w32console.el -- Setup w32 console keys and colors. +;;; w32console.el -- Setup w32 console keys and colors. -*- lexical-binding: t; -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el index 1b7beeaa36..05a6989664 100644 --- a/test/lisp/electric-tests.el +++ b/test/lisp/electric-tests.el @@ -1,4 +1,4 @@ -;;; electric-tests.el --- tests for electric.el +;;; electric-tests.el --- tests for electric.el -*- lexical-binding: t; -*- ;; Copyright (C) 2013-2021 Free Software Foundation, Inc. commit 0120f45db630753bc8c4d6c43f7cdb7f953144fd Author: Lars Ingebrigtsen Date: Thu Jan 28 13:10:45 2021 +0100 Protect against bad results from libravatar * lisp/image/gravatar.el (gravatar--service-libravatar): Don't have (gravatar-retrieve "foobar@zjp.codes" 'ignore) (which returns a CNAME) bug out. diff --git a/lisp/image/gravatar.el b/lisp/image/gravatar.el index 4f37834a27..b1e2a314ce 100644 --- a/lisp/image/gravatar.el +++ b/lisp/image/gravatar.el @@ -160,12 +160,16 @@ to track whether you're reading a specific mail." (cond ((and result ;there is a result - (let* ((data (mapcar (lambda (record) + (let* ((answers (dns-get 'answers result)) + (data (mapcar (lambda (record) (dns-get 'data (cdr record))) - (dns-get 'answers result))) - (priorities (mapcar (lambda (r) - (dns-get 'priority r)) - data)) + ;; We may get junk data back (or CNAME; + ;; ignore). + (and (eq (dns-get 'type answers) 'SRV) + answers))) + (priorities (and (mapcar (lambda (r) + (dns-get 'priority r)) + data))) (max-priority (if priorities (apply #'max priorities) 0)) commit 64d464886983378b9fa62a38b31ec6fc996f587b Author: Lars Ingebrigtsen Date: Thu Jan 28 09:57:48 2021 +0100 Fix numerical `comment-padding' value * lisp/newcomment.el (comment-padright): Allow using a number for `comment-padding', like the doc string says (bug#40056). diff --git a/lisp/newcomment.el b/lisp/newcomment.el index 4216fc1a39..ea47eec4fd 100644 --- a/lisp/newcomment.el +++ b/lisp/newcomment.el @@ -832,12 +832,17 @@ Ensure that `comment-normalize-vars' has been called before you use this." (when (and (stringp str) (string-match "\\S-" str)) ;; Separate the actual string from any leading/trailing padding (string-match "\\`\\s-*\\(.*?\\)\\s-*\\'" str) - (let ((s (match-string 1 str)) ;actual string + (let ((s (match-string 1 str)) ;actual string (lpad (substring str 0 (match-beginning 1))) ;left padding - (rpad (concat (substring str (match-end 1)) ;original right padding - (substring comment-padding ;additional right padding - (min (- (match-end 0) (match-end 1)) - (length comment-padding))))) + (rpad (concat + (substring str (match-end 1)) ;original right padding + (if (numberp comment-padding) + (make-string (min comment-padding + (- (match-end 0) (match-end 1))) + ?\s) + (substring comment-padding ;additional right padding + (min (- (match-end 0) (match-end 1)) + (length comment-padding)))))) ;; We can only duplicate C if the comment-end has multiple chars ;; or if comments can be nested, else the comment-end `}' would ;; be turned into `}}}' where only the first ends the comment @@ -852,7 +857,7 @@ Ensure that `comment-normalize-vars' has been called before you use this." (concat (mapconcat (lambda (c) (concat (regexp-quote (string c)) "?")) lpad "") ;padding is not required (regexp-quote s) - (when multi "+") ;the last char of S might be repeated + (when multi "+") ;the last char of S might be repeated (mapconcat (lambda (c) (concat (regexp-quote (string c)) "?")) rpad "")))))) ;padding is not required commit 8992f8abf348b5b4eb2b2074d00b9c9aaaa6df17 Author: Lars Ingebrigtsen Date: Thu Jan 28 08:40:15 2021 +0100 Make the default `whitespace-enable-predicate' use `derived-mode-p' * lisp/whitespace.el (whitespace-enable-predicate): Use `derived-mode-p' to check modes instead of `eq' (bug#40481). diff --git a/etc/NEWS b/etc/NEWS index e038076e96..f12c94d649 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1098,6 +1098,11 @@ If present in 'whitespace-style' (as it is by default), the final character in the buffer will be highlighted if the buffer doesn't end with a newline. +--- +*** The default 'whitespace-enable-predicate' predicate has changed. +It used to check elements in the list version of +'whitespace-global-modes' with 'eq', but now uses 'derived-mode-p'. + ** Texinfo --- diff --git a/lisp/whitespace.el b/lisp/whitespace.el index 7b8e5b7cc1..22bfae0697 100644 --- a/lisp/whitespace.el +++ b/lisp/whitespace.el @@ -1000,8 +1000,8 @@ See also `whitespace-style', `whitespace-newline' and ((eq whitespace-global-modes t)) ((listp whitespace-global-modes) (if (eq (car-safe whitespace-global-modes) 'not) - (not (memq major-mode (cdr whitespace-global-modes))) - (memq major-mode whitespace-global-modes))) + (not (apply #'derived-mode-p (cdr whitespace-global-modes))) + (apply #'derived-mode-p whitespace-global-modes))) (t nil)) ;; ...we have a display (not running a batch job) (not noninteractive) commit e7e7ef15886ce28d1d1873164e7ee17a6a5878e0 Author: Mattias M Date: Thu Jan 28 07:34:10 2021 +0100 Fix fill-paragraph in asm-mode * lisp/progmodes/asm-mode.el: The value of fill-prefix ought to be nil not "\t" so that fill-context-prefix can do its thing. In fact, fill-prefix does not have to be set at all becuase asm-mode derives from prog-mode and fill-prefix is set in simple.el. * test/lisp/progmodes/asm-mode-tests.el: Add relevant test (bug#41064). Copyright-paperwork-exempt: yes diff --git a/lisp/progmodes/asm-mode.el b/lisp/progmodes/asm-mode.el index 62ff783fba..99b2ec6d87 100644 --- a/lisp/progmodes/asm-mode.el +++ b/lisp/progmodes/asm-mode.el @@ -141,8 +141,7 @@ Special commands: (setq-local comment-add 1) (setq-local comment-start-skip "\\(?:\\s<+\\|/[/*]+\\)[ \t]*") (setq-local comment-end-skip "[ \t]*\\(\\s>\\|\\*+/\\)") - (setq-local comment-end "") - (setq fill-prefix "\t")) + (setq-local comment-end "")) (defun asm-indent-line () "Auto-indent the current line." diff --git a/test/lisp/progmodes/asm-mode-tests.el b/test/lisp/progmodes/asm-mode-tests.el index 6ae4fdf585..87872179d9 100644 --- a/test/lisp/progmodes/asm-mode-tests.el +++ b/test/lisp/progmodes/asm-mode-tests.el @@ -69,4 +69,14 @@ (should (string-match-p ";;; \nlabel:" (buffer-string))) (should (= (current-column) 4)))) +(ert-deftest asm-mode-tests-fill-comment () + (asm-mode-tests--with-temp-buffer + (call-interactively #'comment-dwim) + (insert "Pellentesque condimentum, magna ut suscipit hendrerit, \ +ipsum augue ornare nulla, non luctus diam neque sit amet urna.") + (call-interactively #'fill-paragraph) + (should (equal (buffer-string) "\t;; Pellentesque condimentum, \ +magna ut suscipit hendrerit,\n\t;; ipsum augue ornare nulla, non \ +luctus diam neque sit amet\n\t;; urna.")))) + ;;; asm-mode-tests.el ends here commit 0870ebb3cbfcb097d85eea5eacaf992dd88ed204 Author: Lars Ingebrigtsen Date: Thu Jan 28 07:09:18 2021 +0100 Allow commenting out white space lines in latex-mode * lisp/newcomment.el (comment-region-default-1): Allow commenting out whitespace-only regions (bug#41793). * lisp/textmodes/tex-mode.el (latex--comment-region): Use it. (latex-mode): Set a comment style shim. diff --git a/lisp/newcomment.el b/lisp/newcomment.el index 5d0d1053f4..4216fc1a39 100644 --- a/lisp/newcomment.el +++ b/lisp/newcomment.el @@ -1221,21 +1221,33 @@ changed with `comment-style'." ;; FIXME: maybe we should call uncomment depending on ARG. (funcall comment-region-function beg end arg))) -(defun comment-region-default-1 (beg end &optional arg) +(defun comment-region-default-1 (beg end &optional arg noadjust) + "Comment region between BEG and END. +See `comment-region' for ARG. If NOADJUST, do not skip past +leading/trailing space when determining the region to comment +out." (let* ((numarg (prefix-numeric-value arg)) (style (cdr (assoc comment-style comment-styles))) (lines (nth 2 style)) (block (nth 1 style)) (multi (nth 0 style))) - ;; We use `chars' instead of `syntax' because `\n' might be - ;; of end-comment syntax rather than of whitespace syntax. - ;; sanitize BEG and END - (goto-char beg) (skip-chars-forward " \t\n\r") (beginning-of-line) - (setq beg (max beg (point))) - (goto-char end) (skip-chars-backward " \t\n\r") (end-of-line) - (setq end (min end (point))) - (if (>= beg end) (error "Nothing to comment")) + (if noadjust + (when (bolp) + (setq end (1- end))) + ;; We use `chars' instead of `syntax' because `\n' might be + ;; of end-comment syntax rather than of whitespace syntax. + ;; sanitize BEG and END + (goto-char beg) + (skip-chars-forward " \t\n\r") + (beginning-of-line) + (setq beg (max beg (point))) + (goto-char end) + (skip-chars-backward " \t\n\r") + (end-of-line) + (setq end (min end (point))) + (when (>= beg end) + (error "Nothing to comment"))) ;; sanitize LINES (setq lines diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el index c4e4864da1..ce665e6165 100644 --- a/lisp/textmodes/tex-mode.el +++ b/lisp/textmodes/tex-mode.el @@ -1169,7 +1169,12 @@ subshell is initiated, `tex-shell-hook' is run." (setq-local outline-regexp latex-outline-regexp) (setq-local outline-level #'latex-outline-level) (setq-local forward-sexp-function #'latex-forward-sexp) - (setq-local skeleton-end-hook nil)) + (setq-local skeleton-end-hook nil) + (setq-local comment-region-function #'latex--comment-region) + (setq-local comment-style 'plain)) + +(defun latex--comment-region (beg end &optional arg) + (comment-region-default-1 beg end arg t)) ;;;###autoload (define-derived-mode slitex-mode latex-mode "SliTeX" commit e4c667079086528c6e0a9eead9c2d4d5f5b7c6e1 Author: Lars Ingebrigtsen Date: Thu Jan 28 06:21:40 2021 +0100 Fix Gnus icalendar button navigation * lisp/gnus/gnus-icalendar.el (gnus-icalendar-insert-button): Mark buttons correctly for TAB navigation (bug#46135). diff --git a/lisp/gnus/gnus-icalendar.el b/lisp/gnus/gnus-icalendar.el index 1e0e207101..9811e8b440 100644 --- a/lisp/gnus/gnus-icalendar.el +++ b/lisp/gnus/gnus-icalendar.el @@ -835,6 +835,7 @@ These will be used to retrieve the RSVP information from ical events." keymap ,gnus-mime-button-map face ,gnus-article-button-face follow-link t + category t button t gnus-data ,data)))) commit 9b01bc568278a939bd7e36a37623153d07171894 Author: Harald Jörg Date: Thu Jan 28 04:22:21 2021 +0100 perl-mode.el: Eliminate keywords which are not in Perl. * lisp/progmodes/perl-mode.el (perl-imenu-generic-expression): Remove keywords which are not part of Perl. (perl-font-lock-keywords-2): Remove keywords which are not part of Perl (bug#46024). (These keywords are part of Raku; aka. Perl 6.) diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el index d047dd543c..0120e4a7cd 100644 --- a/lisp/progmodes/perl-mode.el +++ b/lisp/progmodes/perl-mode.el @@ -143,7 +143,7 @@ '(;; Functions (nil "^[ \t]*sub\\s-+\\([-[:alnum:]+_:]+\\)" 1) ;;Variables - ("Variables" "^[ \t]*\\(?:anon\\|argument\\|has\\|local\\|my\\|our\\|state\\|supersede\\)\\s-+\\([$@%][-[:alnum:]+_:]+\\)\\s-*=" 1) + ("Variables" "^[ \t]*\\(?:has\\|local\\|my\\|our\\|state\\)\\s-+\\([$@%][-[:alnum:]+_:]+\\)\\s-*=" 1) ("Packages" "^[ \t]*package\\s-+\\([-[:alnum:]+_:]+\\);" 1) ("Doc sections" "^=head[0-9][ \t]+\\(.*\\)" 1)) "Imenu generic expression for Perl mode. See `imenu-generic-expression'.") @@ -188,9 +188,8 @@ "\\>") ;; ;; Fontify declarators and prefixes as types. - ("\\<\\(anon\\|argument\\|has\\|local\\|my\\|our\\|state\\|supersede\\)\\>" . font-lock-type-face) ; declarators - ("\\<\\(let\\|temp\\)\\>" . font-lock-type-face) ; prefixes - ;; + ("\\<\\(has\\|local\\|my\\|our\\|state\\)\\>" . font-lock-type-face) ; declarators + ;; ;; Fontify function, variable and file name references. ("&\\(\\sw+\\(::\\sw+\\)*\\)" 1 font-lock-function-name-face) ;; Additionally fontify non-scalar variables. `perl-non-scalar-variable' commit 2a71831eb3dcd122ee4f91254b31a801922c7917 Author: João Távora Date: Thu Jan 28 04:18:12 2021 +0100 Allow project/xref packages to be used in Emacs 26.1 * lisp/progmodes/project.el: Change Package-Requires to Emacs 26.1 (bug#44671). * lisp/progmodes/xref.el: Ditto. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 768cd58ae4..fc5e30111e 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1,8 +1,8 @@ ;;; project.el --- Operations on the current project -*- lexical-binding: t; -*- ;; Copyright (C) 2015-2021 Free Software Foundation, Inc. -;; Version: 0.5.3 -;; Package-Requires: ((emacs "26.3") (xref "1.0.2")) +;; Version: 0.5.4 +;; Package-Requires: ((emacs "26.1") (xref "1.0.2")) ;; This is a GNU ELPA :core package. Avoid using functionality that ;; not compatible with the version of Emacs recorded above. diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 898cb4fb4c..07a65d4ed9 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -2,7 +2,7 @@ ;; Copyright (C) 2014-2021 Free Software Foundation, Inc. ;; Version: 1.0.4 -;; Package-Requires: ((emacs "26.3")) +;; Package-Requires: ((emacs "26.1")) ;; This is a GNU ELPA :core package. Avoid functionality that is not ;; compatible with the version of Emacs recorded above. commit 30914167fd49e208c483541663f0275253e42227 Author: Stefan Monnier Date: Wed Jan 27 18:53:58 2021 -0500 * lisp/emacs-lisp/macroexp.el (macroexp-if): Fix typo diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index 78f0b636a7..e842222b7c 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -377,7 +377,7 @@ Never returns an empty list." (t `(cond (,test ,@(macroexp-unprogn then)) (,(nth 1 else) ,@(macroexp-unprogn (nth 2 else))) - ,@(let ((def (nthcdr 3 else))) (if def '((t ,@def)))))))) + ,@(let ((def (nthcdr 3 else))) (if def `((t ,@def)))))))) ((eq (car-safe else) 'cond) `(cond (,test ,@(macroexp-unprogn then)) ,@(cdr else))) ;; Invert the test if that lets us reduce the depth of the tree. commit d93bca019713e98228aca9f4d1a4838a72b1cf92 Author: Stefan Monnier Date: Wed Jan 27 18:51:09 2021 -0500 * lisp/emacs-lisp/pcase.el (pcase--split-pred): Handle `memq` pred. Improve handling of the `member` tests generated from (or 'a 'b 'c). This will expand (pcase EXP ((and (or 1 2 3) (guard (FOO))) EXP1) (1 EXP2) (6 EXP3)) to (cond ((memql '(3 2 1) EXP) (cond ((FOO) EXP1) ((eql EXP 1) EXP2))) ((eql EXP 6) EXP3)) rather than to (cond ((memql '(3 2 1) EXP) (cond ((FOO) EXP1) ((eql EXP 1) EXP2) ((eql EXP 6) EXP3))) ((eql EXP 1) EXP2) ((eql EXP 6) EXP3)) diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index bfd577c5d1..cf129c453e 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -683,11 +683,6 @@ A and B can be one of: ;; and catch at least the easy cases such as (bug#14773). (not (macroexp--fgrep (mapcar #'car vars) (cadr upat))))) '(:pcase--succeed . :pcase--fail)) - ;; In case UPAT is of the form (pred (not PRED)) - ((and (eq 'pred (car upat)) (eq 'not (car-safe (cadr upat)))) - (let* ((test (cadr (cadr upat))) - (res (pcase--split-pred vars `(pred ,test) pat))) - (cons (cdr res) (car res)))) ;; In case PAT is of the form (pred (not PRED)) ((and (eq 'pred (car-safe pat)) (eq 'not (car-safe (cadr pat)))) (let* ((test (cadr (cadr pat))) @@ -696,19 +691,34 @@ A and B can be one of: ((eq x :pcase--fail) :pcase--succeed))))) (cons (funcall reverse (car res)) (funcall reverse (cdr res))))) - ((and (eq 'pred (car upat)) - (let ((otherpred - (cond ((eq 'pred (car-safe pat)) (cadr pat)) - ((not (eq 'quote (car-safe pat))) nil) - ((consp (cadr pat)) #'consp) - ((stringp (cadr pat)) #'stringp) - ((vectorp (cadr pat)) #'vectorp) - ((byte-code-function-p (cadr pat)) - #'byte-code-function-p)))) - (pcase--mutually-exclusive-p (cadr upat) otherpred))) + ;; All the rest below presumes UPAT is of the form (pred ...). + ((not (eq 'pred (car upat))) nil) + ;; In case UPAT is of the form (pred (not PRED)) + ((eq 'not (car-safe (cadr upat))) + (let* ((test (cadr (cadr upat))) + (res (pcase--split-pred vars `(pred ,test) pat))) + (cons (cdr res) (car res)))) + ((let ((otherpred + (cond ((eq 'pred (car-safe pat)) (cadr pat)) + ((not (eq 'quote (car-safe pat))) nil) + ((consp (cadr pat)) #'consp) + ((stringp (cadr pat)) #'stringp) + ((vectorp (cadr pat)) #'vectorp) + ((byte-code-function-p (cadr pat)) + #'byte-code-function-p)))) + (pcase--mutually-exclusive-p (cadr upat) otherpred)) '(:pcase--fail . nil)) - ((and (eq 'pred (car upat)) - (eq 'quote (car-safe pat)) + ;; Since we turn (or 'a 'b 'c) into (pred (pcase--flip (memq '(a b c)))) + ;; try and preserve the info we get from that memq test. + ((and (eq 'pcase--flip (car-safe (cadr upat))) + (memq (cadr (cadr upat)) '(memq member memql)) + (eq 'quote (car-safe (nth 2 (cadr upat)))) + (eq 'quote (car-safe pat))) + (let ((set (cadr (nth 2 (cadr upat))))) + (if (member (cadr pat) set) + '(nil . :pcase--fail) + '(:pcase--fail . nil)))) + ((and (eq 'quote (car-safe pat)) (symbolp (cadr upat)) (or (symbolp (cadr pat)) (stringp (cadr pat)) (numberp (cadr pat))) (get (cadr upat) 'side-effect-free) commit d168110a322389a9f991d7a5bdd1cf777642c990 Author: Stefan Monnier Date: Wed Jan 27 17:35:28 2021 -0500 * lisp/emacs-lisp/macroexp.el (macroexp--expand-all): Perform β-reduction Also, in `funcall` macroexpand the function before checking to see if we can remove the `funcall`. (macroexp-if): Trim trailing `nil` in the generated code while we're at it. diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index aa49bccc8d..78f0b636a7 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -241,9 +241,22 @@ Assumes the caller has bound `macroexpand-all-environment'." form)) (`(,(and fun `(lambda . ,_)) . ,args) ;; Embedded lambda in function position. - (macroexp--cons (macroexp--all-forms fun 2) - (macroexp--all-forms args) - form)) + ;; If the byte-optimizer is loaded, try to unfold this, + ;; i.e. rewrite it to (let () ). We'd do it in the optimizer + ;; anyway, but doing it here (i.e. earlier) can sometimes avoid the + ;; creation of a closure, thus resulting in much better code. + (let ((newform (if (not (fboundp 'byte-compile-unfold-lambda)) + 'macroexp--not-unfolded + ;; Don't unfold if byte-opt is not yet loaded. + (byte-compile-unfold-lambda form)))) + (if (or (eq newform 'macroexp--not-unfolded) + (eq newform form)) + ;; Unfolding failed for some reason, avoid infinite recursion. + (macroexp--cons (macroexp--all-forms fun 2) + (macroexp--all-forms args) + form) + (macroexp--expand-all newform)))) + ;; The following few cases are for normal function calls that ;; are known to funcall one of their arguments. The byte ;; compiler has traditionally handled these functions specially @@ -257,17 +270,21 @@ Assumes the caller has bound `macroexpand-all-environment'." (macroexp--warn-and-return (format "%s quoted with ' rather than with #'" (list 'lambda (nth 1 f) '...)) - (macroexp--expand-all `(,fun ,f . ,args)))) + (macroexp--expand-all `(,fun #',f . ,args)))) ;; Second arg is a function: (`(,(and fun (or 'sort)) ,arg1 ',(and f `(lambda . ,_)) . ,args) (macroexp--warn-and-return (format "%s quoted with ' rather than with #'" (list 'lambda (nth 1 f) '...)) - (macroexp--expand-all `(,fun ,arg1 ,f . ,args)))) - (`(funcall #',(and f (pred symbolp)) . ,args) - ;; Rewrite (funcall #'foo bar) to (foo bar), in case `foo' - ;; has a compiler-macro. - (macroexp--expand-all `(,f . ,args))) + (macroexp--expand-all `(,fun ,arg1 #',f . ,args)))) + (`(funcall ,exp . ,args) + (let ((eexp (macroexp--expand-all exp)) + (eargs (macroexp--all-forms args))) + ;; Rewrite (funcall #'foo bar) to (foo bar), in case `foo' + ;; has a compiler-macro, or to unfold it. + (pcase eexp + (`#',f (macroexp--expand-all `(,f . ,eargs))) + (_ `(funcall ,eexp . ,eargs))))) (`(,func . ,_) ;; Macro expand compiler macros. This cannot be delayed to ;; byte-optimize-form because the output of the compiler-macro can @@ -360,12 +377,12 @@ Never returns an empty list." (t `(cond (,test ,@(macroexp-unprogn then)) (,(nth 1 else) ,@(macroexp-unprogn (nth 2 else))) - (t ,@(nthcdr 3 else)))))) + ,@(let ((def (nthcdr 3 else))) (if def '((t ,@def)))))))) ((eq (car-safe else) 'cond) `(cond (,test ,@(macroexp-unprogn then)) ,@(cdr else))) ;; Invert the test if that lets us reduce the depth of the tree. ((memq (car-safe then) '(if cond)) (macroexp-if `(not ,test) else then)) - (t `(if ,test ,then ,@(macroexp-unprogn else))))) + (t `(if ,test ,then ,@(if else (macroexp-unprogn else)))))) (defmacro macroexp-let2 (test sym exp &rest body) "Evaluate BODY with SYM bound to an expression for EXP's value. commit 9f25ca5107fdb0b6da268d0a41a30aa2e55a1c64 Author: Juri Linkov Date: Wed Jan 27 20:33:13 2021 +0200 * lisp/replace.el (query-replace-read-from-suggestions): New function. (query-replace-read-from): Use it instead of hard-coded '(car search-ring)'. (read-regexp-suggestions): Add the active region (bug#41692). diff --git a/lisp/replace.el b/lisp/replace.el index 4483d7f780..cbf24bedef 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -186,6 +186,21 @@ See `replace-regexp' and `query-replace-regexp-eval'.") length) length))))) +(defun query-replace-read-from-suggestions () + "Return a list of standard suggestions for `query-replace-read-from'. +By default, the list includes the active region, the identifier +(a.k.a. \"tag\") at point (see Info node `(emacs) Identifier Search'), +the last isearch string, and the last replacement regexp. +`query-replace-read-from' appends the list returned +by this function to the end of values available via +\\\\[next-history-element]." + (delq nil (list (when (use-region-p) + (buffer-substring-no-properties + (region-beginning) (region-end))) + (find-tag-default) + (car search-ring) + (car (symbol-value query-replace-from-history-variable))))) + (defun query-replace-read-from (prompt regexp-flag) "Query and return the `from' argument of a query-replace operation. Prompt with PROMPT. REGEXP-FLAG non-nil means the response should be a regexp. @@ -242,7 +257,8 @@ wants to replace FROM with TO." (if regexp-flag (read-regexp prompt nil 'minibuffer-history) (read-from-minibuffer - prompt nil nil nil nil (car search-ring) t))))) + prompt nil nil nil nil + (query-replace-read-from-suggestions) t))))) (to)) (if (and (zerop (length from)) query-replace-defaults) (cons (caar query-replace-defaults) @@ -808,13 +824,16 @@ the function that you set this to can check `this-command'." (defun read-regexp-suggestions () "Return a list of standard suggestions for `read-regexp'. -By default, the list includes the identifier (a.k.a. \"tag\") -at point (see Info node `(emacs) Identifier Search'), the last -isearch regexp, the last isearch string, and the last +By default, the list includes the active region, the identifier +(a.k.a. \"tag\") at point (see Info node `(emacs) Identifier Search'), +the last isearch regexp, the last isearch string, and the last replacement regexp. `read-regexp' appends the list returned by this function to the end of values available via \\\\[next-history-element]." (list + (when (use-region-p) + (buffer-substring-no-properties + (region-beginning) (region-end))) (find-tag-default-as-regexp) (find-tag-default-as-symbol-regexp) (car regexp-search-ring) commit f5d30d9d8b7665216e596b11730964937c6c610d Author: Paul Eggert Date: Wed Jan 27 10:10:44 2021 -0800 * admin/notes/unicode: titdic-cnv.el is now utf-8. diff --git a/admin/notes/unicode b/admin/notes/unicode index 45455d897f..d69d5418e2 100644 --- a/admin/notes/unicode +++ b/admin/notes/unicode @@ -256,15 +256,6 @@ nontrivial changes to the build process. etc/tutorials/TUTORIAL.ja - * iso-2022-7bit - - This file contains multiple Chinese charsets, and converting it - to UTF-8 would lose the charset property and would change the - code's behavior. Although this could be worked around by - propertizing the strings, that hasn't been done. - - lisp/international/titdic-cnv.el - * utf-8-emacs These files contain characters that cannot be encoded in UTF-8. commit 85f8b575001ec8c3503d7e8746862e49c0c7a3bf Author: Juri Linkov Date: Wed Jan 27 20:08:43 2021 +0200 Support multi-line prompt and contents in previous-line-or-history-element. * lisp/simple.el (previous-line-or-history-element): Move to the beginning of minibuffer contents if there is editable minibuffer contents on the same line after moving point to the prompt (bug#46033). Fix minimal old-column from 0 to 1 to put point at the beginning of minibuffer contents after going to the previous history element. diff --git a/lisp/simple.el b/lisp/simple.el index c878fdab92..e82b138b0d 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -2472,14 +2472,24 @@ previous element of the minibuffer history in the minibuffer." (save-excursion (goto-char (1- prompt-end)) (current-column))) - 0) + 1) (current-column))))) (condition-case nil (with-no-warnings (previous-line arg) ;; Avoid moving point to the prompt (when (< (point) (minibuffer-prompt-end)) - (signal 'beginning-of-buffer nil))) + ;; If there is minibuffer contents on the same line + (if (<= (minibuffer-prompt-end) + (save-excursion + (if (or truncate-lines (not line-move-visual)) + (end-of-line) + (end-of-visual-line)) + (point))) + ;; Move to the beginning of minibuffer contents + (goto-char (minibuffer-prompt-end)) + ;; Otherwise, go to the previous history element + (signal 'beginning-of-buffer nil)))) (beginning-of-buffer ;; Restore old position since `line-move-visual' moves point to ;; the beginning of the line when it fails to go to the previous line. commit 2d8daac122e71dd5ee69a991c9c1dd0d31c2433f Author: Stefan Monnier Date: Wed Jan 27 12:35:19 2021 -0500 * lisp/international/titdic-cnv.el (tsang-quick-converter): Simplify Merge branches which only differed in the `charset` property of the strings they intended to return, since that info gets lost later on anyway. diff --git a/lisp/international/titdic-cnv.el b/lisp/international/titdic-cnv.el index 84e218f179..ce5c04293a 100644 --- a/lisp/international/titdic-cnv.el +++ b/lisp/international/titdic-cnv.el @@ -375,7 +375,7 @@ SPC, 6, 3, 4, or 7 specifying a tone (SPC:陰平, 6:陽平, 3:上聲, 4:去聲, ;; Arg DOCSTRING (let ((doc (concat tit-prompt "\n")) (comments (if tit-comments - (mapconcat 'identity (nreverse tit-comments) "\n"))) + (mapconcat #'identity (nreverse tit-comments) "\n"))) (doc-ext (nth 2 (assoc package quail-cxterm-package-ext-info)))) (if comments (setq doc (concat doc "\n" comments "\n"))) @@ -737,12 +737,10 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"." ;; method is for inputting CNS characters. (defun tsang-quick-converter (dicbuf tsang-p big5-p) - (let ((fulltitle (if tsang-p (if big5-p "倉頡" "倉頡") - (if big5-p "簡易" "簡易"))) + (let ((fulltitle (if tsang-p "倉頡" "簡易")) dic) (goto-char (point-max)) - (if big5-p - (insert (format "\"中文輸入【%s】BIG5 + (insert (format "\"中文輸入【%s】%s 漢語%s輸入鍵盤 @@ -753,19 +751,7 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"." [Z ] [X 難] [C 金] [V 女] [B 月] [N 弓] [M 一] \\\\\"\n" - fulltitle fulltitle)) - (insert (format "\"中文輸入【%s】CNS - - 漢語%s輸入鍵盤 - - [Q 手] [W 田] [E 水] [R 口] [T 廿] [Y 卜] [U 山] [I 戈] [O 人] [P 心] - - [A 日] [S 尸] [D 木] [F 火] [G 土] [H 竹] [J 十] [L 中] - - [Z ] [X 難] [C 金] [V 女] [B 月] [N 弓] [M 一] - -\\\\\"\n" - fulltitle fulltitle))) + fulltitle (if big5-p "BIG5" "CNS") fulltitle)) (insert " '((\".\" . quail-next-translation-block) (\",\" . quail-prev-translation-block)) nil nil)\n\n") @@ -953,7 +939,7 @@ method `chinese-tonepy' with which you must specify tones by digits (= (length (aref trans i)) 1)) (setq i (1+ i))) (if (= i len) - (setq trans (mapconcat 'identity trans ""))))) + (setq trans (mapconcat #'identity trans ""))))) (setq dic (cons (cons key trans) dic))) table))) (setq dic (sort dic (lambda (x y) (string< (car x) (car y))))) commit 89327ce68d096da9539f5032f598870ba97155c7 Author: Stefan Monnier Date: Wed Jan 27 12:25:52 2021 -0500 * lisp/international/titdic-cnv.el: Revert to utf-8 encoding While it's true that using the iso-2022-jp encoding on the file does allow Emacs to render the two strings differently, this only applies to the source file. The .elc files all use `utf-8-emacs` encoding anyway, so that info is lost. And the difference is even lost before we write the .elc file because when Emacs byte-compiles that code the byte-compiler considers those two strings as "equal" and emits only one string in the byte-code (so the two branches return `eq` strings). So, I think using `iso-2022-jp` is a bad idea here: it gives the illusion that the the `charset` info exists, even it will be lost. Eli discussed it with Handa-san a year ago, and they arrived at the conclusion that the charset information is indeed no longer important. diff --git a/lisp/international/titdic-cnv.el b/lisp/international/titdic-cnv.el index 753139e5dd..84e218f179 100644 --- a/lisp/international/titdic-cnv.el +++ b/lisp/international/titdic-cnv.el @@ -1,4 +1,4 @@ -;;; titdic-cnv.el --- convert cxterm dictionary (TIT format) to Quail package -*- coding:iso-2022-7bit; lexical-binding:t -*- +;;; titdic-cnv.el --- convert cxterm dictionary (TIT format) to Quail package -*- coding: utf-8-emacs; lexical-binding:t -*- ;; Copyright (C) 1997-1998, 2000-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, @@ -83,9 +83,9 @@ ;; how to select a translation from a list of candidates. (defvar quail-cxterm-package-ext-info - '(("chinese-4corner" "$(0(?-F(B") - ("chinese-array30" "$(0#R#O(B") - ("chinese-ccdospy" "$AKuF4(B" + '(("chinese-4corner" "四角") + ("chinese-array30" "30") + ("chinese-ccdospy" "缩拼" "Pinyin base input method for Chinese charset GB2312 (`chinese-gb2312'). Pinyin is the standard Roman transliteration method for Chinese. @@ -94,10 +94,10 @@ method `chinese-py'. This input method works almost the same way as `chinese-py'. The difference is that you type a single key for these Pinyin spelling. - Pinyin: zh en eng ang ch an ao ai ong sh ing yu($A(9(B) + Pinyin: zh en eng ang ch an ao ai ong sh ing yu(ü) keyseq: a f g h i j k l s u y v For example: - Chinese: $A0!(B $A9{(B $AVP(B $AND(B $A9b(B $ASq(B $AH+(B + Chinese: 啊 果 中 文 光 玉 全 Pinyin: a guo zhong wen guang yu quan Keyseq: a1 guo4 as1 wf4 guh1 yu..6 qvj6 @@ -106,14 +106,14 @@ For example: For double-width GB2312 characters corresponding to ASCII, use the input method `chinese-qj'.") - ("chinese-ecdict" "$(05CKH(B" + ("chinese-ecdict" "英漢" "In this input method, you enter a Chinese (Big5) character or word by typing the corresponding English word. For example, if you type -\"computer\", \"$(0IZH+(B\" is input. +\"computer\", \"電腦\" is input. \\") - ("chinese-etzy" "$(06/0D(B" + ("chinese-etzy" "倚注" "Zhuyin base input method for Chinese Big5 characters (`chinese-big5-1', `chinese-big5-2'). @@ -122,20 +122,20 @@ compose one Chinese character. In this input method, you enter a Chinese character by first typing keys corresponding to Zhuyin symbols (see the above table) followed by -SPC, 1, 2, 3, or 4 specifying a tone (SPC:$(0?v(N(B, 1:$(0M=Vy(B, 2:$(0Dm(N(B, 3: $(0&9Vy(B, -4:$(0(+Vy(B). +SPC, 1, 2, 3, or 4 specifying a tone (SPC:陰平, 1:輕聲, 2:陽平, 3: 上聲, +4:去聲). \\") - ("chinese-punct-b5" "$(0O:(BB" + ("chinese-punct-b5" "標B" "Input method for Chinese punctuation and symbols of Big5 \(`chinese-big5-1' and `chinese-big5-2').") - ("chinese-punct" "$A1j(BG" + ("chinese-punct" "标G" "Input method for Chinese punctuation and symbols of GB2312 \(`chinese-gb2312').") - ("chinese-py-b5" "$(03<(BB" + ("chinese-py-b5" "拼B" "Pinyin base input method for Chinese Big5 characters \(`chinese-big5-1', `chinese-big5-2'). @@ -153,28 +153,28 @@ method `chinese-qj-b5'. The input method `chinese-py' and `chinese-tonepy' are also Pinyin based, but for the character set GB2312 (`chinese-gb2312').") - ("chinese-qj-b5" "$(0)A(BB") + ("chinese-qj-b5" "全B") - ("chinese-qj" "$AH+(BG") + ("chinese-qj" "全G") - ("chinese-sw" "$AJWN2(B" + ("chinese-sw" "首尾" "Radical base input method for Chinese charset GB2312 (`chinese-gb2312'). In this input method, you enter a Chinese character by typing two -keys. The first key corresponds to the first ($AJW(B) radical, the second -key corresponds to the last ($AN2(B) radical. The correspondence of keys +keys. The first key corresponds to the first (首) radical, the second +key corresponds to the last (尾) radical. The correspondence of keys and radicals is as below: first radical: a b c d e f g h i j k l m n o p q r s t u v w x y z - $APD(B $AZ"(B $AJ,(B $AX<(B $A;p(B $A?Z(B $A^P(B $Ac_(B $AZ%(B $A\3(B $AXi(B $AD>(B $Alj(B $Ab;(B $ATB(B $Afy(B $AJ/(B $AMu(B $A0K(B $AX/(B $AHU(B $AeA(B $Aak(B $AVq(B $AR;(B $AHK(B + 心 冖 尸 丶 火 口 扌 氵 讠 艹 亻 木 礻 饣 月 纟 石 王 八 丿 日 辶 犭 竹 一 人 last radical: a b c d e f g h i j k l m n o p q r s t u v w x y z - $ASV(B $AI=(B $AMA(B $A56(B $AZb(B $A?Z(B $ARB(B $Aqb(B $A4s(B $A6!(B $A[L(B $Ala(B $AJ.(B $A4u(B $AXg(B $ACE(B $A=q(B $AX-(B $AE.(B $ARR(B $A`m(B $AP!(B $A3'(B $A3f(B $A_.(B $A27(B + 又 山 土 刀 阝 口 衣 疋 大 丁 厶 灬 十 歹 冂 门 今 丨 女 乙 囗 小 厂 虫 弋 卜 \\") - ("chinese-tonepy" "$A5wF4(B" + ("chinese-tonepy" "调拼" "Pinyin base input method for Chinese charset GB2312 (`chinese-gb2312'). Pinyin is the standard roman transliteration method for Chinese. @@ -183,18 +183,18 @@ method `chinese-py'. This input method works almost the same way as `chinese-py'. The difference is that you must type 1..5 after each Pinyin spelling to -specify a tone (1:$ARuF=(B, 2:$AQtF=(B, 3:$AIOIy(B, 4$AOBIy(B, 5:$AGaIy(B). +specify a tone (1:阴平, 2:阳平, 3:上声, 4下声, 5:轻声). \\ -For instance, to input $ADc(B, you type \"n i 3 3\", the first \"n i\" is +For instance, to input 你, you type \"n i 3 3\", the first \"n i\" is a Pinyin, the next \"3\" specifies tone, and the last \"3\" selects the third character from the candidate list. For double-width GB2312 characters corresponding to ASCII, use the input method `chinese-qj'.") - ("chinese-zozy" "$(0I\0D(B" + ("chinese-zozy" "零注" "Zhuyin base input method for Chinese Big5 characters (`chinese-big5-1', `chinese-big5-2'). @@ -203,8 +203,8 @@ compose a Chinese character. In this input method, you enter a Chinese character by first typing keys corresponding to Zhuyin symbols (see the above table) followed by -SPC, 6, 3, 4, or 7 specifying a tone (SPC:$(0?v(N(B, 6:$(0Dm(N(B, 3:$(0&9Vy(B, 4:$(0(+Vy(B, -7:$(0M=Vy(B). +SPC, 6, 3, 4, or 7 specifying a tone (SPC:陰平, 6:陽平, 3:上聲, 4:去聲, +7:輕聲). \\"))) @@ -354,7 +354,7 @@ SPC, 6, 3, 4, or 7 specifying a tone (SPC:$(0?v(N(B, 6:$(0Dm(N(B, 3:$(0&9Vy (princ (nth 2 (assoc tit-encode tit-encode-list))) (princ "\" \"") (princ (or title - (if (string-match "[:$A!K$(0!(!J(B]+\\([^:$A!K$(0!(!K(B]+\\)" tit-prompt) + (if (string-match "[:∷:【]+\\([^:∷:】]+\\)" tit-prompt) (substring tit-prompt (match-beginning 1) (match-end 1)) tit-prompt))) (princ "\"\n")) @@ -580,7 +580,7 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"." ;; ) (defvar quail-misc-package-ext-info - '(("chinese-b5-tsangchi" "$(06A(BB" + '(("chinese-b5-tsangchi" "倉B" "cangjie-table.b5" big5 "tsang-b5.el" tsang-b5-converter "\ @@ -590,7 +590,7 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"." ;; # unmodified versions is granted without royalty provided ;; # this notice is preserved.") - ("chinese-b5-quick" "$(0X|(BB" + ("chinese-b5-quick" "簡B" "cangjie-table.b5" big5 "quick-b5.el" quick-b5-converter "\ @@ -600,7 +600,7 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"." ;; # unmodified versions is granted without royalty provided ;; # this notice is preserved.") - ("chinese-cns-tsangchi" "$(GT?(BC" + ("chinese-cns-tsangchi" "倉C" "cangjie-table.cns" iso-2022-cn-ext "tsang-cns.el" tsang-cns-converter "\ @@ -610,7 +610,7 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"." ;; # unmodified versions is granted without royalty provided ;; # this notice is preserved.") - ("chinese-cns-quick" "$(Gv|(BC" + ("chinese-cns-quick" "簡C" "cangjie-table.cns" iso-2022-cn-ext "quick-cns.el" quick-cns-converter "\ @@ -620,7 +620,7 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"." ;; # unmodified versions is granted without royalty provided ;; # this notice is preserved.") - ("chinese-py" "$AF4(BG" + ("chinese-py" "拼G" "pinyin.map" cn-gb-2312 "PY.el" py-converter "\ @@ -648,7 +648,7 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"." ;; You should have received a copy of the GNU General Public License along with ;; CCE. If not, see .") - ("chinese-ziranma" "$AWTH;(B" + ("chinese-ziranma" "自然" "ziranma.cin" cn-gb-2312 "ZIRANMA.el" ziranma-converter "\ @@ -676,7 +676,7 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"." ;; You should have received a copy of the GNU General Public License along with ;; CCE. If not, see .") - ("chinese-ctlau" "$AAuTA(B" + ("chinese-ctlau" "刘粤" "CTLau.html" cn-gb-2312 "CTLau.el" ctlau-gb-converter "\ @@ -701,7 +701,7 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"." ;; # You should have received a copy of the GNU General Public License ;; # along with this program. If not, see .") - ("chinese-ctlaub" "$(0N,Gn(B" + ("chinese-ctlaub" "劉粵" "CTLau-b5.html" big5 "CTLau-b5.el" ctlau-b5-converter "\ @@ -731,38 +731,38 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"." ;; dictionary in the buffer DICBUF. The input method name of the ;; Quail package is NAME, and the title string is TITLE. -;; TSANG-P is non-nil, generate $(06AQo(B input method. Otherwise -;; generate $(0X|/y(B (simple version of $(06AQo(B). If BIG5-P is non-nil, the +;; TSANG-P is non-nil, generate 倉頡 input method. Otherwise +;; generate 簡易 (simple version of 倉頡). If BIG5-P is non-nil, the ;; input method is for inputting Big5 characters. Otherwise the input ;; method is for inputting CNS characters. (defun tsang-quick-converter (dicbuf tsang-p big5-p) - (let ((fulltitle (if tsang-p (if big5-p "$(06AQo(B" "$(GT?on(B") - (if big5-p "$(0X|/y(B" "$(Gv|Mx(B"))) + (let ((fulltitle (if tsang-p (if big5-p "倉頡" "倉頡") + (if big5-p "簡易" "簡易"))) dic) (goto-char (point-max)) (if big5-p - (insert (format "\"$(0&d'GTT&,!J(B%s$(0!K(BBIG5 + (insert (format "\"中文輸入【%s】BIG5 - $(0KHM$(B%s$(0TT&,WoOu(B + 漢語%s輸入鍵盤 - [Q $(0'D(B] [W $(0(q(B] [E $(0'V(B] [R $(0&H(B] [T $(0'>(B] [Y $(0&4(B] [U $(0&U(B] [I $(0'B(B] [O $(0&*(B] [P $(0'A(B] + [Q 手] [W 田] [E 水] [R 口] [T 廿] [Y 卜] [U 山] [I 戈] [O 人] [P 心] - [A $(0'K(B] [S $(0&T(B] [D $(0'N(B] [F $(0'W(B] [G $(0&I(B] [H $(0*M(B] [J $(0&3(B] [L $(0&d(B] + [A 日] [S 尸] [D 木] [F 火] [G 土] [H 竹] [J 十] [L 中] - [Z ] [X $(0[E(B] [C $(01[(B] [V $(0&M(B] [B $(0'M(B] [N $(0&_(B] [M $(0&"(B] + [Z ] [X 難] [C 金] [V 女] [B 月] [N 弓] [M 一] \\\\\"\n" fulltitle fulltitle)) - (insert (format "\"$(GDcEFrSD+!J(B%s$(G!K(BCNS + (insert (format "\"中文輸入【%s】CNS - $(GiGk#(B%s$(GrSD+uomu(B + 漢語%s輸入鍵盤 - [Q $(GEC(B] [W $(GFp(B] [E $(GEU(B] [R $(GDG(B] [T $(GE=(B] [Y $(GD3(B] [U $(GDT(B] [I $(GEA(B] [O $(GD)(B] [P $(GE@(B] + [Q 手] [W 田] [E 水] [R 口] [T 廿] [Y 卜] [U 山] [I 戈] [O 人] [P 心] - [A $(GEJ(B] [S $(GDS(B] [D $(GEM(B] [F $(GEV(B] [G $(GDH(B] [H $(GHL(B] [J $(GD2(B] [L $(GDc(B] + [A 日] [S 尸] [D 木] [F 火] [G 土] [H 竹] [J 十] [L 中] - [Z ] [X $(GyE(B] [C $(GOZ(B] [V $(GDL(B] [B $(GEL(B] [N $(GD^(B] [M $(GD!(B] + [Z ] [X 難] [C 金] [V 女] [B 月] [N 弓] [M 一] \\\\\"\n" fulltitle fulltitle))) @@ -798,35 +798,35 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"." (setq dic (sort dic (lambda (x y) (string< (car x ) (car y))))) (dolist (elt dic) (insert (format "(%S\t%S)\n" (car elt) (cdr elt)))) - (let ((punctuation '((";" "$(0!'!2!"!#!.!/(B" "$(G!'!2!"!#!.!/(B") - (":" "$(0!(!+!3!%!$!&!0!1(B" "$(G!(!+!3!%!$!&!0!1(B") - ("'" "$(0!e!d(B" "$(G!e!d(B") - ("\"" "$(0!g!f!h!i!q(B" "$(G!g!f!h!i!q(B") - ("\\" "$(0"`"b#M(B" "$(G"`"b#M(B") - ("|" "$(0!6!8!:"^(B" "$(G!6!8!:"^(B") - ("/" "$(0"_"a#L(B" "$(G"_"a#L(B") - ("?" "$(0!)!4(B" "$(G!)!4(B") - ("<" "$(0!R"6"A!T"H(B" "$(G!R"6"A!T"H(B") - (">" "$(0!S"7"B!U(B" "$(G!S"7"B!U(B") - ("[" "$(0!F!J!b!H!L!V!Z!X!\(B" "$(G!F!J!b!H!L!V!Z!X!\(B") - ("]" "$(0!G!K!c!I!M!W![!Y!](B" "$(G!G!K!c!I!M!W![!Y!](B") - ("{" "$(0!B!`!D(B " "$(G!B!`!D(B ") - ("}" "$(0!C!a!E(B" "$(G!C!a!E(B") - ("`" "$(0!j!k(B" "$(G!j!k(B") - ("~" "$(0"D"+",!!^!@(B" "$(G!>!^!@(B") - (")" "$(0!?!_!A(B" "$(G!?!_!A(B") - ("-" "$(0!7!9"#"$"1"@(B" "$(G!7!9"#"$"1"@(B") - ("_" "$(0"%"&(B" "$(G"%"&(B") - ("=" "$(0"8"C(B" "$(G"8"C(B") - ("+" "$(0"0"?(B" "$(G"0"?(B")))) + (let ((punctuation '((";" ";﹔,、﹐﹑" ";﹔,、﹐﹑") + (":" ":︰﹕.。‧﹒·" ":︰﹕.。・﹒·") + ("'" "’‘" "’‘") + ("\"" "”“〝〞〃" "”“〝〞〃") + ("\\" "\﹨╲" "\﹨╲") + ("|" "|︱︳∣" "︱︲|") + ("/" "/∕╱" "/∕╱") + ("?" "?﹖" "?﹖") + ("<" "〈<﹤︿∠" "〈<﹤︿∠") + (">" "〉>﹥﹀" "〉>﹦﹀") + ("[" "〔【﹝︹︻「『﹁﹃" "〔【﹝︹︻「『﹁﹃") + ("]" "〕】﹞︺︼」』﹂﹄" "〕】﹞︺︼」』﹂﹄") + ("{" "{﹛︷ " "{﹛︷ ") + ("}" "}﹜︸" "}﹜︸") + ("`" "‵′" "′‵") + ("~" "~﹋﹌︴﹏" "∼﹋﹌") + ("!" "!﹗" "!﹗") + ("@" "@﹫" "@﹫") + ("#" "#﹟" "#﹟") + ("$" "$﹩" "$﹩") + ("%" "%﹪" "%﹪") + ("&" "&﹠" "&﹠") + ("*" "*﹡※☆★" "*﹡※☆★") + ("(" "(﹙︵" "(﹙︵") + (")" ")﹚︶" ")﹚︶") + ("-" "–—¯ ̄-﹣" "—–‾-﹣") + ("_" "_ˍ" "_") + ("=" "=﹦" "=﹥") + ("+" "+﹢" "+﹢")))) (dolist (elt punctuation) (insert (format "(%S %S)\n" (concat "z" (car elt)) (if big5-p (nth 1 elt) (nth 2 elt)))))) @@ -850,11 +850,11 @@ To get complete usage, invoke \"emacs -batch -f batch-titdic-convert -h\"." (defun py-converter (dicbuf) (goto-char (point-max)) - (insert (format "%S\n" "$A::WVJdHk!KF4Rt!K(B + (insert (format "%S\n" "汉字输入∷拼音∷ - $AF4Rt7=08(B + 拼音方案 - $AP!P4S"NDWVD84z1m!8F4Rt!97{:E#,(B \"u(yu) $ATrSC(B u: $A1mJ>!C(B + 小写英文字母代表「拼音」符号, \"u(yu) 则用 u: 表示∶ Pinyin base input method for Chinese charset GB2312 (`chinese-gb2312'). @@ -868,14 +868,14 @@ character. The sequence is made by the combination of the initials iang ing iong u ua uo uai ui uan un uan ueng yu yue yuan yun (Note: In the correct Pinyin writing, the sequence \"yu\" in the last - four finals should be written by the character u-umlaut `$A(9(B'.) + four finals should be written by the character u-umlaut `ü'.) With this input method, you enter a Chinese character by first entering its pinyin spelling. \\ -For instance, to input $ADc(B, you type \"n i C-n 3\". The first \"n i\" +For instance, to input 你, you type \"n i C-n 3\". The first \"n i\" is a Pinyin, \"C-n\" selects the next group of candidates (each group contains at most 10 characters), \"3\" select the third character in that group. @@ -958,22 +958,22 @@ method `chinese-tonepy' with which you must specify tones by digits table))) (setq dic (sort dic (lambda (x y) (string< (car x) (car y))))) (goto-char (point-max)) - (insert (format "%S\n" "$A::WVJdHk!K!>WTH;!?!K(B - - $A<|EL6TUU1m(B: - $A)3)%)%)W)%)%)W)%)%)W)%)%)W)%)%)W)%)%)W)%)%)W)%)%)W)%)%)W)%)%)7(B - $A)'#Q(B $A)'#W(B $A)'#E(B $A)'#R(B $A)'#T(B $A)'#Y(B $A)'#U(Bsh$A)'#I(Bch$A)'#O(B $A)'#P(B $A)'(B - $A)'(B iu$A)'(B ua$A)'(B e$A)'(B uan$A)'(B ue$A)'(B uai$A)'(B u$A)'(B i$A)'(B o$A)'(B un$A)'(B - $A)'(B $A)'(B ia$A)'(B $A)'(B van$A)'(B ve$A)'(B ing$A)'(B $A)'(B $A)'(B uo$A)'(B vn$A)'(B - $A);)W)%)_)W)%)_)W)%)_)W)%)_)W)%)_)W)%)_)W)%)_)W)%)_)W)%)_)W)%)?(B - $A)'#A(B $A)'#S(B $A)'#D(B $A)'#F(B $A)'#G(B $A)'#H(B $A)'#J(B $A)'#K(B $A)'#L(B $A)'(B - $A)'(B a$A)'(Biong$A)'(Buang$A)'(B en$A)'(B eng$A)'(B ang$A)'(B an$A)'(B ao$A)'(B ai$A)'(B - $A)'(B $A)'(B ong$A)'(Biang$A)'(B $A)'(B ng$A)'(B $A)'(B $A)'(B $A)'(B $A)'(B - $A);)W)%)_)W)%)_)W)%)_)W)%)_)W)%)_)W)%)_)W)%)_)W)%)_)W)%)_)W)%)%)7(B - $A)'#Z(B $A)'#X(B $A)'#C(B $A)'#V(Bzh$A)'#B(B $A)'#N(B $A)'#M(B $A)'#,(B $A)'#.(B $A)'(B $A#/(B $A)'(B - $A)'(B ei$A)'(B ie$A)'(B iao$A)'(B ui$A)'(B ou$A)'(B in$A)'(B ian$A)'G0R3)':sR3)'7{:E)'(B - $A)'(B $A)'(B $A)'(B $A)'(B v$A)'(B $A)'(B $A)'(B $A)'(B $A)'(B $A)'(B $A)'(B - $A);)%)%)_)%)%)_)%)%)_)%)%)_)%)%)_)%)%)_)%)%)_)%)%)_)%)%)_)%)%)?(B + (insert (format "%S\n" "汉字输入∷【自然】∷ + + 键盘对照表: + ┏━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┓ + ┃Q ┃W ┃E ┃R ┃T ┃Y ┃Ush┃Ich┃O ┃P ┃ + ┃ iu┃ ua┃ e┃ uan┃ ue┃ uai┃ u┃ i┃ o┃ un┃ + ┃ ┃ ia┃ ┃ van┃ ve┃ ing┃ ┃ ┃ uo┃ vn┃ + ┗┳━┻┳━┻┳━┻┳━┻┳━┻┳━┻┳━┻┳━┻┳━┻┳━┛ + ┃A ┃S ┃D ┃F ┃G ┃H ┃J ┃K ┃L ┃ + ┃ a┃iong┃uang┃ en┃ eng┃ ang┃ an┃ ao┃ ai┃ + ┃ ┃ ong┃iang┃ ┃ ng┃ ┃ ┃ ┃ ┃ + ┗┳━┻┳━┻┳━┻┳━┻┳━┻┳━┻┳━┻┳━┻┳━┻┳━━┓ + ┃Z ┃X ┃C ┃Vzh┃B ┃N ┃M ┃, ┃. ┃ / ┃ + ┃ ei┃ ie┃ iao┃ ui┃ ou┃ in┃ ian┃前页┃后页┃符号┃ + ┃ ┃ ┃ ┃ v┃ ┃ ┃ ┃ ┃ ┃ ┃ + ┗━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┛ Pinyin base input method for Chinese GB2312 characters (`chinese-gb2312'). @@ -985,34 +985,34 @@ method `chinese-py'. Unlike the standard spelling of Pinyin, in this input method all initials and finals are assigned to single keys (see the above table). For instance, the initial \"ch\" is assigned to the key `i', the final -\"iu\" is assigned to the key `q', and tones 1, 2, 3, 4, and $AGaIy(B are +\"iu\" is assigned to the key `q', and tones 1, 2, 3, 4, and 轻声 are assigned to the keys `q', `w', `e', `r', `t' respectively. \\ To input one-letter words, you type 4 keys, the first two for the Pinyin of the letter, next one for tone, and the last one is always a -quote ('). For instance, \"vsq'\" input $AVP(B. Exceptions are these +quote ('). For instance, \"vsq'\" input 中. Exceptions are these letters. You can input them just by typing a single key. - Character: $A04(B $A2;(B $A4N(B $A5D(B $A6~(B $A7"(B $A8v(B $A:M(B $A3v(B $A<0(B $A?I(B $AAK(B $AC;(B + Character: 按 不 次 的 二 发 个 和 出 及 可 了 没 Key: a b c d e f g h i j k l m - Character: $ADc(B $AE7(B $AF,(B $AF_(B $AHK(B $AH}(B $AK{(B $AJG(B $AWE(B $ANR(B $AP!(B $AR;(B $ATZ(B + Character: 你 欧 片 七 人 三 他 是 着 我 小 一 在 Key: n o p q r s t u v w x y z To input two-letter words, you have two ways. One way is to type 4 keys, two for the first Pinyin, two for the second Pinyin. For -instance, \"vsgo\" inputs $AVP9z(B. Another way is to type 3 keys: 2 +instance, \"vsgo\" inputs 中国. Another way is to type 3 keys: 2 initials of two letters, and quote ('). For instance, \"vg'\" also -inputs $AVP9z(B. +inputs 中国. To input three-letter words, you type 4 keys: initials of three -letters, and the last is quote ('). For instance, \"bjy'2\" inputs $A11(B -$A>)Q<(B (the last `2' is to select one of the candidates). +letters, and the last is quote ('). For instance, \"bjy'2\" inputs 北 +京鸭 (the last `2' is to select one of the candidates). To input words of more than three letters, you type 4 keys, initials of the first three letters and the last letter. For instance, -\"bjdt\" inputs $A11>)5gJSL((B. +\"bjdt\" inputs 北京电视台. To input symbols and punctuation, type `/' followed by one of `a' to `z', then select one of the candidates.")) @@ -1059,7 +1059,7 @@ To input symbols and punctuation, type `/' followed by one of `a' to ;; which the file is converted have no Big5 equivalent. Go ;; through and delete them. (goto-char pos) - (while (search-forward "$(0!{(B" nil t) + (while (search-forward "□" nil t) (delete-char -1)) ;; Uppercase keys in dictionary need to be downcased. Backslashes ;; at the beginning of keys need to be turned into double @@ -1083,31 +1083,31 @@ To input symbols and punctuation, type `/' followed by one of `a' to (defun ctlau-gb-converter (dicbuf) (ctlau-converter dicbuf -"$A::WVJdHk!KAuN}OiJ=TARt!K(B +"汉字输入∷刘锡祥式粤音∷ - $AAuN}OiJ=TASoW"Rt7=08(B + 刘锡祥式粤语注音方案 Sidney Lau's Cantonese transcription scheme as described in his book \"Elementary Cantonese\", The Government Printer, Hong Kong, 1972. - This file was prepared by Fung Fung Lee ($A@n7c7e(B). + This file was prepared by Fung Fung Lee (李枫峰). Originally converted from CTCPS3.tit Last modified: June 2, 1993. Some infrequent GB characters are accessed by typing \\, followed by - the Cantonese romanization of the respective radical ($A2?JW(B).")) + the Cantonese romanization of the respective radical (部首).")) (defun ctlau-b5-converter (dicbuf) (ctlau-converter dicbuf -"$(0KH)tTT&,!(N,Tg>A*#Gn5x!((B +"漢字輸入:劉錫祥式粵音: - $(0N,Tg>A*#GnM$0D5x'J7{(B + 劉錫祥式粵語注音方案 Sidney Lau's Cantonese transcription scheme as described in his book \"Elementary Cantonese\", The Government Printer, Hong Kong, 1972. - This file was prepared by Fung Fung Lee ($(0,XFS76(B). + This file was prepared by Fung Fung Lee (李楓峰). Originally converted from CTCPS3.tit Last modified: June 2, 1993. Some infrequent characters are accessed by typing \\, followed by - the Cantonese romanization of the respective radical ($(0?f5}(B).")) + the Cantonese romanization of the respective radical (部首).")) (declare-function dos-8+3-filename "dos-fns.el" (filename)) commit b0e96e554c0e78c17ee6e092e307112e814e5a65 Author: Stefan Monnier Date: Tue Jan 26 21:11:49 2021 -0500 Use lexical-binding in of all lisp/language * lisp/international/titdic-cnv.el (pinyin-convert): Enable lexical-binding in the generated file(s). * lisp/language/ethio-util.el: Use lexical-binding. (ethio-tex-to-fidel-buffer): Use `inhibit-read-only`. Remove unused vars `p` and `ch`. * lisp/language/hanja-util.el: Use lexical-binding. * lisp/language/ind-util.el: Use lexical-binding. (indian-translate-region): Actually use the `from` and `to` arguments. (): Use `dlet`. Remove unused var `current-repertory`. (indian-2-column-to-ucs-region): Remove unused var `pos`. * lisp/language/japan-util.el: Use lexical-binding. (japanese-katakana-region, japanese-hiragana-region) (japanese-zenkaku-region): Remove unused var `next`. * lisp/language/korea-util.el: Use lexical-binding. * lisp/language/lao-util.el: Use lexical-binding. (lao-composition-function): Remove unused var `glyph`. * lisp/language/thai-util.el: Use lexical-binding. (thai-composition-function): Remove unused var `glyph`. * lisp/language/thai-word.el: Use lexical-binding. (thai-forward-word): Remove unused var `tail`. * lisp/language/tibet-util.el: Use lexical-binding. (tibetan-add-components): Remove unused var `tmp`. (tibetan-compose-region): Remove unused vars `str`, `result`, `chars`. * lisp/language/viet-util.el: * lisp/language/tv-util.el: * lisp/language/cyril-util.el: * lisp/language/china-util.el: Use lexical-binding. diff --git a/lisp/international/titdic-cnv.el b/lisp/international/titdic-cnv.el index 58c81bfd1f..753139e5dd 100644 --- a/lisp/international/titdic-cnv.el +++ b/lisp/international/titdic-cnv.el @@ -1212,8 +1212,10 @@ The library is named pinyin.el, and contains the constant (dst-file (cadr command-line-args-left)) (coding-system-for-write 'utf-8-unix)) (with-temp-file dst-file - (insert ";; This file is automatically generated from pinyin.map,\ - by the\n;; function pinyin-convert.\n\n") + (insert ";;; " (file-name-nondirectory dst-file) + " -*- lexical-binding:t -*- +;; This file is automatically generated from pinyin.map, by the +;; function pinyin-convert.\n\n") (insert "(defconst pinyin-character-map\n'(") (let ((pos (point))) (insert-file-contents src-file) diff --git a/lisp/language/burmese.el b/lisp/language/burmese.el index d689e87d78..373f25ac5c 100644 --- a/lisp/language/burmese.el +++ b/lisp/language/burmese.el @@ -51,7 +51,7 @@ regexp t t)))) regexp)) -(let ((elt (list (vector burmese-composable-pattern 0 'font-shape-gstring) - (vector "." 0 'font-shape-gstring)))) +(let ((elt (list (vector burmese-composable-pattern 0 #'font-shape-gstring) + (vector "." 0 #'font-shape-gstring)))) (set-char-table-range composition-function-table '(#x1000 . #x107F) elt) (set-char-table-range composition-function-table '(#xAA60 . #xAA7B) elt)) diff --git a/lisp/language/cham.el b/lisp/language/cham.el index aa820dc649..3aac986b43 100644 --- a/lisp/language/cham.el +++ b/lisp/language/cham.el @@ -29,7 +29,7 @@ (set-char-table-range composition-function-table '(#xAA00 . #xAA5F) - (list (vector "[\xAA00-\xAA5F]+" 0 'font-shape-gstring))) + (list (vector "[\xAA00-\xAA5F]+" 0 #'font-shape-gstring))) (set-language-info-alist "Cham" '((charset unicode) diff --git a/lisp/language/china-util.el b/lisp/language/china-util.el index 4bc2eaa2cd..105e7a735f 100644 --- a/lisp/language/china-util.el +++ b/lisp/language/china-util.el @@ -1,4 +1,4 @@ -;;; china-util.el --- utilities for Chinese -*- coding: utf-8 -*- +;;; china-util.el --- utilities for Chinese -*- lexical-binding: t; -*- ;; Copyright (C) 1995, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, diff --git a/lisp/language/cyril-util.el b/lisp/language/cyril-util.el index 72ceffdf0d..04e681d743 100644 --- a/lisp/language/cyril-util.el +++ b/lisp/language/cyril-util.el @@ -1,4 +1,4 @@ -;;; cyril-util.el --- utilities for Cyrillic scripts +;;; cyril-util.el --- utilities for Cyrillic scripts -*- lexical-binding: t; -*- ;; Copyright (C) 1997-1998, 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/language/ethio-util.el b/lisp/language/ethio-util.el index 174b9ecfda..9b5fdf24d2 100644 --- a/lisp/language/ethio-util.el +++ b/lisp/language/ethio-util.el @@ -1,4 +1,4 @@ -;;; ethio-util.el --- utilities for Ethiopic -*- coding: utf-8-emacs; -*- +;;; ethio-util.el --- utilities for Ethiopic -*- coding: utf-8-emacs; lexical-binding: t; -*- ;; Copyright (C) 1997-1998, 2002-2021 Free Software Foundation, Inc. ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, @@ -832,11 +832,12 @@ The 2nd and 3rd arguments BEGIN and END specify the region." (set-buffer-modified-p nil))) ;;;###autoload -(defun ethio-tex-to-fidel-buffer nil +(defun ethio-tex-to-fidel-buffer () "Convert fidel-tex commands in the current buffer into fidel chars." (interactive) - (let ((buffer-read-only nil) - (p) (ch)) + (let ((inhibit-read-only t) + ;; (p) (ch) + ) ;; TeX macros to Ethiopic characters (robin-convert-region (point-min) (point-max) "ethiopic-tex") @@ -1018,7 +1019,7 @@ With ARG, insert that many delimiters." ;; ;;;###autoload -(defun ethio-composition-function (pos to font-object string _direction) +(defun ethio-composition-function (pos _to _font-object string _direction) (setq pos (1- pos)) (let ((pattern "\\ce\\(፟\\|\\)")) (if string diff --git a/lisp/language/ethiopic.el b/lisp/language/ethiopic.el index 8573f6177d..209dcd51c9 100644 --- a/lisp/language/ethiopic.el +++ b/lisp/language/ethiopic.el @@ -79,8 +79,8 @@ ))) ;; For automatic composition -(aset composition-function-table ? 'ethio-composition-function) -(aset composition-function-table ?፟ 'ethio-composition-function) +(aset composition-function-table ? #'ethio-composition-function) +(aset composition-function-table ?፟ #'ethio-composition-function) (provide 'ethiopic) diff --git a/lisp/language/hanja-util.el b/lisp/language/hanja-util.el index 313fc63beb..9e9213536c 100644 --- a/lisp/language/hanja-util.el +++ b/lisp/language/hanja-util.el @@ -1,4 +1,4 @@ -;;; hanja-util.el --- Korean Hanja util module -*- coding: utf-8 -*- +;;; hanja-util.el --- Korean Hanja util module -*- lexical-binding: t; -*- ;; Copyright (C) 2008-2021 Free Software Foundation, Inc. diff --git a/lisp/language/hebrew.el b/lisp/language/hebrew.el index 389565669a..c55d23f72d 100644 --- a/lisp/language/hebrew.el +++ b/lisp/language/hebrew.el @@ -245,9 +245,9 @@ Bidirectional editing is supported."))) (pattern2 (concat base "\u200D" combining))) (set-char-table-range composition-function-table '(#x591 . #x5C7) - (list (vector pattern2 3 'hebrew-shape-gstring) - (vector pattern2 2 'hebrew-shape-gstring) - (vector pattern1 1 'hebrew-shape-gstring) + (list (vector pattern2 3 #'hebrew-shape-gstring) + (vector pattern2 2 #'hebrew-shape-gstring) + (vector pattern1 1 #'hebrew-shape-gstring) [nil 0 hebrew-shape-gstring])) ;; Exclude non-combining characters. (set-char-table-range diff --git a/lisp/language/ind-util.el b/lisp/language/ind-util.el index 4bd1cd76a6..8d4b2a826e 100644 --- a/lisp/language/ind-util.el +++ b/lisp/language/ind-util.el @@ -1,4 +1,4 @@ -;;; ind-util.el --- Transliteration and Misc. Tools for Indian Languages -*- coding: utf-8-emacs; -*- +;;; ind-util.el --- Transliteration and Misc. Tools for Indian Languages -*- coding: utf-8-emacs; lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. @@ -40,7 +40,7 @@ (defun indian-regexp-of-hashtbl-keys (hashtbl) "Return the regular expression of hash table keys." (let (keys) - (maphash (lambda (key val) (push key keys)) hashtbl) + (maphash (lambda (key _val) (push key keys)) hashtbl) (regexp-opt keys))) (defvar indian-dev-base-table @@ -565,7 +565,7 @@ (let ((regexp ,(indian-regexp-of-hashtbl-keys (if encode-p (car (eval hashtable)) (cdr (eval hashtable)))))) - (narrow-to-region from to) + (narrow-to-region ,from ,to) (goto-char (point-min)) (while (re-search-forward regexp nil t) (let ((matchstr (gethash (match-string 0) @@ -613,7 +613,7 @@ ;; The followings provide conversion between IS 13194 (ISCII) and UCS. -(let +(dlet ;;Unicode vs IS13194 ;; only Devanagari is supported now. ((ucs-devanagari-to-is13194-alist '((?\x0900 . "[U+0900]") @@ -820,11 +820,11 @@ Returns new end position." (save-restriction (narrow-to-region from to) (goto-char (point-min)) - (let* ((current-repertory is13194-default-repertory)) + ;; (let* ((current-repertory is13194-default-repertory)) (while (re-search-forward indian-ucs-to-is13194-regexp nil t) (replace-match (get-char-code-property (string-to-char (match-string 0)) - 'iscii)))) + 'iscii)));; ) (point-max)))) (defun indian-iscii-to-ucs-region (from to) @@ -1246,7 +1246,7 @@ Returns new end position." (interactive "r") (save-excursion (save-restriction - (let ((pos from) + (let (;; (pos from) (alist (char-table-extra-slot indian-2-column-to-ucs-chartable 0))) (narrow-to-region from to) (decompose-region from to) diff --git a/lisp/language/indian.el b/lisp/language/indian.el index 5ff57966c1..6f9d270384 100644 --- a/lisp/language/indian.el +++ b/lisp/language/indian.el @@ -381,7 +381,7 @@ South Indian language Malayalam is supported in this language environment.")) (if slot (set-char-table-range composition-function-table key - (list (vector (cdr slot) 0 'font-shape-gstring)))))) + (list (vector (cdr slot) 0 #'font-shape-gstring)))))) char-script-table)) (provide 'indian) diff --git a/lisp/language/japan-util.el b/lisp/language/japan-util.el index 9dce17c496..948bfef9f2 100644 --- a/lisp/language/japan-util.el +++ b/lisp/language/japan-util.el @@ -1,4 +1,4 @@ -;;; japan-util.el --- utilities for Japanese +;;; japan-util.el --- utilities for Japanese -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, @@ -236,7 +236,7 @@ of which charset is `japanese-jisx0201-kana'." (composition (and (not hankaku) (get-char-code-property kana 'kana-composition))) - next slot) + slot) ;; next (if (and composition (setq slot (assq (following-char) composition))) (japanese-replace-region (match-beginning 0) (1+ (point)) (cdr slot)) @@ -258,7 +258,7 @@ of which charset is `japanese-jisx0201-kana'." (while (re-search-forward "\\cK\\|\\ck" nil t) (let* ((kata (preceding-char)) (composition (get-char-code-property kata 'kana-composition)) - next slot) + slot) ;; next (if (and composition (setq slot (assq (following-char) composition))) (japanese-replace-region (match-beginning 0) (1+ (point)) (get-char-code-property @@ -305,7 +305,7 @@ Optional argument KATAKANA-ONLY non-nil means to convert only KATAKANA char." (re-search-forward "\\ca\\|\\ck" nil t))) (let* ((hankaku (preceding-char)) (composition (get-char-code-property hankaku 'kana-composition)) - next slot) + slot) ;; next (if (and composition (setq slot (assq (following-char) composition))) (japanese-replace-region (match-beginning 0) (1+ (point)) (cdr slot)) diff --git a/lisp/language/khmer.el b/lisp/language/khmer.el index 37173c9fb9..6f08e60d60 100644 --- a/lisp/language/khmer.el +++ b/lisp/language/khmer.el @@ -31,7 +31,7 @@ (documentation . t))) (let ((val (list (vector "[\x1780-\x17FF\x19E0-\x19FF\x200C\x200D]+" - 0 'font-shape-gstring)))) + 0 #'font-shape-gstring)))) (set-char-table-range composition-function-table '(#x1780 . #x17FF) val) (set-char-table-range composition-function-table '(#x19E0 . #x19FF) val)) diff --git a/lisp/language/korea-util.el b/lisp/language/korea-util.el index eb7b85bce8..c99ff3c3f2 100644 --- a/lisp/language/korea-util.el +++ b/lisp/language/korea-util.el @@ -1,4 +1,4 @@ -;;; korea-util.el --- utilities for Korean +;;; korea-util.el --- utilities for Korean -*- lexical-binding: t; -*- ;; Copyright (C) 1997, 1999, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, @@ -45,7 +45,7 @@ (activate-input-method (concat "korean-hangul" default-korean-keyboard)))) -(defun quail-hangul-switch-symbol-ksc (&rest ignore) +(defun quail-hangul-switch-symbol-ksc (&rest _ignore) "Switch to/from Korean symbol package." (interactive "i") (and current-input-method @@ -54,7 +54,7 @@ default-korean-keyboard)) (activate-input-method "korean-symbol")))) -(defun quail-hangul-switch-hanja (&rest ignore) +(defun quail-hangul-switch-hanja (&rest _ignore) "Switch to/from Korean hanja package." (interactive "i") (and current-input-method diff --git a/lisp/language/korean.el b/lisp/language/korean.el index 22b33a440e..bdf8240de9 100644 --- a/lisp/language/korean.el +++ b/lisp/language/korean.el @@ -92,10 +92,10 @@ and the following key bindings are available within Korean input methods: (pattern (concat choseong jungseong jongseong))) (set-char-table-range composition-function-table '(#x1100 . #x115F) - (list (vector pattern 0 'font-shape-gstring))) + (list (vector pattern 0 #'font-shape-gstring))) (set-char-table-range composition-function-table '(#xA960 . #xA97C) - (list (vector pattern 0 'font-shape-gstring)))) + (list (vector pattern 0 #'font-shape-gstring)))) (provide 'korean) diff --git a/lisp/language/lao-util.el b/lisp/language/lao-util.el index 59c9850b1a..c8c3fe4f7e 100644 --- a/lisp/language/lao-util.el +++ b/lisp/language/lao-util.el @@ -1,4 +1,4 @@ -;;; lao-util.el --- utilities for Lao -*- coding: utf-8; -*- +;;; lao-util.el --- utilities for Lao -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, @@ -498,10 +498,10 @@ syllable. In that case, FROM and TO are indexes to STR." (compose-gstring-for-graphic gstring direction) (or (font-shape-gstring gstring direction) (let ((glyph-len (lgstring-glyph-len gstring)) - (i 0) - glyph) + (i 0)) ;; glyph (while (and (< i glyph-len) - (setq glyph (lgstring-glyph gstring i))) + ;; (setq glyph + (lgstring-glyph gstring i)) ;;) (setq i (1+ i))) (compose-glyph-string-relative gstring 0 i 0.1))))) diff --git a/lisp/language/lao.el b/lisp/language/lao.el index 5252f1e60e..c699d57c15 100644 --- a/lisp/language/lao.el +++ b/lisp/language/lao.el @@ -66,7 +66,7 @@ (t (string c)))) (cdr l) "")) ;; Element of composition-function-table. - (elt (list (vector regexp 1 'lao-composition-function) + (elt (list (vector regexp 1 #'lao-composition-function) fallback-rule)) ch) (dotimes (i len) diff --git a/lisp/language/misc-lang.el b/lisp/language/misc-lang.el index 0a274f144c..a2ca678b2b 100644 --- a/lisp/language/misc-lang.el +++ b/lisp/language/misc-lang.el @@ -137,9 +137,9 @@ thin (i.e. 1-dot width) space." composition-function-table '(#x600 . #x74F) (list (vector "[\u200C\u200D][\u0600-\u074F\u200C\u200D]+" - 1 'arabic-shape-gstring) + 1 #'arabic-shape-gstring) (vector "[\u0600-\u074F\u200C\u200D]+" - 0 'arabic-shape-gstring))) + 0 #'arabic-shape-gstring))) ;; The Egyptian Hieroglyph Format Controls were introduced in Unicode ;; Standard v12.0. Apparently, they are not yet well supported in @@ -186,13 +186,13 @@ thin (i.e. 1-dot width) space." ;; doesn't support these controls, the glyphs are ;; displayed individually, and not as a single ;; grapheme cluster. - 1 'font-shape-gstring))) + 1 #'font-shape-gstring))) ;; Grouping controls (set-char-table-range composition-function-table #x13437 (list (vector "\U00013437[\U00013000-\U0001343F]+" - 0 'egyptian-shape-grouping)))) + 0 #'egyptian-shape-grouping)))) (provide 'misc-lang) diff --git a/lisp/language/sinhala.el b/lisp/language/sinhala.el index 90fc41c1c4..99a104ec33 100644 --- a/lisp/language/sinhala.el +++ b/lisp/language/sinhala.el @@ -43,6 +43,6 @@ "[\u0D85-\u0D96][\u0D82-\u0D83]?\\|" ;; any other singleton characters "[\u0D80-\u0DFF]") - 0 'font-shape-gstring))) + 0 #'font-shape-gstring))) ;; sinhala.el ends here diff --git a/lisp/language/tai-viet.el b/lisp/language/tai-viet.el index 17abf136f7..4549b111a3 100644 --- a/lisp/language/tai-viet.el +++ b/lisp/language/tai-viet.el @@ -30,7 +30,7 @@ (set-char-table-range composition-function-table '(#xAA80 . #xAADF) - 'tai-viet-composition-function) + #'tai-viet-composition-function) (set-language-info-alist "TaiViet" '((charset unicode) diff --git a/lisp/language/thai-util.el b/lisp/language/thai-util.el index f9c57e8ca8..e11a05445c 100644 --- a/lisp/language/thai-util.el +++ b/lisp/language/thai-util.el @@ -1,4 +1,4 @@ -;;; thai-util.el --- utilities for Thai -*- coding: utf-8; -*- +;;; thai-util.el --- utilities for Thai -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, @@ -232,10 +232,10 @@ positions (integers or markers) specifying the region." (let ((glyph-len (lgstring-glyph-len gstring)) (last-char (lgstring-char gstring (1- (lgstring-char-len gstring)))) - (i 0) - glyph) + (i 0)) ;; glyph (while (and (< i glyph-len) - (setq glyph (lgstring-glyph gstring i))) + ;; (setq glyph + (lgstring-glyph gstring i)) ;; ) (setq i (1+ i))) (if (= last-char ?ำ) (setq i (1- i))) diff --git a/lisp/language/thai-word.el b/lisp/language/thai-word.el index 94c6ab9897..ff1e80298b 100644 --- a/lisp/language/thai-word.el +++ b/lisp/language/thai-word.el @@ -1,4 +1,4 @@ -;;; thai-word.el -- find Thai word boundaries +;;; thai-word.el -- find Thai word boundaries -*- lexical-binding: t; -*- ;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 ;; National Institute of Advanced Industrial Science and Technology (AIST) @@ -10973,8 +10973,7 @@ If COUNT is negative, move point backward (- COUNT) words." ;; special instead of using forward-word. (let ((start (point)) (limit (match-end 0)) - boundaries - tail) + boundaries) ;; tail ;; If thai-forward-word has been called within a Thai ;; region, we must go back until the Thai region starts ;; to do the contextual analysis for finding word diff --git a/lisp/language/tibet-util.el b/lisp/language/tibet-util.el index e741af1874..ddf4a0c0fb 100644 --- a/lisp/language/tibet-util.el +++ b/lisp/language/tibet-util.el @@ -1,4 +1,4 @@ -;;; tibet-util.el --- utilities for Tibetan -*- coding: utf-8-emacs; -*- +;;; tibet-util.el --- utilities for Tibetan -*- coding: utf-8-emacs; lexical-binding: t; -*- ;; Copyright (C) 1997, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, @@ -126,42 +126,42 @@ The returned string has no composition information." (setq t-str-list (cons (substring str idx) t-str-list))) (apply 'concat (nreverse t-str-list)))) -;;; +;; ;;; Functions for composing/decomposing Tibetan sequence. -;;; -;;; A Tibetan syllable is typically structured as follows: -;;; -;;; [Prefix] C [C+] V [M] [Suffix [Post suffix]] -;;; -;;; where C's are all vertically stacked, V appears below or above -;;; consonant cluster and M is always put above the C[C+]V combination. -;;; (Sanskrit visarga, though it is a vowel modifier, is considered -;;; to be a punctuation.) -;;; -;;; Here are examples of the words "bsgrubs" and "hfauM" -;;; -;;; བསྒྲུབས ཧཱུཾ -;;; -;;; M -;;; b s b s h -;;; g fa -;;; r u -;;; u -;;; -;;; Consonants `'' (འ), `w' (ཝ), `y' (ཡ), `r' (ར) take special -;;; forms when they are used as subjoined consonant. Consonant `r' -;;; takes another special form when used as superjoined in such a case -;;; as "rka", while it does not change its form when conjoined with -;;; subjoined `'', `w' or `y' as in "rwa", "rya". - -;; Append a proper composition rule and glyph to COMPONENTS to compose -;; CHAR with a composition that has COMPONENTS. +;; +;; A Tibetan syllable is typically structured as follows: +;; +;; [Prefix] C [C+] V [M] [Suffix [Post suffix]] +;; +;; where C's are all vertically stacked, V appears below or above +;; consonant cluster and M is always put above the C[C+]V combination. +;; (Sanskrit visarga, though it is a vowel modifier, is considered +;; to be a punctuation.) +;; +;; Here are examples of the words "bsgrubs" and "hfauM" +;; +;; བསྒྲུབས ཧཱུཾ +;; +;; M +;; b s b s h +;; g fa +;; r u +;; u +;; +;; Consonants `'' (འ), `w' (ཝ), `y' (ཡ), `r' (ར) take special +;; forms when they are used as subjoined consonant. Consonant `r' +;; takes another special form when used as superjoined in such a case +;; as "rka", while it does not change its form when conjoined with +;; subjoined `'', `w' or `y' as in "rwa", "rya". + +; Append a proper composition rule and glyph to COMPONENTS to compose +; CHAR with a composition that has COMPONENTS. (defun tibetan-add-components (components char) (let ((last (last components)) (stack-upper '(tc . bc)) (stack-under '(bc . tc)) - rule comp-vowel tmp) + rule comp-vowel) ;; Special treatment for 'a chung. ;; If 'a follows a consonant, turn it into the subjoined form. ;; * Disabled by Tomabechi 2000/06/09 * @@ -246,7 +246,7 @@ The returned string has no composition information." (defun tibetan-compose-region (beg end) "Compose Tibetan text the region BEG and END." (interactive "r") - (let (str result chars) + ;; (let (str result chars) (save-excursion (save-restriction (narrow-to-region beg end) @@ -272,7 +272,7 @@ The returned string has no composition information." (while (< (point) to) (tibetan-add-components components (following-char)) (forward-char 1)) - (compose-region from to components))))))) + (compose-region from to components)))))) ;; ) (defvar tibetan-decompose-precomposition-alist (mapcar (lambda (x) (cons (string-to-char (cdr x)) (car x))) diff --git a/lisp/language/tibetan.el b/lisp/language/tibetan.el index edd9d765b1..48c7638948 100644 --- a/lisp/language/tibetan.el +++ b/lisp/language/tibetan.el @@ -605,7 +605,7 @@ This also matches some punctuation characters which need conversion.") ;; For automatic composition. (set-char-table-range composition-function-table '(#xF00 . #xFD1) - (list (vector tibetan-composable-pattern 0 'font-shape-gstring))) + (list (vector tibetan-composable-pattern 0 #'font-shape-gstring))) (provide 'tibetan) diff --git a/lisp/language/tv-util.el b/lisp/language/tv-util.el index 7ce8ee1e50..1a530d350f 100644 --- a/lisp/language/tv-util.el +++ b/lisp/language/tv-util.el @@ -1,4 +1,4 @@ -;;; tv-util.el --- support for Tai Viet -*- coding: utf-8 -*- +;;; tv-util.el --- support for Tai Viet -*- lexical-binding: t; -*- ;; Copyright (C) 2007, 2008, 2009, 2010, 2011 ;; National Institute of Advanced Industrial Science and Technology (AIST) @@ -128,7 +128,7 @@ ;;;###autoload -(defun tai-viet-composition-function (from to font-object string _direction) +(defun tai-viet-composition-function (from _to _font-object string _direction) (if string (if (string-match tai-viet-re string from) (tai-viet-compose-string from (match-end 0) string)) diff --git a/lisp/language/viet-util.el b/lisp/language/viet-util.el index 177b04bc47..bfaf0f3b94 100644 --- a/lisp/language/viet-util.el +++ b/lisp/language/viet-util.el @@ -1,4 +1,4 @@ -;;; viet-util.el --- utilities for Vietnamese -*- coding: utf-8; -*- +;;; viet-util.el --- utilities for Vietnamese -*- lexical-binding: t; -*- ;; Copyright (C) 1998, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, commit 7c257e228676542fd20bac1eeb8be43825db5de4 Merge: 4be6c9215b e79e377a4e Author: Glenn Morris Date: Wed Jan 27 07:55:11 2021 -0800 ; Merge from origin/emacs-27 The following commits were skipped: e79e377a4e (origin/emacs-27) Improve documentation of 'read-regexp' a... 0340e9eccb read-regexp-suggestions doc string improvement 932aba674c Try to improve the read-regexp doc string 809503431d ; xref-revert-buffer: Drop the (goto-char) at the end 0399cc2ab5 Erase the buffer only after fetching the new contents commit 4be6c9215bdc5c6856e6d1b2c445f4a268a6f2be Merge: 27889f029a 3443a1c698 Author: Glenn Morris Date: Wed Jan 27 07:55:11 2021 -0800 Merge from origin/emacs-27 3443a1c698 Fix last change commit 27889f029ac3728edaf9a6b1c9c0c511cb22c6fc Merge: 0ca75f1956 c8fa056a50 Author: Glenn Morris Date: Wed Jan 27 07:55:11 2021 -0800 ; Merge from origin/emacs-27 The following commit was skipped: c8fa056a50 Mention undo-amalgamate-change-group in the lispref manual commit 0ca75f19561f7c1100ec97e5af019977443a575b Merge: 5597398462 3f610177ad Author: Glenn Morris Date: Wed Jan 27 07:55:11 2021 -0800 Merge from origin/emacs-27 3f610177ad Avoid sending systemd shutdown notifications if non-daemon 009df5cb3c * src/cmds.c (Fforward_line): Doc fix. (Bug#46027) ee1c54ebc0 Improve documentation of sendmail.el defcustom's commit 55973984629cc08a3dbf9c7c4367851b712be21b Merge: 588d2306ac 82c228a017 Author: Glenn Morris Date: Wed Jan 27 07:55:11 2021 -0800 ; Merge from origin/emacs-27 The following commit was skipped: 82c228a017 Don't let `maybe_quit` prevent resetting `consing_until_gc... commit 588d2306ac914fef2bd04699084978add6d2d109 Merge: ff03411269 b58fd1eab9 Author: Glenn Morris Date: Wed Jan 27 07:55:11 2021 -0800 Merge from origin/emacs-27 b58fd1eab9 ; * lisp/language/cham.el: Fix copy-paste mistake in comment. commit ff0341126918e36777d1b85a3661577442b574cb Author: Eli Zaretskii Date: Wed Jan 27 17:52:51 2021 +0200 Fix display of stretches of whitespace in the display margins * src/xdisp.c (produce_stretch_glyph): Truncate the stretch glyph due to line wrap only when drawing in the text area. * src/xterm.c (x_draw_stretch_glyph_string): * src/w32term.c (w32_draw_stretch_glyph_string): Fix the adjustment of the stretch X and width so that stretch glyphs could be drawn in the left margin. Reported by Paul W. Rankin . diff --git a/src/w32term.c b/src/w32term.c index 109aa58d73..0ee805a852 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -2404,14 +2404,29 @@ w32_draw_stretch_glyph_string (struct glyph_string *s) else if (!s->background_filled_p) { int background_width = s->background_width; - int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA); + int x = s->x, text_left_x = window_box_left_offset (s->w, TEXT_AREA); - /* Don't draw into left margin, fringe or scrollbar area - except for header line and mode line. */ - if (x < left_x && !s->row->mode_line_p) + /* Don't draw into left fringe or scrollbar area except for + header line and mode line. */ + if (x < text_left_x && !s->row->mode_line_p) { - background_width -= left_x - x; - x = left_x; + int left_x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (s->w); + int right_x = text_left_x; + + if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s->w)) + left_x += WINDOW_LEFT_FRINGE_WIDTH (s->w); + else + right_x -= WINDOW_LEFT_FRINGE_WIDTH (s->w); + + /* Adjust X and BACKGROUND_WIDTH to fit inside the space + between LEFT_X and RIGHT_X. */ + if (x < left_x) + { + background_width -= left_x - x; + x = left_x; + } + if (x + background_width > right_x) + background_width = right_x - x; } if (background_width > 0) w32_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height); diff --git a/src/xdisp.c b/src/xdisp.c index e1e4ff4136..11b9e1becf 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -29813,7 +29813,8 @@ produce_stretch_glyph (struct it *it) #endif /* HAVE_WINDOW_SYSTEM */ height = 1; - if (width > 0 && it->line_wrap != TRUNCATE + if (width > 0 + && it->area == TEXT_AREA && it->line_wrap != TRUNCATE && it->current_x + width > it->last_visible_x) { width = it->last_visible_x - it->current_x; diff --git a/src/xterm.c b/src/xterm.c index a855d2d67a..744b80c68a 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -3585,14 +3585,29 @@ x_draw_stretch_glyph_string (struct glyph_string *s) else if (!s->background_filled_p) { int background_width = s->background_width; - int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA); + int x = s->x, text_left_x = window_box_left_offset (s->w, TEXT_AREA); - /* Don't draw into left margin, fringe or scrollbar area - except for header line and mode line. */ - if (x < left_x && !s->row->mode_line_p) + /* Don't draw into left fringe or scrollbar area except for + header line and mode line. */ + if (x < text_left_x && !s->row->mode_line_p) { - background_width -= left_x - x; - x = left_x; + int left_x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (s->w); + int right_x = text_left_x; + + if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s->w)) + left_x += WINDOW_LEFT_FRINGE_WIDTH (s->w); + else + right_x -= WINDOW_LEFT_FRINGE_WIDTH (s->w); + + /* Adjust X and BACKGROUND_WIDTH to fit inside the space + between LEFT_X and RIGHT_X. */ + if (x < left_x) + { + background_width -= left_x - x; + x = left_x; + } + if (x + background_width > right_x) + background_width = right_x - x; } if (background_width > 0) x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height); commit 12095de8b918b3c44c603bf88bc98f1842910f86 Author: Michael Albinus Date: Wed Jan 27 16:30:49 2021 +0100 Some Tramp fixes * doc/misc/tramp.texi (GVFS-based methods): Ban sftp RemoteCommand option. * lisp/net/tramp-adb.el (tramp-adb-handle-copy-file) (tramp-adb-handle-rename-file): Avoid calling jka-compr when writing the target file. * lisp/net/tramp-sh.el (tramp-sh-handle-file-ownership-preserved-p): Skip GROUP test on *BSD machines. * test/lisp/net/tramp-tests.el (tramp-test17-insert-directory-one-file): Skip for tamp-crypt.el. (tramp--test-sh-no-ls--dired-p): Ignore errors. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 5d89b06588..efe839574d 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -1286,6 +1286,9 @@ This method uses @command{sftp} in order to securely access remote hosts. @command{sftp} is a more secure option for connecting to hosts that for security reasons refuse @command{ssh} connections. +When there is a respective entry in your @command{ssh} configuration, +do @emph{not} set the @option{RemoteCommand} option. + @end table @defopt tramp-gvfs-methods diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index 2c4ef2acae..73dffe1d64 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -636,7 +636,10 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (copy-directory filename newname keep-date t) (let ((t1 (tramp-tramp-file-p filename)) - (t2 (tramp-tramp-file-p newname))) + (t2 (tramp-tramp-file-p newname)) + ;; We don't want the target file to be compressed, so we + ;; let-bind `jka-compr-inhibit' to t. + (jka-compr-inhibit t)) (with-parsed-tramp-file-name (if t1 filename newname) nil (unless (file-exists-p filename) (tramp-error @@ -717,7 +720,10 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (delete-directory filename 'recursive)) (let ((t1 (tramp-tramp-file-p filename)) - (t2 (tramp-tramp-file-p newname))) + (t2 (tramp-tramp-file-p newname)) + ;; We don't want the target file to be compressed, so we + ;; let-bind `jka-compr-inhibit' to t. + (jka-compr-inhibit t)) (with-parsed-tramp-file-name (if t1 filename newname) nil (unless (file-exists-p filename) (tramp-error diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index ed3d15377c..2274efdf8b 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -1708,6 +1708,12 @@ ID-FORMAT valid values are `string' and `integer'." (= (tramp-compat-file-attribute-user-id attributes) (tramp-get-remote-uid v 'integer)) (or (not group) + ;; On BSD-derived systems files always inherit the + ;; parent directory's group, so skip the group-gid + ;; test. + (string-match-p + "BSD\\|DragonFly\\|Darwin" + (tramp-get-connection-property v "uname" "")) (= (tramp-compat-file-attribute-group-id attributes) (tramp-get-remote-gid v 'integer))))))))) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 7757c55c16..6467c7ee21 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -3192,6 +3192,8 @@ This tests also `file-directory-p' and `file-accessible-directory-p'." (ert-deftest tramp-test17-insert-directory-one-file () "Check `insert-directory' inside directory listing." (skip-unless (tramp--test-enabled)) + ;; Relative file names in dired are not supported in tramp-crypt.el. + (skip-unless (not (tramp--test-crypt-p))) (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil))) (let* ((tmp-name1 @@ -5793,7 +5795,9 @@ Additionally, ls does not support \"--dired\"." (and (tramp--test-sh-p) (with-temp-buffer ;; We must refill the cache. `insert-directory' does it. - (insert-directory tramp-test-temporary-file-directory "-al") + ;; This fails for tramp-crypt.el, so we ignore that. + (ignore-errors + (insert-directory tramp-test-temporary-file-directory "-al")) (not (tramp-get-connection-property tramp-test-vec "ls--dired" nil))))) (defun tramp--test-share-p () commit 45112398cdcfa1e32986ef630dc235ce38d10774 Author: Michael Albinus Date: Wed Jan 27 16:30:08 2021 +0100 * lisp/net/dbus.el (dbus-monitor-handler): Disable buffer undo. diff --git a/lisp/net/dbus.el b/lisp/net/dbus.el index 7a7bbef536..195ddc6bba 100644 --- a/lisp/net/dbus.el +++ b/lisp/net/dbus.el @@ -2079,6 +2079,7 @@ daemon, it is rather the timestamp the corresponding D-Bus event has been handled by this function." (with-current-buffer (get-buffer-create "*D-Bus Monitor*") (special-mode) + (buffer-disable-undo) ;; Move forward and backward between messages. (local-set-key [?n] #'forward-paragraph) (local-set-key [?p] #'backward-paragraph) commit e79e377a4e06d187e56dcad826fb761659abe3f3 Author: Eli Zaretskii Date: Wed Jan 27 17:15:46 2021 +0200 Improve documentation of 'read-regexp' and friends * doc/emacs/glossary.texi (Glossary): Add "Tag" to the Glossary. * doc/emacs/maintaining.texi (Xref): Mention that identifiers are also known as "tags". * lisp/replace.el (read-regexp, read-regexp-suggestions): Improve wording of doc strings. (Bug#46088) (Bug#46089) (cherry picked from commit 49eb03d6c8a181fd46adbbcf1f0a976d0a9efa87) diff --git a/doc/emacs/glossary.texi b/doc/emacs/glossary.texi index 35df06591e..4f971eb1e0 100644 --- a/doc/emacs/glossary.texi +++ b/doc/emacs/glossary.texi @@ -1369,10 +1369,14 @@ configurations. @xref{Tab Bars}. The tab line is a line of tabs at the top of an Emacs window. Clicking on one of these tabs switches window buffers. @xref{Tab Line}. +@item Tag +A tag is an identifier in a program source. @xref{Xref}. + @anchor{Glossary---Tags Table} @item Tags Table -A tags table is a file that serves as an index to the function -definitions in one or more other files. @xref{Tags Tables}. +A tags table is a file that serves as an index to identifiers: definitions +of functions, macros, data structures, etc., in one or more other files. +@xref{Tags Tables}. @item Termscript File A termscript file contains a record of all characters sent by Emacs to diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index 14911d30e9..9bb3378c3f 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -1860,19 +1860,21 @@ Of course, you should substitute the proper years and copyright holder. @section Find Identifier References @cindex xref +@cindex tag An @dfn{identifier} is a name of a syntactical subunit of the program: a function, a subroutine, a method, a class, a data type, a macro, etc. In a programming language, each identifier is a symbol in -the language's syntax. Program development and maintenance requires -capabilities to quickly find where each identifier was defined and -referenced, to rename identifiers across the entire project, etc. - -These capabilities are also useful for finding references in major -modes other than those defined to support programming languages. For -example, chapters, sections, appendices, etc.@: of a text or a @TeX{} -document can be treated as subunits as well, and their names can be -used as identifiers. In this chapter, we use the term ``identifiers'' -to collectively refer to the names of any kind of subunits, in program +the language's syntax. Identifiers are also known as @dfn{tags}. + +Program development and maintenance requires capabilities to quickly +find where each identifier was defined and referenced, to rename +identifiers across the entire project, etc. These capabilities are +also useful for finding references in major modes other than those +defined to support programming languages. For example, chapters, +sections, appendices, etc.@: of a text or a @TeX{} document can be +treated as subunits as well, and their names can be used as +identifiers. In this chapter, we use the term ``identifiers'' to +collectively refer to the names of any kind of subunits, in program source and in other kinds of text alike. Emacs provides a unified interface to these capabilities, called diff --git a/lisp/replace.el b/lisp/replace.el index d1618a485e..416d9f1d1e 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -786,11 +786,11 @@ the function that you set this to can check `this-command'." (defun read-regexp-suggestions () "Return a list of standard suggestions for `read-regexp'. -By default, the list includes the \"tag\" at point (see Info -node `(emacs) Identifier Search'), the last isearch regexp, the -last isearch string, and the last replacement regexp. -`read-regexp' appends the list returned by this function to the -end of values available via +By default, the list includes the identifier (a.k.a. \"tag\") +at point (see Info node `(emacs) Identifier Search'), the last +isearch regexp, the last isearch string, and the last +replacement regexp. `read-regexp' appends the list returned +by this function to the end of values available via \\\\[next-history-element]." (list (find-tag-default-as-regexp) @@ -805,33 +805,35 @@ Prompt with the string PROMPT. If PROMPT ends in \":\" (followed by optional whitespace), use it as-is. Otherwise, add \": \" to the end, possibly preceded by the default result (see below). -The optional argument DEFAULTS can be either: nil, a string, a list -of strings, or a symbol. We use DEFAULTS to construct the default -return value in case of empty input. +The optional argument DEFAULTS is used to construct the default +return value in case of empty input. DEFAULTS can be nil, a string, +a list of strings, or a symbol. -If DEFAULTS is a string, we use it as-is. +If DEFAULTS is a string, the function uses it as-is. If DEFAULTS is a list of strings, the first element is the default return value, but all the elements are accessible using the history command \\\\[next-history-element]. -DEFAULTS can be a symbol. If DEFAULTS is the symbol -`regexp-history-last', we use the first element of HISTORY (if -specified) or `regexp-history'. If DEFAULTS is a symbol with a -function definition, we call it with no arguments and use what it -returns, which should be either nil, a string, or a list of -strings. Other symbol values for DEFAULTS are ignored. If -`read-regexp-defaults-function' is non-nil, its value is used -instead of DEFAULTS in the two cases described in this paragraph. +If DEFAULTS is the symbol `regexp-history-last', the default return +value will be the first element of HISTORY. If HISTORY is omitted or +nil, `regexp-history' is used instead. +If DEFAULTS is a symbol with a function definition, it is called with +no arguments and should return either nil, a string, or a list of +strings, which will be used as above. +Other symbol values for DEFAULTS are ignored. -We append the standard values from `read-regexp-suggestions' to DEFAULTS -before using it. +If `read-regexp-defaults-function' is non-nil, its value is used +instead of DEFAULTS in the two cases described in the last paragraph. + +Before using whatever value DEFAULTS yields, the function appends the +standard values from `read-regexp-suggestions' to that value. If the first element of DEFAULTS is non-nil (and if PROMPT does not end -in \":\", followed by optional whitespace), we add it to the prompt. +in \":\", followed by optional whitespace), DEFAULT is added to the prompt. The optional argument HISTORY is a symbol to use for the history list. -If nil, uses `regexp-history'." +If nil, use `regexp-history'." (let* ((defaults (if (and defaults (symbolp defaults)) (cond commit 0340e9eccbb15492064b8dfda9313793b49de752 Author: Lars Ingebrigtsen Date: Wed Jan 27 03:47:02 2021 +0100 read-regexp-suggestions doc string improvement * lisp/replace.el (read-regexp-suggestions): Add a link to the manual to explain what a tag is (bug#46089). (cherry picked from commit f9cc2d48246fe8370e9286866e6115ba8e2acf44) diff --git a/lisp/replace.el b/lisp/replace.el index a769595125..d1618a485e 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -786,10 +786,12 @@ the function that you set this to can check `this-command'." (defun read-regexp-suggestions () "Return a list of standard suggestions for `read-regexp'. -By default, the list includes the tag at point, the last isearch regexp, -the last isearch string, and the last replacement regexp. `read-regexp' -appends the list returned by this function to the end of values available -via \\\\[next-history-element]." +By default, the list includes the \"tag\" at point (see Info +node `(emacs) Identifier Search'), the last isearch regexp, the +last isearch string, and the last replacement regexp. +`read-regexp' appends the list returned by this function to the +end of values available via +\\\\[next-history-element]." (list (find-tag-default-as-regexp) (find-tag-default-as-symbol-regexp) commit 932aba674c9a64dfd970d7c2343517c7f4c7a409 Author: Lars Ingebrigtsen Date: Wed Jan 27 03:38:49 2021 +0100 Try to improve the read-regexp doc string * lisp/replace.el (read-regexp): Attempt to clarify the semantics (bug#46088). (cherry picked from commit eded2a7ad7d456a417354a2797c18e9a578414d7) diff --git a/lisp/replace.el b/lisp/replace.el index 0288be82d2..a769595125 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -813,12 +813,14 @@ If DEFAULTS is a list of strings, the first element is the default return value, but all the elements are accessible using the history command \\\\[next-history-element]. -If DEFAULTS is a non-nil symbol, then if `read-regexp-defaults-function' -is non-nil, we use that in place of DEFAULTS in the following: - If DEFAULTS is the symbol `regexp-history-last', we use the first - element of HISTORY (if specified) or `regexp-history'. - If DEFAULTS is a function, we call it with no arguments and use - what it returns, which should be either nil, a string, or a list of strings. +DEFAULTS can be a symbol. If DEFAULTS is the symbol +`regexp-history-last', we use the first element of HISTORY (if +specified) or `regexp-history'. If DEFAULTS is a symbol with a +function definition, we call it with no arguments and use what it +returns, which should be either nil, a string, or a list of +strings. Other symbol values for DEFAULTS are ignored. If +`read-regexp-defaults-function' is non-nil, its value is used +instead of DEFAULTS in the two cases described in this paragraph. We append the standard values from `read-regexp-suggestions' to DEFAULTS before using it. commit 49eb03d6c8a181fd46adbbcf1f0a976d0a9efa87 Author: Eli Zaretskii Date: Wed Jan 27 17:15:46 2021 +0200 Improve documentation of 'read-regexp' and friends * doc/emacs/glossary.texi (Glossary): Add "Tag" to the Glossary. * doc/emacs/maintaining.texi (Xref): Mention that identifiers are also known as "tags". * lisp/replace.el (read-regexp, read-regexp-suggestions): Improve wording of doc strings. (Bug#46088) (Bug#46089) diff --git a/doc/emacs/glossary.texi b/doc/emacs/glossary.texi index 35df06591e..4f971eb1e0 100644 --- a/doc/emacs/glossary.texi +++ b/doc/emacs/glossary.texi @@ -1369,10 +1369,14 @@ configurations. @xref{Tab Bars}. The tab line is a line of tabs at the top of an Emacs window. Clicking on one of these tabs switches window buffers. @xref{Tab Line}. +@item Tag +A tag is an identifier in a program source. @xref{Xref}. + @anchor{Glossary---Tags Table} @item Tags Table -A tags table is a file that serves as an index to the function -definitions in one or more other files. @xref{Tags Tables}. +A tags table is a file that serves as an index to identifiers: definitions +of functions, macros, data structures, etc., in one or more other files. +@xref{Tags Tables}. @item Termscript File A termscript file contains a record of all characters sent by Emacs to diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index 415815473e..bc276c4904 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -1994,19 +1994,21 @@ Of course, you should substitute the proper years and copyright holder. @section Find Identifier References @cindex xref +@cindex tag An @dfn{identifier} is a name of a syntactical subunit of the program: a function, a subroutine, a method, a class, a data type, a macro, etc. In a programming language, each identifier is a symbol in -the language's syntax. Program development and maintenance requires -capabilities to quickly find where each identifier was defined and -referenced, to rename identifiers across the entire project, etc. - -These capabilities are also useful for finding references in major -modes other than those defined to support programming languages. For -example, chapters, sections, appendices, etc.@: of a text or a @TeX{} -document can be treated as subunits as well, and their names can be -used as identifiers. In this chapter, we use the term ``identifiers'' -to collectively refer to the names of any kind of subunits, in program +the language's syntax. Identifiers are also known as @dfn{tags}. + +Program development and maintenance requires capabilities to quickly +find where each identifier was defined and referenced, to rename +identifiers across the entire project, etc. These capabilities are +also useful for finding references in major modes other than those +defined to support programming languages. For example, chapters, +sections, appendices, etc.@: of a text or a @TeX{} document can be +treated as subunits as well, and their names can be used as +identifiers. In this chapter, we use the term ``identifiers'' to +collectively refer to the names of any kind of subunits, in program source and in other kinds of text alike. Emacs provides a unified interface to these capabilities, called diff --git a/lisp/replace.el b/lisp/replace.el index 32fbc24064..4483d7f780 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -808,11 +808,11 @@ the function that you set this to can check `this-command'." (defun read-regexp-suggestions () "Return a list of standard suggestions for `read-regexp'. -By default, the list includes the \"tag\" at point (see Info -node `(emacs) Identifier Search'), the last isearch regexp, the -last isearch string, and the last replacement regexp. -`read-regexp' appends the list returned by this function to the -end of values available via +By default, the list includes the identifier (a.k.a. \"tag\") +at point (see Info node `(emacs) Identifier Search'), the last +isearch regexp, the last isearch string, and the last +replacement regexp. `read-regexp' appends the list returned +by this function to the end of values available via \\\\[next-history-element]." (list (find-tag-default-as-regexp) @@ -827,33 +827,35 @@ Prompt with the string PROMPT. If PROMPT ends in \":\" (followed by optional whitespace), use it as-is. Otherwise, add \": \" to the end, possibly preceded by the default result (see below). -The optional argument DEFAULTS can be either: nil, a string, a list -of strings, or a symbol. We use DEFAULTS to construct the default -return value in case of empty input. +The optional argument DEFAULTS is used to construct the default +return value in case of empty input. DEFAULTS can be nil, a string, +a list of strings, or a symbol. -If DEFAULTS is a string, we use it as-is. +If DEFAULTS is a string, the function uses it as-is. If DEFAULTS is a list of strings, the first element is the default return value, but all the elements are accessible using the history command \\\\[next-history-element]. -DEFAULTS can be a symbol. If DEFAULTS is the symbol -`regexp-history-last', we use the first element of HISTORY (if -specified) or `regexp-history'. If DEFAULTS is a symbol with a -function definition, we call it with no arguments and use what it -returns, which should be either nil, a string, or a list of -strings. Other symbol values for DEFAULTS are ignored. If -`read-regexp-defaults-function' is non-nil, its value is used -instead of DEFAULTS in the two cases described in this paragraph. +If DEFAULTS is the symbol `regexp-history-last', the default return +value will be the first element of HISTORY. If HISTORY is omitted or +nil, `regexp-history' is used instead. +If DEFAULTS is a symbol with a function definition, it is called with +no arguments and should return either nil, a string, or a list of +strings, which will be used as above. +Other symbol values for DEFAULTS are ignored. -We append the standard values from `read-regexp-suggestions' to DEFAULTS -before using it. +If `read-regexp-defaults-function' is non-nil, its value is used +instead of DEFAULTS in the two cases described in the last paragraph. + +Before using whatever value DEFAULTS yields, the function appends the +standard values from `read-regexp-suggestions' to that value. If the first element of DEFAULTS is non-nil (and if PROMPT does not end -in \":\", followed by optional whitespace), we add it to the prompt. +in \":\", followed by optional whitespace), DEFAULT is added to the prompt. The optional argument HISTORY is a symbol to use for the history list. -If nil, uses `regexp-history'." +If nil, use `regexp-history'." (let* ((defaults (if (and defaults (symbolp defaults)) (cond commit 08574a7f40f27ad29efb8f7d975012ecc9111717 Author: Juri Linkov Date: Wed Jan 27 11:42:30 2021 +0200 * lisp/subr.el (empty-history): Move defvar to functions where it's used. diff --git a/lisp/subr.el b/lisp/subr.el index f249ec3578..afa73c72ea 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2965,8 +2965,6 @@ Also discard all previous input in the minibuffer." (minibuffer-message "Wrong answer") (sit-for 2))) -(defvar empty-history) - (defun read-char-from-minibuffer (prompt &optional chars history) "Read a character from the minibuffer, prompting for it with PROMPT. Like `read-char', but uses the minibuffer to read and return a character. @@ -2981,6 +2979,7 @@ while calling this function, then pressing `help-char' causes it to evaluate `help-form' and display the result. There is no need to explicitly add `help-char' to CHARS; `help-char' is bound automatically to `help-form-show'." + (defvar empty-history) (let* ((empty-history '()) (map (if (consp chars) (or (gethash (list help-form (cons help-char chars)) @@ -3093,8 +3092,6 @@ Also discard all previous input in the minibuffer." "Prefer `read-key' when answering a \"y or n\" question by `y-or-n-p'. Otherwise, use the minibuffer.") -(defvar empty-history) - (defun y-or-n-p (prompt) "Ask user a \"y or n\" question. Return t if answer is \"y\" and nil if it is \"n\". @@ -3190,6 +3187,7 @@ is nil and `use-dialog-box' is non-nil." (discard-input))) (t (setq prompt (funcall padded prompt)) + (defvar empty-history) (let* ((empty-history '()) (enable-recursive-minibuffers t) (msg help-form) commit fb05199b0bf2055d75b7eba52c3ab2fd49d38509 Author: Juri Linkov Date: Mon Jan 25 22:10:15 2021 +0200 Support variable name for previous-window in display-buffer-in-previous-window * lisp/window.el (display-buffer-in-previous-window): Support the value of 'previous-window' entry as a symbol for variable name (bug#45688). diff --git a/lisp/window.el b/lisp/window.el index 0a37d16273..d587691420 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -8196,8 +8196,8 @@ such alists. If ALIST has a non-nil `inhibit-same-window' entry, the selected window is not usable. A dedicated window is usable only if it already shows BUFFER. If ALIST contains a `previous-window' -entry, the window specified by that entry is usable even if it -never showed BUFFER before. +entry, the window specified by that entry (either a variable +or a value) is usable even if it never showed BUFFER before. If ALIST contains a `reusable-frames' entry, its value determines which frames to search for a usable window: @@ -8239,6 +8239,7 @@ indirectly called by the latter." 0) (display-buffer-reuse-frames 0) (t (last-nonminibuffer-frame)))) + (previous-window (cdr (assq 'previous-window alist))) best-window second-best-window window) ;; Scan windows whether they have shown the buffer recently. (catch 'best @@ -8252,7 +8253,9 @@ indirectly called by the latter." (throw 'best t))))) ;; When ALIST has a `previous-window' entry, that entry may override ;; anything we found so far. - (when (and (setq window (cdr (assq 'previous-window alist))) + (when (and previous-window (boundp previous-window)) + (setq previous-window (symbol-value previous-window))) + (when (and (setq window previous-window) (window-live-p window) (or (eq buffer (window-buffer window)) (not (window-dedicated-p window)))) commit 9d50d7a0c6ff742ad682ef63e09c7e7341909b28 Author: Lars Ingebrigtsen Date: Wed Jan 27 07:04:08 2021 +0100 Fix indentation in sieve-mode * lisp/net/sieve-mode.el (sieve-mode-indent-function): New function. (sieve-mode): Don't inherit from C mode, because the syntax doesn't really resemble C mode that much (except being curly braced). diff --git a/lisp/net/sieve-mode.el b/lisp/net/sieve-mode.el index fbc4e75fae..7bc1d16122 100644 --- a/lisp/net/sieve-mode.el +++ b/lisp/net/sieve-mode.el @@ -128,6 +128,9 @@ (modify-syntax-entry ?| "." st) (modify-syntax-entry ?_ "_" st) (modify-syntax-entry ?\' "\"" st) + (modify-syntax-entry ?\{ "(}" st) + (modify-syntax-entry ?\} "){" st) + (modify-syntax-entry ?\" "\"" st) st) "Syntax table in use in sieve-mode buffers.") @@ -178,12 +181,8 @@ 'syntax-table (string-to-syntax "|"))))) ;;;###autoload -(define-derived-mode sieve-mode c-mode "Sieve" +(define-derived-mode sieve-mode prog-mode "Sieve" "Major mode for editing Sieve code. -This is much like C mode except for the syntax of comments. Its keymap -inherits from C mode's and it has the same variables for customizing -indentation. It has its own abbrev table and its own syntax table. - Turning on Sieve mode runs `sieve-mode-hook'." (setq-local paragraph-start (concat "$\\|" page-delimiter)) (setq-local paragraph-separate paragraph-start) @@ -194,8 +193,17 @@ Turning on Sieve mode runs `sieve-mode-hook'." (setq-local syntax-propertize-function #'sieve-syntax-propertize) (setq-local font-lock-defaults '(sieve-font-lock-keywords nil nil ((?_ . "w")))) + (setq-local indent-line-function #'sieve-mode-indent-function) (easy-menu-add-item nil nil sieve-mode-menu)) +(defun sieve-mode-indent-function () + (save-excursion + (beginning-of-line) + (let ((depth (car (syntax-ppss)))) + (when (looking-at "[ \t]*}") + (setq depth (1- depth))) + (indent-line-to (* 2 depth))))) + (provide 'sieve-mode) ;; sieve-mode.el ends here commit 883c15fb3244500901bb30bddc66c26e8a6ba200 Author: Lars Ingebrigtsen Date: Wed Jan 27 04:27:42 2021 +0100 Fix setting of line/point style in calc gnuplot * lisp/calc/calc-graph.el (calc-graph-set-styles): Modern gnuplot requires "ls" before the line style and "ps" before the point style (bug#46070). diff --git a/lisp/calc/calc-graph.el b/lisp/calc/calc-graph.el index 4785fb7fba..423d1e6412 100644 --- a/lisp/calc/calc-graph.el +++ b/lisp/calc/calc-graph.el @@ -1136,11 +1136,11 @@ This \"dumb\" driver will be present in Gnuplot 3.0." (if penbl "linespoints" "lines") (if penbl "points" "dots")))) (if (and pstyle (> pstyle 0)) - (insert " " + (insert " ls " (if (and lstyle (> lstyle 0)) (int-to-string lstyle) "1") - " " (int-to-string pstyle)) + " ps " (int-to-string pstyle)) (if (and lstyle (> lstyle 0)) - (insert " " (int-to-string lstyle))))))) + (insert " ls " (int-to-string lstyle))))))) (calc-graph-view-commands)) (defun calc-graph-zero-x (flag) commit f9cc2d48246fe8370e9286866e6115ba8e2acf44 Author: Lars Ingebrigtsen Date: Wed Jan 27 03:47:02 2021 +0100 read-regexp-suggestions doc string improvement * lisp/replace.el (read-regexp-suggestions): Add a link to the manual to explain what a tag is (bug#46089). diff --git a/lisp/replace.el b/lisp/replace.el index cf1dcb4992..32fbc24064 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -808,10 +808,12 @@ the function that you set this to can check `this-command'." (defun read-regexp-suggestions () "Return a list of standard suggestions for `read-regexp'. -By default, the list includes the tag at point, the last isearch regexp, -the last isearch string, and the last replacement regexp. `read-regexp' -appends the list returned by this function to the end of values available -via \\\\[next-history-element]." +By default, the list includes the \"tag\" at point (see Info +node `(emacs) Identifier Search'), the last isearch regexp, the +last isearch string, and the last replacement regexp. +`read-regexp' appends the list returned by this function to the +end of values available via +\\\\[next-history-element]." (list (find-tag-default-as-regexp) (find-tag-default-as-symbol-regexp) commit eded2a7ad7d456a417354a2797c18e9a578414d7 Author: Lars Ingebrigtsen Date: Wed Jan 27 03:38:49 2021 +0100 Try to improve the read-regexp doc string * lisp/replace.el (read-regexp): Attempt to clarify the semantics (bug#46088). diff --git a/lisp/replace.el b/lisp/replace.el index db5b340631..cf1dcb4992 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -835,12 +835,14 @@ If DEFAULTS is a list of strings, the first element is the default return value, but all the elements are accessible using the history command \\\\[next-history-element]. -If DEFAULTS is a non-nil symbol, then if `read-regexp-defaults-function' -is non-nil, we use that in place of DEFAULTS in the following: - If DEFAULTS is the symbol `regexp-history-last', we use the first - element of HISTORY (if specified) or `regexp-history'. - If DEFAULTS is a function, we call it with no arguments and use - what it returns, which should be either nil, a string, or a list of strings. +DEFAULTS can be a symbol. If DEFAULTS is the symbol +`regexp-history-last', we use the first element of HISTORY (if +specified) or `regexp-history'. If DEFAULTS is a symbol with a +function definition, we call it with no arguments and use what it +returns, which should be either nil, a string, or a list of +strings. Other symbol values for DEFAULTS are ignored. If +`read-regexp-defaults-function' is non-nil, its value is used +instead of DEFAULTS in the two cases described in this paragraph. We append the standard values from `read-regexp-suggestions' to DEFAULTS before using it. commit b870e584a4275be83d6878001ee613997282fd37 Author: Stefan Monnier Date: Tue Jan 26 18:17:00 2021 -0500 Use lexical-binding in all of `lisp/url` * lisp/url/url-dav.el: Use lexical-binding. (url-dav-process-DAV:prop): Remove unused var `handler-func`. (url-dav-lock-resource): Remove unused var `child-url`. (url-dav-active-locks): Remove unused var `properties`. (url-dav-delete-directory): Remove unused var `props`. (url-dav-file-name-completion): Remove unused var `result`. * lisp/url/url-expand.el (url-expand-file-name): Use \s * lisp/url/url-file.el (url-file): Improve regexp. * lisp/url/url-gw.el: Use lexical-binding. (url-open-stream): Remove unused var `cur-retries`, `retry`, `errobj`. * lisp/url/url-imap.el: Use lexical-binding. (imap-username, imap-password): Declare. * lisp/url/url-mailto.el: Use lexical-binding. (url-mailto): Remove unused var `func`. Use `push`. * lisp/url/url-news.el: Use lexical-binding. (url-news): Remove unused var `article-brackets`. * lisp/url/url-cid.el: * lisp/url/url-cache.el: * lisp/url/url-about.el: * lisp/url/url-tramp.el: * lisp/url/url-proxy.el: * lisp/url/url-privacy.el: * lisp/url/url-nfs.el: * lisp/url/url-ldap.el: * lisp/url/url-misc.el: * lisp/url/url-methods.el: Use lexical-binding. diff --git a/lisp/url/url-about.el b/lisp/url/url-about.el index bff5570f6d..6ae90ccefa 100644 --- a/lisp/url/url-about.el +++ b/lisp/url/url-about.el @@ -1,4 +1,4 @@ -;;; url-about.el --- Show internal URLs +;;; url-about.el --- Show internal URLs -*- lexical-binding: t; -*- ;; Copyright (C) 2001, 2004-2021 Free Software Foundation, Inc. @@ -44,7 +44,7 @@ (defvar url-scheme-registry) -(defun url-about-protocols (url) +(defun url-about-protocols (_url) (url-probe-protocols) (insert "\n" " \n" @@ -73,13 +73,15 @@ "ynchronous
\n" (if (url-scheme-get-property k 'default-port) (format "Default Port: %d
\n" - (url-scheme-get-property k 'default-port)) "") + (url-scheme-get-property k 'default-port)) + "") (if (assoc k url-proxy-services) (format "Proxy: %s
\n" (assoc k url-proxy-services)) "")) ;; Now the description... (insert " " (or (url-scheme-get-property k 'description) "N/A")))) - (sort (let (x) (maphash (lambda (k v) (push k x)) url-scheme-registry) x) 'string-lessp)) + (sort (let (x) (maphash (lambda (k _v) (push k x)) url-scheme-registry) x) + #'string-lessp)) (insert " \n" " \n" "\n")) diff --git a/lisp/url/url-cache.el b/lisp/url/url-cache.el index acf88eb021..830e6ba9dc 100644 --- a/lisp/url/url-cache.el +++ b/lisp/url/url-cache.el @@ -1,4 +1,4 @@ -;;; url-cache.el --- Uniform Resource Locator retrieval tool +;;; url-cache.el --- Uniform Resource Locator retrieval tool -*- lexical-binding: t; -*- ;; Copyright (C) 1996-1999, 2004-2021 Free Software Foundation, Inc. diff --git a/lisp/url/url-cid.el b/lisp/url/url-cid.el index d465cabc90..0ca2d8a073 100644 --- a/lisp/url/url-cid.el +++ b/lisp/url/url-cid.el @@ -1,4 +1,4 @@ -;;; url-cid.el --- Content-ID URL loader +;;; url-cid.el --- Content-ID URL loader -*- lexical-binding: t; -*- ;; Copyright (C) 1998-1999, 2004-2021 Free Software Foundation, Inc. diff --git a/lisp/url/url-dav.el b/lisp/url/url-dav.el index 12d5a683e9..edb1c1de9f 100644 --- a/lisp/url/url-dav.el +++ b/lisp/url/url-dav.el @@ -1,4 +1,4 @@ -;;; url-dav.el --- WebDAV support +;;; url-dav.el --- WebDAV support -*- lexical-binding: t; -*- ;; Copyright (C) 2001, 2004-2021 Free Software Foundation, Inc. @@ -133,7 +133,8 @@ Returns nil if WebDAV is not supported." (node-type nil) (props nil) (value nil) - (handler-func nil)) + ;; (handler-func nil) + ) (when (not children) (error "No child nodes in DAV:prop")) @@ -453,7 +454,7 @@ FAILURE-RESULTS is a list of (URL STATUS)." " \n")) (response nil) ; Responses to the LOCK request (result nil) ; For walking thru the response list - (child-url nil) + ;; (child-url nil) (child-status nil) (failures nil) ; List of failure cases (URL . STATUS) (successes nil)) ; List of success cases (URL . STATUS) @@ -468,7 +469,7 @@ FAILURE-RESULTS is a list of (URL STATUS)." ;; status code. (while response (setq result (pop response) - child-url (url-expand-file-name (pop result) url) + ;; child-url (url-expand-file-name (pop result) url) child-status (or (plist-get result 'DAV:status) 500)) (if (url-dav-http-success-p child-status) (push (list url child-status "huh") successes) @@ -478,7 +479,7 @@ FAILURE-RESULTS is a list of (URL STATUS)." (defun url-dav-active-locks (url &optional depth) "Return an assoc list of all active locks on URL." (let ((response (url-dav-get-properties url '(DAV:lockdiscovery) depth)) - (properties nil) + ;; (properties nil) (child nil) (child-url nil) (child-results nil) @@ -676,7 +677,6 @@ Use with care, and even then think three times." If optional second argument RECURSIVE is non-nil, then delete all files in the collection as well." (let ((status nil) - (props nil) (props nil)) (setq props (url-dav-delete-something url lock-token @@ -769,7 +769,7 @@ If NOSORT is non-nil, the list is not sorted--its order is unpredictable. (when (member 'DAV:collection (plist-get properties 'DAV:resourcetype)) t))) -(defun url-dav-make-directory (url &optional parents) +(defun url-dav-make-directory (url &optional _parents) "Create the directory DIR and any nonexistent parent dirs." (let* ((url-request-extra-headers nil) (url-request-method "MKCOL") @@ -849,7 +849,9 @@ that start with FILE. If there is only one and FILE matches it exactly, returns t. Returns nil if URL contains no name starting with FILE." (let ((matches (url-dav-file-name-all-completions file url)) - (result nil)) + ;; (result nil) + ) + ;; FIXME: Use `try-completion'! (cond ((null matches) ;; No matches diff --git a/lisp/url/url-expand.el b/lisp/url/url-expand.el index a42b4c7ad2..05088e3cac 100644 --- a/lisp/url/url-expand.el +++ b/lisp/url/url-expand.el @@ -66,7 +66,7 @@ path components followed by `..' are removed, along with the `..' itself." ;; Need to nuke newlines and spaces in the URL, or we open ;; ourselves up to potential security holes. (setq url (mapconcat (lambda (x) - (if (memq x '(? ?\n ?\r)) + (if (memq x '(?\s ?\n ?\r)) "" (char-to-string x))) url ""))) diff --git a/lisp/url/url-file.el b/lisp/url/url-file.el index 52a9588030..0e2ab5544b 100644 --- a/lisp/url/url-file.el +++ b/lisp/url/url-file.el @@ -154,7 +154,7 @@ to them." ;; not the compressed one. ;; FIXME should this regexp not include more extensions; basically ;; everything that url-file-find-possibly-compressed-file does? - (setq uncompressed-filename (if (string-match "\\.\\(gz\\|Z\\|z\\)$" filename) + (setq uncompressed-filename (if (string-match "\\.\\(gz\\|Z\\|z\\)\\'" filename) (substring filename 0 (match-beginning 0)) filename)) (setq content-type (mailcap-extension-to-mime diff --git a/lisp/url/url-gw.el b/lisp/url/url-gw.el index 68df67f648..d2bf843fc3 100644 --- a/lisp/url/url-gw.el +++ b/lisp/url/url-gw.el @@ -1,4 +1,4 @@ -;;; url-gw.el --- Gateway munging for URL loading +;;; url-gw.el --- Gateway munging for URL loading -*- lexical-binding: t; -*- ;; Copyright (C) 1997-1998, 2004-2021 Free Software Foundation, Inc. @@ -222,18 +222,17 @@ overriding the value of `url-gateway-method'." host)) 'native gwm)) - ;; An attempt to deal with denied connections, and attempt - ;; to reconnect - (cur-retries 0) - (retry t) - (errobj nil) - (conn nil)) + ;; An attempt to deal with denied connections, and attempt + ;; to reconnect + ;; (cur-retries 0) + ;; (retry t) + (conn nil)) ;; If the user told us to do DNS for them, do it. (if url-gateway-broken-resolution (setq host (url-gateway-nslookup-host host))) - (condition-case errobj + (condition-case nil ;; This is a clean way to ensure the new process inherits the ;; right coding systems in both Emacs and XEmacs. (let ((coding-system-for-read 'binary) diff --git a/lisp/url/url-http.el b/lisp/url/url-http.el index 324cf99554..61e07a0d9c 100644 --- a/lisp/url/url-http.el +++ b/lisp/url/url-http.el @@ -66,7 +66,7 @@ (defconst url-http-default-port 80 "Default HTTP port.") (defconst url-http-asynchronous-p t "HTTP retrievals are asynchronous.") -(defalias 'url-http-expand-file-name 'url-default-expander) +(defalias 'url-http-expand-file-name #'url-default-expander) (defvar url-http-real-basic-auth-storage nil) (defvar url-http-proxy-basic-auth-storage nil) @@ -150,7 +150,7 @@ request.") ;; These routines will allow us to implement persistent HTTP ;; connections. (defsubst url-http-debug (&rest args) - (apply 'url-debug 'http args)) + (apply #'url-debug 'http args)) (defun url-http-mark-connection-as-busy (host port proc) (url-http-debug "Marking connection as busy: %s:%d %S" host port proc) @@ -1203,8 +1203,7 @@ the end of the document." ;; We got back a headerless malformed response from the ;; server. (url-http-activate-callback)) - ((or (= url-http-response-status 204) - (= url-http-response-status 205)) + ((memq url-http-response-status '(204 205)) (url-http-debug "%d response must have headers only (%s)." url-http-response-status (buffer-name)) (when (url-http-parse-headers) @@ -1239,11 +1238,11 @@ the end of the document." (url-http-debug "Saw HTTP/0.9 response, connection closed means end of document.") (setq url-http-after-change-function - 'url-http-simple-after-change-function)) + #'url-http-simple-after-change-function)) ((equal url-http-transfer-encoding "chunked") (url-http-debug "Saw chunked encoding.") (setq url-http-after-change-function - 'url-http-chunked-encoding-after-change-function) + #'url-http-chunked-encoding-after-change-function) (when (> nd url-http-end-of-headers) (url-http-debug "Calling initial chunked-encoding for extra data at end of headers") @@ -1254,7 +1253,7 @@ the end of the document." (url-http-debug "Got a content-length, being smart about document end.") (setq url-http-after-change-function - 'url-http-content-length-after-change-function) + #'url-http-content-length-after-change-function) (cond ((= 0 url-http-content-length) ;; We got a NULL body! Activate the callback @@ -1275,7 +1274,7 @@ the end of the document." (t (url-http-debug "No content-length, being dumb.") (setq url-http-after-change-function - 'url-http-simple-after-change-function))))) + #'url-http-simple-after-change-function))))) ;; We are still at the beginning of the buffer... must just be ;; waiting for a response. (url-http-debug "Spinning waiting for headers...") @@ -1374,7 +1373,7 @@ The return value of this function is the retrieval buffer." url-http-referer referer) (set-process-buffer connection buffer) - (set-process-filter connection 'url-http-generic-filter) + (set-process-filter connection #'url-http-generic-filter) (pcase (process-status connection) ('connect ;; Asynchronous connection @@ -1388,12 +1387,12 @@ The return value of this function is the retrieval buffer." (url-type url-current-object))) (url-https-proxy-connect connection) (set-process-sentinel connection - 'url-http-end-of-document-sentinel) + #'url-http-end-of-document-sentinel) (process-send-string connection (url-http-create-request))))))) buffer)) (defun url-https-proxy-connect (connection) - (setq url-http-after-change-function 'url-https-proxy-after-change-function) + (setq url-http-after-change-function #'url-https-proxy-after-change-function) (process-send-string connection (format @@ -1441,7 +1440,7 @@ The return value of this function is the retrieval buffer." (with-current-buffer process-buffer (erase-buffer)) (set-process-buffer tls-connection process-buffer) (setq url-http-after-change-function - 'url-http-wait-for-headers-change-function) + #'url-http-wait-for-headers-change-function) (set-process-filter tls-connection 'url-http-generic-filter) (process-send-string tls-connection (url-http-create-request))) @@ -1510,7 +1509,7 @@ The return value of this function is the retrieval buffer." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defalias 'url-http-symbol-value-in-buffer (if (fboundp 'symbol-value-in-buffer) - 'symbol-value-in-buffer + #'symbol-value-in-buffer (lambda (symbol buffer &optional unbound-value) "Return the value of SYMBOL in BUFFER, or UNBOUND-VALUE if it is unbound." (with-current-buffer buffer diff --git a/lisp/url/url-imap.el b/lisp/url/url-imap.el index 05c3e73fb0..492907f33f 100644 --- a/lisp/url/url-imap.el +++ b/lisp/url/url-imap.el @@ -1,4 +1,4 @@ -;;; url-imap.el --- IMAP retrieval routines +;;; url-imap.el --- IMAP retrieval routines -*- lexical-binding: t; -*- ;; Copyright (C) 1999, 2004-2021 Free Software Foundation, Inc. @@ -37,6 +37,9 @@ (defconst url-imap-default-port 143 "Default IMAP port.") +(defvar imap-username) +(defvar imap-password) + (defun url-imap-open-host (host port user pass) ;; xxx use user and password (if (fboundp 'nnheader-init-server-buffer) diff --git a/lisp/url/url-ldap.el b/lisp/url/url-ldap.el index 0fa9970fa4..d26562b7f1 100644 --- a/lisp/url/url-ldap.el +++ b/lisp/url/url-ldap.el @@ -1,4 +1,4 @@ -;;; url-ldap.el --- LDAP Uniform Resource Locator retrieval code +;;; url-ldap.el --- LDAP Uniform Resource Locator retrieval code -*- lexical-binding: t; -*- ;; Copyright (C) 1998-1999, 2004-2021 Free Software Foundation, Inc. diff --git a/lisp/url/url-mailto.el b/lisp/url/url-mailto.el index 688f102cab..72884c07cc 100644 --- a/lisp/url/url-mailto.el +++ b/lisp/url/url-mailto.el @@ -1,4 +1,4 @@ -;;; url-mail.el --- Mail Uniform Resource Locator retrieval code +;;; url-mail.el --- Mail Uniform Resource Locator retrieval code -*- lexical-binding: t; -*- ;; Copyright (C) 1996-1999, 2004-2021 Free Software Foundation, Inc. @@ -67,7 +67,7 @@ ;; mailto:wmperry@gnu.org (setf (url-filename url) (concat (url-user url) "@" (url-filename url)))) (setq url (url-filename url)) - (let (to args source-url subject func headers-start) + (let (to args source-url subject headers-start) ;; func (if (string-match (regexp-quote "?") url) (setq headers-start (match-end 0) to (url-unhex-string (substring url 0 (match-beginning 0))) @@ -76,10 +76,11 @@ (setq to (url-unhex-string url))) (setq source-url (url-view-url t)) (if (and url-request-data (not (assoc "subject" args))) - (setq args (cons (list "subject" + (push (list "subject" (concat "Automatic submission from " url-package-name "/" - url-package-version)) args))) + url-package-version)) + args)) (if (and source-url (not (assoc "x-url-from" args))) (setq args (cons (list "x-url-from" source-url) args))) @@ -107,7 +108,7 @@ (replace-regexp-in-string "\r\n" "\n" string)) (cdar args) "\n"))) (url-mail-goto-field (caar args)) - (setq func (intern-soft (concat "mail-" (caar args)))) + ;; (setq func (intern-soft (concat "mail-" (caar args)))) (insert (mapconcat 'identity (cdar args) ", "))) (setq args (cdr args))) ;; (url-mail-goto-field "User-Agent") diff --git a/lisp/url/url-methods.el b/lisp/url/url-methods.el index 7aad741210..cfe7d5bc6a 100644 --- a/lisp/url/url-methods.el +++ b/lisp/url/url-methods.el @@ -1,4 +1,4 @@ -;;; url-methods.el --- Load URL schemes as needed +;;; url-methods.el --- Load URL schemes as needed -*- lexical-binding: t; -*- ;; Copyright (C) 1996-1999, 2004-2021 Free Software Foundation, Inc. @@ -57,7 +57,7 @@ 'file-exists-p 'ignore 'file-attributes 'ignore)) -(defun url-scheme-default-loader (url &optional callback cbargs) +(defun url-scheme-default-loader (url &optional _callback _cbargs) "Signal an error for an unknown URL scheme." (error "Unknown URL scheme: %s" (url-type url))) diff --git a/lisp/url/url-misc.el b/lisp/url/url-misc.el index d3db31d612..fe2393beb6 100644 --- a/lisp/url/url-misc.el +++ b/lisp/url/url-misc.el @@ -1,4 +1,4 @@ -;;; url-misc.el --- Misc Uniform Resource Locator retrieval code +;;; url-misc.el --- Misc Uniform Resource Locator retrieval code -*- lexical-binding: t; -*- ;; Copyright (C) 1996-1999, 2002, 2004-2021 Free Software Foundation, ;; Inc. diff --git a/lisp/url/url-news.el b/lisp/url/url-news.el index d5f8483ab7..585a28291a 100644 --- a/lisp/url/url-news.el +++ b/lisp/url/url-news.el @@ -1,4 +1,4 @@ -;;; url-news.el --- News Uniform Resource Locator retrieval code +;;; url-news.el --- News Uniform Resource Locator retrieval code -*- lexical-binding: t; -*- ;; Copyright (C) 1996-1999, 2004-2021 Free Software Foundation, Inc. @@ -106,7 +106,7 @@ ;; Find a news reference (let* ((host (or (url-host url) url-news-server)) (port (url-port url)) - (article-brackets nil) + ;; (article-brackets nil) (buf nil) (article (url-unhex-string (url-filename url)))) (url-news-open-host host port (url-user url) (url-password url)) diff --git a/lisp/url/url-nfs.el b/lisp/url/url-nfs.el index 3c80c8059b..0449930408 100644 --- a/lisp/url/url-nfs.el +++ b/lisp/url/url-nfs.el @@ -1,4 +1,4 @@ -;;; url-nfs.el --- NFS URL interface +;;; url-nfs.el --- NFS URL interface -*- lexical-binding: t; -*- ;; Copyright (C) 1996-1999, 2004-2021 Free Software Foundation, Inc. diff --git a/lisp/url/url-privacy.el b/lisp/url/url-privacy.el index e3ca0f66d9..d926775c48 100644 --- a/lisp/url/url-privacy.el +++ b/lisp/url/url-privacy.el @@ -1,4 +1,4 @@ -;;; url-privacy.el --- Global history tracking for URL package +;;; url-privacy.el --- Global history tracking for URL package -*- lexical-binding: t; -*- ;; Copyright (C) 1996-1999, 2004-2021 Free Software Foundation, Inc. @@ -23,7 +23,7 @@ (require 'url-vars) -(defun url-device-type (&optional device) +(defun url-device-type (&optional _device) (declare (obsolete nil "27.1")) (or window-system 'tty)) diff --git a/lisp/url/url-proxy.el b/lisp/url/url-proxy.el index 6bf6584509..8436c7a4be 100644 --- a/lisp/url/url-proxy.el +++ b/lisp/url/url-proxy.el @@ -1,4 +1,4 @@ -;;; url-proxy.el --- Proxy server support +;;; url-proxy.el --- Proxy server support -*- lexical-binding: t; -*- ;; Copyright (C) 1999, 2004-2021 Free Software Foundation, Inc. diff --git a/lisp/url/url-tramp.el b/lisp/url/url-tramp.el index 325d25cb8e..5b9dd8a268 100644 --- a/lisp/url/url-tramp.el +++ b/lisp/url/url-tramp.el @@ -1,4 +1,4 @@ -;;; url-tramp.el --- file-name-handler magic invoking Tramp for some protocols +;;; url-tramp.el --- file-name-handler magic invoking Tramp for some protocols -*- lexical-binding: t; -*- ;; Copyright (C) 2014-2021 Free Software Foundation, Inc. diff --git a/lisp/url/url.el b/lisp/url/url.el index 172a3af2b3..8daf9f0a8e 100644 --- a/lisp/url/url.el +++ b/lisp/url/url.el @@ -156,16 +156,16 @@ If INHIBIT-COOKIES, cookies will neither be stored nor sent to the server. If URL is a multibyte string, it will be encoded as utf-8 and URL-encoded before it's used." -;;; XXX: There is code in Emacs that does dynamic binding -;;; of the following variables around url-retrieve: -;;; url-standalone-mode, url-gateway-unplugged, w3-honor-stylesheets, -;;; url-confirmation-func, url-cookie-multiple-line, -;;; url-cookie-{{,secure-}storage,confirmation} -;;; url-standalone-mode and url-gateway-unplugged should work as -;;; usual. url-confirmation-func is only used in nnwarchive.el and -;;; webmail.el; the latter should be updated. Is -;;; url-cookie-multiple-line needed anymore? The other url-cookie-* -;;; are (for now) only used in synchronous retrievals. + ;; XXX: There is code in Emacs that does dynamic binding + ;; of the following variables around url-retrieve: + ;; url-standalone-mode, url-gateway-unplugged, w3-honor-stylesheets, + ;; url-confirmation-func, url-cookie-multiple-line, + ;; url-cookie-{{,secure-}storage,confirmation} + ;; url-standalone-mode and url-gateway-unplugged should work as + ;; usual. url-confirmation-func is only used in nnwarchive.el and + ;; webmail.el; the latter should be updated. Is + ;; url-cookie-multiple-line needed anymore? The other url-cookie-* + ;; are (for now) only used in synchronous retrievals. (url-retrieve-internal url callback (cons nil cbargs) silent inhibit-cookies)) @@ -210,7 +210,7 @@ URL-encoded before it's used." (asynch (url-scheme-get-property (url-type url) 'asynchronous-p))) (if url-using-proxy (setq asynch t - loader 'url-proxy)) + loader #'url-proxy)) (if asynch (let ((url-current-object url)) (setq buffer (funcall loader url callback cbargs))) commit a572b21928a33b7ede445769bde5a67356327fef Author: Stefan Monnier Date: Tue Jan 26 17:57:26 2021 -0500 * lisp/progmodes/sh-script.el (sh-smie-sh-rules): Tweak indent of new `for` The new `for (TEST) { BODY }` syntax introduces various challenges. This patch just fixes a trivial subcase. diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index cc045a1b2d..fd68952767 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -1957,12 +1957,18 @@ May return nil if the line should not be treated as continued." ('(:after . "case-)") (- (sh-var-value 'sh-indent-for-case-alt) (sh-var-value 'sh-indent-for-case-label))) (`(:before . ,(or "(" "{" "[" "while" "if" "for" "case")) - (if (not (smie-rule-prev-p "&&" "||" "|")) - (when (smie-rule-hanging-p) - (smie-rule-parent)) + (cond + ((and (equal token "{") (smie-rule-parent-p "for")) + (let ((data (smie-backward-sexp "in"))) + (when (equal (nth 2 data) "for") + `(column . ,(smie-indent-virtual))))) + ((not (smie-rule-prev-p "&&" "||" "|")) + (when (smie-rule-hanging-p) + (smie-rule-parent))) + (t (unless (smie-rule-bolp) (while (equal "|" (nth 2 (smie-backward-sexp 'halfexp)))) - `(column . ,(smie-indent-virtual))))) + `(column . ,(smie-indent-virtual)))))) ;; FIXME: Maybe this handling of ;; should be made into ;; a smie-rule-terminator function that takes the substitute ";" as arg. (`(:before . ,(or ";;" ";&" ";;&")) diff --git a/test/manual/indent/shell.sh b/test/manual/indent/shell.sh index dc184ea0d7..bd4a74f705 100755 --- a/test/manual/indent/shell.sh +++ b/test/manual/indent/shell.sh @@ -6,6 +6,13 @@ setlock -n /tmp/getmail.lock && echo getmail isn\'t running toto=$(grep hello foo | wc) +myfun () { + for ((it=0; it<${limit}; ++it)) + { + echo "whatever $it" + } +} + # adsgsdg if foo; then commit 046db04e3da4afa7c6eb05af8c7ceb048689521a Author: Eric Abrahamsen Date: Tue Jan 26 08:47:07 2021 -0800 Revert "Allow gnus-retrieve-headers to return headers directly" This reverts commit 20add1cd22f9775a4475148b300cf2a4de4bd54a. This needs more work before it's ready to merge. diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el index 686623029e..56640ea830 100644 --- a/lisp/gnus/gnus-agent.el +++ b/lisp/gnus/gnus-agent.el @@ -1789,7 +1789,6 @@ variables. Returns the first non-nil value found." . gnus-agent-enable-expiration) (agent-predicate . gnus-agent-predicate))))))) -;; FIXME: This looks an awful lot like `gnus-agent-retrieve-headers'. (defun gnus-agent-fetch-headers (group) "Fetch interesting headers into the agent. The group's overview file will be updated to include the headers while a list of available @@ -1811,9 +1810,10 @@ article numbers will be returned." (cdr active)))) (gnus-uncompress-range (gnus-active group))) (gnus-list-of-unread-articles group))) + (gnus-decode-encoded-word-function 'identity) + (gnus-decode-encoded-address-function 'identity) (file (gnus-agent-article-name ".overview" group)) - (file-name-coding-system nnmail-pathname-coding-system) - headers fetched-headers) + (file-name-coding-system nnmail-pathname-coding-system)) (unless fetch-all ;; Add articles with marks to the list of article headers we want to @@ -1824,7 +1824,7 @@ article numbers will be returned." (dolist (arts (gnus-info-marks (gnus-get-info group))) (unless (memq (car arts) '(seen recent killed cache)) (setq articles (gnus-range-add articles (cdr arts))))) - (setq articles (sort (gnus-uncompress-range articles) '<))) + (setq articles (sort (gnus-uncompress-sequence articles) '<))) ;; At this point, I have the list of articles to consider for ;; fetching. This is the list that I'll return to my caller. Some @@ -1867,52 +1867,38 @@ article numbers will be returned." 10 "gnus-agent-fetch-headers: undownloaded articles are `%s'" (gnus-compress-sequence articles t))) - ;; Parse known headers from FILE. - (if (file-exists-p file) - (with-current-buffer gnus-agent-overview-buffer - (erase-buffer) - (let ((nnheader-file-coding-system - gnus-agent-file-coding-system)) - (nnheader-insert-nov-file file (car articles)) - (with-current-buffer nntp-server-buffer - (erase-buffer) - (insert-buffer-substring gnus-agent-overview-buffer) - (setq headers - (gnus-get-newsgroup-headers-xover - articles nil (buffer-local-value - 'gnus-newsgroup-dependencies - gnus-summary-buffer) - gnus-newsgroup-name))))) - (gnus-make-directory (nnheader-translate-file-chars - (file-name-directory file) t))) - - ;; Fetch our new headers. - (gnus-message 8 "Fetching headers for %s..." group) - (if articles - (setq fetched-headers (gnus-fetch-headers articles))) - - ;; Merge two sets of headers. - (setq headers - (if (and headers fetched-headers) - (delete-dups - (sort (append headers (copy-sequence fetched-headers)) - (lambda (l r) - (< (mail-header-number l) - (mail-header-number r))))) - (or headers fetched-headers))) - - ;; Save the new set of headers to FILE. - (let ((coding-system-for-write - gnus-agent-file-coding-system)) - (with-current-buffer gnus-agent-overview-buffer - (goto-char (point-max)) - (mapc #'nnheader-insert-nov fetched-headers) - (sort-numeric-fields 1 (point-min) (point-max)) - (gnus-agent-check-overview-buffer) - (write-region (point-min) (point-max) file nil 'silent)) - (gnus-agent-update-view-total-fetched-for group t) - (gnus-agent-save-alist group articles nil))) - headers)) + (with-current-buffer nntp-server-buffer + (if articles + (progn + (gnus-message 8 "Fetching headers for %s..." group) + + ;; Fetch them. + (gnus-make-directory (nnheader-translate-file-chars + (file-name-directory file) t)) + + (unless (eq 'nov (gnus-retrieve-headers articles group)) + (nnvirtual-convert-headers)) + (gnus-agent-check-overview-buffer) + ;; Move these headers to the overview buffer so that + ;; gnus-agent-braid-nov can merge them with the contents + ;; of FILE. + (copy-to-buffer + gnus-agent-overview-buffer (point-min) (point-max)) + ;; NOTE: Call g-a-brand-nov even when the file does not + ;; exist. As a minimum, it will validate the article + ;; numbers already in the buffer. + (gnus-agent-braid-nov articles file) + (let ((coding-system-for-write + gnus-agent-file-coding-system)) + (gnus-agent-check-overview-buffer) + (write-region (point-min) (point-max) file nil 'silent)) + (gnus-agent-update-view-total-fetched-for group t) + (gnus-agent-save-alist group articles nil) + articles) + (ignore-errors + (erase-buffer) + (nnheader-insert-file-contents file))))) + articles)) (defsubst gnus-agent-read-article-number () "Read the article number at point. @@ -1938,6 +1924,96 @@ Return nil when a valid article number can not be read." (set-buffer nntp-server-buffer) (insert-buffer-substring gnus-agent-overview-buffer b e)))) +(defun gnus-agent-braid-nov (articles file) + "Merge agent overview data with given file. +Takes unvalidated headers for ARTICLES from +`gnus-agent-overview-buffer' and validated headers from the given +FILE and places the combined valid headers into +`nntp-server-buffer'. This function can be used, when file +doesn't exist, to valid the overview buffer." + (let (start last) + (set-buffer gnus-agent-overview-buffer) + (goto-char (point-min)) + (set-buffer nntp-server-buffer) + (erase-buffer) + (when (file-exists-p file) + (nnheader-insert-file-contents file)) + (goto-char (point-max)) + (forward-line -1) + + (unless (or (= (point-min) (point-max)) + (< (setq last (read (current-buffer))) (car articles))) + ;; Old and new overlap -- We do it the hard way. + (when (nnheader-find-nov-line (car articles)) + ;; Replacing existing NOV entry + (delete-region (point) (progn (forward-line 1) (point)))) + (gnus-agent-copy-nov-line (pop articles)) + + (ignore-errors + (while articles + (while (let ((art (read (current-buffer)))) + (cond ((< art (car articles)) + (forward-line 1) + t) + ((= art (car articles)) + (beginning-of-line) + (delete-region + (point) (progn (forward-line 1) (point))) + nil) + (t + (beginning-of-line) + nil)))) + + (gnus-agent-copy-nov-line (pop articles))))) + + (goto-char (point-max)) + + ;; Append the remaining lines + (when articles + (when last + (set-buffer gnus-agent-overview-buffer) + (setq start (point)) + (set-buffer nntp-server-buffer)) + + (let ((p (point))) + (insert-buffer-substring gnus-agent-overview-buffer start) + (goto-char p)) + + (setq last (or last -134217728)) + (while (catch 'problems + (let (sort art) + (while (not (eobp)) + (setq art (gnus-agent-read-article-number)) + (cond ((not art) + ;; Bad art num - delete this line + (beginning-of-line) + (delete-region (point) (progn (forward-line 1) (point)))) + ((< art last) + ;; Art num out of order - enable sort + (setq sort t) + (forward-line 1)) + ((= art last) + ;; Bad repeat of art number - delete this line + (beginning-of-line) + (delete-region (point) (progn (forward-line 1) (point)))) + (t + ;; Good art num + (setq last art) + (forward-line 1)))) + (when sort + ;; something is seriously wrong as we simply shouldn't see out-of-order data. + ;; First, we'll fix the sort. + (sort-numeric-fields 1 (point-min) (point-max)) + + ;; but now we have to consider that we may have duplicate rows... + ;; so reset to beginning of file + (goto-char (point-min)) + (setq last -134217728) + + ;; and throw a code that restarts this scan + (throw 'problems t)) + nil)))))) + ;; Keeps the compiler from warning about the free variable in ;; gnus-agent-read-agentview. (defvar gnus-agent-read-agentview) @@ -2310,9 +2386,10 @@ modified) original contents, they are first saved to their own file." (gnus-orphan-score gnus-orphan-score) ;; Maybe some other gnus-summary local variables should also ;; be put here. - fetched-headers + gnus-headers gnus-score + articles predicate info marks ) (unless (gnus-check-group group) @@ -2333,35 +2410,38 @@ modified) original contents, they are first saved to their own file." (setq info (gnus-get-info group))))))) (when arts (setq marked-articles (nconc (gnus-uncompress-range arts) - marked-articles)))))) + marked-articles)) + )))) (setq marked-articles (sort marked-articles '<)) - (setq gnus-newsgroup-dependencies - (or gnus-newsgroup-dependencies - (gnus-make-hashtable))) + ;; Fetch any new articles from the server + (setq articles (gnus-agent-fetch-headers group)) - ;; Fetch headers for any new articles from the server. - (setq fetched-headers (gnus-agent-fetch-headers group)) + ;; Merge new articles with marked + (setq articles (sort (append marked-articles articles) '<)) - (when fetched-headers + (when articles + ;; Parse them and see which articles we want to fetch. + (setq gnus-newsgroup-dependencies + (or gnus-newsgroup-dependencies + (gnus-make-hashtable (length articles)))) (setq gnus-newsgroup-headers - (or gnus-newsgroup-headers - fetched-headers))) - (when marked-articles - ;; `gnus-agent-overview-buffer' may be killed for timeout - ;; reason. If so, recreate it. + (or gnus-newsgroup-headers + (gnus-get-newsgroup-headers-xover articles nil nil + group))) + ;; `gnus-agent-overview-buffer' may be killed for + ;; timeout reason. If so, recreate it. (gnus-agent-create-buffer) (setq predicate - (gnus-get-predicate - (gnus-agent-find-parameter group 'agent-predicate))) - - ;; If the selection predicate requires scoring, score each header. + (gnus-get-predicate + (gnus-agent-find-parameter group 'agent-predicate))) + ;; If the selection predicate requires scoring, score each header (unless (memq predicate '(gnus-agent-true gnus-agent-false)) (let ((score-param (gnus-agent-find-parameter group 'agent-score-file))) - ;; Translate score-param into real one. + ;; Translate score-param into real one (cond ((not score-param)) ((eq score-param 'file) @@ -3581,9 +3661,11 @@ has been fetched." (defun gnus-agent-retrieve-headers (articles group &optional fetch-old) (save-excursion (gnus-agent-create-buffer) - (let ((file (gnus-agent-article-name ".overview" group)) - (file-name-coding-system nnmail-pathname-coding-system) - uncached-articles headers fetched-headers) + (let ((gnus-decode-encoded-word-function 'identity) + (gnus-decode-encoded-address-function 'identity) + (file (gnus-agent-article-name ".overview" group)) + uncached-articles + (file-name-coding-system nnmail-pathname-coding-system)) (gnus-make-directory (nnheader-translate-file-chars (file-name-directory file) t)) @@ -3594,63 +3676,122 @@ has been fetched." 1) (car (last articles)))))) - ;; See if we've got cached headers for ARTICLES and put them in - ;; HEADERS. Articles with no cached headers go in - ;; UNCACHED-ARTICLES to be fetched from the server. + ;; Populate temp buffer with known headers (when (file-exists-p file) (with-current-buffer gnus-agent-overview-buffer (erase-buffer) (let ((nnheader-file-coding-system gnus-agent-file-coding-system)) - (nnheader-insert-nov-file file (car articles)) - (with-current-buffer nntp-server-buffer - (erase-buffer) - (insert-buffer-substring gnus-agent-overview-buffer) - (setq headers - (gnus-get-newsgroup-headers-xover - articles nil (buffer-local-value - 'gnus-newsgroup-dependencies - gnus-summary-buffer) - gnus-newsgroup-name)))))) - - (setq uncached-articles - (gnus-agent-uncached-articles articles group t)) - - (when uncached-articles - (let ((gnus-newsgroup-name group) - gnus-agent) ; Prevent loop. - ;; Fetch additional headers for the uncached articles. - (setq fetched-headers (gnus-fetch-headers uncached-articles)) - ;; Merge headers we got from the overview file with our - ;; newly-fetched headers. - (when fetched-headers - (setq headers - (delete-dups - (sort (append headers (copy-sequence fetched-headers)) - (lambda (l r) - (< (mail-header-number l) - (mail-header-number r)))))) - - ;; Add the new set of known headers to the overview file. + (nnheader-insert-nov-file file (car articles))))) + + (if (setq uncached-articles (gnus-agent-uncached-articles articles group + t)) + (progn + ;; Populate nntp-server-buffer with uncached headers + (set-buffer nntp-server-buffer) + (erase-buffer) + (cond ((not (eq 'nov (let (gnus-agent) ; Turn off agent + (gnus-retrieve-headers + uncached-articles group)))) + (nnvirtual-convert-headers)) + ((eq 'nntp (car gnus-current-select-method)) + ;; The author of gnus-get-newsgroup-headers-xover + ;; reports that the XOVER command is commonly + ;; unreliable. The problem is that recently + ;; posted articles may not be entered into the + ;; NOV database in time to respond to my XOVER + ;; query. + ;; + ;; I'm going to use his assumption that the NOV + ;; database is updated in order of ascending + ;; article ID. Therefore, a response containing + ;; article ID N implies that all articles from 1 + ;; to N-1 are up-to-date. Therefore, missing + ;; articles in that range have expired. + + (set-buffer nntp-server-buffer) + (let* ((fetched-articles (list nil)) + (tail-fetched-articles fetched-articles) + (min (car articles)) + (max (car (last articles)))) + + ;; Get the list of articles that were fetched + (goto-char (point-min)) + (let ((pm (point-max)) + art) + (while (< (point) pm) + (when (setq art (gnus-agent-read-article-number)) + (gnus-agent-append-to-list tail-fetched-articles art)) + (forward-line 1))) + + ;; Clip this list to the headers that will + ;; actually be returned + (setq fetched-articles (gnus-list-range-intersection + (cdr fetched-articles) + (cons min max))) + + ;; Clip the uncached articles list to exclude + ;; IDs after the last FETCHED header. The + ;; excluded IDs may be fetchable using HEAD. + (if (car tail-fetched-articles) + (setq uncached-articles + (gnus-list-range-intersection + uncached-articles + (cons (car uncached-articles) + (car tail-fetched-articles))))) + + ;; Create the list of articles that were + ;; "successfully" fetched. Success, in this + ;; case, means that the ID should not be + ;; fetched again. In the case of an expired + ;; article, the header will not be fetched. + (setq uncached-articles + (gnus-sorted-nunion fetched-articles + uncached-articles)) + ))) + + ;; Erase the temp buffer + (set-buffer gnus-agent-overview-buffer) + (erase-buffer) + + ;; Copy the nntp-server-buffer to the temp buffer + (set-buffer nntp-server-buffer) + (copy-to-buffer gnus-agent-overview-buffer (point-min) (point-max)) + + ;; Merge the temp buffer with the known headers (found on + ;; disk in FILE) into the nntp-server-buffer + (when uncached-articles + (gnus-agent-braid-nov uncached-articles file)) + + ;; Save the new set of known headers to FILE + (set-buffer nntp-server-buffer) (let ((coding-system-for-write gnus-agent-file-coding-system)) - (with-current-buffer gnus-agent-overview-buffer - ;; We stick the new headers in at the end, then - ;; re-sort the whole buffer with - ;; `sort-numeric-fields'. If this turns out to be - ;; slow, we could consider a loop to add the headers - ;; in sorted order to begin with. - (goto-char (point-max)) - (mapc #'nnheader-insert-nov fetched-headers) - (sort-numeric-fields 1 (point-min) (point-max)) - (gnus-agent-check-overview-buffer) - (write-region (point-min) (point-max) file nil 'silent) - (gnus-agent-update-view-total-fetched-for group t) - ;; Update the group's article alist to include the - ;; newly fetched articles. - (gnus-agent-load-alist group) - (gnus-agent-save-alist group uncached-articles nil)))))) - headers))) + (gnus-agent-check-overview-buffer) + (write-region (point-min) (point-max) file nil 'silent)) + + (gnus-agent-update-view-total-fetched-for group t) + + ;; Update the group's article alist to include the newly + ;; fetched articles. + (gnus-agent-load-alist group) + (gnus-agent-save-alist group uncached-articles nil) + ) + + ;; Copy the temp buffer to the nntp-server-buffer + (set-buffer nntp-server-buffer) + (erase-buffer) + (insert-buffer-substring gnus-agent-overview-buffer))) + + (if (and fetch-old + (not (numberp fetch-old))) + t ; Don't remove anything. + (nnheader-nov-delete-outside-range + (car articles) + (car (last articles))) + t) + + 'nov)) (defun gnus-agent-request-article (article group) "Retrieve ARTICLE in GROUP from the agent cache." diff --git a/lisp/gnus/gnus-async.el b/lisp/gnus/gnus-async.el index ed948a26c0..fefd02c7bf 100644 --- a/lisp/gnus/gnus-async.el +++ b/lisp/gnus/gnus-async.el @@ -357,13 +357,8 @@ that was fetched." (let ((nntp-server-buffer (current-buffer)) (nnheader-callback-function (lambda (_arg) - (setq gnus-async-header-prefetched - (cons group unread))))) - ;; FIXME: If header prefetch is ever put into use, we'll - ;; have to handle the possibility that - ;; `gnus-retrieve-headers' might return a list of header - ;; vectors directly, rather than writing them into the - ;; current buffer. + (setq gnus-async-header-prefetched + (cons group unread))))) (gnus-retrieve-headers unread group gnus-fetch-old-headers)))))) (defun gnus-async-retrieve-fetched-headers (articles group) diff --git a/lisp/gnus/gnus-cache.el b/lisp/gnus/gnus-cache.el index 9423d9f2f6..36657e4621 100644 --- a/lisp/gnus/gnus-cache.el +++ b/lisp/gnus/gnus-cache.el @@ -294,47 +294,49 @@ it's not cached." (defun gnus-cache-retrieve-headers (articles group &optional fetch-old) "Retrieve the headers for ARTICLES in GROUP." (let ((cached - (setq gnus-newsgroup-cached (gnus-cache-articles-in-group group))) - (gnus-newsgroup-name group) - (gnus-fetch-old-headers fetch-old)) + (setq gnus-newsgroup-cached (gnus-cache-articles-in-group group)))) (if (not cached) ;; No cached articles here, so we just retrieve them ;; the normal way. (let ((gnus-use-cache nil)) - (gnus-retrieve-headers articles group)) + (gnus-retrieve-headers articles group fetch-old)) (let ((uncached-articles (gnus-sorted-difference articles cached)) (cache-file (gnus-cache-file-name group ".overview")) - (file-name-coding-system nnmail-pathname-coding-system) - headers) + type + (file-name-coding-system nnmail-pathname-coding-system)) ;; We first retrieve all the headers that we don't have in ;; the cache. (let ((gnus-use-cache nil)) (when uncached-articles - (setq headers (and articles - (gnus-fetch-headers uncached-articles))))) + (setq type (and articles + (gnus-retrieve-headers + uncached-articles group fetch-old))))) (gnus-cache-save-buffers) - ;; Then we include the cached headers. - (when (file-exists-p cache-file) - (setq headers - (delete-dups - (sort - (append headers - (let ((coding-system-for-read - gnus-cache-overview-coding-system)) - (with-current-buffer nntp-server-buffer - (erase-buffer) - (insert-file-contents cache-file) - (gnus-get-newsgroup-headers-xover - (gnus-sorted-difference - cached uncached-articles) - nil (buffer-local-value - 'gnus-newsgroup-dependencies - gnus-summary-buffer) - group)))) - (lambda (l r) - (< (mail-header-number l) - (mail-header-number r))))))) - headers)))) + ;; Then we insert the cached headers. + (save-excursion + (cond + ((not (file-exists-p cache-file)) + ;; There are no cached headers. + type) + ((null type) + ;; There were no uncached headers (or retrieval was + ;; unsuccessful), so we use the cached headers exclusively. + (set-buffer nntp-server-buffer) + (erase-buffer) + (let ((coding-system-for-read + gnus-cache-overview-coding-system)) + (insert-file-contents cache-file)) + 'nov) + ((eq type 'nov) + ;; We have both cached and uncached NOV headers, so we + ;; braid them. + (gnus-cache-braid-nov group cached) + type) + (t + ;; We braid HEADs. + (gnus-cache-braid-heads group (gnus-sorted-intersection + cached articles)) + type))))))) (defun gnus-cache-enter-article (&optional n) "Enter the next N articles into the cache. @@ -527,6 +529,70 @@ Returns the list of articles removed." (setq gnus-cache-active-altered t))) articles))) +(defun gnus-cache-braid-nov (group cached &optional file) + (let ((cache-buf (gnus-get-buffer-create " *gnus-cache*")) + beg end) + (gnus-cache-save-buffers) + (with-current-buffer cache-buf + (erase-buffer) + (let ((coding-system-for-read gnus-cache-overview-coding-system) + (file-name-coding-system nnmail-pathname-coding-system)) + (insert-file-contents + (or file (gnus-cache-file-name group ".overview")))) + (goto-char (point-min)) + (insert "\n") + (goto-char (point-min))) + (set-buffer nntp-server-buffer) + (goto-char (point-min)) + (while cached + (while (and (not (eobp)) + (< (read (current-buffer)) (car cached))) + (forward-line 1)) + (beginning-of-line) + (set-buffer cache-buf) + (if (search-forward (concat "\n" (int-to-string (car cached)) "\t") + nil t) + (setq beg (point-at-bol) + end (progn (end-of-line) (point))) + (setq beg nil)) + (set-buffer nntp-server-buffer) + (when beg + (insert-buffer-substring cache-buf beg end) + (insert "\n")) + (setq cached (cdr cached))) + (kill-buffer cache-buf))) + +(defun gnus-cache-braid-heads (group cached) + (let ((cache-buf (gnus-get-buffer-create " *gnus-cache*"))) + (with-current-buffer cache-buf + (erase-buffer)) + (set-buffer nntp-server-buffer) + (goto-char (point-min)) + (dolist (entry cached) + (while (and (not (eobp)) + (looking-at "2.. +\\([0-9]+\\) ") + (< (progn (goto-char (match-beginning 1)) + (read (current-buffer))) + entry)) + (search-forward "\n.\n" nil 'move)) + (beginning-of-line) + (set-buffer cache-buf) + (erase-buffer) + (let ((coding-system-for-read gnus-cache-coding-system) + (file-name-coding-system nnmail-pathname-coding-system)) + (insert-file-contents (gnus-cache-file-name group entry))) + (goto-char (point-min)) + (insert "220 ") + (princ (pop cached) (current-buffer)) + (insert " Article retrieved.\n") + (search-forward "\n\n" nil 'move) + (delete-region (point) (point-max)) + (forward-char -1) + (insert ".") + (set-buffer nntp-server-buffer) + (insert-buffer-substring cache-buf)) + (kill-buffer cache-buf))) + ;;;###autoload (defun gnus-jog-cache () "Go through all groups and put the articles into the cache. diff --git a/lisp/gnus/gnus-cloud.el b/lisp/gnus/gnus-cloud.el index 00b85f546c..f7c71f43ce 100644 --- a/lisp/gnus/gnus-cloud.el +++ b/lisp/gnus/gnus-cloud.el @@ -30,8 +30,6 @@ (require 'parse-time) (require 'nnimap) -(declare-function gnus-fetch-headers "gnus-sum") -(defvar gnus-alter-header-function) (eval-when-compile (require 'epg)) ;; setf-method for `epg-context-armor' (autoload 'epg-make-context "epg") @@ -393,6 +391,8 @@ When FULL is t, upload everything, not just a difference from the last full." (gnus-group-refresh-group group)) (gnus-error 2 "Failed to upload Gnus Cloud data to %s" group))))) +(defvar gnus-alter-header-function) + (defun gnus-cloud-add-timestamps (elems) (dolist (elem elems) (let* ((file-name (plist-get elem :file-name)) @@ -407,10 +407,14 @@ When FULL is t, upload everything, not just a difference from the last full." (gnus-activate-group gnus-cloud-group-name nil nil gnus-cloud-method) (let* ((group (gnus-group-full-name gnus-cloud-group-name gnus-cloud-method)) (active (gnus-active group)) - (gnus-newsgroup-name group) - (headers (gnus-fetch-headers (gnus-uncompress-range active)))) - (when gnus-alter-header-function - (mapc gnus-alter-header-function headers)) + headers head) + (when (gnus-retrieve-headers (gnus-uncompress-range active) group) + (with-current-buffer nntp-server-buffer + (goto-char (point-min)) + (while (setq head (nnheader-parse-head)) + (when gnus-alter-header-function + (funcall gnus-alter-header-function head)) + (push head headers)))) (sort (nreverse headers) (lambda (h1 h2) (> (gnus-cloud-chunk-sequence (mail-header-subject h1)) diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index 5bd58b690a..b0f9ed4c6f 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -5658,21 +5658,10 @@ or a straight list of headers." (setf (mail-header-subject header) subject)))))) (defun gnus-fetch-headers (articles &optional limit force-new dependencies) - "Fetch headers of ARTICLES. -This calls the `gnus-retrieve-headers' function of the current -group's backend server. The server can do one of two things: - -1. Write the headers for ARTICLES into the - `nntp-server-buffer' (the current buffer) in a parseable format, or -2. Return the headers directly as a list of vectors. - -In the first case, `gnus-retrieve-headers' returns a symbol -value, either `nov' or `headers'. This value determines which -parsing function is used to read the headers. It is also stored -into the variable `gnus-headers-retrieved-by', which is consulted -later when possibly building full threads." + "Fetch headers of ARTICLES." (gnus-message 7 "Fetching headers for %s..." gnus-newsgroup-name) - (let ((res (setq gnus-headers-retrieved-by + (prog1 + (pcase (setq gnus-headers-retrieved-by (gnus-retrieve-headers articles gnus-newsgroup-name (or limit @@ -5682,34 +5671,22 @@ later when possibly building full threads." (not (eq gnus-fetch-old-headers 'some)) (not (numberp gnus-fetch-old-headers))) (> (length articles) 1)) - gnus-fetch-old-headers)))))) - (prog1 - (pcase res - ('nov - (gnus-get-newsgroup-headers-xover - articles force-new dependencies gnus-newsgroup-name t)) - ;; For now, assume that any backend returning its own - ;; headers takes some effort to do so, so return `headers'. - ((pred listp) - (setq gnus-headers-retrieved-by 'headers) - (let ((dependencies - (or dependencies - (buffer-local-value - 'gnus-newsgroup-dependencies gnus-summary-buffer)))) - (when (functionp gnus-alter-header-function) - (mapc gnus-alter-header-function res)) - (mapc (lambda (header) - ;; The agent or the cache may have already - ;; registered this header in the dependency - ;; table. - (unless (gethash (mail-header-id header) dependencies) - (gnus-dependencies-add-header - header dependencies force-new))) - res) - res)) - (_ (gnus-get-newsgroup-headers dependencies force-new))) - (gnus-message 7 "Fetching headers for %s...done" - gnus-newsgroup-name)))) + gnus-fetch-old-headers)))) + ('nov + (gnus-get-newsgroup-headers-xover + articles force-new dependencies gnus-newsgroup-name t)) + ('headers + (gnus-get-newsgroup-headers dependencies force-new)) + ((pred listp) + (let ((dependencies + (or dependencies + (with-current-buffer gnus-summary-buffer + gnus-newsgroup-dependencies)))) + (delq nil (mapcar #'(lambda (header) + (gnus-dependencies-add-header + header dependencies force-new)) + gnus-headers-retrieved-by))))) + (gnus-message 7 "Fetching headers for %s...done" gnus-newsgroup-name))) (defun gnus-select-newsgroup (group &optional read-all select-articles) "Select newsgroup GROUP. @@ -6466,10 +6443,6 @@ The resulting hash table is returned, or nil if no Xrefs were found." (unless (gnus-ephemeral-group-p group) (gnus-group-update-group group t)))))) -;; FIXME: Refactor this with `gnus-get-newsgroup-headers-xover' and -;; extract the necessary bits for the direct-header-return case. Also -;; look at this and see how similar it is to -;; `nnheader-parse-naked-head'. (defun gnus-get-newsgroup-headers (&optional dependencies force-new) (let ((dependencies (or dependencies diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index 2e9ee7189d..3b172db211 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el @@ -2388,14 +2388,7 @@ Typical marks are those that make no sense in a standalone back end, such as a mark that says whether an article is stored in the cache \(which doesn't make sense in a standalone back end).") -(defvar gnus-headers-retrieved-by nil - "Holds the return value of `gnus-retrieve-headers'. -This is either the symbol `nov' or the symbol `headers'. This -value is checked during the summary creation process, when -building threads. A value of `nov' indicates that header -retrieval is relatively cheap and threading is encouraged to -include more old articles. A value of `headers' indicates that -retrieval is expensive and should be minimized.") +(defvar gnus-headers-retrieved-by nil) (defvar gnus-article-reply nil) (defvar gnus-override-method nil) (defvar gnus-opened-servers nil) diff --git a/lisp/gnus/nnvirtual.el b/lisp/gnus/nnvirtual.el index ba2934351d..1e2feda636 100644 --- a/lisp/gnus/nnvirtual.el +++ b/lisp/gnus/nnvirtual.el @@ -101,10 +101,15 @@ It is computed from the marks of individual component groups.") (erase-buffer) (if (stringp (car articles)) 'headers - (let ((carticles (nnvirtual-partition-sequence articles)) + (let ((vbuf (nnheader-set-temp-buffer + (gnus-get-buffer-create " *virtual headers*"))) + (carticles (nnvirtual-partition-sequence articles)) (sysname (system-name)) - cgroup headers all-headers article prefix) - (pcase-dolist (`(,cgroup . ,articles) carticles) + cgroup carticle article result prefix) + (while carticles + (setq cgroup (caar carticles)) + (setq articles (cdar carticles)) + (pop carticles) (when (and articles (gnus-check-server (gnus-find-method-for-group cgroup) t) @@ -114,37 +119,69 @@ It is computed from the marks of individual component groups.") ;; This is probably evil if people have set ;; gnus-use-cache to nil themselves, but I ;; have no way of finding the true value of it. - (let ((gnus-use-cache t) - (gnus-newsgroup-name cgroup) - (gnus-fetch-old-headers nil)) - (setq headers (gnus-fetch-headers articles)))) - (erase-buffer) - ;; Remove all header article numbers from `articles'. - ;; If there's anything left, those are expired or - ;; canceled articles, so we update the component group - ;; below. - (dolist (h headers) - (setq articles (delq (mail-header-number h) articles) - article (nnvirtual-reverse-map-article - cgroup (mail-header-number h))) - ;; Update all the header numbers according to their - ;; reverse mapping, and drop any with no such mapping. - (when article - ;; Do this first, before we re-set the header's - ;; article number. - (nnvirtual-update-xref-header - h cgroup prefix sysname) - (setf (mail-header-number h) article) - (push h all-headers))) - ;; Anything left in articles is expired or canceled. - ;; Could be smart and not tell it about articles already - ;; known? - (when articles - (gnus-group-make-articles-read cgroup articles)))) - - (sort all-headers (lambda (h1 h2) - (< (mail-header-number h1) - (mail-header-number h2))))))))) + (let ((gnus-use-cache t)) + (setq result (gnus-retrieve-headers + articles cgroup nil)))) + (set-buffer nntp-server-buffer) + ;; If we got HEAD headers, we convert them into NOV + ;; headers. This is slow, inefficient and, come to think + ;; of it, downright evil. So sue me. I couldn't be + ;; bothered to write a header parse routine that could + ;; parse a mixed HEAD/NOV buffer. + (when (eq result 'headers) + (nnvirtual-convert-headers)) + (goto-char (point-min)) + (while (not (eobp)) + (delete-region (point) + (progn + (setq carticle (read nntp-server-buffer)) + (point))) + + ;; We remove this article from the articles list, if + ;; anything is left in the articles list after going through + ;; the entire buffer, then those articles have been + ;; expired or canceled, so we appropriately update the + ;; component group below. They should be coming up + ;; generally in order, so this shouldn't be slow. + (setq articles (delq carticle articles)) + + (setq article (nnvirtual-reverse-map-article cgroup carticle)) + (if (null article) + ;; This line has no reverse mapping, that means it + ;; was an extra article reference returned by nntp. + (progn + (beginning-of-line) + (delete-region (point) (progn (forward-line 1) (point)))) + ;; Otherwise insert the virtual article number, + ;; and clean up the xrefs. + (princ article nntp-server-buffer) + (nnvirtual-update-xref-header cgroup carticle + prefix sysname) + (forward-line 1)) + ) + + (set-buffer vbuf) + (goto-char (point-max)) + (insert-buffer-substring nntp-server-buffer)) + ;; Anything left in articles is expired or canceled. + ;; Could be smart and not tell it about articles already known? + (when articles + (gnus-group-make-articles-read cgroup articles)) + ) + + ;; The headers are ready for reading, so they are inserted into + ;; the nntp-server-buffer, which is where Gnus expects to find + ;; them. + (prog1 + (with-current-buffer nntp-server-buffer + (erase-buffer) + (insert-buffer-substring vbuf) + ;; FIX FIX FIX, we should be able to sort faster than + ;; this if needed, since each cgroup is sorted, we just + ;; need to merge + (sort-numeric-fields 1 (point-min) (point-max)) + 'nov) + (kill-buffer vbuf))))))) (defvoo nnvirtual-last-accessed-component-group nil) @@ -335,18 +372,61 @@ It is computed from the marks of individual component groups.") ;;; Internal functions. -(defun nnvirtual-update-xref-header (header group prefix sysname) - "Add xref to component GROUP to HEADER. -Also add a server PREFIX any existing xref lines." - (let ((bits (split-string (mail-header-xref header) - nil t "[[:blank:]]")) - (art-no (mail-header-number header))) - (setf (mail-header-xref header) - (concat - (format "%s %s:%d " sysname group art-no) - (mapconcat (lambda (bit) - (concat prefix bit)) - bits " "))))) +(defun nnvirtual-convert-headers () + "Convert HEAD headers into NOV headers." + (with-current-buffer nntp-server-buffer + (let* ((dependencies (make-hash-table :test #'equal)) + (headers (gnus-get-newsgroup-headers dependencies))) + (erase-buffer) + (mapc 'nnheader-insert-nov headers)))) + + +(defun nnvirtual-update-xref-header (group article prefix sysname) + "Edit current NOV header in current buffer to have an xref to the component group, and also server prefix any existing xref lines." + ;; Move to beginning of Xref field, creating a slot if needed. + (beginning-of-line) + (looking-at + "[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t") + (goto-char (match-end 0)) + (unless (search-forward "\t" (point-at-eol) 'move) + (insert "\t")) + + ;; Remove any spaces at the beginning of the Xref field. + (while (eq (char-after (1- (point))) ? ) + (forward-char -1) + (delete-char 1)) + + (insert "Xref: " sysname " " group ":") + (princ article (current-buffer)) + (insert " ") + + ;; If there were existing xref lines, clean them up to have the correct + ;; component server prefix. + (save-restriction + (narrow-to-region (point) + (or (search-forward "\t" (point-at-eol) t) + (point-at-eol))) + (goto-char (point-min)) + (when (re-search-forward "Xref: *[^\n:0-9 ]+ *" nil t) + (replace-match "" t t)) + (goto-char (point-min)) + (when (re-search-forward + (concat (regexp-quote (gnus-group-real-name group)) ":[0-9]+") + nil t) + (replace-match "" t t)) + (unless (eobp) + (insert " ") + (when (not (string= "" prefix)) + (while (re-search-forward "[^ ]+:[0-9]+" nil t) + (save-excursion + (goto-char (match-beginning 0)) + (insert prefix)))))) + + ;; Ensure a trailing \t. + (end-of-line) + (or (eq (char-after (1- (point))) ?\t) + (insert ?\t))) + (defun nnvirtual-possibly-change-server (server) (or (not server) diff --git a/lisp/obsolete/nnir.el b/lisp/obsolete/nnir.el index 0b7d1e454c..147efed005 100644 --- a/lisp/obsolete/nnir.el +++ b/lisp/obsolete/nnir.el @@ -504,6 +504,7 @@ Add an entry here when adding a new search engine.") ,@(mapcar (lambda (elem) (list 'const (car elem))) nnir-engines))))) + (defmacro nnir-add-result (dirnam artno score prefix server artlist) "Construct a result vector and add it to ARTLIST. DIRNAM, ARTNO, SCORE, PREFIX and SERVER are passed to commit 3131a989118722d5ba7ff3f1aea7d9f30881ffe8 Author: Eli Zaretskii Date: Tue Jan 26 18:24:53 2021 +0200 Fix typos and punctuation * src/w32fns.c: * src/frame.h: * doc/lispref/frames.texi (Frame Layout): * etc/NEWS: Fix typos and punctuation in recent changes. diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index ef1b661b2a..19c80fad53 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -694,16 +694,16 @@ parameter (@pxref{Management Parameters}). @item Internal Border The internal border is a border drawn by Emacs around the inner frame -(see below). The specification of its appearance depends on whether -the given frame is a child frame (@pxref{Child Frames}) or not. +(see below). The specification of its appearance depends on whether +or not the given frame is a child frame (@pxref{Child Frames}). For normal frames its width is specified by the @code{internal-border-width} -frame parameter (@pxref{Layout Parameters}) and its color is specified by the +frame parameter (@pxref{Layout Parameters}), and its color is specified by the background of the @code{internal-border} face. For child frames its width is specified by the @code{child-frame-border-width} -frame parameter (but will use the the @code{internal-border-width} parameter as -a fallback) and its color is specified by the background of the +frame parameter (but will use the @code{internal-border-width} parameter as +fallback), and its color is specified by the background of the @code{child-frame-border} face. @item Inner Frame diff --git a/etc/NEWS b/etc/NEWS index 1d4d6af00e..e038076e96 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2019,12 +2019,12 @@ hooks 'kill-buffer-hook', 'kill-buffer-query-functions', and avoids slowing them down when a lot of these hooks are defined. ** New face 'child-frame-border' and frame parameter 'child-frame-border-width'. -The face and width of child frames borders can no be determined -separately from thos of normal frames. To minimize backwards +The face and width of child frames borders can now be determined +separately from those of normal frames. To minimize backward incompatibility, child frames without a 'child-frame-border-width' -parameter will fall back to using 'internal-border-width'. However the -new 'child-frame-border' face does constitute a breaking change since -child frames' borders no longer use the 'internal-border' face. +parameter will fall back to using 'internal-border-width'. However, +the new 'child-frame-border' face does constitute a breaking change +since child frames' borders no longer use the 'internal-border' face. --- ** The obsolete function 'thread-alive-p' has been removed. diff --git a/src/frame.h b/src/frame.h index 4bd01243f6..9b0852c7b9 100644 --- a/src/frame.h +++ b/src/frame.h @@ -534,7 +534,7 @@ struct frame /* Border width of the frame window as known by the (X) window system. */ int border_width; - /* Width of child frames' internal border. Acts as + /* Width of child frames' internal border. Acts as internal_border_width for child frames. */ int child_frame_border_width; @@ -1443,7 +1443,7 @@ FRAME_CHILD_FRAME_BORDER_WIDTH (struct frame *f) } /* Pixel-width of internal border. Uses child_frame_border_width for - child frames if possible and falls back on internal_border_width + child frames if possible, and falls back on internal_border_width otherwise. */ INLINE int FRAME_INTERNAL_BORDER_WIDTH (struct frame *f) diff --git a/src/w32fns.c b/src/w32fns.c index 29d2e3d75f..7519c752b6 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -1556,7 +1556,7 @@ w32_clear_under_internal_border (struct frame *f) * w32_set_child_frame_border_width: * * Set width of child frame F's internal border to ARG pixels. - * ARG < 0 is * treated like ARG = 0. + * ARG < 0 is treated like ARG = 0. */ static void w32_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) commit 3c314f3dd23257d574644563665ade9497d86b70 Author: Martin Rudalics Date: Tue Jan 26 10:59:59 2021 +0100 Fix typo in last change of FRAME_INTERNAL_BORDER_WIDTH * src/frame.h (FRAME_INTERNAL_BORDER_WIDTH): Fix typo in last change. diff --git a/src/frame.h b/src/frame.h index 7b3bf20a24..4bd01243f6 100644 --- a/src/frame.h +++ b/src/frame.h @@ -1455,7 +1455,7 @@ FRAME_INTERNAL_BORDER_WIDTH (struct frame *f) : frame_dimension (f->internal_border_width)) : frame_dimension (f->internal_border_width); #else - return frame_dimension (f->internal_border_width) + return frame_dimension (f->internal_border_width); #endif } commit ff7b1a133bfa7f2614650f8551824ffaef13fadc Author: Alexander Miller Date: Tue Jan 26 10:36:52 2021 +0100 Add distinct controls for child frames' borders (Bug#45620) The background of the 'child-frame-border' face instead of the 'internal-border' face now controls the color of child frames' borders. The 'child-frame-border-width' frame parameter is now used for the width of child frames' borders instead of internal-border-width', though we still fall back on using the latter if the former is not set. * doc/lispref/frames.texi (Frame Layout): Mention 'child-frame-border' and 'child-frame-border-width'. (Layout Parameters): Mention 'child-frame-border-width'. * etc/NEWS: Mention new face 'child-frame-border' and frame parameter 'child-frame-border-width'. * lisp/faces.el (child-frame-border): New face. * src/dispextern.h (enum face_id): Add CHILD_FRAME_BORDER_FACE_ID. * src/frame.c (Fframe_child_frame_border_width): New function. (gui_report_frame_params): Add entry for Qchild_frame_border_width. * src/frame.h (struct frame): New slot child_frame_border_width. (FRAME_CHILD_FRAME_BORDER_WIDTH): New inlined function. * src/nsfns.m (ns_set_child_frame_border_width): New function. (Fx_create_frame): Handle Qchild_frame_border_width parameter. (ns_frame_parm_handlers): Add ns_set_child_frame_border_width. * src/nsterm.m (ns_clear_under_internal_border): Handle CHILD_FRAME_BORDER_FACE_ID. * src/w32fns.c (w32_clear_under_internal_border): Handle CHILD_FRAME_BORDER_FACE_ID. (w32_set_internal_border_width): New function. (Fx_create_frame): Handle Qchild_frame_border_width parameter. (w32_frame_parm_handlers): Add w32_set_child_frame_border_width. * src/xfaces.c (lookup_basic_face, realize_basic_faces): Handle CHILD_FRAME_BORDER_FACE_ID. * src/xfns.c (x_set_child_frame_border_width): New function. (Fx_create_frame): Handle Qchild_frame_border_width parameter. (x_frame_parm_handlers): Add x_set_child_frame_border_width. * src/xterm.c (x_clear_under_internal_border) (x_after_update_window_line): Handle CHILD_FRAME_BORDER_FACE_ID. diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 7f2a6f7542..ef1b661b2a 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -694,9 +694,17 @@ parameter (@pxref{Management Parameters}). @item Internal Border The internal border is a border drawn by Emacs around the inner frame -(see below). Its width is specified by the @code{internal-border-width} -frame parameter (@pxref{Layout Parameters}). Its color is specified by -the background of the @code{internal-border} face. +(see below). The specification of its appearance depends on whether +the given frame is a child frame (@pxref{Child Frames}) or not. + +For normal frames its width is specified by the @code{internal-border-width} +frame parameter (@pxref{Layout Parameters}) and its color is specified by the +background of the @code{internal-border} face. + +For child frames its width is specified by the @code{child-frame-border-width} +frame parameter (but will use the the @code{internal-border-width} parameter as +a fallback) and its color is specified by the background of the +@code{child-frame-border} face. @item Inner Frame @cindex inner frame @@ -1790,6 +1798,11 @@ The width in pixels of the frame's outer border (@pxref{Frame Geometry}). The width in pixels of the frame's internal border (@pxref{Frame Geometry}). +@vindex child-frame-border-width@r{, a frame parameter} +@item child-frame-border-width +The width in pixels of the frame's internal border (@pxref{Frame +Geometry}) if the given frame is a child frame (@pxref{Child Frames}). + @vindex vertical-scroll-bars@r{, a frame parameter} @item vertical-scroll-bars Whether the frame has scroll bars (@pxref{Scroll Bars}) for vertical diff --git a/etc/NEWS b/etc/NEWS index b815d3ac61..1d4d6af00e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2018,6 +2018,14 @@ hooks 'kill-buffer-hook', 'kill-buffer-query-functions', and 'buffer-list-update-hook' for the temporary buffers they create. This avoids slowing them down when a lot of these hooks are defined. +** New face 'child-frame-border' and frame parameter 'child-frame-border-width'. +The face and width of child frames borders can no be determined +separately from thos of normal frames. To minimize backwards +incompatibility, child frames without a 'child-frame-border-width' +parameter will fall back to using 'internal-border-width'. However the +new 'child-frame-border' face does constitute a breaking change since +child frames' borders no longer use the 'internal-border' face. + --- ** The obsolete function 'thread-alive-p' has been removed. diff --git a/lisp/faces.el b/lisp/faces.el index d654b1f0e2..90f11bbe3b 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -2683,11 +2683,20 @@ the same as `window-divider' face." (defface internal-border '((t nil)) - "Basic face for the internal border." + "Basic face for the internal border. +For the internal border of child frames see `child-frame-border'." :version "26.1" :group 'frames :group 'basic-faces) +(defface child-frame-border + '((t nil)) + "Basic face for the internal border of child frames. +For the internal border of non-child frames see `internal-border'." + :version "28.1" + :group 'frames + :group 'basic-faces) + (defface minibuffer-prompt '((((background dark)) :foreground "cyan") ;; Don't use blue because many users of the MS-DOS port customize diff --git a/src/dispextern.h b/src/dispextern.h index 3ad98b8344..f4e872644d 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1826,6 +1826,7 @@ enum face_id WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID, INTERNAL_BORDER_FACE_ID, + CHILD_FRAME_BORDER_FACE_ID, TAB_BAR_FACE_ID, TAB_LINE_FACE_ID, BASIC_FACE_ID_SENTINEL diff --git a/src/frame.c b/src/frame.c index 599c4075f8..a2167ce1e4 100644 --- a/src/frame.c +++ b/src/frame.c @@ -3543,6 +3543,13 @@ DEFUN ("frame-fringe-width", Ffringe_width, Sfringe_width, 0, 1, 0, return make_fixnum (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame))); } +DEFUN ("frame-child-frame-border-width", Fframe_child_frame_border_width, Sframe_child_frame_border_width, 0, 1, 0, + doc: /* Return width of FRAME's child-frame border in pixels. */) + (Lisp_Object frame) +{ + return make_fixnum (FRAME_CHILD_FRAME_BORDER_WIDTH (decode_any_frame (frame))); +} + DEFUN ("frame-internal-border-width", Fframe_internal_border_width, Sframe_internal_border_width, 0, 1, 0, doc: /* Return width of FRAME's internal border in pixels. */) (Lisp_Object frame) @@ -3759,6 +3766,7 @@ static const struct frame_parm_table frame_parms[] = {"foreground-color", -1}, {"icon-name", SYMBOL_INDEX (Qicon_name)}, {"icon-type", SYMBOL_INDEX (Qicon_type)}, + {"child-frame-border-width", SYMBOL_INDEX (Qchild_frame_border_width)}, {"internal-border-width", SYMBOL_INDEX (Qinternal_border_width)}, {"right-divider-width", SYMBOL_INDEX (Qright_divider_width)}, {"bottom-divider-width", SYMBOL_INDEX (Qbottom_divider_width)}, @@ -4302,6 +4310,8 @@ gui_report_frame_params (struct frame *f, Lisp_Object *alistptr) store_in_alist (alistptr, Qborder_width, make_fixnum (f->border_width)); + store_in_alist (alistptr, Qchild_frame_border_width, + make_fixnum (FRAME_CHILD_FRAME_BORDER_WIDTH (f))); store_in_alist (alistptr, Qinternal_border_width, make_fixnum (FRAME_INTERNAL_BORDER_WIDTH (f))); store_in_alist (alistptr, Qright_divider_width, @@ -5999,6 +6009,7 @@ syms_of_frame (void) DEFSYM (Qhorizontal_scroll_bars, "horizontal-scroll-bars"); DEFSYM (Qicon_name, "icon-name"); DEFSYM (Qicon_type, "icon-type"); + DEFSYM (Qchild_frame_border_width, "child-frame-border-width"); DEFSYM (Qinternal_border_width, "internal-border-width"); DEFSYM (Qleft_fringe, "left-fringe"); DEFSYM (Qline_spacing, "line-spacing"); @@ -6423,6 +6434,7 @@ iconify the top level frame instead. */); defsubr (&Sscroll_bar_width); defsubr (&Sscroll_bar_height); defsubr (&Sfringe_width); + defsubr (&Sframe_child_frame_border_width); defsubr (&Sframe_internal_border_width); defsubr (&Sright_divider_width); defsubr (&Sbottom_divider_width); diff --git a/src/frame.h b/src/frame.h index 8cf41dc004..7b3bf20a24 100644 --- a/src/frame.h +++ b/src/frame.h @@ -534,6 +534,10 @@ struct frame /* Border width of the frame window as known by the (X) window system. */ int border_width; + /* Width of child frames' internal border. Acts as + internal_border_width for child frames. */ + int child_frame_border_width; + /* Width of the internal border. This is a line of background color just inside the window's border. When the frame is selected, a highlighting is displayed inside the internal border. */ @@ -1432,11 +1436,27 @@ FRAME_TOTAL_FRINGE_WIDTH (struct frame *f) return FRAME_LEFT_FRINGE_WIDTH (f) + FRAME_RIGHT_FRINGE_WIDTH (f); } -/* Pixel-width of internal border lines. */ +INLINE int +FRAME_CHILD_FRAME_BORDER_WIDTH (struct frame *f) +{ + return frame_dimension (f->child_frame_border_width); +} + +/* Pixel-width of internal border. Uses child_frame_border_width for + child frames if possible and falls back on internal_border_width + otherwise. */ INLINE int FRAME_INTERNAL_BORDER_WIDTH (struct frame *f) { - return frame_dimension (f->internal_border_width); +#ifdef HAVE_WINDOW_SYSTEM + return FRAME_PARENT_FRAME(f) + ? (f->child_frame_border_width + ? FRAME_CHILD_FRAME_BORDER_WIDTH(f) + : frame_dimension (f->internal_border_width)) + : frame_dimension (f->internal_border_width); +#else + return frame_dimension (f->internal_border_width) +#endif } /* Pixel-size of window divider lines. */ diff --git a/src/nsfns.m b/src/nsfns.m index 24ea7d7f63..c383e2f7ec 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -687,6 +687,21 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side. } } +static void +ns_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) +{ + int old_width = FRAME_CHILD_FRAME_BORDER_WIDTH (f); + int new_width = check_int_nonnegative (arg); + + if (new_width == old_width) + return; + f->child_frame_border_width = new_width; + + if (FRAME_NATIVE_WINDOW (f) != 0) + adjust_frame_size (f, -1, -1, 3, 0, Qchild_frame_border_width); + + SET_FRAME_GARBAGED (f); +} static void ns_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) @@ -912,6 +927,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side. ns_set_foreground_color, ns_set_icon_name, ns_set_icon_type, + ns_set_child_frame_border_width, ns_set_internal_border_width, gui_set_right_divider_width, /* generic OK */ gui_set_bottom_divider_width, /* generic OK */ @@ -1197,6 +1213,9 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side. gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (2), "internalBorderWidth", "InternalBorderWidth", RES_TYPE_NUMBER); + gui_default_parameter (f, parms, Qchild_frame_border_width, make_fixnum (2), + "childFrameBorderWidth", "childFrameBorderWidth", + RES_TYPE_NUMBER); gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0), NULL, NULL, RES_TYPE_NUMBER); gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0), diff --git a/src/nsterm.m b/src/nsterm.m index df3934c5c3..1b2328628e 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3037,9 +3037,13 @@ so some key presses (TAB) are swallowed by the system. */ NSRectEdge edge[] = {NSMinXEdge, NSMinYEdge, NSMaxXEdge, NSMaxYEdge}; int face_id = - !NILP (Vface_remapping_alist) - ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) - : INTERNAL_BORDER_FACE_ID; + (FRAME_PARENT_FRAME (f) + ? (!NILP (Vface_remapping_alist) + ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID) + : CHILD_FRAME_BORDER_FACE_ID) + : (!NILP (Vface_remapping_alist) + ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) + : INTERNAL_BORDER_FACE_ID)); struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); if (!face) diff --git a/src/w32fns.c b/src/w32fns.c index c1e18ff7fa..29d2e3d75f 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -1519,9 +1519,13 @@ w32_clear_under_internal_border (struct frame *f) int width = FRAME_PIXEL_WIDTH (f); int height = FRAME_PIXEL_HEIGHT (f); int face_id = - !NILP (Vface_remapping_alist) - ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) - : INTERNAL_BORDER_FACE_ID; + (FRAME_PARENT_FRAME (f) + ? (!NILP (Vface_remapping_alist) + ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID) + : CHILD_FRAME_BORDER_FACE_ID) + : (!NILP (Vface_remapping_alist) + ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) + : INTERNAL_BORDER_FACE_ID)); struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); block_input (); @@ -1548,6 +1552,32 @@ w32_clear_under_internal_border (struct frame *f) } } +/** + * w32_set_child_frame_border_width: + * + * Set width of child frame F's internal border to ARG pixels. + * ARG < 0 is * treated like ARG = 0. + */ +static void +w32_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) +{ + int argval = check_integer_range (arg, INT_MIN, INT_MAX); + int border = max (argval, 0); + + if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f)) + { + f->child_frame_border_width = border; + + if (FRAME_NATIVE_WINDOW (f) != 0) + { + adjust_frame_size (f, -1, -1, 3, false, Qchild_frame_border_width); + + if (FRAME_VISIBLE_P (f)) + w32_clear_under_internal_border (f); + } + } +} + /** * w32_set_internal_border_width: @@ -5873,6 +5903,28 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, parameters); } + /* Same for child frames. */ + if (NILP (Fassq (Qchild_frame_border_width, parameters))) + { + Lisp_Object value; + + value = gui_display_get_arg (dpyinfo, parameters, Qchild_frame_border_width, + "childFrameBorderWidth", "childFrameBorderWidth", + RES_TYPE_NUMBER); + if (! EQ (value, Qunbound)) + parameters = Fcons (Fcons (Qchild_frame_border_width, value), + parameters); + + } + + gui_default_parameter (f, parameters, Qchild_frame_border_width, +#ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */ + make_fixnum (0), +#else + make_fixnum (1), +#endif + "childFrameBorderWidth", "childFrameBorderWidth", + RES_TYPE_NUMBER); gui_default_parameter (f, parameters, Qinternal_border_width, make_fixnum (0), "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER); gui_default_parameter (f, parameters, Qright_divider_width, make_fixnum (0), @@ -10232,6 +10284,7 @@ frame_parm_handler w32_frame_parm_handlers[] = w32_set_foreground_color, w32_set_icon_name, w32_set_icon_type, + w32_set_child_frame_border_width, w32_set_internal_border_width, gui_set_right_divider_width, gui_set_bottom_divider_width, diff --git a/src/xfaces.c b/src/xfaces.c index 258b365eda..12087138e5 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -4914,6 +4914,7 @@ lookup_basic_face (struct window *w, struct frame *f, int face_id) case WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID: name = Qwindow_divider_first_pixel; break; case WINDOW_DIVIDER_LAST_PIXEL_FACE_ID: name = Qwindow_divider_last_pixel; break; case INTERNAL_BORDER_FACE_ID: name = Qinternal_border; break; + case CHILD_FRAME_BORDER_FACE_ID: name = Qchild_frame_border; break; default: emacs_abort (); /* the caller is supposed to pass us a basic face id */ @@ -5620,6 +5621,7 @@ realize_basic_faces (struct frame *f) realize_named_face (f, Qwindow_divider_last_pixel, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID); realize_named_face (f, Qinternal_border, INTERNAL_BORDER_FACE_ID); + realize_named_face (f, Qchild_frame_border, CHILD_FRAME_BORDER_FACE_ID); realize_named_face (f, Qtab_bar, TAB_BAR_FACE_ID); realize_named_face (f, Qtab_line, TAB_LINE_FACE_ID); @@ -6973,6 +6975,7 @@ syms_of_xfaces (void) DEFSYM (Qwindow_divider_first_pixel, "window-divider-first-pixel"); DEFSYM (Qwindow_divider_last_pixel, "window-divider-last-pixel"); DEFSYM (Qinternal_border, "internal-border"); + DEFSYM (Qchild_frame_border, "child-frame-border"); /* TTY color-related functions (defined in tty-colors.el). */ DEFSYM (Qtty_color_desc, "tty-color-desc"); diff --git a/src/xfns.c b/src/xfns.c index 9ab537ca8d..cac41ee485 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -1800,6 +1800,28 @@ x_change_tool_bar_height (struct frame *f, int height) #endif /* USE_GTK */ } +static void +x_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) +{ + int border = check_int_nonnegative (arg); + + if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f)) + { + f->child_frame_border_width = border; + +#ifdef USE_X_TOOLKIT + if (FRAME_X_OUTPUT (f)->edit_widget) + widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget); +#endif + + if (FRAME_X_WINDOW (f)) + { + adjust_frame_size (f, -1, -1, 3, false, Qchild_frame_border_width); + x_clear_under_internal_border (f); + } + } + +} static void x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) @@ -3897,6 +3919,29 @@ This function is an internal primitive--use `make-frame' instead. */) parms = Fcons (Fcons (Qinternal_border_width, value), parms); } + + /* Same for child frames. */ + if (NILP (Fassq (Qchild_frame_border_width, parms))) + { + Lisp_Object value; + + value = gui_display_get_arg (dpyinfo, parms, Qchild_frame_border_width, + "childFrameBorderWidth", "childFrameBorderWidth", + RES_TYPE_NUMBER); + if (! EQ (value, Qunbound)) + parms = Fcons (Fcons (Qchild_frame_border_width, value), + parms); + + } + + gui_default_parameter (f, parms, Qchild_frame_border_width, +#ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */ + make_fixnum (0), +#else + make_fixnum (1), +#endif + "childFrameBorderWidth", "childFrameBorderWidth", + RES_TYPE_NUMBER); gui_default_parameter (f, parms, Qinternal_border_width, #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */ make_fixnum (0), @@ -7762,6 +7807,7 @@ frame_parm_handler x_frame_parm_handlers[] = x_set_foreground_color, x_set_icon_name, x_set_icon_type, + x_set_child_frame_border_width, x_set_internal_border_width, gui_set_right_divider_width, gui_set_bottom_divider_width, diff --git a/src/xterm.c b/src/xterm.c index b8374fed8b..a855d2d67a 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1293,9 +1293,13 @@ x_clear_under_internal_border (struct frame *f) int height = FRAME_PIXEL_HEIGHT (f); int margin = FRAME_TOP_MARGIN_HEIGHT (f); int face_id = - !NILP (Vface_remapping_alist) - ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) - : INTERNAL_BORDER_FACE_ID; + (FRAME_PARENT_FRAME (f) + ? (!NILP (Vface_remapping_alist) + ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID) + : CHILD_FRAME_BORDER_FACE_ID) + : (!NILP (Vface_remapping_alist) + ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) + : INTERNAL_BORDER_FACE_ID)); struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); block_input (); @@ -1360,9 +1364,13 @@ x_after_update_window_line (struct window *w, struct glyph_row *desired_row) { int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y)); int face_id = - !NILP (Vface_remapping_alist) - ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) - : INTERNAL_BORDER_FACE_ID; + (FRAME_PARENT_FRAME (f) + ? (!NILP (Vface_remapping_alist) + ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID) + : CHILD_FRAME_BORDER_FACE_ID) + : (!NILP (Vface_remapping_alist) + ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID) + : INTERNAL_BORDER_FACE_ID)); struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); block_input (); commit b4b6a2684062d4470143b6ea460b5e82012554a1 Author: Stefan Monnier Date: Mon Jan 25 22:58:19 2021 -0500 Use `lexical-binding` in all `lisp/international` files * lisp/startup.el (keyboard-type): Make obsolete and lex-bound. * admin/unidata/unidata-gen.el (unidata-gen-file) (unidata-gen-charprop): Mark the generated files to use lexical binding. * lisp/international/isearch-x.el: Use lexical-binding. (junk-hist): Declare locally. * lisp/international/iso-cvt.el: * lisp/international/utf-7.el: * lisp/international/robin.el: * lisp/international/ogonek.el: * lisp/international/latin1-disp.el: * lisp/international/kkc.el: * lisp/international/kinsoku.el: * lisp/international/ja-dic-utl.el: Use lexical-binding. * lisp/international/ja-dic-cnv.el: Use lexical-binding. (skkdic-breakup-string): Remove unused var `kana-len`. * lisp/international/latexenc.el: Use lexical-binding. (tex-start-of-header): Declare. * lisp/international/mule-diag.el: Use lexical-binding. (list-character-sets): Remove unused var `pos`. (list-character-sets-1): Remove unused vars `tail` and `charset`. (list-charset-chars): Remove unused vars `chars` and `plane`. (describe-coding-system): Remove unused var `extra-spec`. (mule--print-opened): New var. (print-fontset): Bind it. (print-fontset-element): Use it instead of `print-opened`. * lisp/international/quail.el: Use lexical-binding. (quail-start-translation, quail-start-conversion): Remove unused var `generated-events`. (quail-help-insert-keymap-description): Use local dynbound var `the-keymap`. diff --git a/admin/unidata/unidata-gen.el b/admin/unidata/unidata-gen.el index 3918853088..221c9b104e 100644 --- a/admin/unidata/unidata-gen.el +++ b/admin/unidata/unidata-gen.el @@ -1416,7 +1416,8 @@ Property value is a symbol `o' (Open), `c' (Close), or `n' (None)." (or elt (user-error "Unknown output file: %s" basename)) (or noninteractive (message "Generating %s..." file)) (with-temp-file file - (insert ";; " copyright " + (insert ";;; " basename " -*- lexical-binding:t -*- +;; " copyright " ;; Generated from Unicode data files by unidata-gen.el. ;; The sources for this file are found in the admin/unidata/ directory in ;; the Emacs sources. The Unicode data files are used under the @@ -1451,7 +1452,8 @@ Property value is a symbol `o' (Open), `c' (Close), or `n' (None)." (defun unidata-gen-charprop (&optional charprop-file) (or charprop-file (setq charprop-file (pop command-line-args-left))) (with-temp-file charprop-file - (insert ";; Automatically generated by unidata-gen.el.\n" + (insert ";; Automatically generated by unidata-gen.el." + " -*- lexical-binding: t -*-\n" ";; See the admin/unidata/ directory in the Emacs sources.\n") (dolist (elt unidata-file-alist) (dolist (proplist (cdr elt)) diff --git a/etc/NEWS b/etc/NEWS index 6a80493e23..b815d3ac61 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2133,6 +2133,8 @@ obsolete back in Emacs-23.1. The affected functions are: make-obsolete, define-obsolete-function-alias, make-obsolete-variable, define-obsolete-variable-alias. +** The variable 'keyboard-type' is obsolete and not dynamically scoped any more + * Lisp Changes in Emacs 28.1 diff --git a/lisp/international/isearch-x.el b/lisp/international/isearch-x.el index 400421ddb2..b890bde48d 100644 --- a/lisp/international/isearch-x.el +++ b/lisp/international/isearch-x.el @@ -1,4 +1,4 @@ -;;; isearch-x.el --- extended isearch handling commands +;;; isearch-x.el --- extended isearch handling commands -*- lexical-binding: t; -*- ;; Copyright (C) 1997, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, @@ -67,7 +67,7 @@ ;; Exit from recursive edit safely. Set in `after-change-functions' ;; by isearch-with-keyboard-coding. -(defun isearch-exit-recursive-edit (start end length) +(defun isearch-exit-recursive-edit (_start _end _length) (interactive) (throw 'exit nil)) @@ -102,6 +102,7 @@ ;;;###autoload (defun isearch-process-search-multibyte-characters (last-char &optional count) + (defvar junk-hist) (if (eq this-command 'isearch-printing-char) (let ((overriding-terminal-local-map nil) (prompt (isearch-message-prefix)) diff --git a/lisp/international/iso-cvt.el b/lisp/international/iso-cvt.el index 3f3843e23d..ead7c8aa61 100644 --- a/lisp/international/iso-cvt.el +++ b/lisp/international/iso-cvt.el @@ -1,4 +1,4 @@ -;;; iso-cvt.el --- translate ISO 8859-1 from/to various encodings -*- coding: utf-8 -*- +;;; iso-cvt.el --- translate ISO 8859-1 from/to various encodings -*- lexical-binding: t; -*- ;; This file was formerly called gm-lingo.el. ;; Copyright (C) 1993-1998, 2000-2021 Free Software Foundation, Inc. @@ -79,7 +79,7 @@ (point-max)))) ;;;###autoload -(defun iso-spanish (from to &optional buffer) +(defun iso-spanish (from to &optional _buffer) "Translate net conventions for Spanish to ISO 8859-1. Translate the region between FROM and TO using the table `iso-spanish-trans-tab'. @@ -121,7 +121,7 @@ and may translate too little.") "Currently active translation table for German.") ;;;###autoload -(defun iso-german (from to &optional buffer) +(defun iso-german (from to &optional _buffer) "Translate net conventions for German to ISO 8859-1. Translate the region FROM and TO using the table `iso-german-trans-tab'. @@ -194,7 +194,7 @@ Optional arg BUFFER is ignored (for use in `format-alist')." "Translation table for translating ISO 8859-1 characters to TeX sequences.") ;;;###autoload -(defun iso-iso2tex (from to &optional buffer) +(defun iso-iso2tex (from to &optional _buffer) "Translate ISO 8859-1 characters to TeX sequences. Translate the region between FROM and TO using the table `iso-iso2tex-trans-tab'. @@ -387,7 +387,7 @@ This table is not exhaustive (and due to TeX's power can never be). It only contains commonly used sequences.") ;;;###autoload -(defun iso-tex2iso (from to &optional buffer) +(defun iso-tex2iso (from to &optional _buffer) "Translate TeX sequences to ISO 8859-1 characters. Translate the region between FROM and TO using the table `iso-tex2iso-trans-tab'. @@ -646,7 +646,7 @@ It only contains commonly used sequences.") "Translation table for translating ISO 8859-1 characters to German TeX.") ;;;###autoload -(defun iso-gtex2iso (from to &optional buffer) +(defun iso-gtex2iso (from to &optional _buffer) "Translate German TeX sequences to ISO 8859-1 characters. Translate the region between FROM and TO using the table `iso-gtex2iso-trans-tab'. @@ -655,7 +655,7 @@ Optional arg BUFFER is ignored (for use in `format-alist')." (iso-translate-conventions from to iso-gtex2iso-trans-tab)) ;;;###autoload -(defun iso-iso2gtex (from to &optional buffer) +(defun iso-iso2gtex (from to &optional _buffer) "Translate ISO 8859-1 characters to German TeX sequences. Translate the region between FROM and TO using the table `iso-iso2gtex-trans-tab'. @@ -674,7 +674,7 @@ Optional arg BUFFER is ignored (for use in `format-alist')." "Translation table for translating ISO 8859-1 characters to Duden sequences.") ;;;###autoload -(defun iso-iso2duden (from to &optional buffer) +(defun iso-iso2duden (from to &optional _buffer) "Translate ISO 8859-1 characters to Duden sequences. Translate the region between FROM and TO using the table `iso-iso2duden-trans-tab'. @@ -812,7 +812,7 @@ Optional arg BUFFER is ignored (for use in `format-alist')." ("ÿ" "ÿ"))) ;;;###autoload -(defun iso-iso2sgml (from to &optional buffer) +(defun iso-iso2sgml (from to &optional _buffer) "Translate ISO 8859-1 characters in the region to SGML entities. Use entities from \"ISO 8879:1986//ENTITIES Added Latin 1//EN\". Optional arg BUFFER is ignored (for use in `format-alist')." @@ -820,7 +820,7 @@ Optional arg BUFFER is ignored (for use in `format-alist')." (iso-translate-conventions from to iso-iso2sgml-trans-tab)) ;;;###autoload -(defun iso-sgml2iso (from to &optional buffer) +(defun iso-sgml2iso (from to &optional _buffer) "Translate SGML entities in the region to ISO 8859-1 characters. Use entities from \"ISO 8879:1986//ENTITIES Added Latin 1//EN\". Optional arg BUFFER is ignored (for use in `format-alist')." @@ -828,13 +828,13 @@ Optional arg BUFFER is ignored (for use in `format-alist')." (iso-translate-conventions from to iso-sgml2iso-trans-tab)) ;;;###autoload -(defun iso-cvt-read-only (&rest ignore) +(defun iso-cvt-read-only (&rest _ignore) "Warn that format is read-only." (interactive) (error "This format is read-only; specify another format for writing")) ;;;###autoload -(defun iso-cvt-write-only (&rest ignore) +(defun iso-cvt-write-only (&rest _ignore) "Warn that format is write-only." (interactive) (error "This format is write-only")) diff --git a/lisp/international/ja-dic-cnv.el b/lisp/international/ja-dic-cnv.el index b80590491c..155c85fb42 100644 --- a/lisp/international/ja-dic-cnv.el +++ b/lisp/international/ja-dic-cnv.el @@ -1,4 +1,4 @@ -;;; ja-dic-cnv.el --- convert a Japanese dictionary (SKK-JISYO.L) to Emacs Lisp +;;; ja-dic-cnv.el --- convert a Japanese dictionary (SKK-JISYO.L) to Emacs Lisp -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. @@ -96,7 +96,7 @@ ("もく" "目") ("ゆき" "行"))) -(defun skkdic-convert-postfix (skkbuf buf) +(defun skkdic-convert-postfix (_skkbuf buf) (byte-compile-info "Processing POSTFIX entries" t) (goto-char (point-min)) (with-current-buffer buf @@ -150,7 +150,7 @@ (defconst skkdic-prefix-list '(skkdic-prefix-list)) -(defun skkdic-convert-prefix (skkbuf buf) +(defun skkdic-convert-prefix (_skkbuf buf) (byte-compile-info "Processing PREFIX entries" t) (goto-char (point-min)) (with-current-buffer buf @@ -209,7 +209,7 @@ (substring str from idx) skkdic-word-list))) (if (or (and (consp kana2-list) - (let ((kana-len (length kana)) + (let (;; (kana-len (length kana)) kana2) (catch 'skkdic-tag (while kana2-list diff --git a/lisp/international/ja-dic-utl.el b/lisp/international/ja-dic-utl.el index 498fb23f70..cc636986f9 100644 --- a/lisp/international/ja-dic-utl.el +++ b/lisp/international/ja-dic-utl.el @@ -1,4 +1,4 @@ -;;; ja-dic-utl.el --- utilities for handling Japanese dictionary (SKK-JISYO.L) +;;; ja-dic-utl.el --- utilities for handling Japanese dictionary (SKK-JISYO.L) -*- lexical-binding: t; -*- ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, ;; 2005, 2006, 2007, 2008, 2009, 2010, 2011 diff --git a/lisp/international/kinsoku.el b/lisp/international/kinsoku.el index cd740acc6a..05179a98ac 100644 --- a/lisp/international/kinsoku.el +++ b/lisp/international/kinsoku.el @@ -1,4 +1,4 @@ -;;; kinsoku.el --- `Kinsoku' processing funcs +;;; kinsoku.el --- `Kinsoku' processing funcs -*- lexical-binding: t; -*- ;; Copyright (C) 1997, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, diff --git a/lisp/international/kkc.el b/lisp/international/kkc.el index 290f4fa0cf..87f73897bf 100644 --- a/lisp/international/kkc.el +++ b/lisp/international/kkc.el @@ -1,4 +1,4 @@ -;;; kkc.el --- Kana Kanji converter +;;; kkc.el --- Kana Kanji converter -*- lexical-binding: t; -*- ;; Copyright (C) 1997-1998, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, diff --git a/lisp/international/latexenc.el b/lisp/international/latexenc.el index e2ee3fb37e..ff7cddcb26 100644 --- a/lisp/international/latexenc.el +++ b/lisp/international/latexenc.el @@ -1,4 +1,4 @@ -;;; latexenc.el --- guess correct coding system in LaTeX files -*-coding: utf-8 -*- +;;; latexenc.el --- guess correct coding system in LaTeX files -*- lexical-binding: t; -*- ;; Copyright (C) 2005-2021 Free Software Foundation, Inc. @@ -109,6 +109,8 @@ Return nil if no matching input encoding can be found." (defvar latexenc-dont-use-tex-guess-main-file-flag nil "Non-nil means don't use tex-guessmain-file to find the coding system.") +(defvar tex-start-of-header) + ;;;###autoload (defun latexenc-find-file-coding-system (arg-list) "Determine the coding system of a LaTeX file if it uses \"inputenc.sty\". diff --git a/lisp/international/latin1-disp.el b/lisp/international/latin1-disp.el index bda2c51ab9..4b6ef9833e 100644 --- a/lisp/international/latin1-disp.el +++ b/lisp/international/latin1-disp.el @@ -1,4 +1,4 @@ -;;; latin1-disp.el --- display tables for other ISO 8859 on Latin-1 terminals -*-coding: utf-8;-*- +;;; latin1-disp.el --- display tables for other ISO 8859 on Latin-1 terminals -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. @@ -86,8 +86,8 @@ use either \\[customize] or the function `latin1-display'." :group 'latin1-display :type 'boolean :require 'latin1-disp - :initialize 'custom-initialize-default - :set (lambda (symbol value) + :initialize #'custom-initialize-default + :set (lambda (_symbol value) (if value (apply #'latin1-display latin1-display-sets) (latin1-display)))) @@ -186,7 +186,7 @@ character set." 'arabic-iso8859-6 (car (remq 'ascii (get-language-info language 'charset)))))) - (map-charset-chars #'(lambda (range arg) + (map-charset-chars #'(lambda (range _arg) (standard-display-default (car range) (cdr range))) charset)) (sit-for 0)) @@ -201,11 +201,10 @@ character set: `latin-2', `hebrew' etc." (char (and info (decode-char (car (remq 'ascii info)) ?\ )))) (and char (char-displayable-p char)))) -(defun latin1-display-setup (set &optional force) +(defun latin1-display-setup (set &optional _force) "Set up Latin-1 display for characters in the given SET. SET must be a member of `latin1-display-sets'. Normally, check -whether a font for SET is available and don't set the display if it -is. If FORCE is non-nil, set up the display regardless." +whether a font for SET is available and don't set the display if it is." (cond ((eq set 'latin-2) (latin1-display-identities set) @@ -735,7 +734,7 @@ is. If FORCE is non-nil, set up the display regardless." (sit-for 0)) ;;;###autoload -(defcustom latin1-display-ucs-per-lynx nil +(defcustom latin1-display-ucs-per-lynx nil ;FIXME: Isn't this a minor mode? "Set up Latin-1/ASCII display for Unicode characters. This uses the transliterations of the Lynx browser. The display isn't changed if the display can render Unicode characters. @@ -745,8 +744,8 @@ use either \\[customize] or the function `latin1-display'." :group 'latin1-display :type 'boolean :require 'latin1-disp - :initialize 'custom-initialize-default - :set (lambda (symbol value) + :initialize #'custom-initialize-default + :set (lambda (_symbol value) (if value (latin1-display-ucs-per-lynx 1) (latin1-display-ucs-per-lynx -1)))) diff --git a/lisp/international/mule-diag.el b/lisp/international/mule-diag.el index d622268525..d97d090cd0 100644 --- a/lisp/international/mule-diag.el +++ b/lisp/international/mule-diag.el @@ -1,4 +1,4 @@ -;;; mule-diag.el --- show diagnosis of multilingual environment (Mule) +;;; mule-diag.el --- show diagnosis of multilingual environment (Mule) -*- lexical-binding: t; -*- ;; Copyright (C) 1997-1998, 2000-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, @@ -86,8 +86,7 @@ but still shows the full information." (indent-to 48) (insert "| +--CHARS\n") (let ((columns '(("CHARSET-NAME" . name) "\t\t\t\t\t" - ("D CH FINAL-BYTE" . iso-spec))) - pos) + ("D CH FINAL-BYTE" . iso-spec)))) (while columns (if (stringp (car columns)) (insert (car columns)) @@ -117,8 +116,8 @@ but still shows the full information." SORT-KEY should be `name' or `iso-spec' (default `name')." (or sort-key (setq sort-key 'name)) - (let ((tail charset-list) - charset-info-list supplementary-list charset sort-func) + (let (;; (tail charset-list) + charset-info-list supplementary-list sort-func) (dolist (charset charset-list) ;; Generate a list that contains all information to display. (let ((elt (list charset @@ -273,9 +272,9 @@ meanings of these arguments." (setq tab-width 4) (set-buffer-multibyte t) (let ((dim (charset-dimension charset)) - (chars (charset-chars charset)) - ;; (plane (charset-iso-graphic-plane charset)) - (plane 1) + ;; (chars (charset-chars charset)) + ;; (plane (charset-iso-graphic-plane charset)) + ;; (plane 1) (range (plist-get (charset-plist charset) :code-space)) min max min2 max2) (if (> dim 2) @@ -415,7 +414,8 @@ or provided just for backward compatibility." nil))) (print-coding-system-briefly coding-system 'doc-string) (let ((type (coding-system-type coding-system)) ;; Fixme: use this - (extra-spec (coding-system-plist coding-system))) + ;; (extra-spec (coding-system-plist coding-system)) + ) (princ "Type: ") (princ type) (cond ((eq type 'undecided) @@ -858,6 +858,8 @@ The IGNORED argument is ignored." (with-output-to-temp-buffer "*Help*" (describe-font-internal font-info))))) +(defvar mule--print-opened) + (defun print-fontset-element (val) ;; VAL has this format: ;; ((REQUESTED-FONT-NAME OPENED-FONT-NAME ...) ...) @@ -915,7 +917,7 @@ The IGNORED argument is ignored." (or adstyle "*") registry))))) ;; Insert opened font names (if any). - (if (and (boundp 'print-opened) (symbol-value 'print-opened)) + (if (bound-and-true-p mule--print-opened) (dolist (opened (cdr elt)) (insert "\n\t[" opened "]"))))))) @@ -943,8 +945,9 @@ the current buffer." " and [" (propertize "OPENED" 'face 'underline) "])") (let* ((info (fontset-info fontset)) (default-info (char-table-extra-slot info 0)) + (mule--print-opened print-opened) start1 end1 start2 end2) - (describe-vector info 'print-fontset-element) + (describe-vector info #'print-fontset-element) (when (char-table-range info nil) ;; The default of FONTSET is described. (setq start1 (re-search-backward "^default")) @@ -956,7 +959,7 @@ the current buffer." (when default-info (insert "\n ------") (put-text-property (line-beginning-position) (point) 'face 'highlight) - (describe-vector default-info 'print-fontset-element) + (describe-vector default-info #'print-fontset-element) (when (char-table-range default-info nil) ;; The default of the default fontset is described. (setq end2 (re-search-backward "^default")) diff --git a/lisp/international/ogonek.el b/lisp/international/ogonek.el index 79e446875d..e049832d58 100644 --- a/lisp/international/ogonek.el +++ b/lisp/international/ogonek.el @@ -1,4 +1,4 @@ -;;; ogonek.el --- change the encoding of Polish diacritics +;;; ogonek.el --- change the encoding of Polish diacritics -*- lexical-binding: t; -*- ;; Copyright (C) 1997-1998, 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/international/quail.el b/lisp/international/quail.el index f2ac44a8a6..9698d46153 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el @@ -1,4 +1,4 @@ -;;; quail.el --- provides simple input method for multilingual text +;;; quail.el --- provides simple input method for multilingual text -*- lexical-binding: t; -*- ;; Copyright (C) 1997-1998, 2000-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, @@ -1046,7 +1046,7 @@ the following annotation types are supported. (quail-install-decode-map ',decode-map)))))) ;;;###autoload -(defun quail-install-map (map &optional name) +(defun quail-install-map (map &optional _name) "Install the Quail map MAP in the current Quail package. Optional 2nd arg NAME, if non-nil, is a name of Quail package for @@ -1060,7 +1060,7 @@ The installed map can be referred by the function `quail-map'." (setcar (cdr (cdr quail-current-package)) map)) ;;;###autoload -(defun quail-install-decode-map (decode-map &optional name) +(defun quail-install-decode-map (decode-map &optional _name) "Install the Quail decode map DECODE-MAP in the current Quail package. Optional 2nd arg NAME, if non-nil, is a name of Quail package for @@ -1390,7 +1390,7 @@ Return the input string." (let* ((echo-keystrokes 0) (help-char nil) (overriding-terminal-local-map (quail-translation-keymap)) - (generated-events nil) ;FIXME: What is this? + ;; (generated-events nil) ;FIXME: What is this? (input-method-function nil) (modified-p (buffer-modified-p)) last-command-event last-command this-command inhibit-record) @@ -1455,7 +1455,7 @@ Return the input string." (let* ((echo-keystrokes 0) (help-char nil) (overriding-terminal-local-map (quail-conversion-keymap)) - (generated-events nil) ;FIXME: What is this? + ;; (generated-events nil) ;FIXME: What is this? (input-method-function nil) (modified-p (buffer-modified-p)) last-command-event last-command this-command inhibit-record) @@ -2452,7 +2452,7 @@ should be made by `quail-build-decode-map' (which see)." (insert-char ?- single-trans-width) (forward-line 1) ;; Insert the key-tran pairs. - (dotimes (row rows) + (dotimes (_ rows) (let ((elt (pop single-list))) (when elt (move-to-column col) @@ -2625,12 +2625,14 @@ KEY BINDINGS FOR CONVERSION (run-hooks 'temp-buffer-show-hook))))) (defun quail-help-insert-keymap-description (keymap &optional header) + (defvar the-keymap) (let ((pos1 (point)) + (the-keymap keymap) pos2) (if header (insert header)) (save-excursion - (insert (substitute-command-keys "\\{keymap}"))) + (insert (substitute-command-keys "\\{the-keymap}"))) ;; Skip headers "key bindings", etc. (forward-line 3) (setq pos2 (point)) diff --git a/lisp/international/robin.el b/lisp/international/robin.el index 16cac07c77..55390df315 100644 --- a/lisp/international/robin.el +++ b/lisp/international/robin.el @@ -1,4 +1,4 @@ -;;; robin.el --- yet another input method (smaller than quail) +;;; robin.el --- yet another input method (smaller than quail) -*- lexical-binding: t; -*- ;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 ;; National Institute of Advanced Industrial Science and Technology (AIST) diff --git a/lisp/international/utf-7.el b/lisp/international/utf-7.el index e941abb463..dece184ffe 100644 --- a/lisp/international/utf-7.el +++ b/lisp/international/utf-7.el @@ -1,4 +1,4 @@ -;;; utf-7.el --- utf-7 coding system +;;; utf-7.el --- utf-7 coding system -*- lexical-binding: t; -*- ;; Copyright (C) 2003-2021 Free Software Foundation, Inc. diff --git a/lisp/startup.el b/lisp/startup.el index 7011fbf458..60e1a200bb 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -320,6 +320,8 @@ early init file.") This variable is used to define the proper function and keypad keys for use under X. It is used in a fashion analogous to the environment variable TERM.") +(make-obsolete-variable 'keyboard-type nil "28.1") +(internal-make-var-non-special 'keyboard-type) (defvar window-setup-hook nil "Normal hook run after loading init files and handling the command line. commit 8f0a2c84b66ff8d45a9d088a181617417115ec9e Author: Lars Ingebrigtsen Date: Tue Jan 26 01:12:45 2021 +0100 Make subdirs . nil in dir-locals in ~/ work * lisp/files.el (dir-locals-collect-variables): Compare directory names after expanding. This makes a (subdirs . nil) in ~/ work as expected (bug#17205). Test case: ((nil . ((a . "hallo") (subdirs . nil)))) in ~/ diff --git a/lisp/files.el b/lisp/files.el index 7af5549bcb..77e3a3a834 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -4068,7 +4068,7 @@ Return the new variables list." ;; integer values for subdir, where N means ;; variables apply to this directory and N levels ;; below it (0 == nil). - (equal root default-directory)) + (equal root (expand-file-name default-directory))) (setq variables (dir-locals-collect-mode-variables alist variables)))))))) (error commit 49e01d85ed6a6e4c95d43b6eeb4f32c7daa319a7 Author: Juri Linkov Date: Mon Jan 25 19:14:22 2021 +0200 Don't move point to the prompt in previous-line-or-history-element (bug#46033) * lisp/simple.el (previous-line-or-history-element): Avoid moving point to the prompt. diff --git a/lisp/simple.el b/lisp/simple.el index 8d4e4a7a6b..c878fdab92 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -2476,7 +2476,10 @@ previous element of the minibuffer history in the minibuffer." (current-column))))) (condition-case nil (with-no-warnings - (previous-line arg)) + (previous-line arg) + ;; Avoid moving point to the prompt + (when (< (point) (minibuffer-prompt-end)) + (signal 'beginning-of-buffer nil))) (beginning-of-buffer ;; Restore old position since `line-move-visual' moves point to ;; the beginning of the line when it fails to go to the previous line. commit a10c74fbea46d5299e19167248383c69fd30648c Author: Lars Ingebrigtsen Date: Mon Jan 25 07:44:29 2021 +0100 Fontify special forms and macros the same * lisp/emacs-lisp/lisp-mode.el (lisp--el-match-keyword): Handle special forms and macros the same way (bug#43265). This makes things like (setq a '(if a b)) be fontified correctly (i.e., not fontified as a keyword). diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 22435d5965..c96d849d44 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -257,10 +257,9 @@ (concat "(\\(" lisp-mode-symbol-regexp "\\)\\_>")) limit t) (let ((sym (intern-soft (match-string 1)))) - (when (or (special-form-p sym) - (and (macrop sym) - (not (get sym 'no-font-lock-keyword)) - (lisp--el-funcall-position-p (match-beginning 0)))) + (when (and (or (special-form-p sym) (macrop sym)) + (not (get sym 'no-font-lock-keyword)) + (lisp--el-funcall-position-p (match-beginning 0))) (throw 'found t)))))) (defmacro let-when-compile (bindings &rest body) diff --git a/test/lisp/progmodes/elisp-mode-tests.el b/test/lisp/progmodes/elisp-mode-tests.el index e84184ff07..badcad670c 100644 --- a/test/lisp/progmodes/elisp-mode-tests.el +++ b/test/lisp/progmodes/elisp-mode-tests.el @@ -871,7 +871,6 @@ to (xref-elisp-test-descr-to-target xref)." 'font-lock-keyword-face))) (ert-deftest test-elisp-font-keywords-3 () - :expected-result :failed ; FIXME bug#43265 (should (eq (test--font '(setq a '(if when zot)) "(\\(if\\)") nil))) commit 9503f8d96cc89fa89bb68e183c79f0d9cb1b4d32 Author: Lars Ingebrigtsen Date: Sun Jan 24 23:25:52 2021 +0100 Rewrite lisp--el-funcall-position-p to be inverse of the -not function * lisp/emacs-lisp/lisp-mode.el (lisp--el-funcall-position-p): Rename and rewrite to return the inverse value. Non-inverted predicate functions are easier to reason about. (lisp--el-non-funcall-position-p): Make obsolete. diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 9c2b0dbe20..22435d5965 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -200,48 +200,54 @@ res)) (defun lisp--el-non-funcall-position-p (pos) + "Heuristically determine whether POS is an evaluated position." + (declare (obsolete lisp--el-funcall-position-p "28.1")) + (not (lisp--el-funcall-position-p pos))) + +(defun lisp--el-funcall-position-p (pos) "Heuristically determine whether POS is an evaluated position." (save-match-data (save-excursion (ignore-errors (goto-char pos) ;; '(lambda ..) is not a funcall position, but #'(lambda ...) is. - (or (and (eql (char-before) ?\') - (not (eql (char-before (1- (point))) ?#))) - (let* ((ppss (syntax-ppss)) - (paren-posns (nth 9 ppss)) - (parent - (when paren-posns - (goto-char (car (last paren-posns))) ;(up-list -1) - (cond - ((ignore-errors - (and (eql (char-after) ?\() - (when (cdr paren-posns) - (goto-char (car (last paren-posns 2))) - (looking-at "(\\_")))) - (goto-char (match-end 0)) - 'let) - ((looking-at - (rx "(" - (group-n 1 (+ (or (syntax w) (syntax _)))) - symbol-end)) - (prog1 (intern-soft (match-string-no-properties 1)) - (goto-char (match-end 1)))))))) - (or (eq parent 'declare) - (and (eq parent 'let) - (progn - (forward-sexp 1) - (< pos (point)))) - (and (eq parent 'condition-case) - ;; If (cdr paren-posns), then we're in the BODY - ;; of HANDLERS. - (and (not (cdr paren-posns)) - (progn - (forward-sexp 1) - ;; If we're in the second form, then we're in - ;; a funcall position. - (not (< (point) pos (progn (forward-sexp 1) - (point)))))))))))))) + (if (eql (char-before) ?\') + (eql (char-before (1- (point))) ?#) + (let* ((ppss (syntax-ppss)) + (paren-posns (nth 9 ppss)) + (parent + (when paren-posns + (goto-char (car (last paren-posns))) ;(up-list -1) + (cond + ((ignore-errors + (and (eql (char-after) ?\() + (when (cdr paren-posns) + (goto-char (car (last paren-posns 2))) + (looking-at "(\\_")))) + (goto-char (match-end 0)) + 'let) + ((looking-at + (rx "(" + (group-n 1 (+ (or (syntax w) (syntax _)))) + symbol-end)) + (prog1 (intern-soft (match-string-no-properties 1)) + (goto-char (match-end 1)))))))) + (pcase parent + ('declare nil) + ('let + (forward-sexp 1) + (>= pos (point))) + ('condition-case + ;; If (cdr paren-posns), then we're in the BODY + ;; of HANDLERS. + (or (cdr paren-posns) + (progn + (forward-sexp 1) + ;; If we're in the second form, then we're in + ;; a funcall position. + (< (point) pos (progn (forward-sexp 1) + (point)))))) + (_ t)))))))) (defun lisp--el-match-keyword (limit) ;; FIXME: Move to elisp-mode.el. @@ -254,8 +260,7 @@ (when (or (special-form-p sym) (and (macrop sym) (not (get sym 'no-font-lock-keyword)) - (not (lisp--el-non-funcall-position-p - (match-beginning 0))))) + (lisp--el-funcall-position-p (match-beginning 0)))) (throw 'found t)))))) (defmacro let-when-compile (bindings &rest body) commit 196be2bf12e1018335e4261cd4d6f25d6d16c415 Author: Lars Ingebrigtsen Date: Sun Jan 24 21:43:25 2021 +0100 Fix macro fontification in `condition-case' handler bodies * lisp/emacs-lisp/lisp-mode.el (lisp--el-non-funcall-position-p): Fontify macros in the BODY of HANDLERS in `condition-case' correctly (bug#43265). diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 34ecfd1c25..9c2b0dbe20 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -233,12 +233,15 @@ (forward-sexp 1) (< pos (point)))) (and (eq parent 'condition-case) - (progn - (forward-sexp 1) - ;; If we're in the second form, then we're in - ;; a funcall position. - (not (< (point) pos (progn (forward-sexp 1) - (point))))))))))))) + ;; If (cdr paren-posns), then we're in the BODY + ;; of HANDLERS. + (and (not (cdr paren-posns)) + (progn + (forward-sexp 1) + ;; If we're in the second form, then we're in + ;; a funcall position. + (not (< (point) pos (progn (forward-sexp 1) + (point)))))))))))))) (defun lisp--el-match-keyword (limit) ;; FIXME: Move to elisp-mode.el. diff --git a/test/lisp/progmodes/elisp-mode-tests.el b/test/lisp/progmodes/elisp-mode-tests.el index 714751eafc..e84184ff07 100644 --- a/test/lisp/progmodes/elisp-mode-tests.el +++ b/test/lisp/progmodes/elisp-mode-tests.el @@ -864,7 +864,6 @@ to (xref-elisp-test-descr-to-target xref)." 'nil))) (ert-deftest test-elisp-font-keywords-2 () - :expected-result :failed ; FIXME bug#43265 (should (eq (test--font '(condition-case nil (foo) (error (when a b))) commit 8f28a1b9da06a12ac3631de38119d8845f14499c Author: Lars Ingebrigtsen Date: Sun Jan 24 21:31:09 2021 +0100 Tweak `condition-case' keyword highlights * lisp/emacs-lisp/lisp-mode.el (lisp--el-non-funcall-position-p): Tweak `condition-case' position check to skip the VAR form. diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 8780c5dcd3..34ecfd1c25 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -234,8 +234,11 @@ (< pos (point)))) (and (eq parent 'condition-case) (progn - (forward-sexp 2) - (< (point) pos)))))))))) + (forward-sexp 1) + ;; If we're in the second form, then we're in + ;; a funcall position. + (not (< (point) pos (progn (forward-sexp 1) + (point))))))))))))) (defun lisp--el-match-keyword (limit) ;; FIXME: Move to elisp-mode.el. diff --git a/test/lisp/progmodes/elisp-mode-tests.el b/test/lisp/progmodes/elisp-mode-tests.el index 0da0e39353..714751eafc 100644 --- a/test/lisp/progmodes/elisp-mode-tests.el +++ b/test/lisp/progmodes/elisp-mode-tests.el @@ -877,7 +877,7 @@ to (xref-elisp-test-descr-to-target xref)." "(\\(if\\)") nil))) -(ert-deftest test-elisp-font-keywords-if () +(ert-deftest test-elisp-font-keywords-4 () :expected-result :failed ; FIXME bug#43265 (should (eq (test--font '(condition-case nil (foo) @@ -885,5 +885,12 @@ to (xref-elisp-test-descr-to-target xref)." "(\\(if\\)") nil))) +(ert-deftest test-elisp-font-keywords-5 () + (should (eq (test--font '(condition-case (when a) + (foo) + (error t)) + "(\\(when\\)") + nil))) + (provide 'elisp-mode-tests) ;;; elisp-mode-tests.el ends here commit e5aaa1251cfb9d6d18682a5eda137a2e12ca4213 Author: Lars Ingebrigtsen Date: Sun Jan 24 20:53:36 2021 +0100 Add some elisp-mode font lock tests diff --git a/test/lisp/progmodes/elisp-mode-tests.el b/test/lisp/progmodes/elisp-mode-tests.el index fd43707f27..0da0e39353 100644 --- a/test/lisp/progmodes/elisp-mode-tests.el +++ b/test/lisp/progmodes/elisp-mode-tests.el @@ -834,5 +834,56 @@ to (xref-elisp-test-descr-to-target xref)." (indent-region (point-min) (point-max)) (should (equal (buffer-string) orig))))) +(defun test--font (form search) + (with-temp-buffer + (emacs-lisp-mode) + (if (stringp form) + (insert form) + (pp form (current-buffer))) + (font-lock-debug-fontify) + (goto-char (point-min)) + (and (re-search-forward search nil t) + (get-text-property (match-beginning 1) 'face)))) + +(ert-deftest test-elisp-font-keywords-1 () + ;; Special form. + (should (eq (test--font '(if foo bar) "(\\(if\\)") + 'font-lock-keyword-face)) + ;; Macro. + (should (eq (test--font '(when foo bar) "(\\(when\\)") + 'font-lock-keyword-face)) + (should (eq (test--font '(condition-case nil + (foo) + (error (if a b))) + "(\\(if\\)") + 'font-lock-keyword-face)) + (should (eq (test--font '(condition-case nil + (foo) + (when (if a b))) + "(\\(when\\)") + 'nil))) + +(ert-deftest test-elisp-font-keywords-2 () + :expected-result :failed ; FIXME bug#43265 + (should (eq (test--font '(condition-case nil + (foo) + (error (when a b))) + "(\\(when\\)") + 'font-lock-keyword-face))) + +(ert-deftest test-elisp-font-keywords-3 () + :expected-result :failed ; FIXME bug#43265 + (should (eq (test--font '(setq a '(if when zot)) + "(\\(if\\)") + nil))) + +(ert-deftest test-elisp-font-keywords-if () + :expected-result :failed ; FIXME bug#43265 + (should (eq (test--font '(condition-case nil + (foo) + ((if foo) (when a b))) + "(\\(if\\)") + nil))) + (provide 'elisp-mode-tests) ;;; elisp-mode-tests.el ends here commit 3cefda090304bbbce43d242072918ca855326842 Author: Michael Albinus Date: Sun Jan 24 19:26:02 2021 +0100 Make Tramp's insert-directory more robust * lisp/net/tramp-sh.el (tramp-sh-handle-insert-directory): Use `tramp-sh--quoting-style-options'. * test/lisp/net/tramp-tests.el (tramp--test-hpux-p, tramp--test-ksh-p): Remove superfluous nil. (tramp--test-sh-no-ls--dired-p): New defun. (tramp--test-special-characters): Use it. diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index d7ca7c9780..ed3d15377c 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -2617,11 +2617,8 @@ The method used must be an out-of-band method." filename switches wildcard full-directory-p) (when (stringp switches) (setq switches (split-string switches))) - (when (tramp-get-ls-command-with ;FIXME: tramp-sh--quoting-style-options? - v "--quoting-style=literal --show-control-chars") - (setq switches - (append - switches '("--quoting-style=literal" "--show-control-chars")))) + (setq switches + (append switches (split-string (tramp-sh--quoting-style-options v)))) (unless (tramp-get-ls-command-with v "--dired") (setq switches (delete "--dired" switches))) (when wildcard diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 4c84507807..7757c55c16 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -5720,16 +5720,16 @@ This requires restrictions of file name syntax." (tramp-find-foreign-file-name-handler tramp-test-temporary-file-directory) 'tramp-ftp-file-name-handler)) +(defun tramp--test-crypt-p () + "Check, whether the remote directory is crypted" + (tramp-crypt-file-name-p tramp-test-temporary-file-directory)) + (defun tramp--test-docker-p () "Check, whether the docker method is used. This does not support some special file names." (string-equal "docker" (file-remote-p tramp-test-temporary-file-directory 'method))) -(defun tramp--test-crypt-p () - "Check, whether the remote directory is crypted" - (tramp-crypt-file-name-p tramp-test-temporary-file-directory)) - (defun tramp--test-ftp-p () "Check, whether an FTP-like method is used. This does not support globbing characters in file names (yet)." @@ -5748,7 +5748,7 @@ If optional METHOD is given, it is checked first." "Check, whether the remote host runs HP-UX. Several special characters do not work properly there." ;; We must refill the cache. `file-truename' does it. - (file-truename tramp-test-temporary-file-directory) nil + (file-truename tramp-test-temporary-file-directory) (string-match-p "^HP-UX" (tramp-get-connection-property tramp-test-vec "uname" ""))) @@ -5757,7 +5757,7 @@ Several special characters do not work properly there." ksh93 makes some strange conversions of non-latin characters into a $'' syntax." ;; We must refill the cache. `file-truename' does it. - (file-truename tramp-test-temporary-file-directory) nil + (file-truename tramp-test-temporary-file-directory) (string-match-p "ksh$" (tramp-get-connection-property tramp-test-vec "remote-shell" ""))) @@ -5787,6 +5787,15 @@ This does not support special file names." "Check, whether the remote host runs a based method from tramp-sh.el." (tramp-sh-file-name-handler-p tramp-test-vec)) +(defun tramp--test-sh-no-ls--dired-p () + "Check, whether the remote host runs a based method from tramp-sh.el. +Additionally, ls does not support \"--dired\"." + (and (tramp--test-sh-p) + (with-temp-buffer + ;; We must refill the cache. `insert-directory' does it. + (insert-directory tramp-test-temporary-file-directory "-al") + (not (tramp-get-connection-property tramp-test-vec "ls--dired" nil))))) + (defun tramp--test-share-p () "Check, whether the method needs a share." (and (tramp--test-gvfs-p) @@ -6023,17 +6032,20 @@ This requires restrictions of file name syntax." ;; expanded to . (let ((files (list - (if (or (tramp--test-ange-ftp-p) - (tramp--test-gvfs-p) - (tramp--test-rclone-p) - (tramp--test-sudoedit-p) - (tramp--test-windows-nt-or-smb-p)) - "foo bar baz" - (if (or (tramp--test-adb-p) - (tramp--test-docker-p) - (eq system-type 'cygwin)) - " foo bar baz " - " foo\tbar baz\t")) + (cond ((or (tramp--test-ange-ftp-p) + (tramp--test-gvfs-p) + (tramp--test-rclone-p) + (tramp--test-sudoedit-p) + (tramp--test-windows-nt-or-smb-p)) + "foo bar baz") + ((or (tramp--test-adb-p) + (tramp--test-docker-p) + (eq system-type 'cygwin)) + " foo bar baz ") + ((tramp--test-sh-no-ls--dired-p) + "\tfoo bar baz\t") + (t " foo\tbar baz\t")) + "@foo@bar@baz@" "$foo$bar$$baz$" "-foo-bar-baz-" "%foo%bar%baz%" commit b26e09e0f02b94d72bddfb108a16daffb74139f6 Author: Eric Abrahamsen Date: Sun Jan 24 10:09:05 2021 -0800 Fix insertion logic of newly subscribed Gnus groups * lisp/gnus/gnus-start.el (gnus-subscribe-newsgroup): This was a misunderstanding of the next/previous argument: no group should ever be inserted before "dummy.group". (gnus-group-change-level): Make it clearer that PREVIOUS can be nil. In fact none of this code would error on a nil value, but it _looks_ like nil is unexpected. diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el index fbdbf41dc0..cf37a1ccdf 100644 --- a/lisp/gnus/gnus-start.el +++ b/lisp/gnus/gnus-start.el @@ -637,7 +637,7 @@ the first newsgroup." ;; We subscribe the group by changing its level to `subscribed'. (gnus-group-change-level newsgroup gnus-level-default-subscribed - gnus-level-killed (or next "dummy.group")) + gnus-level-killed next) (gnus-request-update-group-status newsgroup 'subscribe) (gnus-message 5 "Subscribe newsgroup: %s" newsgroup) (run-hook-with-args 'gnus-subscribe-newsgroup-functions newsgroup) @@ -1282,7 +1282,8 @@ string name) to insert this group before." (gnus-dribble-enter (format "(gnus-group-change-level %S %S %S %S %S)" group level oldlevel - (cadr (member previous gnus-group-list)) + (when previous + (cadr (member previous gnus-group-list))) fromkilled))) ;; Then we remove the newgroup from any old structures, if needed. @@ -1341,9 +1342,10 @@ string name) to insert this group before." ;; at the head of `gnus-newsrc-alist'. (push info (cdr gnus-newsrc-alist)) (puthash group (list num info) gnus-newsrc-hashtb) - (when (stringp previous) + (when (and previous (stringp previous)) (setq previous (gnus-group-entry previous))) - (let ((idx (or (seq-position gnus-group-list (caadr previous)) + (let ((idx (or (and previous + (seq-position gnus-group-list (caadr previous))) (length gnus-group-list)))) (push group (nthcdr idx gnus-group-list))) (gnus-dribble-enter commit d4dd12d3589559e61cdce978c40e1eb86a871266 Author: Philipp Stephani Date: Sun Jan 24 13:56:18 2021 +0100 Add more assertions to recently-added process test. * test/src/process-tests.el (process-tests/multiple-threads-waiting): Also check that 'thread-join' and 'thread-last-error' return the expected errors. diff --git a/test/src/process-tests.el b/test/src/process-tests.el index 676e1b1ac3..a3fba8d328 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -814,7 +814,8 @@ have written output." (cl-loop for process in processes and thread in threads do - (thread-join thread) + (should-not (thread-join thread)) + (should-not (thread-last-error)) (should (eq (process-status process) 'exit)) (should (eql (process-exit-status process) 0))))))) commit 809503431d47afb9d20e8463853298a595e1fcb2 Author: Dmitry Gutov Date: Sat Jan 23 02:58:53 2021 +0200 ; xref-revert-buffer: Drop the (goto-char) at the end (cherry picked from commit cc98d0bf5225c281f91152aa838c4cb093df52e9) diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 7f5e76c740..0b25110b79 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -884,8 +884,7 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (insert (propertize (error-message-string err) - 'face 'error)))) - (goto-char (point-min))))) + 'face 'error))))))) (defun xref--show-defs-buffer (fetcher alist) (let ((xrefs (funcall fetcher))) commit 0399cc2ab5cc64129d7e9030db7db76689e3a095 Author: Dmitry Gutov Date: Sat Jan 23 02:53:12 2021 +0200 Erase the buffer only after fetching the new contents * lisp/progmodes/xref.el (xref-revert-buffer): Erase the buffer only after fetching the new contents (bug#46042). (cherry picked from commit 5821dee0949b2913c07970d6e4b8bb8e8a35f036) diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index e55d295861..7f5e76c740 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -876,10 +876,10 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (let ((inhibit-read-only t) (buffer-undo-list t)) (save-excursion - (erase-buffer) (condition-case err - (xref--insert-xrefs - (xref--analyze (funcall xref--fetcher))) + (let ((alist (xref--analyze (funcall xref--fetcher)))) + (erase-buffer) + (xref--insert-xrefs alist)) (user-error (insert (propertize commit e1902ac6182b156efaaf93013a707abb4b627765 Author: Basil L. Contovounesios Date: Sat Jan 23 23:31:13 2021 +0000 Fix recently uncovered 'make check' failures For discussion, see the following thread: https://lists.gnu.org/r/emacs-devel/2021-01/msg01111.html * test/lisp/autorevert-tests.el (auto-revert-test07-auto-revert-several-buffers): * test/lisp/emacs-lisp/seq-tests.el (test-seq-do-indexed) (test-seq-random-elt-take-all): Fix errors from using add-to-list on lexical variables. * test/lisp/emacs-lisp/cl-lib-tests.el (cl-lib-defstruct-record): Expect test to succeed when byte-compiled following change of 2021-01-23 'Fix missing file&line info in "Unknown defun property" warnings'. (cl-lib-tests--dummy-function): Remove; no longer needed. (old-struct): Silence byte-compiler warning about unused lexical variable. diff --git a/test/lisp/autorevert-tests.el b/test/lisp/autorevert-tests.el index 683e3ea30d..45cf635396 100644 --- a/test/lisp/autorevert-tests.el +++ b/test/lisp/autorevert-tests.el @@ -609,11 +609,12 @@ This expects `auto-revert--messages' to be bound by (should auto-revert-mode)) (dotimes (i num-buffers) - (add-to-list - 'buffers - (make-indirect-buffer - (car buffers) (format "%s-%d" (buffer-file-name (car buffers)) i) 'clone) - 'append)) + (push (make-indirect-buffer + (car buffers) + (format "%s-%d" (buffer-file-name (car buffers)) i) + 'clone) + buffers)) + (setq buffers (nreverse buffers)) (dolist (buf buffers) (with-current-buffer buf (should (string-equal (buffer-string) "any text")) @@ -640,10 +641,10 @@ This expects `auto-revert--messages' to be bound by (auto-revert-tests--write-file "any text" tmpfile (pop times)) (dotimes (i num-buffers) - (add-to-list - 'buffers - (generate-new-buffer (format "%s-%d" (file-name-nondirectory tmpfile) i)) - 'append)) + (push (generate-new-buffer + (format "%s-%d" (file-name-nondirectory tmpfile) i)) + buffers)) + (setq buffers (nreverse buffers)) (dolist (buf buffers) (with-current-buffer buf (insert-file-contents tmpfile 'visit) diff --git a/test/lisp/emacs-lisp/cl-lib-tests.el b/test/lisp/emacs-lisp/cl-lib-tests.el index 97a44c43ef..065ca4fa65 100644 --- a/test/lisp/emacs-lisp/cl-lib-tests.el +++ b/test/lisp/emacs-lisp/cl-lib-tests.el @@ -543,15 +543,7 @@ (apply (lambda (x) (+ x 1)) (list 8))))) '(5 (6 5) (6 6) 9)))) -(defun cl-lib-tests--dummy-function () - ;; Dummy function to see if the file is compiled. - t) - (ert-deftest cl-lib-defstruct-record () - ;; This test fails when compiled, see Bug#24402/27718. - :expected-result (if (byte-code-function-p - (symbol-function 'cl-lib-tests--dummy-function)) - :failed :passed) (cl-defstruct foo x) (let ((x (make-foo :x 42))) (should (recordp x)) @@ -566,6 +558,7 @@ (should (eq (type-of x) 'vector)) (cl-old-struct-compat-mode 1) + (defvar cl-struct-foo) (let ((cl-struct-foo (cl--struct-get-class 'foo))) (setf (symbol-function 'cl-struct-foo) :quick-object-witness-check) (should (eq (type-of x) 'foo)) diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el index 670398354a..05c7fbe781 100644 --- a/test/lisp/emacs-lisp/seq-tests.el +++ b/test/lisp/emacs-lisp/seq-tests.el @@ -29,6 +29,9 @@ (require 'ert) (require 'seq) +(eval-when-compile + (require 'cl-lib)) + (defmacro with-test-sequences (spec &rest body) "Successively bind VAR to a list, vector, and string built from SEQ. Evaluate BODY for each created sequence. @@ -108,16 +111,12 @@ Evaluate BODY for each created sequence. '((a 0) (b 1) (c 2) (d 3))))) (ert-deftest test-seq-do-indexed () - (let ((result nil)) - (seq-do-indexed (lambda (elt i) - (add-to-list 'result (list elt i))) - nil) - (should (equal result nil))) + (let (result) + (seq-do-indexed (lambda (elt i) (push (list elt i) result)) ()) + (should-not result)) (with-test-sequences (seq '(4 5 6)) - (let ((result nil)) - (seq-do-indexed (lambda (elt i) - (add-to-list 'result (list elt i))) - seq) + (let (result) + (seq-do-indexed (lambda (elt i) (push (list elt i) result)) seq) (should (equal (seq-elt result 0) '(6 2))) (should (equal (seq-elt result 1) '(5 1))) (should (equal (seq-elt result 2) '(4 0)))))) @@ -410,12 +409,10 @@ Evaluate BODY for each created sequence. (ert-deftest test-seq-random-elt-take-all () (let ((seq '(a b c d e)) - (elts '())) - (should (= 0 (length elts))) + elts) (dotimes (_ 1000) (let ((random-elt (seq-random-elt seq))) - (add-to-list 'elts - random-elt))) + (cl-pushnew random-elt elts))) (should (= 5 (length elts))))) (ert-deftest test-seq-random-elt-signal-on-empty () commit 7cc970e7e3939672ec8ae490fff8300395e16b76 Author: Jean Louis Date: Sun Jan 24 00:34:44 2021 +0100 Add support for dired compressing .lz/.lzo files * lisp/dired-aux.el (dired-compress-files-alist): Add support for .lz/.lzo files (bug#44901). diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index f860743a06..c765e4be45 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -1168,6 +1168,8 @@ ARGS are command switches passed to PROGRAM.") ("\\.tar\\.bz2\\'" . "tar -cf - %i | bzip2 -c9 > %o") ("\\.tar\\.xz\\'" . "tar -cf - %i | xz -c9 > %o") ("\\.tar\\.zst\\'" . "tar -cf - %i | zstd -19 -o %o") + ("\\.tar\\.lz\\'" . "tar -cf - %i | lzip -c9 > %o") + ("\\.tar\\.lzo\\'" . "tar -cf - %i | lzop -c9 > %o") ("\\.zip\\'" . "zip %o -r --filesync %i") ("\\.pax\\'" . "pax -wf %o %i")) "Control the compression shell command for `dired-do-compress-to'. commit 0ebf9d6cef211a3eddcf035aa8494d95ab7a2649 Author: Eric Abrahamsen Date: Sat Jan 23 14:24:09 2021 -0800 Properly initialize gnus-search-namazu-index-directory * lisp/gnus/gnus-search.el (gnus-search-namazu): We were missing the appropriate :initform on this slot definition (Bug#46047). diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el index 5c6a5b9efd..44780609af 100644 --- a/lisp/gnus/gnus-search.el +++ b/lisp/gnus/gnus-search.el @@ -909,6 +909,7 @@ quirks.") (defclass gnus-search-namazu (gnus-search-indexed) ((index-directory :initarg :index-directory + :initform (symbol-value 'gnus-search-namazu-index-directory) :type string :custom directory) (program commit 75f6b264f549ee66faae75bfbad4d3f7602e2a64 Author: Lars Ingebrigtsen Date: Sat Jan 23 23:12:05 2021 +0100 Make (subdirs . nil) in .dir-locals.el work * lisp/files.el (dir-locals-collect-variables): Don't destructively modify the cached structure (bug#17205), because that means that (subdirs . nil) doesn't work. diff --git a/lisp/files.el b/lisp/files.el index d2e5413b3a..7af5549bcb 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -4062,7 +4062,7 @@ Return the new variables list." (subdirs (assq 'subdirs alist))) (if (or (not subdirs) (progn - (setq alist (delq subdirs alist)) + (setq alist (remq subdirs alist)) (cdr-safe subdirs)) ;; TODO someone might want to extend this to allow ;; integer values for subdir, where N means commit 1559cc445a306b61b2a47c710e049ea26fe5265d Author: Stefan Monnier Date: Sat Jan 23 16:04:36 2021 -0500 Fix missing file&line info in "Unknown defun property" warnings * lisp/emacs-lisp/byte-run.el (defmacro, defun): Use `macroexp--warn-and-return` rather than `message`. * lisp/emacs-lisp/macroexp.el: Fix `macroexp--compiling-p`. (macroexp--warn-and-return): Don't try and detect repetition on forms like `nil`. (macroexp-macroexpand): Don't forget to bind `macroexpand-all-environment`. diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index 0f8dd5a284..88f362d24f 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el @@ -232,8 +232,11 @@ The return value is undefined. #'(lambda (x) (let ((f (cdr (assq (car x) macro-declarations-alist)))) (if f (apply (car f) name arglist (cdr x)) - (message "Warning: Unknown macro property %S in %S" - (car x) name)))) + (macroexp--warn-and-return + (format-message + "Unknown macro property %S in %S" + (car x) name) + nil)))) decls))) ;; Refresh font-lock if this is a new macro, or it is an ;; existing macro whose 'no-font-lock-keyword declaration @@ -301,9 +304,12 @@ The return value is undefined. (cdr body) body))) nil) - (t (message "Warning: Unknown defun property `%S' in %S" - (car x) name))))) - decls)) + (t + (macroexp--warn-and-return + (format-message "Unknown defun property `%S' in %S" + (car x) name) + nil))))) + decls)) (def (list 'defalias (list 'quote name) (list 'function diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index 37844977f8..aa49bccc8d 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -127,7 +127,7 @@ and also to avoid outputting the warning during normal execution." (cond ((null msg) form) ((macroexp--compiling-p) - (if (gethash form macroexp--warned) + (if (and (consp form) (gethash form macroexp--warned)) ;; Already wrapped this exp with a warning: avoid inf-looping ;; where we keep adding the same warning onto `form' because ;; macroexpand-all gets right back to macroexpanding `form'. @@ -138,9 +138,10 @@ and also to avoid outputting the warning during normal execution." ,form))) (t (unless compile-only - (message "%s%s" (if (stringp load-file-name) - (concat (file-relative-name load-file-name) ": ") - "") + (message "%sWarning: %s" + (if (stringp load-file-name) + (concat (file-relative-name load-file-name) ": ") + "") msg)) form)))) @@ -180,8 +181,9 @@ and also to avoid outputting the warning during normal execution." (defun macroexp-macroexpand (form env) "Like `macroexpand' but checking obsolescence." - (let ((new-form - (macroexpand form env))) + (let* ((macroexpand-all-environment env) + (new-form + (macroexpand form env))) (if (and (not (eq form new-form)) ;It was a macro call. (car-safe form) (symbolp (car form)) commit b7068be5c410c5592856aeebd7aa4d62b1dc68e5 Author: Lars Ingebrigtsen Date: Sat Jan 23 20:39:45 2021 +0100 Provide a (thing-at-point 'url) in eww buffers * lisp/net/eww.el (eww-mode): Allow (thing-at-point 'url) to work in eww buffers. (eww--url-at-point): New function. diff --git a/lisp/net/eww.el b/lisp/net/eww.el index d131b2bf8c..e39a4c33b2 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -1050,9 +1050,16 @@ the like." ;; multi-page isearch support (setq-local multi-isearch-next-buffer-function #'eww-isearch-next-buffer) (setq truncate-lines t) + (setq-local thing-at-point-provider-alist + (append thing-at-point-provider-alist + '((url . eww--url-at-point)))) (buffer-disable-undo) (setq buffer-read-only t)) +(defun eww--url-at-point () + "`thing-at-point' provider function." + (get-text-property (point) 'shr-url)) + ;;;###autoload (defun eww-browse-url (url &optional new-window) "Ask the EWW browser to load URL. commit 259edd435e0c02c3c906e8b34e7ece37724ccf11 Author: Lars Ingebrigtsen Date: Sat Jan 23 20:38:54 2021 +0100 Add a mechanism for buffer-local thing-at-points * doc/lispref/text.texi (Buffer Contents): Document it. * lisp/thingatpt.el (thing-at-point-provider-alist): New variable. (thing-at-point): Use it. diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 35bc6f9f16..14854a5aaf 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -334,6 +334,25 @@ but there is no peace. (thing-at-point 'whitespace) @result{} nil @end example + +@defvar thing-at-point-provider-alist +This variable allows users and modes to tweak how +@code{thing-at-point} works. It's an association list of @var{thing}s +and functions (called with zero parameters) to return that thing. +Entries for @var{thing} will be evaluated in turn until a +non-@code{nil} result is returned. + +For instance, a major mode could say: + +@lisp +(setq-local thing-at-point-provider-alist + (append thing-at-point-provider-alist + '((url . my-mode--url-at-point)))) +@end lisp + +If no providers have a non-@code{nil} return, the @var{thing} will be +computed the standard way. +@end defvar @end defun @node Comparing Text diff --git a/etc/NEWS b/etc/NEWS index 357c75b7e9..6a80493e23 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1564,6 +1564,12 @@ that makes it a valid button. *** New macro `named-let` that provides Scheme's "named let" looping construct +** thingatpt + ++++ +*** New variable 'thing-at-point-provider-alist'. +This allows mode-specific alterations to how `thing-at-point' works. + ** Miscellaneous --- diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el index 67d4092d40..c52fcfcc05 100644 --- a/lisp/thingatpt.el +++ b/lisp/thingatpt.el @@ -52,8 +52,30 @@ ;;; Code: +(require 'cl-lib) (provide 'thingatpt) +(defvar thing-at-point-provider-alist nil + "Alist of providers for returning a \"thing\" at point. +This variable can be set globally, or appended to buffer-locally +by modes, to provide functions that will return a \"thing\" at +point. The first provider for the \"thing\" that returns a +non-nil value wins. + +For instance, a major mode could say: + +\(setq-local thing-at-point-provider-alist + (append thing-at-point-provider-alist + \\='((url . my-mode--url-at-point)))) + +to provide a way to get an `url' at point in that mode. The +provider functions are called with no parameters at the point in +question. + +\"things\" include `symbol', `list', `sexp', `defun', `filename', +`url', `email', `uuid', `word', `sentence', `whitespace', `line', +and `page'.") + ;; Basic movement ;;;###autoload @@ -143,11 +165,18 @@ strip text properties from the return value. See the file `thingatpt.el' for documentation on how to define a symbol as a valid THING." (let ((text - (if (get thing 'thing-at-point) - (funcall (get thing 'thing-at-point)) + (cond + ((cl-loop for (pthing . function) in thing-at-point-provider-alist + when (eq pthing thing) + for result = (funcall function) + when result + return result)) + ((get thing 'thing-at-point) + (funcall (get thing 'thing-at-point))) + (t (let ((bounds (bounds-of-thing-at-point thing))) (when bounds - (buffer-substring (car bounds) (cdr bounds))))))) + (buffer-substring (car bounds) (cdr bounds)))))))) (when (and text no-properties (sequencep text)) (set-text-properties 0 (length text) nil text)) text)) commit 7c9841b8428edfbc369eccf54788b668d4b27328 Author: Paul Eggert Date: Sat Jan 23 11:35:44 2021 -0800 Update from Gnulib by running admin/merge-gnulib diff --git a/lib/cdefs.h b/lib/cdefs.h index de74f4211c..17a0919cd8 100644 --- a/lib/cdefs.h +++ b/lib/cdefs.h @@ -320,14 +320,16 @@ #endif /* The nonnull function attribute marks pointer parameters that - must not be NULL. Do not define __nonnull if it is already defined, - for portability when this file is used in Gnulib. */ + must not be NULL. */ #ifndef __nonnull # if __GNUC_PREREQ (3,3) || __glibc_has_attribute (__nonnull__) # define __nonnull(params) __attribute__ ((__nonnull__ params)) # else # define __nonnull(params) # endif +#elif !defined __GLIBC__ +# undef __nonnull +# define __nonnull(params) _GL_ATTRIBUTE_NONNULL (params) #endif /* If fortification mode, we warn about unused results of certain diff --git a/lib/explicit_bzero.c b/lib/explicit_bzero.c index feea4446c0..f50ed0875d 100644 --- a/lib/explicit_bzero.c +++ b/lib/explicit_bzero.c @@ -54,11 +54,21 @@ explicit_bzero (void *s, size_t len) explicit_memset (s, '\0', len); #elif HAVE_MEMSET_S (void) memset_s (s, len, '\0', len); -#else +#elif defined __GNUC__ && !defined __clang__ memset (s, '\0', len); -# if defined __GNUC__ && !defined __clang__ /* Compiler barrier. */ asm volatile ("" ::: "memory"); -# endif +#elif defined __clang__ + memset (s, '\0', len); + /* Compiler barrier. */ + /* With asm ("" ::: "memory") LLVM analyzes uses of 's' and finds that the + whole thing is dead and eliminates it. Use 'g' to work around this + problem. See . */ + __asm__ volatile ("" : : "g"(s) : "memory"); +#else + /* Invoke memset through a volatile function pointer. This defeats compiler + optimizations. */ + void * (* const volatile volatile_memset) (void *, int, size_t) = memset; + (void) volatile_memset (s, '\0', len); #endif } commit 30d95d33737e4694b579c38328564716d10217b6 Author: Gabriel do Nascimento Ribeiro Date: Sat Jan 23 15:38:42 2021 -0300 Use single post-command-hook on hl-line modes * lisp/hl-line.el (hl-line-mode, global-hl-line-mode): Ensure that 'maybe-unhighlight' is called after line is highlighted. (Bug#45946) (hl-line-unhighlight, global-hl-line-unhighlight): Set overlay variable to nil after overlay is deleted. diff --git a/lisp/hl-line.el b/lisp/hl-line.el index 73870f9579..82952e934b 100644 --- a/lisp/hl-line.el +++ b/lisp/hl-line.el @@ -45,11 +45,7 @@ ;; An overlay is used. In the non-sticky cases, this overlay is ;; active only on the selected window. A hook is added to ;; `post-command-hook' to activate the overlay and move it to the line -;; about point. To get the non-sticky behavior, `hl-line-unhighlight' -;; is added to `pre-command-hook' as well. This function deactivates -;; the overlay unconditionally in case the command changes the -;; selected window. (It does so rather than keeping track of changes -;; in the selected window). +;; about point. ;; You could make variable `global-hl-line-mode' buffer-local and set ;; it to nil to avoid highlighting specific buffers, when the global @@ -91,9 +87,9 @@ when `global-hl-line-sticky-flag' is non-nil.") (set symbol value) (dolist (buffer (buffer-list)) (with-current-buffer buffer - (when hl-line-overlay + (when (overlayp hl-line-overlay) (overlay-put hl-line-overlay 'face hl-line-face)))) - (when global-hl-line-overlay + (when (overlayp global-hl-line-overlay) (overlay-put global-hl-line-overlay 'face hl-line-face)))) (defcustom hl-line-sticky-flag t @@ -141,9 +137,7 @@ non-selected window. Hl-Line mode uses the function `hl-line-highlight' on `post-command-hook' in this case. When `hl-line-sticky-flag' is nil, Hl-Line mode highlights the -line about point in the selected window only. In this case, it -uses the function `hl-line-maybe-unhighlight' in -addition to `hl-line-highlight' on `post-command-hook'." +line about point in the selected window only." :group 'hl-line (if hl-line-mode (progn @@ -151,12 +145,10 @@ addition to `hl-line-highlight' on `post-command-hook'." (add-hook 'change-major-mode-hook #'hl-line-unhighlight nil t) (hl-line-highlight) (setq hl-line-overlay-buffer (current-buffer)) - (add-hook 'post-command-hook #'hl-line-highlight nil t) - (add-hook 'post-command-hook #'hl-line-maybe-unhighlight nil t)) + (add-hook 'post-command-hook #'hl-line-highlight nil t)) (remove-hook 'post-command-hook #'hl-line-highlight t) (hl-line-unhighlight) - (remove-hook 'change-major-mode-hook #'hl-line-unhighlight t) - (remove-hook 'post-command-hook #'hl-line-maybe-unhighlight t))) + (remove-hook 'change-major-mode-hook #'hl-line-unhighlight t))) (defun hl-line-make-overlay () (let ((ol (make-overlay (point) (point)))) @@ -168,17 +160,19 @@ addition to `hl-line-highlight' on `post-command-hook'." "Activate the Hl-Line overlay on the current line." (if hl-line-mode ; Might be changed outside the mode function. (progn - (unless hl-line-overlay + (unless (overlayp hl-line-overlay) (setq hl-line-overlay (hl-line-make-overlay))) ; To be moved. (overlay-put hl-line-overlay 'window (unless hl-line-sticky-flag (selected-window))) - (hl-line-move hl-line-overlay)) + (hl-line-move hl-line-overlay) + (hl-line-maybe-unhighlight)) (hl-line-unhighlight))) (defun hl-line-unhighlight () "Deactivate the Hl-Line overlay on the current line." - (when hl-line-overlay - (delete-overlay hl-line-overlay))) + (when (overlayp hl-line-overlay) + (delete-overlay hl-line-overlay) + (setq hl-line-overlay nil))) (defun hl-line-maybe-unhighlight () "Maybe deactivate the Hl-Line overlay on the current line. @@ -191,8 +185,7 @@ such overlays in all buffers except the current one." (not (eq curbuf hlob)) (not (minibufferp))) (with-current-buffer hlob - (when (overlayp hl-line-overlay) - (delete-overlay hl-line-overlay)))) + (hl-line-unhighlight))) (when (and (overlayp hl-line-overlay) (eq (overlay-buffer hl-line-overlay) curbuf)) (setq hl-line-overlay-buffer curbuf)))) @@ -205,8 +198,8 @@ If `global-hl-line-sticky-flag' is non-nil, Global Hl-Line mode highlights the line about the current buffer's point in all live windows. -Global-Hl-Line mode uses the functions `global-hl-line-highlight' -and `global-hl-line-maybe-unhighlight' on `post-command-hook'." +Global-Hl-Line mode uses the function `global-hl-line-highlight' +on `post-command-hook'." :global t :group 'hl-line (if global-hl-line-mode @@ -214,25 +207,24 @@ and `global-hl-line-maybe-unhighlight' on `post-command-hook'." ;; In case `kill-all-local-variables' is called. (add-hook 'change-major-mode-hook #'global-hl-line-unhighlight) (global-hl-line-highlight-all) - (add-hook 'post-command-hook #'global-hl-line-highlight) - (add-hook 'post-command-hook #'global-hl-line-maybe-unhighlight)) + (add-hook 'post-command-hook #'global-hl-line-highlight)) (global-hl-line-unhighlight-all) (remove-hook 'post-command-hook #'global-hl-line-highlight) - (remove-hook 'change-major-mode-hook #'global-hl-line-unhighlight) - (remove-hook 'post-command-hook #'global-hl-line-maybe-unhighlight))) + (remove-hook 'change-major-mode-hook #'global-hl-line-unhighlight))) (defun global-hl-line-highlight () "Highlight the current line in the current window." (when global-hl-line-mode ; Might be changed outside the mode function. (unless (window-minibuffer-p) - (unless global-hl-line-overlay + (unless (overlayp global-hl-line-overlay) (setq global-hl-line-overlay (hl-line-make-overlay))) ; To be moved. (unless (member global-hl-line-overlay global-hl-line-overlays) (push global-hl-line-overlay global-hl-line-overlays)) (overlay-put global-hl-line-overlay 'window (unless global-hl-line-sticky-flag (selected-window))) - (hl-line-move global-hl-line-overlay)))) + (hl-line-move global-hl-line-overlay) + (global-hl-line-maybe-unhighlight)))) (defun global-hl-line-highlight-all () "Highlight the current line in all live windows." @@ -243,8 +235,9 @@ and `global-hl-line-maybe-unhighlight' on `post-command-hook'." (defun global-hl-line-unhighlight () "Deactivate the Global-Hl-Line overlay on the current line." - (when global-hl-line-overlay - (delete-overlay global-hl-line-overlay))) + (when (overlayp global-hl-line-overlay) + (delete-overlay global-hl-line-overlay) + (setq global-hl-line-overlay nil))) (defun global-hl-line-maybe-unhighlight () "Maybe deactivate the Global-Hl-Line overlay on the current line. @@ -256,9 +249,8 @@ all such overlays in all buffers except the current one." (bufferp ovb) (not (eq ovb (current-buffer))) (not (minibufferp))) - (with-current-buffer ovb - (when (overlayp global-hl-line-overlay) - (delete-overlay global-hl-line-overlay)))))) + (with-current-buffer ovb + (global-hl-line-unhighlight))))) global-hl-line-overlays)) (defun global-hl-line-unhighlight-all () commit d860ca98ccb4ff9ff3b2348c3a7156ef010f2284 Author: Eli Zaretskii Date: Sat Jan 23 21:04:13 2021 +0200 ; * src/process.c (child_signal_read): Remove FIXME comment. diff --git a/src/process.c b/src/process.c index 8abdcd4f0c..1df4ed9ce0 100644 --- a/src/process.c +++ b/src/process.c @@ -291,7 +291,6 @@ static int child_signal_read_fd = -1; static int child_signal_write_fd = -1; static void child_signal_init (void); #ifndef WINDOWSNT -/* FIXME: This is never used, on all platforms. */ static void child_signal_read (int, void *); #endif static void child_signal_notify (void); commit 8dcb19fc5e3afee7a951194a892f4731bee8ed31 Author: Philipp Stephani Date: Sat Jan 23 19:10:22 2021 +0100 Add a unit test testing interaction between threads and processes. This unit test tests that we can call 'accept-process-output' in parallel from multiple threads. * test/src/process-tests.el (process-tests/multiple-threads-waiting): New unit test. diff --git a/test/src/process-tests.el b/test/src/process-tests.el index 949f73595b..676e1b1ac3 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -789,6 +789,35 @@ have written output." (should (equal calls (list (list process "finished\n")))))))))) +(ert-deftest process-tests/multiple-threads-waiting () + (skip-unless (fboundp 'make-thread)) + (with-timeout (60 (ert-fail "Test timed out")) + (process-tests--with-processes processes + (let ((threads ()) + (cat (executable-find "cat"))) + (skip-unless cat) + (dotimes (i 10) + (let* ((name (format "test %d" i)) + (process (make-process :name name + :command (list cat) + :coding 'no-conversion + :noquery t + :connection-type 'pipe))) + (push process processes) + (set-process-thread process nil) + (push (make-thread + (lambda () + (while (accept-process-output process))) + name) + threads))) + (mapc #'process-send-eof processes) + (cl-loop for process in processes + and thread in threads + do + (thread-join thread) + (should (eq (process-status process) 'exit)) + (should (eql (process-exit-status process) 0))))))) + (defun process-tests--eval (command form) "Return a command that evaluates FORM in an Emacs subprocess. COMMAND must be a list returned by commit 17fec603709eb879297a4a0ff0c535c00a13066b Author: Philipp Stephani Date: Sat Jan 23 19:08:52 2021 +0100 Avoid a few compilation warnings in Objective-C code. * src/nsfns.m (Fns_frame_restack): Remove unused variable 'flag'. * src/nsmenu.m (ns_update_menubar): Remove unused variable 'pool'. * src/nsterm.m (focus_view, hide_bell): Define conditionally. (ns_update_end): Define variable 'view' conditionally. (ns_redraw_scroll_bars): Don't define unused function. (copyRect): Don't perform arithmetic on 'void' pointers. (nswindow_orderedIndex_sort): Make static. diff --git a/src/nsfns.m b/src/nsfns.m index ae114f83e4..24ea7d7f63 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -1487,7 +1487,6 @@ Frames are listed from topmost (first) to bottommost (last). */) { EmacsWindow *window = (EmacsWindow *)[FRAME_NS_VIEW (f1) window]; NSWindow *window2 = [FRAME_NS_VIEW (f2) window]; - BOOL flag = !NILP (above); if ([window restackWindow:window2 above:!NILP (above)]) return Qt; diff --git a/src/nsmenu.m b/src/nsmenu.m index 8086f56854..f8219d2702 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -101,7 +101,6 @@ static void ns_update_menubar (struct frame *f, bool deep_p) { - NSAutoreleasePool *pool; BOOL needsSet = NO; id menu = [NSApp mainMenu]; bool owfi; diff --git a/src/nsterm.m b/src/nsterm.m index c5815ce8d1..df3934c5c3 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -272,7 +272,9 @@ - (NSColor *)colorUsingDefaultColorSpace /* display update */ static struct frame *ns_updating_frame; +#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 static NSView *focus_view = NULL; +#endif static int ns_window_num = 0; static BOOL gsaved = NO; static BOOL ns_fake_keydown = NO; @@ -1139,7 +1141,9 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen) external (RIF) call; for whole frame, called after gui_update_window_end -------------------------------------------------------------------------- */ { +#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 EmacsView *view = FRAME_NS_VIEW (f); +#endif NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_end"); @@ -1449,7 +1453,7 @@ -(void)remove } } - +#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 static void hide_bell (void) /* -------------------------------------------------------------------------- @@ -1463,6 +1467,7 @@ -(void)remove [bell_view remove]; } } +#endif /* ========================================================================== @@ -2876,6 +2881,8 @@ so some key presses (TAB) are swallowed by the system. */ ========================================================================== */ +#if 0 +/* FIXME: Remove this function. */ static void ns_redraw_scroll_bars (struct frame *f) { @@ -2890,6 +2897,7 @@ so some key presses (TAB) are swallowed by the system. */ [view display]; } } +#endif void @@ -8399,21 +8407,23 @@ - (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect void *pixels = CGBitmapContextGetData (context); int rowSize = CGBitmapContextGetBytesPerRow (context); int srcRowSize = NSWidth (srcRect) * scale * bpp; - void *srcPixels = pixels + (int)(NSMinY (srcRect) * scale * rowSize - + NSMinX (srcRect) * scale * bpp); - void *dstPixels = pixels + (int)(NSMinY (dstRect) * scale * rowSize - + NSMinX (dstRect) * scale * bpp); + void *srcPixels = (char *) pixels + + (int) (NSMinY (srcRect) * scale * rowSize + + NSMinX (srcRect) * scale * bpp); + void *dstPixels = (char *) pixels + + (int) (NSMinY (dstRect) * scale * rowSize + + NSMinX (dstRect) * scale * bpp); if (NSIntersectsRect (srcRect, dstRect) && NSMinY (srcRect) < NSMinY (dstRect)) for (int y = NSHeight (srcRect) * scale - 1 ; y >= 0 ; y--) - memmove (dstPixels + y * rowSize, - srcPixels + y * rowSize, + memmove ((char *) dstPixels + y * rowSize, + (char *) srcPixels + y * rowSize, srcRowSize); else for (int y = 0 ; y < NSHeight (srcRect) * scale ; y++) - memmove (dstPixels + y * rowSize, - srcPixels + y * rowSize, + memmove ((char *) dstPixels + y * rowSize, + (char *) srcPixels + y * rowSize, srcRowSize); #if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 @@ -8742,7 +8752,8 @@ - (void)makeKeyAndOrderFront:(id)sender /* The array returned by [NSWindow parentWindow] may already be sorted, but the documentation doesn't tell us whether or not it is, so to be safe we'll sort it. */ -NSInteger nswindow_orderedIndex_sort (id w1, id w2, void *c) +static NSInteger +nswindow_orderedIndex_sort (id w1, id w2, void *c) { NSInteger i1 = [w1 orderedIndex]; NSInteger i2 = [w2 orderedIndex]; commit 27a023d02928366f52ab8d5e5c398ef080483523 Author: Philipp Stephani Date: Sat Jan 23 19:04:53 2021 +0100 * .clang-format: Fix base style. diff --git a/.clang-format b/.clang-format index 9ab09a86ff..44200a3995 100644 --- a/.clang-format +++ b/.clang-format @@ -1,5 +1,5 @@ Language: Cpp -BasedOnStyle: LLVM +BasedOnStyle: GNU AlignEscapedNewlinesLeft: true AlwaysBreakAfterReturnType: TopLevelDefinitions BreakBeforeBinaryOperators: All commit 59e9ec72442d264a3e08c9886ad3b49fa8dc9f37 Author: Philipp Stephani Date: Sat Jan 23 18:39:20 2021 +0100 Add a FIXME comment to improve the SIGCHLD race condition handling. * src/process.c: Add FIXME comment describing how we could avoid the self-pipe on modern Unix-like systems. diff --git a/src/process.c b/src/process.c index 9b1de19f0a..8abdcd4f0c 100644 --- a/src/process.c +++ b/src/process.c @@ -7164,6 +7164,11 @@ process has been transmitted to the serial port. */) because that emulation delays the delivery of the simulated SIGCHLD until all the output from the subprocess has been consumed. */ +/* FIXME: On Unix-like systems that have a proper 'pselect' + (HAVE_PSELECT), we should block SIGCHLD in + 'wait_reading_process_output' and pass a non-NULL signal mask to + 'pselect' to avoid the need for the self-pipe. */ + /* Set up `child_signal_read_fd' and `child_signal_write_fd'. */ static void commit aeff424c555da7e80775482db84eecef10286fc3 Author: Philipp Stephani Date: Sat Jan 23 17:24:34 2021 +0100 Mark both ends of self-pipe a nonblocking. While no deadlocks caused by the blocking write end have been reported yet, marking both ends nonblocking is consistent and also recommended in the GNU/Linux manpage of 'select'. * src/process.c (child_signal_init): Mark write end of self-pipe as nonblocking. diff --git a/src/process.c b/src/process.c index 697d9b0b19..9b1de19f0a 100644 --- a/src/process.c +++ b/src/process.c @@ -7195,6 +7195,8 @@ child_signal_init (void) eassert (0 <= fds[1]); if (fcntl (fds[0], F_SETFL, O_NONBLOCK) != 0) emacs_perror ("fcntl"); + if (fcntl (fds[1], F_SETFL, O_NONBLOCK) != 0) + emacs_perror ("fcntl"); add_read_fd (fds[0], child_signal_read, NULL); fd_callback_info[fds[0]].flags &= ~KEYBOARD_FD; child_signal_read_fd = fds[0]; commit 6a6fde0375d499a418f81a0dafe803d6cb0d4c97 Author: Michael Albinus Date: Sat Jan 23 16:59:07 2021 +0100 Fix failed autorevert test on emba * test/lisp/autorevert-tests.el (auto-revert-test05-global-notify): Check, whether buffer is alive. diff --git a/test/lisp/autorevert-tests.el b/test/lisp/autorevert-tests.el index 6da515bb2c..683e3ea30d 100644 --- a/test/lisp/autorevert-tests.el +++ b/test/lisp/autorevert-tests.el @@ -524,8 +524,10 @@ This expects `auto-revert--messages' to be bound by (auto-revert-test--write-file "1-b" file-1) (auto-revert-test--wait-for-buffer-text buf-1 "1-b" (auto-revert--timeout)) - (should (buffer-local-value - 'auto-revert-notify-watch-descriptor buf-1)) + ;; On emba, `buf-1' is a killed buffer. + (when (buffer-live-p buf-1) + (should (buffer-local-value + 'auto-revert-notify-watch-descriptor buf-1))) ;; Write a buffer to a new file, then modify the new file on disk. (with-current-buffer buf-2 commit f0517ab9c2e140d306fea6285589a1c02dac5064 Author: Michael Albinus Date: Sat Jan 23 12:13:03 2021 +0100 * test/infra/gitlab-ci.yml (.job-template): Check also for test/lib-src/*.el. diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml index 2f71d12bdb..5a0ab54e4b 100644 --- a/test/infra/gitlab-ci.yml +++ b/test/infra/gitlab-ci.yml @@ -72,6 +72,7 @@ default: - lisp/**/*.el - src/*.{h,c} - test/infra/* + - test/lib-src/*.el - test/lisp/**/*.el - test/src/*.el - changes: commit 8d8e1dfd05fd79859e8206de0e89329b0d862ce1 Author: Eli Zaretskii Date: Sat Jan 23 12:51:57 2021 +0200 Clean up the recently added self-pipe mechanism for WINDOWSNT * src/process.c (child_signal_init, child_signal_read) (child_signal_notify): #ifdef away on WINDOWSNT. diff --git a/src/process.c b/src/process.c index 57105982c1..697d9b0b19 100644 --- a/src/process.c +++ b/src/process.c @@ -290,7 +290,10 @@ static int child_signal_read_fd = -1; status changes. */ static int child_signal_write_fd = -1; static void child_signal_init (void); +#ifndef WINDOWSNT +/* FIXME: This is never used, on all platforms. */ static void child_signal_read (int, void *); +#endif static void child_signal_notify (void); /* Indexed by descriptor, gives the process (if any) for that descriptor. */ @@ -7148,8 +7151,18 @@ process has been transmitted to the serial port. */) have the same process ID. To avoid a deadlock when receiving SIGCHLD while - `wait_reading_process_output' is in `pselect', the SIGCHLD handler - will notify the `pselect' using a pipe. */ + 'wait_reading_process_output' is in 'pselect', the SIGCHLD handler + will notify the `pselect' using a self-pipe. The deadlock could + occur if SIGCHLD is delivered outside of the 'pselect' call, in + which case 'pselect' will not be interrupted by the signal, and + will therefore wait on the process's output descriptor for the + output that will never come. + + WINDOWSNT doesn't need this facility because its 'pselect' + emulation (see 'sys_select' in w32proc.c) waits on a subprocess + handle, which becomes signaled when the process exits, and also + because that emulation delays the delivery of the simulated SIGCHLD + until all the output from the subprocess has been consumed. */ /* Set up `child_signal_read_fd' and `child_signal_write_fd'. */ @@ -7159,6 +7172,7 @@ child_signal_init (void) /* Either both are initialized, or both are uninitialized. */ eassert ((child_signal_read_fd < 0) == (child_signal_write_fd < 0)); +#ifndef WINDOWSNT if (0 <= child_signal_read_fd) return; /* already done */ @@ -7185,8 +7199,10 @@ child_signal_init (void) fd_callback_info[fds[0]].flags &= ~KEYBOARD_FD; child_signal_read_fd = fds[0]; child_signal_write_fd = fds[1]; +#endif /* !WINDOWSNT */ } +#ifndef WINDOWSNT /* Consume a process status change. */ static void @@ -7198,6 +7214,7 @@ child_signal_read (int fd, void *data) if (emacs_read (fd, &dummy, 1) < 0) emacs_perror ("reading from child signal FD"); } +#endif /* !WINDOWSNT */ /* Notify `wait_reading_process_output' of a process status change. */ @@ -7205,11 +7222,13 @@ child_signal_read (int fd, void *data) static void child_signal_notify (void) { +#ifndef WINDOWSNT int fd = child_signal_write_fd; eassert (0 <= fd); char dummy = 0; if (emacs_write (fd, &dummy, 1) != 1) emacs_perror ("writing to child signal FD"); +#endif } /* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing commit 3443a1c698790fca0481178f08dcb45cca576a30 Author: Eli Zaretskii Date: Sat Jan 23 11:28:32 2021 +0200 Fix last change * doc/lispref/text.texi (Undo): Add a cross-reference to the description of 'undo-amalgamate-change-group'. (Atomic Changes): Expand and improve the description of 'undo-amalgamate-change-group'. (Bug#42303) diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 5eead42031..89582acd35 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -1422,6 +1422,11 @@ the @code{amalgamating-undo-limit} variable. If this variable is 1, no changes are amalgamated. @end defun +A Lisp program can amalgamate a series of changes into a single change +group by calling @code{undo-amalgamate-change-group} (@pxref{Atomic +Changes}). Note that @code{amalgamating-undo-limit} has no effect on +the groups produced by that function. + @defvar undo-auto-current-boundary-timer Some buffers, such as process buffers, can change even when no commands are executing. In these cases, @code{undo-boundary} is @@ -5561,9 +5566,17 @@ This function cancels and undoes all the changes in the change group specified by @var{handle}. @end defun + You can cause some or all of the changes in a change group to be +considered as a single unit for the purposes of the @code{undo} +commands (@pxref{Undo}) by using @code{undo-amalgamate-change-group}. + @defun undo-amalgamate-change-group -Amalgamate changes in change-group since @var{handle}. I.e., remove -all undo boundaries between the state of @var{handle} and now. +Amalgamate all the changes made in the change-group since the state +identified by @var{handle}. This function removes all undo boundaries +between undo records of changes since the state described by +@var{handle}. Usually, @var{handle} is the handle returned by +@code{prepare-change-group}, in which case all the changes since the +beginning of the change-group are amalgamated into a single undo unit. @end defun Your code should use @code{unwind-protect} to make sure the group is commit c8fa056a50586429be37fc5bfde8226c4b6cefa2 Author: Lars Ingebrigtsen Date: Fri Jan 22 21:07:35 2021 +0100 Mention undo-amalgamate-change-group in the lispref manual * doc/lispref/text.texi (Atomic Changes): Mention undo-amalgamate-change-group (bug#42303). (cherry picked from commit ba25a82855a2c03c25fec83f3056c166b692e94f) diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 06975f7670..5eead42031 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -5559,6 +5559,11 @@ This function accepts all the changes in the change group specified by @defun cancel-change-group handle This function cancels and undoes all the changes in the change group specified by @var{handle}. +@end defun + +@defun undo-amalgamate-change-group +Amalgamate changes in change-group since @var{handle}. I.e., remove +all undo boundaries between the state of @var{handle} and now. @end defun Your code should use @code{unwind-protect} to make sure the group is commit cc98d0bf5225c281f91152aa838c4cb093df52e9 Author: Dmitry Gutov Date: Sat Jan 23 02:58:53 2021 +0200 ; xref-revert-buffer: Drop the (goto-char) at the end diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index abaa0dc5e8..898cb4fb4c 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -975,8 +975,7 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (insert (propertize (error-message-string err) - 'face 'error)))) - (goto-char (point-min))))) + 'face 'error))))))) (defun xref-show-definitions-buffer (fetcher alist) "Show the definitions list in a regular window. commit 5821dee0949b2913c07970d6e4b8bb8e8a35f036 Author: Dmitry Gutov Date: Sat Jan 23 02:53:12 2021 +0200 Erase the buffer only after fetching the new contents * lisp/progmodes/xref.el (xref-revert-buffer): Erase the buffer only after fetching the new contents (bug#46042). diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index aecb30a0ad..abaa0dc5e8 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -967,10 +967,10 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (let ((inhibit-read-only t) (buffer-undo-list t)) (save-excursion - (erase-buffer) (condition-case err - (xref--insert-xrefs - (xref--analyze (funcall xref--fetcher))) + (let ((alist (xref--analyze (funcall xref--fetcher)))) + (erase-buffer) + (xref--insert-xrefs alist)) (user-error (insert (propertize commit b9d0cdcacbd3da93b4ebfa10d778efb618881ccc Author: Stefan Monnier Date: Fri Jan 22 16:56:57 2021 -0500 * lisp/simple.el (newline-and-indent): Disable `electric-indent-mode` With `electric-indent-mode` enabled, `newline-and-indent` ends up indenting 3 times: once for the original line and twice on the new line. `reindent-then-newline-and-indent` is even worse, indenting twice both lines. None of those commands should be affected by `electric-indent-mode` since they even explicitly say in their name when and how they do indentation. (reindent-then-newline-and-indent): Temporarily disable `electric-indent-mode` as well. diff --git a/lisp/simple.el b/lisp/simple.el index 2c6e3916cd..8d4e4a7a6b 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -820,9 +820,10 @@ With ARG, perform this action that many times." (delete-horizontal-space t) (unless arg (setq arg 1)) - (dotimes (_ arg) - (newline nil t) - (indent-according-to-mode))) + (let ((electric-indent-mode nil)) + (dotimes (_ arg) + (newline nil t) + (indent-according-to-mode)))) (defun reindent-then-newline-and-indent () "Reindent current line, insert newline, then indent the new line. @@ -832,7 +833,8 @@ In programming language modes, this is the same as TAB. In some text modes, where TAB inserts a tab, this indents to the column specified by the function `current-left-margin'." (interactive "*") - (let ((pos (point))) + (let ((pos (point)) + (electric-indent-mode nil)) ;; Be careful to insert the newline before indenting the line. ;; Otherwise, the indentation might be wrong. (newline) commit ba25a82855a2c03c25fec83f3056c166b692e94f Author: Lars Ingebrigtsen Date: Fri Jan 22 21:07:35 2021 +0100 Mention undo-amalgamate-change-group in the lispref manual * doc/lispref/text.texi (Atomic Changes): Mention undo-amalgamate-change-group (bug#42303). diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 0b567d82c6..35bc6f9f16 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -5608,6 +5608,11 @@ This function accepts all the changes in the change group specified by @defun cancel-change-group handle This function cancels and undoes all the changes in the change group specified by @var{handle}. +@end defun + +@defun undo-amalgamate-change-group +Amalgamate changes in change-group since @var{handle}. I.e., remove +all undo boundaries between the state of @var{handle} and now. @end defun Your code should use @code{unwind-protect} to make sure the group is commit b99ec5d5b11154bafb193ceaaac6976daafe3f82 Author: Paul Eggert Date: Fri Jan 22 11:47:22 2021 -0800 Work around __has_attribute bug in clang 3.4 * src/conf_post.h (HAS_ATTRIBUTE): * src/emacs-module.h.in (EMACS_ATTRIBUTE_NONNULL): Port to clang 3.4 and earlier. diff --git a/src/conf_post.h b/src/conf_post.h index bd56f29e28..176ab28b21 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -71,7 +71,9 @@ typedef bool bool_bf; It is used only on arguments like cleanup that are handled here. This macro should be used only in #if expressions, as Oracle Studio 12.5's __has_attribute does not work in plain code. */ -#ifdef __has_attribute +#if (defined __has_attribute \ + && (!defined __clang_minor__ \ + || 3 < __clang_major__ + (5 <= __clang_minor__))) # define HAS_ATTRIBUTE(a) __has_attribute (__##a##__) #else # define HAS_ATTRIBUTE(a) HAS_ATTR_##a diff --git a/src/emacs-module.h.in b/src/emacs-module.h.in index 2989b43910..fe52587c1a 100644 --- a/src/emacs-module.h.in +++ b/src/emacs-module.h.in @@ -51,7 +51,9 @@ information how to write modules and use this header file. #if 3 < __GNUC__ + (3 <= __GNUC_MINOR__) # define EMACS_ATTRIBUTE_NONNULL(...) \ __attribute__ ((__nonnull__ (__VA_ARGS__))) -#elif defined __has_attribute +#elif (defined __has_attribute \ + && (!defined __clang_minor__ \ + || 3 < __clang_major__ + (5 <= __clang_minor__))) # if __has_attribute (__nonnull__) # define EMACS_ATTRIBUTE_NONNULL(...) \ __attribute__ ((__nonnull__ (__VA_ARGS__))) commit a900e641fa1fd765799f12a7f699f768ebfccfe8 Author: Paul Eggert Date: Fri Jan 22 11:45:38 2021 -0800 Update from Gnulib by running admin/merge-gnulib diff --git a/build-aux/config.guess b/build-aux/config.guess index 7f74817797..f7727026b7 100755 --- a/build-aux/config.guess +++ b/build-aux/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2020 Free Software Foundation, Inc. +# Copyright 1992-2021 Free Software Foundation, Inc. -timestamp='2020-12-22' +timestamp='2021-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2020 Free Software Foundation, Inc. +Copyright 1992-2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -1087,7 +1087,7 @@ EOF ppcle:Linux:*:*) echo powerpcle-unknown-linux-"$LIBC" exit ;; - riscv32:Linux:*:* | riscv64:Linux:*:*) + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) diff --git a/build-aux/config.sub b/build-aux/config.sub index 90bb8aeda6..b0f8492348 100755 --- a/build-aux/config.sub +++ b/build-aux/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2020 Free Software Foundation, Inc. +# Copyright 1992-2021 Free Software Foundation, Inc. -timestamp='2020-12-22' +timestamp='2021-01-07' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -67,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2020 Free Software Foundation, Inc. +Copyright 1992-2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -1230,7 +1230,7 @@ case $cpu-$vendor in | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ | pru \ | pyramid \ - | riscv | riscv32 | riscv64 \ + | riscv | riscv32 | riscv32be | riscv64 | riscv64be \ | rl78 | romp | rs6000 | rx \ | s390 | s390x \ | score \ @@ -1687,7 +1687,7 @@ case $os in musl* | newlib* | uclibc*) ;; # Likewise for "kernel-libc" - eabi | eabihf | gnueabi | gnueabihf) + eabi* | gnueabi*) ;; # Now accept the basic system types. # The portable systems comes first. diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex index 3c7051d1c7..dac7ae3d19 100644 --- a/doc/misc/texinfo.tex +++ b/doc/misc/texinfo.tex @@ -3,7 +3,7 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2020-10-24.12} +\def\texinfoversion{2020-11-25.18} % % Copyright 1985, 1986, 1988, 1990-2020 Free Software Foundation, Inc. % @@ -572,10 +572,9 @@ \fi } -% @end foo executes the definition of \Efoo. -% But first, it executes a specialized version of \checkenv -% -\parseargdef\end{% + +% @end foo calls \checkenv and executes the definition of \Efoo. +\parseargdef\end{ \if 1\csname iscond.#1\endcsname \else % The general wording of \badenverr may not be ideal. @@ -2673,8 +2672,6 @@ \definetextfontsizexi -\message{markup,} - % Check if we are currently using a typewriter font. Since all the % Computer Modern typewriter fonts have zero interword stretch (and % shrink), and it is reasonable to expect all typewriter fonts to have @@ -2682,68 +2679,14 @@ % \def\ifmonospace{\ifdim\fontdimen3\font=0pt } -% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will -% define and register \INITMACRO to be called on markup style changes. -% \INITMACRO can check \currentmarkupstyle for the innermost -% style. - -\let\currentmarkupstyle\empty - -\def\setupmarkupstyle#1{% - \def\currentmarkupstyle{#1}% - \markupstylesetup -} - -\let\markupstylesetup\empty - -\def\defmarkupstylesetup#1{% - \expandafter\def\expandafter\markupstylesetup - \expandafter{\markupstylesetup #1}% - \def#1% -} - -% Markup style setup for left and right quotes. -\defmarkupstylesetup\markupsetuplq{% - \expandafter\let\expandafter \temp - \csname markupsetuplq\currentmarkupstyle\endcsname - \ifx\temp\relax \markupsetuplqdefault \else \temp \fi -} - -\defmarkupstylesetup\markupsetuprq{% - \expandafter\let\expandafter \temp - \csname markupsetuprq\currentmarkupstyle\endcsname - \ifx\temp\relax \markupsetuprqdefault \else \temp \fi -} - { \catcode`\'=\active \catcode`\`=\active -\gdef\markupsetuplqdefault{\let`\lq} -\gdef\markupsetuprqdefault{\let'\rq} - -\gdef\markupsetcodequoteleft{\let`\codequoteleft} -\gdef\markupsetcodequoteright{\let'\codequoteright} +\gdef\setcodequotes{\let`\codequoteleft \let'\codequoteright} +\gdef\setregularquotes{\let`\lq \let'\rq} } -\let\markupsetuplqcode \markupsetcodequoteleft -\let\markupsetuprqcode \markupsetcodequoteright -% -\let\markupsetuplqexample \markupsetcodequoteleft -\let\markupsetuprqexample \markupsetcodequoteright -% -\let\markupsetuplqkbd \markupsetcodequoteleft -\let\markupsetuprqkbd \markupsetcodequoteright -% -\let\markupsetuplqsamp \markupsetcodequoteleft -\let\markupsetuprqsamp \markupsetcodequoteright -% -\let\markupsetuplqverb \markupsetcodequoteleft -\let\markupsetuprqverb \markupsetcodequoteright -% -\let\markupsetuplqverbatim \markupsetcodequoteleft -\let\markupsetuprqverbatim \markupsetcodequoteright - % Allow an option to not use regular directed right quote/apostrophe % (char 0x27), but instead the undirected quote from cmtt (char 0x0d). % The undirected quote is ugly, so don't make it the default, but it @@ -2906,7 +2849,7 @@ } % @samp. -\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}} +\def\samp#1{{\setcodequotes\lq\tclose{#1}\rq\null}} % @indicateurl is \samp, that is, with quotes. \let\indicateurl=\samp @@ -2949,8 +2892,7 @@ \global\let'=\rq \global\let`=\lq % default definitions % \global\def\code{\begingroup - \setupmarkupstyle{code}% - % The following should really be moved into \setupmarkupstyle handlers. + \setcodequotes \catcode\dashChar=\active \catcode\underChar=\active \ifallowcodebreaks \let-\codedash @@ -3104,7 +3046,7 @@ \urefcatcodes % \global\def\urefcode{\begingroup - \setupmarkupstyle{code}% + \setcodequotes \urefcatcodes \let&\urefcodeamp \let.\urefcodedot @@ -3225,8 +3167,8 @@ \def\kbdsub#1#2#3\par{% \def\one{#1}\def\three{#3}\def\threex{??}% \ifx\one\xkey\ifx\threex\three \key{#2}% - \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi - \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi + \else{\tclose{\kbdfont\setcodequotes\look}}\fi + \else{\tclose{\kbdfont\setcodequotes\look}}\fi } % definition of @key that produces a lozenge. Doesn't adjust to text size. @@ -3243,7 +3185,7 @@ % monospace, don't change it; that way, we respect @kbdinputstyle. But % if it isn't monospace, then use \tt. % -\def\key#1{{\setupmarkupstyle{key}% +\def\key#1{{\setregularquotes \nohyphenation \ifmonospace\else\tt\fi #1}\null} @@ -3373,16 +3315,20 @@ {\obeylines \globaldefs=1 \envdef\displaymath{% -\tex +\tex% \def\thisenv{\displaymath}% +\begingroup\let\end\displaymathend% $$% } -\def\Edisplaymath{$$ +\def\displaymathend{$$\endgroup\end}% + +\def\Edisplaymath{% \def\thisenv{\tex}% \end tex }} + % @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. % Ignore unless FMTNAME == tex; then it is like @iftex and @tex, % except specified as a normal braced arg, so no newlines to worry about. @@ -7144,7 +7090,7 @@ % But \@ or @@ will get a plain @ character. \envdef\tex{% - \setupmarkupstyle{tex}% + \setregularquotes \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie @@ -7370,7 +7316,7 @@ % If you want all examples etc. small: @set dispenvsize small. % If you want even small examples the full size: @set dispenvsize nosmall. % This affects the following displayed environments: -% @example, @display, @format, @lisp +% @example, @display, @format, @lisp, @verbatim % \def\smallword{small} \def\nosmallword{nosmall} @@ -7416,9 +7362,9 @@ % \maketwodispenvdef{lisp}{example}{% \nonfillstart - \tt\setupmarkupstyle{example}% + \tt\setcodequotes \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. - \gobble % eat return + \parsearg\gobble } % @display/@smalldisplay: same as @lisp except keep current font. % @@ -7576,7 +7522,7 @@ \def\setupverb{% \tt % easiest (and conventionally used) font for verbatim \def\par{\leavevmode\endgraf}% - \setupmarkupstyle{verb}% + \setcodequotes \tabeightspaces % Respect line breaks, % print special symbols as themselves, and @@ -7617,7 +7563,7 @@ \tt % easiest (and conventionally used) font for verbatim \def\par{\egroup\leavevmode\box\verbbox\endgraf\starttabbox}% \tabexpand - \setupmarkupstyle{verbatim}% + \setcodequotes % Respect line breaks, % print special symbols as themselves, and % make each space count. @@ -8036,7 +7982,7 @@ % leave the code in, but it's strange for @var to lead to typewriter. % Nowadays we recommend @code, since the difference between a ttsl hyphen % and a tt hyphen is pretty tiny. @code also disables ?` !`. - \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}% + \def\var##1{{\setregularquotes\ttslanted{##1}}}% #1% \sl\hyphenchar\font=45 } @@ -8145,11 +8091,18 @@ } \fi +\let\E=\expandafter + % Used at the time of macro expansion. % Argument is macro body with arguments substituted \def\scanmacro#1{% \newlinechar`\^^M - \def\xeatspaces{\eatspaces}% + % expand the expansion of \eatleadingcr twice to maybe remove a leading + % newline (and \else and \fi tokens), then call \eatspaces on the result. + \def\xeatspaces##1{% + \E\E\E\E\E\E\E\eatspaces\E\E\E\E\E\E\E{\eatleadingcr##1% + }}% + \def\xempty##1{}% % % Process the macro body under the current catcode regime. \scantokens{#1@comment}% @@ -8202,6 +8155,11 @@ \unbrace{\gdef\trim@@@ #1 } #2@{#1} } +{\catcode`\^^M=\other% +\gdef\eatleadingcr#1{\if\noexpand#1\noexpand^^M\else\E#1\fi}}% +% Warning: this won't work for a delimited argument +% or for an empty argument + % Trim a single trailing ^^M off a string. {\catcode`\^^M=\other \catcode`\Q=3% \gdef\eatcr #1{\eatcra #1Q^^MQ}% @@ -8368,6 +8326,7 @@ \let\hash\relax % \hash is redefined to `#' later to get it into definitions \let\xeatspaces\relax + \let\xempty\relax \parsemargdefxxx#1,;,% \ifnum\paramno<10\relax\else \paramno0\relax @@ -8379,9 +8338,11 @@ \else \let\next=\parsemargdefxxx \advance\paramno by 1 \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname - {\xeatspaces{\hash\the\paramno}}% + {\xeatspaces{\hash\the\paramno\noexpand\xempty{}}}% \edef\paramlist{\paramlist\hash\the\paramno,}% \fi\next} +% the \xempty{} is to give \eatleadingcr an argument in the case of an +% empty macro argument. % \parsemacbody, \parsermacbody % @@ -9107,20 +9068,22 @@ % output the `[mynode]' via the macro below so it can be overridden. \xrefprintnodename\printedrefname % - % But we always want a comma and a space: - ,\space - % - % output the `page 3'. - \turnoffactive \putwordpage\tie\refx{#1-pg}{}% - % Add a , if xref followed by a space - \if\space\noexpand\tokenafterxref ,% - \else\ifx\ \tokenafterxref ,% @TAB - \else\ifx\*\tokenafterxref ,% @* - \else\ifx\ \tokenafterxref ,% @SPACE - \else\ifx\ - \tokenafterxref ,% @NL - \else\ifx\tie\tokenafterxref ,% @tie - \fi\fi\fi\fi\fi\fi + \expandafter\ifx\csname SETtxiomitxrefpg\endcsname\relax + % But we always want a comma and a space: + ,\space + % + % output the `page 3'. + \turnoffactive \putwordpage\tie\refx{#1-pg}{}% + % Add a , if xref followed by a space + \if\space\noexpand\tokenafterxref ,% + \else\ifx\ \tokenafterxref ,% @TAB + \else\ifx\*\tokenafterxref ,% @* + \else\ifx\ \tokenafterxref ,% @SPACE + \else\ifx\ + \tokenafterxref ,% @NL + \else\ifx\tie\tokenafterxref ,% @tie + \fi\fi\fi\fi\fi\fi + \fi \fi\fi \fi \endlink @@ -9550,7 +9513,7 @@ \def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup \catcode`\^^M = 5 % in case we're inside an example \normalturnoffactive % allow _ et al. in names - \def\xprocessmacroarg{\eatspaces}% in case we are being used via a macro + \makevalueexpandable % If the image is by itself, center it. \ifvmode \imagevmodetrue @@ -11603,7 +11566,7 @@ \let> = \activegtr \let~ = \activetilde \let^ = \activehat - \markupsetuplqdefault \markupsetuprqdefault + \setregularquotes \let\b = \strong \let\i = \smartitalic % in principle, all other definitions in \tex have to be undone too. @@ -11662,8 +11625,7 @@ @let|=@normalverticalbar @let~=@normaltilde @let\=@ttbackslash - @markupsetuplqdefault - @markupsetuprqdefault + @setregularquotes @unsepspaces } } @@ -11756,8 +11718,7 @@ @c Do this last of all since we use ` in the previous @catcode assignments. @catcode`@'=@active @catcode`@`=@active -@markupsetuplqdefault -@markupsetuprqdefault +@setregularquotes @c Local variables: @c eval: (add-hook 'before-save-hook 'time-stamp) diff --git a/lib/_Noreturn.h b/lib/_Noreturn.h index 38afe1d567..fb718bc069 100644 --- a/lib/_Noreturn.h +++ b/lib/_Noreturn.h @@ -26,14 +26,16 @@ AIX system header files and several gnulib header files use precisely this syntax with 'extern'. */ # define _Noreturn [[noreturn]] -# elif ((!defined __cplusplus || defined __clang__) \ - && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \ - || 4 < __GNUC__ + (7 <= __GNUC_MINOR__) \ - || (defined __apple_build_version__ \ - ? 6000000 <= __apple_build_version__ \ - : 3 < __clang_major__ + (5 <= __clang_minor__)))) +# elif ((!defined __cplusplus || defined __clang__) \ + && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \ + || (!defined __STRICT_ANSI__ \ + && (__4 < __GNUC__ + (7 <= __GNUC_MINOR__) \ + || (defined __apple_build_version__ \ + ? 6000000 <= __apple_build_version__ \ + : 3 < __clang_major__ + (5 <= __clang_minor__)))))) /* _Noreturn works as-is. */ -# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C +# elif (2 < __GNUC__ + (8 <= __GNUC_MINOR__) || defined __clang__ \ + || 0x5110 <= __SUNPRO_C) # define _Noreturn __attribute__ ((__noreturn__)) # elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0) # define _Noreturn __declspec (noreturn) diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c index b6dc3a447a..b7dba08994 100644 --- a/lib/canonicalize-lgpl.c +++ b/lib/canonicalize-lgpl.c @@ -85,10 +85,6 @@ # define IF_LINT(Code) /* empty */ #endif -/* True if adding two valid object sizes might overflow idx_t. - As a practical matter, this cannot happen on 64-bit machines. */ -enum { NARROW_ADDRESSES = IDX_MAX >> 31 >> 31 == 0 }; - #ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT # define DOUBLE_SLASH_IS_DISTINCT_ROOT false #endif @@ -145,11 +141,11 @@ suffix_requires_dir_check (char const *end) macOS 10.13 , and should also work on platforms like AIX 7.2 that need at least "/.". */ -#if defined _LIBC || defined LSTAT_FOLLOWS_SLASHED_SYMLINK +# if defined _LIBC || defined LSTAT_FOLLOWS_SLASHED_SYMLINK static char const dir_suffix[] = "/"; -#else +# else static char const dir_suffix[] = "/./"; -#endif +# endif /* Return true if DIR is a searchable dir, false (setting errno) otherwise. DIREND points to the NUL byte at the end of the DIR string. @@ -191,13 +187,13 @@ get_path_max (void) to pacify GCC is known; even an explicit #pragma does not pacify GCC. When the GCC bug is fixed this workaround should be limited to the broken GCC versions. */ -#if __GNUC_PREREQ (10, 1) -# if defined GCC_LINT || defined lint +# if __GNUC_PREREQ (10, 1) +# if defined GCC_LINT || defined lint __attribute__ ((__noinline__)) -# elif __OPTIMIZE__ && !__NO_INLINE__ -# define GCC_BOGUS_WRETURN_LOCAL_ADDR +# elif __OPTIMIZE__ && !__NO_INLINE__ +# define GCC_BOGUS_WRETURN_LOCAL_ADDR +# endif # endif -#endif static char * realpath_stk (const char *name, char *resolved, struct scratch_buffer *rname_buf) @@ -343,7 +339,7 @@ realpath_stk (const char *name, char *resolved, if (end_in_extra_buffer) end_idx = end - extra_buf; size_t len = strlen (end); - if (NARROW_ADDRESSES && INT_ADD_OVERFLOW (len, n)) + if (INT_ADD_OVERFLOW (len, n)) { __set_errno (ENOMEM); goto error_nomem; @@ -443,7 +439,8 @@ __realpath (const char *name, char *resolved) } libc_hidden_def (__realpath) versioned_symbol (libc, __realpath, realpath, GLIBC_2_3); -#endif /* !FUNC_REALPATH_WORKS || defined _LIBC */ + +#endif /* defined _LIBC || !FUNC_REALPATH_WORKS */ #if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3) diff --git a/lib/cdefs.h b/lib/cdefs.h index 2a3dc9666b..de74f4211c 100644 --- a/lib/cdefs.h +++ b/lib/cdefs.h @@ -25,7 +25,7 @@ /* The GNU libc does not support any K&R compilers or the traditional mode of ISO C compilers anymore. Check for some of the combinations not - anymore supported. */ + supported anymore. */ #if defined __GNUC__ && !defined __STDC__ # error "You need a ISO C conforming compiler to use the glibc headers" #endif @@ -34,31 +34,26 @@ #undef __P #undef __PMT -/* Compilers that are not clang may object to - #if defined __clang__ && __has_attribute(...) - even though they do not need to evaluate the right-hand side of the &&. */ -#if defined __clang__ && defined __has_attribute -# define __glibc_clang_has_attribute(name) __has_attribute (name) +/* Compilers that lack __has_attribute may object to + #if defined __has_attribute && __has_attribute (...) + even though they do not need to evaluate the right-hand side of the &&. + Similarly for __has_builtin, etc. */ +#if (defined __has_attribute \ + && (!defined __clang_minor__ \ + || 3 < __clang_major__ + (5 <= __clang_minor__))) +# define __glibc_has_attribute(attr) __has_attribute (attr) #else -# define __glibc_clang_has_attribute(name) 0 +# define __glibc_has_attribute(attr) 0 #endif - -/* Compilers that are not clang may object to - #if defined __clang__ && __has_builtin(...) - even though they do not need to evaluate the right-hand side of the &&. */ -#if defined __clang__ && defined __has_builtin -# define __glibc_clang_has_builtin(name) __has_builtin (name) +#ifdef __has_builtin +# define __glibc_has_builtin(name) __has_builtin (name) #else -# define __glibc_clang_has_builtin(name) 0 +# define __glibc_has_builtin(name) 0 #endif - -/* Compilers that are not clang may object to - #if defined __clang__ && __has_extension(...) - even though they do not need to evaluate the right-hand side of the &&. */ -#if defined __clang__ && defined __has_extension -# define __glibc_clang_has_extension(ext) __has_extension (ext) +#ifdef __has_extension +# define __glibc_has_extension(ext) __has_extension (ext) #else -# define __glibc_clang_has_extension(ext) 0 +# define __glibc_has_extension(ext) 0 #endif #if defined __GNUC__ || defined __clang__ @@ -74,22 +69,26 @@ # endif /* GCC can always grok prototypes. For C++ programs we add throw() - to help it optimize the function calls. But this works only with + to help it optimize the function calls. But this only works with gcc 2.8.x and egcs. For gcc 3.4 and up we even mark C functions as non-throwing using a function attribute since programs can use the -fexceptions options for C code as well. */ # if !defined __cplusplus \ - && (__GNUC_PREREQ (3, 4) || __glibc_clang_has_attribute (__nothrow__)) + && (__GNUC_PREREQ (3, 4) || __glibc_has_attribute (__nothrow__)) # define __THROW __attribute__ ((__nothrow__ __LEAF)) # define __THROWNL __attribute__ ((__nothrow__)) # define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct # define __NTHNL(fct) __attribute__ ((__nothrow__)) fct # else # if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major >= 4) -# define __THROW throw () -# define __THROWNL throw () -# define __NTH(fct) __LEAF_ATTR fct throw () -# define __NTHNL(fct) fct throw () +# if __cplusplus >= 201103L +# define __THROW noexcept (true) +# else +# define __THROW throw () +# endif +# define __THROWNL __THROW +# define __NTH(fct) __LEAF_ATTR fct __THROW +# define __NTHNL(fct) fct __THROW # else # define __THROW # define __THROWNL @@ -142,24 +141,20 @@ #define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1) #define __bos0(ptr) __builtin_object_size (ptr, 0) +/* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */ +#if __USE_FORTIFY_LEVEL == 3 && __glibc_clang_prereq (9, 0) +# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0) +# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1) +#else +# define __glibc_objsize0(__o) __bos0 (__o) +# define __glibc_objsize(__o) __bos (__o) +#endif + #if __GNUC_PREREQ (4,3) -# define __warndecl(name, msg) \ - extern void name (void) __attribute__((__warning__ (msg))) # define __warnattr(msg) __attribute__((__warning__ (msg))) # define __errordecl(name, msg) \ extern void name (void) __attribute__((__error__ (msg))) -#elif __glibc_clang_has_attribute (__diagnose_if__) && 0 -/* These definitions are not enabled, because they produce bogus warnings - in the glibc Fortify functions. These functions are written in a style - that works with GCC. In order to work with clang, these functions would - need to be modified. */ -# define __warndecl(name, msg) \ - extern void name (void) __attribute__((__diagnose_if__ (1, msg, "warning"))) -# define __warnattr(msg) __attribute__((__diagnose_if__ (1, msg, "warning"))) -# define __errordecl(name, msg) \ - extern void name (void) __attribute__((__diagnose_if__ (1, msg, "error"))) #else -# define __warndecl(name, msg) extern void name (void) # define __warnattr(msg) # define __errordecl(name, msg) extern void name (void) #endif @@ -233,7 +228,7 @@ /* At some point during the gcc 2.96 development the `malloc' attribute for functions was introduced. We don't want to use it unconditionally (although this would be possible) since it generates warnings. */ -#if __GNUC_PREREQ (2,96) || __glibc_clang_has_attribute (__malloc__) +#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__malloc__) # define __attribute_malloc__ __attribute__ ((__malloc__)) #else # define __attribute_malloc__ /* Ignore */ @@ -251,23 +246,31 @@ /* At some point during the gcc 2.96 development the `pure' attribute for functions was introduced. We don't want to use it unconditionally (although this would be possible) since it generates warnings. */ -#if __GNUC_PREREQ (2,96) || __glibc_clang_has_attribute (__pure__) +#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__pure__) # define __attribute_pure__ __attribute__ ((__pure__)) #else # define __attribute_pure__ /* Ignore */ #endif /* This declaration tells the compiler that the value is constant. */ -#if __GNUC_PREREQ (2,5) || __glibc_clang_has_attribute (__const__) +#if __GNUC_PREREQ (2,5) || __glibc_has_attribute (__const__) # define __attribute_const__ __attribute__ ((__const__)) #else # define __attribute_const__ /* Ignore */ #endif +#if defined __STDC_VERSION__ && 201710L < __STDC_VERSION__ +# define __attribute_maybe_unused__ [[__maybe_unused__]] +#elif __GNUC_PREREQ (2,7) || __glibc_has_attribute (__unused__) +# define __attribute_maybe_unused__ __attribute__ ((__unused__)) +#else +# define __attribute_maybe_unused__ /* Ignore */ +#endif + /* At some point during the gcc 3.1 development the `used' attribute for functions was introduced. We don't want to use it unconditionally (although this would be possible) since it generates warnings. */ -#if __GNUC_PREREQ (3,1) || __glibc_clang_has_attribute (__used__) +#if __GNUC_PREREQ (3,1) || __glibc_has_attribute (__used__) # define __attribute_used__ __attribute__ ((__used__)) # define __attribute_noinline__ __attribute__ ((__noinline__)) #else @@ -276,7 +279,7 @@ #endif /* Since version 3.2, gcc allows marking deprecated functions. */ -#if __GNUC_PREREQ (3,2) || __glibc_clang_has_attribute (__deprecated__) +#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__deprecated__) # define __attribute_deprecated__ __attribute__ ((__deprecated__)) #else # define __attribute_deprecated__ /* Ignore */ @@ -285,8 +288,8 @@ /* Since version 4.5, gcc also allows one to specify the message printed when a deprecated function is used. clang claims to be gcc 4.2, but may also support this feature. */ -#if __GNUC_PREREQ (4,5) || \ - __glibc_clang_has_extension (__attribute_deprecated_with_message__) +#if __GNUC_PREREQ (4,5) \ + || __glibc_has_extension (__attribute_deprecated_with_message__) # define __attribute_deprecated_msg__(msg) \ __attribute__ ((__deprecated__ (msg))) #else @@ -299,7 +302,7 @@ If several `format_arg' attributes are given for the same function, in gcc-3.0 and older, all but the last one are ignored. In newer gccs, all designated arguments are considered. */ -#if __GNUC_PREREQ (2,8) || __glibc_clang_has_attribute (__format_arg__) +#if __GNUC_PREREQ (2,8) || __glibc_has_attribute (__format_arg__) # define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x))) #else # define __attribute_format_arg__(x) /* Ignore */ @@ -309,7 +312,7 @@ attribute for functions was introduced. We don't want to use it unconditionally (although this would be possible) since it generates warnings. */ -#if __GNUC_PREREQ (2,97) || __glibc_clang_has_attribute (__format__) +#if __GNUC_PREREQ (2,97) || __glibc_has_attribute (__format__) # define __attribute_format_strfmon__(a,b) \ __attribute__ ((__format__ (__strfmon__, a, b))) #else @@ -320,7 +323,7 @@ must not be NULL. Do not define __nonnull if it is already defined, for portability when this file is used in Gnulib. */ #ifndef __nonnull -# if __GNUC_PREREQ (3,3) || __glibc_clang_has_attribute (__nonnull__) +# if __GNUC_PREREQ (3,3) || __glibc_has_attribute (__nonnull__) # define __nonnull(params) __attribute__ ((__nonnull__ params)) # else # define __nonnull(params) @@ -329,7 +332,7 @@ /* If fortification mode, we warn about unused results of certain function calls which can lead to problems. */ -#if __GNUC_PREREQ (3,4) || __glibc_clang_has_attribute (__warn_unused_result__) +#if __GNUC_PREREQ (3,4) || __glibc_has_attribute (__warn_unused_result__) # define __attribute_warn_unused_result__ \ __attribute__ ((__warn_unused_result__)) # if defined __USE_FORTIFY_LEVEL && __USE_FORTIFY_LEVEL > 0 @@ -343,7 +346,7 @@ #endif /* Forces a function to be always inlined. */ -#if __GNUC_PREREQ (3,2) || __glibc_clang_has_attribute (__always_inline__) +#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__always_inline__) /* The Linux kernel defines __always_inline in stddef.h (283d7573), and it conflicts with this definition. Therefore undefine it first to allow either header to be included first. */ @@ -356,7 +359,7 @@ /* Associate error messages with the source location of the call site rather than with the source location inside the function. */ -#if __GNUC_PREREQ (4,3) || __glibc_clang_has_attribute (__artificial__) +#if __GNUC_PREREQ (4,3) || __glibc_has_attribute (__artificial__) # define __attribute_artificial__ __attribute__ ((__artificial__)) #else # define __attribute_artificial__ /* Ignore */ @@ -433,7 +436,7 @@ # endif #endif -#if (__GNUC__ >= 3) || __glibc_clang_has_builtin (__builtin_expect) +#if (__GNUC__ >= 3) || __glibc_has_builtin (__builtin_expect) # define __glibc_unlikely(cond) __builtin_expect ((cond), 0) # define __glibc_likely(cond) __builtin_expect ((cond), 1) #else @@ -441,12 +444,6 @@ # define __glibc_likely(cond) (cond) #endif -#ifdef __has_attribute -# define __glibc_has_attribute(attr) __has_attribute (attr) -#else -# define __glibc_has_attribute(attr) 0 -#endif - #if (!defined _Noreturn \ && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ && !(__GNUC_PREREQ (4,7) \ @@ -467,6 +464,16 @@ # define __attribute_nonstring__ #endif +/* Undefine (also defined in libc-symbols.h). */ +#undef __attribute_copy__ +#if __GNUC_PREREQ (9, 0) +/* Copies attributes from the declaration or type referenced by + the argument. */ +# define __attribute_copy__(arg) __attribute__ ((__copy__ (arg))) +#else +# define __attribute_copy__(arg) +#endif + #if (!defined _Static_assert && !defined __cplusplus \ && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ && (!(__GNUC_PREREQ (4, 6) || __clang_major__ >= 4) \ @@ -483,7 +490,37 @@ # include #endif -#if defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH +#if __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1 +# ifdef __REDIRECT + +/* Alias name defined automatically. */ +# define __LDBL_REDIR(name, proto) ... unused__ldbl_redir +# define __LDBL_REDIR_DECL(name) \ + extern __typeof (name) name __asm (__ASMNAME ("__" #name "ieee128")); + +/* Alias name defined automatically, with leading underscores. */ +# define __LDBL_REDIR2_DECL(name) \ + extern __typeof (__##name) __##name \ + __asm (__ASMNAME ("__" #name "ieee128")); + +/* Alias name defined manually. */ +# define __LDBL_REDIR1(name, proto, alias) ... unused__ldbl_redir1 +# define __LDBL_REDIR1_DECL(name, alias) \ + extern __typeof (name) name __asm (__ASMNAME (#alias)); + +# define __LDBL_REDIR1_NTH(name, proto, alias) \ + __REDIRECT_NTH (name, proto, alias) +# define __REDIRECT_NTH_LDBL(name, proto, alias) \ + __LDBL_REDIR1_NTH (name, proto, __##alias##ieee128) + +/* Unused. */ +# define __REDIRECT_LDBL(name, proto, alias) ... unused__redirect_ldbl +# define __LDBL_REDIR_NTH(name, proto) ... unused__ldbl_redir_nth + +# else +_Static_assert (0, "IEEE 128-bits long double requires redirection on this platform"); +# endif +#elif defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH # define __LDBL_COMPAT 1 # ifdef __REDIRECT # define __LDBL_REDIR1(name, proto, alias) __REDIRECT (name, proto, alias) @@ -492,6 +529,8 @@ # define __LDBL_REDIR1_NTH(name, proto, alias) __REDIRECT_NTH (name, proto, alias) # define __LDBL_REDIR_NTH(name, proto) \ __LDBL_REDIR1_NTH (name, proto, __nldbl_##name) +# define __LDBL_REDIR2_DECL(name) \ + extern __typeof (__##name) __##name __asm (__ASMNAME ("__nldbl___" #name)); # define __LDBL_REDIR1_DECL(name, alias) \ extern __typeof (name) name __asm (__ASMNAME (#alias)); # define __LDBL_REDIR_DECL(name) \ @@ -502,11 +541,13 @@ __LDBL_REDIR1_NTH (name, proto, __nldbl_##alias) # endif #endif -#if !defined __LDBL_COMPAT || !defined __REDIRECT +#if (!defined __LDBL_COMPAT && __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 0) \ + || !defined __REDIRECT # define __LDBL_REDIR1(name, proto, alias) name proto # define __LDBL_REDIR(name, proto) name proto # define __LDBL_REDIR1_NTH(name, proto, alias) name proto __THROW # define __LDBL_REDIR_NTH(name, proto) name proto __THROW +# define __LDBL_REDIR2_DECL(name) # define __LDBL_REDIR_DECL(name) # ifdef __REDIRECT # define __REDIRECT_LDBL(name, proto, alias) __REDIRECT (name, proto, alias) @@ -537,7 +578,7 @@ check is required to enable the use of generic selection. */ #if !defined __cplusplus \ && (__GNUC_PREREQ (4, 9) \ - || __glibc_clang_has_extension (c_generic_selections) \ + || __glibc_has_extension (c_generic_selections) \ || (!defined __GNUC__ && defined __STDC_VERSION__ \ && __STDC_VERSION__ >= 201112L)) # define __HAVE_GENERIC_SELECTION 1 @@ -545,4 +586,23 @@ # define __HAVE_GENERIC_SELECTION 0 #endif +#if __GNUC_PREREQ (10, 0) +/* Designates a 1-based positional argument ref-index of pointer type + that can be used to access size-index elements of the pointed-to + array according to access mode, or at least one element when + size-index is not provided: + access (access-mode, [, ]) */ +#define __attr_access(x) __attribute__ ((__access__ x)) +#else +# define __attr_access(x) +#endif + +/* Specify that a function such as setjmp or vfork may return + twice. */ +#if __GNUC_PREREQ (4, 1) +# define __attribute_returns_twice__ __attribute__ ((__returns_twice__)) +#else +# define __attribute_returns_twice__ /* Ignore. */ +#endif + #endif /* sys/cdefs.h */ diff --git a/lib/dirent.in.h b/lib/dirent.in.h index 2e2c5119a1..4666972b15 100644 --- a/lib/dirent.in.h +++ b/lib/dirent.in.h @@ -154,7 +154,8 @@ _GL_WARN_ON_USE (closedir, "closedir is not portable - " /* Return the file descriptor associated with the given directory stream, or -1 if none exists. */ # if @REPLACE_DIRFD@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +/* On kLIBC, dirfd() is a macro that does not work. Undefine it. */ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) || defined dirfd # undef dirfd # define dirfd rpl_dirfd # endif diff --git a/lib/dynarray.h b/lib/dynarray.h new file mode 100644 index 0000000000..6da3e87e55 --- /dev/null +++ b/lib/dynarray.h @@ -0,0 +1,31 @@ +/* Type-safe arrays which grow dynamically. + Copyright 2021 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Paul Eggert, 2021. */ + +#ifndef _GL_DYNARRAY_H +#define _GL_DYNARRAY_H + +#include + +#define __libc_dynarray_at_failure gl_dynarray_at_failure +#define __libc_dynarray_emplace_enlarge gl_dynarray_emplace_enlarge +#define __libc_dynarray_finalize gl_dynarray_finalize +#define __libc_dynarray_resize_clear gl_dynarray_resize_clear +#define __libc_dynarray_resize gl_dynarray_resize +#include + +#endif /* _GL_DYNARRAY_H */ diff --git a/lib/fchmodat.c b/lib/fchmodat.c index d27c0d7734..eb6e2242fd 100644 --- a/lib/fchmodat.c +++ b/lib/fchmodat.c @@ -38,6 +38,7 @@ orig_fchmodat (int dir, char const *file, mode_t mode, int flags) #include #include #include +#include #include #ifdef __osf__ @@ -63,6 +64,22 @@ orig_fchmodat (int dir, char const *file, mode_t mode, int flags) int fchmodat (int dir, char const *file, mode_t mode, int flags) { +# if HAVE_NEARLY_WORKING_FCHMODAT + /* Correct the trailing slash handling. */ + size_t len = strlen (file); + if (len && file[len - 1] == '/') + { + struct stat st; + if (fstatat (dir, file, &st, flags & AT_SYMLINK_NOFOLLOW) < 0) + return -1; + if (!S_ISDIR (st.st_mode)) + { + errno = ENOTDIR; + return -1; + } + } +# endif + # if NEED_FCHMODAT_NONSYMLINK_FIX if (flags == AT_SYMLINK_NOFOLLOW) { diff --git a/lib/free.c b/lib/free.c index 135c3eb16b..5c89787aba 100644 --- a/lib/free.c +++ b/lib/free.c @@ -27,7 +27,21 @@ void rpl_free (void *p) #undef free { +#if defined __GNUC__ && !defined __clang__ + /* An invalid GCC optimization + + would optimize away the assignments in the code below, when link-time + optimization (LTO) is enabled. Make the code more complicated, so that + GCC does not grok how to optimize it. */ + int err[2]; + err[0] = errno; + err[1] = errno; + errno = 0; + free (p); + errno = err[errno == 0]; +#else int err = errno; free (p); errno = err; +#endif } diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index c457ac6120..07736f9b8b 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -516,6 +516,7 @@ GNULIB_SYMLINK = @GNULIB_SYMLINK@ GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@ GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@ GNULIB_TIMEGM = @GNULIB_TIMEGM@ +GNULIB_TIMESPEC_GET = @GNULIB_TIMESPEC_GET@ GNULIB_TIME_R = @GNULIB_TIME_R@ GNULIB_TIME_RZ = @GNULIB_TIME_RZ@ GNULIB_TMPFILE = @GNULIB_TMPFILE@ @@ -746,6 +747,7 @@ HAVE_SYS_SELECT_H = @HAVE_SYS_SELECT_H@ HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@ HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ HAVE_TIMEGM = @HAVE_TIMEGM@ +HAVE_TIMESPEC_GET = @HAVE_TIMESPEC_GET@ HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@ HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@ HAVE_UNISTD_H = @HAVE_UNISTD_H@ @@ -949,6 +951,7 @@ REPLACE_FCNTL = @REPLACE_FCNTL@ REPLACE_FDOPEN = @REPLACE_FDOPEN@ REPLACE_FDOPENDIR = @REPLACE_FDOPENDIR@ REPLACE_FFLUSH = @REPLACE_FFLUSH@ +REPLACE_FFSLL = @REPLACE_FFSLL@ REPLACE_FOPEN = @REPLACE_FOPEN@ REPLACE_FPRINTF = @REPLACE_FPRINTF@ REPLACE_FPURGE = @REPLACE_FPURGE@ @@ -989,7 +992,9 @@ REPLACE_MEMCHR = @REPLACE_MEMCHR@ REPLACE_MEMMEM = @REPLACE_MEMMEM@ REPLACE_MKDIR = @REPLACE_MKDIR@ REPLACE_MKFIFO = @REPLACE_MKFIFO@ +REPLACE_MKFIFOAT = @REPLACE_MKFIFOAT@ REPLACE_MKNOD = @REPLACE_MKNOD@ +REPLACE_MKNODAT = @REPLACE_MKNODAT@ REPLACE_MKSTEMP = @REPLACE_MKSTEMP@ REPLACE_MKTIME = @REPLACE_MKTIME@ REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@ @@ -1087,6 +1092,7 @@ SYSTEM_TYPE = @SYSTEM_TYPE@ SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ TERMCAP_OBJ = @TERMCAP_OBJ@ TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@ +TIME_H_DEFINES_TIME_UTC = @TIME_H_DEFINES_TIME_UTC@ TOOLKIT_LIBW = @TOOLKIT_LIBW@ UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@ UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@ @@ -1171,6 +1177,7 @@ gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1 = @gl_GNULIB_ENABLED_a9786850 gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36 = @gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36@ gl_GNULIB_ENABLED_cloexec = @gl_GNULIB_ENABLED_cloexec@ gl_GNULIB_ENABLED_dirfd = @gl_GNULIB_ENABLED_dirfd@ +gl_GNULIB_ENABLED_dynarray = @gl_GNULIB_ENABLED_dynarray@ gl_GNULIB_ENABLED_euidaccess = @gl_GNULIB_ENABLED_euidaccess@ gl_GNULIB_ENABLED_getdtablesize = @gl_GNULIB_ENABLED_getdtablesize@ gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@ @@ -1584,6 +1591,20 @@ EXTRA_libgnu_a_SOURCES += dup2.c endif ## end gnulib module dup2 +## begin gnulib module dynarray +ifeq (,$(OMIT_GNULIB_MODULE_dynarray)) + +ifneq (,$(gl_GNULIB_ENABLED_dynarray)) +libgnu_a_SOURCES += malloc/dynarray_at_failure.c malloc/dynarray_emplace_enlarge.c malloc/dynarray_finalize.c malloc/dynarray_resize.c malloc/dynarray_resize_clear.c + +endif +EXTRA_DIST += dynarray.h malloc/dynarray-skeleton.c malloc/dynarray.h + +EXTRA_libgnu_a_SOURCES += malloc/dynarray-skeleton.c + +endif +## end gnulib module dynarray + ## begin gnulib module eloop-threshold ifeq (,$(OMIT_GNULIB_MODULE_eloop-threshold)) @@ -3036,6 +3057,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''HAVE_SIGDESCR_NP''@|$(HAVE_SIGDESCR_NP)|g' \ -e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \ -e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \ + -e 's|@''REPLACE_FFSLL''@|$(REPLACE_FFSLL)|g' \ -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \ -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \ -e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \ @@ -3237,7 +3259,9 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU -e 's|@''REPLACE_LSTAT''@|$(REPLACE_LSTAT)|g' \ -e 's|@''REPLACE_MKDIR''@|$(REPLACE_MKDIR)|g' \ -e 's|@''REPLACE_MKFIFO''@|$(REPLACE_MKFIFO)|g' \ + -e 's|@''REPLACE_MKFIFOAT''@|$(REPLACE_MKFIFOAT)|g' \ -e 's|@''REPLACE_MKNOD''@|$(REPLACE_MKNOD)|g' \ + -e 's|@''REPLACE_MKNODAT''@|$(REPLACE_MKNODAT)|g' \ -e 's|@''REPLACE_STAT''@|$(REPLACE_STAT)|g' \ -e 's|@''REPLACE_UTIMENSAT''@|$(REPLACE_UTIMENSAT)|g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ @@ -3350,6 +3374,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's/@''GNULIB_STRFTIME''@/$(GNULIB_STRFTIME)/g' \ -e 's/@''GNULIB_STRPTIME''@/$(GNULIB_STRPTIME)/g' \ -e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \ + -e 's/@''GNULIB_TIMESPEC_GET''@/$(GNULIB_TIMESPEC_GET)/g' \ -e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \ -e 's/@''GNULIB_TIME_RZ''@/$(GNULIB_TIME_RZ)/g' \ -e 's/@''GNULIB_TZSET''@/$(GNULIB_TZSET)/g' \ @@ -3358,6 +3383,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \ -e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \ -e 's|@''HAVE_TIMEGM''@|$(HAVE_TIMEGM)|g' \ + -e 's|@''HAVE_TIMESPEC_GET''@|$(HAVE_TIMESPEC_GET)|g' \ -e 's|@''HAVE_TIMEZONE_T''@|$(HAVE_TIMEZONE_T)|g' \ -e 's|@''REPLACE_CTIME''@|$(REPLACE_CTIME)|g' \ -e 's|@''REPLACE_GMTIME''@|$(REPLACE_GMTIME)|g' \ @@ -3372,6 +3398,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''SYS_TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(SYS_TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \ -e 's|@''TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \ -e 's|@''UNISTD_H_DEFINES_STRUCT_TIMESPEC''@|$(UNISTD_H_DEFINES_STRUCT_TIMESPEC)|g' \ + -e 's|@''TIME_H_DEFINES_TIME_UTC''@|$(TIME_H_DEFINES_TIME_UTC)|g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ diff --git a/lib/libc-config.h b/lib/libc-config.h index d4e29951f3..c0eac707cf 100644 --- a/lib/libc-config.h +++ b/lib/libc-config.h @@ -71,107 +71,112 @@ # endif #endif - -/* Prepare to include , which is our copy of glibc - . */ +#ifndef __attribute_maybe_unused__ +/* either does not exist, or is too old for Gnulib. + Prepare to include , which is Gnulib's version of a + more-recent glibc . */ /* Define _FEATURES_H so that does not include . */ -#ifndef _FEATURES_H -# define _FEATURES_H 1 -#endif +# ifndef _FEATURES_H +# define _FEATURES_H 1 +# endif /* Define __WORDSIZE so that does not attempt to include nonexistent files. Make it a syntax error, since Gnulib does not use __WORDSIZE now, and if Gnulib uses it later the syntax error will let us know that __WORDSIZE needs configuring. */ -#ifndef __WORDSIZE -# define __WORDSIZE %%% -#endif +# ifndef __WORDSIZE +# define __WORDSIZE %%% +# endif /* Undef the macros unconditionally defined by our copy of glibc , so that they do not clash with any system-defined versions. */ -#undef _SYS_CDEFS_H -#undef __ASMNAME -#undef __ASMNAME2 -#undef __BEGIN_DECLS -#undef __CONCAT -#undef __END_DECLS -#undef __HAVE_GENERIC_SELECTION -#undef __LDBL_COMPAT -#undef __LDBL_REDIR -#undef __LDBL_REDIR1 -#undef __LDBL_REDIR1_DECL -#undef __LDBL_REDIR1_NTH -#undef __LDBL_REDIR_DECL -#undef __LDBL_REDIR_NTH -#undef __LEAF -#undef __LEAF_ATTR -#undef __NTH -#undef __NTHNL -#undef __P -#undef __PMT -#undef __REDIRECT -#undef __REDIRECT_LDBL -#undef __REDIRECT_NTH -#undef __REDIRECT_NTHNL -#undef __REDIRECT_NTH_LDBL -#undef __STRING -#undef __THROW -#undef __THROWNL -#undef __always_inline -#undef __attribute__ -#undef __attribute_alloc_size__ -#undef __attribute_artificial__ -#undef __attribute_const__ -#undef __attribute_deprecated__ -#undef __attribute_deprecated_msg__ -#undef __attribute_format_arg__ -#undef __attribute_format_strfmon__ -#undef __attribute_malloc__ -#undef __attribute_noinline__ -#undef __attribute_nonstring__ -#undef __attribute_pure__ -#undef __attribute_used__ -#undef __attribute_warn_unused_result__ -#undef __bos -#undef __bos0 -#undef __errordecl -#undef __extension__ -#undef __extern_always_inline -#undef __extern_inline -#undef __flexarr -#undef __fortify_function -#undef __glibc_c99_flexarr_available -#undef __glibc_clang_has_extension -#undef __glibc_likely -#undef __glibc_macro_warning -#undef __glibc_macro_warning1 -#undef __glibc_unlikely -#undef __inline -#undef __ptr_t -#undef __restrict -#undef __restrict_arr -#undef __va_arg_pack -#undef __va_arg_pack_len -#undef __warnattr -#undef __warndecl +# undef _SYS_CDEFS_H +# undef __ASMNAME +# undef __ASMNAME2 +# undef __BEGIN_DECLS +# undef __CONCAT +# undef __END_DECLS +# undef __HAVE_GENERIC_SELECTION +# undef __LDBL_COMPAT +# undef __LDBL_REDIR +# undef __LDBL_REDIR1 +# undef __LDBL_REDIR1_DECL +# undef __LDBL_REDIR1_NTH +# undef __LDBL_REDIR2_DECL +# undef __LDBL_REDIR_DECL +# undef __LDBL_REDIR_NTH +# undef __LEAF +# undef __LEAF_ATTR +# undef __NTH +# undef __NTHNL +# undef __REDIRECT +# undef __REDIRECT_LDBL +# undef __REDIRECT_NTH +# undef __REDIRECT_NTHNL +# undef __REDIRECT_NTH_LDBL +# undef __STRING +# undef __THROW +# undef __THROWNL +# undef __attr_access +# undef __attribute__ +# undef __attribute_alloc_size__ +# undef __attribute_artificial__ +# undef __attribute_const__ +# undef __attribute_deprecated__ +# undef __attribute_deprecated_msg__ +# undef __attribute_format_arg__ +# undef __attribute_format_strfmon__ +# undef __attribute_malloc__ +# undef __attribute_noinline__ +# undef __attribute_nonstring__ +# undef __attribute_pure__ +# undef __attribute_returns_twice__ +# undef __attribute_used__ +# undef __attribute_warn_unused_result__ +# undef __bos +# undef __bos0 +# undef __errordecl +# undef __extension__ +# undef __extern_always_inline +# undef __extern_inline +# undef __flexarr +# undef __fortify_function +# undef __glibc_c99_flexarr_available +# undef __glibc_has_attribute +# undef __glibc_has_builtin +# undef __glibc_has_extension +# undef __glibc_macro_warning +# undef __glibc_macro_warning1 +# undef __glibc_objsize +# undef __glibc_objsize0 +# undef __glibc_unlikely +# undef __inline +# undef __ptr_t +# undef __restrict +# undef __restrict_arr +# undef __va_arg_pack +# undef __va_arg_pack_len +# undef __warnattr /* Include our copy of glibc . */ -#include +# include /* __inline is too pessimistic for non-GCC. */ -#undef __inline -#ifndef HAVE___INLINE -# if 199901 <= __STDC_VERSION__ || defined inline -# define __inline inline -# else -# define __inline +# undef __inline +# ifndef HAVE___INLINE +# if 199901 <= __STDC_VERSION__ || defined inline +# define __inline inline +# else +# define __inline +# endif # endif -#endif + +#endif /* defined __glibc_likely */ /* A substitute for glibc , good enough for Gnulib. */ #define attribute_hidden -#define libc_hidden_proto(name, ...) +#define libc_hidden_proto(name) #define libc_hidden_def(name) #define libc_hidden_weak(name) #define libc_hidden_ver(local, name) diff --git a/lib/malloc/dynarray-skeleton.c b/lib/malloc/dynarray-skeleton.c new file mode 100644 index 0000000000..4995fd1c04 --- /dev/null +++ b/lib/malloc/dynarray-skeleton.c @@ -0,0 +1,525 @@ +/* Type-safe arrays which grow dynamically. + Copyright (C) 2017-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with the GNU C Library; if not, see + . */ + +/* Pre-processor macros which act as parameters: + + DYNARRAY_STRUCT + The struct tag of dynamic array to be defined. + DYNARRAY_ELEMENT + The type name of the element type. Elements are copied + as if by memcpy, and can change address as the dynamic + array grows. + DYNARRAY_PREFIX + The prefix of the functions which are defined. + + The following parameters are optional: + + DYNARRAY_ELEMENT_FREE + DYNARRAY_ELEMENT_FREE (E) is evaluated to deallocate the + contents of elements. E is of type DYNARRAY_ELEMENT *. + DYNARRAY_ELEMENT_INIT + DYNARRAY_ELEMENT_INIT (E) is evaluated to initialize a new + element. E is of type DYNARRAY_ELEMENT *. + If DYNARRAY_ELEMENT_FREE but not DYNARRAY_ELEMENT_INIT is + defined, new elements are automatically zero-initialized. + Otherwise, new elements have undefined contents. + DYNARRAY_INITIAL_SIZE + The size of the statically allocated array (default: + at least 2, more elements if they fit into 128 bytes). + Must be a preprocessor constant. If DYNARRAY_INITIAL_SIZE is 0, + there is no statically allocated array at, and all non-empty + arrays are heap-allocated. + DYNARRAY_FINAL_TYPE + The name of the type which holds the final array. If not + defined, is PREFIX##finalize not provided. DYNARRAY_FINAL_TYPE + must be a struct type, with members of type DYNARRAY_ELEMENT and + size_t at the start (in this order). + + These macros are undefined after this header file has been + included. + + The following types are provided (their members are private to the + dynarray implementation): + + struct DYNARRAY_STRUCT + + The following functions are provided: + + void DYNARRAY_PREFIX##init (struct DYNARRAY_STRUCT *); + void DYNARRAY_PREFIX##free (struct DYNARRAY_STRUCT *); + bool DYNARRAY_PREFIX##has_failed (const struct DYNARRAY_STRUCT *); + void DYNARRAY_PREFIX##mark_failed (struct DYNARRAY_STRUCT *); + size_t DYNARRAY_PREFIX##size (const struct DYNARRAY_STRUCT *); + DYNARRAY_ELEMENT *DYNARRAY_PREFIX##begin (const struct DYNARRAY_STRUCT *); + DYNARRAY_ELEMENT *DYNARRAY_PREFIX##end (const struct DYNARRAY_STRUCT *); + DYNARRAY_ELEMENT *DYNARRAY_PREFIX##at (struct DYNARRAY_STRUCT *, size_t); + void DYNARRAY_PREFIX##add (struct DYNARRAY_STRUCT *, DYNARRAY_ELEMENT); + DYNARRAY_ELEMENT *DYNARRAY_PREFIX##emplace (struct DYNARRAY_STRUCT *); + bool DYNARRAY_PREFIX##resize (struct DYNARRAY_STRUCT *, size_t); + void DYNARRAY_PREFIX##remove_last (struct DYNARRAY_STRUCT *); + void DYNARRAY_PREFIX##clear (struct DYNARRAY_STRUCT *); + + The following functions are provided are provided if the + prerequisites are met: + + bool DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *, + DYNARRAY_FINAL_TYPE *); + (if DYNARRAY_FINAL_TYPE is defined) + DYNARRAY_ELEMENT *DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *, + size_t *); + (if DYNARRAY_FINAL_TYPE is not defined) +*/ + +#include + +#include +#include +#include + +#ifndef DYNARRAY_STRUCT +# error "DYNARRAY_STRUCT must be defined" +#endif + +#ifndef DYNARRAY_ELEMENT +# error "DYNARRAY_ELEMENT must be defined" +#endif + +#ifndef DYNARRAY_PREFIX +# error "DYNARRAY_PREFIX must be defined" +#endif + +#ifdef DYNARRAY_INITIAL_SIZE +# if DYNARRAY_INITIAL_SIZE < 0 +# error "DYNARRAY_INITIAL_SIZE must be non-negative" +# endif +# if DYNARRAY_INITIAL_SIZE > 0 +# define DYNARRAY_HAVE_SCRATCH 1 +# else +# define DYNARRAY_HAVE_SCRATCH 0 +# endif +#else +/* Provide a reasonable default which limits the size of + DYNARRAY_STRUCT. */ +# define DYNARRAY_INITIAL_SIZE \ + (sizeof (DYNARRAY_ELEMENT) > 64 ? 2 : 128 / sizeof (DYNARRAY_ELEMENT)) +# define DYNARRAY_HAVE_SCRATCH 1 +#endif + +/* Public type definitions. */ + +/* All fields of this struct are private to the implementation. */ +struct DYNARRAY_STRUCT +{ + union + { + struct dynarray_header dynarray_abstract; + struct + { + /* These fields must match struct dynarray_header. */ + size_t used; + size_t allocated; + DYNARRAY_ELEMENT *array; + } dynarray_header; + } u; + +#if DYNARRAY_HAVE_SCRATCH + /* Initial inline allocation. */ + DYNARRAY_ELEMENT scratch[DYNARRAY_INITIAL_SIZE]; +#endif +}; + +/* Internal use only: Helper macros. */ + +/* Ensure macro-expansion of DYNARRAY_PREFIX. */ +#define DYNARRAY_CONCAT0(prefix, name) prefix##name +#define DYNARRAY_CONCAT1(prefix, name) DYNARRAY_CONCAT0(prefix, name) +#define DYNARRAY_NAME(name) DYNARRAY_CONCAT1(DYNARRAY_PREFIX, name) + +/* Use DYNARRAY_FREE instead of DYNARRAY_NAME (free), + so that Gnulib does not change 'free' to 'rpl_free'. */ +#define DYNARRAY_FREE DYNARRAY_CONCAT1 (DYNARRAY_NAME (f), ree) + +/* Address of the scratch buffer if any. */ +#if DYNARRAY_HAVE_SCRATCH +# define DYNARRAY_SCRATCH(list) (list)->scratch +#else +# define DYNARRAY_SCRATCH(list) NULL +#endif + +/* Internal use only: Helper functions. */ + +/* Internal function. Call DYNARRAY_ELEMENT_FREE with the array + elements. Name mangling needed due to the DYNARRAY_ELEMENT_FREE + macro expansion. */ +static inline void +DYNARRAY_NAME (free__elements__) (DYNARRAY_ELEMENT *__dynarray_array, + size_t __dynarray_used) +{ +#ifdef DYNARRAY_ELEMENT_FREE + for (size_t __dynarray_i = 0; __dynarray_i < __dynarray_used; ++__dynarray_i) + DYNARRAY_ELEMENT_FREE (&__dynarray_array[__dynarray_i]); +#endif /* DYNARRAY_ELEMENT_FREE */ +} + +/* Internal function. Free the non-scratch array allocation. */ +static inline void +DYNARRAY_NAME (free__array__) (struct DYNARRAY_STRUCT *list) +{ +#if DYNARRAY_HAVE_SCRATCH + if (list->u.dynarray_header.array != list->scratch) + free (list->u.dynarray_header.array); +#else + free (list->u.dynarray_header.array); +#endif +} + +/* Public functions. */ + +/* Initialize a dynamic array object. This must be called before any + use of the object. */ +__nonnull ((1)) +static void +DYNARRAY_NAME (init) (struct DYNARRAY_STRUCT *list) +{ + list->u.dynarray_header.used = 0; + list->u.dynarray_header.allocated = DYNARRAY_INITIAL_SIZE; + list->u.dynarray_header.array = DYNARRAY_SCRATCH (list); +} + +/* Deallocate the dynamic array and its elements. */ +__attribute_maybe_unused__ __nonnull ((1)) +static void +DYNARRAY_FREE (struct DYNARRAY_STRUCT *list) +{ + DYNARRAY_NAME (free__elements__) + (list->u.dynarray_header.array, list->u.dynarray_header.used); + DYNARRAY_NAME (free__array__) (list); + DYNARRAY_NAME (init) (list); +} + +/* Return true if the dynamic array is in an error state. */ +__nonnull ((1)) +static inline bool +DYNARRAY_NAME (has_failed) (const struct DYNARRAY_STRUCT *list) +{ + return list->u.dynarray_header.allocated == __dynarray_error_marker (); +} + +/* Mark the dynamic array as failed. All elements are deallocated as + a side effect. */ +__nonnull ((1)) +static void +DYNARRAY_NAME (mark_failed) (struct DYNARRAY_STRUCT *list) +{ + DYNARRAY_NAME (free__elements__) + (list->u.dynarray_header.array, list->u.dynarray_header.used); + DYNARRAY_NAME (free__array__) (list); + list->u.dynarray_header.array = DYNARRAY_SCRATCH (list); + list->u.dynarray_header.used = 0; + list->u.dynarray_header.allocated = __dynarray_error_marker (); +} + +/* Return the number of elements which have been added to the dynamic + array. */ +__nonnull ((1)) +static inline size_t +DYNARRAY_NAME (size) (const struct DYNARRAY_STRUCT *list) +{ + return list->u.dynarray_header.used; +} + +/* Return a pointer to the array element at INDEX. Terminate the + process if INDEX is out of bounds. */ +__nonnull ((1)) +static inline DYNARRAY_ELEMENT * +DYNARRAY_NAME (at) (struct DYNARRAY_STRUCT *list, size_t index) +{ + if (__glibc_unlikely (index >= DYNARRAY_NAME (size) (list))) + __libc_dynarray_at_failure (DYNARRAY_NAME (size) (list), index); + return list->u.dynarray_header.array + index; +} + +/* Return a pointer to the first array element, if any. For a + zero-length array, the pointer can be NULL even though the dynamic + array has not entered the failure state. */ +__nonnull ((1)) +static inline DYNARRAY_ELEMENT * +DYNARRAY_NAME (begin) (struct DYNARRAY_STRUCT *list) +{ + return list->u.dynarray_header.array; +} + +/* Return a pointer one element past the last array element. For a + zero-length array, the pointer can be NULL even though the dynamic + array has not entered the failure state. */ +__nonnull ((1)) +static inline DYNARRAY_ELEMENT * +DYNARRAY_NAME (end) (struct DYNARRAY_STRUCT *list) +{ + return list->u.dynarray_header.array + list->u.dynarray_header.used; +} + +/* Internal function. Slow path for the add function below. */ +static void +DYNARRAY_NAME (add__) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item) +{ + if (__glibc_unlikely + (!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract, + DYNARRAY_SCRATCH (list), + sizeof (DYNARRAY_ELEMENT)))) + { + DYNARRAY_NAME (mark_failed) (list); + return; + } + + /* Copy the new element and increase the array length. */ + list->u.dynarray_header.array[list->u.dynarray_header.used++] = item; +} + +/* Add ITEM at the end of the array, enlarging it by one element. + Mark *LIST as failed if the dynamic array allocation size cannot be + increased. */ +__nonnull ((1)) +static inline void +DYNARRAY_NAME (add) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item) +{ + /* Do nothing in case of previous error. */ + if (DYNARRAY_NAME (has_failed) (list)) + return; + + /* Enlarge the array if necessary. */ + if (__glibc_unlikely (list->u.dynarray_header.used + == list->u.dynarray_header.allocated)) + { + DYNARRAY_NAME (add__) (list, item); + return; + } + + /* Copy the new element and increase the array length. */ + list->u.dynarray_header.array[list->u.dynarray_header.used++] = item; +} + +/* Internal function. Building block for the emplace functions below. + Assumes space for one more element in *LIST. */ +static inline DYNARRAY_ELEMENT * +DYNARRAY_NAME (emplace__tail__) (struct DYNARRAY_STRUCT *list) +{ + DYNARRAY_ELEMENT *result + = &list->u.dynarray_header.array[list->u.dynarray_header.used]; + ++list->u.dynarray_header.used; +#if defined (DYNARRAY_ELEMENT_INIT) + DYNARRAY_ELEMENT_INIT (result); +#elif defined (DYNARRAY_ELEMENT_FREE) + memset (result, 0, sizeof (*result)); +#endif + return result; +} + +/* Internal function. Slow path for the emplace function below. */ +static DYNARRAY_ELEMENT * +DYNARRAY_NAME (emplace__) (struct DYNARRAY_STRUCT *list) +{ + if (__glibc_unlikely + (!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract, + DYNARRAY_SCRATCH (list), + sizeof (DYNARRAY_ELEMENT)))) + { + DYNARRAY_NAME (mark_failed) (list); + return NULL; + } + return DYNARRAY_NAME (emplace__tail__) (list); +} + +/* Allocate a place for a new element in *LIST and return a pointer to + it. The pointer can be NULL if the dynamic array cannot be + enlarged due to a memory allocation failure. */ +__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1)) +static +/* Avoid inlining with the larger initialization code. */ +#if !(defined (DYNARRAY_ELEMENT_INIT) || defined (DYNARRAY_ELEMENT_FREE)) +inline +#endif +DYNARRAY_ELEMENT * +DYNARRAY_NAME (emplace) (struct DYNARRAY_STRUCT *list) +{ + /* Do nothing in case of previous error. */ + if (DYNARRAY_NAME (has_failed) (list)) + return NULL; + + /* Enlarge the array if necessary. */ + if (__glibc_unlikely (list->u.dynarray_header.used + == list->u.dynarray_header.allocated)) + return (DYNARRAY_NAME (emplace__) (list)); + return DYNARRAY_NAME (emplace__tail__) (list); +} + +/* Change the size of *LIST to SIZE. If SIZE is larger than the + existing size, new elements are added (which can be initialized). + Otherwise, the list is truncated, and elements are freed. Return + false on memory allocation failure (and mark *LIST as failed). */ +__attribute_maybe_unused__ __nonnull ((1)) +static bool +DYNARRAY_NAME (resize) (struct DYNARRAY_STRUCT *list, size_t size) +{ + if (size > list->u.dynarray_header.used) + { + bool ok; +#if defined (DYNARRAY_ELEMENT_INIT) + /* The new elements have to be initialized. */ + size_t old_size = list->u.dynarray_header.used; + ok = __libc_dynarray_resize (&list->u.dynarray_abstract, + size, DYNARRAY_SCRATCH (list), + sizeof (DYNARRAY_ELEMENT)); + if (ok) + for (size_t i = old_size; i < size; ++i) + { + DYNARRAY_ELEMENT_INIT (&list->u.dynarray_header.array[i]); + } +#elif defined (DYNARRAY_ELEMENT_FREE) + /* Zero initialization is needed so that the elements can be + safely freed. */ + ok = __libc_dynarray_resize_clear + (&list->u.dynarray_abstract, size, + DYNARRAY_SCRATCH (list), sizeof (DYNARRAY_ELEMENT)); +#else + ok = __libc_dynarray_resize (&list->u.dynarray_abstract, + size, DYNARRAY_SCRATCH (list), + sizeof (DYNARRAY_ELEMENT)); +#endif + if (__glibc_unlikely (!ok)) + DYNARRAY_NAME (mark_failed) (list); + return ok; + } + else + { + /* The list has shrunk in size. Free the removed elements. */ + DYNARRAY_NAME (free__elements__) + (list->u.dynarray_header.array + size, + list->u.dynarray_header.used - size); + list->u.dynarray_header.used = size; + return true; + } +} + +/* Remove the last element of LIST if it is present. */ +__attribute_maybe_unused__ __nonnull ((1)) +static void +DYNARRAY_NAME (remove_last) (struct DYNARRAY_STRUCT *list) +{ + /* used > 0 implies that the array is the non-failed state. */ + if (list->u.dynarray_header.used > 0) + { + size_t new_length = list->u.dynarray_header.used - 1; +#ifdef DYNARRAY_ELEMENT_FREE + DYNARRAY_ELEMENT_FREE (&list->u.dynarray_header.array[new_length]); +#endif + list->u.dynarray_header.used = new_length; + } +} + +/* Remove all elements from the list. The elements are freed, but the + list itself is not. */ +__attribute_maybe_unused__ __nonnull ((1)) +static void +DYNARRAY_NAME (clear) (struct DYNARRAY_STRUCT *list) +{ + /* free__elements__ does nothing if the list is in the failed + state. */ + DYNARRAY_NAME (free__elements__) + (list->u.dynarray_header.array, list->u.dynarray_header.used); + list->u.dynarray_header.used = 0; +} + +#ifdef DYNARRAY_FINAL_TYPE +/* Transfer the dynamic array to a permanent location at *RESULT. + Returns true on success on false on allocation failure. In either + case, *LIST is re-initialized and can be reused. A NULL pointer is + stored in *RESULT if LIST refers to an empty list. On success, the + pointer in *RESULT is heap-allocated and must be deallocated using + free. */ +__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1, 2)) +static bool +DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list, + DYNARRAY_FINAL_TYPE *result) +{ + struct dynarray_finalize_result res; + if (__libc_dynarray_finalize (&list->u.dynarray_abstract, + DYNARRAY_SCRATCH (list), + sizeof (DYNARRAY_ELEMENT), &res)) + { + /* On success, the result owns all the data. */ + DYNARRAY_NAME (init) (list); + *result = (DYNARRAY_FINAL_TYPE) { res.array, res.length }; + return true; + } + else + { + /* On error, we need to free all data. */ + DYNARRAY_FREE (list); + errno = ENOMEM; + return false; + } +} +#else /* !DYNARRAY_FINAL_TYPE */ +/* Transfer the dynamic array to a heap-allocated array and return a + pointer to it. The pointer is NULL if memory allocation fails, or + if the array is empty, so this function should be used only for + arrays which are known not be empty (usually because they always + have a sentinel at the end). If LENGTHP is not NULL, the array + length is written to *LENGTHP. *LIST is re-initialized and can be + reused. */ +__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1)) +static DYNARRAY_ELEMENT * +DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list, size_t *lengthp) +{ + struct dynarray_finalize_result res; + if (__libc_dynarray_finalize (&list->u.dynarray_abstract, + DYNARRAY_SCRATCH (list), + sizeof (DYNARRAY_ELEMENT), &res)) + { + /* On success, the result owns all the data. */ + DYNARRAY_NAME (init) (list); + if (lengthp != NULL) + *lengthp = res.length; + return res.array; + } + else + { + /* On error, we need to free all data. */ + DYNARRAY_FREE (list); + errno = ENOMEM; + return NULL; + } +} +#endif /* !DYNARRAY_FINAL_TYPE */ + +/* Undo macro definitions. */ + +#undef DYNARRAY_CONCAT0 +#undef DYNARRAY_CONCAT1 +#undef DYNARRAY_NAME +#undef DYNARRAY_SCRATCH +#undef DYNARRAY_HAVE_SCRATCH + +#undef DYNARRAY_STRUCT +#undef DYNARRAY_ELEMENT +#undef DYNARRAY_PREFIX +#undef DYNARRAY_ELEMENT_FREE +#undef DYNARRAY_ELEMENT_INIT +#undef DYNARRAY_INITIAL_SIZE +#undef DYNARRAY_FINAL_TYPE diff --git a/lib/malloc/dynarray.h b/lib/malloc/dynarray.h new file mode 100644 index 0000000000..84e4394bf3 --- /dev/null +++ b/lib/malloc/dynarray.h @@ -0,0 +1,178 @@ +/* Type-safe arrays which grow dynamically. Shared definitions. + Copyright (C) 2017-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with the GNU C Library; if not, see + . */ + +/* To use the dynarray facility, you need to include + and define the parameter macros + documented in that file. + + A minimal example which provides a growing list of integers can be + defined like this: + + struct int_array + { + // Pointer to result array followed by its length, + // as required by DYNARRAY_FINAL_TYPE. + int *array; + size_t length; + }; + + #define DYNARRAY_STRUCT dynarray_int + #define DYNARRAY_ELEMENT int + #define DYNARRAY_PREFIX dynarray_int_ + #define DYNARRAY_FINAL_TYPE struct int_array + #include + + To create a three-element array with elements 1, 2, 3, use this + code: + + struct dynarray_int dyn; + dynarray_int_init (&dyn); + for (int i = 1; i <= 3; ++i) + { + int *place = dynarray_int_emplace (&dyn); + assert (place != NULL); + *place = i; + } + struct int_array result; + bool ok = dynarray_int_finalize (&dyn, &result); + assert (ok); + assert (result.length == 3); + assert (result.array[0] == 1); + assert (result.array[1] == 2); + assert (result.array[2] == 3); + free (result.array); + + If the elements contain resources which must be freed, define + DYNARRAY_ELEMENT_FREE appropriately, like this: + + struct str_array + { + char **array; + size_t length; + }; + + #define DYNARRAY_STRUCT dynarray_str + #define DYNARRAY_ELEMENT char * + #define DYNARRAY_ELEMENT_FREE(ptr) free (*ptr) + #define DYNARRAY_PREFIX dynarray_str_ + #define DYNARRAY_FINAL_TYPE struct str_array + #include + + Compared to scratch buffers, dynamic arrays have the following + features: + + - They have an element type, and are not just an untyped buffer of + bytes. + + - When growing, previously stored elements are preserved. (It is + expected that scratch_buffer_grow_preserve and + scratch_buffer_set_array_size eventually go away because all + current users are moved to dynamic arrays.) + + - Scratch buffers have a more aggressive growth policy because + growing them typically means a retry of an operation (across an + NSS service module boundary), which is expensive. + + - For the same reason, scratch buffers have a much larger initial + stack allocation. */ + +#ifndef _DYNARRAY_H +#define _DYNARRAY_H + +#include +#include +#include + +struct dynarray_header +{ + size_t used; + size_t allocated; + void *array; +}; + +/* Marker used in the allocated member to indicate that an error was + encountered. */ +static inline size_t +__dynarray_error_marker (void) +{ + return -1; +} + +/* Internal function. See the has_failed function in + dynarray-skeleton.c. */ +static inline bool +__dynarray_error (struct dynarray_header *list) +{ + return list->allocated == __dynarray_error_marker (); +} + +/* Internal function. Enlarge the dynamically allocated area of the + array to make room for one more element. SCRATCH is a pointer to + the scratch area (which is not heap-allocated and must not be + freed). ELEMENT_SIZE is the size, in bytes, of one element. + Return false on failure, true on success. */ +bool __libc_dynarray_emplace_enlarge (struct dynarray_header *, + void *scratch, size_t element_size); + +/* Internal function. Enlarge the dynamically allocated area of the + array to make room for at least SIZE elements (which must be larger + than the existing used part of the dynamic array). SCRATCH is a + pointer to the scratch area (which is not heap-allocated and must + not be freed). ELEMENT_SIZE is the size, in bytes, of one element. + Return false on failure, true on success. */ +bool __libc_dynarray_resize (struct dynarray_header *, size_t size, + void *scratch, size_t element_size); + +/* Internal function. Like __libc_dynarray_resize, but clear the new + part of the dynamic array. */ +bool __libc_dynarray_resize_clear (struct dynarray_header *, size_t size, + void *scratch, size_t element_size); + +/* Internal type. */ +struct dynarray_finalize_result +{ + void *array; + size_t length; +}; + +/* Internal function. Copy the dynamically-allocated area to an + explicitly-sized heap allocation. SCRATCH is a pointer to the + embedded scratch space. ELEMENT_SIZE is the size, in bytes, of the + element type. On success, true is returned, and pointer and length + are written to *RESULT. On failure, false is returned. The caller + has to take care of some of the memory management; this function is + expected to be called from dynarray-skeleton.c. */ +bool __libc_dynarray_finalize (struct dynarray_header *list, void *scratch, + size_t element_size, + struct dynarray_finalize_result *result); + + +/* Internal function. Terminate the process after an index error. + SIZE is the number of elements of the dynamic array. INDEX is the + lookup index which triggered the failure. */ +_Noreturn void __libc_dynarray_at_failure (size_t size, size_t index); + +#ifndef _ISOMAC +libc_hidden_proto (__libc_dynarray_emplace_enlarge) +libc_hidden_proto (__libc_dynarray_resize) +libc_hidden_proto (__libc_dynarray_resize_clear) +libc_hidden_proto (__libc_dynarray_finalize) +libc_hidden_proto (__libc_dynarray_at_failure) +#endif + +#endif /* _DYNARRAY_H */ diff --git a/lib/malloc/dynarray_at_failure.c b/lib/malloc/dynarray_at_failure.c new file mode 100644 index 0000000000..a442459374 --- /dev/null +++ b/lib/malloc/dynarray_at_failure.c @@ -0,0 +1,35 @@ +/* Report an dynamic array index out of bounds condition. + Copyright (C) 2017-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +void +__libc_dynarray_at_failure (size_t size, size_t index) +{ +#ifdef _LIBC + char buf[200]; + __snprintf (buf, sizeof (buf), "Fatal glibc error: " + "array index %zu not less than array length %zu\n", + index, size); +#else + abort (); +#endif +} +libc_hidden_def (__libc_dynarray_at_failure) diff --git a/lib/malloc/dynarray_emplace_enlarge.c b/lib/malloc/dynarray_emplace_enlarge.c new file mode 100644 index 0000000000..7ac4b6db40 --- /dev/null +++ b/lib/malloc/dynarray_emplace_enlarge.c @@ -0,0 +1,73 @@ +/* Increase the size of a dynamic array in preparation of an emplace operation. + Copyright (C) 2017-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include + +bool +__libc_dynarray_emplace_enlarge (struct dynarray_header *list, + void *scratch, size_t element_size) +{ + size_t new_allocated; + if (list->allocated == 0) + { + /* No scratch buffer provided. Choose a reasonable default + size. */ + if (element_size < 4) + new_allocated = 16; + else if (element_size < 8) + new_allocated = 8; + else + new_allocated = 4; + } + else + /* Increase the allocated size, using an exponential growth + policy. */ + { + new_allocated = list->allocated + list->allocated / 2 + 1; + if (new_allocated <= list->allocated) + { + /* Overflow. */ + __set_errno (ENOMEM); + return false; + } + } + + size_t new_size; + if (INT_MULTIPLY_WRAPV (new_allocated, element_size, &new_size)) + return false; + void *new_array; + if (list->array == scratch) + { + /* The previous array was not heap-allocated. */ + new_array = malloc (new_size); + if (new_array != NULL && list->array != NULL) + memcpy (new_array, list->array, list->used * element_size); + } + else + new_array = realloc (list->array, new_size); + if (new_array == NULL) + return false; + list->array = new_array; + list->allocated = new_allocated; + return true; +} +libc_hidden_def (__libc_dynarray_emplace_enlarge) diff --git a/lib/malloc/dynarray_finalize.c b/lib/malloc/dynarray_finalize.c new file mode 100644 index 0000000000..be9441e313 --- /dev/null +++ b/lib/malloc/dynarray_finalize.c @@ -0,0 +1,62 @@ +/* Copy the dynamically-allocated area to an explicitly-sized heap allocation. + Copyright (C) 2017-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +bool +__libc_dynarray_finalize (struct dynarray_header *list, + void *scratch, size_t element_size, + struct dynarray_finalize_result *result) +{ + if (__dynarray_error (list)) + /* The caller will reported the deferred error. */ + return false; + + size_t used = list->used; + + /* Empty list. */ + if (used == 0) + { + /* An empty list could still be backed by a heap-allocated + array. Free it if necessary. */ + if (list->array != scratch) + free (list->array); + *result = (struct dynarray_finalize_result) { NULL, 0 }; + return true; + } + + size_t allocation_size = used * element_size; + void *heap_array = malloc (allocation_size); + if (heap_array != NULL) + { + /* The new array takes ownership of the strings. */ + if (list->array != NULL) + memcpy (heap_array, list->array, allocation_size); + if (list->array != scratch) + free (list->array); + *result = (struct dynarray_finalize_result) + { .array = heap_array, .length = used }; + return true; + } + else + /* The caller will perform the freeing operation. */ + return false; +} +libc_hidden_def (__libc_dynarray_finalize) diff --git a/lib/malloc/dynarray_resize.c b/lib/malloc/dynarray_resize.c new file mode 100644 index 0000000000..92bbddd446 --- /dev/null +++ b/lib/malloc/dynarray_resize.c @@ -0,0 +1,64 @@ +/* Increase the size of a dynamic array. + Copyright (C) 2017-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include + +bool +__libc_dynarray_resize (struct dynarray_header *list, size_t size, + void *scratch, size_t element_size) +{ + /* The existing allocation provides sufficient room. */ + if (size <= list->allocated) + { + list->used = size; + return true; + } + + /* Otherwise, use size as the new allocation size. The caller is + expected to provide the final size of the array, so there is no + over-allocation here. */ + + size_t new_size_bytes; + if (INT_MULTIPLY_WRAPV (size, element_size, &new_size_bytes)) + { + /* Overflow. */ + __set_errno (ENOMEM); + return false; + } + void *new_array; + if (list->array == scratch) + { + /* The previous array was not heap-allocated. */ + new_array = malloc (new_size_bytes); + if (new_array != NULL && list->array != NULL) + memcpy (new_array, list->array, list->used * element_size); + } + else + new_array = realloc (list->array, new_size_bytes); + if (new_array == NULL) + return false; + list->array = new_array; + list->allocated = size; + list->used = size; + return true; +} +libc_hidden_def (__libc_dynarray_resize) diff --git a/lib/malloc/dynarray_resize_clear.c b/lib/malloc/dynarray_resize_clear.c new file mode 100644 index 0000000000..99c2cc87c3 --- /dev/null +++ b/lib/malloc/dynarray_resize_clear.c @@ -0,0 +1,35 @@ +/* Increase the size of a dynamic array and clear the new part. + Copyright (C) 2017-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +bool +__libc_dynarray_resize_clear (struct dynarray_header *list, size_t size, + void *scratch, size_t element_size) +{ + size_t old_size = list->used; + if (!__libc_dynarray_resize (list, size, scratch, element_size)) + return false; + /* __libc_dynarray_resize already checked for overflow. */ + char *array = list->array; + memset (array + (old_size * element_size), 0, + (size - old_size) * element_size); + return true; +} +libc_hidden_def (__libc_dynarray_resize_clear) diff --git a/lib/malloc/scratch_buffer_grow.c b/lib/malloc/scratch_buffer_grow.c index 41befe3d65..e7606d81cd 100644 --- a/lib/malloc/scratch_buffer_grow.c +++ b/lib/malloc/scratch_buffer_grow.c @@ -1,5 +1,5 @@ /* Variable-sized buffer with on-stack default allocation. - Copyright (C) 2015-2020 Free Software Foundation, Inc. + Copyright (C) 2015-2021 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/lib/malloc/scratch_buffer_grow_preserve.c b/lib/malloc/scratch_buffer_grow_preserve.c index aef232938d..59f8c71000 100644 --- a/lib/malloc/scratch_buffer_grow_preserve.c +++ b/lib/malloc/scratch_buffer_grow_preserve.c @@ -1,5 +1,5 @@ /* Variable-sized buffer with on-stack default allocation. - Copyright (C) 2015-2020 Free Software Foundation, Inc. + Copyright (C) 2015-2021 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/lib/malloc/scratch_buffer_set_array_size.c b/lib/malloc/scratch_buffer_set_array_size.c index 5f5e4c24f5..e2b9f31211 100644 --- a/lib/malloc/scratch_buffer_set_array_size.c +++ b/lib/malloc/scratch_buffer_set_array_size.c @@ -1,5 +1,5 @@ /* Variable-sized buffer with on-stack default allocation. - Copyright (C) 2015-2020 Free Software Foundation, Inc. + Copyright (C) 2015-2021 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/lib/mini-gmp.c b/lib/mini-gmp.c index d34fe525e4..de061e673a 100644 --- a/lib/mini-gmp.c +++ b/lib/mini-gmp.c @@ -4521,7 +4521,7 @@ mpz_export (void *r, size_t *countp, int order, size_t size, int endian, mp_size_t un; if (nails != 0) - gmp_die ("mpz_import: Nails not supported."); + gmp_die ("mpz_export: Nails not supported."); assert (order == 1 || order == -1); assert (endian >= -1 && endian <= 1); diff --git a/lib/mktime-internal.h b/lib/mktime-internal.h index b765a37ee3..9c447bd7b0 100644 --- a/lib/mktime-internal.h +++ b/lib/mktime-internal.h @@ -1,5 +1,5 @@ /* Internals of mktime and related functions - Copyright 2016-2020 Free Software Foundation, Inc. + Copyright 2016-2021 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Paul Eggert . diff --git a/lib/nstrftime.c b/lib/nstrftime.c index 8ba6975552..2f5e4fbe63 100644 --- a/lib/nstrftime.c +++ b/lib/nstrftime.c @@ -19,7 +19,7 @@ # define USE_IN_EXTENDED_LOCALE_MODEL 1 # define HAVE_STRUCT_ERA_ENTRY 1 # define HAVE_TM_GMTOFF 1 -# define HAVE_TM_ZONE 1 +# define HAVE_STRUCT_TM_TM_ZONE 1 # define HAVE_TZNAME 1 # include "../locale/localeinfo.h" #else @@ -499,7 +499,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) #endif zone = NULL; -#if HAVE_TM_ZONE +#if HAVE_STRUCT_TM_TM_ZONE /* The POSIX test suite assumes that setting the environment variable TZ to a new value before calling strftime() will influence the result (the %Z format) even if the information in @@ -516,7 +516,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) } else { -# if !HAVE_TM_ZONE +# if !HAVE_STRUCT_TM_TM_ZONE /* Infer the zone name from *TZ instead of from TZNAME. */ tzname_vec = tz->tzname_copy; # endif diff --git a/lib/regex.c b/lib/regex.c index 88173bb105..f76a416b3b 100644 --- a/lib/regex.c +++ b/lib/regex.c @@ -1,5 +1,5 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002-2020 Free Software Foundation, Inc. + Copyright (C) 2002-2021 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . diff --git a/lib/regex_internal.h b/lib/regex_internal.h index be2fa4fe78..4c634edcbf 100644 --- a/lib/regex_internal.h +++ b/lib/regex_internal.h @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -444,25 +445,6 @@ typedef struct re_dfa_t re_dfa_t; #define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx)) #define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx)) -#if defined _LIBC || HAVE_ALLOCA -# include -#endif - -#ifndef _LIBC -# if HAVE_ALLOCA -/* The OS usually guarantees only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - allocate anything larger than 4096 bytes. Also care for the possibility - of a few compiler-allocated temporary stack slots. */ -# define __libc_use_alloca(n) ((n) < 4032) -# else -/* alloca is implemented with malloc, so just use malloc. */ -# define __libc_use_alloca(n) 0 -# undef alloca -# define alloca(n) malloc (n) -# endif -#endif - #ifdef _LIBC # define MALLOC_0_IS_NONNULL 1 #elif !defined MALLOC_0_IS_NONNULL @@ -848,12 +830,14 @@ re_string_elem_size_at (const re_string_t *pstr, Idx idx) } #endif /* RE_ENABLE_I18N */ -#ifndef FALLTHROUGH -# if (__GNUC__ >= 7) || (__clang_major__ >= 10) +#ifdef _LIBC +# if __GNUC__ >= 7 # define FALLTHROUGH __attribute__ ((__fallthrough__)) # else # define FALLTHROUGH ((void) 0) # endif +#else +# include "attribute.h" #endif #endif /* _REGEX_INTERNAL_H */ diff --git a/lib/regexec.c b/lib/regexec.c index 395e37db59..15dc57bd0e 100644 --- a/lib/regexec.c +++ b/lib/regexec.c @@ -1,5 +1,5 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002-2020 Free Software Foundation, Inc. + Copyright (C) 2002-2021 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . @@ -1355,6 +1355,12 @@ pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs, return fs->stack[num].node; } + +#define DYNARRAY_STRUCT regmatch_list +#define DYNARRAY_ELEMENT regmatch_t +#define DYNARRAY_PREFIX regmatch_list_ +#include + /* Set the positions where the subexpressions are starts/ends to registers PMATCH. Note: We assume that pmatch[0] is already set, and @@ -1370,8 +1376,8 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, re_node_set eps_via_nodes; struct re_fail_stack_t *fs; struct re_fail_stack_t fs_body = { 0, 2, NULL }; - regmatch_t *prev_idx_match; - bool prev_idx_match_malloced = false; + struct regmatch_list prev_match; + regmatch_list_init (&prev_match); DEBUG_ASSERT (nmatch > 1); DEBUG_ASSERT (mctx->state_log != NULL); @@ -1388,18 +1394,13 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, cur_node = dfa->init_node; re_node_set_init_empty (&eps_via_nodes); - if (__libc_use_alloca (nmatch * sizeof (regmatch_t))) - prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t)); - else + if (!regmatch_list_resize (&prev_match, nmatch)) { - prev_idx_match = re_malloc (regmatch_t, nmatch); - if (prev_idx_match == NULL) - { - free_fail_stack_return (fs); - return REG_ESPACE; - } - prev_idx_match_malloced = true; + regmatch_list_free (&prev_match); + free_fail_stack_return (fs); + return REG_ESPACE; } + regmatch_t *prev_idx_match = regmatch_list_begin (&prev_match); memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch); for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;) @@ -1417,8 +1418,7 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, if (reg_idx == nmatch) { re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); + regmatch_list_free (&prev_match); return free_fail_stack_return (fs); } cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, @@ -1427,8 +1427,7 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, else { re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); + regmatch_list_free (&prev_match); return REG_NOERROR; } } @@ -1442,8 +1441,7 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, if (__glibc_unlikely (cur_node == -2)) { re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); + regmatch_list_free (&prev_match); free_fail_stack_return (fs); return REG_ESPACE; } @@ -1453,15 +1451,13 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, else { re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); + regmatch_list_free (&prev_match); return REG_NOMATCH; } } } re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); + regmatch_list_free (&prev_match); return free_fail_stack_return (fs); } @@ -3251,7 +3247,7 @@ expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes, /* Build transition table for the state. Return true if successful. */ -static bool +static bool __attribute_noinline__ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) { reg_errcode_t err; @@ -3259,36 +3255,20 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) int ch; bool need_word_trtable = false; bitset_word_t elem, mask; - bool dests_node_malloced = false; - bool dest_states_malloced = false; Idx ndests; /* Number of the destination states from 'state'. */ re_dfastate_t **trtable; - re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl; - re_node_set follows, *dests_node; - bitset_t *dests_ch; + re_dfastate_t *dest_states[SBC_MAX]; + re_dfastate_t *dest_states_word[SBC_MAX]; + re_dfastate_t *dest_states_nl[SBC_MAX]; + re_node_set follows; bitset_t acceptable; - struct dests_alloc - { - re_node_set dests_node[SBC_MAX]; - bitset_t dests_ch[SBC_MAX]; - } *dests_alloc; - /* We build DFA states which corresponds to the destination nodes from 'state'. 'dests_node[i]' represents the nodes which i-th destination state contains, and 'dests_ch[i]' represents the characters which i-th destination state accepts. */ - if (__libc_use_alloca (sizeof (struct dests_alloc))) - dests_alloc = (struct dests_alloc *) alloca (sizeof (struct dests_alloc)); - else - { - dests_alloc = re_malloc (struct dests_alloc, 1); - if (__glibc_unlikely (dests_alloc == NULL)) - return false; - dests_node_malloced = true; - } - dests_node = dests_alloc->dests_node; - dests_ch = dests_alloc->dests_ch; + re_node_set dests_node[SBC_MAX]; + bitset_t dests_ch[SBC_MAX]; /* Initialize transition table. */ state->word_trtable = state->trtable = NULL; @@ -3298,8 +3278,6 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch); if (__glibc_unlikely (ndests <= 0)) { - if (dests_node_malloced) - re_free (dests_alloc); /* Return false in case of an error, true otherwise. */ if (ndests == 0) { @@ -3314,38 +3292,14 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) err = re_node_set_alloc (&follows, ndests + 1); if (__glibc_unlikely (err != REG_NOERROR)) - goto out_free; - - /* Avoid arithmetic overflow in size calculation. */ - size_t ndests_max - = ((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX) - / (3 * sizeof (re_dfastate_t *))); - if (__glibc_unlikely (ndests_max < ndests)) - goto out_free; - - if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX - + ndests * 3 * sizeof (re_dfastate_t *))) - dest_states = (re_dfastate_t **) - alloca (ndests * 3 * sizeof (re_dfastate_t *)); - else { - dest_states = re_malloc (re_dfastate_t *, ndests * 3); - if (__glibc_unlikely (dest_states == NULL)) - { -out_free: - if (dest_states_malloced) - re_free (dest_states); - re_node_set_free (&follows); - for (i = 0; i < ndests; ++i) - re_node_set_free (dests_node + i); - if (dests_node_malloced) - re_free (dests_alloc); - return false; - } - dest_states_malloced = true; + out_free: + re_node_set_free (&follows); + for (i = 0; i < ndests; ++i) + re_node_set_free (dests_node + i); + return false; } - dest_states_word = dest_states + ndests; - dest_states_nl = dest_states_word + ndests; + bitset_empty (acceptable); /* Then build the states for all destinations. */ @@ -3470,16 +3424,9 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) } } - if (dest_states_malloced) - re_free (dest_states); - re_node_set_free (&follows); for (i = 0; i < ndests; ++i) re_node_set_free (dests_node + i); - - if (dests_node_malloced) - re_free (dests_alloc); - return true; } diff --git a/lib/scratch_buffer.h b/lib/scratch_buffer.h index 3e2b5ef27d..603b0d65d0 100644 --- a/lib/scratch_buffer.h +++ b/lib/scratch_buffer.h @@ -21,6 +21,7 @@ #include +#define __libc_scratch_buffer_dupfree gl_scratch_buffer_dupfree #define __libc_scratch_buffer_grow gl_scratch_buffer_grow #define __libc_scratch_buffer_grow_preserve gl_scratch_buffer_grow_preserve #define __libc_scratch_buffer_set_array_size gl_scratch_buffer_set_array_size diff --git a/lib/stddef.in.h b/lib/stddef.in.h index ba7195a910..0f506a5b18 100644 --- a/lib/stddef.in.h +++ b/lib/stddef.in.h @@ -49,6 +49,23 @@ # ifndef _@GUARD_PREFIX@_STDDEF_H +/* On AIX 7.2, with xlc in 64-bit mode, defines max_align_t to a + type with alignment 4, but 'long' has alignment 8. */ +# if defined _AIX && defined _ARCH_PPC64 +# if !GNULIB_defined_max_align_t +# ifdef _MAX_ALIGN_T +/* /usr/include/stddef.h has already defined max_align_t. Override it. */ +typedef long rpl_max_align_t; +# define max_align_t rpl_max_align_t +# else +/* Prevent /usr/include/stddef.h from defining max_align_t. */ +typedef long max_align_t; +# define _MAX_ALIGN_T +# endif +# define GNULIB_defined_max_align_t 1 +# endif +# endif + /* The include_next requires a split double-inclusion guard. */ # @INCLUDE_NEXT@ @NEXT_STDDEF_H@ @@ -86,8 +103,10 @@ we are currently compiling with gcc. On MSVC, max_align_t is defined only in C++ mode, after was included. Its definition is good since it has an alignment of 8 (on x86 - and x86_64). */ -#if defined _MSC_VER && defined __cplusplus + and x86_64). + Similarly on OS/2 kLIBC. */ +#if (defined _MSC_VER || (defined __KLIBC__ && !defined __LIBCN__)) \ + && defined __cplusplus # include #else # if ! (@HAVE_MAX_ALIGN_T@ || defined _GCC_MAX_ALIGN_T) diff --git a/lib/string.in.h b/lib/string.in.h index 9f68e77c76..c76c1820b3 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -69,6 +69,14 @@ # include #endif +/* AIX 7.2 declares ffsl and ffsll in , not in . */ +/* But in any case avoid namespace pollution on glibc systems. */ +#if ((@GNULIB_FFSL@ || @GNULIB_FFSLL@ || defined GNULIB_POSIXCHECK) \ + && defined _AIX) \ + && ! defined __GLIBC__ +# include +#endif + /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ /* The definition of _GL_ARG_NONNULL is copied here. */ @@ -110,10 +118,18 @@ _GL_WARN_ON_USE (ffsl, "ffsl is not portable - use the ffsl module"); /* Find the index of the least-significant set bit. */ #if @GNULIB_FFSLL@ -# if !@HAVE_FFSLL@ +# if @REPLACE_FFSLL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define ffsll rpl_ffsll +# endif +_GL_FUNCDECL_RPL (ffsll, int, (long long int i)); +_GL_CXXALIAS_RPL (ffsll, int, (long long int i)); +# else +# if !@HAVE_FFSLL@ _GL_FUNCDECL_SYS (ffsll, int, (long long int i)); -# endif +# endif _GL_CXXALIAS_SYS (ffsll, int, (long long int i)); +# endif _GL_CXXALIASWARN (ffsll); #elif defined GNULIB_POSIXCHECK # undef ffsll diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h index ccdb5cbd14..13d12943cd 100644 --- a/lib/sys_stat.in.h +++ b/lib/sys_stat.in.h @@ -713,11 +713,21 @@ _GL_WARN_ON_USE (mkfifo, "mkfifo is not portable - " #if @GNULIB_MKFIFOAT@ -# if !@HAVE_MKFIFOAT@ +# if @REPLACE_MKFIFOAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mkfifoat +# define mkfifoat rpl_mkfifoat +# endif +_GL_FUNCDECL_RPL (mkfifoat, int, (int fd, char const *file, mode_t mode) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (mkfifoat, int, (int fd, char const *file, mode_t mode)); +# else +# if !@HAVE_MKFIFOAT@ _GL_FUNCDECL_SYS (mkfifoat, int, (int fd, char const *file, mode_t mode) _GL_ARG_NONNULL ((2))); -# endif +# endif _GL_CXXALIAS_SYS (mkfifoat, int, (int fd, char const *file, mode_t mode)); +# endif _GL_CXXALIASWARN (mkfifoat); #elif defined GNULIB_POSIXCHECK # undef mkfifoat @@ -756,13 +766,25 @@ _GL_WARN_ON_USE (mknod, "mknod is not portable - " #if @GNULIB_MKNODAT@ -# if !@HAVE_MKNODAT@ +# if @REPLACE_MKNODAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mknodat +# define mknodat rpl_mknodat +# endif +_GL_FUNCDECL_RPL (mknodat, int, + (int fd, char const *file, mode_t mode, dev_t dev) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (mknodat, int, + (int fd, char const *file, mode_t mode, dev_t dev)); +# else +# if !@HAVE_MKNODAT@ _GL_FUNCDECL_SYS (mknodat, int, (int fd, char const *file, mode_t mode, dev_t dev) _GL_ARG_NONNULL ((2))); -# endif +# endif _GL_CXXALIAS_SYS (mknodat, int, (int fd, char const *file, mode_t mode, dev_t dev)); +# endif _GL_CXXALIASWARN (mknodat); #elif defined GNULIB_POSIXCHECK # undef mknodat diff --git a/lib/tempname.c b/lib/tempname.c index 3d91deef1e..e243483eaf 100644 --- a/lib/tempname.c +++ b/lib/tempname.c @@ -22,6 +22,7 @@ #include #include +#include #include @@ -61,7 +62,8 @@ # define __gen_tempname gen_tempname # define __mkdir mkdir # define __open open -# define __lxstat64(version, file, buf) lstat (file, buf) +# define __lstat64(file, buf) lstat (file, buf) +# define __stat64(file, buf) stat (file, buf) # define __getrandom getrandom # define __clock_gettime64 clock_gettime # define __timespec64 timespec @@ -76,13 +78,14 @@ typedef uint_fast64_t random_value; #define BASE_62_POWER (62LL * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62) static random_value -random_bits (random_value var) +random_bits (random_value var, bool use_getrandom) { random_value r; - if (__getrandom (&r, sizeof r, 0) == sizeof r) + /* Without GRND_NONBLOCK it can be blocked for minutes on some systems. */ + if (use_getrandom && __getrandom (&r, sizeof r, GRND_NONBLOCK) == sizeof r) return r; #if _LIBC || (defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME) - /* Add entropy if getrandom is not supported. */ + /* Add entropy if getrandom did not work. */ struct __timespec64 tv; __clock_gettime64 (CLOCK_MONOTONIC, &tv); var ^= tv.tv_nsec; @@ -96,7 +99,7 @@ static int direxists (const char *dir) { struct_stat64 buf; - return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode); + return __stat64 (dir, &buf) == 0 && S_ISDIR (buf.st_mode); } /* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is @@ -188,7 +191,7 @@ try_nocreate (char *tmpl, void *flags _GL_UNUSED) { struct_stat64 st; - if (__lxstat64 (_STAT_VER, tmpl, &st) == 0 || errno == EOVERFLOW) + if (__lstat64 (tmpl, &st) == 0 || errno == EOVERFLOW) __set_errno (EEXIST); return errno == ENOENT ? 0 : -1; } @@ -267,6 +270,13 @@ try_tempname_len (char *tmpl, int suffixlen, void *args, /* How many random base-62 digits can currently be extracted from V. */ int vdigits = 0; + /* Whether to consume entropy when acquiring random bits. On the + first try it's worth the entropy cost with __GT_NOCREATE, which + is inherently insecure and can use the entropy to make it a bit + less secure. On the (rare) second and later attempts it might + help against DoS attacks. */ + bool use_getrandom = tryfunc == try_nocreate; + /* Least unfair value for V. If V is less than this, V can generate BASE_62_DIGITS digits fairly. Otherwise it might be biased. */ random_value const unfair_min @@ -290,7 +300,10 @@ try_tempname_len (char *tmpl, int suffixlen, void *args, if (vdigits == 0) { do - v = random_bits (v); + { + v = random_bits (v, use_getrandom); + use_getrandom = true; + } while (unfair_min <= v); vdigits = BASE_62_DIGITS; diff --git a/lib/time-internal.h b/lib/time-internal.h index 63a3f9e3db..067ee729ed 100644 --- a/lib/time-internal.h +++ b/lib/time-internal.h @@ -24,7 +24,7 @@ struct tm_zone members are zero. */ struct tm_zone *next; -#if HAVE_TZNAME && !HAVE_TM_ZONE +#if HAVE_TZNAME && !HAVE_STRUCT_TM_TM_ZONE /* Copies of recent strings taken from tzname[0] and tzname[1]. The copies are in ABBRS, so that they survive tzset. Null if unknown. */ char *tzname_copy[2]; diff --git a/lib/time.in.h b/lib/time.in.h index 958dc0bd29..1385980cdf 100644 --- a/lib/time.in.h +++ b/lib/time.in.h @@ -101,6 +101,25 @@ struct __time_t_must_be_integral { # define GNULIB_defined_struct_time_t_must_be_integral 1 # endif +/* Define TIME_UTC, a positive integer constant used for timespec_get(). */ +# if ! @TIME_H_DEFINES_TIME_UTC@ +# if !GNULIB_defined_TIME_UTC +# define TIME_UTC 1 +# define GNULIB_defined_TIME_UTC 1 +# endif +# endif + +/* Set *TS to the current time, and return BASE. + Upon failure, return 0. */ +# if @GNULIB_TIMESPEC_GET@ +# if ! @HAVE_TIMESPEC_GET@ +_GL_FUNCDECL_SYS (timespec_get, int, (struct timespec *ts, int base) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (timespec_get, int, (struct timespec *ts, int base)); +_GL_CXXALIASWARN (timespec_get); +# endif + /* Sleep for at least RQTP seconds unless interrupted, If interrupted, return -1 and store the remaining time into RMTP. See . */ diff --git a/lib/time_rz.c b/lib/time_rz.c index 65e20cc566..3ac053c621 100644 --- a/lib/time_rz.c +++ b/lib/time_rz.c @@ -71,7 +71,7 @@ tzalloc (char const *name) if (tz) { tz->next = NULL; -#if HAVE_TZNAME && !HAVE_TM_ZONE +#if HAVE_TZNAME && !HAVE_STRUCT_TM_TM_ZONE tz->tzname_copy[0] = tz->tzname_copy[1] = NULL; #endif tz->tz_is_set = !!name; @@ -83,13 +83,13 @@ tzalloc (char const *name) } /* Save into TZ any nontrivial time zone abbreviation used by TM, and - update *TM (if HAVE_TM_ZONE) or *TZ (if !HAVE_TM_ZONE && - HAVE_TZNAME) if they use the abbreviation. Return true if - successful, false (setting errno) otherwise. */ + update *TM (if HAVE_STRUCT_TM_TM_ZONE) or *TZ (if + !HAVE_STRUCT_TM_TM_ZONE && HAVE_TZNAME) if they use the abbreviation. + Return true if successful, false (setting errno) otherwise. */ static bool save_abbr (timezone_t tz, struct tm *tm) { -#if HAVE_TM_ZONE || HAVE_TZNAME +#if HAVE_STRUCT_TM_TM_ZONE || HAVE_TZNAME char const *zone = NULL; char *zone_copy = (char *) ""; @@ -97,7 +97,7 @@ save_abbr (timezone_t tz, struct tm *tm) int tzname_index = -1; # endif -# if HAVE_TM_ZONE +# if HAVE_STRUCT_TM_TM_ZONE zone = tm->tm_zone; # endif @@ -145,7 +145,7 @@ save_abbr (timezone_t tz, struct tm *tm) } /* Replace the zone name so that its lifetime matches that of TZ. */ -# if HAVE_TM_ZONE +# if HAVE_STRUCT_TM_TM_ZONE tm->tm_zone = zone_copy; # else if (0 <= tzname_index) @@ -303,7 +303,7 @@ mktime_z (timezone_t tz, struct tm *tm) tm_1.tm_isdst = tm->tm_isdst; time_t t = mktime (&tm_1); bool ok = 0 <= tm_1.tm_yday; -#if HAVE_TM_ZONE || HAVE_TZNAME +#if HAVE_STRUCT_TM_TM_ZONE || HAVE_TZNAME ok = ok && save_abbr (tz, &tm_1); #endif if (revert_tz (old_tz) && ok) diff --git a/lib/timegm.c b/lib/timegm.c index fa30943084..e4127e71c0 100644 --- a/lib/timegm.c +++ b/lib/timegm.c @@ -1,6 +1,6 @@ /* Convert UTC calendar time to simple time. Like mktime but assumes UTC. - Copyright (C) 1994-2020 Free Software Foundation, Inc. + Copyright (C) 1994-2021 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/lib/utimens.c b/lib/utimens.c index 5bbae05813..44d1ea003e 100644 --- a/lib/utimens.c +++ b/lib/utimens.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -52,7 +53,9 @@ /* Avoid recursion with rpl_futimens or rpl_utimensat. */ #undef futimens -#undef utimensat +#if !HAVE_NEARLY_WORKING_UTIMENSAT +# undef utimensat +#endif /* Solaris 9 mistakenly succeeds when given a non-directory with a trailing slash. Force the use of rpl_stat for a fix. */ @@ -246,6 +249,20 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2]) # if HAVE_UTIMENSAT if (fd < 0) { +# if defined __APPLE__ && defined __MACH__ + size_t len = strlen (file); + if (len > 0 && file[len - 1] == '/') + { + struct stat statbuf; + if (stat (file, &statbuf) < 0) + return -1; + if (!S_ISDIR (statbuf.st_mode)) + { + errno = ENOTDIR; + return -1; + } + } +# endif result = utimensat (AT_FDCWD, file, ts, 0); # ifdef __linux__ /* Work around a kernel bug: diff --git a/lib/utimensat.c b/lib/utimensat.c index 2cea64f698..9fdecd681f 100644 --- a/lib/utimensat.c +++ b/lib/utimensat.c @@ -24,14 +24,40 @@ #include #include #include +#include +#include #include "stat-time.h" #include "timespec.h" #include "utimens.h" -#if HAVE_UTIMENSAT +#if HAVE_NEARLY_WORKING_UTIMENSAT +/* Use the original utimensat(), but correct the trailing slash handling. */ +int +rpl_utimensat (int fd, char const *file, struct timespec const times[2], + int flag) # undef utimensat +{ + size_t len = strlen (file); + if (len && file[len - 1] == '/') + { + struct stat st; + if (fstatat (fd, file, &st, flag & AT_SYMLINK_NOFOLLOW) < 0) + return -1; + if (!S_ISDIR (st.st_mode)) + { + errno = ENOTDIR; + return -1; + } + } + + return utimensat (fd, file, times, flag); +} + +#else + +# if HAVE_UTIMENSAT /* If we have a native utimensat, but are compiling this file, then utimensat was defined to rpl_utimensat by our replacement @@ -42,24 +68,25 @@ local_utimensat provides the fallback manipulation. */ static int local_utimensat (int, char const *, struct timespec const[2], int); -# define AT_FUNC_NAME local_utimensat +# define AT_FUNC_NAME local_utimensat /* Like utimensat, but work around native bugs. */ int rpl_utimensat (int fd, char const *file, struct timespec const times[2], int flag) +# undef utimensat { -# if defined __linux__ || defined __sun +# if defined __linux__ || defined __sun struct timespec ts[2]; -# endif +# endif /* See comments in utimens.c for details. */ static int utimensat_works_really; /* 0 = unknown, 1 = yes, -1 = no. */ if (0 <= utimensat_works_really) { int result; -# if defined __linux__ || defined __sun +# if defined __linux__ || defined __sun struct stat st; /* As recently as Linux kernel 2.6.32 (Dec 2009), several file systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT, @@ -90,7 +117,7 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], ts[1] = times[1]; times = ts; } -# ifdef __hppa__ +# ifdef __hppa__ /* Linux kernel 2.6.22.19 on hppa does not reject invalid tv_nsec values. */ else if (times @@ -104,8 +131,36 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], errno = EINVAL; return -1; } +# endif +# endif +# if defined __APPLE__ && defined __MACH__ + /* macOS 10.13 does not reject invalid tv_nsec values either. */ + if (times + && ((times[0].tv_nsec != UTIME_OMIT + && times[0].tv_nsec != UTIME_NOW + && ! (0 <= times[0].tv_nsec + && times[0].tv_nsec < TIMESPEC_HZ)) + || (times[1].tv_nsec != UTIME_OMIT + && times[1].tv_nsec != UTIME_NOW + && ! (0 <= times[1].tv_nsec + && times[1].tv_nsec < TIMESPEC_HZ)))) + { + errno = EINVAL; + return -1; + } + size_t len = strlen (file); + if (len > 0 && file[len - 1] == '/') + { + struct stat statbuf; + if (fstatat (fd, file, &statbuf, 0) < 0) + return -1; + if (!S_ISDIR (statbuf.st_mode)) + { + errno = ENOTDIR; + return -1; + } + } # endif -# endif result = utimensat (fd, file, times, flag); /* Linux kernel 2.6.25 has a bug where it returns EINVAL for UTIME_NOW or UTIME_OMIT with non-zero tv_sec, which @@ -129,11 +184,11 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], return local_utimensat (fd, file, times, flag); } -#else /* !HAVE_UTIMENSAT */ +# else /* !HAVE_UTIMENSAT */ -# define AT_FUNC_NAME utimensat +# define AT_FUNC_NAME utimensat -#endif /* !HAVE_UTIMENSAT */ +# endif /* !HAVE_UTIMENSAT */ /* Set the access and modification timestamps of FILE to be TIMESPEC[0] and TIMESPEC[1], respectively; relative to directory @@ -146,15 +201,17 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], Return 0 on success, -1 (setting errno) on failure. */ /* AT_FUNC_NAME is now utimensat or local_utimensat. */ -#define AT_FUNC_F1 lutimens -#define AT_FUNC_F2 utimens -#define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW -#define AT_FUNC_POST_FILE_PARAM_DECLS , struct timespec const ts[2], int flag -#define AT_FUNC_POST_FILE_ARGS , ts -#include "at-func.c" -#undef AT_FUNC_NAME -#undef AT_FUNC_F1 -#undef AT_FUNC_F2 -#undef AT_FUNC_USE_F1_COND -#undef AT_FUNC_POST_FILE_PARAM_DECLS -#undef AT_FUNC_POST_FILE_ARGS +# define AT_FUNC_F1 lutimens +# define AT_FUNC_F2 utimens +# define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW +# define AT_FUNC_POST_FILE_PARAM_DECLS , struct timespec const ts[2], int flag +# define AT_FUNC_POST_FILE_ARGS , ts +# include "at-func.c" +# undef AT_FUNC_NAME +# undef AT_FUNC_F1 +# undef AT_FUNC_F2 +# undef AT_FUNC_USE_F1_COND +# undef AT_FUNC_POST_FILE_PARAM_DECLS +# undef AT_FUNC_POST_FILE_ARGS + +#endif /* !HAVE_NEARLY_WORKING_UTIMENSAT */ diff --git a/lib/verify.h b/lib/verify.h index 3cdcdca567..65514c34b9 100644 --- a/lib/verify.h +++ b/lib/verify.h @@ -22,16 +22,10 @@ /* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert (R, DIAGNOSTIC) - works as per C11. This is supported by GCC 4.6.0 and later, in C - mode, and by clang (also in C++ mode). + works as per C11. This is supported by GCC 4.6.0+ and by clang 4+. Define _GL_HAVE__STATIC_ASSERT1 to 1 if _Static_assert (R) works as - per C2X. This is supported by GCC 9.1 and later, and by clang in - C++1z mode. - - Define _GL_HAVE_STATIC_ASSERT1 if static_assert (R) works as per - C++17. This is supported by GCC 9.1 and later, and by clang in - C++1z mode. + per C2X. This is supported by GCC 9.1+. Support compilers claiming conformance to the relevant standard, and also support GCC when not pedantic. If we were willing to slow @@ -47,18 +41,6 @@ || (!defined __STRICT_ANSI__ && 9 <= __GNUC__)) # define _GL_HAVE__STATIC_ASSERT1 1 # endif -#else -# if 4 <= __clang_major__ -# define _GL_HAVE__STATIC_ASSERT 1 -# endif -# if 4 <= __clang_major__ && 201411 <= __cpp_static_assert -# define _GL_HAVE__STATIC_ASSERT1 1 -# endif -# if 201703L <= __cplusplus \ - || 9 <= __GNUC__ \ - || (4 <= __clang_major__ && 201411 <= __cpp_static_assert) -# define _GL_HAVE_STATIC_ASSERT1 1 -# endif #endif /* FreeBSD 9.1 , included by and lots of other @@ -225,7 +207,9 @@ template Unfortunately, unlike C11, this implementation must appear as an ordinary declaration, and cannot appear inside struct { ... }. */ -#if defined _GL_HAVE__STATIC_ASSERT +#if 200410 <= __cpp_static_assert +# define _GL_VERIFY(R, DIAGNOSTIC, ...) static_assert (R, DIAGNOSTIC) +#elif defined _GL_HAVE__STATIC_ASSERT # define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC) #else # define _GL_VERIFY(R, DIAGNOSTIC, ...) \ @@ -239,7 +223,7 @@ template # define _Static_assert(...) \ _GL_VERIFY (__VA_ARGS__, "static assertion failed", -) # endif -# if !defined _GL_HAVE_STATIC_ASSERT1 && !defined static_assert +# if __cpp_static_assert < 201411 && !defined static_assert # define static_assert _Static_assert /* C11 requires this #define. */ # endif #endif diff --git a/m4/canonicalize.m4 b/m4/canonicalize.m4 index 475fa15d6b..0dfb2da9a6 100644 --- a/m4/canonicalize.m4 +++ b/m4/canonicalize.m4 @@ -1,4 +1,4 @@ -# canonicalize.m4 serial 35 +# canonicalize.m4 serial 37 dnl Copyright (C) 2003-2007, 2009-2021 Free Software Foundation, Inc. @@ -78,68 +78,106 @@ AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE], # so is the latter. AC_DEFUN([gl_FUNC_REALPATH_WORKS], [ - AC_CHECK_FUNCS_ONCE([realpath]) + AC_CHECK_FUNCS_ONCE([realpath lstat]) AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles AC_CACHE_CHECK([whether realpath works], [gl_cv_func_realpath_works], [ rm -rf conftest.a conftest.d touch conftest.a + # Assume that if we have lstat, we can also check symlinks. + if test $ac_cv_func_lstat = yes; then + ln -s conftest.a conftest.l + fi mkdir conftest.d AC_RUN_IFELSE([ AC_LANG_PROGRAM([[ ]GL_NOCRASH[ + #include #include #include ]], [[ int result = 0; + /* This test fails on Solaris 10. */ { char *name = realpath ("conftest.a", NULL); if (!(name && *name == '/')) result |= 1; free (name); } + /* This test fails on older versions of Cygwin. */ { char *name = realpath ("conftest.b/../conftest.a", NULL); if (name != NULL) result |= 2; free (name); } + /* This test fails on Cygwin 2.9. */ + #if HAVE_LSTAT + { + char *name = realpath ("conftest.l/../conftest.a", NULL); + if (name != NULL || errno != ENOTDIR) + result |= 4; + free (name); + } + #endif + /* This test fails on Mac OS X 10.13, OpenBSD 6.0. */ { char *name = realpath ("conftest.a/", NULL); if (name != NULL) - result |= 4; + result |= 8; free (name); } + /* This test fails on AIX 7, Solaris 10. */ { char *name1 = realpath (".", NULL); char *name2 = realpath ("conftest.d//./..", NULL); if (! name1 || ! name2 || strcmp (name1, name2)) - result |= 8; + result |= 16; free (name1); free (name2); } + #ifdef __linux__ + /* On Linux, // is the same as /. See also double-slash-root.m4. + realpath() should respect this. + This test fails on musl libc 1.2.2. */ + { + char *name = realpath ("//", NULL); + if (! name || strcmp (name, "/")) + result |= 32; + free (name); + } + #endif return result; ]]) ], [gl_cv_func_realpath_works=yes], - [gl_cv_func_realpath_works=no], + [case $? in + 32) gl_cv_func_realpath_works=nearly ;; + *) gl_cv_func_realpath_works=no ;; + esac + ], [case "$host_os" in # Guess yes on glibc systems. *-gnu* | gnu*) gl_cv_func_realpath_works="guessing yes" ;; - # Guess yes on musl systems. - *-musl*) gl_cv_func_realpath_works="guessing yes" ;; + # Guess 'nearly' on musl systems. + *-musl*) gl_cv_func_realpath_works="guessing nearly" ;; + # Guess no on Cygwin. + cygwin*) gl_cv_func_realpath_works="guessing no" ;; # Guess no on native Windows. mingw*) gl_cv_func_realpath_works="guessing no" ;; # If we don't know, obey --enable-cross-guesses. *) gl_cv_func_realpath_works="$gl_cross_guess_normal" ;; esac ]) - rm -rf conftest.a conftest.d + rm -rf conftest.a conftest.l conftest.d ]) case "$gl_cv_func_realpath_works" in *yes) - AC_DEFINE([FUNC_REALPATH_WORKS], [1], [Define to 1 if realpath() - can malloc memory, always gives an absolute path, and handles - trailing slash correctly.]) + AC_DEFINE([FUNC_REALPATH_WORKS], [1], + [Define to 1 if realpath() can malloc memory, always gives an absolute path, and handles leading slashes and a trailing slash correctly.]) + ;; + *nearly) + AC_DEFINE([FUNC_REALPATH_NEARLY_WORKS], [1], + [Define to 1 if realpath() can malloc memory, always gives an absolute path, and handles a trailing slash correctly.]) ;; esac ]) diff --git a/m4/extensions.m4 b/m4/extensions.m4 index f7333acbd4..5792a9557a 100644 --- a/m4/extensions.m4 +++ b/m4/extensions.m4 @@ -1,4 +1,4 @@ -# serial 21 -*- Autoconf -*- +# serial 22 -*- Autoconf -*- # Enable extensions on systems that normally disable them. # Copyright (C) 2003, 2006-2021 Free Software Foundation, Inc. @@ -212,4 +212,16 @@ dnl it should only be defined when necessary. AC_DEFUN_ONCE([gl_USE_SYSTEM_EXTENSIONS], [ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + dnl On OpenBSD 6.8 with GCC, the include files contain a couple of + dnl definitions that are only activated with an explicit -D_ISOC11_SOURCE. + dnl That's because this version of GCC (4.2.1) supports the option + dnl '-std=gnu99' but not the option '-std=gnu11'. + AC_REQUIRE([AC_CANONICAL_HOST]) + case "$host_os" in + openbsd*) + AC_DEFINE([_ISOC11_SOURCE], [1], + [Define to enable the declarations of ISO C 11 types and functions.]) + ;; + esac ]) diff --git a/m4/fchmodat.m4 b/m4/fchmodat.m4 index 0938032779..66c0e308fc 100644 --- a/m4/fchmodat.m4 +++ b/m4/fchmodat.m4 @@ -1,4 +1,4 @@ -# fchmodat.m4 serial 5 +# fchmodat.m4 serial 6 dnl Copyright (C) 2004-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -16,11 +16,9 @@ AC_DEFUN([gl_FUNC_FCHMODAT], HAVE_FCHMODAT=0 else AC_CACHE_CHECK( - [whether fchmodat+AT_SYMLINK_NOFOLLOW works on non-symlinks], + [whether fchmodat works], [gl_cv_func_fchmodat_works], - [dnl This test fails on GNU/Linux with glibc 2.31 (but not on - dnl GNU/kFreeBSD nor GNU/Hurd) and Cygwin 2.9. - AC_RUN_IFELSE( + [AC_RUN_IFELSE( [AC_LANG_PROGRAM( [ AC_INCLUDES_DEFAULT[ @@ -44,27 +42,49 @@ AC_DEFUN([gl_FUNC_FCHMODAT], [[ int permissive = S_IRWXU | S_IRWXG | S_IRWXO; int desired = S_IRUSR | S_IWUSR; - static char const f[] = "conftest.fchmodat"; + int result = 0; + #define file "conftest.fchmodat" struct stat st; - if (creat (f, permissive) < 0) + if (creat (file, permissive) < 0) return 1; - if (fchmodat (AT_FDCWD, f, desired, AT_SYMLINK_NOFOLLOW) != 0) + /* Test whether fchmodat rejects a trailing slash on a non-directory. + This test fails on AIX 7.2. */ + if (fchmodat (AT_FDCWD, file "/", desired, 0) == 0) + result |= 2; + /* Test whether fchmodat+AT_SYMLINK_NOFOLLOW works on non-symlinks. + This test fails on GNU/Linux with glibc 2.31 (but not on + GNU/kFreeBSD nor GNU/Hurd) and Cygwin 2.9. */ + if (fchmodat (AT_FDCWD, file, desired, AT_SYMLINK_NOFOLLOW) != 0) + result |= 4; + if (stat (file, &st) != 0) return 1; - if (stat (f, &st) != 0) - return 1; - return ! ((st.st_mode & permissive) == desired); + if ((st.st_mode & permissive) != desired) + result |= 4; + return result; ]])], [gl_cv_func_fchmodat_works=yes], - [gl_cv_func_fchmodat_works=no], + [case $? in + 2) gl_cv_func_fchmodat_works='nearly' ;; + *) gl_cv_func_fchmodat_works=no ;; + esac + ], [case "$host_os" in - dnl Guess no on Linux with glibc and Cygwin, yes otherwise. + # Guess no on Linux with glibc and Cygwin. linux-gnu* | cygwin*) gl_cv_func_fchmodat_works="guessing no" ;; + # Guess 'nearly' on AIX. + aix*) gl_cv_func_fchmodat_works="guessing nearly" ;; + # If we don't know, obey --enable-cross-guesses. *) gl_cv_func_fchmodat_works="$gl_cross_guess_normal" ;; esac ]) rm -f conftest.fchmodat]) - case $gl_cv_func_fchmodat_works in + case "$gl_cv_func_fchmodat_works" in *yes) ;; + *nearly) + AC_DEFINE([HAVE_NEARLY_WORKING_FCHMODAT], [1], + [Define to 1 if fchmodat works, except for the trailing slash handling.]) + REPLACE_FCHMODAT=1 + ;; *) AC_DEFINE([NEED_FCHMODAT_NONSYMLINK_FIX], [1], [Define to 1 if fchmodat+AT_SYMLINK_NOFOLLOW does not work right on non-symlinks.]) diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4 index 535359b2cf..f2eff10de6 100644 --- a/m4/gnulib-common.m4 +++ b/m4/gnulib-common.m4 @@ -39,11 +39,12 @@ AC_DEFUN([gl_COMMON_BODY], [ this syntax with 'extern'. */ # define _Noreturn [[noreturn]] # elif ((!defined __cplusplus || defined __clang__) \ - && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \ - || _GL_GNUC_PREREQ (4, 7) \ - || (defined __apple_build_version__ \ - ? 6000000 <= __apple_build_version__ \ - : 3 < __clang_major__ + (5 <= __clang_minor__)))) + && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \ + || (!defined __STRICT_ANSI__ \ + && (_GL_GNUC_PREREQ (4, 7) \ + || (defined __apple_build_version__ \ + ? 6000000 <= __apple_build_version__ \ + : 3 < __clang_major__ + (5 <= __clang_minor__)))))) /* _Noreturn works as-is. */ # elif _GL_GNUC_PREREQ (2, 8) || defined __clang__ || 0x5110 <= __SUNPRO_C # define _Noreturn __attribute__ ((__noreturn__)) @@ -66,7 +67,9 @@ AC_DEFUN([gl_COMMON_BODY], [ #endif]) AH_VERBATIM([attribute], [/* Attributes. */ -#ifdef __has_attribute +#if (defined __has_attribute \ + && (!defined __clang_minor__ \ + || 3 < __clang_major__ + (5 <= __clang_minor__))) # define _GL_HAS_ATTRIBUTE(attr) __has_attribute (__##attr##__) #else # define _GL_HAS_ATTRIBUTE(attr) _GL_ATTR_##attr diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index ad109520dd..cd6f7b4bbd 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -75,6 +75,7 @@ AC_DEFUN([gl_EARLY], # Code from module dtoastr: # Code from module dtotimespec: # Code from module dup2: + # Code from module dynarray: # Code from module eloop-threshold: # Code from module environ: # Code from module errno: @@ -517,6 +518,7 @@ AC_DEFUN([gl_INIT], gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=false gl_gnulib_enabled_cloexec=false gl_gnulib_enabled_dirfd=false + gl_gnulib_enabled_dynarray=false gl_gnulib_enabled_925677f0343de64b89a9f0c790b4104c=false gl_gnulib_enabled_euidaccess=false gl_gnulib_enabled_getdtablesize=false @@ -564,6 +566,12 @@ AC_DEFUN([gl_INIT], gl_gnulib_enabled_dirfd=true fi } + func_gl_gnulib_m4code_dynarray () + { + if ! $gl_gnulib_enabled_dynarray; then + gl_gnulib_enabled_dynarray=true + fi + } func_gl_gnulib_m4code_925677f0343de64b89a9f0c790b4104c () { if ! $gl_gnulib_enabled_925677f0343de64b89a9f0c790b4104c; then @@ -797,6 +805,9 @@ AC_DEFUN([gl_INIT], if test $HAVE_READLINKAT = 0 || test $REPLACE_READLINKAT = 1; then func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7 fi + if test $ac_use_included_regex = yes; then + func_gl_gnulib_m4code_dynarray + fi if { test $HAVE_DECL_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; } && test $ac_cv_type_long_long_int = yes; then func_gl_gnulib_m4code_strtoll fi @@ -819,6 +830,7 @@ AC_DEFUN([gl_INIT], AM_CONDITIONAL([gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b], [$gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b]) AM_CONDITIONAL([gl_GNULIB_ENABLED_cloexec], [$gl_gnulib_enabled_cloexec]) AM_CONDITIONAL([gl_GNULIB_ENABLED_dirfd], [$gl_gnulib_enabled_dirfd]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_dynarray], [$gl_gnulib_enabled_dynarray]) AM_CONDITIONAL([gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c], [$gl_gnulib_enabled_925677f0343de64b89a9f0c790b4104c]) AM_CONDITIONAL([gl_GNULIB_ENABLED_euidaccess], [$gl_gnulib_enabled_euidaccess]) AM_CONDITIONAL([gl_GNULIB_ENABLED_getdtablesize], [$gl_gnulib_enabled_getdtablesize]) @@ -1021,6 +1033,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/dtoastr.c lib/dtotimespec.c lib/dup2.c + lib/dynarray.h lib/eloop-threshold.h lib/errno.in.h lib/euidaccess.c @@ -1076,6 +1089,13 @@ AC_DEFUN([gl_FILE_LIST], [ lib/libc-config.h lib/limits.in.h lib/lstat.c + lib/malloc/dynarray-skeleton.c + lib/malloc/dynarray.h + lib/malloc/dynarray_at_failure.c + lib/malloc/dynarray_emplace_enlarge.c + lib/malloc/dynarray_finalize.c + lib/malloc/dynarray_resize.c + lib/malloc/dynarray_resize_clear.c lib/malloc/scratch_buffer.h lib/malloc/scratch_buffer_dupfree.c lib/malloc/scratch_buffer_grow.c diff --git a/m4/nstrftime.m4 b/m4/nstrftime.m4 index 4674442810..b510554b94 100644 --- a/m4/nstrftime.m4 +++ b/m4/nstrftime.m4 @@ -1,4 +1,4 @@ -# serial 36 +# serial 37 # Copyright (C) 1996-1997, 1999-2007, 2009-2021 Free Software Foundation, Inc. # @@ -12,7 +12,7 @@ AC_DEFUN([gl_FUNC_GNU_STRFTIME], [ AC_REQUIRE([AC_C_RESTRICT]) - # This defines (or not) HAVE_TZNAME and HAVE_TM_ZONE. + # This defines (or not) HAVE_TZNAME and HAVE_STRUCT_TM_TM_ZONE. AC_REQUIRE([AC_STRUCT_TIMEZONE]) AC_REQUIRE([gl_TM_GMTOFF]) diff --git a/m4/stddef_h.m4 b/m4/stddef_h.m4 index 18e872f483..cd666c4a58 100644 --- a/m4/stddef_h.m4 +++ b/m4/stddef_h.m4 @@ -1,14 +1,19 @@ -dnl A placeholder for , for platforms that have issues. -# stddef_h.m4 serial 7 +# stddef_h.m4 serial 9 dnl Copyright (C) 2009-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. +dnl A placeholder for , for platforms that have issues. + AC_DEFUN([gl_STDDEF_H], [ AC_REQUIRE([gl_STDDEF_H_DEFAULTS]) AC_REQUIRE([gt_TYPE_WCHAR_T]) + + dnl Persuade OpenBSD to declare max_align_t. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + STDDEF_H= dnl Test whether the type max_align_t exists and whether its alignment @@ -23,6 +28,13 @@ AC_DEFUN([gl_STDDEF_H], int check1[2 * (__alignof__ (double) <= __alignof__ (max_align_t)) - 1]; int check2[2 * (__alignof__ (long double) <= __alignof__ (max_align_t)) - 1]; #endif + typedef struct { char a; max_align_t b; } max_helper; + typedef struct { char a; long b; } long_helper; + typedef struct { char a; double b; } double_helper; + typedef struct { char a; long double b; } long_double_helper; + int check3[2 * (offsetof (long_helper, b) <= offsetof (max_helper, b)) - 1]; + int check4[2 * (offsetof (double_helper, b) <= offsetof (max_helper, b)) - 1]; + int check5[2 * (offsetof (long_double_helper, b) <= offsetof (max_helper, b)) - 1]; ]])], [gl_cv_type_max_align_t=yes], [gl_cv_type_max_align_t=no]) diff --git a/m4/string_h.m4 b/m4/string_h.m4 index 3e65355735..a4cc5b4378 100644 --- a/m4/string_h.m4 +++ b/m4/string_h.m4 @@ -5,7 +5,7 @@ # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 28 +# serial 29 # Written by Paul Eggert. @@ -113,6 +113,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], HAVE_SIGDESCR_NP=1; AC_SUBST([HAVE_SIGDESCR_NP]) HAVE_DECL_STRSIGNAL=1; AC_SUBST([HAVE_DECL_STRSIGNAL]) HAVE_STRVERSCMP=1; AC_SUBST([HAVE_STRVERSCMP]) + REPLACE_FFSLL=0; AC_SUBST([REPLACE_FFSLL]) REPLACE_MEMCHR=0; AC_SUBST([REPLACE_MEMCHR]) REPLACE_MEMMEM=0; AC_SUBST([REPLACE_MEMMEM]) REPLACE_STPNCPY=0; AC_SUBST([REPLACE_STPNCPY]) diff --git a/m4/sys_stat_h.m4 b/m4/sys_stat_h.m4 index e8eac71b46..23cbdd28eb 100644 --- a/m4/sys_stat_h.m4 +++ b/m4/sys_stat_h.m4 @@ -1,4 +1,4 @@ -# sys_stat_h.m4 serial 36 -*- Autoconf -*- +# sys_stat_h.m4 serial 38 -*- Autoconf -*- dnl Copyright (C) 2006-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -104,7 +104,9 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS], REPLACE_LSTAT=0; AC_SUBST([REPLACE_LSTAT]) REPLACE_MKDIR=0; AC_SUBST([REPLACE_MKDIR]) REPLACE_MKFIFO=0; AC_SUBST([REPLACE_MKFIFO]) + REPLACE_MKFIFOAT=0; AC_SUBST([REPLACE_MKFIFOAT]) REPLACE_MKNOD=0; AC_SUBST([REPLACE_MKNOD]) + REPLACE_MKNODAT=0; AC_SUBST([REPLACE_MKNODAT]) REPLACE_STAT=0; AC_SUBST([REPLACE_STAT]) REPLACE_UTIMENSAT=0; AC_SUBST([REPLACE_UTIMENSAT]) ]) diff --git a/m4/time_h.m4 b/m4/time_h.m4 index 07e6967e45..b6a1aa3bc0 100644 --- a/m4/time_h.m4 +++ b/m4/time_h.m4 @@ -2,7 +2,7 @@ # Copyright (C) 2000-2001, 2003-2007, 2009-2021 Free Software Foundation, Inc. -# serial 13 +# serial 15 # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -25,6 +25,22 @@ AC_DEFUN([gl_HEADER_TIME_H_BODY], AC_REQUIRE([gl_CHECK_TYPE_STRUCT_TIMESPEC]) AC_REQUIRE([AC_C_RESTRICT]) + + AC_CACHE_CHECK([for TIME_UTC in ], + [gl_cv_time_h_has_TIME_UTC], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + ]], + [[static int x = TIME_UTC; x++;]])], + [gl_cv_time_h_has_TIME_UTC=yes], + [gl_cv_time_h_has_TIME_UTC=no])]) + if test $gl_cv_time_h_has_TIME_UTC = yes; then + TIME_H_DEFINES_TIME_UTC=1 + else + TIME_H_DEFINES_TIME_UTC=0 + fi + AC_SUBST([TIME_H_DEFINES_TIME_UTC]) ]) dnl Check whether 'struct timespec' is declared @@ -113,6 +129,7 @@ AC_DEFUN([gl_HEADER_TIME_H_DEFAULTS], GNULIB_STRFTIME=0; AC_SUBST([GNULIB_STRFTIME]) GNULIB_STRPTIME=0; AC_SUBST([GNULIB_STRPTIME]) GNULIB_TIMEGM=0; AC_SUBST([GNULIB_TIMEGM]) + GNULIB_TIMESPEC_GET=0; AC_SUBST([GNULIB_TIMESPEC_GET]) GNULIB_TIME_R=0; AC_SUBST([GNULIB_TIME_R]) GNULIB_TIME_RZ=0; AC_SUBST([GNULIB_TIME_RZ]) GNULIB_TZSET=0; AC_SUBST([GNULIB_TZSET]) @@ -123,6 +140,7 @@ AC_DEFUN([gl_HEADER_TIME_H_DEFAULTS], HAVE_NANOSLEEP=1; AC_SUBST([HAVE_NANOSLEEP]) HAVE_STRPTIME=1; AC_SUBST([HAVE_STRPTIME]) HAVE_TIMEGM=1; AC_SUBST([HAVE_TIMEGM]) + HAVE_TIMESPEC_GET=1; AC_SUBST([HAVE_TIMESPEC_GET]) dnl Even GNU libc does not have timezone_t yet. HAVE_TIMEZONE_T=0; AC_SUBST([HAVE_TIMEZONE_T]) dnl If another module says to replace or to not replace, do that. diff --git a/m4/utimensat.m4 b/m4/utimensat.m4 index bdabe24c56..b5bff1651f 100644 --- a/m4/utimensat.m4 +++ b/m4/utimensat.m4 @@ -1,4 +1,4 @@ -# serial 7 +# serial 9 # See if we need to provide utimensat replacement. dnl Copyright (C) 2009-2021 Free Software Foundation, Inc. @@ -12,6 +12,7 @@ AC_DEFUN([gl_FUNC_UTIMENSAT], [ AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS]) AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles AC_CHECK_FUNCS_ONCE([utimensat]) if test $ac_cv_func_utimensat = no; then HAVE_UTIMENSAT=0 @@ -28,10 +29,19 @@ AC_DEFUN([gl_FUNC_UTIMENSAT], const char *f = "conftest.file"; if (close (creat (f, 0600))) return 1; + /* Test whether a trailing slash is handled correctly. + This fails on AIX 7.2. */ + { + struct timespec ts[2]; + ts[0].tv_sec = 345183300; ts[0].tv_nsec = 0; + ts[1] = ts[0]; + if (utimensat (AT_FDCWD, "conftest.file/", ts, 0) == 0) + result |= 2; + } /* Test whether the AT_SYMLINK_NOFOLLOW flag is supported. */ { if (utimensat (AT_FDCWD, f, NULL, AT_SYMLINK_NOFOLLOW)) - result |= 2; + result |= 4; } /* Test whether UTIME_NOW and UTIME_OMIT work. */ { @@ -41,7 +51,7 @@ AC_DEFUN([gl_FUNC_UTIMENSAT], ts[1].tv_sec = 1; ts[1].tv_nsec = UTIME_NOW; if (utimensat (AT_FDCWD, f, ts, 0)) - result |= 4; + result |= 8; } sleep (1); { @@ -52,19 +62,44 @@ AC_DEFUN([gl_FUNC_UTIMENSAT], ts[1].tv_sec = 1; ts[1].tv_nsec = UTIME_OMIT; if (utimensat (AT_FDCWD, f, ts, 0)) - result |= 8; - if (stat (f, &st)) result |= 16; - else if (st.st_ctime < st.st_atime) + if (stat (f, &st)) result |= 32; + else if (st.st_ctime < st.st_atime) + result |= 64; } return result; ]])], [gl_cv_func_utimensat_works=yes], - [gl_cv_func_utimensat_works=no], - [gl_cv_func_utimensat_works="guessing yes"])]) - if test "$gl_cv_func_utimensat_works" = no; then - REPLACE_UTIMENSAT=1 - fi + [case $? in + 2) gl_cv_func_utimensat_works='nearly' ;; + *) gl_cv_func_utimensat_works=no ;; + esac + ], + [case "$host_os" in + # Guess yes on Linux or glibc systems. + linux-* | linux | *-gnu* | gnu*) + gl_cv_func_utimensat_works="guessing yes" ;; + # Guess 'nearly' on AIX. + aix*) + gl_cv_func_utimensat_works="guessing nearly" ;; + # If we don't know, obey --enable-cross-guesses. + *) + gl_cv_func_utimensat_works="$gl_cross_guess_normal" ;; + esac + ]) + ]) + case "$gl_cv_func_utimensat_works" in + *yes) + ;; + *nearly) + AC_DEFINE([HAVE_NEARLY_WORKING_UTIMENSAT], [1], + [Define to 1 if utimensat works, except for the trailing slash handling.]) + REPLACE_UTIMENSAT=1 + ;; + *) + REPLACE_UTIMENSAT=1 + ;; + esac fi ]) commit 9143eba0c6861f467c18bc52d66e6f5c573be56b Author: Paul Eggert Date: Fri Jan 22 11:44:50 2021 -0800 Prepare for update from Gnulib * configure.ac: Also create lib/malloc and lib/deps/malloc if the dynarray module is in use, as Gnulib regex will start needing it due to recent glibc changes. diff --git a/configure.ac b/configure.ac index bea2833809..08f3c0cd85 100644 --- a/configure.ac +++ b/configure.ac @@ -5898,7 +5898,7 @@ if test $AUTO_DEPEND = yes; then AS_MKDIR_P([$dir/deps]) done fi -if $gl_gnulib_enabled_scratch_buffer; then +if $gl_gnulib_enabled_dynarray || $gl_gnulib_enabled_scratch_buffer; then AS_MKDIR_P([lib/malloc]) if test $AUTO_DEPEND = yes; then AS_MKDIR_P([lib/deps/malloc]) commit b7f318aa9611f132ba93745f663573bd223a2641 Author: Lars Ingebrigtsen Date: Fri Jan 22 19:22:07 2021 +0100 Fix up previous mh-speed.el ignored variable change * lisp/mh-e/mh-speed.el (mh-speed-toggle, mh-speed-view): Mark the ignored parameter with _ instead of using the Common Lispish (declare (ignore args)) (which Emacs Lisp doesn't really support), except by accident. diff --git a/lisp/mh-e/mh-speed.el b/lisp/mh-e/mh-speed.el index 00b9680417..7cbd42c8ea 100644 --- a/lisp/mh-e/mh-speed.el +++ b/lisp/mh-e/mh-speed.el @@ -125,10 +125,9 @@ With non-nil FORCE, the update is always carried out." ;; Otherwise on to your regular programming (t t))) -(defun mh-speed-toggle (&rest ignored) +(defun mh-speed-toggle (&rest _ignored) "Toggle the display of child folders in the speedbar. The optional arguments from speedbar are IGNORED." - (declare (ignore args)) (interactive) (beginning-of-line) (let ((parent (get-text-property (point) 'mh-folder)) @@ -164,10 +163,9 @@ The optional arguments from speedbar are IGNORED." (mh-line-beginning-position) (1+ (line-beginning-position)) '(mh-expanded t))))))) -(defun mh-speed-view (&rest ignored) +(defun mh-speed-view (&rest _ignored) "Visits the selected folder just as if you had used \\\\[mh-visit-folder]. The optional arguments from speedbar are IGNORED." - (declare (ignore args)) (interactive) (let* ((folder (get-text-property (mh-line-beginning-position) 'mh-folder)) (range (and (stringp folder) commit 2be55ad66910730d81f727d3bc4a25d196422d04 Author: Keith David Bershatsky Date: Fri Jan 22 19:18:41 2021 +0100 Add more isearch-related bindings to ns-win.el * lisp/term/ns-win.el (minibuffer-local-isearch-map): Add more bindings to mirror bindings in isearch.el (bug#15667). diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el index 5f4dd9ef58..94e9d5c582 100644 --- a/lisp/term/ns-win.el +++ b/lisp/term/ns-win.el @@ -120,6 +120,15 @@ The properties returned may include `top', `left', `height', and `width'." (define-key global-map [?\s-d] 'isearch-repeat-backward) (define-key global-map [?\s-e] 'isearch-yank-kill) (define-key global-map [?\s-f] 'isearch-forward) +(define-key esc-map [?\s-f] 'isearch-forward-regexp) +(define-key minibuffer-local-isearch-map [?\s-f] + 'isearch-forward-exit-minibuffer) +(define-key isearch-mode-map [?\s-f] 'isearch-repeat-forward) +(define-key global-map [?\s-F] 'isearch-backward) +(define-key esc-map [?\s-F] 'isearch-backward-regexp) +(define-key minibuffer-local-isearch-map [?\s-F] + 'isearch-reverse-exit-minibuffer) +(define-key isearch-mode-map [?\s-F] 'isearch-repeat-backward) (define-key global-map [?\s-g] 'isearch-repeat-forward) (define-key global-map [?\s-h] 'ns-do-hide-emacs) (define-key global-map [?\s-H] 'ns-do-hide-others) commit ef14acfb68bb5b0ce42221e9681b93562f8085eb Author: Lars Ingebrigtsen Date: Fri Jan 22 19:07:52 2021 +0100 Make nnml handle invalid non-ASCII headers more consistently * lisp/gnus/nnml.el (nnml--encode-headers): New function to RFC2047-encode invalid Subject/From headers (bug#45925). This will make them be displayed more consistently in the Summary buffer (but still "wrong" sometimes, since there's not that much we can guess at at this stage, charset wise). (nnml-parse-head): Use it. diff --git a/lisp/gnus/nnml.el b/lisp/gnus/nnml.el index ebececa3ce..3cdfc74970 100644 --- a/lisp/gnus/nnml.el +++ b/lisp/gnus/nnml.el @@ -769,8 +769,24 @@ article number. This function is called narrowed to an article." (let ((headers (nnheader-parse-head t))) (setf (mail-header-chars headers) chars) (setf (mail-header-number headers) number) + ;; If there's non-ASCII raw characters in the data, + ;; RFC2047-encode them to avoid having arbitrary data in the + ;; .overview file. + (nnml--encode-headers headers) headers)))) +(defun nnml--encode-headers (headers) + (let ((subject (mail-header-subject headers)) + (rfc2047-encoding-type 'mime)) + (unless (string-match "\\`[[:ascii:]]*\\'" subject) + (setf (mail-header-subject headers) + (mail-encode-encoded-word-string subject t)))) + (let ((from (mail-header-from headers)) + (rfc2047-encoding-type 'address-mime)) + (unless (string-match "\\`[[:ascii:]]*\\'" from) + (setf (mail-header-from headers) + (rfc2047-encode-string from t))))) + (defun nnml-get-nov-buffer (group &optional incrementalp) (let ((buffer (gnus-get-buffer-create (format " *nnml %soverview %s*" commit b2b26bd4d66d25f2456baa4e9eb9516c122a30e0 Author: Michael Albinus Date: Fri Jan 22 17:39:52 2021 +0100 Use RemoteCommand option for Tramp's sshx and scpx methods * doc/misc/tramp.texi (Inline methods) : (External methods) : Adapt call sequence. (Remote shell setup): Mention, that sshx and scpx overwrite RemoteCommand. (Remote processes): Restriction: direct asynchronous processes cannot be used when RemoteCommand is in use. `tramp-remote-process-environment' is not ignored any longer. * lisp/net/tramp-sh.el (tramp-methods) : Handle login shell via RemoteCommand. Remove `tramp-direct-async' parameter. (tramp-maybe-open-connection): Add "-i" to login. * lisp/net/tramp-smb.el (tramp-smb-errors): Add "NT_STATUS_NOT_SUPPORTED". (tramp-smb-handle-insert-directory): Fix point moving error. * test/lisp/net/tramp-tests.el (tramp-test34-explicit-shell-file-name): Use `get-buffer-process' where appropriate. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index e9ffd6a8c4..5d89b06588 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -810,9 +810,10 @@ behavior. @cindex @option{sshx} method Works like @option{ssh} but without the extra authentication prompts. -@option{sshx} uses @samp{ssh -t -t @var{host} -l @var{user} /bin/sh} -to open a connection with a ``standard'' login shell. It supports -changing the remote login shell @command{/bin/sh}. +@option{sshx} uses @samp{ssh -t -t -l @var{user} -o +RemoteCommand='/bin/sh -i' @var{host}} to open a connection with a +``standard'' login shell. It supports changing the remote login shell +@command{/bin/sh}. @strong{Note} that @option{sshx} does not bypass authentication questions. For example, if the host key of the remote host is not @@ -935,9 +936,10 @@ This method supports the @samp{-p} argument. @cindex @command{ssh} (with @option{scpx} method) @option{scpx} is useful to avoid login shell questions. It is similar -in performance to @option{scp}. @option{scpx} uses @samp{ssh -t -t -@var{host} -l @var{user} /bin/sh} to open a connection. It supports -changing the remote login shell @command{/bin/sh}. +in performance to @option{scp}. @option{scpx} uses @samp{ssh -t -t -l +@var{user} -o RemoteCommand='/bin/sh -i' @var{host}} to open a +connection. It supports changing the remote login shell +@command{/bin/sh}. @option{scpx} is useful for MS Windows users when @command{ssh} triggers an error about allocating a pseudo tty. This happens due to @@ -2220,7 +2222,10 @@ This uses also the settings in @code{tramp-sh-extra-args}. @vindex RemoteCommand@r{, ssh option} @strong{Note}: If you use an @option{ssh}-based method for connection, do @emph{not} set the @option{RemoteCommand} option in your -@command{ssh} configuration, for example to @command{screen}. +@command{ssh} configuration, for example to @command{screen}. On the +other hand, some @option{ssh}-based methods, like @option{sshx} or +@option{scpx}, silently overwrite a @option{RemoteCommand} option of +the configuration file. @subsection Other remote shell setup hints @@ -3580,13 +3585,16 @@ Furthermore, this approach has the following limitations: It works only for connection methods defined in @file{tramp-sh.el} and @file{tramp-adb.el}. -@vindex ControlMaster@r{, ssh option} @item It does not support interactive user authentication. With @option{ssh}-based methods, this can be avoided by using a password agent like @command{ssh-agent}, using public key authentication, or using @option{ControlMaster} options. +@item +It cannot be applied for @option{ssh}-based methods, which use the +@option{RemoteCommand} option. + @item It cannot be killed via @code{interrupt-process}. @@ -3597,8 +3605,7 @@ It does not report the remote terminal name via @code{process-tty-name}. It does not set process property @code{remote-pid}. @item -It does not use @code{tramp-remote-path} and -@code{tramp-remote-process-environment}. +It does not use @code{tramp-remote-path}. @end itemize In order to gain even more performance, it is recommended to bind diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 618a9fb9d0..d7ca7c9780 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -181,10 +181,9 @@ The string is used in `tramp-methods'.") `("scpx" (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") - ("-e" "none") ("-t" "-t") ("%h") - ("%l"))) + ("-e" "none") ("-t" "-t") + ("-o" "RemoteCommand='%l'") ("%h"))) (tramp-async-args (("-q"))) - (tramp-direct-async t) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) @@ -238,10 +237,9 @@ The string is used in `tramp-methods'.") `("sshx" (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") - ("-e" "none") ("-t" "-t") ("%h") - ("%l"))) + ("-e" "none") ("-t" "-t") + ("-o" "RemoteCommand='%l'") ("%h"))) (tramp-async-args (("-q"))) - (tramp-direct-async t) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")))) @@ -5124,7 +5122,7 @@ connection if a previous connection has died for some reason." options (format-spec options spec) spec (format-spec-make ?h l-host ?u l-user ?p l-port ?c options - ?l (concat remote-shell " " extra-args)) + ?l (concat remote-shell " " extra-args " -i")) command (concat ;; We do not want to see the trailing local diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 1604e8962c..c5a74a5c65 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -156,6 +156,7 @@ this variable (\"client min protocol=NT1\") ." "NT_STATUS_NO_SUCH_FILE" "NT_STATUS_NO_SUCH_USER" "NT_STATUS_NOT_A_DIRECTORY" + "NT_STATUS_NOT_SUPPORTED" "NT_STATUS_OBJECT_NAME_COLLISION" "NT_STATUS_OBJECT_NAME_INVALID" "NT_STATUS_OBJECT_NAME_NOT_FOUND" @@ -371,17 +372,17 @@ pass to the OPERATION." (tramp-error v2 'file-error "add-name-to-file: %s must not be a directory" filename)) - ;; Do the 'confirm if exists' thing. - (when (file-exists-p newname) - ;; What to do? - (if (or (null ok-if-already-exists) ; not allowed to exist - (and (numberp ok-if-already-exists) - (not (yes-or-no-p - (format - "File %s already exists; make it a link anyway? " - v2-localname))))) - (tramp-error v2 'file-already-exists newname) - (delete-file newname))) + ;; Do the 'confirm if exists' thing. + (when (file-exists-p newname) + ;; What to do? + (if (or (null ok-if-already-exists) ; not allowed to exist + (and (numberp ok-if-already-exists) + (not (yes-or-no-p + (format + "File %s already exists; make it a link anyway? " + v2-localname))))) + (tramp-error v2 'file-already-exists newname) + (delete-file newname))) ;; We must also flush the cache of the directory, because ;; `file-attributes' reads the values from there. (tramp-flush-file-properties v2 v2-localname) @@ -1166,7 +1167,6 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (insert " -> " (tramp-compat-file-attribute-type attr)))) (insert "\n") - (forward-line) (beginning-of-line))) entries)))))) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 5deee65829..4c84507807 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -5247,7 +5247,7 @@ Use direct async.") ;; order to avoid a question. `explicit-sh-args' echoes the ;; test data. (with-current-buffer (get-buffer-create "*shell*") - (ignore-errors (kill-process (current-buffer))) + (ignore-errors (kill-process (get-buffer-process (current-buffer)))) (should-not explicit-shell-file-name) (call-interactively #'shell) (with-timeout (10) commit 4c0dce4b66c41a12a4cf7439b036962e9525eeaa Author: Mattias Engdegård Date: Fri Jan 22 15:47:48 2021 +0100 Calc: use big brackets around function arguments * lisp/calc/calccomp.el (math-compose-expr): Use big brackets around arguments in Big mode, so that expressions like sin(a/b) look a bit better. diff --git a/lisp/calc/calccomp.el b/lisp/calc/calccomp.el index 5f38ee71c7..bd81d7fe40 100644 --- a/lisp/calc/calccomp.el +++ b/lisp/calc/calccomp.el @@ -822,9 +822,16 @@ (if (setq spfn (get calc-language 'math-func-formatter)) (funcall spfn func a) - (list 'horiz func calc-function-open - (math-compose-vector (cdr a) ", " 0) - calc-function-close)))))))))) + (let ((args (math-compose-vector (cdr a) ", " 0))) + (if (and (member calc-function-open '("(" "[" "{")) + (member calc-function-close '(")" "]" "}"))) + (list 'horiz func + (math--comp-bracket + (string-to-char calc-function-open) + (string-to-char calc-function-close) + args)) + (list 'horiz func calc-function-open + args calc-function-close)))))))))))) (defun math-prod-first-term (x) commit 3f610177adb844248fe37f52eb713d462e833a62 Author: Eli Zaretskii Date: Fri Jan 22 14:30:22 2021 +0200 Avoid sending systemd shutdown notifications if non-daemon * src/emacs.c (Fkill_emacs): Send the shutdown notification only in daemon mode. (Bug#46022) diff --git a/src/emacs.c b/src/emacs.c index f2e858f13b..67220ebb76 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -187,7 +187,8 @@ bool build_details; /* Name for the server started by the daemon.*/ static char *daemon_name; -/* 0 not a daemon, 1 new-style (foreground), 2 old-style (background). */ +/* 0 not a daemon, 1 new-style (foreground), 2 old-style (background). + A negative value means the daemon initialization was already done. */ int daemon_type; #ifndef WINDOWSNT @@ -2371,7 +2372,10 @@ all of which are called before Emacs is actually killed. */ int exit_code; #ifdef HAVE_LIBSYSTEMD - sd_notify(0, "STOPPING=1"); + /* Notify systemd we are shutting down, but only if we have notified + it about startup. */ + if (daemon_type == -1) + sd_notify(0, "STOPPING=1"); #endif /* HAVE_LIBSYSTEMD */ /* Fsignal calls emacs_abort () if it sees that waiting_for_input is @@ -2876,7 +2880,7 @@ from the parent process and its tty file descriptors. */) } /* Set it to an invalid value so we know we've already run this function. */ - daemon_type = -1; + daemon_type = -daemon_type; #else /* WINDOWSNT */ /* Signal the waiting emacsclient process. */ commit 561197e519c5adc33622c2e5519693d270f6262b Author: Eli Zaretskii Date: Fri Jan 22 14:16:51 2021 +0200 Fix last change for DOS_NT systems * src/term.c (tty_draw_row_with_mouse_face) (tty_write_glyphs_with_face): Don't define on MSDOS and WINDOWSNT, as those have their own implementations of that. diff --git a/src/term.c b/src/term.c index 37c06a560d..1059b0669a 100644 --- a/src/term.c +++ b/src/term.c @@ -790,6 +790,8 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len) cmcheckmagic (tty); } +#ifndef DOS_NT + static void tty_write_glyphs_with_face (register struct frame *f, register struct glyph *string, register int len, register int face_id) @@ -846,6 +848,8 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str cmcheckmagic (tty); } +#endif + /* An implementation of insert_glyphs for termcap frames. */ static void @@ -2377,7 +2381,9 @@ frame's terminal). */) Mouse ***********************************************************************/ -/* Implementation of draw_row_with_mouse_face for TTY/GPM. */ +#ifndef DOS_NT + +/* Implementation of draw_row_with_mouse_face for TTY/GPM and macOS. */ void tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row, int start_hpos, int end_hpos, @@ -2409,6 +2415,8 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row, cursor_to (f, save_y, save_x); } +#endif + #ifdef HAVE_GPM void commit 463300d431a56c58ca7f1db9615046143f354a81 Author: João Távora Date: Sat Jan 16 14:17:58 2021 -0800 Enable TTY mouse-face support when built without GPM support * src/term.c (tty_write_glyphs_with_face): Move definition out of ifdef block. * src/xdisp.c (draw_row_with_mouse_face): Now called unconditionally on all platforms. diff --git a/src/term.c b/src/term.c index 2e2ab2bf43..37c06a560d 100644 --- a/src/term.c +++ b/src/term.c @@ -790,8 +790,6 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len) cmcheckmagic (tty); } -#ifdef HAVE_GPM /* Only used by GPM code. */ - static void tty_write_glyphs_with_face (register struct frame *f, register struct glyph *string, register int len, register int face_id) @@ -847,7 +845,6 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str cmcheckmagic (tty); } -#endif /* An implementation of insert_glyphs for termcap frames. */ @@ -2380,22 +2377,6 @@ frame's terminal). */) Mouse ***********************************************************************/ -#ifdef HAVE_GPM - -void -term_mouse_moveto (int x, int y) -{ - /* TODO: how to set mouse position? - const char *name; - int fd; - name = (const char *) ttyname (0); - fd = emacs_open (name, O_WRONLY, 0); - SOME_FUNCTION (x, y, fd); - emacs_close (fd); - last_mouse_x = x; - last_mouse_y = y; */ -} - /* Implementation of draw_row_with_mouse_face for TTY/GPM. */ void tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row, @@ -2428,6 +2409,22 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row, cursor_to (f, save_y, save_x); } +#ifdef HAVE_GPM + +void +term_mouse_moveto (int x, int y) +{ + /* TODO: how to set mouse position? + const char *name; + int fd; + name = (const char *) ttyname (0); + fd = emacs_open (name, O_WRONLY, 0); + SOME_FUNCTION (x, y, fd); + emacs_close (fd); + last_mouse_x = x; + last_mouse_y = y; */ +} + /* Return the current time, as a Time value. Wrap around on overflow. */ static Time current_Time (void) diff --git a/src/xdisp.c b/src/xdisp.c index 32e9773b54..e1e4ff4136 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -31927,9 +31927,8 @@ draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row, return; } #endif -#if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT) + tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw); -#endif } /* Display the active region described by mouse_face_* according to DRAW. */ commit 6bfc672bc7f467edf39cfba262c5c4f11897d4e0 Author: Glenn Morris Date: Fri Jan 22 08:52:12 2021 +0000 * lisp/textmodes/remember.el (remember-text-format-function): Fix type. diff --git a/lisp/textmodes/remember.el b/lisp/textmodes/remember.el index 811a265118..820ee38d10 100644 --- a/lisp/textmodes/remember.el +++ b/lisp/textmodes/remember.el @@ -415,7 +415,7 @@ The default emulates `current-time-string' for backward compatibility." "The function to format the remembered text. The function receives the remembered text as argument and should return the text to be remembered." - :type 'function + :type '(choice (const nil) function) :group 'remember :version "28.1") commit 009df5cb3cec5108a66538503bd63a8bd6f8addf Author: Eli Zaretskii Date: Fri Jan 22 10:10:21 2021 +0200 * src/cmds.c (Fforward_line): Doc fix. (Bug#46027) diff --git a/src/cmds.c b/src/cmds.c index 102135359f..c771eeb968 100644 --- a/src/cmds.c +++ b/src/cmds.c @@ -108,6 +108,7 @@ DEFUN ("forward-line", Fforward_line, Sforward_line, 0, 1, "^p", Precisely, if point is on line I, move to the start of line I + N \("start of line" in the logical order). If there isn't room, go as far as possible (no error). +Interactively, N is the numeric prefix argument and defaults to 1. Returns the count of lines left to move. If moving forward, that is N minus number of lines moved; if backward, N plus number commit ee1c54ebc01bc377dce99af891730c1a53cc3f86 Author: Eli Zaretskii Date: Fri Jan 22 09:57:19 2021 +0200 Improve documentation of sendmail.el defcustom's * lisp/mail/sendmail.el (mail-archive-file-name) (mail-default-reply-to, mail-self-blind, mail-default-headers): Say in the doc string that 'message-default-mail-headers' shall be customized when using 'message-mode' for email composition. (Bug#46029) diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el index ad1a02734c..15f7f22402 100644 --- a/lisp/mail/sendmail.el +++ b/lisp/mail/sendmail.el @@ -104,7 +104,9 @@ being sent is used), or nil (in which case the value of (defcustom mail-self-blind nil "Non-nil means insert Bcc to self in messages to be sent. This is done when the message is initialized, -so you can remove or alter the Bcc field to override the default." +so you can remove or alter the Bcc field to override the default. +If you are using `message-mode' to compose messages, customize the +variable `message-default-mail-headers' instead." :type 'boolean) ;;;###autoload @@ -172,14 +174,18 @@ This is used by the default mail-sending commands. See also (defcustom mail-archive-file-name nil "Name of file to write all outgoing messages in, or nil for none. This is normally an mbox file, but for backwards compatibility may also -be a Babyl file." +be a Babyl file. +If you are using `message-mode' to compose messages, customize the +variable `message-default-mail-headers' instead." :type '(choice file (const nil))) ;;;###autoload (defcustom mail-default-reply-to nil "Address to insert as default Reply-To field of outgoing messages. If nil, it will be initialized from the REPLYTO environment variable -when you first send mail." +when you first send mail. +If you are using `message-mode' to compose messages, customize the +variable `message-default-mail-headers' instead." :type '(choice (const nil) string)) (defcustom mail-alias-file nil @@ -388,7 +394,9 @@ in `message-auto-save-directory'." (defcustom mail-default-headers nil "A string containing header lines, to be inserted in outgoing messages. It can contain newlines, and should end in one. It is inserted -before you edit the message, so you can edit or delete the lines." +before you edit the message, so you can edit or delete the lines. +If you are using `message-mode' to compose messages, customize the +variable `message-default-mail-headers' instead." :type '(choice (const nil) string)) (defcustom mail-bury-selects-summary t commit 90bd6d8ba66bde8d9626f3dd05d14372734e6ce5 Author: Ted Zlatanov Date: Thu Jan 21 19:34:03 2021 +0000 * test/infra/gitlab-ci.yml: Copy newer files to image to build less often. diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml index e5413ad938..2f71d12bdb 100644 --- a/test/infra/gitlab-ci.yml +++ b/test/infra/gitlab-ci.yml @@ -100,10 +100,13 @@ default: script: - docker pull ${CI_REGISTRY_IMAGE}:${target}-${BUILD_TAG} # TODO: with make -j4 several of the tests were failing, for example shadowfile-tests, but passed without it - - docker run -i --rm -e EMACS_EMBA_CI=${EMACS_EMBA_CI} ${CI_REGISTRY_IMAGE}:${target}-${BUILD_TAG} make ${make_params} + - 'export PWD=$(pwd)' + - 'docker run -i --rm -e EMACS_EMBA_CI=${EMACS_EMBA_CI} --volumes-from $(docker ps -q -f "label=com.gitlab.gitlab-runner.job.id=${CI_JOB_ID}"):ro ${CI_REGISTRY_IMAGE}:${target}-${BUILD_TAG} /bin/bash -c "git fetch ${PWD} HEAD && echo checking out these updated files && git diff --name-only FETCH_HEAD && ( git diff --name-only FETCH_HEAD | xargs git checkout -f FETCH_HEAD ) && make -j4 && make ${make_params}"' .build-template: rules: + - if: '$CI_PIPELINE_SOURCE == "web"' + when: always - changes: - "**/Makefile.in" - .gitlab-ci.yml @@ -111,11 +114,9 @@ default: - autogen.sh - configure.ac - lib/*.{h,c} - - lisp/**/*.el + - lisp/emacs-lisp/*.el - src/*.{h,c} - test/infra/* - - test/lisp/**/*.el - - test/src/*.el - changes: # gfilemonitor, kqueue - src/gfilenotify.c commit b41b4add7bc2485fadc6ff3a890efbd1307b2351 Author: Stefan Monnier Date: Thu Jan 21 13:15:05 2021 -0500 Fix spurious "Lexical argument shadows the dynamic variable" due to inlining Before this patch doing: rm lisp/calendar/calendar.elc make lisp/calendar/cal-hebrew.elc would spew out lots of spurious such warnings about a `date` argument, pointing to code which has no `date` argument in sight. This was because that code had calls to inlinable functions (taking a `date` argument) defined in `calendar.el`, and while `date` is a normal lexical var at the site of those functions' definitions, it was declared as dynbound at the call site. * lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand): Don't impose our local context onto the inlined function. * test/lisp/emacs-lisp/bytecomp-tests.el: Add matching test. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index cfa407019a..66a117fccc 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -284,8 +284,10 @@ ;; If `fn' is from the same file, it has already ;; been preprocessed! `(function ,fn) - (byte-compile-preprocess - (byte-compile--reify-function fn))))) + ;; Try and process it "in its original environment". + (let ((byte-compile-bound-variables nil)) + (byte-compile-preprocess + (byte-compile--reify-function fn)))))) (if (eq (car-safe newfn) 'function) (byte-compile-unfold-lambda `(,(cadr newfn) ,@(cdr form))) ;; This can happen because of macroexp-warn-and-return &co. diff --git a/test/lisp/emacs-lisp/bytecomp-resources/foo-inlinable.el b/test/lisp/emacs-lisp/bytecomp-resources/foo-inlinable.el new file mode 100644 index 0000000000..47481574ea --- /dev/null +++ b/test/lisp/emacs-lisp/bytecomp-resources/foo-inlinable.el @@ -0,0 +1,6 @@ +;; -*- lexical-binding: t; -*- + +(defsubst foo-inlineable (foo-var) + (+ foo-var 2)) + +(provide 'foo-inlinable) diff --git a/test/lisp/emacs-lisp/bytecomp-resources/nowarn-inline-after-defvar.el b/test/lisp/emacs-lisp/bytecomp-resources/nowarn-inline-after-defvar.el new file mode 100644 index 0000000000..5582b2ab0e --- /dev/null +++ b/test/lisp/emacs-lisp/bytecomp-resources/nowarn-inline-after-defvar.el @@ -0,0 +1,17 @@ +;; -*- lexical-binding: t; -*- + +;; In this test, we try and make sure that inlined functions's code isn't +;; mistakenly re-interpreted in the caller's context: we import an +;; inlinable function from another file where `foo-var' is a normal +;; lexical variable, and then call(inline) it in a function where +;; `foo-var' is a dynamically-scoped variable. + +(require 'foo-inlinable + (expand-file-name "foo-inlinable.el" + (file-name-directory + (or byte-compile-current-file load-file-name)))) + +(defvar foo-var) + +(defun foo-fun () + (+ (foo-inlineable 5) 1)) diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el index 263736af4e..980b402ca2 100644 --- a/test/lisp/emacs-lisp/bytecomp-tests.el +++ b/test/lisp/emacs-lisp/bytecomp-tests.el @@ -713,6 +713,10 @@ Subtests signal errors if something goes wrong." "warn-wide-docstring-multiline.el" "defvar.*foo.*wider than.*characters") +(bytecomp--define-warning-file-test + "nowarn-inline-after-defvar.el" + "Lexical argument shadows" 'reverse) + ;;;; Macro expansion. commit 931be5ee7d618904361ab2d434d3901cbd9abc9a Author: Stefan Kangas Date: Thu Jan 21 18:52:48 2021 +0100 * lisp/net/webjump.el: Add Maintainer: emacs-devel. Ref: https://lists.gnu.org/r/emacs-devel/2021-01/msg01019.html diff --git a/lisp/net/webjump.el b/lisp/net/webjump.el index 9bcf1d3734..e5941ae652 100644 --- a/lisp/net/webjump.el +++ b/lisp/net/webjump.el @@ -2,9 +2,10 @@ ;; Copyright (C) 1996-1997, 2001-2021 Free Software Foundation, Inc. -;; Author: Neil W. Van Dyke -;; Created: 09-Aug-1996 -;; Keywords: comm www +;; Author: Neil W. Van Dyke +;; Maintainer: emacs-devel@gnu.org +;; Created: 09-Aug-1996 +;; Keywords: comm www ;; This file is part of GNU Emacs. commit 2cf347a0a87bf490391a26fc26b29ca40a0fda93 Author: Lars Ingebrigtsen Date: Thu Jan 21 18:10:16 2021 +0100 Don't have type-break-mode signal errors on corrupted files * lisp/type-break.el (type-break-get-previous-time): (type-break-get-previous-count): Signal a warning instead of an error (bug#38246). type-break will still continue to work even if the database can't be loaded after a restart, but this allows Emacs to be started. diff --git a/lisp/type-break.el b/lisp/type-break.el index 84c240c9f8..a6d5cd0170 100644 --- a/lisp/type-break.el +++ b/lisp/type-break.el @@ -487,7 +487,7 @@ Return nil if the file is missing or if the time is not a Lisp time value." (goto-char (point-min)) (read (current-buffer))) (end-of-file - (error "End of file in `%s'" file)))))))) + (warn "End of file in `%s'" file)))))))) (defun type-break-get-previous-count () "Get previous keystroke count from `type-break-file-name'. @@ -505,7 +505,7 @@ integer." (forward-line 1) (read (current-buffer))) (end-of-file - (error "End of file in `%s'" file))))))) + (warn "End of file in `%s'" file))))))) file 0))) commit a6f030fc7bb3eae2a93dc4d944b6d7d313bd0bce Author: Lars Ingebrigtsen Date: Thu Jan 21 17:10:02 2021 +0100 Fix message.el build warning from previous change * lisp/gnus/message.el (subr-x): Fix build warning from previous commit. diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 7d1eb970c6..1409a4384a 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -47,7 +47,7 @@ (require 'rfc2047) (require 'puny) (require 'rmc) ; read-multiple-choice -(eval-when-compile (require 'subr-x)) +(require 'subr-x) (autoload 'mailclient-send-it "mailclient") commit 5d2ebcd8962b79898d5cdb80cffb6235a033d3d2 Author: Ted Zlatanov Date: Thu Jan 21 16:02:28 2021 +0000 * test/infra/gitlab-ci.yml: Revert to always building. diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml index ddabacfe01..e5413ad938 100644 --- a/test/infra/gitlab-ci.yml +++ b/test/infra/gitlab-ci.yml @@ -104,8 +104,6 @@ default: .build-template: rules: - - if: '$CI_PIPELINE_SOURCE == "web"' - when: always - changes: - "**/Makefile.in" - .gitlab-ci.yml @@ -113,9 +111,11 @@ default: - autogen.sh - configure.ac - lib/*.{h,c} - - lisp/emacs-lisp/*.el + - lisp/**/*.el - src/*.{h,c} - test/infra/* + - test/lisp/**/*.el + - test/src/*.el - changes: # gfilemonitor, kqueue - src/gfilenotify.c commit de761b58f091b11221469b796394e23b34685991 Author: Lars Ingebrigtsen Date: Thu Jan 21 17:08:28 2021 +0100 Add dired support for compressing .pax files * lisp/dired-aux.el (dired-compress-files-alist): Add support for compressing .pax files (bug#40135). diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 5a96742fda..f860743a06 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -1168,7 +1168,8 @@ ARGS are command switches passed to PROGRAM.") ("\\.tar\\.bz2\\'" . "tar -cf - %i | bzip2 -c9 > %o") ("\\.tar\\.xz\\'" . "tar -cf - %i | xz -c9 > %o") ("\\.tar\\.zst\\'" . "tar -cf - %i | zstd -19 -o %o") - ("\\.zip\\'" . "zip %o -r --filesync %i")) + ("\\.zip\\'" . "zip %o -r --filesync %i") + ("\\.pax\\'" . "pax -wf %o %i")) "Control the compression shell command for `dired-do-compress-to'. Each element is (REGEXP . CMD), where REGEXP is the name of the commit 7d122cf9a3c5e02d1fab625a1c81791806f80c40 Author: Lars Ingebrigtsen Date: Thu Jan 21 16:48:01 2021 +0100 Tweak previous message-forward-included-mime-headers change * lisp/gnus/message.el (message-forward-included-mime-headers): Should probably not include Content-Transfer-Encoding, because we will reencode anyway. diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 2bcd367638..7d1eb970c6 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -655,7 +655,7 @@ When forwarding messages as MIME, but when regexp)) (defcustom message-forward-included-mime-headers - '("^Content-Type:" "^MIME-Version:" "^Content-Transfer-Encoding:") + '("^Content-Type:" "^MIME-Version:") "When forwarding as MIME, but not using MML, don't delete these headers. Also see `message-forward-ignored-headers' and `message-forward-ignored-headers'. commit a7fb4ab826669443e204458ecbe5e4074ca1329a Author: Lars Ingebrigtsen Date: Thu Jan 21 16:44:53 2021 +0100 Make Message respect header removal instructions more * doc/misc/message.texi (Forwarding): Document it. * lisp/gnus/message.el (message-forward-ignored-headers): Improve documentation. (message-forward-included-headers): Ditto. (message-forward-included-mime-headers): New user option. (message-remove-ignored-headers): Use it to preserve the necessary MIME headers. (message-forward-make-body): Remove headers when forwarding as MIME, too. diff --git a/doc/misc/message.texi b/doc/misc/message.texi index f2680b4a79..be6c9a419b 100644 --- a/doc/misc/message.texi +++ b/doc/misc/message.texi @@ -317,6 +317,12 @@ when forwarding a message. In non-@code{nil}, only headers that match this regexp will be kept when forwarding a message. This can also be a list of regexps. +@item message-forward-included-mime-headers +@vindex message-forward-included-mime-headers +In non-@code{nil}, headers that match this regexp will be kept when +forwarding a message as @acronym{MIME}, but @acronym{MML} isn't used. +This can also be a list of regexps. + @item message-make-forward-subject-function @vindex message-make-forward-subject-function A list of functions that are called to generate a subject header for diff --git a/etc/NEWS b/etc/NEWS index 59b13998cf..357c75b7e9 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -721,9 +721,11 @@ not. --- *** Respect 'message-forward-ignored-headers' more. Previously, this variable would not be consulted if -'message-forward-show-mml' was nil. It's now always used, except if -'message-forward-show-mml' is 'best', and we're forwarding an -encrypted/signed message. +'message-forward-show-mml' was nil and forwarding as MIME. + ++++ +*** New user option 'message-forward-included-mime-headers'. +This is used when forwarding messages as MIME, but not using MML. +++ *** Message now supports the OpenPGP header. diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index b22b4543e7..2bcd367638 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -620,8 +620,8 @@ Done before generating the new subject of a forward." (defcustom message-forward-ignored-headers "^Content-Transfer-Encoding:\\|^X-Gnus" "All headers that match this regexp will be deleted when forwarding a message. -This variable is not consulted when forwarding encrypted messages -and `message-forward-show-mml' is `best'. +Also see `message-forward-included-headers' -- both variables are applied. +In addition, see `message-forward-included-mime-headers'. This may also be a list of regexps." :version "21.1" @@ -637,7 +637,14 @@ This may also be a list of regexps." '("^From:" "^Subject:" "^Date:" "^To:" "^Cc:") "If non-nil, delete non-matching headers when forwarding a message. Only headers that match this regexp will be included. This -variable should be a regexp or a list of regexps." +variable should be a regexp or a list of regexps. + +Also see `message-forward-ignored-headers' -- both variables are applied. +In addition, see `message-forward-included-mime-headers'. + +When forwarding messages as MIME, but when +`message-forward-show-mml' results in MML not being used, +`message-forward-included-mime-headers' take precedence." :version "27.1" :group 'message-forwarding :type '(repeat :value-to-internal (lambda (widget value) @@ -647,6 +654,24 @@ variable should be a regexp or a list of regexps." (widget-editable-list-match widget value))) regexp)) +(defcustom message-forward-included-mime-headers + '("^Content-Type:" "^MIME-Version:" "^Content-Transfer-Encoding:") + "When forwarding as MIME, but not using MML, don't delete these headers. +Also see `message-forward-ignored-headers' and +`message-forward-ignored-headers'. + +When forwarding messages as MIME, but when +`message-forward-show-mml' results in MML not being used, +`message-forward-included-mime-headers' take precedence." + :version "28.1" + :group 'message-forwarding + :type '(repeat :value-to-internal (lambda (widget value) + (custom-split-regexp-maybe value)) + :match (lambda (widget value) + (or (stringp value) + (widget-editable-list-match widget value))) + regexp)) + (defcustom message-ignored-cited-headers "." "Delete these headers from the messages you yank." :group 'message-insertion @@ -7617,14 +7642,28 @@ Optional DIGEST will use digest to forward." "-------------------- End of forwarded message --------------------\n") (message-remove-ignored-headers b e))) -(defun message-remove-ignored-headers (b e) +(defun message-remove-ignored-headers (b e &optional preserve-mime) (when (or message-forward-ignored-headers message-forward-included-headers) + (let ((saved-headers nil)) (save-restriction (narrow-to-region b e) (goto-char b) (narrow-to-region (point) (or (search-forward "\n\n" nil t) (point))) + ;; When forwarding as MIME, preserve some MIME headers. + (when preserve-mime + (let ((headers (buffer-string))) + (with-temp-buffer + (insert headers) + (message-remove-header + (if (listp message-forward-included-mime-headers) + (mapconcat + #'identity (cons "^$" message-forward-included-mime-headers) + "\\|") + message-forward-included-mime-headers) + t nil t) + (setq saved-headers (string-lines (buffer-string) t))))) (when message-forward-ignored-headers (let ((ignored (if (stringp message-forward-ignored-headers) (list message-forward-ignored-headers) @@ -7637,10 +7676,14 @@ Optional DIGEST will use digest to forward." (mapconcat #'identity (cons "^$" message-forward-included-headers) "\\|") message-forward-included-headers) - t nil t))))) + t nil t)) + ;; Insert the MIME headers, if any. + (goto-char (point-max)) + (forward-line -1) + (dolist (header saved-headers) + (insert header "\n")))))) -(defun message-forward-make-body-mime (forward-buffer &optional beg end - remove-headers) +(defun message-forward-make-body-mime (forward-buffer &optional beg end) (let ((b (point))) (insert "\n\n<#part type=message/rfc822 disposition=inline raw=t>\n") (save-restriction @@ -7650,8 +7693,7 @@ Optional DIGEST will use digest to forward." (goto-char (point-min)) (when (looking-at "From ") (replace-match "X-From-Line: ")) - (when remove-headers - (message-remove-ignored-headers (point-min) (point-max))) + (message-remove-ignored-headers (point-min) (point-max) t) (goto-char (point-max))) (insert "<#/part>\n") ;; Consider there is no illegible text. @@ -7790,8 +7832,7 @@ is for the internal use." (message-signed-or-encrypted-p) (error t)))))) (message-forward-make-body-mml forward-buffer) - (message-forward-make-body-mime - forward-buffer nil nil (not (eq message-forward-show-mml 'best)))) + (message-forward-make-body-mime forward-buffer)) (message-forward-make-body-plain forward-buffer))) (message-position-point)) commit b2d30fd6303a2461c591f0ace7eb2a43638bba21 Author: Eli Zaretskii Date: Thu Jan 21 16:21:45 2021 +0200 A better fix for 'kill-visual-line' * lisp/simple.el (kill-visual-line): Use the 6th element of the return value of 'posn-at-point', which provides the coordinates in terms or row and column, and is thus more reliable for deciding whether we moved to the next screen line. (Bug#45837) diff --git a/lisp/simple.el b/lisp/simple.el index 37c0885dcc..2c6e3916cd 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -7338,10 +7338,7 @@ even beep.)" ;; of the kill before killing. (let ((opoint (point)) (kill-whole-line (and kill-whole-line (bolp))) - (orig-y (cdr (nth 2 (posn-at-point)))) - ;; FIXME: This tolerance should be zero! It isn't due to a - ;; bug in posn-at-point, see bug#45837. - (tol (/ (line-pixel-height) 2))) + (orig-vlnum (cdr (nth 6 (posn-at-point))))) (if arg (vertical-motion (prefix-numeric-value arg)) (end-of-visual-line 1) @@ -7352,8 +7349,8 @@ even beep.)" ;; end-of-visual-line didn't overshoot due to complications ;; like display or overlay strings, intangible text, etc.: ;; otherwise, we don't want to kill a character that's - ;; unrelated to the place where the visual line wrapped. - (and (< (abs (- (cdr (nth 2 (posn-at-point))) orig-y)) tol) + ;; unrelated to the place where the visual line wraps. + (and (= (cdr (nth 6 (posn-at-point))) orig-vlnum) ;; Make sure we delete the character where the line wraps ;; under visual-line-mode, be it whitespace or a ;; character whose category set allows to wrap at it. commit 8e7728a5bfaf99efd3fb9ea7dd42dabd11a00b5c Author: Lars Ingebrigtsen Date: Thu Jan 21 12:45:24 2021 +0100 Fix thinko in previous footnote.el change * lisp/mail/footnote.el (footnote--regenerate-alist): Don't error out when there's no footnotes. diff --git a/lisp/mail/footnote.el b/lisp/mail/footnote.el index 9c1a738035..995ae5f916 100644 --- a/lisp/mail/footnote.el +++ b/lisp/mail/footnote.el @@ -916,8 +916,7 @@ play around with the following keys: (defun footnote--regenerate-alist () (save-excursion (goto-char (point-min)) - (if (not (re-search-forward footnote-section-tag-regexp nil t)) - (error "No footnote section in this buffer") + (when (re-search-forward footnote-section-tag-regexp nil t) (setq footnote--markers-alist (cl-loop with start-of-footnotes = (match-beginning 0) commit bacc24b5d0d708dd9ac34e314c2d3af25b311397 Author: Stefan Monnier Date: Wed Jan 20 23:45:18 2021 -0500 Use `lexical-binding` in all the cal-*.el files * lisp/calendar/cal-bahai.el: Use lexical-binding. (calendar-bahai-date-string): Use `calendar-dlet*`. * lisp/calendar/cal-china.el: Use lexical-binding. (calendar-chinese-zodiac-sign-on-or-after) (calendar-chinese-new-moon-on-or-after): Declare `year`. (calendar-chinese-from-absolute-for-diary) (calendar-chinese-to-absolute-for-diary) (calendar-chinese-mark-date-pattern): Avoid dynbound var `date` as function argument. * lisp/calendar/cal-coptic.el: Use lexical-binding. (calendar-coptic-date-string): Use `calendar-dlet*`. (calendar-ethiopic-to-absolute, calendar-ethiopic-from-absolute) (calendar-ethiopic-date-string, calendar-ethiopic-goto-date): Avoid dynbound var `date` as function argument. * lisp/calendar/cal-french.el: Use lexical-binding. * lisp/calendar/cal-hebrew.el: Use lexical-binding. (holiday-hebrew-hanukkah): Don't use the third form in `dotimes`. * lisp/calendar/cal-islam.el: Use lexical-binding. (calendar-islamic-to-absolute): Comment out unused vars `month` and `day`. * lisp/calendar/cal-move.el: * lisp/calendar/cal-mayan.el: * lisp/calendar/cal-iso.el: Use lexical-binding. * lisp/calendar/cal-persia.el: Use lexical-binding. (calendar-persian-date-string): Use `calendar-dlet*`. * lisp/calendar/cal-html.el: Use lexical-binding. (cal-html-insert-minical): Comment out unused var `date`. (cal-html-cursor-month, cal-html-cursor-year): Mark `event` arg as unused. * lisp/calendar/cal-menu.el: Use lexical-binding. (diary-list-include-blanks): Declare var. * lisp/calendar/cal-x.el: Use lexical-binding. * lisp/calendar/cal-tex.el: Use lexical-binding. (diary-list-include-blanks): Declare var. (cal-tex-insert-days, cal-tex-cursor-week-iso, cal-tex-week-hours) (cal-tex-weekly-common, cal-tex-cursor-filofax-2week) (cal-tex-cursor-filofax-daily, cal-tex-daily-page): Declare `date` as dynbound for the benefit of `cal-tex-daily-string`. diff --git a/lisp/calendar/cal-bahai.el b/lisp/calendar/cal-bahai.el index 16176e37b4..c2e4205c0b 100644 --- a/lisp/calendar/cal-bahai.el +++ b/lisp/calendar/cal-bahai.el @@ -1,4 +1,4 @@ -;;; cal-bahai.el --- calendar functions for the Bahá’í calendar. +;;; cal-bahai.el --- calendar functions for the Bahá’í calendar. -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. @@ -124,9 +124,10 @@ Defaults to today's date if DATE is not given." (y (calendar-extract-year bahai-date))) (if (< y 1) "" ; pre-Bahai - (let* ((m (calendar-extract-month bahai-date)) - (d (calendar-extract-day bahai-date)) - (monthname (if (and (= m 19) + (let ((m (calendar-extract-month bahai-date)) + (d (calendar-extract-day bahai-date))) + (calendar-dlet* + ((monthname (if (and (= m 19) (<= d 0)) "Ayyám-i-Há" (aref calendar-bahai-month-name-array (1- m)))) @@ -137,8 +138,8 @@ Defaults to today's date if DATE is not given." (year (number-to-string y)) (month (number-to-string m)) dayname) - ;; Can't call calendar-date-string because of monthname oddity. - (mapconcat 'eval calendar-date-display-form ""))))) + ;; Can't call calendar-date-string because of monthname oddity. + (mapconcat #'eval calendar-date-display-form "")))))) ;;;###cal-autoload (defun calendar-bahai-print-date () diff --git a/lisp/calendar/cal-china.el b/lisp/calendar/cal-china.el index dd69d849df..9a28984a7a 100644 --- a/lisp/calendar/cal-china.el +++ b/lisp/calendar/cal-china.el @@ -1,4 +1,4 @@ -;;; cal-china.el --- calendar functions for the Chinese calendar +;;; cal-china.el --- calendar functions for the Chinese calendar -*- lexical-binding: t; -*- ;; Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. @@ -185,7 +185,9 @@ N congruent to 1 gives the first name, N congruent to 2 gives the second name, (defun calendar-chinese-zodiac-sign-on-or-after (d) "Absolute date of first new Zodiac sign on or after absolute date D. The Zodiac signs begin when the sun's longitude is a multiple of 30 degrees." - (let* ((year (calendar-extract-year (calendar-gregorian-from-absolute d))) + (with-suppressed-warnings ((lexical year)) + (defvar year)) + (let* ((year (calendar-extract-year (calendar-gregorian-from-absolute d))) (calendar-time-zone (eval calendar-chinese-time-zone)) ; uses year (calendar-daylight-time-offset calendar-chinese-daylight-time-offset) @@ -207,6 +209,8 @@ The Zodiac signs begin when the sun's longitude is a multiple of 30 degrees." (defun calendar-chinese-new-moon-on-or-after (d) "Absolute date of first new moon on or after absolute date D." + (with-suppressed-warnings ((lexical year)) + (defvar year)) (let* ((year (calendar-extract-year (calendar-gregorian-from-absolute d))) (calendar-time-zone (eval calendar-chinese-time-zone)) (calendar-daylight-time-offset @@ -665,17 +669,17 @@ Echo Chinese date unless NOECHO is non-nil." ["正月" "二月" "三月" "四月" "五月" "六月" "七月" "八月" "九月" "十月" "冬月" "臘月"]) -;;; NOTE: In the diary the cycle and year of a Chinese date is -;;; combined using this formula: (+ (* cycle 100) year). +;; NOTE: In the diary the cycle and year of a Chinese date is +;; combined using this formula: (+ (* cycle 100) year). ;;; -;;; These two functions convert to and back from this representation. -(defun calendar-chinese-from-absolute-for-diary (date) - (pcase-let ((`(,c ,y ,m ,d) (calendar-chinese-from-absolute date))) +;; These two functions convert to and back from this representation. +(defun calendar-chinese-from-absolute-for-diary (thedate) + (pcase-let ((`(,c ,y ,m ,d) (calendar-chinese-from-absolute thedate))) ;; Note: For leap months M is a float. (list (floor m) d (+ (* c 100) y)))) -(defun calendar-chinese-to-absolute-for-diary (date &optional prefer-leap) - (pcase-let* ((`(,m ,d ,y) date) +(defun calendar-chinese-to-absolute-for-diary (thedate &optional prefer-leap) + (pcase-let* ((`(,m ,d ,y) thedate) (cycle (floor y 100)) (year (mod y 100)) (months (calendar-chinese-months cycle year)) @@ -693,7 +697,8 @@ Echo Chinese date unless NOECHO is non-nil." (unless (zerop month) (calendar-mark-1 month day year #'calendar-chinese-from-absolute-for-diary - (lambda (date) (calendar-chinese-to-absolute-for-diary date t)) + (lambda (thedate) + (calendar-chinese-to-absolute-for-diary thedate t)) color))) ;;;###cal-autoload diff --git a/lisp/calendar/cal-coptic.el b/lisp/calendar/cal-coptic.el index 2a0e7d81e0..346585e181 100644 --- a/lisp/calendar/cal-coptic.el +++ b/lisp/calendar/cal-coptic.el @@ -1,4 +1,4 @@ -;;; cal-coptic.el --- calendar functions for the Coptic/Ethiopic calendars +;;; cal-coptic.el --- calendar functions for the Coptic/Ethiopic calendars -*- lexical-binding: t; -*- ;; Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. @@ -116,12 +116,13 @@ Defaults to today's date if DATE is not given." (m (calendar-extract-month coptic-date))) (if (< y 1) "" - (let ((monthname (aref calendar-coptic-month-name-array (1- m))) - (day (number-to-string (calendar-extract-day coptic-date))) - (dayname nil) - (month (number-to-string m)) - (year (number-to-string y))) - (mapconcat 'eval calendar-date-display-form ""))))) + (calendar-dlet* + ((monthname (aref calendar-coptic-month-name-array (1- m))) + (day (number-to-string (calendar-extract-day coptic-date))) + (dayname nil) + (month (number-to-string m)) + (year (number-to-string y))) + (mapconcat #'eval calendar-date-display-form ""))))) ;;;###cal-autoload (defun calendar-coptic-print-date () @@ -197,30 +198,30 @@ Echo Coptic date unless NOECHO is t." (defconst calendar-ethiopic-name "Ethiopic" "Used in some message strings.") -(defun calendar-ethiopic-to-absolute (date) +(defun calendar-ethiopic-to-absolute (thedate) "Compute absolute date from Ethiopic date DATE. The absolute date is the number of days elapsed since the (imaginary) Gregorian date Sunday, December 31, 1 BC." (let ((calendar-coptic-epoch calendar-ethiopic-epoch)) - (calendar-coptic-to-absolute date))) + (calendar-coptic-to-absolute thedate))) -(defun calendar-ethiopic-from-absolute (date) +(defun calendar-ethiopic-from-absolute (thedate) "Compute the Ethiopic equivalent for absolute date DATE. The result is a list of the form (MONTH DAY YEAR). The absolute date is the number of days elapsed since the imaginary Gregorian date Sunday, December 31, 1 BC." (let ((calendar-coptic-epoch calendar-ethiopic-epoch)) - (calendar-coptic-from-absolute date))) + (calendar-coptic-from-absolute thedate))) ;;;###cal-autoload -(defun calendar-ethiopic-date-string (&optional date) +(defun calendar-ethiopic-date-string (&optional thedate) "String of Ethiopic date of Gregorian DATE. Returns the empty string if DATE is pre-Ethiopic calendar. Defaults to today's date if DATE is not given." (let ((calendar-coptic-epoch calendar-ethiopic-epoch) (calendar-coptic-name calendar-ethiopic-name) (calendar-coptic-month-name-array calendar-ethiopic-month-name-array)) - (calendar-coptic-date-string date))) + (calendar-coptic-date-string thedate))) ;;;###cal-autoload (defun calendar-ethiopic-print-date () @@ -232,8 +233,8 @@ Defaults to today's date if DATE is not given." (call-interactively 'calendar-coptic-print-date))) ;;;###cal-autoload -(defun calendar-ethiopic-goto-date (date &optional noecho) - "Move cursor to Ethiopic date DATE. +(defun calendar-ethiopic-goto-date (thedate &optional noecho) + "Move cursor to Ethiopic date THEDATE. Echo Ethiopic date unless NOECHO is t." (interactive (let ((calendar-coptic-epoch calendar-ethiopic-epoch) @@ -241,7 +242,7 @@ Echo Ethiopic date unless NOECHO is t." (calendar-coptic-month-name-array calendar-ethiopic-month-name-array)) (calendar-coptic-read-date))) (calendar-goto-date (calendar-gregorian-from-absolute - (calendar-ethiopic-to-absolute date))) + (calendar-ethiopic-to-absolute thedate))) (or noecho (calendar-ethiopic-print-date))) ;; To be called from diary-list-sexp-entries, where DATE is bound. diff --git a/lisp/calendar/cal-french.el b/lisp/calendar/cal-french.el index 07c41c00bf..639bae700c 100644 --- a/lisp/calendar/cal-french.el +++ b/lisp/calendar/cal-french.el @@ -1,4 +1,4 @@ -;;; cal-french.el --- calendar functions for the French Revolutionary calendar +;;; cal-french.el --- calendar functions for the French Revolutionary calendar -*- lexical-binding: t; -*- ;; Copyright (C) 1988-1989, 1992, 1994-1995, 1997, 2001-2021 Free ;; Software Foundation, Inc. diff --git a/lisp/calendar/cal-hebrew.el b/lisp/calendar/cal-hebrew.el index a835f9b430..50b4fc363b 100644 --- a/lisp/calendar/cal-hebrew.el +++ b/lisp/calendar/cal-hebrew.el @@ -1,4 +1,4 @@ -;;; cal-hebrew.el --- calendar functions for the Hebrew calendar +;;; cal-hebrew.el --- calendar functions for the Hebrew calendar -*- lexical-binding: t; -*- ;; Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. @@ -399,19 +399,20 @@ is non-nil." (list m (calendar-last-day-of-month m y) y)))))) (abs-h (calendar-hebrew-to-absolute (list 9 25 h-y))) (ord ["first" "second" "third" "fourth" "fifth" "sixth" - "seventh" "eighth"]) - han) + "seventh" "eighth"])) (holiday-filter-visible-calendar (if (or all calendar-hebrew-all-holidays-flag) (append (list (list (calendar-gregorian-from-absolute (1- abs-h)) "Erev Hanukkah")) - (dotimes (i 8 (nreverse han)) - (push (list - (calendar-gregorian-from-absolute (+ abs-h i)) - (format "Hanukkah (%s day)" (aref ord i))) - han))) + (let (han) + (dotimes (i 8) + (push (list + (calendar-gregorian-from-absolute (+ abs-h i)) + (format "Hanukkah (%s day)" (aref ord i))) + han)) + (nreverse han))) (list (list (calendar-gregorian-from-absolute abs-h) "Hanukkah"))))))) ;;;###holiday-autoload diff --git a/lisp/calendar/cal-html.el b/lisp/calendar/cal-html.el index 3d7cc93843..e5810c3f02 100644 --- a/lisp/calendar/cal-html.el +++ b/lisp/calendar/cal-html.el @@ -1,4 +1,4 @@ -;;; cal-html.el --- functions for printing HTML calendars +;;; cal-html.el --- functions for printing HTML calendars -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. @@ -250,7 +250,7 @@ Contains links to previous and next month and year, and current minical." calendar-week-start-day)) 7)) (monthpage-name (cal-html-monthpage-name month year)) - date) + ) ;; date ;; Start writing table. (insert (cal-html-comment "MINICAL") (cal-html-b-table "class=minical border=1 align=center")) @@ -276,7 +276,7 @@ Contains links to previous and next month and year, and current minical." (insert cal-html-e-tablerow-string cal-html-b-tablerow-string))) ;; End empty slots (for some browsers like konqueror). - (dotimes (i end-blank-days) + (dotimes (_ end-blank-days) (insert cal-html-b-tabledata-string cal-html-e-tabledata-string))) @@ -431,12 +431,11 @@ holidays in HOLIDAY-LIST." ;;; User commands. ;;;###cal-autoload -(defun cal-html-cursor-month (month year dir &optional event) +(defun cal-html-cursor-month (month year dir &optional _event) "Write an HTML calendar file for numeric MONTH of four-digit YEAR. The output directory DIR is created if necessary. Interactively, -MONTH and YEAR are taken from the calendar cursor position, or from -the position specified by EVENT. Note that any existing output files -are overwritten." +MONTH and YEAR are taken from the calendar cursor position. +Note that any existing output files are overwritten." (interactive (let* ((event last-nonmenu-event) (date (calendar-cursor-to-date t event)) (month (calendar-extract-month date)) @@ -446,11 +445,11 @@ are overwritten." (cal-html-one-month month year dir)) ;;;###cal-autoload -(defun cal-html-cursor-year (year dir &optional event) +(defun cal-html-cursor-year (year dir &optional _event) "Write HTML calendar files (index and monthly pages) for four-digit YEAR. The output directory DIR is created if necessary. Interactively, -YEAR is taken from the calendar cursor position, or from the position -specified by EVENT. Note that any existing output files are overwritten." +YEAR is taken from the calendar cursor position. +Note that any existing output files are overwritten." (interactive (let* ((event last-nonmenu-event) (year (calendar-extract-year (calendar-cursor-to-date t event)))) diff --git a/lisp/calendar/cal-islam.el b/lisp/calendar/cal-islam.el index 4082ed43e5..45c6ffa7bd 100644 --- a/lisp/calendar/cal-islam.el +++ b/lisp/calendar/cal-islam.el @@ -1,4 +1,4 @@ -;;; cal-islam.el --- calendar functions for the Islamic calendar +;;; cal-islam.el --- calendar functions for the Islamic calendar -*- lexical-binding: t; -*- ;; Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. @@ -67,8 +67,8 @@ "Absolute date of Islamic DATE. The absolute date is the number of days elapsed since the (imaginary) Gregorian date Sunday, December 31, 1 BC." - (let* ((month (calendar-extract-month date)) - (day (calendar-extract-day date)) + (let* (;;(month (calendar-extract-month date)) + ;;(day (calendar-extract-day date)) (year (calendar-extract-year date)) (y (% year 30)) (leap-years-in-cycle (cond ((< y 3) 0) diff --git a/lisp/calendar/cal-iso.el b/lisp/calendar/cal-iso.el index a247b2d15a..90f57c25e9 100644 --- a/lisp/calendar/cal-iso.el +++ b/lisp/calendar/cal-iso.el @@ -1,4 +1,4 @@ -;;; cal-iso.el --- calendar functions for the ISO calendar +;;; cal-iso.el --- calendar functions for the ISO calendar -*- lexical-binding: t; -*- ;; Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/calendar/cal-mayan.el b/lisp/calendar/cal-mayan.el index e3533e7b1d..9a22192113 100644 --- a/lisp/calendar/cal-mayan.el +++ b/lisp/calendar/cal-mayan.el @@ -1,4 +1,4 @@ -;;; cal-mayan.el --- calendar functions for the Mayan calendars +;;; cal-mayan.el --- calendar functions for the Mayan calendars -*- lexical-binding: t; -*- ;; Copyright (C) 1992-1993, 1995, 1997, 2001-2021 Free Software ;; Foundation, Inc. diff --git a/lisp/calendar/cal-menu.el b/lisp/calendar/cal-menu.el index a30c681a89..497f332905 100644 --- a/lisp/calendar/cal-menu.el +++ b/lisp/calendar/cal-menu.el @@ -1,4 +1,4 @@ -;;; cal-menu.el --- calendar functions for menu bar and popup menu support +;;; cal-menu.el --- calendar functions for menu bar and popup menu support -*- lexical-binding: t; -*- ;; Copyright (C) 1994-1995, 2001-2021 Free Software Foundation, Inc. @@ -183,6 +183,8 @@ Signals an error if popups are unavailable." ;; Autoloaded in diary-lib. (declare-function calendar-check-holidays "holidays" (date)) +(defvar diary-list-include-blanks) + (defun calendar-mouse-view-diary-entries (&optional date diary event) "Pop up menu of diary entries for mouse-selected date. Use optional DATE and alternative file DIARY. EVENT is the event diff --git a/lisp/calendar/cal-move.el b/lisp/calendar/cal-move.el index c2b5d618ea..9294362cb4 100644 --- a/lisp/calendar/cal-move.el +++ b/lisp/calendar/cal-move.el @@ -1,4 +1,4 @@ -;;; cal-move.el --- calendar functions for movement in the calendar +;;; cal-move.el --- calendar functions for movement in the calendar -*- lexical-binding: t; -*- ;; Copyright (C) 1995, 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/calendar/cal-persia.el b/lisp/calendar/cal-persia.el index 21085284ac..ca37d80322 100644 --- a/lisp/calendar/cal-persia.el +++ b/lisp/calendar/cal-persia.el @@ -1,4 +1,4 @@ -;;; cal-persia.el --- calendar functions for the Persian calendar +;;; cal-persia.el --- calendar functions for the Persian calendar -*- lexical-binding: t; -*- ;; Copyright (C) 1996-1997, 2001-2021 Free Software Foundation, Inc. @@ -139,13 +139,14 @@ Gregorian date Sunday, December 31, 1 BC." (calendar-absolute-from-gregorian (or date (calendar-current-date))))) (y (calendar-extract-year persian-date)) - (m (calendar-extract-month persian-date)) - (monthname (aref calendar-persian-month-name-array (1- m))) + (m (calendar-extract-month persian-date))) + (calendar-dlet* + ((monthname (aref calendar-persian-month-name-array (1- m))) (day (number-to-string (calendar-extract-day persian-date))) (year (number-to-string y)) (month (number-to-string m)) dayname) - (mapconcat 'eval calendar-date-display-form ""))) + (mapconcat #'eval calendar-date-display-form "")))) ;;;###cal-autoload (defun calendar-persian-print-date () diff --git a/lisp/calendar/cal-tex.el b/lisp/calendar/cal-tex.el index 9df9f4cbed..f5932014dd 100644 --- a/lisp/calendar/cal-tex.el +++ b/lisp/calendar/cal-tex.el @@ -1,4 +1,4 @@ -;;; cal-tex.el --- calendar functions for printing calendars with LaTeX +;;; cal-tex.el --- calendar functions for printing calendars with LaTeX -*- lexical-binding: t; -*- ;; Copyright (C) 1995, 2001-2021 Free Software Foundation, Inc. @@ -248,6 +248,8 @@ This definition is the heart of the calendar!") (autoload 'diary-list-entries "diary-lib") +(defvar diary-list-include-blanks) + (defun cal-tex-list-diary-entries (d1 d2) "Generate a list of all diary-entries from absolute date D1 to D2." (let (diary-list-include-blanks) @@ -591,6 +593,8 @@ indicates a buffer position to use instead of point." LaTeX commands are inserted for the days of the MONTH in YEAR. Diary entries on DIARY-LIST are included. Holidays on HOLIDAYS are included. Each day is formatted using format DAY-FORMAT." + (with-suppressed-warnings ((lexical date)) + (defvar date)) ;For `cal-tex-daily-string'. (let ((blank-days ; at start of month (mod (- (calendar-day-of-week (list month 1 year)) @@ -605,7 +609,7 @@ are included. Each day is formatted using format DAY-FORMAT." (insert (format day-format (cal-tex-month-name month) j)) (cal-tex-arg (cal-tex-latexify-list diary-list date)) (cal-tex-arg (cal-tex-latexify-list holidays date)) - (cal-tex-arg (eval cal-tex-daily-string)) + (cal-tex-arg (eval cal-tex-daily-string t)) (cal-tex-arg) (cal-tex-comment)) (when (and (zerop (mod (+ j blank-days) 7)) @@ -885,13 +889,15 @@ argument EVENT specifies a different buffer position." (interactive (list (prefix-numeric-value current-prefix-arg) last-nonmenu-event)) (or n (setq n 1)) + (with-suppressed-warnings ((lexical date)) + (defvar date)) ;For `cal-tex-daily-string'. (let* ((date (calendar-gregorian-from-absolute (calendar-dayname-on-or-before 1 (calendar-absolute-from-gregorian (calendar-cursor-to-date t event))))) (month (calendar-extract-month date)) - (year (calendar-extract-year date)) + ;; (year (calendar-extract-year date)) (day (calendar-extract-day date)) (d1 (calendar-absolute-from-gregorian date)) (d2 (+ (* 7 n) d1)) @@ -932,7 +938,7 @@ argument EVENT specifies a different buffer position." (insert ": ") (cal-tex-large-bf s)) (cal-tex-hfill) - (insert " " (eval cal-tex-daily-string)) + (insert " " (eval cal-tex-daily-string t)) (cal-tex-e-parbox) (cal-tex-nl) (cal-tex-noindent) @@ -951,7 +957,8 @@ argument EVENT specifies a different buffer position." (cal-tex-e-parbox "2cm") (cal-tex-nl) (setq month (calendar-extract-month date) - year (calendar-extract-year date))) + ;; year (calendar-extract-year date) + )) (cal-tex-e-parbox) (unless (= i (1- n)) (run-hooks 'cal-tex-week-hook) @@ -961,13 +968,16 @@ argument EVENT specifies a different buffer position." ;; TODO respect cal-tex-daily-start,end? ;; Using different numbers of hours will probably break some layouts. -(defun cal-tex-week-hours (date holidays height) - "Insert hourly entries for DATE with HOLIDAYS, with line height HEIGHT. +(defun cal-tex-week-hours (thedate holidays height) + "Insert hourly entries for THEDATE with HOLIDAYS, with line height HEIGHT. Uses the 24-hour clock if `cal-tex-24' is non-nil. Note that the hours shown are hard-coded to 8-12, 13-17." - (let ((month (calendar-extract-month date)) + (with-suppressed-warnings ((lexical date)) + (defvar date)) ;For `cal-tex-daily-string'. + (let ((date thedate) + (month (calendar-extract-month date)) (day (calendar-extract-day date)) - (year (calendar-extract-year date)) + ;; (year (calendar-extract-year date)) morning afternoon s) (cal-tex-comment "begin cal-tex-week-hours") (cal-tex-cmd "\\ \\\\[-.2cm]") @@ -983,7 +993,7 @@ shown are hard-coded to 8-12, 13-17." (insert ": ") (cal-tex-large-bf s)) (cal-tex-hfill) - (insert " " (eval cal-tex-daily-string)) + (insert " " (eval cal-tex-daily-string t)) (cal-tex-e-parbox) (cal-tex-nl "-.3cm") (cal-tex-rule "0pt" "6.8in" ".2mm") @@ -1088,14 +1098,16 @@ shown are hard-coded to 8-12, 13-17." (defun cal-tex-weekly-common (n event &optional filofax) "Common code for weekly calendars." (or n (setq n 1)) + (with-suppressed-warnings ((lexical date)) + (defvar date)) ;For `cal-tex-daily-string'. (let* ((date (calendar-gregorian-from-absolute (calendar-dayname-on-or-before 1 (calendar-absolute-from-gregorian (calendar-cursor-to-date t event))))) - (month (calendar-extract-month date)) - (year (calendar-extract-year date)) - (day (calendar-extract-day date)) + ;; (month (calendar-extract-month date)) + ;; (year (calendar-extract-year date)) + ;; (day (calendar-extract-day date)) (d1 (calendar-absolute-from-gregorian date)) (d2 (+ (* 7 n) d1)) (holidays (if cal-tex-holidays @@ -1161,7 +1173,7 @@ shown are hard-coded to 8-12, 13-17." (cal-tex-arg (number-to-string (calendar-extract-day date))) (cal-tex-arg (cal-tex-latexify-list diary-list date)) (cal-tex-arg (cal-tex-latexify-list holidays date)) - (cal-tex-arg (eval cal-tex-daily-string)) + (cal-tex-arg (eval cal-tex-daily-string t)) (insert "%\n") (setq date (cal-tex-incr-date date))) (insert "\\noindent\\rule{\\textwidth}{0.3pt}\\\\%\n") @@ -1258,14 +1270,16 @@ Optional EVENT indicates a buffer position to use instead of point." (interactive (list (prefix-numeric-value current-prefix-arg) last-nonmenu-event)) (or n (setq n 1)) + (with-suppressed-warnings ((lexical date)) + (defvar date)) ;For `cal-tex-daily-string'. (let* ((date (calendar-gregorian-from-absolute (calendar-dayname-on-or-before calendar-week-start-day (calendar-absolute-from-gregorian (calendar-cursor-to-date t event))))) - (month (calendar-extract-month date)) - (year (calendar-extract-year date)) - (day (calendar-extract-day date)) + ;; (month (calendar-extract-month date)) + ;; (year (calendar-extract-year date)) + ;; (day (calendar-extract-day date)) (d1 (calendar-absolute-from-gregorian date)) (d2 (+ (* 7 n) d1)) (holidays (if cal-tex-holidays @@ -1311,7 +1325,7 @@ Optional EVENT indicates a buffer position to use instead of point." (cal-tex-arg (number-to-string (calendar-extract-day date))) (cal-tex-arg (cal-tex-latexify-list diary-list date)) (cal-tex-arg (cal-tex-latexify-list holidays date)) - (cal-tex-arg (eval cal-tex-daily-string)) + (cal-tex-arg (eval cal-tex-daily-string t)) (insert "%\n") (setq date (cal-tex-incr-date date))) (unless (= i (1- n)) @@ -1342,14 +1356,16 @@ Optional EVENT indicates a buffer position to use instead of point." (interactive (list (prefix-numeric-value current-prefix-arg) last-nonmenu-event)) (or n (setq n 1)) + (with-suppressed-warnings ((lexical date)) + (defvar date)) ;For `cal-tex-daily-string'. (let* ((date (calendar-gregorian-from-absolute (calendar-dayname-on-or-before 1 (calendar-absolute-from-gregorian (calendar-cursor-to-date t event))))) - (month (calendar-extract-month date)) - (year (calendar-extract-year date)) - (day (calendar-extract-day date)) + ;; (month (calendar-extract-month date)) + ;; (year (calendar-extract-year date)) + ;; (day (calendar-extract-day date)) (d1 (calendar-absolute-from-gregorian date)) (d2 (+ (* 7 n) d1)) (holidays (if cal-tex-holidays @@ -1383,11 +1399,11 @@ Optional EVENT indicates a buffer position to use instead of point." "\\leftday"))) (cal-tex-arg (cal-tex-latexify-list diary-list date)) (cal-tex-arg (cal-tex-latexify-list holidays date "\\\\" t)) - (cal-tex-arg (eval cal-tex-daily-string)) + (cal-tex-arg (eval cal-tex-daily-string t)) (insert "%\n") - (if cal-tex-rules - (insert "\\linesfill\n") - (insert "\\vfill\\noindent\\rule{\\textwidth}{0.3pt}\\\\%\n")) + (insert (if cal-tex-rules + "\\linesfill\n" + "\\vfill\\noindent\\rule{\\textwidth}{0.3pt}\\\\%\n")) (cal-tex-newpage) (setq date (cal-tex-incr-date date))) (insert "%\n") @@ -1397,11 +1413,11 @@ Optional EVENT indicates a buffer position to use instead of point." (insert "\\weekend") (cal-tex-arg (cal-tex-latexify-list diary-list date)) (cal-tex-arg (cal-tex-latexify-list holidays date "\\\\" t)) - (cal-tex-arg (eval cal-tex-daily-string)) + (cal-tex-arg (eval cal-tex-daily-string t)) (insert "%\n") - (if cal-tex-rules - (insert "\\linesfill\n") - (insert "\\vfill")) + (insert (if cal-tex-rules + "\\linesfill\n" + "\\vfill")) (setq date (cal-tex-incr-date date))) (or cal-tex-rules (insert "\\noindent\\rule{\\textwidth}{0.3pt}\\\\%\n")) @@ -1442,12 +1458,15 @@ a buffer position to use instead of point." (cal-tex-end-document) (run-hooks 'cal-tex-hook))) -(defun cal-tex-daily-page (date) - "Make a calendar page for Gregorian DATE on 8.5 by 11 paper. +(defun cal-tex-daily-page (thedate) + "Make a calendar page for Gregorian THEDATE on 8.5 by 11 paper. Uses the 24-hour clock if `cal-tex-24' is non-nil. Produces hourly sections for the period specified by `cal-tex-daily-start' and `cal-tex-daily-end'." - (let ((month-name (cal-tex-month-name (calendar-extract-month date))) + (with-suppressed-warnings ((lexical date)) + (defvar date)) ;For `cal-tex-daily-string'. + (let ((date thedate) + (month-name (cal-tex-month-name (calendar-extract-month date))) (i (1- cal-tex-daily-start)) hour) (cal-tex-banner "cal-tex-daily-page") @@ -1459,7 +1478,7 @@ and `cal-tex-daily-end'." (cal-tex-bf month-name ) (cal-tex-e-parbox) (cal-tex-hspace "1cm") - (cal-tex-scriptsize (eval cal-tex-daily-string)) + (cal-tex-scriptsize (eval cal-tex-daily-string t)) (cal-tex-hspace "3.5cm") (cal-tex-e-makebox) (cal-tex-hfill) diff --git a/lisp/calendar/cal-x.el b/lisp/calendar/cal-x.el index 1c19a60db1..ca303ce39a 100644 --- a/lisp/calendar/cal-x.el +++ b/lisp/calendar/cal-x.el @@ -1,4 +1,4 @@ -;;; cal-x.el --- calendar windows in dedicated frames +;;; cal-x.el --- calendar windows in dedicated frames -*- lexical-binding: t; -*- ;; Copyright (C) 1994-1995, 2001-2021 Free Software Foundation, Inc. commit 0c93d0d072d6030c57bb8ab9e7b90686ed79af15 Author: Stefan Monnier Date: Wed Jan 20 23:14:25 2021 -0500 Use `calendar-read-sexp` instead of the now obsolete `calendar-read` * lisp/calendar/diary-lib.el (diary-insert-cyclic-entry): * lisp/calendar/cal-persia.el (calendar-persian-read-date): * lisp/calendar/cal-move.el (calendar-goto-day-of-year): * lisp/calendar/cal-mayan.el (calendar-mayan-read-haab-date) (calendar-mayan-read-tzolkin-date): * lisp/calendar/cal-julian.el (calendar-julian-goto-date) (calendar-astro-goto-day-number): * lisp/calendar/cal-iso.el (calendar-iso-read-date): * lisp/calendar/cal-islam.el (calendar-islamic-read-date): * lisp/calendar/cal-hebrew.el (calendar-hebrew-read-date) (calendar-hebrew-list-yahrzeits): * lisp/calendar/cal-french.el (calendar-french-goto-date): * lisp/calendar/cal-coptic.el (calendar-coptic-read-date): * lisp/calendar/cal-china.el (calendar-chinese-goto-date): * lisp/calendar/cal-bahai.el (calendar-bahai-read-date): * lisp/calendar/holidays.el (list-holidays): Use `calendar-read-sexp`. diff --git a/lisp/calendar/cal-bahai.el b/lisp/calendar/cal-bahai.el index 22e4cdbcd5..16176e37b4 100644 --- a/lisp/calendar/cal-bahai.el +++ b/lisp/calendar/cal-bahai.el @@ -153,13 +153,12 @@ Defaults to today's date if DATE is not given." "Interactively read the arguments for a Bahá’í date command. Reads a year, month and day." (let* ((today (calendar-current-date)) - (year (calendar-read - "Bahá’í calendar year (not 0): " + (year (calendar-read-sexp + "Bahá’í calendar year (not 0)" (lambda (x) (not (zerop x))) - (number-to-string - (calendar-extract-year - (calendar-bahai-from-absolute - (calendar-absolute-from-gregorian today)))))) + (calendar-extract-year + (calendar-bahai-from-absolute + (calendar-absolute-from-gregorian today))))) (completion-ignore-case t) (month (cdr (assoc (completing-read @@ -169,8 +168,8 @@ Reads a year, month and day." nil t) (calendar-make-alist calendar-bahai-month-name-array 1)))) - (day (calendar-read "Bahá’í calendar day (1-19): " - (lambda (x) (and (< 0 x) (<= x 19)))))) + (day (calendar-read-sexp "Bahá’í calendar day (1-19)" + (lambda (x) (and (< 0 x) (<= x 19)))))) (list (list month day year)))) ;;;###cal-autoload diff --git a/lisp/calendar/cal-china.el b/lisp/calendar/cal-china.el index 7e5d0c46e1..dd69d849df 100644 --- a/lisp/calendar/cal-china.el +++ b/lisp/calendar/cal-china.el @@ -602,14 +602,14 @@ Echo Chinese date unless NOECHO is non-nil." (interactive (let* ((c (calendar-chinese-from-absolute (calendar-absolute-from-gregorian (calendar-current-date)))) - (cycle (calendar-read - "Chinese calendar cycle number (>44): " + (cycle (calendar-read-sexp + "Chinese calendar cycle number (>44)" (lambda (x) (> x 44)) - (number-to-string (car c)))) - (year (calendar-read - "Year in Chinese cycle (1..60): " + (car c))) + (year (calendar-read-sexp + "Year in Chinese cycle (1..60)" (lambda (x) (and (<= 1 x) (<= x 60))) - (number-to-string (cadr c)))) + (cadr c))) (month-list (calendar-chinese-months-to-alist (calendar-chinese-months cycle year))) (month (cdr (assoc @@ -624,9 +624,11 @@ Echo Chinese date unless NOECHO is non-nil." (list cycle year month 1)))))) 30 29)) - (day (calendar-read - (format "Chinese calendar day (1-%d): " last) - (lambda (x) (and (<= 1 x) (<= x last)))))) + (day (calendar-read-sexp + "Chinese calendar day (1-%d)" + (lambda (x) (and (<= 1 x) (<= x last))) + nil + last))) (list (list cycle year month day)))) (calendar-goto-date (calendar-gregorian-from-absolute (calendar-chinese-to-absolute date))) diff --git a/lisp/calendar/cal-coptic.el b/lisp/calendar/cal-coptic.el index 3461f3259b..2a0e7d81e0 100644 --- a/lisp/calendar/cal-coptic.el +++ b/lisp/calendar/cal-coptic.el @@ -136,13 +136,13 @@ Defaults to today's date if DATE is not given." "Interactively read the arguments for a Coptic date command. Reads a year, month, and day." (let* ((today (calendar-current-date)) - (year (calendar-read - (format "%s calendar year (>0): " calendar-coptic-name) + (year (calendar-read-sexp + "%s calendar year (>0)" (lambda (x) (> x 0)) - (number-to-string - (calendar-extract-year - (calendar-coptic-from-absolute - (calendar-absolute-from-gregorian today)))))) + (calendar-extract-year + (calendar-coptic-from-absolute + (calendar-absolute-from-gregorian today))) + calendar-coptic-name)) (completion-ignore-case t) (month (cdr (assoc-string (completing-read @@ -151,11 +151,14 @@ Reads a year, month, and day." (append calendar-coptic-month-name-array nil)) nil t) (calendar-make-alist calendar-coptic-month-name-array - 1) t))) + 1) + t))) (last (calendar-coptic-last-day-of-month month year)) - (day (calendar-read - (format "%s calendar day (1-%d): " calendar-coptic-name last) - (lambda (x) (and (< 0 x) (<= x last)))))) + (day (calendar-read-sexp + "%s calendar day (1-%d)" + (lambda (x) (and (< 0 x) (<= x last))) + nil + calendar-coptic-name last))) (list (list month day year)))) ;;;###cal-autoload diff --git a/lisp/calendar/cal-french.el b/lisp/calendar/cal-french.el index c8ab6c41d8..07c41c00bf 100644 --- a/lisp/calendar/cal-french.el +++ b/lisp/calendar/cal-french.el @@ -188,14 +188,13 @@ Echo French Revolutionary date unless NOECHO is non-nil." (let* ((months calendar-french-month-name-array) (special-days calendar-french-special-days-array) (year (progn - (calendar-read - "Année de la Révolution (>0): " + (calendar-read-sexp + "Année de la Révolution (>0)" (lambda (x) (> x 0)) - (number-to-string - (calendar-extract-year - (calendar-french-from-absolute - (calendar-absolute-from-gregorian - (calendar-current-date)))))))) + (calendar-extract-year + (calendar-french-from-absolute + (calendar-absolute-from-gregorian + (calendar-current-date))))))) (month-list (mapcar 'list (append months @@ -219,8 +218,8 @@ Echo French Revolutionary date unless NOECHO is non-nil." (calendar-make-alist month-list 1 'car) t))) (day (if (> month 12) (- month 12) - (calendar-read - "Jour (1-30): " + (calendar-read-sexp + "Jour (1-30)" (lambda (x) (and (<= 1 x) (<= x 30)))))) (month (if (> month 12) 13 month))) (list (list month day year)))) diff --git a/lisp/calendar/cal-hebrew.el b/lisp/calendar/cal-hebrew.el index bcc80f0877..a835f9b430 100644 --- a/lisp/calendar/cal-hebrew.el +++ b/lisp/calendar/cal-hebrew.el @@ -225,13 +225,12 @@ Driven by the variable `calendar-date-display-form'." "Interactively read the arguments for a Hebrew date command. Reads a year, month, and day." (let* ((today (calendar-current-date)) - (year (calendar-read - "Hebrew calendar year (>3760): " + (year (calendar-read-sexp + "Hebrew calendar year (>3760)" (lambda (x) (> x 3760)) - (number-to-string - (calendar-extract-year - (calendar-hebrew-from-absolute - (calendar-absolute-from-gregorian today)))))) + (calendar-extract-year + (calendar-hebrew-from-absolute + (calendar-absolute-from-gregorian today))))) (month-array (if (calendar-hebrew-leap-year-p year) calendar-hebrew-month-name-array-leap-year calendar-hebrew-month-name-array-common-year)) @@ -258,10 +257,11 @@ Reads a year, month, and day." (last (calendar-hebrew-last-day-of-month month year)) (first (if (and (= year 3761) (= month 10)) 18 1)) - (day (calendar-read - (format "Hebrew calendar day (%d-%d): " - first last) - (lambda (x) (and (<= first x) (<= x last)))))) + (day (calendar-read-sexp + "Hebrew calendar day (%d-%d)" + (lambda (x) (and (<= first x) (<= x last))) + nil + first last))) (list (list month day year)))) ;;;###cal-autoload @@ -681,10 +681,10 @@ from the cursor position." (if (equal (current-buffer) (get-buffer calendar-buffer)) (calendar-cursor-to-date t) (let* ((today (calendar-current-date)) - (year (calendar-read - "Year of death (>0): " + (year (calendar-read-sexp + "Year of death (>0)" (lambda (x) (> x 0)) - (number-to-string (calendar-extract-year today)))) + (calendar-extract-year today))) (month-array calendar-month-name-array) (completion-ignore-case t) (month (cdr (assoc-string @@ -694,20 +694,23 @@ from the cursor position." nil t) (calendar-make-alist month-array 1) t))) (last (calendar-last-day-of-month month year)) - (day (calendar-read - (format "Day of death (1-%d): " last) - (lambda (x) (and (< 0 x) (<= x last)))))) + (day (calendar-read-sexp + "Day of death (1-%d)" + (lambda (x) (and (< 0 x) (<= x last))) + nil + last))) (list month day year)))) (death-year (calendar-extract-year death-date)) - (start-year (calendar-read - (format "Starting year of Yahrzeit table (>%d): " - death-year) + (start-year (calendar-read-sexp + "Starting year of Yahrzeit table (>%d)" (lambda (x) (> x death-year)) - (number-to-string (1+ death-year)))) - (end-year (calendar-read - (format "Ending year of Yahrzeit table (>=%d): " - start-year) - (lambda (x) (>= x start-year))))) + (1+ death-year) + death-year)) + (end-year (calendar-read-sexp + "Ending year of Yahrzeit table (>=%d)" + (lambda (x) (>= x start-year)) + nil + start-year))) (list death-date start-year end-year))) (message "Computing Yahrzeits...") (let* ((h-date (calendar-hebrew-from-absolute diff --git a/lisp/calendar/cal-islam.el b/lisp/calendar/cal-islam.el index d256310ba6..4082ed43e5 100644 --- a/lisp/calendar/cal-islam.el +++ b/lisp/calendar/cal-islam.el @@ -143,13 +143,12 @@ Driven by the variable `calendar-date-display-form'." "Interactively read the arguments for an Islamic date command. Reads a year, month, and day." (let* ((today (calendar-current-date)) - (year (calendar-read - "Islamic calendar year (>0): " + (year (calendar-read-sexp + "Islamic calendar year (>0)" (lambda (x) (> x 0)) - (number-to-string - (calendar-extract-year - (calendar-islamic-from-absolute - (calendar-absolute-from-gregorian today)))))) + (calendar-extract-year + (calendar-islamic-from-absolute + (calendar-absolute-from-gregorian today))))) (month-array calendar-islamic-month-name-array) (completion-ignore-case t) (month (cdr (assoc-string @@ -159,9 +158,11 @@ Reads a year, month, and day." nil t) (calendar-make-alist month-array 1) t))) (last (calendar-islamic-last-day-of-month month year)) - (day (calendar-read - (format "Islamic calendar day (1-%d): " last) - (lambda (x) (and (< 0 x) (<= x last)))))) + (day (calendar-read-sexp + "Islamic calendar day (1-%d)" + (lambda (x) (and (< 0 x) (<= x last))) + nil + last))) (list (list month day year)))) ;;;###cal-autoload diff --git a/lisp/calendar/cal-iso.el b/lisp/calendar/cal-iso.el index 956433e4a2..a247b2d15a 100644 --- a/lisp/calendar/cal-iso.el +++ b/lisp/calendar/cal-iso.el @@ -92,22 +92,23 @@ date Sunday, December 31, 1 BC." "Interactively read the arguments for an ISO date command. Reads a year and week, and if DAYFLAG is non-nil a day (otherwise taken to be 1)." - (let* ((year (calendar-read - "ISO calendar year (>0): " + (let* ((year (calendar-read-sexp + "ISO calendar year (>0)" (lambda (x) (> x 0)) - (number-to-string (calendar-extract-year - (calendar-current-date))))) + (calendar-extract-year (calendar-current-date)))) (no-weeks (calendar-extract-month (calendar-iso-from-absolute (1- (calendar-dayname-on-or-before 1 (calendar-absolute-from-gregorian (list 1 4 (1+ year)))))))) - (week (calendar-read - (format "ISO calendar week (1-%d): " no-weeks) - (lambda (x) (and (> x 0) (<= x no-weeks))))) - (day (if dayflag (calendar-read - "ISO day (1-7): " + (week (calendar-read-sexp + "ISO calendar week (1-%d)" + (lambda (x) (and (> x 0) (<= x no-weeks))) + nil + no-weeks)) + (day (if dayflag (calendar-read-sexp + "ISO day (1-7)" (lambda (x) (and (<= 1 x) (<= x 7)))) 1))) (list (list week day year)))) diff --git a/lisp/calendar/cal-julian.el b/lisp/calendar/cal-julian.el index 235b4d0090..47880a4e97 100644 --- a/lisp/calendar/cal-julian.el +++ b/lisp/calendar/cal-julian.el @@ -95,14 +95,13 @@ Driven by the variable `calendar-date-display-form'." "Move cursor to Julian DATE; echo Julian date unless NOECHO is non-nil." (interactive (let* ((today (calendar-current-date)) - (year (calendar-read - "Julian calendar year (>0): " + (year (calendar-read-sexp + "Julian calendar year (>0)" (lambda (x) (> x 0)) - (number-to-string - (calendar-extract-year - (calendar-julian-from-absolute - (calendar-absolute-from-gregorian - today)))))) + (calendar-extract-year + (calendar-julian-from-absolute + (calendar-absolute-from-gregorian + today))))) (month-array calendar-month-name-array) (completion-ignore-case t) (month (cdr (assoc-string @@ -115,12 +114,13 @@ Driven by the variable `calendar-date-display-form'." (if (and (zerop (% year 4)) (= month 2)) 29 (aref [31 28 31 30 31 30 31 31 30 31 30 31] (1- month)))) - (day (calendar-read - (format "Julian calendar day (%d-%d): " - (if (and (= year 1) (= month 1)) 3 1) last) + (day (calendar-read-sexp + "Julian calendar day (%d-%d)" (lambda (x) (and (< (if (and (= year 1) (= month 1)) 2 0) x) - (<= x last)))))) + (<= x last))) + nil + (if (and (= year 1) (= month 1)) 3 1) last))) (list (list month day year)))) (calendar-goto-date (calendar-gregorian-from-absolute (calendar-julian-to-absolute date))) @@ -173,8 +173,8 @@ Defaults to today's date if DATE is not given." (defun calendar-astro-goto-day-number (daynumber &optional noecho) "Move cursor to astronomical (Julian) DAYNUMBER. Echo astronomical (Julian) day number unless NOECHO is non-nil." - (interactive (list (calendar-read - "Astronomical (Julian) day number (>1721425): " + (interactive (list (calendar-read-sexp + "Astronomical (Julian) day number (>1721425)" (lambda (x) (> x 1721425))))) (calendar-goto-date (calendar-gregorian-from-absolute diff --git a/lisp/calendar/cal-mayan.el b/lisp/calendar/cal-mayan.el index 8d894ebd98..e3533e7b1d 100644 --- a/lisp/calendar/cal-mayan.el +++ b/lisp/calendar/cal-mayan.el @@ -135,8 +135,8 @@ but some use 1137140. Using 1232041 gives you Spinden's correlation; using (defun calendar-mayan-read-haab-date () "Prompt for a Mayan haab date." (let* ((completion-ignore-case t) - (haab-day (calendar-read - "Haab kin (0-19): " + (haab-day (calendar-read-sexp + "Haab kin (0-19)" (lambda (x) (and (>= x 0) (< x 20))))) (haab-month-list (append calendar-mayan-haab-month-name-array (and (< haab-day 5) '("Uayeb")))) @@ -151,8 +151,8 @@ but some use 1137140. Using 1232041 gives you Spinden's correlation; using (defun calendar-mayan-read-tzolkin-date () "Prompt for a Mayan tzolkin date." (let* ((completion-ignore-case t) - (tzolkin-count (calendar-read - "Tzolkin kin (1-13): " + (tzolkin-count (calendar-read-sexp + "Tzolkin kin (1-13)" (lambda (x) (and (> x 0) (< x 14))))) (tzolkin-name-list (append calendar-mayan-tzolkin-names-array nil)) (tzolkin-name (cdr diff --git a/lisp/calendar/cal-move.el b/lisp/calendar/cal-move.el index 710ce37ccb..c2b5d618ea 100644 --- a/lisp/calendar/cal-move.el +++ b/lisp/calendar/cal-move.el @@ -386,15 +386,16 @@ Moves forward if ARG is negative." "Move cursor to YEAR, DAY number; echo DAY/YEAR unless NOECHO is non-nil. Negative DAY counts backward from end of year." (interactive - (let* ((year (calendar-read - "Year (>0): " + (let* ((year (calendar-read-sexp + "Year (>0)" (lambda (x) (> x 0)) - (number-to-string (calendar-extract-year - (calendar-current-date))))) + (calendar-extract-year (calendar-current-date)))) (last (if (calendar-leap-year-p year) 366 365)) - (day (calendar-read - (format "Day number (+/- 1-%d): " last) - (lambda (x) (and (<= 1 (abs x)) (<= (abs x) last)))))) + (day (calendar-read-sexp + "Day number (+/- 1-%d)" + (lambda (x) (and (<= 1 (abs x)) (<= (abs x) last))) + nil + last))) (list year day))) (calendar-goto-date (calendar-gregorian-from-absolute diff --git a/lisp/calendar/cal-persia.el b/lisp/calendar/cal-persia.el index a9c99fedbd..21085284ac 100644 --- a/lisp/calendar/cal-persia.el +++ b/lisp/calendar/cal-persia.el @@ -157,14 +157,13 @@ Gregorian date Sunday, December 31, 1 BC." (defun calendar-persian-read-date () "Interactively read the arguments for a Persian date command. Reads a year, month, and day." - (let* ((year (calendar-read - "Persian calendar year (not 0): " + (let* ((year (calendar-read-sexp + "Persian calendar year (not 0)" (lambda (x) (not (zerop x))) - (number-to-string - (calendar-extract-year - (calendar-persian-from-absolute - (calendar-absolute-from-gregorian - (calendar-current-date))))))) + (calendar-extract-year + (calendar-persian-from-absolute + (calendar-absolute-from-gregorian + (calendar-current-date)))))) (completion-ignore-case t) (month (cdr (assoc (completing-read @@ -175,9 +174,11 @@ Reads a year, month, and day." (calendar-make-alist calendar-persian-month-name-array 1)))) (last (calendar-persian-last-day-of-month month year)) - (day (calendar-read - (format "Persian calendar day (1-%d): " last) - (lambda (x) (and (< 0 x) (<= x last)))))) + (day (calendar-read-sexp + "Persian calendar day (1-%d)" + (lambda (x) (and (< 0 x) (<= x last))) + nil + last))) (list (list month day year)))) ;;;###cal-autoload diff --git a/lisp/calendar/diary-lib.el b/lisp/calendar/diary-lib.el index aad70161f9..4efa366996 100644 --- a/lisp/calendar/diary-lib.el +++ b/lisp/calendar/diary-lib.el @@ -2221,8 +2221,8 @@ Prefix argument ARG makes the entry nonmarking." (diary-make-entry (format "%s(diary-cyclic %d %s)" diary-sexp-entry-symbol - (calendar-read "Repeat every how many days: " - (lambda (x) (> x 0))) + (calendar-read-sexp "Repeat every how many days" + (lambda (x) (> x 0))) (calendar-date-string (calendar-cursor-to-date t) nil t)) arg))) diff --git a/lisp/calendar/holidays.el b/lisp/calendar/holidays.el index 932993beba..4bc17de306 100644 --- a/lisp/calendar/holidays.el +++ b/lisp/calendar/holidays.el @@ -423,16 +423,15 @@ of a holiday list. The optional LABEL is used to label the buffer created." (interactive - (let* ((start-year (calendar-read - "Starting year of holidays (>0): " + (let* ((start-year (calendar-read-sexp + "Starting year of holidays (>0)" (lambda (x) (> x 0)) - (number-to-string (calendar-extract-year - (calendar-current-date))))) - (end-year (calendar-read - (format "Ending year (inclusive) of holidays (>=%s): " - start-year) + (calendar-extract-year (calendar-current-date)))) + (end-year (calendar-read-sexp + "Ending year (inclusive) of holidays (>=%s)" (lambda (x) (>= x start-year)) - (number-to-string start-year))) + start-year + start-year)) (completion-ignore-case t) (lists (list commit 0f65baa03b54dc95b24b765bc91370354743a449 Author: Stefan Monnier Date: Wed Jan 20 23:08:25 2021 -0500 * lisp/calendar/cal-french.el (calendar-french-accents-p): Obsolete function Always assume accented letters can be used (calendar-french-month-name-array) (calendar-french-special-days-array): Use the accented names. (calendar-french-multibyte-month-name-array) (calendar-french-multibyte-special-days-array): Make those vars obsolete aliases. (calendar-french-month-name-array, calendar-french-day-name-array) (calendar-french-special-days-array): Mark functions as obsolete. (calendar-french-date-string, calendar-french-goto-date): Always use the text with accents. diff --git a/lisp/calendar/cal-french.el b/lisp/calendar/cal-french.el index e759b5dad9..c8ab6c41d8 100644 --- a/lisp/calendar/cal-french.el +++ b/lisp/calendar/cal-french.el @@ -35,54 +35,45 @@ (defconst calendar-french-epoch (calendar-absolute-from-gregorian '(9 22 1792)) "Absolute date of start of French Revolutionary calendar = Sept 22, 1792.") -(defconst calendar-french-month-name-array - ["Vende'miaire" "Brumaire" "Frimaire" "Nivo^se" "Pluvio^se" "Vento^se" - "Germinal" "Flore'al" "Prairial" "Messidor" "Thermidor" "Fructidor"] - "Array of month names in the French calendar.") +(define-obsolete-variable-alias 'calendar-french-multibyte-month-name-array + 'calendar-french-month-name-array "28.1") -(defconst calendar-french-multibyte-month-name-array +(defconst calendar-french-month-name-array ["Vendémiaire" "Brumaire" "Frimaire" "Nivôse" "Pluviôse" "Ventôse" "Germinal" "Floréal" "Prairial" "Messidor" "Thermidor" "Fructidor"] - "Array of multibyte month names in the French calendar.") + "Array of month names in the French calendar.") (defconst calendar-french-day-name-array ["Primidi" "Duodi" "Tridi" "Quartidi" "Quintidi" "Sextidi" "Septidi" "Octidi" "Nonidi" "Decadi"] "Array of day names in the French calendar.") -(defconst calendar-french-special-days-array - ["de la Vertu" "du Ge'nie" "du Travail" "de la Raison" "des Re'compenses" - "de la Re'volution"] - "Array of special day names in the French calendar.") +(define-obsolete-variable-alias 'calendar-french-multibyte-special-days-array + 'calendar-french-special-days-array "28.1") -(defconst calendar-french-multibyte-special-days-array +(defconst calendar-french-special-days-array ["de la Vertu" "du Génie" "du Travail" "de la Raison" "des Récompenses" "de la Révolution"] - "Array of multibyte special day names in the French calendar.") + "Array of special day names in the French calendar.") (defun calendar-french-accents-p () - "Return non-nil if diacritical marks are available." - (and (or window-system - (terminal-coding-system)) - (or enable-multibyte-characters - (and (char-table-p standard-display-table) - (equal (aref standard-display-table 161) [161]))))) + (declare (obsolete nil "28.1")) + t) (defun calendar-french-month-name-array () "Return the array of month names, depending on whether accents are available." - (if (calendar-french-accents-p) - calendar-french-multibyte-month-name-array - calendar-french-month-name-array)) + (declare (obsolete "use the variable of the same name instead" "28.1")) + calendar-french-month-name-array) (defun calendar-french-day-name-array () "Return the array of day names." + (declare (obsolete "use the variable of the same name instead" "28.1")) calendar-french-day-name-array) (defun calendar-french-special-days-array () "Return the special day names, depending on whether accents are available." - (if (calendar-french-accents-p) - calendar-french-multibyte-special-days-array - calendar-french-special-days-array)) + (declare (obsolete "use the variable of the same name instead" "28.1")) + calendar-french-special-days-array) (defun calendar-french-leap-year-p (year) "True if YEAR is a leap year on the French Revolutionary calendar. @@ -171,17 +162,13 @@ Defaults to today's date if DATE is not given." (d (calendar-extract-day french-date))) (cond ((< y 1) "") - ((= m 13) (format (if (calendar-french-accents-p) - "Jour %s de l'Année %d de la Révolution" - "Jour %s de l'Anne'e %d de la Re'volution") - (aref (calendar-french-special-days-array) (1- d)) + ((= m 13) (format "Jour %s de l'Année %d de la Révolution" + (aref calendar-french-special-days-array (1- d)) y)) (t (format - (if (calendar-french-accents-p) - "%d %s an %d de la Révolution" - "%d %s an %d de la Re'volution") + "%d %s an %d de la Révolution" d - (aref (calendar-french-month-name-array) (1- m)) + (aref calendar-french-month-name-array (1- m)) y))))) ;;;###cal-autoload @@ -198,13 +185,11 @@ Defaults to today's date if DATE is not given." "Move cursor to French Revolutionary date DATE. Echo French Revolutionary date unless NOECHO is non-nil." (interactive - (let* ((months (calendar-french-month-name-array)) - (special-days (calendar-french-special-days-array)) + (let* ((months calendar-french-month-name-array) + (special-days calendar-french-special-days-array) (year (progn (calendar-read - (if (calendar-french-accents-p) - "Année de la Révolution (>0): " - "Anne'e de la Re'volution (>0): ") + "Année de la Révolution (>0): " (lambda (x) (> x 0)) (number-to-string (calendar-extract-year commit d8a9828b3b7c5d80ecc57089e0c93c4dfa6837b7 Author: Stefan Monnier Date: Wed Jan 20 23:00:57 2021 -0500 * lisp/calendar/calendar.el (calendar-read-sexp): New function (calendar-read): Mark as obsolete. (calendar-read-date): Use it. Add `default-date` argument. Provide defaults for the month and day (fixes bug#32105). diff --git a/lisp/calendar/calendar.el b/lisp/calendar/calendar.el index 21cea212e1..3f9fe1c9d8 100644 --- a/lisp/calendar/calendar.el +++ b/lisp/calendar/calendar.el @@ -112,6 +112,8 @@ ;;; Code: +(eval-when-compile (require 'subr-x)) + (load "cal-loaddefs" nil t) ;; Calendar has historically relied heavily on dynamic scoping. @@ -1459,7 +1461,7 @@ Optional integers MON and YR are used instead of today's date." Inserts STRING so that it ends at INDENT. STRING is either a literal string, or a sexp to evaluate to return such. Truncates STRING to length TRUNCATE, and ensures a trailing space." - (if (not (ignore-errors (stringp (setq string (eval string))))) + (if (not (ignore-errors (stringp (setq string (eval string t))))) (calendar-move-to-column indent) (if (> (string-width string) truncate) (setq string (truncate-string-to-width string truncate))) @@ -1526,7 +1528,7 @@ first INDENT characters on the line." (format (format "%%%dd" calendar-day-digit-width) day) 'mouse-face 'highlight 'help-echo (calendar-dlet* ((day day) (month month) (year year)) - (eval calendar-date-echo-text)) + (eval calendar-date-echo-text t)) ;; 'date property prevents intermonth text confusing re-searches. ;; (Tried intangible, it did not really work.) 'date t) @@ -2054,23 +2056,40 @@ With argument ARG, jump to mark, pop it, and put point at end of ring." (error "%s not available in the calendar" (global-key-binding (this-command-keys)))) +(defun calendar-read-sexp (prompt predicate &optional default &rest args) + "Return an object read from the minibuffer. +Passes PROMPT, DEFAULT, and ARGS to `format-prompt' to build +the actual prompt. PREDICATE is called with a single value (the object +the user entered) and it should return non-nil if that value is a valid choice. +DEFAULT is the default value to use." + (unless (stringp default) (setq default (format "%S" default))) + (named-let query () + ;; The call to `read-from-minibuffer' is copied from `read-minibuffer', + ;; except it's changed to use the DEFAULT arg instead of INITIAL-CONTENTS. + (let ((value (read-from-minibuffer + (apply #'format-prompt prompt default args) + nil minibuffer-local-map t 'minibuffer-history default))) + (if (funcall predicate value) + value + (query))))) + (defun calendar-read (prompt acceptable &optional initial-contents) "Return an object read from the minibuffer. Prompt with the string PROMPT and use the function ACCEPTABLE to decide if entered item is acceptable. If non-nil, optional third arg INITIAL-CONTENTS is a string to insert in the minibuffer before reading." + (declare (obsolete calendar-read-sexp "28.1")) (let ((value (read-minibuffer prompt initial-contents))) (while (not (funcall acceptable value)) (setq value (read-minibuffer prompt initial-contents))) value)) - (defun calendar-customized-p (symbol) "Return non-nil if SYMBOL has been customized." (and (default-boundp symbol) (let ((standard (get symbol 'standard-value))) (and standard - (not (equal (eval (car standard)) (default-value symbol))))))) + (not (equal (eval (car standard) t) (default-value symbol))))))) (defun calendar-abbrev-construct (full &optional maxlen) "From sequence FULL, return a vector of abbreviations. @@ -2284,32 +2303,38 @@ arguments SEQUENCES." (append (list sequence) sequences)) (reverse alist))) -(defun calendar-read-date (&optional noday) +(defun calendar-read-date (&optional noday default-date) "Prompt for Gregorian date. Return a list (month day year). If optional NODAY is t, does not ask for day, but just returns \(month 1 year); if NODAY is any other non-nil value the value returned is (month year)." - (let* ((year (calendar-read - "Year (>0): " - (lambda (x) (> x 0)) - (number-to-string (calendar-extract-year - (calendar-current-date))))) + (unless default-date (setq default-date (calendar-current-date))) + (let* ((defyear (calendar-extract-year default-date)) + (year (calendar-read-sexp "Year (>0)" + (lambda (x) (> x 0)) + defyear)) (month-array calendar-month-name-array) + (defmon (aref month-array (1- (calendar-extract-month default-date)))) (completion-ignore-case t) (month (cdr (assoc-string - (completing-read - "Month name: " - (mapcar #'list (append month-array nil)) - nil t) + (completing-read + (format-prompt "Month name" defmon) + (append month-array nil) + nil t nil nil defmon) (calendar-make-alist month-array 1) t))) + (defday (calendar-extract-day default-date)) (last (calendar-last-day-of-month month year))) (if noday (if (eq noday t) (list month 1 year) (list month year)) (list month - (calendar-read (format "Day (1-%d): " last) - (lambda (x) (and (< 0 x) (<= x last)))) + (calendar-read-sexp "Day (1-%d)" + (lambda (x) (and (< 0 x) (<= x last))) + ;; Don't offer today's day as default + ;; if it's not valid for the chosen + ;; month/year. + (if (<= defday last) defday) last) year)))) (defun calendar-interval (mon1 yr1 mon2 yr2) commit b9511362f5fe4dc772cb2b65afeb051a7443f2a4 Author: Stefan Monnier Date: Wed Jan 20 20:17:11 2021 -0500 * lisp/emacs-lisp/bytecomp.el (byte-compile--declare-var): Fix warning Make sure the "declared after first use" is under the control of the `lexical` option. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 360da6b6ba..9429d6a0d5 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2505,7 +2505,8 @@ list that represents a doc string reference. (when (memq sym byte-compile-lexical-variables) (setq byte-compile-lexical-variables (delq sym byte-compile-lexical-variables)) - (byte-compile-warn "Variable `%S' declared after its first use" sym)) + (when (byte-compile-warning-enabled-p 'lexical sym) + (byte-compile-warn "Variable `%S' declared after its first use" sym))) (push sym byte-compile-bound-variables) (push sym byte-compile--seen-defvars)) commit 0df23b73e4718937bcaddf9008ad8ef9ca3a2413 Author: Lars Ingebrigtsen Date: Wed Jan 20 23:30:53 2021 +0100 Fix recent remember-diary-extract-entries change * lisp/textmodes/remember.el (remember-diary-extract-entries): Use `remember-diary-file' over `diary-file'. diff --git a/lisp/textmodes/remember.el b/lisp/textmodes/remember.el index 7f107977d5..811a265118 100644 --- a/lisp/textmodes/remember.el +++ b/lisp/textmodes/remember.el @@ -549,6 +549,8 @@ If this is nil, then `diary-file' will be used instead." :type 'regexp :version "28.1") +(defvar diary-file) + ;;;###autoload (defun remember-diary-extract-entries () "Extract diary entries from the region based on `remember-diary-regexp'." @@ -561,7 +563,8 @@ If this is nil, then `diary-file' will be used instead." (diary-make-entry (mapconcat 'identity list "\n") nil remember-diary-file) (when remember-save-after-remembering - (with-current-buffer (find-buffer-visiting diary-file) + (with-current-buffer (find-buffer-visiting (or remember-diary-file + diary-file)) (save-buffer)))) nil))) ;; Continue processing commit 61b716bd3034ac50829ef66399c14113a903f82a Author: Lars Ingebrigtsen Date: Wed Jan 20 22:15:38 2021 +0100 checkdoc-spellcheck-documentation-flag doc string improvement * lisp/emacs-lisp/checkdoc.el (checkdoc-spellcheck-documentation-flag): Mention `ispell-kill-ispell' (bug#6221). diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index 2e204ff7ae..76638ec13b 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -241,7 +241,12 @@ system. Possible values are: defun - Spell-check when style checking a single defun. buffer - Spell-check when style checking the whole buffer. interactive - Spell-check during any interactive check. - t - Always spell-check." + t - Always spell-check. + +There is a list of Lisp-specific words which checkdoc will +install into Ispell on the fly, but only if Ispell is not already +running. Use `ispell-kill-ispell' to make checkdoc restart it +with these words enabled." :type '(choice (const nil) (const defun) (const buffer) commit 1a6ed932d9d9779419f403e32e911f86657cb9f7 Author: Lars Ingebrigtsen Date: Wed Jan 20 22:11:38 2021 +0100 Revert "Always send Lisp words to checkdoc-ispell-init" This reverts commit 93141d581330d94e7eec9f114def2bec15f87866. This would make checkdoc words be used in other flyspell buffers. diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index aae807b8c1..2e204ff7ae 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -2106,14 +2106,12 @@ nil." (unless ispell-process (condition-case nil (progn - ;; Initialize variables and dict alists. - (ispell-set-spellchecker-params) - ;; Use the correct dictionary. - (ispell-accept-buffer-local-defs)) - (error (setq checkdoc-spellcheck-documentation-flag nil)))) - ;; This code copied in part from ispell.el Emacs 19.34 - (dolist (w checkdoc-ispell-lisp-words) - (process-send-string ispell-process (concat "@" w "\n")))) + (ispell-set-spellchecker-params) ; Initialize variables and dict alists. + (ispell-accept-buffer-local-defs) ; Use the correct dictionary. + ;; This code copied in part from ispell.el Emacs 19.34 + (dolist (w checkdoc-ispell-lisp-words) + (process-send-string ispell-process (concat "@" w "\n")))) + (error (setq checkdoc-spellcheck-documentation-flag nil))))) (defun checkdoc-ispell-docstring-engine (end &optional take-notes) "Run the Ispell tools on the doc string between point and END. commit 93141d581330d94e7eec9f114def2bec15f87866 Author: Lars Ingebrigtsen Date: Wed Jan 20 21:46:30 2021 +0100 Always send Lisp words to checkdoc-ispell-init * lisp/emacs-lisp/checkdoc.el (checkdoc-ispell-init): Always send the Lisp words to the process (bug#6221). This allows an existing ispell process to be correctly initialised. diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index 2e204ff7ae..aae807b8c1 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -2106,12 +2106,14 @@ nil." (unless ispell-process (condition-case nil (progn - (ispell-set-spellchecker-params) ; Initialize variables and dict alists. - (ispell-accept-buffer-local-defs) ; Use the correct dictionary. - ;; This code copied in part from ispell.el Emacs 19.34 - (dolist (w checkdoc-ispell-lisp-words) - (process-send-string ispell-process (concat "@" w "\n")))) - (error (setq checkdoc-spellcheck-documentation-flag nil))))) + ;; Initialize variables and dict alists. + (ispell-set-spellchecker-params) + ;; Use the correct dictionary. + (ispell-accept-buffer-local-defs)) + (error (setq checkdoc-spellcheck-documentation-flag nil)))) + ;; This code copied in part from ispell.el Emacs 19.34 + (dolist (w checkdoc-ispell-lisp-words) + (process-send-string ispell-process (concat "@" w "\n")))) (defun checkdoc-ispell-docstring-engine (end &optional take-notes) "Run the Ispell tools on the doc string between point and END. commit 5065698c81dcf241fc234c78bffea54af4203892 Author: Juri Linkov Date: Wed Jan 20 21:19:23 2021 +0200 Move the ‘declare’ form before the interactive spec in 10 functions. * lisp/emacs-lisp/package.el (package-menu-hide-package): * lisp/font-lock.el (font-lock-debug-fontify): * lisp/image.el (image-jpeg-p): * lisp/mail/flow-fill.el (fill-flowed-test): * lisp/mh-e/mh-speed.el (mh-speed-toggle, mh-speed-view): * lisp/progmodes/project.el (project-async-shell-command) (project-shell-command, project-compile): * lisp/progmodes/sh-script.el (sh-assignment): Fix special forms to follow in this order: docstring, declare, interactive. diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 453e86c783..90b7b88d58 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -3260,9 +3260,9 @@ To unhide a package, type `\\[customize-variable] RET package-hidden-regexps'. Type \\[package-menu-toggle-hiding] to toggle package hiding." + (declare (interactive-only "change `package-hidden-regexps' instead.")) (interactive) (package--ensure-package-menu-mode) - (declare (interactive-only "change `package-hidden-regexps' instead.")) (let* ((name (when (derived-mode-p 'package-menu-mode) (concat "\\`" (regexp-quote (symbol-name (package-desc-name (tabulated-list-get-id)))) diff --git a/lisp/font-lock.el b/lisp/font-lock.el index a51434c38c..a9fc69d419 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -1104,8 +1104,8 @@ Called with two arguments BEG and END.") "Reinitialize the font-lock machinery and (re-)fontify the buffer. This functions is a convenience functions when developing font locking for a mode, and is not meant to be called from lisp functions." - (interactive) (declare (interactive-only t)) + (interactive) ;; Make font-lock recalculate all the mode-specific data. (setq font-lock-major-mode nil) ;; Make the syntax machinery discard all information. diff --git a/lisp/image.el b/lisp/image.el index 814035594b..6955a90de7 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -264,9 +264,9 @@ compatibility with versions of Emacs that lack the variable ;; Used to be in image-type-header-regexps, but now not used anywhere ;; (since 2009-08-28). (defun image-jpeg-p (data) - (declare (obsolete "It is unused inside Emacs and will be removed." "27.1")) "Value is non-nil if DATA, a string, consists of JFIF image data. We accept the tag Exif because that is the same format." + (declare (obsolete "It is unused inside Emacs and will be removed." "27.1")) (setq data (ignore-errors (string-to-unibyte data))) (when (and data (string-match-p "\\`\xff\xd8" data)) (catch 'jfif diff --git a/lisp/mail/flow-fill.el b/lisp/mail/flow-fill.el index e93ba547a8..0fab1b21b4 100644 --- a/lisp/mail/flow-fill.el +++ b/lisp/mail/flow-fill.el @@ -174,8 +174,8 @@ lines." (defvar fill-flowed-encode-tests) (defun fill-flowed-test () - (interactive "") (declare (obsolete nil "27.1")) + (interactive "") (user-error (concat "This function is obsolete. Please see " "test/lisp/mail/flow-fill-tests.el " "in the Emacs source tree"))) diff --git a/lisp/mh-e/mh-speed.el b/lisp/mh-e/mh-speed.el index 35d5884b16..00b9680417 100644 --- a/lisp/mh-e/mh-speed.el +++ b/lisp/mh-e/mh-speed.el @@ -128,8 +128,8 @@ With non-nil FORCE, the update is always carried out." (defun mh-speed-toggle (&rest ignored) "Toggle the display of child folders in the speedbar. The optional arguments from speedbar are IGNORED." - (interactive) (declare (ignore args)) + (interactive) (beginning-of-line) (let ((parent (get-text-property (point) 'mh-folder)) (kids-p (get-text-property (point) 'mh-children-p)) @@ -167,8 +167,8 @@ The optional arguments from speedbar are IGNORED." (defun mh-speed-view (&rest ignored) "Visits the selected folder just as if you had used \\\\[mh-visit-folder]. The optional arguments from speedbar are IGNORED." - (interactive) (declare (ignore args)) + (interactive) (let* ((folder (get-text-property (mh-line-beginning-position) 'mh-folder)) (range (and (stringp folder) (mh-read-range "Scan" folder t nil nil diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 18124227d1..768cd58ae4 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -928,16 +928,16 @@ if one already exists." ;;;###autoload (defun project-async-shell-command () "Run `async-shell-command' in the current project's root directory." - (interactive) (declare (interactive-only async-shell-command)) + (interactive) (let ((default-directory (project-root (project-current t)))) (call-interactively #'async-shell-command))) ;;;###autoload (defun project-shell-command () "Run `shell-command' in the current project's root directory." - (interactive) (declare (interactive-only shell-command)) + (interactive) (let ((default-directory (project-root (project-current t)))) (call-interactively #'shell-command))) @@ -974,8 +974,8 @@ loop using the command \\[fileloop-continue]." ;;;###autoload (defun project-compile () "Run `compile' in the project root." - (interactive) (declare (interactive-only compile)) + (interactive) (let ((default-directory (project-root (project-current t)))) (call-interactively #'compile))) diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index d3692d4720..cc045a1b2d 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -2927,8 +2927,8 @@ option followed by a colon `:' if the option accepts an argument." (put 'sh-assignment 'delete-selection t) (defun sh-assignment (arg) "Remember preceding identifier for future completion and do self-insert." - (interactive "p") (declare (obsolete nil "27.1")) + (interactive "p") (self-insert-command arg) (sh--assignment-collect)) commit 0d3635536d4ed8ada6946e98e7d9f03fa443bc36 Author: Stefan Monnier Date: Wed Jan 20 14:12:50 2021 -0500 * lisp/emacs-lisp/subr-x.el (named-let): New macro diff --git a/etc/NEWS b/etc/NEWS index c8cbce1882..59b13998cf 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1554,6 +1554,13 @@ buttons in it. This function takes a string and returns a string propertized in a way that makes it a valid button. +** subr-x ++++ +*** A number of new string manipulation functions have been added. +'string-clean-whitespace', 'string-fill', 'string-limit', +'string-lines', 'string-pad' and 'string-chop-newline'. + +*** New macro `named-let` that provides Scheme's "named let" looping construct ** Miscellaneous @@ -1593,11 +1600,6 @@ length to a number). *** New user option 'authinfo-hide-elements'. This can be set to nil to inhibit hiding passwords in ".authinfo" files. -+++ -*** A number of new string manipulation functions have been added. -'string-clean-whitespace', 'string-fill', 'string-limit', -'string-lines', 'string-pad' and 'string-chop-newline'. - +++ *** New variable 'current-minibuffer-command'. This is like 'this-command', but it is bound recursively when entering diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index b90227da42..a4514454c0 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -389,6 +389,28 @@ it makes no sense to convert it to a string using (set-buffer source-buffer) (replace-buffer-contents tmp-buffer max-secs max-costs))))))))) +(defmacro named-let (name bindings &rest body) + "Looping construct taken from Scheme. +Like `let', bind variables in BINDINGS and then evaluate BODY, +but with the twist that BODY can evaluate itself recursively by +calling NAME, where the arguments passed to NAME are used +as the new values of the bound variables in the recursive invocation." + (declare (indent 2) (debug (symbolp (&rest (symbolp form)) body))) + (require 'cl-lib) + (let ((fargs (mapcar (lambda (b) (if (consp b) (car b) b)) bindings)) + (aargs (mapcar (lambda (b) (if (consp b) (cadr b))) bindings))) + ;; According to the Scheme semantics of named let, `name' is not in scope + ;; while evaluating the expressions in `bindings', and for this reason, the + ;; "initial" function call below needs to be outside of the `cl-labels'. + ;; When the "self-tco" eliminates all recursive calls, the `cl-labels' + ;; expands to a lambda which the byte-compiler then combines with the + ;; funcall to make a `let' so we end up with a plain `while' loop and no + ;; remaining `lambda' at all. + `(funcall + (cl-labels ((,name ,fargs . ,body)) #',name) + . ,aargs))) + + (provide 'subr-x) ;;; subr-x.el ends here commit 66439d31ad2a63753d29e4582b76b36b9363d96b Author: Stefan Monnier Date: Wed Jan 20 14:08:35 2021 -0500 * lisp/emacs-lisp/byte-opt.el (byte-optimize-lapcode): Add 2 new opts This introduces two new optimizations. They're designed for code like (while (let (...) (if ... (progn blabla t) (progn blabla nil))) ...) and they allow the elimination of the test internal to `while` since we can immediately know when we return `t` or `nil` what the result of the test will be. `cl-labels` tends to generate this kind of code when it applies the tail-call optimization. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 620bd91b64..cfa407019a 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -2056,6 +2056,7 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance." (setcdr (cdr rest) tmp) (byte-compile-log-lap " %s [discard/discardN]...\t-->\t%s" lap0 lap1)) + ;; ;; discardN-preserve-tos return --> return ;; dup return --> return @@ -2071,6 +2072,36 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance." (setq lap (delq lap0 lap)) (byte-compile-log-lap " %s %s\t-->\t%s" lap0 lap1 lap1)) + ;; + ;; goto-X ... X: discard ==> discard goto-Y ... X: discard Y: + ;; + ((and (eq (car lap0) 'byte-goto) + (setq tmp (cdr (memq (cdr lap0) lap))) + (memq (caar tmp) '(byte-discard byte-discardN + byte-discardN-preserve-tos))) + (byte-compile-log-lap + " goto-X .. X: \t-->\t%s goto-X.. X: %s Y:" + (car tmp) (car tmp)) + (setq keep-going t) + (let* ((newtag (byte-compile-make-tag)) + ;; Make a copy, since we sometimes modify insts in-place! + (newdiscard (cons (caar tmp) (cdar tmp))) + (newjmp (cons (car lap0) newtag))) + (push newtag (cdr tmp)) ;Push new tag after the discard. + (setcar rest newdiscard) + (push newjmp (cdr rest)))) + + ;; + ;; const discardN-preserve-tos ==> discardN const + ;; + ((and (eq (car lap0) 'byte-constant) + (eq (car lap1) 'byte-discardN-preserve-tos)) + (setq keep-going t) + (let ((newdiscard (cons 'byte-discardN (cdr lap1)))) + (byte-compile-log-lap + " %s %s\t-->\t%s %s" lap0 lap1 newdiscard lap0) + (setf (car rest) newdiscard) + (setf (cadr rest) lap0))) ) (setq rest (cdr rest))) ) commit 4dfebf25c743d4ba4506919b58591f74debfb334 Author: Stefan Monnier Date: Wed Jan 20 13:59:58 2021 -0500 * lisp/emacs-lisp/byte-opt.el (byte-optimize-lapcode): Move some opts. This moves two optimizations from the final pass to the main loop. Both may enable further optimizations (and the second can be applied repeatedly but "from the end", so the loop in the final pass only gets to apply it once). diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 6d1f4179ce..620bd91b64 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -2021,6 +2021,56 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance." byte-goto byte-goto)))) ) (setq keep-going t)) + + ;; + ;; stack-set-M [discard/discardN ...] --> discardN-preserve-tos + ;; stack-set-M [discard/discardN ...] --> discardN + ;; + ((and (eq (car lap0) 'byte-stack-set) + (memq (car lap1) '(byte-discard byte-discardN)) + (progn + ;; See if enough discard operations follow to expose or + ;; destroy the value stored by the stack-set. + (setq tmp (cdr rest)) + (setq tmp2 (1- (cdr lap0))) + (setq tmp3 0) + (while (memq (car (car tmp)) '(byte-discard byte-discardN)) + (setq tmp3 + (+ tmp3 (if (eq (car (car tmp)) 'byte-discard) + 1 + (cdr (car tmp))))) + (setq tmp (cdr tmp))) + (>= tmp3 tmp2))) + ;; Do the optimization. + (setq lap (delq lap0 lap)) + (setcar lap1 + (if (= tmp2 tmp3) + ;; The value stored is the new TOS, so pop one more + ;; value (to get rid of the old value) using the + ;; TOS-preserving discard operator. + 'byte-discardN-preserve-tos + ;; Otherwise, the value stored is lost, so just use a + ;; normal discard. + 'byte-discardN)) + (setcdr lap1 (1+ tmp3)) + (setcdr (cdr rest) tmp) + (byte-compile-log-lap " %s [discard/discardN]...\t-->\t%s" + lap0 lap1)) + ;; + ;; discardN-preserve-tos return --> return + ;; dup return --> return + ;; stack-set-N return --> return ; where N is TOS-1 + ;; + ((and (eq (car lap1) 'byte-return) + (or (memq (car lap0) '(byte-discardN-preserve-tos byte-dup)) + (and (eq (car lap0) 'byte-stack-set) + (= (cdr lap0) 1)))) + (setq keep-going t) + ;; The byte-code interpreter will pop the stack for us, so + ;; we can just leave stuff on it. + (setq lap (delq lap0 lap)) + (byte-compile-log-lap " %s %s\t-->\t%s" lap0 lap1 lap1)) + ) (setq rest (cdr rest))) ) @@ -2084,41 +2134,6 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance." (setq lap (delq lap0 lap)) (setcdr lap1 (+ (cdr lap1) (cdr lap0)))) - ;; - ;; stack-set-M [discard/discardN ...] --> discardN-preserve-tos - ;; stack-set-M [discard/discardN ...] --> discardN - ;; - ((and (eq (car lap0) 'byte-stack-set) - (memq (car lap1) '(byte-discard byte-discardN)) - (progn - ;; See if enough discard operations follow to expose or - ;; destroy the value stored by the stack-set. - (setq tmp (cdr rest)) - (setq tmp2 (1- (cdr lap0))) - (setq tmp3 0) - (while (memq (car (car tmp)) '(byte-discard byte-discardN)) - (setq tmp3 - (+ tmp3 (if (eq (car (car tmp)) 'byte-discard) - 1 - (cdr (car tmp))))) - (setq tmp (cdr tmp))) - (>= tmp3 tmp2))) - ;; Do the optimization. - (setq lap (delq lap0 lap)) - (setcar lap1 - (if (= tmp2 tmp3) - ;; The value stored is the new TOS, so pop one more - ;; value (to get rid of the old value) using the - ;; TOS-preserving discard operator. - 'byte-discardN-preserve-tos - ;; Otherwise, the value stored is lost, so just use a - ;; normal discard. - 'byte-discardN)) - (setcdr lap1 (1+ tmp3)) - (setcdr (cdr rest) tmp) - (byte-compile-log-lap " %s [discard/discardN]...\t-->\t%s" - lap0 lap1)) - ;; ;; discard/discardN/discardN-preserve-tos-X discard/discardN-Y --> ;; discardN-(X+Y) @@ -2146,20 +2161,6 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance." (setq lap (delq lap0 lap)) (setcdr lap1 (+ (cdr lap0) (cdr lap1))) (byte-compile-log-lap " %s %s\t-->\t%s" lap0 lap1 (car rest))) - - ;; - ;; discardN-preserve-tos return --> return - ;; dup return --> return - ;; stack-set-N return --> return ; where N is TOS-1 - ;; - ((and (eq (car lap1) 'byte-return) - (or (memq (car lap0) '(byte-discardN-preserve-tos byte-dup)) - (and (eq (car lap0) 'byte-stack-set) - (= (cdr lap0) 1)))) - ;; The byte-code interpreter will pop the stack for us, so - ;; we can just leave stuff on it. - (setq lap (delq lap0 lap)) - (byte-compile-log-lap " %s %s\t-->\t%s" lap0 lap1 lap1)) ) (setq rest (cdr rest))) (setq byte-compile-maxdepth (+ byte-compile-maxdepth add-depth))) commit 09bfb12edc57ace138090861e335366d8f1cc4b2 Author: Stefan Monnier Date: Wed Jan 20 13:54:11 2021 -0500 * lisp/emacs-lisp/byte-opt.el (byte-optimize-lapcode): Re-indent diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index f29f85b965..6d1f4179ce 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -1561,467 +1561,467 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance." ;; You may notice that sequences like "dup varset discard" are ;; optimized but sequences like "dup varset TAG1: discard" are not. ;; You may be tempted to change this; resist that temptation. - (cond ;; - ;; pop --> - ;; ...including: - ;; const-X pop --> - ;; varref-X pop --> - ;; dup pop --> - ;; - ((and (eq 'byte-discard (car lap1)) - (memq (car lap0) side-effect-free)) - (setq keep-going t) - (setq tmp (aref byte-stack+-info (symbol-value (car lap0)))) - (setq rest (cdr rest)) - (cond ((= tmp 1) - (byte-compile-log-lap - " %s discard\t-->\t" lap0) - (setq lap (delq lap0 (delq lap1 lap)))) - ((= tmp 0) - (byte-compile-log-lap - " %s discard\t-->\t discard" lap0) - (setq lap (delq lap0 lap))) - ((= tmp -1) - (byte-compile-log-lap - " %s discard\t-->\tdiscard discard" lap0) - (setcar lap0 'byte-discard) - (setcdr lap0 0)) - ((error "Optimizer error: too much on the stack")))) - ;; - ;; goto*-X X: --> X: - ;; - ((and (memq (car lap0) byte-goto-ops) - (eq (cdr lap0) lap1)) - (cond ((eq (car lap0) 'byte-goto) - (setq lap (delq lap0 lap)) - (setq tmp "")) - ((memq (car lap0) byte-goto-always-pop-ops) - (setcar lap0 (setq tmp 'byte-discard)) - (setcdr lap0 0)) - ((error "Depth conflict at tag %d" (nth 2 lap0)))) - (and (memq byte-optimize-log '(t byte)) - (byte-compile-log " (goto %s) %s:\t-->\t%s %s:" - (nth 1 lap1) (nth 1 lap1) - tmp (nth 1 lap1))) - (setq keep-going t)) - ;; - ;; varset-X varref-X --> dup varset-X - ;; varbind-X varref-X --> dup varbind-X - ;; const/dup varset-X varref-X --> const/dup varset-X const/dup - ;; const/dup varbind-X varref-X --> const/dup varbind-X const/dup - ;; The latter two can enable other optimizations. - ;; - ;; For lexical variables, we could do the same - ;; stack-set-X+1 stack-ref-X --> dup stack-set-X+2 - ;; but this is a very minor gain, since dup is stack-ref-0, - ;; i.e. it's only better if X>5, and even then it comes - ;; at the cost of an extra stack slot. Let's not bother. - ((and (eq 'byte-varref (car lap2)) - (eq (cdr lap1) (cdr lap2)) - (memq (car lap1) '(byte-varset byte-varbind))) - (if (and (setq tmp (memq (car (cdr lap2)) byte-boolean-vars)) - (not (eq (car lap0) 'byte-constant))) - nil - (setq keep-going t) - (if (memq (car lap0) '(byte-constant byte-dup)) - (progn - (setq tmp (if (or (not tmp) - (macroexp--const-symbol-p - (car (cdr lap0)))) - (cdr lap0) - (byte-compile-get-constant t))) - (byte-compile-log-lap " %s %s %s\t-->\t%s %s %s" - lap0 lap1 lap2 lap0 lap1 - (cons (car lap0) tmp)) - (setcar lap2 (car lap0)) - (setcdr lap2 tmp)) - (byte-compile-log-lap " %s %s\t-->\tdup %s" lap1 lap2 lap1) - (setcar lap2 (car lap1)) - (setcar lap1 'byte-dup) - (setcdr lap1 0) - ;; The stack depth gets locally increased, so we will - ;; increase maxdepth in case depth = maxdepth here. - ;; This can cause the third argument to byte-code to - ;; be larger than necessary. - (setq add-depth 1)))) - ;; - ;; dup varset-X discard --> varset-X - ;; dup varbind-X discard --> varbind-X - ;; dup stack-set-X discard --> stack-set-X-1 - ;; (the varbind variant can emerge from other optimizations) - ;; - ((and (eq 'byte-dup (car lap0)) - (eq 'byte-discard (car lap2)) - (memq (car lap1) '(byte-varset byte-varbind - byte-stack-set))) - (byte-compile-log-lap " dup %s discard\t-->\t%s" lap1 lap1) - (setq keep-going t - rest (cdr rest)) - (if (eq 'byte-stack-set (car lap1)) (cl-decf (cdr lap1))) - (setq lap (delq lap0 (delq lap2 lap)))) - ;; - ;; not goto-X-if-nil --> goto-X-if-non-nil - ;; not goto-X-if-non-nil --> goto-X-if-nil - ;; - ;; it is wrong to do the same thing for the -else-pop variants. - ;; - ((and (eq 'byte-not (car lap0)) - (memq (car lap1) '(byte-goto-if-nil byte-goto-if-not-nil))) - (byte-compile-log-lap " not %s\t-->\t%s" - lap1 - (cons - (if (eq (car lap1) 'byte-goto-if-nil) - 'byte-goto-if-not-nil - 'byte-goto-if-nil) - (cdr lap1))) - (setcar lap1 (if (eq (car lap1) 'byte-goto-if-nil) - 'byte-goto-if-not-nil - 'byte-goto-if-nil)) - (setq lap (delq lap0 lap)) - (setq keep-going t)) - ;; - ;; goto-X-if-nil goto-Y X: --> goto-Y-if-non-nil X: - ;; goto-X-if-non-nil goto-Y X: --> goto-Y-if-nil X: - ;; - ;; it is wrong to do the same thing for the -else-pop variants. - ;; - ((and (memq (car lap0) - '(byte-goto-if-nil byte-goto-if-not-nil)) ; gotoX - (eq 'byte-goto (car lap1)) ; gotoY - (eq (cdr lap0) lap2)) ; TAG X - (let ((inverse (if (eq 'byte-goto-if-nil (car lap0)) - 'byte-goto-if-not-nil 'byte-goto-if-nil))) - (byte-compile-log-lap " %s %s %s:\t-->\t%s %s:" - lap0 lap1 lap2 - (cons inverse (cdr lap1)) lap2) - (setq lap (delq lap0 lap)) - (setcar lap1 inverse) - (setq keep-going t))) - ;; - ;; const goto-if-* --> whatever - ;; - ((and (eq 'byte-constant (car lap0)) - (memq (car lap1) byte-conditional-ops) - ;; If the `byte-constant's cdr is not a cons cell, it has - ;; to be an index into the constant pool); even though - ;; it'll be a constant, that constant is not known yet - ;; (it's typically a free variable of a closure, so will - ;; only be known when the closure will be built at - ;; run-time). - (consp (cdr lap0))) - (cond ((if (memq (car lap1) '(byte-goto-if-nil - byte-goto-if-nil-else-pop)) - (car (cdr lap0)) - (not (car (cdr lap0)))) - (byte-compile-log-lap " %s %s\t-->\t" - lap0 lap1) - (setq rest (cdr rest) - lap (delq lap0 (delq lap1 lap)))) - (t - (byte-compile-log-lap " %s %s\t-->\t%s" - lap0 lap1 - (cons 'byte-goto (cdr lap1))) - (when (memq (car lap1) byte-goto-always-pop-ops) - (setq lap (delq lap0 lap))) - (setcar lap1 'byte-goto))) - (setq keep-going t)) - ;; - ;; varref-X varref-X --> varref-X dup - ;; varref-X [dup ...] varref-X --> varref-X [dup ...] dup - ;; stackref-X [dup ...] stackref-X+N --> stackref-X [dup ...] dup - ;; We don't optimize the const-X variations on this here, - ;; because that would inhibit some goto optimizations; we - ;; optimize the const-X case after all other optimizations. - ;; - ((and (memq (car lap0) '(byte-varref byte-stack-ref)) - (progn - (setq tmp (cdr rest)) - (setq tmp2 0) - (while (eq (car (car tmp)) 'byte-dup) - (setq tmp2 (1+ tmp2)) - (setq tmp (cdr tmp))) - t) - (eq (if (eq 'byte-stack-ref (car lap0)) - (+ tmp2 1 (cdr lap0)) - (cdr lap0)) - (cdr (car tmp))) - (eq (car lap0) (car (car tmp)))) - (if (memq byte-optimize-log '(t byte)) - (let ((str "")) - (setq tmp2 (cdr rest)) - (while (not (eq tmp tmp2)) - (setq tmp2 (cdr tmp2) - str (concat str " dup"))) - (byte-compile-log-lap " %s%s %s\t-->\t%s%s dup" - lap0 str lap0 lap0 str))) - (setq keep-going t) - (setcar (car tmp) 'byte-dup) - (setcdr (car tmp) 0) - (setq rest tmp)) - ;; - ;; TAG1: TAG2: --> TAG1: - ;; (and other references to TAG2 are replaced with TAG1) - ;; - ((and (eq (car lap0) 'TAG) - (eq (car lap1) 'TAG)) - (and (memq byte-optimize-log '(t byte)) - (byte-compile-log " adjacent tags %d and %d merged" - (nth 1 lap1) (nth 1 lap0))) - (setq tmp3 lap) - (while (setq tmp2 (rassq lap0 tmp3)) - (setcdr tmp2 lap1) - (setq tmp3 (cdr (memq tmp2 tmp3)))) - (setq lap (delq lap0 lap) - keep-going t) - ;; replace references to tag in jump tables, if any - (dolist (table byte-compile-jump-tables) - (maphash #'(lambda (value tag) - (when (equal tag lap0) - (puthash value lap1 table))) - table))) - ;; - ;; unused-TAG: --> - ;; - ((and (eq 'TAG (car lap0)) - (not (rassq lap0 lap)) - ;; make sure this tag isn't used in a jump-table - (cl-loop for table in byte-compile-jump-tables - when (member lap0 (hash-table-values table)) - return nil finally return t)) - (and (memq byte-optimize-log '(t byte)) - (byte-compile-log " unused tag %d removed" (nth 1 lap0))) - (setq lap (delq lap0 lap) - keep-going t)) - ;; - ;; goto ... --> goto - ;; return ... --> return - ;; (unless a jump-table is being used, where deleting may affect - ;; other valid case bodies) - ;; - ((and (memq (car lap0) '(byte-goto byte-return)) - (not (memq (car lap1) '(TAG nil))) - ;; FIXME: Instead of deferring simply when jump-tables are - ;; being used, keep a list of tags used for switch tags and - ;; use them instead (see `byte-compile-inline-lapcode'). - (not byte-compile-jump-tables)) - (setq tmp rest) - (let ((i 0) - (opt-p (memq byte-optimize-log '(t lap))) - str deleted) - (while (and (setq tmp (cdr tmp)) - (not (eq 'TAG (car (car tmp))))) - (if opt-p (setq deleted (cons (car tmp) deleted) - str (concat str " %s") - i (1+ i)))) - (if opt-p - (let ((tagstr - (if (eq 'TAG (car (car tmp))) - (format "%d:" (car (cdr (car tmp)))) - (or (car tmp) "")))) - (if (< i 6) - (apply 'byte-compile-log-lap-1 - (concat " %s" str - " %s\t-->\t%s %s") - lap0 - (nconc (nreverse deleted) - (list tagstr lap0 tagstr))) - (byte-compile-log-lap - " %s <%d unreachable op%s> %s\t-->\t%s %s" - lap0 i (if (= i 1) "" "s") - tagstr lap0 tagstr)))) - (rplacd rest tmp)) - (setq keep-going t)) - ;; - ;; unbind --> unbind - ;; (this may enable other optimizations.) - ;; - ((and (eq 'byte-unbind (car lap1)) - (memq (car lap0) byte-after-unbind-ops)) - (byte-compile-log-lap " %s %s\t-->\t%s %s" lap0 lap1 lap1 lap0) - (setcar rest lap1) - (setcar (cdr rest) lap0) - (setq keep-going t)) - ;; - ;; varbind-X unbind-N --> discard unbind-(N-1) - ;; save-excursion unbind-N --> unbind-(N-1) - ;; save-restriction unbind-N --> unbind-(N-1) - ;; - ((and (eq 'byte-unbind (car lap1)) - (memq (car lap0) '(byte-varbind byte-save-excursion - byte-save-restriction)) - (< 0 (cdr lap1))) - (if (zerop (setcdr lap1 (1- (cdr lap1)))) - (delq lap1 rest)) - (if (eq (car lap0) 'byte-varbind) - (setcar rest (cons 'byte-discard 0)) + (cond + ;; pop --> + ;; ...including: + ;; const-X pop --> + ;; varref-X pop --> + ;; dup pop --> + ;; + ((and (eq 'byte-discard (car lap1)) + (memq (car lap0) side-effect-free)) + (setq keep-going t) + (setq tmp (aref byte-stack+-info (symbol-value (car lap0)))) + (setq rest (cdr rest)) + (cond ((= tmp 1) + (byte-compile-log-lap + " %s discard\t-->\t" lap0) + (setq lap (delq lap0 (delq lap1 lap)))) + ((= tmp 0) + (byte-compile-log-lap + " %s discard\t-->\t discard" lap0) (setq lap (delq lap0 lap))) - (byte-compile-log-lap " %s %s\t-->\t%s %s" - lap0 (cons (car lap1) (1+ (cdr lap1))) - (if (eq (car lap0) 'byte-varbind) - (car rest) - (car (cdr rest))) - (if (and (/= 0 (cdr lap1)) - (eq (car lap0) 'byte-varbind)) - (car (cdr rest)) - "")) - (setq keep-going t)) - ;; - ;; goto*-X ... X: goto-Y --> goto*-Y - ;; goto-X ... X: return --> return - ;; - ((and (memq (car lap0) byte-goto-ops) - (memq (car (setq tmp (nth 1 (memq (cdr lap0) lap)))) - '(byte-goto byte-return))) - (cond ((and (not (eq tmp lap0)) - (or (eq (car lap0) 'byte-goto) - (eq (car tmp) 'byte-goto))) - (byte-compile-log-lap " %s [%s]\t-->\t%s" - (car lap0) tmp tmp) - (if (eq (car tmp) 'byte-return) - (setcar lap0 'byte-return)) - (setcdr lap0 (cdr tmp)) - (setq keep-going t)))) - ;; - ;; goto-*-else-pop X ... X: goto-if-* --> whatever - ;; goto-*-else-pop X ... X: discard --> whatever - ;; - ((and (memq (car lap0) '(byte-goto-if-nil-else-pop - byte-goto-if-not-nil-else-pop)) - (memq (car (car (setq tmp (cdr (memq (cdr lap0) lap))))) - (eval-when-compile - (cons 'byte-discard byte-conditional-ops))) - (not (eq lap0 (car tmp)))) - (setq tmp2 (car tmp)) - (setq tmp3 (assq (car lap0) '((byte-goto-if-nil-else-pop - byte-goto-if-nil) - (byte-goto-if-not-nil-else-pop - byte-goto-if-not-nil)))) - (if (memq (car tmp2) tmp3) - (progn (setcar lap0 (car tmp2)) - (setcdr lap0 (cdr tmp2)) - (byte-compile-log-lap " %s-else-pop [%s]\t-->\t%s" - (car lap0) tmp2 lap0)) - ;; Get rid of the -else-pop's and jump one step further. + ((= tmp -1) + (byte-compile-log-lap + " %s discard\t-->\tdiscard discard" lap0) + (setcar lap0 'byte-discard) + (setcdr lap0 0)) + ((error "Optimizer error: too much on the stack")))) + ;; + ;; goto*-X X: --> X: + ;; + ((and (memq (car lap0) byte-goto-ops) + (eq (cdr lap0) lap1)) + (cond ((eq (car lap0) 'byte-goto) + (setq lap (delq lap0 lap)) + (setq tmp "")) + ((memq (car lap0) byte-goto-always-pop-ops) + (setcar lap0 (setq tmp 'byte-discard)) + (setcdr lap0 0)) + ((error "Depth conflict at tag %d" (nth 2 lap0)))) + (and (memq byte-optimize-log '(t byte)) + (byte-compile-log " (goto %s) %s:\t-->\t%s %s:" + (nth 1 lap1) (nth 1 lap1) + tmp (nth 1 lap1))) + (setq keep-going t)) + ;; + ;; varset-X varref-X --> dup varset-X + ;; varbind-X varref-X --> dup varbind-X + ;; const/dup varset-X varref-X --> const/dup varset-X const/dup + ;; const/dup varbind-X varref-X --> const/dup varbind-X const/dup + ;; The latter two can enable other optimizations. + ;; + ;; For lexical variables, we could do the same + ;; stack-set-X+1 stack-ref-X --> dup stack-set-X+2 + ;; but this is a very minor gain, since dup is stack-ref-0, + ;; i.e. it's only better if X>5, and even then it comes + ;; at the cost of an extra stack slot. Let's not bother. + ((and (eq 'byte-varref (car lap2)) + (eq (cdr lap1) (cdr lap2)) + (memq (car lap1) '(byte-varset byte-varbind))) + (if (and (setq tmp (memq (car (cdr lap2)) byte-boolean-vars)) + (not (eq (car lap0) 'byte-constant))) + nil + (setq keep-going t) + (if (memq (car lap0) '(byte-constant byte-dup)) + (progn + (setq tmp (if (or (not tmp) + (macroexp--const-symbol-p + (car (cdr lap0)))) + (cdr lap0) + (byte-compile-get-constant t))) + (byte-compile-log-lap " %s %s %s\t-->\t%s %s %s" + lap0 lap1 lap2 lap0 lap1 + (cons (car lap0) tmp)) + (setcar lap2 (car lap0)) + (setcdr lap2 tmp)) + (byte-compile-log-lap " %s %s\t-->\tdup %s" lap1 lap2 lap1) + (setcar lap2 (car lap1)) + (setcar lap1 'byte-dup) + (setcdr lap1 0) + ;; The stack depth gets locally increased, so we will + ;; increase maxdepth in case depth = maxdepth here. + ;; This can cause the third argument to byte-code to + ;; be larger than necessary. + (setq add-depth 1)))) + ;; + ;; dup varset-X discard --> varset-X + ;; dup varbind-X discard --> varbind-X + ;; dup stack-set-X discard --> stack-set-X-1 + ;; (the varbind variant can emerge from other optimizations) + ;; + ((and (eq 'byte-dup (car lap0)) + (eq 'byte-discard (car lap2)) + (memq (car lap1) '(byte-varset byte-varbind + byte-stack-set))) + (byte-compile-log-lap " dup %s discard\t-->\t%s" lap1 lap1) + (setq keep-going t + rest (cdr rest)) + (if (eq 'byte-stack-set (car lap1)) (cl-decf (cdr lap1))) + (setq lap (delq lap0 (delq lap2 lap)))) + ;; + ;; not goto-X-if-nil --> goto-X-if-non-nil + ;; not goto-X-if-non-nil --> goto-X-if-nil + ;; + ;; it is wrong to do the same thing for the -else-pop variants. + ;; + ((and (eq 'byte-not (car lap0)) + (memq (car lap1) '(byte-goto-if-nil byte-goto-if-not-nil))) + (byte-compile-log-lap " not %s\t-->\t%s" + lap1 + (cons + (if (eq (car lap1) 'byte-goto-if-nil) + 'byte-goto-if-not-nil + 'byte-goto-if-nil) + (cdr lap1))) + (setcar lap1 (if (eq (car lap1) 'byte-goto-if-nil) + 'byte-goto-if-not-nil + 'byte-goto-if-nil)) + (setq lap (delq lap0 lap)) + (setq keep-going t)) + ;; + ;; goto-X-if-nil goto-Y X: --> goto-Y-if-non-nil X: + ;; goto-X-if-non-nil goto-Y X: --> goto-Y-if-nil X: + ;; + ;; it is wrong to do the same thing for the -else-pop variants. + ;; + ((and (memq (car lap0) + '(byte-goto-if-nil byte-goto-if-not-nil)) ; gotoX + (eq 'byte-goto (car lap1)) ; gotoY + (eq (cdr lap0) lap2)) ; TAG X + (let ((inverse (if (eq 'byte-goto-if-nil (car lap0)) + 'byte-goto-if-not-nil 'byte-goto-if-nil))) + (byte-compile-log-lap " %s %s %s:\t-->\t%s %s:" + lap0 lap1 lap2 + (cons inverse (cdr lap1)) lap2) + (setq lap (delq lap0 lap)) + (setcar lap1 inverse) + (setq keep-going t))) + ;; + ;; const goto-if-* --> whatever + ;; + ((and (eq 'byte-constant (car lap0)) + (memq (car lap1) byte-conditional-ops) + ;; If the `byte-constant's cdr is not a cons cell, it has + ;; to be an index into the constant pool); even though + ;; it'll be a constant, that constant is not known yet + ;; (it's typically a free variable of a closure, so will + ;; only be known when the closure will be built at + ;; run-time). + (consp (cdr lap0))) + (cond ((if (memq (car lap1) '(byte-goto-if-nil + byte-goto-if-nil-else-pop)) + (car (cdr lap0)) + (not (car (cdr lap0)))) + (byte-compile-log-lap " %s %s\t-->\t" + lap0 lap1) + (setq rest (cdr rest) + lap (delq lap0 (delq lap1 lap)))) + (t + (byte-compile-log-lap " %s %s\t-->\t%s" + lap0 lap1 + (cons 'byte-goto (cdr lap1))) + (when (memq (car lap1) byte-goto-always-pop-ops) + (setq lap (delq lap0 lap))) + (setcar lap1 'byte-goto))) + (setq keep-going t)) + ;; + ;; varref-X varref-X --> varref-X dup + ;; varref-X [dup ...] varref-X --> varref-X [dup ...] dup + ;; stackref-X [dup ...] stackref-X+N --> stackref-X [dup ...] dup + ;; We don't optimize the const-X variations on this here, + ;; because that would inhibit some goto optimizations; we + ;; optimize the const-X case after all other optimizations. + ;; + ((and (memq (car lap0) '(byte-varref byte-stack-ref)) + (progn + (setq tmp (cdr rest)) + (setq tmp2 0) + (while (eq (car (car tmp)) 'byte-dup) + (setq tmp2 (1+ tmp2)) + (setq tmp (cdr tmp))) + t) + (eq (if (eq 'byte-stack-ref (car lap0)) + (+ tmp2 1 (cdr lap0)) + (cdr lap0)) + (cdr (car tmp))) + (eq (car lap0) (car (car tmp)))) + (if (memq byte-optimize-log '(t byte)) + (let ((str "")) + (setq tmp2 (cdr rest)) + (while (not (eq tmp tmp2)) + (setq tmp2 (cdr tmp2) + str (concat str " dup"))) + (byte-compile-log-lap " %s%s %s\t-->\t%s%s dup" + lap0 str lap0 lap0 str))) + (setq keep-going t) + (setcar (car tmp) 'byte-dup) + (setcdr (car tmp) 0) + (setq rest tmp)) + ;; + ;; TAG1: TAG2: --> TAG1: + ;; (and other references to TAG2 are replaced with TAG1) + ;; + ((and (eq (car lap0) 'TAG) + (eq (car lap1) 'TAG)) + (and (memq byte-optimize-log '(t byte)) + (byte-compile-log " adjacent tags %d and %d merged" + (nth 1 lap1) (nth 1 lap0))) + (setq tmp3 lap) + (while (setq tmp2 (rassq lap0 tmp3)) + (setcdr tmp2 lap1) + (setq tmp3 (cdr (memq tmp2 tmp3)))) + (setq lap (delq lap0 lap) + keep-going t) + ;; replace references to tag in jump tables, if any + (dolist (table byte-compile-jump-tables) + (maphash #'(lambda (value tag) + (when (equal tag lap0) + (puthash value lap1 table))) + table))) + ;; + ;; unused-TAG: --> + ;; + ((and (eq 'TAG (car lap0)) + (not (rassq lap0 lap)) + ;; make sure this tag isn't used in a jump-table + (cl-loop for table in byte-compile-jump-tables + when (member lap0 (hash-table-values table)) + return nil finally return t)) + (and (memq byte-optimize-log '(t byte)) + (byte-compile-log " unused tag %d removed" (nth 1 lap0))) + (setq lap (delq lap0 lap) + keep-going t)) + ;; + ;; goto ... --> goto + ;; return ... --> return + ;; (unless a jump-table is being used, where deleting may affect + ;; other valid case bodies) + ;; + ((and (memq (car lap0) '(byte-goto byte-return)) + (not (memq (car lap1) '(TAG nil))) + ;; FIXME: Instead of deferring simply when jump-tables are + ;; being used, keep a list of tags used for switch tags and + ;; use them instead (see `byte-compile-inline-lapcode'). + (not byte-compile-jump-tables)) + (setq tmp rest) + (let ((i 0) + (opt-p (memq byte-optimize-log '(t lap))) + str deleted) + (while (and (setq tmp (cdr tmp)) + (not (eq 'TAG (car (car tmp))))) + (if opt-p (setq deleted (cons (car tmp) deleted) + str (concat str " %s") + i (1+ i)))) + (if opt-p + (let ((tagstr + (if (eq 'TAG (car (car tmp))) + (format "%d:" (car (cdr (car tmp)))) + (or (car tmp) "")))) + (if (< i 6) + (apply 'byte-compile-log-lap-1 + (concat " %s" str + " %s\t-->\t%s %s") + lap0 + (nconc (nreverse deleted) + (list tagstr lap0 tagstr))) + (byte-compile-log-lap + " %s <%d unreachable op%s> %s\t-->\t%s %s" + lap0 i (if (= i 1) "" "s") + tagstr lap0 tagstr)))) + (rplacd rest tmp)) + (setq keep-going t)) + ;; + ;; unbind --> unbind + ;; (this may enable other optimizations.) + ;; + ((and (eq 'byte-unbind (car lap1)) + (memq (car lap0) byte-after-unbind-ops)) + (byte-compile-log-lap " %s %s\t-->\t%s %s" lap0 lap1 lap1 lap0) + (setcar rest lap1) + (setcar (cdr rest) lap0) + (setq keep-going t)) + ;; + ;; varbind-X unbind-N --> discard unbind-(N-1) + ;; save-excursion unbind-N --> unbind-(N-1) + ;; save-restriction unbind-N --> unbind-(N-1) + ;; + ((and (eq 'byte-unbind (car lap1)) + (memq (car lap0) '(byte-varbind byte-save-excursion + byte-save-restriction)) + (< 0 (cdr lap1))) + (if (zerop (setcdr lap1 (1- (cdr lap1)))) + (delq lap1 rest)) + (if (eq (car lap0) 'byte-varbind) + (setcar rest (cons 'byte-discard 0)) + (setq lap (delq lap0 lap))) + (byte-compile-log-lap " %s %s\t-->\t%s %s" + lap0 (cons (car lap1) (1+ (cdr lap1))) + (if (eq (car lap0) 'byte-varbind) + (car rest) + (car (cdr rest))) + (if (and (/= 0 (cdr lap1)) + (eq (car lap0) 'byte-varbind)) + (car (cdr rest)) + "")) + (setq keep-going t)) + ;; + ;; goto*-X ... X: goto-Y --> goto*-Y + ;; goto-X ... X: return --> return + ;; + ((and (memq (car lap0) byte-goto-ops) + (memq (car (setq tmp (nth 1 (memq (cdr lap0) lap)))) + '(byte-goto byte-return))) + (cond ((and (not (eq tmp lap0)) + (or (eq (car lap0) 'byte-goto) + (eq (car tmp) 'byte-goto))) + (byte-compile-log-lap " %s [%s]\t-->\t%s" + (car lap0) tmp tmp) + (if (eq (car tmp) 'byte-return) + (setcar lap0 'byte-return)) + (setcdr lap0 (cdr tmp)) + (setq keep-going t)))) + ;; + ;; goto-*-else-pop X ... X: goto-if-* --> whatever + ;; goto-*-else-pop X ... X: discard --> whatever + ;; + ((and (memq (car lap0) '(byte-goto-if-nil-else-pop + byte-goto-if-not-nil-else-pop)) + (memq (car (car (setq tmp (cdr (memq (cdr lap0) lap))))) + (eval-when-compile + (cons 'byte-discard byte-conditional-ops))) + (not (eq lap0 (car tmp)))) + (setq tmp2 (car tmp)) + (setq tmp3 (assq (car lap0) '((byte-goto-if-nil-else-pop + byte-goto-if-nil) + (byte-goto-if-not-nil-else-pop + byte-goto-if-not-nil)))) + (if (memq (car tmp2) tmp3) + (progn (setcar lap0 (car tmp2)) + (setcdr lap0 (cdr tmp2)) + (byte-compile-log-lap " %s-else-pop [%s]\t-->\t%s" + (car lap0) tmp2 lap0)) + ;; Get rid of the -else-pop's and jump one step further. + (or (eq 'TAG (car (nth 1 tmp))) + (setcdr tmp (cons (byte-compile-make-tag) + (cdr tmp)))) + (byte-compile-log-lap " %s [%s]\t-->\t%s " + (car lap0) tmp2 (nth 1 tmp3)) + (setcar lap0 (nth 1 tmp3)) + (setcdr lap0 (nth 1 tmp))) + (setq keep-going t)) + ;; + ;; const goto-X ... X: goto-if-* --> whatever + ;; const goto-X ... X: discard --> whatever + ;; + ((and (eq (car lap0) 'byte-constant) + (eq (car lap1) 'byte-goto) + (memq (car (car (setq tmp (cdr (memq (cdr lap1) lap))))) + (eval-when-compile + (cons 'byte-discard byte-conditional-ops))) + (not (eq lap1 (car tmp)))) + (setq tmp2 (car tmp)) + (cond ((when (consp (cdr lap0)) + (memq (car tmp2) + (if (null (car (cdr lap0))) + '(byte-goto-if-nil byte-goto-if-nil-else-pop) + '(byte-goto-if-not-nil + byte-goto-if-not-nil-else-pop)))) + (byte-compile-log-lap " %s goto [%s]\t-->\t%s %s" + lap0 tmp2 lap0 tmp2) + (setcar lap1 (car tmp2)) + (setcdr lap1 (cdr tmp2)) + ;; Let next step fix the (const,goto-if*) sequence. + (setq rest (cons nil rest)) + (setq keep-going t)) + ((or (consp (cdr lap0)) + (eq (car tmp2) 'byte-discard)) + ;; Jump one step further + (byte-compile-log-lap + " %s goto [%s]\t-->\t goto " + lap0 tmp2) (or (eq 'TAG (car (nth 1 tmp))) (setcdr tmp (cons (byte-compile-make-tag) (cdr tmp)))) - (byte-compile-log-lap " %s [%s]\t-->\t%s " - (car lap0) tmp2 (nth 1 tmp3)) - (setcar lap0 (nth 1 tmp3)) - (setcdr lap0 (nth 1 tmp))) - (setq keep-going t)) - ;; - ;; const goto-X ... X: goto-if-* --> whatever - ;; const goto-X ... X: discard --> whatever - ;; - ((and (eq (car lap0) 'byte-constant) - (eq (car lap1) 'byte-goto) - (memq (car (car (setq tmp (cdr (memq (cdr lap1) lap))))) - (eval-when-compile - (cons 'byte-discard byte-conditional-ops))) - (not (eq lap1 (car tmp)))) - (setq tmp2 (car tmp)) - (cond ((when (consp (cdr lap0)) - (memq (car tmp2) - (if (null (car (cdr lap0))) - '(byte-goto-if-nil byte-goto-if-nil-else-pop) - '(byte-goto-if-not-nil - byte-goto-if-not-nil-else-pop)))) - (byte-compile-log-lap " %s goto [%s]\t-->\t%s %s" - lap0 tmp2 lap0 tmp2) - (setcar lap1 (car tmp2)) - (setcdr lap1 (cdr tmp2)) - ;; Let next step fix the (const,goto-if*) sequence. - (setq rest (cons nil rest)) - (setq keep-going t)) - ((or (consp (cdr lap0)) - (eq (car tmp2) 'byte-discard)) - ;; Jump one step further - (byte-compile-log-lap - " %s goto [%s]\t-->\t goto " - lap0 tmp2) - (or (eq 'TAG (car (nth 1 tmp))) - (setcdr tmp (cons (byte-compile-make-tag) - (cdr tmp)))) - (setcdr lap1 (car (cdr tmp))) - (setq lap (delq lap0 lap)) - (setq keep-going t)))) - ;; - ;; X: varref-Y ... varset-Y goto-X --> - ;; X: varref-Y Z: ... dup varset-Y goto-Z - ;; (varset-X goto-BACK, BACK: varref-X --> copy the varref down.) - ;; (This is so usual for while loops that it is worth handling). - ;; - ;; Here again, we could do it for stack-ref/stack-set, but - ;; that's replacing a stack-ref-Y with a stack-ref-0, which - ;; is a very minor improvement (if any), at the cost of - ;; more stack use and more byte-code. Let's not do it. - ;; - ((and (eq (car lap1) 'byte-varset) - (eq (car lap2) 'byte-goto) - (not (memq (cdr lap2) rest)) ;Backwards jump - (eq (car (car (setq tmp (cdr (memq (cdr lap2) lap))))) - 'byte-varref) - (eq (cdr (car tmp)) (cdr lap1)) - (not (memq (car (cdr lap1)) byte-boolean-vars))) - ;;(byte-compile-log-lap " Pulled %s to end of loop" (car tmp)) - (let ((newtag (byte-compile-make-tag))) - (byte-compile-log-lap - " %s: %s ... %s %s\t-->\t%s: %s %s: ... %s %s %s" - (nth 1 (cdr lap2)) (car tmp) - lap1 lap2 - (nth 1 (cdr lap2)) (car tmp) - (nth 1 newtag) 'byte-dup lap1 - (cons 'byte-goto newtag) - ) - (setcdr rest (cons (cons 'byte-dup 0) (cdr rest))) - (setcdr tmp (cons (setcdr lap2 newtag) (cdr tmp)))) - (setq add-depth 1) - (setq keep-going t)) - ;; - ;; goto-X Y: ... X: goto-if*-Y --> goto-if-not-*-X+1 Y: - ;; (This can pull the loop test to the end of the loop) - ;; - ((and (eq (car lap0) 'byte-goto) - (eq (car lap1) 'TAG) - (eq lap1 - (cdr (car (setq tmp (cdr (memq (cdr lap0) lap)))))) - (memq (car (car tmp)) - '(byte-goto byte-goto-if-nil byte-goto-if-not-nil - byte-goto-if-nil-else-pop))) -;; (byte-compile-log-lap " %s %s, %s %s --> moved conditional" -;; lap0 lap1 (cdr lap0) (car tmp)) - (let ((newtag (byte-compile-make-tag))) - (byte-compile-log-lap - "%s %s: ... %s: %s\t-->\t%s ... %s:" - lap0 (nth 1 lap1) (nth 1 (cdr lap0)) (car tmp) - (cons (cdr (assq (car (car tmp)) - '((byte-goto-if-nil . byte-goto-if-not-nil) - (byte-goto-if-not-nil . byte-goto-if-nil) - (byte-goto-if-nil-else-pop . - byte-goto-if-not-nil-else-pop) - (byte-goto-if-not-nil-else-pop . - byte-goto-if-nil-else-pop)))) - newtag) - - (nth 1 newtag) - ) - (setcdr tmp (cons (setcdr lap0 newtag) (cdr tmp))) - (if (eq (car (car tmp)) 'byte-goto-if-nil-else-pop) - ;; We can handle this case but not the -if-not-nil case, - ;; because we won't know which non-nil constant to push. - (setcdr rest (cons (cons 'byte-constant - (byte-compile-get-constant nil)) - (cdr rest)))) - (setcar lap0 (nth 1 (memq (car (car tmp)) - '(byte-goto-if-nil-else-pop - byte-goto-if-not-nil - byte-goto-if-nil - byte-goto-if-not-nil - byte-goto byte-goto)))) - ) - (setq keep-going t)) - ) + (setcdr lap1 (car (cdr tmp))) + (setq lap (delq lap0 lap)) + (setq keep-going t)))) + ;; + ;; X: varref-Y ... varset-Y goto-X --> + ;; X: varref-Y Z: ... dup varset-Y goto-Z + ;; (varset-X goto-BACK, BACK: varref-X --> copy the varref down.) + ;; (This is so usual for while loops that it is worth handling). + ;; + ;; Here again, we could do it for stack-ref/stack-set, but + ;; that's replacing a stack-ref-Y with a stack-ref-0, which + ;; is a very minor improvement (if any), at the cost of + ;; more stack use and more byte-code. Let's not do it. + ;; + ((and (eq (car lap1) 'byte-varset) + (eq (car lap2) 'byte-goto) + (not (memq (cdr lap2) rest)) ;Backwards jump + (eq (car (car (setq tmp (cdr (memq (cdr lap2) lap))))) + 'byte-varref) + (eq (cdr (car tmp)) (cdr lap1)) + (not (memq (car (cdr lap1)) byte-boolean-vars))) + ;;(byte-compile-log-lap " Pulled %s to end of loop" (car tmp)) + (let ((newtag (byte-compile-make-tag))) + (byte-compile-log-lap + " %s: %s ... %s %s\t-->\t%s: %s %s: ... %s %s %s" + (nth 1 (cdr lap2)) (car tmp) + lap1 lap2 + (nth 1 (cdr lap2)) (car tmp) + (nth 1 newtag) 'byte-dup lap1 + (cons 'byte-goto newtag) + ) + (setcdr rest (cons (cons 'byte-dup 0) (cdr rest))) + (setcdr tmp (cons (setcdr lap2 newtag) (cdr tmp)))) + (setq add-depth 1) + (setq keep-going t)) + ;; + ;; goto-X Y: ... X: goto-if*-Y --> goto-if-not-*-X+1 Y: + ;; (This can pull the loop test to the end of the loop) + ;; + ((and (eq (car lap0) 'byte-goto) + (eq (car lap1) 'TAG) + (eq lap1 + (cdr (car (setq tmp (cdr (memq (cdr lap0) lap)))))) + (memq (car (car tmp)) + '(byte-goto byte-goto-if-nil byte-goto-if-not-nil + byte-goto-if-nil-else-pop))) + ;; (byte-compile-log-lap " %s %s, %s %s --> moved conditional" + ;; lap0 lap1 (cdr lap0) (car tmp)) + (let ((newtag (byte-compile-make-tag))) + (byte-compile-log-lap + "%s %s: ... %s: %s\t-->\t%s ... %s:" + lap0 (nth 1 lap1) (nth 1 (cdr lap0)) (car tmp) + (cons (cdr (assq (car (car tmp)) + '((byte-goto-if-nil . byte-goto-if-not-nil) + (byte-goto-if-not-nil . byte-goto-if-nil) + (byte-goto-if-nil-else-pop . + byte-goto-if-not-nil-else-pop) + (byte-goto-if-not-nil-else-pop . + byte-goto-if-nil-else-pop)))) + newtag) + + (nth 1 newtag) + ) + (setcdr tmp (cons (setcdr lap0 newtag) (cdr tmp))) + (if (eq (car (car tmp)) 'byte-goto-if-nil-else-pop) + ;; We can handle this case but not the -if-not-nil case, + ;; because we won't know which non-nil constant to push. + (setcdr rest (cons (cons 'byte-constant + (byte-compile-get-constant nil)) + (cdr rest)))) + (setcar lap0 (nth 1 (memq (car (car tmp)) + '(byte-goto-if-nil-else-pop + byte-goto-if-not-nil + byte-goto-if-nil + byte-goto-if-not-nil + byte-goto byte-goto)))) + ) + (setq keep-going t)) + ) (setq rest (cdr rest))) ) ;; Cleanup stage: commit 434057ad925cad3ebcae1802fab60733ae5decae Author: Lars Ingebrigtsen Date: Wed Jan 20 19:42:21 2021 +0100 Fix footnote-mode problem when reopening an old file * lisp/mail/footnote.el (footnote--regenerate-alist): New function (bug#7258). (footnote-mode): Use it to restore footnotes after opening an old file with footnotes. diff --git a/lisp/mail/footnote.el b/lisp/mail/footnote.el index ea109eec12..9c1a738035 100644 --- a/lisp/mail/footnote.el +++ b/lisp/mail/footnote.el @@ -910,7 +910,32 @@ play around with the following keys: (unless (assoc bullet-regexp filladapt-token-table) (setq filladapt-token-table (append filladapt-token-table - (list (list bullet-regexp 'bullet))))))))) + (list (list bullet-regexp 'bullet))))))) + (footnote--regenerate-alist))) + +(defun footnote--regenerate-alist () + (save-excursion + (goto-char (point-min)) + (if (not (re-search-forward footnote-section-tag-regexp nil t)) + (error "No footnote section in this buffer") + (setq footnote--markers-alist + (cl-loop + with start-of-footnotes = (match-beginning 0) + with regexp = (footnote--current-regexp) + for (note text) in + (cl-loop for pos = (re-search-forward regexp nil t) + while pos + collect (list (match-string 1) + (copy-marker (match-beginning 0) t))) + do (goto-char (point-min)) + collect (cl-list* + (string-to-number note) + text + (cl-loop + for pos = (re-search-forward regexp start-of-footnotes t) + while pos + when (equal note (match-string 1)) + collect (copy-marker (match-beginning 0) t)))))))) (provide 'footnote) commit 7fe7efe0bbb00a541df1da68ca4cb4af14441fe1 Author: Lars Ingebrigtsen Date: Wed Jan 20 18:52:17 2021 +0100 cua-toggle-global-mark doc string clarification * lisp/emulation/cua-gmrk.el (cua-toggle-global-mark): Clarify that also inserted characters are affected (bug#8083). diff --git a/lisp/emulation/cua-gmrk.el b/lisp/emulation/cua-gmrk.el index 195bba1f31..6f6b9fce13 100644 --- a/lisp/emulation/cua-gmrk.el +++ b/lisp/emulation/cua-gmrk.el @@ -87,9 +87,11 @@ (defun cua-toggle-global-mark (stay) "Set or cancel the global marker. -When the global marker is set, CUA cut and copy commands will automatically -insert the deleted or copied text before the global marker, even when the -global marker is in another buffer. +When the global marker is set, CUA cut and copy commands will +automatically insert the inserted, deleted or copied text before +the global marker, even when the global marker is in another +buffer. + If the global marker isn't set, set the global marker at point in the current buffer. Otherwise jump to the global marker position and cancel it. With prefix argument, don't jump to global mark when canceling it." commit bd423b869978f33bea8d399684f02b0b5b53da43 Author: Michael Albinus Date: Wed Jan 20 18:51:52 2021 +0100 Fix environment handling in tramp-handle-make-process * lisp/net/tramp.el (tramp-test-message): Add `tramp-suppress-trace' property. (tramp-handle-make-process): Handle also 'tramp-remote-process-environment'. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 2816c58fe7..7b34a74882 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1990,6 +1990,8 @@ the resulting error message." (tramp-dissect-file-name default-directory) 0 fmt-string arguments) (apply #'message fmt-string arguments))) +(put #'tramp-test-message 'tramp-suppress-trace t) + ;; This function provides traces in case of errors not triggered by ;; Tramp functions. (defun tramp-signal-hook-function (error-symbol data) @@ -3801,15 +3803,20 @@ It does not support `:stderr'." (get-buffer-create buffer) ;; BUFFER can be nil. We use a temporary buffer. (generate-new-buffer tramp-temp-buffer-name))) - ;; We use as environment the difference to toplevel - ;; `process-environment'. (env (mapcar (lambda (elt) - (unless - (member - elt (default-toplevel-value 'process-environment)) - (when (string-match-p "=" elt) elt))) - process-environment)) + (when (string-match-p "=" elt) elt)) + tramp-remote-process-environment)) + ;; We use as environment the difference to toplevel + ;; `process-environment'. + (env (dolist (elt process-environment env) + (when + (and + (string-match-p "=" elt) + (not + (member + elt (default-toplevel-value 'process-environment)))) + (setq env (cons elt env))))) (env (setenv-internal env "INSIDE_EMACS" (concat (or (getenv "INSIDE_EMACS") emacs-version) commit 38173af10df67cb36521cdcc2f1f42103d67de98 Author: Gabriel do Nascimento Ribeiro Date: Wed Jan 20 17:54:43 2021 +0100 Respect remember-save-after-remembering on remember-diary-extract-entries * lisp/textmodes/remember.el (remember-diary-extract-entries): Save automatically if `remember-save-after-remembering' is non-nil (bug#45811). diff --git a/lisp/textmodes/remember.el b/lisp/textmodes/remember.el index 6c94f8d03c..7f107977d5 100644 --- a/lisp/textmodes/remember.el +++ b/lisp/textmodes/remember.el @@ -559,7 +559,10 @@ If this is nil, then `diary-file' will be used instead." (push (remember-diary-convert-entry (match-string 1)) list)) (when list (diary-make-entry (mapconcat 'identity list "\n") - nil remember-diary-file)) + nil remember-diary-file) + (when remember-save-after-remembering + (with-current-buffer (find-buffer-visiting diary-file) + (save-buffer)))) nil))) ;; Continue processing ;;; Internal Functions: commit edf6350e7ffd51f93fd84df3e0f9734e337cd51c Author: Gabriel do Nascimento Ribeiro Date: Wed Jan 20 17:53:04 2021 +0100 Add option remember-text-format-function * lisp/textmodes/remember.el (remember-text-format-function): New variable (bug#45809). (remember-append-to-file): Use it. diff --git a/etc/NEWS b/etc/NEWS index a0e1e3b2a1..c8cbce1882 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1560,6 +1560,9 @@ that makes it a valid button. --- *** New user option 'remember-diary-regexp'. +--- +*** New user option 'remember-text-format-function'. + *** New function 'buffer-line-statistics'. This function returns some statistics about the line lengths in a buffer. diff --git a/lisp/textmodes/remember.el b/lisp/textmodes/remember.el index 92706e3807..6c94f8d03c 100644 --- a/lisp/textmodes/remember.el +++ b/lisp/textmodes/remember.el @@ -411,13 +411,24 @@ The default emulates `current-time-string' for backward compatibility." :group 'remember :version "27.1") +(defcustom remember-text-format-function nil + "The function to format the remembered text. +The function receives the remembered text as argument and should +return the text to be remembered." + :type 'function + :group 'remember + :version "28.1") + (defun remember-append-to-file () "Remember, with description DESC, the given TEXT." (let* ((text (buffer-string)) (desc (remember-buffer-desc)) - (remember-text (concat "\n" remember-leader-text - (format-time-string remember-time-format) - " (" desc ")\n\n" text + (remember-text (concat "\n" + (if remember-text-format-function + (funcall remember-text-format-function text) + (concat remember-leader-text + (format-time-string remember-time-format) + " (" desc ")\n\n" text)) (save-excursion (goto-char (point-max)) (if (bolp) nil "\n")))) (buf (find-buffer-visiting remember-data-file))) commit 72d4522b05c81ba9400603963db55e47c6d836ce Author: Gabriel do Nascimento Ribeiro Date: Wed Jan 20 17:45:08 2021 +0100 Add option remember-diary-regexp * lisp/textmodes/remember.el (remember-diary-extract-entries): Use it (bug#45808). (remember-diary-regexp): New variable. diff --git a/etc/NEWS b/etc/NEWS index 7a012b4891..a0e1e3b2a1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1557,6 +1557,9 @@ that makes it a valid button. ** Miscellaneous +--- +*** New user option 'remember-diary-regexp'. + *** New function 'buffer-line-statistics'. This function returns some statistics about the line lengths in a buffer. diff --git a/lisp/textmodes/remember.el b/lisp/textmodes/remember.el index 98d3a3856e..92706e3807 100644 --- a/lisp/textmodes/remember.el +++ b/lisp/textmodes/remember.el @@ -159,7 +159,8 @@ ;; ;; This should be before other entries that may return t ;; (add-to-list 'remember-handler-functions 'remember-diary-extract-entries) ;; -;; This module recognizes entries of the form +;; This module recognizes entries of the form (defined by +;; `remember-diary-regexp') ;; ;; DIARY: .... ;; @@ -532,13 +533,18 @@ If this is nil, then `diary-file' will be used instead." (autoload 'diary-make-entry "diary-lib") +(defcustom remember-diary-regexp "^DIARY:\\s-*\\(.+\\)" + "Regexp to extract diary entries." + :type 'regexp + :version "28.1") + ;;;###autoload (defun remember-diary-extract-entries () - "Extract diary entries from the region." + "Extract diary entries from the region based on `remember-diary-regexp'." (save-excursion (goto-char (point-min)) (let (list) - (while (re-search-forward "^DIARY:\\s-*\\(.+\\)" nil t) + (while (re-search-forward remember-diary-regexp nil t) (push (remember-diary-convert-entry (match-string 1)) list)) (when list (diary-make-entry (mapconcat 'identity list "\n") commit cad2c4b14a98d24d6cba4089bd48340899dcff52 Author: Lars Ingebrigtsen Date: Wed Jan 20 17:25:40 2021 +0100 Tweak tty-find-type to allow TERM=screen.xterm * lisp/faces.el (tty-find-type): Allow TERM=screen.xterm to find term/screen.el (bug#45824). diff --git a/lisp/faces.el b/lisp/faces.el index 4e98338432..d654b1f0e2 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -2199,7 +2199,7 @@ the above example." (not (funcall pred type))) ;; Strip off last hyphen and what follows, then try again (setq type - (if (setq hyphend (string-match-p "[-_][^-_]+$" type)) + (if (setq hyphend (string-match-p "[-_.][^-_.]+$" type)) (substring type 0 hyphend) nil)))) type) diff --git a/test/lisp/faces-tests.el b/test/lisp/faces-tests.el index 6e77259fe1..c0db9c9de1 100644 --- a/test/lisp/faces-tests.el +++ b/test/lisp/faces-tests.el @@ -217,5 +217,13 @@ )) ) +(ert-deftest test-tty-find-type () + (let ((pred (lambda (string) + (locate-library (concat "term/" string ".el"))))) + (should (tty-find-type pred "cygwin")) + (should (tty-find-type pred "cygwin-foo")) + (should (equal (tty-find-type pred "xterm") "xterm")) + (should (equal (tty-find-type pred "screen.xterm") "screen")))) + (provide 'faces-tests) ;;; faces-tests.el ends here commit f30cf07ecba8f4316b268b7ad57705a0aa16d660 Author: Lars Ingebrigtsen Date: Wed Jan 20 16:58:09 2021 +0100 Make symbol-at-point return nil if there's no symbols in the buffer * lisp/thingatpt.el (thing-at-point--beginning-of-symbol): Special op that errors out when there's no symbols in the buffer before point (bug#14234). (symbol): Use it. diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el index d3ba941fcc..67d4092d40 100644 --- a/lisp/thingatpt.el +++ b/lisp/thingatpt.el @@ -218,6 +218,15 @@ The bounds of THING are determined by `bounds-of-thing-at-point'." (put 'sexp 'beginning-op 'thing-at-point--beginning-of-sexp) +;; Symbols + +(put 'symbol 'beginning-op 'thing-at-point--beginning-of-symbol) + +(defun thing-at-point--beginning-of-symbol () + "Move point to the beginning of the current symbol." + (and (re-search-backward "\\(\\sw\\|\\s_\\)+") + (skip-syntax-backward "w_"))) + ;; Lists (put 'list 'bounds-of-thing-at-point 'thing-at-point-bounds-of-list-at-point) diff --git a/test/lisp/thingatpt-tests.el b/test/lisp/thingatpt-tests.el index 8eec853d46..62a27f09cb 100644 --- a/test/lisp/thingatpt-tests.el +++ b/test/lisp/thingatpt-tests.el @@ -185,7 +185,6 @@ position to retrieve THING.") (should (eq (symbol-at-point) 'bar)))) (ert-deftest test-symbol-thing-3 () - :expected-result :failed ; FIXME bug#14234 (with-temp-buffer (insert "`[[`(") (goto-char 2) commit ce1a42a6eb41ab7a4473de9e8d8961498568576a Author: Lars Ingebrigtsen Date: Wed Jan 20 16:47:39 2021 +0100 Add tests for symbol-at-point (bug#14234) diff --git a/test/lisp/thingatpt-tests.el b/test/lisp/thingatpt-tests.el index c43c81af9f..8eec853d46 100644 --- a/test/lisp/thingatpt-tests.el +++ b/test/lisp/thingatpt-tests.el @@ -146,4 +146,49 @@ position to retrieve THING.") (should (thing-at-point-looking-at "2abcd")) (should (equal (match-data) m2))))) +(ert-deftest test-symbol-thing-1 () + (with-temp-buffer + (insert "foo bar zot") + (goto-char 4) + (should (eq (symbol-at-point) 'foo)) + (forward-char 1) + (should (eq (symbol-at-point) 'bar)) + (forward-char 1) + (should (eq (symbol-at-point) 'bar)) + (forward-char 1) + (should (eq (symbol-at-point) 'bar)) + (forward-char 1) + (should (eq (symbol-at-point) 'bar)) + (forward-char 1) + (should (eq (symbol-at-point) 'zot)))) + +(ert-deftest test-symbol-thing-2 () + (with-temp-buffer + (insert " bar ") + (goto-char (point-max)) + (should (eq (symbol-at-point) nil)) + (forward-char -1) + (should (eq (symbol-at-point) 'bar)))) + +(ert-deftest test-symbol-thing-2 () + (with-temp-buffer + (insert " bar ") + (goto-char (point-max)) + (should (eq (symbol-at-point) nil)) + (forward-char -1) + (should (eq (symbol-at-point) 'bar)))) + +(ert-deftest test-symbol-thing-3 () + (with-temp-buffer + (insert "bar") + (goto-char 2) + (should (eq (symbol-at-point) 'bar)))) + +(ert-deftest test-symbol-thing-3 () + :expected-result :failed ; FIXME bug#14234 + (with-temp-buffer + (insert "`[[`(") + (goto-char 2) + (should (eq (symbol-at-point) nil)))) + ;;; thingatpt.el ends here commit 82c228a017cfbb69ac5a91fba51419eb3b1f7032 Author: Stefan Monnier Date: Wed Jan 20 09:52:07 2021 -0500 Don't let `maybe_quit` prevent resetting `consing_until_gc` (bug#43389) * src/alloc.c (garbage_collect): Postpone `unblock_input` a bit. * src/window.c (window_parameter): Avoid `maybe_quit`. cherry picked from commit 420661af07448857f0a17e15dc27bceeb6aff541 diff --git a/src/alloc.c b/src/alloc.c index ebd99b9f65..4c76f4a554 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -5987,11 +5987,13 @@ garbage_collect (void) gc_in_progress = 0; - unblock_input (); - consing_until_gc = gc_threshold = consing_threshold (gc_cons_threshold, Vgc_cons_percentage, 0); + /* Unblock *after* re-setting `consing_until_gc` in case `unblock_input` + signals an error (see bug#43389). */ + unblock_input (); + if (garbage_collection_messages && NILP (Vmemory_full)) { if (message_p || minibuf_level > 0) diff --git a/src/window.c b/src/window.c index 43f2a8f00f..f231187f7b 100644 --- a/src/window.c +++ b/src/window.c @@ -2272,7 +2272,7 @@ return value is a list of elements of the form (PARAMETER . VALUE). */) Lisp_Object window_parameter (struct window *w, Lisp_Object parameter) { - Lisp_Object result = Fassq (parameter, w->window_parameters); + Lisp_Object result = assq_no_quit (parameter, w->window_parameters); return CDR_SAFE (result); } commit 420661af07448857f0a17e15dc27bceeb6aff541 Author: Stefan Monnier Date: Wed Jan 20 09:52:07 2021 -0500 Don't let `maybe_quit` prevent resetting `consing_until_gc` (bug#43389) * src/alloc.c (garbage_collect): Postpone `unblock_input` a bit. * src/window.c (window_parameter): Avoid `maybe_quit`. diff --git a/src/alloc.c b/src/alloc.c index c0a55e61b9..b86ed4ed26 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -6101,11 +6101,13 @@ garbage_collect (void) gc_in_progress = 0; - unblock_input (); - consing_until_gc = gc_threshold = consing_threshold (gc_cons_threshold, Vgc_cons_percentage, 0); + /* Unblock *after* re-setting `consing_until_gc` in case `unblock_input` + signals an error (see bug#43389). */ + unblock_input (); + if (garbage_collection_messages && NILP (Vmemory_full)) { if (message_p || minibuf_level > 0) diff --git a/src/window.c b/src/window.c index e025e0b082..eb16e2a433 100644 --- a/src/window.c +++ b/src/window.c @@ -2260,7 +2260,7 @@ return value is a list of elements of the form (PARAMETER . VALUE). */) Lisp_Object window_parameter (struct window *w, Lisp_Object parameter) { - Lisp_Object result = Fassq (parameter, w->window_parameters); + Lisp_Object result = assq_no_quit (parameter, w->window_parameters); return CDR_SAFE (result); } commit 849fe71de7b041c21cb776c7428c39e0ce67df14 Author: Fabrice Bauzac Date: Mon Jan 18 23:02:21 2021 +0100 Sort Ibuffer filename/process column as displayed * lisp/ibuf-ext.el (ibuffer-do-sort-by-filename/process): Use the same function for sorting and for displaying the filename/process (Bug#45800). Copyright-paperwork-exempt: yes diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el index ed5c9c0211..44574abd46 100644 --- a/lisp/ibuf-ext.el +++ b/lisp/ibuf-ext.el @@ -1497,10 +1497,10 @@ Ordering is lexicographic." (string-lessp ;; FIXME: For now just compare the file name and the process name ;; (if it exists). Is there a better way to do this? - (or (buffer-file-name (car a)) + (or (with-current-buffer (car a) (ibuffer-buffer-file-name)) (let ((pr-a (get-buffer-process (car a)))) (and (processp pr-a) (process-name pr-a)))) - (or (buffer-file-name (car b)) + (or (with-current-buffer (car b) (ibuffer-buffer-file-name)) (let ((pr-b (get-buffer-process (car b)))) (and (processp pr-b) (process-name pr-b)))))) commit 8b33b76eb9fbb857bccbe3d223c961c486e4e8f9 Author: Lars Ingebrigtsen Date: Wed Jan 20 05:44:16 2021 +0100 Revert "Make `symbol-at-point' work in buffers with no symbols" This reverts commit 40a5df81434ce02fba01779256b50976fb74da4f. This fails when a point is after a symbol, and there's nothing else in the buffer. diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el index 69c23c3543..d3ba941fcc 100644 --- a/lisp/thingatpt.el +++ b/lisp/thingatpt.el @@ -218,14 +218,6 @@ The bounds of THING are determined by `bounds-of-thing-at-point'." (put 'sexp 'beginning-op 'thing-at-point--beginning-of-sexp) -;; Symbols - -(put 'symbol 'end-op 'thing-at-point--end-of-symbol) - -(defun thing-at-point--end-of-symbol () - "Move point to the end of the current symbol." - (re-search-forward "\\(\\sw\\|\\s_\\)+")) - ;; Lists (put 'list 'bounds-of-thing-at-point 'thing-at-point-bounds-of-list-at-point) diff --git a/test/lisp/thingatpt-tests.el b/test/lisp/thingatpt-tests.el index b7c315062f..c43c81af9f 100644 --- a/test/lisp/thingatpt-tests.el +++ b/test/lisp/thingatpt-tests.el @@ -146,18 +146,4 @@ position to retrieve THING.") (should (thing-at-point-looking-at "2abcd")) (should (equal (match-data) m2))))) -(ert-deftest test-narrow-buffer-symbol () - (with-temp-buffer - (insert "foo bar zot") - (goto-char 5) - (should (equal (symbol-at-point) 'bar))) - (with-temp-buffer - (insert "`[[`(") - (goto-char 2) - (should (equal (symbol-at-point) nil))) - (with-temp-buffer - (insert "aa `[[`(") - (goto-char 4) - (should (equal (symbol-at-point) nil)))) - ;;; thingatpt.el ends here commit c502cdd2b71f396b202e22103cd8aa5b0796fdab Author: Lars Ingebrigtsen Date: Wed Jan 20 05:08:56 2021 +0100 Don't add Content-Type when ceasing an rmail edit * lisp/mail/rmailedit.el (rmail-cease-edit): Take an optional parameter to avoid altering the message (bug#13327). (rmail-abort-edit): Use it. diff --git a/lisp/mail/rmailedit.el b/lisp/mail/rmailedit.el index 2680ed7f3a..c3b351d7bc 100644 --- a/lisp/mail/rmailedit.el +++ b/lisp/mail/rmailedit.el @@ -145,8 +145,9 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'. (declare-function rmail-summary-enable "rmailsum" ()) (declare-function rmail-summary-update-line "rmailsum" (n)) -(defun rmail-cease-edit () - "Finish editing message; switch back to Rmail proper." +(defun rmail-cease-edit (&optional abort) + "Finish editing message; switch back to Rmail proper. +If ABORT, this is the result of aborting an edit." (interactive) (if (rmail-summary-exists) (with-current-buffer rmail-summary-buffer @@ -271,6 +272,8 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'. ;; No match for rmail-mime-charset-pattern, but there was some ;; other Content-Type. We should not insert another. (Bug#4624) (content-type) + ;; Don't insert anything if aborting. + (abort) ((null old-coding) ;; If there was no charset= spec, insert one. (backward-char 1) @@ -352,7 +355,7 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'. (widen) (delete-region (point-min) (point-max)) (insert rmail-old-text) - (rmail-cease-edit) + (rmail-cease-edit t) (rmail-highlight-headers)) (defun rmail-edit-headers-alist (&optional widen markers) commit 40a5df81434ce02fba01779256b50976fb74da4f Author: Lars Ingebrigtsen Date: Wed Jan 20 04:44:18 2021 +0100 Make `symbol-at-point' work in buffers with no symbols * lisp/thingatpt.el (thing-at-point--end-of-symbol): New function (bug#14234). (symbol): Use it instead of `forward-symbol', because the latter will move to the end of the buffer even if there is no symbol there. Instead error out like `forward-sexp' and friends. diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el index d3ba941fcc..69c23c3543 100644 --- a/lisp/thingatpt.el +++ b/lisp/thingatpt.el @@ -218,6 +218,14 @@ The bounds of THING are determined by `bounds-of-thing-at-point'." (put 'sexp 'beginning-op 'thing-at-point--beginning-of-sexp) +;; Symbols + +(put 'symbol 'end-op 'thing-at-point--end-of-symbol) + +(defun thing-at-point--end-of-symbol () + "Move point to the end of the current symbol." + (re-search-forward "\\(\\sw\\|\\s_\\)+")) + ;; Lists (put 'list 'bounds-of-thing-at-point 'thing-at-point-bounds-of-list-at-point) diff --git a/test/lisp/thingatpt-tests.el b/test/lisp/thingatpt-tests.el index c43c81af9f..b7c315062f 100644 --- a/test/lisp/thingatpt-tests.el +++ b/test/lisp/thingatpt-tests.el @@ -146,4 +146,18 @@ position to retrieve THING.") (should (thing-at-point-looking-at "2abcd")) (should (equal (match-data) m2))))) +(ert-deftest test-narrow-buffer-symbol () + (with-temp-buffer + (insert "foo bar zot") + (goto-char 5) + (should (equal (symbol-at-point) 'bar))) + (with-temp-buffer + (insert "`[[`(") + (goto-char 2) + (should (equal (symbol-at-point) nil))) + (with-temp-buffer + (insert "aa `[[`(") + (goto-char 4) + (should (equal (symbol-at-point) nil)))) + ;;; thingatpt.el ends here commit 3bbec2eb2b2a48a0eaac8e83c27313bfbe9d420e Author: Lars Ingebrigtsen Date: Wed Jan 20 04:17:41 2021 +0100 Fix up example in the Modifying Menus node in the lispref manual * doc/lispref/keymaps.texi (Modifying Menus): Make the second example more regular (bug#14257). diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi index 37bab7ea9b..55d179b875 100644 --- a/doc/lispref/keymaps.texi +++ b/doc/lispref/keymaps.texi @@ -2852,9 +2852,8 @@ Here is how to insert an item called @samp{Work} in the @samp{Signals} menu of Shell mode, after the item @code{break}: @example -(define-key-after - (lookup-key shell-mode-map [menu-bar signals]) - [work] '("Work" . work-command) 'break) +(define-key-after shell-mode-map [menu-bar signals work] + '("Work" . work-command) 'break) @end example @end defun commit f925aabcceb353f04e4d2507b6d05eb74822f83b Author: Lars Ingebrigtsen Date: Wed Jan 20 03:54:18 2021 +0100 Mention that the mouse will switch on transient-mark-mode in manual * doc/lispref/markers.texi (The Mark): Mention that the mouse will enable the `(only)' transient mark mode (bug#14945). diff --git a/doc/lispref/markers.texi b/doc/lispref/markers.texi index cdd0938b45..b39373f072 100644 --- a/doc/lispref/markers.texi +++ b/doc/lispref/markers.texi @@ -560,7 +560,9 @@ deactivate the mark. If the value is @w{@code{(only . @var{oldval})}}, then @code{transient-mark-mode} is set to the value @var{oldval} after any subsequent command that moves point and is not shift-translated (@pxref{Key Sequence Input, shift-translation}), or after any other -action that would normally deactivate the mark. +action that would normally deactivate the mark. (Marking a region +with the mouse will temporarily enable @code{transient-mark-mode} in +this way.) @end defopt @defopt mark-even-if-inactive commit 5aff1bfdaf6fb64b50087c93f212faa18fbe17fb Author: Lars Ingebrigtsen Date: Wed Jan 20 03:25:46 2021 +0100 Make sh-mode use `auto-mode-interpreter-regexp' * lisp/progmodes/sh-script.el (sh-mode): Use `auto-mode-interpreter-regexp' instead of open-coding the value (bug#17158). diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index a417de3264..d3692d4720 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -1556,7 +1556,7 @@ with your script for an edit-interpret-debug cycle." (sh-set-shell (cond ((save-excursion (goto-char (point-min)) - (looking-at "#![ \t]?\\([^ \t\n]*/bin/env[ \t]\\)?\\([^ \t\n]+\\)")) + (looking-at auto-mode-interpreter-regexp)) (match-string 2)) ((not buffer-file-name) sh-shell-file) ;; Checks that use `buffer-file-name' follow. commit 5536893c6e629d9541c75a1b0b239eaa96c6eaeb Author: Nick Drozd Date: Wed Jan 20 02:46:17 2021 +0100 test/lisp/replace-tests.el: Add nested match group test * test/lisp/replace-tests.el (replace-regexp-bug45973): Add test (bug#45973). diff --git a/test/lisp/replace-tests.el b/test/lisp/replace-tests.el index 8c2682a1f1..2db570c97d 100644 --- a/test/lisp/replace-tests.el +++ b/test/lisp/replace-tests.el @@ -587,5 +587,18 @@ bound to HIGHLIGHT-LOCUS." (get-text-property (point) 'occur-target)) (should (funcall check-overlays has-overlay))))))) +(ert-deftest replace-regexp-bug45973 () + "Test for https://debbugs.gnu.org/45973 ." + (let ((before "1RB 1LC 1RC 1RB 1RD 0LE 1LA 1LD 1RH 0LA") + (after "1LB 1RC 1LC 1LB 1LD 0RE 1RA 1RD 1LH 0RA")) + (with-temp-buffer + (insert before) + (goto-char (point-min)) + (replace-regexp + "\\(\\(L\\)\\|\\(R\\)\\)" + '(replace-eval-replacement + replace-quote + (if (match-string 2) "R" "L"))) + (should (equal (buffer-string) after))))) ;;; replace-tests.el ends here commit 8ed97a8d543b9596166c670212265dabc44aa3d5 Author: Philipp Stephani Date: Tue Jan 19 21:35:06 2021 +0100 Make child signal read pipe non-blocking. Otherwise Emacs might hang when trying to read the pipe twice in a row. This is consistent with the other file descriptors we pass to 'pselect'. * src/process.c (child_signal_init): Make read end of pipe non-blocking. diff --git a/src/process.c b/src/process.c index 09f87908a4..57105982c1 100644 --- a/src/process.c +++ b/src/process.c @@ -7179,6 +7179,8 @@ child_signal_init (void) exits. */ eassert (0 <= fds[0]); eassert (0 <= fds[1]); + if (fcntl (fds[0], F_SETFL, O_NONBLOCK) != 0) + emacs_perror ("fcntl"); add_read_fd (fds[0], child_signal_read, NULL); fd_callback_info[fds[0]].flags &= ~KEYBOARD_FD; child_signal_read_fd = fds[0]; commit 8725f7690a44306f03d7cbb9eaa45590fcaf88db Author: Dmitry Gutov Date: Tue Jan 19 21:50:11 2021 +0200 Declare some project commands interactive-only * lisp/progmodes/project.el (project-async-shell-command) (project-shell-command, project-compile): Declare interactive-only (bug#45765). diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 06966f33b7..18124227d1 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -929,6 +929,7 @@ if one already exists." (defun project-async-shell-command () "Run `async-shell-command' in the current project's root directory." (interactive) + (declare (interactive-only async-shell-command)) (let ((default-directory (project-root (project-current t)))) (call-interactively #'async-shell-command))) @@ -936,6 +937,7 @@ if one already exists." (defun project-shell-command () "Run `shell-command' in the current project's root directory." (interactive) + (declare (interactive-only shell-command)) (let ((default-directory (project-root (project-current t)))) (call-interactively #'shell-command))) @@ -973,6 +975,7 @@ loop using the command \\[fileloop-continue]." (defun project-compile () "Run `compile' in the project root." (interactive) + (declare (interactive-only compile)) (let ((default-directory (project-root (project-current t)))) (call-interactively #'compile))) commit eec059b124ed57956cf896904ef8240b24cc7ead Author: Juri Linkov Date: Tue Jan 19 20:27:29 2021 +0200 * lisp/help-fns.el: Move defvar keymap-name-history closer to where it's used. diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 7be2826361..da90519246 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -76,9 +76,6 @@ frame.") ;; costly, really). "Radix-tree representation replacing `definition-prefixes'.") -(defvar keymap-name-history nil - "History for input to `describe-keymap'.") - (defun help-definition-prefixes () "Return the up-to-date radix-tree form of `definition-prefixes'." (when (> (hash-table-count definition-prefixes) 0) @@ -1656,6 +1653,9 @@ in `describe-keymap'. See also `Searching the Active Keymaps'." (get-char-property (point) 'local-map) (current-local-map))))) +(defvar keymap-name-history nil + "History for input to `describe-keymap'.") + ;;;###autoload (defun describe-keymap (keymap) "Describe key bindings in KEYMAP. commit e718d3a84920f545b6a3540a3ba9c2ccd7eefdf7 Author: Juri Linkov Date: Tue Jan 19 20:12:47 2021 +0200 Better check for nil in search-/query-replace-highlight-submatches (bug#45973) * lisp/isearch.el (isearch-highlight): * lisp/replace.el (replace-highlight): Use integer-or-marker-p to check matches. diff --git a/lisp/isearch.el b/lisp/isearch.el index c6f7fe7bd4..a86678572c 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -3757,23 +3757,27 @@ since they have special meaning in a regexp." (overlay-put isearch-overlay 'priority 1001) (overlay-put isearch-overlay 'face isearch-face))) - (when (and search-highlight-submatches - isearch-regexp) + (when (and search-highlight-submatches isearch-regexp) (mapc 'delete-overlay isearch-submatches-overlays) (setq isearch-submatches-overlays nil) - (let ((submatch-data (cddr (butlast match-data))) + ;; 'cddr' removes whole expression match from match-data + (let ((submatch-data (cddr match-data)) (group 0) - ov face) + b e ov face) (while submatch-data - (setq group (1+ group)) - (setq ov (make-overlay (pop submatch-data) (pop submatch-data)) - face (intern-soft (format "isearch-group-%d" group))) - ;; Recycle faces from beginning. - (unless (facep face) - (setq group 1 face 'isearch-group-1)) - (overlay-put ov 'face face) - (overlay-put ov 'priority 1002) - (push ov isearch-submatches-overlays))))) + (setq b (pop submatch-data) + e (pop submatch-data)) + (when (and (integer-or-marker-p b) + (integer-or-marker-p e)) + (setq ov (make-overlay b e) + group (1+ group) + face (intern-soft (format "isearch-group-%d" group))) + ;; Recycle faces from beginning + (unless (facep face) + (setq group 1 face 'isearch-group-1)) + (overlay-put ov 'face face) + (overlay-put ov 'priority 1002) + (push ov isearch-submatches-overlays)))))) (defun isearch-dehighlight () (when isearch-overlay diff --git a/lisp/replace.el b/lisp/replace.el index 8f8cbfac54..db5b340631 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -2425,23 +2425,27 @@ It is called with three arguments, as if it were (overlay-put replace-overlay 'priority 1001) ;higher than lazy overlays (overlay-put replace-overlay 'face 'query-replace))) - (when (and query-replace-highlight-submatches - regexp-flag) + (when (and query-replace-highlight-submatches regexp-flag) (mapc 'delete-overlay replace-submatches-overlays) (setq replace-submatches-overlays nil) - (let ((submatch-data (cddr (butlast (match-data t)))) + ;; 'cddr' removes whole expression match from match-data + (let ((submatch-data (cddr (match-data t))) (group 0) - ov face) + b e ov face) (while submatch-data - (setq group (1+ group)) - (setq ov (make-overlay (pop submatch-data) (pop submatch-data)) - face (intern-soft (format "isearch-group-%d" group))) - ;; Recycle faces from beginning. - (unless (facep face) - (setq group 1 face 'isearch-group-1)) - (overlay-put ov 'face face) - (overlay-put ov 'priority 1002) - (push ov replace-submatches-overlays)))) + (setq b (pop submatch-data) + e (pop submatch-data)) + (when (and (integer-or-marker-p b) + (integer-or-marker-p e)) + (setq ov (make-overlay b e) + group (1+ group) + face (intern-soft (format "isearch-group-%d" group))) + ;; Recycle faces from beginning + (unless (facep face) + (setq group 1 face 'isearch-group-1)) + (overlay-put ov 'face face) + (overlay-put ov 'priority 1002) + (push ov replace-submatches-overlays))))) (if query-replace-lazy-highlight (let ((isearch-string search-string) commit 1248c67484d599b36e094f0e641c82482fd269ce Author: Ted Zlatanov Date: Tue Jan 19 13:35:07 2021 +0000 * test/infra/gitlab-ci.yml: Bootstrap only from web, schedule, or C-related. diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml index 3214f01edd..ddabacfe01 100644 --- a/test/infra/gitlab-ci.yml +++ b/test/infra/gitlab-ci.yml @@ -49,6 +49,8 @@ variables: # DOCKER_TLS_CERTDIR: "/certs" # Put the configuration for each run in a separate directory to avoid conflicts DOCKER_CONFIG: "/.docker-config-${CI_COMMIT_SHA}" + # We don't use ${CI_COMMIT_SHA} to be able to do one bootstrap across multiple builds + BUILD_TAG: ${CI_COMMIT_REF_SLUG} default: image: docker:19.03.12 @@ -96,17 +98,42 @@ default: # - "**/*.log" # using the variables for each job script: - - docker pull ${CI_REGISTRY_IMAGE}:${target}-${CI_COMMIT_SHA} + - docker pull ${CI_REGISTRY_IMAGE}:${target}-${BUILD_TAG} # TODO: with make -j4 several of the tests were failing, for example shadowfile-tests, but passed without it - - docker run -i --rm -e EMACS_EMBA_CI=${EMACS_EMBA_CI} ${CI_REGISTRY_IMAGE}:${target}-${CI_COMMIT_SHA} make ${make_params} + - docker run -i --rm -e EMACS_EMBA_CI=${EMACS_EMBA_CI} ${CI_REGISTRY_IMAGE}:${target}-${BUILD_TAG} make ${make_params} .build-template: + rules: + - if: '$CI_PIPELINE_SOURCE == "web"' + when: always + - changes: + - "**/Makefile.in" + - .gitlab-ci.yml + - aclocal.m4 + - autogen.sh + - configure.ac + - lib/*.{h,c} + - lisp/emacs-lisp/*.el + - src/*.{h,c} + - test/infra/* + - changes: + # gfilemonitor, kqueue + - src/gfilenotify.c + - src/kqueue.c + # MS Windows + - "**/w32*" + # GNUstep + - lisp/term/ns-win.el + - src/ns*.{h,m} + - src/macfont.{h,m} + when: never script: - - docker build --pull --target ${target} -t ${CI_REGISTRY_IMAGE}:${target}-${CI_COMMIT_SHA} -f test/infra/Dockerfile.emba . - - docker push ${CI_REGISTRY_IMAGE}:${target}-${CI_COMMIT_SHA} + - docker build --pull --target ${target} -t ${CI_REGISTRY_IMAGE}:${target}-${BUILD_TAG} -f test/infra/Dockerfile.emba . + - docker push ${CI_REGISTRY_IMAGE}:${target}-${BUILD_TAG} .gnustep-template: rules: + - if: '$CI_PIPELINE_SOURCE == "web"' - if: '$CI_PIPELINE_SOURCE == "schedule"' changes: - "**/Makefile.in" @@ -120,6 +147,7 @@ default: .filenotify-gio-template: rules: + - if: '$CI_PIPELINE_SOURCE == "web"' - if: '$CI_PIPELINE_SOURCE == "schedule"' changes: - "**/Makefile.in" @@ -208,6 +236,7 @@ test-all-inotify: extends: [.job-template] rules: # note there's no "changes" section, so this always runs on a schedule + - if: '$CI_PIPELINE_SOURCE == "web"' - if: '$CI_PIPELINE_SOURCE == "schedule"' variables: target: emacs-inotify commit bfa140d7cf82ed640d033391cde505ab020de0f2 Author: Mattias Engdegård Date: Sat Jan 16 17:30:57 2021 +0100 Calc: use Unicode brackets in Big mode when available (bug#45917) * lisp/calc/calccomp.el (math--big-bracket-alist) (math--big-bracket, math--comp-bracket, math--comp-round-bracket): New. (math-compose-expr, math-compose-log, math-compose-log10) (math-compose-choose, math-compose-integ, math-compose-sum) (math-compose-prod): Use big brackets when available. diff --git a/lisp/calc/calccomp.el b/lisp/calc/calccomp.el index 07e70cad0a..5f38ee71c7 100644 --- a/lisp/calc/calccomp.el +++ b/lisp/calc/calccomp.el @@ -138,19 +138,19 @@ (math-format-number (nth 2 aa)))))) (if (= calc-number-radix 10) c - (list 'horiz "(" c - (list 'subscr ")" - (int-to-string calc-number-radix))))) + (list 'subscr (math--comp-round-bracket c) + (int-to-string calc-number-radix)))) (math-format-number a))) (if (not (eq calc-language 'big)) (math-format-number a prec) (if (memq (car-safe a) '(cplx polar)) (if (math-zerop (nth 2 a)) (math-compose-expr (nth 1 a) prec) - (list 'horiz "(" - (math-compose-expr (nth 1 a) 0) - (if (eq (car a) 'cplx) ", " "; ") - (math-compose-expr (nth 2 a) 0) ")")) + (math--comp-round-bracket + (list 'horiz + (math-compose-expr (nth 1 a) 0) + (if (eq (car a) 'cplx) ", " "; ") + (math-compose-expr (nth 2 a) 0)))) (if (or (= calc-number-radix 10) (not (Math-realp a)) (and calc-group-digits @@ -340,12 +340,13 @@ (funcall spfn a prec) (math-compose-var a))))) ((eq (car a) 'intv) - (list 'horiz - (if (memq (nth 1 a) '(0 1)) "(" "[") - (math-compose-expr (nth 2 a) 0) - " .. " - (math-compose-expr (nth 3 a) 0) - (if (memq (nth 1 a) '(0 2)) ")" "]"))) + (math--comp-bracket + (if (memq (nth 1 a) '(0 1)) ?\( ?\[) + (if (memq (nth 1 a) '(0 2)) ?\) ?\]) + (list 'horiz + (math-compose-expr (nth 2 a) 0) + " .. " + (math-compose-expr (nth 3 a) 0)))) ((eq (car a) 'date) (if (eq (car calc-date-format) 'X) (math-format-date a) @@ -377,7 +378,7 @@ (and (eq (car-safe (nth 1 a)) 'cplx) (math-negp (nth 1 (nth 1 a))) (eq (nth 2 (nth 1 a)) 0))) - (list 'horiz "(" (math-compose-expr (nth 1 a) 0) ")") + (math--comp-round-bracket (math-compose-expr (nth 1 a) 0)) (math-compose-expr (nth 1 a) 201)) (let ((calc-language 'flat) (calc-number-radix 10) @@ -444,7 +445,7 @@ (if (> prec (nth 2 a)) (if (setq spfn (get calc-language 'math-big-parens)) (list 'horiz (car spfn) c (cdr spfn)) - (list 'horiz "(" c ")")) + (math--comp-round-bracket c)) c))) ((and (eq (car a) 'calcFunc-choriz) (not (eq calc-language 'unform)) @@ -612,7 +613,7 @@ (list 'horiz "{left ( " (math-compose-expr a -1) " right )}"))) - (list 'horiz "(" (math-compose-expr a 0) ")")))) + (math--comp-round-bracket (math-compose-expr a 0))))) ((and (memq calc-language '(tex latex)) (memq (car a) '(/ calcFunc-choose calcFunc-evalto)) (>= prec 0)) @@ -638,7 +639,7 @@ (rhs (math-compose-expr (nth 2 a) (nth 3 op) (eq (nth 1 op) '/)))) (and (equal (car op) "^") (eq (math-comp-first-char lhs) ?-) - (setq lhs (list 'horiz "(" lhs ")"))) + (setq lhs (math--comp-round-bracket lhs))) (and (memq calc-language '(tex latex)) (or (equal (car op) "^") (equal (car op) "_")) (not (and (stringp rhs) (= (length rhs) 1))) @@ -721,7 +722,7 @@ (list 'horiz "{left ( " (math-compose-expr a -1) " right )}"))) - (list 'horiz "(" (math-compose-expr a 0) ")")))) + (math--comp-round-bracket (math-compose-expr a 0))))) (t (let ((lhs (math-compose-expr (nth 1 a) (nth 2 op)))) (list 'horiz @@ -759,7 +760,7 @@ (list 'horiz "{left ( " (math-compose-expr a -1) " right )}"))) - (list 'horiz "(" (math-compose-expr a 0) ")")))) + (math--comp-round-bracket (math-compose-expr a 0))))) (t (let ((rhs (math-compose-expr (nth 1 a) (nth 3 op)))) (list 'horiz @@ -966,6 +967,69 @@ (and (memq (car a) '(^ calcFunc-subscr)) (math-tex-expr-is-flat (nth 1 a))))) +;; FIXME: maybe try box drawing chars if big bracket chars are unavailable, +;; like ┌ ┐n +;; │a + b│ ┌ a + b ┐n +;; │-----│ or │ ----- │ ? +;; │ c │ └ c ┘ +;; └ ┘ +;; They are more common than the chars below, but look a bit square. +;; Rounded corners exist but are less commonly available. + +(defconst math--big-bracket-alist + '((?\( . (?⎛ ?⎝ ?⎜)) + (?\) . (?⎞ ?⎠ ?⎟)) + (?\[ . (?⎡ ?⎣ ?⎢)) + (?\] . (?⎤ ?⎦ ?⎥)) + (?\{ . (?⎧ ?⎩ ?⎪ ?⎨)) + (?\} . (?⎫ ?⎭ ?⎪ ?⎬))) + "Alist mapping bracket chars to (UPPER LOWER EXTENSION MIDPIECE). +Not all brackets have midpieces.") + +(defun math--big-bracket (bracket-char height baseline) + "Composition for BRACKET-CHAR of HEIGHT with BASELINE." + (if (<= height 1) + (char-to-string bracket-char) + (let ((pieces (cdr (assq bracket-char math--big-bracket-alist)))) + (if (memq nil (mapcar #'char-displayable-p pieces)) + (char-to-string bracket-char) + (let* ((upper (nth 0 pieces)) + (lower (nth 1 pieces)) + (extension (nth 2 pieces)) + (midpiece (nth 3 pieces))) + (cons 'vleft ; alignment doesn't matter; width is 1 char + (cons baseline + (mapcar + #'char-to-string + (append + (list upper) + (if midpiece + (let ((lower-ext (/ (- height 3) 2))) + (append + (make-list (- height 3 lower-ext) extension) + (list midpiece) + (make-list lower-ext extension))) + (make-list (- height 2) extension)) + (list lower)))))))))) + +(defun math--comp-bracket (left-bracket right-bracket comp) + "Put the composition COMP inside LEFT-BRACKET and RIGHT-BRACKET." + (if (eq calc-language 'big) + (let ((height (math-comp-height comp)) + (baseline (1- (math-comp-ascent comp)))) + (list 'horiz + (math--big-bracket left-bracket height baseline) + comp + (math--big-bracket right-bracket height baseline))) + (list 'horiz + (char-to-string left-bracket) + comp + (char-to-string right-bracket)))) + +(defun math--comp-round-bracket (comp) + "Put the composition COMP inside plain brackets." + (math--comp-bracket ?\( ?\) comp)) + (put 'calcFunc-log 'math-compose-big #'math-compose-log) (defun math-compose-log (a _prec) (and (= (length a) 3) @@ -973,18 +1037,14 @@ (list 'subscr "log" (let ((calc-language 'flat)) (math-compose-expr (nth 2 a) 1000))) - "(" - (math-compose-expr (nth 1 a) 1000) - ")"))) + (math--comp-round-bracket (math-compose-expr (nth 1 a) 1000))))) (put 'calcFunc-log10 'math-compose-big #'math-compose-log10) (defun math-compose-log10 (a _prec) (and (= (length a) 2) (list 'horiz - (list 'subscr "log" "10") - "(" - (math-compose-expr (nth 1 a) 1000) - ")"))) + (list 'subscr "log" "10") + (math--comp-round-bracket (math-compose-expr (nth 1 a) 1000))))) (put 'calcFunc-deriv 'math-compose-big #'math-compose-deriv) (put 'calcFunc-tderiv 'math-compose-big #'math-compose-deriv) @@ -1027,12 +1087,9 @@ (defun math-compose-choose (a _prec) (let ((a1 (math-compose-expr (nth 1 a) 0)) (a2 (math-compose-expr (nth 2 a) 0))) - (list 'horiz - "(" - (list 'vcent - (math-comp-height a1) - a1 " " a2) - ")"))) + (math--comp-round-bracket (list 'vcent + (+ (math-comp-height a1)) + a1 " " a2)))) (put 'calcFunc-integ 'math-compose-big #'math-compose-integ) (defun math-compose-integ (a prec) @@ -1052,9 +1109,12 @@ "d%s" (nth 1 (nth 2 a))))) (nth 1 a)) 185)) - (calc-language 'flat) - (low (and (nth 3 a) (math-compose-expr (nth 3 a) 0))) - (high (and (nth 4 a) (math-compose-expr (nth 4 a) 0))) + (low (and (nth 3 a) + (let ((calc-language 'flat)) + (math-compose-expr (nth 3 a) 0)))) + (high (and (nth 4 a) + (let ((calc-language 'flat)) + (math-compose-expr (nth 4 a) 0)))) ;; Check if we have Unicode integral top/bottom parts. (fancy (and (char-displayable-p ?⌠) (char-displayable-p ?⌡))) @@ -1066,40 +1126,47 @@ ((char-displayable-p ?│) "│ ") ;; U+007C VERTICAL LINE (t "| ")))) - (list 'horiz - (if parens "(" "") - (append (list 'vcent (if fancy - (if high 2 1) - (if high 3 2))) - (and high (list (if fancy - (list 'horiz high " ") - (list 'horiz " " high)))) - (if fancy - (list "⌠ " fancy-stem "⌡ ") - '(" /" - " | " - " | " - " | " - "/ ")) - (and low (list (if fancy - (list 'horiz low " ") - (list 'horiz low " "))))) - expr - (if over - "" - (list 'horiz " d" var)) - (if parens ")" ""))))) + (let ((comp + (list 'horiz + (append (list 'vcent (if fancy + (if high 2 1) + (if high 3 2))) + (and high (list (if fancy + (list 'horiz high " ") + (list 'horiz " " high)))) + (if fancy + (list "⌠ " fancy-stem "⌡ ") + '(" /" + " | " + " | " + " | " + "/ ")) + (and low (list (if fancy + (list 'horiz low " ") + (list 'horiz low " "))))) + expr + (if over + "" + (list 'horiz " d" var))))) + (if parens + (math--comp-round-bracket comp) + comp))))) (put 'calcFunc-sum 'math-compose-big #'math-compose-sum) (defun math-compose-sum (a prec) (and (memq (length a) '(3 5 6)) (let* ((expr (math-compose-expr (nth 1 a) 185)) - (calc-language 'flat) - (var (math-compose-expr (nth 2 a) 0)) - (low (and (nth 3 a) (math-compose-expr (nth 3 a) 0))) - (high (and (nth 4 a) (math-compose-vector (nthcdr 4 a) ", " 0)))) - (list 'horiz - (if (memq prec '(180 201)) "(" "") + (var + (let ((calc-language 'flat)) + (math-compose-expr (nth 2 a) 0))) + (low (and (nth 3 a) + (let ((calc-language 'flat)) + (math-compose-expr (nth 3 a) 0)))) + (high (and (nth 4 a) + (let ((calc-language 'flat)) + (math-compose-vector (nthcdr 4 a) ", " 0)))) + (comp + (list 'horiz (append (list 'vcent (if high 3 2)) (and high (list high)) '("---- " @@ -1112,32 +1179,42 @@ (list var))) (if (memq (car-safe (nth 1 a)) '(calcFunc-sum calcFunc-prod)) " " "") - expr - (if (memq prec '(180 201)) ")" ""))))) + expr))) + (if (memq prec '(180 201)) + (math--comp-round-bracket comp) + comp)))) (put 'calcFunc-prod 'math-compose-big #'math-compose-prod) (defun math-compose-prod (a prec) (and (memq (length a) '(3 5 6)) (let* ((expr (math-compose-expr (nth 1 a) 198)) - (calc-language 'flat) - (var (math-compose-expr (nth 2 a) 0)) - (low (and (nth 3 a) (math-compose-expr (nth 3 a) 0))) - (high (and (nth 4 a) (math-compose-vector (nthcdr 4 a) ", " 0)))) - (list 'horiz - (if (memq prec '(196 201)) "(" "") - (append (list 'vcent (if high 3 2)) - (and high (list high)) - '("----- " - " | | " - " | | " - " | | ") - (if low - (list (list 'horiz var " = " low)) - (list var))) - (if (memq (car-safe (nth 1 a)) '(calcFunc-sum calcFunc-prod)) - " " "") - expr - (if (memq prec '(196 201)) ")" ""))))) + (var + (let ((calc-language 'flat)) + (math-compose-expr (nth 2 a) 0))) + (low (and (nth 3 a) + (let ((calc-language 'flat)) + (math-compose-expr (nth 3 a) 0)))) + (high (and (nth 4 a) + (let ((calc-language 'flat)) + (math-compose-vector (nthcdr 4 a) ", " 0)))) + (comp + (list 'horiz + (append (list 'vcent (if high 3 2)) + (and high (list high)) + '("----- " + " | | " + " | | " + " | | ") + (if low + (list (list 'horiz var " = " low)) + (list var))) + (if (memq (car-safe (nth 1 a)) + '(calcFunc-sum calcFunc-prod)) + " " "") + expr))) + (if (memq prec '(196 201)) + (math--comp-round-bracket comp) + comp)))) ;; The variables math-svo-c, math-svo-wid and math-svo-off are local ;; to math-stack-value-offset in calc.el, but are used by commit 039ab602cbf877eef1b18c6ef8b36dcf52ece5c4 Author: Stefan Monnier Date: Tue Jan 19 12:53:42 2021 -0500 * etc/NEWS.19: Add entry for `indent-line-to` * lisp/version.el (emacs-major-version, emacs-minor-version): Remove redundant version info already displayed by `C-h o`. diff --git a/etc/NEWS.19 b/etc/NEWS.19 index 43235e0e15..f2cef62971 100644 --- a/etc/NEWS.19 +++ b/etc/NEWS.19 @@ -2824,6 +2824,8 @@ the text of the region according to the new value. the fill-column has been exceeded; the function can determine on its own whether filling (or justification) is necessary. +**** New helper function 'indent-line-to' + ** Processes *** process-tty-name is a new function that returns the name of the diff --git a/lisp/version.el b/lisp/version.el index fcfc2f8b80..3a3093fdd4 100644 --- a/lisp/version.el +++ b/lisp/version.el @@ -29,14 +29,12 @@ (defconst emacs-major-version (progn (string-match "^[0-9]+" emacs-version) (string-to-number (match-string 0 emacs-version))) - "Major version number of this version of Emacs. -This variable first existed in version 19.23.") + "Major version number of this version of Emacs.") (defconst emacs-minor-version (progn (string-match "^[0-9]+\\.\\([0-9]+\\)" emacs-version) (string-to-number (match-string 1 emacs-version))) - "Minor version number of this version of Emacs. -This variable first existed in version 19.23.") + "Minor version number of this version of Emacs.") (defconst emacs-build-system (system-name) "Name of the system on which Emacs was built, or nil if not available.") commit f3b9d5b3155fac293d46e55827a1e0ce07afb0ae Author: Michael Albinus Date: Tue Jan 19 18:45:55 2021 +0100 Some Tramp fixes, resulting from test campaign * doc/misc/tramp.texi (Remote shell setup): Clarifications for `tramp-actions-before-shell' example. * lisp/net/tramp-sh.el (tramp-sh-handle-insert-directory): Do not expand FILENAME explicitely. (tramp-open-shell): Add "-i" for interactive shells. * test/lisp/net/tramp-tests.el (tramp-test07-file-exists-p) (tramp-test14-delete-directory) (tramp-test43-asynchronous-requests): Skip for MS windows. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 2c4b792cc2..e9ffd6a8c4 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -2369,8 +2369,7 @@ that can identify such questions using @lisp @group (defconst my-tramp-prompt-regexp - (concat (regexp-opt '("Enter the birth date of your mother:") t) - "\\s-*") + "Enter the birth date of your mother:\\s-*" "Regular expression matching my login prompt question.") @end group @@ -2389,6 +2388,11 @@ that can identify such questions using @end group @end lisp +The regular expressions used in @code{tramp-actions-before-shell} must +match the end of the connection buffer. Due to performance reasons, +this search starts at the end of the buffer, and it is limited to 256 +characters backwards. + @item Conflicting names for users and variables in @file{.profile} diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index e8ee372cb2..618a9fb9d0 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -2608,12 +2608,11 @@ The method used must be an out-of-band method." (defun tramp-sh-handle-insert-directory (filename switches &optional wildcard full-directory-p) "Like `insert-directory' for Tramp files." - (setq filename (expand-file-name filename)) (unless switches (setq switches "")) ;; Check, whether directory is accessible. (unless wildcard (access-file filename "Reading directory")) - (with-parsed-tramp-file-name filename nil + (with-parsed-tramp-file-name (expand-file-name filename) nil (if (and (featurep 'ls-lisp) (not (symbol-value 'ls-lisp-use-insert-directory-program))) (tramp-handle-insert-directory @@ -4306,11 +4305,14 @@ file exists and nonzero exit status otherwise." ;; ensure they have the correct values when the shell starts, not ;; just processes run within the shell. (Which processes include ;; our initial probes to ensure the remote shell is usable.) + ;; For the time being, we assume that all shells interpret -i as + ;; interactive shell. Must be the last argument, because (for + ;; example) bash expects long options first. (tramp-send-command vec (format (concat "exec env TERM='%s' INSIDE_EMACS='%s,tramp:%s' " - "ENV=%s %s PROMPT_COMMAND='' PS1=%s PS2='' PS3='' %s %s") + "ENV=%s %s PROMPT_COMMAND='' PS1=%s PS2='' PS3='' %s %s -i") tramp-terminal-type (or (getenv "INSIDE_EMACS") emacs-version) tramp-version (or (getenv-internal "ENV" tramp-remote-process-environment) "") diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index ef0968a338..5deee65829 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -2272,8 +2272,8 @@ This checks also `file-name-as-directory', `file-name-directory', (delete-file tmp-name) (should-not (file-exists-p tmp-name)) - ;; Trashing files doesn't work for crypted remote files. - (unless (tramp--test-crypt-p) + ;; Trashing files doesn't work on MS Windows, and for crypted remote files. + (unless (or (tramp--test-windows-nt-p) (tramp--test-crypt-p)) (let ((trash-directory (tramp--test-make-temp-name 'local quoted)) (delete-by-moving-to-trash t)) (make-directory trash-directory) @@ -2786,9 +2786,9 @@ This tests also `file-directory-p' and `file-accessible-directory-p'." (should-not (file-directory-p tmp-name1)) ;; Trashing directories works only since Emacs 27.1. It doesn't - ;; work for crypted remote directories and for ange-ftp. - (when (and (not (tramp--test-crypt-p)) (not (tramp--test-ftp-p)) - (tramp--test-emacs27-p)) + ;; work on MS Windows, for crypted remote directories and for ange-ftp. + (when (and (not (tramp--test-windows-nt-p)) (not (tramp--test-crypt-p)) + (not (tramp--test-ftp-p)) (tramp--test-emacs27-p)) (let ((trash-directory (tramp--test-make-temp-name 'local quoted)) (delete-by-moving-to-trash t)) (make-directory trash-directory) @@ -6349,6 +6349,7 @@ process sentinels. They shall not disturb each other." (tramp--test-sh-p))) (skip-unless (not (tramp--test-crypt-p))) (skip-unless (not (tramp--test-docker-p))) + (skip-unless (not (tramp--test-windows-nt-p))) (with-timeout (tramp--test-asynchronous-requests-timeout (tramp--test-timeout-handler)) @@ -6358,12 +6359,11 @@ process sentinels. They shall not disturb each other." (shell-file-name (if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh")) ;; It doesn't work on w32 systems. (watchdog - (unless (tramp--test-windows-nt-p) - (start-process-shell-command - "*watchdog*" nil - (format - "sleep %d; kill -USR1 %d" - tramp--test-asynchronous-requests-timeout (emacs-pid))))) + (start-process-shell-command + "*watchdog*" nil + (format + "sleep %d; kill -USR1 %d" + tramp--test-asynchronous-requests-timeout (emacs-pid)))) (tmp-name (tramp--test-make-temp-name)) (default-directory tmp-name) ;; Do not cache Tramp properties. commit deb90c893d3a0094db77753d8a795716784bbc7e Author: Stefan Monnier Date: Tue Jan 19 12:10:48 2021 -0500 * lisp/startup.el: Fix bug#45857, bug#30994, and bug#45913. (command-line): Don't re-evaluate the `custom-delayed-init-variables` a second time after reading the `early-init.el` file. (x-apply-session-resources): Set `blink-cursor-mode` rather than `no-blinking-cursor`. * lisp/frame.el (blink-cursor-start): Turn `blink-cursor-mode` off if `blink-cursor-mode` was set to nil. (blink-cursor-mode): Default to it being enabled regardless of `window-system`. * lisp/custom.el (custom-initialize-delay): Fox docstring now that autoload.el preserves the `:initialize` info. diff --git a/etc/NEWS b/etc/NEWS index 8fc5f3e046..7a012b4891 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -326,6 +326,10 @@ the buffer cycles the whole buffer between "only top-level headings", * Changes in Specialized Modes and Packages in Emacs 28.1 +** 'blink-cursor-mode' is now enabled by default regardless of the UI. +It used to be enabled when Emacs is started in GUI mode but not when started +in text mode. The cursor still only actually blinks in GUI frames. + ** pcase +++ *** The `pred` pattern can now take the form (pred (not FUN)). diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 0293d34d1c..27fdb72344 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -880,7 +880,7 @@ since it could result in memory overflow and make Emacs crash." ;; Don't re-add to custom-delayed-init-variables post-startup. (unless after-init-time ;; Note this is the _only_ initialize property we handle. - (if (eq (cadr (memq :initialize rest)) 'custom-initialize-delay) + (if (eq (cadr (memq :initialize rest)) #'custom-initialize-delay) ;; These vars are defined early and should hence be initialized ;; early, even if this file happens to be loaded late. so add them ;; to the end of custom-delayed-init-variables. Otherwise, diff --git a/lisp/custom.el b/lisp/custom.el index 58ecd0439a..5e354c4c59 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -125,17 +125,7 @@ This is used in files that are preloaded (or for autoloaded variables), so that the initialization is done in the run-time context rather than the build-time context. This also has the side-effect that the (delayed) initialization is performed with -the :set function. - -For variables in preloaded files, you can simply use this -function for the :initialize property. For autoloaded variables, -you will also need to add an autoload stanza calling this -function, and another one setting the standard-value property. -Or you can wrap the defcustom in a progn, to force the autoloader -to include all of it." ; see eg vc-sccs-search-project-dir - ;; No longer true: - ;; "See `send-mail-function' in sendmail.el for an example." - +the :set function." ;; Defvar it so as to mark it special, etc (bug#25770). (internal--define-uninitialized-variable symbol) diff --git a/lisp/frame.el b/lisp/frame.el index e2d7f21a49..06aab269dd 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -2552,13 +2552,15 @@ Use 0 or negative value to blink forever." This starts the timer `blink-cursor-timer', which makes the cursor blink if appropriate. It also arranges to cancel that timer when the next command starts, by installing a pre-command hook." - (when (null blink-cursor-timer) + (cond + ((null blink-cursor-mode) (blink-cursor-mode -1)) + ((null blink-cursor-timer) ;; Set up the timer first, so that if this signals an error, ;; blink-cursor-end is not added to pre-command-hook. (setq blink-cursor-blinks-done 1) (blink-cursor--start-timer) (add-hook 'pre-command-hook #'blink-cursor-end) - (internal-show-cursor nil nil))) + (internal-show-cursor nil nil)))) (defun blink-cursor-timer-function () "Timer function of timer `blink-cursor-timer'." @@ -2615,7 +2617,7 @@ stopped by `blink-cursor-suspend'. Internally calls `blink-cursor--should-blink' and returns its result." (let ((should-blink (blink-cursor--should-blink))) (when (and should-blink (not blink-cursor-idle-timer)) - (remove-hook 'post-command-hook 'blink-cursor-check) + (remove-hook 'post-command-hook #'blink-cursor-check) (blink-cursor--start-idle-timer)) should-blink)) @@ -2637,16 +2639,16 @@ This command is effective only on graphical frames. On text-only terminals, cursor blinking is controlled by the terminal." :init-value (not (or noninteractive no-blinking-cursor - (eq system-type 'ms-dos) - (not (display-blink-cursor-p)))) - :initialize 'custom-initialize-delay + (eq system-type 'ms-dos))) + :initialize #'custom-initialize-delay :group 'cursor :global t (blink-cursor-suspend) (remove-hook 'after-delete-frame-functions #'blink-cursor--rescan-frames) (remove-function after-focus-change-function #'blink-cursor--rescan-frames) (when blink-cursor-mode - (add-function :after after-focus-change-function #'blink-cursor--rescan-frames) + (add-function :after after-focus-change-function + #'blink-cursor--rescan-frames) (add-hook 'after-delete-frame-functions #'blink-cursor--rescan-frames) (blink-cursor-check))) diff --git a/lisp/startup.el b/lisp/startup.el index 552802a38d..7011fbf458 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -1172,6 +1172,7 @@ please check its value") ;; are dependencies between them. (nreverse custom-delayed-init-variables)) (mapc #'custom-reevaluate-setting custom-delayed-init-variables) + (setq custom-delayed-init-variables nil) ;; Warn for invalid user name. (when init-file-user @@ -1301,12 +1302,6 @@ please check its value") (startup--setup-quote-display) (setq internal--text-quoting-flag t)) - ;; Re-evaluate again the predefined variables whose initial value - ;; depends on the runtime context, in case some of them depend on - ;; the window-system features. Example: blink-cursor-mode. - (mapc #'custom-reevaluate-setting custom-delayed-init-variables) - (setq custom-delayed-init-variables nil) - (normal-erase-is-backspace-setup-frame) ;; Register default TTY colors for the case the terminal hasn't a @@ -1487,13 +1482,13 @@ to reading the init file), or afterwards when the user first opens a graphical frame. This can set the values of `menu-bar-mode', `tool-bar-mode', -`tab-bar-mode', and `no-blinking-cursor', as well as the `cursor' face. +`tab-bar-mode', and `blink-cursor-mode', as well as the `cursor' face. Changed settings will be marked as \"CHANGED outside of Customize\"." (let ((no-vals '("no" "off" "false" "0")) (settings '(("menuBar" "MenuBar" menu-bar-mode nil) ("toolBar" "ToolBar" tool-bar-mode nil) ("scrollBar" "ScrollBar" scroll-bar-mode nil) - ("cursorBlink" "CursorBlink" no-blinking-cursor t)))) + ("cursorBlink" "CursorBlink" blink-cursor-mode nil)))) (dolist (x settings) (if (member (x-get-resource (nth 0 x) (nth 1 x)) no-vals) (set (nth 2 x) (nth 3 x))))) commit 3c584438552f8d01651d7b9358eae5ce8da81fae Author: Lars Ingebrigtsen Date: Tue Jan 19 17:26:01 2021 +0100 Only show "2x entries" i vc log buffers if needed * lisp/vc/vc.el (vc-print-log-setup-buttons): Only show the "more" buttons if we got more or equal to the number of entries we asked for (bug#18959). diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 6c96d8ca7c..bc9f11202b 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -2392,6 +2392,7 @@ If it contains `file', show short logs for files. Not all VC backends support short logs!") (defvar log-view-vc-fileset) +(defvar log-view-message-re) (defun vc-print-log-setup-buttons (working-revision is-start-revision limit pl-return) "Insert at the end of the current buffer buttons to show more log entries. @@ -2401,21 +2402,32 @@ Does nothing if IS-START-REVISION is non-nil, or if LIMIT is nil, or if PL-RETURN is `limit-unsupported'." (when (and limit (not (eq 'limit-unsupported pl-return)) (not is-start-revision)) - (goto-char (point-max)) - (insert "\n") - (insert-text-button "Show 2X entries" - 'action (lambda (&rest _ignore) - (vc-print-log-internal - log-view-vc-backend log-view-vc-fileset - working-revision nil (* 2 limit))) - 'help-echo "Show the log again, and double the number of log entries shown") - (insert " ") - (insert-text-button "Show unlimited entries" - 'action (lambda (&rest _ignore) - (vc-print-log-internal - log-view-vc-backend log-view-vc-fileset - working-revision nil nil)) - 'help-echo "Show the log again, including all entries"))) + (let ((entries 0)) + (goto-char (point-min)) + (while (re-search-forward log-view-message-re nil t) + (cl-incf entries)) + ;; If we got fewer entries than we asked for, then displaying + ;; the "more" buttons isn't useful. + (when (>= entries limit) + (goto-char (point-max)) + (insert "\n") + (insert-text-button + "Show 2X entries" + 'action (lambda (&rest _ignore) + (vc-print-log-internal + log-view-vc-backend log-view-vc-fileset + working-revision nil (* 2 limit))) + 'help-echo + "Show the log again, and double the number of log entries shown") + (insert " ") + (insert-text-button + "Show unlimited entries" + 'action (lambda (&rest _ignore) + (vc-print-log-internal + log-view-vc-backend log-view-vc-fileset + working-revision nil nil)) + 'help-echo "Show the log again, including all entries") + (insert "\n"))))) (defun vc-print-log-internal (backend files working-revision &optional is-start-revision limit type) commit 5369b69bd86ee6d9565a82842cbeb37749cd5a6b Author: Mattias Engdegård Date: Tue Jan 19 11:55:13 2021 +0100 Parse square root sign in embedded Calc mode * lisp/calc/calc-lang.el (math-read-big-rec): Recognise √ since it may be used in Big mode. diff --git a/lisp/calc/calc-lang.el b/lisp/calc/calc-lang.el index b4b2d4cc4f..0117f449dd 100644 --- a/lisp/calc/calc-lang.el +++ b/lisp/calc/calc-lang.el @@ -2181,7 +2181,7 @@ order to Calc's." v math-read-big-baseline)) ;; Small radical sign. - ((and (= other-char ?V) + ((and (memq other-char '(?V ?√)) (= (math-read-big-char (1+ math-rb-h1) (1- v)) ?\_)) (setq h (1+ math-rb-h1)) (math-read-big-emptyp math-rb-h1 math-rb-v1 h (1- v) nil t) commit 297edbebec5eaf2924f65bd2015b65d16cbf9254 Author: Mattias Engdegård Date: Tue Jan 19 11:43:25 2021 +0100 Missing dynamic variable declarations in Calc * lisp/calc/calc-embed.el (calc-embedded-set-modes): Prevent the-language and the-display-just from being lexically bound here, because they may be assigned using 'set'. diff --git a/lisp/calc/calc-embed.el b/lisp/calc/calc-embed.el index ea79bfa69a..fda0b4bbed 100644 --- a/lisp/calc/calc-embed.el +++ b/lisp/calc/calc-embed.el @@ -651,6 +651,8 @@ The command \\[yank] can retrieve it from there." (defvar calc-embed-prev-modes) (defun calc-embedded-set-modes (gmodes modes local-modes &optional temp) + (defvar the-language) + (defvar the-display-just) (let ((the-language (calc-embedded-language)) (the-display-just (calc-embedded-justify)) (v gmodes) commit 3b731b123d11e4c13e2dd16b336b146081f94a30 Author: Lars Ingebrigtsen Date: Tue Jan 19 16:07:54 2021 +0100 Fix slow abbrev expansion in `message-mode' in some circumstances * lisp/gnus/message.el (message--syntax-propertize): Use the correct Message mode syntax table to avoid having `message-cite-prefix-regexp' trigger very heavy backtracing when called from an abbrev context (which defines "_" as a word constituent) (bug#45944). diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 50e0218748..b22b4543e7 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -3057,22 +3057,23 @@ See also `message-forbidden-properties'." (defun message--syntax-propertize (beg end) "Syntax-propertize certain message text specially." - (let ((citation-regexp (concat "^" message-cite-prefix-regexp ".*$")) - (smiley-regexp (regexp-opt message-smileys))) - (goto-char beg) - (while (search-forward-regexp citation-regexp - end 'noerror) - (let ((start (match-beginning 0)) - (end (match-end 0))) - (add-text-properties start (1+ start) - `(syntax-table ,(string-to-syntax "<"))) - (add-text-properties end (min (1+ end) (point-max)) - `(syntax-table ,(string-to-syntax ">"))))) - (goto-char beg) - (while (search-forward-regexp smiley-regexp - end 'noerror) - (add-text-properties (match-beginning 0) (match-end 0) - `(syntax-table ,(string-to-syntax ".")))))) + (with-syntax-table message-mode-syntax-table + (let ((citation-regexp (concat "^" message-cite-prefix-regexp ".*$")) + (smiley-regexp (regexp-opt message-smileys))) + (goto-char beg) + (while (search-forward-regexp citation-regexp + end 'noerror) + (let ((start (match-beginning 0)) + (end (match-end 0))) + (add-text-properties start (1+ start) + `(syntax-table ,(string-to-syntax "<"))) + (add-text-properties end (min (1+ end) (point-max)) + `(syntax-table ,(string-to-syntax ">"))))) + (goto-char beg) + (while (search-forward-regexp smiley-regexp + end 'noerror) + (add-text-properties (match-beginning 0) (match-end 0) + `(syntax-table ,(string-to-syntax "."))))))) ;;;###autoload (define-derived-mode message-mode text-mode "Message" commit e544b863433e37fbd2555d3b48da3a88a6307ddb Author: Lars Ingebrigtsen Date: Tue Jan 19 15:54:40 2021 +0100 Don't stop Gnus startup on password failures * lisp/gnus/nntp.el (nntp-send-authinfo): Don't signal an `nntp-authinfo-rejected' error, because that will stop Gnus startup (bug#45855). Instead signal an error that will be caught higher up. diff --git a/lisp/gnus/nntp.el b/lisp/gnus/nntp.el index 7e10e151a4..c2bb960f94 100644 --- a/lisp/gnus/nntp.el +++ b/lisp/gnus/nntp.el @@ -1209,7 +1209,7 @@ If SEND-IF-FORCE, only send authinfo to the server if the (read-passwd (format "NNTP (%s@%s) password: " user nntp-address))))))) (if (not result) - (signal 'nntp-authinfo-rejected "Password rejected") + (error "Password rejected") result)))))) ;;; Internal functions. commit 91a6e1933722439cb81ed58d655a8c62ee05009f Author: Michael Albinus Date: Tue Jan 19 14:12:22 2021 +0100 Handle also test/lib-src directory * test/Makefile.in (SUBDIRS): Add lib-src. * test/README: Add predefined selectors. * test/file-organization.org: Mention test/lib-src directory. diff --git a/test/Makefile.in b/test/Makefile.in index 4ca43c8c44..c5e86df376 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -247,7 +247,7 @@ endef $(foreach test,${TESTS},$(eval $(call test_template,${test}))) ## Get the tests for only a specific directory. -SUBDIRS = $(sort $(shell find lisp src -type d ! -path "*resources*" -print)) +SUBDIRS = $(sort $(shell find lib-src lisp src -type d ! -path "*resources*" -print)) define subdir_template .PHONY: check-$(subst /,-,$(1)) diff --git a/test/README b/test/README index 58f5f38bec..5f3c10adbe 100644 --- a/test/README +++ b/test/README @@ -60,7 +60,9 @@ https://www.gnu.org/software/emacs/manual/html_node/ert/Test-Selectors.html You could use predefined selectors of the Makefile. "make SELECTOR='$(SELECTOR_DEFAULT)'" runs all tests for .el -except the tests tagged as expensive or unstable. +except the tests tagged as expensive or unstable. Other predefined +selectors are $(SELECTOR_EXPENSIVE) (run all tests except unstable +ones) and $(SELECTOR_ALL) (run all tests). If your test file contains the tests "test-foo", "test2-foo" and "test-foo-remote", and you want to run only the former two tests, you diff --git a/test/file-organization.org b/test/file-organization.org index efc354529c..7cf5b88d6d 100644 --- a/test/file-organization.org +++ b/test/file-organization.org @@ -17,13 +17,15 @@ Sub-directories are in many cases themed after packages (~gnus~, ~org~, ~calc~), related functionality (~net~, ~emacs-lisp~, ~progmodes~) or status (~obsolete~). -C source is stored in the ~src~ directory, which is flat. +C source is stored in the ~src~ directory, which is flat. Source for +utility programs is stored in the ~lib-src~ directory. ** Test Files Automated tests should be stored in the ~test/lisp~ directory for -tests of functionality implemented in Lisp, and in the ~test/src~ -directory for functionality implemented in C. Tests should reflect +tests of functionality implemented in Lisp, in the ~test/src~ +directory for functionality implemented in C, and in the +~test/lib-src~ directory for utility programs. Tests should reflect the directory structure of the source tree; so tests for files in the ~lisp/emacs-lisp~ source directory should reside in the ~test/lisp/emacs-lisp~ directory. @@ -36,10 +38,10 @@ files of any name which are themselves placed in a directory named after the feature with ~-tests~ appended, such as ~/test/lisp/emacs-lisp/eieio-tests~ -Similarly, features implemented in C should reside in ~/test/src~ and -be named after the C file with ~-tests.el~ added to the base-name of -the tested source file. Thus, tests for ~src/fileio.c~ should be in -~test/src/fileio-tests.el~. +Similarly, tests of features implemented in C should reside in +~/test/src~ or in ~test/lib-src~ and be named after the C file with +~-tests.el~ added to the base-name of the tested source file. Thus, +tests for ~src/fileio.c~ should be in ~test/src/fileio-tests.el~. There are also some test materials that cannot be run automatically (i.e. via ert). These should be placed in ~/test/manual~; they are commit f2f06b020904e7d53af1e686a441887f24fb589c Author: Mauro Aranda Date: Tue Jan 19 09:25:00 2021 -0300 Fix list-colors-print handling of callback arg * lisp/facemenu.el (list-colors-print): Keeping backward-compatibility, don't fail when passed a closure object as CALLBACK. (Bug#45831) diff --git a/lisp/facemenu.el b/lisp/facemenu.el index 2609397b0d..dc5f8f46ab 100644 --- a/lisp/facemenu.el +++ b/lisp/facemenu.el @@ -606,9 +606,14 @@ color. The function should accept a single argument, the color name." (defun list-colors-print (list &optional callback) (let ((callback-fn - (if callback - `(lambda (button) - (funcall ,callback (button-get button 'color-name)))))) + ;; Expect CALLBACK to be a function, but allow it to be a form that + ;; evaluates to a function, for backward-compatibility. (Bug#45831) + (cond ((functionp callback) + (lambda (button) + (funcall callback (button-get button 'color-name)))) + (callback + `(lambda (button) + (funcall ,callback (button-get button 'color-name))))))) (dolist (color list) (if (consp color) (if (cdr color) commit 33ff86a20ab5a0b6a7ffe5056341334c4bcafca6 Author: Mauro Aranda Date: Tue Jan 19 09:11:37 2021 -0300 Add test for the widget-color-match function (Bug#45829) * test/lisp/wid-edit-tests.el (widget-test-color-match): New test. diff --git a/test/lisp/wid-edit-tests.el b/test/lisp/wid-edit-tests.el index 17fdfefce8..f843649784 100644 --- a/test/lisp/wid-edit-tests.el +++ b/test/lisp/wid-edit-tests.el @@ -322,4 +322,15 @@ return nil, even with a non-nil bubblep argument." (widget-backward 1) (should (string= "Second" (widget-value (widget-at)))))) +(ert-deftest widget-test-color-match () + "Test that the :match function for the color widget works." + (let ((widget (widget-convert 'color))) + (should (widget-apply widget :match "red")) + (should (widget-apply widget :match "#fa3")) + (should (widget-apply widget :match "#ff0000")) + (should (widget-apply widget :match "#111222333")) + (should (widget-apply widget :match "#111122223333")) + (should-not (widget-apply widget :match "someundefinedcolorihope")) + (should-not (widget-apply widget :match "#11223")))) + ;;; wid-edit-tests.el ends here commit ba0cf1d7017894ff9e539cba83881865b3a025a1 Author: Drew Adams Date: Tue Jan 19 09:11:18 2021 -0300 Tweaks to the color widget (Bug#45829) * lisp/wid-edit.el (widget-color-match, widget-color-validate): New functions. (color): Use the new functions. Base size on longest defined color name, defaulting to the longest RGB hex string. diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index 7dda04eda2..68a0d3d235 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el @@ -4026,17 +4026,19 @@ is inline." ;;; The `color' Widget. -;; Fixme: match (define-widget 'color 'editable-field "Choose a color name (with sample)." :format "%{%t%}: %v (%{sample%})\n" :value-create 'widget-color-value-create - :size 10 + :size (1+ (apply #'max 13 ; Longest RGB hex string. + (mapcar #'length (defined-colors)))) :tag "Color" :value "black" :completions (or facemenu-color-alist (defined-colors)) :sample-face-get 'widget-color-sample-face-get :notify 'widget-color-notify + :match #'widget-color-match + :validate #'widget-color-validate :action 'widget-color-action) (defun widget-color-value-create (widget) @@ -4085,6 +4087,19 @@ is inline." (overlay-put (widget-get widget :sample-overlay) 'face (widget-apply widget :sample-face-get)) (widget-default-notify widget child event)) + +(defun widget-color-match (_widget value) + "Non-nil if VALUE is a defined color or a RGB hex string." + (and (stringp value) + (or (color-defined-p value) + (string-match-p "^#\\(?:[[:xdigit:]]\\{3\\}\\)\\{1,4\\}$" value)))) + +(defun widget-color-validate (widget) + "Check that WIDGET's value is a valid color." + (let ((value (widget-value widget))) + (unless (widget-color-match widget value) + (widget-put widget :error (format "Invalid color: %S" value)) + widget))) ;;; The Help Echo commit b62a1e358befe996a4e2f4038ef48a9dd44901f8 Author: Protesilaos Stavrou Date: Tue Jan 19 08:11:39 2021 +0100 Add 'perl-non-scalar-variable' face to perl-mode * etc/NEWS: Document the new face (bug#45840). * lisp/progmodes/perl-mode.el (perl-non-scalar-variable): Define new face. (perl-font-lock-keywords-2): Apply 'perl-non-scalar-variable' face. diff --git a/etc/NEWS b/etc/NEWS index d632283e7f..8fc5f3e046 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -352,6 +352,12 @@ When emacsclient connects, Emacs will (by default) output a message about how to exit the client frame. If 'server-client-instructions' is set to nil, this message is inhibited. +** Perl mode + +--- +*** New face 'perl-non-scalar-variable'. +This is used to fontify non-scalar variables. + ** Python mode *** 'python-shell-interpreter' now defaults to python3 on systems with python3. diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el index 2a2a4978c6..d047dd543c 100644 --- a/lisp/progmodes/perl-mode.el +++ b/lisp/progmodes/perl-mode.el @@ -95,6 +95,12 @@ :prefix "perl-" :group 'languages) +(defface perl-non-scalar-variable + '((t :inherit font-lock-variable-name-face :underline t)) + "Face used for non-scalar variables." + :version "28.1" + :group 'perl) + (defvar perl-mode-abbrev-table nil "Abbrev table in use in perl-mode buffers.") (define-abbrev-table 'perl-mode-abbrev-table ()) @@ -187,11 +193,12 @@ ;; ;; Fontify function, variable and file name references. ("&\\(\\sw+\\(::\\sw+\\)*\\)" 1 font-lock-function-name-face) - ;; Additionally underline non-scalar variables. Maybe this is a bad idea. + ;; Additionally fontify non-scalar variables. `perl-non-scalar-variable' + ;; will underline them by default. ;;'("[$@%*][#{]?\\(\\sw+\\)" 1 font-lock-variable-name-face) ("[$*]{?\\(\\sw+\\(::\\sw+\\)*\\)" 1 font-lock-variable-name-face) ("\\([@%]\\|\\$#\\)\\(\\sw+\\(::\\sw+\\)*\\)" - (2 (cons font-lock-variable-name-face '(underline)))) + (2 'perl-non-scalar-variable)) ("<\\(\\sw+\\)>" 1 font-lock-constant-face) ;; ;; Fontify keywords with/and labels as we do in `c++-font-lock-keywords'. commit 4e64d023563988a570b6c2ac60d48af7f2d64a68 Author: James N. V. Cash Date: Tue Jan 19 07:07:37 2021 +0100 Define keymap-name-history * lisp/help-fns.el (keymap-name-history): Define the history variable (bug#45879). This avoids problems in other completing systems like Helm. Copyright-paperwork-exempt: yes diff --git a/lisp/help-fns.el b/lisp/help-fns.el index d559221a82..7be2826361 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -76,6 +76,9 @@ frame.") ;; costly, really). "Radix-tree representation replacing `definition-prefixes'.") +(defvar keymap-name-history nil + "History for input to `describe-keymap'.") + (defun help-definition-prefixes () "Return the up-to-date radix-tree form of `definition-prefixes'." (when (> (hash-table-count definition-prefixes) 0) commit 378a01e16808ce319138141bdc0779d96e17f8bf Author: Lars Ingebrigtsen Date: Tue Jan 19 06:05:53 2021 +0100 Actually make the calc trail window dedicated * lisp/calc/calc.el (calc-trail-display): Actually make the trail window dedicated (bug#45928). diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el index d684c7ba97..ec09abb34c 100644 --- a/lisp/calc/calc.el +++ b/lisp/calc/calc.el @@ -2144,7 +2144,7 @@ the United States." (let ((w (split-window nil (/ (* (window-width) 2) 3) t))) (set-window-buffer w calc-trail-buffer) (and calc-make-windows-dedicated - (set-window-dedicated-p nil t)))) + (set-window-dedicated-p w t)))) (calc-wrapper (setq overlay-arrow-string calc-trail-overlay overlay-arrow-position calc-trail-pointer) commit 43982a8f1017f709f78d5722796c266d4f72de05 Author: Lars Ingebrigtsen Date: Tue Jan 19 05:13:03 2021 +0100 Don't infloop in comint-redirect-results-list-from-process * lisp/comint.el (comint-redirect-results-list-from-process): Ensure forward progress (bug#45950). diff --git a/lisp/comint.el b/lisp/comint.el index 53153af7d2..e52d67d0e5 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -3863,7 +3863,11 @@ REGEXP-GROUP is the regular expression group in REGEXP to use." (push (buffer-substring-no-properties (match-beginning regexp-group) (match-end regexp-group)) - results)) + results) + (when (zerop (length (match-string 0))) + ;; If the regexp can be empty (for instance, "^.*$"), we + ;; don't advance, so ensure forward progress. + (forward-line 1))) (nreverse results)))) ;; Converting process modes to use comint mode commit 973799f17996c99f500024f35604d49b70ce4439 Author: Lucas Werkmeister Date: Tue Jan 19 04:47:14 2021 +0100 Mark the various nxml flags as safa * lisp/nxml/nxml-mode.el (nxml-char-ref-display-glyph-flag) (nxml-sexp-element-flag, nxml-slash-auto-complete-flag) (nxml-child-indent, nxml-attribute-indent) (nxml-bind-meta-tab-to-complete-flag) (nxml-prefer-utf-16-to-utf-8-flag) (nxml-prefer-utf-16-little-to-big-endian-flag) (nxml-default-buffer-file-coding-system) (nxml-auto-insert-xml-declaration-flag): Add :safe to allow easier cusomization (bug#45969). diff --git a/lisp/nxml/nxml-mode.el b/lisp/nxml/nxml-mode.el index 5bc3049d90..0602943db2 100644 --- a/lisp/nxml/nxml-mode.el +++ b/lisp/nxml/nxml-mode.el @@ -54,26 +54,30 @@ "Non-nil means display glyph following character reference. The glyph is displayed in face `nxml-glyph'." :group 'nxml - :type 'boolean) + :type 'boolean + :safe #'booleanp) (defcustom nxml-sexp-element-flag t "Non-nil means sexp commands treat an element as a single expression." :version "27.1" ; nil -> t :group 'nxml - :type 'boolean) + :type 'boolean + :safe #'booleanp) (defcustom nxml-slash-auto-complete-flag nil "Non-nil means typing a slash automatically completes the end-tag. This is used by `nxml-electric-slash'." :group 'nxml - :type 'boolean) + :type 'boolean + :safe #'booleanp) (defcustom nxml-child-indent 2 "Indentation for the children of an element relative to the start-tag. This only applies when the line or lines containing the start-tag contains nothing else other than that start-tag." :group 'nxml - :type 'integer) + :type 'integer + :safe #'integerp) (defcustom nxml-attribute-indent 4 "Indentation for the attributes of an element relative to the start-tag. @@ -81,12 +85,14 @@ This only applies when the first attribute of a tag starts a line. In other cases, the first attribute on one line is indented the same as the first attribute on the previous line." :group 'nxml - :type 'integer) + :type 'integer + :safe #'integerp) (defcustom nxml-bind-meta-tab-to-complete-flag t "Non-nil means to use nXML completion in \\[completion-at-point]." :group 'nxml - :type 'boolean) + :type 'boolean + :safe #'booleanp) (defcustom nxml-prefer-utf-16-to-utf-8-flag nil "Non-nil means prefer UTF-16 to UTF-8 when saving a buffer. @@ -94,7 +100,8 @@ This is used only when a buffer does not contain an encoding declaration and when its current `buffer-file-coding-system' specifies neither UTF-16 nor UTF-8." :group 'nxml - :type 'boolean) + :type 'boolean + :safe #'booleanp) (defcustom nxml-prefer-utf-16-little-to-big-endian-flag (eq system-type 'windows-nt) @@ -103,7 +110,8 @@ This is used only for saving a buffer; when reading the byte-order is auto-detected. It may be relevant both when there is no encoding declaration and when the encoding declaration specifies `UTF-16'." :group 'nxml - :type 'boolean) + :type 'boolean + :safe #'booleanp) (defcustom nxml-default-buffer-file-coding-system nil "Default value for `buffer-file-coding-system' for a buffer for a new file. @@ -112,13 +120,15 @@ A value of nil means use the default value of A buffer's `buffer-file-coding-system' affects what \\[nxml-insert-xml-declaration] inserts." :group 'nxml - :type 'coding-system) + :type 'coding-system + :safe #'coding-system-p) (defcustom nxml-auto-insert-xml-declaration-flag nil "Non-nil means automatically insert an XML declaration in a new file. The XML declaration is inserted using `nxml-insert-xml-declaration'." :group 'nxml - :type 'boolean) + :type 'boolean + :safe #'booleanp) (defface nxml-delimited-data '((t (:inherit font-lock-doc-face))) commit f844ce69cd0a07d45852a8b04ed3f1c84a699ed8 Author: Lars Ingebrigtsen Date: Tue Jan 19 04:28:18 2021 +0100 Revert "* .gitignore: add src/fingerprint.c" This reverts commit 2644353cbc65927a6a0a76d68e00d017771cdd03. The src/fingerprint.c file is no longer generated, and the spelling of the obsolete function was correct. diff --git a/.gitignore b/.gitignore index 7e3e434181..dd4eab759c 100644 --- a/.gitignore +++ b/.gitignore @@ -298,4 +298,3 @@ nt/emacs.rc nt/emacsclient.rc src/gdb.ini /var/ -src/fingerprint.c diff --git a/lisp/dired-x.el b/lisp/dired-x.el index aebffe339e..5a52eccbbe 100644 --- a/lisp/dired-x.el +++ b/lisp/dired-x.el @@ -1483,7 +1483,7 @@ a prefix argument, when it offers the filename near point as a default." ;;; Internal functions. ;; Fixme: This should probably use `thing-at-point'. -- fx -(define-obsolete-function-alias 'dired-file-name-at-point +(define-obsolete-function-alias 'dired-filename-at-point #'dired-x-guess-file-name-at-point "28.1") (defun dired-x-guess-file-name-at-point () "Return the filename closest to point, expanded. commit 4ca808ee7adda7b17a7dedffbce9e9e49ee4cd93 Author: Dmitry Gutov Date: Tue Jan 19 03:05:44 2021 +0200 Make sure the new window is not too tall * lisp/progmodes/xref.el (xref-show-definitions-buffer-at-bottom): Make sure the new window is not too tall (bug#45945). diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index b6778de807..aecb30a0ad 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -1001,8 +1001,12 @@ When only one definition found, jump to it right away instead." When there is more than one definition, split the selected window and show the list in a small window at the bottom. And use a local keymap that binds `RET' to `xref-quit-and-goto-xref'." - (let ((xrefs (funcall fetcher)) - (dd default-directory)) + (let* ((xrefs (funcall fetcher)) + (dd default-directory) + ;; XXX: Make percentage customizable maybe? + (max-height (/ (window-height) 2)) + (size-fun (lambda (window) + (fit-window-to-buffer window max-height)))) (cond ((not (cdr xrefs)) (xref-pop-to-location (car xrefs) @@ -1013,7 +1017,8 @@ local keymap that binds `RET' to `xref-quit-and-goto-xref'." (xref--transient-buffer-mode) (xref--show-common-initialize (xref--analyze xrefs) fetcher alist) (pop-to-buffer (current-buffer) - '(display-buffer-in-direction . ((direction . below)))) + `(display-buffer-in-direction . ((direction . below) + (window-height . ,size-fun)))) (current-buffer)))))) (define-obsolete-function-alias 'xref--show-defs-buffer-at-bottom commit 35119b2bc0fd602a19fa0b07d305592d139be6a8 Author: Stephen Gildea Date: Mon Jan 18 13:27:22 2021 -0800 time-stamp-tests now pass in more locales Update time-stamp-tests to use format-time-string to generate the date words (month, day of week, AM/PM) instead of hard-coding English. Now the tests pass in locales other than "C" and US English. Expand the test coverage of modifier characters. diff --git a/test/lisp/time-stamp-tests.el b/test/lisp/time-stamp-tests.el index 81488c3df1..4ae3c1917d 100644 --- a/test/lisp/time-stamp-tests.el +++ b/test/lisp/time-stamp-tests.el @@ -262,40 +262,48 @@ (ert-deftest time-stamp-format-day-of-week () "Test time-stamp formats for named day of week." (with-time-stamp-test-env - ;; implemented and documented since 1997 - (should (equal (time-stamp-string "%3a" ref-time1) "Mon")) - (should (equal (time-stamp-string "%#A" ref-time1) "MONDAY")) - ;; documented 1997-2019 - (should (equal (time-stamp-string "%3A" ref-time1) "MON")) - (should (equal (time-stamp-string "%:a" ref-time1) "Monday")) - ;; implemented since 2001, documented since 2019 - (should (equal (time-stamp-string "%#a" ref-time1) "MON")) - (should (equal (time-stamp-string "%:A" ref-time1) "Monday")) - ;; allowed but undocumented since 2019 (warned 1997-2019) - (should (equal (time-stamp-string "%^A" ref-time1) "MONDAY")) - ;; warned 1997-2019, changed in 2019 - (should (equal (time-stamp-string "%a" ref-time1) "Mon")) - (should (equal (time-stamp-string "%^a" ref-time1) "MON")) - (should (equal (time-stamp-string "%A" ref-time1) "Monday")))) + (let ((Mon (format-time-string "%a" ref-time1 t)) + (MON (format-time-string "%^a" ref-time1 t)) + (Monday (format-time-string "%A" ref-time1 t)) + (MONDAY (format-time-string "%^A" ref-time1 t))) + ;; implemented and documented since 1997 + (should (equal (time-stamp-string "%3a" ref-time1) Mon)) + (should (equal (time-stamp-string "%#A" ref-time1) MONDAY)) + ;; documented 1997-2019 + (should (equal (time-stamp-string "%3A" ref-time1) MON)) + (should (equal (time-stamp-string "%:a" ref-time1) Monday)) + ;; implemented since 2001, documented since 2019 + (should (equal (time-stamp-string "%#a" ref-time1) MON)) + (should (equal (time-stamp-string "%:A" ref-time1) Monday)) + ;; allowed but undocumented since 2019 (warned 1997-2019) + (should (equal (time-stamp-string "%^A" ref-time1) MONDAY)) + ;; warned 1997-2019, changed in 2019 + (should (equal (time-stamp-string "%a" ref-time1) Mon)) + (should (equal (time-stamp-string "%^a" ref-time1) MON)) + (should (equal (time-stamp-string "%A" ref-time1) Monday))))) (ert-deftest time-stamp-format-month-name () "Test time-stamp formats for month name." (with-time-stamp-test-env - ;; implemented and documented since 1997 - (should (equal (time-stamp-string "%3b" ref-time1) "Jan")) - (should (equal (time-stamp-string "%#B" ref-time1) "JANUARY")) - ;; documented 1997-2019 - (should (equal (time-stamp-string "%3B" ref-time1) "JAN")) - (should (equal (time-stamp-string "%:b" ref-time1) "January")) - ;; implemented since 2001, documented since 2019 - (should (equal (time-stamp-string "%#b" ref-time1) "JAN")) - (should (equal (time-stamp-string "%:B" ref-time1) "January")) - ;; allowed but undocumented since 2019 (warned 1997-2019) - (should (equal (time-stamp-string "%^B" ref-time1) "JANUARY")) - ;; warned 1997-2019, changed in 2019 - (should (equal (time-stamp-string "%b" ref-time1) "Jan")) - (should (equal (time-stamp-string "%^b" ref-time1) "JAN")) - (should (equal (time-stamp-string "%B" ref-time1) "January")))) + (let ((Jan (format-time-string "%b" ref-time1 t)) + (JAN (format-time-string "%^b" ref-time1 t)) + (January (format-time-string "%B" ref-time1 t)) + (JANUARY (format-time-string "%^B" ref-time1 t))) + ;; implemented and documented since 1997 + (should (equal (time-stamp-string "%3b" ref-time1) Jan)) + (should (equal (time-stamp-string "%#B" ref-time1) JANUARY)) + ;; documented 1997-2019 + (should (equal (time-stamp-string "%3B" ref-time1) JAN)) + (should (equal (time-stamp-string "%:b" ref-time1) January)) + ;; implemented since 2001, documented since 2019 + (should (equal (time-stamp-string "%#b" ref-time1) JAN)) + (should (equal (time-stamp-string "%:B" ref-time1) January)) + ;; allowed but undocumented since 2019 (warned 1997-2019) + (should (equal (time-stamp-string "%^B" ref-time1) JANUARY)) + ;; warned 1997-2019, changed in 2019 + (should (equal (time-stamp-string "%b" ref-time1) Jan)) + (should (equal (time-stamp-string "%^b" ref-time1) JAN)) + (should (equal (time-stamp-string "%B" ref-time1) January))))) (ert-deftest time-stamp-format-day-of-month () "Test time-stamp formats for day of month." @@ -483,14 +491,18 @@ (ert-deftest time-stamp-format-am-pm () "Test time-stamp formats for AM and PM strings." (with-time-stamp-test-env - ;; implemented and documented since 1997 - (should (equal (time-stamp-string "%#p" ref-time1) "pm")) - (should (equal (time-stamp-string "%#p" ref-time3) "am")) - (should (equal (time-stamp-string "%P" ref-time1) "PM")) - (should (equal (time-stamp-string "%P" ref-time3) "AM")) - ;; warned 1997-2019, changed in 2019 - (should (equal (time-stamp-string "%p" ref-time1) "PM")) - (should (equal (time-stamp-string "%p" ref-time3) "AM")))) + (let ((pm (format-time-string "%#p" ref-time1 t)) + (am (format-time-string "%#p" ref-time3 t)) + (PM (format-time-string "%p" ref-time1 t)) + (AM (format-time-string "%p" ref-time3 t))) + ;; implemented and documented since 1997 + (should (equal (time-stamp-string "%#p" ref-time1) pm)) + (should (equal (time-stamp-string "%#p" ref-time3) am)) + (should (equal (time-stamp-string "%P" ref-time1) PM)) + (should (equal (time-stamp-string "%P" ref-time3) AM)) + ;; warned 1997-2019, changed in 2019 + (should (equal (time-stamp-string "%p" ref-time1) PM)) + (should (equal (time-stamp-string "%p" ref-time3) AM))))) (ert-deftest time-stamp-format-day-number-in-week () "Test time-stamp formats for day number in week." @@ -567,10 +579,15 @@ (ert-deftest time-stamp-format-ignored-modifiers () "Test additional args allowed (but ignored) to allow for future expansion." (with-time-stamp-test-env - ;; allowed modifiers - (should (equal (time-stamp-string "%.,@-+_ ^(stuff)P" ref-time3) "AM")) - ;; not all punctuation is allowed - (should-not (equal (time-stamp-string "%&P" ref-time3) "AM")))) + (let ((May (format-time-string "%B" ref-time3 t))) + ;; allowed modifiers + (should (equal (time-stamp-string "%.,@+ (stuff)B" ref-time3) May)) + ;; parens nest + (should (equal (time-stamp-string "%(st(u)ff)B" ref-time3) May)) + ;; escaped parens do not change the nesting level + (should (equal (time-stamp-string "%(st\\)u\\(ff)B" ref-time3) May)) + ;; not all punctuation is allowed + (should-not (equal (time-stamp-string "%&B" ref-time3) May))))) (ert-deftest time-stamp-format-non-conversions () "Test that without a %, the text is copied literally." @@ -580,16 +597,22 @@ (ert-deftest time-stamp-format-string-width () "Test time-stamp string width modifiers." (with-time-stamp-test-env - ;; strings truncate on the right or are blank-padded on the left - (should (equal (time-stamp-string "%0P" ref-time3) "")) - (should (equal (time-stamp-string "%1P" ref-time3) "A")) - (should (equal (time-stamp-string "%2P" ref-time3) "AM")) - (should (equal (time-stamp-string "%3P" ref-time3) " AM")) - (should (equal (time-stamp-string "%0%" ref-time3) "")) - (should (equal (time-stamp-string "%1%" ref-time3) "%")) - (should (equal (time-stamp-string "%2%" ref-time3) " %")) - (should (equal (time-stamp-string "%#3a" ref-time3) "SUN")) - (should (equal (time-stamp-string "%#3b" ref-time2) "NOV")))) + (let ((May (format-time-string "%b" ref-time3 t)) + (SUN (format-time-string "%^a" ref-time3 t)) + (NOV (format-time-string "%^b" ref-time2 t))) + ;; strings truncate on the right or are blank-padded on the left + (should (equal (time-stamp-string "%0b" ref-time3) "")) + (should (equal (time-stamp-string "%1b" ref-time3) (substring May 0 1))) + (should (equal (time-stamp-string "%2b" ref-time3) (substring May 0 2))) + (should (equal (time-stamp-string "%3b" ref-time3) May)) + (should (equal (time-stamp-string "%4b" ref-time3) (concat " " May))) + (should (equal (time-stamp-string "%0%" ref-time3) "")) + (should (equal (time-stamp-string "%1%" ref-time3) "%")) + (should (equal (time-stamp-string "%2%" ref-time3) " %")) + (should (equal (time-stamp-string "%9%" ref-time3) " %")) + (should (equal (time-stamp-string "%10%" ref-time3) " %")) + (should (equal (time-stamp-string "%#3a" ref-time3) SUN)) + (should (equal (time-stamp-string "%#3b" ref-time2) NOV))))) ;;; Tests of helper functions commit 20add1cd22f9775a4475148b300cf2a4de4bd54a Author: Eric Abrahamsen Date: Tue Mar 17 20:53:05 2020 -0700 Allow gnus-retrieve-headers to return headers directly Previously, all Gnus backends returned header information by writing nov lines into the nntp-server-buffer, which was later parsed. This commit allows the backends to return their header information as a list of already-parsed headers, though so far none of the backends actually do that. The agent, cache, cloud etc. now operate on parsed headers rather than nov text, ie. they use gnus-fetch-headers instead of gnus-retrieve-headers. * lisp/gnus/gnus-sum.el (gnus-fetch-headers): Handle the case in which gnus-retrieve-headers returns headers directly. * lisp/gnus/nnvirtual.el (nnvirtual-retrieve-headers): Use gnus-fetch-headers rather than gnus-retrieve-headers to get headers, meaning we're operating on already-parsed headers. (nnvirtual-convert-headers): Remove now-unnecessary function. (nnvirtual-update-xref-header): Rewrite to operate on parsed header. * lisp/gnus/gnus-cloud.el (gnus-cloud-available-chunks): Use gnus-fetch-headers instead of gnus-retrieve-headers. * lisp/gnus/gnus-cache.el (gnus-cache-retrieve-headers): Use gnus-fetch-headers. (gnus-cache-braid-nov, gnus-cache-braid-heads): Delete unnecessary functions -- we now do this work on a list of parsed headers. * lisp/gnus/gnus-agent.el (gnus-agent-retrieve-headers): Use gnus-fetch-headers. (gnus-agent-braid-nov): Remove unnecessary function. (gnus-agent-fetch-headers): Use gnus-fetch-headers. diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el index 56640ea830..686623029e 100644 --- a/lisp/gnus/gnus-agent.el +++ b/lisp/gnus/gnus-agent.el @@ -1789,6 +1789,7 @@ variables. Returns the first non-nil value found." . gnus-agent-enable-expiration) (agent-predicate . gnus-agent-predicate))))))) +;; FIXME: This looks an awful lot like `gnus-agent-retrieve-headers'. (defun gnus-agent-fetch-headers (group) "Fetch interesting headers into the agent. The group's overview file will be updated to include the headers while a list of available @@ -1810,10 +1811,9 @@ article numbers will be returned." (cdr active)))) (gnus-uncompress-range (gnus-active group))) (gnus-list-of-unread-articles group))) - (gnus-decode-encoded-word-function 'identity) - (gnus-decode-encoded-address-function 'identity) (file (gnus-agent-article-name ".overview" group)) - (file-name-coding-system nnmail-pathname-coding-system)) + (file-name-coding-system nnmail-pathname-coding-system) + headers fetched-headers) (unless fetch-all ;; Add articles with marks to the list of article headers we want to @@ -1824,7 +1824,7 @@ article numbers will be returned." (dolist (arts (gnus-info-marks (gnus-get-info group))) (unless (memq (car arts) '(seen recent killed cache)) (setq articles (gnus-range-add articles (cdr arts))))) - (setq articles (sort (gnus-uncompress-sequence articles) '<))) + (setq articles (sort (gnus-uncompress-range articles) '<))) ;; At this point, I have the list of articles to consider for ;; fetching. This is the list that I'll return to my caller. Some @@ -1867,38 +1867,52 @@ article numbers will be returned." 10 "gnus-agent-fetch-headers: undownloaded articles are `%s'" (gnus-compress-sequence articles t))) - (with-current-buffer nntp-server-buffer - (if articles - (progn - (gnus-message 8 "Fetching headers for %s..." group) - - ;; Fetch them. - (gnus-make-directory (nnheader-translate-file-chars - (file-name-directory file) t)) - - (unless (eq 'nov (gnus-retrieve-headers articles group)) - (nnvirtual-convert-headers)) - (gnus-agent-check-overview-buffer) - ;; Move these headers to the overview buffer so that - ;; gnus-agent-braid-nov can merge them with the contents - ;; of FILE. - (copy-to-buffer - gnus-agent-overview-buffer (point-min) (point-max)) - ;; NOTE: Call g-a-brand-nov even when the file does not - ;; exist. As a minimum, it will validate the article - ;; numbers already in the buffer. - (gnus-agent-braid-nov articles file) - (let ((coding-system-for-write - gnus-agent-file-coding-system)) - (gnus-agent-check-overview-buffer) - (write-region (point-min) (point-max) file nil 'silent)) - (gnus-agent-update-view-total-fetched-for group t) - (gnus-agent-save-alist group articles nil) - articles) - (ignore-errors - (erase-buffer) - (nnheader-insert-file-contents file))))) - articles)) + ;; Parse known headers from FILE. + (if (file-exists-p file) + (with-current-buffer gnus-agent-overview-buffer + (erase-buffer) + (let ((nnheader-file-coding-system + gnus-agent-file-coding-system)) + (nnheader-insert-nov-file file (car articles)) + (with-current-buffer nntp-server-buffer + (erase-buffer) + (insert-buffer-substring gnus-agent-overview-buffer) + (setq headers + (gnus-get-newsgroup-headers-xover + articles nil (buffer-local-value + 'gnus-newsgroup-dependencies + gnus-summary-buffer) + gnus-newsgroup-name))))) + (gnus-make-directory (nnheader-translate-file-chars + (file-name-directory file) t))) + + ;; Fetch our new headers. + (gnus-message 8 "Fetching headers for %s..." group) + (if articles + (setq fetched-headers (gnus-fetch-headers articles))) + + ;; Merge two sets of headers. + (setq headers + (if (and headers fetched-headers) + (delete-dups + (sort (append headers (copy-sequence fetched-headers)) + (lambda (l r) + (< (mail-header-number l) + (mail-header-number r))))) + (or headers fetched-headers))) + + ;; Save the new set of headers to FILE. + (let ((coding-system-for-write + gnus-agent-file-coding-system)) + (with-current-buffer gnus-agent-overview-buffer + (goto-char (point-max)) + (mapc #'nnheader-insert-nov fetched-headers) + (sort-numeric-fields 1 (point-min) (point-max)) + (gnus-agent-check-overview-buffer) + (write-region (point-min) (point-max) file nil 'silent)) + (gnus-agent-update-view-total-fetched-for group t) + (gnus-agent-save-alist group articles nil))) + headers)) (defsubst gnus-agent-read-article-number () "Read the article number at point. @@ -1924,96 +1938,6 @@ Return nil when a valid article number can not be read." (set-buffer nntp-server-buffer) (insert-buffer-substring gnus-agent-overview-buffer b e)))) -(defun gnus-agent-braid-nov (articles file) - "Merge agent overview data with given file. -Takes unvalidated headers for ARTICLES from -`gnus-agent-overview-buffer' and validated headers from the given -FILE and places the combined valid headers into -`nntp-server-buffer'. This function can be used, when file -doesn't exist, to valid the overview buffer." - (let (start last) - (set-buffer gnus-agent-overview-buffer) - (goto-char (point-min)) - (set-buffer nntp-server-buffer) - (erase-buffer) - (when (file-exists-p file) - (nnheader-insert-file-contents file)) - (goto-char (point-max)) - (forward-line -1) - - (unless (or (= (point-min) (point-max)) - (< (setq last (read (current-buffer))) (car articles))) - ;; Old and new overlap -- We do it the hard way. - (when (nnheader-find-nov-line (car articles)) - ;; Replacing existing NOV entry - (delete-region (point) (progn (forward-line 1) (point)))) - (gnus-agent-copy-nov-line (pop articles)) - - (ignore-errors - (while articles - (while (let ((art (read (current-buffer)))) - (cond ((< art (car articles)) - (forward-line 1) - t) - ((= art (car articles)) - (beginning-of-line) - (delete-region - (point) (progn (forward-line 1) (point))) - nil) - (t - (beginning-of-line) - nil)))) - - (gnus-agent-copy-nov-line (pop articles))))) - - (goto-char (point-max)) - - ;; Append the remaining lines - (when articles - (when last - (set-buffer gnus-agent-overview-buffer) - (setq start (point)) - (set-buffer nntp-server-buffer)) - - (let ((p (point))) - (insert-buffer-substring gnus-agent-overview-buffer start) - (goto-char p)) - - (setq last (or last -134217728)) - (while (catch 'problems - (let (sort art) - (while (not (eobp)) - (setq art (gnus-agent-read-article-number)) - (cond ((not art) - ;; Bad art num - delete this line - (beginning-of-line) - (delete-region (point) (progn (forward-line 1) (point)))) - ((< art last) - ;; Art num out of order - enable sort - (setq sort t) - (forward-line 1)) - ((= art last) - ;; Bad repeat of art number - delete this line - (beginning-of-line) - (delete-region (point) (progn (forward-line 1) (point)))) - (t - ;; Good art num - (setq last art) - (forward-line 1)))) - (when sort - ;; something is seriously wrong as we simply shouldn't see out-of-order data. - ;; First, we'll fix the sort. - (sort-numeric-fields 1 (point-min) (point-max)) - - ;; but now we have to consider that we may have duplicate rows... - ;; so reset to beginning of file - (goto-char (point-min)) - (setq last -134217728) - - ;; and throw a code that restarts this scan - (throw 'problems t)) - nil)))))) - ;; Keeps the compiler from warning about the free variable in ;; gnus-agent-read-agentview. (defvar gnus-agent-read-agentview) @@ -2386,10 +2310,9 @@ modified) original contents, they are first saved to their own file." (gnus-orphan-score gnus-orphan-score) ;; Maybe some other gnus-summary local variables should also ;; be put here. - + fetched-headers gnus-headers gnus-score - articles predicate info marks ) (unless (gnus-check-group group) @@ -2410,38 +2333,35 @@ modified) original contents, they are first saved to their own file." (setq info (gnus-get-info group))))))) (when arts (setq marked-articles (nconc (gnus-uncompress-range arts) - marked-articles)) - )))) + marked-articles)))))) (setq marked-articles (sort marked-articles '<)) - ;; Fetch any new articles from the server - (setq articles (gnus-agent-fetch-headers group)) + (setq gnus-newsgroup-dependencies + (or gnus-newsgroup-dependencies + (gnus-make-hashtable))) - ;; Merge new articles with marked - (setq articles (sort (append marked-articles articles) '<)) + ;; Fetch headers for any new articles from the server. + (setq fetched-headers (gnus-agent-fetch-headers group)) - (when articles - ;; Parse them and see which articles we want to fetch. - (setq gnus-newsgroup-dependencies - (or gnus-newsgroup-dependencies - (gnus-make-hashtable (length articles)))) + (when fetched-headers (setq gnus-newsgroup-headers - (or gnus-newsgroup-headers - (gnus-get-newsgroup-headers-xover articles nil nil - group))) - ;; `gnus-agent-overview-buffer' may be killed for - ;; timeout reason. If so, recreate it. + (or gnus-newsgroup-headers + fetched-headers))) + (when marked-articles + ;; `gnus-agent-overview-buffer' may be killed for timeout + ;; reason. If so, recreate it. (gnus-agent-create-buffer) (setq predicate - (gnus-get-predicate - (gnus-agent-find-parameter group 'agent-predicate))) + (gnus-get-predicate + (gnus-agent-find-parameter group 'agent-predicate))) + + ;; If the selection predicate requires scoring, score each header. - ;; If the selection predicate requires scoring, score each header (unless (memq predicate '(gnus-agent-true gnus-agent-false)) (let ((score-param (gnus-agent-find-parameter group 'agent-score-file))) - ;; Translate score-param into real one + ;; Translate score-param into real one. (cond ((not score-param)) ((eq score-param 'file) @@ -3661,11 +3581,9 @@ has been fetched." (defun gnus-agent-retrieve-headers (articles group &optional fetch-old) (save-excursion (gnus-agent-create-buffer) - (let ((gnus-decode-encoded-word-function 'identity) - (gnus-decode-encoded-address-function 'identity) - (file (gnus-agent-article-name ".overview" group)) - uncached-articles - (file-name-coding-system nnmail-pathname-coding-system)) + (let ((file (gnus-agent-article-name ".overview" group)) + (file-name-coding-system nnmail-pathname-coding-system) + uncached-articles headers fetched-headers) (gnus-make-directory (nnheader-translate-file-chars (file-name-directory file) t)) @@ -3676,122 +3594,63 @@ has been fetched." 1) (car (last articles)))))) - ;; Populate temp buffer with known headers + ;; See if we've got cached headers for ARTICLES and put them in + ;; HEADERS. Articles with no cached headers go in + ;; UNCACHED-ARTICLES to be fetched from the server. (when (file-exists-p file) (with-current-buffer gnus-agent-overview-buffer (erase-buffer) (let ((nnheader-file-coding-system gnus-agent-file-coding-system)) - (nnheader-insert-nov-file file (car articles))))) - - (if (setq uncached-articles (gnus-agent-uncached-articles articles group - t)) - (progn - ;; Populate nntp-server-buffer with uncached headers - (set-buffer nntp-server-buffer) - (erase-buffer) - (cond ((not (eq 'nov (let (gnus-agent) ; Turn off agent - (gnus-retrieve-headers - uncached-articles group)))) - (nnvirtual-convert-headers)) - ((eq 'nntp (car gnus-current-select-method)) - ;; The author of gnus-get-newsgroup-headers-xover - ;; reports that the XOVER command is commonly - ;; unreliable. The problem is that recently - ;; posted articles may not be entered into the - ;; NOV database in time to respond to my XOVER - ;; query. - ;; - ;; I'm going to use his assumption that the NOV - ;; database is updated in order of ascending - ;; article ID. Therefore, a response containing - ;; article ID N implies that all articles from 1 - ;; to N-1 are up-to-date. Therefore, missing - ;; articles in that range have expired. - - (set-buffer nntp-server-buffer) - (let* ((fetched-articles (list nil)) - (tail-fetched-articles fetched-articles) - (min (car articles)) - (max (car (last articles)))) - - ;; Get the list of articles that were fetched - (goto-char (point-min)) - (let ((pm (point-max)) - art) - (while (< (point) pm) - (when (setq art (gnus-agent-read-article-number)) - (gnus-agent-append-to-list tail-fetched-articles art)) - (forward-line 1))) - - ;; Clip this list to the headers that will - ;; actually be returned - (setq fetched-articles (gnus-list-range-intersection - (cdr fetched-articles) - (cons min max))) - - ;; Clip the uncached articles list to exclude - ;; IDs after the last FETCHED header. The - ;; excluded IDs may be fetchable using HEAD. - (if (car tail-fetched-articles) - (setq uncached-articles - (gnus-list-range-intersection - uncached-articles - (cons (car uncached-articles) - (car tail-fetched-articles))))) - - ;; Create the list of articles that were - ;; "successfully" fetched. Success, in this - ;; case, means that the ID should not be - ;; fetched again. In the case of an expired - ;; article, the header will not be fetched. - (setq uncached-articles - (gnus-sorted-nunion fetched-articles - uncached-articles)) - ))) - - ;; Erase the temp buffer - (set-buffer gnus-agent-overview-buffer) - (erase-buffer) - - ;; Copy the nntp-server-buffer to the temp buffer - (set-buffer nntp-server-buffer) - (copy-to-buffer gnus-agent-overview-buffer (point-min) (point-max)) - - ;; Merge the temp buffer with the known headers (found on - ;; disk in FILE) into the nntp-server-buffer - (when uncached-articles - (gnus-agent-braid-nov uncached-articles file)) - - ;; Save the new set of known headers to FILE - (set-buffer nntp-server-buffer) + (nnheader-insert-nov-file file (car articles)) + (with-current-buffer nntp-server-buffer + (erase-buffer) + (insert-buffer-substring gnus-agent-overview-buffer) + (setq headers + (gnus-get-newsgroup-headers-xover + articles nil (buffer-local-value + 'gnus-newsgroup-dependencies + gnus-summary-buffer) + gnus-newsgroup-name)))))) + + (setq uncached-articles + (gnus-agent-uncached-articles articles group t)) + + (when uncached-articles + (let ((gnus-newsgroup-name group) + gnus-agent) ; Prevent loop. + ;; Fetch additional headers for the uncached articles. + (setq fetched-headers (gnus-fetch-headers uncached-articles)) + ;; Merge headers we got from the overview file with our + ;; newly-fetched headers. + (when fetched-headers + (setq headers + (delete-dups + (sort (append headers (copy-sequence fetched-headers)) + (lambda (l r) + (< (mail-header-number l) + (mail-header-number r)))))) + + ;; Add the new set of known headers to the overview file. (let ((coding-system-for-write gnus-agent-file-coding-system)) - (gnus-agent-check-overview-buffer) - (write-region (point-min) (point-max) file nil 'silent)) - - (gnus-agent-update-view-total-fetched-for group t) - - ;; Update the group's article alist to include the newly - ;; fetched articles. - (gnus-agent-load-alist group) - (gnus-agent-save-alist group uncached-articles nil) - ) - - ;; Copy the temp buffer to the nntp-server-buffer - (set-buffer nntp-server-buffer) - (erase-buffer) - (insert-buffer-substring gnus-agent-overview-buffer))) - - (if (and fetch-old - (not (numberp fetch-old))) - t ; Don't remove anything. - (nnheader-nov-delete-outside-range - (car articles) - (car (last articles))) - t) - - 'nov)) + (with-current-buffer gnus-agent-overview-buffer + ;; We stick the new headers in at the end, then + ;; re-sort the whole buffer with + ;; `sort-numeric-fields'. If this turns out to be + ;; slow, we could consider a loop to add the headers + ;; in sorted order to begin with. + (goto-char (point-max)) + (mapc #'nnheader-insert-nov fetched-headers) + (sort-numeric-fields 1 (point-min) (point-max)) + (gnus-agent-check-overview-buffer) + (write-region (point-min) (point-max) file nil 'silent) + (gnus-agent-update-view-total-fetched-for group t) + ;; Update the group's article alist to include the + ;; newly fetched articles. + (gnus-agent-load-alist group) + (gnus-agent-save-alist group uncached-articles nil)))))) + headers))) (defun gnus-agent-request-article (article group) "Retrieve ARTICLE in GROUP from the agent cache." diff --git a/lisp/gnus/gnus-async.el b/lisp/gnus/gnus-async.el index fefd02c7bf..ed948a26c0 100644 --- a/lisp/gnus/gnus-async.el +++ b/lisp/gnus/gnus-async.el @@ -357,8 +357,13 @@ that was fetched." (let ((nntp-server-buffer (current-buffer)) (nnheader-callback-function (lambda (_arg) - (setq gnus-async-header-prefetched - (cons group unread))))) + (setq gnus-async-header-prefetched + (cons group unread))))) + ;; FIXME: If header prefetch is ever put into use, we'll + ;; have to handle the possibility that + ;; `gnus-retrieve-headers' might return a list of header + ;; vectors directly, rather than writing them into the + ;; current buffer. (gnus-retrieve-headers unread group gnus-fetch-old-headers)))))) (defun gnus-async-retrieve-fetched-headers (articles group) diff --git a/lisp/gnus/gnus-cache.el b/lisp/gnus/gnus-cache.el index 36657e4621..9423d9f2f6 100644 --- a/lisp/gnus/gnus-cache.el +++ b/lisp/gnus/gnus-cache.el @@ -294,49 +294,47 @@ it's not cached." (defun gnus-cache-retrieve-headers (articles group &optional fetch-old) "Retrieve the headers for ARTICLES in GROUP." (let ((cached - (setq gnus-newsgroup-cached (gnus-cache-articles-in-group group)))) + (setq gnus-newsgroup-cached (gnus-cache-articles-in-group group))) + (gnus-newsgroup-name group) + (gnus-fetch-old-headers fetch-old)) (if (not cached) ;; No cached articles here, so we just retrieve them ;; the normal way. (let ((gnus-use-cache nil)) - (gnus-retrieve-headers articles group fetch-old)) + (gnus-retrieve-headers articles group)) (let ((uncached-articles (gnus-sorted-difference articles cached)) (cache-file (gnus-cache-file-name group ".overview")) - type - (file-name-coding-system nnmail-pathname-coding-system)) + (file-name-coding-system nnmail-pathname-coding-system) + headers) ;; We first retrieve all the headers that we don't have in ;; the cache. (let ((gnus-use-cache nil)) (when uncached-articles - (setq type (and articles - (gnus-retrieve-headers - uncached-articles group fetch-old))))) + (setq headers (and articles + (gnus-fetch-headers uncached-articles))))) (gnus-cache-save-buffers) - ;; Then we insert the cached headers. - (save-excursion - (cond - ((not (file-exists-p cache-file)) - ;; There are no cached headers. - type) - ((null type) - ;; There were no uncached headers (or retrieval was - ;; unsuccessful), so we use the cached headers exclusively. - (set-buffer nntp-server-buffer) - (erase-buffer) - (let ((coding-system-for-read - gnus-cache-overview-coding-system)) - (insert-file-contents cache-file)) - 'nov) - ((eq type 'nov) - ;; We have both cached and uncached NOV headers, so we - ;; braid them. - (gnus-cache-braid-nov group cached) - type) - (t - ;; We braid HEADs. - (gnus-cache-braid-heads group (gnus-sorted-intersection - cached articles)) - type))))))) + ;; Then we include the cached headers. + (when (file-exists-p cache-file) + (setq headers + (delete-dups + (sort + (append headers + (let ((coding-system-for-read + gnus-cache-overview-coding-system)) + (with-current-buffer nntp-server-buffer + (erase-buffer) + (insert-file-contents cache-file) + (gnus-get-newsgroup-headers-xover + (gnus-sorted-difference + cached uncached-articles) + nil (buffer-local-value + 'gnus-newsgroup-dependencies + gnus-summary-buffer) + group)))) + (lambda (l r) + (< (mail-header-number l) + (mail-header-number r))))))) + headers)))) (defun gnus-cache-enter-article (&optional n) "Enter the next N articles into the cache. @@ -529,70 +527,6 @@ Returns the list of articles removed." (setq gnus-cache-active-altered t))) articles))) -(defun gnus-cache-braid-nov (group cached &optional file) - (let ((cache-buf (gnus-get-buffer-create " *gnus-cache*")) - beg end) - (gnus-cache-save-buffers) - (with-current-buffer cache-buf - (erase-buffer) - (let ((coding-system-for-read gnus-cache-overview-coding-system) - (file-name-coding-system nnmail-pathname-coding-system)) - (insert-file-contents - (or file (gnus-cache-file-name group ".overview")))) - (goto-char (point-min)) - (insert "\n") - (goto-char (point-min))) - (set-buffer nntp-server-buffer) - (goto-char (point-min)) - (while cached - (while (and (not (eobp)) - (< (read (current-buffer)) (car cached))) - (forward-line 1)) - (beginning-of-line) - (set-buffer cache-buf) - (if (search-forward (concat "\n" (int-to-string (car cached)) "\t") - nil t) - (setq beg (point-at-bol) - end (progn (end-of-line) (point))) - (setq beg nil)) - (set-buffer nntp-server-buffer) - (when beg - (insert-buffer-substring cache-buf beg end) - (insert "\n")) - (setq cached (cdr cached))) - (kill-buffer cache-buf))) - -(defun gnus-cache-braid-heads (group cached) - (let ((cache-buf (gnus-get-buffer-create " *gnus-cache*"))) - (with-current-buffer cache-buf - (erase-buffer)) - (set-buffer nntp-server-buffer) - (goto-char (point-min)) - (dolist (entry cached) - (while (and (not (eobp)) - (looking-at "2.. +\\([0-9]+\\) ") - (< (progn (goto-char (match-beginning 1)) - (read (current-buffer))) - entry)) - (search-forward "\n.\n" nil 'move)) - (beginning-of-line) - (set-buffer cache-buf) - (erase-buffer) - (let ((coding-system-for-read gnus-cache-coding-system) - (file-name-coding-system nnmail-pathname-coding-system)) - (insert-file-contents (gnus-cache-file-name group entry))) - (goto-char (point-min)) - (insert "220 ") - (princ (pop cached) (current-buffer)) - (insert " Article retrieved.\n") - (search-forward "\n\n" nil 'move) - (delete-region (point) (point-max)) - (forward-char -1) - (insert ".") - (set-buffer nntp-server-buffer) - (insert-buffer-substring cache-buf)) - (kill-buffer cache-buf))) - ;;;###autoload (defun gnus-jog-cache () "Go through all groups and put the articles into the cache. diff --git a/lisp/gnus/gnus-cloud.el b/lisp/gnus/gnus-cloud.el index f7c71f43ce..00b85f546c 100644 --- a/lisp/gnus/gnus-cloud.el +++ b/lisp/gnus/gnus-cloud.el @@ -30,6 +30,8 @@ (require 'parse-time) (require 'nnimap) +(declare-function gnus-fetch-headers "gnus-sum") +(defvar gnus-alter-header-function) (eval-when-compile (require 'epg)) ;; setf-method for `epg-context-armor' (autoload 'epg-make-context "epg") @@ -391,8 +393,6 @@ When FULL is t, upload everything, not just a difference from the last full." (gnus-group-refresh-group group)) (gnus-error 2 "Failed to upload Gnus Cloud data to %s" group))))) -(defvar gnus-alter-header-function) - (defun gnus-cloud-add-timestamps (elems) (dolist (elem elems) (let* ((file-name (plist-get elem :file-name)) @@ -407,14 +407,10 @@ When FULL is t, upload everything, not just a difference from the last full." (gnus-activate-group gnus-cloud-group-name nil nil gnus-cloud-method) (let* ((group (gnus-group-full-name gnus-cloud-group-name gnus-cloud-method)) (active (gnus-active group)) - headers head) - (when (gnus-retrieve-headers (gnus-uncompress-range active) group) - (with-current-buffer nntp-server-buffer - (goto-char (point-min)) - (while (setq head (nnheader-parse-head)) - (when gnus-alter-header-function - (funcall gnus-alter-header-function head)) - (push head headers)))) + (gnus-newsgroup-name group) + (headers (gnus-fetch-headers (gnus-uncompress-range active)))) + (when gnus-alter-header-function + (mapc gnus-alter-header-function headers)) (sort (nreverse headers) (lambda (h1 h2) (> (gnus-cloud-chunk-sequence (mail-header-subject h1)) diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index b0f9ed4c6f..5bd58b690a 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -5658,10 +5658,21 @@ or a straight list of headers." (setf (mail-header-subject header) subject)))))) (defun gnus-fetch-headers (articles &optional limit force-new dependencies) - "Fetch headers of ARTICLES." + "Fetch headers of ARTICLES. +This calls the `gnus-retrieve-headers' function of the current +group's backend server. The server can do one of two things: + +1. Write the headers for ARTICLES into the + `nntp-server-buffer' (the current buffer) in a parseable format, or +2. Return the headers directly as a list of vectors. + +In the first case, `gnus-retrieve-headers' returns a symbol +value, either `nov' or `headers'. This value determines which +parsing function is used to read the headers. It is also stored +into the variable `gnus-headers-retrieved-by', which is consulted +later when possibly building full threads." (gnus-message 7 "Fetching headers for %s..." gnus-newsgroup-name) - (prog1 - (pcase (setq gnus-headers-retrieved-by + (let ((res (setq gnus-headers-retrieved-by (gnus-retrieve-headers articles gnus-newsgroup-name (or limit @@ -5671,22 +5682,34 @@ or a straight list of headers." (not (eq gnus-fetch-old-headers 'some)) (not (numberp gnus-fetch-old-headers))) (> (length articles) 1)) - gnus-fetch-old-headers)))) - ('nov - (gnus-get-newsgroup-headers-xover - articles force-new dependencies gnus-newsgroup-name t)) - ('headers - (gnus-get-newsgroup-headers dependencies force-new)) - ((pred listp) - (let ((dependencies - (or dependencies - (with-current-buffer gnus-summary-buffer - gnus-newsgroup-dependencies)))) - (delq nil (mapcar #'(lambda (header) - (gnus-dependencies-add-header - header dependencies force-new)) - gnus-headers-retrieved-by))))) - (gnus-message 7 "Fetching headers for %s...done" gnus-newsgroup-name))) + gnus-fetch-old-headers)))))) + (prog1 + (pcase res + ('nov + (gnus-get-newsgroup-headers-xover + articles force-new dependencies gnus-newsgroup-name t)) + ;; For now, assume that any backend returning its own + ;; headers takes some effort to do so, so return `headers'. + ((pred listp) + (setq gnus-headers-retrieved-by 'headers) + (let ((dependencies + (or dependencies + (buffer-local-value + 'gnus-newsgroup-dependencies gnus-summary-buffer)))) + (when (functionp gnus-alter-header-function) + (mapc gnus-alter-header-function res)) + (mapc (lambda (header) + ;; The agent or the cache may have already + ;; registered this header in the dependency + ;; table. + (unless (gethash (mail-header-id header) dependencies) + (gnus-dependencies-add-header + header dependencies force-new))) + res) + res)) + (_ (gnus-get-newsgroup-headers dependencies force-new))) + (gnus-message 7 "Fetching headers for %s...done" + gnus-newsgroup-name)))) (defun gnus-select-newsgroup (group &optional read-all select-articles) "Select newsgroup GROUP. @@ -6443,6 +6466,10 @@ The resulting hash table is returned, or nil if no Xrefs were found." (unless (gnus-ephemeral-group-p group) (gnus-group-update-group group t)))))) +;; FIXME: Refactor this with `gnus-get-newsgroup-headers-xover' and +;; extract the necessary bits for the direct-header-return case. Also +;; look at this and see how similar it is to +;; `nnheader-parse-naked-head'. (defun gnus-get-newsgroup-headers (&optional dependencies force-new) (let ((dependencies (or dependencies diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index 3b172db211..2e9ee7189d 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el @@ -2388,7 +2388,14 @@ Typical marks are those that make no sense in a standalone back end, such as a mark that says whether an article is stored in the cache \(which doesn't make sense in a standalone back end).") -(defvar gnus-headers-retrieved-by nil) +(defvar gnus-headers-retrieved-by nil + "Holds the return value of `gnus-retrieve-headers'. +This is either the symbol `nov' or the symbol `headers'. This +value is checked during the summary creation process, when +building threads. A value of `nov' indicates that header +retrieval is relatively cheap and threading is encouraged to +include more old articles. A value of `headers' indicates that +retrieval is expensive and should be minimized.") (defvar gnus-article-reply nil) (defvar gnus-override-method nil) (defvar gnus-opened-servers nil) diff --git a/lisp/gnus/nnvirtual.el b/lisp/gnus/nnvirtual.el index 1e2feda636..ba2934351d 100644 --- a/lisp/gnus/nnvirtual.el +++ b/lisp/gnus/nnvirtual.el @@ -101,15 +101,10 @@ It is computed from the marks of individual component groups.") (erase-buffer) (if (stringp (car articles)) 'headers - (let ((vbuf (nnheader-set-temp-buffer - (gnus-get-buffer-create " *virtual headers*"))) - (carticles (nnvirtual-partition-sequence articles)) + (let ((carticles (nnvirtual-partition-sequence articles)) (sysname (system-name)) - cgroup carticle article result prefix) - (while carticles - (setq cgroup (caar carticles)) - (setq articles (cdar carticles)) - (pop carticles) + cgroup headers all-headers article prefix) + (pcase-dolist (`(,cgroup . ,articles) carticles) (when (and articles (gnus-check-server (gnus-find-method-for-group cgroup) t) @@ -119,69 +114,37 @@ It is computed from the marks of individual component groups.") ;; This is probably evil if people have set ;; gnus-use-cache to nil themselves, but I ;; have no way of finding the true value of it. - (let ((gnus-use-cache t)) - (setq result (gnus-retrieve-headers - articles cgroup nil)))) - (set-buffer nntp-server-buffer) - ;; If we got HEAD headers, we convert them into NOV - ;; headers. This is slow, inefficient and, come to think - ;; of it, downright evil. So sue me. I couldn't be - ;; bothered to write a header parse routine that could - ;; parse a mixed HEAD/NOV buffer. - (when (eq result 'headers) - (nnvirtual-convert-headers)) - (goto-char (point-min)) - (while (not (eobp)) - (delete-region (point) - (progn - (setq carticle (read nntp-server-buffer)) - (point))) - - ;; We remove this article from the articles list, if - ;; anything is left in the articles list after going through - ;; the entire buffer, then those articles have been - ;; expired or canceled, so we appropriately update the - ;; component group below. They should be coming up - ;; generally in order, so this shouldn't be slow. - (setq articles (delq carticle articles)) - - (setq article (nnvirtual-reverse-map-article cgroup carticle)) - (if (null article) - ;; This line has no reverse mapping, that means it - ;; was an extra article reference returned by nntp. - (progn - (beginning-of-line) - (delete-region (point) (progn (forward-line 1) (point)))) - ;; Otherwise insert the virtual article number, - ;; and clean up the xrefs. - (princ article nntp-server-buffer) - (nnvirtual-update-xref-header cgroup carticle - prefix sysname) - (forward-line 1)) - ) - - (set-buffer vbuf) - (goto-char (point-max)) - (insert-buffer-substring nntp-server-buffer)) - ;; Anything left in articles is expired or canceled. - ;; Could be smart and not tell it about articles already known? - (when articles - (gnus-group-make-articles-read cgroup articles)) - ) - - ;; The headers are ready for reading, so they are inserted into - ;; the nntp-server-buffer, which is where Gnus expects to find - ;; them. - (prog1 - (with-current-buffer nntp-server-buffer - (erase-buffer) - (insert-buffer-substring vbuf) - ;; FIX FIX FIX, we should be able to sort faster than - ;; this if needed, since each cgroup is sorted, we just - ;; need to merge - (sort-numeric-fields 1 (point-min) (point-max)) - 'nov) - (kill-buffer vbuf))))))) + (let ((gnus-use-cache t) + (gnus-newsgroup-name cgroup) + (gnus-fetch-old-headers nil)) + (setq headers (gnus-fetch-headers articles)))) + (erase-buffer) + ;; Remove all header article numbers from `articles'. + ;; If there's anything left, those are expired or + ;; canceled articles, so we update the component group + ;; below. + (dolist (h headers) + (setq articles (delq (mail-header-number h) articles) + article (nnvirtual-reverse-map-article + cgroup (mail-header-number h))) + ;; Update all the header numbers according to their + ;; reverse mapping, and drop any with no such mapping. + (when article + ;; Do this first, before we re-set the header's + ;; article number. + (nnvirtual-update-xref-header + h cgroup prefix sysname) + (setf (mail-header-number h) article) + (push h all-headers))) + ;; Anything left in articles is expired or canceled. + ;; Could be smart and not tell it about articles already + ;; known? + (when articles + (gnus-group-make-articles-read cgroup articles)))) + + (sort all-headers (lambda (h1 h2) + (< (mail-header-number h1) + (mail-header-number h2))))))))) (defvoo nnvirtual-last-accessed-component-group nil) @@ -372,61 +335,18 @@ It is computed from the marks of individual component groups.") ;;; Internal functions. -(defun nnvirtual-convert-headers () - "Convert HEAD headers into NOV headers." - (with-current-buffer nntp-server-buffer - (let* ((dependencies (make-hash-table :test #'equal)) - (headers (gnus-get-newsgroup-headers dependencies))) - (erase-buffer) - (mapc 'nnheader-insert-nov headers)))) - - -(defun nnvirtual-update-xref-header (group article prefix sysname) - "Edit current NOV header in current buffer to have an xref to the component group, and also server prefix any existing xref lines." - ;; Move to beginning of Xref field, creating a slot if needed. - (beginning-of-line) - (looking-at - "[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t") - (goto-char (match-end 0)) - (unless (search-forward "\t" (point-at-eol) 'move) - (insert "\t")) - - ;; Remove any spaces at the beginning of the Xref field. - (while (eq (char-after (1- (point))) ? ) - (forward-char -1) - (delete-char 1)) - - (insert "Xref: " sysname " " group ":") - (princ article (current-buffer)) - (insert " ") - - ;; If there were existing xref lines, clean them up to have the correct - ;; component server prefix. - (save-restriction - (narrow-to-region (point) - (or (search-forward "\t" (point-at-eol) t) - (point-at-eol))) - (goto-char (point-min)) - (when (re-search-forward "Xref: *[^\n:0-9 ]+ *" nil t) - (replace-match "" t t)) - (goto-char (point-min)) - (when (re-search-forward - (concat (regexp-quote (gnus-group-real-name group)) ":[0-9]+") - nil t) - (replace-match "" t t)) - (unless (eobp) - (insert " ") - (when (not (string= "" prefix)) - (while (re-search-forward "[^ ]+:[0-9]+" nil t) - (save-excursion - (goto-char (match-beginning 0)) - (insert prefix)))))) - - ;; Ensure a trailing \t. - (end-of-line) - (or (eq (char-after (1- (point))) ?\t) - (insert ?\t))) - +(defun nnvirtual-update-xref-header (header group prefix sysname) + "Add xref to component GROUP to HEADER. +Also add a server PREFIX any existing xref lines." + (let ((bits (split-string (mail-header-xref header) + nil t "[[:blank:]]")) + (art-no (mail-header-number header))) + (setf (mail-header-xref header) + (concat + (format "%s %s:%d " sysname group art-no) + (mapconcat (lambda (bit) + (concat prefix bit)) + bits " "))))) (defun nnvirtual-possibly-change-server (server) (or (not server) diff --git a/lisp/obsolete/nnir.el b/lisp/obsolete/nnir.el index 147efed005..0b7d1e454c 100644 --- a/lisp/obsolete/nnir.el +++ b/lisp/obsolete/nnir.el @@ -504,7 +504,6 @@ Add an entry here when adding a new search engine.") ,@(mapcar (lambda (elem) (list 'const (car elem))) nnir-engines))))) - (defmacro nnir-add-result (dirnam artno score prefix server artlist) "Construct a result vector and add it to ARTLIST. DIRNAM, ARTNO, SCORE, PREFIX and SERVER are passed to commit 8f4b3b812aab62a5a205bc2f8690c3b4c460ba09 Author: Basil L. Contovounesios Date: Sun Jan 17 15:53:53 2021 +0000 Fix ibuffer-mark-by-file-name-regexp abbreviations * lisp/ibuffer.el (ibuffer--abbreviate-file-name): New function. (filename): Use it. * lisp/ibuf-ext.el (ibuffer-mark-by-file-name-regexp): Prefer read-regexp over read-string for reading regexps. Determine file name using ibuffer-buffer-file-name for consistency. Abbreviate file name using ibuffer-directory-abbrev-alist (bug#18859). diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el index 7be1b3d16c..ed5c9c0211 100644 --- a/lisp/ibuf-ext.el +++ b/lisp/ibuf-ext.el @@ -1823,18 +1823,12 @@ When BUF nil, default to the buffer at current line." ;;;###autoload (defun ibuffer-mark-by-file-name-regexp (regexp) "Mark all buffers whose file name matches REGEXP." - (interactive "sMark by file name (regexp): ") + (interactive (list (read-regexp "Mark by file name (regexp)"))) (ibuffer-mark-on-buffer - #'(lambda (buf) - (let ((name (or (buffer-file-name buf) - (with-current-buffer buf - (and - (boundp 'dired-directory) - (stringp dired-directory) - dired-directory))))) - (when name - ;; Match on the displayed file name (which is abbreviated). - (string-match regexp (abbreviate-file-name name))))))) + (lambda (buf) + (when-let ((name (with-current-buffer buf (ibuffer-buffer-file-name)))) + ;; Match on the displayed file name (which is abbreviated). + (string-match-p regexp (ibuffer--abbreviate-file-name name)))))) ;;;###autoload (defun ibuffer-mark-by-content-regexp (regexp &optional all-buffers) diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el index 4800e0243d..84c53b16ac 100644 --- a/lisp/ibuffer.el +++ b/lisp/ibuffer.el @@ -1308,6 +1308,11 @@ a new window in the current frame, splitting vertically." (car dired-directory))))) (and dirname (expand-file-name dirname)))))) +(defun ibuffer--abbreviate-file-name (filename) + "Abbreviate FILENAME using `ibuffer-directory-abbrev-alist'." + (let ((directory-abbrev-alist ibuffer-directory-abbrev-alist)) + (abbreviate-file-name filename))) + (define-ibuffer-op ibuffer-do-save () "Save marked buffers as with `save-buffer'." (:complex t @@ -1885,9 +1890,7 @@ If point is on a group name, this function operates on that group." (cond ((zerop total) "No files") ((= 1 total) "1 file") (t (format "%d files" total)))))) - (let ((directory-abbrev-alist ibuffer-directory-abbrev-alist)) - (abbreviate-file-name - (or (ibuffer-buffer-file-name) "")))) + (ibuffer--abbreviate-file-name (or (ibuffer-buffer-file-name) ""))) (define-ibuffer-column filename-and-process (:name "Filename/Process" commit bdb9889f784dc6113a74c259a53cf0623e49ab2d Author: Basil L. Contovounesios Date: Sun Jan 17 18:56:50 2021 +0000 Use format-prompt in read-regexp. * lisp/replace.el (read-regexp): Use format-prompt (bug#12443). diff --git a/lisp/replace.el b/lisp/replace.el index d41dc98a0d..8f8cbfac54 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -866,13 +866,10 @@ If nil, uses `regexp-history'." ;; Do not automatically add default to the history for empty input. (history-add-new-input nil) (input (read-from-minibuffer - (cond ((string-match-p ":[ \t]*\\'" prompt) - prompt) - ((and default (> (length default) 0)) - (format "%s (default %s): " prompt - (query-replace-descr default))) - (t - (format "%s: " prompt))) + (if (string-match-p ":[ \t]*\\'" prompt) + prompt + (format-prompt prompt (and (length> default 0) + (query-replace-descr default)))) nil nil nil (or history 'regexp-history) suggestions t))) (if (equal input "") ;; Return the default value when the user enters empty input. commit 92144027915bc2fc9c222d87a8e2e5da3df46c82 Author: Eric Ludlam Date: Mon Jan 18 12:49:11 2021 -0500 * lisp/cedet/ede/proj.el: Enable Project files to load (ede-proj-target-makefile): Give more precise type for its `rules` slot. * lisp/cedet/ede/base.el (ede-target-list): Don't define. (ede-project): Use `list-of` instead. diff --git a/lisp/cedet/ede/base.el b/lisp/cedet/ede/base.el index 7799746e0c..810d6ef3bd 100644 --- a/lisp/cedet/ede/base.el +++ b/lisp/cedet/ede/base.el @@ -160,16 +160,13 @@ and querying them will cause the actual project to get loaded.") ;; Projects can also affect how EDE works, by changing what appears in ;; the EDE menu, or how some keys are bound. ;; -(unless (fboundp 'ede-target-list-p) - (cl-deftype ede-target-list () '(list-of ede-target))) - (defclass ede-project (ede-project-placeholder) ((subproj :initform nil :type list :documentation "Sub projects controlled by this project. For Automake based projects, each directory is treated as a project.") (targets :initarg :targets - :type ede-target-list + :type (list-of ede-target) :custom (repeat (object :objectcreatefcn ede-new-target-custom)) :label "Local Targets" :group (targets) diff --git a/lisp/cedet/ede/proj.el b/lisp/cedet/ede/proj.el index 59628ebf4c..4af8b4104f 100644 --- a/lisp/cedet/ede/proj.el +++ b/lisp/cedet/ede/proj.el @@ -184,7 +184,7 @@ Target variables are always renamed such as foo_CFLAGS, then included into commands where the variable would usually appear.") (rules :initarg :rules :initform nil - :type list + :type (list-of ede-makefile-rule) :custom (repeat (object :objecttype ede-makefile-rule)) :label "Additional Rules" :group (make) commit b2e6ed40268e7339be501b3481774773179ca476 Author: Eli Zaretskii Date: Mon Jan 18 19:17:59 2021 +0200 Fix recent changes for Cham script * lisp/language/cham.el ("Cham"): Fix sample-text. * lisp/leim/quail/cham.el: Really install this new file. diff --git a/lisp/language/cham.el b/lisp/language/cham.el index 59eaef67bf..089988da91 100644 --- a/lisp/language/cham.el +++ b/lisp/language/cham.el @@ -36,7 +36,7 @@ (coding-system utf-8) (coding-priority utf-8) (input-method . "cham") - (sample-text . "Cham (ꨌꩌ)\tꨦꨤꩌ ꨦꨰꨁ") + (sample-text . "Cham (ꨌꩌ)\tꨦꨤꩌ ꨦꨁꨰ") (documentation . "\ The Cham script is a Brahmic script used to write Cham, an Austronesian language spoken by some 245,000 Chams diff --git a/lisp/leim/quail/cham.el b/lisp/leim/quail/cham.el new file mode 100644 index 0000000000..d12ae6cddf --- /dev/null +++ b/lisp/leim/quail/cham.el @@ -0,0 +1,116 @@ +;;; cham.el --- Quail package for inputting Cham characters -*- coding: utf-8; lexical-binding:t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Eli Zaretskii +;; Keywords: i18n + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; This file defines the following Cham keyboards: +;; +;; - QWERTY-based Cham. + +;;; Code: + +(require 'quail) + +(quail-define-package + "cham" "Cham" "ꨌꩌ" t + "A QWERTY-based Cham input method." + nil t nil nil t nil nil nil nil nil t) + +(quail-define-rules + ("a" ?ꨀ) + ("A" ?ꨄ) + ("i" ?ꨁ) + ("u" ?ꨂ) + ("e" ?ꨃ) + ("o" ?ꨅ) + ("k" ?ꨆ) + ("K" ?ꨇ) + ("g" ?ꨈ) + ("G" ?ꨉ) + ("q" ?ꨊ) + ("Q" ?ꨋ) + ("c" ?ꨌ) + ("C" ?ꨍ) + ("j" ?ꨎ) + ("J" ?ꨏ) + ("z" ?ꨐ) + ("Z" ?ꨑ) + ("zz" ?ꨒ) + ("t" ?ꨓ) + ("T" ?ꨔ) + ("d" ?ꨕ) + ("D" ?ꨖ) + ("n" ?ꨗ) + ("N" ?ꨘ) + ("p" ?ꨚ) + ("P" ?ꨛ) + ("f" ?ꨜ) + ("b" ?ꨝ) + ("B" ?ꨞ) + ("m" ?ꨟ) + ("M" ?ꨠ) + ("mm" ?ꨡ) + ("y" ?ꨢ) + ("r" ?ꨣ) + ("l" ?ꨤ) + ("w" ?ꨥ) + ("v" ?ꨥ) + ("x" ?ꨦ) + ("s" ?ꨧ) + ("h" ?ꨨ) + ("kk" ?ꩀ) + ("ww" ?ꩁ) + ("vv" ?ꩁ) + ("qq" ?ꩂ) + ("cc" ?ꩄ) + ("tt" ?ꩅ) + ("nn" ?ꩆ) + ("pp" ?ꩇ) + ("yy" ?ꩈ) + ("rr" ?ꩉ) + ("ll" ?ꩊ) + ("gg" ?ꩊ) + ("xx" ?ꩋ) + ("." ?ꩌ) + ("H" ?ꩍ) + ("0" ?꩐) + ("1" ?꩑) + ("2" ?꩒) + ("3" ?꩓) + ("4" ?꩔) + ("5" ?꩕) + ("6" ?꩖) + ("7" ?꩗) + ("8" ?꩘) + ("9" ?꩙) + ("!" ?ꨩ) + ("#" ?ꨪ) + ("$" ?ꨫ) + ("^" ?ꨬ) + ("&" ?ꨮ) + ("`" ?꩜) + ("=" ?ꨱ) + ("-" ?ꩃ) + ("~" ?꩟) + ) + +;;; cham.el ends here commit 47ddda0cc4d2bc206d8ccd2f12338b4e2616049a Merge: c4be126c42 f9dab61272 Author: Eli Zaretskii Date: Mon Jan 18 19:03:46 2021 +0200 Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs commit c4be126c42600990375720511326c5ab8fb22a84 Author: Aaron Jensen Date: Sat Jan 16 12:28:46 2021 -0600 * test/src/xdisp-tests.el: Fix tests to work in batch mode (xdisp-tests--window-text-pixel-size) (xdisp-tests--window-text-pixel-size-leading-space) (xdisp-tests--window-text-pixel-size-trailing-space): Fix tests. (Bug#45748) diff --git a/test/src/xdisp-tests.el b/test/src/xdisp-tests.el index ec96d777ff..4e7d2ad8ab 100644 --- a/test/src/xdisp-tests.el +++ b/test/src/xdisp-tests.el @@ -75,31 +75,28 @@ (ert-deftest xdisp-tests--window-text-pixel-size () ;; bug#45748 (with-temp-buffer (insert "xxx") - (let* ((window - (display-buffer (current-buffer) '(display-buffer-in-child-frame . nil))) - (char-width (frame-char-width)) - (size (window-text-pixel-size nil t t))) - (delete-frame (window-frame window)) - (should (equal (/ (car size) char-width) 3))))) + (switch-to-buffer (current-buffer)) + (let* ((char-width (frame-char-width)) + (size (window-text-pixel-size nil t t)) + (width-in-chars (/ (car size) char-width))) + (should (equal width-in-chars 3))))) (ert-deftest xdisp-tests--window-text-pixel-size-leading-space () ;; bug#45748 (with-temp-buffer (insert " xx") - (let* ((window - (display-buffer (current-buffer) '(display-buffer-in-child-frame . nil))) - (char-width (frame-char-width)) - (size (window-text-pixel-size nil t t))) - (delete-frame (window-frame window)) - (should (equal (/ (car size) char-width) 3))))) + (switch-to-buffer (current-buffer)) + (let* ((char-width (frame-char-width)) + (size (window-text-pixel-size nil t t)) + (width-in-chars (/ (car size) char-width))) + (should (equal width-in-chars 3))))) (ert-deftest xdisp-tests--window-text-pixel-size-trailing-space () ;; bug#45748 (with-temp-buffer (insert "xx ") - (let* ((window - (display-buffer (current-buffer) '(display-buffer-in-child-frame . nil))) - (char-width (frame-char-width)) - (size (window-text-pixel-size nil t t))) - (delete-frame (window-frame window)) - (should (equal (/ (car size) char-width) 3))))) + (switch-to-buffer (current-buffer)) + (let* ((char-width (frame-char-width)) + (size (window-text-pixel-size nil t t)) + (width-in-chars (/ (car size) char-width))) + (should (equal width-in-chars 3))))) ;;; xdisp-tests.el ends here commit f9dab612726148919812ec4ff804df6120022407 Author: Lars Ingebrigtsen Date: Mon Jan 18 17:35:55 2021 +0100 Don't double up keys in epa--list-keys * lisp/epa.el (epa--list-keys): Delete the list keys before redisplaying (bug#44134). diff --git a/lisp/epa.el b/lisp/epa.el index e909b1d869..197cd92f97 100644 --- a/lisp/epa.el +++ b/lisp/epa.el @@ -374,7 +374,7 @@ DOC is documentation text to insert at the start." ;; Now delete the key description text, if any. (when point (delete-region point - (or (next-single-property-change point 'epa-key) + (or (next-single-property-change point 'epa-list-keys) (point-max))) (goto-char point)) commit 455f08c095c5c1606142144508fc91eab0860a6a Author: Stephen Berman Date: Mon Jan 18 17:29:41 2021 +0100 Fix problem with `epa-list-keys' bugging out * lisp/epa.el (epa--list-keys): Partially revert 517285f7cae which removed the wrong property (bug#44134). diff --git a/lisp/epa.el b/lisp/epa.el index db2b127147..e909b1d869 100644 --- a/lisp/epa.el +++ b/lisp/epa.el @@ -359,8 +359,8 @@ DOC is documentation text to insert at the start." ;; Find the end of the documentation text at the start. ;; Set POINT to where it ends, or nil if ends at eob. - (unless (get-text-property point 'epa-list-keys) - (setq point (next-single-property-change point 'epa-list-keys))) + (unless (get-text-property point 'epa-key) + (setq point (next-single-property-change point 'epa-key))) ;; If caller specified documentation text for that, replace the old ;; documentation text (if any) with what was specified. @@ -374,7 +374,7 @@ DOC is documentation text to insert at the start." ;; Now delete the key description text, if any. (when point (delete-region point - (or (next-single-property-change point 'epa-list-keys) + (or (next-single-property-change point 'epa-key) (point-max))) (goto-char point)) commit 36d33776c21b3765b8a611f09ae7d86417abee8a Author: Mattias Engdegård Date: Sun Jan 10 17:05:18 2021 +0100 Avoid macOS NSFilenamesPboardType warning (bug#33035) * src/nsterm.h (NS_USE_NSPasteboardTypeFileURL): New #define. * src/nsterm.m (ns_term_init): ([EmacsView performDragOperation:]): * src/nsselect.m (ns_string_to_symbol): (nxatoms_of_nsselect): NSFilenamesPboardType was deprecated in macOS 10.14; use NSPasteboardTypeFileURL instead when available. diff --git a/src/nsselect.m b/src/nsselect.m index 27db9248e4..5ab3ef77fe 100644 --- a/src/nsselect.m +++ b/src/nsselect.m @@ -78,7 +78,13 @@ Updated by Christian Limpach (chris@nice.ch) return QSECONDARY; if ([t isEqualToString: NSPasteboardTypeString]) return QTEXT; - if ([t isEqualToString: NSFilenamesPboardType]) + if ([t isEqualToString: +#if NS_USE_NSPasteboardTypeFileURL != 0 + NSPasteboardTypeFileURL +#else + NSFilenamesPboardType +#endif + ]) return QFILE_NAME; if ([t isEqualToString: NSPasteboardTypeTabularText]) return QTEXT; @@ -467,7 +473,12 @@ Updated by Christian Limpach (chris@nice.ch) [NSNumber numberWithLong:0], NXPrimaryPboard, [NSNumber numberWithLong:0], NXSecondaryPboard, [NSNumber numberWithLong:0], NSPasteboardTypeString, - [NSNumber numberWithLong:0], NSFilenamesPboardType, + [NSNumber numberWithLong:0], +#if NS_USE_NSPasteboardTypeFileURL != 0 + NSPasteboardTypeFileURL, +#else + NSFilenamesPboardType, +#endif [NSNumber numberWithLong:0], NSPasteboardTypeTabularText, nil] retain]; } diff --git a/src/nsterm.h b/src/nsterm.h index 2c9d8e85ba..eae1d0725e 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -39,6 +39,15 @@ typedef CGFloat EmacsCGFloat; typedef float EmacsCGFloat; #endif +/* NSFilenamesPboardType is deprecated in macOS 10.14, but + NSPasteboardTypeFileURL is only available in 10.13 (and GNUstep + probably lacks it too). */ +#if defined NS_IMPL_COCOA && MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 +#define NS_USE_NSPasteboardTypeFileURL 1 +#else +#define NS_USE_NSPasteboardTypeFileURL 0 +#endif + /* ========================================================================== Trace support diff --git a/src/nsterm.m b/src/nsterm.m index 2defb9e2ee..c5815ce8d1 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -5602,7 +5602,11 @@ Needs to be here because ns_initialize_display_info () uses AppKit classes. ns_drag_types = [[NSArray arrayWithObjects: NSPasteboardTypeString, NSPasteboardTypeTabularText, +#if NS_USE_NSPasteboardTypeFileURL != 0 + NSPasteboardTypeFileURL, +#else NSFilenamesPboardType, +#endif NSPasteboardTypeURL, nil] retain]; /* If fullscreen is in init/default-frame-alist, focus isn't set @@ -8533,9 +8537,19 @@ -(BOOL)performDragOperation: (id ) sender { return NO; } - /* FIXME: NSFilenamesPboardType is deprecated in 10.14, but the - NSURL method can only handle one file at a time. Stick with the - existing code at the moment. */ +#if NS_USE_NSPasteboardTypeFileURL != 0 + else if ([type isEqualToString: NSPasteboardTypeFileURL]) + { + type_sym = Qfile; + + NSArray *urls = [pb readObjectsForClasses: @[[NSURL self]] + options: nil]; + NSEnumerator *uenum = [urls objectEnumerator]; + NSURL *url; + while ((url = [uenum nextObject])) + strings = Fcons ([[url path] lispString], strings); + } +#else // !NS_USE_NSPasteboardTypeFileURL else if ([type isEqualToString: NSFilenamesPboardType]) { NSArray *files; @@ -8551,6 +8565,7 @@ -(BOOL)performDragOperation: (id ) sender while ( (file = [fenum nextObject]) ) strings = Fcons ([file lispString], strings); } +#endif // !NS_USE_NSPasteboardTypeFileURL else if ([type isEqualToString: NSPasteboardTypeURL]) { NSURL *url = [NSURL URLFromPasteboard: pb]; commit 3b4050154e3f72c06501cd9a5ad83841b92c7bd6 Author: Philipp Stephani Date: Mon Jan 18 11:38:58 2021 +0100 Replace Unix commands with Emacs in process tests. That way, the tests only depend on Emacs, and not on utilities that might not be available during test time. * test/src/process-tests.el (process-tests--eval) (process-tests--emacs-command, process-tests--emacs-binary) (process-tests--dump-file) (process-tests--usable-file-for-reinvoke): New helper functions. (process-tests/sentinel-called) (process-tests/sentinel-with-multiple-processes): Use them. diff --git a/test/src/process-tests.el b/test/src/process-tests.el index d2a98dc19f..949f73595b 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -736,15 +736,16 @@ Return nil if that can't be determined." (ert-deftest process-tests/sentinel-called () "Check that sentinels are called after processes finish" - (let ((echo (executable-find "echo"))) - (skip-unless echo) + (let ((command (process-tests--emacs-command))) + (skip-unless command) (dolist (conn-type '(pipe pty)) (ert-info ((format "Connection type: %s" conn-type)) (process-tests--with-processes processes (let* ((calls ()) (process (make-process :name "echo" - :command (list echo "first") + :command (process-tests--eval + command '(print "first")) :noquery t :connection-type conn-type :coding 'utf-8-unix @@ -759,17 +760,16 @@ Return nil if that can't be determined." (ert-deftest process-tests/sentinel-with-multiple-processes () "Check that sentinels are called in time even when other processes have written output." - (let ((echo (executable-find "echo")) - (bash (executable-find "bash"))) - (skip-unless echo) - (skip-unless bash) + (let ((command (process-tests--emacs-command))) + (skip-unless command) (dolist (conn-type '(pipe pty)) (ert-info ((format "Connection type: %s" conn-type)) (process-tests--with-processes processes (let* ((calls ()) (process (make-process :name "echo" - :command (list echo "first") + :command (process-tests--eval + command '(print "first")) :noquery t :connection-type conn-type :coding 'utf-8-unix @@ -779,7 +779,9 @@ have written output." (push process processes) (push (make-process :name "bash" - :command (list bash "-c" "sleep 10 && echo second") + :command (process-tests--eval + command + '(progn (sleep-for 10) (print "second"))) :noquery t :connection-type conn-type) processes) @@ -787,5 +789,65 @@ have written output." (should (equal calls (list (list process "finished\n")))))))))) +(defun process-tests--eval (command form) + "Return a command that evaluates FORM in an Emacs subprocess. +COMMAND must be a list returned by +`process-tests--emacs-command'." + (let ((print-gensym t) + (print-circle t) + (print-length nil) + (print-level nil) + (print-escape-control-characters t) + (print-escape-newlines t) + (print-escape-multibyte t) + (print-escape-nonascii t)) + `(,@command "--quick" "--batch" ,(format "--eval=%S" form)))) + +(defun process-tests--emacs-command () + "Return a command to reinvoke the current Emacs instance. +Return nil if that doesn't appear to be possible." + (when-let ((binary (process-tests--emacs-binary)) + (dump (process-tests--dump-file))) + (cons binary + (unless (eq dump :not-needed) + (list (concat "--dump-file=" + (file-name-unquote dump))))))) + +(defun process-tests--emacs-binary () + "Return the filename of the currently running Emacs binary. +Return nil if that can't be determined." + (and (stringp invocation-name) + (not (file-remote-p invocation-name)) + (not (file-name-absolute-p invocation-name)) + (stringp invocation-directory) + (not (file-remote-p invocation-directory)) + (file-name-absolute-p invocation-directory) + (when-let ((file (process-tests--usable-file-for-reinvoke + (expand-file-name invocation-name + invocation-directory)))) + (and (file-executable-p file) file)))) + +(defun process-tests--dump-file () + "Return the filename of the dump file used to start Emacs. +Return nil if that can't be determined. Return `:not-needed' if +Emacs wasn't started with a dump file." + (if-let ((stats (and (fboundp 'pdumper-stats) (pdumper-stats)))) + (when-let ((file (process-tests--usable-file-for-reinvoke + (cdr (assq 'dump-file-name stats))))) + (and (file-readable-p file) file)) + :not-needed)) + +(defun process-tests--usable-file-for-reinvoke (filename) + "Return a version of FILENAME that can be used to reinvoke Emacs. +Return nil if FILENAME doesn't exist." + (when (and (stringp filename) + (not (file-remote-p filename))) + (cl-callf file-truename filename) + (and (stringp filename) + (not (file-remote-p filename)) + (file-name-absolute-p filename) + (file-regular-p filename) + filename))) + (provide 'process-tests) ;;; process-tests.el ends here commit b215e83a784be1118bb5d729f17597c4f1c62b52 Author: Eli Zaretskii Date: Sun Jan 17 16:53:54 2021 +0200 Improve support for the Cham script and languages * etc/NEWS: Announce the new 'cham' input method. * etc/HELLO: Fix the order of letters in the Cham greeting. Remove redundant newlines (reported by Ulrich Mueller ). * lisp/language/cham.el ("Cham"): Add input-method entry. * lisp/leim/quail/cham.el: New file. * lisp/international/fontset.el (setup-default-fontset): Add an entry for Cham. diff --git a/etc/HELLO b/etc/HELLO index 9a1f5d30ed..0cebb2bb7c 100644 --- a/etc/HELLO +++ b/etc/HELLO @@ -30,22 +30,16 @@ Bengali (বাংলা) নমস্কার Braille ⠓⠑⠇⠇⠕ Burmese (မြန်မာ) မင်္ဂလာပါ C printf ("Hello, world!\n"); -Cham (ꨌꩌ) ꨦꨤꩌ ꨦꨰꨁ - +Cham (ꨌꩌ) ꨦꨤꩌ ꨦꨁꨰ Cherokee (ᏣᎳᎩ ᎦᏬᏂᎯᏍᏗ) ᎣᏏᏲ / ᏏᏲ Comanche /kəˈmæntʃiː/ Haa marʉ́awe - Cree (ᓀᐦᐃᔭᐍᐏᐣ) ᑕᓂᓯ / ᐙᒋᔮ - Czech (čeština) Dobrý den Danish (dansk) Hej / Goddag / Halløj Dutch (Nederlands) Hallo / Dag Efik /ˈɛfɪk/ Mɔkɔm - Egyptian Hieroglyphs (𓂋𓐰𓏤𓈖𓆎𓅓𓏏𓐰𓊖) 𓅓𓊵𓐰𓐷𓏏𓊪𓐸, 𓇍𓇋𓂻𓍘𓇋 - Emacs emacs --no-splash -f view-hello-file - Emoji 👋 English /ˈɪŋɡlɪʃ/ Hello Esperanto Saluton (Eĥoŝanĝo ĉiuĵaŭde) @@ -61,7 +55,6 @@ Hebrew (עִבְרִית) שָׁלוֹם Hungarian (magyar) Szép jó napot! Hindi (हिंदी) नमस्ते / नमस्कार । Inuktitut (ᐃᓄᒃᑎᑐᑦ) ᐊᐃ - Italian (italiano) Ciao / Buon giorno Javanese (ꦧꦱꦗꦮꦶ) console.log("ꦲꦭꦺꦴ"); Kannada (ಕನ್ನಡ) ನಮಸ್ಕಾರ @@ -69,7 +62,6 @@ Khmer (ភាសាខ្មែរ) ជំរាបសួរ Lao (ພາສາລາວ) ສະບາຍດີ / ຂໍໃຫ້ໂຊກດີ Malayalam (മലയാളം) നമസ്കാരം Maldivian (ދިވެހި) އައްސަލާމު ޢަލައިކުމް / ކިހިނެހް؟ - Maltese (il-Malti) Bonġu / Saħħa Mathematics ∀ p ∈ world • hello p □ Mongolian (монгол хэл) Сайн байна уу? @@ -85,7 +77,6 @@ Swedish (svenska) Hej / Goddag / Hallå Tamil (தமிழ்) வணக்கம் Telugu (తెలుగు) నమస్కారం TaiViet (ꪁꪫꪱꪣ ꪼꪕ) ꪅꪰꪙꫂ ꪨꪮꫂ ꪁꪫꪱ / ꪅꪽ ꪨꪷ ꪁꪫꪱ - Thai (ภาษาไทย) สวัสดีครับ / สวัสดีค่ะ Tibetan (བོད་སྐད་) བཀྲ་ཤིས་བདེ་ལེགས༎ Tigrigna (ትግርኛ) ሰላማት @@ -99,7 +90,6 @@ Vietnamese (tiếng Việt) Chào bạn chinese-gb2312Chinese (中文,普通话,汉语) 你好 chinese-big5-1Cantonese (粵語,廣東話) 早晨, 你好 korean-ksc5601Korean (한글) 안녕하세요 / 안녕하십니까 - diff --git a/etc/NEWS b/etc/NEWS index 359d308bf1..d632283e7f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -827,6 +827,10 @@ so e.g. like 'C-x 8 [' inserts a left single quotation mark, Added a new Mozhi scheme. The inapplicable ITRANS scheme is now deprecated. Errors in the Inscript method were corrected. +--- +*** New input method 'cham'. +There's also a Cham greeting in 'etc/HELLO'. + ** Ispell +++ diff --git a/lisp/international/fontset.el b/lisp/international/fontset.el index 14e7b89dd1..8f0f263dcc 100644 --- a/lisp/international/fontset.el +++ b/lisp/international/fontset.el @@ -719,6 +719,7 @@ georgian cherokee canadian-aboriginal + cham ogham runic symbol diff --git a/lisp/language/cham.el b/lisp/language/cham.el index 194574f6a8..59eaef67bf 100644 --- a/lisp/language/cham.el +++ b/lisp/language/cham.el @@ -35,6 +35,7 @@ "Cham" '((charset unicode) (coding-system utf-8) (coding-priority utf-8) + (input-method . "cham") (sample-text . "Cham (ꨌꩌ)\tꨦꨤꩌ ꨦꨰꨁ") (documentation . "\ The Cham script is a Brahmic script used to write Cham, commit 372694e7c6b264fb0c8e316d9f0033e0fd22ee7a Author: Ted Zlatanov Date: Sun Jan 17 13:59:59 2021 +0000 ; * test/infra/gitlab-ci.yml: Merge test-template script into job-template. diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml index 78743d1adb..3214f01edd 100644 --- a/test/infra/gitlab-ci.yml +++ b/test/infra/gitlab-ci.yml @@ -94,6 +94,11 @@ default: paths: [] # - "test/**/*.log" # - "**/*.log" + # using the variables for each job + script: + - docker pull ${CI_REGISTRY_IMAGE}:${target}-${CI_COMMIT_SHA} + # TODO: with make -j4 several of the tests were failing, for example shadowfile-tests, but passed without it + - docker run -i --rm -e EMACS_EMBA_CI=${EMACS_EMBA_CI} ${CI_REGISTRY_IMAGE}:${target}-${CI_COMMIT_SHA} make ${make_params} .build-template: script: @@ -127,12 +132,6 @@ default: - test/lisp/autorevert-tests.el - test/lisp/filenotify-tests.el - # using the variables for each job - script: - - docker pull ${CI_REGISTRY_IMAGE}:${target}-${CI_COMMIT_SHA} - # TODO: with make -j4 several of the tests were failing, for example shadowfile-tests, but passed without it - - docker run -i --rm -e EMACS_EMBA_CI=${EMACS_EMBA_CI} ${CI_REGISTRY_IMAGE}:${target}-${CI_COMMIT_SHA} make ${make_params} - stages: - prep-images - build-images commit 1fe135a024dde56fe904c35f14d6b30add024f5b Author: Ted Zlatanov Date: Sun Jan 17 13:56:27 2021 +0000 * test/infra/gitlab-ci.yml: Merge test-template into job-template. diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml index b8d068a847..78743d1adb 100644 --- a/test/infra/gitlab-ci.yml +++ b/test/infra/gitlab-ci.yml @@ -59,6 +59,30 @@ default: - docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY} .job-template: + rules: + - changes: + - "**/Makefile.in" + - .gitlab-ci.yml + - aclocal.m4 + - autogen.sh + - configure.ac + - lib/*.{h,c} + - lisp/**/*.el + - src/*.{h,c} + - test/infra/* + - test/lisp/**/*.el + - test/src/*.el + - changes: + # gfilemonitor, kqueue + - src/gfilenotify.c + - src/kqueue.c + # MS Windows + - "**/w32*" + # GNUstep + - lisp/term/ns-win.el + - src/ns*.{h,m} + - src/macfont.{h,m} + when: never # these will be cached across builds cache: key: ${CI_COMMIT_SHA} @@ -103,32 +127,6 @@ default: - test/lisp/autorevert-tests.el - test/lisp/filenotify-tests.el -.test-template: - rules: - - changes: - - "**/Makefile.in" - - .gitlab-ci.yml - - aclocal.m4 - - autogen.sh - - configure.ac - - lib/*.{h,c} - - lisp/**/*.el - - src/*.{h,c} - - test/infra/* - - test/lisp/**/*.el - - test/src/*.el - - changes: - # gfilemonitor, kqueue - - src/gfilenotify.c - - src/kqueue.c - # MS Windows - - "**/w32*" - # GNUstep - - lisp/term/ns-win.el - - src/ns*.{h,m} - - src/macfont.{h,m} - when: never - # using the variables for each job script: - docker pull ${CI_REGISTRY_IMAGE}:${target}-${CI_COMMIT_SHA} @@ -158,7 +156,7 @@ build-image-inotify: test-fast-inotify: stage: fast - extends: [.job-template, .test-template] + extends: [.job-template] variables: target: emacs-inotify make_params: "-C test check" @@ -177,14 +175,14 @@ build-image-gnustep: test-lisp-inotify: stage: normal - extends: [.job-template, .test-template] + extends: [.job-template] variables: target: emacs-inotify make_params: "-C test check-lisp" test-lisp-net-inotify: stage: normal - extends: [.job-template, .test-template] + extends: [.job-template] variables: target: emacs-inotify make_params: "-C test check-lisp-net" @@ -192,7 +190,7 @@ test-lisp-net-inotify: test-filenotify-gio: # This tests file monitor libraries gfilemonitor and gio. stage: platforms - extends: [.job-template, .test-template, .filenotify-gio-template] + extends: [.job-template, .filenotify-gio-template] variables: target: emacs-filenotify-gio make_params: "-k -C test autorevert-tests filenotify-tests" @@ -200,7 +198,7 @@ test-filenotify-gio: test-gnustep: # This tests the GNUstep build process stage: platforms - extends: [.job-template, .test-template, .gnustep-template] + extends: [.job-template, .gnustep-template] variables: target: emacs-gnustep make_params: install @@ -208,7 +206,7 @@ test-gnustep: test-all-inotify: # This tests also file monitor libraries inotify and inotifywatch. stage: slow - extends: [.job-template, .test-template] + extends: [.job-template] rules: # note there's no "changes" section, so this always runs on a schedule - if: '$CI_PIPELINE_SOURCE == "schedule"' commit 1773679af3241919a85d6174b1554070a63cca79 Author: Philipp Stephani Date: Sun Jan 17 14:00:16 2021 +0100 Ensure that sentinels are called during 'accept-process-output'. When we're trying to notify a process about a status change, we need to ignore the SIGCHLD pipe temporarily, otherwise the code would likely not run into the timeout case that's necessary for a status change to happen. * src/process.c (wait_reading_process_output): Ignore the SIGCHLD pipe when notifying a process about a status change. * test/src/process-tests.el (process-tests/sentinel-called) (process-tests/sentinel-with-multiple-processes): New unit tests. diff --git a/src/process.c b/src/process.c index aca87f8ed3..09f87908a4 100644 --- a/src/process.c +++ b/src/process.c @@ -5323,6 +5323,15 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, compute_input_wait_mask (&Atemp); compute_write_mask (&Ctemp); + /* If a process status has changed, the child signal pipe + will likely be readable. We want to ignore it for now, + because otherwise we wouldn't run into a timeout + below. */ + int fd = child_signal_read_fd; + eassert (fd < FD_SETSIZE); + if (0 <= fd) + FD_CLR (fd, &Atemp); + timeout = make_timespec (0, 0); if ((thread_select (pselect, max_desc + 1, &Atemp, diff --git a/test/src/process-tests.el b/test/src/process-tests.el index dad36426a0..d2a98dc19f 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -734,5 +734,58 @@ Return nil if that can't be determined." (match-string-no-properties 1)))))) process-tests--EMFILE-message) +(ert-deftest process-tests/sentinel-called () + "Check that sentinels are called after processes finish" + (let ((echo (executable-find "echo"))) + (skip-unless echo) + (dolist (conn-type '(pipe pty)) + (ert-info ((format "Connection type: %s" conn-type)) + (process-tests--with-processes processes + (let* ((calls ()) + (process (make-process + :name "echo" + :command (list echo "first") + :noquery t + :connection-type conn-type + :coding 'utf-8-unix + :sentinel (lambda (process message) + (push (list process message) + calls))))) + (push process processes) + (while (accept-process-output process)) + (should (equal calls + (list (list process "finished\n")))))))))) + +(ert-deftest process-tests/sentinel-with-multiple-processes () + "Check that sentinels are called in time even when other processes +have written output." + (let ((echo (executable-find "echo")) + (bash (executable-find "bash"))) + (skip-unless echo) + (skip-unless bash) + (dolist (conn-type '(pipe pty)) + (ert-info ((format "Connection type: %s" conn-type)) + (process-tests--with-processes processes + (let* ((calls ()) + (process (make-process + :name "echo" + :command (list echo "first") + :noquery t + :connection-type conn-type + :coding 'utf-8-unix + :sentinel (lambda (process message) + (push (list process message) + calls))))) + (push process processes) + (push (make-process + :name "bash" + :command (list bash "-c" "sleep 10 && echo second") + :noquery t + :connection-type conn-type) + processes) + (while (accept-process-output process)) + (should (equal calls + (list (list process "finished\n")))))))))) + (provide 'process-tests) ;;; process-tests.el ends here commit 39a65844e8d67b5ca3bb2d179e899ff99cd85618 Author: Michael Albinus Date: Sun Jan 17 13:37:58 2021 +0100 Add new targets to test/Makefile * test/Makefile.in (SUBDIRS): New variable. (subdir_template): New template. (top) Create new check- targets. * test/README: Document them. * test/infra/gitlab-ci.yml (test-lisp-net-inotify): Rename. diff --git a/test/Makefile.in b/test/Makefile.in index 2d595d9bf1..4ca43c8c44 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -246,11 +246,17 @@ endef $(foreach test,${TESTS},$(eval $(call test_template,${test}))) -# Get the tests for only a specific directory -NET_TESTS := $(patsubst %.el,%,$(wildcard lisp/net/*.el)) -LISP_TESTS := $(patsubst %.el,%,$(wildcard lisp/*.el)) -check-net: ${NET_TESTS} -check-lisp: ${LISP_TESTS} +## Get the tests for only a specific directory. +SUBDIRS = $(sort $(shell find lisp src -type d ! -path "*resources*" -print)) + +define subdir_template + .PHONY: check-$(subst /,-,$(1)) + check-$(subst /,-,$(1)): + @${MAKE} check LOGFILES="$(patsubst %.el,%.log, \ + $(patsubst $(srcdir)/%,%,$(wildcard $(1)/*.el)))" +endef + +$(foreach subdir, $(SUBDIRS), $(eval $(call subdir_template,$(subdir)))) ifeq (@HAVE_MODULES@, yes) # -fPIC is a no-op on Windows, but causes a compiler warning @@ -318,10 +324,10 @@ check-doit: ifeq ($(TEST_INTERACTIVE), yes) HOME=$(TEST_HOME) $(emacs) \ -l ert ${ert_opts} \ - $(patsubst %,-l %,$(if $(findstring $(TEST_LOAD_EL),yes),$ELFILES,$(ELFILES:.el=))) \ + $(patsubst %,-l %,$(if $(findstring $(TEST_LOAD_EL),yes),$ELFILES,$(ELFILES:.el=))) \ $(TEST_RUN_ERT) else - -@${MAKE} -k ${LOGFILES} + -@${MAKE} -k ${LOGFILES} @$(emacs) --batch -l ert --eval \ "(ert-summarize-tests-batch-and-exit ${SUMMARIZE_TESTS})" ${LOGFILES} endif diff --git a/test/README b/test/README index 38f4a10970..58f5f38bec 100644 --- a/test/README +++ b/test/README @@ -39,11 +39,10 @@ The Makefile in this directory supports the following targets: * make check-all Like "make check", but run all tests. -* make check-lisp - Like "make check", but run only the tests in test/lisp/*.el - -* make check-net - Like "make check", but run only the tests in test/lisp/net/*.el +* make check- + Like "make check", but run only the tests in test//*.el. + is a relative directory path, which has replaced "/" by "-", + like in "check-src" or "check-lisp-net". * make -or- make .log Run all tests declared in .el. This includes expensive diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml index f9c0e0c11a..b8d068a847 100644 --- a/test/infra/gitlab-ci.yml +++ b/test/infra/gitlab-ci.yml @@ -182,12 +182,12 @@ test-lisp-inotify: target: emacs-inotify make_params: "-C test check-lisp" -test-net-inotify: +test-lisp-net-inotify: stage: normal extends: [.job-template, .test-template] variables: target: emacs-inotify - make_params: "-C test check-net" + make_params: "-C test check-lisp-net" test-filenotify-gio: # This tests file monitor libraries gfilemonitor and gio. commit 152964362f905ba4f6d60d8c082330b739b8bc8e Author: Philipp Stephani Date: Sun Jan 17 11:52:40 2021 +0100 Add a bit more clarification around standard error processes. * doc/lispref/processes.texi (Asynchronous Processes): Document how to obtain the standard error process that Emacs creates. (Accepting Output): Add an example how to wait for standard error in case Emacs has created a standard error process. diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 535cebed7a..6dedaa31f2 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -729,7 +729,9 @@ coding systems (@pxref{Default Coding Systems}). On the other hand, it will use @var{query-flag} as its query-on-exit flag (@pxref{Query Before Exit}). It will be associated with the @var{stderr} buffer (@pxref{Process Buffers}) and send its output (which is the standard -error of the main process) there. +error of the main process) there. To get the process object for the +standard error process, pass the @var{stderr} buffer to +@code{get-buffer-process}. If @var{stderr} is a pipe process, Emacs will use it as standard error process for the new process. @@ -1942,6 +1944,29 @@ code: (while (accept-process-output stderr-process)) @end example +If you passed a buffer to the @var{stderr} argument of +@code{make-process}, you still have to wait for the standard error +process, like so: + +@example +(let* ((stdout (generate-new-buffer "stdout")) + (stderr (generate-new-buffer "stderr")) + (process (make-process :name "test" + :command '("my-program") + :buffer stdout + :stderr stderr)) + (stderr-process (get-buffer-process stderr))) + (unless (and process stderr-process) + (error "Process unexpectedly nil")) + (while (accept-process-output process)) + (while (accept-process-output stderr-process))) +@end example + +@noindent +Only when both @code{accept-process-output} forms return @code{nil}, +you can be sure that the process has exited and Emacs has read all its +output. + Reading pending standard error from a process running on a remote host is not possible this way. commit 25e1b732947bcba51e457a7168eba6608fb666c0 Author: Stefan Monnier Date: Sat Jan 16 10:51:09 2021 -0500 * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Use pcase diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index cf89456541..f29f85b965 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -374,185 +374,184 @@ ;; the important aspect is that they are subrs that don't evaluate all of ;; their args.) ;; - (let ((fn (car-safe form)) - tmp) - (cond ((not (consp form)) - (if (not (and for-effect - (or byte-compile-delete-errors - (not (symbolp form)) - (eq form t)))) - form)) - ((eq fn 'quote) - (if (cdr (cdr form)) - (byte-compile-warn "malformed quote form: `%s'" - (prin1-to-string form))) - ;; map (quote nil) to nil to simplify optimizer logic. - ;; map quoted constants to nil if for-effect (just because). - (and (nth 1 form) - (not for-effect) - form)) - ((memq fn '(let let*)) - ;; recursively enter the optimizer for the bindings and body - ;; of a let or let*. This for depth-firstness: forms that - ;; are more deeply nested are optimized first. - (cons fn + ;; FIXME: There are a bunch of `byte-compile-warn' here which arguably + ;; have no place in an optimizer: the corresponding tests should be + ;; performed in `macroexpand-all', or in `cconv', or in `bytecomp'. + (let ((fn (car-safe form))) + (pcase form + ((pred (not consp)) + (if (not (and for-effect + (or byte-compile-delete-errors + (not (symbolp form)) + (eq form t)))) + form)) + (`(quote . ,v) + (if (cdr v) + (byte-compile-warn "malformed quote form: `%s'" + (prin1-to-string form))) + ;; Map (quote nil) to nil to simplify optimizer logic. + ;; Map quoted constants to nil if for-effect (just because). + (and (car v) + (not for-effect) + form)) + (`(,(or 'let 'let*) . ,(or `(,bindings . ,exps) pcase--dontcare)) + ;; Recursively enter the optimizer for the bindings and body + ;; of a let or let*. This for depth-firstness: forms that + ;; are more deeply nested are optimized first. + (cons fn (cons (mapcar (lambda (binding) - (if (symbolp binding) - binding - (if (cdr (cdr binding)) - (byte-compile-warn "malformed let binding: `%s'" - (prin1-to-string binding))) - (list (car binding) - (byte-optimize-form (nth 1 binding) nil)))) - (nth 1 form)) - (byte-optimize-body (cdr (cdr form)) for-effect)))) - ((eq fn 'cond) - (cons fn - (mapcar (lambda (clause) - (if (consp clause) - (cons - (byte-optimize-form (car clause) nil) - (byte-optimize-body (cdr clause) for-effect)) - (byte-compile-warn "malformed cond form: `%s'" - (prin1-to-string clause)) - clause)) - (cdr form)))) - ((eq fn 'progn) - ;; As an extra added bonus, this simplifies (progn ) --> . - (if (cdr (cdr form)) - (macroexp-progn (byte-optimize-body (cdr form) for-effect)) - (byte-optimize-form (nth 1 form) for-effect))) - ((eq fn 'prog1) - (if (cdr (cdr form)) - (cons 'prog1 - (cons (byte-optimize-form (nth 1 form) for-effect) - (byte-optimize-body (cdr (cdr form)) t))) - (byte-optimize-form (nth 1 form) for-effect))) - - ((memq fn '(save-excursion save-restriction save-current-buffer)) - ;; those subrs which have an implicit progn; it's not quite good - ;; enough to treat these like normal function calls. - ;; This can turn (save-excursion ...) into (save-excursion) which - ;; will be optimized away in the lap-optimize pass. - (cons fn (byte-optimize-body (cdr form) for-effect))) - - ((eq fn 'if) - (when (< (length form) 3) - (byte-compile-warn "too few arguments for `if'")) - (cons fn - (cons (byte-optimize-form (nth 1 form) nil) - (cons - (byte-optimize-form (nth 2 form) for-effect) - (byte-optimize-body (nthcdr 3 form) for-effect))))) - - ((memq fn '(and or)) ; Remember, and/or are control structures. - ;; Take forms off the back until we can't any more. - ;; In the future it could conceivably be a problem that the - ;; subexpressions of these forms are optimized in the reverse - ;; order, but it's ok for now. - (if for-effect - (let ((backwards (reverse (cdr form)))) - (while (and backwards - (null (setcar backwards - (byte-optimize-form (car backwards) - for-effect)))) - (setq backwards (cdr backwards))) - (if (and (cdr form) (null backwards)) - (byte-compile-log - " all subforms of %s called for effect; deleted" form)) - (and backwards - (cons fn (nreverse (mapcar 'byte-optimize-form - backwards))))) - (cons fn (mapcar 'byte-optimize-form (cdr form))))) - - ((eq fn 'while) - (unless (consp (cdr form)) - (byte-compile-warn "too few arguments for `while'")) - (cons fn - (cons (byte-optimize-form (cadr form) nil) - (byte-optimize-body (cddr form) t)))) - - ((eq fn 'interactive) - (byte-compile-warn "misplaced interactive spec: `%s'" - (prin1-to-string form)) - nil) - - ((eq fn 'function) - ;; This forms is compiled as constant or by breaking out - ;; all the subexpressions and compiling them separately. - form) - - ((eq fn 'condition-case) - `(condition-case ,(nth 1 form) ;Not evaluated. - ,(byte-optimize-form (nth 2 form) for-effect) - ,@(mapcar (lambda (clause) - `(,(car clause) - ,@(byte-optimize-body (cdr clause) for-effect))) - (nthcdr 3 form)))) - - ((eq fn 'unwind-protect) - ;; the "protected" part of an unwind-protect is compiled (and thus - ;; optimized) as a top-level form, so don't do it here. But the - ;; non-protected part has the same for-effect status as the - ;; unwind-protect itself. (The protected part is always for effect, - ;; but that isn't handled properly yet.) - (cons fn - (cons (byte-optimize-form (nth 1 form) for-effect) - (cdr (cdr form))))) - - ((eq fn 'catch) - (cons fn - (cons (byte-optimize-form (nth 1 form) nil) - (byte-optimize-body (cdr form) for-effect)))) - - ((eq fn 'ignore) - ;; Don't treat the args to `ignore' as being - ;; computed for effect. We want to avoid the warnings - ;; that might occur if they were treated that way. - ;; However, don't actually bother calling `ignore'. - `(prog1 nil . ,(mapcar 'byte-optimize-form (cdr form)))) - - ;; Needed as long as we run byte-optimize-form after cconv. - ((eq fn 'internal-make-closure) form) - - ((eq (car-safe fn) 'lambda) - (let ((newform (byte-compile-unfold-lambda form))) - (if (eq newform form) - ;; Some error occurred, avoid infinite recursion - form - (byte-optimize-form newform for-effect)))) - - ((eq (car-safe fn) 'closure) form) - - ((byte-code-function-p fn) - (cons fn (mapcar #'byte-optimize-form (cdr form)))) - - ((not (symbolp fn)) - (byte-compile-warn "`%s' is a malformed function" - (prin1-to-string fn)) - form) - - ((and for-effect (setq tmp (get fn 'side-effect-free)) - (or byte-compile-delete-errors - (eq tmp 'error-free) - (progn - (byte-compile-warn "value returned from %s is unused" - (prin1-to-string form)) - nil))) - (byte-compile-log " %s called for effect; deleted" fn) - ;; appending a nil here might not be necessary, but it can't hurt. - (byte-optimize-form - (cons 'progn (append (cdr form) '(nil))) t)) + (if (symbolp binding) + binding + (if (cdr (cdr binding)) + (byte-compile-warn "malformed let binding: `%s'" + (prin1-to-string binding))) + (list (car binding) + (byte-optimize-form (nth 1 binding) nil)))) + bindings) + (byte-optimize-body exps for-effect)))) + (`(cond . ,clauses) + (cons fn + (mapcar (lambda (clause) + (if (consp clause) + (cons + (byte-optimize-form (car clause) nil) + (byte-optimize-body (cdr clause) for-effect)) + (byte-compile-warn "malformed cond form: `%s'" + (prin1-to-string clause)) + clause)) + clauses))) + (`(progn . ,exps) + ;; As an extra added bonus, this simplifies (progn ) --> . + (if (cdr exps) + (macroexp-progn (byte-optimize-body exps for-effect)) + (byte-optimize-form (car exps) for-effect))) + (`(prog1 . ,(or `(,exp . ,exps) pcase--dontcare)) + (if exps + `(prog1 ,(byte-optimize-form exp for-effect) + . ,(byte-optimize-body exps t)) + (byte-optimize-form exp for-effect))) + + (`(,(or `save-excursion `save-restriction `save-current-buffer) . ,exps) + ;; Those subrs which have an implicit progn; it's not quite good + ;; enough to treat these like normal function calls. + ;; This can turn (save-excursion ...) into (save-excursion) which + ;; will be optimized away in the lap-optimize pass. + (cons fn (byte-optimize-body exps for-effect))) + + (`(if ,test ,then . ,else) + `(if ,(byte-optimize-form test nil) + ,(byte-optimize-form then for-effect) + . ,(byte-optimize-body else for-effect))) + (`(if . ,_) + (byte-compile-warn "too few arguments for `if'")) + + (`(,(or 'and 'or) . ,exps) ; Remember, and/or are control structures. + ;; Take forms off the back until we can't any more. + ;; In the future it could conceivably be a problem that the + ;; subexpressions of these forms are optimized in the reverse + ;; order, but it's ok for now. + (if for-effect + (let ((backwards (reverse exps))) + (while (and backwards + (null (setcar backwards + (byte-optimize-form (car backwards) + for-effect)))) + (setq backwards (cdr backwards))) + (if (and exps (null backwards)) + (byte-compile-log + " all subforms of %s called for effect; deleted" form)) + (and backwards + (cons fn (nreverse (mapcar #'byte-optimize-form + backwards))))) + (cons fn (mapcar #'byte-optimize-form exps)))) + + (`(while ,exp . ,exps) + `(while ,(byte-optimize-form exp nil) + . ,(byte-optimize-body exps t))) + (`(while . ,_) + (byte-compile-warn "too few arguments for `while'")) + + (`(interactive . ,_) + (byte-compile-warn "misplaced interactive spec: `%s'" + (prin1-to-string form)) + nil) + + (`(function . ,_) + ;; This forms is compiled as constant or by breaking out + ;; all the subexpressions and compiling them separately. + form) - (t - ;; Otherwise, no args can be considered to be for-effect, - ;; even if the called function is for-effect, because we - ;; don't know anything about that function. - (let ((form (cons fn (mapcar #'byte-optimize-form (cdr form))))) - (if (get fn 'pure) - (byte-optimize-constant-args form) - form)))))) + (`(condition-case . ,(or `(,var ,exp . ,clauses) pcase--dontcare)) + `(condition-case ,var ;Not evaluated. + ,(byte-optimize-form exp for-effect) + ,@(mapcar (lambda (clause) + `(,(car clause) + ,@(byte-optimize-body (cdr clause) for-effect))) + clauses))) + + (`(unwind-protect . ,(or `(,exp . ,exps) pcase--dontcare)) + ;; The "protected" part of an unwind-protect is compiled (and thus + ;; optimized) as a top-level form, so don't do it here. But the + ;; non-protected part has the same for-effect status as the + ;; unwind-protect itself. (The protected part is always for effect, + ;; but that isn't handled properly yet.) + `(unwind-protect ,(byte-optimize-form exp for-effect) . ,exps)) + + (`(catch . ,(or `(,tag . ,exps) pcase--dontcare)) + `(catch ,(byte-optimize-form tag nil) + . ,(byte-optimize-body exps for-effect))) + + (`(ignore . ,exps) + ;; Don't treat the args to `ignore' as being + ;; computed for effect. We want to avoid the warnings + ;; that might occur if they were treated that way. + ;; However, don't actually bother calling `ignore'. + `(prog1 nil . ,(mapcar #'byte-optimize-form exps))) + + ;; Needed as long as we run byte-optimize-form after cconv. + (`(internal-make-closure . ,_) form) + + (`((lambda . ,_) . ,_) + (let ((newform (byte-compile-unfold-lambda form))) + (if (eq newform form) + ;; Some error occurred, avoid infinite recursion. + form + (byte-optimize-form newform for-effect)))) + + ;; FIXME: Strictly speaking, I think this is a bug: (closure...) + ;; is a *value* and shouldn't appear in the car. + (`((closure . ,_) . ,_) form) + + (`(,(pred byte-code-function-p) . ,exps) + (cons fn (mapcar #'byte-optimize-form exps))) + + (`(,(pred (not symbolp)) . ,_) + (byte-compile-warn "`%s' is a malformed function" + (prin1-to-string fn)) + form) + + ((guard (when for-effect + (if-let ((tmp (get fn 'side-effect-free))) + (or byte-compile-delete-errors + (eq tmp 'error-free) + (progn + (byte-compile-warn "value returned from %s is unused" + (prin1-to-string form)) + nil))))) + (byte-compile-log " %s called for effect; deleted" fn) + ;; appending a nil here might not be necessary, but it can't hurt. + (byte-optimize-form + (cons 'progn (append (cdr form) '(nil))) t)) + + (_ + ;; Otherwise, no args can be considered to be for-effect, + ;; even if the called function is for-effect, because we + ;; don't know anything about that function. + (let ((form (cons fn (mapcar #'byte-optimize-form (cdr form))))) + (if (get fn 'pure) + (byte-optimize-constant-args form) + form)))))) (defun byte-optimize-form (form &optional for-effect) "The source-level pass of the optimizer." commit 0ab56a4e935b3aa759229923804ba33c841f425c Author: Stefan Monnier Date: Sat Jan 16 10:15:47 2021 -0500 * lisp/emacs-lisp/pcase.el: Add support for `not` to `pred` (pcase--split-pred, pcase--funcall): Adjust for `not`. (pcase--get-macroexpander): New function. (pcase--edebug-match-macro, pcase--make-docstring) (pcase--macroexpand): Use it. * lisp/emacs-lisp/radix-tree.el (radix-tree-leaf): Use it! * doc/lispref/control.texi (The @code{pcase} macro): Document it. * lisp/emacs-lisp/ert.el (ert--explain-equal-rec): Remove redundant test. diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 55bcddb31a..80e9eb7dd8 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -557,8 +557,9 @@ Likewise, it makes no sense to bind keyword symbols @item (pred @var{function}) Matches if the predicate @var{function} returns non-@code{nil} -when called on @var{expval}. -the predicate @var{function} can have one of the following forms: +when called on @var{expval}. The test can be negated with the syntax +@code{(pred (not @var{function}))}. +The predicate @var{function} can have one of the following forms: @table @asis @item function name (a symbol) diff --git a/etc/NEWS b/etc/NEWS index fc7dcbcf4c..359d308bf1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -326,6 +326,12 @@ the buffer cycles the whole buffer between "only top-level headings", * Changes in Specialized Modes and Packages in Emacs 28.1 +** pcase ++++ +*** The `pred` pattern can now take the form (pred (not FUN)). +This is like (pred (lambda (x) (not (FUN x)))) but results +in better code. + +++ ** profiler.el The results displayed by 'profiler-report' now have the usage figures diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index 5851754945..fdbf95319f 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -487,7 +487,7 @@ Errors during evaluation are caught and handled like nil." Returns nil if they are." (if (not (eq (type-of a) (type-of b))) `(different-types ,a ,b) - (pcase-exhaustive a + (pcase a ((pred consp) (let ((a-length (proper-list-p a)) (b-length (proper-list-p b))) @@ -538,7 +538,7 @@ Returns nil if they are." for xi = (ert--explain-equal-rec ai bi) do (when xi (cl-return `(array-elt ,i ,xi))) finally (cl-assert (equal a b) t)))) - ((pred atom) + (_ (if (not (equal a b)) (if (and (symbolp a) (symbolp b) (string= a b)) `(different-symbols-with-the-same-name ,a ,b) diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 72ea1ba018..bfd577c5d1 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -39,10 +39,10 @@ ;; - along these lines, provide patterns to match CL structs. ;; - provide something like (setq VAR) so a var can be set rather than ;; let-bound. -;; - provide a way to fallthrough to subsequent cases (not sure what I meant by -;; this :-() +;; - provide a way to fallthrough to subsequent cases +;; (e.g. Like Racket's (=> ID). ;; - try and be more clever to reduce the size of the decision tree, and -;; to reduce the number of leaves that need to be turned into function: +;; to reduce the number of leaves that need to be turned into functions: ;; - first, do the tests shared by all remaining branches (it will have ;; to be performed anyway, so better do it first so it's shared). ;; - then choose the test that discriminates more (?). @@ -97,11 +97,15 @@ (declare-function get-edebug-spec "edebug" (symbol)) (declare-function edebug-match "edebug" (cursor specs)) +(defun pcase--get-macroexpander (s) + "Return the macroexpander for pcase pattern head S, or nil" + (get s 'pcase-macroexpander)) + (defun pcase--edebug-match-macro (cursor) (let (specs) (mapatoms (lambda (s) - (let ((m (get s 'pcase-macroexpander))) + (let ((m (pcase--get-macroexpander s))) (when (and m (get-edebug-spec m)) (push (cons (symbol-name s) (get-edebug-spec m)) specs))))) @@ -128,6 +132,7 @@ PATTERN matches. PATTERN can take one of the forms: If a SYMBOL is used twice in the same pattern the second occurrence becomes an `eq'uality test. (pred FUN) matches if FUN called on EXPVAL returns non-nil. + (pred (not FUN)) matches if FUN called on EXPVAL returns nil. (app FUN PAT) matches if FUN called on EXPVAL matches PAT. (guard BOOLEXP) matches if BOOLEXP evaluates to non-nil. (let PAT EXPR) matches if EXPR matches PAT. @@ -193,7 +198,7 @@ Emacs Lisp manual for more information and examples." (let (more) ;; Collect all the extensions. (mapatoms (lambda (symbol) - (let ((me (get symbol 'pcase-macroexpander))) + (let ((me (pcase--get-macroexpander symbol))) (when me (push (cons symbol me) more))))) @@ -424,7 +429,7 @@ of the elements of LIST is performed as if by `pcase-let'. ((eq head 'let) `(let ,(pcase--macroexpand (cadr pat)) ,@(cddr pat))) ((eq head 'app) `(app ,(nth 1 pat) ,(pcase--macroexpand (nth 2 pat)))) (t - (let* ((expander (get head 'pcase-macroexpander)) + (let* ((expander (pcase--get-macroexpander head)) (npat (if expander (apply expander (cdr pat))))) (if (null npat) (error (if expander @@ -658,6 +663,14 @@ MATCH is the pattern that needs to be matched, of the form: '(:pcase--succeed . nil)))) (defun pcase--split-pred (vars upat pat) + "Indicate the overlap or mutual-exclusion between UPAT and PAT. +More specifically retuns a pair (A . B) where A indicates whether PAT +can match when UPAT has matched, and B does the same for the case +where UPAT failed to match. +A and B can be one of: +- nil if we don't know +- `:pcase--fail' if UPAT match's result implies that PAT can't match +- `:pcase--succeed' if UPAT match's result implies that PAT matches" (let (test) (cond ((and (equal upat pat) @@ -670,6 +683,19 @@ MATCH is the pattern that needs to be matched, of the form: ;; and catch at least the easy cases such as (bug#14773). (not (macroexp--fgrep (mapcar #'car vars) (cadr upat))))) '(:pcase--succeed . :pcase--fail)) + ;; In case UPAT is of the form (pred (not PRED)) + ((and (eq 'pred (car upat)) (eq 'not (car-safe (cadr upat)))) + (let* ((test (cadr (cadr upat))) + (res (pcase--split-pred vars `(pred ,test) pat))) + (cons (cdr res) (car res)))) + ;; In case PAT is of the form (pred (not PRED)) + ((and (eq 'pred (car-safe pat)) (eq 'not (car-safe (cadr pat)))) + (let* ((test (cadr (cadr pat))) + (res (pcase--split-pred vars upat `(pred ,test))) + (reverse (lambda (x) (cond ((eq x :pcase--succeed) :pcase--fail) + ((eq x :pcase--fail) :pcase--succeed))))) + (cons (funcall reverse (car res)) + (funcall reverse (cdr res))))) ((and (eq 'pred (car upat)) (let ((otherpred (cond ((eq 'pred (car-safe pat)) (cadr pat)) @@ -728,8 +754,10 @@ MATCH is the pattern that needs to be matched, of the form: (defun pcase--funcall (fun arg vars) "Build a function call to FUN with arg ARG." - (if (symbolp fun) - `(,fun ,arg) + (cond + ((symbolp fun) `(,fun ,arg)) + ((eq 'not (car-safe fun)) `(not ,(pcase--funcall (cadr fun) arg vars))) + (t (let* (;; `env' is an upper bound on the bindings we need. (env (mapcar (lambda (x) (list (car x) (cdr x))) (macroexp--fgrep vars fun))) @@ -747,7 +775,7 @@ MATCH is the pattern that needs to be matched, of the form: ;; Let's not replace `vars' in `fun' since it's ;; too difficult to do it right, instead just ;; let-bind `vars' around `fun'. - `(let* ,env ,call))))) + `(let* ,env ,call)))))) (defun pcase--eval (exp vars) "Build an expression that will evaluate EXP." diff --git a/lisp/emacs-lisp/radix-tree.el b/lisp/emacs-lisp/radix-tree.el index 6a483a6d49..0905ac608b 100644 --- a/lisp/emacs-lisp/radix-tree.el +++ b/lisp/emacs-lisp/radix-tree.el @@ -198,9 +198,10 @@ If not found, return nil." (pcase-defmacro radix-tree-leaf (vpat) "Pattern which matches a radix-tree leaf. The pattern VPAT is matched against the leaf's carried value." - ;; FIXME: We'd like to use a negative pattern (not consp), but pcase - ;; doesn't support it. Using `atom' works but generates sub-optimal code. - `(or `(t . ,,vpat) (and (pred atom) ,vpat)))) + ;; We used to use `(pred atom)', but `pcase' doesn't understand that + ;; `atom' is equivalent to the negation of `consp' and hence generates + ;; suboptimal code. + `(or `(t . ,,vpat) (and (pred (not consp)) ,vpat)))) (defun radix-tree-iter-subtrees (tree fun) "Apply FUN to every immediate subtree of radix TREE. diff --git a/test/lisp/emacs-lisp/pcase-tests.el b/test/lisp/emacs-lisp/pcase-tests.el index 1b06c6e754..e6f4c09750 100644 --- a/test/lisp/emacs-lisp/pcase-tests.el +++ b/test/lisp/emacs-lisp/pcase-tests.el @@ -32,6 +32,10 @@ (should (equal (pcase '(2 . 3) ;bug#18554 (`(,hd . ,(and (pred atom) tl)) (list hd tl)) ((pred consp) nil)) + '(2 3))) + (should (equal (pcase '(2 . 3) + (`(,hd . ,(and (pred (not consp)) tl)) (list hd tl)) + ((pred consp) nil)) '(2 3)))) (pcase-defmacro pcase-tests-plus (pat n) commit df34ed8cbfdcf4584aa0ebfe827fac3a8d932bb6 Author: Philipp Stephani Date: Sun Jan 10 17:59:29 2021 +0100 Don't crash if no asynchronous process has been created yet. * src/process.c (wait_reading_process_output): Allow child_signal_read_fd < 0. diff --git a/src/process.c b/src/process.c index 474c87089e..aca87f8ed3 100644 --- a/src/process.c +++ b/src/process.c @@ -5413,9 +5413,9 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, an asynchronous process. Otherwise this might deadlock if we receive a SIGCHLD during `pselect'. */ int child_fd = child_signal_read_fd; - eassert (0 <= child_fd); eassert (child_fd < FD_SETSIZE); - FD_SET (child_fd, &Available); + if (0 <= child_fd) + FD_SET (child_fd, &Available); /* If frame size has changed or the window is newly mapped, redisplay now, before we start to wait. There is a race commit 8f0ce42d3eb9b212424a4a25a376287ffc94a73e Author: Philipp Stephani Date: Sun Jan 10 16:31:12 2021 +0100 Fix deadlock when receiving SIGCHLD during 'pselect'. If we receive and handle a SIGCHLD signal for a process while waiting for that process, 'pselect' might never return. Instead, we have to explicitly 'pselect' that the process status has changed. We do this by writing to a pipe in the SIGCHLD handler and having 'wait_reading_process_output' select on it. * src/process.c (child_signal_init): New helper function to create a pipe for SIGCHLD notifications. (child_signal_read, child_signal_notify): New helper functions to read from/write to the child signal pipe. (create_process): Initialize the child signal pipe on first use. (handle_child_signal): Notify waiters that a process status has changed. (wait_reading_process_output): Make sure that we also catch SIGCHLD/process status changes. * test/src/process-tests.el (process-tests/fd-setsize-no-crash/make-process): Remove workaround, which is no longer needed. diff --git a/src/process.c b/src/process.c index dac7d0440f..474c87089e 100644 --- a/src/process.c +++ b/src/process.c @@ -283,6 +283,16 @@ static int max_desc; the file descriptor of a socket that is already bound. */ static int external_sock_fd; +/* File descriptor that becomes readable when we receive SIGCHLD. */ +static int child_signal_read_fd = -1; +/* The write end thereof. The SIGCHLD handler writes to this file + descriptor to notify `wait_reading_process_output' of process + status changes. */ +static int child_signal_write_fd = -1; +static void child_signal_init (void); +static void child_signal_read (int, void *); +static void child_signal_notify (void); + /* Indexed by descriptor, gives the process (if any) for that descriptor. */ static Lisp_Object chan_process[FD_SETSIZE]; static void wait_for_socket_fds (Lisp_Object, char const *); @@ -2060,6 +2070,10 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) Lisp_Object lisp_pty_name = Qnil; sigset_t oldset; + /* Ensure that the SIGCHLD handler can notify + `wait_reading_process_output'. */ + child_signal_init (); + inchannel = outchannel = -1; if (p->pty_flag) @@ -5395,6 +5409,14 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, check_write = true; } + /* We have to be informed when we receive a SIGCHLD signal for + an asynchronous process. Otherwise this might deadlock if we + receive a SIGCHLD during `pselect'. */ + int child_fd = child_signal_read_fd; + eassert (0 <= child_fd); + eassert (child_fd < FD_SETSIZE); + FD_SET (child_fd, &Available); + /* If frame size has changed or the window is newly mapped, redisplay now, before we start to wait. There is a race condition here; if a SIGIO arrives between now and the select @@ -7114,7 +7136,70 @@ process has been transmitted to the serial port. */) subprocesses which the main thread should not reap. For example, if the main thread attempted to reap an already-reaped child, it might inadvertently reap a GTK-created process that happened to - have the same process ID. */ + have the same process ID. + + To avoid a deadlock when receiving SIGCHLD while + `wait_reading_process_output' is in `pselect', the SIGCHLD handler + will notify the `pselect' using a pipe. */ + +/* Set up `child_signal_read_fd' and `child_signal_write_fd'. */ + +static void +child_signal_init (void) +{ + /* Either both are initialized, or both are uninitialized. */ + eassert ((child_signal_read_fd < 0) == (child_signal_write_fd < 0)); + + if (0 <= child_signal_read_fd) + return; /* already done */ + + int fds[2]; + if (emacs_pipe (fds) < 0) + report_file_error ("Creating pipe for child signal", Qnil); + if (FD_SETSIZE <= fds[0]) + { + /* Since we need to `pselect' on the read end, it has to fit + into an `fd_set'. */ + emacs_close (fds[0]); + emacs_close (fds[1]); + report_file_errno ("Creating pipe for child signal", Qnil, + EMFILE); + } + + /* We leave the file descriptors open until the Emacs process + exits. */ + eassert (0 <= fds[0]); + eassert (0 <= fds[1]); + add_read_fd (fds[0], child_signal_read, NULL); + fd_callback_info[fds[0]].flags &= ~KEYBOARD_FD; + child_signal_read_fd = fds[0]; + child_signal_write_fd = fds[1]; +} + +/* Consume a process status change. */ + +static void +child_signal_read (int fd, void *data) +{ + eassert (0 <= fd); + eassert (fd == child_signal_read_fd); + char dummy; + if (emacs_read (fd, &dummy, 1) < 0) + emacs_perror ("reading from child signal FD"); +} + +/* Notify `wait_reading_process_output' of a process status + change. */ + +static void +child_signal_notify (void) +{ + int fd = child_signal_write_fd; + eassert (0 <= fd); + char dummy = 0; + if (emacs_write (fd, &dummy, 1) != 1) + emacs_perror ("writing to child signal FD"); +} /* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing its own SIGCHLD handling. On POSIXish systems, glib needs this to @@ -7152,6 +7237,7 @@ static void handle_child_signal (int sig) { Lisp_Object tail, proc; + bool changed = false; /* Find the process that signaled us, and record its status. */ @@ -7174,6 +7260,7 @@ handle_child_signal (int sig) eassert (ok); if (child_status_changed (deleted_pid, 0, 0)) { + changed = true; if (STRINGP (XCDR (head))) unlink (SSDATA (XCDR (head))); XSETCAR (tail, Qnil); @@ -7191,6 +7278,7 @@ handle_child_signal (int sig) && child_status_changed (p->pid, &status, WUNTRACED | WCONTINUED)) { /* Change the status of the process that was found. */ + changed = true; p->tick = ++process_tick; p->raw_status = status; p->raw_status_new = 1; @@ -7210,6 +7298,10 @@ handle_child_signal (int sig) } } + if (changed) + /* Wake up `wait_reading_process_output'. */ + child_signal_notify (); + lib_child_handler (sig); #ifdef NS_IMPL_GNUSTEP /* NSTask in GNUstep sets its child handler each time it is called. diff --git a/test/src/process-tests.el b/test/src/process-tests.el index 57097cfa05..dad36426a0 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -576,11 +576,6 @@ FD_SETSIZE file descriptors (Bug#24325)." (should (memq (process-status process) '(run exit))) (when (process-live-p process) (process-send-eof process)) - ;; FIXME: This `sleep-for' shouldn't be needed. It - ;; indicates a bug in Emacs; perhaps SIGCHLD is - ;; received in parallel with `accept-process-output', - ;; causing the latter to hang. - (sleep-for 0.1) (while (accept-process-output process)) (should (eq (process-status process) 'exit)) ;; If there's an error between fork and exec, Emacs commit 66756df286bea6efd3f9a8290e38e8d77bdf0264 Author: Eli Zaretskii Date: Sat Jan 16 20:18:32 2021 +0200 Fix Rmail summary for more than 99,999 messages * lisp/mail/rmailsum.el (rmail-summary-font-lock-keywords): Don't assume there will be less than 100,000 messages in an mbox file. (Bug#45912) diff --git a/lisp/mail/rmailsum.el b/lisp/mail/rmailsum.el index 60b67edf85..d29115a957 100644 --- a/lisp/mail/rmailsum.el +++ b/lisp/mail/rmailsum.el @@ -51,10 +51,10 @@ Setting this option to nil might speed up the generation of summaries." :group 'rmail-summary) (defvar rmail-summary-font-lock-keywords - '(("^.....D.*" . font-lock-string-face) ; Deleted. - ("^.....-.*" . font-lock-type-face) ; Unread. + '(("^ *[0-9]+D.*" . font-lock-string-face) ; Deleted. + ("^ *[0-9]+-.*" . font-lock-type-face) ; Unread. ;; Neither of the below will be highlighted if either of the above are: - ("^.....[^D-] \\(......\\)" 1 font-lock-keyword-face) ; Date. + ("^ *[0-9]+[^D-] \\(......\\)" 1 font-lock-keyword-face) ; Date. ("{ \\([^\n}]+\\) }" 1 font-lock-comment-face)) ; Labels. "Additional expressions to highlight in Rmail Summary mode.") commit 0057294b2ad6cdd2802e1b290a190fa42e723fb8 Author: Eli Zaretskii Date: Sat Jan 16 20:15:17 2021 +0200 Fix two tests * test/lisp/progmodes/elisp-mode-tests.el (xref-elisp-test-run): Make sure file names can be compared as strings, by running them through 'file-truename'. Reported by Vin Shelton . * test/lisp/emacs-lisp/bytecomp-tests.el ("warn-obsolete-hook.el") ("warn-obsolete-variable.el"): Use [^z-a] to match a newline as well. Reported by Vin Shelton . diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el index a07af188fa..263736af4e 100644 --- a/test/lisp/emacs-lisp/bytecomp-tests.el +++ b/test/lisp/emacs-lisp/bytecomp-tests.el @@ -617,13 +617,13 @@ Subtests signal errors if something goes wrong." (make-obsolete-variable 'bytecomp--tests-obsolete-var nil "99.99") (bytecomp--define-warning-file-test "warn-obsolete-hook.el" - "bytecomp--tests-obs.*obsolete.*99.99") + "bytecomp--tests-obs.*obsolete[^z-a]*99.99") (bytecomp--define-warning-file-test "warn-obsolete-variable-same-file.el" "foo-obs.*obsolete.*99.99" t) (bytecomp--define-warning-file-test "warn-obsolete-variable.el" - "bytecomp--tests-obs.*obsolete.*99.99") + "bytecomp--tests-obs.*obsolete[^z-a]*99.99") (bytecomp--define-warning-file-test "warn-obsolete-variable-bound.el" "bytecomp--tests-obs.*obsolete.*99.99" t) diff --git a/test/lisp/progmodes/elisp-mode-tests.el b/test/lisp/progmodes/elisp-mode-tests.el index a10d5dab90..fd43707f27 100644 --- a/test/lisp/progmodes/elisp-mode-tests.el +++ b/test/lisp/progmodes/elisp-mode-tests.el @@ -314,7 +314,19 @@ (let* ((xref (pop xrefs)) (expected (pop expected-xrefs)) (expected-xref (or (when (consp expected) (car expected)) expected)) - (expected-source (when (consp expected) (cdr expected)))) + (expected-source (when (consp expected) (cdr expected))) + (xref-file (xref-elisp-location-file (oref xref location))) + (expected-file (xref-elisp-location-file + (oref expected-xref location)))) + + ;; Make sure file names compare as strings. + (when (file-name-absolute-p xref-file) + (setf (xref-elisp-location-file (oref xref location)) + (file-truename (xref-elisp-location-file (oref xref location))))) + (when (file-name-absolute-p expected-file) + (setf (xref-elisp-location-file (oref expected-xref location)) + (file-truename (xref-elisp-location-file + (oref expected-xref location))))) ;; Downcase the filenames for case-insensitive file systems. (when xref--case-insensitive commit 57ae3f29af160d08a3a3568a7d969adecd25bcb7 Author: Ted Zlatanov Date: Sat Jan 16 15:45:05 2021 +0000 test/infra/gitlab-ci.yml: run only for tags and some branches diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml index d8934551b0..f9c0e0c11a 100644 --- a/test/infra/gitlab-ci.yml +++ b/test/infra/gitlab-ci.yml @@ -26,10 +26,19 @@ # Never run merge request pipelines, they usually duplicate push pipelines # see https://docs.gitlab.com/ee/ci/yaml/README.html#common-if-clauses-for-rules + +# Rules: always run tags and branches named master*, emacs*, feature*, fix* +# Test that it triggers by pushing a tag: `git tag mytag; git push origin mytag` +# Test that it triggers by pushing to: feature/emba, feature1, master, master-2, fix/emba, emacs-299, fix-2 +# Test that it doesn't trigger by pushing to: scratch-2, scratch/emba, oldbranch, dev workflow: rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' when: never + - if: '$CI_COMMIT_TAG' + when: always + - if: '$CI_COMMIT_BRANCH !~ /^(master|emacs|feature|fix)/' + when: never - when: always variables: commit 378ce65a0d26347cb6f25237650f2c8ba9b37bcf Author: Eli Zaretskii Date: Sat Jan 16 16:54:01 2021 +0200 Improve support for Cham script * lisp/language/cham.el ("Cham"): Expand the entry. * etc/HELLO: Add entry for Cham. diff --git a/etc/HELLO b/etc/HELLO index dec3a775af..9a1f5d30ed 100644 --- a/etc/HELLO +++ b/etc/HELLO @@ -30,6 +30,8 @@ Bengali (বাংলা) নমস্কার Braille ⠓⠑⠇⠇⠕ Burmese (မြန်မာ) မင်္ဂလာပါ C printf ("Hello, world!\n"); +Cham (ꨌꩌ) ꨦꨤꩌ ꨦꨰꨁ + Cherokee (ᏣᎳᎩ ᎦᏬᏂᎯᏍᏗ) ᎣᏏᏲ / ᏏᏲ Comanche /kəˈmæntʃiː/ Haa marʉ́awe diff --git a/lisp/language/cham.el b/lisp/language/cham.el index eef6d6f8f9..194574f6a8 100644 --- a/lisp/language/cham.el +++ b/lisp/language/cham.el @@ -34,6 +34,11 @@ (set-language-info-alist "Cham" '((charset unicode) (coding-system utf-8) - (coding-priority utf-8))) + (coding-priority utf-8) + (sample-text . "Cham (ꨌꩌ)\tꨦꨤꩌ ꨦꨰꨁ") + (documentation . "\ +The Cham script is a Brahmic script used to write Cham, +an Austronesian language spoken by some 245,000 Chams +in Vietnam and Cambodia."))) (provide 'cham) commit b58fd1eab9e7a07711b63f5ce67d518972efaba9 Author: Eli Zaretskii Date: Sat Jan 16 16:32:00 2021 +0200 ; * lisp/language/cham.el: Fix copy-paste mistake in comment. diff --git a/lisp/language/cham.el b/lisp/language/cham.el index 4749f2e8db..be1a6b4f4c 100644 --- a/lisp/language/cham.el +++ b/lisp/language/cham.el @@ -23,7 +23,7 @@ ;;; Commentary: -;; Tai Viet is being included in the Unicode at the range U+AA80..U+AADF. +;; Cham script is included in the Unicode at the range U+AA00..U+AA5F. ;;; Code: commit 84e0749b8b180bb94a5c32ebda11b5f22942dc22 Author: Ted Zlatanov Date: Sat Jan 16 13:03:58 2021 +0000 EMBA container build improvements for Emacs build testing. * test/infra/gitlab-ci.yml: Moved from .gitlab-ci.yml. Use the EMBA container registry with a different login token storage file for each commit. Split test stages into prep, build, fast tests, normal tests, platform tests, and slow (everything) and use templates where possible. * .gitlab-ci.yml: Include test/infra/gitlab-ci.yml and move all content there. diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index eb884767c9..3138f4184e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright (C) 2017-2021 Free Software Foundation, Inc. +# Copyright (C) 2021 Free Software Foundation, Inc. # # This file is part of GNU Emacs. # @@ -24,141 +24,5 @@ # Maintainer: Ted Zlatanov # URL: https://emba.gnu.org/emacs/emacs -# Never run merge request pipelines, they usually duplicate push pipelines -# see https://docs.gitlab.com/ee/ci/yaml/README.html#common-if-clauses-for-rules -workflow: - rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - when: never - - when: always - -variables: - GIT_STRATEGY: fetch - EMACS_EMBA_CI: 1 - -default: - image: docker:19.03.12 - timeout: 3 hours - before_script: - - docker info - -.job-template: - # these will be cached across builds - cache: - key: ${CI_COMMIT_REF_SLUG} - paths: [] - policy: pull-push - # these will be saved for followup builds - artifacts: - expire_in: 24 hrs - paths: [] - # - "test/**/*.log" - # - "**/*.log" - -.test-template: - rules: - - changes: - - "**/Makefile.in" - - .gitlab-ci.yml - - aclocal.m4 - - autogen.sh - - configure.ac - - lib/*.{h,c} - - lisp/**/*.el - - src/*.{h,c} - - test/infra/* - - test/lisp/**/*.el - - test/src/*.el - - changes: - # gfilemonitor, kqueue - - src/gfilenotify.c - - src/kqueue.c - # MS Windows - - "**/w32*" - # GNUstep - - lisp/term/ns-win.el - - src/ns*.{h,m} - - src/macfont.{h,m} - when: never - - # using the variables for each job - script: - - docker build --target ${target} -t ${target}:${CI_COMMIT_REF_SLUG} -t ${target}:${CI_COMMIT_SHA} -f test/infra/Dockerfile.emba . - # TODO: with make -j4 several of the tests were failing, for example shadowfile-tests, but passed without it - - docker run -i --rm -e EMACS_EMBA_CI=${EMACS_EMBA_CI} ${target}:${CI_COMMIT_SHA} make ${make_params} - -stages: - - fast - - normal - - slow - -test-fast: - stage: fast - extends: [.job-template, .test-template] - variables: - target: emacs-inotify - make_params: "-C test check" - -test-lisp: - stage: normal - extends: [.job-template, .test-template] - variables: - target: emacs-inotify - make_params: "-C test check-lisp" - -test-net: - stage: normal - extends: [.job-template, .test-template] - variables: - target: emacs-inotify - make_params: "-C test check-net" - -test-filenotify-gio: - # This tests file monitor libraries gfilemonitor and gio. - stage: normal - extends: [.job-template, .test-template] - rules: - - if: '$CI_PIPELINE_SOURCE == "schedule"' - changes: - - "**/Makefile.in" - - .gitlab-ci.yml - - lisp/autorevert.el - - lisp/filenotify.el - - lisp/net/tramp-sh.el - - src/gfilenotify.c - - test/infra/* - - test/lisp/autorevert-tests.el - - test/lisp/filenotify-tests.el - variables: - target: emacs-filenotify-gio - make_params: "-k -C test autorevert-tests filenotify-tests" - -test-gnustep: - # This tests the GNUstep build process - stage: normal - extends: [.job-template, .test-template] - rules: - - if: '$CI_PIPELINE_SOURCE == "schedule"' - changes: - - "**/Makefile.in" - - .gitlab-ci.yml - - configure.ac - - src/ns*.{h,m} - - src/macfont.{h,m} - - lisp/term/ns-win.el - - nextstep/**/* - - test/infra/* - variables: - target: emacs-gnustep - make_params: install - -test-all: - # This tests also file monitor libraries inotify and inotifywatch. - stage: slow - extends: [.job-template, .test-template] - rules: - # note there's no "changes" section, so this always runs on a schedule - - if: '$CI_PIPELINE_SOURCE == "schedule"' - variables: - target: emacs-inotify - make_params: check-expensive +# Just load from test/infra, to keep build automation files there. +include: '/test/infra/gitlab-ci.yml' diff --git a/test/infra/Dockerfile.emba b/test/infra/Dockerfile.emba index dd41982ad5..421264db9c 100644 --- a/test/infra/Dockerfile.emba +++ b/test/infra/Dockerfile.emba @@ -41,7 +41,7 @@ COPY . /checkout WORKDIR /checkout RUN ./autogen.sh autoconf RUN ./configure --without-makeinfo -RUN make bootstrap +RUN make -j4 bootstrap RUN make -j4 FROM emacs-base as emacs-filenotify-gio diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml new file mode 100644 index 0000000000..d8934551b0 --- /dev/null +++ b/test/infra/gitlab-ci.yml @@ -0,0 +1,208 @@ +# Copyright (C) 2017-2021 Free Software Foundation, Inc. +# +# This file is part of GNU Emacs. +# +# GNU Emacs is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GNU Emacs is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Emacs. If not, see . + +# GNU Emacs support for the GitLab protocol for CI + +# The presence of this file does not imply any FSF/GNU endorsement of +# any particular service that uses that protocol. Also, it is intended for +# evaluation purposes, thus possibly temporary. + +# Maintainer: Ted Zlatanov +# URL: https://emba.gnu.org/emacs/emacs + +# Never run merge request pipelines, they usually duplicate push pipelines +# see https://docs.gitlab.com/ee/ci/yaml/README.html#common-if-clauses-for-rules +workflow: + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' + when: never + - when: always + +variables: + GIT_STRATEGY: fetch + EMACS_EMBA_CI: 1 + # # Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled + # DOCKER_HOST: tcp://docker:2376 + # DOCKER_TLS_CERTDIR: "/certs" + # Put the configuration for each run in a separate directory to avoid conflicts + DOCKER_CONFIG: "/.docker-config-${CI_COMMIT_SHA}" + +default: + image: docker:19.03.12 + timeout: 3 hours + before_script: + - docker info + - echo "docker registry is ${CI_REGISTRY}" + - docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY} + +.job-template: + # these will be cached across builds + cache: + key: ${CI_COMMIT_SHA} + paths: [] + policy: pull-push + # these will be saved for followup builds + artifacts: + expire_in: 24 hrs + paths: [] + # - "test/**/*.log" + # - "**/*.log" + +.build-template: + script: + - docker build --pull --target ${target} -t ${CI_REGISTRY_IMAGE}:${target}-${CI_COMMIT_SHA} -f test/infra/Dockerfile.emba . + - docker push ${CI_REGISTRY_IMAGE}:${target}-${CI_COMMIT_SHA} + +.gnustep-template: + rules: + - if: '$CI_PIPELINE_SOURCE == "schedule"' + changes: + - "**/Makefile.in" + - .gitlab-ci.yml + - configure.ac + - src/ns*.{h,m} + - src/macfont.{h,m} + - lisp/term/ns-win.el + - nextstep/**/* + - test/infra/* + +.filenotify-gio-template: + rules: + - if: '$CI_PIPELINE_SOURCE == "schedule"' + changes: + - "**/Makefile.in" + - .gitlab-ci.yml + - lisp/autorevert.el + - lisp/filenotify.el + - lisp/net/tramp-sh.el + - src/gfilenotify.c + - test/infra/* + - test/lisp/autorevert-tests.el + - test/lisp/filenotify-tests.el + +.test-template: + rules: + - changes: + - "**/Makefile.in" + - .gitlab-ci.yml + - aclocal.m4 + - autogen.sh + - configure.ac + - lib/*.{h,c} + - lisp/**/*.el + - src/*.{h,c} + - test/infra/* + - test/lisp/**/*.el + - test/src/*.el + - changes: + # gfilemonitor, kqueue + - src/gfilenotify.c + - src/kqueue.c + # MS Windows + - "**/w32*" + # GNUstep + - lisp/term/ns-win.el + - src/ns*.{h,m} + - src/macfont.{h,m} + when: never + + # using the variables for each job + script: + - docker pull ${CI_REGISTRY_IMAGE}:${target}-${CI_COMMIT_SHA} + # TODO: with make -j4 several of the tests were failing, for example shadowfile-tests, but passed without it + - docker run -i --rm -e EMACS_EMBA_CI=${EMACS_EMBA_CI} ${CI_REGISTRY_IMAGE}:${target}-${CI_COMMIT_SHA} make ${make_params} + +stages: + - prep-images + - build-images + - fast + - normal + - platform-images + - platforms + - slow + +prep-image-base: + stage: prep-images + extends: [.job-template, .build-template] + variables: + target: emacs-base + +build-image-inotify: + stage: build-images + extends: [.job-template, .build-template] + variables: + target: emacs-inotify + +test-fast-inotify: + stage: fast + extends: [.job-template, .test-template] + variables: + target: emacs-inotify + make_params: "-C test check" + +build-image-filenotify-gio: + stage: platform-images + extends: [.job-template, .build-template, .filenotify-gio-template] + variables: + target: emacs-filenotify-gio + +build-image-gnustep: + stage: platform-images + extends: [.job-template, .build-template, .gnustep-template] + variables: + target: emacs-gnustep + +test-lisp-inotify: + stage: normal + extends: [.job-template, .test-template] + variables: + target: emacs-inotify + make_params: "-C test check-lisp" + +test-net-inotify: + stage: normal + extends: [.job-template, .test-template] + variables: + target: emacs-inotify + make_params: "-C test check-net" + +test-filenotify-gio: + # This tests file monitor libraries gfilemonitor and gio. + stage: platforms + extends: [.job-template, .test-template, .filenotify-gio-template] + variables: + target: emacs-filenotify-gio + make_params: "-k -C test autorevert-tests filenotify-tests" + +test-gnustep: + # This tests the GNUstep build process + stage: platforms + extends: [.job-template, .test-template, .gnustep-template] + variables: + target: emacs-gnustep + make_params: install + +test-all-inotify: + # This tests also file monitor libraries inotify and inotifywatch. + stage: slow + extends: [.job-template, .test-template] + rules: + # note there's no "changes" section, so this always runs on a schedule + - if: '$CI_PIPELINE_SOURCE == "schedule"' + variables: + target: emacs-inotify + make_params: check-expensive commit c55b7b8e1f46612849a25f035578a46fa3fe343b Author: Eli Zaretskii Date: Sat Jan 16 15:02:48 2021 +0200 Fix last change * src/frame.c (Fset_mouse_position, Fset_mouse_pixel_position): Don't compile the FRAME_MSDOS_P case on platforms other than MSDOS, as that will never happen there. diff --git a/src/frame.c b/src/frame.c index 4d3d05ebbd..599c4075f8 100644 --- a/src/frame.c +++ b/src/frame.c @@ -2579,13 +2579,13 @@ before calling this function on it, like this. frame_set_mouse_position (XFRAME (frame), xval, yval); #endif /* HAVE_WINDOW_SYSTEM */ } +#ifdef MSDOS else if (FRAME_MSDOS_P (XFRAME (frame))) { Fselect_frame (frame, Qnil); -#ifdef MSDOS mouse_moveto (xval, yval); -#endif /* MSDOS */ } +#endif /* MSDOS */ else { Fselect_frame (frame, Qnil); @@ -2624,13 +2624,13 @@ before calling this function on it, like this. frame_set_mouse_pixel_position (XFRAME (frame), xval, yval); #endif /* HAVE_WINDOW_SYSTEM */ } +#ifdef MSDOS else if (FRAME_MSDOS_P (XFRAME (frame))) { Fselect_frame (frame, Qnil); -#ifdef MSDOS mouse_moveto (xval, yval); -#endif /* MSDOS */ } +#endif /* MSDOS */ else { Fselect_frame (frame, Qnil); commit ba29d13f41b777969a324894ba82646d36e1ff5c Author: Jared Finder Date: Wed Dec 2 00:05:59 2020 -0800 Make mouse-related calls be more consistent on all frame types * src/frame.c (Fset_mouse_position, Fset_mouse_pixel_position): Call Fselect_frame and appropriate mouse_moveto function on all non-GUI frame types, independent of #ifdef's. * src/term.c (init_tty): Initialize mouse_face_window for all non-GUI frame types. (term_mouse_moveto) [HAVE_GPM]: Make available even if HAVE_WINDOW_SYSTEM is defined. * src/xdisp.c (try_window_id): Call gui_clear_window_mouse_face in all cases. diff --git a/src/frame.c b/src/frame.c index 45ee96e962..4d3d05ebbd 100644 --- a/src/frame.c +++ b/src/frame.c @@ -2572,23 +2572,30 @@ before calling this function on it, like this. int yval = check_integer_range (y, INT_MIN, INT_MAX); /* I think this should be done with a hook. */ -#ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (XFRAME (frame))) - /* Warping the mouse will cause enternotify and focus events. */ - frame_set_mouse_position (XFRAME (frame), xval, yval); -#elif defined MSDOS - if (FRAME_MSDOS_P (XFRAME (frame))) + { +#ifdef HAVE_WINDOW_SYSTEM + /* Warping the mouse will cause enternotify and focus events. */ + frame_set_mouse_position (XFRAME (frame), xval, yval); +#endif /* HAVE_WINDOW_SYSTEM */ + } + else if (FRAME_MSDOS_P (XFRAME (frame))) { Fselect_frame (frame, Qnil); +#ifdef MSDOS mouse_moveto (xval, yval); +#endif /* MSDOS */ } -#elif defined HAVE_GPM - Fselect_frame (frame, Qnil); - term_mouse_moveto (xval, yval); + else + { + Fselect_frame (frame, Qnil); +#ifdef HAVE_GPM + term_mouse_moveto (xval, yval); #else - (void) xval; - (void) yval; -#endif + (void) xval; + (void) yval; +#endif /* HAVE_GPM */ + } return Qnil; } @@ -2610,23 +2617,31 @@ before calling this function on it, like this. int yval = check_integer_range (y, INT_MIN, INT_MAX); /* I think this should be done with a hook. */ -#ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (XFRAME (frame))) - /* Warping the mouse will cause enternotify and focus events. */ - frame_set_mouse_pixel_position (XFRAME (frame), xval, yval); -#elif defined MSDOS - if (FRAME_MSDOS_P (XFRAME (frame))) + { + /* Warping the mouse will cause enternotify and focus events. */ +#ifdef HAVE_WINDOW_SYSTEM + frame_set_mouse_pixel_position (XFRAME (frame), xval, yval); +#endif /* HAVE_WINDOW_SYSTEM */ + } + else if (FRAME_MSDOS_P (XFRAME (frame))) { Fselect_frame (frame, Qnil); +#ifdef MSDOS mouse_moveto (xval, yval); +#endif /* MSDOS */ } -#elif defined HAVE_GPM - Fselect_frame (frame, Qnil); - term_mouse_moveto (xval, yval); + else + { + Fselect_frame (frame, Qnil); +#ifdef HAVE_GPM + term_mouse_moveto (xval, yval); #else - (void) xval; - (void) yval; -#endif + (void) xval; + (void) yval; +#endif /* HAVE_GPM */ + + } return Qnil; } diff --git a/src/term.c b/src/term.c index a87f9c745c..2e2ab2bf43 100644 --- a/src/term.c +++ b/src/term.c @@ -2382,7 +2382,6 @@ frame's terminal). */) #ifdef HAVE_GPM -#ifndef HAVE_WINDOW_SYSTEM void term_mouse_moveto (int x, int y) { @@ -2396,7 +2395,6 @@ term_mouse_moveto (int x, int y) last_mouse_x = x; last_mouse_y = y; */ } -#endif /* HAVE_WINDOW_SYSTEM */ /* Implementation of draw_row_with_mouse_face for TTY/GPM. */ void @@ -4246,8 +4244,8 @@ use the Bourne shell command 'TERM=...; export TERM' (C-shell:\n\ #ifdef HAVE_GPM terminal->mouse_position_hook = term_mouse_position; - tty->mouse_highlight.mouse_face_window = Qnil; #endif + tty->mouse_highlight.mouse_face_window = Qnil; terminal->kboard = allocate_kboard (Qnil); terminal->kboard->reference_count++; diff --git a/src/termhooks.h b/src/termhooks.h index 85a47c071b..3800679e80 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -366,9 +366,7 @@ enum { #ifdef HAVE_GPM #include extern int handle_one_term_event (struct tty_display_info *, Gpm_Event *); -#ifndef HAVE_WINDOW_SYSTEM extern void term_mouse_moveto (int, int); -#endif /* The device for which we have enabled gpm support. */ extern struct tty_display_info *gpm_tty; diff --git a/src/xdisp.c b/src/xdisp.c index ea67329cff..32e9773b54 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -20822,9 +20822,8 @@ try_window_id (struct window *w) + window_wants_header_line (w) + window_internal_height (w)); -#if defined (HAVE_GPM) || defined (MSDOS) gui_clear_window_mouse_face (w); -#endif + /* Perform the operation on the screen. */ if (dvpos > 0) { commit 0732fc31932c75c682c8b65b4dcb4376ca63e8fd Author: Stefan Monnier Date: Fri Jan 15 23:18:08 2021 -0500 * lisp/frame.el Don't activate `blink-cursor-idle-timer` needlessly. (blink-cursor-mode): Use `blink-cursor-check` rather than `blink-cursor--start-idle-timer` so we check for the presence of a frame where the cursor can be blinked before activating the idle timer. diff --git a/lisp/frame.el b/lisp/frame.el index c71276287a..e2d7f21a49 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -2557,7 +2557,7 @@ command starts, by installing a pre-command hook." ;; blink-cursor-end is not added to pre-command-hook. (setq blink-cursor-blinks-done 1) (blink-cursor--start-timer) - (add-hook 'pre-command-hook 'blink-cursor-end) + (add-hook 'pre-command-hook #'blink-cursor-end) (internal-show-cursor nil nil))) (defun blink-cursor-timer-function () @@ -2572,14 +2572,14 @@ command starts, by installing a pre-command hook." (when (and (> blink-cursor-blinks 0) (<= (* 2 blink-cursor-blinks) blink-cursor-blinks-done)) (blink-cursor-suspend) - (add-hook 'post-command-hook 'blink-cursor-check))) + (add-hook 'post-command-hook #'blink-cursor-check))) (defun blink-cursor-end () "Stop cursor blinking. This is installed as a pre-command hook by `blink-cursor-start'. When run, it cancels the timer `blink-cursor-timer' and removes itself as a pre-command hook." - (remove-hook 'pre-command-hook 'blink-cursor-end) + (remove-hook 'pre-command-hook #'blink-cursor-end) (internal-show-cursor nil t) (when blink-cursor-timer (cancel-timer blink-cursor-timer) @@ -2648,7 +2648,7 @@ terminals, cursor blinking is controlled by the terminal." (when blink-cursor-mode (add-function :after after-focus-change-function #'blink-cursor--rescan-frames) (add-hook 'after-delete-frame-functions #'blink-cursor--rescan-frames) - (blink-cursor--start-idle-timer))) + (blink-cursor-check))) ;; Frame maximization/fullscreen commit 1513ee37a4defbf1db7f26d1e8148843416dc987 Author: Kévin Le Gouguec Date: Sun Jan 10 10:43:41 2021 +0100 Change default-directory before prompting in project-compile This causes command completion to work from the project root, letting users complete top-level folders, make targets, etc (bug#45765). * lisp/progmodes/project.el (project-compile): Simplify using call-interactively, as done with project(-async)-shell-command. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 62c3cf44cb..06966f33b7 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -970,20 +970,11 @@ loop using the command \\[fileloop-continue]." (declare-function compilation-read-command "compile") ;;;###autoload -(defun project-compile (command &optional comint) - "Run `compile' in the project root. -Arguments the same as in `compile'." - (interactive - (list - (let ((command (eval compile-command))) - (require 'compile) - (if (or compilation-read-command current-prefix-arg) - (compilation-read-command command) - command)) - (consp current-prefix-arg))) - (let* ((pr (project-current t)) - (default-directory (project-root pr))) - (compile command comint))) +(defun project-compile () + "Run `compile' in the project root." + (interactive) + (let ((default-directory (project-root (project-current t)))) + (call-interactively #'compile))) (defun project--read-project-buffer () (let* ((pr (project-current t)) commit 5d6817086d6485bc6e3dde054d877c0759656ddd Author: Stefan Monnier Date: Fri Jan 15 22:38:52 2021 -0500 * src/dispnew.c (sit_for): Return nil when interrupted by process output Before adbb4eacc2a984c0fc0b65ec761368fd9067d6c5, `read_and_dispose_of_process_output` called `record_asynch_buffer_change` which added "artificial" input events (in the form of BUFFER_SWITCH_EVENTs), causing sit_for to return Qnil when interrupted by process output. Without those BUFFER_SWITCH_EVENTs, sit_for now tends to return Qt when interrupted by process output making `read_char` believe that we've waited the whole timeout, As consequence incoming process output tended to cause premature auto-saving of files (sometimes right after almost every key press). This patch recovers the previous behavior, which is not ideal (incoming process output can delay auto-save indefinitely), but has been good enough for many years. diff --git a/src/dispnew.c b/src/dispnew.c index 36a6dd8a09..e603c67136 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -6049,7 +6049,14 @@ additional wait period, in milliseconds; this is for backwards compatibility. READING is true if reading input. If DISPLAY_OPTION is >0 display process output while waiting. If DISPLAY_OPTION is >1 perform an initial redisplay before waiting. -*/ + + Returns a boolean Qt if we waited the full time and returns Qnil if the + wait was interrupted by incoming process output or keyboard events. + + FIXME: When `wait_reading_process_output` returns early because of + process output, instead of returning nil we should loop and wait some + more (i.e. until either there's pending input events or the timeout + expired). */ Lisp_Object sit_for (Lisp_Object timeout, bool reading, int display_option) @@ -6110,8 +6117,9 @@ sit_for (Lisp_Object timeout, bool reading, int display_option) gobble_input (); #endif - wait_reading_process_output (sec, nsec, reading ? -1 : 1, do_display, - Qnil, NULL, 0); + int nbytes + = wait_reading_process_output (sec, nsec, reading ? -1 : 1, do_display, + Qnil, NULL, 0); if (reading && curbuf_eq_winbuf) /* Timers and process filters/sentinels may have changed the selected @@ -6120,7 +6128,7 @@ sit_for (Lisp_Object timeout, bool reading, int display_option) buffer to start with). */ set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents)); - return detect_input_pending () ? Qnil : Qt; + return (nbytes > 0 || detect_input_pending ()) ? Qnil : Qt; } commit f45be48ddbde00610e1e08fca6590dcf24a4e1b5 Author: Basil L. Contovounesios Date: Fri Jan 15 21:30:14 2021 +0000 ; Remove recent spurious addition in window.el * lisp/window.el (display-buffer-use-some-window): Remove spurious message included in 2021-01-11 "Support using auth-source for NickServ passwords in ERC" (bug#45340#44). diff --git a/lisp/window.el b/lisp/window.el index 719bafccb4..0a37d16273 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -8316,7 +8316,6 @@ indirectly called by the latter." (when (and (listp quad) (integerp (nth 3 quad)) (> (nth 3 quad) (window-total-height window))) - (message "foo") (condition-case nil (window-resize window (- (nth 3 quad) (window-total-height window))) (error nil))) commit 667f2e097cdfdb057de0696867c83ebfd1a3e816 Author: Phillip Lord Date: Thu Jan 14 22:51:13 2021 +0000 Remove support for 32 bit build * admin/nt/dist-build/README-scripts: Update * admin/nt/dist-build/README-windows-binaries: Update * admin/nt/dist-build/build-zips.sh: Remove 32 bit and fix paths * admin/nt/dist-build/build-dep-zips.py: Remove 32 bit and update paths * admin/nt/dist-build/emacs.nsi: Remove 32 bit and fix paths diff --git a/admin/nt/dist-build/README-scripts b/admin/nt/dist-build/README-scripts index 4c3554e8df..f27bcd3bd6 100644 --- a/admin/nt/dist-build/README-scripts +++ b/admin/nt/dist-build/README-scripts @@ -33,26 +33,21 @@ build-zips.sh file will create this for you. A location for the dependencies. This needs to contain two zip files with the dependencies. build-dep-zips.py will create these files for you. -~/emacs-build/deps/libXpm/i686 -~/emacs-build/deps/libXpm/x86_64 +~/emacs-build/deps/libXpm Contain libXpm-noX4.dll. This file is used to load images for the splash screen, menu items and so on. Emacs runs without it, but looks -horrible. The x86_64 comes from msys2, while the i686 comes from -ezwinports because it itself has no dependencies. These have to be -placed manually (but probably never need updating). +horrible. The files came original from msys2, and contains no +dependencies. It has to be placed manually (but probably never +need updating). - -~/emacs-build/build/$version/i686 -~/emacs-build/build/$version/x86_64 +~/emacs-build/build/$version We build Emacs out-of-source here. This directory is created by build-zips.sh. This directory can be freely deleted after zips have been created - -~/emacs-build/install/$version/i686 -~/emacs-build/install/$version/x86_64 +~/emacs-build/install/$version We install Emacs here. This directory is created by build-zips.sh. This directory can and *should* be deleted after zips have been @@ -79,9 +74,9 @@ To do this: Update msys to the latest version with `pacman -Syu`. -Then run build-dep-zips.py, in the ~/emacs-build/deps directory. Three -zips will be created, containing the 64bit and 32bit dependencies, as -well as the source for these. +Then run build-dep-zips.py, in the ~/emacs-build/deps directory. Two +zips will be created, containing the dependencies, as well as the +source for these. For emacs release or pre-test version: @@ -105,12 +100,12 @@ To do this: Update msys to the latest version with `pacman -Syu`. -Then run build-dep-zips.py, in ~/emacs-build/deps directory. Three -zips will be created, containing the 64bit and 32bit dependencies, as -well as the source for these. These deps files contain the date of -creation in their name. The deps file can be reused as desired, or a -new version created. Where multiple deps files exist, the most -recent will be used. +Then run build-dep-zips.py, in ~/emacs-build/deps directory. Two zips +will be created, containing the dependencies, as well as the source +for these. These deps files contain the date of creation in their +name. The deps file can be reused as desired, or a new version +created. Where multiple deps files exist, the most recent will be +used. Now, run `build-zips.sh -s` to build a snapshot release. @@ -134,4 +129,5 @@ For snapshots from another branch Snapshots can be build from any other branch. There is rarely a need to do this, except where some significant, wide-ranging feature is being added on a feature branch. In this case, the branch can be -given using `build-zips.sh -b pdumper -s` for example. +given using `build-zips.sh -b pdumper -s` for example. Any "/" +characters in the branch title are replaced. diff --git a/admin/nt/dist-build/README-windows-binaries b/admin/nt/dist-build/README-windows-binaries index 001bdd73f7..b6f6e55d8c 100644 --- a/admin/nt/dist-build/README-windows-binaries +++ b/admin/nt/dist-build/README-windows-binaries @@ -4,7 +4,7 @@ See the end of the file for license conditions. Precompiled Distributions of Emacs for Windows - Jan 1, 2020 + Jan 14, 2021 This directory contains precompiled distributions for GNU Emacs on Windows @@ -25,51 +25,33 @@ old binaries. Windows Binaries ================ -Currently, we provide six different binary packages for Emacs, which +Currently, we provide three different binary packages for Emacs, which are: -emacs-$VERSION-x86_64-installer.exe +emacs-$VERSION-installer.exe -Contains a 64-bit build of Emacs with dependencies as an installer +Contains Emacs with dependencies as an installer package. Mostly, this is the best one to install. -emacs-$VERSION-x86_64.zip +emacs-$VERSION.zip -Contains a 64-bit build of Emacs with dependencies. This contains the -same files as the installer but as a zip file which some users may -prefer. +Contains Emacs with dependencies. This contains the same files as the +installer but as a zip file which some users may prefer. -emacs-$VERSION-x86_64-no-deps.zip +emacs-$VERSION-no-deps.zip -Contains a 64-bit build of Emacs without any dependencies. This may be -useful if you wish to install where the dependencies are already -available, or if you want the small possible Emacs. - -emacs-$VERSION-i686-installer.exe - -Contains a 32-bit build of Emacs with dependencies as an installer -package. This is useful for running on a 32-bit machine. - -emacs-$VERSION-i686.zip - -Contains a 32-bit build of Emacs with dependencies. - -emacs-$VERSION-i686-no-deps.zip - -Contains a 32-bit build of Emacs without dependencies +Contains Emacs without any dependencies. This may be useful if you +wish to install where the dependencies are already available, or if +you want the small possible Emacs. In addition, we provide the following files which will not be useful for most end-users. -emacs-$VERSION-x86_64-deps.zip +emacs-$VERSION-deps.zip The dependencies. Unzipping this file on top of -emacs-$VERSION-x86_64-no-deps.zip should result in the same install as -emacs-$VERSION-x86_64.zip. - -emacs-$VERSION-i686-deps.zip - -The 32-bit version of the dependencies. +emacs-$VERSION-no-deps.zip should result in the same install as +emacs-$VERSION.zip. emacs-$VERSION-deps-mingw-w64-src.zip @@ -85,7 +67,8 @@ Snapshots We also distribute "snapshots" of Emacs built at points throughout the development cycle, for those interested in following this cycle. They -are not recommended for normal users. +are not recommended for normal users; however, they are useful for +people who want to report bugs against the current master. The files follow the same naming convention, but also include a date (and sometimes information about their branch). The Emacs source at diff --git a/admin/nt/dist-build/build-dep-zips.py b/admin/nt/dist-build/build-dep-zips.py index ec99bd606d..19168e7ff2 100755 --- a/admin/nt/dist-build/build-dep-zips.py +++ b/admin/nt/dist-build/build-dep-zips.py @@ -17,7 +17,6 @@ ## You should have received a copy of the GNU General Public License ## along with GNU Emacs. If not, see . import argparse -import multiprocessing as mp import os import shutil import re @@ -64,31 +63,30 @@ def check_output_maybe(*args,**kwargs): return check_output(*args,**kwargs) ## DLL Capture -def gather_deps(arch, directory): - os.mkdir(arch) - os.chdir(arch) +def gather_deps(): - for dep in full_dll_dependency(directory): - check_output_maybe(["cp /{}/bin/{}*.dll .".format(directory, dep)], + os.mkdir("x86_64") + os.chdir("x86_64") + + for dep in full_dll_dependency(): + check_output_maybe(["cp /mingw64/bin/{}*.dll .".format(dep)], shell=True) - ## And package them up - ## os.chdir(arch) - print("Zipping: {}".format(arch)) - check_output_maybe("zip -9r ../emacs-{}-{}{}-deps.zip *" - .format(EMACS_MAJOR_VERSION, DATE, arch), + print("Zipping") + check_output_maybe("zip -9r ../emacs-{}-{}deps.zip *" + .format(EMACS_MAJOR_VERSION, DATE), shell=True) os.chdir("../") ## Return all Emacs dependencies -def full_dll_dependency(directory): - deps = [dll_dependency(dep, directory) for dep in DLL_REQ] +def full_dll_dependency(): + deps = [dll_dependency(dep) for dep in DLL_REQ] return set(sum(deps, []) + DLL_REQ) ## Dependencies for a given DLL -def dll_dependency(dll, directory): +def dll_dependency(dll): output = check_output(["/mingw64/bin/ntldd", "--recursive", - "/{}/bin/{}*.dll".format(directory, dll)]).decode("utf-8") + "/mingw64/bin/{}*.dll".format(dll)]).decode("utf-8") ## munge output return ntldd_munge(output) @@ -114,14 +112,11 @@ def ntldd_munge(out): ## Packages to fiddle with ## Source for gcc-libs is part of gcc SKIP_SRC_PKGS=["mingw-w64-gcc-libs"] -SKIP_DEP_PKGS=["mingw-w64-x86_64-glib2"] +SKIP_DEP_PKGS=["mingw-w64-glib2"] MUNGE_SRC_PKGS={"mingw-w64-libwinpthread-git":"mingw-w64-winpthreads-git"} MUNGE_DEP_PKGS={ - "mingw-w64-i686-libwinpthread":"mingw-w64-i686-libwinpthread-git", "mingw-w64-x86_64-libwinpthread":"mingw-w64-x86_64-libwinpthread-git", - "mingw-w64-x86_64-libtre": "mingw-w64-x86_64-libtre-git", - "mingw-w64-i686-libtre": "mingw-w64-i686-libtre-git" } ## Currently no packages seem to require this! @@ -155,13 +150,11 @@ def extract_deps(): # Get a list of all dependencies needed for packages mentioned above. pkgs = PKG_REQ[:] - print("Initial pkgs", pkgs) n = 0 while n < len(pkgs): subdeps = immediate_deps(pkgs[n]) for p in subdeps: if not (p in pkgs or p in SKIP_DEP_PKGS): - print("adding", p) pkgs.append(p) n = n + 1 @@ -171,33 +164,29 @@ def extract_deps(): def download_source(tarball): print("Acquiring {}...".format(tarball)) - if os.path.exists("../emacs-src-cache/{}".format(tarball)): - print("Copying {} from local".format(tarball)) - shutil.copyfile("../emacs-src-cache/{}".format(tarball), - "{}".format(tarball)) - else: + if not os.path.exists("../emacs-src-cache/{}".format(tarball)): print("Downloading {}...".format(tarball)) check_output_maybe( - "wget -a ../download.log -O {} {}/{}/download" + "wget -a ../download.log -O ../emacs-src-cache/{} {}/{}/download" .format(tarball, SRC_REPO, tarball), shell=True ) print("Downloading {}... done".format(tarball)) + print("Copying {} from local".format(tarball)) + shutil.copyfile("../emacs-src-cache/{}".format(tarball), + "{}".format(tarball)) + + ## Fetch all the source code def gather_source(deps): + if not os.path.exists("emacs-src-cache"): + os.mkdir("emacs-src-cache") - ## Source for gcc-libs is part of gcc - ## Source for libwinpthread is in libwinpthreads - ## mpc, termcap, xpm -- has x86_64, and i686 versions - - ## This needs to have been run first at the same time as the - ## system was updated. os.mkdir("emacs-src") os.chdir("emacs-src") - to_download = [] for pkg in deps: pkg_name_and_version= \ check_output(["pacman","-Q", pkg]).decode("utf-8").strip() @@ -208,31 +197,18 @@ def gather_source(deps): pkg_name=pkg_name_components[0] pkg_version=pkg_name_components[1] - ## make a simple name to make lookup easier - simple_pkg_name = re.sub(r"x86_64-","",pkg_name) + ## source pkgs don't have an architecture in them + pkg_name = re.sub(r"x86_64-","",pkg_name) - if(simple_pkg_name in SKIP_SRC_PKGS): + if(pkg_name in SKIP_SRC_PKGS): continue - ## Some packages have different source files for different - ## architectures. For these we need two downloads. - if(simple_pkg_name in ARCH_PKGS): - downloads = [pkg_name, - re.sub(r"x86_64","i686",pkg_name)] - else: - downloads = [simple_pkg_name] + ## Switch names if necessary + pkg_name = MUNGE_SRC_PKGS.get(pkg_name,pkg_name) - for d in downloads: - ## Switch names if necessary - d = MUNGE_SRC_PKGS.get(d,d) + tarball = "{}-{}.src.tar.gz".format(pkg_name,pkg_version) - tarball = "{}-{}.src.tar.gz".format(d,pkg_version) - - to_download.append(tarball) - - ## Download in parallel or it is just too slow - p = mp.Pool(1) - p.map(download_source,to_download) + download_source(tarball) print("Zipping") check_output_maybe("zip -9 ../emacs-{}-{}deps-mingw-w64-src.zip *" @@ -245,7 +221,6 @@ def gather_source(deps): def clean(): print("Cleaning") os.path.isdir("emacs-src") and shutil.rmtree("emacs-src") - os.path.isdir("i686") and shutil.rmtree("i686") os.path.isdir("x86_64") and shutil.rmtree("x86_64") os.path.isfile("download.log") and os.remove("download.log") @@ -259,12 +234,6 @@ def clean(): parser.add_argument("-s", help="snapshot build", action="store_true") -parser.add_argument("-t", help="32 bit deps only", - action="store_true") - -parser.add_argument("-f", help="64 bit deps only", - action="store_true") - parser.add_argument("-r", help="source code only", action="store_true") @@ -278,7 +247,7 @@ def clean(): action="store_true") args = parser.parse_args() -do_all=not (args.c or args.r or args.f or args.t) +do_all=not (args.c or args.r) @@ -294,11 +263,8 @@ def clean(): else: DATE="" -if( do_all or args.t ): - gather_deps("i686","mingw32") - -if( do_all or args.f ): - gather_deps("x86_64","mingw64") +if( do_all): + gather_deps() if( do_all or args.r ): deps=extract_deps() diff --git a/admin/nt/dist-build/build-zips.sh b/admin/nt/dist-build/build-zips.sh index fbb9889538..7bc6ea6a9e 100755 --- a/admin/nt/dist-build/build-zips.sh +++ b/admin/nt/dist-build/build-zips.sh @@ -29,70 +29,62 @@ function git_up { } function build_zip { - - ARCH=$1 - PKG=$2 - HOST=$3 - - echo [build] Building Emacs-$VERSION for $ARCH - if [ $ARCH == "i686" ] - then - PATH=/mingw32/bin:$PATH - MSYSTEM=MINGW32 - fi + echo [build] Building Emacs-$VERSION ## Clean the install location because we use it twice - rm -rf $HOME/emacs-build/install/emacs-$VERSION/$ARCH - mkdir --parents $HOME/emacs-build/build/emacs-$VERSION/$ARCH - cd $HOME/emacs-build/build/emacs-$VERSION/$ARCH + rm -rf $HOME/emacs-build/install/emacs-$VERSION + mkdir --parents $HOME/emacs-build/build/emacs-$VERSION + cd $HOME/emacs-build/build/emacs-$VERSION + + ## Do we need this or is it the default? + export PKG_CONFIG_PATH=/mingw64/lib/pkgconfig - export PKG_CONFIG_PATH=$PKG ## Running configure forces a rebuild of the C core which takes ## time that is not always needed, so do not do it unless we have ## to. if [ ! -f Makefile ] || (($CONFIG)) then - echo [build] Configuring Emacs $ARCH + echo [build] Configuring Emacs $REPO_DIR/$BRANCH/configure \ --without-dbus \ - --host=$HOST --without-compress-install \ + --without-compress-install \ $CACHE \ CFLAGS="$CFLAGS" fi make -j 4 $INSTALL_TARGET \ - prefix=$HOME/emacs-build/install/emacs-$VERSION/$ARCH - cd $HOME/emacs-build/install/emacs-$VERSION/$ARCH - zip -r -9 emacs-$OF_VERSION-$ARCH-no-deps.zip * - mv emacs-$OF_VERSION-$ARCH-no-deps.zip $HOME/emacs-upload + prefix=$HOME/emacs-build/install/emacs-$VERSION + cd $HOME/emacs-build/install/emacs-$VERSION + zip -r -9 emacs-$OF_VERSION-no-deps.zip * + mv emacs-$OF_VERSION-no-deps.zip $HOME/emacs-upload if [ -z $SNAPSHOT ]; then - DEPS_FILE=$HOME/emacs-build/deps/emacs-$MAJOR_VERSION-$ARCH-deps.zip + DEPS_FILE=$HOME/emacs-build/deps/emacs-$MAJOR_VERSION-deps.zip else ## Pick the most recent snapshot whatever that is - DEPS_FILE=`ls $HOME/emacs-build/deps/emacs-$MAJOR_VERSION-*-$ARCH-deps.zip | tail -n 1` + DEPS_FILE=`ls $HOME/emacs-build/deps/emacs-$MAJOR_VERSION-*-deps.zip | tail -n 1` fi echo [build] Using $DEPS_FILE unzip -d bin $DEPS_FILE - zip -r -9 emacs-$OF_VERSION-$ARCH.zip * - mv emacs-$OF_VERSION-$ARCH.zip ~/emacs-upload + zip -r -9 emacs-$OF_VERSION.zip * + mv emacs-$OF_VERSION.zip ~/emacs-upload } function build_installer { - ARCH=$1 - cd $HOME/emacs-build/install/emacs-$VERSION + cd $HOME/emacs-build/install/ echo [build] Calling makensis in `pwd` cp $REPO_DIR/$BRANCH/admin/nt/dist-build/emacs.nsi . makensis -v4 \ - -DARCH=$ARCH -DEMACS_VERSION=$ACTUAL_VERSION \ + -DEMACS_VERSION=$ACTUAL_VERSION \ + -DVERSION_BRANCH=$VERSION \ -DOUT_VERSION=$OF_VERSION emacs.nsi rm emacs.nsi - mv emacs-$OF_VERSION-$ARCH-installer.exe ~/emacs-upload + mv emacs-$OF_VERSION-installer.exe ~/emacs-upload } set -o errexit @@ -101,7 +93,6 @@ SNAPSHOT= CACHE= BUILD=1 -BUILD_32=1 BUILD_64=1 GIT_UP=0 CONFIG=1 @@ -112,19 +103,8 @@ INSTALL_TARGET="install-strip" REPO_DIR=$HOME/emacs-build/git/ -while getopts "36gb:hnsiV:" opt; do +while getopts "gb:hnsiV:" opt; do case $opt in - 3) - BUILD_32=1 - BUILD_64=0 - GIT_UP=0 - ;; - 6) - BUILD_32=0 - BUILD_64=1 - GIT_UP=0 - ;; - g) BUILD_32=0 BUILD_64=0 @@ -150,10 +130,11 @@ while getopts "36gb:hnsiV:" opt; do ;; h) echo "build-zips.sh" - echo " -3 32 bit build only" - echo " -6 64 bit build only" + echo " -b args -- build args branch" echo " -g git update and worktree only" echo " -i build installer only" + echo " -n do not configure" + echo " -s snaphot build" exit 0 ;; \?) @@ -223,18 +204,7 @@ if (($BUILD_64)) then if (($BUILD)) then - build_zip x86_64 /mingw64/lib/pkgconfig x86_64-w64-mingw32 - fi - build_installer x86_64 -fi - -## Do the 64 bit build first, because we reset some environment -## variables during the 32 bit which will break the build. -if (($BUILD_32)) -then - if (($BUILD)) - then - build_zip i686 /mingw32/lib/pkgconfig i686-w64-mingw32 + build_zip fi - build_installer i686 + build_installer fi diff --git a/admin/nt/dist-build/emacs.nsi b/admin/nt/dist-build/emacs.nsi index dce8f3db4a..557bb106dd 100644 --- a/admin/nt/dist-build/emacs.nsi +++ b/admin/nt/dist-build/emacs.nsi @@ -2,7 +2,7 @@ !include LogicLib.nsh !include x64.nsh -Outfile "emacs-${OUT_VERSION}-${ARCH}-installer.exe" +Outfile "emacs-${OUT_VERSION}-installer.exe" SetCompressor /solid lzma @@ -14,15 +14,15 @@ Var StartMenuFolder !define MUI_WELCOMEPAGE_TITLE_3LINES !define MUI_WELCOMEPAGE_TEXT "Welcome to Emacs -- the editor of a lifetime." -!define MUI_WELCOMEFINISHPAGE_BITMAP "${ARCH}\share\emacs\${EMACS_VERSION}\etc\images\splash.bmp" -!define MUI_ICON "${ARCH}\share\emacs\${EMACS_VERSION}\etc\images\icons\hicolor\scalable\apps\emacs.ico" -!define MUI_UNICON "${ARCH}\share\emacs\${EMACS_VERSION}\etc\images\icons\hicolor\scalable\apps\emacs.ico" +!define MUI_WELCOMEFINISHPAGE_BITMAP "emacs-${VERSION_BRANCH}\share\emacs\${EMACS_VERSION}\etc\images\splash.bmp" +!define MUI_ICON "emacs-${VERSION_BRANCH}\share\emacs\${EMACS_VERSION}\etc\images\icons\hicolor\scalable\apps\emacs.ico" +!define MUI_UNICON "emacs-${VERSION_BRANCH}\share\emacs\${EMACS_VERSION}\etc\images\icons\hicolor\scalable\apps\emacs.ico" !insertmacro MUI_PAGE_WELCOME !define MUI_LICENSEPAGE_TEXT_TOP "The GNU General Public License" -!insertmacro MUI_PAGE_LICENSE "${ARCH}\share\emacs\${EMACS_VERSION}\lisp\COPYING" +!insertmacro MUI_PAGE_LICENSE "emacs-${VERSION_BRANCH}\share\emacs\${EMACS_VERSION}\lisp\COPYING" !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES @@ -36,19 +36,7 @@ Var StartMenuFolder Name Emacs-${EMACS_VERSION} function .onInit - ${If} ${RunningX64} - ${If} ${ARCH} == "x86_64" - StrCpy $INSTDIR "$PROGRAMFILES64\Emacs" - ${Else} - StrCpy $INSTDIR "$PROGRAMFILES32\Emacs" - ${Endif} - ${Else} - ${If} ${ARCH} == "x86_64" - Quit - ${Else} - StrCpy $INSTDIR "$PROGRAMFILES\Emacs" - ${Endif} - ${EndIf} + StrCpy $INSTDIR "$PROGRAMFILES64\Emacs" functionend @@ -56,7 +44,8 @@ Section SetOutPath $INSTDIR - File /r ${ARCH} + File /r emacs-${VERSION_BRANCH} + # define uninstaller name WriteUninstaller $INSTDIR\Uninstall.exe @@ -66,7 +55,7 @@ Section CreateShortcut "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" "$INSTDIR\Uninstall.exe" !insertmacro MUI_STARTMENU_WRITE_END - CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Emacs.lnk" "$INSTDIR\${ARCH}\bin\runemacs.exe" + CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Emacs.lnk" "$INSTDIR\emacs-${VERSION_BRANCH}\bin\runemacs.exe" SectionEnd @@ -78,7 +67,7 @@ Section "Uninstall" Delete "$INSTDIR\Uninstall.exe" # now delete installed directory - RMDir /r "$INSTDIR\${ARCH}" + RMDir /r "$INSTDIR" RMDir "$INSTDIR" !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder commit f95c1b32300fbdef7b8e2b36b330a1d81db949ed Author: Phillip Lord Date: Thu Jan 7 22:06:53 2021 +0000 Update dependency capture * admin/nt/dist-build/build-dep-zips.py: Use ntldd to directly determine DLL dependencies diff --git a/admin/nt/dist-build/build-dep-zips.py b/admin/nt/dist-build/build-dep-zips.py index 47185dbb1b..ec99bd606d 100755 --- a/admin/nt/dist-build/build-dep-zips.py +++ b/admin/nt/dist-build/build-dep-zips.py @@ -40,10 +40,77 @@ mingw-w64-x86_64-libxml2 mingw-w64-x86_64-xpm-nox'''.split() +DLL_REQ='''libgif +libgnutls +libharfbuzz +libjansson +liblcms2 +libturbojpeg +libpng +librsvg +libtiff +libxml +libXpm'''.split() + ## Options DRY_RUN=False + +def check_output_maybe(*args,**kwargs): + if(DRY_RUN): + print("Calling: {}{}".format(args,kwargs)) + else: + return check_output(*args,**kwargs) + +## DLL Capture +def gather_deps(arch, directory): + os.mkdir(arch) + os.chdir(arch) + + for dep in full_dll_dependency(directory): + check_output_maybe(["cp /{}/bin/{}*.dll .".format(directory, dep)], + shell=True) + + ## And package them up + ## os.chdir(arch) + print("Zipping: {}".format(arch)) + check_output_maybe("zip -9r ../emacs-{}-{}{}-deps.zip *" + .format(EMACS_MAJOR_VERSION, DATE, arch), + shell=True) + os.chdir("../") + +## Return all Emacs dependencies +def full_dll_dependency(directory): + deps = [dll_dependency(dep, directory) for dep in DLL_REQ] + return set(sum(deps, []) + DLL_REQ) + +## Dependencies for a given DLL +def dll_dependency(dll, directory): + output = check_output(["/mingw64/bin/ntldd", "--recursive", + "/{}/bin/{}*.dll".format(directory, dll)]).decode("utf-8") + ## munge output + return ntldd_munge(output) + +def ntldd_munge(out): + deps = out.splitlines() + rtn = [] + for dep in deps: + ## Output looks something like this + + ## KERNEL32.dll => C:\Windows\SYSTEM32\KERNEL32.dll (0x0000000002a30000) + ## libwinpthread-1.dll => C:\msys64\mingw64\bin\libwinpthread-1.dll (0x0000000000090000) + + ## if it's the former, we want it, if its the later we don't + splt = dep.split() + if len(splt) > 2 and "msys64" in splt[2]: + print("Adding dep", splt[0]) + rtn.append(splt[0].split(".")[0]) + + return rtn + +#### Source Capture + ## Packages to fiddle with ## Source for gcc-libs is part of gcc SKIP_SRC_PKGS=["mingw-w64-gcc-libs"] @@ -62,12 +129,6 @@ SRC_REPO="https://sourceforge.net/projects/msys2/files/REPOS/MINGW/Sources" -def check_output_maybe(*args,**kwargs): - if(DRY_RUN): - print("Calling: {}{}".format(args,kwargs)) - else: - return check_output(*args,**kwargs) - def immediate_deps(pkg): package_info = check_output(["pacman", "-Si", pkg]).decode("utf-8").split("\n") @@ -87,6 +148,7 @@ def immediate_deps(pkg): return dependencies +## Extract all the msys2 packages that are dependencies of our direct dependencies def extract_deps(): print( "Extracting deps" ) @@ -105,44 +167,6 @@ def extract_deps(): return sorted(pkgs) -def gather_deps(deps, arch, directory): - - os.mkdir(arch) - os.chdir(arch) - - ## Replace the architecture with the correct one - deps = [re.sub(r"x86_64",arch,x) for x in deps] - - ## find all files the transitive dependencies - deps_files = check_output( - ["pacman", "-Ql"] + deps - ).decode("utf-8").split("\n") - - ## Produces output like - ## mingw-w64-x86_64-zlib /mingw64/lib/libminizip.a - - ## drop the package name - tmp = deps_files.copy() - deps_files=[] - for d in tmp: - slt = d.split() - if(not slt==[]): - deps_files.append(slt[1]) - - ## sort uniq - deps_files = sorted(list(set(deps_files))) - ## copy all files into local - print("Copying dependencies: {}".format(arch)) - check_output_maybe(["rsync", "-R"] + deps_files + ["."]) - - ## And package them up - os.chdir(directory) - print("Zipping: {}".format(arch)) - check_output_maybe("zip -9r ../../emacs-{}-{}{}-deps.zip *" - .format(EMACS_MAJOR_VERSION, DATE, arch), - shell=True) - os.chdir("../../") - def download_source(tarball): print("Acquiring {}...".format(tarball)) @@ -160,6 +184,7 @@ def download_source(tarball): ) print("Downloading {}... done".format(tarball)) +## Fetch all the source code def gather_source(deps): @@ -206,7 +231,7 @@ def gather_source(deps): to_download.append(tarball) ## Download in parallel or it is just too slow - p = mp.Pool(16) + p = mp.Pool(1) p.map(download_source,to_download) print("Zipping") @@ -255,7 +280,7 @@ def clean(): args = parser.parse_args() do_all=not (args.c or args.r or args.f or args.t) -deps=extract_deps() + DRY_RUN=args.d @@ -270,12 +295,13 @@ def clean(): DATE="" if( do_all or args.t ): - gather_deps(deps,"i686","mingw32") + gather_deps("i686","mingw32") if( do_all or args.f ): - gather_deps(deps,"x86_64","mingw64") + gather_deps("x86_64","mingw64") if( do_all or args.r ): + deps=extract_deps() gather_source(deps) if( args.c ): diff --git a/admin/nt/dist-build/build-zips.sh b/admin/nt/dist-build/build-zips.sh index 4a9a7b596e..fbb9889538 100755 --- a/admin/nt/dist-build/build-zips.sh +++ b/admin/nt/dist-build/build-zips.sh @@ -64,10 +64,8 @@ function build_zip { make -j 4 $INSTALL_TARGET \ prefix=$HOME/emacs-build/install/emacs-$VERSION/$ARCH cd $HOME/emacs-build/install/emacs-$VERSION/$ARCH - cp $HOME/emacs-build/deps/libXpm/$ARCH/libXpm-noX4.dll bin zip -r -9 emacs-$OF_VERSION-$ARCH-no-deps.zip * mv emacs-$OF_VERSION-$ARCH-no-deps.zip $HOME/emacs-upload - rm bin/libXpm-noX4.dll if [ -z $SNAPSHOT ]; then @@ -78,7 +76,7 @@ function build_zip { fi echo [build] Using $DEPS_FILE - unzip $DEPS_FILE + unzip -d bin $DEPS_FILE zip -r -9 emacs-$OF_VERSION-$ARCH.zip * mv emacs-$OF_VERSION-$ARCH.zip ~/emacs-upload @@ -208,7 +206,7 @@ then else BRANCH=$REQUIRED_BRANCH echo [build] Building from Branch $BRANCH - VERSION=$VERSION-$BRANCH + VERSION=$VERSION-${BRANCH/\//_} OF_VERSION="$VERSION-`date +%Y-%m-%d`" ## Use snapshot dependencies SNAPSHOT=1 commit 2644353cbc65927a6a0a76d68e00d017771cdd03 Author: Stephen Leake Date: Fri Jan 15 10:03:06 2021 -0800 * .gitignore: add src/fingerprint.c * lisp/dired-x.el (dired-file-name-at-point): Fix spelling in obsolete message. diff --git a/.gitignore b/.gitignore index dd4eab759c..7e3e434181 100644 --- a/.gitignore +++ b/.gitignore @@ -298,3 +298,4 @@ nt/emacs.rc nt/emacsclient.rc src/gdb.ini /var/ +src/fingerprint.c diff --git a/lisp/dired-x.el b/lisp/dired-x.el index 5a52eccbbe..aebffe339e 100644 --- a/lisp/dired-x.el +++ b/lisp/dired-x.el @@ -1483,7 +1483,7 @@ a prefix argument, when it offers the filename near point as a default." ;;; Internal functions. ;; Fixme: This should probably use `thing-at-point'. -- fx -(define-obsolete-function-alias 'dired-filename-at-point +(define-obsolete-function-alias 'dired-file-name-at-point #'dired-x-guess-file-name-at-point "28.1") (defun dired-x-guess-file-name-at-point () "Return the filename closest to point, expanded. commit 4dc72dd9deb1c3394ada3de3f52bc7c1ff831ab6 Author: Aaron Jensen Date: Sat Jan 9 20:43:32 2021 -0600 Fix 'window-text-pixel-size' when there are leading/trailing spaces First, scan to find the first non-whitespace character and then backtrack to find the beginning of the line. The previous algorithm always started on the non-whitespace character during the backtrack, causing it to stop immediately and not actually find the beginning of the line. The same applies to the end of line calculation. * src/xdisp.c: (Fwindow_text_pixel_size): Fix off by one error. (Bug#45748) * test/src/xdisp-tests.el (xdisp-tests--window-text-pixel-size) (xdisp-tests--window-text-pixel-size-leading-space) (xdisp-tests--window-text-pixel-size-trailing-space): New tests. diff --git a/src/xdisp.c b/src/xdisp.c index 64f401690a..ea67329cff 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10649,9 +10649,10 @@ include the height of both, if present, in the return value. */) bpos = BEGV_BYTE; while (bpos < ZV_BYTE) { - c = fetch_char_advance (&start, &bpos); + c = FETCH_BYTE (bpos); if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) break; + inc_both (&start, &bpos); } while (bpos > BEGV_BYTE) { @@ -10680,7 +10681,10 @@ include the height of both, if present, in the return value. */) dec_both (&end, &bpos); c = FETCH_BYTE (bpos); if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) - break; + { + inc_both (&end, &bpos); + break; + } } while (bpos < ZV_BYTE) { diff --git a/test/src/xdisp-tests.el b/test/src/xdisp-tests.el index d13ce77a99..ec96d777ff 100644 --- a/test/src/xdisp-tests.el +++ b/test/src/xdisp-tests.el @@ -72,4 +72,34 @@ (should (equal (nth 0 posns) (nth 1 posns))) (should (equal (nth 1 posns) (nth 2 posns))))) +(ert-deftest xdisp-tests--window-text-pixel-size () ;; bug#45748 + (with-temp-buffer + (insert "xxx") + (let* ((window + (display-buffer (current-buffer) '(display-buffer-in-child-frame . nil))) + (char-width (frame-char-width)) + (size (window-text-pixel-size nil t t))) + (delete-frame (window-frame window)) + (should (equal (/ (car size) char-width) 3))))) + +(ert-deftest xdisp-tests--window-text-pixel-size-leading-space () ;; bug#45748 + (with-temp-buffer + (insert " xx") + (let* ((window + (display-buffer (current-buffer) '(display-buffer-in-child-frame . nil))) + (char-width (frame-char-width)) + (size (window-text-pixel-size nil t t))) + (delete-frame (window-frame window)) + (should (equal (/ (car size) char-width) 3))))) + +(ert-deftest xdisp-tests--window-text-pixel-size-trailing-space () ;; bug#45748 + (with-temp-buffer + (insert "xx ") + (let* ((window + (display-buffer (current-buffer) '(display-buffer-in-child-frame . nil))) + (char-width (frame-char-width)) + (size (window-text-pixel-size nil t t))) + (delete-frame (window-frame window)) + (should (equal (/ (car size) char-width) 3))))) + ;;; xdisp-tests.el ends here commit 66ac17289a5d04366a6b05eb5a105dff408b16b8 Author: Jared Finder Date: Sat Jan 2 14:10:17 2021 -0800 Make libraries works with xterm-mouse-mode. Change calls from 'read-event' to 'read-key' in libraries expecting mouse events. Do this only when 'xterm-mouse-mode' is enabled. That way those libraries read decoded mouse events instead of the underlying escape sequence. Add a parameter to 'read-key' that avoids running any of the unbound fallbacks in 'read-key-sequence' so the libraries can read mouse button-down events. For backward compatibility purposes, the above logic is contained in a new internal-only function: 'read--potential-mouse-event'. * doc/lispref/commands.texi (Reading One Event): Document new parameter to 'read-key'. Mention that non-character events on terminals need 'read-key'. * lisp/subr.el (read-key-full-map): Add new keymap used by 'read-key'. (read-key): Add new parameter 'fallbacks-disabled' to prevent running any of the unbound fallbacks normally run by 'read-key-sequence'. (read--potential-mouse-event): Add new function that calls 'read-key' or 'read-event' depending on if 'xterm-mouse-mode' is set. * lisp/foldout.el (foldout-mouse-swallow-events): * lisp/isearch.el (isearch-pre-command-hook): * lisp/mouse-drag.el (mouse-drag-throw, mouse-drag-drag): * lisp/mouse.el (mouse-drag-secondary): * lisp/ruler-mode.el (ruler-mode-mouse-grab-any-column) (ruler-mode-mouse-drag-any-column-iteration): * lisp/strokes.el (strokes-read-stroke, strokes-read-complex-stroke): * lisp/textmodes/artist.el (artist-mouse-draw-continously) (artist-mouse-draw-poly, artist-mouse-draw-2points): * lisp/vc/ediff-wind.el (ediff-get-window-by-clicking): * lisp/wid-edit.el (widget-button--check-and-call-button) (widget-button-click): Call 'read--potential-mouse-event' instead of 'read-event'. * lisp/wid-edit.el (widget-key-sequence-read-event): Call 'read-key' with 'fallbacks-disabled' set instead of 'read-event'. Unlike above changes, this is unconditionally applied so it works for function keys too. Apply 'local-function-key-map' instead of 'function-key-map' as that contains the full terminal translations. * lisp/vc/ediff.el (ediff-windows): Use 'display-mouse-p' to check if a mouse is available. * src/lread.c (Fread_event): Recommend 'read-key' in docstring for 'read-event' for non-character events. diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 6c68f70482..3a2c7d019e 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -2696,9 +2696,11 @@ from the terminal---not counting those generated by keyboard macros. @code{read-event}, @code{read-char}, and @code{read-char-exclusive} do not perform the translations described in @ref{Translation Keymaps}. If you wish to read a single key taking these translations into -account, use the function @code{read-key}: +account (for example, to read @ref{Function Keys} in a terminal or +@ref{Mouse Events} from @code{xterm-mouse-mode}), use the function +@code{read-key}: -@defun read-key &optional prompt +@defun read-key &optional prompt disable-fallbacks This function reads a single key. It is intermediate between @code{read-key-sequence} and @code{read-event}. Unlike the former, it reads a single key, not a key sequence. Unlike the latter, it does @@ -2708,6 +2710,14 @@ and @code{key-translation-map} (@pxref{Translation Keymaps}). The argument @var{prompt} is either a string to be displayed in the echo area as a prompt, or @code{nil}, meaning not to display a prompt. + +If argument @var{disable-fallbacks} is non-@code{nil} then the usual +fallback logic for unbound keys in @code{read-key-sequence} is not +applied. This means that mouse button-down and multi-click events +will not be discarded and @code{local-function-key-map} and +@code{key-translation-map} will not get applied. If @code{nil} or +unspecified, the only fallback disabled is downcasing of the last +event. @end defun @defun read-char-choice prompt chars &optional inhibit-quit diff --git a/lisp/foldout.el b/lisp/foldout.el index 771b81e5be..4c479d68e9 100644 --- a/lisp/foldout.el +++ b/lisp/foldout.el @@ -487,7 +487,7 @@ What happens depends on the number of mouse clicks:- Signal an error if the final event isn't the same type as the first one." (let ((initial-event-type (event-basic-type event))) (while (null (sit-for (/ double-click-time 1000.0) 'nodisplay)) - (setq event (read-event))) + (setq event (read--potential-mouse-event))) (or (eq initial-event-type (event-basic-type event)) (error ""))) event) diff --git a/lisp/isearch.el b/lisp/isearch.el index d8d3a731a4..c6f7fe7bd4 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -3002,7 +3002,7 @@ See more for options in `search-exit-option'." ((and (eq (car-safe main-event) 'down-mouse-1) (window-minibuffer-p (posn-window (event-start main-event)))) ;; Swallow the up-event. - (read-event) + (read--potential-mouse-event) (setq this-command 'isearch-edit-string)) ;; Don't terminate the search for motion commands. ((and isearch-yank-on-move diff --git a/lisp/mouse-drag.el b/lisp/mouse-drag.el index f6612600bd..907ef06159 100644 --- a/lisp/mouse-drag.el +++ b/lisp/mouse-drag.el @@ -225,7 +225,7 @@ To test this function, evaluate: ;; Don't change the mouse pointer shape while we drag. (setq track-mouse 'dragging) (while (progn - (setq event (read-event) + (setq event (read--potential-mouse-event) end (event-end event) row (cdr (posn-col-row end)) col (car (posn-col-row end))) @@ -286,7 +286,7 @@ To test this function, evaluate: window-last-col (- (window-width) 2)) (track-mouse (while (progn - (setq event (read-event) + (setq event (read--potential-mouse-event) end (event-end event) row (cdr (posn-col-row end)) col (car (posn-col-row end))) diff --git a/lisp/mouse.el b/lisp/mouse.el index 0da82882fc..8732fb8086 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -1792,7 +1792,7 @@ The function returns a non-nil value if it creates a secondary selection." (let (event end end-point) (track-mouse (while (progn - (setq event (read-event)) + (setq event (read--potential-mouse-event)) (or (mouse-movement-p event) (memq (car-safe event) '(switch-frame select-window)))) diff --git a/lisp/ruler-mode.el b/lisp/ruler-mode.el index 7cda6c96af..1e81904419 100644 --- a/lisp/ruler-mode.el +++ b/lisp/ruler-mode.el @@ -429,7 +429,7 @@ dragging. See also the variable `ruler-mode-dragged-symbol'." ;; `ding' flushes the next messages about setting goal ;; column. So here I force fetch the event(mouse-2) and ;; throw away. - (read-event) + (read--potential-mouse-event) ;; Ding BEFORE `message' is OK. (when ruler-mode-set-goal-column-ding-flag (ding)) @@ -460,7 +460,7 @@ the mouse has been clicked." (track-mouse ;; Signal the display engine to freeze the mouse pointer shape. (setq track-mouse 'dragging) - (while (mouse-movement-p (setq event (read-event))) + (while (mouse-movement-p (setq event (read--potential-mouse-event))) (setq drags (1+ drags)) (when (eq window (posn-window (event-end event))) (ruler-mode-mouse-drag-any-column event) diff --git a/lisp/strokes.el b/lisp/strokes.el index b0ab4f990f..55f2ae8cc4 100644 --- a/lisp/strokes.el +++ b/lisp/strokes.el @@ -756,12 +756,12 @@ Optional EVENT is acceptable as the starting event of the stroke." (strokes-fill-current-buffer-with-whitespace)) (when prompt (message "%s" prompt) - (setq event (read-event)) + (setq event (read--potential-mouse-event)) (or (strokes-button-press-event-p event) (error "You must draw with the mouse"))) (unwind-protect (track-mouse - (or event (setq event (read-event) + (or event (setq event (read--potential-mouse-event) safe-to-draw-p t)) (while (not (strokes-button-release-event-p event)) (if (strokes-mouse-event-p event) @@ -776,7 +776,7 @@ Optional EVENT is acceptable as the starting event of the stroke." (setq safe-to-draw-p t)) (push (cdr (mouse-pixel-position)) pix-locs))) - (setq event (read-event))))) + (setq event (read--potential-mouse-event))))) ;; protected ;; clean up strokes buffer and then bury it. (when (equal (buffer-name) strokes-buffer-name) @@ -787,16 +787,16 @@ Optional EVENT is acceptable as the starting event of the stroke." ;; Otherwise, don't use strokes buffer and read stroke silently (when prompt (message "%s" prompt) - (setq event (read-event)) + (setq event (read--potential-mouse-event)) (or (strokes-button-press-event-p event) (error "You must draw with the mouse"))) (track-mouse - (or event (setq event (read-event))) + (or event (setq event (read--potential-mouse-event))) (while (not (strokes-button-release-event-p event)) (if (strokes-mouse-event-p event) (push (cdr (mouse-pixel-position)) pix-locs)) - (setq event (read-event)))) + (setq event (read--potential-mouse-event)))) (setq grid-locs (strokes-renormalize-to-grid (nreverse pix-locs))) (strokes-fill-stroke (strokes-eliminate-consecutive-redundancies grid-locs))))) @@ -817,10 +817,10 @@ Optional EVENT is acceptable as the starting event of the stroke." (if prompt (while (not (strokes-button-press-event-p event)) (message "%s" prompt) - (setq event (read-event)))) + (setq event (read--potential-mouse-event)))) (unwind-protect (track-mouse - (or event (setq event (read-event))) + (or event (setq event (read--potential-mouse-event))) (while (not (and (strokes-button-press-event-p event) (eq 'mouse-3 (car (get (car event) @@ -834,14 +834,15 @@ Optional EVENT is acceptable as the starting event of the stroke." ?\s strokes-character)) (push (cdr (mouse-pixel-position)) pix-locs))) - (setq event (read-event))) + (setq event (read--potential-mouse-event))) (push strokes-lift pix-locs) (while (not (strokes-button-press-event-p event)) - (setq event (read-event)))) + (setq event (read--potential-mouse-event)))) ;; ### KLUDGE! ### sit and wait ;; for some useless event to ;; happen to fix the minibuffer bug. - (while (not (strokes-button-release-event-p (read-event)))) + (while (not (strokes-button-release-event-p + (read--potential-mouse-event)))) (setq pix-locs (nreverse (cdr pix-locs)) grid-locs (strokes-renormalize-to-grid pix-locs)) (strokes-fill-stroke diff --git a/lisp/subr.el b/lisp/subr.el index 9b89e49370..f249ec3578 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2569,23 +2569,52 @@ It can be retrieved with `(process-get PROCESS PROPNAME)'." ;;;; Input and display facilities. -(defconst read-key-empty-map (make-sparse-keymap)) +;; The following maps are used by `read-key' to remove all key +;; bindings while calling `read-key-sequence'. This way the keys +;; returned are independent of the key binding state. + +(defconst read-key-empty-map (make-sparse-keymap) + "Used internally by `read-key'.") + +(defconst read-key-full-map + (let ((map (make-sparse-keymap))) + (define-key map [t] 'dummy) + + ;; ESC needs to be unbound so that escape sequences in + ;; `input-decode-map' are still processed by `read-key-sequence'. + (define-key map [?\e] nil) + map) + "Used internally by `read-key'.") (defvar read-key-delay 0.01) ;Fast enough for 100Hz repeat rate, hopefully. -(defun read-key (&optional prompt) +(defun read-key (&optional prompt disable-fallbacks) "Read a key from the keyboard. Contrary to `read-event' this will not return a raw event but instead will obey the input decoding and translations usually done by `read-key-sequence'. So escape sequences and keyboard encoding are taken into account. When there's an ambiguity because the key looks like the prefix of -some sort of escape sequence, the ambiguity is resolved via `read-key-delay'." +some sort of escape sequence, the ambiguity is resolved via `read-key-delay'. + +If the optional argument PROMPT is non-nil, display that as a +prompt. + +If the optional argument DISABLE-FALLBACKS is non-nil, all +unbound fallbacks usually done by `read-key-sequence' are +disabled such as discarding mouse down events. This is generally +what you want as `read-key' temporarily removes all bindings +while calling `read-key-sequence'. If nil or unspecified, the +only unbound fallback disabled is downcasing of the last event." ;; This overriding-terminal-local-map binding also happens to ;; disable quail's input methods, so although read-key-sequence ;; always inherits the input method, in practice read-key does not ;; inherit the input method (at least not if it's based on quail). (let ((overriding-terminal-local-map nil) - (overriding-local-map read-key-empty-map) + (overriding-local-map + ;; FIXME: Audit existing uses of `read-key' to see if they + ;; should always specify disable-fallbacks to be more in line + ;; with `read-event'. + (if disable-fallbacks read-key-full-map read-key-empty-map)) (echo-keystrokes 0) (old-global-map (current-global-map)) (timer (run-with-idle-timer @@ -2639,6 +2668,23 @@ some sort of escape sequence, the ambiguity is resolved via `read-key-delay'." (message nil) (use-global-map old-global-map)))) +;; FIXME: Once there's a safe way to transition away from read-event, +;; callers to this function should be updated to that way and this +;; function should be deleted. +(defun read--potential-mouse-event () + "Read an event that might be a mouse event. + +This function exists for backward compatibility in code packaged +with Emacs. Do not call it directly in your own packages." + ;; `xterm-mouse-mode' events must go through `read-key' as they + ;; are decoded via `input-decode-map'. + (if xterm-mouse-mode + (read-key nil + ;; Normally `read-key' discards all mouse button + ;; down events. However, we want them here. + t) + (read-event))) + (defvar read-passwd-map ;; BEWARE: `defconst' would purecopy it, breaking the sharing with ;; minibuffer-local-map along the way! diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el index ce620821d6..50c00c9532 100644 --- a/lisp/textmodes/artist.el +++ b/lisp/textmodes/artist.el @@ -5004,7 +5004,7 @@ The event, EV, is the mouse event." (setq timer (run-at-time interval interval draw-fn x1 y1)))) ;; Read next event - (setq ev (read-event)))) + (setq ev (read--potential-mouse-event)))) ;; Cleanup: get rid of any active timer. (if timer (cancel-timer timer))) @@ -5212,7 +5212,7 @@ The event, EV, is the mouse event." ;; Read next event (only if we should not stop) (if (not done) - (setq ev (read-event))))) + (setq ev (read--potential-mouse-event))))) ;; Reverse point-list (last points are cond'ed first) (setq point-list (reverse point-list)) @@ -5339,7 +5339,7 @@ The event, EV, is the mouse event." ;; Read next event - (setq ev (read-event)))) + (setq ev (read--potential-mouse-event)))) ;; If we are not rubber-banding (that is, we were moving around the `2') ;; draw the shape diff --git a/lisp/vc/ediff-wind.el b/lisp/vc/ediff-wind.el index 72b345874f..47ef37a19e 100644 --- a/lisp/vc/ediff-wind.el +++ b/lisp/vc/ediff-wind.el @@ -262,11 +262,12 @@ keyboard input to go into icons." (let (event) (message "Select windows by clicking. Please click on Window %d " wind-number) - (while (not (ediff-mouse-event-p (setq event (read-event)))) + (while (not (ediff-mouse-event-p (setq event + (read--potential-mouse-event)))) (if (sit-for 1) ; if sequence of events, wait till the final word (beep 1)) (message "Please click on Window %d " wind-number)) - (read-event) ; discard event + (read--potential-mouse-event) ; discard event (posn-window (event-start event)))) diff --git a/lisp/vc/ediff.el b/lisp/vc/ediff.el index e3612dd8e3..ed375738b4 100644 --- a/lisp/vc/ediff.el +++ b/lisp/vc/ediff.el @@ -939,7 +939,7 @@ arguments after setting up the Ediff buffers." ;; If WIND-A is nil, use selected window. ;; If WIND-B is nil, use window next to WIND-A. (defun ediff-windows (dumb-mode wind-A wind-B startup-hooks job-name word-mode) - (if (or dumb-mode (not (ediff-window-display-p))) + (if (or dumb-mode (not (display-mouse-p))) (setq wind-A (ediff-get-next-window wind-A nil) wind-B (ediff-get-next-window wind-B wind-A)) (setq wind-A (ediff-get-window-by-clicking wind-A nil 1) diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index 8b10d71dcb..7dda04eda2 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el @@ -1104,7 +1104,7 @@ If nothing was called, return non-nil." (unless (widget-apply button :mouse-down-action event) (let ((track-mouse t)) (while (not (widget-button-release-event-p event)) - (setq event (read-event)) + (setq event (read--potential-mouse-event)) (when (and mouse-1 (mouse-movement-p event)) (push event unread-command-events) (setq event oevent) @@ -1169,7 +1169,7 @@ If nothing was called, return non-nil." (when up ;; Don't execute up events twice. (while (not (widget-button-release-event-p event)) - (setq event (read-event)))) + (setq event (read--potential-mouse-event)))) (when command (call-interactively command))))) (message "You clicked somewhere weird."))) @@ -3486,14 +3486,16 @@ It reads a directory name from an editable text field." :help-echo "C-q: insert KEY, EVENT, or CODE; RET: enter value" :tag "Key sequence") +;; FIXME: Consider combining this with help--read-key-sequence which +;; can also read double and triple mouse events. (defun widget-key-sequence-read-event (ev) (interactive (list (let ((inhibit-quit t) quit-flag) - (read-event "Insert KEY, EVENT, or CODE: ")))) + (read-key "Insert KEY, EVENT, or CODE: " t)))) (let ((ev2 (and (memq 'down (event-modifiers ev)) - (read-event))) - (tr (and (keymapp function-key-map) - (lookup-key function-key-map (vector ev))))) + (read-key nil t))) + (tr (and (keymapp local-function-key-map) + (lookup-key local-function-key-map (vector ev))))) (when (and (integerp ev) (or (and (<= ?0 ev) (< ev (+ ?0 (min 10 read-quoted-char-radix)))) (and (<= ?a (downcase ev)) diff --git a/src/lread.c b/src/lread.c index 4b168fb84b..72b68df663 100644 --- a/src/lread.c +++ b/src/lread.c @@ -787,6 +787,12 @@ If `inhibit-interaction' is non-nil, this function will signal an DEFUN ("read-event", Fread_event, Sread_event, 0, 3, 0, doc: /* Read an event object from the input stream. + +If you want to read non-character events, consider calling `read-key' +instead. `read-key' will decode events via `input-decode-map' that +`read-event' will not. On a terminal this includes function keys such +as and , or mouse events generated by `xterm-mouse-mode'. + If the optional argument PROMPT is non-nil, display that as a prompt. If PROMPT is nil or the string \"\", the key sequence/events that led to the current command is used as the prompt. commit 138486cddb9a0a4e3f159a6e9d7711570bdf2a4c Author: Michael Albinus Date: Fri Jan 15 11:32:12 2021 +0100 Some Tramp adaptions, mainly direct async processes * doc/misc/tramp.texi (Firewalls, Remote processes) (Frequently Asked Questions): Add @vindex. (Predefined connection information): Precise precondition or direct async processes. (Remote shell setup): Ban ssh RemoteCommand option. (Frequently Asked Questions): Adapt quoting. * doc/misc/trampver.texi: * lisp/net/trampver.el: Change version to "2.5.1-pre". * lisp/net/tramp-adb.el (tramp-methods) : Add `tramp-direct-async' parameter. (tramp-adb-handle-make-process): Adapt docstring. * lisp/net/tramp-sh.el (tramp-methods) : Add `tramp-direct-async' parameter. (tramp-sh-handle-insert-directory): Simplify merkers. (tramp-sh-handle-make-process): Adapt docstring. * lisp/net/tramp.el (tramp-methods): Adapt docstring. (tramp-debug-message): Suppress lockfiles. (tramp-test-message): New defun. (tramp-direct-async-process-p): Check also for `tramp-direct-async'. (tramp-handle-make-process): Do not check for `tramp-direct-async-args'. * test/lisp/net/tramp-tests.el (all): Replace `string-match' by `string-match-p'. (dired-copy-dereference): Declare. (tramp-test-temporary-file-directory): Remove `tramp-direct-async-args` for mock method. (tramp-test15-copy-directory, tramp-test40-special-characters) (tramp-test40-special-characters-with-stat) (tramp-test40-special-characters-with-perl) (tramp-test40-special-characters-with-ls, tramp-test41-utf8) (tramp-test41-utf8-with-stat, tramp-test41-utf8-with-perl) (tramp-test41-utf8-with-ls): Skip for tramp-rclone.el. (tramp--test--deftest-direct-async-process): Do not skip for mock method. (tramp-test32-shell-command): Adapt test for direct async processes. (tramp-test36-vc-registered, tramp--test-hpux-p, tramp--test-ksh-p): Use `tramp-test-vec'. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 4195ef7a51..2c4b792cc2 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -1622,6 +1622,7 @@ support this command. @subsection Tunneling with ssh +@vindex ProxyCommand@r{, ssh option} With @command{ssh}, you could use the @option{ProxyCommand} entry in @file{~/.ssh/config}: @@ -2056,9 +2057,11 @@ default value is @t{"/data/local/tmp"} for the @option{adb} method, @item @t{"direct-async-process"} When this property is non-@code{nil}, an alternative, more performant -implementation of @code{make-process} and -@code{start-file-process} is applied. @ref{Improving performance of -asynchronous remote processes} for a discussion of constraints. +implementation of @code{make-process} and @code{start-file-process} is +applied. The connection method must also be marked with a +non-@code{nil} @code{tramp-direct-async} parameter in +@code{tramp-methods}. @ref{Improving performance of asynchronous +remote processes} for a discussion of constraints. @item @t{"posix"} @@ -2214,6 +2217,11 @@ overwrite this, you might apply This uses also the settings in @code{tramp-sh-extra-args}. +@vindex RemoteCommand@r{, ssh option} +@strong{Note}: If you use an @option{ssh}-based method for connection, +do @emph{not} set the @option{RemoteCommand} option in your +@command{ssh} configuration, for example to @command{screen}. + @subsection Other remote shell setup hints @cindex remote shell setup @@ -3304,6 +3312,8 @@ whatever reason, then replace @code{(getenv "DISPLAY")} with a hard-coded, fixed name. Note that using @code{:0} for X11 display name here will not work as expected. +@vindex ForwardX11@r{, ssh option} +@vindex ForwardX11Trusted@r{, ssh option} An alternate approach is specify @option{ForwardX11 yes} or @option{ForwardX11Trusted yes} in @file{~/.ssh/config} on the local host. @@ -3566,6 +3576,7 @@ Furthermore, this approach has the following limitations: It works only for connection methods defined in @file{tramp-sh.el} and @file{tramp-adb.el}. +@vindex ControlMaster@r{, ssh option} @item It does not support interactive user authentication. With @option{ssh}-based methods, this can be avoided by using a password @@ -4269,6 +4280,7 @@ In order to disable those optimizations, set user option @item @value{tramp} does not recognize if a @command{ssh} session hangs +@vindex ServerAliveInterval@r{, ssh option} @command{ssh} sessions on the local host hang when the network is down. @value{tramp} cannot safely detect such hangs. The network configuration for @command{ssh} can be configured to kill such hangs @@ -4285,6 +4297,8 @@ Host * @item @value{tramp} does not use default @command{ssh} @option{ControlPath} +@vindex ControlPath@r{, ssh option} +@vindex ControlPersist@r{, ssh option} @value{tramp} overwrites @option{ControlPath} settings when initiating @command{ssh} sessions. @value{tramp} does this to fend off a stall if a master session opened outside the Emacs session is no longer @@ -4306,8 +4320,8 @@ which allows you to set the @option{ControlPath} provided the variable @end group @end lisp -Note how "%r", "%h" and "%p" must be encoded as "%%r", "%%h" and -"%%p". +Note how @samp{%r}, @samp{%h} and @samp{%p} must be encoded as +@samp{%%r}, @samp{%%h} and @samp{%%p}. @vindex tramp-use-ssh-controlmaster-options If the @file{~/.ssh/config} is configured appropriately for the above @@ -4318,6 +4332,8 @@ this @code{nil} setting: (customize-set-variable 'tramp-use-ssh-controlmaster-options nil) @end lisp +@vindex ProxyCommand@r{, ssh option} +@vindex ProxyJump@r{, ssh option} This shall also be set to @code{nil} if you use the @option{ProxyCommand} or @option{ProxyJump} options in your @command{ssh} configuration. diff --git a/doc/misc/trampver.texi b/doc/misc/trampver.texi index 6970c46aef..827c477328 100644 --- a/doc/misc/trampver.texi +++ b/doc/misc/trampver.texi @@ -8,7 +8,7 @@ @c In the Tramp GIT, the version numbers are auto-frobbed from @c tramp.el, and the bug report address is auto-frobbed from @c configure.ac. -@set trampver 2.5.0 +@set trampver 2.5.1-pre @set trampurl https://www.gnu.org/software/tramp/ @set tramp-bug-report-address tramp-devel@@gnu.org @set emacsver 25.1 diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index c0c215de87..2c4ef2acae 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -98,6 +98,7 @@ It is used for TCP/IP devices." `(,tramp-adb-method (tramp-login-program ,tramp-adb-program) (tramp-login-args (("shell"))) + (tramp-direct-async t) (tramp-tmpdir "/data/local/tmp") (tramp-default-port 5555))) @@ -895,8 +896,9 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." ;; terminated. (defun tramp-adb-handle-make-process (&rest args) "Like `make-process' for Tramp files. -If connection property \"direct-async-process\" is non-nil, an -alternative implementation will be used." +If method parameter `tramp-direct-async' and connection property +\"direct-async-process\" are non-nil, an alternative +implementation will be used." (if (tramp-direct-async-process-p args) (apply #'tramp-handle-make-process args) (when args diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 72873157f0..e8ee372cb2 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -168,6 +168,7 @@ The string is used in `tramp-methods'.") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) + (tramp-direct-async t) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) @@ -183,6 +184,7 @@ The string is used in `tramp-methods'.") ("-e" "none") ("-t" "-t") ("%h") ("%l"))) (tramp-async-args (("-q"))) + (tramp-direct-async t) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) @@ -197,6 +199,7 @@ The string is used in `tramp-methods'.") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) + (tramp-direct-async t) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) @@ -227,6 +230,7 @@ The string is used in `tramp-methods'.") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) + (tramp-direct-async t) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")))) @@ -237,6 +241,7 @@ The string is used in `tramp-methods'.") ("-e" "none") ("-t" "-t") ("%h") ("%l"))) (tramp-async-args (("-q"))) + (tramp-direct-async t) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")))) @@ -2668,11 +2673,9 @@ The method used must be an out-of-band method." #'file-name-nondirectory (list localname)))) (tramp-get-remote-null-device v)))) - (let ((beg-marker (point-marker)) - (end-marker (point-marker)) + (let ((beg-marker (copy-marker (point) nil)) + (end-marker (copy-marker (point) t)) (emc enable-multibyte-characters)) - (set-marker-insertion-type beg-marker nil) - (set-marker-insertion-type end-marker t) ;; We cannot use `insert-buffer-substring' because the Tramp ;; buffer changes its contents before insertion due to calling ;; `expand-file-name' and alike. @@ -2837,9 +2840,9 @@ the result will be a local, non-Tramp, file name." ;; terminated. (defun tramp-sh-handle-make-process (&rest args) "Like `make-process' for Tramp files. -STDERR can also be a file name. If connection property -\"direct-async-process\" is non-nil, an alternative -implementation will be used." +STDERR can also be a file name. If method parameter `tramp-direct-async' +and connection property \"direct-async-process\" are non-nil, an +alternative implementation will be used." (if (tramp-direct-async-process-p args) (apply #'tramp-handle-make-process args) (when args diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index cc8dda809e..2816c58fe7 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -259,9 +259,9 @@ pair of the form (KEY VALUE). The following KEYs are defined: parameters to suppress diagnostic messages, in order not to tamper the process output. - * `tramp-direct-async-args' - An additional argument when a direct asynchronous process is - started. Used so far only in the \"mock\" method of tramp-tests.el. + * `tramp-direct-async' + Whether the method supports direct asynchronous processes. + Until now, just \"ssh\"-based and \"adb\"-based methods do. * `tramp-copy-program' This specifies the name of the program to use for remotely copying @@ -1755,7 +1755,8 @@ The outline level is equal to the verbosity of the Tramp message." Message is formatted with FMT-STRING as control string and the remaining ARGUMENTS to actually emit the message (if applicable)." (let ((inhibit-message t) - file-name-handler-alist message-log-max signal-hook-function) + create-lockfiles file-name-handler-alist message-log-max + signal-hook-function) (with-current-buffer (tramp-get-debug-buffer vec) (goto-char (point-max)) (let ((point (point))) @@ -1982,6 +1983,13 @@ the resulting error message." (put #'tramp-with-demoted-errors 'tramp-suppress-trace t) +(defun tramp-test-message (fmt-string &rest arguments) + "Emit a Tramp message according `default-directory'." + (if (tramp-tramp-file-p default-directory) + (apply #'tramp-message + (tramp-dissect-file-name default-directory) 0 fmt-string arguments) + (apply #'message fmt-string arguments))) + ;; This function provides traces in case of errors not triggered by ;; Tramp functions. (defun tramp-signal-hook-function (error-symbol data) @@ -3741,7 +3749,9 @@ User is always nil." (let ((v (tramp-dissect-file-name default-directory)) (buffer (plist-get args :buffer)) (stderr (plist-get args :stderr))) - (and ;; It has been indicated. + (and ;; The method supports it. + (tramp-get-method-parameter v 'tramp-direct-async) + ;; It has been indicated. (tramp-get-connection-property v "direct-async-process" nil) ;; There's no multi-hop. (or (not (tramp-multi-hop-p v)) @@ -3821,8 +3831,6 @@ It does not support `:stderr'." (tramp-get-method-parameter v 'tramp-login-args)) (async-args (tramp-get-method-parameter v 'tramp-async-args)) - (direct-async-args - (tramp-get-method-parameter v 'tramp-direct-async-args)) ;; We don't create the temporary file. In fact, it ;; is just a prefix for the ControlPath option of ;; ssh; the real temporary file has another name, and @@ -3850,7 +3858,7 @@ It does not support `:stderr'." ?h (or host "") ?u (or user "") ?p (or port "") ?c options ?l "") ;; Add arguments for asynchronous processes. - login-args (append async-args direct-async-args login-args) + login-args (append async-args login-args) ;; Expand format spec. login-args (tramp-compat-flatten-tree diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el index 714b3f9bb0..ced3e93fc0 100644 --- a/lisp/net/trampver.el +++ b/lisp/net/trampver.el @@ -7,7 +7,7 @@ ;; Maintainer: Michael Albinus ;; Keywords: comm, processes ;; Package: tramp -;; Version: 2.5.0 +;; Version: 2.5.1-pre ;; Package-Requires: ((emacs "25.1")) ;; Package-Type: multi ;; URL: https://www.gnu.org/software/tramp/ @@ -40,7 +40,7 @@ ;; ./configure" to change them. ;;;###tramp-autoload -(defconst tramp-version "2.5.0" +(defconst tramp-version "2.5.1-pre" "This version of Tramp.") ;;;###tramp-autoload @@ -76,7 +76,7 @@ ;; Check for Emacs version. (let ((x (if (not (string-lessp emacs-version "25.1")) "ok" - (format "Tramp 2.5.0 is not fit for %s" + (format "Tramp 2.5.1-pre is not fit for %s" (replace-regexp-in-string "\n" "" (emacs-version)))))) (unless (string-equal "ok" x) (error "%s" x))) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 3995006898..ef0968a338 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -78,6 +78,8 @@ ;; Needed for Emacs 27. (defvar process-file-return-signal-string) (defvar shell-command-dont-erase-buffer) +;; Needed for Emacs 28. +(defvar dired-copy-dereference) ;; Beautify batch mode. (when noninteractive @@ -98,7 +100,6 @@ '("mock" (tramp-login-program "sh") (tramp-login-args (("-i"))) - (tramp-direct-async-args (("-c"))) (tramp-remote-shell "/bin/sh") (tramp-remote-shell-args ("-c")) (tramp-connection-timeout 10))) @@ -2438,7 +2439,7 @@ This checks also `file-name-as-directory', `file-name-directory', ;; We must check the last line. There could be ;; other messages from the progress reporter. (should - (string-match + (string-match-p (if (and (null noninteractive) (or (eq visit t) (null visit) (stringp visit))) (format "^Wrote %s\n\\'" (regexp-quote tmp-name)) @@ -2833,6 +2834,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'." (ert-deftest tramp-test15-copy-directory () "Check `copy-directory'." (skip-unless (tramp--test-enabled)) + (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil))) (let* ((tmp-name1 (tramp--test-make-temp-name nil quoted)) @@ -3612,8 +3614,8 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." `(condition-case err (progn ,@body) (file-error - (unless (string-match "^error with add-name-to-file" - (error-message-string err)) + (unless (string-match-p "^error with add-name-to-file" + (error-message-string err)) (signal (car err) (cdr err)))))) (ert-deftest tramp-test21-file-links () @@ -4388,7 +4390,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." ;; there's an indication for a signal describing string. (let ((process-file-return-signal-string t)) (should - (string-match + (string-match-p "Interrupt\\|Signal 2" (process-file (if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh") @@ -4456,7 +4458,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (with-timeout (10 (tramp--test-timeout-handler)) (while (< (- (point-max) (point-min)) (length "foo")) (while (accept-process-output proc 0 nil t)))) - (should (string-match "foo" (buffer-string)))) + (should (string-match-p "foo" (buffer-string)))) ;; Cleanup. (ignore-errors (delete-process proc))) @@ -4475,7 +4477,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (with-timeout (10 (tramp--test-timeout-handler)) (while (< (- (point-max) (point-min)) (length "foo")) (while (accept-process-output proc 0 nil t)))) - (should (string-match "foo" (buffer-string)))) + (should (string-match-p "foo" (buffer-string)))) ;; Cleanup. (ignore-errors @@ -4497,7 +4499,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (with-timeout (10 (tramp--test-timeout-handler)) (while (< (- (point-max) (point-min)) (length "foo")) (while (accept-process-output proc 0 nil t)))) - (should (string-match "foo" (buffer-string)))) + (should (string-match-p "foo" (buffer-string)))) ;; Cleanup. (ignore-errors (delete-process proc))) @@ -4539,8 +4541,6 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (cons '(nil "direct-async-process" t) tramp-connection-properties))) (skip-unless (tramp-direct-async-process-p)) - ;; For whatever reason, it doesn't cooperate with the "mock" method. - (skip-unless (not (tramp--test-mock-p))) ;; We do expect an established connection already, ;; `file-truename' does it by side-effect. Suppress ;; `tramp--test-enabled', in order to keep the connection. @@ -4586,7 +4586,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (with-timeout (10 (tramp--test-timeout-handler)) (while (< (- (point-max) (point-min)) (length "foo")) (while (accept-process-output proc 0 nil t)))) - (should (string-match "foo" (buffer-string)))) + (should (string-match-p "foo" (buffer-string)))) ;; Cleanup. (ignore-errors (delete-process proc))) @@ -4607,7 +4607,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (with-timeout (10 (tramp--test-timeout-handler)) (while (< (- (point-max) (point-min)) (length "foo")) (while (accept-process-output proc 0 nil t)))) - (should (string-match "foo" (buffer-string)))) + (should (string-match-p "foo" (buffer-string)))) ;; Cleanup. (ignore-errors @@ -4631,9 +4631,9 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (process-send-eof proc) ;; Read output. (with-timeout (10 (tramp--test-timeout-handler)) - (while (not (string-match "foo" (buffer-string))) + (while (not (string-match-p "foo" (buffer-string))) (while (accept-process-output proc 0 nil t)))) - (should (string-match "foo" (buffer-string)))) + (should (string-match-p "foo" (buffer-string)))) ;; Cleanup. (ignore-errors (delete-process proc))) @@ -4658,7 +4658,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (with-timeout (10 (tramp--test-timeout-handler)) (while (accept-process-output proc 0 nil t))) ;; On some MS Windows systems, it returns "unknown signal". - (should (string-match "unknown signal\\|killed" (buffer-string)))) + (should (string-match-p "unknown signal\\|killed" (buffer-string)))) ;; Cleanup. (ignore-errors (delete-process proc))) @@ -4682,7 +4682,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (delete-process proc) (with-current-buffer stderr (should - (string-match + (string-match-p "cat:.* No such file or directory" (buffer-string))))) ;; Cleanup. @@ -4709,7 +4709,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (with-temp-buffer (insert-file-contents tmpfile) (should - (string-match + (string-match-p "cat:.* No such file or directory" (buffer-string))))) ;; Cleanup. @@ -4852,7 +4852,7 @@ INPUT, if non-nil, is a string sent to the process." (should (string-equal ;; tramp-adb.el echoes, so we must add the string. - (if (tramp--test-adb-p) + (if (and (tramp--test-adb-p) (not (tramp-direct-async-process-p))) (format "%s\n%s\n" (file-name-nondirectory tmp-name) @@ -5043,7 +5043,7 @@ INPUT, if non-nil, is a string sent to the process." (cons (concat envvar "=foo") process-environment))) ;; Default value. (should - (string-match + (string-match-p "foo" (funcall this-shell-command-to-string @@ -5054,13 +5054,13 @@ INPUT, if non-nil, is a string sent to the process." (cons (concat envvar "=") process-environment))) ;; Value is null. (should - (string-match + (string-match-p "bla" (funcall this-shell-command-to-string (format "echo \"${%s:-bla}\"" envvar)))) ;; Variable is set. (should - (string-match + (string-match-p (regexp-quote envvar) (funcall this-shell-command-to-string "set")))) @@ -5072,7 +5072,7 @@ INPUT, if non-nil, is a string sent to the process." (cons (concat envvar "=foo") tramp-remote-process-environment))) ;; Set the initial value, we want to unset below. (should - (string-match + (string-match-p "foo" (funcall this-shell-command-to-string @@ -5080,14 +5080,14 @@ INPUT, if non-nil, is a string sent to the process." (let ((process-environment (cons envvar process-environment))) ;; Variable is unset. (should - (string-match + (string-match-p "bla" (funcall this-shell-command-to-string (format "echo \"${%s:-bla}\"" envvar)))) ;; Variable is unset. (should-not - (string-match + (string-match-p (regexp-quote envvar) ;; We must remove PS1, the output is truncated otherwise. (funcall @@ -5125,7 +5125,7 @@ Use direct async.") (format "%s=%d" envvar port) tramp-remote-process-environment))) (should - (string-match + (string-match-p (number-to-string port) (shell-command-to-string (format "echo $%s" envvar)))))) @@ -5253,7 +5253,7 @@ Use direct async.") (with-timeout (10) (while (accept-process-output (get-buffer-process (current-buffer)) nil nil t))) - (should (string-match "^foo$" (buffer-string))))) + (should (string-match-p "^foo$" (buffer-string))))) ;; Cleanup. (put 'explicit-shell-file-name 'permanent-local nil) @@ -5388,25 +5388,27 @@ Use direct async.") (tramp-remote-process-environment tramp-remote-process-environment) (inhibit-message t) (vc-handled-backends - (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil - (cond - ((tramp-find-executable - v vc-git-program (tramp-get-remote-path v)) - '(Git)) - ((tramp-find-executable - v vc-hg-program (tramp-get-remote-path v)) - '(Hg)) - ((tramp-find-executable - v vc-bzr-program (tramp-get-remote-path v)) - (setq tramp-remote-process-environment - (cons (format "BZR_HOME=%s" - (file-remote-p tmp-name1 'localname)) - tramp-remote-process-environment)) - ;; We must force a reconnect, in order to activate $BZR_HOME. - (tramp-cleanup-connection - tramp-test-vec 'keep-debug 'keep-password) - '(Bzr)) - (t nil)))) + (cond + ((tramp-find-executable + tramp-test-vec vc-git-program + (tramp-get-remote-path tramp-test-vec)) + '(Git)) + ((tramp-find-executable + tramp-test-vec vc-hg-program + (tramp-get-remote-path tramp-test-vec)) + '(Hg)) + ((tramp-find-executable + tramp-test-vec vc-bzr-program + (tramp-get-remote-path tramp-test-vec)) + (setq tramp-remote-process-environment + (cons (format "BZR_HOME=%s" + (file-remote-p tmp-name1 'localname)) + tramp-remote-process-environment)) + ;; We must force a reconnect, in order to activate $BZR_HOME. + (tramp-cleanup-connection + tramp-test-vec 'keep-debug 'keep-password) + '(Bzr)) + (t nil))) ;; Suppress nasty messages. (inhibit-message t)) (skip-unless vc-handled-backends) @@ -5732,7 +5734,7 @@ This does not support some special file names." "Check, whether an FTP-like method is used. This does not support globbing characters in file names (yet)." ;; Globbing characters are ??, ?* and ?\[. - (string-match + (string-match-p "ftp$" (file-remote-p tramp-test-temporary-file-directory 'method))) (defun tramp--test-gvfs-p (&optional method) @@ -5746,18 +5748,18 @@ If optional METHOD is given, it is checked first." "Check, whether the remote host runs HP-UX. Several special characters do not work properly there." ;; We must refill the cache. `file-truename' does it. - (with-parsed-tramp-file-name - (file-truename tramp-test-temporary-file-directory) nil - (string-match "^HP-UX" (tramp-get-connection-property v "uname" "")))) + (file-truename tramp-test-temporary-file-directory) nil + (string-match-p + "^HP-UX" (tramp-get-connection-property tramp-test-vec "uname" ""))) (defun tramp--test-ksh-p () "Check, whether the remote shell is ksh. ksh93 makes some strange conversions of non-latin characters into a $'' syntax." ;; We must refill the cache. `file-truename' does it. - (with-parsed-tramp-file-name - (file-truename tramp-test-temporary-file-directory) nil - (string-match "ksh$" (tramp-get-connection-property v "remote-shell" "")))) + (file-truename tramp-test-temporary-file-directory) nil + (string-match-p + "ksh$" (tramp-get-connection-property tramp-test-vec "remote-shell" ""))) (defun tramp--test-mock-p () "Check, whether the mock method is used. @@ -5809,7 +5811,7 @@ This does not support special characters." "Check, whether the locale host runs MS Windows, and ps{cp,ftp} is used. This does not support utf8 based file transfer." (and (eq system-type 'windows-nt) - (string-match + (string-match-p (regexp-opt '("pscp" "psftp")) (file-remote-p tramp-test-temporary-file-directory 'method)))) @@ -6072,6 +6074,7 @@ This requires restrictions of file name syntax." (skip-unless (tramp--test-enabled)) (skip-unless (not (tramp--test-rsync-p))) (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) + (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) (tramp--test-special-characters)) @@ -6083,6 +6086,8 @@ Use the `stat' command." (skip-unless (tramp--test-sh-p)) (skip-unless (not (tramp--test-rsync-p))) (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) + (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) + ;; We cannot use `tramp-test-vec', because this fails during compilation. (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil (skip-unless (tramp-get-remote-stat v))) @@ -6101,6 +6106,8 @@ Use the `perl' command." (skip-unless (tramp--test-sh-p)) (skip-unless (not (tramp--test-rsync-p))) (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) + (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) + ;; We cannot use `tramp-test-vec', because this fails during compilation. (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil (skip-unless (tramp-get-remote-perl v))) @@ -6123,6 +6130,7 @@ Use the `ls' command." (skip-unless (not (tramp--test-rsync-p))) (skip-unless (not (tramp--test-windows-nt-and-batch-p))) (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) + (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) (let ((tramp-connection-properties (append @@ -6191,6 +6199,7 @@ Use the `ls' command." (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) (skip-unless (not (tramp--test-ksh-p))) (skip-unless (not (tramp--test-crypt-p))) + (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) (tramp--test-utf8)) @@ -6206,6 +6215,8 @@ Use the `stat' command." (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) (skip-unless (not (tramp--test-ksh-p))) (skip-unless (not (tramp--test-crypt-p))) + (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) + ;; We cannot use `tramp-test-vec', because this fails during compilation. (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil (skip-unless (tramp-get-remote-stat v))) @@ -6228,6 +6239,8 @@ Use the `perl' command." (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) (skip-unless (not (tramp--test-ksh-p))) (skip-unless (not (tramp--test-crypt-p))) + (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) + ;; We cannot use `tramp-test-vec', because this fails during compilation. (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil (skip-unless (tramp-get-remote-perl v))) @@ -6253,6 +6266,7 @@ Use the `ls' command." (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) (skip-unless (not (tramp--test-ksh-p))) (skip-unless (not (tramp--test-crypt-p))) + (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) (let ((tramp-connection-properties (append @@ -6541,7 +6555,7 @@ process sentinels. They shall not disturb each other." (message \"Tramp loaded: %%s\" (and (file-remote-p %S) t)))" tramp-test-temporary-file-directory))) (should - (string-match + (string-match-p "Tramp loaded: t[\n\r]+" (shell-command-to-string (format @@ -6572,7 +6586,7 @@ process sentinels. They shall not disturb each other." ;; Tramp doesn't load when `tramp-mode' is nil. (dolist (tm '(t nil)) (should - (string-match + (string-match-p (format "Tramp loaded: nil[\n\r]+Tramp loaded: nil[\n\r]+Tramp loaded: %s[\n\r]+" tm) @@ -6598,7 +6612,7 @@ process sentinels. They shall not disturb each other." tramp-test-temporary-file-directory temporary-file-directory))) (should-not - (string-match + (string-match-p "Recursive load" (shell-command-to-string (format @@ -6623,7 +6637,7 @@ process sentinels. They shall not disturb each other." (load-path (cons \"/foo:bar:\" load-path))) \ (tramp-cleanup-all-connections))")) (should - (string-match + (string-match-p (format "Loading %s" (regexp-quote @@ -6670,11 +6684,11 @@ Since it unloads Tramp, it shall be the last test to run." (lambda (x) (and (or (and (boundp x) (null (local-variable-if-set-p x))) (and (functionp x) (null (autoloadp (symbol-function x))))) - (string-match "^tramp" (symbol-name x)) + (string-match-p "^tramp" (symbol-name x)) ;; `tramp-completion-mode' is autoloaded in Emacs < 28.1. (not (eq 'tramp-completion-mode x)) - (not (string-match "^tramp\\(-archive\\)?--?test" (symbol-name x))) - (not (string-match "unload-hook$" (symbol-name x))) + (not (string-match-p "^tramp\\(-archive\\)?--?test" (symbol-name x))) + (not (string-match-p "unload-hook$" (symbol-name x))) (ert-fail (format "`%s' still bound" x))))) ;; The defstruct `tramp-file-name' and all its internal functions ;; shall be purged. @@ -6682,15 +6696,15 @@ Since it unloads Tramp, it shall be the last test to run." (mapatoms (lambda (x) (and (functionp x) - (string-match "tramp-file-name" (symbol-name x)) + (string-match-p "tramp-file-name" (symbol-name x)) (ert-fail (format "Structure function `%s' still exists" x))))) ;; There shouldn't be left a hook function containing a Tramp ;; function. We do not regard the Tramp unload hooks. (mapatoms (lambda (x) (and (boundp x) - (string-match "-\\(hook\\|function\\)s?$" (symbol-name x)) - (not (string-match "unload-hook$" (symbol-name x))) + (string-match-p "-\\(hook\\|function\\)s?$" (symbol-name x)) + (not (string-match-p "unload-hook$" (symbol-name x))) (consp (symbol-value x)) (ignore-errors (all-completions "tramp" (symbol-value x))) (ert-fail (format "Hook `%s' still contains Tramp function" x)))))) commit 0a26f479152bbc3967f52d1d00efc663b58939b5 Author: Glenn Morris Date: Fri Jan 15 09:38:20 2021 +0000 * lisp/emacs-lisp/seq.el (seq-concatenate): Unautoload (merge fix). gitmerge-skip-regexp does not handle line breaks. diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 64d7e53375..31c15fea90 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -284,9 +284,6 @@ sorted. FUNCTION must be a function of one argument." (cl-defmethod seq-reverse ((sequence sequence)) (reverse sequence)) -;; We are autoloading seq-concatenate because cl-concatenate needs -;; that when it's inlined, per the cl-proclaim in cl-macs.el. -;;;###autoload (cl-defgeneric seq-concatenate (type &rest sequences) "Concatenate SEQUENCES into a single sequence of type TYPE. TYPE must be one of following symbols: vector, string or list. commit b4b98a044b4c40e78500d39e805427873b5e4bd7 Author: Eli Zaretskii Date: Fri Jan 15 10:12:09 2021 +0200 Fix 'kill-visual-line' * lisp/simple.el (kill-whole-line): Mention in the doc string that this option affects 'kill-visual-line' as well. (kill-visual-line): Improve the doc string. Delete the character at which the line was wrapped under 'visual-line-mode'. Don't indiscriminately delete whitespace following the wrap point. (Bug#45837) diff --git a/lisp/simple.el b/lisp/simple.el index 54c35c04be..37c0885dcc 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -5606,7 +5606,9 @@ See also `zap-up-to-char'." ;; kill-line and its subroutines. (defcustom kill-whole-line nil - "If non-nil, `kill-line' with no arg at start of line kills the whole line." + "If non-nil, `kill-line' with no arg at start of line kills the whole line. +This variable also affects `kill-visual-line' in the same way as +it does `kill-line'." :type 'boolean :group 'killing) @@ -7319,6 +7321,10 @@ If ARG is negative, kill visual lines backward. If ARG is zero, kill the text before point on the current visual line. +If the variable `kill-whole-line' is non-nil, and this command is +invoked at start of a line that ends in a newline, kill the newline +as well. + If you want to append the killed line to the last killed text, use \\[append-next-kill] before \\[kill-line]. @@ -7331,18 +7337,30 @@ even beep.)" ;; Like in `kill-line', it's better to move point to the other end ;; of the kill before killing. (let ((opoint (point)) - (kill-whole-line (and kill-whole-line (bolp)))) + (kill-whole-line (and kill-whole-line (bolp))) + (orig-y (cdr (nth 2 (posn-at-point)))) + ;; FIXME: This tolerance should be zero! It isn't due to a + ;; bug in posn-at-point, see bug#45837. + (tol (/ (line-pixel-height) 2))) (if arg (vertical-motion (prefix-numeric-value arg)) (end-of-visual-line 1) (if (= (point) opoint) (vertical-motion 1) - ;; Skip any trailing whitespace at the end of the visual line. - ;; We used to do this only if `show-trailing-whitespace' is - ;; nil, but that's wrong; the correct thing would be to check - ;; whether the trailing whitespace is highlighted. But, it's - ;; OK to just do this unconditionally. - (skip-chars-forward " \t"))) + ;; The first condition below verifies we are still on the same + ;; screen line, i.e. that the line isn't continued, and that + ;; end-of-visual-line didn't overshoot due to complications + ;; like display or overlay strings, intangible text, etc.: + ;; otherwise, we don't want to kill a character that's + ;; unrelated to the place where the visual line wrapped. + (and (< (abs (- (cdr (nth 2 (posn-at-point))) orig-y)) tol) + ;; Make sure we delete the character where the line wraps + ;; under visual-line-mode, be it whitespace or a + ;; character whose category set allows to wrap at it. + (or (looking-at-p "[ \t]") + (and word-wrap-by-category + (aref (char-category-set (following-char)) ?\|))) + (forward-char)))) (kill-region opoint (if (and kill-whole-line (= (following-char) ?\n)) (1+ (point)) (point))))) commit 65d22bf188438c6e16bd42056256f3d7e06c2e95 Author: Stefan Monnier Date: Thu Jan 14 17:37:57 2021 -0500 * lisp/startup.el (command-line): Remove redundant set of no-blinking-cursor This is redundant because this was set based on "X" resources under (memq window-system '(x w32 ns)) but the exact same resources and values are tested in `x-apply-session-resources` which is also used for those 3 window systems. diff --git a/lisp/startup.el b/lisp/startup.el index 932b3ffcd4..552802a38d 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -1297,15 +1297,6 @@ please check its value") (unless noninteractive (tool-bar-setup))) - ;; Turn off blinking cursor if so specified in X resources. This is here - ;; only because all other settings of no-blinking-cursor are here. - (unless (or noninteractive - emacs-basic-display - (and (memq window-system '(x w32 ns)) - (not (member (x-get-resource "cursorBlink" "CursorBlink") - '("no" "off" "false" "0"))))) - (setq no-blinking-cursor t)) - (unless noninteractive (startup--setup-quote-display) (setq internal--text-quoting-flag t)) commit 9422ff45654e07371d17d804131fafbf697b6e1e Author: Stefan Monnier Date: Thu Jan 14 17:21:56 2021 -0500 * lisp/startup.el (command-line): Remove redundant set of no-blinking-cursor This was set when (or noninteractive emacs-basic-display), but the code that sets `emacs-basic-display` also sets `no-blinking-cursor` and `blink-cursor-mode`s value already tests `noninteractive` alongside `no-blinking-cursor`. diff --git a/lisp/startup.el b/lisp/startup.el index 0ad5c2f179..932b3ffcd4 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -1288,8 +1288,7 @@ please check its value") (if (or noninteractive emacs-basic-display) (setq menu-bar-mode nil tab-bar-mode nil - tool-bar-mode nil - no-blinking-cursor t)) + tool-bar-mode nil)) (frame-initialize)) (when (fboundp 'x-create-frame) commit 5039f79340c408f26f9fb606ce29e72afc2fb01d Author: Stefan Monnier Date: Thu Jan 14 16:45:40 2021 -0500 Fix marking "delayed-initialization" vars as dynamically scoped We used to mark those vars as dynbound in `custom-reevaluate-setting` which forced us to bind `current-load-list` around it to avoid having the vars be associated with the wrong file. Move this marking to `custom-initialize-delay` so we don't need this workaround. * lisp/custom.el (custom-initialize-delay): Mark the var as dynamic. (custom-reevaluate-setting): Don't use `defvar` here. * lisp/startup.el (command-line): Don't let-bind `current-load-list` around calls to `custom-reevaluate-setting`. diff --git a/lisp/custom.el b/lisp/custom.el index 0c82df9b45..58ecd0439a 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -136,6 +136,9 @@ to include all of it." ; see eg vc-sccs-search-project-dir ;; No longer true: ;; "See `send-mail-function' in sendmail.el for an example." + ;; Defvar it so as to mark it special, etc (bug#25770). + (internal--define-uninitialized-variable symbol) + ;; Until the var is actually initialized, it is kept unbound. ;; This seemed to be at least as good as setting it to an arbitrary ;; value like nil (evaluating `value' is not an option because it @@ -780,8 +783,7 @@ Return non-nil if the `customized-value' property actually changed." Use the :set function to do so. This is useful for customizable options that are defined before their standard value can really be computed. E.g. dumped variables whose default depends on run-time information." - ;; If it has never been set at all, defvar it so as to mark it - ;; special, etc (bug#25770). This means we are initializing + ;; We are initializing ;; the variable, and normally any :set function would not apply. ;; For custom-initialize-delay, however, it is documented that "the ;; (delayed) initialization is performed with the :set function". @@ -789,11 +791,10 @@ E.g. dumped variables whose default depends on run-time information." ;; custom-initialize-delay but needs the :set function custom-set-minor-mode ;; to also run during initialization. So, long story short, we ;; always do the funcall step, even if symbol was not bound before. - (or (default-boundp symbol) - (eval `(defvar ,symbol nil))) ; reset below, so any value is fine (funcall (or (get symbol 'custom-set) #'set-default) symbol - (eval (car (or (get symbol 'saved-value) (get symbol 'standard-value)))))) + (eval (car (or (get symbol 'saved-value) + (get symbol 'standard-value)))))) ;;; Custom Themes diff --git a/lisp/startup.el b/lisp/startup.el index cc14fb2814..0ad5c2f179 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -1167,12 +1167,11 @@ please check its value") ;; Re-evaluate predefined variables whose initial value depends on ;; the runtime context. - (let (current-load-list) ; c-r-s may call defvar, and hence LOADHIST_ATTACH - (setq custom-delayed-init-variables - ;; Initialize them in the same order they were loaded, in case there - ;; are dependencies between them. - (nreverse custom-delayed-init-variables)) - (mapc 'custom-reevaluate-setting custom-delayed-init-variables)) + (setq custom-delayed-init-variables + ;; Initialize them in the same order they were loaded, in case there + ;; are dependencies between them. + (nreverse custom-delayed-init-variables)) + (mapc #'custom-reevaluate-setting custom-delayed-init-variables) ;; Warn for invalid user name. (when init-file-user @@ -1315,9 +1314,8 @@ please check its value") ;; Re-evaluate again the predefined variables whose initial value ;; depends on the runtime context, in case some of them depend on ;; the window-system features. Example: blink-cursor-mode. - (let (current-load-list) ; c-r-s may call defvar, and hence LOADHIST_ATTACH - (mapc 'custom-reevaluate-setting custom-delayed-init-variables) - (setq custom-delayed-init-variables nil)) + (mapc #'custom-reevaluate-setting custom-delayed-init-variables) + (setq custom-delayed-init-variables nil) (normal-erase-is-backspace-setup-frame) commit 53514e77a5a85b53ea0acd55f2ea5f1f78dc356c Author: Juri Linkov Date: Thu Jan 14 21:08:46 2021 +0200 * lisp/info.el (Info-search): Don't deactivate mark when landed in same node (bug#45839) diff --git a/lisp/info.el b/lisp/info.el index 62d7b583ff..dec93928b3 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -1973,7 +1973,6 @@ If DIRECTION is `backward', search in the reverse direction." "Regexp search%s" (car Info-search-history) (if case-fold-search "" " case-sensitively")) nil 'Info-search-history))) - (deactivate-mark) (when (equal regexp "") (setq regexp (car Info-search-history))) (when regexp @@ -2066,6 +2065,7 @@ If DIRECTION is `backward', search in the reverse direction." (< found opoint-max)) ;; Search landed in the same node (goto-char found) + (deactivate-mark) (widen) (goto-char found) (save-match-data (Info-select-node))) commit c83590b12114a0958c8e26846c87c84f492405bc Merge: 4ad332d844 488204cdc6 Author: Glenn Morris Date: Thu Jan 14 07:50:28 2021 -0800 Merge from origin/emacs-27 488204cdc6 (origin/emacs-27) Remove one of recently added warnings ab... 55bc1560ac Fix assertion failure in window_box_height (Bug#45737) 27743e9e70 Fix cl-concatenate inlining 32a3758c84 Fix infloop in 'pixel-scroll-mode' 74d18957b8 Fix inhibiting the default.el loading in user init file commit 4ad332d844b5b441c05c617304853e80a4714d51 Merge: 84372a710b 5d76288660 Author: Glenn Morris Date: Thu Jan 14 07:50:28 2021 -0800 ; Merge from origin/emacs-27 The following commit was skipped: 5d76288660 Fix problem with 8bit content-transfer-encoding in nndoc m... commit 84372a710b480e1dd3ec90ae4a57d22284fb71a2 Merge: 707ee6afe2 149d64bbb2 Author: Glenn Morris Date: Thu Jan 14 07:50:25 2021 -0800 Merge from origin/emacs-27 149d64bbb2 * doc/misc/tramp.texi (Quick Start Guide): Fix thinko. 97747e6fb9 Tell people how to remove fontconfig customizations 33d0c603c6 ; * doc/lispref/modes.texi (SMIE Indentation Example): Fix... 03080b5545 Remove extraneous closing paren commit 707ee6afe235e1b0f39900d8def0e770003de2db Author: Ted Zlatanov Date: Thu Jan 14 10:34:09 2021 +0000 EMBA infrastructure improvements for Emacs build testing. * .gitlab-ci.yml: Use job templates and rules. Split tests into fast/normal/slow. Make Docker images for each tested platform (inotify, filenotify-gio, gnustep). Increase timeout. * test/Makefile.in (check-lisp, check-net): Add new testing targets. * test/README: Document them. * test/file-organization.org: Mention test/infra. * test/infra/Dockerfile.emba: Add special Docker recipes for EMBA testing. diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bc18137a43..eb884767c9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,89 +24,141 @@ # Maintainer: Ted Zlatanov # URL: https://emba.gnu.org/emacs/emacs -image: debian:stretch +# Never run merge request pipelines, they usually duplicate push pipelines +# see https://docs.gitlab.com/ee/ci/yaml/README.html#common-if-clauses-for-rules +workflow: + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' + when: never + - when: always variables: GIT_STRATEGY: fetch EMACS_EMBA_CI: 1 -before_script: - - apt update -qq - - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y -qq -o=Dpkg::Use-Pty=0 libc-dev gcc g++ make autoconf automake libncurses-dev gnutls-dev git +default: + image: docker:19.03.12 + timeout: 3 hours + before_script: + - docker info -stages: - - test +.job-template: + # these will be cached across builds + cache: + key: ${CI_COMMIT_REF_SLUG} + paths: [] + policy: pull-push + # these will be saved for followup builds + artifacts: + expire_in: 24 hrs + paths: [] + # - "test/**/*.log" + # - "**/*.log" -test-all: - # This tests also file monitor libraries inotify and inotifywatch. - stage: test - only: - changes: - - "Makefile.in" - - .gitlab-ci.yml - - aclocal.m4 - - autogen.sh - - configure.ac - - lib/*.{h,c} - - lisp/*.el - - lisp/**/*.el - - src/*.{h,c} - - test/lisp/*.el - - test/lisp/**/*.el - - test/src/*.el - except: - changes: - # gfilemonitor, kqueue - - src/gfilenotify.c - - src/kqueue.c - # MS Windows - - lisp/w32*.el - - lisp/term/w32*.el - - src/w32*.{h,c} - # GNUstep - - lisp/term/ns-win.el - - src/ns*.{h,m} - - src/macfont.{h,m} +.test-template: + rules: + - changes: + - "**/Makefile.in" + - .gitlab-ci.yml + - aclocal.m4 + - autogen.sh + - configure.ac + - lib/*.{h,c} + - lisp/**/*.el + - src/*.{h,c} + - test/infra/* + - test/lisp/**/*.el + - test/src/*.el + - changes: + # gfilemonitor, kqueue + - src/gfilenotify.c + - src/kqueue.c + # MS Windows + - "**/w32*" + # GNUstep + - lisp/term/ns-win.el + - src/ns*.{h,m} + - src/macfont.{h,m} + when: never + + # using the variables for each job script: - - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y -qq -o=Dpkg::Use-Pty=0 inotify-tools - - ./autogen.sh autoconf - - ./configure --without-makeinfo - - make bootstrap - - make check-expensive + - docker build --target ${target} -t ${target}:${CI_COMMIT_REF_SLUG} -t ${target}:${CI_COMMIT_SHA} -f test/infra/Dockerfile.emba . + # TODO: with make -j4 several of the tests were failing, for example shadowfile-tests, but passed without it + - docker run -i --rm -e EMACS_EMBA_CI=${EMACS_EMBA_CI} ${target}:${CI_COMMIT_SHA} make ${make_params} + +stages: + - fast + - normal + - slow + +test-fast: + stage: fast + extends: [.job-template, .test-template] + variables: + target: emacs-inotify + make_params: "-C test check" + +test-lisp: + stage: normal + extends: [.job-template, .test-template] + variables: + target: emacs-inotify + make_params: "-C test check-lisp" + +test-net: + stage: normal + extends: [.job-template, .test-template] + variables: + target: emacs-inotify + make_params: "-C test check-net" test-filenotify-gio: - stage: test # This tests file monitor libraries gfilemonitor and gio. - only: - changes: - - .gitlab-ci.yml - - lisp/autorevert.el - - lisp/filenotify.el - - lisp/net/tramp-sh.el - - src/gfilenotify.c - - test/lisp/autorevert-tests.el - - test/lisp/filenotify-tests.el - script: - - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y -qq -o=Dpkg::Use-Pty=0 libglib2.0-dev libglib2.0-bin libglib2.0-0 - - ./autogen.sh autoconf - - ./configure --without-makeinfo --with-file-notification=gfile - - make bootstrap - - make -k -C test autorevert-tests filenotify-tests + stage: normal + extends: [.job-template, .test-template] + rules: + - if: '$CI_PIPELINE_SOURCE == "schedule"' + changes: + - "**/Makefile.in" + - .gitlab-ci.yml + - lisp/autorevert.el + - lisp/filenotify.el + - lisp/net/tramp-sh.el + - src/gfilenotify.c + - test/infra/* + - test/lisp/autorevert-tests.el + - test/lisp/filenotify-tests.el + variables: + target: emacs-filenotify-gio + make_params: "-k -C test autorevert-tests filenotify-tests" test-gnustep: - stage: test # This tests the GNUstep build process - only: - changes: - - .gitlab-ci.yml - - configure.ac - - src/ns*.{h,m} - - src/macfont.{h,m} - - lisp/term/ns-win.el - - nextstep/**/* - script: - - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y -qq -o=Dpkg::Use-Pty=0 gnustep-devel - - ./autogen.sh autoconf - - ./configure --without-makeinfo --with-ns - - make bootstrap - - make install + stage: normal + extends: [.job-template, .test-template] + rules: + - if: '$CI_PIPELINE_SOURCE == "schedule"' + changes: + - "**/Makefile.in" + - .gitlab-ci.yml + - configure.ac + - src/ns*.{h,m} + - src/macfont.{h,m} + - lisp/term/ns-win.el + - nextstep/**/* + - test/infra/* + variables: + target: emacs-gnustep + make_params: install + +test-all: + # This tests also file monitor libraries inotify and inotifywatch. + stage: slow + extends: [.job-template, .test-template] + rules: + # note there's no "changes" section, so this always runs on a schedule + - if: '$CI_PIPELINE_SOURCE == "schedule"' + variables: + target: emacs-inotify + make_params: check-expensive diff --git a/test/Makefile.in b/test/Makefile.in index fc40dad5e2..2d595d9bf1 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -246,6 +246,12 @@ endef $(foreach test,${TESTS},$(eval $(call test_template,${test}))) +# Get the tests for only a specific directory +NET_TESTS := $(patsubst %.el,%,$(wildcard lisp/net/*.el)) +LISP_TESTS := $(patsubst %.el,%,$(wildcard lisp/*.el)) +check-net: ${NET_TESTS} +check-lisp: ${LISP_TESTS} + ifeq (@HAVE_MODULES@, yes) # -fPIC is a no-op on Windows, but causes a compiler warning ifeq ($(SO),.dll) diff --git a/test/README b/test/README index ec566cb58d..38f4a10970 100644 --- a/test/README +++ b/test/README @@ -39,6 +39,12 @@ The Makefile in this directory supports the following targets: * make check-all Like "make check", but run all tests. +* make check-lisp + Like "make check", but run only the tests in test/lisp/*.el + +* make check-net + Like "make check", but run only the tests in test/lisp/net/*.el + * make -or- make .log Run all tests declared in .el. This includes expensive tests. In the former case the output is shown on the terminal, in diff --git a/test/file-organization.org b/test/file-organization.org index 64c0755b3b..efc354529c 100644 --- a/test/file-organization.org +++ b/test/file-organization.org @@ -57,3 +57,8 @@ directory called ~test/lisp/progmodes/flymake-resources~. No guidance is given for the organization of resource files inside the ~-resources~ directory; files can be organized at the author's discretion. + +** Testing Infrastructure Files + +Files used to support testing infrastructure such as EMBA should be +placed in ~infra~. diff --git a/test/infra/Dockerfile.emba b/test/infra/Dockerfile.emba new file mode 100644 index 0000000000..dd41982ad5 --- /dev/null +++ b/test/infra/Dockerfile.emba @@ -0,0 +1,71 @@ +# Copyright (C) 2021 Free Software Foundation, Inc. +# +# This file is part of GNU Emacs. +# +# GNU Emacs is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GNU Emacs is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Emacs. If not, see . + +# GNU Emacs support for the GitLab-specific build of Docker images. + +# The presence of this file does not imply any FSF/GNU endorsement of +# Docker or any other particular tool. Also, it is intended for +# evaluation purposes, thus possibly temporary. + +# Maintainer: Ted Zlatanov +# URL: https://emba.gnu.org/emacs/emacs + +FROM debian:stretch as emacs-base + +RUN apt-get update && \ + apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 \ + libc-dev gcc g++ make autoconf automake libncurses-dev gnutls-dev git \ + && rm -rf /var/lib/apt/lists/* + +FROM emacs-base as emacs-inotify + +RUN apt-get update && \ + apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 inotify-tools \ + && rm -rf /var/lib/apt/lists/* + +COPY . /checkout +WORKDIR /checkout +RUN ./autogen.sh autoconf +RUN ./configure --without-makeinfo +RUN make bootstrap +RUN make -j4 + +FROM emacs-base as emacs-filenotify-gio + +RUN apt-get update && \ + apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 libglib2.0-dev libglib2.0-bin libglib2.0-0 \ + && rm -rf /var/lib/apt/lists/* + +COPY . /checkout +WORKDIR /checkout +RUN ./autogen.sh autoconf +RUN ./configure --without-makeinfo --with-file-notification=gfile +RUN make bootstrap +RUN make -j4 + +FROM emacs-base as emacs-gnustep + +RUN apt-get update && \ + apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 gnustep-devel \ + && rm -rf /var/lib/apt/lists/* + +COPY . /checkout +WORKDIR /checkout +RUN ./autogen.sh autoconf +RUN ./configure --without-makeinfo --with-ns +RUN make bootstrap +RUN make -j4 commit 488204cdc64b6a130042ecc64d59c4538287b81d Author: Juri Linkov Date: Wed Jan 13 20:32:36 2021 +0200 Remove one of recently added warnings abound binding keys in Isearch maps * lisp/isearch.el (minibuffer-local-isearch-map): Remove comments which warn against wantonly rebinding unbound keys from irrelevant keymap. https://lists.gnu.org/archive/html/emacs-devel/2021-01/msg00259.html diff --git a/lisp/isearch.el b/lisp/isearch.el index cbe72efb80..8320847893 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -823,10 +823,6 @@ This is like `describe-bindings', but displays only Isearch keys." :image '(isearch-tool-bar-image "left-arrow"))) map)) -;; Note: Before adding more key bindings to this map, please keep in -;; mind that any unbound key exits Isearch and runs the command bound -;; to it in the local or global map. So in effect every key unbound -;; in this map is implicitly bound. (defvar minibuffer-local-isearch-map (let ((map (make-sparse-keymap))) (set-keymap-parent map minibuffer-local-map) commit ebab8898cad35b07c703c62d62dcd2aebd51d637 Author: Juri Linkov Date: Wed Jan 13 20:19:22 2021 +0200 * lisp/isearch.el: C-s C-u M-y reads a string from the kill-ring minibuffer * lisp/isearch.el (isearch-yank-from-kill-ring): New command with code moved from isearch-yank-pop. (isearch-yank-pop): Use isearch-yank-from-kill-ring. (isearch-yank-pop-only): Add optional arg, and call isearch-yank-from-kill-ring when the prefix arg is C-u. https://lists.gnu.org/archive/html/emacs-devel/2021-01/msg00089.html diff --git a/lisp/isearch.el b/lisp/isearch.el index 67cc7bed15..602643f8ae 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -2498,6 +2498,21 @@ If search string is empty, just beep." (unless isearch-mode (isearch-mode t)) (isearch-yank-string (current-kill 0))) +(defun isearch-yank-from-kill-ring () + "Read a string from the `kill-ring' and append it to the search string." + (interactive) + (with-isearch-suspended + (let ((string (read-from-kill-ring))) + (if (and isearch-case-fold-search + (eq 'not-yanks search-upper-case)) + (setq string (downcase string))) + (if isearch-regexp (setq string (regexp-quote string))) + (setq isearch-yank-flag t) + (setq isearch-new-string (concat isearch-string string) + isearch-new-message (concat isearch-message + (mapconcat 'isearch-text-char-description + string "")))))) + (defun isearch-yank-pop () "Replace just-yanked search string with previously killed string. Unlike `isearch-yank-pop-only', when this command is called not immediately @@ -2506,37 +2521,31 @@ minibuffer to read a string from the `kill-ring' as `yank-pop' does." (interactive) (if (not (memq last-command '(isearch-yank-kill isearch-yank-pop isearch-yank-pop-only))) - ;; Yank string from kill-ring-browser. - (with-isearch-suspended - (let ((string (read-from-kill-ring))) - (if (and isearch-case-fold-search - (eq 'not-yanks search-upper-case)) - (setq string (downcase string))) - (if isearch-regexp (setq string (regexp-quote string))) - (setq isearch-yank-flag t) - (setq isearch-new-string (concat isearch-string string) - isearch-new-message (concat isearch-message - (mapconcat 'isearch-text-char-description - string ""))))) + (isearch-yank-from-kill-ring) (isearch-pop-state) (isearch-yank-string (current-kill 1)))) -(defun isearch-yank-pop-only () +(defun isearch-yank-pop-only (&optional arg) "Replace just-yanked search string with previously killed string. Unlike `isearch-yank-pop', when this command is called not immediately after a `isearch-yank-kill' or a `isearch-yank-pop-only', it only pops the last killed string instead of activating the minibuffer to read -a string from the `kill-ring' as `yank-pop' does." - (interactive) - (if (not (memq last-command '(isearch-yank-kill - isearch-yank-pop isearch-yank-pop-only))) - ;; Fall back on `isearch-yank-kill' for the benefits of people - ;; who are used to the old behavior of `M-y' in isearch mode. - ;; In future, `M-y' could be changed from `isearch-yank-pop-only' - ;; to `isearch-yank-pop' that uses the kill-ring-browser. - (isearch-yank-kill) +a string from the `kill-ring' as `yank-pop' does. The prefix arg C-u +always reads a string from the `kill-ring' using the minibuffer." + (interactive "P") + (cond + ((equal arg '(4)) + (isearch-yank-from-kill-ring)) + ((not (memq last-command '(isearch-yank-kill + isearch-yank-pop isearch-yank-pop-only))) + ;; Fall back on `isearch-yank-kill' for the benefits of people + ;; who are used to the old behavior of `M-y' in isearch mode. + ;; In future, `M-y' could be changed from `isearch-yank-pop-only' + ;; to `isearch-yank-pop' that uses the kill-ring-browser. + (isearch-yank-kill)) + (t (isearch-pop-state) - (isearch-yank-string (current-kill 1)))) + (isearch-yank-string (current-kill 1))))) (defun isearch-yank-x-selection () "Pull current X selection into search string." commit a9658cd5b07e88a5d413cbb4dfd8f9d9d0c8bbf5 Author: Stefan Kangas Date: Wed Jan 13 18:54:09 2021 +0100 Lift {global,local}-key-binding to Lisp * lisp/subr.el (local-key-binding, global-key-binding): New defuns. * src/keymap.c (Flocal_key_binding, Fglobal_key_binding): Remove DEFUNs. (syms_of_keymap): Remove defsubrs for above DEFUNs. * test/lisp/subr-tests.el (subr-test-local-key-binding) (subr-test-global-key-binding): New tests. diff --git a/lisp/subr.el b/lisp/subr.el index 6d3ea45c1a..9b89e49370 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1178,6 +1178,30 @@ KEY is a string or vector representing a sequence of keystrokes." (if (current-local-map) (local-set-key key nil)) nil) + +(defun local-key-binding (keys &optional accept-default) + "Return the binding for command KEYS in current local keymap only. +KEYS is a string or vector, a sequence of keystrokes. +The binding is probably a symbol with a function definition. + +If optional argument ACCEPT-DEFAULT is non-nil, recognize default +bindings; see the description of `lookup-key' for more details +about this." + (let ((map (current-local-map))) + (when map (lookup-key map keys accept-default)))) + +(defun global-key-binding (keys &optional accept-default) + "Return the binding for command KEYS in current global keymap only. +KEYS is a string or vector, a sequence of keystrokes. +The binding is probably a symbol with a function definition. +This function's return values are the same as those of `lookup-key' +\(which see). + +If optional argument ACCEPT-DEFAULT is non-nil, recognize default +bindings; see the description of `lookup-key' for more details +about this." + (lookup-key (current-global-map) keys accept-default)) + ;;;; substitute-key-definition and its subroutines. diff --git a/src/keymap.c b/src/keymap.c index 1197f6fd4a..de9b2b58c5 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -1646,39 +1646,6 @@ specified buffer position instead of point are used. /* GC is possible in this function if it autoloads a keymap. */ -DEFUN ("local-key-binding", Flocal_key_binding, Slocal_key_binding, 1, 2, 0, - doc: /* Return the binding for command KEYS in current local keymap only. -KEYS is a string or vector, a sequence of keystrokes. -The binding is probably a symbol with a function definition. - -If optional argument ACCEPT-DEFAULT is non-nil, recognize default -bindings; see the description of `lookup-key' for more details about this. */) - (Lisp_Object keys, Lisp_Object accept_default) -{ - register Lisp_Object map = BVAR (current_buffer, keymap); - if (NILP (map)) - return Qnil; - return Flookup_key (map, keys, accept_default); -} - -/* GC is possible in this function if it autoloads a keymap. */ - -DEFUN ("global-key-binding", Fglobal_key_binding, Sglobal_key_binding, 1, 2, 0, - doc: /* Return the binding for command KEYS in current global keymap only. -KEYS is a string or vector, a sequence of keystrokes. -The binding is probably a symbol with a function definition. -This function's return values are the same as those of `lookup-key' -\(which see). - -If optional argument ACCEPT-DEFAULT is non-nil, recognize default -bindings; see the description of `lookup-key' for more details about this. */) - (Lisp_Object keys, Lisp_Object accept_default) -{ - return Flookup_key (current_global_map, keys, accept_default); -} - -/* GC is possible in this function if it autoloads a keymap. */ - DEFUN ("minor-mode-key-binding", Fminor_mode_key_binding, Sminor_mode_key_binding, 1, 2, 0, doc: /* Find the visible minor mode bindings of KEY. Return an alist of pairs (MODENAME . BINDING), where MODENAME is @@ -3253,8 +3220,6 @@ be preferred. */); defsubr (&Scopy_keymap); defsubr (&Scommand_remapping); defsubr (&Skey_binding); - defsubr (&Slocal_key_binding); - defsubr (&Sglobal_key_binding); defsubr (&Sminor_mode_key_binding); defsubr (&Sdefine_key); defsubr (&Slookup_key); diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index e0826208b6..fc5a1eba6d 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -87,6 +87,17 @@ ;; Returns the symbol. (should (eq (define-prefix-command 'foo-bar) 'foo-bar))) +(ert-deftest subr-test-local-key-binding () + (with-temp-buffer + (emacs-lisp-mode) + (should (keymapp (local-key-binding [menu-bar]))) + (should-not (local-key-binding [f12])))) + +(ert-deftest subr-test-global-key-binding () + (should (eq (global-key-binding [f1]) 'help-command)) + (should (eq (global-key-binding "x") 'self-insert-command)) + (should-not (global-key-binding [f12]))) + ;;;; Mode hooks. commit be9b7e83bc4191aff01c692be0f7a156ec4056da Author: Stefan Kangas Date: Wed Jan 13 17:39:53 2021 +0100 Prefer skip-unless in more tests * test/lisp/emacs-lisp/timer-tests.el (timer-tests-debug-timer-check): * test/src/decompress-tests.el (zlib--decompress): * test/src/xml-tests.el (libxml-tests): Prefer skip-unless. diff --git a/test/lisp/emacs-lisp/timer-tests.el b/test/lisp/emacs-lisp/timer-tests.el index 74da33eff6..7856c217f9 100644 --- a/test/lisp/emacs-lisp/timer-tests.el +++ b/test/lisp/emacs-lisp/timer-tests.el @@ -36,8 +36,8 @@ (ert-deftest timer-tests-debug-timer-check () ;; This function exists only if --enable-checking. - (if (fboundp 'debug-timer-check) - (should (debug-timer-check)) t)) + (skip-unless (fboundp 'debug-timer-check)) + (should (debug-timer-check))) (ert-deftest timer-test-multiple-of-time () (should (time-equal-p diff --git a/test/src/decompress-tests.el b/test/src/decompress-tests.el index 67a7fefb05..520445cca5 100644 --- a/test/src/decompress-tests.el +++ b/test/src/decompress-tests.el @@ -29,16 +29,16 @@ (ert-deftest zlib--decompress () "Test decompressing a gzipped file." - (when (and (fboundp 'zlib-available-p) - (zlib-available-p)) - (should (string= - (with-temp-buffer - (set-buffer-multibyte nil) - (insert-file-contents-literally - (expand-file-name "foo.gz" zlib-tests-data-directory)) - (zlib-decompress-region (point-min) (point-max)) - (buffer-string)) - "foo\n")))) + (skip-unless (and (fboundp 'zlib-available-p) + (zlib-available-p))) + (should (string= + (with-temp-buffer + (set-buffer-multibyte nil) + (insert-file-contents-literally + (expand-file-name "foo.gz" zlib-tests-data-directory)) + (zlib-decompress-region (point-min) (point-max)) + (buffer-string)) + "foo\n"))) (provide 'decompress-tests) diff --git a/test/src/xml-tests.el b/test/src/xml-tests.el index 632cf965fa..a35b4d2ccc 100644 --- a/test/src/xml-tests.el +++ b/test/src/xml-tests.el @@ -44,12 +44,12 @@ (ert-deftest libxml-tests () "Test libxml." - (when (fboundp 'libxml-parse-xml-region) - (with-temp-buffer - (dolist (test libxml-tests--data-comments-preserved) - (erase-buffer) - (insert (car test)) - (should (equal (cdr test) - (libxml-parse-xml-region (point-min) (point-max)))))))) + (skip-unless (fboundp 'libxml-parse-xml-region)) + (with-temp-buffer + (dolist (test libxml-tests--data-comments-preserved) + (erase-buffer) + (insert (car test)) + (should (equal (cdr test) + (libxml-parse-xml-region (point-min) (point-max))))))) ;;; libxml-tests.el ends here commit 19b169c4e22abe5112d36ff4740f382409f6acdf Author: Eli Zaretskii Date: Wed Jan 13 16:45:31 2021 +0200 Fix 'visual-line-mode' when 'word-wrap-by-category' is in effect * src/xdisp.c (move_it_in_display_line_to): Don't reset next_may_wrap after saving a potential wrap point. This fixes the case where several characters in a row can serve as a wrap point. (Bug#45837) diff --git a/src/xdisp.c b/src/xdisp.c index 6a4304d194..64f401690a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -9285,8 +9285,8 @@ move_it_in_display_line_to (struct it *it, if (may_wrap && char_can_wrap_before (it)) { /* We have reached a glyph that follows one or more - whitespace characters or a character that allows - wrapping after it. If this character allows + whitespace characters or characters that allow + wrapping after them. If this character allows wrapping before it, save this position as a wrapping point. */ if (atpos_it.sp >= 0) @@ -9303,7 +9303,6 @@ move_it_in_display_line_to (struct it *it, } /* Otherwise, we can wrap here. */ SAVE_IT (wrap_it, *it, wrap_data); - next_may_wrap = false; } /* Update may_wrap for the next iteration. */ may_wrap = next_may_wrap; commit aeb11da203d011d4331e1e09ec7c2e98584afcb8 Author: Stefan Kangas Date: Wed Jan 13 15:23:31 2021 +0100 Use skip-unless instead of if+message in test * test/lisp/cedet/semantic-utest.el (semantic-utest-Javascript): Use skip-unless instead of if+message. diff --git a/test/lisp/cedet/semantic-utest.el b/test/lisp/cedet/semantic-utest.el index c0099386f1..67de4a5b02 100644 --- a/test/lisp/cedet/semantic-utest.el +++ b/test/lisp/cedet/semantic-utest.el @@ -577,10 +577,8 @@ INSERTME is the text to be inserted after the deletion." (ert-deftest semantic-utest-Javascript() - (if (fboundp 'javascript-mode) - (semantic-utest-generic (semantic-utest-fname "javascripttest.js") semantic-utest-Javascript-buffer-contents semantic-utest-Javascript-name-contents '("fun2") "//1" "//deleted line") - (message "Skipping JavaScript test: NO major mode.")) - ) + (skip-unless (fboundp 'javascript-mode)) + (semantic-utest-generic (semantic-utest-fname "javascripttest.js") semantic-utest-Javascript-buffer-contents semantic-utest-Javascript-name-contents '("fun2") "//1" "//deleted line")) (ert-deftest semantic-utest-Java() ;; If JDE is installed, it might mess things up depending on the version commit 118d6ef554e9e821925578d6ca6f3fd3d4cba780 Author: Stefan Kangas Date: Wed Jan 13 15:17:44 2021 +0100 Remove some XEmacs compat code from tests * test/lisp/cedet/srecode-utest-getset.el (srecode-utest-getset-output): * test/lisp/cedet/srecode-utest-template.el (srecode-utest-template-output): Remove XEmacs compat code. diff --git a/test/lisp/cedet/srecode-utest-getset.el b/test/lisp/cedet/srecode-utest-getset.el index 0497dea505..1c6578038c 100644 --- a/test/lisp/cedet/srecode-utest-getset.el +++ b/test/lisp/cedet/srecode-utest-getset.el @@ -128,7 +128,6 @@ private: (srecode-utest-getset-jumptotag "miscFunction")) (let ((pos (point))) - (skip-chars-backward " \t\n") ; xemacs forward-comment is different. (forward-comment -1) (re-search-forward "miscFunction" pos)) diff --git a/test/lisp/cedet/srecode-utest-template.el b/test/lisp/cedet/srecode-utest-template.el index 57d8a64805..f97ff18320 100644 --- a/test/lisp/cedet/srecode-utest-template.el +++ b/test/lisp/cedet/srecode-utest-template.el @@ -307,13 +307,9 @@ INSIDE SECTION: ARG HANDLER ONE") (should (srecode-table major-mode)) ;; Loop over the output testpoints. - (dolist (p srecode-utest-output-entries) - (set-buffer testbuff) ;; XEmacs causes a buffer switch. I don't know why - (should-not (srecode-utest-test p)) - ) + (should-not (srecode-utest-test p))))) - )) (when (file-exists-p srecode-utest-testfile) (delete-file srecode-utest-testfile))) commit 6d467eb4d153c703c11f329b01720b8a436511fd Author: Stefan Kangas Date: Wed Jan 13 15:12:08 2021 +0100 * lisp/calc/calc.el: Remove some XEmacs compat code. diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el index 68ae468589..d684c7ba97 100644 --- a/lisp/calc/calc.el +++ b/lisp/calc/calc.el @@ -1095,15 +1095,7 @@ Used by `calc-user-invocation'.") (ignore-errors (define-key calc-digit-map x 'calcDigit-delchar) (define-key calc-mode-map x 'calc-pop) - (define-key calc-mode-map - (if (and (vectorp x) (featurep 'xemacs)) - (if (= (length x) 1) - (vector (if (consp (aref x 0)) - (cons 'meta (aref x 0)) - (list 'meta (aref x 0)))) - "\e\C-d") - (vconcat "\e" x)) - 'calc-pop-above))) + (define-key calc-mode-map (vconcat "\e" x) 'calc-pop-above))) (if calc-scan-for-dels (append (where-is-internal 'delete-forward-char global-map) '("\C-d")) commit 820bd0e09a913e0bc9e1fc9fe007f6a653be2808 Author: Mattias Engdegård Date: Wed Jan 13 14:16:57 2021 +0100 Stabilise lunar-phase-list test (bug#45818) The test reference data was produced with accidental interference from the system daylight saving in effect at the time. Prevent that from occurring again and correct the data. * test/lisp/calendar/lunar-tests.el (with-lunar-test): Switch to UTC and make sure daylight saving adjustment is disabled. Use normal time presentation for maintainability. * test/lisp/calendar/lunar-tests.el (lunar-test-phase): Adjust to UTC. (lunar-test-phase-list): Adjust to UTC with correct times. Enable the test by removing its :unstable mark. diff --git a/test/lisp/calendar/lunar-tests.el b/test/lisp/calendar/lunar-tests.el index 5f1f6782f1..268dcfdb55 100644 --- a/test/lisp/calendar/lunar-tests.el +++ b/test/lisp/calendar/lunar-tests.el @@ -27,39 +27,37 @@ (defmacro with-lunar-test (&rest body) `(let ((calendar-latitude 40.1) (calendar-longitude -88.2) - (calendar-location-name "Urbana, IL") - (calendar-time-zone -360) - (calendar-standard-time-zone-name "CST") - (calendar-time-display-form '(12-hours ":" minutes am-pm))) + (calendar-location-name "Paris") + (calendar-time-zone 0) + (calendar-standard-time-zone-name "UTC") + ;; Make sure daylight saving is disabled to avoid interference + ;; from the system settings (see bug#45818). + (calendar-daylight-savings-starts nil) + (calendar-time-display-form '(24-hours ":" minutes))) ,@body)) (ert-deftest lunar-test-phase () (with-lunar-test (should (equal (lunar-phase 1) - '((1 7 1900) "11:40pm" 1 ""))))) + '((1 8 1900) "05:40" 1 ""))))) (ert-deftest lunar-test-eclipse-check () (with-lunar-test (should (equal (eclipse-check 1 1) "** Eclipse **")))) -;; This fails in certain time zones. -;; Eg TZ=America/Phoenix make lisp/calendar/lunar-tests -;; Similarly with TZ=UTC. -;; Daylight saving related? (ert-deftest lunar-test-phase-list () - :tags '(:unstable) (with-lunar-test (should (equal (lunar-phase-list 3 1871) - '(((3 20 1871) "11:03pm" 0 "") - ((3 29 1871) "1:46am" 1 "** Eclipse **") - ((4 5 1871) "9:20am" 2 "") - ((4 12 1871) "12:57am" 3 "** Eclipse possible **") - ((4 19 1871) "2:06pm" 0 "") - ((4 27 1871) "6:49pm" 1 "") - ((5 4 1871) "5:57pm" 2 "") - ((5 11 1871) "9:29am" 3 "") - ((5 19 1871) "5:46am" 0 "") - ((5 27 1871) "8:02am" 1 "")))))) + '(((3 21 1871) "04:03" 0 "") + ((3 29 1871) "06:46" 1 "** Eclipse **") + ((4 5 1871) "14:20" 2 "") + ((4 12 1871) "05:57" 3 "** Eclipse possible **") + ((4 19 1871) "19:06" 0 "") + ((4 27 1871) "23:49" 1 "") + ((5 4 1871) "22:57" 2 "") + ((5 11 1871) "14:29" 3 "") + ((5 19 1871) "10:46" 0 "") + ((5 27 1871) "13:02" 1 "")))))) (ert-deftest lunar-test-new-moon-time () (with-lunar-test commit c734ba68623279d814e857ddc536421a08c38f34 Author: Mattias Engdegård Date: Tue Jan 12 21:38:47 2021 +0100 Fix Indian time zone test when run by Irishmen (bug#45818) * test/lisp/calendar/solar-tests.el (solar-sunrise-sunset): Inhibit any attempt by confused calendar code to apply daylight saving correction when Irish time zone settings are in effect. It's not entirely clear why this is needed but may be related to the fact that 'IST' stands for both Irish and Indian Standard Time, and that Ireland uses reversed daylight saving in winter. diff --git a/test/lisp/calendar/solar-tests.el b/test/lisp/calendar/solar-tests.el index 7a37f8db55..337deb8ce9 100644 --- a/test/lisp/calendar/solar-tests.el +++ b/test/lisp/calendar/solar-tests.el @@ -26,7 +26,9 @@ (calendar-longitude 75.8) (calendar-time-zone +330) (calendar-standard-time-zone-name "IST") - (calendar-daylight-time-zone-name "IST") + ;; Make sure our clockwork isn't confused by daylight saving rules + ;; in effect for any other time zone (bug#45818). + (calendar-daylight-savings-starts nil) (epsilon (/ 60.0))) ; Minute accuracy is good enough. (let* ((sunrise-sunset (solar-sunrise-sunset '(12 30 2020))) (sunrise (car (nth 0 sunrise-sunset))) commit d93de0b4121f03d19ef6bd985ed383f359577cb8 Author: Arash Esbati Date: Tue Jan 12 17:18:24 2021 +0100 ; Update docstring * lisp/textmodes/reftex-vars.el (reftex-label-regexps): Track the latest addition of "frame" environment. diff --git a/lisp/textmodes/reftex-vars.el b/lisp/textmodes/reftex-vars.el index d4c1b87262..1b29eafabf 100644 --- a/lisp/textmodes/reftex-vars.el +++ b/lisp/textmodes/reftex-vars.el @@ -900,7 +900,7 @@ DOWNCASE t: Downcase words before using them." ,(concat ;; Make sure we search only for optional arguments of ;; environments/macros and don't match any other [. ctable - ;; provides a macro called \ctable, listings/breqn have + ;; provides a macro called \ctable, beamer/breqn/listings have ;; environments. Start with a backslash and a group for names "\\\\\\(?:" ;; begin, optional spaces and opening brace @@ -936,8 +936,9 @@ The default value matches usual \\label{...} definitions and keyval style [..., label = {...}, ...] label definitions. The regexp for keyval style explicitly looks for environments provided by the packages \"listings\" (\"lstlisting\"), -\"breqn\" (\"dmath\", \"dseries\", \"dgroup\", \"darray\") and -the macro \"\\ctable\" provided by the package of the same name. +\"beamer\" (\"frame\"), \"breqn\" (\"dmath\", \"dseries\", +\"dgroup\", \"darray\") and the macro \"\\ctable\" provided by +the package of the same name. It is assumed that the regexp group 1 matches the label text, so you have to define it using \\(?1:...\\) when adding new regexps. commit 0f6c083251ccc727d0b18a62cdd99901aa692c78 Author: Robert Pluim Date: Tue Jan 12 18:50:38 2021 +0100 Only run IPv6 tests if we have an IPv6 address * test/src/process-tests.el (ipv6-is-available): New function for checking whether we have a globally routable IPv6 prefix assigned. (lookup-family-specification): Use 'ipv6-is-available' to check for IPv6. Use 'localhost' instead of 'google.com' to test 'network-lookup-address-info' API. (lookup-google): Use 'ipv6-is-available' to check for IPv6. * test/lisp/net/nsm-tests.el (nsm-ipv6-is-available): Rename to 'ipv6-is-available', make identical to the one in test/src/process-tests.el. diff --git a/test/lisp/net/nsm-tests.el b/test/lisp/net/nsm-tests.el index 88c30c2039..ff453319b3 100644 --- a/test/lisp/net/nsm-tests.el +++ b/test/lisp/net/nsm-tests.el @@ -49,15 +49,17 @@ (should (eq nil (nsm-should-check "127.0.0.1"))) (should (eq nil (nsm-should-check "localhost")))))) -(defun nsm-ipv6-is-available () +;; This will need updating when IANA assign more IPv6 global ranges. +(defun ipv6-is-available () (and (featurep 'make-network-process '(:family ipv6)) (cl-rassoc-if (lambda (elt) - (eq 9 (length elt))) + (and (eq 9 (length elt)) + (= (logand (aref elt 0) #xe000) #x2000))) (network-interface-list)))) (ert-deftest nsm-check-local-subnet-ipv6 () - (skip-unless (nsm-ipv6-is-available)) + (skip-unless (ipv6-is-available)) (let ((local-ip '[123 456 789 11 172 26 128 160 0]) (mask '[255 255 255 255 255 255 255 0 0]) diff --git a/test/src/process-tests.el b/test/src/process-tests.el index 921bcd5f85..57097cfa05 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -28,6 +28,7 @@ (require 'puny) (require 'rx) (require 'subr-x) +(require 'dns) ;; Timeout in seconds; the test fails if the timeout is reached. (defvar process-test-sentinel-wait-timeout 2.0) @@ -350,14 +351,23 @@ See Bug#30460." ;; All the following tests require working DNS, which appears not to ;; be the case for hydra.nixos.org, so disable them there for now. +;; This will need updating when IANA assign more IPv6 global ranges. +(defun ipv6-is-available () + (and (featurep 'make-network-process '(:family ipv6)) + (cl-rassoc-if + (lambda (elt) + (and (eq 9 (length elt)) + (= (logand (aref elt 0) #xe000) #x2000))) + (network-interface-list)))) + (ert-deftest lookup-family-specification () "`network-lookup-address-info' should only accept valid family symbols." (skip-unless (not (getenv "EMACS_HYDRA_CI"))) (with-timeout (60 (ert-fail "Test timed out")) - (should-error (network-lookup-address-info "google.com" 'both)) - (should (network-lookup-address-info "google.com" 'ipv4)) - (when (featurep 'make-network-process '(:family ipv6)) - (should (network-lookup-address-info "google.com" 'ipv6))))) + (should-error (network-lookup-address-info "localhost" 'both)) + (should (network-lookup-address-info "localhost" 'ipv4)) + (when (ipv6-is-available) + (should (network-lookup-address-info "localhost" 'ipv6))))) (ert-deftest lookup-unicode-domains () "Unicode domains should fail." @@ -380,7 +390,8 @@ See Bug#30460." (addresses-v4 (network-lookup-address-info "google.com" 'ipv4))) (should addresses-both) (should addresses-v4)) - (when (featurep 'make-network-process '(:family ipv6)) + (when (and (ipv6-is-available) + (dns-query "google.com" 'AAAA)) (should (network-lookup-address-info "google.com" 'ipv6))))) (ert-deftest non-existent-lookup-failure () commit 6dc4fc7d621008086388dae48f6794f7d69edff9 Author: Robert Pluim Date: Tue Jan 12 18:36:01 2021 +0100 Fix nsm-should-check for "google.com" failure * lisp/net/nsm.el (nsm-should-check): Extract the mask from 'network-interface-list' rather than the broadcast address (Bug#45798). diff --git a/lisp/net/nsm.el b/lisp/net/nsm.el index 3f3e713371..0ce65a35ea 100644 --- a/lisp/net/nsm.el +++ b/lisp/net/nsm.el @@ -239,7 +239,7 @@ otherwise." (mapc (lambda (info) (let ((local-ip (nth 1 info)) - (mask (nth 2 info))) + (mask (nth 3 info))) (when (nsm-network-same-subnet (substring local-ip 0 -1) (substring mask 0 -1) commit 792ba7196ff1171f44571d9ba9b88b96d5be85ad Author: Lars Ingebrigtsen Date: Tue Jan 12 18:43:53 2021 +0100 Add a new function 'buffer-line-statistics' * src/fns.c (Fbuffer_line_statistics): New function. diff --git a/etc/NEWS b/etc/NEWS index f2aa158d9d..fc7dcbcf4c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1537,6 +1537,9 @@ that makes it a valid button. ** Miscellaneous +*** New function 'buffer-line-statistics'. +This function returns some statistics about the line lengths in a buffer. + +++ *** New variable 'inhibit-interaction' to make user prompts signal an error. If this is bound to something non-nil, functions like diff --git a/src/fns.c b/src/fns.c index 5fcc54f0d1..7ab2e8f1a0 100644 --- a/src/fns.c +++ b/src/fns.c @@ -5548,6 +5548,90 @@ It should not be used for anything security-related. See return make_digest_string (digest, SHA1_DIGEST_SIZE); } +DEFUN ("buffer-line-statistics", Fbuffer_line_statistics, + Sbuffer_line_statistics, 0, 1, 0, + doc: /* Return data about lines in BUFFER. +The data is returned as a list, and the first element is the number of +lines in the buffer, the second is the length of the longest line, and +the third is the mean line length. The lengths returned are in bytes, not +characters. */ ) + (Lisp_Object buffer_or_name) +{ + Lisp_Object buffer; + ptrdiff_t lines = 0, longest = 0; + double mean = 0; + struct buffer *b; + + if (NILP (buffer_or_name)) + buffer = Fcurrent_buffer (); + else + buffer = Fget_buffer (buffer_or_name); + if (NILP (buffer)) + nsberror (buffer_or_name); + + b = XBUFFER (buffer); + + unsigned char *start = BUF_BEG_ADDR (b); + ptrdiff_t area = BUF_GPT_BYTE (b) - BUF_BEG_BYTE (b), pre_gap = 0; + + /* Process the first part of the buffer. */ + while (area > 0) + { + unsigned char *n = memchr (start, '\n', area); + + if (n) + { + ptrdiff_t this_line = n - start; + if (this_line > longest) + longest = this_line; + lines++; + /* Blame Knuth. */ + mean = mean + (this_line - mean) / lines; + area = area - this_line - 1; + start += this_line + 1; + } + else + { + /* Didn't have a newline here, so save the rest for the + post-gap calculation. */ + pre_gap = area; + area = 0; + } + } + + /* If the gap is before the end of the buffer, process the last half + of the buffer. */ + if (BUF_GPT_BYTE (b) < BUF_Z_BYTE (b)) + { + start = BUF_GAP_END_ADDR (b); + area = BUF_Z_ADDR (b) - BUF_GAP_END_ADDR (b); + + while (area > 0) + { + unsigned char *n = memchr (start, '\n', area); + ptrdiff_t this_line = n? n - start + pre_gap: area + pre_gap; + + if (this_line > longest) + longest = this_line; + lines++; + /* Blame Knuth again. */ + mean = mean + (this_line - mean) / lines; + area = area - this_line - 1; + start += this_line + 1; + pre_gap = 0; + } + } + else if (pre_gap > 0) + { + if (pre_gap > longest) + longest = pre_gap; + lines++; + mean = mean + (pre_gap - mean) / lines; + } + + return list3 (make_int (lines), make_int (longest), make_float (mean)); +} + static bool string_ascii_p (Lisp_Object string) { @@ -5871,4 +5955,5 @@ this variable. */); defsubr (&Ssecure_hash); defsubr (&Sbuffer_hash); defsubr (&Slocale_info); + defsubr (&Sbuffer_line_statistics); } diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el index a9daf878b8..e0aed2a71b 100644 --- a/test/src/fns-tests.el +++ b/test/src/fns-tests.el @@ -1040,3 +1040,61 @@ (let ((list (list 1))) (setcdr list list) (length< list #x1fffe)))) + +(defun approx-equal (list1 list2) + (and (equal (length list1) (length list2)) + (cl-loop for v1 in list1 + for v2 in list2 + when (not (or (= v1 v2) + (< (abs (- v1 v2)) 0.1))) + return nil + finally return t))) + +(ert-deftest test-buffer-line-stats-nogap () + (with-temp-buffer + (insert "") + (should (approx-equal (buffer-line-statistics) '(0 0 0)))) + (with-temp-buffer + (insert "123\n") + (should (approx-equal (buffer-line-statistics) '(1 3 3)))) + (with-temp-buffer + (insert "123\n12345\n123\n") + (should (approx-equal (buffer-line-statistics) '(3 5 3.66)))) + (with-temp-buffer + (insert "123\n12345\n123") + (should (approx-equal (buffer-line-statistics) '(3 5 3.66)))) + (with-temp-buffer + (insert "123\n12345") + (should (approx-equal (buffer-line-statistics) '(2 5 4)))) + + (with-temp-buffer + (insert "123\n12é45\n123\n") + (should (approx-equal (buffer-line-statistics) '(3 6 4)))) + + (with-temp-buffer + (insert "\n\n\n") + (should (approx-equal (buffer-line-statistics) '(3 0 0))))) + +(ert-deftest test-buffer-line-stats-gap () + (with-temp-buffer + (dotimes (_ 1000) + (insert "12345678901234567890123456789012345678901234567890\n")) + (goto-char (point-min)) + ;; This should make a gap appear. + (insert "123\n") + (delete-region (point-min) (point)) + (should (approx-equal (buffer-line-statistics) '(1000 50 50.0)))) + (with-temp-buffer + (dotimes (_ 1000) + (insert "12345678901234567890123456789012345678901234567890\n")) + (goto-char (point-min)) + (insert "123\n") + (should (approx-equal (buffer-line-statistics) '(1001 50 49.9)))) + (with-temp-buffer + (dotimes (_ 1000) + (insert "12345678901234567890123456789012345678901234567890\n")) + (goto-char (point-min)) + (insert "123\n") + (goto-char (point-max)) + (insert "fóo") + (should (approx-equal (buffer-line-statistics) '(1002 50 49.9))))) commit ca024b0575c4ea754c4c6e6dbf21ed610e0d1fb8 Author: Lars Ingebrigtsen Date: Tue Jan 12 15:12:28 2021 +0100 Add a new variable `inhibit-interaction' * doc/lispref/elisp.texi (Top): Add a link. * doc/lispref/errors.texi (Standard Errors): Mention the new error. * doc/lispref/minibuf.texi (Minibuffers): Add a link. (Inhibiting Interaction): New node. * src/data.c (syms_of_data): Define the `inhibited-interaction' error. * src/lisp.h: Export the barfing function. * src/lread.c (Fread_char, Fread_event, Fread_char_exclusive): Barf if inhibited. * src/minibuf.c (barf_if_interaction_inhibited): New function. (Fread_from_minibuffer, Fread_no_blanks_input): Barf if inhibited. (syms_of_minibuf): Define the `inhibit-interaction' variable. diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi index fa548b503a..12255d122f 100644 --- a/doc/lispref/elisp.texi +++ b/doc/lispref/elisp.texi @@ -739,6 +739,7 @@ Minibuffers * Minibuffer Windows:: Operating on the special minibuffer windows. * Minibuffer Contents:: How such commands access the minibuffer text. * Recursive Mini:: Whether recursive entry to minibuffer is allowed. +* Inhibiting Interaction:: Running Emacs when no interaction is possible. * Minibuffer Misc:: Various customization hooks and variables. Completion diff --git a/doc/lispref/errors.texi b/doc/lispref/errors.texi index 9ec1271499..fb393b951f 100644 --- a/doc/lispref/errors.texi +++ b/doc/lispref/errors.texi @@ -230,6 +230,11 @@ The message is @samp{Wrong type argument}. @xref{Type Predicates}. @item unknown-image-type The message is @samp{Cannot determine image type}. @xref{Images}. + +@item inhibited-interaction +The message is @samp{User interaction while inhibited}. This error is +signalled when @code{inhibit-interaction} is non-@code{nil} and a user +interaction function (like @code{read-from-minibuffer}) is called. @end table @ignore The following seem to be unused now. diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index d316c1f060..0ce17ed571 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -32,6 +32,7 @@ argument. * Minibuffer Windows:: Operating on the special minibuffer windows. * Minibuffer Contents:: How such commands access the minibuffer text. * Recursive Mini:: Whether recursive entry to minibuffer is allowed. +* Inhibiting Interaction:: Running Emacs when no interaction is possible. * Minibuffer Misc:: Various customization hooks and variables. @end menu @@ -2617,6 +2618,38 @@ to @code{t} in the interactive declaration (@pxref{Using Interactive}). The minibuffer command @code{next-matching-history-element} (normally @kbd{M-s} in the minibuffer) does the latter. +@node Inhibiting Interaction +@section Inhibiting Interaction + +It's sometimes useful to be able to run Emacs as a headless server +process that responds to commands given over a network connection. +However, Emacs is primarily a platform for interactive usage, so many +commands prompt the user for feedback in certain anomalous situations. +This makes this use case more difficult, since the server process will +just hang waiting for user input. + +@vindex inhibit-interaction +Binding the @code{inhibit-interaction} variable to something +non-@code{nil} makes Emacs signal a @code{inhibited-interaction} error +instead of prompting, which can then be used by the server process to +handle these situations. + +Here's a typical use case: + +@lisp +(let ((inhibit-interaction t)) + (respond-to-client + (condition-case err + (my-client-handling-function) + (inhibited-interaction err)))) +@end lisp + +If @code{my-client-handling-function} ends up calling something that +asks the user for something (via @code{y-or-n-p} or +@code{read-from-minibuffer} or the like), an +@code{inhibited-interaction} error is signalled instead. The server +code then catches that error and reports it to the client. + @node Minibuffer Misc @section Minibuffer Miscellany diff --git a/etc/NEWS b/etc/NEWS index 28dffef73a..f2aa158d9d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1537,6 +1537,12 @@ that makes it a valid button. ** Miscellaneous ++++ +*** New variable 'inhibit-interaction' to make user prompts signal an error. +If this is bound to something non-nil, functions like +`read-from-minibuffer', `read-char' (and related) will signal an +`inhibited-interaction' error. + --- *** 'process-attributes' now works under OpenBSD, too. diff --git a/src/data.c b/src/data.c index d420bf5fc5..35a6890b9b 100644 --- a/src/data.c +++ b/src/data.c @@ -3760,6 +3760,7 @@ syms_of_data (void) DEFSYM (Qbuffer_read_only, "buffer-read-only"); DEFSYM (Qtext_read_only, "text-read-only"); DEFSYM (Qmark_inactive, "mark-inactive"); + DEFSYM (Qinhibited_interaction, "inhibited-interaction"); DEFSYM (Qlistp, "listp"); DEFSYM (Qconsp, "consp"); @@ -3844,6 +3845,8 @@ syms_of_data (void) PUT_ERROR (Qbuffer_read_only, error_tail, "Buffer is read-only"); PUT_ERROR (Qtext_read_only, pure_cons (Qbuffer_read_only, error_tail), "Text is read-only"); + PUT_ERROR (Qinhibited_interaction, error_tail, + "User interaction while inhibited"); DEFSYM (Qrange_error, "range-error"); DEFSYM (Qdomain_error, "domain-error"); diff --git a/src/lisp.h b/src/lisp.h index 9d8dbbd629..f658868544 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4351,6 +4351,7 @@ extern EMACS_INT minibuf_level; extern Lisp_Object get_minibuffer (EMACS_INT); extern void init_minibuf_once (void); extern void syms_of_minibuf (void); +extern void barf_if_interaction_inhibited (void); /* Defined in callint.c. */ diff --git a/src/lread.c b/src/lread.c index 1ff0828e85..4b168fb84b 100644 --- a/src/lread.c +++ b/src/lread.c @@ -767,11 +767,16 @@ is used for reading a character. If the optional argument SECONDS is non-nil, it should be a number specifying the maximum number of seconds to wait for input. If no input arrives in that time, return nil. SECONDS may be a -floating-point value. */) +floating-point value. + +If `inhibit-interaction' is non-nil, this function will signal an +`inhibited-interaction' error. */) (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) { Lisp_Object val; + barf_if_interaction_inhibited (); + if (! NILP (prompt)) message_with_string ("%s", prompt, 0); val = read_filtered_event (1, 1, 1, ! NILP (inherit_input_method), seconds); @@ -793,9 +798,14 @@ is used for reading a character. If the optional argument SECONDS is non-nil, it should be a number specifying the maximum number of seconds to wait for input. If no input arrives in that time, return nil. SECONDS may be a -floating-point value. */) +floating-point value. + +If `inhibit-interaction' is non-nil, this function will signal an +`inhibited-interaction' error. */) (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) { + barf_if_interaction_inhibited (); + if (! NILP (prompt)) message_with_string ("%s", prompt, 0); return read_filtered_event (0, 0, 0, ! NILP (inherit_input_method), seconds); @@ -822,11 +832,16 @@ is used for reading a character. If the optional argument SECONDS is non-nil, it should be a number specifying the maximum number of seconds to wait for input. If no input arrives in that time, return nil. SECONDS may be a -floating-point value. */) - (Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) +floating-point value. + +If `inhibit-interaction' is non-nil, this function will signal an +`inhibited-interaction' error. */) +(Lisp_Object prompt, Lisp_Object inherit_input_method, Lisp_Object seconds) { Lisp_Object val; + barf_if_interaction_inhibited (); + if (! NILP (prompt)) message_with_string ("%s", prompt, 0); diff --git a/src/minibuf.c b/src/minibuf.c index 868e481f84..5df1045373 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -1075,6 +1075,13 @@ read_minibuf_unwind (void) } +void +barf_if_interaction_inhibited (void) +{ + if (inhibit_interaction) + xsignal0 (Qinhibited_interaction); +} + DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, 7, 0, doc: /* Read a string from the minibuffer, prompting with string PROMPT. @@ -1119,6 +1126,9 @@ If the variable `minibuffer-allow-text-properties' is non-nil, then the string which is returned includes whatever text properties were present in the minibuffer. Otherwise the value has no text properties. +If `inhibit-interaction' is non-nil, this function will signal an + `inhibited-interaction' error. + The remainder of this documentation string describes the INITIAL-CONTENTS argument in more detail. It is only relevant when studying existing code, or when HIST is a cons. If non-nil, @@ -1134,6 +1144,8 @@ and some related functions, which use zero-indexing for POSITION. */) { Lisp_Object histvar, histpos, val; + barf_if_interaction_inhibited (); + CHECK_STRING (prompt); if (NILP (keymap)) keymap = Vminibuffer_local_map; @@ -1207,11 +1219,17 @@ point positioned at the end, so that SPACE will accept the input. \(Actually, INITIAL can also be a cons of a string and an integer. Such values are treated as in `read-from-minibuffer', but are normally not useful in this function.) + Third arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits -the current input method and the setting of`enable-multibyte-characters'. */) +the current input method and the setting of`enable-multibyte-characters'. + +If `inhibit-interaction' is non-nil, this function will signal an +`inhibited-interaction' error. */) (Lisp_Object prompt, Lisp_Object initial, Lisp_Object inherit_input_method) { CHECK_STRING (prompt); + barf_if_interaction_inhibited (); + return read_minibuf (Vminibuffer_local_ns_map, initial, prompt, 0, Qminibuffer_history, make_fixnum (0), Qnil, 0, !NILP (inherit_input_method)); @@ -2321,6 +2339,15 @@ This variable also overrides the default character that `read-passwd' uses to hide passwords. */); Vread_hide_char = Qnil; + DEFVAR_BOOL ("inhibit-interaction", + inhibit_interaction, + doc: /* Non-nil means any user interaction will signal an error. +This variable can be bound when user interaction can't be performed, +for instance when running a headless Emacs server. Functions like +`read-from-minibuffer' (and the like) will signal `inhibited-interaction' +instead. */); + inhibit_interaction = 0; + defsubr (&Sactive_minibuffer_window); defsubr (&Sset_minibuffer_window); defsubr (&Sread_from_minibuffer); diff --git a/test/src/lread-tests.el b/test/src/lread-tests.el index edf88214f9..f2a60bcf32 100644 --- a/test/src/lread-tests.el +++ b/test/src/lread-tests.el @@ -190,4 +190,10 @@ literals (Bug#20852)." (ert-deftest lread-circular-hash () (should-error (read "#s(hash-table data #0=(#0# . #0#))"))) +(ert-deftest test-inhibit-interaction () + (let ((inhibit-interaction t)) + (should-error (read-char "foo: ")) + (should-error (read-event "foo: ")) + (should-error (read-char-exclusive "foo: ")))) + ;;; lread-tests.el ends here diff --git a/test/src/minibuf-tests.el b/test/src/minibuf-tests.el index b9cd255462..28119fc999 100644 --- a/test/src/minibuf-tests.el +++ b/test/src/minibuf-tests.el @@ -410,5 +410,20 @@ (should (equal (try-completion "baz" '("bAz" "baz")) (try-completion "baz" '("baz" "bAz")))))) +(ert-deftest test-inhibit-interaction () + (let ((inhibit-interaction t)) + (should-error (read-from-minibuffer "foo: ")) + + (should-error (y-or-n-p "foo: ")) + (should-error (yes-or-no-p "foo: ")) + (should-error (read-blanks-no-input "foo: ")) + + ;; See that we get the expected error. + (should (eq (condition-case nil + (read-from-minibuffer "foo: ") + (inhibited-interaction 'inhibit) + (error nil)) + 'inhibit)))) + ;;; minibuf-tests.el ends here commit d191f1589b6d06221a58c8c4e6a6441b0a2a2e49 Author: Glenn Morris Date: Tue Jan 12 05:41:13 2021 -0800 Update substitute-command-keys tests, again * test/lisp/help-tests.el (help-tests-substitute-command-keys/keymaps) (help-tests-substitute-command-keys/keymap-change): Update following recent minibuffer changes. diff --git a/test/lisp/help-tests.el b/test/lisp/help-tests.el index 835d9fe794..8034764741 100644 --- a/test/lisp/help-tests.el +++ b/test/lisp/help-tests.el @@ -95,7 +95,7 @@ key binding --- ------- -C-g abort-recursive-edit +C-g abort-minibuffers TAB minibuffer-complete C-j minibuffer-complete-and-exit RET minibuffer-complete-and-exit @@ -122,7 +122,7 @@ M-s next-matching-history-element (ert-deftest help-tests-substitute-command-keys/keymap-change () (with-substitute-command-keys-test - (test "\\\\[abort-recursive-edit]" "C-g") + (test "\\\\[abort-recursive-edit]" "C-]") (test "\\\\[eval-defun]" "C-M-x"))) (defvar help-tests-remap-map commit 78ef0a72fa57c05c4be1401b2304c106a02c257d Author: Brian Leung Date: Tue Jan 12 13:29:03 2021 +0100 comint-read-input-ring: Simplify last commit * lisp/comint.el (comint-read-input-ring): It is not necessary to use `goto-char' again since we have already moved point to the desired location (bug#45797). diff --git a/lisp/comint.el b/lisp/comint.el index 3476fd146c..53153af7d2 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -1000,7 +1000,6 @@ See also `comint-input-ignoredups' and `comint-write-input-ring'." (goto-char (match-end 0))) (setq start (point)) (setq history (buffer-substring start end)) - (goto-char start) (when (and (not (string-match history-ignore history)) (or (null ignoredups) (ring-empty-p ring) commit d8936322f43c88bb1cdebe1a50a7cc7eb0efe834 Author: Stefan Monnier Date: Mon Jan 11 16:44:39 2021 -0500 * lisp/emacs-lisp/eieio-base.el: Silence warnings in last change (eieio-persistent-make-instance): Quote the `eieio-named` class name. (eieio-named): Move before `eieio-persistent`. diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el index 19809265ff..ec1077d447 100644 --- a/lisp/emacs-lisp/eieio-base.el +++ b/lisp/emacs-lisp/eieio-base.el @@ -162,6 +162,59 @@ only one object ever exists." old))) +;;; Named object + +(defclass eieio-named () + ((object-name :initarg :object-name :initform nil)) + "Object with a name." + :abstract t) + +(cl-defmethod eieio-object-name-string ((obj eieio-named)) + "Return a string which is OBJ's name." + (or (slot-value obj 'object-name) + (cl-call-next-method))) + +(cl-defgeneric eieio-object-set-name-string (obj name) + "Set the string which is OBJ's NAME." + (declare (obsolete "inherit from `eieio-named' and use (setf (slot-value OBJ \\='object-name) NAME) instead" "25.1")) + (cl-check-type name string) + (setf (gethash obj eieio--object-names) name)) +(define-obsolete-function-alias + 'object-set-name-string 'eieio-object-set-name-string "24.4") + +(with-suppressed-warnings ((obsolete eieio-object-set-name-string)) + (cl-defmethod eieio-object-set-name-string ((obj eieio-named) name) + "Set the string which is OBJ's NAME." + (cl-check-type name string) + (eieio-oset obj 'object-name name))) + +(cl-defmethod clone ((obj eieio-named) &rest params) + "Clone OBJ, initializing `:parent' to OBJ. +All slots are unbound, except those initialized with PARAMS." + (let* ((newname (and (stringp (car params)) (pop params))) + (nobj (apply #'cl-call-next-method obj params)) + (nm (slot-value nobj 'object-name))) + (eieio-oset nobj 'object-name + (or newname + (if (equal nm (slot-value obj 'object-name)) + (save-match-data + (if (and nm (string-match "-\\([0-9]+\\)" nm)) + (let ((num (1+ (string-to-number + (match-string 1 nm))))) + (concat (substring nm 0 (match-beginning 0)) + "-" (int-to-string num))) + (concat nm "-1"))) + nm))) + nobj)) + +(cl-defmethod make-instance ((class (subclass eieio-named)) &rest args) + (if (not (stringp (car args))) + (cl-call-next-method) + (funcall (if eieio-backward-compatibility #'ignore #'message) + "Obsolete: name passed without :object-name to %S constructor" + class) + (apply #'cl-call-next-method class :object-name args))) + ;;; eieio-persistent ;; ;; For objects which must save themselves to disk. Provides an @@ -296,7 +349,7 @@ objects found there." ;; Check for special case of subclass of `eieio-named', and do ;; name assignment. (when (and eieio-backward-compatibility - (object-of-class-p newobj eieio-named) + (object-of-class-p newobj 'eieio-named) (not (oref newobj object-name)) name) (oset newobj object-name name)) @@ -423,59 +476,6 @@ instance." ;; It should also set up some hooks to help it keep itself up to date. -;;; Named object - -(defclass eieio-named () - ((object-name :initarg :object-name :initform nil)) - "Object with a name." - :abstract t) - -(cl-defmethod eieio-object-name-string ((obj eieio-named)) - "Return a string which is OBJ's name." - (or (slot-value obj 'object-name) - (cl-call-next-method))) - -(cl-defgeneric eieio-object-set-name-string (obj name) - "Set the string which is OBJ's NAME." - (declare (obsolete "inherit from `eieio-named' and use (setf (slot-value OBJ \\='object-name) NAME) instead" "25.1")) - (cl-check-type name string) - (setf (gethash obj eieio--object-names) name)) -(define-obsolete-function-alias - 'object-set-name-string 'eieio-object-set-name-string "24.4") - -(with-suppressed-warnings ((obsolete eieio-object-set-name-string)) - (cl-defmethod eieio-object-set-name-string ((obj eieio-named) name) - "Set the string which is OBJ's NAME." - (cl-check-type name string) - (eieio-oset obj 'object-name name))) - -(cl-defmethod clone ((obj eieio-named) &rest params) - "Clone OBJ, initializing `:parent' to OBJ. -All slots are unbound, except those initialized with PARAMS." - (let* ((newname (and (stringp (car params)) (pop params))) - (nobj (apply #'cl-call-next-method obj params)) - (nm (slot-value nobj 'object-name))) - (eieio-oset nobj 'object-name - (or newname - (if (equal nm (slot-value obj 'object-name)) - (save-match-data - (if (and nm (string-match "-\\([0-9]+\\)" nm)) - (let ((num (1+ (string-to-number - (match-string 1 nm))))) - (concat (substring nm 0 (match-beginning 0)) - "-" (int-to-string num))) - (concat nm "-1"))) - nm))) - nobj)) - -(cl-defmethod make-instance ((class (subclass eieio-named)) &rest args) - (if (not (stringp (car args))) - (cl-call-next-method) - (funcall (if eieio-backward-compatibility #'ignore #'message) - "Obsolete: name passed without :object-name to %S constructor" - class) - (apply #'cl-call-next-method class :object-name args))) - (provide 'eieio-base) commit bb4399f647f0977fe560283351b325d2816cd129 Author: Eric Ludlam Date: Sun Jan 10 10:37:50 2021 -0500 cedet/ede/auto.el: (ede-calc-fromconfig): New method. Support functions in addition to string matchers. (ede-dirmatch-installed, ede-do-dirmatch): Use `ede-calc-fromconfig' to do conversion. Author: Eric Ludlam diff --git a/lisp/cedet/ede/auto.el b/lisp/cedet/ede/auto.el index ee75e29799..e1417d7806 100644 --- a/lisp/cedet/ede/auto.el +++ b/lisp/cedet/ede/auto.el @@ -64,24 +64,22 @@ location is varied dependent on other complex criteria, this class can be used to define that match without loading the specific project into memory.") +(cl-defmethod ede-calc-fromconfig ((dirmatch ede-project-autoload-dirmatch)) + "Calculate the value of :fromconfig from DIRMATCH." + (let* ((fc (oref dirmatch fromconfig)) + (found (cond ((stringp fc) fc) + ((functionp fc) (funcall fc)) + (t (error "Unknown dirmatch object match style."))))) + (expand-file-name found) + )) + (cl-defmethod ede-dirmatch-installed ((dirmatch ede-project-autoload-dirmatch)) "Return non-nil if the tool DIRMATCH might match is installed on the system." - (let ((fc (oref dirmatch fromconfig))) - - (cond - ;; If the thing to match is stored in a config file. - ((stringp fc) - (file-exists-p fc)) - - ;; Add new types of dirmatches here. - - ;; Error for weird stuff - (t (error "Unknown dirmatch type."))))) - + (file-exists-p (ede-calc-fromconfig dirmatch))) (cl-defmethod ede-do-dirmatch ((dirmatch ede-project-autoload-dirmatch) file) "Does DIRMATCH match the filename FILE." - (let ((fc (oref dirmatch fromconfig))) + (let ((fc (ede-calc-fromconfig dirmatch))) (cond ;; If the thing to match is stored in a config file. commit 002f9dc091ecaabbed38917a13748dd0d893fffd Author: Eric Ludlam Date: Sun Jan 10 10:54:49 2021 -0500 eieio-base.el: (eieio-persistent-make-instance): Save the backward compatible 'name' of objects saved in the file, and if the newly loaded class inherits from 'eieio-named', restore the name of the object. Author: Eric Ludlam diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el index 4ba72aea56..19809265ff 100644 --- a/lisp/emacs-lisp/eieio-base.el +++ b/lisp/emacs-lisp/eieio-base.el @@ -264,12 +264,17 @@ objects found there." (:method ((objclass (subclass eieio-default-superclass)) inputlist) - (let ((slots (if (stringp (car inputlist)) - ;; Earlier versions of `object-write' added a - ;; string name for the object, now obsolete. - (cdr inputlist) - inputlist)) - (createslots nil)) + (let* ((name nil) + (slots (if (stringp (car inputlist)) + (progn + ;; Earlier versions of `object-write' added a + ;; string name for the object, now obsolete. + ;; Save as 'name' in case this object is subclass + ;; of eieio-named with no :object-name slot specified. + (setq name (car inputlist)) + (cdr inputlist)) + inputlist)) + (createslots nil)) ;; If OBJCLASS is an eieio autoload object, then we need to ;; load it (we don't need the return value). (eieio--full-class-object objclass) @@ -286,7 +291,17 @@ objects found there." (setq slots (cdr (cdr slots)))) - (apply #'make-instance objclass (nreverse createslots))))) + (let ((newobj (apply #'make-instance objclass (nreverse createslots)))) + + ;; Check for special case of subclass of `eieio-named', and do + ;; name assignment. + (when (and eieio-backward-compatibility + (object-of-class-p newobj eieio-named) + (not (oref newobj object-name)) + name) + (oset newobj object-name name)) + + newobj)))) (defun eieio-persistent-fix-value (proposed-value) "Fix PROPOSED-VALUE. commit fcf8ad610d43ba9b96d9ad1cc67185144c819006 Author: Eric Abrahamsen Date: Mon Jan 11 09:46:58 2021 -0800 Fix possible prepending of "TEXT" to IMAP searches * lisp/gnus/gnus-search.el (gnus-search-imap-search-keys): Add missing keys "old", "new", "or" and "not". (gnus-search-run-search): In addition, don't touch the query if it starts with a parenthesis. Consider just getting rid of this convenience altogether. diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el index 44f43b073c..5c6a5b9efd 100644 --- a/lisp/gnus/gnus-search.el +++ b/lisp/gnus/gnus-search.el @@ -1036,7 +1036,7 @@ Responsible for handling and, or, and parenthetical expressions.") '(body cc bcc from header keyword larger smaller subject text to uid x-gm-raw answered before deleted draft flagged on since recent seen sentbefore senton sentsince unanswered undeleted undraft unflagged unkeyword - unseen all) + unseen all old new or not) "Known IMAP search keys.") ;; imap interface @@ -1072,10 +1072,11 @@ Responsible for handling and, or, and parenthetical expressions.") ;; A bit of backward-compatibility slash convenience: if the ;; query string doesn't start with any known IMAP search ;; keyword, assume it is a "TEXT" search. - (unless (and (string-match "\\`[^[:blank:]]+" q-string) - (memql (intern-soft (downcase - (match-string 0 q-string))) - gnus-search-imap-search-keys)) + (unless (or (looking-at "(") + (and (string-match "\\`[^[:blank:]]+" q-string) + (memql (intern-soft (downcase + (match-string 0 q-string))) + gnus-search-imap-search-keys))) (setq q-string (concat "TEXT " q-string))) ;; If it's a thread query, make sure that all message-id commit 1aa36d968cd82f6eb5fc09ecad24efd811220483 Author: Stephen Leake Date: Mon Jan 11 09:18:31 2021 -0800 * admin/notes/elpa: Update to match recent Gnu ELPA changes diff --git a/admin/notes/elpa b/admin/notes/elpa index ea6c132fe1..1e9e7a9f52 100644 --- a/admin/notes/elpa +++ b/admin/notes/elpa @@ -5,17 +5,31 @@ repository named "elpa", hosted on Savannah. To check it out: git clone git://git.sv.gnu.org/emacs/elpa cd elpa - git remote set-url --push origin git+ssh://git.sv.gnu.org/srv/git/emacs/elpa - [create task branch for edits, etc.] + make setup -Changes to this branch propagate to elpa.gnu.org via a "deployment" script run -daily. This script (which is kept in elpa/admin/update-archive.sh) generates -the content visible at https://elpa.gnu.org/packages. +That leaves the elpa/packages directory empty; you must check out the +ones you want. -A new package is released as soon as the "version number" of that package is -changed. So you can use 'elpa' to work on a package without fear of releasing -those changes prematurely. And once the code is ready, just bump the -version number to make a new release of the package. +If you wish to check out all the packages into the packages directory, +you can run the command: + + make worktrees + +You can check out a specific package into the packages +directory with: + + make packages/ + + +Changes to this repository propagate to elpa.gnu.org via a +"deployment" script run daily. This script generates the content +visible at https://elpa.gnu.org/packages. + +A new package is released as soon as the "version number" of that +package is changed. So you can use 'elpa' to work on a package +without fear of releasing those changes prematurely. And once the +code is ready, just bump the version number to make a new release of +the package. It is easy to use the elpa branch to deploy a "local" copy of the package archive. For details, see the README file in the elpa branch. commit 00908e052a48ed8006485069ce2b2b761f040b67 Author: Lars Ingebrigtsen Date: Mon Jan 11 17:06:11 2021 +0100 Mark previous erc-services change as not needing documentation diff --git a/etc/NEWS b/etc/NEWS index a6419d603a..28dffef73a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1371,6 +1371,7 @@ https://www.w3.org/TR/xml/#charsets). Now it rejects such strings. ** erc +--- *** erc-services.el now supports NickServ passwords from auth-source. The 'erc-use-auth-source-for-nickserv-password' variable enables querying auth-source for NickServ passwords. To enable this, add the following commit d0d5e40a5d90eac440d82fb34e7b470c8d07c004 Author: Brian Leung Date: Mon Jan 11 16:42:03 2021 +0100 Make comint-read-input-ring skip uninteresting text in .zsh_history * lisp/comint.el (comint-read-input-ring): Simplify (bug#45606). * lisp/shell.el (shell-mode): Add "~/.zsh_history". * lisp/comint.el (comint-read-input-ring): Bind `comint-input-ring-file-prefix' in anticipation of a buffer switch. * lisp/comint.el (comint-read-input-ring): Skip the separator. Because re-search-backward moves point to the beginning of the match, and since we don't want the separator appearing in the output, we skip over it. This is required to properly detect instances of the value that zsh uses for `comint-input-ring-file-prefix'; if the `comint-input-ring-file-prefix' is ':potato', the subsequent invocation `looking-at' sees '\n:potato' for all entries after the one at the very beginning of the history file. diff --git a/lisp/comint.el b/lisp/comint.el index 2e683a7572..3476fd146c 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -979,6 +979,7 @@ See also `comint-input-ignoredups' and `comint-write-input-ring'." (ring (make-ring ring-size)) ;; Use possibly buffer-local values of these variables. (ring-separator comint-input-ring-separator) + (ring-file-prefix comint-input-ring-file-prefix) (history-ignore comint-input-history-ignore) (ignoredups comint-input-ignoredups)) (with-temp-buffer @@ -990,22 +991,14 @@ See also `comint-input-ignoredups' and `comint-write-input-ring'." (while (and (< count comint-input-ring-size) (re-search-backward ring-separator nil t) (setq end (match-beginning 0))) - (setq start - (if (re-search-backward ring-separator nil t) - (progn - (when (and comint-input-ring-file-prefix - (looking-at - comint-input-ring-file-prefix)) - ;; Skip zsh extended_history stamps - (goto-char (match-end 0))) - (match-end 0)) - (progn - (goto-char (point-min)) - (when (and comint-input-ring-file-prefix - (looking-at - comint-input-ring-file-prefix)) - (goto-char (match-end 0))) - (point)))) + (goto-char (if (re-search-backward ring-separator nil t) + (match-end 0) + (point-min))) + (when (and ring-file-prefix + (looking-at ring-file-prefix)) + ;; Skip zsh extended_history stamps + (goto-char (match-end 0))) + (setq start (point)) (setq history (buffer-substring start end)) (goto-char start) (when (and (not (string-match history-ignore history)) diff --git a/lisp/shell.el b/lisp/shell.el index c179dd24d3..0f866158fe 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -603,6 +603,7 @@ buffer." (or hfile (cond ((string-equal shell "bash") "~/.bash_history") ((string-equal shell "ksh") "~/.sh_history") + ((string-equal shell "zsh") "~/.zsh_history") (t "~/.history"))))) (if (or (equal comint-input-ring-file-name "") (equal (file-truename comint-input-ring-file-name) commit 26ed7c734557043827f02629dbba00031358e64a Author: Anticrisis Date: Mon Jan 11 16:16:50 2021 +0100 Add a failing test for bug#44834 * test/lisp/progmodes/tcl-tests.el (tcl-mode-namespace-indent-2): New, failing test (bug#44834). (tcl-mode-function-name-2): (tcl-mode-function-name-3): Fix names of the tests so that they're actually run. Copyright-paperwork-exempt: yes diff --git a/test/lisp/progmodes/tcl-tests.el b/test/lisp/progmodes/tcl-tests.el index 8ff85470ec..cf1ed2896e 100644 --- a/test/lisp/progmodes/tcl-tests.el +++ b/test/lisp/progmodes/tcl-tests.el @@ -50,14 +50,14 @@ (insert "proc notinthis {} {\n # nothing\n}\n\n") (should-not (add-log-current-defun)))) -(ert-deftest tcl-mode-function-name () +(ert-deftest tcl-mode-function-name-2 () (with-temp-buffer (tcl-mode) (insert "proc simple {} {\n # nothing\n}") (backward-char 3) (should (equal "simple" (add-log-current-defun))))) -(ert-deftest tcl-mode-function-name () +(ert-deftest tcl-mode-function-name-3 () (with-temp-buffer (tcl-mode) (insert "proc inthis {} {\n # nothing\n") @@ -72,6 +72,16 @@ (indent-region (point-min) (point-max)) (should (equal (buffer-string) text))))) +;; From bug#44834 +(ert-deftest tcl-mode-namespace-indent-2 () + :expected-result :failed + (with-temp-buffer + (tcl-mode) + (let ((text "namespace eval Foo {\n proc foo {} {}\n\n proc bar {}{}}\n")) + (insert text) + (indent-region (point-min) (point-max)) + (should (equal (buffer-string) text))))) + (provide 'tcl-tests) ;;; tcl-tests.el ends here commit 42e72f4adee8809ed754a14e11e058f40b337f78 Author: Leon Vack Date: Mon Jan 11 15:51:14 2021 +0100 Support using auth-source for NickServ passwords in ERC * lisp/etc/erc-services.el (erc-nickserv-passwords): Document that the passwords are only used when erc-prompt-for-nickserv-password is nil. * (erc-use-auth-source-for-nickserv-password): New customizable variable to enable checking auth-source for NickServ passwords. * (etc-nickserv-get-password): New function to handle the lookup of the NickServ password from both auth-source and the erc-nickserv-passwords variable. * (erc-nickserv-call-identify-function): Use new erc-nickserv-get-password function to lookup NickServ passwords. * (erc-nickserv-identify-autodetect, erc-nickserv-identify-on-connect, erc-nickserv-identify-on-nick-change): Call erc-nickserv-call-identify-function when erc-use-auth-source-for-nickserv-password is set. * etc/NEWS: Document change (bug#45340). diff --git a/etc/NEWS b/etc/NEWS index 7e84d69508..a6419d603a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1371,6 +1371,14 @@ https://www.w3.org/TR/xml/#charsets). Now it rejects such strings. ** erc +*** erc-services.el now supports NickServ passwords from auth-source. +The 'erc-use-auth-source-for-nickserv-password' variable enables querying +auth-source for NickServ passwords. To enable this, add the following +to your init file: + + (setq erc-prompt-for-nickserv-password nil + erc-use-auth-source-for-nickserv-password t) + --- *** The '/ignore' command will now ask for a timeout to stop ignoring the user. Allowed inputs are seconds or ISO8601-like periods like "1h" or "4h30m". diff --git a/lisp/erc/erc-services.el b/lisp/erc/erc-services.el index 4f9b0b199f..9ef8b7f46a 100644 --- a/lisp/erc/erc-services.el +++ b/lisp/erc/erc-services.el @@ -168,8 +168,19 @@ You can also use \\[erc-nickserv-identify-mode] to change modes." :group 'erc-services :type 'boolean) +(defcustom erc-use-auth-source-for-nickserv-password nil + "Query auth-source for a password when identifiying to NickServ. +This option has an no effect if `erc-prompt-for-nickserv-password' +is non-nil, and passwords from `erc-nickserv-passwords' take +precedence." + :version "28.1" + :group 'erc-services + :type 'boolean) + (defcustom erc-nickserv-passwords nil "Passwords used when identifying to NickServ automatically. +`erc-prompt-for-nickserv-password' must be nil for these +passwords to be used. Example of use: (setq erc-nickserv-passwords @@ -375,7 +386,8 @@ Make sure it is the real NickServ for this network. If `erc-prompt-for-nickserv-password' is non-nil, prompt the user for the password for this nickname, otherwise try to send it automatically." (unless (and (null erc-nickserv-passwords) - (null erc-prompt-for-nickserv-password)) + (null erc-prompt-for-nickserv-password) + (null erc-use-auth-source-for-nickserv-password)) (let* ((network (erc-network)) (sender (erc-nickserv-alist-sender network)) (identify-regex (erc-nickserv-alist-regexp network)) @@ -394,30 +406,49 @@ password for this nickname, otherwise try to send it automatically." (defun erc-nickserv-identify-on-connect (_server nick) "Identify to Nickserv after the connection to the server is established." (unless (or (and (null erc-nickserv-passwords) - (null erc-prompt-for-nickserv-password)) - (and (eq erc-nickserv-identify-mode 'both) - (erc-nickserv-alist-regexp (erc-network)))) + (null erc-prompt-for-nickserv-password) + (null erc-use-auth-source-for-nickserv-password)) + (and (eq erc-nickserv-identify-mode 'both) + (erc-nickserv-alist-regexp (erc-network)))) (erc-nickserv-call-identify-function nick))) (defun erc-nickserv-identify-on-nick-change (nick _old-nick) "Identify to Nickserv whenever your nick changes." (unless (or (and (null erc-nickserv-passwords) - (null erc-prompt-for-nickserv-password)) - (and (eq erc-nickserv-identify-mode 'both) - (erc-nickserv-alist-regexp (erc-network)))) + (null erc-prompt-for-nickserv-password) + (null erc-use-auth-source-for-nickserv-password)) + (and (eq erc-nickserv-identify-mode 'both) + (erc-nickserv-alist-regexp (erc-network)))) (erc-nickserv-call-identify-function nick))) +(defun erc-nickserv-get-password (nickname) + "Return the password for NICKNAME from configured sources. + +It uses `erc-nickserv-passwords' and additionally auth-source +when `erc-use-auth-source-for-nickserv-password' is not nil." + (or + (when erc-nickserv-passwords + (cdr (assoc nickname + (nth 1 (assoc (erc-network) + erc-nickserv-passwords))))) + (when erc-use-auth-source-for-nickserv-password + (let* ((secret (nth 0 (auth-source-search + :max 1 :require '(:secret) + :host (erc-with-server-buffer erc-session-server) + :port (format ; ensure we have a string + "%s" (erc-with-server-buffer erc-session-port)) + :user nickname)))) + (when secret + (let ((passwd (plist-get secret :secret))) + (if (functionp passwd) (funcall passwd) passwd))))))) + (defun erc-nickserv-call-identify-function (nickname) "Call `erc-nickserv-identify'. Either call it interactively or run it with NICKNAME's password, depending on the value of `erc-prompt-for-nickserv-password'." (if erc-prompt-for-nickserv-password (call-interactively 'erc-nickserv-identify) - (when erc-nickserv-passwords - (erc-nickserv-identify - (cdr (assoc nickname - (nth 1 (assoc (erc-network) - erc-nickserv-passwords)))))))) + (erc-nickserv-identify (erc-nickserv-get-password nickname)))) (defvar erc-auto-discard-away) @@ -451,6 +482,7 @@ When called interactively, read the password using `read-passwd'." (provide 'erc-services) + ;;; erc-services.el ends here ;; ;; Local Variables: diff --git a/lisp/window.el b/lisp/window.el index a6cdd4dec2..5bb7d577aa 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -8314,6 +8314,7 @@ indirectly called by the latter." (when (and (listp quad) (integerp (nth 3 quad)) (> (nth 3 quad) (window-total-height window))) + (message "foo") (condition-case nil (window-resize window (- (nth 3 quad) (window-total-height window))) (error nil))) commit 6129ebf4499ba641c3964eac4a028d4aa370f090 Author: Alexandre Duret-Lutz Date: Mon Jan 11 15:27:54 2021 +0100 Fix problem with non-ASCII characters in nnmaildir * lisp/gnus/nnmaildir.el (nnmaildir-request-article): Enable multipart 8bit-content-transfer-encoded files to be displayed correctly by reading as `raw-text' instead of having Emacs (incorrectly) decode the files (bug#44307). Copyright-paperwork-exempt: yes diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el index e4fd976742..2a4c74db5e 100644 --- a/lisp/gnus/nnmaildir.el +++ b/lisp/gnus/nnmaildir.el @@ -1351,7 +1351,8 @@ This variable is set by `nnmaildir-request-article'.") (throw 'return nil)) (with-current-buffer (or to-buffer nntp-server-buffer) (erase-buffer) - (nnheader-insert-file-contents nnmaildir-article-file-name)) + (let ((coding-system-for-read mm-text-coding-system)) + (mm-insert-file-contents nnmaildir-article-file-name))) (cons gname num-msgid)))) (defun nnmaildir-request-post (&optional _server) commit e694f61fc618c0c8553649edae6b9ca6d9b475be Author: Pedro Andres Aranda Gutierrez Date: Mon Jan 11 15:07:01 2021 +0100 Add `flat-button' to custom-face-attributes * lisp/cus-face.el (custom-face-attributes): Add `flat-button' (bug#45769). diff --git a/lisp/cus-face.el b/lisp/cus-face.el index 5dcb2842a2..21fe89c621 100644 --- a/lisp/cus-face.el +++ b/lisp/cus-face.el @@ -175,6 +175,7 @@ (choice :tag "Style" (const :tag "Raised" released-button) (const :tag "Sunken" pressed-button) + (const :tag "Flat" flat-button) (const :tag "None" nil)))) ;; filter to make value suitable for customize (lambda (real-value) commit ef55cc07ba70e81dd6573cffb11eae261999416f Author: Robert Pluim Date: Mon Jan 11 13:16:59 2021 +0100 * configure.ac: Alphabetize emacs_config_features diff --git a/configure.ac b/configure.ac index 616fa55b8a..bea2833809 100644 --- a/configure.ac +++ b/configure.ac @@ -5677,12 +5677,14 @@ Configured for '${canonical}'. Where do we find X Windows header files? ${x_includes:-$emacs_standard_dirs} Where do we find X Windows libraries? ${x_libraries:-$emacs_standard_dirs}"]) +#### Please respect alphabetical ordering when making additions. optsep= emacs_config_features= -for opt in XAW3D XPM JPEG TIFF GIF PNG RSVG CAIRO IMAGEMAGICK SOUND GPM DBUS \ - GCONF GSETTINGS GLIB NOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE HARFBUZZ M17N_FLT \ - LIBOTF XFT ZLIB TOOLKIT_SCROLL_BARS X_TOOLKIT OLDXMENU X11 XDBE XIM \ - NS MODULES THREADS XWIDGETS LIBSYSTEMD JSON PDUMPER UNEXEC LCMS2 GMP; do +for opt in ACL CAIRO DBUS FREETYPE GCONF GIF GLIB GMP GNUTLS GPM GSETTINGS \ + HARFBUZZ IMAGEMAGICK JPEG JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 \ + M17N_FLT MODULES NOTIFY NS OLDXMENU PDUMPER PNG RSVG SOUND THREADS TIFF \ + TOOLKIT_SCROLL_BARS UNEXEC X11 XAW3D XDBE XFT XIM XPM XWIDGETS X_TOOLKIT \ + ZLIB; do case $opt in PDUMPER) val=${with_pdumper} ;; commit 62e3750af306218a6dc08b1a2ca62e9a73aa306f Author: Robert Pluim Date: Mon Jan 11 13:11:51 2021 +0100 Ensure HAVE_GMP is reflected in emacs_config_features * configure.ac: Move HAVE_GMP setting before emacs_config_features setting (Bug#45771). diff --git a/configure.ac b/configure.ac index 66c660696b..616fa55b8a 100644 --- a/configure.ac +++ b/configure.ac @@ -5657,6 +5657,12 @@ else ACL_SUMMARY=no fi +if test -z "$GMP_H"; then + HAVE_GMP=yes +else + HAVE_GMP=no +fi + emacs_standard_dirs='Standard dirs' AS_ECHO([" Configured for '${canonical}'. @@ -5713,11 +5719,6 @@ done AC_DEFINE_UNQUOTED(EMACS_CONFIG_FEATURES, "${emacs_config_features}", [Summary of some of the main features enabled by configure.]) -if test -z "$GMP_H"; then - HAVE_GMP=yes -else - HAVE_GMP=no -fi AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D} Does Emacs use -lXpm? ${HAVE_XPM} Does Emacs use -ljpeg? ${HAVE_JPEG} commit 17bd039539d22a0a2da792d3921f2c603cc2d460 Author: Dmitry Gutov Date: Mon Jan 11 00:44:38 2021 +0200 New command xref-quit-and-pop-marker-stack * lisp/progmodes/xref.el (xref-quit-and-pop-marker-stack): New command. (xref--xref-buffer-mode-map): Binding for it. diff --git a/etc/NEWS b/etc/NEWS index a7a872d979..7e84d69508 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1343,6 +1343,11 @@ have been renamed to have "proper" public names and documented ('xref-show-definitions-buffer' and 'xref-show-definitions-buffer-at-bottom'). +*** New command 'xref-quit-and-pop-marker-stack' and a binding for it +in Xref buffers ('M-,'). This combination is easy to press +semi-accidentally if the user wants to go back in the middle of +choosing the exact definition to go to, and this should do TRT. + --- *** New value 'project-relative' for 'xref-file-name-display' If chosen, file names in *xref* buffers will be displayed relative diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index d3b6ae71a0..b6778de807 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -663,6 +663,12 @@ means to first quit the *xref* buffer." (interactive) (xref-goto-xref t)) +(defun xref-quit-and-pop-marker-stack () + "Quit *xref* buffer, then pop the xref marker stack." + (interactive) + (quit-window) + (xref-pop-marker-stack)) + (defun xref-query-replace-in-results (from to) "Perform interactive replacement of FROM with TO in all displayed xrefs. @@ -793,6 +799,7 @@ references displayed in the current *xref* buffer." (define-key map (kbd ".") #'xref-next-line) (define-key map (kbd ",") #'xref-prev-line) (define-key map (kbd "g") #'xref-revert-buffer) + (define-key map (kbd "M-,") #'xref-quit-and-pop-marker-stack) map)) (define-derived-mode xref--xref-buffer-mode special-mode "XREF" commit fb32f928793d76346579b7d2331fe221dc7094d1 Author: Phillip Lord Date: Sun Jan 10 21:49:51 2021 +0000 Allow evaluation of tests from local source repository * etc/w32-feature.el (w32-feature-load-tests): Add new command diff --git a/etc/w32-feature.el b/etc/w32-feature.el index c5f2cd548a..364e9341ae 100644 --- a/etc/w32-feature.el +++ b/etc/w32-feature.el @@ -25,9 +25,21 @@ ;; designed to check whether bundled binary distributions of Emacs on ;; windows are fully functional. +;; By default is checks whether the features that we are expect to be +;; available on Emacs for Windows are reported to be available. It +;; should be possible to run these tests from a distributed version of +;; Emacs. + +;; In addition, it provides a single command +;; `w32-feature-load-tests'. If the full source repository of Emacs is +;; available, this will load selected files from the repository which +;; test these features. + ;;; Code: (require 'ert) +(defvar w32-feature-core-tests nil) + (ert-deftest feature-optimization () (should (string-match-p "CFLAGS=-O2" system-configuration-options))) @@ -41,16 +53,24 @@ (ert-deftest feature-gnutls () (should (gnutls-available-p))) +(add-to-list 'w32-feature-core-tests "lisp/net/gnutls-tests.el") + (ert-deftest feature-zlib () (should (zlib-available-p))) +(add-to-list 'w32-feature-core-tests "src/decompress-tests.el") + (ert-deftest feature-thread () (should (fboundp 'make-thread))) +(add-to-list 'w32-feature-core-tests "lisp/thread-tests.el") + (ert-deftest feature-json () (should (fboundp 'json-serialize))) +(add-to-list 'w32-feature-core-tests "src/json-tests.el") + (ert-deftest feature-gmp () (should (string-match-p "GMP" system-configuration-features))) @@ -61,9 +81,13 @@ (ert-deftest feature-libxml () (should (libxml-available-p))) +(add-to-list 'w32-feature-core-tests "src/xml-tests.el") + (ert-deftest feature-lcms2 () (should (lcms2-available-p))) +(add-to-list 'w32-feature-core-tests "src/lcms-tests.el") + (ert-deftest feature-xpm () (should (image-type-available-p 'xpm))) @@ -73,8 +97,7 @@ (ert-deftest feature-png () (should (image-type-available-p 'png))) -(ert-deftest feature-xpm () - (should (image-type-available-p 'xpm))) +(add-to-list 'w32-feature-core-tests "lisp/image-file-tests.el") (ert-deftest feature-jpeg () (should (image-type-available-p 'jpeg))) @@ -84,4 +107,12 @@ (ert-deftest feature-svg () (should (image-type-available-p 'svg))) + +(defun w32-feature-load-tests (dir) + (interactive "D") + (mapc + (lambda(f) + (load-file (concat dir "test/" f))) + w32-feature-core-tests)) + ;;; feature.el ends here commit 45abd52f3c870ab4ee05fddfc4896d2444594c3d Author: Philipp Stephani Date: Sun Jan 10 22:35:02 2021 +0100 Fix build breakage if Lisp_Object is not a primitive type. * src/minibuf.c (choose_minibuf_frame): Don't compare Lisp_Objects with '!='. Use 'EQ' instead. diff --git a/src/minibuf.c b/src/minibuf.c index c527e2bc9c..868e481f84 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -141,8 +141,8 @@ choose_minibuf_frame (void) if (!EQ (frame, selected_frame) && minibuf_level > 1 /* The frame's minibuffer can be on a different frame. */ - && XWINDOW ((of = XFRAME (frame))->minibuffer_window)->frame - != selected_frame) + && ! EQ (XWINDOW ((of = XFRAME (frame))->minibuffer_window)->frame, + selected_frame)) { if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (of)))) Fset_frame_selected_window (frame, Fframe_first_window (frame), commit 94344d130c2c2db90bcc47e12870d1d58f020ecf Author: Philipp Stephani Date: Sun Jan 10 22:28:31 2021 +0100 Add functions to open a file without quitting. In some situations, e.g. when the Lisp machinery isn't available, we can't quit. Don't check the quit flags in such situations, in case they contain garbage. * src/sysdep.c (emacs_open_noquit, emacs_openat_noquit): New variants of 'emacs_open' and 'emacs_openat' that don't check the quit flags. * src/emacs.c (main, Fdaemon_initialized): * src/pdumper.c (pdumper_load): * src/w32term.c (w32_initialize): * src/buffer.c (mmap_init): * src/callproc.c (emacs_spawn): Use them where we can't quit. diff --git a/src/buffer.c b/src/buffer.c index 71ad5edd52..80c799e719 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -4785,7 +4785,7 @@ mmap_init (void) if (mmap_fd <= 0) { /* No anonymous mmap -- we need the file descriptor. */ - mmap_fd = emacs_open ("/dev/zero", O_RDONLY, 0); + mmap_fd = emacs_open_noquit ("/dev/zero", O_RDONLY, 0); if (mmap_fd == -1) fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno)); } diff --git a/src/callproc.c b/src/callproc.c index 1da315bef1..cb72b070b7 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -1336,7 +1336,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, would work? */ if (std_in >= 0) emacs_close (std_in); - std_out = std_in = emacs_open (pty, O_RDWR, 0); + std_out = std_in = emacs_open_noquit (pty, O_RDWR, 0); if (std_in < 0) { diff --git a/src/emacs.c b/src/emacs.c index 69d10821fa..77114271b2 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1275,7 +1275,7 @@ main (int argc, char **argv) { emacs_close (STDIN_FILENO); emacs_close (STDOUT_FILENO); - int result = emacs_open (term, O_RDWR, 0); + int result = emacs_open_noquit (term, O_RDWR, 0); if (result != STDIN_FILENO || (fcntl (STDIN_FILENO, F_DUPFD_CLOEXEC, STDOUT_FILENO) != STDOUT_FILENO)) @@ -2847,7 +2847,7 @@ from the parent process and its tty file descriptors. */) int nfd; /* Get rid of stdin, stdout and stderr. */ - nfd = emacs_open ("/dev/null", O_RDWR, 0); + nfd = emacs_open_noquit ("/dev/null", O_RDWR, 0); err |= nfd < 0; err |= dup2 (nfd, STDIN_FILENO) < 0; err |= dup2 (nfd, STDOUT_FILENO) < 0; diff --git a/src/lisp.h b/src/lisp.h index 86be25852a..9d8dbbd629 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4577,6 +4577,7 @@ extern AVOID emacs_abort (void) NO_INLINE; extern int emacs_fstatat (int, char const *, void *, int); extern int emacs_openat (int, char const *, int, int); extern int emacs_open (const char *, int, int); +extern int emacs_open_noquit (const char *, int, int); extern int emacs_pipe (int[2]); extern int emacs_close (int); extern ptrdiff_t emacs_read (int, void *, ptrdiff_t); diff --git a/src/pdumper.c b/src/pdumper.c index 116cc28dbb..c1388ebbb3 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -5273,7 +5273,7 @@ pdumper_load (const char *dump_filename) eassert (!dump_loaded_p ()); int err; - int dump_fd = emacs_open (dump_filename, O_RDONLY, 0); + int dump_fd = emacs_open_noquit (dump_filename, O_RDONLY, 0); if (dump_fd < 0) { err = (errno == ENOENT || errno == ENOTDIR diff --git a/src/sysdep.c b/src/sysdep.c index a49f1775eb..941b4e2fa2 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -2320,6 +2320,28 @@ emacs_open (char const *file, int oflags, int mode) return emacs_openat (AT_FDCWD, file, oflags, mode); } +/* Same as above, but doesn't allow the user to quit. */ + +static int +emacs_openat_noquit (int dirfd, const char *file, int oflags, + int mode) +{ + int fd; + if (! (oflags & O_TEXT)) + oflags |= O_BINARY; + oflags |= O_CLOEXEC; + do + fd = openat (dirfd, file, oflags, mode); + while (fd < 0 && errno == EINTR); + return fd; +} + +int +emacs_open_noquit (char const *file, int oflags, int mode) +{ + return emacs_openat_noquit (AT_FDCWD, file, oflags, mode); +} + /* Open FILE as a stream for Emacs use, with mode MODE. Act like emacs_open with respect to threads, signals, and quits. */ diff --git a/src/w32term.c b/src/w32term.c index e5a8a823b4..109aa58d73 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -7507,7 +7507,8 @@ w32_initialize (void) } #ifdef CYGWIN - if ((w32_message_fd = emacs_open ("/dev/windows", O_RDWR, 0)) == -1) + if ((w32_message_fd = emacs_open_noquit ("/dev/windows", O_RDWR, 0)) + == -1) fatal ("opening /dev/windows: %s", strerror (errno)); #endif /* CYGWIN */ commit c7c154bb5756e0ae71d342c5d8aabf725877f186 Author: Alan Mackenzie Date: Sun Jan 10 20:32:40 2021 +0000 Fix incompleteness in the implementation of minibuffer-follows-selected-frame In particular, add a new value to the variable, and fix several bugs apparent with the implementation up till now. * doc/emacs/mini.texi (Basic Minibuffer): Add a description of the new non-nil, non-t value of minibuffer-follows-selected-frame. * doc/emacs/trouble.texi (Quitting): Add a description of how C-g handles recursive minibuffers when typed in one which isn't the most nested. * doc/lispref/minibuf.texi (Intro to Minibuffers): Add an @dfn for "active minibuffer". (Minibuffer Commands): Document that exit-minibuffer throws an error when not invoked from the innermost Minibuffer. (Recursive Mini): Amend the description of the visibility of outer level minibuffers. (Minibuffer Misc): In the description of the minibuffer hooks, replace "the minibuffer" with "a minibuffer". * etc/NEWS (Entry announcing minibuffer-follows-selected-frame): Add a description of the new non-nil, non-t value. * lisp/cus-start.el (top level): make the customize entry for minibuffer-follows-selected-frame a choice between three entries. * lisp/minibuffer.el (exit-minibuffer): throw an error when we're not in the most nested minibuffer. (top level): Bind C-g to abort-minibuffers in minibuffer-local-map. * lisp/window.el (window-deletable-p): return the symbol `frame' when (amongst other things) minibuffer-follows-selected-frame is t. * src/eval.c (internal_catch): Add a mechanism to (throw 'exit t) repeatedly when the throw currently being processed doesn't terminate the current minibuffer. * src/lisp.h (this_minibuffer_depth): New extern declaration (minibuf_level): extern declaration moved here from window.h. * src/minibuf.c (minibuffer_follows_frame, minibuf_stays_put) (minibuf_moves_frame_when_opened): New and amended functions to query the value of minibuffer-follows-selected-frame. (choose_minibuf_frame): check (minibuf > 1) in place of (minibufer > 0) at a particular place. At another place, check that an alleged frame is so and is live. Before selecting a non-miniwindow on a different frame, ensure it really is a different frame. (move_minibuffer_onto_frame): Stack up all recursive minibuffers on the target frame. Check the minibuf_window isn't in the old frame before setting that frame's miniwindow to an inactive minibuffer. (Finnermost_minibuffer_p, Fabort_minibuffers): New primitives. (this_minibuffer_depth): New function. (read_minibuf): Record the calling frame in a variable, and switch back to it after the recursive edit has terminated normally, using select-frame-set-input-focus. Stack up all the recursive minibuffers on the miniwindow where a new minibuffer is being opened. After the recursive edit, switch the selected window away from the expired minibuffer's window. (nth_minibuffer): New function. (minibuffer-follows-selected-frame): Change from a DEFVAR_BOOL to a DEFVAR_LISP. * src/window.c (decode_next_window_args): Set *minibuf to w's mini-window's content when that content is a minibuffer. * src/window.h (minibuf_level) Declaration moved from here to lisp.h. diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi index c7c8fb30ac..f81e64bdf9 100644 --- a/doc/emacs/mini.texi +++ b/doc/emacs/mini.texi @@ -76,9 +76,13 @@ default, the active minibuffer moves to this new frame. If you set the user option @code{minibuffer-follows-selected-frame} to @code{nil}, then the minibuffer stays in the frame where you opened it, and you must switch back to that frame in order to complete (or -abort) the current command. Note that the effect of the command, when -you finally finish using the minibuffer, always takes place in the -frame where you first opened it. +abort) the current command. If you set that option to a value which +is neither @code{nil} nor @code{t}, the minibuffer moves frame only +after a recursive minibuffer has been opened in the current command +(@pxref{Recursive Mini,,, elisp}). This option is mainly to retain +(approximately) the behavior prior to Emacs 28.1. Note that the +effect of the command, when you finally finish using the minibuffer, +always takes place in the frame where you first opened it. @node Minibuffer File @section Minibuffers for File Names diff --git a/doc/emacs/trouble.texi b/doc/emacs/trouble.texi index 4da3d4a3e8..9a638818c9 100644 --- a/doc/emacs/trouble.texi +++ b/doc/emacs/trouble.texi @@ -57,6 +57,13 @@ incremental search, @kbd{C-g} behaves specially; it may take two successive @kbd{C-g} characters to get out of a search. @xref{Incremental Search}, for details. + If you type @kbd{C-g} in a minibuffer, this quits the command that +opened that minibuffer, closing it. If that minibuffer is not the +most recently opened one (which can happen when +@code{minibuffer-follows-selected-frame} is @code{nil} (@pxref{Basic +Minibuffer})), @kbd{C-g} also closes the more recently opened ones, +quitting their associated commands, after asking you for confirmation. + On MS-DOS, the character @kbd{C-@key{Break}} serves as a quit character like @kbd{C-g}. The reason is that it is not feasible, on MS-DOS, to recognize @kbd{C-g} while a command is running, between interactions diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index f0036f0ccf..d316c1f060 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -82,10 +82,12 @@ there is an active minibuffer; such a minibuffer is called a incrementing the number at the end of the name. (The names begin with a space so that they won't show up in normal buffer lists.) Of several recursive minibuffers, the innermost (or most recently -entered) is the active minibuffer. We usually call this @emph{the} -minibuffer. You can permit or forbid recursive minibuffers by setting -the variable @code{enable-recursive-minibuffers}, or by putting -properties of that name on command symbols (@xref{Recursive Mini}.) +entered) is the @dfn{active minibuffer}--it is the one you can +terminate by typing @key{RET} (@code{exit-minibuffer}) in. We usually +call this @emph{the} minibuffer. You can permit or forbid recursive +minibuffers by setting the variable +@code{enable-recursive-minibuffers}, or by putting properties of that +name on command symbols (@xref{Recursive Mini}.) Like other buffers, a minibuffer uses a local keymap (@pxref{Keymaps}) to specify special key bindings. The function that @@ -2380,7 +2382,8 @@ minibuffer. @deffn Command exit-minibuffer This command exits the active minibuffer. It is normally bound to -keys in minibuffer local keymaps. +keys in minibuffer local keymaps. The command throws an error if the +current buffer is not the active minibuffer. @end deffn @deffn Command self-insert-and-exit @@ -2594,8 +2597,11 @@ returns zero. If this variable is non-@code{nil}, you can invoke commands (such as @code{find-file}) that use minibuffers even while the minibuffer is active. Such invocation produces a recursive editing level for a new -minibuffer. The outer-level minibuffer is invisible while you are -editing the inner one. +minibuffer. By default, the outer-level minibuffer is invisible while +you are editing the inner one. If you have +@code{minibuffer-follows-selected-frame} set to @code{nil}, you can +have minibuffers visible on several frames at the same time. +@xref{Basic Minibuffer,,, emacs}. If this variable is @code{nil}, you cannot invoke minibuffer commands when the minibuffer is active, not even if you switch to another window @@ -2623,7 +2629,7 @@ active minibuffer. @end defun @defvar minibuffer-setup-hook -This is a normal hook that is run whenever the minibuffer is entered. +This is a normal hook that is run whenever a minibuffer is entered. @xref{Hooks}. @end defvar @@ -2641,7 +2647,7 @@ called once, for the outermost use of the minibuffer. @end defmac @defvar minibuffer-exit-hook -This is a normal hook that is run whenever the minibuffer is exited. +This is a normal hook that is run whenever a minibuffer is exited. @xref{Hooks}. @end defvar diff --git a/etc/NEWS b/etc/NEWS index 1a1f76d128..a7a872d979 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -102,12 +102,13 @@ effect should be negligible in the vast majority of cases anyway. By default, when you switch to another frame, an active minibuffer now moves to the newly selected frame. Nevertheless, the effect of what you type in the minibuffer happens in the frame where the minibuffer -was first activated, even if it moved to another frame. An -alternative behavior is available by customizing -'minibuffer-follows-selected-frame' to nil. Here, the minibuffer -stays in the frame where you first opened it, and you must switch back -to this frame to continue or abort its command. The old, somewhat -unsystematic behavior, which mixed these two is no longer available. +was first activated. An alternative behavior is available by +customizing 'minibuffer-follows-selected-frame' to nil. Here, the +minibuffer stays in the frame where you first opened it, and you must +switch back to this frame to continue or abort its command. The old +behavior, which mixed these two, can be approximated by customizing +'minibuffer-follows-selected-frame' to a value which is neither nil +nor t. +++ ** New system for displaying documentation for groups of functions. diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 85dd14f628..0293d34d1c 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -394,7 +394,11 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of ;; (directory :format "%v")))) (load-prefer-newer lisp boolean "24.4") ;; minibuf.c - (minibuffer-follows-selected-frame minibuffer boolean "28.1") + (minibuffer-follows-selected-frame + minibuffer (choice (const :tag "Always" t) + (const :tag "When used" hybrid) + (const :tag "Never" nil)) + "28.1") (enable-recursive-minibuffers minibuffer boolean) (history-length minibuffer (choice (const :tag "Infinite" t) integer) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 556f5d3a56..315f2d369a 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -2125,8 +2125,10 @@ variables.") ;; A better solution would be to make deactivate-mark buffer-local ;; (or to turn it into a list of buffers, ...), but in the mean time, ;; this should do the trick in most cases. - (setq deactivate-mark nil) - (throw 'exit nil)) + (when (innermost-minibuffer-p) + (setq deactivate-mark nil) + (throw 'exit nil)) + (error "%s" "Not in most nested minibuffer")) (defun self-insert-and-exit () "Terminate minibuffer input." @@ -2394,7 +2396,7 @@ The completion method is determined by `completion-at-point-functions'." ;;; Key bindings. (let ((map minibuffer-local-map)) - (define-key map "\C-g" 'abort-recursive-edit) + (define-key map "\C-g" 'abort-minibuffers) (define-key map "\M-<" 'minibuffer-beginning-of-buffer) (define-key map "\r" 'exit-minibuffer) diff --git a/lisp/window.el b/lisp/window.el index 38be778906..a6cdd4dec2 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -4116,7 +4116,10 @@ frame can be safely deleted." frame)) (throw 'other t)))) (let ((minibuf (active-minibuffer-window))) - (and minibuf (eq frame (window-frame minibuf))))) + (and minibuf (eq frame (window-frame minibuf)) + (not (eq (default-toplevel-value + minibuffer-follows-selected-frame) + t))))) 'frame)) ((window-minibuffer-p window) ;; If WINDOW is the minibuffer window of a non-minibuffer-only diff --git a/src/eval.c b/src/eval.c index 706aafdf50..5bf3faebc8 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1167,9 +1167,18 @@ Lisp_Object internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) { + /* MINIBUFFER_QUIT_LEVEL is to handle quitting from nested minibuffers by + throwing t to tag `exit'. + Value -1 means there is no (throw 'exit t) in progress; + 0 means the `throw' wasn't done from an active minibuffer; + N > 0 means the `throw' was done from the minibuffer at level N. */ + static EMACS_INT minibuffer_quit_level = -1; /* This structure is made part of the chain `catchlist'. */ struct handler *c = push_handler (tag, CATCHER); + if (EQ (tag, Qexit)) + minibuffer_quit_level = -1; + /* Call FUNC. */ if (! sys_setjmp (c->jmp)) { @@ -1183,6 +1192,23 @@ internal_catch (Lisp_Object tag, Lisp_Object val = handlerlist->val; clobbered_eassert (handlerlist == c); handlerlist = handlerlist->next; + if (EQ (tag, Qexit) && EQ (val, Qt)) + /* If we've thrown t to tag `exit' from within a minibuffer, we + exit all minibuffers more deeply nested than the current + one. */ + { + EMACS_INT mini_depth = this_minibuffer_depth (Qnil); + if (mini_depth && mini_depth != minibuffer_quit_level) + { + if (minibuffer_quit_level == -1) + minibuffer_quit_level = mini_depth; + if (minibuffer_quit_level + && (minibuf_level > minibuffer_quit_level)) + Fthrow (Qexit, Qt); + } + else + minibuffer_quit_level = -1; + } return val; } } diff --git a/src/lisp.h b/src/lisp.h index d139df9342..86be25852a 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4346,6 +4346,8 @@ extern Lisp_Object Vminibuffer_list; extern Lisp_Object last_minibuf_string; extern void move_minibuffer_onto_frame (void); extern bool is_minibuffer (EMACS_INT, Lisp_Object); +extern EMACS_INT this_minibuffer_depth (Lisp_Object); +extern EMACS_INT minibuf_level; extern Lisp_Object get_minibuffer (EMACS_INT); extern void init_minibuf_once (void); extern void syms_of_minibuf (void); diff --git a/src/minibuf.c b/src/minibuf.c index 5ee440f662..c527e2bc9c 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -63,9 +63,30 @@ static Lisp_Object minibuf_prompt; static ptrdiff_t minibuf_prompt_width; +static Lisp_Object nth_minibuffer (EMACS_INT depth); + +/* Return TRUE when a frame switch causes a minibuffer on the old + frame to move onto the new one. */ static bool minibuf_follows_frame (void) +{ + return EQ (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame), + Qt); +} + +/* Return TRUE when a minibuffer always remains on the frame where it + was first invoked. */ +static bool +minibuf_stays_put (void) +{ + return NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame)); +} + +/* Return TRUE when opening a (recursive) minibuffer causes + minibuffers on other frames to move to the selected frame. */ +static bool +minibuf_moves_frame_when_opened (void) { return !NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame)); } @@ -90,7 +111,7 @@ choose_minibuf_frame (void) minibuf_window = sf->minibuffer_window; /* If we've still got another minibuffer open, use its mini-window instead. */ - if (minibuf_level && !minibuf_follows_frame ()) + if (minibuf_level > 1 && minibuf_stays_put ()) { Lisp_Object buffer = get_minibuffer (minibuf_level); Lisp_Object tail, frame; @@ -105,26 +126,40 @@ choose_minibuf_frame (void) } } - if (minibuf_follows_frame ()) + if (minibuf_moves_frame_when_opened () + && FRAMEP (selected_frame) + && FRAME_LIVE_P (XFRAME (selected_frame))) /* Make sure no other frame has a minibuffer as its selected window, because the text would not be displayed in it, and that would be confusing. Only allow the selected frame to do this, and that only if the minibuffer is active. */ - { - Lisp_Object tail, frame; - - FOR_EACH_FRAME (tail, frame) - if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (XFRAME (frame)))) - && !(EQ (frame, selected_frame) - && minibuf_level > 0)) - Fset_frame_selected_window (frame, Fframe_first_window (frame), - Qnil); - } + { + Lisp_Object tail, frame; + struct frame *of; + + FOR_EACH_FRAME (tail, frame) + if (!EQ (frame, selected_frame) + && minibuf_level > 1 + /* The frame's minibuffer can be on a different frame. */ + && XWINDOW ((of = XFRAME (frame))->minibuffer_window)->frame + != selected_frame) + { + if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (of)))) + Fset_frame_selected_window (frame, Fframe_first_window (frame), + Qnil); + + if (!EQ (XWINDOW (of->minibuffer_window)->contents, + nth_minibuffer (0))) + set_window_buffer (of->minibuffer_window, + nth_minibuffer (0), 0, 0); + } + } } -/* If `minibuffer_follows_selected_frame' and we have a minibuffer, move it - from its current frame to the selected frame. This function is - intended to be called from `do_switch_frame' in frame.c. */ +/* If `minibuffer_follows_selected_frame' is t and we have a + minibuffer, move it from its current frame to the selected frame. + This function is intended to be called from `do_switch_frame' in + frame.c. */ void move_minibuffer_onto_frame (void) { if (!minibuf_level) @@ -135,14 +170,18 @@ void move_minibuffer_onto_frame (void) && FRAME_LIVE_P (XFRAME (selected_frame)) && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window)) { + EMACS_INT i; struct frame *sf = XFRAME (selected_frame); Lisp_Object old_frame = XWINDOW (minibuf_window)->frame; struct frame *of = XFRAME (old_frame); - Lisp_Object buffer = XWINDOW (minibuf_window)->contents; - set_window_buffer (sf->minibuffer_window, buffer, 0, 0); + /* Stack up all the (recursively) open minibuffers on the selected + mini_window. */ + for (i = 1; i <= minibuf_level; i++) + set_window_buffer (sf->minibuffer_window, nth_minibuffer (i), 0, 0); minibuf_window = sf->minibuffer_window; - set_window_buffer (of->minibuffer_window, get_minibuffer (0), 0, 0); + if (of != sf) + set_window_buffer (of->minibuffer_window, get_minibuffer (0), 0, 0); } } @@ -336,6 +375,63 @@ return t only if BUFFER is an active minibuffer. */) ? Qt : Qnil; } +DEFUN ("innermost-minibuffer-p", Finnermost_minibuffer_p, + Sinnermost_minibuffer_p, 0, 1, 0, + doc: /* Return t if BUFFER is the most nested active minibuffer. +No argument or nil as argument means use the current buffer as BUFFER. */) + (Lisp_Object buffer) +{ + if (NILP (buffer)) + buffer = Fcurrent_buffer (); + return EQ (buffer, (Fcar (Fnthcdr (make_fixnum (minibuf_level), + Vminibuffer_list)))) + ? Qt + : Qnil; +} + +/* Return the nesting depth of the active minibuffer BUFFER, or 0 if + BUFFER isn't such a thing. If BUFFER is nil, this means use the current + buffer. */ +EMACS_INT +this_minibuffer_depth (Lisp_Object buffer) +{ + EMACS_INT i; + Lisp_Object bufs; + + if (NILP (buffer)) + buffer = Fcurrent_buffer (); + for (i = 1, bufs = Fcdr (Vminibuffer_list); + i <= minibuf_level; + i++, bufs = Fcdr (bufs)) + if (EQ (Fcar (bufs), buffer)) + return i; + return 0; +} + +DEFUN ("abort-minibuffers", Fabort_minibuffers, Sabort_minibuffers, 0, 0, "", + doc: /* Abort the current minibuffer. +If we are not currently in the innermost minibuffer, prompt the user to +confirm the aborting of the current minibuffer and all contained ones. */) + (void) +{ + EMACS_INT minibuf_depth = this_minibuffer_depth (Qnil); + Lisp_Object array[2]; + AUTO_STRING (fmt, "Abort %s minibuffer levels? "); + + if (!minibuf_depth) + error ("Not in a minibuffer"); + if (minibuf_depth < minibuf_level) + { + array[0] = fmt; + array[1] = make_fixnum (minibuf_level - minibuf_depth + 1); + if (!NILP (Fyes_or_no_p (Fformat (2, array)))) + Fthrow (Qexit, Qt); + } + else + Fthrow (Qexit, Qt); + return Qnil; +} + DEFUN ("minibuffer-prompt-end", Fminibuffer_prompt_end, Sminibuffer_prompt_end, 0, 0, 0, doc: /* Return the buffer position of the end of the minibuffer prompt. @@ -411,6 +507,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, Lisp_Object val; ptrdiff_t count = SPECPDL_INDEX (); Lisp_Object mini_frame, ambient_dir, minibuffer, input_method; + Lisp_Object calling_frame = selected_frame; Lisp_Object enable_multibyte; EMACS_INT pos = 0; /* String to add to the history. */ @@ -648,6 +745,17 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, } } + if (minibuf_moves_frame_when_opened ()) + { + EMACS_INT i; + + /* Stack up all the (recursively) open minibuffers on the selected + mini_window. */ + for (i = 1; i < minibuf_level; i++) + set_window_buffer (XFRAME (mini_frame)->minibuffer_window, + nth_minibuffer (i), 0, 0); + } + /* Display this minibuffer in the proper window. */ /* Use set_window_buffer instead of Fset_window_buffer (see discussion of bug#11984, bug#12025, bug#12026). */ @@ -729,6 +837,20 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, recursive_edit_1 (); + /* We've exited the recursive edit without an error, so switch the + current window away from the expired minibuffer window. */ + { + Lisp_Object prev = Fprevious_window (minibuf_window, Qnil, Qnil); + /* PREV can be on a different frame when we have a minibuffer only + frame, the other frame's minibuffer window is MINIBUF_WINDOW, + and its "focus window" is also MINIBUF_WINDOW. */ + while (!EQ (prev, minibuf_window) + && !EQ (selected_frame, WINDOW_FRAME (XWINDOW (prev)))) + prev = Fprevious_window (prev, Qnil, Qnil); + if (!EQ (prev, minibuf_window)) + Fset_frame_selected_window (selected_frame, prev, Qnil); + } + /* If cursor is on the minibuffer line, show the user we have exited by putting it in column 0. */ if (XWINDOW (minibuf_window)->cursor.vpos >= 0 @@ -767,6 +889,12 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, in set-window-configuration. */ unbind_to (count, Qnil); + /* Switch the frame back to the calling frame. */ + if (!EQ (selected_frame, calling_frame) + && FRAMEP (calling_frame) + && FRAME_LIVE_P (XFRAME (calling_frame))) + call2 (intern ("select-frame-set-input-focus"), calling_frame, Qnil); + /* Add the value to the appropriate history list, if any. This is done after the previous buffer has been made current again, in case the history variable is buffer-local. */ @@ -790,6 +918,14 @@ is_minibuffer (EMACS_INT depth, Lisp_Object buf) && EQ (Fcar (tail), buf); } +/* Return the DEPTHth minibuffer, or nil if such does not yet exist. */ +static Lisp_Object +nth_minibuffer (EMACS_INT depth) +{ + Lisp_Object tail = Fnthcdr (make_fixnum (depth), Vminibuffer_list); + return XCAR (tail); +} + /* Return a buffer to be used as the minibuffer at depth `depth'. depth = 0 is the lowest allowed argument, and that is the value used for nonrecursive minibuffer invocations. */ @@ -2032,13 +2168,15 @@ For example, `eval-expression' uses this. */); The function is called with the arguments passed to `read-buffer'. */); Vread_buffer_function = Qnil; - DEFVAR_BOOL ("minibuffer-follows-selected-frame", minibuffer_follows_selected_frame, - doc: /* Non-nil means the active minibuffer always displays on the selected frame. + DEFVAR_LISP ("minibuffer-follows-selected-frame", minibuffer_follows_selected_frame, + doc: /* t means the active minibuffer always displays on the selected frame. Nil means that a minibuffer will appear only in the frame which created it. +Any other value means the minibuffer will move onto another frame, but +only when the user starts using a minibuffer there. Any buffer local or dynamic binding of this variable is ignored. Only the default top level value is used. */); - minibuffer_follows_selected_frame = 1; + minibuffer_follows_selected_frame = Qt; DEFVAR_BOOL ("read-buffer-completion-ignore-case", read_buffer_completion_ignore_case, @@ -2196,6 +2334,8 @@ uses to hide passwords. */); defsubr (&Sminibuffer_prompt); defsubr (&Sminibufferp); + defsubr (&Sinnermost_minibuffer_p); + defsubr (&Sabort_minibuffers); defsubr (&Sminibuffer_prompt_end); defsubr (&Sminibuffer_contents); defsubr (&Sminibuffer_contents_no_properties); diff --git a/src/window.c b/src/window.c index 5e78aa400b..e025e0b082 100644 --- a/src/window.c +++ b/src/window.c @@ -2663,12 +2663,15 @@ static void decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames) { struct window *w = decode_live_window (*window); + Lisp_Object miniwin = XFRAME (w->frame)->minibuffer_window; XSETWINDOW (*window, w); /* MINIBUF nil may or may not include minibuffers. Decide if it does. */ if (NILP (*minibuf)) - *minibuf = minibuf_level ? minibuf_window : Qlambda; + *minibuf = this_minibuffer_depth (XWINDOW (miniwin)->contents) + ? miniwin + : Qlambda; else if (!EQ (*minibuf, Qt)) *minibuf = Qlambda; diff --git a/src/window.h b/src/window.h index 332cb3091f..79eb44e7a3 100644 --- a/src/window.h +++ b/src/window.h @@ -1124,10 +1124,6 @@ extern Lisp_Object echo_area_window; extern EMACS_INT command_loop_level; -/* Depth in minibuffer invocations. */ - -extern EMACS_INT minibuf_level; - /* Non-zero if we should redraw the mode lines on the next redisplay. Usually set to a unique small integer so we can track the main causes of full redisplays in `redisplay--mode-lines-cause'. */ commit a583c72305530f7d3ecc9ba50eefa70b6ddecdd9 Author: Lars Ingebrigtsen Date: Sun Jan 10 16:16:42 2021 +0100 Respect message-forward-ignored-headers more * lisp/gnus/message.el (message-forward-ignored-headers): Clarify doc string once again. (message-forward-make-body-mime): Remove headers when not encrypted (bug#45631). (message-forward-make-body): Pass in correct values. diff --git a/etc/NEWS b/etc/NEWS index 13ef7d8371..1a1f76d128 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -701,6 +701,13 @@ not. ** Message +--- +*** Respect 'message-forward-ignored-headers' more. +Previously, this variable would not be consulted if +'message-forward-show-mml' was nil. It's now always used, except if +'message-forward-show-mml' is 'best', and we're forwarding an +encrypted/signed message. + +++ *** Message now supports the OpenPGP header. To generate these headers, add the new function diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 3ff3d29b45..50e0218748 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -620,8 +620,8 @@ Done before generating the new subject of a forward." (defcustom message-forward-ignored-headers "^Content-Transfer-Encoding:\\|^X-Gnus" "All headers that match this regexp will be deleted when forwarding a message. -This variable is only consulted when forwarding \"normally\", not -when forwarding as MIME or the like. +This variable is not consulted when forwarding encrypted messages +and `message-forward-show-mml' is `best'. This may also be a list of regexps." :version "21.1" @@ -7638,7 +7638,8 @@ Optional DIGEST will use digest to forward." message-forward-included-headers) t nil t))))) -(defun message-forward-make-body-mime (forward-buffer &optional beg end) +(defun message-forward-make-body-mime (forward-buffer &optional beg end + remove-headers) (let ((b (point))) (insert "\n\n<#part type=message/rfc822 disposition=inline raw=t>\n") (save-restriction @@ -7648,6 +7649,8 @@ Optional DIGEST will use digest to forward." (goto-char (point-min)) (when (looking-at "From ") (replace-match "X-From-Line: ")) + (when remove-headers + (message-remove-ignored-headers (point-min) (point-max))) (goto-char (point-max))) (insert "<#/part>\n") ;; Consider there is no illegible text. @@ -7786,7 +7789,8 @@ is for the internal use." (message-signed-or-encrypted-p) (error t)))))) (message-forward-make-body-mml forward-buffer) - (message-forward-make-body-mime forward-buffer)) + (message-forward-make-body-mime + forward-buffer nil nil (not (eq message-forward-show-mml 'best)))) (message-forward-make-body-plain forward-buffer))) (message-position-point)) commit fa686f099800aac22dcdc39fb84ee2dcca8ffbf4 Author: Glenn Morris Date: Sun Jan 10 15:48:57 2021 +0100 Default python-shell-interpreter to python3 * lisp/progmodes/python.el (python-shell-interpreter): Default to python3 (bug#45655). diff --git a/etc/NEWS b/etc/NEWS index d655955ae2..13ef7d8371 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -347,6 +347,8 @@ is set to nil, this message is inhibited. ** Python mode +*** 'python-shell-interpreter' now defaults to python3 on systems with python3. + *** 'C-c C-r' can now be used on arbitrary regions. The command previously extended the start of the region to the start of the line, but will now actually send the marked region, as diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 0965fecfb7..d6c0a4d1db 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -2027,8 +2027,12 @@ position, else returns nil." :group 'python :safe 'stringp) -(defcustom python-shell-interpreter "python" +(defcustom python-shell-interpreter + (cond ((executable-find "python3") "python3") + ((executable-find "python") "python") + (t "python3")) "Default Python interpreter for shell." + :version "28.1" :type 'string :group 'python) commit 6858b74763cd784e4594b329633ac39c599c686d Author: David Edmondson Date: Sun Jan 10 15:45:07 2021 +0100 Fix example in the Gnus manual * doc/misc/gnus.texi (Score Variables): In the example showing how to use a list of functions for gnus-score-find-score-files-find-function, return a list of strings from the lambda rather than trying to call the string as a function (bug#45673). diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi index 797315d5b8..5a79cbc08f 100644 --- a/doc/misc/gnus.texi +++ b/doc/misc/gnus.texi @@ -20195,7 +20195,7 @@ Phu. For example, to do hierarchical scoring but use a non-server-specific overall score file, you could use the value @example -(list (lambda (group) ("all.SCORE")) +(list (lambda (group) (list "all.SCORE")) 'gnus-score-find-hierarchical) @end example commit 9717ba930975d772412c65b0e2dbb9258cf502bd Author: Lars Ingebrigtsen Date: Sun Jan 10 15:32:57 2021 +0100 Specify precedence in .authinfo files * doc/misc/auth.texi (Help for users): Mention placing more specific entries first (bug#45711). diff --git a/doc/misc/auth.texi b/doc/misc/auth.texi index d810f15c80..034004d1df 100644 --- a/doc/misc/auth.texi +++ b/doc/misc/auth.texi @@ -107,6 +107,18 @@ The @code{user} is the user name. It's known as @var{:user} in @code{auth-source-search} queries. You can also use @code{login} and @code{account}. +Matching entries are usually used in the order they appear, so placing +the most specific entries first in the file is a good idea. For +instance: + +@example +machine example.com login foobar password geheimnis port smtp +machine example.com login foobar password hemmelig +@end example + +Here we're using one password for the @code{smtp} service, and a +different one for all the other services. + You can also use this file to specify client certificates to use when setting up TLS connections. The format is: commit e186af261a4ed0fbcf8cbb35374b69582f42f25b Author: Lars Ingebrigtsen Date: Sun Jan 10 15:04:39 2021 +0100 Improve fill-region-as-paragraph when there's a fill prefix * lisp/textmodes/fill.el (fill-region-as-paragraph): Try to improve how line breaks are set on unbreakable text with a fill prefix area that has spaces within (bug#45720). diff --git a/lisp/textmodes/fill.el b/lisp/textmodes/fill.el index 3346c551d9..6681b03913 100644 --- a/lisp/textmodes/fill.el +++ b/lisp/textmodes/fill.el @@ -743,9 +743,16 @@ space does not end a sentence, so don't break a line there." ;; This is the actual filling loop. (goto-char from) - (let (linebeg) + (let ((first t) + linebeg) (while (< (point) to) - (setq linebeg (point)) + ;; On the first line, there may be text in the fill prefix + ;; zone. In that case, don't consider that area when + ;; trying to find a place to put a line break (bug#45720). + (if (not first) + (setq linebeg (point)) + (setq first nil + linebeg (+ (point) (length fill-prefix)))) (move-to-column (current-fill-column)) (if (when (< (point) to) ;; Find the position where we'll break the line. diff --git a/test/lisp/textmodes/fill-tests.el b/test/lisp/textmodes/fill-tests.el index f2c63a93d3..21efe62099 100644 --- a/test/lisp/textmodes/fill-tests.el +++ b/test/lisp/textmodes/fill-tests.el @@ -44,6 +44,37 @@ (fill-paragraph) (should (string= (buffer-string) "Abc\nd efg\n(h ijk).")))) +(ert-deftest fill-test-unbreakable-paragraph () + (with-temp-buffer + (let ((string "aaa = baaaaaaaaaaaaaaaaaaaaaaaaaaaa\n")) + (insert string) + (goto-char (point-min)) + (search-forward "b") + (let* ((pos (point)) + (beg (line-beginning-position)) + (end (line-end-position)) + (fill-prefix (make-string (- pos beg) ?\s)) + ;; `fill-column' is too small to accomodate the current line + (fill-column (- end beg 10))) + (fill-region-as-paragraph beg end nil nil pos)) + (should (equal (buffer-string) string))))) + +(ert-deftest fill-test-breakable-paragraph () + (with-temp-buffer + (let ((string "aaa = baaaaaaaa aaaaaaaaaa aaaaaaaaaa\n")) + (insert string) + (goto-char (point-min)) + (search-forward "b") + (let* ((pos (point)) + (beg (line-beginning-position)) + (end (line-end-position)) + (fill-prefix (make-string (- pos beg) ?\s)) + ;; `fill-column' is too small to accomodate the current line + (fill-column (- end beg 10))) + (fill-region-as-paragraph beg end nil nil pos)) + (should (equal + (buffer-string) + "aaa = baaaaaaaa aaaaaaaaaa\n aaaaaaaaaa\n"))))) (provide 'fill-tests) commit 918a5eae179f7998e4872cc5cf2f301a21c36587 Author: k3tu0isui Date: Sun Jan 10 14:36:51 2021 +0100 Make font locking work in mercury-mode * lisp/progmodes/prolog.el (prolog-font-lock-keywords): Work in all modes derived from prolog-mode (bug#45747). (mercury-mode): Set up variables based on the Prolog system (bug#45747). Copyright-paperwork-exempt: yes diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el index c8f6c12a3f..9f5f9ed6d3 100644 --- a/lisp/progmodes/prolog.el +++ b/lisp/progmodes/prolog.el @@ -1201,7 +1201,9 @@ Commands: (define-derived-mode mercury-mode prolog-mode "Prolog[Mercury]" "Major mode for editing Mercury programs. Actually this is just customized `prolog-mode'." - (setq-local prolog-system 'mercury)) + (setq-local prolog-system 'mercury) + ;; Run once more to set up based on `prolog-system' + (prolog-mode-variables)) ;;------------------------------------------------------------------- @@ -2082,7 +2084,7 @@ Argument BOUND is a buffer position limiting searching." (delq nil (cond - ((eq major-mode 'prolog-mode) + ((derived-mode-p 'prolog-mode) (list head-predicates head-predicates-1 commit 25dadca0d175aa7f9f1654314f90af64cdcb68fd Author: Basil L. Contovounesios Date: Sun Dec 27 14:21:50 2020 +0000 Hyperlink symbol names without word syntax in Help * lisp/emacs-lisp/lisp-mode.el (lisp-el-font-lock-keywords-2) (lisp-cl-font-lock-keywords-2): Allow single-character symbol names. * lisp/help-mode.el (help-xref-symbol-regexp): Also match symbol names starting with symbol syntax (bug#6601, bug#24309). * test/lisp/help-mode-tests.el (help-mode-tests-xref-button): Test hyperlink creation for function names without symbol syntax. diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 1ae216c1a2..8780c5dcd3 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -456,8 +456,7 @@ This will generate compile-time constants from BINDINGS." ("\\(\\\\\\)\\([^\"\\]\\)" (1 (elisp--font-lock-backslash) prepend)) ;; Words inside ‘’ and `' tend to be symbol names. - (,(concat "[`‘]\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)" - lisp-mode-symbol-regexp "\\)['’]") + (,(concat "[`‘]\\(" lisp-mode-symbol-regexp "\\)['’]") (1 font-lock-constant-face prepend)) ;; Constant values. (,(concat "\\_<:" lisp-mode-symbol-regexp "\\_>") @@ -507,8 +506,7 @@ This will generate compile-time constants from BINDINGS." (,(concat "(" cl-errs-re "\\_>") (1 font-lock-warning-face)) ;; Words inside ‘’ and `' tend to be symbol names. - (,(concat "[`‘]\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)" - lisp-mode-symbol-regexp "\\)['’]") + (,(concat "[`‘]\\(" lisp-mode-symbol-regexp "\\)['’]") (1 font-lock-constant-face prepend)) ;; Uninterned symbols, e.g., (defpackage #:my-package ...) ;; must come before keywords below to have effect diff --git a/lisp/help-mode.el b/lisp/help-mode.el index cd08b2b2ba..7043f12c9a 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -357,8 +357,7 @@ Commands: "\\(symbol\\|program\\|property\\)\\|" ; Don't link "\\(source \\(?:code \\)?\\(?:of\\|for\\)\\)\\)" "[ \t\n]+\\)?" - ;; Note starting with word-syntax character: - "['`‘]\\(\\sw\\(\\sw\\|\\s_\\)+\\|`\\)['’]")) + "['`‘]\\(\\(?:\\sw\\|\\s_\\)+\\|`\\)['’]")) "Regexp matching doc string references to symbols. The words preceding the quoted symbol can be used in doc strings to diff --git a/test/lisp/help-mode-tests.el b/test/lisp/help-mode-tests.el index e0e82c9cc1..43db59d4b1 100644 --- a/test/lisp/help-mode-tests.el +++ b/test/lisp/help-mode-tests.el @@ -72,14 +72,19 @@ Lisp concepts such as car, cdr, cons cell and list.") #'info))))) (ert-deftest help-mode-tests-xref-button () - (with-temp-buffer - (insert "See also the function ‘interactive’.") - (string-match help-xref-symbol-regexp (buffer-string)) - (help-xref-button 8 'help-function) - (should-not (button-at 22)) - (should-not (button-at 35)) - (let ((button (button-at 30))) - (should (eq (button-type button) 'help-function))))) + (let* ((fmt "See also the function ‘%s’.") + ;; 1+ translates string index to buffer position. + (beg (1+ (string-search "%" fmt)))) + (with-temp-buffer + (dolist (fn '(interactive \` = + - * / %)) + (erase-buffer) + (insert (format fmt fn)) + (goto-char (point-min)) + (re-search-forward help-xref-symbol-regexp) + (help-xref-button 8 'help-function) + (should-not (button-at (1- beg))) + (should-not (button-at (+ beg (length (symbol-name fn))))) + (should (eq (button-type (button-at beg)) 'help-function)))))) (ert-deftest help-mode-tests-insert-xref-button () (with-temp-buffer commit 4c55eeee39c05aa56df5ffdca6ff5b233607727c Author: Omar Polo Date: Sun Jan 10 14:25:22 2021 +0100 Add support for 'process-attributes' on OpenBSD * src/sysdep.c (make_lisp_timeval): (system_process_attributes): Implement for OpenBSD (bug#45729). diff --git a/etc/NEWS b/etc/NEWS index cd7e0574bf..d655955ae2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1513,6 +1513,9 @@ that makes it a valid button. ** Miscellaneous +--- +*** 'process-attributes' now works under OpenBSD, too. + +++ *** New button face 'flat-button'. This is a plain 2D button, but uses the background color instead of diff --git a/src/sysdep.c b/src/sysdep.c index 6ede06b1aa..a49f1775eb 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -53,6 +53,10 @@ along with GNU Emacs. If not, see . */ # include #endif +#if defined __OpenBSD__ +# include +#endif + #ifdef DARWIN_OS # include #endif @@ -2972,6 +2976,14 @@ make_lisp_timeval (struct timeval t) return make_lisp_time (timeval_to_timespec (t)); } +#elif defined __OpenBSD__ + +static Lisp_Object +make_lisp_timeval (long sec, long usec) +{ + return make_lisp_time(make_timespec(sec, usec * 1000)); +} + #endif #ifdef GNU_LINUX @@ -3661,6 +3673,189 @@ system_process_attributes (Lisp_Object pid) return attrs; } +#elif defined __OpenBSD__ + +Lisp_Object +system_process_attributes (Lisp_Object pid) +{ + int proc_id, nentries, fscale, i; + int pagesize = getpagesize (); + int mib[6]; + size_t len; + double pct; + char *ttyname, args[ARG_MAX]; + struct kinfo_proc proc; + struct passwd *pw; + struct group *gr; + struct timespec t; + struct uvmexp uvmexp; + + Lisp_Object attrs = Qnil; + Lisp_Object decoded_comm; + + CHECK_NUMBER (pid); + CONS_TO_INTEGER (pid, int, proc_id); + + len = sizeof proc; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = proc_id; + mib[4] = len; + mib[5] = 1; + if (sysctl (mib, 6, &proc, &len, NULL, 0) != 0) + return attrs; + + attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (proc.p_uid)), attrs); + + block_input (); + pw = getpwuid (proc.p_uid); + unblock_input (); + if (pw) + attrs = Fcons (Fcons (Quser, build_string(pw->pw_name)), attrs); + + attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER(proc.p_svgid)), attrs); + + block_input (); + gr = getgrgid (proc.p_svgid); + unblock_input (); + if (gr) + attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); + + AUTO_STRING (comm, proc.p_comm); + decoded_comm = code_convert_string_norecord (comm, Vlocale_coding_system, 0); + attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs); + + { + char state[2] = {'\0', '\0'}; + switch (proc.p_stat) { + case SIDL: + state[0] = 'I'; + break; + case SRUN: + state[0] = 'R'; + break; + case SSLEEP: + state[0] = 'S'; + break; + case SSTOP: + state[0] = 'T'; + break; + case SZOMB: + state[0] = 'Z'; + break; + case SDEAD: + state[0] = 'D'; + break; + } + attrs = Fcons (Fcons (Qstate, build_string (state)), attrs); + } + + attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (proc.p_ppid)), attrs); + attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (proc.p_gid)), attrs); + attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (proc.p_sid)), attrs); + + block_input (); + ttyname = proc.p_tdev == NODEV ? NULL : devname (proc.p_tdev, S_IFCHR); + unblock_input (); + if (ttyname) + attrs = Fcons (Fcons (Qttname, build_string (ttyname)), attrs); + + attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (proc.p_tpgid)), attrs); + attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (proc.p_uru_minflt)), + attrs); + attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (proc.p_uru_majflt)), + attrs); + + /* FIXME: missing cminflt, cmajflt. */ + + attrs = Fcons (Fcons (Qutime, make_lisp_timeval (proc.p_uutime_sec, + proc.p_uutime_usec)), + attrs); + attrs = Fcons (Fcons (Qstime, make_lisp_timeval (proc.p_ustime_sec, + proc.p_ustime_usec)), + attrs); + t = timespec_add (make_timespec (proc.p_uutime_sec, + proc.p_uutime_usec * 1000), + make_timespec (proc.p_ustime_sec, + proc.p_ustime_usec * 1000)); + attrs = Fcons (Fcons (Qtime, make_lisp_time (t)), attrs); + + attrs = Fcons (Fcons (Qcutime, make_lisp_timeval (proc.p_uctime_sec, + proc.p_uctime_usec)), + attrs); + + /* FIXME: missing cstime and thus ctime. */ + + attrs = Fcons (Fcons (Qpri, make_fixnum (proc.p_priority)), attrs); + attrs = Fcons (Fcons (Qnice, make_fixnum (proc.p_nice)), attrs); + + /* FIXME: missing thcount (thread count) */ + + attrs = Fcons (Fcons (Qstart, make_lisp_timeval (proc.p_ustart_sec, + proc.p_ustart_usec)), + attrs); + + len = (proc.p_vm_tsize + proc.p_vm_dsize + proc.p_vm_ssize) * pagesize >> 10; + attrs = Fcons (Fcons (Qvsize, make_fixnum (len)), attrs); + + attrs = Fcons (Fcons (Qrss, make_fixnum (proc.p_vm_rssize * pagesize >> 10)), + attrs); + + t = make_timespec (proc.p_ustart_sec, + proc.p_ustart_usec * 1000); + t = timespec_sub (current_timespec (), t); + attrs = Fcons (Fcons (Qetime, make_lisp_time (t)), attrs); + + len = sizeof (fscale); + mib[0] = CTL_KERN; + mib[1] = KERN_FSCALE; + if (sysctl (mib, 2, &fscale, &len, NULL, 0) != -1) + { + pct = (double)proc.p_pctcpu / fscale * 100.0; + attrs = Fcons (Fcons (Qpcpu, make_float (pct)), attrs); + } + + len = sizeof (uvmexp); + mib[0] = CTL_VM; + mib[1] = VM_UVMEXP; + if (sysctl (mib, 2, &uvmexp, &len, NULL, 0) != -1) + { + pct = (100.0 * (double)proc.p_vm_rssize / uvmexp.npages); + attrs = Fcons (Fcons (Qpmem, make_float (pct)), attrs); + } + + len = sizeof args; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC_ARGS; + mib[2] = proc_id; + mib[3] = KERN_PROC_ARGV; + if (sysctl (mib, 4, &args, &len, NULL, 0) == 0 && len != 0) + { + char **argv = (char**)args; + + /* concatenate argv reusing the existing storage storage. + sysctl(8) guarantees that "the buffer pointed to by oldp is + filled with an array of char pointers followed by the strings + themselves." */ + for (i = 0; argv[i] != NULL; ++i) + { + if (argv[i+1] != NULL) + { + len = strlen (argv[i]); + argv[i][len] = ' '; + } + } + + AUTO_STRING (comm, *argv); + decoded_comm = code_convert_string_norecord (comm, + Vlocale_coding_system, 0); + attrs = Fcons (Fcons (Qargs, decoded_comm), attrs); + } + + return attrs; +} + #elif defined DARWIN_OS Lisp_Object commit 5960e9cf5770dab2bd3abfb8640f6553bfa1b190 Author: Basil L. Contovounesios Date: Sun Jan 10 13:20:51 2021 +0000 ; * lisp/custom.el (defcustom): Fix last change. diff --git a/lisp/custom.el b/lisp/custom.el index bc155d32dd..0c82df9b45 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -237,8 +237,8 @@ The following keywords are meaningful: :type VALUE should be a widget type for editing the symbol's value. Every `defcustom' should specify a value for this keyword. - See `(elisp) Customization Types' for a list of base types - and useful composite types. + See Info node `(elisp) Customization Types' for a list of + base types and useful composite types. :options VALUE should be a list of valid members of the widget type. :initialize VALUE should be a function used to initialize the commit 13bd909591e9c1cf0228750b2d4a9e4364f61cc9 Author: Pedro Andres Aranda Gutierrez Date: Sun Jan 10 14:10:18 2021 +0100 Add support for flat buttons * src/xfaces.c (Finternal_set_lisp_face_attribute): (realize_gui_face): Add support for `flat-button' (bug#45735). Copyright-paperwork-exempt: yes diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index b149a665fe..93e935ccf8 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -2485,15 +2485,16 @@ avoiding any increase in the character height or width. For simplification the width could be specified with only a single number @var{n} instead of a list, such case is equivalent to @code{((abs @var{n}) . @var{n})}. -The value @var{color} specifies the color to draw with. The default is -the foreground color of the face for simple boxes, and the background -color of the face for 3D boxes. - The value @var{style} specifies whether to draw a 3D box. If it is -@code{released-button}, the box looks like a 3D button that is not being -pressed. If it is @code{pressed-button}, the box looks like a 3D button -that is being pressed. If it is @code{nil} or omitted, a plain 2D box -is used. +@code{released-button}, the box looks like a 3D button that is not +being pressed. If it is @code{pressed-button}, the box looks like a +3D button that is being pressed. If it is @code{nil}, +@code{flat-button} or omitted, a plain 2D box is used. + +The value @var{color} specifies the color to draw with. The default +is the background color of the face for 3D boxes and +@code{flat-button}, and the foreground color of the face for other +boxes. @end table @item :inverse-video diff --git a/etc/NEWS b/etc/NEWS index eaaf9bfb0e..cd7e0574bf 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1514,7 +1514,9 @@ that makes it a valid button. ** Miscellaneous +++ -*** 'add-to-ordered-list' can now take a test predicate. +*** New button face 'flat-button'. +This is a plain 2D button, but uses the background color instead of +the foreground color. +++ *** New predicate functions 'length<', 'length>' and 'length='. diff --git a/src/xfaces.c b/src/xfaces.c index b3b19a9cb2..258b365eda 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -3293,7 +3293,8 @@ FRAME 0 means change the face on all frames, and change the default } else if (EQ (k, QCstyle)) { - if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button)) + if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button) + && !EQ(v, Qflat_button)) break; } else @@ -6031,6 +6032,10 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] face->box = FACE_RAISED_BOX; else if (EQ (value, Qpressed_button)) face->box = FACE_SUNKEN_BOX; + else if (EQ (value, Qflat_button)) { + face->box = FACE_SIMPLE_BOX; + face->box_color = face->background; + } } } } @@ -6919,6 +6924,7 @@ syms_of_xfaces (void) DEFSYM (Qwave, "wave"); DEFSYM (Qreleased_button, "released-button"); DEFSYM (Qpressed_button, "pressed-button"); + DEFSYM (Qflat_button, "flat-button"); DEFSYM (Qnormal, "normal"); DEFSYM (Qextra_light, "extra-light"); DEFSYM (Qlight, "light"); commit e62f71988f8e75de676ea5e0775c97eab1d8793a Author: Daniel Martín Date: Sun Jan 10 13:45:44 2021 +0100 Minor shortdoc link improvements * lisp/emacs-lisp/shortdoc.el (shortdoc--display-function): Use describe-function as a fallback link when a function is not documented in any Info manual. Also make the link respond to mouse-1, like the rest of *Help* links, and add a proper help-echo property. * lisp/help-fns.el (help-fns--mention-shortdoc-groups): Same link improvement as described before, this time for the shortdoc groups (bug#45750). diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index 698467e939..39e69f5aab 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -1126,12 +1126,21 @@ There can be any number of :example/:result elements." (insert (propertize "(" 'shortdoc-function t)) (if (plist-get data :no-manual) - (insert (symbol-name function)) + (insert-text-button + (symbol-name function) + 'face 'button + 'action (lambda (_) + (describe-function function)) + 'follow-link t + 'help-echo (purecopy "mouse-1, RET: describe function")) (insert-text-button (symbol-name function) 'face 'button 'action (lambda (_) - (info-lookup-symbol function 'emacs-lisp-mode)))) + (info-lookup-symbol function 'emacs-lisp-mode)) + 'follow-link t + 'help-echo (purecopy "mouse-1, RET: show \ +function's documentation in the Info manual"))) (setq arglist-start (point)) (insert ")\n") ;; Doc string. diff --git a/lisp/help-fns.el b/lisp/help-fns.el index afbb5e3649..d559221a82 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -713,7 +713,9 @@ FILE is the file where FUNCTION was probably defined." (insert-text-button (symbol-name group) 'action (lambda (_) - (shortdoc-display-group group)))) + (shortdoc-display-group group)) + 'follow-link t + 'help-echo (purecopy "mouse-1, RET: show documentation group"))) groups) (insert (if (= (length groups) 1) " group.\n" commit 14a1a84a33a500d49ce23124f549ff28bd007f41 Author: Lars Ingebrigtsen Date: Sun Jan 10 13:43:12 2021 +0100 Add a link to the manual from the defcustom doc string * lisp/custom.el (defcustom): Add a link to the manual for the :type element. diff --git a/lisp/custom.el b/lisp/custom.el index d9d0898dcb..bc155d32dd 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -237,6 +237,8 @@ The following keywords are meaningful: :type VALUE should be a widget type for editing the symbol's value. Every `defcustom' should specify a value for this keyword. + See `(elisp) Customization Types' for a list of base types + and useful composite types. :options VALUE should be a list of valid members of the widget type. :initialize VALUE should be a function used to initialize the commit b84b6897464f5af69d24a4efa95704ab51b3cd7b Author: Lars Ingebrigtsen Date: Sun Jan 10 13:30:25 2021 +0100 Revert recent mm-with-part change * lisp/gnus/mm-decode.el (mm-with-part): Revert 23a887e426f81033b0de2f4c93a8525cb31c28da -- this is the wrong place to handle this peculiarity. diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el index 2b0b61bfac..61946aa581 100644 --- a/lisp/gnus/mm-decode.el +++ b/lisp/gnus/mm-decode.el @@ -1264,20 +1264,11 @@ in HANDLE." (when (and (mm-handle-buffer handle) (buffer-name (mm-handle-buffer handle))) (with-temp-buffer - (if (and (eq (mm-handle-encoding handle) '8bit) - (with-current-buffer (mm-handle-buffer handle) - enable-multibyte-characters)) - ;; Due to unfortunate historical reasons, we may have a - ;; multibyte buffer here, but if it's using an 8bit - ;; Content-Transfer-Encoding, then work around that by - ;; just ignoring the situation. - (insert-buffer-substring (mm-handle-buffer handle)) - ;; Do the decoding. - (mm-disable-multibyte) - (insert-buffer-substring (mm-handle-buffer handle)) - (mm-decode-content-transfer-encoding - (mm-handle-encoding handle) - (mm-handle-media-type handle))) + (mm-disable-multibyte) + (insert-buffer-substring (mm-handle-buffer handle)) + (mm-decode-content-transfer-encoding + (mm-handle-encoding handle) + (mm-handle-media-type handle)) ,@forms)))) (put 'mm-with-part 'lisp-indent-function 1) (put 'mm-with-part 'edebug-form-spec '(body)) diff --git a/test/lisp/gnus/mm-decode-tests.el b/test/lisp/gnus/mm-decode-tests.el index 6e8fae6eaf..7d059cb3f8 100644 --- a/test/lisp/gnus/mm-decode-tests.el +++ b/test/lisp/gnus/mm-decode-tests.el @@ -70,22 +70,6 @@ 'charset))) "ääää\n")))))) -(ert-deftest test-mm-with-part-multibyte () - (with-temp-buffer - (set-buffer-multibyte t) - (nnheader-insert-file-contents (ert-resource-file "8bit-multipart.bin")) - (while (search-forward "\r\n" nil t) - (replace-match "\n")) - (let ((handle (mm-dissect-buffer))) - (pop handle) - (let ((part (pop handle))) - (should (equal (decode-coding-string - (mm-with-part part - (buffer-string)) - (intern (mail-content-type-get (mm-handle-type part) - 'charset))) - "ääää\n")))))) - (ert-deftest test-mm-dissect-buffer-win1252 () (with-temp-buffer (set-buffer-multibyte nil) commit 2c03bdc887488537ef111cc44d5506eafc282ad5 Merge: aa6ee3302f 4ad8fc61e7 Author: Michael Albinus Date: Sun Jan 10 13:27:10 2021 +0100 Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs commit aa6ee3302f81f2e1727d06f9b2a7e64d1390fdaa Author: Michael Albinus Date: Sun Jan 10 13:26:29 2021 +0100 Rework parts of Tramp's insert-directory, bug#45691 * lisp/net/tramp-sh.el (tramp-sh-handle-insert-directory): Fix some unibyte/multibyte inconsistencies. (Bug#45691) * test/lisp/net/tramp-tests.el (tramp-test17-insert-directory-one-file): New test. diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index b43b4485fe..72873157f0 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -2601,7 +2601,7 @@ The method used must be an out-of-band method." (t nil))))))))) (defun tramp-sh-handle-insert-directory - (filename switches &optional wildcard full-directory-p) + (filename switches &optional wildcard full-directory-p) "Like `insert-directory' for Tramp files." (setq filename (expand-file-name filename)) (unless switches (setq switches "")) @@ -2636,66 +2636,65 @@ The method used must be an out-of-band method." v 4 "Inserting directory `ls %s %s', wildcard %s, fulldir %s" switches filename (if wildcard "yes" "no") (if full-directory-p "yes" "no")) - ;; If `full-directory-p', we just say `ls -l FILENAME'. - ;; Else we chdir to the parent directory, then say `ls -ld BASENAME'. + ;; If `full-directory-p', we just say `ls -l FILENAME'. Else we + ;; chdir to the parent directory, then say `ls -ld BASENAME'. (if full-directory-p (tramp-send-command - v - (format "%s %s %s 2>%s" - (tramp-get-ls-command v) - switches - (if wildcard - localname - (tramp-shell-quote-argument (concat localname "."))) - (tramp-get-remote-null-device v))) + v (format "%s %s %s 2>%s" + (tramp-get-ls-command v) + switches + (if wildcard + localname + (tramp-shell-quote-argument (concat localname "."))) + (tramp-get-remote-null-device v))) (tramp-barf-unless-okay - v - (format "cd %s" (tramp-shell-quote-argument - (tramp-run-real-handler - #'file-name-directory (list localname)))) + v (format "cd %s" (tramp-shell-quote-argument + (tramp-run-real-handler + #'file-name-directory (list localname)))) "Couldn't `cd %s'" (tramp-shell-quote-argument (tramp-run-real-handler #'file-name-directory (list localname)))) (tramp-send-command - v - (format "%s %s %s 2>%s" - (tramp-get-ls-command v) - switches - (if (or wildcard - (zerop (length - (tramp-run-real-handler - #'file-name-nondirectory (list localname))))) - "" - (tramp-shell-quote-argument - (tramp-run-real-handler - #'file-name-nondirectory (list localname)))) - (tramp-get-remote-null-device v)))) - - (save-restriction - (let ((beg (point)) - (emc enable-multibyte-characters)) - (narrow-to-region (point) (point)) - ;; We cannot use `insert-buffer-substring' because the Tramp - ;; buffer changes its contents before insertion due to calling - ;; `expand-file-name' and alike. - (insert - (with-current-buffer (tramp-get-buffer v) - (buffer-string))) - - ;; Check for "--dired" output. We must enable unibyte - ;; strings, because the "--dired" output counts in bytes. - (set-buffer-multibyte nil) + v (format "%s %s %s 2>%s" + (tramp-get-ls-command v) + switches + (if (or wildcard + (zerop (length + (tramp-run-real-handler + #'file-name-nondirectory (list localname))))) + "" + (tramp-shell-quote-argument + (tramp-run-real-handler + #'file-name-nondirectory (list localname)))) + (tramp-get-remote-null-device v)))) + + (let ((beg-marker (point-marker)) + (end-marker (point-marker)) + (emc enable-multibyte-characters)) + (set-marker-insertion-type beg-marker nil) + (set-marker-insertion-type end-marker t) + ;; We cannot use `insert-buffer-substring' because the Tramp + ;; buffer changes its contents before insertion due to calling + ;; `expand-file-name' and alike. + (insert (with-current-buffer (tramp-get-buffer v) (buffer-string))) + + ;; We must enable unibyte strings, because the "--dired" + ;; output counts in bytes. + (set-buffer-multibyte nil) + (save-restriction + (narrow-to-region beg-marker end-marker) + ;; Check for "--dired" output. (forward-line -2) (when (looking-at-p "//SUBDIRED//") (forward-line -1)) (when (looking-at "//DIRED//\\s-+") - (let ((databeg (match-end 0)) + (let ((beg (match-end 0)) (end (point-at-eol))) ;; Now read the numeric positions of file names. - (goto-char databeg) + (goto-char beg) (while (< (point) end) - (let ((start (+ beg (read (current-buffer)))) - (end (+ beg (read (current-buffer))))) + (let ((start (+ (point-min) (read (current-buffer)))) + (end (+ (point-min) (read (current-buffer))))) (if (memq (char-after end) '(?\n ?\ )) ;; End is followed by \n or by " -> ". (put-text-property start end 'dired-filename t)))))) @@ -2703,18 +2702,18 @@ The method used must be an out-of-band method." (goto-char (point-at-bol)) (while (looking-at "//") (forward-line 1) - (delete-region (match-beginning 0) (point))) - ;; Reset multibyte if needed. - (set-buffer-multibyte emc) + (delete-region (match-beginning 0) (point)))) + ;; Reset multibyte if needed. + (set-buffer-multibyte emc) + (save-restriction + (narrow-to-region beg-marker end-marker) ;; Some busyboxes are reluctant to discard colors. (unless (string-match-p "color" (tramp-get-connection-property v "ls" "")) - (save-excursion - (goto-char beg) - (while - (re-search-forward tramp-display-escape-sequence-regexp nil t) - (replace-match "")))) + (goto-char (point-min)) + (while (re-search-forward tramp-display-escape-sequence-regexp nil t) + (replace-match ""))) ;; Now decode what read if necessary. Stolen from `insert-directory'. (let ((coding (or coding-system-for-read @@ -2729,36 +2728,32 @@ The method used must be an out-of-band method." ;; If no coding system is specified or detection is ;; requested, detect the coding. (if (eq (coding-system-base coding) 'undecided) - (setq coding (detect-coding-region beg (point) t))) - (if (not (eq (coding-system-base coding) 'undecided)) - (save-restriction - (setq coding-no-eol - (coding-system-change-eol-conversion coding 'unix)) - (narrow-to-region beg (point)) - (goto-char (point-min)) - (while (not (eobp)) - (setq pos (point) - val (get-text-property (point) 'dired-filename)) - (goto-char (next-single-property-change - (point) 'dired-filename nil (point-max))) - ;; Force no eol conversion on a file name, so - ;; that CR is preserved. - (decode-coding-region pos (point) - (if val coding-no-eol coding)) - (if val - (put-text-property pos (point) - 'dired-filename t))))))) + (setq coding (detect-coding-region (point-min) (point) t))) + (unless (eq (coding-system-base coding) 'undecided) + (setq coding-no-eol + (coding-system-change-eol-conversion coding 'unix)) + (goto-char (point-min)) + (while (not (eobp)) + (setq pos (point) + val (get-text-property (point) 'dired-filename)) + (goto-char (next-single-property-change + (point) 'dired-filename nil (point-max))) + ;; Force no eol conversion on a file name, so that + ;; CR is preserved. + (decode-coding-region + pos (point) (if val coding-no-eol coding)) + (if val (put-text-property pos (point) 'dired-filename t)))))) ;; The inserted file could be from somewhere else. (when (and (not wildcard) (not full-directory-p)) (goto-char (point-max)) (when (file-symlink-p filename) - (goto-char (search-backward "->" beg 'noerror))) + (goto-char (search-backward "->" (point-min) 'noerror))) (search-backward (if (directory-name-p filename) "." (file-name-nondirectory filename)) - beg 'noerror) + (point-min) 'noerror) (replace-match (file-relative-name filename) t)) ;; Try to insert the amount of free space. @@ -2769,9 +2764,11 @@ The method used must be an out-of-band method." ;; Replace "total" with "total used", to avoid confusion. (replace-match "\\1 used in directory") (end-of-line) - (insert " available " available))) + (insert " available " available)))) - (goto-char (point-max))))))) + (prog1 (goto-char end-marker) + (set-marker beg-marker nil) + (set-marker end-marker nil)))))) ;; Canonicalization of file names. diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index e1cb9939f2..3995006898 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -3067,9 +3067,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'." (regexp-opt (directory-files tmp-name1)) (length (directory-files tmp-name1))))))) - ;; Check error case. We do not check for the error type, - ;; because ls-lisp returns `file-error', and native Tramp - ;; returns `file-missing'. + ;; Check error case. (delete-directory tmp-name1 'recursive) (with-temp-buffer (should-error @@ -3188,6 +3186,59 @@ This tests also `file-directory-p' and `file-accessible-directory-p'." (ignore-errors (delete-directory tmp-name1 'recursive)) (ignore-errors (delete-directory tmp-name2 'recursive)))))) +;; The following test is inspired by Bug#45691. +(ert-deftest tramp-test17-insert-directory-one-file () + "Check `insert-directory' inside directory listing." + (skip-unless (tramp--test-enabled)) + + (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil))) + (let* ((tmp-name1 + (expand-file-name (tramp--test-make-temp-name nil quoted))) + (tmp-name2 (expand-file-name "foo" tmp-name1)) + (tmp-name3 (expand-file-name "bar" tmp-name1)) + (dired-copy-preserve-time t) + (dired-recursive-copies 'top) + dired-copy-dereference + buffer) + (unwind-protect + (progn + (make-directory tmp-name1) + (write-region "foo" nil tmp-name2) + (should (file-directory-p tmp-name1)) + (should (file-exists-p tmp-name2)) + + ;; Check, that `insert-directory' works properly. + (with-current-buffer + (setq buffer (dired-noselect tmp-name1 "--dired -al")) + (read-only-mode -1) + (goto-char (point-min)) + (while (not (or (eobp) + (string-equal + (dired-get-filename 'localp 'no-error) + (file-name-nondirectory tmp-name2)))) + (forward-line 1)) + (should-not (eobp)) + (copy-file tmp-name2 tmp-name3) + (insert-directory + (file-name-nondirectory tmp-name3) "--dired -al -d") + ;; Point shall still be the recent file. + (should + (string-equal + (dired-get-filename 'localp 'no-error) + (file-name-nondirectory tmp-name2))) + (should-not (re-search-forward "dired" nil t)) + ;; The copied file has been inserted the line before. + (forward-line -1) + (should + (string-equal + (dired-get-filename 'localp 'no-error) + (file-name-nondirectory tmp-name3)))) + (kill-buffer buffer)) + + ;; Cleanup. + (ignore-errors (kill-buffer buffer)) + (ignore-errors (delete-directory tmp-name1 'recursive)))))) + ;; Method "smb" supports `make-symbolic-link' only if the remote host ;; has CIFS capabilities. tramp-adb.el, tramp-gvfs.el and ;; tramp-rclone.el do not support symbolic links at all. commit 4ad8fc61e7c47831e596b8ea9d5cb985cabfe3cf Author: Lars Ingebrigtsen Date: Sun Jan 10 13:20:49 2021 +0100 Add more mm-decode tests diff --git a/test/lisp/gnus/mm-decode-resources/win1252-multipart.bin b/test/lisp/gnus/mm-decode-resources/win1252-multipart.bin new file mode 100644 index 0000000000..d3c5026dcc --- /dev/null +++ b/test/lisp/gnus/mm-decode-resources/win1252-multipart.bin @@ -0,0 +1,44 @@ +To: example +From: example +Date: Tue, 5 Jan 2021 10:30:34 +0100 +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------FB569A4368539497CC91D1DC" +Content-Language: fr +Subject: test + +--------------FB569A4368539497CC91D1DC +Content-Type: multipart/alternative; + boundary="------------61C81A7DC7592E4C6F856A85" + + +--------------61C81A7DC7592E4C6F856A85 +Content-Type: text/plain; charset=windows-1252; format=flowed +Content-Transfer-Encoding: 8bit + +dj rat + +--------------61C81A7DC7592E4C6F856A85 +Content-Type: text/html; charset=windows-1252 +Content-Transfer-Encoding: 8bit + + + + + + + dj rat + + + +--------------61C81A7DC7592E4C6F856A85-- + +--------------FB569A4368539497CC91D1DC +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: inline + +mailing list signature + +--------------FB569A4368539497CC91D1DC-- + diff --git a/test/lisp/gnus/mm-decode-tests.el b/test/lisp/gnus/mm-decode-tests.el index 74591f919d..6e8fae6eaf 100644 --- a/test/lisp/gnus/mm-decode-tests.el +++ b/test/lisp/gnus/mm-decode-tests.el @@ -86,4 +86,33 @@ 'charset))) "ääää\n")))))) +(ert-deftest test-mm-dissect-buffer-win1252 () + (with-temp-buffer + (set-buffer-multibyte nil) + (insert-file-contents-literally (ert-resource-file "win1252-multipart.bin")) + (let ((handle (mm-dissect-buffer))) + (should (equal (mm-handle-media-type handle) "multipart/mixed")) + ;; Skip multipart type. + (pop handle) + (setq handle (car handle)) + (pop handle) + (let ((part (pop handle))) + (should (equal (mm-handle-media-type part) "text/plain")) + (should (eq (mm-handle-encoding part) '8bit)) + (with-current-buffer (mm-handle-buffer part) + (should (equal (decode-coding-string + (buffer-string) + (intern (mail-content-type-get (mm-handle-type part) + 'charset))) + "déjà raté\n")))) + (let ((part (pop handle))) + (should (equal (mm-handle-media-type part) "text/html")) + (should (eq (mm-handle-encoding part) '8bit)) + (with-current-buffer (mm-handle-buffer part) + (should (equal (decode-coding-string + (buffer-string) + (intern (mail-content-type-get (mm-handle-type part) + 'charset))) + "\n \n \n \n \n déjà raté\n \n\n"))))))) + ;;; mm-decode-tests.el ends here commit ac9c4ca8c9456ea4e0cbfea2317579ac57b13289 Author: Stefan Kangas Date: Sat Jan 9 12:03:12 2021 +0100 * lisp/subr.el (global-map): Doc fix; add cross-reference. diff --git a/lisp/subr.el b/lisp/subr.el index 260202945b..6d3ea45c1a 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1330,7 +1330,9 @@ The normal global definition of the character C-x indirects to this keymap.") map) "Default global keymap mapping Emacs keyboard input into commands. The value is a keymap that is usually (but not necessarily) Emacs's -global map.") +global map. + +See also `current-global-map'.") (use-global-map global-map) commit 09ee2d0095b6cbc4e28e417d3c42e61b319a2745 Author: F. Jason Park Date: Sun Jan 10 12:40:53 2021 +0100 Create new test file for socks.el * test/lisp/net/socks-tests.el (socks-tests-auth-filter-url-http): Add SOCKS5 authentication test and fake server (bug#45162). diff --git a/test/lisp/net/socks-tests.el b/test/lisp/net/socks-tests.el new file mode 100644 index 0000000000..b378ed2964 --- /dev/null +++ b/test/lisp/net/socks-tests.el @@ -0,0 +1,103 @@ +;;; socks-tests.el --- tests for SOCKS -*- coding: utf-8; lexical-binding: t; -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;;; Code: + +(require 'socks) +(require 'url-http) + +(defvar socks-tests-canned-server-port nil) + +(defun socks-tests-canned-server-create (verbatim patterns) + "Create a fake SOCKS server and return the process. + +`VERBATIM' and `PATTERNS' are dotted alists containing responses. +Requests are tried in order. On failure, an error is raised." + (let* ((buf (generate-new-buffer "*canned-socks-server*")) + (filt (lambda (proc line) + (let ((resp (or (assoc-default line verbatim + (lambda (k s) ; s is line + (string= (concat k) s))) + (assoc-default line patterns + (lambda (p s) + (string-match-p p s)))))) + (unless resp + (error "Unknown request: %s" line)) + (let ((print-escape-control-characters t)) + (princ (format "<- %s\n" (prin1-to-string line)) buf) + (princ (format "-> %s\n" (prin1-to-string resp)) buf)) + (process-send-string proc (concat resp))))) + (srv (make-network-process :server 1 + :buffer buf + :filter filt + :name "server" + :family 'ipv4 + :host 'local + :service socks-tests-canned-server-port))) + (set-process-query-on-exit-flag srv nil) + (princ (format "[%s] Listening on localhost:10080\n" srv) buf) + srv)) + +;; Add ([5 3 0 1 2] . [5 2]) to the `verbatim' list below to validate +;; against curl 7.71 with the following options: +;; $ curl --verbose -U foo:bar --proxy socks5h://127.0.0.1:10080 example.com +;; +;; If later implementing version 4a, try these: +;; [4 1 0 80 0 0 0 1 0 ?e ?x ?a ?m ?p ?l ?e ?. ?c ?o ?m 0] . [0 90 0 0 0 0 0 0] +;; $ curl --verbose --proxy socks4a://127.0.0.1:10080 example.com + +(ert-deftest socks-tests-auth-filter-url-http () + "Verify correct handling of SOCKS5 user/pass authentication." + (let* ((socks-server '("server" "127.0.0.1" 10080 5)) + (socks-username "foo") + (socks-password "bar") + (url-gateway-method 'socks) + (url (url-generic-parse-url "http://example.com")) + (verbatim '(([5 2 0 2] . [5 2]) + ([1 3 ?f ?o ?o 3 ?b ?a ?r] . [1 0]) + ([5 1 0 3 11 ?e ?x ?a ?m ?p ?l ?e ?. ?c ?o ?m 0 80] + . [5 0 0 1 0 0 0 0 0 0]))) + (patterns + `(("^GET /" . ,(concat "HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain; charset=UTF-8\r\n" + "Content-Length: 13\r\n\r\n" + "Hello World!\n")))) + (socks-tests-canned-server-port 10080) + (server (socks-tests-canned-server-create verbatim patterns)) + (tries 10) + ;; + done + ;; + (cb (lambda (&rest _r) + (goto-char (point-min)) + (should (search-forward "Hello World" nil t)) + (setq done t))) + (buf (url-http url cb '(nil)))) + (ert-info ("Connect to HTTP endpoint over SOCKS5 with USER/PASS method") + (while (and (not done) (< 0 (cl-decf tries))) ; cl-lib via url-http + (sleep-for 0.1))) + (should done) + (delete-process server) + (kill-buffer (process-buffer server)) + (kill-buffer buf) + (ignore url-gateway-method))) + +;;; socks-tests.el ends here commit 55bc1560ac804a2faa497707ae9b1364cc5c8592 Author: Martin Rudalics Date: Sun Jan 10 11:20:56 2021 +0100 Fix assertion failure in window_box_height (Bug#45737) * lisp/window.el (window-sizable): Don't try to grow a mini window when the root window's minimum height is already larger than its actual height (Bug#45737). diff --git a/lisp/window.el b/lisp/window.el index 11b56d0820..f388f86372 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -1716,9 +1716,11 @@ interpret DELTA as pixels." (setq window (window-normalize-window window)) (cond ((< delta 0) - (max (- (window-min-size window horizontal ignore pixelwise) - (window-size window horizontal pixelwise)) - delta)) + (let ((min-size (window-min-size window horizontal ignore pixelwise)) + (size (window-size window horizontal pixelwise))) + (if (<= size min-size) + 0 + (max (- min-size size) delta)))) ((> delta 0) (if (window-size-fixed-p window horizontal ignore) 0 commit 690cf6b8d8b8827f046bc1e24b2e556afeff976c Author: Philipp Stephani Date: Sun Jan 10 10:14:27 2021 +0100 Increase probability that a process test succeeds. * test/src/process-tests.el (process-tests/fd-setsize-no-crash/make-process): Work around potential Emacs bug. diff --git a/test/src/process-tests.el b/test/src/process-tests.el index ca98f54bdb..921bcd5f85 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -565,6 +565,11 @@ FD_SETSIZE file descriptors (Bug#24325)." (should (memq (process-status process) '(run exit))) (when (process-live-p process) (process-send-eof process)) + ;; FIXME: This `sleep-for' shouldn't be needed. It + ;; indicates a bug in Emacs; perhaps SIGCHLD is + ;; received in parallel with `accept-process-output', + ;; causing the latter to hang. + (sleep-for 0.1) (while (accept-process-output process)) (should (eq (process-status process) 'exit)) ;; If there's an error between fork and exec, Emacs commit 302e6d4623d6f87789c055717490799c1f2ec015 Author: Philipp Stephani Date: Sun Jan 10 09:50:15 2021 +0100 Remove a pointless check for WCOREDUMPED. WCOREDUMPED can only be used if the process was killed. * src/process.c (status_convert): Don't check WCOREDUMPED if WIFEXITED. diff --git a/src/process.c b/src/process.c index 67e930e18f..dac7d0440f 100644 --- a/src/process.c +++ b/src/process.c @@ -692,8 +692,7 @@ status_convert (int w) if (WIFSTOPPED (w)) return Fcons (Qstop, Fcons (make_fixnum (WSTOPSIG (w)), Qnil)); else if (WIFEXITED (w)) - return Fcons (Qexit, Fcons (make_fixnum (WEXITSTATUS (w)), - WCOREDUMP (w) ? Qt : Qnil)); + return Fcons (Qexit, Fcons (make_fixnum (WEXITSTATUS (w)), Qnil)); else if (WIFSIGNALED (w)) return Fcons (Qsignal, Fcons (make_fixnum (WTERMSIG (w)), WCOREDUMP (w) ? Qt : Qnil)); commit 7a89b4b5d3bb44a1f43cc32c73cc85b63658c38b Author: Tassilo Horn Date: Sun Jan 10 09:40:07 2021 +0100 Support keyval style beamer frame labels * lisp/textmodes/reftex-vars.el (reftex-label-regexps): Support keyval style beamer frame labels. diff --git a/lisp/textmodes/reftex-vars.el b/lisp/textmodes/reftex-vars.el index 073059d52e..d4c1b87262 100644 --- a/lisp/textmodes/reftex-vars.el +++ b/lisp/textmodes/reftex-vars.el @@ -906,7 +906,8 @@ DOWNCASE t: Downcase words before using them." ;; begin, optional spaces and opening brace "begin[[:space:]]*{" ;; Build a regexp for env names - (regexp-opt '("lstlisting" "dmath" "dseries" "dgroup" "darray")) + (regexp-opt '("lstlisting" "dmath" "dseries" "dgroup" + "darray" "frame")) ;; closing brace, optional spaces "}[[:space:]]*" ;; Now for macros @@ -919,9 +920,9 @@ DOWNCASE t: Downcase words before using them." "\\[[^][]*" ;; Allow nested levels of chars enclosed in braces "\\(?:{[^}{]*" - "\\(?:{[^}{]*" - "\\(?:{[^}{]*}[^}{]*\\)*" - "}[^}{]*\\)*" + "\\(?:{[^}{]*" + "\\(?:{[^}{]*}[^}{]*\\)*" + "}[^}{]*\\)*" "}[^][]*\\)*" ;; Match the label key "\\ Date: Sat Jan 9 09:45:49 2021 -0800 Remove reference to gnus-bug-create-help-buffer * lisp/gnus/gnus-win.el (gnus-buffer-configuration): Variable no longer exists. diff --git a/lisp/gnus/gnus-win.el b/lisp/gnus/gnus-win.el index 18924a3ad0..3fb8e469d0 100644 --- a/lisp/gnus/gnus-win.el +++ b/lisp/gnus/gnus-win.el @@ -145,7 +145,6 @@ used to display Gnus windows." (,shell-command-buffer-name 1.0))) (bug (vertical 1.0 - (if gnus-bug-create-help-buffer '("*Gnus Help Bug*" 0.5)) ("*Gnus Bug*" 1.0 point))) (score-trace (vertical 1.0 commit 4cebd2ded01f733957919cea9d10a67101cb7a67 Author: Philipp Stephani Date: Sat Jan 9 21:17:42 2021 +0100 Don't unblock SIGCHLD too early. We first need to register the received process ID so that 'handle_child_signal' checks it. Otherwise we might never call 'waitpid' for these processes, risking deadlock. * src/callproc.c (call_process): * src/process.c (create_process): Don't unblock SIGCHLD before registering the process ID to wait for. * src/callproc.c (emacs_spawn): Accept a signal set from the caller. diff --git a/src/callproc.c b/src/callproc.c index 8d2a5619eb..1da315bef1 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -314,6 +314,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ char *tempfile = NULL; #else + sigset_t oldset; pid_t pid = -1; #endif int child_errno; @@ -601,9 +602,12 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, #ifndef MSDOS + block_input (); + block_child_signal (&oldset); + child_errno = emacs_spawn (&pid, filefd, fd_output, fd_error, new_argv, env, - SSDATA (current_dir), NULL); + SSDATA (current_dir), NULL, &oldset); eassert ((child_errno == 0) == (0 < pid)); if (pid > 0) @@ -624,6 +628,9 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, } } + unblock_child_signal (&oldset); + unblock_input (); + if (pid < 0) report_file_errno (CHILD_SETUP_ERROR_DESC, Qnil, child_errno); @@ -1227,17 +1234,21 @@ child_setup (int in, int out, int err, char **new_argv, char **env, process image file ARGV[0]. Use ENVP for the environment block for the new process. Use CWD as working directory for the new process. If PTY is not NULL, it must be a pseudoterminal device. If PTY is - NULL, don't perform any terminal setup. */ + NULL, don't perform any terminal setup. OLDSET must be a pointer + to a signal set initialized by `block_child_signal'. Before + calling this function, call `block_input' and `block_child_signal'; + afterwards, call `unblock_input' and `unblock_child_signal'. Be + sure to call `unblock_child_signal' only after registering NEWPID + in a list where `handle_child_signal' can find it! */ int emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, - char **argv, char **envp, const char *cwd, const char *pty) + char **argv, char **envp, const char *cwd, + const char *pty, const sigset_t *oldset) { - sigset_t oldset; int pid; - block_input (); - block_child_signal (&oldset); + eassert (input_blocked_p ()); #ifndef WINDOWSNT /* vfork, and prevent local vars from being clobbered by the vfork. */ @@ -1249,6 +1260,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, int volatile stdout_volatile = std_out; int volatile stderr_volatile = std_err; char **volatile envp_volatile = envp; + const sigset_t *volatile oldset_volatile = oldset; #ifdef DARWIN_OS /* Darwin doesn't let us run setsid after a vfork, so use fork when @@ -1270,6 +1282,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, std_out = stdout_volatile; std_err = stderr_volatile; envp = envp_volatile; + oldset = oldset_volatile; if (pid == 0) #endif /* not WINDOWSNT */ @@ -1364,7 +1377,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, #endif /* Stop blocking SIGCHLD in the child. */ - unblock_child_signal (&oldset); + unblock_child_signal (oldset); if (pty_flag) child_setup_tty (std_out); @@ -1382,10 +1395,6 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, int vfork_error = pid < 0 ? errno : 0; - /* Stop blocking in the parent. */ - unblock_child_signal (&oldset); - unblock_input (); - if (pid < 0) { eassert (0 < vfork_error); diff --git a/src/lisp.h b/src/lisp.h index ca0eb51c06..d139df9342 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4495,8 +4495,8 @@ extern void setup_process_coding_systems (Lisp_Object); # define CHILD_SETUP_ERROR_DESC "Doing vfork" #endif -extern int emacs_spawn (pid_t *, int, int, int, char **, char **, const char *, - const char *); +extern int emacs_spawn (pid_t *, int, int, int, char **, char **, + const char *, const char *, const sigset_t *); extern char **make_environment_block (Lisp_Object); extern void init_callproc_1 (void); extern void init_callproc (void); diff --git a/src/process.c b/src/process.c index 06d750d336..67e930e18f 100644 --- a/src/process.c +++ b/src/process.c @@ -2059,6 +2059,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) bool pty_flag = 0; char pty_name[PTY_NAME_SIZE]; Lisp_Object lisp_pty_name = Qnil; + sigset_t oldset; inchannel = outchannel = -1; @@ -2139,13 +2140,16 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) setup_process_coding_systems (process); char **env = make_environment_block (current_dir); + block_input (); + block_child_signal (&oldset); + pty_flag = p->pty_flag; eassert (pty_flag == ! NILP (lisp_pty_name)); vfork_errno = emacs_spawn (&pid, forkin, forkout, forkerr, new_argv, env, SSDATA (current_dir), - pty_flag ? SSDATA (lisp_pty_name) : NULL); + pty_flag ? SSDATA (lisp_pty_name) : NULL, &oldset); eassert ((vfork_errno == 0) == (0 < pid)); @@ -2153,6 +2157,10 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) if (pid >= 0) p->alive = 1; + /* Stop blocking in the parent. */ + unblock_child_signal (&oldset); + unblock_input (); + /* Environment block no longer needed. */ unbind_to (count, Qnil); commit ace749f2e3be5b23cf4cd29c702a0e82d4d871c3 Author: João Távora Date: Sat Jan 9 18:49:49 2021 +0000 Count Flymake diagnostics in modeline by severity, not type Originally reported in https://github.com/joaotavora/eglot/issues/588 by Pankaj Jangid. * lisp/progmodes/flymake.el (flymake--mode-line-counter): Count diagnostics by severity level, not by type. (Version): Bump to 1.1.1 diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index fddc13f56b..460af718aa 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -4,7 +4,7 @@ ;; Author: Pavel Kobyakov ;; Maintainer: João Távora -;; Version: 1.1.0 +;; Version: 1.1.1 ;; Keywords: c languages tools ;; Package-Requires: ((emacs "26.1") (eldoc "1.1.0")) @@ -1283,6 +1283,8 @@ correctly.") (when (flymake-running-backends) flymake-mode-line-counter-format)) (defun flymake--mode-line-counter (type &optional no-space) + "Compute number of diagnostics in buffer with TYPE's severity. +TYPE is usually keyword `:error', `:warning' or `:note'." (let ((count 0) (face (flymake--lookup-type-property type 'mode-line-face @@ -1290,7 +1292,8 @@ correctly.") (maphash (lambda (_b state) (dolist (d (flymake--backend-state-diags state)) - (when (eq type (flymake--diag-type d)) + (when (= (flymake--severity type) + (flymake--severity (flymake--diag-type d))) (cl-incf count)))) flymake--backend-state) (when (or (cl-plusp count) commit 981d5eaba8e9fe3f48e74d957b2b409c32cb258e Author: Stefan Monnier Date: Sat Jan 9 11:35:53 2021 -0500 * lisp/emacs-lisp/cl-macs.el (cl--self-tco): Fix build of gnus-agent.el Don't burp on "naked" variable let bindings. diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 4cee091e60..c2bf02ccec 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -2121,7 +2121,8 @@ Like `cl-flet' but the definitions can refer to previous ones. ;; Note: it's OK for this `let' to shadow any ;; of the formal arguments since we will only ;; setq the fresh new `ofargs' vars instead ;-) - (let ((shadowings (mapcar #'car bindings))) + (let ((shadowings + (mapcar (lambda (b) (if (consp b) (car b) b)) bindings))) ;; If `var' is shadowed, then it clearly can't be ;; tail-called any more. (not (memq var shadowings))))) commit fe7263803c37c836b3484861fbe13674a5063b4e Author: Eli Zaretskii Date: Sat Jan 9 14:12:14 2021 +0200 Fix cl-concatenate use in macros * lisp/emacs-lisp/cl-macs.el (inline): Remove cl-concatenate. (Bug#45610) diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index ba634d87bc..4cee091e60 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -3487,8 +3487,8 @@ macro that returns its `&whole' argument." (put y 'side-effect-free t)) ;;; Things that are inline. -(cl-proclaim '(inline cl-acons cl-map cl-concatenate cl-notany - cl-notevery cl-revappend cl-nreconc gethash)) +(cl-proclaim '(inline cl-acons cl-map cl-notany cl-notevery cl-revappend + cl-nreconc gethash)) ;;; Things that are side-effect-free. (mapc (lambda (x) (function-put x 'side-effect-free t)) commit 27743e9e709aa9b6cf5e84d2dfa97a68fc359cab Author: Eli Zaretskii Date: Sat Jan 9 14:07:13 2021 +0200 Fix cl-concatenate inlining * lisp/emacs-lisp/seq.el (seq-concatenate): Auto-load it. Do not merge to master. (Bug#45610) diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index e84f618297..ef2b1092c8 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -284,6 +284,9 @@ sorted. FUNCTION must be a function of one argument." (cl-defmethod seq-reverse ((sequence sequence)) (reverse sequence)) +;; We are autoloading seq-concatenate because cl-concatenate needs +;; that when it's inlined, per the cl-proclaim in cl-macs.el. +;;;###autoload (cl-defgeneric seq-concatenate (type &rest sequences) "Concatenate SEQUENCES into a single sequence of type TYPE. TYPE must be one of following symbols: vector, string or list. commit 32a3758c84a6031b118fbcce91606d307a93cc14 Author: Tak Kunihiro Date: Sat Jan 9 11:21:04 2021 +0200 Fix infloop in 'pixel-scroll-mode' * lisp/pixel-scroll.el (pixel-scroll-up, pixel-scroll-down): Avoid inflooping when 'vertical-motion' doesn't move. (Bug#45628) diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el index 8e6e049d24..f722c25b75 100644 --- a/lisp/pixel-scroll.el +++ b/lisp/pixel-scroll.el @@ -133,8 +133,10 @@ This is an alternative of `scroll-up'. Scope moves downward." (pixel-line-height)))) (if (pixel-eob-at-top-p) ; when end-of-the-buffer is close (scroll-up 1) ; relay on robust method - (while (pixel-point-at-top-p amt) ; prevent too late (multi tries) - (vertical-motion 1)) ; move point downward + (catch 'no-movement + (while (pixel-point-at-top-p amt) ; prevent too late (multi tries) + (unless (>= (vertical-motion 1) 1) ; move point downward + (throw 'no-movement nil)))) ; exit loop when point did not move (pixel-scroll-pixel-up amt)))))) ; move scope downward (defun pixel-scroll-down (&optional arg) @@ -150,8 +152,10 @@ This is and alternative of `scroll-down'. Scope moves upward." pixel-resolution-fine-flag (frame-char-height)) (pixel-line-height -1)))) - (while (pixel-point-at-bottom-p amt) ; prevent too late (multi tries) - (vertical-motion -1)) ; move point upward + (catch 'no-movement + (while (pixel-point-at-bottom-p amt) ; prevent too late (multi tries) + (unless (<= (vertical-motion -1) -1) ; move point upward + (throw 'no-movement nil)))) ; exit loop when point did not move (if (or (pixel-bob-at-top-p amt) ; when beginning-of-the-buffer is seen (pixel-eob-at-top-p)) ; for file with a long line (scroll-down 1) ; relay on robust method commit 29c7f8c915c3889dfd5b25878aa0692f826cd38f Author: Stefan Monnier Date: Fri Jan 8 19:59:16 2021 -0500 * lisp/emacs-lisp/cl-macs.el: Optimize self-calls in tail position Implement a limited form of tail-call optimization for the special case of recursive functions defined with `cl-labels`. Only self-recursion is optimized, no attempt is made to handle more complex cases such a mutual recursion. The main benefit is to reduce the use of the stack, tho in my limited tests, this can also improve performance (about half of the way to a hand-written `while` loop). (cl--self-tco): New function. (cl-labels): Use it. * lisp/subr.el (letrec): Optimize single-binding corner case. * test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs--labels): Add tests to check that TCO is working. diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 1cb195d129..ba634d87bc 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -2060,10 +2060,98 @@ Like `cl-flet' but the definitions can refer to previous ones. ((null (cdr bindings)) `(cl-flet ,bindings ,@body)) (t `(cl-flet (,(pop bindings)) (cl-flet* ,bindings ,@body))))) +(defun cl--self-tco (var fargs body) + ;; This tries to "optimize" tail calls for the specific case + ;; of recursive self-calls by replacing them with a `while' loop. + ;; It is quite far from a general tail-call optimization, since it doesn't + ;; even handle mutually recursive functions. + (letrec + ((done nil) ;; Non-nil if some TCO happened. + (retvar (make-symbol "retval")) + (ofargs (mapcar (lambda (s) (if (memq s cl--lambda-list-keywords) s + (make-symbol (symbol-name s)))) + fargs)) + (opt-exps (lambda (exps) ;; `exps' is in tail position! + (append (butlast exps) + (list (funcall opt (car (last exps))))))) + (opt + (lambda (exp) ;; `exp' is in tail position! + (pcase exp + ;; FIXME: Optimize `apply'? + (`(funcall ,(pred (eq var)) . ,aargs) + ;; This is a self-recursive call in tail position. + (let ((sets nil) + (fargs ofargs)) + (while fargs + (pcase (pop fargs) + ('&rest + (push (pop fargs) sets) + (push `(list . ,aargs) sets) + ;; (cl-assert (null fargs)) + ) + ('&optional nil) + (farg + (push farg sets) + (push (pop aargs) sets)))) + (setq done t) + `(progn (setq . ,(nreverse sets)) + :recurse))) + (`(progn . ,exps) `(progn . ,(funcall opt-exps exps))) + (`(if ,cond ,then . ,else) + `(if ,cond ,(funcall opt then) . ,(funcall opt-exps else))) + (`(cond . ,conds) + (let ((cs '())) + (while conds + (pcase (pop conds) + (`(,exp) + (push (if conds + ;; This returns the value of `exp' but it's + ;; only in tail position if it's the + ;; last condition. + `((setq ,retvar ,exp) nil) + `(,(funcall opt exp))) + cs)) + (exps + (push (funcall opt-exps exps) cs)))) + (if (eq t (caar cs)) + `(cond . ,(nreverse cs)) + `(cond ,@(nreverse cs) (t (setq ,retvar nil)))))) + ((and `(,(or 'let 'let*) ,bindings . ,exps) + (guard + ;; Note: it's OK for this `let' to shadow any + ;; of the formal arguments since we will only + ;; setq the fresh new `ofargs' vars instead ;-) + (let ((shadowings (mapcar #'car bindings))) + ;; If `var' is shadowed, then it clearly can't be + ;; tail-called any more. + (not (memq var shadowings))))) + `(,(car exp) ,bindings . ,(funcall opt-exps exps))) + (_ + `(progn (setq ,retvar ,exp) nil)))))) + + (let ((optimized-body (funcall opt-exps body))) + (if (not done) + (cons fargs body) + ;; We use two sets of vars: `ofargs' and `fargs' because we need + ;; to be careful that if a closure captures a formal argument + ;; in one iteration, it needs to capture a different binding + ;; then that of other iterations, e.g. + (cons + ofargs + `((let (,retvar) + (while (let ,(delq nil + (cl-mapcar + (lambda (a oa) + (unless (memq a cl--lambda-list-keywords) + (list a oa))) + fargs ofargs)) + . ,optimized-body)) + ,retvar))))))) + ;;;###autoload (defmacro cl-labels (bindings &rest body) - "Make local (recursive) function definitions. -Each definition can take the form (FUNC ARGLIST BODY...) where + "Make local (recursive) function definitions. ++BINDINGS is a list of definitions of the form (FUNC ARGLIST BODY...) where FUNC is the function name, ARGLIST its arguments, and BODY the forms of the function body. FUNC is defined in any BODY, as well as FORM, so you can write recursive and mutually recursive @@ -2075,17 +2163,33 @@ details. (let ((binds ()) (newenv macroexpand-all-environment)) (dolist (binding bindings) (let ((var (make-symbol (format "--cl-%s--" (car binding))))) - (push (list var `(cl-function (lambda . ,(cdr binding)))) binds) + (push (cons var (cdr binding)) binds) (push (cons (car binding) (lambda (&rest args) (if (eq (car args) cl--labels-magic) (list cl--labels-magic var) (cl-list* 'funcall var args)))) newenv))) - (macroexpand-all `(letrec ,(nreverse binds) ,@body) - ;; Don't override lexical-let's macro-expander. - (if (assq 'function newenv) newenv - (cons (cons 'function #'cl--labels-convert) newenv))))) + ;; Don't override lexical-let's macro-expander. + (unless (assq 'function newenv) + (push (cons 'function #'cl--labels-convert) newenv)) + ;; Perform self-tail call elimination. + (setq binds (mapcar + (lambda (bind) + (pcase-let* + ((`(,var ,sargs . ,sbody) bind) + (`(function (lambda ,fargs . ,ebody)) + (macroexpand-all `(cl-function (lambda ,sargs . ,sbody)) + newenv)) + (`(,ofargs . ,obody) + (cl--self-tco var fargs ebody))) + `(,var (function (lambda ,ofargs . ,obody))))) + (nreverse binds))) + `(letrec ,binds + . ,(macroexp-unprogn + (macroexpand-all + (macroexp-progn body) + newenv))))) ;; The following ought to have a better definition for use with newer ;; byte compilers. diff --git a/lisp/subr.el b/lisp/subr.el index bc0c417990..260202945b 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1893,9 +1893,14 @@ all symbols are bound before any of the VALUEFORMs are evalled." `(let ,(mapcar #'car binders) ,@(mapcar (lambda (binder) `(setq ,@binder)) binders) ,@body)))) - (if seqbinds - `(let* ,(nreverse seqbinds) ,nbody) - nbody)))) + (cond + ;; All bindings are recursive. + ((null seqbinds) nbody) + ;; Special case for trivial uses. + ((and (symbolp nbody) (null (cdr seqbinds)) (eq nbody (caar seqbinds))) + (nth 1 (car seqbinds))) + ;; General case. + (t `(let* ,(nreverse seqbinds) ,nbody)))))) (defmacro dlet (binders &rest body) "Like `let*' but using dynamic scoping." diff --git a/test/lisp/emacs-lisp/cl-macs-tests.el b/test/lisp/emacs-lisp/cl-macs-tests.el index 7774ed3145..bcd63f73a3 100644 --- a/test/lisp/emacs-lisp/cl-macs-tests.el +++ b/test/lisp/emacs-lisp/cl-macs-tests.el @@ -616,6 +616,21 @@ collection clause." ;; Simple recursive function. (cl-labels ((len (xs) (if xs (1+ (len (cdr xs))) 0))) (should (equal (len (make-list 42 t)) 42))) - ) + + ;; Simple tail-recursive function. + (cl-labels ((len (xs n) (if xs (len (cdr xs) (1+ n)) n))) + (should (equal (len (make-list 42 t) 0) 42)) + ;; Should not bump into stack depth limits. + (should (equal (len (make-list 42000 t) 0) 42000))) + + ;; Check that non-recursive functions are handled more efficiently. + (should (pcase (macroexpand '(cl-labels ((f (x) (+ x 1))) (f 5))) + (`(let* ,_ (funcall ,_ 5)) t))) + + ;; Case of "tail-recursive lambdas". + (should (pcase (macroexpand + '(cl-labels ((len (xs n) (if xs (len (cdr xs) (1+ n)) n))) + #'len)) + (`(function (lambda (,_ ,_) . ,_)) t)))) ;;; cl-macs-tests.el ends here commit 6e73e07a6f5cbdd1c5ae6e0f3fbd0f8f56813f1a Author: Dmitry Gutov Date: Sat Jan 9 02:08:59 2021 +0200 Make sure default-directory relates to the originating buffer * lisp/progmodes/xref.el (xref--show-xref-buffer): Pick up default-directory value from the caller (https://lists.gnu.org/archive/html/emacs-devel/2021-01/msg00551.html). (xref-show-definitions-buffer-at-bottom): Same. diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index b393b8d0f1..d3b6ae71a0 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -928,8 +928,10 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (or (assoc-default 'fetched-xrefs alist) (funcall fetcher))) - (xref-alist (xref--analyze xrefs))) + (xref-alist (xref--analyze xrefs)) + (dd default-directory)) (with-current-buffer (get-buffer-create xref-buffer-name) + (setq default-directory dd) (xref--xref-buffer-mode) (xref--show-common-initialize xref-alist fetcher alist) (pop-to-buffer (current-buffer)) @@ -992,13 +994,15 @@ When only one definition found, jump to it right away instead." When there is more than one definition, split the selected window and show the list in a small window at the bottom. And use a local keymap that binds `RET' to `xref-quit-and-goto-xref'." - (let ((xrefs (funcall fetcher))) + (let ((xrefs (funcall fetcher)) + (dd default-directory)) (cond ((not (cdr xrefs)) (xref-pop-to-location (car xrefs) (assoc-default 'display-action alist))) (t (with-current-buffer (get-buffer-create xref-buffer-name) + (setq default-directory dd) (xref--transient-buffer-mode) (xref--show-common-initialize (xref--analyze xrefs) fetcher alist) (pop-to-buffer (current-buffer) commit 3b9dad88e02f05773c599808266febf3e4128222 Author: Stefan Monnier Date: Fri Jan 8 18:44:13 2021 -0500 * lisp/subr.el (letrec): Optimize some non-recursive bindings * lisp/emacs-lisp/macroexp.el (macroexp--fgrep): Look inside bytecode objects as well. * test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs--labels): * test/lisp/subr-tests.el (subr--tests-letrec): New tests. diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index d5fda528b4..37844977f8 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -499,7 +499,7 @@ test of free variables in the following ways: (dolist (binding (macroexp--fgrep bindings (pop sexp))) (push binding res) (setq bindings (remove binding bindings)))) - (if (vectorp sexp) + (if (or (vectorp sexp) (byte-code-function-p sexp)) ;; With backquote, code can appear within vectors as well. ;; This wouldn't be needed if we `macroexpand-all' before ;; calling macroexp--fgrep, OTOH. diff --git a/lisp/subr.el b/lisp/subr.el index b92744cdcb..bc0c417990 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1874,9 +1874,28 @@ all symbols are bound before any of the VALUEFORMs are evalled." ;; As a special-form, we could implement it more efficiently (and cleanly, ;; making the vars actually unbound during evaluation of the binders). (declare (debug let) (indent 1)) - `(let ,(mapcar #'car binders) - ,@(mapcar (lambda (binder) `(setq ,@binder)) binders) - ,@body)) + ;; Use plain `let*' for the non-recursive definitions. + ;; This only handles the case where the first few definitions are not + ;; recursive. Nothing as fancy as an SCC analysis. + (let ((seqbinds nil)) + ;; Our args haven't yet been macro-expanded, so `macroexp--fgrep' + ;; may fail to see references that will be introduced later by + ;; macroexpansion. We could call `macroexpand-all' to avoid that, + ;; but in order to avoid that, we instead check to see if the binders + ;; appear in the macroexp environment, since that's how references can be + ;; introduced later on. + (unless (macroexp--fgrep binders macroexpand-all-environment) + (while (and binders + (null (macroexp--fgrep binders (nth 1 (car binders))))) + (push (pop binders) seqbinds))) + (let ((nbody (if (null binders) + (macroexp-progn body) + `(let ,(mapcar #'car binders) + ,@(mapcar (lambda (binder) `(setq ,@binder)) binders) + ,@body)))) + (if seqbinds + `(let* ,(nreverse seqbinds) ,nbody) + nbody)))) (defmacro dlet (binders &rest body) "Like `let*' but using dynamic scoping." diff --git a/test/lisp/emacs-lisp/cl-macs-tests.el b/test/lisp/emacs-lisp/cl-macs-tests.el index 446983c2e3..7774ed3145 100644 --- a/test/lisp/emacs-lisp/cl-macs-tests.el +++ b/test/lisp/emacs-lisp/cl-macs-tests.el @@ -610,4 +610,12 @@ collection clause." ;; Just make sure the function can be instrumented. (edebug-defun))) +;;; cl-labels + +(ert-deftest cl-macs--labels () + ;; Simple recursive function. + (cl-labels ((len (xs) (if xs (1+ (len (cdr xs))) 0))) + (should (equal (len (make-list 42 t)) 42))) + ) + ;;; cl-macs-tests.el ends here diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index 2118530336..e0826208b6 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -433,6 +433,15 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350." (should (equal (flatten-tree '(1 ("foo" "bar") 2)) '(1 "foo" "bar" 2)))) +(ert-deftest subr--tests-letrec () + ;; Test that simple cases of `letrec' get optimized back to `let*'. + (should (equal (macroexpand '(letrec ((subr-tests-var1 1) + (subr-tests-var2 subr-tests-var1)) + (+ subr-tests-var1 subr-tests-var2))) + '(let* ((subr-tests-var1 1) + (subr-tests-var2 subr-tests-var1)) + (+ subr-tests-var1 subr-tests-var2))))) + (defvar subr-tests--hook nil) (ert-deftest subr-tests-add-hook-depth () commit 9d3d6f850060db078c7a6853aa3eb8f6e8dca520 Author: Stefan Monnier Date: Fri Jan 8 18:28:47 2021 -0500 * lisp/emacs-lisp/cl-generic.el (cl--generic-lambda): Fix last change diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index 529de9346d..8e36dbe4a3 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el @@ -370,7 +370,7 @@ the specializer used will be the one returned by BODY." (cons (not (not uses-cnm)) `#'(lambda (,@(if uses-cnm (list cnm)) ,@args) ,@(car parsed-body) - ,(if (not (memq nmp uses-cnm)) + ,(if (not (assq nmp uses-cnm)) nbody `(let ((,nmp (lambda () (cl--generic-isnot-nnm-p ,cnm)))) commit 768a35279388106f83842b7e029aa4a61b142df2 Author: Stefan Monnier Date: Fri Jan 8 17:57:26 2021 -0500 * lisp/emacs-lisp/macroexp.el (macroexp--fgrep): Rename from `pcase--fgrep` * lisp/emacs-lisp/cl-generic.el (cl--generic-fgrep): Delete. (cl--generic-lambda): Use `macroexp--pacse` instead. * lisp/emacs-lisp/pcase.el (pcase--fgrep): Rename to `macroexp--fgrep`. diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index 19dd54c864..529de9346d 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el @@ -304,15 +304,6 @@ the specializer used will be the one returned by BODY." (lambda ,args ,@body)))) (eval-and-compile ;Needed while compiling the cl-defmethod calls below! - (defun cl--generic-fgrep (vars sexp) ;Copied from pcase.el. - "Check which of the symbols VARS appear in SEXP." - (let ((res '())) - (while (consp sexp) - (dolist (var (cl--generic-fgrep vars (pop sexp))) - (unless (memq var res) (push var res)))) - (and (memq sexp vars) (not (memq sexp res)) (push sexp res)) - res)) - (defun cl--generic-split-args (args) "Return (SPEC-ARGS . PLAIN-ARGS)." (let ((plain-args ()) @@ -375,7 +366,7 @@ the specializer used will be the one returned by BODY." ;; is used. ;; FIXME: Also, optimize the case where call-next-method is ;; only called with explicit arguments. - (uses-cnm (cl--generic-fgrep (list cnm nmp) nbody))) + (uses-cnm (macroexp--fgrep `((,cnm) (,nmp)) nbody))) (cons (not (not uses-cnm)) `#'(lambda (,@(if uses-cnm (list cnm)) ,@args) ,@(car parsed-body) @@ -617,11 +608,11 @@ The set of acceptable TYPEs (also called \"specializers\") is defined (lambda (,@fixedargs &rest args) (let ,bindings (apply (cl--generic-with-memoization - (gethash ,tag-exp method-cache) - (cl--generic-cache-miss - generic ',dispatch-arg dispatches-left methods - ,(if (cdr typescodes) - `(append ,@typescodes) (car typescodes)))) + (gethash ,tag-exp method-cache) + (cl--generic-cache-miss + generic ',dispatch-arg dispatches-left methods + ,(if (cdr typescodes) + `(append ,@typescodes) (car typescodes)))) ,@fixedargs args))))))))) (defun cl--generic-make-function (generic) @@ -1110,7 +1101,8 @@ These match if the argument is a cons cell whose car is `eql' to VAL." (if (not (eq (car-safe specializer) 'head)) (cl-call-next-method) (cl--generic-with-memoization - (gethash (cadr specializer) cl--generic-head-used) specializer) + (gethash (cadr specializer) cl--generic-head-used) + specializer) (list cl--generic-head-generalizer))) (cl--generic-prefill-dispatchers 0 (head eql)) diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index 82a8cd2d77..d5fda528b4 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -480,6 +480,35 @@ itself or not." v (list 'quote v))) +(defun macroexp--fgrep (bindings sexp) + "Return those of the BINDINGS which might be used in SEXP. +It is used as a poor-man's \"free variables\" test. It differs from a true +test of free variables in the following ways: +- It does not distinguish variables from functions, so it can be used + both to detect whether a given variable is used by SEXP and to + detect whether a given function is used by SEXP. +- It does not actually know ELisp syntax, so it only looks for the presence + of symbols in SEXP and can't distinguish if those symbols are truly + references to the given variable (or function). That can make the result + include bindings which actually aren't used. +- For the same reason it may cause the result to fail to include bindings + which will be used if SEXP is not yet fully macro-expanded and the + use of the binding will only be revealed by macro expansion." + (let ((res '())) + (while (and (consp sexp) bindings) + (dolist (binding (macroexp--fgrep bindings (pop sexp))) + (push binding res) + (setq bindings (remove binding bindings)))) + (if (vectorp sexp) + ;; With backquote, code can appear within vectors as well. + ;; This wouldn't be needed if we `macroexpand-all' before + ;; calling macroexp--fgrep, OTOH. + (macroexp--fgrep bindings (mapcar #'identity sexp)) + (let ((tmp (assq sexp bindings))) + (if tmp + (cons tmp res) + res))))) + ;;; Load-time macro-expansion. ;; Because macro-expansion used to be more lazy, eager macro-expansion diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 8fb79d220d..72ea1ba018 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -344,7 +344,7 @@ of the elements of LIST is performed as if by `pcase-let'. (seen '()) (codegen (lambda (code vars) - (let ((vars (pcase--fgrep vars code)) + (let ((vars (macroexp--fgrep vars code)) (prev (assq code seen))) (if (not prev) (let ((res (pcase-codegen code vars))) @@ -401,7 +401,7 @@ of the elements of LIST is performed as if by `pcase-let'. ;; occurrences of this leaf since it's small. (lambda (code vars) (pcase-codegen code - (pcase--fgrep vars code))) + (macroexp--fgrep vars code))) codegen) (cdr case) vars)))) @@ -668,7 +668,7 @@ MATCH is the pattern that needs to be matched, of the form: ;; run, but we don't have the environment in which `pat' will ;; run, so we can't do a reliable verification. But let's try ;; and catch at least the easy cases such as (bug#14773). - (not (pcase--fgrep (mapcar #'car vars) (cadr upat))))) + (not (macroexp--fgrep (mapcar #'car vars) (cadr upat))))) '(:pcase--succeed . :pcase--fail)) ((and (eq 'pred (car upat)) (let ((otherpred @@ -692,23 +692,6 @@ MATCH is the pattern that needs to be matched, of the form: '(nil . :pcase--fail) '(:pcase--fail . nil)))))) -(defun pcase--fgrep (bindings sexp) - "Return those of the BINDINGS which might be used in SEXP." - (let ((res '())) - (while (and (consp sexp) bindings) - (dolist (binding (pcase--fgrep bindings (pop sexp))) - (push binding res) - (setq bindings (remove binding bindings)))) - (if (vectorp sexp) - ;; With backquote, code can appear within vectors as well. - ;; This wouldn't be needed if we `macroexpand-all' before - ;; calling pcase--fgrep, OTOH. - (pcase--fgrep bindings (mapcar #'identity sexp)) - (let ((tmp (assq sexp bindings))) - (if tmp - (cons tmp res) - res))))) - (defun pcase--self-quoting-p (upat) (or (keywordp upat) (integerp upat) (stringp upat))) @@ -749,7 +732,7 @@ MATCH is the pattern that needs to be matched, of the form: `(,fun ,arg) (let* (;; `env' is an upper bound on the bindings we need. (env (mapcar (lambda (x) (list (car x) (cdr x))) - (pcase--fgrep vars fun))) + (macroexp--fgrep vars fun))) (call (progn (when (assq arg env) ;; `arg' is shadowed by `env'. @@ -770,7 +753,7 @@ MATCH is the pattern that needs to be matched, of the form: "Build an expression that will evaluate EXP." (let* ((found (assq exp vars))) (if found (cdr found) - (let* ((env (pcase--fgrep vars exp))) + (let* ((env (macroexp--fgrep vars exp))) (if env (macroexp-let* (mapcar (lambda (x) (list (car x) (cdr x))) env) commit a31bfd594523dc06941ceb89cdbeabcd4a5d19f7 Author: Stefan Kangas Date: Fri Jan 8 15:26:02 2021 +0100 Merge recently added kbd tests * test/lisp/subr-tests.el (subr--kbd): Merge test... (subr-test-kbd): ...with this one. Fix thinko in my previous commit. Thanks to Mattias Engdegård . diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index 83031c44fc..2118530336 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -66,9 +66,15 @@ (ert-deftest subr-test-kbd () (should (equal (kbd "f") "f")) - (should (equal (kbd "F1") "F1")) + (should (equal (kbd "") [f1])) (should (equal (kbd "RET") "\C-m")) - (should (equal (kbd "C-x a") "\C-xa"))) + (should (equal (kbd "C-x a") "\C-xa")) + ;; Check that kbd handles both new and old style key descriptions + ;; (bug#45536). + (should (equal (kbd "s-") [s-return])) + (should (equal (kbd "") [s-return])) + (should (equal (kbd "C-M-") [C-M-return])) + (should (equal (kbd "") [C-M-return]))) (ert-deftest subr-test-define-prefix-command () (define-prefix-command 'foo-prefix-map) @@ -653,13 +659,5 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350." (should (>= (length (apropos-internal "^help" #'commandp)) 15)) (should-not (apropos-internal "^next-line$" #'keymapp))) -(ert-deftest subr--kbd () - ;; Check that kbd handles both new and old style key descriptions - ;; (bug#45536). - (should (equal (kbd "s-") [s-return])) - (should (equal (kbd "") [s-return])) - (should (equal (kbd "C-M-") [C-M-return])) - (should (equal (kbd "") [C-M-return]))) - (provide 'subr-tests) ;;; subr-tests.el ends here commit 5ac7b480757d8731fe2bda0452e48f0cd0356aa4 Author: Stefan Kangas Date: Fri Jan 8 15:16:02 2021 +0100 Lift define-prefix-command to Lisp * lisp/subr.el (define-prefix-command): New defun. * src/keymap.c (Fdefine_prefix_command): Remove DEFUN. (syms_of_keymap): Remove defsubr for Fdefine_prefix_command. * test/lisp/subr-tests.el (subr-test-define-prefix-command): New test. diff --git a/lisp/subr.el b/lisp/subr.el index 11aabfe504..b92744cdcb 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -995,6 +995,22 @@ a menu, so this function is not useful for non-menu keymaps." (setq inserted t))) (setq tail (cdr tail))))) +(defun define-prefix-command (command &optional mapvar name) + "Define COMMAND as a prefix command. COMMAND should be a symbol. +A new sparse keymap is stored as COMMAND's function definition and its +value. +This prepares COMMAND for use as a prefix key's binding. +If a second optional argument MAPVAR is given, it should be a symbol. +The map is then stored as MAPVAR's value instead of as COMMAND's +value; but COMMAND is still defined as a function. +The third optional argument NAME, if given, supplies a menu name +string for the map. This is required to use the keymap as a menu. +This function returns COMMAND." + (let ((map (make-sparse-keymap name))) + (fset command map) + (set (or mapvar command) map) + command)) + (defun map-keymap-sorted (function keymap) "Implement `map-keymap' with sorting. Don't call this function; it is for internal use only." diff --git a/src/keymap.c b/src/keymap.c index 3d1993869b..1197f6fd4a 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -1712,28 +1712,6 @@ bindings; see the description of `lookup-key' for more details about this. */) return Flist (j, maps); } -DEFUN ("define-prefix-command", Fdefine_prefix_command, Sdefine_prefix_command, 1, 3, 0, - doc: /* Define COMMAND as a prefix command. COMMAND should be a symbol. -A new sparse keymap is stored as COMMAND's function definition and its -value. -This prepares COMMAND for use as a prefix key's binding. -If a second optional argument MAPVAR is given, it should be a symbol. -The map is then stored as MAPVAR's value instead of as COMMAND's -value; but COMMAND is still defined as a function. -The third optional argument NAME, if given, supplies a menu name -string for the map. This is required to use the keymap as a menu. -This function returns COMMAND. */) - (Lisp_Object command, Lisp_Object mapvar, Lisp_Object name) -{ - Lisp_Object map = Fmake_sparse_keymap (name); - Ffset (command, map); - if (!NILP (mapvar)) - Fset (mapvar, map); - else - Fset (command, map); - return command; -} - DEFUN ("use-global-map", Fuse_global_map, Suse_global_map, 1, 1, 0, doc: /* Select KEYMAP as the global keymap. */) (Lisp_Object keymap) @@ -3280,7 +3258,6 @@ be preferred. */); defsubr (&Sminor_mode_key_binding); defsubr (&Sdefine_key); defsubr (&Slookup_key); - defsubr (&Sdefine_prefix_command); defsubr (&Suse_global_map); defsubr (&Suse_local_map); defsubr (&Scurrent_local_map); diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index 54f6eb4b2a..83031c44fc 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -70,6 +70,17 @@ (should (equal (kbd "RET") "\C-m")) (should (equal (kbd "C-x a") "\C-xa"))) +(ert-deftest subr-test-define-prefix-command () + (define-prefix-command 'foo-prefix-map) + (should (keymapp foo-prefix-map)) + (should (fboundp #'foo-prefix-map)) + ;; With optional argument. + (define-prefix-command 'bar-prefix 'bar-prefix-map) + (should (keymapp bar-prefix-map)) + (should (fboundp #'bar-prefix)) + ;; Returns the symbol. + (should (eq (define-prefix-command 'foo-bar) 'foo-bar))) + ;;;; Mode hooks. commit f5cfe5a0a9c64f001f1cec3f78b811a3b6e69b09 Author: Stefan Kangas Date: Fri Jan 8 12:27:32 2021 +0100 * test/lisp/subr-tests.el (subr-test-kbd): New test. diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index 8d19a26877..54f6eb4b2a 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -61,6 +61,18 @@ (quote (0 font-lock-keyword-face)))))))) + +;;;; Keymap support. + +(ert-deftest subr-test-kbd () + (should (equal (kbd "f") "f")) + (should (equal (kbd "F1") "F1")) + (should (equal (kbd "RET") "\C-m")) + (should (equal (kbd "C-x a") "\C-xa"))) + + +;;;; Mode hooks. + (defalias 'subr-tests--parent-mode (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode)) commit 705292c200a6e35127c26a0ff676f41a072fefa4 Author: Stefan Kangas Date: Thu Jan 7 19:01:55 2021 +0100 Remove unused DEFSYM * src/minibuf.c (syms_of_minibuf) : Remove unused DEFSYM. diff --git a/src/minibuf.c b/src/minibuf.c index 8b23569019..5ee440f662 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -2013,9 +2013,6 @@ syms_of_minibuf (void) DEFSYM (Qminibuffer_setup_hook, "minibuffer-setup-hook"); DEFSYM (Qminibuffer_exit_hook, "minibuffer-exit-hook"); - /* The maximum length of a minibuffer history. */ - DEFSYM (Qhistory_length, "history-length"); - DEFSYM (Qcurrent_input_method, "current-input-method"); DEFSYM (Qactivate_input_method, "activate-input-method"); DEFSYM (Qcase_fold_search, "case-fold-search"); commit 62e0c675908cc11907c15d1ae084b7bca7890a1a Author: Eli Zaretskii Date: Fri Jan 8 13:53:28 2021 +0200 Fix syntax of space characters * lisp/international/characters.el (tbl): Give all the space characters whose Unicode General Category is Zs the 'space' syntax. (Bug#45660) diff --git a/lisp/international/characters.el b/lisp/international/characters.el index 87e8589e6f..9bce419b48 100644 --- a/lisp/international/characters.el +++ b/lisp/international/characters.el @@ -526,9 +526,6 @@ with L, LRE, or LRO Unicode bidi character type.") ;; FIXME: We should probably just use the Unicode properties to set ;; up the syntax table. - ;; NBSP isn't semantically interchangeable with other whitespace chars, - ;; so it's more like punctuation. - (set-case-syntax ?  "." tbl) (set-case-syntax ?¡ "." tbl) (set-case-syntax ?¦ "_" tbl) (set-case-syntax ?§ "." tbl) @@ -602,11 +599,17 @@ with L, LRE, or LRO Unicode bidi character type.") ;; Cyrillic Extended-C (modify-category-entry '(#x1C80 . #x1C8F) ?y) - ;; general punctuation + ;; space characters (see section 6.2 in the Unicode Standard) + (set-case-syntax ?  " " tbl) (setq c #x2000) (while (<= c #x200b) (set-case-syntax c " " tbl) (setq c (1+ c))) + (let ((chars '(#x202F #x205F #x3000))) + (while chars + (set-case-syntax (car chars) " " tbl) + (setq chars (cdr chars)))) + ;; general punctuation (while (<= c #x200F) (set-case-syntax c "." tbl) (setq c (1+ c))) commit 656801f5bb3a9d619e1c0b987d905c22387cc462 Author: Michael Albinus Date: Fri Jan 8 09:58:31 2021 +0100 * test/lisp/net/tramp-tests.el (tramp-test31-interrupt-process): Tag it :unstable on hydra. diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 819d69b600..e1cb9939f2 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -4670,7 +4670,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (ert-deftest tramp-test31-interrupt-process () "Check `interrupt-process'." - :tags (if (getenv "EMACS_EMBA_CI") + :tags (if (or (getenv "EMACS_HYDRA_CI") (getenv "EMACS_EMBA_CI")) '(:expensive-test :unstable) '(:expensive-test)) (skip-unless (tramp--test-enabled)) (skip-unless (tramp--test-sh-p)) commit 74d18957b898e687dcc07ba86559367c8d8ba482 Author: Eli Zaretskii Date: Fri Jan 8 09:35:05 2021 +0200 Fix inhibiting the default.el loading in user init file * lisp/startup.el (startup--load-user-init-file): Test the value of 'inhibit-default-init', not just the LOAD-DEFAULTS argument, because loading the user's init file could have set the value of the former. (command-line): Call 'startup--load-user-init-file' with last arg t: there's no longer any need to test the value of 'inhibit-default-init' here, as it will be tested by the called function. (Bug#45708) diff --git a/lisp/startup.el b/lisp/startup.el index cdf4eea1c3..b60c13e448 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -927,7 +927,8 @@ the name of the init-file to load. If this file cannot be loaded, and ALTERNATE-FILENAME-FUNCTION is non-nil, then it is called with no arguments and should return the name of an alternate init-file to load. If LOAD-DEFAULTS is non-nil, then -load default.el after the init-file. +load default.el after the init-file, unless `inhibit-default-init' +is non-nil. This function sets `user-init-file' to the name of the loaded init-file, or to a default value if loading is not possible." @@ -983,8 +984,8 @@ init-file, or to a default value if loading is not possible." (sit-for 1)) (setq user-init-file source)))) - (when load-defaults - + (when (and load-defaults + (not inhibit-default-init)) ;; Prevent default.el from changing the value of ;; `inhibit-startup-screen'. (let ((inhibit-startup-screen nil)) @@ -1390,7 +1391,7 @@ please check its value") (expand-file-name "init" startup-init-directory)) - (not inhibit-default-init)) + t) (when (and deactivate-mark transient-mark-mode) (with-current-buffer (window-buffer) commit cd56406b621bebff484a2978662c98f7689540bf Author: Juri Linkov Date: Thu Jan 7 20:08:44 2021 +0200 * lisp/tab-bar.el: Improve tab-bar-show (bug#45556) * lisp/tab-bar.el (tab-bar-show): Change :set lambda to update all frames. Improve docstring. diff --git a/etc/NEWS b/etc/NEWS index 14d6b45c92..eaaf9bfb0e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -412,8 +412,8 @@ value of 'tab-bar-show'. --- *** New command 'toggle-frame-tab-bar'. -It can be used to enable/disable the tab bar individually -on each frame independently from the state of `tab-bar-mode'. +It can be used to enable/disable the tab bar individually on each frame +independently from the value of 'tab-bar-mode' and 'tab-bar-show'. --- *** New user option 'tab-bar-tab-name-format-function'. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 5a95e5975d..7e556550da 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -187,9 +187,9 @@ on a console which has no window system but does have a mouse." ;; Clicking anywhere outside existing tabs will add a new tab (tab-bar-new-tab))))) -;; Used in the Show/Hide menu, to have the toggle reflect the current frame. (defun toggle-tab-bar-mode-from-frame (&optional arg) "Toggle tab bar on or off, based on the status of the current frame. +Used in the Show/Hide menu, to have the toggle reflect the current frame. See `tab-bar-mode' for more information." (interactive (list (or current-prefix-arg 'toggle))) (if (eq arg 'toggle) @@ -236,18 +236,31 @@ If the value is `1', then hide the tab bar when it has only one tab, and show it again once more tabs are created. If nil, always keep the tab bar hidden. In this case it's still possible to use persistent named window configurations by relying on -keyboard commands `tab-new', `tab-close', `tab-next', `tab-switcher', etc." +keyboard commands `tab-new', `tab-close', `tab-next', `tab-switcher', etc. + +Setting this variable directly does not take effect; please customize +it (see the info node `Easy Customization'), then it will automatically +update the tab bar on all frames according to the new value. + +To enable or disable the tab bar individually on each frame, +you can use the command `toggle-frame-tab-bar'." :type '(choice (const :tag "Always" t) (const :tag "When more than one tab" 1) (const :tag "Never" nil)) :initialize 'custom-initialize-default :set (lambda (sym val) (set-default sym val) - (tab-bar-mode - (if (or (eq val t) - (and (natnump val) - (> (length (funcall tab-bar-tabs-function)) val))) - 1 -1))) + ;; Preload button images + (tab-bar-mode 1) + ;; Then handle each frame individually + (dolist (frame (frame-list)) + (set-frame-parameter + frame 'tab-bar-lines + (if (or (eq val t) + (and (natnump val) + (> (length (funcall tab-bar-tabs-function frame)) + val))) + 1 0)))) :group 'tab-bar :version "27.1") commit c0ca9359179071cc634adc0efd4523907b1e2e74 Author: Juri Linkov Date: Thu Jan 7 19:56:59 2021 +0200 * lisp/mb-depth.el (minibuffer-depth-indicator): Add :group 'minibuffer'. diff --git a/lisp/mb-depth.el b/lisp/mb-depth.el index ea2ea174b5..f9a24e34bf 100644 --- a/lisp/mb-depth.el +++ b/lisp/mb-depth.el @@ -37,6 +37,7 @@ and must return a string.") (defface minibuffer-depth-indicator '((t :inherit highlight)) "Face to use for minibuffer depth indicator." + :group 'minibuffer :version "28.1") ;; An overlay covering the prompt. This is a buffer-local variable in commit c8448f61858c156dcdc78bb88171544a4eff0ff5 Author: Stefan Kangas Date: Thu Jan 7 18:51:50 2021 +0100 Remove an outdated comment * lisp/subr.el: Remove comment to reflect recent change in the definition of global-map, esc-map and ctl-x-map. diff --git a/lisp/subr.el b/lisp/subr.el index a5a979a217..11aabfe504 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1239,9 +1239,6 @@ in a cleaner way with command remapping, like this: ;;;; The global keymap tree. -;; global-map, esc-map, and ctl-x-map have their values set up in -;; keymap.c; we just give them docstrings here. - (defvar esc-map (let ((map (make-keymap))) (define-key map "u" #'upcase-word) commit 3dc3874c768060e720aecc1c4ac0e87eea44d073 Author: Lars Ingebrigtsen Date: Thu Jan 7 16:47:26 2021 +0100 Further display-buffer doc changes * lisp/window.el (display-buffer): `display-buffer-alist' is apparently the variable the user should be directed towards. diff --git a/lisp/window.el b/lisp/window.el index 37e1800ad1..38be778906 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -7379,8 +7379,8 @@ fails, call `display-buffer-pop-up-frame'.") (defun display-buffer (buffer-or-name &optional action frame) "Display BUFFER-OR-NAME in some window, without selecting it. -To change which window is used, set `display-buffer-base-action' -to a list containing one of these \"action\" functions: +To change which window is used, set `display-buffer-alist' +to an expression containing one of these \"action\" functions: `display-buffer-same-window' -- Use the selected window. `display-buffer-reuse-window' -- Use a window already showing @@ -7403,7 +7403,7 @@ to a list containing one of these \"action\" functions: For instance: - (setq display-buffer-base-action '(display-buffer-at-bottom)) + (setq display-buffer-alist '((\".*\" display-buffer-at-bottom))) Buffer display can be further customized to a very high degree; the rest of this docstring explains some of the many commit 3e99ff97e5411e6f999895fb80cf446399d57c59 Merge: f5b8e5a757 40a0f8a3a2 Author: Michael Albinus Date: Thu Jan 7 16:43:45 2021 +0100 Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs commit f5b8e5a7577c9b05bae1849f7b507b16c1f37c96 Author: Michael Albinus Date: Thu Jan 7 16:43:27 2021 +0100 * test/lisp/filenotify-tests.el (file-notify-test07-many-events-remote): Mark it as unstable also on emba. diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el index 047109a96a..d73b072661 100644 --- a/test/lisp/filenotify-tests.el +++ b/test/lisp/filenotify-tests.el @@ -1265,7 +1265,7 @@ delivered." ;; Unpredictable failures, eg https://hydra.nixos.org/build/86016286 (file-notify--deftest-remote file-notify-test07-many-events "Check that events are not dropped for remote directories." - (getenv "EMACS_HYDRA_CI")) + (or (getenv "EMACS_HYDRA_CI") (getenv "EMACS_EMBA_CI"))) (ert-deftest file-notify-test08-backup () "Check that backup keeps file notification." commit 40a0f8a3a2ac790bb398c321e7eb6928da330511 Author: Lars Ingebrigtsen Date: Thu Jan 7 16:35:48 2021 +0100 Add a display-buffer window selection function that's more like XEmacs * doc/lispref/windows.texi (Buffer Display Action Functions): Document it. * lisp/window.el (display-buffer--action-function-custom-type): Add. (display-buffer): Mention it. (display-buffer-use-least-recent-window): New function (bug#45688). * src/window.c (Fwindow_bump_use_time): New function. diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index b0906acbad..f305d1a8ee 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@ -2634,6 +2634,12 @@ window and displaying the buffer in that window. It can fail if all windows are dedicated to other buffers (@pxref{Dedicated Windows}). @end defun +@defun display-buffer-use-least-recent-window buffer alist +This function is like @code{display-buffer-use-some-window}, but will +not reuse the current window, and will use the least recently +switched-to window. +@end defun + @defun display-buffer-in-direction buffer alist This function tries to display @var{buffer} at a location specified by @var{alist}. For this purpose, @var{alist} should contain a diff --git a/etc/NEWS b/etc/NEWS index 48fb4b88e1..14d6b45c92 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -373,6 +373,15 @@ disabled entirely. ** Windows ++++ +*** New 'display-buffer' function 'display-buffer-use-least-recent-window' +This is like 'display-buffer-use-some-window', but won't reuse the +current window, and when called repeatedly will try not to reuse a +previously selected window. + +*** New function 'window-bump-use-time'. +This updates the use time of a window. + *** The key prefix 'C-x 4 1' displays next command buffer in the same window. It's bound to the command 'same-window-prefix' that requests the buffer of the next command to be displayed in the same window. diff --git a/lisp/window.el b/lisp/window.el index c54a0db211..37e1800ad1 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -7243,6 +7243,7 @@ The actual non-nil value of this variable will be copied to the (const display-buffer-below-selected) (const display-buffer-at-bottom) (const display-buffer-in-previous-window) + (const display-buffer-use-least-recent-window) (const display-buffer-use-some-window) (const display-buffer-use-some-frame) (function :tag "Other function")) @@ -7387,6 +7388,8 @@ to a list containing one of these \"action\" functions: `display-buffer-in-previous-window' -- Use a window that did show the buffer before. `display-buffer-use-some-window' -- Use some existing window. + `display-buffer-use-least-recent-window' -- Try to avoid re-using + windows that have recently been switched to. `display-buffer-pop-up-window' -- Pop up a new window. `display-buffer-below-selected' -- Use or pop up a window below the selected one. @@ -8256,6 +8259,16 @@ indirectly called by the latter." (when (setq window (or best-window second-best-window)) (window--display-buffer buffer window 'reuse alist)))) +(defun display-buffer-use-least-recent-window (buffer alist) + "Display BUFFER in an existing window, but that hasn't been used lately. +This `display-buffer' action function is like +`display-buffer-use-some-window', but will cycle through windows +when displaying buffers repeatedly, and if there's only a single +window, it will split the window." + (when-let ((window (display-buffer-use-some-window + buffer (cons (cons 'inhibit-same-window t) alist)))) + (window-bump-use-time window))) + (defun display-buffer-use-some-window (buffer alist) "Display BUFFER in an existing window. Search for a usable window, set that window to the buffer, and diff --git a/src/window.c b/src/window.c index 58204c13e4..5e78aa400b 100644 --- a/src/window.c +++ b/src/window.c @@ -8100,6 +8100,18 @@ and scrolling positions. */) return Qt; return Qnil; } + +DEFUN ("window-bump-use-time", Fwindow_bump_use_time, + Swindow_bump_use_time, 1, 1, 0, + doc: /* Mark WINDOW as having been recently used. */) + (Lisp_Object window) +{ + struct window *w = decode_valid_window (window); + + w->use_time = ++window_select_count; + return Qnil; +} + static void init_window_once_for_pdumper (void); @@ -8573,6 +8585,7 @@ displayed after a scrolling operation to be somewhat inaccurate. */); defsubr (&Swindow_vscroll); defsubr (&Sset_window_vscroll); defsubr (&Scompare_window_configurations); + defsubr (&Swindow_bump_use_time); defsubr (&Swindow_list); defsubr (&Swindow_list_1); defsubr (&Swindow_prev_buffers); commit 0e6b74d2047452bb1fc3285921465132aeda0cb7 Author: Lars Ingebrigtsen Date: Thu Jan 7 16:00:58 2021 +0100 Fix typo in last display-buffer doc string change * lisp/window.el (display-buffer): Fix typo in last doc string change. diff --git a/lisp/window.el b/lisp/window.el index 9d16e2956e..c54a0db211 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -7400,7 +7400,7 @@ to a list containing one of these \"action\" functions: For instance: - (setq display-buffer-below-selected '(display-buffer-at-bottom)) + (setq display-buffer-base-action '(display-buffer-at-bottom)) Buffer display can be further customized to a very high degree; the rest of this docstring explains some of the many commit fa1f41159ff10f5ae4adc51e28e051f8acd27181 Author: Lars Ingebrigtsen Date: Thu Jan 7 15:45:05 2021 +0100 Edit the display-buffer doc string slightly * lisp/window.el (display-buffer): Reword the start of the doc string (bug#45688). diff --git a/lisp/window.el b/lisp/window.el index cd13e6603a..9d16e2956e 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -7378,6 +7378,35 @@ fails, call `display-buffer-pop-up-frame'.") (defun display-buffer (buffer-or-name &optional action frame) "Display BUFFER-OR-NAME in some window, without selecting it. +To change which window is used, set `display-buffer-base-action' +to a list containing one of these \"action\" functions: + + `display-buffer-same-window' -- Use the selected window. + `display-buffer-reuse-window' -- Use a window already showing + the buffer. + `display-buffer-in-previous-window' -- Use a window that did + show the buffer before. + `display-buffer-use-some-window' -- Use some existing window. + `display-buffer-pop-up-window' -- Pop up a new window. + `display-buffer-below-selected' -- Use or pop up a window below + the selected one. + `display-buffer-at-bottom' -- Use or pop up a window at the + bottom of the selected frame. + `display-buffer-pop-up-frame' -- Show the buffer on a new frame. + `display-buffer-in-child-frame' -- Show the buffer in a + child frame. + `display-buffer-no-window' -- Do not display the buffer and + have `display-buffer' return nil immediately. + +For instance: + + (setq display-buffer-below-selected '(display-buffer-at-bottom)) + +Buffer display can be further customized to a very high degree; +the rest of this docstring explains some of the many +possibilities, and also see `(emacs)Window Choice' for more +information. + BUFFER-OR-NAME must be a buffer or a string naming a live buffer. Return the window chosen for displaying that buffer, or nil if no such window is found. @@ -7403,23 +7432,8 @@ function in the combined function list in turn, passing the buffer as the first argument and the combined action alist as the second argument, until one of the functions returns non-nil. -Action functions and the action they try to perform are: - `display-buffer-same-window' -- Use the selected window. - `display-buffer-reuse-window' -- Use a window already showing - the buffer. - `display-buffer-in-previous-window' -- Use a window that did - show the buffer before. - `display-buffer-use-some-window' -- Use some existing window. - `display-buffer-pop-up-window' -- Pop up a new window. - `display-buffer-below-selected' -- Use or pop up a window below - the selected one. - `display-buffer-at-bottom' -- Use or pop up a window at the - bottom of the selected frame. - `display-buffer-pop-up-frame' -- Show the buffer on a new frame. - `display-buffer-in-child-frame' -- Show the buffer in a - child frame. - `display-buffer-no-window' -- Do not display the buffer and - have `display-buffer' return nil immediately. +See above for the action functions and the action they try to +perform. Action alist entries are: `inhibit-same-window' -- A non-nil value prevents the same commit 23a887e426f81033b0de2f4c93a8525cb31c28da Author: Lars Ingebrigtsen Date: Thu Jan 7 15:12:23 2021 +0100 Add work-around for nnmaildir encoding problem * lisp/gnus/mm-decode.el (mm-with-part): Fix problem with multipart 8bit encoded posts from nnmaildir (bug#44307). diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el index 61946aa581..2b0b61bfac 100644 --- a/lisp/gnus/mm-decode.el +++ b/lisp/gnus/mm-decode.el @@ -1264,11 +1264,20 @@ in HANDLE." (when (and (mm-handle-buffer handle) (buffer-name (mm-handle-buffer handle))) (with-temp-buffer - (mm-disable-multibyte) - (insert-buffer-substring (mm-handle-buffer handle)) - (mm-decode-content-transfer-encoding - (mm-handle-encoding handle) - (mm-handle-media-type handle)) + (if (and (eq (mm-handle-encoding handle) '8bit) + (with-current-buffer (mm-handle-buffer handle) + enable-multibyte-characters)) + ;; Due to unfortunate historical reasons, we may have a + ;; multibyte buffer here, but if it's using an 8bit + ;; Content-Transfer-Encoding, then work around that by + ;; just ignoring the situation. + (insert-buffer-substring (mm-handle-buffer handle)) + ;; Do the decoding. + (mm-disable-multibyte) + (insert-buffer-substring (mm-handle-buffer handle)) + (mm-decode-content-transfer-encoding + (mm-handle-encoding handle) + (mm-handle-media-type handle))) ,@forms)))) (put 'mm-with-part 'lisp-indent-function 1) (put 'mm-with-part 'edebug-form-spec '(body)) diff --git a/test/lisp/gnus/mm-decode-tests.el b/test/lisp/gnus/mm-decode-tests.el index 976e7269b1..74591f919d 100644 --- a/test/lisp/gnus/mm-decode-tests.el +++ b/test/lisp/gnus/mm-decode-tests.el @@ -54,7 +54,7 @@ 'charset))) "ääää\n"))))))) -(ert-deftest test-mm-with-part () +(ert-deftest test-mm-with-part-unibyte () (with-temp-buffer (set-buffer-multibyte nil) (insert-file-contents-literally (ert-resource-file "8bit-multipart.bin")) @@ -70,4 +70,20 @@ 'charset))) "ääää\n")))))) +(ert-deftest test-mm-with-part-multibyte () + (with-temp-buffer + (set-buffer-multibyte t) + (nnheader-insert-file-contents (ert-resource-file "8bit-multipart.bin")) + (while (search-forward "\r\n" nil t) + (replace-match "\n")) + (let ((handle (mm-dissect-buffer))) + (pop handle) + (let ((part (pop handle))) + (should (equal (decode-coding-string + (mm-with-part part + (buffer-string)) + (intern (mail-content-type-get (mm-handle-type part) + 'charset))) + "ääää\n")))))) + ;;; mm-decode-tests.el ends here commit 5d76288660279c2affa4bed45956efd311eaf53d Author: Lars Ingebrigtsen Date: Fri Aug 21 15:36:45 2020 +0200 Fix problem with 8bit content-transfer-encoding in nndoc mbox files * lisp/gnus/nndoc.el (nndoc-possibly-change-buffer): If we're reading an mbox file, it may contain messages that use content-transfer-encoding 8bit, which means that we have to treat the file as a sequence of byte (bug#42951). This avoids double-decoding -- once by Emacs when inserting the mbox into the buffer, and once by Gnus when displaying the articles. diff --git a/lisp/gnus/nndoc.el b/lisp/gnus/nndoc.el index 79518bb4f8..9d5e3900e8 100644 --- a/lisp/gnus/nndoc.el +++ b/lisp/gnus/nndoc.el @@ -352,6 +352,7 @@ from the document.") nndoc-group-alist) (setq nndoc-dissection-alist nil) (with-current-buffer nndoc-current-buffer + (set-buffer-multibyte nil) (erase-buffer) (condition-case error (if (and (stringp nndoc-address) commit 7e80aecc248a78eab923005b266c939c18936c1b Author: Lars Ingebrigtsen Date: Thu Jan 7 14:32:28 2021 +0100 Add tests for mm-decode.el diff --git a/test/lisp/gnus/mm-decode-resources/8bit-multipart.bin b/test/lisp/gnus/mm-decode-resources/8bit-multipart.bin new file mode 100644 index 0000000000..0b193a2723 --- /dev/null +++ b/test/lisp/gnus/mm-decode-resources/8bit-multipart.bin @@ -0,0 +1,20 @@ +From: example +To: example +Content-Type: multipart/alternative; boundary="===============2877195075946974246==" +Date: Thu, 29 Oct 2020 14:47:55 +0100 +MIME-Version: 1.0 +Subject: test + +--===============2877195075946974246== +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 8bit + +ääää + +--===============2877195075946974246== +Content-Type: text/html; charset="utf-8" +Content-Transfer-Encoding: 8bit + +ääää + +--===============2877195075946974246==-- diff --git a/test/lisp/gnus/mm-decode-tests.el b/test/lisp/gnus/mm-decode-tests.el new file mode 100644 index 0000000000..976e7269b1 --- /dev/null +++ b/test/lisp/gnus/mm-decode-tests.el @@ -0,0 +1,73 @@ +;;; mm-decode-tests.el --- -*- lexical-binding:t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'ert-x) +(require 'mm-decode) + +(ert-deftest test-mm-dissect-buffer () + (with-temp-buffer + (set-buffer-multibyte nil) + (insert-file-contents-literally (ert-resource-file "8bit-multipart.bin")) + (while (search-forward "\r\n" nil t) + (replace-match "\n")) + (let ((handle (mm-dissect-buffer))) + (should (equal (mm-handle-media-type handle) "multipart/alternative")) + ;; Skip multipart type. + (pop handle) + (let ((part (pop handle))) + (should (equal (mm-handle-media-type part) "text/plain")) + (should (eq (mm-handle-encoding part) '8bit)) + (with-current-buffer (mm-handle-buffer part) + (should (equal (decode-coding-string + (buffer-string) + (intern (mail-content-type-get (mm-handle-type part) + 'charset))) + "ääää\n")))) + (let ((part (pop handle))) + (should (equal (mm-handle-media-type part) "text/html")) + (should (eq (mm-handle-encoding part) '8bit)) + (with-current-buffer (mm-handle-buffer part) + (should (equal (decode-coding-string + (buffer-string) + (intern (mail-content-type-get (mm-handle-type part) + 'charset))) + "ääää\n"))))))) + +(ert-deftest test-mm-with-part () + (with-temp-buffer + (set-buffer-multibyte nil) + (insert-file-contents-literally (ert-resource-file "8bit-multipart.bin")) + (while (search-forward "\r\n" nil t) + (replace-match "\n")) + (let ((handle (mm-dissect-buffer))) + (pop handle) + (let ((part (pop handle))) + (should (equal (decode-coding-string + (mm-with-part part + (buffer-string)) + (intern (mail-content-type-get (mm-handle-type part) + 'charset))) + "ääää\n")))))) + +;;; mm-decode-tests.el ends here commit a7fdba7889b4e570b659b15710186745b1033ef8 Author: F. Jason Park Date: Thu Jan 7 13:43:13 2021 +0100 Clear socks protocol scratch after authentication * lisp/net/socks.el (socks-open-connection): Fix incomplete patch titled "Append incremental message segments in socks-filter," which addressed chunk ordering but neglected to zero out the work area following successful username/password authentication (bug#45162). diff --git a/lisp/net/socks.el b/lisp/net/socks.el index 0d48fd7e05..96fafc826b 100644 --- a/lisp/net/socks.el +++ b/lisp/net/socks.el @@ -385,6 +385,7 @@ ) ) (process-put proc 'socks-state socks-state-authenticated) + (process-put proc 'socks-scratch "") (set-process-filter proc #'socks-filter))) proc))) commit e15386da5d684b1d64204db6b33fbf613cbaad50 Author: Andreas Schwab Date: Thu Jan 7 13:20:43 2021 +0100 Fix quoting problem in pop3-uidl-save * lisp/net/pop3.el (pop3-uidl-save): Quote strings properly (bug#43896). diff --git a/lisp/net/pop3.el b/lisp/net/pop3.el index aa34fe7f1a..dcac36f2a4 100644 --- a/lisp/net/pop3.el +++ b/lisp/net/pop3.el @@ -463,7 +463,7 @@ Return non-nil if it is necessary to update the local UIDL file." (when (cdr elt) (insert "(\"" (pop elt) "\"\n ") (while elt - (insert (format "\"%s\" %s\n " (pop elt) (pop elt)))) + (insert (format "%S %s\n " (pop elt) (pop elt)))) (delete-char -4) (insert ")\n "))) (delete-char -3) commit 2f6e30cd86a575ef06e8d056fbb6582336f6aadd Author: Lars Ingebrigtsen Date: Thu Jan 7 13:08:45 2021 +0100 Revert mark-paragraph change and add tests * lisp/textmodes/paragraphs.el (mark-paragraph): Revert eb090f65ceb0ae8a90829e911694348583135ba5 (bug#45318). This restores the behaviour from Emacs 27 -- further work is needed on this patch. diff --git a/lisp/textmodes/paragraphs.el b/lisp/textmodes/paragraphs.el index 217ae10fe4..96edfd6de3 100644 --- a/lisp/textmodes/paragraphs.el +++ b/lisp/textmodes/paragraphs.el @@ -371,50 +371,33 @@ See `forward-paragraph' for more information." (defun mark-paragraph (&optional arg allow-extend) "Put point at beginning of this paragraph, mark at end. -The paragraph marked is the one that contains point or follows -point. +The paragraph marked is the one that contains point or follows point. -With argument ARG, puts mark at the end of this or a following -paragraph, so that the number of paragraphs marked equals ARG. +With argument ARG, puts mark at end of a following paragraph, so that +the number of paragraphs marked equals ARG. -If ARG is negative, point is put at the end of this paragraph, -mark is put at the beginning of this or a previous paragraph. +If ARG is negative, point is put at end of this paragraph, mark is put +at beginning of this or a previous paragraph. Interactively (or if ALLOW-EXTEND is non-nil), if this command is -repeated or (in Transient Mark mode) if the mark is active, it -marks the next ARG paragraphs after the region already marked. -This also means when activating the mark immediately before using -this command, the current paragraph is only marked from point." - (interactive "P\np") - (let ((numeric-arg (prefix-numeric-value arg))) - (cond ((zerop numeric-arg)) - ((and allow-extend - (or (and (eq last-command this-command) mark-active) - (region-active-p))) - (if arg - (setq arg numeric-arg) - (if (< (mark) (point)) - (setq arg -1) - (setq arg 1))) - (set-mark - (save-excursion - (goto-char (mark)) - (forward-paragraph arg) - (point)))) - ;; don't activate the mark when at eob - ((and (eobp) (> numeric-arg 0))) - (t - (unless (save-excursion - (forward-line 0) - (looking-at paragraph-start)) - (backward-paragraph (cond ((> numeric-arg 0) 1) - ((< numeric-arg 0) -1) - (t 0)))) - (push-mark - (save-excursion - (forward-paragraph numeric-arg) - (point)) - t t))))) +repeated or (in Transient Mark mode) if the mark is active, +it marks the next ARG paragraphs after the ones already marked." + (interactive "p\np") + (unless arg (setq arg 1)) + (when (zerop arg) + (error "Cannot mark zero paragraphs")) + (cond ((and allow-extend + (or (and (eq last-command this-command) (mark t)) + (and transient-mark-mode mark-active))) + (set-mark + (save-excursion + (goto-char (mark)) + (forward-paragraph arg) + (point)))) + (t + (forward-paragraph arg) + (push-mark nil t t) + (backward-paragraph arg)))) (defun kill-paragraph (arg) "Kill forward to end of paragraph. diff --git a/test/lisp/textmodes/paragraphs-resources/mark-paragraph.bin b/test/lisp/textmodes/paragraphs-resources/mark-paragraph.bin new file mode 100644 index 0000000000..1905477af8 --- /dev/null +++ b/test/lisp/textmodes/paragraphs-resources/mark-paragraph.bin @@ -0,0 +1,9 @@ +First +paragraph + +Second + +Third +paragraph + +No line end \ No newline at end of file diff --git a/test/lisp/textmodes/paragraphs-tests.el b/test/lisp/textmodes/paragraphs-tests.el index bf7f37090f..712169029d 100644 --- a/test/lisp/textmodes/paragraphs-tests.el +++ b/test/lisp/textmodes/paragraphs-tests.el @@ -24,6 +24,7 @@ ;;; Code: (require 'ert) +(require 'ert-x) ;; (require 'paragraphs) ; loaded by default (ert-deftest paragraphs-tests-sentence-end () @@ -161,5 +162,27 @@ (should (equal (buffer-string) "First sentence. Third sentence. Second sentence.")))) +(ert-deftest test-mark-paragraphs () + (with-current-buffer + (find-file-noselect (ert-resource-file "mark-paragraph.bin")) + (goto-char (point-max)) + ;; Just a sanity check that the file hasn't changed. + (should (= (point) 54)) + (mark-paragraph) + (should (= (point) 42)) + (should (= (mark) 54)) + ;; Doesn't move. + (mark-paragraph) + (should (= (point) 42)) + (should (= (mark) 54)) + (forward-line -1) + (mark-paragraph) + (should (= (point) 25)) + (should (= (mark) 42)) + (goto-char (point-min)) + (mark-paragraph) + (should (= (point) 1)) + (should (= (mark) 17)))) + (provide 'paragraphs-tests) ;;; paragraphs-tests.el ends here commit 9db1c0993a99853968c021d094eba37c0cae60bb Author: Michael Albinus Date: Thu Jan 7 10:14:37 2021 +0100 * test/Makefile.in (WRITE_LOG): Mark also problematic tests for emba. diff --git a/test/Makefile.in b/test/Makefile.in index 8aa37ca785..fc40dad5e2 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -161,11 +161,15 @@ endif ## Save logs, and show logs for failed tests. WRITE_LOG = > $@ 2>&1 || { STAT=$$?; cat $@; exit $$STAT; } +## On Hydra or Emba, always show logs for certain problematic tests. ifdef EMACS_HYDRA_CI -## On Hydra, always show logs for certain problematic tests. lisp/net/tramp-tests.log \ : WRITE_LOG = 2>&1 | tee $@ endif +ifdef EMACS_EMBA_CI +lisp/filenotify-tests.log lisp/net/tramp-tests.log \ +: WRITE_LOG = 2>&1 | tee $@ +endif ifeq ($(TEST_LOAD_EL), yes) testloadfile = $*.el commit 9b31802e2d13cf8478c23d651741b54ffd4b984b Author: Glenn Morris Date: Wed Jan 6 17:19:17 2021 -0800 Update a substitute-command-keys test * test/lisp/help-tests.el (help-tests-substitute-command-keys/keymaps): Update for "Pretty-print keys without <> around modifiers" change. diff --git a/test/lisp/help-tests.el b/test/lisp/help-tests.el index 95557c95eb..835d9fe794 100644 --- a/test/lisp/help-tests.el +++ b/test/lisp/help-tests.el @@ -102,7 +102,7 @@ RET minibuffer-complete-and-exit ESC Prefix Command SPC minibuffer-complete-word ? minibuffer-completion-help - file-cache-minibuffer-complete +C- file-cache-minibuffer-complete previous-history-element next-history-element next-line-or-history-element commit 331e40a8fd491ceb35c08a3345785dab61bc60d9 Author: Daniel Martín Date: Wed Jan 6 22:53:40 2021 +0200 Fix some failing tests in BSD systems * test/lisp/progmodes/xref-tests.el (xref--xref-file-name-display-is-abs) (xref--xref-file-name-display-is-relative-to-project-root): Accommodate some older versions of BSD find (https://lists.gnu.org/archive/html/emacs-devel/2021-01/msg00156.html). diff --git a/test/lisp/progmodes/xref-tests.el b/test/lisp/progmodes/xref-tests.el index eaafc5888c..b4b5e4db5d 100644 --- a/test/lisp/progmodes/xref-tests.el +++ b/test/lisp/progmodes/xref-tests.el @@ -99,13 +99,18 @@ (should (null (marker-position (cdr (nth 0 (cdr cons2)))))))) (ert-deftest xref--xref-file-name-display-is-abs () - (let ((xref-file-name-display 'abs)) - (should (equal (delete-dups - (mapcar 'xref-location-group - (xref-tests--locations-in-data-dir "\\(bar\\|foo\\)"))) - (list - (concat xref-tests--data-dir "file1.txt") - (concat xref-tests--data-dir "file2.txt")))))) + (let ((xref-file-name-display 'abs) + ;; Some older BSD find versions can produce '//' in the output. + (expected (list + (concat xref-tests--data-dir "/?file1.txt") + (concat xref-tests--data-dir "/?file2.txt"))) + (actual (delete-dups + (mapcar 'xref-location-group + (xref-tests--locations-in-data-dir "\\(bar\\|foo\\)"))))) + (should (and (= (length expected) (length actual)) + (cl-every (lambda (e1 e2) + (string-match-p e1 e2)) + expected actual))))) (ert-deftest xref--xref-file-name-display-is-nondirectory () (let ((xref-file-name-display 'nondirectory)) @@ -121,10 +126,15 @@ (file-name-directory (directory-file-name xref-tests--data-dir))) (project-find-functions #'(lambda (_) (cons 'transient data-parent-dir))) - (xref-file-name-display 'project-relative)) - (should (equal (delete-dups - (mapcar 'xref-location-group - (xref-tests--locations-in-data-dir "\\(bar\\|foo\\)"))) - (list - "xref-resources/file1.txt" - "xref-resources/file2.txt"))))) + (xref-file-name-display 'project-relative) + ;; Some older BSD find versions can produce '//' in the output. + (expected (list + "xref-resources//?file1.txt" + "xref-resources//?file2.txt")) + (actual (delete-dups + (mapcar 'xref-location-group + (xref-tests--locations-in-data-dir "\\(bar\\|foo\\)"))))) + (should (and (= (length expected) (length actual)) + (cl-every (lambda (e1 e2) + (string-match-p e1 e2)) + expected actual))))) commit 665b4e7c4e093391a353506e7b2385f0902db70b Author: Dmitry Gutov Date: Wed Jan 6 19:41:55 2021 +0200 Proof some searches and file listings against symlinks * lisp/progmodes/project.el (project--files-in-directory): Make sure the directory includes the trailing slash in case it's a symlink, discussed in https://lists.gnu.org/archive/html/emacs-devel/2021-01/msg00345.html. * lisp/progmodes/xref.el (xref-matches-in-directory): Same. * lisp/cedet/semantic/symref/grep.el (semantic-symref-perform-search): Same. diff --git a/lisp/cedet/semantic/symref/grep.el b/lisp/cedet/semantic/symref/grep.el index 5f9a3fa352..9f0ac38ec7 100644 --- a/lisp/cedet/semantic/symref/grep.el +++ b/lisp/cedet/semantic/symref/grep.el @@ -168,7 +168,8 @@ This shell should support pipe redirect syntax." (erase-buffer) (setq default-directory rootdir) (let ((cmd (semantic-symref-grep-use-template - (file-local-name rootdir) filepattern grepflags greppat))) + (file-name-as-directory (file-local-name rootdir)) + filepattern grepflags greppat))) (process-file semantic-symref-grep-shell nil b nil shell-command-switch cmd))) (setq ans (semantic-symref-parse-tool-output tool b)) diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index d417382c0d..62c3cf44cb 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -291,7 +291,8 @@ to find the list of ignores for each directory." (localdir (file-local-name (expand-file-name dir))) (command (format "%s %s %s -type f %s -print0" find-program - localdir + ;; In case DIR is a symlink. + (file-name-as-directory localdir) (xref--find-ignores-arguments ignores localdir) (if files (concat (shell-quote-argument "(") diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 2fefc23e19..b393b8d0f1 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -1374,7 +1374,8 @@ IGNORES is a list of glob patterns for files to ignore." ;; do that reliably enough, without creating false negatives? (command (xref--rgrep-command (xref--regexp-to-extended regexp) files - (file-local-name (expand-file-name dir)) + (file-name-as-directory + (file-local-name (expand-file-name dir))) ignores)) (def default-directory) (buf (get-buffer-create " *xref-grep*")) commit 7936c8a96060fa118220d4d874f740dc75e2fe47 Author: Gabriel do Nascimento Ribeiro Date: Wed Jan 6 20:27:26 2021 +0200 * lisp/mb-depth.el (minibuffer-depth-indicator): New face. (minibuffer-depth-setup): Use new face and add a single space between the depth indicator and the minibuffer prompt. https://lists.gnu.org/archive/html/emacs-devel/2020-12/msg00230.html Copyright-paperwork-exempt: yes diff --git a/lisp/mb-depth.el b/lisp/mb-depth.el index 06da0739d6..ea2ea174b5 100644 --- a/lisp/mb-depth.el +++ b/lisp/mb-depth.el @@ -35,6 +35,10 @@ It is called with one argument, the minibuffer depth, and must return a string.") +(defface minibuffer-depth-indicator '((t :inherit highlight)) + "Face to use for minibuffer depth indicator." + :version "28.1") + ;; An overlay covering the prompt. This is a buffer-local variable in ;; each affected minibuffer. ;; @@ -52,7 +56,10 @@ The prompt should already have been inserted." (overlay-put minibuffer-depth-overlay 'before-string (if minibuffer-depth-indicator-function (funcall minibuffer-depth-indicator-function depth) - (propertize (format "[%d]" depth) 'face 'highlight))) + (concat (propertize (format "[%d]" depth) + 'face + 'minibuffer-depth-indicator) + " "))) (overlay-put minibuffer-depth-overlay 'evaporate t)))) ;;;###autoload commit 96bbbaec5c1b2612946ff08abf9d43e7478e8c43 Author: Michael Heerdegen Date: Tue Dec 22 05:44:47 2020 +0100 Fix obsolete variable warnings about class names * lisp/emacs-lisp/eieio-core.el (eieio-defclass-autoload): Try to make the wording of the warning about the obsoleted variable less confusing. * lisp/emacs-lisp/bytecomp.el (byte-compile-check-variable): Don't warn for lexical variables (Bug#39169). Fix spurious `or'. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp/warn-obsolete-variable-bound\.el): New test. * test/lisp/emacs-lisp/bytecomp-resources/warn-obsolete-variable-bound.el: New file. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 76457814ac..360da6b6ba 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -3441,10 +3441,11 @@ for symbols generated by the byte compiler itself." (and od (not (memq var byte-compile-not-obsolete-vars)) (not (memq var byte-compile-global-not-obsolete-vars)) - (or (pcase (nth 1 od) - ('set (not (eq access-type 'reference))) - ('get (eq access-type 'reference)) - (_ t))))) + (not (memq var byte-compile-lexical-variables)) + (pcase (nth 1 od) + ('set (not (eq access-type 'reference))) + ('get (eq access-type 'reference)) + (_ t)))) (byte-compile-warn-obsolete var)))) (defsubst byte-compile-dynamic-variable-op (base-op var) diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index 3e5e9b9523..a8361c0d4b 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el @@ -215,7 +215,8 @@ It creates an autoload function for CNAME's constructor." ;; turn this into a usable self-pointing symbol (when eieio-backward-compatibility (set cname cname) - (make-obsolete-variable cname (format "use \\='%s instead" cname) + (make-obsolete-variable cname (format "\ +use \\='%s or turn off `eieio-backward-compatibility' instead" cname) "25.1")) (setf (cl--find-class cname) newc) diff --git a/test/lisp/emacs-lisp/bytecomp-resources/warn-obsolete-variable-bound.el b/test/lisp/emacs-lisp/bytecomp-resources/warn-obsolete-variable-bound.el new file mode 100644 index 0000000000..e65a541e6e --- /dev/null +++ b/test/lisp/emacs-lisp/bytecomp-resources/warn-obsolete-variable-bound.el @@ -0,0 +1,7 @@ +;;; -*- lexical-binding: t -*- + +(make-obsolete-variable 'bytecomp--tests-obsolete-var-2 nil "99.99") + +(defun foo () + (let ((bytecomp--tests-obsolete-var-2 2)) + bytecomp--tests-obsolete-var-2)) diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el index 5e5f99dbda..a07af188fa 100644 --- a/test/lisp/emacs-lisp/bytecomp-tests.el +++ b/test/lisp/emacs-lisp/bytecomp-tests.el @@ -625,6 +625,9 @@ Subtests signal errors if something goes wrong." (bytecomp--define-warning-file-test "warn-obsolete-variable.el" "bytecomp--tests-obs.*obsolete.*99.99") +(bytecomp--define-warning-file-test "warn-obsolete-variable-bound.el" + "bytecomp--tests-obs.*obsolete.*99.99" t) + (bytecomp--define-warning-file-test "warn-redefine-defun-as-macro.el" "as both function and macro") commit ba011e487d40b96691d3e7af917ff6ce9d7c7a00 Author: Stefan Monnier Date: Tue Jan 5 21:29:41 2021 -0500 * lisp/play/dunnet.el: Run the game when loaded via `--batch -l dunnet` (dun--batch): Rename from `dun-batch` and don't autoload. (dunnet): Delegate to `dun--batch` when in batch mode. diff --git a/lisp/play/dunnet.el b/lisp/play/dunnet.el index e328b6eab5..3916e35f76 100644 --- a/lisp/play/dunnet.el +++ b/lisp/play/dunnet.el @@ -25,7 +25,8 @@ ;;; Commentary: ;; This game can be run in batch mode. To do this, use: -;; emacs -batch -l dunnet +;; +;; emacs --batch -f dunnet ;;; Code: @@ -1170,11 +1171,13 @@ treasures for points?" "4" "four") (defun dunnet () "Switch to *dungeon* buffer and start game." (interactive) - (pop-to-buffer-same-window "*dungeon*") - (dun-mode) - (setq dun-dead nil) - (setq dun-room 0) - (dun-messages)) + (if noninteractive + (dun--batch) + (pop-to-buffer-same-window "*dungeon*") + (dun-mode) + (setq dun-dead nil) + (setq dun-room 0) + (dun-messages))) ;;;; ;;;; This section contains all of the verbs and commands. @@ -3126,8 +3129,7 @@ File not found"))) (dun-mprinc "\n") (dun-batch-loop)) -;;;###autoload -(defun dun-batch () +(defun dun--batch () "Start `dunnet' in batch mode." (fset 'dun-mprinc #'dun-batch-mprinc) (fset 'dun-mprincl #'dun-batch-mprincl) @@ -3140,6 +3142,17 @@ File not found"))) (setq dun-batch-mode t) (dun-batch-loop)) +;; Apparently, there are many references out there to running us via +;; +;; emacs --batch -l dunnet +;; +;; So try and accommodate those without interfering with other cases +;; where `dunnet.el' might be loaded in batch mode with no intention +;; to run the game. +(when (and noninteractive + (equal '("-l" "dunnet") (member "-l" command-line-args))) + (dun--batch)) + (provide 'dunnet) ;; Local Variables: commit cf672c66711c0aa24500cab99eb7f2ef63b02bf2 Author: Stefan Monnier Date: Tue Jan 5 21:26:03 2021 -0500 * lisp/emacs-lisp/package.el (package-activate-all): Another tweak `package-quickstart.el` files presume `package-activated-list` is a bound variable, so make sure this is the case even when `package.el` is not yet loaded. diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index a38363df23..453e86c783 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -1640,6 +1640,8 @@ The variable `package-load-list' controls which packages to load." ;; 2 when loading the .el file (this assumes we were careful to ;; save this file so it doesn't need any decoding). (let ((load-source-file-function nil)) + (unless (boundp 'package-activated-list) + (setq package-activated-list nil)) (load qs nil 'nomessage)) (require 'package) (package--activate-all))))) commit 7d7bfbf0346114b116e14a4338ea235d12674f13 Author: Stefan Monnier Date: Tue Jan 5 17:57:15 2021 -0500 * lisp/emacs-lisp/autoload.el: Improve last change It turns out there were other places that used `custom-initialize-delay` on autoloaded variables and used various hacks to make it work with `autoload.el`. The new code makes those hacks unneeded. Also, there's no point trying to "optimize" those rare cases anyway, so I simplified the `autoload.el` code for those cases. (make-autoload): For non-trivial cases, just include the whole `defcustom` instead of trying to mimic it. * lisp/mail/rmail.el (rmail-spool-directory): Remove hacks. * lisp/info.el (Info-default-directory-list): Remove `progn` hack. * lisp/custom.el (custom-declare-variable) (custom-handle-all-keywords): Don't use pseudo-group `nil`. diff --git a/lisp/custom.el b/lisp/custom.el index dfa8539c44..d9d0898dcb 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -161,7 +161,9 @@ set to nil, as the value is no longer rogue." ;; Whether automatically buffer-local. buffer-local) (unless (memq :group args) - (custom-add-to-group (custom-current-group) symbol 'custom-variable)) + (let ((cg (custom-current-group))) + (when cg + (custom-add-to-group cg symbol 'custom-variable)))) (while args (let ((keyword (pop args))) (unless (symbolp keyword) @@ -525,7 +527,9 @@ If no such group is found, return nil." "For customization option SYMBOL, handle keyword arguments ARGS. Third argument TYPE is the custom option type." (unless (memq :group args) - (custom-add-to-group (custom-current-group) symbol type)) + (let ((cg (custom-current-group))) + (when cg + (custom-add-to-group cg symbol type)))) (while args (let ((arg (car args))) (setq args (cdr args)) diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el index 77de05a6f6..ec7492dd4b 100644 --- a/lisp/emacs-lisp/autoload.el +++ b/lisp/emacs-lisp/autoload.el @@ -220,22 +220,27 @@ expression, in which case we want to handle forms differently." ;; Convert defcustom to less space-consuming data. ((eq car 'defcustom) - (let ((varname (car-safe (cdr-safe form))) - (initializer (plist-get (nthcdr 4 form) :initialize)) - (init (car-safe (cdr-safe (cdr-safe form)))) - (doc (car-safe (cdr-safe (cdr-safe (cdr-safe form))))) - ;; (rest (cdr-safe (cdr-safe (cdr-safe (cdr-safe form))))) - ) + (let* ((varname (car-safe (cdr-safe form))) + (props (nthcdr 4 form)) + (initializer (plist-get props :initialize)) + (init (car-safe (cdr-safe (cdr-safe form)))) + (doc (car-safe (cdr-safe (cdr-safe (cdr-safe form))))) + ;; (rest (cdr-safe (cdr-safe (cdr-safe (cdr-safe form))))) + ) `(progn - ,(if (null initializer) - `(defvar ,varname ,init ,doc) - `(progn (defvar ,varname nil ,doc) - (let ((exp ',init)) - (put ',varname 'standard-value (list exp)) - (,(eval initializer t) ',varname exp)))) + ,(if (not (member initializer '(nil 'custom-initialize-default + #'custom-initialize-default + 'custom-initialize-reset + #'custom-initialize-reset))) + form + `(defvar ,varname ,init ,doc)) + ;; When we include the complete `form', this `custom-autoload' + ;; is not indispensable, but it still helps in case the `defcustom' + ;; doesn't specify its group explicitly, and probably in a few other + ;; corner cases. (custom-autoload ',varname ,file ,(condition-case nil - (null (cadr (memq :set form))) + (null (plist-get props :set)) (error nil)))))) ((eq car 'defgroup) diff --git a/lisp/info.el b/lisp/info.el index ef94aa945f..62d7b583ff 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -160,17 +160,14 @@ A header-line does not scroll with the rest of the buffer." :version "24.4") ;; This is a defcustom largely so that we can get the benefit -;; of custom-initialize-delay. Perhaps it would work to make it a -;; defvar and explicitly give it a standard-value property, and -;; call custom-initialize-delay on it. -;; The progn forces the autoloader to include the whole thing, not -;; just an abbreviated version. The value is initialized at startup -;; time, when command-line calls custom-reevaluate-setting on all -;; the defcustoms in custom-delayed-init-variables. This is -;; somewhat sub-optimal, as ideally this should be done when Info -;; mode is first invoked. +;; of `custom-initialize-delay'. Perhaps it would work to make it a +;; `defvar' and explicitly give it a `standard-value' property, and +;; call `custom-initialize-delay' on it. +;; The value is initialized at startup time, when command-line calls +;; `custom-reevaluate-setting' on all the defcustoms in +;; `custom-delayed-init-variables'. This is somewhat sub-optimal, as ideally +;; this should be done when Info mode is first invoked. ;;;###autoload -(progn (defcustom Info-default-directory-list (let* ((config-dir (file-name-as-directory @@ -232,8 +229,8 @@ the environment variable INFOPATH is set. Although this is a customizable variable, that is mainly for technical reasons. Normally, you should either set INFOPATH or customize `Info-additional-directory-list', rather than changing this variable." - :initialize 'custom-initialize-delay - :type '(repeat directory))) + :initialize #'custom-initialize-delay + :type '(repeat directory)) (defvar Info-directory-list nil "List of directories to search for Info documentation files. diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el index 69797837cd..29460cc20f 100644 --- a/lisp/mail/rmail.el +++ b/lisp/mail/rmail.el @@ -160,13 +160,6 @@ its character representation and its display representation.") :group 'rmail :version "21.1") -;;;###autoload -(put 'rmail-spool-directory 'standard-value - '((cond ((file-exists-p "/var/mail") "/var/mail/") - ((file-exists-p "/var/spool/mail") "/var/spool/mail/") - ((memq system-type '(hpux usg-unix-v)) "/usr/mail/") - (t "/usr/spool/mail/")))) - ;;;###autoload (defcustom rmail-spool-directory (purecopy @@ -181,12 +174,10 @@ its character representation and its display representation.") (t "/usr/spool/mail/"))) "Name of directory used by system mailer for delivering new mail. Its name should end with a slash." - :initialize 'custom-initialize-delay + :initialize #'custom-initialize-delay :type 'directory :group 'rmail) -;;;###autoload(custom-initialize-delay 'rmail-spool-directory nil) - (defcustom rmail-movemail-program nil "If non-nil, the file name of the `movemail' program." :group 'rmail-retrieve commit 048b1aaec8d5cd4ce6e6a5a9b8091608d0af81a6 Author: Alan Third Date: Tue Jan 5 21:43:12 2021 +0000 Prevent stack overflow in GNUstep menu code * src/nsmenu.m (ns_update_menubar): Always do a deep update for GNUstep. ([EmacsMenu menuNeedsUpdate:]): Don't update the menu as it should always have had a deep update. diff --git a/src/nsmenu.m b/src/nsmenu.m index 9b56958100..8086f56854 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -145,6 +145,10 @@ t = -(1000*tb.time+tb.millitm); #endif +#ifdef NS_IMPL_GNUSTEP + deep_p = 1; /* See comment in menuNeedsUpdate. */ +#endif + if (deep_p) { /* Make a widget-value tree representing the entire menu trees. */ @@ -433,21 +437,22 @@ - (instancetype)initWithTitle: (NSString *)title } -/* Delegate method called when a submenu is being opened: run a 'deep' call - to set_frame_menubar. */ - -/* TODO: GNUstep calls this method when the menu is still being built - which throws it into an infinite loop. One possible solution is to - use menuWillOpen instead, but the Apple docs explicitly warn - against changing the contents of the menu in it. I don't know what - the right thing to do for GNUstep is. */ +/* Delegate method called when a submenu is being opened: run a 'deep' + call to ns_update_menubar. */ - (void)menuNeedsUpdate: (NSMenu *)menu { if (!FRAME_LIVE_P (SELECTED_FRAME ())) return; +#ifdef NS_IMPL_COCOA +/* TODO: GNUstep calls this method when the menu is still being built + which results in a recursive stack overflow. One possible solution + is to use menuWillOpen instead, but the Apple docs explicitly warn + against changing the contents of the menu in it. I don't know what + the right thing to do for GNUstep is. */ if (needsUpdate) ns_update_menubar (SELECTED_FRAME (), true); +#endif } commit 3b835f7b81030f482348364e83f384a0fa4c2857 Author: Juri Linkov Date: Tue Jan 5 20:59:51 2021 +0200 * lisp/subr.el (remove-hook): Add default value (bug#45393) diff --git a/lisp/subr.el b/lisp/subr.el index 50acbd2790..a5a979a217 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1800,7 +1800,11 @@ unless HOOK has both local and global functions). If multiple functions have the same representation under `princ', the first one will be removed." (interactive - (let* ((hook (intern (completing-read "Hook variable: " obarray #'boundp t))) + (let* ((default (and (symbolp (variable-at-point)) + (symbol-name (variable-at-point)))) + (hook (intern (completing-read + (format-prompt "Hook variable" default) + obarray #'boundp t nil nil default))) (local (and (local-variable-p hook) commit 7469214d94981d4dbc1ca83a427000fd2b257b47 Author: Juri Linkov Date: Tue Jan 5 20:55:29 2021 +0200 * lisp/tab-bar.el (tab-bar-tab-name-format-function): New defcustom. (tab-bar-tab-name-format-default): New function as the default value. (tab-bar-make-keymap-1): Funcall tab-bar-tab-name-format-function. diff --git a/etc/NEWS b/etc/NEWS index d1cc422e9f..48fb4b88e1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -396,10 +396,19 @@ of the next command to be displayed in a new tab. +++ *** New command 'C-x t C-r' to open file read-only in other tab. +--- *** The tab bar is frame-local when 'tab-bar-show' is a number. Show/hide the tab bar independently for each frame, according to the value of 'tab-bar-show'. +--- +*** New command 'toggle-frame-tab-bar'. +It can be used to enable/disable the tab bar individually +on each frame independently from the state of `tab-bar-mode'. + +--- +*** New user option 'tab-bar-tab-name-format-function'. + --- *** The tabs in the tab line can now be scrolled using horizontal scroll. If your mouse or trackpad supports it, you can now scroll tabs when diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index b44fcfa3a0..5a95e5975d 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -436,6 +436,30 @@ Return its existing value or a new value." tabs)) +(defcustom tab-bar-tab-name-format-function #'tab-bar-tab-name-format-default + "Function to format a tab name. +Function gets two arguments, the tab and its number, and should return +the formatted tab name to display in the tab bar." + :type 'function + :initialize 'custom-initialize-default + :set (lambda (sym val) + (set-default sym val) + (force-mode-line-update)) + :group 'tab-bar + :version "28.1") + +(defun tab-bar-tab-name-format-default (tab i) + (let ((current-p (eq (car tab) 'current-tab))) + (propertize + (concat (if tab-bar-tab-hints (format "%d " i) "") + (alist-get 'name tab) + (or (and tab-bar-close-button-show + (not (eq tab-bar-close-button-show + (if current-p 'non-selected 'selected))) + tab-bar-close-button) + "")) + 'face (if current-p 'tab-bar-tab 'tab-bar-tab-inactive)))) + (defun tab-bar-make-keymap-1 () "Generate an actual keymap from `tab-bar-map', without caching." (let* ((separator (or tab-bar-separator (if window-system " " "|"))) @@ -461,25 +485,13 @@ Return its existing value or a new value." ((eq (car tab) 'current-tab) `((current-tab menu-item - ,(propertize (concat (if tab-bar-tab-hints (format "%d " i) "") - (alist-get 'name tab) - (or (and tab-bar-close-button-show - (not (eq tab-bar-close-button-show - 'non-selected)) - tab-bar-close-button) "")) - 'face 'tab-bar-tab) + ,(funcall tab-bar-tab-name-format-function tab i) ignore :help "Current tab"))) (t `((,(intern (format "tab-%i" i)) menu-item - ,(propertize (concat (if tab-bar-tab-hints (format "%d " i) "") - (alist-get 'name tab) - (or (and tab-bar-close-button-show - (not (eq tab-bar-close-button-show - 'selected)) - tab-bar-close-button) "")) - 'face 'tab-bar-tab-inactive) + ,(funcall tab-bar-tab-name-format-function tab i) ,(or (alist-get 'binding tab) `(lambda () commit e72fd12ec688efe046de98d5a6494fe2ffab7762 Author: Juri Linkov Date: Tue Jan 5 20:43:22 2021 +0200 * lisp/tab-bar.el (toggle-frame-tab-bar): New command (bug#45556) diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 93f3c550ce..b44fcfa3a0 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -196,6 +196,18 @@ See `tab-bar-mode' for more information." (tab-bar-mode (if (> (frame-parameter nil 'tab-bar-lines) 0) 0 1)) (tab-bar-mode arg))) +(defun toggle-frame-tab-bar (&optional frame) + "Toggle tab bar of FRAME. +This is useful when you want to enable the tab bar individually +on each new frame when the global `tab-bar-mode' is disabled, +or when you want to disable the tab bar individually on each +new frame when the global `tab-bar-mode' is enabled, by using + + (add-hook 'after-make-frame-functions 'toggle-frame-tab-bar)" + (interactive) + (set-frame-parameter frame 'tab-bar-lines + (if (> (frame-parameter frame 'tab-bar-lines) 0) 0 1))) + (defvar tab-bar-map (make-sparse-keymap) "Keymap for the tab bar. Define this locally to override the global tab bar.") commit c1daeb4c2826af28311a08100e98948349715c37 Author: James N. V. Cash Date: Tue Jan 5 20:35:35 2021 +0200 Refactor tab-bar-mode to -define-keys and -load-buttons (bug#42052) * lisp/tab-bar.el (tab-bar--define-keys, tab-bar--load-buttons): Move some code here from 'tab-bar-mode'. (tab-bar-new-tab-to): Call tab-bar--load-buttons and tab-bar--define-keys. Copyright-paperwork-exempt: yes diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 935c97e2a4..93f3c550ce 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -95,23 +95,26 @@ Possible modifier keys are `control', `meta', `shift', `hyper', `super' and :version "27.1") -(define-minor-mode tab-bar-mode - "Toggle the tab bar in all graphical frames (Tab Bar mode)." - :global t - ;; It's defined in C/cus-start, this stops the d-m-m macro defining it again. - :variable tab-bar-mode - (let ((val (if tab-bar-mode 1 0))) - (dolist (frame (frame-list)) - (set-frame-parameter frame 'tab-bar-lines val)) - ;; If the user has given `default-frame-alist' a `tab-bar-lines' - ;; parameter, replace it. - (if (assq 'tab-bar-lines default-frame-alist) - (setq default-frame-alist - (cons (cons 'tab-bar-lines val) - (assq-delete-all 'tab-bar-lines - default-frame-alist))))) - - (when (and tab-bar-mode tab-bar-new-button +(defun tab-bar--define-keys () + "Install key bindings for switching between tabs if the user has configured them." + (when tab-bar-select-tab-modifiers + (global-set-key (vector (append tab-bar-select-tab-modifiers (list ?0))) + 'tab-bar-switch-to-recent-tab) + (dotimes (i 9) + (global-set-key (vector (append tab-bar-select-tab-modifiers + (list (+ i 1 ?0)))) + 'tab-bar-select-tab))) + ;; Don't override user customized key bindings + (unless (global-key-binding [(control tab)]) + (global-set-key [(control tab)] 'tab-next)) + (unless (global-key-binding [(control shift tab)]) + (global-set-key [(control shift tab)] 'tab-previous)) + (unless (global-key-binding [(control shift iso-lefttab)]) + (global-set-key [(control shift iso-lefttab)] 'tab-previous))) + +(defun tab-bar--load-buttons () + "Load the icons for the tab buttons." + (when (and tab-bar-new-button (not (get-text-property 0 'display tab-bar-new-button))) ;; This file is pre-loaded so only here we can use the right data-directory: (add-text-properties 0 (length tab-bar-new-button) @@ -121,7 +124,7 @@ Possible modifier keys are `control', `meta', `shift', `hyper', `super' and :ascent center)) tab-bar-new-button)) - (when (and tab-bar-mode tab-bar-close-button + (when (and tab-bar-close-button (not (get-text-property 0 'display tab-bar-close-button))) ;; This file is pre-loaded so only here we can use the right data-directory: (add-text-properties 0 (length tab-bar-close-button) @@ -129,24 +132,27 @@ Possible modifier keys are `control', `meta', `shift', `hyper', `super' and :file "tabs/close.xpm" :margin (2 . 0) :ascent center)) - tab-bar-close-button)) + tab-bar-close-button))) +(define-minor-mode tab-bar-mode + "Toggle the tab bar in all graphical frames (Tab Bar mode)." + :global t + ;; It's defined in C/cus-start, this stops the d-m-m macro defining it again. + :variable tab-bar-mode + (let ((val (if tab-bar-mode 1 0))) + (dolist (frame (frame-list)) + (set-frame-parameter frame 'tab-bar-lines val)) + ;; If the user has given `default-frame-alist' a `tab-bar-lines' + ;; parameter, replace it. + (if (assq 'tab-bar-lines default-frame-alist) + (setq default-frame-alist + (cons (cons 'tab-bar-lines val) + (assq-delete-all 'tab-bar-lines + default-frame-alist))))) + (when tab-bar-mode + (tab-bar--load-buttons)) (if tab-bar-mode - (progn - (when tab-bar-select-tab-modifiers - (global-set-key (vector (append tab-bar-select-tab-modifiers (list ?0))) - 'tab-bar-switch-to-recent-tab) - (dotimes (i 9) - (global-set-key (vector (append tab-bar-select-tab-modifiers - (list (+ i 1 ?0)))) - 'tab-bar-select-tab))) - ;; Don't override user customized key bindings - (unless (global-key-binding [(control tab)]) - (global-set-key [(control tab)] 'tab-next)) - (unless (global-key-binding [(control shift tab)]) - (global-set-key [(control shift tab)] 'tab-previous)) - (unless (global-key-binding [(control shift iso-lefttab)]) - (global-set-key [(control shift iso-lefttab)] 'tab-previous))) + (tab-bar--define-keys) ;; Unset only keys bound by tab-bar (when (eq (global-key-binding [(control tab)]) 'tab-next) (global-unset-key [(control tab)])) @@ -815,7 +821,10 @@ After the tab is created, the hooks in ((and (natnump tab-bar-show) (> (length (funcall tab-bar-tabs-function)) tab-bar-show) (zerop (frame-parameter nil 'tab-bar-lines))) - (set-frame-parameter nil 'tab-bar-lines 1))) + (progn + (tab-bar--load-buttons) + (tab-bar--define-keys) + (set-frame-parameter nil 'tab-bar-lines 1)))) (force-mode-line-update) (unless tab-bar-mode commit 02e6ffe860cacc2681448b40f8b3279d31442b58 Author: Eli Zaretskii Date: Tue Jan 5 20:26:38 2021 +0200 Fix process-tests on MS-Windows It was again broken by recent changes. * test/src/process-tests.el (process-tests/fd-setsize-no-crash/make-serial-process): Skip test on MS-Windows. diff --git a/test/src/process-tests.el b/test/src/process-tests.el index 1f88232c7f..ca98f54bdb 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -646,6 +646,8 @@ FD_SETSIZE file descriptors (Bug#24325)." (ert-deftest process-tests/fd-setsize-no-crash/make-serial-process () "Check that Emacs doesn't crash when trying to use more than FD_SETSIZE file descriptors (Bug#24325)." + ;; This test cannot be run if PTYs aren't supported. + (skip-unless (not (eq system-type 'windows-nt))) (with-timeout (60 (ert-fail "Test timed out")) (process-tests--with-processes processes ;; In order to use `make-serial-process', we need to create some @@ -667,6 +669,15 @@ FD_SETSIZE file descriptors (Bug#24325)." (tty-name (process-tty-name host))) (should (processp host)) (push host processes) + ;; FIXME: The assumption below that using :connection 'pty + ;; in make-process necessarily produces a process with PTY + ;; connection is unreliable and non-portable. + ;; make-process can legitimately and silently fall back on + ;; pipes if allocating a PTY fails (and on MS-Windows it + ;; always fails). The following code also assumes that + ;; process-tty-name produces a file name that can be + ;; passed to 'stat' and to make-serial-process, which is + ;; also non-portable. (should tty-name) (should (file-exists-p tty-name)) (should-not (member tty-name tty-names)) commit 9973019764250ac1f4d77a6b426cdd9c241151c5 Author: Stefan Monnier Date: Tue Jan 5 12:28:37 2021 -0500 * lisp/emacs-lisp/package.el: Load package-quickstart without package.el Speed up startup when `package-quickstart` is in use by making it possible to load the quickstart file without having to load `package.el` at all. (package-user-dir, package-directory-list, package-quickstart-file): Preload those variables. (package--get-activatable-pkg): New fun, extracted from `package-activate`. (package-activate): Use it. (package--activate-all): New function, extracted from `package-activate-all`. (package-activate-all): Use it and make the function preloaded. (package--archives-initialize): New function. (package-install): Use it. (list-packages): Avoid `switch-to-buffer`. (package-get-descriptor): New function. * lisp/startup.el (command-line): Simplify the code now that package-user-dir and package-directory-list are preloaded. * lisp/emacs-lisp/autoload.el (make-autoload): Add support for `:initialize #'custom-initialize-delay` in `defcustom`. diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el index 1786b5cd6a..77de05a6f6 100644 --- a/lisp/emacs-lisp/autoload.el +++ b/lisp/emacs-lisp/autoload.el @@ -221,12 +221,18 @@ expression, in which case we want to handle forms differently." ;; Convert defcustom to less space-consuming data. ((eq car 'defcustom) (let ((varname (car-safe (cdr-safe form))) + (initializer (plist-get (nthcdr 4 form) :initialize)) (init (car-safe (cdr-safe (cdr-safe form)))) (doc (car-safe (cdr-safe (cdr-safe (cdr-safe form))))) ;; (rest (cdr-safe (cdr-safe (cdr-safe (cdr-safe form))))) ) `(progn - (defvar ,varname ,init ,doc) + ,(if (null initializer) + `(defvar ,varname ,init ,doc) + `(progn (defvar ,varname nil ,doc) + (let ((exp ',init)) + (put ',varname 'standard-value (list exp)) + (,(eval initializer t) ',varname exp)))) (custom-autoload ',varname ,file ,(condition-case nil (null (cadr (memq :set form))) diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 40ba135551..a38363df23 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -173,12 +173,12 @@ with \"-q\"). Even if the value is nil, you can type \\[package-initialize] to make installed packages available at any time, or you can -call (package-initialize) in your init-file." +call (package-activate-all) in your init-file." :type 'boolean :version "24.1") (defcustom package-load-list '(all) - "List of packages for `package-initialize' to make available. + "List of packages for `package-activate-all' to make available. Each element in this list should be a list (NAME VERSION), or the symbol `all'. The symbol `all' says to make available the latest installed versions of all packages not specified by other @@ -292,15 +292,18 @@ the package will be unavailable." :risky t :version "24.4") +;;;###autoload (defcustom package-user-dir (locate-user-emacs-file "elpa") "Directory containing the user's Emacs Lisp packages. The directory name should be absolute. Apart from this directory, Emacs also looks for system-wide packages in `package-directory-list'." :type 'directory + :initialize #'custom-initialize-delay :risky t :version "24.1") +;;;###autoload (defcustom package-directory-list ;; Defaults are subdirs named "elpa" in the site-lisp dirs. (let (result) @@ -315,6 +318,7 @@ Each directory name should be absolute. These directories contain packages intended for system-wide; in contrast, `package-user-dir' contains packages for personal use." :type '(repeat directory) + :initialize #'custom-initialize-delay :risky t :version "24.1") @@ -587,9 +591,8 @@ package." ;;; Installed packages ;; The following variables store information about packages present in ;; the system. The most important of these is `package-alist'. The -;; command `package-initialize' is also closely related to this -;; section, but it is left for a later section because it also affects -;; other stuff. +;; command `package-activate-all' is also closely related to this +;; section. (defvar package--builtins nil "Alist of built-in packages. @@ -608,7 +611,7 @@ name (a symbol) and DESCS is a non-empty list of `package-desc' structures, sorted by decreasing versions. This variable is set automatically by `package-load-descriptor', -called via `package-initialize'. To change which packages are +called via `package-activate-all'. To change which packages are loaded and/or activated, customize `package-load-list'.") (put 'package-alist 'risky-local-variable t) @@ -869,6 +872,20 @@ DIR, sorted by most recently loaded last." (lambda (x y) (< (cdr x) (cdr y)))))))) ;;;; `package-activate' + +(defun package--get-activatable-pkg (pkg-name) + ;; Is "activatable" a word? + (let ((pkg-descs (cdr (assq pkg-name package-alist)))) + ;; Check if PACKAGE is available in `package-alist'. + (while + (when pkg-descs + (let ((available-version (package-desc-version (car pkg-descs)))) + (or (package-disabled-p pkg-name available-version) + ;; Prefer a builtin package. + (package-built-in-p pkg-name available-version)))) + (setq pkg-descs (cdr pkg-descs))) + (car pkg-descs))) + ;; This function activates a newer version of a package if an older ;; one was already activated. It also loads a features of this ;; package which were already loaded. @@ -876,24 +893,16 @@ DIR, sorted by most recently loaded last." "Activate the package named PACKAGE. If FORCE is true, (re-)activate it if it's already activated. Newer versions are always activated, regardless of FORCE." - (let ((pkg-descs (cdr (assq package package-alist)))) - ;; Check if PACKAGE is available in `package-alist'. - (while - (when pkg-descs - (let ((available-version (package-desc-version (car pkg-descs)))) - (or (package-disabled-p package available-version) - ;; Prefer a builtin package. - (package-built-in-p package available-version)))) - (setq pkg-descs (cdr pkg-descs))) + (let ((pkg-desc (package--get-activatable-pkg package))) (cond ;; If no such package is found, maybe it's built-in. - ((null pkg-descs) + ((null pkg-desc) (package-built-in-p package)) ;; If the package is already activated, just return t. ((and (memq package package-activated-list) (not force)) t) ;; Otherwise, proceed with activation. - (t (package-activate-1 (car pkg-descs) nil 'deps))))) + (t (package-activate-1 pkg-desc nil 'deps))))) ;;; Installation -- Local operations @@ -1616,9 +1625,8 @@ that code in the early init-file." ;; `package--initialized' is t. (package--build-compatibility-table)) -(defvar package-quickstart-file) - ;;;###autoload +(progn ;; Make the function usable without loading `package.el'. (defun package-activate-all () "Activate all installed packages. The variable `package-load-list' controls which packages to load." @@ -1633,12 +1641,16 @@ The variable `package-load-list' controls which packages to load." ;; save this file so it doesn't need any decoding). (let ((load-source-file-function nil)) (load qs nil 'nomessage)) - (dolist (elt (package--alist)) - (condition-case err - (package-activate (car elt)) - ;; Don't let failure of activation of a package arbitrarily stop - ;; activation of further packages. - (error (message "%s" (error-message-string err)))))))) + (require 'package) + (package--activate-all))))) + +(defun package--activate-all () + (dolist (elt (package--alist)) + (condition-case err + (package-activate (car elt)) + ;; Don't let failure of activation of a package arbitrarily stop + ;; activation of further packages. + (error (message "%s" (error-message-string err)))))) ;;;; Populating `package-archive-contents' from archives ;; This subsection populates the variables listed above from the @@ -2066,6 +2078,13 @@ PACKAGES are satisfied, i.e. that PACKAGES is computed using `package-compute-transaction'." (mapc #'package-install-from-archive packages)) +(defun package--archives-initialize () + "Make sure the list of installed and remote packages are initialized." + (unless package--initialized + (package-initialize t)) + (unless package-archive-contents + (package-refresh-contents))) + ;;;###autoload (defun package-install (pkg &optional dont-select) "Install the package PKG. @@ -2086,10 +2105,7 @@ to install it but still mark it as selected." (progn ;; Initialize the package system to get the list of package ;; symbols for completion. - (unless package--initialized - (package-initialize t)) - (unless package-archive-contents - (package-refresh-contents)) + (package--archives-initialize) (list (intern (completing-read "Install package: " (delq nil @@ -2099,6 +2115,7 @@ to install it but still mark it as selected." package-archive-contents)) nil t)) nil))) + (package--archives-initialize) (add-hook 'post-command-hook #'package-menu--post-refresh) (let ((name (if (package-desc-p pkg) (package-desc-name pkg) @@ -3714,7 +3731,7 @@ short description." (package-menu--generate nil t))) ;; The package menu buffer has keybindings. If the user types ;; `M-x list-packages', that suggests it should become current. - (switch-to-buffer buf))) + (pop-to-buffer-same-window buf))) ;;;###autoload (defalias 'package-list-packages 'list-packages) @@ -4042,10 +4059,12 @@ activations need to be changed, such as when `package-load-list' is modified." :type 'boolean :version "27.1") +;;;###autoload (defcustom package-quickstart-file (locate-user-emacs-file "package-quickstart.el") "Location of the file used to speed up activation of packages at startup." :type 'file + :initialize #'custom-initialize-delay :version "27.1") (defun package--quickstart-maybe-refresh () @@ -4111,6 +4130,8 @@ activations need to be changed, such as when `package-load-list' is modified." ;; no-update-autoloads: t ;; End: ")) + ;; FIXME: Do it asynchronously in an Emacs subprocess, and + ;; don't show the byte-compiler warnings. (byte-compile-file package-quickstart-file))) (defun package--imenu-prev-index-position-function () @@ -4131,6 +4152,15 @@ beginning of the line." (package-version-join (package-desc-version package-desc)) (package-desc-summary package-desc)))) +;;;; Introspection + +(defun package-get-descriptor (pkg-name) + "Return the `package-desc' of PKG-NAME." + (unless package--initialized (package-initialize 'no-activate)) + (or (package--get-activatable-pkg pkg-name) + (cadr (assq pkg-name package-alist)) + (cadr (assq pkg-name package-archive-contents)))) + (provide 'package) ;;; package.el ends here diff --git a/lisp/startup.el b/lisp/startup.el index dfac0c8ed0..57fd87f20f 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -1230,17 +1230,7 @@ please check its value") package-enable-at-startup (not (bound-and-true-p package--activated)) (catch 'package-dir-found - (let (dirs) - (if (boundp 'package-directory-list) - (setq dirs package-directory-list) - (dolist (f load-path) - (and (stringp f) - (equal (file-name-nondirectory f) "site-lisp") - (push (expand-file-name "elpa" f) dirs)))) - (push (if (boundp 'package-user-dir) - package-user-dir - (locate-user-emacs-file "elpa")) - dirs) + (let ((dirs (cons package-user-dir package-directory-list))) (dolist (dir dirs) (when (file-directory-p dir) (dolist (subdir (directory-files dir)) commit 149d64bbb2b46f63c759fe4754bdf90eb6f2a3cc Author: Michael Albinus Date: Tue Jan 5 15:45:45 2021 +0100 * doc/misc/tramp.texi (Quick Start Guide): Fix thinko. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index cabbc9d726..0a968e3945 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -442,7 +442,7 @@ are optional, in case of a missing part a default value is assumed. The default value for an empty local file name part is the remote user's home directory. The shortest remote file name is @file{@trampfn{-,,}}, therefore. The @samp{-} notation for the -default host is used for syntactical reasons, @ref{Default Host}. +default method is used for syntactical reasons, @ref{Default Method}. The @code{method} part describes the connection method used to reach the remote host, see below. commit 97747e6fb9890ef528cbe21636cc99508efeba2b Author: Robert Pluim Date: Tue Jan 5 14:42:10 2021 +0100 Tell people how to remove fontconfig customizations diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 7499726678..cfca598d60 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -693,6 +693,11 @@ versions of gnutls-cli, or use Emacs's built-in gnutls support. ** Characters are displayed as empty boxes or with wrong font under X. +*** This may be due to your local fontconfig customization. +Try removing or moving aside "$XDG_CONFIG_HOME/fontconfig/conf.d" and +"$XDG_CONFIG_HOME/fontconfig/fonts.conf" +($XDG_CONFIG_HOME is treated as "~/.config" if not set) + *** This can occur when two different versions of FontConfig are used. For example, XFree86 4.3.0 has one version and Gnome usually comes with a newer version. Emacs compiled with Gtk+ will then use the commit 33d0c603c6795488ed0283a1e83cb02eb290f567 Author: Simen Heggestøyl Date: Tue Jan 5 12:17:13 2021 +0100 ; * doc/lispref/modes.texi (SMIE Indentation Example): Fix previous commit diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 72740868a6..746ea3eddd 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -4164,8 +4164,8 @@ Here is an example of an indentation function: (`(:elem . basic) sample-indent-basic) (`(,_ . ",") (smie-rule-separator kind)) (`(:after . ":=") sample-indent-basic) - (`(:before . ,(or `"begin" `"(" `"@{"))) - (if (smie-rule-hanging-p) (smie-rule-parent)) + (`(:before . ,(or `"begin" `"(" `"@{")) + (if (smie-rule-hanging-p) (smie-rule-parent))) (`(:before . "if") (and (not (smie-rule-bolp)) (smie-rule-prev-p "else") (smie-rule-parent))))) commit 1433a1201447f6f8b610f4d7f78a4b8a739c6572 Author: Mattias Engdegård Date: Tue Jan 5 12:01:32 2021 +0100 ruby-mode: eliminate redundant regexp branch * lisp/progmodes/ruby-mode.el (ruby-add-log-current-method): Since ruby-operator-re matches dot, don't include both in regexp. This pacifies relint. diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index cd9d087856..a8667acb9d 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -1603,9 +1603,9 @@ See `add-log-current-defun-function'." "\\(" ;; \\. and :: for class methods "\\([A-Za-z_]" ruby-symbol-re "*[?!]?" - (when method-name? "\\|") - (when method-name? ruby-operator-re) - "\\|\\.\\|::" "\\)" + "\\|" + (if method-name? ruby-operator-re "\\.") + "\\|::" "\\)" "+\\)"))) (definition-re (funcall make-definition-re ruby-defun-beg-re t)) (module-re (funcall make-definition-re "\\(class\\|module\\)"))) commit 77796eb0142f5d9b616f59f271ef380f099f1cac Author: Mattias Engdegård Date: Tue Jan 5 11:27:41 2021 +0100 ; * lisp/subr.el (ctl-x-map): Fix typo in kill-buffer binding. diff --git a/lisp/subr.el b/lisp/subr.el index 60a77859c4..50acbd2790 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1272,7 +1272,7 @@ The normal global definition of the character ESC indirects to this keymap.") (define-key map "t" tab-prefix-map) (define-key map "b" #'switch-to-buffer) - (define-key map "l" #'kill-buffer) + (define-key map "k" #'kill-buffer) (define-key map "\C-u" #'upcase-region) (put 'upcase-region 'disabled t) (define-key map "\C-l" #'downcase-region) (put 'downcase-region 'disabled t) (define-key map "<" #'scroll-left) commit 7f16f177270e8e69cb8b78fb502caae3653a32cf Author: Mattias Engdegård Date: Tue Dec 29 16:55:06 2020 +0100 Pretty-print keys without <> around modifiers (bug#45536) Be consistent when pretty-printing keys: put modifiers outside <>, thus the more logical C-M- instead of . * src/keymap.c (Fsingle_key_description): Skip modifier prefix before adding <>. * doc/lispref/help.texi (Describing Characters): Update example. * doc/lispref/debugging.texi (Backtraces): * doc/lispref/minibuf.texi (Text from Minibuffer): Use @kbd instead of @key. * etc/NEWS: Announce the change. * test/src/keymap-tests.el (keymap--key-description): * test/lisp/subr-tests.el (subr--kbd): New tests. diff --git a/doc/lispref/debugging.texi b/doc/lispref/debugging.texi index 1e779ac705..8e4b0ebfe9 100644 --- a/doc/lispref/debugging.texi +++ b/doc/lispref/debugging.texi @@ -424,7 +424,7 @@ move to it and type @key{RET}, to visit the source code. You can also type @key{RET} while point is on any name of a function or variable which is not underlined, to see help information for that symbol in a help buffer, if any exists. The @code{xref-find-definitions} command, -bound to @key{M-.}, can also be used on any identifier in a backtrace +bound to @kbd{M-.}, can also be used on any identifier in a backtrace (@pxref{Looking Up Identifiers,,,emacs, The GNU Emacs Manual}). In backtraces, the tails of long lists and the ends of long strings, diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi index 2fd05b7391..298bec5230 100644 --- a/doc/lispref/help.texi +++ b/doc/lispref/help.texi @@ -545,7 +545,7 @@ brackets. @end group @group (single-key-description 'C-mouse-1) - @result{} "" + @result{} "C-" @end group @group (single-key-description 'C-mouse-1 t) diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index 81139b9e74..f0036f0ccf 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -348,7 +348,7 @@ default, it makes the following bindings: @item @key{RET} @code{exit-minibuffer} -@item @key{M-<} +@item @kbd{M-<} @code{minibuffer-beginning-of-buffer} @item @kbd{C-g} diff --git a/etc/NEWS b/etc/NEWS index ef1c4b39a6..d1cc422e9f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -218,6 +218,13 @@ and other "slow scrolling" situations. It is hoped it behaves better than 'fast-but-imprecise-scrolling' and 'jit-lock-defer-time'. It is not enabled by default. ++++ +** Modifiers now go outside angle brackets in pretty-printed key bindings. +For example, with Control and Meta modifiers is now shown as +C-M- instead of . Either variant can be used as +input; functions such as 'kbd' and 'read-kbd-macro' accept both styles +as equivalent (they have done so for a long time). + * Editing Changes in Emacs 28.1 diff --git a/src/keymap.c b/src/keymap.c index 37270f5782..3d1993869b 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -2188,11 +2188,21 @@ See `text-char-description' for describing character codes. */) { if (NILP (no_angles)) { - Lisp_Object result; - char *buffer = SAFE_ALLOCA (sizeof "<>" - + SBYTES (SYMBOL_NAME (key))); - esprintf (buffer, "<%s>", SDATA (SYMBOL_NAME (key))); - result = build_string (buffer); + Lisp_Object namestr = SYMBOL_NAME (key); + const char *sym = SSDATA (namestr); + ptrdiff_t len = SBYTES (namestr); + /* Find the extent of the modifier prefix, like "C-M-". */ + int i = 0; + while (i < len - 3 && sym[i + 1] == '-' && strchr ("CMSsHA", sym[i])) + i += 2; + /* First I bytes of SYM are modifiers; put <> around the rest. */ + char *buffer = SAFE_ALLOCA (len + 3); + memcpy (buffer, sym, i); + buffer[i] = '<'; + memcpy (buffer + i + 1, sym + i, len - i); + buffer [len + 1] = '>'; + buffer [len + 2] = '\0'; + Lisp_Object result = build_string (buffer); SAFE_FREE (); return result; } diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index 2f5b38d05d..8d19a26877 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -630,5 +630,13 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350." (should (>= (length (apropos-internal "^help" #'commandp)) 15)) (should-not (apropos-internal "^next-line$" #'keymapp))) +(ert-deftest subr--kbd () + ;; Check that kbd handles both new and old style key descriptions + ;; (bug#45536). + (should (equal (kbd "s-") [s-return])) + (should (equal (kbd "") [s-return])) + (should (equal (kbd "C-M-") [C-M-return])) + (should (equal (kbd "") [C-M-return]))) + (provide 'subr-tests) ;;; subr-tests.el ends here diff --git a/test/src/keymap-tests.el b/test/src/keymap-tests.el index 74fb3c892d..d4f5fc3f19 100644 --- a/test/src/keymap-tests.el +++ b/test/src/keymap-tests.el @@ -248,6 +248,18 @@ g .. h foo 0 .. 3 foo "))))) +(ert-deftest keymap--key-description () + (should (equal (key-description [right] [?\C-x]) + "C-x ")) + (should (equal (key-description [M-H-right] [?\C-x]) + "C-x M-H-")) + (should (equal (single-key-description 'home) + "")) + (should (equal (single-key-description 'home t) + "home")) + (should (equal (single-key-description 'C-s-home) + "C-s-"))) + (provide 'keymap-tests) ;;; keymap-tests.el ends here commit e6617f0dffbb1ca7a72287621c9c38c8a72145aa Author: Mattias Engdegård Date: Tue Jan 5 10:27:36 2021 +0100 * lisp/filesets.el (filesets-external-viewers): Tighten regexp. diff --git a/lisp/filesets.el b/lisp/filesets.el index 661a93edf1..2ef13ae832 100644 --- a/lisp/filesets.el +++ b/lisp/filesets.el @@ -588,7 +588,7 @@ the filename." (:ignore-on-read-text t) ;; (:constraintp ,pdf-cmd) )) - (".\\.e?ps\\(.gz\\)?\\'" ,ps-cmd + (".\\.e?ps\\(?:\\.gz\\)?\\'" ,ps-cmd ((:ignore-on-open-all t) (:ignore-on-read-text t) ;; (:constraintp ,ps-cmd) commit 06810abc591fb40450bcf448d584316d26e8e98b Author: Harald Jörg Date: Tue Jan 5 10:15:04 2021 +0100 perl-mode: Display here-docs as strings instead of comments * lisp/progmodes/perl-mode.el (perl-syntax-propertize-function): Handle HERE doc starter lines ending in a comment. (perl-heredoc): New face for HERE docs, inheriting from font-lock-string-face. (perl-font-lock-syntactic-face-function): Apply the new face to HERE docs (Bug#23461). * test/lisp/progmodes/cperl-mode-tests.el (cperl-test--run-bug-10483): Skip for Perl mode. The test explicitly calls a function of CPerl mode. diff --git a/etc/NEWS b/etc/NEWS index d8f25ab362..ef1c4b39a6 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1833,6 +1833,9 @@ also keep the type information of their arguments. Use the ** CPerl Mode +--- +*** New face 'perl-heredoc', used for heredoc elements. + --- *** The command 'cperl-set-style' offers the new value "PBP". This value customizes Emacs to use the style recommended in Damian diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el index ec20b01a0f..2a2a4978c6 100644 --- a/lisp/progmodes/perl-mode.el +++ b/lisp/progmodes/perl-mode.el @@ -324,13 +324,33 @@ ;; disambiguate with the left-bitshift operator. "\\|" perl--syntax-exp-intro-regexp "<<\\(?2:\\sw+\\)\\)" ".*\\(\n\\)") - (4 (let* ((st (get-text-property (match-beginning 4) 'syntax-table)) + (4 (let* ((eol (match-beginning 4)) + (st (get-text-property eol 'syntax-table)) (name (match-string 2)) (indented (match-beginning 1))) (goto-char (match-end 2)) (if (save-excursion (nth 8 (syntax-ppss (match-beginning 0)))) + ;; '<<' occurred in a string, or in a comment. ;; Leave the property of the newline unchanged. st + ;; Beware of `foo <<'BAR' #baz` because + ;; the newline needs to start the here-doc + ;; and can't be used to close the comment. + (let ((eol-state (save-excursion (syntax-ppss eol)))) + (when (nth 4 eol-state) + (if (/= (1- eol) (nth 8 eol-state)) + ;; make the last char of the comment closing it + (put-text-property (1- eol) eol + 'syntax-table (string-to-syntax ">")) + ;; In `foo <<'BAR' #` the # is the last character + ;; before eol and can't both open and close the + ;; comment. Workaround: disguise the "#" as + ;; whitespace and fontify it as a comment. + (put-text-property (1- eol) eol + 'syntax-table (string-to-syntax "-")) + (put-text-property (1- eol) eol + 'font-lock-face + 'font-lock-comment-face)))) (cons (car (string-to-syntax "< c")) ;; Remember the names of heredocs found on this line. (cons (cons (pcase (aref name 0) @@ -483,8 +503,15 @@ ;; as twoarg). (perl-syntax-propertize-special-constructs limit))))))))) +(defface perl-heredoc + '((t (:inherit font-lock-string-face))) + "The face for here-documents. Inherits from font-lock-string-face.") + (defun perl-font-lock-syntactic-face-function (state) (cond + ((and (eq 2 (nth 7 state)) ; c-style comment + (cdr-safe (get-text-property (nth 8 state) 'syntax-table))) ; HERE doc + 'perl-heredoc) ((and (nth 3 state) (eq ?e (cdr-safe (get-text-property (nth 8 state) 'syntax-table))) ;; This is a second-arg of s{..}{...} form; let's check if this second diff --git a/test/lisp/progmodes/cperl-mode-resources/here-docs.pl b/test/lisp/progmodes/cperl-mode-resources/here-docs.pl new file mode 100644 index 0000000000..8af4625fff --- /dev/null +++ b/test/lisp/progmodes/cperl-mode-resources/here-docs.pl @@ -0,0 +1,143 @@ +use 5.020; + +=head1 NAME + +here-docs.pl - resource file for cperl-test-here-docs + +=head1 DESCRIPTION + +This file holds a couple of HERE documents, with a variety of normal +and edge cases. For a formatted view of this description, run: + + (cperl-perldoc "here-docs.pl") + +For each of the HERE documents, the following checks will done: + +=over 4 + +=item * + +All occurrences of the string "look-here" are fontified correcty. +Note that we deliberately test the face, not the syntax property: +Users won't care for the syntax property, but they see the face. +Different implementations with different syntax properties have been +seen in the past. + +=item * + +Indentation of the line(s) containing "look-here" is 0, i.e. there are no +leading spaces. + +=item * + +Indentation of the following perl statement containing "indent" should +be 0 if the statement contains "noindent", and according to the mode's +continued-statement-offset otherwise. + +=back + +=cut + +# Prologue to make the test file valid without warnings + +my $text; +my $any; +my $indentation; +my $anywhere = 'back again'; +my $noindent; + +=head1 The Tests + +=head2 Test Case 1 + +We have two HERE documents in one line with different quoting styles. + +=cut + +## test case + +$text = <<"HERE" . <<'THERE' . $any; +#look-here and +HERE +$tlook-here and +THERE + +$noindent = "This should be left-justified"; + +=head2 Test case 2 + +A HERE document followed by a continuation line + +=cut + +## test case + +$text = < Date: Mon Jan 4 23:20:44 2021 -0500 * lisp/subr.el (esc-map): Initialize inside declaration * src/commands.h (meta_map): * src/keymap.c (meta_map): Delete variable. (syms_of_keymap): Don't initialize esc-map here. (initial_define_key): * src/keymap.h (initial_define_key): Delete function. * src/keyboard.c (keys_of_keyboard): Don't initialize esc-map here. * src/window.h (keys_of_window): * src/window.c (keys_of_window): Delete function. * src/lisp.h (keys_of_casefiddle): * src/casefiddle.c (keys_of_casefiddle): Delete function. * src/emacs.c (main): Don't call them. diff --git a/lisp/subr.el b/lisp/subr.el index 206e71ac03..60a77859c4 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1242,9 +1242,17 @@ in a cleaner way with command remapping, like this: ;; global-map, esc-map, and ctl-x-map have their values set up in ;; keymap.c; we just give them docstrings here. -(defvar esc-map nil +(defvar esc-map + (let ((map (make-keymap))) + (define-key map "u" #'upcase-word) + (define-key map "l" #'downcase-word) + (define-key map "c" #'capitalize-word) + (define-key map "x" #'execute-extended-command) + map) "Default keymap for ESC (meta) commands. The normal global definition of the character ESC indirects to this keymap.") +(fset 'ESC-prefix esc-map) +(make-obsolete 'ESC-prefix 'esc-map "28.1") (defvar ctl-x-4-map (make-sparse-keymap) "Keymap for subcommands of C-x 4.") @@ -1273,7 +1281,7 @@ The normal global definition of the character ESC indirects to this keymap.") "Default keymap for C-x commands. The normal global definition of the character C-x indirects to this keymap.") (fset 'Control-X-prefix ctl-x-map) -(make-obsolete 'Control-X-prefix 'ctl-x-map "28.1") +(make-obsolete 'Control-X-prefix 'ctl-x-map "28.1") (defvar global-map (let ((map (make-keymap))) @@ -1296,10 +1304,16 @@ The normal global definition of the character C-x indirects to this keymap.") (define-key map "\C-b" #'backward-char) (define-key map "\C-e" #'end-of-line) (define-key map "\C-f" #'forward-char) + (define-key map "\C-z" #'suspend-emacs) ;FIXME: Re-bound later! (define-key map "\C-x\C-z" #'suspend-emacs) ;FIXME: Re-bound later! - (define-key map "\C-v" #'scroll-up-command) - (define-key map "\C-]" #'abort-recursive-edit) + + (define-key map "\C-v" #'scroll-up-command) + (define-key map "\M-v" #'scroll-down-command) + (define-key map "\M-\C-v" #'scroll-other-window) + + (define-key map "\M-\C-c" #'exit-recursive-edit) + (define-key map "\C-]" #'abort-recursive-edit) map) "Default global keymap mapping Emacs keyboard input into commands. The value is a keymap that is usually (but not necessarily) Emacs's diff --git a/src/casefiddle.c b/src/casefiddle.c index 42de9722ec..a7a2541490 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c @@ -682,11 +682,3 @@ Called with one argument METHOD which can be: defsubr (&Sdowncase_word); defsubr (&Scapitalize_word); } - -void -keys_of_casefiddle (void) -{ - initial_define_key (meta_map, 'u', "upcase-word"); - initial_define_key (meta_map, 'l', "downcase-word"); - initial_define_key (meta_map, 'c', "capitalize-word"); -} diff --git a/src/commands.h b/src/commands.h index 8f9c76b1e2..2205ebf7d3 100644 --- a/src/commands.h +++ b/src/commands.h @@ -23,12 +23,6 @@ along with GNU Emacs. If not, see . */ #define Ctl(c) ((c)&037) -/* Define the names of keymaps, just so people can refer to them in - calls to initial_define_key. These should *not* be used after - initialization; use-global-map doesn't affect these; it sets - current_global_map instead. */ -extern Lisp_Object meta_map; - /* If not Qnil, this is a switch-frame event which we decided to put off until the end of a key sequence. This should be read as the next command input, after any Vunread_command_events. diff --git a/src/emacs.c b/src/emacs.c index 18b54dd07e..69d10821fa 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1956,9 +1956,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem syms_of_json (); #endif - keys_of_casefiddle (); keys_of_keyboard (); - keys_of_window (); } else { diff --git a/src/keyboard.c b/src/keyboard.c index bb4d981fe5..9ee4c4f6d6 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -12388,9 +12388,6 @@ syms_of_keyboard_for_pdumper (void) void keys_of_keyboard (void) { - initial_define_key (meta_map, Ctl ('C'), "exit-recursive-edit"); - initial_define_key (meta_map, 'x', "execute-extended-command"); - initial_define_lispy_key (Vspecial_event_map, "delete-frame", "handle-delete-frame"); #ifdef HAVE_NTGUI diff --git a/src/keymap.c b/src/keymap.c index 171f946041..37270f5782 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -59,17 +59,6 @@ along with GNU Emacs. If not, see . */ Lisp_Object current_global_map; /* Current global keymap. */ -Lisp_Object meta_map; /* The keymap used for globally bound - ESC-prefixed default commands. */ - - /* The keymap used by the minibuf for local - bindings when spaces are allowed in the - minibuf. */ - - /* The keymap used by the minibuf for local - bindings when spaces are not encouraged - in the minibuf. */ - /* Alist of elements like (DEL . "\d"). */ static Lisp_Object exclude_keys; @@ -135,19 +124,6 @@ in case you use it as a menu with `x-popup-menu'. */) return list1 (Qkeymap); } -/* This function is used for installing the standard key bindings - at initialization time. - - For example: - - initial_define_key (control_x_map, Ctl('X'), "exchange-point-and-mark"); */ - -void -initial_define_key (Lisp_Object keymap, int key, const char *defname) -{ - store_in_keymap (keymap, make_fixnum (key), intern_c_string (defname)); -} - void initial_define_lispy_key (Lisp_Object keymap, const char *keyname, const char *defname) { @@ -3193,10 +3169,6 @@ syms_of_keymap (void) current_global_map = Qnil; staticpro (¤t_global_map); - meta_map = Fmake_keymap (Qnil); - Fset (intern_c_string ("esc-map"), meta_map); - Ffset (intern_c_string ("ESC-prefix"), meta_map); - exclude_keys = pure_list (pure_cons (build_pure_c_string ("DEL"), build_pure_c_string ("\\d")), pure_cons (build_pure_c_string ("TAB"), build_pure_c_string ("\\t")), diff --git a/src/keymap.h b/src/keymap.h index 1967025dcb..f417301c8f 100644 --- a/src/keymap.h +++ b/src/keymap.h @@ -37,7 +37,6 @@ extern char *push_key_description (EMACS_INT, char *); extern Lisp_Object access_keymap (Lisp_Object, Lisp_Object, bool, bool, bool); extern Lisp_Object get_keymap (Lisp_Object, bool, bool); extern ptrdiff_t current_minor_maps (Lisp_Object **, Lisp_Object **); -extern void initial_define_key (Lisp_Object, int, const char *); extern void initial_define_lispy_key (Lisp_Object, const char *, const char *); extern void syms_of_keymap (void); diff --git a/src/lisp.h b/src/lisp.h index 915ad64f6e..ca0eb51c06 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4357,7 +4357,6 @@ extern void syms_of_callint (void); /* Defined in casefiddle.c. */ extern void syms_of_casefiddle (void); -extern void keys_of_casefiddle (void); /* Defined in casetab.c. */ diff --git a/src/window.c b/src/window.c index 29d499ccd4..58204c13e4 100644 --- a/src/window.c +++ b/src/window.c @@ -8583,10 +8583,3 @@ displayed after a scrolling operation to be somewhat inaccurate. */); defsubr (&Swindow_parameter); defsubr (&Sset_window_parameter); } - -void -keys_of_window (void) -{ - initial_define_key (meta_map, Ctl ('V'), "scroll-other-window"); - initial_define_key (meta_map, 'v', "scroll-down-command"); -} diff --git a/src/window.h b/src/window.h index 1f94fc0252..332cb3091f 100644 --- a/src/window.h +++ b/src/window.h @@ -1202,7 +1202,6 @@ extern bool window_outdated (struct window *); extern void init_window_once (void); extern void init_window (void); extern void syms_of_window (void); -extern void keys_of_window (void); /* Move cursor to row/column position VPOS/HPOS, pixel coordinates Y/X. HPOS/VPOS are window-relative row and column numbers and X/Y are window-relative pixel positions. This is always done during commit 5bddc097385c1d9088748ed92abc2370857b2202 Author: Stefan Monnier Date: Mon Jan 4 23:11:07 2021 -0500 * lisp/subr.el (ctl-x-map): Initialize inside the declaration. * src/command.h (control_x_map): * src/keymap.c (control_x_map): Delete variable. (syms_of_keymap): * src/keyboard.c (keys_of_keyboard): * src/casefiddle.c (keys_of_casefiddle): * src/window.c (keys_of_window): Move initialization of ctl-x-map to subr.el. * src/lisp.h (syms_of_buffer): * src/buffer.c (keys_of_buffer): Delete function. * src/emacs.c (main): Don't call it. diff --git a/lisp/subr.el b/lisp/subr.el index 6187f7ad3c..206e71ac03 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1246,23 +1246,34 @@ in a cleaner way with command remapping, like this: "Default keymap for ESC (meta) commands. The normal global definition of the character ESC indirects to this keymap.") -(defvar ctl-x-map nil - "Default keymap for C-x commands. -The normal global definition of the character C-x indirects to this keymap.") - (defvar ctl-x-4-map (make-sparse-keymap) "Keymap for subcommands of C-x 4.") (defalias 'ctl-x-4-prefix ctl-x-4-map) -(define-key ctl-x-map "4" 'ctl-x-4-prefix) (defvar ctl-x-5-map (make-sparse-keymap) "Keymap for frame commands.") (defalias 'ctl-x-5-prefix ctl-x-5-map) -(define-key ctl-x-map "5" 'ctl-x-5-prefix) (defvar tab-prefix-map (make-sparse-keymap) "Keymap for tab-bar related commands.") -(define-key ctl-x-map "t" tab-prefix-map) + +(defvar ctl-x-map + (let ((map (make-keymap))) + (define-key map "4" 'ctl-x-4-prefix) + (define-key map "5" 'ctl-x-5-prefix) + (define-key map "t" tab-prefix-map) + + (define-key map "b" #'switch-to-buffer) + (define-key map "l" #'kill-buffer) + (define-key map "\C-u" #'upcase-region) (put 'upcase-region 'disabled t) + (define-key map "\C-l" #'downcase-region) (put 'downcase-region 'disabled t) + (define-key map "<" #'scroll-left) + (define-key map ">" #'scroll-right) + map) + "Default keymap for C-x commands. +The normal global definition of the character C-x indirects to this keymap.") +(fset 'Control-X-prefix ctl-x-map) +(make-obsolete 'Control-X-prefix 'ctl-x-map "28.1") (defvar global-map (let ((map (make-keymap))) @@ -1285,8 +1296,8 @@ The normal global definition of the character C-x indirects to this keymap.") (define-key map "\C-b" #'backward-char) (define-key map "\C-e" #'end-of-line) (define-key map "\C-f" #'forward-char) - (define-key map "\C-z" #'suspend-emacs) ;FIXME: Re-bound later! - + (define-key map "\C-z" #'suspend-emacs) ;FIXME: Re-bound later! + (define-key map "\C-x\C-z" #'suspend-emacs) ;FIXME: Re-bound later! (define-key map "\C-v" #'scroll-up-command) (define-key map "\C-]" #'abort-recursive-edit) map) diff --git a/src/buffer.c b/src/buffer.c index 0a7ff6e675..71ad5edd52 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -6380,10 +6380,3 @@ nil NORECORD argument since it may lead to infinite recursion. */); Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt); } - -void -keys_of_buffer (void) -{ - initial_define_key (control_x_map, 'b', "switch-to-buffer"); - initial_define_key (control_x_map, 'k', "kill-buffer"); -} diff --git a/src/casefiddle.c b/src/casefiddle.c index a948bb3bc8..42de9722ec 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c @@ -686,11 +686,6 @@ Called with one argument METHOD which can be: void keys_of_casefiddle (void) { - initial_define_key (control_x_map, Ctl ('U'), "upcase-region"); - Fput (intern ("upcase-region"), Qdisabled, Qt); - initial_define_key (control_x_map, Ctl ('L'), "downcase-region"); - Fput (intern ("downcase-region"), Qdisabled, Qt); - initial_define_key (meta_map, 'u', "upcase-word"); initial_define_key (meta_map, 'l', "downcase-word"); initial_define_key (meta_map, 'c', "capitalize-word"); diff --git a/src/commands.h b/src/commands.h index be6f5823bc..8f9c76b1e2 100644 --- a/src/commands.h +++ b/src/commands.h @@ -28,7 +28,6 @@ along with GNU Emacs. If not, see . */ initialization; use-global-map doesn't affect these; it sets current_global_map instead. */ extern Lisp_Object meta_map; -extern Lisp_Object control_x_map; /* If not Qnil, this is a switch-frame event which we decided to put off until the end of a key sequence. This should be read as the diff --git a/src/emacs.c b/src/emacs.c index 3c293d85ed..18b54dd07e 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1957,7 +1957,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem #endif keys_of_casefiddle (); - keys_of_buffer (); keys_of_keyboard (); keys_of_window (); } diff --git a/src/keyboard.c b/src/keyboard.c index 52d913c537..bb4d981fe5 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -12388,7 +12388,6 @@ syms_of_keyboard_for_pdumper (void) void keys_of_keyboard (void) { - initial_define_key (control_x_map, Ctl ('Z'), "suspend-emacs"); initial_define_key (meta_map, Ctl ('C'), "exit-recursive-edit"); initial_define_key (meta_map, 'x', "execute-extended-command"); diff --git a/src/keymap.c b/src/keymap.c index 772ced42cc..171f946041 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -62,9 +62,6 @@ Lisp_Object current_global_map; /* Current global keymap. */ Lisp_Object meta_map; /* The keymap used for globally bound ESC-prefixed default commands. */ -Lisp_Object control_x_map; /* The keymap used for globally bound - C-x-prefixed default commands. */ - /* The keymap used by the minibuf for local bindings when spaces are allowed in the minibuf. */ @@ -3200,10 +3197,6 @@ syms_of_keymap (void) Fset (intern_c_string ("esc-map"), meta_map); Ffset (intern_c_string ("ESC-prefix"), meta_map); - control_x_map = Fmake_keymap (Qnil); - Fset (intern_c_string ("ctl-x-map"), control_x_map); - Ffset (intern_c_string ("Control-X-prefix"), control_x_map); - exclude_keys = pure_list (pure_cons (build_pure_c_string ("DEL"), build_pure_c_string ("\\d")), pure_cons (build_pure_c_string ("TAB"), build_pure_c_string ("\\t")), diff --git a/src/lisp.h b/src/lisp.h index d259e950da..915ad64f6e 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4261,7 +4261,6 @@ extern Lisp_Object get_truename_buffer (Lisp_Object); extern void init_buffer_once (void); extern void init_buffer (void); extern void syms_of_buffer (void); -extern void keys_of_buffer (void); /* Defined in marker.c. */ diff --git a/src/window.c b/src/window.c index f2862a287d..29d499ccd4 100644 --- a/src/window.c +++ b/src/window.c @@ -8587,9 +8587,6 @@ displayed after a scrolling operation to be somewhat inaccurate. */); void keys_of_window (void) { - initial_define_key (control_x_map, '<', "scroll-left"); - initial_define_key (control_x_map, '>', "scroll-right"); - initial_define_key (meta_map, Ctl ('V'), "scroll-other-window"); initial_define_key (meta_map, 'v', "scroll-down-command"); } commit d6f30e5632b1c9cf43ebfbdbf164d5c54be33475 Author: Stefan Monnier Date: Mon Jan 4 22:57:21 2021 -0500 * lisp/subr.el (global-map): Initialize inside declaration. * src/commands.h (global_map): * src/keymap.c (global_map): Delete variable. (syms_of_keymap): Don't initialize global_map here. (keys_of_keymap): Delete function. * src/lisp.h (keys_of_cmds): * src/cmds.c (keys_of_cmds): Delete function. * src/emacs.c (main): Don't call them. * src/window.c (keys_of_window): Don't initialize global_map here. * src/keyboard.c (keys_of_keyboard): Don't initialize global_map here. diff --git a/lisp/subr.el b/lisp/subr.el index 1acc3c3250..6187f7ad3c 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1242,11 +1242,6 @@ in a cleaner way with command remapping, like this: ;; global-map, esc-map, and ctl-x-map have their values set up in ;; keymap.c; we just give them docstrings here. -(defvar global-map nil - "Default global keymap mapping Emacs keyboard input into commands. -The value is a keymap that is usually (but not necessarily) Emacs's -global map.") - (defvar esc-map nil "Default keymap for ESC (meta) commands. The normal global definition of the character ESC indirects to this keymap.") @@ -1269,6 +1264,37 @@ The normal global definition of the character C-x indirects to this keymap.") "Keymap for tab-bar related commands.") (define-key ctl-x-map "t" tab-prefix-map) +(defvar global-map + (let ((map (make-keymap))) + (define-key map "\C-[" 'ESC-prefix) + (define-key map "\C-x" 'Control-X-prefix) + + (define-key map "\C-i" #'self-insert-command) + (let* ((vec1 (make-vector 1 nil)) + (f (lambda (from to) + (while (< from to) + (aset vec1 0 from) + (define-key map vec1 #'self-insert-command) + (setq from (1+ from)))))) + (funcall f #o040 #o0177) + (when (eq system-type 'ms-dos) ;FIXME: Why? + (funcall f #o0200 #o0240)) + (funcall f #o0240 #o0400)) + + (define-key map "\C-a" #'beginning-of-line) + (define-key map "\C-b" #'backward-char) + (define-key map "\C-e" #'end-of-line) + (define-key map "\C-f" #'forward-char) + (define-key map "\C-z" #'suspend-emacs) ;FIXME: Re-bound later! + + (define-key map "\C-v" #'scroll-up-command) + (define-key map "\C-]" #'abort-recursive-edit) + map) + "Default global keymap mapping Emacs keyboard input into commands. +The value is a keymap that is usually (but not necessarily) Emacs's +global map.") +(use-global-map global-map) + ;;;; Event manipulation functions. diff --git a/src/cmds.c b/src/cmds.c index 798fd68a92..1547db80e8 100644 --- a/src/cmds.c +++ b/src/cmds.c @@ -529,24 +529,3 @@ This is run after inserting the character. */); defsubr (&Sdelete_char); defsubr (&Sself_insert_command); } - -void -keys_of_cmds (void) -{ - int n; - - initial_define_key (global_map, Ctl ('I'), "self-insert-command"); - for (n = 040; n < 0177; n++) - initial_define_key (global_map, n, "self-insert-command"); -#ifdef MSDOS - for (n = 0200; n < 0240; n++) - initial_define_key (global_map, n, "self-insert-command"); -#endif - for (n = 0240; n < 0400; n++) - initial_define_key (global_map, n, "self-insert-command"); - - initial_define_key (global_map, Ctl ('A'), "beginning-of-line"); - initial_define_key (global_map, Ctl ('B'), "backward-char"); - initial_define_key (global_map, Ctl ('E'), "end-of-line"); - initial_define_key (global_map, Ctl ('F'), "forward-char"); -} diff --git a/src/commands.h b/src/commands.h index a09858d050..be6f5823bc 100644 --- a/src/commands.h +++ b/src/commands.h @@ -27,7 +27,6 @@ along with GNU Emacs. If not, see . */ calls to initial_define_key. These should *not* be used after initialization; use-global-map doesn't affect these; it sets current_global_map instead. */ -extern Lisp_Object global_map; extern Lisp_Object meta_map; extern Lisp_Object control_x_map; diff --git a/src/emacs.c b/src/emacs.c index fe8dcb1c47..3c293d85ed 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1957,10 +1957,8 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem #endif keys_of_casefiddle (); - keys_of_cmds (); keys_of_buffer (); keys_of_keyboard (); - keys_of_keymap (); keys_of_window (); } else diff --git a/src/keyboard.c b/src/keyboard.c index cf15cd7357..52d913c537 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -12388,10 +12388,8 @@ syms_of_keyboard_for_pdumper (void) void keys_of_keyboard (void) { - initial_define_key (global_map, Ctl ('Z'), "suspend-emacs"); initial_define_key (control_x_map, Ctl ('Z'), "suspend-emacs"); initial_define_key (meta_map, Ctl ('C'), "exit-recursive-edit"); - initial_define_key (global_map, Ctl (']'), "abort-recursive-edit"); initial_define_key (meta_map, 'x', "execute-extended-command"); initial_define_lispy_key (Vspecial_event_map, "delete-frame", diff --git a/src/keymap.c b/src/keymap.c index 1eeea81f62..772ced42cc 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -59,8 +59,6 @@ along with GNU Emacs. If not, see . */ Lisp_Object current_global_map; /* Current global keymap. */ -Lisp_Object global_map; /* Default global key bindings. */ - Lisp_Object meta_map; /* The keymap used for globally bound ESC-prefixed default commands. */ @@ -3195,11 +3193,7 @@ syms_of_keymap (void) Each one is the value of a Lisp variable, and is also pointed to by a C variable */ - global_map = Fmake_keymap (Qnil); - Fset (intern_c_string ("global-map"), global_map); - - current_global_map = global_map; - staticpro (&global_map); + current_global_map = Qnil; staticpro (¤t_global_map); meta_map = Fmake_keymap (Qnil); @@ -3328,10 +3322,3 @@ be preferred. */); defsubr (&Swhere_is_internal); defsubr (&Sdescribe_buffer_bindings); } - -void -keys_of_keymap (void) -{ - initial_define_key (global_map, 033, "ESC-prefix"); - initial_define_key (global_map, Ctl ('X'), "Control-X-prefix"); -} diff --git a/src/keymap.h b/src/keymap.h index 072c09348e..1967025dcb 100644 --- a/src/keymap.h +++ b/src/keymap.h @@ -40,7 +40,6 @@ extern ptrdiff_t current_minor_maps (Lisp_Object **, Lisp_Object **); extern void initial_define_key (Lisp_Object, int, const char *); extern void initial_define_lispy_key (Lisp_Object, const char *, const char *); extern void syms_of_keymap (void); -extern void keys_of_keymap (void); typedef void (*map_keymap_function_t) (Lisp_Object key, Lisp_Object val, Lisp_Object args, void *data); diff --git a/src/lisp.h b/src/lisp.h index 5cc735be86..d259e950da 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3561,7 +3561,6 @@ extern void swap_in_global_binding (struct Lisp_Symbol *); /* Defined in cmds.c */ extern void syms_of_cmds (void); -extern void keys_of_cmds (void); /* Defined in coding.c. */ extern Lisp_Object detect_coding_system (const unsigned char *, ptrdiff_t, diff --git a/src/window.c b/src/window.c index ba8682eed7..f2862a287d 100644 --- a/src/window.c +++ b/src/window.c @@ -8590,7 +8590,6 @@ keys_of_window (void) initial_define_key (control_x_map, '<', "scroll-left"); initial_define_key (control_x_map, '>', "scroll-right"); - initial_define_key (global_map, Ctl ('V'), "scroll-up-command"); initial_define_key (meta_map, Ctl ('V'), "scroll-other-window"); initial_define_key (meta_map, 'v', "scroll-down-command"); } commit 898a94a9be06a3ab51116778f6b4a263f832759d Author: Stefan Monnier Date: Mon Jan 4 20:57:42 2021 -0500 Use lexical-binding in the remaining preloaded files * lisp/widget.el: * lisp/w32-fns.el: * lisp/textmodes/fill.el: * lisp/term/common-win.el: * lisp/scroll-bar.el: * lisp/rfn-eshadow.el: * lisp/menu-bar.el: * lisp/language/tibetan.el: * lisp/language/thai.el: * lisp/language/misc-lang.el: * lisp/language/lao.el: * lisp/language/korean.el: * lisp/language/japanese.el: * lisp/language/indian.el: * lisp/language/hebrew.el: * lisp/language/european.el: * lisp/language/ethiopic.el: * lisp/language/english.el: * lisp/language/cyrillic.el: * lisp/language/chinese.el: * lisp/jka-cmpr-hook.el: * lisp/international/ucs-normalize.el: * lisp/international/mule.el: * lisp/international/mule-conf.el: * lisp/international/iso-transl.el: * lisp/international/fontset.el: * lisp/international/characters.el: * lisp/format.el: * lisp/facemenu.el: * lisp/electric.el: * lisp/dos-w32.el: * lisp/dos-fns.el: * lisp/disp-table.el: * lisp/cus-face.el: * lisp/composite.el: * lisp/bindings.el: * admin/unidata/blocks.awk: * admin/charsets/eucjp-ms.awk: * admin/charsets/cp51932.awk: Use `lexical-binding`. diff --git a/admin/charsets/cp51932.awk b/admin/charsets/cp51932.awk index c355509524..22b24af1ef 100644 --- a/admin/charsets/cp51932.awk +++ b/admin/charsets/cp51932.awk @@ -31,7 +31,7 @@ # already been mapped to 1 or 3. BEGIN { - print ";;; cp51932.el -- translation table for CP51932"; + print ";;; cp51932.el -- translation table for CP51932 -*- lexical-binding:t -*-"; print ";;; Automatically generated from CP932-2BYTE.map"; print "(let ((map"; printf " '(;JISEXT<->UNICODE"; diff --git a/admin/charsets/eucjp-ms.awk b/admin/charsets/eucjp-ms.awk index f6a6748ce5..ca9a317611 100644 --- a/admin/charsets/eucjp-ms.awk +++ b/admin/charsets/eucjp-ms.awk @@ -38,7 +38,7 @@ BEGIN { JISX0208_FROM2 = "/xf5/xa1"; JISX0212_FROM = "/x8f/xf3/xf3"; - print ";;; eucjp-ms.el -- translation table for eucJP-ms"; + print ";;; eucjp-ms.el -- translation table for eucJP-ms -*- lexical-binding:t -*-"; print ";;; Automatically generated from /usr/share/i18n/charmaps/EUC-JP-MS.gz"; print "(let ((map"; print " '(;JISEXT<->UNICODE"; diff --git a/admin/unidata/blocks.awk b/admin/unidata/blocks.awk index 986d299e66..4ecb233fe7 100755 --- a/admin/unidata/blocks.awk +++ b/admin/unidata/blocks.awk @@ -203,7 +203,7 @@ function name2alias(name , w, w2) { } END { - print ";;; charscript.el --- character script table" + print ";;; charscript.el --- character script table -*- lexical-binding:t -*-" print ";;; Automatically generated from admin/unidata/Blocks.txt" print "(let (script-list)" print " (dolist (elt '(" diff --git a/lisp/bindings.el b/lisp/bindings.el index b68d55e73d..187444af66 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -1,4 +1,4 @@ -;;; bindings.el --- define standard key bindings and some variables +;;; bindings.el --- define standard key bindings and some variables -*- lexical-binding: t; -*- ;; Copyright (C) 1985-1987, 1992-1996, 1999-2021 Free Software ;; Foundation, Inc. @@ -856,7 +856,7 @@ in contrast with \\[forward-char] and \\[backward-char], which see." (interactive "^p") (if visual-order-cursor-movement - (dotimes (i (if (numberp n) (abs n) 1)) + (dotimes (_ (if (numberp n) (abs n) 1)) (move-point-visually (if (and (numberp n) (< n 0)) -1 1))) (if (eq (current-bidi-paragraph-direction) 'left-to-right) (forward-char n) @@ -874,7 +874,7 @@ in contrast with \\[forward-char] and \\[backward-char], which see." (interactive "^p") (if visual-order-cursor-movement - (dotimes (i (if (numberp n) (abs n) 1)) + (dotimes (_ (if (numberp n) (abs n) 1)) (move-point-visually (if (and (numberp n) (< n 0)) 1 -1))) (if (eq (current-bidi-paragraph-direction) 'left-to-right) (backward-char n) diff --git a/lisp/composite.el b/lisp/composite.el index 7337605d4a..6f654df15a 100644 --- a/lisp/composite.el +++ b/lisp/composite.el @@ -1,4 +1,4 @@ -;;; composite.el --- support character composition +;;; composite.el --- support character composition -*- lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. @@ -593,7 +593,6 @@ All non-spacing characters have this function in (as (lglyph-ascent glyph)) (de (lglyph-descent glyph)) (ce (/ (+ lb rb) 2)) - (w (lglyph-width glyph)) xoff yoff) (cond ((and class (>= class 200) (<= class 240)) @@ -653,7 +652,8 @@ All non-spacing characters have this function in ((and (= class 0) (eq (get-char-code-property (lglyph-char glyph) ;; Me = enclosing mark - 'general-category) 'Me)) + 'general-category) + 'Me)) ;; Artificially laying out glyphs in an enclosing ;; mark is difficult. All we can do is to adjust ;; the x-offset and width of the base glyph to @@ -695,9 +695,7 @@ All non-spacing characters have this function in (defun compose-gstring-for-dotted-circle (gstring direction) (let* ((dc (lgstring-glyph gstring 0)) ; glyph of dotted-circle - (dc-id (lglyph-code dc)) (fc (lgstring-glyph gstring 1)) ; glyph of the following char - (fc-id (lglyph-code fc)) (gstr (and nil (font-shape-gstring gstring direction)))) (if (and gstr (or (= (lgstring-glyph-len gstr) 1) diff --git a/lisp/cus-face.el b/lisp/cus-face.el index 7d9d1fe13a..5dcb2842a2 100644 --- a/lisp/cus-face.el +++ b/lisp/cus-face.el @@ -1,4 +1,4 @@ -;;; cus-face.el --- customization support for faces +;;; cus-face.el --- customization support for faces -*- lexical-binding: t; -*- ;; ;; Copyright (C) 1996-1997, 1999-2021 Free Software Foundation, Inc. ;; diff --git a/lisp/disp-table.el b/lisp/disp-table.el index 6de14b1d29..a7fc8f0a76 100644 --- a/lisp/disp-table.el +++ b/lisp/disp-table.el @@ -1,4 +1,4 @@ -;;; disp-table.el --- functions for dealing with char tables +;;; disp-table.el --- functions for dealing with char tables -*- lexical-binding: t; -*- ;; Copyright (C) 1987, 1994-1995, 1999, 2001-2021 Free Software ;; Foundation, Inc. diff --git a/lisp/dos-fns.el b/lisp/dos-fns.el index 5d4aa7843f..255edd0f37 100644 --- a/lisp/dos-fns.el +++ b/lisp/dos-fns.el @@ -1,4 +1,4 @@ -;;; dos-fns.el --- MS-Dos specific functions +;;; dos-fns.el --- MS-Dos specific functions -*- lexical-binding: t; -*- ;; Copyright (C) 1991, 1993, 1995-1996, 2001-2021 Free Software ;; Foundation, Inc. diff --git a/lisp/dos-w32.el b/lisp/dos-w32.el index e902491446..cf75321462 100644 --- a/lisp/dos-w32.el +++ b/lisp/dos-w32.el @@ -1,4 +1,4 @@ -;; dos-w32.el --- Functions shared among MS-DOS and W32 (NT/95) platforms +;; dos-w32.el --- Functions shared among MS-DOS and W32 (NT/95) platforms -*- lexical-binding: t; -*- ;; Copyright (C) 1996, 2001-2021 Free Software Foundation, Inc. @@ -154,13 +154,15 @@ when writing the file." ;; FIXME: Can't we use find-file-literally for the same purposes? (interactive "FFind file binary: ") (let ((coding-system-for-read 'no-conversion)) ;; FIXME: undecided-unix? - (find-file filename))) + (with-suppressed-warnings ((interactive-only find-file)) + (find-file filename)))) (defun find-file-text (filename) "Visit file FILENAME and treat it as a text file." (interactive "FFind file text: ") (let ((coding-system-for-read 'undecided-dos)) - (find-file filename))) + (with-suppressed-warnings ((interactive-only find-file)) + (find-file filename)))) (defun w32-find-file-not-found-set-buffer-file-coding-system () (with-current-buffer (current-buffer) @@ -261,6 +263,8 @@ filesystem mounted on drive Z:, FILESYSTEM could be \"Z:\"." :group 'dos-fns :group 'w32) +(defvar w32-quote-process-args) + ;; Function to actually send data to the printer port. ;; Supports writing directly, and using various programs. (defun w32-direct-print-region-helper (printer diff --git a/lisp/electric.el b/lisp/electric.el index 506e9aa0f7..6701a36d8b 100644 --- a/lisp/electric.el +++ b/lisp/electric.el @@ -1,4 +1,4 @@ -;;; electric.el --- window maker and Command loop for `electric' modes +;;; electric.el --- window maker and Command loop for `electric' modes -*- lexical-binding: t; -*- ;; Copyright (C) 1985-1986, 1995, 2001-2021 Free Software Foundation, ;; Inc. @@ -385,6 +385,8 @@ If multiple rules match, only first one is executed.") (when electric-layout-mode (electric-layout-post-self-insert-function-1))) +(defvar electric-pair-open-newline-between-pairs) + ;; for edebug's sake, a separate function (defun electric-layout-post-self-insert-function-1 () (let* ((pos (electric--after-char-pos)) diff --git a/lisp/facemenu.el b/lisp/facemenu.el index d362adcc9b..2609397b0d 100644 --- a/lisp/facemenu.el +++ b/lisp/facemenu.el @@ -1,4 +1,4 @@ -;;; facemenu.el --- create a face menu for interactively adding fonts to text +;;; facemenu.el --- create a face menu for interactively adding fonts to text -*- lexical-binding: t; -*- ;; Copyright (C) 1994-1996, 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/font-core.el b/lisp/font-core.el index 38307bb157..0f1a3d1c36 100644 --- a/lisp/font-core.el +++ b/lisp/font-core.el @@ -1,4 +1,4 @@ -;;; font-core.el --- Core interface to font-lock +;;; font-core.el --- Core interface to font-lock -*- lexical-binding: t; -*- ;; Copyright (C) 1992-2021 Free Software Foundation, Inc. diff --git a/lisp/format.el b/lisp/format.el index df3bc462c9..4209fc6401 100644 --- a/lisp/format.el +++ b/lisp/format.el @@ -1,4 +1,4 @@ -;;; format.el --- read and save files in multiple formats +;;; format.el --- read and save files in multiple formats -*- lexical-binding: t; -*- ;; Copyright (C) 1994-1995, 1997, 1999, 2001-2021 Free Software ;; Foundation, Inc. @@ -419,7 +419,8 @@ If FORMAT is nil then do not do any format conversion." (file-name-nondirectory file))))) (list file fmt))) (let ((format-alist nil)) - (find-file filename)) + (with-suppressed-warnings ((interactive-only find-file)) + (find-file filename))) (if format (format-decode-buffer format))) diff --git a/lisp/international/characters.el b/lisp/international/characters.el index 6924e1c06d..87e8589e6f 100644 --- a/lisp/international/characters.el +++ b/lisp/international/characters.el @@ -1,4 +1,4 @@ -;;; characters.el --- set syntax and category for multibyte characters +;;; characters.el --- set syntax and category for multibyte characters -*- lexical-binding: t; -*- ;; Copyright (C) 1997, 2000-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, diff --git a/lisp/international/fontset.el b/lisp/international/fontset.el index 4d80e17e3d..14e7b89dd1 100644 --- a/lisp/international/fontset.el +++ b/lisp/international/fontset.el @@ -1,4 +1,4 @@ -;;; fontset.el --- commands for handling fontset +;;; fontset.el --- commands for handling fontset -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, diff --git a/lisp/international/iso-transl.el b/lisp/international/iso-transl.el index 8b5814e577..2c7da2b7cd 100644 --- a/lisp/international/iso-transl.el +++ b/lisp/international/iso-transl.el @@ -1,4 +1,4 @@ -;;; iso-transl.el --- keyboard input for ISO 10646 chars -*- coding: utf-8 -*- +;;; iso-transl.el --- keyboard input for ISO 10646 chars -*- coding: utf-8; lexical-binding: t; -*- ;; Copyright (C) 1987, 1993-1999, 2001-2021 Free Software Foundation, ;; Inc. diff --git a/lisp/international/mule-conf.el b/lisp/international/mule-conf.el index 662f211bd2..64aac46fce 100644 --- a/lisp/international/mule-conf.el +++ b/lisp/international/mule-conf.el @@ -1,4 +1,4 @@ -;;; mule-conf.el --- configure multilingual environment +;;; mule-conf.el --- configure multilingual environment -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 diff --git a/lisp/international/mule.el b/lisp/international/mule.el index d3a1005dae..6a32cffe9a 100644 --- a/lisp/international/mule.el +++ b/lisp/international/mule.el @@ -1,4 +1,4 @@ -;;; mule.el --- basic commands for multilingual environment +;;; mule.el --- basic commands for multilingual environment -*- lexical-binding: t; -*- ;; Copyright (C) 1997-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, diff --git a/lisp/international/ucs-normalize.el b/lisp/international/ucs-normalize.el index d1b5c07781..0f8dedfc09 100644 --- a/lisp/international/ucs-normalize.el +++ b/lisp/international/ucs-normalize.el @@ -1,4 +1,4 @@ -;;; ucs-normalize.el --- Unicode normalization NFC/NFD/NFKD/NFKC +;;; ucs-normalize.el --- Unicode normalization NFC/NFD/NFKD/NFKC -*- lexical-binding: t; -*- ;; Copyright (C) 2009-2021 Free Software Foundation, Inc. @@ -185,7 +185,7 @@ ;; always returns nil, something the code here doesn't like. (define-char-code-property 'decomposition "uni-decomposition.el") (define-char-code-property 'canonical-combining-class "uni-combining.el") - (let ((char 0) ccc decomposition) + (let (ccc decomposition) (mapc (lambda (start-end) (cl-do ((char (car start-end) (+ char 1))) ((> char (cdr start-end))) diff --git a/lisp/jka-cmpr-hook.el b/lisp/jka-cmpr-hook.el index 3c7d2a057d..11d93a6df9 100644 --- a/lisp/jka-cmpr-hook.el +++ b/lisp/jka-cmpr-hook.el @@ -1,4 +1,4 @@ -;;; jka-cmpr-hook.el --- preloaded code to enable jka-compr.el +;;; jka-cmpr-hook.el --- preloaded code to enable jka-compr.el -*- lexical-binding: t; -*- ;; Copyright (C) 1993-1995, 1997, 1999-2000, 2002-2021 Free Software ;; Foundation, Inc. @@ -93,6 +93,7 @@ Otherwise, it is nil.") "\\)" file-name-version-regexp "?\\'")))) ;; Functions for accessing the return value of jka-compr-get-compression-info +;; FIXME: Use cl-defstruct! (defun jka-compr-info-regexp (info) (aref info 0)) (defun jka-compr-info-compress-message (info) (aref info 1)) (defun jka-compr-info-compress-program (info) (aref info 2)) diff --git a/lisp/language/chinese.el b/lisp/language/chinese.el index 6b434feb13..5cb8344c09 100644 --- a/lisp/language/chinese.el +++ b/lisp/language/chinese.el @@ -1,4 +1,4 @@ -;;; chinese.el --- support for Chinese -*- coding: utf-8; -*- +;;; chinese.el --- support for Chinese -*- coding: utf-8; lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, diff --git a/lisp/language/cyrillic.el b/lisp/language/cyrillic.el index c491644d57..c12096f95e 100644 --- a/lisp/language/cyrillic.el +++ b/lisp/language/cyrillic.el @@ -1,4 +1,4 @@ -;;; cyrillic.el --- support for Cyrillic -*- coding: utf-8; -*- +;;; cyrillic.el --- support for Cyrillic -*- coding: utf-8; lexical-binding: t; -*- ;; Copyright (C) 1997-1998, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, diff --git a/lisp/language/english.el b/lisp/language/english.el index dfbec85792..41d56be7d4 100644 --- a/lisp/language/english.el +++ b/lisp/language/english.el @@ -1,4 +1,4 @@ -;;; english.el --- support for English +;;; english.el --- support for English -*- lexical-binding: t; -*- ;; Copyright (C) 1997, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, diff --git a/lisp/language/ethiopic.el b/lisp/language/ethiopic.el index 1e409e3dcf..8573f6177d 100644 --- a/lisp/language/ethiopic.el +++ b/lisp/language/ethiopic.el @@ -1,4 +1,4 @@ -;;; ethiopic.el --- support for Ethiopic -*- coding: utf-8-emacs; -*- +;;; ethiopic.el --- support for Ethiopic -*- coding: utf-8-emacs; lexical-binding: t; -*- ;; Copyright (C) 1997, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, diff --git a/lisp/language/european.el b/lisp/language/european.el index 1f27ff0c73..bcd62a14c4 100644 --- a/lisp/language/european.el +++ b/lisp/language/european.el @@ -1,4 +1,4 @@ -;;; european.el --- support for European languages -*- coding: utf-8; -*- +;;; european.el --- support for European languages -*- coding: utf-8; lexical-binding: t; -*- ;; Copyright (C) 1997-1998, 2000-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, diff --git a/lisp/language/hebrew.el b/lisp/language/hebrew.el index 9f9a14a0dc..389565669a 100644 --- a/lisp/language/hebrew.el +++ b/lisp/language/hebrew.el @@ -1,4 +1,4 @@ -;;; hebrew.el --- support for Hebrew -*- coding: utf-8 -*- +;;; hebrew.el --- support for Hebrew -*- coding: utf-8; lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, diff --git a/lisp/language/indian.el b/lisp/language/indian.el index b92fda5364..5ff57966c1 100644 --- a/lisp/language/indian.el +++ b/lisp/language/indian.el @@ -1,4 +1,4 @@ -;;; indian.el --- Indian languages support -*- coding: utf-8; -*- +;;; indian.el --- Indian languages support -*- coding: utf-8; lexical-binding: t; -*- ;; Copyright (C) 1997, 1999, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 diff --git a/lisp/language/japanese.el b/lisp/language/japanese.el index 8c724ee966..bd8ef6ec85 100644 --- a/lisp/language/japanese.el +++ b/lisp/language/japanese.el @@ -1,4 +1,4 @@ -;;; japanese.el --- support for Japanese +;;; japanese.el --- support for Japanese -*- lexical-binding: t; -*- ;; Copyright (C) 1997, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, diff --git a/lisp/language/korean.el b/lisp/language/korean.el index 997b8ae131..22b33a440e 100644 --- a/lisp/language/korean.el +++ b/lisp/language/korean.el @@ -1,4 +1,4 @@ -;;; korean.el --- support for Korean -*- coding: utf-8 -*- +;;; korean.el --- support for Korean -*- coding: utf-8; lexical-binding: t; -*- ;; Copyright (C) 1998, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, diff --git a/lisp/language/lao.el b/lisp/language/lao.el index 44fe8d230d..5252f1e60e 100644 --- a/lisp/language/lao.el +++ b/lisp/language/lao.el @@ -1,4 +1,4 @@ -;;; lao.el --- support for Lao -*- coding: utf-8 -*- +;;; lao.el --- support for Lao -*- coding: utf-8; lexical-binding: t; -*- ;; Copyright (C) 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, diff --git a/lisp/language/misc-lang.el b/lisp/language/misc-lang.el index 089b79c520..0a274f144c 100644 --- a/lisp/language/misc-lang.el +++ b/lisp/language/misc-lang.el @@ -1,4 +1,4 @@ -;;; misc-lang.el --- support for miscellaneous languages (characters) +;;; misc-lang.el --- support for miscellaneous languages (characters) -*- lexical-binding: t; -*- ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, ;; 2005, 2006, 2007, 2008, 2009, 2010, 2011 diff --git a/lisp/language/thai.el b/lisp/language/thai.el index 44a9a31933..be15db49db 100644 --- a/lisp/language/thai.el +++ b/lisp/language/thai.el @@ -1,4 +1,4 @@ -;;; thai.el --- support for Thai -*- coding: utf-8 -*- +;;; thai.el --- support for Thai -*- coding: utf-8; lexical-binding: t; -*- ;; Copyright (C) 1997-1998, 2000-2021 Free Software Foundation, Inc. ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, diff --git a/lisp/language/tibetan.el b/lisp/language/tibetan.el index 5b8e29c2c7..edd9d765b1 100644 --- a/lisp/language/tibetan.el +++ b/lisp/language/tibetan.el @@ -1,4 +1,4 @@ -;;; tibetan.el --- support for Tibetan language -*- coding: utf-8-emacs; -*- +;;; tibetan.el --- support for Tibetan language -*- coding: utf-8-emacs; lexical-binding: t; -*- ;; Copyright (C) 1997, 2001-2021 Free Software Foundation, Inc. ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index c4eae686bd..526491f027 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -1,4 +1,4 @@ -;;; menu-bar.el --- define a default menu bar +;;; menu-bar.el --- define a default menu bar -*- lexical-binding: t; -*- ;; Copyright (C) 1993-1995, 2000-2021 Free Software Foundation, Inc. @@ -229,7 +229,8 @@ (filename (car (find-file-read-args "Find file: " mustmatch)))) (if mustmatch (find-file-existing filename) - (find-file filename)))) + (with-suppressed-warnings ((interactive-only find-file)) + (find-file filename))))) ;; The "Edit->Search" submenu (defvar menu-bar-last-search-type nil diff --git a/lisp/rfn-eshadow.el b/lisp/rfn-eshadow.el index f9842b52b1..378358feac 100644 --- a/lisp/rfn-eshadow.el +++ b/lisp/rfn-eshadow.el @@ -1,4 +1,4 @@ -;;; rfn-eshadow.el --- Highlight `shadowed' part of read-file-name input text +;;; rfn-eshadow.el --- Highlight `shadowed' part of read-file-name input text -*- lexical-binding: t; -*- ;; ;; Copyright (C) 2000-2021 Free Software Foundation, Inc. ;; diff --git a/lisp/scroll-bar.el b/lisp/scroll-bar.el index 802cb3072f..eecdb60f3a 100644 --- a/lisp/scroll-bar.el +++ b/lisp/scroll-bar.el @@ -1,4 +1,4 @@ -;;; scroll-bar.el --- window system-independent scroll bar support +;;; scroll-bar.el --- window system-independent scroll bar support -*- lexical-binding: t; -*- ;; Copyright (C) 1993-1995, 1999-2021 Free Software Foundation, Inc. diff --git a/lisp/term/common-win.el b/lisp/term/common-win.el index 8d5cb191dd..8ae58718e3 100644 --- a/lisp/term/common-win.el +++ b/lisp/term/common-win.el @@ -1,4 +1,4 @@ -;;; common-win.el --- common part of handling window systems +;;; common-win.el --- common part of handling window systems -*- lexical-binding: t; -*- ;; Copyright (C) 1993-1994, 2001-2021 Free Software Foundation, Inc. diff --git a/lisp/term/tty-colors.el b/lisp/term/tty-colors.el index 1aeaffbbc0..740d0654a1 100644 --- a/lisp/term/tty-colors.el +++ b/lisp/term/tty-colors.el @@ -1,4 +1,4 @@ -;;; tty-colors.el --- color support for character terminals +;;; tty-colors.el --- color support for character terminals -*- lexical-binding: t; -*- ;; Copyright (C) 1999-2021 Free Software Foundation, Inc. diff --git a/lisp/textmodes/fill.el b/lisp/textmodes/fill.el index e9bef6ec80..3346c551d9 100644 --- a/lisp/textmodes/fill.el +++ b/lisp/textmodes/fill.el @@ -1,4 +1,4 @@ -;;; fill.el --- fill commands for Emacs +;;; fill.el --- fill commands for Emacs -*- lexical-binding: t; -*- ;; Copyright (C) 1985-1986, 1992, 1994-1997, 1999, 2001-2021 Free ;; Software Foundation, Inc. @@ -40,13 +40,11 @@ Non-nil means changing indent doesn't end a paragraph. That mode can handle paragraphs with extra indentation on the first line, but it requires separator lines between paragraphs. A value of nil means that any change in indentation starts a new paragraph." - :type 'boolean - :group 'fill) + :type 'boolean) (defcustom colon-double-space nil "Non-nil means put two spaces after a colon when filling." - :type 'boolean - :group 'fill) + :type 'boolean) (put 'colon-double-space 'safe-local-variable 'booleanp) (defcustom fill-separate-heterogeneous-words-with-space nil @@ -56,7 +54,6 @@ the beginning of the next line when concatenating them for filling those lines. Whether to use a space depends on how the words are categorized." :type 'boolean - :group 'fill :version "26.1") (defvar fill-paragraph-function nil @@ -75,8 +72,7 @@ such as `fill-forward-paragraph-function'.") Kinsoku processing is designed to prevent certain characters from being placed at the beginning or end of a line by filling. See the documentation of `kinsoku' for more information." - :type 'boolean - :group 'fill) + :type 'boolean) (defun set-fill-prefix () "Set the fill prefix to the current line up to point. @@ -96,8 +92,7 @@ reinserts the fill prefix in each resulting line." (defcustom adaptive-fill-mode t "Non-nil means determine a paragraph's fill prefix from its text." - :type 'boolean - :group 'fill) + :type 'boolean) (defcustom adaptive-fill-regexp ;; Added `!' for doxygen comments starting with `//!' or `/*!'. @@ -113,8 +108,7 @@ standard indentation for the whole paragraph. If the paragraph has just one line, the indentation is taken from that line, but in that case `adaptive-fill-first-line-regexp' also plays a role." - :type 'regexp - :group 'fill) + :type 'regexp) (defcustom adaptive-fill-first-line-regexp (purecopy "\\`[ \t]*\\'") "Regexp specifying whether to set fill prefix from a one-line paragraph. @@ -126,15 +120,13 @@ By default, this regexp matches sequences of just spaces and tabs. However, we never use a prefix from a one-line paragraph if it would act as a paragraph-starter on the second line." - :type 'regexp - :group 'fill) + :type 'regexp) (defcustom adaptive-fill-function #'ignore "Function to call to choose a fill prefix for a paragraph. A nil return value means the function has not determined the fill prefix." :version "27.1" - :type 'function - :group 'fill) + :type 'function) (defvar fill-indent-according-to-mode nil ;Screws up CC-mode's filling tricks. "Whether or not filling should try to use the major mode's indentation.") @@ -367,15 +359,13 @@ which is an error according to some typographical conventions." The predicates are called with no arguments, with point at the place to be tested. If it returns a non-nil value, fill commands do not break the line there." - :group 'fill :type 'hook :options '(fill-french-nobreak-p fill-single-word-nobreak-p fill-single-char-nobreak-p)) (defcustom fill-nobreak-invisible nil "Non-nil means that fill commands do not break lines in invisible text." - :type 'boolean - :group 'fill) + :type 'boolean) (defun fill-nobreak-p () "Return nil if breaking the line at point is allowed. @@ -1110,8 +1100,7 @@ The `justification' text-property can locally override this variable." (const full) (const center) (const none)) - :safe 'symbolp - :group 'fill) + :safe 'symbolp) (make-variable-buffer-local 'default-justification) (defun current-justification () diff --git a/lisp/w32-fns.el b/lisp/w32-fns.el index 3da24c85c8..9ef2da737a 100644 --- a/lisp/w32-fns.el +++ b/lisp/w32-fns.el @@ -1,4 +1,4 @@ -;;; w32-fns.el --- Lisp routines for 32-bit Windows +;;; w32-fns.el --- Lisp routines for 32-bit Windows -*- lexical-binding: t; -*- ;; Copyright (C) 1994, 2001-2021 Free Software Foundation, Inc. @@ -383,10 +383,10 @@ for any permissions. This is required because the Windows build environment is not required to include Sed, which is used by leim/Makefile.in to do the job." - (find-file orig) - (goto-char (point-max)) - (insert-file-contents extra) - (delete-matching-lines "^$\\|^;") - (save-buffers-kill-emacs t)) + (with-current-buffer (find-file-noselect orig) + (goto-char (point-max)) + (insert-file-contents extra) + (delete-matching-lines "^$\\|^;") + (save-buffers-kill-emacs t))) ;;; w32-fns.el ends here diff --git a/lisp/widget.el b/lisp/widget.el index de690ad225..401b4cf298 100644 --- a/lisp/widget.el +++ b/lisp/widget.el @@ -1,4 +1,4 @@ -;;; widget.el --- a library of user interface components +;;; widget.el --- a library of user interface components -*- lexical-binding: t; -*- ;; ;; Copyright (C) 1996-1997, 2001-2021 Free Software Foundation, Inc. ;; commit 80e26472206cc44837521ba594cd50e724d9af5c Author: Stefan Monnier Date: Mon Jan 4 18:23:43 2021 -0500 * lisp/filesets.el: Use lexical-binding Remove redundant `:group` args. Require cl-lib and seq. Fix various O(n²) bug and flag a few remaining ones. (filesets-external-viewers): Simplify regexps. Use \' instead of $. Remove useless :constraint-flag properties. (filesets-convert-path-list): η-reduce. (filesets-eviewer-constraint-p): Mark :constraint-flag as obsolete. (filesets-spawn-external-viewer): Can't use `run-hooks` on lexical variable. (filesets-filter-list): Fix O(n²) bug. (filesets-ormap): Simplify. (filesets-some, filesets-member, filesets-sublist): Make them obsolete aliases. (filesets-reset-fileset): Simplify. (filesets-directory-files): Use `push`. (filesets-spawn-external-viewer): Use `mapconcat` to fix O(n²) bug. (filesets-cmd-get-args): Use `mapcan` to fix O(n²) bug. (filesets-run-cmd): Use `mapconcat` and `mapcan` to fix O(n²) bugs. (filesets-ingroup-collect-finder): Use dynamic scoping. (filesets-ingroup-collect-files): Use `nreverse` to fix O(n²) bug. (filesets-ingroup-collect-build-menu): Use `mapcan` to fix O(n²) bug. diff --git a/lisp/filesets.el b/lisp/filesets.el index 7c01b15b34..661a93edf1 100644 --- a/lisp/filesets.el +++ b/lisp/filesets.el @@ -1,4 +1,4 @@ -;;; filesets.el --- handle group of files +;;; filesets.el --- handle group of files -*- lexical-binding: t; -*- ;; Copyright (C) 2002-2021 Free Software Foundation, Inc. @@ -88,7 +88,8 @@ ;;; Code: -(eval-when-compile (require 'cl-lib)) +(require 'cl-lib) +(require 'seq) (require 'easymenu) ;;; Some variables @@ -153,52 +154,25 @@ COND-FN takes one argument: the current element." ; (cl-remove 'dummy lst :test (lambda (dummy elt) ; (not (funcall cond-fn elt))))) (let ((rv nil)) - (dolist (elt lst rv) + (dolist (elt lst) (when (funcall cond-fn elt) - (setq rv (append rv (list elt))))))) + (push elt rv))) + (nreverse rv))) (defun filesets-ormap (fsom-pred lst) "Return the tail of LST for the head of which FSOM-PRED is non-nil." (let ((fsom-lst lst) (fsom-rv nil)) - (while (and (not (null fsom-lst)) + (while (and fsom-lst (null fsom-rv)) (if (funcall fsom-pred (car fsom-lst)) (setq fsom-rv fsom-lst) (setq fsom-lst (cdr fsom-lst)))) fsom-rv)) -(defun filesets-some (fss-pred fss-lst) - "Return non-nil if FSS-PRED is non-nil for any element of FSS-LST. -Like `some', return the first value of FSS-PRED that is non-nil." - (catch 'exit - (dolist (fss-this fss-lst nil) - (let ((fss-rv (funcall fss-pred fss-this))) - (when fss-rv - (throw 'exit fss-rv)))))) -;(fset 'filesets-some 'cl-some) ;; or use the cl function - -(defun filesets-member (fsm-item fsm-lst &rest fsm-keys) - "Find the first occurrence of FSM-ITEM in FSM-LST. -It is supposed to work like cl's `member*'. At the moment only the :test -key is supported." - (let ((fsm-test (or (plist-get fsm-keys ':test) - (function equal)))) - (filesets-ormap (lambda (fsm-this) - (funcall fsm-test fsm-item fsm-this)) - fsm-lst))) -;(fset 'filesets-member 'cl-member) ;; or use the cl function - -(defun filesets-sublist (lst beg &optional end) - "Get the sublist of LST from BEG to END - 1." - (let ((rv nil) - (i beg) - (top (or end - (length lst)))) - (while (< i top) - (setq rv (append rv (list (nth i lst)))) - (setq i (+ i 1))) - rv)) +(define-obsolete-function-alias 'filesets-some #'cl-some "28.1") +(define-obsolete-function-alias 'filesets-member #'cl-member "28.1") +(define-obsolete-function-alias 'filesets-sublist #'seq-subseq "28.1") (defun filesets-select-command (cmd-list) "Select one command from CMD-LIST -- a string with space separated names." @@ -222,7 +196,7 @@ key is supported." (defun filesets-message (level &rest args) "Show a message only if LEVEL is greater or equal then `filesets-verbosity'." (when (<= level (abs filesets-verbosity)) - (apply 'message args))) + (apply #'message args))) ;;; config file @@ -233,9 +207,9 @@ key is supported." (defun filesets-reset-fileset (&optional fileset no-cache) "Reset the cached values for one or all filesets." - (if fileset - (setq filesets-submenus (lax-plist-put filesets-submenus fileset nil)) - (setq filesets-submenus nil)) + (setq filesets-submenus (if fileset + (lax-plist-put filesets-submenus fileset nil) + nil)) (setq filesets-has-changed-flag t) (setq filesets-update-cache-file-flag (or filesets-update-cache-file-flag (not no-cache)))) @@ -303,50 +277,46 @@ SYM to VAL and return t. If INIT-FLAG is non-nil, set with (defcustom filesets-menu-name "Filesets" "Filesets' menu name." - :set (function filesets-set-default) - :type 'string - :group 'filesets) + :set #'filesets-set-default + :type 'string) (defcustom filesets-menu-path '("File") ; cf recentf-menu-path "The menu under which the filesets menu should be inserted. See `easy-menu-add-item' for documentation." - :set (function filesets-set-default) + :set #'filesets-set-default :type '(choice (const :tag "Top Level" nil) (sexp :tag "Menu Path")) :version "23.1" ; was nil - :group 'filesets) + ) (defcustom filesets-menu-before "Open File..." ; cf recentf-menu-before "The name of a menu before which this menu should be added. See `easy-menu-add-item' for documentation." - :set (function filesets-set-default) + :set #'filesets-set-default :type '(choice (string :tag "Name") (const :tag "Last" nil)) :version "23.1" ; was "File" - :group 'filesets) + ) (defcustom filesets-menu-in-menu nil "Use that instead of `current-menubar' as the menu to change. See `easy-menu-add-item' for documentation." - :set (function filesets-set-default) - :type 'sexp - :group 'filesets) + :set #'filesets-set-default + :type 'sexp) (defcustom filesets-menu-shortcuts-flag t "Non-nil means to prepend menus with hopefully unique shortcuts." - :set (function filesets-set-default!) - :type 'boolean - :group 'filesets) + :set #'filesets-set-default! + :type 'boolean) (defcustom filesets-menu-shortcuts-marker "%_" "String for marking menu shortcuts." - :set (function filesets-set-default!) - :type 'string - :group 'filesets) + :set #'filesets-set-default! + :type 'string) ;;(defcustom filesets-menu-cnvfp-flag nil ;; "Non-nil means show \"Convert :pattern to :files\" entry for :pattern menus." -;; :set (function filesets-set-default!) +;; :set #'filesets-set-default! ;; :type 'boolean ;; :group 'filesets) @@ -355,9 +325,8 @@ See `easy-menu-add-item' for documentation." "File to be used for saving the filesets menu between sessions. Set this to \"\", to disable caching of menus. Don't forget to check out `filesets-menu-ensure-use-cached'." - :set (function filesets-set-default) - :type 'file - :group 'filesets) + :set #'filesets-set-default + :type 'file) (put 'filesets-menu-cache-file 'risky-local-variable t) (defcustom filesets-menu-cache-contents @@ -383,7 +352,7 @@ If you want caching to work properly, at least `filesets-submenus', list. Don't forget to check out `filesets-menu-ensure-use-cached'." - :set (function filesets-set-default) + :set #'filesets-set-default :type '(repeat (choice :tag "Variable" (const :tag "filesets-submenus" @@ -400,8 +369,7 @@ Don't forget to check out `filesets-menu-ensure-use-cached'." :value filesets-ingroup-patterns) (const :tag "filesets-be-docile-flag" :value filesets-be-docile-flag) - (sexp :tag "Other" :value nil))) - :group 'filesets) + (sexp :tag "Other" :value nil)))) (define-obsolete-variable-alias 'filesets-cache-fill-content-hooks 'filesets-cache-fill-content-hook "24.3") @@ -423,48 +391,43 @@ configuration file, you can add a something like this to this hook. Don't forget to check out `filesets-menu-ensure-use-cached'." - :set (function filesets-set-default) - :type 'hook - :group 'filesets) + :set #'filesets-set-default + :type 'hook) (defcustom filesets-cache-hostname-flag nil "Non-nil means cache the hostname. If the current name differs from the cached one, rebuild the menu and create a new cache file." - :set (function filesets-set-default) - :type 'boolean - :group 'filesets) + :set #'filesets-set-default + :type 'boolean) (defcustom filesets-cache-save-often-flag nil "Non-nil means save buffer on every change of the filesets menu. If this variable is set to nil and if Emacs crashes, the cache and filesets-data could get out of sync. Set this to t if this happens from time to time or if the fileset cache causes troubles." - :set (function filesets-set-default) - :type 'boolean - :group 'filesets) + :set #'filesets-set-default + :type 'boolean) (defcustom filesets-max-submenu-length 25 "Maximum length of submenus. Set this value to 0 to turn menu splitting off. BTW, parts of submenus will not be rewrapped if their length exceeds this value." - :set (function filesets-set-default) - :type 'integer - :group 'filesets) + :set #'filesets-set-default + :type 'integer) (defcustom filesets-max-entry-length 50 "Truncate names of split submenus to this length." - :set (function filesets-set-default) - :type 'integer - :group 'filesets) + :set #'filesets-set-default + :type 'integer) -(defcustom filesets-browse-dir-function 'dired +(defcustom filesets-browse-dir-function #'dired "A function or command used for browsing directories. When using an external command, \"%s\" will be replaced with the directory's name. Note: You have to manually rebuild the menu if you change this value." - :set (function filesets-set-default) + :set #'filesets-set-default :type '(choice :tag "Function:" (const :tag "dired" :value dired) @@ -473,10 +436,9 @@ Note: You have to manually rebuild the menu if you change this value." (string :tag "Name") (string :tag "Arguments")) (function :tag "Function" - :value nil)) - :group 'filesets) + :value nil))) -(defcustom filesets-open-file-function 'filesets-find-or-display-file +(defcustom filesets-open-file-function #'filesets-find-or-display-file "The function used for opening files. `filesets-find-or-display-file' ... Filesets' default function for @@ -489,26 +451,24 @@ for a specific file type. Either this viewer, if defined, or readable, will not be opened. Caveat: Changes will take effect only after rebuilding the menu." - :set (function filesets-set-default) + :set #'filesets-set-default :type '(choice :tag "Function:" (const :tag "filesets-find-or-display-file" :value filesets-find-or-display-file) (const :tag "filesets-find-file" :value filesets-find-file) (function :tag "Function" - :value nil)) - :group 'filesets) + :value nil))) -(defcustom filesets-save-buffer-function 'save-buffer +(defcustom filesets-save-buffer-function #'save-buffer "The function used to save a buffer. Caveat: Changes will take effect after rebuilding the menu." - :set (function filesets-set-default) + :set #'filesets-set-default :type '(choice :tag "Function:" (const :tag "save-buffer" :value save-buffer) (function :tag "Function" - :value nil)) - :group 'filesets) + :value nil))) (defcustom filesets-find-file-delay (if (and (featurep 'xemacs) gutter-buffers-tab-visible-p) @@ -519,29 +479,25 @@ This is for calls via `filesets-find-or-display-file' or `filesets-find-file'. Set this to 0, if you don't use XEmacs's buffer tabs." - :set (function filesets-set-default) - :type 'number - :group 'filesets) + :set #'filesets-set-default + :type 'number) (defcustom filesets-be-docile-flag nil "Non-nil means don't complain if a file or a directory doesn't exist. This is useful if you want to use the same startup files in different computer environments." - :set (function filesets-set-default) - :type 'boolean - :group 'filesets) + :set #'filesets-set-default + :type 'boolean) (defcustom filesets-sort-menu-flag t "Non-nil means sort the filesets menu alphabetically." - :set (function filesets-set-default) - :type 'boolean - :group 'filesets) + :set #'filesets-set-default + :type 'boolean) (defcustom filesets-sort-case-sensitive-flag t "Non-nil means sorting of the filesets menu is case sensitive." - :set (function filesets-set-default) - :type 'boolean - :group 'filesets) + :set #'filesets-set-default + :type 'boolean) (defcustom filesets-tree-max-level 3 "Maximum scan depth for directory trees. @@ -561,9 +517,8 @@ i.e. how deep the menu should be. Try something like and it should become clear what this option is about. In any case, including directory trees to the menu can take a lot of memory." - :set (function filesets-set-default) - :type 'integer - :group 'filesets) + :set #'filesets-set-default + :type 'integer) (defcustom filesets-commands '(("Isearch" @@ -590,7 +545,7 @@ function that returns one) to be run on a filesets' files. The argument or <> (quoted) will be replaced with the filename." - :set (function filesets-set-default+) + :set #'filesets-set-default+ :type '(repeat :tag "Commands" (list :tag "Definition" :value ("") (string "Name") @@ -606,8 +561,7 @@ the filename." (string :tag "Quoted File Name" :value "<>") (function :tag "Function" - :value nil))))) - :group 'filesets) + :value nil)))))) (put 'filesets-commands 'risky-local-variable t) (defcustom filesets-external-viewers @@ -627,28 +581,33 @@ the filename." (dvi-cmd "xdvi") (doc-cmd "antiword") (pic-cmd "gqview")) - `(("^.+\\..?html?$" browse-url + `((".\\..?html?\\'" browse-url ((:ignore-on-open-all t))) - ("^.+\\.pdf$" ,pdf-cmd + (".\\.pdf\\'" ,pdf-cmd ((:ignore-on-open-all t) (:ignore-on-read-text t) - (:constraint-flag ,pdf-cmd))) - ("^.+\\.e?ps\\(.gz\\)?$" ,ps-cmd + ;; (:constraintp ,pdf-cmd) + )) + (".\\.e?ps\\(.gz\\)?\\'" ,ps-cmd ((:ignore-on-open-all t) (:ignore-on-read-text t) - (:constraint-flag ,ps-cmd))) - ("^.+\\.dvi$" ,dvi-cmd + ;; (:constraintp ,ps-cmd) + )) + (".\\.dvi\\'" ,dvi-cmd ((:ignore-on-open-all t) (:ignore-on-read-text t) - (:constraint-flag ,dvi-cmd))) - ("^.+\\.doc$" ,doc-cmd + ;; (:constraintp ,dvi-cmd) + )) + (".\\.doc\\'" ,doc-cmd ((:capture-output t) (:ignore-on-read-text t) - (:constraint-flag ,doc-cmd))) - ("^.+\\.\\(tiff\\|xpm\\|gif\\|pgn\\)$" ,pic-cmd + ;; (:constraintp ,doc-cmd) + )) + (".\\.\\(tiff\\|xpm\\|gif\\|pgn\\)\\'" ,pic-cmd ((:ignore-on-open-all t) (:ignore-on-read-text t) - (:constraint-flag ,pic-cmd))))) + ;; (:constraintp ,pic-cmd) + )))) "Association list of file patterns and external viewers for use with `filesets-find-or-display-file'. @@ -665,10 +624,8 @@ i.e. on open-all-files-events or when running commands :constraintp FUNCTION ... use this viewer only if FUNCTION returns non-nil -:constraint-flag SEXP ... use this viewer only if SEXP evaluates to non-nil - -:open-hook HOOK ... run hooks after spawning the viewer -- mainly useful -in conjunction with :capture-output +:open-hook FUNCTIONs ... run FUNCTIONs after spawning the viewer -- mainly +useful in conjunction with :capture-output :args (FORMAT-STRING or SYMBOL or FUNCTION) ... a list of arguments \(defaults to (list \"%S\")) when using shell commands @@ -693,7 +650,7 @@ In order to view pdf or rtf files in an Emacs buffer, you could use these: (:constraintp (lambda () (and (filesets-which-command-p \"rtf2htm\") (filesets-which-command-p \"w3m\"))))))" - :set (function filesets-set-default) + :set #'filesets-set-default :type '(repeat :tag "Viewer" (list :tag "Definition" :value ("^.+\\.suffix$" "") @@ -708,7 +665,7 @@ In order to view pdf or rtf files in an Emacs buffer, you could use these: (const :format "" :value :constraintp) (function :tag "Function")) - (list :tag ":constraint-flag" + (list :tag ":constraint-flag (obsolete)" :value (:constraint-flag) (const :format "" :value :constraint-flag) @@ -749,8 +706,7 @@ In order to view pdf or rtf files in an Emacs buffer, you could use these: :value (:capture-output t) (const :format "" :value :capture-output) - (boolean :tag "Boolean")))))) - :group 'filesets) + (boolean :tag "Boolean"))))))) (put 'filesets-external-viewers 'risky-local-variable t) (defcustom filesets-ingroup-patterns @@ -891,7 +847,7 @@ With duplicates removed, it would be: M + A - X B" - :set (function filesets-set-default) + :set #'filesets-set-default :type '(repeat :tag "Include" (list @@ -937,8 +893,7 @@ With duplicates removed, it would be: (list :tag ":preprocess" :value (:preprocess) (const :format "" :value :preprocess) - (function :tag "Function"))))))) - :group 'filesets) + (function :tag "Function")))))))) (put 'filesets-ingroup-patterns 'risky-local-variable t) (defcustom filesets-data nil @@ -1009,8 +964,7 @@ is used. Before using :ingroup, make sure that the file type is already defined in `filesets-ingroup-patterns'." - :group 'filesets - :set (function filesets-data-set-default) + :set #'filesets-data-set-default :type '(repeat (cons :tag "Fileset" (string :tag "Name" :value "") @@ -1072,9 +1026,8 @@ defined in `filesets-ingroup-patterns'." (defcustom filesets-query-user-limit 15 "Query the user before opening a fileset with that many files." - :set (function filesets-set-default) - :type 'integer - :group 'filesets) + :set #'filesets-set-default + :type 'integer) (defun filesets-filter-dir-names (lst &optional negative) @@ -1127,16 +1080,16 @@ Return full path if FULL-FLAG is non-nil." (string-match-p pattern this)) (filesets-message 5 "Filesets: matched dir %S with pattern %S" this pattern) - (setq dirs (cons this dirs)))) + (push this dirs))) (t (when (or (not pattern) (string-match-p pattern this)) (filesets-message 5 "Filesets: matched file %S with pattern %S" this pattern) - (setq files (cons (if full-flag - (concat (file-name-as-directory dir) this) - this) - files)))))) + (push (if full-flag + (concat (file-name-as-directory dir) this) + this) + files))))) (cond ((equal what ':dirs) (filesets-conditional-sort dirs)) @@ -1193,7 +1146,7 @@ Return full path if FULL-FLAG is non-nil." (defun filesets-convert-path-list (string) "Return a path-list given as STRING as list." (if string - (mapcar (lambda (x) (file-name-as-directory x)) + (mapcar #'file-name-as-directory (split-string string path-separator)) nil)) @@ -1203,17 +1156,17 @@ Return full path if FULL-FLAG is non-nil." filename))) (if (file-exists-p f) f - (filesets-some + (cl-some (lambda (dir) (let ((dir (file-name-as-directory dir)) (files (if (file-exists-p dir) (filesets-directory-files dir nil ':files) nil))) - (filesets-some (lambda (file) - (if (equal filename (file-name-nondirectory file)) - (concat dir file) - nil)) - files))) + (cl-some (lambda (file) + (if (equal filename (file-name-nondirectory file)) + (concat dir file) + nil)) + files))) path-list)))) @@ -1223,12 +1176,14 @@ Return full path if FULL-FLAG is non-nil." (defun filesets-eviewer-constraint-p (entry) (let* ((props (filesets-eviewer-get-props entry)) - (constraint (assoc ':constraintp props)) - (constraint-flag (assoc ':constraint-flag props))) + (constraint (assoc :constraintp props)) + (constraint-flag (assoc :constraint-flag props))) (cond (constraint (funcall (cadr constraint))) (constraint-flag + (message "Obsolete :constraint-flag %S, use :constraintp instead" + (cadr constraint-flag)) (eval (cadr constraint-flag))) (t t)))) @@ -1236,7 +1191,7 @@ Return full path if FULL-FLAG is non-nil." (defun filesets-get-external-viewer (file) "Find an external viewer for FILE." (let ((filename (file-name-nondirectory file))) - (filesets-some + (cl-some (lambda (entry) (when (and (string-match-p (nth 0 entry) filename) (filesets-eviewer-constraint-p entry)) @@ -1246,7 +1201,7 @@ Return full path if FULL-FLAG is non-nil." (defun filesets-get-external-viewer-by-name (name) "Get the external viewer definition called NAME." (when name - (filesets-some + (cl-some (lambda (entry) (when (and (string-equal (nth 1 entry) name) (filesets-eviewer-constraint-p entry)) @@ -1308,17 +1263,13 @@ Use the viewer defined in EV-ENTRY (a valid element of (oh (filesets-filetype-get-prop ':open-hook file entry)) (args (let ((fmt (filesets-filetype-get-prop ':args file entry))) (if fmt - (let ((rv "")) - (dolist (this fmt rv) - (setq rv (concat rv - (cond - ((stringp this) - (format this file)) - ((and (symbolp this) - (fboundp this)) - (format "%S" (funcall this))) - (t - (format "%S" this))))))) + (mapconcat + (lambda (this) + (if (stringp this) (format this file) + (format "%S" (if (functionp this) + (funcall this) + this)))) + fmt "") (format "%S" file)))) (output (cond @@ -1338,13 +1289,15 @@ Use the viewer defined in EV-ENTRY (a valid element of (insert output) (setq-local filesets-output-buffer-flag t) (set-visited-file-name file t) - (when oh - (run-hooks 'oh)) + (if (functionp oh) + (funcall oh) + (mapc #'funcall oh)) (set-buffer-modified-p nil) (setq buffer-read-only t) (goto-char (point-min))) - (when oh - (run-hooks 'oh)))) + (if (functionp oh) + (funcall oh) + (mapc #'funcall oh)))) (error "Filesets: general error when spawning external viewer")))) (defun filesets-find-file (file) @@ -1355,7 +1308,8 @@ not be opened." (when (or (file-readable-p file) (not filesets-be-docile-flag)) (sit-for filesets-find-file-delay) - (find-file file))) + (with-suppressed-warnings ((interactive-only find-file)) + (find-file file)))) (defun filesets-find-or-display-file (&optional file viewer) "Visit FILE using an external VIEWER or open it in an Emacs buffer." @@ -1394,7 +1348,8 @@ not be opened." (if (functionp filesets-browse-dir-function) (funcall filesets-browse-dir-function dir) (let ((name (car filesets-browse-dir-function)) - (args (format (cadr filesets-browse-dir-function) (expand-file-name dir)))) + (args (format (cadr filesets-browse-dir-function) + (expand-file-name dir)))) (with-temp-buffer (start-process (concat "Filesets:" name) "*Filesets external directory browser*" @@ -1445,7 +1400,7 @@ Return DEFAULT if not found. Return (car VALUE) if CARP is non-nil." "Return fileset ENTRY's mode: :files, :file, :tree, :pattern, or :ingroup. See `filesets-data'." (let ((data (filesets-data-get-data entry))) - (filesets-some + (cl-some (lambda (x) (if (assoc x data) x)) @@ -1557,16 +1512,15 @@ SAVE-FUNCTION takes no argument, but works on the current buffer." (assoc cmd-name filesets-commands)) (defun filesets-cmd-get-args (cmd-name) - (let ((args (let ((def (filesets-cmd-get-def cmd-name))) - (nth 2 def))) - (rv nil)) - (dolist (this args rv) - (cond - ((and (symbolp this) (fboundp this)) - (let ((x (funcall this))) - (setq rv (append rv (if (listp x) x (list x)))))) - (t - (setq rv (append rv (list this)))))))) + (mapcan (lambda (this) + (cond + ((and (symbolp this) (fboundp this)) + (let ((x (funcall this))) + (if (listp x) x (list x)))) + (t + (list this)))) + (let ((def (filesets-cmd-get-def cmd-name))) + (nth 2 def)))) (defun filesets-cmd-get-fn (cmd-name) (let ((def (filesets-cmd-get-def cmd-name))) @@ -1628,28 +1582,24 @@ Replace or <> with filename." (cond ((stringp fn) (let* ((args - (let ((txt "")) - (dolist (this args txt) - (setq txt - (concat txt - (if (equal txt "") "" " ") - (filesets-run-cmd--repl-fn + (mapconcat + (lambda (this) + (filesets-run-cmd--repl-fn this (lambda (this) - (format "%s" this)))))))) + (format "%s" this)))) + args + " ")) (cmd (concat fn " " args))) (filesets-cmd-show-result cmd (shell-command-to-string cmd)))) ((symbolp fn) - (let ((args - (let ((argl nil)) - (dolist (this args argl) - (setq argl - (append argl - (filesets-run-cmd--repl-fn - this - 'list))))))) - (apply fn args))))))))))))))))) + (apply fn + (mapcan (lambda (this) + (filesets-run-cmd--repl-fn + this + 'list)) + args))))))))))))))))) (defun filesets-get-cmd-menu () "Create filesets command menu." @@ -1832,8 +1782,8 @@ User will be queried, if no fileset name is provided." (if entry (let* ((files (filesets-entry-get-files entry)) (this (buffer-file-name buffer)) - (inlist (filesets-member this files - :test 'filesets-files-equalp))) + (inlist (cl-member this files + :test #'filesets-files-equalp))) (cond (inlist (message "Filesets: `%s' is already in `%s'" this name)) @@ -1858,8 +1808,8 @@ User will be queried, if no fileset name is provided." (if entry (let* ((files (filesets-entry-get-files entry)) (this (buffer-file-name buffer)) - (inlist (filesets-member this files - :test 'filesets-files-equalp))) + (inlist (cl-member this files + :test #'filesets-files-equalp))) ;;(message "%s %s %s" files this inlist) (if (and files this inlist) (let ((new (list (cons ':files (delete (car inlist) files))))) @@ -1908,7 +1858,7 @@ User will be queried, if no fileset name is provided." (substring (elt submenu 0) 2)))) (if (listp submenu) (cons name (cdr submenu)) - (apply 'vector (list name (cadr (append submenu nil))))))) + (apply #'vector (list name (cadr (append submenu nil))))))) ; (vconcat `[,name] (subseq submenu 1))))) (defun filesets-wrap-submenu (submenu-body) @@ -1926,12 +1876,14 @@ User will be queried, if no fileset name is provided." ((or (> count bl) (null data))) ;; (let ((sl (subseq submenu-body count - (let ((sl (filesets-sublist submenu-body count - (let ((x (+ count factor))) - (if (>= bl x) - x - nil))))) + (let ((sl (seq-subseq submenu-body count + (let ((x (+ count factor))) + (if (>= bl x) + x + nil))))) (when sl + ;; FIXME: O(n²) performance bug because of repeated `append': + ;; use `mapcan'? (setq result (append result @@ -1948,6 +1900,8 @@ User will be queried, if no fileset name is provided." (if (null (cdr x)) "" ", ")))) + ;; FIXME: O(n²) performance bug because of + ;; repeated `concat': use `mapconcat'? (setq rv (concat rv @@ -2023,11 +1977,11 @@ LOOKUP-NAME is used as lookup name for retrieving fileset specific settings." (and (stringp a) (stringp b) (string-match-p a b)))))) - (filesets-some (lambda (x) - (if (funcall fn (car x) masterfile) - (nth pos x) - nil)) - filesets-ingroup-patterns))) + (cl-some (lambda (x) + (if (funcall fn (car x) masterfile) + (nth pos x) + nil)) + filesets-ingroup-patterns))) (defun filesets-ingroup-get-pattern (master) "Access to `filesets-ingroup-patterns'. Extract patterns." @@ -2039,12 +1993,8 @@ LOOKUP-NAME is used as lookup name for retrieving fileset specific settings." (defun filesets-ingroup-collect-finder (patt case-sensitivep) "Helper function for `filesets-ingroup-collect'. Find pattern PATT." - (let ((cfs case-fold-search) - (rv (progn - (setq case-fold-search (not case-sensitivep)) - (re-search-forward patt nil t)))) - (setq case-fold-search cfs) - rv)) + (let ((case-fold-search (not case-sensitivep))) + (re-search-forward patt nil t))) (defun filesets-ingroup-cache-get (master) "Access to `filesets-ingroup-cache'." @@ -2102,9 +2052,9 @@ LOOKUP-NAME is used as lookup name for retrieving fileset specific settings." (when (and f (not (member f flist)) (or (not remdupl-flag) - (not (filesets-member + (not (cl-member f filesets-ingroup-files - :test 'filesets-files-equalp)))) + :test #'filesets-files-equalp)))) (let ((no-stub-flag (and (not this-stub-flag) (if this-stubp @@ -2116,16 +2066,18 @@ LOOKUP-NAME is used as lookup name for retrieving fileset specific settings." (cons f filesets-ingroup-files)) (when no-stub-flag (filesets-ingroup-cache-put master f)) - (setq lst (append lst (list f)))))))) + (push f lst)))))) (when lst (setq rv + ;; FIXME: O(n²) performance bug because of repeated + ;; `nconc'. (nconc rv (mapcar (lambda (this) `((,this ,this-name) ,@(filesets-ingroup-collect-files fs remdupl-flag this (- this-sd 1)))) - lst)))))))) + (nreverse lst))))))))) (filesets-message 2 "Filesets: no patterns defined for %S" master))))) (defun filesets-ingroup-collect-build-menu (fs flist &optional other-count) @@ -2135,42 +2087,41 @@ FS is a fileset's name. FLIST is a list returned by (if (null flist) nil (let ((count 0) - (fsn fs) - (rv nil)) - (dolist (this flist rv) - (setq count (+ count 1)) - (let* ((def (if (listp this) (car this) (list this ""))) - (files (if (listp this) (cdr this) nil)) - (master (nth 0 def)) - (name (nth 1 def)) - (nm (concat (filesets-get-shortcut (if (or (not other-count) files) - count other-count)) - (if (or (null name) (equal name "")) - "" - (format "%s: " name)) - (file-name-nondirectory master)))) - (setq rv - (append rv - (if files - `((,nm - [,(concat "Inclusion Group: " - (file-name-nondirectory master)) - (filesets-open ':ingroup ',master ',fsn)] - "---" - [,master (filesets-file-open nil ',master ',fsn)] - "---" - ,@(let ((count 0)) - (mapcar - (lambda (this) - (setq count (+ count 1)) - (let ((ff (filesets-ingroup-collect-build-menu - fs (list this) count))) - (if (= (length ff) 1) - (car ff) - ff))) - files)) - ,@(filesets-get-menu-epilog master ':ingroup fsn))) - `([,nm (filesets-file-open nil ',master ',fsn)]))))))))) + (fsn fs)) + (mapcan (lambda (this) + (setq count (+ count 1)) + (let* ((def (if (listp this) (car this) (list this ""))) + (files (if (listp this) (cdr this) nil)) + (master (nth 0 def)) + (name (nth 1 def)) + (nm (concat (filesets-get-shortcut + (if (or (not other-count) files) + count other-count)) + (if (or (null name) (equal name "")) + "" + (format "%s: " name)) + (file-name-nondirectory master)))) + (if files + `((,nm + [,(concat "Inclusion Group: " + (file-name-nondirectory master)) + (filesets-open ':ingroup ',master ',fsn)] + "---" + [,master (filesets-file-open nil ',master ',fsn)] + "---" + ,@(let ((count 0)) + (mapcar + (lambda (this) + (setq count (+ count 1)) + (let ((ff (filesets-ingroup-collect-build-menu + fs (list this) count))) + (if (= (length ff) 1) + (car ff) + ff))) + files)) + ,@(filesets-get-menu-epilog master ':ingroup fsn))) + `([,nm (filesets-file-open nil ',master ',fsn)])))) + flist)))) (defun filesets-ingroup-collect (fs remdupl-flag master) "Collect names of included files and build submenu." @@ -2275,7 +2226,7 @@ Construct a shortcut from COUNT." (:pattern (let* ((files (filesets-get-filelist entry mode 'on-ls)) (dirpatt (filesets-entry-get-pattern entry)) - (pattname (apply 'concat (cons "Pattern: " dirpatt))) + (pattname (apply #'concat (cons "Pattern: " dirpatt))) (count 0)) ;;(filesets-message 3 "Filesets: scanning %S" pattname) `([,pattname @@ -2418,14 +2369,14 @@ fileset thinks this is necessary or not." (dolist (this filesets-menu-cache-contents) (if (get this 'custom-type) (progn - (insert (format "(setq-default %s '%S)" this (eval this))) + (insert (format "(setq-default %s '%S)" this (eval this t))) (when filesets-menu-ensure-use-cached (newline) (insert (format "(setq %s (cons '%s %s))" 'filesets-ignore-next-set-default this 'filesets-ignore-next-set-default)))) - (insert (format "(setq %s '%S)" this (eval this)))) + (insert (format "(setq %s '%S)" this (eval this t)))) (newline 2)) (insert (format "(setq filesets-cache-version %S)" filesets-version)) (newline 2) @@ -2526,9 +2477,9 @@ We apologize for the inconvenience."))) "Filesets initialization. Set up hooks, load the cache file -- if existing -- and build the menu." (add-hook 'menu-bar-update-hook #'filesets-build-menu-maybe) - (add-hook 'kill-buffer-hook (function filesets-remove-from-ubl)) - (add-hook 'first-change-hook (function filesets-reset-filename-on-change)) - (add-hook 'kill-emacs-hook (function filesets-exit)) + (add-hook 'kill-buffer-hook #'filesets-remove-from-ubl) + (add-hook 'first-change-hook #'filesets-reset-filename-on-change) + (add-hook 'kill-emacs-hook #'filesets-exit) (if (filesets-menu-cache-file-load) (progn (filesets-build-menu-maybe) @@ -2542,7 +2493,7 @@ Set up hooks, load the cache file -- if existing -- and build the menu." (defun filesets-error (_class &rest args) "`error' wrapper." (declare (obsolete error "28.1")) - (error "%s" (mapconcat 'identity args " "))) + (error "%s" (mapconcat #'identity args " "))) (provide 'filesets) commit 57e872ac757d7a003f4a7f132a08798c3a1a6e97 Author: Philipp Stephani Date: Mon Jan 4 22:08:39 2021 +0100 Make a process tests a bit more robust. * test/src/process-tests.el (process-tests/fd-setsize-no-crash/make-process): Allow for processes to fail before 'exec'. diff --git a/test/src/process-tests.el b/test/src/process-tests.el index 5294bc07ce..1f88232c7f 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -560,8 +560,11 @@ FD_SETSIZE file descriptors (Bug#24325)." ;; We should have managed to start at least one process. (should processes) (dolist (process processes) - (should (process-live-p process)) - (process-send-eof process) + ;; The process now should either be running, or have + ;; already failed before `exec'. + (should (memq (process-status process) '(run exit))) + (when (process-live-p process) + (process-send-eof process)) (while (accept-process-output process)) (should (eq (process-status process) 'exit)) ;; If there's an error between fork and exec, Emacs commit 37e3a6eb3161c664ea1a81dcaadb0f29fdf162fb Author: Stefan Monnier Date: Mon Jan 4 15:34:12 2021 -0500 * lisp/cedet/srecode/semantic.el: Use lexical-binding (srecode-semantic-insert-tag): Can't use `run-hook-with-args` on lexical variable. diff --git a/lisp/cedet/srecode/semantic.el b/lisp/cedet/srecode/semantic.el index 21ed1f96ae..101246cae6 100644 --- a/lisp/cedet/srecode/semantic.el +++ b/lisp/cedet/srecode/semantic.el @@ -1,4 +1,4 @@ -;;; srecode/semantic.el --- Semantic specific extensions to SRecode. +;;; srecode/semantic.el --- Semantic specific extensions to SRecode -*- lexical-binding:t -*- ;; Copyright (C) 2007-2021 Free Software Foundation, Inc. @@ -57,7 +57,7 @@ This class will be used to derive dictionary values.") (cl-defmethod srecode-compound-toString((cp srecode-semantic-tag) function - dictionary) + _dictionary) "Convert the compound dictionary value CP to a string. If FUNCTION is non-nil, then FUNCTION is somehow applied to an aspect of the compound value." @@ -410,7 +410,9 @@ as `function' will leave point where code might be inserted." ;; Insert the template. (let ((endpt (srecode-insert-fcn temp dict nil t))) - (run-hook-with-args 'point-insert-fcn tag) + (if (functionp point-insert-fcn) + (funcall point-insert-fcn tag) + (dolist (f point-insert-fcn) (funcall f tag))) ;;(sit-for 1) (cond commit a79e1a85f8f20911be3bbac883ee7bdffcfbe7a0 Author: Stefan Monnier Date: Mon Jan 4 15:31:58 2021 -0500 * lisp/mail/reporter.el: Use lexical-binding (reporter--run-functions): New function. (reporter-dump-state): Use it and simplify the code. diff --git a/lisp/mail/reporter.el b/lisp/mail/reporter.el index f4de299f53..2e583a470d 100644 --- a/lisp/mail/reporter.el +++ b/lisp/mail/reporter.el @@ -1,4 +1,4 @@ -;;; reporter.el --- customizable bug reporting of lisp programs +;;; reporter.el --- customizable bug reporting of lisp programs -*- lexical-binding: t; -*- ;; Copyright (C) 1993-1998, 2001-2021 Free Software Foundation, Inc. @@ -158,7 +158,7 @@ composed.") t) (error indent-enclosing-p)))) -(defun reporter-lisp-indent (indent-point state) +(defun reporter-lisp-indent (_indent-point state) "A better lisp indentation style for bug reporting." (save-excursion (goto-char (1+ (nth 1 state))) @@ -193,7 +193,7 @@ MAILBUF is the mail buffer being composed." (<= maxwidth (current-column))) (save-excursion (let ((compact-p (not (memq varsym reporter-dont-compact-list))) - (lisp-indent-function 'reporter-lisp-indent)) + (lisp-indent-function #'reporter-lisp-indent)) (goto-char here) (reporter-beautify-list maxwidth compact-p)))) (insert "\n")) @@ -206,6 +206,11 @@ MAILBUF is the mail buffer being composed." (error (error "")))) +(defun reporter--run-functions (funs) + (if (functionp funs) + (funcall funs) + (mapc #'funcall funs))) + (defun reporter-dump-state (pkgname varlist pre-hooks post-hooks) "Dump the state of the mode specific variables. PKGNAME contains the name of the mode as it will appear in the bug @@ -230,42 +235,39 @@ properly. PRE-HOOKS is run after the Emacs version and PKGNAME are inserted, but before the VARLIST is dumped. POST-HOOKS is run after the VARLIST is dumped." - (let ((buffer (current-buffer))) - (set-buffer buffer) - (insert "Emacs : " (emacs-version) "\n") - (and pkgname - (insert "Package: " pkgname "\n")) - (run-hooks 'pre-hooks) - (if (not varlist) - nil - (insert "\ncurrent state:\n==============\n") - ;; create an emacs-lisp-mode buffer to contain the output, which - ;; we'll later insert into the mail buffer - (condition-case fault - (let ((mailbuf (current-buffer)) - (elbuf (get-buffer-create " *tmp-reporter-buffer*"))) - (with-current-buffer elbuf - (emacs-lisp-mode) - (erase-buffer) - (insert "(setq\n") - (lisp-indent-line) - (mapc - (lambda (varsym-or-cons-cell) - (let ((varsym (or (car-safe varsym-or-cons-cell) - varsym-or-cons-cell)) - (printer (or (cdr-safe varsym-or-cons-cell) - 'reporter-dump-variable))) - (funcall printer varsym mailbuf))) - varlist) - (lisp-indent-line) - (insert ")\n")) - (insert-buffer-substring elbuf)) - (error - (insert "State could not be dumped due to the following error:\n\n" - (format "%s" fault) - "\n\nYou should still send this bug report.")))) - (run-hooks 'post-hooks) - )) + (insert "Emacs : " (emacs-version) "\n") + (and pkgname + (insert "Package: " pkgname "\n")) + (reporter--run-functions pre-hooks) + (if (not varlist) + nil + (insert "\ncurrent state:\n==============\n") + ;; create an emacs-lisp-mode buffer to contain the output, which + ;; we'll later insert into the mail buffer + (condition-case fault + (let ((mailbuf (current-buffer)) + (elbuf (get-buffer-create " *tmp-reporter-buffer*"))) + (with-current-buffer elbuf + (emacs-lisp-mode) + (erase-buffer) + (insert "(setq\n") + (lisp-indent-line) + (mapc + (lambda (varsym-or-cons-cell) + (let ((varsym (or (car-safe varsym-or-cons-cell) + varsym-or-cons-cell)) + (printer (or (cdr-safe varsym-or-cons-cell) + 'reporter-dump-variable))) + (funcall printer varsym mailbuf))) + varlist) + (lisp-indent-line) + (insert ")\n")) + (insert-buffer-substring elbuf)) + (error + (insert "State could not be dumped due to the following error:\n\n" + (format "%s" fault) + "\n\nYou should still send this bug report.")))) + (reporter--run-functions post-hooks)) (defun reporter-compose-outgoing () @@ -365,7 +367,7 @@ mail-sending package is used for editing and sending the message." (skip-chars-backward " \t\n") (setq reporter-initial-text (buffer-substring after-sep-pos (point)))) (if (setq hookvar (get agent 'hookvar)) - (add-hook hookvar 'reporter-bug-hook nil t)) + (add-hook hookvar #'reporter-bug-hook nil t)) ;; compose the minibuf message and display this. (let* ((sendkey-whereis (where-is-internal commit 42c3f7a134f8e51f4eb78e907abb521421e50e39 Author: Stefan Monnier Date: Mon Jan 4 15:25:29 2021 -0500 * lisp/erc/erc.el (erc-process-input-line): Undo confused last change diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 66f8828098..bb68173b6d 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -2821,9 +2821,9 @@ this function from interpreting the line as a command." (let* ((cmd (nth 0 command-list)) (args (nth 1 command-list))) (condition-case nil - (if (functionp args) - (funcall cmd args) - (apply cmd args)) + (if (listp args) + (apply cmd args) + (funcall cmd args)) (wrong-number-of-arguments (erc-display-message nil 'error (current-buffer) 'incorrect-args ?c (erc-command-name cmd) commit 1e776d7d6a5672de15b2ee9c75f5637ca1756280 Author: Dmitry Gutov Date: Mon Jan 4 21:13:33 2021 +0200 ruby-add-log-current-method: Support methods with symbolic names * lisp/progmodes/ruby-mode.el (ruby-add-log-current-method): Support methods with symbolic names. diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 3effb6ed66..cd9d087856 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -1598,13 +1598,16 @@ See `add-log-current-defun-function'." (let* ((indent 0) mname mlist (start (point)) (make-definition-re - (lambda (re) + (lambda (re &optional method-name?) (concat "^[ \t]*" re "[ \t]+" "\\(" ;; \\. and :: for class methods - "\\([A-Za-z_]" ruby-symbol-re "*[?!]?\\|\\.\\|::" "\\)" + "\\([A-Za-z_]" ruby-symbol-re "*[?!]?" + (when method-name? "\\|") + (when method-name? ruby-operator-re) + "\\|\\.\\|::" "\\)" "+\\)"))) - (definition-re (funcall make-definition-re ruby-defun-beg-re)) + (definition-re (funcall make-definition-re ruby-defun-beg-re t)) (module-re (funcall make-definition-re "\\(class\\|module\\)"))) ;; Get the current method definition (or class/module). (when (re-search-backward definition-re nil t) diff --git a/test/lisp/progmodes/ruby-mode-tests.el b/test/lisp/progmodes/ruby-mode-tests.el index 67b592e907..42a011c8bc 100644 --- a/test/lisp/progmodes/ruby-mode-tests.el +++ b/test/lisp/progmodes/ruby-mode-tests.el @@ -497,7 +497,8 @@ VALUES-PLIST is a list with alternating index and value elements." (ert-deftest ruby-add-log-current-method-examples () (let ((pairs '(("foo" . "#foo") ("C.foo" . ".foo") - ("self.foo" . ".foo")))) + ("self.foo" . ".foo") + ("<<" . "#<<")))) (dolist (pair pairs) (let ((name (car pair)) (value (cdr pair))) commit 97226aacfde717ec48fa8931c870497e089da17b Author: Paul Eggert Date: Mon Jan 4 10:33:43 2021 -0800 Do not assume Xrender merely because Cairo Problem reported by Andrea Corallo in: https://lists.gnu.org/r/emacs-devel/2021-01/msg00225.html * src/xterm.c (x_term_init) [USE_CAIRO && !HAVE_XRENDER]: Do not call XRenderQueryExtension. diff --git a/src/xterm.c b/src/xterm.c index 0a86738cc2..b8374fed8b 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -13035,13 +13035,13 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) or larger than other for other applications, even if it is the same font name (monospace-10 for example). */ +# ifdef HAVE_XRENDER int event_base, error_base; - char *v; - double d; - XRenderQueryExtension (dpyinfo->display, &event_base, &error_base); +# endif - v = XGetDefault (dpyinfo->display, "Xft", "dpi"); + char *v = XGetDefault (dpyinfo->display, "Xft", "dpi"); + double d; if (v != NULL && sscanf (v, "%lf", &d) == 1) dpyinfo->resy = dpyinfo->resx = d; } commit fa574e68dec8255e211fbca95e187083ec6eabb4 Author: Paul Eggert Date: Sun Jan 3 11:19:48 2021 -0800 Fix broken build on AIX 7.2 Without this fix, the build on AIX 7.2 with xlc fails in the ‘CCLD temacs’ step with the diagnostic ‘ld: 0711-317 ERROR: Undefined symbol: BC’. This is because -lcurses does not define BC etc. * configure.ac: When building terminfo.o, define TERMINFO_DEFINES_BC if the library defines BC etc. * src/terminfo.c (UP, BC, PC): Define depending on TERMINFO_DEFINES_BC, not on TERMINFO. (cherry picked from commit 632917461a7c1893a83979a3873b51d4da3b8a42) diff --git a/configure.ac b/configure.ac index bcc0be7de0..66c660696b 100644 --- a/configure.ac +++ b/configure.ac @@ -4393,6 +4393,18 @@ TERMCAP_OBJ=tparam.o if test $TERMINFO = yes; then AC_DEFINE(TERMINFO, 1, [Define to 1 if you use terminfo instead of termcap.]) TERMCAP_OBJ=terminfo.o + AC_CACHE_CHECK([whether $LIBS_TERMCAP library defines BC], + [emacs_cv_terminfo_defines_BC], + [OLD_LIBS=$LIBS + LIBS="$LIBS $LIBS_TERMCAP" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern char *BC;]], [[return !*BC;]])], + [emacs_cv_terminfo_defines_BC=yes], + [emacs_cv_terminfo_defines_BC=no]) + LIBS=$OLD_LIBS]) + if test "$emacs_cv_terminfo_defines_BC" = yes; then + AC_DEFINE([TERMINFO_DEFINES_BC], 1, [Define to 1 if the + terminfo library defines the variables BC, PC, and UP.]) + fi fi if test "X$LIBS_TERMCAP" = "X-lncurses"; then AC_DEFINE(USE_NCURSES, 1, [Define to 1 if you use ncurses.]) diff --git a/src/terminfo.c b/src/terminfo.c index 15aff317f1..a9c9572bbb 100644 --- a/src/terminfo.c +++ b/src/terminfo.c @@ -23,10 +23,10 @@ along with GNU Emacs. If not, see . */ /* Define these variables that serve as global parameters to termcap, so that we do not need to conditionalize the places in Emacs - that set them. But don't do that for terminfo, as that could - cause link errors when using -fno-common. */ + that set them. But don't do that if terminfo defines them, as that + could cause link errors when using -fno-common. */ -#if !TERMINFO +#ifndef TERMINFO_DEFINES_BC char *UP, *BC, PC; #endif commit 03080b554523732b5d53db62866e70bf090031e3 Author: Simen Heggestøyl Date: Mon Jan 4 14:04:04 2021 +0100 Remove extraneous closing paren * doc/lispref/modes.texi (SMIE Indentation Example): Remove extraneous closing paren. diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 27ca5441f4..72740868a6 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -4165,7 +4165,7 @@ Here is an example of an indentation function: (`(,_ . ",") (smie-rule-separator kind)) (`(:after . ":=") sample-indent-basic) (`(:before . ,(or `"begin" `"(" `"@{"))) - (if (smie-rule-hanging-p) (smie-rule-parent))) + (if (smie-rule-hanging-p) (smie-rule-parent)) (`(:before . "if") (and (not (smie-rule-bolp)) (smie-rule-prev-p "else") (smie-rule-parent))))) commit 2c847902522ae74c9b25b2a3fa60565e0187fd0a Merge: b90f3c5cae 99cc0045eb Author: Glenn Morris Date: Mon Jan 4 07:50:26 2021 -0800 Merge from origin/emacs-27 99cc0045eb (origin/emacs-27) Update two user option names in the Widg... commit b90f3c5cae7b27c06a017611e220178573bee122 Merge: 1395fb8ff7 32c960bdc6 Author: Glenn Morris Date: Mon Jan 4 07:50:26 2021 -0800 ; Merge from origin/emacs-27 The following commit was skipped: 32c960bdc6 Mention -lcurses problem on AIX commit 1395fb8ff7c7e55bc7f5d3c901cb45bd0b3c7c8f Merge: e8bf7258ae 2e09efdb68 Author: Glenn Morris Date: Mon Jan 4 07:50:25 2021 -0800 Merge from origin/emacs-27 2e09efdb68 Revert previous patch which was installed into wrong branch. commit e8bf7258ae4ef2bfe2c4e09cb00516dd4ccbe214 Merge: 49137d3278 585997d05a Author: Glenn Morris Date: Mon Jan 4 07:50:25 2021 -0800 ; Merge from origin/emacs-27 The following commit was skipped: 585997d05a Fix broken build on AIX 7.2 commit 49137d3278ab9632e24b3f97bbfad26bdccfdfd0 Merge: 33108bc477 a7c2793efe Author: Glenn Morris Date: Mon Jan 4 07:50:25 2021 -0800 Merge from origin/emacs-27 a7c2793efe Fix last change commit 33108bc4775068289cf4f37d993094e21ddc5dd0 Merge: ba2f2f9378 ec1e1f80e6 Author: Glenn Morris Date: Mon Jan 4 07:50:25 2021 -0800 ; Merge from origin/emacs-27 The following commit was skipped: ec1e1f80e6 Add a reference between the Strings node and Search/Replace commit ba2f2f9378a7983edd337e99bb4306b39d7246f9 Merge: 82c6f43653 90c782e92e Author: Glenn Morris Date: Mon Jan 4 07:50:25 2021 -0800 Merge from origin/emacs-27 90c782e92e Merge branch 'emacs-27' of git.savannah.gnu.org:/srv/git/e... commit 82c6f4365392b252ca603027bc9a27ec0561a254 Merge: 6f0bb2fe58 f0deca159d Author: Glenn Morris Date: Mon Jan 4 07:50:25 2021 -0800 ; Merge from origin/emacs-27 The following commit was skipped: f0deca159d (emacs-27) ; Auto-commit of loaddefs files. commit 6f0bb2fe589e6b42666640d290e2e82ac24c8583 Merge: dadffdd81f 7384ec6416 Author: Glenn Morris Date: Mon Jan 4 07:50:22 2021 -0800 Merge from origin/emacs-27 7384ec6416 Add warning comments abound binding keys in Isearch maps commit dadffdd81fdc958e212f64277a5733b79a80dc57 Merge: f5a1315f1e 3711339f92 Author: Glenn Morris Date: Mon Jan 4 07:50:22 2021 -0800 ; Merge from origin/emacs-27 The following commit was skipped: 3711339f92 Fix crash in ns_mouse_position (bug#45541) commit f5a1315f1ea035f30d1161e4af200acafdfebe01 Author: Michael Albinus Date: Mon Jan 4 16:32:32 2021 +0100 Fix error in tramp-sh-handle-insert-directory * lisp/net/tramp-sh.el (tramp-sh-handle-insert-directory): Let buffer be unibyte when applying numbers returned with the ls --dired option. Reported by Justus Piater . * test/lisp/net/tramp-tests.el (tramp--test-check-files): Extend test. diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 865ea4e92a..b43b4485fe 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -2672,7 +2672,8 @@ The method used must be an out-of-band method." (tramp-get-remote-null-device v)))) (save-restriction - (let ((beg (point))) + (let ((beg (point)) + (emc enable-multibyte-characters)) (narrow-to-region (point) (point)) ;; We cannot use `insert-buffer-substring' because the Tramp ;; buffer changes its contents before insertion due to calling @@ -2681,7 +2682,9 @@ The method used must be an out-of-band method." (with-current-buffer (tramp-get-buffer v) (buffer-string))) - ;; Check for "--dired" output. + ;; Check for "--dired" output. We must enable unibyte + ;; strings, because the "--dired" output counts in bytes. + (set-buffer-multibyte nil) (forward-line -2) (when (looking-at-p "//SUBDIRED//") (forward-line -1)) @@ -2701,6 +2704,8 @@ The method used must be an out-of-band method." (while (looking-at "//") (forward-line 1) (delete-region (match-beginning 0) (point))) + ;; Reset multibyte if needed. + (set-buffer-multibyte emc) ;; Some busyboxes are reluctant to discard colors. (unless diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 896b9978e7..819d69b600 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -5787,7 +5787,8 @@ This requires restrictions of file name syntax." (tmp-name2 (tramp--test-make-temp-name 'local quoted)) (files (delq nil files)) (process-environment process-environment) - (sorted-files (sort (copy-sequence files) #'string-lessp))) + (sorted-files (sort (copy-sequence files) #'string-lessp)) + buffer) (unwind-protect (progn (make-directory tmp-name1) @@ -5849,6 +5850,18 @@ This requires restrictions of file name syntax." tmp-name2 nil directory-files-no-dot-files-regexp)) sorted-files)) + ;; Check, that `insert-directory' works properly. + (with-current-buffer + (setq buffer (dired-noselect tmp-name1 "--dired -al")) + (goto-char (point-min)) + (while (not (eobp)) + (when-let ((name (dired-get-filename 'localp 'no-error))) + (unless + (string-match-p name directory-files-no-dot-files-regexp) + (should (member name files)))) + (forward-line 1))) + (kill-buffer buffer) + ;; `substitute-in-file-name' could return different ;; values. For `adb', there could be strange file ;; permissions preventing overwriting a file. We don't @@ -5944,6 +5957,7 @@ This requires restrictions of file name syntax." (regexp-quote (getenv envvar)))))))))) ;; Cleanup. + (ignore-errors (kill-buffer buffer)) (ignore-errors (delete-directory tmp-name1 'recursive)) (ignore-errors (delete-directory tmp-name2 'recursive)))))) commit 99cc0045ebd45ade32c0b42fe807d87a52458542 Author: Mauro Aranda Date: Mon Jan 4 09:58:10 2021 -0300 Update two user option names in the Widget manual * doc/misc/widget.texi (Basic Types): The user options widget-glyph-directory and widget-glyph-enable were renamed long ago to widget-image-directory and widget-image-enable, but the manual kept calling them by their old names. Update the names. diff --git a/doc/misc/widget.texi b/doc/misc/widget.texi index 6f0b63e5bf..64cbf8d950 100644 --- a/doc/misc/widget.texi +++ b/doc/misc/widget.texi @@ -692,14 +692,14 @@ arguments, which will be used when creating the @code{radio-button} or @end table -@deffn {User Option} widget-glyph-directory -Directory where glyphs are found. +@deffn {User Option} widget-image-directory +Directory where Widget should look for images. Widget will look here for a file with the same name as specified for the image, with either a @file{.xpm} (if supported) or @file{.xbm} extension. @end deffn -@deffn{User Option} widget-glyph-enable -If non-@code{nil}, allow glyphs to appear on displays where they are supported. +@deffn{User Option} widget-image-enable +If non-@code{nil}, allow images to appear on displays where they are supported. @end deffn commit 56556b5f4d73d9c3683fa7573e6bd89f2ef37902 Author: Basil L. Contovounesios Date: Mon Jan 4 13:09:40 2021 +0000 Fix build for --enable-checking=structs The last change to lisp.h only added comments in Lisp_String, so the portable dumper need not be changed. * src/pdumper.c (dump_string): Update hash for Lisp_String. diff --git a/src/pdumper.c b/src/pdumper.c index 6956ee3682..116cc28dbb 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2058,7 +2058,7 @@ dump_interval_tree (struct dump_context *ctx, static dump_off dump_string (struct dump_context *ctx, const struct Lisp_String *string) { -#if CHECK_STRUCTS && !defined (HASH_Lisp_String_86FEA6EC7C) +#if CHECK_STRUCTS && !defined (HASH_Lisp_String_348C2B2FDB) # error "Lisp_String changed. See CHECK_STRUCTS comment in config.h." #endif /* If we have text properties, write them _after_ the string so that commit 4e80eb7b7ce76e02fa0b2b0fa66223f29e3f6bcd Author: Mauro Aranda Date: Mon Jan 4 10:02:20 2021 -0300 Don't skip widgets when moving backward * lisp/wid-edit.el (widget-move): Remove code that caused widget-backward to skip an immediate previous widget when moving backward from the start of a widget. (Bug#45623) * test/lisp/wid-edit-tests.el (widget-test-widget-backward): New test. diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index f920130226..8b10d71dcb 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el @@ -1204,7 +1204,6 @@ This is much faster.") ARG may be negative to move backward. When the second optional argument is non-nil, nothing is shown in the echo area." - (or (bobp) (> arg 0) (backward-char)) (let ((wrapped 0) (number arg) (old (widget-tabable-at))) diff --git a/test/lisp/wid-edit-tests.el b/test/lisp/wid-edit-tests.el index 35235c6566..17fdfefce8 100644 --- a/test/lisp/wid-edit-tests.el +++ b/test/lisp/wid-edit-tests.el @@ -301,4 +301,25 @@ return nil, even with a non-nil bubblep argument." (should child) (should (equal (widget-value widget) '((1 "One"))))))) +(ert-deftest widget-test-widget-move () + "Test moving with `widget-forward' and `widget-backward'." + (with-temp-buffer + (dolist (el '("First" "Second" "Third")) + (widget-create 'push-button el)) + (widget-insert "\n") + (use-local-map widget-keymap) + (widget-setup) + (goto-char (point-min)) + ;; Check that moving from the widget's start works. + (widget-forward 2) + (should (string= "Third" (widget-value (widget-at)))) + (widget-backward 1) + (should (string= "Second" (widget-value (widget-at)))) + ;; Check that moving from inside the widget works. + (goto-char (point-min)) + (widget-forward 2) + (forward-char) + (widget-backward 1) + (should (string= "Second" (widget-value (widget-at)))))) + ;;; wid-edit-tests.el ends here commit 65f21729e60f831026ce134b87561c5119b6a926 Author: Amin Bandali Date: Mon Jan 4 10:48:08 2021 +0100 Fix off-by-one error in mode-line-compact code * src/xdisp.c (display_mode_line): Fix off-by-one error that would chop off the final non-space character when compacting (bug#45646). diff --git a/src/xdisp.c b/src/xdisp.c index 43447e2bf7..6a4304d194 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -25504,7 +25504,7 @@ display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format) if (start < i) display_string (NULL, Fsubstring (mode_string, make_fixnum (start), - make_fixnum (i - 1)), + make_fixnum (i)), Qnil, 0, 0, &it, 0, 0, 0, STRING_MULTIBYTE (mode_string)); } commit b2f81b7bab92109af02ec5fc2d2b721c70b97f40 Author: Lars Ingebrigtsen Date: Mon Jan 4 10:42:13 2021 +0100 Fix computation of Lines in nnmaildir * lisp/gnus/nnmaildir.el (nnmaildir--update-nov): Lines is -1 if it's not present; not 0 (probably) (bug#45650). diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el index 68c31dc451..e4fd976742 100644 --- a/lisp/gnus/nnmaildir.el +++ b/lisp/gnus/nnmaildir.el @@ -494,7 +494,7 @@ This variable is set by `nnmaildir-request-article'.") (delete-char 1) (setq nov (nnheader-parse-head t) field (or (mail-header-lines nov) 0))) - (unless (or (zerop field) (nnmaildir--param pgname 'distrust-Lines:)) + (unless (or (<= field 0) (nnmaildir--param pgname 'distrust-Lines:)) (setq nov-mid field)) (setq nov-mid (number-to-string nov-mid) nov-mid (concat (number-to-string attr) "\t" nov-mid)) commit 90951f847c04d288121d5cb3b2e03639f060125c Author: Stefan Monnier Date: Mon Jan 4 01:00:33 2021 -0500 * src/print.c (print_vectorlike): Use `HASH_TABLE_SIZE` diff --git a/src/lisp.h b/src/lisp.h index 0ad788cff8..5cc735be86 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1478,8 +1478,8 @@ struct Lisp_String { struct { - ptrdiff_t size; - ptrdiff_t size_byte; + ptrdiff_t size; /* MSB is used as the markbit. */ + ptrdiff_t size_byte; /* Set to -1 for unibyte strings. */ INTERVAL intervals; /* Text properties in this string. */ unsigned char *data; } s; diff --git a/src/print.c b/src/print.c index 94a8bcbf88..14af919547 100644 --- a/src/print.c +++ b/src/print.c @@ -1557,7 +1557,8 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag, /* Implement a readable output, e.g.: #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */ /* Always print the size. */ - int len = sprintf (buf, "#s(hash-table size %"pD"d", ASIZE (h->next)); + int len = sprintf (buf, "#s(hash-table size %"pD"d", + HASH_TABLE_SIZE (h)); strout (buf, len, len, printcharfun); if (!NILP (h->test.name)) commit b2f8c9f96fbda53387b9f910d3b97aefefab6cab Author: Stefan Monnier Date: Mon Jan 4 00:59:56 2021 -0500 * src/xdisp.c (syms_of_xdisp): New var redisplay-skip-fontification-on-input (handle_fontified_prop): Use it. * src/keyboard.h (input_was_pending): Declare. * src/keyboard.c (input_was_pending): Make non-static. diff --git a/etc/NEWS b/etc/NEWS index 8003175a83..d8f25ab362 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -212,6 +212,12 @@ This makes debugging Emacs Lisp scripts run in batch mode easier. To get back the old behavior, set the new variable 'backtrace-on-error-noninteractive' to a nil value. +** 'redisplay-skip-fontification-on-input' helps Emacs keep up with fast input. +This is another attempt to solve the problem of handling high key repeat rate +and other "slow scrolling" situations. It is hoped it behaves better +than 'fast-but-imprecise-scrolling' and 'jit-lock-defer-time'. +It is not enabled by default. + * Editing Changes in Emacs 28.1 diff --git a/src/keyboard.c b/src/keyboard.c index d2f0cb405f..cf15cd7357 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -285,7 +285,7 @@ bool input_pending; with the input rate, but if it can keep up just enough that there's no input_pending when we begin the command, then redisplay is not skipped which results in better feedback to the user. */ -static bool input_was_pending; +bool input_was_pending; /* Circular buffer for pre-read keyboard input. */ diff --git a/src/keyboard.h b/src/keyboard.h index 91c6f4604f..8bdffaa2bf 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -432,7 +432,7 @@ extern int parse_solitary_modifier (Lisp_Object symbol); extern Lisp_Object real_this_command; extern int quit_char; - +extern bool input_was_pending; extern unsigned int timers_run; extern bool menu_separator_name_p (const char *); diff --git a/src/xdisp.c b/src/xdisp.c index 749893baad..43447e2bf7 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -4262,6 +4262,7 @@ handle_fontified_prop (struct it *it) if (!STRINGP (it->string) && it->s == NULL && !NILP (Vfontification_functions) + && !(input_was_pending && redisplay_skip_fontification_on_input) && !NILP (Vrun_hooks) && (pos = make_fixnum (IT_CHARPOS (*it)), prop = Fget_char_property (pos, Qfontified, Qnil), @@ -35598,6 +35599,19 @@ best except in special circumstances such as running redisplay tests in batch mode. */); redisplay_skip_initial_frame = true; + DEFVAR_BOOL ("redisplay-skip-fontification-on-input", + redisplay_skip_fontification_on_input, + doc: /* Skip `fontification_functions` when there is input pending. +If non-nil and there was input pending at the beginning of the command, +the `fontification_functions` hook is not run. This usually does not +affect the display because redisplay is completely skipped anyway if input +was pending, but it can make scrolling smoother by avoiding +unnecessary fontification. +It is similar to `fast-but-imprecise-scrolling' with similar tradeoffs, +but with the advantage that it should only affect the behavior when Emacs +has trouble keeping up with the incoming input rate. */); + redisplay_skip_fontification_on_input = false; + DEFVAR_BOOL ("redisplay-adhoc-scroll-in-resize-mini-windows", redisplay_adhoc_scroll_in_resize_mini_windows, doc: /* If nil always use normal scrolling in minibuffer windows. commit 0c599ee2e2c3fcebcab023cc9d52c9a6464b391c Author: Stefan Monnier Date: Mon Jan 4 00:21:02 2021 -0500 * lisp/erc/erc.el: Use `run-hook-with-args` for `erc-pre-send-functions` (erc-process-input-line): A function can be `listp`. (erc-send-input): Use `run-hook-with-args` for `erc-pre-send-functions`. (erc-display-command): Comment out, unused. diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 1044acff8d..66f8828098 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -1046,8 +1046,8 @@ anyway." (make-obsolete-variable 'erc-send-pre-hook 'erc-pre-send-functions "27.1") (defcustom erc-pre-send-functions nil - "List of functions called to possibly alter the string that is sent. -The functions are called with one argument, a `erc-input' struct, + "Special hook run to possibly alter the string that is sent. +The functions are called with one argument, an `erc-input' struct, and should alter that struct. The struct has three slots: @@ -1056,7 +1056,7 @@ The struct has three slots: `insertp': Whether the string should be inserted into the erc buffer. `sendp': Whether the string should be sent to the irc server." :group 'erc - :type '(repeat function) + :type 'hook :version "27.1") (defvar erc-insert-this t @@ -1295,9 +1295,9 @@ Example: (define-erc-module replace nil \"This mode replaces incoming text according to `erc-replace-alist'.\" ((add-hook \\='erc-insert-modify-hook - \\='erc-replace-insert)) + #\\='erc-replace-insert)) ((remove-hook \\='erc-insert-modify-hook - \\='erc-replace-insert)))" + #\\='erc-replace-insert)))" (declare (doc-string 3)) (let* ((sn (symbol-name name)) (mode (intern (format "erc-%s-mode" (downcase sn)))) @@ -1495,7 +1495,7 @@ Defaults to the server buffer." (setq-local paragraph-start (concat "\\(" (regexp-quote (erc-prompt)) "\\)")) (setq-local completion-ignore-case t) - (add-hook 'completion-at-point-functions 'erc-complete-word-at-point nil t)) + (add-hook 'completion-at-point-functions #'erc-complete-word-at-point nil t)) ;; activation @@ -2585,7 +2585,7 @@ This function adds `erc-lurker-update-status' to most recent PRIVMSG as well as initializing the state variable storing this information." (setq erc-lurker-state (make-hash-table :test 'equal)) - (add-hook 'erc-insert-pre-hook 'erc-lurker-update-status)) + (add-hook 'erc-insert-pre-hook #'erc-lurker-update-status)) (defun erc-lurker-cleanup () "Remove all last PRIVMSG state older than `erc-lurker-threshold-time'. @@ -2694,7 +2694,7 @@ otherwise `erc-server-announced-name'. SERVER is matched against (defun erc-add-targets (scope target-list) (let ((targets (mapcar (lambda (targets) (member scope targets)) target-list))) - (cdr (apply 'append (delete nil targets))))) + (cdr (apply #'append (delete nil targets))))) (defun erc-hide-current-message-p (parsed) "Predicate indicating whether the parsed ERC response PARSED should be hidden. @@ -2821,9 +2821,9 @@ this function from interpreting the line as a command." (let* ((cmd (nth 0 command-list)) (args (nth 1 command-list))) (condition-case nil - (if (listp args) - (apply cmd args) - (funcall cmd args)) + (if (functionp args) + (funcall cmd args) + (apply cmd args)) (wrong-number-of-arguments (erc-display-message nil 'error (current-buffer) 'incorrect-args ?c (erc-command-name cmd) @@ -3038,7 +3038,7 @@ If no USER argument is specified, list the contents of `erc-ignore-list'." (erc-display-message nil 'notice (current-buffer) 'ops ?i (length ops) ?s (if (> (length ops) 1) "s" "") - ?o (mapconcat 'identity ops " ")) + ?o (mapconcat #'identity ops " ")) (erc-display-message nil 'notice (current-buffer) 'ops-none))) t) @@ -3209,7 +3209,7 @@ command." (defun erc-cmd-KICK (target &optional reason-or-nick &rest reasonwords) "Kick the user indicated in LINE from the current channel. LINE has the format: \"#CHANNEL NICK REASON\" or \"NICK REASON\"." - (let ((reasonstring (mapconcat 'identity reasonwords " "))) + (let ((reasonstring (mapconcat #'identity reasonwords " "))) (if (string= "" reasonstring) (setq reasonstring (format "Kicked by %s" (erc-current-nick)))) (if (erc-channel-p target) @@ -3744,7 +3744,7 @@ the message given by REASON." " -" (make-string (length people) ?o) " " - (mapconcat 'identity people " "))) + (mapconcat #'identity people " "))) t)) (defun erc-cmd-OP (&rest people) @@ -3754,7 +3754,7 @@ the message given by REASON." " +" (make-string (length people) ?o) " " - (mapconcat 'identity people " "))) + (mapconcat #'identity people " "))) t)) (defun erc-cmd-TIME (&optional line) @@ -3952,7 +3952,7 @@ Unban all currently banned users in the current channel." (erc-server-send (format "MODE %s -%s %s" (erc-default-target) (make-string (length x) ?b) - (mapconcat 'identity x " ")))) + (mapconcat #'identity x " ")))) (erc-group-list bans 3)))) t)))) @@ -4183,7 +4183,7 @@ Displays PROC and PARSED appropriately using `erc-display-message'." (erc-display-message parsed 'notice proc (mapconcat - 'identity + #'identity (let (res) (mapc #'(lambda (x) (if (stringp x) @@ -5553,12 +5553,10 @@ This returns non-nil only if we actually send anything." ;; Instead `erc-pre-send-functions' is used as a filter to do ;; allow both changing and suppressing the string. (run-hook-with-args 'erc-send-pre-hook input) - (setq state (make-erc-input :string str + (setq state (make-erc-input :string str ;May be != from `input' now! :insertp erc-insert-this :sendp erc-send-this)) - (dolist (func erc-pre-send-functions) - ;; The functions can return nil to inhibit sending. - (funcall func state)) + (run-hook-with-args 'erc-pre-send-functions state) (when (and (erc-input-sendp state) erc-send-this) (let ((string (erc-input-string state))) @@ -5579,26 +5577,26 @@ This returns non-nil only if we actually send anything." (erc-process-input-line (concat string "\n") t nil)) t)))))) -(defun erc-display-command (line) - (when erc-insert-this - (let ((insert-position (point))) - (unless erc-hide-prompt - (erc-display-prompt nil nil (erc-command-indicator) - (and (erc-command-indicator) - 'erc-command-indicator-face))) - (let ((beg (point))) - (insert line) - (erc-put-text-property beg (point) - 'font-lock-face 'erc-command-indicator-face) - (insert "\n")) - (when (processp erc-server-process) - (set-marker (process-mark erc-server-process) (point))) - (set-marker erc-insert-marker (point)) - (save-excursion - (save-restriction - (narrow-to-region insert-position (point)) - (run-hooks 'erc-send-modify-hook) - (run-hooks 'erc-send-post-hook)))))) +;; (defun erc-display-command (line) +;; (when erc-insert-this +;; (let ((insert-position (point))) +;; (unless erc-hide-prompt +;; (erc-display-prompt nil nil (erc-command-indicator) +;; (and (erc-command-indicator) +;; 'erc-command-indicator-face))) +;; (let ((beg (point))) +;; (insert line) +;; (erc-put-text-property beg (point) +;; 'font-lock-face 'erc-command-indicator-face) +;; (insert "\n")) +;; (when (processp erc-server-process) +;; (set-marker (process-mark erc-server-process) (point))) +;; (set-marker erc-insert-marker (point)) +;; (save-excursion +;; (save-restriction +;; (narrow-to-region insert-position (point)) +;; (run-hooks 'erc-send-modify-hook) +;; (run-hooks 'erc-send-post-hook)))))) (defun erc-display-msg (line) "Display LINE as a message of the user to the current target at the @@ -6563,7 +6561,7 @@ If optional argument HERE is non-nil, insert version number at point." If optional argument HERE is non-nil, insert version number at point." (interactive "P") (let ((string - (mapconcat 'identity + (mapconcat #'identity (let (modes (case-fold-search nil)) (dolist (var (apropos-internal "^erc-.*mode$")) (when (and (boundp var) @@ -6817,7 +6815,8 @@ See also `format-spec'." ;;; Various hook functions -(add-hook 'kill-buffer-hook 'erc-kill-buffer-function) +;; FIXME: Don't set the hook globally! +(add-hook 'kill-buffer-hook #'erc-kill-buffer-function) (defcustom erc-kill-server-hook '(erc-kill-server) "Invoked whenever a server buffer is killed via `kill-buffer'." commit 535a25164b5d656874b06fcc3a81f1bbd39b442a Author: Stefan Monnier Date: Mon Jan 4 00:01:58 2021 -0500 * lisp/calc/calc-yank.el (calc-edit-mode): Make it into a proper major mode Also make `calc-edit-handler` hold a function instead of an expression. (calc-original-buffer, calc-return-buffer, calc-one-window) (calc-edit-handler, calc-restore-trail, calc-allow-ret) (calc-edit-top): Give them a default value. (calc--edit-mode): New function extracted from old `calc-edit-mode`. (calc-edit-return, calc-edit-finish): Don't need to test `boundp` any more. (calc-edit-finish): Allow `calc-edit-handler` to be a function. (calc-edit, calc-alg-edit): * lisp/calc/calc-prog.el (calc-edit-user-syntax, calc-user-define-edit): * lisp/calc/calc-embed.el (calc-embedded-edit): * lisp/calc/calc-sel.el (calc-edit-selection): * lisp/calc/calc-store.el (calc-edit-variable): Use `calc--edit-mode` and make first arg into a function. * lisp/calc/calc-ext.el (calc-init-extensions): Autoload `calc--edit-mode` instead of `calc-edit-mode`. diff --git a/lisp/calc/calc-embed.el b/lisp/calc/calc-embed.el index a113572610..ea79bfa69a 100644 --- a/lisp/calc/calc-embed.el +++ b/lisp/calc/calc-embed.el @@ -396,7 +396,7 @@ (calc-wrapper (setq str (math-showing-full-precision (math-format-nice-expr (aref info 8) (frame-width)))) - (calc-edit-mode (list 'calc-embedded-finish-edit info)) + (calc--edit-mode (lambda () (calc-embedded-finish-edit info))) (insert str "\n"))) (calc-show-edit-buffer))) diff --git a/lisp/calc/calc-ext.el b/lisp/calc/calc-ext.el index 7c319c4d65..f4ddb840b5 100644 --- a/lisp/calc/calc-ext.el +++ b/lisp/calc/calc-ext.el @@ -1195,7 +1195,7 @@ calc-set-xor calc-sort calc-subvector calc-tail calc-transpose calc-unpack calc-unpack-bits calc-vector-find calc-vlength) ("calc-yank" calc-copy-as-kill calc-copy-region-as-kill -calc-copy-to-buffer calc-edit calc-edit-cancel calc-edit-mode +calc-copy-to-buffer calc-edit calc-edit-cancel calc--edit-mode calc-kill calc-kill-region calc-yank)))) (defun calc-init-prefixes () diff --git a/lisp/calc/calc-prog.el b/lisp/calc/calc-prog.el index 6ac554ed69..3097b09b01 100644 --- a/lisp/calc/calc-prog.el +++ b/lisp/calc/calc-prog.el @@ -483,13 +483,13 @@ (interactive) (calc-wrapper (let ((lang calc-language)) - (calc-edit-mode (list 'calc-finish-user-syntax-edit (list 'quote lang)) - t - (format "Editing %s-Mode Syntax Table. " - (cond ((null lang) "Normal") - ((eq lang 'tex) "TeX") - ((eq lang 'latex) "LaTeX") - (t (capitalize (symbol-name lang)))))) + (calc--edit-mode (lambda () (calc-finish-user-syntax-edit lang)) + t + (format "Editing %s-Mode Syntax Table. " + (cond ((null lang) "Normal") + ((eq lang 'tex) "TeX") + ((eq lang 'latex) "LaTeX") + (t (capitalize (symbol-name lang)))))) (calc-write-parse-table (cdr (assq lang calc-user-parse-tables)) lang))) (calc-show-edit-buffer)) @@ -696,12 +696,13 @@ (setq cmd (symbol-function cmd))) (cond ((or (stringp cmd) (and (consp cmd) - (eq (car-safe (nth 3 cmd)) 'calc-execute-kbd-macro))) + (eq (car-safe (nth 3 cmd)) #'calc-execute-kbd-macro))) + ;; FIXME: Won't (nth 3 cmd) fail when (stringp cmd)? (let* ((mac (elt (nth 1 (nth 3 cmd)) 1)) (str (edmacro-format-keys mac t)) (kys (nth 3 (nth 3 cmd)))) - (calc-edit-mode - (list 'calc-edit-macro-finish-edit cmdname kys) + (calc--edit-mode + (lambda () (calc-edit-macro-finish-edit cmdname kys)) t (format (concat "Editing keyboard macro (%s, bound to %s).\n" "Original keys: %s \n") @@ -719,8 +720,8 @@ (if (and defn (calc-valid-formula-func func)) (let ((niceexpr (math-format-nice-expr defn (frame-width)))) (calc-wrapper - (calc-edit-mode - (list 'calc-finish-formula-edit (list 'quote func)) + (calc--edit-mode + (lambda () (calc-finish-formula-edit func)) nil (format (concat "Editing formula (%s, %s, bound to %s).\n" diff --git a/lisp/calc/calc-sel.el b/lisp/calc/calc-sel.el index e6c6337f96..2b317ac369 100644 --- a/lisp/calc/calc-sel.el +++ b/lisp/calc/calc-sel.el @@ -675,12 +675,12 @@ (entry (calc-top num 'entry)) (expr (car entry)) (sel (or (calc-auto-selection entry) expr)) - ) ;; alg - (let ((str (math-showing-full-precision - (math-format-nice-expr sel (frame-width))))) - (calc-edit-mode (list 'calc-finish-selection-edit - num (list 'quote sel) calc-sel-reselect)) - (insert str "\n")))) + ;; alg + (str (math-showing-full-precision + (math-format-nice-expr sel (frame-width)))) + (csr calc-sel-reselect)) + (calc--edit-mode (lambda () (calc-finish-selection-edit num sel csr))) + (insert str "\n"))) (calc-show-edit-buffer)) (defvar calc-original-buffer) diff --git a/lisp/calc/calc-store.el b/lisp/calc/calc-store.el index a5e9012dec..ee29c440fe 100644 --- a/lisp/calc/calc-store.el +++ b/lisp/calc/calc-store.el @@ -437,10 +437,10 @@ (if (eq (car-safe value) 'special-const) (error "%s is a special constant" var)) (setq calc-last-edited-variable var) - (calc-edit-mode (list 'calc-finish-stack-edit (list 'quote var)) - t - (format-message - "Editing variable `%s'" (calc-var-name var))) + (calc--edit-mode (lambda () (calc-finish-stack-edit var)) + t + (format-message + "Editing variable `%s'" (calc-var-name var))) (and value (insert (math-format-nice-expr value (frame-width)) "\n"))))) (calc-show-edit-buffer)) diff --git a/lisp/calc/calc-yank.el b/lisp/calc/calc-yank.el index 8267340a3e..e5f05236f3 100644 --- a/lisp/calc/calc-yank.el +++ b/lisp/calc/calc-yank.el @@ -651,14 +651,14 @@ Interactively, reads the register using `register-read-with-preview'." (if (> n 0) (calc-top-list n) (calc-top-list 1 (- n))))))) - (calc-edit-mode (list 'calc-finish-stack-edit (or flag n)) allow-ret) + (calc--edit-mode (lambda () (calc-finish-stack-edit (or flag n))) allow-ret) (while list (insert (car list) "\n") (setq list (cdr list))))) (calc-show-edit-buffer)) (defun calc-alg-edit (str) - (calc-edit-mode '(calc-finish-stack-edit 0)) + (calc--edit-mode (lambda () (calc-finish-stack-edit 0))) (calc-show-edit-buffer) (insert str "\n") (backward-char 1) @@ -666,54 +666,47 @@ Interactively, reads the register using `register-read-with-preview'." (defvar calc-edit-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\n" 'calc-edit-finish) - (define-key map "\r" 'calc-edit-return) - (define-key map "\C-c\C-c" 'calc-edit-finish) + (define-key map "\n" #'calc-edit-finish) + (define-key map "\r" #'calc-edit-return) + (define-key map "\C-c\C-c" #'calc-edit-finish) map) - "Keymap for use by the calc-edit command.") + "Keymap for use by the `calc-edit' command.") -(defvar calc-original-buffer) -(defvar calc-return-buffer) -(defvar calc-one-window) -(defvar calc-edit-handler) -(defvar calc-restore-trail) -(defvar calc-allow-ret) -(defvar calc-edit-top) +(defvar calc-original-buffer nil) +(defvar calc-return-buffer nil) +(defvar calc-one-window nil) +(defvar calc-edit-handler nil) +(defvar calc-restore-trail nil) +(defvar calc-allow-ret nil) +(defvar calc-edit-top nil) -(defun calc-edit-mode (&optional handler allow-ret title) +(put 'calc-edit-mode 'mode-class 'special) +(define-derived-mode calc-edit-mode nil "Calc Edit" "Calculator editing mode. Press RET, LFD, or C-c C-c to finish. To cancel the edit, simply kill the *Calc Edit* buffer." - (interactive) + (setq-local buffer-read-only nil) + (setq-local truncate-lines nil)) + +(defun calc--edit-mode (handler &optional allow-ret title) (unless handler (error "This command can be used only indirectly through calc-edit")) (let ((oldbuf (current-buffer)) (buf (get-buffer-create "*Calc Edit*"))) (set-buffer buf) - (kill-all-local-variables) - (use-local-map calc-edit-mode-map) - (setq buffer-read-only nil) - (setq truncate-lines nil) - (setq major-mode 'calc-edit-mode) - (setq mode-name "Calc Edit") - (run-mode-hooks 'calc-edit-mode-hook) - (make-local-variable 'calc-original-buffer) - (setq calc-original-buffer oldbuf) - (make-local-variable 'calc-return-buffer) - (setq calc-return-buffer oldbuf) - (make-local-variable 'calc-one-window) - (setq calc-one-window (and (one-window-p t) pop-up-windows)) - (make-local-variable 'calc-edit-handler) - (setq calc-edit-handler handler) - (make-local-variable 'calc-restore-trail) - (setq calc-restore-trail (get-buffer-window (calc-trail-buffer))) - (make-local-variable 'calc-allow-ret) - (setq calc-allow-ret allow-ret) + (calc-edit-mode) + (setq-local calc-original-buffer oldbuf) + (setq-local calc-return-buffer oldbuf) + (setq-local calc-one-window (and (one-window-p t) pop-up-windows)) + (setq-local calc-edit-handler handler) + (setq-local calc-restore-trail (get-buffer-window (calc-trail-buffer))) + (setq-local calc-allow-ret allow-ret) (let ((inhibit-read-only t)) (erase-buffer)) (add-hook 'kill-buffer-hook (lambda () (let ((calc-edit-handler nil)) (calc-edit-finish t)) - (message "(Canceled)")) t t) + (message "(Canceled)")) + t t) (insert (propertize (concat (or title title "Calc Edit Mode. ") @@ -721,9 +714,7 @@ To cancel the edit, simply kill the *Calc Edit* buffer." (if allow-ret "" " or RET") (format-message " to finish, `C-x k RET' to cancel.\n\n")) 'font-lock-face 'italic 'read-only t 'rear-nonsticky t 'front-sticky t)) - (make-local-variable 'calc-edit-top) - (setq calc-edit-top (point)))) -(put 'calc-edit-mode 'mode-class 'special) + (setq-local calc-edit-top (point)))) (defun calc-show-edit-buffer () (let ((buf (current-buffer))) @@ -743,24 +734,19 @@ To cancel the edit, simply kill the *Calc Edit* buffer." (defun calc-edit-return () (interactive) - (if (and (boundp 'calc-allow-ret) calc-allow-ret) + (if calc-allow-ret (newline) (calc-edit-finish))) -;; The variable calc-edit-disp-trail is local to calc-edit finish, but -;; is used by calc-finish-selection-edit and calc-finish-stack-edit. +;; The variable `calc-edit-disp-trail' is local to `calc-edit-finish', but +;; is used by `calc-finish-selection-edit' and `calc-finish-stack-edit'. (defvar calc-edit-disp-trail) (defun calc-edit-finish (&optional keep) - "Finish calc-edit mode. Parse buffer contents and push them on the stack." + "Finish `calc-edit' mode. Parse buffer contents and push them on the stack." (interactive "P") (message "Working...") - (or (and (boundp 'calc-original-buffer) - (boundp 'calc-return-buffer) - (boundp 'calc-one-window) - (boundp 'calc-edit-handler) - (boundp 'calc-restore-trail) - (eq major-mode 'calc-edit-mode)) + (or (derived-mode-p 'calc-edit-mode) (error "This command is valid only in buffers created by calc-edit")) (let ((buf (current-buffer)) (original calc-original-buffer) @@ -775,7 +761,11 @@ To cancel the edit, simply kill the *Calc Edit* buffer." (error "Original calculator buffer has been corrupted"))) (goto-char calc-edit-top) (if (buffer-modified-p) - (eval calc-edit-handler t)) + (if (functionp calc-edit-handler) + (funcall calc-edit-handler) + (message "Deprecated handler expression in calc-edit-handler: %S" + calc-edit-handler) + (eval calc-edit-handler t))) (if (and one-window (not (one-window-p t))) (delete-window)) (if (get-buffer-window return) commit d8d223e7ef1d5ad2768662d114767f35601a0e87 Author: Stefan Monnier Date: Sun Jan 3 23:15:33 2021 -0500 * Makefile.in (test/%): New target diff --git a/Makefile.in b/Makefile.in index f963351ba0..2068362299 100644 --- a/Makefile.in +++ b/Makefile.in @@ -969,6 +969,10 @@ else @echo "Maybe you used a release tarfile that lacks tests." endif +test/%: + $(MAKE) -C test $* + + dist: cd ${srcdir}; ./make-dist commit 587a97bcb23bc6ea429ab790efa03f2260a9bca8 Author: Stefan Monnier Date: Sun Jan 3 23:14:18 2021 -0500 * lisp/calendar/appt.el (appt-activate): Set the local `write-file-functions` diff --git a/lisp/calendar/appt.el b/lisp/calendar/appt.el index 29bcd6de2c..281b89e088 100644 --- a/lisp/calendar/appt.el +++ b/lisp/calendar/appt.el @@ -700,7 +700,7 @@ ARG is positive, otherwise off." (let ((appt-active appt-timer)) (setq appt-active (if arg (> (prefix-numeric-value arg) 0) (not appt-active))) - (remove-hook 'write-file-functions #'appt-update-list) + (remove-hook 'write-file-functions #'appt-update-list 'local) (or global-mode-string (setq global-mode-string '(""))) (delq 'appt-mode-string global-mode-string) (when appt-timer @@ -708,7 +708,7 @@ ARG is positive, otherwise off." (setq appt-timer nil)) (if appt-active (progn - (add-hook 'write-file-functions #'appt-update-list) + (add-hook 'write-file-functions #'appt-update-list nil t) (setq appt-timer (run-at-time t 60 #'appt-check) global-mode-string (append global-mode-string '(appt-mode-string))) commit 9c0387d786fe470de5190fe34f21b671d76c49f5 Author: Mark Oteiza Date: Sun Jan 3 22:07:59 2021 -0500 Fix last change in json.el * lisp/json.el (json-encode-array): Include optimization for lists. diff --git a/lisp/json.el b/lisp/json.el index 24986590cb..1f1f608eab 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -654,7 +654,9 @@ become JSON objects." (defun json-encode-array (array) "Return a JSON representation of ARRAY." (if (and json-encoding-pretty-print - (/= 0 (length array))) + (if (listp array) + array + (> (length array) 0))) (concat "[" (json--with-indentation commit dbc16cdd1351604c7489bd021bcc0d0d6a809b79 Author: Stefan Monnier Date: Sun Jan 3 20:16:40 2021 -0500 * lisp/arc-mode.el (tar-grind-file-mode): Remove left over autoload diff --git a/lisp/arc-mode.el b/lisp/arc-mode.el index 52908d9fb6..6c9ceb0b5a 100644 --- a/lisp/arc-mode.el +++ b/lisp/arc-mode.el @@ -2237,8 +2237,6 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." ;; not the GNU nor the BSD extensions. As it turns out, this is sufficient ;; for .deb packages. -(autoload 'tar-grind-file-mode "tar-mode") - (defconst archive-ar-file-header-re "\\(.\\{16\\}\\)\\([ 0-9]\\{12\\}\\)\\([ 0-9]\\{6\\}\\)\\([ 0-9]\\{6\\}\\)\\([ 0-7]\\{8\\}\\)\\([ 0-9]\\{10\\}\\)`\n") commit 5282e1378e24fc824eccdcfc4e9d3cad0ddef6c2 Author: Stefan Monnier Date: Sun Jan 3 20:14:16 2021 -0500 * doc/lispref/syntax.texi (Syntax Class Table): Clarify `@` diff --git a/doc/lispref/syntax.texi b/doc/lispref/syntax.texi index b4bd48771f..d27053a179 100644 --- a/doc/lispref/syntax.texi +++ b/doc/lispref/syntax.texi @@ -252,7 +252,7 @@ comment and a newline or formfeed ends one. @item Inherit standard syntax: @samp{@@} This syntax class does not specify a particular syntax. It says to -look in the standard syntax table to find the syntax of this +look in the parent syntax table to find the syntax of this character. @item Generic comment delimiters: @samp{!} commit 20ad0cc03b73f6576ece195bb16878415c313d45 Author: Stefan Monnier Date: Sun Jan 3 17:25:06 2021 -0500 * admin/last-chance.el (last-chance): Use `grep`s return value (compilation-finish-functions): Only set it buffer-locally. diff --git a/admin/last-chance.el b/admin/last-chance.el index fd5b8e9bd7..e8021129e3 100644 --- a/admin/last-chance.el +++ b/admin/last-chance.el @@ -105,18 +105,14 @@ defaulting to the one at point." "Symbol: " obarray nil nil one nil one))))) - (let ((default-directory (or (vc-root-dir) - default-directory))) - (grep (format "%s %s" - last-chance-grep-command - symbol))) - (setf (buffer-local-value 'last-chance-symbol - (process-buffer - (car compilation-in-progress))) - symbol)) - -(add-to-list 'compilation-finish-functions - 'last-chance-cleanup) + (with-current-buffer + (let ((default-directory (or (vc-root-dir) + default-directory))) + (grep (format "%s %s" + last-chance-grep-command + symbol))) + (add-hook 'compilation-finish-functions #'last-chance-cleanup nil t) + (setq-local last-chance-symbol symbol))) (provide 'last-chance) commit c2e0f1982f886a9c269fed50a3fc904ca2e1655a Author: Stefan Monnier Date: Sun Jan 3 16:07:16 2021 -0500 * src/buffer.c (Fset_buffer_multibyte): Remove dead code diff --git a/src/buffer.c b/src/buffer.c index 81f7d922fd..0a7ff6e675 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -2602,8 +2602,6 @@ current buffer is cleared. */) p += bytes, pos += bytes; } } - if (narrowed) - Fnarrow_to_region (make_fixnum (begv), make_fixnum (zv)); } else { @@ -2682,9 +2680,6 @@ current buffer is cleared. */) if (pt != PT) TEMP_SET_PT (pt); - if (narrowed) - Fnarrow_to_region (make_fixnum (begv), make_fixnum (zv)); - /* Do this first, so that chars_in_text asks the right question. set_intervals_multibyte needs it too. */ bset_enable_multibyte_characters (current_buffer, Qt); commit d3d60ab2723fe4b3fa15f4d593319d0d08892cb0 Author: Mark Oteiza Date: Sun Jan 3 16:58:09 2021 -0500 Remove unnecessary dependency on seq library * lisp/json.el: Remove require declaration. (json-encode-array): Just use length and /=. diff --git a/lisp/json.el b/lisp/json.el index f5659d81ef..24986590cb 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -55,7 +55,6 @@ ;;; Code: (require 'map) -(require 'seq) (require 'subr-x) ;; Parameters @@ -655,7 +654,7 @@ become JSON objects." (defun json-encode-array (array) "Return a JSON representation of ARRAY." (if (and json-encoding-pretty-print - (not (seq-empty-p array))) + (/= 0 (length array))) (concat "[" (json--with-indentation commit 1fa1354964aa3a0e5e649df6c963b6c11333a350 Author: Phillip Lord Date: Sun Jan 3 18:35:25 2021 +0000 Remove relative paths for consistency * admin/nt/dist-build/build-zips.sh: Remove Paths diff --git a/admin/nt/dist-build/build-zips.sh b/admin/nt/dist-build/build-zips.sh index 809cbc65ca..4a9a7b596e 100755 --- a/admin/nt/dist-build/build-zips.sh +++ b/admin/nt/dist-build/build-zips.sh @@ -20,7 +20,7 @@ function git_up { echo [build] Making git worktree for Emacs $VERSION - cd $HOME/emacs-build/git/emacs-$MAJOR_VERSION + cd $REPO_DIR/emacs-$MAJOR_VERSION git pull git worktree add ../$BRANCH $BRANCH @@ -54,7 +54,7 @@ function build_zip { if [ ! -f Makefile ] || (($CONFIG)) then echo [build] Configuring Emacs $ARCH - ../../../git/$BRANCH/configure \ + $REPO_DIR/$BRANCH/configure \ --without-dbus \ --host=$HOST --without-compress-install \ $CACHE \ @@ -88,7 +88,7 @@ function build_installer { ARCH=$1 cd $HOME/emacs-build/install/emacs-$VERSION echo [build] Calling makensis in `pwd` - cp ../../git/$BRANCH/admin/nt/dist-build/emacs.nsi . + cp $REPO_DIR/$BRANCH/admin/nt/dist-build/emacs.nsi . makensis -v4 \ -DARCH=$ARCH -DEMACS_VERSION=$ACTUAL_VERSION \ @@ -110,6 +110,10 @@ CONFIG=1 CFLAGS="-O2 -static" INSTALL_TARGET="install-strip" +## The location of the git repo +REPO_DIR=$HOME/emacs-build/git/ + + while getopts "36gb:hnsiV:" opt; do case $opt in 3) commit 32c6732d16385f242b1109517f25e9aefd6caa5c Author: Stefan Monnier Date: Sun Jan 3 15:43:31 2021 -0500 * lisp/emacs-lisp/byte-run.el (make-obsolete): Make `when` mandatory (define-obsolete-function-alias, make-obsolete-variable) (define-obsolete-variable-alias): Adjust similarly. diff --git a/etc/NEWS b/etc/NEWS index b294ff1d23..8003175a83 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2019,6 +2019,12 @@ ledit.el, lmenu.el, lucid.el and old-whitespace.el. 'vcursor-toggle-vcursor-map', 'w32-focus-frame', 'w32-select-font', 'wisent-lex-make-token-table'. +** The 'when' argument of `make-obsolete` and related functions is mandatory. +The use of those functions without a 'when' argument was marked +obsolete back in Emacs-23.1. The affected functions are: +make-obsolete, define-obsolete-function-alias, make-obsolete-variable, +define-obsolete-variable-alias. + * Lisp Changes in Emacs 28.1 diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index 8334c09bf9..0f8dd5a284 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el @@ -372,7 +372,7 @@ convention was modified." (puthash (indirect-function function) signature advertised-signature-table)) -(defun make-obsolete (obsolete-name current-name &optional when) +(defun make-obsolete (obsolete-name current-name when) "Make the byte-compiler warn that function OBSOLETE-NAME is obsolete. OBSOLETE-NAME should be a function name or macro name (a symbol). @@ -381,17 +381,14 @@ If CURRENT-NAME is a string, that is the `use instead' message \(it should end with a period, and not start with a capital). WHEN should be a string indicating when the function was first made obsolete, for example a date or a release number." - (declare (advertised-calling-convention - ;; New code should always provide the `when' argument. - (obsolete-name current-name when) "23.1")) (put obsolete-name 'byte-obsolete-info ;; The second entry used to hold the `byte-compile' handler, but ;; is not used any more nowadays. (purecopy (list current-name nil when))) obsolete-name) -(defmacro define-obsolete-function-alias (obsolete-name current-name - &optional when docstring) +(defmacro define-obsolete-function-alias ( obsolete-name current-name when + &optional docstring) "Set OBSOLETE-NAME's function definition to CURRENT-NAME and mark it obsolete. \(define-obsolete-function-alias \\='old-fun \\='new-fun \"22.1\" \"old-fun's doc.\") @@ -405,15 +402,13 @@ WHEN should be a string indicating when the function was first made obsolete, for example a date or a release number. See the docstrings of `defalias' and `make-obsolete' for more details." - (declare (doc-string 4) - (advertised-calling-convention - ;; New code should always provide the `when' argument. - (obsolete-name current-name when &optional docstring) "23.1")) + (declare (doc-string 4)) `(progn (defalias ,obsolete-name ,current-name ,docstring) (make-obsolete ,obsolete-name ,current-name ,when))) -(defun make-obsolete-variable (obsolete-name current-name &optional when access-type) +(defun make-obsolete-variable ( obsolete-name current-name when + &optional access-type) "Make the byte-compiler warn that OBSOLETE-NAME is obsolete. The warning will say that CURRENT-NAME should be used instead. If CURRENT-NAME is a string, that is the `use instead' message. @@ -421,16 +416,13 @@ WHEN should be a string indicating when the variable was first made obsolete, for example a date or a release number. ACCESS-TYPE if non-nil should specify the kind of access that will trigger obsolescence warnings; it can be either `get' or `set'." - (declare (advertised-calling-convention - ;; New code should always provide the `when' argument. - (obsolete-name current-name when &optional access-type) "23.1")) (put obsolete-name 'byte-obsolete-variable (purecopy (list current-name access-type when))) obsolete-name) -(defmacro define-obsolete-variable-alias (obsolete-name current-name - &optional when docstring) +(defmacro define-obsolete-variable-alias ( obsolete-name current-name when + &optional docstring) "Make OBSOLETE-NAME a variable alias for CURRENT-NAME and mark it obsolete. WHEN should be a string indicating when the variable was first @@ -459,10 +451,7 @@ For the benefit of Customize, if OBSOLETE-NAME has any of the following properties, they are copied to CURRENT-NAME, if it does not already have them: `saved-value', `saved-variable-comment'." - (declare (doc-string 4) - (advertised-calling-convention - ;; New code should always provide the `when' argument. - (obsolete-name current-name when &optional docstring) "23.1")) + (declare (doc-string 4)) `(progn (defvaralias ,obsolete-name ,current-name ,docstring) ;; See Bug#4706. commit 32c960bdc61e26521507f2d629ba4da8a4db842e Author: Paul Eggert Date: Sun Jan 3 12:32:27 2021 -0800 Mention -lcurses problem on AIX * etc/PROBLEMS: Describe problem with Emacs 27 and -lcurses. Do not merge to master. diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 2ab76e50bd..7499726678 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -2879,6 +2879,19 @@ A solution is to link with GCC, like this: Since the .o object files already exist, this will not recompile Emacs with GCC, but just restart by trying again to link temacs. +*** Building Emacs with -lcurses fails with undefined symbols like BC. + +The 'configure' script attempts to use several terminal libraries, +including tinfo, ncurses, and terminfo, and curses (in that order). +If it happens to choose the long-obsolete curses library, Emacs will +not link correctly. Emacs 28 is expected to work around this problem; +in the meantime you can work around it by installing tinfo, ncurses or +terminfo instead. + +This problem can happen on AIX 7.2 if you build with IBM's compiler XLC, +as AIX's ncurses library suffers from the libgcc problem mentioned above. +To work around this, configure and build with GCC. + *** Sun with acc: Link failure when using acc on a Sun. To use acc, you need additional options just before the libraries, such as commit 632917461a7c1893a83979a3873b51d4da3b8a42 Author: Paul Eggert Date: Sun Jan 3 11:19:48 2021 -0800 Fix broken build on AIX 7.2 Without this fix, the build on AIX 7.2 with xlc fails in the ‘CCLD temacs’ step with the diagnostic ‘ld: 0711-317 ERROR: Undefined symbol: BC’. This is because -lcurses does not define BC etc. * configure.ac: When building terminfo.o, define TERMINFO_DEFINES_BC if the library defines BC etc. * src/terminfo.c (UP, BC, PC): Define depending on TERMINFO_DEFINES_BC, not on TERMINFO. diff --git a/configure.ac b/configure.ac index bcc0be7de0..66c660696b 100644 --- a/configure.ac +++ b/configure.ac @@ -4393,6 +4393,18 @@ TERMCAP_OBJ=tparam.o if test $TERMINFO = yes; then AC_DEFINE(TERMINFO, 1, [Define to 1 if you use terminfo instead of termcap.]) TERMCAP_OBJ=terminfo.o + AC_CACHE_CHECK([whether $LIBS_TERMCAP library defines BC], + [emacs_cv_terminfo_defines_BC], + [OLD_LIBS=$LIBS + LIBS="$LIBS $LIBS_TERMCAP" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern char *BC;]], [[return !*BC;]])], + [emacs_cv_terminfo_defines_BC=yes], + [emacs_cv_terminfo_defines_BC=no]) + LIBS=$OLD_LIBS]) + if test "$emacs_cv_terminfo_defines_BC" = yes; then + AC_DEFINE([TERMINFO_DEFINES_BC], 1, [Define to 1 if the + terminfo library defines the variables BC, PC, and UP.]) + fi fi if test "X$LIBS_TERMCAP" = "X-lncurses"; then AC_DEFINE(USE_NCURSES, 1, [Define to 1 if you use ncurses.]) diff --git a/src/terminfo.c b/src/terminfo.c index 15aff317f1..a9c9572bbb 100644 --- a/src/terminfo.c +++ b/src/terminfo.c @@ -23,10 +23,10 @@ along with GNU Emacs. If not, see . */ /* Define these variables that serve as global parameters to termcap, so that we do not need to conditionalize the places in Emacs - that set them. But don't do that for terminfo, as that could - cause link errors when using -fno-common. */ + that set them. But don't do that if terminfo defines them, as that + could cause link errors when using -fno-common. */ -#if !TERMINFO +#ifndef TERMINFO_DEFINES_BC char *UP, *BC, PC; #endif commit 2e09efdb6877a2c189385be45d4cdceb617b6c5d Author: Paul Eggert Date: Sun Jan 3 11:58:34 2021 -0800 Revert previous patch which was installed into wrong branch. diff --git a/configure.ac b/configure.ac index 89b0785d03..48e96529ff 100644 --- a/configure.ac +++ b/configure.ac @@ -4366,18 +4366,6 @@ TERMCAP_OBJ=tparam.o if test $TERMINFO = yes; then AC_DEFINE(TERMINFO, 1, [Define to 1 if you use terminfo instead of termcap.]) TERMCAP_OBJ=terminfo.o - AC_CACHE_CHECK([whether $LIBS_TERMCAP library defines BC], - [emacs_cv_terminfo_defines_BC], - [OLD_LIBS=$LIBS - LIBS="$LIBS $LIBS_TERMCAP" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern char *BC;]], [[return !*BC;]])], - [emacs_cv_terminfo_defines_BC=yes], - [emacs_cv_terminfo_defines_BC=no]) - LIBS=$OLD_LIBS]) - if test "$emacs_cv_terminfo_defines_BC" = yes; then - AC_DEFINE([TERMINFO_DEFINES_BC], 1, [Define to 1 if the - terminfo library defines the variables BC, PC, and UP.]) - fi fi if test "X$LIBS_TERMCAP" = "X-lncurses"; then AC_DEFINE(USE_NCURSES, 1, [Define to 1 if you use ncurses.]) diff --git a/src/terminfo.c b/src/terminfo.c index a9c9572bbb..15aff317f1 100644 --- a/src/terminfo.c +++ b/src/terminfo.c @@ -23,10 +23,10 @@ along with GNU Emacs. If not, see . */ /* Define these variables that serve as global parameters to termcap, so that we do not need to conditionalize the places in Emacs - that set them. But don't do that if terminfo defines them, as that - could cause link errors when using -fno-common. */ + that set them. But don't do that for terminfo, as that could + cause link errors when using -fno-common. */ -#ifndef TERMINFO_DEFINES_BC +#if !TERMINFO char *UP, *BC, PC; #endif commit 585997d05adde5a3510ce1221f9e8dd60407ce30 Author: Paul Eggert Date: Sun Jan 3 11:19:48 2021 -0800 Fix broken build on AIX 7.2 Without this fix, the build on AIX 7.2 with xlc fails in the ‘CCLD temacs’ step with the diagnostic ‘ld: 0711-317 ERROR: Undefined symbol: BC’. This is because -lcurses does not define BC etc. * configure.ac: When building terminfo.o, define TERMINFO_DEFINES_BC if the library defines BC etc. * src/terminfo.c (UP, BC, PC): Define depending on TERMINFO_DEFINES_BC, not on TERMINFO. diff --git a/configure.ac b/configure.ac index 48e96529ff..89b0785d03 100644 --- a/configure.ac +++ b/configure.ac @@ -4366,6 +4366,18 @@ TERMCAP_OBJ=tparam.o if test $TERMINFO = yes; then AC_DEFINE(TERMINFO, 1, [Define to 1 if you use terminfo instead of termcap.]) TERMCAP_OBJ=terminfo.o + AC_CACHE_CHECK([whether $LIBS_TERMCAP library defines BC], + [emacs_cv_terminfo_defines_BC], + [OLD_LIBS=$LIBS + LIBS="$LIBS $LIBS_TERMCAP" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern char *BC;]], [[return !*BC;]])], + [emacs_cv_terminfo_defines_BC=yes], + [emacs_cv_terminfo_defines_BC=no]) + LIBS=$OLD_LIBS]) + if test "$emacs_cv_terminfo_defines_BC" = yes; then + AC_DEFINE([TERMINFO_DEFINES_BC], 1, [Define to 1 if the + terminfo library defines the variables BC, PC, and UP.]) + fi fi if test "X$LIBS_TERMCAP" = "X-lncurses"; then AC_DEFINE(USE_NCURSES, 1, [Define to 1 if you use ncurses.]) diff --git a/src/terminfo.c b/src/terminfo.c index 15aff317f1..a9c9572bbb 100644 --- a/src/terminfo.c +++ b/src/terminfo.c @@ -23,10 +23,10 @@ along with GNU Emacs. If not, see . */ /* Define these variables that serve as global parameters to termcap, so that we do not need to conditionalize the places in Emacs - that set them. But don't do that for terminfo, as that could - cause link errors when using -fno-common. */ + that set them. But don't do that if terminfo defines them, as that + could cause link errors when using -fno-common. */ -#if !TERMINFO +#ifndef TERMINFO_DEFINES_BC char *UP, *BC, PC; #endif commit ad2567fb1efced752352096f345c69f88e1ff405 Author: Alan Third Date: Sun Jan 3 16:15:18 2021 +0000 Fix child frame restacking on NS (bug#41422) * src/nsfns.m (Fns_frame_restack): Use new restackWindow method. * src/nsterm.m ([EmacsWindow orderFront:]): ([EmacsWindow makeKeyAndOrderFront:]): (nswindow_orderedIndex_sort): ([EmacsWindow orderBack:]): ([EmacsWindow restackWindow:above:]): Override superclass methods to handle child windows the way we want. diff --git a/src/nsfns.m b/src/nsfns.m index ee2daea072..ae114f83e4 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -1485,14 +1485,14 @@ Frames are listed from topmost (first) to bottommost (last). */) if (FRAME_NS_VIEW (f1) && FRAME_NS_VIEW (f2)) { - NSWindow *window = [FRAME_NS_VIEW (f1) window]; - NSInteger window2 = [[FRAME_NS_VIEW (f2) window] windowNumber]; - NSWindowOrderingMode flag = NILP (above) ? NSWindowBelow : NSWindowAbove; + EmacsWindow *window = (EmacsWindow *)[FRAME_NS_VIEW (f1) window]; + NSWindow *window2 = [FRAME_NS_VIEW (f2) window]; + BOOL flag = !NILP (above); - [window orderWindow: flag - relativeTo: window2]; - - return Qt; + if ([window restackWindow:window2 above:!NILP (above)]) + return Qt; + else + return Qnil; } else { diff --git a/src/nsterm.h b/src/nsterm.h index 3fb64494f7..2c9d8e85ba 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -498,6 +498,7 @@ typedef id instancetype; NSPoint grabOffset; } +- (BOOL)restackWindow:(NSWindow *)win above:(BOOL)above; - (void)setAppearance; @end diff --git a/src/nsterm.m b/src/nsterm.m index 2731063950..2defb9e2ee 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -8693,6 +8693,112 @@ - (int) fullscreenState @implementation EmacsWindow +/* It seems the only way to reorder child frames is by removing them + from the parent and then reattaching them in the correct order. */ + +- (void)orderFront:(id)sender +{ + NSTRACE ("[EmacsWindow orderFront:]"); + + NSWindow *parent = [self parentWindow]; + if (parent) + { + [parent removeChildWindow:self]; + [parent addChildWindow:self ordered:NSWindowAbove]; + } + else + [super orderFront:sender]; +} + +- (void)makeKeyAndOrderFront:(id)sender +{ + NSTRACE ("[EmacsWindow makeKeyAndOrderFront:]"); + + if ([self parentWindow]) + { + [self orderFront:sender]; + [self makeKeyWindow]; + } + else + [super makeKeyAndOrderFront:sender]; +} + + +/* The array returned by [NSWindow parentWindow] may already be + sorted, but the documentation doesn't tell us whether or not it is, + so to be safe we'll sort it. */ +NSInteger nswindow_orderedIndex_sort (id w1, id w2, void *c) +{ + NSInteger i1 = [w1 orderedIndex]; + NSInteger i2 = [w2 orderedIndex]; + + if (i1 > i2) + return NSOrderedAscending; + if (i1 < i2) + return NSOrderedDescending; + + return NSOrderedSame; +} + +- (void)orderBack:(id)sender +{ + NSTRACE ("[EmacsWindow orderBack:]"); + + NSWindow *parent = [self parentWindow]; + if (parent) + { + NSArray *children = [[parent childWindows] + sortedArrayUsingFunction:nswindow_orderedIndex_sort + context:nil]; + [parent removeChildWindow:self]; + [parent addChildWindow:self ordered:NSWindowAbove]; + + for (NSWindow *win in children) + { + if (win != self) + { + [parent removeChildWindow:win]; + [parent addChildWindow:win ordered:NSWindowAbove]; + } + } + } + else + [super orderBack:sender]; +} + +- (BOOL)restackWindow:(NSWindow *)win above:(BOOL)above +{ + NSTRACE ("[EmacsWindow restackWindow:above:]"); + + /* If parent windows don't match we can't restack these frames + without changing the parents. */ + if ([self parentWindow] != [win parentWindow]) + return NO; + else if (![self parentWindow]) + [self orderWindow:(above ? NSWindowAbove : NSWindowBelow) + relativeTo:[win windowNumber]]; + else + { + NSInteger index; + NSWindow *parent = [self parentWindow]; + NSMutableArray *children = [[[parent childWindows] + sortedArrayUsingFunction:nswindow_orderedIndex_sort + context:nil] + mutableCopy]; + [children removeObject:self]; + index = [children indexOfObject:win]; + [children insertObject:self atIndex:(above ? index+1 : index)]; + + for (NSWindow *w in children) + { + [parent removeChildWindow:w]; + [parent addChildWindow:w ordered:NSWindowAbove]; + } + } + + return YES; +} + #ifdef NS_IMPL_COCOA - (id)accessibilityAttributeValue:(NSString *)attribute { commit 825b4ec338e82869dc656c7041ab2483b6c22479 Author: Stefan Monnier Date: Sat Jan 2 23:12:10 2021 -0500 * lisp/progmodes/xref.el (xref--show-defs-buffer-at-bottom): Fix missing arg diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index d2b5acd555..2fefc23e19 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -1005,8 +1005,8 @@ local keymap that binds `RET' to `xref-quit-and-goto-xref'." '(display-buffer-in-direction . ((direction . below)))) (current-buffer)))))) -(define-obsolete-function-alias - 'xref--show-defs-buffer-at-bottom #'xref-show-definitions-buffer-at-bottom) +(define-obsolete-function-alias 'xref--show-defs-buffer-at-bottom + #'xref-show-definitions-buffer-at-bottom "28.1") (defun xref-show-definitions-completing-read (fetcher alist) "Let the user choose the target definition with completion. commit f14869cd70e61b1908ec88a5e3d4bf21c7d538a0 Author: Alan Third Date: Sat Jan 2 22:27:53 2021 +0000 Fix crash when using menus and tramp on NS ; Fixes bug#24472, bug#37557 and bug#37922. * src/nsterm.m (ns_select): Don't drain outerpool in this function. diff --git a/src/nsterm.m b/src/nsterm.m index a4ee147693..2731063950 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -4721,8 +4721,22 @@ in certain situations (rapid incoming events). thread_select(pselect, 0, NULL, NULL, NULL, &t, sigmask); } - [outerpool release]; - outerpool = [[NSAutoreleasePool alloc] init]; + /* FIXME: This draining of outerpool causes a crash when a buffer + running over tramp is displayed and the user tries to use the + menus. I believe some other autorelease pool's lifetime + straddles this call causing a violation of autorelease pool + nesting. There's no good reason to keep these here since the + pool will be drained some other time anyway, but removing them + leaves the menus sometimes not opening until the user moves their + mouse pointer, but that's better than a crash. + + There must be something about running external processes like + tramp that interferes with the modal menu code. + + See bugs 24472, 37557, 37922. */ + + // [outerpool release]; + // outerpool = [[NSAutoreleasePool alloc] init]; send_appdefined = YES; commit d84cf78df8ea5d99cc5b38c49f3b7aed081170f5 Author: Alan Third Date: Sat Jan 2 18:19:39 2021 +0000 Fix NS toolbar image release crash (bug#43973) The toolbar fails to make a proper copy of EmacsImage objects, so releasing the copy incorrectly released instance variables from the original objects. * src/nsimage.m ([EmacsImage copyWithZone:]): New function to enable correct copying of EmacsImage. diff --git a/src/nsimage.m b/src/nsimage.m index f0014b50b9..fa81a41a51 100644 --- a/src/nsimage.m +++ b/src/nsimage.m @@ -293,6 +293,18 @@ - (void)dealloc } +- (id)copyWithZone:(NSZone *)zone +{ + EmacsImage *copy = [super copyWithZone:zone]; + + copy->stippleMask = [stippleMask copyWithZone:zone]; + copy->bmRep = [bmRep copyWithZone:zone]; + copy->transform = [transform copyWithZone:zone]; + + return copy; +} + + /* Create image from monochrome bitmap. If both FG and BG are 0 (black), set the background to white and make it transparent. */ - (instancetype)initFromXBM: (unsigned char *)bits width: (int)w height: (int)h commit dde3269633550debb8b13cdc77136fe638c8e1fc Author: Roland Winkler Date: Sat Jan 2 13:44:23 2021 -0600 bibtex-mode: Extend widget bibtex-entry-alist diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el index d238b6037e..a22cd97b30 100644 --- a/lisp/textmodes/bibtex.el +++ b/lisp/textmodes/bibtex.el @@ -312,7 +312,9 @@ If parsing fails, try to set this variable to nil." (option (choice :tag "Comment" :value nil (const nil) string)) (option (choice :tag "Init" :value nil - (const nil) string function))))))) + (const nil) string function)) + (option (choice :tag "Alternative" :value nil + (const nil) integer))))))) (define-obsolete-variable-alias 'bibtex-entry-field-alist 'bibtex-BibTeX-entry-alist "24.1") commit bfb4db5e4464e834224fd668a6e9c949e03393d6 Author: Eric Abrahamsen Date: Sat Jan 2 11:05:38 2021 -0800 Reposition call to set-buffer-modified-p in sieve-upload * lisp/net/sieve.el (sieve-upload): It's meant to affect the script buffer, not sieve-buffer, so needs to be outside the call to with-current-buffer. diff --git a/lisp/net/sieve.el b/lisp/net/sieve.el index e46f4daae2..ca100267f6 100644 --- a/lisp/net/sieve.el +++ b/lisp/net/sieve.el @@ -360,8 +360,8 @@ Used to bracket operations which move point in the sieve-buffer." (if (not (sieve-manage-ok-p err)) (message "Sieve upload failed: %s" (nth 2 err)) (message "Sieve upload done. Use %s to manage scripts." - (substitute-command-keys "\\[sieve-manage]")) - (set-buffer-modified-p nil)))))) + (substitute-command-keys "\\[sieve-manage]")))) + (set-buffer-modified-p nil)))) ;;;###autoload (defun sieve-upload-and-bury (&optional name) commit 6b10ce867f2130532b82d32865b74ec270515809 Author: Dmitry Gutov Date: Sat Jan 2 20:50:22 2021 +0200 xref--show-pos-in-buf: Don't set other-window-scroll-buffer * lisp/progmodes/xref.el (xref--show-pos-in-buf): Don't set other-window-scroll-buffer (bug#45581). diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 29e7b6849f..d2b5acd555 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -547,8 +547,7 @@ If SELECT is non-nil, select the target window." "Goto and display position POS of buffer BUF in a window. Honor `xref--original-window-intent', run `xref-after-jump-hook' and finally return the window." - (let* ((xref-buf (current-buffer)) - (pop-up-frames + (let* ((pop-up-frames (or (eq xref--original-window-intent 'frame) pop-up-frames)) (action @@ -566,9 +565,6 @@ and finally return the window." (with-selected-window (display-buffer buf action) (xref--goto-char pos) (run-hooks 'xref-after-jump-hook) - (let ((buf (current-buffer))) - (with-current-buffer xref-buf - (setq-local other-window-scroll-buffer buf))) (selected-window)))) (defun xref--display-buffer-in-other-window (buffer alist) commit d10c96c42628c548f60f8004d44d765d0ae82517 Author: Mattias Engdegård Date: Sat Jan 2 18:08:47 2021 +0100 Fix backslash mistakes in doc strings in C code These were found by an instrumented version of make-docfile. * src/gnutls.c (Fgnutls_available_p): * src/keymap.c (Fkey_description): * src/xdisp.c (syms_of_xdisp): diff --git a/src/gnutls.c b/src/gnutls.c index b995ffffa6..aa245ee5c3 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -2766,7 +2766,7 @@ GnuTLS MACs : the list will contain `macs'. GnuTLS digests : the list will contain `digests'. GnuTLS symmetric ciphers: the list will contain `ciphers'. GnuTLS AEAD ciphers : the list will contain `AEAD-ciphers'. -%DUMBFW : the list will contain `ClientHello\ Padding'. +%DUMBFW : the list will contain `ClientHello\\ Padding'. Any GnuTLS extension with ID up to 100 : the list will contain its name. */) (void) diff --git a/src/keymap.c b/src/keymap.c index f9aac6d731..1eeea81f62 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -1968,7 +1968,7 @@ then the value includes only maps for prefixes that start with PREFIX. */) DEFUN ("key-description", Fkey_description, Skey_description, 1, 2, 0, doc: /* Return a pretty description of key-sequence KEYS. Optional arg PREFIX is the sequence of keys leading up to KEYS. -For example, [?\C-x ?l] is converted into the string \"C-x l\". +For example, [?\\C-x ?l] is converted into the string \"C-x l\". For an approximate inverse of this, see `kbd'. */) (Lisp_Object keys, Lisp_Object prefix) diff --git a/src/xdisp.c b/src/xdisp.c index 64ec0abad4..749893baad 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -35581,7 +35581,7 @@ message displayed by its counterpart function specified by DEFVAR_BOOL ("display-raw-bytes-as-hex", display_raw_bytes_as_hex, doc: /* Non-nil means display raw bytes in hexadecimal format. -The default is to use octal format (\200) whereas hexadecimal (\x80) +The default is to use octal format (\\200) whereas hexadecimal (\\x80) may be more familiar to users. */); display_raw_bytes_as_hex = false; commit c7f15dfa80f5d104fa2b7faf06298a88160b59d9 Author: Mauro Aranda Date: Sat Jan 2 11:59:36 2021 -0300 Fix Quit button in dictionary buffer * lisp/net/dictionary.el (dictionay-close): Changing the arity of the function in cc5f2803785c5dc785f09a292313cf799e8d29bb was a mistake. Restore it, but mark the argument as unused to avoid a wrong-number-of-arguments error when using the Quit button. diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el index 07f44ba035..f8733429e9 100644 --- a/lisp/net/dictionary.el +++ b/lisp/net/dictionary.el @@ -516,7 +516,7 @@ The connection takes the proxy setting in customization group ;; Dealing with closing the buffer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun dictionary-close () +(defun dictionary-close (&rest ignored) "Close the current dictionary buffer and its connection." (interactive) (if (eq major-mode 'dictionary-mode) commit 4ac6148ef94fed6863c75e73ad91b565ce60cabe Author: Philipp Stephani Date: Sat Jan 2 15:04:50 2021 +0100 Avoid printing stacktraces when it probably wouldn't work anyway. * src/eval.c (signal_or_quit): Don't try to call the debugger if it's inhibited or we are about to dump or bootstrap. In those cases the debugger probably wouldn't work anyway. diff --git a/src/eval.c b/src/eval.c index d0db902217..706aafdf50 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1731,12 +1731,16 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit) return Qnil; } - /* If we're in batch mode, print a backtrace unconditionally to help with - debugging. Make sure to use `debug' unconditionally to not interfere with - ERT or other packages that install custom debuggers. */ + /* If we're in batch mode, print a backtrace unconditionally to help + with debugging. Make sure to use `debug' unconditionally to not + interfere with ERT or other packages that install custom + debuggers. Don't try to call the debugger while dumping or + bootstrapping, it wouldn't work anyway. */ if (!debugger_called && !NILP (error_symbol) - && (NILP (clause) || EQ (h->tag_or_ch, Qerror)) && noninteractive - && backtrace_on_error_noninteractive) + && (NILP (clause) || EQ (h->tag_or_ch, Qerror)) + && noninteractive && backtrace_on_error_noninteractive + && !will_dump_p () && !will_bootstrap_p () + && NILP (Vinhibit_debugger)) { ptrdiff_t count = SPECPDL_INDEX (); specbind (Vdebugger, Qdebug); commit 64f2c96cbe3ba803c4026c976c425771911e29e3 Author: Philipp Stephani Date: Sat Jan 2 13:53:17 2021 +0100 Make a process test faster. The test 'process-tests/fd-setsize-no-crash/make-process' used to call 'sleep' to ensure that enough processes are live to trigger a FD_SETSIZE overflow. However, we can just call 'cat' instead and close standard input when done. That way, we only wait as long as needed. * process-tests.el (process-tests/fd-setsize-no-crash/make-process): Invoke 'cat' instead of 'sleep'. Close standard input to exit the 'cat' processes. diff --git a/test/src/process-tests.el b/test/src/process-tests.el index e1e25068e4..5294bc07ce 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -535,8 +535,8 @@ Afterwards, delete the directory." "Check that Emacs doesn't crash when trying to use more than FD_SETSIZE file descriptors (Bug#24325)." (with-timeout (60 (ert-fail "Test timed out")) - (let ((sleep (executable-find "sleep"))) - (skip-unless sleep) + (let ((cat (executable-find "cat"))) + (skip-unless cat) (dolist (conn-type '(pipe pty)) (ert-info ((format "Connection type `%s'" conn-type)) (process-tests--fd-setsize-test @@ -552,7 +552,7 @@ FD_SETSIZE file descriptors (Bug#24325)." ;; ignore `file-error'. (process-tests--ignore-EMFILE (make-process :name (format "test %d" i) - :command (list sleep "5") + :command (list cat) :connection-type conn-type :coding 'no-conversion :noquery t)))) @@ -560,6 +560,8 @@ FD_SETSIZE file descriptors (Bug#24325)." ;; We should have managed to start at least one process. (should processes) (dolist (process processes) + (should (process-live-p process)) + (process-send-eof process) (while (accept-process-output process)) (should (eq (process-status process) 'exit)) ;; If there's an error between fork and exec, Emacs commit df605870fde7e31d2ca76fd7e69961ba94604a34 Author: Philipp Stephani Date: Sat Jan 2 13:30:53 2021 +0100 Simplify TTY allocation. The 'process-tty-name' already provides the TTY name, we don't have interrogate the TTY host. * test/src/process-tests.el (process-tests/fd-setsize-no-crash/make-serial-process): Use 'process-tty-name' instead of having the TTY host print its TTY name. Check whether TTY names are unique. (process-tests--new-pty, process-tests--with-temp-file): Remove; no longer used. diff --git a/test/src/process-tests.el b/test/src/process-tests.el index cddf955853..e1e25068e4 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -512,18 +512,6 @@ FD_SETSIZE." (delete-process (pop ,processes)) ,@body))))) -(defmacro process-tests--with-temp-file (var &rest body) - "Bind VAR to the name of a new regular file and evaluate BODY. -Afterwards, delete the file." - (declare (indent 1) (debug (symbolp body))) - (cl-check-type var symbol) - (let ((file (make-symbol "file"))) - `(let ((,file (make-temp-file "emacs-test-"))) - (unwind-protect - (let ((,var ,file)) - ,@body) - (delete-file ,file))))) - (defmacro process-tests--with-temp-directory (var &rest body) "Bind VAR to the name of a new directory and evaluate BODY. Afterwards, delete the directory." @@ -654,12 +642,6 @@ FD_SETSIZE file descriptors (Bug#24325)." "Check that Emacs doesn't crash when trying to use more than FD_SETSIZE file descriptors (Bug#24325)." (with-timeout (60 (ert-fail "Test timed out")) - (skip-unless (file-executable-p shell-file-name)) - (skip-unless (executable-find "tty")) - (skip-unless (executable-find "sleep")) - ;; `process-tests--new-pty' probably only works with GNU Bash. - (skip-unless (string-equal - (file-name-nondirectory shell-file-name) "bash")) (process-tests--with-processes processes ;; In order to use `make-serial-process', we need to create some ;; pseudoterminals. The easiest way to do that is to start a @@ -667,14 +649,22 @@ FD_SETSIZE file descriptors (Bug#24325)." ;; ensure that the terminal stays around while we connect to it. ;; Create the host processes before the dummy pipes so we have a ;; high chance of succeeding here. - (let ((tty-names ())) - (dotimes (_ 10) - (cl-destructuring-bind - (host tty-name) (process-tests--new-pty) + (let ((sleep (executable-find "sleep")) + (tty-names ())) + (skip-unless sleep) + (dotimes (i 10) + (let* ((host (make-process :name (format "tty host %d" i) + :command (list sleep "60") + :buffer nil + :coding 'utf-8-unix + :connection-type 'pty + :noquery t)) + (tty-name (process-tty-name host))) (should (processp host)) (push host processes) (should tty-name) (should (file-exists-p tty-name)) + (should-not (member tty-name tty-names)) (push tty-name tty-names))) (process-tests--fd-setsize-test (process-tests--with-processes processes @@ -717,42 +707,5 @@ Return nil if that can't be determined." (match-string-no-properties 1)))))) process-tests--EMFILE-message) -(defun process-tests--new-pty () - "Allocate a new pseudoterminal. -Return a list (PROCESS TTY-NAME)." - ;; The command below will typically only work with GNU Bash. - (should (string-equal (file-name-nondirectory shell-file-name) - "bash")) - (process-tests--with-temp-file temp-file - (should-not (file-remote-p temp-file)) - (let* ((command (list shell-file-name shell-command-switch - (format "tty > %s && sleep 60" - (shell-quote-argument - (file-name-unquote temp-file))))) - (process (make-process :name "tty host" - :command command - :buffer nil - :coding 'utf-8-unix - :connection-type 'pty - :noquery t)) - (tty-name nil) - (coding-system-for-read 'utf-8-unix) - (coding-system-for-write 'utf-8-unix)) - ;; Wait until TTY name has arrived. - (with-timeout (2 (message "Timed out waiting for TTY name")) - (while (and (process-live-p process) (not tty-name)) - (sleep-for 0.1) - (when-let ((attributes (file-attributes temp-file))) - (when (cl-plusp (file-attribute-size attributes)) - (with-temp-buffer - (insert-file-contents temp-file) - (goto-char (point-max)) - ;; `tty' has printed a trailing newline. - (skip-chars-backward "\n") - (unless (bobp) - (setq tty-name (buffer-substring-no-properties - (point-min) (point))))))))) - (list process tty-name)))) - (provide 'process-tests) ;;; process-tests.el ends here commit 72b048bb9650283f40c93735a5ab50f62e0f4118 Author: Eli Zaretskii Date: Sat Jan 2 13:36:54 2021 +0200 Fix last change in characters.el * lisp/international/characters.el: Adjust syntax of more characters to follow that of Unicode properties. (Bug#44974) diff --git a/lisp/international/characters.el b/lisp/international/characters.el index 88f2e20dcc..6924e1c06d 100644 --- a/lisp/international/characters.el +++ b/lisp/international/characters.el @@ -226,6 +226,7 @@ with L, LRE, or LRO Unicode bidi character type.") ;; JISX0208 +;; Note: Some of these have their syntax updated later below. (map-charset-chars #'modify-syntax-entry 'japanese-jisx0208 "_" #x2121 #x227E) (map-charset-chars #'modify-syntax-entry 'japanese-jisx0208 "_" #x2821 #x287E) (let ((chars '(?ー ?゛ ?゜ ?ヽ ?ヾ ?ゝ ?ゞ ?〃 ?仝 ?々 ?〆 ?〇))) @@ -681,6 +682,13 @@ with L, LRE, or LRO Unicode bidi character type.") (set-case-syntax c "." tbl) (setq c (1+ c))) + ;; Ideographic punctuation + (setq c #x3001) + (while (<= c #x3003) + (set-case-syntax c "." tbl) + (setq c (1+ c))) + (set-case-syntax #x30FB "." tbl) + ;; Symbols for Legacy Computing (setq c #x1FB00) (while (<= c #x1FBCA) @@ -698,6 +706,10 @@ with L, LRE, or LRO Unicode bidi character type.") (setq c (1+ c))) (set-case-syntax #xFF04 "_" tbl) (set-case-syntax #xFF0B "_" tbl) + (set-case-syntax #xFF1A "." tbl) + (set-case-syntax #xFF1B "." tbl) + (set-case-syntax #xFF1F "." tbl) + (set-case-syntax #xFF20 "." tbl) (setq c #xFF21) (while (<= c #xFF3A) (modify-category-entry c ?l) commit 70e6c0850eae29eeb2b9a850bcf9023e88caaa7d Author: João Távora Date: Sat Jan 2 11:18:40 2021 +0000 ; * lisp/progmodes/flymake.el: Bump version to 1.1.0. diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index 5ba9460eee..fddc13f56b 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -4,7 +4,7 @@ ;; Author: Pavel Kobyakov ;; Maintainer: João Távora -;; Version: 1.0.9 +;; Version: 1.1.0 ;; Keywords: c languages tools ;; Package-Requires: ((emacs "26.1") (eldoc "1.1.0")) commit 70484f92a1807897dcd16189442a45385c6e7bbb Author: Eli Zaretskii Date: Sat Jan 2 12:42:16 2021 +0200 Fix syntax of symbol and punctuation characters * lisp/international/characters.el: Adjust syntax of punctuation and symbol charcaters to follow that of Unicode properties. (Bug#44974) diff --git a/lisp/international/characters.el b/lisp/international/characters.el index 64460b411a..88f2e20dcc 100644 --- a/lisp/international/characters.el +++ b/lisp/international/characters.el @@ -317,6 +317,7 @@ with L, LRE, or LRO Unicode bidi character type.") (modify-syntax-entry #x5be ".") ; MAQAF (modify-syntax-entry #x5c0 ".") ; PASEQ (modify-syntax-entry #x5c3 ".") ; SOF PASUQ +(modify-syntax-entry #x5c6 ".") ; NUN HAFUKHA (modify-syntax-entry #x5f3 ".") ; GERESH (modify-syntax-entry #x5f4 ".") ; GERSHAYIM @@ -521,6 +522,9 @@ with L, LRE, or LRO Unicode bidi character type.") ;; syntax: ¢£¤¥¨ª¯²³´¶¸¹º.) There should be a well-defined way of ;; relating Unicode categories to Emacs syntax codes. + ;; FIXME: We should probably just use the Unicode properties to set + ;; up the syntax table. + ;; NBSP isn't semantically interchangeable with other whitespace chars, ;; so it's more like punctuation. (set-case-syntax ?  "." tbl) @@ -558,7 +562,7 @@ with L, LRE, or LRO Unicode bidi character type.") (setq c (1+ c))) ;; Latin Extended Additional - (modify-category-entry '(#x1e00 . #x1ef9) ?l) + (modify-category-entry '(#x1E00 . #x1EF9) ?l) ;; Latin Extended-C (setq c #x2C60) @@ -579,13 +583,13 @@ with L, LRE, or LRO Unicode bidi character type.") (setq c (1+ c))) ;; Greek - (modify-category-entry '(#x0370 . #x03ff) ?g) + (modify-category-entry '(#x0370 . #x03FF) ?g) ;; Armenian (setq c #x531) ;; Greek Extended - (modify-category-entry '(#x1f00 . #x1fff) ?g) + (modify-category-entry '(#x1F00 . #x1FFF) ?g) ;; cyrillic (modify-category-entry '(#x0400 . #x04FF) ?y) @@ -605,40 +609,43 @@ with L, LRE, or LRO Unicode bidi character type.") (while (<= c #x200F) (set-case-syntax c "." tbl) (setq c (1+ c))) - ;; Fixme: These aren't all right: (setq c #x2010) - (while (<= c #x2016) - (set-case-syntax c "_" tbl) + ;; Fixme: What to do with characters that have Pi and Pf + ;; Unicode properties? + (while (<= c #x2017) + (set-case-syntax c "." tbl) (setq c (1+ c))) ;; Punctuation syntax for quotation marks (like `) - (while (<= c #x201f) + (while (<= c #x201F) (set-case-syntax c "." tbl) (setq c (1+ c))) - ;; Fixme: These aren't all right: (while (<= c #x2027) - (set-case-syntax c "_" tbl) + (set-case-syntax c "." tbl) (setq c (1+ c))) - (while (<= c #x206F) + (setq c #x2030) + (while (<= c #x205E) (set-case-syntax c "." tbl) (setq c (1+ c))) + (let ((chars '(?‹ ?› ?⁄ ?⁒))) + (while chars + (modify-syntax-entry (car chars) "_") + (setq chars (cdr chars)))) - ;; Fixme: The following blocks might be better as symbol rather than - ;; punctuation. ;; Arrows (setq c #x2190) (while (<= c #x21FF) - (set-case-syntax c "." tbl) + (set-case-syntax c "_" tbl) (setq c (1+ c))) ;; Mathematical Operators (while (<= c #x22FF) - (set-case-syntax c "." tbl) + (set-case-syntax c "_" tbl) (setq c (1+ c))) ;; Miscellaneous Technical (while (<= c #x23FF) - (set-case-syntax c "." tbl) + (set-case-syntax c "_" tbl) (setq c (1+ c))) ;; Control Pictures - (while (<= c #x243F) + (while (<= c #x244F) (set-case-syntax c "_" tbl) (setq c (1+ c))) @@ -652,13 +659,13 @@ with L, LRE, or LRO Unicode bidi character type.") ;; Supplemental Mathematical Operators (setq c #x2A00) (while (<= c #x2AFF) - (set-case-syntax c "." tbl) + (set-case-syntax c "_" tbl) (setq c (1+ c))) ;; Miscellaneous Symbols and Arrows (setq c #x2B00) (while (<= c #x2BFF) - (set-case-syntax c "." tbl) + (set-case-syntax c "_" tbl) (setq c (1+ c))) ;; Coptic @@ -676,17 +683,34 @@ with L, LRE, or LRO Unicode bidi character type.") ;; Symbols for Legacy Computing (setq c #x1FB00) + (while (<= c #x1FBCA) + (set-case-syntax c "_" tbl) + (setq c (1+ c))) + ;; FIXME: Should these be digits? (while (<= c #x1FBFF) (set-case-syntax c "." tbl) (setq c (1+ c))) ;; Fullwidth Latin - (setq c #xff21) - (while (<= c #xff3a) + (setq c #xFF01) + (while (<= c #xFF0F) + (set-case-syntax c "." tbl) + (setq c (1+ c))) + (set-case-syntax #xFF04 "_" tbl) + (set-case-syntax #xFF0B "_" tbl) + (setq c #xFF21) + (while (<= c #xFF3A) (modify-category-entry c ?l) (modify-category-entry (+ c #x20) ?l) (setq c (1+ c))) + ;; Halfwidth Latin + (setq c #xFF64) + (while (<= c #xFF65) + (set-case-syntax c "." tbl) + (setq c (1+ c))) + (set-case-syntax #xFF61 "." tbl) + ;; Combining diacritics (modify-category-entry '(#x300 . #x362) ?^) ;; Combining marks commit a7c2793efe503ad7ad9f2d6fc73555da3a4cdaea Author: Eli Zaretskii Date: Sat Jan 2 10:27:28 2021 +0200 Fix last change * doc/lispref/strings.texi (Creating Strings): Improve wording of last change. (Bug#45516) diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index a033168a00..e4981cd603 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -120,9 +120,9 @@ character (i.e., an integer), @code{nil} otherwise. @cindex string creation The following functions create strings, either from scratch, or by -putting strings together, or by taking them apart. (For functions that -create strings based on searching the contents of other strings (like -@code{string-replace} and @code{replace-regexp-in-string}), see +putting strings together, or by taking them apart. (For functions +that create strings based on the modified contents of other strings, +like @code{string-replace} and @code{replace-regexp-in-string}, see @ref{Search and Replace}.) @defun make-string count character &optional multibyte commit ec1e1f80e6fa6a219f78969e495c0d1022bd0750 Author: Lars Ingebrigtsen Date: Tue Dec 29 02:19:03 2020 +0100 Add a reference between the Strings node and Search/Replace * doc/lispref/strings.texi (Creating Strings): Mention string-replace/replace-regexp-in-string (bug#45516). (cherry picked from commit b9359d4183a1a6923122d3aa12b922ab89693354) diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 0f0ce13dfe..a033168a00 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -120,7 +120,10 @@ character (i.e., an integer), @code{nil} otherwise. @cindex string creation The following functions create strings, either from scratch, or by -putting strings together, or by taking them apart. +putting strings together, or by taking them apart. (For functions that +create strings based on searching the contents of other strings (like +@code{string-replace} and @code{replace-regexp-in-string}), see +@ref{Search and Replace}.) @defun make-string count character &optional multibyte This function returns a string made up of @var{count} repetitions of commit 0f561ee55348ff451600cc6027db5940ee14606f Author: Dmitry Gutov Date: Sat Jan 2 04:18:59 2021 +0200 ruby-smie-rules: Avoid one case of infinite recursion * lisp/progmodes/ruby-mode.el (ruby-smie-rules): Avoid one case of infinite recursion (bug#29107). diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 155a1609d3..3effb6ed66 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -598,7 +598,7 @@ It is used when `ruby-encoding-magic-comment-style' is set to `custom'." (`(:before . ,(or "(" "[" "{")) (cond ((and (equal token "{") - (not (smie-rule-prev-p "(" "{" "[" "," "=>" "=" "return" ";")) + (not (smie-rule-prev-p "(" "{" "[" "," "=>" "=" "return" ";" "do")) (save-excursion (forward-comment -1) (not (eq (preceding-char) ?:)))) commit 1c5208ba71156d225b54592e5e36788748f48ade Author: Alan Third Date: Sat Dec 19 20:46:55 2020 +0000 Fix GNUstep warnings * src/nsterm.h: EmacsSurface is only required if NS_DRAW_TO_BUFFER is defined. * src/nsterm.m (ns_judge_scroll_bars): Remove unused variable. * src/nsmenu.m (update_frame_tool_bar): (ns_update_menubar): Remove unused variables. diff --git a/src/nsmenu.m b/src/nsmenu.m index 2e0b2c172b..9b56958100 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -956,15 +956,12 @@ - (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f int i, k = 0; EmacsView *view = FRAME_NS_VIEW (f); EmacsToolbar *toolbar = [view toolbar]; - int oldh; NSTRACE ("update_frame_tool_bar"); if (view == nil || toolbar == nil) return; block_input (); - oldh = FRAME_TOOLBAR_HEIGHT (f); - #ifdef NS_IMPL_COCOA [toolbar clearActive]; #else diff --git a/src/nsterm.h b/src/nsterm.h index 9d3ac75caf..3fb64494f7 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -705,7 +705,7 @@ typedef id instancetype; + (CGFloat)scrollerWidth; @end - +#ifdef NS_DRAW_TO_BUFFER @interface EmacsSurface : NSObject { NSMutableArray *cache; @@ -722,6 +722,7 @@ typedef id instancetype; - (void) releaseContext; - (IOSurfaceRef) getSurface; @end +#endif /* ========================================================================== diff --git a/src/nsterm.m b/src/nsterm.m index e0db204fbc..a4ee147693 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -5080,15 +5080,13 @@ in certain situations (rapid incoming events). id view; EmacsView *eview = FRAME_NS_VIEW (f); NSArray *subviews = [[eview superview] subviews]; - BOOL removed = NO; NSTRACE ("ns_judge_scroll_bars"); for (i = [subviews count]-1; i >= 0; --i) { view = [subviews objectAtIndex: i]; if (![view isKindOfClass: [EmacsScroller class]]) continue; - if ([view judge]) - removed = YES; + [view judge]; } } commit 107978365e17ede02d85b52fcbd99512dcc87428 Author: Alan Third Date: Wed Dec 16 21:12:04 2020 +0000 Improve drawing performance on macOS * configure.ac: Require IOSurface framework. * src/nsterm.h: New EmacsSurface class and update EmacsView definitions. * src/nsterm.m (ns_update_end): (ns_unfocus): Use new unfocusDrawingBuffer method. (ns_draw_window_cursor): Move ns_focus to before we set colors. ([EmacsView dealloc]): ([EmacsView viewDidResize:]): Handle new EmacsSurface class. ([EmacsView initFrameFromEmacs:]): Remove reference to old method. ([EmacsView createDrawingBuffer]): Remove method. ([EmacsView focusOnDrawingBuffer]): ([EmacsView windowDidChangeBackingProperties:]): Use new EmacsSurface class. ([EmacsView unfocusDrawingBuffer]): New method. ([EmacsView copyRect:to:]): Get information from the context instead of direct from the IOSurface. ([EmacsView updateLayer]): Use new EmacsSurface class. ([EmacsView copyRect:to:]): Use memcpy to copy bits around instead of using NS image functions. ([EmacsSurface initWithSize:ColorSpace:]): ([EmacsSurface dealloc]): ([EmacsSurface getSize]): ([EmacsSurface getContext]): ([EmacsSurface releaseContext]): ([EmacsSurface getSurface]): ([EmacsSurface copyContentsTo:]): New class and methods. diff --git a/configure.ac b/configure.ac index 5f822fe951..bcc0be7de0 100644 --- a/configure.ac +++ b/configure.ac @@ -5496,7 +5496,7 @@ case "$opsys" in if test "$HAVE_NS" = "yes"; then libs_nsgui="-framework AppKit" if test "$NS_IMPL_COCOA" = "yes"; then - libs_nsgui="$libs_nsgui -framework IOKit -framework Carbon" + libs_nsgui="$libs_nsgui -framework IOKit -framework Carbon -framework IOSurface" fi else libs_nsgui= diff --git a/src/nsterm.h b/src/nsterm.h index c17a0c0135..9d3ac75caf 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -414,6 +414,7 @@ typedef id instancetype; ========================================================================== */ @class EmacsToolbar; +@class EmacsSurface; #ifdef NS_IMPL_COCOA @interface EmacsView : NSView @@ -435,7 +436,7 @@ typedef id instancetype; BOOL fs_is_native; BOOL in_fullscreen_transition; #ifdef NS_DRAW_TO_BUFFER - CGContextRef drawingBuffer; + EmacsSurface *surface; #endif @public struct frame *emacsframe; @@ -478,7 +479,7 @@ typedef id instancetype; #ifdef NS_DRAW_TO_BUFFER - (void)focusOnDrawingBuffer; -- (void)createDrawingBuffer; +- (void)unfocusDrawingBuffer; #endif - (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect; @@ -705,6 +706,24 @@ typedef id instancetype; @end +@interface EmacsSurface : NSObject +{ + NSMutableArray *cache; + NSSize size; + CGColorSpaceRef colorSpace; + IOSurfaceRef currentSurface; + IOSurfaceRef lastSurface; + CGContextRef context; +} +- (id) initWithSize: (NSSize)s ColorSpace: (CGColorSpaceRef)cs; +- (void) dealloc; +- (NSSize) getSize; +- (CGContextRef) getContext; +- (void) releaseContext; +- (IOSurfaceRef) getSurface; +@end + + /* ========================================================================== Rendering diff --git a/src/nsterm.m b/src/nsterm.m index b34974f1bf..e0db204fbc 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -72,6 +72,10 @@ Updated by Christian Limpach (chris@nice.ch) #include #endif +#ifdef NS_DRAW_TO_BUFFER +#include +#endif + static EmacsMenu *dockMenu; #ifdef NS_IMPL_COCOA static EmacsMenu *mainMenu; @@ -1147,7 +1151,7 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen) if ([FRAME_NS_VIEW (f) wantsUpdateLayer]) { #endif - [NSGraphicsContext setCurrentContext:nil]; + [FRAME_NS_VIEW (f) unfocusDrawingBuffer]; #if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 } else @@ -1255,6 +1259,8 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen) if ([FRAME_NS_VIEW (f) wantsUpdateLayer]) { #endif + if (! ns_updating_frame) + [FRAME_NS_VIEW (f) unfocusDrawingBuffer]; [FRAME_NS_VIEW (f) setNeedsDisplay:YES]; #if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 } @@ -3386,6 +3392,8 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. /* Prevent the cursor from being drawn outside the text area. */ r = NSIntersectionRect (r, ns_row_rect (w, glyph_row, TEXT_AREA)); + ns_focus (f, &r, 1); + face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id); if (face && NS_FACE_BACKGROUND (face) == ns_index_color (FRAME_CURSOR_COLOR (f), f)) @@ -3396,8 +3404,6 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. else [FRAME_CURSOR_COLOR (f) set]; - ns_focus (f, &r, 1); - switch (cursor_type) { case DEFAULT_CURSOR: @@ -6267,7 +6273,7 @@ - (void)dealloc object:nil]; #ifdef NS_DRAW_TO_BUFFER - CGContextRelease (drawingBuffer); + [surface release]; #endif [toolbar release]; @@ -7290,8 +7296,9 @@ - (void)viewDidResize:(NSNotification *)notification if ([self wantsUpdateLayer]) { CGFloat scale = [[self window] backingScaleFactor]; - int oldw = (CGFloat)CGBitmapContextGetWidth (drawingBuffer) / scale; - int oldh = (CGFloat)CGBitmapContextGetHeight (drawingBuffer) / scale; + NSSize size = [surface getSize]; + int oldw = size.width / scale; + int oldh = size.height / scale; NSTRACE_SIZE ("Original size", NSMakeSize (oldw, oldh)); @@ -7301,6 +7308,9 @@ - (void)viewDidResize:(NSNotification *)notification NSTRACE_MSG ("No change"); return; } + + [surface release]; + surface = nil; } #endif @@ -7313,9 +7323,6 @@ - (void)viewDidResize:(NSNotification *)notification FRAME_PIXEL_TO_TEXT_HEIGHT (emacsframe, newh), 0, YES, 0, 1); -#ifdef NS_DRAW_TO_BUFFER - [self createDrawingBuffer]; -#endif SET_FRAME_GARBAGED (emacsframe); cancel_mouse_face (emacsframe); } @@ -7586,10 +7593,6 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f [NSApp registerServicesMenuSendTypes: ns_send_types returnTypes: [NSArray array]]; -#ifdef NS_DRAW_TO_BUFFER - [self createDrawingBuffer]; -#endif - /* Set up view resize notifications. */ [self setPostsFrameChangedNotifications:YES]; [[NSNotificationCenter defaultCenter] @@ -8309,45 +8312,41 @@ - (instancetype)toggleToolbar: (id)sender #ifdef NS_DRAW_TO_BUFFER -- (void)createDrawingBuffer - /* Create and store a new CGGraphicsContext for Emacs to draw into. - - We can't do this in GNUstep as there's no equivalent, so under - GNUstep we retain the old method of drawing direct to the - EmacsView. */ +- (void)focusOnDrawingBuffer { - NSTRACE ("EmacsView createDrawingBuffer]"); + CGFloat scale = [[self window] backingScaleFactor]; - if (! [self wantsUpdateLayer]) - return; + NSTRACE ("[EmacsView focusOnDrawingBuffer]"); - NSGraphicsContext *screen; - CGColorSpaceRef colorSpace = [[[self window] colorSpace] CGColorSpace]; - CGFloat scale = [[self window] backingScaleFactor]; - NSRect frame = [self frame]; + if (! surface) + { + NSRect frame = [self frame]; + NSSize s = NSMakeSize (NSWidth (frame) * scale, NSHeight (frame) * scale); + + surface = [[EmacsSurface alloc] initWithSize:s + ColorSpace:[[[self window] colorSpace] + CGColorSpace]]; + } - if (drawingBuffer != nil) - CGContextRelease (drawingBuffer); + CGContextRef context = [surface getContext]; - drawingBuffer = CGBitmapContextCreate (nil, NSWidth (frame) * scale, NSHeight (frame) * scale, - 8, 0, colorSpace, - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); + CGContextTranslateCTM(context, 0, [surface getSize].height); + CGContextScaleCTM(context, scale, -scale); - /* This fixes the scale to match the backing scale factor, and flips the image. */ - CGContextTranslateCTM(drawingBuffer, 0, NSHeight (frame) * scale); - CGContextScaleCTM(drawingBuffer, scale, -scale); + [NSGraphicsContext + setCurrentContext:[NSGraphicsContext + graphicsContextWithCGContext:context + flipped:YES]]; } -- (void)focusOnDrawingBuffer +- (void)unfocusDrawingBuffer { - NSTRACE ("EmacsView focusOnDrawingBuffer]"); + NSTRACE ("[EmacsView unfocusDrawingBuffer]"); - NSGraphicsContext *buf = - [NSGraphicsContext - graphicsContextWithCGContext:drawingBuffer flipped:YES]; - - [NSGraphicsContext setCurrentContext:buf]; + [NSGraphicsContext setCurrentContext:nil]; + [surface releaseContext]; + [self setNeedsDisplay:YES]; } @@ -8356,11 +8355,11 @@ - (void)windowDidChangeBackingProperties:(NSNotification *)notification { NSTRACE ("EmacsView windowDidChangeBackingProperties:]"); - if (! [self wantsUpdateLayer]) - return; - NSRect frame = [self frame]; - [self createDrawingBuffer]; + + [surface release]; + surface = nil; + ns_clear_frame (emacsframe); expose_frame (emacsframe, 0, 0, NSWidth (frame), NSHeight (frame)); } @@ -8378,33 +8377,28 @@ - (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect if ([self wantsUpdateLayer]) { #endif - CGImageRef copy; - NSRect frame = [self frame]; - NSAffineTransform *setOrigin = [NSAffineTransform transform]; - - [[NSGraphicsContext currentContext] saveGraphicsState]; - - /* Set the clipping before messing with the buffer's - orientation. */ - NSRectClip (dstRect); - - /* Unflip the buffer as the copied image will be unflipped, and - offset the top left so when we draw back into the buffer the - correct part of the image is drawn. */ - CGContextScaleCTM(drawingBuffer, 1, -1); - CGContextTranslateCTM(drawingBuffer, - NSMinX (dstRect) - NSMinX (srcRect), - -NSHeight (frame) - (NSMinY (dstRect) - NSMinY (srcRect))); - - /* Take a copy of the buffer and then draw it back to the buffer, - limited by the clipping rectangle. */ - copy = CGBitmapContextCreateImage (drawingBuffer); - CGContextDrawImage (drawingBuffer, frame, copy); - - CGImageRelease (copy); - - [[NSGraphicsContext currentContext] restoreGraphicsState]; - [self setNeedsDisplayInRect:dstRect]; + double scale = [[self window] backingScaleFactor]; + CGContextRef context = [[NSGraphicsContext currentContext] CGContext]; + int bpp = CGBitmapContextGetBitsPerPixel (context) / 8; + void *pixels = CGBitmapContextGetData (context); + int rowSize = CGBitmapContextGetBytesPerRow (context); + int srcRowSize = NSWidth (srcRect) * scale * bpp; + void *srcPixels = pixels + (int)(NSMinY (srcRect) * scale * rowSize + + NSMinX (srcRect) * scale * bpp); + void *dstPixels = pixels + (int)(NSMinY (dstRect) * scale * rowSize + + NSMinX (dstRect) * scale * bpp); + + if (NSIntersectsRect (srcRect, dstRect) + && NSMinY (srcRect) < NSMinY (dstRect)) + for (int y = NSHeight (srcRect) * scale - 1 ; y >= 0 ; y--) + memmove (dstPixels + y * rowSize, + srcPixels + y * rowSize, + srcRowSize); + else + for (int y = 0 ; y < NSHeight (srcRect) * scale ; y++) + memmove (dstPixels + y * rowSize, + srcPixels + y * rowSize, + srcRowSize); #if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 } @@ -8445,9 +8439,12 @@ - (void)updateLayer { NSTRACE ("[EmacsView updateLayer]"); - CGImageRef contentsImage = CGBitmapContextCreateImage(drawingBuffer); - [[self layer] setContents:(id)contentsImage]; - CGImageRelease(contentsImage); + /* This can fail to update the screen if the same surface is + provided twice in a row, even if its contents have changed. + There's a private method, -[CALayer setContentsChanged], that we + could use to force it, but we shouldn't often get the same + surface twice in a row. */ + [[self layer] setContents:(id)[surface getSurface]]; } #endif @@ -9490,6 +9487,210 @@ - (void) scrollWheel: (NSEvent *)theEvent @end /* EmacsScroller */ +#ifdef NS_DRAW_TO_BUFFER + +/* ========================================================================== + + A class to handle the screen buffer. + + ========================================================================== */ + +@implementation EmacsSurface + + +/* An IOSurface is a pixel buffer that is efficiently copied to VRAM + for display. In order to use an IOSurface we must first lock it, + write to it, then unlock it. At this point it is transferred to + VRAM and if we modify it during this transfer we may see corruption + of the output. To avoid this problem we can check if the surface + is "in use", and if it is then avoid using it. Unfortunately to + avoid writing to a surface that's in use, but still maintain the + ability to draw to the screen at any time, we need to keep a cache + of multiple surfaces that we can use at will. + + The EmacsSurface class maintains this cache of surfaces, and + handles the conversion to a CGGraphicsContext that AppKit can use + to draw on. + + The cache is simple: if a free surface is found it is removed from + the cache and set as the "current" surface. Once Emacs is done + with drawing to the current surface, the previous surface that was + drawn to is added to the cache for reuse, and the current one is + set as the last surface. If no free surfaces are found in the + cache then a new one is created. + + When AppKit wants to update the screen, we provide it with the last + surface, as that has the most recent data. + + FIXME: It is possible for the cache to grow if Emacs draws faster + than the surfaces can be drawn to the screen, so there should + probably be some sort of pruning job that removes excess + surfaces. */ + + +- (id) initWithSize: (NSSize)s + ColorSpace: (CGColorSpaceRef)cs +{ + NSTRACE ("[EmacsSurface initWithSize:ColorSpace:]"); + + [super init]; + + cache = [[NSMutableArray arrayWithCapacity:3] retain]; + size = s; + colorSpace = cs; + + return self; +} + + +- (void) dealloc +{ + if (context) + CGContextRelease (context); + + if (currentSurface) + CFRelease (currentSurface); + if (lastSurface) + CFRelease (lastSurface); + + for (id object in cache) + CFRelease ((IOSurfaceRef)object); + + [cache removeAllObjects]; + + [super dealloc]; +} + + +/* Return the size values our cached data is using. */ +- (NSSize) getSize +{ + return size; +} + + +/* Return a CGContextRef that can be used for drawing to the screen. + This must ALWAYS be paired with a call to releaseContext, and the + calls cannot be nested. */ +- (CGContextRef) getContext +{ + IOSurfaceRef surface = NULL; + + NSTRACE ("[EmacsSurface getContextWithSize:]"); + NSTRACE_MSG (@"IOSurface count: %lu", [cache count] + (lastSurface ? 1 : 0)); + + for (id object in cache) + { + if (!IOSurfaceIsInUse ((IOSurfaceRef)object)) + { + surface = (IOSurfaceRef)object; + [cache removeObject:object]; + break; + } + } + + if (!surface) + { + int bytesPerRow = IOSurfaceAlignProperty (kIOSurfaceBytesPerRow, + size.width * 4); + + surface = IOSurfaceCreate + ((CFDictionaryRef)@{(id)kIOSurfaceWidth:[NSNumber numberWithInt:size.width], + (id)kIOSurfaceHeight:[NSNumber numberWithInt:size.height], + (id)kIOSurfaceBytesPerRow:[NSNumber numberWithInt:bytesPerRow], + (id)kIOSurfaceBytesPerElement:[NSNumber numberWithInt:4], + (id)kIOSurfacePixelFormat:[NSNumber numberWithUnsignedInt:'BGRA']}); + } + + IOReturn lockStatus = IOSurfaceLock (surface, 0, nil); + if (lockStatus != kIOReturnSuccess) + NSLog (@"Failed to lock surface: %x", lockStatus); + + [self copyContentsTo:surface]; + + currentSurface = surface; + + context = CGBitmapContextCreate (IOSurfaceGetBaseAddress (currentSurface), + IOSurfaceGetWidth (currentSurface), + IOSurfaceGetHeight (currentSurface), + 8, + IOSurfaceGetBytesPerRow (currentSurface), + colorSpace, + (kCGImageAlphaPremultipliedFirst + | kCGBitmapByteOrder32Host)); + return context; +} + + +/* Releases the CGGraphicsContext and unlocks the associated + IOSurface, so it will be sent to VRAM. */ +- (void) releaseContext +{ + NSTRACE ("[EmacsSurface releaseContextAndGetSurface]"); + + CGContextRelease (context); + context = NULL; + + IOReturn lockStatus = IOSurfaceUnlock (currentSurface, 0, nil); + if (lockStatus != kIOReturnSuccess) + NSLog (@"Failed to unlock surface: %x", lockStatus); + + /* Put lastSurface back on the end of the cache. It may not have + been displayed on the screen yet, but we probably want the new + data and not some stale data anyway. */ + if (lastSurface) + [cache addObject:(id)lastSurface]; + lastSurface = currentSurface; + currentSurface = NULL; +} + + +/* Get the IOSurface that we want to draw to the screen. */ +- (IOSurfaceRef) getSurface +{ + /* lastSurface always contains the most up-to-date and complete data. */ + return lastSurface; +} + + +/* Copy the contents of lastSurface to DESTINATION. This is required + every time we want to use an IOSurface as its contents are probably + blanks (if it's new), or stale. */ +- (void) copyContentsTo: (IOSurfaceRef) destination +{ + IOReturn lockStatus; + void *sourceData, *destinationData; + int numBytes = IOSurfaceGetAllocSize (destination); + + NSTRACE ("[EmacsSurface copyContentsTo:]"); + + if (! lastSurface) + return; + + lockStatus = IOSurfaceLock (lastSurface, kIOSurfaceLockReadOnly, nil); + if (lockStatus != kIOReturnSuccess) + NSLog (@"Failed to lock source surface: %x", lockStatus); + + sourceData = IOSurfaceGetBaseAddress (lastSurface); + destinationData = IOSurfaceGetBaseAddress (destination); + + /* Since every IOSurface should have the exact same settings, a + memcpy seems like the fastest way to copy the data from one to + the other. */ + memcpy (destinationData, sourceData, numBytes); + + lockStatus = IOSurfaceUnlock (lastSurface, kIOSurfaceLockReadOnly, nil); + if (lockStatus != kIOReturnSuccess) + NSLog (@"Failed to unlock source surface: %x", lockStatus); +} + + +@end /* EmacsSurface */ + + +#endif + + #ifdef NS_IMPL_GNUSTEP /* Dummy class to get rid of startup warnings. */ @implementation EmacsDocument commit aac17c9dca21462df57367123301b7c940f9243a Author: Roland Winkler Date: Fri Jan 1 16:35:15 2021 -0600 bibtex-mode: Handle biblatex field aliases (bug#44976) * lisp/textmodes/bibtex.el (bibtex-biblatex-entry-alist): Define field aliases. (bibtex-vec-incr): Remove. (bibtex-format-entry, bibtex-validate): Check for field aliases. (bibtex--skip-field-aliases): New function. (bibtex-field-list): Use it. diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el index f64629d0ea..d238b6037e 100644 --- a/lisp/textmodes/bibtex.el +++ b/lisp/textmodes/bibtex.el @@ -477,280 +477,376 @@ COMMENT is the comment string that appears in the echo area. If COMMENT is nil use `bibtex-BibTeX-field-alist' if possible. INIT is either the initial content of the field or a function, which is called to determine the initial content of the field. -ALTERNATIVE if non-nil is an integer that numbers sets of -alternatives, starting from zero." +ALTERNATIVE if non-nil is an integer N that numbers sets of +alternatives. A negative integer -N indicates an alias for the +field +N. Such aliases are ignored by `bibtex-entry' in the template +for a new entry." :group 'bibtex - :version "26.1" ; add Conference + :version "28.1" ; extend alternatives :type 'bibtex-entry-alist :risky t) (defcustom bibtex-biblatex-entry-alist ;; Compare in biblatex documentation: ;; Sec. 2.1.1 Regular types (required and optional fields) + ;; Sec. 2.2.5 Field Aliases ;; Appendix A Default Crossref setup '(("Article" "Article in Journal" - (("author") ("title") ("journaltitle") - ("year" nil nil 0) ("date" nil nil 0)) + (("author") ("title") + ("journaltitle" nil nil 3) ("journal" nil nil -3) + ("date" nil nil 1) ("year" nil nil -1)) nil (("translator") ("annotator") ("commentator") ("subtitle") ("titleaddon") ("editor") ("editora") ("editorb") ("editorc") ("journalsubtitle") ("journaltitleaddon") ("issuetitle") ("issuesubtitle") ("issuetitleaddon") ("language") ("origlanguage") ("series") ("volume") ("number") ("eid") ("issue") ("month") ("pages") ("version") ("note") ("issn") - ("addendum") ("pubstate") ("doi") ("eprint") ("eprintclass") - ("eprinttype") ("url") ("urldate"))) + ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("Book" "Single-Volume Book" - (("author") ("title") ("year" nil nil 0) ("date" nil nil 0)) + (("author") ("title") + ("date" nil nil 1) ("year" nil nil -1)) nil (("editor") ("editora") ("editorb") ("editorc") ("translator") ("annotator") ("commentator") ("introduction") ("foreword") ("afterword") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle") ("maintitleaddon") ("language") ("origlanguage") ("volume") ("part") ("edition") ("volumes") - ("series") ("number") ("note") ("publisher") ("location") ("isbn") ("eid") + ("series") ("number") ("note") ("publisher") + ("location" nil nil 2) ("address" nil nil -2) ("isbn") ("eid") ("chapter") ("pages") ("pagetotal") ("addendum") ("pubstate") ("doi") - ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("MVBook" "Multi-Volume Book" - (("author") ("title") ("year" nil nil 0) ("date" nil nil 0)) + (("author") ("title") + ("date" nil nil 1) ("year" nil nil -1)) nil (("editor") ("editora") ("editorb") ("editorc") ("translator") ("annotator") ("commentator") ("introduction") ("foreword") ("afterword") ("subtitle") ("titleaddon") ("language") ("origlanguage") ("edition") ("volumes") ("series") ("number") ("note") ("publisher") - ("location") ("isbn") ("pagetotal") ("addendum") ("pubstate") ("doi") - ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("location" nil nil 2) ("address" nil nil -2) + ("isbn") ("pagetotal") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("InBook" "Chapter or Pages in a Book" - (("title") ("year" nil nil 0) ("date" nil nil 0)) + (("title") ("date" nil nil 1) ("year" nil nil -1)) (("author") ("booktitle")) (("bookauthor") ("editor") ("editora") ("editorb") ("editorc") ("translator") ("annotator") ("commentator") ("introduction") ("foreword") ("afterword") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle") ("maintitleaddon") ("booksubtitle") ("booktitleaddon") ("language") ("origlanguage") ("volume") ("part") ("edition") ("volumes") - ("series") ("number") ("note") ("publisher") ("location") ("isbn") ("eid") - ("chapter") ("pages") ("addendum") ("pubstate") - ("doi") ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("series") ("number") ("note") ("publisher") + ("location" nil nil 2) ("address" nil nil -2) ("isbn") ("eid") + ("chapter") ("pages") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("BookInBook" "Book in Collection" ; same as @inbook - (("title") ("year" nil nil 0) ("date" nil nil 0)) + (("title") ("date" nil nil 1) ("year" nil nil -1)) (("author") ("booktitle")) (("bookauthor") ("editor") ("editora") ("editorb") ("editorc") ("translator") ("annotator") ("commentator") ("introduction") ("foreword") ("afterword") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle") ("maintitleaddon") ("booksubtitle") ("booktitleaddon") ("language") ("origlanguage") ("volume") ("part") ("edition") ("volumes") - ("series") ("number") ("note") ("publisher") ("location") ("isbn") ("eid") - ("chapter") ("pages") ("addendum") ("pubstate") - ("doi") ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("series") ("number") ("note") ("publisher") + ("location" nil nil 2) ("address" nil nil -2) ("isbn") ("eid") + ("chapter") ("pages") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("SuppBook" "Supplemental Material in a Book" ; same as @inbook - (("title") ("year" nil nil 0) ("date" nil nil 0)) + (("title") ("date" nil nil 1) ("year" nil nil -1)) (("author") ("booktitle")) (("bookauthor") ("editor") ("editora") ("editorb") ("editorc") ("translator") ("annotator") ("commentator") ("introduction") ("foreword") ("afterword") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle") ("maintitleaddon") ("booksubtitle") ("booktitleaddon") ("language") ("origlanguage") ("volume") ("part") ("edition") ("volumes") - ("series") ("number") ("note") ("publisher") ("location") ("isbn") ("eid") - ("chapter") ("pages") ("addendum") ("pubstate") - ("doi") ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("series") ("number") ("note") ("publisher") + ("location" nil nil 2) ("address" nil nil -2) ("isbn") ("eid") + ("chapter") ("pages") ("addendum") ("pubstate") ("doi") + ("eprint")("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("Booklet" "Booklet (Bound, but no Publisher)" (("author" nil nil 0) ("editor" nil nil 0) ("title") - ("year" nil nil 1) ("date" nil nil 1)) + ("date" nil nil 1) ("year" nil nil -1)) nil (("subtitle") ("titleaddon") ("language") ("howpublished") ("type") - ("note") ("location") ("eid") ("chapter") ("pages") ("pagetotal") - ("addendum") ("pubstate") ("doi") ("eprint") ("eprintclass") - ("eprinttype") ("url") ("urldate"))) + ("note") ("location" nil nil 2) ("address" nil nil -2) + ("eid") ("chapter") ("pages") ("pagetotal") + ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("Collection" "Single-Volume Collection" - (("editor") ("title") ("year" nil nil 0) ("date" nil nil 0)) + (("editor") ("title") + ("date" nil nil 1) ("year" nil nil -1)) nil (("editora") ("editorb") ("editorc") ("translator") ("annotator") ("commentator") ("introduction") ("foreword") ("afterword") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle") ("maintitleaddon") ("language") ("origlanguage") ("volume") ("part") ("edition") ("volumes") ("series") ("number") ("note") - ("publisher") ("location") ("isbn") ("eid") ("chapter") ("pages") - ("pagetotal") ("addendum") ("pubstate") ("doi") ("eprint") ("eprintclass") - ("eprinttype") ("url") ("urldate"))) + ("publisher") ("location" nil nil 2) ("address" nil nil -2) + ("isbn") ("eid") ("chapter") ("pages") + ("pagetotal") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("MVCollection" "Multi-Volume Collection" - (("editor") ("title") ("year" nil nil 0) ("date" nil nil 0)) + (("editor") ("title") + ("date" nil nil 1) ("year" nil nil -1)) nil (("editora") ("editorb") ("editorc") ("translator") ("annotator") ("commentator") ("introduction") ("foreword") ("afterword") ("subtitle") ("titleaddon") ("language") ("origlanguage") ("edition") ("volumes") ("series") ("number") ("note") ("publisher") - ("location") ("isbn") ("pagetotal") ("addendum") ("pubstate") ("doi") - ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("location" nil nil 2) ("address" nil nil -2) + ("isbn") ("pagetotal") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("InCollection" "Article in a Collection" - (("author") ("title") ("year" nil nil 0) ("date" nil nil 0)) + (("author") ("title") + ("date" nil nil 1) ("year" nil nil -1)) (("booktitle")) (("editor") ("editora") ("editorb") ("editorc") ("translator") ("annotator") ("commentator") ("introduction") ("foreword") ("afterword") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle") ("maintitleaddon") ("booksubtitle") ("booktitleaddon") ("language") ("origlanguage") ("volume") ("part") ("edition") - ("volumes") ("series") ("number") ("note") ("publisher") ("location") + ("volumes") ("series") ("number") ("note") ("publisher") + ("location" nil nil 2) ("address" nil nil -2) ("isbn") ("eid") ("chapter") ("pages") ("addendum") ("pubstate") ("doi") - ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("SuppCollection" "Supplemental Material in a Collection" ; same as @incollection - (("author") ("title") ("year" nil nil 0) ("date" nil nil 0)) + (("author") ("title") + ("date" nil nil 1) ("year" nil nil -1)) (("booktitle")) (("editor") ("editora") ("editorb") ("editorc") ("translator") ("annotator") ("commentator") ("introduction") ("foreword") ("afterword") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle") ("maintitleaddon") ("booksubtitle") ("booktitleaddon") ("language") ("origlanguage") ("volume") ("part") ("edition") - ("volumes") ("series") ("number") ("note") ("publisher") ("location") + ("volumes") ("series") ("number") ("note") ("publisher") + ("location" nil nil 2) ("address" nil nil -2) ("isbn") ("eid") ("chapter") ("pages") ("addendum") ("pubstate") ("doi") - ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("Dataset" "Data Set" (("author" nil nil 0) ("editor" nil nil 0) ("title") - ("year" nil nil 1) ("date" nil nil 1)) + ("date" nil nil 1) ("year" nil nil -1)) nil (("subtitle") ("titleaddon") ("language") ("edition") ("type") ("series") ("number") ("version") ("note") ("organization") ("publisher") - ("location") ("addendum") ("pubstate") ("doi") ("eprint") ("eprintclass") - ("eprinttype") ("url") ("urldate"))) + ("location" nil nil 2) ("address" nil nil -2) + ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("Manual" "Technical Manual" (("author" nil nil 0) ("editor" nil nil 0) ("title") - ("year" nil nil 1) ("date" nil nil 1)) + ("date" nil nil 1) ("year" nil nil -1)) nil (("subtitle") ("titleaddon") ("language") ("edition") ("type") ("series") ("number") ("version") ("note") - ("organization") ("publisher") ("location") ("isbn") ("eid") ("chapter") - ("pages") ("pagetotal") ("addendum") ("pubstate") - ("doi") ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("organization") ("publisher") + ("location" nil nil 2) ("address" nil nil -2) + ("isbn") ("eid") ("chapter") + ("pages") ("pagetotal") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("Misc" "Miscellaneous" (("author" nil nil 0) ("editor" nil nil 0) ("title") - ("year" nil nil 1) ("date" nil nil 1)) + ("date" nil nil 1) ("year" nil nil -1)) nil (("subtitle") ("titleaddon") ("language") ("howpublished") ("type") - ("version") ("note") ("organization") ("location") - ("month") ("addendum") ("pubstate") - ("doi") ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("version") ("note") ("organization") + ("location" nil nil 2) ("address" nil nil -2) + ("month") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("Online" "Online Resource" (("author" nil nil 0) ("editor" nil nil 0) ("title") - ("year" nil nil 1) ("date" nil nil 1) + ("date" nil nil 1) ("year" nil nil -1) ("doi" nil nil 2) ("eprint" nil nil 2) ("url" nil nil 2)) nil (("subtitle") ("titleaddon") ("language") ("version") ("note") ("organization") ("month") ("addendum") - ("pubstate") ("eprintclass") ("eprinttype") ("urldate"))) + ("pubstate") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) ("urldate"))) ("Patent" "Patent" - (("author") ("title") ("number") ("year" nil nil 0) ("date" nil nil 0)) + (("author") ("title") ("number") + ("date" nil nil 1) ("year" nil nil -1)) nil - (("holder") ("subtitle") ("titleaddon") ("type") ("version") ("location") - ("note") ("month") ("addendum") ("pubstate") - ("doi") ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + (("holder") ("subtitle") ("titleaddon") ("type") ("version") + ("location" nil nil 2) ("address" nil nil -2) + ("note") ("month") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("Periodical" "Complete Issue of a Periodical" - (("editor") ("title") ("year" nil nil 0) ("date" nil nil 0)) + (("editor") ("title") + ("date" nil nil 1) ("year" nil nil -1)) nil (("editora") ("editorb") ("editorc") ("subtitle") ("titleaddon") ("issuetitle") ("issuesubtitle") ("issuetitleaddon") ("language") ("series") ("volume") ("number") ("issue") - ("month") ("note") ("issn") ("addendum") ("pubstate") - ("doi") ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("month") ("note") ("issn") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("SuppPeriodical" "Supplemental Material in a Periodical" ; same as @article - (("author") ("title") ("journaltitle") - ("year" nil nil 0) ("date" nil nil 0)) + (("author") ("title") + ("journaltitle" nil nil 3) ("journal" nil nil -3) + ("date" nil nil 1) ("year" nil nil -1)) nil (("translator") ("annotator") ("commentator") ("subtitle") ("titleaddon") ("editor") ("editora") ("editorb") ("editorc") ("journalsubtitle") ("journaltitleaddon") ("issuetitle") ("issuesubtitle") ("issuetitleaddon") ("language") ("origlanguage") ("series") ("volume") ("number") ("eid") ("issue") ("month") ("pages") ("version") ("note") ("issn") - ("addendum") ("pubstate") ("doi") ("eprint") ("eprintclass") - ("eprinttype") ("url") ("urldate"))) + ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("Proceedings" "Single-Volume Conference Proceedings" - (("title") ("year" nil nil 0) ("date" nil nil 0)) + (("title") ("date" nil nil 1) ("year" nil nil -1)) nil (("editor") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle") ("maintitleaddon") ("eventtitle") ("eventtitleaddon") ("eventdate") ("venue") ("language") ("volume") ("part") ("volumes") ("series") - ("number") ("note") ("organization") ("publisher") ("location") ("month") + ("number") ("note") ("organization") ("publisher") + ("location" nil nil 2) ("address" nil nil -2) ("month") ("isbn") ("eid") ("chapter") ("pages") ("pagetotal") ("addendum") - ("pubstate") ("doi") ("eprint") ("eprintclass") ("eprinttype") ("url") - ("urldate"))) + ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("MVProceedings" "Multi-Volume Conference Proceedings" - (("title") ("year" nil nil 0) ("date" nil nil 0)) + (("title") ("date" nil nil 1) ("year" nil nil -1)) nil (("editor") ("subtitle") ("titleaddon") ("eventtitle") ("eventtitleaddon") ("eventdate") ("venue") ("language") ("volumes") ("series") ("number") - ("note") ("organization") ("publisher") ("location") ("month") - ("isbn") ("pagetotal") ("addendum") ("pubstate") - ("doi") ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("note") ("organization") ("publisher") + ("location" nil nil 2) ("address" nil nil -2) ("month") + ("isbn") ("pagetotal") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("InProceedings" "Article in Conference Proceedings" - (("author") ("title") ("year" nil nil 0) ("date" nil nil 0)) + (("author") ("title") + ("date" nil nil 1) ("year" nil nil -1)) (("booktitle")) (("editor") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle") ("maintitleaddon") ("booksubtitle") ("booktitleaddon") ("eventtitle") ("eventtitleaddon") ("eventdate") ("venue") ("language") ("volume") ("part") ("volumes") ("series") ("number") ("note") - ("organization") ("publisher") ("location") ("month") ("isbn") ("eid") - ("chapter") ("pages") ("addendum") ("pubstate") - ("doi") ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("organization") ("publisher") + ("location" nil nil 2) ("address" nil nil -2) ("month") ("isbn") ("eid") + ("chapter") ("pages") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("Reference" "Single-Volume Work of Reference" ; same as @collection - (("editor") ("title") ("year" nil nil 0) ("date" nil nil 0)) + (("editor") ("title") ("date" nil nil 1) ("year" nil nil -1)) nil (("editora") ("editorb") ("editorc") ("translator") ("annotator") ("commentator") ("introduction") ("foreword") ("afterword") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle") ("maintitleaddon") ("language") ("origlanguage") ("volume") ("part") ("edition") ("volumes") ("series") ("number") ("note") - ("publisher") ("location") ("isbn") ("eid") ("chapter") ("pages") - ("pagetotal") ("addendum") ("pubstate") ("doi") ("eprint") ("eprintclass") - ("eprinttype") ("url") ("urldate"))) + ("publisher") ("location" nil nil 2) ("address" nil nil -2) + ("isbn") ("eid") ("chapter") ("pages") + ("pagetotal") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("MVReference" "Multi-Volume Work of Reference" ; same as @mvcollection - (("editor") ("title") ("year" nil nil 0) ("date" nil nil 0)) + (("editor") ("title") ("date" nil nil 1) ("year" nil nil -1)) nil (("editora") ("editorb") ("editorc") ("translator") ("annotator") ("commentator") ("introduction") ("foreword") ("afterword") ("subtitle") ("titleaddon") ("language") ("origlanguage") ("edition") ("volumes") ("series") ("number") ("note") ("publisher") - ("location") ("isbn") ("pagetotal") ("addendum") ("pubstate") ("doi") - ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("location" nil nil 2) ("address" nil nil -2) + ("isbn") ("pagetotal") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("InReference" "Article in a Work of Reference" ; same as @incollection - (("author") ("title") ("year" nil nil 0) ("date" nil nil 0)) + (("author") ("title") ("date" nil nil 1) ("year" nil nil -1)) (("booktitle")) (("editor") ("editora") ("editorb") ("editorc") ("translator") ("annotator") ("commentator") ("introduction") ("foreword") ("afterword") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle") ("maintitleaddon") ("booksubtitle") ("booktitleaddon") ("language") ("origlanguage") ("volume") ("part") ("edition") - ("volumes") ("series") ("number") ("note") ("publisher") ("location") + ("volumes") ("series") ("number") ("note") ("publisher") + ("location" nil nil 2) ("address" nil nil -2) ("isbn") ("eid") ("chapter") ("pages") ("addendum") ("pubstate") ("doi") - ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("Report" "Technical or Research Report" - (("author") ("title") ("type") ("institution") - ("year" nil nil 0) ("date" nil nil 0)) + (("author") ("title") ("type") + ("institution" nil nil 6) ("school" nil nil -6) + ("date" nil nil 1) ("year" nil nil -1)) nil (("subtitle") ("titleaddon") ("language") ("number") ("version") ("note") - ("location") ("month") ("isrn") ("eid") ("chapter") ("pages") - ("pagetotal") ("addendum") ("pubstate") - ("doi") ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("location" nil nil 2) ("address" nil nil -2) + ("month") ("isrn") ("eid") ("chapter") ("pages") + ("pagetotal") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("Software" "Computer Software" ; Same as @misc. (("author" nil nil 0) ("editor" nil nil 0) ("title") - ("year" nil nil 1) ("date" nil nil 1)) + ("date" nil nil 1) ("year" nil nil -1)) nil (("subtitle") ("titleaddon") ("language") ("howpublished") ("type") - ("version") ("note") ("organization") ("location") - ("month") ("addendum") ("pubstate") - ("doi") ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("version") ("note") ("organization") + ("location" nil nil 2) ("address" nil nil -2) + ("month") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("Thesis" "PhD or Master's Thesis" - (("author") ("title") ("type") ("institution") - ("year" nil nil 0) ("date" nil nil 0)) + (("author") ("title") ("type") + ("institution" nil nil 6) ("school" nil nil -6) + ("date" nil nil 1) ("year" nil nil -1)) nil - (("subtitle") ("titleaddon") ("language") ("note") ("location") + (("subtitle") ("titleaddon") ("language") ("note") + ("location" nil nil 2) ("address" nil nil -2) ("month") ("isbn") ("eid") ("chapter") ("pages") ("pagetotal") - ("addendum") ("pubstate") - ("doi") ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate"))) + ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate"))) ("Unpublished" "Unpublished" - (("author") ("title") ("year" nil nil 0) ("date" nil nil 0)) + (("author") ("title") ("date" nil nil 1) ("year" nil nil -1)) nil (("subtitle") ("titleaddon") ("type") ("eventtitle") ("eventtitleaddon") ("eventdate") ("venue") ("language") ("howpublished") ("note") - ("location") ("isbn") ("month") ("addendum") ("pubstate") ("doi") - ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate")))) + ("location" nil nil 2) ("address" nil nil -2) + ("isbn") ("month") ("addendum") ("pubstate") ("doi") + ("eprint") ("eprintclass" nil nil 4) ("primaryclass" nil nil -4) + ("eprinttype" nil nil 5) ("archiveprefix" nil nil -5) + ("url") ("urldate")))) "Alist of biblatex entry types and their associated fields. It has the same format as `bibtex-BibTeX-entry-alist'." :group 'bibtex @@ -2328,10 +2424,6 @@ Optional arg COMMA is as in `bibtex-enclosing-field'." "Add NEWELT to the list stored in VEC at index IDX." (aset vec idx (cons newelt (aref vec idx)))) -(defsubst bibtex-vec-incr (vec idx) - "Increment by 1 the counter which is stored in VEC at index IDX." - (aset vec idx (1+ (aref vec idx)))) - (defun bibtex-format-entry () "Helper function for `bibtex-clean-entry'. Formats current entry according to variable `bibtex-entry-format'." @@ -2352,7 +2444,8 @@ Formats current entry according to variable `bibtex-entry-format'." strings sort-fields) bibtex-entry-format)) (left-delim-re (regexp-quote (bibtex-field-left-delimiter))) - bounds crossref-key req-field-list default-field-list field-list + bounds crossref-key req-field-list opt-field-list + default-field-list field-list num-alt alt-fields idx error-field-name) (unwind-protect ;; formatting (undone if error occurs) @@ -2399,16 +2492,22 @@ Formats current entry according to variable `bibtex-entry-format'." ;; list of required fields appropriate for an entry with ;; or without crossref key. - (setq req-field-list (if crossref-key (nth 2 entry-list) - (append (nth 2 entry-list) (nth 3 entry-list))) + (setq req-field-list (append (nth 2 entry-list) + (unless crossref-key + (nth 3 entry-list))) + opt-field-list (append (if crossref-key + (nth 3 entry-list)) + (nth 4 entry-list) + bibtex-user-optional-fields) ;; default list of fields that may appear in this entry - default-field-list (append (nth 2 entry-list) (nth 3 entry-list) - (nth 4 entry-list) - bibtex-user-optional-fields) - ;; number of ALT fields we expect to find - num-alt (length (delq nil (delete-dups - (mapcar (lambda (x) (nth 3 x)) - req-field-list)))) + default-field-list (append req-field-list opt-field-list) + ;; number of ALT fields we may find + num-alt (let ((n 0)) + (mapc (lambda (x) + (if (nth 3 x) + (setq n (max n (abs (nth 3 x)))))) + default-field-list) + (1+ n)) ;; ALT fields of respective groups alt-fields (make-vector num-alt nil)) @@ -2447,8 +2546,9 @@ Formats current entry according to variable `bibtex-entry-format'." (if opt-alt (setq field-name (substring field-name 3))) ;; keep track of alternatives - (if (setq idx (nth 3 (assoc-string field-name req-field-list t))) - (bibtex-vec-push alt-fields idx field-name)) + (if (and (not empty-field) + (setq idx (nth 3 (assoc-string field-name default-field-list t)))) + (bibtex-vec-push alt-fields (abs idx) field-name)) (if (memq 'opts-or-alts format) ;; delete empty optional and alternative fields @@ -2597,34 +2697,34 @@ Formats current entry according to variable `bibtex-entry-format'." ;; check whether all required fields are present (when (memq 'required-fields format) - (let ((alt-expect (make-vector num-alt nil)) - (alt-found (make-vector num-alt 0))) + (let ((alt-expect (make-vector num-alt nil))) (dolist (fname req-field-list) - (cond ((setq idx (nth 3 fname)) - ;; t if field has alternative flag - (bibtex-vec-push alt-expect idx (car fname)) - (if (member-ignore-case (car fname) field-list) - (bibtex-vec-incr alt-found idx))) + (cond ((nth 3 fname) + ;; t if required field has alternative flag + (setq idx (abs (nth 3 fname))) + (bibtex-vec-push alt-expect idx (car fname))) ((not (member-ignore-case (car fname) field-list)) - ;; If we use the crossref field, a required field - ;; can have the OPT prefix. So if it was empty, - ;; we have deleted by now. Nonetheless we can - ;; move point on this empty field. - (setq error-field-name (car fname)) + (setq error-field-name (car fname)) (user-error "Mandatory field `%s' is missing" (car fname))))) (dotimes (idx num-alt) - (cond ((= 0 (aref alt-found idx)) + (cond ((and (aref alt-expect idx) + (not (aref alt-fields idx))) (setq error-field-name (car (last (aref alt-fields idx)))) - (user-error "Alternative mandatory field `%s' is missing" - (aref alt-expect idx))) - ((< 1 (aref alt-found idx)) + (user-error "Alternative mandatory fields `%s' are missing" + (mapconcat 'identity + (reverse + (aref alt-expect idx)) + ", "))) + ((nth 1 (aref alt-fields idx)) (setq error-field-name (car (last (aref alt-fields idx)))) - (user-error "Alternative fields `%s' are defined %s times" - (aref alt-expect idx) - (length (aref alt-fields idx)))))))) + (user-error "Fields `%s' are alternatives" + (mapconcat 'identity + (reverse + (aref alt-fields idx)) + ", "))))))) ;; update comma after last field (if (memq 'last-comma format) @@ -3653,8 +3753,7 @@ and `bibtex-user-optional-fields'." (setq required (append (nth 2 e-list) (nth 3 e-list)) optional (nth 4 e-list))) (if bibtex-include-OPTkey - (push (list "key" - "Crossref key" + (push (list "key" "Used as label with certain BibTeX styles" (if (or (stringp bibtex-include-OPTkey) (functionp bibtex-include-OPTkey)) bibtex-include-OPTkey)) @@ -3663,7 +3762,41 @@ and `bibtex-user-optional-fields'." (push '("crossref" "Reference key of the cross-referenced entry") optional)) (setq optional (append optional bibtex-user-optional-fields)) - (cons required optional))) + (cons (bibtex--skip-field-aliases required) + (bibtex--skip-field-aliases optional)))) + +(defun bibtex--skip-field-aliases (list) + "Skip fields in LIST that are aliases, return the shortened list. +Aliases are fields for which the element ALTERNATIVE is a negative number, +see `bibtex-BibTeX-entry-alist'. The shortened field list is used +for the templates of `bibtex-entry', whereas entry validation performed by +`bibtex-format-entry' uses the full list of fields for an entry." + ;; FIXME: `bibtex-entry' and `bibtex-format-entry' handle aliases + ;; under the hood in a manner that is largely invisible to users. + ;; If instead one wanted to display the aliases as alternatives + ;; in the usual way, field names may get both the ALT and the OPT prefix. + ;; That gets rather clumsy. Also, the code currently assumes that + ;; field names have either the ALT or the OPT prefix, but not both. + ;; Are there scenarios when it would be useful to display both? + (let (alt-list new-list) + (dolist (elt list) ; identify alternatives + (if (and (nth 3 elt) + (<= 0 (nth 3 elt))) + (push (nth 3 elt) alt-list))) + (setq alt-list (sort alt-list '<)) + ;; Skip aliases. If ELT is marked as "proper alternative", but all + ;; alternatives for field ELT are aliases, we do not label ELT + ;; as an alternative either. + (dolist (elt list) + (let ((alt (nth 3 elt))) + (if alt + (if (<= 0 alt) + (push (if (eq alt (cadr (memq alt alt-list))) + elt ; ELT has proper alternatives + (butlast elt)) ; alternatives of ELT are alias + new-list)) + (push elt new-list)))) + (reverse new-list))) (defun bibtex-entry (entry-type) "Insert a template for a BibTeX entry of type ENTRY-TYPE. @@ -4399,12 +4532,19 @@ Return t if test was successful, nil otherwise." (entry-list (assoc-string (bibtex-type-in-head) bibtex-entry-alist t)) (crossref (bibtex-search-forward-field "crossref" end)) - (req (if crossref (copy-sequence (nth 2 entry-list)) - (append (nth 2 entry-list) + (req (append (nth 2 entry-list) + (unless crossref (copy-sequence (nth 3 entry-list))))) - (num-alt (length (delq nil (delete-dups - (mapcar (lambda (x) (nth 3 x)) - req))))) + (opt (append (if crossref (nth 3 entry-list)) + (nth 4 entry-list) + bibtex-user-optional-fields)) + (default (append req opt)) + (num-alt (let ((n 0)) + (mapc (lambda (x) + (if (nth 3 x) + (setq n (max n (abs (nth 3 x)))))) + default) + (1+ n))) (alt-fields (make-vector num-alt nil)) bounds field idx) (while (setq bounds (bibtex-parse-field)) @@ -4419,7 +4559,7 @@ Return t if test was successful, nil otherwise." (push (cons (bibtex-current-line) "Questionable month field") error-list)) - (setq field (assoc-string field-name req t) + (setq field (assoc-string field-name default t) req (delete field req)) (if (setq idx (nth 3 field)) (if (aref alt-fields idx) @@ -4438,12 +4578,13 @@ Return t if test was successful, nil otherwise." (car field))) error-list))) (dotimes (idx num-alt) - (unless (aref alt-fields idx) - (push (cons beg-line - (format-message - "Alternative fields `%s' missing" - (aref alt-expect idx))) - error-list)))))))) + (if (and (aref alt-expect idx) + (not (aref alt-fields idx))) + (push (cons beg-line + (format-message + "Alternative fields `%s' missing" + (aref alt-expect idx))) + error-list)))))))) (bibtex-progress-message 'done))))) (if error-list commit aa2739bf1b9a045d94220b607c03b21dbbb7959d Author: Paul Eggert Date: Fri Jan 1 12:57:26 2021 -0800 Fix CCL_MOD typo * src/ccl.c (ccl_driver): Fix typo that disabled the checks for undefined behavior with integer remainder. Problem caught by Oracle Studio 12.6. diff --git a/src/ccl.c b/src/ccl.c index 629cb70294..7c033afc88 100644 --- a/src/ccl.c +++ b/src/ccl.c @@ -1151,7 +1151,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size if (!INT_DIVIDE_OVERFLOW (reg[rrr], i)) reg[rrr] /= i; break; - case CCL_MOD: reg[rrr] %= i; break; + case CCL_MOD: if (!i) CCL_INVALID_CMD; reg[rrr] = i == -1 ? 0 : reg[rrr] % i; commit a1f603f0a388a519771ef77ae18f44a448a81c5a Author: Paul Eggert Date: Fri Jan 1 12:55:35 2021 -0800 Add overflow check for INPUT_EVENT_POS_MIN * src/keyboard.c (INPUT_EVENT_POS_MIN): Don’t assume (-1 - INPUT_EVENT_POS_MAX) fits into ptrdiff_t. This fixes a purely-theoretical problem that cannot occur on two’s-complement arithmetic. The Solaris 10 compiler still complains incorrectly, but oh well. diff --git a/src/keyboard.c b/src/keyboard.c index 0cf7adae74..d2f0cb405f 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -3647,7 +3647,8 @@ kbd_buffer_unget_event (struct selection_input_event *event) #define INPUT_EVENT_POS_MAX \ ((ptrdiff_t) min (PTRDIFF_MAX, min (TYPE_MAXIMUM (Time) / 2, \ MOST_POSITIVE_FIXNUM))) -#define INPUT_EVENT_POS_MIN (-1 - INPUT_EVENT_POS_MAX) +#define INPUT_EVENT_POS_MIN (PTRDIFF_MIN < -INPUT_EVENT_POS_MAX \ + ? -1 - INPUT_EVENT_POS_MAX : PTRDIFF_MIN) /* Return a Time that encodes position POS. POS must be in range. */ commit 9076a631fe331763414a5d323496846d563ccaa0 Author: Paul Eggert Date: Fri Jan 1 12:52:55 2021 -0800 Port to Solaris 10 * configure.ac: Instead of AC_CHECK_HEADER, use AC_COMPILE_IFELSE with X11/Intrinsic.h when checking for X11/extensions/Xrender.h. This suppresses a bogus "report a bug to bug-gnu-emacs" diagnostic from 'configure' in Solaris 10. (SETUP_SLAVE_PTY): Adjust to recent renaming of forkin to std_in in callproc.c. Needed on Solaris and Unixware. * lib-src/Makefile.in (LIB_GETRANDOM, LIBS_ETAGS): New vars, needed because on Solaris 10 the Gnulib tempname module now needs the -lrt library for clock_gettime. Throw in the LIB_GETRANDOM stuff too while we’re at it; from getrandom.m4 it seems to be needed for MingW. (LIBS_MOVE, etags_libs): Use them. * src/callproc.c [SETUP_SLAVE_PTY]: Include sys/stream.h and sys/stropts.h, for SETUP_SLAVE_PTY’s definiens. * src/process.c [NEED_BSDTTY]: Don’t include bsdtty.h; hasn’t been needed in years. [USG5_4]: Don’t include sys/stream.h or sys/stropts.h; these directives havbe been moved to callproc.c because the only use of SETUP_SLAVE_PTY is there now. diff --git a/configure.ac b/configure.ac index 574024af96..5f822fe951 100644 --- a/configure.ac +++ b/configure.ac @@ -3291,7 +3291,12 @@ fi # Check for XRender HAVE_XRENDER=no if test "${HAVE_X11}" = "yes"; then - AC_CHECK_HEADER([X11/extensions/Xrender.h], + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #include + ]], + [[return !XRenderQueryExtension;]])], [AC_CHECK_LIB([Xrender], [XRenderQueryExtension], [HAVE_XRENDER=yes])]) if test $HAVE_XRENDER = yes; then XRENDER_LIBS="-lXrender" @@ -4926,7 +4931,7 @@ case $opsys in AC_DEFINE(FIRST_PTY_LETTER, ['z']) AC_DEFINE(PTY_NAME_SPRINTF, [strcpy (pty_name, "/dev/ptmx");]) dnl Push various streams modules onto a PTY channel. Used in process.c. - AC_DEFINE(SETUP_SLAVE_PTY, [if (ioctl (forkin, I_PUSH, "ptem") == -1) fatal ("ioctl I_PUSH ptem"); if (ioctl (forkin, I_PUSH, "ldterm") == -1) fatal ("ioctl I_PUSH ldterm"); if (ioctl (forkin, I_PUSH, "ttcompat") == -1) fatal ("ioctl I_PUSH ttcompat");], [How to set up a slave PTY, if needed.]) + AC_DEFINE(SETUP_SLAVE_PTY, [if (ioctl (std_in, I_PUSH, "ptem") == -1) fatal ("ioctl I_PUSH ptem"); if (ioctl (std_in, I_PUSH, "ldterm") == -1) fatal ("ioctl I_PUSH ldterm"); if (ioctl (std_in, I_PUSH, "ttcompat") == -1) fatal ("ioctl I_PUSH ttcompat");], [How to set up a slave PTY, if needed.]) ;; esac diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in index 064342b4d3..0a6dd826c1 100644 --- a/lib-src/Makefile.in +++ b/lib-src/Makefile.in @@ -204,14 +204,19 @@ LIBRESOLV=@LIBRESOLV@ LIBS_MAIL=@LIBS_MAIL@ ## empty or -lrt or -lposix4 if HAVE_CLOCK_GETTIME LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +## empty or -lbcrypt or -ladvapi32 +LIB_GETRANDOM = @LIB_GETRANDOM@ ## Whatever libraries are needed for euidaccess LIB_EACCESS=@LIB_EACCESS@ ## empty or -lwsock2 for MinGW LIB_WSOCK32=@LIB_WSOCK32@ +## Extra libraries for etags +LIBS_ETAGS = $(LIB_CLOCK_GETTIME) $(LIB_GETRANDOM) + ## Extra libraries to use when linking movemail. LIBS_MOVE = $(LIBS_MAIL) $(KRB4LIB) $(DESLIB) $(KRB5LIB) $(CRYPTOLIB) \ - $(COM_ERRLIB) $(LIBHESIOD) $(LIBRESOLV) $(LIB_WSOCK32) + $(COM_ERRLIB) $(LIBHESIOD) $(LIBRESOLV) $(LIB_WSOCK32) $(LIBS_ETAGS) ## Extra libraries when linking emacsclient ## (empty or -lcomctl32 for MinGW) @@ -360,7 +365,7 @@ TAGS: etags${EXEEXT} ${tagsfiles} $(MAKE) -C ../lib all etags_deps = ${srcdir}/etags.c $(NTLIB) $(config_h) -etags_libs = $(NTLIB) $(LOADLIBES) +etags_libs = $(NTLIB) $(LOADLIBES) $(LIBS_ETAGS) etags${EXEEXT}: ${etags_deps} $(AM_V_CCLD)$(CC) ${ALL_CFLAGS} -o $@ $< $(etags_libs) diff --git a/src/callproc.c b/src/callproc.c index 7c5863e6ad..8d2a5619eb 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -30,6 +30,11 @@ along with GNU Emacs. If not, see . */ #include "lisp.h" +#ifdef SETUP_SLAVE_PTY +# include +# include +#endif + #ifdef WINDOWSNT #include /* for fcntl */ #include diff --git a/src/process.c b/src/process.c index eaa7fa1465..06d750d336 100644 --- a/src/process.c +++ b/src/process.c @@ -80,15 +80,6 @@ static struct rlimit nofile_limit; #endif -#ifdef NEED_BSDTTY -#include -#endif - -#ifdef USG5_4 -# include -# include -#endif - #ifdef HAVE_UTIL_H #include #endif commit ac8875173ad63c030e003363706d49a87aa85745 Author: Paul Eggert Date: Fri Jan 1 08:45:41 2021 -0800 New file scratch_buffer_dupfree.c * lib/malloc/scratch_buffer_dupfree.c: New file, from Gnulib (originally from glibc 2.33 code). This is needed on macOS and some other platforms; I forgot to commit it in the most recent Gnulib update. diff --git a/lib/malloc/scratch_buffer_dupfree.c b/lib/malloc/scratch_buffer_dupfree.c new file mode 100644 index 0000000000..775bff5609 --- /dev/null +++ b/lib/malloc/scratch_buffer_dupfree.c @@ -0,0 +1,41 @@ +/* Variable-sized buffer with on-stack default allocation. + Copyright (C) 2020-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _LIBC +# include +#endif + +#include +#include + +void * +__libc_scratch_buffer_dupfree (struct scratch_buffer *buffer, size_t size) +{ + void *data = buffer->data; + if (data == buffer->__space.__c) + { + void *copy = malloc (size); + return copy != NULL ? memcpy (copy, data, size) : NULL; + } + else + { + void *copy = realloc (data, size); + return copy != NULL ? copy : data; + } +} +libc_hidden_def (__libc_scratch_buffer_dupfree) commit 90c782e92e76ec67bc7d2df152a508f782dd3b42 Merge: 7384ec6416 f0deca159d Author: Eli Zaretskii Date: Fri Jan 1 17:17:19 2021 +0200 Merge branch 'emacs-27' of git.savannah.gnu.org:/srv/git/emacs into emacs-27 commit a4f0b8d85a4e4af84f752543cf05233f2e39540c Author: Glenn Morris Date: Fri Jan 1 06:30:23 2021 -0800 ; Auto-commit of loaddefs files. diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index ed1b2c7714..c6fa497c21 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -1,4 +1,4 @@ -;;; loaddefs.el --- automatically extracted autoloads +;;; loaddefs.el --- automatically extracted autoloads -*- lexical-binding: t -*- ;; ;;; Code: @@ -1202,14 +1202,16 @@ The variables are: Variables you assign: array-max-row: The number of rows in the array. array-max-column: The number of columns in the array. - array-columns-per-line: The number of columns in the array per line of buffer. + array-columns-per-line: The number of columns in the array + per line of buffer. array-field-width: The width of each field, in characters. array-rows-numbered: A logical variable describing whether to ignore - row numbers in the buffer. + row numbers in the buffer. Variables which are calculated: array-line-length: The number of characters in a buffer line. - array-lines-per-row: The number of buffer lines used to display each row. + array-lines-per-row: The number of buffer lines used to + display each row. The following commands are available (an asterisk indicates it may take a numeric prefix argument): @@ -1219,17 +1221,17 @@ take a numeric prefix argument): * \\[array-next-row] Move down one row. * \\[array-previous-row] Move up one row. - * \\[array-copy-forward] Copy the current field into the column to the right. - * \\[array-copy-backward] Copy the current field into the column to the left. - * \\[array-copy-down] Copy the current field into the row below. - * \\[array-copy-up] Copy the current field into the row above. + * \\[array-copy-forward] Copy current field into the column to the right. + * \\[array-copy-backward] Copy current field into the column to the left. + * \\[array-copy-down] Copy current field into the row below. + * \\[array-copy-up] Copy current field into the row above. - * \\[array-copy-column-forward] Copy the current column into the column to the right. - * \\[array-copy-column-backward] Copy the current column into the column to the left. + * \\[array-copy-column-forward] Copy current column into the column to the right. + * \\[array-copy-column-backward] Copy current column into the column to the left. * \\[array-copy-row-down] Copy the current row into the row below. * \\[array-copy-row-up] Copy the current row into the row above. - \\[array-fill-rectangle] Copy the field at mark into every cell with row and column + \\[array-fill-rectangle] Copy field at mark into every cell with row and column between that of point and mark. \\[array-what-position] Display the current array row and column. @@ -1240,7 +1242,7 @@ take a numeric prefix argument): \\[array-expand-rows] Expand the array (remove row numbers and newlines inside rows) - \\[array-display-local-variables] Display the current values of local variables. + \\[array-display-local-variables] Display current values of local variables. Entering array mode calls the function `array-mode-hook'. @@ -1510,8 +1512,9 @@ let-binding.") (autoload 'authinfo-mode "auth-source" "\ Mode for editing .authinfo/.netrc files. -This is just like `fundamental-mode', but hides passwords. The -passwords are revealed when point moved into the password. +This is just like `fundamental-mode', but has basic syntax +highlighting and hides passwords. Passwords are revealed when +point is moved into the passwords (see `authinfo-hide-elements'). \\{authinfo-mode-map} @@ -4877,8 +4880,18 @@ DEFAULT-BODY, if present, is used as the body of a default method. (autoload 'cl-defmethod "cl-generic" "\ Define a new method for generic function NAME. -I.e. it defines the implementation of NAME to use for invocations where the -values of the dispatch arguments match the specified TYPEs. +This it defines an implementation of NAME to use for invocations +of specific types of arguments. + +ARGS is a list of dispatch arguments (see `cl-defun'), but where +each variable element is either just a single variable name VAR, +or a list on the form (VAR TYPE). + +For instance: + + (cl-defmethod foo (bar (format-string string) &optional zot) + (format format-string bar)) + The dispatch arguments have to be among the mandatory arguments, and all methods of NAME have to use the same set of arguments for dispatch. Each dispatch argument and TYPE are specified in ARGS where the corresponding @@ -5399,7 +5412,7 @@ You might also use mode hooks to specify it in certain modes, like this: (lambda () (unless (or (file-exists-p \"makefile\") (file-exists-p \"Makefile\")) - (set (make-local-variable \\='compile-command) + (setq-local compile-command (concat \"make -k \" (if buffer-file-name (shell-quote-argument @@ -6643,14 +6656,13 @@ or call the function `global-cwarn-mode'.") (autoload 'global-cwarn-mode "cwarn" "\ Toggle Cwarn mode in all buffers. With prefix ARG, enable Global Cwarn mode if ARG is positive; -otherwise, disable it. If called from Lisp, enable the mode if -ARG is omitted or nil. +otherwise, disable it. If called from Lisp, enable the mode if ARG is +omitted or nil. Cwarn mode is enabled in all buffers where `turn-on-cwarn-mode-if-enabled' would do it. -See `cwarn-mode' for more information on -Cwarn mode. +See `cwarn-mode' for more information on Cwarn mode. \(fn &optional ARG)" t nil) @@ -7536,6 +7548,90 @@ Major mode for editing the diary file. (register-definition-prefixes "diary-lib" '("calendar-mark-" "diary-")) +;;;*** + +;;;### (autoloads nil "dictionary" "net/dictionary.el" (0 0 0 0)) +;;; Generated autoloads from net/dictionary.el + +(autoload 'dictionary-mode "dictionary" "\ +Mode for searching a dictionary. +This is a mode for searching a dictionary server implementing the +protocol defined in RFC 2229. + +This is a quick reference to this mode describing the default key bindings: + +* q close the dictionary buffer +* h display this help information +* s ask for a new word to search +* d search the word at point +* n or Tab place point to the next link +* p or S-Tab place point to the prev link + +* m ask for a pattern and list all matching words. +* D select the default dictionary +* M select the default search strategy + +* Return or Button2 visit that link +" nil nil) + +(autoload 'dictionary "dictionary" "\ +Create a new dictonary buffer and install dictionary-mode." t nil) + +(autoload 'dictionary-search "dictionary" "\ +Search the WORD in DICTIONARY if given or in all if nil. +It presents the selection or word at point as default input and +allows editing it. + +\(fn WORD &optional DICTIONARY)" t nil) + +(autoload 'dictionary-lookup-definition "dictionary" "\ +Unconditionally lookup the word at point." t nil) + +(autoload 'dictionary-match-words "dictionary" "\ +Search PATTERN in current default dictionary using default strategy. + +\(fn &optional PATTERN &rest IGNORED)" t nil) + +(autoload 'dictionary-mouse-popup-matching-words "dictionary" "\ +Display entries matching the word at the cursor retrieved using EVENT. + +\(fn EVENT)" t nil) + +(autoload 'dictionary-popup-matching-words "dictionary" "\ +Display entries matching WORD or the current word if not given. + +\(fn &optional WORD)" t nil) + +(autoload 'dictionary-tooltip-mode "dictionary" "\ +Display tooltips for the current word. + +This function can be used to enable or disable the tooltip mode +for the current buffer (based on ARG). If global-tooltip-mode is +active it will overwrite that mode for the current buffer. + +\(fn &optional ARG)" t nil) + +(autoload 'global-dictionary-tooltip-mode "dictionary" "\ +Enable/disable dictionary-tooltip-mode for all buffers. + +Internally it provides a default for the dictionary-tooltip-mode. +It can be overwritten for each buffer using dictionary-tooltip-mode. + +Note: (global-dictionary-tooltip-mode 0) will not disable the mode +any buffer where (dictionary-tooltip-mode 1) has been called. + +\(fn &optional ARG)" t nil) + +(register-definition-prefixes "dictionary" '("dictionary-" "global-dictionary-tooltip-mode")) + +;;;*** + +;;;### (autoloads nil "dictionary-connection" "net/dictionary-connection.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from net/dictionary-connection.el + +(register-definition-prefixes "dictionary-connection" '("dictionary-connection-")) + ;;;*** ;;;### (autoloads nil "diff" "vc/diff.el" (0 0 0 0)) @@ -8039,9 +8135,9 @@ or call the function `global-display-fill-column-indicator-mode'.") (autoload 'global-display-fill-column-indicator-mode "display-fill-column-indicator" "\ Toggle Display-Fill-Column-Indicator mode in all buffers. -With prefix ARG, enable Global Display-Fill-Column-Indicator mode if ARG is positive; -otherwise, disable it. If called from Lisp, enable the mode if -ARG is omitted or nil. +With prefix ARG, enable Global Display-Fill-Column-Indicator mode if +ARG is positive; otherwise, disable it. If called from Lisp, enable +the mode if ARG is omitted or nil. Display-Fill-Column-Indicator mode is enabled in all buffers where `display-fill-column-indicator--turn-on' would do it. @@ -8049,8 +8145,8 @@ Display-Fill-Column-Indicator mode is enabled in all buffers where See `display-fill-column-indicator-mode' for more information on Display-Fill-Column-Indicator mode. -`global-display-fill-column-indicator-modes' is used to control which modes -this minor mode is used in. +`global-display-fill-column-indicator-modes' is used to control +which modes this minor mode is used in. \(fn &optional ARG)" t nil) @@ -8113,9 +8209,9 @@ or call the function `global-display-line-numbers-mode'.") (autoload 'global-display-line-numbers-mode "display-line-numbers" "\ Toggle Display-Line-Numbers mode in all buffers. -With prefix ARG, enable Global Display-Line-Numbers mode if ARG is positive; -otherwise, disable it. If called from Lisp, enable the mode if -ARG is omitted or nil. +With prefix ARG, enable Global Display-Line-Numbers mode if ARG is +positive; otherwise, disable it. If called from Lisp, enable the mode +if ARG is omitted or nil. Display-Line-Numbers mode is enabled in all buffers where `display-line-numbers--turn-on' would do it. @@ -8319,6 +8415,9 @@ strings when pressed twice. See `double-map' for details. (autoload 'dunnet "dunnet" "\ Switch to *dungeon* buffer and start game." t nil) +(autoload 'dun-batch "dunnet" "\ +Start `dunnet' in batch mode." nil nil) + (register-definition-prefixes "dunnet" '("dun" "obj-special")) ;;;*** @@ -11204,8 +11303,8 @@ Search through all files listed in tags table for match for REGEXP. Stops when a match is found. To continue searching for next match, use command \\[tags-loop-continue]. -If FILES if non-nil should be a list or an iterator returning the files to search. -The search will be restricted to these files. +If FILES if non-nil should be a list or an iterator returning the +files to search. The search will be restricted to these files. Also see the documentation of the `tags-file-name' variable. @@ -11887,13 +11986,13 @@ Set the base remapping of FACE in the current buffer to SPECS. This causes the remappings specified by `face-remap-add-relative' to apply on top of the face specification given by SPECS. -The remaining arguments, SPECS, should form a list of faces. -Each list element should be either a face name or a property list +The remaining arguments, SPECS, specify the base of the remapping. +Each one of SPECS should be either a face name or a property list of face attribute/value pairs, like in a `face' text property. -If SPECS is empty, call `face-remap-reset-base' to use the normal -definition of FACE as the base remapping; note that this is -different from SPECS containing a single value nil, which means +If SPECS is empty or a single face `eq' to FACE, call `face-remap-reset-base' +to use the normal definition of FACE as the base remapping; note that +this is different from SPECS containing a single value nil, which means not to inherit from the global definition of FACE at all. \(fn FACE &rest SPECS)" nil nil) @@ -12101,10 +12200,10 @@ internally by feedmail): after-run (the queue has just been run, possibly sending messages) WHAT-EVENT is used as a key into the table `feedmail-queue-reminder-alist'. If -the associated value is a function, it is called without arguments and is expected -to perform the reminder activity. You can supply your own reminder functions -by redefining `feedmail-queue-reminder-alist'. If you don't want any reminders, -you can set `feedmail-queue-reminder-alist' to nil. +the associated value is a function, it is called without arguments and is +expected to perform the reminder activity. You can supply your own reminder +functions by redefining `feedmail-queue-reminder-alist'. If you don't want any +reminders, you can set `feedmail-queue-reminder-alist' to nil. \(fn &optional WHAT-EVENT)" t nil) @@ -12883,7 +12982,7 @@ diagnostics at BEG. (autoload 'flymake-diag-region "flymake" "\ Compute BUFFER's region (BEG . END) corresponding to LINE and COL. If COL is nil, return a region just for LINE. Return nil if the -region is invalid. +region is invalid. This function saves match data. \(fn BUFFER LINE &optional COL)" nil nil) @@ -13261,7 +13360,10 @@ the symbol `delete', remove those %-specs from the result; otherwise do the same as for the symbol `ignore', but also leave any occurrences of \"%%\" in FORMAT verbatim in the result. -\(fn FORMAT SPECIFICATION &optional IGNORE-MISSING)" nil nil) +If SPLIT, instead of returning a single string, a list of strings +is returned, where each format spec is its own element. + +\(fn FORMAT SPECIFICATION &optional IGNORE-MISSING SPLIT)" nil nil) (register-definition-prefixes "format-spec" '("format-spec-")) @@ -14950,14 +15052,13 @@ or call the function `global-goto-address-mode'.") (autoload 'global-goto-address-mode "goto-addr" "\ Toggle Goto-Address mode in all buffers. With prefix ARG, enable Global Goto-Address mode if ARG is positive; -otherwise, disable it. If called from Lisp, enable the mode if -ARG is omitted or nil. +otherwise, disable it. If called from Lisp, enable the mode if ARG +is omitted or nil. Goto-Address mode is enabled in all buffers where `goto-addr-mode--turn-on' would do it. -See `goto-address-mode' for more information on -Goto-Address mode. +See `goto-address-mode' for more information on Goto-Address mode. \(fn &optional ARG)" t nil) @@ -15041,7 +15142,7 @@ List of hook functions run by `grep-process-setup' (see `run-hooks').") (custom-autoload 'grep-setup-hook "grep" t) -(defconst grep-regexp-alist `((,(concat "^\\(?:" "\\(?1:[^\0\n]+\\)\\(?3:\0\\)\\(?2:[0-9]+\\):" "\\|" "\\(?1:" "\\(?:[a-zA-Z]:\\)?" "[^\n:]+?[^\n/:]\\):[\11 ]*\\(?2:[1-9][0-9]*\\)[\11 ]*:" "\\)") 1 2 (,(lambda nil (when grep-highlight-matches (let* ((beg (match-end 0)) (end (save-excursion (goto-char beg) (line-end-position))) (mbeg (text-property-any beg end 'font-lock-face grep-match-face))) (when mbeg (- mbeg beg))))) \, (lambda nil (when grep-highlight-matches (let* ((beg (match-end 0)) (end (save-excursion (goto-char beg) (line-end-position))) (mbeg (text-property-any beg end 'font-lock-face grep-match-face)) (mend (and mbeg (next-single-property-change mbeg 'font-lock-face nil end)))) (when mend (- mend beg)))))) nil nil (3 '(face nil display ":"))) ("^Binary file \\(.+\\) matches$" 1 nil nil 0 1)) "\ +(defconst grep-regexp-alist `((,(concat "^\\(?:" "\\(?1:[^\0\n]+\\)\\(?3:\0\\)\\(?2:[0-9]+\\):" "\\|" "\\(?1:" "\\(?:[a-zA-Z]:\\)?" "[^\n:]+?[^\n/:]\\):[\11 ]*\\(?2:[1-9][0-9]*\\)[\11 ]*:" "\\)") 1 2 (,(lambda nil (when grep-highlight-matches (let* ((beg (match-end 0)) (end (save-excursion (goto-char beg) (line-end-position))) (mbeg (text-property-any beg end 'font-lock-face grep-match-face))) (when mbeg (- mbeg beg))))) \, (lambda nil (when grep-highlight-matches (let* ((beg (match-end 0)) (end (save-excursion (goto-char beg) (line-end-position))) (mbeg (text-property-any beg end 'font-lock-face grep-match-face)) (mend (and mbeg (next-single-property-change mbeg 'font-lock-face nil end)))) (when mend (- mend beg)))))) nil nil (3 '(face nil display ":"))) ("^Binary file \\(.+\\) matches" 1 nil nil 0 1)) "\ Regexp used to match grep hits. See `compilation-error-regexp-alist' for format details.") @@ -15251,7 +15352,7 @@ and source-file directory for your debugger. \(fn COMMAND-LINE)" t nil) (autoload 'pdb "gud" "\ -Run COMMAND-LINE in the `*gud-FILE*' buffer. +Run COMMAND-LINE in the `*gud-FILE*' buffer to debug Python programs. COMMAND-LINE should include the pdb executable name (`gud-pdb-command-name') and the file to be debugged. @@ -16113,14 +16214,13 @@ or call the function `global-hi-lock-mode'.") (autoload 'global-hi-lock-mode "hi-lock" "\ Toggle Hi-Lock mode in all buffers. With prefix ARG, enable Global Hi-Lock mode if ARG is positive; -otherwise, disable it. If called from Lisp, enable the mode if -ARG is omitted or nil. +otherwise, disable it. If called from Lisp, enable the mode if ARG is +omitted or nil. Hi-Lock mode is enabled in all buffers where `turn-on-hi-lock-if-enabled' would do it. -See `hi-lock-mode' for more information on -Hi-Lock mode. +See `hi-lock-mode' for more information on Hi-Lock mode. \(fn &optional ARG)" t nil) @@ -16498,8 +16598,8 @@ or call the function `global-highlight-changes-mode'.") (autoload 'global-highlight-changes-mode "hilit-chg" "\ Toggle Highlight-Changes mode in all buffers. -With prefix ARG, enable Global Highlight-Changes mode if ARG is positive; -otherwise, disable it. If called from Lisp, enable the mode if +With prefix ARG, enable Global Highlight-Changes mode if ARG is +positive; otherwise, disable it. If called from Lisp, enable the mode if ARG is omitted or nil. Highlight-Changes mode is enabled in all buffers where @@ -17759,11 +17859,13 @@ is supported, and FILE exists, is used to construct the image specification to be returned. Return nil if no specification is satisfied. +If CACHE is non-nil, results are cached and returned on subsequent calls. + The image is looked for in `image-load-path'. Image files should not be larger than specified by `max-image-size'. -\(fn SPECS)" nil nil) +\(fn SPECS &optional CACHE)" nil nil) (autoload 'defimage "image" "\ Define SYMBOL as an image, and return SYMBOL. @@ -17801,7 +17903,7 @@ recognizes these files as having image type `imagemagick'. If Emacs is compiled without ImageMagick support, this does nothing." nil nil) -(register-definition-prefixes "image" '("image" "unknown-image-type")) +(register-definition-prefixes "image" '("find-image--cache" "image" "unknown-image-type")) ;;;*** @@ -18810,16 +18912,6 @@ Add submenus to the File menu, to convert to and from various formats." t nil) (register-definition-prefixes "iso-cvt" '("iso-")) -;;;*** - -;;;### (autoloads nil "iso-transl" "international/iso-transl.el" -;;;;;; (0 0 0 0)) -;;; Generated autoloads from international/iso-transl.el - (define-key key-translation-map "\C-x8" 'iso-transl-ctl-x-8-map) - (autoload 'iso-transl-ctl-x-8-map "iso-transl" "Keymap for C-x 8 prefix." t 'keymap) - -(register-definition-prefixes "iso-transl" '("iso-transl-")) - ;;;*** ;;;### (autoloads nil "iso8601" "calendar/iso8601.el" (0 0 0 0)) @@ -19731,14 +19823,12 @@ or call the function `global-linum-mode'.") (autoload 'global-linum-mode "linum" "\ Toggle Linum mode in all buffers. With prefix ARG, enable Global Linum mode if ARG is positive; -otherwise, disable it. If called from Lisp, enable the mode if -ARG is omitted or nil. +otherwise, disable it. If called from Lisp, enable the mode if ARG is +omitted or nil. -Linum mode is enabled in all buffers where -`linum-on' would do it. +Linum mode is enabled in all buffers where `linum-on' would do it. -See `linum-mode' for more information on -Linum mode. +See `linum-mode' for more information on Linum mode. \(fn &optional ARG)" t nil) @@ -20692,6 +20782,21 @@ recursion depth in the minibuffer prompt. This is only useful if (register-definition-prefixes "md4" '("md4")) +;;;*** + +;;;### (autoloads nil "memory-report" "emacs-lisp/memory-report.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from emacs-lisp/memory-report.el + +(autoload 'memory-report "memory-report" "\ +Generate a report of how Emacs is using memory. + +This report is approximate, and will commonly over-count memory +usage by variables, because shared data structures will usually +by counted more than once." t nil) + +(register-definition-prefixes "memory-report" '("memory-report-")) + ;;;*** ;;;### (autoloads nil "message" "gnus/message.el" (0 0 0 0)) @@ -22898,7 +23003,6 @@ Many aspects this mode can be customized using ;;;### (autoloads nil "ob-abc" "org/ob-abc.el" (0 0 0 0)) ;;; Generated autoloads from org/ob-abc.el -(push (purecopy '(ob-abc 0 1)) package--builtin-versions) (register-definition-prefixes "ob-abc" '("org-babel-")) @@ -22929,7 +23033,7 @@ Many aspects this mode can be customized using ;;;### (autoloads nil "ob-clojure" "org/ob-clojure.el" (0 0 0 0)) ;;; Generated autoloads from org/ob-clojure.el -(register-definition-prefixes "ob-clojure" '("org-babel-")) +(register-definition-prefixes "ob-clojure" '("ob-clojure-" "org-babel-")) ;;;*** @@ -22970,7 +23074,6 @@ Many aspects this mode can be customized using ;;;### (autoloads nil "ob-ebnf" "org/ob-ebnf.el" (0 0 0 0)) ;;; Generated autoloads from org/ob-ebnf.el -(push (purecopy '(ob-ebnf 1 0)) package--builtin-versions) (register-definition-prefixes "ob-ebnf" '("org-babel-")) @@ -23218,7 +23321,6 @@ Many aspects this mode can be customized using ;;;### (autoloads nil "ob-sed" "org/ob-sed.el" (0 0 0 0)) ;;; Generated autoloads from org/ob-sed.el -(push (purecopy '(ob-sed 0 1 1)) package--builtin-versions) (register-definition-prefixes "ob-sed" '("org-babel-")) @@ -23321,110 +23423,6 @@ startup file, `~/.emacs-octave'. (register-definition-prefixes "ogonek" '("ogonek-")) -;;;*** - -;;;### (autoloads nil "ol" "org/ol.el" (0 0 0 0)) -;;; Generated autoloads from org/ol.el - -(autoload 'org-next-link "ol" "\ -Move forward to the next link. -If the link is in hidden text, expose it. When SEARCH-BACKWARD -is non-nil, move backward. - -\(fn &optional SEARCH-BACKWARD)" t nil) - -(autoload 'org-previous-link "ol" "\ -Move backward to the previous link. -If the link is in hidden text, expose it." t nil) - -(autoload 'org-toggle-link-display "ol" "\ -Toggle the literal or descriptive display of links." t nil) - -(autoload 'org-store-link "ol" "\ -Store a link to the current location. -\\ -This link is added to `org-stored-links' and can later be inserted -into an Org buffer with `org-insert-link' (`\\[org-insert-link]'). - -For some link types, a `\\[universal-argument]' prefix ARG is interpreted. A single -`\\[universal-argument]' negates `org-context-in-file-links' for file links or -`org-gnus-prefer-web-links' for links to Usenet articles. - -A `\\[universal-argument] \\[universal-argument]' prefix ARG forces skipping storing functions that are not -part of Org core. - -A `\\[universal-argument] \\[universal-argument] \\[universal-argument]' prefix ARG forces storing a link for each line in the -active region. - -Assume the function is called interactively if INTERACTIVE? is -non-nil. - -\(fn ARG &optional INTERACTIVE\\=\\?)" t nil) - -(autoload 'org-insert-link "ol" "\ -Insert a link. At the prompt, enter the link. - -Completion can be used to insert any of the link protocol prefixes in use. - -The history can be used to select a link previously stored with -`org-store-link'. When the empty string is entered (i.e. if you just -press `RET' at the prompt), the link defaults to the most recently -stored link. As `SPC' triggers completion in the minibuffer, you need to -use `M-SPC' or `C-q SPC' to force the insertion of a space character. - -You will also be prompted for a description, and if one is given, it will -be displayed in the buffer instead of the link. - -If there is already a link at point, this command will allow you to edit -link and description parts. - -With a `\\[universal-argument]' prefix, prompts for a file to link to. The file name can be -selected using completion. The path to the file will be relative to the -current directory if the file is in the current directory or a subdirectory. -Otherwise, the link will be the absolute path as completed in the minibuffer -\(i.e. normally ~/path/to/file). You can configure this behavior using the -option `org-link-file-path-type'. - -With a `\\[universal-argument] \\[universal-argument]' prefix, enforce an absolute path even if the file is in -the current directory or below. - -A `\\[universal-argument] \\[universal-argument] \\[universal-argument]' prefix negates `org-link-keep-stored-after-insertion'. - -If the LINK-LOCATION parameter is non-nil, this value will be used as -the link location instead of reading one interactively. - -If the DESCRIPTION parameter is non-nil, this value will be used as the -default description. Otherwise, if `org-link-make-description-function' -is non-nil, this function will be called with the link target, and the -result will be the default link description. When called non-interactively, -don't allow to edit the default description. - -\(fn &optional COMPLETE-FILE LINK-LOCATION DESCRIPTION)" t nil) - -(autoload 'org-insert-all-links "ol" "\ -Insert all links in `org-stored-links'. -When a universal prefix, do not delete the links from `org-stored-links'. -When `ARG' is a number, insert the last N link(s). -`PRE' and `POST' are optional arguments to define a string to -prepend or to append. - -\(fn ARG &optional PRE POST)" t nil) - -(autoload 'org-insert-last-stored-link "ol" "\ -Insert the last link stored in `org-stored-links'. - -\(fn ARG)" t nil) - -(autoload 'org-insert-link-global "ol" "\ -Insert a link like Org mode does. -This command can be called in any mode to insert a link in Org syntax." t nil) - -(autoload 'org-update-radio-target-regexp "ol" "\ -Find all radio targets in this file and update the regular expression. -Also refresh fontification if needed." t nil) - -(register-definition-prefixes "ol" '("org-")) - ;;;*** ;;;### (autoloads nil "ol-bibtex" "org/ol-bibtex.el" (0 0 0 0)) @@ -23529,7 +23527,7 @@ Coloring: ;;;### (autoloads nil "org" "org/org.el" (0 0 0 0)) ;;; Generated autoloads from org/org.el -(push (purecopy '(org 9 3)) package--builtin-versions) +(push (purecopy '(org 9 4 4)) package--builtin-versions) (autoload 'org-babel-do-load-languages "org" "\ Load the languages defined in `org-babel-load-languages'. @@ -23554,6 +23552,11 @@ FULL is given. \(fn &optional HERE FULL MESSAGE)" t nil) +(autoload 'org-load-modules-maybe "org" "\ +Load all extensions listed in `org-modules'. + +\(fn &optional FORCE)" nil nil) + (autoload 'org-clock-persistence-insinuate "org" "\ Set up hooks for clock persistence." nil nil) @@ -23623,10 +23626,10 @@ When point is not at the beginning of a headline, execute the global binding for `TAB', which is re-indenting the line. See the option `org-cycle-emulate-tab' for details. -As a special case, if point is at the beginning of the buffer and there is -no headline in line 1, this function will act as if called with prefix arg -\(`\\[universal-argument] TAB', same as `S-TAB') also when called without prefix arg, but only -if the variable `org-cycle-global-at-bob' is t. +As a special case, if point is at the very beginning of the buffer, if +there is no headline there, and if the variable `org-cycle-global-at-bob' +is non-nil, this function acts as if called with prefix argument (`\\[universal-argument] TAB', +same as `S-TAB') also when called without prefix argument. \(fn &optional ARG)" t nil) @@ -24052,109 +24055,23 @@ Set `org-capture-templates' to be similar to `org-remember-templates'." t nil) ;;;*** -;;;### (autoloads nil "org-colview" "org/org-colview.el" (0 0 0 0)) -;;; Generated autoloads from org/org-colview.el - -(autoload 'org-columns-remove-overlays "org-colview" "\ -Remove all currently active column overlays." t nil) - -(autoload 'org-columns-get-format-and-top-level "org-colview" nil nil nil) - -(autoload 'org-columns "org-colview" "\ -Turn on column view on an Org mode file. - -Column view applies to the whole buffer if point is before the -first headline. Otherwise, it applies to the first ancestor -setting \"COLUMNS\" property. If there is none, it defaults to -the current headline. With a `\\[universal-argument]' prefix argument, turn on column -view for the whole buffer unconditionally. - -When COLUMNS-FMT-STRING is non-nil, use it as the column format. - -\(fn &optional GLOBAL COLUMNS-FMT-STRING)" t nil) - -(autoload 'org-columns-compute "org-colview" "\ -Summarize the values of PROPERTY hierarchically. -Also update existing values for PROPERTY according to the first -column specification. - -\(fn PROPERTY)" t nil) - -(autoload 'org-dblock-write:columnview "org-colview" "\ -Write the column view table. - -PARAMS is a property list of parameters: - -`:id' (mandatory) - - The ID property of the entry where the columns view should be - built. When the symbol `local', call locally. When `global' - call column view with the cursor at the beginning of the - buffer (usually this means that the whole buffer switches to - column view). When \"file:path/to/file.org\", invoke column - view at the start of that file. Otherwise, the ID is located - using `org-id-find'. - -`:exclude-tags' - - List of tags to exclude from column view table. - -`:format' - - When non-nil, specify the column view format to use. - -`:hlines' - - When non-nil, insert a hline before each item. When - a number, insert a hline before each level inferior or equal - to that number. - -`:indent' - - When non-nil, indent each ITEM field according to its level. - -`:match' - - When set to a string, use this as a tags/property match filter. - -`:maxlevel' - - When set to a number, don't capture headlines below this level. - -`:skip-empty-rows' - - When non-nil, skip rows where all specifiers other than ITEM - are empty. - -`:vlines' - - When non-nil, make each column a column group to enforce - vertical lines. - -\(fn PARAMS)" nil nil) - -(autoload 'org-columns-insert-dblock "org-colview" "\ -Create a dynamic block capturing a column view table." t nil) - -(autoload 'org-agenda-columns "org-colview" "\ -Turn on or update column view in the agenda." t nil) +;;;### (autoloads nil "org-crypt" "org/org-crypt.el" (0 0 0 0)) +;;; Generated autoloads from org/org-crypt.el -(register-definition-prefixes "org-colview" '("org-")) +(autoload 'org-encrypt-entry "org-crypt" "\ +Encrypt the content of the current headline." t nil) -;;;*** - -;;;### (autoloads nil "org-compat" "org/org-compat.el" (0 0 0 0)) -;;; Generated autoloads from org/org-compat.el +(autoload 'org-decrypt-entry "org-crypt" "\ +Decrypt the content of the current headline." t nil) -(autoload 'org-check-version "org-compat" "\ -Try very hard to provide sensible version strings." nil t) +(autoload 'org-encrypt-entries "org-crypt" "\ +Encrypt all top-level entries in the current buffer." t nil) -(register-definition-prefixes "org-compat" '("org-")) +(autoload 'org-decrypt-entries "org-crypt" "\ +Decrypt all entries in the current buffer." t nil) -;;;*** - -;;;### (autoloads nil "org-crypt" "org/org-crypt.el" (0 0 0 0)) -;;; Generated autoloads from org/org-crypt.el +(autoload 'org-crypt-use-before-save-magic "org-crypt" "\ +Add a hook to automatically encrypt entries before a file is saved to disk." nil nil) (register-definition-prefixes "org-crypt" '("org-")) @@ -24165,61 +24082,6 @@ Try very hard to provide sensible version strings." nil t) (register-definition-prefixes "org-ctags" '("org-ctags-")) -;;;*** - -;;;### (autoloads nil "org-duration" "org/org-duration.el" (0 0 0 -;;;;;; 0)) -;;; Generated autoloads from org/org-duration.el - -(autoload 'org-duration-set-regexps "org-duration" "\ -Set duration related regexps." t nil) - -(autoload 'org-duration-p "org-duration" "\ -Non-nil when string S is a time duration. - -\(fn S)" nil nil) - -(autoload 'org-duration-to-minutes "org-duration" "\ -Return number of minutes of DURATION string. - -When optional argument CANONICAL is non-nil, ignore -`org-duration-units' and use standard time units value. - -A bare number is translated into minutes. The empty string is -translated into 0.0. - -Return value as a float. Raise an error if duration format is -not recognized. - -\(fn DURATION &optional CANONICAL)" nil nil) - -(autoload 'org-duration-from-minutes "org-duration" "\ -Return duration string for a given number of MINUTES. - -Format duration according to `org-duration-format' or FMT, when -non-nil. - -When optional argument CANONICAL is non-nil, ignore -`org-duration-units' and use standard time units value. - -Raise an error if expected format is unknown. - -\(fn MINUTES &optional FMT CANONICAL)" nil nil) - -(autoload 'org-duration-h:mm-only-p "org-duration" "\ -Non-nil when every duration in TIMES has \"H:MM\" or \"H:MM:SS\" format. - -TIMES is a list of duration strings. - -Return nil if any duration is expressed with units, as defined in -`org-duration-units'. Otherwise, if any duration is expressed -with \"H:MM:SS\" format, return `h:mm:ss'. Otherwise, return -`h:mm'. - -\(fn TIMES)" nil nil) - -(register-definition-prefixes "org-duration" '("org-duration-")) - ;;;*** ;;;### (autoloads nil "org-entities" "org/org-entities.el" (0 0 0 @@ -24235,42 +24097,6 @@ with \"H:MM:SS\" format, return `h:mm:ss'. Otherwise, return (register-definition-prefixes "org-faces" '("org-")) -;;;*** - -;;;### (autoloads nil "org-goto" "org/org-goto.el" (0 0 0 0)) -;;; Generated autoloads from org/org-goto.el - -(autoload 'org-goto-location "org-goto" "\ -Let the user select a location in current buffer. -This function uses a recursive edit. It returns the selected -position or nil. - -\(fn &optional BUF HELP)" nil nil) - -(autoload 'org-goto "org-goto" "\ -Look up a different location in the current file, keeping current visibility. - -When you want look-up or go to a different location in a -document, the fastest way is often to fold the entire buffer and -then dive into the tree. This method has the disadvantage, that -the previous location will be folded, which may not be what you -want. - -This command works around this by showing a copy of the current -buffer in an indirect buffer, in overview mode. You can dive -into the tree in that copy, use org-occur and incremental search -to find a location. When pressing RET or `Q', the command -returns to the original buffer in which the visibility is still -unchanged. After RET it will also jump to the location selected -in the indirect buffer and expose the headline hierarchy above. - -With a prefix argument, use the alternative interface: e.g., if -`org-goto-interface' is `outline' use `outline-path-completion'. - -\(fn &optional ALTERNATIVE-INTERFACE)" t nil) - -(register-definition-prefixes "org-goto" '("org-goto-")) - ;;;*** ;;;### (autoloads nil "org-habit" "org/org-habit.el" (0 0 0 0)) @@ -24286,41 +24112,6 @@ With a prefix argument, use the alternative interface: e.g., if (register-definition-prefixes "org-inlinetask" '("org-inlinetask-")) -;;;*** - -;;;### (autoloads nil "org-keys" "org/org-keys.el" (0 0 0 0)) -;;; Generated autoloads from org/org-keys.el - -(autoload 'org-babel-describe-bindings "org-keys" "\ -Describe all keybindings behind `org-babel-key-prefix'." t nil) - -(register-definition-prefixes "org-keys" '("org-")) - -;;;*** - -;;;### (autoloads nil "org-lint" "org/org-lint.el" (0 0 0 0)) -;;; Generated autoloads from org/org-lint.el - -(autoload 'org-lint "org-lint" "\ -Check current Org buffer for syntax mistakes. - -By default, run all checkers. With a `\\[universal-argument]' prefix ARG, select one -category of checkers only. With a `\\[universal-argument] \\[universal-argument]' prefix, run one precise -checker by its name. - -ARG can also be a list of checker names, as symbols, to run. - -\(fn &optional ARG)" t nil) - -(register-definition-prefixes "org-lint" '("org-lint-")) - -;;;*** - -;;;### (autoloads nil "org-list" "org/org-list.el" (0 0 0 0)) -;;; Generated autoloads from org/org-list.el - -(register-definition-prefixes "org-list" '("org-")) - ;;;*** ;;;### (autoloads nil "org-macro" "org/org-macro.el" (0 0 0 0)) @@ -24328,18 +24119,6 @@ ARG can also be a list of checker names, as symbols, to run. (register-definition-prefixes "org-macro" '("org-macro-")) -;;;*** - -;;;### (autoloads nil "org-macs" "org/org-macs.el" (0 0 0 0)) -;;; Generated autoloads from org/org-macs.el - -(autoload 'org-load-noerror-mustsuffix "org-macs" "\ -Load FILE with optional arguments NOERROR and MUSTSUFFIX. - -\(fn FILE)" nil t) - -(register-definition-prefixes "org-macs" '("org-")) - ;;;*** ;;;### (autoloads nil "org-mouse" "org/org-mouse.el" (0 0 0 0)) @@ -24347,35 +24126,6 @@ Load FILE with optional arguments NOERROR and MUSTSUFFIX. (register-definition-prefixes "org-mouse" '("org-mouse-")) -;;;*** - -;;;### (autoloads nil "org-num" "org/org-num.el" (0 0 0 0)) -;;; Generated autoloads from org/org-num.el - -(autoload 'org-num-default-format "org-num" "\ -Default numbering display function. -NUMBERING is a list of numbers. - -\(fn NUMBERING)" nil nil) - -(autoload 'org-num-mode "org-num" "\ -Dynamic numbering of headlines in an Org buffer. - -If called interactively, toggle `Org-Num mode'. If the prefix -argument is positive, enable the mode, and if it is zero or negative, -disable the mode. - -If called from Lisp, toggle the mode if ARG is `toggle'. Enable the -mode if ARG is nil, omitted, or is a positive number. Disable the -mode if ARG is a negative number. - -The mode's hook is called both when the mode is enabled and when it is -disabled. - -\(fn &optional ARG)" t nil) - -(register-definition-prefixes "org-num" '("org-num-")) - ;;;*** ;;;### (autoloads nil "org-pcomplete" "org/org-pcomplete.el" (0 0 @@ -24472,6 +24222,13 @@ See the command `outline-mode' for more information on this mode. (register-definition-prefixes "outline" '("outline-")) +;;;*** + +;;;### (autoloads nil "ox-man" "org/ox-man.el" (0 0 0 0)) +;;; Generated autoloads from org/ox-man.el + +(register-definition-prefixes "ox-man" '("org-man-")) + ;;;*** ;;;### (autoloads nil "package" "emacs-lisp/package.el" (0 0 0 0)) @@ -26094,7 +25851,7 @@ Open profile FILENAME. ;;;### (autoloads nil "project" "progmodes/project.el" (0 0 0 0)) ;;; Generated autoloads from progmodes/project.el -(push (purecopy '(project 0 5 2)) package--builtin-versions) +(push (purecopy '(project 0 5 3)) package--builtin-versions) (autoload 'project-current "project" "\ Return the project instance in DIRECTORY, defaulting to `default-directory'. @@ -26115,7 +25872,7 @@ of the project instance object. \(fn &optional MAYBE-PROMPT DIRECTORY)" nil nil) -(defvar project-prefix-map (let ((map (make-sparse-keymap))) (define-key map "!" 'project-shell-command) (define-key map "&" 'project-async-shell-command) (define-key map "f" 'project-find-file) (define-key map "F" 'project-or-external-find-file) (define-key map "b" 'project-switch-to-buffer) (define-key map "s" 'project-shell) (define-key map "d" 'project-dired) (define-key map "v" 'project-vc-dir) (define-key map "c" 'project-compile) (define-key map "e" 'project-eshell) (define-key map "k" 'project-kill-buffers) (define-key map "p" 'project-switch-project) (define-key map "g" 'project-find-regexp) (define-key map "G" 'project-or-external-find-regexp) (define-key map "r" 'project-query-replace-regexp) map) "\ +(defvar project-prefix-map (let ((map (make-sparse-keymap))) (define-key map "!" 'project-shell-command) (define-key map "&" 'project-async-shell-command) (define-key map "f" 'project-find-file) (define-key map "F" 'project-or-external-find-file) (define-key map "b" 'project-switch-to-buffer) (define-key map "s" 'project-shell) (define-key map "d" 'project-dired) (define-key map "v" 'project-vc-dir) (define-key map "c" 'project-compile) (define-key map "e" 'project-eshell) (define-key map "k" 'project-kill-buffers) (define-key map "p" 'project-switch-project) (define-key map "g" 'project-find-regexp) (define-key map "G" 'project-or-external-find-regexp) (define-key map "r" 'project-query-replace-regexp) (define-key map "x" 'project-execute-extended-command) map) "\ Keymap for project commands.") (define-key ctl-x-map "p" project-prefix-map) @@ -26279,19 +26036,33 @@ Save the result in `project-list-file' if the list of projects has changed. (autoload 'project-known-project-roots "project" "\ Return the list of root directories of all known projects." nil nil) -(defvar project-switch-commands '((102 "Find file" project-find-file) (103 "Find regexp" project-find-regexp) (100 "Dired" project-dired) (118 "VC-Dir" project-vc-dir) (101 "Eshell" project-eshell)) "\ -Alist mapping keys to project switching menu entries. +(autoload 'project-execute-extended-command "project" "\ +Execute an extended command in project root." t nil) + +(function-put 'project-execute-extended-command 'interactive-only 'command-execute) + +(defvar project-switch-commands '((project-find-file "Find file") (project-find-regexp "Find regexp") (project-dired "Dired") (project-vc-dir "VC-Dir") (project-eshell "Eshell")) "\ +Alist mapping commands to descriptions. Used by `project-switch-project' to construct a dispatch menu of commands available upon \"switching\" to another project. -Each element is of the form (KEY LABEL COMMAND), where COMMAND is the -command to run when KEY is pressed. LABEL is used to distinguish -the menu entries in the dispatch menu.") +Each element is of the form (COMMAND LABEL &optional KEY) where +COMMAND is the command to run when KEY is pressed. LABEL is used +to distinguish the menu entries in the dispatch menu. If KEY is +absent, COMMAND must be bound in `project-prefix-map', and the +key is looked up in that map.") + +(custom-autoload 'project-switch-commands "project" t) (autoload 'project-switch-project "project" "\ \"Switch\" to another project by running an Emacs command. The available commands are presented as a dispatch menu -made from `project-switch-commands'." t nil) +made from `project-switch-commands'. + +When called in a program, it will use the project corresponding +to directory DIR. + +\(fn DIR)" t nil) (register-definition-prefixes "project" '("project-")) @@ -26625,7 +26396,7 @@ Optional argument FACE specifies the face to do the highlighting. ;;;### (autoloads nil "python" "progmodes/python.el" (0 0 0 0)) ;;; Generated autoloads from progmodes/python.el -(push (purecopy '(python 0 27)) package--builtin-versions) +(push (purecopy '(python 0 27 1)) package--builtin-versions) (add-to-list 'auto-mode-alist (cons (purecopy "\\.py[iw]?\\'") 'python-mode)) @@ -28013,6 +27784,7 @@ Instead, these commands are available: \\[rmail-undelete-previous-message] Undelete message. Tries current message, then earlier messages till a deleted message is found. \\[rmail-edit-current-message] Edit the current message. \\[rmail-cease-edit] to return to Rmail. +\\[rmail-epa-decrypt] Decrypt the current message. \\[rmail-expunge] Expunge deleted messages. \\[rmail-expunge-and-save] Expunge and save the file. \\[rmail-quit] Quit Rmail: expunge, save, then switch to another buffer. @@ -29574,7 +29346,7 @@ sorted. FUNCTION must be a function of one argument. \(fn FUNCTION PRED SEQUENCE)" nil nil) (autoload 'seq-filter "seq" "\ -Return a list of all the elements for which (PRED element) is non-nil in SEQUENCE. +Return a list of all elements for which (PRED element) is non-nil in SEQUENCE. \(fn PRED SEQUENCE)" nil nil) @@ -29811,8 +29583,8 @@ have

Very Major Headlines

through
Very Minor Headlines

Paragraphs only need an opening tag. Line breaks and multiple spaces are ignored unless the text is

preformatted.
Text can be marked as -bold, italic or underlined using the normal M-o or -Edit/Text Properties/Face commands. +bold, italic or underlined using the normal M-o +or Edit/Text Properties/Face commands. Pages can have
named points and can link other points to them with see also somename. In the same way -\\[tetris-start-game] Starts a new game of Tetris -\\[tetris-end-game] Terminates the current game -\\[tetris-pause-game] Pauses (or resumes) the current game -\\[tetris-move-left] Moves the shape one square to the left -\\[tetris-move-right] Moves the shape one square to the right -\\[tetris-rotate-prev] Rotates the shape clockwise -\\[tetris-rotate-next] Rotates the shape anticlockwise -\\[tetris-move-bottom] Drops the shape to the bottom of the playing area - -" t nil) +\\ +\\[tetris-start-game] Start a new game of Tetris +\\[tetris-end-game] Terminate the current game +\\[tetris-pause-game] Pause (or resume) the current game +\\[tetris-move-left] Move the shape one square to the left +\\[tetris-move-right] Move the shape one square to the right +\\[tetris-rotate-prev] Rotate the shape clockwise +\\[tetris-rotate-next] Rotate the shape anticlockwise +\\[tetris-move-bottom] Drop the shape to the bottom of the playing area" t nil) (register-definition-prefixes "tetris" '("tetris-")) @@ -34234,7 +34001,6 @@ the output buffer or changing the window configuration. ;;;### (autoloads nil "tramp" "net/tramp.el" (0 0 0 0)) ;;; Generated autoloads from net/tramp.el -(push (purecopy '(tramp 2 5 0 -1)) package--builtin-versions) (defvar tramp-mode t "\ Whether Tramp is enabled. @@ -34408,6 +34174,7 @@ Add archive file name handler to `file-name-handler-alist'." (when tramp-archive ;;;### (autoloads nil "trampver" "net/trampver.el" (0 0 0 0)) ;;; Generated autoloads from net/trampver.el +(push (purecopy '(tramp 2 5 0)) package--builtin-versions) (register-definition-prefixes "trampver" '("tramp-")) @@ -38445,7 +38212,7 @@ If LIMIT is non-nil, then do not consider characters beyond LIMIT. ;;;### (autoloads nil "xref" "progmodes/xref.el" (0 0 0 0)) ;;; Generated autoloads from progmodes/xref.el -(push (purecopy '(xref 1 0 3)) package--builtin-versions) +(push (purecopy '(xref 1 0 4)) package--builtin-versions) (autoload 'xref-find-backend "xref" nil nil nil) @@ -38699,39 +38466,39 @@ Zone out, completely." t nil) ;;;;;; "font-lock.el" "format.el" "frame.el" "help.el" "hfy-cmap.el" ;;;;;; "ibuf-ext.el" "indent.el" "international/characters.el" "international/charprop.el" ;;;;;; "international/charscript.el" "international/cp51932.el" -;;;;;; "international/eucjp-ms.el" "international/mule-cmds.el" -;;;;;; "international/mule-conf.el" "international/mule.el" "international/uni-bidi.el" -;;;;;; "international/uni-brackets.el" "international/uni-category.el" -;;;;;; "international/uni-combining.el" "international/uni-comment.el" -;;;;;; "international/uni-decimal.el" "international/uni-decomposition.el" -;;;;;; "international/uni-digit.el" "international/uni-lowercase.el" -;;;;;; "international/uni-mirrored.el" "international/uni-name.el" -;;;;;; "international/uni-numeric.el" "international/uni-old-name.el" -;;;;;; "international/uni-special-lowercase.el" "international/uni-special-titlecase.el" -;;;;;; "international/uni-special-uppercase.el" "international/uni-titlecase.el" -;;;;;; "international/uni-uppercase.el" "isearch.el" "jit-lock.el" -;;;;;; "jka-cmpr-hook.el" "language/burmese.el" "language/cham.el" -;;;;;; "language/chinese.el" "language/cyrillic.el" "language/czech.el" -;;;;;; "language/english.el" "language/ethiopic.el" "language/european.el" -;;;;;; "language/georgian.el" "language/greek.el" "language/hebrew.el" -;;;;;; "language/indian.el" "language/japanese.el" "language/khmer.el" -;;;;;; "language/korean.el" "language/lao.el" "language/misc-lang.el" -;;;;;; "language/romanian.el" "language/sinhala.el" "language/slovak.el" -;;;;;; "language/tai-viet.el" "language/thai.el" "language/tibetan.el" -;;;;;; "language/utf-8-lang.el" "language/vietnamese.el" "ldefs-boot.el" -;;;;;; "leim/ja-dic/ja-dic.el" "leim/leim-list.el" "leim/quail/4Corner.el" -;;;;;; "leim/quail/ARRAY30.el" "leim/quail/CCDOSPY.el" "leim/quail/CTLau-b5.el" -;;;;;; "leim/quail/CTLau.el" "leim/quail/ECDICT.el" "leim/quail/ETZY.el" -;;;;;; "leim/quail/PY-b5.el" "leim/quail/PY.el" "leim/quail/Punct-b5.el" -;;;;;; "leim/quail/Punct.el" "leim/quail/QJ-b5.el" "leim/quail/QJ.el" -;;;;;; "leim/quail/SW.el" "leim/quail/TONEPY.el" "leim/quail/ZIRANMA.el" -;;;;;; "leim/quail/ZOZY.el" "leim/quail/arabic.el" "leim/quail/compose.el" -;;;;;; "leim/quail/croatian.el" "leim/quail/cyril-jis.el" "leim/quail/cyrillic.el" -;;;;;; "leim/quail/czech.el" "leim/quail/georgian.el" "leim/quail/greek.el" -;;;;;; "leim/quail/hanja-jis.el" "leim/quail/hanja.el" "leim/quail/hanja3.el" -;;;;;; "leim/quail/hebrew.el" "leim/quail/ipa-praat.el" "leim/quail/latin-alt.el" -;;;;;; "leim/quail/latin-ltx.el" "leim/quail/latin-post.el" "leim/quail/latin-pre.el" -;;;;;; "leim/quail/persian.el" "leim/quail/programmer-dvorak.el" +;;;;;; "international/eucjp-ms.el" "international/iso-transl.el" +;;;;;; "international/mule-cmds.el" "international/mule-conf.el" +;;;;;; "international/mule.el" "international/uni-bidi.el" "international/uni-brackets.el" +;;;;;; "international/uni-category.el" "international/uni-combining.el" +;;;;;; "international/uni-comment.el" "international/uni-decimal.el" +;;;;;; "international/uni-decomposition.el" "international/uni-digit.el" +;;;;;; "international/uni-lowercase.el" "international/uni-mirrored.el" +;;;;;; "international/uni-name.el" "international/uni-numeric.el" +;;;;;; "international/uni-old-name.el" "international/uni-special-lowercase.el" +;;;;;; "international/uni-special-titlecase.el" "international/uni-special-uppercase.el" +;;;;;; "international/uni-titlecase.el" "international/uni-uppercase.el" +;;;;;; "isearch.el" "jit-lock.el" "jka-cmpr-hook.el" "language/burmese.el" +;;;;;; "language/cham.el" "language/chinese.el" "language/cyrillic.el" +;;;;;; "language/czech.el" "language/english.el" "language/ethiopic.el" +;;;;;; "language/european.el" "language/georgian.el" "language/greek.el" +;;;;;; "language/hebrew.el" "language/indian.el" "language/japanese.el" +;;;;;; "language/khmer.el" "language/korean.el" "language/lao.el" +;;;;;; "language/misc-lang.el" "language/romanian.el" "language/sinhala.el" +;;;;;; "language/slovak.el" "language/tai-viet.el" "language/thai.el" +;;;;;; "language/tibetan.el" "language/utf-8-lang.el" "language/vietnamese.el" +;;;;;; "ldefs-boot.el" "leim/ja-dic/ja-dic.el" "leim/leim-list.el" +;;;;;; "leim/quail/4Corner.el" "leim/quail/ARRAY30.el" "leim/quail/CCDOSPY.el" +;;;;;; "leim/quail/CTLau-b5.el" "leim/quail/CTLau.el" "leim/quail/ECDICT.el" +;;;;;; "leim/quail/ETZY.el" "leim/quail/PY-b5.el" "leim/quail/PY.el" +;;;;;; "leim/quail/Punct-b5.el" "leim/quail/Punct.el" "leim/quail/QJ-b5.el" +;;;;;; "leim/quail/QJ.el" "leim/quail/SW.el" "leim/quail/TONEPY.el" +;;;;;; "leim/quail/ZIRANMA.el" "leim/quail/ZOZY.el" "leim/quail/arabic.el" +;;;;;; "leim/quail/compose.el" "leim/quail/croatian.el" "leim/quail/cyril-jis.el" +;;;;;; "leim/quail/cyrillic.el" "leim/quail/czech.el" "leim/quail/georgian.el" +;;;;;; "leim/quail/greek.el" "leim/quail/hanja-jis.el" "leim/quail/hanja.el" +;;;;;; "leim/quail/hanja3.el" "leim/quail/hebrew.el" "leim/quail/ipa-praat.el" +;;;;;; "leim/quail/latin-alt.el" "leim/quail/latin-ltx.el" "leim/quail/latin-post.el" +;;;;;; "leim/quail/latin-pre.el" "leim/quail/persian.el" "leim/quail/programmer-dvorak.el" ;;;;;; "leim/quail/py-punct.el" "leim/quail/pypunct-b5.el" "leim/quail/quick-b5.el" ;;;;;; "leim/quail/quick-cns.el" "leim/quail/rfc1345.el" "leim/quail/sami.el" ;;;;;; "leim/quail/sgml-input.el" "leim/quail/slovak.el" "leim/quail/symbol-ksc.el" @@ -38743,14 +38510,17 @@ Zone out, completely." t nil) ;;;;;; "mh-e/mh-loaddefs.el" "minibuffer.el" "mouse.el" "net/tramp-loaddefs.el" ;;;;;; "newcomment.el" "obarray.el" "org/ob-core.el" "org/ob-lob.el" ;;;;;; "org/ob-matlab.el" "org/ob-tangle.el" "org/ob.el" "org/ol-bbdb.el" -;;;;;; "org/ol-irc.el" "org/org-archive.el" "org/org-attach.el" -;;;;;; "org/org-clock.el" "org/org-datetree.el" "org/org-element.el" -;;;;;; "org/org-feed.el" "org/org-footnote.el" "org/org-id.el" "org/org-indent.el" -;;;;;; "org/org-install.el" "org/org-mobile.el" "org/org-plot.el" +;;;;;; "org/ol-irc.el" "org/ol.el" "org/org-archive.el" "org/org-attach.el" +;;;;;; "org/org-clock.el" "org/org-colview.el" "org/org-compat.el" +;;;;;; "org/org-datetree.el" "org/org-duration.el" "org/org-element.el" +;;;;;; "org/org-feed.el" "org/org-footnote.el" "org/org-goto.el" +;;;;;; "org/org-id.el" "org/org-indent.el" "org/org-install.el" +;;;;;; "org/org-keys.el" "org/org-lint.el" "org/org-list.el" "org/org-macs.el" +;;;;;; "org/org-mobile.el" "org/org-num.el" "org/org-plot.el" "org/org-refile.el" ;;;;;; "org/org-table.el" "org/org-timer.el" "org/ox-ascii.el" "org/ox-beamer.el" ;;;;;; "org/ox-html.el" "org/ox-icalendar.el" "org/ox-latex.el" -;;;;;; "org/ox-man.el" "org/ox-md.el" "org/ox-odt.el" "org/ox-org.el" -;;;;;; "org/ox-publish.el" "org/ox-texinfo.el" "org/ox.el" "progmodes/elisp-mode.el" +;;;;;; "org/ox-md.el" "org/ox-odt.el" "org/ox-org.el" "org/ox-publish.el" +;;;;;; "org/ox-texinfo.el" "org/ox.el" "progmodes/elisp-mode.el" ;;;;;; "progmodes/prog-mode.el" "ps-mule.el" "register.el" "replace.el" ;;;;;; "rfn-eshadow.el" "select.el" "simple.el" "startup.el" "subdirs.el" ;;;;;; "subr.el" "tab-bar.el" "textmodes/fill.el" "textmodes/page.el" commit f0deca159d006f23da8f179cbf4ec96cbfa883df Author: Glenn Morris Date: Fri Jan 1 06:16:29 2021 -0800 ; Auto-commit of loaddefs files. diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index ecba0f5f41..7d4c7b84bf 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -12098,13 +12098,13 @@ Set the base remapping of FACE in the current buffer to SPECS. This causes the remappings specified by `face-remap-add-relative' to apply on top of the face specification given by SPECS. -The remaining arguments, SPECS, should form a list of faces. -Each list element should be either a face name or a property list +The remaining arguments, SPECS, specify the base of the remapping. +Each one of SPECS should be either a face name or a property list of face attribute/value pairs, like in a `face' text property. -If SPECS is empty, call `face-remap-reset-base' to use the normal -definition of FACE as the base remapping; note that this is -different from SPECS containing a single value nil, which means +If SPECS is empty or a single face `eq' to FACE, call `face-remap-reset-base' +to use the normal definition of FACE as the base remapping; note that +this is different from SPECS containing a single value nil, which means not to inherit from the global definition of FACE at all. \(fn FACE &rest SPECS)" nil nil) @@ -23319,7 +23319,7 @@ Coloring: ;;;### (autoloads nil "org" "org/org.el" (0 0 0 0)) ;;; Generated autoloads from org/org.el -(push (purecopy '(org 9 4 3)) package--builtin-versions) +(push (purecopy '(org 9 4 4)) package--builtin-versions) (autoload 'org-babel-do-load-languages "org" "\ Load the languages defined in `org-babel-load-languages'. @@ -23517,10 +23517,278 @@ Call the customize function with org as argument." t nil) ;;;*** -;;;### (autoloads "actual autoloads are elsewhere" "org-agenda" "org/org-agenda.el" -;;;;;; (0 0 0 0)) +;;;### (autoloads nil "org-agenda" "org/org-agenda.el" (0 0 0 0)) ;;; Generated autoloads from org/org-agenda.el +(autoload 'org-toggle-sticky-agenda "org-agenda" "\ +Toggle `org-agenda-sticky'. + +\(fn &optional ARG)" t nil) + +(autoload 'org-agenda "org-agenda" "\ +Dispatch agenda commands to collect entries to the agenda buffer. +Prompts for a command to execute. Any prefix arg will be passed +on to the selected command. The default selections are: + +a Call `org-agenda-list' to display the agenda for current day or week. +t Call `org-todo-list' to display the global todo list. +T Call `org-todo-list' to display the global todo list, select only + entries with a specific TODO keyword (the user gets a prompt). +m Call `org-tags-view' to display headlines with tags matching + a condition (the user is prompted for the condition). +M Like `m', but select only TODO entries, no ordinary headlines. +e Export views to associated files. +s Search entries for keywords. +S Search entries for keywords, only with TODO keywords. +/ Multi occur across all agenda files and also files listed + in `org-agenda-text-search-extra-files'. +< Restrict agenda commands to buffer, subtree, or region. + Press several times to get the desired effect. +> Remove a previous restriction. +# List \"stuck\" projects. +! Configure what \"stuck\" means. +C Configure custom agenda commands. + +More commands can be added by configuring the variable +`org-agenda-custom-commands'. In particular, specific tags and TODO keyword +searches can be pre-defined in this way. + +If the current buffer is in Org mode and visiting a file, you can also +first press `<' once to indicate that the agenda should be temporarily +\(until the next use of `\\[org-agenda]') restricted to the current file. +Pressing `<' twice means to restrict to the current subtree or region +\(if active). + +\(fn &optional ARG ORG-KEYS RESTRICTION)" t nil) + +(autoload 'org-batch-agenda "org-agenda" "\ +Run an agenda command in batch mode and send the result to STDOUT. +If CMD-KEY is a string of length 1, it is used as a key in +`org-agenda-custom-commands' and triggers this command. If it is a +longer string it is used as a tags/todo match string. +Parameters are alternating variable names and values that will be bound +before running the agenda command. + +\(fn CMD-KEY &rest PARAMETERS)" nil t) + +(autoload 'org-batch-agenda-csv "org-agenda" "\ +Run an agenda command in batch mode and send the result to STDOUT. +If CMD-KEY is a string of length 1, it is used as a key in +`org-agenda-custom-commands' and triggers this command. If it is a +longer string it is used as a tags/todo match string. +Parameters are alternating variable names and values that will be bound +before running the agenda command. + +The output gives a line for each selected agenda item. Each +item is a list of comma-separated values, like this: + +category,head,type,todo,tags,date,time,extra,priority-l,priority-n + +category The category of the item +head The headline, without TODO kwd, TAGS and PRIORITY +type The type of the agenda entry, can be + todo selected in TODO match + tagsmatch selected in tags match + diary imported from diary + deadline a deadline on given date + scheduled scheduled on given date + timestamp entry has timestamp on given date + closed entry was closed on given date + upcoming-deadline warning about deadline + past-scheduled forwarded scheduled item + block entry has date block including g. date +todo The todo keyword, if any +tags All tags including inherited ones, separated by colons +date The relevant date, like 2007-2-14 +time The time, like 15:00-16:50 +extra String with extra planning info +priority-l The priority letter if any was given +priority-n The computed numerical priority +agenda-day The day in the agenda where this is listed + +\(fn CMD-KEY &rest PARAMETERS)" nil t) + +(autoload 'org-store-agenda-views "org-agenda" "\ +Store agenda views. + +\(fn &rest PARAMETERS)" t nil) + +(autoload 'org-batch-store-agenda-views "org-agenda" "\ +Run all custom agenda commands that have a file argument. + +\(fn &rest PARAMETERS)" nil t) + +(autoload 'org-agenda-list "org-agenda" "\ +Produce a daily/weekly view from all files in variable `org-agenda-files'. +The view will be for the current day or week, but from the overview buffer +you will be able to go to other days/weeks. + +With a numeric prefix argument in an interactive call, the agenda will +span ARG days. Lisp programs should instead specify SPAN to change +the number of days. SPAN defaults to `org-agenda-span'. + +START-DAY defaults to TODAY, or to the most recent match for the weekday +given in `org-agenda-start-on-weekday'. + +When WITH-HOUR is non-nil, only include scheduled and deadline +items if they have an hour specification like [h]h:mm. + +\(fn &optional ARG START-DAY SPAN WITH-HOUR)" t nil) + +(autoload 'org-search-view "org-agenda" "\ +Show all entries that contain a phrase or words or regular expressions. + +With optional prefix argument TODO-ONLY, only consider entries that are +TODO entries. The argument STRING can be used to pass a default search +string into this function. If EDIT-AT is non-nil, it means that the +user should get a chance to edit this string, with cursor at position +EDIT-AT. + +The search string can be viewed either as a phrase that should be found as +is, or it can be broken into a number of snippets, each of which must match +in a Boolean way to select an entry. The default depends on the variable +`org-agenda-search-view-always-boolean'. +Even if this is turned off (the default) you can always switch to +Boolean search dynamically by preceding the first word with \"+\" or \"-\". + +The default is a direct search of the whole phrase, where each space in +the search string can expand to an arbitrary amount of whitespace, +including newlines. + +If using a Boolean search, the search string is split on whitespace and +each snippet is searched separately, with logical AND to select an entry. +Words prefixed with a minus must *not* occur in the entry. Words without +a prefix or prefixed with a plus must occur in the entry. Matching is +case-insensitive. Words are enclosed by word delimiters (i.e. they must +match whole words, not parts of a word) if +`org-agenda-search-view-force-full-words' is set (default is nil). + +Boolean search snippets enclosed by curly braces are interpreted as +regular expressions that must or (when preceded with \"-\") must not +match in the entry. Snippets enclosed into double quotes will be taken +as a whole, to include whitespace. + +- If the search string starts with an asterisk, search only in headlines. +- If (possibly after the leading star) the search string starts with an + exclamation mark, this also means to look at TODO entries only, an effect + that can also be achieved with a prefix argument. +- If (possibly after star and exclamation mark) the search string starts + with a colon, this will mean that the (non-regexp) snippets of the + Boolean search must match as full words. + +This command searches the agenda files, and in addition the files +listed in `org-agenda-text-search-extra-files' unless a restriction lock +is active. + +\(fn &optional TODO-ONLY STRING EDIT-AT)" t nil) + +(autoload 'org-todo-list "org-agenda" "\ +Show all (not done) TODO entries from all agenda file in a single list. +The prefix arg can be used to select a specific TODO keyword and limit +the list to these. When using `\\[universal-argument]', you will be prompted +for a keyword. A numeric prefix directly selects the Nth keyword in +`org-todo-keywords-1'. + +\(fn &optional ARG)" t nil) + +(autoload 'org-tags-view "org-agenda" "\ +Show all headlines for all `org-agenda-files' matching a TAGS criterion. +The prefix arg TODO-ONLY limits the search to TODO entries. + +\(fn &optional TODO-ONLY MATCH)" t nil) + +(autoload 'org-agenda-list-stuck-projects "org-agenda" "\ +Create agenda view for projects that are stuck. +Stuck projects are project that have no next actions. For the definitions +of what a project is and how to check if it stuck, customize the variable +`org-stuck-projects'. + +\(fn &rest IGNORE)" t nil) + +(autoload 'org-diary "org-agenda" "\ +Return diary information from org files. +This function can be used in a \"sexp\" diary entry in the Emacs calendar. +It accesses org files and extracts information from those files to be +listed in the diary. The function accepts arguments specifying what +items should be listed. For a list of arguments allowed here, see the +variable `org-agenda-entry-types'. + +The call in the diary file should look like this: + + &%%(org-diary) ~/path/to/some/orgfile.org + +Use a separate line for each org file to check. Or, if you omit the file name, +all files listed in `org-agenda-files' will be checked automatically: + + &%%(org-diary) + +If you don't give any arguments (as in the example above), the default value +of `org-agenda-entry-types' is used: (:deadline :scheduled :timestamp :sexp). +So the example above may also be written as + + &%%(org-diary :deadline :timestamp :sexp :scheduled) + +The function expects the lisp variables `entry' and `date' to be provided +by the caller, because this is how the calendar works. Don't use this +function from a program - use `org-agenda-get-day-entries' instead. + +\(fn &rest ARGS)" nil nil) + +(autoload 'org-agenda-check-for-timestamp-as-reason-to-ignore-todo-item "org-agenda" "\ +Do we have a reason to ignore this TODO entry because it has a time stamp? + +\(fn &optional END)" nil nil) + +(autoload 'org-agenda-set-restriction-lock "org-agenda" "\ +Set restriction lock for agenda to current subtree or file. +When in a restricted subtree, remove it. + +The restriction will span over the entire file if TYPE is `file', +or if type is '(4), or if the cursor is before the first headline +in the file. Otherwise, only apply the restriction to the current +subtree. + +\(fn &optional TYPE)" t nil) + +(autoload 'org-calendar-goto-agenda "org-agenda" "\ +Compute the Org agenda for the calendar date displayed at the cursor. +This is a command that has to be installed in `calendar-mode-map'." t nil) + +(autoload 'org-agenda-to-appt "org-agenda" "\ +Activate appointments found in `org-agenda-files'. + +With a `\\[universal-argument]' prefix, refresh the list of appointments. + +If FILTER is t, interactively prompt the user for a regular +expression, and filter out entries that don't match it. + +If FILTER is a string, use this string as a regular expression +for filtering entries out. + +If FILTER is a function, filter out entries against which +calling the function returns nil. This function takes one +argument: an entry from `org-agenda-get-day-entries'. + +FILTER can also be an alist with the car of each cell being +either `headline' or `category'. For example: + + \\='((headline \"IMPORTANT\") + (category \"Work\")) + +will only add headlines containing IMPORTANT or headlines +belonging to the \"Work\" category. + +ARGS are symbols indicating what kind of entries to consider. +By default `org-agenda-to-appt' will use :deadline*, :scheduled* +\(i.e., deadlines and scheduled items with a hh:mm specification) +and :timestamp entries. See the docstring of `org-diary' for +details and examples. + +If an entry has a APPT_WARNTIME property, its value will be used +to override `appt-message-warning-time'. + +\(fn &optional REFRESH FILTER &rest ARGS)" t nil) + (if (fboundp 'register-definition-prefixes) (register-definition-prefixes "org-agenda" '("org-"))) ;;;*** @@ -23549,10 +23817,48 @@ Call the customize function with org as argument." t nil) ;;;*** -;;;### (autoloads "actual autoloads are elsewhere" "org-capture" -;;;;;; "org/org-capture.el" (0 0 0 0)) +;;;### (autoloads nil "org-capture" "org/org-capture.el" (0 0 0 0)) ;;; Generated autoloads from org/org-capture.el +(autoload 'org-capture-string "org-capture" "\ +Capture STRING with the template selected by KEYS. + +\(fn STRING &optional KEYS)" t nil) + +(autoload 'org-capture "org-capture" "\ +Capture something. +\\ +This will let you select a template from `org-capture-templates', and +then file the newly captured information. The text is immediately +inserted at the target location, and an indirect buffer is shown where +you can edit it. Pressing `\\[org-capture-finalize]' brings you back to the previous +state of Emacs, so that you can continue your work. + +When called interactively with a `\\[universal-argument]' prefix argument GOTO, don't +capture anything, just go to the file/headline where the selected +template stores its notes. + +With a `\\[universal-argument] \\[universal-argument]' prefix argument, go to the last note stored. + +When called with a `C-0' (zero) prefix, insert a template at point. + +When called with a `C-1' (one) prefix, force prompting for a date when +a datetree entry is made. + +ELisp programs can set KEYS to a string associated with a template +in `org-capture-templates'. In this case, interactive selection +will be bypassed. + +If `org-capture-use-agenda-date' is non-nil, capturing from the +agenda will use the date at point as the default date. Then, a +`C-1' prefix will tell the capture process to use the HH:MM time +of the day at point (if any) or the current HH:MM time. + +\(fn &optional GOTO KEYS)" t nil) + +(autoload 'org-capture-import-remember-templates "org-capture" "\ +Set `org-capture-templates' to be similar to `org-remember-templates'." t nil) + (if (fboundp 'register-definition-prefixes) (register-definition-prefixes "org-capture" '("org-capture-"))) ;;;*** @@ -38331,19 +38637,10 @@ Zone out, completely." t nil) ;;;;;; "eshell/em-unix.el" "eshell/em-xtra.el" "facemenu.el" "faces.el" ;;;;;; "files.el" "font-core.el" "font-lock.el" "format.el" "frame.el" ;;;;;; "help.el" "hfy-cmap.el" "ibuf-ext.el" "indent.el" "international/characters.el" -;;;;;; "international/charprop.el" "international/charscript.el" -;;;;;; "international/cp51932.el" "international/eucjp-ms.el" "international/mule-cmds.el" -;;;;;; "international/mule-conf.el" "international/mule.el" "international/uni-bidi.el" -;;;;;; "international/uni-brackets.el" "international/uni-category.el" -;;;;;; "international/uni-combining.el" "international/uni-comment.el" -;;;;;; "international/uni-decimal.el" "international/uni-decomposition.el" -;;;;;; "international/uni-digit.el" "international/uni-lowercase.el" -;;;;;; "international/uni-mirrored.el" "international/uni-name.el" -;;;;;; "international/uni-numeric.el" "international/uni-old-name.el" -;;;;;; "international/uni-special-lowercase.el" "international/uni-special-titlecase.el" -;;;;;; "international/uni-special-uppercase.el" "international/uni-titlecase.el" -;;;;;; "international/uni-uppercase.el" "isearch.el" "jit-lock.el" -;;;;;; "jka-cmpr-hook.el" "language/burmese.el" "language/cham.el" +;;;;;; "international/charscript.el" "international/cp51932.el" +;;;;;; "international/eucjp-ms.el" "international/mule-cmds.el" +;;;;;; "international/mule-conf.el" "international/mule.el" "isearch.el" +;;;;;; "jit-lock.el" "jka-cmpr-hook.el" "language/burmese.el" "language/cham.el" ;;;;;; "language/chinese.el" "language/cyrillic.el" "language/czech.el" ;;;;;; "language/english.el" "language/ethiopic.el" "language/european.el" ;;;;;; "language/georgian.el" "language/greek.el" "language/hebrew.el" @@ -38376,26 +38673,25 @@ Zone out, completely." t nil) ;;;;;; "minibuffer.el" "mouse.el" "net/tramp-loaddefs.el" "newcomment.el" ;;;;;; "obarray.el" "org/ob-core.el" "org/ob-lob.el" "org/ob-matlab.el" ;;;;;; "org/ob-tangle.el" "org/ob.el" "org/ol-bbdb.el" "org/ol-irc.el" -;;;;;; "org/ol.el" "org/org-agenda.el" "org/org-archive.el" "org/org-attach.el" -;;;;;; "org/org-capture.el" "org/org-clock.el" "org/org-colview.el" -;;;;;; "org/org-compat.el" "org/org-datetree.el" "org/org-duration.el" -;;;;;; "org/org-element.el" "org/org-feed.el" "org/org-footnote.el" -;;;;;; "org/org-goto.el" "org/org-id.el" "org/org-indent.el" "org/org-install.el" -;;;;;; "org/org-keys.el" "org/org-lint.el" "org/org-list.el" "org/org-macs.el" -;;;;;; "org/org-mobile.el" "org/org-num.el" "org/org-plot.el" "org/org-refile.el" -;;;;;; "org/org-table.el" "org/org-timer.el" "org/ox-ascii.el" "org/ox-beamer.el" -;;;;;; "org/ox-html.el" "org/ox-icalendar.el" "org/ox-latex.el" -;;;;;; "org/ox-md.el" "org/ox-odt.el" "org/ox-org.el" "org/ox-publish.el" -;;;;;; "org/ox-texinfo.el" "org/ox.el" "progmodes/elisp-mode.el" -;;;;;; "progmodes/prog-mode.el" "ps-mule.el" "register.el" "replace.el" -;;;;;; "rfn-eshadow.el" "select.el" "simple.el" "startup.el" "subdirs.el" -;;;;;; "subr.el" "tab-bar.el" "textmodes/fill.el" "textmodes/page.el" -;;;;;; "textmodes/paragraphs.el" "textmodes/reftex-auc.el" "textmodes/reftex-cite.el" -;;;;;; "textmodes/reftex-dcr.el" "textmodes/reftex-global.el" "textmodes/reftex-index.el" -;;;;;; "textmodes/reftex-parse.el" "textmodes/reftex-ref.el" "textmodes/reftex-sel.el" -;;;;;; "textmodes/reftex-toc.el" "textmodes/text-mode.el" "uniquify.el" -;;;;;; "vc/ediff-hook.el" "vc/vc-hooks.el" "version.el" "widget.el" -;;;;;; "window.el") (0 0 0 0)) +;;;;;; "org/ol.el" "org/org-archive.el" "org/org-attach.el" "org/org-clock.el" +;;;;;; "org/org-colview.el" "org/org-compat.el" "org/org-datetree.el" +;;;;;; "org/org-duration.el" "org/org-element.el" "org/org-feed.el" +;;;;;; "org/org-footnote.el" "org/org-goto.el" "org/org-id.el" "org/org-indent.el" +;;;;;; "org/org-install.el" "org/org-keys.el" "org/org-lint.el" +;;;;;; "org/org-list.el" "org/org-macs.el" "org/org-mobile.el" "org/org-num.el" +;;;;;; "org/org-plot.el" "org/org-refile.el" "org/org-table.el" +;;;;;; "org/org-timer.el" "org/ox-ascii.el" "org/ox-beamer.el" "org/ox-html.el" +;;;;;; "org/ox-icalendar.el" "org/ox-latex.el" "org/ox-md.el" "org/ox-odt.el" +;;;;;; "org/ox-org.el" "org/ox-publish.el" "org/ox-texinfo.el" "org/ox.el" +;;;;;; "progmodes/elisp-mode.el" "progmodes/prog-mode.el" "ps-mule.el" +;;;;;; "register.el" "replace.el" "rfn-eshadow.el" "select.el" "simple.el" +;;;;;; "startup.el" "subdirs.el" "subr.el" "tab-bar.el" "textmodes/fill.el" +;;;;;; "textmodes/page.el" "textmodes/paragraphs.el" "textmodes/reftex-auc.el" +;;;;;; "textmodes/reftex-cite.el" "textmodes/reftex-dcr.el" "textmodes/reftex-global.el" +;;;;;; "textmodes/reftex-index.el" "textmodes/reftex-parse.el" "textmodes/reftex-ref.el" +;;;;;; "textmodes/reftex-sel.el" "textmodes/reftex-toc.el" "textmodes/text-mode.el" +;;;;;; "uniquify.el" "vc/ediff-hook.el" "vc/vc-hooks.el" "version.el" +;;;;;; "widget.el" "window.el") (0 0 0 0)) ;;;*** commit a516e6986383b8fd0b840cd2e18ac3212bf2550d Author: Dmitry Gutov Date: Fri Jan 1 15:18:41 2021 +0200 xref-show-definitions-completing-read: Default to the first location * lisp/progmodes/xref.el (xref-show-definitions-completing-read): Default to the first location. diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 04798de76f..29e7b6849f 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -1057,9 +1057,12 @@ between them by typing in the minibuffer with completion." ((eq action 'metadata) '(metadata . ((category . xref-location)))) (t - (complete-with-action action collection string pred)))))) + (complete-with-action action collection string pred))))) + (def (caar collection))) (cdr (assoc (completing-read "Choose definition: " - ctable nil t) + ctable nil t + nil nil + def) collection))))) (xref-pop-to-location xref (assoc-default 'display-action alist)))) commit 3ea7cec4c0d7f76fd5adeb00b03fabd2ef3b756d Author: Dmitry Gutov Date: Fri Jan 1 14:35:57 2021 +0200 ; ruby-smie--bosp: Fix the breakage diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 9acd7b4787..155a1609d3 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -403,8 +403,8 @@ It is used when `ruby-encoding-magic-comment-style' is set to `custom'." (not (eq (char-before (1- (point))) ?\\))) (eq (char-before) ?\;) (and (eq (char-before) ?=) - (eq (syntax-after (1- (point))) - (string-to-syntax ".")))))) + (equal (syntax-after (1- (point))) + (string-to-syntax ".")))))) (defun ruby-smie--implicit-semi-p () (save-excursion commit 7384ec6416cbcea12a65db058e5a65e40d3a157f Author: Eli Zaretskii Date: Fri Jan 1 13:52:37 2021 +0200 Add warning comments abound binding keys in Isearch maps * lisp/isearch.el (isearch-mode-map) (minibuffer-local-isearch-map): Add comments which warn against wantonly rebinding unbound keys. diff --git a/lisp/isearch.el b/lisp/isearch.el index ac0ebc735d..cbe72efb80 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -655,6 +655,10 @@ This is like `describe-bindings', but displays only Isearch keys." (if isearch-success 'isearch-abort binding)))) map)) +;; Note: Before adding more key bindings to this map, please keep in +;; mind that any unbound key exits Isearch and runs the command bound +;; to it in the local or global map. So in effect every key unbound +;; in this map is implicitly bound. (defvar isearch-mode-map (let ((i 0) (map (make-keymap))) @@ -819,6 +823,10 @@ This is like `describe-bindings', but displays only Isearch keys." :image '(isearch-tool-bar-image "left-arrow"))) map)) +;; Note: Before adding more key bindings to this map, please keep in +;; mind that any unbound key exits Isearch and runs the command bound +;; to it in the local or global map. So in effect every key unbound +;; in this map is implicitly bound. (defvar minibuffer-local-isearch-map (let ((map (make-sparse-keymap))) (set-keymap-parent map minibuffer-local-map) commit 0273cb61a4bb8a7ddd2dccf0d67d5da8c3da6a42 Author: Philipp Stephani Date: Fri Jan 1 12:39:14 2021 +0100 Fix a compilation warning. ruby-mode uses 'cl-evenp' at runtime, so cl-lib must be available at runtime as well. * lisp/progmodes/ruby-mode.el (cl-lib): Require at runtime as well. diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 5635bf1cab..9acd7b4787 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -32,7 +32,7 @@ ;;; Code: -(eval-when-compile (require 'cl-lib)) +(require 'cl-lib) (defgroup ruby nil "Major mode for editing Ruby code." commit 3711339f92be0c50633aefae991d8fa4a135fe33 Author: Alan Third Date: Fri Jan 1 10:36:39 2021 +0000 Fix crash in ns_mouse_position (bug#45541) * src/nsterm.m (ns_mouse_position): Explicitly initialize f to NULL. ; Do not merge to master diff --git a/src/nsterm.m b/src/nsterm.m index b75c6c7ef5..b8658a05da 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -2480,7 +2480,7 @@ so some key presses (TAB) are swallowed by the system. */ id view; NSPoint view_position; Lisp_Object frame, tail; - struct frame *f; + struct frame *f = NULL; struct ns_display_info *dpyinfo; NSTRACE ("ns_mouse_position"); commit 30a1d5da7a43d51a97cbe8d91add9a26dd99df90 Author: Paul Eggert Date: Fri Jan 1 02:03:46 2021 -0800 Remove stray copy of image-tests.el * test/manual/image-circular-tests.el: Remove a stray copy of image-tests.el that was appended to this file. Found by its duplicate copyright notice. diff --git a/test/manual/image-circular-tests.el b/test/manual/image-circular-tests.el index 28b5f892e5..3d1d23234b 100644 --- a/test/manual/image-circular-tests.el +++ b/test/manual/image-circular-tests.el @@ -1,4 +1,4 @@ -;;; image-tests.el --- Test suite for image-related functions. +;;; image-circular-tests.el --- test image functions with circular objects ;; Copyright (C) 2019, 2021 Free Software Foundation, Inc. @@ -61,84 +61,5 @@ (and (equal (image-size spec1 t) (cons 1 1)) (equal (image-size spec2 t) (cons 1 1)))))) -(provide 'image-tests) -;;; image-tests.el ends here. -;;; image-tests.el --- tests for image.el -*- lexical-binding: t -*- - -;; Copyright (C) 2019-2020 Free Software Foundation, Inc. - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software: you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs. If not, see . - -;;; Code: - -(require 'ert) -(require 'image) -(eval-when-compile - (require 'cl-lib)) - -(defconst image-tests--emacs-images-directory - (expand-file-name "../etc/images" (getenv "EMACS_TEST_DIRECTORY")) - "Directory containing Emacs images.") - -(ert-deftest image--set-property () - "Test `image--set-property' behavior." - (let ((image (list 'image))) - ;; Add properties. - (setf (image-property image :scale) 1) - (should (equal image '(image :scale 1))) - (setf (image-property image :width) 8) - (should (equal image '(image :scale 1 :width 8))) - (setf (image-property image :height) 16) - (should (equal image '(image :scale 1 :width 8 :height 16))) - ;; Delete properties. - (setf (image-property image :type) nil) - (should (equal image '(image :scale 1 :width 8 :height 16))) - (setf (image-property image :scale) nil) - (should (equal image '(image :width 8 :height 16))) - (setf (image-property image :height) nil) - (should (equal image '(image :width 8))) - (setf (image-property image :width) nil) - (should (equal image '(image))))) - -(ert-deftest image-type-from-file-header-test () - "Test image-type-from-file-header." - (should (eq (if (image-type-available-p 'svg) 'svg) - (image-type-from-file-header - (expand-file-name "splash.svg" - image-tests--emacs-images-directory))))) - -(ert-deftest image-rotate () - "Test `image-rotate'." - (cl-letf* ((image (list 'image)) - ((symbol-function 'image--get-imagemagick-and-warn) - (lambda () image))) - (let ((current-prefix-arg '(4))) - (call-interactively #'image-rotate)) - (should (equal image '(image :rotation 270.0))) - (call-interactively #'image-rotate) - (should (equal image '(image :rotation 0.0))) - (image-rotate) - (should (equal image '(image :rotation 90.0))) - (image-rotate 0) - (should (equal image '(image :rotation 90.0))) - (image-rotate 1) - (should (equal image '(image :rotation 91.0))) - (image-rotate 1234.5) - (should (equal image '(image :rotation 245.5))) - (image-rotate -154.5) - (should (equal image '(image :rotation 91.0))))) - -;;; image-tests.el ends here +(provide 'image-circular-tests) +;;; image-circular-tests.el ends here. commit 1b59478f4cf442f5201500b0a9c66f4332fce640 Author: Paul Eggert Date: Fri Jan 1 01:51:18 2021 -0800 Update from Gnulib by running admin/merge-gnulib. diff --git a/build-aux/config.guess b/build-aux/config.guess index 35dd8a1a3e..7f74817797 100755 --- a/build-aux/config.guess +++ b/build-aux/config.guess @@ -1,6 +1,6 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2021 Free Software Foundation, Inc. +# Copyright 1992-2020 Free Software Foundation, Inc. timestamp='2020-12-22' diff --git a/build-aux/config.sub b/build-aux/config.sub index 1208219189..90bb8aeda6 100755 --- a/build-aux/config.sub +++ b/build-aux/config.sub @@ -1,6 +1,6 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2021 Free Software Foundation, Inc. +# Copyright 1992-2020 Free Software Foundation, Inc. timestamp='2020-12-22' diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex index 5be2e13a67..3c7051d1c7 100644 --- a/doc/misc/texinfo.tex +++ b/doc/misc/texinfo.tex @@ -5,7 +5,7 @@ % \def\texinfoversion{2020-10-24.12} % -% Copyright 1985--1986, 1988, 1990--2021 Free Software Foundation, Inc. +% Copyright 1985, 1986, 1988, 1990-2020 Free Software Foundation, Inc. % % This texinfo.tex file is free software: you can redistribute it and/or % modify it under the terms of the GNU General Public License as diff --git a/lib/alloca.in.h b/lib/alloca.in.h index d165308106..0a6137e037 100644 --- a/lib/alloca.in.h +++ b/lib/alloca.in.h @@ -1,7 +1,7 @@ /* Memory allocation on the stack. - Copyright (C) 1995, 1999, 2001-2004, 2006-2021 Free Software - Foundation, Inc. + Copyright (C) 1995, 1999, 2001-2004, 2006-2021 Free Software Foundation, + Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published diff --git a/lib/binary-io.h b/lib/binary-io.h index d56be18309..8654fd2d39 100644 --- a/lib/binary-io.h +++ b/lib/binary-io.h @@ -1,6 +1,5 @@ /* Binary mode I/O. - Copyright (C) 2001, 2003, 2005, 2008-2021 Free Software Foundation, - Inc. + Copyright (C) 2001, 2003, 2005, 2008-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/c-ctype.h b/lib/c-ctype.h index 231611b7f6..bf24a88310 100644 --- a/lib/c-ctype.h +++ b/lib/c-ctype.h @@ -5,8 +5,7 @@ functions' behaviour depends on the current locale set via setlocale. - Copyright (C) 2000-2003, 2006, 2008-2021 Free Software Foundation, - Inc. + Copyright (C) 2000-2003, 2006, 2008-2021 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/c-strcasecmp.c b/lib/c-strcasecmp.c index 10f23e924a..55479d6a33 100644 --- a/lib/c-strcasecmp.c +++ b/lib/c-strcasecmp.c @@ -1,6 +1,5 @@ /* c-strcasecmp.c -- case insensitive string comparator in C locale - Copyright (C) 1998-1999, 2005-2006, 2009-2021 Free Software - Foundation, Inc. + Copyright (C) 1998-1999, 2005-2006, 2009-2021 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/c-strncasecmp.c b/lib/c-strncasecmp.c index ad7bfeb7db..02bc0f2ecd 100644 --- a/lib/c-strncasecmp.c +++ b/lib/c-strncasecmp.c @@ -1,6 +1,5 @@ /* c-strncasecmp.c -- case insensitive string comparator in C locale - Copyright (C) 1998-1999, 2005-2006, 2009-2021 Free Software - Foundation, Inc. + Copyright (C) 1998-1999, 2005-2006, 2009-2021 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c index dcc6e12d9c..b6dc3a447a 100644 --- a/lib/canonicalize-lgpl.c +++ b/lib/canonicalize-lgpl.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -40,16 +39,11 @@ #include #include #include +#include #include #ifdef _LIBC # include -# include -# ifdef __ASSUME_FACCESSAT2 -# define FACCESSAT_NEVER_EOVERFLOWS __ASSUME_FACCESSAT2 -# else -# define FACCESSAT_NEVER_EOVERFLOWS true -# endif # define GCC_LINT 1 # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) #else @@ -91,14 +85,15 @@ # define IF_LINT(Code) /* empty */ #endif +/* True if adding two valid object sizes might overflow idx_t. + As a practical matter, this cannot happen on 64-bit machines. */ +enum { NARROW_ADDRESSES = IDX_MAX >> 31 >> 31 == 0 }; + #ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT # define DOUBLE_SLASH_IS_DISTINCT_ROOT false #endif -#ifndef FACCESSAT_NEVER_EOVERFLOWS -# define FACCESSAT_NEVER_EOVERFLOWS false -#endif -#if !FUNC_REALPATH_WORKS || defined _LIBC +#if defined _LIBC || !FUNC_REALPATH_WORKS /* Return true if FILE's existence can be shown, false (setting errno) otherwise. Follow symbolic links. */ @@ -106,14 +101,11 @@ static bool file_accessible (char const *file) { # if defined _LIBC || HAVE_FACCESSAT - int r = __faccessat (AT_FDCWD, file, F_OK, AT_EACCESS); + return __faccessat (AT_FDCWD, file, F_OK, AT_EACCESS) == 0; # else struct stat st; - int r = __stat (file, &st); + return __stat (file, &st) == 0 || errno == EOVERFLOW; # endif - - return ((!FACCESSAT_NEVER_EOVERFLOWS && r < 0 && errno == EOVERFLOW) - || r == 0); } /* True if concatenating END as a suffix to a file name means that the @@ -350,7 +342,12 @@ realpath_stk (const char *name, char *resolved, idx_t end_idx IF_LINT (= 0); if (end_in_extra_buffer) end_idx = end - extra_buf; - idx_t len = strlen (end); + size_t len = strlen (end); + if (NARROW_ADDRESSES && INT_ADD_OVERFLOW (len, n)) + { + __set_errno (ENOMEM); + goto error_nomem; + } while (extra_buffer.length <= len + n) { if (!scratch_buffer_grow_preserve (&extra_buffer)) @@ -413,24 +410,14 @@ realpath_stk (const char *name, char *resolved, error_nomem: scratch_buffer_free (&extra_buffer); scratch_buffer_free (&link_buffer); - if (failed || rname == resolved) - scratch_buffer_free (rname_buf); - - if (failed) - return NULL; - if (rname == resolved) - return rname; - idx_t rname_size = dest - rname; - if (rname == rname_on_stack) + if (failed || rname == resolved) { - rname = malloc (rname_size); - if (rname == NULL) - return NULL; - return memcpy (rname, rname_on_stack, rname_size); + scratch_buffer_free (rname_buf); + return failed ? NULL : resolved; } - char *result = realloc (rname, rname_size); - return result != NULL ? result : rname; + + return scratch_buffer_dupfree (rname_buf, dest - rname); } /* Return the canonical absolute name of file NAME. A canonical name diff --git a/lib/careadlinkat.c b/lib/careadlinkat.c index c6d7c35eff..18cfc114b6 100644 --- a/lib/careadlinkat.c +++ b/lib/careadlinkat.c @@ -1,7 +1,7 @@ /* Read symbolic links into a buffer without size limitation, relative to fd. - Copyright (C) 2001, 2003-2004, 2007, 2009-2021 Free Software - Foundation, Inc. + Copyright (C) 2001, 2003-2004, 2007, 2009-2021 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/cloexec.c b/lib/cloexec.c index 3286ad3432..8363ddaa60 100644 --- a/lib/cloexec.c +++ b/lib/cloexec.c @@ -1,7 +1,6 @@ /* cloexec.c - set or clear the close-on-exec descriptor flag - Copyright (C) 1991, 2004-2006, 2009-2021 Free Software Foundation, - Inc. + Copyright (C) 1991, 2004-2006, 2009-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/close-stream.c b/lib/close-stream.c index 11cc11fe99..86f6d6e1de 100644 --- a/lib/close-stream.c +++ b/lib/close-stream.c @@ -1,7 +1,6 @@ /* Close a stream, with nicer error checking than fclose's. - Copyright (C) 1998-2002, 2004, 2006-2021 Free Software Foundation, - Inc. + Copyright (C) 1998-2002, 2004, 2006-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/diffseq.h b/lib/diffseq.h index 570f09d6be..1cac430edd 100644 --- a/lib/diffseq.h +++ b/lib/diffseq.h @@ -1,7 +1,7 @@ /* Analyze differences between two vectors. - Copyright (C) 1988-1989, 1992-1995, 2001-2004, 2006-2021 Free - Software Foundation, Inc. + Copyright (C) 1988-1989, 1992-1995, 2001-2004, 2006-2021 Free Software + Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/dup2.c b/lib/dup2.c index 0a17c811ac..c4a0a29fbd 100644 --- a/lib/dup2.c +++ b/lib/dup2.c @@ -1,7 +1,6 @@ /* Duplicate an open file descriptor to a specified file descriptor. - Copyright (C) 1999, 2004-2007, 2009-2021 Free Software Foundation, - Inc. + Copyright (C) 1999, 2004-2007, 2009-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/faccessat.c b/lib/faccessat.c index 93e99b48f0..3a776466cf 100644 --- a/lib/faccessat.c +++ b/lib/faccessat.c @@ -32,13 +32,6 @@ #include #undef _GL_INCLUDING_UNISTD_H -#ifndef FACCESSAT_NEVER_EOVERFLOWS -# define FACCESSAT_NEVER_EOVERFLOWS 0 -#endif -#ifndef LSTAT_FOLLOWS_SLASHED_SYMLINK -# define LSTAT_FOLLOWS_SLASHED_SYMLINK 0 -#endif - #if HAVE_FACCESSAT static int orig_faccessat (int fd, char const *name, int mode, int flag) @@ -66,12 +59,7 @@ rpl_faccessat (int fd, char const *file, int mode, int flag) { int result = orig_faccessat (fd, file, mode, flag); - if (result != 0) - { - if (!FACCESSAT_NEVER_EOVERFLOWS && mode == F_OK && errno == EOVERFLOW) - return 0; - } - else if (!LSTAT_FOLLOWS_SLASHED_SYMLINK && file[strlen (file) - 1] == '/') + if (result == 0 && file[strlen (file) - 1] == '/') { struct stat st; result = fstatat (fd, file, &st, 0); diff --git a/lib/fcntl.in.h b/lib/fcntl.in.h index cbc4af4dc4..0b14467c54 100644 --- a/lib/fcntl.in.h +++ b/lib/fcntl.in.h @@ -112,7 +112,7 @@ _GL_CXXALIASWARN (creat); /* Assume creat is always declared. */ _GL_WARN_ON_USE (creat, "creat is not always POSIX compliant - " "use gnulib module creat for portability"); -#else +#elif @GNULIB_MDA_CREAT@ /* On native Windows, map 'creat' to '_creat', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::creat always. */ @@ -186,7 +186,7 @@ _GL_CXXALIASWARN (open); /* Assume open is always declared. */ _GL_WARN_ON_USE (open, "open is not always POSIX compliant - " "use gnulib module open for portability"); -#else +#elif @GNULIB_MDA_OPEN@ /* On native Windows, map 'open' to '_open', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::open always. */ diff --git a/lib/filemode.h b/lib/filemode.h index dc240db270..a02facb757 100644 --- a/lib/filemode.h +++ b/lib/filemode.h @@ -1,7 +1,7 @@ /* Make a string describing file modes. - Copyright (C) 1998-1999, 2003, 2006, 2009-2021 Free Software - Foundation, Inc. + Copyright (C) 1998-1999, 2003, 2006, 2009-2021 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/filename.h b/lib/filename.h index 5bd86f4805..541ffec0d5 100644 --- a/lib/filename.h +++ b/lib/filename.h @@ -1,18 +1,20 @@ /* Basic filename support macros. Copyright (C) 2001-2004, 2007-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + You should have received a copy of the GNU General Public + License along with the GNU C Library; if not, see + . */ /* From Paul Eggert and Jim Meyering. */ diff --git a/lib/fpending.c b/lib/fpending.c index abcb596174..7c61f7eea7 100644 --- a/lib/fpending.c +++ b/lib/fpending.c @@ -1,6 +1,6 @@ /* fpending.c -- return the number of pending output bytes on a stream - Copyright (C) 2000, 2004, 2006-2007, 2009-2021 Free Software - Foundation, Inc. + Copyright (C) 2000, 2004, 2006-2007, 2009-2021 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/fpending.h b/lib/fpending.h index 246b62ffb3..016341bab5 100644 --- a/lib/fpending.h +++ b/lib/fpending.h @@ -1,7 +1,7 @@ /* Declare __fpending. - Copyright (C) 2000, 2003, 2005-2006, 2009-2021 Free Software - Foundation, Inc. + Copyright (C) 2000, 2003, 2005-2006, 2009-2021 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/fsusage.c b/lib/fsusage.c index 57116f28e5..35de136cd8 100644 --- a/lib/fsusage.c +++ b/lib/fsusage.c @@ -1,7 +1,7 @@ /* fsusage.c -- return space usage of mounted file systems - Copyright (C) 1991-1992, 1996, 1998-1999, 2002-2006, 2009-2021 Free - Software Foundation, Inc. + Copyright (C) 1991-1992, 1996, 1998-1999, 2002-2006, 2009-2021 Free Software + Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/getgroups.c b/lib/getgroups.c index a1bbb6617c..af602a74d3 100644 --- a/lib/getgroups.c +++ b/lib/getgroups.c @@ -1,7 +1,6 @@ /* provide consistent interface to getgroups for systems that don't allow N==0 - Copyright (C) 1996, 1999, 2003, 2006-2021 Free Software Foundation, - Inc. + Copyright (C) 1996, 1999, 2003, 2006-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/getloadavg.c b/lib/getloadavg.c index 8668ee3f2a..d42d0cd279 100644 --- a/lib/getloadavg.c +++ b/lib/getloadavg.c @@ -1,7 +1,7 @@ /* Get the system load averages. - Copyright (C) 1985-1989, 1991-1995, 1997, 1999-2000, 2003-2021 Free - Software Foundation, Inc. + Copyright (C) 1985-1989, 1991-1995, 1997, 1999-2000, 2003-2021 Free Software + Foundation, Inc. NOTE: The canonical source of this file is maintained with gnulib. Bugs can be reported to bug-gnulib@gnu.org. diff --git a/lib/gettext.h b/lib/gettext.h index 8c7c3a6132..3552157efd 100644 --- a/lib/gettext.h +++ b/lib/gettext.h @@ -1,6 +1,6 @@ /* Convenience header for conditional use of GNU . - Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2021 Free - Software Foundation, Inc. + Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2021 Free Software + Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/gettime.c b/lib/gettime.c index 82fac30002..fb721b2cda 100644 --- a/lib/gettime.c +++ b/lib/gettime.c @@ -1,7 +1,6 @@ /* gettime -- get the system clock - Copyright (C) 2002, 2004-2007, 2009-2021 Free Software Foundation, - Inc. + Copyright (C) 2002, 2004-2007, 2009-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/gettimeofday.c b/lib/gettimeofday.c index 363a2acb53..b1c93e1c3a 100644 --- a/lib/gettimeofday.c +++ b/lib/gettimeofday.c @@ -1,7 +1,6 @@ /* Provide gettimeofday for systems that don't have it or for which it's broken. - Copyright (C) 2001-2003, 2005-2007, 2009-2021 Free Software - Foundation, Inc. + Copyright (C) 2001-2003, 2005-2007, 2009-2021 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index 60358f717f..c457ac6120 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -242,7 +242,6 @@ GETOPT_CDEFS_H = @GETOPT_CDEFS_H@ GETOPT_H = @GETOPT_H@ GFILENOTIFY_CFLAGS = @GFILENOTIFY_CFLAGS@ GFILENOTIFY_LIBS = @GFILENOTIFY_LIBS@ -GLIBC21 = @GLIBC21@ GL_COND_LIBTOOL = @GL_COND_LIBTOOL@ GL_GENERATE_ALLOCA_H = @GL_GENERATE_ALLOCA_H@ GL_GENERATE_BYTESWAP_H = @GL_GENERATE_BYTESWAP_H@ @@ -277,6 +276,13 @@ GNULIB_DUP2 = @GNULIB_DUP2@ GNULIB_DUP3 = @GNULIB_DUP3@ GNULIB_ENVIRON = @GNULIB_ENVIRON@ GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@ +GNULIB_EXECL = @GNULIB_EXECL@ +GNULIB_EXECLE = @GNULIB_EXECLE@ +GNULIB_EXECLP = @GNULIB_EXECLP@ +GNULIB_EXECV = @GNULIB_EXECV@ +GNULIB_EXECVE = @GNULIB_EXECVE@ +GNULIB_EXECVP = @GNULIB_EXECVP@ +GNULIB_EXECVPE = @GNULIB_EXECVPE@ GNULIB_EXPLICIT_BZERO = @GNULIB_EXPLICIT_BZERO@ GNULIB_FACCESSAT = @GNULIB_FACCESSAT@ GNULIB_FCHDIR = @GNULIB_FCHDIR@ @@ -362,10 +368,51 @@ GNULIB_MBSSPN = @GNULIB_MBSSPN@ GNULIB_MBSSTR = @GNULIB_MBSSTR@ GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@ GNULIB_MBTOWC = @GNULIB_MBTOWC@ +GNULIB_MDA_ACCESS = @GNULIB_MDA_ACCESS@ +GNULIB_MDA_CHDIR = @GNULIB_MDA_CHDIR@ +GNULIB_MDA_CHMOD = @GNULIB_MDA_CHMOD@ +GNULIB_MDA_CLOSE = @GNULIB_MDA_CLOSE@ +GNULIB_MDA_CREAT = @GNULIB_MDA_CREAT@ +GNULIB_MDA_DUP = @GNULIB_MDA_DUP@ +GNULIB_MDA_DUP2 = @GNULIB_MDA_DUP2@ +GNULIB_MDA_ECVT = @GNULIB_MDA_ECVT@ +GNULIB_MDA_EXECL = @GNULIB_MDA_EXECL@ +GNULIB_MDA_EXECLE = @GNULIB_MDA_EXECLE@ +GNULIB_MDA_EXECLP = @GNULIB_MDA_EXECLP@ +GNULIB_MDA_EXECV = @GNULIB_MDA_EXECV@ +GNULIB_MDA_EXECVE = @GNULIB_MDA_EXECVE@ +GNULIB_MDA_EXECVP = @GNULIB_MDA_EXECVP@ +GNULIB_MDA_EXECVPE = @GNULIB_MDA_EXECVPE@ +GNULIB_MDA_FCLOSEALL = @GNULIB_MDA_FCLOSEALL@ +GNULIB_MDA_FCVT = @GNULIB_MDA_FCVT@ +GNULIB_MDA_FDOPEN = @GNULIB_MDA_FDOPEN@ +GNULIB_MDA_FILENO = @GNULIB_MDA_FILENO@ +GNULIB_MDA_GCVT = @GNULIB_MDA_GCVT@ +GNULIB_MDA_GETCWD = @GNULIB_MDA_GETCWD@ +GNULIB_MDA_GETPID = @GNULIB_MDA_GETPID@ +GNULIB_MDA_GETW = @GNULIB_MDA_GETW@ +GNULIB_MDA_ISATTY = @GNULIB_MDA_ISATTY@ +GNULIB_MDA_LSEEK = @GNULIB_MDA_LSEEK@ +GNULIB_MDA_MEMCCPY = @GNULIB_MDA_MEMCCPY@ +GNULIB_MDA_MKDIR = @GNULIB_MDA_MKDIR@ +GNULIB_MDA_MKTEMP = @GNULIB_MDA_MKTEMP@ +GNULIB_MDA_OPEN = @GNULIB_MDA_OPEN@ +GNULIB_MDA_PUTENV = @GNULIB_MDA_PUTENV@ +GNULIB_MDA_PUTW = @GNULIB_MDA_PUTW@ +GNULIB_MDA_READ = @GNULIB_MDA_READ@ +GNULIB_MDA_RMDIR = @GNULIB_MDA_RMDIR@ +GNULIB_MDA_STRDUP = @GNULIB_MDA_STRDUP@ +GNULIB_MDA_SWAB = @GNULIB_MDA_SWAB@ +GNULIB_MDA_TEMPNAM = @GNULIB_MDA_TEMPNAM@ +GNULIB_MDA_TZSET = @GNULIB_MDA_TZSET@ +GNULIB_MDA_UMASK = @GNULIB_MDA_UMASK@ +GNULIB_MDA_UNLINK = @GNULIB_MDA_UNLINK@ +GNULIB_MDA_WRITE = @GNULIB_MDA_WRITE@ GNULIB_MEMCHR = @GNULIB_MEMCHR@ GNULIB_MEMMEM = @GNULIB_MEMMEM@ GNULIB_MEMPCPY = @GNULIB_MEMPCPY@ GNULIB_MEMRCHR = @GNULIB_MEMRCHR@ +GNULIB_MKDIR = @GNULIB_MKDIR@ GNULIB_MKDIRAT = @GNULIB_MKDIRAT@ GNULIB_MKDTEMP = @GNULIB_MKDTEMP@ GNULIB_MKFIFO = @GNULIB_MKFIFO@ @@ -567,6 +614,7 @@ HAVE_DIRENT_H = @HAVE_DIRENT_H@ HAVE_DPRINTF = @HAVE_DPRINTF@ HAVE_DUP3 = @HAVE_DUP3@ HAVE_EUIDACCESS = @HAVE_EUIDACCESS@ +HAVE_EXECVPE = @HAVE_EXECVPE@ HAVE_EXPLICIT_BZERO = @HAVE_EXPLICIT_BZERO@ HAVE_FACCESSAT = @HAVE_FACCESSAT@ HAVE_FCHDIR = @HAVE_FCHDIR@ @@ -886,6 +934,13 @@ REPLACE_DIRFD = @REPLACE_DIRFD@ REPLACE_DPRINTF = @REPLACE_DPRINTF@ REPLACE_DUP = @REPLACE_DUP@ REPLACE_DUP2 = @REPLACE_DUP2@ +REPLACE_EXECL = @REPLACE_EXECL@ +REPLACE_EXECLE = @REPLACE_EXECLE@ +REPLACE_EXECLP = @REPLACE_EXECLP@ +REPLACE_EXECV = @REPLACE_EXECV@ +REPLACE_EXECVE = @REPLACE_EXECVE@ +REPLACE_EXECVP = @REPLACE_EXECVP@ +REPLACE_EXECVPE = @REPLACE_EXECVPE@ REPLACE_FACCESSAT = @REPLACE_FACCESSAT@ REPLACE_FCHMODAT = @REPLACE_FCHMODAT@ REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@ @@ -1111,11 +1166,11 @@ gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b = @gl_GNULIB_ENABLED_260941c0 gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31 = @gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31@ gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c = @gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c@ gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec = @gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec@ +gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c = @gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c@ gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1 = @gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1@ gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36 = @gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36@ gl_GNULIB_ENABLED_cloexec = @gl_GNULIB_ENABLED_cloexec@ gl_GNULIB_ENABLED_dirfd = @gl_GNULIB_ENABLED_dirfd@ -gl_GNULIB_ENABLED_ef07dc4b3077c11ea9cef586db4e5955 = @gl_GNULIB_ENABLED_ef07dc4b3077c11ea9cef586db4e5955@ gl_GNULIB_ENABLED_euidaccess = @gl_GNULIB_ENABLED_euidaccess@ gl_GNULIB_ENABLED_getdtablesize = @gl_GNULIB_ENABLED_getdtablesize@ gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@ @@ -1680,6 +1735,8 @@ fcntl.h: fcntl.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's/@''GNULIB_NONBLOCKING''@/$(GNULIB_NONBLOCKING)/g' \ -e 's/@''GNULIB_OPEN''@/$(GNULIB_OPEN)/g' \ -e 's/@''GNULIB_OPENAT''@/$(GNULIB_OPENAT)/g' \ + -e 's/@''GNULIB_MDA_CREAT''@/$(GNULIB_MDA_CREAT)/g' \ + -e 's/@''GNULIB_MDA_OPEN''@/$(GNULIB_MDA_OPEN)/g' \ -e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \ -e 's|@''HAVE_OPENAT''@|$(HAVE_OPENAT)|g' \ -e 's|@''REPLACE_CREAT''@|$(REPLACE_CREAT)|g' \ @@ -2361,7 +2418,7 @@ endif ifeq (,$(OMIT_GNULIB_MODULE_scratch_buffer)) ifneq (,$(gl_GNULIB_ENABLED_scratch_buffer)) -libgnu_a_SOURCES += malloc/scratch_buffer_grow.c malloc/scratch_buffer_grow_preserve.c malloc/scratch_buffer_set_array_size.c +libgnu_a_SOURCES += malloc/scratch_buffer_dupfree.c malloc/scratch_buffer_grow.c malloc/scratch_buffer_grow_preserve.c malloc/scratch_buffer_set_array_size.c endif EXTRA_DIST += malloc/scratch_buffer.h scratch_buffer.h @@ -2679,6 +2736,12 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's/@''GNULIB_VPRINTF_POSIX''@/$(GNULIB_VPRINTF_POSIX)/g' \ -e 's/@''GNULIB_VSNPRINTF''@/$(GNULIB_VSNPRINTF)/g' \ -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GNULIB_VSPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_MDA_FCLOSEALL''@/$(GNULIB_MDA_FCLOSEALL)/g' \ + -e 's/@''GNULIB_MDA_FDOPEN''@/$(GNULIB_MDA_FDOPEN)/g' \ + -e 's/@''GNULIB_MDA_FILENO''@/$(GNULIB_MDA_FILENO)/g' \ + -e 's/@''GNULIB_MDA_GETW''@/$(GNULIB_MDA_GETW)/g' \ + -e 's/@''GNULIB_MDA_PUTW''@/$(GNULIB_MDA_PUTW)/g' \ + -e 's/@''GNULIB_MDA_TEMPNAM''@/$(GNULIB_MDA_TEMPNAM)/g' \ < $(srcdir)/stdio.in.h | \ sed -e 's|@''HAVE_DECL_FCLOSEALL''@|$(HAVE_DECL_FCLOSEALL)|g' \ -e 's|@''HAVE_DECL_FPURGE''@|$(HAVE_DECL_FPURGE)|g' \ @@ -2796,6 +2859,11 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -e 's/@''GNULIB_UNLOCKPT''@/$(GNULIB_UNLOCKPT)/g' \ -e 's/@''GNULIB_UNSETENV''@/$(GNULIB_UNSETENV)/g' \ -e 's/@''GNULIB_WCTOMB''@/$(GNULIB_WCTOMB)/g' \ + -e 's/@''GNULIB_MDA_ECVT''@/$(GNULIB_MDA_ECVT)/g' \ + -e 's/@''GNULIB_MDA_FCVT''@/$(GNULIB_MDA_FCVT)/g' \ + -e 's/@''GNULIB_MDA_GCVT''@/$(GNULIB_MDA_GCVT)/g' \ + -e 's/@''GNULIB_MDA_MKTEMP''@/$(GNULIB_MDA_MKTEMP)/g' \ + -e 's/@''GNULIB_MDA_PUTENV''@/$(GNULIB_MDA_PUTENV)/g' \ < $(srcdir)/stdlib.in.h | \ sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \ -e 's|@''HAVE_ALIGNED_ALLOC''@|$(HAVE_ALIGNED_ALLOC)|g' \ @@ -2941,6 +3009,8 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's/@''GNULIB_SIGDESCR_NP''@/$(GNULIB_SIGDESCR_NP)/g' \ -e 's/@''GNULIB_STRSIGNAL''@/$(GNULIB_STRSIGNAL)/g' \ -e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \ + -e 's/@''GNULIB_MDA_MEMCCPY''@/$(GNULIB_MDA_MEMCCPY)/g' \ + -e 's/@''GNULIB_MDA_STRDUP''@/$(GNULIB_MDA_STRDUP)/g' \ < $(srcdir)/string.in.h | \ sed -e 's|@''HAVE_EXPLICIT_BZERO''@|$(HAVE_EXPLICIT_BZERO)|g' \ -e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \ @@ -3136,6 +3206,7 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU -e 's/@''GNULIB_GETUMASK''@/$(GNULIB_GETUMASK)/g' \ -e 's/@''GNULIB_LCHMOD''@/$(GNULIB_LCHMOD)/g' \ -e 's/@''GNULIB_LSTAT''@/$(GNULIB_LSTAT)/g' \ + -e 's/@''GNULIB_MKDIR''@/$(GNULIB_MKDIR)/g' \ -e 's/@''GNULIB_MKDIRAT''@/$(GNULIB_MKDIRAT)/g' \ -e 's/@''GNULIB_MKFIFO''@/$(GNULIB_MKFIFO)/g' \ -e 's/@''GNULIB_MKFIFOAT''@/$(GNULIB_MKFIFOAT)/g' \ @@ -3144,6 +3215,9 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU -e 's/@''GNULIB_STAT''@/$(GNULIB_STAT)/g' \ -e 's/@''GNULIB_UTIMENSAT''@/$(GNULIB_UTIMENSAT)/g' \ -e 's/@''GNULIB_OVERRIDES_STRUCT_STAT''@/$(GNULIB_OVERRIDES_STRUCT_STAT)/g' \ + -e 's/@''GNULIB_MDA_CHMOD''@/$(GNULIB_MDA_CHMOD)/g' \ + -e 's/@''GNULIB_MDA_MKDIR''@/$(GNULIB_MDA_MKDIR)/g' \ + -e 's/@''GNULIB_MDA_UMASK''@/$(GNULIB_MDA_UMASK)/g' \ -e 's|@''HAVE_FCHMODAT''@|$(HAVE_FCHMODAT)|g' \ -e 's|@''HAVE_FSTATAT''@|$(HAVE_FSTATAT)|g' \ -e 's|@''HAVE_FUTIMENS''@|$(HAVE_FUTIMENS)|g' \ @@ -3279,6 +3353,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \ -e 's/@''GNULIB_TIME_RZ''@/$(GNULIB_TIME_RZ)/g' \ -e 's/@''GNULIB_TZSET''@/$(GNULIB_TZSET)/g' \ + -e 's/@''GNULIB_MDA_TZSET''@/$(GNULIB_MDA_TZSET)/g' \ -e 's|@''HAVE_DECL_LOCALTIME_R''@|$(HAVE_DECL_LOCALTIME_R)|g' \ -e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \ -e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \ @@ -3407,6 +3482,13 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's/@''GNULIB_DUP3''@/$(GNULIB_DUP3)/g' \ -e 's/@''GNULIB_ENVIRON''@/$(GNULIB_ENVIRON)/g' \ -e 's/@''GNULIB_EUIDACCESS''@/$(GNULIB_EUIDACCESS)/g' \ + -e 's/@''GNULIB_EXECL''@/$(GNULIB_EXECL)/g' \ + -e 's/@''GNULIB_EXECLE''@/$(GNULIB_EXECLE)/g' \ + -e 's/@''GNULIB_EXECLP''@/$(GNULIB_EXECLP)/g' \ + -e 's/@''GNULIB_EXECV''@/$(GNULIB_EXECV)/g' \ + -e 's/@''GNULIB_EXECVE''@/$(GNULIB_EXECVE)/g' \ + -e 's/@''GNULIB_EXECVP''@/$(GNULIB_EXECVP)/g' \ + -e 's/@''GNULIB_EXECVPE''@/$(GNULIB_EXECVPE)/g' \ -e 's/@''GNULIB_FACCESSAT''@/$(GNULIB_FACCESSAT)/g' \ -e 's/@''GNULIB_FCHDIR''@/$(GNULIB_FCHDIR)/g' \ -e 's/@''GNULIB_FCHOWNAT''@/$(GNULIB_FCHOWNAT)/g' \ @@ -3452,11 +3534,33 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's/@''GNULIB_UNLINKAT''@/$(GNULIB_UNLINKAT)/g' \ -e 's/@''GNULIB_USLEEP''@/$(GNULIB_USLEEP)/g' \ -e 's/@''GNULIB_WRITE''@/$(GNULIB_WRITE)/g' \ + -e 's/@''GNULIB_MDA_ACCESS''@/$(GNULIB_MDA_ACCESS)/g' \ + -e 's/@''GNULIB_MDA_CHDIR''@/$(GNULIB_MDA_CHDIR)/g' \ + -e 's/@''GNULIB_MDA_CLOSE''@/$(GNULIB_MDA_CLOSE)/g' \ + -e 's/@''GNULIB_MDA_DUP''@/$(GNULIB_MDA_DUP)/g' \ + -e 's/@''GNULIB_MDA_DUP2''@/$(GNULIB_MDA_DUP2)/g' \ + -e 's/@''GNULIB_MDA_EXECL''@/$(GNULIB_MDA_EXECL)/g' \ + -e 's/@''GNULIB_MDA_EXECLE''@/$(GNULIB_MDA_EXECLE)/g' \ + -e 's/@''GNULIB_MDA_EXECLP''@/$(GNULIB_MDA_EXECLP)/g' \ + -e 's/@''GNULIB_MDA_EXECV''@/$(GNULIB_MDA_EXECV)/g' \ + -e 's/@''GNULIB_MDA_EXECVE''@/$(GNULIB_MDA_EXECVE)/g' \ + -e 's/@''GNULIB_MDA_EXECVP''@/$(GNULIB_MDA_EXECVP)/g' \ + -e 's/@''GNULIB_MDA_EXECVPE''@/$(GNULIB_MDA_EXECVPE)/g' \ + -e 's/@''GNULIB_MDA_GETCWD''@/$(GNULIB_MDA_GETCWD)/g' \ + -e 's/@''GNULIB_MDA_GETPID''@/$(GNULIB_MDA_GETPID)/g' \ + -e 's/@''GNULIB_MDA_ISATTY''@/$(GNULIB_MDA_ISATTY)/g' \ + -e 's/@''GNULIB_MDA_LSEEK''@/$(GNULIB_MDA_LSEEK)/g' \ + -e 's/@''GNULIB_MDA_READ''@/$(GNULIB_MDA_READ)/g' \ + -e 's/@''GNULIB_MDA_RMDIR''@/$(GNULIB_MDA_RMDIR)/g' \ + -e 's/@''GNULIB_MDA_SWAB''@/$(GNULIB_MDA_SWAB)/g' \ + -e 's/@''GNULIB_MDA_UNLINK''@/$(GNULIB_MDA_UNLINK)/g' \ + -e 's/@''GNULIB_MDA_WRITE''@/$(GNULIB_MDA_WRITE)/g' \ < $(srcdir)/unistd.in.h | \ sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \ -e 's|@''HAVE_COPY_FILE_RANGE''@|$(HAVE_COPY_FILE_RANGE)|g' \ -e 's|@''HAVE_DUP3''@|$(HAVE_DUP3)|g' \ -e 's|@''HAVE_EUIDACCESS''@|$(HAVE_EUIDACCESS)|g' \ + -e 's|@''HAVE_EXECVPE''@|$(HAVE_EXECVPE)|g' \ -e 's|@''HAVE_FACCESSAT''@|$(HAVE_FACCESSAT)|g' \ -e 's|@''HAVE_FCHDIR''@|$(HAVE_FCHDIR)|g' \ -e 's|@''HAVE_FCHOWNAT''@|$(HAVE_FCHOWNAT)|g' \ @@ -3505,6 +3609,13 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \ -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \ -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \ + -e 's|@''REPLACE_EXECL''@|$(REPLACE_EXECL)|g' \ + -e 's|@''REPLACE_EXECLE''@|$(REPLACE_EXECLE)|g' \ + -e 's|@''REPLACE_EXECLP''@|$(REPLACE_EXECLP)|g' \ + -e 's|@''REPLACE_EXECV''@|$(REPLACE_EXECV)|g' \ + -e 's|@''REPLACE_EXECVE''@|$(REPLACE_EXECVE)|g' \ + -e 's|@''REPLACE_EXECVP''@|$(REPLACE_EXECVP)|g' \ + -e 's|@''REPLACE_EXECVPE''@|$(REPLACE_EXECVPE)|g' \ -e 's|@''REPLACE_FACCESSAT''@|$(REPLACE_FACCESSAT)|g' \ -e 's|@''REPLACE_FCHOWNAT''@|$(REPLACE_FCHOWNAT)|g' \ -e 's|@''REPLACE_FTRUNCATE''@|$(REPLACE_FTRUNCATE)|g' \ diff --git a/lib/group-member.c b/lib/group-member.c index d7ded6a1b0..52159016ea 100644 --- a/lib/group-member.c +++ b/lib/group-member.c @@ -1,7 +1,7 @@ /* group-member.c -- determine whether group id is in calling user's group list - Copyright (C) 1994, 1997-1998, 2003, 2005-2006, 2009-2021 Free - Software Foundation, Inc. + Copyright (C) 1994, 1997-1998, 2003, 2005-2006, 2009-2021 Free Software + Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/idx.h b/lib/idx.h index 22ac320b50..681c8c90f1 100644 --- a/lib/idx.h +++ b/lib/idx.h @@ -1,19 +1,20 @@ /* A type for indices and sizes. - Copyright (C) 2020-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ + You should have received a copy of the GNU General Public + License along with the GNU C Library; if not, see + . */ #ifndef _IDX_H #define _IDX_H diff --git a/lib/malloc/scratch_buffer.h b/lib/malloc/scratch_buffer.h index 6efca9ba3f..26e306212d 100644 --- a/lib/malloc/scratch_buffer.h +++ b/lib/malloc/scratch_buffer.h @@ -132,4 +132,20 @@ scratch_buffer_set_array_size (struct scratch_buffer *buffer, (buffer, nelem, size)); } +/* Return a copy of *BUFFER's first SIZE bytes as a heap-allocated block, + deallocating *BUFFER if it was heap-allocated. SIZE must be at + most *BUFFER's size. Return NULL (setting errno) on memory + exhaustion. */ +void *__libc_scratch_buffer_dupfree (struct scratch_buffer *buffer, + size_t size); +libc_hidden_proto (__libc_scratch_buffer_dupfree) + +/* Alias for __libc_scratch_dupfree. */ +static __always_inline void * +scratch_buffer_dupfree (struct scratch_buffer *buffer, size_t size) +{ + void *r = __libc_scratch_buffer_dupfree (buffer, size); + return __glibc_likely (r != NULL) ? r : NULL; +} + #endif /* _SCRATCH_BUFFER_H */ diff --git a/lib/malloc/scratch_buffer_grow.c b/lib/malloc/scratch_buffer_grow.c index e7606d81cd..41befe3d65 100644 --- a/lib/malloc/scratch_buffer_grow.c +++ b/lib/malloc/scratch_buffer_grow.c @@ -1,5 +1,5 @@ /* Variable-sized buffer with on-stack default allocation. - Copyright (C) 2015-2021 Free Software Foundation, Inc. + Copyright (C) 2015-2020 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/lib/malloc/scratch_buffer_grow_preserve.c b/lib/malloc/scratch_buffer_grow_preserve.c index 59f8c71000..aef232938d 100644 --- a/lib/malloc/scratch_buffer_grow_preserve.c +++ b/lib/malloc/scratch_buffer_grow_preserve.c @@ -1,5 +1,5 @@ /* Variable-sized buffer with on-stack default allocation. - Copyright (C) 2015-2021 Free Software Foundation, Inc. + Copyright (C) 2015-2020 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/lib/malloc/scratch_buffer_set_array_size.c b/lib/malloc/scratch_buffer_set_array_size.c index e2b9f31211..5f5e4c24f5 100644 --- a/lib/malloc/scratch_buffer_set_array_size.c +++ b/lib/malloc/scratch_buffer_set_array_size.c @@ -1,5 +1,5 @@ /* Variable-sized buffer with on-stack default allocation. - Copyright (C) 2015-2021 Free Software Foundation, Inc. + Copyright (C) 2015-2020 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/lib/md5.c b/lib/md5.c index d103c13314..e7eeeaab03 100644 --- a/lib/md5.c +++ b/lib/md5.c @@ -1,7 +1,7 @@ /* Functions to compute MD5 message digest of files or memory blocks. according to the definition of MD5 in RFC 1321 from April 1992. - Copyright (C) 1995-1997, 1999-2001, 2005-2006, 2008-2021 Free - Software Foundation, Inc. + Copyright (C) 1995-1997, 1999-2001, 2005-2006, 2008-2021 Free Software + Foundation, Inc. This file is part of the GNU C Library. This program is free software; you can redistribute it and/or modify it diff --git a/lib/md5.h b/lib/md5.h index 9015b9a867..aa4b0805d5 100644 --- a/lib/md5.h +++ b/lib/md5.h @@ -1,7 +1,7 @@ /* Declaration of functions and data types used for MD5 sum computing library functions. - Copyright (C) 1995-1997, 1999-2001, 2004-2006, 2008-2021 Free - Software Foundation, Inc. + Copyright (C) 1995-1997, 1999-2001, 2004-2006, 2008-2021 Free Software + Foundation, Inc. This file is part of the GNU C Library. This program is free software; you can redistribute it and/or modify it diff --git a/lib/memmem.c b/lib/memmem.c index 5c35976ebc..87266fa87a 100644 --- a/lib/memmem.c +++ b/lib/memmem.c @@ -1,5 +1,5 @@ -/* Copyright (C) 1991-1994, 1996-1998, 2000, 2004, 2007-2021 Free - Software Foundation, Inc. +/* Copyright (C) 1991-1994, 1996-1998, 2000, 2004, 2007-2021 Free Software + Foundation, Inc. This file is part of the GNU C Library. This program is free software; you can redistribute it and/or modify diff --git a/lib/memrchr.c b/lib/memrchr.c index 6608004fec..dcd24fafc6 100644 --- a/lib/memrchr.c +++ b/lib/memrchr.c @@ -1,7 +1,7 @@ /* memrchr -- find the last occurrence of a byte in a memory block - Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2021 Free - Software Foundation, Inc. + Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2021 Free Software + Foundation, Inc. Based on strlen implementation by Torbjorn Granlund (tege@sics.se), with help from Dan Sahlin (dan@sics.se) and diff --git a/lib/mktime-internal.h b/lib/mktime-internal.h index 9c447bd7b0..b765a37ee3 100644 --- a/lib/mktime-internal.h +++ b/lib/mktime-internal.h @@ -1,5 +1,5 @@ /* Internals of mktime and related functions - Copyright 2016-2021 Free Software Foundation, Inc. + Copyright 2016-2020 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Paul Eggert . diff --git a/lib/regex.c b/lib/regex.c index f76a416b3b..88173bb105 100644 --- a/lib/regex.c +++ b/lib/regex.c @@ -1,5 +1,5 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002-2021 Free Software Foundation, Inc. + Copyright (C) 2002-2020 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . diff --git a/lib/regexec.c b/lib/regexec.c index a75365f907..395e37db59 100644 --- a/lib/regexec.c +++ b/lib/regexec.c @@ -1,5 +1,5 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002-2021 Free Software Foundation, Inc. + Copyright (C) 2002-2020 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . diff --git a/lib/sha1.c b/lib/sha1.c index d7c2939da1..612d46de82 100644 --- a/lib/sha1.c +++ b/lib/sha1.c @@ -1,8 +1,7 @@ /* sha1.c - Functions to compute SHA1 message digest of files or memory blocks according to the NIST specification FIPS-180-1. - Copyright (C) 2000-2001, 2003-2006, 2008-2021 Free Software - Foundation, Inc. + Copyright (C) 2000-2001, 2003-2006, 2008-2021 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the diff --git a/lib/sig2str.c b/lib/sig2str.c index bfce99c30c..c2cc35d830 100644 --- a/lib/sig2str.c +++ b/lib/sig2str.c @@ -1,7 +1,6 @@ /* sig2str.c -- convert between signal names and numbers - Copyright (C) 2002, 2004, 2006, 2009-2021 Free Software Foundation, - Inc. + Copyright (C) 2002, 2004, 2006, 2009-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/stdio.in.h b/lib/stdio.in.h index c7d7bbb4e4..a930840505 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -229,27 +229,29 @@ _GL_WARN_ON_USE (fclose, "fclose is not always POSIX compliant - " "use gnulib module fclose for portable POSIX compliance"); #endif +#if @GNULIB_MDA_FCLOSEALL@ /* On native Windows, map 'fcloseall' to '_fcloseall', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::fcloseall on all platforms that have it. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef fcloseall -# define fcloseall _fcloseall -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fcloseall +# define fcloseall _fcloseall +# endif _GL_CXXALIAS_MDA (fcloseall, int, (void)); -#else -# if @HAVE_DECL_FCLOSEALL@ -# if defined __FreeBSD__ +# else +# if @HAVE_DECL_FCLOSEALL@ +# if defined __FreeBSD__ _GL_CXXALIAS_SYS (fcloseall, void, (void)); -# else +# else _GL_CXXALIAS_SYS (fcloseall, int, (void)); +# endif # endif # endif -#endif -#if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_FCLOSEALL@ +# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_FCLOSEALL@ _GL_CXXALIASWARN (fcloseall); +# endif #endif #if @GNULIB_FDOPEN@ @@ -276,7 +278,7 @@ _GL_CXXALIASWARN (fdopen); /* Assume fdopen is always declared. */ _GL_WARN_ON_USE (fdopen, "fdopen on native Windows platforms is not POSIX compliant - " "use gnulib module fdopen for portability"); -#else +#elif @GNULIB_MDA_FDOPEN@ /* On native Windows, map 'fdopen' to '_fdopen', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::fdopen always. */ @@ -354,19 +356,21 @@ _GL_CXXALIASWARN (fgets); # endif #endif +#if @GNULIB_MDA_FILENO@ /* On native Windows, map 'fileno' to '_fileno', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::fileno always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef fileno -# define fileno _fileno -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fileno +# define fileno _fileno +# endif _GL_CXXALIAS_MDA (fileno, int, (FILE *restrict stream)); -#else +# else _GL_CXXALIAS_SYS (fileno, int, (FILE *restrict stream)); -#endif +# endif _GL_CXXALIASWARN (fileno); +#endif #if @GNULIB_FOPEN@ # if @REPLACE_FOPEN@ @@ -895,19 +899,21 @@ _GL_WARN_ON_USE (getline, "getline is unportable - " _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); #endif +#if @GNULIB_MDA_GETW@ /* On native Windows, map 'getw' to '_getw', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::getw always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef getw -# define getw _getw -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getw +# define getw _getw +# endif _GL_CXXALIAS_MDA (getw, int, (FILE *restrict stream)); -#else +# else _GL_CXXALIAS_SYS (getw, int, (FILE *restrict stream)); -#endif +# endif _GL_CXXALIASWARN (getw); +#endif #if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@ struct obstack; @@ -1122,19 +1128,21 @@ _GL_CXXALIASWARN (puts); # endif #endif +#if @GNULIB_MDA_PUTW@ /* On native Windows, map 'putw' to '_putw', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::putw always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef putw -# define putw _putw -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef putw +# define putw _putw +# endif _GL_CXXALIAS_MDA (putw, int, (int w, FILE *restrict stream)); -#else +# else _GL_CXXALIAS_SYS (putw, int, (int w, FILE *restrict stream)); -#endif +# endif _GL_CXXALIASWARN (putw); +#endif #if @GNULIB_REMOVE@ # if @REPLACE_REMOVE@ @@ -1315,19 +1323,21 @@ _GL_WARN_ON_USE (sprintf, "sprintf is not always POSIX compliant - " "POSIX compliance"); #endif +#if @GNULIB_MDA_TEMPNAM@ /* On native Windows, map 'tempnam' to '_tempnam', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::tempnam always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef tempnam -# define tempnam _tempnam -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef tempnam +# define tempnam _tempnam +# endif _GL_CXXALIAS_MDA (tempnam, char *, (const char *dir, const char *prefix)); -#else +# else _GL_CXXALIAS_SYS (tempnam, char *, (const char *dir, const char *prefix)); -#endif +# endif _GL_CXXALIASWARN (tempnam); +#endif #if @GNULIB_TMPFILE@ # if @REPLACE_TMPFILE@ diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index 9217ebd4ab..49fc44e14a 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -1,7 +1,6 @@ /* A GNU-like . - Copyright (C) 1995, 2001-2004, 2006-2021 Free Software Foundation, - Inc. + Copyright (C) 1995, 2001-2004, 2006-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -243,46 +242,50 @@ _GL_WARN_ON_USE (canonicalize_file_name, # endif #endif +#if @GNULIB_MDA_ECVT@ /* On native Windows, map 'ecvt' to '_ecvt', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::ecvt on all platforms that have it. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef ecvt -# define ecvt _ecvt -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ecvt +# define ecvt _ecvt +# endif _GL_CXXALIAS_MDA (ecvt, char *, (double number, int ndigits, int *decptp, int *signp)); -#else -# if @HAVE_DECL_ECVT@ +# else +# if @HAVE_DECL_ECVT@ _GL_CXXALIAS_SYS (ecvt, char *, (double number, int ndigits, int *decptp, int *signp)); +# endif # endif -#endif -#if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_ECVT@ +# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_ECVT@ _GL_CXXALIASWARN (ecvt); +# endif #endif +#if @GNULIB_MDA_FCVT@ /* On native Windows, map 'fcvt' to '_fcvt', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::fcvt on all platforms that have it. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef fcvt -# define fcvt _fcvt -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fcvt +# define fcvt _fcvt +# endif _GL_CXXALIAS_MDA (fcvt, char *, (double number, int ndigits, int *decptp, int *signp)); -#else -# if @HAVE_DECL_FCVT@ +# else +# if @HAVE_DECL_FCVT@ _GL_CXXALIAS_SYS (fcvt, char *, (double number, int ndigits, int *decptp, int *signp)); +# endif # endif -#endif -#if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_FCVT@ +# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_FCVT@ _GL_CXXALIASWARN (fcvt); +# endif #endif #if @GNULIB_FREE_POSIX@ @@ -306,23 +309,25 @@ _GL_WARN_ON_USE (free, "free is not future POSIX compliant everywhere - " "use gnulib module free for portability"); #endif +#if @GNULIB_MDA_GCVT@ /* On native Windows, map 'gcvt' to '_gcvt', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::gcvt on all platforms that have it. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef gcvt -# define gcvt _gcvt -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef gcvt +# define gcvt _gcvt +# endif _GL_CXXALIAS_MDA (gcvt, char *, (double number, int ndigits, char *buf)); -#else -# if @HAVE_DECL_GCVT@ +# else +# if @HAVE_DECL_GCVT@ _GL_CXXALIAS_SYS (gcvt, char *, (double number, int ndigits, char *buf)); +# endif # endif -#endif -#if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_GCVT@ +# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_GCVT@ _GL_CXXALIASWARN (gcvt); +# endif #endif #if @GNULIB_GETLOADAVG@ @@ -576,19 +581,21 @@ _GL_WARN_ON_USE (mkstemps, "mkstemps is unportable - " # endif #endif +#if @GNULIB_MDA_MKTEMP@ /* On native Windows, map 'mktemp' to '_mktemp', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::mktemp always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef mktemp -# define mktemp _mktemp -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mktemp +# define mktemp _mktemp +# endif _GL_CXXALIAS_MDA (mktemp, char *, (char * /*template*/)); -#else +# else _GL_CXXALIAS_SYS (mktemp, char *, (char * /*template*/)); -#endif +# endif _GL_CXXALIASWARN (mktemp); +#endif /* Allocate memory with indefinite extent and specified alignment. */ #if @GNULIB_POSIX_MEMALIGN@ @@ -707,7 +714,7 @@ _GL_CXXALIAS_MDA (putenv, int, (char *string)); _GL_CXXALIAS_SYS (putenv, int, (char *string)); # endif _GL_CXXALIASWARN (putenv); -#else +#elif @GNULIB_MDA_PUTENV@ /* On native Windows, map 'putenv' to '_putenv', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::putenv always. */ diff --git a/lib/string.in.h b/lib/string.in.h index 4625c611bf..9f68e77c76 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -123,21 +123,23 @@ _GL_WARN_ON_USE (ffsll, "ffsll is not portable - use the ffsll module"); #endif +#if @GNULIB_MDA_MEMCCPY@ /* On native Windows, map 'memccpy' to '_memccpy', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::memccpy always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef memccpy -# define memccpy _memccpy -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef memccpy +# define memccpy _memccpy +# endif _GL_CXXALIAS_MDA (memccpy, void *, (void *dest, const void *src, int c, size_t n)); -#else +# else _GL_CXXALIAS_SYS (memccpy, void *, (void *dest, const void *src, int c, size_t n)); -#endif +# endif _GL_CXXALIASWARN (memccpy); +#endif /* Return the first instance of C within N bytes of S, or NULL. */ @@ -425,7 +427,7 @@ _GL_CXXALIASWARN (strdup); _GL_WARN_ON_USE (strdup, "strdup is unportable - " "use gnulib module strdup for portability"); # endif -#else +#elif @GNULIB_MDA_STRDUP@ /* On native Windows, map 'creat' to '_creat', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::creat always. */ diff --git a/lib/strtoimax.c b/lib/strtoimax.c index db2c553738..37a25c31d4 100644 --- a/lib/strtoimax.c +++ b/lib/strtoimax.c @@ -1,7 +1,7 @@ /* Convert string representation of a number into an intmax_t value. - Copyright (C) 1999, 2001-2004, 2006, 2009-2021 Free Software - Foundation, Inc. + Copyright (C) 1999, 2001-2004, 2006, 2009-2021 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/strtol.c b/lib/strtol.c index d0cf7949f6..2f2159b623 100644 --- a/lib/strtol.c +++ b/lib/strtol.c @@ -1,7 +1,7 @@ /* Convert string representation of a number into an integer value. - Copyright (C) 1991-1992, 1994-1999, 2003, 2005-2007, 2009-2021 Free - Software Foundation, Inc. + Copyright (C) 1991-1992, 1994-1999, 2003, 2005-2007, 2009-2021 Free Software + Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@gnu.org. diff --git a/lib/strtoll.c b/lib/strtoll.c index bb71c53a1d..30daefc50f 100644 --- a/lib/strtoll.c +++ b/lib/strtoll.c @@ -1,6 +1,6 @@ /* Function to parse a 'long long int' from text. - Copyright (C) 1995-1997, 1999, 2001, 2009-2021 Free Software - Foundation, Inc. + Copyright (C) 1995-1997, 1999, 2001, 2009-2021 Free Software Foundation, + Inc. This file is part of the GNU C Library. This program is free software: you can redistribute it and/or modify diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h index 4e7b212a61..ccdb5cbd14 100644 --- a/lib/sys_stat.in.h +++ b/lib/sys_stat.in.h @@ -391,20 +391,22 @@ struct stat #endif +#if @GNULIB_MDA_CHMOD@ /* On native Windows, map 'chmod' to '_chmod', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::chmod always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef chmod -# define chmod _chmod -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef chmod +# define chmod _chmod +# endif /* Need to cast, because in mingw the last argument is 'int mode'. */ _GL_CXXALIAS_MDA_CAST (chmod, int, (const char *filename, mode_t mode)); -#else +# else _GL_CXXALIAS_SYS (chmod, int, (const char *filename, mode_t mode)); -#endif +# endif _GL_CXXALIASWARN (chmod); +#endif #if @GNULIB_FCHMODAT@ @@ -606,21 +608,20 @@ _GL_WARN_ON_USE (lstat, "lstat is unportable - " #endif -#if @REPLACE_MKDIR@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef mkdir -# define mkdir rpl_mkdir -# endif +#if @GNULIB_MKDIR@ +# if @REPLACE_MKDIR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mkdir +# define mkdir rpl_mkdir +# endif _GL_FUNCDECL_RPL (mkdir, int, (char const *name, mode_t mode) - _GL_ARG_NONNULL ((1))); + _GL_ARG_NONNULL ((1))); _GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode)); -#else +# elif defined _WIN32 && !defined __CYGWIN__ /* mingw's _mkdir() function has 1 argument, but we pass 2 arguments. Additionally, it declares _mkdir (and depending on compile flags, an alias mkdir), only in the nonstandard includes and , which are included above. */ -# if defined _WIN32 && ! defined __CYGWIN__ - # if !GNULIB_defined_rpl_mkdir static int rpl_mkdir (char const *name, mode_t mode) @@ -629,16 +630,44 @@ rpl_mkdir (char const *name, mode_t mode) } # define GNULIB_defined_rpl_mkdir 1 # endif - # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mkdir +# define mkdir rpl_mkdir +# endif +_GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode)); +# else +_GL_CXXALIAS_SYS (mkdir, int, (char const *name, mode_t mode)); +# endif +_GL_CXXALIASWARN (mkdir); +#elif defined GNULIB_POSIXCHECK +# undef mkdir +# if HAVE_RAW_DECL_MKDIR +_GL_WARN_ON_USE (mkdir, "mkdir does not always support two parameters - " + "use gnulib module mkdir for portability"); +# endif +#elif @GNULIB_MDA_MKDIR@ +/* On native Windows, map 'mkdir' to '_mkdir', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::mkdir always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !GNULIB_defined_rpl_mkdir +static int +rpl_mkdir (char const *name, mode_t mode) +{ + return _mkdir (name); +} +# define GNULIB_defined_rpl_mkdir 1 +# endif +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mkdir # define mkdir rpl_mkdir # endif _GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode)); # else _GL_CXXALIAS_SYS (mkdir, int, (char const *name, mode_t mode)); # endif -#endif _GL_CXXALIASWARN (mkdir); +#endif #if @GNULIB_MKDIRAT@ @@ -818,20 +847,22 @@ _GL_WARN_ON_USE (stat, "stat is unportable - " #endif +#if @GNULIB_MDA_UMASK@ /* On native Windows, map 'umask' to '_umask', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::umask always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef umask -# define umask _umask -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef umask +# define umask _umask +# endif /* Need to cast, because in mingw the last argument is 'int mode'. */ _GL_CXXALIAS_MDA_CAST (umask, mode_t, (mode_t mask)); -#else +# else _GL_CXXALIAS_SYS (umask, mode_t, (mode_t mask)); -#endif +# endif _GL_CXXALIASWARN (umask); +#endif #if @GNULIB_UTIMENSAT@ diff --git a/lib/time.in.h b/lib/time.in.h index ed44997e38..958dc0bd29 100644 --- a/lib/time.in.h +++ b/lib/time.in.h @@ -145,7 +145,7 @@ _GL_CXXALIAS_MDA (tzset, void, (void)); _GL_CXXALIAS_SYS (tzset, void, (void)); # endif _GL_CXXALIASWARN (tzset); -# else +# elif @GNULIB_MDA_TZSET@ /* On native Windows, map 'tzset' to '_tzset', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::tzset always. */ diff --git a/lib/time_r.c b/lib/time_r.c index 446a30f9f0..d908986870 100644 --- a/lib/time_r.c +++ b/lib/time_r.c @@ -1,7 +1,6 @@ /* Reentrant time functions like localtime_r. - Copyright (C) 2003, 2006-2007, 2010-2021 Free Software Foundation, - Inc. + Copyright (C) 2003, 2006-2007, 2010-2021 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/timegm.c b/lib/timegm.c index e4127e71c0..fa30943084 100644 --- a/lib/timegm.c +++ b/lib/timegm.c @@ -1,6 +1,6 @@ /* Convert UTC calendar time to simple time. Like mktime but assumes UTC. - Copyright (C) 1994-2021 Free Software Foundation, Inc. + Copyright (C) 1994-2020 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/lib/unistd.in.h b/lib/unistd.in.h index b5e7aaef7d..5e9b47d981 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -287,7 +287,7 @@ _GL_WARN_ON_USE (access, "access does not always support X_OK - " "also, this function is a security risk - " "use the gnulib module faccessat instead"); # endif -#else +#elif @GNULIB_MDA_ACCESS@ /* On native Windows, map 'access' to '_access', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::access always. */ @@ -321,7 +321,7 @@ _GL_CXXALIASWARN (chdir); _GL_WARN_ON_USE (chown, "chdir is not always in - " "use gnulib module chdir for portability"); # endif -#else +#elif @GNULIB_MDA_CHDIR@ /* On native Windows, map 'chdir' to '_chdir', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::chdir always. */ @@ -397,7 +397,7 @@ _GL_CXXALIASWARN (close); /* Assume close is always declared. */ _GL_WARN_ON_USE (close, "close does not portably work on sockets - " "use gnulib module close for portability"); -#else +#elif @GNULIB_MDA_CLOSE@ /* On native Windows, map 'close' to '_close', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::close always. */ @@ -456,7 +456,7 @@ _GL_CXXALIASWARN (dup); _GL_WARN_ON_USE (dup, "dup is unportable - " "use gnulib module dup for portability"); # endif -#else +#elif @GNULIB_MDA_DUP@ /* On native Windows, map 'dup' to '_dup', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::dup always. */ @@ -501,7 +501,7 @@ _GL_CXXALIASWARN (dup2); _GL_WARN_ON_USE (dup2, "dup2 is unportable - " "use gnulib module dup2 for portability"); # endif -#else +#elif @GNULIB_MDA_DUP2@ /* On native Windows, map 'dup2' to '_dup2', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::dup2 always. */ @@ -615,116 +615,279 @@ _GL_WARN_ON_USE (euidaccess, "euidaccess is unportable - " #endif +#if @GNULIB_EXECL@ +# if @REPLACE_EXECL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execl +# define execl rpl_execl +# endif +_GL_FUNCDECL_RPL (execl, int, (const char *program, const char *arg, ...) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (execl, int, (const char *program, const char *arg, ...)); +# else +_GL_CXXALIAS_SYS (execl, int, (const char *program, const char *arg, ...)); +# endif +_GL_CXXALIASWARN (execl); +#elif defined GNULIB_POSIXCHECK +# undef execl +# if HAVE_RAW_DECL_EXECL +_GL_WARN_ON_USE (execl, "execl behaves very differently on mingw - " + "use gnulib module execl for portability"); +# endif +#elif @GNULIB_MDA_EXECL@ /* On native Windows, map 'execl' to '_execl', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::execl always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef execl -# define execl _execl -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execl +# define execl _execl +# endif _GL_CXXALIAS_MDA (execl, intptr_t, (const char *program, const char *arg, ...)); -#else +# else _GL_CXXALIAS_SYS (execl, int, (const char *program, const char *arg, ...)); -#endif +# endif _GL_CXXALIASWARN (execl); +#endif +#if @GNULIB_EXECLE@ +# if @REPLACE_EXECLE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execle +# define execle rpl_execle +# endif +_GL_FUNCDECL_RPL (execle, int, (const char *program, const char *arg, ...) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (execle, int, (const char *program, const char *arg, ...)); +# else +_GL_CXXALIAS_SYS (execle, int, (const char *program, const char *arg, ...)); +# endif +_GL_CXXALIASWARN (execle); +#elif defined GNULIB_POSIXCHECK +# undef execle +# if HAVE_RAW_DECL_EXECLE +_GL_WARN_ON_USE (execle, "execle behaves very differently on mingw - " + "use gnulib module execle for portability"); +# endif +#elif @GNULIB_MDA_EXECLE@ /* On native Windows, map 'execle' to '_execle', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::execle always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef execle -# define execle _execle -# endif -_GL_CXXALIAS_MDA (execle, intptr_t, (const char *program, const char *arg, ...)); -#else +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execle +# define execle _execle +# endif +_GL_CXXALIAS_MDA (execle, intptr_t, + (const char *program, const char *arg, ...)); +# else _GL_CXXALIAS_SYS (execle, int, (const char *program, const char *arg, ...)); -#endif +# endif _GL_CXXALIASWARN (execle); +#endif +#if @GNULIB_EXECLP@ +# if @REPLACE_EXECLP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execlp +# define execlp rpl_execlp +# endif +_GL_FUNCDECL_RPL (execlp, int, (const char *program, const char *arg, ...) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (execlp, int, (const char *program, const char *arg, ...)); +# else +_GL_CXXALIAS_SYS (execlp, int, (const char *program, const char *arg, ...)); +# endif +_GL_CXXALIASWARN (execlp); +#elif defined GNULIB_POSIXCHECK +# undef execlp +# if HAVE_RAW_DECL_EXECLP +_GL_WARN_ON_USE (execlp, "execlp behaves very differently on mingw - " + "use gnulib module execlp for portability"); +# endif +#elif @GNULIB_MDA_EXECLP@ /* On native Windows, map 'execlp' to '_execlp', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::execlp always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef execlp -# define execlp _execlp -# endif -_GL_CXXALIAS_MDA (execlp, intptr_t, (const char *program, const char *arg, ...)); -#else +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execlp +# define execlp _execlp +# endif +_GL_CXXALIAS_MDA (execlp, intptr_t, + (const char *program, const char *arg, ...)); +# else _GL_CXXALIAS_SYS (execlp, int, (const char *program, const char *arg, ...)); -#endif +# endif _GL_CXXALIASWARN (execlp); +#endif +#if @GNULIB_EXECV@ +# if @REPLACE_EXECV@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execv +# define execv rpl_execv +# endif +_GL_FUNCDECL_RPL (execv, int, (const char *program, char * const *argv) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (execv, int, (const char *program, char * const *argv)); +# else +_GL_CXXALIAS_SYS (execv, int, (const char *program, char * const *argv)); +# endif +_GL_CXXALIASWARN (execv); +#elif defined GNULIB_POSIXCHECK +# undef execv +# if HAVE_RAW_DECL_EXECV +_GL_WARN_ON_USE (execv, "execv behaves very differently on mingw - " + "use gnulib module execv for portability"); +# endif +#elif @GNULIB_MDA_EXECV@ /* On native Windows, map 'execv' to '_execv', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::execv always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef execv -# define execv _execv -# endif -_GL_CXXALIAS_MDA (execv, intptr_t, - (const char *program, const char * const *argv)); -#else +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execv +# define execv _execv +# endif +_GL_CXXALIAS_MDA_CAST (execv, intptr_t, + (const char *program, char * const *argv)); +# else _GL_CXXALIAS_SYS (execv, int, (const char *program, char * const *argv)); -#endif +# endif _GL_CXXALIASWARN (execv); +#endif +#if @GNULIB_EXECVE@ +# if @REPLACE_EXECVE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execve +# define execve rpl_execve +# endif +_GL_FUNCDECL_RPL (execve, int, + (const char *program, char * const *argv, char * const *env) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (execve, int, + (const char *program, char * const *argv, char * const *env)); +# else +_GL_CXXALIAS_SYS (execve, int, + (const char *program, char * const *argv, char * const *env)); +# endif +_GL_CXXALIASWARN (execve); +#elif defined GNULIB_POSIXCHECK +# undef execve +# if HAVE_RAW_DECL_EXECVE +_GL_WARN_ON_USE (execve, "execve behaves very differently on mingw - " + "use gnulib module execve for portability"); +# endif +#elif @GNULIB_MDA_EXECVE@ /* On native Windows, map 'execve' to '_execve', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::execve always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef execve -# define execve _execve -# endif -_GL_CXXALIAS_MDA (execve, intptr_t, - (const char *program, const char * const *argv, - const char * const *env)); -#else +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execve +# define execve _execve +# endif +_GL_CXXALIAS_MDA_CAST (execve, intptr_t, + (const char *program, char * const *argv, + char * const *env)); +# else _GL_CXXALIAS_SYS (execve, int, (const char *program, char * const *argv, char * const *env)); -#endif +# endif _GL_CXXALIASWARN (execve); +#endif +#if @GNULIB_EXECVP@ +# if @REPLACE_EXECVP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execvp +# define execvp rpl_execvp +# endif +_GL_FUNCDECL_RPL (execvp, int, (const char *program, char * const *argv) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (execvp, int, (const char *program, char * const *argv)); +# else +_GL_CXXALIAS_SYS (execvp, int, (const char *program, char * const *argv)); +# endif +_GL_CXXALIASWARN (execvp); +#elif defined GNULIB_POSIXCHECK +# undef execvp +# if HAVE_RAW_DECL_EXECVP +_GL_WARN_ON_USE (execvp, "execvp behaves very differently on mingw - " + "use gnulib module execvp for portability"); +# endif +#elif @GNULIB_MDA_EXECVP@ /* On native Windows, map 'execvp' to '_execvp', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::execvp always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef execvp -# define execvp _execvp -# endif -_GL_CXXALIAS_MDA (execvp, intptr_t, - (const char *program, const char * const *argv)); -#else +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execvp +# define execvp _execvp +# endif +_GL_CXXALIAS_MDA_CAST (execvp, intptr_t, + (const char *program, char * const *argv)); +# else _GL_CXXALIAS_SYS (execvp, int, (const char *program, char * const *argv)); -#endif +# endif _GL_CXXALIASWARN (execvp); +#endif +#if @GNULIB_EXECVPE@ +# if @REPLACE_EXECVPE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execvpe +# define execvpe rpl_execvpe +# endif +_GL_FUNCDECL_RPL (execvpe, int, + (const char *program, char * const *argv, char * const *env) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (execvpe, int, + (const char *program, char * const *argv, char * const *env)); +# else +# if !@HAVE_DECL_EXECVPE@ +_GL_FUNCDECL_SYS (execvpe, int, + (const char *program, char * const *argv, char * const *env) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (execvpe, int, + (const char *program, char * const *argv, char * const *env)); +# endif +_GL_CXXALIASWARN (execvpe); +#elif defined GNULIB_POSIXCHECK +# undef execvpe +# if HAVE_RAW_DECL_EXECVPE +_GL_WARN_ON_USE (execvpe, "execvpe behaves very differently on mingw - " + "use gnulib module execvpe for portability"); +# endif +#elif @GNULIB_MDA_EXECVPE@ /* On native Windows, map 'execvpe' to '_execvpe', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::execvpe on all platforms that have it. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef execvpe -# define execvpe _execvpe -# endif -_GL_CXXALIAS_MDA (execvpe, intptr_t, - (const char *program, const char * const *argv, - const char * const *env)); -#else -# if @HAVE_DECL_EXECVPE@ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execvpe +# define execvpe _execvpe +# endif +_GL_CXXALIAS_MDA_CAST (execvpe, intptr_t, + (const char *program, char * const *argv, + char * const *env)); +# elif @HAVE_EXECVPE@ +# if !@HAVE_DECL_EXECVPE@ +_GL_FUNCDECL_SYS (execvpe, int, + (const char *program, char * const *argv, char * const *env) + _GL_ARG_NONNULL ((1, 2))); +# endif _GL_CXXALIAS_SYS (execvpe, int, (const char *program, char * const *argv, char * const *env)); # endif -#endif -#if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_EXECVPE@ +# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_EXECVPE@ _GL_CXXALIASWARN (execvpe); +# endif #endif @@ -815,7 +978,7 @@ _GL_CXXALIASWARN (fchownat); # undef fchownat # if HAVE_RAW_DECL_FCHOWNAT _GL_WARN_ON_USE (fchownat, "fchownat is not portable - " - "use gnulib module openat for portability"); + "use gnulib module fchownat for portability"); # endif #endif @@ -921,7 +1084,7 @@ _GL_CXXALIASWARN (getcwd); _GL_WARN_ON_USE (getcwd, "getcwd is unportable - " "use gnulib module getcwd for portability"); # endif -#else +#elif @GNULIB_MDA_GETCWD@ /* On native Windows, map 'getcwd' to '_getcwd', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::getcwd always. */ @@ -1271,19 +1434,21 @@ _GL_WARN_ON_USE (getpass, "getpass is unportable - " #endif +#if @GNULIB_MDA_GETPID@ /* On native Windows, map 'getpid' to '_getpid', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::getpid always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef getpid -# define getpid _getpid -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getpid +# define getpid _getpid +# endif _GL_CXXALIAS_MDA (getpid, int, (void)); -#else +# else _GL_CXXALIAS_SYS (getpid, pid_t, (void)); -#endif +# endif _GL_CXXALIASWARN (getpid); +#endif #if @GNULIB_GETUSERSHELL@ @@ -1374,7 +1539,7 @@ _GL_CXXALIASWARN (isatty); _GL_WARN_ON_USE (isatty, "isatty has portability problems on native Windows - " "use gnulib module isatty for portability"); # endif -#else +#elif @GNULIB_MDA_ISATTY@ /* On native Windows, map 'isatty' to '_isatty', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::isatty always. */ @@ -1515,7 +1680,7 @@ _GL_CXXALIASWARN (lseek); _GL_WARN_ON_USE (lseek, "lseek does not fail with ESPIPE on pipes on some " "systems - use gnulib module lseek for portability"); # endif -#else +#elif @GNULIB_MDA_LSEEK@ /* On native Windows, map 'lseek' to '_lseek', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::lseek always. */ @@ -1671,7 +1836,7 @@ _GL_CXXALIAS_MDA (read, ssize_t, (int fd, void *buf, size_t count)); _GL_CXXALIAS_SYS (read, ssize_t, (int fd, void *buf, size_t count)); # endif _GL_CXXALIASWARN (read); -#else +#elif @GNULIB_MDA_READ@ /* On native Windows, map 'read' to '_read', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::read always. */ @@ -1787,7 +1952,7 @@ _GL_CXXALIASWARN (rmdir); _GL_WARN_ON_USE (rmdir, "rmdir is unportable - " "use gnulib module rmdir for portability"); # endif -#else +#elif @GNULIB_MDA_RMDIR@ /* On native Windows, map 'rmdir' to '_rmdir', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::rmdir always. */ @@ -1859,19 +2024,21 @@ _GL_WARN_ON_USE (sleep, "sleep is unportable - " #endif +#if @GNULIB_MDA_SWAB@ /* On native Windows, map 'swab' to '_swab', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::creat always. */ -#if defined _WIN32 && !defined __CYGWIN__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef swab -# define swab _swab -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef swab +# define swab _swab +# endif _GL_CXXALIAS_MDA (swab, void, (char *from, char *to, int n)); -#else +# else _GL_CXXALIAS_SYS (swab, void, (const void *from, void *to, ssize_t n)); -#endif +# endif _GL_CXXALIASWARN (swab); +#endif #if @GNULIB_SYMLINK@ @@ -2014,7 +2181,7 @@ _GL_CXXALIASWARN (unlink); _GL_WARN_ON_USE (unlink, "unlink is not portable - " "use gnulib module unlink for portability"); # endif -#else +#elif @GNULIB_MDA_UNLINK@ /* On native Windows, map 'unlink' to '_unlink', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::unlink always. */ @@ -2052,7 +2219,7 @@ _GL_CXXALIASWARN (unlinkat); # undef unlinkat # if HAVE_RAW_DECL_UNLINKAT _GL_WARN_ON_USE (unlinkat, "unlinkat is not portable - " - "use gnulib module openat for portability"); + "use gnulib module unlinkat for portability"); # endif #endif @@ -2109,7 +2276,7 @@ _GL_CXXALIAS_MDA (write, ssize_t, (int fd, const void *buf, size_t count)); _GL_CXXALIAS_SYS (write, ssize_t, (int fd, const void *buf, size_t count)); # endif _GL_CXXALIASWARN (write); -#else +#elif @GNULIB_MDA_WRITE@ /* On native Windows, map 'write' to '_write', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between platforms by defining GNULIB_NAMESPACE::write always. */ diff --git a/lib/xalloc-oversized.h b/lib/xalloc-oversized.h index 3550cab846..53daf59663 100644 --- a/lib/xalloc-oversized.h +++ b/lib/xalloc-oversized.h @@ -1,7 +1,6 @@ /* xalloc-oversized.h -- memory allocation size checking - Copyright (C) 1990-2000, 2003-2004, 2006-2021 Free Software - Foundation, Inc. + Copyright (C) 1990-2000, 2003-2004, 2006-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/m4/alloca.m4 b/m4/alloca.m4 index 4a0d09f815..ba2f679d8e 100644 --- a/m4/alloca.m4 +++ b/m4/alloca.m4 @@ -1,6 +1,6 @@ # alloca.m4 serial 20 -dnl Copyright (C) 2002-2004, 2006-2007, 2009-2021 Free Software -dnl Foundation, Inc. +dnl Copyright (C) 2002-2004, 2006-2007, 2009-2021 Free Software Foundation, +dnl Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/canonicalize.m4 b/m4/canonicalize.m4 index 647a651e04..475fa15d6b 100644 --- a/m4/canonicalize.m4 +++ b/m4/canonicalize.m4 @@ -1,4 +1,4 @@ -# canonicalize.m4 serial 34 +# canonicalize.m4 serial 35 dnl Copyright (C) 2003-2007, 2009-2021 Free Software Foundation, Inc. @@ -11,7 +11,6 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_CANONICALIZE_FILENAME_MODE], [ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - AC_REQUIRE([gl_FUNC_FACCESSAT_EOVERFLOW]) AC_REQUIRE([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK]) AC_CHECK_FUNCS_ONCE([canonicalize_file_name faccessat]) AC_REQUIRE([gl_DOUBLE_SLASH_ROOT]) @@ -58,7 +57,6 @@ AC_DEFUN([gl_CANONICALIZE_LGPL], AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE], [ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - AC_REQUIRE([gl_FUNC_FACCESSAT_EOVERFLOW]) AC_REQUIRE([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK]) AC_CHECK_FUNCS_ONCE([canonicalize_file_name faccessat]) diff --git a/m4/d-type.m4 b/m4/d-type.m4 index fa4ddeb4b6..534a59e3e5 100644 --- a/m4/d-type.m4 +++ b/m4/d-type.m4 @@ -5,8 +5,7 @@ dnl dnl Check whether struct dirent has a member named d_type. dnl -# Copyright (C) 1997, 1999-2004, 2006, 2009-2021 Free Software -# Foundation, Inc. +# Copyright (C) 1997, 1999-2004, 2006, 2009-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/m4/dup2.m4 b/m4/dup2.m4 index 7d66aab0ee..0753a32491 100644 --- a/m4/dup2.m4 +++ b/m4/dup2.m4 @@ -1,6 +1,5 @@ #serial 27 -dnl Copyright (C) 2002, 2005, 2007, 2009-2021 Free Software Foundation, -dnl Inc. +dnl Copyright (C) 2002, 2005, 2007, 2009-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/faccessat.m4 b/m4/faccessat.m4 index 56d1d3e045..9d6b363511 100644 --- a/m4/faccessat.m4 +++ b/m4/faccessat.m4 @@ -1,4 +1,4 @@ -# serial 9 +# serial 10 # See if we need to provide faccessat replacement. dnl Copyright (C) 2009-2021 Free Software Foundation, Inc. @@ -8,31 +8,6 @@ dnl with or without modifications, as long as this notice is preserved. # Written by Eric Blake. -AC_DEFUN([gl_FUNC_FACCESSAT_EOVERFLOW], -[ - AC_CHECK_FUNCS_ONCE([faccessat]) - if test "$ac_cv_func_faccessat" = yes; then - AC_CACHE_CHECK([whether faccessat works when stat would EOVERFLOW], - [gl_cv_func_faccessat_never_eoverflows], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([], - [[#ifdef __linux__ - #include - #if (! (KERNEL_VERSION (5, 8, 0) <= LINUX_VERSION_CODE \ - && 2 < (__GLIBC__ + (33 <= __GLIBC_MINOR__)))) - #error "faccessat might fail with EOVERFLOW" - #endif - #endif - ]])], - [gl_cv_func_faccessat_never_eoverflows=yes], - [gl_cv_func_faccessat_never_eoverflows=no])]) - if test "$gl_cv_func_faccessat_never_eoverflows" = yes; then - AC_DEFINE([FACCESSAT_NEVER_EOVERFLOWS], 1, - [Define to 1 if faccessat is EOVERFLOW-free.]) - fi - fi -]) - AC_DEFUN([gl_FUNC_FACCESSAT], [ AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) @@ -41,14 +16,12 @@ AC_DEFUN([gl_FUNC_FACCESSAT], dnl Persuade glibc to declare faccessat(). AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - AC_REQUIRE([gl_FUNC_FACCESSAT_EOVERFLOW]) - AC_CHECK_FUNCS_ONCE([faccessat]) if test $ac_cv_func_faccessat = no; then HAVE_FACCESSAT=0 else - case $gl_cv_func_lstat_dereferences_slashed_symlink,$gl_cv_func_faccessat_never_eoverflows in - *yes,*yes) ;; + case $gl_cv_func_lstat_dereferences_slashed_symlink in + *yes) ;; *) REPLACE_FACCESSAT=1 ;; esac fi diff --git a/m4/fcntl_h.m4 b/m4/fcntl_h.m4 index 8febb5cbfd..e63a82f10a 100644 --- a/m4/fcntl_h.m4 +++ b/m4/fcntl_h.m4 @@ -1,4 +1,4 @@ -# serial 16 +# serial 17 # Configure fcntl.h. dnl Copyright (C) 2006-2007, 2009-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation @@ -42,6 +42,9 @@ AC_DEFUN([gl_FCNTL_H_DEFAULTS], GNULIB_NONBLOCKING=0; AC_SUBST([GNULIB_NONBLOCKING]) GNULIB_OPEN=0; AC_SUBST([GNULIB_OPEN]) GNULIB_OPENAT=0; AC_SUBST([GNULIB_OPENAT]) + dnl Support Microsoft deprecated alias function names by default. + GNULIB_MDA_CREAT=1; AC_SUBST([GNULIB_MDA_CREAT]) + GNULIB_MDA_OPEN=1; AC_SUBST([GNULIB_MDA_OPEN]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_FCNTL=1; AC_SUBST([HAVE_FCNTL]) HAVE_OPENAT=1; AC_SUBST([HAVE_OPENAT]) diff --git a/m4/filemode.m4 b/m4/filemode.m4 index 190a5d1948..4dc24efbd3 100644 --- a/m4/filemode.m4 +++ b/m4/filemode.m4 @@ -1,6 +1,5 @@ # filemode.m4 serial 9 -dnl Copyright (C) 2002, 2005-2006, 2009-2021 Free Software Foundation, -dnl Inc. +dnl Copyright (C) 2002, 2005-2006, 2009-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/fsusage.m4 b/m4/fsusage.m4 index 40e7ba528a..d005579f9e 100644 --- a/m4/fsusage.m4 +++ b/m4/fsusage.m4 @@ -1,8 +1,7 @@ # serial 35 # Obtaining file system usage information. -# Copyright (C) 1997-1998, 2000-2001, 2003-2021 Free Software -# Foundation, Inc. +# Copyright (C) 1997-1998, 2000-2001, 2003-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/m4/getgroups.m4 b/m4/getgroups.m4 index 0a6eb9f384..bd746cdf88 100644 --- a/m4/getgroups.m4 +++ b/m4/getgroups.m4 @@ -3,8 +3,7 @@ dnl From Jim Meyering. dnl A wrapper around AC_FUNC_GETGROUPS. -# Copyright (C) 1996-1997, 1999-2004, 2008-2021 Free Software -# Foundation, Inc. +# Copyright (C) 1996-1997, 1999-2004, 2008-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/m4/getloadavg.m4 b/m4/getloadavg.m4 index 8713e322da..bba2216949 100644 --- a/m4/getloadavg.m4 +++ b/m4/getloadavg.m4 @@ -1,7 +1,7 @@ # Check for getloadavg. -# Copyright (C) 1992-1996, 1999-2000, 2002-2003, 2006, 2008-2021 Free -# Software Foundation, Inc. +# Copyright (C) 1992-1996, 1999-2000, 2002-2003, 2006, 2008-2021 Free Software +# Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/m4/gettime.m4 b/m4/gettime.m4 index ddc72fa353..de7c33046c 100644 --- a/m4/gettime.m4 +++ b/m4/gettime.m4 @@ -1,6 +1,5 @@ # gettime.m4 serial 9 -dnl Copyright (C) 2002, 2004-2006, 2009-2021 Free Software Foundation, -dnl Inc. +dnl Copyright (C) 2002, 2004-2006, 2009-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/gettimeofday.m4 b/m4/gettimeofday.m4 index 9cbf88e2e2..3c20081574 100644 --- a/m4/gettimeofday.m4 +++ b/m4/gettimeofday.m4 @@ -1,7 +1,6 @@ # serial 28 -# Copyright (C) 2001-2003, 2005, 2007, 2009-2021 Free Software -# Foundation, Inc. +# Copyright (C) 2001-2003, 2005, 2007, 2009-2021 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index c0efba76a2..ad109520dd 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -1077,6 +1077,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/limits.in.h lib/lstat.c lib/malloc/scratch_buffer.h + lib/malloc/scratch_buffer_dupfree.c lib/malloc/scratch_buffer_grow.c lib/malloc/scratch_buffer_grow_preserve.c lib/malloc/scratch_buffer_set_array_size.c @@ -1216,7 +1217,6 @@ AC_DEFUN([gl_FILE_LIST], [ m4/gettime.m4 m4/gettimeofday.m4 m4/gl-openssl.m4 - m4/glibc21.m4 m4/gnulib-common.m4 m4/group-member.m4 m4/ieee754-h.m4 diff --git a/m4/group-member.m4 b/m4/group-member.m4 index ccf80137a4..7a7bb40afc 100644 --- a/m4/group-member.m4 +++ b/m4/group-member.m4 @@ -1,7 +1,6 @@ # serial 14 -# Copyright (C) 1999-2001, 2003-2007, 2009-2021 Free Software -# Foundation, Inc. +# Copyright (C) 1999-2001, 2003-2007, 2009-2021 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/m4/mempcpy.m4 b/m4/mempcpy.m4 index 75afbb695f..c5ee2af8cc 100644 --- a/m4/mempcpy.m4 +++ b/m4/mempcpy.m4 @@ -1,6 +1,6 @@ # mempcpy.m4 serial 11 -dnl Copyright (C) 2003-2004, 2006-2007, 2009-2021 Free Software -dnl Foundation, Inc. +dnl Copyright (C) 2003-2004, 2006-2007, 2009-2021 Free Software Foundation, +dnl Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/memrchr.m4 b/m4/memrchr.m4 index b4c21ab4d2..d0c05896e5 100644 --- a/m4/memrchr.m4 +++ b/m4/memrchr.m4 @@ -1,6 +1,6 @@ # memrchr.m4 serial 10 -dnl Copyright (C) 2002-2003, 2005-2007, 2009-2021 Free Software -dnl Foundation, Inc. +dnl Copyright (C) 2002-2003, 2005-2007, 2009-2021 Free Software Foundation, +dnl Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/mktime.m4 b/m4/mktime.m4 index 94c31084f1..245649e774 100644 --- a/m4/mktime.m4 +++ b/m4/mktime.m4 @@ -1,6 +1,6 @@ # serial 35 -dnl Copyright (C) 2002-2003, 2005-2007, 2009-2021 Free Software -dnl Foundation, Inc. +dnl Copyright (C) 2002-2003, 2005-2007, 2009-2021 Free Software Foundation, +dnl Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/nstrftime.m4 b/m4/nstrftime.m4 index 6ebde79a6c..4674442810 100644 --- a/m4/nstrftime.m4 +++ b/m4/nstrftime.m4 @@ -1,7 +1,6 @@ # serial 36 -# Copyright (C) 1996-1997, 1999-2007, 2009-2021 Free Software -# Foundation, Inc. +# Copyright (C) 1996-1997, 1999-2007, 2009-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/m4/pathmax.m4 b/m4/pathmax.m4 index 6059496bd8..e67c656659 100644 --- a/m4/pathmax.m4 +++ b/m4/pathmax.m4 @@ -1,6 +1,6 @@ # pathmax.m4 serial 11 -dnl Copyright (C) 2002-2003, 2005-2006, 2009-2021 Free Software -dnl Foundation, Inc. +dnl Copyright (C) 2002-2003, 2005-2006, 2009-2021 Free Software Foundation, +dnl Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/regex.m4 b/m4/regex.m4 index f35c981ced..850c572228 100644 --- a/m4/regex.m4 +++ b/m4/regex.m4 @@ -1,4 +1,4 @@ -# serial 70 +# serial 71 # Copyright (C) 1996-2001, 2003-2021 Free Software Foundation, Inc. # @@ -354,7 +354,6 @@ AC_DEFUN([gl_PREREQ_REGEX], AC_REQUIRE([AC_C_RESTRICT]) AC_REQUIRE([AC_TYPE_MBSTATE_T]) AC_REQUIRE([gl_EEMALLOC]) - AC_REQUIRE([gl_GLIBC21]) AC_CHECK_HEADERS([libintl.h]) AC_CHECK_FUNCS_ONCE([isblank iswctype]) AC_CHECK_DECLS([isblank], [], [], [[#include ]]) diff --git a/m4/sig2str.m4 b/m4/sig2str.m4 index 974f68ab01..8951bbd7f0 100644 --- a/m4/sig2str.m4 +++ b/m4/sig2str.m4 @@ -1,6 +1,5 @@ # serial 7 -dnl Copyright (C) 2002, 2005-2006, 2009-2021 Free Software Foundation, -dnl Inc. +dnl Copyright (C) 2002, 2005-2006, 2009-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/ssize_t.m4 b/m4/ssize_t.m4 index 4bd88b3b09..f0ed509fcc 100644 --- a/m4/ssize_t.m4 +++ b/m4/ssize_t.m4 @@ -1,6 +1,5 @@ # ssize_t.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 2001-2003, 2006, 2010-2021 Free Software Foundation, -dnl Inc. +dnl Copyright (C) 2001-2003, 2006, 2010-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/stat-time.m4 b/m4/stat-time.m4 index 46c5ac9e64..df1c2a7453 100644 --- a/m4/stat-time.m4 +++ b/m4/stat-time.m4 @@ -1,7 +1,7 @@ # Checks for stat-related time functions. -# Copyright (C) 1998-1999, 2001, 2003, 2005-2007, 2009-2021 Free -# Software Foundation, Inc. +# Copyright (C) 1998-1999, 2001, 2003, 2005-2007, 2009-2021 Free Software +# Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 index 7500a01447..4c3f24acca 100644 --- a/m4/stdio_h.m4 +++ b/m4/stdio_h.m4 @@ -1,4 +1,4 @@ -# stdio_h.m4 serial 51 +# stdio_h.m4 serial 52 dnl Copyright (C) 2007-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -180,6 +180,13 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS], GNULIB_VPRINTF_POSIX=0; AC_SUBST([GNULIB_VPRINTF_POSIX]) GNULIB_VSNPRINTF=0; AC_SUBST([GNULIB_VSNPRINTF]) GNULIB_VSPRINTF_POSIX=0; AC_SUBST([GNULIB_VSPRINTF_POSIX]) + dnl Support Microsoft deprecated alias function names by default. + GNULIB_MDA_FCLOSEALL=1; AC_SUBST([GNULIB_MDA_FCLOSEALL]) + GNULIB_MDA_FDOPEN=1; AC_SUBST([GNULIB_MDA_FDOPEN]) + GNULIB_MDA_FILENO=1; AC_SUBST([GNULIB_MDA_FILENO]) + GNULIB_MDA_GETW=1; AC_SUBST([GNULIB_MDA_GETW]) + GNULIB_MDA_PUTW=1; AC_SUBST([GNULIB_MDA_PUTW]) + GNULIB_MDA_TEMPNAM=1; AC_SUBST([GNULIB_MDA_TEMPNAM]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_DECL_FCLOSEALL=1; AC_SUBST([HAVE_DECL_FCLOSEALL]) HAVE_DECL_FPURGE=1; AC_SUBST([HAVE_DECL_FPURGE]) diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 index 9c944dafbf..5a02972e05 100644 --- a/m4/stdlib_h.m4 +++ b/m4/stdlib_h.m4 @@ -1,4 +1,4 @@ -# stdlib_h.m4 serial 54 +# stdlib_h.m4 serial 55 dnl Copyright (C) 2007-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -95,6 +95,12 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], GNULIB_UNLOCKPT=0; AC_SUBST([GNULIB_UNLOCKPT]) GNULIB_UNSETENV=0; AC_SUBST([GNULIB_UNSETENV]) GNULIB_WCTOMB=0; AC_SUBST([GNULIB_WCTOMB]) + dnl Support Microsoft deprecated alias function names by default. + GNULIB_MDA_ECVT=1; AC_SUBST([GNULIB_MDA_ECVT]) + GNULIB_MDA_FCVT=1; AC_SUBST([GNULIB_MDA_FCVT]) + GNULIB_MDA_GCVT=1; AC_SUBST([GNULIB_MDA_GCVT]) + GNULIB_MDA_MKTEMP=1; AC_SUBST([GNULIB_MDA_MKTEMP]) + GNULIB_MDA_PUTENV=1; AC_SUBST([GNULIB_MDA_PUTENV]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE__EXIT=1; AC_SUBST([HAVE__EXIT]) HAVE_ALIGNED_ALLOC=1; AC_SUBST([HAVE_ALIGNED_ALLOC]) diff --git a/m4/string_h.m4 b/m4/string_h.m4 index 09a659cb98..3e65355735 100644 --- a/m4/string_h.m4 +++ b/m4/string_h.m4 @@ -5,7 +5,7 @@ # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 27 +# serial 28 # Written by Paul Eggert. @@ -86,6 +86,9 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], GNULIB_STRSIGNAL=0; AC_SUBST([GNULIB_STRSIGNAL]) GNULIB_STRVERSCMP=0; AC_SUBST([GNULIB_STRVERSCMP]) HAVE_MBSLEN=0; AC_SUBST([HAVE_MBSLEN]) + dnl Support Microsoft deprecated alias function names by default. + GNULIB_MDA_MEMCCPY=1; AC_SUBST([GNULIB_MDA_MEMCCPY]) + GNULIB_MDA_STRDUP=1; AC_SUBST([GNULIB_MDA_STRDUP]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_EXPLICIT_BZERO=1; AC_SUBST([HAVE_EXPLICIT_BZERO]) HAVE_FFSL=1; AC_SUBST([HAVE_FFSL]) diff --git a/m4/strnlen.m4 b/m4/strnlen.m4 index 7cc8dcea98..bb9a680fdc 100644 --- a/m4/strnlen.m4 +++ b/m4/strnlen.m4 @@ -1,6 +1,6 @@ # strnlen.m4 serial 13 -dnl Copyright (C) 2002-2003, 2005-2007, 2009-2021 Free Software -dnl Foundation, Inc. +dnl Copyright (C) 2002-2003, 2005-2007, 2009-2021 Free Software Foundation, +dnl Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/strtoimax.m4 b/m4/strtoimax.m4 index b0fa904ebc..d767d57451 100644 --- a/m4/strtoimax.m4 +++ b/m4/strtoimax.m4 @@ -1,6 +1,5 @@ # strtoimax.m4 serial 16 -dnl Copyright (C) 2002-2004, 2006, 2009-2021 Free Software Foundation, -dnl Inc. +dnl Copyright (C) 2002-2004, 2006, 2009-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/strtoll.m4 b/m4/strtoll.m4 index a232ded6df..d2c9e5310d 100644 --- a/m4/strtoll.m4 +++ b/m4/strtoll.m4 @@ -1,6 +1,5 @@ # strtoll.m4 serial 8 -dnl Copyright (C) 2002, 2004, 2006, 2008-2021 Free Software Foundation, -dnl Inc. +dnl Copyright (C) 2002, 2004, 2006, 2008-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/m4/sys_stat_h.m4 b/m4/sys_stat_h.m4 index 3305764b61..e8eac71b46 100644 --- a/m4/sys_stat_h.m4 +++ b/m4/sys_stat_h.m4 @@ -1,4 +1,4 @@ -# sys_stat_h.m4 serial 34 -*- Autoconf -*- +# sys_stat_h.m4 serial 36 -*- Autoconf -*- dnl Copyright (C) 2006-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -71,6 +71,7 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS], GNULIB_GETUMASK=0; AC_SUBST([GNULIB_GETUMASK]) GNULIB_LCHMOD=0; AC_SUBST([GNULIB_LCHMOD]) GNULIB_LSTAT=0; AC_SUBST([GNULIB_LSTAT]) + GNULIB_MKDIR=0; AC_SUBST([GNULIB_MKDIR]) GNULIB_MKDIRAT=0; AC_SUBST([GNULIB_MKDIRAT]) GNULIB_MKFIFO=0; AC_SUBST([GNULIB_MKFIFO]) GNULIB_MKFIFOAT=0; AC_SUBST([GNULIB_MKFIFOAT]) @@ -79,6 +80,10 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS], GNULIB_STAT=0; AC_SUBST([GNULIB_STAT]) GNULIB_UTIMENSAT=0; AC_SUBST([GNULIB_UTIMENSAT]) GNULIB_OVERRIDES_STRUCT_STAT=0; AC_SUBST([GNULIB_OVERRIDES_STRUCT_STAT]) + dnl Support Microsoft deprecated alias function names by default. + GNULIB_MDA_CHMOD=1; AC_SUBST([GNULIB_MDA_CHMOD]) + GNULIB_MDA_MKDIR=1; AC_SUBST([GNULIB_MDA_MKDIR]) + GNULIB_MDA_UMASK=1; AC_SUBST([GNULIB_MDA_UMASK]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_FCHMODAT=1; AC_SUBST([HAVE_FCHMODAT]) HAVE_FSTATAT=1; AC_SUBST([HAVE_FSTATAT]) diff --git a/m4/time_h.m4 b/m4/time_h.m4 index 296ee45035..07e6967e45 100644 --- a/m4/time_h.m4 +++ b/m4/time_h.m4 @@ -1,9 +1,8 @@ # Configure a more-standard replacement for . -# Copyright (C) 2000-2001, 2003-2007, 2009-2021 Free Software -# Foundation, Inc. +# Copyright (C) 2000-2001, 2003-2007, 2009-2021 Free Software Foundation, Inc. -# serial 12 +# serial 13 # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -117,6 +116,8 @@ AC_DEFUN([gl_HEADER_TIME_H_DEFAULTS], GNULIB_TIME_R=0; AC_SUBST([GNULIB_TIME_R]) GNULIB_TIME_RZ=0; AC_SUBST([GNULIB_TIME_RZ]) GNULIB_TZSET=0; AC_SUBST([GNULIB_TZSET]) + dnl Support Microsoft deprecated alias function names by default. + GNULIB_MDA_TZSET=1; AC_SUBST([GNULIB_MDA_TZSET]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_DECL_LOCALTIME_R=1; AC_SUBST([HAVE_DECL_LOCALTIME_R]) HAVE_NANOSLEEP=1; AC_SUBST([HAVE_NANOSLEEP]) diff --git a/m4/timespec.m4 b/m4/timespec.m4 index 3af3d12c6d..40307d4f60 100644 --- a/m4/timespec.m4 +++ b/m4/timespec.m4 @@ -1,7 +1,6 @@ #serial 15 -# Copyright (C) 2000-2001, 2003-2007, 2009-2021 Free Software -# Foundation, Inc. +# Copyright (C) 2000-2001, 2003-2007, 2009-2021 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index 38c8a45d0f..0f26fb908d 100644 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -1,4 +1,4 @@ -# unistd_h.m4 serial 83 +# unistd_h.m4 serial 85 dnl Copyright (C) 2006-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -42,6 +42,7 @@ AC_DEFUN([gl_UNISTD_H], # endif #endif ]], [access chdir chown copy_file_range dup dup2 dup3 environ euidaccess + execl execle execlp execv execve execvp execvpe faccessat fchdir fchownat fdatasync fsync ftruncate getcwd getdomainname getdtablesize getentropy getgroups gethostname getlogin getlogin_r getpagesize getpass @@ -79,6 +80,13 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], GNULIB_DUP3=0; AC_SUBST([GNULIB_DUP3]) GNULIB_ENVIRON=0; AC_SUBST([GNULIB_ENVIRON]) GNULIB_EUIDACCESS=0; AC_SUBST([GNULIB_EUIDACCESS]) + GNULIB_EXECL=0; AC_SUBST([GNULIB_EXECL]) + GNULIB_EXECLE=0; AC_SUBST([GNULIB_EXECLE]) + GNULIB_EXECLP=0; AC_SUBST([GNULIB_EXECLP]) + GNULIB_EXECV=0; AC_SUBST([GNULIB_EXECV]) + GNULIB_EXECVE=0; AC_SUBST([GNULIB_EXECVE]) + GNULIB_EXECVP=0; AC_SUBST([GNULIB_EXECVP]) + GNULIB_EXECVPE=0; AC_SUBST([GNULIB_EXECVPE]) GNULIB_FACCESSAT=0; AC_SUBST([GNULIB_FACCESSAT]) GNULIB_FCHDIR=0; AC_SUBST([GNULIB_FCHDIR]) GNULIB_FCHOWNAT=0; AC_SUBST([GNULIB_FCHOWNAT]) @@ -123,11 +131,34 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], GNULIB_UNLINKAT=0; AC_SUBST([GNULIB_UNLINKAT]) GNULIB_USLEEP=0; AC_SUBST([GNULIB_USLEEP]) GNULIB_WRITE=0; AC_SUBST([GNULIB_WRITE]) + dnl Support Microsoft deprecated alias function names by default. + GNULIB_MDA_ACCESS=1; AC_SUBST([GNULIB_MDA_ACCESS]) + GNULIB_MDA_CHDIR=1; AC_SUBST([GNULIB_MDA_CHDIR]) + GNULIB_MDA_CLOSE=1; AC_SUBST([GNULIB_MDA_CLOSE]) + GNULIB_MDA_DUP=1; AC_SUBST([GNULIB_MDA_DUP]) + GNULIB_MDA_DUP2=1; AC_SUBST([GNULIB_MDA_DUP2]) + GNULIB_MDA_EXECL=1; AC_SUBST([GNULIB_MDA_EXECL]) + GNULIB_MDA_EXECLE=1; AC_SUBST([GNULIB_MDA_EXECLE]) + GNULIB_MDA_EXECLP=1; AC_SUBST([GNULIB_MDA_EXECLP]) + GNULIB_MDA_EXECV=1; AC_SUBST([GNULIB_MDA_EXECV]) + GNULIB_MDA_EXECVE=1; AC_SUBST([GNULIB_MDA_EXECVE]) + GNULIB_MDA_EXECVP=1; AC_SUBST([GNULIB_MDA_EXECVP]) + GNULIB_MDA_EXECVPE=1; AC_SUBST([GNULIB_MDA_EXECVPE]) + GNULIB_MDA_GETCWD=1; AC_SUBST([GNULIB_MDA_GETCWD]) + GNULIB_MDA_GETPID=1; AC_SUBST([GNULIB_MDA_GETPID]) + GNULIB_MDA_ISATTY=1; AC_SUBST([GNULIB_MDA_ISATTY]) + GNULIB_MDA_LSEEK=1; AC_SUBST([GNULIB_MDA_LSEEK]) + GNULIB_MDA_READ=1; AC_SUBST([GNULIB_MDA_READ]) + GNULIB_MDA_RMDIR=1; AC_SUBST([GNULIB_MDA_RMDIR]) + GNULIB_MDA_SWAB=1; AC_SUBST([GNULIB_MDA_SWAB]) + GNULIB_MDA_UNLINK=1; AC_SUBST([GNULIB_MDA_UNLINK]) + GNULIB_MDA_WRITE=1; AC_SUBST([GNULIB_MDA_WRITE]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_CHOWN=1; AC_SUBST([HAVE_CHOWN]) HAVE_COPY_FILE_RANGE=1; AC_SUBST([HAVE_COPY_FILE_RANGE]) HAVE_DUP3=1; AC_SUBST([HAVE_DUP3]) HAVE_EUIDACCESS=1; AC_SUBST([HAVE_EUIDACCESS]) + HAVE_EXECVPE=1; AC_SUBST([HAVE_EXECVPE]) HAVE_FACCESSAT=1; AC_SUBST([HAVE_FACCESSAT]) HAVE_FCHDIR=1; AC_SUBST([HAVE_FCHDIR]) HAVE_FCHOWNAT=1; AC_SUBST([HAVE_FCHOWNAT]) @@ -176,6 +207,13 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], REPLACE_CLOSE=0; AC_SUBST([REPLACE_CLOSE]) REPLACE_DUP=0; AC_SUBST([REPLACE_DUP]) REPLACE_DUP2=0; AC_SUBST([REPLACE_DUP2]) + REPLACE_EXECL=0; AC_SUBST([REPLACE_EXECL]) + REPLACE_EXECLE=0; AC_SUBST([REPLACE_EXECLE]) + REPLACE_EXECLP=0; AC_SUBST([REPLACE_EXECLP]) + REPLACE_EXECV=0; AC_SUBST([REPLACE_EXECV]) + REPLACE_EXECVE=0; AC_SUBST([REPLACE_EXECVE]) + REPLACE_EXECVP=0; AC_SUBST([REPLACE_EXECVP]) + REPLACE_EXECVPE=0; AC_SUBST([REPLACE_EXECVPE]) REPLACE_FACCESSAT=0; AC_SUBST([REPLACE_FACCESSAT]) REPLACE_FCHOWNAT=0; AC_SUBST([REPLACE_FCHOWNAT]) REPLACE_FTRUNCATE=0; AC_SUBST([REPLACE_FTRUNCATE]) commit 50f3949119cd5bb2f058b90d14b2940a3a8a7a0e Merge: c63ce13206 33d159c36f Author: Paul Eggert Date: Fri Jan 1 01:28:16 2021 -0800 Merge from origin/emacs-27 33d159c36f Fix copyright years by hand commit c63ce13206de9a6d4018e97b98b1f6966ee666d8 Merge: 8bc552ffa5 8c1fe1e5ef Author: Paul Eggert Date: Fri Jan 1 01:14:59 2021 -0800 ; Merge from origin/emacs-27 The following commit was skipped: 8c1fe1e5ef Update copyright year to 2021 commit 8bc552ffa53936f9fa1517c30d5057be80d09ca4 Merge: ba05d005e5 74a77ef299 Author: Paul Eggert Date: Fri Jan 1 01:14:58 2021 -0800 Merge from origin/emacs-27 74a77ef299 Improve documentation of 'network-lookup-address-info' c6d5555646 Display messages sent using ERC's /say c156723769 Fix Rmail summary display when From: header is malformed commit ba05d005e5a81bc123ad8da928b1bccb6b160e7a Author: Paul Eggert Date: Fri Jan 1 01:13:56 2021 -0800 Update copyright year to 2021 Run "TZ=UTC0 admin/update-copyright". diff --git a/.gitattributes b/.gitattributes index 00f434da7c..a99cf12af5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,6 @@ # Attributes of Emacs files in the Git repository. -# Copyright 2015-2020 Free Software Foundation, Inc. +# Copyright 2015-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/.gitignore b/.gitignore index bf7e934981..dd4eab759c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # Files that Git should ignore in the Emacs source directory. -# Copyright 2009-2020 Free Software Foundation, Inc. +# Copyright 2009-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bab2573c88..bc18137a43 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright (C) 2017-2020 Free Software Foundation, Inc. +# Copyright (C) 2017-2021 Free Software Foundation, Inc. # # This file is part of GNU Emacs. # diff --git a/ChangeLog.1 b/ChangeLog.1 index b01a316f74..82e0ad5c2b 100644 --- a/ChangeLog.1 +++ b/ChangeLog.1 @@ -14700,7 +14700,7 @@ ;; coding: utf-8 ;; End: - Copyright (C) 1993-1999, 2001-2020 Free Software Foundation, Inc. + Copyright (C) 1993-1999, 2001-2021 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/ChangeLog.2 b/ChangeLog.2 index 5e9b8b901e..7b40c54dc6 100644 --- a/ChangeLog.2 +++ b/ChangeLog.2 @@ -35787,7 +35787,7 @@ See ChangeLog.1 for earlier changes. ;; coding: utf-8 ;; End: - Copyright (C) 2015-2020 Free Software Foundation, Inc. + Copyright (C) 2015-2021 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/ChangeLog.3 b/ChangeLog.3 index 0f36310079..22b45cb5a3 100644 --- a/ChangeLog.3 +++ b/ChangeLog.3 @@ -142485,7 +142485,7 @@ See ChangeLog.2 for earlier changes. ;; coding: utf-8 ;; End: - Copyright (C) 2015-2020 Free Software Foundation, Inc. + Copyright (C) 2015-2021 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/GNUmakefile b/GNUmakefile index c6407d0491..f27163840b 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,6 +1,6 @@ # Build Emacs from a fresh tarball or version-control checkout. -# Copyright (C) 2011-2020 Free Software Foundation, Inc. +# Copyright (C) 2011-2021 Free Software Foundation, Inc. # # This file is part of GNU Emacs. # diff --git a/INSTALL b/INSTALL index 324ef60c69..b6f681a153 100644 --- a/INSTALL +++ b/INSTALL @@ -1,5 +1,5 @@ GNU Emacs Installation Guide -Copyright (C) 1992, 1994, 1996-1997, 2000-2020 Free Software Foundation, +Copyright (C) 1992, 1994, 1996-1997, 2000-2021 Free Software Foundation, Inc. See the end of the file for license conditions. diff --git a/INSTALL.REPO b/INSTALL.REPO index da0c220c2b..da56d7611b 100644 --- a/INSTALL.REPO +++ b/INSTALL.REPO @@ -83,7 +83,7 @@ never platform-specific. -Copyright (C) 2002-2020 Free Software Foundation, Inc. +Copyright (C) 2002-2021 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/Makefile.in b/Makefile.in index fbb1891ba7..f963351ba0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,6 +1,6 @@ ### @configure_input@ -# Copyright (C) 1992-2020 Free Software Foundation, Inc. +# Copyright (C) 1992-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/README b/README index 3d499a3596..a1d5e2dcef 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -Copyright (C) 2001-2020 Free Software Foundation, Inc. +Copyright (C) 2001-2021 Free Software Foundation, Inc. See the end of the file for license conditions. diff --git a/admin/ChangeLog.1 b/admin/ChangeLog.1 index 64c65bdd12..f3de691325 100644 --- a/admin/ChangeLog.1 +++ b/admin/ChangeLog.1 @@ -2577,7 +2577,7 @@ ;; coding: utf-8 ;; End: - Copyright (C) 2001-2020 Free Software Foundation, Inc. + Copyright (C) 2001-2021 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/admin/README b/admin/README index 67f51a3413..312f09839e 100644 --- a/admin/README +++ b/admin/README @@ -1,4 +1,4 @@ -Copyright (C) 2001-2020 Free Software Foundation, Inc. +Copyright (C) 2001-2021 Free Software Foundation, Inc. See the end of the file for license conditions. diff --git a/admin/admin.el b/admin/admin.el index 22d29673fb..fa96b7e5ca 100644 --- a/admin/admin.el +++ b/admin/admin.el @@ -1,6 +1,6 @@ ;;; admin.el --- utilities for Emacs administration -;; Copyright (C) 2001-2020 Free Software Foundation, Inc. +;; Copyright (C) 2001-2021 Free Software Foundation, Inc. ;; This file is part of GNU Emacs. diff --git a/admin/alloc-colors.c b/admin/alloc-colors.c index 203605cc58..ea5b750236 100644 --- a/admin/alloc-colors.c +++ b/admin/alloc-colors.c @@ -1,6 +1,6 @@ /* Allocate X colors. Used for testing with dense colormaps. -Copyright (C) 2001-2020 Free Software Foundation, Inc. +Copyright (C) 2001-2021 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/admin/authors.el b/admin/authors.el index ced0e56810..0180ffea25 100644 --- a/admin/authors.el +++ b/admin/authors.el @@ -1,6 +1,6 @@ ;;; authors.el --- utility for maintaining Emacs's AUTHORS file -;; Copyright (C) 2000-2020 Free Software Foundation, Inc. +;; Copyright (C) 2000-2021 Free Software Foundation, Inc. ;; Author: Gerd Moellmann ;; Maintainer: emacs-devel@gnu.org diff --git a/admin/automerge b/admin/automerge index cd0f22c3f2..61570587d6 100755 --- a/admin/automerge +++ b/admin/automerge @@ -1,7 +1,7 @@ #!/bin/bash ### automerge - automatically merge the Emacs release branch to master -## Copyright (C) 2018-2020 Free Software Foundation, Inc. +## Copyright (C) 2018-2021 Free Software Foundation, Inc. ## Author: Glenn Morris ## Maintainer: emacs-devel@gnu.org diff --git a/admin/build-configs b/admin/build-configs index dfd037cace..2e04e0008e 100755 --- a/admin/build-configs +++ b/admin/build-configs @@ -1,7 +1,7 @@ #! /usr/bin/perl # Build Emacs in several different configurations. -# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/admin/charsets/Makefile.in b/admin/charsets/Makefile.in index 3af0f02816..0fd130d346 100644 --- a/admin/charsets/Makefile.in +++ b/admin/charsets/Makefile.in @@ -1,6 +1,6 @@ ### @configure_input@ -# Copyright (C) 2015-2020 Free Software Foundation, Inc. +# Copyright (C) 2015-2021 Free Software Foundation, Inc. # Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 # National Institute of Advanced Industrial Science and Technology (AIST) diff --git a/admin/charsets/mapconv b/admin/charsets/mapconv index ad62f3cb64..f933c34ffc 100755 --- a/admin/charsets/mapconv +++ b/admin/charsets/mapconv @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright (C) 2015-2020 Free Software Foundation, Inc. +# Copyright (C) 2015-2021 Free Software Foundation, Inc. # Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 # National Institute of Advanced Industrial Science and Technology (AIST) diff --git a/admin/charsets/mapfiles/README b/admin/charsets/mapfiles/README index c3205672d1..60f09125a9 100644 --- a/admin/charsets/mapfiles/README +++ b/admin/charsets/mapfiles/README @@ -1,4 +1,4 @@ -Copyright (C) 2009-2020 Free Software Foundation, Inc. +Copyright (C) 2009-2021 Free Software Foundation, Inc. Copyright (C) 2009, 2010, 2011 National Institute of Advanced Industrial Science and Technology (AIST) Registration Number H13PRO009 diff --git a/admin/cus-test.el b/admin/cus-test.el index b4e4b42651..aca7b68aa7 100644 --- a/admin/cus-test.el +++ b/admin/cus-test.el @@ -1,6 +1,6 @@ ;;; cus-test.el --- tests for custom types and load problems -;; Copyright (C) 1998, 2000, 2002-2020 Free Software Foundation, Inc. +;; Copyright (C) 1998, 2000, 2002-2021 Free Software Foundation, Inc. ;; Author: Markus Rost ;; Created: 13 Sep 1998 diff --git a/admin/diff-tar-files b/admin/diff-tar-files index 52c7a480a4..cdcc512ae6 100755 --- a/admin/diff-tar-files +++ b/admin/diff-tar-files @@ -1,6 +1,6 @@ #! /bin/sh -# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/admin/find-gc.el b/admin/find-gc.el index 7de2474b82..c70a051bfb 100644 --- a/admin/find-gc.el +++ b/admin/find-gc.el @@ -1,6 +1,6 @@ ;;; find-gc.el --- detect functions that call the garbage collector -;; Copyright (C) 1992, 2001-2020 Free Software Foundation, Inc. +;; Copyright (C) 1992, 2001-2021 Free Software Foundation, Inc. ;; Maintainer: emacs-devel@gnu.org diff --git a/admin/gitmerge.el b/admin/gitmerge.el index 18da466aaa..1364bdc67a 100644 --- a/admin/gitmerge.el +++ b/admin/gitmerge.el @@ -1,6 +1,6 @@ ;;; gitmerge.el --- help merge one Emacs branch into another -;; Copyright (C) 2010-2020 Free Software Foundation, Inc. +;; Copyright (C) 2010-2021 Free Software Foundation, Inc. ;; Authors: David Engster ;; Stefan Monnier diff --git a/admin/grammars/Makefile.in b/admin/grammars/Makefile.in index a170e08924..98c9c623ab 100644 --- a/admin/grammars/Makefile.in +++ b/admin/grammars/Makefile.in @@ -1,6 +1,6 @@ ### @configure_input@ -## Copyright (C) 2013-2020 Free Software Foundation, Inc. +## Copyright (C) 2013-2021 Free Software Foundation, Inc. ## This file is part of GNU Emacs. diff --git a/admin/grammars/c.by b/admin/grammars/c.by index d12e6f95cb..2d04c999ac 100644 --- a/admin/grammars/c.by +++ b/admin/grammars/c.by @@ -1,5 +1,5 @@ ;;; c.by -- LL grammar for C/C++ language specification -;; Copyright (C) 1999-2020 Free Software Foundation, Inc. +;; Copyright (C) 1999-2021 Free Software Foundation, Inc. ;; ;; Author: Eric M. Ludlam ;; David Ponce diff --git a/admin/grammars/grammar.wy b/admin/grammars/grammar.wy index 1ae2a903bd..054e85bf70 100644 --- a/admin/grammars/grammar.wy +++ b/admin/grammars/grammar.wy @@ -1,6 +1,6 @@ ;;; semantic-grammar.wy -- LALR grammar of Semantic input grammars ;; -;; Copyright (C) 2002-2020 Free Software Foundation, Inc. +;; Copyright (C) 2002-2021 Free Software Foundation, Inc. ;; ;; Author: David Ponce ;; Created: 26 Aug 2002 diff --git a/admin/grammars/java-tags.wy b/admin/grammars/java-tags.wy index 678b36cd0a..486924b799 100644 --- a/admin/grammars/java-tags.wy +++ b/admin/grammars/java-tags.wy @@ -1,6 +1,6 @@ ;;; java-tags.wy -- Semantic LALR grammar for Java -;; Copyright (C) 2002-2020 Free Software Foundation, Inc. +;; Copyright (C) 2002-2021 Free Software Foundation, Inc. ;; ;; Author: David Ponce ;; Created: 26 Aug 2002 diff --git a/admin/grammars/js.wy b/admin/grammars/js.wy index 94837baf7c..e85db1572c 100644 --- a/admin/grammars/js.wy +++ b/admin/grammars/js.wy @@ -1,6 +1,6 @@ ;;; javascript-jv.wy -- LALR grammar for Javascript -;; Copyright (C) 2005-2020 Free Software Foundation, Inc. +;; Copyright (C) 2005-2021 Free Software Foundation, Inc. ;; Copyright (C) 1998-2011 Ecma International. ;; Author: Joakim Verona diff --git a/admin/grammars/make.by b/admin/grammars/make.by index 7573d0cf9e..f66585e70e 100644 --- a/admin/grammars/make.by +++ b/admin/grammars/make.by @@ -1,6 +1,6 @@ ;;; make.by -- BY notation for Makefiles. -;; Copyright (C) 1999-2020 Free Software Foundation, Inc. +;; Copyright (C) 1999-2021 Free Software Foundation, Inc. ;; ;; Author: Eric M. Ludlam ;; David Ponce diff --git a/admin/grammars/python.wy b/admin/grammars/python.wy index 5790461c73..aaa25ced20 100644 --- a/admin/grammars/python.wy +++ b/admin/grammars/python.wy @@ -1,6 +1,6 @@ ;;; python.wy -- LALR grammar for Python -;; Copyright (C) 2002-2020 Free Software Foundation, Inc. +;; Copyright (C) 2002-2021 Free Software Foundation, Inc. ;; Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, ;; 2009, 2010 Python Software Foundation; All Rights Reserved diff --git a/admin/grammars/scheme.by b/admin/grammars/scheme.by index 572cf564d7..c3abb5a28e 100644 --- a/admin/grammars/scheme.by +++ b/admin/grammars/scheme.by @@ -1,6 +1,6 @@ ;;; scheme.by -- Scheme BNF language specification -;; Copyright (C) 2001-2020 Free Software Foundation, Inc. +;; Copyright (C) 2001-2021 Free Software Foundation, Inc. ;; This file is part of GNU Emacs. diff --git a/admin/grammars/srecode-template.wy b/admin/grammars/srecode-template.wy index c8d1492af2..868a81cf18 100644 --- a/admin/grammars/srecode-template.wy +++ b/admin/grammars/srecode-template.wy @@ -1,6 +1,6 @@ ;;; srecode-template.wy --- Semantic Recoder Template parser -;; Copyright (C) 2005-2020 Free Software Foundation, Inc. +;; Copyright (C) 2005-2021 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: syntax diff --git a/admin/last-chance.el b/admin/last-chance.el index 8ee6af5a66..fd5b8e9bd7 100644 --- a/admin/last-chance.el +++ b/admin/last-chance.el @@ -1,6 +1,6 @@ ;;; last-chance.el --- dangling deterrence -*- lexical-binding: t; -*- -;; Copyright (C) 2016-2020 Free Software Foundation, Inc. +;; Copyright (C) 2016-2021 Free Software Foundation, Inc. ;; Author: Thien-Thi Nguyen ;; Maintainer: emacs-devel@gnu.org diff --git a/admin/make-emacs b/admin/make-emacs index 634c226ac8..fa7880b566 100755 --- a/admin/make-emacs +++ b/admin/make-emacs @@ -2,7 +2,7 @@ # Build Emacs with various options for profiling, debugging, # with and without warnings enabled etc. -# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/admin/make-manuals b/admin/make-manuals index 13a8148bb3..f133949520 100755 --- a/admin/make-manuals +++ b/admin/make-manuals @@ -1,7 +1,7 @@ #!/bin/bash ### make-manuals - create the Emacs manuals to upload to the gnu.org website -## Copyright 2018-2020 Free Software Foundation, Inc. +## Copyright 2018-2021 Free Software Foundation, Inc. ## Author: Glenn Morris ## Maintainer: emacs-devel@gnu.org diff --git a/admin/merge-gnulib b/admin/merge-gnulib index 880dc5eef5..1c8b442700 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib @@ -4,7 +4,7 @@ # # admin/merge-gnulib -# Copyright 2012-2020 Free Software Foundation, Inc. +# Copyright 2012-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/admin/merge-pkg-config b/admin/merge-pkg-config index ab705ccebf..1136a304dd 100755 --- a/admin/merge-pkg-config +++ b/admin/merge-pkg-config @@ -4,7 +4,7 @@ # # admin/merge-pkg-config -# Copyright 2014-2020 Free Software Foundation, Inc. +# Copyright 2014-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/admin/notes/copyright b/admin/notes/copyright index 156eec04cd..5b00c82ce9 100644 --- a/admin/notes/copyright +++ b/admin/notes/copyright @@ -1,4 +1,4 @@ -Copyright (C) 2007-2020 Free Software Foundation, Inc. +Copyright (C) 2007-2021 Free Software Foundation, Inc. See the end of the file for license conditions. diff --git a/admin/notes/emba b/admin/notes/emba index 76b0d3c599..adebcefcf3 100644 --- a/admin/notes/emba +++ b/admin/notes/emba @@ -1,6 +1,6 @@ -*- mode: outline; coding: utf-8 -*- -Copyright (C) 2019-2020 Free Software Foundation, Inc. +Copyright (C) 2019-2021 Free Software Foundation, Inc. See the end of the file for license conditions. NOTES FOR EMACS CONTINUOUS BUILD ON EMBA diff --git a/admin/notes/hydra b/admin/notes/hydra index 1b7d915c7a..62ad7ebf9c 100644 --- a/admin/notes/hydra +++ b/admin/notes/hydra @@ -1,6 +1,6 @@ -*- mode: outline; coding: utf-8 -*- -Copyright (C) 2013-2020 Free Software Foundation, Inc. +Copyright (C) 2013-2021 Free Software Foundation, Inc. See the end of the file for license conditions. NOTES FOR EMACS CONTINUOUS BUILD ON HYDRA diff --git a/admin/notes/multi-tty b/admin/notes/multi-tty index dee816ddb3..1a337b9d79 100644 --- a/admin/notes/multi-tty +++ b/admin/notes/multi-tty @@ -1,6 +1,6 @@ -*- coding: utf-8; mode: text; -*- -Copyright (C) 2007-2020 Free Software Foundation, Inc. +Copyright (C) 2007-2021 Free Software Foundation, Inc. See the end of the file for license conditions. From README.multi-tty in the multi-tty branch. diff --git a/admin/notes/unicode b/admin/notes/unicode index 1e418590a6..45455d897f 100644 --- a/admin/notes/unicode +++ b/admin/notes/unicode @@ -1,6 +1,6 @@ -*-mode: text; coding: utf-8;-*- -Copyright (C) 2002-2020 Free Software Foundation, Inc. +Copyright (C) 2002-2021 Free Software Foundation, Inc. See the end of the file for license conditions. Importing a new Unicode Standard version into Emacs diff --git a/admin/notes/www b/admin/notes/www index cfc23ace01..524b908d0e 100644 --- a/admin/notes/www +++ b/admin/notes/www @@ -1,6 +1,6 @@ -*- outline -*- -Copyright (C) 2013-2020 Free Software Foundation, Inc. +Copyright (C) 2013-2021 Free Software Foundation, Inc. See the end of the file for license conditions. NOTES FOR EMACS WWW PAGES diff --git a/admin/nt/README-UNDUMP.W32 b/admin/nt/README-UNDUMP.W32 index 7937d65a51..aaaea3b91f 100644 --- a/admin/nt/README-UNDUMP.W32 +++ b/admin/nt/README-UNDUMP.W32 @@ -1,4 +1,4 @@ -Copyright (C) 2001-2020 Free Software Foundation, Inc. +Copyright (C) 2001-2021 Free Software Foundation, Inc. See the end of the file for license conditions. Emacs for Windows diff --git a/admin/nt/dist-build/README-windows-binaries b/admin/nt/dist-build/README-windows-binaries index 01f7ed9da1..001bdd73f7 100644 --- a/admin/nt/dist-build/README-windows-binaries +++ b/admin/nt/dist-build/README-windows-binaries @@ -1,4 +1,4 @@ -Copyright (C) 2001-2020 Free Software Foundation, Inc. +Copyright (C) 2001-2021 Free Software Foundation, Inc. See the end of the file for license conditions. Precompiled Distributions of diff --git a/admin/nt/dist-build/build-dep-zips.py b/admin/nt/dist-build/build-dep-zips.py index bc5f65f085..47185dbb1b 100755 --- a/admin/nt/dist-build/build-dep-zips.py +++ b/admin/nt/dist-build/build-dep-zips.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -## Copyright (C) 2017-2020 Free Software Foundation, Inc. +## Copyright (C) 2017-2021 Free Software Foundation, Inc. ## This file is part of GNU Emacs. diff --git a/admin/nt/dist-build/build-zips.sh b/admin/nt/dist-build/build-zips.sh index 8eaa3a909b..809cbc65ca 100755 --- a/admin/nt/dist-build/build-zips.sh +++ b/admin/nt/dist-build/build-zips.sh @@ -1,6 +1,6 @@ #!/bin/bash -## Copyright (C) 2017-2020 Free Software Foundation, Inc. +## Copyright (C) 2017-2021 Free Software Foundation, Inc. ## This file is part of GNU Emacs. diff --git a/admin/quick-install-emacs b/admin/quick-install-emacs index 0439c77d01..475658ae93 100755 --- a/admin/quick-install-emacs +++ b/admin/quick-install-emacs @@ -1,7 +1,7 @@ #!/bin/sh ### quick-install-emacs --- do a halfway-decent job of installing emacs quickly -## Copyright (C) 2001-2020 Free Software Foundation, Inc. +## Copyright (C) 2001-2021 Free Software Foundation, Inc. ## Author: Miles Bader diff --git a/admin/unidata/Makefile.in b/admin/unidata/Makefile.in index f3e1c78611..f31e1bb09f 100644 --- a/admin/unidata/Makefile.in +++ b/admin/unidata/Makefile.in @@ -1,6 +1,6 @@ ### @configure_input@ -# Copyright (C) 2012-2020 Free Software Foundation, Inc. +# Copyright (C) 2012-2021 Free Software Foundation, Inc. # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 # National Institute of Advanced Industrial Science and Technology (AIST) diff --git a/admin/unidata/blocks.awk b/admin/unidata/blocks.awk index 70e96ed802..986d299e66 100755 --- a/admin/unidata/blocks.awk +++ b/admin/unidata/blocks.awk @@ -1,6 +1,6 @@ #!/usr/bin/awk -f -## Copyright (C) 2015-2020 Free Software Foundation, Inc. +## Copyright (C) 2015-2021 Free Software Foundation, Inc. ## Author: Glenn Morris ## Maintainer: emacs-devel@gnu.org diff --git a/admin/unidata/unidata-gen.el b/admin/unidata/unidata-gen.el index 510bb7959f..3918853088 100644 --- a/admin/unidata/unidata-gen.el +++ b/admin/unidata/unidata-gen.el @@ -1,6 +1,6 @@ ;; unidata-gen.el -- Create files containing character property data -*- lexical-binding:t -*- -;; Copyright (C) 2008-2020 Free Software Foundation, Inc. +;; Copyright (C) 2008-2021 Free Software Foundation, Inc. ;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 ;; National Institute of Advanced Industrial Science and Technology (AIST) diff --git a/admin/unidata/uvs.el b/admin/unidata/uvs.el index 6b8909ce66..0141b638fb 100644 --- a/admin/unidata/uvs.el +++ b/admin/unidata/uvs.el @@ -1,6 +1,6 @@ ;;; uvs.el --- utility for UVS (format 14) cmap subtables in OpenType fonts -*- lexical-binding:t -*- -;; Copyright (C) 2014-2020 Free Software Foundation, Inc. +;; Copyright (C) 2014-2021 Free Software Foundation, Inc. ;; Author: YAMAMOTO Mitsuharu diff --git a/admin/update-copyright b/admin/update-copyright index a70d7a3ff9..86953838bd 100755 --- a/admin/update-copyright +++ b/admin/update-copyright @@ -7,7 +7,7 @@ # By default, this script uses the local-time calendar year. # Set the UPDATE_COPYRIGHT_YEAR environment variable to override the default. -# Copyright 2013-2020 Free Software Foundation, Inc. +# Copyright 2013-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/admin/update_autogen b/admin/update_autogen index d60984e13f..35c391da19 100755 --- a/admin/update_autogen +++ b/admin/update_autogen @@ -1,7 +1,7 @@ #!/usr/bin/env bash ### update_autogen - update some auto-generated files in the Emacs tree -## Copyright (C) 2011-2020 Free Software Foundation, Inc. +## Copyright (C) 2011-2021 Free Software Foundation, Inc. ## Author: Glenn Morris ## Maintainer: emacs-devel@gnu.org diff --git a/admin/upload-manuals b/admin/upload-manuals index b7187971df..52999c2997 100755 --- a/admin/upload-manuals +++ b/admin/upload-manuals @@ -2,7 +2,7 @@ ### upload-manuals - upload the Emacs manuals to the gnu.org website -## Copyright 2018-2020 Free Software Foundation, Inc. +## Copyright 2018-2021 Free Software Foundation, Inc. ## Author: Glenn Morris ## Maintainer: emacs-devel@gnu.org diff --git a/autogen.sh b/autogen.sh index c5e14900d6..531e5775f9 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,7 +1,7 @@ #!/bin/sh ### autogen.sh - tool to help build Emacs from a repository checkout -## Copyright (C) 2011-2020 Free Software Foundation, Inc. +## Copyright (C) 2011-2021 Free Software Foundation, Inc. ## Author: Glenn Morris ## Maintainer: emacs-devel@gnu.org diff --git a/build-aux/config.guess b/build-aux/config.guess index 7f74817797..35dd8a1a3e 100755 --- a/build-aux/config.guess +++ b/build-aux/config.guess @@ -1,6 +1,6 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2020 Free Software Foundation, Inc. +# Copyright 1992-2021 Free Software Foundation, Inc. timestamp='2020-12-22' diff --git a/build-aux/config.sub b/build-aux/config.sub index 90bb8aeda6..1208219189 100755 --- a/build-aux/config.sub +++ b/build-aux/config.sub @@ -1,6 +1,6 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2020 Free Software Foundation, Inc. +# Copyright 1992-2021 Free Software Foundation, Inc. timestamp='2020-12-22' diff --git a/build-aux/git-hooks/commit-msg b/build-aux/git-hooks/commit-msg index e84be4cbaf..cf0f74c644 100755 --- a/build-aux/git-hooks/commit-msg +++ b/build-aux/git-hooks/commit-msg @@ -1,7 +1,7 @@ #!/bin/sh # Check the format of GNU Emacs change log entries. -# Copyright 2014-2020 Free Software Foundation, Inc. +# Copyright 2014-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/build-aux/git-hooks/pre-commit b/build-aux/git-hooks/pre-commit index 59fdaf58c1..719bfefc50 100755 --- a/build-aux/git-hooks/pre-commit +++ b/build-aux/git-hooks/pre-commit @@ -1,7 +1,7 @@ #!/bin/sh # Check file names in git commits for GNU Emacs. -# Copyright 2014-2020 Free Software Foundation, Inc. +# Copyright 2014-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/build-aux/git-hooks/prepare-commit-msg b/build-aux/git-hooks/prepare-commit-msg index 06e328a1c3..dd8434479d 100755 --- a/build-aux/git-hooks/prepare-commit-msg +++ b/build-aux/git-hooks/prepare-commit-msg @@ -1,7 +1,7 @@ #!/bin/sh # Check the format of GNU Emacs change log entries. -# Copyright 2019-2020 Free Software Foundation, Inc. +# Copyright 2019-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/build-aux/gitlog-to-changelog b/build-aux/gitlog-to-changelog index be8082e7ff..de76f658d4 100755 --- a/build-aux/gitlog-to-changelog +++ b/build-aux/gitlog-to-changelog @@ -3,7 +3,7 @@ # Convert git log output to ChangeLog format. -# Copyright (C) 2008-2020 Free Software Foundation, Inc. +# Copyright (C) 2008-2021 Free Software Foundation, Inc. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/build-aux/gitlog-to-emacslog b/build-aux/gitlog-to-emacslog index 23702807ef..30b2d78659 100755 --- a/build-aux/gitlog-to-emacslog +++ b/build-aux/gitlog-to-emacslog @@ -2,7 +2,7 @@ # Convert git log output to ChangeLog format for GNU Emacs. -# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# Copyright (C) 2014-2021 Free Software Foundation, Inc. # Author: Paul Eggert diff --git a/build-aux/make-info-dir b/build-aux/make-info-dir index ee2197beb3..ea26479cd9 100755 --- a/build-aux/make-info-dir +++ b/build-aux/make-info-dir @@ -2,7 +2,7 @@ ### make-info-dir - create info/dir, for systems without install-info -## Copyright (C) 2013-2020 Free Software Foundation, Inc. +## Copyright (C) 2013-2021 Free Software Foundation, Inc. ## Author: Glenn Morris ## Maintainer: emacs-devel@gnu.org diff --git a/build-aux/move-if-change b/build-aux/move-if-change index 653dc98159..e85e90af50 100755 --- a/build-aux/move-if-change +++ b/build-aux/move-if-change @@ -8,7 +8,7 @@ VERSION='2018-03-07 03:47'; # UTC # If you change this file with Emacs, please let the write hook # do its job. Otherwise, update this string manually. -# Copyright (C) 2002-2020 Free Software Foundation, Inc. +# Copyright (C) 2002-2021 Free Software Foundation, Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/build-aux/msys-to-w32 b/build-aux/msys-to-w32 index 4e0b2aaeba..e4e5e08641 100755 --- a/build-aux/msys-to-w32 +++ b/build-aux/msys-to-w32 @@ -2,7 +2,7 @@ # Convert a MSYS path list to Windows-native format. # Status is zero if successful, nonzero otherwise. -# Copyright (C) 2013-2020 Free Software Foundation, Inc. +# Copyright (C) 2013-2021 Free Software Foundation, Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/build-aux/update-copyright b/build-aux/update-copyright index d9b7f683a0..fae3a5fb33 100755 --- a/build-aux/update-copyright +++ b/build-aux/update-copyright @@ -3,7 +3,7 @@ # Update an FSF copyright year list to include the current year. -# Copyright (C) 2009-2020 Free Software Foundation, Inc. +# Copyright (C) 2009-2021 Free Software Foundation, Inc. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/build-aux/update-subdirs b/build-aux/update-subdirs index c0ecb84810..e56eea44de 100755 --- a/build-aux/update-subdirs +++ b/build-aux/update-subdirs @@ -1,7 +1,7 @@ #!/bin/sh # Write into $1/subdirs.el a list of subdirs of directory $1. -# Copyright (C) 1994-1995, 1997, 1999, 2001-2020 Free Software +# Copyright (C) 1994-1995, 1997, 1999, 2001-2021 Free Software # Foundation, Inc. # This file is part of GNU Emacs. diff --git a/configure.ac b/configure.ac index bf768441fe..0505a63b6a 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ dnl autoconf dnl in the directory containing this script. dnl If you changed any AC_DEFINES, also run autoheader. dnl -dnl Copyright (C) 1994-1996, 1999-2020 Free Software Foundation, Inc. +dnl Copyright (C) 1994-1996, 1999-2021 Free Software Foundation, Inc. dnl dnl This file is part of GNU Emacs. dnl diff --git a/doc/emacs/ChangeLog.1 b/doc/emacs/ChangeLog.1 index cf641beec1..bc4dbd4705 100644 --- a/doc/emacs/ChangeLog.1 +++ b/doc/emacs/ChangeLog.1 @@ -10919,7 +10919,7 @@ ;; coding: utf-8 ;; End: - Copyright (C) 1993-1999, 2001-2020 Free Software Foundation, Inc. + Copyright (C) 1993-1999, 2001-2021 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/doc/emacs/Makefile.in b/doc/emacs/Makefile.in index 53b7d07451..2a3f53f740 100644 --- a/doc/emacs/Makefile.in +++ b/doc/emacs/Makefile.in @@ -1,6 +1,6 @@ ### @configure_input@ -# Copyright (C) 1994, 1996-2020 Free Software Foundation, Inc. +# Copyright (C) 1994, 1996-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/doc/emacs/abbrevs.texi b/doc/emacs/abbrevs.texi index e3766aae9e..c83da8aaec 100644 --- a/doc/emacs/abbrevs.texi +++ b/doc/emacs/abbrevs.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Abbrevs diff --git a/doc/emacs/ack.texi b/doc/emacs/ack.texi index 4658cd4723..d771393ffa 100644 --- a/doc/emacs/ack.texi +++ b/doc/emacs/ack.texi @@ -1,6 +1,6 @@ @c -*- coding: utf-8 -*- @c This is part of the Emacs manual. -@c Copyright (C) 1994--1997, 1999--2020 Free Software Foundation, Inc. +@c Copyright (C) 1994--1997, 1999--2021 Free Software Foundation, Inc. @c See file emacs.texi for copying conditions. @c @node Acknowledgments diff --git a/doc/emacs/anti.texi b/doc/emacs/anti.texi index d1e67e6656..49da473fa5 100644 --- a/doc/emacs/anti.texi +++ b/doc/emacs/anti.texi @@ -1,6 +1,6 @@ @c -*- coding: utf-8 -*- @c This is part of the Emacs manual. -@c Copyright (C) 2005--2020 Free Software Foundation, Inc. +@c Copyright (C) 2005--2021 Free Software Foundation, Inc. @c See file emacs.texi for copying conditions. @node Antinews diff --git a/doc/emacs/arevert-xtra.texi b/doc/emacs/arevert-xtra.texi index ef42fb2a7c..5dede6246c 100644 --- a/doc/emacs/arevert-xtra.texi +++ b/doc/emacs/arevert-xtra.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 2004--2020 Free Software Foundation, Inc. +@c Copyright (C) 2004--2021 Free Software Foundation, Inc. @c See file emacs.texi for copying conditions. @c @c This file is included either in emacs-xtra.texi (when producing the diff --git a/doc/emacs/basic.texi b/doc/emacs/basic.texi index 77c8054746..444b28f24b 100644 --- a/doc/emacs/basic.texi +++ b/doc/emacs/basic.texi @@ -1,6 +1,6 @@ @c -*- coding: utf-8 -*- @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Basic diff --git a/doc/emacs/buffers.texi b/doc/emacs/buffers.texi index 537c653608..9cdfa493ed 100644 --- a/doc/emacs/buffers.texi +++ b/doc/emacs/buffers.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Buffers diff --git a/doc/emacs/building.texi b/doc/emacs/building.texi index 91c749aa2d..7194eb90ca 100644 --- a/doc/emacs/building.texi +++ b/doc/emacs/building.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Building diff --git a/doc/emacs/cal-xtra.texi b/doc/emacs/cal-xtra.texi index 3f1198987d..aec2e6cc5a 100644 --- a/doc/emacs/cal-xtra.texi +++ b/doc/emacs/cal-xtra.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -*- coding: utf-8 -*- -@c Copyright (C) 2004--2020 Free Software Foundation, Inc. +@c Copyright (C) 2004--2021 Free Software Foundation, Inc. @c See file emacs.texi for copying conditions. @c @c This file is included either in emacs-xtra.texi (when producing the diff --git a/doc/emacs/calendar.texi b/doc/emacs/calendar.texi index e5ee7e94bc..3750e78e70 100644 --- a/doc/emacs/calendar.texi +++ b/doc/emacs/calendar.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -*- coding: utf-8 -*- -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Calendar/Diary diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi index a828eee076..b7f0bda785 100644 --- a/doc/emacs/cmdargs.texi +++ b/doc/emacs/cmdargs.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Emacs Invocation diff --git a/doc/emacs/commands.texi b/doc/emacs/commands.texi index ad0cbc6f65..82a917ce7d 100644 --- a/doc/emacs/commands.texi +++ b/doc/emacs/commands.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @iftex diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi index fb60caa773..ccf5f1932f 100644 --- a/doc/emacs/custom.texi +++ b/doc/emacs/custom.texi @@ -1,6 +1,6 @@ @c -*- coding: utf-8 -*- @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Customization diff --git a/doc/emacs/dired-xtra.texi b/doc/emacs/dired-xtra.texi index 25cffe4916..fc8130d8e6 100644 --- a/doc/emacs/dired-xtra.texi +++ b/doc/emacs/dired-xtra.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 2004--2020 Free Software Foundation, Inc. +@c Copyright (C) 2004--2021 Free Software Foundation, Inc. @c See file emacs.texi for copying conditions. @c @c This file is included either in emacs-xtra.texi (when producing the diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi index fdc4703e86..34d12acc34 100644 --- a/doc/emacs/dired.texi +++ b/doc/emacs/dired.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Dired diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi index 7dadb0966f..f4b1854142 100644 --- a/doc/emacs/display.texi +++ b/doc/emacs/display.texi @@ -1,6 +1,6 @@ @c -*- coding: utf-8 -*- @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. diff --git a/doc/emacs/emacs-xtra.texi b/doc/emacs/emacs-xtra.texi index 544b808c7d..2d511bffbc 100644 --- a/doc/emacs/emacs-xtra.texi +++ b/doc/emacs/emacs-xtra.texi @@ -16,7 +16,7 @@ @copying This manual describes specialized features of Emacs. -Copyright @copyright{} 2004--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2004--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi index bd40e10052..4054b094de 100644 --- a/doc/emacs/emacs.texi +++ b/doc/emacs/emacs.texi @@ -20,7 +20,7 @@ This is the @cite{GNU Emacs Manual}, @end ifclear updated for Emacs version @value{EMACSVER}. -Copyright @copyright{} 1985--1987, 1993--2020 Free Software Foundation, +Copyright @copyright{} 1985--1987, 1993--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/emacs/emerge-xtra.texi b/doc/emacs/emerge-xtra.texi index d5759650c2..7bf24151e5 100644 --- a/doc/emacs/emerge-xtra.texi +++ b/doc/emacs/emerge-xtra.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 2004--2020 Free Software Foundation, Inc. +@c Copyright (C) 2004--2021 Free Software Foundation, Inc. @c See file emacs.texi for copying conditions. @c @c This file is included either in emacs-xtra.texi (when producing the diff --git a/doc/emacs/entering.texi b/doc/emacs/entering.texi index 4cd5c65df5..0476466da5 100644 --- a/doc/emacs/entering.texi +++ b/doc/emacs/entering.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 2001--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 2001--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @iftex diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index eb4353b678..ede382c146 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 1999--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 1999--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Files diff --git a/doc/emacs/fixit.texi b/doc/emacs/fixit.texi index db77ae4ec2..6b41849ccc 100644 --- a/doc/emacs/fixit.texi +++ b/doc/emacs/fixit.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Fixit diff --git a/doc/emacs/fortran-xtra.texi b/doc/emacs/fortran-xtra.texi index 11222e532e..c8efd56c37 100644 --- a/doc/emacs/fortran-xtra.texi +++ b/doc/emacs/fortran-xtra.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 2004--2020 Free Software Foundation, Inc. +@c Copyright (C) 2004--2021 Free Software Foundation, Inc. @c See file emacs.texi for copying conditions. @c @c This file is included either in emacs-xtra.texi (when producing the diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi index f5e2e8d172..e1a4e64a7d 100644 --- a/doc/emacs/frames.texi +++ b/doc/emacs/frames.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 1999--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 1999--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Frames diff --git a/doc/emacs/glossary.texi b/doc/emacs/glossary.texi index 4d622ec0e3..35df06591e 100644 --- a/doc/emacs/glossary.texi +++ b/doc/emacs/glossary.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Glossary diff --git a/doc/emacs/gnu.texi b/doc/emacs/gnu.texi index 0028b484c9..4d48dcdb8e 100644 --- a/doc/emacs/gnu.texi +++ b/doc/emacs/gnu.texi @@ -1,4 +1,4 @@ -@c Copyright (C) 1985--1987, 1993, 1995, 2001--2020 Free Software +@c Copyright (C) 1985--1987, 1993, 1995, 2001--2021 Free Software @c Foundation, Inc. @c @c Permission is granted to anyone to make or distribute verbatim copies diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi index c5b59e5492..81cdeb4be5 100644 --- a/doc/emacs/help.texi +++ b/doc/emacs/help.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Help diff --git a/doc/emacs/indent.texi b/doc/emacs/indent.texi index e8b4650633..df9e67fee6 100644 --- a/doc/emacs/indent.texi +++ b/doc/emacs/indent.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Indentation diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi index 0bd18fd0d7..9bc786dc47 100644 --- a/doc/emacs/killing.texi +++ b/doc/emacs/killing.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. diff --git a/doc/emacs/kmacro.texi b/doc/emacs/kmacro.texi index 7b1d365ff0..adb2ab8d56 100644 --- a/doc/emacs/kmacro.texi +++ b/doc/emacs/kmacro.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Keyboard Macros diff --git a/doc/emacs/m-x.texi b/doc/emacs/m-x.texi index b18c334acf..865220fb21 100644 --- a/doc/emacs/m-x.texi +++ b/doc/emacs/m-x.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node M-x diff --git a/doc/emacs/macos.texi b/doc/emacs/macos.texi index 00daa8b35d..cd1db1a7ba 100644 --- a/doc/emacs/macos.texi +++ b/doc/emacs/macos.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 2000--2020 Free Software Foundation, Inc. +@c Copyright (C) 2000--2021 Free Software Foundation, Inc. @c See file emacs.texi for copying conditions. @node Mac OS / GNUstep @appendix Emacs and macOS / GNUstep diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index aa4513e317..415815473e 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual., Abbrevs, This is part of the Emacs manual., Top -@c Copyright (C) 1985--1987, 1993--1995, 1997, 1999--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 1999--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Maintaining diff --git a/doc/emacs/mark.texi b/doc/emacs/mark.texi index 97aeed896a..20cb8ee2c6 100644 --- a/doc/emacs/mark.texi +++ b/doc/emacs/mark.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Mark diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi index ede95a28d4..c7c8fb30ac 100644 --- a/doc/emacs/mini.texi +++ b/doc/emacs/mini.texi @@ -1,6 +1,6 @@ @c -*- coding: utf-8 -*- @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Minibuffer diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index 54fafae565..fbb8122a1b 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @iftex diff --git a/doc/emacs/modes.texi b/doc/emacs/modes.texi index c9c175d51e..cc25d3e1e3 100644 --- a/doc/emacs/modes.texi +++ b/doc/emacs/modes.texi @@ -1,6 +1,6 @@ @c -*- coding: utf-8 -*- @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Modes diff --git a/doc/emacs/msdos-xtra.texi b/doc/emacs/msdos-xtra.texi index 045ac6c460..fce6ae46f8 100644 --- a/doc/emacs/msdos-xtra.texi +++ b/doc/emacs/msdos-xtra.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 2004--2020 Free Software Foundation, Inc. +@c Copyright (C) 2004--2021 Free Software Foundation, Inc. @c See file emacs.texi for copying conditions. @c @c This file is included either in emacs-xtra.texi (when producing the diff --git a/doc/emacs/msdos.texi b/doc/emacs/msdos.texi index 48492ab2f2..4b58f6aa2f 100644 --- a/doc/emacs/msdos.texi +++ b/doc/emacs/msdos.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Microsoft Windows diff --git a/doc/emacs/mule.texi b/doc/emacs/mule.texi index bf7088d8db..922eec7426 100644 --- a/doc/emacs/mule.texi +++ b/doc/emacs/mule.texi @@ -1,6 +1,6 @@ @c -*- coding: utf-8 -*- @c This is part of the Emacs manual. -@c Copyright (C) 1997, 1999--2020 Free Software Foundation, Inc. +@c Copyright (C) 1997, 1999--2021 Free Software Foundation, Inc. @c See file emacs.texi for copying conditions. @node International @chapter International Character Set Support diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi index 4981dd50c7..038a31a35b 100644 --- a/doc/emacs/package.texi +++ b/doc/emacs/package.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Packages diff --git a/doc/emacs/picture-xtra.texi b/doc/emacs/picture-xtra.texi index 9decda30da..a04b72d38d 100644 --- a/doc/emacs/picture-xtra.texi +++ b/doc/emacs/picture-xtra.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 2004--2020 Free Software Foundation, Inc. +@c Copyright (C) 2004--2021 Free Software Foundation, Inc. @c See file emacs.texi for copying conditions. @c @c This file is included either in emacs-xtra.texi (when producing the diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi index f0dd62dad4..fe3ee57ac0 100644 --- a/doc/emacs/programs.texi +++ b/doc/emacs/programs.texi @@ -1,6 +1,6 @@ @c -*- coding: utf-8 -*- @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 1999--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 1999--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Programs diff --git a/doc/emacs/regs.texi b/doc/emacs/regs.texi index d1b9ea8f67..59fa0ff0a1 100644 --- a/doc/emacs/regs.texi +++ b/doc/emacs/regs.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Registers diff --git a/doc/emacs/rmail.texi b/doc/emacs/rmail.texi index 0c47812449..e7ca2ae48b 100644 --- a/doc/emacs/rmail.texi +++ b/doc/emacs/rmail.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Rmail diff --git a/doc/emacs/screen.texi b/doc/emacs/screen.texi index 5c5a5da551..2ff808e040 100644 --- a/doc/emacs/screen.texi +++ b/doc/emacs/screen.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Screen diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi index 77a4e8097e..637867b811 100644 --- a/doc/emacs/search.texi +++ b/doc/emacs/search.texi @@ -1,6 +1,6 @@ @c -*- coding: utf-8 -*- @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Search diff --git a/doc/emacs/sending.texi b/doc/emacs/sending.texi index e3f9fbec07..174e52ac9a 100644 --- a/doc/emacs/sending.texi +++ b/doc/emacs/sending.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Sending Mail diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi index c77dcf7fbc..54e16698a7 100644 --- a/doc/emacs/text.texi +++ b/doc/emacs/text.texi @@ -1,6 +1,6 @@ @c -*- coding: utf-8 -*- @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Text diff --git a/doc/emacs/trouble.texi b/doc/emacs/trouble.texi index dbd1a07557..4da3d4a3e8 100644 --- a/doc/emacs/trouble.texi +++ b/doc/emacs/trouble.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @iftex diff --git a/doc/emacs/vc-xtra.texi b/doc/emacs/vc-xtra.texi index 37804242ea..51b9d66778 100644 --- a/doc/emacs/vc-xtra.texi +++ b/doc/emacs/vc-xtra.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 2004--2020 Free Software Foundation, Inc. +@c Copyright (C) 2004--2021 Free Software Foundation, Inc. @c See file emacs.texi for copying conditions. @c @c This file is included in emacs-xtra.texi when producing the printed diff --git a/doc/emacs/vc1-xtra.texi b/doc/emacs/vc1-xtra.texi index 26199924d5..4cd00cba6c 100644 --- a/doc/emacs/vc1-xtra.texi +++ b/doc/emacs/vc1-xtra.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 2004--2020 Free Software Foundation, Inc. +@c Copyright (C) 2004--2021 Free Software Foundation, Inc. @c See file emacs.texi for copying conditions. @c @c This file is included either in vc-xtra.texi (when producing the diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi index 07f826933d..e851f1b1b5 100644 --- a/doc/emacs/windows.texi +++ b/doc/emacs/windows.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2020 Free Software +@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node Windows diff --git a/doc/emacs/xresources.texi b/doc/emacs/xresources.texi index 730cf304e2..00fa6c0aa3 100644 --- a/doc/emacs/xresources.texi +++ b/doc/emacs/xresources.texi @@ -1,5 +1,5 @@ @c This is part of the Emacs manual. -@c Copyright (C) 1987, 1993--1995, 1997, 2001--2020 Free Software +@c Copyright (C) 1987, 1993--1995, 1997, 2001--2021 Free Software @c Foundation, Inc. @c See file emacs.texi for copying conditions. @node X Resources diff --git a/doc/lispintro/ChangeLog.1 b/doc/lispintro/ChangeLog.1 index 75f5872dc3..bb4323a773 100644 --- a/doc/lispintro/ChangeLog.1 +++ b/doc/lispintro/ChangeLog.1 @@ -782,7 +782,7 @@ ;; coding: utf-8 ;; End: - Copyright (C) 2001-2020 Free Software Foundation, Inc. + Copyright (C) 2001-2021 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/doc/lispintro/Makefile.in b/doc/lispintro/Makefile.in index 7a2b6f0a58..d8b909c9c1 100644 --- a/doc/lispintro/Makefile.in +++ b/doc/lispintro/Makefile.in @@ -1,6 +1,6 @@ ### @configure_input@ -# Copyright (C) 1994-1999, 2001-2020 Free Software Foundation, Inc. +# Copyright (C) 1994-1999, 2001-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/doc/lispintro/README b/doc/lispintro/README index 6361f5a65c..eca19c76a4 100644 --- a/doc/lispintro/README +++ b/doc/lispintro/README @@ -1,4 +1,4 @@ -Copyright (C) 2001-2020 Free Software Foundation, Inc. +Copyright (C) 2001-2021 Free Software Foundation, Inc. See the end of the file for license conditions. diff --git a/doc/lispintro/cons-1.eps b/doc/lispintro/cons-1.eps index c5d414c758..4877df7135 100644 --- a/doc/lispintro/cons-1.eps +++ b/doc/lispintro/cons-1.eps @@ -4,7 +4,7 @@ %%CreationDate: Wed Mar 8 14:26:58 1995 %%Creator: Tgif-2.16-p4 by William Chia-Wei Cheng (william@cs.UCLA.edu) -% Copyright (C) 1995, 1997, 2001-2020 Free Software Foundation, Inc. +% Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. % % This file is part of GNU Emacs. % diff --git a/doc/lispintro/cons-2.eps b/doc/lispintro/cons-2.eps index f6d97c7cc0..48fdc7e876 100644 --- a/doc/lispintro/cons-2.eps +++ b/doc/lispintro/cons-2.eps @@ -4,7 +4,7 @@ %%CreationDate: Wed Mar 8 14:26:39 1995 %%Creator: Tgif-2.16-p4 by William Chia-Wei Cheng (william@cs.UCLA.edu) -% Copyright (C) 1995, 1997, 2001-2020 Free Software Foundation, Inc. +% Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. % % This file is part of GNU Emacs. % diff --git a/doc/lispintro/cons-2a.eps b/doc/lispintro/cons-2a.eps index 57b96eba16..81053d3f26 100644 --- a/doc/lispintro/cons-2a.eps +++ b/doc/lispintro/cons-2a.eps @@ -4,7 +4,7 @@ %%CreationDate: Tue Mar 14 15:09:30 1995 %%Creator: Tgif-2.16-p4 by William Chia-Wei Cheng (william@cs.UCLA.edu) -% Copyright (C) 1995, 1997, 2001-2020 Free Software Foundation, Inc. +% Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. % % This file is part of GNU Emacs. % diff --git a/doc/lispintro/cons-3.eps b/doc/lispintro/cons-3.eps index e51c2c4008..e6a80f1c8b 100644 --- a/doc/lispintro/cons-3.eps +++ b/doc/lispintro/cons-3.eps @@ -4,7 +4,7 @@ %%CreationDate: Wed Mar 8 14:25:41 1995 %%Creator: Tgif-2.16-p4 by William Chia-Wei Cheng (william@cs.UCLA.edu) -% Copyright (C) 1995, 1997, 2001-2020 Free Software Foundation, Inc. +% Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. % % This file is part of GNU Emacs. % diff --git a/doc/lispintro/cons-4.eps b/doc/lispintro/cons-4.eps index 1cbf44fab0..c1aac9c09b 100644 --- a/doc/lispintro/cons-4.eps +++ b/doc/lispintro/cons-4.eps @@ -4,7 +4,7 @@ %%CreationDate: Wed Mar 8 14:25:06 1995 %%Creator: Tgif-2.16-p4 by William Chia-Wei Cheng (william@cs.UCLA.edu) -% Copyright (C) 1995, 1997, 2001-2020 Free Software Foundation, Inc. +% Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. % % This file is part of GNU Emacs. % diff --git a/doc/lispintro/cons-5.eps b/doc/lispintro/cons-5.eps index 85a553bcbc..a0918a92c5 100644 --- a/doc/lispintro/cons-5.eps +++ b/doc/lispintro/cons-5.eps @@ -4,7 +4,7 @@ %%CreationDate: Wed Mar 8 14:27:28 1995 %%Creator: Tgif-2.16-p4 by William Chia-Wei Cheng (william@cs.UCLA.edu) -% Copyright (C) 1995, 1997, 2001-2020 Free Software Foundation, Inc. +% Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. % % This file is part of GNU Emacs. % diff --git a/doc/lispintro/drawers.eps b/doc/lispintro/drawers.eps index b71bdb82ae..725bd9723c 100644 --- a/doc/lispintro/drawers.eps +++ b/doc/lispintro/drawers.eps @@ -9,7 +9,7 @@ %%EndComments %%BeginProlog -% Copyright (C) 2001-2020 Free Software Foundation, Inc. +% Copyright (C) 2001-2021 Free Software Foundation, Inc. % % This file is part of GNU Emacs. % diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index b13b16285c..d5c280b792 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -117,7 +117,7 @@ Edition @value{edition-number}, @value{update-date} @sp 1 Distributed with Emacs version @value{EMACSVER}. @sp 1 -Copyright @copyright{} 1990--1995, 1997, 2001--2020 Free Software +Copyright @copyright{} 1990--1995, 1997, 2001--2021 Free Software Foundation, Inc. @sp 1 diff --git a/doc/lispintro/lambda-1.eps b/doc/lispintro/lambda-1.eps index 08bd6007b7..43b2d08aed 100644 --- a/doc/lispintro/lambda-1.eps +++ b/doc/lispintro/lambda-1.eps @@ -4,7 +4,7 @@ %%CreationDate: Wed Mar 8 14:31:53 1995 %%Creator: Tgif-2.16-p4 by William Chia-Wei Cheng (william@cs.UCLA.edu) -% Copyright (C) 1995, 1997, 2001-2020 Free Software Foundation, Inc. +% Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. % % This file is part of GNU Emacs. % diff --git a/doc/lispintro/lambda-2.eps b/doc/lispintro/lambda-2.eps index 6ccf9993e3..c6c71f2b77 100644 --- a/doc/lispintro/lambda-2.eps +++ b/doc/lispintro/lambda-2.eps @@ -4,7 +4,7 @@ %%CreationDate: Wed Mar 8 14:33:09 1995 %%Creator: Tgif-2.16-p4 by William Chia-Wei Cheng (william@cs.UCLA.edu) -% Copyright (C) 1995, 1997, 2001-2020 Free Software Foundation, Inc. +% Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. % % This file is part of GNU Emacs. % diff --git a/doc/lispintro/lambda-3.eps b/doc/lispintro/lambda-3.eps index aac0392c4b..ae939d537f 100644 --- a/doc/lispintro/lambda-3.eps +++ b/doc/lispintro/lambda-3.eps @@ -4,7 +4,7 @@ %%CreationDate: Wed Mar 8 14:33:49 1995 %%Creator: Tgif-2.16-p4 by William Chia-Wei Cheng (william@cs.UCLA.edu) -% Copyright (C) 1995, 1997, 2001-2020 Free Software Foundation, Inc. +% Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. % % This file is part of GNU Emacs. % diff --git a/doc/lispref/ChangeLog.1 b/doc/lispref/ChangeLog.1 index 8d92a943d5..bd7a9c4e79 100644 --- a/doc/lispref/ChangeLog.1 +++ b/doc/lispref/ChangeLog.1 @@ -13989,7 +13989,7 @@ ;; coding: utf-8 ;; End: - Copyright (C) 1998-2020 Free Software Foundation, Inc. + Copyright (C) 1998-2021 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/doc/lispref/Makefile.in b/doc/lispref/Makefile.in index bd65009111..271f06eddd 100644 --- a/doc/lispref/Makefile.in +++ b/doc/lispref/Makefile.in @@ -1,6 +1,6 @@ ### @configure_input@ -# Copyright (C) 1990-1996, 1998-2020 Free Software Foundation, Inc. +# Copyright (C) 1990-1996, 1998-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/doc/lispref/README b/doc/lispref/README index ac0c2b554e..9b99837130 100644 --- a/doc/lispref/README +++ b/doc/lispref/README @@ -1,4 +1,4 @@ -Copyright (C) 2001-2020 Free Software Foundation, Inc. -*- outline -*- +Copyright (C) 2001-2021 Free Software Foundation, Inc. -*- outline -*- See the end of the file for license conditions. diff --git a/doc/lispref/abbrevs.texi b/doc/lispref/abbrevs.texi index 575be187d3..71fac1ae3b 100644 --- a/doc/lispref/abbrevs.texi +++ b/doc/lispref/abbrevs.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1994, 1999, 2001--2020 Free Software Foundation, +@c Copyright (C) 1990--1994, 1999, 2001--2021 Free Software Foundation, @c Inc. @c See the file elisp.texi for copying conditions. @node Abbrevs diff --git a/doc/lispref/anti.texi b/doc/lispref/anti.texi index a134e88358..ced8082f6a 100644 --- a/doc/lispref/anti.texi +++ b/doc/lispref/anti.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1999, 2002--2020 Free Software Foundation, Inc. +@c Copyright (C) 1999, 2002--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @c This node must have no pointers. diff --git a/doc/lispref/back.texi b/doc/lispref/back.texi index 817249ee01..c238863833 100644 --- a/doc/lispref/back.texi +++ b/doc/lispref/back.texi @@ -1,6 +1,6 @@ \input texinfo @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 2001--2020 Free Software Foundation, Inc. +@c Copyright (C) 2001--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @c @c %**start of header diff --git a/doc/lispref/backups.texi b/doc/lispref/backups.texi index c20ef6830a..c0a4065bdb 100644 --- a/doc/lispref/backups.texi +++ b/doc/lispref/backups.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1999, 2001--2020 Free Software Foundation, +@c Copyright (C) 1990--1995, 1999, 2001--2021 Free Software Foundation, @c Inc. @c See the file elisp.texi for copying conditions. @node Backups and Auto-Saving diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi index 33eb23984d..69733f91c4 100644 --- a/doc/lispref/buffers.texi +++ b/doc/lispref/buffers.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Buffers diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 15d7e4e3a7..6c68f70482 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Command Loop diff --git a/doc/lispref/compile.texi b/doc/lispref/compile.texi index 51a4b04486..6624234315 100644 --- a/doc/lispref/compile.texi +++ b/doc/lispref/compile.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1994, 2001--2020 Free Software Foundation, Inc. +@c Copyright (C) 1990--1994, 2001--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Byte Compilation @chapter Byte Compilation diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index d2419f415b..55bcddb31a 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -1,6 +1,6 @@ @c -*- mode: texinfo; coding: utf-8 -*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Control Structures diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi index 8591247079..8fd12f7902 100644 --- a/doc/lispref/customize.texi +++ b/doc/lispref/customize.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1997--2020 Free Software Foundation, Inc. +@c Copyright (C) 1997--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Customization @chapter Customization Settings diff --git a/doc/lispref/debugging.texi b/doc/lispref/debugging.texi index 661961f937..1e779ac705 100644 --- a/doc/lispref/debugging.texi +++ b/doc/lispref/debugging.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1994, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1994, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Debugging diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 949fd8987c..b149a665fe 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -1,6 +1,6 @@ @c -*- mode: texinfo; coding: utf-8 -*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--2020 Free Software Foundation, Inc. +@c Copyright (C) 1990--1995, 1998--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Display @chapter Emacs Display diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi index b4c631b449..569545d83f 100644 --- a/doc/lispref/edebug.texi +++ b/doc/lispref/edebug.texi @@ -1,6 +1,6 @@ @comment -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1992--1994, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1992--1994, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi index 9a6796790c..fa548b503a 100644 --- a/doc/lispref/elisp.texi +++ b/doc/lispref/elisp.texi @@ -99,7 +99,7 @@ This is the @cite{GNU Emacs Lisp Reference Manual} @end ifclear corresponding to Emacs version @value{EMACSVER}. -Copyright @copyright{} 1990--1996, 1998--2020 Free Software Foundation, +Copyright @copyright{} 1990--1996, 1998--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/lispref/errors.texi b/doc/lispref/errors.texi index a386a41bd3..9ec1271499 100644 --- a/doc/lispref/errors.texi +++ b/doc/lispref/errors.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1993, 1999, 2001--2020 Free Software Foundation, +@c Copyright (C) 1990--1993, 1999, 2001--2021 Free Software Foundation, @c Inc. @c See the file elisp.texi for copying conditions. @node Standard Errors diff --git a/doc/lispref/eval.texi b/doc/lispref/eval.texi index 39f342a798..80e038c96d 100644 --- a/doc/lispref/eval.texi +++ b/doc/lispref/eval.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1994, 1998, 2001--2020 Free Software Foundation, +@c Copyright (C) 1990--1994, 1998, 2001--2021 Free Software Foundation, @c Inc. @c See the file elisp.texi for copying conditions. @node Evaluation diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index 6949ca29c6..4110c51099 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Files diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index e3d0fdeb27..7f2a6f7542 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Frames diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index 222a17fad4..414035f684 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi @@ -1,6 +1,6 @@ @c -*- mode: texinfo; coding: utf-8 -*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Functions diff --git a/doc/lispref/hash.texi b/doc/lispref/hash.texi index 12781c6cb9..8781fad30c 100644 --- a/doc/lispref/hash.texi +++ b/doc/lispref/hash.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1999, 2001--2020 Free Software Foundation, Inc. +@c Copyright (C) 1999, 2001--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Hash Tables @chapter Hash Tables diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi index 90406df9c1..2fd05b7391 100644 --- a/doc/lispref/help.texi +++ b/doc/lispref/help.texi @@ -1,6 +1,6 @@ @c -*- mode: texinfo; coding: utf-8 -*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Documentation diff --git a/doc/lispref/hooks.texi b/doc/lispref/hooks.texi index a8b4d5619d..b1c7e61371 100644 --- a/doc/lispref/hooks.texi +++ b/doc/lispref/hooks.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1993, 1998, 2001--2020 Free Software Foundation, +@c Copyright (C) 1990--1993, 1998, 2001--2021 Free Software Foundation, @c Inc. @c See the file elisp.texi for copying conditions. @node Standard Hooks diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi index 0adbef33ca..4150a2b21b 100644 --- a/doc/lispref/internals.texi +++ b/doc/lispref/internals.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1993, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1993, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node GNU Emacs Internals diff --git a/doc/lispref/intro.texi b/doc/lispref/intro.texi index a4b479597e..35f852b7e4 100644 --- a/doc/lispref/intro.texi +++ b/doc/lispref/intro.texi @@ -1,6 +1,6 @@ @c -*-coding: utf-8-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1994, 2001--2020 Free Software Foundation, Inc. +@c Copyright (C) 1990--1994, 2001--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Introduction diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi index 9daeb2c77f..37bab7ea9b 100644 --- a/doc/lispref/keymaps.texi +++ b/doc/lispref/keymaps.texi @@ -1,6 +1,6 @@ @c -*- mode: texinfo; coding: utf-8 -*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1994, 1998--2020 Free Software Foundation, Inc. +@c Copyright (C) 1990--1994, 1998--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Keymaps @chapter Keymaps diff --git a/doc/lispref/lay-flat.texi b/doc/lispref/lay-flat.texi index 3cca5189b1..4ea58e6172 100644 --- a/doc/lispref/lay-flat.texi +++ b/doc/lispref/lay-flat.texi @@ -1,6 +1,6 @@ \input texinfo @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 2001--2020 Free Software Foundation, Inc. +@c Copyright (C) 2001--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @c @comment %**start of header diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi index ae793d5e15..c54496f616 100644 --- a/doc/lispref/lists.texi +++ b/doc/lispref/lists.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Lists diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi index e5364152d5..22f0dde593 100644 --- a/doc/lispref/loading.texi +++ b/doc/lispref/loading.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Loading diff --git a/doc/lispref/macros.texi b/doc/lispref/macros.texi index eeb4152a5b..e56a85c747 100644 --- a/doc/lispref/macros.texi +++ b/doc/lispref/macros.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998, 2001--2020 Free Software Foundation, +@c Copyright (C) 1990--1995, 1998, 2001--2021 Free Software Foundation, @c Inc. @c See the file elisp.texi for copying conditions. @node Macros diff --git a/doc/lispref/maps.texi b/doc/lispref/maps.texi index 1e84f9b3bb..aea0242408 100644 --- a/doc/lispref/maps.texi +++ b/doc/lispref/maps.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1993, 1999, 2001--2020 Free Software Foundation, +@c Copyright (C) 1990--1993, 1999, 2001--2021 Free Software Foundation, @c Inc. @c See the file elisp.texi for copying conditions. @node Standard Keymaps diff --git a/doc/lispref/markers.texi b/doc/lispref/markers.texi index 686b87771f..cdd0938b45 100644 --- a/doc/lispref/markers.texi +++ b/doc/lispref/markers.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Markers diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index 48f068ee60..81139b9e74 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Minibuffers diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 5ac33691c9..9d38fe6af9 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Modes diff --git a/doc/lispref/nonascii.texi b/doc/lispref/nonascii.texi index 97bc85f152..84f5d2f081 100644 --- a/doc/lispref/nonascii.texi +++ b/doc/lispref/nonascii.texi @@ -1,6 +1,6 @@ @c -*- mode: texinfo; coding: utf-8 -*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1998--1999, 2001--2020 Free Software Foundation, Inc. +@c Copyright (C) 1998--1999, 2001--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Non-ASCII Characters @chapter Non-@acronym{ASCII} Characters diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi index 9a5bff5a5b..63e3e0bace 100644 --- a/doc/lispref/numbers.texi +++ b/doc/lispref/numbers.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Numbers diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi index 8306674412..64e7d53d93 100644 --- a/doc/lispref/objects.texi +++ b/doc/lispref/objects.texi @@ -1,6 +1,6 @@ @c -*- mode: texinfo; coding: utf-8 -*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Lisp Data Types diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index 85f930d189..37fde0a953 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node System Interface diff --git a/doc/lispref/package.texi b/doc/lispref/package.texi index af87479c7d..e8aaa3ae1d 100644 --- a/doc/lispref/package.texi +++ b/doc/lispref/package.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 2010--2020 Free Software Foundation, Inc. +@c Copyright (C) 2010--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Packaging @chapter Preparing Lisp code for distribution diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index 751adcff5a..dc0c7442d8 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi @@ -1,6 +1,6 @@ @c -*- mode: texinfo; coding: utf-8 -*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--2020 Free Software Foundation, Inc. +@c Copyright (C) 1990--1995, 1998--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Positions @chapter Positions diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 5fefab99d4..0f713bcae2 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Processes diff --git a/doc/lispref/records.texi b/doc/lispref/records.texi index f7a21a4b8c..573caf1672 100644 --- a/doc/lispref/records.texi +++ b/doc/lispref/records.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 2017--2020 Free Software Foundation, Inc. +@c Copyright (C) 2017--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Records @chapter Records diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi index 35a518805c..16a8e56e90 100644 --- a/doc/lispref/searching.texi +++ b/doc/lispref/searching.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Searching and Matching diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index 57b49847e7..0c74dbe2aa 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Sequences Arrays Vectors diff --git a/doc/lispref/streams.texi b/doc/lispref/streams.texi index 5b4be83250..535fc958f2 100644 --- a/doc/lispref/streams.texi +++ b/doc/lispref/streams.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1994, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1994, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Read and Print diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 4ac5057454..897b424b18 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -1,6 +1,6 @@ @c -*- mode: texinfo; coding: utf-8 -*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Strings and Characters diff --git a/doc/lispref/symbols.texi b/doc/lispref/symbols.texi index d6b0494d1a..ed36f5139a 100644 --- a/doc/lispref/symbols.texi +++ b/doc/lispref/symbols.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Symbols diff --git a/doc/lispref/syntax.texi b/doc/lispref/syntax.texi index b99b5de0b3..b4bd48771f 100644 --- a/doc/lispref/syntax.texi +++ b/doc/lispref/syntax.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Syntax Tables diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index b712768a21..0b567d82c6 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--2020 Free Software Foundation, Inc. +@c Copyright (C) 1990--1995, 1998--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Text @chapter Text diff --git a/doc/lispref/threads.texi b/doc/lispref/threads.texi index de19c0604c..a06bd3e801 100644 --- a/doc/lispref/threads.texi +++ b/doc/lispref/threads.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 2012--2020 Free Software Foundation, Inc. +@c Copyright (C) 2012--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Threads @chapter Threads diff --git a/doc/lispref/tips.texi b/doc/lispref/tips.texi index c9a43e0cde..715c440fbb 100644 --- a/doc/lispref/tips.texi +++ b/doc/lispref/tips.texi @@ -1,6 +1,6 @@ @c -*- mode: texinfo; coding: utf-8 -*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1993, 1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1993, 1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Tips diff --git a/doc/lispref/two-volume-cross-refs.txt b/doc/lispref/two-volume-cross-refs.txt index 63f5563464..ad13d98dd9 100644 --- a/doc/lispref/two-volume-cross-refs.txt +++ b/doc/lispref/two-volume-cross-refs.txt @@ -1,4 +1,4 @@ -Copyright (C) 2001-2020 Free Software Foundation, Inc. +Copyright (C) 2001-2021 Free Software Foundation, Inc. See end for copying conditions. Two Volume Cross References diff --git a/doc/lispref/two-volume.make b/doc/lispref/two-volume.make index 133c50be23..cf612b1257 100644 --- a/doc/lispref/two-volume.make +++ b/doc/lispref/two-volume.make @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2020 Free Software Foundation, Inc. +# Copyright (C) 2007-2021 Free Software Foundation, Inc. # See end for copying conditions. # although it would be nice to use tex rather than pdftex to avoid diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi index 9447e8d04c..63438170d1 100644 --- a/doc/lispref/variables.texi +++ b/doc/lispref/variables.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--2020 Free Software Foundation, Inc. +@c Copyright (C) 1990--1995, 1998--2021 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Variables @chapter Variables diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index db80b49507..b0906acbad 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990--1995, 1998--1999, 2001--2020 Free Software +@c Copyright (C) 1990--1995, 1998--1999, 2001--2021 Free Software @c Foundation, Inc. @c See the file elisp.texi for copying conditions. @node Windows diff --git a/doc/man/ChangeLog.1 b/doc/man/ChangeLog.1 index 5e23bb3e30..9ad144a457 100644 --- a/doc/man/ChangeLog.1 +++ b/doc/man/ChangeLog.1 @@ -176,7 +176,7 @@ ;; coding: utf-8 ;; End: - Copyright (C) 2007-2020 Free Software Foundation, Inc. + Copyright (C) 2007-2021 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/doc/man/ebrowse.1 b/doc/man/ebrowse.1 index 330c1ea523..7bb32b80d4 100644 --- a/doc/man/ebrowse.1 +++ b/doc/man/ebrowse.1 @@ -82,7 +82,7 @@ should give you access to the complete manual. was written by Gerd Moellmann. . .SH COPYING -Copyright 2008-2020 Free Software Foundation, Inc. +Copyright 2008-2021 Free Software Foundation, Inc. .PP Permission is granted to make and distribute verbatim copies of this document provided the copyright notice and this permission notice are diff --git a/doc/man/emacs.1.in b/doc/man/emacs.1.in index 3a5758e1aa..da912bd511 100644 --- a/doc/man/emacs.1.in +++ b/doc/man/emacs.1.in @@ -657,7 +657,7 @@ For detailed credits and acknowledgments, see the GNU Emacs manual. . . .SH COPYING -Copyright 1995, 1999-2020 Free Software Foundation, Inc. +Copyright 1995, 1999-2021 Free Software Foundation, Inc. .PP Permission is granted to make and distribute verbatim copies of this document provided the copyright notice and this permission notice are diff --git a/doc/man/etags.1 b/doc/man/etags.1 index 8053e863fc..c5c15fb182 100644 --- a/doc/man/etags.1 +++ b/doc/man/etags.1 @@ -281,7 +281,7 @@ Stallman. .BR vi ( 1 ). .SH COPYING -Copyright 1992, 1999, 2001-2020 Free Software Foundation, Inc. +Copyright 1992, 1999, 2001-2021 Free Software Foundation, Inc. .PP Permission is granted to make and distribute verbatim copies of this document provided the copyright notice and this permission notice are diff --git a/doc/misc/ChangeLog.1 b/doc/misc/ChangeLog.1 index f74e51f400..c050e5d4cb 100644 --- a/doc/misc/ChangeLog.1 +++ b/doc/misc/ChangeLog.1 @@ -12116,7 +12116,7 @@ ;; coding: utf-8 ;; End: - Copyright (C) 1993-1999, 2001-2020 Free Software Foundation, Inc. + Copyright (C) 1993-1999, 2001-2021 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in index f4fb7d2ee6..d627055ae1 100644 --- a/doc/misc/Makefile.in +++ b/doc/misc/Makefile.in @@ -1,6 +1,6 @@ ### @configure_input@ -# Copyright (C) 1994, 1996-2020 Free Software Foundation, Inc. +# Copyright (C) 1994, 1996-2021 Free Software Foundation, Inc. # This file is part of GNU Emacs. diff --git a/doc/misc/auth.texi b/doc/misc/auth.texi index f8fcb64290..d810f15c80 100644 --- a/doc/misc/auth.texi +++ b/doc/misc/auth.texi @@ -9,7 +9,7 @@ @copying This file describes the Emacs auth-source library. -Copyright @copyright{} 2008--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2008--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/autotype.texi b/doc/misc/autotype.texi index 7b7f8827a7..72ba73697d 100644 --- a/doc/misc/autotype.texi +++ b/doc/misc/autotype.texi @@ -11,7 +11,7 @@ @c @cindex autotypist @copying -Copyright @copyright{} 1994--1995, 1999, 2001--2020 Free Software +Copyright @copyright{} 1994--1995, 1999, 2001--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/misc/bovine.texi b/doc/misc/bovine.texi index 8ee985046d..780f0addb5 100644 --- a/doc/misc/bovine.texi +++ b/doc/misc/bovine.texi @@ -24,7 +24,7 @@ @c %**end of header @copying -Copyright @copyright{} 1999--2004, 2012--2020 Free Software Foundation, +Copyright @copyright{} 1999--2004, 2012--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/misc/calc.texi b/doc/misc/calc.texi index 1fa13e98b3..c4ccea3caf 100644 --- a/doc/misc/calc.texi +++ b/doc/misc/calc.texi @@ -95,7 +95,7 @@ This file documents Calc, the GNU Emacs calculator, included with GNU Emacs @value{EMACSVER}. @end ifnotinfo -Copyright @copyright{} 1990--1991, 2001--2020 Free Software Foundation, +Copyright @copyright{} 1990--1991, 2001--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/misc/cc-mode.texi b/doc/misc/cc-mode.texi index c0d0fc2457..24ab4b773c 100644 --- a/doc/misc/cc-mode.texi +++ b/doc/misc/cc-mode.texi @@ -167,7 +167,7 @@ CC Mode @copying This manual is for CC Mode in Emacs. -Copyright @copyright{} 1995--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1995--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi index 742be28fe3..7464ba2eb1 100644 --- a/doc/misc/cl.texi +++ b/doc/misc/cl.texi @@ -7,7 +7,7 @@ @copying This file documents the GNU Emacs Common Lisp emulation package. -Copyright @copyright{} 1993, 2001--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1993, 2001--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/dbus.texi b/doc/misc/dbus.texi index 5a1dd55248..e8e99db76b 100644 --- a/doc/misc/dbus.texi +++ b/doc/misc/dbus.texi @@ -10,7 +10,7 @@ @syncodeindex fn cp @copying -Copyright @copyright{} 2007--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2007--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/dired-x.texi b/doc/misc/dired-x.texi index 243b59b242..87a127c4f3 100644 --- a/doc/misc/dired-x.texi +++ b/doc/misc/dired-x.texi @@ -20,7 +20,7 @@ @comment %**end of header (This is for running Texinfo on a region.) @copying -Copyright @copyright{} 1994--1995, 1999, 2001--2020 Free Software +Copyright @copyright{} 1994--1995, 1999, 2001--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/misc/ebrowse.texi b/doc/misc/ebrowse.texi index 98c1a790bb..8962f7c8cf 100644 --- a/doc/misc/ebrowse.texi +++ b/doc/misc/ebrowse.texi @@ -11,7 +11,7 @@ @copying This file documents Ebrowse, a C++ class browser for GNU Emacs. -Copyright @copyright{} 2000--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2000--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/ede.texi b/doc/misc/ede.texi index 63e3595a50..a53f879c96 100644 --- a/doc/misc/ede.texi +++ b/doc/misc/ede.texi @@ -6,7 +6,7 @@ @copying This file describes EDE, the Emacs Development Environment. -Copyright @copyright{} 1998--2001, 2004--2005, 2008--2020 Free Software +Copyright @copyright{} 1998--2001, 2004--2005, 2008--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/misc/ediff.texi b/doc/misc/ediff.texi index 1ef13716b1..8162a84f61 100644 --- a/doc/misc/ediff.texi +++ b/doc/misc/ediff.texi @@ -26,7 +26,7 @@ This file documents Ediff, a comprehensive visual interface to Unix diff and patch utilities. -Copyright @copyright{} 1995--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1995--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/edt.texi b/doc/misc/edt.texi index b0200b4745..b4dabdb938 100644 --- a/doc/misc/edt.texi +++ b/doc/misc/edt.texi @@ -6,7 +6,7 @@ @copying This file documents the EDT emulation package for Emacs. -Copyright @copyright{} 1986, 1992, 1994--1995, 1999--2020 Free Software +Copyright @copyright{} 1986, 1992, 1994--1995, 1999--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/misc/efaq-w32.texi b/doc/misc/efaq-w32.texi index c875d58ef1..2abde2c284 100644 --- a/doc/misc/efaq-w32.texi +++ b/doc/misc/efaq-w32.texi @@ -15,7 +15,7 @@ Answers to Frequently asked Questions about using Emacs on Microsoft Windows. @include emacsver.texi @copying -Copyright @copyright{} 2008, 2010--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2008, 2010--2021 Free Software Foundation, Inc. @quotation This list of frequently asked questions about GNU Emacs on MS Windows diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi index c31de0ba9a..f26ae63778 100644 --- a/doc/misc/efaq.texi +++ b/doc/misc/efaq.texi @@ -12,7 +12,7 @@ @c appreciate a notice if you do). @copying -Copyright @copyright{} 2001--2020 Free Software Foundation, Inc.@* +Copyright @copyright{} 2001--2021 Free Software Foundation, Inc.@* Copyright @copyright{} 1994, 1995, 1996, 1997, 1998, 1999, 2000 Reuven M. Lerner@* Copyright @copyright{} 1992, 1993 Steven Byrnes@* diff --git a/doc/misc/eieio.texi b/doc/misc/eieio.texi index 8dd394cb84..4952e90990 100644 --- a/doc/misc/eieio.texi +++ b/doc/misc/eieio.texi @@ -12,7 +12,7 @@ @copying This manual documents EIEIO, an object framework for Emacs Lisp. -Copyright @copyright{} 2007--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2007--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/emacs-gnutls.texi b/doc/misc/emacs-gnutls.texi index bb13ebdf23..fbc4443c0a 100644 --- a/doc/misc/emacs-gnutls.texi +++ b/doc/misc/emacs-gnutls.texi @@ -9,7 +9,7 @@ @copying This file describes the Emacs GnuTLS integration. -Copyright @copyright{} 2012--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2012--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/emacs-mime.texi b/doc/misc/emacs-mime.texi index 316a1baf57..0cf5ba9650 100644 --- a/doc/misc/emacs-mime.texi +++ b/doc/misc/emacs-mime.texi @@ -10,7 +10,7 @@ @copying This file documents the Emacs MIME interface functionality. -Copyright @copyright{} 1998--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1998--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/epa.texi b/doc/misc/epa.texi index fa1833a3da..cca0d300fa 100644 --- a/doc/misc/epa.texi +++ b/doc/misc/epa.texi @@ -10,7 +10,7 @@ @copying This file describes EasyPG Assistant @value{VERSION}. -Copyright @copyright{} 2007--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2007--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/erc.texi b/doc/misc/erc.texi index c39d2f98dc..d635cac5ab 100644 --- a/doc/misc/erc.texi +++ b/doc/misc/erc.texi @@ -10,7 +10,7 @@ @copying This manual is for ERC as distributed with Emacs @value{EMACSVER}. -Copyright @copyright{} 2005--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2005--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/ert.texi b/doc/misc/ert.texi index bc56a4af99..a4e2cb506a 100644 --- a/doc/misc/ert.texi +++ b/doc/misc/ert.texi @@ -15,7 +15,7 @@ @end direntry @copying -Copyright @copyright{} 2008, 2010--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2008, 2010--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 0c5501f36b..e106f39cdd 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -10,7 +10,7 @@ @copying This manual is for Eshell, the Emacs shell. -Copyright @copyright{} 1999--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1999--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/eudc.texi b/doc/misc/eudc.texi index 69a8512f17..b40277003c 100644 --- a/doc/misc/eudc.texi +++ b/doc/misc/eudc.texi @@ -14,7 +14,7 @@ This file documents EUDC version 1.40.0. EUDC is the Emacs Unified Directory Client, a common interface to directory servers and contact information. -Copyright @copyright{} 1998, 2000--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1998, 2000--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/eww.texi b/doc/misc/eww.texi index a2a21f031d..6e82a97030 100644 --- a/doc/misc/eww.texi +++ b/doc/misc/eww.texi @@ -8,7 +8,7 @@ @copying This file documents the GNU Emacs Web Wowser (EWW) package. -Copyright @copyright{} 2014--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2014--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/flymake.texi b/doc/misc/flymake.texi index 704e9611c6..9c838a8341 100644 --- a/doc/misc/flymake.texi +++ b/doc/misc/flymake.texi @@ -14,7 +14,7 @@ This manual is for GNU Flymake (version @value{VERSION}, @value{UPDATED}), which is a universal on-the-fly syntax checker for GNU Emacs. -Copyright @copyright{} 2004--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2004--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/forms.texi b/doc/misc/forms.texi index 20b0904ad1..3d7ac96cc2 100644 --- a/doc/misc/forms.texi +++ b/doc/misc/forms.texi @@ -19,7 +19,7 @@ @copying This file documents Forms mode, a form-editing major mode for GNU Emacs. -Copyright @copyright{} 1989, 1997, 2001--2020 Free Software Foundation, +Copyright @copyright{} 1989, 1997, 2001--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/misc/gnus-coding.texi b/doc/misc/gnus-coding.texi index 9a14a95f79..94d952b423 100644 --- a/doc/misc/gnus-coding.texi +++ b/doc/misc/gnus-coding.texi @@ -8,7 +8,7 @@ @syncodeindex pg cp @copying -Copyright @copyright{} 2004--2005, 2007--2020 Free Software Foundation, +Copyright @copyright{} 2004--2005, 2007--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/misc/gnus-faq.texi b/doc/misc/gnus-faq.texi index c30e80ff56..4c29976c05 100644 --- a/doc/misc/gnus-faq.texi +++ b/doc/misc/gnus-faq.texi @@ -1,7 +1,7 @@ @c \input texinfo @c -*-texinfo-*- @c Uncomment 1st line before texing this file alone. @c %**start of header -@c Copyright (C) 1995, 2001--2020 Free Software Foundation, Inc. +@c Copyright (C) 1995, 2001--2021 Free Software Foundation, Inc. @c @c @setfilename gnus-faq.info @c @settitle Frequently Asked Questions diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi index 3743b497da..797315d5b8 100644 --- a/doc/misc/gnus.texi +++ b/doc/misc/gnus.texi @@ -8,7 +8,7 @@ @syncodeindex pg cp @copying -Copyright @copyright{} 1995--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1995--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/htmlfontify.texi b/doc/misc/htmlfontify.texi index fc4f32020e..1674565cda 100644 --- a/doc/misc/htmlfontify.texi +++ b/doc/misc/htmlfontify.texi @@ -10,7 +10,7 @@ This manual documents Htmlfontify, a source code -> crosslinked + formatted + syntax colorized html transformer. -Copyright @copyright{} 2002--2003, 2013--2020 Free Software Foundation, +Copyright @copyright{} 2002--2003, 2013--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/misc/idlwave.texi b/doc/misc/idlwave.texi index 538c088282..3cd53c71da 100644 --- a/doc/misc/idlwave.texi +++ b/doc/misc/idlwave.texi @@ -23,7 +23,7 @@ Emacs, and interacting with an IDL shell run as a subprocess. This is edition @value{EDITION} of the IDLWAVE User Manual for IDLWAVE @value{VERSION}. -Copyright @copyright{} 1999--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1999--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/ido.texi b/doc/misc/ido.texi index 7cc4edd286..1c960940a0 100644 --- a/doc/misc/ido.texi +++ b/doc/misc/ido.texi @@ -7,7 +7,7 @@ @copying This file documents the Ido package for GNU Emacs. -Copyright @copyright{} 2013--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2013--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/info.texi b/doc/misc/info.texi index 85e04a9960..27c00f3925 100644 --- a/doc/misc/info.texi +++ b/doc/misc/info.texi @@ -15,7 +15,7 @@ This file describes how to use Info, the menu-driven GNU documentation system. -Copyright @copyright{} 1989, 1992, 1996--2020 Free Software Foundation, +Copyright @copyright{} 1989, 1992, 1996--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/misc/mairix-el.texi b/doc/misc/mairix-el.texi index 30f5f00677..a571c74487 100644 --- a/doc/misc/mairix-el.texi +++ b/doc/misc/mairix-el.texi @@ -5,7 +5,7 @@ @include docstyle.texi @copying -Copyright @copyright{} 2008--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2008--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/message.texi b/doc/misc/message.texi index b192822fac..f2680b4a79 100644 --- a/doc/misc/message.texi +++ b/doc/misc/message.texi @@ -9,7 +9,7 @@ @copying This file documents Message, the Emacs message composition mode. -Copyright @copyright{} 1996--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1996--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/mh-e.texi b/doc/misc/mh-e.texi index 962f22af5d..308ea3f34c 100644 --- a/doc/misc/mh-e.texi +++ b/doc/misc/mh-e.texi @@ -25,7 +25,7 @@ This is version @value{VERSION}@value{EDITION} of @cite{The MH-E Manual}, last updated @value{UPDATED}. -Copyright @copyright{} 1995, 2001--2003, 2005--2020 Free Software +Copyright @copyright{} 1995, 2001--2003, 2005--2021 Free Software Foundation, Inc. @c This dual license has been agreed upon by the FSF. diff --git a/doc/misc/modus-themes.texi b/doc/misc/modus-themes.texi index de3ccd27c4..b16aece2ee 100644 --- a/doc/misc/modus-themes.texi +++ b/doc/misc/modus-themes.texi @@ -33,7 +33,7 @@ released on 2020-10-08. Any reference to a newer feature which does not yet form part of the latest tagged commit, is explicitly marked as such. -Copyright (C) 2020 Free Software Foundation, Inc. +Copyright (C) 2020--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this diff --git a/doc/misc/newsticker.texi b/doc/misc/newsticker.texi index f144975451..5d052cc27d 100644 --- a/doc/misc/newsticker.texi +++ b/doc/misc/newsticker.texi @@ -15,7 +15,7 @@ This manual documents Newsticker, a feed reader for Emacs. It corresponds to Emacs version @value{EMACSVER}. @noindent -Copyright @copyright{} 2004--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2004--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/nxml-mode.texi b/doc/misc/nxml-mode.texi index 1741222d4b..3671ac8f3d 100644 --- a/doc/misc/nxml-mode.texi +++ b/doc/misc/nxml-mode.texi @@ -9,7 +9,7 @@ This manual documents nXML mode, an Emacs major mode for editing XML with RELAX NG support. -Copyright @copyright{} 2007--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2007--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/octave-mode.texi b/doc/misc/octave-mode.texi index 2005a8e181..1adc268969 100644 --- a/doc/misc/octave-mode.texi +++ b/doc/misc/octave-mode.texi @@ -6,7 +6,7 @@ @c %**end of header @copying -Copyright @copyright{} 1996--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1996--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/org.texi b/doc/misc/org.texi index 2f1781657d..5eeb098cc7 100644 --- a/doc/misc/org.texi +++ b/doc/misc/org.texi @@ -15,7 +15,7 @@ @copying This manual is for Org version 9.4. -Copyright @copyright{} 2004--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2004--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/pcl-cvs.texi b/doc/misc/pcl-cvs.texi index d1951f581c..0d4f976911 100644 --- a/doc/misc/pcl-cvs.texi +++ b/doc/misc/pcl-cvs.texi @@ -7,7 +7,7 @@ @c %**end of header @copying -Copyright @copyright{} 1991--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1991--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/pgg.texi b/doc/misc/pgg.texi index 261897b735..82495275fc 100644 --- a/doc/misc/pgg.texi +++ b/doc/misc/pgg.texi @@ -10,7 +10,7 @@ This file describes PGG @value{VERSION}, an Emacs interface to various PGP implementations. -Copyright @copyright{} 2001, 2003--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2001, 2003--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/rcirc.texi b/doc/misc/rcirc.texi index 2054ca5860..ff8133b2a1 100644 --- a/doc/misc/rcirc.texi +++ b/doc/misc/rcirc.texi @@ -6,7 +6,7 @@ @c %**end of header @copying -Copyright @copyright{} 2006--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2006--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/reftex.texi b/doc/misc/reftex.texi index 0dab524151..599252fabf 100644 --- a/doc/misc/reftex.texi +++ b/doc/misc/reftex.texi @@ -46,7 +46,7 @@ This manual documents @RefTeX{} (version @value{VERSION}), a package to do labels, references, citations and indices for LaTeX documents with Emacs. -Copyright @copyright{} 1997--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1997--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/remember.texi b/doc/misc/remember.texi index df845372f4..80065be0a1 100644 --- a/doc/misc/remember.texi +++ b/doc/misc/remember.texi @@ -9,7 +9,7 @@ @copying This manual is for Remember Mode, version 2.0 -Copyright @copyright{} 2001, 2004--2005, 2007--2020 Free Software +Copyright @copyright{} 2001, 2004--2005, 2007--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/misc/sasl.texi b/doc/misc/sasl.texi index a25f98566c..847ad5ed76 100644 --- a/doc/misc/sasl.texi +++ b/doc/misc/sasl.texi @@ -9,7 +9,7 @@ @copying This file describes the Emacs SASL library, version @value{VERSION}. -Copyright @copyright{} 2000, 2004--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2000, 2004--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/sc.texi b/doc/misc/sc.texi index ccf5b9efb0..3f5b5917a0 100644 --- a/doc/misc/sc.texi +++ b/doc/misc/sc.texi @@ -15,7 +15,7 @@ This document describes Supercite, an Emacs package for citing and attributing replies to mail and news messages. -Copyright @copyright{} 1993, 2001--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1993, 2001--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/sem-user.texi b/doc/misc/sem-user.texi index d151cee02c..c37291ac14 100644 --- a/doc/misc/sem-user.texi +++ b/doc/misc/sem-user.texi @@ -1,5 +1,5 @@ @c This is part of the Semantic manual. -@c Copyright (C) 1999--2005, 2007, 2009--2020 Free Software Foundation, +@c Copyright (C) 1999--2005, 2007, 2009--2021 Free Software Foundation, @c Inc. @c See file semantic.texi for copying conditions. diff --git a/doc/misc/semantic.texi b/doc/misc/semantic.texi index c2b2be2282..3c4f2f0c0e 100644 --- a/doc/misc/semantic.texi +++ b/doc/misc/semantic.texi @@ -25,7 +25,7 @@ @copying This manual documents the Semantic library and utilities. -Copyright @copyright{} 1999--2005, 2007, 2009--2020 Free Software +Copyright @copyright{} 1999--2005, 2007, 2009--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/misc/ses.texi b/doc/misc/ses.texi index 6edd6a6576..b529f0b836 100644 --- a/doc/misc/ses.texi +++ b/doc/misc/ses.texi @@ -12,7 +12,7 @@ @copying This file documents @acronym{SES}: the Simple Emacs Spreadsheet. -Copyright @copyright{} 2002--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2002--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/sieve.texi b/doc/misc/sieve.texi index 0813caebd0..c30409fc32 100644 --- a/doc/misc/sieve.texi +++ b/doc/misc/sieve.texi @@ -10,7 +10,7 @@ @copying This file documents the Emacs Sieve package, for server-side mail filtering. -Copyright @copyright{} 2001--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2001--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/smtpmail.texi b/doc/misc/smtpmail.texi index f4367b3537..dd481d2101 100644 --- a/doc/misc/smtpmail.texi +++ b/doc/misc/smtpmail.texi @@ -4,7 +4,7 @@ @include docstyle.texi @syncodeindex vr fn @copying -Copyright @copyright{} 2003--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2003--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/speedbar.texi b/doc/misc/speedbar.texi index c9c3daf963..9991917b3f 100644 --- a/doc/misc/speedbar.texi +++ b/doc/misc/speedbar.texi @@ -5,7 +5,7 @@ @syncodeindex fn cp @copying -Copyright @copyright{} 1999--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1999--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/srecode.texi b/doc/misc/srecode.texi index 79734685e9..a0e999b681 100644 --- a/doc/misc/srecode.texi +++ b/doc/misc/srecode.texi @@ -16,7 +16,7 @@ @c %**end of header @copying -Copyright @copyright{} 2007--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2007--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex index 3c7051d1c7..5be2e13a67 100644 --- a/doc/misc/texinfo.tex +++ b/doc/misc/texinfo.tex @@ -5,7 +5,7 @@ % \def\texinfoversion{2020-10-24.12} % -% Copyright 1985, 1986, 1988, 1990-2020 Free Software Foundation, Inc. +% Copyright 1985--1986, 1988, 1990--2021 Free Software Foundation, Inc. % % This texinfo.tex file is free software: you can redistribute it and/or % modify it under the terms of the GNU General Public License as diff --git a/doc/misc/todo-mode.texi b/doc/misc/todo-mode.texi index 428df56f6e..dbd7f3d02f 100644 --- a/doc/misc/todo-mode.texi +++ b/doc/misc/todo-mode.texi @@ -9,7 +9,7 @@ @c %**end of header @copying -Copyright @copyright{} 2013--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2013--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 2133dfec35..358f6fc542 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -12,7 +12,7 @@ @footnotestyle end @copying -Copyright @copyright{} 1999--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1999--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/trampver.texi b/doc/misc/trampver.texi index ba98a7e31f..6970c46aef 100644 --- a/doc/misc/trampver.texi +++ b/doc/misc/trampver.texi @@ -2,7 +2,7 @@ @c texi/trampver.texi. Generated from trampver.texi.in by configure. @c This is part of the Emacs manual. -@c Copyright (C) 2003--2020 Free Software Foundation, Inc. +@c Copyright (C) 2003--2021 Free Software Foundation, Inc. @c See file doclicense.texi for copying conditions. @c In the Tramp GIT, the version numbers are auto-frobbed from diff --git a/doc/misc/url.texi b/doc/misc/url.texi index 0304ff4b9f..8f15e11007 100644 --- a/doc/misc/url.texi +++ b/doc/misc/url.texi @@ -21,7 +21,7 @@ @copying This is the manual for the @code{url} Emacs Lisp library. -Copyright @copyright{} 1993--1999, 2002, 2004--2020 Free Software +Copyright @copyright{} 1993--1999, 2002, 2004--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/misc/vhdl-mode.texi b/doc/misc/vhdl-mode.texi index 527302e0cb..fef98a7463 100644 --- a/doc/misc/vhdl-mode.texi +++ b/doc/misc/vhdl-mode.texi @@ -10,7 +10,7 @@ @copying This file documents VHDL Mode, an Emacs mode for editing VHDL code. -Copyright @copyright{} 1995--2008, 2010, 2012, 2015--2020 Free Software +Copyright @copyright{} 1995--2008, 2010, 2012, 2015--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/misc/vip.texi b/doc/misc/vip.texi index fe50309dd9..92c76ad251 100644 --- a/doc/misc/vip.texi +++ b/doc/misc/vip.texi @@ -4,7 +4,7 @@ @include docstyle.texi @copying -Copyright @copyright{} 1987, 2001--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1987, 2001--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/viper.texi b/doc/misc/viper.texi index 661eb7c947..e127f62bb5 100644 --- a/doc/misc/viper.texi +++ b/doc/misc/viper.texi @@ -8,7 +8,7 @@ @include docstyle.texi @copying -Copyright @copyright{} 1995--1997, 2001--2020 Free Software Foundation, +Copyright @copyright{} 1995--1997, 2001--2021 Free Software Foundation, Inc. @quotation diff --git a/doc/misc/widget.texi b/doc/misc/widget.texi index 83a6c4c8d2..b0254e0824 100644 --- a/doc/misc/widget.texi +++ b/doc/misc/widget.texi @@ -9,7 +9,7 @@ @c %**end of header @copying -Copyright @copyright{} 2000--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2000--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/doc/misc/wisent.texi b/doc/misc/wisent.texi index 8b6929be27..dc5b8e4d20 100644 --- a/doc/misc/wisent.texi +++ b/doc/misc/wisent.texi @@ -24,7 +24,7 @@ @c %**end of header @copying -Copyright @copyright{} 1988--1993, 1995, 1998--2004, 2007, 2012--2020 +Copyright @copyright{} 1988--1993, 1995, 1998--2004, 2007, 2012--2021 Free Software Foundation, Inc. @c Since we are both GNU manuals, we do not need to ack each other here. diff --git a/doc/misc/woman.texi b/doc/misc/woman.texi index a114415e3a..4470afcad2 100644 --- a/doc/misc/woman.texi +++ b/doc/misc/woman.texi @@ -15,7 +15,7 @@ This file documents WoMan: A program to browse Unix manual pages ``W.O. (without) man''. -Copyright @copyright{} 2001--2020 Free Software Foundation, Inc. +Copyright @copyright{} 2001--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/etc/CALC-NEWS b/etc/CALC-NEWS index a0b9cdf696..da9ed66f15 100644 --- a/etc/CALC-NEWS +++ b/etc/CALC-NEWS @@ -1,4 +1,4 @@ -Copyright (C) 2001-2020 Free Software Foundation, Inc. +Copyright (C) 2001-2021 Free Software Foundation, Inc. See the end of the file for license conditions. Calc is an advanced desk calculator for GNU Emacs. diff --git a/etc/ChangeLog.1 b/etc/ChangeLog.1 index 5a7cd59c97..629ab0b1fd 100644 --- a/etc/ChangeLog.1 +++ b/etc/ChangeLog.1 @@ -6891,7 +6891,7 @@ ;; coding: utf-8 ;; End: - Copyright (C) 1993-1999, 2001-2020 Free Software Foundation, Inc. + Copyright (C) 1993-1999, 2001-2021 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/etc/DEBUG b/etc/DEBUG index 7fb7e44758..fae8726186 100644 --- a/etc/DEBUG +++ b/etc/DEBUG @@ -1,6 +1,6 @@ Debugging GNU Emacs -Copyright (C) 1985, 2000-2020 Free Software Foundation, Inc. +Copyright (C) 1985, 2000-2021 Free Software Foundation, Inc. See the end of the file for license conditions. ** Preliminaries diff --git a/etc/DISTRIB b/etc/DISTRIB index 767dac6a2f..610c347289 100644 --- a/etc/DISTRIB +++ b/etc/DISTRIB @@ -1,7 +1,7 @@ -*- text -*- GNU Emacs availability information -Copyright (C) 1986-1993, 1995, 1998, 2000-2020 Free Software Foundation, +Copyright (C) 1986-1993, 1995, 1998, 2000-2021 Free Software Foundation, Inc. See the end of the file for license conditions. diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS index 78cb540177..8c9306b5ca 100644 --- a/etc/ERC-NEWS +++ b/etc/ERC-NEWS @@ -1,6 +1,6 @@ ERC NEWS -*- outline -*- -Copyright (C) 2006-2020 Free Software Foundation, Inc. +Copyright (C) 2006-2021 Free Software Foundation, Inc. See the end of the file for license conditions. * For changes after ERC 5.3, see the main Emacs NEWS file diff --git a/etc/ETAGS.EBNF b/etc/ETAGS.EBNF index 04db4e3dc8..c72ac6f721 100644 --- a/etc/ETAGS.EBNF +++ b/etc/ETAGS.EBNF @@ -94,7 +94,7 @@ those. ===================== end of discussion of tag names ===================== -Copyright (C) 2002-2020 Free Software Foundation, Inc. +Copyright (C) 2002-2021 Free Software Foundation, Inc. COPYING PERMISSIONS: diff --git a/etc/ETAGS.README b/etc/ETAGS.README index 314e3215ab..3c56021524 100644 --- a/etc/ETAGS.README +++ b/etc/ETAGS.README @@ -28,7 +28,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -Copyright (C) 1984, 1987-1989, 1993-1995, 1998-2020 Free Software +Copyright (C) 1984, 1987-1989, 1993-1995, 1998-2021 Free Software Foundation, Inc. This file is not considered part of GNU Emacs. diff --git a/etc/HELLO b/etc/HELLO index 9ea7ebc2de..dec3a775af 100644 --- a/etc/HELLO +++ b/etc/HELLO @@ -103,7 +103,7 @@ Vietnamese (tiếng Việt) Chào bạn -Copyright (C) 2001-2020 Free Software Foundation, Inc. +Copyright (C) 2001-2021 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/etc/MACHINES b/etc/MACHINES index 78e9cef0fd..9799577737 100644 --- a/etc/MACHINES +++ b/etc/MACHINES @@ -1,6 +1,6 @@ Emacs machines list -Copyright (C) 1989-1990, 1992-1993, 1998, 2001-2020 Free Software +Copyright (C) 1989-1990, 1992-1993, 1998, 2001-2021 Free Software Foundation, Inc. See the end of the file for license conditions. diff --git a/etc/MH-E-NEWS b/etc/MH-E-NEWS index 420ddd026f..29c48c7214 100644 --- a/etc/MH-E-NEWS +++ b/etc/MH-E-NEWS @@ -1,6 +1,6 @@ * COPYRIGHT -Copyright (C) 2001-2020 Free Software Foundation, Inc. +Copyright (C) 2001-2021 Free Software Foundation, Inc. See the end of the file for license conditions. * Changes in MH-E 8.6 diff --git a/etc/NEWS b/etc/NEWS index 62907a6124..b294ff1d23 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1,6 +1,6 @@ GNU Emacs NEWS -- history of user-visible changes. -Copyright (C) 2017-2020 Free Software Foundation, Inc. +Copyright (C) 2017-2021 Free Software Foundation, Inc. See the end of the file for license conditions. Please send Emacs bug reports to 'bug-gnu-emacs@gnu.org'. diff --git a/etc/NEWS.1-17 b/etc/NEWS.1-17 index c4ff83bb70..42a3ced1c3 100644 --- a/etc/NEWS.1-17 +++ b/etc/NEWS.1-17 @@ -1,6 +1,6 @@ GNU Emacs NEWS -- history of user-visible changes. 26-Mar-1986 -Copyright (C) 1985-1986, 2006-2020 Free Software Foundation, Inc. +Copyright (C) 1985-1986, 2006-2021 Free Software Foundation, Inc. See the end of the file for license conditions. diff --git a/etc/NEWS.18 b/etc/NEWS.18 index e044f663c4..b11a189c30 100644 --- a/etc/NEWS.18 +++ b/etc/NEWS.18 @@ -1,6 +1,6 @@ GNU Emacs NEWS -- history of user-visible changes. 17-Aug-1988 -Copyright (C) 1988, 2006-2020 Free Software Foundation, Inc. +Copyright (C) 1988, 2006-2021 Free Software Foundation, Inc. See the end of the file for license conditions. diff --git a/etc/NEWS.19 b/etc/NEWS.19 index d919608d27..43235e0e15 100644 --- a/etc/NEWS.19 +++ b/etc/NEWS.19 @@ -1,6 +1,6 @@ GNU Emacs NEWS -- history of user-visible changes. 1992. -Copyright (C) 1993-1995, 2001, 2006-2020 Free Software Foundation, Inc. +Copyright (C) 1993-1995, 2001, 2006-2021 Free Software Foundation, Inc. See the end of the file for license conditions. diff --git a/etc/NEWS.20 b/etc/NEWS.20 index 69ce24a301..efd0e5d5c2 100644 --- a/etc/NEWS.20 +++ b/etc/NEWS.20 @@ -1,6 +1,6 @@ GNU Emacs NEWS -- history of user-visible changes. 2006-05-31 -Copyright (C) 1999-2001, 2006-2020 Free Software Foundation, Inc. +Copyright (C) 1999-2001, 2006-2021 Free Software Foundation, Inc. See the end of the file for license conditions. diff --git a/etc/NEWS.21 b/etc/NEWS.21 index 1228984fe8..b9d59594a4 100644 --- a/etc/NEWS.21 +++ b/etc/NEWS.21 @@ -1,6 +1,6 @@ GNU Emacs NEWS -- history of user-visible changes. 2006-05-31 -Copyright (C) 2000-2020 Free Software Foundation, Inc. +Copyright (C) 2000-2021 Free Software Foundation, Inc. See the end of the file for license conditions. diff --git a/etc/NEWS.22 b/etc/NEWS.22 index 4df1792fbc..1f03dc3a13 100644 --- a/etc/NEWS.22 +++ b/etc/NEWS.22 @@ -1,6 +1,6 @@ GNU Emacs NEWS -- history of user-visible changes. -Copyright (C) 2001-2020 Free Software Foundation, Inc. +Copyright (C) 2001-2021 Free Software Foundation, Inc. See the end of the file for license conditions. Please send Emacs bug reports to bug-gnu-emacs@gnu.org. diff --git a/etc/NEWS.23 b/etc/NEWS.23 index 331ed281a3..8611ba53d2 100644 --- a/etc/NEWS.23 +++ b/etc/NEWS.23 @@ -1,6 +1,6 @@ GNU Emacs NEWS -- history of user-visible changes. -Copyright (C) 2007-2020 Free Software Foundation, Inc. +Copyright (C) 2007-2021 Free Software Foundation, Inc. See the end of the file for license conditions. Please send Emacs bug reports to bug-gnu-emacs@gnu.org. diff --git a/etc/NEWS.24 b/etc/NEWS.24 index 60c2b4dfc6..acf6219f74 100644 --- a/etc/NEWS.24 +++ b/etc/NEWS.24 @@ -1,6 +1,6 @@ GNU Emacs NEWS -- history of user-visible changes. -Copyright (C) 2010-2020 Free Software Foundation, Inc. +Copyright (C) 2010-2021 Free Software Foundation, Inc. See the end of the file for license conditions. Please send Emacs bug reports to bug-gnu-emacs@gnu.org. diff --git a/etc/NEWS.25 b/etc/NEWS.25 index 8c04d94090..c533f27709 100644 --- a/etc/NEWS.25 +++ b/etc/NEWS.25 @@ -1,6 +1,6 @@ GNU Emacs NEWS -- history of user-visible changes. -Copyright (C) 2014-2020 Free Software Foundation, Inc. +Copyright (C) 2014-2021 Free Software Foundation, Inc. See the end of the file for license conditions. Please send Emacs bug reports to bug-gnu-emacs@gnu.org. diff --git a/etc/NEWS.26 b/etc/NEWS.26 index c6306a6d45..05e8672625 100644 --- a/etc/NEWS.26 +++ b/etc/NEWS.26 @@ -1,6 +1,6 @@ GNU Emacs NEWS -- history of user-visible changes. -Copyright (C) 2016-2020 Free Software Foundation, Inc. +Copyright (C) 2016-2021 Free Software Foundation, Inc. See the end of the file for license conditions. Please send Emacs bug reports to 'bug-gnu-emacs@gnu.org'. diff --git a/etc/NEWS.27 b/etc/NEWS.27 index 4855cd3b61..9232a308c5 100644 --- a/etc/NEWS.27 +++ b/etc/NEWS.27 @@ -1,6 +1,6 @@ GNU Emacs NEWS -- history of user-visible changes. -Copyright (C) 2017-2020 Free Software Foundation, Inc. +Copyright (C) 2017-2021 Free Software Foundation, Inc. See the end of the file for license conditions. Please send Emacs bug reports to 'bug-gnu-emacs@gnu.org'. diff --git a/etc/NEXTSTEP b/etc/NEXTSTEP index 5ac3b6b174..5dd2e646ed 100644 --- a/etc/NEXTSTEP +++ b/etc/NEXTSTEP @@ -1,4 +1,4 @@ -Copyright (C) 2008-2020 Free Software Foundation, Inc. +Copyright (C) 2008-2021 Free Software Foundation, Inc. See the end of the file for license conditions. This file contains information about GNU Emacs on "Nextstep" platforms. diff --git a/etc/NXML-NEWS b/etc/NXML-NEWS index 5df9790c2f..cdce6e72ba 100644 --- a/etc/NXML-NEWS +++ b/etc/NXML-NEWS @@ -1,4 +1,4 @@ -Copyright (C) 2007-2020 Free Software Foundation, Inc. +Copyright (C) 2007-2021 Free Software Foundation, Inc. See the end of the file for license conditions. diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 0c094411ab..2cae8b92ac 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -5,7 +5,7 @@ ORG NEWS -- history of user-visible changes. -*- mode: org; coding: utf-8 -*- #+LINK: doc https://orgmode.org/worg/doc.html#%s #+LINK: git https://code.orgmode.org/bzg/org-mode/commit/%s -Copyright (C) 2012-2020 Free Software Foundation, Inc. +Copyright (C) 2012-2021 Free Software Foundation, Inc. See the end of the file for license conditions. Please send Org bug reports to mailto:emacs-orgmode@gnu.org. diff --git a/etc/PROBLEMS b/etc/PROBLEMS index f24c6f03c8..25e129bcd9 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -1,6 +1,6 @@ Known Problems with GNU Emacs -Copyright (C) 1987-1989, 1993-1999, 2001-2020 Free Software Foundation, +Copyright (C) 1987-1989, 1993-1999, 2001-2021 Free Software Foundation, Inc. See the end of the file for license conditions. diff --git a/etc/README b/etc/README index b9b4bc4f0e..6d7a15a6f2 100644 --- a/etc/README +++ b/etc/README @@ -7,5 +7,5 @@ COPYRIGHT AND LICENSE INFORMATION FOR IMAGE FILES File: emacs.icon Author: Sun Microsystems, Inc - Copyright (C) 1999, 2001-2020 Free Software Foundation, Inc. + Copyright (C) 1999, 2001-2021 Free Software Foundation, Inc. License: GNU General Public License version 3 or later (see COPYING) diff --git a/etc/TERMS b/etc/TERMS index 20c0a9a68c..80b39c80e9 100644 --- a/etc/TERMS +++ b/etc/TERMS @@ -1,4 +1,4 @@ -Copyright (C) 1999, 2001-2020 Free Software Foundation, Inc. +Copyright (C) 1999, 2001-2021 Free Software Foundation, Inc. See the end of the file for copying permissions. This file describes what you must or might want to do to termcap entries diff --git a/etc/TODO b/etc/TODO index d7bcfd4d97..9448617626 100644 --- a/etc/TODO +++ b/etc/TODO @@ -1,6 +1,6 @@ Emacs TODO List -*-outline-*- -Copyright (C) 2001-2020 Free Software Foundation, Inc. +Copyright (C) 2001-2021 Free Software Foundation, Inc. See the end of the file for license conditions. diff --git a/etc/charsets/README b/etc/charsets/README index 3312367f29..0045a0f638 100644 --- a/etc/charsets/README +++ b/etc/charsets/README @@ -1,6 +1,6 @@ # README file for charset mapping files in this directory. -# Copyright (C) 2003-2020 Free Software Foundation, Inc. +# Copyright (C) 2003-2021 Free Software Foundation, Inc. # Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 # National Institute of Advanced Industrial Science and Technology (AIST) # Registration Number H13PRO009 diff --git a/etc/compilation.txt b/etc/compilation.txt index 7e406389d4..e56d3b6847 100644 --- a/etc/compilation.txt +++ b/etc/compilation.txt @@ -676,7 +676,7 @@ Compilation segmentation fault at Thu Jul 13 10:55:49 Compilation finished at Thu Jul 21 15:02:15 -Copyright (C) 2004-2020 Free Software Foundation, Inc. +Copyright (C) 2004-2021 Free Software Foundation, Inc. COPYING PERMISSIONS: diff --git a/etc/edt-user.el b/etc/edt-user.el index 2852f936f2..8e1a599f0d 100644 --- a/etc/edt-user.el +++ b/etc/edt-user.el @@ -1,6 +1,6 @@ ;;; edt-user.el --- Sample user customizations for Emacs EDT emulation -*- lexical-binding: t -*- -;; Copyright (C) 1986, 1992-1993, 2000-2020 Free Software Foundation, +;; Copyright (C) 1986, 1992-1993, 2000-2021 Free Software Foundation, ;; Inc. ;; Author: Kevin Gallagher diff --git a/etc/emacs-buffer.gdb b/etc/emacs-buffer.gdb index e237742407..41af836599 100644 --- a/etc/emacs-buffer.gdb +++ b/etc/emacs-buffer.gdb @@ -1,6 +1,6 @@ # emacs-buffer.gdb --- gdb macros for recovering buffers from emacs coredumps -# Copyright (C) 2005-2020 Free Software Foundation, Inc. +# Copyright (C) 2005-2021 Free Software Foundation, Inc. # Author: Noah Friedman # Created: 2005-04-28 diff --git a/etc/emacs.appdata.xml b/etc/emacs.appdata.xml index 1b5d7f9aae..ca6233a59a 100644 --- a/etc/emacs.appdata.xml +++ b/etc/emacs.appdata.xml @@ -1,5 +1,5 @@ - + org.gnu.emacs GFDL-1.3+ diff --git a/etc/enriched.txt b/etc/enriched.txt index 1e1dc46c41..dd269e313c 100644 --- a/etc/enriched.txt +++ b/etc/enriched.txt @@ -253,7 +253,7 @@ it. -Copyright (C) 1995, 1997, 2001-2020 Free Software Foundation, Inc. +Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. COPYING PERMISSIONS: diff --git a/etc/forms/forms-d2.el b/etc/forms/forms-d2.el index 1b0d6426e0..cd4231cf2d 100644 --- a/etc/forms/forms-d2.el +++ b/etc/forms/forms-d2.el @@ -1,6 +1,6 @@ ;;; forms-d2.el --- demo forms-mode -*- lexical-binding:t -*- -;; Copyright (C) 1991, 1994-1997, 2001-2020 Free Software Foundation, +;; Copyright (C) 1991, 1994-1997, 2001-2021 Free Software Foundation, ;; Inc. ;; Author: Johan Vromans diff --git a/etc/gnus-tut.txt b/etc/gnus-tut.txt index 2001b913d2..27e868b79c 100644 --- a/etc/gnus-tut.txt +++ b/etc/gnus-tut.txt @@ -24,7 +24,7 @@ was done by moi, yours truly, your humble servant, Lars Magne Ingebrigtsen. If you have a WWW browser, you can investigate to your heart's delight at . -;; Copyright (C) 1995, 2001-2020 Free Software Foundation, Inc. +;; Copyright (C) 1995, 2001-2021 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; Keywords: news diff --git a/etc/grep.txt b/etc/grep.txt index 3dc4aac3c8..b5b78459b5 100644 --- a/etc/grep.txt +++ b/etc/grep.txt @@ -103,7 +103,7 @@ grep -nH -e "xyzxyz" ../info/* -Copyright (C) 2005-2020 Free Software Foundation, Inc. +Copyright (C) 2005-2021 Free Software Foundation, Inc. COPYING PERMISSIONS: diff --git a/etc/images/README b/etc/images/README index 2cee207e24..f6e4f69668 100644 --- a/etc/images/README +++ b/etc/images/README @@ -27,7 +27,7 @@ COPYRIGHT AND LICENSE INFORMATION FOR IMAGE FILES File: mh-logo.xpm Author: Satyaki Das - Copyright (C) 2003-2020 Free Software Foundation, Inc. + Copyright (C) 2003-2021 Free Software Foundation, Inc. Files: gnus.pbm Author: Luis Fernandes diff --git a/etc/images/custom/README b/etc/images/custom/README index 7eb87c4400..fc9cd8d7f1 100644 --- a/etc/images/custom/README +++ b/etc/images/custom/README @@ -6,5 +6,5 @@ COPYRIGHT AND LICENSE INFORMATION FOR IMAGE FILES Files: down.xpm down-pushed.xpm right.xpm right-pushed.xpm Author: Juri Linkov -Copyright (C) 2008-2020 Free Software Foundation, Inc. +Copyright (C) 2008-2021 Free Software Foundation, Inc. License: GNU General Public License version 3 or later (see COPYING) diff --git a/etc/images/ezimage/README b/etc/images/ezimage/README index 2aef056abe..865ce5b4c0 100644 --- a/etc/images/ezimage/README +++ b/etc/images/ezimage/README @@ -7,5 +7,5 @@ Files: bits.xpm bitsbang.xpm box-minus.xpm box-plus.xpm tag-gt.xpm tag-minus.xpm tag-plus.xpm tag-type.xpm tag-v.xpm tag.xpm unlock.xpm Author: Eric M. Ludlam -Copyright (C) 1999-2020 Free Software Foundation, Inc. +Copyright (C) 1999-2021 Free Software Foundation, Inc. License: GNU General Public License version 3 or later (see COPYING) diff --git a/etc/images/gnus/README b/etc/images/gnus/README index f9c51f02c7..4ca948ecd7 100644 --- a/etc/images/gnus/README +++ b/etc/images/gnus/README @@ -7,7 +7,7 @@ COPYRIGHT AND LICENSE INFORMATION FOR IMAGE FILES Files: important.xpm, unimportant.xpm Author: Simon Josefsson -Copyright (C) 2001-2020 Free Software Foundation, Inc. +Copyright (C) 2001-2021 Free Software Foundation, Inc. Files: catchup.pbm catchup.xpm cu-exit.pbm cu-exit.xpm describe-group.pbm describe-group.xpm exit-gnus.pbm exit-gnus.xpm diff --git a/etc/images/gnus/gnus.svg b/etc/images/gnus/gnus.svg index 7514f34463..362dc16cb6 100644 --- a/etc/images/gnus/gnus.svg +++ b/etc/images/gnus/gnus.svg @@ -1,7 +1,7 @@ + org.gnu.emacs GFDL-1.3+ diff --git a/etc/enriched.txt b/etc/enriched.txt index 1e1dc46c41..dd269e313c 100644 --- a/etc/enriched.txt +++ b/etc/enriched.txt @@ -253,7 +253,7 @@ it. -Copyright (C) 1995, 1997, 2001-2020 Free Software Foundation, Inc. +Copyright (C) 1995, 1997, 2001-2021 Free Software Foundation, Inc. COPYING PERMISSIONS: diff --git a/etc/forms/forms-d2.el b/etc/forms/forms-d2.el index 67cdb9cd01..e54c5610a3 100644 --- a/etc/forms/forms-d2.el +++ b/etc/forms/forms-d2.el @@ -1,6 +1,6 @@ ;;; forms-d2.el --- demo forms-mode -;; Copyright (C) 1991, 1994-1997, 2001-2020 Free Software Foundation, +;; Copyright (C) 1991, 1994-1997, 2001-2021 Free Software Foundation, ;; Inc. ;; Author: Johan Vromans diff --git a/etc/gnus-tut.txt b/etc/gnus-tut.txt index 2001b913d2..27e868b79c 100644 --- a/etc/gnus-tut.txt +++ b/etc/gnus-tut.txt @@ -24,7 +24,7 @@ was done by moi, yours truly, your humble servant, Lars Magne Ingebrigtsen. If you have a WWW browser, you can investigate to your heart's delight at . -;; Copyright (C) 1995, 2001-2020 Free Software Foundation, Inc. +;; Copyright (C) 1995, 2001-2021 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; Keywords: news diff --git a/etc/grep.txt b/etc/grep.txt index 19a3b4b47b..72f697a28d 100644 --- a/etc/grep.txt +++ b/etc/grep.txt @@ -97,7 +97,7 @@ grep -nH -e "xyzxyz" ../info/* -Copyright (C) 2005-2020 Free Software Foundation, Inc. +Copyright (C) 2005-2021 Free Software Foundation, Inc. COPYING PERMISSIONS: diff --git a/etc/images/README b/etc/images/README index 2cee207e24..f6e4f69668 100644 --- a/etc/images/README +++ b/etc/images/README @@ -27,7 +27,7 @@ COPYRIGHT AND LICENSE INFORMATION FOR IMAGE FILES File: mh-logo.xpm Author: Satyaki Das - Copyright (C) 2003-2020 Free Software Foundation, Inc. + Copyright (C) 2003-2021 Free Software Foundation, Inc. Files: gnus.pbm Author: Luis Fernandes diff --git a/etc/images/custom/README b/etc/images/custom/README index 7eb87c4400..fc9cd8d7f1 100644 --- a/etc/images/custom/README +++ b/etc/images/custom/README @@ -6,5 +6,5 @@ COPYRIGHT AND LICENSE INFORMATION FOR IMAGE FILES Files: down.xpm down-pushed.xpm right.xpm right-pushed.xpm Author: Juri Linkov -Copyright (C) 2008-2020 Free Software Foundation, Inc. +Copyright (C) 2008-2021 Free Software Foundation, Inc. License: GNU General Public License version 3 or later (see COPYING) diff --git a/etc/images/ezimage/README b/etc/images/ezimage/README index 2aef056abe..865ce5b4c0 100644 --- a/etc/images/ezimage/README +++ b/etc/images/ezimage/README @@ -7,5 +7,5 @@ Files: bits.xpm bitsbang.xpm box-minus.xpm box-plus.xpm tag-gt.xpm tag-minus.xpm tag-plus.xpm tag-type.xpm tag-v.xpm tag.xpm unlock.xpm Author: Eric M. Ludlam -Copyright (C) 1999-2020 Free Software Foundation, Inc. +Copyright (C) 1999-2021 Free Software Foundation, Inc. License: GNU General Public License version 3 or later (see COPYING) diff --git a/etc/images/gnus/README b/etc/images/gnus/README index f9c51f02c7..4ca948ecd7 100644 --- a/etc/images/gnus/README +++ b/etc/images/gnus/README @@ -7,7 +7,7 @@ COPYRIGHT AND LICENSE INFORMATION FOR IMAGE FILES Files: important.xpm, unimportant.xpm Author: Simon Josefsson -Copyright (C) 2001-2020 Free Software Foundation, Inc. +Copyright (C) 2001-2021 Free Software Foundation, Inc. Files: catchup.pbm catchup.xpm cu-exit.pbm cu-exit.xpm describe-group.pbm describe-group.xpm exit-gnus.pbm exit-gnus.xpm diff --git a/etc/images/gnus/gnus.svg b/etc/images/gnus/gnus.svg index 7514f34463..362dc16cb6 100644 --- a/etc/images/gnus/gnus.svg +++ b/etc/images/gnus/gnus.svg @@ -1,7 +1,7 @@